summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/attarray.cxx2611
-rw-r--r--sc/source/core/data/attrib.cxx1328
-rw-r--r--sc/source/core/data/autonamecache.cxx109
-rw-r--r--sc/source/core/data/bcaslot.cxx937
-rw-r--r--sc/source/core/data/cell.cxx2037
-rw-r--r--sc/source/core/data/cell2.cxx1627
-rw-r--r--sc/source/core/data/clipparam.cxx200
-rw-r--r--sc/source/core/data/column.cxx2160
-rw-r--r--sc/source/core/data/column2.cxx1866
-rw-r--r--sc/source/core/data/column3.cxx2001
-rw-r--r--sc/source/core/data/compressedarray.cxx906
-rw-r--r--sc/source/core/data/conditio.cxx1603
-rw-r--r--sc/source/core/data/dbdocutl.cxx197
-rw-r--r--sc/source/core/data/dociter.cxx2158
-rw-r--r--sc/source/core/data/docpool.cxx1059
-rw-r--r--sc/source/core/data/documen2.cxx1300
-rw-r--r--sc/source/core/data/documen3.cxx2128
-rw-r--r--sc/source/core/data/documen4.cxx1203
-rw-r--r--sc/source/core/data/documen5.cxx794
-rw-r--r--sc/source/core/data/documen6.cxx184
-rw-r--r--sc/source/core/data/documen7.cxx534
-rw-r--r--sc/source/core/data/documen8.cxx1625
-rw-r--r--sc/source/core/data/documen9.cxx820
-rw-r--r--sc/source/core/data/document.cxx5269
-rw-r--r--sc/source/core/data/dpcachetable.cxx468
-rw-r--r--sc/source/core/data/dpdimsave.cxx584
-rwxr-xr-xsc/source/core/data/dpglobal.cxx150
-rw-r--r--sc/source/core/data/dpgroup.cxx1589
-rw-r--r--sc/source/core/data/dpobject.cxx2642
-rwxr-xr-xsc/source/core/data/dpoutput.cxx2060
-rw-r--r--sc/source/core/data/dpoutputgeometry.cxx214
-rw-r--r--sc/source/core/data/dpsave.cxx1480
-rw-r--r--sc/source/core/data/dpsdbtab.cxx312
-rwxr-xr-xsc/source/core/data/dpshttab.cxx315
-rwxr-xr-xsc/source/core/data/dptabdat.cxx329
-rw-r--r--sc/source/core/data/dptablecache.cxx1135
-rwxr-xr-xsc/source/core/data/dptabres.cxx4109
-rw-r--r--sc/source/core/data/dptabsrc.cxx2927
-rw-r--r--sc/source/core/data/drawpage.cxx65
-rw-r--r--sc/source/core/data/drwlayer.cxx2109
-rw-r--r--sc/source/core/data/fillinfo.cxx1079
-rw-r--r--sc/source/core/data/global.cxx1992
-rw-r--r--sc/source/core/data/global2.cxx915
-rw-r--r--sc/source/core/data/globalx.cxx171
-rw-r--r--sc/source/core/data/makefile.mk179
-rw-r--r--sc/source/core/data/markarr.cxx410
-rw-r--r--sc/source/core/data/markdata.cxx608
-rw-r--r--sc/source/core/data/olinetab.cxx806
-rw-r--r--sc/source/core/data/pagepar.cxx122
-rw-r--r--sc/source/core/data/patattr.cxx1347
-rw-r--r--sc/source/core/data/pivot2.cxx115
-rw-r--r--sc/source/core/data/poolhelp.cxx128
-rw-r--r--sc/source/core/data/postit.cxx920
-rw-r--r--sc/source/core/data/scdpoutputimpl.cxx187
-rwxr-xr-xsc/source/core/data/scdpoutputimpl.hxx79
-rw-r--r--sc/source/core/data/segmenttree.cxx582
-rw-r--r--sc/source/core/data/sheetevents.cxx172
-rw-r--r--sc/source/core/data/sortparam.cxx263
-rw-r--r--sc/source/core/data/stlpool.cxx641
-rw-r--r--sc/source/core/data/stlsheet.cxx346
-rw-r--r--sc/source/core/data/tabbgcolor.cxx62
-rw-r--r--sc/source/core/data/table1.cxx1721
-rw-r--r--sc/source/core/data/table2.cxx3246
-rw-r--r--sc/source/core/data/table3.cxx2022
-rw-r--r--sc/source/core/data/table4.cxx1990
-rw-r--r--sc/source/core/data/table5.cxx1195
-rw-r--r--sc/source/core/data/table6.cxx690
-rw-r--r--sc/source/core/data/tabprotection.cxx429
-rw-r--r--sc/source/core/data/userdat.cxx127
-rw-r--r--sc/source/core/data/validat.cxx996
-rw-r--r--sc/source/core/inc/addinhelpid.hxx60
-rw-r--r--sc/source/core/inc/addinlis.hxx98
-rw-r--r--sc/source/core/inc/adiasync.hxx92
-rw-r--r--sc/source/core/inc/bcaslot.hxx306
-rw-r--r--sc/source/core/inc/cellkeytranslator.hxx91
-rw-r--r--sc/source/core/inc/core_pch.hxx248
-rw-r--r--sc/source/core/inc/ddelink.hxx99
-rw-r--r--sc/source/core/inc/doubleref.hxx193
-rw-r--r--sc/source/core/inc/interpre.hxx905
-rw-r--r--sc/source/core/inc/jumpmatrix.hxx222
-rw-r--r--sc/source/core/inc/makefile.mk26
-rw-r--r--sc/source/core/inc/parclass.hxx180
-rw-r--r--sc/source/core/inc/poolhelp.hxx74
-rw-r--r--sc/source/core/inc/refupdat.hxx100
-rw-r--r--sc/source/core/inc/scrdata.hxx49
-rw-r--r--sc/source/core/src/compiler.src79
-rw-r--r--sc/source/core/src/makefile.mk48
-rw-r--r--sc/source/core/tool/addincfg.cxx72
-rw-r--r--sc/source/core/tool/addincol.cxx1802
-rw-r--r--sc/source/core/tool/addinhelpid.cxx217
-rw-r--r--sc/source/core/tool/addinlis.cxx190
-rw-r--r--sc/source/core/tool/address.cxx2029
-rw-r--r--sc/source/core/tool/adiasync.cxx187
-rw-r--r--sc/source/core/tool/appoptio.cxx745
-rw-r--r--sc/source/core/tool/autoform.cxx1200
-rw-r--r--sc/source/core/tool/callform.cxx469
-rw-r--r--sc/source/core/tool/cellform.cxx216
-rw-r--r--sc/source/core/tool/cellkeytranslator.cxx232
-rw-r--r--sc/source/core/tool/cellkeywords.inl181
-rw-r--r--sc/source/core/tool/chartarr.cxx615
-rw-r--r--sc/source/core/tool/charthelper.cxx298
-rw-r--r--sc/source/core/tool/chartlis.cxx736
-rw-r--r--sc/source/core/tool/chartlock.cxx195
-rw-r--r--sc/source/core/tool/chartpos.cxx646
-rw-r--r--sc/source/core/tool/chgtrack.cxx4869
-rw-r--r--sc/source/core/tool/chgviset.cxx178
-rw-r--r--sc/source/core/tool/collect.cxx522
-rw-r--r--sc/source/core/tool/compiler.cxx5484
-rw-r--r--sc/source/core/tool/consoli.cxx858
-rw-r--r--sc/source/core/tool/dbcolect.cxx891
-rw-r--r--sc/source/core/tool/ddelink.cxx279
-rw-r--r--sc/source/core/tool/detdata.cxx118
-rw-r--r--sc/source/core/tool/detfunc.cxx1712
-rw-r--r--sc/source/core/tool/docoptio.cxx442
-rw-r--r--sc/source/core/tool/doubleref.cxx565
-rw-r--r--sc/source/core/tool/editutil.cxx778
-rw-r--r--sc/source/core/tool/filtopt.cxx120
-rw-r--r--sc/source/core/tool/formulaparserpool.cxx168
-rw-r--r--sc/source/core/tool/hints.cxx162
-rw-r--r--sc/source/core/tool/inputopt.cxx274
-rw-r--r--sc/source/core/tool/interpr1.cxx7460
-rw-r--r--sc/source/core/tool/interpr2.cxx3032
-rw-r--r--sc/source/core/tool/interpr3.cxx4244
-rw-r--r--sc/source/core/tool/interpr4.cxx3979
-rw-r--r--sc/source/core/tool/interpr5.cxx2815
-rw-r--r--sc/source/core/tool/interpr6.cxx199
-rw-r--r--sc/source/core/tool/lookupcache.cxx126
-rw-r--r--sc/source/core/tool/makefile.mk167
-rw-r--r--sc/source/core/tool/navicfg.cxx80
-rw-r--r--sc/source/core/tool/odffmap.cxx149
-rw-r--r--sc/source/core/tool/optutil.cxx79
-rw-r--r--sc/source/core/tool/parclass.cxx578
-rw-r--r--sc/source/core/tool/printopt.cxx211
-rw-r--r--sc/source/core/tool/prnsave.cxx135
-rw-r--r--sc/source/core/tool/progress.cxx198
-rw-r--r--sc/source/core/tool/queryparam.cxx369
-rw-r--r--sc/source/core/tool/rangelst.cxx703
-rw-r--r--sc/source/core/tool/rangenam.cxx824
-rw-r--r--sc/source/core/tool/rangeseq.cxx476
-rw-r--r--sc/source/core/tool/rangeutl.cxx1054
-rw-r--r--sc/source/core/tool/rechead.cxx173
-rw-r--r--sc/source/core/tool/refdata.cxx372
-rw-r--r--sc/source/core/tool/reffind.cxx168
-rw-r--r--sc/source/core/tool/refreshtimer.cxx81
-rw-r--r--sc/source/core/tool/reftokenhelper.cxx479
-rw-r--r--sc/source/core/tool/refupdat.cxx939
-rw-r--r--sc/source/core/tool/scmatrix.cxx859
-rw-r--r--sc/source/core/tool/stringutil.cxx131
-rw-r--r--sc/source/core/tool/subtotal.cxx81
-rw-r--r--sc/source/core/tool/token.cxx1836
-rw-r--r--sc/source/core/tool/unitconv.cxx178
-rw-r--r--sc/source/core/tool/userlist.cxx297
-rw-r--r--sc/source/core/tool/viewopti.cxx754
-rw-r--r--sc/source/core/tool/zforauto.cxx106
-rw-r--r--sc/source/filter/dif/difexp.cxx317
-rw-r--r--sc/source/filter/dif/difimp.cxx1008
-rw-r--r--sc/source/filter/dif/makefile.mk54
-rw-r--r--sc/source/filter/excel/colrowst.cxx318
-rw-r--r--sc/source/filter/excel/excdoc.cxx832
-rw-r--r--sc/source/filter/excel/excel.cxx304
-rw-r--r--sc/source/filter/excel/excform.cxx2013
-rw-r--r--sc/source/filter/excel/excform8.cxx1596
-rw-r--r--sc/source/filter/excel/excimp8.cxx727
-rw-r--r--sc/source/filter/excel/excrecds.cxx1051
-rw-r--r--sc/source/filter/excel/exctools.cxx434
-rw-r--r--sc/source/filter/excel/expop2.cxx219
-rw-r--r--sc/source/filter/excel/fontbuff.cxx163
-rw-r--r--sc/source/filter/excel/frmbase.cxx282
-rw-r--r--sc/source/filter/excel/impop.cxx1334
-rw-r--r--sc/source/filter/excel/makefile.mk160
-rw-r--r--sc/source/filter/excel/namebuff.cxx344
-rw-r--r--sc/source/filter/excel/ooxml-export-TODO.txt148
-rw-r--r--sc/source/filter/excel/read.cxx1243
-rw-r--r--sc/source/filter/excel/tokstack.cxx888
-rw-r--r--sc/source/filter/excel/xechart.cxx3303
-rw-r--r--sc/source/filter/excel/xecontent.cxx1462
-rw-r--r--sc/source/filter/excel/xeescher.cxx1284
-rw-r--r--sc/source/filter/excel/xeformula.cxx2646
-rw-r--r--sc/source/filter/excel/xehelper.cxx1144
-rw-r--r--sc/source/filter/excel/xelink.cxx2371
-rw-r--r--sc/source/filter/excel/xename.cxx791
-rw-r--r--sc/source/filter/excel/xepage.cxx414
-rw-r--r--sc/source/filter/excel/xepivot.cxx1810
-rw-r--r--sc/source/filter/excel/xerecord.cxx302
-rw-r--r--sc/source/filter/excel/xeroot.cxx269
-rw-r--r--sc/source/filter/excel/xestream.cxx1034
-rw-r--r--sc/source/filter/excel/xestring.cxx656
-rw-r--r--sc/source/filter/excel/xestyle.cxx2903
-rw-r--r--sc/source/filter/excel/xetable.cxx2579
-rw-r--r--sc/source/filter/excel/xeview.cxx538
-rwxr-xr-xsc/source/filter/excel/xichart.cxx4147
-rw-r--r--sc/source/filter/excel/xicontent.cxx1319
-rw-r--r--sc/source/filter/excel/xiescher.cxx4120
-rw-r--r--sc/source/filter/excel/xiformula.cxx127
-rw-r--r--sc/source/filter/excel/xihelper.cxx918
-rw-r--r--sc/source/filter/excel/xilink.cxx807
-rw-r--r--sc/source/filter/excel/xiname.cxx264
-rw-r--r--sc/source/filter/excel/xipage.cxx390
-rw-r--r--sc/source/filter/excel/xipivot.cxx1638
-rw-r--r--sc/source/filter/excel/xiroot.cxx299
-rw-r--r--sc/source/filter/excel/xistream.cxx1102
-rw-r--r--sc/source/filter/excel/xistring.cxx213
-rw-r--r--sc/source/filter/excel/xistyle.cxx1823
-rw-r--r--sc/source/filter/excel/xiview.cxx304
-rw-r--r--sc/source/filter/excel/xladdress.cxx161
-rwxr-xr-xsc/source/filter/excel/xlchart.cxx1328
-rw-r--r--sc/source/filter/excel/xlescher.cxx379
-rw-r--r--sc/source/filter/excel/xlformula.cxx786
-rw-r--r--sc/source/filter/excel/xlpage.cxx248
-rw-r--r--sc/source/filter/excel/xlpivot.cxx1031
-rw-r--r--sc/source/filter/excel/xlroot.cxx419
-rw-r--r--sc/source/filter/excel/xlstyle.cxx1771
-rw-r--r--sc/source/filter/excel/xltools.cxx736
-rw-r--r--sc/source/filter/excel/xltracer.cxx270
-rw-r--r--sc/source/filter/excel/xlview.cxx115
-rw-r--r--sc/source/filter/ftools/fapihelper.cxx412
-rw-r--r--sc/source/filter/ftools/fprogressbar.cxx260
-rw-r--r--sc/source/filter/ftools/ftools.cxx406
-rw-r--r--sc/source/filter/ftools/makefile.mk58
-rw-r--r--sc/source/filter/html/htmlexp.cxx1341
-rw-r--r--sc/source/filter/html/htmlexp2.cxx249
-rw-r--r--sc/source/filter/html/htmlimp.cxx260
-rw-r--r--sc/source/filter/html/htmlpars.cxx3069
-rw-r--r--sc/source/filter/html/makefile.mk62
-rw-r--r--sc/source/filter/inc/XclExpChangeTrack.hxx641
-rw-r--r--sc/source/filter/inc/XclImpChangeTrack.hxx202
-rw-r--r--sc/source/filter/inc/biff.hxx64
-rw-r--r--sc/source/filter/inc/colrowst.hxx80
-rw-r--r--sc/source/filter/inc/decl.h44
-rw-r--r--sc/source/filter/inc/dif.hxx227
-rw-r--r--sc/source/filter/inc/eeimport.hxx68
-rw-r--r--sc/source/filter/inc/eeparser.hxx153
-rw-r--r--sc/source/filter/inc/excdefs.hxx106
-rw-r--r--sc/source/filter/inc/excdoc.hxx120
-rw-r--r--sc/source/filter/inc/excform.hxx160
-rw-r--r--sc/source/filter/inc/excimp8.hxx165
-rw-r--r--sc/source/filter/inc/excrecds.hxx506
-rw-r--r--sc/source/filter/inc/excscen.hxx147
-rw-r--r--sc/source/filter/inc/exp_op.hxx147
-rw-r--r--sc/source/filter/inc/expbase.hxx82
-rw-r--r--sc/source/filter/inc/fapihelper.hxx352
-rw-r--r--sc/source/filter/inc/filt_pch.hxx321
-rw-r--r--sc/source/filter/inc/fkttab.h46
-rw-r--r--sc/source/filter/inc/flttypes.hxx51
-rw-r--r--sc/source/filter/inc/formel.hxx296
-rw-r--r--sc/source/filter/inc/fprogressbar.hxx243
-rw-r--r--sc/source/filter/inc/ftools.hxx544
-rw-r--r--sc/source/filter/inc/funktion.h50
-rw-r--r--sc/source/filter/inc/htmlexp.hxx174
-rw-r--r--sc/source/filter/inc/htmlimp.hxx52
-rw-r--r--sc/source/filter/inc/htmlpars.hxx638
-rw-r--r--sc/source/filter/inc/imp_op.hxx205
-rw-r--r--sc/source/filter/inc/lotattr.hxx153
-rw-r--r--sc/source/filter/inc/lotfntbf.hxx111
-rw-r--r--sc/source/filter/inc/lotform.hxx132
-rw-r--r--sc/source/filter/inc/lotimpop.hxx169
-rw-r--r--sc/source/filter/inc/lotrange.hxx167
-rw-r--r--sc/source/filter/inc/makefile.mk26
-rw-r--r--sc/source/filter/inc/namebuff.hxx356
-rw-r--r--sc/source/filter/inc/op.h70
-rw-r--r--sc/source/filter/inc/optab.h52
-rw-r--r--sc/source/filter/inc/otlnbuff.hxx78
-rw-r--r--sc/source/filter/inc/qpro.hxx59
-rw-r--r--sc/source/filter/inc/qproform.hxx86
-rw-r--r--sc/source/filter/inc/qprostyle.hxx69
-rw-r--r--sc/source/filter/inc/root.hxx119
-rw-r--r--sc/source/filter/inc/rtfexp.hxx52
-rw-r--r--sc/source/filter/inc/rtfimp.hxx41
-rw-r--r--sc/source/filter/inc/rtfparse.hxx89
-rw-r--r--sc/source/filter/inc/scflt.hxx764
-rw-r--r--sc/source/filter/inc/scfobj.hxx45
-rw-r--r--sc/source/filter/inc/scmem.h37
-rw-r--r--sc/source/filter/inc/tokstack.hxx408
-rw-r--r--sc/source/filter/inc/tool.h164
-rw-r--r--sc/source/filter/inc/xcl97dum.hxx90
-rw-r--r--sc/source/filter/inc/xcl97esc.hxx201
-rw-r--r--sc/source/filter/inc/xcl97rec.hxx592
-rw-r--r--sc/source/filter/inc/xechart.hxx1275
-rw-r--r--sc/source/filter/inc/xecontent.hxx352
-rw-r--r--sc/source/filter/inc/xeescher.hxx435
-rw-r--r--sc/source/filter/inc/xeformula.hxx97
-rw-r--r--sc/source/filter/inc/xehelper.hxx451
-rw-r--r--sc/source/filter/inc/xelink.hxx221
-rw-r--r--sc/source/filter/inc/xename.hxx91
-rw-r--r--sc/source/filter/inc/xepage.hxx137
-rw-r--r--sc/source/filter/inc/xepivot.hxx486
-rw-r--r--sc/source/filter/inc/xerecord.hxx419
-rw-r--r--sc/source/filter/inc/xeroot.hxx175
-rw-r--r--sc/source/filter/inc/xestream.hxx355
-rw-r--r--sc/source/filter/inc/xestring.hxx350
-rw-r--r--sc/source/filter/inc/xestyle.hxx781
-rw-r--r--sc/source/filter/inc/xetable.hxx1089
-rw-r--r--sc/source/filter/inc/xeview.hxx180
-rw-r--r--sc/source/filter/inc/xichart.hxx1514
-rw-r--r--sc/source/filter/inc/xicontent.hxx311
-rw-r--r--sc/source/filter/inc/xiescher.hxx1275
-rw-r--r--sc/source/filter/inc/xiformula.hxx68
-rw-r--r--sc/source/filter/inc/xihelper.hxx369
-rw-r--r--sc/source/filter/inc/xilink.hxx210
-rw-r--r--sc/source/filter/inc/xiname.hxx100
-rw-r--r--sc/source/filter/inc/xipage.hxx82
-rw-r--r--sc/source/filter/inc/xipivot.hxx457
-rw-r--r--sc/source/filter/inc/xiroot.hxx219
-rw-r--r--sc/source/filter/inc/xistream.hxx529
-rw-r--r--sc/source/filter/inc/xistring.hxx121
-rw-r--r--sc/source/filter/inc/xistyle.hxx679
-rw-r--r--sc/source/filter/inc/xiview.hxx95
-rw-r--r--sc/source/filter/inc/xladdress.hxx197
-rwxr-xr-xsc/source/filter/inc/xlchart.hxx1486
-rw-r--r--sc/source/filter/inc/xlconst.hxx277
-rw-r--r--sc/source/filter/inc/xlcontent.hxx194
-rw-r--r--sc/source/filter/inc/xlescher.hxx450
-rw-r--r--sc/source/filter/inc/xlformula.hxx569
-rw-r--r--sc/source/filter/inc/xllink.hxx93
-rw-r--r--sc/source/filter/inc/xlname.hxx75
-rw-r--r--sc/source/filter/inc/xlpage.hxx156
-rw-r--r--sc/source/filter/inc/xlpivot.hxx817
-rw-r--r--sc/source/filter/inc/xlroot.hxx289
-rw-r--r--sc/source/filter/inc/xlstream.hxx53
-rw-r--r--sc/source/filter/inc/xlstring.hxx97
-rw-r--r--sc/source/filter/inc/xlstyle.hxx619
-rw-r--r--sc/source/filter/inc/xltable.hxx202
-rw-r--r--sc/source/filter/inc/xltools.hxx267
-rw-r--r--sc/source/filter/inc/xltracer.hxx148
-rw-r--r--sc/source/filter/inc/xlview.hxx178
-rw-r--r--sc/source/filter/lotus/expop.cxx412
-rw-r--r--sc/source/filter/lotus/export.cxx58
-rw-r--r--sc/source/filter/lotus/filter.cxx248
-rw-r--r--sc/source/filter/lotus/lotattr.cxx299
-rw-r--r--sc/source/filter/lotus/lotform.cxx2074
-rw-r--r--sc/source/filter/lotus/lotimpop.cxx473
-rw-r--r--sc/source/filter/lotus/lotread.cxx324
-rw-r--r--sc/source/filter/lotus/lotus.cxx102
-rw-r--r--sc/source/filter/lotus/makefile.mk69
-rw-r--r--sc/source/filter/lotus/memory.cxx139
-rw-r--r--sc/source/filter/lotus/op.cxx684
-rw-r--r--sc/source/filter/lotus/optab.cxx248
-rw-r--r--sc/source/filter/lotus/tool.cxx651
-rw-r--r--sc/source/filter/qpro/biff.cxx104
-rw-r--r--sc/source/filter/qpro/makefile.mk57
-rw-r--r--sc/source/filter/qpro/qpro.cxx230
-rw-r--r--sc/source/filter/qpro/qproform.cxx745
-rw-r--r--sc/source/filter/qpro/qprostyle.cxx167
-rw-r--r--sc/source/filter/rtf/eeimpars.cxx636
-rw-r--r--sc/source/filter/rtf/expbase.cxx107
-rw-r--r--sc/source/filter/rtf/makefile.mk59
-rw-r--r--sc/source/filter/rtf/rtfexp.cxx305
-rw-r--r--sc/source/filter/rtf/rtfimp.cxx75
-rw-r--r--sc/source/filter/rtf/rtfparse.cxx420
-rw-r--r--sc/source/filter/starcalc/makefile.mk56
-rw-r--r--sc/source/filter/starcalc/scflt.cxx2511
-rw-r--r--sc/source/filter/starcalc/scfobj.cxx104
-rw-r--r--sc/source/filter/xcl97/XclExpChangeTrack.cxx1248
-rw-r--r--sc/source/filter/xcl97/XclImpChangeTrack.cxx502
-rw-r--r--sc/source/filter/xcl97/makefile.mk62
-rw-r--r--sc/source/filter/xcl97/xcl97dum.cxx163
-rw-r--r--sc/source/filter/xcl97/xcl97esc.cxx512
-rw-r--r--sc/source/filter/xcl97/xcl97rec.cxx1448
-rw-r--r--sc/source/filter/xml/XMLCalculationSettingsContext.cxx273
-rw-r--r--sc/source/filter/xml/XMLCalculationSettingsContext.hxx111
-rw-r--r--sc/source/filter/xml/XMLCellRangeSourceContext.cxx133
-rw-r--r--sc/source/filter/xml/XMLCellRangeSourceContext.hxx80
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx817
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx98
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx935
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx249
-rwxr-xr-xsc/source/filter/xml/XMLCodeNameProvider.cxx204
-rwxr-xr-xsc/source/filter/xml/XMLCodeNameProvider.hxx70
-rw-r--r--sc/source/filter/xml/XMLColumnRowGroupExport.cxx187
-rw-r--r--sc/source/filter/xml/XMLColumnRowGroupExport.hxx73
-rw-r--r--sc/source/filter/xml/XMLConsolidationContext.cxx160
-rw-r--r--sc/source/filter/xml/XMLConsolidationContext.hxx73
-rw-r--r--sc/source/filter/xml/XMLConverter.cxx670
-rw-r--r--sc/source/filter/xml/XMLConverter.hxx177
-rw-r--r--sc/source/filter/xml/XMLDDELinksContext.cxx490
-rw-r--r--sc/source/filter/xml/XMLDDELinksContext.hxx230
-rw-r--r--sc/source/filter/xml/XMLDetectiveContext.cxx265
-rw-r--r--sc/source/filter/xml/XMLDetectiveContext.hxx175
-rw-r--r--sc/source/filter/xml/XMLEmptyContext.cxx63
-rw-r--r--sc/source/filter/xml/XMLEmptyContext.hxx57
-rw-r--r--sc/source/filter/xml/XMLExportDDELinks.cxx221
-rw-r--r--sc/source/filter/xml/XMLExportDDELinks.hxx52
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.cxx898
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.hxx80
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.cxx699
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.hxx62
-rw-r--r--sc/source/filter/xml/XMLExportIterator.cxx892
-rw-r--r--sc/source/filter/xml/XMLExportIterator.hxx413
-rw-r--r--sc/source/filter/xml/XMLExportSharedData.cxx163
-rw-r--r--sc/source/filter/xml/XMLExportSharedData.hxx90
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.cxx1267
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.hxx294
-rw-r--r--sc/source/filter/xml/XMLStylesImportHelper.cxx587
-rw-r--r--sc/source/filter/xml/XMLStylesImportHelper.hxx195
-rw-r--r--sc/source/filter/xml/XMLTableHeaderFooterContext.cxx268
-rw-r--r--sc/source/filter/xml/XMLTableHeaderFooterContext.hxx114
-rw-r--r--sc/source/filter/xml/XMLTableMasterPageExport.cxx178
-rw-r--r--sc/source/filter/xml/XMLTableMasterPageExport.hxx66
-rw-r--r--sc/source/filter/xml/XMLTableShapeImportHelper.cxx215
-rw-r--r--sc/source/filter/xml/XMLTableShapeImportHelper.hxx62
-rw-r--r--sc/source/filter/xml/XMLTableShapeResizer.cxx385
-rw-r--r--sc/source/filter/xml/XMLTableShapeResizer.hxx81
-rw-r--r--sc/source/filter/xml/XMLTableShapesContext.cxx87
-rw-r--r--sc/source/filter/xml/XMLTableShapesContext.hxx55
-rw-r--r--sc/source/filter/xml/XMLTableSourceContext.cxx146
-rw-r--r--sc/source/filter/xml/XMLTableSourceContext.hxx63
-rw-r--r--sc/source/filter/xml/XMLTextPContext.cxx224
-rw-r--r--sc/source/filter/xml/XMLTextPContext.hxx72
-rw-r--r--sc/source/filter/xml/XMLTrackedChangesContext.cxx2025
-rw-r--r--sc/source/filter/xml/XMLTrackedChangesContext.hxx62
-rw-r--r--sc/source/filter/xml/makefile.mk109
-rw-r--r--sc/source/filter/xml/sheetdata.cxx283
-rw-r--r--sc/source/filter/xml/xmlannoi.cxx220
-rw-r--r--sc/source/filter/xml/xmlannoi.hxx122
-rw-r--r--sc/source/filter/xml/xmlbodyi.cxx338
-rw-r--r--sc/source/filter/xml/xmlbodyi.hxx61
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx1127
-rw-r--r--sc/source/filter/xml/xmlcelli.hxx130
-rw-r--r--sc/source/filter/xml/xmlcoli.cxx333
-rw-r--r--sc/source/filter/xml/xmlcoli.hxx93
-rw-r--r--sc/source/filter/xml/xmlconti.cxx107
-rw-r--r--sc/source/filter/xml/xmlconti.hxx63
-rw-r--r--sc/source/filter/xml/xmlcvali.cxx696
-rw-r--r--sc/source/filter/xml/xmlcvali.hxx61
-rw-r--r--sc/source/filter/xml/xmldpimp.cxx1835
-rw-r--r--sc/source/filter/xml/xmldpimp.hxx693
-rw-r--r--sc/source/filter/xml/xmldrani.cxx991
-rw-r--r--sc/source/filter/xml/xmldrani.hxx362
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx4611
-rw-r--r--sc/source/filter/xml/xmlexprt.hxx293
-rw-r--r--sc/source/filter/xml/xmlexternaltabi.cxx437
-rw-r--r--sc/source/filter/xml/xmlexternaltabi.hxx176
-rw-r--r--sc/source/filter/xml/xmlfilti.cxx785
-rw-r--r--sc/source/filter/xml/xmlfilti.hxx310
-rw-r--r--sc/source/filter/xml/xmlfonte.cxx152
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx3048
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx1048
-rw-r--r--sc/source/filter/xml/xmllabri.cxx145
-rw-r--r--sc/source/filter/xml/xmllabri.hxx90
-rw-r--r--sc/source/filter/xml/xmlnexpi.cxx250
-rw-r--r--sc/source/filter/xml/xmlnexpi.hxx101
-rw-r--r--sc/source/filter/xml/xmlrowi.cxx369
-rw-r--r--sc/source/filter/xml/xmlrowi.hxx93
-rw-r--r--sc/source/filter/xml/xmlsceni.cxx173
-rw-r--r--sc/source/filter/xml/xmlsceni.hxx70
-rw-r--r--sc/source/filter/xml/xmlsorti.cxx279
-rw-r--r--sc/source/filter/xml/xmlsorti.hxx106
-rw-r--r--sc/source/filter/xml/xmlstyle.cxx1876
-rw-r--r--sc/source/filter/xml/xmlstyle.hxx349
-rw-r--r--sc/source/filter/xml/xmlstyli.cxx1087
-rw-r--r--sc/source/filter/xml/xmlstyli.hxx329
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx833
-rw-r--r--sc/source/filter/xml/xmlsubti.hxx193
-rw-r--r--sc/source/filter/xml/xmltabi.cxx422
-rw-r--r--sc/source/filter/xml/xmltabi.hxx78
-rw-r--r--sc/source/filter/xml/xmlwrap.cxx1024
-rw-r--r--sc/source/ui/Accessibility/AccessibilityHints.cxx112
-rw-r--r--sc/source/ui/Accessibility/AccessibleCell.cxx459
-rw-r--r--sc/source/ui/Accessibility/AccessibleCellBase.cxx345
-rw-r--r--sc/source/ui/Accessibility/AccessibleContextBase.cxx628
-rw-r--r--sc/source/ui/Accessibility/AccessibleCsvControl.cxx1680
-rw-r--r--sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx739
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocument.cxx2120
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocumentBase.cxx51
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx1942
-rw-r--r--sc/source/ui/Accessibility/AccessibleEditObject.cxx358
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenu.cxx398
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx205
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx127
-rw-r--r--sc/source/ui/Accessibility/AccessibleGlobal.cxx95
-rw-r--r--sc/source/ui/Accessibility/AccessiblePageHeader.cxx441
-rw-r--r--sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx330
-rw-r--r--sc/source/ui/Accessibility/AccessiblePreviewCell.cxx316
-rw-r--r--sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx443
-rw-r--r--sc/source/ui/Accessibility/AccessiblePreviewTable.cxx769
-rw-r--r--sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx999
-rw-r--r--sc/source/ui/Accessibility/AccessibleTableBase.cxx495
-rw-r--r--sc/source/ui/Accessibility/AccessibleText.cxx1911
-rw-r--r--sc/source/ui/Accessibility/DrawModelBroadcaster.cxx92
-rw-r--r--sc/source/ui/Accessibility/makefile.mk94
-rw-r--r--sc/source/ui/app/client.cxx256
-rw-r--r--sc/source/ui/app/drwtrans.cxx804
-rw-r--r--sc/source/ui/app/inputhdl.cxx3826
-rw-r--r--sc/source/ui/app/inputwin.cxx1819
-rw-r--r--sc/source/ui/app/lnktrans.cxx97
-rw-r--r--sc/source/ui/app/makefile.mk75
-rw-r--r--sc/source/ui/app/msgpool.cxx123
-rw-r--r--sc/source/ui/app/rfindlst.cxx67
-rw-r--r--sc/source/ui/app/scdll.cxx419
-rw-r--r--sc/source/ui/app/scmod.cxx2276
-rw-r--r--sc/source/ui/app/scmod2.cxx107
-rw-r--r--sc/source/ui/app/seltrans.cxx449
-rw-r--r--sc/source/ui/app/template.cxx79
-rw-r--r--sc/source/ui/app/transobj.cxx867
-rw-r--r--sc/source/ui/app/typemap.cxx135
-rw-r--r--sc/source/ui/app/uiitems.cxx737
-rw-r--r--sc/source/ui/app/wtcdummy.cxx65
-rw-r--r--sc/source/ui/attrdlg/attrdlg.cxx158
-rw-r--r--sc/source/ui/attrdlg/condfrmt.cxx829
-rw-r--r--sc/source/ui/attrdlg/makefile.mk63
-rw-r--r--sc/source/ui/attrdlg/scabstdlg.cxx56
-rw-r--r--sc/source/ui/attrdlg/scdlgfact.cxx1600
-rw-r--r--sc/source/ui/attrdlg/scdlgfact.hxx593
-rw-r--r--sc/source/ui/attrdlg/scuiexp.cxx55
-rw-r--r--sc/source/ui/attrdlg/tabpages.cxx250
-rw-r--r--sc/source/ui/cctrl/cbuttonw.cxx178
-rw-r--r--sc/source/ui/cctrl/dpcontrol.cxx1422
-rw-r--r--sc/source/ui/cctrl/dpcontrol.src79
-rw-r--r--sc/source/ui/cctrl/editfield.cxx84
-rw-r--r--sc/source/ui/cctrl/makefile.mk71
-rw-r--r--sc/source/ui/cctrl/popmenu.cxx48
-rw-r--r--sc/source/ui/cctrl/tbinsert.cxx232
-rw-r--r--sc/source/ui/cctrl/tbzoomsliderctrl.cxx540
-rw-r--r--sc/source/ui/dbgui/asciiopt.cxx480
-rw-r--r--sc/source/ui/dbgui/asciiopt.hrc71
-rw-r--r--sc/source/ui/dbgui/asciiopt.src305
-rw-r--r--sc/source/ui/dbgui/consdlg.cxx655
-rw-r--r--sc/source/ui/dbgui/consdlg.hrc61
-rw-r--r--sc/source/ui/dbgui/consdlg.src217
-rw-r--r--sc/source/ui/dbgui/csvcontrol.cxx337
-rw-r--r--sc/source/ui/dbgui/csvgrid.cxx1355
-rw-r--r--sc/source/ui/dbgui/csvruler.cxx682
-rw-r--r--sc/source/ui/dbgui/csvsplits.cxx120
-rw-r--r--sc/source/ui/dbgui/csvtablebox.cxx464
-rw-r--r--sc/source/ui/dbgui/dapidata.cxx229
-rw-r--r--sc/source/ui/dbgui/dapitype.cxx142
-rw-r--r--sc/source/ui/dbgui/dapitype.hrc53
-rw-r--r--sc/source/ui/dbgui/dapitype.src308
-rw-r--r--sc/source/ui/dbgui/dbnamdlg.cxx721
-rw-r--r--sc/source/ui/dbgui/dpgroupdlg.cxx360
-rw-r--r--sc/source/ui/dbgui/dpgroupdlg.hrc64
-rw-r--r--sc/source/ui/dbgui/dpgroupdlg.src270
-rw-r--r--sc/source/ui/dbgui/expftext.cxx95
-rw-r--r--sc/source/ui/dbgui/fieldwnd.cxx776
-rw-r--r--sc/source/ui/dbgui/filtdlg.cxx1186
-rw-r--r--sc/source/ui/dbgui/foptmgr.cxx337
-rw-r--r--sc/source/ui/dbgui/imoptdlg.cxx90
-rw-r--r--sc/source/ui/dbgui/imoptdlg.hrc44
-rw-r--r--sc/source/ui/dbgui/imoptdlg.src141
-rw-r--r--sc/source/ui/dbgui/makefile.mk122
-rw-r--r--sc/source/ui/dbgui/outline.src51
-rw-r--r--sc/source/ui/dbgui/pfiltdlg.cxx620
-rw-r--r--sc/source/ui/dbgui/pivot.hrc81
-rw-r--r--sc/source/ui/dbgui/pivot.src328
-rw-r--r--sc/source/ui/dbgui/pvfundlg.cxx790
-rw-r--r--sc/source/ui/dbgui/pvfundlg.hrc83
-rw-r--r--sc/source/ui/dbgui/pvfundlg.src515
-rw-r--r--sc/source/ui/dbgui/pvglob.hxx42
-rw-r--r--sc/source/ui/dbgui/pvlaydlg.cxx1823
-rw-r--r--sc/source/ui/dbgui/scendlg.cxx243
-rw-r--r--sc/source/ui/dbgui/scendlg.hrc57
-rw-r--r--sc/source/ui/dbgui/scendlg.src195
-rw-r--r--sc/source/ui/dbgui/scuiasciiopt.cxx723
-rw-r--r--sc/source/ui/dbgui/scuiimoptdlg.cxx316
-rw-r--r--sc/source/ui/dbgui/sfiltdlg.cxx530
-rw-r--r--sc/source/ui/dbgui/sortdlg.cxx107
-rw-r--r--sc/source/ui/dbgui/subtdlg.cxx69
-rw-r--r--sc/source/ui/dbgui/textimportoptions.cxx121
-rw-r--r--sc/source/ui/dbgui/textimportoptions.src110
-rw-r--r--sc/source/ui/dbgui/tpsort.cxx1080
-rw-r--r--sc/source/ui/dbgui/tpsubt.cxx686
-rw-r--r--sc/source/ui/dbgui/validate.cxx1021
-rw-r--r--sc/source/ui/dbgui/validate.src407
-rw-r--r--sc/source/ui/docshell/arealink.cxx530
-rw-r--r--sc/source/ui/docshell/autostyl.cxx244
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx1503
-rw-r--r--sc/source/ui/docshell/dbdocimp.cxx720
-rw-r--r--sc/source/ui/docshell/docfunc.cxx4881
-rw-r--r--sc/source/ui/docshell/docsh.cxx2948
-rw-r--r--sc/source/ui/docshell/docsh2.cxx263
-rw-r--r--sc/source/ui/docshell/docsh3.cxx1409
-rw-r--r--sc/source/ui/docshell/docsh4.cxx2734
-rw-r--r--sc/source/ui/docshell/docsh5.cxx995
-rw-r--r--sc/source/ui/docshell/docsh6.cxx469
-rw-r--r--sc/source/ui/docshell/docsh7.cxx45
-rw-r--r--sc/source/ui/docshell/docsh8.cxx1098
-rw-r--r--sc/source/ui/docshell/docshimp.hxx57
-rw-r--r--sc/source/ui/docshell/editable.cxx162
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx2456
-rw-r--r--sc/source/ui/docshell/hiranges.cxx53
-rw-r--r--sc/source/ui/docshell/impex.cxx2094
-rw-r--r--sc/source/ui/docshell/makefile.mk139
-rw-r--r--sc/source/ui/docshell/olinefun.cxx790
-rw-r--r--sc/source/ui/docshell/pagedata.cxx139
-rw-r--r--sc/source/ui/docshell/pntlock.cxx61
-rw-r--r--sc/source/ui/docshell/servobj.cxx273
-rw-r--r--sc/source/ui/docshell/sizedev.cxx77
-rw-r--r--sc/source/ui/docshell/tablink.cxx621
-rw-r--r--sc/source/ui/docshell/tpstat.cxx101
-rw-r--r--sc/source/ui/docshell/tpstat.hrc36
-rw-r--r--sc/source/ui/docshell/tpstat.src112
-rw-r--r--sc/source/ui/drawfunc/chartsh.cxx83
-rw-r--r--sc/source/ui/drawfunc/drawsh.cxx503
-rw-r--r--sc/source/ui/drawfunc/drawsh2.cxx399
-rw-r--r--sc/source/ui/drawfunc/drawsh4.cxx115
-rw-r--r--sc/source/ui/drawfunc/drawsh5.cxx760
-rw-r--r--sc/source/ui/drawfunc/drformsh.cxx83
-rw-r--r--sc/source/ui/drawfunc/drformsh.src250
-rw-r--r--sc/source/ui/drawfunc/drtxtob.cxx1095
-rw-r--r--sc/source/ui/drawfunc/drtxtob1.cxx156
-rw-r--r--sc/source/ui/drawfunc/drtxtob2.cxx299
-rw-r--r--sc/source/ui/drawfunc/fuconarc.cxx234
-rw-r--r--sc/source/ui/drawfunc/fuconcustomshape.cxx288
-rw-r--r--sc/source/ui/drawfunc/fuconpol.cxx355
-rw-r--r--sc/source/ui/drawfunc/fuconrec.cxx315
-rw-r--r--sc/source/ui/drawfunc/fuconstr.cxx335
-rw-r--r--sc/source/ui/drawfunc/fuconuno.cxx190
-rw-r--r--sc/source/ui/drawfunc/fudraw.cxx863
-rw-r--r--sc/source/ui/drawfunc/fuins1.cxx447
-rw-r--r--sc/source/ui/drawfunc/fuins2.cxx849
-rw-r--r--sc/source/ui/drawfunc/fumark.cxx290
-rw-r--r--sc/source/ui/drawfunc/fupoor.cxx385
-rw-r--r--sc/source/ui/drawfunc/fusel.cxx649
-rw-r--r--sc/source/ui/drawfunc/fusel2.cxx185
-rw-r--r--sc/source/ui/drawfunc/futext.cxx882
-rw-r--r--sc/source/ui/drawfunc/futext2.cxx307
-rw-r--r--sc/source/ui/drawfunc/futext3.cxx249
-rw-r--r--sc/source/ui/drawfunc/graphsh.cxx148
-rw-r--r--sc/source/ui/drawfunc/makefile.mk88
-rw-r--r--sc/source/ui/drawfunc/mediash.cxx143
-rw-r--r--sc/source/ui/drawfunc/objdraw.src1547
-rw-r--r--sc/source/ui/drawfunc/oleobjsh.cxx83
-rw-r--r--sc/source/ui/formdlg/dwfunctr.cxx1182
-rw-r--r--sc/source/ui/formdlg/dwfunctr.hrc37
-rw-r--r--sc/source/ui/formdlg/dwfunctr.src155
-rw-r--r--sc/source/ui/formdlg/formdata.cxx61
-rw-r--r--sc/source/ui/formdlg/formdlgs.src29
-rw-r--r--sc/source/ui/formdlg/formula.cxx667
-rw-r--r--sc/source/ui/formdlg/makefile.mk55
-rw-r--r--sc/source/ui/formdlg/privsplt.cxx422
-rw-r--r--sc/source/ui/inc/AccessibilityHints.hxx97
-rw-r--r--sc/source/ui/inc/AccessibleCell.hxx173
-rw-r--r--sc/source/ui/inc/AccessibleCellBase.hxx153
-rw-r--r--sc/source/ui/inc/AccessibleContextBase.hxx344
-rw-r--r--sc/source/ui/inc/AccessibleCsvControl.hxx666
-rw-r--r--sc/source/ui/inc/AccessibleDataPilotControl.hxx145
-rw-r--r--sc/source/ui/inc/AccessibleDocument.hxx328
-rw-r--r--sc/source/ui/inc/AccessibleDocumentBase.hxx50
-rw-r--r--sc/source/ui/inc/AccessibleDocumentPagePreview.hxx159
-rw-r--r--sc/source/ui/inc/AccessibleEditObject.hxx178
-rw-r--r--sc/source/ui/inc/AccessiblePageHeader.hxx111
-rw-r--r--sc/source/ui/inc/AccessiblePageHeaderArea.hxx138
-rw-r--r--sc/source/ui/inc/AccessiblePreviewCell.hxx121
-rw-r--r--sc/source/ui/inc/AccessiblePreviewHeaderCell.hxx152
-rw-r--r--sc/source/ui/inc/AccessiblePreviewTable.hxx182
-rw-r--r--sc/source/ui/inc/AccessibleSpreadsheet.hxx289
-rw-r--r--sc/source/ui/inc/AccessibleTableBase.hxx298
-rw-r--r--sc/source/ui/inc/AccessibleText.hxx359
-rw-r--r--sc/source/ui/inc/ChartRangeSelectionListener.hxx79
-rw-r--r--sc/source/ui/inc/DrawModelBroadcaster.hxx59
-rw-r--r--sc/source/ui/inc/IAnyRefDialog.hxx64
-rw-r--r--sc/source/ui/inc/ScDevChart.hxx84
-rw-r--r--sc/source/ui/inc/acredlin.hrc75
-rw-r--r--sc/source/ui/inc/acredlin.hxx264
-rw-r--r--sc/source/ui/inc/anyrefdg.hxx281
-rw-r--r--sc/source/ui/inc/areasave.hxx84
-rw-r--r--sc/source/ui/inc/areasdlg.hxx108
-rw-r--r--sc/source/ui/inc/asciiopt.hxx211
-rw-r--r--sc/source/ui/inc/attrdlg.hrc51
-rw-r--r--sc/source/ui/inc/attrdlg.hxx69
-rw-r--r--sc/source/ui/inc/auditsh.hxx59
-rw-r--r--sc/source/ui/inc/autofmt.hxx210
-rw-r--r--sc/source/ui/inc/autostyl.hxx68
-rw-r--r--sc/source/ui/inc/cbutton.hxx84
-rw-r--r--sc/source/ui/inc/cellsh.hxx106
-rw-r--r--sc/source/ui/inc/chartsh.hxx52
-rw-r--r--sc/source/ui/inc/client.hxx64
-rw-r--r--sc/source/ui/inc/colrowba.hxx110
-rw-r--r--sc/source/ui/inc/condfrmt.hrc73
-rw-r--r--sc/source/ui/inc/condfrmt.hxx155
-rw-r--r--sc/source/ui/inc/conflictsdlg.hrc43
-rw-r--r--sc/source/ui/inc/conflictsdlg.hxx216
-rw-r--r--sc/source/ui/inc/consdlg.hxx136
-rw-r--r--sc/source/ui/inc/content.hxx169
-rw-r--r--sc/source/ui/inc/corodlg.hxx81
-rw-r--r--sc/source/ui/inc/crdlg.hxx66
-rw-r--r--sc/source/ui/inc/crnrdlg.hrc46
-rw-r--r--sc/source/ui/inc/crnrdlg.hxx112
-rw-r--r--sc/source/ui/inc/csvcontrol.hxx432
-rw-r--r--sc/source/ui/inc/csvgrid.hxx358
-rw-r--r--sc/source/ui/inc/csvruler.hxx200
-rw-r--r--sc/source/ui/inc/csvsplits.hxx103
-rw-r--r--sc/source/ui/inc/csvtablebox.hxx161
-rw-r--r--sc/source/ui/inc/dapidata.hxx72
-rw-r--r--sc/source/ui/inc/dapitype.hxx95
-rw-r--r--sc/source/ui/inc/dbdocfun.hxx124
-rw-r--r--sc/source/ui/inc/dbfunc.hxx136
-rw-r--r--sc/source/ui/inc/dbnamdlg.hrc51
-rw-r--r--sc/source/ui/inc/dbnamdlg.hxx127
-rw-r--r--sc/source/ui/inc/delcldlg.hxx64
-rw-r--r--sc/source/ui/inc/delcodlg.hxx74
-rw-r--r--sc/source/ui/inc/docfunc.hxx189
-rw-r--r--sc/source/ui/inc/docsh.hxx468
-rw-r--r--sc/source/ui/inc/dpcontrol.hrc40
-rw-r--r--sc/source/ui/inc/dpcontrol.hxx363
-rw-r--r--sc/source/ui/inc/dpgroupdlg.hxx172
-rw-r--r--sc/source/ui/inc/drawsh.hxx94
-rw-r--r--sc/source/ui/inc/drawutil.hxx51
-rw-r--r--sc/source/ui/inc/drawview.hxx151
-rw-r--r--sc/source/ui/inc/drformsh.hxx55
-rw-r--r--sc/source/ui/inc/drtxtob.hxx89
-rw-r--r--sc/source/ui/inc/drwtrans.hxx110
-rw-r--r--sc/source/ui/inc/dwfunctr.hxx158
-rw-r--r--sc/source/ui/inc/editable.hxx86
-rw-r--r--sc/source/ui/inc/editfield.hxx50
-rw-r--r--sc/source/ui/inc/editsh.hxx86
-rw-r--r--sc/source/ui/inc/expftext.hxx45
-rwxr-xr-xsc/source/ui/inc/fieldwnd.hxx220
-rw-r--r--sc/source/ui/inc/filldlg.hxx144
-rw-r--r--sc/source/ui/inc/filtdlg.hxx267
-rw-r--r--sc/source/ui/inc/filter.hrc82
-rw-r--r--sc/source/ui/inc/foptmgr.hxx121
-rw-r--r--sc/source/ui/inc/formatsh.hxx79
-rw-r--r--sc/source/ui/inc/formdata.hxx66
-rw-r--r--sc/source/ui/inc/formula.hxx138
-rw-r--r--sc/source/ui/inc/fuconarc.hxx62
-rw-r--r--sc/source/ui/inc/fuconcustomshape.hxx61
-rw-r--r--sc/source/ui/inc/fuconpol.hxx63
-rw-r--r--sc/source/ui/inc/fuconrec.hxx62
-rw-r--r--sc/source/ui/inc/fuconstr.hxx67
-rw-r--r--sc/source/ui/inc/fuconuno.hxx67
-rw-r--r--sc/source/ui/inc/fudraw.hxx77
-rw-r--r--sc/source/ui/inc/fuedipo.hxx60
-rw-r--r--sc/source/ui/inc/fuinsert.hxx85
-rw-r--r--sc/source/ui/inc/fumark.hxx74
-rw-r--r--sc/source/ui/inc/funcpage.hxx128
-rw-r--r--sc/source/ui/inc/funcutl.hxx198
-rw-r--r--sc/source/ui/inc/fupoor.hxx136
-rw-r--r--sc/source/ui/inc/fusel.hxx81
-rw-r--r--sc/source/ui/inc/futext.hxx81
-rw-r--r--sc/source/ui/inc/graphsh.hxx57
-rw-r--r--sc/source/ui/inc/gridmerg.hxx64
-rw-r--r--sc/source/ui/inc/gridwin.hxx426
-rw-r--r--sc/source/ui/inc/groupdlg.hxx61
-rw-r--r--sc/source/ui/inc/hdrcont.hxx141
-rw-r--r--sc/source/ui/inc/hfedtdlg.hxx56
-rw-r--r--sc/source/ui/inc/highred.hrc71
-rw-r--r--sc/source/ui/inc/highred.hxx124
-rw-r--r--sc/source/ui/inc/hintwin.hxx54
-rw-r--r--sc/source/ui/inc/hiranges.hxx64
-rw-r--r--sc/source/ui/inc/imoptdlg.hxx108
-rw-r--r--sc/source/ui/inc/impex.hxx191
-rw-r--r--sc/source/ui/inc/inputhdl.hxx296
-rw-r--r--sc/source/ui/inc/inputwin.hxx228
-rw-r--r--sc/source/ui/inc/inscldlg.hxx62
-rw-r--r--sc/source/ui/inc/inscodlg.hxx122
-rw-r--r--sc/source/ui/inc/instbdlg.hrc52
-rw-r--r--sc/source/ui/inc/instbdlg.hxx136
-rw-r--r--sc/source/ui/inc/invmerge.hxx61
-rw-r--r--sc/source/ui/inc/lbseldlg.hxx70
-rw-r--r--sc/source/ui/inc/linkarea.hrc42
-rw-r--r--sc/source/ui/inc/linkarea.hxx106
-rw-r--r--sc/source/ui/inc/lnktrans.hxx53
-rw-r--r--sc/source/ui/inc/makefile.mk26
-rw-r--r--sc/source/ui/inc/mediash.hxx54
-rw-r--r--sc/source/ui/inc/miscdlgs.hrc188
-rw-r--r--sc/source/ui/inc/msgpool.hxx78
-rw-r--r--sc/source/ui/inc/mtrindlg.hxx76
-rw-r--r--sc/source/ui/inc/mvtabdlg.hxx79
-rw-r--r--sc/source/ui/inc/namecrea.hxx59
-rw-r--r--sc/source/ui/inc/namedlg.hrc52
-rw-r--r--sc/source/ui/inc/namedlg.hxx123
-rw-r--r--sc/source/ui/inc/namepast.hxx62
-rw-r--r--sc/source/ui/inc/navcitem.hxx55
-rw-r--r--sc/source/ui/inc/navipi.hxx366
-rw-r--r--sc/source/ui/inc/navsett.hxx59
-rw-r--r--sc/source/ui/inc/notemark.hxx80
-rw-r--r--sc/source/ui/inc/oleobjsh.hxx52
-rw-r--r--sc/source/ui/inc/olinefun.hxx68
-rw-r--r--sc/source/ui/inc/olinewin.hxx244
-rw-r--r--sc/source/ui/inc/opredlin.hrc38
-rw-r--r--sc/source/ui/inc/opredlin.hxx86
-rw-r--r--sc/source/ui/inc/optdlg.hrc192
-rw-r--r--sc/source/ui/inc/optload.hrc40
-rw-r--r--sc/source/ui/inc/optload.hxx68
-rw-r--r--sc/source/ui/inc/optsolver.hrc98
-rw-r--r--sc/source/ui/inc/optsolver.hxx264
-rw-r--r--sc/source/ui/inc/output.hxx272
-rw-r--r--sc/source/ui/inc/pagedata.hxx95
-rw-r--r--sc/source/ui/inc/parawin.hxx171
-rw-r--r--sc/source/ui/inc/pfiltdlg.hxx145
-rw-r--r--sc/source/ui/inc/pfuncache.hxx125
-rw-r--r--sc/source/ui/inc/pgbrksh.hxx53
-rw-r--r--sc/source/ui/inc/pivotsh.hxx61
-rw-r--r--sc/source/ui/inc/pntlock.hxx67
-rw-r--r--sc/source/ui/inc/popmenu.hxx53
-rw-r--r--sc/source/ui/inc/preview.hxx168
-rw-r--r--sc/source/ui/inc/prevloc.hxx157
-rw-r--r--sc/source/ui/inc/prevwsh.hxx137
-rw-r--r--sc/source/ui/inc/printfun.hxx368
-rw-r--r--sc/source/ui/inc/privsplt.hxx86
-rw-r--r--sc/source/ui/inc/protectiondlg.hrc44
-rw-r--r--sc/source/ui/inc/protectiondlg.hxx82
-rw-r--r--sc/source/ui/inc/pvfundlg.hxx244
-rw-r--r--sc/source/ui/inc/pvlaydlg.hxx239
-rw-r--r--sc/source/ui/inc/redcom.hxx70
-rw-r--r--sc/source/ui/inc/reffact.hxx122
-rw-r--r--sc/source/ui/inc/refundo.hxx69
-rw-r--r--sc/source/ui/inc/retypepassdlg.hrc71
-rw-r--r--sc/source/ui/inc/retypepassdlg.hxx174
-rw-r--r--sc/source/ui/inc/rfindlst.hxx75
-rw-r--r--sc/source/ui/inc/scendlg.hxx80
-rw-r--r--sc/source/ui/inc/scui_def.hxx57
-rw-r--r--sc/source/ui/inc/scuiasciiopt.hxx147
-rw-r--r--sc/source/ui/inc/scuiautofmt.hxx88
-rw-r--r--sc/source/ui/inc/scuiimoptdlg.hxx78
-rw-r--r--sc/source/ui/inc/scuitphfedit.hxx165
-rw-r--r--sc/source/ui/inc/select.hxx127
-rw-r--r--sc/source/ui/inc/selectionstate.hxx79
-rw-r--r--sc/source/ui/inc/seltrans.hxx81
-rw-r--r--sc/source/ui/inc/servobj.hxx76
-rw-r--r--sc/source/ui/inc/sharedocdlg.hrc44
-rw-r--r--sc/source/ui/inc/sharedocdlg.hxx76
-rw-r--r--sc/source/ui/inc/shtabdlg.hxx75
-rw-r--r--sc/source/ui/inc/simpref.hrc37
-rw-r--r--sc/source/ui/inc/simpref.hxx122
-rw-r--r--sc/source/ui/inc/sizedev.hxx55
-rw-r--r--sc/source/ui/inc/solveroptions.hrc47
-rw-r--r--sc/source/ui/inc/solveroptions.hxx123
-rw-r--r--sc/source/ui/inc/solverutil.hxx50
-rw-r--r--sc/source/ui/inc/solvrdlg.hrc46
-rw-r--r--sc/source/ui/inc/solvrdlg.hxx109
-rw-r--r--sc/source/ui/inc/sortdlg.hrc90
-rw-r--r--sc/source/ui/inc/sortdlg.hxx87
-rw-r--r--sc/source/ui/inc/spelldialog.hxx103
-rw-r--r--sc/source/ui/inc/spelleng.hxx169
-rw-r--r--sc/source/ui/inc/spellparam.hxx87
-rw-r--r--sc/source/ui/inc/strindlg.hxx66
-rw-r--r--sc/source/ui/inc/styledlg.hrc39
-rw-r--r--sc/source/ui/inc/styledlg.hxx59
-rw-r--r--sc/source/ui/inc/submenu.hrc68
-rw-r--r--sc/source/ui/inc/subtdlg.hrc64
-rw-r--r--sc/source/ui/inc/subtdlg.hxx56
-rw-r--r--sc/source/ui/inc/tabbgcolordlg.hxx78
-rw-r--r--sc/source/ui/inc/tabcont.hxx87
-rw-r--r--sc/source/ui/inc/tabopdlg.hrc50
-rw-r--r--sc/source/ui/inc/tabopdlg.hxx114
-rw-r--r--sc/source/ui/inc/tabpages.hxx83
-rw-r--r--sc/source/ui/inc/tabpopsh.hxx53
-rw-r--r--sc/source/ui/inc/tabsplit.hxx60
-rw-r--r--sc/source/ui/inc/tabview.hxx533
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx442
-rw-r--r--sc/source/ui/inc/target.hxx52
-rw-r--r--sc/source/ui/inc/tbinsert.hrc32
-rw-r--r--sc/source/ui/inc/tbinsert.hxx88
-rw-r--r--sc/source/ui/inc/tbzoomsliderctrl.hxx87
-rw-r--r--sc/source/ui/inc/textdlgs.hxx72
-rw-r--r--sc/source/ui/inc/textimportoptions.hrc42
-rw-r--r--sc/source/ui/inc/textimportoptions.hxx76
-rw-r--r--sc/source/ui/inc/tpcalc.hxx102
-rw-r--r--sc/source/ui/inc/tphf.hxx103
-rw-r--r--sc/source/ui/inc/tphfedit.hxx239
-rw-r--r--sc/source/ui/inc/tpprint.hxx56
-rw-r--r--sc/source/ui/inc/tpsort.hxx222
-rw-r--r--sc/source/ui/inc/tpstat.hxx65
-rw-r--r--sc/source/ui/inc/tpsubt.hxx188
-rw-r--r--sc/source/ui/inc/tptable.hxx115
-rw-r--r--sc/source/ui/inc/tpusrlst.hxx117
-rw-r--r--sc/source/ui/inc/tpview.hxx171
-rw-r--r--sc/source/ui/inc/transobj.hxx115
-rw-r--r--sc/source/ui/inc/ui_pch.hxx332
-rw-r--r--sc/source/ui/inc/uiitems.hxx378
-rw-r--r--sc/source/ui/inc/undobase.hxx171
-rw-r--r--sc/source/ui/inc/undoblk.hxx988
-rw-r--r--sc/source/ui/inc/undocell.hxx366
-rw-r--r--sc/source/ui/inc/undodat.hxx535
-rw-r--r--sc/source/ui/inc/undodraw.hxx63
-rw-r--r--sc/source/ui/inc/undoolk.hxx44
-rw-r--r--sc/source/ui/inc/undostyl.hxx117
-rw-r--r--sc/source/ui/inc/undotab.hxx543
-rw-r--r--sc/source/ui/inc/undoutil.hxx66
-rw-r--r--sc/source/ui/inc/validate.hrc88
-rw-r--r--sc/source/ui/inc/validate.hxx347
-rw-r--r--sc/source/ui/inc/viewdata.hxx557
-rw-r--r--sc/source/ui/inc/viewfunc.hxx369
-rw-r--r--sc/source/ui/inc/viewutil.hxx116
-rw-r--r--sc/source/ui/inc/warnbox.hxx74
-rw-r--r--sc/source/ui/miscdlgs/acredlin.cxx2139
-rw-r--r--sc/source/ui/miscdlgs/acredlin.src258
-rw-r--r--sc/source/ui/miscdlgs/anyrefdg.cxx1011
-rw-r--r--sc/source/ui/miscdlgs/autofmt.cxx979
-rw-r--r--sc/source/ui/miscdlgs/conflictsdlg.cxx894
-rw-r--r--sc/source/ui/miscdlgs/conflictsdlg.src109
-rw-r--r--sc/source/ui/miscdlgs/crdlg.cxx87
-rw-r--r--sc/source/ui/miscdlgs/crnrdlg.cxx1172
-rw-r--r--sc/source/ui/miscdlgs/delcldlg.cxx120
-rw-r--r--sc/source/ui/miscdlgs/delcodlg.cxx180
-rw-r--r--sc/source/ui/miscdlgs/filldlg.cxx375
-rw-r--r--sc/source/ui/miscdlgs/groupdlg.cxx83
-rw-r--r--sc/source/ui/miscdlgs/highred.cxx301
-rw-r--r--sc/source/ui/miscdlgs/highred.src133
-rw-r--r--sc/source/ui/miscdlgs/inscldlg.cxx120
-rw-r--r--sc/source/ui/miscdlgs/inscodlg.cxx372
-rw-r--r--sc/source/ui/miscdlgs/instbdlg.cxx433
-rw-r--r--sc/source/ui/miscdlgs/instbdlg.src184
-rw-r--r--sc/source/ui/miscdlgs/lbseldlg.cxx108
-rw-r--r--sc/source/ui/miscdlgs/linkarea.cxx366
-rw-r--r--sc/source/ui/miscdlgs/linkarea.src120
-rw-r--r--sc/source/ui/miscdlgs/makefile.mk127
-rw-r--r--sc/source/ui/miscdlgs/mtrindlg.cxx186
-rw-r--r--sc/source/ui/miscdlgs/mvtabdlg.cxx205
-rw-r--r--sc/source/ui/miscdlgs/namecrea.cxx79
-rw-r--r--sc/source/ui/miscdlgs/namepast.cxx133
-rw-r--r--sc/source/ui/miscdlgs/optsolver.cxx1066
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.cxx161
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.src127
-rw-r--r--sc/source/ui/miscdlgs/redcom.cxx186
-rw-r--r--sc/source/ui/miscdlgs/retypepassdlg.cxx544
-rw-r--r--sc/source/ui/miscdlgs/retypepassdlg.src313
-rw-r--r--sc/source/ui/miscdlgs/scuiautofmt.cxx476
-rw-r--r--sc/source/ui/miscdlgs/sharedocdlg.cxx235
-rw-r--r--sc/source/ui/miscdlgs/sharedocdlg.src110
-rw-r--r--sc/source/ui/miscdlgs/shtabdlg.cxx111
-rw-r--r--sc/source/ui/miscdlgs/simpref.cxx257
-rw-r--r--sc/source/ui/miscdlgs/solveroptions.cxx492
-rw-r--r--sc/source/ui/miscdlgs/solverutil.cxx229
-rw-r--r--sc/source/ui/miscdlgs/solvrdlg.cxx313
-rw-r--r--sc/source/ui/miscdlgs/strindlg.cxx107
-rw-r--r--sc/source/ui/miscdlgs/tabbgcolordlg.cxx198
-rw-r--r--sc/source/ui/miscdlgs/tabopdlg.cxx371
-rw-r--r--sc/source/ui/miscdlgs/textdlgs.cxx140
-rw-r--r--sc/source/ui/miscdlgs/warnbox.cxx91
-rw-r--r--sc/source/ui/namedlg/makefile.mk51
-rw-r--r--sc/source/ui/namedlg/namedlg.cxx649
-rw-r--r--sc/source/ui/navipi/content.cxx1526
-rw-r--r--sc/source/ui/navipi/makefile.mk57
-rw-r--r--sc/source/ui/navipi/navcitem.cxx127
-rw-r--r--sc/source/ui/navipi/navipi.cxx1565
-rw-r--r--sc/source/ui/navipi/navipi.hrc63
-rw-r--r--sc/source/ui/navipi/navipi.src414
-rw-r--r--sc/source/ui/navipi/scenwnd.cxx309
-rw-r--r--sc/source/ui/optdlg/makefile.mk59
-rw-r--r--sc/source/ui/optdlg/opredlin.cxx289
-rw-r--r--sc/source/ui/optdlg/tpcalc.cxx305
-rw-r--r--sc/source/ui/optdlg/tpprint.cxx144
-rw-r--r--sc/source/ui/optdlg/tpusrlst.cxx839
-rw-r--r--sc/source/ui/optdlg/tpview.cxx745
-rw-r--r--sc/source/ui/pagedlg/areasdlg.cxx906
-rw-r--r--sc/source/ui/pagedlg/hfedtdlg.cxx186
-rw-r--r--sc/source/ui/pagedlg/hfedtdlg.hrc64
-rw-r--r--sc/source/ui/pagedlg/hfedtdlg.src829
-rw-r--r--sc/source/ui/pagedlg/makefile.mk74
-rw-r--r--sc/source/ui/pagedlg/pagedlg.hrc103
-rw-r--r--sc/source/ui/pagedlg/pagedlg.src416
-rw-r--r--sc/source/ui/pagedlg/scuitphfedit.cxx1001
-rw-r--r--sc/source/ui/pagedlg/tphf.cxx331
-rw-r--r--sc/source/ui/pagedlg/tphf.src64
-rw-r--r--sc/source/ui/pagedlg/tphfedit.cxx874
-rw-r--r--sc/source/ui/pagedlg/tptable.cxx570
-rw-r--r--sc/source/ui/src/attrdlg.src203
-rw-r--r--sc/source/ui/src/autofmt.src271
-rw-r--r--sc/source/ui/src/condfrmt.src398
-rw-r--r--sc/source/ui/src/crnrdlg.src166
-rw-r--r--sc/source/ui/src/dbnamdlg.src198
-rw-r--r--sc/source/ui/src/filter.src820
-rw-r--r--sc/source/ui/src/globstr.src1742
-rw-r--r--sc/source/ui/src/hdrcont.src256
-rw-r--r--sc/source/ui/src/makefile.mk77
-rw-r--r--sc/source/ui/src/miscdlgs.src1463
-rw-r--r--sc/source/ui/src/namedlg.src165
-rw-r--r--sc/source/ui/src/opredlin.src136
-rw-r--r--sc/source/ui/src/optdlg.src722
-rw-r--r--sc/source/ui/src/optsolver.src540
-rw-r--r--sc/source/ui/src/popup.src544
-rw-r--r--sc/source/ui/src/pseudo.src62
-rw-r--r--sc/source/ui/src/sc.src49
-rw-r--r--sc/source/ui/src/scerrors.src170
-rw-r--r--sc/source/ui/src/scfuncs.src9043
-rw-r--r--sc/source/ui/src/scstring.src771
-rw-r--r--sc/source/ui/src/scwarngs.src83
-rw-r--r--sc/source/ui/src/simpref.src105
-rw-r--r--sc/source/ui/src/solveroptions.src189
-rw-r--r--sc/source/ui/src/solvrdlg.src135
-rw-r--r--sc/source/ui/src/sortdlg.src348
-rw-r--r--sc/source/ui/src/subtdlg.src291
-rw-r--r--sc/source/ui/src/tabopdlg.src142
-rw-r--r--sc/source/ui/src/textdlgs.src197
-rw-r--r--sc/source/ui/src/toolbox.src299
-rw-r--r--sc/source/ui/styleui/makefile.mk57
-rw-r--r--sc/source/ui/styleui/scstyles.src70
-rw-r--r--sc/source/ui/styleui/styledlg.cxx234
-rw-r--r--sc/source/ui/styleui/styledlg.src172
-rw-r--r--sc/source/ui/styleui/template.curbin0 -> 326 bytes
-rw-r--r--sc/source/ui/undo/areasave.cxx230
-rw-r--r--sc/source/ui/undo/makefile.mk85
-rw-r--r--sc/source/ui/undo/refundo.cxx214
-rw-r--r--sc/source/ui/undo/target.cxx45
-rw-r--r--sc/source/ui/undo/undobase.cxx539
-rw-r--r--sc/source/ui/undo/undoblk.cxx2253
-rw-r--r--sc/source/ui/undo/undoblk2.cxx215
-rw-r--r--sc/source/ui/undo/undoblk3.cxx2127
-rw-r--r--sc/source/ui/undo/undocell.cxx1129
-rw-r--r--sc/source/ui/undo/undodat.cxx2193
-rw-r--r--sc/source/ui/undo/undodraw.cxx269
-rw-r--r--sc/source/ui/undo/undoolk.cxx102
-rw-r--r--sc/source/ui/undo/undostyl.cxx311
-rw-r--r--sc/source/ui/undo/undotab.cxx1725
-rw-r--r--sc/source/ui/undo/undoutil.cxx133
-rw-r--r--sc/source/ui/unoobj/ChartRangeSelectionListener.cxx95
-rw-r--r--sc/source/ui/unoobj/addruno.cxx315
-rw-r--r--sc/source/ui/unoobj/afmtuno.cxx882
-rw-r--r--sc/source/ui/unoobj/appluno.cxx1086
-rw-r--r--sc/source/ui/unoobj/celllistsource.cxx449
-rw-r--r--sc/source/ui/unoobj/celllistsource.hxx175
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx9842
-rw-r--r--sc/source/ui/unoobj/cellvaluebinding.cxx663
-rw-r--r--sc/source/ui/unoobj/cellvaluebinding.hxx171
-rw-r--r--sc/source/ui/unoobj/chart2uno.cxx3914
-rw-r--r--sc/source/ui/unoobj/chartuno.cxx817
-rw-r--r--sc/source/ui/unoobj/confuno.cxx488
-rw-r--r--sc/source/ui/unoobj/convuno.cxx64
-rw-r--r--sc/source/ui/unoobj/cursuno.cxx510
-rwxr-xr-xsc/source/ui/unoobj/dapiuno.cxx3554
-rw-r--r--sc/source/ui/unoobj/datauno.cxx2371
-rw-r--r--sc/source/ui/unoobj/defltuno.cxx387
-rw-r--r--sc/source/ui/unoobj/detreg.cxx111
-rw-r--r--sc/source/ui/unoobj/dispuno.cxx415
-rw-r--r--sc/source/ui/unoobj/docuno.cxx3788
-rw-r--r--sc/source/ui/unoobj/drdefuno.cxx83
-rw-r--r--sc/source/ui/unoobj/editsrc.cxx373
-rwxr-xr-xsc/source/ui/unoobj/eventuno.cxx201
-rw-r--r--sc/source/ui/unoobj/fielduno.cxx1549
-rw-r--r--sc/source/ui/unoobj/filtuno.cxx317
-rw-r--r--sc/source/ui/unoobj/fmtuno.cxx1066
-rw-r--r--sc/source/ui/unoobj/forbiuno.cxx93
-rw-r--r--sc/source/ui/unoobj/funcuno.cxx745
-rw-r--r--sc/source/ui/unoobj/linkuno.cxx1821
-rw-r--r--sc/source/ui/unoobj/listenercalls.cxx89
-rw-r--r--sc/source/ui/unoobj/makefile.mk120
-rw-r--r--sc/source/ui/unoobj/miscuno.cxx424
-rw-r--r--sc/source/ui/unoobj/nameuno.cxx1131
-rw-r--r--sc/source/ui/unoobj/notesuno.cxx729
-rw-r--r--sc/source/ui/unoobj/optuno.cxx237
-rw-r--r--sc/source/ui/unoobj/pageuno.cxx78
-rwxr-xr-xsc/source/ui/unoobj/scdetect.cxx918
-rw-r--r--sc/source/ui/unoobj/scdetect.hxx95
-rw-r--r--sc/source/ui/unoobj/servuno.cxx598
-rw-r--r--sc/source/ui/unoobj/shapeuno.cxx1521
-rw-r--r--sc/source/ui/unoobj/srchuno.cxx276
-rw-r--r--sc/source/ui/unoobj/styleuno.cxx2140
-rw-r--r--sc/source/ui/unoobj/targuno.cxx318
-rw-r--r--sc/source/ui/unoobj/textuno.cxx1152
-rw-r--r--sc/source/ui/unoobj/tokenuno.cxx467
-rw-r--r--sc/source/ui/unoobj/unodoc.cxx67
-rw-r--r--sc/source/ui/unoobj/unoguard.cxx47
-rw-r--r--sc/source/ui/unoobj/unoreflist.cxx73
-rw-r--r--sc/source/ui/unoobj/viewuno.cxx2358
-rw-r--r--sc/source/ui/unoobj/warnpassword.cxx95
-rw-r--r--sc/source/ui/vba/excelvbahelper.cxx268
-rw-r--r--sc/source/ui/vba/excelvbahelper.hxx67
-rw-r--r--sc/source/ui/vba/helperdecl.hxx53
-rw-r--r--sc/source/ui/vba/makefile.mk124
-rw-r--r--sc/source/ui/vba/service.cxx134
-rw-r--r--sc/source/ui/vba/testvba/README37
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/ApplicationRunTest.xlsbin0 -> 25088 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/AutoFilter.xlsbin0 -> 54272 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcFont.xlsbin0 -> 73728 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcZoom.xlsbin0 -> 62976 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncTests.xlsbin0 -> 71168 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncs.xlsbin0 -> 47104 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscOperatorTests.xlsbin0 -> 66048 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscRangeTests.xlsbin0 -> 126976 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/PageBreaks.xlsbin0 -> 63488 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-2.xlsbin0 -> 2209280 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-3.xlsbin0 -> 54784 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges.xlsbin0 -> 2236416 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/Shapes.xlsbin0 -> 74240 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/StrConv-test.xlsbin0 -> 65024 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/Template.xlsbin0 -> 65024 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestAddress.xlsbin0 -> 84480 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest.xlsbin0 -> 67584 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest2.xlsbin0 -> 71680 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestIntersection.xlsbin0 -> 81408 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestUnion.xlsbin0 -> 72192 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/VariantTest.xlsbin0 -> 68608 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/Window.xlsbin0 -> 87040 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/bytearraystring.xlsbin0 -> 58880 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/dateserial.xlsbin0 -> 57344 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/datevalue.xlsbin0 -> 61952 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/format.xlsbin0 -> 102400 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/AutoFilter.log20
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/MiscRangeTests.log45
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-2.log68
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-3.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges.log280
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestAddress.log62
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest.log60
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest2.log64
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/format.log36
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/AutoFilter.log20
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcFont.log17
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcZoom.log18
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/FinancialFuncTests.log31
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscOperatorTests.log30
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscRangeTests.log45
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/PageBreaks.log10
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-2.log68
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-3.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges.log280
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Shapes.log77
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/StrConv-test.log9
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Template.log14
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestAddress.log67
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest.log60
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest2.log65
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestIntersection.log26
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestUnion.log17
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/VariantTest.log47
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Window.log46
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/bytearraystring.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/dateserial.log9
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/datevalue.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/format.log36
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/pagesetup.log77
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/partition.log11
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/range-4.log16
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/replace.log14
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/stringplusdouble.log62
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/window2.log41
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/AutoFilter.log20
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/CalcFont.log17
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscOperatorTests.log29
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscRangeTests.log45
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/PageBreaks.log10
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-2.log68
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-3.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges.log280
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Shapes.log77
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/StrConv-test.log9
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Template.log14
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestAddress.log67
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest.log60
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest2.log65
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestIntersection.log26
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestUnion.log17
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/VariantTest.log47
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Window.log46
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/bytearraystring.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/dateserial.log9
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/datevalue.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/format.log36
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/pagesetup.log87
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/partition.log11
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/range-4.log16
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/replace.log14
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/stringplusdouble.log62
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/window2.log41
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/error.xlsbin0 -> 38400 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/imagecontrols.xlsbin0 -> 2415104 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/keyword.xlsbin0 -> 50688 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/objectmodule.xlsbin0 -> 62464 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/stringtodouble.odsbin0 -> 13260 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/partition.xlsbin0 -> 65536 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/range-4.xlsbin0 -> 2192384 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/replace.xlsbin0 -> 64512 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/stringplusdouble.xlsbin0 -> 75264 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments-ooo-build/window2.xlsbin0 -> 72192 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/ApplicationRunTest.xlsbin0 -> 25088 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/AutoFilter.xlsbin0 -> 54272 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/CalcFont.xlsbin0 -> 73728 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/FinancialFuncs.xlsbin0 -> 47104 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/MiscRangeTests.xlsbin0 -> 126976 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/PageBreaks.xlsbin0 -> 63488 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/Ranges-2.xlsbin0 -> 2209280 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/Ranges-3.xlsbin0 -> 54784 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/Ranges.xlsbin0 -> 2236416 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/Shapes.xlsbin0 -> 74240 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/StrConv-test.xlsbin0 -> 65024 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/Template.xlsbin0 -> 65024 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/TestAddress.xlsbin0 -> 84480 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest.xlsbin0 -> 67584 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest2.xlsbin0 -> 71680 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/TestIntersection.xlsbin0 -> 81408 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/TestUnion.xlsbin0 -> 72192 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/Window.xlsbin0 -> 87040 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/bytearraystring.xlsbin0 -> 58880 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/dateserial.xlsbin0 -> 57344 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/datevalue.xlsbin0 -> 61952 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/format.xlsbin0 -> 102400 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/AutoFilter.log20
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/MiscRangeTests.log45
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-2.log68
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-3.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges.log280
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestAddress.log62
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest.log60
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest2.log64
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/AutoFilter.log20
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/CalcFont.log17
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/MiscRangeTests.log45
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/PageBreaks.log10
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-2.log68
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-3.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges.log280
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/Shapes.log77
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/StrConv-test.log9
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/Template.log14
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestAddress.log67
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest.log60
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest2.log65
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestIntersection.log26
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestUnion.log17
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/Window.log46
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/bytearraystring.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/dateserial.log9
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/datevalue.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/format.log36
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/pagesetup.log77
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/partition.log11
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/range-4.log16
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/replace.log14
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/stringplusdouble.log62
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/unix/window2.log41
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/AutoFilter.log20
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/MiscRangeTests.log45
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-2.log68
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-3.log8
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges.log280
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/Shapes.log77
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/TestAddress.log62
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest.log60
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest2.log65
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/pagesetup.log87
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/logs/win/replace.log14
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/pagesetup.xlsbin0 -> 72704 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/partition.xlsbin0 -> 65536 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/range-4.xlsbin0 -> 2192384 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/replace.xlsbin0 -> 64512 bytes
-rw-r--r--sc/source/ui/vba/testvba/TestDocuments/stringplusdouble.xlsbin0 -> 75264 bytes
-rwxr-xr-xsc/source/ui/vba/testvba/TestDocuments/window2.xlsbin0 -> 72192 bytes
-rw-r--r--sc/source/ui/vba/testvba/launchTest.pl45
-rw-r--r--sc/source/ui/vba/testvba/makefile.mk69
-rwxr-xr-xsc/source/ui/vba/testvba/runTests.pl121
-rw-r--r--sc/source/ui/vba/testvba/testResult.pl171
-rwxr-xr-xsc/source/ui/vba/testvba/testResults.pl163
-rwxr-xr-xsc/source/ui/vba/testvba/testclientbin0 -> 50595 bytes
-rw-r--r--sc/source/ui/vba/testvba/testvba.cxx309
-rwxr-xr-xsc/source/ui/vba/testvba/timestampsClean.pl73
-rw-r--r--sc/source/ui/vba/vbaapplication.cxx1184
-rw-r--r--sc/source/ui/vba/vbaapplication.hxx123
-rw-r--r--sc/source/ui/vba/vbaassistant.cxx132
-rw-r--r--sc/source/ui/vba/vbaassistant.hxx70
-rw-r--r--sc/source/ui/vba/vbaaxes.cxx203
-rw-r--r--sc/source/ui/vba/vbaaxes.hxx51
-rw-r--r--sc/source/ui/vba/vbaaxis.cxx670
-rw-r--r--sc/source/ui/vba/vbaaxis.hxx98
-rw-r--r--sc/source/ui/vba/vbaaxistitle.cxx58
-rw-r--r--sc/source/ui/vba/vbaaxistitle.hxx44
-rw-r--r--sc/source/ui/vba/vbaborders.cxx574
-rw-r--r--sc/source/ui/vba/vbaborders.hxx76
-rw-r--r--sc/source/ui/vba/vbacharacters.cxx136
-rw-r--r--sc/source/ui/vba/vbacharacters.hxx75
-rw-r--r--sc/source/ui/vba/vbachart.cxx1253
-rw-r--r--sc/source/ui/vba/vbachart.hxx114
-rw-r--r--sc/source/ui/vba/vbachartobject.cxx210
-rw-r--r--sc/source/ui/vba/vbachartobject.hxx80
-rw-r--r--sc/source/ui/vba/vbachartobjects.cxx194
-rw-r--r--sc/source/ui/vba/vbachartobjects.hxx75
-rw-r--r--sc/source/ui/vba/vbacharts.cxx120
-rw-r--r--sc/source/ui/vba/vbacharts.hxx60
-rw-r--r--sc/source/ui/vba/vbacharttitle.cxx58
-rw-r--r--sc/source/ui/vba/vbacharttitle.hxx44
-rw-r--r--sc/source/ui/vba/vbacomment.cxx239
-rw-r--r--sc/source/ui/vba/vbacomment.hxx81
-rw-r--r--sc/source/ui/vba/vbacomments.cxx116
-rw-r--r--sc/source/ui/vba/vbacomments.hxx65
-rw-r--r--sc/source/ui/vba/vbacondition.cxx175
-rw-r--r--sc/source/ui/vba/vbacondition.hxx54
-rw-r--r--sc/source/ui/vba/vbadialog.cxx88
-rw-r--r--sc/source/ui/vba/vbadialog.hxx50
-rw-r--r--sc/source/ui/vba/vbadialogs.cxx68
-rw-r--r--sc/source/ui/vba/vbadialogs.hxx55
-rwxr-xr-xsc/source/ui/vba/vbaeventshelper.cxx753
-rwxr-xr-xsc/source/ui/vba/vbaeventshelper.hxx88
-rw-r--r--sc/source/ui/vba/vbafont.cxx501
-rw-r--r--sc/source/ui/vba/vbafont.hxx90
-rw-r--r--sc/source/ui/vba/vbaformat.cxx843
-rw-r--r--sc/source/ui/vba/vbaformat.hxx108
-rw-r--r--sc/source/ui/vba/vbaformatcondition.cxx176
-rw-r--r--sc/source/ui/vba/vbaformatcondition.hxx70
-rw-r--r--sc/source/ui/vba/vbaformatconditions.cxx301
-rw-r--r--sc/source/ui/vba/vbaformatconditions.hxx65
-rw-r--r--sc/source/ui/vba/vbaglobals.cxx304
-rw-r--r--sc/source/ui/vba/vbaglobals.hxx95
-rw-r--r--sc/source/ui/vba/vbahelper.cxx758
-rw-r--r--sc/source/ui/vba/vbahyperlink.cxx246
-rw-r--r--sc/source/ui/vba/vbahyperlink.hxx88
-rwxr-xr-xsc/source/ui/vba/vbahyperlinks.cxx293
-rwxr-xr-xsc/source/ui/vba/vbahyperlinks.hxx150
-rw-r--r--sc/source/ui/vba/vbainterior.cxx417
-rw-r--r--sc/source/ui/vba/vbainterior.hxx88
-rw-r--r--sc/source/ui/vba/vbaname.cxx269
-rw-r--r--sc/source/ui/vba/vbaname.hxx84
-rw-r--r--sc/source/ui/vba/vbanames.cxx206
-rw-r--r--sc/source/ui/vba/vbanames.hxx82
-rw-r--r--sc/source/ui/vba/vbaoleobject.cxx164
-rw-r--r--sc/source/ui/vba/vbaoleobject.hxx67
-rw-r--r--sc/source/ui/vba/vbaoleobjects.cxx185
-rw-r--r--sc/source/ui/vba/vbaoleobjects.hxx57
-rw-r--r--sc/source/ui/vba/vbaoutline.cxx65
-rw-r--r--sc/source/ui/vba/vbaoutline.hxx52
-rw-r--r--sc/source/ui/vba/vbapagebreak.cxx172
-rw-r--r--sc/source/ui/vba/vbapagebreak.hxx103
-rw-r--r--sc/source/ui/vba/vbapagebreaks.cxx327
-rw-r--r--sc/source/ui/vba/vbapagebreaks.hxx97
-rw-r--r--sc/source/ui/vba/vbapagesetup.cxx626
-rw-r--r--sc/source/ui/vba/vbapagesetup.hxx90
-rw-r--r--sc/source/ui/vba/vbapalette.cxx111
-rw-r--r--sc/source/ui/vba/vbapalette.hxx54
-rw-r--r--sc/source/ui/vba/vbapane.cxx206
-rw-r--r--sc/source/ui/vba/vbapane.hxx67
-rw-r--r--sc/source/ui/vba/vbapivotcache.cxx60
-rw-r--r--sc/source/ui/vba/vbapivotcache.hxx49
-rw-r--r--sc/source/ui/vba/vbapivottable.cxx63
-rw-r--r--sc/source/ui/vba/vbapivottable.hxx49
-rw-r--r--sc/source/ui/vba/vbapivottables.cxx94
-rw-r--r--sc/source/ui/vba/vbapivottables.hxx65
-rw-r--r--sc/source/ui/vba/vbapropvalue.cxx45
-rw-r--r--sc/source/ui/vba/vbapropvalue.hxx57
-rwxr-xr-xsc/source/ui/vba/vbarange.cxx5671
-rw-r--r--sc/source/ui/vba/vbarange.hxx298
-rw-r--r--sc/source/ui/vba/vbaseriescollection.cxx80
-rw-r--r--sc/source/ui/vba/vbaseriescollection.hxx54
-rwxr-xr-xsc/source/ui/vba/vbasheetobject.cxx517
-rwxr-xr-xsc/source/ui/vba/vbasheetobject.hxx220
-rwxr-xr-xsc/source/ui/vba/vbasheetobjects.cxx534
-rwxr-xr-xsc/source/ui/vba/vbasheetobjects.hxx113
-rw-r--r--sc/source/ui/vba/vbastyle.cxx186
-rw-r--r--sc/source/ui/vba/vbastyle.hxx96
-rw-r--r--sc/source/ui/vba/vbastyles.cxx182
-rw-r--r--sc/source/ui/vba/vbastyles.hxx57
-rw-r--r--sc/source/ui/vba/vbatextboxshape.cxx66
-rw-r--r--sc/source/ui/vba/vbatextboxshape.hxx50
-rw-r--r--sc/source/ui/vba/vbatextframe.cxx78
-rw-r--r--sc/source/ui/vba/vbatextframe.hxx49
-rw-r--r--sc/source/ui/vba/vbatitle.hxx163
-rw-r--r--sc/source/ui/vba/vbavalidation.cxx333
-rw-r--r--sc/source/ui/vba/vbavalidation.hxx71
-rw-r--r--sc/source/ui/vba/vbawindow.cxx858
-rw-r--r--sc/source/ui/vba/vbawindow.hxx123
-rw-r--r--sc/source/ui/vba/vbawindows.cxx260
-rw-r--r--sc/source/ui/vba/vbawindows.hxx64
-rw-r--r--sc/source/ui/vba/vbaworkbook.cxx363
-rw-r--r--sc/source/ui/vba/vbaworkbook.hxx80
-rw-r--r--sc/source/ui/vba/vbaworkbooks.cxx367
-rw-r--r--sc/source/ui/vba/vbaworkbooks.hxx71
-rw-r--r--sc/source/ui/vba/vbaworksheet.cxx1019
-rw-r--r--sc/source/ui/vba/vbaworksheet.hxx174
-rw-r--r--sc/source/ui/vba/vbaworksheets.cxx501
-rw-r--r--sc/source/ui/vba/vbaworksheets.hxx83
-rw-r--r--sc/source/ui/vba/vbawsfunction.cxx259
-rw-r--r--sc/source/ui/vba/vbawsfunction.hxx57
-rw-r--r--sc/source/ui/view/auditsh.cxx155
-rw-r--r--sc/source/ui/view/cellsh.cxx1005
-rw-r--r--sc/source/ui/view/cellsh1.cxx2206
-rw-r--r--sc/source/ui/view/cellsh2.cxx1432
-rw-r--r--sc/source/ui/view/cellsh3.cxx966
-rw-r--r--sc/source/ui/view/cellsh4.cxx382
-rw-r--r--sc/source/ui/view/colrowba.cxx419
-rw-r--r--sc/source/ui/view/dbfunc.cxx512
-rw-r--r--sc/source/ui/view/dbfunc2.cxx77
-rwxr-xr-xsc/source/ui/view/dbfunc3.cxx2375
-rw-r--r--sc/source/ui/view/dbfunc4.cxx102
-rw-r--r--sc/source/ui/view/drawattr.cxx82
-rw-r--r--sc/source/ui/view/drawutil.cxx116
-rw-r--r--sc/source/ui/view/drawvie2.cxx62
-rw-r--r--sc/source/ui/view/drawvie3.cxx182
-rw-r--r--sc/source/ui/view/drawvie4.cxx394
-rw-r--r--sc/source/ui/view/drawview.cxx849
-rw-r--r--sc/source/ui/view/editsh.cxx1206
-rw-r--r--sc/source/ui/view/formatsh.cxx2168
-rw-r--r--sc/source/ui/view/galwrap.cxx79
-rw-r--r--sc/source/ui/view/gridmerg.cxx174
-rw-r--r--sc/source/ui/view/gridwin.cxx5706
-rw-r--r--sc/source/ui/view/gridwin2.cxx1061
-rw-r--r--sc/source/ui/view/gridwin3.cxx443
-rw-r--r--sc/source/ui/view/gridwin4.cxx2069
-rw-r--r--sc/source/ui/view/gridwin5.cxx439
-rw-r--r--sc/source/ui/view/hdrcont.cxx1046
-rw-r--r--sc/source/ui/view/hintwin.cxx108
-rw-r--r--sc/source/ui/view/imapwrap.cxx76
-rw-r--r--sc/source/ui/view/invmerge.cxx192
-rw-r--r--sc/source/ui/view/makefile.mk173
-rw-r--r--sc/source/ui/view/notemark.cxx200
-rw-r--r--sc/source/ui/view/olinewin.cxx1045
-rw-r--r--sc/source/ui/view/olkact.cxx282
-rw-r--r--sc/source/ui/view/output.cxx2476
-rw-r--r--sc/source/ui/view/output2.cxx3705
-rw-r--r--sc/source/ui/view/output3.cxx276
-rw-r--r--sc/source/ui/view/pfuncache.cxx198
-rw-r--r--sc/source/ui/view/pgbrksh.cxx85
-rw-r--r--sc/source/ui/view/pivotsh.cxx204
-rw-r--r--sc/source/ui/view/preview.cxx1603
-rw-r--r--sc/source/ui/view/prevloc.cxx792
-rw-r--r--sc/source/ui/view/prevwsh.cxx1241
-rw-r--r--sc/source/ui/view/prevwsh2.cxx357
-rw-r--r--sc/source/ui/view/printfun.cxx3202
-rw-r--r--sc/source/ui/view/reffact.cxx434
-rw-r--r--sc/source/ui/view/scextopt.cxx224
-rw-r--r--sc/source/ui/view/select.cxx891
-rw-r--r--sc/source/ui/view/selectionstate.cxx89
-rw-r--r--sc/source/ui/view/spelldialog.cxx279
-rw-r--r--sc/source/ui/view/spelleng.cxx458
-rw-r--r--sc/source/ui/view/tabcont.cxx638
-rw-r--r--sc/source/ui/view/tabpopsh.cxx72
-rw-r--r--sc/source/ui/view/tabsplit.cxx105
-rw-r--r--sc/source/ui/view/tabview.cxx2535
-rw-r--r--sc/source/ui/view/tabview2.cxx982
-rw-r--r--sc/source/ui/view/tabview3.cxx2790
-rw-r--r--sc/source/ui/view/tabview4.cxx573
-rw-r--r--sc/source/ui/view/tabview5.cxx722
-rw-r--r--sc/source/ui/view/tabvwsh.cxx117
-rw-r--r--sc/source/ui/view/tabvwsh2.cxx481
-rw-r--r--sc/source/ui/view/tabvwsh3.cxx1234
-rw-r--r--sc/source/ui/view/tabvwsh4.cxx2114
-rw-r--r--sc/source/ui/view/tabvwsh5.cxx428
-rw-r--r--sc/source/ui/view/tabvwsh8.cxx104
-rw-r--r--sc/source/ui/view/tabvwsh9.cxx295
-rw-r--r--sc/source/ui/view/tabvwsha.cxx890
-rw-r--r--sc/source/ui/view/tabvwshb.cxx500
-rw-r--r--sc/source/ui/view/tabvwshc.cxx327
-rw-r--r--sc/source/ui/view/tabvwshd.cxx100
-rw-r--r--sc/source/ui/view/tabvwshe.cxx343
-rw-r--r--sc/source/ui/view/tabvwshf.cxx964
-rw-r--r--sc/source/ui/view/tabvwshg.cxx140
-rw-r--r--sc/source/ui/view/tabvwshh.cxx293
-rw-r--r--sc/source/ui/view/viewdata.cxx3179
-rw-r--r--sc/source/ui/view/viewfun2.cxx3145
-rw-r--r--sc/source/ui/view/viewfun3.cxx1789
-rw-r--r--sc/source/ui/view/viewfun4.cxx846
-rw-r--r--sc/source/ui/view/viewfun5.cxx749
-rw-r--r--sc/source/ui/view/viewfun6.cxx197
-rw-r--r--sc/source/ui/view/viewfun7.cxx454
-rw-r--r--sc/source/ui/view/viewfunc.cxx3018
-rw-r--r--sc/source/ui/view/viewutil.cxx640
-rw-r--r--sc/source/ui/view/waitoff.cxx70
1436 files changed, 643800 insertions, 0 deletions
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
new file mode 100644
index 000000000000..f3443312bd4e
--- /dev/null
+++ b/sc/source/core/data/attarray.cxx
@@ -0,0 +1,2611 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/shaditem.hxx>
+#include <svl/poolcach.hxx>
+#include <editeng/fontitem.hxx>
+#include <unotools/fontcvt.hxx>
+
+#include "attarray.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "markarr.hxx"
+#include "rechead.hxx"
+#include "globstr.hrc"
+#include "segmenttree.hxx"
+
+#undef DBG_INVALIDATE
+#define DBGOUTPUT(s) \
+ DBG_ERROR( String("Invalidate ") + String(s) + String(": ") \
+ + String(nCol) + String('/') + String(aAdrStart.Row()) + String('/') + String(nTab) \
+ + String(" bis ") \
+ + String(nCol) + String('/') + String(aAdrEnd.Row()) + String('/') + String(nTab) \
+ );
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//------------------------------------------------------------------------
+
+ScAttrArray::ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc ) :
+ nCol( nNewCol ),
+ nTab( nNewTab ),
+ pDocument( pDoc )
+{
+ nCount = nLimit = 1;
+ pData = new ScAttrEntry[1];
+ if (pData)
+ {
+ pData[0].nRow = MAXROW;
+ pData[0].pPattern = pDocument->GetDefPattern(); // ohne Put !!!
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScAttrArray::~ScAttrArray()
+{
+#ifdef DBG_UTIL
+ TestData();
+#endif
+
+ if (pData)
+ {
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+ for (SCSIZE i=0; i<nCount; i++)
+ pDocPool->Remove(*pData[i].pPattern);
+
+ delete[] pData;
+ }
+}
+
+//------------------------------------------------------------------------
+#ifdef DBG_UTIL
+void ScAttrArray::TestData() const
+{
+
+ USHORT nErr = 0;
+ if (pData)
+ {
+ SCSIZE nPos;
+ for (nPos=0; nPos<nCount; nPos++)
+ {
+ if (nPos > 0)
+ if (pData[nPos].pPattern == pData[nPos-1].pPattern || pData[nPos].nRow <= pData[nPos-1].nRow)
+ ++nErr;
+ if (pData[nPos].pPattern->Which() != ATTR_PATTERN)
+ ++nErr;
+ }
+ if ( nPos && pData[nPos-1].nRow != MAXROW )
+ ++nErr;
+ }
+ if (nErr)
+ {
+ ByteString aMsg = ByteString::CreateFromInt32(nErr);
+ aMsg += " errors in attribute array, column ";
+ aMsg += ByteString::CreateFromInt32(nCol);
+ DBG_ERROR( aMsg.GetBuffer() );
+ }
+}
+#endif
+
+//------------------------------------------------------------------------
+
+void ScAttrArray::Reset( const ScPatternAttr* pPattern, BOOL bAlloc )
+{
+ if (pData)
+ {
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+ const ScPatternAttr* pOldPattern;
+ ScAddress aAdrStart( nCol, 0, nTab );
+ ScAddress aAdrEnd ( nCol, 0, nTab );
+
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ // ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
+ pOldPattern = pData[i].pPattern;
+ BOOL bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
+ pPattern->GetItemSet(), pOldPattern->GetItemSet() ) )
+ {
+ aAdrStart.SetRow( i ? pData[i-1].nRow+1 : 0 );
+ aAdrEnd .SetRow( pData[i].nRow );
+ pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
+#ifdef DBG_INVALIDATE
+ DBGOUTPUT("Reset");
+#endif
+ }
+ // bedingtes Format gesetzt oder geloescht?
+ if ( &pPattern->GetItem(ATTR_CONDITIONAL) != &pOldPattern->GetItem(ATTR_CONDITIONAL) )
+ {
+ pDocument->ConditionalChanged( ((const SfxUInt32Item&)
+ pOldPattern->GetItem(ATTR_CONDITIONAL)).GetValue() );
+ pDocument->ConditionalChanged( ((const SfxUInt32Item&)
+ pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() );
+ }
+ pDocPool->Remove(*pOldPattern);
+ }
+ delete[] pData;
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
+
+ if (bAlloc)
+ {
+ nCount = nLimit = 1;
+ pData = new ScAttrEntry[1];
+ if (pData)
+ {
+ ScPatternAttr* pNewPattern = (ScPatternAttr*) &pDocPool->Put(*pPattern);
+ pData[0].nRow = MAXROW;
+ pData[0].pPattern = pNewPattern;
+ }
+ }
+ else
+ {
+ nCount = nLimit = 0;
+ pData = NULL; // muss sofort wieder belegt werden !
+ }
+ }
+}
+
+
+BOOL ScAttrArray::Concat(SCSIZE nPos)
+{
+ BOOL bRet = FALSE;
+ if (pData && (nPos < nCount))
+ {
+ if (nPos > 0)
+ {
+ if (pData[nPos - 1].pPattern == pData[nPos].pPattern)
+ {
+ pData[nPos - 1].nRow = pData[nPos].nRow;
+ pDocument->GetPool()->Remove(*pData[nPos].pPattern);
+ memmove(&pData[nPos], &pData[nPos + 1], (nCount - nPos - 1) * sizeof(ScAttrEntry));
+ pData[nCount - 1].pPattern = NULL;
+ pData[nCount - 1].nRow = 0;
+ nCount--;
+ nPos--;
+ bRet = TRUE;
+ }
+ }
+ if (nPos + 1 < nCount)
+ {
+ if (pData[nPos + 1].pPattern == pData[nPos].pPattern)
+ {
+ pData[nPos].nRow = pData[nPos + 1].nRow;
+ pDocument->GetPool()->Remove(*pData[nPos].pPattern);
+ memmove(&pData[nPos + 1], &pData[nPos + 2], (nCount - nPos - 2) * sizeof(ScAttrEntry));
+ pData[nCount - 1].pPattern = NULL;
+ pData[nCount - 1].nRow = 0;
+ nCount--;
+ bRet = TRUE;
+ }
+ }
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScAttrArray::Search( SCROW nRow, SCSIZE& nIndex ) const
+{
+ long nLo = 0;
+ long nHi = static_cast<long>(nCount) - 1;
+ long nStartRow = 0;
+ long nEndRow = 0;
+ long i = 0;
+ BOOL bFound = (nCount == 1);
+ if (pData)
+ {
+ while ( !bFound && nLo <= nHi )
+ {
+ i = (nLo + nHi) / 2;
+ if (i > 0)
+ nStartRow = (long) pData[i - 1].nRow;
+ else
+ nStartRow = -1;
+ nEndRow = (long) pData[i].nRow;
+ if (nEndRow < (long) nRow)
+ nLo = ++i;
+ else
+ if (nStartRow >= (long) nRow)
+ nHi = --i;
+ else
+ bFound = TRUE;
+ }
+ }
+ else
+ bFound = FALSE;
+
+ if (bFound)
+ nIndex=(SCSIZE)i;
+ else
+ nIndex=0;
+ return bFound;
+}
+
+
+const ScPatternAttr* ScAttrArray::GetPattern( SCROW nRow ) const
+{
+ SCSIZE i;
+ if (Search( nRow, i ))
+ return pData[i].pPattern;
+ else
+ return NULL;
+}
+
+
+const ScPatternAttr* ScAttrArray::GetPatternRange( SCROW& rStartRow,
+ SCROW& rEndRow, SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if ( Search( nRow, nIndex ) )
+ {
+ if ( nIndex > 0 )
+ rStartRow = pData[nIndex-1].nRow + 1;
+ else
+ rStartRow = 0;
+ rEndRow = pData[nIndex].nRow;
+ return pData[nIndex].pPattern;
+ }
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+void ScAttrArray::SetPattern( SCROW nRow, const ScPatternAttr* pPattern, BOOL bPutToPool )
+{
+ SetPatternArea( nRow, nRow, pPattern, bPutToPool );
+}
+
+
+void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr *pPattern, BOOL bPutToPool )
+{
+ if (ValidRow(nStartRow) && ValidRow(nEndRow))
+ {
+ if (bPutToPool)
+ pPattern = (const ScPatternAttr*) &pDocument->GetPool()->Put(*pPattern);
+
+ if ((nStartRow == 0) && (nEndRow == MAXROW))
+ Reset(pPattern);
+ else
+ {
+ SCSIZE nNeeded = nCount + 2;
+ if ( nLimit < nNeeded )
+ {
+ nLimit += SC_ATTRARRAY_DELTA;
+ if ( nLimit < nNeeded )
+ nLimit = nNeeded;
+ ScAttrEntry* pNewData = new ScAttrEntry[nLimit];
+ memcpy( pNewData, pData, nCount*sizeof(ScAttrEntry) );
+ delete[] pData;
+ pData = pNewData;
+ }
+
+ ScAddress aAdrStart( nCol, 0, nTab );
+ ScAddress aAdrEnd ( nCol, 0, nTab );
+
+ SCSIZE ni = 0; // number of entries in beginning
+ SCSIZE nx = 0; // track position
+ SCROW ns = 0; // start row of track position
+ if ( nStartRow > 0 )
+ {
+ // skip beginning
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ ni = nIndex;
+
+ if ( ni > 0 )
+ {
+ nx = ni;
+ ns = pData[ni-1].nRow+1;
+ }
+ }
+
+ // ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
+ // oder bedingte Formate neu gesetzt oder geloescht werden
+ while ( ns <= nEndRow )
+ {
+ const SfxItemSet& rNewSet = pPattern->GetItemSet();
+ const SfxItemSet& rOldSet = pData[nx].pPattern->GetItemSet();
+
+ BOOL bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
+ rNewSet, rOldSet ) )
+ {
+ aAdrStart.SetRow( Max(nStartRow,ns) );
+ aAdrEnd .SetRow( Min(nEndRow,pData[nx].nRow) );
+ pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
+#ifdef DBG_INVALIDATE
+ DBGOUTPUT("SetPatternArea");
+#endif
+ }
+ if ( &rNewSet.Get(ATTR_CONDITIONAL) != &rOldSet.Get(ATTR_CONDITIONAL) )
+ {
+ pDocument->ConditionalChanged( ((const SfxUInt32Item&)
+ rOldSet.Get(ATTR_CONDITIONAL)).GetValue() );
+ pDocument->ConditionalChanged( ((const SfxUInt32Item&)
+ rNewSet.Get(ATTR_CONDITIONAL)).GetValue() );
+ }
+ ns = pData[nx].nRow + 1;
+ nx++;
+ }
+
+ // continue modifying data array
+
+ SCSIZE nInsert; // insert position (MAXROWCOUNT := no insert)
+ BOOL bCombined = FALSE;
+ BOOL bSplit = FALSE;
+ if ( nStartRow > 0 )
+ {
+ nInsert = MAXROWCOUNT;
+ if ( pData[ni].pPattern != pPattern )
+ {
+ if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
+ { // may be a split or a simple insert or just a shrink,
+ // row adjustment is done further down
+ if ( pData[ni].nRow > nEndRow )
+ bSplit = TRUE;
+ ni++;
+ nInsert = ni;
+ }
+ else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
+ nInsert = ni;
+ }
+ if ( ni > 0 && pData[ni-1].pPattern == pPattern )
+ { // combine
+ pData[ni-1].nRow = nEndRow;
+ nInsert = MAXROWCOUNT;
+ bCombined = TRUE;
+ }
+ }
+ else
+ nInsert = 0;
+
+ SCSIZE nj = ni; // stop position of range to replace
+ while ( nj < nCount && pData[nj].nRow <= nEndRow )
+ nj++;
+ if ( !bSplit )
+ {
+ if ( nj < nCount && pData[nj].pPattern == pPattern )
+ { // combine
+ if ( ni > 0 )
+ {
+ if ( pData[ni-1].pPattern == pPattern )
+ { // adjacent entries
+ pData[ni-1].nRow = pData[nj].nRow;
+ nj++;
+ }
+ else if ( ni == nInsert )
+ pData[ni-1].nRow = nStartRow - 1; // shrink
+ }
+ nInsert = MAXROWCOUNT;
+ bCombined = TRUE;
+ }
+ else if ( ni > 0 && ni == nInsert )
+ pData[ni-1].nRow = nStartRow - 1; // shrink
+ }
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+ if ( bSplit )
+ { // duplicate splitted entry in pool
+ pDocPool->Put( *pData[ni-1].pPattern );
+ }
+ if ( ni < nj )
+ { // remove middle entries
+ for ( SCSIZE nk=ni; nk<nj; nk++)
+ { // remove entries from pool
+ pDocPool->Remove( *pData[nk].pPattern );
+ }
+ if ( !bCombined )
+ { // replace one entry
+ pData[ni].nRow = nEndRow;
+ pData[ni].pPattern = pPattern;
+ ni++;
+ nInsert = MAXROWCOUNT;
+ }
+ if ( ni < nj )
+ { // remove entries
+ memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScAttrEntry) );
+ nCount -= nj - ni;
+ }
+ }
+
+ if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+ { // insert or append new entry
+ if ( nInsert <= nCount )
+ {
+ if ( !bSplit )
+ memmove( pData + nInsert + 1, pData + nInsert,
+ (nCount - nInsert) * sizeof(ScAttrEntry) );
+ else
+ {
+ memmove( pData + nInsert + 2, pData + nInsert,
+ (nCount - nInsert) * sizeof(ScAttrEntry) );
+ pData[nInsert+1] = pData[nInsert-1];
+ nCount++;
+ }
+ }
+ if ( nInsert )
+ pData[nInsert-1].nRow = nStartRow - 1;
+ pData[nInsert].nRow = nEndRow;
+ pData[nInsert].pPattern = pPattern;
+ nCount++;
+ }
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
+ }
+ }
+// InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
+
+#ifdef DBG_UTIL
+ TestData();
+#endif
+}
+
+
+void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle )
+{
+ if (ValidRow(nStartRow) && ValidRow(nEndRow))
+ {
+ SCSIZE nPos;
+ SCROW nStart=0;
+ if (!Search( nStartRow, nPos ))
+ {
+ DBG_ERROR("Search-Fehler");
+ return;
+ }
+
+ ScAddress aAdrStart( nCol, 0, nTab );
+ ScAddress aAdrEnd ( nCol, 0, nTab );
+
+ do
+ {
+ const ScPatternAttr* pOldPattern = pData[nPos].pPattern;
+ ScPatternAttr* pNewPattern = new ScPatternAttr(*pOldPattern);
+ pNewPattern->SetStyleSheet(pStyle);
+ SCROW nY1 = nStart;
+ SCROW nY2 = pData[nPos].nRow;
+ nStart = pData[nPos].nRow + 1;
+
+ if ( *pNewPattern == *pOldPattern )
+ {
+ // keep the original pattern (might be default)
+ // pNewPattern is deleted below
+ nPos++;
+ }
+ else if ( nY1 < nStartRow || nY2 > nEndRow )
+ {
+ if (nY1 < nStartRow) nY1=nStartRow;
+ if (nY2 > nEndRow) nY2=nEndRow;
+ SetPatternArea( nY1, nY2, pNewPattern, TRUE );
+ Search( nStart, nPos );
+ }
+ else
+ {
+ // ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
+ // bedingte Formate in Vorlagen gibt es (noch) nicht
+
+ const SfxItemSet& rNewSet = pNewPattern->GetItemSet();
+ const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
+
+ BOOL bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
+ rNewSet, rOldSet ) )
+ {
+ aAdrStart.SetRow( nPos ? pData[nPos-1].nRow+1 : 0 );
+ aAdrEnd .SetRow( pData[nPos].nRow );
+ pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
+#ifdef DBG_INVALIDATE
+ DBGOUTPUT("ApplyStyleArea");
+#endif
+ }
+
+ pDocument->GetPool()->Remove(*pData[nPos].pPattern);
+ pData[nPos].pPattern = (const ScPatternAttr*)
+ &pDocument->GetPool()->Put(*pNewPattern);
+ if (Concat(nPos))
+ Search(nStart, nPos);
+ else
+ nPos++;
+ }
+ delete pNewPattern;
+ }
+ while ((nStart <= nEndRow) && (nPos < nCount));
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
+ }
+
+#ifdef DBG_UTIL
+ TestData();
+#endif
+}
+
+
+ // const wird weggecastet, weil es sonst
+ // zu ineffizient/kompliziert wird!
+#define SET_LINECOLOR(dest,c) \
+ if ((dest)) \
+ { \
+ ((SvxBorderLine*)(dest))->SetColor((c)); \
+ }
+
+#define SET_LINE(dest,src) \
+ if ((dest)) \
+ { \
+ SvxBorderLine* pCast = (SvxBorderLine*)(dest); \
+ pCast->SetOutWidth((src)->GetOutWidth()); \
+ pCast->SetInWidth ((src)->GetInWidth()); \
+ pCast->SetDistance((src)->GetDistance()); \
+ }
+
+void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
+ const SvxBorderLine* pLine, BOOL bColorOnly )
+{
+ if ( bColorOnly && !pLine )
+ return;
+
+ if (ValidRow(nStartRow) && ValidRow(nEndRow))
+ {
+ SCSIZE nPos;
+ SCROW nStart=0;
+ if (!Search( nStartRow, nPos ))
+ {
+ DBG_ERROR("Search-Fehler");
+ return;
+ }
+
+ do
+ {
+ const ScPatternAttr* pOldPattern = pData[nPos].pPattern;
+ const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
+ const SfxPoolItem* pBoxItem = 0;
+ SfxItemState eState = rOldSet.GetItemState( ATTR_BORDER, TRUE, &pBoxItem );
+ const SfxPoolItem* pTLBRItem = 0;
+ SfxItemState eTLBRState = rOldSet.GetItemState( ATTR_BORDER_TLBR, TRUE, &pTLBRItem );
+ const SfxPoolItem* pBLTRItem = 0;
+ SfxItemState eBLTRState = rOldSet.GetItemState( ATTR_BORDER_BLTR, TRUE, &pBLTRItem );
+
+ if ( (SFX_ITEM_SET == eState) || (SFX_ITEM_SET == eTLBRState) || (SFX_ITEM_SET == eBLTRState) )
+ {
+ ScPatternAttr* pNewPattern = new ScPatternAttr(*pOldPattern);
+ SfxItemSet& rNewSet = pNewPattern->GetItemSet();
+ SCROW nY1 = nStart;
+ SCROW nY2 = pData[nPos].nRow;
+
+ SvxBoxItem* pNewBoxItem = pBoxItem ? (SvxBoxItem*)pBoxItem->Clone() : 0;
+ SvxLineItem* pNewTLBRItem = pTLBRItem ? (SvxLineItem*)pTLBRItem->Clone() : 0;
+ SvxLineItem* pNewBLTRItem = pBLTRItem ? (SvxLineItem*)pBLTRItem->Clone() : 0;
+
+ // Linienattribute holen und mit Parametern aktualisieren
+
+ if ( !pLine )
+ {
+ if( pNewBoxItem )
+ {
+ if ( pNewBoxItem->GetTop() ) pNewBoxItem->SetLine( NULL, BOX_LINE_TOP );
+ if ( pNewBoxItem->GetBottom() ) pNewBoxItem->SetLine( NULL, BOX_LINE_BOTTOM );
+ if ( pNewBoxItem->GetLeft() ) pNewBoxItem->SetLine( NULL, BOX_LINE_LEFT );
+ if ( pNewBoxItem->GetRight() ) pNewBoxItem->SetLine( NULL, BOX_LINE_RIGHT );
+ }
+ if( pNewTLBRItem && pNewTLBRItem->GetLine() )
+ pNewTLBRItem->SetLine( 0 );
+ if( pNewBLTRItem && pNewBLTRItem->GetLine() )
+ pNewBLTRItem->SetLine( 0 );
+ }
+ else
+ {
+ if ( bColorOnly )
+ {
+ Color aColor( pLine->GetColor() );
+ if( pNewBoxItem )
+ {
+ SET_LINECOLOR( pNewBoxItem->GetTop(), aColor );
+ SET_LINECOLOR( pNewBoxItem->GetBottom(), aColor );
+ SET_LINECOLOR( pNewBoxItem->GetLeft(), aColor );
+ SET_LINECOLOR( pNewBoxItem->GetRight(), aColor );
+ }
+ if( pNewTLBRItem )
+ SET_LINECOLOR( pNewTLBRItem->GetLine(), aColor );
+ if( pNewBLTRItem )
+ SET_LINECOLOR( pNewBLTRItem->GetLine(), aColor );
+ }
+ else
+ {
+ if( pNewBoxItem )
+ {
+ SET_LINE( pNewBoxItem->GetTop(), pLine );
+ SET_LINE( pNewBoxItem->GetBottom(), pLine );
+ SET_LINE( pNewBoxItem->GetLeft(), pLine );
+ SET_LINE( pNewBoxItem->GetRight(), pLine );
+ }
+ if( pNewTLBRItem )
+ SET_LINE( pNewTLBRItem->GetLine(), pLine );
+ if( pNewBLTRItem )
+ SET_LINE( pNewBLTRItem->GetLine(), pLine );
+ }
+ }
+ if( pNewBoxItem ) rNewSet.Put( *pNewBoxItem );
+ if( pNewTLBRItem ) rNewSet.Put( *pNewTLBRItem );
+ if( pNewBLTRItem ) rNewSet.Put( *pNewBLTRItem );
+
+ nStart = pData[nPos].nRow + 1;
+
+ if ( nY1 < nStartRow || nY2 > nEndRow )
+ {
+ if (nY1 < nStartRow) nY1=nStartRow;
+ if (nY2 > nEndRow) nY2=nEndRow;
+ SetPatternArea( nY1, nY2, pNewPattern, TRUE );
+ Search( nStart, nPos );
+ }
+ else
+ {
+ //! aus Pool loeschen?
+ pDocument->GetPool()->Remove(*pData[nPos].pPattern);
+ pData[nPos].pPattern = (const ScPatternAttr*)
+ &pDocument->GetPool()->Put(*pNewPattern);
+
+ if (Concat(nPos))
+ Search(nStart, nPos);
+ else
+ nPos++;
+ }
+ delete pNewBoxItem;
+ delete pNewTLBRItem;
+ delete pNewBLTRItem;
+ delete pNewPattern;
+ }
+ else
+ {
+ nStart = pData[nPos].nRow + 1;
+ nPos++;
+ }
+ }
+ while ((nStart <= nEndRow) && (nPos < nCount));
+ }
+}
+
+#undef SET_LINECOLOR
+#undef SET_LINE
+
+
+void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache )
+{
+#ifdef DBG_UTIL
+ TestData();
+#endif
+
+ if (ValidRow(nStartRow) && ValidRow(nEndRow))
+ {
+ SCSIZE nPos;
+ SCROW nStart=0;
+ if (!Search( nStartRow, nPos ))
+ {
+ DBG_ERROR("Search-Fehler");
+ return;
+ }
+
+ ScAddress aAdrStart( nCol, 0, nTab );
+ ScAddress aAdrEnd ( nCol, 0, nTab );
+
+ do
+ {
+ const ScPatternAttr* pOldPattern = pData[nPos].pPattern;
+ const ScPatternAttr* pNewPattern = (const ScPatternAttr*) &pCache->ApplyTo( *pOldPattern, TRUE );
+ ScDocumentPool::CheckRef( *pOldPattern );
+ ScDocumentPool::CheckRef( *pNewPattern );
+ if (pNewPattern != pOldPattern)
+ {
+ SCROW nY1 = nStart;
+ SCROW nY2 = pData[nPos].nRow;
+ nStart = pData[nPos].nRow + 1;
+
+ if ( nY1 < nStartRow || nY2 > nEndRow )
+ {
+ if (nY1 < nStartRow) nY1=nStartRow;
+ if (nY2 > nEndRow) nY2=nEndRow;
+ SetPatternArea( nY1, nY2, pNewPattern );
+ Search( nStart, nPos );
+ }
+ else
+ {
+ // ueberpruefen, ob Attributierung die Textbreite der Zelle aendert
+
+ const SfxItemSet& rNewSet = pNewPattern->GetItemSet();
+ const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
+
+ BOOL bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
+ rNewSet, rOldSet ) )
+ {
+ aAdrStart.SetRow( nPos ? pData[nPos-1].nRow+1 : 0 );
+ aAdrEnd .SetRow( pData[nPos].nRow );
+ pDocument->InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged );
+#ifdef DBG_INVALIDATE
+ DBGOUTPUT("ApplyCacheArea");
+#endif
+ }
+
+ // bedingte Formate neu gesetzt oder geloescht ?
+
+ if ( &rNewSet.Get(ATTR_CONDITIONAL) != &rOldSet.Get(ATTR_CONDITIONAL) )
+ {
+ pDocument->ConditionalChanged( ((const SfxUInt32Item&)
+ rOldSet.Get(ATTR_CONDITIONAL)).GetValue() );
+ pDocument->ConditionalChanged( ((const SfxUInt32Item&)
+ rNewSet.Get(ATTR_CONDITIONAL)).GetValue() );
+ }
+
+ pDocument->GetPool()->Remove(*pData[nPos].pPattern);
+ pData[nPos].pPattern = pNewPattern;
+ if (Concat(nPos))
+ Search(nStart, nPos);
+ else
+ ++nPos;
+ }
+ }
+ else
+ {
+//!!!!!!!!!!!!!!!!!! mit diesem Remove gibt es Abstuerze (Calc1 Import)
+//! pDocument->GetPool()->Remove(*pNewPattern);
+ nStart = pData[nPos].nRow + 1;
+ ++nPos;
+ }
+ }
+ while (nStart <= nEndRow);
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
+ }
+
+#ifdef DBG_UTIL
+ TestData();
+#endif
+}
+
+
+void lcl_MergeDeep( SfxItemSet& rMergeSet, const SfxItemSet& rSource )
+{
+ const SfxPoolItem* pNewItem;
+ const SfxPoolItem* pOldItem;
+ for (USHORT nId=ATTR_PATTERN_START; nId<=ATTR_PATTERN_END; nId++)
+ {
+ // pMergeSet hat keinen Parent
+ SfxItemState eOldState = rMergeSet.GetItemState( nId, FALSE, &pOldItem );
+
+ if ( eOldState == SFX_ITEM_DEFAULT ) // Default
+ {
+ SfxItemState eNewState = rSource.GetItemState( nId, TRUE, &pNewItem );
+ if ( eNewState == SFX_ITEM_SET )
+ {
+ if ( *pNewItem != rMergeSet.GetPool()->GetDefaultItem(nId) )
+ rMergeSet.InvalidateItem( nId );
+ }
+ }
+ else if ( eOldState == SFX_ITEM_SET ) // Item gesetzt
+ {
+ SfxItemState eNewState = rSource.GetItemState( nId, TRUE, &pNewItem );
+ if ( eNewState == SFX_ITEM_SET )
+ {
+ if ( pNewItem != pOldItem ) // beide gepuhlt
+ rMergeSet.InvalidateItem( nId );
+ }
+ else // Default
+ {
+ if ( *pOldItem != rSource.GetPool()->GetDefaultItem(nId) )
+ rMergeSet.InvalidateItem( nId );
+ }
+ }
+ // Dontcare bleibt Dontcare
+ }
+}
+
+
+void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW nEndRow,
+ ScMergePatternState& rState, BOOL bDeep ) const
+{
+ if (ValidRow(nStartRow) && ValidRow(nEndRow))
+ {
+ SCSIZE nPos;
+ SCROW nStart=0;
+ if (!Search( nStartRow, nPos ))
+ {
+ DBG_ERROR("Search-Fehler");
+ return;
+ }
+
+ do
+ {
+ // gleiche Patterns muessen nicht mehrfach angesehen werden
+
+ const ScPatternAttr* pPattern = pData[nPos].pPattern;
+ if ( pPattern != rState.pOld1 && pPattern != rState.pOld2 )
+ {
+ const SfxItemSet& rThisSet = pPattern->GetItemSet();
+ if (rState.pItemSet)
+ {
+ // (*ppSet)->MergeValues( rThisSet, FALSE );
+ // geht nicht, weil die Vorlagen nicht beruecksichtigt werden
+
+ if (bDeep)
+ lcl_MergeDeep( *rState.pItemSet, rThisSet );
+ else
+ rState.pItemSet->MergeValues( rThisSet, FALSE );
+ }
+ else
+ {
+ // erstes Pattern - in Set ohne Parent kopieren
+ rState.pItemSet = new SfxItemSet( *rThisSet.GetPool(), rThisSet.GetRanges() );
+ rState.pItemSet->Set( rThisSet, bDeep );
+ }
+
+ rState.pOld2 = rState.pOld1;
+ rState.pOld1 = pPattern;
+ }
+
+ nStart = pData[nPos].nRow + 1;
+ ++nPos;
+ }
+ while (nStart <= nEndRow);
+ }
+}
+
+
+
+// Umrandung zusammenbauen
+
+BOOL lcl_TestAttr( const SvxBorderLine* pOldLine, const SvxBorderLine* pNewLine,
+ BYTE& rModified, const SvxBorderLine*& rpNew )
+{
+ if (rModified == SC_LINE_DONTCARE)
+ return FALSE; // weiter geht's nicht
+
+ if (rModified == SC_LINE_EMPTY)
+ {
+ rModified = SC_LINE_SET;
+ rpNew = pNewLine;
+ return TRUE; // zum ersten mal gesetzt
+ }
+
+ if (pOldLine == pNewLine)
+ {
+ rpNew = pOldLine;
+ return FALSE;
+ }
+
+ if (pOldLine && pNewLine)
+ if (*pOldLine == *pNewLine)
+ {
+ rpNew = pOldLine;
+ return FALSE;
+ }
+
+ rModified = SC_LINE_DONTCARE;
+ rpNew = NULL;
+ return TRUE; // andere Linie -> dontcare
+}
+
+
+void lcl_MergeToFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
+ ScLineFlags& rFlags, const ScPatternAttr* pPattern,
+ BOOL bLeft, SCCOL nDistRight, BOOL bTop, SCROW nDistBottom )
+{
+ // rechten/unteren Rahmen setzen, wenn Zelle bis zum Ende zusammengefasst:
+ const ScMergeAttr& rMerge = (const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE);
+ if ( rMerge.GetColMerge() == nDistRight + 1 )
+ nDistRight = 0;
+ if ( rMerge.GetRowMerge() == nDistBottom + 1 )
+ nDistBottom = 0;
+
+ const SvxBoxItem* pCellFrame = (SvxBoxItem*) &pPattern->GetItemSet().Get( ATTR_BORDER );
+ const SvxBorderLine* pLeftAttr = pCellFrame->GetLeft();
+ const SvxBorderLine* pRightAttr = pCellFrame->GetRight();
+ const SvxBorderLine* pTopAttr = pCellFrame->GetTop();
+ const SvxBorderLine* pBottomAttr = pCellFrame->GetBottom();
+ const SvxBorderLine* pNew;
+
+ if (bTop)
+ {
+ if (lcl_TestAttr( pLineOuter->GetTop(), pTopAttr, rFlags.nTop, pNew ))
+ pLineOuter->SetLine( pNew, BOX_LINE_TOP );
+ }
+ else
+ {
+ if (lcl_TestAttr( pLineInner->GetHori(), pTopAttr, rFlags.nHori, pNew ))
+ pLineInner->SetLine( pNew, BOXINFO_LINE_HORI );
+ }
+
+ if (nDistBottom == 0)
+ {
+ if (lcl_TestAttr( pLineOuter->GetBottom(), pBottomAttr, rFlags.nBottom, pNew ))
+ pLineOuter->SetLine( pNew, BOX_LINE_BOTTOM );
+ }
+ else
+ {
+ if (lcl_TestAttr( pLineInner->GetHori(), pBottomAttr, rFlags.nHori, pNew ))
+ pLineInner->SetLine( pNew, BOXINFO_LINE_HORI );
+ }
+
+ if (bLeft)
+ {
+ if (lcl_TestAttr( pLineOuter->GetLeft(), pLeftAttr, rFlags.nLeft, pNew ))
+ pLineOuter->SetLine( pNew, BOX_LINE_LEFT );
+ }
+ else
+ {
+ if (lcl_TestAttr( pLineInner->GetVert(), pLeftAttr, rFlags.nVert, pNew ))
+ pLineInner->SetLine( pNew, BOXINFO_LINE_VERT );
+ }
+
+ if (nDistRight == 0)
+ {
+ if (lcl_TestAttr( pLineOuter->GetRight(), pRightAttr, rFlags.nRight, pNew ))
+ pLineOuter->SetLine( pNew, BOX_LINE_RIGHT );
+ }
+ else
+ {
+ if (lcl_TestAttr( pLineInner->GetVert(), pRightAttr, rFlags.nVert, pNew ))
+ pLineInner->SetLine( pNew, BOXINFO_LINE_VERT );
+ }
+}
+
+
+void ScAttrArray::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
+ ScLineFlags& rFlags,
+ SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight ) const
+{
+ const ScPatternAttr* pPattern;
+
+ if (nStartRow == nEndRow)
+ {
+ pPattern = GetPattern( nStartRow );
+ lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, TRUE, 0 );
+ }
+ else
+ {
+ pPattern = GetPattern( nStartRow );
+ lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, TRUE,
+ nEndRow-nStartRow );
+
+ SCSIZE nStartIndex;
+ SCSIZE nEndIndex;
+ Search( nStartRow+1, nStartIndex );
+ Search( nEndRow-1, nEndIndex );
+ for (SCSIZE i=nStartIndex; i<=nEndIndex; i++)
+ {
+ pPattern = (ScPatternAttr*) pData[i].pPattern;
+ lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, FALSE,
+ nEndRow - Min( pData[i].nRow, (SCROW)(nEndRow-1) ) );
+ // nDistBottom hier immer > 0
+ }
+
+ pPattern = GetPattern( nEndRow );
+ lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, FALSE, 0 );
+ }
+}
+
+//
+// Rahmen anwenden
+//
+
+// ApplyFrame - auf einen Eintrag im Array
+
+
+BOOL ScAttrArray::ApplyFrame( const SvxBoxItem* pBoxItem,
+ const SvxBoxInfoItem* pBoxInfoItem,
+ SCROW nStartRow, SCROW nEndRow,
+ BOOL bLeft, SCCOL nDistRight, BOOL bTop, SCROW nDistBottom )
+{
+ DBG_ASSERT( pBoxItem && pBoxInfoItem, "Linienattribute fehlen!" );
+
+ const ScPatternAttr* pPattern = GetPattern( nStartRow );
+ const SvxBoxItem* pOldFrame = (const SvxBoxItem*)
+ &pPattern->GetItemSet().Get( ATTR_BORDER );
+
+ // rechten/unteren Rahmen setzen, wenn Zelle bis zum Ende zusammengefasst:
+ const ScMergeAttr& rMerge = (const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE);
+ if ( rMerge.GetColMerge() == nDistRight + 1 )
+ nDistRight = 0;
+ if ( rMerge.GetRowMerge() == nDistBottom + 1 )
+ nDistBottom = 0;
+
+ SvxBoxItem aNewFrame( *pOldFrame );
+
+ if ( bLeft ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) )
+ aNewFrame.SetLine( bLeft ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(),
+ BOX_LINE_LEFT );
+ if ( (nDistRight==0) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) )
+ aNewFrame.SetLine( (nDistRight==0) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(),
+ BOX_LINE_RIGHT );
+ if ( bTop ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) )
+ aNewFrame.SetLine( bTop ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(),
+ BOX_LINE_TOP );
+ if ( (nDistBottom==0) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) )
+ aNewFrame.SetLine( (nDistBottom==0) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(),
+ BOX_LINE_BOTTOM );
+
+ if (aNewFrame == *pOldFrame)
+ {
+ // nothing to do
+ return FALSE;
+ }
+ else
+ {
+ SfxItemPoolCache aCache( pDocument->GetPool(), &aNewFrame );
+ ApplyCacheArea( nStartRow, nEndRow, &aCache );
+
+/* ScPatternAttr* pNewPattern = (ScPatternAttr*) pPattern->Clone();
+ pNewPattern->GetItemSet().Put( aNewFrame );
+ SetPatternArea( nStartRow, nEndRow, pNewPattern, TRUE );
+*/
+ return TRUE;
+ }
+}
+
+
+void ScAttrArray::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
+ SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight )
+{
+ if (nStartRow == nEndRow)
+ ApplyFrame( pLineOuter, pLineInner, nStartRow, nEndRow, bLeft, nDistRight, TRUE, 0 );
+ else
+ {
+ ApplyFrame( pLineOuter, pLineInner, nStartRow, nStartRow, bLeft, nDistRight,
+ TRUE, nEndRow-nStartRow );
+
+ if ( nEndRow > nStartRow+1 ) // innerer Teil vorhanden?
+ {
+ SCSIZE nStartIndex;
+ SCSIZE nEndIndex;
+ Search( nStartRow+1, nStartIndex );
+ Search( nEndRow-1, nEndIndex );
+ SCROW nTmpStart = nStartRow+1;
+ SCROW nTmpEnd;
+ for (SCSIZE i=nStartIndex; i<=nEndIndex;)
+ {
+ nTmpEnd = Min( (SCROW)(nEndRow-1), (SCROW)(pData[i].nRow) );
+ BOOL bChanged = ApplyFrame( pLineOuter, pLineInner, nTmpStart, nTmpEnd,
+ bLeft, nDistRight, FALSE, nEndRow-nTmpEnd );
+ nTmpStart = nTmpEnd+1;
+ if (bChanged)
+ {
+ Search(nTmpStart, i);
+ Search(nEndRow-1, nEndIndex);
+ }
+ else
+ i++;
+ }
+ }
+
+ ApplyFrame( pLineOuter, pLineInner, nEndRow, nEndRow, bLeft, nDistRight, FALSE, 0 );
+ }
+}
+
+
+long lcl_LineSize( const SvxBorderLine& rLine )
+{
+ // nur eine Linie -> halbe Breite, min. 20
+ // doppelte Linie -> halber Abstand + eine Linie (je min. 20)
+
+ long nTotal = 0;
+ USHORT nWidth = Max( rLine.GetOutWidth(), rLine.GetInWidth() );
+ USHORT nDist = rLine.GetDistance();
+ if (nDist)
+ {
+ DBG_ASSERT( rLine.GetOutWidth() && rLine.GetInWidth(),
+ "Linie hat Abstand, aber nur eine Breite ???" );
+
+// nTotal += ( nDist > 40 ) ? ( nDist / 2 ) : 20;
+ nTotal += ( nDist > 20 ) ? nDist : 20;
+ nTotal += ( nWidth > 20 ) ? nWidth : 20;
+ }
+ else if (nWidth)
+// nTotal += ( nWidth > 40 ) ? ( nWidth / 2 ) : 20;
+ nTotal += ( nWidth > 20 ) ? nWidth : 20;
+
+ //! auch halbieren ???
+
+ return nTotal;
+}
+
+
+BOOL ScAttrArray::HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes,
+ BOOL bLeft, BOOL bRight ) const
+{
+ SCSIZE nStartIndex;
+ SCSIZE nEndIndex;
+ Search( nRow1, nStartIndex );
+ Search( nRow2, nEndIndex );
+ BOOL bFound = FALSE;
+
+ const SvxBoxItem* pItem = 0;
+ const SvxBorderLine* pLine = 0;
+ long nCmp;
+
+ // oben
+
+ pItem = (const SvxBoxItem*) &pData[nStartIndex].pPattern->GetItem(ATTR_BORDER);
+ pLine = pItem->GetTop();
+ if (pLine)
+ {
+ nCmp = lcl_LineSize(*pLine);
+ if ( nCmp > rSizes.Top() )
+ rSizes.Top() = nCmp;
+ bFound = TRUE;
+ }
+
+ // unten
+
+ if ( nEndIndex != nStartIndex )
+ pItem = (const SvxBoxItem*) &pData[nEndIndex].pPattern->GetItem(ATTR_BORDER);
+ pLine = pItem->GetBottom();
+ if (pLine)
+ {
+ nCmp = lcl_LineSize(*pLine);
+ if ( nCmp > rSizes.Bottom() )
+ rSizes.Bottom() = nCmp;
+ bFound = TRUE;
+ }
+
+ if ( bLeft || bRight )
+ for ( SCSIZE i=nStartIndex; i<=nEndIndex; i++)
+ {
+ pItem = (const SvxBoxItem*) &pData[i].pPattern->GetItem(ATTR_BORDER);
+
+ // links
+
+ if (bLeft)
+ {
+ pLine = pItem->GetLeft();
+ if (pLine)
+ {
+ nCmp = lcl_LineSize(*pLine);
+ if ( nCmp > rSizes.Left() )
+ rSizes.Left() = nCmp;
+ bFound = TRUE;
+ }
+ }
+
+ // rechts
+
+ if (bRight)
+ {
+ pLine = pItem->GetRight();
+ if (pLine)
+ {
+ nCmp = lcl_LineSize(*pLine);
+ if ( nCmp > rSizes.Right() )
+ rSizes.Right() = nCmp;
+ bFound = TRUE;
+ }
+ }
+ }
+
+ return bFound;
+}
+
+// Testen, ob Bereich bestimmtes Attribut enthaelt
+
+bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const
+{
+ SCSIZE nStartIndex;
+ SCSIZE nEndIndex;
+ Search( nRow1, nStartIndex );
+ Search( nRow2, nEndIndex );
+ bool bFound = false;
+
+ for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++)
+ {
+ const ScPatternAttr* pPattern = pData[i].pPattern;
+ if ( nMask & HASATTR_MERGED )
+ {
+ const ScMergeAttr* pMerge =
+ (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
+ if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
+ bFound = true;
+ }
+ if ( nMask & ( HASATTR_OVERLAPPED | HASATTR_NOTOVERLAPPED | HASATTR_AUTOFILTER ) )
+ {
+ const ScMergeFlagAttr* pMergeFlag =
+ (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG );
+ if ( (nMask & HASATTR_OVERLAPPED) && pMergeFlag->IsOverlapped() )
+ bFound = true;
+ if ( (nMask & HASATTR_NOTOVERLAPPED) && !pMergeFlag->IsOverlapped() )
+ bFound = true;
+ if ( (nMask & HASATTR_AUTOFILTER) && pMergeFlag->HasAutoFilter() )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_LINES )
+ {
+ const SvxBoxItem* pBox =
+ (const SvxBoxItem*) &pPattern->GetItem( ATTR_BORDER );
+ if ( pBox->GetLeft() || pBox->GetRight() || pBox->GetTop() || pBox->GetBottom() )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_SHADOW )
+ {
+ const SvxShadowItem* pShadow =
+ (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW );
+ if ( pShadow->GetLocation() != SVX_SHADOW_NONE )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_CONDITIONAL )
+ {
+ const SfxUInt32Item* pConditional =
+ (const SfxUInt32Item*) &pPattern->GetItem( ATTR_CONDITIONAL );
+ if ( pConditional->GetValue() != 0 )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_PROTECTED )
+ {
+ const ScProtectionAttr* pProtect =
+ (const ScProtectionAttr*) &pPattern->GetItem( ATTR_PROTECTION );
+ if ( pProtect->GetProtection() || pProtect->GetHideCell() )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_ROTATE )
+ {
+ const SfxInt32Item* pRotate =
+ (const SfxInt32Item*) &pPattern->GetItem( ATTR_ROTATE_VALUE );
+ // 90 or 270 degrees is former SvxOrientationItem - only look for other values
+ // (see ScPatternAttr::GetCellOrientation)
+ INT32 nAngle = pRotate->GetValue();
+ if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_NEEDHEIGHT )
+ {
+ if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
+ bFound = true;
+ else if (((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue())
+ bFound = true;
+ else if ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK)
+ bFound = true;
+ else if (((const SfxUInt32Item&)pPattern->GetItem( ATTR_CONDITIONAL )).GetValue())
+ bFound = true;
+ else if (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE )).GetValue())
+ bFound = true;
+ }
+ if ( nMask & ( HASATTR_SHADOW_RIGHT | HASATTR_SHADOW_DOWN ) )
+ {
+ const SvxShadowItem* pShadow =
+ (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW );
+ SvxShadowLocation eLoc = pShadow->GetLocation();
+ if ( nMask & HASATTR_SHADOW_RIGHT )
+ if ( eLoc == SVX_SHADOW_TOPRIGHT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
+ bFound = true;
+ if ( nMask & HASATTR_SHADOW_DOWN )
+ if ( eLoc == SVX_SHADOW_BOTTOMLEFT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_RTL )
+ {
+ const SvxFrameDirectionItem& rDirection =
+ (const SvxFrameDirectionItem&) pPattern->GetItem( ATTR_WRITINGDIR );
+ if ( rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP )
+ bFound = true;
+ }
+ if ( nMask & HASATTR_RIGHTORCENTER )
+ {
+ // called only if the sheet is LTR, so physical=logical alignment can be assumed
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)
+ ((const SvxHorJustifyItem&) pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
+ if ( eHorJust == SVX_HOR_JUSTIFY_RIGHT || eHorJust == SVX_HOR_JUSTIFY_CENTER )
+ bFound = true;
+ }
+ }
+
+ return bFound;
+}
+
+// Bereich um evtl. enthaltene Zusammenfassungen erweitern
+// und evtl. MergeFlag anpassen (bRefresh)
+
+BOOL ScAttrArray::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
+ SCCOL& rPaintCol, SCROW& rPaintRow,
+ BOOL bRefresh, BOOL bAttrs )
+{
+ const ScPatternAttr* pPattern;
+ const ScMergeAttr* pItem;
+ SCSIZE nStartIndex;
+ SCSIZE nEndIndex;
+ Search( nStartRow, nStartIndex );
+ Search( nEndRow, nEndIndex );
+ BOOL bFound = FALSE;
+
+ for (SCSIZE i=nStartIndex; i<=nEndIndex; i++)
+ {
+ pPattern = pData[i].pPattern;
+ pItem = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
+ SCsCOL nCountX = pItem->GetColMerge();
+ SCsROW nCountY = pItem->GetRowMerge();
+ if (nCountX>1 || nCountY>1)
+ {
+ SCROW nThisRow = (i>0) ? pData[i-1].nRow+1 : 0;
+ SCCOL nMergeEndCol = nThisCol + nCountX - 1;
+ SCROW nMergeEndRow = nThisRow + nCountY - 1;
+ if (nMergeEndCol > rPaintCol && nMergeEndCol <= MAXCOL)
+ rPaintCol = nMergeEndCol;
+ if (nMergeEndRow > rPaintRow && nMergeEndRow <= MAXROW)
+ rPaintRow = nMergeEndRow;
+ bFound = TRUE;
+
+ if (bAttrs)
+ {
+ const SvxShadowItem* pShadow =
+ (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW );
+ SvxShadowLocation eLoc = pShadow->GetLocation();
+ if ( eLoc == SVX_SHADOW_TOPRIGHT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
+ if ( nMergeEndCol+1 > rPaintCol && nMergeEndCol < MAXCOL )
+ rPaintCol = nMergeEndCol+1;
+ if ( eLoc == SVX_SHADOW_BOTTOMLEFT || eLoc == SVX_SHADOW_BOTTOMRIGHT )
+ if ( nMergeEndRow+1 > rPaintRow && nMergeEndRow < MAXROW )
+ rPaintRow = nMergeEndRow+1;
+ }
+
+ if (bRefresh)
+ {
+ if ( nMergeEndCol > nThisCol )
+ pDocument->ApplyFlagsTab( nThisCol+1, nThisRow, nMergeEndCol, pData[i].nRow,
+ nTab, SC_MF_HOR );
+ if ( nMergeEndRow > nThisRow )
+ pDocument->ApplyFlagsTab( nThisCol, nThisRow+1, nThisCol, nMergeEndRow,
+ nTab, SC_MF_VER );
+ if ( nMergeEndCol > nThisCol && nMergeEndRow > nThisRow )
+ pDocument->ApplyFlagsTab( nThisCol+1, nThisRow+1, nMergeEndCol, nMergeEndRow,
+ nTab, SC_MF_HOR | SC_MF_VER );
+
+ Search( nThisRow, i ); // Daten wurden veraendert
+ Search( nStartRow, nStartIndex );
+ Search( nEndRow, nEndIndex );
+ }
+ }
+ }
+
+ return bFound;
+}
+
+
+BOOL ScAttrArray::RemoveAreaMerge(SCROW nStartRow, SCROW nEndRow)
+{
+ BOOL bFound = FALSE;
+ const ScPatternAttr* pPattern;
+ const ScMergeAttr* pItem;
+ SCSIZE nIndex;
+
+ Search( nStartRow, nIndex );
+ SCROW nThisStart = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ if (nThisStart < nStartRow)
+ nThisStart = nStartRow;
+
+ while ( nThisStart <= nEndRow )
+ {
+ SCROW nThisEnd = pData[nIndex].nRow;
+ if (nThisEnd > nEndRow)
+ nThisEnd = nEndRow;
+
+ pPattern = pData[nIndex].pPattern;
+ pItem = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
+ SCsCOL nCountX = pItem->GetColMerge();
+ SCsROW nCountY = pItem->GetRowMerge();
+ if (nCountX>1 || nCountY>1)
+ {
+ const ScMergeAttr* pAttr = (const ScMergeAttr*)
+ &pDocument->GetPool()->GetDefaultItem( ATTR_MERGE );
+ const ScMergeFlagAttr* pFlagAttr = (const ScMergeFlagAttr*)
+ &pDocument->GetPool()->GetDefaultItem( ATTR_MERGE_FLAG );
+
+ DBG_ASSERT( nCountY==1 || nThisStart==nThisEnd, "was'n hier los?" );
+
+ SCCOL nThisCol = nCol;
+ SCCOL nMergeEndCol = nThisCol + nCountX - 1;
+ SCROW nMergeEndRow = nThisEnd + nCountY - 1;
+
+ //! ApplyAttr fuer Bereiche !!!
+
+ for (SCROW nThisRow = nThisStart; nThisRow <= nThisEnd; nThisRow++)
+ pDocument->ApplyAttr( nThisCol, nThisRow, nTab, *pAttr );
+
+ ScPatternAttr* pNewPattern = new ScPatternAttr( pDocument->GetPool() );
+ SfxItemSet* pSet = &pNewPattern->GetItemSet();
+ pSet->Put( *pFlagAttr );
+ pDocument->ApplyPatternAreaTab( nThisCol, nThisStart, nMergeEndCol, nMergeEndRow,
+ nTab, *pNewPattern );
+ delete pNewPattern;
+
+ Search( nThisEnd, nIndex ); // Daten wurden veraendert !!!
+ }
+
+ ++nIndex;
+ if ( nIndex < nCount )
+ nThisStart = pData[nIndex-1].nRow+1;
+ else
+ nThisStart = MAXROW+1; // Ende
+ }
+
+ return bFound;
+}
+
+ // Bereich loeschen, aber Merge-Flags stehenlassen
+
+void ScAttrArray::DeleteAreaSafe(SCROW nStartRow, SCROW nEndRow)
+{
+ SetPatternAreaSafe( nStartRow, nEndRow, pDocument->GetDefPattern(), TRUE );
+}
+
+
+void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow,
+ const ScPatternAttr* pWantedPattern, BOOL bDefault )
+{
+ const ScPatternAttr* pOldPattern;
+ const ScMergeFlagAttr* pItem;
+
+ SCSIZE nIndex;
+ SCROW nRow;
+ SCROW nThisRow;
+ BOOL bFirstUse = TRUE;
+
+ Search( nStartRow, nIndex );
+ nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ while ( nThisRow <= nEndRow )
+ {
+ pOldPattern = pData[nIndex].pPattern;
+ if (pOldPattern != pWantedPattern) //! else-Zweig ?
+ {
+ if (nThisRow < nStartRow) nThisRow = nStartRow;
+ nRow = pData[nIndex].nRow;
+ SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
+ pItem = (const ScMergeFlagAttr*) &pOldPattern->GetItem( ATTR_MERGE_FLAG );
+
+ if (pItem->IsOverlapped() || pItem->HasAutoFilter())
+ {
+ // #108045# default-constructing a ScPatternAttr for DeleteArea doesn't work
+ // because it would have no cell style information.
+ // Instead, the document's GetDefPattern is copied. Since it is passed as
+ // pWantedPattern, no special treatment of default is needed here anymore.
+ ScPatternAttr* pNewPattern = new ScPatternAttr( *pWantedPattern );
+ SfxItemSet* pSet = &pNewPattern->GetItemSet();
+ pSet->Put( *pItem );
+ SetPatternArea( nThisRow, nAttrRow, pNewPattern, TRUE );
+ delete pNewPattern;
+ }
+ else
+ {
+ if ( !bDefault )
+ {
+ if (bFirstUse)
+ bFirstUse = FALSE;
+ else
+ pDocument->GetPool()->Put( *pWantedPattern ); // im Pool ist es schon!
+ }
+ SetPatternArea( nThisRow, nAttrRow, pWantedPattern );
+ }
+
+ Search( nThisRow, nIndex ); // Daten wurden veraendert !!!
+ }
+
+ ++nIndex;
+ nThisRow = pData[nIndex-1].nRow+1;
+ }
+}
+
+
+BOOL ScAttrArray::ApplyFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags )
+{
+ const ScPatternAttr* pOldPattern;
+
+ INT16 nOldValue;
+ SCSIZE nIndex;
+ SCROW nRow;
+ SCROW nThisRow;
+ BOOL bChanged = FALSE;
+
+ Search( nStartRow, nIndex );
+ nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ if (nThisRow < nStartRow) nThisRow = nStartRow;
+
+ while ( nThisRow <= nEndRow )
+ {
+ pOldPattern = pData[nIndex].pPattern;
+ nOldValue = ((const ScMergeFlagAttr*) &pOldPattern->GetItem( ATTR_MERGE_FLAG ))->GetValue();
+ if ( (nOldValue | nFlags) != nOldValue )
+ {
+ nRow = pData[nIndex].nRow;
+ SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
+ ScPatternAttr aNewPattern(*pOldPattern);
+ aNewPattern.GetItemSet().Put( ScMergeFlagAttr( nOldValue | nFlags ) );
+ SetPatternArea( nThisRow, nAttrRow, &aNewPattern, TRUE );
+ Search( nThisRow, nIndex ); // Daten wurden veraendert !!!
+ bChanged = TRUE;
+ }
+
+ ++nIndex;
+ nThisRow = pData[nIndex-1].nRow+1;
+ }
+
+ return bChanged;
+}
+
+
+BOOL ScAttrArray::RemoveFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags )
+{
+ const ScPatternAttr* pOldPattern;
+
+ INT16 nOldValue;
+ SCSIZE nIndex;
+ SCROW nRow;
+ SCROW nThisRow;
+ BOOL bChanged = FALSE;
+
+ Search( nStartRow, nIndex );
+ nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ if (nThisRow < nStartRow) nThisRow = nStartRow;
+
+ while ( nThisRow <= nEndRow )
+ {
+ pOldPattern = pData[nIndex].pPattern;
+ nOldValue = ((const ScMergeFlagAttr*) &pOldPattern->GetItem( ATTR_MERGE_FLAG ))->GetValue();
+ if ( (nOldValue & ~nFlags) != nOldValue )
+ {
+ nRow = pData[nIndex].nRow;
+ SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
+ ScPatternAttr aNewPattern(*pOldPattern);
+ aNewPattern.GetItemSet().Put( ScMergeFlagAttr( nOldValue & ~nFlags ) );
+ SetPatternArea( nThisRow, nAttrRow, &aNewPattern, TRUE );
+ Search( nThisRow, nIndex ); // Daten wurden veraendert !!!
+ bChanged = TRUE;
+ }
+
+ ++nIndex;
+ nThisRow = pData[nIndex-1].nRow+1;
+ }
+
+ return bChanged;
+}
+
+
+void ScAttrArray::ClearItems( SCROW nStartRow, SCROW nEndRow, const USHORT* pWhich )
+{
+ const ScPatternAttr* pOldPattern;
+
+ SCSIZE nIndex;
+ SCROW nRow;
+ SCROW nThisRow;
+
+ Search( nStartRow, nIndex );
+ nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ if (nThisRow < nStartRow) nThisRow = nStartRow;
+
+ while ( nThisRow <= nEndRow )
+ {
+ pOldPattern = pData[nIndex].pPattern;
+ if ( pOldPattern->HasItemsSet( pWhich ) )
+ {
+ ScPatternAttr aNewPattern(*pOldPattern);
+ aNewPattern.ClearItems( pWhich );
+
+ nRow = pData[nIndex].nRow;
+ SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
+ SetPatternArea( nThisRow, nAttrRow, &aNewPattern, TRUE );
+ Search( nThisRow, nIndex ); // Daten wurden veraendert !!!
+ }
+
+ ++nIndex;
+ nThisRow = pData[nIndex-1].nRow+1;
+ }
+}
+
+
+void ScAttrArray::ChangeIndent( SCROW nStartRow, SCROW nEndRow, BOOL bIncrement )
+{
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ SCROW nThisStart = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ if (nThisStart < nStartRow) nThisStart = nStartRow;
+
+ while ( nThisStart <= nEndRow )
+ {
+ const ScPatternAttr* pOldPattern = pData[nIndex].pPattern;
+ const SfxItemSet& rOldSet = pOldPattern->GetItemSet();
+ const SfxPoolItem* pItem;
+
+ BOOL bNeedJust = ( rOldSet.GetItemState( ATTR_HOR_JUSTIFY, FALSE, &pItem ) != SFX_ITEM_SET
+ || ((const SvxHorJustifyItem*)pItem)->GetValue() != SVX_HOR_JUSTIFY_LEFT );
+ USHORT nOldValue = ((const SfxUInt16Item&)rOldSet.Get( ATTR_INDENT )).GetValue();
+ USHORT nNewValue = nOldValue;
+ if ( bIncrement )
+ {
+ if ( nNewValue < SC_MAX_INDENT )
+ {
+ nNewValue += SC_INDENT_STEP;
+ if ( nNewValue > SC_MAX_INDENT ) nNewValue = SC_MAX_INDENT;
+ }
+ }
+ else
+ {
+ if ( nNewValue > 0 )
+ {
+ if ( nNewValue > SC_INDENT_STEP )
+ nNewValue -= SC_INDENT_STEP;
+ else
+ nNewValue = 0;
+ }
+ }
+
+ if ( bNeedJust || nNewValue != nOldValue )
+ {
+ SCROW nThisEnd = pData[nIndex].nRow;
+ SCROW nAttrRow = Min( nThisEnd, nEndRow );
+ ScPatternAttr aNewPattern(*pOldPattern);
+ aNewPattern.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT, nNewValue ) );
+ if ( bNeedJust )
+ aNewPattern.GetItemSet().Put(
+ SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
+ SetPatternArea( nThisStart, nAttrRow, &aNewPattern, TRUE );
+
+ nThisStart = nThisEnd + 1;
+ Search( nThisStart, nIndex ); // Daten wurden veraendert !!!
+ }
+ else
+ {
+ nThisStart = pData[nIndex].nRow + 1; // weiterzaehlen...
+ ++nIndex;
+ }
+ }
+}
+
+
+SCsROW ScAttrArray::GetNextUnprotected( SCsROW nRow, BOOL bUp ) const
+{
+ long nRet = nRow;
+ if (VALIDROW(nRow))
+ {
+ SCSIZE nIndex;
+ Search(nRow, nIndex);
+ while (((const ScProtectionAttr&)pData[nIndex].pPattern->
+ GetItem(ATTR_PROTECTION)).GetProtection())
+ {
+ if (bUp)
+ {
+ if (nIndex==0)
+ return -1; // nichts gefunden
+ --nIndex;
+ nRet = pData[nIndex].nRow;
+ }
+ else
+ {
+ nRet = pData[nIndex].nRow+1;
+ ++nIndex;
+ if (nIndex>=nCount)
+ return MAXROW+1; // nichts gefunden
+ }
+ }
+ }
+ return nRet;
+}
+
+void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
+{
+ SCROW nStart = 0;
+ SCSIZE nPos = 0;
+ while (nPos < nCount)
+ {
+ SCROW nEnd = pData[nPos].nRow;
+ if (pData[nPos].pPattern->GetStyleSheet() == pStyleSheet)
+ {
+// for (SCROW nRow = nStart; nRow <= nEnd; nRow++)
+// pUsed[nRow] = TRUE;
+
+ rUsedRows.setTrue(nStart, nEnd);
+
+ if (bReset)
+ {
+ ScPatternAttr* pNewPattern = new ScPatternAttr(*pData[nPos].pPattern);
+ pDocument->GetPool()->Remove(*pData[nPos].pPattern);
+ pNewPattern->SetStyleSheet( (ScStyleSheet*)
+ pDocument->GetStyleSheetPool()->
+ Find( ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
+ SFX_STYLE_FAMILY_PARA,
+ SFXSTYLEBIT_AUTO | SCSTYLEBIT_STANDARD ) );
+ pData[nPos].pPattern = (const ScPatternAttr*)
+ &pDocument->GetPool()->Put(*pNewPattern);
+ delete pNewPattern;
+
+ if (Concat(nPos))
+ {
+ Search(nStart, nPos);
+ --nPos; // wegen ++ am Ende
+ }
+ }
+ }
+ nStart = nEnd + 1;
+ ++nPos;
+ }
+}
+
+
+BOOL ScAttrArray::IsStyleSheetUsed( const ScStyleSheet& rStyle,
+ BOOL bGatherAllStyles ) const
+{
+ BOOL bIsUsed = FALSE;
+ SCSIZE nPos = 0;
+
+ while ( nPos < nCount )
+ {
+ const ScStyleSheet* pStyle = pData[nPos].pPattern->GetStyleSheet();
+ if ( pStyle )
+ {
+ pStyle->SetUsage( ScStyleSheet::USED );
+ if ( pStyle == &rStyle )
+ {
+ if ( !bGatherAllStyles )
+ return TRUE;
+ bIsUsed = TRUE;
+ }
+ }
+ nPos++;
+ }
+
+ return bIsUsed;
+}
+
+
+BOOL ScAttrArray::IsEmpty() const
+{
+ if (nCount == 1)
+ {
+ if ( pData[0].pPattern != pDocument->GetDefPattern() )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+//UNUSED2008-05 SCROW ScAttrArray::GetFirstEntryPos() const
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ASSERT( nCount, "nCount = 0" );
+//UNUSED2008-05
+//UNUSED2008-05 if ( pData[0].pPattern != pDocument->GetDefPattern() )
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 if (nCount==1)
+//UNUSED2008-05 return 0; // leer
+//UNUSED2008-05 else
+//UNUSED2008-05 return pData[0].nRow + 1;
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05
+//UNUSED2008-05 SCROW ScAttrArray::GetLastEntryPos( BOOL bIncludeBottom ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ASSERT( nCount, "nCount == 0" );
+//UNUSED2008-05
+//UNUSED2008-05 if (bIncludeBottom)
+//UNUSED2008-05 bIncludeBottom = ( pData[nCount-1].pPattern != pDocument->GetDefPattern() );
+//UNUSED2008-05
+//UNUSED2008-05 if (bIncludeBottom)
+//UNUSED2008-05 return MAXROW;
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 if (nCount<=1)
+//UNUSED2008-05 return 0; // leer
+//UNUSED2008-05 else
+//UNUSED2008-05 return pData[nCount-2].nRow;
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+
+BOOL ScAttrArray::GetFirstVisibleAttr( SCROW& rFirstRow ) const
+{
+ DBG_ASSERT( nCount, "nCount == 0" );
+
+ BOOL bFound = FALSE;
+ SCSIZE nStart = 0;
+
+ // Skip first entry if more than 1 row.
+ // Entries at the end are not skipped, GetFirstVisibleAttr may be larger than GetLastVisibleAttr.
+
+ SCSIZE nVisStart = 1;
+ while ( nVisStart < nCount && pData[nVisStart].pPattern->IsVisibleEqual(*pData[nVisStart-1].pPattern) )
+ ++nVisStart;
+ if ( nVisStart >= nCount || pData[nVisStart-1].nRow > 0 ) // more than 1 row?
+ nStart = nVisStart;
+
+ while ( nStart < nCount && !bFound )
+ {
+ if ( pData[nStart].pPattern->IsVisible() )
+ {
+ rFirstRow = nStart ? ( pData[nStart-1].nRow + 1 ) : 0;
+ bFound = TRUE;
+ }
+ else
+ ++nStart;
+ }
+
+ return bFound;
+}
+
+// size (rows) of a range of attributes after cell content where the search is stopped
+// (more than a default page size, 2*42 because it's as good as any number)
+
+const SCROW SC_VISATTR_STOP = 84;
+
+BOOL ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData ) const
+{
+ // #i30830# changed behavior:
+ // ignore all attributes starting with the first run of SC_VISATTR_STOP equal rows
+ // below the last content cell
+
+ if ( nLastData == MAXROW )
+ {
+ rLastRow = MAXROW; // can't look for attributes below MAXROW
+ return TRUE;
+ }
+
+ BOOL bFound = FALSE;
+
+ // loop backwards from the end instead of using Search, assuming that
+ // there usually aren't many attributes below the last cell
+
+ SCSIZE nPos = nCount;
+ while ( nPos > 0 && pData[nPos-1].nRow > nLastData )
+ {
+ SCSIZE nEndPos = nPos - 1;
+ SCSIZE nStartPos = nEndPos; // find range of visually equal formats
+ while ( nStartPos > 0 &&
+ pData[nStartPos-1].nRow > nLastData &&
+ pData[nStartPos-1].pPattern->IsVisibleEqual(*pData[nStartPos].pPattern) )
+ --nStartPos;
+
+ SCROW nAttrStartRow = ( nStartPos > 0 ) ? ( pData[nStartPos-1].nRow + 1 ) : 0;
+ if ( nAttrStartRow <= nLastData )
+ nAttrStartRow = nLastData + 1;
+ SCROW nAttrSize = pData[nEndPos].nRow + 1 - nAttrStartRow;
+ if ( nAttrSize >= SC_VISATTR_STOP )
+ {
+ bFound = FALSE; // ignore this range and below
+ }
+ else if ( !bFound && pData[nEndPos].pPattern->IsVisible() )
+ {
+ rLastRow = pData[nEndPos].nRow;
+ bFound = TRUE;
+ }
+
+ nPos = nStartPos; // look further from the top of the range
+ }
+
+ return bFound;
+}
+
+
+BOOL ScAttrArray::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const
+{
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ SCROW nThisStart = nStartRow;
+ BOOL bFound = FALSE;
+ while ( nIndex < nCount && nThisStart <= nEndRow && !bFound )
+ {
+ if ( pData[nIndex].pPattern->IsVisible() )
+ bFound = TRUE;
+
+ nThisStart = pData[nIndex].nRow + 1;
+ ++nIndex;
+ }
+
+ return bFound;
+}
+
+
+BOOL ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther,
+ SCROW nStartRow, SCROW nEndRow ) const
+{
+ BOOL bEqual = TRUE;
+ SCSIZE nThisPos = 0;
+ SCSIZE nOtherPos = 0;
+ if ( nStartRow > 0 )
+ {
+ Search( nStartRow, nThisPos );
+ rOther.Search( nStartRow, nOtherPos );
+ }
+
+ while ( nThisPos<nCount && nOtherPos<rOther.nCount && bEqual )
+ {
+ SCROW nThisRow = pData[nThisPos].nRow;
+ SCROW nOtherRow = rOther.pData[nOtherPos].nRow;
+ const ScPatternAttr* pThisPattern = pData[nThisPos].pPattern;
+ const ScPatternAttr* pOtherPattern = rOther.pData[nOtherPos].pPattern;
+ bEqual = ( pThisPattern == pOtherPattern ||
+ pThisPattern->IsVisibleEqual(*pOtherPattern) );
+
+ if ( nThisRow >= nOtherRow )
+ {
+ if ( nOtherRow >= nEndRow ) break;
+ ++nOtherPos;
+ }
+ if ( nThisRow <= nOtherRow )
+ {
+ if ( nThisRow >= nEndRow ) break;
+ ++nThisPos;
+ }
+ }
+
+ return bEqual;
+}
+
+
+BOOL ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW nEndRow ) const
+{
+ //! mit IsVisibleEqual zusammenfassen?
+
+ BOOL bEqual = TRUE;
+ SCSIZE nThisPos = 0;
+ SCSIZE nOtherPos = 0;
+ if ( nStartRow > 0 )
+ {
+ Search( nStartRow, nThisPos );
+ rOther.Search( nStartRow, nOtherPos );
+ }
+
+ while ( nThisPos<nCount && nOtherPos<rOther.nCount && bEqual )
+ {
+ SCROW nThisRow = pData[nThisPos].nRow;
+ SCROW nOtherRow = rOther.pData[nOtherPos].nRow;
+ const ScPatternAttr* pThisPattern = pData[nThisPos].pPattern;
+ const ScPatternAttr* pOtherPattern = rOther.pData[nOtherPos].pPattern;
+ bEqual = ( pThisPattern == pOtherPattern );
+
+ if ( nThisRow >= nOtherRow )
+ {
+ if ( nOtherRow >= nEndRow ) break;
+ ++nOtherPos;
+ }
+ if ( nThisRow <= nOtherRow )
+ {
+ if ( nThisRow >= nEndRow ) break;
+ ++nThisPos;
+ }
+ }
+
+ return bEqual;
+}
+
+
+BOOL ScAttrArray::TestInsertCol( SCROW nStartRow, SCROW nEndRow) const
+{
+ // horizontal zusammengefasste duerfen nicht herausgeschoben werden
+ // (ob die ganze Zusammenfassung betroffen ist, ist hier nicht zu erkennen)
+
+ BOOL bTest = TRUE;
+ if (!IsEmpty())
+ {
+ SCSIZE nIndex = 0;
+ if ( nStartRow > 0 )
+ Search( nStartRow, nIndex );
+
+ for ( ; nIndex < nCount; nIndex++ )
+ {
+ if ( ((const ScMergeFlagAttr&)pData[nIndex].pPattern->
+ GetItem(ATTR_MERGE_FLAG)).IsHorOverlapped() )
+ {
+ bTest = FALSE; // darf nicht herausgeschoben werden
+ break;
+ }
+ if ( pData[nIndex].nRow >= nEndRow ) // Ende des Bereichs
+ break;
+ }
+ }
+ return bTest;
+}
+
+
+BOOL ScAttrArray::TestInsertRow( SCSIZE nSize ) const
+{
+ // wenn die erste herausgeschobene Zeile vertikal ueberlappt ist,
+ // wuerde eine kaputte Zusammenfassung uebrigbleiben
+
+ if (pData)
+ {
+ // MAXROW + 1 - nSize = erste herausgeschobene Zeile
+
+ SCSIZE nFirstLost = nCount-1;
+ while ( nFirstLost && pData[nFirstLost-1].nRow >= sal::static_int_cast<SCROW>(MAXROW + 1 - nSize) )
+ --nFirstLost;
+
+ if ( ((const ScMergeFlagAttr&)pData[nFirstLost].pPattern->
+ GetItem(ATTR_MERGE_FLAG)).IsVerOverlapped() )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+void ScAttrArray::InsertRow( SCROW nStartRow, SCSIZE nSize )
+{
+ if (!pData)
+ return;
+
+ SCROW nSearch = nStartRow > 0 ? nStartRow - 1 : 0; // Vorgaenger erweitern
+ SCSIZE nIndex;
+ Search( nSearch, nIndex );
+
+ // ein gesetztes ScMergeAttr darf nicht ausgedehnt werden
+ // (darum hinterher wieder loeschen)
+
+ BOOL bDoMerge = ((const ScMergeAttr&) pData[nIndex].pPattern->GetItem(ATTR_MERGE)).IsMerged();
+
+ SCSIZE nRemove = 0;
+ SCSIZE i;
+ for (i = nIndex; i < nCount-1; i++)
+ {
+ SCROW nNew = pData[i].nRow + nSize;
+ if ( nNew >= MAXROW ) // Ende erreicht ?
+ {
+ nNew = MAXROW;
+ if (!nRemove)
+ nRemove = i+1; // folgende loeschen
+ }
+ pData[i].nRow = nNew;
+ }
+
+ // muessen Eintraege am Ende geloescht werden?
+
+ if (nRemove && nRemove < nCount)
+ DeleteRange( nRemove, nCount-1 );
+
+ if (bDoMerge) // ausgedehntes ScMergeAttr wieder reparieren
+ {
+ //! ApplyAttr fuer Bereiche !!!
+
+ const SfxPoolItem& rDef = pDocument->GetPool()->GetDefaultItem( ATTR_MERGE );
+ for (SCSIZE nAdd=0; nAdd<nSize; nAdd++)
+ pDocument->ApplyAttr( nCol, nStartRow+nAdd, nTab, rDef );
+
+ // im eingefuegten Bereich ist nichts zusammengefasst
+ }
+
+ // Don't duplicate the merge flags in the inserted row.
+ // #i108488# SC_MF_SCENARIO has to be allowed.
+ RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO | SC_MF_BUTTON );
+}
+
+
+void ScAttrArray::DeleteRow( SCROW nStartRow, SCSIZE nSize )
+{
+ if (pData)
+ {
+ BOOL bFirst=TRUE;
+ SCSIZE nStartIndex = 0;
+ SCSIZE nEndIndex = 0;
+ SCSIZE i;
+
+ for ( i = 0; i < nCount-1; i++)
+ if (pData[i].nRow >= nStartRow && pData[i].nRow <= sal::static_int_cast<SCROW>(nStartRow+nSize-1))
+ {
+ if (bFirst)
+ {
+ nStartIndex = i;
+ bFirst = FALSE;
+ }
+ nEndIndex = i;
+ }
+ if (!bFirst)
+ {
+ SCROW nStart;
+ if (nStartIndex==0)
+ nStart = 0;
+ else
+ nStart = pData[nStartIndex-1].nRow + 1;
+
+ if (nStart < nStartRow)
+ {
+ pData[nStartIndex].nRow = nStartRow - 1;
+ ++nStartIndex;
+ }
+ if (nEndIndex >= nStartIndex)
+ {
+ DeleteRange( nStartIndex, nEndIndex );
+ if (nStartIndex > 0)
+ if ( pData[nStartIndex-1].pPattern == pData[nStartIndex].pPattern )
+ DeleteRange( nStartIndex-1, nStartIndex-1 );
+ }
+ }
+ for (i = 0; i < nCount-1; i++)
+ if (pData[i].nRow >= nStartRow)
+ pData[i].nRow -= nSize;
+
+// unten nicht Default-Pattern nachschieben, um Druckbereiche erkennen zu koennen
+// stattdessen nur Merge-Flags loeschen
+
+ RemoveFlags( MAXROW-nSize+1, MAXROW, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
+ }
+}
+
+
+void ScAttrArray::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex )
+{
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+ for (SCSIZE i = nStartIndex; i <= nEndIndex; i++)
+ pDocPool->Remove(*pData[i].pPattern);
+
+ memmove( &pData[nStartIndex], &pData[nEndIndex + 1], (nCount - nEndIndex - 1) * sizeof(ScAttrEntry) );
+ nCount -= nEndIndex-nStartIndex+1;
+}
+
+
+void ScAttrArray::DeleteArea(SCROW nStartRow, SCROW nEndRow)
+{
+ RemoveAreaMerge( nStartRow, nEndRow ); // von zusammengefassten auch die Flags loeschen
+
+ if ( !HasAttrib( nStartRow, nEndRow, HASATTR_OVERLAPPED | HASATTR_AUTOFILTER) )
+ SetPatternArea( nStartRow, nEndRow, pDocument->GetDefPattern() );
+ else
+ DeleteAreaSafe( nStartRow, nEndRow ); // Merge-Flags stehenlassen
+}
+
+
+void ScAttrArray::DeleteHardAttr(SCROW nStartRow, SCROW nEndRow)
+{
+ const ScPatternAttr* pDefPattern = pDocument->GetDefPattern();
+ const ScPatternAttr* pOldPattern;
+
+ SCSIZE nIndex;
+ SCROW nRow;
+ SCROW nThisRow;
+
+ Search( nStartRow, nIndex );
+ nThisRow = (nIndex>0) ? pData[nIndex-1].nRow+1 : 0;
+ if (nThisRow < nStartRow) nThisRow = nStartRow;
+
+ while ( nThisRow <= nEndRow )
+ {
+ pOldPattern = pData[nIndex].pPattern;
+
+ if ( pOldPattern->GetItemSet().Count() ) // harte Attribute ?
+ {
+ nRow = pData[nIndex].nRow;
+ SCROW nAttrRow = Min( (SCROW)nRow, (SCROW)nEndRow );
+
+ ScPatternAttr aNewPattern(*pOldPattern);
+ SfxItemSet& rSet = aNewPattern.GetItemSet();
+ for (USHORT nId = ATTR_PATTERN_START; nId <= ATTR_PATTERN_END; nId++)
+ if (nId != ATTR_MERGE && nId != ATTR_MERGE_FLAG)
+ rSet.ClearItem(nId);
+
+ if ( aNewPattern == *pDefPattern )
+ SetPatternArea( nThisRow, nAttrRow, pDefPattern, FALSE );
+ else
+ SetPatternArea( nThisRow, nAttrRow, &aNewPattern, TRUE );
+
+ Search( nThisRow, nIndex ); // Daten wurden veraendert !!!
+ }
+
+ ++nIndex;
+ nThisRow = pData[nIndex-1].nRow+1;
+ }
+}
+
+ // Verschieben innerhalb eines Dokuments
+
+void ScAttrArray::MoveTo(SCROW nStartRow, SCROW nEndRow, ScAttrArray& rAttrArray)
+{
+ SCROW nStart = nStartRow;
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ if ((pData[i].nRow >= nStartRow) && ((i==0) ? TRUE : pData[i-1].nRow < nEndRow))
+ {
+ // Kopieren (bPutToPool=TRUE)
+ rAttrArray.SetPatternArea( nStart, Min( (SCROW)pData[i].nRow, (SCROW)nEndRow ),
+ pData[i].pPattern, TRUE );
+ }
+ nStart = Max( (SCROW)nStart, (SCROW)(pData[i].nRow + 1) );
+ }
+ DeleteArea(nStartRow, nEndRow);
+}
+
+
+ // Kopieren zwischen Dokumenten (Clipboard)
+
+void ScAttrArray::CopyArea( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray,
+ INT16 nStripFlags )
+{
+ nStartRow -= nDy; // Source
+ nEndRow -= nDy;
+
+ SCROW nDestStart = Max((long)((long)nStartRow + nDy), (long) 0);
+ SCROW nDestEnd = Min((long)((long)nEndRow + nDy), (long) MAXROW);
+
+ ScDocumentPool* pSourceDocPool = pDocument->GetPool();
+ ScDocumentPool* pDestDocPool = rAttrArray.pDocument->GetPool();
+ BOOL bSamePool = (pSourceDocPool==pDestDocPool);
+
+ for (SCSIZE i = 0; (i < nCount) && (nDestStart <= nDestEnd); i++)
+ {
+ if (pData[i].nRow >= nStartRow)
+ {
+ const ScPatternAttr* pOldPattern = pData[i].pPattern;
+ const ScPatternAttr* pNewPattern;
+
+ if (IsDefaultItem( pOldPattern ))
+ {
+ // am Default muss nichts veraendert werden
+
+ pNewPattern = (const ScPatternAttr*)
+ &pDestDocPool->GetDefaultItem( ATTR_PATTERN );
+ }
+ else if ( nStripFlags )
+ {
+ ScPatternAttr* pTmpPattern = new ScPatternAttr( *pOldPattern );
+ INT16 nNewFlags = 0;
+ if ( nStripFlags != SC_MF_ALL )
+ nNewFlags = ((const ScMergeFlagAttr&)pTmpPattern->GetItem(ATTR_MERGE_FLAG)).
+ GetValue() & ~nStripFlags;
+
+ if ( nNewFlags )
+ pTmpPattern->GetItemSet().Put( ScMergeFlagAttr( nNewFlags ) );
+ else
+ pTmpPattern->GetItemSet().ClearItem( ATTR_MERGE_FLAG );
+
+ if (bSamePool)
+ pNewPattern = (ScPatternAttr*) &pDestDocPool->Put(*pTmpPattern);
+ else
+ pNewPattern = pTmpPattern->PutInPool( rAttrArray.pDocument, pDocument );
+ delete pTmpPattern;
+ }
+ else
+ {
+ if (bSamePool)
+ pNewPattern = (ScPatternAttr*) &pDestDocPool->Put(*pOldPattern);
+ else
+ pNewPattern = pOldPattern->PutInPool( rAttrArray.pDocument, pDocument );
+ }
+
+ rAttrArray.SetPatternArea(nDestStart,
+ Min((SCROW)(pData[i].nRow + nDy), nDestEnd), pNewPattern);
+ }
+
+ // when pasting from clipboard and skipping filtered rows, the adjusted end position
+ // can be negative
+ nDestStart = Max((long)nDestStart, (long)(pData[i].nRow + nDy + 1));
+ }
+}
+
+ // Flags stehenlassen
+ //! mit CopyArea zusammenfassen !!!
+
+void ScAttrArray::CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray )
+{
+ nStartRow -= nDy; // Source
+ nEndRow -= nDy;
+
+ SCROW nDestStart = Max((long)((long)nStartRow + nDy), (long) 0);
+ SCROW nDestEnd = Min((long)((long)nEndRow + nDy), (long) MAXROW);
+
+ if ( !rAttrArray.HasAttrib( nDestStart, nDestEnd, HASATTR_OVERLAPPED ) )
+ {
+ CopyArea( nStartRow+nDy, nEndRow+nDy, nDy, rAttrArray );
+ return;
+ }
+
+ ScDocumentPool* pSourceDocPool = pDocument->GetPool();
+ ScDocumentPool* pDestDocPool = rAttrArray.pDocument->GetPool();
+ BOOL bSamePool = (pSourceDocPool==pDestDocPool);
+
+ for (SCSIZE i = 0; (i < nCount) && (nDestStart <= nDestEnd); i++)
+ {
+ if (pData[i].nRow >= nStartRow)
+ {
+ const ScPatternAttr* pOldPattern = pData[i].pPattern;
+ const ScPatternAttr* pNewPattern;
+
+ if (bSamePool)
+ pNewPattern = (ScPatternAttr*) &pDestDocPool->Put(*pOldPattern);
+ else
+ pNewPattern = pOldPattern->PutInPool( rAttrArray.pDocument, pDocument );
+
+ rAttrArray.SetPatternAreaSafe(nDestStart,
+ Min((SCROW)(pData[i].nRow + nDy), nDestEnd), pNewPattern, FALSE);
+ }
+
+ // when pasting from clipboard and skipping filtered rows, the adjusted end position
+ // can be negative
+ nDestStart = Max((long)nDestStart, (long)(pData[i].nRow + nDy + 1));
+ }
+}
+
+
+SCsROW ScAttrArray::SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
+ BOOL bUp, ScMarkArray* pMarkArray )
+{
+ BOOL bFound = FALSE;
+
+ if (pMarkArray)
+ {
+ nRow = pMarkArray->GetNextMarked( nRow, bUp );
+ if (!VALIDROW(nRow))
+ return nRow;
+ }
+
+ SCSIZE nIndex;
+ Search(nRow, nIndex);
+ const ScPatternAttr* pPattern = pData[nIndex].pPattern;
+
+ while (nIndex < nCount && !bFound)
+ {
+ if (pPattern->GetStyleSheet() == pSearchStyle)
+ {
+ if (pMarkArray)
+ {
+ nRow = pMarkArray->GetNextMarked( nRow, bUp );
+ SCROW nStart = nIndex ? pData[nIndex-1].nRow+1 : 0;
+ if (nRow >= nStart && nRow <= pData[nIndex].nRow)
+ bFound = TRUE;
+ }
+ else
+ bFound = TRUE;
+ }
+
+ if (!bFound)
+ {
+ if (bUp)
+ {
+ if (nIndex==0)
+ {
+ nIndex = nCount;
+ nRow = -1;
+ }
+ else
+ {
+ --nIndex;
+ nRow = pData[nIndex].nRow;
+ pPattern = pData[nIndex].pPattern;
+ }
+ }
+ else
+ {
+ nRow = pData[nIndex].nRow+1;
+ ++nIndex;
+ if (nIndex<nCount)
+ pPattern = pData[nIndex].pPattern;
+ }
+ }
+ }
+
+ DBG_ASSERT( bFound || !ValidRow(nRow), "interner Fehler in ScAttrArray::SearchStyle" );
+
+ return nRow;
+}
+
+
+BOOL ScAttrArray::SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow,
+ const ScStyleSheet* pSearchStyle, BOOL bUp, ScMarkArray* pMarkArray )
+{
+ SCsROW nStartRow = SearchStyle( rRow, pSearchStyle, bUp, pMarkArray );
+ if (VALIDROW(nStartRow))
+ {
+ SCSIZE nIndex;
+ Search(nStartRow,nIndex);
+
+ rRow = nStartRow;
+ if (bUp)
+ {
+ if (nIndex>0)
+ rEndRow = pData[nIndex-1].nRow + 1;
+ else
+ rEndRow = 0;
+ if (pMarkArray)
+ {
+ SCROW nMarkEnd = pMarkArray->GetMarkEnd( nStartRow, TRUE );
+ if (nMarkEnd>rEndRow)
+ rEndRow = nMarkEnd;
+ }
+ }
+ else
+ {
+ rEndRow = pData[nIndex].nRow;
+ if (pMarkArray)
+ {
+ SCROW nMarkEnd = pMarkArray->GetMarkEnd( nStartRow, FALSE );
+ if (nMarkEnd<rEndRow)
+ rEndRow = nMarkEnd;
+ }
+ }
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+//
+// Laden / Speichern
+//
+
+
+#if 0
+void ScAttrArray::Save( SvStream& /* rStream */ ) const
+{
+#if SC_ROWLIMIT_STREAM_ACCESS
+#error address types changed!
+ ScWriteHeader aHdr( rStream, 8 );
+
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+
+ USHORT nSaveCount = nCount;
+ SCROW nSaveMaxRow = pDocument->GetSrcMaxRow();
+ if ( nSaveMaxRow != MAXROW )
+ {
+ if ( nSaveCount > 1 && pData[nSaveCount-2].nRow >= nSaveMaxRow )
+ {
+ pDocument->SetLostData(); // Warnung ausgeben
+ do
+ --nSaveCount;
+ while ( nSaveCount > 1 && pData[nSaveCount-2].nRow >= nSaveMaxRow );
+ }
+ }
+
+ rStream << nSaveCount;
+
+ const SfxPoolItem* pItem;
+ for (SCSIZE i=0; i<nSaveCount; i++)
+ {
+ rStream << Min( pData[i].nRow, nSaveMaxRow );
+
+ const ScPatternAttr* pPattern = pData[i].pPattern;
+ pDocPool->StoreSurrogate( rStream, pPattern );
+
+ // FALSE, weil ATTR_CONDITIONAL (noch) nicht in Vorlagen:
+ if (pPattern->GetItemSet().GetItemState(ATTR_CONDITIONAL,FALSE,&pItem) == SFX_ITEM_SET)
+ pDocument->SetConditionalUsed( ((const SfxUInt32Item*)pItem)->GetValue() );
+
+ if (pPattern->GetItemSet().GetItemState(ATTR_VALIDDATA,FALSE,&pItem) == SFX_ITEM_SET)
+ pDocument->SetValidationUsed( ((const SfxUInt32Item*)pItem)->GetValue() );
+ }
+#endif // SC_ROWLIMIT_STREAM_ACCESS
+}
+
+
+void ScAttrArray::Load( SvStream& /* rStream */ )
+{
+#if SC_ROWLIMIT_STREAM_ACCESS
+#error address types changed!
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+
+ ScReadHeader aHdr( rStream );
+
+ USHORT nNewCount;
+ rStream >> nNewCount;
+ if ( nNewCount > MAXROW+1 ) // wuerde das Array zu gross?
+ {
+ pDocument->SetLostData();
+ rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return;
+ }
+
+ Reset( pDocument->GetDefPattern(), FALSE ); // loeschen
+ pData = new ScAttrEntry[nNewCount]; // neu anlegen
+ for (SCSIZE i=0; i<nNewCount; i++)
+ {
+ rStream >> pData[i].nRow;
+
+ USHORT nWhich = ATTR_PATTERN;
+ const ScPatternAttr* pNewPattern = (const ScPatternAttr*)
+ pDocPool->LoadSurrogate( rStream, nWhich, ATTR_PATTERN );
+ if (!pNewPattern)
+ {
+ // da is was schiefgelaufen
+ DBG_ERROR("ScAttrArray::Load: Surrogat nicht im Pool");
+ pNewPattern = pDocument->GetDefPattern();
+ }
+ ScDocumentPool::CheckRef( *pNewPattern );
+ pData[i].pPattern = pNewPattern;
+
+ // LoadSurrogate erhoeht auch die Ref
+ }
+ nCount = nLimit = nNewCount;
+
+ if ( nCount > 1 && pData[nCount-2].nRow >= MAXROW ) // faengt ein Attribut hinter MAXROW an?
+ {
+ pDocument->SetLostData();
+ rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return;
+ }
+
+ if ( pDocument->GetSrcMaxRow() != MAXROW ) // Ende anpassen?
+ {
+ // Ende immer auf MAXROW umsetzen (nur auf 32 Bit)
+
+ DBG_ASSERT( pData[nCount-1].nRow == pDocument->GetSrcMaxRow(), "Attribut-Ende ?!?" );
+ pData[nCount-1].nRow = MAXROW;
+ }
+#endif // SC_ROWLIMIT_STREAM_ACCESS
+}
+#endif
+
+
+//UNUSED2008-05 void ScAttrArray::ConvertFontsAfterLoad()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScFontToSubsFontConverter_AutoPtr xFontConverter;
+//UNUSED2008-05 const ULONG nFlags = FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS;
+//UNUSED2008-05 SCSIZE nIndex = 0;
+//UNUSED2008-05 SCROW nThisRow = 0;
+//UNUSED2008-05
+//UNUSED2008-05 while ( nThisRow <= MAXROW )
+//UNUSED2008-05 {
+//UNUSED2008-05 const ScPatternAttr* pOldPattern = pData[nIndex].pPattern;
+//UNUSED2008-05 const SfxPoolItem* pItem;
+//UNUSED2008-05 if( pOldPattern->GetItemSet().GetItemState( ATTR_FONT, FALSE, &pItem ) == SFX_ITEM_SET )
+//UNUSED2008-05 {
+//UNUSED2008-05 const SvxFontItem* pFontItem = (const SvxFontItem*) pItem;
+//UNUSED2008-05 const String& rOldName = pFontItem->GetFamilyName();
+//UNUSED2008-05 xFontConverter = CreateFontToSubsFontConverter( rOldName, nFlags );
+//UNUSED2008-05 if ( xFontConverter )
+//UNUSED2008-05 {
+//UNUSED2008-05 String aNewName( GetFontToSubsFontName( xFontConverter ) );
+//UNUSED2008-05 if ( aNewName != rOldName )
+//UNUSED2008-05 {
+//UNUSED2008-05 SCROW nAttrRow = pData[nIndex].nRow;
+//UNUSED2008-05 SvxFontItem aNewItem( pFontItem->GetFamily(), aNewName,
+//UNUSED2008-05 pFontItem->GetStyleName(), pFontItem->GetPitch(),
+//UNUSED2008-05 RTL_TEXTENCODING_DONTKNOW, ATTR_FONT );
+//UNUSED2008-05 ScPatternAttr aNewPattern( *pOldPattern );
+//UNUSED2008-05 aNewPattern.GetItemSet().Put( aNewItem );
+//UNUSED2008-05 SetPatternArea( nThisRow, nAttrRow, &aNewPattern, TRUE );
+//UNUSED2008-05 Search( nThisRow, nIndex ); //! data changed
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 ++nIndex;
+//UNUSED2008-05 nThisRow = pData[nIndex-1].nRow+1;
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
diff --git a/sc/source/core/data/attrib.cxx b/sc/source/core/data/attrib.cxx
new file mode 100644
index 000000000000..301883197fb8
--- /dev/null
+++ b/sc/source/core/data/attrib.cxx
@@ -0,0 +1,1328 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/util/CellProtection.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/boxitem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/flditem.hxx>
+
+#include "attrib.hxx"
+#include "global.hxx"
+#include "editutil.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include "textuno.hxx" // ScHeaderFooterContentObj
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+TYPEINIT1(ScMergeAttr, SfxPoolItem);
+TYPEINIT1_AUTOFACTORY(ScProtectionAttr, SfxPoolItem);
+TYPEINIT1(ScRangeItem, SfxPoolItem);
+TYPEINIT1(ScTableListItem, SfxPoolItem);
+TYPEINIT1(ScPageHFItem, SfxPoolItem);
+TYPEINIT1(ScViewObjectModeItem, SfxEnumItem);
+TYPEINIT1(ScDoubleItem, SfxPoolItem);
+TYPEINIT1(ScPageScaleToItem, SfxPoolItem);
+
+//------------------------------------------------------------------------
+
+//
+// allgemeine Hilfsfunktionen
+//
+
+BOOL ScHasPriority( const SvxBorderLine* pThis, const SvxBorderLine* pOther )
+{
+// DBG_ASSERT( pThis || pOther, "LineAttr == 0" );
+
+ if (!pThis)
+ return FALSE;
+ if (!pOther)
+ return TRUE;
+
+ USHORT nThisSize = pThis->GetOutWidth() + pThis->GetDistance() + pThis->GetInWidth();
+ USHORT nOtherSize = pOther->GetOutWidth() + pOther->GetDistance() + pOther->GetInWidth();
+
+ if (nThisSize > nOtherSize)
+ return TRUE;
+ else if (nThisSize < nOtherSize)
+ return FALSE;
+ else
+ {
+ if ( pOther->GetInWidth() && !pThis->GetInWidth() )
+ return TRUE;
+ else if ( pThis->GetInWidth() && !pOther->GetInWidth() )
+ return FALSE;
+ else
+ {
+ return TRUE; //! ???
+ }
+ }
+}
+
+
+//
+// Item - Implementierungen
+//
+
+//------------------------------------------------------------------------
+// Merge
+//------------------------------------------------------------------------
+
+ScMergeAttr::ScMergeAttr():
+ SfxPoolItem(ATTR_MERGE),
+ nColMerge(0),
+ nRowMerge(0)
+{}
+
+//------------------------------------------------------------------------
+
+ScMergeAttr::ScMergeAttr( SCsCOL nCol, SCsROW nRow):
+ SfxPoolItem(ATTR_MERGE),
+ nColMerge(nCol),
+ nRowMerge(nRow)
+{}
+
+//------------------------------------------------------------------------
+
+ScMergeAttr::ScMergeAttr(const ScMergeAttr& rItem):
+ SfxPoolItem(ATTR_MERGE)
+{
+ nColMerge = rItem.nColMerge;
+ nRowMerge = rItem.nRowMerge;
+}
+
+ScMergeAttr::~ScMergeAttr()
+{
+}
+
+//------------------------------------------------------------------------
+
+String ScMergeAttr::GetValueText() const
+{
+ String aString( '(' );
+ aString += String::CreateFromInt32( nColMerge );
+ aString += ',';
+ aString += String::CreateFromInt32( nRowMerge );
+ aString += ')';
+ return aString;
+}
+
+//------------------------------------------------------------------------
+
+int ScMergeAttr::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( Which() != rItem.Which() || Type() == rItem.Type(), "which ==, type !=" );
+ return (Which() == rItem.Which())
+ && (nColMerge == ((ScMergeAttr&)rItem).nColMerge)
+ && (nRowMerge == ((ScMergeAttr&)rItem).nRowMerge);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScMergeAttr::Clone( SfxItemPool * ) const
+{
+ return new ScMergeAttr(*this);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScMergeAttr::Create( SvStream& rStream, USHORT /* nVer */ ) const
+{
+ INT16 nCol;
+ INT16 nRow;
+ rStream >> nCol;
+ rStream >> nRow;
+ return new ScMergeAttr(static_cast<SCCOL>(nCol),static_cast<SCROW>(nRow));
+}
+
+//------------------------------------------------------------------------
+// MergeFlag
+//------------------------------------------------------------------------
+
+ScMergeFlagAttr::ScMergeFlagAttr():
+ SfxInt16Item(ATTR_MERGE_FLAG, 0)
+{
+}
+
+//------------------------------------------------------------------------
+
+ScMergeFlagAttr::ScMergeFlagAttr(INT16 nFlags):
+ SfxInt16Item(ATTR_MERGE_FLAG, nFlags)
+{
+}
+
+ScMergeFlagAttr::~ScMergeFlagAttr()
+{
+}
+
+//------------------------------------------------------------------------
+// Protection
+//------------------------------------------------------------------------
+
+ScProtectionAttr::ScProtectionAttr():
+ SfxPoolItem(ATTR_PROTECTION),
+ bProtection(TRUE),
+ bHideFormula(FALSE),
+ bHideCell(FALSE),
+ bHidePrint(FALSE)
+{
+}
+
+//------------------------------------------------------------------------
+
+ScProtectionAttr::ScProtectionAttr( BOOL bProtect, BOOL bHFormula,
+ BOOL bHCell, BOOL bHPrint):
+ SfxPoolItem(ATTR_PROTECTION),
+ bProtection(bProtect),
+ bHideFormula(bHFormula),
+ bHideCell(bHCell),
+ bHidePrint(bHPrint)
+{
+}
+
+//------------------------------------------------------------------------
+
+ScProtectionAttr::ScProtectionAttr(const ScProtectionAttr& rItem):
+ SfxPoolItem(ATTR_PROTECTION)
+{
+ bProtection = rItem.bProtection;
+ bHideFormula = rItem.bHideFormula;
+ bHideCell = rItem.bHideCell;
+ bHidePrint = rItem.bHidePrint;
+}
+
+ScProtectionAttr::~ScProtectionAttr()
+{
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScProtectionAttr::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case 0 :
+ {
+ util::CellProtection aProtection;
+ aProtection.IsLocked = bProtection;
+ aProtection.IsFormulaHidden = bHideFormula;
+ aProtection.IsHidden = bHideCell;
+ aProtection.IsPrintHidden = bHidePrint;
+ rVal <<= aProtection;
+ break;
+ }
+ case MID_1 :
+ rVal <<= (sal_Bool ) bProtection; break;
+ case MID_2 :
+ rVal <<= (sal_Bool ) bHideFormula; break;
+ case MID_3 :
+ rVal <<= (sal_Bool ) bHideCell; break;
+ case MID_4 :
+ rVal <<= (sal_Bool ) bHidePrint; break;
+ default:
+ DBG_ERROR("Wrong MemberID!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL ScProtectionAttr::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ BOOL bRet = FALSE;
+ sal_Bool bVal = sal_Bool();
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case 0 :
+ {
+ util::CellProtection aProtection;
+ if ( rVal >>= aProtection )
+ {
+ bProtection = aProtection.IsLocked;
+ bHideFormula = aProtection.IsFormulaHidden;
+ bHideCell = aProtection.IsHidden;
+ bHidePrint = aProtection.IsPrintHidden;
+ bRet = TRUE;
+ }
+ else
+ {
+ DBG_ERROR("exception - wrong argument");
+ }
+ break;
+ }
+ case MID_1 :
+ bRet = (rVal >>= bVal); if (bRet) bProtection=bVal; break;
+ case MID_2 :
+ bRet = (rVal >>= bVal); if (bRet) bHideFormula=bVal; break;
+ case MID_3 :
+ bRet = (rVal >>= bVal); if (bRet) bHideCell=bVal; break;
+ case MID_4 :
+ bRet = (rVal >>= bVal); if (bRet) bHidePrint=bVal; break;
+ default:
+ DBG_ERROR("Wrong MemberID!");
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+String ScProtectionAttr::GetValueText() const
+{
+ String aValue;
+ String aStrYes ( ScGlobal::GetRscString(STR_YES) );
+ String aStrNo ( ScGlobal::GetRscString(STR_NO) );
+ sal_Unicode cDelim = ',';
+
+ aValue = '(';
+ aValue += (bProtection ? aStrYes : aStrNo); aValue += cDelim;
+ aValue += (bHideFormula ? aStrYes : aStrNo); aValue += cDelim;
+ aValue += (bHideCell ? aStrYes : aStrNo); aValue += cDelim;
+ aValue += (bHidePrint ? aStrYes : aStrNo);
+ aValue += ')';
+
+ return aValue;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation ScProtectionAttr::GetPresentation
+ (
+ SfxItemPresentation ePres,
+ SfxMapUnit /* eCoreMetric */,
+ SfxMapUnit /* ePresMetric */,
+ String& rText,
+ const IntlWrapper* /* pIntl */
+ ) const
+{
+ String aStrYes ( ScGlobal::GetRscString(STR_YES) );
+ String aStrNo ( ScGlobal::GetRscString(STR_NO) );
+ String aStrSep = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+ String aStrDelim = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
+
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText = GetValueText();
+ break;
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_PROTECTION); rText += aStrSep;
+ rText += (bProtection ? aStrYes : aStrNo); rText += aStrDelim;
+ rText += ScGlobal::GetRscString(STR_FORMULAS); rText += aStrSep;
+ rText += (!bHideFormula ? aStrYes : aStrNo); rText += aStrDelim;
+ rText += ScGlobal::GetRscString(STR_HIDE); rText += aStrSep;
+ rText += (bHideCell ? aStrYes : aStrNo); rText += aStrDelim;
+ rText += ScGlobal::GetRscString(STR_PRINT); rText += aStrSep;
+ rText += (!bHidePrint ? aStrYes : aStrNo);
+ break;
+
+ default:
+ ePres = SFX_ITEM_PRESENTATION_NONE;
+ }
+
+ return ePres;
+}
+
+//------------------------------------------------------------------------
+
+int ScProtectionAttr::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( Which() != rItem.Which() || Type() == rItem.Type(), "which ==, type !=" );
+ return (Which() == rItem.Which())
+ && (bProtection == ((ScProtectionAttr&)rItem).bProtection)
+ && (bHideFormula == ((ScProtectionAttr&)rItem).bHideFormula)
+ && (bHideCell == ((ScProtectionAttr&)rItem).bHideCell)
+ && (bHidePrint == ((ScProtectionAttr&)rItem).bHidePrint);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScProtectionAttr::Clone( SfxItemPool * ) const
+{
+ return new ScProtectionAttr(*this);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScProtectionAttr::Create( SvStream& rStream, USHORT /* n */ ) const
+{
+ BOOL bProtect;
+ BOOL bHFormula;
+ BOOL bHCell;
+ BOOL bHPrint;
+
+ rStream >> bProtect;
+ rStream >> bHFormula;
+ rStream >> bHCell;
+ rStream >> bHPrint;
+
+ return new ScProtectionAttr(bProtect,bHFormula,bHCell,bHPrint);
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScProtectionAttr::SetProtection( BOOL bProtect)
+{
+ bProtection = bProtect;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScProtectionAttr::SetHideFormula( BOOL bHFormula)
+{
+ bHideFormula = bHFormula;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScProtectionAttr::SetHideCell( BOOL bHCell)
+{
+ bHideCell = bHCell;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScProtectionAttr::SetHidePrint( BOOL bHPrint)
+{
+ bHidePrint = bHPrint;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+// ScRangeItem - Tabellenbereich
+// -----------------------------------------------------------------------
+
+int ScRangeItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( aRange == ( (ScRangeItem&)rAttr ).aRange );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* ScRangeItem::Clone( SfxItemPool* ) const
+{
+ return new ScRangeItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation ScRangeItem::GetPresentation
+ (
+ SfxItemPresentation ePres,
+ SfxMapUnit /* eCoreUnit */,
+ SfxMapUnit /* ePresUnit */,
+ String& rText,
+ const IntlWrapper* /* pIntl */
+ ) const
+{
+ rText.Erase();
+
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_AREA);
+ rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+// break;// Durchfallen !!!
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ String aText;
+ /* Always use OOo:A1 format */
+ aRange.Format( aText );
+ rText += aText;
+ }
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ return ePres;
+}
+
+// -----------------------------------------------------------------------
+// ScTableListItem - Liste von Tabellen(-nummern)
+// -----------------------------------------------------------------------
+
+ScTableListItem::ScTableListItem( const ScTableListItem& rCpy )
+ : SfxPoolItem ( rCpy.Which() ),
+ nCount ( rCpy.nCount )
+{
+ if ( nCount > 0 )
+ {
+ pTabArr = new SCTAB [nCount];
+
+ for ( USHORT i=0; i<nCount; i++ )
+ pTabArr[i] = rCpy.pTabArr[i];
+ }
+ else
+ pTabArr = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+//UNUSED2008-05 ScTableListItem::ScTableListItem( const USHORT nWhichP, const List& rList )
+//UNUSED2008-05 : SfxPoolItem ( nWhichP ),
+//UNUSED2008-05 nCount ( 0 ),
+//UNUSED2008-05 pTabArr ( NULL )
+//UNUSED2008-05 {
+//UNUSED2008-05 SetTableList( rList );
+//UNUSED2008-05 }
+
+// -----------------------------------------------------------------------
+
+ScTableListItem::~ScTableListItem()
+{
+ delete [] pTabArr;
+}
+
+// -----------------------------------------------------------------------
+
+ScTableListItem& ScTableListItem::operator=( const ScTableListItem& rCpy )
+{
+ delete [] pTabArr;
+
+ if ( rCpy.nCount > 0 )
+ {
+ pTabArr = new SCTAB [rCpy.nCount];
+ for ( USHORT i=0; i<rCpy.nCount; i++ )
+ pTabArr[i] = rCpy.pTabArr[i];
+ }
+ else
+ pTabArr = NULL;
+
+ nCount = rCpy.nCount;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+int ScTableListItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ ScTableListItem& rCmp = (ScTableListItem&)rAttr;
+ BOOL bEqual = (nCount == rCmp.nCount);
+
+ if ( nCount > 0 )
+ {
+ USHORT i=0;
+
+ bEqual = ( pTabArr && rCmp.pTabArr );
+
+ while ( bEqual && i<nCount )
+ {
+ bEqual = ( pTabArr[i] == rCmp.pTabArr[i] );
+ i++;
+ }
+ }
+ return bEqual;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* ScTableListItem::Clone( SfxItemPool* ) const
+{
+ return new ScTableListItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation ScTableListItem::GetPresentation
+ (
+ SfxItemPresentation ePres,
+ SfxMapUnit /* eCoreUnit */,
+ SfxMapUnit /* ePresUnit */,
+ String& rText,
+ const IntlWrapper* /* pIntl */
+ ) const
+{
+ const sal_Unicode cDelim = ',';
+
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ rText = '(';
+ if ( nCount>0 && pTabArr )
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ rText += String::CreateFromInt32( pTabArr[i] );
+ if ( i<(nCount-1) )
+ rText += cDelim;
+ }
+ rText += ')';
+ }
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+//UNUSED2009-05 BOOL ScTableListItem::GetTableList( List& aList ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 for ( USHORT i=0; i<nCount; i++ )
+//UNUSED2009-05 aList.Insert( new SCTAB( pTabArr[i] ) );
+//UNUSED2009-05
+//UNUSED2009-05 return ( nCount > 0 );
+//UNUSED2009-05 }
+
+// -----------------------------------------------------------------------
+
+//UNUSED2009-05 void ScTableListItem::SetTableList( const List& rList )
+//UNUSED2009-05 {
+//UNUSED2009-05 nCount = (USHORT)rList.Count();
+//UNUSED2009-05
+//UNUSED2009-05 delete [] pTabArr;
+//UNUSED2009-05
+//UNUSED2009-05 if ( nCount > 0 )
+//UNUSED2009-05 {
+//UNUSED2009-05 pTabArr = new SCTAB [nCount];
+//UNUSED2009-05
+//UNUSED2009-05 for ( USHORT i=0; i<nCount; i++ )
+//UNUSED2009-05 pTabArr[i] = *( (SCTAB*)rList.GetObject( i ) );
+//UNUSED2009-05 }
+//UNUSED2009-05 else
+//UNUSED2009-05 pTabArr = NULL;
+//UNUSED2009-05 }
+
+
+// -----------------------------------------------------------------------
+// ScPageHFItem - Daten der Kopf-/Fusszeilen
+// -----------------------------------------------------------------------
+
+ScPageHFItem::ScPageHFItem( USHORT nWhichP )
+ : SfxPoolItem ( nWhichP ),
+ pLeftArea ( NULL ),
+ pCenterArea ( NULL ),
+ pRightArea ( NULL )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScPageHFItem::ScPageHFItem( const ScPageHFItem& rItem )
+ : SfxPoolItem ( rItem ),
+ pLeftArea ( NULL ),
+ pCenterArea ( NULL ),
+ pRightArea ( NULL )
+{
+ if ( rItem.pLeftArea )
+ pLeftArea = rItem.pLeftArea->Clone();
+ if ( rItem.pCenterArea )
+ pCenterArea = rItem.pCenterArea->Clone();
+ if ( rItem.pRightArea )
+ pRightArea = rItem.pRightArea->Clone();
+}
+
+//------------------------------------------------------------------------
+
+ScPageHFItem::~ScPageHFItem()
+{
+ delete pLeftArea;
+ delete pCenterArea;
+ delete pRightArea;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScPageHFItem::QueryValue( uno::Any& rVal, BYTE /* nMemberId */ ) const
+{
+ uno::Reference<sheet::XHeaderFooterContent> xContent =
+ new ScHeaderFooterContentObj( pLeftArea, pCenterArea, pRightArea );
+
+ rVal <<= xContent;
+ return TRUE;
+}
+
+BOOL ScPageHFItem::PutValue( const uno::Any& rVal, BYTE /* nMemberId */ )
+{
+ BOOL bRet = FALSE;
+ uno::Reference<sheet::XHeaderFooterContent> xContent;
+ if ( rVal >>= xContent )
+ {
+ if ( xContent.is() )
+ {
+ ScHeaderFooterContentObj* pImp =
+ ScHeaderFooterContentObj::getImplementation( xContent );
+ if (pImp)
+ {
+ const EditTextObject* pImpLeft = pImp->GetLeftEditObject();
+ delete pLeftArea;
+ pLeftArea = pImpLeft ? pImpLeft->Clone() : NULL;
+
+ const EditTextObject* pImpCenter = pImp->GetCenterEditObject();
+ delete pCenterArea;
+ pCenterArea = pImpCenter ? pImpCenter->Clone() : NULL;
+
+ const EditTextObject* pImpRight = pImp->GetRightEditObject();
+ delete pRightArea;
+ pRightArea = pImpRight ? pImpRight->Clone() : NULL;
+
+ if ( !pLeftArea || !pCenterArea || !pRightArea )
+ {
+ // keine Texte auf NULL stehen lassen
+ ScEditEngineDefaulter aEngine( EditEngine::CreatePool(), TRUE );
+ if (!pLeftArea)
+ pLeftArea = aEngine.CreateTextObject();
+ if (!pCenterArea)
+ pCenterArea = aEngine.CreateTextObject();
+ if (!pRightArea)
+ pRightArea = aEngine.CreateTextObject();
+ }
+
+ bRet = TRUE;
+ }
+ }
+ }
+
+ if (!bRet)
+ {
+ DBG_ERROR("exception - wrong argument");
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+String ScPageHFItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScPageHFItem"));
+}
+
+//------------------------------------------------------------------------
+
+int ScPageHFItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScPageHFItem& r = (const ScPageHFItem&)rItem;
+
+ return ScGlobal::EETextObjEqual(pLeftArea, r.pLeftArea)
+ && ScGlobal::EETextObjEqual(pCenterArea, r.pCenterArea)
+ && ScGlobal::EETextObjEqual(pRightArea, r.pRightArea);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScPageHFItem::Clone( SfxItemPool* ) const
+{
+ return new ScPageHFItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+void lcl_SetSpace( String& rStr, const ESelection& rSel )
+{
+ // Text durch ein Leerzeichen ersetzen, damit Positionen stimmen:
+
+ xub_StrLen nLen = rSel.nEndPos-rSel.nStartPos;
+ rStr.Erase( rSel.nStartPos, nLen-1 );
+ rStr.SetChar( rSel.nStartPos, ' ' );
+}
+
+BOOL lcl_ConvertFields(EditEngine& rEng, const String* pCommands)
+{
+ BOOL bChange = FALSE;
+ USHORT nParCnt = rEng.GetParagraphCount();
+ for (USHORT nPar = 0; nPar<nParCnt; nPar++)
+ {
+ String aStr = rEng.GetText( nPar );
+ xub_StrLen nPos;
+
+ while ((nPos = aStr.Search(pCommands[0])) != STRING_NOTFOUND)
+ {
+ ESelection aSel( nPar,nPos, nPar,nPos+pCommands[0].Len() );
+ rEng.QuickInsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), aSel );
+ lcl_SetSpace(aStr, aSel ); bChange = TRUE;
+ }
+ while ((nPos = aStr.Search(pCommands[1])) != STRING_NOTFOUND)
+ {
+ ESelection aSel( nPar,nPos, nPar,nPos+pCommands[1].Len() );
+ rEng.QuickInsertField( SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD), aSel );
+ lcl_SetSpace(aStr, aSel ); bChange = TRUE;
+ }
+ while ((nPos = aStr.Search(pCommands[2])) != STRING_NOTFOUND)
+ {
+ ESelection aSel( nPar,nPos, nPar,nPos+pCommands[2].Len() );
+ rEng.QuickInsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR), EE_FEATURE_FIELD), aSel );
+ lcl_SetSpace(aStr, aSel ); bChange = TRUE;
+ }
+ while ((nPos = aStr.Search(pCommands[3])) != STRING_NOTFOUND)
+ {
+ ESelection aSel( nPar,nPos, nPar,nPos+pCommands[3].Len() );
+ rEng.QuickInsertField( SvxFieldItem(SvxTimeField(), EE_FEATURE_FIELD ), aSel );
+ lcl_SetSpace(aStr, aSel ); bChange = TRUE;
+ }
+ while ((nPos = aStr.Search(pCommands[4])) != STRING_NOTFOUND)
+ {
+ ESelection aSel( nPar,nPos, nPar,nPos+pCommands[4].Len() );
+ rEng.QuickInsertField( SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD), aSel );
+ lcl_SetSpace(aStr, aSel ); bChange = TRUE;
+ }
+ while ((nPos = aStr.Search(pCommands[5])) != STRING_NOTFOUND)
+ {
+ ESelection aSel( nPar,nPos, nPar,nPos+pCommands[5].Len() );
+ rEng.QuickInsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), aSel );
+ lcl_SetSpace(aStr, aSel ); bChange = TRUE;
+ }
+ }
+ return bChange;
+}
+
+#define SC_FIELD_COUNT 6
+
+SfxPoolItem* ScPageHFItem::Create( SvStream& rStream, USHORT nVer ) const
+{
+ EditTextObject* pLeft = EditTextObject::Create(rStream);
+ EditTextObject* pCenter = EditTextObject::Create(rStream);
+ EditTextObject* pRight = EditTextObject::Create(rStream);
+
+ DBG_ASSERT( pLeft && pCenter && pRight, "Error reading ScPageHFItem" );
+
+ if ( pLeft == NULL || pLeft->GetParagraphCount() == 0 ||
+ pCenter == NULL || pCenter->GetParagraphCount() == 0 ||
+ pRight == NULL || pRight->GetParagraphCount() == 0 )
+ {
+ // If successfully loaded, each object contains at least one paragraph.
+ // Excel import in 5.1 created broken TextObjects (#67442#) that are
+ // corrected here to avoid saving wrong files again (#90487#).
+
+ ScEditEngineDefaulter aEngine( EditEngine::CreatePool(), TRUE );
+ if ( pLeft == NULL || pLeft->GetParagraphCount() == 0 )
+ {
+ delete pLeft;
+ pLeft = aEngine.CreateTextObject();
+ }
+ if ( pCenter == NULL || pCenter->GetParagraphCount() == 0 )
+ {
+ delete pCenter;
+ pCenter = aEngine.CreateTextObject();
+ }
+ if ( pRight == NULL || pRight->GetParagraphCount() == 0 )
+ {
+ delete pRight;
+ pRight = aEngine.CreateTextObject();
+ }
+ }
+
+ if ( nVer < 1 ) // alte Feldbefehle umsetzen
+ {
+ USHORT i;
+ const String& rDel = ScGlobal::GetRscString( STR_HFCMD_DELIMITER );
+ String aCommands[SC_FIELD_COUNT];
+ for (i=0; i<SC_FIELD_COUNT; i++)
+ aCommands[i] = rDel;
+ aCommands[0] += ScGlobal::GetRscString(STR_HFCMD_PAGE);
+ aCommands[1] += ScGlobal::GetRscString(STR_HFCMD_PAGES);
+ aCommands[2] += ScGlobal::GetRscString(STR_HFCMD_DATE);
+ aCommands[3] += ScGlobal::GetRscString(STR_HFCMD_TIME);
+ aCommands[4] += ScGlobal::GetRscString(STR_HFCMD_FILE);
+ aCommands[5] += ScGlobal::GetRscString(STR_HFCMD_TABLE);
+ for (i=0; i<SC_FIELD_COUNT; i++)
+ aCommands[i] += rDel;
+
+ ScEditEngineDefaulter aEngine( EditEngine::CreatePool(), TRUE );
+ aEngine.SetText(*pLeft);
+ if (lcl_ConvertFields(aEngine,aCommands))
+ {
+ delete pLeft;
+ pLeft = aEngine.CreateTextObject();
+ }
+ aEngine.SetText(*pCenter);
+ if (lcl_ConvertFields(aEngine,aCommands))
+ {
+ delete pCenter;
+ pCenter = aEngine.CreateTextObject();
+ }
+ aEngine.SetText(*pRight);
+ if (lcl_ConvertFields(aEngine,aCommands))
+ {
+ delete pRight;
+ pRight = aEngine.CreateTextObject();
+ }
+ }
+ else if ( nVer < 2 )
+ { // nichts tun, SvxFileField nicht gegen SvxExtFileField austauschen
+ }
+
+ ScPageHFItem* pItem = new ScPageHFItem( Which() );
+ pItem->SetArea( pLeft, SC_HF_LEFTAREA );
+ pItem->SetArea( pCenter, SC_HF_CENTERAREA );
+ pItem->SetArea( pRight, SC_HF_RIGHTAREA );
+
+ return pItem;
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2009-05 class ScFieldChangerEditEngine : public ScEditEngineDefaulter
+//UNUSED2009-05 {
+//UNUSED2009-05 TypeId aExtFileId;
+//UNUSED2009-05 USHORT nConvPara;
+//UNUSED2009-05 xub_StrLen nConvPos;
+//UNUSED2009-05 BOOL bConvert;
+//UNUSED2009-05
+//UNUSED2009-05 public:
+//UNUSED2009-05 ScFieldChangerEditEngine( SfxItemPool* pEnginePool, BOOL bDeleteEnginePool );
+//UNUSED2009-05 virtual ~ScFieldChangerEditEngine() {}
+//UNUSED2009-05
+//UNUSED2009-05 virtual String CalcFieldValue( const SvxFieldItem& rField, USHORT nPara,
+//UNUSED2009-05 USHORT nPos, Color*& rTxtColor,
+//UNUSED2009-05 Color*& rFldColor );
+//UNUSED2009-05
+//UNUSED2009-05 BOOL ConvertFields();
+//UNUSED2009-05 };
+//UNUSED2009-05
+//UNUSED2009-05 ScFieldChangerEditEngine::ScFieldChangerEditEngine( SfxItemPool* pEnginePoolP,
+//UNUSED2009-05 BOOL bDeleteEnginePoolP ) :
+//UNUSED2009-05 ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
+//UNUSED2009-05 aExtFileId( TYPE( SvxExtFileField ) ),
+//UNUSED2009-05 nConvPara( 0 ),
+//UNUSED2009-05 nConvPos( 0 ),
+//UNUSED2009-05 bConvert( FALSE )
+//UNUSED2009-05 {
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 String ScFieldChangerEditEngine::CalcFieldValue( const SvxFieldItem& rField,
+//UNUSED2009-05 USHORT nPara, USHORT nPos, Color*& /* rTxtColor */, Color*& /* rFldColor */ )
+//UNUSED2009-05 {
+//UNUSED2009-05 const SvxFieldData* pFieldData = rField.GetField();
+//UNUSED2009-05 if ( pFieldData && pFieldData->Type() == aExtFileId )
+//UNUSED2009-05 {
+//UNUSED2009-05 bConvert = TRUE;
+//UNUSED2009-05 nConvPara = nPara;
+//UNUSED2009-05 nConvPos = nPos;
+//UNUSED2009-05 }
+//UNUSED2009-05 return EMPTY_STRING;
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 BOOL ScFieldChangerEditEngine::ConvertFields()
+//UNUSED2009-05 {
+//UNUSED2009-05 BOOL bConverted = FALSE;
+//UNUSED2009-05 do
+//UNUSED2009-05 {
+//UNUSED2009-05 bConvert = FALSE;
+//UNUSED2009-05 UpdateFields();
+//UNUSED2009-05 if ( bConvert )
+//UNUSED2009-05 {
+//UNUSED2009-05 ESelection aSel( nConvPara, nConvPos, nConvPara, nConvPos+1 );
+//UNUSED2009-05 QuickInsertField( SvxFieldItem( SvxFileField(), EE_FEATURE_FIELD), aSel );
+//UNUSED2009-05 bConverted = TRUE;
+//UNUSED2009-05 }
+//UNUSED2009-05 } while ( bConvert );
+//UNUSED2009-05 return bConverted;
+//UNUSED2009-05 }
+
+void ScPageHFItem::SetLeftArea( const EditTextObject& rNew )
+{
+ delete pLeftArea;
+ pLeftArea = rNew.Clone();
+}
+
+//------------------------------------------------------------------------
+
+void ScPageHFItem::SetCenterArea( const EditTextObject& rNew )
+{
+ delete pCenterArea;
+ pCenterArea = rNew.Clone();
+}
+
+//------------------------------------------------------------------------
+
+void ScPageHFItem::SetRightArea( const EditTextObject& rNew )
+{
+ delete pRightArea;
+ pRightArea = rNew.Clone();
+}
+
+void ScPageHFItem::SetArea( EditTextObject *pNew, int nArea )
+{
+ switch ( nArea )
+ {
+ case SC_HF_LEFTAREA: delete pLeftArea; pLeftArea = pNew; break;
+ case SC_HF_CENTERAREA: delete pCenterArea; pCenterArea = pNew; break;
+ case SC_HF_RIGHTAREA: delete pRightArea; pRightArea = pNew; break;
+ default:
+ DBG_ERROR( "New Area?" );
+ }
+}
+
+//-----------------------------------------------------------------------
+// ScViewObjectModeItem - Darstellungsmodus von ViewObjekten
+//-----------------------------------------------------------------------
+
+ScViewObjectModeItem::ScViewObjectModeItem( USHORT nWhichP )
+ : SfxEnumItem( nWhichP, VOBJ_MODE_SHOW )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScViewObjectModeItem::ScViewObjectModeItem( USHORT nWhichP, ScVObjMode eMode )
+ : SfxEnumItem( nWhichP, sal::static_int_cast<USHORT>(eMode) )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScViewObjectModeItem::~ScViewObjectModeItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation ScViewObjectModeItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /* eCoreUnit */,
+ SfxMapUnit /* ePresUnit */,
+ String& rText,
+ const IntlWrapper* /* pIntl */
+) const
+{
+ String aDel = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(": "));
+ rText.Erase();
+
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ switch( Which() )
+ {
+ case SID_SCATTR_PAGE_CHARTS:
+ rText = ScGlobal::GetRscString(STR_VOBJ_CHART);
+ rText += aDel;
+ break;
+
+ case SID_SCATTR_PAGE_OBJECTS:
+ rText = ScGlobal::GetRscString(STR_VOBJ_OBJECT);
+ rText += aDel;
+ break;
+
+ case SID_SCATTR_PAGE_DRAWINGS:
+ rText = ScGlobal::GetRscString(STR_VOBJ_DRAWINGS);
+ rText += aDel;
+ break;
+
+ default:
+ ePres = SFX_ITEM_PRESENTATION_NAMELESS;//das geht immer!
+ break;
+ }
+// break; // DURCHFALLEN!!!
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ScGlobal::GetRscString(STR_VOBJ_MODE_SHOW+GetValue());
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ return ePres;
+}
+
+//------------------------------------------------------------------------
+
+String ScViewObjectModeItem::GetValueText( USHORT nVal ) const
+{
+ DBG_ASSERT( nVal <= VOBJ_MODE_HIDE, "enum overflow!" );
+
+ return ScGlobal::GetRscString( STR_VOBJ_MODE_SHOW + (nVal % 2));
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScViewObjectModeItem::GetValueCount() const
+{
+ return 2;
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScViewObjectModeItem::Clone( SfxItemPool* ) const
+{
+ return new ScViewObjectModeItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScViewObjectModeItem::GetVersion( USHORT /* nFileVersion */ ) const
+{
+ return 1;
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScViewObjectModeItem::Create(
+ SvStream& rStream,
+ USHORT nVersion ) const
+{
+ if ( nVersion == 0 )
+ {
+ // alte Version mit AllEnumItem -> mit Mode "Show" erzeugen
+ return new ScViewObjectModeItem( Which() );
+ }
+ else
+ {
+ USHORT nVal;
+ rStream >> nVal;
+
+ //#i80528# adapt to new range eventually
+ if((USHORT)VOBJ_MODE_HIDE < nVal) nVal = (USHORT)VOBJ_MODE_SHOW;
+
+ return new ScViewObjectModeItem( Which(), (ScVObjMode)nVal);
+ }
+}
+
+// -----------------------------------------------------------------------
+// double
+// -----------------------------------------------------------------------
+
+ScDoubleItem::ScDoubleItem( USHORT nWhichP, double nVal )
+ : SfxPoolItem ( nWhichP ),
+ nValue ( nVal )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScDoubleItem::ScDoubleItem( const ScDoubleItem& rItem )
+ : SfxPoolItem ( rItem )
+{
+ nValue = rItem.nValue;
+}
+
+//------------------------------------------------------------------------
+
+String ScDoubleItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScDoubleItem"));
+}
+
+//------------------------------------------------------------------------
+
+int ScDoubleItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+ const ScDoubleItem& _rItem = (const ScDoubleItem&)rItem;
+ return int(nValue == _rItem.nValue);
+ //int(nValue == ((const ScDoubleItem&)rItem).nValue);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScDoubleItem::Clone( SfxItemPool* ) const
+{
+ return new ScDoubleItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* ScDoubleItem::Create( SvStream& rStream, USHORT /* nVer */ ) const
+{
+ double nTmp=0;
+ rStream >> nTmp;
+
+ ScDoubleItem* pItem = new ScDoubleItem( Which(), nTmp );
+
+ return pItem;
+}
+
+//------------------------------------------------------------------------
+
+ScDoubleItem::~ScDoubleItem()
+{
+}
+
+
+// ============================================================================
+
+ScPageScaleToItem::ScPageScaleToItem() :
+ SfxPoolItem( ATTR_PAGE_SCALETO ),
+ mnWidth( 0 ),
+ mnHeight( 0 )
+{
+}
+
+ScPageScaleToItem::ScPageScaleToItem( sal_uInt16 nWidth, sal_uInt16 nHeight ) :
+ SfxPoolItem( ATTR_PAGE_SCALETO ),
+ mnWidth( nWidth ),
+ mnHeight( nHeight )
+{
+}
+
+ScPageScaleToItem::~ScPageScaleToItem()
+{
+}
+
+ScPageScaleToItem* ScPageScaleToItem::Clone( SfxItemPool* ) const
+{
+ return new ScPageScaleToItem( *this );
+}
+
+int ScPageScaleToItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rCmp ), "ScPageScaleToItem::operator== - unequal wid or type" );
+ const ScPageScaleToItem& rPageCmp = static_cast< const ScPageScaleToItem& >( rCmp );
+ return ((mnWidth == rPageCmp.mnWidth) && (mnHeight == rPageCmp.mnHeight)) ? 1 : 0;
+}
+
+namespace {
+void lclAppendScalePageCount( String& rText, sal_uInt16 nPages )
+{
+ rText.AppendAscii( ": " );
+ if( nPages )
+ {
+ String aPages( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALE_PAGES ) );
+ aPages.SearchAndReplaceAscii( "%1", String::CreateFromInt32( nPages ) );
+ rText.Append( aPages );
+ }
+ else
+ rText.Append( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALE_AUTO ) );
+}
+} // namespace
+
+SfxItemPresentation ScPageScaleToItem::GetPresentation(
+ SfxItemPresentation ePres, SfxMapUnit, SfxMapUnit, XubString& rText, const IntlWrapper* ) const
+{
+ rText.Erase();
+ if( !IsValid() || (ePres == SFX_ITEM_PRESENTATION_NONE) )
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ String aName( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALETO ) );
+ String aValue( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALE_WIDTH ) );
+ lclAppendScalePageCount( aValue, mnWidth );
+ aValue.AppendAscii( ", " ).Append( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALE_HEIGHT ) );
+ lclAppendScalePageCount( aValue, mnHeight );
+
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMEONLY:
+ rText = aName;
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText = aValue;
+ break;
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText.Assign( aName ).AppendAscii( " (" ).Append( aValue ).Append( ')' );
+ break;
+
+ default:
+ DBG_ERRORFILE( "ScPageScaleToItem::GetPresentation - unknown presentation mode" );
+ ePres = SFX_ITEM_PRESENTATION_NONE;
+ }
+ return ePres;
+}
+
+BOOL ScPageScaleToItem::QueryValue( uno::Any& rAny, BYTE nMemberId ) const
+{
+ BOOL bRet = TRUE;
+ switch( nMemberId )
+ {
+ case SC_MID_PAGE_SCALETO_WIDTH: rAny <<= mnWidth; break;
+ case SC_MID_PAGE_SCALETO_HEIGHT: rAny <<= mnHeight; break;
+ default:
+ DBG_ERRORFILE( "ScPageScaleToItem::QueryValue - unknown member ID" );
+ bRet = FALSE;
+ }
+ return bRet;
+}
+
+BOOL ScPageScaleToItem::PutValue( const uno::Any& rAny, BYTE nMemberId )
+{
+ BOOL bRet = FALSE;
+ switch( nMemberId )
+ {
+ case SC_MID_PAGE_SCALETO_WIDTH: bRet = rAny >>= mnWidth; break;
+ case SC_MID_PAGE_SCALETO_HEIGHT: bRet = rAny >>= mnHeight; break;
+ default:
+ DBG_ERRORFILE( "ScPageScaleToItem::PutValue - unknown member ID" );
+ }
+ return bRet;
+}
+
+// ============================================================================
+
+
diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx
new file mode 100644
index 000000000000..c9abd4aa90b8
--- /dev/null
+++ b/sc/source/core/data/autonamecache.cxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <unotools/transliterationwrapper.hxx>
+
+#include "autonamecache.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "queryparam.hxx"
+
+// -----------------------------------------------------------------------
+
+ScAutoNameCache::ScAutoNameCache( ScDocument* pD ) :
+ pDoc( pD ),
+ nCurrentTab( 0 ) // doesn't matter - aNames is empty
+{
+}
+
+ScAutoNameCache::~ScAutoNameCache()
+{
+}
+
+const ScAutoNameAddresses& ScAutoNameCache::GetNameOccurences( const String& rName, SCTAB nTab )
+{
+ if ( nTab != nCurrentTab )
+ {
+ // the lists are valid only for one sheet, so they are cleared when another sheet is used
+ aNames.clear();
+ nCurrentTab = nTab;
+ }
+
+ ScAutoNameHashMap::const_iterator aFound = aNames.find( rName );
+ if ( aFound != aNames.end() )
+ return aFound->second; // already initialized
+
+ ScAutoNameAddresses& rAddresses = aNames[rName];
+
+ ScCellIterator aIter( pDoc, ScRange( 0, 0, nCurrentTab, MAXCOL, MAXROW, nCurrentTab ) );
+ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
+ {
+ // don't check code length here, always use the stored result
+ // (AutoCalc is disabled during CompileXML)
+
+ if ( pCell->HasStringData() )
+ {
+ String aStr;
+ CellType eType = pCell->GetCellType();
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ ((ScStringCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_FORMULA:
+ ((ScFormulaCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_EDIT:
+ ((ScEditCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_NONE:
+ case CELLTYPE_VALUE:
+ case CELLTYPE_NOTE:
+ case CELLTYPE_SYMBOLS:
+#ifdef DBG_UTIL
+ case CELLTYPE_DESTROYED:
+#endif
+ ; // nothing, prevent compiler warning
+ break;
+ }
+ if ( ScGlobal::GetpTransliteration()->isEqual( aStr, rName ) )
+ {
+ rAddresses.push_back( ScAddress( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ) );
+ }
+ }
+ }
+
+ return rAddresses;
+}
+
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
new file mode 100644
index 000000000000..540fb577a79b
--- /dev/null
+++ b/sc/source/core/data/bcaslot.cxx
@@ -0,0 +1,937 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <sfx2/objsh.hxx>
+#include <svl/listener.hxx>
+#include <svl/listeneriter.hxx>
+
+#include "document.hxx"
+#include "brdcst.hxx"
+#include "bcaslot.hxx"
+#include "scerrors.hxx"
+#include "docoptio.hxx"
+#include "refupdat.hxx"
+#include "table.hxx"
+
+// Number of slots per dimension
+// must be integer divisors of MAXCOLCOUNT respectively MAXROWCOUNT
+#define BCA_SLOTS_COL ((MAXCOLCOUNT_DEFINE) / 16)
+#if MAXROWCOUNT_DEFINE == 32000
+#define BCA_SLOTS_ROW 256
+#define BCA_SLICE 125
+#else
+#define BCA_SLICE 128
+#define BCA_SLOTS_ROW ((MAXROWCOUNT_DEFINE) / BCA_SLICE)
+#endif
+#define BCA_SLOT_COLS ((MAXCOLCOUNT_DEFINE) / BCA_SLOTS_COL)
+#define BCA_SLOT_ROWS ((MAXROWCOUNT_DEFINE) / BCA_SLOTS_ROW)
+// multiple?
+#if (BCA_SLOT_COLS * BCA_SLOTS_COL) != (MAXCOLCOUNT_DEFINE)
+#error bad BCA_SLOTS_COL value!
+#endif
+#if (BCA_SLOT_ROWS * BCA_SLOTS_ROW) != (MAXROWCOUNT_DEFINE)
+#error bad BCA_SLOTS_ROW value!
+#endif
+// size of slot array if linear
+#define BCA_SLOTS_DEFINE (BCA_SLOTS_COL * BCA_SLOTS_ROW)
+// Arbitrary 2**31/8, assuming size_t can hold at least 2^31 values and
+// sizeof_ptr is at most 8 bytes. You'd probably doom your machine's memory
+// anyway, once you reached these values..
+#if BCA_SLOTS_DEFINE > 268435456
+#error BCA_SLOTS_DEFINE DOOMed!
+#endif
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1( ScHint, SfxSimpleHint );
+TYPEINIT1( ScAreaChangedHint, SfxHint );
+
+struct ScSlotData
+{
+ SCROW nStartRow; // first row of this segment
+ SCROW nStopRow; // first row of next segment
+ SCSIZE nSlice; // slice size in this segment
+ SCSIZE nCumulated; // cumulated slots of previous segments
+
+ ScSlotData( SCROW r1, SCROW r2, SCSIZE s, SCSIZE c ) : nStartRow(r1), nStopRow(r2), nSlice(s), nCumulated(c) {}
+};
+typedef ::std::vector< ScSlotData > ScSlotDistribution;
+#if MAXROWCOUNT_DEFINE <= 65536
+// Linear distribution.
+static ScSlotDistribution aSlotDistribution( ScSlotData( 0, MAXROWCOUNT, BCA_SLOT_ROWS, 0));
+static SCSIZE nBcaSlotsRow = BCA_SLOTS_ROW;
+static SCSIZE nBcaSlots = BCA_SLOTS_DEFINE;
+#else
+// Logarithmic or any other distribution.
+// Upper sheet part usually is more populated and referenced and gets fine
+// grained resolution, larger data in larger hunks.
+// Could be further enhanced by also applying a different distribution of
+// column slots.
+static SCSIZE initSlotDistribution( ScSlotDistribution & rSD, SCSIZE & rBSR )
+{
+ SCSIZE nSlots = 0;
+ SCROW nRow1 = 0;
+ SCROW nRow2 = 32*1024;
+ SCSIZE nSlice = 128;
+ // Must be sorted by row1,row2!
+ while (nRow2 <= MAXROWCOUNT)
+ {
+ //fprintf( stderr, "r1,r2,slice,cum: %7zu, %7zu, %7zu, %7zu\n", (size_t)nRow1, (size_t)nRow2, (size_t)nSlice, (size_t)nSlots);
+ // {0,32k,128,0;32k,64k,256,0+256;64k,128k,512,0+256+128;128k,256k,1024,0+256+128+128;256k,512k,2048,...;512k,1M,4096,...}
+ rSD.push_back( ScSlotData( nRow1, nRow2, nSlice, nSlots));
+ nSlots += (nRow2 - nRow1) / nSlice;
+ nRow1 = nRow2;
+ nRow2 *= 2;
+ nSlice *= 2;
+ }
+ //fprintf( stderr, "Slices: %zu, slots per sheet: %zu, memory per referenced sheet: %zu\n", (size_t) nSlots, (size_t) nSlots * BCA_SLOTS_COL, (size_t) nSlots * BCA_SLOTS_COL * sizeof(void*));
+ rBSR = nSlots;
+ return nSlots;
+}
+static ScSlotDistribution aSlotDistribution;
+static SCSIZE nBcaSlotsRow;
+static SCSIZE nBcaSlots = initSlotDistribution( aSlotDistribution, nBcaSlotsRow) * BCA_SLOTS_COL;
+// Ensure that all static variables are initialized with this one call.
+#endif
+
+
+ScBroadcastAreaSlot::ScBroadcastAreaSlot( ScDocument* pDocument,
+ ScBroadcastAreaSlotMachine* pBASMa ) :
+ aTmpSeekBroadcastArea( ScRange()),
+ pDoc( pDocument ),
+ pBASM( pBASMa )
+{
+}
+
+
+ScBroadcastAreaSlot::~ScBroadcastAreaSlot()
+{
+ for ( ScBroadcastAreas::iterator aIter( aBroadcastAreaTbl.begin());
+ aIter != aBroadcastAreaTbl.end(); /* none */)
+ {
+ // Prevent hash from accessing dangling pointer in case area is
+ // deleted.
+ ScBroadcastArea* pArea = *aIter;
+ // Erase all so no hash will be accessed upon destruction of the
+ // hash_set.
+ aBroadcastAreaTbl.erase( aIter++);
+ if (!pArea->DecRef())
+ delete pArea;
+ }
+}
+
+
+bool ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
+{
+ if ( pDoc->GetHardRecalcState() )
+ return true;
+ if (aBroadcastAreaTbl.size() >= aBroadcastAreaTbl.max_size())
+ { // this is more hypothetical now, check existed for old SV_PTRARR_SORT
+ if ( !pDoc->GetHardRecalcState() )
+ {
+ pDoc->SetHardRecalcState( 1 );
+
+ SfxObjectShell* pShell = pDoc->GetDocumentShell();
+ DBG_ASSERT( pShell, "Missing DocShell :-/" );
+
+ if ( pShell )
+ pShell->SetError( SCWARN_CORE_HARD_RECALC, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ pDoc->SetAutoCalc( FALSE );
+ pDoc->SetHardRecalcState( 2 );
+ }
+ return true;
+ }
+ return false;
+}
+
+
+bool ScBroadcastAreaSlot::StartListeningArea( const ScRange& rRange,
+ SvtListener* pListener, ScBroadcastArea*& rpArea )
+{
+ bool bNewArea = false;
+ DBG_ASSERT(pListener, "StartListeningArea: pListener Null");
+ if (CheckHardRecalcStateCondition())
+ return false;
+ if ( !rpArea )
+ {
+ // Even if most times the area doesn't exist yet and immediately trying
+ // to new and insert it would save an attempt to find it, on mass
+ // operations like identical large [HV]LOOKUP() areas the new/delete
+ // would add quite some penalty for all but the first formula cell.
+ ScBroadcastAreas::const_iterator aIter( FindBroadcastArea( rRange));
+ if (aIter != aBroadcastAreaTbl.end())
+ rpArea = *aIter;
+ else
+ {
+ rpArea = new ScBroadcastArea( rRange);
+ if (aBroadcastAreaTbl.insert( rpArea).second)
+ {
+ rpArea->IncRef();
+ bNewArea = true;
+ }
+ else
+ {
+ DBG_ERRORFILE("StartListeningArea: area not found and not inserted in slot?!?");
+ delete rpArea;
+ rpArea = 0;
+ }
+ }
+ if (rpArea)
+ pListener->StartListening( rpArea->GetBroadcaster());
+ }
+ else
+ {
+ if (aBroadcastAreaTbl.insert( rpArea).second)
+ rpArea->IncRef();
+ }
+ return bNewArea;
+}
+
+
+void ScBroadcastAreaSlot::InsertListeningArea( ScBroadcastArea* pArea )
+{
+ DBG_ASSERT( pArea, "InsertListeningArea: pArea NULL");
+ if (CheckHardRecalcStateCondition())
+ return;
+ if (aBroadcastAreaTbl.insert( pArea).second)
+ pArea->IncRef();
+}
+
+
+// If rpArea != NULL then no listeners are stopped, only the area is removed
+// and the reference count decremented.
+void ScBroadcastAreaSlot::EndListeningArea( const ScRange& rRange,
+ SvtListener* pListener, ScBroadcastArea*& rpArea )
+{
+ DBG_ASSERT(pListener, "EndListeningArea: pListener Null");
+ if ( !rpArea )
+ {
+ ScBroadcastAreas::iterator aIter( FindBroadcastArea( rRange));
+ if (aIter == aBroadcastAreaTbl.end())
+ return;
+ rpArea = *aIter;
+ pListener->EndListening( rpArea->GetBroadcaster() );
+ if ( !rpArea->GetBroadcaster().HasListeners() )
+ { // if nobody is listening we can dispose it
+ aBroadcastAreaTbl.erase( aIter);
+ if ( !rpArea->DecRef() )
+ {
+ delete rpArea;
+ rpArea = NULL;
+ }
+ }
+ }
+ else
+ {
+ if ( !rpArea->GetBroadcaster().HasListeners() )
+ {
+ ScBroadcastAreas::iterator aIter( FindBroadcastArea( rRange));
+ if (aIter == aBroadcastAreaTbl.end())
+ return;
+ DBG_ASSERT( *aIter == rpArea, "EndListeningArea: area pointer mismatch");
+ aBroadcastAreaTbl.erase( aIter);
+ if ( !rpArea->DecRef() )
+ {
+ delete rpArea;
+ rpArea = NULL;
+ }
+ }
+ }
+}
+
+
+ScBroadcastAreas::iterator ScBroadcastAreaSlot::FindBroadcastArea(
+ const ScRange& rRange ) const
+{
+ aTmpSeekBroadcastArea.UpdateRange( rRange);
+ return aBroadcastAreaTbl.find( &aTmpSeekBroadcastArea);
+}
+
+
+BOOL ScBroadcastAreaSlot::AreaBroadcast( const ScHint& rHint) const
+{
+ if (aBroadcastAreaTbl.empty())
+ return FALSE;
+ BOOL bIsBroadcasted = FALSE;
+ const ScAddress& rAddress = rHint.GetAddress();
+ for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin());
+ aIter != aBroadcastAreaTbl.end(); /* increment in body */ )
+ {
+ ScBroadcastArea* pArea = *aIter;
+ // A Notify() during broadcast may call EndListeningArea() and thus
+ // dispose this area if it was the last listener, which would
+ // invalidate the iterator, hence increment before call.
+ ++aIter;
+ const ScRange& rAreaRange = pArea->GetRange();
+ if (rAreaRange.In( rAddress))
+ {
+ if (!pBASM->IsInBulkBroadcast() || pBASM->InsertBulkArea( pArea))
+ {
+ pArea->GetBroadcaster().Broadcast( rHint);
+ bIsBroadcasted = TRUE;
+ }
+ }
+ }
+ return bIsBroadcasted;
+}
+
+
+BOOL ScBroadcastAreaSlot::AreaBroadcastInRange( const ScRange& rRange,
+ const ScHint& rHint) const
+{
+ if (aBroadcastAreaTbl.empty())
+ return FALSE;
+ BOOL bIsBroadcasted = FALSE;
+ for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin());
+ aIter != aBroadcastAreaTbl.end(); /* increment in body */ )
+ {
+ ScBroadcastArea* pArea = *aIter;
+ // A Notify() during broadcast may call EndListeningArea() and thus
+ // dispose this area if it was the last listener, which would
+ // invalidate the iterator, hence increment before call.
+ ++aIter;
+ const ScRange& rAreaRange = pArea->GetRange();
+ if (rAreaRange.Intersects( rRange ))
+ {
+ if (!pBASM->IsInBulkBroadcast() || pBASM->InsertBulkArea( pArea))
+ {
+ pArea->GetBroadcaster().Broadcast( rHint);
+ bIsBroadcasted = TRUE;
+ }
+ }
+ }
+ return bIsBroadcasted;
+}
+
+
+void ScBroadcastAreaSlot::DelBroadcastAreasInRange( const ScRange& rRange )
+{
+ if (aBroadcastAreaTbl.empty())
+ return;
+ for (ScBroadcastAreas::iterator aIter( aBroadcastAreaTbl.begin());
+ aIter != aBroadcastAreaTbl.end(); /* increment in body */ )
+ {
+ const ScRange& rAreaRange = (*aIter)->GetRange();
+ if (rRange.In( rAreaRange))
+ {
+ ScBroadcastArea* pArea = *aIter;
+ aBroadcastAreaTbl.erase( aIter++); // erase before modifying
+ if (!pArea->DecRef())
+ {
+ if (pBASM->IsInBulkBroadcast())
+ pBASM->RemoveBulkArea( pArea);
+ delete pArea;
+ }
+ }
+ else
+ ++aIter;
+ }
+}
+
+
+void ScBroadcastAreaSlot::UpdateRemove( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ if (aBroadcastAreaTbl.empty())
+ return;
+
+ SCCOL nCol1, nCol2, theCol1, theCol2;
+ SCROW nRow1, nRow2, theRow1, theRow2;
+ SCTAB nTab1, nTab2, theTab1, theTab2;
+ rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ for ( ScBroadcastAreas::iterator aIter( aBroadcastAreaTbl.begin());
+ aIter != aBroadcastAreaTbl.end(); /* increment in body */ )
+ {
+ ScBroadcastArea* pArea = *aIter;
+ if ( pArea->IsInUpdateChain() )
+ {
+ aBroadcastAreaTbl.erase( aIter++);
+ pArea->DecRef();
+ }
+ else
+ {
+ pArea->GetRange().GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2);
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
+ theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ))
+ {
+ aBroadcastAreaTbl.erase( aIter++);
+ pArea->DecRef();
+ if (pBASM->IsInBulkBroadcast())
+ pBASM->RemoveBulkArea( pArea);
+ pArea->SetInUpdateChain( TRUE );
+ ScBroadcastArea* pUC = pBASM->GetEOUpdateChain();
+ if ( pUC )
+ pUC->SetUpdateChainNext( pArea );
+ else // no tail => no head
+ pBASM->SetUpdateChain( pArea );
+ pBASM->SetEOUpdateChain( pArea );
+ }
+ else
+ ++aIter;
+ }
+ }
+}
+
+
+void ScBroadcastAreaSlot::UpdateRemoveArea( ScBroadcastArea* pArea )
+{
+ ScBroadcastAreas::iterator aIter( aBroadcastAreaTbl.find( pArea));
+ if (aIter == aBroadcastAreaTbl.end())
+ return;
+ if (*aIter != pArea)
+ DBG_ERRORFILE( "UpdateRemoveArea: area pointer mismatch");
+ else
+ {
+ aBroadcastAreaTbl.erase( aIter);
+ pArea->DecRef();
+ }
+}
+
+
+void ScBroadcastAreaSlot::UpdateInsert( ScBroadcastArea* pArea )
+{
+ ::std::pair< ScBroadcastAreas::iterator, bool > aPair =
+ aBroadcastAreaTbl.insert( pArea );
+ if (aPair.second)
+ pArea->IncRef();
+ else
+ {
+ // Identical area already exists, add listeners.
+ ScBroadcastArea* pTarget = *(aPair.first);
+ if (pArea != pTarget)
+ {
+ SvtBroadcaster& rTarget = pTarget->GetBroadcaster();
+ SvtListenerIter it( pArea->GetBroadcaster());
+ for (SvtListener* pListener = it.GetCurr(); pListener;
+ pListener = it.GoNext())
+ {
+ pListener->StartListening( rTarget);
+ }
+ }
+ }
+}
+
+
+// --- ScBroadcastAreaSlotMachine -------------------------------------
+
+ScBroadcastAreaSlotMachine::TableSlots::TableSlots()
+{
+ ppSlots = new ScBroadcastAreaSlot* [ nBcaSlots ];
+ memset( ppSlots, 0 , sizeof( ScBroadcastAreaSlot* ) * nBcaSlots );
+}
+
+
+ScBroadcastAreaSlotMachine::TableSlots::~TableSlots()
+{
+ for ( ScBroadcastAreaSlot** pp = ppSlots + nBcaSlots; --pp >= ppSlots; /* nothing */ )
+ {
+ if (*pp)
+ delete *pp;
+ }
+ delete [] ppSlots;
+}
+
+
+ScBroadcastAreaSlotMachine::ScBroadcastAreaSlotMachine(
+ ScDocument* pDocument ) :
+ pBCAlways( NULL ),
+ pDoc( pDocument ),
+ pUpdateChain( NULL ),
+ pEOUpdateChain( NULL ),
+ nInBulkBroadcast( 0 )
+{
+}
+
+
+ScBroadcastAreaSlotMachine::~ScBroadcastAreaSlotMachine()
+{
+ for (TableSlotsMap::iterator iTab( aTableSlotsMap.begin());
+ iTab != aTableSlotsMap.end(); ++iTab)
+ {
+ delete (*iTab).second;
+ }
+ delete pBCAlways;
+}
+
+
+inline SCSIZE ScBroadcastAreaSlotMachine::ComputeSlotOffset(
+ const ScAddress& rAddress ) const
+{
+ SCROW nRow = rAddress.Row();
+ SCCOL nCol = rAddress.Col();
+ if ( !ValidRow(nRow) || !ValidCol(nCol) )
+ {
+ DBG_ERRORFILE( "Row/Col invalid, using first slot!" );
+ return 0;
+ }
+ for (size_t i=0; i < aSlotDistribution.size(); ++i)
+ {
+ if (nRow < aSlotDistribution[i].nStopRow)
+ {
+ const ScSlotData& rSD = aSlotDistribution[i];
+ return rSD.nCumulated +
+ (static_cast<SCSIZE>(nRow - rSD.nStartRow)) / rSD.nSlice +
+ static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * nBcaSlotsRow;
+ }
+ }
+ DBG_ERRORFILE( "No slot found, using last!" );
+ return nBcaSlots - 1;
+}
+
+
+void ScBroadcastAreaSlotMachine::ComputeAreaPoints( const ScRange& rRange,
+ SCSIZE& rStart, SCSIZE& rEnd, SCSIZE& rRowBreak ) const
+{
+ rStart = ComputeSlotOffset( rRange.aStart );
+ rEnd = ComputeSlotOffset( rRange.aEnd );
+ // count of row slots per column minus one
+ rRowBreak = ComputeSlotOffset(
+ ScAddress( rRange.aStart.Col(), rRange.aEnd.Row(), 0 ) ) - rStart;
+}
+
+
+inline void ComputeNextSlot( SCSIZE & nOff, SCSIZE & nBreak, ScBroadcastAreaSlot** & pp,
+ SCSIZE & nStart, ScBroadcastAreaSlot** const & ppSlots, SCSIZE const & nRowBreak )
+{
+ if ( nOff < nBreak )
+ {
+ ++nOff;
+ ++pp;
+ }
+ else
+ {
+ nStart += nBcaSlotsRow;
+ nOff = nStart;
+ pp = ppSlots + nOff;
+ nBreak = nOff + nRowBreak;
+ }
+}
+
+
+void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange,
+ SvtListener* pListener )
+{
+ //fprintf( stderr, "StartListeningArea (c,r,t): %d, %d, %d, %d, %d, %d\n", (int)rRange.aStart.Col(), (int)rRange.aStart.Row(), (int)rRange.aStart.Tab(), (int)rRange.aEnd.Col(), (int)rRange.aEnd.Row(), (int)rRange.aEnd.Tab());
+ if ( rRange == BCA_LISTEN_ALWAYS )
+ {
+ if ( !pBCAlways )
+ pBCAlways = new SvtBroadcaster;
+ pListener->StartListening( *pBCAlways );
+ }
+ else
+ {
+ bool bDone = false;
+ for (SCTAB nTab = rRange.aStart.Tab();
+ !bDone && nTab <= rRange.aEnd.Tab(); ++nTab)
+ {
+ TableSlotsMap::iterator iTab( aTableSlotsMap.find( nTab));
+ if (iTab == aTableSlotsMap.end())
+ iTab = aTableSlotsMap.insert( TableSlotsMap::value_type(
+ nTab, new TableSlots)).first;
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( rRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ ScBroadcastArea* pArea = NULL;
+ while ( !bDone && nOff <= nEnd )
+ {
+ if ( !*pp )
+ *pp = new ScBroadcastAreaSlot( pDoc, this );
+ if (!pArea)
+ {
+ // If the call to StartListeningArea didn't create the
+ // ScBroadcastArea, listeners were added to an already
+ // existing identical area that doesn't need to be inserted
+ // to slots again.
+ if (!(*pp)->StartListeningArea( rRange, pListener, pArea))
+ bDone = true;
+ }
+ else
+ (*pp)->InsertListeningArea( pArea);
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+ }
+}
+
+
+void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange,
+ SvtListener* pListener )
+{
+ //fprintf( stderr, "EndListeningArea (c,r,t): %d, %d, %d, %d, %d, %d\n", (int)rRange.aStart.Col(), (int)rRange.aStart.Row(), (int)rRange.aStart.Tab(), (int)rRange.aEnd.Col(), (int)rRange.aEnd.Row(), (int)rRange.aEnd.Tab());
+ if ( rRange == BCA_LISTEN_ALWAYS )
+ {
+ DBG_ASSERT( pBCAlways, "ScBroadcastAreaSlotMachine::EndListeningArea: BCA_LISTEN_ALWAYS but none established");
+ if ( pBCAlways )
+ {
+ pListener->EndListening( *pBCAlways);
+ if (!pBCAlways->HasListeners())
+ {
+ delete pBCAlways;
+ pBCAlways = NULL;
+ }
+ }
+ }
+ else
+ {
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ for (TableSlotsMap::iterator iTab( aTableSlotsMap.lower_bound( rRange.aStart.Tab()));
+ iTab != aTableSlotsMap.end() && (*iTab).first <= nEndTab; ++iTab)
+ {
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( rRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ ScBroadcastArea* pArea = NULL;
+ if (nOff == 0 && nEnd == nBcaSlots-1)
+ {
+ // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
+ // happen for insertion and deletion of sheets.
+ ScBroadcastAreaSlot** const pStop = ppSlots + nEnd;
+ do
+ {
+ if ( *pp )
+ (*pp)->EndListeningArea( rRange, pListener, pArea );
+ } while (++pp < pStop);
+ }
+ else
+ {
+ while ( nOff <= nEnd )
+ {
+ if ( *pp )
+ (*pp)->EndListeningArea( rRange, pListener, pArea );
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+ }
+ }
+}
+
+
+BOOL ScBroadcastAreaSlotMachine::AreaBroadcast( const ScHint& rHint ) const
+{
+ const ScAddress& rAddress = rHint.GetAddress();
+ if ( rAddress == BCA_BRDCST_ALWAYS )
+ {
+ if ( pBCAlways )
+ {
+ pBCAlways->Broadcast( rHint );
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ else
+ {
+ TableSlotsMap::const_iterator iTab( aTableSlotsMap.find( rAddress.Tab()));
+ if (iTab == aTableSlotsMap.end())
+ return FALSE;
+ ScBroadcastAreaSlot* pSlot = (*iTab).second->getAreaSlot(
+ ComputeSlotOffset( rAddress));
+ if ( pSlot )
+ return pSlot->AreaBroadcast( rHint );
+ else
+ return FALSE;
+ }
+}
+
+
+BOOL ScBroadcastAreaSlotMachine::AreaBroadcastInRange( const ScRange& rRange,
+ const ScHint& rHint ) const
+{
+ BOOL bBroadcasted = FALSE;
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ for (TableSlotsMap::const_iterator iTab( aTableSlotsMap.lower_bound( rRange.aStart.Tab()));
+ iTab != aTableSlotsMap.end() && (*iTab).first <= nEndTab; ++iTab)
+ {
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( rRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ while ( nOff <= nEnd )
+ {
+ if ( *pp )
+ bBroadcasted |= (*pp)->AreaBroadcastInRange( rRange, rHint );
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+ return bBroadcasted;
+}
+
+
+void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange(
+ const ScRange& rRange )
+{
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ for (TableSlotsMap::iterator iTab( aTableSlotsMap.lower_bound( rRange.aStart.Tab()));
+ iTab != aTableSlotsMap.end() && (*iTab).first <= nEndTab; ++iTab)
+ {
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( rRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ if (nOff == 0 && nEnd == nBcaSlots-1)
+ {
+ // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
+ // happen for insertion and deletion of sheets.
+ ScBroadcastAreaSlot** const pStop = ppSlots + nEnd;
+ do
+ {
+ if ( *pp )
+ (*pp)->DelBroadcastAreasInRange( rRange );
+ } while (++pp < pStop);
+ }
+ else
+ {
+ while ( nOff <= nEnd )
+ {
+ if ( *pp )
+ (*pp)->DelBroadcastAreasInRange( rRange );
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+ }
+}
+
+
+// for all affected: remove, chain, update range, insert, and maybe delete
+void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
+ UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ // remove affected and put in chain
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ for (TableSlotsMap::iterator iTab( aTableSlotsMap.lower_bound( rRange.aStart.Tab()));
+ iTab != aTableSlotsMap.end() && (*iTab).first <= nEndTab; ++iTab)
+ {
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( rRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ if (nOff == 0 && nEnd == nBcaSlots-1)
+ {
+ // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
+ // happen for insertion and deletion of sheets.
+ ScBroadcastAreaSlot** const pStop = ppSlots + nEnd;
+ do
+ {
+ if ( *pp )
+ (*pp)->UpdateRemove( eUpdateRefMode, rRange, nDx, nDy, nDz );
+ } while (++pp < pStop);
+ }
+ else
+ {
+ while ( nOff <= nEnd )
+ {
+ if ( *pp )
+ (*pp)->UpdateRemove( eUpdateRefMode, rRange, nDx, nDy, nDz );
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+ }
+
+ // Updating an area's range will modify the hash key, remove areas from all
+ // affected slots. Will be reinserted later with the updated range.
+ ScBroadcastArea* pChain = pUpdateChain;
+ while (pChain)
+ {
+ ScBroadcastArea* pArea = pChain;
+ pChain = pArea->GetUpdateChainNext();
+ ScRange aRange( pArea->GetRange());
+ // remove from slots
+ for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab() && pArea->GetRef(); ++nTab)
+ {
+ TableSlotsMap::iterator iTab( aTableSlotsMap.find( nTab));
+ if (iTab == aTableSlotsMap.end())
+ {
+ DBG_ERRORFILE( "UpdateBroadcastAreas: Where's the TableSlot?!?");
+ continue; // for
+ }
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( aRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ while ( nOff <= nEnd && pArea->GetRef() )
+ {
+ if (*pp)
+ (*pp)->UpdateRemoveArea( pArea);
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+
+ }
+
+ // shift sheets
+ if (nDz)
+ {
+ if (nDz < 0)
+ {
+ TableSlotsMap::iterator iDel( aTableSlotsMap.lower_bound( rRange.aStart.Tab()));
+ TableSlotsMap::iterator iTab( aTableSlotsMap.lower_bound( rRange.aStart.Tab() - nDz));
+ // Remove sheets, if any, iDel or/and iTab may as well point to end().
+ while (iDel != iTab)
+ {
+ delete (*iDel).second;
+ aTableSlotsMap.erase( iDel++);
+ }
+ // shift remaining down
+ while (iTab != aTableSlotsMap.end())
+ {
+ SCTAB nTab = (*iTab).first + nDz;
+ aTableSlotsMap[nTab] = (*iTab).second;
+ aTableSlotsMap.erase( iTab++);
+ }
+ }
+ else
+ {
+ TableSlotsMap::iterator iStop( aTableSlotsMap.lower_bound( rRange.aStart.Tab()));
+ if (iStop != aTableSlotsMap.end())
+ {
+ bool bStopIsBegin = (iStop == aTableSlotsMap.begin());
+ if (!bStopIsBegin)
+ --iStop;
+ TableSlotsMap::iterator iTab( aTableSlotsMap.end());
+ --iTab;
+ while (iTab != iStop)
+ {
+ SCTAB nTab = (*iTab).first + nDz;
+ aTableSlotsMap[nTab] = (*iTab).second;
+ aTableSlotsMap.erase( iTab--);
+ }
+ // Shift the very first, iTab==iStop in this case.
+ if (bStopIsBegin)
+ {
+ SCTAB nTab = (*iTab).first + nDz;
+ aTableSlotsMap[nTab] = (*iTab).second;
+ aTableSlotsMap.erase( iStop);
+ }
+ }
+ }
+ }
+
+ // work off chain
+ SCCOL nCol1, nCol2, theCol1, theCol2;
+ SCROW nRow1, nRow2, theRow1, theRow2;
+ SCTAB nTab1, nTab2, theTab1, theTab2;
+ rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ while ( pUpdateChain )
+ {
+ ScBroadcastArea* pArea = pUpdateChain;
+ ScRange aRange( pArea->GetRange());
+ pUpdateChain = pArea->GetUpdateChainNext();
+
+ // update range
+ aRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2);
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
+ theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ))
+ {
+ aRange = ScRange( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
+ pArea->UpdateRange( aRange );
+ pArea->GetBroadcaster().Broadcast( ScAreaChangedHint( aRange ) ); // for DDE
+ }
+
+ // insert to slots
+ for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); ++nTab)
+ {
+ TableSlotsMap::iterator iTab( aTableSlotsMap.find( nTab));
+ if (iTab == aTableSlotsMap.end())
+ iTab = aTableSlotsMap.insert( TableSlotsMap::value_type(
+ nTab, new TableSlots)).first;
+ ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
+ SCSIZE nStart, nEnd, nRowBreak;
+ ComputeAreaPoints( aRange, nStart, nEnd, nRowBreak );
+ SCSIZE nOff = nStart;
+ SCSIZE nBreak = nOff + nRowBreak;
+ ScBroadcastAreaSlot** pp = ppSlots + nOff;
+ while ( nOff <= nEnd )
+ {
+ if (!*pp)
+ *pp = new ScBroadcastAreaSlot( pDoc, this );
+ (*pp)->UpdateInsert( pArea );
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+ }
+ }
+
+ // unchain
+ pArea->SetUpdateChainNext( NULL );
+ pArea->SetInUpdateChain( FALSE );
+
+ // Delete if not inserted to any slot. RemoveBulkArea(pArea) was
+ // already executed in UpdateRemove().
+ if (!pArea->GetRef())
+ delete pArea;
+ }
+ pEOUpdateChain = NULL;
+}
+
+
+void ScBroadcastAreaSlotMachine::EnterBulkBroadcast()
+{
+ ++nInBulkBroadcast;
+}
+
+
+void ScBroadcastAreaSlotMachine::LeaveBulkBroadcast()
+{
+ if (nInBulkBroadcast > 0)
+ {
+ if (--nInBulkBroadcast == 0)
+ ScBroadcastAreasBulk().swap( aBulkBroadcastAreas);
+ }
+}
+
+
+bool ScBroadcastAreaSlotMachine::InsertBulkArea( const ScBroadcastArea* pArea )
+{
+ return aBulkBroadcastAreas.insert( pArea ).second;
+}
+
+
+size_t ScBroadcastAreaSlotMachine::RemoveBulkArea( const ScBroadcastArea* pArea )
+{
+ return aBulkBroadcastAreas.erase( pArea );
+}
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
new file mode 100644
index 000000000000..aa492630ab0e
--- /dev/null
+++ b/sc/source/core/data/cell.cxx
@@ -0,0 +1,2037 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/zforlist.hxx>
+
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "cell.hxx"
+#include "compiler.hxx"
+#include "interpre.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include "dociter.hxx"
+#include "docoptio.hxx"
+#include "rechead.hxx"
+#include "rangenam.hxx"
+#include "brdcst.hxx"
+#include "ddelink.hxx"
+#include "validat.hxx"
+#include "progress.hxx"
+#include "editutil.hxx"
+#include "recursionhelper.hxx"
+#include "postit.hxx"
+#include "externalrefmgr.hxx"
+#include <editeng/editobj.hxx>
+#include <svl/intitem.hxx>
+#include <editeng/flditem.hxx>
+#include <svl/broadcast.hxx>
+
+using namespace formula;
+// More or less arbitrary, of course all recursions must fit into available
+// stack space (which is what on all systems we don't know yet?). Choosing a
+// lower value may be better than trying a much higher value that also isn't
+// sufficient but temporarily leads to high memory consumption. On the other
+// hand, if the value fits all recursions, execution is quicker as no resumes
+// are necessary. Could be made a configurable option.
+// Allow for a year's calendar (366).
+const USHORT MAXRECURSION = 400;
+
+// STATIC DATA -----------------------------------------------------------
+
+#ifdef USE_MEMPOOL
+// MemPools auf 4k Boundaries - 64 Bytes ausrichten
+const USHORT nMemPoolValueCell = (0x8000 - 64) / sizeof(ScValueCell);
+const USHORT nMemPoolFormulaCell = (0x8000 - 64) / sizeof(ScFormulaCell);
+const USHORT nMemPoolStringCell = (0x4000 - 64) / sizeof(ScStringCell);
+const USHORT nMemPoolNoteCell = (0x1000 - 64) / sizeof(ScNoteCell);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScValueCell, nMemPoolValueCell, nMemPoolValueCell )
+IMPL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell, nMemPoolFormulaCell, nMemPoolFormulaCell )
+IMPL_FIXEDMEMPOOL_NEWDEL( ScStringCell, nMemPoolStringCell, nMemPoolStringCell )
+IMPL_FIXEDMEMPOOL_NEWDEL( ScNoteCell, nMemPoolNoteCell, nMemPoolNoteCell )
+#endif
+
+// ============================================================================
+
+ScBaseCell::ScBaseCell( CellType eNewType ) :
+ mpNote( 0 ),
+ mpBroadcaster( 0 ),
+ nTextWidth( TEXTWIDTH_DIRTY ),
+ eCellType( sal::static_int_cast<BYTE>(eNewType) ),
+ nScriptType( SC_SCRIPTTYPE_UNKNOWN )
+{
+}
+
+ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
+ mpNote( 0 ),
+ mpBroadcaster( 0 ),
+ nTextWidth( rCell.nTextWidth ),
+ eCellType( rCell.eCellType ),
+ nScriptType( SC_SCRIPTTYPE_UNKNOWN )
+{
+}
+
+ScBaseCell::~ScBaseCell()
+{
+ delete mpNote;
+ delete mpBroadcaster;
+ DBG_ASSERT( eCellType == CELLTYPE_DESTROYED, "BaseCell Destructor" );
+}
+
+namespace {
+
+ScBaseCell* lclCloneCell( const ScBaseCell& rSrcCell, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags )
+{
+ switch( rSrcCell.GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ return new ScValueCell( static_cast< const ScValueCell& >( rSrcCell ) );
+ case CELLTYPE_STRING:
+ return new ScStringCell( static_cast< const ScStringCell& >( rSrcCell ) );
+ case CELLTYPE_EDIT:
+ return new ScEditCell( static_cast< const ScEditCell& >( rSrcCell ), rDestDoc );
+ case CELLTYPE_FORMULA:
+ return new ScFormulaCell( static_cast< const ScFormulaCell& >( rSrcCell ), rDestDoc, rDestPos, nCloneFlags );
+ case CELLTYPE_NOTE:
+ return new ScNoteCell;
+ default:;
+ }
+ DBG_ERROR( "lclCloneCell - unknown cell type" );
+ return 0;
+}
+
+} // namespace
+
+ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, int nCloneFlags ) const
+{
+ // notes will not be cloned -> cell address only needed for formula cells
+ ScAddress aDestPos;
+ if( eCellType == CELLTYPE_FORMULA )
+ aDestPos = static_cast< const ScFormulaCell* >( this )->aPos;
+ return lclCloneCell( *this, rDestDoc, aDestPos, nCloneFlags );
+}
+
+ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
+{
+ return lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
+}
+
+ScBaseCell* ScBaseCell::CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
+{
+ ScBaseCell* pNewCell = lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
+ if( mpNote )
+ {
+ if( !pNewCell )
+ pNewCell = new ScNoteCell;
+ bool bCloneCaption = (nCloneFlags & SC_CLONECELL_NOCAPTION) == 0;
+ pNewCell->TakeNote( mpNote->Clone( rOwnPos, rDestDoc, rDestPos, bCloneCaption ) );
+ }
+ return pNewCell;
+}
+
+void ScBaseCell::Delete()
+{
+ DeleteNote();
+ switch (eCellType)
+ {
+ case CELLTYPE_VALUE:
+ delete (ScValueCell*) this;
+ break;
+ case CELLTYPE_STRING:
+ delete (ScStringCell*) this;
+ break;
+ case CELLTYPE_EDIT:
+ delete (ScEditCell*) this;
+ break;
+ case CELLTYPE_FORMULA:
+ delete (ScFormulaCell*) this;
+ break;
+ case CELLTYPE_NOTE:
+ delete (ScNoteCell*) this;
+ break;
+ default:
+ DBG_ERROR("Unbekannter Zellentyp");
+ break;
+ }
+}
+
+bool ScBaseCell::IsBlank( bool bIgnoreNotes ) const
+{
+ return (eCellType == CELLTYPE_NOTE) && (bIgnoreNotes || !mpNote);
+}
+
+void ScBaseCell::TakeNote( ScPostIt* pNote )
+{
+ delete mpNote;
+ mpNote = pNote;
+}
+
+ScPostIt* ScBaseCell::ReleaseNote()
+{
+ ScPostIt* pNote = mpNote;
+ mpNote = 0;
+ return pNote;
+}
+
+void ScBaseCell::DeleteNote()
+{
+ DELETEZ( mpNote );
+}
+
+void ScBaseCell::TakeBroadcaster( SvtBroadcaster* pBroadcaster )
+{
+ delete mpBroadcaster;
+ mpBroadcaster = pBroadcaster;
+}
+
+SvtBroadcaster* ScBaseCell::ReleaseBroadcaster()
+{
+ SvtBroadcaster* pBroadcaster = mpBroadcaster;
+ mpBroadcaster = 0;
+ return pBroadcaster;
+}
+
+void ScBaseCell::DeleteBroadcaster()
+{
+ DELETEZ( mpBroadcaster );
+}
+
+ScBaseCell* ScBaseCell::CreateTextCell( const String& rString, ScDocument* pDoc )
+{
+ if ( rString.Search('\n') != STRING_NOTFOUND || rString.Search(CHAR_CR) != STRING_NOTFOUND )
+ return new ScEditCell( rString, pDoc );
+ else
+ return new ScStringCell( rString );
+}
+
+void ScBaseCell::StartListeningTo( ScDocument* pDoc )
+{
+ if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
+ && !pDoc->GetNoListening()
+ && !((ScFormulaCell*)this)->IsInChangeTrack()
+ )
+ {
+ pDoc->SetDetectiveDirty(TRUE); // es hat sich was geaendert...
+
+ ScFormulaCell* pFormCell = (ScFormulaCell*)this;
+ ScTokenArray* pArr = pFormCell->GetCode();
+ if( pArr->IsRecalcModeAlways() )
+ pDoc->StartListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
+ else
+ {
+ pArr->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+ {
+ StackVar eType = t->GetType();
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ ScSingleRefData& rRef2 = (eType == svDoubleRef ?
+ t->GetDoubleRef().Ref2 : rRef1);
+ switch( eType )
+ {
+ case svSingleRef:
+ rRef1.CalcAbsIfRel( pFormCell->aPos );
+ if ( rRef1.Valid() )
+ {
+ pDoc->StartListeningCell(
+ ScAddress( rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab ), pFormCell );
+ }
+ break;
+ case svDoubleRef:
+ t->CalcAbsIfRel( pFormCell->aPos );
+ if ( rRef1.Valid() && rRef2.Valid() )
+ {
+ if ( t->GetOpCode() == ocColRowNameAuto )
+ { // automagically
+ if ( rRef1.IsColRel() )
+ { // ColName
+ pDoc->StartListeningArea( ScRange (
+ rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab,
+ rRef2.nCol,
+ MAXROW,
+ rRef2.nTab ), pFormCell );
+ }
+ else
+ { // RowName
+ pDoc->StartListeningArea( ScRange (
+ rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab,
+ MAXCOL,
+ rRef2.nRow,
+ rRef2.nTab ), pFormCell );
+ }
+ }
+ else
+ {
+ pDoc->StartListeningArea( ScRange (
+ rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab,
+ rRef2.nCol,
+ rRef2.nRow,
+ rRef2.nTab ), pFormCell );
+ }
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ pFormCell->SetNeedsListening( FALSE);
+ }
+}
+
+// pArr gesetzt -> Referenzen von anderer Zelle nehmen
+// dann muss auch aPos uebergeben werden!
+
+void ScBaseCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
+ ScAddress aPos )
+{
+ if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
+ && !((ScFormulaCell*)this)->IsInChangeTrack()
+ )
+ {
+ pDoc->SetDetectiveDirty(TRUE); // es hat sich was geaendert...
+
+ ScFormulaCell* pFormCell = (ScFormulaCell*)this;
+ if( pFormCell->GetCode()->IsRecalcModeAlways() )
+ pDoc->EndListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
+ else
+ {
+ if (!pArr)
+ {
+ pArr = pFormCell->GetCode();
+ aPos = pFormCell->aPos;
+ }
+ pArr->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+ {
+ StackVar eType = t->GetType();
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ ScSingleRefData& rRef2 = (eType == svDoubleRef ?
+ t->GetDoubleRef().Ref2 : rRef1);
+ switch( eType )
+ {
+ case svSingleRef:
+ rRef1.CalcAbsIfRel( aPos );
+ if ( rRef1.Valid() )
+ {
+ pDoc->EndListeningCell(
+ ScAddress( rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab ), pFormCell );
+ }
+ break;
+ case svDoubleRef:
+ t->CalcAbsIfRel( aPos );
+ if ( rRef1.Valid() && rRef2.Valid() )
+ {
+ if ( t->GetOpCode() == ocColRowNameAuto )
+ { // automagically
+ if ( rRef1.IsColRel() )
+ { // ColName
+ pDoc->EndListeningArea( ScRange (
+ rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab,
+ rRef2.nCol,
+ MAXROW,
+ rRef2.nTab ), pFormCell );
+ }
+ else
+ { // RowName
+ pDoc->EndListeningArea( ScRange (
+ rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab,
+ MAXCOL,
+ rRef2.nRow,
+ rRef2.nTab ), pFormCell );
+ }
+ }
+ else
+ {
+ pDoc->EndListeningArea( ScRange (
+ rRef1.nCol,
+ rRef1.nRow,
+ rRef1.nTab,
+ rRef2.nCol,
+ rRef2.nRow,
+ rRef2.nTab ), pFormCell );
+ }
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ }
+}
+
+
+USHORT ScBaseCell::GetErrorCode() const
+{
+ switch ( eCellType )
+ {
+ case CELLTYPE_FORMULA :
+ return ((ScFormulaCell*)this)->GetErrCode();
+ default:
+ return 0;
+ }
+}
+
+
+BOOL ScBaseCell::HasEmptyData() const
+{
+ switch ( eCellType )
+ {
+ case CELLTYPE_NOTE :
+ return TRUE;
+ case CELLTYPE_FORMULA :
+ return ((ScFormulaCell*)this)->IsEmpty();
+ default:
+ return FALSE;
+ }
+}
+
+
+BOOL ScBaseCell::HasValueData() const
+{
+ switch ( eCellType )
+ {
+ case CELLTYPE_VALUE :
+ return TRUE;
+ case CELLTYPE_FORMULA :
+ return ((ScFormulaCell*)this)->IsValue();
+ default:
+ return FALSE;
+ }
+}
+
+
+BOOL ScBaseCell::HasStringData() const
+{
+ switch ( eCellType )
+ {
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ return TRUE;
+ case CELLTYPE_FORMULA :
+ return !((ScFormulaCell*)this)->IsValue();
+ default:
+ return FALSE;
+ }
+}
+
+String ScBaseCell::GetStringData() const
+{
+ String aStr;
+ switch ( eCellType )
+ {
+ case CELLTYPE_STRING:
+ ((const ScStringCell*)this)->GetString( aStr );
+ break;
+ case CELLTYPE_EDIT:
+ ((const ScEditCell*)this)->GetString( aStr );
+ break;
+ case CELLTYPE_FORMULA:
+ ((ScFormulaCell*)this)->GetString( aStr ); // an der Formelzelle nicht-const
+ break;
+ }
+ return aStr;
+}
+
+// static
+BOOL ScBaseCell::CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 )
+{
+ CellType eType1 = CELLTYPE_NONE;
+ CellType eType2 = CELLTYPE_NONE;
+ if ( pCell1 )
+ {
+ eType1 = pCell1->GetCellType();
+ if (eType1 == CELLTYPE_EDIT)
+ eType1 = CELLTYPE_STRING;
+ else if (eType1 == CELLTYPE_NOTE)
+ eType1 = CELLTYPE_NONE;
+ }
+ if ( pCell2 )
+ {
+ eType2 = pCell2->GetCellType();
+ if (eType2 == CELLTYPE_EDIT)
+ eType2 = CELLTYPE_STRING;
+ else if (eType2 == CELLTYPE_NOTE)
+ eType2 = CELLTYPE_NONE;
+ }
+ if ( eType1 != eType2 )
+ return FALSE;
+
+ switch ( eType1 ) // beide Typen gleich
+ {
+ case CELLTYPE_NONE: // beide leer
+ return TRUE;
+ case CELLTYPE_VALUE: // wirklich Value-Zellen
+ return ( ((const ScValueCell*)pCell1)->GetValue() ==
+ ((const ScValueCell*)pCell2)->GetValue() );
+ case CELLTYPE_STRING: // String oder Edit
+ {
+ String aText1;
+ if ( pCell1->GetCellType() == CELLTYPE_STRING )
+ ((const ScStringCell*)pCell1)->GetString(aText1);
+ else
+ ((const ScEditCell*)pCell1)->GetString(aText1);
+ String aText2;
+ if ( pCell2->GetCellType() == CELLTYPE_STRING )
+ ((const ScStringCell*)pCell2)->GetString(aText2);
+ else
+ ((const ScEditCell*)pCell2)->GetString(aText2);
+ return ( aText1 == aText2 );
+ }
+ case CELLTYPE_FORMULA:
+ {
+ //! eingefuegte Zeilen / Spalten beruecksichtigen !!!!!
+ //! Vergleichsfunktion an der Formelzelle ???
+ //! Abfrage mit ScColumn::SwapRow zusammenfassen!
+
+ ScTokenArray* pCode1 = ((ScFormulaCell*)pCell1)->GetCode();
+ ScTokenArray* pCode2 = ((ScFormulaCell*)pCell2)->GetCode();
+
+ if (pCode1->GetLen() == pCode2->GetLen()) // nicht-UPN
+ {
+ BOOL bEqual = TRUE;
+ USHORT nLen = pCode1->GetLen();
+ FormulaToken** ppToken1 = pCode1->GetArray();
+ FormulaToken** ppToken2 = pCode2->GetArray();
+ for (USHORT i=0; i<nLen; i++)
+ if ( !ppToken1[i]->TextEqual(*(ppToken2[i])) )
+ {
+ bEqual = FALSE;
+ break;
+ }
+
+ if (bEqual)
+ return TRUE;
+ }
+
+ return FALSE; // unterschiedlich lang oder unterschiedliche Tokens
+ }
+ default:
+ DBG_ERROR("huch, was fuer Zellen???");
+ }
+ return FALSE;
+}
+
+// ============================================================================
+
+ScNoteCell::ScNoteCell( SvtBroadcaster* pBC ) :
+ ScBaseCell( CELLTYPE_NOTE )
+{
+ TakeBroadcaster( pBC );
+}
+
+ScNoteCell::ScNoteCell( ScPostIt* pNote, SvtBroadcaster* pBC ) :
+ ScBaseCell( CELLTYPE_NOTE )
+{
+ TakeNote( pNote );
+ TakeBroadcaster( pBC );
+}
+
+#ifdef DBG_UTIL
+ScNoteCell::~ScNoteCell()
+{
+ eCellType = CELLTYPE_DESTROYED;
+}
+#endif
+
+// ============================================================================
+
+ScValueCell::ScValueCell() :
+ ScBaseCell( CELLTYPE_VALUE ),
+ mfValue( 0.0 )
+{
+}
+
+ScValueCell::ScValueCell( double fValue ) :
+ ScBaseCell( CELLTYPE_VALUE ),
+ mfValue( fValue )
+{
+}
+
+#ifdef DBG_UTIL
+ScValueCell::~ScValueCell()
+{
+ eCellType = CELLTYPE_DESTROYED;
+}
+#endif
+
+// ============================================================================
+
+ScStringCell::ScStringCell() :
+ ScBaseCell( CELLTYPE_STRING )
+{
+}
+
+ScStringCell::ScStringCell( const String& rString ) :
+ ScBaseCell( CELLTYPE_STRING ),
+ maString( rString.intern() )
+{
+}
+
+#ifdef DBG_UTIL
+ScStringCell::~ScStringCell()
+{
+ eCellType = CELLTYPE_DESTROYED;
+}
+#endif
+
+// ============================================================================
+
+//
+// ScFormulaCell
+//
+
+ScFormulaCell::ScFormulaCell() :
+ ScBaseCell( CELLTYPE_FORMULA ),
+ eTempGrammar( FormulaGrammar::GRAM_DEFAULT),
+ pCode( NULL ),
+ pDocument( NULL ),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nFormatIndex(0),
+ nFormatType( NUMBERFORMAT_NUMBER ),
+ nSeenInIteration(0),
+ cMatrixFlag ( MM_NONE ),
+ bDirty( FALSE ),
+ bChanged( FALSE ),
+ bRunning( FALSE ),
+ bCompile( FALSE ),
+ bSubTotal( FALSE ),
+ bIsIterCell( FALSE ),
+ bInChangeTrack( FALSE ),
+ bTableOpDirty( FALSE ),
+ bNeedListening( FALSE ),
+ aPos(0,0,0)
+{
+}
+
+ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
+ const String& rFormula,
+ const FormulaGrammar::Grammar eGrammar,
+ BYTE cMatInd ) :
+ ScBaseCell( CELLTYPE_FORMULA ),
+ eTempGrammar( eGrammar),
+ pCode( NULL ),
+ pDocument( pDoc ),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nFormatIndex(0),
+ nFormatType( NUMBERFORMAT_NUMBER ),
+ nSeenInIteration(0),
+ cMatrixFlag ( cMatInd ),
+ bDirty( TRUE ), // -> wg. Benutzung im Fkt.AutoPiloten, war: cMatInd != 0
+ bChanged( FALSE ),
+ bRunning( FALSE ),
+ bCompile( FALSE ),
+ bSubTotal( FALSE ),
+ bIsIterCell( FALSE ),
+ bInChangeTrack( FALSE ),
+ bTableOpDirty( FALSE ),
+ bNeedListening( FALSE ),
+ aPos( rPos )
+{
+ Compile( rFormula, TRUE, eGrammar ); // bNoListening, Insert does that
+}
+
+// Wird von den Importfiltern verwendet
+
+ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
+ const ScTokenArray* pArr,
+ const FormulaGrammar::Grammar eGrammar, BYTE cInd ) :
+ ScBaseCell( CELLTYPE_FORMULA ),
+ eTempGrammar( eGrammar),
+ pCode( pArr ? new ScTokenArray( *pArr ) : new ScTokenArray ),
+ pDocument( pDoc ),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nFormatIndex(0),
+ nFormatType( NUMBERFORMAT_NUMBER ),
+ nSeenInIteration(0),
+ cMatrixFlag ( cInd ),
+ bDirty( NULL != pArr ), // -> wg. Benutzung im Fkt.AutoPiloten, war: cInd != 0
+ bChanged( FALSE ),
+ bRunning( FALSE ),
+ bCompile( FALSE ),
+ bSubTotal( FALSE ),
+ bIsIterCell( FALSE ),
+ bInChangeTrack( FALSE ),
+ bTableOpDirty( FALSE ),
+ bNeedListening( FALSE ),
+ aPos( rPos )
+{
+ // UPN-Array erzeugen
+ if( pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen() )
+ {
+ ScCompiler aComp( pDocument, aPos, *pCode);
+ aComp.SetGrammar(eTempGrammar);
+ bSubTotal = aComp.CompileTokenArray();
+ nFormatType = aComp.GetNumFormatType();
+ }
+ else
+ {
+ pCode->Reset();
+ if ( pCode->GetNextOpCodeRPN( ocSubTotal ) )
+ bSubTotal = TRUE;
+ }
+}
+
+ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
+ ScBaseCell( rCell ),
+ SvtListener(),
+ aResult( rCell.aResult ),
+ eTempGrammar( rCell.eTempGrammar),
+ pDocument( &rDoc ),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nFormatIndex( &rDoc == rCell.pDocument ? rCell.nFormatIndex : 0 ),
+ nFormatType( rCell.nFormatType ),
+ nSeenInIteration(0),
+ cMatrixFlag ( rCell.cMatrixFlag ),
+ bDirty( rCell.bDirty ),
+ bChanged( rCell.bChanged ),
+ bRunning( FALSE ),
+ bCompile( rCell.bCompile ),
+ bSubTotal( rCell.bSubTotal ),
+ bIsIterCell( FALSE ),
+ bInChangeTrack( FALSE ),
+ bTableOpDirty( FALSE ),
+ bNeedListening( FALSE ),
+ aPos( rPos )
+{
+ pCode = rCell.pCode->Clone();
+
+ if ( nCloneFlags & SC_CLONECELL_ADJUST3DREL )
+ pCode->ReadjustRelative3DReferences( rCell.aPos, aPos );
+
+ // evtl. Fehler zuruecksetzen und neu kompilieren
+ // nicht im Clipboard - da muss das Fehlerflag erhalten bleiben
+ // Spezialfall Laenge=0: als Fehlerzelle erzeugt, dann auch Fehler behalten
+ if ( pCode->GetCodeError() && !pDocument->IsClipboard() && pCode->GetLen() )
+ {
+ pCode->SetCodeError( 0 );
+ bCompile = TRUE;
+ }
+ //! Compile ColRowNames on URM_MOVE/URM_COPY _after_ UpdateReference
+ BOOL bCompileLater = FALSE;
+ BOOL bClipMode = rCell.pDocument->IsClipboard();
+ if( !bCompile )
+ { // Name references with references and ColRowNames
+ pCode->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReferenceOrName()) ) != NULL && !bCompile )
+ {
+ if ( t->GetOpCode() == ocExternalRef )
+ {
+ // External name, cell, and area references.
+ bCompile = true;
+ }
+ else if ( t->GetType() == svIndex )
+ {
+ ScRangeData* pRangeData = rDoc.GetRangeName()->FindIndex( t->GetIndex() );
+ if( pRangeData )
+ {
+ if( pRangeData->HasReferences() )
+ bCompile = TRUE;
+ }
+ else
+ bCompile = TRUE; // invalid reference!
+ }
+ else if ( t->GetOpCode() == ocColRowName )
+ {
+ bCompile = TRUE; // new lookup needed
+ bCompileLater = bClipMode;
+ }
+ }
+ }
+ if( bCompile )
+ {
+ if ( !bCompileLater && bClipMode )
+ {
+ // Merging ranges needs the actual positions after UpdateReference.
+ // ColRowNames need new lookup after positions are adjusted.
+ bCompileLater = pCode->HasOpCode( ocRange) || pCode->HasOpCode( ocColRowName);
+ }
+ if ( !bCompileLater )
+ {
+ // bNoListening, not at all if in Clipboard/Undo,
+ // and not from Clipboard either, instead after Insert(Clone) and UpdateReference.
+ CompileTokenArray( TRUE );
+ }
+ }
+
+ if( nCloneFlags & SC_CLONECELL_STARTLISTENING )
+ StartListeningTo( &rDoc );
+}
+
+ScFormulaCell::~ScFormulaCell()
+{
+ pDocument->RemoveFromFormulaTree( this );
+
+ if (pDocument->HasExternalRefManager())
+ pDocument->GetExternalRefManager()->removeRefCell(this);
+
+ delete pCode;
+#ifdef DBG_UTIL
+ eCellType = CELLTYPE_DESTROYED;
+#endif
+}
+
+void ScFormulaCell::GetFormula( rtl::OUStringBuffer& rBuffer,
+ const FormulaGrammar::Grammar eGrammar ) const
+{
+ if( pCode->GetCodeError() && !pCode->GetLen() )
+ {
+ rBuffer = rtl::OUStringBuffer( ScGlobal::GetErrorString( pCode->GetCodeError()));
+ return;
+ }
+ else if( cMatrixFlag == MM_REFERENCE )
+ {
+ // Reference to another cell that contains a matrix formula.
+ pCode->Reset();
+ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if( p )
+ {
+ /* FIXME: original GetFormula() code obtained
+ * pCell only if (!this->IsInChangeTrack()),
+ * GetEnglishFormula() omitted that test.
+ * Can we live without in all cases? */
+ ScBaseCell* pCell;
+ ScSingleRefData& rRef = p->GetSingleRef();
+ rRef.CalcAbsIfRel( aPos );
+ if ( rRef.Valid() )
+ pCell = pDocument->GetCell( ScAddress( rRef.nCol,
+ rRef.nRow, rRef.nTab ) );
+ else
+ pCell = NULL;
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ((ScFormulaCell*)pCell)->GetFormula( rBuffer, eGrammar);
+ return;
+ }
+ else
+ {
+ ScCompiler aComp( pDocument, aPos, *pCode);
+ aComp.SetGrammar(eGrammar);
+ aComp.CreateStringFromTokenArray( rBuffer );
+ }
+ }
+ else
+ {
+ DBG_ERROR("ScFormulaCell::GetFormula: not a matrix");
+ }
+ }
+ else
+ {
+ ScCompiler aComp( pDocument, aPos, *pCode);
+ aComp.SetGrammar(eGrammar);
+ aComp.CreateStringFromTokenArray( rBuffer );
+ }
+
+ sal_Unicode ch('=');
+ rBuffer.insert( 0, &ch, 1 );
+ if( cMatrixFlag )
+ {
+ sal_Unicode ch2('{');
+ rBuffer.insert( 0, &ch2, 1);
+ rBuffer.append( sal_Unicode('}'));
+ }
+}
+
+void ScFormulaCell::GetFormula( String& rFormula, const FormulaGrammar::Grammar eGrammar ) const
+{
+ rtl::OUStringBuffer rBuffer( rFormula );
+ GetFormula( rBuffer, eGrammar );
+ rFormula = rBuffer;
+}
+
+void ScFormulaCell::GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows )
+{
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+
+ const ScMatrix* pMat = NULL;
+ if (!pCode->GetCodeError() && aResult.GetType() == svMatrixCell &&
+ ((pMat = static_cast<const ScToken*>(aResult.GetToken().get())->GetMatrix()) != 0))
+ pMat->GetDimensions( rCols, rRows );
+ else
+ {
+ rCols = 0;
+ rRows = 0;
+ }
+}
+
+void ScFormulaCell::Compile( const String& rFormula, BOOL bNoListening,
+ const FormulaGrammar::Grammar eGrammar )
+{
+ if ( pDocument->IsClipOrUndo() ) return;
+ BOOL bWasInFormulaTree = pDocument->IsInFormulaTree( this );
+ if ( bWasInFormulaTree )
+ pDocument->RemoveFromFormulaTree( this );
+ // pCode darf fuer Abfragen noch nicht geloescht, muss aber leer sein
+ if ( pCode )
+ pCode->Clear();
+ ScTokenArray* pCodeOld = pCode;
+ ScCompiler aComp( pDocument, aPos);
+ aComp.SetGrammar(eGrammar);
+ pCode = aComp.CompileString( rFormula );
+ if ( pCodeOld )
+ delete pCodeOld;
+ if( !pCode->GetCodeError() )
+ {
+ if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() && rFormula == aResult.GetHybridFormula() )
+ { // #65994# nicht rekursiv CompileTokenArray/Compile/CompileTokenArray
+ if ( rFormula.GetChar(0) == '=' )
+ pCode->AddBad( rFormula.GetBuffer() + 1 );
+ else
+ pCode->AddBad( rFormula.GetBuffer() );
+ }
+ bCompile = TRUE;
+ CompileTokenArray( bNoListening );
+ }
+ else
+ {
+ bChanged = TRUE;
+ SetTextWidth( TEXTWIDTH_DIRTY );
+ SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+ }
+ if ( bWasInFormulaTree )
+ pDocument->PutInFormulaTree( this );
+}
+
+
+void ScFormulaCell::CompileTokenArray( BOOL bNoListening )
+{
+ // Not already compiled?
+ if( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar);
+ else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() )
+ {
+ // RPN length may get changed
+ BOOL bWasInFormulaTree = pDocument->IsInFormulaTree( this );
+ if ( bWasInFormulaTree )
+ pDocument->RemoveFromFormulaTree( this );
+
+ // Loading from within filter? No listening yet!
+ if( pDocument->IsInsertingFromOtherDoc() )
+ bNoListening = TRUE;
+
+ if( !bNoListening && pCode->GetCodeLen() )
+ EndListeningTo( pDocument );
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ bSubTotal = aComp.CompileTokenArray();
+ if( !pCode->GetCodeError() )
+ {
+ nFormatType = aComp.GetNumFormatType();
+ nFormatIndex = 0;
+ bChanged = TRUE;
+ aResult.SetToken( NULL);
+ bCompile = FALSE;
+ if ( !bNoListening )
+ StartListeningTo( pDocument );
+ }
+ if ( bWasInFormulaTree )
+ pDocument->PutInFormulaTree( this );
+ }
+}
+
+
+void ScFormulaCell::CompileXML( ScProgress& rProgress )
+{
+ if ( cMatrixFlag == MM_REFERENCE )
+ { // is already token code via ScDocFunc::EnterMatrix, ScDocument::InsertMatrixFormula
+ // just establish listeners
+ StartListeningTo( pDocument );
+ return ;
+ }
+
+ ScCompiler aComp( pDocument, aPos, *pCode);
+ aComp.SetGrammar(eTempGrammar);
+ 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, aFormulaNmsp );
+ delete pCodeOld;
+ if( !pCode->GetCodeError() )
+ {
+ if ( !pCode->GetLen() )
+ {
+ if ( aFormula.GetChar(0) == '=' )
+ pCode->AddBad( aFormula.GetBuffer() + 1 );
+ else
+ pCode->AddBad( aFormula.GetBuffer() );
+ }
+ bSubTotal = aComp.CompileTokenArray();
+ if( !pCode->GetCodeError() )
+ {
+ nFormatType = aComp.GetNumFormatType();
+ nFormatIndex = 0;
+ bChanged = TRUE;
+ bCompile = FALSE;
+ StartListeningTo( pDocument );
+ }
+ }
+ else
+ {
+ bChanged = TRUE;
+ SetTextWidth( TEXTWIDTH_DIRTY );
+ SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+ }
+
+ // Same as in Load: after loading, it must be known if ocMacro is in any formula
+ // (for macro warning, CompileXML is called at the end of loading XML file)
+ if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) )
+ pDocument->SetHasMacroFunc( TRUE );
+}
+
+
+void ScFormulaCell::CalcAfterLoad()
+{
+ BOOL bNewCompiled = FALSE;
+ // Falls ein Calc 1.0-Doc eingelesen wird, haben wir ein Ergebnis,
+ // aber kein TokenArray
+ if( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ {
+ Compile( aResult.GetHybridFormula(), TRUE, eTempGrammar);
+ aResult.SetToken( NULL);
+ bDirty = TRUE;
+ bNewCompiled = TRUE;
+ }
+ // Das UPN-Array wird nicht erzeugt, wenn ein Calc 3.0-Doc eingelesen
+ // wurde, da die RangeNames erst jetzt existieren.
+ if( pCode->GetLen() && !pCode->GetCodeLen() && !pCode->GetCodeError() )
+ {
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ bSubTotal = aComp.CompileTokenArray();
+ nFormatType = aComp.GetNumFormatType();
+ nFormatIndex = 0;
+ bDirty = TRUE;
+ bCompile = FALSE;
+ bNewCompiled = TRUE;
+ }
+ // irgendwie koennen unter os/2 mit rotter FPU-Exception /0 ohne Err503
+ // gespeichert werden, woraufhin spaeter im NumberFormatter die BLC Lib
+ // bei einem fabs(-NAN) abstuerzt (#32739#)
+ // hier fuer alle Systeme ausbuegeln, damit da auch Err503 steht
+ if ( aResult.IsValue() && !::rtl::math::isFinite( aResult.GetDouble() ) )
+ {
+ DBG_ERRORFILE("Formelzelle INFINITY !!! Woher kommt das Dokument?");
+ aResult.SetResultError( errIllegalFPOperation );
+ bDirty = TRUE;
+ }
+ // DoubleRefs bei binaeren Operatoren waren vor v5.0 immer Matrix,
+ // jetzt nur noch wenn in Matrixformel, sonst implizite Schnittmenge
+ if ( pDocument->GetSrcVersion() < SC_MATRIX_DOUBLEREF &&
+ GetMatrixFlag() == MM_NONE && pCode->HasMatrixDoubleRefOps() )
+ {
+ cMatrixFlag = MM_FORMULA;
+ SetMatColsRows( 1, 1);
+ }
+ // Muss die Zelle berechnet werden?
+ // Nach Load koennen Zellen einen Fehlercode enthalten, auch dann
+ // Listener starten und ggbf. neu berechnen wenn nicht RECALCMODE_NORMAL
+ if( !bNewCompiled || !pCode->GetCodeError() )
+ {
+ StartListeningTo( pDocument );
+ if( !pCode->IsRecalcModeNormal() )
+ bDirty = TRUE;
+ }
+ if ( pCode->IsRecalcModeAlways() )
+ { // zufall(), heute(), jetzt() bleiben immer im FormulaTree, damit sie
+ // auch bei jedem F9 berechnet werden.
+ bDirty = TRUE;
+ }
+ // Noch kein SetDirty weil noch nicht alle Listener bekannt, erst in
+ // SetDirtyAfterLoad.
+}
+
+
+bool ScFormulaCell::MarkUsedExternalReferences()
+{
+ return pCode && pDocument->MarkUsedExternalReferences( *pCode);
+}
+
+
+// FIXME: set to 0
+#define erDEBUGDOT 0
+// If set to 1, write output that's suitable for graphviz tools like dot.
+// Only node1 -> node2 entries are written, you'll have to manually surround
+// the file content with [strict] digraph name { ... }
+// The ``strict'' keyword might be necessary in case of multiple identical
+// paths like they occur in iterations, otherwise dot may consume too much
+// memory when generating the layout, or you'll get unreadable output. On the
+// other hand, information about recurring calculation is lost then.
+// Generates output only if variable nDebug is set in debugger, see below.
+// FIXME: currently doesn't cope with iterations and recursions. Code fragments
+// are a leftover from a previous debug session, meant as a pointer.
+#if erDEBUGDOT
+#include <cstdio>
+using ::std::fopen;
+using ::std::fprintf;
+#include <vector>
+static const char aDebugDotFile[] = "ttt_debug.dot";
+#endif
+
+void ScFormulaCell::Interpret()
+{
+
+#if erDEBUGDOT
+ static int nDebug = 0;
+ static const int erDEBUGDOTRUN = 3;
+ static FILE* pDebugFile = 0;
+ static sal_Int32 nDebugRootCount = 0;
+ static unsigned int nDebugPathCount = 0;
+ static ScAddress aDebugLastPos( ScAddress::INITIALIZE_INVALID);
+ static ScAddress aDebugThisPos( ScAddress::INITIALIZE_INVALID);
+ typedef ::std::vector< ByteString > DebugVector;
+ static DebugVector aDebugVec;
+ class DebugElement
+ {
+ public:
+ static void push( ScFormulaCell* pCell )
+ {
+ aDebugThisPos = pCell->aPos;
+ if (aDebugVec.empty())
+ {
+ ByteString aR( "root_");
+ aR += ByteString::CreateFromInt32( ++nDebugRootCount);
+ aDebugVec.push_back( aR);
+ }
+ String aStr;
+ pCell->aPos.Format( aStr, SCA_VALID | SCA_TAB_3D, pCell->GetDocument(),
+ pCell->GetDocument()->GetAddressConvention() );
+ ByteString aB( aStr, RTL_TEXTENCODING_UTF8);
+ aDebugVec.push_back( aB);
+ }
+ static void pop()
+ {
+ aDebugLastPos = aDebugThisPos;
+ if (!aDebugVec.empty())
+ {
+ aDebugVec.pop_back();
+ if (aDebugVec.size() == 1)
+ {
+ aDebugVec.pop_back();
+ aDebugLastPos = ScAddress( ScAddress::INITIALIZE_INVALID);
+ }
+ }
+ }
+ DebugElement( ScFormulaCell* p ) { push(p); }
+ ~DebugElement() { pop(); }
+ };
+ class DebugDot
+ {
+ public:
+ static void out( const char* pColor )
+ {
+ if (nDebug != erDEBUGDOTRUN)
+ return;
+ char pColorString[256];
+ sprintf( pColorString, (*pColor ?
+ ",color=\"%s\",fontcolor=\"%s\"" : "%s%s"), pColor,
+ pColor);
+ size_t n = aDebugVec.size();
+ fprintf( pDebugFile,
+ "\"%s\" -> \"%s\" [label=\"%u\"%s]; // v:%d\n",
+ aDebugVec[n-2].GetBuffer(), aDebugVec[n-1].GetBuffer(),
+ ++nDebugPathCount, pColorString, n-1);
+ fflush( pDebugFile);
+ }
+ };
+ #define erDEBUGDOT_OUT( p ) (DebugDot::out(p))
+ #define erDEBUGDOT_ELEMENT_PUSH( p ) (DebugElement::push(p))
+ #define erDEBUGDOT_ELEMENT_POP() (DebugElement::pop())
+#else
+ #define erDEBUGDOT_OUT( p )
+ #define erDEBUGDOT_ELEMENT_PUSH( p )
+ #define erDEBUGDOT_ELEMENT_POP()
+#endif
+
+ if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn())
+ return; // no double/triple processing
+
+ //! HACK:
+ // Wenn der Aufruf aus einem Reschedule im DdeLink-Update kommt, dirty stehenlassen
+ // Besser: Dde-Link Update ohne Reschedule oder ganz asynchron !!!
+
+ if ( pDocument->IsInDdeLinkUpdate() )
+ return;
+
+#if erDEBUGDOT
+ // set nDebug=1 in debugger to init things
+ if (nDebug == 1)
+ {
+ ++nDebug;
+ pDebugFile = fopen( aDebugDotFile, "a");
+ if (!pDebugFile)
+ nDebug = 0;
+ else
+ nDebug = erDEBUGDOTRUN;
+ }
+ // set nDebug=3 (erDEBUGDOTRUN) in debugger to get any output
+ DebugElement aDebugElem( this);
+ // set nDebug=5 in debugger to close output
+ if (nDebug == 5)
+ {
+ nDebug = 0;
+ fclose( pDebugFile);
+ pDebugFile = 0;
+ }
+#endif
+
+ if (bRunning)
+ {
+
+#if erDEBUGDOT
+ if (!pDocument->GetRecursionHelper().IsDoingIteration() ||
+ aDebugThisPos != aDebugLastPos)
+ erDEBUGDOT_OUT(aDebugThisPos == aDebugLastPos ? "orange" :
+ (pDocument->GetRecursionHelper().GetIteration() ? "blue" :
+ "red"));
+#endif
+
+ if (!pDocument->GetDocOptions().IsIter())
+ {
+ aResult.SetResultError( errCircularReference );
+ return;
+ }
+
+ if (aResult.GetResultError() == errCircularReference)
+ aResult.SetResultError( 0 );
+
+ // Start or add to iteration list.
+ if (!pDocument->GetRecursionHelper().IsDoingIteration() ||
+ !pDocument->GetRecursionHelper().GetRecursionInIterationStack().top()->bIsIterCell)
+ pDocument->GetRecursionHelper().SetInIterationReturn( true);
+
+ return;
+ }
+ // #63038# no multiple interprets for GetErrCode, IsValue, GetValue and
+ // different entry point recursions. Would also lead to premature
+ // convergence in iterations.
+ if (pDocument->GetRecursionHelper().GetIteration() && nSeenInIteration ==
+ pDocument->GetRecursionHelper().GetIteration())
+ return ;
+
+ erDEBUGDOT_OUT( pDocument->GetRecursionHelper().GetIteration() ? "magenta" : "");
+
+ ScRecursionHelper& rRecursionHelper = pDocument->GetRecursionHelper();
+ BOOL bOldRunning = bRunning;
+ if (rRecursionHelper.GetRecursionCount() > MAXRECURSION)
+ {
+ bRunning = TRUE;
+ rRecursionHelper.SetInRecursionReturn( true);
+ }
+ else
+ {
+ InterpretTail( SCITP_NORMAL);
+ }
+
+ // While leaving a recursion or iteration stack, insert its cells to the
+ // recursion list in reverse order.
+ if (rRecursionHelper.IsInReturn())
+ {
+ if (rRecursionHelper.GetRecursionCount() > 0 ||
+ !rRecursionHelper.IsDoingRecursion())
+ rRecursionHelper.Insert( this, bOldRunning, aResult);
+ bool bIterationFromRecursion = false;
+ bool bResumeIteration = false;
+ do
+ {
+ if ((rRecursionHelper.IsInIterationReturn() &&
+ rRecursionHelper.GetRecursionCount() == 0 &&
+ !rRecursionHelper.IsDoingIteration()) ||
+ bIterationFromRecursion || bResumeIteration)
+ {
+ ScFormulaCell* pIterCell = this; // scope for debug convenience
+ bool & rDone = rRecursionHelper.GetConvergingReference();
+ rDone = false;
+ if (!bIterationFromRecursion && bResumeIteration)
+ {
+ bResumeIteration = false;
+ // Resuming iteration expands the range.
+ ScFormulaRecursionList::const_iterator aOldStart(
+ rRecursionHelper.GetLastIterationStart());
+ rRecursionHelper.ResumeIteration();
+ // Mark new cells being in iteration.
+ for (ScFormulaRecursionList::const_iterator aIter(
+ rRecursionHelper.GetIterationStart()); aIter !=
+ aOldStart; ++aIter)
+ {
+ pIterCell = (*aIter).pCell;
+ pIterCell->bIsIterCell = TRUE;
+ }
+ // Mark older cells dirty again, in case they converted
+ // without accounting for all remaining cells in the circle
+ // that weren't touched so far, e.g. conditional. Restore
+ // backuped result.
+ USHORT nIteration = rRecursionHelper.GetIteration();
+ for (ScFormulaRecursionList::const_iterator aIter(
+ aOldStart); aIter !=
+ rRecursionHelper.GetIterationEnd(); ++aIter)
+ {
+ pIterCell = (*aIter).pCell;
+ if (pIterCell->nSeenInIteration == nIteration)
+ {
+ if (!pIterCell->bDirty || aIter == aOldStart)
+ {
+ pIterCell->aResult = (*aIter).aPreviousResult;
+ }
+ --pIterCell->nSeenInIteration;
+ }
+ pIterCell->bDirty = TRUE;
+ }
+ }
+ else
+ {
+ bResumeIteration = false;
+ // Close circle once.
+ rRecursionHelper.GetList().back().pCell->InterpretTail(
+ SCITP_CLOSE_ITERATION_CIRCLE);
+ // Start at 1, init things.
+ rRecursionHelper.StartIteration();
+ // Mark all cells being in iteration.
+ for (ScFormulaRecursionList::const_iterator aIter(
+ rRecursionHelper.GetIterationStart()); aIter !=
+ rRecursionHelper.GetIterationEnd(); ++aIter)
+ {
+ pIterCell = (*aIter).pCell;
+ pIterCell->bIsIterCell = TRUE;
+ }
+ }
+ bIterationFromRecursion = false;
+ USHORT nIterMax = pDocument->GetDocOptions().GetIterCount();
+ for ( ; rRecursionHelper.GetIteration() <= nIterMax && !rDone;
+ rRecursionHelper.IncIteration())
+ {
+ rDone = true;
+ for ( ScFormulaRecursionList::iterator aIter(
+ rRecursionHelper.GetIterationStart()); aIter !=
+ rRecursionHelper.GetIterationEnd() &&
+ !rRecursionHelper.IsInReturn(); ++aIter)
+ {
+ pIterCell = (*aIter).pCell;
+ if (pIterCell->IsDirtyOrInTableOpDirty() &&
+ rRecursionHelper.GetIteration() !=
+ pIterCell->GetSeenInIteration())
+ {
+ (*aIter).aPreviousResult = pIterCell->aResult;
+ pIterCell->InterpretTail( SCITP_FROM_ITERATION);
+ }
+ rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty();
+ }
+ if (rRecursionHelper.IsInReturn())
+ {
+ bResumeIteration = true;
+ break; // for
+ // Don't increment iteration.
+ }
+ }
+ if (!bResumeIteration)
+ {
+ if (rDone)
+ {
+ for (ScFormulaRecursionList::const_iterator aIter(
+ rRecursionHelper.GetIterationStart());
+ aIter != rRecursionHelper.GetIterationEnd();
+ ++aIter)
+ {
+ pIterCell = (*aIter).pCell;
+ pIterCell->bIsIterCell = FALSE;
+ pIterCell->nSeenInIteration = 0;
+ pIterCell->bRunning = (*aIter).bOldRunning;
+ }
+ }
+ else
+ {
+ for (ScFormulaRecursionList::const_iterator aIter(
+ rRecursionHelper.GetIterationStart());
+ aIter != rRecursionHelper.GetIterationEnd();
+ ++aIter)
+ {
+ pIterCell = (*aIter).pCell;
+ pIterCell->bIsIterCell = FALSE;
+ pIterCell->nSeenInIteration = 0;
+ pIterCell->bRunning = (*aIter).bOldRunning;
+ // If one cell didn't converge, all cells of this
+ // circular dependency don't, no matter whether
+ // single cells did.
+ pIterCell->bDirty = FALSE;
+ pIterCell->bTableOpDirty = FALSE;
+ pIterCell->aResult.SetResultError( errNoConvergence);
+ pIterCell->bChanged = TRUE;
+ pIterCell->SetTextWidth( TEXTWIDTH_DIRTY);
+ pIterCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN);
+ }
+ }
+ // End this iteration and remove entries.
+ rRecursionHelper.EndIteration();
+ bResumeIteration = rRecursionHelper.IsDoingIteration();
+ }
+ }
+ if (rRecursionHelper.IsInRecursionReturn() &&
+ rRecursionHelper.GetRecursionCount() == 0 &&
+ !rRecursionHelper.IsDoingRecursion())
+ {
+ bIterationFromRecursion = false;
+ // Iterate over cells known so far, start with the last cell
+ // encountered, inserting new cells if another recursion limit
+ // is reached. Repeat until solved.
+ rRecursionHelper.SetDoingRecursion( true);
+ do
+ {
+ rRecursionHelper.SetInRecursionReturn( false);
+ for (ScFormulaRecursionList::const_iterator aIter(
+ rRecursionHelper.GetStart());
+ !rRecursionHelper.IsInReturn() && aIter !=
+ rRecursionHelper.GetEnd(); ++aIter)
+ {
+ ScFormulaCell* pCell = (*aIter).pCell;
+ if (pCell->IsDirtyOrInTableOpDirty())
+ {
+ pCell->InterpretTail( SCITP_NORMAL);
+ if (!pCell->IsDirtyOrInTableOpDirty() && !pCell->IsIterCell())
+ pCell->bRunning = (*aIter).bOldRunning;
+ }
+ }
+ } while (rRecursionHelper.IsInRecursionReturn());
+ rRecursionHelper.SetDoingRecursion( false);
+ if (rRecursionHelper.IsInIterationReturn())
+ {
+ if (!bResumeIteration)
+ bIterationFromRecursion = true;
+ }
+ else if (bResumeIteration ||
+ rRecursionHelper.IsDoingIteration())
+ rRecursionHelper.GetList().erase(
+ rRecursionHelper.GetStart(),
+ rRecursionHelper.GetLastIterationStart());
+ else
+ rRecursionHelper.Clear();
+ }
+ } while (bIterationFromRecursion || bResumeIteration);
+ }
+}
+
+void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
+{
+ class RecursionCounter
+ {
+ ScRecursionHelper& rRec;
+ bool bStackedInIteration;
+ public:
+ RecursionCounter( ScRecursionHelper& r, ScFormulaCell* p ) : rRec(r)
+ {
+ bStackedInIteration = rRec.IsDoingIteration();
+ if (bStackedInIteration)
+ rRec.GetRecursionInIterationStack().push( p);
+ rRec.IncRecursionCount();
+ }
+ ~RecursionCounter()
+ {
+ rRec.DecRecursionCount();
+ if (bStackedInIteration)
+ rRec.GetRecursionInIterationStack().pop();
+ }
+ } aRecursionCounter( pDocument->GetRecursionHelper(), this);
+ nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();
+ if( !pCode->GetCodeLen() && !pCode->GetCodeError() )
+ {
+ // #i11719# no UPN and no error and no token code but result string present
+ // => interpretation of this cell during name-compilation and unknown names
+ // => can't exchange underlying code array in CompileTokenArray() /
+ // Compile() because interpreter's token iterator would crash.
+ // This should only be a temporary condition and, since we set an
+ // error, if ran into it again we'd bump into the dirty-clearing
+ // condition further down.
+ if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ {
+ pCode->SetCodeError( errNoCode );
+ // This is worth an assertion; if encountered in daily work
+ // documents we might need another solution. Or just confirm correctness.
+ DBG_ERRORFILE( "ScFormulaCell::Interpret: no UPN, no error, no token, but string" );
+ return;
+ }
+ CompileTokenArray();
+ }
+
+ if( pCode->GetCodeLen() && pDocument )
+ {
+ class StackCleaner
+ {
+ ScDocument* pDoc;
+ ScInterpreter* pInt;
+ public:
+ StackCleaner( ScDocument* pD, ScInterpreter* pI )
+ : pDoc(pD), pInt(pI)
+ {}
+ ~StackCleaner()
+ {
+ delete pInt;
+ pDoc->DecInterpretLevel();
+ }
+ };
+ pDocument->IncInterpretLevel();
+ ScInterpreter* p = new ScInterpreter( this, pDocument, aPos, *pCode );
+ StackCleaner aStackCleaner( pDocument, p);
+ USHORT nOldErrCode = aResult.GetResultError();
+ if ( nSeenInIteration == 0 )
+ { // Only the first time
+ // With bChanged=FALSE, if a newly compiled cell has a result of
+ // 0.0, no change is detected and the cell will not be repainted.
+ // bChanged = FALSE;
+ aResult.SetResultError( 0 );
+ }
+
+ switch ( aResult.GetResultError() )
+ {
+ case errCircularReference : // will be determined again if so
+ aResult.SetResultError( 0 );
+ break;
+ }
+
+ BOOL bOldRunning = bRunning;
+ bRunning = TRUE;
+ p->Interpret();
+ if (pDocument->GetRecursionHelper().IsInReturn() && eTailParam != SCITP_CLOSE_ITERATION_CIRCLE)
+ {
+ if (nSeenInIteration > 0)
+ --nSeenInIteration; // retry when iteration is resumed
+ return;
+ }
+ bRunning = bOldRunning;
+
+ // #i102616# For single-sheet saving consider only content changes, not format type,
+ // because format type isn't set on loading (might be changed later)
+ BOOL bContentChanged = FALSE;
+
+ // Do not create a HyperLink() cell if the formula results in an error.
+ if( p->GetError() && pCode->IsHyperLink())
+ pCode->SetHyperLink(FALSE);
+
+ if( p->GetError() && p->GetError() != errCircularReference)
+ {
+ bDirty = FALSE;
+ bTableOpDirty = FALSE;
+ bChanged = TRUE;
+ }
+ if (eTailParam == SCITP_FROM_ITERATION && IsDirtyOrInTableOpDirty())
+ {
+ bool bIsValue = aResult.IsValue(); // the previous type
+ // Did it converge?
+ if ((bIsValue && p->GetResultType() == svDouble && fabs(
+ p->GetNumResult() - aResult.GetDouble()) <=
+ pDocument->GetDocOptions().GetIterEps()) ||
+ (!bIsValue && p->GetResultType() == svString &&
+ p->GetStringResult() == aResult.GetString()))
+ {
+ // A convergence in the first iteration doesn't necessarily
+ // mean that it's done, it may be because not all related cells
+ // of a circle changed their values yet. If the set really
+ // converges it will do so also during the next iteration. This
+ // fixes situations like of #i44115#. If this wasn't wanted an
+ // initial "uncalculated" value would be needed for all cells
+ // of a circular dependency => graph needed before calculation.
+ if (nSeenInIteration > 1 ||
+ pDocument->GetDocOptions().GetIterCount() == 1)
+ {
+ bDirty = FALSE;
+ bTableOpDirty = FALSE;
+ }
+ }
+ }
+
+ // New error code?
+ if( p->GetError() != nOldErrCode )
+ {
+ bChanged = TRUE;
+ // bContentChanged only has to be set if the file content would be changed
+ if ( aResult.GetCellResultType() != svUnknown )
+ bContentChanged = TRUE;
+ }
+ // Different number format?
+ if( nFormatType != p->GetRetFormatType() )
+ {
+ nFormatType = p->GetRetFormatType();
+ bChanged = TRUE;
+ }
+ if( nFormatIndex != p->GetRetFormatIndex() )
+ {
+ nFormatIndex = p->GetRetFormatIndex();
+ bChanged = TRUE;
+ }
+
+ // In case of changes just obtain the result, no temporary and
+ // comparison needed anymore.
+ if (bChanged)
+ {
+ // #i102616# Compare anyway if the sheet is still marked unchanged for single-sheet saving
+ // Also handle special cases of initial results after loading.
+
+ if ( !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
+ {
+ ScFormulaResult aNewResult( p->GetResultToken());
+ StackVar eOld = aResult.GetCellResultType();
+ StackVar eNew = aNewResult.GetCellResultType();
+ if ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) )
+ {
+ // ScXMLTableRowCellContext::EndElement doesn't call SetFormulaResultDouble for 0
+ // -> no change
+ }
+ else
+ {
+ if ( eOld == svHybridCell ) // string result from SetFormulaResultString?
+ eOld = svString; // ScHybridCellToken has a valid GetString method
+
+ // #i106045# use approxEqual to compare with stored value
+ bContentChanged = (eOld != eNew ||
+ (eNew == svDouble && !rtl::math::approxEqual( aResult.GetDouble(), aNewResult.GetDouble() )) ||
+ (eNew == svString && aResult.GetString() != aNewResult.GetString()));
+ }
+ }
+
+ aResult.SetToken( p->GetResultToken() );
+ }
+ else
+ {
+ ScFormulaResult aNewResult( p->GetResultToken());
+ StackVar eOld = aResult.GetCellResultType();
+ StackVar eNew = aNewResult.GetCellResultType();
+ bChanged = (eOld != eNew ||
+ (eNew == svDouble && aResult.GetDouble() != aNewResult.GetDouble()) ||
+ (eNew == svString && aResult.GetString() != aNewResult.GetString()));
+
+ // #i102616# handle special cases of initial results after loading (only if the sheet is still marked unchanged)
+ if ( bChanged && !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
+ {
+ if ( ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) ) ||
+ ( eOld == svHybridCell && eNew == svString && aResult.GetString() == aNewResult.GetString() ) ||
+ ( eOld == svDouble && eNew == svDouble && rtl::math::approxEqual( aResult.GetDouble(), aNewResult.GetDouble() ) ) )
+ {
+ // no change, see above
+ }
+ else
+ bContentChanged = TRUE;
+ }
+
+ aResult.Assign( aNewResult);
+ }
+
+ // Precision as shown?
+ if ( aResult.IsValue() && !p->GetError()
+ && pDocument->GetDocOptions().IsCalcAsShown()
+ && nFormatType != NUMBERFORMAT_DATE
+ && nFormatType != NUMBERFORMAT_TIME
+ && nFormatType != NUMBERFORMAT_DATETIME )
+ {
+ ULONG nFormat = pDocument->GetNumberFormat( aPos );
+ if ( nFormatIndex && (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nFormat = nFormatIndex;
+ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nFormat = ScGlobal::GetStandardFormat(
+ *pDocument->GetFormatTable(), nFormat, nFormatType );
+ aResult.SetDouble( pDocument->RoundValueAsShown(
+ aResult.GetDouble(), nFormat));
+ }
+ if (eTailParam == SCITP_NORMAL)
+ {
+ bDirty = FALSE;
+ bTableOpDirty = FALSE;
+ }
+ if( aResult.GetMatrix().Is() )
+ {
+ // If the formula wasn't entered as a matrix formula, live on with
+ // the upper left corner and let reference counting delete the matrix.
+ if( cMatrixFlag != MM_FORMULA && !pCode->IsHyperLink() )
+ aResult.SetToken( aResult.GetCellResultToken());
+ }
+ if ( aResult.IsValue() && !::rtl::math::isFinite( aResult.GetDouble() ) )
+ {
+ // Coded double error may occur via filter import.
+ USHORT nErr = GetDoubleErrorValue( aResult.GetDouble());
+ aResult.SetResultError( nErr);
+ bChanged = bContentChanged = true;
+ }
+ if( bChanged )
+ {
+ SetTextWidth( TEXTWIDTH_DIRTY );
+ SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+ }
+ if (bContentChanged && pDocument->IsStreamValid(aPos.Tab()))
+ {
+ // pass bIgnoreLock=TRUE, because even if called from pending row height update,
+ // a changed result must still reset the stream flag
+ pDocument->SetStreamValid(aPos.Tab(), FALSE, TRUE);
+ }
+ if ( !pCode->IsRecalcModeAlways() )
+ pDocument->RemoveFromFormulaTree( this );
+
+ // FORCED Zellen auch sofort auf Gueltigkeit testen (evtl. Makro starten)
+
+ if ( pCode->IsRecalcModeForced() )
+ {
+ ULONG nValidation = ((const SfxUInt32Item*) pDocument->GetAttr(
+ aPos.Col(), aPos.Row(), aPos.Tab(), ATTR_VALIDDATA ))->GetValue();
+ if ( nValidation )
+ {
+ const ScValidationData* pData = pDocument->GetValidationEntry( nValidation );
+ if ( pData && !pData->IsDataValid( this, aPos ) )
+ pData->DoCalcError( this );
+ }
+ }
+
+ // Reschedule verlangsamt das ganze erheblich, nur bei Prozentaenderung ausfuehren
+ ScProgress::GetInterpretProgress()->SetStateCountDownOnPercent(
+ pDocument->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE );
+ }
+ else
+ {
+ // Zelle bei Compiler-Fehlern nicht ewig auf dirty stehenlassen
+ DBG_ASSERT( pCode->GetCodeError(), "kein UPN-Code und kein Fehler ?!?!" );
+ bDirty = FALSE;
+ bTableOpDirty = FALSE;
+ }
+}
+
+
+void ScFormulaCell::SetMatColsRows( SCCOL nCols, SCROW nRows )
+{
+ ScMatrixFormulaCellToken* pMat = aResult.GetMatrixFormulaCellTokenNonConst();
+ if (pMat)
+ pMat->SetMatColsRows( nCols, nRows);
+ else if (nCols || nRows)
+ aResult.SetToken( new ScMatrixFormulaCellToken( nCols, nRows));
+}
+
+
+void ScFormulaCell::GetMatColsRows( SCCOL & nCols, SCROW & nRows ) const
+{
+ const ScMatrixFormulaCellToken* pMat = aResult.GetMatrixFormulaCellToken();
+ if (pMat)
+ pMat->GetMatColsRows( nCols, nRows);
+ else
+ {
+ nCols = 0;
+ nRows = 0;
+ }
+}
+
+
+ULONG ScFormulaCell::GetStandardFormat( SvNumberFormatter& rFormatter, ULONG nFormat ) const
+{
+ if ( nFormatIndex && (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ return nFormatIndex;
+ //! not ScFormulaCell::IsValue(), that could reinterpret the formula again.
+ if ( aResult.IsValue() )
+ return ScGlobal::GetStandardFormat( aResult.GetDouble(), rFormatter, nFormat, nFormatType );
+ else
+ return ScGlobal::GetStandardFormat( rFormatter, nFormat, nFormatType );
+}
+
+
+void __EXPORT ScFormulaCell::Notify( SvtBroadcaster&, const SfxHint& rHint)
+{
+ if ( !pDocument->IsInDtorClear() && !pDocument->GetHardRecalcState() )
+ {
+ const ScHint* p = PTR_CAST( ScHint, &rHint );
+ ULONG nHint = (p ? p->GetId() : 0);
+ if (nHint & (SC_HINT_DATACHANGED | SC_HINT_DYING | SC_HINT_TABLEOPDIRTY))
+ {
+ BOOL bForceTrack = FALSE;
+ if ( nHint & SC_HINT_TABLEOPDIRTY )
+ {
+ bForceTrack = !bTableOpDirty;
+ if ( !bTableOpDirty )
+ {
+ pDocument->AddTableOpFormulaCell( this );
+ bTableOpDirty = TRUE;
+ }
+ }
+ else
+ {
+ bForceTrack = !bDirty;
+ bDirty = TRUE;
+ }
+ // #35962# Don't remove from FormulaTree to put in FormulaTrack to
+ // put in FormulaTree again and again, only if necessary.
+ // Any other means except RECALCMODE_ALWAYS by which a cell could
+ // be in FormulaTree if it would notify other cells through
+ // FormulaTrack which weren't in FormulaTrack/FormulaTree before?!?
+ // #87866# Yes. The new TableOpDirty made it necessary to have a
+ // forced mode where formulas may still be in FormulaTree from
+ // TableOpDirty but have to notify dependents for normal dirty.
+ if ( (bForceTrack || !pDocument->IsInFormulaTree( this )
+ || pCode->IsRecalcModeAlways())
+ && !pDocument->IsInFormulaTrack( this ) )
+ pDocument->AppendToFormulaTrack( this );
+ }
+ }
+}
+
+void ScFormulaCell::SetDirty()
+{
+ if ( !IsInChangeTrack() )
+ {
+ if ( pDocument->GetHardRecalcState() )
+ bDirty = TRUE;
+ else
+ {
+ // Mehrfach-FormulaTracking in Load und in CompileAll
+ // nach CopyScenario und CopyBlockFromClip vermeiden.
+ // Wenn unbedingtes FormulaTracking noetig, vor SetDirty bDirty=FALSE
+ // setzen, z.B. in CompileTokenArray
+ if ( !bDirty || !pDocument->IsInFormulaTree( this ) )
+ {
+ bDirty = TRUE;
+ pDocument->AppendToFormulaTrack( this );
+ pDocument->TrackFormulas();
+ }
+ }
+
+ if (pDocument->IsStreamValid(aPos.Tab()))
+ pDocument->SetStreamValid(aPos.Tab(), FALSE);
+ }
+}
+
+void ScFormulaCell::SetDirtyAfterLoad()
+{
+ bDirty = TRUE;
+ if ( !pDocument->GetHardRecalcState() )
+ pDocument->PutInFormulaTree( this );
+}
+
+void ScFormulaCell::SetTableOpDirty()
+{
+ if ( !IsInChangeTrack() )
+ {
+ if ( pDocument->GetHardRecalcState() )
+ bTableOpDirty = TRUE;
+ else
+ {
+ if ( !bTableOpDirty || !pDocument->IsInFormulaTree( this ) )
+ {
+ if ( !bTableOpDirty )
+ {
+ pDocument->AddTableOpFormulaCell( this );
+ bTableOpDirty = TRUE;
+ }
+ pDocument->AppendToFormulaTrack( this );
+ pDocument->TrackFormulas( SC_HINT_TABLEOPDIRTY );
+ }
+ }
+ }
+}
+
+
+BOOL ScFormulaCell::IsDirtyOrInTableOpDirty() const
+{
+ return bDirty || (bTableOpDirty && pDocument->IsInInterpreterTableOp());
+}
+
+
+void ScFormulaCell::SetErrCode( USHORT n )
+{
+ /* FIXME: check the numerous places where ScTokenArray::GetCodeError() is
+ * used whether it is solely for transport of a simple result error and get
+ * rid of that abuse. */
+ pCode->SetCodeError( n );
+ // Hard set errors are transported as result type value per convention,
+ // e.g. via clipboard. ScFormulaResult::IsValue() and
+ // ScFormulaResult::GetDouble() handle that.
+ aResult.SetResultError( n );
+}
+
+void ScFormulaCell::AddRecalcMode( ScRecalcMode nBits )
+{
+ if ( (nBits & RECALCMODE_EMASK) != RECALCMODE_NORMAL )
+ bDirty = TRUE;
+ if ( nBits & RECALCMODE_ONLOAD_ONCE )
+ { // OnLoadOnce nur zum Dirty setzen nach Filter-Import
+ nBits = (nBits & ~RECALCMODE_EMASK) | RECALCMODE_NORMAL;
+ }
+ pCode->AddRecalcMode( nBits );
+}
+
+// Dynamically create the URLField on a mouse-over action on a hyperlink() cell.
+void ScFormulaCell::GetURLResult( String& rURL, String& rCellText )
+{
+ String aCellString;
+
+ Color* pColor;
+
+ // Cell Text uses the Cell format while the URL uses
+ // the default format for the type.
+ ULONG nCellFormat = pDocument->GetNumberFormat( aPos );
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+
+ if ( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nCellFormat = GetStandardFormat( *pFormatter,nCellFormat );
+
+ ULONG nURLFormat = ScGlobal::GetStandardFormat( *pFormatter,nCellFormat, NUMBERFORMAT_NUMBER);
+
+ if ( IsValue() )
+ {
+ double fValue = GetValue();
+ pFormatter->GetOutputString( fValue, nCellFormat, rCellText, &pColor );
+ }
+ else
+ {
+ GetString( aCellString );
+ pFormatter->GetOutputString( aCellString, nCellFormat, rCellText, &pColor );
+ }
+ ScConstMatrixRef xMat( aResult.GetMatrix());
+ if (xMat)
+ {
+ ScMatValType nMatValType;
+ // determine if the matrix result is a string or value.
+ const ScMatrixValue* pMatVal = xMat->Get(0, 1, nMatValType);
+ if (pMatVal)
+ {
+ if (!ScMatrix::IsValueType( nMatValType))
+ rURL = pMatVal->GetString();
+ else
+ pFormatter->GetOutputString( pMatVal->fVal, nURLFormat, rURL, &pColor );
+ }
+ }
+
+ if(!rURL.Len())
+ {
+ if(IsValue())
+ pFormatter->GetOutputString( GetValue(), nURLFormat, rURL, &pColor );
+ else
+ pFormatter->GetOutputString( aCellString, nURLFormat, rURL, &pColor );
+ }
+}
+
+bool ScFormulaCell::IsMultilineResult()
+{
+ if (!IsValue())
+ return aResult.IsMultiline();
+ return false;
+}
+
+EditTextObject* ScFormulaCell::CreateURLObject()
+{
+ String aCellText;
+ String aURL;
+ GetURLResult( aURL, aCellText );
+
+ SvxURLField aUrlField( aURL, aCellText, SVXURLFORMAT_APPDEFAULT);
+ EditEngine& rEE = pDocument->GetEditEngine();
+ rEE.SetText( EMPTY_STRING );
+ rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection( 0xFFFF, 0xFFFF ) );
+
+ return rEE.CreateTextObject();
+}
+
+// ============================================================================
+
+ScDetectiveRefIter::ScDetectiveRefIter( ScFormulaCell* pCell )
+{
+ pCode = pCell->GetCode();
+ pCode->Reset();
+ aPos = pCell->aPos;
+}
+
+BOOL lcl_ScDetectiveRefIter_SkipRef( ScToken* p )
+{
+ ScSingleRefData& rRef1 = p->GetSingleRef();
+ if ( rRef1.IsColDeleted() || rRef1.IsRowDeleted() || rRef1.IsTabDeleted()
+ || !rRef1.Valid() )
+ return TRUE;
+ if ( p->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
+ if ( rRef2.IsColDeleted() || rRef2.IsRowDeleted() || rRef2.IsTabDeleted()
+ || !rRef2.Valid() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ScDetectiveRefIter::GetNextRef( ScRange& rRange )
+{
+ BOOL bRet = FALSE;
+
+ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if (p)
+ p->CalcAbsIfRel( aPos );
+
+ while ( p && lcl_ScDetectiveRefIter_SkipRef( p ) )
+ {
+ p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if (p)
+ p->CalcAbsIfRel( aPos );
+ }
+
+ if( p )
+ {
+ SingleDoubleRefProvider aProv( *p );
+ rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab );
+ rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ============================================================================
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
new file mode 100644
index 000000000000..1aab26acf3aa
--- /dev/null
+++ b/sc/source/core/data/cell2.cxx
@@ -0,0 +1,1627 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <algorithm>
+#include <deque>
+
+#include <boost/bind.hpp>
+
+#include <vcl/mapmod.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+
+#include "cell.hxx"
+#include "compiler.hxx"
+#include "formula/errorcodes.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "rechead.hxx"
+#include "refupdat.hxx"
+#include "scmatrix.hxx"
+#include "editutil.hxx"
+#include "chgtrack.hxx"
+#include "externalrefmgr.hxx"
+
+using namespace formula;
+
+// STATIC DATA -----------------------------------------------------------
+
+#ifdef USE_MEMPOOL
+const USHORT nMemPoolEditCell = (0x1000 - 64) / sizeof(ScNoteCell);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScEditCell, nMemPoolEditCell, nMemPoolEditCell )
+#endif
+
+// ============================================================================
+
+ScEditCell::ScEditCell( const EditTextObject* pObject, ScDocument* pDocP,
+ const SfxItemPool* pFromPool ) :
+ ScBaseCell( CELLTYPE_EDIT ),
+ pString( NULL ),
+ pDoc( pDocP )
+{
+ SetTextObject( pObject, pFromPool );
+}
+
+ScEditCell::ScEditCell( const ScEditCell& rCell, ScDocument& rDoc ) :
+ ScBaseCell( rCell ),
+ pString( NULL ),
+ pDoc( &rDoc )
+{
+ SetTextObject( rCell.pData, rCell.pDoc->GetEditPool() );
+}
+
+ScEditCell::ScEditCell( const String& rString, ScDocument* pDocP ) :
+ ScBaseCell( CELLTYPE_EDIT ),
+ pString( NULL ),
+ pDoc( pDocP )
+{
+ DBG_ASSERT( rString.Search('\n') != STRING_NOTFOUND ||
+ rString.Search(CHAR_CR) != STRING_NOTFOUND,
+ "EditCell mit einfachem Text !?!?" );
+
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( rString );
+ pData = rEngine.CreateTextObject();
+}
+
+ScEditCell::~ScEditCell()
+{
+ delete pData;
+ delete pString;
+
+#ifdef DBG_UTIL
+ eCellType = CELLTYPE_DESTROYED;
+#endif
+}
+
+void ScEditCell::SetData( const EditTextObject* pObject,
+ const SfxItemPool* pFromPool )
+{
+ if ( pString )
+ {
+ delete pString;
+ pString = NULL;
+ }
+ delete pData;
+ SetTextObject( pObject, pFromPool );
+}
+
+void ScEditCell::GetData( const EditTextObject*& rpObject ) const
+{
+ rpObject = pData;
+}
+
+void ScEditCell::GetString( String& rString ) const
+{
+ if ( pString )
+ rString = *pString;
+ else if ( pData )
+ {
+ // auch Text von URL-Feldern, Doc-Engine ist eine ScFieldEditEngine
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ rString = ScEditUtil::GetMultilineString(rEngine); // string with line separators between paragraphs
+ // cache short strings for formulas
+ if ( rString.Len() < 256 )
+ ((ScEditCell*)this)->pString = new String( rString ); //! non-const
+ }
+ else
+ rString.Erase();
+}
+
+void ScEditCell::SetTextObject( const EditTextObject* pObject,
+ const SfxItemPool* pFromPool )
+{
+ if ( pObject )
+ {
+ if ( pFromPool && pDoc->GetEditPool() == pFromPool )
+ pData = pObject->Clone();
+ else
+ { //! anderer Pool
+ // Leider gibt es keinen anderen Weg, um den Pool umzuhaengen,
+ // als das Object durch eine entsprechende Engine zu schleusen..
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ if ( pObject->HasOnlineSpellErrors() )
+ {
+ ULONG nControl = rEngine.GetControlWord();
+ const ULONG nSpellControl = EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS;
+ BOOL bNewControl = ( (nControl & nSpellControl) != nSpellControl );
+ if ( bNewControl )
+ rEngine.SetControlWord( nControl | nSpellControl );
+ rEngine.SetText( *pObject );
+ pData = rEngine.CreateTextObject();
+ if ( bNewControl )
+ rEngine.SetControlWord( nControl );
+ }
+ else
+ {
+ rEngine.SetText( *pObject );
+ pData = rEngine.CreateTextObject();
+ }
+ }
+ }
+ else
+ pData = NULL;
+}
+
+// ============================================================================
+
+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())
+ Interpret();
+ return aResult.GetCellResultType() == formula::svEmptyCell;
+}
+
+BOOL ScFormulaCell::IsEmptyDisplayedAsString()
+{
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+ return aResult.IsEmptyDisplayedAsString();
+}
+
+BOOL ScFormulaCell::IsValue()
+{
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+ return aResult.IsValue();
+}
+
+double ScFormulaCell::GetValue()
+{
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+ if ((!pCode->GetCodeError() || pCode->GetCodeError() == errDoubleRef) &&
+ !aResult.GetResultError())
+ return aResult.GetDouble();
+ return 0.0;
+}
+
+double ScFormulaCell::GetValueAlways()
+{
+ // for goal seek: return result value even if error code is set
+
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+ return aResult.GetDouble();
+}
+
+void ScFormulaCell::GetString( String& rString )
+{
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+ if ((!pCode->GetCodeError() || pCode->GetCodeError() == errDoubleRef) &&
+ !aResult.GetResultError())
+ rString = aResult.GetString();
+ else
+ rString.Erase();
+}
+
+const ScMatrix* ScFormulaCell::GetMatrix()
+{
+ if ( pDocument->GetAutoCalc() )
+ {
+ // Was stored !bDirty but an accompanying matrix cell was bDirty?
+ // => we need to get the matrix.
+ if (!bDirty && cMatrixFlag == MM_FORMULA && !aResult.GetMatrix().Is())
+ bDirty = TRUE;
+ if ( IsDirtyOrInTableOpDirty() )
+ Interpret();
+ }
+ return aResult.GetMatrix();
+}
+
+BOOL ScFormulaCell::GetMatrixOrigin( ScAddress& rPos ) const
+{
+ switch ( cMatrixFlag )
+ {
+ case MM_FORMULA :
+ rPos = aPos;
+ return TRUE;
+// break;
+ case MM_REFERENCE :
+ {
+ pCode->Reset();
+ ScToken* t = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if( t )
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ rRef.CalcAbsIfRel( aPos );
+ if ( rRef.Valid() )
+ {
+ rPos.Set( rRef.nCol, rRef.nRow, rRef.nTab );
+ return TRUE;
+ }
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+/*
+ Edge-Values:
+
+ 8
+ 4 16
+ 2
+
+ innerhalb: 1
+ ausserhalb: 0
+ (reserviert: offen: 32)
+ */
+
+USHORT ScFormulaCell::GetMatrixEdge( ScAddress& rOrgPos )
+{
+ switch ( cMatrixFlag )
+ {
+ case MM_FORMULA :
+ case MM_REFERENCE :
+ {
+ static SCCOL nC;
+ static SCROW nR;
+ ScAddress aOrg;
+ if ( !GetMatrixOrigin( aOrg ) )
+ return 0; // dumm gelaufen..
+ if ( aOrg != rOrgPos )
+ { // erstes Mal oder andere Matrix als letztes Mal
+ rOrgPos = aOrg;
+ ScFormulaCell* pFCell;
+ if ( cMatrixFlag == MM_REFERENCE )
+ pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
+ else
+ pFCell = this; // this MM_FORMULA
+ // this gibt's nur einmal, kein Vergleich auf pFCell==this
+ if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA
+ && pFCell->cMatrixFlag == MM_FORMULA )
+ {
+ pFCell->GetMatColsRows( nC, nR );
+ if ( nC == 0 || nR == 0 )
+ { // aus altem Dokument geladen, neu erzeugen
+ nC = 1;
+ nR = 1;
+ ScAddress aTmpOrg;
+ ScBaseCell* pCell;
+ ScAddress aAdr( aOrg );
+ aAdr.IncCol();
+ BOOL bCont = TRUE;
+ do
+ {
+ pCell = pDocument->GetCell( aAdr );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
+ && GetMatrixOrigin( aTmpOrg ) && aTmpOrg == aOrg )
+ {
+ nC++;
+ aAdr.IncCol();
+ }
+ else
+ bCont = FALSE;
+ } while ( bCont );
+ aAdr = aOrg;
+ aAdr.IncRow();
+ bCont = TRUE;
+ do
+ {
+ pCell = pDocument->GetCell( aAdr );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
+ && GetMatrixOrigin( aTmpOrg ) && aTmpOrg == aOrg )
+ {
+ nR++;
+ aAdr.IncRow();
+ }
+ else
+ bCont = FALSE;
+ } while ( bCont );
+ pFCell->SetMatColsRows( nC, nR );
+ }
+ }
+ else
+ {
+#ifdef DBG_UTIL
+ String aTmp;
+ ByteString aMsg( "broken Matrix, no MatFormula at origin, Pos: " );
+ aPos.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
+ aMsg += ByteString( aTmp, RTL_TEXTENCODING_ASCII_US );
+ aMsg += ", MatOrg: ";
+ aOrg.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
+ aMsg += ByteString( aTmp, RTL_TEXTENCODING_ASCII_US );
+ DBG_ERRORFILE( aMsg.GetBuffer() );
+#endif
+ return 0; // bad luck ...
+ }
+ }
+ // here we are, healthy and clean, somewhere in between
+ SCsCOL dC = aPos.Col() - aOrg.Col();
+ SCsROW dR = aPos.Row() - aOrg.Row();
+ USHORT nEdges = 0;
+ if ( dC >= 0 && dR >= 0 && dC < nC && dR < nR )
+ {
+ if ( dC == 0 )
+ nEdges |= 4; // linke Kante
+ if ( dC+1 == nC )
+ nEdges |= 16; // rechte Kante
+ if ( dR == 0 )
+ nEdges |= 8; // obere Kante
+ if ( dR+1 == nR )
+ nEdges |= 2; // untere Kante
+ if ( !nEdges )
+ nEdges = 1; // mittendrin
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ String aTmp;
+ ByteString aMsg( "broken Matrix, Pos: " );
+ aPos.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
+ aMsg += ByteString( aTmp, RTL_TEXTENCODING_ASCII_US );
+ aMsg += ", MatOrg: ";
+ aOrg.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
+ aMsg += ByteString( aTmp, RTL_TEXTENCODING_ASCII_US );
+ aMsg += ", MatCols: ";
+ aMsg += ByteString::CreateFromInt32( nC );
+ aMsg += ", MatRows: ";
+ aMsg += ByteString::CreateFromInt32( nR );
+ aMsg += ", DiffCols: ";
+ aMsg += ByteString::CreateFromInt32( dC );
+ aMsg += ", DiffRows: ";
+ aMsg += ByteString::CreateFromInt32( dR );
+ DBG_ERRORFILE( aMsg.GetBuffer() );
+ }
+#endif
+ return nEdges;
+// break;
+ }
+ default:
+ return 0;
+ }
+}
+
+USHORT ScFormulaCell::GetErrCode()
+{
+ if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
+ Interpret();
+ /* FIXME: If ScTokenArray::SetCodeError() was really only for code errors
+ * and not also abused for signaling other error conditions we could bail
+ * out even before attempting to interpret broken code. */
+ USHORT nErr = pCode->GetCodeError();
+ if (nErr)
+ return nErr;
+ return aResult.GetResultError();
+}
+
+USHORT ScFormulaCell::GetRawError()
+{
+ USHORT nErr = pCode->GetCodeError();
+ if (nErr)
+ return nErr;
+ return aResult.GetResultError();
+}
+
+BOOL ScFormulaCell::HasOneReference( ScRange& r ) const
+{
+ pCode->Reset();
+ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ if( p && !pCode->GetNextReferenceRPN() ) // nur eine!
+ {
+ p->CalcAbsIfRel( aPos );
+ SingleDoubleRefProvider aProv( *p );
+ r.aStart.Set( aProv.Ref1.nCol,
+ aProv.Ref1.nRow,
+ aProv.Ref1.nTab );
+ r.aEnd.Set( aProv.Ref2.nCol,
+ aProv.Ref2.nRow,
+ aProv.Ref2.nTab );
+ return TRUE;
+ }
+ else
+ 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.
+ */
+
+ // Detect the simple case of exactly one reference in advance without all
+ // overhead.
+ // #i107741# Doing so actually makes outlines using SUBTOTAL(x;reference)
+ // work again, where the function does not have only references.
+ if (HasOneReference( rRange))
+ return true;
+
+ 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();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReferenceRPN()) ) != NULL )
+ {
+ if ( t->GetSingleRef().IsRelName() ||
+ (t->GetType() == formula::svDoubleRef &&
+ t->GetDoubleRef().Ref2.IsRelName()) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ScFormulaCell::HasColRowName() const
+{
+ pCode->Reset();
+ return (pCode->GetNextColRowName() != NULL);
+}
+
+void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
+ const ScRange& r,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
+{
+ SCCOL nCol1 = r.aStart.Col();
+ SCROW nRow1 = r.aStart.Row();
+ SCTAB nTab1 = r.aStart.Tab();
+ SCCOL nCol2 = r.aEnd.Col();
+ SCROW nRow2 = r.aEnd.Row();
+ SCTAB nTab2 = r.aEnd.Tab();
+ SCCOL nCol = aPos.Col();
+ 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;
+ if (eUpdateRefMode == URM_INSDEL)
+ {
+ bIsInsert = (nDx >= 0 && nDy >= 0 && nDz >= 0);
+ if ( nDx && nRow >= nRow1 && nRow <= nRow2 &&
+ nTab >= nTab1 && nTab <= nTab2 )
+ {
+ if (nCol >= nCol1)
+ {
+ nCol = sal::static_int_cast<SCCOL>( nCol + nDx );
+ if ((SCsCOL) nCol < 0)
+ nCol = 0;
+ else if ( nCol > MAXCOL )
+ nCol = MAXCOL;
+ aPos.SetCol( nCol );
+// bPosChanged = TRUE;
+ }
+ }
+ if ( nDy && nCol >= nCol1 && nCol <= nCol2 &&
+ nTab >= nTab1 && nTab <= nTab2 )
+ {
+ if (nRow >= nRow1)
+ {
+ nRow = sal::static_int_cast<SCROW>( nRow + nDy );
+ if ((SCsROW) nRow < 0)
+ nRow = 0;
+ else if ( nRow > MAXROW )
+ nRow = MAXROW;
+ aPos.SetRow( nRow );
+// bPosChanged = TRUE;
+ }
+ }
+ if ( nDz && nCol >= nCol1 && nCol <= nCol2 &&
+ nRow >= nRow1 && nRow <= nRow2 )
+ {
+ if (nTab >= nTab1)
+ {
+ SCTAB nMaxTab = pDocument->GetTableCount() - 1;
+ nTab = sal::static_int_cast<SCTAB>( nTab + nDz );
+ if ((SCsTAB) nTab < 0)
+ nTab = 0;
+ else if ( nTab > nMaxTab )
+ nTab = nMaxTab;
+ aPos.SetTab( nTab );
+// bPosChanged = TRUE;
+ }
+ }
+ }
+ else if ( r.In( aPos ) )
+ {
+ aOldPos.Set( nCol - nDx, nRow - nDy, nTab - nDz );
+// bPosChanged = TRUE;
+ }
+
+ BOOL bHasRefs = FALSE;
+ BOOL bHasColRowNames = FALSE;
+ BOOL bOnRefMove = FALSE;
+ if ( !pDocument->IsClipOrUndo() )
+ {
+ pCode->Reset();
+ bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
+ if ( !bHasRefs || eUpdateRefMode == URM_COPY )
+ {
+ pCode->Reset();
+ bHasColRowNames = (pCode->GetNextColRowName() != NULL);
+ bHasRefs = bHasRefs || bHasColRowNames;
+ }
+ bOnRefMove = pCode->IsRecalcModeOnRefMove();
+ }
+ if( bHasRefs || bOnRefMove )
+ {
+ ScTokenArray* pOld = pUndoDoc ? pCode->Clone() : NULL;
+ BOOL bValChanged;
+ ScRangeData* pRangeData;
+ BOOL bRangeModified; // any range, not only shared formula
+ BOOL bRefSizeChanged;
+ if ( bHasRefs )
+ {
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, r,
+ nDx, nDy, nDz,
+ bValChanged, bRefSizeChanged);
+ bRangeModified = aComp.HasModifiedRange();
+ }
+ else
+ {
+ bValChanged = FALSE;
+ pRangeData = NULL;
+ bRangeModified = FALSE;
+ bRefSizeChanged = FALSE;
+ }
+ if ( bOnRefMove )
+ bOnRefMove = (bValChanged || (aPos != aOldPos));
+ // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+
+ BOOL bColRowNameCompile, bHasRelName, bNewListening, bInDeleteUndo;
+ if ( bHasRefs )
+ {
+ // Upon Insert ColRowNames have to be recompiled in case the
+ // insertion occurs right in front of the range.
+ bColRowNameCompile =
+ (eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0));
+ if ( bColRowNameCompile )
+ {
+ bColRowNameCompile = FALSE;
+ ScToken* t;
+ ScRangePairList* pColList = pDocument->GetColNameRanges();
+ ScRangePairList* pRowList = pDocument->GetRowNameRanges();
+ pCode->Reset();
+ while ( !bColRowNameCompile && (t = static_cast<ScToken*>(pCode->GetNextColRowName())) != NULL )
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ if ( nDy > 0 && rRef.IsColRel() )
+ { // ColName
+ rRef.CalcAbsIfRel( aPos );
+ ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+ ScRangePair* pR = pColList->Find( aAdr );
+ if ( pR )
+ { // definiert
+ if ( pR->GetRange(1).aStart.Row() == nRow1 )
+ bColRowNameCompile = TRUE;
+ }
+ else
+ { // on the fly
+ if ( rRef.nRow + 1 == nRow1 )
+ bColRowNameCompile = TRUE;
+ }
+ }
+ if ( nDx > 0 && rRef.IsRowRel() )
+ { // RowName
+ rRef.CalcAbsIfRel( aPos );
+ ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+ ScRangePair* pR = pRowList->Find( aAdr );
+ if ( pR )
+ { // definiert
+ if ( pR->GetRange(1).aStart.Col() == nCol1 )
+ bColRowNameCompile = TRUE;
+ }
+ else
+ { // on the fly
+ if ( rRef.nCol + 1 == nCol1 )
+ bColRowNameCompile = TRUE;
+ }
+ }
+ }
+ }
+ else if ( eUpdateRefMode == URM_MOVE )
+ { // bei Move/D&D neu kompilieren wenn ColRowName verschoben wurde
+ // oder diese Zelle auf einen zeigt und verschoben wurde
+ bColRowNameCompile = bCompile; // evtl. aus Copy-ctor
+ if ( !bColRowNameCompile )
+ {
+ BOOL bMoved = (aPos != aOldPos);
+ pCode->Reset();
+ ScToken* t = static_cast<ScToken*>(pCode->GetNextColRowName());
+ if ( t && bMoved )
+ bColRowNameCompile = TRUE;
+ while ( t && !bColRowNameCompile )
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ rRef.CalcAbsIfRel( aPos );
+ if ( rRef.Valid() )
+ {
+ ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+ if ( r.In( aAdr ) )
+ bColRowNameCompile = TRUE;
+ }
+ t = static_cast<ScToken*>(pCode->GetNextColRowName());
+ }
+ }
+ }
+ else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
+ {
+ bColRowNameCompile = TRUE;
+ }
+ ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
+ if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
+ bInDeleteUndo = TRUE;
+ else
+ bInDeleteUndo = FALSE;
+ // RelNameRefs are always moved
+ bHasRelName = HasRelNameReference();
+ // Reference changed and new listening needed?
+ // Except in Insert/Delete without specialties.
+ bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
+ || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
+ bInDeleteUndo || bRefSizeChanged)) ||
+ (bHasRelName && eUpdateRefMode != URM_COPY))
+ // #i36299# Don't duplicate action during cut&paste / drag&drop
+ // on a cell in the range moved, start/end listeners is done
+ // via ScDocument::DeleteArea() and ScDocument::CopyFromClip().
+ && !(eUpdateRefMode == URM_MOVE &&
+ pDocument->IsInsertingFromOtherDoc() && r.In(aPos));
+ if ( bNewListening )
+ EndListeningTo( pDocument, pOld, aOldPos );
+ }
+ else
+ {
+ bColRowNameCompile = bHasRelName = bNewListening = bInDeleteUndo =
+ FALSE;
+ }
+
+ BOOL bNeedDirty;
+ // NeedDirty bei Aenderungen ausser Copy und Move/Insert ohne RelNames
+ if ( bRangeModified || pRangeData || bColRowNameCompile ||
+ (bValChanged && eUpdateRefMode != URM_COPY &&
+ (eUpdateRefMode != URM_MOVE || bHasRelName) &&
+ (!bIsInsert || bHasRelName || bInDeleteUndo ||
+ bRefSizeChanged)) || bOnRefMove)
+ bNeedDirty = TRUE;
+ else
+ bNeedDirty = FALSE;
+ if (pUndoDoc && (bValChanged || pRangeData || bOnRefMove))
+ {
+ // Copy the cell to aUndoPos, which is its current position in the document,
+ // so this works when UpdateReference is called before moving the cells
+ // (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
+ // is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
+
+ // 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 )
+ { // Replace shared formula with own formula
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = pRangeData->GetCode()->Clone();
+ // #i18937# #i110008# call MoveRelWrap, but with the old position
+ ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, r,
+ nDx, nDy, nDz );
+ bValChanged = TRUE;
+ bNeedDirty = TRUE;
+ }
+ if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
+ {
+ CompileTokenArray( bNewListening ); // kein Listening
+ bNeedDirty = TRUE;
+ }
+ if ( !bInDeleteUndo )
+ { // In ChangeTrack Delete-Reject listeners are established in
+ // InsertCol/InsertRow
+ if ( bNewListening )
+ {
+ if ( eUpdateRefMode == URM_INSDEL )
+ {
+ // Inserts/Deletes re-establish listeners after all
+ // UpdateReference calls.
+ // All replaced shared formula listeners have to be
+ // established after an Insert or Delete. Do nothing here.
+ SetNeedsListening( TRUE);
+ }
+ else
+ StartListeningTo( pDocument );
+ }
+ }
+ if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
+ { // Referenzen abgeschnitten, ungueltig o.ae.?
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ // kein Interpret in SubMinimalRecalc wegen evtl. falscher Referenzen
+ pDocument->SetAutoCalc( FALSE );
+ SetDirty();
+ pDocument->SetAutoCalc( bOldAutoCalc );
+ }
+
+ delete pOld;
+ }
+}
+
+void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
+{
+ BOOL bPosChanged = ( aPos.Tab() >= nTable ? TRUE : FALSE );
+ pCode->Reset();
+ if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() )
+ {
+ EndListeningTo( pDocument );
+ // IncTab _nach_ EndListeningTo und _vor_ Compiler UpdateInsertTab !
+ if ( bPosChanged )
+ aPos.IncTab();
+ ScRangeData* pRangeData;
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pRangeData = aComp.UpdateInsertTab( nTable, FALSE );
+ if (pRangeData) // Shared Formula gegen echte Formel
+ { // austauschen
+ BOOL bRefChanged;
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = new ScTokenArray( *pRangeData->GetCode() );
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ 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.
+ aComp2.UpdateDeleteTab( nTable, FALSE, TRUE, bRefChanged );
+ bCompile = TRUE;
+ }
+ // kein StartListeningTo weil pTab[nTab] noch nicht existiert!
+ }
+ else if ( bPosChanged )
+ aPos.IncTab();
+}
+
+BOOL ScFormulaCell::UpdateDeleteTab(SCTAB nTable, BOOL bIsMove)
+{
+ BOOL bRefChanged = FALSE;
+ BOOL bPosChanged = ( aPos.Tab() > nTable ? TRUE : FALSE );
+ pCode->Reset();
+ if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() )
+ {
+ EndListeningTo( pDocument );
+ // IncTab _nach_ EndListeningTo und _vor_ Compiler UpdateDeleteTab !
+ if ( bPosChanged )
+ aPos.IncTab(-1);
+ ScRangeData* pRangeData;
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pRangeData = aComp.UpdateDeleteTab(nTable, bIsMove, FALSE, bRefChanged);
+ if (pRangeData) // Shared Formula gegen echte Formel
+ { // austauschen
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = pRangeData->GetCode()->Clone();
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ aComp2.CompileTokenArray();
+ 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.
+ aComp2.UpdateInsertTab( nTable,TRUE );
+ // bRefChanged kann beim letzten UpdateDeleteTab zurueckgesetzt worden sein
+ bRefChanged = TRUE;
+ bCompile = TRUE;
+ }
+ // kein StartListeningTo weil pTab[nTab] noch nicht korrekt!
+ }
+ else if ( bPosChanged )
+ aPos.IncTab(-1);
+
+ return bRefChanged;
+}
+
+void ScFormulaCell::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
+{
+ pCode->Reset();
+ if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() )
+ {
+ EndListeningTo( pDocument );
+ // SetTab _nach_ EndListeningTo und _vor_ Compiler UpdateMoveTab !
+ aPos.SetTab( nTabNo );
+ ScRangeData* pRangeData;
+ ScCompiler aComp(pDocument, aPos, *pCode);
+ aComp.SetGrammar(pDocument->GetGrammar());
+ pRangeData = aComp.UpdateMoveTab( nOldPos, nNewPos, FALSE );
+ if (pRangeData) // Shared Formula gegen echte Formel
+ { // austauschen
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = pRangeData->GetCode()->Clone();
+ ScCompiler aComp2(pDocument, aPos, *pCode);
+ aComp2.SetGrammar(pDocument->GetGrammar());
+ aComp2.CompileTokenArray();
+ aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+ aComp2.UpdateMoveTab( nOldPos, nNewPos, TRUE );
+ bCompile = TRUE;
+ }
+ // kein StartListeningTo weil pTab[nTab] noch nicht korrekt!
+ }
+ else
+ aPos.SetTab( nTabNo );
+}
+
+void ScFormulaCell::UpdateInsertTabAbs(SCTAB nTable)
+{
+ if( !pDocument->IsClipOrUndo() )
+ {
+ pCode->Reset();
+ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ while( p )
+ {
+ ScSingleRefData& rRef1 = p->GetSingleRef();
+ if( !rRef1.IsTabRel() && (SCsTAB) nTable <= rRef1.nTab )
+ rRef1.nTab++;
+ if( p->GetType() == formula::svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
+ if( !rRef2.IsTabRel() && (SCsTAB) nTable <= rRef2.nTab )
+ rRef2.nTab++;
+ }
+ p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ }
+ }
+}
+
+BOOL ScFormulaCell::TestTabRefAbs(SCTAB nTable)
+{
+ BOOL bRet = FALSE;
+ if( !pDocument->IsClipOrUndo() )
+ {
+ pCode->Reset();
+ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ while( p )
+ {
+ ScSingleRefData& rRef1 = p->GetSingleRef();
+ if( !rRef1.IsTabRel() )
+ {
+ if( (SCsTAB) nTable != rRef1.nTab )
+ bRet = TRUE;
+ else if (nTable != aPos.Tab())
+ rRef1.nTab = aPos.Tab();
+ }
+ if( p->GetType() == formula::svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
+ if( !rRef2.IsTabRel() )
+ {
+ if( (SCsTAB) nTable != rRef2.nTab )
+ bRet = TRUE;
+ else if (nTable != aPos.Tab())
+ rRef2.nTab = aPos.Tab();
+ }
+ }
+ p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+ }
+ }
+ return bRet;
+}
+
+void ScFormulaCell::UpdateCompile( BOOL bForceIfNameInUse )
+{
+ if ( bForceIfNameInUse && !bCompile )
+ bCompile = pCode->HasNameOrColRowName();
+ if ( bCompile )
+ pCode->SetCodeError( 0 ); // make sure it will really be compiled
+ CompileTokenArray();
+}
+
+// Referenzen transponieren - wird nur in Clipboard-Dokumenten aufgerufen
+
+void ScFormulaCell::TransposeReference()
+{
+ BOOL bFound = FALSE;
+ pCode->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsColRel() && rRef1.IsRowRel() )
+ {
+ BOOL bDouble = (t->GetType() == formula::svDoubleRef);
+ ScSingleRefData& rRef2 = (bDouble ? t->GetDoubleRef().Ref2 : rRef1);
+ if ( !bDouble || (rRef2.IsColRel() && rRef2.IsRowRel()) )
+ {
+ INT16 nTemp;
+
+ nTemp = rRef1.nRelCol;
+ rRef1.nRelCol = static_cast<SCCOL>(rRef1.nRelRow);
+ rRef1.nRelRow = static_cast<SCROW>(nTemp);
+
+ if ( bDouble )
+ {
+ nTemp = rRef2.nRelCol;
+ rRef2.nRelCol = static_cast<SCCOL>(rRef2.nRelRow);
+ rRef2.nRelRow = static_cast<SCROW>(nTemp);
+ }
+
+ bFound = TRUE;
+ }
+ }
+ }
+
+ if (bFound)
+ bCompile = TRUE;
+}
+
+void ScFormulaCell::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
+ ScDocument* pUndoDoc )
+{
+ EndListeningTo( pDocument );
+
+ ScAddress aOldPos = aPos;
+ BOOL bPosChanged = FALSE; // ob diese Zelle bewegt wurde
+
+ ScRange aDestRange( rDest, ScAddress(
+ static_cast<SCCOL>(rDest.Col() + rSource.aEnd.Row() - rSource.aStart.Row()),
+ static_cast<SCROW>(rDest.Row() + rSource.aEnd.Col() - rSource.aStart.Col()),
+ rDest.Tab() + rSource.aEnd.Tab() - rSource.aStart.Tab() ) );
+ if ( aDestRange.In( aOldPos ) )
+ {
+ // Position zurueckrechnen
+ SCsCOL nRelPosX = aOldPos.Col();
+ SCsROW nRelPosY = aOldPos.Row();
+ SCsTAB nRelPosZ = aOldPos.Tab();
+ ScRefUpdate::DoTranspose( nRelPosX, nRelPosY, nRelPosZ, pDocument, aDestRange, rSource.aStart );
+ aOldPos.Set( nRelPosX, nRelPosY, nRelPosZ );
+ bPosChanged = TRUE;
+ }
+
+ ScTokenArray* pOld = pUndoDoc ? pCode->Clone() : NULL;
+ BOOL bRefChanged = FALSE;
+ ScToken* t;
+
+ ScRangeData* pShared = NULL;
+ pCode->Reset();
+ while( (t = static_cast<ScToken*>(pCode->GetNextReferenceOrName())) != NULL )
+ {
+ if( t->GetOpCode() == ocName )
+ {
+ ScRangeData* pName = pDocument->GetRangeName()->FindIndex( t->GetIndex() );
+ if (pName)
+ {
+ if (pName->IsModified())
+ bRefChanged = TRUE;
+ if (pName->HasType(RT_SHAREDMOD))
+ pShared = pName;
+ }
+ }
+ else if( t->GetType() != svIndex )
+ {
+ t->CalcAbsIfRel( aOldPos );
+ BOOL bMod;
+ { // own scope for SingleDoubleRefModifier dtor if SingleRef
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ bMod = (ScRefUpdate::UpdateTranspose( pDocument, rSource,
+ rDest, rRef ) != UR_NOTHING || bPosChanged);
+ }
+ if ( bMod )
+ {
+ t->CalcRelFromAbs( aPos );
+ bRefChanged = TRUE;
+ }
+ }
+ }
+
+ if (pShared) // Shared Formula gegen echte Formel austauschen
+ {
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = new ScTokenArray( *pShared->GetCode() );
+ bRefChanged = TRUE;
+ pCode->Reset();
+ while( (t = static_cast<ScToken*>(pCode->GetNextReference())) != NULL )
+ {
+ if( t->GetType() != svIndex )
+ {
+ t->CalcAbsIfRel( aOldPos );
+ BOOL bMod;
+ { // own scope for SingleDoubleRefModifier dtor if SingleRef
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ bMod = (ScRefUpdate::UpdateTranspose( pDocument, rSource,
+ rDest, rRef ) != UR_NOTHING || bPosChanged);
+ }
+ if ( bMod )
+ t->CalcRelFromAbs( aPos );
+ }
+ }
+ }
+
+ if (bRefChanged)
+ {
+ if (pUndoDoc)
+ {
+ ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aPos, pOld,
+ eTempGrammar, cMatrixFlag);
+ pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
+ pUndoDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pFCell );
+ }
+
+ bCompile = TRUE;
+ CompileTokenArray(); // ruft auch StartListeningTo
+ SetDirty();
+ }
+ else
+ StartListeningTo( pDocument ); // Listener wie vorher
+
+ delete pOld;
+}
+
+void ScFormulaCell::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
+{
+ EndListeningTo( pDocument );
+
+ BOOL bRefChanged = FALSE;
+ ScToken* t;
+ ScRangeData* pShared = NULL;
+
+ pCode->Reset();
+ while( (t = static_cast<ScToken*>(pCode->GetNextReferenceOrName())) != NULL )
+ {
+ if( t->GetOpCode() == ocName )
+ {
+ ScRangeData* pName = pDocument->GetRangeName()->FindIndex( t->GetIndex() );
+ if (pName)
+ {
+ if (pName->IsModified())
+ bRefChanged = TRUE;
+ if (pName->HasType(RT_SHAREDMOD))
+ pShared = pName;
+ }
+ }
+ else if( t->GetType() != svIndex )
+ {
+ t->CalcAbsIfRel( aPos );
+ BOOL bMod;
+ { // own scope for SingleDoubleRefModifier dtor if SingleRef
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ bMod = (ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY,
+ rRef ) != UR_NOTHING);
+ }
+ if ( bMod )
+ {
+ t->CalcRelFromAbs( aPos );
+ bRefChanged = TRUE;
+ }
+ }
+ }
+
+ if (pShared) // Shared Formula gegen echte Formel austauschen
+ {
+ pDocument->RemoveFromFormulaTree( this ); // update formula count
+ delete pCode;
+ pCode = new ScTokenArray( *pShared->GetCode() );
+ bRefChanged = TRUE;
+ pCode->Reset();
+ while( (t = static_cast<ScToken*>(pCode->GetNextReference())) != NULL )
+ {
+ if( t->GetType() != svIndex )
+ {
+ t->CalcAbsIfRel( aPos );
+ BOOL bMod;
+ { // own scope for SingleDoubleRefModifier dtor if SingleRef
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ bMod = (ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY,
+ rRef ) != UR_NOTHING);
+ }
+ if ( bMod )
+ t->CalcRelFromAbs( aPos );
+ }
+ }
+ }
+
+ if (bRefChanged)
+ {
+ bCompile = TRUE;
+ CompileTokenArray(); // ruft auch StartListeningTo
+ SetDirty();
+ }
+ else
+ StartListeningTo( pDocument ); // Listener wie vorher
+}
+
+BOOL lcl_IsRangeNameInUse(USHORT nIndex, ScTokenArray* pCode, ScRangeName* pNames)
+{
+ for (FormulaToken* p = pCode->First(); p; p = pCode->Next())
+ {
+ if (p->GetOpCode() == ocName)
+ {
+ if (p->GetIndex() == nIndex)
+ return TRUE;
+ else
+ {
+ // RangeData kann Null sein in bestimmten Excel-Dateien (#31168#)
+ ScRangeData* pSubName = pNames->FindIndex(p->GetIndex());
+ if (pSubName && lcl_IsRangeNameInUse(nIndex,
+ pSubName->GetCode(), pNames))
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOL ScFormulaCell::IsRangeNameInUse(USHORT nIndex) const
+{
+ return lcl_IsRangeNameInUse( nIndex, pCode, pDocument->GetRangeName() );
+}
+
+void lcl_FindRangeNamesInUse(std::set<USHORT>& rIndexes, ScTokenArray* pCode, ScRangeName* pNames)
+{
+ for (FormulaToken* p = pCode->First(); p; p = pCode->Next())
+ {
+ if (p->GetOpCode() == ocName)
+ {
+ USHORT nTokenIndex = p->GetIndex();
+ rIndexes.insert( nTokenIndex );
+
+ ScRangeData* pSubName = pNames->FindIndex(p->GetIndex());
+ if (pSubName)
+ lcl_FindRangeNamesInUse(rIndexes, pSubName->GetCode(), pNames);
+ }
+ }
+}
+
+void ScFormulaCell::FindRangeNamesInUse(std::set<USHORT>& rIndexes) const
+{
+ lcl_FindRangeNamesInUse( rIndexes, pCode, pDocument->GetRangeName() );
+}
+
+void ScFormulaCell::ReplaceRangeNamesInUse( const ScRangeData::IndexMap& rMap )
+{
+ for( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
+ {
+ if( p->GetOpCode() == ocName )
+ {
+ sal_uInt16 nIndex = p->GetIndex();
+ ScRangeData::IndexMap::const_iterator itr = rMap.find(nIndex);
+ sal_uInt16 nNewIndex = itr == rMap.end() ? nIndex : itr->second;
+ if ( nIndex != nNewIndex )
+ {
+ p->SetIndex( nNewIndex );
+ bCompile = TRUE;
+ }
+ }
+ }
+ if( bCompile )
+ CompileTokenArray();
+}
+
+void ScFormulaCell::CompileDBFormula()
+{
+ for( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
+ {
+ if ( p->GetOpCode() == ocDBArea
+ || (p->GetOpCode() == ocName && p->GetIndex() >= SC_START_INDEX_DB_COLL) )
+ {
+ bCompile = TRUE;
+ CompileTokenArray();
+ SetDirty();
+ break;
+ }
+ }
+}
+
+void ScFormulaCell::CompileDBFormula( BOOL bCreateFormulaString )
+{
+ // zwei Phasen, muessen (!) nacheinander aufgerufen werden:
+ // 1. FormelString mit alten Namen erzeugen
+ // 2. FormelString mit neuen Namen kompilieren
+ if ( bCreateFormulaString )
+ {
+ BOOL bRecompile = FALSE;
+ pCode->Reset();
+ for ( FormulaToken* p = pCode->First(); p && !bRecompile; p = pCode->Next() )
+ {
+ switch ( p->GetOpCode() )
+ {
+ case ocBad: // DB-Bereich evtl. zugefuegt
+ case ocColRowName: // #36762# falls Namensgleichheit
+ case ocDBArea: // DB-Bereich
+ bRecompile = TRUE;
+ break;
+ case ocName:
+ if ( p->GetIndex() >= SC_START_INDEX_DB_COLL )
+ bRecompile = TRUE; // DB-Bereich
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ if ( bRecompile )
+ {
+ String aFormula;
+ GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+ if ( GetMatrixFlag() != MM_NONE && aFormula.Len() )
+ {
+ if ( aFormula.GetChar( aFormula.Len()-1 ) == '}' )
+ aFormula.Erase( aFormula.Len()-1 , 1 );
+ if ( aFormula.GetChar(0) == '{' )
+ aFormula.Erase( 0, 1 );
+ }
+ EndListeningTo( pDocument );
+ pDocument->RemoveFromFormulaTree( this );
+ pCode->Clear();
+ SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+ }
+ }
+ else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ {
+ Compile( aResult.GetHybridFormula(), FALSE, eTempGrammar );
+ aResult.SetToken( NULL);
+ SetDirty();
+ }
+}
+
+void ScFormulaCell::CompileNameFormula( BOOL bCreateFormulaString )
+{
+ // zwei Phasen, muessen (!) nacheinander aufgerufen werden:
+ // 1. FormelString mit alten RangeNames erzeugen
+ // 2. FormelString mit neuen RangeNames kompilieren
+ if ( bCreateFormulaString )
+ {
+ BOOL bRecompile = FALSE;
+ pCode->Reset();
+ for ( FormulaToken* p = pCode->First(); p && !bRecompile; p = pCode->Next() )
+ {
+ switch ( p->GetOpCode() )
+ {
+ case ocBad: // RangeName evtl. zugefuegt
+ case ocColRowName: // #36762# falls Namensgleichheit
+ bRecompile = TRUE;
+ break;
+ default:
+ if ( p->GetType() == svIndex )
+ bRecompile = TRUE; // RangeName
+ }
+ }
+ if ( bRecompile )
+ {
+ String aFormula;
+ GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+ if ( GetMatrixFlag() != MM_NONE && aFormula.Len() )
+ {
+ if ( aFormula.GetChar( aFormula.Len()-1 ) == '}' )
+ aFormula.Erase( aFormula.Len()-1 , 1 );
+ if ( aFormula.GetChar(0) == '{' )
+ aFormula.Erase( 0, 1 );
+ }
+ EndListeningTo( pDocument );
+ pDocument->RemoveFromFormulaTree( this );
+ pCode->Clear();
+ SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+ }
+ }
+ else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ {
+ Compile( aResult.GetHybridFormula(), FALSE, eTempGrammar );
+ aResult.SetToken( NULL);
+ SetDirty();
+ }
+}
+
+void ScFormulaCell::CompileColRowNameFormula()
+{
+ pCode->Reset();
+ for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
+ {
+ if ( p->GetOpCode() == ocColRowName )
+ {
+ bCompile = TRUE;
+ CompileTokenArray();
+ SetDirty();
+ break;
+ }
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/core/data/clipparam.cxx b/sc/source/core/data/clipparam.cxx
new file mode 100644
index 000000000000..9ab5995ca26c
--- /dev/null
+++ b/sc/source/core/data/clipparam.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "clipparam.hxx"
+
+using ::std::vector;
+
+ScClipParam::ScClipParam() :
+ meDirection(Unspecified),
+ mbCutMode(false)
+{
+}
+
+ScClipParam::ScClipParam(const ScRange& rRange, bool bCutMode) :
+ meDirection(Unspecified),
+ mbCutMode(bCutMode)
+{
+ maRanges.Append(rRange);
+}
+
+ScClipParam::ScClipParam(const ScClipParam& r) :
+ maRanges(r.maRanges),
+ meDirection(r.meDirection),
+ mbCutMode(r.mbCutMode)
+{
+}
+
+bool ScClipParam::isMultiRange() const
+{
+ return maRanges.Count() > 1;
+}
+
+SCCOL ScClipParam::getPasteColSize()
+{
+ if (!maRanges.Count())
+ return 0;
+
+ switch (meDirection)
+ {
+ case ScClipParam::Column:
+ {
+ SCCOL nColSize = 0;
+ for (ScRangePtr p = maRanges.First(); p; p = maRanges.Next())
+ nColSize += p->aEnd.Col() - p->aStart.Col() + 1;
+ return nColSize;
+ }
+ case ScClipParam::Row:
+ {
+ // We assume that all ranges have identical column size.
+ const ScRange& rRange = *maRanges.First();
+ return rRange.aEnd.Col() - rRange.aStart.Col() + 1;
+ }
+ case ScClipParam::Unspecified:
+ default:
+ ;
+ }
+ return 0;
+}
+
+SCROW ScClipParam::getPasteRowSize()
+{
+ if (!maRanges.Count())
+ return 0;
+
+ switch (meDirection)
+ {
+ case ScClipParam::Column:
+ {
+ // We assume that all ranges have identical row size.
+ const ScRange& rRange = *maRanges.First();
+ return rRange.aEnd.Row() - rRange.aStart.Row() + 1;
+ }
+ case ScClipParam::Row:
+ {
+ SCROW nRowSize = 0;
+ for (ScRangePtr p = maRanges.First(); p; p = maRanges.Next())
+ nRowSize += p->aEnd.Row() - p->aStart.Row() + 1;
+ return nRowSize;
+ }
+ case ScClipParam::Unspecified:
+ default:
+ ;
+ }
+ return 0;
+}
+
+ScRange ScClipParam::getWholeRange() const
+{
+ ScRange aWhole;
+ bool bFirst = true;
+ ScRangeList aRanges = maRanges;
+ for (ScRange* p = aRanges.First(); p; p = aRanges.Next())
+ {
+ if (bFirst)
+ {
+ aWhole = *p;
+ bFirst = false;
+ continue;
+ }
+
+ if (aWhole.aStart.Col() > p->aStart.Col())
+ aWhole.aStart.SetCol(p->aStart.Col());
+
+ if (aWhole.aStart.Row() > p->aStart.Row())
+ aWhole.aStart.SetRow(p->aStart.Row());
+
+ if (aWhole.aEnd.Col() < p->aEnd.Col())
+ aWhole.aEnd.SetCol(p->aEnd.Col());
+
+ if (aWhole.aEnd.Row() < p->aEnd.Row())
+ aWhole.aEnd.SetRow(p->aEnd.Row());
+ }
+ return aWhole;
+}
+
+void ScClipParam::transpose()
+{
+ switch (meDirection)
+ {
+ case Column:
+ meDirection = ScClipParam::Row;
+ break;
+ case Row:
+ meDirection = ScClipParam::Column;
+ break;
+ case Unspecified:
+ default:
+ ;
+ }
+
+ ScRangeList aNewRanges;
+ if (maRanges.Count())
+ {
+ ScRange* p = maRanges.First();
+ SCCOL nColOrigin = p->aStart.Col();
+ SCROW nRowOrigin = p->aStart.Row();
+ for (; p; p = maRanges.Next())
+ {
+ SCCOL nColDelta = p->aStart.Col() - nColOrigin;
+ SCROW nRowDelta = p->aStart.Row() - nRowOrigin;
+ SCCOL nCol1 = 0;
+ SCCOL nCol2 = static_cast<SCCOL>(p->aEnd.Row() - p->aStart.Row());
+ SCROW nRow1 = 0;
+ SCROW nRow2 = static_cast<SCROW>(p->aEnd.Col() - p->aStart.Col());
+ nCol1 += static_cast<SCCOL>(nRowDelta);
+ nCol2 += static_cast<SCCOL>(nRowDelta);
+ nRow1 += static_cast<SCROW>(nColDelta);
+ nRow2 += static_cast<SCROW>(nColDelta);
+ ScRange aNew(nCol1, nRow1, p->aStart.Tab(), nCol2, nRow2, p->aStart.Tab());
+ aNewRanges.Append(aNew);
+ }
+ }
+ maRanges = aNewRanges;
+}
+
+// ============================================================================
+
+ScClipRangeNameData::ScClipRangeNameData() :
+ mbReplace(false)
+{
+}
+
+ScClipRangeNameData::~ScClipRangeNameData()
+{
+}
+
+void ScClipRangeNameData::insert(sal_uInt16 nOldIndex, sal_uInt16 nNewIndex)
+{
+ maRangeMap.insert(
+ ScRangeData::IndexMap::value_type(nOldIndex, nNewIndex));
+}
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
new file mode 100644
index 000000000000..e9fd26ced939
--- /dev/null
+++ b/sc/source/core/data/column.cxx
@@ -0,0 +1,2160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <map>
+
+#include <svl/poolcach.hxx>
+#include <svl/zforlist.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <string.h>
+
+#include "scitems.hxx"
+#include "column.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "attarray.hxx"
+#include "patattr.hxx"
+#include "compiler.hxx"
+#include "brdcst.hxx"
+#include "markdata.hxx"
+#include "detfunc.hxx" // for Notes in Sort/Swap
+#include "postit.hxx"
+
+//#pragma optimize ( "", off )
+// nur Search ohne Optimierung!
+
+// STATIC DATA -----------------------------------------------------------
+using namespace formula;
+
+inline BOOL IsAmbiguousScriptNonZero( BYTE nScript )
+{
+ //! move to a header file
+ return ( nScript != SCRIPTTYPE_LATIN &&
+ nScript != SCRIPTTYPE_ASIAN &&
+ nScript != SCRIPTTYPE_COMPLEX &&
+ nScript != 0 );
+}
+
+// -----------------------------------------------------------------------------------------
+
+
+ScColumn::ScColumn() :
+ nCol( 0 ),
+ nCount( 0 ),
+ nLimit( 0 ),
+ pItems( NULL ),
+ pAttrArray( NULL ),
+ pDocument( NULL )
+{
+}
+
+
+ScColumn::~ScColumn()
+{
+ FreeAll();
+ if (pAttrArray) delete pAttrArray;
+}
+
+
+void ScColumn::Init(SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc)
+{
+ nCol = nNewCol;
+ nTab = nNewTab;
+ pDocument = pDoc;
+ pAttrArray = new ScAttrArray( nCol, nTab, pDocument );
+}
+
+
+SCsROW ScColumn::GetNextUnprotected( SCROW nRow, BOOL bUp ) const
+{
+ return pAttrArray->GetNextUnprotected(nRow, bUp);
+}
+
+
+USHORT ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, USHORT nMask ) const
+{
+ // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
+ if ( !pItems )
+ return 0;
+ if ( nRow1 == nRow2 )
+ {
+ SCSIZE nIndex;
+ if ( Search( nRow1, nIndex ) )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
+ {
+ ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
+ return ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
+ BOOL bOpen = FALSE;
+ USHORT nEdges = 0;
+ SCSIZE nIndex;
+ Search( nRow1, nIndex );
+ while ( nIndex < nCount && pItems[nIndex].nRow <= nRow2 )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
+ {
+ nEdges = ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
+ if ( nEdges )
+ {
+ if ( nEdges & 8 )
+ bOpen = TRUE; // obere Kante oeffnet, weitersehen
+ else if ( !bOpen )
+ return nEdges | 32; // es gibt was, was nicht geoeffnet wurde
+ else if ( nEdges & 1 )
+ return nEdges; // mittendrin
+ // (nMask & 16 und (4 und nicht 16)) oder
+ // (nMask & 4 und (16 und nicht 4))
+ if ( ((nMask & 16) && (nEdges & 4) && !(nEdges & 16))
+ || ((nMask & 4) && (nEdges & 16) && !(nEdges & 4)) )
+ return nEdges; // nur linke/rechte Kante
+ if ( nEdges & 2 )
+ bOpen = FALSE; // untere Kante schliesst
+ }
+ }
+ nIndex++;
+ }
+ if ( bOpen )
+ nEdges |= 32; // es geht noch weiter
+ return nEdges;
+ }
+}
+
+
+BOOL ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const
+{
+ if ( rMark.IsMultiMarked() )
+ {
+ BOOL bFound = FALSE;
+
+ ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
+ ScAddress aCurOrg( ScAddress::INITIALIZE_INVALID );
+ SCROW nTop, nBottom;
+ ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
+ while ( !bFound && aMarkIter.Next( nTop, nBottom ) )
+ {
+ BOOL bOpen = FALSE;
+ USHORT nEdges;
+ SCSIZE nIndex;
+ Search( nTop, nIndex );
+ while ( !bFound && nIndex < nCount && pItems[nIndex].nRow <= nBottom )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
+ {
+ nEdges = ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
+ if ( nEdges )
+ {
+ if ( nEdges & 8 )
+ bOpen = TRUE; // obere Kante oeffnet, weitersehen
+ else if ( !bOpen )
+ return TRUE; // es gibt was, was nicht geoeffnet wurde
+ else if ( nEdges & 1 )
+ bFound = TRUE; // mittendrin, alles selektiert?
+ // (4 und nicht 16) oder (16 und nicht 4)
+ if ( (((nEdges & 4) | 16) ^ ((nEdges & 16) | 4)) )
+ bFound = TRUE; // nur linke/rechte Kante, alles selektiert?
+ if ( nEdges & 2 )
+ bOpen = FALSE; // untere Kante schliesst
+
+ if ( bFound )
+ { // alles selektiert?
+ if ( aCurOrg != aOrg )
+ { // neue Matrix zu pruefen?
+ aCurOrg = aOrg;
+ ScFormulaCell* pFCell;
+ if ( ((ScFormulaCell*)pCell)->GetMatrixFlag()
+ == MM_REFERENCE )
+ pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
+ else
+ pFCell = (ScFormulaCell*)pCell;
+ SCCOL nC;
+ SCROW nR;
+ pFCell->GetMatColsRows( nC, nR );
+ ScRange aRange( aOrg, ScAddress(
+ aOrg.Col() + nC - 1, aOrg.Row() + nR - 1,
+ aOrg.Tab() ) );
+ if ( rMark.IsAllMarked( aRange ) )
+ bFound = FALSE;
+ }
+ else
+ bFound = FALSE; // war schon
+ }
+ }
+ }
+ nIndex++;
+ }
+ if ( bOpen )
+ return TRUE;
+ }
+ return bFound;
+ }
+ else
+ return FALSE;
+}
+
+
+//UNUSED2009-05 BOOL ScColumn::HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes,
+//UNUSED2009-05 BOOL bLeft, BOOL bRight ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 return pAttrArray->HasLines( nRow1, nRow2, rSizes, bLeft, bRight );
+//UNUSED2009-05 }
+
+
+bool ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const
+{
+ return pAttrArray->HasAttrib( nRow1, nRow2, nMask );
+}
+
+
+BOOL ScColumn::HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const
+{
+ BOOL bFound = FALSE;
+
+ SCROW nTop;
+ SCROW nBottom;
+
+ if (rMark.IsMultiMarked())
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
+ while (aMarkIter.Next( nTop, nBottom ) && !bFound)
+ {
+ if (pAttrArray->HasAttrib( nTop, nBottom, nMask ))
+ bFound = TRUE;
+ }
+ }
+
+ return bFound;
+}
+
+
+BOOL ScColumn::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
+ SCCOL& rPaintCol, SCROW& rPaintRow,
+ BOOL bRefresh, BOOL bAttrs )
+{
+ return pAttrArray->ExtendMerge( nThisCol, nStartRow, nEndRow, rPaintCol, rPaintRow, bRefresh, bAttrs );
+}
+
+
+void ScColumn::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const
+{
+ SCROW nTop;
+ SCROW nBottom;
+
+ if ( rMark.IsMultiMarked() )
+ {
+ const ScMarkArray* pArray = rMark.GetArray() + nCol;
+ if ( pArray->HasMarks() )
+ {
+ ScMarkArrayIter aMarkIter( pArray );
+ while (aMarkIter.Next( nTop, nBottom ))
+ pAttrArray->MergePatternArea( nTop, nBottom, rState, bDeep );
+ }
+ }
+}
+
+
+void ScColumn::MergePatternArea( ScMergePatternState& rState, SCROW nRow1, SCROW nRow2, BOOL bDeep ) const
+{
+ pAttrArray->MergePatternArea( nRow1, nRow2, rState, bDeep );
+}
+
+
+void ScColumn::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
+ ScLineFlags& rFlags,
+ SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight ) const
+{
+ pAttrArray->MergeBlockFrame( pLineOuter, pLineInner, rFlags, nStartRow, nEndRow, bLeft, nDistRight );
+}
+
+
+void ScColumn::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
+ SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight )
+{
+ pAttrArray->ApplyBlockFrame( pLineOuter, pLineInner, nStartRow, nEndRow, bLeft, nDistRight );
+}
+
+
+const ScPatternAttr* ScColumn::GetPattern( SCROW nRow ) const
+{
+ return pAttrArray->GetPattern( nRow );
+}
+
+
+const SfxPoolItem* ScColumn::GetAttr( SCROW nRow, USHORT nWhich ) const
+{
+ return &pAttrArray->GetPattern( nRow )->GetItemSet().Get(nWhich);
+}
+
+
+const ScPatternAttr* ScColumn::GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const
+{
+ ::std::map< const ScPatternAttr*, size_t > aAttrMap;
+ const ScPatternAttr* pMaxPattern = 0;
+ size_t nMaxCount = 0;
+
+ ScAttrIterator aAttrIter( pAttrArray, nStartRow, nEndRow );
+ const ScPatternAttr* pPattern;
+ SCROW nAttrRow1 = 0, nAttrRow2 = 0;
+
+ while( (pPattern = aAttrIter.Next( nAttrRow1, nAttrRow2 )) != 0 )
+ {
+ size_t& rnCount = aAttrMap[ pPattern ];
+ rnCount += (nAttrRow2 - nAttrRow1 + 1);
+ if( rnCount > nMaxCount )
+ {
+ pMaxPattern = pPattern;
+ nMaxCount = rnCount;
+ }
+ }
+
+ return pMaxPattern;
+}
+
+
+ULONG ScColumn::GetNumberFormat( SCROW nRow ) const
+{
+ return pAttrArray->GetPattern( nRow )->GetNumberFormat( pDocument->GetFormatTable() );
+}
+
+
+SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark )
+{
+ SCROW nTop = 0;
+ SCROW nBottom = 0;
+ BOOL bFound = FALSE;
+
+ if ( rMark.IsMultiMarked() )
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
+ while (aMarkIter.Next( nTop, nBottom ))
+ {
+ pAttrArray->ApplyCacheArea( nTop, nBottom, pCache );
+ bFound = TRUE;
+ }
+ }
+
+ if (!bFound)
+ return -1;
+ else if (nTop==0 && nBottom==MAXROW)
+ return 0;
+ else
+ return nBottom;
+}
+
+
+void ScColumn::ChangeSelectionIndent( BOOL bIncrement, const ScMarkData& rMark )
+{
+ SCROW nTop;
+ SCROW nBottom;
+
+ if ( pAttrArray && rMark.IsMultiMarked() )
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
+ while (aMarkIter.Next( nTop, nBottom ))
+ pAttrArray->ChangeIndent(nTop, nBottom, bIncrement);
+ }
+}
+
+
+void ScColumn::ClearSelectionItems( const USHORT* pWhich,const ScMarkData& rMark )
+{
+ SCROW nTop;
+ SCROW nBottom;
+
+ if ( pAttrArray && rMark.IsMultiMarked() )
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
+ while (aMarkIter.Next( nTop, nBottom ))
+ pAttrArray->ClearItems(nTop, nBottom, pWhich);
+ }
+}
+
+
+void ScColumn::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
+{
+ SCROW nTop;
+ SCROW nBottom;
+
+ if ( rMark.IsMultiMarked() )
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
+ while (aMarkIter.Next( nTop, nBottom ))
+ DeleteArea(nTop, nBottom, nDelFlag);
+ }
+}
+
+
+void ScColumn::ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr )
+{
+ const SfxItemSet* pSet = &rPatAttr.GetItemSet();
+ SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
+
+ const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
+
+ // TRUE = alten Eintrag behalten
+
+ ScPatternAttr* pNewPattern = (ScPatternAttr*) &aCache.ApplyTo( *pPattern, TRUE );
+ ScDocumentPool::CheckRef( *pPattern );
+ ScDocumentPool::CheckRef( *pNewPattern );
+
+ if (pNewPattern != pPattern)
+ pAttrArray->SetPattern( nRow, pNewPattern );
+}
+
+
+void ScColumn::ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr )
+{
+ const SfxItemSet* pSet = &rPatAttr.GetItemSet();
+ SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
+ pAttrArray->ApplyCacheArea( nStartRow, nEndRow, &aCache );
+}
+
+
+void ScColumn::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
+ const ScPatternAttr& rPattern, short nNewType )
+{
+ const SfxItemSet* pSet = &rPattern.GetItemSet();
+ SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ SCROW nEndRow = rRange.aEnd.Row();
+ for ( SCROW nRow = rRange.aStart.Row(); nRow <= nEndRow; nRow++ )
+ {
+ SCROW nRow1, nRow2;
+ const ScPatternAttr* pPattern = pAttrArray->GetPatternRange(
+ nRow1, nRow2, nRow );
+ ULONG nFormat = pPattern->GetNumberFormat( pFormatter );
+ short nOldType = pFormatter->GetType( nFormat );
+ if ( nOldType == nNewType || pFormatter->IsCompatible( nOldType, nNewType ) )
+ nRow = nRow2;
+ else
+ {
+ SCROW nNewRow1 = Max( nRow1, nRow );
+ SCROW nNewRow2 = Min( nRow2, nEndRow );
+ pAttrArray->ApplyCacheArea( nNewRow1, nNewRow2, &aCache );
+ nRow = nNewRow2;
+ }
+ }
+}
+
+
+void ScColumn::ApplyStyle( SCROW nRow, const ScStyleSheet& rStyle )
+{
+ const ScPatternAttr* pPattern = pAttrArray->GetPattern(nRow);
+ ScPatternAttr* pNewPattern = new ScPatternAttr(*pPattern);
+ if (pNewPattern)
+ {
+ pNewPattern->SetStyleSheet((ScStyleSheet*)&rStyle);
+ pAttrArray->SetPattern(nRow, pNewPattern, TRUE);
+ delete pNewPattern;
+ }
+}
+
+
+void ScColumn::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle )
+{
+ pAttrArray->ApplyStyleArea(nStartRow, nEndRow, (ScStyleSheet*)&rStyle);
+}
+
+
+void ScColumn::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
+{
+ SCROW nTop;
+ SCROW nBottom;
+
+ if ( rMark.IsMultiMarked() )
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
+ while (aMarkIter.Next( nTop, nBottom ))
+ pAttrArray->ApplyStyleArea(nTop, nBottom, (ScStyleSheet*)&rStyle);
+ }
+}
+
+
+void ScColumn::ApplySelectionLineStyle( const ScMarkData& rMark,
+ const SvxBorderLine* pLine, BOOL bColorOnly )
+{
+ if ( bColorOnly && !pLine )
+ return;
+
+ SCROW nTop;
+ SCROW nBottom;
+
+ if (rMark.IsMultiMarked())
+ {
+ ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
+ while (aMarkIter.Next( nTop, nBottom ))
+ pAttrArray->ApplyLineStyleArea(nTop, nBottom, pLine, bColorOnly );
+ }
+}
+
+
+const ScStyleSheet* ScColumn::GetStyle( SCROW nRow ) const
+{
+ return pAttrArray->GetPattern( nRow )->GetStyleSheet();
+}
+
+
+const ScStyleSheet* ScColumn::GetSelectionStyle( const ScMarkData& rMark, BOOL& rFound ) const
+{
+ rFound = FALSE;
+ if (!rMark.IsMultiMarked())
+ {
+ DBG_ERROR("ScColumn::GetSelectionStyle ohne Selektion");
+ return NULL;
+ }
+
+ BOOL bEqual = TRUE;
+
+ const ScStyleSheet* pStyle = NULL;
+ const ScStyleSheet* pNewStyle;
+
+ ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
+ SCROW nTop;
+ SCROW nBottom;
+ while (bEqual && aMarkIter.Next( nTop, nBottom ))
+ {
+ ScAttrIterator aAttrIter( pAttrArray, nTop, nBottom );
+ SCROW nRow;
+ SCROW nDummy;
+ const ScPatternAttr* pPattern;
+ while (bEqual && ( pPattern = aAttrIter.Next( nRow, nDummy ) ) != NULL)
+ {
+ pNewStyle = pPattern->GetStyleSheet();
+ rFound = TRUE;
+ if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
+ bEqual = FALSE; // unterschiedliche
+ pStyle = pNewStyle;
+ }
+ }
+
+ return bEqual ? pStyle : NULL;
+}
+
+
+const ScStyleSheet* ScColumn::GetAreaStyle( BOOL& rFound, SCROW nRow1, SCROW nRow2 ) const
+{
+ rFound = FALSE;
+
+ BOOL bEqual = TRUE;
+
+ const ScStyleSheet* pStyle = NULL;
+ const ScStyleSheet* pNewStyle;
+
+ ScAttrIterator aAttrIter( pAttrArray, nRow1, nRow2 );
+ SCROW nRow;
+ SCROW nDummy;
+ const ScPatternAttr* pPattern;
+ while (bEqual && ( pPattern = aAttrIter.Next( nRow, nDummy ) ) != NULL)
+ {
+ pNewStyle = pPattern->GetStyleSheet();
+ rFound = TRUE;
+ if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
+ bEqual = FALSE; // unterschiedliche
+ pStyle = pNewStyle;
+ }
+
+ return bEqual ? pStyle : NULL;
+}
+
+void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
+{
+ pAttrArray->FindStyleSheet( pStyleSheet, rUsedRows, bReset );
+}
+
+BOOL ScColumn::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
+{
+ return pAttrArray->IsStyleSheetUsed( rStyle, bGatherAllStyles );
+}
+
+
+BOOL ScColumn::ApplyFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags )
+{
+ return pAttrArray->ApplyFlags( nStartRow, nEndRow, nFlags );
+}
+
+
+BOOL ScColumn::RemoveFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags )
+{
+ return pAttrArray->RemoveFlags( nStartRow, nEndRow, nFlags );
+}
+
+
+void ScColumn::ClearItems( SCROW nStartRow, SCROW nEndRow, const USHORT* pWhich )
+{
+ pAttrArray->ClearItems( nStartRow, nEndRow, pWhich );
+}
+
+
+void ScColumn::SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr, BOOL bPutToPool )
+{
+ pAttrArray->SetPattern( nRow, &rPatAttr, bPutToPool );
+}
+
+
+void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow,
+ const ScPatternAttr& rPatAttr, BOOL bPutToPool )
+{
+ pAttrArray->SetPatternArea( nStartRow, nEndRow, &rPatAttr, bPutToPool );
+}
+
+
+void ScColumn::ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr )
+{
+ // um nur ein neues SetItem zu erzeugen, brauchen wir keinen SfxItemPoolCache.
+ //! Achtung: der SfxItemPoolCache scheint zuviele Refs fuer das neue SetItem zu erzeugen ??
+
+ ScDocumentPool* pDocPool = pDocument->GetPool();
+
+ const ScPatternAttr* pOldPattern = pAttrArray->GetPattern( nRow );
+ ScPatternAttr* pTemp = new ScPatternAttr(*pOldPattern);
+ pTemp->GetItemSet().Put(rAttr);
+ const ScPatternAttr* pNewPattern = (const ScPatternAttr*) &pDocPool->Put( *pTemp );
+
+ if ( pNewPattern != pOldPattern )
+ pAttrArray->SetPattern( nRow, pNewPattern );
+ else
+ pDocPool->Remove( *pNewPattern ); // ausser Spesen nichts gewesen
+
+ delete pTemp;
+
+ // alte Version mit SfxItemPoolCache:
+#if 0
+ SfxItemPoolCache aCache( pDocument->GetPool(), &rAttr );
+
+ const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
+
+ // TRUE = alten Eintrag behalten
+
+ ScPatternAttr* pNewPattern = (ScPatternAttr*) &aCache.ApplyTo( *pPattern, TRUE );
+ ScDocumentPool::CheckRef( *pPattern );
+ ScDocumentPool::CheckRef( *pNewPattern );
+
+ if (pNewPattern != pPattern)
+ pAttrArray->SetPattern( nRow, pNewPattern );
+#endif
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+
+BOOL ScColumn::Search( SCROW nRow, SCSIZE& nIndex ) const
+{
+ if ( !pItems || !nCount )
+ {
+ nIndex = 0;
+ return FALSE;
+ }
+ SCROW nMinRow = pItems[0].nRow;
+ if ( nRow <= nMinRow )
+ {
+ nIndex = 0;
+ return nRow == nMinRow;
+ }
+ SCROW nMaxRow = pItems[nCount-1].nRow;
+ if ( nRow >= nMaxRow )
+ {
+ if ( nRow == nMaxRow )
+ {
+ nIndex = nCount - 1;
+ return TRUE;
+ }
+ else
+ {
+ nIndex = nCount;
+ return FALSE;
+ }
+ }
+
+ long nOldLo, nOldHi;
+ long nLo = nOldLo = 0;
+ long nHi = nOldHi = Min(static_cast<long>(nCount)-1, static_cast<long>(nRow) );
+ long i = 0;
+ BOOL bFound = FALSE;
+ // quite continuous distribution? => interpolating search
+ BOOL bInterpol = (static_cast<SCSIZE>(nMaxRow - nMinRow) < nCount * 2);
+ SCROW nR;
+
+ while ( !bFound && nLo <= nHi )
+ {
+ if ( !bInterpol || nHi - nLo < 3 )
+ i = (nLo+nHi) / 2; // no effort, no division by zero
+ else
+ { // interpolating search
+ long nLoRow = pItems[nLo].nRow; // no unsigned underflow upon substraction
+ i = nLo + (long)((long)(nRow - nLoRow) * (nHi - nLo)
+ / (pItems[nHi].nRow - nLoRow));
+ if ( i < 0 || static_cast<SCSIZE>(i) >= nCount )
+ { // oops ...
+ i = (nLo+nHi) / 2;
+ bInterpol = FALSE;
+ }
+ }
+ nR = pItems[i].nRow;
+ if ( nR < nRow )
+ {
+ nLo = i+1;
+ if ( bInterpol )
+ {
+ if ( nLo <= nOldLo )
+ bInterpol = FALSE;
+ else
+ nOldLo = nLo;
+ }
+ }
+ else
+ {
+ if ( nR > nRow )
+ {
+ nHi = i-1;
+ if ( bInterpol )
+ {
+ if ( nHi >= nOldHi )
+ bInterpol = FALSE;
+ else
+ nOldHi = nHi;
+ }
+ }
+ else
+ bFound = TRUE;
+ }
+ }
+ if (bFound)
+ nIndex = static_cast<SCSIZE>(i);
+ else
+ nIndex = static_cast<SCSIZE>(nLo); // rear index
+ return bFound;
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+
+ScBaseCell* ScColumn::GetCell( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ return pItems[nIndex].pCell;
+ return NULL;
+}
+
+
+void ScColumn::Resize( SCSIZE nSize )
+{
+ if (nSize > sal::static_int_cast<SCSIZE>(MAXROWCOUNT))
+ nSize = MAXROWCOUNT;
+ if (nSize < nCount)
+ nSize = nCount;
+
+ ColEntry* pNewItems;
+ if (nSize)
+ {
+ SCSIZE nNewSize = nSize + COLUMN_DELTA - 1;
+ nNewSize -= nNewSize % COLUMN_DELTA;
+ nLimit = nNewSize;
+ pNewItems = new ColEntry[nLimit];
+ }
+ else
+ {
+ nLimit = 0;
+ pNewItems = NULL;
+ }
+ if (pItems)
+ {
+ if (pNewItems)
+ memmove( pNewItems, pItems, nCount * sizeof(ColEntry) );
+ delete[] pItems;
+ }
+ pItems = pNewItems;
+}
+
+// SwapRow zum Sortieren
+
+namespace {
+
+/** Moves broadcaster from old cell to new cell if exists, otherwise creates a new note cell. */
+void lclTakeBroadcaster( ScBaseCell*& rpCell, SvtBroadcaster* pBC )
+{
+ if( pBC )
+ {
+ if( rpCell )
+ rpCell->TakeBroadcaster( pBC );
+ else
+ rpCell = new ScNoteCell( pBC );
+ }
+}
+
+} // namespace
+
+void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
+{
+ /* Simple swap of cell pointers does not work if broadcasters exist (crash
+ if cell broadcasts directly or indirectly to itself). While swapping
+ the cells, broadcasters have to remain at old positions! */
+
+ /* While cloning cells, do not clone notes, but move note pointers to new
+ cells. This prevents creation of new caption drawing objects for every
+ swap operation while sorting. */
+
+ ScBaseCell* pCell1 = 0;
+ SCSIZE nIndex1;
+ if ( Search( nRow1, nIndex1 ) )
+ pCell1 = pItems[nIndex1].pCell;
+
+ ScBaseCell* pCell2 = 0;
+ SCSIZE nIndex2;
+ if ( Search( nRow2, nIndex2 ) )
+ pCell2 = pItems[nIndex2].pCell;
+
+ // no cells found, nothing to do
+ if ( !pCell1 && !pCell2 )
+ return ;
+
+ // swap variables if first cell is empty, to save some code below
+ if ( !pCell1 )
+ {
+ ::std::swap( nRow1, nRow2 );
+ ::std::swap( nIndex1, nIndex2 );
+ ::std::swap( pCell1, pCell2 );
+ }
+
+ // from here: first cell (pCell1, nIndex1) exists always
+
+ ScAddress aPos1( nCol, nRow1, nTab );
+ ScAddress aPos2( nCol, nRow2, nTab );
+
+ CellType eType1 = pCell1->GetCellType();
+ CellType eType2 = pCell2 ? pCell2->GetCellType() : CELLTYPE_NONE;
+
+ ScFormulaCell* pFmlaCell1 = (eType1 == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell1 ) : 0;
+ ScFormulaCell* pFmlaCell2 = (eType2 == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell2 ) : 0;
+
+ // simple swap if no formula cells present
+ if ( !pFmlaCell1 && !pFmlaCell2 )
+ {
+ // remember cell broadcasters, must remain at old position
+ SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
+
+ if ( pCell2 )
+ {
+ /* Both cells exist, no formula cells involved, a simple swap can
+ be performed (but keep broadcasters and notes at old position). */
+ pItems[nIndex1].pCell = pCell2;
+ pItems[nIndex2].pCell = pCell1;
+
+ SvtBroadcaster* pBC2 = pCell2->ReleaseBroadcaster();
+ pCell1->TakeBroadcaster( pBC2 );
+ pCell2->TakeBroadcaster( pBC1 );
+ }
+ else
+ {
+ ScNoteCell* pDummyCell = pBC1 ? new ScNoteCell( pBC1 ) : 0;
+ if ( pDummyCell )
+ {
+ // insert dummy note cell (without note) containing old broadcaster
+ pItems[nIndex1].pCell = pDummyCell;
+ }
+ else
+ {
+ // remove ColEntry at old position
+ --nCount;
+ memmove( &pItems[nIndex1], &pItems[nIndex1 + 1], (nCount - nIndex1) * sizeof(ColEntry) );
+ pItems[nCount].nRow = 0;
+ pItems[nCount].pCell = 0;
+ }
+
+ // insert ColEntry at new position
+ Insert( nRow2, pCell1 );
+ }
+
+ return;
+ }
+
+ // from here: at least one of the cells is a formula cell
+
+ /* Never move any array formulas. Disabling sort if parts of array
+ formulas are contained is done at UI. */
+ if ( (pFmlaCell1 && (pFmlaCell1->GetMatrixFlag() != 0)) || (pFmlaCell2 && (pFmlaCell2->GetMatrixFlag() != 0)) )
+ return;
+
+ // do not swap, if formulas are equal
+ if ( pFmlaCell1 && pFmlaCell2 )
+ {
+ ScTokenArray* pCode1 = pFmlaCell1->GetCode();
+ ScTokenArray* pCode2 = pFmlaCell2->GetCode();
+
+ if (pCode1->GetLen() == pCode2->GetLen()) // nicht-UPN
+ {
+ BOOL bEqual = TRUE;
+ USHORT nLen = pCode1->GetLen();
+ FormulaToken** ppToken1 = pCode1->GetArray();
+ FormulaToken** ppToken2 = pCode2->GetArray();
+ for (USHORT i=0; i<nLen; i++)
+ {
+ if ( !ppToken1[i]->TextEqual(*(ppToken2[i])) ||
+ ppToken1[i]->Is3DRef() || ppToken2[i]->Is3DRef() )
+ {
+ bEqual = FALSE;
+ break;
+ }
+ }
+
+ // do not swap formula cells with equal formulas, but swap notes
+ if (bEqual)
+ {
+ ScPostIt* pNote1 = pCell1->ReleaseNote();
+ pCell1->TakeNote( pCell2->ReleaseNote() );
+ pCell2->TakeNote( pNote1 );
+ return;
+ }
+ }
+ }
+
+ // hier kein UpdateReference wegen #30529# - mitsortiert werden nur noch relative Referenzen
+// long dy = (long)nRow2 - (long)nRow1;
+
+ /* Create clone of pCell1 at position of pCell2 (pCell1 exists always, see
+ variable swapping above). Do not clone the note, but move pointer of
+ old note to new cell. */
+ ScBaseCell* pNew2 = pCell1->CloneWithoutNote( *pDocument, aPos2, SC_CLONECELL_ADJUST3DREL );
+ pNew2->TakeNote( pCell1->ReleaseNote() );
+
+ /* Create clone of pCell2 at position of pCell1. Do not clone the note,
+ but move pointer of old note to new cell. */
+ ScBaseCell* pNew1 = 0;
+ if ( pCell2 )
+ {
+ pNew1 = pCell2->CloneWithoutNote( *pDocument, aPos1, SC_CLONECELL_ADJUST3DREL );
+ pNew1->TakeNote( pCell2->ReleaseNote() );
+ }
+
+ // move old broadcasters new cells at the same old position
+ SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
+ lclTakeBroadcaster( pNew1, pBC1 );
+ SvtBroadcaster* pBC2 = pCell2 ? pCell2->ReleaseBroadcaster() : 0;
+ lclTakeBroadcaster( pNew2, pBC2 );
+
+ /* Insert the new cells. Old cell has to be deleted, if there is no new
+ cell (call to Insert deletes old cell by itself). */
+ if ( !pNew1 )
+ Delete( nRow1 ); // deletes pCell1
+ else
+ Insert( nRow1, pNew1 ); // deletes pCell1, inserts pNew1
+
+ if ( pCell2 && !pNew2 )
+ Delete( nRow2 ); // deletes pCell2
+ else if ( pNew2 )
+ Insert( nRow2, pNew2 ); // deletes pCell2 (if existing), inserts pNew2
+}
+
+
+void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
+{
+ ScBaseCell* pCell1 = 0;
+ SCSIZE nIndex1;
+ if ( Search( nRow, nIndex1 ) )
+ pCell1 = pItems[nIndex1].pCell;
+
+ ScBaseCell* pCell2 = 0;
+ SCSIZE nIndex2;
+ if ( rCol.Search( nRow, nIndex2 ) )
+ pCell2 = rCol.pItems[nIndex2].pCell;
+
+ // reverse call if own cell is missing (ensures own existing cell in following code)
+ if( !pCell1 )
+ {
+ if( pCell2 )
+ rCol.SwapCell( nRow, *this );
+ return;
+ }
+
+ // from here: own cell (pCell1, nIndex1) exists always
+
+ ScFormulaCell* pFmlaCell1 = (pCell1->GetCellType() == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell1 ) : 0;
+ ScFormulaCell* pFmlaCell2 = (pCell2 && (pCell2->GetCellType() == CELLTYPE_FORMULA)) ? static_cast< ScFormulaCell* >( pCell2 ) : 0;
+
+ if ( pCell2 )
+ {
+ // Tauschen
+ pItems[nIndex1].pCell = pCell2;
+ rCol.pItems[nIndex2].pCell = pCell1;
+ // Referenzen aktualisieren
+ SCsCOL dx = rCol.nCol - nCol;
+ if ( pFmlaCell1 )
+ {
+ ScRange aRange( ScAddress( rCol.nCol, 0, nTab ),
+ ScAddress( rCol.nCol, MAXROW, nTab ) );
+ pFmlaCell1->aPos.SetCol( rCol.nCol );
+ pFmlaCell1->UpdateReference(URM_MOVE, aRange, dx, 0, 0);
+ }
+ if ( pFmlaCell2 )
+ {
+ ScRange aRange( ScAddress( nCol, 0, nTab ),
+ ScAddress( nCol, MAXROW, nTab ) );
+ pFmlaCell2->aPos.SetCol( nCol );
+ pFmlaCell2->UpdateReference(URM_MOVE, aRange, -dx, 0, 0);
+ }
+ }
+ else
+ {
+ // Loeschen
+ --nCount;
+ memmove( &pItems[nIndex1], &pItems[nIndex1 + 1], (nCount - nIndex1) * sizeof(ColEntry) );
+ pItems[nCount].nRow = 0;
+ pItems[nCount].pCell = 0;
+ // Referenzen aktualisieren
+ SCsCOL dx = rCol.nCol - nCol;
+ if ( pFmlaCell1 )
+ {
+ ScRange aRange( ScAddress( rCol.nCol, 0, nTab ),
+ ScAddress( rCol.nCol, MAXROW, nTab ) );
+ pFmlaCell1->aPos.SetCol( rCol.nCol );
+ pFmlaCell1->UpdateReference(URM_MOVE, aRange, dx, 0, 0);
+ }
+ // Einfuegen
+ rCol.Insert(nRow, pCell1);
+ }
+}
+
+
+BOOL ScColumn::TestInsertCol( SCROW nStartRow, SCROW nEndRow) const
+{
+ if (!IsEmpty())
+ {
+ BOOL bTest = TRUE;
+ if (pItems)
+ for (SCSIZE i=0; (i<nCount) && bTest; i++)
+ bTest = (pItems[i].nRow < nStartRow) || (pItems[i].nRow > nEndRow)
+ || pItems[i].pCell->IsBlank();
+
+ // AttrArray testet nur zusammengefasste
+
+ if ((bTest) && (pAttrArray))
+ bTest = pAttrArray->TestInsertCol(nStartRow, nEndRow);
+
+ //! rausgeschobene Attribute bei Undo beruecksichtigen
+
+ return bTest;
+ }
+ else
+ return TRUE;
+}
+
+
+BOOL ScColumn::TestInsertRow( SCSIZE nSize ) const
+{
+ // AttrArray only looks for merged cells
+
+ if ( pItems && nCount )
+ return ( nSize <= sal::static_int_cast<SCSIZE>(MAXROW) &&
+ pItems[nCount-1].nRow <= MAXROW-(SCROW)nSize && pAttrArray->TestInsertRow( nSize ) );
+ else
+ return pAttrArray->TestInsertRow( nSize );
+
+#if 0
+ //! rausgeschobene Attribute bei Undo beruecksichtigen
+
+ if ( nSize > static_cast<SCSIZE>(MAXROW) )
+ return FALSE;
+
+ SCSIZE nVis = nCount;
+ while ( nVis && pItems[nVis-1].pCell->IsBlank() )
+ --nVis;
+
+ if ( nVis )
+ return ( pItems[nVis-1].nRow <= MAXROW-nSize );
+ else
+ return TRUE;
+#endif
+}
+
+
+void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
+{
+ pAttrArray->InsertRow( nStartRow, nSize );
+
+ //! Search
+
+ if ( !pItems || !nCount )
+ return;
+
+ SCSIZE i;
+ Search( nStartRow, i );
+ if ( i >= nCount )
+ return ;
+
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+
+ SCSIZE nNewCount = nCount;
+ BOOL bCountChanged = FALSE;
+ ScAddress aAdr( nCol, 0, nTab );
+ ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)
+ ScAddress& rAddress = aHint.GetAddress();
+ // for sparse occupation use single broadcasts, not ranges
+ BOOL bSingleBroadcasts = (((pItems[nCount-1].nRow - pItems[i].nRow) /
+ (nCount - i)) > 1);
+ if ( bSingleBroadcasts )
+ {
+ SCROW nLastBroadcast = MAXROW+1;
+ for ( ; i < nCount; i++)
+ {
+ SCROW nOldRow = pItems[i].nRow;
+ // #43940# Aenderung Quelle broadcasten
+ if ( nLastBroadcast != nOldRow )
+ { // direkt aufeinanderfolgende nicht doppelt broadcasten
+ rAddress.SetRow( nOldRow );
+ pDocument->AreaBroadcast( aHint );
+ }
+ SCROW nNewRow = (pItems[i].nRow += nSize);
+ // #43940# Aenderung Ziel broadcasten
+ rAddress.SetRow( nNewRow );
+ pDocument->AreaBroadcast( aHint );
+ nLastBroadcast = nNewRow;
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
+ if ( nNewRow > MAXROW && !bCountChanged )
+ {
+ nNewCount = i;
+ bCountChanged = TRUE;
+ }
+ }
+ }
+ else
+ {
+ rAddress.SetRow( pItems[i].nRow );
+ ScRange aRange( rAddress );
+ for ( ; i < nCount; i++)
+ {
+ SCROW nNewRow = (pItems[i].nRow += nSize);
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
+ if ( nNewRow > MAXROW && !bCountChanged )
+ {
+ nNewCount = i;
+ bCountChanged = TRUE;
+ aRange.aEnd.SetRow( MAXROW );
+ }
+ }
+ if ( !bCountChanged )
+ aRange.aEnd.SetRow( pItems[nCount-1].nRow );
+ pDocument->AreaBroadcastInRange( aRange, aHint );
+ }
+
+ if (bCountChanged)
+ {
+ SCSIZE nDelCount = nCount - nNewCount;
+ ScBaseCell** ppDelCells = new ScBaseCell*[nDelCount];
+ SCROW* pDelRows = new SCROW[nDelCount];
+ for (i = 0; i < nDelCount; i++)
+ {
+ ppDelCells[i] = pItems[nNewCount+i].pCell;
+ pDelRows[i] = pItems[nNewCount+i].nRow;
+ }
+ nCount = nNewCount;
+
+ for (i = 0; i < nDelCount; i++)
+ {
+ ScBaseCell* pCell = ppDelCells[i];
+ DBG_ASSERT( pCell->IsBlank(), "sichtbare Zelle weggeschoben" );
+ SvtBroadcaster* pBC = pCell->GetBroadcaster();
+ if (pBC)
+ {
+ MoveListeners( *pBC, pDelRows[i] - nSize );
+ pCell->DeleteBroadcaster();
+ pCell->Delete();
+ }
+ }
+
+ delete [] pDelRows;
+ delete [] ppDelCells;
+ }
+
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, BOOL bKeepScenarioFlags, BOOL bCloneNoteCaptions)
+{
+ pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray,
+ bKeepScenarioFlags ? (SC_MF_ALL & ~SC_MF_SCENARIO) : SC_MF_ALL );
+
+ SCSIZE i;
+ SCSIZE nBlockCount = 0;
+ SCSIZE nStartIndex = 0, nEndIndex = 0;
+ for (i = 0; i < nCount; i++)
+ if ((pItems[i].nRow >= nRow1) && (pItems[i].nRow <= nRow2))
+ {
+ if (!nBlockCount)
+ nStartIndex = i;
+ nEndIndex = i;
+ ++nBlockCount;
+
+ // im Clipboard muessen interpretierte Zellen stehen, um andere Formate
+ // (Text, Grafik...) erzueugen zu koennen
+
+ if ( pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pItems[i].pCell;
+ if (pFCell->GetDirty() && pDocument->GetAutoCalc())
+ pFCell->Interpret();
+ }
+ }
+
+ if (nBlockCount)
+ {
+ int nCloneFlags = bCloneNoteCaptions ? SC_CLONECELL_DEFAULT : SC_CLONECELL_NOCAPTION;
+ rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
+ ScAddress aOwnPos( nCol, 0, nTab );
+ ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
+ for (i = nStartIndex; i <= nEndIndex; i++)
+ {
+ 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 );
+ }
+ }
+}
+
+
+void ScColumn::CopyToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarked,
+ ScColumn& rColumn, const ScMarkData* pMarkData, BOOL bAsLink )
+{
+ if (bMarked)
+ {
+ SCROW nStart, nEnd;
+ if (pMarkData && pMarkData->IsMultiMarked())
+ {
+ ScMarkArrayIter aIter( pMarkData->GetArray()+nCol );
+
+ while ( aIter.Next( nStart, nEnd ) && nStart <= nRow2 )
+ {
+ if ( nEnd >= nRow1 )
+ CopyToColumn( Max(nRow1,nStart), Min(nRow2,nEnd),
+ nFlags, FALSE, rColumn, pMarkData, bAsLink );
+ }
+ }
+ else
+ {
+ DBG_ERROR("CopyToColumn: bMarked, aber keine Markierung");
+ }
+ return;
+ }
+
+ if ( (nFlags & IDF_ATTRIB) != 0 )
+ {
+ if ( (nFlags & IDF_STYLES) != IDF_STYLES )
+ { // StyleSheets im Zieldokument bleiben erhalten
+ // z.B. DIF und RTF Clipboard-Import
+ for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
+ {
+ const ScStyleSheet* pStyle =
+ rColumn.pAttrArray->GetPattern( nRow )->GetStyleSheet();
+ const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
+ ScPatternAttr* pNewPattern = new ScPatternAttr( *pPattern );
+ pNewPattern->SetStyleSheet( (ScStyleSheet*)pStyle );
+ rColumn.pAttrArray->SetPattern( nRow, pNewPattern, TRUE );
+ delete pNewPattern;
+ }
+ }
+ else
+ pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray);
+ }
+
+
+ if ((nFlags & IDF_CONTENTS) != 0)
+ {
+ SCSIZE i;
+ SCSIZE nBlockCount = 0;
+ SCSIZE nStartIndex = 0, nEndIndex = 0;
+ for (i = 0; i < nCount; i++)
+ if ((pItems[i].nRow >= nRow1) && (pItems[i].nRow <= nRow2))
+ {
+ if (!nBlockCount)
+ nStartIndex = i;
+ nEndIndex = i;
+ ++nBlockCount;
+ }
+
+ if (nBlockCount)
+ {
+ rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
+ ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
+ for (i = nStartIndex; i <= nEndIndex; i++)
+ {
+ aDestPos.SetRow( pItems[i].nRow );
+ ScBaseCell* pNew = bAsLink ?
+ CreateRefCell( rColumn.pDocument, aDestPos, i, nFlags ) :
+ CloneCell( i, nFlags, *rColumn.pDocument, aDestPos );
+
+ if (pNew)
+ rColumn.Insert(pItems[i].nRow, pNew);
+ }
+ }
+ }
+}
+
+
+void ScColumn::UndoToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarked,
+ ScColumn& rColumn, const ScMarkData* pMarkData )
+{
+ if (nRow1 > 0)
+ CopyToColumn( 0, nRow1-1, IDF_FORMULA, FALSE, rColumn );
+
+ CopyToColumn( nRow1, nRow2, nFlags, bMarked, rColumn, pMarkData ); //! bMarked ????
+
+ if (nRow2 < MAXROW)
+ CopyToColumn( nRow2+1, MAXROW, IDF_FORMULA, FALSE, rColumn );
+}
+
+
+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++)
+ {
+ aOwnPos.SetRow( rPosCol.pItems[nPosIndex].nRow );
+ aDestPos.SetRow( aOwnPos.Row() );
+ SCSIZE nThisIndex;
+ if ( Search( aDestPos.Row(), nThisIndex ) )
+ {
+ ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( aOwnPos, rDestDoc, aDestPos );
+ rDestCol.Insert( aDestPos.Row(), pNew );
+ }
+ }
+
+ // Dummy:
+ // CopyToColumn( 0,MAXROW, IDF_FORMULA, FALSE, rDestCol, NULL, FALSE );
+}
+
+
+void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
+{
+ // Dies ist die Szenario-Tabelle, die Daten werden hineinkopiert
+
+ ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
+ SCROW nStart = -1, nEnd = -1;
+ const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
+ while (pPattern)
+ {
+ if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
+ {
+ DeleteArea( nStart, nEnd, IDF_CONTENTS );
+ ((ScColumn&)rSrcCol).
+ CopyToColumn( nStart, nEnd, IDF_CONTENTS, FALSE, *this );
+
+ // UpdateUsed nicht noetig, schon in TestCopyScenario passiert
+
+ SCsTAB nDz = nTab - rSrcCol.nTab;
+ UpdateReference(URM_COPY, nCol, nStart, nTab,
+ nCol, nEnd, nTab,
+ 0, 0, nDz, NULL);
+ UpdateCompile();
+ }
+
+ //! CopyToColumn "const" machen !!!
+
+ pPattern = aAttrIter.Next( nStart, nEnd );
+ }
+}
+
+
+void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
+{
+ // Dies ist die Szenario-Tabelle, die Daten werden in die andere kopiert
+
+ ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
+ SCROW nStart = -1, nEnd = -1;
+ const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
+ while (pPattern)
+ {
+ if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
+ {
+ rDestCol.DeleteArea( nStart, nEnd, IDF_CONTENTS );
+ ((ScColumn*)this)->
+ CopyToColumn( nStart, nEnd, IDF_CONTENTS, FALSE, rDestCol );
+
+ // UpdateUsed nicht noetig, schon in TestCopyScenario passiert
+
+ SCsTAB nDz = rDestCol.nTab - nTab;
+ rDestCol.UpdateReference(URM_COPY, rDestCol.nCol, nStart, rDestCol.nTab,
+ rDestCol.nCol, nEnd, rDestCol.nTab,
+ 0, 0, nDz, NULL);
+ rDestCol.UpdateCompile();
+ }
+
+ //! CopyToColumn "const" machen !!!
+
+ pPattern = aAttrIter.Next( nStart, nEnd );
+ }
+}
+
+
+BOOL ScColumn::TestCopyScenarioTo( const ScColumn& rDestCol ) const
+{
+ BOOL bOk = TRUE;
+ ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
+ SCROW nStart = 0, nEnd = 0;
+ const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
+ while (pPattern && bOk)
+ {
+ if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
+ if ( rDestCol.pAttrArray->HasAttrib( nStart, nEnd, HASATTR_PROTECTED ) )
+ bOk = FALSE;
+
+ pPattern = aAttrIter.Next( nStart, nEnd );
+ }
+ return bOk;
+}
+
+
+void ScColumn::MarkScenarioIn( ScMarkData& rDestMark ) const
+{
+ ScRange aRange( nCol, 0, nTab );
+
+ ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
+ SCROW nStart = -1, nEnd = -1;
+ const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
+ while (pPattern)
+ {
+ if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
+ {
+ aRange.aStart.SetRow( nStart );
+ aRange.aEnd.SetRow( nEnd );
+ rDestMark.SetMultiMarkArea( aRange, TRUE );
+ }
+
+ pPattern = aAttrIter.Next( nStart, nEnd );
+ }
+}
+
+
+void ScColumn::SwapCol(ScColumn& rCol)
+{
+ SCSIZE nTemp;
+
+ nTemp = rCol.nCount;
+ rCol.nCount = nCount;
+ nCount = nTemp;
+
+ nTemp = rCol.nLimit;
+ rCol.nLimit = nLimit;
+ nLimit = nTemp;
+
+ ColEntry* pTempItems = rCol.pItems;
+ rCol.pItems = pItems;
+ pItems = pTempItems;
+
+ ScAttrArray* pTempAttr = rCol.pAttrArray;
+ rCol.pAttrArray = pAttrArray;
+ pAttrArray = pTempAttr;
+
+ // #38415# AttrArray muss richtige Spaltennummer haben
+ pAttrArray->SetCol(nCol);
+ rCol.pAttrArray->SetCol(rCol.nCol);
+
+ SCSIZE i;
+ if (pItems)
+ for (i = 0; i < nCount; i++)
+ {
+ ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ pCell->aPos.SetCol(nCol);
+ }
+ if (rCol.pItems)
+ for (i = 0; i < rCol.nCount; i++)
+ {
+ ScFormulaCell* pCell = (ScFormulaCell*) rCol.pItems[i].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ pCell->aPos.SetCol(rCol.nCol);
+ }
+}
+
+
+void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
+{
+ pAttrArray->MoveTo(nStartRow, nEndRow, *rCol.pAttrArray);
+
+ if (pItems)
+ {
+ ::std::vector<SCROW> aRows;
+ bool bConsecutive = true;
+ SCSIZE i;
+ Search( nStartRow, i); // i points to start row or position thereafter
+ SCSIZE nStartPos = i;
+ for ( ; i < nCount && pItems[i].nRow <= nEndRow; ++i)
+ {
+ SCROW nRow = pItems[i].nRow;
+ aRows.push_back( nRow);
+ rCol.Insert( nRow, pItems[i].pCell);
+ if (nRow != pItems[i].nRow)
+ { // Listener inserted
+ bConsecutive = false;
+ Search( nRow, i);
+ }
+ }
+ SCSIZE nStopPos = i;
+ if (nStartPos < nStopPos)
+ {
+ // Create list of ranges of cell entry positions
+ typedef ::std::pair<SCSIZE,SCSIZE> PosPair;
+ typedef ::std::vector<PosPair> EntryPosPairs;
+ EntryPosPairs aEntries;
+ if (bConsecutive)
+ aEntries.push_back( PosPair(nStartPos, nStopPos));
+ else
+ {
+ bool bFirst = true;
+ nStopPos = 0;
+ for (::std::vector<SCROW>::const_iterator it( aRows.begin());
+ it != aRows.end() && nStopPos < nCount; ++it,
+ ++nStopPos)
+ {
+ if (!bFirst && *it != pItems[nStopPos].nRow)
+ {
+ aEntries.push_back( PosPair(nStartPos, nStopPos));
+ bFirst = true;
+ }
+ if (bFirst && Search( *it, nStartPos))
+ {
+ bFirst = false;
+ nStopPos = nStartPos;
+ }
+ }
+ if (!bFirst && nStartPos < nStopPos)
+ aEntries.push_back( PosPair(nStartPos, nStopPos));
+ }
+ // Broadcast changes
+ ScAddress aAdr( nCol, 0, nTab );
+ ScHint aHint( SC_HINT_DYING, aAdr, NULL ); // areas only
+ ScAddress& rAddress = aHint.GetAddress();
+ ScNoteCell* pNoteCell = new ScNoteCell; // Dummy like in DeleteRange
+
+ // #121990# must iterate backwards, because indexes of following cells become invalid
+ for (EntryPosPairs::reverse_iterator it( aEntries.rbegin());
+ it != aEntries.rend(); ++it)
+ {
+ nStartPos = (*it).first;
+ nStopPos = (*it).second;
+ for (i=nStartPos; i<nStopPos; ++i)
+ pItems[i].pCell = pNoteCell;
+ for (i=nStartPos; i<nStopPos; ++i)
+ {
+ rAddress.SetRow( pItems[i].nRow );
+ pDocument->AreaBroadcast( aHint );
+ }
+ nCount -= nStopPos - nStartPos;
+ memmove( &pItems[nStartPos], &pItems[nStopPos],
+ (nCount - nStartPos) * sizeof(ColEntry) );
+ }
+ delete pNoteCell;
+ pItems[nCount].nRow = 0;
+ pItems[nCount].pCell = NULL;
+ }
+ }
+}
+
+
+void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc )
+{
+ if (pItems)
+ {
+ ScRange aRange( ScAddress( nCol1, nRow1, nTab1 ),
+ ScAddress( nCol2, nRow2, nTab2 ) );
+ if ( eUpdateRefMode == URM_COPY && nRow1 == nRow2 )
+ { // z.B. eine einzelne Zelle aus dem Clipboard eingefuegt
+ SCSIZE nIndex;
+ if ( Search( nRow1, nIndex ) )
+ {
+ ScFormulaCell* pCell = (ScFormulaCell*) pItems[nIndex].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ pCell->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
+ }
+ }
+ else
+ {
+ // #90279# For performance reasons two loop bodies instead of
+ // testing for update mode in each iteration.
+ // Anyways, this is still a bottleneck on large arrays with few
+ // formulas cells.
+ if ( eUpdateRefMode == URM_COPY )
+ {
+ SCSIZE i;
+ Search( nRow1, i );
+ for ( ; i < nCount; i++ )
+ {
+ SCROW nRow = pItems[i].nRow;
+ if ( nRow > nRow2 )
+ break;
+ ScBaseCell* pCell = pItems[i].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener removed/inserted?
+ }
+ }
+ }
+ else
+ {
+ SCSIZE i = 0;
+ for ( ; i < nCount; i++ )
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ SCROW nRow = pItems[i].nRow;
+ // 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?
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
+ ScDocument* pUndoDoc )
+{
+ if (pItems)
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ SCROW nRow = pItems[i].nRow;
+ ((ScFormulaCell*)pCell)->UpdateTranspose( rSource, rDest, pUndoDoc );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
+{
+ if (pItems)
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ SCROW nRow = pItems[i].nRow;
+ ((ScFormulaCell*)pCell)->UpdateGrow( rArea, nGrowX, nGrowY );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::UpdateInsertTab( SCTAB nTable)
+{
+ if (nTab >= nTable)
+ pAttrArray->SetTab(++nTab);
+ if( pItems )
+ UpdateInsertTabOnlyCells( nTable );
+}
+
+
+void ScColumn::UpdateInsertTabOnlyCells( SCTAB nTable)
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ SCROW nRow = pItems[i].nRow;
+ pCell->UpdateInsertTab(nTable);
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::UpdateInsertTabAbs(SCTAB nTable)
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
+ if( pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ SCROW nRow = pItems[i].nRow;
+ pCell->UpdateInsertTabAbs(nTable);
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::UpdateDeleteTab( SCTAB nTable, BOOL bIsMove, ScColumn* pRefUndo )
+{
+ if (nTab > nTable)
+ pAttrArray->SetTab(--nTab);
+
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ if ( pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ SCROW nRow = pItems[i].nRow;
+ ScFormulaCell* pOld = (ScFormulaCell*)pItems[i].pCell;
+
+ /* Do not copy cell note to the undo document. Undo will copy
+ back the formula cell while keeping the original note. */
+ ScBaseCell* pSave = pRefUndo ? pOld->CloneWithoutNote( *pDocument ) : 0;
+
+ BOOL bChanged = pOld->UpdateDeleteTab(nTable, bIsMove);
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+
+ if (pRefUndo)
+ {
+ if (bChanged)
+ pRefUndo->Insert( nRow, pSave );
+ else if(pSave)
+ pSave->Delete();
+ }
+ }
+}
+
+
+void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
+{
+ nTab = nTabNo;
+ pAttrArray->SetTab( nTabNo );
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScFormulaCell* pCell = (ScFormulaCell*) pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ SCROW nRow = pItems[i].nRow;
+ pCell->UpdateMoveTab( nOldPos, nNewPos, nTabNo );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::UpdateCompile( BOOL bForceIfNameInUse )
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
+ if( p->GetCellType() == CELLTYPE_FORMULA )
+ {
+ SCROW nRow = pItems[i].nRow;
+ p->UpdateCompile( bForceIfNameInUse );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::SetTabNo(SCTAB nNewTab)
+{
+ nTab = nNewTab;
+ pAttrArray->SetTab( nNewTab );
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
+ if( p->GetCellType() == CELLTYPE_FORMULA )
+ p->aPos.SetTab( nNewTab );
+ }
+}
+
+
+BOOL ScColumn::IsRangeNameInUse(SCROW nRow1, SCROW nRow2, USHORT nIndex) const
+{
+ BOOL bInUse = FALSE;
+ if (pItems)
+ for (SCSIZE i = 0; !bInUse && (i < nCount); i++)
+ if ((pItems[i].nRow >= nRow1) &&
+ (pItems[i].nRow <= nRow2) &&
+ (pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
+ bInUse = ((ScFormulaCell*)pItems[i].pCell)->IsRangeNameInUse(nIndex);
+ return bInUse;
+}
+
+void ScColumn::FindRangeNamesInUse(SCROW nRow1, SCROW nRow2, std::set<USHORT>& rIndexes) const
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ if ((pItems[i].nRow >= nRow1) &&
+ (pItems[i].nRow <= nRow2) &&
+ (pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
+ ((ScFormulaCell*)pItems[i].pCell)->FindRangeNamesInUse(rIndexes);
+}
+
+void ScColumn::ReplaceRangeNamesInUse(SCROW nRow1, SCROW nRow2,
+ const ScRangeData::IndexMap& rMap )
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ if ((pItems[i].nRow >= nRow1) &&
+ (pItems[i].nRow <= nRow2) &&
+ (pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
+ {
+ SCROW nRow = pItems[i].nRow;
+ ((ScFormulaCell*)pItems[i].pCell)->ReplaceRangeNamesInUse( rMap );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+void ScColumn::SetDirtyVar()
+{
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
+ if( p->GetCellType() == CELLTYPE_FORMULA )
+ p->SetDirtyVar();
+ }
+}
+
+
+void ScColumn::SetDirty()
+{
+ // wird nur dokumentweit verwendet, kein FormulaTrack
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
+ if( p->GetCellType() == CELLTYPE_FORMULA )
+ {
+ p->SetDirtyVar();
+ if ( !pDocument->IsInFormulaTree( p ) )
+ pDocument->PutInFormulaTree( p );
+ }
+ }
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::SetDirty( const ScRange& rRange )
+{ // broadcastet alles innerhalb eines Range, mit FormulaTrack
+ if ( !pItems || !nCount )
+ return ;
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ SCROW nRow2 = rRange.aEnd.Row();
+ ScAddress aPos( nCol, 0, nTab );
+ ScHint aHint( SC_HINT_DATACHANGED, aPos, NULL );
+ SCROW nRow;
+ SCSIZE nIndex;
+ Search( rRange.aStart.Row(), nIndex );
+ while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRow2 )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->SetDirty();
+ else
+ {
+ aHint.GetAddress().SetRow( nRow );
+ aHint.SetCell( pCell );
+ pDocument->Broadcast( aHint );
+ }
+ nIndex++;
+ }
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::SetTableOpDirty( const ScRange& rRange )
+{
+ if ( !pItems || !nCount )
+ return ;
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // no multiple recalculation
+ SCROW nRow2 = rRange.aEnd.Row();
+ ScAddress aPos( nCol, 0, nTab );
+ ScHint aHint( SC_HINT_TABLEOPDIRTY, aPos, NULL );
+ SCROW nRow;
+ SCSIZE nIndex;
+ Search( rRange.aStart.Row(), nIndex );
+ while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRow2 )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->SetTableOpDirty();
+ else
+ {
+ aHint.GetAddress().SetRow( nRow );
+ aHint.SetCell( pCell );
+ pDocument->Broadcast( aHint );
+ }
+ nIndex++;
+ }
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::SetDirtyAfterLoad()
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
+#if 1
+ // Simply set dirty and append to FormulaTree, without broadcasting,
+ // which is a magnitude faster. This is used to calculate the entire
+ // document, e.g. when loading alien file formats.
+ if ( p->GetCellType() == CELLTYPE_FORMULA )
+ p->SetDirtyAfterLoad();
+#else
+/* This was used with the binary file format that stored results, where only
+ * newly compiled and volatile functions and their dependents had to be
+ * recalculated, which was faster then. Since that was moved to 'binfilter' to
+ * convert to an XML file this isn't needed anymore, and not used for other
+ * file formats. Kept for reference in case mechanism needs to be reactivated
+ * for some file formats, we'd have to introduce a controlling parameter to
+ * this method here then.
+*/
+
+ // If the cell was alsready dirty because of CalcAfterLoad,
+ // FormulaTracking has to take place.
+ if ( p->GetCellType() == CELLTYPE_FORMULA && p->GetDirty() )
+ p->SetDirty();
+#endif
+ }
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::SetRelNameDirty()
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScFormulaCell* p = (ScFormulaCell*) pItems[i].pCell;
+ if( p->GetCellType() == CELLTYPE_FORMULA && p->HasRelNameReference() )
+ p->SetDirty();
+ }
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::CalcAll()
+{
+ if (pItems)
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ // nach F9 ctrl-F9: ueberprueft die Berechnung per FormulaTree
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ double nOldVal, nNewVal;
+ nOldVal = pFCell->GetValue();
+#endif
+ ((ScFormulaCell*)pCell)->Interpret();
+#if OSL_DEBUG_LEVEL > 1
+ if ( pFCell->GetCode()->IsRecalcModeNormal() )
+ nNewVal = pFCell->GetValue();
+ else
+ nNewVal = nOldVal; // random(), jetzt() etc.
+ DBG_ASSERT( nOldVal==nNewVal, "CalcAll: nOldVal != nNewVal" );
+#endif
+ }
+ }
+}
+
+
+void ScColumn::CompileAll()
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ SCROW nRow = pItems[i].nRow;
+ // fuer unbedingtes kompilieren
+ // bCompile=TRUE und pCode->nError=0
+ ((ScFormulaCell*)pCell)->GetCode()->SetCodeError( 0 );
+ ((ScFormulaCell*)pCell)->SetCompile( TRUE );
+ ((ScFormulaCell*)pCell)->CompileTokenArray();
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::CompileXML( ScProgress& rProgress )
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ SCROW nRow = pItems[i].nRow;
+ ((ScFormulaCell*)pCell)->CompileXML( rProgress );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener geloescht/eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::CalcAfterLoad()
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->CalcAfterLoad();
+ }
+}
+
+
+void ScColumn::ResetChanged( SCROW nStartRow, SCROW nEndRow )
+{
+ if (pItems)
+ {
+ SCSIZE nIndex;
+ Search(nStartRow,nIndex);
+ while (nIndex<nCount && pItems[nIndex].nRow <= nEndRow)
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ ((ScFormulaCell*)pCell)->ResetChanged();
+ ++nIndex;
+ }
+ }
+}
+
+
+BOOL ScColumn::HasEditCells(SCROW nStartRow, SCROW nEndRow, SCROW& rFirst) const
+{
+ // used in GetOptimalHeight - ambiguous script type counts as edit cell
+
+ SCROW nRow = 0;
+ SCSIZE nIndex;
+ Search(nStartRow,nIndex);
+ while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEndRow) : FALSE )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ CellType eCellType = pCell->GetCellType();
+ if ( eCellType == CELLTYPE_EDIT ||
+ IsAmbiguousScriptNonZero( pDocument->GetScriptType(nCol, nRow, nTab, pCell) ) ||
+ ((eCellType == CELLTYPE_FORMULA) && ((ScFormulaCell*)pCell)->IsMultilineResult()) )
+ {
+ rFirst = nRow;
+ return TRUE;
+ }
+ ++nIndex;
+ }
+
+ return FALSE;
+}
+
+
+SCsROW ScColumn::SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
+ BOOL bUp, BOOL bInSelection, const ScMarkData& rMark )
+{
+ if (bInSelection)
+ {
+ if (rMark.IsMultiMarked())
+ return pAttrArray->SearchStyle( nRow, pSearchStyle, bUp,
+ (ScMarkArray*) rMark.GetArray()+nCol ); //! const
+ else
+ return -1;
+ }
+ else
+ return pAttrArray->SearchStyle( nRow, pSearchStyle, bUp, NULL );
+}
+
+
+BOOL ScColumn::SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow, const ScStyleSheet* pSearchStyle,
+ BOOL bUp, BOOL bInSelection, const ScMarkData& rMark )
+{
+ if (bInSelection)
+ {
+ if (rMark.IsMultiMarked())
+ return pAttrArray->SearchStyleRange( rRow, rEndRow, pSearchStyle, bUp,
+ (ScMarkArray*) rMark.GetArray()+nCol ); //! const
+ else
+ return FALSE;
+ }
+ else
+ return pAttrArray->SearchStyleRange( rRow, rEndRow, pSearchStyle, bUp, NULL );
+}
+
+
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
new file mode 100644
index 000000000000..2adf6d926f0f
--- /dev/null
+++ b/sc/source/core/data/column2.cxx
@@ -0,0 +1,1866 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/algitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/broadcast.hxx>
+#include <svl/listeneriter.hxx>
+#include <vcl/outdev.hxx>
+
+#include "column.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "attarray.hxx"
+#include "patattr.hxx"
+#include "cellform.hxx"
+#include "collect.hxx"
+#include "stlsheet.hxx"
+#include "rechead.hxx"
+#include "brdcst.hxx"
+#include "editutil.hxx"
+#include "subtotal.hxx"
+#include "markdata.hxx"
+#include "compiler.hxx" // ScTokenArray GetCodeLen
+#include "dbcolect.hxx"
+#include "fillinfo.hxx"
+#include "segmenttree.hxx"
+
+#include <math.h>
+
+// -----------------------------------------------------------------------
+
+// factor from font size to optimal cell height (text width)
+#define SC_ROT_BREAK_FACTOR 6
+
+// -----------------------------------------------------------------------
+
+inline BOOL IsAmbiguousScript( BYTE nScript )
+{
+ //! move to a header file
+ return ( nScript != SCRIPTTYPE_LATIN &&
+ nScript != SCRIPTTYPE_ASIAN &&
+ nScript != SCRIPTTYPE_COMPLEX );
+}
+
+// -----------------------------------------------------------------------------------------
+
+//
+// Datei-Operationen
+//
+
+// -----------------------------------------------------------------------------------------
+
+//UNUSED2008-05 SCROW ScColumn::NoteCount( SCROW nMaxRow ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 SCROW nNoteCount = 0;
+//UNUSED2008-05 SCSIZE i;
+//UNUSED2008-05
+//UNUSED2008-05 for (i=0; i<nCount; i++)
+//UNUSED2008-05 if ( pItems[i].pCell->GetNotePtr() && pItems[i].nRow<=nMaxRow )
+//UNUSED2008-05 ++nNoteCount;
+//UNUSED2008-05
+//UNUSED2008-05 return nNoteCount;
+//UNUSED2008-05 }
+
+// -----------------------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScColumn::CorrectSymbolCells( CharSet eStreamCharSet )
+//UNUSED2008-05 {
+//UNUSED2008-05 // #99139# find and correct string cells that are formatted with a symbol font,
+//UNUSED2008-05 // but are not in the LoadedSymbolStringCellsList
+//UNUSED2008-05 // (because CELLTYPE_SYMBOLS wasn't written in the file)
+//UNUSED2008-05
+//UNUSED2008-05 ScFontToSubsFontConverter_AutoPtr xFontConverter;
+//UNUSED2008-05 const ULONG nFontConverterFlags = FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS;
+//UNUSED2008-05
+//UNUSED2008-05 BOOL bListInitialized = FALSE;
+//UNUSED2008-05 ScSymbolStringCellEntry* pCurrentEntry = NULL;
+//UNUSED2008-05
+//UNUSED2008-05 ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
+//UNUSED2008-05 SCROW nStt, nEnd;
+//UNUSED2008-05 const ScPatternAttr* pAttr = aAttrIter.Next( nStt, nEnd );
+//UNUSED2008-05 while ( pAttr )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( (xFontConverter = pAttr->GetSubsFontConverter( nFontConverterFlags )) ||
+//UNUSED2008-05 pAttr->IsSymbolFont() )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScColumnIterator aCellIter( this, nStt, nEnd );
+//UNUSED2008-05 SCROW nRow;
+//UNUSED2008-05 ScBaseCell* pCell;
+//UNUSED2008-05 while ( aCellIter.Next( nRow, pCell ) )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( pCell->GetCellType() == CELLTYPE_STRING )
+//UNUSED2008-05 {
+//UNUSED2008-05 List& rList = pDocument->GetLoadedSymbolStringCellsList();
+//UNUSED2008-05 if (!bListInitialized)
+//UNUSED2008-05 {
+//UNUSED2008-05 pCurrentEntry = (ScSymbolStringCellEntry*)rList.First();
+//UNUSED2008-05 bListInitialized = TRUE;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 while ( pCurrentEntry && pCurrentEntry->nRow < nRow )
+//UNUSED2008-05 pCurrentEntry = (ScSymbolStringCellEntry*)rList.Next();
+//UNUSED2008-05
+//UNUSED2008-05 if ( pCurrentEntry && pCurrentEntry->nRow == nRow )
+//UNUSED2008-05 {
+//UNUSED2008-05 // found
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 // not in list -> convert and put into list
+//UNUSED2008-05
+//UNUSED2008-05 ScStringCell* pStrCell = (ScStringCell*)pCell;
+//UNUSED2008-05 String aOldStr;
+//UNUSED2008-05 pStrCell->GetString( aOldStr );
+//UNUSED2008-05
+//UNUSED2008-05 // convert back to stream character set (get original data)
+//UNUSED2008-05 ByteString aByteStr( aOldStr, eStreamCharSet );
+//UNUSED2008-05
+//UNUSED2008-05 // convert using symbol encoding, as for CELLTYPE_SYMBOLS cells
+//UNUSED2008-05 String aNewStr( aByteStr, RTL_TEXTENCODING_SYMBOL );
+//UNUSED2008-05 pStrCell->SetString( aNewStr );
+//UNUSED2008-05
+//UNUSED2008-05 ScSymbolStringCellEntry * pEntry = new ScSymbolStringCellEntry;
+//UNUSED2008-05 pEntry->pCell = pStrCell;
+//UNUSED2008-05 pEntry->nRow = nRow;
+//UNUSED2008-05
+//UNUSED2008-05 if ( pCurrentEntry )
+//UNUSED2008-05 rList.Insert( pEntry ); // before current entry - pCurrentEntry stays valid
+//UNUSED2008-05 else
+//UNUSED2008-05 rList.Insert( pEntry, LIST_APPEND ); // append if already behind last entry
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 pAttr = aAttrIter.Next( nStt, nEnd );
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+// -----------------------------------------------------------------------------------------
+
+ // GetNeededSize: optimale Hoehe / Breite in Pixeln
+
+long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bWidth, const ScNeededSizeOptions& rOptions )
+{
+ long nValue=0;
+ SCSIZE nIndex;
+ double nPPT = bWidth ? nPPTX : nPPTY;
+ if (Search(nRow,nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ const ScPatternAttr* pPattern = rOptions.pPattern;
+ if (!pPattern)
+ pPattern = pAttrArray->GetPattern( nRow );
+
+ // zusammengefasst?
+ // Merge nicht in bedingter Formatierung
+
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ const ScMergeFlagAttr* pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
+
+ if ( bWidth )
+ {
+ if ( pFlag->IsHorOverlapped() )
+ return 0;
+ if ( rOptions.bSkipMerged && pMerge->GetColMerge() > 1 )
+ return 0;
+ }
+ else
+ {
+ if ( pFlag->IsVerOverlapped() )
+ return 0;
+ if ( rOptions.bSkipMerged && pMerge->GetRowMerge() > 1 )
+ return 0;
+ }
+
+ // bedingte Formatierung
+ const SfxItemSet* pCondSet = NULL;
+ if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
+ pCondSet = pDocument->GetCondResult( nCol, nRow, nTab );
+
+ // Zeilenumbruch?
+
+ const SfxPoolItem* pCondItem;
+ SvxCellHorJustify eHorJust;
+ if (pCondSet &&
+ pCondSet->GetItemState(ATTR_HOR_JUSTIFY, TRUE, &pCondItem) == SFX_ITEM_SET)
+ eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem*)pCondItem)->GetValue();
+ else
+ eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
+ bool bBreak;
+ if ( eHorJust == SVX_HOR_JUSTIFY_BLOCK )
+ bBreak = true;
+ else if ( pCondSet &&
+ pCondSet->GetItemState(ATTR_LINEBREAK, TRUE, &pCondItem) == SFX_ITEM_SET)
+ bBreak = ((const SfxBoolItem*)pCondItem)->GetValue();
+ else
+ bBreak = ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
+
+ if (pCell->HasValueData())
+ // Cell has a value. Disable line break.
+ bBreak = false;
+
+ // get other attributes from pattern and conditional formatting
+
+ SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
+ BOOL bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED &&
+ ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() );
+ if ( bAsianVertical )
+ bBreak = false;
+
+ if ( bWidth && bBreak ) // after determining bAsianVertical (bBreak may be reset)
+ return 0;
+
+ long nRotate = 0;
+ SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
+ if ( eOrient == SVX_ORIENTATION_STANDARD )
+ {
+ if (pCondSet &&
+ pCondSet->GetItemState(ATTR_ROTATE_VALUE, TRUE, &pCondItem) == SFX_ITEM_SET)
+ nRotate = ((const SfxInt32Item*)pCondItem)->GetValue();
+ else
+ nRotate = ((const SfxInt32Item&)pPattern->GetItem(ATTR_ROTATE_VALUE)).GetValue();
+ if ( nRotate )
+ {
+ if (pCondSet &&
+ pCondSet->GetItemState(ATTR_ROTATE_MODE, TRUE, &pCondItem) == SFX_ITEM_SET)
+ eRotMode = (SvxRotateMode)((const SvxRotateModeItem*)pCondItem)->GetValue();
+ else
+ eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE)).GetValue();
+
+ if ( nRotate == 18000 )
+ eRotMode = SVX_ROTATE_MODE_STANDARD; // keinen Ueberlauf
+ }
+ }
+
+ if ( eHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ {
+ // ignore orientation/rotation if "repeat" is active
+ eOrient = SVX_ORIENTATION_STANDARD;
+ nRotate = 0;
+ bAsianVertical = FALSE;
+ }
+
+ const SvxMarginItem* pMargin;
+ if (pCondSet &&
+ pCondSet->GetItemState(ATTR_MARGIN, TRUE, &pCondItem) == SFX_ITEM_SET)
+ pMargin = (const SvxMarginItem*) pCondItem;
+ else
+ pMargin = (const SvxMarginItem*) &pPattern->GetItem(ATTR_MARGIN);
+ USHORT nIndent = 0;
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ {
+ if (pCondSet &&
+ pCondSet->GetItemState(ATTR_INDENT, TRUE, &pCondItem) == SFX_ITEM_SET)
+ nIndent = ((const SfxUInt16Item*)pCondItem)->GetValue();
+ else
+ nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue();
+ }
+
+ BYTE nScript = pDocument->GetScriptType( nCol, nRow, nTab, pCell );
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+
+ // also call SetFont for edit cells, because bGetFont may be set only once
+ // bGetFont is set also if script type changes
+ if (rOptions.bGetFont)
+ {
+ Fraction aFontZoom = ( eOrient == SVX_ORIENTATION_STANDARD ) ? rZoomX : rZoomY;
+ Font aFont;
+ // font color doesn't matter here
+ pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aFontZoom, pCondSet, nScript );
+ pDev->SetFont(aFont);
+ }
+
+ BOOL bAddMargin = TRUE;
+ CellType eCellType = pCell->GetCellType();
+
+ BOOL bEditEngine = ( eCellType == CELLTYPE_EDIT ||
+ eOrient == SVX_ORIENTATION_STACKED ||
+ IsAmbiguousScript( nScript ) ||
+ ((eCellType == CELLTYPE_FORMULA) && ((ScFormulaCell*)pCell)->IsMultilineResult()) );
+
+ if (!bEditEngine) // direkte Ausgabe
+ {
+ String aValStr;
+ Color* pColor;
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ ULONG nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
+ ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor,
+ *pFormatter,
+ TRUE, rOptions.bFormula, ftCheck );
+ if (aValStr.Len())
+ {
+ // SetFont ist nach oben verschoben
+
+ Size aSize( pDev->GetTextWidth( aValStr ), pDev->GetTextHeight() );
+ if ( eOrient != SVX_ORIENTATION_STANDARD )
+ {
+ long nTemp = aSize.Width();
+ aSize.Width() = aSize.Height();
+ aSize.Height() = nTemp;
+ }
+ else if ( nRotate )
+ {
+ //! unterschiedliche Skalierung X/Y beruecksichtigen
+
+ double nRealOrient = nRotate * F_PI18000; // nRotate sind 1/100 Grad
+ double nCosAbs = fabs( cos( nRealOrient ) );
+ double nSinAbs = fabs( sin( nRealOrient ) );
+ long nHeight = (long)( aSize.Height() * nCosAbs + aSize.Width() * nSinAbs );
+ long nWidth;
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nWidth = (long)( aSize.Width() * nCosAbs + aSize.Height() * nSinAbs );
+ else if ( rOptions.bTotalSize )
+ {
+ nWidth = (long) ( pDocument->GetColWidth( nCol,nTab ) * nPPT );
+ bAddMargin = FALSE;
+ // nur nach rechts:
+ //! unterscheiden nach Ausrichtung oben/unten (nur Text/ganze Hoehe)
+ if ( pPattern->GetRotateDir( pCondSet ) == SC_ROTDIR_RIGHT )
+ nWidth += (long)( pDocument->GetRowHeight( nRow,nTab ) *
+ nPPT * nCosAbs / nSinAbs );
+ }
+ else
+ nWidth = (long)( aSize.Height() / nSinAbs ); //! begrenzen?
+
+ if ( bBreak && !rOptions.bTotalSize )
+ {
+ // #47744# limit size for line break
+ long nCmp = pDev->GetFont().GetSize().Height() * SC_ROT_BREAK_FACTOR;
+ if ( nHeight > nCmp )
+ nHeight = nCmp;
+ }
+
+ aSize = Size( nWidth, nHeight );
+ }
+ nValue = bWidth ? aSize.Width() : aSize.Height();
+
+ if ( bAddMargin )
+ {
+ if (bWidth)
+ {
+ nValue += (long) ( pMargin->GetLeftMargin() * nPPT ) +
+ (long) ( pMargin->GetRightMargin() * nPPT );
+ if ( nIndent )
+ nValue += (long) ( nIndent * nPPT );
+ }
+ else
+ nValue += (long) ( pMargin->GetTopMargin() * nPPT ) +
+ (long) ( pMargin->GetBottomMargin() * nPPT );
+ }
+
+ // Zeilenumbruch ausgefuehrt ?
+
+ if ( bBreak && !bWidth )
+ {
+ // Test mit EditEngine zur Sicherheit schon bei 90%
+ // (wegen Rundungsfehlern und weil EditEngine teilweise anders formatiert)
+
+ long nDocPixel = (long) ( ( pDocument->GetColWidth( nCol,nTab ) -
+ pMargin->GetLeftMargin() - pMargin->GetRightMargin() -
+ nIndent )
+ * nPPT );
+ nDocPixel = (nDocPixel * 9) / 10; // zur Sicherheit
+ if ( aSize.Width() > nDocPixel )
+ bEditEngine = TRUE;
+ }
+ }
+ }
+
+ if (bEditEngine)
+ {
+ // der Font wird bei !bEditEngine nicht jedesmal neu gesetzt
+ Font aOldFont = pDev->GetFont();
+
+ MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY );
+
+ // am Dokument speichern ?
+ ScFieldEditEngine* pEngine = pDocument->CreateFieldEditEngine();
+
+ pEngine->SetUpdateMode( FALSE );
+ MapMode aOld = pDev->GetMapMode();
+ pDev->SetMapMode( aHMMMode );
+ pEngine->SetRefDevice( pDev );
+ pEngine->SetForbiddenCharsTable( pDocument->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDocument->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDocument->GetAsianKerning() );
+ SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pPattern->FillEditItemSet( pSet, pCondSet );
+
+// no longer needed, are setted with the text (is faster)
+// pEngine->SetDefaults( pSet );
+
+ if ( ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() ) {
+
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
+ pEngine->SetHyphenator( xXHyphenator );
+ }
+
+ Size aPaper = Size( 1000000, 1000000 );
+ if ( eOrient==SVX_ORIENTATION_STACKED && !bAsianVertical )
+ aPaper.Width() = 1;
+ else if (bBreak)
+ {
+ double fWidthFactor = nPPTX;
+ BOOL bTextWysiwyg = ( pDev->GetOutDevType() == OUTDEV_PRINTER );
+ if ( bTextWysiwyg )
+ {
+ // #95593# if text is formatted for printer, don't use PixelToLogic,
+ // to ensure the exact same paper width (and same line breaks) as in
+ // ScEditUtil::GetEditArea, used for output.
+
+ fWidthFactor = HMM_PER_TWIPS;
+ }
+
+ // use original width for hidden columns:
+ long nDocWidth = (long) ( pDocument->GetOriginalWidth(nCol,nTab) * fWidthFactor );
+ SCCOL nColMerge = pMerge->GetColMerge();
+ if (nColMerge > 1)
+ for (SCCOL nColAdd=1; nColAdd<nColMerge; nColAdd++)
+ nDocWidth += (long) ( pDocument->GetColWidth(nCol+nColAdd,nTab) * fWidthFactor );
+ nDocWidth -= (long) ( pMargin->GetLeftMargin() * fWidthFactor )
+ + (long) ( pMargin->GetRightMargin() * fWidthFactor )
+ + 1; // Ausgabebereich ist Breite-1 Pixel (wegen Gitterlinien)
+ if ( nIndent )
+ nDocWidth -= (long) ( nIndent * fWidthFactor );
+
+ // space for AutoFilter button: 20 * nZoom/100
+ if ( pFlag->HasAutoFilter() && !bTextWysiwyg )
+ nDocWidth -= (rZoomX.GetNumerator()*20)/rZoomX.GetDenominator();
+
+ aPaper.Width() = nDocWidth;
+
+ if ( !bTextWysiwyg )
+ aPaper = pDev->PixelToLogic( aPaper, aHMMMode );
+ }
+ pEngine->SetPaperSize(aPaper);
+
+ if ( pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ const EditTextObject* pData;
+ ((ScEditCell*)pCell)->GetData(pData);
+ pEngine->SetTextNewDefaults(*pData, pSet);
+ }
+ else
+ {
+ Color* pColor;
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ ULONG nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
+ String aString;
+ ScCellFormat::GetString( pCell, nFormat, aString, &pColor,
+ *pFormatter,
+ TRUE, rOptions.bFormula, ftCheck );
+ if (aString.Len())
+ pEngine->SetTextNewDefaults(aString, pSet);
+ else
+ pEngine->SetDefaults(pSet);
+ }
+
+ BOOL bEngineVertical = pEngine->IsVertical();
+ pEngine->SetVertical( bAsianVertical );
+ pEngine->SetUpdateMode( TRUE );
+
+ BOOL bEdWidth = bWidth;
+ if ( eOrient != SVX_ORIENTATION_STANDARD && eOrient != SVX_ORIENTATION_STACKED )
+ bEdWidth = !bEdWidth;
+ if ( nRotate )
+ {
+ //! unterschiedliche Skalierung X/Y beruecksichtigen
+
+ Size aSize( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );
+ double nRealOrient = nRotate * F_PI18000; // nRotate sind 1/100 Grad
+ double nCosAbs = fabs( cos( nRealOrient ) );
+ double nSinAbs = fabs( sin( nRealOrient ) );
+ long nHeight = (long)( aSize.Height() * nCosAbs + aSize.Width() * nSinAbs );
+ long nWidth;
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nWidth = (long)( aSize.Width() * nCosAbs + aSize.Height() * nSinAbs );
+ else if ( rOptions.bTotalSize )
+ {
+ nWidth = (long) ( pDocument->GetColWidth( nCol,nTab ) * nPPT );
+ bAddMargin = FALSE;
+ if ( pPattern->GetRotateDir( pCondSet ) == SC_ROTDIR_RIGHT )
+ nWidth += (long)( pDocument->GetRowHeight( nRow,nTab ) *
+ nPPT * nCosAbs / nSinAbs );
+ }
+ else
+ nWidth = (long)( aSize.Height() / nSinAbs ); //! begrenzen?
+ aSize = Size( nWidth, nHeight );
+
+ Size aPixSize = pDev->LogicToPixel( aSize, aHMMMode );
+ if ( bEdWidth )
+ nValue = aPixSize.Width();
+ else
+ {
+ nValue = aPixSize.Height();
+
+ if ( bBreak && !rOptions.bTotalSize )
+ {
+ // #47744# limit size for line break
+ long nCmp = aOldFont.GetSize().Height() * SC_ROT_BREAK_FACTOR;
+ if ( nValue > nCmp )
+ nValue = nCmp;
+ }
+ }
+ }
+ else if ( bEdWidth )
+ {
+ if (bBreak)
+ nValue = 0;
+ else
+ nValue = pDev->LogicToPixel(Size( pEngine->CalcTextWidth(), 0 ),
+ aHMMMode).Width();
+ }
+ else // Hoehe
+ {
+ nValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ),
+ aHMMMode).Height();
+ }
+
+ if ( nValue && bAddMargin )
+ {
+ if (bWidth)
+ {
+ nValue += (long) ( pMargin->GetLeftMargin() * nPPT ) +
+ (long) ( pMargin->GetRightMargin() * nPPT );
+ if (nIndent)
+ nValue += (long) ( nIndent * nPPT );
+ }
+ else
+ {
+ nValue += (long) ( pMargin->GetTopMargin() * nPPT ) +
+ (long) ( pMargin->GetBottomMargin() * nPPT );
+
+ if ( bAsianVertical && pDev->GetOutDevType() != OUTDEV_PRINTER )
+ {
+ // add 1pt extra (default margin value) for line breaks with SetVertical
+ nValue += (long) ( 20 * nPPT );
+ }
+ }
+ }
+
+ // EditEngine is cached and re-used, so the old vertical flag must be restored
+ pEngine->SetVertical( bEngineVertical );
+
+ pDocument->DisposeFieldEditEngine(pEngine);
+
+ pDev->SetMapMode( aOld );
+ pDev->SetFont( aOldFont );
+ }
+
+ if (bWidth)
+ {
+ // Platz fuer Autofilter-Button
+ // 20 * nZoom/100
+ // bedingte Formatierung hier nicht interessant
+
+ INT16 nFlags = ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).GetValue();
+ if (nFlags & SC_MF_AUTO)
+ nValue += (rZoomX.GetNumerator()*20)/rZoomX.GetDenominator();
+ }
+ }
+ return nValue;
+}
+
+long ScColumn::GetSimpleTextNeededSize( SCSIZE nIndex, OutputDevice* pDev,
+ BOOL bWidth )
+{
+ long nValue=0;
+ if ( nIndex < nCount )
+ {
+ SCROW nRow = pItems[nIndex].nRow;
+ const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ String aValStr;
+ Color* pColor;
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ ULONG nFormat = pPattern->GetNumberFormat( pFormatter );
+ ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor,
+ *pFormatter, TRUE, FALSE, ftCheck );
+ if ( aValStr.Len() )
+ {
+ if ( bWidth )
+ nValue = pDev->GetTextWidth( aValStr );
+ else
+ nValue = pDev->GetTextHeight();
+ }
+ }
+ return nValue;
+}
+
+USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula, USHORT nOldWidth,
+ const ScMarkData* pMarkData,
+ BOOL bSimpleTextImport )
+{
+ if (nCount == 0)
+ return nOldWidth;
+
+ USHORT nWidth = (USHORT) (nOldWidth * nPPTX);
+ BOOL bFound = FALSE;
+
+ SCSIZE nIndex;
+ ScMarkedDataIter aDataIter(this, pMarkData, TRUE);
+ if ( bSimpleTextImport )
+ { // alles eins bis auf NumberFormate
+ const ScPatternAttr* pPattern = GetPattern( 0 );
+ Font aFont;
+ // font color doesn't matter here
+ pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &rZoomX, NULL );
+ pDev->SetFont( aFont );
+ const SvxMarginItem* pMargin = (const SvxMarginItem*) &pPattern->GetItem(ATTR_MARGIN);
+ long nMargin = (long) ( pMargin->GetLeftMargin() * nPPTX ) +
+ (long) ( pMargin->GetRightMargin() * nPPTX );
+
+ while (aDataIter.Next( nIndex ))
+ {
+ USHORT nThis = (USHORT) (GetSimpleTextNeededSize( nIndex, pDev,
+ TRUE ) + nMargin);
+ if (nThis)
+ {
+ if (nThis>nWidth || !bFound)
+ {
+ nWidth = nThis;
+ bFound = TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ ScNeededSizeOptions aOptions;
+ aOptions.bFormula = bFormula;
+ const ScPatternAttr* pOldPattern = NULL;
+ BYTE nOldScript = 0;
+
+ while (aDataIter.Next( nIndex ))
+ {
+ SCROW nRow = pItems[nIndex].nRow;
+
+ BYTE nScript = pDocument->GetScriptType( nCol, nRow, nTab, pItems[nIndex].pCell );
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+
+ const ScPatternAttr* pPattern = GetPattern( nRow );
+ aOptions.pPattern = pPattern;
+ aOptions.bGetFont = (pPattern != pOldPattern || nScript != nOldScript);
+ USHORT nThis = (USHORT) GetNeededSize( nRow, pDev, nPPTX, nPPTY,
+ rZoomX, rZoomY, TRUE, aOptions );
+ pOldPattern = pPattern;
+ if (nThis)
+ {
+ if (nThis>nWidth || !bFound)
+ {
+ nWidth = nThis;
+ bFound = TRUE;
+ }
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ nWidth += 2;
+ USHORT nTwips = (USHORT) (nWidth / nPPTX);
+ return nTwips;
+ }
+ else
+ return nOldWidth;
+}
+
+USHORT lcl_GetAttribHeight( const ScPatternAttr& rPattern, USHORT nFontHeightId )
+{
+ USHORT nHeight = (USHORT) ((const SvxFontHeightItem&) rPattern.GetItem(nFontHeightId)).GetHeight();
+ const SvxMarginItem* pMargin = (const SvxMarginItem*) &rPattern.GetItem(ATTR_MARGIN);
+ nHeight += nHeight / 5;
+ // gibt bei 10pt 240
+
+ if ( ((const SvxEmphasisMarkItem&)rPattern.
+ GetItem(ATTR_FONT_EMPHASISMARK)).GetEmphasisMark() != EMPHASISMARK_NONE )
+ {
+ // add height for emphasis marks
+ //! font metrics should be used instead
+ nHeight += nHeight / 4;
+ }
+
+ if ( nHeight + 240 > ScGlobal::nDefFontHeight )
+ {
+ nHeight = sal::static_int_cast<USHORT>( nHeight + ScGlobal::nDefFontHeight );
+ nHeight -= 240;
+ }
+
+ // Standard-Hoehe: TextHeight + Raender - 23
+ // -> 257 unter Windows
+
+ if (nHeight > STD_ROWHEIGHT_DIFF)
+ nHeight -= STD_ROWHEIGHT_DIFF;
+
+ nHeight += pMargin->GetTopMargin() + pMargin->GetBottomMargin();
+
+ return nHeight;
+}
+
+// pHeight in Twips
+// nMinHeight, nMinStart zur Optimierung: ab nRow >= nMinStart ist mindestens nMinHeight
+// (wird nur bei bStdAllowed ausgewertet)
+
+void ScColumn::GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT* pHeight,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bShrink, USHORT nMinHeight, SCROW nMinStart )
+{
+ ScAttrIterator aIter( pAttrArray, nStartRow, nEndRow );
+
+ SCROW nStart = -1;
+ SCROW nEnd = -1;
+ SCROW nEditPos = 0;
+ SCROW nNextEnd = 0;
+
+ // bei bedingter Formatierung werden immer die einzelnen Zellen angesehen
+
+ const ScPatternAttr* pPattern = aIter.Next(nStart,nEnd);
+ while ( pPattern )
+ {
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ const ScMergeFlagAttr* pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
+ if ( pMerge->GetRowMerge() > 1 || pFlag->IsOverlapped() )
+ {
+ // nix - vertikal bei der zusammengefassten und den ueberdeckten,
+ // horizontal nur bei den ueberdeckten (unsichtbaren) -
+ // eine nur horizontal zusammengefasste wird aber beruecksichtigt
+ }
+ else
+ {
+ SCROW nRow = 0;
+ BOOL bStdAllowed = (pPattern->GetCellOrientation() == SVX_ORIENTATION_STANDARD);
+ BOOL bStdOnly = FALSE;
+ if (bStdAllowed)
+ {
+ BOOL bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
+ ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() ==
+ SVX_HOR_JUSTIFY_BLOCK);
+ bStdOnly = !bBreak;
+
+ // bedingte Formatierung: Zellen durchgehen
+ if ( bStdOnly && ((const SfxUInt32Item&)pPattern->
+ GetItem(ATTR_CONDITIONAL)).GetValue() )
+ bStdOnly = FALSE;
+
+ // gedrehter Text: Zellen durchgehen
+ if ( bStdOnly && ((const SfxInt32Item&)pPattern->
+ GetItem(ATTR_ROTATE_VALUE)).GetValue() )
+ bStdOnly = FALSE;
+ }
+
+ if (bStdOnly)
+ if (HasEditCells(nStart,nEnd,nEditPos)) // includes mixed script types
+ {
+ if (nEditPos == nStart)
+ {
+ bStdOnly = FALSE;
+ if (nEnd > nEditPos)
+ nNextEnd = nEnd;
+ nEnd = nEditPos; // einzeln ausrechnen
+ bStdAllowed = FALSE; // wird auf jeden Fall per Zelle berechnet
+ }
+ else
+ {
+ nNextEnd = nEnd;
+ nEnd = nEditPos - 1; // Standard - Teil
+ }
+ }
+
+ if (bStdAllowed)
+ {
+ USHORT nLatHeight = 0;
+ USHORT nCjkHeight = 0;
+ USHORT nCtlHeight = 0;
+ USHORT nDefHeight;
+ BYTE nDefScript = ScGlobal::GetDefaultScriptType();
+ if ( nDefScript == SCRIPTTYPE_ASIAN )
+ nDefHeight = nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
+ else if ( nDefScript == SCRIPTTYPE_COMPLEX )
+ nDefHeight = nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
+ else
+ nDefHeight = nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
+
+ // if everything below is already larger, the loop doesn't have to
+ // be run again
+ SCROW nStdEnd = nEnd;
+ if ( nDefHeight <= nMinHeight && nStdEnd >= nMinStart )
+ nStdEnd = (nMinStart>0) ? nMinStart-1 : 0;
+
+ for (nRow=nStart; nRow<=nStdEnd; nRow++)
+ if (nDefHeight > pHeight[nRow-nStartRow])
+ pHeight[nRow-nStartRow] = nDefHeight;
+
+ if ( bStdOnly )
+ {
+ // if cells are not handled individually below,
+ // check for cells with different script type
+
+ SCSIZE nIndex;
+ Search(nStart,nIndex);
+ while ( nIndex < nCount && (nRow=pItems[nIndex].nRow) <= nEnd )
+ {
+ BYTE nScript = pDocument->GetScriptType( nCol, nRow, nTab, pItems[nIndex].pCell );
+ if ( nScript != nDefScript )
+ {
+ if ( nScript == SCRIPTTYPE_ASIAN )
+ {
+ if ( nCjkHeight == 0 )
+ nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
+ if (nCjkHeight > pHeight[nRow-nStartRow])
+ pHeight[nRow-nStartRow] = nCjkHeight;
+ }
+ else if ( nScript == SCRIPTTYPE_COMPLEX )
+ {
+ if ( nCtlHeight == 0 )
+ nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
+ if (nCtlHeight > pHeight[nRow-nStartRow])
+ pHeight[nRow-nStartRow] = nCtlHeight;
+ }
+ else
+ {
+ if ( nLatHeight == 0 )
+ nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
+ if (nLatHeight > pHeight[nRow-nStartRow])
+ pHeight[nRow-nStartRow] = nLatHeight;
+ }
+ }
+ ++nIndex;
+ }
+ }
+ }
+
+ if (!bStdOnly) // belegte Zellen suchen
+ {
+ ScNeededSizeOptions aOptions;
+
+ SCSIZE nIndex;
+ Search(nStart,nIndex);
+ while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEnd) : FALSE )
+ {
+ // Zellhoehe nur berechnen, wenn sie spaeter auch gebraucht wird (#37928#)
+
+ if ( bShrink || !(pDocument->GetRowFlags(nRow, nTab) & CR_MANUALSIZE) )
+ {
+ aOptions.pPattern = pPattern;
+ USHORT nHeight = (USHORT)
+ ( GetNeededSize( nRow, pDev, nPPTX, nPPTY,
+ rZoomX, rZoomY, FALSE, aOptions ) / nPPTY );
+ if (nHeight > pHeight[nRow-nStartRow])
+ pHeight[nRow-nStartRow] = nHeight;
+ }
+ ++nIndex;
+ }
+ }
+ }
+
+ if (nNextEnd > 0)
+ {
+ nStart = nEnd + 1;
+ nEnd = nNextEnd;
+ nNextEnd = 0;
+ }
+ else
+ pPattern = aIter.Next(nStart,nEnd);
+ }
+}
+
+BOOL ScColumn::GetNextSpellingCell(SCROW& nRow, BOOL bInSel, const ScMarkData& rData) const
+{
+ BOOL bStop = FALSE;
+ CellType eCellType;
+ SCSIZE nIndex;
+ if (!bInSel && Search(nRow, nIndex))
+ {
+ eCellType = GetCellType(nRow);
+ if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
+ !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
+ pDocument->IsTabProtected(nTab)) )
+ return TRUE;
+ }
+ while (!bStop)
+ {
+ if (bInSel)
+ {
+ nRow = rData.GetNextMarked(nCol, nRow, FALSE);
+ if (!ValidRow(nRow))
+ {
+ nRow = MAXROW+1;
+ bStop = TRUE;
+ }
+ else
+ {
+ eCellType = GetCellType(nRow);
+ if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
+ !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
+ pDocument->IsTabProtected(nTab)) )
+ return TRUE;
+ else
+ nRow++;
+ }
+ }
+ else if (GetNextDataPos(nRow))
+ {
+ eCellType = GetCellType(nRow);
+ if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
+ !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
+ pDocument->IsTabProtected(nTab)) )
+ return TRUE;
+ else
+ nRow++;
+ }
+ else
+ {
+ nRow = MAXROW+1;
+ bStop = TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// =========================================================================================
+
+void ScColumn::RemoveAutoSpellObj()
+{
+ ScTabEditEngine* pEngine = NULL;
+
+ for (SCSIZE i=0; i<nCount; i++)
+ if ( pItems[i].pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ ScEditCell* pOldCell = (ScEditCell*) pItems[i].pCell;
+ const EditTextObject* pData = pOldCell->GetData();
+ // keine Abfrage auf HasOnlineSpellErrors, damit es auch
+ // nach dem Laden funktioniert
+
+ // Fuer den Test auf harte Formatierung (ScEditAttrTester) sind die Defaults
+ // in der EditEngine unwichtig. Wenn der Tester spaeter einmal gleiche
+ // Attribute in Default und harter Formatierung erkennen und weglassen sollte,
+ // muessten an der EditEngine zu jeder Zelle die richtigen Defaults gesetzt
+ // werden!
+
+ // auf Attribute testen
+ if ( !pEngine )
+ pEngine = new ScTabEditEngine(pDocument);
+ pEngine->SetText( *pData );
+ ScEditAttrTester aTester( pEngine );
+ if ( aTester.NeedsObject() ) // nur Spell-Errors entfernen
+ {
+ EditTextObject* pNewData = pEngine->CreateTextObject(); // ohne BIGOBJ
+ pOldCell->SetData( pNewData, pEngine->GetEditTextObjectPool() );
+ delete pNewData;
+ }
+ else // String erzeugen
+ {
+ String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
+ ScBaseCell* pNewCell = new ScStringCell( aText );
+ pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
+ pNewCell->TakeNote( pOldCell->ReleaseNote() );
+ pItems[i].pCell = pNewCell;
+ delete pOldCell;
+ }
+ }
+
+ delete pEngine;
+}
+
+void ScColumn::RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow )
+{
+ ScFieldEditEngine* pEngine = NULL;
+
+ SCSIZE i;
+ Search( nStartRow, i );
+ for (; i<nCount && pItems[i].nRow <= nEndRow; i++)
+ if ( pItems[i].pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ ScEditCell* pOldCell = (ScEditCell*) pItems[i].pCell;
+ const EditTextObject* pData = pOldCell->GetData();
+
+ // Fuer den Test auf harte Formatierung (ScEditAttrTester) sind die Defaults
+ // in der EditEngine unwichtig. Wenn der Tester spaeter einmal gleiche
+ // Attribute in Default und harter Formatierung erkennen und weglassen sollte,
+ // muessten an der EditEngine zu jeder Zelle die richtigen Defaults gesetzt
+ // werden!
+
+ // auf Attribute testen
+ if ( !pEngine )
+ {
+ //pEngine = new ScTabEditEngine(pDocument);
+ pEngine = new ScFieldEditEngine( pDocument->GetEditPool() );
+ // EE_CNTRL_ONLINESPELLING falls schon Fehler drin sind
+ pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_ONLINESPELLING );
+ pEngine->SetForbiddenCharsTable( pDocument->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDocument->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDocument->GetAsianKerning() );
+ }
+ pEngine->SetText( *pData );
+ USHORT nParCount = pEngine->GetParagraphCount();
+ for (USHORT nPar=0; nPar<nParCount; nPar++)
+ {
+ pEngine->QuickRemoveCharAttribs( nPar );
+ const SfxItemSet& rOld = pEngine->GetParaAttribs( nPar );
+ if ( rOld.Count() )
+ {
+ SfxItemSet aNew( *rOld.GetPool(), rOld.GetRanges() ); // leer
+ pEngine->SetParaAttribs( nPar, aNew );
+ }
+ }
+ // URL-Felder in Text wandeln (andere gibt's nicht, darum pType=0)
+ pEngine->RemoveFields( TRUE );
+
+ BOOL bSpellErrors = pEngine->HasOnlineSpellErrors();
+ BOOL bNeedObject = bSpellErrors || nParCount>1; // Errors/Absaetze behalten
+ // ScEditAttrTester nicht mehr noetig, Felder sind raus
+
+ if ( bNeedObject ) // bleibt Edit-Zelle
+ {
+ ULONG nCtrl = pEngine->GetControlWord();
+ ULONG nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
+ if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
+ pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
+ EditTextObject* pNewData = pEngine->CreateTextObject();
+ pOldCell->SetData( pNewData, pEngine->GetEditTextObjectPool() );
+ delete pNewData;
+ }
+ else // String erzeugen
+ {
+ String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
+ ScBaseCell* pNewCell = new ScStringCell( aText );
+ pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
+ pNewCell->TakeNote( pOldCell->ReleaseNote() );
+ pItems[i].pCell = pNewCell;
+ delete pOldCell;
+ }
+ }
+
+ delete pEngine;
+}
+
+// =========================================================================================
+
+BOOL ScColumn::TestTabRefAbs(SCTAB nTable)
+{
+ BOOL bRet = FALSE;
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ if ( pItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
+ if (((ScFormulaCell*)pItems[i].pCell)->TestTabRefAbs(nTable))
+ bRet = TRUE;
+ return bRet;
+}
+
+// =========================================================================================
+
+ScColumnIterator::ScColumnIterator( const ScColumn* pCol, SCROW nStart, SCROW nEnd ) :
+ pColumn( pCol ),
+ nTop( nStart ),
+ nBottom( nEnd )
+{
+ pColumn->Search( nTop, nPos );
+}
+
+ScColumnIterator::~ScColumnIterator()
+{
+}
+
+BOOL ScColumnIterator::Next( SCROW& rRow, ScBaseCell*& rpCell )
+{
+ if ( nPos < pColumn->nCount )
+ {
+ rRow = pColumn->pItems[nPos].nRow;
+ if ( rRow <= nBottom )
+ {
+ rpCell = pColumn->pItems[nPos].pCell;
+ ++nPos;
+ return TRUE;
+ }
+ }
+
+ rRow = 0;
+ rpCell = NULL;
+ return FALSE;
+}
+
+SCSIZE ScColumnIterator::GetIndex() const // Index zur letzen abgefragten Zelle
+{
+ return nPos - 1; // bei Next ist Pos hochgezaehlt worden
+}
+
+// -----------------------------------------------------------------------------------------
+
+ScMarkedDataIter::ScMarkedDataIter( const ScColumn* pCol, const ScMarkData* pMarkData,
+ BOOL bAllIfNone ) :
+ pColumn( pCol ),
+ pMarkIter( NULL ),
+ bNext( TRUE ),
+ bAll( bAllIfNone )
+{
+ if (pMarkData && pMarkData->IsMultiMarked())
+ pMarkIter = new ScMarkArrayIter( pMarkData->GetArray() + pCol->GetCol() );
+}
+
+ScMarkedDataIter::~ScMarkedDataIter()
+{
+ delete pMarkIter;
+}
+
+BOOL ScMarkedDataIter::Next( SCSIZE& rIndex )
+{
+ BOOL bFound = FALSE;
+ do
+ {
+ if (bNext)
+ {
+ if (!pMarkIter || !pMarkIter->Next( nTop, nBottom ))
+ {
+ if (bAll) // ganze Spalte
+ {
+ nTop = 0;
+ nBottom = MAXROW;
+ }
+ else
+ return FALSE;
+ }
+ pColumn->Search( nTop, nPos );
+ bNext = FALSE;
+ bAll = FALSE; // nur beim ersten Versuch
+ }
+
+ if ( nPos >= pColumn->nCount )
+ return FALSE;
+
+ if ( pColumn->pItems[nPos].nRow <= nBottom )
+ bFound = TRUE;
+ else
+ bNext = TRUE;
+ }
+ while (!bFound);
+
+ rIndex = nPos++;
+ return TRUE;
+}
+
+//UNUSED2009-05 USHORT ScColumn::GetErrorData( SCROW nRow ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 SCSIZE nIndex;
+//UNUSED2009-05 if (Search(nRow, nIndex))
+//UNUSED2009-05 {
+//UNUSED2009-05 ScBaseCell* pCell = pItems[nIndex].pCell;
+//UNUSED2009-05 switch (pCell->GetCellType())
+//UNUSED2009-05 {
+//UNUSED2009-05 case CELLTYPE_FORMULA :
+//UNUSED2009-05 return ((ScFormulaCell*)pCell)->GetErrCode();
+//UNUSED2009-05 // break;
+//UNUSED2009-05 default:
+//UNUSED2009-05 return 0;
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 return 0;
+//UNUSED2009-05 }
+
+//------------
+
+BOOL ScColumn::IsEmptyData() const
+{
+ return (nCount == 0);
+}
+
+BOOL ScColumn::IsEmptyVisData(BOOL bNotes) const
+{
+ if (!pItems || nCount == 0)
+ return TRUE;
+ else
+ {
+ BOOL bVisData = FALSE;
+ SCSIZE i;
+ for (i=0; i<nCount && !bVisData; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
+ bVisData = TRUE;
+ }
+ return !bVisData;
+ }
+}
+
+SCSIZE ScColumn::VisibleCount( SCROW nStartRow, SCROW nEndRow ) const
+{
+ // Notizen werden nicht mitgezaehlt
+
+ SCSIZE nVisCount = 0;
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
+ {
+ if ( pItems[nIndex].nRow >= nStartRow &&
+ pItems[nIndex].pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ ++nVisCount;
+ }
+ ++nIndex;
+ }
+ return nVisCount;
+}
+
+SCROW ScColumn::GetLastVisDataPos(BOOL bNotes) const
+{
+ SCROW nRet = 0;
+ if (pItems)
+ {
+ SCSIZE i;
+ BOOL bFound = FALSE;
+ for (i=nCount; i>0 && !bFound; )
+ {
+ --i;
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
+ {
+ bFound = TRUE;
+ nRet = pItems[i].nRow;
+ }
+ }
+ }
+ return nRet;
+}
+
+SCROW ScColumn::GetFirstVisDataPos(BOOL bNotes) const
+{
+ SCROW nRet = 0;
+ if (pItems)
+ {
+ SCSIZE i;
+ BOOL bFound = FALSE;
+ for (i=0; i<nCount && !bFound; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
+ {
+ bFound = TRUE;
+ nRet = pItems[i].nRow;
+ }
+ }
+ }
+ return nRet;
+}
+
+BOOL ScColumn::HasVisibleDataAt(SCROW nRow) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ if (!pItems[nIndex].pCell->IsBlank())
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL ScColumn::IsEmptyAttr() const
+{
+ if (pAttrArray)
+ return pAttrArray->IsEmpty();
+ else
+ return TRUE;
+}
+
+BOOL ScColumn::IsEmpty() const
+{
+ return (IsEmptyData() && IsEmptyAttr());
+}
+
+BOOL ScColumn::IsEmptyBlock(SCROW nStartRow, SCROW nEndRow, bool bIgnoreNotes) const
+{
+ if ( nCount == 0 || !pItems )
+ return TRUE;
+
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
+ {
+ if ( !pItems[nIndex].pCell->IsBlank( bIgnoreNotes ) ) // found a cell
+ return FALSE; // not empty
+ ++nIndex;
+ }
+ return TRUE; // no cell found
+}
+
+SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const
+{
+ SCSIZE nLines = 0;
+ BOOL bFound = FALSE;
+ SCSIZE i;
+ if (pItems && (nCount > 0))
+ {
+ if (eDir == DIR_BOTTOM)
+ {
+ i = nCount;
+ while (!bFound && (i > 0))
+ {
+ i--;
+ if ( pItems[i].nRow < nStartRow )
+ break;
+ bFound = pItems[i].nRow <= nEndRow && !pItems[i].pCell->IsBlank();
+ }
+ if (bFound)
+ nLines = static_cast<SCSIZE>(nEndRow - pItems[i].nRow);
+ else
+ nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
+ }
+ else if (eDir == DIR_TOP)
+ {
+ i = 0;
+ while (!bFound && (i < nCount))
+ {
+ if ( pItems[i].nRow > nEndRow )
+ break;
+ bFound = pItems[i].nRow >= nStartRow && !pItems[i].pCell->IsBlank();
+ i++;
+ }
+ if (bFound)
+ nLines = static_cast<SCSIZE>(pItems[i-1].nRow - nStartRow);
+ else
+ nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
+ }
+ }
+ else
+ nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
+ return nLines;
+}
+
+SCROW ScColumn::GetFirstDataPos() const
+{
+ if (nCount)
+ return pItems[0].nRow;
+ else
+ return 0;
+}
+
+SCROW ScColumn::GetLastDataPos() const
+{
+ if (nCount)
+ return pItems[nCount-1].nRow;
+ else
+ return 0;
+}
+
+BOOL ScColumn::GetPrevDataPos(SCROW& rRow) const
+{
+ BOOL bFound = FALSE;
+ SCSIZE i = nCount;
+ while (!bFound && (i > 0))
+ {
+ --i;
+ bFound = (pItems[i].nRow < rRow);
+ if (bFound)
+ rRow = pItems[i].nRow;
+ }
+ return bFound;
+}
+
+BOOL ScColumn::GetNextDataPos(SCROW& rRow) const // greater than rRow
+{
+ SCSIZE nIndex;
+ if (Search( rRow, nIndex ))
+ ++nIndex; // next cell
+
+ BOOL bMore = ( nIndex < nCount );
+ if ( bMore )
+ rRow = pItems[nIndex].nRow;
+ return bMore;
+}
+
+void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
+{
+ if (!nMovY) return;
+ BOOL bForward = (nMovY>0);
+
+ SCSIZE nIndex;
+ BOOL bThere = Search(rRow, nIndex);
+ if (bThere && pItems[nIndex].pCell->IsBlank())
+ bThere = FALSE;
+
+ if (bThere)
+ {
+ SCROW nLast = rRow;
+ SCSIZE nOldIndex = nIndex;
+ if (bForward)
+ {
+ if (nIndex<nCount-1)
+ {
+ ++nIndex;
+ while (nIndex<nCount-1 && pItems[nIndex].nRow==nLast+1
+ && !pItems[nIndex].pCell->IsBlank())
+ {
+ ++nIndex;
+ ++nLast;
+ }
+ if (nIndex==nCount-1)
+ if (pItems[nIndex].nRow==nLast+1 && !pItems[nIndex].pCell->IsBlank())
+ ++nLast;
+ }
+ }
+ else
+ {
+ if (nIndex>0)
+ {
+ --nIndex;
+ while (nIndex>0 && pItems[nIndex].nRow+1==nLast
+ && !pItems[nIndex].pCell->IsBlank())
+ {
+ --nIndex;
+ --nLast;
+ }
+ if (nIndex==0)
+ if (pItems[nIndex].nRow+1==nLast && !pItems[nIndex].pCell->IsBlank())
+ --nLast;
+ }
+ }
+ if (nLast==rRow)
+ {
+ bThere = FALSE;
+ nIndex = bForward ? nOldIndex+1 : nOldIndex;
+ }
+ else
+ rRow = nLast;
+ }
+
+ if (!bThere)
+ {
+ if (bForward)
+ {
+ while (nIndex<nCount && pItems[nIndex].pCell->IsBlank())
+ ++nIndex;
+ if (nIndex<nCount)
+ rRow = pItems[nIndex].nRow;
+ else
+ rRow = MAXROW;
+ }
+ else
+ {
+ while (nIndex>0 && pItems[nIndex-1].pCell->IsBlank())
+ --nIndex;
+ if (nIndex>0)
+ rRow = pItems[nIndex-1].nRow;
+ else
+ rRow = 0;
+ }
+ }
+}
+
+BOOL ScColumn::HasDataAt(SCROW nRow) const
+{
+/* SCSIZE nIndex;
+ return Search( nRow, nIndex );
+*/
+ // immer nur sichtbare interessant ?
+ //! dann HasVisibleDataAt raus
+
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ if (!pItems[nIndex].pCell->IsBlank())
+ return TRUE;
+
+ return FALSE;
+
+}
+
+BOOL ScColumn::IsAllAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
+{
+ if (pAttrArray && rCol.pAttrArray)
+ return pAttrArray->IsAllEqual( *rCol.pAttrArray, nStartRow, nEndRow );
+ else
+ return !pAttrArray && !rCol.pAttrArray;
+}
+
+BOOL ScColumn::IsVisibleAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
+{
+ if (pAttrArray && rCol.pAttrArray)
+ return pAttrArray->IsVisibleEqual( *rCol.pAttrArray, nStartRow, nEndRow );
+ else
+ return !pAttrArray && !rCol.pAttrArray;
+}
+
+BOOL ScColumn::GetFirstVisibleAttr( SCROW& rFirstRow ) const
+{
+ if (pAttrArray)
+ return pAttrArray->GetFirstVisibleAttr( rFirstRow );
+ else
+ return FALSE;
+}
+
+BOOL ScColumn::GetLastVisibleAttr( SCROW& rLastRow ) const
+{
+ if (pAttrArray)
+ {
+ // row of last cell is needed
+ SCROW nLastData = GetLastVisDataPos( TRUE ); // always including notes, 0 if none
+
+ return pAttrArray->GetLastVisibleAttr( rLastRow, nLastData );
+ }
+ else
+ return FALSE;
+}
+
+BOOL ScColumn::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const
+{
+ if (pAttrArray)
+ return pAttrArray->HasVisibleAttrIn( nStartRow, nEndRow );
+ else
+ return FALSE;
+}
+
+void ScColumn::FindUsed( SCROW nStartRow, SCROW nEndRow, BOOL* pUsed ) const
+{
+ SCROW nRow = 0;
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEndRow) : FALSE )
+ {
+ pUsed[nRow-nStartRow] = TRUE;
+ ++nIndex;
+ }
+}
+
+void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
+{
+ SvtBroadcaster* pBC = NULL;
+ ScBaseCell* pCell;
+
+ SCSIZE nIndex;
+ if (Search(nRow,nIndex))
+ {
+ pCell = pItems[nIndex].pCell;
+ pBC = pCell->GetBroadcaster();
+ }
+ else
+ {
+ pCell = new ScNoteCell;
+ Insert(nRow, pCell);
+ }
+
+ if (!pBC)
+ {
+ pBC = new SvtBroadcaster;
+ pCell->TakeBroadcaster(pBC);
+ }
+ rLst.StartListening(*pBC);
+}
+
+void ScColumn::MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow )
+{
+ SvtBroadcaster* pBC = NULL;
+ ScBaseCell* pCell;
+
+ SCSIZE nIndex;
+ if (Search(nDestRow,nIndex))
+ {
+ pCell = pItems[nIndex].pCell;
+ pBC = pCell->GetBroadcaster();
+ }
+ else
+ {
+ pCell = new ScNoteCell;
+ Insert(nDestRow, pCell);
+ }
+
+ if (!pBC)
+ {
+ pBC = new SvtBroadcaster;
+ pCell->TakeBroadcaster(pBC);
+ }
+
+ if (rSource.HasListeners())
+ {
+ SvtListenerIter aIter( rSource);
+ for (SvtListener* pLst = aIter.GoStart(); pLst; pLst = aIter.GoNext())
+ {
+ pLst->StartListening( *pBC);
+ pLst->EndListening( rSource);
+ }
+ }
+}
+
+void ScColumn::EndListening( SvtListener& rLst, SCROW nRow )
+{
+ SCSIZE nIndex;
+ if (Search(nRow,nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ SvtBroadcaster* pBC = pCell->GetBroadcaster();
+ if (pBC)
+ {
+ rLst.EndListening(*pBC);
+
+ if (!pBC->HasListeners())
+ {
+ if (pCell->IsBlank())
+ DeleteAtIndex(nIndex);
+ else
+ pCell->DeleteBroadcaster();
+ }
+ }
+// else
+// DBG_ERROR("ScColumn::EndListening - kein Broadcaster");
+ }
+// else
+// DBG_ERROR("ScColumn::EndListening - keine Zelle");
+}
+
+void ScColumn::CompileDBFormula()
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*) pCell)->CompileDBFormula();
+ }
+}
+
+void ScColumn::CompileDBFormula( BOOL bCreateFormulaString )
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*) pCell)->CompileDBFormula( bCreateFormulaString );
+ }
+}
+
+void ScColumn::CompileNameFormula( BOOL bCreateFormulaString )
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*) pCell)->CompileNameFormula( bCreateFormulaString );
+ }
+}
+
+void ScColumn::CompileColRowNameFormula()
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*) pCell)->CompileColRowNameFormula();
+ }
+}
+
+void lcl_UpdateSubTotal( ScFunctionData& rData, ScBaseCell* pCell )
+{
+ double nValue = 0.0;
+ BOOL bVal = FALSE;
+ BOOL bCell = TRUE;
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ nValue = ((ScValueCell*)pCell)->GetValue();
+ bVal = TRUE;
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ if ( rData.eFunc != SUBTOTAL_FUNC_CNT2 ) // da interessiert's nicht
+ {
+ ScFormulaCell* pFC = (ScFormulaCell*)pCell;
+ if ( pFC->GetErrCode() )
+ {
+ if ( rData.eFunc != SUBTOTAL_FUNC_CNT ) // fuer Anzahl einfach weglassen
+ rData.bError = TRUE;
+ }
+ else if (pFC->IsValue())
+ {
+ nValue = pFC->GetValue();
+ bVal = TRUE;
+ }
+ // sonst Text
+ }
+ }
+ break;
+ case CELLTYPE_NOTE:
+ bCell = FALSE;
+ break;
+ // bei Strings nichts
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (!rData.bError)
+ {
+ switch (rData.eFunc)
+ {
+ case SUBTOTAL_FUNC_SUM:
+ case SUBTOTAL_FUNC_AVE:
+ if (bVal)
+ {
+ ++rData.nCount;
+ if (!SubTotal::SafePlus( rData.nVal, nValue ))
+ rData.bError = TRUE;
+ }
+ break;
+ case SUBTOTAL_FUNC_CNT: // nur Werte
+ if (bVal)
+ ++rData.nCount;
+ break;
+ case SUBTOTAL_FUNC_CNT2: // alle
+ if (bCell)
+ ++rData.nCount;
+ break;
+ case SUBTOTAL_FUNC_MAX:
+ if (bVal)
+ if (++rData.nCount == 1 || nValue > rData.nVal )
+ rData.nVal = nValue;
+ break;
+ case SUBTOTAL_FUNC_MIN:
+ if (bVal)
+ if (++rData.nCount == 1 || nValue < rData.nVal )
+ rData.nVal = nValue;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+// Mehrfachselektion:
+void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark,
+ ScFunctionData& rData,
+ ScFlatBoolRowSegments& rHiddenRows,
+ BOOL bDoExclude, SCROW nExStartRow, SCROW nExEndRow )
+{
+ SCSIZE nIndex;
+ ScMarkedDataIter aDataIter(this, &rMark, FALSE);
+ while (aDataIter.Next( nIndex ))
+ {
+ SCROW nRow = pItems[nIndex].nRow;
+ bool bRowHidden = rHiddenRows.getValue(nRow);
+ if ( !bRowHidden )
+ if ( !bDoExclude || nRow < nExStartRow || nRow > nExEndRow )
+ lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
+ }
+}
+
+// bei bNoMarked die Mehrfachselektion weglassen
+void ScColumn::UpdateAreaFunction( ScFunctionData& rData,
+ ScFlatBoolRowSegments& rHiddenRows,
+ SCROW nStartRow, SCROW nEndRow )
+{
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ while ( nIndex<nCount && pItems[nIndex].nRow<=nEndRow )
+ {
+ SCROW nRow = pItems[nIndex].nRow;
+ bool bRowHidden = rHiddenRows.getValue(nRow);
+ if ( !bRowHidden )
+ lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
+ ++nIndex;
+ }
+}
+
+ULONG ScColumn::GetWeightedCount() const
+{
+ ULONG nTotal = 0;
+
+ // Notizen werden nicht gezaehlt
+
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ case CELLTYPE_STRING:
+ ++nTotal;
+ break;
+ case CELLTYPE_FORMULA:
+ nTotal += 5 + ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen();
+ break;
+ case CELLTYPE_EDIT:
+ nTotal += 50;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return nTotal;
+}
+
+ULONG ScColumn::GetCodeCount() const
+{
+ ULONG nCodeCount = 0;
+
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ nCodeCount += ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen();
+ }
+
+ return nCodeCount;
+}
+
+
+
+
+
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
new file mode 100644
index 000000000000..65e896c7f2c4
--- /dev/null
+++ b/sc/source/core/data/column3.cxx
@@ -0,0 +1,2001 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/objsh.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+
+#include "scitems.hxx"
+#include "column.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "attarray.hxx"
+#include "patattr.hxx"
+#include "cellform.hxx"
+#include "collect.hxx"
+#include "formula/errorcodes.hxx"
+#include "formula/token.hxx"
+#include "brdcst.hxx"
+#include "docoptio.hxx" // GetStdPrecision fuer GetMaxNumberStringLen
+#include "subtotal.hxx"
+#include "markdata.hxx"
+#include "detfunc.hxx" // fuer Notizen bei DeleteRange
+#include "postit.hxx"
+#include "stringutil.hxx"
+
+#include <com/sun/star/i18n/LocaleDataItem.hpp>
+
+using ::com::sun::star::i18n::LocaleDataItem;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// Err527 Workaround
+extern const ScFormulaCell* pLastFormulaTreeTop; // in cellform.cxx
+using namespace formula;
+// STATIC DATA -----------------------------------------------------------
+
+BOOL ScColumn::bDoubleAlloc = FALSE; // fuer Import: Groesse beim Allozieren verdoppeln
+
+
+void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
+{
+ BOOL bIsAppended = FALSE;
+ if (pItems && nCount>0)
+ {
+ if (pItems[nCount-1].nRow < nRow)
+ {
+ Append(nRow, pNewCell );
+ bIsAppended = TRUE;
+ }
+ }
+ if ( !bIsAppended )
+ {
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pOldCell = pItems[nIndex].pCell;
+
+ // move broadcaster and note to new cell, if not existing in new cell
+ if (pOldCell->HasBroadcaster() && !pNewCell->HasBroadcaster())
+ pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
+ if (pOldCell->HasNote() && !pNewCell->HasNote())
+ pNewCell->TakeNote( pOldCell->ReleaseNote() );
+
+ if ( pOldCell->GetCellType() == CELLTYPE_FORMULA && !pDocument->IsClipOrUndo() )
+ {
+ pOldCell->EndListeningTo( pDocument );
+ // falls in EndListening NoteCell in gleicher Col zerstoert
+ if ( nIndex >= nCount || pItems[nIndex].nRow != nRow )
+ Search(nRow, nIndex);
+ }
+ pOldCell->Delete();
+ pItems[nIndex].pCell = pNewCell;
+ }
+ else
+ {
+ if (nCount + 1 > nLimit)
+ {
+ if (bDoubleAlloc)
+ {
+ if (nLimit < COLUMN_DELTA)
+ nLimit = COLUMN_DELTA;
+ else
+ {
+ nLimit *= 2;
+ if ( nLimit > sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+ nLimit = MAXROWCOUNT;
+ }
+ }
+ else
+ nLimit += COLUMN_DELTA;
+
+ ColEntry* pNewItems = new ColEntry[nLimit];
+ if (pItems)
+ {
+ memmove( pNewItems, pItems, nCount * sizeof(ColEntry) );
+ delete[] pItems;
+ }
+ pItems = pNewItems;
+ }
+ memmove( &pItems[nIndex + 1], &pItems[nIndex], (nCount - nIndex) * sizeof(ColEntry) );
+ pItems[nIndex].pCell = pNewCell;
+ pItems[nIndex].nRow = nRow;
+ ++nCount;
+ }
+ }
+ // Bei aus Clipboard sind hier noch falsche (alte) Referenzen!
+ // Werden in CopyBlockFromClip per UpdateReference umgesetzt,
+ // danach StartListeningFromClip und BroadcastFromClip gerufen.
+ // Wird ins Clipboard/UndoDoc gestellt, wird kein Broadcast gebraucht.
+ // Nach Import wird CalcAfterLoad gerufen, dort Listening.
+ if ( !(pDocument->IsClipOrUndo() || pDocument->IsInsertingFromOtherDoc()) )
+ {
+ pNewCell->StartListeningTo( pDocument );
+ CellType eCellType = pNewCell->GetCellType();
+ // Notizzelle entsteht beim Laden nur durch StartListeningCell,
+ // ausloesende Formelzelle muss sowieso dirty sein.
+ if ( !(pDocument->IsCalcingAfterLoad() && eCellType == CELLTYPE_NOTE) )
+ {
+ if ( eCellType == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pNewCell)->SetDirty();
+ else
+ pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
+ ScAddress( nCol, nRow, nTab ), pNewCell ) );
+ }
+ }
+}
+
+
+void ScColumn::Insert( SCROW nRow, ULONG nNumberFormat, ScBaseCell* pCell )
+{
+ Insert(nRow, pCell);
+ short eOldType = pDocument->GetFormatTable()->
+ GetType( (ULONG)
+ ((SfxUInt32Item*)GetAttr( nRow, ATTR_VALUE_FORMAT ))->
+ GetValue() );
+ short eNewType = pDocument->GetFormatTable()->GetType(nNumberFormat);
+ if (!pDocument->GetFormatTable()->IsCompatible(eOldType, eNewType))
+ ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT, (UINT32) nNumberFormat) );
+}
+
+
+void ScColumn::Append( SCROW nRow, ScBaseCell* pCell )
+{
+ if (nCount + 1 > nLimit)
+ {
+ if (bDoubleAlloc)
+ {
+ if (nLimit < COLUMN_DELTA)
+ nLimit = COLUMN_DELTA;
+ else
+ {
+ nLimit *= 2;
+ if ( nLimit > sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+ nLimit = MAXROWCOUNT;
+ }
+ }
+ else
+ nLimit += COLUMN_DELTA;
+
+ ColEntry* pNewItems = new ColEntry[nLimit];
+ if (pItems)
+ {
+ memmove( pNewItems, pItems, nCount * sizeof(ColEntry) );
+ delete[] pItems;
+ }
+ pItems = pNewItems;
+ }
+ pItems[nCount].pCell = pCell;
+ pItems[nCount].nRow = nRow;
+ ++nCount;
+}
+
+
+void ScColumn::Delete( SCROW nRow )
+{
+ SCSIZE nIndex;
+
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ ScNoteCell* pNoteCell = new ScNoteCell;
+ pItems[nIndex].pCell = pNoteCell; // Dummy fuer Interpret
+ pDocument->Broadcast( ScHint( SC_HINT_DYING,
+ ScAddress( nCol, nRow, nTab ), pCell ) );
+ if ( SvtBroadcaster* pBC = pCell->ReleaseBroadcaster() )
+ {
+ pNoteCell->TakeBroadcaster( pBC );
+ }
+ else
+ {
+ delete pNoteCell;
+ --nCount;
+ memmove( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(ColEntry) );
+ pItems[nCount].nRow = 0;
+ pItems[nCount].pCell = NULL;
+ // Soll man hier den Speicher freigeben (delta)? Wird dann langsamer!
+ }
+ pCell->EndListeningTo( pDocument );
+ pCell->Delete();
+ }
+}
+
+
+void ScColumn::DeleteAtIndex( SCSIZE nIndex )
+{
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ ScNoteCell* pNoteCell = new ScNoteCell;
+ pItems[nIndex].pCell = pNoteCell; // Dummy fuer Interpret
+ pDocument->Broadcast( ScHint( SC_HINT_DYING,
+ ScAddress( nCol, pItems[nIndex].nRow, nTab ), pCell ) );
+ delete pNoteCell;
+ --nCount;
+ memmove( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(ColEntry) );
+ pItems[nCount].nRow = 0;
+ pItems[nCount].pCell = NULL;
+ pCell->EndListeningTo( pDocument );
+ pCell->Delete();
+}
+
+
+void ScColumn::FreeAll()
+{
+ if (pItems)
+ {
+ for (SCSIZE i = 0; i < nCount; i++)
+ pItems[i].pCell->Delete();
+ delete[] pItems;
+ pItems = NULL;
+ }
+ nCount = 0;
+ nLimit = 0;
+}
+
+
+void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
+{
+ pAttrArray->DeleteRow( nStartRow, nSize );
+
+ if ( !pItems || !nCount )
+ return ;
+
+ SCSIZE nFirstIndex;
+ Search( nStartRow, nFirstIndex );
+ if ( nFirstIndex >= nCount )
+ return ;
+
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+
+ BOOL bFound=FALSE;
+ SCROW nEndRow = nStartRow + nSize - 1;
+ SCSIZE nStartIndex = 0;
+ SCSIZE nEndIndex = 0;
+ SCSIZE i;
+
+ for ( i = nFirstIndex; i < nCount && pItems[i].nRow <= nEndRow; i++ )
+ {
+ if (!bFound)
+ {
+ nStartIndex = i;
+ bFound = TRUE;
+ }
+ nEndIndex = i;
+
+ ScBaseCell* pCell = pItems[i].pCell;
+ SvtBroadcaster* pBC = pCell->GetBroadcaster();
+ if (pBC)
+ {
+// gibt jetzt invalid reference, kein Aufruecken der direkten Referenzen
+// MoveListeners( *pBC, nRow+nSize );
+ pCell->DeleteBroadcaster();
+ // in DeleteRange werden leere Broadcaster geloescht
+ }
+ }
+ if (bFound)
+ {
+ DeleteRange( nStartIndex, nEndIndex, IDF_CONTENTS );
+ Search( nStartRow, i );
+ if ( i >= nCount )
+ {
+ pDocument->SetAutoCalc( bOldAutoCalc );
+ return ;
+ }
+ }
+ else
+ i = nFirstIndex;
+
+ ScAddress aAdr( nCol, 0, nTab );
+ ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)
+ ScAddress& rAddress = aHint.GetAddress();
+ // for sparse occupation use single broadcasts, not ranges
+ BOOL bSingleBroadcasts = (((pItems[nCount-1].nRow - pItems[i].nRow) /
+ (nCount - i)) > 1);
+ if ( bSingleBroadcasts )
+ {
+ SCROW nLastBroadcast = MAXROW+1;
+ for ( ; i < nCount; i++ )
+ {
+ SCROW nOldRow = pItems[i].nRow;
+ // #43940# Aenderung Quelle broadcasten
+ rAddress.SetRow( nOldRow );
+ pDocument->AreaBroadcast( aHint );
+ SCROW nNewRow = (pItems[i].nRow -= nSize);
+ // #43940# Aenderung Ziel broadcasten
+ if ( nLastBroadcast != nNewRow )
+ { // direkt aufeinanderfolgende nicht doppelt broadcasten
+ rAddress.SetRow( nNewRow );
+ pDocument->AreaBroadcast( aHint );
+ }
+ nLastBroadcast = nOldRow;
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
+ }
+ }
+ else
+ {
+ rAddress.SetRow( pItems[i].nRow );
+ ScRange aRange( rAddress );
+ aRange.aEnd.SetRow( pItems[nCount-1].nRow );
+ for ( ; i < nCount; i++ )
+ {
+ SCROW nNewRow = (pItems[i].nRow -= nSize);
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
+ }
+ pDocument->AreaBroadcastInRange( aRange, aHint );
+ }
+
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, USHORT nDelFlag )
+{
+ /* If caller specifies to not remove the note caption objects, all cells
+ have to forget the pointers to them. This is used e.g. while undoing a
+ "paste cells" operation, which removes the caption objects later in
+ drawing undo. */
+ bool bDeleteNote = (nDelFlag & IDF_NOTE) != 0;
+ bool bNoCaptions = (nDelFlag & IDF_NOCAPTIONS) != 0;
+ if (bDeleteNote && bNoCaptions)
+ for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx )
+ if ( ScPostIt* pNote = pItems[ nIdx ].pCell->GetNote() )
+ pNote->ForgetCaption();
+
+ // special simple mode if all contents are deleted and cells do not contain broadcasters
+ bool bSimple = ((nDelFlag & IDF_CONTENTS) == IDF_CONTENTS);
+ if (bSimple)
+ for ( SCSIZE nIdx = nStartIndex; bSimple && (nIdx <= nEndIndex); ++nIdx )
+ if (pItems[ nIdx ].pCell->GetBroadcaster())
+ bSimple = false;
+
+ ScHint aHint( SC_HINT_DYING, ScAddress( nCol, 0, nTab ), 0 );
+
+ // cache all formula cells, they will be deleted at end of this function
+ typedef ::std::vector< ScFormulaCell* > FormulaCellVector;
+ FormulaCellVector aDelCells;
+ aDelCells.reserve( nEndIndex - nStartIndex + 1 );
+
+ // simple deletion of the cell objects
+ if (bSimple)
+ {
+ // pNoteCell: dummy replacement for old cells, to prevent that interpreter uses old cell
+ ScNoteCell* pNoteCell = new ScNoteCell;
+ for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx )
+ {
+ ScBaseCell* pOldCell = pItems[ nIdx ].pCell;
+ if (pOldCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ // cache formula cell, will be deleted below
+ aDelCells.push_back( static_cast< ScFormulaCell* >( pOldCell ) );
+ }
+ else
+ {
+ // interpret in broadcast must not use the old cell
+ pItems[ nIdx ].pCell = pNoteCell;
+ aHint.GetAddress().SetRow( pItems[ nIdx ].nRow );
+ aHint.SetCell( pOldCell );
+ pDocument->Broadcast( aHint );
+ pOldCell->Delete();
+ }
+ }
+ delete pNoteCell;
+ memmove( &pItems[nStartIndex], &pItems[nEndIndex + 1], (nCount - nEndIndex - 1) * sizeof(ColEntry) );
+ nCount -= nEndIndex-nStartIndex+1;
+ }
+
+ // else: delete some contents of the cells
+ else
+ {
+ SCSIZE j = nStartIndex;
+ for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx )
+ {
+ // decide whether to delete the cell object according to passed flags
+ bool bDelete = false;
+ ScBaseCell* pOldCell = pItems[j].pCell;
+ CellType eCellType = pOldCell->GetCellType();
+ switch ( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ {
+ USHORT nValFlags = nDelFlag & (IDF_DATETIME|IDF_VALUE);
+ // delete values and dates?
+ bDelete = nValFlags == (IDF_DATETIME|IDF_VALUE);
+ // if not, decide according to cell number format
+ if( !bDelete && (nValFlags != 0) )
+ {
+ ULONG nIndex = (ULONG)((SfxUInt32Item*)GetAttr( pItems[j].nRow, ATTR_VALUE_FORMAT ))->GetValue();
+ short nType = pDocument->GetFormatTable()->GetType(nIndex);
+ bool bIsDate = (nType == NUMBERFORMAT_DATE) || (nType == NUMBERFORMAT_TIME) || (nType == NUMBERFORMAT_DATETIME);
+ bDelete = nValFlags == (bIsDate ? IDF_DATETIME : IDF_VALUE);
+ }
+ }
+ break;
+
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ bDelete = (nDelFlag & IDF_STRING) != 0;
+ break;
+
+ case CELLTYPE_FORMULA:
+ bDelete = (nDelFlag & IDF_FORMULA) != 0;
+ break;
+
+ case CELLTYPE_NOTE:
+ // do note delete note cell with broadcaster
+ bDelete = bDeleteNote && !pOldCell->GetBroadcaster();
+ break;
+
+ default:; // added to avoid warnings
+ }
+
+ if (bDelete)
+ {
+ // try to create a replacement note cell, if note or broadcaster exists
+ ScNoteCell* pNoteCell = 0;
+ if (eCellType != CELLTYPE_NOTE)
+ {
+ // do not rescue note if it has to be deleted according to passed flags
+ ScPostIt* pNote = bDeleteNote ? 0 : pOldCell->ReleaseNote();
+ // #i99844# do not release broadcaster from old cell, it still has to notify deleted content
+ SvtBroadcaster* pBC = pOldCell->GetBroadcaster();
+ if( pNote || pBC )
+ pNoteCell = new ScNoteCell( pNote, pBC );
+ }
+
+ // remove cell entry in cell item list
+ SCROW nOldRow = pItems[j].nRow;
+ if (pNoteCell)
+ {
+ // replace old cell with the replacement note cell
+ pItems[j].pCell = pNoteCell;
+ ++j;
+ }
+ else
+ {
+ // remove the old cell from the cell item list
+ --nCount;
+ memmove( &pItems[j], &pItems[j + 1], (nCount - j) * sizeof(ColEntry) );
+ pItems[nCount].nRow = 0;
+ pItems[nCount].pCell = 0;
+ }
+
+ // cache formula cells (will be deleted later), delete cell of other type
+ if (eCellType == CELLTYPE_FORMULA)
+ {
+ aDelCells.push_back( static_cast< ScFormulaCell* >( pOldCell ) );
+ }
+ else
+ {
+ aHint.GetAddress().SetRow( nOldRow );
+ aHint.SetCell( pOldCell );
+ pDocument->Broadcast( aHint );
+ // #i99844# after broadcasting, old cell has to forget the broadcaster (owned by pNoteCell)
+ pOldCell->ReleaseBroadcaster();
+ pOldCell->Delete();
+ }
+ }
+ else
+ {
+ // delete cell note
+ if (bDeleteNote)
+ pItems[j].pCell->DeleteNote();
+ // cell not deleted, move index to next cell
+ ++j;
+ }
+ }
+ }
+
+ // *** delete all formula cells ***
+
+ // first, all cells stop listening, may save unneeded recalcualtions
+ 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 )
+ {
+ aHint.SetAddress( (*aIt)->aPos );
+ aHint.SetCell( *aIt );
+ pDocument->Broadcast( aHint );
+ // #i99844# after broadcasting, old cell has to forget the broadcaster (owned by replacement note cell)
+ (*aIt)->ReleaseBroadcaster();
+ (*aIt)->Delete();
+ }
+}
+
+
+void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, USHORT nDelFlag)
+{
+ // FreeAll darf hier nicht gerufen werden wegen Broadcastern
+
+ // Attribute erst am Ende, damit vorher noch zwischen Zahlen und Datum
+ // unterschieden werden kann (#47901#)
+
+ USHORT nContMask = IDF_CONTENTS;
+ // IDF_NOCAPTIONS needs to be passed too, if IDF_NOTE is set
+ if( nDelFlag & IDF_NOTE )
+ nContMask |= IDF_NOCAPTIONS;
+ USHORT nContFlag = nDelFlag & nContMask;
+
+ if (pItems && nCount>0 && nContFlag)
+ {
+ if (nStartRow==0 && nEndRow==MAXROW)
+ DeleteRange( 0, nCount-1, nContFlag );
+ else
+ {
+ BOOL bFound=FALSE;
+ SCSIZE nStartIndex = 0;
+ SCSIZE nEndIndex = 0;
+ for (SCSIZE i = 0; i < nCount; i++)
+ if ((pItems[i].nRow >= nStartRow) && (pItems[i].nRow <= nEndRow))
+ {
+ if (!bFound)
+ {
+ nStartIndex = i;
+ bFound = TRUE;
+ }
+ nEndIndex = i;
+ }
+ if (bFound)
+ DeleteRange( nStartIndex, nEndIndex, nContFlag );
+ }
+ }
+
+ if ( nDelFlag & IDF_EDITATTR )
+ {
+ DBG_ASSERT( nContFlag == 0, "DeleteArea: falsche Flags" );
+ RemoveEditAttribs( nStartRow, nEndRow );
+ }
+
+ // Attribute erst hier
+ if ((nDelFlag & IDF_ATTRIB) == IDF_ATTRIB) pAttrArray->DeleteArea( nStartRow, nEndRow );
+ else if ((nDelFlag & IDF_ATTRIB) != 0) pAttrArray->DeleteHardAttr( nStartRow, nEndRow );
+}
+
+
+ScFormulaCell* ScColumn::CreateRefCell( ScDocument* pDestDoc, const ScAddress& rDestPos,
+ SCSIZE nIndex, USHORT nFlags ) const
+{
+ USHORT nContFlags = nFlags & IDF_CONTENTS;
+ if (!nContFlags)
+ return NULL;
+
+ // Testen, ob Zelle kopiert werden soll
+ // auch bei IDF_CONTENTS komplett, wegen Notes / Broadcastern
+
+ BOOL bMatch = FALSE;
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ CellType eCellType = pCell->GetCellType();
+ switch ( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ {
+ USHORT nValFlags = nFlags & (IDF_DATETIME|IDF_VALUE);
+
+ if ( nValFlags == (IDF_DATETIME|IDF_VALUE) )
+ bMatch = TRUE;
+ else if ( nValFlags )
+ {
+ ULONG nNumIndex = (ULONG)((SfxUInt32Item*)GetAttr(
+ pItems[nIndex].nRow, ATTR_VALUE_FORMAT ))->GetValue();
+ short nTyp = pDocument->GetFormatTable()->GetType(nNumIndex);
+ if ((nTyp == NUMBERFORMAT_DATE) || (nTyp == NUMBERFORMAT_TIME) || (nTyp == NUMBERFORMAT_DATETIME))
+ bMatch = ((nFlags & IDF_DATETIME) != 0);
+ else
+ bMatch = ((nFlags & IDF_VALUE) != 0);
+ }
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT: bMatch = ((nFlags & IDF_STRING) != 0); break;
+ case CELLTYPE_FORMULA: bMatch = ((nFlags & IDF_FORMULA) != 0); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if (!bMatch)
+ return NULL;
+
+
+ // Referenz einsetzen
+ ScSingleRefData aRef;
+ aRef.nCol = nCol;
+ aRef.nRow = pItems[nIndex].nRow;
+ aRef.nTab = nTab;
+ aRef.InitFlags(); // -> alles absolut
+ aRef.SetFlag3D(TRUE);
+
+ //! 3D(FALSE) und TabRel(TRUE), wenn die endgueltige Position auf der selben Tabelle ist?
+ //! (bei TransposeClip ist die Zielposition noch nicht bekannt)
+
+ aRef.CalcRelFromAbs( rDestPos );
+
+ ScTokenArray aArr;
+ aArr.AddSingleReference( aRef );
+
+ return new ScFormulaCell( pDestDoc, rDestPos, &aArr );
+}
+
+
+// rColumn = Quelle
+// nRow1, nRow2 = Zielposition
+
+void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
+ USHORT nInsFlag, BOOL bAsLink, BOOL bSkipAttrForEmpty,
+ ScColumn& rColumn)
+{
+ if ((nInsFlag & IDF_ATTRIB) != 0)
+ {
+ if ( bSkipAttrForEmpty )
+ {
+ // copy only attributes for non-empty cells
+ // (notes are not counted as non-empty here, to match the content behavior)
+
+ SCSIZE nStartIndex;
+ rColumn.Search( nRow1-nDy, nStartIndex );
+ while ( nStartIndex < rColumn.nCount && rColumn.pItems[nStartIndex].nRow <= nRow2-nDy )
+ {
+ SCSIZE nEndIndex = nStartIndex;
+ if ( rColumn.pItems[nStartIndex].pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ SCROW nStartRow = rColumn.pItems[nStartIndex].nRow;
+ SCROW nEndRow = nStartRow;
+
+ // find consecutive non-empty cells
+
+ while ( nEndRow < nRow2-nDy &&
+ nEndIndex+1 < rColumn.nCount &&
+ rColumn.pItems[nEndIndex+1].nRow == nEndRow+1 &&
+ rColumn.pItems[nEndIndex+1].pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ ++nEndIndex;
+ ++nEndRow;
+ }
+
+ rColumn.pAttrArray->CopyAreaSafe( nStartRow+nDy, nEndRow+nDy, nDy, *pAttrArray );
+ }
+ nStartIndex = nEndIndex + 1;
+ }
+ }
+ else
+ rColumn.pAttrArray->CopyAreaSafe( nRow1, nRow2, nDy, *pAttrArray );
+ }
+ if ((nInsFlag & IDF_CONTENTS) == 0)
+ return;
+
+ if ( bAsLink && nInsFlag == IDF_ALL )
+ {
+ // bei "alles" werden auch leere Zellen referenziert
+ //! IDF_ALL muss immer mehr Flags enthalten, als bei "Inhalte Einfuegen"
+ //! einzeln ausgewaehlt werden koennen!
+
+ Resize( nCount + static_cast<SCSIZE>(nRow2-nRow1+1) );
+
+ ScAddress aDestPos( nCol, 0, nTab ); // Row wird angepasst
+
+ // Referenz erzeugen (Quell-Position)
+ ScSingleRefData aRef;
+ aRef.nCol = rColumn.nCol;
+ // nRow wird angepasst
+ aRef.nTab = rColumn.nTab;
+ aRef.InitFlags(); // -> alles absolut
+ aRef.SetFlag3D(TRUE);
+
+ for (SCROW nDestRow = nRow1; nDestRow <= nRow2; nDestRow++)
+ {
+ aRef.nRow = nDestRow - nDy; // Quell-Zeile
+ aDestPos.SetRow( nDestRow );
+
+ aRef.CalcRelFromAbs( aDestPos );
+ ScTokenArray aArr;
+ aArr.AddSingleReference( aRef );
+ Insert( nDestRow, new ScFormulaCell( pDocument, aDestPos, &aArr ) );
+ }
+
+ return;
+ }
+
+ SCSIZE nColCount = rColumn.nCount;
+
+ // ignore IDF_FORMULA - "all contents but no formulas" results in the same number of cells
+ if ((nInsFlag & ( IDF_CONTENTS & ~IDF_FORMULA )) == ( IDF_CONTENTS & ~IDF_FORMULA ) && nRow2-nRow1 >= 64)
+ {
+ //! Always do the Resize from the outside, where the number of repetitions is known
+ //! (then it can be removed here)
+
+ SCSIZE nNew = nCount + nColCount;
+ if ( nLimit < nNew )
+ 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++)
+ {
+ SCsROW nDestRow = rColumn.pItems[i].nRow + nDy;
+ if ( nDestRow > (SCsROW) nRow2 )
+ bAtEnd = TRUE;
+ else if ( nDestRow >= (SCsROW) nRow1 )
+ {
+ // rows at the beginning may be skipped if filtered rows are left out,
+ // nDestRow may be negative then
+
+ ScAddress aDestPos( nCol, (SCROW)nDestRow, nTab );
+
+ /* #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 );
+ }
+ }
+ }
+}
+
+
+namespace {
+
+/** Helper for ScColumn::CloneCell - decides whether to clone a value cell depending on clone flags and number format. */
+bool lclCanCloneValue( ScDocument& rDoc, const ScColumn& rCol, SCROW nRow, bool bCloneValue, bool bCloneDateTime )
+{
+ // values and dates, or nothing to be cloned -> not needed to check number format
+ if( bCloneValue == bCloneDateTime )
+ return bCloneValue;
+
+ // check number format of value cell
+ ULONG nNumIndex = (ULONG)((SfxUInt32Item*)rCol.GetAttr( nRow, ATTR_VALUE_FORMAT ))->GetValue();
+ short nTyp = rDoc.GetFormatTable()->GetType( nNumIndex );
+ bool bIsDateTime = (nTyp == NUMBERFORMAT_DATE) || (nTyp == NUMBERFORMAT_TIME) || (nTyp == NUMBERFORMAT_DATETIME);
+ return bIsDateTime ? bCloneDateTime : bCloneValue;
+}
+
+} // namespace
+
+
+ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, USHORT nFlags, ScDocument& rDestDoc, const ScAddress& rDestPos)
+{
+ bool bCloneValue = (nFlags & IDF_VALUE) != 0;
+ bool bCloneDateTime = (nFlags & IDF_DATETIME) != 0;
+ bool bCloneString = (nFlags & IDF_STRING) != 0;
+ bool bCloneFormula = (nFlags & IDF_FORMULA) != 0;
+ bool bCloneNote = (nFlags & IDF_NOTE) != 0;
+
+ ScBaseCell* pNew = 0;
+ ScBaseCell& rSource = *pItems[nIndex].pCell;
+ switch (rSource.GetCellType())
+ {
+ case CELLTYPE_NOTE:
+ // note will be cloned below
+ break;
+
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ // note will be cloned below
+ if (bCloneString)
+ pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos );
+ break;
+
+ case CELLTYPE_VALUE:
+ // note will be cloned below
+ if (lclCanCloneValue( *pDocument, *this, pItems[nIndex].nRow, bCloneValue, bCloneDateTime ))
+ pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos );
+ break;
+
+ case CELLTYPE_FORMULA:
+ if (bCloneFormula)
+ {
+ // note will be cloned below
+ pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos );
+ }
+ else if ( (bCloneValue || bCloneDateTime || bCloneString) && !rDestDoc.IsUndo() )
+ {
+ // #48491# ins Undo-Dokument immer nur die Original-Zelle kopieren,
+ // aus Formeln keine Value/String-Zellen erzeugen
+ ScFormulaCell& rForm = (ScFormulaCell&)rSource;
+ USHORT nErr = rForm.GetErrCode();
+ if ( nErr )
+ {
+ // error codes are cloned with values
+ if (bCloneValue)
+ {
+ ScFormulaCell* pErrCell = new ScFormulaCell( &rDestDoc, rDestPos );
+ pErrCell->SetErrCode( nErr );
+ pNew = pErrCell;
+ }
+ }
+ else if (rForm.IsValue())
+ {
+ if (lclCanCloneValue( *pDocument, *this, pItems[nIndex].nRow, bCloneValue, bCloneDateTime ))
+ {
+ double nVal = rForm.GetValue();
+ pNew = new ScValueCell(nVal);
+ }
+ }
+ else if (bCloneString)
+ {
+ String aString;
+ rForm.GetString( aString );
+ // #33224# do not clone empty string
+ if (aString.Len() > 0)
+ {
+ if ( rForm.IsMultilineResult() )
+ {
+ pNew = new ScEditCell( aString, &rDestDoc );
+ }
+ else
+ {
+ pNew = new ScStringCell( aString );
+ }
+ }
+ }
+ }
+ break;
+
+ default: DBG_ERRORFILE( "ScColumn::CloneCell - unknown cell type" );
+ }
+
+ // clone the cell note
+ if (bCloneNote)
+ {
+ if (ScPostIt* pNote = rSource.GetNote())
+ {
+ bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0;
+ // #i52342# if caption is cloned, the note must be constructed with the destination document
+ ScAddress aOwnPos( nCol, pItems[nIndex].nRow, nTab );
+ ScPostIt* pNewNote = pNote->Clone( aOwnPos, rDestDoc, rDestPos, bCloneCaption );
+ if (!pNew)
+ pNew = new ScNoteCell( pNewNote );
+ else
+ pNew->TakeNote( pNewNote );
+ }
+ }
+
+ return pNew;
+}
+
+
+void ScColumn::MixMarked( const ScMarkData& rMark, USHORT nFunction,
+ BOOL bSkipEmpty, ScColumn& rSrcCol )
+{
+ SCROW nRow1, nRow2;
+
+ if (rMark.IsMultiMarked())
+ {
+ ScMarkArrayIter aIter( rMark.GetArray()+nCol );
+ while (aIter.Next( nRow1, nRow2 ))
+ MixData( nRow1, nRow2, nFunction, bSkipEmpty, rSrcCol );
+ }
+}
+
+
+// Ergebnis in rVal1
+
+BOOL lcl_DoFunction( double& rVal1, double nVal2, USHORT nFunction )
+{
+ BOOL bOk = FALSE;
+ switch (nFunction)
+ {
+ case PASTE_ADD:
+ bOk = SubTotal::SafePlus( rVal1, nVal2 );
+ break;
+ case PASTE_SUB:
+ nVal2 = -nVal2; //! geht das immer ohne Fehler?
+ bOk = SubTotal::SafePlus( rVal1, nVal2 );
+ break;
+ case PASTE_MUL:
+ bOk = SubTotal::SafeMult( rVal1, nVal2 );
+ break;
+ case PASTE_DIV:
+ bOk = SubTotal::SafeDiv( rVal1, nVal2 );
+ break;
+ }
+ return bOk;
+}
+
+
+void lcl_AddCode( ScTokenArray& rArr, ScFormulaCell* pCell )
+{
+ rArr.AddOpCode(ocOpen);
+
+ ScTokenArray* pCode = pCell->GetCode();
+ if (pCode)
+ {
+ const formula::FormulaToken* pToken = pCode->First();
+ while (pToken)
+ {
+ rArr.AddToken( *pToken );
+ pToken = pCode->Next();
+ }
+ }
+
+ rArr.AddOpCode(ocClose);
+}
+
+
+void ScColumn::MixData( SCROW nRow1, SCROW nRow2,
+ USHORT nFunction, BOOL bSkipEmpty,
+ ScColumn& rSrcCol )
+{
+ SCSIZE nSrcCount = rSrcCol.nCount;
+
+ SCSIZE nIndex;
+ Search( nRow1, nIndex );
+
+// SCSIZE nSrcIndex = 0;
+ SCSIZE nSrcIndex;
+ rSrcCol.Search( nRow1, nSrcIndex ); //! Testen, ob Daten ganz vorne
+
+ SCROW nNextThis = MAXROW+1;
+ if ( nIndex < nCount )
+ nNextThis = pItems[nIndex].nRow;
+ SCROW nNextSrc = MAXROW+1;
+ if ( nSrcIndex < nSrcCount )
+ nNextSrc = rSrcCol.pItems[nSrcIndex].nRow;
+
+ while ( nNextThis <= nRow2 || nNextSrc <= nRow2 )
+ {
+ SCROW nRow = Min( nNextThis, nNextSrc );
+
+ ScBaseCell* pSrc = NULL;
+ ScBaseCell* pDest = NULL;
+ ScBaseCell* pNew = NULL;
+ BOOL bDelete = FALSE;
+
+ if ( nSrcIndex < nSrcCount && nNextSrc == nRow )
+ pSrc = rSrcCol.pItems[nSrcIndex].pCell;
+
+ if ( nIndex < nCount && nNextThis == nRow )
+ pDest = pItems[nIndex].pCell;
+
+ DBG_ASSERT( pSrc || pDest, "Nanu ?" );
+
+ CellType eSrcType = pSrc ? pSrc->GetCellType() : CELLTYPE_NONE;
+ CellType eDestType = pDest ? pDest->GetCellType() : CELLTYPE_NONE;
+
+ BOOL bSrcEmpty = ( eSrcType == CELLTYPE_NONE || eSrcType == CELLTYPE_NOTE );
+ BOOL bDestEmpty = ( eDestType == CELLTYPE_NONE || eDestType == CELLTYPE_NOTE );
+
+ if ( bSkipEmpty && bDestEmpty ) // Originalzelle wiederherstellen
+ {
+ if ( pSrc ) // war da eine Zelle?
+ {
+ pNew = pSrc->CloneWithoutNote( *pDocument );
+ }
+ }
+ else if ( nFunction ) // wirklich Rechenfunktion angegeben
+ {
+ double nVal1;
+ double nVal2;
+ if ( eSrcType == CELLTYPE_VALUE )
+ nVal1 = ((ScValueCell*)pSrc)->GetValue();
+ else
+ nVal1 = 0.0;
+ if ( eDestType == CELLTYPE_VALUE )
+ nVal2 = ((ScValueCell*)pDest)->GetValue();
+ else
+ nVal2 = 0.0;
+
+ // leere Zellen werden als Werte behandelt
+
+ BOOL bSrcVal = ( bSrcEmpty || eSrcType == CELLTYPE_VALUE );
+ BOOL bDestVal = ( bDestEmpty || eDestType == CELLTYPE_VALUE );
+
+ BOOL bSrcText = ( eSrcType == CELLTYPE_STRING ||
+ eSrcType == CELLTYPE_EDIT );
+ BOOL bDestText = ( eDestType == CELLTYPE_STRING ||
+ eDestType == CELLTYPE_EDIT );
+
+ // sonst bleibt nur Formel...
+
+ if ( bSrcEmpty && bDestEmpty )
+ {
+ // beide leer -> nix
+ }
+ else if ( bSrcVal && bDestVal )
+ {
+ // neuen Wert eintragen, oder Fehler bei Ueberlauf
+
+ BOOL bOk = lcl_DoFunction( nVal1, nVal2, nFunction );
+
+ if (bOk)
+ pNew = new ScValueCell( nVal1 );
+ else
+ {
+ ScFormulaCell* pFC = new ScFormulaCell( pDocument,
+ ScAddress( nCol, nRow, nTab ) );
+ pFC->SetErrCode( errNoValue );
+ //! oder NOVALUE, dann auch in consoli,
+ //! sonst in Interpreter::GetCellValue die Abfrage auf errNoValue raus
+ //! (dann geht Stringzelle+Wertzelle nicht mehr)
+ pNew = pFC;
+ }
+ }
+ else if ( bSrcText || bDestText )
+ {
+ // mit Texten wird nicht gerechnet - immer "alte" Zelle, also pSrc
+
+ if (pSrc)
+ pNew = pSrc->CloneWithoutNote( *pDocument );
+ else if (pDest)
+ bDelete = TRUE;
+ }
+ else
+ {
+ // Kombination aus Wert und mindestens einer Formel -> Formel erzeugen
+
+ ScTokenArray aArr;
+
+ // erste Zelle
+ if ( eSrcType == CELLTYPE_FORMULA )
+ lcl_AddCode( aArr, (ScFormulaCell*)pSrc );
+ else
+ aArr.AddDouble( nVal1 );
+
+ // Operator
+ OpCode eOp = ocAdd;
+ switch ( nFunction )
+ {
+ case PASTE_ADD: eOp = ocAdd; break;
+ case PASTE_SUB: eOp = ocSub; break;
+ case PASTE_MUL: eOp = ocMul; break;
+ case PASTE_DIV: eOp = ocDiv; break;
+ }
+ aArr.AddOpCode(eOp); // Funktion
+
+ // zweite Zelle
+ if ( eDestType == CELLTYPE_FORMULA )
+ lcl_AddCode( aArr, (ScFormulaCell*)pDest );
+ else
+ aArr.AddDouble( nVal2 );
+
+ pNew = new ScFormulaCell( pDocument, ScAddress( nCol, nRow, nTab ), &aArr );
+ }
+ }
+
+
+ if ( pNew || bDelete ) // neues Ergebnis ?
+ {
+ if (pDest && !pNew) // alte Zelle da ?
+ {
+ if ( pDest->GetBroadcaster() )
+ pNew = new ScNoteCell; // Broadcaster uebernehmen
+ else
+ Delete(nRow); // -> loeschen
+ }
+ if (pNew)
+ Insert(nRow, pNew); // neue einfuegen
+
+ Search( nRow, nIndex ); // alles kann sich verschoben haben
+ if (pNew)
+ nNextThis = nRow; // nIndex zeigt jetzt genau auf nRow
+ else
+ nNextThis = ( nIndex < nCount ) ? pItems[nIndex].nRow : MAXROW+1;
+ }
+
+ if ( nNextThis == nRow )
+ {
+ ++nIndex;
+ nNextThis = ( nIndex < nCount ) ? pItems[nIndex].nRow : MAXROW+1;
+ }
+ if ( nNextSrc == nRow )
+ {
+ ++nSrcIndex;
+ nNextSrc = ( nSrcIndex < nSrcCount ) ?
+ rSrcCol.pItems[nSrcIndex].nRow :
+ MAXROW+1;
+ }
+ }
+}
+
+
+ScAttrIterator* ScColumn::CreateAttrIterator( SCROW nStartRow, SCROW nEndRow ) const
+{
+ return new ScAttrIterator( pAttrArray, nStartRow, nEndRow );
+}
+
+
+void ScColumn::StartAllListeners()
+{
+ if (pItems)
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ SCROW nRow = pItems[i].nRow;
+ ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener eingefuegt?
+ }
+ }
+}
+
+
+void ScColumn::StartNeededListeners()
+{
+ if (pItems)
+ {
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ ScBaseCell* pCell = pItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if (pFCell->NeedsListening())
+ {
+ SCROW nRow = pItems[i].nRow;
+ pFCell->StartListeningTo( pDocument );
+ if ( nRow != pItems[i].nRow )
+ Search( nRow, i ); // Listener eingefuegt?
+ }
+ }
+ }
+ }
+}
+
+
+void ScColumn::BroadcastInArea( SCROW nRow1, SCROW nRow2 )
+{
+ if ( pItems )
+ {
+ SCROW nRow;
+ SCSIZE nIndex;
+ Search( nRow1, nIndex );
+ while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRow2 )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->SetDirty();
+ else
+ pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
+ ScAddress( nCol, nRow, nTab ), pCell ) );
+ nIndex++;
+ }
+ }
+}
+
+
+void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 )
+{
+ if ( pItems )
+ {
+ SCROW nRow;
+ SCSIZE nIndex;
+ Search( nRow1, nIndex );
+ while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRow2 )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
+ if ( nRow != pItems[nIndex].nRow )
+ Search( nRow, nIndex ); // durch Listening eingefuegt
+ nIndex++;
+ }
+ }
+}
+
+
+// TRUE = Zahlformat gesetzt
+BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
+ formula::FormulaGrammar::AddressConvention eConv,
+ SvNumberFormatter* pLangFormatter, bool bDetectNumberFormat )
+{
+ BOOL bNumFmtSet = FALSE;
+ if (VALIDROW(nRow))
+ {
+ ScBaseCell* pNewCell = NULL;
+ BOOL bIsLoading = FALSE;
+ if (rString.Len() > 0)
+ {
+ double nVal;
+ sal_uInt32 nIndex, nOldIndex = 0;
+ sal_Unicode cFirstChar;
+ // #i110979# If a different NumberFormatter is passed in (pLangFormatter),
+ // its formats aren't valid in the document.
+ // Only use the language / LocaleDataWrapper from pLangFormatter,
+ // always the document's number formatter for IsNumberFormat.
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
+ if ( pDocSh )
+ bIsLoading = pDocSh->IsLoading();
+ // IsLoading bei ConvertFrom Import
+ if ( !bIsLoading )
+ {
+ nIndex = nOldIndex = GetNumberFormat( nRow );
+ if ( rString.Len() > 1
+ && pFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
+ cFirstChar = rString.GetChar(0);
+ else
+ cFirstChar = 0; // Text
+ }
+ else
+ { // waehrend ConvertFrom Import gibt es keine gesetzten Formate
+ cFirstChar = rString.GetChar(0);
+ }
+
+ if ( cFirstChar == '=' )
+ {
+ if ( rString.Len() == 1 ) // = Text
+ pNewCell = new ScStringCell( rString );
+ else // =Formel
+ pNewCell = new ScFormulaCell( pDocument,
+ ScAddress( nCol, nRow, nTabP ), rString,
+ formula::FormulaGrammar::mergeToGrammar( formula::FormulaGrammar::GRAM_DEFAULT,
+ eConv), MM_NONE );
+ }
+ else if ( cFirstChar == '\'') // 'Text
+ pNewCell = new ScStringCell( rString.Copy(1) );
+ else
+ {
+ BOOL bIsText = FALSE;
+ if ( bIsLoading )
+ {
+ if ( pItems && nCount )
+ {
+ String aStr;
+ SCSIZE i = nCount;
+ SCSIZE nStop = (i >= 3 ? i - 3 : 0);
+ // die letzten Zellen vergleichen, ob gleicher String
+ // und IsNumberFormat eingespart werden kann
+ do
+ {
+ i--;
+ ScBaseCell* pCell = pItems[i].pCell;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_STRING :
+ ((ScStringCell*)pCell)->GetString( aStr );
+ if ( rString == aStr )
+ bIsText = TRUE;
+ break;
+ case CELLTYPE_NOTE : // durch =Formel referenziert
+ break;
+ default:
+ if ( i == nCount - 1 )
+ i = 0;
+ // wahrscheinlich ganze Spalte kein String
+ }
+ } while ( i && i > nStop && !bIsText );
+ }
+ // nIndex fuer IsNumberFormat vorbelegen
+ if ( !bIsText )
+ nIndex = nOldIndex = pFormatter->GetStandardIndex();
+ }
+
+ do
+ {
+ if (bIsText)
+ break;
+
+ if (bDetectNumberFormat)
+ {
+ if ( pLangFormatter )
+ {
+ // for number detection: valid format index for selected language
+ nIndex = pFormatter->GetStandardIndex( pLangFormatter->GetLanguage() );
+ }
+
+ if (!pFormatter->IsNumberFormat(rString, nIndex, nVal))
+ break;
+
+ if ( pLangFormatter )
+ {
+ // convert back to the original language if a built-in format was detected
+ const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex );
+ if ( pOldFormat )
+ nIndex = pFormatter->GetFormatForLanguageIfBuiltIn( nIndex, pOldFormat->GetLanguage() );
+ }
+
+ pNewCell = new ScValueCell( nVal );
+ if ( nIndex != nOldIndex)
+ {
+ // #i22345# New behavior: Apply the detected number format only if
+ // the old one was the default number, date, time or boolean format.
+ // Exception: If the new format is boolean, always apply it.
+
+ BOOL bOverwrite = FALSE;
+ const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex );
+ if ( pOldFormat )
+ {
+ short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED;
+ if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE ||
+ nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL )
+ {
+ if ( nOldIndex == pFormatter->GetStandardFormat(
+ nOldType, pOldFormat->GetLanguage() ) )
+ {
+ bOverwrite = TRUE; // default of these types can be overwritten
+ }
+ }
+ }
+ if ( !bOverwrite && pFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL )
+ {
+ bOverwrite = TRUE; // overwrite anything if boolean was detected
+ }
+
+ if ( bOverwrite )
+ {
+ ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT,
+ (UINT32) nIndex) );
+ bNumFmtSet = TRUE;
+ }
+ }
+ }
+ else
+ {
+ // Only check if the string is a regular number.
+ SvNumberFormatter* pLocaleSource = pLangFormatter ? pLangFormatter : pFormatter;
+ const LocaleDataWrapper* pLocale = pLocaleSource->GetLocaleData();
+ if (!pLocale)
+ break;
+
+ LocaleDataItem aLocaleItem = pLocale->getLocaleItem();
+ const OUString& rDecSep = aLocaleItem.decimalSeparator;
+ const OUString& rGroupSep = aLocaleItem.thousandSeparator;
+ if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1)
+ break;
+
+ sal_Unicode dsep = rDecSep.getStr()[0];
+ sal_Unicode gsep = rGroupSep.getStr()[0];
+
+ if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, nVal))
+ break;
+
+ pNewCell = new ScValueCell(nVal);
+ }
+ }
+ while (false);
+
+ if (!pNewCell)
+ pNewCell = new ScStringCell(rString);
+ }
+ }
+
+ if ( bIsLoading && (!nCount || nRow > pItems[nCount-1].nRow) )
+ { // Search einsparen und ohne Umweg ueber Insert, Listener aufbauen
+ // und Broadcast kommt eh erst nach dem Laden
+ if ( pNewCell )
+ Append( nRow, pNewCell );
+ }
+ else
+ {
+ SCSIZE i;
+ if (Search(nRow, i))
+ {
+ ScBaseCell* pOldCell = pItems[i].pCell;
+ ScPostIt* pNote = pOldCell->ReleaseNote();
+ SvtBroadcaster* pBC = pOldCell->ReleaseBroadcaster();
+ if (pNewCell || pNote || pBC)
+ {
+ if (pNewCell)
+ pNewCell->TakeNote( pNote );
+ else
+ pNewCell = new ScNoteCell( pNote );
+ if (pBC)
+ {
+ pNewCell->TakeBroadcaster(pBC);
+ pLastFormulaTreeTop = 0; // Err527 Workaround
+ }
+
+ if ( pOldCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ pOldCell->EndListeningTo( pDocument );
+ // falls in EndListening NoteCell in gleicher Col zerstoert
+ if ( i >= nCount || pItems[i].nRow != nRow )
+ Search(nRow, i);
+ }
+ pOldCell->Delete();
+ pItems[i].pCell = pNewCell; // ersetzen
+ if ( pNewCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ pNewCell->StartListeningTo( pDocument );
+ ((ScFormulaCell*)pNewCell)->SetDirty();
+ }
+ else
+ pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
+ ScAddress( nCol, nRow, nTabP ), pNewCell ) );
+ }
+ else
+ {
+ DeleteAtIndex(i); // loeschen und Broadcast
+ }
+ }
+ else if (pNewCell)
+ {
+ Insert(nRow, pNewCell); // neu eintragen und Broadcast
+ }
+ }
+
+ // hier keine Formate mehr fuer Formeln setzen!
+ // (werden bei der Ausgabe abgefragt)
+
+ }
+ return bNumFmtSet;
+}
+
+
+void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollection& rStrings, bool& rHasDates)
+{
+ bool bHasDates = false;
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ String aString;
+ SCROW nRow = 0;
+ SCSIZE nIndex;
+
+ Search( nStartRow, nIndex );
+
+ while ( (nIndex < nCount) ? ((nRow=pItems[nIndex].nRow) <= nEndRow) : FALSE )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ TypedStrData* pData;
+ ULONG nFormat = GetNumberFormat( nRow );
+
+ ScCellFormat::GetInputString( pCell, nFormat, aString, *pFormatter );
+
+ if ( pDocument->HasStringData( nCol, nRow, nTab ) )
+ pData = new TypedStrData( aString );
+ else
+ {
+ double nValue;
+
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ nValue = ((ScValueCell*)pCell)->GetValue();
+ break;
+
+ case CELLTYPE_FORMULA:
+ nValue = ((ScFormulaCell*)pCell)->GetValue();
+ break;
+
+ default:
+ nValue = 0.0;
+ }
+
+ if (pFormatter)
+ {
+ short nType = pFormatter->GetType(nFormat);
+ if ((nType & NUMBERFORMAT_DATE) && !(nType & NUMBERFORMAT_TIME))
+ {
+ // special case for date values. Disregard the time
+ // element if the number format is of date type.
+ nValue = ::rtl::math::approxFloor(nValue);
+ bHasDates = true;
+ }
+ }
+
+ pData = new TypedStrData( aString, nValue, SC_STRTYPE_VALUE );
+ }
+#if 0 // DR
+ ScPostIt aCellNote( ScPostIt::UNINITIALIZED );
+ // Hide visible notes during Filtering.
+ if(pCell->GetNote(aCellNote) && aCellNote.IsCaptionShown())
+ {
+ ScDetectiveFunc( pDocument, nTab ).HideComment( nCol, nRow );
+ aCellNote.SetShown( false );
+ pCell->SetNote(aCellNote);
+ }
+#endif
+
+ if ( !rStrings.Insert( pData ) )
+ delete pData; // doppelt
+
+ ++nIndex;
+ }
+
+ rHasDates = bHasDates;
+}
+
+//
+// GetDataEntries - Strings aus zusammenhaengendem Bereich um nRow
+//
+
+// DATENT_MAX - max. Anzahl Eintrage in Liste fuer Auto-Eingabe
+// DATENT_SEARCH - max. Anzahl Zellen, die durchsucht werden - neu: nur Strings zaehlen
+#define DATENT_MAX 200
+#define DATENT_SEARCH 2000
+
+
+BOOL ScColumn::GetDataEntries(SCROW nStartRow, TypedScStrCollection& rStrings, BOOL bLimit)
+{
+ BOOL bFound = FALSE;
+ SCSIZE nThisIndex;
+ BOOL bThisUsed = Search( nStartRow, nThisIndex );
+ String aString;
+ USHORT nCells = 0;
+
+ // Die Beschraenkung auf angrenzende Zellen (ohne Luecken) ist nicht mehr gewollt
+ // (Featurekommission zur 5.1), stattdessen abwechselnd nach oben und unten suchen,
+ // damit naheliegende Zellen wenigstens zuerst gefunden werden.
+ //! Abstaende der Zeilennummern vergleichen? (Performance??)
+
+ SCSIZE nUpIndex = nThisIndex; // zeigt hinter die Zelle
+ SCSIZE nDownIndex = nThisIndex; // zeigt auf die Zelle
+ if (bThisUsed)
+ ++nDownIndex; // Startzelle ueberspringen
+
+ while ( nUpIndex || nDownIndex < nCount )
+ {
+ if ( nUpIndex ) // nach oben
+ {
+ ScBaseCell* pCell = pItems[nUpIndex-1].pCell;
+ CellType eType = pCell->GetCellType();
+ if (eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT) // nur Strings interessieren
+ {
+ if (eType == CELLTYPE_STRING)
+ ((ScStringCell*)pCell)->GetString(aString);
+ else
+ ((ScEditCell*)pCell)->GetString(aString);
+
+ TypedStrData* pData = new TypedStrData(aString);
+ if ( !rStrings.Insert( pData ) )
+ delete pData; // doppelt
+ else if ( bLimit && rStrings.GetCount() >= DATENT_MAX )
+ break; // Maximum erreicht
+ bFound = TRUE;
+
+ if ( bLimit )
+ if (++nCells >= DATENT_SEARCH)
+ break; // genug gesucht
+ }
+ --nUpIndex;
+ }
+
+ if ( nDownIndex < nCount ) // nach unten
+ {
+ ScBaseCell* pCell = pItems[nDownIndex].pCell;
+ CellType eType = pCell->GetCellType();
+ if (eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT) // nur Strings interessieren
+ {
+ if (eType == CELLTYPE_STRING)
+ ((ScStringCell*)pCell)->GetString(aString);
+ else
+ ((ScEditCell*)pCell)->GetString(aString);
+
+ TypedStrData* pData = new TypedStrData(aString);
+ if ( !rStrings.Insert( pData ) )
+ delete pData; // doppelt
+ else if ( bLimit && rStrings.GetCount() >= DATENT_MAX )
+ break; // Maximum erreicht
+ bFound = TRUE;
+
+ if ( bLimit )
+ if (++nCells >= DATENT_SEARCH)
+ break; // genug gesucht
+ }
+ ++nDownIndex;
+ }
+ }
+
+ return bFound;
+}
+
+#undef DATENT_MAX
+#undef DATENT_SEARCH
+
+
+void ScColumn::RemoveProtected( SCROW nStartRow, SCROW nEndRow )
+{
+ ScAttrIterator aAttrIter( pAttrArray, nStartRow, nEndRow );
+ SCROW nTop = -1;
+ SCROW nBottom = -1;
+ SCSIZE nIndex;
+ const ScPatternAttr* pPattern = aAttrIter.Next( nTop, nBottom );
+ while (pPattern)
+ {
+ const ScProtectionAttr* pAttr = (const ScProtectionAttr*)&pPattern->GetItem(ATTR_PROTECTION);
+ if ( pAttr->GetHideCell() )
+ DeleteArea( nTop, nBottom, IDF_CONTENTS );
+ else if ( pAttr->GetHideFormula() )
+ {
+ Search( nTop, nIndex );
+ while ( nIndex<nCount && pItems[nIndex].nRow<=nBottom )
+ {
+ if ( pItems[nIndex].pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFormula = (ScFormulaCell*)pItems[nIndex].pCell;
+ if (pFormula->IsValue())
+ {
+ double nVal = pFormula->GetValue();
+ pItems[nIndex].pCell = new ScValueCell( nVal );
+ }
+ else
+ {
+ String aString;
+ pFormula->GetString(aString);
+ pItems[nIndex].pCell = new ScStringCell( aString );
+ }
+ delete pFormula;
+ }
+ ++nIndex;
+ }
+ }
+
+ pPattern = aAttrIter.Next( nTop, nBottom );
+ }
+}
+
+
+void ScColumn::SetError( SCROW nRow, const USHORT nError)
+{
+ if (VALIDROW(nRow))
+ {
+ ScFormulaCell* pCell = new ScFormulaCell
+ ( pDocument, ScAddress( nCol, nRow, nTab ) );
+ pCell->SetErrCode( nError );
+ Insert( nRow, pCell );
+ }
+}
+
+
+void ScColumn::SetValue( SCROW nRow, const double& rVal)
+{
+ if (VALIDROW(nRow))
+ {
+ ScBaseCell* pCell = new ScValueCell(rVal);
+ Insert( nRow, pCell );
+ }
+}
+
+
+void ScColumn::GetString( SCROW nRow, String& rString ) const
+{
+ SCSIZE nIndex;
+ Color* pColor;
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if (pCell->GetCellType() != CELLTYPE_NOTE)
+ {
+ ULONG nFormat = GetNumberFormat( nRow );
+ ScCellFormat::GetString( pCell, nFormat, rString, &pColor, *(pDocument->GetFormatTable()) );
+ }
+ else
+ rString.Erase();
+ }
+ else
+ rString.Erase();
+}
+
+
+void ScColumn::GetInputString( SCROW nRow, String& rString ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if (pCell->GetCellType() != CELLTYPE_NOTE)
+ {
+ ULONG nFormat = GetNumberFormat( nRow );
+ ScCellFormat::GetInputString( pCell, nFormat, rString, *(pDocument->GetFormatTable()) );
+ }
+ else
+ rString.Erase();
+ }
+ else
+ rString.Erase();
+}
+
+
+double ScColumn::GetValue( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ return ((ScValueCell*)pCell)->GetValue();
+// break;
+ case CELLTYPE_FORMULA:
+ {
+ if (((ScFormulaCell*)pCell)->IsValue())
+ return ((ScFormulaCell*)pCell)->GetValue();
+ else
+ return 0.0;
+ }
+// break;
+ default:
+ return 0.0;
+// break;
+ }
+ }
+ return 0.0;
+}
+
+
+void ScColumn::GetFormula( SCROW nRow, String& rFormula, BOOL ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ ((ScFormulaCell*)pCell)->GetFormula( rFormula );
+ else
+ rFormula.Erase();
+ }
+ else
+ rFormula.Erase();
+}
+
+
+CellType ScColumn::GetCellType( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ return pItems[nIndex].pCell->GetCellType();
+ return CELLTYPE_NONE;
+}
+
+
+USHORT ScColumn::GetErrCode( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ return ((ScFormulaCell*)pCell)->GetErrCode();
+ }
+ return 0;
+}
+
+
+BOOL ScColumn::HasStringData( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ return (pItems[nIndex].pCell)->HasStringData();
+ return FALSE;
+}
+
+
+BOOL ScColumn::HasValueData( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (Search(nRow, nIndex))
+ return (pItems[nIndex].pCell)->HasValueData();
+ return FALSE;
+}
+
+BOOL ScColumn::HasStringCells( SCROW nStartRow, SCROW nEndRow ) const
+{
+ // TRUE, wenn String- oder Editzellen im Bereich
+
+ if ( pItems )
+ {
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
+ {
+ CellType eType = pItems[nIndex].pCell->GetCellType();
+ if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
+ return TRUE;
+ ++nIndex;
+ }
+ }
+ return FALSE;
+}
+
+
+ScPostIt* ScColumn::GetNote( SCROW nRow )
+{
+ SCSIZE nIndex;
+ return Search( nRow, nIndex ) ? pItems[ nIndex ].pCell->GetNote() : 0;
+}
+
+
+void ScColumn::TakeNote( SCROW nRow, ScPostIt* pNote )
+{
+ SCSIZE nIndex;
+ if( Search( nRow, nIndex ) )
+ pItems[ nIndex ].pCell->TakeNote( pNote );
+ else
+ Insert( nRow, new ScNoteCell( pNote ) );
+}
+
+
+ScPostIt* ScColumn::ReleaseNote( SCROW nRow )
+{
+ ScPostIt* pNote = 0;
+ SCSIZE nIndex;
+ if( Search( nRow, nIndex ) )
+ {
+ ScBaseCell* pCell = pItems[ nIndex ].pCell;
+ pNote = pCell->ReleaseNote();
+ if( (pCell->GetCellType() == CELLTYPE_NOTE) && !pCell->GetBroadcaster() )
+ DeleteAtIndex( nIndex );
+ }
+ return pNote;
+}
+
+
+void ScColumn::DeleteNote( SCROW nRow )
+{
+ delete ReleaseNote( nRow );
+}
+
+
+sal_Int32 ScColumn::GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, CharSet eCharSet ) const
+{
+ sal_Int32 nStringLen = 0;
+ if ( pItems )
+ {
+ String aString;
+ rtl::OString aOString;
+ bool bIsOctetTextEncoding = rtl_isOctetTextEncoding( eCharSet);
+ SvNumberFormatter* pNumFmt = pDocument->GetFormatTable();
+ SCSIZE nIndex;
+ SCROW nRow;
+ Search( nRowStart, nIndex );
+ while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRowEnd )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ if ( pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ Color* pColor;
+ ULONG nFormat = (ULONG) ((SfxUInt32Item*) GetAttr(
+ nRow, ATTR_VALUE_FORMAT ))->GetValue();
+ ScCellFormat::GetString( pCell, nFormat, aString, &pColor,
+ *pNumFmt );
+ sal_Int32 nLen;
+ if (bIsOctetTextEncoding)
+ {
+ rtl::OUString aOUString( aString);
+ if (!aOUString.convertToString( &aOString, eCharSet,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ {
+ // TODO: anything? this is used by the dBase export filter
+ // that throws an error anyway, but in case of another
+ // context we might want to indicate a conversion error
+ // early.
+ }
+ nLen = aOString.getLength();
+ }
+ else
+ nLen = aString.Len() * sizeof(sal_Unicode);
+ if ( nStringLen < nLen)
+ nStringLen = nLen;
+ }
+ nIndex++;
+ }
+ }
+ return nStringLen;
+}
+
+
+xub_StrLen ScColumn::GetMaxNumberStringLen(
+ sal_uInt16& nPrecision, SCROW nRowStart, SCROW nRowEnd ) const
+{
+ xub_StrLen nStringLen = 0;
+ nPrecision = pDocument->GetDocOptions().GetStdPrecision();
+ if ( nPrecision == SvNumberFormatter::UNLIMITED_PRECISION )
+ // In case of unlimited precision, use 2 instead.
+ nPrecision = 2;
+
+ if ( pItems )
+ {
+ String aString;
+ SvNumberFormatter* pNumFmt = pDocument->GetFormatTable();
+ SCSIZE nIndex;
+ SCROW nRow;
+ Search( nRowStart, nIndex );
+ while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRowEnd )
+ {
+ ScBaseCell* pCell = pItems[nIndex].pCell;
+ CellType eType = pCell->GetCellType();
+ if ( eType == CELLTYPE_VALUE || (eType == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->IsValue()) )
+ {
+ ULONG nFormat = (ULONG) ((SfxUInt32Item*) GetAttr(
+ nRow, ATTR_VALUE_FORMAT ))->GetValue();
+ ScCellFormat::GetInputString( pCell, nFormat, aString, *pNumFmt );
+ xub_StrLen nLen = aString.Len();
+ if ( nLen )
+ {
+ if ( nFormat )
+ { // more decimals than standard?
+ sal_uInt16 nPrec = pNumFmt->GetFormatPrecision( nFormat );
+ if ( nPrec != SvNumberFormatter::UNLIMITED_PRECISION && nPrec > nPrecision )
+ nPrecision = nPrec;
+ }
+ if ( nPrecision )
+ { // less than nPrecision in string => widen it
+ // more => shorten it
+ String aSep = pNumFmt->GetFormatDecimalSep( nFormat );
+ xub_StrLen nTmp = aString.Search( aSep );
+ if ( nTmp == STRING_NOTFOUND )
+ nLen += nPrecision + aSep.Len();
+ else
+ {
+ nTmp = aString.Len() - (nTmp + aSep.Len());
+ if ( nTmp != nPrecision )
+ nLen += nPrecision - nTmp;
+ // nPrecision > nTmp : nLen + Diff
+ // nPrecision < nTmp : nLen - Diff
+ }
+ }
+ if ( nStringLen < nLen )
+ nStringLen = nLen;
+ }
+ }
+ nIndex++;
+ }
+ }
+ return nStringLen;
+}
+
diff --git a/sc/source/core/data/compressedarray.cxx b/sc/source/core/data/compressedarray.cxx
new file mode 100644
index 000000000000..95da04fef0e0
--- /dev/null
+++ b/sc/source/core/data/compressedarray.cxx
@@ -0,0 +1,906 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "compressedarray.hxx"
+#include "address.hxx"
+
+#include <algorithm>
+
+template< typename A, typename D >
+ScCompressedArray<A,D>::ScCompressedArray( A nMaxAccessP, const D& rValue,
+ size_t nDeltaP )
+ : nCount(1)
+ , nLimit(1)
+ , nDelta( nDeltaP > 0 ? nDeltaP : 1)
+ , pData( new DataEntry[1])
+ , nMaxAccess( nMaxAccessP)
+{
+ pData[0].aValue = rValue;
+ pData[0].nEnd = nMaxAccess;
+}
+
+
+template< typename A, typename D >
+ScCompressedArray<A,D>::ScCompressedArray( A nMaxAccessP, const D* pDataArray,
+ size_t nDataCount )
+ : nCount(0)
+ , nLimit( nDataCount)
+ , nDelta( nScCompressedArrayDelta)
+ , pData( new DataEntry[nDataCount])
+ , nMaxAccess( nMaxAccessP)
+{
+ D aValue = pDataArray[0];
+ for (size_t j=0; j<nDataCount; ++j)
+ {
+ if (!(aValue == pDataArray[j]))
+ {
+ pData[nCount].aValue = aValue;
+ pData[nCount].nEnd = j-1;
+ ++nCount;
+ aValue = pDataArray[j];
+ }
+ }
+ pData[nCount].aValue = aValue;
+ pData[nCount].nEnd = nMaxAccess;
+ ++nCount;
+ Resize( nCount);
+}
+
+
+template< typename A, typename D >
+ScCompressedArray<A,D>::~ScCompressedArray()
+{
+ delete[] pData;
+}
+
+
+template< typename A, typename D >
+void ScCompressedArray<A,D>::Resize( size_t nNewLimit)
+{
+ if ((nCount <= nNewLimit && nNewLimit < nLimit) || nLimit < nNewLimit)
+ {
+ nLimit = nNewLimit;
+ DataEntry* pNewData = new DataEntry[nLimit];
+ memcpy( pNewData, pData, nCount*sizeof(DataEntry));
+ delete[] pData;
+ pData = pNewData;
+ }
+}
+
+
+template< typename A, typename D >
+size_t ScCompressedArray<A,D>::Search( A nAccess ) const
+{
+ if (nAccess == 0)
+ return 0;
+
+ long nLo = 0;
+ long nHi = static_cast<long>(nCount) - 1;
+ long nStart = 0;
+ long nEnd = 0;
+ long i = 0;
+ bool bFound = (nCount == 1);
+ while (!bFound && nLo <= nHi)
+ {
+ i = (nLo + nHi) / 2;
+ if (i > 0)
+ nStart = (long) pData[i - 1].nEnd;
+ else
+ nStart = -1;
+ nEnd = (long) pData[i].nEnd;
+ if (nEnd < (long) nAccess)
+ nLo = ++i;
+ else
+ if (nStart >= (long) nAccess)
+ nHi = --i;
+ else
+ bFound = true;
+ }
+ return (bFound ? static_cast<size_t>(i) : (nAccess < 0 ? 0 : nCount-1));
+}
+
+
+template< typename A, typename D >
+void ScCompressedArray<A,D>::SetValue( A nStart, A nEnd, const D& rValue )
+{
+ if (0 <= nStart && nStart <= nMaxAccess && 0 <= nEnd && nEnd <= nMaxAccess
+ && nStart <= nEnd)
+ {
+ if ((nStart == 0) && (nEnd == nMaxAccess))
+ Reset( rValue);
+ else
+ {
+ // Create a temporary copy in case we got a reference passed that
+ // points to a part of the array to be reallocated.
+ D aNewVal( rValue);
+ size_t nNeeded = nCount + 2;
+ if (nLimit < nNeeded)
+ {
+ nLimit += nDelta;
+ if (nLimit < nNeeded)
+ nLimit = nNeeded;
+ DataEntry* pNewData = new DataEntry[nLimit];
+ memcpy( pNewData, pData, nCount*sizeof(DataEntry));
+ delete[] pData;
+ pData = pNewData;
+ }
+
+ size_t ni; // number of leading entries
+ size_t nInsert; // insert position (nMaxAccess+1 := no insert)
+ bool bCombined = false;
+ bool bSplit = false;
+ if (nStart > 0)
+ {
+ // skip leading
+ ni = Search( nStart);
+
+ nInsert = nMaxAccess+1;
+ if (!(pData[ni].aValue == aNewVal))
+ {
+ if (ni == 0 || (pData[ni-1].nEnd < nStart - 1))
+ { // may be a split or a simple insert or just a shrink,
+ // row adjustment is done further down
+ if (pData[ni].nEnd > nEnd)
+ bSplit = true;
+ ni++;
+ nInsert = ni;
+ }
+ else if (ni > 0 && pData[ni-1].nEnd == nStart - 1)
+ nInsert = ni;
+ }
+ if (ni > 0 && pData[ni-1].aValue == aNewVal)
+ { // combine
+ pData[ni-1].nEnd = nEnd;
+ nInsert = nMaxAccess+1;
+ bCombined = true;
+ }
+ }
+ else
+ {
+ nInsert = 0;
+ ni = 0;
+ }
+
+ size_t nj = ni; // stop position of range to replace
+ while (nj < nCount && pData[nj].nEnd <= nEnd)
+ nj++;
+ if (!bSplit)
+ {
+ if (nj < nCount && pData[nj].aValue == aNewVal)
+ { // combine
+ if (ni > 0)
+ {
+ if (pData[ni-1].aValue == aNewVal)
+ { // adjacent entries
+ pData[ni-1].nEnd = pData[nj].nEnd;
+ nj++;
+ }
+ else if (ni == nInsert)
+ pData[ni-1].nEnd = nStart - 1; // shrink
+ }
+ nInsert = nMaxAccess+1;
+ bCombined = true;
+ }
+ else if (ni > 0 && ni == nInsert)
+ pData[ni-1].nEnd = nStart - 1; // shrink
+ }
+ if (ni < nj)
+ { // remove middle entries
+ if (!bCombined)
+ { // replace one entry
+ pData[ni].nEnd = nEnd;
+ pData[ni].aValue = aNewVal;
+ ni++;
+ nInsert = nMaxAccess+1;
+ }
+ if (ni < nj)
+ { // remove entries
+ memmove( pData + ni, pData + nj,
+ (nCount - nj) * sizeof(DataEntry));
+ nCount -= nj - ni;
+ }
+ }
+
+ if (nInsert < static_cast<size_t>(nMaxAccess+1))
+ { // insert or append new entry
+ if (nInsert <= nCount)
+ {
+ if (!bSplit)
+ memmove( pData + nInsert + 1, pData + nInsert,
+ (nCount - nInsert) * sizeof(DataEntry));
+ else
+ {
+ memmove( pData + nInsert + 2, pData + nInsert,
+ (nCount - nInsert) * sizeof(DataEntry));
+ pData[nInsert+1] = pData[nInsert-1];
+ nCount++;
+ }
+ }
+ if (nInsert)
+ pData[nInsert-1].nEnd = nStart - 1;
+ pData[nInsert].nEnd = nEnd;
+ pData[nInsert].aValue = aNewVal;
+ nCount++;
+ }
+ }
+ }
+}
+
+
+template< typename A, typename D >
+void ScCompressedArray<A,D>::CopyFrom( const ScCompressedArray<A,D>& rArray, A nStart,
+ A nEnd, long nSourceDy )
+{
+ size_t nIndex;
+ A nRegionEnd;
+ for (A j=nStart; j<=nEnd; ++j)
+ {
+ const D& rValue = (j==nStart ?
+ rArray.GetValue( j+nSourceDy, nIndex, nRegionEnd) :
+ rArray.GetNextValue( nIndex, nRegionEnd));
+ nRegionEnd -= nSourceDy;
+ if (nRegionEnd > nEnd)
+ nRegionEnd = nEnd;
+ SetValue( j, nRegionEnd, rValue);
+ j = nRegionEnd;
+ }
+}
+
+
+template< typename A, typename D >
+const D& ScCompressedArray<A,D>::Insert( A nStart, size_t nAccessCount )
+{
+ size_t nIndex = Search( nStart);
+ // No real insertion is needed, simply extend the one entry and adapt all
+ // following. In case nStart points to the start row of an entry, extend
+ // the previous entry (inserting before nStart).
+ if (nIndex > 0 && pData[nIndex-1].nEnd+1 == nStart)
+ --nIndex;
+ const D& rValue = pData[nIndex].aValue; // the value "copied"
+ do
+ {
+ pData[nIndex].nEnd += nAccessCount;
+ if (pData[nIndex].nEnd >= nMaxAccess)
+ {
+ pData[nIndex].nEnd = nMaxAccess;
+ nCount = nIndex + 1; // discard trailing entries
+ }
+ } while (++nIndex < nCount);
+ return rValue;
+}
+
+
+template< typename A, typename D >
+void ScCompressedArray<A,D>::Remove( A nStart, size_t nAccessCount )
+{
+ A nEnd = nStart + nAccessCount - 1;
+ size_t nIndex = Search( nStart);
+ // equalize/combine/remove all entries in between
+ if (nEnd > pData[nIndex].nEnd)
+ SetValue( nStart, nEnd, pData[nIndex].aValue);
+ // remove an exactly matching entry by shifting up all following by one
+ if ((nStart == 0 || (nIndex > 0 && nStart == pData[nIndex-1].nEnd+1)) &&
+ pData[nIndex].nEnd == nEnd && nIndex < nCount-1)
+ {
+ // In case removing an entry results in two adjacent entries with
+ // identical data, combine them into one. This is also necessary to
+ // make the algorithm used in SetValue() work correctly, it relies on
+ // the fact that consecutive values actually differ.
+ size_t nRemove;
+ if (nIndex > 0 && pData[nIndex-1].aValue == pData[nIndex+1].aValue)
+ {
+ nRemove = 2;
+ --nIndex;
+ }
+ else
+ nRemove = 1;
+ memmove( pData + nIndex, pData + nIndex + nRemove, (nCount - (nIndex +
+ nRemove)) * sizeof(DataEntry));
+ nCount -= nRemove;
+ }
+ // adjust end rows, nIndex still being valid
+ do
+ {
+ pData[nIndex].nEnd -= nAccessCount;
+ } while (++nIndex < nCount);
+ pData[nCount-1].nEnd = nMaxAccess;
+}
+
+
+template< typename A, typename D >
+A ScCompressedArray<A,D>::GetLastUnequalAccess( A nStart, const D& rCompare )
+{
+ A nEnd = ::std::numeric_limits<A>::max();
+ size_t nIndex = nCount-1;
+ while (1)
+ {
+ if (pData[nIndex].aValue != rCompare)
+ {
+ nEnd = pData[nIndex].nEnd;
+ break; // while
+ }
+ else
+ {
+ if (nIndex > 0)
+ {
+ --nIndex;
+ if (pData[nIndex].nEnd < nStart)
+ break; // while
+ }
+ else
+ break; // while
+ }
+ }
+ return nEnd;
+}
+
+
+// === ScSummableCompressedArray =============================================
+
+template< typename A, typename D >
+unsigned long ScSummableCompressedArray<A,D>::SumValues( A nStart, A nEnd ) const
+{
+ size_t nIndex = Search( nStart);
+ unsigned long nSum = SumValuesContinuation( nStart, nEnd, nIndex);
+ if (nEnd > this->nMaxAccess)
+ nSum += this->pData[this->nCount-1].aValue * (nEnd - this->nMaxAccess);
+ return nSum;
+}
+
+
+template< typename A, typename D >
+unsigned long ScSummableCompressedArray<A,D>::SumValuesContinuation(
+ A nStart, A nEnd, size_t& nIndex ) const
+{
+ unsigned long nSum = 0;
+ A nS = nStart;
+ while (nIndex < this->nCount && nS <= nEnd)
+ {
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ // FIXME: test for overflow in a single region?
+ unsigned long nNew = (unsigned long) this->pData[nIndex].aValue * (nE - nS + 1);
+ nSum += nNew;
+ if (nSum < nNew)
+ return ::std::numeric_limits<unsigned long>::max();
+ nS = nE + 1;
+ if (nS <= nEnd)
+ ++nIndex;
+ }
+ return nSum;
+}
+
+
+template< typename A, typename D >
+unsigned long ScSummableCompressedArray<A,D>::SumScaledValuesContinuation(
+ A nStart, A nEnd, size_t& nIndex, double fScale ) const
+{
+ unsigned long nSum = 0;
+ A nS = nStart;
+ while (nIndex < this->nCount && nS <= nEnd)
+ {
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ unsigned long nScaledVal = (unsigned long) (this->pData[nIndex].aValue * fScale);
+ // FIXME: test for overflow in a single region?
+ unsigned long nNew = nScaledVal * (nE - nS + 1);
+ nSum += nNew;
+ if (nSum < nNew)
+ return ::std::numeric_limits<unsigned long>::max();
+ nS = nE + 1;
+ if (nS <= nEnd)
+ ++nIndex;
+ }
+ return nSum;
+}
+
+
+// === ScBitMaskCompressedArray ==============================================
+
+template< typename A, typename D >
+void ScBitMaskCompressedArray<A,D>::AndValue( A nStart, A nEnd,
+ const D& rValueToAnd )
+{
+ if (nStart > nEnd)
+ return;
+
+ size_t nIndex = Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex].aValue & rValueToAnd) != this->pData[nIndex].aValue)
+ {
+ A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ SetValue( nS, nE, this->pData[nIndex].aValue & rValueToAnd);
+ if (nE >= nEnd)
+ break; // while
+ nIndex = Search( nE + 1);
+ }
+ else if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ else
+ ++nIndex;
+ } while (nIndex < this->nCount);
+}
+
+
+template< typename A, typename D >
+void ScBitMaskCompressedArray<A,D>::OrValue( A nStart, A nEnd,
+ const D& rValueToOr )
+{
+ if (nStart > nEnd)
+ return;
+
+ size_t nIndex = Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex].aValue | rValueToOr) != this->pData[nIndex].aValue)
+ {
+ A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ SetValue( nS, nE, this->pData[nIndex].aValue | rValueToOr);
+ if (nE >= nEnd)
+ break; // while
+ nIndex = Search( nE + 1);
+ }
+ else if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ else
+ ++nIndex;
+ } while (nIndex < this->nCount);
+}
+
+
+template< typename A, typename D >
+void ScBitMaskCompressedArray<A,D>::CopyFromAnded(
+ const ScBitMaskCompressedArray<A,D>& rArray, A nStart, A nEnd,
+ const D& rValueToAnd, long nSourceDy )
+{
+ size_t nIndex;
+ A nRegionEnd;
+ for (A j=nStart; j<=nEnd; ++j)
+ {
+ const D& rValue = (j==nStart ?
+ rArray.GetValue( j+nSourceDy, nIndex, nRegionEnd) :
+ rArray.GetNextValue( nIndex, nRegionEnd));
+ nRegionEnd -= nSourceDy;
+ if (nRegionEnd > nEnd)
+ nRegionEnd = nEnd;
+ SetValue( j, nRegionEnd, rValue & rValueToAnd);
+ j = nRegionEnd;
+ }
+}
+
+
+template< typename A, typename D >
+void ScBitMaskCompressedArray<A,D>::CopyFromOred(
+ const ScBitMaskCompressedArray<A,D>& rArray, A nStart, A nEnd,
+ const D& rValueToOr, long nSourceDy )
+{
+ size_t nIndex;
+ A nRegionEnd;
+ for (A j=nStart; j<=nEnd; ++j)
+ {
+ const D& rValue = (j==nStart ?
+ rArray.GetValue( j+nSourceDy, nIndex, nRegionEnd) :
+ rArray.GetNextValue( nIndex, nRegionEnd));
+ nRegionEnd -= nSourceDy;
+ if (nRegionEnd > nEnd)
+ nRegionEnd = nEnd;
+ SetValue( j, nRegionEnd, rValue | rValueToOr);
+ j = nRegionEnd;
+ }
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::GetBitStateStart( A nEnd,
+ const D& rBitMask, const D& rMaskedCompare ) const
+{
+ A nStart = ::std::numeric_limits<A>::max();
+ size_t nIndex = Search( nEnd);
+ while ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
+ {
+ if (nIndex > 0)
+ {
+ --nIndex;
+ nStart = this->pData[nIndex].nEnd + 1;
+ }
+ else
+ {
+ nStart = 0;
+ break; // while
+ }
+ }
+ return nStart;
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::GetBitStateEnd( A nStart,
+ const D& rBitMask, const D& rMaskedCompare ) const
+{
+ A nEnd = ::std::numeric_limits<A>::max();
+ size_t nIndex = Search( nStart);
+ while (nIndex < this->nCount && (this->pData[nIndex].aValue & rBitMask) ==
+ rMaskedCompare)
+ {
+ nEnd = this->pData[nIndex].nEnd;
+ ++nIndex;
+ }
+ return nEnd;
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::GetFirstForCondition( A nStart, A nEnd,
+ const D& rBitMask, const D& rMaskedCompare ) const
+{
+ size_t nIndex = Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
+ {
+ A nFound = nIndex > 0 ? this->pData[nIndex-1].nEnd + 1 : 0;
+ return ::std::max( nFound, nStart);
+ }
+ if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ ++nIndex;
+ } while (nIndex < this->nCount);
+ return ::std::numeric_limits<A>::max();
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::GetLastForCondition( A nStart, A nEnd,
+ const D& rBitMask, const D& rMaskedCompare ) const
+{
+ size_t nIndex = Search( nEnd);
+ while (1)
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
+ return ::std::min( this->pData[nIndex].nEnd, nEnd);
+
+ if (nIndex > 0)
+ {
+ --nIndex;
+ if (this->pData[nIndex].nEnd < nStart)
+ break; // while
+ }
+ else
+ break; // while
+ }
+ return ::std::numeric_limits<A>::max();
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::CountForCondition( A nStart, A nEnd,
+ const D& rBitMask, const D& rMaskedCompare ) const
+{
+ A nRet = 0;
+ size_t nIndex = Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
+ {
+ A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ nRet += nE - nS + 1;
+ }
+ if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ ++nIndex;
+ } while (nIndex < this->nCount);
+ return nRet;
+}
+
+
+template< typename A, typename D >
+size_t ScBitMaskCompressedArray<A,D>::FillArrayForCondition( A nStart, A nEnd,
+ const D& rBitMask, const D& rMaskedCompare,
+ A * pArray, size_t nArraySize ) const
+{
+ size_t nUsed = 0;
+ size_t nIndex = Search( nStart);
+ while (nIndex < this->nCount && nUsed < nArraySize)
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
+ {
+ A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ while (nS <= nE && nUsed < nArraySize)
+ pArray[nUsed++] = nS++;
+ }
+ if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ ++nIndex;
+ }
+ return nUsed;
+}
+
+
+template< typename A, typename D >
+bool ScBitMaskCompressedArray<A,D>::HasCondition( A nStart, A nEnd,
+ const D& rBitMask, const D& rMaskedCompare ) const
+{
+ size_t nIndex = Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) == rMaskedCompare)
+ return true;
+ if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ ++nIndex;
+ } while (nIndex < this->nCount);
+ return false;
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::CountForAnyBitCondition( A nStart, A nEnd,
+ const D& rBitMask ) const
+{
+ A nRet = 0;
+ size_t nIndex = Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) != 0)
+ {
+ A nS = ::std::max( (nIndex>0 ? this->pData[nIndex-1].nEnd+1 : 0), nStart);
+ A nE = ::std::min( this->pData[nIndex].nEnd, nEnd);
+ nRet += nE - nS + 1;
+ }
+ if (this->pData[nIndex].nEnd >= nEnd)
+ break; // while
+ ++nIndex;
+ } while (nIndex < this->nCount);
+ return nRet;
+}
+
+
+template< typename A, typename D >
+A ScBitMaskCompressedArray<A,D>::GetLastAnyBitAccess( A nStart,
+ const D& rBitMask ) const
+{
+ A nEnd = ::std::numeric_limits<A>::max();
+ size_t nIndex = this->nCount-1;
+ while (1)
+ {
+ if ((this->pData[nIndex].aValue & rBitMask) != 0)
+ {
+ nEnd = this->pData[nIndex].nEnd;
+ break; // while
+ }
+ else
+ {
+ if (nIndex > 0)
+ {
+ --nIndex;
+ if (this->pData[nIndex].nEnd < nStart)
+ break; // while
+ }
+ else
+ break; // while
+ }
+ }
+ return nEnd;
+}
+
+
+template< typename A, typename D >
+template< typename S >
+unsigned long ScBitMaskCompressedArray<A,D>::SumCoupledArrayForCondition(
+ A nStart, A nEnd, const D& rBitMask, const D& rMaskedCompare,
+ const ScSummableCompressedArray<A,S>& rArray ) const
+{
+ unsigned long nSum = 0;
+ A nS = nStart;
+ size_t nIndex1 = Search( nStart);
+ size_t nIndex2 = rArray.Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex1].aValue & rBitMask) == rMaskedCompare)
+ {
+ while (nIndex2 < rArray.GetEntryCount() &&
+ rArray.GetDataEntry(nIndex2).nEnd < nS)
+ ++nIndex2;
+ unsigned long nNew = rArray.SumValuesContinuation( nS,
+ ::std::min( this->pData[nIndex1].nEnd, nEnd), nIndex2);
+ nSum += nNew;
+ if (nSum < nNew)
+ return ::std::numeric_limits<unsigned long>::max();
+ }
+ nS = this->pData[nIndex1].nEnd + 1;
+ ++nIndex1;
+ } while (nIndex1 < this->nCount && nS <= nEnd);
+ if (nEnd > this->nMaxAccess &&
+ (this->pData[this->GetEntryCount()-1].aValue & rBitMask) == rMaskedCompare)
+ nSum += rArray.GetDataEntry(rArray.GetEntryCount()-1).aValue * (nEnd -
+ this->nMaxAccess);
+ return nSum;
+}
+
+
+template< typename A, typename D >
+template< typename S >
+unsigned long ScBitMaskCompressedArray<A,D>::SumScaledCoupledArrayForCondition(
+ A nStart, A nEnd, const D& rBitMask, const D& rMaskedCompare,
+ const ScSummableCompressedArray<A,S>& rArray, double fScale ) const
+{
+ unsigned long nSum = 0;
+ A nS = nStart;
+ size_t nIndex1 = Search( nStart);
+ size_t nIndex2 = rArray.Search( nStart);
+ do
+ {
+ if ((this->pData[nIndex1].aValue & rBitMask) == rMaskedCompare)
+ {
+ while (nIndex2 < rArray.GetEntryCount() &&
+ rArray.GetDataEntry(nIndex2).nEnd < nS)
+ ++nIndex2;
+ unsigned long nNew = rArray.SumScaledValuesContinuation( nS,
+ ::std::min( this->pData[nIndex1].nEnd, nEnd), nIndex2, fScale);
+ nSum += nNew;
+ if (nSum < nNew)
+ return ::std::numeric_limits<unsigned long>::max();
+ }
+ nS = this->pData[nIndex1].nEnd + 1;
+ ++nIndex1;
+ } while (nIndex1 < this->nCount && nS <= nEnd);
+ if (nEnd > this->nMaxAccess &&
+ (this->pData[this->GetEntryCount()-1].aValue & rBitMask) == rMaskedCompare)
+ nSum += (unsigned long)
+ (rArray.GetDataEntry(rArray.GetEntryCount()-1).aValue * fScale) *
+ (nEnd - this->nMaxAccess);
+ return nSum;
+}
+
+
+// === ScCompressedArrayIterator =============================================
+
+template< typename A, typename D >
+template< typename X >
+void ScCompressedArrayIterator<A,D>::Follow(
+ const ScCompressedArrayIterator<A,X>& rIter )
+{
+ nCurrent = rIter.GetPos();
+ if (GetRangeStart() <= nCurrent && nCurrent <= GetRangeEnd())
+ ; // nothing
+ else if (nCurrent > GetRangeEnd())
+ {
+ A nPos = nCurrent; // nCurrent gets changed in NextRange()
+ bool bAdv;
+ do
+ {
+ bAdv = NextRange();
+ } while (bAdv && GetRangeEnd() < nPos);
+ nCurrent = nPos;
+ }
+ else
+ nIndex = rArray.Search( nCurrent);
+}
+
+
+// === ScCoupledCompressedArrayIterator ======================================
+
+template< typename A, typename D, typename S >
+ScCoupledCompressedArrayIterator<A,D,S>::ScCoupledCompressedArrayIterator(
+ const ScBitMaskCompressedArray<A,D> & rArray1, A nStart, A nEnd,
+ const D& rBitMaskP, const D& rMaskedCompareP,
+ const ScCompressedArray<A,S> & rArray2 )
+ : aIter1( rArray1, nStart, nEnd )
+ , aIter2( rArray2, nStart, nEnd )
+ , rBitMask( rBitMaskP )
+ , rMaskedCompare( rMaskedCompareP )
+{
+ InitLimits();
+}
+
+
+template< typename A, typename D, typename S >
+void ScCoupledCompressedArrayIterator<A,D,S>::InitLimits()
+{
+ bool bFound = true;
+ bool bMoved = false;
+ while (bFound && ((*aIter1 & rBitMask) != rMaskedCompare))
+ {
+ bFound = aIter1.NextRange();
+ bMoved = true;
+ }
+ if (bMoved && bFound)
+ aIter2.Follow( aIter1);
+}
+
+
+template< typename A, typename D, typename S >
+void ScCoupledCompressedArrayIterator<A,D,S>::NewLimits( A nStart, A nEnd )
+{
+ aIter1.NewLimits( nStart, nEnd);
+ aIter2.NewLimits( nStart, nEnd);
+ InitLimits();
+}
+
+
+template< typename A, typename D, typename S >
+bool ScCoupledCompressedArrayIterator<A,D,S>::NextRange()
+{
+ bool bAdv;
+ if (aIter1.GetRangeEnd() <= aIter2.GetRangeEnd())
+ {
+ // Advance bit mask array until condition is met, coupled array
+ // follows.
+ do
+ {
+ bAdv = aIter1.NextRange();
+ } while (bAdv && ((*aIter1 & rBitMask) != rMaskedCompare));
+ if (bAdv)
+ aIter2.Follow( aIter1);
+ }
+ else
+ {
+ // Make coupled array catch up with bit mask array.
+ do
+ {
+ bAdv = aIter2.NextRange();
+ } while (bAdv && aIter2.GetRangeEnd() < aIter1.GetRangeStart());
+ if (bAdv)
+ aIter1.Follow( aIter2); // synchronize aIter1.nCurrent
+ }
+ return operator bool();
+}
+
+
+template< typename A, typename D, typename S >
+void ScCoupledCompressedArrayIterator<A,D,S>::Resync( A nPos )
+{
+ aIter1.Resync( nPos);
+ aIter2.Resync( nPos);
+ InitLimits();
+}
+
+
+// === Force instantiation of specializations ================================
+
+template class ScCompressedArray< SCROW, USHORT>; // heights, base class
+template class ScSummableCompressedArray< SCROW, USHORT>; // heights
+template class ScCompressedArray< SCROW, BYTE>; // flags, base class
+template class ScBitMaskCompressedArray< SCROW, BYTE>; // flags
+template unsigned long ScBitMaskCompressedArray< SCROW,
+ BYTE>::SumCoupledArrayForCondition( SCROW, SCROW, const BYTE&, const BYTE&,
+ const ScSummableCompressedArray< SCROW, USHORT>&) const;
+template unsigned long ScBitMaskCompressedArray< SCROW,
+ BYTE>::SumScaledCoupledArrayForCondition( SCROW, SCROW, const BYTE&,
+ const BYTE&, const ScSummableCompressedArray< SCROW, USHORT>&,
+ double) const;
+template void ScCompressedArrayIterator< SCROW, USHORT>::Follow(
+ const ScCompressedArrayIterator< SCROW, BYTE>&);
+template class ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT>;
+
+// === EOF ===================================================================
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
new file mode 100644
index 000000000000..b08838198477
--- /dev/null
+++ b/sc/source/core/data/conditio.cxx
@@ -0,0 +1,1603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/objsh.hxx>
+#include <svl/itemset.hxx>
+#include <svl/zforlist.hxx>
+#include <rtl/math.hxx>
+#include <unotools/collatorwrapper.hxx>
+
+#include "conditio.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "hints.hxx"
+#include "compiler.hxx"
+#include "rechead.hxx"
+#include "rangelst.hxx"
+#include "stlpool.hxx"
+#include "rangenam.hxx"
+
+using namespace formula;
+//------------------------------------------------------------------------
+
+SV_IMPL_OP_PTRARR_SORT( ScConditionalFormats_Impl, ScConditionalFormatPtr );
+
+//------------------------------------------------------------------------
+
+BOOL lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, USHORT nRecursion = 0 )
+{
+ if (pFormula)
+ {
+ pFormula->Reset();
+ FormulaToken* t;
+ for( t = pFormula->Next(); t; t = pFormula->Next() )
+ {
+ switch( t->GetType() )
+ {
+ case svDoubleRef:
+ {
+ ScSingleRefData& rRef2 = static_cast<ScToken*>(t)->GetDoubleRef().Ref2;
+ if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() )
+ return TRUE;
+ }
+ // fall through
+
+ case svSingleRef:
+ {
+ ScSingleRefData& rRef1 = static_cast<ScToken*>(t)->GetSingleRef();
+ if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() )
+ return TRUE;
+ }
+ break;
+
+ case svIndex:
+ {
+ if( t->GetOpCode() == ocName ) // DB areas always absolute
+ if( ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( t->GetIndex() ) )
+ if( (nRecursion < 42) && lcl_HasRelRef( pDoc, pRangeData->GetCode(), nRecursion + 1 ) )
+ return TRUE;
+ }
+ break;
+
+ // #i34474# function result dependent on cell position
+ case svByte:
+ {
+ switch( t->GetOpCode() )
+ {
+ case ocRow: // ROW() returns own row index
+ case ocColumn: // COLUMN() returns own column index
+ case ocTable: // SHEET() returns own sheet index
+ case ocCell: // CELL() may return own cell address
+ return TRUE;
+// break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
+ eOp(r.eOp),
+ nOptions(r.nOptions),
+ nVal1(r.nVal1),
+ nVal2(r.nVal2),
+ aStrVal1(r.aStrVal1),
+ aStrVal2(r.aStrVal2),
+ aStrNmsp1(r.aStrNmsp1),
+ aStrNmsp2(r.aStrNmsp2),
+ eTempGrammar1(r.eTempGrammar1),
+ eTempGrammar2(r.eTempGrammar2),
+ bIsStr1(r.bIsStr1),
+ bIsStr2(r.bIsStr2),
+ pFormula1(NULL),
+ pFormula2(NULL),
+ aSrcPos(r.aSrcPos),
+ aSrcString(r.aSrcString),
+ pFCell1(NULL),
+ pFCell2(NULL),
+ pDoc(r.pDoc),
+ bRelRef1(r.bRelRef1),
+ bRelRef2(r.bRelRef2),
+ bFirstRun(TRUE)
+{
+ // ScTokenArray copy ctor erzeugt flache Kopie
+
+ if (r.pFormula1)
+ pFormula1 = new ScTokenArray( *r.pFormula1 );
+ if (r.pFormula2)
+ pFormula2 = new ScTokenArray( *r.pFormula2 );
+
+ // Formelzellen werden erst bei IsValid angelegt
+}
+
+ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntry& r ) :
+ eOp(r.eOp),
+ nOptions(r.nOptions),
+ nVal1(r.nVal1),
+ nVal2(r.nVal2),
+ aStrVal1(r.aStrVal1),
+ aStrVal2(r.aStrVal2),
+ aStrNmsp1(r.aStrNmsp1),
+ aStrNmsp2(r.aStrNmsp2),
+ eTempGrammar1(r.eTempGrammar1),
+ eTempGrammar2(r.eTempGrammar2),
+ bIsStr1(r.bIsStr1),
+ bIsStr2(r.bIsStr2),
+ pFormula1(NULL),
+ pFormula2(NULL),
+ aSrcPos(r.aSrcPos),
+ aSrcString(r.aSrcString),
+ pFCell1(NULL),
+ pFCell2(NULL),
+ pDoc(pDocument),
+ bRelRef1(r.bRelRef1),
+ bRelRef2(r.bRelRef2),
+ bFirstRun(TRUE)
+{
+ // echte Kopie der Formeln (fuer Ref-Undo)
+
+ if (r.pFormula1)
+ pFormula1 = r.pFormula1->Clone();
+ if (r.pFormula2)
+ pFormula2 = r.pFormula2->Clone();
+
+ // Formelzellen werden erst bei IsValid angelegt
+ //! im Clipboard nicht - dann vorher interpretieren !!!
+}
+
+ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
+ 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),
+ aStrNmsp1(rExprNmsp1),
+ aStrNmsp2(rExprNmsp2),
+ eTempGrammar1(eGrammar1),
+ eTempGrammar2(eGrammar2),
+ bIsStr1(FALSE),
+ bIsStr2(FALSE),
+ pFormula1(NULL),
+ pFormula2(NULL),
+ aSrcPos(rPos),
+ pFCell1(NULL),
+ pFCell2(NULL),
+ pDoc(pDocument),
+ bRelRef1(FALSE),
+ bRelRef2(FALSE),
+ bFirstRun(TRUE)
+{
+ Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, FALSE );
+
+ // Formelzellen werden erst bei IsValid angelegt
+}
+
+ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
+ const ScTokenArray* pArr1, const ScTokenArray* pArr2,
+ ScDocument* pDocument, const ScAddress& rPos ) :
+ eOp(eOper),
+ nOptions(0), // spaeter...
+ nVal1(0.0),
+ nVal2(0.0),
+ eTempGrammar1(FormulaGrammar::GRAM_DEFAULT),
+ eTempGrammar2(FormulaGrammar::GRAM_DEFAULT),
+ bIsStr1(FALSE),
+ bIsStr2(FALSE),
+ pFormula1(NULL),
+ pFormula2(NULL),
+ aSrcPos(rPos),
+ pFCell1(NULL),
+ pFCell2(NULL),
+ pDoc(pDocument),
+ bRelRef1(FALSE),
+ bRelRef2(FALSE),
+ bFirstRun(TRUE)
+{
+ if ( pArr1 )
+ {
+ pFormula1 = new ScTokenArray( *pArr1 );
+ if ( pFormula1->GetLen() == 1 )
+ {
+ // einzelne (konstante Zahl) ?
+ FormulaToken* pToken = pFormula1->First();
+ if ( pToken->GetOpCode() == ocPush )
+ {
+ if ( pToken->GetType() == svDouble )
+ {
+ nVal1 = pToken->GetDouble();
+ DELETEZ(pFormula1); // nicht als Formel merken
+ }
+ else if ( pToken->GetType() == svString )
+ {
+ bIsStr1 = TRUE;
+ aStrVal1 = pToken->GetString();
+ DELETEZ(pFormula1); // nicht als Formel merken
+ }
+ }
+ }
+ bRelRef1 = lcl_HasRelRef( pDoc, pFormula1 );
+ }
+ if ( pArr2 )
+ {
+ pFormula2 = new ScTokenArray( *pArr2 );
+ if ( pFormula2->GetLen() == 1 )
+ {
+ // einzelne (konstante Zahl) ?
+ FormulaToken* pToken = pFormula2->First();
+ if ( pToken->GetOpCode() == ocPush )
+ {
+ if ( pToken->GetType() == svDouble )
+ {
+ nVal2 = pToken->GetDouble();
+ DELETEZ(pFormula2); // nicht als Formel merken
+ }
+ else if ( pToken->GetType() == svString )
+ {
+ bIsStr2 = TRUE;
+ aStrVal2 = pToken->GetString();
+ DELETEZ(pFormula2); // nicht als Formel merken
+ }
+ }
+ }
+ bRelRef2 = lcl_HasRelRef( pDoc, pFormula2 );
+ }
+
+ // formula cells are created at IsValid
+}
+
+ScConditionEntry::~ScConditionEntry()
+{
+ delete pFCell1;
+ delete pFCell2;
+
+ delete pFormula1;
+ delete pFormula2;
+}
+
+void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2, BOOL bTextToReal )
+{
+ if ( rExpr1.Len() || rExpr2.Len() )
+ {
+ ScCompiler aComp( pDoc, aSrcPos );
+
+ if ( rExpr1.Len() )
+ {
+ aComp.SetGrammar( eGrammar1 );
+ if ( pDoc->IsImportingXML() && !bTextToReal )
+ {
+ // temporary formula string as string tokens
+ //! merge with lcl_ScDocFunc_CreateTokenArrayXML
+ pFormula1 = new ScTokenArray;
+ pFormula1->AddString( rExpr1 );
+ // bRelRef1 is set when the formula is compiled again (CompileXML)
+ }
+ else
+ {
+ pFormula1 = aComp.CompileString( rExpr1, rExprNmsp1 );
+ if ( pFormula1->GetLen() == 1 )
+ {
+ // einzelne (konstante Zahl) ?
+ FormulaToken* pToken = pFormula1->First();
+ if ( pToken->GetOpCode() == ocPush )
+ {
+ if ( pToken->GetType() == svDouble )
+ {
+ nVal1 = pToken->GetDouble();
+ DELETEZ(pFormula1); // nicht als Formel merken
+ }
+ else if ( pToken->GetType() == svString )
+ {
+ bIsStr1 = TRUE;
+ aStrVal1 = pToken->GetString();
+ DELETEZ(pFormula1); // nicht als Formel merken
+ }
+ }
+ }
+ bRelRef1 = lcl_HasRelRef( pDoc, pFormula1 );
+ }
+ }
+
+ if ( rExpr2.Len() )
+ {
+ aComp.SetGrammar( eGrammar2 );
+ if ( pDoc->IsImportingXML() && !bTextToReal )
+ {
+ // temporary formula string as string tokens
+ //! merge with lcl_ScDocFunc_CreateTokenArrayXML
+ pFormula2 = new ScTokenArray;
+ pFormula2->AddString( rExpr2 );
+ // bRelRef2 is set when the formula is compiled again (CompileXML)
+ }
+ else
+ {
+ pFormula2 = aComp.CompileString( rExpr2, rExprNmsp2 );
+ if ( pFormula2->GetLen() == 1 )
+ {
+ // einzelne (konstante Zahl) ?
+ FormulaToken* pToken = pFormula2->First();
+ if ( pToken->GetOpCode() == ocPush )
+ {
+ if ( pToken->GetType() == svDouble )
+ {
+ nVal2 = pToken->GetDouble();
+ DELETEZ(pFormula2); // nicht als Formel merken
+ }
+ else if ( pToken->GetType() == svString )
+ {
+ bIsStr2 = TRUE;
+ aStrVal2 = pToken->GetString();
+ DELETEZ(pFormula2); // nicht als Formel merken
+ }
+ }
+ }
+ bRelRef2 = lcl_HasRelRef( pDoc, pFormula2 );
+ }
+ }
+ }
+}
+
+void ScConditionEntry::MakeCells( const ScAddress& rPos ) // Formelzellen anlegen
+{
+ if ( !pDoc->IsClipOrUndo() ) // nie im Clipboard rechnen!
+ {
+ if ( pFormula1 && !pFCell1 && !bRelRef1 )
+ {
+ pFCell1 = new ScFormulaCell( pDoc, rPos, pFormula1 );
+ pFCell1->StartListeningTo( pDoc );
+ }
+
+ if ( pFormula2 && !pFCell2 && !bRelRef2 )
+ {
+ pFCell2 = new ScFormulaCell( pDoc, rPos, pFormula2 );
+ pFCell2->StartListeningTo( pDoc );
+ }
+ }
+}
+
+void ScConditionEntry::SetIgnoreBlank(BOOL bSet)
+{
+ // Das Bit SC_COND_NOBLANKS wird gesetzt, wenn Blanks nicht ignoriert werden
+ // (nur bei Gueltigkeit)
+
+ if (bSet)
+ nOptions &= ~SC_COND_NOBLANKS;
+ else
+ nOptions |= SC_COND_NOBLANKS;
+}
+
+void ScConditionEntry::CompileAll()
+{
+ // Formelzellen loeschen, dann wird beim naechsten IsValid neu kompiliert
+
+ DELETEZ(pFCell1);
+ DELETEZ(pFCell2);
+}
+
+void ScConditionEntry::CompileXML()
+{
+ // #b4974740# First parse the formula source position if it was stored as text
+
+ if ( aSrcString.Len() )
+ {
+ ScAddress aNew;
+ /* XML is always in OOo:A1 format, although R1C1 would be more amenable
+ * to compression */
+ if ( aNew.Parse( aSrcString, pDoc ) & SCA_VALID )
+ aSrcPos = aNew;
+ // if the position is invalid, there isn't much we can do at this time
+ aSrcString.Erase();
+ }
+
+ // Convert the text tokens that were created during XML import into real tokens.
+
+ Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
+ GetExpression(aSrcPos, 1, 0, eTempGrammar2),
+ aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, TRUE );
+}
+
+void ScConditionEntry::SetSrcString( const String& rNew )
+{
+ // aSrcString is only evaluated in CompileXML
+ DBG_ASSERT( pDoc->IsImportingXML(), "SetSrcString is only valid for XML import" );
+
+ aSrcString = rNew;
+}
+
+void ScConditionEntry::SetFormula1( const ScTokenArray& rArray )
+{
+ DELETEZ( pFormula1 );
+ if( rArray.GetLen() > 0 )
+ {
+ pFormula1 = new ScTokenArray( rArray );
+ bRelRef1 = lcl_HasRelRef( pDoc, pFormula1 );
+ }
+}
+
+void ScConditionEntry::SetFormula2( const ScTokenArray& rArray )
+{
+ DELETEZ( pFormula2 );
+ if( rArray.GetLen() > 0 )
+ {
+ pFormula2 = new ScTokenArray( rArray );
+ bRelRef2 = lcl_HasRelRef( pDoc, pFormula2 );
+ }
+}
+
+void lcl_CondUpdateInsertTab( ScTokenArray& rCode, SCTAB nInsTab, SCTAB nPosTab, BOOL& rChanged )
+{
+ // Insert table: only update absolute table references.
+ // (Similar to ScCompiler::UpdateInsertTab with bIsName=TRUE, result is the same as for named ranges)
+ // For deleting, ScCompiler::UpdateDeleteTab is used because of the handling of invalid references.
+
+ rCode.Reset();
+ ScToken* p = static_cast<ScToken*>(rCode.GetNextReference());
+ while( p )
+ {
+ ScSingleRefData& rRef1 = p->GetSingleRef();
+ if ( !rRef1.IsTabRel() && nInsTab <= rRef1.nTab )
+ {
+ rRef1.nTab += 1;
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ rChanged = TRUE;
+ }
+ if( p->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
+ if ( !rRef2.IsTabRel() && nInsTab <= rRef2.nTab )
+ {
+ rRef2.nTab += 1;
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ rChanged = TRUE;
+ }
+ }
+ p = static_cast<ScToken*>(rCode.GetNextReference());
+ }
+}
+
+void ScConditionEntry::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ BOOL bInsertTab = ( eUpdateRefMode == URM_INSDEL && nDz == 1 );
+ BOOL bDeleteTab = ( eUpdateRefMode == URM_INSDEL && nDz == -1 );
+
+ BOOL bChanged1 = FALSE;
+ BOOL bChanged2 = FALSE;
+
+ if (pFormula1)
+ {
+ if ( bInsertTab )
+ lcl_CondUpdateInsertTab( *pFormula1, rRange.aStart.Tab(), aSrcPos.Tab(), bChanged1 );
+ else
+ {
+ ScCompiler aComp( pDoc, aSrcPos, *pFormula1 );
+ aComp.SetGrammar(pDoc->GetGrammar());
+ if ( bDeleteTab )
+ aComp.UpdateDeleteTab( rRange.aStart.Tab(), FALSE, TRUE, bChanged1 );
+ else
+ aComp.UpdateNameReference( eUpdateRefMode, rRange, nDx, nDy, nDz, bChanged1 );
+ }
+
+ if (bChanged1)
+ DELETEZ(pFCell1); // is created again in IsValid
+ }
+ if (pFormula2)
+ {
+ if ( bInsertTab )
+ lcl_CondUpdateInsertTab( *pFormula2, rRange.aStart.Tab(), aSrcPos.Tab(), bChanged2 );
+ else
+ {
+ ScCompiler aComp( pDoc, aSrcPos, *pFormula2);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ if ( bDeleteTab )
+ aComp.UpdateDeleteTab( rRange.aStart.Tab(), FALSE, TRUE, bChanged2 );
+ else
+ aComp.UpdateNameReference( eUpdateRefMode, rRange, nDx, nDy, nDz, bChanged2 );
+ }
+
+ if (bChanged2)
+ DELETEZ(pFCell2); // is created again in IsValid
+ }
+}
+
+void ScConditionEntry::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
+{
+ if (pFormula1)
+ {
+ ScCompiler aComp( pDoc, aSrcPos, *pFormula1);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.UpdateMoveTab(nOldPos, nNewPos, TRUE );
+ DELETEZ(pFCell1);
+ }
+ if (pFormula2)
+ {
+ ScCompiler aComp( pDoc, aSrcPos, *pFormula2);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.UpdateMoveTab(nOldPos, nNewPos, TRUE );
+ DELETEZ(pFCell2);
+ }
+}
+
+//! als Vergleichsoperator ans TokenArray ???
+
+BOOL lcl_IsEqual( const ScTokenArray* pArr1, const ScTokenArray* pArr2 )
+{
+ // verglichen wird nur das nicht-UPN Array
+
+ if ( pArr1 && pArr2 )
+ {
+ USHORT nLen = pArr1->GetLen();
+ if ( pArr2->GetLen() != nLen )
+ return FALSE;
+
+ FormulaToken** ppToken1 = pArr1->GetArray();
+ FormulaToken** ppToken2 = pArr2->GetArray();
+ for (USHORT i=0; i<nLen; i++)
+ {
+ if ( ppToken1[i] != ppToken2[i] &&
+ !(*ppToken1[i] == *ppToken2[i]) )
+ return FALSE; // Unterschied
+ }
+ return TRUE; // alle Eintraege gleich
+ }
+ else
+ return !pArr1 && !pArr2; // beide 0 -> gleich
+}
+
+int ScConditionEntry::operator== ( const ScConditionEntry& r ) const
+{
+ BOOL bEq = (eOp == r.eOp && nOptions == r.nOptions &&
+ lcl_IsEqual( pFormula1, r.pFormula1 ) &&
+ lcl_IsEqual( pFormula2, r.pFormula2 ));
+ if (bEq)
+ {
+ // for formulas, the reference positions must be compared, too
+ // (including aSrcString, for inserting the entries during XML import)
+ if ( ( pFormula1 || pFormula2 ) && ( aSrcPos != r.aSrcPos || aSrcString != r.aSrcString ) )
+ bEq = FALSE;
+
+ // wenn keine Formeln, Werte vergleichen
+ if ( !pFormula1 && ( nVal1 != r.nVal1 || aStrVal1 != r.aStrVal1 || bIsStr1 != r.bIsStr1 ) )
+ bEq = FALSE;
+ if ( !pFormula2 && ( nVal2 != r.nVal2 || aStrVal2 != r.aStrVal2 || bIsStr2 != r.bIsStr2 ) )
+ bEq = FALSE;
+ }
+
+ return bEq;
+}
+
+void ScConditionEntry::Interpret( const ScAddress& rPos )
+{
+ // Formelzellen anlegen
+ // dabei koennen neue Broadcaster (Note-Zellen) ins Dokument eingefuegt werden !!!!
+
+ if ( ( pFormula1 && !pFCell1 ) || ( pFormula2 && !pFCell2 ) )
+ MakeCells( rPos );
+
+ // Formeln auswerten
+
+ BOOL bDirty = FALSE; //! 1 und 2 getrennt ???
+
+ ScFormulaCell* pTemp1 = NULL;
+ ScFormulaCell* pEff1 = pFCell1;
+ if ( bRelRef1 )
+ {
+ pTemp1 = new ScFormulaCell( pDoc, rPos, pFormula1 ); // ohne Listening
+ pEff1 = pTemp1;
+ }
+ if ( pEff1 )
+ {
+ if (!pEff1->IsRunning()) // keine 522 erzeugen
+ {
+ //! Changed statt Dirty abfragen !!!
+ if (pEff1->GetDirty() && !bRelRef1)
+ bDirty = TRUE;
+ if (pEff1->IsValue())
+ {
+ bIsStr1 = FALSE;
+ nVal1 = pEff1->GetValue();
+ aStrVal1.Erase();
+ }
+ else
+ {
+ bIsStr1 = TRUE;
+ pEff1->GetString( aStrVal1 );
+ nVal1 = 0.0;
+ }
+ }
+ }
+ delete pTemp1;
+
+ ScFormulaCell* pTemp2 = NULL;
+ ScFormulaCell* pEff2 = pFCell2; //@ 1!=2
+ if ( bRelRef2 )
+ {
+ pTemp2 = new ScFormulaCell( pDoc, rPos, pFormula2 ); // ohne Listening
+ pEff2 = pTemp2;
+ }
+ if ( pEff2 )
+ {
+ if (!pEff2->IsRunning()) // keine 522 erzeugen
+ {
+ if (pEff2->GetDirty() && !bRelRef2)
+ bDirty = TRUE;
+ if (pEff2->IsValue())
+ {
+ bIsStr2 = FALSE;
+ nVal2 = pEff2->GetValue();
+ aStrVal2.Erase();
+ }
+ else
+ {
+ bIsStr2 = TRUE;
+ pEff2->GetString( aStrVal2 );
+ nVal2 = 0.0;
+ }
+ }
+ }
+ delete pTemp2;
+
+ // wenn IsRunning, bleiben die letzten Werte erhalten
+
+ if (bDirty && !bFirstRun)
+ {
+ // bei bedingten Formaten neu painten
+
+ DataChanged( NULL ); // alles
+ }
+
+ bFirstRun = FALSE;
+}
+
+BOOL ScConditionEntry::IsValid( double nArg ) const
+{
+ // Interpret muss schon gerufen sein
+
+ if ( bIsStr1 )
+ {
+ // wenn auf String getestet wird, bei Zahlen immer FALSE, ausser bei "ungleich"
+
+ return ( eOp == SC_COND_NOTEQUAL );
+ }
+
+ if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
+ if ( bIsStr2 )
+ return FALSE;
+
+ double nComp1 = nVal1; // Kopie, damit vertauscht werden kann
+ double nComp2 = nVal2;
+
+ if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
+ if ( nComp1 > nComp2 )
+ {
+ // richtige Reihenfolge fuer Wertebereich
+ double nTemp = nComp1; nComp1 = nComp2; nComp2 = nTemp;
+ }
+
+ // Alle Grenzfaelle muessen per ::rtl::math::approxEqual getestet werden!
+
+ BOOL bValid = FALSE;
+ switch (eOp)
+ {
+ case SC_COND_NONE:
+ break; // immer FALSE;
+ case SC_COND_EQUAL:
+ bValid = ::rtl::math::approxEqual( nArg, nComp1 );
+ break;
+ case SC_COND_NOTEQUAL:
+ bValid = !::rtl::math::approxEqual( nArg, nComp1 );
+ break;
+ case SC_COND_GREATER:
+ bValid = ( nArg > nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
+ break;
+ case SC_COND_EQGREATER:
+ bValid = ( nArg >= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
+ break;
+ case SC_COND_LESS:
+ bValid = ( nArg < nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
+ break;
+ case SC_COND_EQLESS:
+ bValid = ( nArg <= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
+ break;
+ case SC_COND_BETWEEN:
+ bValid = ( nArg >= nComp1 && nArg <= nComp2 ) ||
+ ::rtl::math::approxEqual( nArg, nComp1 ) || ::rtl::math::approxEqual( nArg, nComp2 );
+ break;
+ case SC_COND_NOTBETWEEN:
+ bValid = ( nArg < nComp1 || nArg > nComp2 ) &&
+ !::rtl::math::approxEqual( nArg, nComp1 ) && !::rtl::math::approxEqual( nArg, nComp2 );
+ break;
+ case SC_COND_DIRECT:
+ bValid = !::rtl::math::approxEqual( nComp1, 0.0 );
+ break;
+ default:
+ DBG_ERROR("unbekannte Operation bei ScConditionEntry");
+ break;
+ }
+ return bValid;
+}
+
+BOOL ScConditionEntry::IsValidStr( const String& rArg ) const
+{
+ // Interpret muss schon gerufen sein
+
+ if ( eOp == SC_COND_DIRECT ) // Formel ist unabhaengig vom Inhalt
+ return !::rtl::math::approxEqual( nVal1, 0.0 );
+
+ // Wenn Bedingung Zahl enthaelt, immer FALSE, ausser bei "ungleich"
+
+ if ( !bIsStr1 )
+ return ( eOp == SC_COND_NOTEQUAL );
+ if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
+ if ( !bIsStr2 )
+ return FALSE;
+
+ String aUpVal1( aStrVal1 ); //! als Member? (dann auch in Interpret setzen)
+ String aUpVal2( aStrVal2 );
+
+ if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
+ if ( ScGlobal::GetCollator()->compareString( aUpVal1, aUpVal2 )
+ == COMPARE_GREATER )
+ {
+ // richtige Reihenfolge fuer Wertebereich
+ String aTemp( aUpVal1 ); aUpVal1 = aUpVal2; aUpVal2 = aTemp;
+ }
+
+ BOOL bValid;
+ switch ( eOp )
+ {
+ case SC_COND_EQUAL:
+ bValid = (ScGlobal::GetCollator()->compareString(
+ rArg, aUpVal1 ) == COMPARE_EQUAL);
+ break;
+ case SC_COND_NOTEQUAL:
+ bValid = (ScGlobal::GetCollator()->compareString(
+ rArg, aUpVal1 ) != COMPARE_EQUAL);
+ break;
+ default:
+ {
+ sal_Int32 nCompare = ScGlobal::GetCollator()->compareString(
+ rArg, aUpVal1 );
+ switch ( eOp )
+ {
+ case SC_COND_GREATER:
+ bValid = ( nCompare == COMPARE_GREATER );
+ break;
+ case SC_COND_EQGREATER:
+ bValid = ( nCompare == COMPARE_EQUAL || nCompare == COMPARE_GREATER );
+ break;
+ case SC_COND_LESS:
+ bValid = ( nCompare == COMPARE_LESS );
+ break;
+ case SC_COND_EQLESS:
+ bValid = ( nCompare == COMPARE_EQUAL || nCompare == COMPARE_LESS );
+ break;
+ case SC_COND_BETWEEN:
+ case SC_COND_NOTBETWEEN:
+ // Test auf NOTBETWEEN:
+ bValid = ( nCompare == COMPARE_LESS ||
+ ScGlobal::GetCollator()->compareString( rArg,
+ aUpVal2 ) == COMPARE_GREATER );
+ if ( eOp == SC_COND_BETWEEN )
+ bValid = !bValid;
+ break;
+ // SC_COND_DIRECT schon oben abgefragt
+ default:
+ DBG_ERROR("unbekannte Operation bei ScConditionEntry");
+ bValid = FALSE;
+ break;
+ }
+ }
+ }
+ return bValid;
+}
+
+BOOL ScConditionEntry::IsCellValid( ScBaseCell* pCell, const ScAddress& rPos ) const
+{
+ ((ScConditionEntry*)this)->Interpret(rPos); // Formeln auswerten
+
+ double nArg = 0.0;
+ String aArgStr;
+ BOOL bVal = TRUE;
+
+ if ( pCell )
+ {
+ CellType eType = pCell->GetCellType();
+ switch (eType)
+ {
+ case CELLTYPE_VALUE:
+ nArg = ((ScValueCell*)pCell)->GetValue();
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ bVal = pFCell->IsValue();
+ if (bVal)
+ nArg = pFCell->GetValue();
+ else
+ pFCell->GetString(aArgStr);
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ bVal = FALSE;
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString(aArgStr);
+ else
+ ((ScEditCell*)pCell)->GetString(aArgStr);
+ break;
+
+ default:
+ pCell = NULL; // Note-Zellen wie leere
+ break;
+ }
+ }
+
+ if (!pCell)
+ if (bIsStr1)
+ bVal = FALSE; // leere Zellen je nach Bedingung
+
+ if (bVal)
+ return IsValid( nArg );
+ else
+ return IsValidStr( aArgStr );
+}
+
+String ScConditionEntry::GetExpression( const ScAddress& rCursor, USHORT nIndex,
+ ULONG nNumFmt,
+ const FormulaGrammar::Grammar eGrammar ) const
+{
+ String aRet;
+
+ if ( FormulaGrammar::isEnglish( eGrammar) && nNumFmt == 0 )
+ nNumFmt = pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US );
+
+ if ( nIndex==0 )
+ {
+ if ( pFormula1 )
+ {
+ ScCompiler aComp(pDoc, rCursor, *pFormula1);
+ aComp.SetGrammar(eGrammar);
+ aComp.CreateStringFromTokenArray( aRet );
+ }
+ else if (bIsStr1)
+ {
+ aRet = '"';
+ aRet += aStrVal1;
+ aRet += '"';
+ }
+ else
+ pDoc->GetFormatTable()->GetInputLineString(nVal1, nNumFmt, aRet);
+ }
+ else if ( nIndex==1 )
+ {
+ if ( pFormula2 )
+ {
+ ScCompiler aComp(pDoc, rCursor, *pFormula2);
+ aComp.SetGrammar(eGrammar);
+ aComp.CreateStringFromTokenArray( aRet );
+ }
+ else if (bIsStr2)
+ {
+ aRet = '"';
+ aRet += aStrVal2;
+ aRet += '"';
+ }
+ else
+ pDoc->GetFormatTable()->GetInputLineString(nVal2, nNumFmt, aRet);
+ }
+ else
+ {
+ DBG_ERROR("GetExpression: falscher Index");
+ }
+
+ return aRet;
+}
+
+ScTokenArray* ScConditionEntry::CreateTokenArry( USHORT nIndex ) const
+{
+ ScTokenArray* pRet = NULL;
+ ScAddress aAddr;
+
+ if ( nIndex==0 )
+ {
+ if ( pFormula1 )
+ pRet = new ScTokenArray( *pFormula1 );
+ else
+ {
+ pRet = new ScTokenArray();
+ if (bIsStr1)
+ pRet->AddString( aStrVal1.GetBuffer() );
+ else
+ pRet->AddDouble( nVal1 );
+ }
+ }
+ else if ( nIndex==1 )
+ {
+ if ( pFormula2 )
+ pRet = new ScTokenArray( *pFormula2 );
+ else
+ {
+ pRet = new ScTokenArray();
+ if (bIsStr2)
+ pRet->AddString( aStrVal2.GetBuffer() );
+ else
+ pRet->AddDouble( nVal2 );
+ }
+ }
+ else
+ {
+ DBG_ERROR("GetExpression: falscher Index");
+ }
+
+ return pRet;
+}
+
+void ScConditionEntry::SourceChanged( const ScAddress& rChanged )
+{
+ for (USHORT nPass = 0; nPass < 2; nPass++)
+ {
+ ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
+ if (pFormula)
+ {
+ pFormula->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pFormula->GetNextReference()) ) != NULL )
+ {
+ SingleDoubleRefProvider aProv( *t );
+ if ( aProv.Ref1.IsColRel() || aProv.Ref1.IsRowRel() || aProv.Ref1.IsTabRel() ||
+ aProv.Ref2.IsColRel() || aProv.Ref2.IsRowRel() || aProv.Ref2.IsTabRel() )
+ {
+ // absolut muss getroffen sein, relativ bestimmt Bereich
+
+ BOOL bHit = TRUE;
+ SCsCOL nCol1;
+ SCsROW nRow1;
+ SCsTAB nTab1;
+ SCsCOL nCol2;
+ SCsROW nRow2;
+ SCsTAB nTab2;
+
+ if ( aProv.Ref1.IsColRel() )
+ nCol2 = rChanged.Col() - aProv.Ref1.nRelCol;
+ else
+ {
+ bHit &= ( rChanged.Col() >= aProv.Ref1.nCol );
+ nCol2 = MAXCOL;
+ }
+ if ( aProv.Ref1.IsRowRel() )
+ nRow2 = rChanged.Row() - aProv.Ref1.nRelRow;
+ else
+ {
+ bHit &= ( rChanged.Row() >= aProv.Ref1.nRow );
+ nRow2 = MAXROW;
+ }
+ if ( aProv.Ref1.IsTabRel() )
+ nTab2 = rChanged.Tab() - aProv.Ref1.nRelTab;
+ else
+ {
+ bHit &= ( rChanged.Tab() >= aProv.Ref1.nTab );
+ nTab2 = MAXTAB;
+ }
+
+ if ( aProv.Ref2.IsColRel() )
+ nCol1 = rChanged.Col() - aProv.Ref2.nRelCol;
+ else
+ {
+ bHit &= ( rChanged.Col() <= aProv.Ref2.nCol );
+ nCol1 = 0;
+ }
+ if ( aProv.Ref2.IsRowRel() )
+ nRow1 = rChanged.Row() - aProv.Ref2.nRelRow;
+ else
+ {
+ bHit &= ( rChanged.Row() <= aProv.Ref2.nRow );
+ nRow1 = 0;
+ }
+ if ( aProv.Ref2.IsTabRel() )
+ nTab1 = rChanged.Tab() - aProv.Ref2.nRelTab;
+ else
+ {
+ bHit &= ( rChanged.Tab() <= aProv.Ref2.nTab );
+ nTab1 = 0;
+ }
+
+ if ( bHit )
+ {
+ //! begrenzen
+
+ ScRange aPaint( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 );
+
+ // kein Paint, wenn es nur die Zelle selber ist
+ if ( aPaint.aStart != rChanged || aPaint.aEnd != rChanged )
+ DataChanged( &aPaint );
+ }
+ }
+ }
+ }
+ }
+}
+
+ScAddress ScConditionEntry::GetValidSrcPos() const
+{
+ // return a position that's adjusted to allow textual representation of expressions if possible
+
+ SCTAB nMinTab = aSrcPos.Tab();
+ SCTAB nMaxTab = nMinTab;
+
+ for (USHORT nPass = 0; nPass < 2; nPass++)
+ {
+ ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
+ if (pFormula)
+ {
+ pFormula->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pFormula->GetNextReference()) ) != NULL )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
+ {
+ if ( rRef1.nTab < nMinTab )
+ nMinTab = rRef1.nTab;
+ if ( rRef1.nTab > nMaxTab )
+ nMaxTab = rRef1.nTab;
+ }
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
+ {
+ if ( rRef2.nTab < nMinTab )
+ nMinTab = rRef2.nTab;
+ if ( rRef2.nTab > nMaxTab )
+ nMaxTab = rRef2.nTab;
+ }
+ }
+ }
+ }
+ }
+
+ ScAddress aValidPos = aSrcPos;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nMaxTab >= nTabCount && nMinTab > 0 )
+ aValidPos.SetTab( aSrcPos.Tab() - nMinTab ); // so the lowest tab ref will be on 0
+
+ if ( aValidPos.Tab() >= nTabCount )
+ aValidPos.SetTab( nTabCount - 1 ); // ensure a valid position even if some references will be invalid
+
+ return aValidPos;
+}
+
+void ScConditionEntry::DataChanged( const ScRange* /* pModified */ ) const
+{
+ // nix
+}
+
+bool ScConditionEntry::MarkUsedExternalReferences() const
+{
+ bool bAllMarked = false;
+ for (USHORT nPass = 0; !bAllMarked && nPass < 2; nPass++)
+ {
+ ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
+ if (pFormula)
+ bAllMarked = pDoc->MarkUsedExternalReferences( *pFormula);
+ }
+ return bAllMarked;
+}
+
+//------------------------------------------------------------------------
+
+ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
+ const String& rExpr1, const String& rExpr2,
+ ScDocument* pDocument, const ScAddress& rPos,
+ const String& rStyle,
+ 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 )
+{
+}
+
+ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
+ const ScTokenArray* pArr1, const ScTokenArray* pArr2,
+ ScDocument* pDocument, const ScAddress& rPos,
+ const String& rStyle ) :
+ ScConditionEntry( eOper, pArr1, pArr2, pDocument, rPos ),
+ aStyleName( rStyle ),
+ pParent( NULL )
+{
+}
+
+ScCondFormatEntry::ScCondFormatEntry( const ScCondFormatEntry& r ) :
+ ScConditionEntry( r ),
+ aStyleName( r.aStyleName ),
+ pParent( NULL )
+{
+}
+
+ScCondFormatEntry::ScCondFormatEntry( ScDocument* pDocument, const ScCondFormatEntry& r ) :
+ ScConditionEntry( pDocument, r ),
+ aStyleName( r.aStyleName ),
+ pParent( NULL )
+{
+}
+
+int ScCondFormatEntry::operator== ( const ScCondFormatEntry& r ) const
+{
+ return ScConditionEntry::operator==( r ) &&
+ aStyleName == r.aStyleName;
+
+ // Range wird nicht verglichen
+}
+
+ScCondFormatEntry::~ScCondFormatEntry()
+{
+}
+
+void ScCondFormatEntry::DataChanged( const ScRange* pModified ) const
+{
+ if ( pParent )
+ pParent->DoRepaint( pModified );
+}
+
+//------------------------------------------------------------------------
+
+ScConditionalFormat::ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument) :
+ pDoc( pDocument ),
+ pAreas( NULL ),
+ nKey( nNewKey ),
+ ppEntries( NULL ),
+ nEntryCount( 0 )
+{
+}
+
+ScConditionalFormat::ScConditionalFormat(const ScConditionalFormat& r) :
+ pDoc( r.pDoc ),
+ pAreas( NULL ),
+ nKey( r.nKey ),
+ ppEntries( NULL ),
+ nEntryCount( r.nEntryCount )
+{
+ if (nEntryCount)
+ {
+ ppEntries = new ScCondFormatEntry*[nEntryCount];
+ for (USHORT i=0; i<nEntryCount; i++)
+ {
+ ppEntries[i] = new ScCondFormatEntry(*r.ppEntries[i]);
+ ppEntries[i]->SetParent(this);
+ }
+ }
+}
+
+ScConditionalFormat* ScConditionalFormat::Clone(ScDocument* pNewDoc) const
+{
+ // echte Kopie der Formeln (fuer Ref-Undo / zwischen Dokumenten)
+
+ if (!pNewDoc)
+ pNewDoc = pDoc;
+
+ ScConditionalFormat* pNew = new ScConditionalFormat(nKey, pNewDoc);
+ DBG_ASSERT(!pNew->ppEntries, "wo kommen die Eintraege her?");
+
+ if (nEntryCount)
+ {
+ pNew->ppEntries = new ScCondFormatEntry*[nEntryCount];
+ for (USHORT i=0; i<nEntryCount; i++)
+ {
+ pNew->ppEntries[i] = new ScCondFormatEntry( pNewDoc, *ppEntries[i] );
+ pNew->ppEntries[i]->SetParent(pNew);
+ }
+ pNew->nEntryCount = nEntryCount;
+ }
+
+ return pNew;
+}
+
+BOOL ScConditionalFormat::EqualEntries( const ScConditionalFormat& r ) const
+{
+ if ( nEntryCount != r.nEntryCount )
+ return FALSE;
+
+ //! auf gleiche Eintraege in anderer Reihenfolge testen ???
+
+ for (USHORT i=0; i<nEntryCount; i++)
+ if ( ! (*ppEntries[i] == *r.ppEntries[i]) )
+ return FALSE;
+
+ return TRUE;
+}
+
+void ScConditionalFormat::AddEntry( const ScCondFormatEntry& rNew )
+{
+ ScCondFormatEntry** ppNew = new ScCondFormatEntry*[nEntryCount+1];
+ for (USHORT i=0; i<nEntryCount; i++)
+ ppNew[i] = ppEntries[i];
+ ppNew[nEntryCount] = new ScCondFormatEntry(rNew);
+ ppNew[nEntryCount]->SetParent(this);
+ ++nEntryCount;
+ delete[] ppEntries;
+ ppEntries = ppNew;
+}
+
+ScConditionalFormat::~ScConditionalFormat()
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ delete ppEntries[i];
+ delete[] ppEntries;
+
+ delete pAreas;
+}
+
+const ScCondFormatEntry* ScConditionalFormat::GetEntry( USHORT nPos ) const
+{
+ if ( nPos < nEntryCount )
+ return ppEntries[nPos];
+ else
+ return NULL;
+}
+
+const String& ScConditionalFormat::GetCellStyle( ScBaseCell* pCell, const ScAddress& rPos ) const
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ if ( ppEntries[i]->IsCellValid( pCell, rPos ) )
+ return ppEntries[i]->GetStyle();
+
+ return EMPTY_STRING;
+}
+
+void lcl_Extend( ScRange& rRange, ScDocument* pDoc, BOOL bLines )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ DBG_ASSERT(rRange.aEnd.Tab() == nTab, "lcl_Extend - mehrere Tabellen?");
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+
+ BOOL bEx = pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+
+ if (bLines)
+ {
+ if (nStartCol > 0) --nStartCol;
+ if (nStartRow > 0) --nStartRow;
+ if (nEndCol < MAXCOL) ++nEndCol;
+ if (nEndRow < MAXROW) ++nEndRow;
+ }
+
+ if ( bEx || bLines )
+ {
+ rRange.aStart.Set( nStartCol, nStartRow, nTab );
+ rRange.aEnd.Set( nEndCol, nEndRow, nTab );
+ }
+}
+
+BOOL lcl_CutRange( ScRange& rRange, const ScRange& rOther )
+{
+ rRange.Justify();
+ ScRange aCmpRange = rOther;
+ aCmpRange.Justify();
+
+ if ( rRange.aStart.Col() <= aCmpRange.aEnd.Col() &&
+ rRange.aEnd.Col() >= aCmpRange.aStart.Col() &&
+ rRange.aStart.Row() <= aCmpRange.aEnd.Row() &&
+ rRange.aEnd.Row() >= aCmpRange.aStart.Row() &&
+ rRange.aStart.Tab() <= aCmpRange.aEnd.Tab() &&
+ rRange.aEnd.Tab() >= aCmpRange.aStart.Tab() )
+ {
+ if ( rRange.aStart.Col() < aCmpRange.aStart.Col() )
+ rRange.aStart.SetCol( aCmpRange.aStart.Col() );
+ if ( rRange.aStart.Row() < aCmpRange.aStart.Row() )
+ rRange.aStart.SetRow( aCmpRange.aStart.Row() );
+ if ( rRange.aStart.Tab() < aCmpRange.aStart.Tab() )
+ rRange.aStart.SetTab( aCmpRange.aStart.Tab() );
+ if ( rRange.aEnd.Col() > aCmpRange.aEnd.Col() )
+ rRange.aEnd.SetCol( aCmpRange.aEnd.Col() );
+ if ( rRange.aEnd.Row() > aCmpRange.aEnd.Row() )
+ rRange.aEnd.SetRow( aCmpRange.aEnd.Row() );
+ if ( rRange.aEnd.Tab() > aCmpRange.aEnd.Tab() )
+ rRange.aEnd.SetTab( aCmpRange.aEnd.Tab() );
+
+ return TRUE;
+ }
+
+ return FALSE; // ausserhalb
+}
+
+void ScConditionalFormat::DoRepaint( const ScRange* pModified )
+{
+ USHORT i;
+ SfxObjectShell* pSh = pDoc->GetDocumentShell();
+ if (pSh)
+ {
+ // Rahmen/Schatten enthalten?
+ // (alle Bedingungen testen)
+ BOOL bExtend = FALSE;
+ BOOL bRotate = FALSE;
+ BOOL bAttrTested = FALSE;
+
+ if (!pAreas) // RangeList ggf. holen
+ {
+ pAreas = new ScRangeList;
+ pDoc->FindConditionalFormat( nKey, *pAreas );
+ }
+ USHORT nCount = (USHORT) pAreas->Count();
+ for (i=0; i<nCount; i++)
+ {
+ ScRange aRange = *pAreas->GetObject(i);
+ BOOL bDo = TRUE;
+ if ( pModified )
+ {
+ if ( !lcl_CutRange( aRange, *pModified ) )
+ bDo = FALSE;
+ }
+ if (bDo)
+ {
+ if ( !bAttrTested )
+ {
+ // #116562# Look at the style's content only if the repaint is necessary
+ // for any condition, to avoid the time-consuming Find() if there are many
+ // conditional formats and styles.
+ for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aStyle = ppEntries[nEntry]->GetStyle();
+ if (aStyle.Len())
+ {
+ SfxStyleSheetBase* pStyleSheet =
+ pDoc->GetStyleSheetPool()->Find( aStyle, SFX_STYLE_FAMILY_PARA );
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if (rSet.GetItemState( ATTR_BORDER, TRUE ) == SFX_ITEM_SET ||
+ rSet.GetItemState( ATTR_SHADOW, TRUE ) == SFX_ITEM_SET)
+ {
+ bExtend = TRUE;
+ }
+ if (rSet.GetItemState( ATTR_ROTATE_VALUE, TRUE ) == SFX_ITEM_SET ||
+ rSet.GetItemState( ATTR_ROTATE_MODE, TRUE ) == SFX_ITEM_SET)
+ {
+ bRotate = TRUE;
+ }
+ }
+ }
+ }
+ bAttrTested = TRUE;
+ }
+
+ lcl_Extend( aRange, pDoc, bExtend ); // zusammengefasste und bExtend
+ if ( bRotate )
+ {
+ aRange.aStart.SetCol(0);
+ aRange.aEnd.SetCol(MAXCOL); // gedreht: ganze Zeilen
+ }
+
+ // gedreht -> ganze Zeilen
+ if ( aRange.aStart.Col() != 0 || aRange.aEnd.Col() != MAXCOL )
+ {
+ if ( pDoc->HasAttrib( 0,aRange.aStart.Row(),aRange.aStart.Tab(),
+ MAXCOL,aRange.aEnd.Row(),aRange.aEnd.Tab(),
+ HASATTR_ROTATE ) )
+ {
+ aRange.aStart.SetCol(0);
+ aRange.aEnd.SetCol(MAXCOL);
+ }
+ }
+
+ pSh->Broadcast( ScPaintHint( aRange, PAINT_GRID ) );
+ }
+ }
+ }
+}
+
+void ScConditionalFormat::InvalidateArea()
+{
+ delete pAreas;
+ pAreas = NULL;
+}
+
+void ScConditionalFormat::CompileAll()
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ ppEntries[i]->CompileAll();
+}
+
+void ScConditionalFormat::CompileXML()
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ ppEntries[i]->CompileXML();
+}
+
+void ScConditionalFormat::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ ppEntries[i]->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz);
+
+ delete pAreas; // aus dem AttrArray kommt beim Einfuegen/Loeschen kein Aufruf
+ pAreas = NULL;
+}
+
+void ScConditionalFormat::RenameCellStyle(const String& rOld, const String& rNew)
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ if ( ppEntries[i]->GetStyle() == rOld )
+ ppEntries[i]->UpdateStyleName( rNew );
+}
+
+void ScConditionalFormat::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ ppEntries[i]->UpdateMoveTab( nOldPos, nNewPos );
+
+ delete pAreas; // aus dem AttrArray kommt beim Einfuegen/Loeschen kein Aufruf
+ pAreas = NULL;
+}
+
+void ScConditionalFormat::SourceChanged( const ScAddress& rAddr )
+{
+ for (USHORT i=0; i<nEntryCount; i++)
+ ppEntries[i]->SourceChanged( rAddr );
+}
+
+bool ScConditionalFormat::MarkUsedExternalReferences() const
+{
+ bool bAllMarked = false;
+ for (USHORT i=0; !bAllMarked && i<nEntryCount; i++)
+ bAllMarked = ppEntries[i]->MarkUsedExternalReferences();
+ return bAllMarked;
+}
+
+//------------------------------------------------------------------------
+
+ScConditionalFormatList::ScConditionalFormatList(const ScConditionalFormatList& rList) :
+ ScConditionalFormats_Impl()
+{
+ // fuer Ref-Undo - echte Kopie mit neuen Tokens!
+
+ USHORT nCount = rList.Count();
+
+ for (USHORT i=0; i<nCount; i++)
+ InsertNew( rList[i]->Clone() );
+
+ //! sortierte Eintraege aus rList schneller einfuegen ???
+}
+
+ScConditionalFormatList::ScConditionalFormatList(ScDocument* pNewDoc,
+ const ScConditionalFormatList& rList)
+{
+ // fuer neues Dokument - echte Kopie mit neuen Tokens!
+
+ USHORT nCount = rList.Count();
+
+ for (USHORT i=0; i<nCount; i++)
+ InsertNew( rList[i]->Clone(pNewDoc) );
+
+ //! sortierte Eintraege aus rList schneller einfuegen ???
+}
+
+BOOL ScConditionalFormatList::operator==( const ScConditionalFormatList& r ) const
+{
+ // fuer Ref-Undo - interne Variablen werden nicht verglichen
+
+ USHORT nCount = Count();
+ BOOL bEqual = ( nCount == r.Count() );
+ for (USHORT i=0; i<nCount && bEqual; i++) // Eintraege sind sortiert
+ if ( !(*this)[i]->EqualEntries(*r[i]) ) // Eintraege unterschiedlich ?
+ bEqual = FALSE;
+
+ return bEqual;
+}
+
+ScConditionalFormat* ScConditionalFormatList::GetFormat( sal_uInt32 nKey )
+{
+ //! binaer suchen
+
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ if ((*this)[i]->GetKey() == nKey)
+ return (*this)[i];
+
+ DBG_ERROR("ScConditionalFormatList: Eintrag nicht gefunden");
+ return NULL;
+}
+
+void ScConditionalFormatList::CompileAll()
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->CompileAll();
+}
+
+void ScConditionalFormatList::CompileXML()
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->CompileXML();
+}
+
+void ScConditionalFormatList::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz );
+}
+
+void ScConditionalFormatList::RenameCellStyle( const String& rOld, const String& rNew )
+{
+ ULONG nCount=Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->RenameCellStyle(rOld,rNew);
+}
+
+void ScConditionalFormatList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->UpdateMoveTab( nOldPos, nNewPos );
+}
+
+void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->SourceChanged( rAddr );
+}
+
+bool ScConditionalFormatList::MarkUsedExternalReferences() const
+{
+ bool bAllMarked = false;
+ USHORT nCount = Count();
+ for (USHORT i=0; !bAllMarked && i<nCount; i++)
+ bAllMarked = (*this)[i]->MarkUsedExternalReferences();
+ return bAllMarked;
+}
diff --git a/sc/source/core/data/dbdocutl.cxx b/sc/source/core/data/dbdocutl.cxx
new file mode 100644
index 000000000000..39675704fb70
--- /dev/null
+++ b/sc/source/core/data/dbdocutl.cxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+
+#include <svl/zforlist.hxx>
+
+#include "dbdocutl.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "formula/errorcodes.hxx"
+
+using namespace ::com::sun::star;
+
+#define D_TIMEFACTOR 86400.0
+
+// -----------------------------------------------------------------------
+
+// static
+void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+ const uno::Reference<sdbc::XRow>& xRow, long nRowPos,
+ long nType, BOOL bCurrency, BOOL* pSimpleFlag )
+{
+ String aString;
+ double nVal = 0.0;
+ BOOL bValue = FALSE;
+ BOOL bEmptyFlag = FALSE;
+ BOOL bError = FALSE;
+ ULONG nFormatIndex = 0;
+
+ //! wasNull calls only if null value was found?
+
+ try
+ {
+ switch ( nType )
+ {
+ case sdbc::DataType::BIT:
+ case sdbc::DataType::BOOLEAN:
+ //! use language from doc (here, date/time and currency)?
+ nFormatIndex = pDoc->GetFormatTable()->GetStandardFormat(
+ NUMBERFORMAT_LOGICAL, ScGlobal::eLnge );
+ nVal = (xRow->getBoolean(nRowPos) ? 1 : 0);
+ bEmptyFlag = ( nVal == 0.0 ) && xRow->wasNull();
+ bValue = TRUE;
+ break;
+
+ case sdbc::DataType::TINYINT:
+ case sdbc::DataType::SMALLINT:
+ case sdbc::DataType::INTEGER:
+ case sdbc::DataType::BIGINT:
+ case sdbc::DataType::FLOAT:
+ case sdbc::DataType::REAL:
+ case sdbc::DataType::DOUBLE:
+ case sdbc::DataType::NUMERIC:
+ case sdbc::DataType::DECIMAL:
+ //! do the conversion here?
+ nVal = xRow->getDouble(nRowPos);
+ bEmptyFlag = ( nVal == 0.0 ) && xRow->wasNull();
+ bValue = TRUE;
+ break;
+
+ case sdbc::DataType::CHAR:
+ case sdbc::DataType::VARCHAR:
+ case sdbc::DataType::LONGVARCHAR:
+ aString = xRow->getString(nRowPos);
+ bEmptyFlag = ( aString.Len() == 0 ) && xRow->wasNull();
+ break;
+
+ case sdbc::DataType::DATE:
+ {
+ SvNumberFormatter* pFormTable = pDoc->GetFormatTable();
+ nFormatIndex = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_DATE, ScGlobal::eLnge );
+
+ util::Date aDate = xRow->getDate(nRowPos);
+ nVal = Date( aDate.Day, aDate.Month, aDate.Year ) -
+ *pFormTable->GetNullDate();
+ bEmptyFlag = xRow->wasNull();
+ bValue = TRUE;
+ }
+ break;
+
+ case sdbc::DataType::TIME:
+ {
+ SvNumberFormatter* pFormTable = pDoc->GetFormatTable();
+ nFormatIndex = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_TIME, ScGlobal::eLnge );
+
+ util::Time aTime = xRow->getTime(nRowPos);
+ nVal = ( aTime.Hours * 3600 + aTime.Minutes * 60 +
+ aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
+ bEmptyFlag = xRow->wasNull();
+ bValue = TRUE;
+ }
+ break;
+
+ case sdbc::DataType::TIMESTAMP:
+ {
+ SvNumberFormatter* pFormTable = pDoc->GetFormatTable();
+ nFormatIndex = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_DATETIME, ScGlobal::eLnge );
+
+ util::DateTime aStamp = xRow->getTimestamp(nRowPos);
+ nVal = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) -
+ *pFormTable->GetNullDate() ) +
+ ( aStamp.Hours * 3600 + aStamp.Minutes * 60 +
+ aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
+ bEmptyFlag = xRow->wasNull();
+ bValue = TRUE;
+ }
+ break;
+
+ case sdbc::DataType::SQLNULL:
+ bEmptyFlag = TRUE;
+ break;
+
+ case sdbc::DataType::BINARY:
+ case sdbc::DataType::VARBINARY:
+ case sdbc::DataType::LONGVARBINARY:
+ default:
+ bError = TRUE; // unknown type
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ bError = TRUE;
+ }
+
+ if ( bValue && bCurrency )
+ nFormatIndex = pDoc->GetFormatTable()->GetStandardFormat(
+ NUMBERFORMAT_CURRENCY, ScGlobal::eLnge );
+
+ ScBaseCell* pCell;
+ if (bEmptyFlag)
+ {
+ pCell = NULL;
+ pDoc->PutCell( nCol, nRow, nTab, pCell );
+ }
+ else if (bError)
+ {
+ pDoc->SetError( nCol, nRow, nTab, NOTAVAILABLE );
+ }
+ else if (bValue)
+ {
+ pCell = new ScValueCell( nVal );
+ if (nFormatIndex == 0)
+ pDoc->PutCell( nCol, nRow, nTab, pCell );
+ else
+ pDoc->PutCell( nCol, nRow, nTab, pCell, nFormatIndex );
+ }
+ else
+ {
+ if (aString.Len())
+ {
+ pCell = ScBaseCell::CreateTextCell( aString, pDoc );
+ if ( pSimpleFlag && pCell->GetCellType() == CELLTYPE_EDIT )
+ *pSimpleFlag = FALSE;
+ }
+ else
+ pCell = NULL;
+ pDoc->PutCell( nCol, nRow, nTab, pCell );
+ }
+}
+
+
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
new file mode 100644
index 000000000000..aa5b011da93b
--- /dev/null
+++ b/sc/source/core/data/dociter.cxx
@@ -0,0 +1,2158 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/zforlist.hxx>
+
+#include "scitems.hxx"
+#include "global.hxx"
+#include "dociter.hxx"
+#include "document.hxx"
+#include "table.hxx"
+#include "column.hxx"
+#include "cell.hxx"
+#include "attarray.hxx"
+#include "patattr.hxx"
+#include "docoptio.hxx"
+#include "cellform.hxx"
+
+#include <vector>
+
+using ::rtl::math::approxEqual;
+using ::std::vector;
+using ::rtl::OUString;
+using ::std::set;
+
+// STATIC DATA -----------------------------------------------------------
+
+namespace {
+
+void lcl_toUpper(OUString& rStr)
+{
+ rStr = ScGlobal::pCharClass->toUpper(rStr.trim(), 0, static_cast<USHORT>(rStr.getLength()));
+}
+
+}
+
+ScDocumentIterator::ScDocumentIterator( ScDocument* pDocument,
+ SCTAB nStartTable, SCTAB nEndTable ) :
+ pDoc( pDocument ),
+ nStartTab( nStartTable ),
+ nEndTab( nEndTable )
+{
+ PutInOrder( nStartTab, nEndTab );
+ if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
+ if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
+
+ pDefPattern = pDoc->GetDefPattern();
+
+ nCol = 0;
+ nRow = 0;
+ nTab = nStartTab;
+
+ nColPos = 0;
+ nAttrPos = 0;
+}
+
+ScDocumentIterator::~ScDocumentIterator()
+{
+}
+
+BOOL ScDocumentIterator::GetThisCol()
+{
+ ScTable* pTab;
+ while ( (pTab = pDoc->pTab[nTab]) == NULL )
+ {
+ if ( nTab == nEndTab )
+ {
+ nCol = MAXCOL;
+ nRow = MAXROW;
+ return FALSE;
+ }
+ ++nTab;
+ }
+ ScColumn* pCol = &pTab->aCol[nCol];
+ ScAttrArray* pAtt = pCol->pAttrArray;
+
+ BOOL bFound = FALSE;
+ do
+ {
+ SCROW nColRow;
+ SCROW nAttrEnd;
+
+ do
+ {
+ nAttrEnd = pAtt->pData[nAttrPos].nRow;
+ if (nAttrEnd < nRow)
+ ++nAttrPos;
+ }
+ while (nAttrEnd < nRow);
+
+ do
+ {
+ nColRow = (nColPos < pCol->nCount) ? pCol->pItems[nColPos].nRow : MAXROW+1;
+ if (nColRow < nRow)
+ ++nColPos;
+ }
+ while (nColRow < nRow);
+
+ if (nColRow == nRow)
+ {
+ bFound = TRUE;
+ pCell = pCol->pItems[nColPos].pCell;
+ pPattern = pAtt->pData[nAttrPos].pPattern;
+ }
+ else if ( pAtt->pData[nAttrPos].pPattern != pDefPattern )
+ {
+ bFound = TRUE;
+ pCell = NULL;
+ pPattern = pAtt->pData[nAttrPos].pPattern;
+ }
+ else
+ {
+ nRow = Min( (SCROW)nColRow, (SCROW)(nAttrEnd+1) );
+ }
+ }
+ while (!bFound && nRow <= MAXROW);
+
+ return bFound;
+}
+
+BOOL ScDocumentIterator::GetThis()
+{
+ BOOL bEnd = FALSE;
+ BOOL bSuccess = FALSE;
+
+ while ( !bSuccess && !bEnd )
+ {
+ if ( nRow > MAXROW )
+ bSuccess = FALSE;
+ else
+ bSuccess = GetThisCol();
+
+ if ( !bSuccess )
+ {
+ ++nCol;
+ if (nCol > MAXCOL)
+ {
+ nCol = 0;
+ ++nTab;
+ if (nTab > nEndTab)
+ bEnd = TRUE;
+ }
+ nRow = 0;
+ nColPos = 0;
+ nAttrPos = 0;
+ }
+ }
+
+ return !bEnd;
+}
+
+BOOL ScDocumentIterator::GetFirst()
+{
+ nCol = 0;
+ nTab = nStartTab;
+
+ nRow = 0;
+ nColPos = 0;
+ nAttrPos = 0;
+
+ return GetThis();
+}
+
+BOOL ScDocumentIterator::GetNext()
+{
+ ++nRow;
+
+ return GetThis();
+}
+
+//------------------------------------------------------------------------
+
+ScBaseCell* ScDocumentIterator::GetCell()
+{
+ return pCell;
+}
+
+const ScPatternAttr* ScDocumentIterator::GetPattern()
+{
+ return pPattern;
+}
+
+void ScDocumentIterator::GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
+{
+ rCol = nCol;
+ rRow = nRow;
+ rTab = nTab;
+}
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+void lcl_IterGetNumberFormat( ULONG& nFormat, const ScAttrArray*& rpArr,
+ SCROW& nAttrEndRow, const ScAttrArray* pNewArr, SCROW nRow,
+ ScDocument* pDoc )
+{
+ if ( rpArr != pNewArr || nAttrEndRow < nRow )
+ {
+ SCSIZE nPos;
+ pNewArr->Search( nRow, nPos ); // nPos 0 gueltig wenn nicht gefunden
+ const ScPatternAttr* pPattern = pNewArr->pData[nPos].pPattern;
+ nFormat = pPattern->GetNumberFormat( pDoc->GetFormatTable() );
+ rpArr = pNewArr;
+ nAttrEndRow = pNewArr->pData[nPos].nRow;
+ }
+}
+
+//UNUSED2008-05 ScValueIterator::ScValueIterator( ScDocument* pDocument,
+//UNUSED2008-05 SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
+//UNUSED2008-05 SCCOL nECol, SCROW nERow, SCTAB nETab,
+//UNUSED2008-05 BOOL bSTotal, BOOL bTextZero ) :
+//UNUSED2008-05 pDoc( pDocument ),
+//UNUSED2008-05 nNumFmtIndex(0),
+//UNUSED2008-05 nStartCol( nSCol),
+//UNUSED2008-05 nStartRow( nSRow),
+//UNUSED2008-05 nStartTab( nSTab ),
+//UNUSED2008-05 nEndCol( nECol ),
+//UNUSED2008-05 nEndRow( nERow),
+//UNUSED2008-05 nEndTab( nETab ),
+//UNUSED2008-05 nNumFmtType( NUMBERFORMAT_UNDEFINED ),
+//UNUSED2008-05 bNumValid( FALSE ),
+//UNUSED2008-05 bSubTotal(bSTotal),
+//UNUSED2008-05 bNextValid( FALSE ),
+//UNUSED2008-05 bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
+//UNUSED2008-05 bTextAsZero( bTextZero )
+//UNUSED2008-05 {
+//UNUSED2008-05 PutInOrder( nStartCol, nEndCol);
+//UNUSED2008-05 PutInOrder( nStartRow, nEndRow);
+//UNUSED2008-05 PutInOrder( nStartTab, nEndTab );
+//UNUSED2008-05
+//UNUSED2008-05 if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+//UNUSED2008-05 if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+//UNUSED2008-05 if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+//UNUSED2008-05 if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+//UNUSED2008-05 if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
+//UNUSED2008-05 if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
+//UNUSED2008-05
+//UNUSED2008-05 nCol = nStartCol;
+//UNUSED2008-05 nRow = nStartRow;
+//UNUSED2008-05 nTab = nStartTab;
+//UNUSED2008-05
+//UNUSED2008-05 nColRow = 0; // wird bei GetFirst initialisiert
+//UNUSED2008-05
+//UNUSED2008-05 nNumFormat = 0; // werden bei GetNumberFormat initialisiert
+//UNUSED2008-05 pAttrArray = 0;
+//UNUSED2008-05 nAttrEndRow = 0;
+//UNUSED2008-05 }
+
+ScValueIterator::ScValueIterator( ScDocument* pDocument, const ScRange& rRange,
+ BOOL bSTotal, BOOL bTextZero ) :
+ pDoc( pDocument ),
+ nNumFmtIndex(0),
+ nStartCol( rRange.aStart.Col() ),
+ nStartRow( rRange.aStart.Row() ),
+ nStartTab( rRange.aStart.Tab() ),
+ nEndCol( rRange.aEnd.Col() ),
+ nEndRow( rRange.aEnd.Row() ),
+ nEndTab( rRange.aEnd.Tab() ),
+ nNumFmtType( NUMBERFORMAT_UNDEFINED ),
+ bNumValid( FALSE ),
+ bSubTotal(bSTotal),
+ bNextValid( FALSE ),
+ bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
+ bTextAsZero( bTextZero )
+{
+ PutInOrder( nStartCol, nEndCol);
+ PutInOrder( nStartRow, nEndRow);
+ PutInOrder( nStartTab, nEndTab );
+
+ if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+ if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+ if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+ if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+ if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
+ if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
+
+ nCol = nStartCol;
+ nRow = nStartRow;
+ nTab = nStartTab;
+
+ nColRow = 0; // wird bei GetFirst initialisiert
+
+ nNumFormat = 0; // werden bei GetNumberFormat initialisiert
+ pAttrArray = 0;
+ nAttrEndRow = 0;
+}
+
+BOOL ScValueIterator::GetThis(double& rValue, USHORT& rErr)
+{
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ for (;;)
+ {
+ if ( nRow > nEndRow )
+ {
+ nRow = nStartRow;
+ do
+ {
+ nCol++;
+ if ( nCol > nEndCol )
+ {
+ nCol = nStartCol;
+ nTab++;
+ if ( nTab > nEndTab )
+ {
+ // rValue = 0.0; //! do not change caller's value!
+ rErr = 0;
+ return FALSE; // Ende und Aus
+ }
+ }
+ pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ } while ( pCol->nCount == 0 );
+ pCol->Search( nRow, nColRow );
+ }
+
+ while (( nColRow < pCol->nCount ) && ( pCol->pItems[nColRow].nRow < nRow ))
+ nColRow++;
+
+ if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
+ {
+ nRow = pCol->pItems[nColRow].nRow + 1;
+ if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow-1 ) )
+ {
+ ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
+ ++nColRow;
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ {
+ bNumValid = FALSE;
+ rValue = ((ScValueCell*)pCell)->GetValue();
+ rErr = 0;
+ --nRow;
+ if ( bCalcAsShown )
+ {
+ lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
+ nAttrEndRow, pCol->pAttrArray, nRow, pDoc );
+ rValue = pDoc->RoundValueAsShown( rValue, nNumFormat );
+ }
+ //
+ // wenn in der selben Spalte gleich noch eine Value-Cell folgt, die
+ // auch noch im Block liegt, den Wert jetzt schon holen
+ //
+ if ( nColRow < pCol->nCount &&
+ pCol->pItems[nColRow].nRow <= nEndRow &&
+ pCol->pItems[nColRow].pCell->GetCellType() == CELLTYPE_VALUE &&
+ !bSubTotal )
+ {
+ fNextValue = ((ScValueCell*)pCol->pItems[nColRow].pCell)->GetValue();
+ nNextRow = pCol->pItems[nColRow].nRow;
+ bNextValid = TRUE;
+ if ( bCalcAsShown )
+ {
+ lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
+ nAttrEndRow, pCol->pAttrArray, nNextRow, pDoc );
+ fNextValue = pDoc->RoundValueAsShown( fNextValue, nNumFormat );
+ }
+ }
+
+ return TRUE; // gefunden
+ }
+// break;
+ case CELLTYPE_FORMULA:
+ {
+ if (!bSubTotal || !((ScFormulaCell*)pCell)->IsSubTotal())
+ {
+ rErr = ((ScFormulaCell*)pCell)->GetErrCode();
+ if ( rErr || ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ rValue = ((ScFormulaCell*)pCell)->GetValue();
+ nRow--;
+ bNumValid = FALSE;
+ return TRUE; // gefunden
+ }
+ else if ( bTextAsZero )
+ {
+ rValue = 0.0;
+ nRow--;
+ bNumValid = FALSE;
+ return TRUE;
+ }
+ }
+ }
+ break;
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ {
+ if ( bTextAsZero )
+ {
+ rErr = 0;
+ rValue = 0.0;
+ nNumFmtType = NUMBERFORMAT_NUMBER;
+ nNumFmtIndex = 0;
+ bNumValid = TRUE;
+ --nRow;
+ return TRUE;
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ else
+ nRow = nEndRow + 1; // naechste Spalte
+ }
+}
+
+void ScValueIterator::GetCurNumFmtInfo( short& nType, ULONG& nIndex )
+{
+ if (!bNumValid)
+ {
+ const ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ nNumFmtIndex = pCol->GetNumberFormat( nRow );
+ if ( (nNumFmtIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ {
+ const ScBaseCell* pCell;
+ SCSIZE nIdx = nColRow - 1;
+ // there might be rearranged something, so be on the safe side
+ if ( nIdx < pCol->nCount && pCol->pItems[nIdx].nRow == nRow )
+ pCell = pCol->pItems[nIdx].pCell;
+ else
+ {
+ if ( pCol->Search( nRow, nIdx ) )
+ pCell = pCol->pItems[nIdx].pCell;
+ else
+ pCell = NULL;
+ }
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((const ScFormulaCell*)pCell)->GetFormatInfo( nNumFmtType, nNumFmtIndex );
+ else
+ nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
+ }
+ else
+ nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
+ bNumValid = TRUE;
+ }
+ nType = nNumFmtType;
+ nIndex = nNumFmtIndex;
+}
+
+BOOL ScValueIterator::GetFirst(double& rValue, USHORT& rErr)
+{
+ nCol = nStartCol;
+ nRow = nStartRow;
+ nTab = nStartTab;
+
+// nColRow = 0;
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ pCol->Search( nRow, nColRow );
+
+ nNumFormat = 0; // werden bei GetNumberFormat initialisiert
+ pAttrArray = 0;
+ nAttrEndRow = 0;
+
+ return GetThis(rValue, rErr);
+}
+
+/* ist inline:
+BOOL ScValueIterator::GetNext(double& rValue, USHORT& rErr)
+{
+ ++nRow;
+ return GetThis(rValue, rErr);
+}
+*/
+
+// ============================================================================
+
+ScDBQueryDataIterator::DataAccess::DataAccess(const ScDBQueryDataIterator* pParent) :
+ mpParent(pParent)
+{
+}
+
+ScDBQueryDataIterator::DataAccess::~DataAccess()
+{
+}
+
+SCROW ScDBQueryDataIterator::GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow)
+{
+ ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
+ return pCol->pItems[nColRow].nRow;
+}
+
+ScBaseCell* ScDBQueryDataIterator::GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow)
+{
+ ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
+ return pCol->pItems[nColRow].pCell;
+}
+
+ScAttrArray* ScDBQueryDataIterator::GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol)
+{
+ ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
+ return pCol->pAttrArray;
+}
+
+bool ScDBQueryDataIterator::IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell)
+{
+ return rDoc.pTab[nTab]->ValidQuery(nRow, rParam, NULL, pCell);
+}
+
+SCSIZE ScDBQueryDataIterator::SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol)
+{
+ ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
+ SCSIZE nColRow;
+ pCol->Search(nRow, nColRow);
+ return nColRow;
+}
+
+// ----------------------------------------------------------------------------
+
+ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc) :
+ DataAccess(pParent),
+ mpParam(pParam),
+ mpDoc(pDoc)
+{
+ nCol = mpParam->mnField;
+ nRow = mpParam->nRow1;
+ nTab = mpParam->nTab;
+
+ nColRow = 0; // wird bei GetFirst initialisiert
+ SCSIZE i;
+ SCSIZE nCount = mpParam->GetEntryCount();
+ for (i=0; (i<nCount) && (mpParam->GetEntry(i).bDoQuery); i++)
+ {
+ ScQueryEntry& rEntry = mpParam->GetEntry(i);
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString =
+ !(mpDoc->GetFormatTable()->IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal));
+ }
+ nNumFormat = 0; // werden bei GetNumberFormat initialisiert
+ pAttrArray = 0;
+ nAttrEndRow = 0;
+}
+
+ScDBQueryDataIterator::DataAccessInternal::~DataAccessInternal()
+{
+}
+
+bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue)
+{
+ SCCOLROW nFirstQueryField = mpParam->GetEntry(0).nField;
+ for ( ;; )
+ {
+ if (nRow > mpParam->nRow2)
+ {
+ // Bottom of the range reached. Bail out.
+ rValue.mnError = 0;
+ return false;
+ }
+
+ SCSIZE nCellCount = mpDoc->GetCellCount(nTab, nCol);
+ SCROW nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
+ while ( (nColRow < nCellCount) && (nThisRow < nRow) )
+ nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, ++nColRow);
+
+ if ( nColRow < nCellCount && nThisRow <= mpParam->nRow2 )
+ {
+ nRow = nThisRow;
+ ScBaseCell* pCell = NULL;
+ if (nCol == static_cast<SCCOL>(nFirstQueryField))
+ pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
+
+ if (ScDBQueryDataIterator::IsQueryValid(*mpDoc, *mpParam, nTab, nRow, pCell))
+ {
+ // #i109812# get cell here if it wasn't done above
+ if (nCol != static_cast<SCCOL>(nFirstQueryField))
+ pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
+
+ switch (pCell ? pCell->GetCellType() : CELLTYPE_NONE)
+ {
+ case CELLTYPE_VALUE:
+ {
+ rValue.mfValue = ((ScValueCell*)pCell)->GetValue();
+ rValue.mbIsNumber = true;
+ if ( bCalcAsShown )
+ {
+ const ScAttrArray* pNewAttrArray =
+ ScDBQueryDataIterator::GetAttrArrayByCol(*mpDoc, nTab, nCol);
+ lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
+ nAttrEndRow, pNewAttrArray, nRow, mpDoc );
+ rValue.mfValue = mpDoc->RoundValueAsShown( rValue.mfValue, nNumFormat );
+ }
+ nNumFmtType = NUMBERFORMAT_NUMBER;
+ nNumFmtIndex = 0;
+ rValue.mnError = 0;
+ return TRUE; // gefunden
+ }
+// break;
+ case CELLTYPE_FORMULA:
+ {
+ if (((ScFormulaCell*)pCell)->IsValue())
+ {
+ rValue.mfValue = ((ScFormulaCell*)pCell)->GetValue();
+ rValue.mbIsNumber = true;
+ mpDoc->GetNumberFormatInfo( nNumFmtType,
+ nNumFmtIndex, ScAddress( nCol, nRow, nTab ),
+ pCell );
+ rValue.mnError = ((ScFormulaCell*)pCell)->GetErrCode();
+ return TRUE; // gefunden
+ }
+ else
+ nRow++;
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if (mpParam->mbSkipString)
+ ++nRow;
+ else
+ {
+ rValue.maString = pCell->GetStringData();
+ rValue.mfValue = 0.0;
+ rValue.mnError = 0;
+ rValue.mbIsNumber = false;
+ return true;
+ }
+ break;
+ default:
+ nRow++;
+ break;
+ }
+ }
+ else
+ nRow++;
+ }
+ else
+ nRow = mpParam->nRow2 + 1; // Naechste Spalte
+ }
+// statement unreachable
+// return false;
+}
+
+bool ScDBQueryDataIterator::DataAccessInternal::getFirst(Value& rValue)
+{
+ if (mpParam->bHasHeader)
+ nRow++;
+
+ nColRow = ScDBQueryDataIterator::SearchColEntryIndex(*mpDoc, nTab, nRow, nCol);
+ return getCurrent(rValue);
+}
+
+bool ScDBQueryDataIterator::DataAccessInternal::getNext(Value& rValue)
+{
+ ++nRow;
+ return getCurrent(rValue);
+}
+
+// ----------------------------------------------------------------------------
+
+ScDBQueryDataIterator::DataAccessMatrix::DataAccessMatrix(const ScDBQueryDataIterator* pParent, ScDBQueryParamMatrix* pParam) :
+ DataAccess(pParent),
+ mpParam(pParam)
+{
+ SCSIZE nC, nR;
+ mpParam->mpMatrix->GetDimensions(nC, nR);
+ mnRows = static_cast<SCROW>(nR);
+ mnCols = static_cast<SCCOL>(nC);
+}
+
+ScDBQueryDataIterator::DataAccessMatrix::~DataAccessMatrix()
+{
+}
+
+bool ScDBQueryDataIterator::DataAccessMatrix::getCurrent(Value& rValue)
+{
+ // Starting from row == mnCurRow, get the first row that satisfies all the
+ // query parameters.
+ for ( ;mnCurRow < mnRows; ++mnCurRow)
+ {
+ const ScMatrix& rMat = *mpParam->mpMatrix;
+ if (rMat.IsEmpty(mpParam->mnField, mnCurRow))
+ // Don't take empty values into account.
+ continue;
+
+ bool bIsStrVal = rMat.IsString(mpParam->mnField, mnCurRow);
+ if (bIsStrVal && mpParam->mbSkipString)
+ continue;
+
+ if (isValidQuery(mnCurRow, rMat))
+ {
+ rValue.maString = rMat.GetString(mpParam->mnField, mnCurRow);
+ rValue.mfValue = rMat.GetDouble(mpParam->mnField, mnCurRow);
+ rValue.mbIsNumber = !bIsStrVal;
+ rValue.mnError = 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ScDBQueryDataIterator::DataAccessMatrix::getFirst(Value& rValue)
+{
+ mnCurRow = mpParam->bHasHeader ? 1 : 0;
+ return getCurrent(rValue);
+}
+
+bool ScDBQueryDataIterator::DataAccessMatrix::getNext(Value& rValue)
+{
+ ++mnCurRow;
+ return getCurrent(rValue);
+}
+
+namespace {
+
+bool lcl_isQueryByValue(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
+{
+ if (rEntry.bQueryByString)
+ return false;
+
+ if (!rMat.IsValueOrEmpty(nCol, nRow))
+ return false;
+
+ return true;
+}
+
+bool lcl_isQueryByString(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
+{
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL:
+ case SC_NOT_EQUAL:
+ case SC_CONTAINS:
+ case SC_DOES_NOT_CONTAIN:
+ case SC_BEGINS_WITH:
+ case SC_ENDS_WITH:
+ case SC_DOES_NOT_BEGIN_WITH:
+ case SC_DOES_NOT_END_WITH:
+ return true;
+ default:
+ ;
+ }
+
+ if (rEntry.bQueryByString && rMat.IsString(nCol, nRow))
+ return true;
+
+ return false;
+}
+
+}
+
+bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScMatrix& rMat) const
+{
+ SCSIZE nEntryCount = mpParam->GetEntryCount();
+ vector<bool> aResults;
+ aResults.reserve(nEntryCount);
+
+ const CollatorWrapper& rCollator =
+ mpParam->bCaseSens ? *ScGlobal::GetCaseCollator() : *ScGlobal::GetCollator();
+
+ for (SCSIZE i = 0; i < nEntryCount; ++i)
+ {
+ const ScQueryEntry& rEntry = mpParam->GetEntry(i);
+ if (!rEntry.bDoQuery)
+ continue;
+
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL:
+ case SC_LESS:
+ case SC_GREATER:
+ case SC_LESS_EQUAL:
+ case SC_GREATER_EQUAL:
+ case SC_NOT_EQUAL:
+ break;
+ default:
+ // Only the above operators are supported.
+ continue;
+ }
+
+ bool bValid = false;
+
+ SCSIZE nField = static_cast<SCSIZE>(rEntry.nField);
+ if (lcl_isQueryByValue(rEntry, rMat, nField, nRow))
+ {
+ // By value
+ double fMatVal = rMat.GetDouble(nField, nRow);
+ bool bEqual = approxEqual(fMatVal, rEntry.nVal);
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL:
+ bValid = bEqual;
+ break;
+ case SC_LESS:
+ bValid = (fMatVal < rEntry.nVal) && !bEqual;
+ break;
+ case SC_GREATER:
+ bValid = (fMatVal > rEntry.nVal) && !bEqual;
+ break;
+ case SC_LESS_EQUAL:
+ bValid = (fMatVal < rEntry.nVal) || bEqual;
+ break;
+ case SC_GREATER_EQUAL:
+ bValid = (fMatVal > rEntry.nVal) || bEqual;
+ break;
+ case SC_NOT_EQUAL:
+ bValid = !bEqual;
+ break;
+ default:
+ ;
+ }
+ }
+ else if (lcl_isQueryByString(rEntry, rMat, nField, nRow))
+ {
+ // By string
+ do
+ {
+ if (!rEntry.pStr)
+ break;
+
+ // Equality check first.
+
+ OUString aMatStr = rMat.GetString(nField, nRow);
+ lcl_toUpper(aMatStr);
+ OUString aQueryStr = *rEntry.pStr;
+ lcl_toUpper(aQueryStr);
+ bool bDone = false;
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL:
+ bValid = aMatStr.equals(aQueryStr);
+ bDone = true;
+ break;
+ case SC_NOT_EQUAL:
+ bValid = !aMatStr.equals(aQueryStr);
+ bDone = true;
+ break;
+ default:
+ ;
+ }
+
+ if (bDone)
+ break;
+
+ // Unequality check using collator.
+
+ sal_Int32 nCompare = rCollator.compareString(aMatStr, aQueryStr);
+ switch (rEntry.eOp)
+ {
+ case SC_LESS :
+ bValid = (nCompare < 0);
+ break;
+ case SC_GREATER :
+ bValid = (nCompare > 0);
+ break;
+ case SC_LESS_EQUAL :
+ bValid = (nCompare <= 0);
+ break;
+ case SC_GREATER_EQUAL :
+ bValid = (nCompare >= 0);
+ break;
+ default:
+ ;
+ }
+ }
+ while (false);
+ }
+ else if (mpParam->bMixedComparison)
+ {
+ // Not used at the moment.
+ }
+
+ if (aResults.empty())
+ // First query entry.
+ aResults.push_back(bValid);
+ else if (rEntry.eConnect == SC_AND)
+ {
+ // For AND op, tuck the result into the last result value.
+ size_t n = aResults.size();
+ aResults[n-1] = aResults[n-1] && bValid;
+ }
+ else
+ // For OR op, store its own result.
+ aResults.push_back(bValid);
+ }
+
+ // Row is valid as long as there is at least one result being true.
+ vector<bool>::const_iterator itr = aResults.begin(), itrEnd = aResults.end();
+ for (; itr != itrEnd; ++itr)
+ if (*itr)
+ return true;
+
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+ScDBQueryDataIterator::Value::Value() :
+ mnError(0), mbIsNumber(true)
+{
+ ::rtl::math::setNan(&mfValue);
+}
+
+// ----------------------------------------------------------------------------
+
+ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam) :
+ mpParam (pParam)
+{
+ switch (mpParam->GetType())
+ {
+ case ScDBQueryParamBase::INTERNAL:
+ {
+ ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pParam);
+ mpData.reset(new DataAccessInternal(this, p, pDocument));
+ }
+ break;
+ case ScDBQueryParamBase::MATRIX:
+ {
+ ScDBQueryParamMatrix* p = static_cast<ScDBQueryParamMatrix*>(pParam);
+ mpData.reset(new DataAccessMatrix(this, p));
+ }
+ }
+}
+
+bool ScDBQueryDataIterator::GetFirst(Value& rValue)
+{
+ return mpData->getFirst(rValue);
+}
+
+bool ScDBQueryDataIterator::GetNext(Value& rValue)
+{
+ return mpData->getNext(rValue);
+}
+
+// ============================================================================
+
+ScCellIterator::ScCellIterator( ScDocument* pDocument,
+ SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
+ SCCOL nECol, SCROW nERow, SCTAB nETab, BOOL bSTotal ) :
+ pDoc( pDocument ),
+ nStartCol( nSCol),
+ nStartRow( nSRow),
+ nStartTab( nSTab ),
+ nEndCol( nECol ),
+ nEndRow( nERow),
+ nEndTab( nETab ),
+ bSubTotal(bSTotal)
+
+{
+ PutInOrder( nStartCol, nEndCol);
+ PutInOrder( nStartRow, nEndRow);
+ PutInOrder( nStartTab, nEndTab );
+
+ if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+ if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+ if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+ if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+ if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
+ if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
+
+ while (nEndTab>0 && !pDoc->pTab[nEndTab])
+ --nEndTab; // nur benutzte Tabellen
+ if (nStartTab>nEndTab)
+ nStartTab = nEndTab;
+
+ nCol = nStartCol;
+ nRow = nStartRow;
+ nTab = nStartTab;
+ nColRow = 0; // wird bei GetFirst initialisiert
+
+ if (!pDoc->pTab[nTab])
+ {
+ DBG_ERROR("Tabelle nicht gefunden");
+ nStartCol = nCol = MAXCOL+1;
+ nStartRow = nRow = MAXROW+1;
+ nStartTab = nTab = MAXTAB+1; // -> Abbruch bei GetFirst
+ }
+}
+
+ScCellIterator::ScCellIterator
+ ( ScDocument* pDocument, const ScRange& rRange, BOOL bSTotal ) :
+ pDoc( pDocument ),
+ nStartCol( rRange.aStart.Col() ),
+ nStartRow( rRange.aStart.Row() ),
+ nStartTab( rRange.aStart.Tab() ),
+ nEndCol( rRange.aEnd.Col() ),
+ nEndRow( rRange.aEnd.Row() ),
+ nEndTab( rRange.aEnd.Tab() ),
+ bSubTotal(bSTotal)
+
+{
+ PutInOrder( nStartCol, nEndCol);
+ PutInOrder( nStartRow, nEndRow);
+ PutInOrder( nStartTab, nEndTab );
+
+ if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+ if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+ if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+ if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+ if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
+ if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
+
+ while (nEndTab>0 && !pDoc->pTab[nEndTab])
+ --nEndTab; // nur benutzte Tabellen
+ if (nStartTab>nEndTab)
+ nStartTab = nEndTab;
+
+ nCol = nStartCol;
+ nRow = nStartRow;
+ nTab = nStartTab;
+ nColRow = 0; // wird bei GetFirst initialisiert
+
+ if (!pDoc->pTab[nTab])
+ {
+ DBG_ERROR("Tabelle nicht gefunden");
+ nStartCol = nCol = MAXCOL+1;
+ nStartRow = nRow = MAXROW+1;
+ nStartTab = nTab = MAXTAB+1; // -> Abbruch bei GetFirst
+ }
+}
+
+ScBaseCell* ScCellIterator::GetThis()
+{
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ for ( ;; )
+ {
+ if ( nRow > nEndRow )
+ {
+ nRow = nStartRow;
+ do
+ {
+ nCol++;
+ if ( nCol > nEndCol )
+ {
+ nCol = nStartCol;
+ nTab++;
+ if ( nTab > nEndTab )
+ return NULL; // Ende und Aus
+ }
+ pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ } while ( pCol->nCount == 0 );
+ pCol->Search( nRow, nColRow );
+ }
+
+ while ( (nColRow < pCol->nCount) && (pCol->pItems[nColRow].nRow < nRow) )
+ nColRow++;
+
+ if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
+ {
+ nRow = pCol->pItems[nColRow].nRow;
+ if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow ) )
+ {
+ ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
+
+ if ( bSubTotal && pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->IsSubTotal() )
+ nRow++; // Sub-Total-Zeilen nicht
+ else
+ return pCell; // gefunden
+ }
+ else
+ nRow++;
+ }
+ else
+ nRow = nEndRow + 1; // Naechste Spalte
+ }
+}
+
+ScBaseCell* ScCellIterator::GetFirst()
+{
+ if ( !ValidTab(nTab) )
+ return NULL;
+ nCol = nStartCol;
+ nRow = nStartRow;
+ nTab = nStartTab;
+// nColRow = 0;
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ pCol->Search( nRow, nColRow );
+ return GetThis();
+}
+
+ScBaseCell* ScCellIterator::GetNext()
+{
+ ++nRow;
+ return GetThis();
+}
+
+//-------------------------------------------------------------------------------
+
+ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
+ const ScQueryParam& rParam, BOOL bMod ) :
+ aParam (rParam),
+ pDoc( pDocument ),
+ nTab( nTable),
+ nStopOnMismatch( nStopOnMismatchDisabled ),
+ nTestEqualCondition( nTestEqualConditionDisabled ),
+ bAdvanceQuery( FALSE ),
+ bIgnoreMismatchOnLeadingStrings( FALSE )
+{
+ nCol = aParam.nCol1;
+ nRow = aParam.nRow1;
+ nColRow = 0; // wird bei GetFirst initialisiert
+ SCSIZE i;
+ if (bMod) // sonst schon eingetragen
+ {
+ for (i=0; (i<MAXQUERY) && (aParam.GetEntry(i).bDoQuery); i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString =
+ !(pDoc->GetFormatTable()->IsNumberFormat(*rEntry.pStr,
+ nIndex, rEntry.nVal));
+ }
+ }
+ nNumFormat = 0; // werden bei GetNumberFormat initialisiert
+ pAttrArray = 0;
+ nAttrEndRow = 0;
+}
+
+ScBaseCell* ScQueryCellIterator::GetThis()
+{
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ const ScQueryEntry& rEntry = aParam.GetEntry(0);
+ SCCOLROW nFirstQueryField = rEntry.nField;
+ bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings &&
+ !rEntry.bQueryByString;
+ bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
+ !aParam.bHasHeader && rEntry.bQueryByString &&
+ ((aParam.bByRow && nRow == aParam.nRow1) ||
+ (!aParam.bByRow && nCol == aParam.nCol1));
+ for ( ;; )
+ {
+ if ( nRow > aParam.nRow2 )
+ {
+ nRow = aParam.nRow1;
+ if (aParam.bHasHeader && aParam.bByRow)
+ nRow++;
+ do
+ {
+ if ( ++nCol > aParam.nCol2 )
+ return NULL; // Ende und Aus
+ if ( bAdvanceQuery )
+ {
+ AdvanceQueryParamEntryField();
+ nFirstQueryField = rEntry.nField;
+ }
+ pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ } while ( pCol->nCount == 0 );
+ pCol->Search( nRow, nColRow );
+ bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
+ !aParam.bHasHeader && rEntry.bQueryByString &&
+ aParam.bByRow;
+ }
+
+ while ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow < nRow )
+ nColRow++;
+
+ if ( nColRow < pCol->nCount &&
+ (nRow = pCol->pItems[nColRow].nRow) <= aParam.nRow2 )
+ {
+ ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_NOTE )
+ ++nRow;
+ else if (bAllStringIgnore && pCell->HasStringData())
+ ++nRow;
+ else
+ {
+ BOOL bTestEqualCondition;
+ if ( (pDoc->pTab[nTab])->ValidQuery( nRow, aParam, NULL,
+ (nCol == static_cast<SCCOL>(nFirstQueryField) ? pCell : NULL),
+ (nTestEqualCondition ? &bTestEqualCondition : NULL) ) )
+ {
+ if ( nTestEqualCondition && bTestEqualCondition )
+ nTestEqualCondition |= nTestEqualConditionMatched;
+ return pCell; // found
+ }
+ else if ( nStopOnMismatch )
+ {
+ // Yes, even a mismatch may have a fulfilled equal
+ // condition if regular expressions were involved and
+ // SC_LESS_EQUAL or SC_GREATER_EQUAL were queried.
+ if ( nTestEqualCondition && bTestEqualCondition )
+ {
+ nTestEqualCondition |= nTestEqualConditionMatched;
+ nStopOnMismatch |= nStopOnMismatchOccured;
+ return NULL;
+ }
+ bool bStop;
+ if (bFirstStringIgnore)
+ {
+ if (pCell->HasStringData())
+ {
+ ++nRow;
+ bStop = false;
+ }
+ else
+ bStop = true;
+ }
+ else
+ bStop = true;
+ if (bStop)
+ {
+ nStopOnMismatch |= nStopOnMismatchOccured;
+ return NULL;
+ }
+ }
+ else
+ nRow++;
+ }
+ }
+ else
+ nRow = aParam.nRow2 + 1; // Naechste Spalte
+ bFirstStringIgnore = false;
+ }
+}
+
+ScBaseCell* ScQueryCellIterator::GetFirst()
+{
+ nCol = aParam.nCol1;
+ nRow = aParam.nRow1;
+ if (aParam.bHasHeader)
+ nRow++;
+// nColRow = 0;
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ pCol->Search( nRow, nColRow );
+ return GetThis();
+}
+
+ScBaseCell* ScQueryCellIterator::GetNext()
+{
+ ++nRow;
+ if ( nStopOnMismatch )
+ nStopOnMismatch = nStopOnMismatchEnabled;
+ if ( nTestEqualCondition )
+ nTestEqualCondition = nTestEqualConditionEnabled;
+ return GetThis();
+}
+
+void ScQueryCellIterator::AdvanceQueryParamEntryField()
+{
+ SCSIZE nEntries = aParam.GetEntryCount();
+ for ( SCSIZE j = 0; j < nEntries; j++ )
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry( j );
+ if ( rEntry.bDoQuery )
+ {
+ if ( rEntry.nField < MAXCOL )
+ rEntry.nField++;
+ else
+ {
+ DBG_ERRORFILE( "AdvanceQueryParamEntryField: ++rEntry.nField > MAXCOL" );
+ }
+ }
+ else
+ break; // for
+ }
+}
+
+
+BOOL ScQueryCellIterator::FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
+ SCROW& nFoundRow, BOOL bSearchForEqualAfterMismatch,
+ BOOL bIgnoreMismatchOnLeadingStringsP )
+{
+ nFoundCol = MAXCOL+1;
+ nFoundRow = MAXROW+1;
+ SetStopOnMismatch( TRUE ); // assume sorted keys
+ SetTestEqualCondition( TRUE );
+ bIgnoreMismatchOnLeadingStrings = bIgnoreMismatchOnLeadingStringsP;
+ bool bRegExp = aParam.bRegExp && aParam.GetEntry(0).bQueryByString;
+ bool bBinary = !bRegExp && aParam.bByRow && (aParam.GetEntry(0).eOp ==
+ SC_LESS_EQUAL || aParam.GetEntry(0).eOp == SC_GREATER_EQUAL);
+ if (bBinary ? (BinarySearch() ? GetThis() : 0) : GetFirst())
+ {
+ // First equal entry or last smaller than (greater than) entry.
+ SCSIZE nColRowSave;
+ ScBaseCell* pNext = 0;
+ do
+ {
+ nFoundCol = GetCol();
+ nFoundRow = GetRow();
+ nColRowSave = nColRow;
+ } while ( !IsEqualConditionFulfilled() && (pNext = GetNext()) != NULL );
+ // There may be no pNext but equal condition fulfilled if regular
+ // expressions are involved. Keep the found entry and proceed.
+ if (!pNext && !IsEqualConditionFulfilled())
+ {
+ // Step back to last in range and adjust position markers for
+ // GetNumberFormat() or similar.
+ nCol = nFoundCol;
+ nRow = nFoundRow;
+ nColRow = nColRowSave;
+ }
+ }
+ if ( IsEqualConditionFulfilled() )
+ {
+ // Position on last equal entry.
+ SCSIZE nEntries = aParam.GetEntryCount();
+ for ( SCSIZE j = 0; j < nEntries; j++ )
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry( j );
+ if ( rEntry.bDoQuery )
+ {
+ switch ( rEntry.eOp )
+ {
+ case SC_LESS_EQUAL :
+ case SC_GREATER_EQUAL :
+ rEntry.eOp = SC_EQUAL;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ break; // for
+ }
+ SCSIZE nColRowSave;
+ bIgnoreMismatchOnLeadingStrings = FALSE;
+ SetTestEqualCondition( FALSE );
+ do
+ {
+ nFoundCol = GetCol();
+ nFoundRow = GetRow();
+ nColRowSave = nColRow;
+ } while (GetNext());
+ // Step back conditions same as above
+ nCol = nFoundCol;
+ nRow = nFoundRow;
+ nColRow = nColRowSave;
+ return TRUE;
+ }
+ if ( (bSearchForEqualAfterMismatch || aParam.bRegExp) &&
+ StoppedOnMismatch() )
+ {
+ // Assume found entry to be the last value less than respectively
+ // greater than the query. But keep on searching for an equal match.
+ SCSIZE nEntries = aParam.GetEntryCount();
+ for ( SCSIZE j = 0; j < nEntries; j++ )
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry( j );
+ if ( rEntry.bDoQuery )
+ {
+ switch ( rEntry.eOp )
+ {
+ case SC_LESS_EQUAL :
+ case SC_GREATER_EQUAL :
+ rEntry.eOp = SC_EQUAL;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ break; // for
+ }
+ SetStopOnMismatch( FALSE );
+ SetTestEqualCondition( FALSE );
+ if (GetNext())
+ {
+ // Last of a consecutive area, avoid searching the entire parameter
+ // range as it is a real performance bottleneck in case of regular
+ // expressions.
+ SCSIZE nColRowSave;
+ do
+ {
+ nFoundCol = GetCol();
+ nFoundRow = GetRow();
+ nColRowSave = nColRow;
+ SetStopOnMismatch( TRUE );
+ } while (GetNext());
+ nCol = nFoundCol;
+ nRow = nFoundRow;
+ nColRow = nColRowSave;
+ }
+ }
+ return (nFoundCol <= MAXCOL) && (nFoundRow <= MAXROW);
+}
+
+
+ScBaseCell* ScQueryCellIterator::BinarySearch()
+{
+ nCol = aParam.nCol1;
+ ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
+ if (!pCol->nCount)
+ return 0;
+
+ ScBaseCell* pCell;
+ SCSIZE nHi, nLo;
+ CollatorWrapper* pCollator = (aParam.bCaseSens ? ScGlobal::GetCaseCollator() :
+ ScGlobal::GetCollator());
+ SvNumberFormatter& rFormatter = *(pDoc->GetFormatTable());
+ const ScQueryEntry& rEntry = aParam.GetEntry(0);
+ bool bLessEqual = rEntry.eOp == SC_LESS_EQUAL;
+ bool bByString = rEntry.bQueryByString;
+ bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings && !bByString;
+ bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
+ !aParam.bHasHeader && bByString;
+
+ nRow = aParam.nRow1;
+ if (aParam.bHasHeader)
+ nRow++;
+ const ColEntry* pItems = pCol->pItems;
+ if (pCol->Search( nRow, nLo ) && bFirstStringIgnore &&
+ pItems[nLo].pCell->HasStringData())
+ {
+ String aCellStr;
+ ULONG nFormat = pCol->GetNumberFormat( pItems[nLo].nRow);
+ ScCellFormat::GetInputString( pItems[nLo].pCell, nFormat, aCellStr,
+ rFormatter);
+ sal_Int32 nTmp = pCollator->compareString( aCellStr, *rEntry.pStr);
+ if ((rEntry.eOp == SC_LESS_EQUAL && nTmp > 0) ||
+ (rEntry.eOp == SC_GREATER_EQUAL && nTmp < 0) ||
+ (rEntry.eOp == SC_EQUAL && nTmp != 0))
+ ++nLo;
+ }
+ if (!pCol->Search( aParam.nRow2, nHi ) && nHi>0)
+ --nHi;
+ while (bAllStringIgnore && nLo <= nHi && nLo < pCol->nCount &&
+ pItems[nLo].pCell->HasStringData())
+ ++nLo;
+
+ // Bookkeeping values for breaking up the binary search in case the data
+ // range isn't strictly sorted.
+ SCSIZE nLastInRange = nLo;
+ SCSIZE nFirstLastInRange = nLastInRange;
+ double fLastInRangeValue = bLessEqual ?
+ -(::std::numeric_limits<double>::max()) :
+ ::std::numeric_limits<double>::max();
+ String aLastInRangeString;
+ if (!bLessEqual)
+ aLastInRangeString.Assign( sal_Unicode(0xFFFF));
+ if (nLastInRange < pCol->nCount)
+ {
+ pCell = pItems[nLastInRange].pCell;
+ if (pCell->HasStringData())
+ {
+ ULONG nFormat = pCol->GetNumberFormat( pItems[nLastInRange].nRow);
+ ScCellFormat::GetInputString( pCell, nFormat, aLastInRangeString,
+ rFormatter);
+ }
+ else
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ fLastInRangeValue =
+ static_cast<ScValueCell*>(pCell)->GetValue();
+ break;
+ case CELLTYPE_FORMULA :
+ fLastInRangeValue =
+ static_cast<ScFormulaCell*>(pCell)->GetValue();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+
+ sal_Int32 nRes = 0;
+ bool bFound = false;
+ bool bDone = false;
+ while (nLo <= nHi && !bDone)
+ {
+ SCSIZE nMid = (nLo+nHi)/2;
+ SCSIZE i = nMid;
+ while (i <= nHi && pItems[i].pCell->GetCellType() == CELLTYPE_NOTE)
+ ++i;
+ if (i > nHi)
+ {
+ if (nMid > 0)
+ nHi = nMid - 1;
+ else
+ bDone = true;
+ continue; // while
+ }
+ BOOL bStr = pItems[i].pCell->HasStringData();
+ nRes = 0;
+ // compares are content<query:-1, content>query:1
+ // Cell value comparison similar to ScTable::ValidQuery()
+ if (!bStr && !bByString)
+ {
+ double nCellVal;
+ pCell = pItems[i].pCell;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ nCellVal = static_cast<ScValueCell*>(pCell)->GetValue();
+ break;
+ case CELLTYPE_FORMULA :
+ nCellVal = static_cast<ScFormulaCell*>(pCell)->GetValue();
+ break;
+ default:
+ nCellVal = 0.0;
+ }
+ if ((nCellVal < rEntry.nVal) && !::rtl::math::approxEqual(
+ nCellVal, rEntry.nVal))
+ {
+ nRes = -1;
+ if (bLessEqual)
+ {
+ if (fLastInRangeValue < nCellVal)
+ {
+ fLastInRangeValue = nCellVal;
+ nLastInRange = i;
+ }
+ else if (fLastInRangeValue > nCellVal)
+ {
+ // not strictly sorted, continue with GetThis()
+ nLastInRange = nFirstLastInRange;
+ bDone = true;
+ }
+ }
+ }
+ else if ((nCellVal > rEntry.nVal) && !::rtl::math::approxEqual(
+ nCellVal, rEntry.nVal))
+ {
+ nRes = 1;
+ if (!bLessEqual)
+ {
+ if (fLastInRangeValue > nCellVal)
+ {
+ fLastInRangeValue = nCellVal;
+ nLastInRange = i;
+ }
+ else if (fLastInRangeValue < nCellVal)
+ {
+ // not strictly sorted, continue with GetThis()
+ nLastInRange = nFirstLastInRange;
+ bDone = true;
+ }
+ }
+ }
+ }
+ else if (bStr && bByString)
+ {
+ String aCellStr;
+ ULONG nFormat = pCol->GetNumberFormat( pItems[i].nRow);
+ ScCellFormat::GetInputString( pItems[i].pCell, nFormat, aCellStr,
+ rFormatter);
+ nRes = pCollator->compareString( aCellStr, *rEntry.pStr);
+ if (nRes < 0 && bLessEqual)
+ {
+ sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
+ aCellStr);
+ if (nTmp < 0)
+ {
+ aLastInRangeString = aCellStr;
+ nLastInRange = i;
+ }
+ else if (nTmp > 0)
+ {
+ // not strictly sorted, continue with GetThis()
+ nLastInRange = nFirstLastInRange;
+ bDone = true;
+ }
+ }
+ else if (nRes > 0 && !bLessEqual)
+ {
+ sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
+ aCellStr);
+ if (nTmp > 0)
+ {
+ aLastInRangeString = aCellStr;
+ nLastInRange = i;
+ }
+ else if (nTmp < 0)
+ {
+ // not strictly sorted, continue with GetThis()
+ nLastInRange = nFirstLastInRange;
+ bDone = true;
+ }
+ }
+ }
+ else if (!bStr && bByString)
+ {
+ nRes = -1; // numeric < string
+ if (bLessEqual)
+ nLastInRange = i;
+ }
+ else // if (bStr && !bByString)
+ {
+ nRes = 1; // string > numeric
+ if (!bLessEqual)
+ nLastInRange = i;
+ }
+ if (nRes < 0)
+ {
+ if (bLessEqual)
+ nLo = nMid + 1;
+ else // assumed to be SC_GREATER_EQUAL
+ {
+ if (nMid > 0)
+ nHi = nMid - 1;
+ else
+ bDone = true;
+ }
+ }
+ else if (nRes > 0)
+ {
+ if (bLessEqual)
+ {
+ if (nMid > 0)
+ nHi = nMid - 1;
+ else
+ bDone = true;
+ }
+ else // assumed to be SC_GREATER_EQUAL
+ nLo = nMid + 1;
+ }
+ else
+ {
+ nLo = i;
+ bDone = bFound = true;
+ }
+ }
+ if (!bFound)
+ {
+ // If all hits didn't result in a moving limit there's something
+ // strange, e.g. data range not properly sorted, or only identical
+ // values encountered, which doesn't mean there aren't any others in
+ // between.. leave it to GetThis(). The condition for this would be
+ // if (nLastInRange == nFirstLastInRange) nLo = nFirstLastInRange;
+ // Else, in case no exact match was found, we step back for a
+ // subsequent GetThis() to find the last in range. Effectively this is
+ // --nLo with nLastInRange == nLo-1. Both conditions combined yield:
+ nLo = nLastInRange;
+ }
+ if (nLo < pCol->nCount && pCol->pItems[nLo].nRow <= aParam.nRow2)
+ {
+ nRow = pItems[nLo].nRow;
+ pCell = pItems[nLo].pCell;
+ nColRow = nLo;
+ }
+ else
+ {
+ nRow = aParam.nRow2 + 1;
+ pCell = 0;
+ nColRow = pCol->nCount - 1;
+ }
+ return pCell;
+}
+
+
+//-------------------------------------------------------------------------------
+
+ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
+ pDoc( pDocument ),
+ nTab( nTable ),
+ nStartCol( nCol1 ),
+ nEndCol( nCol2 ),
+ nEndRow( nRow2 ),
+ nCol( nCol1 ),
+ nRow( nRow1 ),
+ bMore( TRUE )
+{
+ SCCOL i;
+ SCSIZE nIndex;
+
+ pNextRows = new SCROW[ nCol2-nCol1+1 ];
+ pNextIndices = new SCSIZE[ nCol2-nCol1+1 ];
+
+ for (i=nStartCol; i<=nEndCol; i++)
+ {
+ ScColumn* pCol = &pDoc->pTab[nTab]->aCol[i];
+
+ pCol->Search( nRow1, nIndex );
+ if ( nIndex < pCol->nCount )
+ {
+ pNextRows[i-nStartCol] = pCol->pItems[nIndex].nRow;
+ pNextIndices[i-nStartCol] = nIndex;
+ }
+ else
+ {
+ pNextRows[i-nStartCol] = MAXROWCOUNT; // nichts gefunden
+ pNextIndices[i-nStartCol] = MAXROWCOUNT;
+ }
+ }
+
+ if (pNextRows[0] != nRow1)
+ Advance();
+}
+
+ScHorizontalCellIterator::~ScHorizontalCellIterator()
+{
+ delete [] pNextRows;
+ delete [] pNextIndices;
+}
+
+ScBaseCell* ScHorizontalCellIterator::GetNext( SCCOL& rCol, SCROW& rRow )
+{
+ if ( bMore )
+ {
+ rCol = nCol;
+ rRow = nRow;
+
+ ScColumn* pCol = &pDoc->pTab[nTab]->aCol[nCol];
+ SCSIZE nIndex = pNextIndices[nCol-nStartCol];
+ DBG_ASSERT( nIndex < pCol->nCount, "ScHorizontalCellIterator::GetNext: nIndex out of range" );
+ ScBaseCell* pCell = pCol->pItems[nIndex].pCell;
+ if ( ++nIndex < pCol->nCount )
+ {
+ pNextRows[nCol-nStartCol] = pCol->pItems[nIndex].nRow;
+ pNextIndices[nCol-nStartCol] = nIndex;
+ }
+ else
+ {
+ pNextRows[nCol-nStartCol] = MAXROWCOUNT; // nichts gefunden
+ pNextIndices[nCol-nStartCol] = MAXROWCOUNT;
+ }
+
+ Advance();
+ return pCell;
+ }
+ else
+ return NULL;
+}
+
+BOOL ScHorizontalCellIterator::ReturnNext( SCCOL& rCol, SCROW& rRow )
+{
+ rCol = nCol;
+ rRow = nRow;
+ return bMore;
+}
+
+void ScHorizontalCellIterator::Advance()
+{
+ BOOL bFound = FALSE;
+ SCCOL i;
+
+ for (i=nCol+1; i<=nEndCol && !bFound; i++)
+ if (pNextRows[i-nStartCol] == nRow)
+ {
+ nCol = i;
+ bFound = TRUE;
+ }
+
+ if (!bFound)
+ {
+ SCROW nMinRow = MAXROW+1;
+ for (i=nStartCol; i<=nEndCol; i++)
+ if (pNextRows[i-nStartCol] < nMinRow)
+ {
+ nCol = i;
+ nMinRow = pNextRows[i-nStartCol];
+ }
+
+ if (nMinRow <= nEndRow)
+ {
+ nRow = nMinRow;
+ bFound = TRUE;
+ }
+ }
+
+ if ( !bFound )
+ bMore = FALSE;
+}
+
+//-------------------------------------------------------------------------------
+
+ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
+ pDoc( pDocument ),
+ nTab( nTable ),
+ nStartCol( nCol1 ),
+ nStartRow( nRow1 ),
+ nEndCol( nCol2 ),
+ nEndRow( nRow2 )
+{
+ DBG_ASSERT( pDoc->pTab[nTab], "Tabelle nicht da" );
+
+ SCCOL i;
+
+ nRow = nStartRow;
+ nCol = nStartCol;
+ bRowEmpty = FALSE;
+
+ pIndices = new SCSIZE[nEndCol-nStartCol+1];
+ pNextEnd = new SCROW[nEndCol-nStartCol+1];
+ ppPatterns = new const ScPatternAttr*[nEndCol-nStartCol+1];
+
+ SCROW nSkipTo = MAXROW;
+ BOOL bEmpty = TRUE;
+ for (i=nStartCol; i<=nEndCol; i++)
+ {
+ SCCOL nPos = i - nStartCol;
+ ScAttrArray* pArray = pDoc->pTab[nTab]->aCol[i].pAttrArray;
+ DBG_ASSERT( pArray, "pArray == 0" );
+
+ SCSIZE nIndex;
+ pArray->Search( nStartRow, nIndex );
+
+ const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
+ SCROW nThisEnd = pArray->pData[nIndex].nRow;
+ if ( IsDefaultItem( pPattern ) )
+ {
+ pPattern = NULL;
+ if ( nThisEnd < nSkipTo )
+ nSkipTo = nThisEnd; // nSkipTo kann gleich hier gesetzt werden
+ }
+ else
+ bEmpty = FALSE; // Attribute gefunden
+
+ pIndices[nPos] = nIndex;
+ pNextEnd[nPos] = nThisEnd;
+ ppPatterns[nPos] = pPattern;
+ }
+
+ if (bEmpty)
+ nRow = nSkipTo; // bis zum naechsten Bereichsende ueberspringen
+ bRowEmpty = bEmpty;
+}
+
+ScHorizontalAttrIterator::~ScHorizontalAttrIterator()
+{
+ delete[] (ScPatternAttr**)ppPatterns;
+ delete[] pNextEnd;
+ delete[] pIndices;
+}
+
+const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow )
+{
+ for (;;)
+ {
+ if (!bRowEmpty)
+ {
+ // in dieser Zeile suchen
+
+ while ( nCol <= nEndCol && !ppPatterns[nCol-nStartCol] )
+ ++nCol;
+
+ if ( nCol <= nEndCol )
+ {
+ const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
+ rRow = nRow;
+ rCol1 = nCol;
+ while ( nCol < nEndCol && ppPatterns[nCol+1-nStartCol] == pPat )
+ ++nCol;
+ rCol2 = nCol;
+ ++nCol; // hochzaehlen fuer naechsten Aufruf
+ return pPat; // gefunden
+ }
+ }
+
+ // naechste Zeile
+
+ ++nRow;
+ if ( nRow > nEndRow ) // schon am Ende?
+ return NULL; // nichts gefunden
+
+ BOOL bEmpty = TRUE;
+ SCCOL i;
+
+ for ( i = nStartCol; i <= nEndCol; i++)
+ {
+ SCCOL nPos = i-nStartCol;
+ if ( pNextEnd[nPos] < nRow )
+ {
+ ScAttrArray* pArray = pDoc->pTab[nTab]->aCol[i].pAttrArray;
+
+ SCSIZE nIndex = ++pIndices[nPos];
+ if ( nIndex < pArray->nCount )
+ {
+ const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
+ SCROW nThisEnd = pArray->pData[nIndex].nRow;
+ if ( IsDefaultItem( pPattern ) )
+ pPattern = NULL;
+ else
+ bEmpty = FALSE; // Attribute gefunden
+
+ pNextEnd[nPos] = nThisEnd;
+ ppPatterns[nPos] = pPattern;
+
+ DBG_ASSERT( pNextEnd[nPos] >= nRow, "Reihenfolge durcheinander" );
+ }
+ else
+ {
+ DBG_ERROR("AttrArray reicht nicht bis MAXROW");
+ pNextEnd[nPos] = MAXROW;
+ ppPatterns[nPos] = NULL;
+ }
+ }
+ else if ( ppPatterns[nPos] )
+ bEmpty = FALSE; // Bereich noch nicht zuende
+ }
+
+ if (bEmpty)
+ {
+ SCCOL nCount = nEndCol-nStartCol+1;
+ SCROW nSkipTo = pNextEnd[0]; // naechstes Bereichsende suchen
+ for (i=1; i<nCount; i++)
+ if ( pNextEnd[i] < nSkipTo )
+ nSkipTo = pNextEnd[i];
+ nRow = nSkipTo; // leere Zeilen ueberspringen
+ }
+ bRowEmpty = bEmpty;
+ nCol = nStartCol; // wieder links anfangen
+ }
+
+// return NULL;
+}
+
+//-------------------------------------------------------------------------------
+
+inline BOOL IsGreater( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ return ( nRow1 > nRow2 ) || ( nRow1 == nRow2 && nCol1 > nCol2 );
+}
+
+ScUsedAreaIterator::ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
+ aCellIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
+ aAttrIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
+ nNextCol( nCol1 ),
+ nNextRow( nRow1 )
+{
+ pCell = aCellIter.GetNext( nCellCol, nCellRow );
+ pPattern = aAttrIter.GetNext( nAttrCol1, nAttrCol2, nAttrRow );
+}
+
+ScUsedAreaIterator::~ScUsedAreaIterator()
+{
+}
+
+BOOL ScUsedAreaIterator::GetNext()
+{
+ // Iteratoren weiterzaehlen
+
+ if ( pCell && IsGreater( nNextCol, nNextRow, nCellCol, nCellRow ) )
+ pCell = aCellIter.GetNext( nCellCol, nCellRow );
+
+ while ( pCell && pCell->IsBlank() )
+ pCell = aCellIter.GetNext( nCellCol, nCellRow );
+
+ if ( pPattern && IsGreater( nNextCol, nNextRow, nAttrCol2, nAttrRow ) )
+ pPattern = aAttrIter.GetNext( nAttrCol1, nAttrCol2, nAttrRow );
+
+ if ( pPattern && nAttrRow == nNextRow && nAttrCol1 < nNextCol )
+ nAttrCol1 = nNextCol;
+
+ // naechsten Abschnitt heraussuchen
+
+ BOOL bFound = TRUE;
+ BOOL bUseCell = FALSE;
+
+ if ( pCell && pPattern )
+ {
+ if ( IsGreater( nCellCol, nCellRow, nAttrCol1, nAttrRow ) ) // vorne nur Attribute ?
+ {
+ pFoundCell = NULL;
+ pFoundPattern = pPattern;
+ nFoundRow = nAttrRow;
+ nFoundStartCol = nAttrCol1;
+ if ( nCellRow == nAttrRow && nCellCol <= nAttrCol2 ) // auch Zelle im Bereich ?
+ nFoundEndCol = nCellCol - 1; // nur bis vor der Zelle
+ else
+ nFoundEndCol = nAttrCol2; // alles
+ }
+ else
+ {
+ bUseCell = TRUE;
+ if ( nAttrRow == nCellRow && nAttrCol1 == nCellCol ) // Attribute auf der Zelle ?
+ pFoundPattern = pPattern;
+ else
+ pFoundPattern = NULL;
+ }
+ }
+ else if ( pCell ) // nur Zelle -> direkt uebernehmen
+ {
+ pFoundPattern = NULL;
+ bUseCell = TRUE; // Position von Zelle
+ }
+ else if ( pPattern ) // nur Attribute -> direkt uebernehmen
+ {
+ pFoundCell = NULL;
+ pFoundPattern = pPattern;
+ nFoundRow = nAttrRow;
+ nFoundStartCol = nAttrCol1;
+ nFoundEndCol = nAttrCol2;
+ }
+ else // gar nichts
+ bFound = FALSE;
+
+ if ( bUseCell ) // Position von Zelle
+ {
+ pFoundCell = pCell;
+ nFoundRow = nCellRow;
+ nFoundStartCol = nFoundEndCol = nCellCol;
+ }
+
+ if (bFound)
+ {
+ nNextRow = nFoundRow;
+ nNextCol = nFoundEndCol + 1;
+ }
+
+ return bFound;
+}
+
+//-------------------------------------------------------------------------------
+
+ScDocAttrIterator::ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
+ SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2) :
+ pDoc( pDocument ),
+ nTab( nTable ),
+ nEndCol( nCol2 ),
+ nStartRow( nRow1 ),
+ nEndRow( nRow2 ),
+ nCol( nCol1 )
+{
+ if ( ValidTab(nTab) && pDoc->pTab[nTab] )
+ pColIter = pDoc->pTab[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
+ else
+ pColIter = NULL;
+}
+
+ScDocAttrIterator::~ScDocAttrIterator()
+{
+ delete pColIter;
+}
+
+const ScPatternAttr* ScDocAttrIterator::GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 )
+{
+ while ( pColIter )
+ {
+ const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
+ if ( pPattern )
+ {
+ rCol = nCol;
+ return pPattern;
+ }
+
+ delete pColIter;
+ ++nCol;
+ if ( nCol <= nEndCol )
+ pColIter = pDoc->pTab[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
+ else
+ pColIter = NULL;
+ }
+ return NULL; // is nix mehr
+}
+
+//-------------------------------------------------------------------------------
+
+ScAttrRectIterator::ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
+ SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2) :
+ pDoc( pDocument ),
+ nTab( nTable ),
+ nEndCol( nCol2 ),
+ nStartRow( nRow1 ),
+ nEndRow( nRow2 ),
+ nIterStartCol( nCol1 ),
+ nIterEndCol( nCol1 )
+{
+ if ( ValidTab(nTab) && pDoc->pTab[nTab] )
+ {
+ pColIter = pDoc->pTab[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
+ while ( nIterEndCol < nEndCol &&
+ pDoc->pTab[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
+ pDoc->pTab[nTab]->aCol[nIterEndCol+1], nStartRow, nEndRow ) )
+ ++nIterEndCol;
+ }
+ else
+ pColIter = NULL;
+}
+
+ScAttrRectIterator::~ScAttrRectIterator()
+{
+ delete pColIter;
+}
+
+void ScAttrRectIterator::DataChanged()
+{
+ if (pColIter)
+ {
+ SCROW nNextRow = pColIter->GetNextRow();
+ delete pColIter;
+ pColIter = pDoc->pTab[nTab]->aCol[nIterStartCol].CreateAttrIterator( nNextRow, nEndRow );
+ }
+}
+
+const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
+ SCROW& rRow1, SCROW& rRow2 )
+{
+ while ( pColIter )
+ {
+ const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
+ if ( pPattern )
+ {
+ rCol1 = nIterStartCol;
+ rCol2 = nIterEndCol;
+ return pPattern;
+ }
+
+ delete pColIter;
+ nIterStartCol = nIterEndCol+1;
+ if ( nIterStartCol <= nEndCol )
+ {
+ nIterEndCol = nIterStartCol;
+ pColIter = pDoc->pTab[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
+ while ( nIterEndCol < nEndCol &&
+ pDoc->pTab[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
+ pDoc->pTab[nTab]->aCol[nIterEndCol+1], nStartRow, nEndRow ) )
+ ++nIterEndCol;
+ }
+ else
+ pColIter = NULL;
+ }
+ return NULL; // is nix mehr
+}
+
+// ============================================================================
+
+SCROW ScRowBreakIterator::NOT_FOUND = -1;
+
+ScRowBreakIterator::ScRowBreakIterator(set<SCROW>& rBreaks) :
+ mrBreaks(rBreaks),
+ maItr(rBreaks.begin()), maEnd(rBreaks.end())
+{
+}
+
+SCROW ScRowBreakIterator::first()
+{
+ maItr = mrBreaks.begin();
+ return maItr == maEnd ? NOT_FOUND : *maItr;
+}
+
+SCROW ScRowBreakIterator::next()
+{
+ ++maItr;
+ return maItr == maEnd ? NOT_FOUND : *maItr;
+}
diff --git a/sc/source/core/data/docpool.cxx b/sc/source/core/data/docpool.cxx
new file mode 100644
index 000000000000..8b2f48d8a2cc
--- /dev/null
+++ b/sc/source/core/data/docpool.cxx
@@ -0,0 +1,1059 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <tools/shl.hxx>
+#include <vcl/outdev.hxx>
+#include <svl/aeitem.hxx>
+#include <svl/itemiter.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <svx/dialmgr.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/hngpnctitem.hxx>
+#include <editeng/itemtype.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/postitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/svxitems.hrc>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/xmlcnitm.hxx>
+
+#include "docpool.hxx"
+#include "global.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "globstr.hrc"
+#include "sc.hrc" // Slot-IDs
+
+
+#define SC_MAX_POOLREF (SFX_ITEMS_OLD_MAXREF - 39)
+#define SC_SAFE_POOLREF (SC_MAX_POOLREF + 20)
+
+// STATIC DATA -----------------------------------------------------------
+
+USHORT* ScDocumentPool::pVersionMap1 = 0;
+USHORT* ScDocumentPool::pVersionMap2 = 0;
+USHORT* ScDocumentPool::pVersionMap3 = 0;
+USHORT* ScDocumentPool::pVersionMap4 = 0;
+USHORT* ScDocumentPool::pVersionMap5 = 0;
+USHORT* ScDocumentPool::pVersionMap6 = 0;
+USHORT* ScDocumentPool::pVersionMap7 = 0;
+USHORT* ScDocumentPool::pVersionMap8 = 0;
+USHORT* ScDocumentPool::pVersionMap9 = 0;
+USHORT* ScDocumentPool::pVersionMap10 = 0;
+USHORT* ScDocumentPool::pVersionMap11 = 0;
+
+// ATTR_FONT_TWOLINES (not used) was changed to ATTR_USERDEF (not saved in binary format) in 641c
+
+static SfxItemInfo __READONLY_DATA aItemInfos[] =
+{
+ { SID_ATTR_CHAR_FONT, SFX_ITEM_POOLABLE }, // ATTR_FONT
+ { SID_ATTR_CHAR_FONTHEIGHT, SFX_ITEM_POOLABLE }, // ATTR_FONT_HEIGHT
+ { SID_ATTR_CHAR_WEIGHT, SFX_ITEM_POOLABLE }, // ATTR_FONT_WEIGHT
+ { SID_ATTR_CHAR_POSTURE, SFX_ITEM_POOLABLE }, // ATTR_FONT_POSTURE
+ { SID_ATTR_CHAR_UNDERLINE, SFX_ITEM_POOLABLE }, // ATTR_FONT_UNDERLINE
+ { SID_ATTR_CHAR_OVERLINE, SFX_ITEM_POOLABLE }, // ATTR_FONT_OVERLINE
+ { SID_ATTR_CHAR_STRIKEOUT, SFX_ITEM_POOLABLE }, // ATTR_FONT_CROSSEDOUT
+ { SID_ATTR_CHAR_CONTOUR, SFX_ITEM_POOLABLE }, // ATTR_FONT_CONTOUR
+ { SID_ATTR_CHAR_SHADOWED, SFX_ITEM_POOLABLE }, // ATTR_FONT_SHADOWED
+ { SID_ATTR_CHAR_COLOR, SFX_ITEM_POOLABLE }, // ATTR_FONT_COLOR
+ { SID_ATTR_CHAR_LANGUAGE, SFX_ITEM_POOLABLE }, // ATTR_FONT_LANGUAGE
+ { SID_ATTR_CHAR_CJK_FONT, SFX_ITEM_POOLABLE }, // ATTR_CJK_FONT from 614
+ { SID_ATTR_CHAR_CJK_FONTHEIGHT, SFX_ITEM_POOLABLE }, // ATTR_CJK_FONT_HEIGHT from 614
+ { SID_ATTR_CHAR_CJK_WEIGHT, SFX_ITEM_POOLABLE }, // ATTR_CJK_FONT_WEIGHT from 614
+ { SID_ATTR_CHAR_CJK_POSTURE, SFX_ITEM_POOLABLE }, // ATTR_CJK_FONT_POSTURE from 614
+ { SID_ATTR_CHAR_CJK_LANGUAGE, SFX_ITEM_POOLABLE }, // ATTR_CJK_FONT_LANGUAGE from 614
+ { SID_ATTR_CHAR_CTL_FONT, SFX_ITEM_POOLABLE }, // ATTR_CTL_FONT from 614
+ { SID_ATTR_CHAR_CTL_FONTHEIGHT, SFX_ITEM_POOLABLE }, // ATTR_CTL_FONT_HEIGHT from 614
+ { SID_ATTR_CHAR_CTL_WEIGHT, SFX_ITEM_POOLABLE }, // ATTR_CTL_FONT_WEIGHT from 614
+ { SID_ATTR_CHAR_CTL_POSTURE, SFX_ITEM_POOLABLE }, // ATTR_CTL_FONT_POSTURE from 614
+ { SID_ATTR_CHAR_CTL_LANGUAGE, SFX_ITEM_POOLABLE }, // ATTR_CTL_FONT_LANGUAGE from 614
+ { SID_ATTR_CHAR_EMPHASISMARK, SFX_ITEM_POOLABLE }, // ATTR_FONT_EMPHASISMARK from 614
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_USERDEF from 614 / 641c
+ { SID_ATTR_CHAR_WORDLINEMODE, SFX_ITEM_POOLABLE }, // ATTR_FONT_WORDLINE from 632b
+ { SID_ATTR_CHAR_RELIEF, SFX_ITEM_POOLABLE }, // ATTR_FONT_RELIEF from 632b
+ { SID_ATTR_ALIGN_HYPHENATION, SFX_ITEM_POOLABLE }, // ATTR_HYPHENATE from 632b
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_SCRIPTSPACE from 614d
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_HANGPUNCTUATION from 614d
+ { SID_ATTR_PARA_FORBIDDEN_RULES,SFX_ITEM_POOLABLE }, // ATTR_FORBIDDEN_RULES from 614d
+ { SID_ATTR_ALIGN_HOR_JUSTIFY, SFX_ITEM_POOLABLE }, // ATTR_HOR_JUSTIFY
+ { SID_ATTR_ALIGN_INDENT, SFX_ITEM_POOLABLE }, // ATTR_INDENT ab 350
+ { SID_ATTR_ALIGN_VER_JUSTIFY, SFX_ITEM_POOLABLE }, // ATTR_VER_JUSTIFY
+ { SID_ATTR_ALIGN_STACKED, SFX_ITEM_POOLABLE }, // ATTR_STACKED from 680/dr14 (replaces ATTR_ORIENTATION)
+ { SID_ATTR_ALIGN_DEGREES, SFX_ITEM_POOLABLE }, // ATTR_ROTATE_VALUE ab 367
+ { SID_ATTR_ALIGN_LOCKPOS, SFX_ITEM_POOLABLE }, // ATTR_ROTATE_MODE ab 367
+ { SID_ATTR_ALIGN_ASIANVERTICAL, SFX_ITEM_POOLABLE }, // ATTR_VERTICAL_ASIAN from 642
+ { SID_ATTR_FRAMEDIRECTION, SFX_ITEM_POOLABLE }, // ATTR_WRITINGDIR from 643
+ { SID_ATTR_ALIGN_LINEBREAK, SFX_ITEM_POOLABLE }, // ATTR_LINEBREAK
+ { SID_ATTR_ALIGN_SHRINKTOFIT, SFX_ITEM_POOLABLE }, // ATTR_SHRINKTOFIT from 680/dr14
+ { SID_ATTR_BORDER_DIAG_TLBR, SFX_ITEM_POOLABLE }, // ATTR_BORDER_TLBR from 680/dr14
+ { SID_ATTR_BORDER_DIAG_BLTR, SFX_ITEM_POOLABLE }, // ATTR_BORDER_BLTR from 680/dr14
+ { SID_ATTR_ALIGN_MARGIN, SFX_ITEM_POOLABLE }, // ATTR_MARGIN
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_MERGE
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_MERGE_FLAG
+ { SID_ATTR_NUMBERFORMAT_VALUE, SFX_ITEM_POOLABLE }, // ATTR_VALUE_FORMAT
+ { ATTR_LANGUAGE_FORMAT, SFX_ITEM_POOLABLE }, // ATTR_LANGUAGE_FORMAT ab 329, wird im Dialog mit SID_ATTR_NUMBERFORMAT_VALUE kombiniert
+ { SID_ATTR_BRUSH, SFX_ITEM_POOLABLE }, // ATTR_BACKGROUND
+ { SID_SCATTR_PROTECTION, SFX_ITEM_POOLABLE }, // ATTR_PROTECTION
+ { SID_ATTR_BORDER_OUTER, SFX_ITEM_POOLABLE }, // ATTR_BORDER
+ { SID_ATTR_BORDER_INNER, SFX_ITEM_POOLABLE }, // ATTR_BORDER_INNER
+ { SID_ATTR_BORDER_SHADOW, SFX_ITEM_POOLABLE }, // ATTR_SHADOW
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_VALIDDATA
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_CONDITIONAL
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_PATTERN
+ { SID_ATTR_LRSPACE, SFX_ITEM_POOLABLE }, // ATTR_LRSPACE
+ { SID_ATTR_ULSPACE, SFX_ITEM_POOLABLE }, // ATTR_ULSPACE
+ { SID_ATTR_PAGE, SFX_ITEM_POOLABLE }, // ATTR_PAGE
+ { 0, SFX_ITEM_POOLABLE }, // ATTR_PAGE_PAPERTRAY, seit 303 nur noch dummy
+ { SID_ATTR_PAGE_PAPERBIN, SFX_ITEM_POOLABLE }, // ATTR_PAGE_PAPERBIN
+ { SID_ATTR_PAGE_SIZE, SFX_ITEM_POOLABLE }, // ATTR_PAGE_SIZE
+ { SID_ATTR_PAGE_MAXSIZE, SFX_ITEM_POOLABLE }, // ATTR_PAGE_MAXSIZE
+ { SID_ATTR_PAGE_EXT1, SFX_ITEM_POOLABLE }, // ATTR_PAGE_HORCENTER
+ { SID_ATTR_PAGE_EXT2, SFX_ITEM_POOLABLE }, // ATTR_PAGE_VERCENTER
+ { SID_ATTR_PAGE_ON, SFX_ITEM_POOLABLE }, // ATTR_PAGE_ON
+ { SID_ATTR_PAGE_DYNAMIC, SFX_ITEM_POOLABLE }, // ATTR_PAGE_DYNAMIC
+ { SID_ATTR_PAGE_SHARED, SFX_ITEM_POOLABLE }, // ATTR_PAGE_SHARED
+ { SID_SCATTR_PAGE_NOTES, SFX_ITEM_POOLABLE }, // ATTR_PAGE_NOTES
+ { SID_SCATTR_PAGE_GRID, SFX_ITEM_POOLABLE }, // ATTR_PAGE_GRID
+ { SID_SCATTR_PAGE_HEADERS, SFX_ITEM_POOLABLE }, // ATTR_PAGE_HEADERS
+ { SID_SCATTR_PAGE_CHARTS, SFX_ITEM_POOLABLE }, // ATTR_PAGE_CHARTS
+ { SID_SCATTR_PAGE_OBJECTS, SFX_ITEM_POOLABLE }, // ATTR_PAGE_OBJECTS
+ { SID_SCATTR_PAGE_DRAWINGS, SFX_ITEM_POOLABLE }, // ATTR_PAGE_DRAWINGS
+ { SID_SCATTR_PAGE_TOPDOWN, SFX_ITEM_POOLABLE }, // ATTR_PAGE_TOPDOWN
+ { SID_SCATTR_PAGE_SCALE, SFX_ITEM_POOLABLE }, // ATTR_PAGE_SCALE
+ { SID_SCATTR_PAGE_SCALETOPAGES, SFX_ITEM_POOLABLE }, // ATTR_PAGE_SCALETOPAGES
+ { SID_SCATTR_PAGE_FIRSTPAGENO, SFX_ITEM_POOLABLE }, // ATTR_PAGE_FIRSTPAGENO
+ { SID_SCATTR_PAGE_PRINTAREA, SFX_ITEM_POOLABLE }, // ATTR_PAGE_PRINTAREA
+ { SID_SCATTR_PAGE_REPEATROW, SFX_ITEM_POOLABLE }, // ATTR_PAGE_REPEATROW
+ { SID_SCATTR_PAGE_REPEATCOL, SFX_ITEM_POOLABLE }, // ATTR_PAGE_REPEATCOL
+ { SID_SCATTR_PAGE_PRINTTABLES, SFX_ITEM_POOLABLE }, // ATTR_PAGE_PRINTTABLES
+ { SID_SCATTR_PAGE_HEADERLEFT, SFX_ITEM_POOLABLE }, // ATTR_PAGE_HEADERLEFT
+ { SID_SCATTR_PAGE_FOOTERLEFT, SFX_ITEM_POOLABLE }, // ATTR_PAGE_FOOTERLEFT
+ { SID_SCATTR_PAGE_HEADERRIGHT, SFX_ITEM_POOLABLE }, // ATTR_PAGE_HEADERRIGHT
+ { SID_SCATTR_PAGE_FOOTERRIGHT, SFX_ITEM_POOLABLE }, // ATTR_PAGE_FOOTERRIGHT
+ { SID_ATTR_PAGE_HEADERSET, SFX_ITEM_POOLABLE }, // ATTR_PAGE_HEADERSET
+ { SID_ATTR_PAGE_FOOTERSET, SFX_ITEM_POOLABLE }, // ATTR_PAGE_FOOTERSET
+ { SID_SCATTR_PAGE_FORMULAS, SFX_ITEM_POOLABLE }, // ATTR_PAGE_FORMULAS
+ { SID_SCATTR_PAGE_NULLVALS, SFX_ITEM_POOLABLE }, // ATTR_PAGE_NULLVALS
+ { SID_SCATTR_PAGE_SCALETO, SFX_ITEM_POOLABLE } // ATTR_PAGE_SCALETO
+};
+
+// -----------------------------------------------------------------------
+
+ScDocumentPool::ScDocumentPool( SfxItemPool* pSecPool, BOOL bLoadRefCounts )
+
+ : SfxItemPool ( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScDocumentPool")),
+ ATTR_STARTINDEX, ATTR_ENDINDEX,
+ aItemInfos, NULL, bLoadRefCounts ),
+ pSecondary ( pSecPool )
+{
+ // latin font from GetDefaultFonts is not used, DEFAULTFONT_LATIN_SPREADSHEET instead
+ Font aStdFont = OutputDevice::GetDefaultFont( DEFAULTFONT_LATIN_SPREADSHEET, LANGUAGE_ENGLISH_US,
+ DEFAULTFONT_FLAGS_ONLYONE );
+ SvxFontItem* pStdFont = new SvxFontItem( aStdFont.GetFamily(),
+ aStdFont.GetName(), aStdFont.GetStyleName(),
+ aStdFont.GetPitch(), aStdFont.GetCharSet(),
+ ATTR_FONT );
+
+ SvxFontItem* pCjkFont = new SvxFontItem( ATTR_CJK_FONT );
+ SvxFontItem* pCtlFont = new SvxFontItem( ATTR_CTL_FONT );
+ SvxFontItem aDummy( ATTR_FONT );
+ GetDefaultFonts( aDummy, *pCjkFont, *pCtlFont );
+
+ SvxBoxInfoItem* pGlobalBorderInnerAttr = new SvxBoxInfoItem( ATTR_BORDER_INNER );
+ SfxItemSet* pSet = new SfxItemSet( *this, ATTR_PATTERN_START, ATTR_PATTERN_END );
+ SfxItemSet aSetItemItemSet( *this,
+ ATTR_BACKGROUND, ATTR_BACKGROUND,
+ ATTR_BORDER, ATTR_SHADOW,
+ ATTR_LRSPACE, ATTR_ULSPACE,
+ ATTR_PAGE_SIZE, ATTR_PAGE_SIZE,
+ ATTR_PAGE_ON, ATTR_PAGE_SHARED,
+ 0 );
+
+ pGlobalBorderInnerAttr->SetLine(NULL, BOXINFO_LINE_HORI);
+ pGlobalBorderInnerAttr->SetLine(NULL, BOXINFO_LINE_VERT);
+ pGlobalBorderInnerAttr->SetTable(TRUE);
+ pGlobalBorderInnerAttr->SetDist(TRUE);
+ pGlobalBorderInnerAttr->SetMinDist(FALSE);
+
+ ppPoolDefaults = new SfxPoolItem*[ATTR_ENDINDEX-ATTR_STARTINDEX+1];
+
+ ppPoolDefaults[ ATTR_FONT - ATTR_STARTINDEX ] = pStdFont;
+ ppPoolDefaults[ ATTR_FONT_HEIGHT - ATTR_STARTINDEX ] = new SvxFontHeightItem( 200, 100, ATTR_FONT_HEIGHT ); // 10 pt;
+ ppPoolDefaults[ ATTR_FONT_WEIGHT - ATTR_STARTINDEX ] = new SvxWeightItem( WEIGHT_NORMAL, ATTR_FONT_WEIGHT );
+ ppPoolDefaults[ ATTR_FONT_POSTURE - ATTR_STARTINDEX ] = new SvxPostureItem( ITALIC_NONE, ATTR_FONT_POSTURE );
+ ppPoolDefaults[ ATTR_FONT_UNDERLINE - ATTR_STARTINDEX ] = new SvxUnderlineItem( UNDERLINE_NONE, ATTR_FONT_UNDERLINE );
+ ppPoolDefaults[ ATTR_FONT_OVERLINE - ATTR_STARTINDEX ] = new SvxOverlineItem( UNDERLINE_NONE, ATTR_FONT_OVERLINE );
+ ppPoolDefaults[ ATTR_FONT_CROSSEDOUT - ATTR_STARTINDEX ] = new SvxCrossedOutItem( STRIKEOUT_NONE, ATTR_FONT_CROSSEDOUT );
+ ppPoolDefaults[ ATTR_FONT_CONTOUR - ATTR_STARTINDEX ] = new SvxContourItem( sal_False, ATTR_FONT_CONTOUR );
+ ppPoolDefaults[ ATTR_FONT_SHADOWED - ATTR_STARTINDEX ] = new SvxShadowedItem( sal_False, ATTR_FONT_SHADOWED );
+ ppPoolDefaults[ ATTR_FONT_COLOR - ATTR_STARTINDEX ] = new SvxColorItem( Color(COL_AUTO), ATTR_FONT_COLOR );
+ ppPoolDefaults[ ATTR_FONT_LANGUAGE - ATTR_STARTINDEX ] = new SvxLanguageItem( LanguageType(LANGUAGE_DONTKNOW), ATTR_FONT_LANGUAGE );
+ ppPoolDefaults[ ATTR_CJK_FONT - ATTR_STARTINDEX ] = pCjkFont;
+ ppPoolDefaults[ ATTR_CJK_FONT_HEIGHT - ATTR_STARTINDEX ] = new SvxFontHeightItem( 200, 100, ATTR_CJK_FONT_HEIGHT );
+ ppPoolDefaults[ ATTR_CJK_FONT_WEIGHT - ATTR_STARTINDEX ] = new SvxWeightItem( WEIGHT_NORMAL, ATTR_CJK_FONT_WEIGHT );
+ ppPoolDefaults[ ATTR_CJK_FONT_POSTURE- ATTR_STARTINDEX ] = new SvxPostureItem( ITALIC_NONE, ATTR_CJK_FONT_POSTURE );
+ ppPoolDefaults[ ATTR_CJK_FONT_LANGUAGE-ATTR_STARTINDEX ] = new SvxLanguageItem( LanguageType(LANGUAGE_DONTKNOW),
+ ATTR_CJK_FONT_LANGUAGE );
+ ppPoolDefaults[ ATTR_CTL_FONT - ATTR_STARTINDEX ] = pCtlFont;
+ ppPoolDefaults[ ATTR_CTL_FONT_HEIGHT - ATTR_STARTINDEX ] = new SvxFontHeightItem( 200, 100, ATTR_CTL_FONT_HEIGHT );
+ ppPoolDefaults[ ATTR_CTL_FONT_WEIGHT - ATTR_STARTINDEX ] = new SvxWeightItem( WEIGHT_NORMAL, ATTR_CTL_FONT_WEIGHT );
+ ppPoolDefaults[ ATTR_CTL_FONT_POSTURE- ATTR_STARTINDEX ] = new SvxPostureItem( ITALIC_NONE, ATTR_CTL_FONT_POSTURE );
+ ppPoolDefaults[ ATTR_CTL_FONT_LANGUAGE-ATTR_STARTINDEX ] = new SvxLanguageItem( LanguageType(LANGUAGE_DONTKNOW),
+ ATTR_CTL_FONT_LANGUAGE );
+ ppPoolDefaults[ ATTR_FONT_EMPHASISMARK-ATTR_STARTINDEX ] = new SvxEmphasisMarkItem( EMPHASISMARK_NONE, ATTR_FONT_EMPHASISMARK );
+ ppPoolDefaults[ ATTR_USERDEF - ATTR_STARTINDEX ] = new SvXMLAttrContainerItem( ATTR_USERDEF );
+ ppPoolDefaults[ ATTR_FONT_WORDLINE - ATTR_STARTINDEX ] = new SvxWordLineModeItem(sal_False, ATTR_FONT_WORDLINE );
+ ppPoolDefaults[ ATTR_FONT_RELIEF - ATTR_STARTINDEX ] = new SvxCharReliefItem( RELIEF_NONE, ATTR_FONT_RELIEF );
+ ppPoolDefaults[ ATTR_HYPHENATE - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_HYPHENATE );
+ ppPoolDefaults[ ATTR_SCRIPTSPACE - ATTR_STARTINDEX ] = new SvxScriptSpaceItem( sal_False, ATTR_SCRIPTSPACE);
+ ppPoolDefaults[ ATTR_HANGPUNCTUATION - ATTR_STARTINDEX ] = new SvxHangingPunctuationItem( sal_False, ATTR_HANGPUNCTUATION);
+ ppPoolDefaults[ ATTR_FORBIDDEN_RULES - ATTR_STARTINDEX ] = new SvxForbiddenRuleItem( sal_False, ATTR_FORBIDDEN_RULES);
+ ppPoolDefaults[ ATTR_HOR_JUSTIFY - ATTR_STARTINDEX ] = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY);
+ ppPoolDefaults[ ATTR_INDENT - ATTR_STARTINDEX ] = new SfxUInt16Item( ATTR_INDENT, 0 );
+ ppPoolDefaults[ ATTR_VER_JUSTIFY - ATTR_STARTINDEX ] = new SvxVerJustifyItem( SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY);
+ ppPoolDefaults[ ATTR_STACKED - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_STACKED, FALSE );
+ ppPoolDefaults[ ATTR_ROTATE_VALUE - ATTR_STARTINDEX ] = new SfxInt32Item( ATTR_ROTATE_VALUE, 0 );
+ ppPoolDefaults[ ATTR_ROTATE_MODE - ATTR_STARTINDEX ] = new SvxRotateModeItem( SVX_ROTATE_MODE_BOTTOM, ATTR_ROTATE_MODE );
+ ppPoolDefaults[ ATTR_VERTICAL_ASIAN - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_VERTICAL_ASIAN );
+ // The default for the ATTR_WRITINGDIR cell attribute must by FRMDIR_ENVIRONMENT,
+ // so that value is returned when asking for a default cell's attributes.
+ // The value from the page style is set as DefaultHorizontalTextDirection for the EditEngine.
+ ppPoolDefaults[ ATTR_WRITINGDIR - ATTR_STARTINDEX ] = new SvxFrameDirectionItem( FRMDIR_ENVIRONMENT, ATTR_WRITINGDIR );
+ ppPoolDefaults[ ATTR_LINEBREAK - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_LINEBREAK );
+ ppPoolDefaults[ ATTR_SHRINKTOFIT - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_SHRINKTOFIT );
+ ppPoolDefaults[ ATTR_BORDER_TLBR - ATTR_STARTINDEX ] = new SvxLineItem( ATTR_BORDER_TLBR );
+ ppPoolDefaults[ ATTR_BORDER_BLTR - ATTR_STARTINDEX ] = new SvxLineItem( ATTR_BORDER_BLTR );
+ ppPoolDefaults[ ATTR_MARGIN - ATTR_STARTINDEX ] = new SvxMarginItem( ATTR_MARGIN );
+ ppPoolDefaults[ ATTR_MERGE - ATTR_STARTINDEX ] = new ScMergeAttr;
+ ppPoolDefaults[ ATTR_MERGE_FLAG - ATTR_STARTINDEX ] = new ScMergeFlagAttr;
+ ppPoolDefaults[ ATTR_VALUE_FORMAT - ATTR_STARTINDEX ] = new SfxUInt32Item( ATTR_VALUE_FORMAT, 0 );
+ ppPoolDefaults[ ATTR_LANGUAGE_FORMAT - ATTR_STARTINDEX ] = new SvxLanguageItem( ScGlobal::eLnge, ATTR_LANGUAGE_FORMAT );
+ ppPoolDefaults[ ATTR_BACKGROUND - ATTR_STARTINDEX ] = new SvxBrushItem( Color(COL_TRANSPARENT), ATTR_BACKGROUND );
+ ppPoolDefaults[ ATTR_PROTECTION - ATTR_STARTINDEX ] = new ScProtectionAttr;
+ ppPoolDefaults[ ATTR_BORDER - ATTR_STARTINDEX ] = new SvxBoxItem( ATTR_BORDER );
+ ppPoolDefaults[ ATTR_BORDER_INNER - ATTR_STARTINDEX ] = pGlobalBorderInnerAttr;
+ ppPoolDefaults[ ATTR_SHADOW - ATTR_STARTINDEX ] = new SvxShadowItem( ATTR_SHADOW );
+ ppPoolDefaults[ ATTR_VALIDDATA - ATTR_STARTINDEX ] = new SfxUInt32Item( ATTR_VALIDDATA, 0 );
+ ppPoolDefaults[ ATTR_CONDITIONAL - ATTR_STARTINDEX ] = new SfxUInt32Item( ATTR_CONDITIONAL, 0 );
+
+ // GetRscString funktioniert erst nach ScGlobal::Init, zu erkennen am EmptyBrushItem
+ //! zusaetzliche Methode ScGlobal::IsInit() oder so...
+ //! oder erkennen, ob dies der Secondary-Pool fuer einen MessagePool ist
+ if ( ScGlobal::GetEmptyBrushItem() )
+ ppPoolDefaults[ ATTR_PATTERN - ATTR_STARTINDEX ] = new ScPatternAttr( pSet, ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
+ else
+ ppPoolDefaults[ ATTR_PATTERN - ATTR_STARTINDEX ] = new ScPatternAttr( pSet,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STRING_STANDARD)) ); //! without name?
+
+ ppPoolDefaults[ ATTR_LRSPACE - ATTR_STARTINDEX ] = new SvxLRSpaceItem( ATTR_LRSPACE );
+ ppPoolDefaults[ ATTR_ULSPACE - ATTR_STARTINDEX ] = new SvxULSpaceItem( ATTR_ULSPACE );
+ ppPoolDefaults[ ATTR_PAGE - ATTR_STARTINDEX ] = new SvxPageItem( ATTR_PAGE );
+ ppPoolDefaults[ ATTR_PAGE_PAPERTRAY - ATTR_STARTINDEX ] = new SfxAllEnumItem( ATTR_PAGE_PAPERTRAY );
+ ppPoolDefaults[ ATTR_PAGE_PAPERBIN - ATTR_STARTINDEX ] = new SvxPaperBinItem( ATTR_PAGE_PAPERBIN );
+ ppPoolDefaults[ ATTR_PAGE_SIZE - ATTR_STARTINDEX ] = new SvxSizeItem( ATTR_PAGE_SIZE );
+ ppPoolDefaults[ ATTR_PAGE_MAXSIZE - ATTR_STARTINDEX ] = new SvxSizeItem( ATTR_PAGE_MAXSIZE );
+ ppPoolDefaults[ ATTR_PAGE_HORCENTER - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_HORCENTER );
+ ppPoolDefaults[ ATTR_PAGE_VERCENTER - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_VERCENTER );
+ ppPoolDefaults[ ATTR_PAGE_ON - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_ON, TRUE );
+ ppPoolDefaults[ ATTR_PAGE_DYNAMIC - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_DYNAMIC, TRUE );
+ ppPoolDefaults[ ATTR_PAGE_SHARED - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_SHARED, TRUE );
+ ppPoolDefaults[ ATTR_PAGE_NOTES - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_NOTES, FALSE );
+ ppPoolDefaults[ ATTR_PAGE_GRID - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_GRID, FALSE );
+ ppPoolDefaults[ ATTR_PAGE_HEADERS - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_HEADERS, FALSE );
+ ppPoolDefaults[ ATTR_PAGE_CHARTS - ATTR_STARTINDEX ] = new ScViewObjectModeItem( ATTR_PAGE_CHARTS );
+ ppPoolDefaults[ ATTR_PAGE_OBJECTS - ATTR_STARTINDEX ] = new ScViewObjectModeItem( ATTR_PAGE_OBJECTS );
+ ppPoolDefaults[ ATTR_PAGE_DRAWINGS - ATTR_STARTINDEX ] = new ScViewObjectModeItem( ATTR_PAGE_DRAWINGS );
+ ppPoolDefaults[ ATTR_PAGE_TOPDOWN - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_TOPDOWN, TRUE );
+ ppPoolDefaults[ ATTR_PAGE_SCALE - ATTR_STARTINDEX ] = new SfxUInt16Item( ATTR_PAGE_SCALE, 100 );
+ ppPoolDefaults[ ATTR_PAGE_SCALETOPAGES-ATTR_STARTINDEX ] = new SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, 1 );
+ ppPoolDefaults[ ATTR_PAGE_FIRSTPAGENO- ATTR_STARTINDEX ] = new SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 1 );
+ ppPoolDefaults[ ATTR_PAGE_PRINTAREA - ATTR_STARTINDEX ] = new ScRangeItem( ATTR_PAGE_PRINTAREA );
+ ppPoolDefaults[ ATTR_PAGE_REPEATROW - ATTR_STARTINDEX ] = new ScRangeItem( ATTR_PAGE_REPEATROW );
+ ppPoolDefaults[ ATTR_PAGE_REPEATCOL - ATTR_STARTINDEX ] = new ScRangeItem( ATTR_PAGE_REPEATCOL );
+ ppPoolDefaults[ ATTR_PAGE_PRINTTABLES- ATTR_STARTINDEX ] = new ScTableListItem( ATTR_PAGE_PRINTTABLES );
+ ppPoolDefaults[ ATTR_PAGE_HEADERLEFT - ATTR_STARTINDEX ] = new ScPageHFItem( ATTR_PAGE_HEADERLEFT );
+ ppPoolDefaults[ ATTR_PAGE_FOOTERLEFT - ATTR_STARTINDEX ] = new ScPageHFItem( ATTR_PAGE_FOOTERLEFT );
+ ppPoolDefaults[ ATTR_PAGE_HEADERRIGHT- ATTR_STARTINDEX ] = new ScPageHFItem( ATTR_PAGE_HEADERRIGHT );
+ ppPoolDefaults[ ATTR_PAGE_FOOTERRIGHT- ATTR_STARTINDEX ] = new ScPageHFItem( ATTR_PAGE_FOOTERRIGHT );
+ ppPoolDefaults[ ATTR_PAGE_HEADERSET - ATTR_STARTINDEX ] = new SvxSetItem( ATTR_PAGE_HEADERSET, aSetItemItemSet );
+ ppPoolDefaults[ ATTR_PAGE_FOOTERSET - ATTR_STARTINDEX ] = new SvxSetItem( ATTR_PAGE_FOOTERSET, aSetItemItemSet );
+ ppPoolDefaults[ ATTR_PAGE_FORMULAS - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_FORMULAS, FALSE );
+ ppPoolDefaults[ ATTR_PAGE_NULLVALS - ATTR_STARTINDEX ] = new SfxBoolItem( ATTR_PAGE_NULLVALS, TRUE );
+ ppPoolDefaults[ ATTR_PAGE_SCALETO - ATTR_STARTINDEX ] = new ScPageScaleToItem( 1, 1 );
+// ppPoolDefaults[ ATTR_ITEM_DOUBLE - ATTR_STARTINDEX ] = new ScDoubleItem( ATTR_ITEM_DOUBLE, 0 );
+
+ SetDefaults( ppPoolDefaults );
+
+ if ( pSecondary )
+ SetSecondaryPool( pSecondary );
+
+ // ATTR_LANGUAGE_FORMAT ab sv329 eingefuegt, VersionMap in _ScGlobal__Init
+ SetVersionMap( 1, 100, 157, pVersionMap1 );
+
+ // ATTR_VALIDDATA, ATTR_CONDITIONAL ab 341
+ SetVersionMap( 2, 100, 158, pVersionMap2 );
+
+ // ATTR_INDENT ab 350
+ SetVersionMap( 3, 100, 160, pVersionMap3 );
+
+ // ATTR_ROTATE_VALUE, ATTR_ROTATE_MODE ab 367
+ SetVersionMap( 4, 100, 161, pVersionMap4 );
+
+ // CJK, CTL, EMPHASISMARK, TWOLINES from 614
+ SetVersionMap( 5, 100, 163, pVersionMap5 );
+
+ // ATTR_SCRIPTSPACE, ATTR_HANGPUNCTUATION, ATTR_FORBIDDEN_RULES from 614d
+ SetVersionMap( 6, 100, 175, pVersionMap6 );
+
+ // ATTR_FONT_WORDLINE, ATTR_FONT_RELIEF, ATTR_HYPHENATE from 632b
+ SetVersionMap( 7, 100, 178, pVersionMap7 );
+
+ // ATTR_VERTICAL_ASIAN from 642q
+ SetVersionMap( 8, 100, 181, pVersionMap8 );
+
+ // ATTR_WRITINGDIR from 643y
+ SetVersionMap( 9, 100, 182, pVersionMap9 );
+
+ // ATTR_PAGE_SCALETO added in 680/sab008
+ // new version map not required
+
+ // ATTR_SHRINKTOFIT, ATTR_BORDER_TL_BR, ATTR_BORDER_BL_TR added in 680/dr14
+ SetVersionMap( 10, 100, 184, pVersionMap10 );
+
+ // ATTR_FONT_OVERLINE added in DEV300/overline2
+ SetVersionMap( 11, 100, 187, pVersionMap11 );
+}
+
+__EXPORT ScDocumentPool::~ScDocumentPool()
+{
+ Delete();
+
+ for ( USHORT i=0; i < ATTR_ENDINDEX-ATTR_STARTINDEX+1; i++ )
+ {
+ SetRefCount( *ppPoolDefaults[i], 0 );
+ delete ppPoolDefaults[i];
+ }
+
+ delete[] ppPoolDefaults;
+ SfxItemPool::Free(pSecondary);
+}
+
+void ScDocumentPool::InitVersionMaps()
+{
+ DBG_ASSERT( !pVersionMap1 && !pVersionMap2 &&
+ !pVersionMap3 && !pVersionMap4 &&
+ !pVersionMap5 && !pVersionMap6 &&
+ !pVersionMap7 && !pVersionMap8 &&
+ !pVersionMap9 && !pVersionMap10 &&
+ !pVersionMap11, "InitVersionMaps call multiple times" );
+
+ // alte WhichId's mappen
+ // nicht mit ATTR_* zaehlen, falls die sich nochmal aendern
+
+ // erste Map: ATTR_LANGUAGE_FORMAT ab sv329 eingefuegt
+
+ const USHORT nMap1Start = 100; // alter ATTR_STARTINDEX
+ const USHORT nMap1End = 157; // alter ATTR_ENDINDEX
+ const USHORT nMap1Count = nMap1End - nMap1Start + 1;
+ const USHORT nMap1New = 18; // ATTR_LANGUAGE_FORMAT - ATTR_STARTINDEX
+ pVersionMap1 = new USHORT [ nMap1Count ];
+ USHORT i, j;
+ for ( i=0, j=nMap1Start; i < nMap1New; i++, j++ )
+ pVersionMap1[i] = j;
+ // ein Eintrag eingefuegt...
+ for ( i=nMap1New, j=nMap1Start+nMap1New+1; i < nMap1Count; i++, j++ )
+ pVersionMap1[i] = j;
+
+ // zweite Map: ATTR_VALIDDATA und ATTR_CONDITIONAL ab 341 eingefuegt
+
+ const USHORT nMap2Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap2End = 158; // ATTR_ENDINDEX
+ const USHORT nMap2Count = nMap2End - nMap2Start + 1;
+ const USHORT nMap2New = 24; // ATTR_VALIDDATA - ATTR_STARTINDEX
+ pVersionMap2 = new USHORT [ nMap2Count ];
+ for ( i=0, j=nMap2Start; i < nMap2New; i++, j++ )
+ pVersionMap2[i] = j;
+ // zwei Eintraege eingefuegt...
+ for ( i=nMap2New, j=nMap2Start+nMap2New+2; i < nMap2Count; i++, j++ )
+ pVersionMap2[i] = j;
+
+ // dritte Map: ATTR_INDENT ab 350 eingefuegt
+
+ const USHORT nMap3Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap3End = 160; // ATTR_ENDINDEX
+ const USHORT nMap3Count = nMap3End - nMap3Start + 1;
+ const USHORT nMap3New = 11; // ATTR_INDENT - ATTR_STARTINDEX
+ pVersionMap3 = new USHORT [ nMap3Count ];
+ for ( i=0, j=nMap3Start; i < nMap3New; i++, j++ )
+ pVersionMap3[i] = j;
+ // ein Eintrag eingefuegt...
+ for ( i=nMap3New, j=nMap3Start+nMap3New+1; i < nMap3Count; i++, j++ )
+ pVersionMap3[i] = j;
+
+ // vierte Map: ATTR_ROTATE_VALUE und ATTR_ROTATE_MODE ab 367 eingefuegt
+
+ const USHORT nMap4Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap4End = 161; // ATTR_ENDINDEX
+ const USHORT nMap4Count = nMap4End - nMap4Start + 1;
+ const USHORT nMap4New = 14; // ATTR_ROTATE_VALUE - ATTR_STARTINDEX
+ pVersionMap4 = new USHORT [ nMap4Count ];
+ for ( i=0, j=nMap4Start; i < nMap4New; i++, j++ )
+ pVersionMap4[i] = j;
+ // zwei Eintraege eingefuegt...
+ for ( i=nMap4New, j=nMap4Start+nMap4New+2; i < nMap4Count; i++, j++ )
+ pVersionMap4[i] = j;
+
+ // fifth map: CJK..., CTL..., EMPHASISMARK, TWOLINES (12 items) added in 614
+
+ const USHORT nMap5Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap5End = 163; // ATTR_ENDINDEX
+ const USHORT nMap5Count = nMap5End - nMap5Start + 1;
+ const USHORT nMap5New = 10; // ATTR_CJK_FONT - ATTR_STARTINDEX
+ pVersionMap5 = new USHORT [ nMap5Count ];
+ for ( i=0, j=nMap5Start; i < nMap5New; i++, j++ )
+ pVersionMap5[i] = j;
+ // 12 entries inserted
+ for ( i=nMap5New, j=nMap5Start+nMap5New+12; i < nMap5Count; i++, j++ )
+ pVersionMap5[i] = j;
+
+ // sixth map: ATTR_SCRIPTSPACE, ATTR_HANGPUNCTUATION, ATTR_FORBIDDEN_RULES added in 614d
+
+ const USHORT nMap6Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap6End = 175; // ATTR_ENDINDEX
+ const USHORT nMap6Count = nMap6End - nMap6Start + 1;
+ const USHORT nMap6New = 22; // ATTR_SCRIPTSPACE - ATTR_STARTINDEX
+ pVersionMap6 = new USHORT [ nMap6Count ];
+ for ( i=0, j=nMap6Start; i < nMap6New; i++, j++ )
+ pVersionMap6[i] = j;
+ // 3 entries inserted
+ for ( i=nMap6New, j=nMap6Start+nMap6New+3; i < nMap6Count; i++, j++ )
+ pVersionMap6[i] = j;
+
+ // seventh map: ATTR_FONT_WORDLINE, ATTR_FONT_RELIEF, ATTR_HYPHENATE added in 632b
+
+ const USHORT nMap7Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap7End = 178; // ATTR_ENDINDEX
+ const USHORT nMap7Count = nMap7End - nMap7Start + 1;
+ const USHORT nMap7New = 22; // ATTR_FONT_WORDLINE - ATTR_STARTINDEX
+ pVersionMap7 = new USHORT [ nMap7Count ];
+ for ( i=0, j=nMap7Start; i < nMap7New; i++, j++ )
+ pVersionMap7[i] = j;
+ // 3 entries inserted
+ for ( i=nMap7New, j=nMap7Start+nMap7New+3; i < nMap7Count; i++, j++ )
+ pVersionMap7[i] = j;
+
+ // eighth map: ATTR_VERTICAL_ASIAN added in 642q
+
+ const USHORT nMap8Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap8End = 181; // ATTR_ENDINDEX
+ const USHORT nMap8Count = nMap8End - nMap8Start + 1;
+ const USHORT nMap8New = 34; // ATTR_VERTICAL_ASIAN - ATTR_STARTINDEX
+ pVersionMap8 = new USHORT [ nMap8Count ];
+ for ( i=0, j=nMap8Start; i < nMap8New; i++, j++ )
+ pVersionMap8[i] = j;
+ // 1 entry inserted
+ for ( i=nMap8New, j=nMap8Start+nMap8New+1; i < nMap8Count; i++, j++ )
+ pVersionMap8[i] = j;
+
+ // 9th map: ATTR_WRITINGDIR added in 643y
+
+ const USHORT nMap9Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap9End = 182; // ATTR_ENDINDEX
+ const USHORT nMap9Count = nMap9End - nMap9Start + 1;
+ const USHORT nMap9New = 35; // ATTR_WRITINGDIR - ATTR_STARTINDEX
+ pVersionMap9 = new USHORT [ nMap9Count ];
+ for ( i=0, j=nMap9Start; i < nMap9New; i++, j++ )
+ pVersionMap9[i] = j;
+ // 1 entry inserted
+ for ( i=nMap9New, j=nMap9Start+nMap9New+1; i < nMap9Count; i++, j++ )
+ pVersionMap9[i] = j;
+
+ // ATTR_PAGE_SCALETO added in 680/sab008
+
+ // 10th map: ATTR_SHRINKTOFIT, ATTR_BORDER_TL_BR, ATTR_BORDER_BL_TR added in 680/dr14
+
+ const USHORT nMap10Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap10End = 184; // ATTR_ENDINDEX
+ const USHORT nMap10Count = nMap10End - nMap10Start + 1;
+ const USHORT nMap10New = 37; // ATTR_SHRINKTOFIT - ATTR_STARTINDEX
+ pVersionMap10 = new USHORT [ nMap10Count ];
+ for ( i=0, j=nMap10Start; i < nMap10New; i++, j++ )
+ pVersionMap10[i] = j;
+ // 3 entries inserted
+ for ( i=nMap10New, j=nMap10Start+nMap10New+3; i < nMap10Count; i++, j++ )
+ pVersionMap10[i] = j;
+
+ // 11th map: ATTR_FONT_OVERLINE added in DEV300/overline2
+
+ const USHORT nMap11Start = 100; // ATTR_STARTINDEX
+ const USHORT nMap11End = 187; // ATTR_ENDINDEX
+ const USHORT nMap11Count = nMap11End - nMap11Start + 1;
+ const USHORT nMap11New = 5; // ATTR_FONT_OVERLINE - ATTR_STARTINDEX
+ pVersionMap11 = new USHORT [ nMap11Count ];
+ for ( i=0, j=nMap11Start; i < nMap11New; i++, j++ )
+ pVersionMap11[i] = j;
+ // 1 entry inserted
+ for ( i=nMap11New, j=nMap11Start+nMap11New+1; i < nMap11Count; i++, j++ )
+ pVersionMap11[i] = j;
+}
+
+void ScDocumentPool::DeleteVersionMaps()
+{
+ DBG_ASSERT( pVersionMap1 && pVersionMap2 &&
+ pVersionMap3 && pVersionMap4 &&
+ pVersionMap5 && pVersionMap6 &&
+ pVersionMap7 && pVersionMap8 &&
+ pVersionMap9 && pVersionMap10 &&
+ pVersionMap11, "DeleteVersionMaps without maps" );
+
+ delete[] pVersionMap11;
+ pVersionMap11 = 0;
+ delete[] pVersionMap10;
+ pVersionMap10 = 0;
+ delete[] pVersionMap9;
+ pVersionMap9 = 0;
+ delete[] pVersionMap8;
+ pVersionMap8 = 0;
+ delete[] pVersionMap7;
+ pVersionMap7 = 0;
+ delete[] pVersionMap6;
+ pVersionMap6 = 0;
+ delete[] pVersionMap5;
+ pVersionMap5 = 0;
+ delete[] pVersionMap4;
+ pVersionMap4 = 0;
+ delete[] pVersionMap3;
+ pVersionMap3 = 0;
+ delete[] pVersionMap2;
+ pVersionMap2 = 0;
+ delete[] pVersionMap1;
+ pVersionMap1 = 0;
+}
+
+// ----------------------------------------------------------------------------------------
+//
+// Fuer die Pattern-Attribute (SetItems) kann der USHORT RefCount leicht ueberlaufen
+// (z.B. 600 ganze Zeilen abwechselnd formatieren).
+// Darum wird der RefCount bei SC_MAX_POOLREF festgehalten und nicht mehr hoch- oder
+// heruntergezaehlt. Dieser RefCount wird dann erst beim naechsten Laden neu gezaehlt.
+// Die Differenz zwischen SC_MAX_POOLREF und SC_SAFE_POOLREF ist ein wenig groesser
+// als noetig, um zu erkennen, wenn der RefCount aus Versehen doch "normal" veraendert
+// wird (Assertions).
+//
+
+const SfxPoolItem& __EXPORT ScDocumentPool::Put( const SfxPoolItem& rItem, USHORT nWhich )
+{
+ if ( rItem.Which() != ATTR_PATTERN ) // nur Pattern ist special
+ return SfxItemPool::Put( rItem, nWhich );
+
+ // das Default-Pattern dieses Pools nicht kopieren
+ if (&rItem == ppPoolDefaults[ ATTR_PATTERN - ATTR_STARTINDEX ])
+ return rItem;
+
+ // ansonsten muss Put immer passieren, weil es ein anderer Pool sein kann
+ const SfxPoolItem& rNew = SfxItemPool::Put( rItem, nWhich );
+ CheckRef( rNew );
+ return rNew;
+}
+
+void __EXPORT ScDocumentPool::Remove( const SfxPoolItem& rItem )
+{
+ if ( rItem.Which() == ATTR_PATTERN ) // nur Pattern ist special
+ {
+ ULONG nRef = rItem.GetRefCount();
+ if ( nRef >= (ULONG) SC_MAX_POOLREF && nRef <= (ULONG) SFX_ITEMS_OLD_MAXREF )
+ {
+ if ( nRef != (ULONG) SC_SAFE_POOLREF )
+ {
+ DBG_ERROR("Wer fummelt da an meinen Ref-Counts herum");
+ SetRefCount( (SfxPoolItem&)rItem, (ULONG) SC_SAFE_POOLREF );
+ }
+ return; // nicht herunterzaehlen
+ }
+ }
+ SfxItemPool::Remove( rItem );
+}
+
+void ScDocumentPool::CheckRef( const SfxPoolItem& rItem ) // static
+{
+ ULONG nRef = rItem.GetRefCount();
+ if ( nRef >= (ULONG) SC_MAX_POOLREF && nRef <= (ULONG) SFX_ITEMS_OLD_MAXREF )
+ {
+ // beim Apply vom Cache wird evtl. um 2 hochgezaehlt (auf MAX+1 oder SAFE+2),
+ // heruntergezaehlt wird nur einzeln (in LoadCompleted)
+ DBG_ASSERT( nRef<=(ULONG)SC_MAX_POOLREF+1 || (nRef>=(ULONG)SC_SAFE_POOLREF-1 && nRef<=(ULONG)SC_SAFE_POOLREF+2),
+ "ScDocumentPool::CheckRef" );
+ SetRefCount( (SfxPoolItem&)rItem, (ULONG) SC_SAFE_POOLREF );
+ }
+}
+
+// ----------------------------------------------------------------------------------------
+
+void ScDocumentPool::StyleDeleted( ScStyleSheet* pStyle )
+{
+ USHORT nCount = GetItemCount(ATTR_PATTERN);
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScPatternAttr* pPattern = (ScPatternAttr*)GetItem(ATTR_PATTERN, i);
+ if ( pPattern && pPattern->GetStyleSheet() == pStyle )
+ pPattern->StyleToName();
+ }
+}
+
+void ScDocumentPool::CellStyleCreated( const String& rName )
+{
+ // If a style was created, don't keep any pattern with its name string in the pool,
+ // because it would compare equal to a pattern with a pointer to the new style.
+ // Calling StyleSheetChanged isn't enough because the pool may still contain items
+ // for undo or clipboard content.
+
+ sal_uInt16 nCount = GetItemCount(ATTR_PATTERN);
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ ScPatternAttr* pPattern = (ScPatternAttr*)GetItem(ATTR_PATTERN, i);
+ if ( pPattern && pPattern->GetStyleSheet() == NULL )
+ {
+ const String* pStyleName = pPattern->GetStyleName();
+ if ( pStyleName && *pStyleName == rName )
+ pPattern->UpdateStyleSheet(); // find and store style pointer
+ }
+ }
+}
+
+SfxItemPool* __EXPORT ScDocumentPool::Clone() const
+{
+ return new SfxItemPool (*this, TRUE);
+}
+
+SfxItemPresentation lcl_HFPresentation
+(
+ const SfxPoolItem& rItem,
+ SfxItemPresentation ePresentation,
+ SfxMapUnit eCoreMetric,
+ SfxMapUnit ePresentationMetric,
+ String& rText,
+ const IntlWrapper* pIntl
+)
+{
+ const SfxItemSet& rSet = ((const SfxSetItem&)rItem).GetItemSet();
+ const SfxPoolItem* pItem;
+
+ if ( SFX_ITEM_SET == rSet.GetItemState(ATTR_PAGE_ON,FALSE,&pItem) )
+ {
+ if( FALSE == ((const SfxBoolItem*)pItem)->GetValue() )
+ return SFX_ITEM_PRESENTATION_NONE;
+ }
+
+ SfxItemIter aIter( rSet );
+ pItem = aIter.FirstItem();
+ String aText;
+ String aDel = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( " + " ));
+
+ while( pItem )
+ {
+ USHORT nWhich = pItem->Which();
+
+ aText.Erase();
+
+ switch( nWhich )
+ {
+ case ATTR_PAGE_ON:
+ case ATTR_PAGE_DYNAMIC:
+ case ATTR_PAGE_SHARED:
+ break;
+
+ case ATTR_LRSPACE:
+ {
+ SvxLRSpaceItem& rLRItem = (SvxLRSpaceItem&)*pItem;
+ USHORT nPropLeftMargin = rLRItem.GetPropLeft();
+ USHORT nPropRightMargin = rLRItem.GetPropRight();
+ USHORT nLeftMargin, nRightMargin;
+ long nTmp;
+ nTmp = rLRItem.GetLeft();
+ nLeftMargin = nTmp < 0 ? 0 : USHORT(nTmp);
+ nTmp = rLRItem.GetRight();
+ nRightMargin = nTmp < 0 ? 0 : USHORT(nTmp);
+
+ aText = EE_RESSTR(RID_SVXITEMS_LRSPACE_LEFT);
+ if ( 100 != nPropLeftMargin )
+ {
+ aText += String::CreateFromInt32( nPropLeftMargin );
+ aText += '%';
+ }
+ else
+ {
+ aText += GetMetricText( (long)nLeftMargin,
+ eCoreMetric, ePresentationMetric, pIntl );
+ aText += EE_RESSTR(GetMetricId(ePresentationMetric));
+ }
+ aText += cpDelim;
+
+ // nPropFirstLineOfst haben wir nicht
+
+ aText += EE_RESSTR(RID_SVXITEMS_LRSPACE_RIGHT);
+ if ( 100 != nPropRightMargin )
+ {
+ aText += String::CreateFromInt32( nPropRightMargin );
+ aText += '%';
+ }
+ else
+ {
+ aText += GetMetricText( (long)nRightMargin,
+ eCoreMetric, ePresentationMetric, pIntl );
+ aText += EE_RESSTR(GetMetricId(ePresentationMetric));
+ }
+ }
+ break;
+
+ default:
+ if ( !pIntl )
+ pIntl = ScGlobal::GetScIntlWrapper();
+ pItem->GetPresentation( ePresentation, eCoreMetric, ePresentationMetric, aText, pIntl );
+
+ }
+
+ if ( aText.Len() )
+ {
+ rText += aText;
+ rText += aDel;
+ }
+
+ pItem = aIter.NextItem();
+ }
+
+ rText.EraseTrailingChars();
+ rText.EraseTrailingChars( '+' );
+ rText.EraseTrailingChars();
+
+ return ePresentation;
+}
+
+SfxItemPresentation __EXPORT ScDocumentPool::GetPresentation(
+ const SfxPoolItem& rItem,
+ SfxItemPresentation ePresentation,
+ SfxMapUnit ePresentationMetric,
+ String& rText,
+ const IntlWrapper* pIntl ) const
+{
+ USHORT nW = rItem.Which();
+ String aStrYes ( ScGlobal::GetRscString(STR_YES) );
+ String aStrNo ( ScGlobal::GetRscString(STR_NO) );
+ String aStrSep = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(": "));
+
+ switch( nW )
+ {
+ case ATTR_PAGE_TOPDOWN:
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_PRINTDIR);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ((const SfxBoolItem&)rItem).GetValue() ?
+ ScGlobal::GetRscString(STR_SCATTR_PAGE_TOPDOWN) :
+ ScGlobal::GetRscString(STR_SCATTR_PAGE_LEFTRIGHT) ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ break;
+
+ case ATTR_PAGE_HEADERS:
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_HEADERS);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ((const SfxBoolItem&)rItem).GetValue() ? aStrYes : aStrNo ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ break;
+
+ case ATTR_PAGE_NULLVALS:
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_NULLVALS);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ((const SfxBoolItem&)rItem).GetValue() ? aStrYes : aStrNo ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ break;
+
+ case ATTR_PAGE_FORMULAS:
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_FORMULAS);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ((const SfxBoolItem&)rItem).GetValue() ? aStrYes : aStrNo ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ break;
+
+ case ATTR_PAGE_NOTES:
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_NOTES);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ((const SfxBoolItem&)rItem).GetValue() ? aStrYes : aStrNo ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ break;
+
+ case ATTR_PAGE_GRID:
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_GRID);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += ((const SfxBoolItem&)rItem).GetValue() ? aStrYes : aStrNo ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ break;
+
+ case ATTR_PAGE_SCALETOPAGES:
+ {
+ USHORT nPagNo = ((const SfxUInt16Item&)rItem).GetValue();
+
+ if( nPagNo )
+ {
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText.Assign( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALETOPAGES ) ).Append( aStrSep );
+ }
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ String aPages( ScGlobal::GetRscString( STR_SCATTR_PAGE_SCALE_PAGES ) );
+ aPages.SearchAndReplaceAscii( "%1", String::CreateFromInt32( nPagNo ) );
+ rText.Append( aPages );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ {
+ ePresentation = SFX_ITEM_PRESENTATION_NONE;
+ }
+ }
+ break;
+
+ case ATTR_PAGE_FIRSTPAGENO:
+ {
+ USHORT nPagNo = ((const SfxUInt16Item&)rItem).GetValue();
+
+ if( nPagNo )
+ {
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_FIRSTPAGENO);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += String::CreateFromInt32( nPagNo );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ {
+ ePresentation = SFX_ITEM_PRESENTATION_NONE;
+ }
+ }
+ break;
+
+ case ATTR_PAGE_SCALE:
+ {
+ USHORT nPercent = ((const SfxUInt16Item&)rItem).GetValue();
+
+ if( nPercent )
+ {
+ switch ( ePresentation )
+ {
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ScGlobal::GetRscString(STR_SCATTR_PAGE_SCALE);
+ rText += aStrSep;
+// break; // DURCHFALLEN!!!
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText += String::CreateFromInt32( nPercent );
+ rText += '%';
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ {
+ ePresentation = SFX_ITEM_PRESENTATION_NONE;
+ }
+ }
+ break;
+
+ case ATTR_PAGE_HEADERSET:
+ {
+ String aBuffer;
+
+ if( lcl_HFPresentation( rItem, ePresentation, GetMetric( nW ), ePresentationMetric, aBuffer, pIntl ) != SFX_ITEM_PRESENTATION_NONE )
+ {
+ rText = ScGlobal::GetRscString(STR_HEADER);
+ rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ( " ));
+ rText += aBuffer;
+ rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ) " ));
+ }
+ }
+ break;
+
+ case ATTR_PAGE_FOOTERSET:
+ {
+ String aBuffer;
+
+ if( lcl_HFPresentation( rItem, ePresentation, GetMetric( nW ), ePresentationMetric, aBuffer, pIntl ) != SFX_ITEM_PRESENTATION_NONE )
+ {
+ rText = ScGlobal::GetRscString(STR_FOOTER);
+ rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ( " ));
+ rText += aBuffer;
+ rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ) " ));
+ }
+ }
+ break;
+
+/*
+ case ATTR_PAGE_HEADERLEFT:
+ rText = "SID_SCATTR_PAGE_HEADERLEFT";
+ break;
+
+ case ATTR_PAGE_FOOTERLEFT:
+ rText = "SID_SCATTR_PAGE_FOOTERLEFT";
+ break;
+
+ case ATTR_PAGE_HEADERRIGHT:
+ rText = "SID_SCATTR_PAGE_HEADERRIGHT";
+ break;
+
+ case ATTR_PAGE_FOOTERRIGHT:
+ rText = "SID_SCATTR_PAGE_FOOTERRIGHT";
+ break;
+*/
+
+ default:
+ if ( !pIntl )
+ pIntl = ScGlobal::GetScIntlWrapper();
+ ePresentation = rItem.GetPresentation( ePresentation, GetMetric( nW ), ePresentationMetric, rText, pIntl );
+ break;
+ }
+
+ return ePresentation;
+}
+
+SfxMapUnit __EXPORT ScDocumentPool::GetMetric( USHORT nWhich ) const
+{
+ // eigene Attribute: Twips, alles andere 1/100 mm
+
+ if ( nWhich >= ATTR_STARTINDEX && nWhich <= ATTR_ENDINDEX )
+ return SFX_MAPUNIT_TWIP;
+ else
+ return SFX_MAPUNIT_100TH_MM;
+}
+
+
+
+
+
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
new file mode 100644
index 000000000000..d2c99c75a95e
--- /dev/null
+++ b/sc/source/core/data/documen2.cxx
@@ -0,0 +1,1300 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editeng.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdobj.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/virdev.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <tools/tenccvt.hxx>
+#include <tools/list.hxx>
+#include <rtl/crc.h>
+#include <basic/basmgr.hxx>
+
+#include "document.hxx"
+#include "table.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "pivot.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "globstr.hrc"
+#include "chartarr.hxx"
+#include "chartlock.hxx"
+#include "rechead.hxx"
+#include "global.hxx"
+#include "brdcst.hxx"
+#include "bcaslot.hxx"
+#include "adiasync.hxx"
+#include "addinlis.hxx"
+#include "chartlis.hxx"
+#include "markdata.hxx"
+#include "conditio.hxx"
+#include "validat.hxx"
+#include "progress.hxx"
+#include "detdata.hxx"
+#include "sc.hrc" // FID_DATACHANGED
+#include "ddelink.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "editutil.hxx"
+#include "hints.hxx"
+#include "dpobject.hxx"
+#include "scrdata.hxx"
+#include "poolhelp.hxx"
+#include "unoreflist.hxx"
+#include "listenercalls.hxx"
+#include "recursionhelper.hxx"
+#include "lookupcache.hxx"
+#include "externalrefmgr.hxx"
+#include "tabprotection.hxx"
+#include "formulaparserpool.hxx"
+#include "clipparam.hxx"
+
+using namespace com::sun::star;
+
+// pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
+// dtor plus helpers are convenient.
+struct ScLookupCacheMapImpl
+{
+ ScLookupCacheMap aCacheMap;
+ ~ScLookupCacheMapImpl()
+ {
+ freeCaches();
+ }
+ void clear()
+ {
+ freeCaches();
+ // Zap map.
+ ScLookupCacheMap aTmp;
+ aCacheMap.swap( aTmp);
+ }
+private:
+ void freeCaches()
+ {
+ for (ScLookupCacheMap::iterator it( aCacheMap.begin()); it != aCacheMap.end(); ++it)
+ delete (*it).second;
+ }
+};
+
+// STATIC DATA -----------------------------------------------------------
+
+ScDocument::ScDocument( ScDocumentMode eMode,
+ SfxObjectShell* pDocShell ) :
+ xServiceManager( ::comphelper::getProcessServiceFactory() ),
+ mpUndoManager( NULL ),
+ pEditEngine( NULL ),
+ pNoteEngine( NULL ),
+ pNoteItemPool( NULL ),
+ pShell( pDocShell ),
+ pPrinter( NULL ),
+ pVirtualDevice_100th_mm( NULL ),
+ pDrawLayer( NULL ),
+ pColorTable( NULL ),
+ pCondFormList( NULL ),
+ pValidationList( NULL ),
+ pFormatExchangeList( NULL ),
+ pDPCollection( NULL ),
+ pLinkManager( NULL ),
+ pFormulaTree( NULL ),
+ pEOFormulaTree( NULL ),
+ pFormulaTrack( NULL ),
+ pEOFormulaTrack( NULL ),
+ pOtherObjects( NULL ),
+ pClipData( NULL ),
+ pDetOpList(NULL),
+ pChangeTrack( NULL ),
+ pUnoBroadcaster( NULL ),
+ pUnoListenerCalls( NULL ),
+ pUnoRefUndoList( NULL ),
+ pChangeViewSettings( NULL ),
+ pScriptTypeData( NULL ),
+ pCacheFieldEditEngine( NULL ),
+ pDocProtection( NULL ),
+ mpClipParam( NULL),
+ pExternalRefMgr( NULL ),
+ pViewOptions( NULL ),
+ pDocOptions( NULL ),
+ pExtDocOptions( NULL ),
+ pConsolidateDlgData( NULL ),
+ pRecursionHelper( NULL ),
+ pAutoNameCache( NULL ),
+ pLookupCacheMapImpl( NULL ),
+ nUnoObjectId( 0 ),
+ nRangeOverflowType( 0 ),
+ aCurTextWidthCalcPos(MAXCOL,0,0),
+ nFormulaCodeInTree(0),
+ nXMLImportedFormulaCount( 0 ),
+ nInterpretLevel(0),
+ nMacroInterpretLevel(0),
+ nInterpreterTableOpLevel(0),
+ nMaxTableNumber( 0 ),
+ nSrcVer( SC_CURRENT_VERSION ),
+ nSrcMaxRow( MAXROW ),
+ nFormulaTrackCount(0),
+ nHardRecalcState(0),
+ nVisibleTab( 0 ),
+ eLinkMode(LM_UNKNOWN),
+ bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
+ bAutoCalcShellDisabled( FALSE ),
+ bForcedFormulaPending( FALSE ),
+ bCalculatingFormulaTree( FALSE ),
+ bIsClip( eMode == SCDOCMODE_CLIP ),
+ bIsUndo( eMode == SCDOCMODE_UNDO ),
+ bIsVisible( FALSE ),
+ bIsEmbedded( FALSE ),
+// bNoSetDirty( TRUE ),
+ bNoSetDirty( FALSE ),
+ bInsertingFromOtherDoc( FALSE ),
+ bLoadingMedium( false ),
+ bImportingXML( false ),
+ bXMLFromWrapper( FALSE ),
+ bCalcingAfterLoad( FALSE ),
+ bNoListening( FALSE ),
+ bIdleDisabled( FALSE ),
+ bInLinkUpdate( FALSE ),
+ bChartListenerCollectionNeedsUpdate( FALSE ),
+ bHasForcedFormulas( FALSE ),
+ bInDtorClear( FALSE ),
+ bExpandRefs( FALSE ),
+ bDetectiveDirty( FALSE ),
+ nMacroCallMode( SC_MACROCALL_ALLOWED ),
+ bHasMacroFunc( FALSE ),
+ nVisSpellState( 0 ),
+ nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
+ nAsianKerning(SC_ASIANKERNING_INVALID),
+ bSetDrawDefaults( FALSE ),
+ bPastingDrawFromOtherDoc( FALSE ),
+ nInDdeLinkUpdate( 0 ),
+ bInUnoBroadcast( FALSE ),
+ bInUnoListenerCall( FALSE ),
+ eGrammar( formula::FormulaGrammar::GRAM_NATIVE ),
+ bStyleSheetUsageInvalid( TRUE ),
+ mbUndoEnabled( true ),
+ mbAdjustHeightEnabled( true ),
+ mbExecuteLinkEnabled( true ),
+ mbChangeReadOnlyEnabled( false ),
+ mbStreamValidLocked( false ),
+ mnNamedRangesLockCount( 0 )
+{
+ SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
+
+ eSrcSet = gsl_getSystemTextEncoding();
+
+ if ( eMode == SCDOCMODE_DOCUMENT )
+ {
+ if ( pDocShell )
+ pLinkManager = new sfx2::LinkManager( pDocShell );
+
+ xPoolHelper = new ScPoolHelper( this );
+
+ pTab[0] = NULL;
+ pBASM = new ScBroadcastAreaSlotMachine( this );
+ pChartListenerCollection = new ScChartListenerCollection( this );
+ pRefreshTimerControl = new ScRefreshTimerControl;
+ }
+ else
+ {
+ pTab[0] = NULL;
+ pBASM = NULL;
+ pChartListenerCollection = NULL;
+ pRefreshTimerControl = NULL;
+ }
+
+ for (SCTAB i=1; i<=MAXTAB; i++)
+ pTab[i] = NULL;
+
+ pRangeName = new ScRangeName( 4, 4, FALSE, this );
+ pDBCollection = new ScDBCollection( 4, 4, FALSE, this );
+ pSelectionAttr = NULL;
+ pChartCollection = new ScChartCollection;
+ apTemporaryChartLock = std::auto_ptr< ScTemporaryChartLock >( new ScTemporaryChartLock(this) );
+ xColNameRanges = new ScRangePairList;
+ xRowNameRanges = new ScRangePairList;
+ ImplCreateOptions();
+ // languages for a visible document are set by docshell later (from options)
+ SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
+
+ aTrackTimer.SetTimeoutHdl( LINK( this, ScDocument, TrackTimeHdl ) );
+ aTrackTimer.SetTimeout( 100 );
+}
+
+sfx2::LinkManager* ScDocument::GetLinkManager() const
+{
+ if ( bAutoCalc && !pLinkManager && pShell)
+ {
+ pLinkManager = new sfx2::LinkManager( pShell );
+ }
+ return pLinkManager;
+}
+
+
+void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram )
+{
+ DBG_ASSERT(
+ eGram == formula::FormulaGrammar::GRAM_ODFF ||
+ eGram == formula::FormulaGrammar::GRAM_PODF,
+ "ScDocument::SetStorageGrammar: wrong storage grammar");
+
+ eStorageGrammar = eGram;
+
+ // FIXME: the XML import shouldn't strip brackets, the compiler should
+ // digest them instead, which could also speedup reference recognition
+ // during import.
+
+ eXmlImportGrammar = formula::FormulaGrammar::mergeToGrammar( eGram,
+ formula::FormulaGrammar::CONV_OOO);
+}
+
+
+void ScDocument::SetDocVisible( BOOL bSet )
+{
+ // called from view ctor - only for a visible document,
+ // each new sheet's RTL flag is initialized from the locale
+ bIsVisible = bSet;
+}
+
+
+sal_uInt32 ScDocument::GetDocumentID() const
+{
+ const ScDocument* pThis = this;
+ sal_uInt32 nCrc = rtl_crc32( 0, &pThis, sizeof(ScDocument*) );
+ // the this pointer only might not be sufficient
+ nCrc = rtl_crc32( nCrc, &pShell, sizeof(SfxObjectShell*) );
+ return nCrc;
+}
+
+
+void ScDocument::StartChangeTracking()
+{
+ if (!pChangeTrack)
+ pChangeTrack = new ScChangeTrack( this );
+}
+
+void ScDocument::EndChangeTracking()
+{
+ delete pChangeTrack;
+ pChangeTrack = NULL;
+}
+
+void ScDocument::SetChangeTrack( ScChangeTrack* pTrack )
+{
+ DBG_ASSERT( pTrack->GetDocument() == this, "SetChangeTrack: different documents" );
+ if ( !pTrack || pTrack == pChangeTrack || pTrack->GetDocument() != this )
+ return ;
+ EndChangeTracking();
+ pChangeTrack = pTrack;
+}
+
+
+IMPL_LINK( ScDocument, TrackTimeHdl, Timer*, EMPTYARG )
+{
+ if ( ScDdeLink::IsInUpdate() ) // nicht verschachteln
+ {
+ aTrackTimer.Start(); // spaeter nochmal versuchen
+ }
+ else if (pShell) // ausfuehren
+ {
+ TrackFormulas();
+ pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
+ ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
+
+ // modified...
+
+ if (!pShell->IsModified())
+ {
+ pShell->SetModified( TRUE );
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_SAVEDOC );
+ pBindings->Invalidate( SID_DOC_MODIFIED );
+ }
+ }
+ }
+
+ return 0;
+}
+
+void ScDocument::StartTrackTimer()
+{
+ if (!aTrackTimer.IsActive()) // nicht ewig aufschieben
+ aTrackTimer.Start();
+}
+
+ScDocument::~ScDocument()
+{
+ DBG_ASSERT( !bInLinkUpdate, "bInLinkUpdate in dtor" );
+
+ bInDtorClear = TRUE;
+
+ // first of all disable all refresh timers by deleting the control
+ if ( pRefreshTimerControl )
+ { // To be sure there isn't anything running do it with a protector,
+ // this ensures also that nothing needs the control anymore.
+ ScRefreshTimerProtector aProt( GetRefreshTimerControlAddress() );
+ delete pRefreshTimerControl, pRefreshTimerControl = NULL;
+ }
+
+ // Links aufrauemen
+
+ if ( GetLinkManager() )
+ {
+ // BaseLinks freigeben
+ for ( USHORT n = pLinkManager->GetServers().Count(); n; )
+ pLinkManager->GetServers()[ --n ]->Closed();
+
+ if ( pLinkManager->GetLinks().Count() )
+ pLinkManager->Remove( 0, pLinkManager->GetLinks().Count() );
+ }
+
+ 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 );
+ 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
+ delete pBASM; // BroadcastAreaSlotMachine
+ pBASM = NULL;
+
+ if (pUnoBroadcaster)
+ {
+ delete pUnoBroadcaster; // broadcasted nochmal SFX_HINT_DYING
+ pUnoBroadcaster = NULL;
+ }
+
+ delete pUnoRefUndoList;
+ delete pUnoListenerCalls;
+
+ Clear( sal_True ); // TRUE = from destructor (needed for SdrModel::ClearModel)
+
+ if (pCondFormList)
+ {
+ pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
+ DELETEZ(pCondFormList);
+ }
+ if (pValidationList)
+ {
+ pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
+ DELETEZ(pValidationList);
+ }
+ delete pRangeName;
+ delete pDBCollection;
+ delete pSelectionAttr;
+ apTemporaryChartLock.reset();
+ delete pChartCollection;
+ DeleteDrawLayer();
+ delete pFormatExchangeList;
+ delete pPrinter;
+ ImplDeleteOptions();
+ delete pConsolidateDlgData;
+ delete pLinkManager;
+ delete pClipData;
+ delete pDetOpList; // loescht auch die Eintraege
+ delete pChangeTrack;
+ delete pEditEngine;
+ delete pNoteEngine;
+ SfxItemPool::Free(pNoteItemPool);
+ delete pChangeViewSettings; // und weg damit
+ delete pVirtualDevice_100th_mm;
+
+ delete pDPCollection;
+
+ // delete the EditEngine before destroying the xPoolHelper
+ delete pCacheFieldEditEngine;
+
+ if ( xPoolHelper.isValid() && !bIsClip )
+ xPoolHelper->SourceDocumentGone();
+ xPoolHelper.unbind();
+
+ DeleteColorTable();
+ delete pScriptTypeData;
+ delete pOtherObjects;
+ delete pRecursionHelper;
+
+ DBG_ASSERT( !pAutoNameCache, "AutoNameCache still set in dtor" );
+}
+
+void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
+{
+ DBG_ASSERT(bIsClip, "InitClipPtrs und nicht bIsClip");
+
+ if (pCondFormList)
+ {
+ pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
+ DELETEZ(pCondFormList);
+ }
+ if (pValidationList)
+ {
+ pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
+ DELETEZ(pValidationList);
+ }
+
+ Clear();
+
+ xPoolHelper = pSourceDoc->xPoolHelper;
+
+ // bedingte Formate / Gueltigkeiten
+ //! Vorlagen kopieren?
+ const ScConditionalFormatList* pSourceCond = pSourceDoc->pCondFormList;
+ if ( pSourceCond )
+ pCondFormList = new ScConditionalFormatList(this, *pSourceCond);
+ const ScValidationDataList* pSourceValid = pSourceDoc->pValidationList;
+ if ( pSourceValid )
+ pValidationList = new ScValidationDataList(this, *pSourceValid);
+
+ // Links in Stream speichern
+ delete pClipData;
+ if (pSourceDoc->HasDdeLinks())
+ {
+ pClipData = new SvMemoryStream;
+ pSourceDoc->SaveDdeLinks(*pClipData);
+ }
+ else
+ pClipData = NULL;
+
+ // Options pointers exist (ImplCreateOptions) for any document.
+ // Must be copied for correct results in OLE objects (#i42666#).
+ SetDocOptions( pSourceDoc->GetDocOptions() );
+ SetViewOptions( pSourceDoc->GetViewOptions() );
+}
+
+SvNumberFormatter* ScDocument::GetFormatTable() const
+{
+ return xPoolHelper->GetFormTable();
+}
+
+SfxItemPool* ScDocument::GetEditPool() const
+{
+ return xPoolHelper->GetEditPool();
+}
+
+SfxItemPool* ScDocument::GetEnginePool() const
+{
+ return xPoolHelper->GetEnginePool();
+}
+
+ScFieldEditEngine& ScDocument::GetEditEngine()
+{
+ if ( !pEditEngine )
+ {
+ pEditEngine = new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
+ pEditEngine->SetUpdateMode( FALSE );
+ pEditEngine->EnableUndo( FALSE );
+ pEditEngine->SetRefMapMode( MAP_100TH_MM );
+ pEditEngine->SetForbiddenCharsTable( xForbiddenCharacters );
+ }
+ return *pEditEngine;
+}
+
+ScNoteEditEngine& ScDocument::GetNoteEngine()
+{
+ if ( !pNoteEngine )
+ {
+ pNoteEngine = new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
+ pNoteEngine->SetUpdateMode( FALSE );
+ pNoteEngine->EnableUndo( FALSE );
+ pNoteEngine->SetRefMapMode( MAP_100TH_MM );
+ pNoteEngine->SetForbiddenCharsTable( xForbiddenCharacters );
+ const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet();
+ SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() );
+ ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
+ pNoteEngine->SetDefaults( pEEItemSet ); // edit engine takes ownership
+ }
+ return *pNoteEngine;
+}
+
+//UNUSED2009-05 SfxItemPool& ScDocument::GetNoteItemPool()
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( !pNoteItemPool )
+//UNUSED2009-05 pNoteItemPool = new SfxItemPool(SdrObject::GetGlobalDrawObjectItemPool());
+//UNUSED2009-05 return *pNoteItemPool;
+//UNUSED2009-05 }
+
+void ScDocument::ResetClip( ScDocument* pSourceDoc, const ScMarkData* pMarks )
+{
+ if (bIsClip)
+ {
+ InitClipPtrs(pSourceDoc);
+
+ for (SCTAB i = 0; i <= MAXTAB; i++)
+ if (pSourceDoc->pTab[i])
+ if (!pMarks || pMarks->GetTableSelect(i))
+ {
+ String aString;
+ pSourceDoc->pTab[i]->GetName(aString);
+ pTab[i] = new ScTable(this, i, aString);
+ pTab[i]->SetLayoutRTL( pSourceDoc->pTab[i]->IsLayoutRTL() );
+ nMaxTableNumber = i+1;
+ }
+ }
+ else
+ {
+ DBG_ERROR("ResetClip");
+ }
+}
+
+void ScDocument::ResetClip( ScDocument* pSourceDoc, SCTAB nTab )
+{
+ if (bIsClip)
+ {
+ InitClipPtrs(pSourceDoc);
+
+ pTab[nTab] = new ScTable(this, nTab,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("baeh")));
+ if (pSourceDoc->pTab[nTab])
+ pTab[nTab]->SetLayoutRTL( pSourceDoc->pTab[nTab]->IsLayoutRTL() );
+ nMaxTableNumber = nTab+1;
+ }
+ else
+ {
+ DBG_ERROR("ResetClip");
+ }
+}
+
+void ScDocument::DeleteNumberFormat( const sal_uInt32* /* pDelKeys */, sal_uInt32 /* nCount */ )
+{
+/*
+ for (ULONG i = 0; i < nCount; i++)
+ xPoolHelper->GetFormTable()->DeleteEntry(pDelKeys[i]);
+*/
+}
+
+void ScDocument::PutCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScBaseCell* pCell, ULONG nFormatIndex, BOOL bForceTab )
+{
+ if (VALIDTAB(nTab))
+ {
+ if ( bForceTab && !pTab[nTab] )
+ {
+ BOOL bExtras = !bIsUndo; // Spaltenbreiten, Zeilenhoehen, Flags
+
+ pTab[nTab] = new ScTable(this, nTab,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
+ bExtras, bExtras);
+ }
+
+ if (pTab[nTab])
+ pTab[nTab]->PutCell( nCol, nRow, nFormatIndex, pCell );
+ }
+}
+
+//UNUSED2009-05 void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell,
+//UNUSED2009-05 ULONG nFormatIndex, BOOL bForceTab )
+//UNUSED2009-05 {
+//UNUSED2009-05 SCTAB nTab = rPos.Tab();
+//UNUSED2009-05 if ( bForceTab && !pTab[nTab] )
+//UNUSED2009-05 {
+//UNUSED2009-05 BOOL bExtras = !bIsUndo; // Spaltenbreiten, Zeilenhoehen, Flags
+//UNUSED2009-05
+//UNUSED2009-05 pTab[nTab] = new ScTable(this, nTab,
+//UNUSED2009-05 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
+//UNUSED2009-05 bExtras, bExtras);
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 if (pTab[nTab])
+//UNUSED2009-05 pTab[nTab]->PutCell( rPos, nFormatIndex, pCell );
+//UNUSED2009-05 }
+
+BOOL ScDocument::GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
+ BOOL bNotes ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ {
+ BOOL bAny = pTab[nTab]->GetPrintArea( rEndCol, rEndRow, bNotes );
+ if (pDrawLayer)
+ {
+ ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
+ if (DrawGetPrintArea( aDrawRange, TRUE, TRUE ))
+ {
+ if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
+ if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
+ bAny = TRUE;
+ }
+ }
+ return bAny;
+ }
+
+ rEndCol = 0;
+ rEndRow = 0;
+ return FALSE;
+}
+
+BOOL ScDocument::GetPrintAreaHor( SCTAB nTab, SCROW nStartRow, SCROW nEndRow,
+ SCCOL& rEndCol, BOOL bNotes ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ {
+ BOOL bAny = pTab[nTab]->GetPrintAreaHor( nStartRow, nEndRow, rEndCol, bNotes );
+ if (pDrawLayer)
+ {
+ ScRange aDrawRange(0,nStartRow,nTab, MAXCOL,nEndRow,nTab);
+ if (DrawGetPrintArea( aDrawRange, TRUE, FALSE ))
+ {
+ if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
+ bAny = TRUE;
+ }
+ }
+ return bAny;
+ }
+
+ rEndCol = 0;
+ return FALSE;
+}
+
+BOOL ScDocument::GetPrintAreaVer( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol,
+ SCROW& rEndRow, BOOL bNotes ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ {
+ BOOL bAny = pTab[nTab]->GetPrintAreaVer( nStartCol, nEndCol, rEndRow, bNotes );
+ if (pDrawLayer)
+ {
+ ScRange aDrawRange(nStartCol,0,nTab, nEndCol,MAXROW,nTab);
+ if (DrawGetPrintArea( aDrawRange, FALSE, TRUE ))
+ {
+ if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
+ bAny = TRUE;
+ }
+ }
+ return bAny;
+ }
+
+ rEndRow = 0;
+ return FALSE;
+}
+
+BOOL ScDocument::GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ {
+ BOOL bAny = pTab[nTab]->GetDataStart( rStartCol, rStartRow );
+ if (pDrawLayer)
+ {
+ ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
+ if (DrawGetPrintArea( aDrawRange, TRUE, TRUE ))
+ {
+ if (aDrawRange.aStart.Col()<rStartCol) rStartCol=aDrawRange.aStart.Col();
+ if (aDrawRange.aStart.Row()<rStartRow) rStartRow=aDrawRange.aStart.Row();
+ bAny = TRUE;
+ }
+ }
+ return bAny;
+ }
+
+ rStartCol = 0;
+ rStartRow = 0;
+ return FALSE;
+}
+
+BOOL ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
+{
+ if (nOldPos == nNewPos) return FALSE;
+ BOOL bValid = FALSE;
+ if (VALIDTAB(nOldPos))
+ {
+ if (pTab[nOldPos])
+ {
+ SCTAB nTabCount = GetTableCount();
+ if (nTabCount > 1)
+ {
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ SetNoListening( TRUE );
+ ScProgress* pProgress = new ScProgress( GetDocumentShell(),
+ ScGlobal::GetRscString(STR_UNDO_MOVE_TAB), GetCodeCount() );
+ if (nNewPos == SC_TAB_APPEND)
+ nNewPos = nTabCount-1;
+
+ // Referenz-Updaterei
+ //! mit UpdateReference zusammenfassen!
+
+ SCsTAB nDz = ((SCsTAB)nNewPos) - (SCsTAB)nOldPos;
+ ScRange aSourceRange( 0,0,nOldPos, MAXCOL,MAXROW,nOldPos );
+ pRangeName->UpdateTabRef(nOldPos, 3, nNewPos);
+ pDBCollection->UpdateMoveTab( nOldPos, nNewPos );
+ xColNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
+ xRowNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
+ if (pDPCollection)
+ pDPCollection->UpdateReference( URM_REORDER, aSourceRange, 0,0,nDz );
+ if (pDetOpList)
+ pDetOpList->UpdateReference( this, URM_REORDER, aSourceRange, 0,0,nDz );
+ UpdateChartRef( URM_REORDER,
+ 0,0,nOldPos, MAXCOL,MAXROW,nOldPos, 0,0,nDz );
+ UpdateRefAreaLinks( URM_REORDER, aSourceRange, 0,0,nDz );
+ if ( pCondFormList )
+ pCondFormList->UpdateMoveTab( nOldPos, nNewPos );
+ if ( pValidationList )
+ pValidationList->UpdateMoveTab( nOldPos, nNewPos );
+ if ( pUnoBroadcaster )
+ pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_REORDER,
+ aSourceRange, 0,0,nDz ) );
+
+ ScTable* pSaveTab = pTab[nOldPos];
+ SCTAB i;
+ for (i = nOldPos + 1; i < nTabCount; i++)
+ pTab[i - 1] = pTab[i];
+ pTab[i-1] = NULL;
+ for (i = nTabCount - 1; i > nNewPos; i--)
+ pTab[i] = pTab[i - 1];
+ pTab[nNewPos] = pSaveTab;
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateMoveTab( nOldPos, nNewPos, i, *pProgress );
+ delete pProgress; // freimachen fuer evtl. andere
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateCompile();
+ SetNoListening( FALSE );
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartAllListeners();
+ // #81844# sheet names of references may not be valid until sheet is moved
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+ SetDirty();
+ SetAutoCalc( bOldAutoCalc );
+
+ if (pDrawLayer)
+ DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
+
+ bValid = TRUE;
+ }
+ }
+ }
+ return bValid;
+}
+
+BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyMarked )
+{
+ if (SC_TAB_APPEND == nNewPos ) nNewPos = nMaxTableNumber;
+ String aName;
+ GetName(nOldPos, aName);
+
+ // vorneweg testen, ob der Prefix als gueltig erkannt wird
+ // wenn nicht, nur doppelte vermeiden
+ BOOL bPrefix = ValidTabName( aName );
+ DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
+ SCTAB nDummy;
+
+ CreateValidTabName(aName);
+
+ BOOL bValid;
+ if (bPrefix)
+ bValid = ( ValidNewTabName(aName) && (nMaxTableNumber <= MAXTAB) );
+ else
+ bValid = ( !GetTable( aName, nDummy ) && (nMaxTableNumber <= MAXTAB) );
+
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ if (bValid)
+ {
+ if (nNewPos == nMaxTableNumber)
+ {
+ pTab[nMaxTableNumber] = new ScTable(this, nMaxTableNumber, aName);
+ ++nMaxTableNumber;
+ }
+ else
+ {
+ if (VALIDTAB(nNewPos) && (nNewPos < nMaxTableNumber))
+ {
+ SetNoListening( TRUE );
+
+ ScRange aRange( 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB );
+ xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
+ xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
+ pRangeName->UpdateTabRef(nNewPos, 1);
+ pDBCollection->UpdateReference(
+ URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
+ if (pDPCollection)
+ pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
+ if (pDetOpList)
+ pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
+ UpdateChartRef( URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
+ UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
+ if ( pUnoBroadcaster )
+ pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
+
+ SCTAB i;
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i] && i != nOldPos)
+ pTab[i]->UpdateInsertTab(nNewPos);
+ for (i = nMaxTableNumber; i > nNewPos; i--)
+ pTab[i] = pTab[i - 1];
+ if (nNewPos <= nOldPos)
+ nOldPos++;
+ pTab[nNewPos] = new ScTable(this, nNewPos, aName);
+ ++nMaxTableNumber;
+ bValid = TRUE;
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i] && i != nOldPos && i != nNewPos)
+ pTab[i]->UpdateCompile();
+ SetNoListening( FALSE );
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i] && i != nOldPos && i != nNewPos)
+ pTab[i]->StartAllListeners();
+
+ // update conditional formats after table is inserted
+ if ( pCondFormList )
+ pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
+ if ( pValidationList )
+ pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
+ // #81844# sheet names of references may not be valid until sheet is copied
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+ }
+ else
+ bValid = FALSE;
+ }
+ }
+ if (bValid)
+ {
+ SetNoListening( TRUE ); // noch nicht bei CopyToTable/Insert
+ pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
+ pTab[nNewPos], pOnlyMarked );
+ pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor());
+
+ SCsTAB nDz;
+/* if (nNewPos < nOldPos)
+ nDz = ((short)nNewPos) - (short)nOldPos + 1;
+ else
+*/ nDz = ((short)nNewPos) - (short)nOldPos;
+ pTab[nNewPos]->UpdateReference(URM_COPY, 0, 0, nNewPos , MAXCOL, MAXROW,
+ nNewPos, 0, 0, nDz, NULL);
+
+ pTab[nNewPos]->UpdateInsertTabAbs(nNewPos); // alle abs. um eins hoch!!
+ pTab[nOldPos]->UpdateInsertTab(nNewPos);
+
+ pTab[nOldPos]->UpdateCompile();
+ pTab[nNewPos]->UpdateCompile( TRUE ); // #67996# maybe already compiled in Clone, but used names need recompilation
+ SetNoListening( FALSE );
+ pTab[nOldPos]->StartAllListeners();
+ pTab[nNewPos]->StartAllListeners();
+ SetDirty();
+ SetAutoCalc( bOldAutoCalc );
+
+ if (pDrawLayer)
+ DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
+
+ pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
+ pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
+ }
+ else
+ SetAutoCalc( bOldAutoCalc );
+ return bValid;
+}
+
+void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource );
+
+ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
+ SCTAB nDestPos, BOOL bInsertNew,
+ BOOL bResultsOnly )
+{
+ ULONG nRetVal = 1; // 0 => Fehler 1 = ok
+ // 2 => RefBox, 3 => NameBox
+ // 4 => beides
+ BOOL bValid = TRUE;
+ if (bInsertNew) // neu einfuegen
+ {
+ String aName;
+ pSrcDoc->GetName(nSrcPos, aName);
+ CreateValidTabName(aName);
+ bValid = InsertTab(nDestPos, aName);
+ }
+ else // bestehende Tabelle ersetzen
+ {
+ if (VALIDTAB(nDestPos) && pTab[nDestPos])
+ {
+ pTab[nDestPos]->DeleteArea( 0,0, MAXCOL,MAXROW, IDF_ALL );
+ }
+ else
+ bValid = FALSE;
+ }
+
+ if (bValid)
+ {
+ BOOL bOldAutoCalcSrc = FALSE;
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ SetNoListening( TRUE );
+ if ( bResultsOnly )
+ {
+ bOldAutoCalcSrc = pSrcDoc->GetAutoCalc();
+ pSrcDoc->SetAutoCalc( TRUE ); // falls was berechnet werden muss
+ }
+
+ {
+ NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
+
+ nDestPos = Min(nDestPos, (SCTAB)(GetTableCount() - 1));
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( pBASM);
+ pSrcDoc->pTab[nSrcPos]->CopyToTable(0, 0, MAXCOL, MAXROW,
+ ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
+ FALSE, pTab[nDestPos] );
+ }
+ }
+ pTab[nDestPos]->SetTabNo(nDestPos);
+
+ if ( !bResultsOnly )
+ {
+ BOOL bNamesLost = FALSE;
+ USHORT nSrcRangeNames = pSrcDoc->pRangeName->GetCount();
+ // array containing range names which might need update of indices
+ ScRangeData** pSrcRangeNames = nSrcRangeNames ? new ScRangeData* [nSrcRangeNames] : NULL;
+ // the index mapping thereof
+ ScRangeData::IndexMap aSrcRangeMap;
+ BOOL bRangeNameReplace = FALSE;
+
+ // find named ranges that are used in the source sheet
+ std::set<USHORT> aUsedNames;
+ pSrcDoc->pTab[nSrcPos]->FindRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aUsedNames );
+
+ for (USHORT i = 0; i < nSrcRangeNames; i++) //! DB-Bereiche Pivot-Bereiche auch !!!
+ {
+ ScRangeData* pSrcData = (*pSrcDoc->pRangeName)[i];
+ USHORT nOldIndex = pSrcData->GetIndex();
+ bool bInUse = ( aUsedNames.find(nOldIndex) != aUsedNames.end() );
+ if (bInUse)
+ {
+ USHORT nExisting = 0;
+ if ( pRangeName->SearchName( pSrcData->GetName(), nExisting ) )
+ {
+ // the name exists already in the destination document
+ // -> use the existing name, but show a warning
+ // (when refreshing links, the existing name is used and the warning not shown)
+
+ ScRangeData* pExistingData = (*pRangeName)[nExisting];
+ USHORT nExistingIndex = pExistingData->GetIndex();
+
+ pSrcRangeNames[i] = NULL; // don't modify the named range
+ aSrcRangeMap.insert(
+ ScRangeData::IndexMap::value_type(nOldIndex, nExistingIndex));
+ bRangeNameReplace = TRUE;
+ bNamesLost = TRUE;
+ }
+ else
+ {
+ ScRangeData* pData = new ScRangeData( *pSrcData );
+ pData->SetDocument(this);
+ if ( pRangeName->FindIndex( pData->GetIndex() ) )
+ pData->SetIndex(0); // need new index, done in Insert
+ if (!pRangeName->Insert(pData))
+ {
+ DBG_ERROR("can't insert name"); // shouldn't happen
+ delete pData;
+ }
+ else
+ {
+ pData->TransferTabRef( nSrcPos, nDestPos );
+ pSrcRangeNames[i] = pData;
+ USHORT nNewIndex = pData->GetIndex();
+ aSrcRangeMap.insert(
+ ScRangeData::IndexMap::value_type(nOldIndex, nNewIndex));
+ if ( !bRangeNameReplace )
+ bRangeNameReplace = ( nOldIndex != nNewIndex );
+ }
+ }
+ }
+ else
+ {
+ pSrcRangeNames[i] = NULL;
+ //aSrcRangeMap.SetPair( i, 0, 0 ); // not needed, defaulted
+ }
+ }
+ if ( bRangeNameReplace )
+ {
+ // first update all inserted named formulas if they contain other
+ // range names and used indices changed
+ for (USHORT i = 0; i < nSrcRangeNames; i++) //! DB-Bereiche Pivot-Bereiche auch
+ {
+ if ( pSrcRangeNames[i] )
+ pSrcRangeNames[i]->ReplaceRangeNamesInUse( aSrcRangeMap );
+ }
+ // then update the formulas, they might need the just updated range names
+ pTab[nDestPos]->ReplaceRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aSrcRangeMap );
+ }
+ if ( pSrcRangeNames )
+ delete [] pSrcRangeNames;
+
+ SCsTAB nDz = ((SCsTAB)nDestPos) - (SCsTAB)nSrcPos;
+ pTab[nDestPos]->UpdateReference(URM_COPY, 0, 0, nDestPos,
+ MAXCOL, MAXROW, nDestPos,
+ 0, 0, nDz, NULL);
+ // Test for outside absolute references for info box
+ BOOL bIsAbsRef = pSrcDoc->pTab[nSrcPos]->TestTabRefAbs(nSrcPos);
+ // Readjust self-contained absolute references to this sheet
+ pTab[nDestPos]->TestTabRefAbs(nSrcPos);
+ if (bIsAbsRef)
+ {
+ nRetVal += 1;
+ // InfoBox AbsoluteRefs sind moeglicherweise nicht mehr korrekt!!
+ }
+ if (bNamesLost)
+ {
+ nRetVal += 2;
+ // message: duplicate names
+ }
+ pTab[nDestPos]->CompileAll();
+ }
+
+ SetNoListening( FALSE );
+ if ( !bResultsOnly )
+ pTab[nDestPos]->StartAllListeners();
+ SetDirty( ScRange( 0, 0, nDestPos, MAXCOL, MAXROW, nDestPos));
+
+ if ( bResultsOnly )
+ pSrcDoc->SetAutoCalc( bOldAutoCalcSrc );
+ SetAutoCalc( bOldAutoCalc );
+
+ // Drawing kopieren
+
+ if (bInsertNew)
+ TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
+
+ pTab[nDestPos]->SetPendingRowHeights( pSrcDoc->pTab[nSrcPos]->IsPendingRowHeights() );
+ }
+ if (!bValid)
+ nRetVal = 0;
+ BOOL bVbaEnabled = IsInVBAMode();
+
+ if ( bVbaEnabled )
+ {
+ SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL;
+ if ( pSrcShell )
+ {
+ StarBASIC* pStarBASIC = pSrcShell ? pSrcShell->GetBasic() : NULL;
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( pSrcShell && pSrcShell->GetBasicManager()->GetName().Len() > 0 )
+ {
+ aLibName = pSrcShell->GetBasicManager()->GetName();
+ pStarBASIC = pSrcShell->GetBasicManager()->GetLib( aLibName );
+ }
+
+ String sCodeName;
+ String sSource;
+ uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer();
+ uno::Reference< container::XNameContainer > xLib;
+ if( xLibContainer.is() )
+ {
+ uno::Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+
+ if( xLib.is() )
+ {
+ String sSrcCodeName;
+ pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName );
+ rtl::OUString sRTLSource;
+ xLib->getByName( sSrcCodeName ) >>= sRTLSource;
+ sSource = sRTLSource;
+ }
+ VBA_InsertModule( *this, nDestPos, sCodeName, sSource );
+ }
+ }
+
+ return nRetVal;
+}
+
+// ----------------------------------------------------------------------------
+
+void ScDocument::SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const USHORT nError)
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->SetError( nCol, nRow, nError );
+}
+
+void ScDocument::EraseNonUsedSharedNames(USHORT nLevel)
+{
+ for (USHORT i = 0; i < pRangeName->GetCount(); i++)
+ {
+ ScRangeData* pRangeData = (*pRangeName)[i];
+ if (pRangeData && pRangeData->HasType(RT_SHARED))
+ {
+ String aName;
+ pRangeData->GetName(aName);
+ aName.Erase(0, 6); // !!! vgl. Table4, FillFormula !!
+ USHORT nInd = (USHORT) aName.ToInt32();
+ if (nInd <= nLevel)
+ {
+ USHORT nIndex = pRangeData->GetIndex();
+ BOOL bInUse = FALSE;
+ for (SCTAB j = 0; !bInUse && (j <= MAXTAB); j++)
+ {
+ if (pTab[j])
+ bInUse = pTab[j]->IsRangeNameInUse(0, 0, MAXCOL-1, MAXROW-1,
+ nIndex);
+ }
+ if (!bInUse)
+ pRangeName->AtFree(i);
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
+{
+ delete pConsolidateDlgData;
+
+ if ( pData )
+ pConsolidateDlgData = new ScConsolidateParam( *pData );
+ else
+ pConsolidateDlgData = NULL;
+}
+
+void ScDocument::SetChangeViewSettings(const ScChangeViewSettings& rNew)
+{
+ if (pChangeViewSettings==NULL)
+ pChangeViewSettings = new ScChangeViewSettings;
+
+ DBG_ASSERT( pChangeViewSettings, "Oops. No ChangeViewSettings :-( by!" );
+
+ *pChangeViewSettings=rNew;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFieldEditEngine* ScDocument::CreateFieldEditEngine()
+{
+ ScFieldEditEngine* pNewEditEngine = NULL;
+ if (!pCacheFieldEditEngine)
+ {
+ pNewEditEngine = new ScFieldEditEngine( GetEnginePool(),
+ GetEditPool(), FALSE );
+ }
+ else
+ {
+ if ( !bImportingXML )
+ {
+ // #i66209# previous use might not have restored update mode,
+ // ensure same state as for a new EditEngine (UpdateMode = TRUE)
+ if ( !pCacheFieldEditEngine->GetUpdateMode() )
+ pCacheFieldEditEngine->SetUpdateMode(TRUE);
+ }
+
+ pNewEditEngine = pCacheFieldEditEngine;
+ pCacheFieldEditEngine = NULL;
+ }
+ return pNewEditEngine;
+}
+
+void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine*& rpEditEngine)
+{
+ if (!pCacheFieldEditEngine && rpEditEngine)
+ {
+ pCacheFieldEditEngine = rpEditEngine;
+ pCacheFieldEditEngine->Clear();
+ }
+ else
+ delete rpEditEngine;
+ rpEditEngine = NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+// static
+ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
+{
+ return new ScRecursionHelper;
+}
+
+// ----------------------------------------------------------------------------
+
+ScLookupCache & ScDocument::GetLookupCache( const ScRange & rRange )
+{
+ ScLookupCache* pCache = 0;
+ if (!pLookupCacheMapImpl)
+ pLookupCacheMapImpl = new ScLookupCacheMapImpl;
+ ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find( rRange));
+ if (it == pLookupCacheMapImpl->aCacheMap.end())
+ {
+ pCache = new ScLookupCache( this, rRange);
+ AddLookupCache( *pCache);
+ }
+ else
+ pCache = (*it).second;
+ return *pCache;
+}
+
+void ScDocument::AddLookupCache( ScLookupCache & rCache )
+{
+ if (!pLookupCacheMapImpl->aCacheMap.insert( ::std::pair< const ScRange,
+ ScLookupCache*>( rCache.getRange(), &rCache)).second)
+ {
+ DBG_ERRORFILE( "ScDocument::AddLookupCache: couldn't add to hash map");
+ }
+ else
+ StartListeningArea( rCache.getRange(), &rCache);
+}
+
+void ScDocument::RemoveLookupCache( ScLookupCache & rCache )
+{
+ ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find(
+ rCache.getRange()));
+ if (it == pLookupCacheMapImpl->aCacheMap.end())
+ {
+ DBG_ERRORFILE( "ScDocument::RemoveLookupCache: range not found in hash map");
+ }
+ else
+ {
+ ScLookupCache* pCache = (*it).second;
+ pLookupCacheMapImpl->aCacheMap.erase( it);
+ EndListeningArea( pCache->getRange(), &rCache);
+ }
+}
+
+void ScDocument::ClearLookupCaches()
+{
+ if( pLookupCacheMapImpl )
+ pLookupCacheMapImpl->clear();
+}
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
new file mode 100644
index 000000000000..8fea4b8af2b9
--- /dev/null
+++ b/sc/source/core/data/documen3.cxx
@@ -0,0 +1,2128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include "scitems.hxx"
+#include <editeng/langitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <vcl/svapp.hxx>
+#include "document.hxx"
+#include "attrib.hxx"
+#include "cell.hxx"
+#include "table.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "pivot.hxx"
+#include "docpool.hxx"
+#include "poolhelp.hxx"
+#include "autoform.hxx"
+#include "rangelst.hxx"
+#include "chartarr.hxx"
+#include "chartlock.hxx"
+#include "refupdat.hxx"
+#include "docoptio.hxx"
+#include "viewopti.hxx"
+#include "scextopt.hxx"
+#include "brdcst.hxx"
+#include "bcaslot.hxx"
+#include "tablink.hxx"
+#include "externalrefmgr.hxx"
+#include "markdata.hxx"
+#include "validat.hxx"
+#include "dociter.hxx"
+#include "detdata.hxx"
+#include "detfunc.hxx"
+#include "scmod.hxx" // SC_MOD
+#include "inputopt.hxx" // GetExpandRefs
+#include "chartlis.hxx"
+#include "sc.hrc" // SID_LINK
+#include "hints.hxx"
+#include "dpobject.hxx"
+#include "unoguard.hxx"
+#include "drwlayer.hxx"
+#include "unoreflist.hxx"
+#include "listenercalls.hxx"
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+#include "dpshttab.hxx"
+#include "dptablecache.hxx"
+// End Comments
+#include "tabprotection.hxx"
+#include "formulaparserpool.hxx"
+#include "clipparam.hxx"
+#include "sheetevents.hxx"
+
+#include <memory>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+ScRangeName* ScDocument::GetRangeName()
+{
+ return pRangeName;
+}
+
+void ScDocument::SetRangeName( ScRangeName* pNewRangeName )
+{
+ if (pRangeName)
+ delete pRangeName;
+ pRangeName = pNewRangeName;
+}
+
+//UNUSED2008-05 ScRangeData* ScDocument::GetRangeAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab,
+//UNUSED2008-05 BOOL bStartOnly) const
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( pRangeName )
+//UNUSED2008-05 return pRangeName->GetRangeAtCursor( ScAddress( nCol, nRow, nTab ), bStartOnly );
+//UNUSED2008-05 else
+//UNUSED2008-05 return NULL;
+//UNUSED2008-05 }
+
+ScRangeData* ScDocument::GetRangeAtBlock( const ScRange& rBlock, String* pName ) const
+{
+ ScRangeData* pData = NULL;
+ if ( pRangeName )
+ {
+ pData = pRangeName->GetRangeAtBlock( rBlock );
+ if (pData && pName)
+ *pName = pData->GetName();
+ }
+ return pData;
+}
+
+ScDBCollection* ScDocument::GetDBCollection() const
+{
+ return pDBCollection;
+}
+
+void ScDocument::SetDBCollection( ScDBCollection* pNewDBCollection, BOOL bRemoveAutoFilter )
+{
+ if ( bRemoveAutoFilter )
+ {
+ // remove auto filter attribute if new db data don't contain auto filter flag
+ // start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
+
+ if ( pDBCollection )
+ {
+ USHORT nOldCount = pDBCollection->GetCount();
+ for (USHORT nOld=0; nOld<nOldCount; nOld++)
+ {
+ ScDBData* pOldData = (*pDBCollection)[nOld];
+ if ( pOldData->HasAutoFilter() )
+ {
+ ScRange aOldRange;
+ pOldData->GetArea( aOldRange );
+
+ BOOL bFound = FALSE;
+ USHORT nNewIndex = 0;
+ if ( pNewDBCollection &&
+ pNewDBCollection->SearchName( pOldData->GetName(), nNewIndex ) )
+ {
+ ScDBData* pNewData = (*pNewDBCollection)[nNewIndex];
+ if ( pNewData->HasAutoFilter() )
+ {
+ ScRange aNewRange;
+ pNewData->GetArea( aNewRange );
+ if ( aOldRange.aStart == aNewRange.aStart )
+ bFound = TRUE;
+ }
+ }
+
+ if ( !bFound )
+ {
+ aOldRange.aEnd.SetRow( aOldRange.aStart.Row() );
+ RemoveFlagsTab( aOldRange.aStart.Col(), aOldRange.aStart.Row(),
+ aOldRange.aEnd.Col(), aOldRange.aEnd.Row(),
+ aOldRange.aStart.Tab(), SC_MF_AUTO );
+ if (pShell)
+ pShell->Broadcast( ScPaintHint( aOldRange, PAINT_GRID ) );
+ }
+ }
+ }
+ }
+ }
+
+ if (pDBCollection)
+ delete pDBCollection;
+ pDBCollection = pNewDBCollection;
+}
+
+ScDBData* ScDocument::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bStartOnly) const
+{
+ if (pDBCollection)
+ return pDBCollection->GetDBAtCursor(nCol, nRow, nTab, bStartOnly);
+ else
+ return NULL;
+}
+
+ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
+{
+ if (pDBCollection)
+ return pDBCollection->GetDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2);
+ else
+ return NULL;
+}
+
+ScDPCollection* ScDocument::GetDPCollection()
+{
+ if (!pDPCollection)
+ pDPCollection = new ScDPCollection(this);
+ return pDPCollection;
+}
+
+ScDPObject* ScDocument::GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
+{
+ if (!pDPCollection)
+ return NULL;
+
+ USHORT nCount = pDPCollection->GetCount();
+ ScAddress aPos( nCol, nRow, nTab );
+ for (USHORT i=0; i<nCount; i++)
+ if ( (*pDPCollection)[i]->GetOutRange().In( aPos ) )
+ return (*pDPCollection)[i];
+
+ return NULL;
+}
+
+ScDPObject* ScDocument::GetDPAtBlock( const ScRange & rBlock ) const
+{
+ if (!pDPCollection)
+ return NULL;
+
+ /* Walk the collection in reverse order to get something of an
+ * approximation of MS Excels 'most recent' effect. */
+ USHORT i = pDPCollection->GetCount();
+ while ( i-- > 0 )
+ if ( (*pDPCollection)[i]->GetOutRange().In( rBlock ) )
+ return (*pDPCollection)[i];
+
+ return NULL;
+}
+
+ScChartCollection* ScDocument::GetChartCollection() const
+{
+ return pChartCollection;
+}
+
+void ScDocument::StopTemporaryChartLock()
+{
+ if( apTemporaryChartLock.get() )
+ apTemporaryChartLock->StopLocking();
+}
+
+void ScDocument::SetChartListenerCollection(
+ ScChartListenerCollection* pNewChartListenerCollection,
+ BOOL bSetChartRangeLists )
+{
+ ScChartListenerCollection* pOld = pChartListenerCollection;
+ pChartListenerCollection = pNewChartListenerCollection;
+ if ( pChartListenerCollection )
+ {
+ if ( pOld )
+ pChartListenerCollection->SetDiffDirty( *pOld, bSetChartRangeLists );
+ pChartListenerCollection->StartAllListeners();
+ }
+ delete pOld;
+}
+
+void ScDocument::SetScenario( SCTAB nTab, BOOL bFlag )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetScenario(bFlag);
+}
+
+BOOL ScDocument::IsScenario( SCTAB nTab ) const
+{
+ return ValidTab(nTab) && pTab[nTab] &&pTab[nTab]->IsScenario();
+ //if (ValidTab(nTab) && pTab[nTab])
+ // return pTab[nTab]->IsScenario();
+
+ //return FALSE;
+}
+
+void ScDocument::SetScenarioData( SCTAB nTab, const String& rComment,
+ const Color& rColor, USHORT nFlags )
+{
+ if (ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsScenario())
+ {
+ pTab[nTab]->SetScenarioComment( rComment );
+ pTab[nTab]->SetScenarioColor( rColor );
+ pTab[nTab]->SetScenarioFlags( nFlags );
+ }
+}
+
+Color ScDocument::GetTabBgColor( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetTabBgColor();
+ return Color(COL_AUTO);
+}
+
+void ScDocument::SetTabBgColor( SCTAB nTab, const Color& rColor )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetTabBgColor(rColor);
+}
+
+bool ScDocument::IsDefaultTabBgColor( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetTabBgColor() == COL_AUTO;
+ return true;
+}
+
+void ScDocument::GetScenarioData( SCTAB nTab, String& rComment,
+ Color& rColor, USHORT& rFlags ) const
+{
+ if (ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsScenario())
+ {
+ pTab[nTab]->GetScenarioComment( rComment );
+ rColor = pTab[nTab]->GetScenarioColor();
+ rFlags = pTab[nTab]->GetScenarioFlags();
+ }
+}
+
+void ScDocument::GetScenarioFlags( SCTAB nTab, USHORT& rFlags ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->IsScenario())
+ rFlags = pTab[nTab]->GetScenarioFlags();
+}
+
+BOOL ScDocument::IsLinked( SCTAB nTab ) const
+{
+ return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsLinked();
+ // euqivalent to
+ //if (ValidTab(nTab) && pTab[nTab])
+ // return pTab[nTab]->IsLinked();
+ //return FALSE;
+}
+
+formula::FormulaGrammar::AddressConvention ScDocument::GetAddressConvention() const
+{
+ return formula::FormulaGrammar::extractRefConvention(eGrammar);
+}
+
+formula::FormulaGrammar::Grammar ScDocument::GetGrammar() const
+{
+ return eGrammar;
+}
+
+void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram )
+{
+ eGrammar = eGram;
+}
+
+BOOL ScDocument::GetLinkMode( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetLinkMode();
+ return SC_LINK_NONE;
+}
+
+const String& ScDocument::GetLinkDoc( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetLinkDoc();
+ return EMPTY_STRING;
+}
+
+const String& ScDocument::GetLinkFlt( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetLinkFlt();
+ return EMPTY_STRING;
+}
+
+const String& ScDocument::GetLinkOpt( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetLinkOpt();
+ return EMPTY_STRING;
+}
+
+const String& ScDocument::GetLinkTab( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetLinkTab();
+ return EMPTY_STRING;
+}
+
+ULONG ScDocument::GetLinkRefreshDelay( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetLinkRefreshDelay();
+ return 0;
+}
+
+void ScDocument::SetLink( SCTAB nTab, BYTE nMode, const String& rDoc,
+ const String& rFilter, const String& rOptions,
+ const String& rTabName, ULONG nRefreshDelay )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetLink( nMode, rDoc, rFilter, rOptions, rTabName, nRefreshDelay );
+}
+
+BOOL ScDocument::HasLink( const String& rDoc,
+ const String& rFilter, const String& rOptions ) const
+{
+ SCTAB nCount = GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ if (pTab[i]->IsLinked()
+ && pTab[i]->GetLinkDoc() == rDoc
+ && pTab[i]->GetLinkFlt() == rFilter
+ && pTab[i]->GetLinkOpt() == rOptions)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL ScDocument::LinkExternalTab( SCTAB& rTab, const String& aDocTab,
+ const String& aFileName, const String& aTabName )
+{
+ if ( IsClipboard() )
+ {
+ DBG_ERRORFILE( "LinkExternalTab in Clipboard" );
+ return FALSE;
+ }
+ rTab = 0;
+ String aFilterName; // wird vom Loader gefuellt
+ String aOptions; // Filter-Optionen
+ sal_uInt32 nLinkCnt = pExtDocOptions ? pExtDocOptions->GetDocSettings().mnLinkCnt : 0;
+ ScDocumentLoader aLoader( aFileName, aFilterName, aOptions, nLinkCnt + 1 );
+ if ( aLoader.IsError() )
+ return FALSE;
+ ScDocument* pSrcDoc = aLoader.GetDocument();
+
+ // Tabelle kopieren
+ SCTAB nSrcTab;
+ if ( pSrcDoc->GetTable( aTabName, nSrcTab ) )
+ {
+ if ( !InsertTab( SC_TAB_APPEND, aDocTab, TRUE ) )
+ {
+ DBG_ERRORFILE("can't insert external document table");
+ return FALSE;
+ }
+ rTab = GetTableCount() - 1;
+ // nicht neu einfuegen, nur Ergebnisse
+ TransferTab( pSrcDoc, nSrcTab, rTab, FALSE, TRUE );
+ }
+ else
+ return FALSE;
+
+ ULONG nRefreshDelay = 0;
+
+ BOOL bWasThere = HasLink( aFileName, aFilterName, aOptions );
+ SetLink( rTab, SC_LINK_VALUE, aFileName, aFilterName, aOptions, aTabName, nRefreshDelay );
+ if ( !bWasThere ) // Link pro Quelldokument nur einmal eintragen
+ {
+ ScTableLink* pLink = new ScTableLink( pShell, aFileName, aFilterName, aOptions, nRefreshDelay );
+ pLink->SetInCreate( TRUE );
+ GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName,
+ &aFilterName );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_LINKS );
+ }
+ return TRUE;
+}
+
+ScExternalRefManager* ScDocument::GetExternalRefManager() const
+{
+ ScDocument* pThis = const_cast<ScDocument*>(this);
+ if (!pExternalRefMgr.get())
+ pThis->pExternalRefMgr.reset( new ScExternalRefManager( pThis));
+
+ return pExternalRefMgr.get();
+}
+
+bool ScDocument::IsInExternalReferenceMarking() const
+{
+ return pExternalRefMgr.get() && pExternalRefMgr->isInReferenceMarking();
+}
+
+void ScDocument::MarkUsedExternalReferences()
+{
+ if (!pExternalRefMgr.get())
+ return;
+ if (!pExternalRefMgr->hasExternalData())
+ return;
+ // Charts.
+ bool bAllMarked = pExternalRefMgr->markUsedByLinkListeners();
+ // Formula cells.
+ bAllMarked = pExternalRefMgr->markUsedExternalRefCells();
+
+ /* NOTE: Conditional formats and validation objects are marked when
+ * collecting them during export. */
+}
+
+ScFormulaParserPool& ScDocument::GetFormulaParserPool() const
+{
+ if( !mxFormulaParserPool.get() )
+ mxFormulaParserPool.reset( new ScFormulaParserPool( *this ) );
+ return *mxFormulaParserPool;
+}
+
+const ScSheetEvents* ScDocument::GetSheetEvents( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetSheetEvents();
+ return NULL;
+}
+
+void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew )
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ pTab[nTab]->SetSheetEvents( pNew );
+}
+
+bool ScDocument::HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents ) const
+{
+ if (pTab[nTab])
+ {
+ // check if any event handler script has been configured
+ const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents();
+ if ( pEvents && pEvents->GetScript( nEvent ) )
+ return true;
+ // check if VBA event handlers exist
+ if (bWithVbaEvents && mxVbaEvents.is()) try
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= nTab;
+ if (mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ) ||
+ mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent ), uno::Sequence< uno::Any >() ))
+ return true;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ return false;
+}
+
+bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents ) const
+{
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if (HasSheetEventScript( nTab, nEvent, bWithVbaEvents ))
+ return true;
+ return false;
+}
+
+BOOL ScDocument::HasCalcNotification( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetCalcNotification();
+ return FALSE;
+}
+
+void ScDocument::SetCalcNotification( SCTAB nTab )
+{
+ // set only if not set before
+ if (VALIDTAB(nTab) && pTab[nTab] && !pTab[nTab]->GetCalcNotification())
+ pTab[nTab]->SetCalcNotification(TRUE);
+}
+
+void ScDocument::ResetCalcNotifications()
+{
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if (pTab[nTab] && pTab[nTab]->GetCalcNotification())
+ pTab[nTab]->SetCalcNotification(FALSE);
+}
+
+ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate )
+{
+ ScOutlineTable* pVal = NULL;
+
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ {
+ pVal = pTab[nTab]->GetOutlineTable();
+ if (!pVal)
+ if (bCreate)
+ {
+ pTab[nTab]->StartOutlineTable();
+ pVal = pTab[nTab]->GetOutlineTable();
+ }
+ }
+
+ return pVal;
+}
+
+BOOL ScDocument::SetOutlineTable( SCTAB nTab, const ScOutlineTable* pNewOutline )
+{
+ return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->SetOutlineTable(pNewOutline);
+ //if (VALIDTAB(nTab))
+ // if (pTab[nTab])
+ // return pTab[nTab]->SetOutlineTable(pNewOutline);
+
+ //return FALSE;
+}
+
+void ScDocument::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ pTab[nTab]->DoAutoOutline( nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+BOOL ScDocument::TestRemoveSubTotals( SCTAB nTab, const ScSubTotalParam& rParam )
+{
+ return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->TestRemoveSubTotals( rParam );
+ //if (VALIDTAB(nTab) && pTab[nTab] )
+ // return pTab[nTab]->TestRemoveSubTotals( rParam );
+
+ //return FALSE;
+}
+
+void ScDocument::RemoveSubTotals( SCTAB nTab, ScSubTotalParam& rParam )
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ pTab[nTab]->RemoveSubTotals( rParam );
+}
+
+BOOL ScDocument::DoSubTotals( SCTAB nTab, ScSubTotalParam& rParam )
+{
+ return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->DoSubTotals( rParam );
+ //if (VALIDTAB(nTab))
+ // if (pTab[nTab])
+ // return pTab[nTab]->DoSubTotals( rParam );
+
+ //return FALSE;
+}
+
+BOOL ScDocument::HasSubTotalCells( const ScRange& rRange )
+{
+ ScCellIterator aIter( this, rRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->IsSubTotal() )
+ return TRUE;
+
+ pCell = aIter.GetNext();
+ }
+ return FALSE; // none found
+}
+
+// kopiert aus diesem Dokument die Zellen von Positionen, an denen in pPosDoc
+// auch Zellen stehen, nach pDestDoc
+
+void ScDocument::CopyUpdated( ScDocument* pPosDoc, ScDocument* pDestDoc )
+{
+ SCTAB nCount = GetTableCount();
+ for (SCTAB nTab=0; nTab<nCount; nTab++)
+ if (pTab[nTab] && pPosDoc->pTab[nTab] && pDestDoc->pTab[nTab])
+ pTab[nTab]->CopyUpdated( pPosDoc->pTab[nTab], pDestDoc->pTab[nTab] );
+}
+
+void ScDocument::CopyScenario( SCTAB nSrcTab, SCTAB nDestTab, BOOL bNewScenario )
+{
+ if (ValidTab(nSrcTab) && ValidTab(nDestTab) && pTab[nSrcTab] && pTab[nDestTab])
+ {
+ // Flags fuer aktive Szenarios richtig setzen
+ // und aktuelle Werte in bisher aktive Szenarios zurueckschreiben
+
+ ScRangeList aRanges = *pTab[nSrcTab]->GetScenarioRanges();
+ const ULONG nRangeCount = aRanges.Count();
+
+ // nDestTab ist die Zieltabelle
+ for ( SCTAB nTab = nDestTab+1;
+ nTab<=MAXTAB && pTab[nTab] && pTab[nTab]->IsScenario();
+ nTab++ )
+ {
+ if ( pTab[nTab]->IsActiveScenario() ) // auch wenn's dasselbe Szenario ist
+ {
+ BOOL bTouched = FALSE;
+ for ( ULONG nR=0; nR<nRangeCount && !bTouched; nR++)
+ {
+ const ScRange* pRange = aRanges.GetObject(nR);
+ if ( pTab[nTab]->HasScenarioRange( *pRange ) )
+ bTouched = TRUE;
+ }
+ if (bTouched)
+ {
+ pTab[nTab]->SetActiveScenario(FALSE);
+ if ( pTab[nTab]->GetScenarioFlags() & SC_SCENARIO_TWOWAY )
+ pTab[nTab]->CopyScenarioFrom( pTab[nDestTab] );
+ }
+ }
+ }
+
+ pTab[nSrcTab]->SetActiveScenario(TRUE); // da kommt's her...
+ if (!bNewScenario) // Daten aus dem ausgewaehlten Szenario kopieren
+ {
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ pTab[nSrcTab]->CopyScenarioTo( pTab[nDestTab] );
+ SetDirty();
+ SetAutoCalc( bOldAutoCalc );
+ }
+ }
+}
+
+void ScDocument::MarkScenario( SCTAB nSrcTab, SCTAB nDestTab, ScMarkData& rDestMark,
+ BOOL bResetMark, USHORT nNeededBits ) const
+{
+ if (bResetMark)
+ rDestMark.ResetMark();
+
+ if (ValidTab(nSrcTab) && pTab[nSrcTab])
+ pTab[nSrcTab]->MarkScenarioIn( rDestMark, nNeededBits );
+
+ rDestMark.SetAreaTab( nDestTab );
+}
+
+BOOL ScDocument::HasScenarioRange( SCTAB nTab, const ScRange& rRange ) const
+{
+ return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->HasScenarioRange( rRange );
+ //if (ValidTab(nTab) && pTab[nTab])
+ // return pTab[nTab]->HasScenarioRange( rRange );
+
+ //return FALSE;
+}
+
+const ScRangeList* ScDocument::GetScenarioRanges( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetScenarioRanges();
+
+ return NULL;
+}
+
+BOOL ScDocument::IsActiveScenario( SCTAB nTab ) const
+{
+ return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsActiveScenario( );
+ //if (ValidTab(nTab) && pTab[nTab])
+ // return pTab[nTab]->IsActiveScenario();
+
+ //return FALSE;
+}
+
+void ScDocument::SetActiveScenario( SCTAB nTab, BOOL bActive )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetActiveScenario( bActive );
+}
+
+BOOL ScDocument::TestCopyScenario( SCTAB nSrcTab, SCTAB nDestTab ) const
+{
+ if (ValidTab(nSrcTab) && ValidTab(nDestTab))
+ return pTab[nSrcTab]->TestCopyScenarioTo( pTab[nDestTab] );
+
+ DBG_ERROR("falsche Tabelle bei TestCopyScenario");
+ return FALSE;
+}
+
+void ScDocument::AddUnoObject( SfxListener& rObject )
+{
+ if (!pUnoBroadcaster)
+ pUnoBroadcaster = new SfxBroadcaster;
+
+ rObject.StartListening( *pUnoBroadcaster );
+}
+
+void ScDocument::RemoveUnoObject( SfxListener& rObject )
+{
+ if (pUnoBroadcaster)
+ {
+ rObject.EndListening( *pUnoBroadcaster );
+
+ if ( bInUnoBroadcast )
+ {
+ // #107294# Broadcasts from ScDocument::BroadcastUno are the only way that
+ // uno object methods are called without holding a reference.
+ //
+ // If RemoveUnoObject is called from an object dtor in the finalizer thread
+ // while the main thread is calling BroadcastUno, the dtor thread must wait
+ // (or the object's Notify might try to access a deleted object).
+ // The SolarMutex can't be locked here because if a component is called from
+ // a VCL event, the main thread has the SolarMutex locked all the time.
+ //
+ // This check is done after calling EndListening, so a later BroadcastUno call
+ // won't touch this object.
+
+ vos::IMutex& rSolarMutex = Application::GetSolarMutex();
+ if ( rSolarMutex.tryToAcquire() )
+ {
+ // BroadcastUno is always called with the SolarMutex locked, so if it
+ // can be acquired, this is within the same thread (should not happen)
+ DBG_ERRORFILE( "RemoveUnoObject called from BroadcastUno" );
+ rSolarMutex.release();
+ }
+ else
+ {
+ // let the thread that called BroadcastUno continue
+ while ( bInUnoBroadcast )
+ {
+ vos::OThread::yield();
+ }
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("No Uno broadcaster");
+ }
+}
+
+void ScDocument::BroadcastUno( const SfxHint &rHint )
+{
+ if (pUnoBroadcaster)
+ {
+ bInUnoBroadcast = TRUE;
+ pUnoBroadcaster->Broadcast( rHint );
+ bInUnoBroadcast = FALSE;
+
+ // During Broadcast notification, Uno objects can add to pUnoListenerCalls.
+ // The listener calls must be processed after completing the broadcast,
+ // because they can add or remove objects from pUnoBroadcaster.
+
+ if ( pUnoListenerCalls && rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DATACHANGED &&
+ !bInUnoListenerCall )
+ {
+ // Listener calls may lead to BroadcastUno calls again. The listener calls
+ // are not nested, instead the calls are collected in the list, and the
+ // outermost call executes them all.
+
+ ScChartLockGuard aChartLockGuard(this);
+ bInUnoListenerCall = TRUE;
+ pUnoListenerCalls->ExecuteAndClear();
+ bInUnoListenerCall = FALSE;
+ }
+ }
+}
+
+void ScDocument::AddUnoListenerCall( const uno::Reference<util::XModifyListener>& rListener,
+ const lang::EventObject& rEvent )
+{
+ DBG_ASSERT( bInUnoBroadcast, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
+
+ if ( !pUnoListenerCalls )
+ pUnoListenerCalls = new ScUnoListenerCalls;
+ pUnoListenerCalls->Add( rListener, rEvent );
+}
+
+void ScDocument::BeginUnoRefUndo()
+{
+ DBG_ASSERT( !pUnoRefUndoList, "BeginUnoRefUndo twice" );
+ delete pUnoRefUndoList;
+
+ pUnoRefUndoList = new ScUnoRefList;
+}
+
+ScUnoRefList* ScDocument::EndUnoRefUndo()
+{
+ ScUnoRefList* pRet = pUnoRefUndoList;
+ pUnoRefUndoList = NULL;
+ return pRet; // must be deleted by caller!
+}
+
+void ScDocument::AddUnoRefChange( sal_Int64 nId, const ScRangeList& rOldRanges )
+{
+ if ( pUnoRefUndoList )
+ pUnoRefUndoList->Add( nId, rOldRanges );
+}
+
+sal_Int64 ScDocument::GetNewUnoId()
+{
+ return ++nUnoObjectId;
+}
+
+void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc, BOOL bIncludeDraw,
+ bool bUpdateNoteCaptionPos )
+{
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ PutInOrder( nTab1, nTab2 );
+ if (VALIDTAB(nTab1) && VALIDTAB(nTab2))
+ {
+ BOOL bExpandRefsOld = IsExpandRefs();
+ if ( eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0 || nDz > 0) )
+ SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
+ SCTAB i;
+ SCTAB iMax;
+ if ( eUpdateRefMode == URM_COPY )
+ {
+ i = nTab1;
+ iMax = nTab2;
+ }
+ else
+ {
+ ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ xColNameRanges->UpdateReference( eUpdateRefMode, this, aRange, nDx, nDy, nDz );
+ xRowNameRanges->UpdateReference( eUpdateRefMode, this, aRange, nDx, nDy, nDz );
+ pDBCollection->UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
+ pRangeName->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
+ if ( pDPCollection )
+ pDPCollection->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
+ UpdateChartRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
+ UpdateRefAreaLinks( eUpdateRefMode, aRange, nDx, nDy, nDz );
+ if ( pCondFormList )
+ pCondFormList->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
+ if ( pValidationList )
+ pValidationList->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
+ if ( pDetOpList )
+ pDetOpList->UpdateReference( this, eUpdateRefMode, aRange, nDx, nDy, nDz );
+ if ( pUnoBroadcaster )
+ pUnoBroadcaster->Broadcast( ScUpdateRefHint(
+ eUpdateRefMode, aRange, nDx, nDy, nDz ) );
+ i = 0;
+ iMax = MAXTAB;
+ }
+ for ( ; i<=iMax; i++)
+ if (pTab[i])
+ pTab[i]->UpdateReference(
+ eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
+ nDx, nDy, nDz, pUndoDoc, bIncludeDraw, bUpdateNoteCaptionPos );
+
+ if ( bIsEmbedded )
+ {
+ SCCOL theCol1;
+ SCROW theRow1;
+ SCTAB theTab1;
+ SCCOL theCol2;
+ SCROW theRow2;
+ SCTAB theTab2;
+ theCol1 = aEmbedRange.aStart.Col();
+ theRow1 = aEmbedRange.aStart.Row();
+ theTab1 = aEmbedRange.aStart.Tab();
+ theCol2 = aEmbedRange.aEnd.Col();
+ theRow2 = aEmbedRange.aEnd.Row();
+ theTab2 = aEmbedRange.aEnd.Tab();
+ if ( ScRefUpdate::Update( this, eUpdateRefMode, nCol1,nRow1,nTab1, nCol2,nRow2,nTab2,
+ nDx,nDy,nDz, theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) )
+ {
+ aEmbedRange = ScRange( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
+ }
+ }
+ SetExpandRefs( bExpandRefsOld );
+
+ // #30428# after moving, no clipboard move ref-updates are possible
+ if ( eUpdateRefMode != URM_COPY && IsClipboardSource() )
+ {
+ ScDocument* pClipDoc = SC_MOD()->GetClipDoc();
+ if (pClipDoc)
+ pClipDoc->GetClipParam().mbCutMode = false;
+ }
+ }
+}
+
+void ScDocument::UpdateTranspose( const ScAddress& rDestPos, ScDocument* pClipDoc,
+ const ScMarkData& rMark, ScDocument* pUndoDoc )
+{
+ DBG_ASSERT(pClipDoc->bIsClip, "UpdateTranspose: kein Clip");
+
+ ScRange aSource;
+ ScClipParam& rClipParam = GetClipParam();
+ if (rClipParam.maRanges.Count())
+ aSource = *rClipParam.maRanges.First();
+ ScAddress aDest = rDestPos;
+
+ SCTAB nClipTab = 0;
+ for (SCTAB nDestTab=0; nDestTab<=MAXTAB && pTab[nDestTab]; nDestTab++)
+ if (rMark.GetTableSelect(nDestTab))
+ {
+ while (!pClipDoc->pTab[nClipTab]) nClipTab = (nClipTab+1) % (MAXTAB+1);
+ aSource.aStart.SetTab( nClipTab );
+ aSource.aEnd.SetTab( nClipTab );
+ aDest.SetTab( nDestTab );
+
+ // wie UpdateReference
+
+ pRangeName->UpdateTranspose( aSource, aDest ); // vor den Zellen!
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateTranspose( aSource, aDest, pUndoDoc );
+
+ nClipTab = (nClipTab+1) % (MAXTAB+1);
+ }
+}
+
+void ScDocument::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
+{
+ //! pDBCollection
+ //! pPivotCollection
+ //! UpdateChartRef
+
+ pRangeName->UpdateGrow( rArea, nGrowX, nGrowY );
+
+ for (SCTAB i=0; i<=MAXTAB && pTab[i]; i++)
+ pTab[i]->UpdateGrow( rArea, nGrowX, nGrowY );
+}
+
+void ScDocument::Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
+ ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
+ double nStepValue, double nMaxValue)
+{
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ for (SCTAB i=0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->Fill(nCol1, nRow1, nCol2, nRow2,
+ nFillCount, eFillDir, eFillCmd, eFillDateCmd,
+ nStepValue, nMaxValue);
+}
+
+String ScDocument::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
+{
+ SCTAB nTab = rSource.aStart.Tab();
+ if (pTab[nTab])
+ return pTab[nTab]->GetAutoFillPreview( rSource, nEndX, nEndY );
+
+ return EMPTY_STRING;
+}
+
+void ScDocument::AutoFormat( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ USHORT nFormatNo, const ScMarkData& rMark )
+{
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ for (SCTAB i=0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo );
+}
+
+void ScDocument::GetAutoFormatData(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ ScAutoFormatData& rData)
+{
+ if (VALIDTAB(nTab))
+ {
+ if (pTab[nTab])
+ {
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ pTab[nTab]->GetAutoFormatData(nStartCol, nStartRow, nEndCol, nEndRow, rData);
+ }
+ }
+}
+
+// static
+void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem& rSearchItem,
+ SCCOL& rCol, SCROW& rRow )
+{
+ USHORT nCommand = rSearchItem.GetCommand();
+ BOOL bReplace = ( nCommand == SVX_SEARCHCMD_REPLACE ||
+ nCommand == SVX_SEARCHCMD_REPLACE_ALL );
+ if ( rSearchItem.GetBackward() )
+ {
+ if ( rSearchItem.GetRowDirection() )
+ {
+ if ( rSearchItem.GetPattern() )
+ {
+ rCol = MAXCOL;
+ rRow = MAXROW+1;
+ }
+ else if ( bReplace )
+ {
+ rCol = MAXCOL;
+ rRow = MAXROW;
+ }
+ else
+ {
+ rCol = MAXCOL+1;
+ rRow = MAXROW;
+ }
+ }
+ else
+ {
+ if ( rSearchItem.GetPattern() )
+ {
+ rCol = MAXCOL+1;
+ rRow = MAXROW;
+ }
+ else if ( bReplace )
+ {
+ rCol = MAXCOL;
+ rRow = MAXROW;
+ }
+ else
+ {
+ rCol = MAXCOL;
+ rRow = MAXROW+1;
+ }
+ }
+ }
+ else
+ {
+ if ( rSearchItem.GetRowDirection() )
+ {
+ if ( rSearchItem.GetPattern() )
+ {
+ rCol = 0;
+ rRow = (SCROW) -1;
+ }
+ else if ( bReplace )
+ {
+ rCol = 0;
+ rRow = 0;
+ }
+ else
+ {
+ rCol = (SCCOL) -1;
+ rRow = 0;
+ }
+ }
+ else
+ {
+ if ( rSearchItem.GetPattern() )
+ {
+ rCol = (SCCOL) -1;
+ rRow = 0;
+ }
+ else if ( bReplace )
+ {
+ rCol = 0;
+ rRow = 0;
+ }
+ else
+ {
+ rCol = 0;
+ rRow = (SCROW) -1;
+ }
+ }
+ }
+}
+
+BOOL ScDocument::SearchAndReplace(const SvxSearchItem& rSearchItem,
+ SCCOL& rCol, SCROW& rRow, SCTAB& rTab,
+ ScMarkData& rMark,
+ String& rUndoStr, ScDocument* pUndoDoc)
+{
+ //! getrennte Markierungen pro Tabelle verwalten !!!!!!!!!!!!!
+
+ rMark.MarkToMulti();
+
+ BOOL bFound = FALSE;
+ if (VALIDTAB(rTab))
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ USHORT nCommand = rSearchItem.GetCommand();
+ if ( nCommand == SVX_SEARCHCMD_FIND_ALL ||
+ nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ for (nTab = 0; nTab <= MAXTAB; nTab++)
+ if (pTab[nTab])
+ {
+ if (rMark.GetTableSelect(nTab))
+ {
+ nCol = 0;
+ nRow = 0;
+ bFound |= pTab[nTab]->SearchAndReplace(
+ rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc );
+ }
+ }
+
+ // Markierung wird innen schon komplett gesetzt
+ }
+ else
+ {
+ nCol = rCol;
+ nRow = rRow;
+ if (rSearchItem.GetBackward())
+ {
+ for (nTab = rTab; ((SCsTAB)nTab >= 0) && !bFound; nTab--)
+ if (pTab[nTab])
+ {
+ if (rMark.GetTableSelect(nTab))
+ {
+ bFound = pTab[nTab]->SearchAndReplace(
+ rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc );
+ if (bFound)
+ {
+ rCol = nCol;
+ rRow = nRow;
+ rTab = nTab;
+ }
+ else
+ ScDocument::GetSearchAndReplaceStart(
+ rSearchItem, nCol, nRow );
+ }
+ }
+ }
+ else
+ {
+ for (nTab = rTab; (nTab <= MAXTAB) && !bFound; nTab++)
+ if (pTab[nTab])
+ {
+ if (rMark.GetTableSelect(nTab))
+ {
+ bFound = pTab[nTab]->SearchAndReplace(
+ rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc );
+ if (bFound)
+ {
+ rCol = nCol;
+ rRow = nRow;
+ rTab = nTab;
+ }
+ else
+ ScDocument::GetSearchAndReplaceStart(
+ rSearchItem, nCol, nRow );
+ }
+ }
+ }
+ }
+ }
+ return bFound;
+}
+
+// Outline anpassen
+
+BOOL ScDocument::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, BOOL bShow )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->UpdateOutlineCol( nStartCol, nEndCol, bShow );
+
+ DBG_ERROR("missing tab");
+ return FALSE;
+}
+
+BOOL ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bShow )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->UpdateOutlineRow( nStartRow, nEndRow, bShow );
+
+ DBG_ERROR("missing tab");
+ return FALSE;
+}
+
+void ScDocument::Sort(SCTAB nTab, const ScSortParam& rSortParam, BOOL bKeepQuery)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ {
+ BOOL bOldDisableIdle = IsIdleDisabled();
+ DisableIdle( TRUE );
+ pTab[nTab]->Sort(rSortParam, bKeepQuery);
+ DisableIdle( bOldDisableIdle );
+ }
+}
+
+SCSIZE ScDocument::Query(SCTAB nTab, const ScQueryParam& rQueryParam, BOOL bKeepSub)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->Query((ScQueryParam&)rQueryParam, bKeepSub);
+
+ DBG_ERROR("missing tab");
+ return 0;
+}
+
+
+BOOL ScDocument::ValidQuery( SCROW nRow, SCTAB nTab, const ScQueryParam& rQueryParam, BOOL* pSpecial )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->ValidQuery( nRow, rQueryParam, pSpecial );
+
+ DBG_ERROR("missing tab");
+ return FALSE;
+}
+
+
+void ScDocument::GetUpperCellString(SCCOL nCol, SCROW nRow, SCTAB nTab, String& rStr)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->GetUpperCellString( nCol, nRow, rStr );
+ else
+ rStr.Erase();
+}
+
+BOOL ScDocument::CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScQueryParam& rQueryParam)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->CreateQueryParam(nCol1, nRow1, nCol2, nRow2, rQueryParam);
+
+ DBG_ERROR("missing tab");
+ return FALSE;
+}
+
+BOOL ScDocument::HasAutoFilter( SCCOL nCurCol, SCROW nCurRow, SCTAB nCurTab )
+{
+ ScDBData* pDBData = GetDBAtCursor( nCurCol, nCurRow, nCurTab );
+ BOOL bHasAutoFilter = ( pDBData != NULL );
+
+ if ( pDBData )
+ {
+ if ( pDBData->HasHeader() )
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ INT16 nFlag;
+
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam );
+ nRow = aParam.nRow1;
+
+ for ( nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAutoFilter; nCol++ )
+ {
+ nFlag = ((ScMergeFlagAttr*)
+ GetAttr( nCol, nRow, nCurTab, ATTR_MERGE_FLAG ))->
+ GetValue();
+
+ if ( (nFlag & SC_MF_AUTO) == 0 )
+ bHasAutoFilter = FALSE;
+ }
+ }
+ else
+ bHasAutoFilter = FALSE;
+ }
+
+ return bHasAutoFilter;
+}
+
+BOOL ScDocument::HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ SCTAB nTab )
+{
+ return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
+ //if (VALIDTAB(nTab))
+ // if (pTab[nTab])
+ // return pTab[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
+
+ //return FALSE;
+}
+
+BOOL ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ SCTAB nTab )
+{
+ return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
+ //if (VALIDTAB(nTab))
+ // if (pTab[nTab])
+ // return pTab[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
+
+ //return FALSE;
+}
+
+//
+// GetFilterEntries - Eintraege fuer AutoFilter-Listbox
+//
+
+BOOL ScDocument::GetFilterEntries(
+ SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, TypedScStrCollection& rStrings, bool& rHasDates)
+{
+ if ( ValidTab(nTab) && pTab[nTab] && pDBCollection )
+ {
+ ScDBData* pDBData = pDBCollection->GetDBAtCursor(nCol, nRow, nTab, FALSE); //!??
+ if (pDBData)
+ {
+ SCTAB nAreaTab;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ if (pDBData->HasHeader())
+ ++nStartRow;
+
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam );
+ rStrings.SetCaseSensitive( aParam.bCaseSens );
+
+ // return all filter entries, if a filter condition is connected with a boolean OR
+ if ( bFilter )
+ {
+ SCSIZE nEntryCount = aParam.GetEntryCount();
+ for ( SCSIZE i = 0; i < nEntryCount && aParam.GetEntry(i).bDoQuery; ++i )
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if ( rEntry.eConnect != SC_AND )
+ {
+ bFilter = false;
+ break;
+ }
+ }
+ }
+
+ if ( bFilter )
+ {
+ pTab[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rStrings, rHasDates );
+ }
+ else
+ {
+ pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates );
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// GetFilterEntriesArea - Eintraege fuer Filter-Dialog
+//
+
+BOOL ScDocument::GetFilterEntriesArea( SCCOL nCol, SCROW nStartRow, SCROW nEndRow,
+ SCTAB nTab, TypedScStrCollection& rStrings, bool& rHasDates )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ {
+ pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//
+// GetDataEntries - Eintraege fuer Auswahlliste-Listbox (keine Zahlen / Formeln)
+//
+
+BOOL ScDocument::GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ TypedScStrCollection& rStrings, BOOL bLimit )
+{
+ if( !bLimit )
+ {
+ /* Try to generate the list from list validation. This part is skipped,
+ if bLimit==TRUE, because in that case this function is called to get
+ cell values for auto completion on input. */
+ sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA ) )->GetValue();
+ if( nValidation )
+ {
+ const ScValidationData* pData = GetValidationEntry( nValidation );
+ if( pData && pData->FillSelectionList( rStrings, ScAddress( nCol, nRow, nTab ) ) )
+ return TRUE;
+ }
+ }
+
+ return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit );
+ //if (ValidTab(nTab) && pTab[nTab])
+ // return pTab[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit );
+
+ //return FALSE;
+}
+
+//
+// GetFormulaEntries - Eintraege fuer Formel-AutoEingabe
+//
+
+// Funktionen werden als 1 schon vom InputHandler eingefuegt
+#define SC_STRTYPE_NAMES 2
+#define SC_STRTYPE_DBNAMES 3
+#define SC_STRTYPE_HEADERS 4
+
+BOOL ScDocument::GetFormulaEntries( TypedScStrCollection& rStrings )
+{
+ USHORT i;
+
+ //
+ // Bereichsnamen
+ //
+
+ if ( pRangeName )
+ {
+ USHORT nRangeCount = pRangeName->GetCount();
+ for ( i=0; i<nRangeCount; i++ )
+ {
+ ScRangeData* pData = (*pRangeName)[i];
+ if (pData)
+ {
+ TypedStrData* pNew = new TypedStrData( pData->GetName(), 0.0, SC_STRTYPE_NAMES );
+ if ( !rStrings.Insert(pNew) )
+ delete pNew;
+ }
+ }
+ }
+
+ //
+ // Datenbank-Bereiche
+ //
+
+ if ( pDBCollection )
+ {
+ USHORT nDBCount = pDBCollection->GetCount();
+ for ( i=0; i<nDBCount; i++ )
+ {
+ ScDBData* pData = (*pDBCollection)[i];
+ if (pData)
+ {
+ TypedStrData* pNew = new TypedStrData( pData->GetName(), 0.0, SC_STRTYPE_DBNAMES );
+ if ( !rStrings.Insert(pNew) )
+ delete pNew;
+ }
+ }
+ }
+
+ //
+ // Inhalte von Beschriftungsbereichen
+ //
+
+ ScRangePairList* pLists[2];
+ pLists[0] = GetColNameRanges();
+ pLists[1] = GetRowNameRanges();
+ for (USHORT nListNo=0; nListNo<2; nListNo++)
+ {
+ ScRangePairList* pList = pLists[nListNo];
+ if (pList)
+ for ( ScRangePair* pPair = pList->First(); pPair; pPair = pList->Next() )
+ {
+ ScRange aRange = pPair->GetRange(0);
+ ScCellIterator aIter( this, aRange );
+ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
+ if ( pCell->HasStringData() )
+ {
+ String aStr = pCell->GetStringData();
+ TypedStrData* pNew = new TypedStrData( aStr, 0.0, SC_STRTYPE_HEADERS );
+ if ( !rStrings.Insert(pNew) )
+ delete pNew;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+BOOL ScDocument::IsEmbedded() const
+{
+ return bIsEmbedded;
+}
+
+void ScDocument::GetEmbedded( ScRange& rRange ) const
+{
+ rRange = aEmbedRange;
+}
+
+Rectangle ScDocument::GetEmbeddedRect() const // 1/100 mm
+{
+ Rectangle aRect;
+ ScTable* pTable = pTab[aEmbedRange.aStart.Tab()];
+ if (!pTable)
+ {
+ DBG_ERROR("GetEmbeddedRect ohne Tabelle");
+ }
+ else
+ {
+ SCCOL i;
+
+ for (i=0; i<aEmbedRange.aStart.Col(); i++)
+ aRect.Left() += pTable->GetColWidth(i);
+ aRect.Top() += pTable->GetRowHeight( 0, aEmbedRange.aStart.Row() - 1);
+ aRect.Right() = aRect.Left();
+ for (i=aEmbedRange.aStart.Col(); i<=aEmbedRange.aEnd.Col(); i++)
+ aRect.Right() += pTable->GetColWidth(i);
+ aRect.Bottom() = aRect.Top();
+ aRect.Bottom() += pTable->GetRowHeight( aEmbedRange.aStart.Row(), aEmbedRange.aEnd.Row());
+
+ aRect.Left() = (long) ( aRect.Left() * HMM_PER_TWIPS );
+ aRect.Right() = (long) ( aRect.Right() * HMM_PER_TWIPS );
+ aRect.Top() = (long) ( aRect.Top() * HMM_PER_TWIPS );
+ aRect.Bottom() = (long) ( aRect.Bottom() * HMM_PER_TWIPS );
+ }
+ return aRect;
+}
+
+void ScDocument::SetEmbedded( const ScRange& rRange )
+{
+ bIsEmbedded = TRUE;
+ aEmbedRange = rRange;
+}
+
+void ScDocument::ResetEmbedded()
+{
+ bIsEmbedded = FALSE;
+ aEmbedRange = ScRange();
+}
+
+
+/** Similar to ScViewData::AddPixelsWhile(), but add height twips and only
+ while result is less than nStopTwips.
+ @return TRUE if advanced at least one row.
+ */
+bool lcl_AddTwipsWhile( long & rTwips, long nStopTwips, SCROW & rPosY, SCROW nEndRow, const ScTable * pTable )
+{
+ SCROW nRow = rPosY;
+ bool bAdded = false;
+ bool bStop = false;
+ while (rTwips < nStopTwips && nRow <= nEndRow && !bStop)
+ {
+ SCROW nHeightEndRow;
+ USHORT nHeight = pTable->GetRowHeight( nRow, NULL, &nHeightEndRow);
+ if (nHeightEndRow > nEndRow)
+ nHeightEndRow = nEndRow;
+ if (!nHeight)
+ nRow = nHeightEndRow + 1;
+ else
+ {
+ SCROW nRows = nHeightEndRow - nRow + 1;
+ sal_Int64 nAdd = static_cast<sal_Int64>(nHeight) * nRows;
+ if (nAdd + rTwips >= nStopTwips)
+ {
+ sal_Int64 nDiff = nAdd + rTwips - nStopTwips;
+ nRows -= static_cast<SCROW>(nDiff / nHeight);
+ nAdd = nHeight * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rTwips >= nStopTwips)
+ {
+ --nRows;
+ nAdd -= nHeight;
+ }
+ bStop = true;
+ }
+ rTwips += static_cast<long>(nAdd);
+ nRow += nRows;
+ }
+ }
+ if (nRow > rPosY)
+ {
+ --nRow;
+ bAdded = true;
+ }
+ rPosY = nRow;
+ return bAdded;
+}
+
+ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
+{
+ ScTable* pTable = pTab[nTab];
+ if (!pTable)
+ {
+ DBG_ERROR("GetRange ohne Tabelle");
+ return ScRange();
+ }
+
+ Rectangle aPosRect = rMMRect;
+ if ( IsNegativePage( nTab ) )
+ ScDrawLayer::MirrorRectRTL( aPosRect ); // always with positive (LTR) values
+
+ long nSize;
+ long nTwips;
+ long nAdd;
+ BOOL bEnd;
+
+ nSize = 0;
+ nTwips = (long) (aPosRect.Left() / HMM_PER_TWIPS);
+
+ SCCOL nX1 = 0;
+ bEnd = FALSE;
+ while (!bEnd)
+ {
+ nAdd = (long) pTable->GetColWidth(nX1);
+ if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
+ {
+ nSize += nAdd;
+ ++nX1;
+ }
+ else
+ bEnd = TRUE;
+ }
+
+ nTwips = (long) (aPosRect.Right() / HMM_PER_TWIPS);
+
+ SCCOL nX2 = nX1;
+ bEnd = FALSE;
+ while (!bEnd)
+ {
+ nAdd = (long) pTable->GetColWidth(nX2);
+ if (nSize+nAdd < nTwips && nX2<MAXCOL)
+ {
+ nSize += nAdd;
+ ++nX2;
+ }
+ else
+ bEnd = TRUE;
+ }
+
+
+ nSize = 0;
+ nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS);
+
+ SCROW nY1 = 0;
+ // Was if(nSize+nAdd<=nTwips+1) inside loop => if(nSize+nAdd<nTwips+2)
+ if (lcl_AddTwipsWhile( nSize, nTwips+2, nY1, MAXROW, pTable) && nY1 < MAXROW)
+ ++nY1; // original loop ended on last matched +1 unless that was MAXROW
+
+ nTwips = (long) (aPosRect.Bottom() / HMM_PER_TWIPS);
+
+ SCROW nY2 = nY1;
+ // Was if(nSize+nAdd<nTwips) inside loop => if(nSize+nAdd<nTwips)
+ if (lcl_AddTwipsWhile( nSize, nTwips, nY2, MAXROW, pTable) && nY2 < MAXROW)
+ ++nY2; // original loop ended on last matched +1 unless that was MAXROW
+
+ return ScRange( nX1,nY1,nTab, nX2,nY2,nTab );
+}
+
+void ScDocument::SetEmbedded( const Rectangle& rRect ) // aus VisArea (1/100 mm)
+{
+ bIsEmbedded = TRUE;
+ aEmbedRange = GetRange( nVisibleTab, rRect );
+}
+
+// VisArea auf Zellgrenzen anpassen
+
+void lcl_SnapHor( ScTable* pTable, long& rVal, SCCOL& rStartCol )
+{
+ SCCOL nCol = 0;
+ long nTwips = (long) (rVal / HMM_PER_TWIPS);
+ long nSnap = 0;
+ while ( nCol<MAXCOL )
+ {
+ long nAdd = pTable->GetColWidth(nCol);
+ if ( nSnap + nAdd/2 < nTwips || nCol < rStartCol )
+ {
+ nSnap += nAdd;
+ ++nCol;
+ }
+ else
+ break;
+ }
+ rVal = (long) ( nSnap * HMM_PER_TWIPS );
+ rStartCol = nCol;
+}
+
+void lcl_SnapVer( ScTable* pTable, long& rVal, SCROW& rStartRow )
+{
+ SCROW nRow = 0;
+ long nTwips = (long) (rVal / HMM_PER_TWIPS);
+ long nSnap = 0;
+
+ bool bFound = false;
+ for (SCROW i = nRow; i <= MAXROW; ++i)
+ {
+ SCROW nLastRow;
+ if (pTable->RowHidden(i, NULL, &nLastRow))
+ {
+ i = nLastRow;
+ continue;
+ }
+
+ nRow = i;
+ long nAdd = pTable->GetRowHeight(i);
+ if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow )
+ {
+ nSnap += nAdd;
+ ++nRow;
+ }
+ else
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ nRow = MAXROW; // all hidden down to the bottom
+
+ rVal = (long) ( nSnap * HMM_PER_TWIPS );
+ rStartRow = nRow;
+}
+
+void ScDocument::SnapVisArea( Rectangle& rRect ) const
+{
+ ScTable* pTable = pTab[nVisibleTab];
+ if (!pTable)
+ {
+ DBG_ERROR("SetEmbedded ohne Tabelle");
+ return;
+ }
+
+ BOOL bNegativePage = IsNegativePage( nVisibleTab );
+ if ( bNegativePage )
+ ScDrawLayer::MirrorRectRTL( rRect ); // calculate with positive (LTR) values
+
+ SCCOL nCol = 0;
+ lcl_SnapHor( pTable, rRect.Left(), nCol );
+ ++nCol; // mindestens eine Spalte
+ lcl_SnapHor( pTable, rRect.Right(), nCol );
+
+ SCROW nRow = 0;
+ lcl_SnapVer( pTable, rRect.Top(), nRow );
+ ++nRow; // mindestens eine Zeile
+ lcl_SnapVer( pTable, rRect.Bottom(), nRow );
+
+ if ( bNegativePage )
+ ScDrawLayer::MirrorRectRTL( rRect ); // back to real rectangle
+}
+
+ScDocProtection* ScDocument::GetDocProtection() const
+{
+ return pDocProtection.get();
+}
+
+void ScDocument::SetDocProtection(const ScDocProtection* pProtect)
+{
+ if (pProtect)
+ pDocProtection.reset(new ScDocProtection(*pProtect));
+ else
+ pDocProtection.reset(NULL);
+}
+
+BOOL ScDocument::IsDocProtected() const
+{
+ return pDocProtection.get() && pDocProtection->isProtected();
+}
+
+BOOL ScDocument::IsDocEditable() const
+{
+ // import into read-only document is possible
+ return !IsDocProtected() && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
+}
+
+BOOL ScDocument::IsTabProtected( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->IsProtected();
+
+ DBG_ERROR("Falsche Tabellennummer");
+ return FALSE;
+}
+
+ScTableProtection* ScDocument::GetTabProtection( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetProtection();
+
+ return NULL;
+}
+
+void ScDocument::SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect)
+{
+ if (!ValidTab(nTab))
+ return;
+
+ 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
+{
+ DBG_ASSERT( pDocOptions, "No DocOptions! :-(" );
+ return *pDocOptions;
+}
+
+void ScDocument::SetDocOptions( const ScDocOptions& rOpt )
+{
+ DBG_ASSERT( pDocOptions, "No DocOptions! :-(" );
+ *pDocOptions = rOpt;
+
+ xPoolHelper->SetFormTableOpt(rOpt);
+}
+
+const ScViewOptions& ScDocument::GetViewOptions() const
+{
+ DBG_ASSERT( pViewOptions, "No ViewOptions! :-(" );
+ return *pViewOptions;
+}
+
+void ScDocument::SetViewOptions( const ScViewOptions& rOpt )
+{
+ DBG_ASSERT( pViewOptions, "No ViewOptions! :-(" );
+ *pViewOptions = rOpt;
+}
+
+void ScDocument::GetLanguage( LanguageType& rLatin, LanguageType& rCjk, LanguageType& rCtl ) const
+{
+ rLatin = eLanguage;
+ rCjk = eCjkLanguage;
+ rCtl = eCtlLanguage;
+}
+
+void ScDocument::SetLanguage( LanguageType eLatin, LanguageType eCjk, LanguageType eCtl )
+{
+ eLanguage = eLatin;
+ eCjkLanguage = eCjk;
+ eCtlLanguage = eCtl;
+ if ( xPoolHelper.isValid() )
+ {
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+ pPool->SetPoolDefaultItem( SvxLanguageItem( eLanguage, ATTR_FONT_LANGUAGE ) );
+ pPool->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage, ATTR_CJK_FONT_LANGUAGE ) );
+ pPool->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage, ATTR_CTL_FONT_LANGUAGE ) );
+ }
+
+ UpdateDrawLanguages(); // set edit engine defaults in drawing layer pool
+}
+
+void ScDocument::SetDrawDefaults()
+{
+ bSetDrawDefaults = TRUE;
+ UpdateDrawDefaults();
+}
+
+Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ DBG_ERROR("GetMMRect: falsche Tabelle");
+ return Rectangle(0,0,0,0);
+ }
+
+ SCCOL i;
+ Rectangle aRect;
+
+ for (i=0; i<nStartCol; i++)
+ aRect.Left() += GetColWidth(i,nTab);
+ aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab);
+
+ aRect.Right() = aRect.Left();
+ aRect.Bottom() = aRect.Top();
+
+ for (i=nStartCol; i<=nEndCol; i++)
+ aRect.Right() += GetColWidth(i,nTab);
+ aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab);
+
+ aRect.Left() = (long)(aRect.Left() * HMM_PER_TWIPS);
+ aRect.Right() = (long)(aRect.Right() * HMM_PER_TWIPS);
+ aRect.Top() = (long)(aRect.Top() * HMM_PER_TWIPS);
+ aRect.Bottom() = (long)(aRect.Bottom() * HMM_PER_TWIPS);
+
+ if ( IsNegativePage( nTab ) )
+ ScDrawLayer::MirrorRectRTL( aRect );
+
+ return aRect;
+}
+
+void ScDocument::SetExtDocOptions( ScExtDocOptions* pNewOptions )
+{
+ delete pExtDocOptions;
+ pExtDocOptions = pNewOptions;
+}
+
+void ScDocument::DoMergeContents( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow )
+{
+ String aEmpty;
+ String aTotal;
+ String aCellStr;
+ SCCOL nCol;
+ SCROW nRow;
+ for (nRow=nStartRow; nRow<=nEndRow; nRow++)
+ for (nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ GetString(nCol,nRow,nTab,aCellStr);
+ if (aCellStr.Len())
+ {
+ if (aTotal.Len())
+ aTotal += ' ';
+ aTotal += aCellStr;
+ }
+ if (nCol != nStartCol || nRow != nStartRow)
+ SetString(nCol,nRow,nTab,aEmpty);
+ }
+
+ SetString(nStartCol,nStartRow,nTab,aTotal);
+}
+
+void ScDocument::DoMerge( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, bool bDeleteCaptions )
+{
+ ScMergeAttr aAttr( nEndCol-nStartCol+1, nEndRow-nStartRow+1 );
+ ApplyAttr( nStartCol, nStartRow, nTab, aAttr );
+
+ if ( nEndCol > nStartCol )
+ ApplyFlagsTab( nStartCol+1, nStartRow, nEndCol, nStartRow, nTab, SC_MF_HOR );
+ if ( nEndRow > nStartRow )
+ ApplyFlagsTab( nStartCol, nStartRow+1, nStartCol, nEndRow, nTab, SC_MF_VER );
+ if ( nEndCol > nStartCol && nEndRow > nStartRow )
+ ApplyFlagsTab( nStartCol+1, nStartRow+1, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
+
+ // remove all covered notes (removed captions are collected by drawing undo if active)
+ USHORT nDelFlag = IDF_NOTE | (bDeleteCaptions ? 0 : IDF_NOCAPTIONS);
+ if( nStartCol < nEndCol )
+ DeleteAreaTab( nStartCol + 1, nStartRow, nEndCol, nStartRow, nTab, nDelFlag );
+ if( nStartRow < nEndRow )
+ DeleteAreaTab( nStartCol, nStartRow + 1, nEndCol, nEndRow, nTab, nDelFlag );
+}
+
+void ScDocument::RemoveMerge( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScMergeAttr* pAttr = (const ScMergeAttr*)
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE );
+
+ if ( pAttr->GetColMerge() <= 1 && pAttr->GetRowMerge() <= 1 )
+ return;
+
+ SCCOL nEndCol = nCol + pAttr->GetColMerge() - 1;
+ SCROW nEndRow = nRow + pAttr->GetRowMerge() - 1;
+
+ RemoveFlagsTab( nCol, nRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
+
+ const ScMergeAttr* pDefAttr = (const ScMergeAttr*)
+ &xPoolHelper->GetDocPool()->GetDefaultItem( ATTR_MERGE );
+ ApplyAttr( nCol, nRow, nTab, *pDefAttr );
+}
+
+void ScDocument::ExtendPrintArea( OutputDevice* pDev, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ExtendPrintArea( pDev, nStartCol, nStartRow, rEndCol, nEndRow );
+}
+
+void ScDocument::IncSizeRecalcLevel( SCTAB nTab )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->IncRecalcLevel();
+}
+
+void ScDocument::DecSizeRecalcLevel( SCTAB nTab, bool bUpdateNoteCaptionPos )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->DecRecalcLevel( bUpdateNoteCaptionPos );
+}
+
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+ScDPTableDataCache* ScDocument::GetDPObjectCache( long nID )
+{
+ for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
+ { //
+ if ( nID == (*iter)->GetId() )
+ return *iter;
+ }
+ return NULL;
+}
+
+ScDPTableDataCache* ScDocument::GetUsedDPObjectCache ( ScRange rRange )
+{
+ ScDPTableDataCache* pCache = NULL;
+ USHORT nCount = GetDPCollection()->GetCount();
+ for ( short i=nCount-1; i>=0 ; i--)
+ {
+ if ( const ScSheetSourceDesc* pUsedSheetDesc = (*pDPCollection)[i]->GetSheetDesc() )
+ if ( rRange == pUsedSheetDesc->aSourceRange )
+ {
+ long nID = (*pDPCollection)[i]->GetCacheId();
+ if ( nID >= 0 )
+ pCache= GetDPObjectCache( nID );
+ if ( pCache )
+ return pCache;
+ }
+ }
+ return pCache;
+}
+
+long ScDocument::AddDPObjectCache( ScDPTableDataCache* pData )
+{
+ if ( pData->GetId() < 0 )
+ { //create a id for it
+ pData->SetId( GetNewDPObjectCacheId() );
+ }
+ m_listDPObjectsCaches.push_back( pData );
+ return pData->GetId();
+}
+
+long ScDocument::GetNewDPObjectCacheId()
+{
+ long nID = 0;
+
+ bool bFound = false;
+ std::list<ScDPTableDataCache*>::iterator iter;
+ do {
+ for ( iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
+ { //Get a new Id
+ if ( nID == (*iter)->GetId() )
+ {
+ nID++;
+ bFound = true;
+ break;
+ }
+ }
+ if ( iter == m_listDPObjectsCaches.end() )
+ bFound = false;
+ } while ( bFound );
+
+ return nID;
+}
+
+void ScDocument::RemoveDPObjectCache( long nID )
+{
+ for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
+ {
+ if ( nID == (*iter)->GetId() )
+ {
+ ScDPTableDataCache* pCache = *iter;
+ m_listDPObjectsCaches.erase( iter );
+ delete pCache;
+ break;
+ }
+ }
+
+}
+
+void ScDocument::RemoveUnusedDPObjectCaches()
+{
+ for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
+ {
+ long nID = (*iter)->GetId();
+ USHORT nCount = GetDPCollection()->GetCount();
+ USHORT i ;
+ for ( i=0; i<nCount; i++)
+ {
+ if ( nID == (*pDPCollection)[i]->GetCacheId() )
+ break;
+ }
+ if ( i == nCount )
+ {
+ ScDPTableDataCache* pCache = *iter;
+ m_listDPObjectsCaches.erase( iter );
+ delete pCache;
+ continue;
+ }
+ }
+}
+
+void ScDocument::GetUsedDPObjectCache( std::list<ScDPTableDataCache*>& usedlist )
+{
+ for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
+ {
+ long nID = (*iter)->GetId();
+ USHORT nCount = GetDPCollection()->GetCount();
+ USHORT i=0;
+ for ( i=0; i<nCount; i++)
+ if ( nID == (*pDPCollection)[i]->GetCacheId() )
+ break;
+ if ( i != nCount )
+ usedlist.push_back( *iter );
+ }
+}
+// End Comments
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
new file mode 100644
index 000000000000..e8b58b0f71d3
--- /dev/null
+++ b/sc/source/core/data/documen4.cxx
@@ -0,0 +1,1203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/sound.hxx>
+#include <formula/token.hxx>
+
+#include "document.hxx"
+#include "table.hxx"
+#include "globstr.hrc"
+#include "subtotal.hxx"
+#include "docoptio.hxx"
+#include "interpre.hxx"
+#include "markdata.hxx"
+#include "validat.hxx"
+#include "scitems.hxx"
+#include "stlpool.hxx"
+#include "poolhelp.hxx"
+#include "detdata.hxx"
+#include "patattr.hxx"
+#include "chgtrack.hxx"
+#include "progress.hxx"
+#include "paramisc.hxx"
+#include "compiler.hxx"
+#include "externalrefmgr.hxx"
+
+using namespace formula;
+
+// -----------------------------------------------------------------------
+
+// Nach der Regula Falsi Methode
+BOOL ScDocument::Solver(SCCOL nFCol, SCROW nFRow, SCTAB nFTab,
+ SCCOL nVCol, SCROW nVRow, SCTAB nVTab,
+ const String& sValStr, double& nX)
+{
+ BOOL bRet = FALSE;
+ nX = 0.0;
+ if (ValidColRow(nFCol, nFRow) && ValidColRow(nVCol, nVRow) &&
+ VALIDTAB(nFTab) && VALIDTAB(nVTab) && pTab[nFTab] && pTab[nVTab])
+ {
+ CellType eFType, eVType;
+ GetCellType(nFCol, nFRow, nFTab, eFType);
+ GetCellType(nVCol, nVRow, nVTab, eVType);
+ // CELLTYPE_NOTE: no value, but referenced by formula
+ // #i108005# convert target value to number using default format,
+ // as previously done in ScInterpreter::GetDouble
+ double nTargetVal = 0.0;
+ sal_uInt32 nFIndex = 0;
+ if (eFType == CELLTYPE_FORMULA && (eVType == CELLTYPE_VALUE || eVType == CELLTYPE_NOTE) &&
+ GetFormatTable()->IsNumberFormat(sValStr, nFIndex, nTargetVal))
+ {
+ ScSingleRefData aRefData;
+ aRefData.InitFlags();
+ aRefData.nCol = nVCol;
+ aRefData.nRow = nVRow;
+ aRefData.nTab = nVTab;
+
+ ScTokenArray aArr;
+ aArr.AddOpCode( ocBackSolver );
+ aArr.AddOpCode( ocOpen );
+ aArr.AddSingleReference( aRefData );
+ aArr.AddOpCode( ocSep );
+
+ aRefData.nCol = nFCol;
+ aRefData.nRow = nFRow;
+ aRefData.nTab = nFTab;
+
+ aArr.AddSingleReference( aRefData );
+ aArr.AddOpCode( ocSep );
+ aArr.AddDouble( nTargetVal );
+ aArr.AddOpCode( ocClose );
+ aArr.AddOpCode( ocStop );
+
+ ScFormulaCell* pCell = new ScFormulaCell( this, ScAddress(), &aArr );
+
+ if (pCell)
+ {
+ // FIXME FIXME FIXME this might need to be reworked now that we have formula::FormulaErrorToken and ScFormulaResult, double check !!!
+ DBG_ERRORFILE("ScDocument::Solver: -> ScFormulaCell::GetValueAlways might need reimplementation");
+ pCell->Interpret();
+ USHORT nErrCode = pCell->GetErrCode();
+ nX = pCell->GetValueAlways();
+ if (nErrCode == 0) // kein fehler beim Rechnen
+ bRet = TRUE;
+ delete pCell;
+ }
+ }
+ }
+ return bRet;
+}
+
+void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark,
+ const String& rFormula,
+ const ScTokenArray* pArr,
+ const formula::FormulaGrammar::Grammar eGram )
+{
+ PutInOrder(nCol1, nCol2);
+ PutInOrder(nRow1, nRow2);
+ SCTAB i, nTab1;
+ SCCOL j;
+ SCROW k;
+ i = 0;
+ BOOL bStop = FALSE;
+ while (i <= MAXTAB && !bStop) // erste markierte Tabelle finden
+ {
+ if (pTab[i] && rMark.GetTableSelect(i))
+ bStop = TRUE;
+ else
+ i++;
+ }
+ nTab1 = i;
+ if (i == MAXTAB + 1)
+ {
+ Sound::Beep();
+ DBG_ERROR("ScDocument::InsertMatrixFormula Keine Tabelle markiert");
+ return;
+ }
+
+ ScFormulaCell* pCell;
+ ScAddress aPos( nCol1, nRow1, nTab1 );
+ if (pArr)
+ pCell = new ScFormulaCell( this, aPos, pArr, eGram, MM_FORMULA );
+ else
+ pCell = new ScFormulaCell( this, aPos, rFormula, eGram, MM_FORMULA );
+ pCell->SetMatColsRows( nCol2 - nCol1 + 1, nRow2 - nRow1 + 1 );
+ for (i = 0; i <= MAXTAB; i++)
+ {
+ if (pTab[i] && rMark.GetTableSelect(i))
+ {
+ if (i == nTab1)
+ pTab[i]->PutCell(nCol1, nRow1, pCell);
+ else
+ pTab[i]->PutCell(nCol1, nRow1, pCell->CloneWithoutNote(*this, ScAddress( nCol1, nRow1, i), SC_CLONECELL_STARTLISTENING));
+ }
+ }
+
+ ScSingleRefData aRefData;
+ aRefData.InitFlags();
+ aRefData.nCol = nCol1;
+ aRefData.nRow = nRow1;
+ aRefData.nTab = nTab1;
+ aRefData.SetColRel( TRUE );
+ aRefData.SetRowRel( TRUE );
+ aRefData.SetTabRel( TRUE );
+ aRefData.CalcRelFromAbs( ScAddress( nCol1, nRow1, nTab1 ) );
+
+ ScTokenArray aArr;
+ ScToken* t = static_cast<ScToken*>(aArr.AddMatrixSingleReference( aRefData));
+
+ for (i = 0; i <= MAXTAB; i++)
+ {
+ if (pTab[i] && rMark.GetTableSelect(i))
+ {
+ pTab[i]->DoColResize( nCol1, nCol2, static_cast<SCSIZE>(nRow2 - nRow1 + 1) );
+ if (i != nTab1)
+ {
+ aRefData.nTab = i;
+ aRefData.nRelTab = i - nTab1;
+ t->GetSingleRef() = aRefData;
+ }
+ for (j = nCol1; j <= nCol2; j++)
+ {
+ for (k = nRow1; k <= nRow2; k++)
+ {
+ if (j != nCol1 || k != nRow1) // nicht in der ersten Zelle
+ {
+ // Array muss geklont werden, damit jede
+ // Zelle ein eigenes Array erhaelt!
+ aPos = ScAddress( j, k, i );
+ t->CalcRelFromAbs( aPos );
+ pCell = new ScFormulaCell( this, aPos, aArr.Clone(), eGram, MM_REFERENCE );
+ pTab[i]->PutCell(j, k, (ScBaseCell*) pCell);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScDocument::InsertTableOp(const ScTabOpParam& rParam, // Mehrfachoperation
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark)
+{
+ PutInOrder(nCol1, nCol2);
+ PutInOrder(nRow1, nRow2);
+ SCTAB i, nTab1;
+ SCCOL j;
+ SCROW k;
+ i = 0;
+ BOOL bStop = FALSE;
+ while (i <= MAXTAB && !bStop) // erste markierte Tabelle finden
+ {
+ if (pTab[i] && rMark.GetTableSelect(i))
+ bStop = TRUE;
+ else
+ i++;
+ }
+ nTab1 = i;
+ if (i == MAXTAB + 1)
+ {
+ Sound::Beep();
+ DBG_ERROR("ScDocument::InsertTableOp: Keine Tabelle markiert");
+ return;
+ }
+
+ ScRefAddress aRef;
+ String aForString = '=';
+ aForString += ScCompiler::GetNativeSymbol(ocTableOp);
+ aForString += ScCompiler::GetNativeSymbol( ocOpen);
+
+ const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
+ if (rParam.nMode == 0) // nur Spalte
+ {
+ aRef.Set( rParam.aRefFormulaCell.GetAddress(), TRUE, FALSE, FALSE );
+ aForString += aRef.GetRefString(this, nTab1);
+ aForString += sSep;
+ aForString += rParam.aRefColCell.GetRefString(this, nTab1);
+ aForString += sSep;
+ aRef.Set( nCol1, nRow1, nTab1, FALSE, TRUE, TRUE );
+ aForString += aRef.GetRefString(this, nTab1);
+ nCol1++;
+ nCol2 = Min( nCol2, (SCCOL)(rParam.aRefFormulaEnd.Col() -
+ rParam.aRefFormulaCell.Col() + nCol1 + 1));
+ }
+ else if (rParam.nMode == 1) // nur zeilenweise
+ {
+ aRef.Set( rParam.aRefFormulaCell.GetAddress(), FALSE, TRUE, FALSE );
+ aForString += aRef.GetRefString(this, nTab1);
+ aForString += sSep;
+ aForString += rParam.aRefRowCell.GetRefString(this, nTab1);
+ aForString += sSep;
+ aRef.Set( nCol1, nRow1, nTab1, TRUE, FALSE, TRUE );
+ aForString += aRef.GetRefString(this, nTab1);
+ nRow1++;
+ nRow2 = Min( nRow2, (SCROW)(rParam.aRefFormulaEnd.Row() -
+ rParam.aRefFormulaCell.Row() + nRow1 + 1));
+ }
+ else // beides
+ {
+ aForString += rParam.aRefFormulaCell.GetRefString(this, nTab1);
+ aForString += sSep;
+ aForString += rParam.aRefColCell.GetRefString(this, nTab1);
+ aForString += sSep;
+ aRef.Set( nCol1, nRow1 + 1, nTab1, FALSE, TRUE, TRUE );
+ aForString += aRef.GetRefString(this, nTab1);
+ aForString += sSep;
+ aForString += rParam.aRefRowCell.GetRefString(this, nTab1);
+ aForString += sSep;
+ aRef.Set( nCol1 + 1, nRow1, nTab1, TRUE, FALSE, TRUE );
+ aForString += aRef.GetRefString(this, nTab1);
+ nCol1++; nRow1++;
+ }
+ aForString += ScCompiler::GetNativeSymbol( ocClose);
+
+ ScFormulaCell aRefCell( this, ScAddress( nCol1, nRow1, nTab1 ), aForString,
+ formula::FormulaGrammar::GRAM_NATIVE, MM_NONE );
+ for( j = nCol1; j <= nCol2; j++ )
+ for( k = nRow1; k <= nRow2; k++ )
+ for (i = 0; i <= MAXTAB; i++)
+ if( pTab[i] && rMark.GetTableSelect(i) )
+ pTab[i]->PutCell( j, k, aRefCell.CloneWithoutNote( *this, ScAddress( j, k, i ), SC_CLONECELL_STARTLISTENING ) );
+}
+
+bool ScDocument::MarkUsedExternalReferences( ScTokenArray & rArr )
+{
+ bool bAllMarked = false;
+ if (rArr.GetLen())
+ {
+ ScExternalRefManager* pRefMgr = NULL;
+ rArr.Reset();
+ ScToken* t;
+ while (!bAllMarked && (t = static_cast<ScToken*>(rArr.GetNextReferenceOrName())) != NULL)
+ {
+ if (t->GetOpCode() == ocExternalRef)
+ {
+ if (!pRefMgr)
+ pRefMgr = GetExternalRefManager();
+ switch (t->GetType())
+ {
+ case svExternalSingleRef:
+ bAllMarked = pRefMgr->setCacheTableReferenced(
+ 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
+ * have to be marked as well, if so. Mechanism would be
+ * different. */
+ DBG_ERRORFILE("ScDocument::MarkUsedExternalReferences: implement the svExternalName case!");
+ break;
+ default: break;
+ }
+ }
+ }
+ }
+ return bAllMarked;
+}
+
+BOOL ScDocument::GetNextSpellingCell(SCCOL& nCol, SCROW& nRow, SCTAB nTab,
+ BOOL bInSel, const ScMarkData& rMark) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetNextSpellingCell( nCol, nRow, bInSel, rMark );
+ else
+ return FALSE;
+}
+
+BOOL ScDocument::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, SCTAB nTab,
+ const ScMarkData& rMark )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetNextMarkedCell( rCol, rRow, rMark );
+ else
+ return FALSE;
+}
+
+BOOL ScDocument::ReplaceStyle(const SvxSearchItem& rSearchItem,
+ SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScMarkData& rMark,
+ BOOL bIsUndoP)
+{
+ if (pTab[nTab])
+ return pTab[nTab]->ReplaceStyle(rSearchItem, nCol, nRow, rMark, bIsUndoP);
+ else
+ return FALSE;
+}
+
+void ScDocument::CompileDBFormula()
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ {
+ if (pTab[i]) pTab[i]->CompileDBFormula();
+ }
+}
+
+void ScDocument::CompileDBFormula( BOOL bCreateFormulaString )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ {
+ if (pTab[i]) pTab[i]->CompileDBFormula( bCreateFormulaString );
+ }
+}
+
+void ScDocument::CompileNameFormula( BOOL bCreateFormulaString )
+{
+ if ( pCondFormList )
+ pCondFormList->CompileAll(); // nach ScNameDlg noetig
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ {
+ if (pTab[i]) pTab[i]->CompileNameFormula( bCreateFormulaString );
+ }
+}
+
+void ScDocument::CompileColRowNameFormula()
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ {
+ if (pTab[i]) pTab[i]->CompileColRowNameFormula();
+ }
+}
+
+void ScDocument::DoColResize( SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->DoColResize( nCol1, nCol2, nAdd );
+ else
+ {
+ DBG_ERROR("DoColResize: falsche Tabelle");
+ }
+}
+
+void ScDocument::InvalidateTableArea()
+{
+ for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
+ {
+ pTab[nTab]->InvalidateTableArea();
+ if ( pTab[nTab]->IsScenario() )
+ pTab[nTab]->InvalidateScenarioRanges();
+ }
+}
+
+sal_Int32 ScDocument::GetMaxStringLen( SCTAB nTab, SCCOL nCol,
+ SCROW nRowStart, SCROW nRowEnd, CharSet eCharSet ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetMaxStringLen( nCol, nRowStart, nRowEnd, eCharSet );
+ else
+ return 0;
+}
+
+xub_StrLen ScDocument::GetMaxNumberStringLen( sal_uInt16& nPrecision, SCTAB nTab,
+ SCCOL nCol,
+ SCROW nRowStart, SCROW nRowEnd ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetMaxNumberStringLen( nPrecision, nCol,
+ nRowStart, nRowEnd );
+ else
+ return 0;
+}
+
+BOOL ScDocument::GetSelectionFunction( ScSubTotalFunc eFunc,
+ const ScAddress& rCursor, const ScMarkData& rMark,
+ double& rResult )
+{
+ ScFunctionData aData(eFunc);
+
+ ScRange aSingle( rCursor );
+ if ( rMark.IsMarked() )
+ rMark.GetMarkArea(aSingle);
+
+ SCCOL nStartCol = aSingle.aStart.Col();
+ SCROW nStartRow = aSingle.aStart.Row();
+ SCCOL nEndCol = aSingle.aEnd.Col();
+ SCROW nEndRow = aSingle.aEnd.Row();
+
+ for (SCTAB nTab=0; nTab<=MAXTAB && !aData.bError; nTab++)
+ if (pTab[nTab] && rMark.GetTableSelect(nTab))
+ pTab[nTab]->UpdateSelectionFunction( aData,
+ nStartCol, nStartRow, nEndCol, nEndRow, rMark );
+
+ //! rMark an UpdateSelectionFunction uebergeben !!!!!
+
+ if (!aData.bError)
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_SUM:
+ rResult = aData.nVal;
+ break;
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2:
+ rResult = aData.nCount;
+ break;
+ case SUBTOTAL_FUNC_AVE:
+ if (aData.nCount)
+ rResult = aData.nVal / (double) aData.nCount;
+ else
+ aData.bError = TRUE;
+ break;
+ case SUBTOTAL_FUNC_MAX:
+ case SUBTOTAL_FUNC_MIN:
+ if (aData.nCount)
+ rResult = aData.nVal;
+ else
+ aData.bError = TRUE;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (aData.bError)
+ rResult = 0.0;
+
+ return !aData.bError;
+}
+
+double ScDocument::RoundValueAsShown( double fVal, ULONG nFormat )
+{
+ short nType;
+ if ( (nType = GetFormatTable()->GetType( nFormat )) != NUMBERFORMAT_DATE
+ && nType != NUMBERFORMAT_TIME && nType != NUMBERFORMAT_DATETIME )
+ {
+ short nPrecision;
+ if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
+ {
+ nPrecision = (short)GetFormatTable()->GetFormatPrecision( nFormat );
+ switch ( nType )
+ {
+ case NUMBERFORMAT_PERCENT: // 0,41% == 0,0041
+ nPrecision += 2;
+ break;
+ case NUMBERFORMAT_SCIENTIFIC: // 1,23e-3 == 0,00123
+ {
+ if ( fVal > 0.0 )
+ nPrecision = sal::static_int_cast<short>( nPrecision - (short)floor( log10( fVal ) ) );
+ else if ( fVal < 0.0 )
+ nPrecision = sal::static_int_cast<short>( nPrecision - (short)floor( log10( -fVal ) ) );
+ break;
+ }
+ }
+ }
+ else
+ {
+ nPrecision = (short)GetDocOptions().GetStdPrecision();
+ // #i115512# no rounding for automatic decimals
+ if (nPrecision == static_cast<short>(SvNumberFormatter::UNLIMITED_PRECISION))
+ return fVal;
+ }
+ double fRound = ::rtl::math::round( fVal, nPrecision );
+ if ( ::rtl::math::approxEqual( fVal, fRound ) )
+ return fVal; // durch Rundung hoechstens Fehler
+ else
+ return fRound;
+ }
+ else
+ return fVal;
+}
+
+//
+// bedingte Formate und Gueltigkeitsbereiche
+//
+
+ULONG ScDocument::AddCondFormat( const ScConditionalFormat& rNew )
+{
+ if (rNew.IsEmpty())
+ return 0; // leer ist immer 0
+
+ if (!pCondFormList)
+ pCondFormList = new ScConditionalFormatList;
+
+ ULONG nMax = 0;
+ USHORT nCount = pCondFormList->Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ const ScConditionalFormat* pForm = (*pCondFormList)[i];
+ ULONG nKey = pForm->GetKey();
+ if ( pForm->EqualEntries( rNew ) )
+ return nKey;
+ if ( nKey > nMax )
+ nMax = nKey;
+ }
+
+ // Der Aufruf kann aus ScPatternAttr::PutInPool kommen, darum Clone (echte Kopie)
+
+ ULONG nNewKey = nMax + 1;
+ ScConditionalFormat* pInsert = rNew.Clone(this);
+ pInsert->SetKey( nNewKey );
+ pCondFormList->InsertNew( pInsert );
+ return nNewKey;
+}
+
+ULONG ScDocument::AddValidationEntry( const ScValidationData& rNew )
+{
+ if (rNew.IsEmpty())
+ return 0; // leer ist immer 0
+
+ if (!pValidationList)
+ pValidationList = new ScValidationDataList;
+
+ ULONG nMax = 0;
+ USHORT nCount = pValidationList->Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ const ScValidationData* pData = (*pValidationList)[i];
+ ULONG nKey = pData->GetKey();
+ if ( pData->EqualEntries( rNew ) )
+ return nKey;
+ if ( nKey > nMax )
+ nMax = nKey;
+ }
+
+ // Der Aufruf kann aus ScPatternAttr::PutInPool kommen, darum Clone (echte Kopie)
+
+ ULONG nNewKey = nMax + 1;
+ ScValidationData* pInsert = rNew.Clone(this);
+ pInsert->SetKey( nNewKey );
+ pValidationList->InsertNew( pInsert );
+ return nNewKey;
+}
+
+const SfxPoolItem* ScDocument::GetEffItem(
+ SCCOL nCol, SCROW nRow, SCTAB nTab, USHORT nWhich ) const
+{
+ const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
+ if ( pPattern )
+ {
+ const SfxItemSet& rSet = pPattern->GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( rSet.GetItemState( ATTR_CONDITIONAL, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ ULONG nIndex = ((const SfxUInt32Item*)pItem)->GetValue();
+ if (nIndex && pCondFormList)
+ {
+ const ScConditionalFormat* pForm = pCondFormList->GetFormat( nIndex );
+ if ( pForm )
+ {
+ ScBaseCell* pCell = ((ScDocument*)this)->GetCell(ScAddress(nCol,nRow,nTab));
+ String aStyle = pForm->GetCellStyle( pCell, ScAddress(nCol, nRow, nTab) );
+ if (aStyle.Len())
+ {
+ SfxStyleSheetBase* pStyleSheet = xPoolHelper->GetStylePool()->Find(
+ aStyle, SFX_STYLE_FAMILY_PARA );
+ if ( pStyleSheet && pStyleSheet->GetItemSet().GetItemState(
+ nWhich, TRUE, &pItem ) == SFX_ITEM_SET )
+ return pItem;
+ }
+ }
+ }
+ }
+ return &rSet.Get( nWhich );
+ }
+ DBG_ERROR("kein Pattern");
+ return NULL;
+}
+
+const SfxItemSet* ScDocument::GetCondResult( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ const ScConditionalFormat* pForm = GetCondFormat( nCol, nRow, nTab );
+ if ( pForm )
+ {
+ ScBaseCell* pCell = ((ScDocument*)this)->GetCell(ScAddress(nCol,nRow,nTab));
+ String aStyle = pForm->GetCellStyle( pCell, ScAddress(nCol, nRow, nTab) );
+ if (aStyle.Len())
+ {
+ SfxStyleSheetBase* pStyleSheet = xPoolHelper->GetStylePool()->Find( aStyle, SFX_STYLE_FAMILY_PARA );
+ if ( pStyleSheet )
+ return &pStyleSheet->GetItemSet();
+ // if style is not there, treat like no condition
+ }
+ }
+ return NULL;
+}
+
+const ScConditionalFormat* ScDocument::GetCondFormat(
+ SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ ULONG nIndex = ((const SfxUInt32Item*)GetAttr(nCol,nRow,nTab,ATTR_CONDITIONAL))->GetValue();
+ if (nIndex)
+ {
+ if (pCondFormList)
+ return pCondFormList->GetFormat( nIndex );
+ else
+ {
+ DBG_ERROR("pCondFormList ist 0");
+ }
+ }
+
+ return NULL;
+}
+
+const ScValidationData* ScDocument::GetValidationEntry( ULONG nIndex ) const
+{
+ if ( pValidationList )
+ return pValidationList->GetData( nIndex );
+ else
+ return NULL;
+}
+
+void ScDocument::FindConditionalFormat( ULONG nKey, ScRangeList& rRanges )
+{
+ for (SCTAB i=0; i<=MAXTAB && pTab[i]; i++)
+ pTab[i]->FindConditionalFormat( nKey, rRanges );
+}
+
+void ScDocument::FindConditionalFormat( ULONG nKey, ScRangeList& rRanges, SCTAB nTab )
+{
+ if(VALIDTAB(nTab) && pTab[nTab])
+ pTab[nTab]->FindConditionalFormat( nKey, rRanges );
+}
+
+void ScDocument::ConditionalChanged( ULONG nKey )
+{
+ if ( nKey && pCondFormList && !bIsClip && !bIsUndo ) // nKey==0 -> noop
+ {
+ ScConditionalFormat* pForm = pCondFormList->GetFormat( nKey );
+ if (pForm)
+ pForm->InvalidateArea();
+ }
+}
+
+void ScDocument::SetCondFormList(ScConditionalFormatList* pNew)
+{
+ if (pCondFormList)
+ {
+ pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
+ delete pCondFormList;
+ }
+
+ pCondFormList = pNew;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocument::HasDetectiveOperations() const
+{
+ return pDetOpList && pDetOpList->Count();
+}
+
+void ScDocument::AddDetectiveOperation( const ScDetOpData& rData )
+{
+ if (!pDetOpList)
+ pDetOpList = new ScDetOpList;
+
+ pDetOpList->Append( new ScDetOpData( rData ) );
+}
+
+void ScDocument::ClearDetectiveOperations()
+{
+ delete pDetOpList; // loescht auch die Eintraege
+ pDetOpList = NULL;
+}
+
+void ScDocument::SetDetOpList(ScDetOpList* pNew)
+{
+ delete pDetOpList; // loescht auch die Eintraege
+ pDetOpList = pNew;
+}
+
+//------------------------------------------------------------------------
+//
+// Vergleich von Dokumenten
+//
+//------------------------------------------------------------------------
+
+// Pfriemel-Faktoren
+#define SC_DOCCOMP_MAXDIFF 256
+#define SC_DOCCOMP_MINGOOD 128
+#define SC_DOCCOMP_COLUMNS 10
+#define SC_DOCCOMP_ROWS 100
+
+
+USHORT ScDocument::RowDifferences( SCROW nThisRow, SCTAB nThisTab,
+ ScDocument& rOtherDoc, SCROW nOtherRow, SCTAB nOtherTab,
+ SCCOL nMaxCol, SCCOLROW* pOtherCols )
+{
+ ULONG nDif = 0;
+ ULONG nUsed = 0;
+ for (SCCOL nThisCol=0; nThisCol<=nMaxCol; nThisCol++)
+ {
+ SCCOL nOtherCol;
+ if ( pOtherCols )
+ nOtherCol = static_cast<SCCOL>(pOtherCols[nThisCol]);
+ else
+ nOtherCol = nThisCol;
+
+ if (ValidCol(nOtherCol)) // nur Spalten vergleichen, die in beiden Dateien sind
+ {
+ const ScBaseCell* pThisCell = GetCell( ScAddress( nThisCol, nThisRow, nThisTab ) );
+ const ScBaseCell* pOtherCell = rOtherDoc.GetCell( ScAddress( nOtherCol, nOtherRow, nOtherTab ) );
+ if (!ScBaseCell::CellEqual( pThisCell, pOtherCell ))
+ {
+ if ( pThisCell && pOtherCell )
+ nDif += 3;
+ else
+ nDif += 4; // Inhalt <-> leer zaehlt mehr
+ }
+
+ if ( ( pThisCell && pThisCell->GetCellType()!=CELLTYPE_NOTE ) ||
+ ( pOtherCell && pOtherCell->GetCellType()!=CELLTYPE_NOTE ) )
+ ++nUsed;
+ }
+ }
+
+ if (nUsed > 0)
+ return static_cast<USHORT>((nDif*64)/nUsed); // max.256 (SC_DOCCOMP_MAXDIFF)
+
+ DBG_ASSERT(!nDif,"Diff ohne Used");
+ return 0;
+}
+
+USHORT ScDocument::ColDifferences( SCCOL nThisCol, SCTAB nThisTab,
+ ScDocument& rOtherDoc, SCCOL nOtherCol, SCTAB nOtherTab,
+ SCROW nMaxRow, SCCOLROW* pOtherRows )
+{
+ //! optimieren mit Iterator oder so
+
+ ULONG nDif = 0;
+ ULONG nUsed = 0;
+ for (SCROW nThisRow=0; nThisRow<=nMaxRow; nThisRow++)
+ {
+ SCROW nOtherRow;
+ if ( pOtherRows )
+ nOtherRow = pOtherRows[nThisRow];
+ else
+ nOtherRow = nThisRow;
+
+ if (ValidRow(nOtherRow)) // nur Zeilen vergleichen, die in beiden Dateien sind
+ {
+ const ScBaseCell* pThisCell = GetCell( ScAddress( nThisCol, nThisRow, nThisTab ) );
+ const ScBaseCell* pOtherCell = rOtherDoc.GetCell( ScAddress( nOtherCol, nOtherRow, nOtherTab ) );
+ if (!ScBaseCell::CellEqual( pThisCell, pOtherCell ))
+ {
+ if ( pThisCell && pOtherCell )
+ nDif += 3;
+ else
+ nDif += 4; // Inhalt <-> leer zaehlt mehr
+ }
+
+ if ( ( pThisCell && pThisCell->GetCellType()!=CELLTYPE_NOTE ) ||
+ ( pOtherCell && pOtherCell->GetCellType()!=CELLTYPE_NOTE ) )
+ ++nUsed;
+ }
+ }
+
+ if (nUsed > 0)
+ return static_cast<USHORT>((nDif*64)/nUsed); // max.256
+
+ DBG_ASSERT(!nDif,"Diff ohne Used");
+ return 0;
+}
+
+void ScDocument::FindOrder( SCCOLROW* pOtherRows, SCCOLROW nThisEndRow, SCCOLROW nOtherEndRow,
+ BOOL bColumns, ScDocument& rOtherDoc, SCTAB nThisTab, SCTAB nOtherTab,
+ SCCOLROW nEndCol, SCCOLROW* pTranslate, ScProgress* pProgress, ULONG nProAdd )
+{
+ // bColumns=TRUE: Zeilen sind Spalten und umgekehrt
+
+ SCCOLROW nMaxCont; // wieviel weiter
+ SCCOLROW nMinGood; // was ist ein Treffer (incl.)
+ if ( bColumns )
+ {
+ nMaxCont = SC_DOCCOMP_COLUMNS; // 10 Spalten
+ nMinGood = SC_DOCCOMP_MINGOOD;
+ //! Extra Durchgang mit nMinGood = 0 ????
+ }
+ else
+ {
+ nMaxCont = SC_DOCCOMP_ROWS; // 100 Zeilen
+ nMinGood = SC_DOCCOMP_MINGOOD;
+ }
+ BOOL bUseTotal = bColumns && !pTranslate; // nur beim ersten Durchgang
+
+
+ SCCOLROW nOtherRow = 0;
+ USHORT nComp;
+ SCCOLROW nThisRow;
+ BOOL bTotal = FALSE; // ueber verschiedene nThisRow beibehalten
+ SCCOLROW nUnknown = 0;
+ for (nThisRow = 0; nThisRow <= nThisEndRow; nThisRow++)
+ {
+ SCCOLROW nTempOther = nOtherRow;
+ BOOL bFound = FALSE;
+ USHORT nBest = SC_DOCCOMP_MAXDIFF;
+ SCCOLROW nMax = Min( nOtherEndRow, static_cast<SCCOLROW>(( nTempOther + nMaxCont + nUnknown )) );
+ for (SCCOLROW i=nTempOther; i<=nMax && nBest>0; i++) // bei 0 abbrechen
+ {
+ if (bColumns)
+ nComp = ColDifferences( static_cast<SCCOL>(nThisRow), nThisTab, rOtherDoc, static_cast<SCCOL>(i), nOtherTab, nEndCol, pTranslate );
+ else
+ nComp = RowDifferences( nThisRow, nThisTab, rOtherDoc, i, nOtherTab, static_cast<SCCOL>(nEndCol), pTranslate );
+ if ( nComp < nBest && ( nComp <= nMinGood || bTotal ) )
+ {
+ nTempOther = i;
+ nBest = nComp;
+ bFound = TRUE;
+ }
+ if ( nComp < SC_DOCCOMP_MAXDIFF || bFound )
+ bTotal = FALSE;
+ else if ( i == nTempOther && bUseTotal )
+ bTotal = TRUE; // nur ganz oben
+ }
+ if ( bFound )
+ {
+ pOtherRows[nThisRow] = nTempOther;
+ nOtherRow = nTempOther + 1;
+ nUnknown = 0;
+ }
+ else
+ {
+ pOtherRows[nThisRow] = SCROW_MAX;
+ ++nUnknown;
+ }
+
+ if (pProgress)
+ pProgress->SetStateOnPercent(nProAdd+static_cast<ULONG>(nThisRow));
+ }
+
+ // Bloecke ohne Uebereinstimmung ausfuellen
+
+ SCROW nFillStart = 0;
+ SCROW nFillPos = 0;
+ BOOL bInFill = FALSE;
+ for (nThisRow = 0; nThisRow <= nThisEndRow+1; nThisRow++)
+ {
+ SCROW nThisOther = ( nThisRow <= nThisEndRow ) ? pOtherRows[nThisRow] : (nOtherEndRow+1);
+ if ( ValidRow(nThisOther) )
+ {
+ if ( bInFill )
+ {
+ if ( nThisOther > nFillStart ) // ist was zu verteilen da?
+ {
+ SCROW nDiff1 = nThisOther - nFillStart;
+ SCROW nDiff2 = nThisRow - nFillPos;
+ SCROW nMinDiff = Min(nDiff1, nDiff2);
+ for (SCROW i=0; i<nMinDiff; i++)
+ pOtherRows[nFillPos+i] = nFillStart+i;
+ }
+
+ bInFill = FALSE;
+ }
+ nFillStart = nThisOther + 1;
+ nFillPos = nThisRow + 1;
+ }
+ else
+ bInFill = TRUE;
+ }
+}
+
+void ScDocument::CompareDocument( ScDocument& rOtherDoc )
+{
+ if (!pChangeTrack)
+ return;
+
+ SCTAB nThisCount = GetTableCount();
+ SCTAB nOtherCount = rOtherDoc.GetTableCount();
+ SCTAB* pOtherTabs = new SCTAB[nThisCount];
+ SCTAB nThisTab;
+
+ // Tabellen mit gleichen Namen vergleichen
+ String aThisName;
+ String aOtherName;
+ for (nThisTab=0; nThisTab<nThisCount; nThisTab++)
+ {
+ SCTAB nOtherTab = SCTAB_MAX;
+ if (!IsScenario(nThisTab)) // Szenarien weglassen
+ {
+ GetName( nThisTab, aThisName );
+ for (SCTAB nTemp=0; nTemp<nOtherCount && nOtherTab>MAXTAB; nTemp++)
+ if (!rOtherDoc.IsScenario(nTemp))
+ {
+ rOtherDoc.GetName( nTemp, aOtherName );
+ if ( aThisName == aOtherName )
+ nOtherTab = nTemp;
+ }
+ }
+ pOtherTabs[nThisTab] = nOtherTab;
+ }
+ // auffuellen, damit einzeln umbenannte Tabellen nicht wegfallen
+ SCTAB nFillStart = 0;
+ SCTAB nFillPos = 0;
+ BOOL bInFill = FALSE;
+ for (nThisTab = 0; nThisTab <= nThisCount; nThisTab++)
+ {
+ SCTAB nThisOther = ( nThisTab < nThisCount ) ? pOtherTabs[nThisTab] : nOtherCount;
+ if ( ValidTab(nThisOther) )
+ {
+ if ( bInFill )
+ {
+ if ( nThisOther > nFillStart ) // ist was zu verteilen da?
+ {
+ SCTAB nDiff1 = nThisOther - nFillStart;
+ SCTAB nDiff2 = nThisTab - nFillPos;
+ SCTAB nMinDiff = Min(nDiff1, nDiff2);
+ for (SCTAB i=0; i<nMinDiff; i++)
+ if ( !IsScenario(nFillPos+i) && !rOtherDoc.IsScenario(nFillStart+i) )
+ pOtherTabs[nFillPos+i] = nFillStart+i;
+ }
+
+ bInFill = FALSE;
+ }
+ nFillStart = nThisOther + 1;
+ nFillPos = nThisTab + 1;
+ }
+ else
+ bInFill = TRUE;
+ }
+
+ //
+ // Tabellen in der gefundenen Reihenfolge vergleichen
+ //
+
+ for (nThisTab=0; nThisTab<nThisCount; nThisTab++)
+ {
+ SCTAB nOtherTab = pOtherTabs[nThisTab];
+ if ( ValidTab(nOtherTab) )
+ {
+ SCCOL nThisEndCol = 0;
+ SCROW nThisEndRow = 0;
+ SCCOL nOtherEndCol = 0;
+ SCROW nOtherEndRow = 0;
+ GetCellArea( nThisTab, nThisEndCol, nThisEndRow );
+ rOtherDoc.GetCellArea( nOtherTab, nOtherEndCol, nOtherEndRow );
+ SCCOL nEndCol = Max(nThisEndCol, nOtherEndCol);
+ SCROW nEndRow = Max(nThisEndRow, nOtherEndRow);
+ SCCOL nThisCol;
+ SCROW nThisRow;
+ ULONG n1,n2; // fuer AppendDeleteRange
+
+ //! ein Progress ueber alle Tabellen ???
+ String aTabName;
+ GetName( nThisTab, aTabName );
+ String aTemplate = ScGlobal::GetRscString(STR_PROGRESS_COMPARING);
+ String aProText = aTemplate.GetToken( 0, '#' );
+ aProText += aTabName;
+ aProText += aTemplate.GetToken( 1, '#' );
+ ScProgress aProgress( GetDocumentShell(),
+ aProText, 3*nThisEndRow ); // 2x FindOrder, 1x hier
+ long nProgressStart = 2*nThisEndRow; // start fuer hier
+
+ SCCOLROW* pTempRows = new SCCOLROW[nThisEndRow+1];
+ SCCOLROW* pOtherRows = new SCCOLROW[nThisEndRow+1];
+ SCCOLROW* pOtherCols = new SCCOLROW[nThisEndCol+1];
+
+ // eingefuegte/geloeschte Spalten/Zeilen finden:
+ // Zwei Versuche:
+ // 1) Original Zeilen vergleichen (pTempRows)
+ // 2) Original Spalten vergleichen (pOtherCols)
+ // mit dieser Spaltenreihenfolge Zeilen vergleichen (pOtherRows)
+
+ //! Spalten vergleichen zweimal mit unterschiedlichem nMinGood ???
+
+ // 1
+ FindOrder( pTempRows, nThisEndRow, nOtherEndRow, FALSE,
+ rOtherDoc, nThisTab, nOtherTab, nEndCol, NULL, &aProgress, 0 );
+ // 2
+ FindOrder( pOtherCols, nThisEndCol, nOtherEndCol, TRUE,
+ rOtherDoc, nThisTab, nOtherTab, nEndRow, NULL, NULL, 0 );
+ FindOrder( pOtherRows, nThisEndRow, nOtherEndRow, FALSE,
+ rOtherDoc, nThisTab, nOtherTab, nThisEndCol,
+ pOtherCols, &aProgress, nThisEndRow );
+
+ ULONG nMatch1 = 0; // pTempRows, keine Spalten
+ for (nThisRow = 0; nThisRow<=nThisEndRow; nThisRow++)
+ if (ValidRow(pTempRows[nThisRow]))
+ nMatch1 += SC_DOCCOMP_MAXDIFF -
+ RowDifferences( nThisRow, nThisTab, rOtherDoc, pTempRows[nThisRow],
+ nOtherTab, nEndCol, NULL );
+
+ ULONG nMatch2 = 0; // pOtherRows, pOtherCols
+ for (nThisRow = 0; nThisRow<=nThisEndRow; nThisRow++)
+ if (ValidRow(pOtherRows[nThisRow]))
+ nMatch2 += SC_DOCCOMP_MAXDIFF -
+ RowDifferences( nThisRow, nThisTab, rOtherDoc, pOtherRows[nThisRow],
+ nOtherTab, nThisEndCol, pOtherCols );
+
+ if ( nMatch1 >= nMatch2 ) // ohne Spalten ?
+ {
+ // Spalten zuruecksetzen
+ for (nThisCol = 0; nThisCol<=nThisEndCol; nThisCol++)
+ pOtherCols[nThisCol] = nThisCol;
+
+ // Zeilenarrays vertauschen (geloescht werden sowieso beide)
+ SCCOLROW* pSwap = pTempRows;
+ pTempRows = pOtherRows;
+ pOtherRows = pSwap;
+ }
+ else
+ {
+ // bleibt bei pOtherCols, pOtherRows
+ }
+
+
+ // Change-Actions erzeugen
+ // 1) Spalten von rechts
+ // 2) Zeilen von unten
+ // 3) einzelne Zellen in normaler Reihenfolge
+
+ // Actions fuer eingefuegte/geloeschte Spalten
+
+ SCCOL nLastOtherCol = static_cast<SCCOL>(nOtherEndCol + 1);
+ // nThisEndCol ... 0
+ for ( nThisCol = nThisEndCol+1; nThisCol > 0; )
+ {
+ --nThisCol;
+ SCCOL nOtherCol = static_cast<SCCOL>(pOtherCols[nThisCol]);
+ if ( ValidCol(nOtherCol) && nOtherCol+1 < nLastOtherCol )
+ {
+ // Luecke -> geloescht
+ ScRange aDelRange( nOtherCol+1, 0, nOtherTab,
+ nLastOtherCol-1, MAXROW, nOtherTab );
+ pChangeTrack->AppendDeleteRange( aDelRange, &rOtherDoc, n1, n2 );
+ }
+ if ( nOtherCol > MAXCOL ) // eingefuegt
+ {
+ // zusammenfassen
+ if ( nThisCol == nThisEndCol || ValidCol(static_cast<SCCOL>(pOtherCols[nThisCol+1])) )
+ {
+ SCCOL nFirstNew = static_cast<SCCOL>(nThisCol);
+ while ( nFirstNew > 0 && pOtherCols[nFirstNew-1] > MAXCOL )
+ --nFirstNew;
+ SCCOL nDiff = nThisCol - nFirstNew;
+ ScRange aRange( nLastOtherCol, 0, nOtherTab,
+ nLastOtherCol+nDiff, MAXROW, nOtherTab );
+ pChangeTrack->AppendInsert( aRange );
+ }
+ }
+ else
+ nLastOtherCol = nOtherCol;
+ }
+ if ( nLastOtherCol > 0 ) // ganz oben geloescht
+ {
+ ScRange aDelRange( 0, 0, nOtherTab,
+ nLastOtherCol-1, MAXROW, nOtherTab );
+ pChangeTrack->AppendDeleteRange( aDelRange, &rOtherDoc, n1, n2 );
+ }
+
+ // Actions fuer eingefuegte/geloeschte Zeilen
+
+ SCROW nLastOtherRow = nOtherEndRow + 1;
+ // nThisEndRow ... 0
+ for ( nThisRow = nThisEndRow+1; nThisRow > 0; )
+ {
+ --nThisRow;
+ SCROW nOtherRow = pOtherRows[nThisRow];
+ if ( ValidRow(nOtherRow) && nOtherRow+1 < nLastOtherRow )
+ {
+ // Luecke -> geloescht
+ ScRange aDelRange( 0, nOtherRow+1, nOtherTab,
+ MAXCOL, nLastOtherRow-1, nOtherTab );
+ pChangeTrack->AppendDeleteRange( aDelRange, &rOtherDoc, n1, n2 );
+ }
+ if ( nOtherRow > MAXROW ) // eingefuegt
+ {
+ // zusammenfassen
+ if ( nThisRow == nThisEndRow || ValidRow(pOtherRows[nThisRow+1]) )
+ {
+ SCROW nFirstNew = nThisRow;
+ while ( nFirstNew > 0 && pOtherRows[nFirstNew-1] > MAXROW )
+ --nFirstNew;
+ SCROW nDiff = nThisRow - nFirstNew;
+ ScRange aRange( 0, nLastOtherRow, nOtherTab,
+ MAXCOL, nLastOtherRow+nDiff, nOtherTab );
+ pChangeTrack->AppendInsert( aRange );
+ }
+ }
+ else
+ nLastOtherRow = nOtherRow;
+ }
+ if ( nLastOtherRow > 0 ) // ganz oben geloescht
+ {
+ ScRange aDelRange( 0, 0, nOtherTab,
+ MAXCOL, nLastOtherRow-1, nOtherTab );
+ pChangeTrack->AppendDeleteRange( aDelRange, &rOtherDoc, n1, n2 );
+ }
+
+ // Zeilen durchgehen um einzelne Zellen zu finden
+
+ for (nThisRow = 0; nThisRow <= nThisEndRow; nThisRow++)
+ {
+ SCROW nOtherRow = pOtherRows[nThisRow];
+ for (nThisCol = 0; nThisCol <= nThisEndCol; nThisCol++)
+ {
+ SCCOL nOtherCol = static_cast<SCCOL>(pOtherCols[nThisCol]);
+ ScAddress aThisPos( nThisCol, nThisRow, nThisTab );
+ const ScBaseCell* pThisCell = GetCell( aThisPos );
+ const ScBaseCell* pOtherCell = NULL;
+ if ( ValidCol(nOtherCol) && ValidRow(nOtherRow) )
+ {
+ ScAddress aOtherPos( nOtherCol, nOtherRow, nOtherTab );
+ pOtherCell = rOtherDoc.GetCell( aOtherPos );
+ }
+ if ( !ScBaseCell::CellEqual( pThisCell, pOtherCell ) )
+ {
+ ScRange aRange( aThisPos );
+ ScChangeActionContent* pAction = new ScChangeActionContent( aRange );
+ pAction->SetOldValue( pOtherCell, &rOtherDoc, this );
+ pAction->SetNewValue( pThisCell, this );
+ pChangeTrack->Append( pAction );
+ }
+ }
+ aProgress.SetStateOnPercent(nProgressStart+nThisRow);
+ }
+
+ delete[] pOtherCols;
+ delete[] pOtherRows;
+ delete[] pTempRows;
+ }
+ }
+
+ //! Inhalt von eingefuegten / geloeschten Tabellen ???
+ //! Aktionen fuer eingefuegte / geloeschte Tabellen ???
+
+ delete[] pOtherTabs;
+}
+
+
+
+
+
diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx
new file mode 100644
index 000000000000..d86d174ab414
--- /dev/null
+++ b/sc/source/core/data/documen5.cxx
@@ -0,0 +1,794 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/objsh.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+
+//REMOVE #ifndef SO2_DECL_SVINPLACEOBJECT_DEFINED
+//REMOVE #define SO2_DECL_SVINPLACEOBJECT_DEFINED
+//REMOVE SO2_DECL_REF(SvInPlaceObject)
+//REMOVE #endif
+
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "chartarr.hxx"
+#include "chartlis.hxx"
+#include "chartlock.hxx"
+#include "refupdat.hxx"
+#include <tools/globname.hxx>
+#include <sot/exchange.hxx>
+
+#include "miscuno.hxx"
+#include "chart2uno.hxx"
+#include "charthelper.hxx"
+
+using namespace ::com::sun::star;
+
+// -----------------------------------------------------------------------
+
+void lcl_GetChartParameters( const uno::Reference< chart2::XChartDocument >& xChartDoc,
+ rtl::OUString& rRanges, chart::ChartDataRowSource& rDataRowSource,
+ bool& rHasCategories, bool& rFirstCellAsLabel )
+{
+ rHasCategories = rFirstCellAsLabel = false; // default if not in sequence
+
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
+
+ uno::Reference< chart2::data::XDataSource > xDataSource = xReceiver->getUsedData();
+ uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
+
+ if ( xProvider.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xDataSource ) );
+
+ const beans::PropertyValue* pPropArray = aArgs.getConstArray();
+ long nPropCount = aArgs.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( "CellRangeRepresentation" ))
+ rProp.Value >>= rRanges;
+ else if (aPropName.EqualsAscii( "DataRowSource" ))
+ rDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( "HasCategories" ))
+ rHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( "FirstCellAsLabel" ))
+ rFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ }
+ }
+}
+
+void lcl_SetChartParameters( const uno::Reference< chart2::data::XDataReceiver >& xReceiver,
+ const rtl::OUString& rRanges, chart::ChartDataRowSource eDataRowSource,
+ bool bHasCategories, bool bFirstCellAsLabel )
+{
+ if ( xReceiver.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aArgs( 4 );
+ aArgs[0] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
+ uno::makeAny( rRanges ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[1] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("HasCategories"), -1,
+ uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[2] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
+ uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[3] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("DataRowSource"), -1,
+ uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
+ xReceiver->setArguments( aArgs );
+ }
+}
+
+// update charts after loading old document
+
+void ScDocument::UpdateAllCharts()
+{
+ if ( !pDrawLayer || !pShell )
+ return;
+
+ USHORT nDataCount = pChartCollection->GetCount();
+ if ( !nDataCount )
+ return ; // nothing to do
+
+ USHORT nPos;
+
+ for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
+ {
+ if (pTab[nTab])
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ ScRange aRange;
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if ( xIPObj.is() )
+ {
+ String aIPName = ((SdrOle2Obj*)pObject)->GetPersistName();
+
+ for (nPos=0; nPos<nDataCount; nPos++)
+ {
+ ScChartArray* pChartObj = (*pChartCollection)[nPos];
+ if (pChartObj->GetName() == aIPName)
+ {
+ ScRangeListRef aRanges = pChartObj->GetRangeList();
+ String sRangeStr;
+ aRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
+
+ chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
+ bool bHasCategories = pChartObj->HasRowHeaders();
+ bool bFirstCellAsLabel = pChartObj->HasColHeaders();
+
+ // Calc -> DataProvider
+ uno::Reference< chart2::data::XDataProvider > xDataProvider =
+ new ScChart2DataProvider( this );
+ // Chart -> DataReceiver
+ uno::Reference< chart2::data::XDataReceiver > xReceiver;
+ uno::Reference< embed::XComponentSupplier > xCompSupp( xIPObj, uno::UNO_QUERY );
+ if( xCompSupp.is())
+ xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
+ if( xReceiver.is())
+ {
+ // connect
+ xReceiver->attachDataProvider( xDataProvider );
+ uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier(
+ pShell->GetModel(), uno::UNO_QUERY );
+ xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
+
+ lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource,
+ bHasCategories, bFirstCellAsLabel );
+ }
+
+ ScChartListener* pCL = new ScChartListener(
+ aIPName, this, pChartObj->GetRangeList() );
+ pChartListenerCollection->Insert( pCL );
+ pCL->StartListeningTo();
+ }
+ }
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ pChartCollection->FreeAll();
+}
+
+BOOL ScDocument::HasChartAtPoint( SCTAB nTab, const Point& rPos, String* pName )
+{
+ if (pDrawLayer && pTab[nTab])
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ pObject->GetCurrentBoundRect().IsInside(rPos) )
+ {
+ // auch Chart-Objekte die nicht in der Collection sind
+
+ if (IsChart(pObject))
+ {
+ if (pName)
+ *pName = ((SdrOle2Obj*)pObject)->GetPersistName();
+ return TRUE;
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+
+ if (pName)
+ pName->Erase();
+ return FALSE; // nix gefunden
+}
+
+void ScDocument::UpdateChartArea( const String& rChartName,
+ const ScRange& rNewArea, BOOL bColHeaders, BOOL bRowHeaders,
+ BOOL bAdd )
+{
+ ScRangeListRef aRLR( new ScRangeList );
+ aRLR->Append( rNewArea );
+ UpdateChartArea( rChartName, aRLR, bColHeaders, bRowHeaders, bAdd );
+}
+
+uno::Reference< chart2::XChartDocument > ScDocument::GetChartByName( const String& rChartName )
+{
+ uno::Reference< chart2::XChartDocument > xReturn;
+
+ if (pDrawLayer)
+ {
+ sal_uInt16 nCount = pDrawLayer->GetPageCount();
+ for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(nTab);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName )
+ {
+ xReturn.set( ScChartHelper::GetChartFromSdrObject( pObject ) );
+ return xReturn;
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ return xReturn;
+}
+void ScDocument::GetChartRanges( const String& rChartName, ::std::vector< ScRangeList >& rRangesVector, ScDocument* pSheetNameDoc )
+{
+ rRangesVector.clear();
+ uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
+ if ( xChartDoc.is() )
+ {
+ uno::Sequence< rtl::OUString > aRangeStrings;
+ ScChartHelper::GetChartRanges( xChartDoc, aRangeStrings );
+ for( sal_Int32 nN=0; nN<aRangeStrings.getLength(); nN++ )
+ {
+ ScRangeList aRanges;
+ aRanges.Parse( aRangeStrings[nN], pSheetNameDoc, SCA_VALID, pSheetNameDoc->GetAddressConvention() );
+ rRangesVector.push_back(aRanges);
+ }
+ }
+}
+
+void ScDocument::SetChartRanges( const String& rChartName, const ::std::vector< ScRangeList >& rRangesVector )
+{
+ uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
+ if ( xChartDoc.is() )
+ {
+ sal_Int32 nCount = static_cast<sal_Int32>( rRangesVector.size() );
+ uno::Sequence< rtl::OUString > aRangeStrings(nCount);
+ for( sal_Int32 nN=0; nN<nCount; nN++ )
+ {
+ ScRangeList aScRangeList( rRangesVector[nN] );
+ String sRangeStr; // This range must be in Calc A1 format.
+ aScRangeList.Format( sRangeStr, SCR_ABS_3D, this );
+ aRangeStrings[nN]=sRangeStr;
+ }
+ ScChartHelper::SetChartRanges( xChartDoc, aRangeStrings );
+ }
+}
+
+void ScDocument::GetOldChartParameters( const String& rName,
+ ScRangeList& rRanges, BOOL& rColHeaders, BOOL& rRowHeaders )
+{
+ // used for undo of changing chart source area
+
+ if (!pDrawLayer)
+ return;
+
+ sal_uInt16 nCount = pDrawLayer->GetPageCount();
+ for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(nTab);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ ((SdrOle2Obj*)pObject)->GetPersistName() == rName )
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) );
+ if ( xChartDoc.is() )
+ {
+ chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
+ bool bHasCategories = false;
+ bool bFirstCellAsLabel = false;
+ rtl::OUString aRangesStr;
+ lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
+
+ rRanges.Parse( aRangesStr, this );
+ if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
+ {
+ rRowHeaders = bHasCategories;
+ rColHeaders = bFirstCellAsLabel;
+ }
+ else
+ {
+ rColHeaders = bHasCategories;
+ rRowHeaders = bFirstCellAsLabel;
+ }
+ }
+ return;
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+
+void ScDocument::UpdateChartArea( const String& rChartName,
+ const ScRangeListRef& rNewList, BOOL bColHeaders, BOOL bRowHeaders,
+ BOOL bAdd )
+{
+ if (!pDrawLayer)
+ return;
+
+ for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName )
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) );
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
+ if ( xChartDoc.is() && xReceiver.is() )
+ {
+ ScRangeListRef aNewRanges;
+ chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
+ bool bHasCategories = false;
+ bool bFirstCellAsLabel = false;
+ rtl::OUString aRangesStr;
+ lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
+
+ sal_Bool bInternalData = xChartDoc->hasInternalDataProvider();
+
+ if ( bAdd && !bInternalData )
+ {
+ // append to old ranges, keep other settings
+
+ aNewRanges = new ScRangeList;
+ aNewRanges->Parse( aRangesStr, this );
+
+ ULONG nAddCount = rNewList->Count();
+ for ( ULONG nAdd=0; nAdd<nAddCount; nAdd++ )
+ aNewRanges->Append( *rNewList->GetObject(nAdd) );
+ }
+ else
+ {
+ // directly use new ranges (only eDataRowSource is used from old settings)
+
+ if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
+ {
+ bHasCategories = bRowHeaders;
+ bFirstCellAsLabel = bColHeaders;
+ }
+ else
+ {
+ bHasCategories = bColHeaders;
+ bFirstCellAsLabel = bRowHeaders;
+ }
+ aNewRanges = rNewList;
+ }
+
+ if ( bInternalData && pShell )
+ {
+ // Calc -> DataProvider
+ uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( this );
+ xReceiver->attachDataProvider( xDataProvider );
+ uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier(
+ pShell->GetModel(), uno::UNO_QUERY );
+ xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
+ }
+
+ String sRangeStr;
+ aNewRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
+
+ lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
+
+ pChartListenerCollection->ChangeListening( rChartName, aNewRanges );
+
+ // ((SdrOle2Obj*)pObject)->GetNewReplacement();
+ // pObject->ActionChanged();
+
+ return; // nicht weitersuchen
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+
+void ScDocument::UpdateChart( const String& rChartName )
+{
+ if (!pDrawLayer || bInDtorClear)
+ return;
+ uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
+ if( xChartDoc.is() )
+ {
+ try
+ {
+ uno::Reference< util::XModifiable > xModif( xChartDoc, uno::UNO_QUERY_THROW );
+ if( apTemporaryChartLock.get() )
+ apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) );
+ xModif->setModified( sal_True );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ // After the update, chart keeps track of its own data source ranges,
+ // the listener doesn't need to listen anymore.
+ if(pChartListenerCollection)
+ pChartListenerCollection->ChangeListening( rChartName, new ScRangeList );
+}
+
+void ScDocument::RestoreChartListener( const String& rName )
+{
+ // Read the data ranges from the chart object, and start listening to those ranges again
+ // (called when a chart is saved, because then it might be swapped out and stop listening itself).
+
+ uno::Reference< embed::XEmbeddedObject > xObject = FindOleObjectByName( rName );
+ if ( xObject.is() )
+ {
+ uno::Reference< util::XCloseable > xComponent = xObject->getComponent();
+ uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY );
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xComponent, uno::UNO_QUERY );
+ if ( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider())
+ {
+ uno::Sequence<rtl::OUString> aRepresentations( xReceiver->getUsedRangeRepresentations() );
+ ScRangeListRef aRanges = new ScRangeList;
+ sal_Int32 nRangeCount = aRepresentations.getLength();
+ for ( sal_Int32 i=0; i<nRangeCount; i++ )
+ {
+ ScRange aRange;
+ ScAddress::Details aDetails(GetAddressConvention(), 0, 0);
+ if ( aRange.ParseAny( aRepresentations[i], this, aDetails ) & SCA_VALID )
+ aRanges->Append( aRange );
+ }
+
+ pChartListenerCollection->ChangeListening( rName, aRanges );
+ }
+ }
+}
+
+void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ if (!pDrawLayer)
+ return;
+
+ USHORT nChartCount = pChartListenerCollection->GetCount();
+ for ( USHORT nIndex = 0; nIndex < nChartCount; nIndex++ )
+ {
+ ScChartListener* pChartListener =
+ (ScChartListener*) (pChartListenerCollection->At(nIndex));
+ ScRangeListRef aRLR( pChartListener->GetRangeList() );
+ ScRangeListRef aNewRLR( new ScRangeList );
+ BOOL bChanged = FALSE;
+ BOOL bDataChanged = FALSE;
+ for ( ScRangePtr pR = aRLR->First(); pR; pR = aRLR->Next() )
+ {
+ SCCOL theCol1 = pR->aStart.Col();
+ SCROW theRow1 = pR->aStart.Row();
+ SCTAB theTab1 = pR->aStart.Tab();
+ SCCOL theCol2 = pR->aEnd.Col();
+ SCROW theRow2 = pR->aEnd.Row();
+ SCTAB theTab2 = pR->aEnd.Tab();
+ ScRefUpdateRes eRes = ScRefUpdate::Update(
+ this, eUpdateRefMode,
+ nCol1,nRow1,nTab1, nCol2,nRow2,nTab2,
+ nDx,nDy,nDz,
+ theCol1,theRow1,theTab1,
+ theCol2,theRow2,theTab2 );
+ if ( eRes != UR_NOTHING )
+ {
+ bChanged = TRUE;
+ aNewRLR->Append( ScRange(
+ theCol1, theRow1, theTab1,
+ theCol2, theRow2, theTab2 ));
+ if ( eUpdateRefMode == URM_INSDEL
+ && !bDataChanged
+ && (eRes == UR_INVALID ||
+ ((pR->aEnd.Col() - pR->aStart.Col()
+ != theCol2 - theCol1)
+ || (pR->aEnd.Row() - pR->aStart.Row()
+ != theRow2 - theRow1)
+ || (pR->aEnd.Tab() - pR->aStart.Tab()
+ != theTab2 - theTab1))) )
+ {
+ bDataChanged = TRUE;
+ }
+ }
+ else
+ aNewRLR->Append( *pR );
+ }
+ if ( bChanged )
+ {
+#if 0
+ if ( nDz != 0 )
+ { // #81844# sheet to be deleted or inserted or moved
+ // => no valid sheet names for references right now
+ pChartListener->ChangeListening( aNewRLR, bDataChanged );
+ pChartListener->ScheduleSeriesRanges();
+ }
+ else
+#endif
+ {
+// SetChartRangeList( pChartListener->GetString(), aNewRLR );
+// pChartListener->ChangeListening( aNewRLR, bDataChanged );
+
+ // Force the chart to be loaded now, so it registers itself for UNO events.
+ // UNO broadcasts are done after UpdateChartRef, so the chart will get this
+ // reference change.
+
+ uno::Reference< embed::XEmbeddedObject > xIPObj = FindOleObjectByName( pChartListener->GetString() );
+ svt::EmbeddedObjectRef::TryRunningState( xIPObj );
+
+ // After the change, chart keeps track of its own data source ranges,
+ // the listener doesn't need to listen anymore.
+
+ pChartListener->ChangeListening( new ScRangeList, bDataChanged );
+ }
+ }
+ }
+}
+
+
+void ScDocument::SetChartRangeList( const String& rChartName,
+ const ScRangeListRef& rNewRangeListRef )
+{
+ // called from ChartListener
+
+ if (!pDrawLayer)
+ return;
+
+ for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName )
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) );
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
+ if ( xChartDoc.is() && xReceiver.is() )
+ {
+ ScRangeListRef aNewRanges;
+ chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
+ bool bHasCategories = false;
+ bool bFirstCellAsLabel = false;
+ rtl::OUString aRangesStr;
+ lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
+
+ String sRangeStr;
+ rNewRangeListRef->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
+
+ lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
+
+ // don't modify pChartListenerCollection here, called from there
+ return;
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+
+
+BOOL ScDocument::HasData( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ if (pTab[nTab])
+ return pTab[nTab]->HasData( nCol, nRow );
+ else
+ return FALSE;
+}
+
+uno::Reference< embed::XEmbeddedObject >
+ ScDocument::FindOleObjectByName( const String& rName )
+{
+ if (!pDrawLayer)
+ return uno::Reference< embed::XEmbeddedObject >();
+
+ // die Seiten hier vom Draw-Layer nehmen,
+ // weil sie evtl. nicht mit den Tabellen uebereinstimmen
+ // (z.B. Redo von Tabelle loeschen, Draw-Redo passiert vor DeleteTab).
+
+ sal_uInt16 nCount = pDrawLayer->GetPageCount();
+ for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(nTab);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ SdrOle2Obj * pOleObject ( dynamic_cast< SdrOle2Obj * >( pObject ));
+ if( pOleObject &&
+ pOleObject->GetPersistName() == rName )
+ {
+ return pOleObject->GetObjRef();
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+
+ return uno::Reference< embed::XEmbeddedObject >();
+}
+
+BOOL lcl_StringInCollection( const ScStrCollection* pColl, const String& rStr )
+{
+ if ( !pColl )
+ return FALSE;
+
+ StrData aData( rStr );
+ USHORT nDummy;
+ return pColl->Search( &aData, nDummy );
+}
+
+void ScDocument::UpdateChartListenerCollection()
+{
+ bChartListenerCollectionNeedsUpdate = FALSE;
+ if (!pDrawLayer)
+ return;
+ else
+ {
+ ScRange aRange;
+ // Range fuer Suche unwichtig
+ ScChartListener aCLSearcher( EMPTY_STRING, this, aRange );
+ for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
+ {
+ if (pTab[nTab])
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ if (!pPage)
+ continue;
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ String aObjName = ((SdrOle2Obj*)pObject)->GetPersistName();
+ aCLSearcher.SetString( aObjName );
+ USHORT nIndex;
+ if ( pChartListenerCollection->Search( &aCLSearcher, nIndex ) )
+ {
+ ((ScChartListener*) (pChartListenerCollection->
+ At( nIndex )))->SetUsed( TRUE );
+ }
+ else if ( lcl_StringInCollection( pOtherObjects, aObjName ) )
+ {
+ // non-chart OLE object -> don't touch
+ }
+ else
+ {
+ bool bIsChart = false;
+
+ uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ DBG_ASSERT( xIPObj.is(), "No embedded object is given!");
+ uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
+ uno::Reference< embed::XComponentSupplier > xCompSupp( xIPObj, uno::UNO_QUERY );
+ if( xCompSupp.is())
+ xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
+
+ // if the object is a chart2::XDataReceiver, we must attach as XDataProvider
+ if( xReceiver.is() &&
+ !PastingDrawFromOtherDoc())
+ {
+ // NOTE: this currently does not work as we are
+ // unable to set the data. So a chart from the
+ // same document is treated like a chart with
+ // own data for the time being.
+#if 0
+ // data provider
+ uno::Reference< chart2::data::XDataProvider > xDataProvider = new
+ ScChart2DataProvider( this );
+ xReceiver->attachDataProvider( xDataProvider );
+ // number formats supplier
+ uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pShell->GetModel(), uno::UNO_QUERY );
+ xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
+ // data ?
+ // how to set?? Defined in XML-file, which is already loaded!!!
+ // => we have to do this stuff here, BEFORE the chart is actually loaded
+
+ bIsChart = true;
+#endif
+ }
+
+ if (!bIsChart)
+ {
+ // put into list of other ole objects, so the object doesn't have to
+ // be swapped in the next time UpdateChartListenerCollection is called
+ //! remove names when objects are no longer there?
+ // (object names aren't used again before reloading the document)
+
+ if (!pOtherObjects)
+ pOtherObjects = new ScStrCollection;
+ pOtherObjects->Insert( new StrData( aObjName ) );
+ }
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ // alle nicht auf SetUsed gesetzten loeschen
+ pChartListenerCollection->FreeUnused();
+ }
+}
+
+void ScDocument::AddOLEObjectToCollection(const String& rName)
+{
+ if (!pOtherObjects)
+ pOtherObjects = new ScStrCollection;
+ pOtherObjects->Insert( new StrData( rName ) );
+}
+
+
+
diff --git a/sc/source/core/data/documen6.cxx b/sc/source/core/data/documen6.cxx
new file mode 100644
index 000000000000..8706c49320d1
--- /dev/null
+++ b/sc/source/core/data/documen6.cxx
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/scripttypeitem.hxx>
+
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include "document.hxx"
+#include "cell.hxx"
+#include "cellform.hxx"
+#include "patattr.hxx"
+#include "scrdata.hxx"
+#include "poolhelp.hxx"
+
+using namespace com::sun::star;
+
+#define SC_BREAKITER_SERVICE "com.sun.star.i18n.BreakIterator"
+
+//
+// this file is compiled with exceptions enabled
+// put functions here that need exceptions!
+//
+
+// -----------------------------------------------------------------------
+
+const uno::Reference< i18n::XBreakIterator >& ScDocument::GetBreakIterator()
+{
+ if ( !pScriptTypeData )
+ pScriptTypeData = new ScScriptTypeData;
+ if ( !pScriptTypeData->xBreakIter.is() )
+ {
+ uno::Reference< uno::XInterface > xInterface = xServiceManager->createInstance(
+ ::rtl::OUString::createFromAscii( SC_BREAKITER_SERVICE ) );
+ pScriptTypeData->xBreakIter = uno::Reference< i18n::XBreakIterator >( xInterface, uno::UNO_QUERY );
+ DBG_ASSERT( pScriptTypeData->xBreakIter.is(), "can't get BreakIterator" );
+ }
+ return pScriptTypeData->xBreakIter;
+}
+
+BOOL ScDocument::HasStringWeakCharacters( const String& rString )
+{
+ if (rString.Len())
+ {
+ uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator();
+ if ( xBreakIter.is() )
+ {
+ rtl::OUString aText = rString;
+ sal_Int32 nLen = aText.getLength();
+
+ sal_Int32 nPos = 0;
+ do
+ {
+ sal_Int16 nType = xBreakIter->getScriptType( aText, nPos );
+ if ( nType == i18n::ScriptType::WEAK )
+ return TRUE; // found
+
+ nPos = xBreakIter->endOfScript( aText, nPos, nType );
+ }
+ while ( nPos >= 0 && nPos < nLen );
+ }
+ }
+
+ return FALSE; // none found
+}
+
+BYTE ScDocument::GetStringScriptType( const String& rString )
+{
+
+ BYTE nRet = 0;
+ if (rString.Len())
+ {
+ uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator();
+ if ( xBreakIter.is() )
+ {
+ rtl::OUString aText = rString;
+ sal_Int32 nLen = aText.getLength();
+
+ sal_Int32 nPos = 0;
+ do
+ {
+ sal_Int16 nType = xBreakIter->getScriptType( aText, nPos );
+ switch ( nType )
+ {
+ case i18n::ScriptType::LATIN:
+ nRet |= SCRIPTTYPE_LATIN;
+ break;
+ case i18n::ScriptType::ASIAN:
+ nRet |= SCRIPTTYPE_ASIAN;
+ break;
+ case i18n::ScriptType::COMPLEX:
+ nRet |= SCRIPTTYPE_COMPLEX;
+ break;
+ // WEAK is ignored
+ }
+ nPos = xBreakIter->endOfScript( aText, nPos, nType );
+ }
+ while ( nPos >= 0 && nPos < nLen );
+ }
+ }
+ return nRet;
+}
+
+BYTE ScDocument::GetCellScriptType( ScBaseCell* pCell, ULONG nNumberFormat )
+{
+ if ( !pCell )
+ return 0; // empty
+
+ BYTE nStored = pCell->GetScriptType();
+ if ( nStored != SC_SCRIPTTYPE_UNKNOWN ) // stored value valid?
+ return nStored; // use stored value
+
+ String aStr;
+ Color* pColor;
+ ScCellFormat::GetString( pCell, nNumberFormat, aStr, &pColor, *xPoolHelper->GetFormTable() );
+
+ BYTE nRet = GetStringScriptType( aStr );
+
+ pCell->SetScriptType( nRet ); // store for later calls
+
+ return nRet;
+}
+
+BYTE ScDocument::GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell )
+{
+ // if cell is not passed, take from document
+
+ if (!pCell)
+ {
+ pCell = GetCell( ScAddress( nCol, nRow, nTab ) );
+ if ( !pCell )
+ return 0; // empty
+ }
+
+ // if script type is set, don't have to get number formats
+
+ BYTE nStored = pCell->GetScriptType();
+ if ( nStored != SC_SCRIPTTYPE_UNKNOWN ) // stored value valid?
+ return nStored; // use stored value
+
+ // include number formats from conditional formatting
+
+ const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
+ if (!pPattern) return 0;
+ const SfxItemSet* pCondSet = NULL;
+ if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
+ pCondSet = GetCondResult( nCol, nRow, nTab );
+
+ ULONG nFormat = pPattern->GetNumberFormat( xPoolHelper->GetFormTable(), pCondSet );
+ return GetCellScriptType( pCell, nFormat );
+}
+
+
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
new file mode 100644
index 000000000000..d77dc1041d9c
--- /dev/null
+++ b/sc/source/core/data/documen7.cxx
@@ -0,0 +1,534 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+
+#if defined( WNT ) && defined( erBEEP )
+#include <svwin.h>
+#define erBEEPER() Beep( 666, 66 )
+#else
+#define erBEEPER()
+#endif
+
+#include "document.hxx"
+#include "brdcst.hxx"
+#include "bcaslot.hxx"
+#include "cell.hxx"
+#include "formula/errorcodes.hxx" // errCircularReference
+#include "scerrors.hxx"
+#include "docoptio.hxx"
+#include "refupdat.hxx"
+#include "table.hxx"
+#include "progress.hxx"
+#include "scmod.hxx" // SC_MOD
+#include "inputopt.hxx" // GetExpandRefs
+#include "conditio.hxx"
+#include "sheetevents.hxx"
+#include <tools/shl.hxx>
+
+
+#include "globstr.hrc"
+
+extern const ScFormulaCell* pLastFormulaTreeTop; // cellform.cxx Err527 WorkAround
+
+// STATIC DATA -----------------------------------------------------------
+
+#ifdef erDEBUG
+ULONG erCountBCAInserts = 0;
+ULONG erCountBCAFinds = 0;
+#endif
+
+// -----------------------------------------------------------------------
+
+void ScDocument::StartListeningArea( const ScRange& rRange,
+ SvtListener* pListener
+ )
+{
+ if ( pBASM )
+ pBASM->StartListeningArea( rRange, pListener );
+}
+
+
+void ScDocument::EndListeningArea( const ScRange& rRange,
+ SvtListener* pListener
+ )
+{
+ if ( pBASM )
+ pBASM->EndListeningArea( rRange, pListener );
+}
+
+
+void ScDocument::Broadcast( ULONG nHint, const ScAddress& rAddr,
+ ScBaseCell* pCell
+ )
+{
+ if ( !pBASM )
+ return ; // Clipboard or Undo
+ ScHint aHint( nHint, rAddr, pCell );
+ Broadcast( aHint );
+}
+
+
+void ScDocument::Broadcast( const ScHint& rHint )
+{
+ if ( !pBASM )
+ return ; // Clipboard or Undo
+ if ( !nHardRecalcState )
+ {
+ ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
+ BOOL bIsBroadcasted = FALSE;
+ ScBaseCell* pCell = rHint.GetCell();
+ if ( pCell )
+ {
+ SvtBroadcaster* pBC = pCell->GetBroadcaster();
+ if ( pBC )
+ {
+ pBC->Broadcast( rHint );
+ bIsBroadcasted = TRUE;
+ }
+ }
+ if ( pBASM->AreaBroadcast( rHint ) || bIsBroadcasted )
+ TrackFormulas( rHint.GetId() );
+ }
+
+ // Repaint fuer bedingte Formate mit relativen Referenzen:
+ if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
+ pCondFormList->SourceChanged( rHint.GetAddress() );
+
+ if ( rHint.GetAddress() != BCA_BRDCST_ALWAYS )
+ {
+ SCTAB nTab = rHint.GetAddress().Tab();
+ if (pTab[nTab] && pTab[nTab]->IsStreamValid())
+ pTab[nTab]->SetStreamValid(FALSE);
+ }
+}
+
+
+void ScDocument::AreaBroadcast( const ScHint& rHint )
+{
+ if ( !pBASM )
+ return ; // Clipboard or Undo
+ if ( !nHardRecalcState )
+ {
+ ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
+ if ( pBASM->AreaBroadcast( rHint ) )
+ TrackFormulas( rHint.GetId() );
+ }
+
+ // Repaint fuer bedingte Formate mit relativen Referenzen:
+ if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
+ pCondFormList->SourceChanged( rHint.GetAddress() );
+}
+
+
+void ScDocument::AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint )
+{
+ if ( !pBASM )
+ return ; // Clipboard or Undo
+ if ( !nHardRecalcState )
+ {
+ ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
+ if ( pBASM->AreaBroadcastInRange( rRange, rHint ) )
+ TrackFormulas( rHint.GetId() );
+ }
+
+ // Repaint for conditional formats containing relative references.
+ //! This is _THE_ bottle neck!
+ if ( pCondFormList )
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ ScAddress aAddress( rRange.aStart );
+ for ( nTab = nTab1; nTab <= nTab2; ++nTab )
+ {
+ aAddress.SetTab( nTab );
+ for ( nCol = nCol1; nCol <= nCol2; ++nCol )
+ {
+ aAddress.SetCol( nCol );
+ for ( nRow = nRow1; nRow <= nRow2; ++nRow )
+ {
+ aAddress.SetRow( nRow );
+ pCondFormList->SourceChanged( aAddress );
+ }
+ }
+ }
+ }
+}
+
+
+void ScDocument::DelBroadcastAreasInRange( const ScRange& rRange )
+{
+ if ( pBASM )
+ pBASM->DelBroadcastAreasInRange( rRange );
+}
+
+void ScDocument::StartListeningCell( const ScAddress& rAddress,
+ SvtListener* pListener )
+{
+ DBG_ASSERT(pListener, "StartListeningCell: pListener Null");
+ SCTAB nTab = rAddress.Tab();
+ if (pTab[nTab])
+ pTab[nTab]->StartListening( rAddress, pListener );
+}
+
+void ScDocument::EndListeningCell( const ScAddress& rAddress,
+ SvtListener* pListener )
+{
+ DBG_ASSERT(pListener, "EndListeningCell: pListener Null");
+ SCTAB nTab = rAddress.Tab();
+ if (pTab[nTab])
+ pTab[nTab]->EndListening( rAddress, pListener );
+}
+
+
+void ScDocument::PutInFormulaTree( ScFormulaCell* pCell )
+{
+ DBG_ASSERT( pCell, "PutInFormulaTree: pCell Null" );
+ RemoveFromFormulaTree( pCell );
+ // anhaengen
+ if ( pEOFormulaTree )
+ pEOFormulaTree->SetNext( pCell );
+ else
+ pFormulaTree = pCell; // kein Ende, kein Anfang..
+ pCell->SetPrevious( pEOFormulaTree );
+ pCell->SetNext( 0 );
+ pEOFormulaTree = pCell;
+ nFormulaCodeInTree += pCell->GetCode()->GetCodeLen();
+}
+
+
+void ScDocument::RemoveFromFormulaTree( ScFormulaCell* pCell )
+{
+ DBG_ASSERT( pCell, "RemoveFromFormulaTree: pCell Null" );
+ ScFormulaCell* pPrev = pCell->GetPrevious();
+ // wenn die Zelle die erste oder sonstwo ist
+ if ( pPrev || pFormulaTree == pCell )
+ {
+ ScFormulaCell* pNext = pCell->GetNext();
+ if ( pPrev )
+ pPrev->SetNext( pNext ); // gibt Vorlaeufer
+ else
+ pFormulaTree = pNext; // ist erste Zelle
+ if ( pNext )
+ pNext->SetPrevious( pPrev ); // gibt Nachfolger
+ else
+ pEOFormulaTree = pPrev; // ist letzte Zelle
+ pCell->SetPrevious( 0 );
+ pCell->SetNext( 0 );
+ USHORT nRPN = pCell->GetCode()->GetCodeLen();
+ if ( nFormulaCodeInTree >= nRPN )
+ nFormulaCodeInTree -= nRPN;
+ else
+ {
+ DBG_ERRORFILE( "RemoveFromFormulaTree: nFormulaCodeInTree < nRPN" );
+ nFormulaCodeInTree = 0;
+ }
+ }
+ else if ( !pFormulaTree && nFormulaCodeInTree )
+ {
+ DBG_ERRORFILE( "!pFormulaTree && nFormulaCodeInTree != 0" );
+ nFormulaCodeInTree = 0;
+ }
+}
+
+
+BOOL ScDocument::IsInFormulaTree( ScFormulaCell* pCell ) const
+{
+ return pCell->GetPrevious() || pFormulaTree == pCell;
+}
+
+
+void ScDocument::CalcFormulaTree( BOOL bOnlyForced, BOOL bNoProgress )
+{
+ DBG_ASSERT( !IsCalculatingFormulaTree(), "CalcFormulaTree recursion" );
+ // never ever recurse into this, might end up lost in infinity
+ if ( IsCalculatingFormulaTree() )
+ return ;
+ bCalculatingFormulaTree = TRUE;
+
+ SetForcedFormulaPending( FALSE );
+ BOOL bOldIdleDisabled = IsIdleDisabled();
+ DisableIdle( TRUE );
+ BOOL bOldAutoCalc = GetAutoCalc();
+ //! _nicht_ SetAutoCalc( TRUE ) weil das evtl. CalcFormulaTree( TRUE )
+ //! aufruft, wenn vorher disabled war und bHasForcedFormulas gesetzt ist
+ bAutoCalc = TRUE;
+ if ( nHardRecalcState )
+ CalcAll();
+ else
+ {
+ ScFormulaCell* pCell = pFormulaTree;
+ while ( pCell )
+ {
+ if ( pCell->GetDirty() )
+ pCell = pCell->GetNext(); // alles klar
+ else
+ {
+ if ( pCell->GetCode()->IsRecalcModeAlways() )
+ {
+ // pCell wird im SetDirty neu angehaengt!
+ ScFormulaCell* pNext = pCell->GetNext();
+ pCell->SetDirty();
+ // falls pNext==0 und neue abhaengige hinten angehaengt
+ // wurden, so macht das nichts, da die alle bDirty sind
+ pCell = pNext;
+ }
+ else
+ { // andere simpel berechnen
+ pCell->SetDirtyVar();
+ pCell = pCell->GetNext();
+ }
+ }
+ }
+ BOOL bProgress = !bOnlyForced && nFormulaCodeInTree && !bNoProgress;
+ if ( bProgress )
+ ScProgress::CreateInterpretProgress( this, TRUE );
+
+ pCell = pFormulaTree;
+ ScFormulaCell* pLastNoGood = 0;
+ while ( pCell )
+ {
+ // Interpret setzt bDirty zurueck und callt Remove, auch der referierten!
+ // bei RECALCMODE_ALWAYS bleibt die Zelle
+ if ( bOnlyForced )
+ {
+ if ( pCell->GetCode()->IsRecalcModeForced() )
+ pCell->Interpret();
+ }
+ else
+ {
+ pCell->Interpret();
+ }
+ if ( pCell->GetPrevious() || pCell == pFormulaTree )
+ { // (IsInFormulaTree(pCell)) kein Remove gewesen => next
+ pLastNoGood = pCell;
+ pCell = pCell->GetNext();
+ }
+ else
+ {
+ if ( pFormulaTree )
+ {
+ if ( pFormulaTree->GetDirty() && !bOnlyForced )
+ {
+ pCell = pFormulaTree;
+ pLastNoGood = 0;
+ }
+ else
+ {
+ // IsInFormulaTree(pLastNoGood)
+ if ( pLastNoGood && (pLastNoGood->GetPrevious() ||
+ pLastNoGood == pFormulaTree) )
+ pCell = pLastNoGood->GetNext();
+ else
+ {
+ pCell = pFormulaTree;
+ while ( pCell && !pCell->GetDirty() )
+ pCell = pCell->GetNext();
+ if ( pCell )
+ pLastNoGood = pCell->GetPrevious();
+ }
+ }
+ }
+ else
+ pCell = 0;
+ }
+ if ( ScProgress::IsUserBreak() )
+ pCell = 0;
+ }
+ if ( bProgress )
+ ScProgress::DeleteInterpretProgress();
+ }
+ bAutoCalc = bOldAutoCalc;
+ DisableIdle( bOldIdleDisabled );
+ bCalculatingFormulaTree = FALSE;
+}
+
+
+void ScDocument::ClearFormulaTree()
+{
+ ScFormulaCell* pCell;
+ ScFormulaCell* pTree = pFormulaTree;
+ while ( pTree )
+ {
+ pCell = pTree;
+ pTree = pCell->GetNext();
+ if ( !pCell->GetCode()->IsRecalcModeAlways() )
+ RemoveFromFormulaTree( pCell );
+ }
+}
+
+
+void ScDocument::AppendToFormulaTrack( ScFormulaCell* pCell )
+{
+ DBG_ASSERT( pCell, "AppendToFormulaTrack: pCell Null" );
+ // Zelle kann nicht in beiden Listen gleichzeitig sein
+ RemoveFromFormulaTrack( pCell );
+ RemoveFromFormulaTree( pCell );
+ if ( pEOFormulaTrack )
+ pEOFormulaTrack->SetNextTrack( pCell );
+ else
+ pFormulaTrack = pCell; // kein Ende, kein Anfang..
+ pCell->SetPreviousTrack( pEOFormulaTrack );
+ pCell->SetNextTrack( 0 );
+ pEOFormulaTrack = pCell;
+ ++nFormulaTrackCount;
+}
+
+
+void ScDocument::RemoveFromFormulaTrack( ScFormulaCell* pCell )
+{
+ DBG_ASSERT( pCell, "RemoveFromFormulaTrack: pCell Null" );
+ ScFormulaCell* pPrev = pCell->GetPreviousTrack();
+ // wenn die Zelle die erste oder sonstwo ist
+ if ( pPrev || pFormulaTrack == pCell )
+ {
+ ScFormulaCell* pNext = pCell->GetNextTrack();
+ if ( pPrev )
+ pPrev->SetNextTrack( pNext ); // gibt Vorlaeufer
+ else
+ pFormulaTrack = pNext; // ist erste Zelle
+ if ( pNext )
+ pNext->SetPreviousTrack( pPrev ); // gibt Nachfolger
+ else
+ pEOFormulaTrack = pPrev; // ist letzte Zelle
+ pCell->SetPreviousTrack( 0 );
+ pCell->SetNextTrack( 0 );
+ --nFormulaTrackCount;
+ }
+}
+
+
+BOOL ScDocument::IsInFormulaTrack( ScFormulaCell* pCell ) const
+{
+ return pCell->GetPreviousTrack() || pFormulaTrack == pCell;
+}
+
+
+/*
+ Der erste wird gebroadcastet,
+ die dadurch entstehenden werden durch das Notify an den Track gehaengt.
+ Der nachfolgende broadcastet wieder usw.
+ View stoesst Interpret an.
+ */
+void ScDocument::TrackFormulas( ULONG nHintId )
+{
+
+ if ( pFormulaTrack )
+ {
+ erBEEPER();
+ // outside the loop, check if any sheet has a "calculate" event script
+ bool bCalcEvent = HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true );
+ SvtBroadcaster* pBC;
+ ScFormulaCell* pTrack;
+ ScFormulaCell* pNext;
+ pTrack = pFormulaTrack;
+ do
+ {
+ ScHint aHint( nHintId, pTrack->aPos, pTrack );
+ if ( ( pBC = pTrack->GetBroadcaster() ) != NULL )
+ pBC->Broadcast( aHint );
+ pBASM->AreaBroadcast( aHint );
+ // Repaint fuer bedingte Formate mit relativen Referenzen:
+ if ( pCondFormList )
+ pCondFormList->SourceChanged( pTrack->aPos );
+ // for "calculate" event, keep track of which sheets are affected by tracked formulas
+ if ( bCalcEvent )
+ SetCalcNotification( pTrack->aPos.Tab() );
+ pTrack = pTrack->GetNextTrack();
+ } while ( pTrack );
+ pTrack = pFormulaTrack;
+ BOOL bHaveForced = FALSE;
+ do
+ {
+ pNext = pTrack->GetNextTrack();
+ RemoveFromFormulaTrack( pTrack );
+ PutInFormulaTree( pTrack );
+ if ( pTrack->GetCode()->IsRecalcModeForced() )
+ bHaveForced = TRUE;
+ pTrack = pNext;
+ } while ( pTrack );
+ if ( bHaveForced )
+ {
+ SetForcedFormulas( TRUE );
+ if ( bAutoCalc && !IsAutoCalcShellDisabled() && !IsInInterpreter()
+ && !IsCalculatingFormulaTree() )
+ CalcFormulaTree( TRUE );
+ else
+ SetForcedFormulaPending( TRUE );
+ }
+ }
+ DBG_ASSERT( nFormulaTrackCount==0, "TrackFormulas: nFormulaTrackCount!=0" );
+}
+
+
+void ScDocument::StartAllListeners()
+{
+ for ( SCTAB i = 0; i <= MAXTAB; ++i )
+ if ( pTab[i] )
+ pTab[i]->StartAllListeners();
+}
+
+void ScDocument::UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz
+ )
+{
+ BOOL bExpandRefsOld = IsExpandRefs();
+ if ( eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0 || nDz > 0) )
+ SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
+ if ( pBASM )
+ pBASM->UpdateBroadcastAreas( eUpdateRefMode, rRange, nDx, nDy, nDz );
+ SetExpandRefs( bExpandRefsOld );
+}
+
+void ScDocument::SetAutoCalc( BOOL bNewAutoCalc )
+{
+ BOOL bOld = bAutoCalc;
+ bAutoCalc = bNewAutoCalc;
+ if ( !bOld && bNewAutoCalc && bHasForcedFormulas )
+ {
+ if ( IsAutoCalcShellDisabled() )
+ SetForcedFormulaPending( TRUE );
+ else if ( !IsInInterpreter() )
+ CalcFormulaTree( TRUE );
+ }
+}
+
+
+
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
new file mode 100644
index 000000000000..e3c9d251fab7
--- /dev/null
+++ b/sc/source/core/data/documen8.cxx
@@ -0,0 +1,1625 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <tools/string.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/langitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svl/flagitem.hxx>
+#include <svl/intitem.hxx>
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <unotools/misccfg.hxx>
+#include <sfx2/app.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <unotools/securityoptions.hxx>
+
+#include <vcl/virdev.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "inputopt.hxx"
+#include "global.hxx"
+#include "table.hxx"
+#include "column.hxx"
+#include "cell.hxx"
+#include "poolhelp.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "docoptio.hxx"
+#include "viewopti.hxx"
+#include "scextopt.hxx"
+#include "rechead.hxx"
+#include "ddelink.hxx"
+#include "scmatrix.hxx"
+#include "arealink.hxx"
+#include "dociter.hxx"
+#include "patattr.hxx"
+#include "hints.hxx"
+#include "editutil.hxx"
+#include "progress.hxx"
+#include "document.hxx"
+#include "chartlis.hxx"
+#include "chartlock.hxx"
+#include "refupdat.hxx"
+#include "validat.hxx" // fuer HasMacroCalls
+#include "markdata.hxx"
+#include "scmod.hxx"
+#include "printopt.hxx"
+#include "externalrefmgr.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "charthelper.hxx"
+#include "dpobject.hxx"
+
+#define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
+
+// states for online spelling in the visible range (0 is set initially)
+#define VSPL_START 0
+#define VSPL_DONE 1
+
+
+// STATIC DATA -----------------------------------------------------------
+
+//------------------------------------------------------------------------
+
+void ScDocument::ImplCreateOptions()
+{
+ pDocOptions = new ScDocOptions();
+ pViewOptions = new ScViewOptions();
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::ImplDeleteOptions()
+{
+ delete pDocOptions;
+ delete pViewOptions;
+ delete pExtDocOptions;
+}
+
+//------------------------------------------------------------------------
+
+SfxPrinter* ScDocument::GetPrinter(BOOL bCreateIfNotExist)
+{
+ if ( !pPrinter && bCreateIfNotExist )
+ {
+ SfxItemSet* pSet =
+ new SfxItemSet( *xPoolHelper->GetDocPool(),
+ SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
+ SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
+ SID_PRINT_SELECTEDSHEET, SID_PRINT_SELECTEDSHEET,
+ SID_SCPRINTOPTIONS, SID_SCPRINTOPTIONS,
+ NULL );
+
+ ::utl::MiscCfg aMisc;
+ USHORT nFlags = 0;
+ if ( aMisc.IsPaperOrientationWarning() )
+ nFlags |= SFX_PRINTER_CHG_ORIENTATION;
+ if ( aMisc.IsPaperSizeWarning() )
+ nFlags |= SFX_PRINTER_CHG_SIZE;
+ pSet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
+ pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
+
+ pPrinter = new SfxPrinter( pSet );
+ pPrinter->SetMapMode( MAP_100TH_MM );
+ UpdateDrawPrinter();
+ pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ }
+
+ return pPrinter;
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::SetPrinter( SfxPrinter* pNewPrinter )
+{
+ if ( pNewPrinter == pPrinter )
+ {
+ // #i6706# SetPrinter is called with the same printer again if
+ // the JobSetup has changed. In that case just call UpdateDrawPrinter
+ // (SetRefDevice for drawing layer) because of changed text sizes.
+ UpdateDrawPrinter();
+ }
+ else
+ {
+ SfxPrinter* pOld = pPrinter;
+ pPrinter = pNewPrinter;
+ UpdateDrawPrinter();
+ pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ delete pOld;
+ }
+ InvalidateTextWidth(NULL, NULL, FALSE); // in both cases
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::SetPrintOptions()
+{
+ if ( !pPrinter ) GetPrinter(); // setzt pPrinter
+ DBG_ASSERT( pPrinter, "Error in printer creation :-/" );
+
+ if ( pPrinter )
+ {
+ ::utl::MiscCfg aMisc;
+ SfxItemSet aOptSet( pPrinter->GetOptions() );
+
+ USHORT nFlags = 0;
+ if ( aMisc.IsPaperOrientationWarning() )
+ nFlags |= SFX_PRINTER_CHG_ORIENTATION;
+ if ( aMisc.IsPaperSizeWarning() )
+ nFlags |= SFX_PRINTER_CHG_SIZE;
+ aOptSet.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
+ aOptSet.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
+
+ pPrinter->SetOptions( aOptSet );
+ }
+}
+
+//------------------------------------------------------------------------
+
+VirtualDevice* ScDocument::GetVirtualDevice_100th_mm()
+{
+ if (!pVirtualDevice_100th_mm)
+ {
+// pVirtualDevice_100th_mm = new VirtualDevice;
+// pVirtualDevice_100th_mm->SetMapMode( MAP_100TH_MM );
+
+ pVirtualDevice_100th_mm = new VirtualDevice( 1 );
+ pVirtualDevice_100th_mm->SetReferenceDevice(VirtualDevice::REFDEV_MODE_MSO1);
+ MapMode aMapMode( pVirtualDevice_100th_mm->GetMapMode() );
+ aMapMode.SetMapUnit( MAP_100TH_MM );
+ pVirtualDevice_100th_mm->SetMapMode( aMapMode );
+ }
+ return pVirtualDevice_100th_mm;
+}
+
+OutputDevice* ScDocument::GetRefDevice()
+{
+ // Create printer like ref device, see Writer...
+ OutputDevice* pRefDevice = NULL;
+ if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
+ pRefDevice = GetPrinter();
+ else
+ pRefDevice = GetVirtualDevice_100th_mm();
+ return pRefDevice;
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::ModifyStyleSheet( SfxStyleSheetBase& rStyleSheet,
+ const SfxItemSet& rChanges )
+{
+ SfxItemSet& rSet = rStyleSheet.GetItemSet();
+
+ switch ( rStyleSheet.GetFamily() )
+ {
+ case SFX_STYLE_FAMILY_PAGE:
+ {
+ const USHORT nOldScale = GET_SCALEVALUE(rSet,ATTR_PAGE_SCALE);
+ const USHORT nOldScaleToPages = GET_SCALEVALUE(rSet,ATTR_PAGE_SCALETOPAGES);
+ rSet.Put( rChanges );
+ const USHORT nNewScale = GET_SCALEVALUE(rSet,ATTR_PAGE_SCALE);
+ const USHORT nNewScaleToPages = GET_SCALEVALUE(rSet,ATTR_PAGE_SCALETOPAGES);
+
+ if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) )
+ InvalidateTextWidth( rStyleSheet.GetName() );
+
+ if( SvtLanguageOptions().IsCTLFontEnabled() )
+ {
+ const SfxPoolItem *pItem = NULL;
+ if( rChanges.GetItemState(ATTR_WRITINGDIR, TRUE, &pItem ) == SFX_ITEM_SET )
+ ScChartHelper::DoUpdateAllCharts( this );
+ }
+ }
+ break;
+
+ case SFX_STYLE_FAMILY_PARA:
+ {
+ BOOL bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
+ rSet, rChanges ) )
+ InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
+
+ for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab)
+ if (pTab[nTab] && pTab[nTab]->IsStreamValid())
+ pTab[nTab]->SetStreamValid( FALSE );
+
+ ULONG nOldFormat =
+ ((const SfxUInt32Item*)&rSet.Get(
+ ATTR_VALUE_FORMAT ))->GetValue();
+ ULONG nNewFormat =
+ ((const SfxUInt32Item*)&rChanges.Get(
+ ATTR_VALUE_FORMAT ))->GetValue();
+ LanguageType eNewLang, eOldLang;
+ eNewLang = eOldLang = LANGUAGE_DONTKNOW;
+ if ( nNewFormat != nOldFormat )
+ {
+ SvNumberFormatter* pFormatter = GetFormatTable();
+ eOldLang = pFormatter->GetEntry( nOldFormat )->GetLanguage();
+ eNewLang = pFormatter->GetEntry( nNewFormat )->GetLanguage();
+ }
+
+ // Bedeutung der Items in rChanges:
+ // Item gesetzt - Aenderung uebernehmen
+ // Dontcare - Default setzen
+ // Default - keine Aenderung
+ // ("keine Aenderung" geht nicht mit PutExtended, darum Schleife)
+ for (USHORT nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
+ {
+ const SfxPoolItem* pItem;
+ SfxItemState eState = rChanges.GetItemState( nWhich, FALSE, &pItem );
+ if ( eState == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ else if ( eState == SFX_ITEM_DONTCARE )
+ rSet.ClearItem( nWhich );
+ // bei Default nichts
+ }
+
+ if ( eNewLang != eOldLang )
+ rSet.Put(
+ SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::CopyStdStylesFrom( ScDocument* pSrcDoc )
+{
+ // #b5017505# number format exchange list has to be handled here, too
+ NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
+ xPoolHelper->GetStylePool()->CopyStdStylesFrom( pSrcDoc->xPoolHelper->GetStylePool() );
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::InvalidateTextWidth( const String& rStyleName )
+{
+ const SCTAB nCount = GetTableCount();
+ for ( SCTAB i=0; i<nCount && pTab[i]; i++ )
+ if ( pTab[i]->GetPageStyle() == rStyleName )
+ InvalidateTextWidth( i );
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::InvalidateTextWidth( SCTAB nTab )
+{
+ ScAddress aAdrFrom( 0, 0, nTab );
+ ScAddress aAdrTo ( MAXCOL, MAXROW, nTab );
+ InvalidateTextWidth( &aAdrFrom, &aAdrTo, FALSE );
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocument::IsPageStyleInUse( const String& rStrPageStyle, SCTAB* pInTab )
+{
+ BOOL bInUse = FALSE;
+ const SCTAB nCount = GetTableCount();
+ SCTAB i;
+
+ for ( i = 0; !bInUse && i < nCount && pTab[i]; i++ )
+ bInUse = ( pTab[i]->GetPageStyle() == rStrPageStyle );
+
+ if ( pInTab )
+ *pInTab = i-1;
+
+ return bInUse;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocument::RemovePageStyleInUse( const String& rStyle )
+{
+ BOOL bWasInUse = FALSE;
+ const SCTAB nCount = GetTableCount();
+
+ for ( SCTAB i=0; i<nCount && pTab[i]; i++ )
+ if ( pTab[i]->GetPageStyle() == rStyle )
+ {
+ bWasInUse = TRUE;
+ pTab[i]->SetPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
+ }
+
+ return bWasInUse;
+}
+
+BOOL ScDocument::RenamePageStyleInUse( const String& rOld, const String& rNew )
+{
+ BOOL bWasInUse = FALSE;
+ const SCTAB nCount = GetTableCount();
+
+ for ( SCTAB i=0; i<nCount && pTab[i]; i++ )
+ if ( pTab[i]->GetPageStyle() == rOld )
+ {
+ bWasInUse = TRUE;
+ pTab[i]->SetPageStyle( rNew );
+ }
+
+ return bWasInUse;
+}
+
+//------------------------------------------------------------------------
+
+BYTE ScDocument::GetEditTextDirection(SCTAB nTab) const
+{
+ EEHorizontalTextDirection eRet = EE_HTEXTDIR_DEFAULT;
+
+ String aStyleName = GetPageStyle( nTab );
+ SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
+ if ( pStyle )
+ {
+ SfxItemSet& rStyleSet = pStyle->GetItemSet();
+ SvxFrameDirection eDirection = (SvxFrameDirection)
+ ((const SvxFrameDirectionItem&)rStyleSet.Get( ATTR_WRITINGDIR )).GetValue();
+
+ if ( eDirection == FRMDIR_HORI_LEFT_TOP )
+ eRet = EE_HTEXTDIR_L2R;
+ else if ( eDirection == FRMDIR_HORI_RIGHT_TOP )
+ eRet = EE_HTEXTDIR_R2L;
+ // else (invalid for EditEngine): keep "default"
+ }
+
+ return sal::static_int_cast<BYTE>(eRet);
+}
+
+//------------------------------------------------------------------------
+
+void ScDocument::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
+ BOOL bNumFormatChanged )
+{
+ BOOL bBroadcast = (bNumFormatChanged && GetDocOptions().IsCalcAsShown() && !IsImportingXML() && !IsClipboard());
+ if ( pAdrFrom && !pAdrTo )
+ {
+ const SCTAB nTab = pAdrFrom->Tab();
+
+ if ( pTab[nTab] )
+ pTab[nTab]->InvalidateTextWidth( pAdrFrom, NULL, bNumFormatChanged, bBroadcast );
+ }
+ else
+ {
+ const SCTAB nTabStart = pAdrFrom ? pAdrFrom->Tab() : 0;
+ const SCTAB nTabEnd = pAdrTo ? pAdrTo->Tab() : MAXTAB;
+
+ for ( SCTAB nTab=nTabStart; nTab<=nTabEnd; nTab++ )
+ if ( pTab[nTab] )
+ pTab[nTab]->InvalidateTextWidth( pAdrFrom, pAdrTo, bNumFormatChanged, bBroadcast );
+ }
+}
+
+//------------------------------------------------------------------------
+
+#define CALCMAX 1000 // Berechnungen
+#define ABORT_EVENTS (INPUT_ANY & ~INPUT_TIMER & ~INPUT_OTHER)
+
+BOOL ScDocument::IdleCalcTextWidth() // TRUE = demnaechst wieder versuchen
+{
+ // #i75610# if a printer hasn't been set or created yet, don't create one for this
+ if ( bIdleDisabled || IsInLinkUpdate() || GetPrinter(FALSE) == NULL )
+ return FALSE;
+ bIdleDisabled = TRUE;
+
+// ULONG nMs = 0;
+// USHORT nIter = 0;
+
+ const ULONG nStart = Time::GetSystemTicks();
+ double nPPTX = 0.0;
+ double nPPTY = 0.0;
+ OutputDevice* pDev = NULL;
+ MapMode aOldMap;
+ ScStyleSheet* pStyle = NULL;
+ ScColumnIterator* pColIter = NULL;
+ ScTable* pTable = NULL;
+ ScColumn* pColumn = NULL;
+ ScBaseCell* pCell = NULL;
+ SCTAB nTab = aCurTextWidthCalcPos.Tab();
+ SCROW nRow = aCurTextWidthCalcPos.Row();
+ SCsCOL nCol = aCurTextWidthCalcPos.Col();
+ USHORT nRestart = 0;
+ USHORT nZoom = 0;
+ BOOL bNeedMore= FALSE;
+
+ if ( !ValidRow(nRow) )
+ nRow = 0, nCol--;
+ if ( nCol < 0 )
+ nCol = MAXCOL, nTab++;
+ if ( !ValidTab(nTab) || !pTab[nTab] )
+ nTab = 0;
+
+// DBG_ERROR( String("Start = ") + String(nTab) + String(',') + String(nCol) + String(',') + String(nRow) );
+
+ // SearchMask/Family muss gemerkt werden,
+ // damit z.B. der Organizer nicht durcheinanderkommt, wenn zwischendurch eine
+ // Query-Box aufgemacht wird !!!
+
+ ScStyleSheetPool* pStylePool = xPoolHelper->GetStylePool();
+ USHORT nOldMask = pStylePool->GetSearchMask();
+ SfxStyleFamily eOldFam = pStylePool->GetSearchFamily();
+
+ pTable = pTab[nTab];
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL );
+ pStyle = (ScStyleSheet*)pStylePool->Find( pTable->aPageStyle,
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyle, "Missing StyleSheet :-/" );
+
+ BOOL bProgress = FALSE;
+ if ( pStyle && 0 == GET_SCALEVALUE(pStyle->GetItemSet(),ATTR_PAGE_SCALETOPAGES) )
+ {
+ USHORT nCount = 0;
+
+ nZoom = GET_SCALEVALUE(pStyle->GetItemSet(),ATTR_PAGE_SCALE);
+ Fraction aZoomFract( nZoom, 100 );
+ pColumn = &pTable->aCol[nCol];
+ pColIter = new ScColumnIterator( pColumn, nRow, MAXROW );
+
+ while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
+ {
+ if ( pColIter->Next( nRow, pCell ) )
+ {
+ if ( TEXTWIDTH_DIRTY == pCell->GetTextWidth() )
+ {
+ if ( !pDev )
+ {
+ pDev = GetPrinter();
+ aOldMap = pDev->GetMapMode();
+ pDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize
+
+ Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ nPPTX = aPix1000.X() / 1000.0;
+ nPPTY = aPix1000.Y() / 1000.0;
+ }
+ if ( !bProgress && pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pCell)->GetDirty() )
+ {
+ ScProgress::CreateInterpretProgress( this, FALSE );
+ bProgress = TRUE;
+ }
+
+// DBG_ERROR( String("t,c,r = ") + String(nTab) + String(',') + String(nCol) + String(',') + String(nRow) );
+// DBG_ERROR( String("nOldWidth = ") + String(pCell->GetTextWidth()) );
+
+ USHORT nNewWidth = (USHORT)GetNeededSize( nCol, nRow, nTab,
+ pDev, nPPTX, nPPTY,
+ aZoomFract,aZoomFract, TRUE,
+ TRUE ); // bTotalSize
+
+// DBG_ERROR( String("nNewWidth = ") + String(nNewWidth) );
+
+ pCell->SetTextWidth( nNewWidth );
+
+ bNeedMore = TRUE;
+ }
+ }
+ else
+ {
+ BOOL bNewTab = FALSE;
+
+ nRow = 0;
+ nCol--;
+
+ if ( nCol < 0 )
+ {
+ nCol = MAXCOL;
+ nTab++;
+ bNewTab = TRUE;
+ }
+
+ if ( !ValidTab(nTab) || !pTab[nTab] )
+ {
+ nTab = 0;
+ nRestart++;
+ bNewTab = TRUE;
+ }
+
+ if ( nRestart < 2 )
+ {
+ if ( bNewTab )
+ {
+ pTable = pTab[nTab];
+ pStyle = (ScStyleSheet*)pStylePool->Find( pTable->aPageStyle,
+ SFX_STYLE_FAMILY_PAGE );
+
+ if ( pStyle )
+ {
+ SfxItemSet& rSet = pStyle->GetItemSet();
+ if ( GET_SCALEVALUE( rSet, ATTR_PAGE_SCALETOPAGES ) == 0 )
+ nZoom = GET_SCALEVALUE(rSet, ATTR_PAGE_SCALE );
+ else
+ nZoom = 0;
+ }
+ else
+ {
+ DBG_ERROR( "Missing StyleSheet :-/" );
+ }
+ }
+
+ if ( nZoom > 0 )
+ {
+ delete pColIter;
+
+ pColumn = &pTable->aCol[nCol];
+ pColIter = new ScColumnIterator( pColumn, nRow, MAXROW );
+ }
+ else
+ nTab++; // Tabelle nicht mit absolutem Zoom -> naechste
+ }
+ }
+
+// nIter = nCount;
+
+ nCount++;
+
+ // Idle Berechnung abbrechen, wenn Berechnungen laenger als
+ // 50ms dauern, oder nach 32 Berechnungen mal nachschauen, ob
+ // bestimmte Events anstehen, die Beachtung wuenschen:
+
+// nMs = SysTicksToMs( GetSysTicks() - nStart );
+
+ if ( ( 50L < Time::GetSystemTicks() - nStart )
+ || ( !(nCount&31) && Application::AnyInput( ABORT_EVENTS ) ) )
+ nCount = CALCMAX;
+ }
+ }
+ else
+ nTab++; // Tabelle nicht mit absolutem Zoom -> naechste
+
+ if ( bProgress )
+ ScProgress::DeleteInterpretProgress();
+
+ delete pColIter;
+
+// DBG_ERROR( String(nCount) + String(" End = ") + String(nTab) + String(',') + String(nCol) + String(',') + String(nRow) );
+
+ if (pDev)
+ pDev->SetMapMode(aOldMap);
+
+ aCurTextWidthCalcPos.SetTab( nTab );
+ aCurTextWidthCalcPos.SetRow( nRow );
+ aCurTextWidthCalcPos.SetCol( (SCCOL)nCol );
+
+// DBG_ERROR( String(nMs) + String(" ms (") + String(nIter) + String(')') );
+
+ pStylePool->SetSearchMask( eOldFam, nOldMask );
+ bIdleDisabled = FALSE;
+
+ return bNeedMore;
+}
+
+//------------------------------------------------------------------------
+
+class ScSpellStatus
+{
+public:
+ BOOL bModified;
+
+ ScSpellStatus() : bModified(FALSE) {};
+
+ DECL_LINK (EventHdl, EditStatus*);
+};
+
+IMPL_LINK( ScSpellStatus, EventHdl, EditStatus *, pStatus )
+{
+ ULONG nStatus = pStatus->GetStatusWord();
+ if ( nStatus & EE_STAT_WRONGWORDCHANGED )
+ bModified = TRUE;
+
+ return 0;
+}
+
+// SPELL_MAXCELLS muss mindestens 256 sein, solange am Iterator keine
+// Start-Spalte gesetzt werden kann
+
+//! SPELL_MAXTEST fuer Timer und Idle unterschiedlich ???
+
+// SPELL_MAXTEST now divided between visible and rest of document
+
+#define SPELL_MAXTEST_VIS 1
+#define SPELL_MAXTEST_ALL 3
+#define SPELL_MAXCELLS 256
+
+BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpellPos,
+ USHORT nMaxTest )
+{
+ ScEditEngineDefaulter* pEngine = NULL; //! am Dokument speichern
+ SfxItemSet* pDefaults = NULL;
+ ScSpellStatus aStatus;
+
+ USHORT nCellCount = 0; // Zellen insgesamt
+ USHORT nTestCount = 0; // Aufrufe Spelling
+ BOOL bChanged = FALSE; // Aenderungen?
+
+ SCCOL nCol = rSpellRange.aStart.Col(); // iterator always starts on the left edge
+ SCROW nRow = rSpellPos.Row();
+ SCTAB nTab = rSpellPos.Tab();
+ if ( !pTab[nTab] ) // sheet deleted?
+ {
+ nTab = rSpellRange.aStart.Tab();
+ nRow = rSpellRange.aStart.Row();
+ if ( !pTab[nTab] )
+ {
+ // may happen for visible range
+ return FALSE;
+ }
+ }
+ ScHorizontalCellIterator aIter( this, nTab,
+ rSpellRange.aStart.Col(), nRow,
+ rSpellRange.aEnd.Col(), rSpellRange.aEnd.Row() );
+ ScBaseCell* pCell = aIter.GetNext( nCol, nRow );
+ // skip everything left of rSpellPos:
+ while ( pCell && nRow == rSpellPos.Row() && nCol < rSpellPos.Col() )
+ pCell = aIter.GetNext( nCol, nRow );
+
+ for (; pCell; pCell = aIter.GetNext(nCol, nRow))
+ {
+ if (pDPCollection && pDPCollection->HasDPTable(nCol, nRow, nTab))
+ // Don't spell check within datapilot table.
+ continue;
+
+ CellType eType = pCell->GetCellType();
+ if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
+ {
+ if (!pEngine)
+ {
+ // #71154# ScTabEditEngine is needed
+ // because MapMode must be set for some old documents
+ pEngine = new ScTabEditEngine( this );
+ pEngine->SetControlWord( pEngine->GetControlWord() |
+ ( EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS ) );
+ pEngine->SetStatusEventHdl( LINK( &aStatus, ScSpellStatus, EventHdl ) );
+ // Delimiters hier wie in inputhdl.cxx !!!
+ pEngine->SetWordDelimiters(
+ ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) );
+ pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
+
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
+
+ pEngine->SetSpeller( xXSpellChecker1 );
+ }
+
+ const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
+ pPattern->FillEditItemSet( pDefaults );
+ pEngine->SetDefaults( pDefaults, FALSE ); //! noetig ?
+
+ USHORT nCellLang = ((const SvxLanguageItem&)
+ pPattern->GetItem(ATTR_FONT_LANGUAGE)).GetValue();
+ if ( nCellLang == LANGUAGE_SYSTEM )
+ nCellLang = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
+ pEngine->SetDefaultLanguage( nCellLang );
+
+ if ( eType == CELLTYPE_STRING )
+ {
+ String aText;
+ ((ScStringCell*)pCell)->GetString(aText);
+ pEngine->SetText( aText );
+ }
+ else
+ pEngine->SetText( *((ScEditCell*)pCell)->GetData() );
+
+ aStatus.bModified = FALSE;
+ pEngine->CompleteOnlineSpelling();
+ if ( aStatus.bModified ) // Fehler dazu oder weggekommen?
+ {
+ BOOL bNeedEdit = TRUE; // Test auf einfachen Text
+ if ( !pEngine->HasOnlineSpellErrors() )
+ {
+ ScEditAttrTester aTester( pEngine );
+ bNeedEdit = aTester.NeedsObject();
+ }
+
+ if ( bNeedEdit )
+ {
+ EditTextObject* pNewData = pEngine->CreateTextObject();
+ if ( eType == CELLTYPE_EDIT )
+ ((ScEditCell*)pCell)->SetData( pNewData,
+ pEngine->GetEditTextObjectPool() );
+ else
+ PutCell( nCol, nRow, nTab, new ScEditCell( pNewData,
+ this, pEngine->GetEditTextObjectPool() ) );
+ delete pNewData;
+ }
+ else // einfacher String
+ PutCell( nCol, nRow, nTab, new ScStringCell( pEngine->GetText() ) );
+
+ // Paint
+ if (pShell)
+ {
+ // #47751# Seitenvorschau ist davon nicht betroffen
+ // (sollte jedenfalls nicht)
+ ScPaintHint aHint( ScRange( nCol, nRow, nTab ), PAINT_GRID );
+ aHint.SetPrintFlag( FALSE );
+ pShell->Broadcast( aHint );
+ }
+
+ bChanged = TRUE;
+ }
+
+ if ( ++nTestCount >= nMaxTest ) // checked enough text?
+ break;
+ }
+
+ if ( ++nCellCount >= SPELL_MAXCELLS ) // seen enough cells?
+ break;
+ }
+
+ if ( pCell )
+ {
+ ++nCol; // continue after last cell
+ if ( nCol > rSpellRange.aEnd.Col() )
+ {
+ nCol = rSpellRange.aStart.Col();
+ ++nRow;
+ if ( nRow > rSpellRange.aEnd.Row() )
+ pCell = NULL;
+ }
+ }
+
+ if (!pCell) // end of range reached -> next sheet
+ {
+ ++nTab;
+ if ( nTab > rSpellRange.aEnd.Tab() || !pTab[nTab] )
+ nTab = rSpellRange.aStart.Tab();
+ nCol = rSpellRange.aStart.Col();
+ nRow = rSpellRange.aStart.Row();
+
+ nVisSpellState = VSPL_DONE; //! only if this is for the visible range
+ }
+ rSpellPos.Set( nCol, nRow, nTab );
+
+ delete pDefaults;
+ delete pEngine; // bevor aStatus out of scope geht
+
+ return bChanged;
+}
+
+
+BOOL ScDocument::ContinueOnlineSpelling()
+{
+ if ( bIdleDisabled || !pDocOptions->IsAutoSpell() || (pShell && pShell->IsReadOnly()) )
+ return FALSE;
+
+ // #i48433# set bInsertingFromOtherDoc flag so there are no broadcasts when PutCell is called
+ // (same behavior as in RemoveAutoSpellObj: just transfer the broadcaster)
+ BOOL bOldInserting = IsInsertingFromOtherDoc();
+ SetInsertingFromOtherDoc( TRUE );
+
+ //! use one EditEngine for both calls
+
+ // #41504# first check visible range
+ BOOL bResult = OnlineSpellInRange( aVisSpellRange, aVisSpellPos, SPELL_MAXTEST_VIS );
+
+ // during first pass through visible range, always continue
+ if ( nVisSpellState == VSPL_START )
+ bResult = TRUE;
+
+ if (bResult)
+ {
+ // if errors found, continue there
+ OnlineSpellInRange( aVisSpellRange, aVisSpellPos, SPELL_MAXTEST_ALL );
+ }
+ else
+ {
+ // if nothing found there, continue with rest of document
+ ScRange aTotalRange( 0,0,0, MAXCOL,MAXROW,MAXTAB );
+ bResult = OnlineSpellInRange( aTotalRange, aOnlineSpellPos, SPELL_MAXTEST_ALL );
+ }
+
+ SetInsertingFromOtherDoc( bOldInserting );
+
+ return bResult;
+}
+
+
+void ScDocument::SetOnlineSpellPos( const ScAddress& rPos )
+{
+ aOnlineSpellPos = rPos;
+
+ // skip visible area for aOnlineSpellPos
+ if ( aVisSpellRange.In( aOnlineSpellPos ) )
+ aOnlineSpellPos = aVisSpellRange.aEnd;
+}
+
+BOOL ScDocument::SetVisibleSpellRange( const ScRange& rNewRange )
+{
+ BOOL bChange = ( aVisSpellRange != rNewRange );
+ if (bChange)
+ {
+ // continue spelling through visible range when scrolling down
+ BOOL bContDown = ( nVisSpellState == VSPL_START && rNewRange.In( aVisSpellPos ) &&
+ rNewRange.aStart.Row() > aVisSpellRange.aStart.Row() &&
+ rNewRange.aStart.Col() == aVisSpellRange.aStart.Col() &&
+ rNewRange.aEnd.Col() == aVisSpellRange.aEnd.Col() );
+
+ aVisSpellRange = rNewRange;
+
+ if ( !bContDown )
+ {
+ aVisSpellPos = aVisSpellRange.aStart;
+ nVisSpellState = VSPL_START;
+ }
+
+ // skip visible area for aOnlineSpellPos
+ if ( aVisSpellRange.In( aOnlineSpellPos ) )
+ aOnlineSpellPos = aVisSpellRange.aEnd;
+ }
+ return bChange;
+}
+
+void ScDocument::RemoveAutoSpellObj()
+{
+ // alle Spelling-Informationen entfernen
+
+ for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
+ pTab[nTab]->RemoveAutoSpellObj();
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocument::IdleCheckLinks() // TRUE = demnaechst wieder versuchen
+{
+ BOOL bAnyLeft = FALSE;
+
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ {
+ ScDdeLink* pDdeLink = (ScDdeLink*)pBase;
+ if (pDdeLink->NeedsUpdate())
+ {
+ pDdeLink->TryUpdate();
+ if (pDdeLink->NeedsUpdate()) // war nix?
+ bAnyLeft = TRUE;
+ }
+ }
+ }
+ }
+
+ return bAnyLeft;
+}
+
+void ScDocument::SaveDdeLinks(SvStream& rStream) const
+{
+ // bei 4.0-Export alle mit Modus != DEFAULT weglassen
+ BOOL bExport40 = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 );
+
+ const ::sfx2::SvBaseLinks& rLinks = GetLinkManager()->GetLinks();
+ USHORT nCount = rLinks.Count();
+
+ // erstmal zaehlen...
+
+ USHORT nDdeCount = 0;
+ USHORT i;
+ for (i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ if ( !bExport40 || ((ScDdeLink*)pBase)->GetMode() == SC_DDE_DEFAULT )
+ ++nDdeCount;
+ }
+
+ // Header
+
+ ScMultipleWriteHeader aHdr( rStream );
+ rStream << nDdeCount;
+
+ // Links speichern
+
+ for (i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ {
+ ScDdeLink* pLink = (ScDdeLink*)pBase;
+ if ( !bExport40 || pLink->GetMode() == SC_DDE_DEFAULT )
+ pLink->Store( rStream, aHdr );
+ }
+ }
+}
+
+void ScDocument::LoadDdeLinks(SvStream& rStream)
+{
+ ScMultipleReadHeader aHdr( rStream );
+
+ GetLinkManager();
+ USHORT nCount;
+ rStream >> nCount;
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScDdeLink* pLink = new ScDdeLink( this, rStream, aHdr );
+ pLinkManager->InsertDDELink( pLink,
+ pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem() );
+ }
+}
+
+BOOL ScDocument::HasDdeLinks() const
+{
+ if (GetLinkManager()) // Clipboard z.B. hat keinen LinkManager
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ if ((*rLinks[i])->ISA(ScDdeLink))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ScDocument::SetInLinkUpdate(BOOL bSet)
+{
+ // called from TableLink and AreaLink
+
+ DBG_ASSERT( bInLinkUpdate != bSet, "SetInLinkUpdate twice" );
+ bInLinkUpdate = bSet;
+}
+
+BOOL ScDocument::IsInLinkUpdate() const
+{
+ return bInLinkUpdate || IsInDdeLinkUpdate();
+}
+
+void ScDocument::UpdateExternalRefLinks()
+{
+ if (!GetLinkManager())
+ return;
+
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+
+ bool bAny = false;
+ for (USHORT i = 0; i < nCount; ++i)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase);
+ if (pRefLink)
+ {
+ pRefLink->Update();
+ bAny = true;
+ }
+ }
+ if (bAny)
+ {
+ 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 );
+ }
+ }
+ }
+}
+
+void ScDocument::UpdateDdeLinks()
+{
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ USHORT i;
+
+ // #49226# falls das Updaten laenger dauert, erstmal alle Werte
+ // zuruecksetzen, damit nichts altes (falsches) stehen bleibt
+ BOOL bAny = FALSE;
+ for (i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ {
+ ((ScDdeLink*)pBase)->ResetValue();
+ bAny = TRUE;
+ }
+ }
+ if (bAny)
+ {
+ // Formeln berechnen und painten wie im TrackTimeHdl
+ TrackFormulas();
+ pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
+ ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
+
+ // wenn FID_DATACHANGED irgendwann mal asynchron werden sollte
+ // (z.B. mit Invalidate am Window), muss hier ein Update erzwungen werden.
+ }
+
+ // nun wirklich updaten...
+ for (i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ ((ScDdeLink*)pBase)->TryUpdate(); // bei DDE-Links TryUpdate statt Update
+ }
+ }
+}
+
+BOOL ScDocument::UpdateDdeLink( const String& rAppl, const String& rTopic, const String& rItem )
+{
+ // fuer refresh() per StarOne Api
+ // ResetValue() fuer einzelnen Link nicht noetig
+ //! wenn's mal alles asynchron wird, aber auch hier
+
+ BOOL bFound = FALSE;
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ {
+ ScDdeLink* pDdeLink = (ScDdeLink*)pBase;
+ if ( pDdeLink->GetAppl() == rAppl &&
+ pDdeLink->GetTopic() == rTopic &&
+ pDdeLink->GetItem() == rItem )
+ {
+ pDdeLink->TryUpdate();
+ bFound = TRUE; // koennen theoretisch mehrere sein (Mode), darum weitersuchen
+ }
+ }
+ }
+ }
+ return bFound;
+}
+
+void ScDocument::DisconnectDdeLinks()
+{
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ pBase->Disconnect(); // bleibt im LinkManager eingetragen
+ }
+ }
+}
+
+void ScDocument::CopyDdeLinks( ScDocument* pDestDoc ) const
+{
+ if (bIsClip) // aus Stream erzeugen
+ {
+ if (pClipData)
+ {
+ pClipData->Seek(0);
+ pDestDoc->LoadDdeLinks(*pClipData);
+ }
+ }
+ else if (GetLinkManager()) // Links direkt kopieren
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScDdeLink))
+ {
+ ScDdeLink* pNew = new ScDdeLink( pDestDoc, *(ScDdeLink*)pBase );
+
+ pDestDoc->pLinkManager->InsertDDELink( pNew,
+ pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem() );
+ }
+ }
+ }
+}
+
+USHORT ScDocument::GetDdeLinkCount() const
+{
+ USHORT nDdeCount = 0;
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ if ((*rLinks[i])->ISA(ScDdeLink))
+ ++nDdeCount;
+ }
+ return nDdeCount;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Tries to find the specified DDE link.
+ @param pnDdePos (out-param) if not 0, the index of the DDE link is returned here
+ (does not include other links from link manager).
+ @return The DDE link, if it exists, otherwise 0. */
+ScDdeLink* lclGetDdeLink(
+ const sfx2::LinkManager* pLinkManager,
+ const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode,
+ USHORT* pnDdePos = NULL )
+{
+ if( pLinkManager )
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ if( pnDdePos ) *pnDdePos = 0;
+ for( USHORT nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
+ if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
+ {
+ if( (pDdeLink->GetAppl() == rAppl) &&
+ (pDdeLink->GetTopic() == rTopic) &&
+ (pDdeLink->GetItem() == rItem) &&
+ ((nMode == SC_DDE_IGNOREMODE) || (nMode == pDdeLink->GetMode())) )
+ return pDdeLink;
+ if( pnDdePos ) ++*pnDdePos;
+ }
+ }
+ }
+ return NULL;
+}
+
+/** Returns a pointer to the specified DDE link.
+ @param nDdePos Index of the DDE link (does not include other links from link manager).
+ @return The DDE link, if it exists, otherwise 0. */
+ScDdeLink* lclGetDdeLink( const sfx2::LinkManager* pLinkManager, USHORT nDdePos )
+{
+ if( pLinkManager )
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ USHORT nDdeIndex = 0; // counts only the DDE links
+ for( USHORT nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
+ if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
+ {
+ if( nDdeIndex == nDdePos )
+ return pDdeLink;
+ ++nDdeIndex;
+ }
+ }
+ }
+ return NULL;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+bool ScDocument::FindDdeLink( const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode, USHORT& rnDdePos )
+{
+ return lclGetDdeLink( GetLinkManager(), rAppl, rTopic, rItem, nMode, &rnDdePos ) != NULL;
+}
+
+bool ScDocument::GetDdeLinkData( USHORT nDdePos, String& rAppl, String& rTopic, String& rItem ) const
+{
+ if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
+ {
+ rAppl = pDdeLink->GetAppl();
+ rTopic = pDdeLink->GetTopic();
+ rItem = pDdeLink->GetItem();
+ return true;
+ }
+ return false;
+}
+
+bool ScDocument::GetDdeLinkMode( USHORT nDdePos, BYTE& rnMode ) const
+{
+ if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
+ {
+ rnMode = pDdeLink->GetMode();
+ return true;
+ }
+ return false;
+}
+
+const ScMatrix* ScDocument::GetDdeLinkResultMatrix( USHORT nDdePos ) const
+{
+ const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos );
+ return pDdeLink ? pDdeLink->GetResult() : NULL;
+}
+
+bool ScDocument::CreateDdeLink( const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode, ScMatrix* pResults )
+{
+ /* Create a DDE link without updating it (i.e. for Excel import), to prevent
+ unwanted connections. First try to find existing link. Set result array
+ on existing and new links. */
+ //! store DDE links additionally at document (for efficiency)?
+ DBG_ASSERT( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
+ if( GetLinkManager() && (nMode != SC_DDE_IGNOREMODE) )
+ {
+ ScDdeLink* pDdeLink = lclGetDdeLink( pLinkManager, rAppl, rTopic, rItem, nMode );
+ if( !pDdeLink )
+ {
+ // create a new DDE link, but without TryUpdate
+ pDdeLink = new ScDdeLink( this, rAppl, rTopic, rItem, nMode );
+ pLinkManager->InsertDDELink( pDdeLink, rAppl, rTopic, rItem );
+ }
+
+ // insert link results
+ if( pResults )
+ pDdeLink->SetResult( pResults );
+
+ return true;
+ }
+ return false;
+}
+
+bool ScDocument::SetDdeLinkResultMatrix( USHORT nDdePos, ScMatrix* pResults )
+{
+ if( ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
+ {
+ pDdeLink->SetResult( pResults );
+ return true;
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocument::HasAreaLinks() const
+{
+ if (GetLinkManager()) // Clipboard z.B. hat keinen LinkManager
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ if ((*rLinks[i])->ISA(ScAreaLink))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ScDocument::UpdateAreaLinks()
+{
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ pBase->Update();
+ }
+ }
+}
+
+void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab )
+{
+ if (GetLinkManager())
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nPos = 0;
+ while ( nPos < rLinks.Count() )
+ {
+ const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
+ if ( pBase->ISA(ScAreaLink) &&
+ static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
+ pLinkManager->Remove( nPos );
+ else
+ ++nPos;
+ }
+ }
+}
+
+void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ if (GetLinkManager())
+ {
+ bool bAnyUpdate = false;
+
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ {
+ ScAreaLink* pLink = (ScAreaLink*) pBase;
+ ScRange aOutRange = pLink->GetDestArea();
+
+ SCCOL nCol1 = aOutRange.aStart.Col();
+ SCROW nRow1 = aOutRange.aStart.Row();
+ SCTAB nTab1 = aOutRange.aStart.Tab();
+ SCCOL nCol2 = aOutRange.aEnd.Col();
+ SCROW nRow2 = aOutRange.aEnd.Row();
+ SCTAB nTab2 = aOutRange.aEnd.Tab();
+
+ ScRefUpdateRes eRes =
+ ScRefUpdate::Update( this, eUpdateRefMode,
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if ( eRes != UR_NOTHING )
+ {
+ pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
+ bAnyUpdate = true;
+ }
+ }
+ }
+
+ if ( bAnyUpdate )
+ {
+ // #i52120# Look for duplicates (after updating all positions).
+ // If several links start at the same cell, the one with the lower index is removed
+ // (file format specifies only one link definition for a cell).
+
+ USHORT nFirstIndex = 0;
+ while ( nFirstIndex < nCount )
+ {
+ bool bFound = false;
+ ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
+ if ( pFirst->ISA(ScAreaLink) )
+ {
+ ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
+ for ( USHORT nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
+ {
+ ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
+ if ( pSecond->ISA(ScAreaLink) &&
+ static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
+ {
+ // remove the first link, exit the inner loop, don't increment nFirstIndex
+ pLinkManager->Remove( pFirst );
+ nCount = rLinks.Count();
+ bFound = true;
+ }
+ }
+ }
+ if (!bFound)
+ ++nFirstIndex;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+// TimerDelays etc.
+void ScDocument::KeyInput( const KeyEvent& )
+{
+ if ( pChartListenerCollection->GetCount() )
+ pChartListenerCollection->StartTimer();
+ if( apTemporaryChartLock.get() )
+ apTemporaryChartLock->StartOrContinueLocking();
+}
+
+// ----------------------------------------------------------------------------
+
+BOOL ScDocument::CheckMacroWarn()
+{
+ // The check for macro configuration, macro warning and disabling is now handled
+ // in SfxObjectShell::AdjustMacroMode, called by SfxObjectShell::CallBasic.
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+SfxBindings* ScDocument::GetViewBindings()
+{
+ // used to invalidate slots after changes to this document
+
+ if ( !pShell )
+ return NULL; // no ObjShell -> no view
+
+ // first check current view
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame && pViewFrame->GetObjectShell() != pShell ) // wrong document?
+ pViewFrame = NULL;
+
+ // otherwise use first view for this doc
+ if ( !pViewFrame )
+ pViewFrame = SfxViewFrame::GetFirst( pShell );
+
+ if (pViewFrame)
+ return &pViewFrame->GetBindings();
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+void lcl_TransliterateEditEngine( ScEditEngineDefaulter& rEngine,
+ utl::TransliterationWrapper& rTranslitarationWrapper,
+ BOOL bConsiderLanguage, ScDocument* pDoc )
+{
+ //! should use TransliterateText method of EditEngine instead, when available!
+
+ sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
+
+ USHORT nParCount = rEngine.GetParagraphCount();
+ for (USHORT nPar=0; nPar<nParCount; nPar++)
+ {
+ SvUShorts aPortions;
+ rEngine.GetPortions( (USHORT)nPar, aPortions );
+
+ for ( USHORT nPos = aPortions.Count(); nPos; )
+ {
+ --nPos;
+ USHORT nEnd = aPortions.GetObject( nPos );
+ USHORT nStart = nPos ? aPortions.GetObject( nPos - 1 ) : 0;
+
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ String aOldStr = rEngine.GetText( aSel );
+ SfxItemSet aAttr = rEngine.GetAttribs( aSel );
+
+ if ( aAttr.GetItemState( EE_FEATURE_FIELD ) != SFX_ITEM_ON ) // fields are not touched
+ {
+ if ( bConsiderLanguage )
+ {
+ BYTE nScript = pDoc->GetStringScriptType( aOldStr );
+ USHORT nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? EE_CHAR_LANGUAGE_CJK :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? EE_CHAR_LANGUAGE_CTL :
+ EE_CHAR_LANGUAGE );
+ nLanguage = ((const SvxLanguageItem&)aAttr.Get(nWhich)).GetValue();
+ }
+
+ com::sun::star::uno::Sequence<sal_Int32> aOffsets;
+ String aNewStr = rTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, aOldStr.Len(), &aOffsets );
+
+ if ( aNewStr != aOldStr )
+ {
+ // replace string, keep attributes
+
+ rEngine.QuickInsertText( aNewStr, aSel );
+ aSel.nEndPos = aSel.nStartPos + aNewStr.Len();
+ rEngine.QuickSetAttribs( aAttr, aSel );
+ }
+ }
+ }
+ }
+}
+
+void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nType )
+{
+ DBG_ASSERT( rMultiMark.IsMultiMarked(), "TransliterateText: no selection" );
+
+ utl::TransliterationWrapper aTranslitarationWrapper( xServiceManager, nType );
+ BOOL bConsiderLanguage = aTranslitarationWrapper.needLanguageForTheMode();
+ sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
+
+ ScEditEngineDefaulter* pEngine = NULL; // not using pEditEngine member because of defaults
+
+ SCTAB nCount = GetTableCount();
+ for (SCTAB nTab = 0; nTab < nCount; nTab++)
+ if ( pTab[nTab] && rMultiMark.GetTableSelect(nTab) )
+ {
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+
+ BOOL bFound = rMultiMark.IsCellMarked( nCol, nRow );
+ if (!bFound)
+ bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
+
+ while (bFound)
+ {
+ const ScBaseCell* pCell = GetCell( ScAddress( nCol, nRow, nTab ) );
+ CellType eType = pCell ? pCell->GetCellType() : CELLTYPE_NONE;
+
+ if ( eType == CELLTYPE_STRING )
+ {
+ String aOldStr;
+ ((const ScStringCell*)pCell)->GetString(aOldStr);
+ xub_StrLen nOldLen = aOldStr.Len();
+
+ if ( bConsiderLanguage )
+ {
+ BYTE nScript = GetStringScriptType( aOldStr ); //! cell script type?
+ USHORT nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE :
+ ATTR_FONT_LANGUAGE );
+ nLanguage = ((const SvxLanguageItem*)GetAttr( nCol, nRow, nTab, nWhich ))->GetValue();
+ }
+
+ com::sun::star::uno::Sequence<sal_Int32> aOffsets;
+ String aNewStr = aTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
+
+ if ( aNewStr != aOldStr )
+ PutCell( nCol, nRow, nTab, new ScStringCell( aNewStr ) );
+ }
+ else if ( eType == CELLTYPE_EDIT )
+ {
+ if (!pEngine)
+ pEngine = new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
+
+ // defaults from cell attributes must be set so right language is used
+ const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
+ SfxItemSet* pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pPattern->FillEditItemSet( pDefaults );
+ pEngine->SetDefaults( pDefaults, TRUE );
+
+ const EditTextObject* pData = ((const ScEditCell*)pCell)->GetData();
+ pEngine->SetText( *pData );
+
+ pEngine->ClearModifyFlag();
+
+ lcl_TransliterateEditEngine( *pEngine, aTranslitarationWrapper, bConsiderLanguage, this );
+
+ if ( pEngine->IsModified() )
+ {
+ ScEditAttrTester aTester( pEngine );
+ if ( aTester.NeedsObject() )
+ {
+ // remove defaults (paragraph attributes) before creating text object
+ SfxItemSet* pEmpty = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pEngine->SetDefaults( pEmpty, TRUE );
+
+ EditTextObject* pNewData = pEngine->CreateTextObject();
+ PutCell( nCol, nRow, nTab,
+ new ScEditCell( pNewData, this, pEngine->GetEditTextObjectPool() ) );
+ delete pNewData;
+ }
+ else
+ {
+ String aNewStr = pEngine->GetText();
+ PutCell( nCol, nRow, nTab, new ScStringCell( aNewStr ) );
+ }
+ }
+ }
+
+ bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
+ }
+ }
+
+ delete pEngine;
+}
+
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
new file mode 100644
index 000000000000..abef7d53c2af
--- /dev/null
+++ b/sc/source/core/data/documen9.cxx
@@ -0,0 +1,820 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sot/exchange.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/xtable.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <unotools/saveopt.hxx>
+#include <unotools/pathoptions.hxx>
+
+#include "document.hxx"
+#include "docoptio.hxx"
+#include "table.hxx"
+#include "drwlayer.hxx"
+#include "markdata.hxx"
+#include "patattr.hxx"
+#include "rechead.hxx"
+#include "poolhelp.hxx"
+#include "docpool.hxx"
+#include "detfunc.hxx" // for UpdateAllComments
+#include "editutil.hxx"
+#include "postit.hxx"
+#include "charthelper.hxx"
+
+using namespace ::com::sun::star;
+#include <stdio.h>
+// -----------------------------------------------------------------------
+
+
+SfxBroadcaster* ScDocument::GetDrawBroadcaster()
+{
+ return pDrawLayer;
+}
+
+void ScDocument::BeginDrawUndo()
+{
+ if (pDrawLayer)
+ pDrawLayer->BeginCalcUndo();
+}
+
+XColorTable* ScDocument::GetColorTable()
+{
+ if (pDrawLayer)
+ return pDrawLayer->GetColorTable();
+ else
+ {
+ if (!pColorTable)
+ {
+ SvtPathOptions aPathOpt;
+ pColorTable = new XColorTable( aPathOpt.GetPalettePath() );
+ }
+
+ return pColorTable;
+ }
+}
+
+void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos)
+{
+ if (pDrawLayer && pSrcDoc->pDrawLayer)
+ {
+ SdrPage* pOldPage = pSrcDoc->pDrawLayer->GetPage(static_cast<sal_uInt16>(nSrcPos));
+ SdrPage* pNewPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestPos));
+
+ if (pOldPage && pNewPage)
+ {
+ SdrObjListIter aIter( *pOldPage, IM_FLAT );
+ SdrObject* pOldObject = aIter.Next();
+ while (pOldObject)
+ {
+ // #116235#
+ SdrObject* pNewObject = pOldObject->Clone();
+ // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer );
+ pNewObject->SetModel(pDrawLayer);
+ pNewObject->SetPage(pNewPage);
+
+ pNewObject->NbcMove(Size(0,0));
+ pNewPage->InsertObject( pNewObject );
+
+ if (pDrawLayer->IsRecording())
+ pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+
+ pOldObject = aIter.Next();
+ }
+ }
+ }
+
+ // #71726# make sure the data references of charts are adapted
+ // (this must be after InsertObject!)
+ ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pSrcDoc, this, nSrcPos, nDestPos );
+}
+
+void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell )
+{
+ if (pDocShell && !pShell)
+ pShell = pDocShell;
+
+// DBG_ASSERT(pShell,"InitDrawLayer ohne Shell");
+
+ if (!pDrawLayer)
+ {
+ String aName;
+ if ( pShell && !pShell->IsLoading() ) // #88438# don't call GetTitle while loading
+ aName = pShell->GetTitle();
+ pDrawLayer = new ScDrawLayer( this, aName );
+ if (GetLinkManager())
+ pDrawLayer->SetLinkManager( pLinkManager );
+
+ // Drawing pages are accessed by table number, so they must also be present
+ // for preceding table numbers, even if the tables aren't allocated
+ // (important for clipboard documents).
+
+ SCTAB nDrawPages = 0;
+ SCTAB nTab;
+ for (nTab=0; nTab<=MAXTAB; nTab++)
+ if (pTab[nTab])
+ nDrawPages = nTab + 1; // needed number of pages
+
+ for (nTab=0; nTab<nDrawPages; nTab++)
+ {
+ pDrawLayer->ScAddPage( nTab ); // always add page, with or without the table
+ if (pTab[nTab])
+ {
+ String aTabName;
+ pTab[nTab]->GetName(aTabName);
+ pDrawLayer->ScRenamePage( nTab, aTabName );
+
+ pTab[nTab]->SetDrawPageSize(false,false); // #54782# set the right size immediately
+#if 0
+ ULONG nx = (ULONG) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
+ ULONG ny = (ULONG) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
+ pDrawLayer->SetPageSize( nTab, Size( nx, ny ) );
+#endif
+ }
+ }
+
+ pDrawLayer->SetDefaultTabulator( GetDocOptions().GetTabDistance() );
+
+ UpdateDrawPrinter();
+ UpdateDrawDefaults();
+ UpdateDrawLanguages();
+ if (bImportingXML)
+ pDrawLayer->EnableAdjust(FALSE);
+
+ pDrawLayer->SetForbiddenCharsTable( xForbiddenCharacters );
+ pDrawLayer->SetCharCompressType( GetAsianCompression() );
+ pDrawLayer->SetKernAsianPunctuation( GetAsianKerning() );
+ }
+}
+
+void ScDocument::UpdateDrawLanguages()
+{
+ if (pDrawLayer)
+ {
+ SfxItemPool& rDrawPool = pDrawLayer->GetItemPool();
+ rDrawPool.SetPoolDefaultItem( SvxLanguageItem( eLanguage, EE_CHAR_LANGUAGE ) );
+ rDrawPool.SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage, EE_CHAR_LANGUAGE_CJK ) );
+ rDrawPool.SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage, EE_CHAR_LANGUAGE_CTL ) );
+ }
+}
+
+void ScDocument::UpdateDrawDefaults()
+{
+ // drawing layer defaults that are set for new documents (if InitNew was called)
+
+ if ( pDrawLayer && bSetDrawDefaults )
+ {
+ SfxItemPool& rDrawPool = pDrawLayer->GetItemPool();
+ rDrawPool.SetPoolDefaultItem( SvxAutoKernItem( TRUE, EE_CHAR_PAIRKERNING ) );
+ }
+}
+
+void ScDocument::UpdateDrawPrinter()
+{
+ if (pDrawLayer)
+ {
+ // use the printer even if IsValid is false
+ // Application::GetDefaultDevice causes trouble with changing MapModes
+
+// OutputDevice* pRefDev = GetPrinter();
+// pRefDev->SetMapMode( MAP_100TH_MM );
+ pDrawLayer->SetRefDevice(GetRefDevice());
+ }
+}
+
+sal_Bool ScDocument::IsChart( const SdrObject* pObject )
+{
+ // #109985#
+ // IsChart() implementation moved to svx drawinglayer
+ if(pObject && OBJ_OLE2 == pObject->GetObjIdentifier())
+ {
+ return ((SdrOle2Obj*)pObject)->IsChart();
+ }
+
+ return sal_False;
+}
+
+IMPL_LINK_INLINE_START( ScDocument, GetUserDefinedColor, USHORT *, pColorIndex )
+{
+ return (long) &((GetColorTable()->GetColor(*pColorIndex))->GetColor());
+}
+IMPL_LINK_INLINE_END( ScDocument, GetUserDefinedColor, USHORT *, pColorIndex )
+
+void ScDocument::DeleteDrawLayer()
+{
+ delete pDrawLayer;
+}
+
+void ScDocument::DeleteColorTable()
+{
+ delete pColorTable;
+}
+
+BOOL ScDocument::DrawGetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) const
+{
+ return pDrawLayer->GetPrintArea( rRange, bSetHor, bSetVer );
+}
+
+void ScDocument::DrawMovePage( USHORT nOldPos, USHORT nNewPos )
+{
+ pDrawLayer->ScMovePage(nOldPos,nNewPos);
+}
+
+void ScDocument::DrawCopyPage( USHORT nOldPos, USHORT nNewPos )
+{
+ // angelegt wird die Page schon im ScTable ctor
+ pDrawLayer->ScCopyPage( nOldPos, nNewPos, FALSE );
+}
+
+void ScDocument::DeleteObjectsInArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark )
+{
+ if (!pDrawLayer)
+ return;
+
+ SCTAB nTabCount = GetTableCount();
+ for (SCTAB nTab=0; nTab<=nTabCount; nTab++)
+ if (pTab[nTab] && rMark.GetTableSelect(nTab))
+ pDrawLayer->DeleteObjectsInArea( nTab, nCol1, nRow1, nCol2, nRow2 );
+}
+
+void ScDocument::DeleteObjectsInSelection( const ScMarkData& rMark )
+{
+ if (!pDrawLayer)
+ return;
+
+ pDrawLayer->DeleteObjectsInSelection( rMark );
+}
+
+BOOL ScDocument::HasOLEObjectsInArea( const ScRange& rRange, const ScMarkData* pTabMark )
+{
+ // pTabMark is used only for selected tables. If pTabMark is 0, all tables of rRange are used.
+
+ if (!pDrawLayer)
+ return FALSE;
+
+ SCTAB nStartTab = 0;
+ SCTAB nEndTab = MAXTAB;
+ if ( !pTabMark )
+ {
+ nStartTab = rRange.aStart.Tab();
+ nEndTab = rRange.aEnd.Tab();
+ }
+
+ for (SCTAB nTab = nStartTab; nTab <= nEndTab; nTab++)
+ {
+ if ( !pTabMark || pTabMark->GetTableSelect(nTab) )
+ {
+ Rectangle aMMRect = GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
+
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ aMMRect.IsInside( pObject->GetCurrentBoundRect() ) )
+ return TRUE;
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+void ScDocument::StartAnimations( SCTAB nTab, Window* pWin )
+{
+ if (!pDrawLayer)
+ return;
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (!pPage)
+ return;
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if (pObject->ISA(SdrGrafObj))
+ {
+ SdrGrafObj* pGrafObj = (SdrGrafObj*)pObject;
+ if ( pGrafObj->IsAnimated() )
+ {
+ const Rectangle& rRect = pGrafObj->GetCurrentBoundRect();
+ pGrafObj->StartAnimation( pWin, rRect.TopLeft(), rRect.GetSize() );
+ }
+ }
+ pObject = aIter.Next();
+ }
+}
+
+//UNUSED2008-05 void ScDocument::RefreshNoteFlags()
+//UNUSED2008-05 {
+//UNUSED2008-05 if (!pDrawLayer)
+//UNUSED2008-05 return;
+//UNUSED2008-05
+//UNUSED2008-05 BOOL bAnyIntObj = FALSE;
+//UNUSED2008-05 SCTAB nTab;
+//UNUSED2008-05 ScPostIt aNote(this);
+//UNUSED2008-05 for (nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
+//UNUSED2008-05 {
+//UNUSED2008-05 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+//UNUSED2008-05 DBG_ASSERT(pPage,"Page ?");
+//UNUSED2008-05 if (pPage)
+//UNUSED2008-05 {
+//UNUSED2008-05 SdrObjListIter aIter( *pPage, IM_FLAT );
+//UNUSED2008-05 SdrObject* pObject = aIter.Next();
+//UNUSED2008-05 while (pObject)
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( pObject->GetLayer() == SC_LAYER_INTERN )
+//UNUSED2008-05 {
+//UNUSED2008-05 bAnyIntObj = TRUE; // for all internal objects, including detective
+//UNUSED2008-05
+//UNUSED2008-05 if ( pObject->ISA( SdrCaptionObj ) )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject );
+//UNUSED2008-05 if ( pData )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( GetNote( pData->aStt.Col(), pData->aStt.Row(), nTab, aNote))
+//UNUSED2008-05 if ( !aNote.IsShown() )
+//UNUSED2008-05 {
+//UNUSED2008-05 aNote.SetShown(TRUE);
+//UNUSED2008-05 SetNote( pData->aStt.Col(), pData->aStt.Row(), nTab, aNote);
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 pObject = aIter.Next();
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 if (bAnyIntObj)
+//UNUSED2008-05 {
+//UNUSED2008-05 // update attributes for all note objects and the colors of detective objects
+//UNUSED2008-05 // (we don't know with which settings the file was created)
+//UNUSED2008-05
+//UNUSED2008-05 ScDetectiveFunc aFunc( this, 0 );
+//UNUSED2008-05 aFunc.UpdateAllComments();
+//UNUSED2008-05 aFunc.UpdateAllArrowColors();
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+BOOL ScDocument::HasBackgroundDraw( SCTAB nTab, const Rectangle& rMMRect )
+{
+ // Gibt es Objekte auf dem Hintergrund-Layer, die (teilweise) von rMMRect
+ // betroffen sind?
+ // (fuer Drawing-Optimierung, vor dem Hintergrund braucht dann nicht geloescht
+ // zu werden)
+
+ if (!pDrawLayer)
+ return FALSE;
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (!pPage)
+ return FALSE;
+
+ BOOL bFound = FALSE;
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if ( pObject->GetLayer() == SC_LAYER_BACK && pObject->GetCurrentBoundRect().IsOver( rMMRect ) )
+ bFound = TRUE;
+ pObject = aIter.Next();
+ }
+
+ return bFound;
+}
+
+BOOL ScDocument::HasAnyDraw( SCTAB nTab, const Rectangle& rMMRect )
+{
+ // Gibt es ueberhaupt Objekte, die (teilweise) von rMMRect
+ // betroffen sind?
+ // (um leere Seiten beim Drucken zu erkennen)
+
+ if (!pDrawLayer)
+ return FALSE;
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (!pPage)
+ return FALSE;
+
+ BOOL bFound = FALSE;
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if ( pObject->GetCurrentBoundRect().IsOver( rMMRect ) )
+ bFound = TRUE;
+ pObject = aIter.Next();
+ }
+
+ return bFound;
+}
+
+void ScDocument::EnsureGraphicNames()
+{
+ if (pDrawLayer)
+ pDrawLayer->EnsureGraphicNames();
+}
+
+SdrObject* ScDocument::GetObjectAtPoint( SCTAB nTab, const Point& rPos )
+{
+ // fuer Drag&Drop auf Zeichenobjekt
+
+ SdrObject* pFound = NULL;
+ if (pDrawLayer && pTab[nTab])
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetCurrentBoundRect().IsInside(rPos) )
+ {
+ // Intern interessiert gar nicht
+ // Objekt vom Back-Layer nur, wenn kein Objekt von anderem Layer getroffen
+
+ SdrLayerID nLayer = pObject->GetLayer();
+ if ( (nLayer != SC_LAYER_INTERN) && (nLayer != SC_LAYER_HIDDEN) )
+ {
+ if ( nLayer != SC_LAYER_BACK ||
+ !pFound || pFound->GetLayer() == SC_LAYER_BACK )
+ {
+ pFound = pObject;
+ }
+ }
+ }
+ // weitersuchen -> letztes (oberstes) getroffenes Objekt nehmen
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+ return pFound;
+}
+
+BOOL ScDocument::IsPrintEmpty( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, BOOL bLeftIsEmpty,
+ ScRange* pLastRange, Rectangle* pLastMM ) const
+{
+ if (!IsBlockEmpty( nTab, nStartCol, nStartRow, nEndCol, nEndRow ))
+ return FALSE;
+
+ ScDocument* pThis = (ScDocument*)this; //! GetMMRect / HasAnyDraw etc. const !!!
+
+ Rectangle aMMRect;
+ if ( pLastRange && pLastMM && nTab == pLastRange->aStart.Tab() &&
+ nStartRow == pLastRange->aStart.Row() && nEndRow == pLastRange->aEnd.Row() )
+ {
+ // keep vertical part of aMMRect, only update horizontal position
+ aMMRect = *pLastMM;
+
+ long nLeft = 0;
+ SCCOL i;
+ for (i=0; i<nStartCol; i++)
+ nLeft += GetColWidth(i,nTab);
+ long nRight = nLeft;
+ for (i=nStartCol; i<=nEndCol; i++)
+ nRight += GetColWidth(i,nTab);
+
+ aMMRect.Left() = (long)(nLeft * HMM_PER_TWIPS);
+ aMMRect.Right() = (long)(nRight * HMM_PER_TWIPS);
+ }
+ else
+ aMMRect = pThis->GetMMRect( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+
+ if ( pLastRange && pLastMM )
+ {
+ *pLastRange = ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
+ *pLastMM = aMMRect;
+ }
+
+ if ( pThis->HasAnyDraw( nTab, aMMRect ))
+ return FALSE;
+
+ if ( nStartCol > 0 && !bLeftIsEmpty )
+ {
+ // aehnlich wie in ScPrintFunc::AdjustPrintArea
+ //! ExtendPrintArea erst ab Start-Spalte des Druckbereichs
+
+ SCCOL nExtendCol = nStartCol - 1;
+ SCROW nTmpRow = nEndRow;
+
+ pThis->ExtendMerge( 0,nStartRow, nExtendCol,nTmpRow, nTab,
+ FALSE, TRUE ); // kein Refresh, incl. Attrs
+
+ OutputDevice* pDev = pThis->GetPrinter();
+ pDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize
+ pThis->ExtendPrintArea( pDev, nTab, 0, nStartRow, nExtendCol, nEndRow );
+ if ( nExtendCol >= nStartCol )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void ScDocument::Clear( sal_Bool bFromDestructor )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ {
+ delete pTab[i];
+ pTab[i]=NULL;
+ }
+ delete pSelectionAttr;
+ pSelectionAttr = NULL;
+
+ if (pDrawLayer)
+ {
+ // #116168#
+ //pDrawLayer->Clear();
+ pDrawLayer->ClearModel( bFromDestructor );
+ }
+}
+
+BOOL ScDocument::HasControl( SCTAB nTab, const Rectangle& rMMRect )
+{
+ BOOL bFound = FALSE;
+
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if (pObject->ISA(SdrUnoObj))
+ {
+ Rectangle aObjRect = pObject->GetLogicRect();
+ if ( aObjRect.IsOver( rMMRect ) )
+ bFound = TRUE;
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScDocument::InvalidateControls( Window* pWin, SCTAB nTab, const Rectangle& rMMRect )
+{
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if (pObject->ISA(SdrUnoObj))
+ {
+ Rectangle aObjRect = pObject->GetLogicRect();
+ if ( aObjRect.IsOver( rMMRect ) )
+ {
+ // Uno-Controls zeichnen sich immer komplett, ohne Ruecksicht
+ // auf ClippingRegions. Darum muss das ganze Objekt neu gepainted
+ // werden, damit die Selektion auf der Tabelle nicht uebermalt wird.
+
+ //pWin->Invalidate( aObjRect.GetIntersection( rMMRect ) );
+ pWin->Invalidate( aObjRect );
+ }
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+}
+
+BOOL ScDocument::HasDetectiveObjects(SCTAB nTab) const
+{
+ // looks for detective objects, annotations don't count
+ // (used to adjust scale so detective objects hit their cells better)
+
+ BOOL bFound = FALSE;
+
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ // anything on the internal layer except captions (annotations)
+ if ( (pObject->GetLayer() == SC_LAYER_INTERN) && !ScDrawLayer::IsNoteCaption( pObject ) )
+ bFound = TRUE;
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScDocument::UpdateFontCharSet()
+{
+ // In alten Versionen (bis incl. 4.0 ohne SP) wurden beim Austausch zwischen
+ // Systemen die CharSets in den Font-Attributen nicht angepasst.
+ // Das muss fuer Dokumente bis incl SP2 nun nachgeholt werden:
+ // Alles, was nicht SYMBOL ist, wird auf den System-CharSet umgesetzt.
+ // Bei neuen Dokumenten (Version SC_FONTCHARSET) sollte der CharSet stimmen.
+
+ BOOL bUpdateOld = ( nSrcVer < SC_FONTCHARSET );
+
+ CharSet eSysSet = gsl_getSystemTextEncoding();
+ if ( eSrcSet != eSysSet || bUpdateOld )
+ {
+ USHORT nCount,i;
+ SvxFontItem* pItem;
+
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+ nCount = pPool->GetItemCount(ATTR_FONT);
+ for (i=0; i<nCount; i++)
+ {
+ pItem = (SvxFontItem*)pPool->GetItem(ATTR_FONT, i);
+ if ( pItem && ( pItem->GetCharSet() == eSrcSet ||
+ ( bUpdateOld && pItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
+ pItem->GetCharSet() = eSysSet;
+ }
+
+ if ( pDrawLayer )
+ {
+ SfxItemPool& rDrawPool = pDrawLayer->GetItemPool();
+ nCount = rDrawPool.GetItemCount(EE_CHAR_FONTINFO);
+ for (i=0; i<nCount; i++)
+ {
+ pItem = (SvxFontItem*)rDrawPool.GetItem(EE_CHAR_FONTINFO, i);
+ if ( pItem && ( pItem->GetCharSet() == eSrcSet ||
+ ( bUpdateOld && pItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
+ pItem->GetCharSet() = eSysSet;
+ }
+ }
+ }
+}
+
+void ScDocument::SetLoadingMedium( bool bVal )
+{
+ bLoadingMedium = bVal;
+ for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
+ {
+ if (!pTab[nTab])
+ return;
+
+ pTab[nTab]->SetLoadingMedium(bVal);
+ }
+}
+
+void ScDocument::SetImportingXML( bool bVal )
+{
+ bImportingXML = bVal;
+ if (pDrawLayer)
+ pDrawLayer->EnableAdjust(!bImportingXML);
+
+ if ( !bVal )
+ {
+ // #i57869# after loading, do the real RTL mirroring for the sheets that have the LoadingRTL flag set
+
+ for ( SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++ )
+ if ( pTab[nTab]->IsLoadingRTL() )
+ {
+ pTab[nTab]->SetLoadingRTL( FALSE );
+ SetLayoutRTL( nTab, TRUE ); // includes mirroring; bImportingXML must be cleared first
+ }
+ }
+
+ SetLoadingMedium(bVal);
+}
+
+void ScDocument::SetXMLFromWrapper( BOOL bVal )
+{
+ bXMLFromWrapper = bVal;
+}
+
+vos::ORef<SvxForbiddenCharactersTable> ScDocument::GetForbiddenCharacters()
+{
+ return xForbiddenCharacters;
+}
+
+void ScDocument::SetForbiddenCharacters( const vos::ORef<SvxForbiddenCharactersTable> xNew )
+{
+ xForbiddenCharacters = xNew;
+ if ( pEditEngine )
+ pEditEngine->SetForbiddenCharsTable( xForbiddenCharacters );
+ if ( pDrawLayer )
+ pDrawLayer->SetForbiddenCharsTable( xForbiddenCharacters );
+}
+
+BOOL ScDocument::IsValidAsianCompression() const
+{
+ return ( nAsianCompression != SC_ASIANCOMPRESSION_INVALID );
+}
+
+BYTE ScDocument::GetAsianCompression() const
+{
+ if ( nAsianCompression == SC_ASIANCOMPRESSION_INVALID )
+ return 0;
+ else
+ return nAsianCompression;
+}
+
+void ScDocument::SetAsianCompression(BYTE nNew)
+{
+ nAsianCompression = nNew;
+ if ( pEditEngine )
+ pEditEngine->SetAsianCompressionMode( nAsianCompression );
+ if ( pDrawLayer )
+ pDrawLayer->SetCharCompressType( nAsianCompression );
+}
+
+BOOL ScDocument::IsValidAsianKerning() const
+{
+ return ( nAsianKerning != SC_ASIANKERNING_INVALID );
+}
+
+BOOL ScDocument::GetAsianKerning() const
+{
+ if ( nAsianKerning == SC_ASIANKERNING_INVALID )
+ return FALSE;
+ else
+ return (BOOL)nAsianKerning;
+}
+
+void ScDocument::SetAsianKerning(BOOL bNew)
+{
+ nAsianKerning = (BYTE)bNew;
+ if ( pEditEngine )
+ pEditEngine->SetKernAsianPunctuation( (BOOL)nAsianKerning );
+ if ( pDrawLayer )
+ pDrawLayer->SetKernAsianPunctuation( (BOOL)nAsianKerning );
+}
+
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
new file mode 100644
index 000000000000..3b78ab5b172f
--- /dev/null
+++ b/sc/source/core/data/document.cxx
@@ -0,0 +1,5269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/boxitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/editeng.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/poolcach.hxx>
+#include <unotools/saveopt.hxx>
+#include <svl/zforlist.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <tools/tenccvt.hxx>
+
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+
+#include "document.hxx"
+#include "table.hxx"
+#include "attrib.hxx"
+#include "attarray.hxx"
+#include "markarr.hxx"
+#include "patattr.hxx"
+#include "rangenam.hxx"
+#include "poolhelp.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "globstr.hrc"
+#include "rechead.hxx"
+#include "dbcolect.hxx"
+#include "pivot.hxx"
+#include "chartlis.hxx"
+#include "rangelst.hxx"
+#include "markdata.hxx"
+#include "drwlayer.hxx"
+#include "conditio.hxx"
+#include "validat.hxx"
+#include "prnsave.hxx"
+#include "chgtrack.hxx"
+#include "sc.hrc"
+#include "scresid.hxx"
+#include "hints.hxx"
+#include "detdata.hxx"
+#include "cell.hxx"
+#include "dpobject.hxx"
+#include "detfunc.hxx" // for UpdateAllComments
+#include "scmod.hxx"
+#include "dociter.hxx"
+#include "progress.hxx"
+#include "autonamecache.hxx"
+#include "bcaslot.hxx"
+#include "postit.hxx"
+#include "externalrefmgr.hxx"
+#include "tabprotection.hxx"
+#include "clipparam.hxx"
+
+#include <map>
+#include <limits>
+
+namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::sheet::TablePageBreakData;
+using ::std::set;
+
+struct ScDefaultAttr
+{
+ const ScPatternAttr* pAttr;
+ SCROW nFirst;
+ SCSIZE nCount;
+ ScDefaultAttr(const ScPatternAttr* pPatAttr) : pAttr(pPatAttr), nFirst(0), nCount(0) {}
+};
+
+struct ScLessDefaultAttr
+{
+ sal_Bool operator() (const ScDefaultAttr& rValue1, const ScDefaultAttr& rValue2) const
+ {
+ return rValue1.pAttr < rValue2.pAttr;
+ }
+};
+
+typedef std::set<ScDefaultAttr, ScLessDefaultAttr> ScDefaultAttrSet;
+
+void ScDocument::MakeTable( SCTAB nTab,bool _bNeedsNameCheck )
+{
+ if ( ValidTab(nTab) && !pTab[nTab] )
+ {
+ String aString = ScGlobal::GetRscString(STR_TABLE_DEF); //"Tabelle"
+ aString += String::CreateFromInt32(nTab+1);
+ if ( _bNeedsNameCheck )
+ CreateValidTabName( aString ); // keine doppelten
+
+ pTab[nTab] = new ScTable(this, nTab, aString);
+ pTab[nTab]->SetLoadingMedium(bLoadingMedium);
+ ++nMaxTableNumber;
+ }
+}
+
+
+BOOL ScDocument::HasTable( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL ScDocument::GetName( SCTAB nTab, String& rName ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ {
+ pTab[nTab]->GetName( rName );
+ return TRUE;
+ }
+ rName.Erase();
+ return FALSE;
+}
+
+BOOL ScDocument::SetCodeName( SCTAB nTab, String& rName )
+{
+ if (VALIDTAB(nTab))
+ {
+ if (pTab[nTab])
+ {
+ pTab[nTab]->SetCodeName( rName );
+ return TRUE;
+ }
+ }
+ OSL_TRACE( "**** can't set code name %s", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return FALSE;
+}
+
+BOOL ScDocument::GetCodeName( SCTAB nTab, String& rName ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ {
+ pTab[nTab]->GetCodeName( rName );
+ return TRUE;
+ }
+ rName.Erase();
+ return FALSE;
+}
+
+
+BOOL ScDocument::GetTable( const String& rName, SCTAB& rTab ) const
+{
+ String aUpperName = rName;
+ ScGlobal::pCharClass->toUpper(aUpperName);
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ {
+ if ( pTab[i]->GetUpperName() == aUpperName )
+ {
+ rTab = i;
+ return TRUE;
+ }
+ }
+ rTab = 0;
+ return FALSE;
+}
+
+
+BOOL ScDocument::ValidTabName( const String& rName ) const
+{
+ xub_StrLen nLen = rName.Len();
+ if (!nLen)
+ return false;
+
+#if 1
+ // Restrict sheet names to what Excel accepts.
+ /* TODO: We may want to remove this restriction for full ODFF compliance.
+ * Merely loading and calculating ODF documents using these characters in
+ * sheet names is not affected by this, but all sheet name editing and
+ * copying functionality is, maybe falling back to "Sheet4" or similar. */
+ for (xub_StrLen i = 0; i < nLen; ++i)
+ {
+ const sal_Unicode c = rName.GetChar(i);
+ switch (c)
+ {
+ case ':':
+ case '\\':
+ case '/':
+ case '?':
+ case '*':
+ case '[':
+ case ']':
+ // these characters are not allowed to match XL's convention.
+ return false;
+ case '\'':
+ if (i == 0 || i == nLen - 1)
+ // single quote is not allowed at the first or last
+ // character position.
+ return false;
+ break;
+ }
+ }
+#endif
+
+ return true;
+}
+
+
+BOOL ScDocument::ValidNewTabName( const String& rName ) const
+{
+ BOOL bValid = ValidTabName(rName);
+ for (SCTAB i=0; (i<=MAXTAB) && bValid; i++)
+ if (pTab[i])
+ {
+ String aOldName;
+ pTab[i]->GetName(aOldName);
+ bValid = !ScGlobal::GetpTransliteration()->isEqual( rName, aOldName );
+ }
+ return bValid;
+}
+
+
+void ScDocument::CreateValidTabName(String& rName) const
+{
+ if ( !ValidTabName(rName) )
+ {
+ // neu erzeugen
+
+ const String aStrTable( ScResId(SCSTR_TABLE) );
+ BOOL bOk = FALSE;
+
+ // vorneweg testen, ob der Prefix als gueltig erkannt wird
+ // wenn nicht, nur doppelte vermeiden
+ BOOL bPrefix = ValidTabName( aStrTable );
+ DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
+ SCTAB nDummy;
+
+ SCTAB nLoops = 0; // "zur Sicherheit"
+ for ( SCTAB i = nMaxTableNumber+1; !bOk && nLoops <= MAXTAB; i++ )
+ {
+ rName = aStrTable;
+ rName += String::CreateFromInt32(i);
+ if (bPrefix)
+ bOk = ValidNewTabName( rName );
+ else
+ bOk = !GetTable( rName, nDummy );
+ ++nLoops;
+ }
+
+ DBG_ASSERT(bOk, "kein gueltiger Tabellenname gefunden");
+ if ( !bOk )
+ rName = aStrTable;
+ }
+ else
+ {
+ // uebergebenen Namen ueberpruefen
+
+ if ( !ValidNewTabName(rName) )
+ {
+ SCTAB i = 1;
+ String aName;
+ do
+ {
+ i++;
+ aName = rName;
+ aName += '_';
+ aName += String::CreateFromInt32(static_cast<sal_Int32>(i));
+ }
+ while (!ValidNewTabName(aName) && (i < MAXTAB+1));
+ rName = aName;
+ }
+ }
+}
+
+
+BOOL ScDocument::InsertTab( SCTAB nPos, const String& rName,
+ BOOL bExternalDocument )
+{
+ SCTAB nTabCount = GetTableCount();
+ BOOL bValid = ValidTab(nTabCount);
+ if ( !bExternalDocument ) // sonst rName == "'Doc'!Tab", vorher pruefen
+ bValid = (bValid && ValidNewTabName(rName));
+ if (bValid)
+ {
+ if (nPos == SC_TAB_APPEND || nPos == nTabCount)
+ {
+ pTab[nTabCount] = new ScTable(this, nTabCount, rName);
+ pTab[nTabCount]->SetCodeName( rName );
+ ++nMaxTableNumber;
+ if ( bExternalDocument )
+ pTab[nTabCount]->SetVisible( FALSE );
+ }
+ else
+ {
+ if (VALIDTAB(nPos) && (nPos < nTabCount))
+ {
+ ScRange aRange( 0,0,nPos, MAXCOL,MAXROW,MAXTAB );
+ xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
+ xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
+ pRangeName->UpdateTabRef( nPos, 1 );
+ pDBCollection->UpdateReference(
+ URM_INSDEL, 0,0,nPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
+ if (pDPCollection)
+ pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
+ if (pDetOpList)
+ pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
+ UpdateChartRef( URM_INSDEL, 0,0,nPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
+ UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
+ if ( pUnoBroadcaster )
+ pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
+
+ SCTAB i;
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateInsertTab(nPos);
+
+ for (i = nTabCount; i > nPos; i--)
+ {
+ pTab[i] = pTab[i - 1];
+ }
+
+ pTab[nPos] = new ScTable(this, nPos, rName);
+ pTab[nPos]->SetCodeName( rName );
+ ++nMaxTableNumber;
+
+ // UpdateBroadcastAreas must be called between UpdateInsertTab,
+ // which ends listening, and StartAllListeners, to not modify
+ // areas that are to be inserted by starting listeners.
+ UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,1);
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateCompile();
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartAllListeners();
+
+ // update conditional formats after table is inserted
+ if ( pCondFormList )
+ pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
+ if ( pValidationList )
+ pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
+ // #81844# sheet names of references are not valid until sheet is inserted
+ if ( pChartListenerCollection )
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+
+ SetDirty();
+ bValid = TRUE;
+ }
+ else
+ bValid = FALSE;
+ }
+ }
+ return bValid;
+}
+
+
+BOOL ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc )
+{
+ BOOL bValid = FALSE;
+ if (VALIDTAB(nTab))
+ {
+ if (pTab[nTab])
+ {
+ SCTAB nTabCount = GetTableCount();
+ if (nTabCount > 1)
+ {
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
+ DelBroadcastAreasInRange( aRange );
+
+ // #i8180# remove database ranges etc. that are on the deleted tab
+ // (restored in undo with ScRefUndoData)
+
+ xColNameRanges->DeleteOnTab( nTab );
+ xRowNameRanges->DeleteOnTab( nTab );
+ pDBCollection->DeleteOnTab( nTab );
+ if (pDPCollection)
+ pDPCollection->DeleteOnTab( nTab );
+ if (pDetOpList)
+ pDetOpList->DeleteOnTab( nTab );
+ DeleteAreaLinksOnTab( nTab );
+
+ // normal reference update
+
+ aRange.aEnd.SetTab( MAXTAB );
+ xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 );
+ xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 );
+ pRangeName->UpdateTabRef( nTab, 2 );
+ pDBCollection->UpdateReference(
+ URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1 );
+ if (pDPCollection)
+ pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,-1 );
+ if (pDetOpList)
+ pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,-1 );
+ UpdateChartRef( URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1 );
+ UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,-1 );
+ if ( pCondFormList )
+ pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,-1 );
+ if ( pValidationList )
+ pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,-1 );
+ if ( pUnoBroadcaster )
+ pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,-1 ) );
+
+ SCTAB i;
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateDeleteTab(nTab,FALSE,
+ pRefUndoDoc ? pRefUndoDoc->pTab[i] : 0);
+ delete pTab[nTab];
+ for (i=nTab + 1; i < nTabCount; i++)
+ pTab[i - 1] = pTab[i];
+ pTab[nTabCount - 1] = NULL;
+ --nMaxTableNumber;
+ // UpdateBroadcastAreas must be called between UpdateDeleteTab,
+ // which ends listening, and StartAllListeners, to not modify
+ // areas that are to be inserted by starting listeners.
+ UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,-1);
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->UpdateCompile();
+ // Excel-Filter loescht einige Tables waehrend des Ladens,
+ // Listener werden erst nach dem Laden aufgesetzt
+ if ( !bInsertingFromOtherDoc )
+ {
+ for (i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartAllListeners();
+ SetDirty();
+ }
+ // #81844# sheet names of references are not valid until sheet is deleted
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+
+ SetAutoCalc( bOldAutoCalc );
+ bValid = TRUE;
+ }
+ }
+ }
+ return bValid;
+}
+
+
+BOOL ScDocument::RenameTab( SCTAB nTab, const String& rName, BOOL /* bUpdateRef */,
+ BOOL bExternalDocument )
+{
+ BOOL bValid = FALSE;
+ SCTAB i;
+ if VALIDTAB(nTab)
+ if (pTab[nTab])
+ {
+ if ( bExternalDocument )
+ bValid = TRUE; // zusammengesetzter Name
+ else
+ bValid = ValidTabName(rName);
+ for (i=0; (i<=MAXTAB) && bValid; i++)
+ if (pTab[i] && (i != nTab))
+ {
+ String aOldName;
+ pTab[i]->GetName(aOldName);
+ bValid = !ScGlobal::GetpTransliteration()->isEqual( rName, aOldName );
+ }
+ if (bValid)
+ {
+ // #i75258# update charts before renaming, so they can get their live data objects.
+ // Once the charts are live, the sheet can be renamed without problems.
+ if ( pChartListenerCollection )
+ pChartListenerCollection->UpdateChartsContainingTab( nTab );
+ pTab[nTab]->SetName(rName);
+
+ // If formulas refer to the renamed sheet, the TokenArray remains valid,
+ // but the XML stream must be re-generated.
+ for (i=0; i<=MAXTAB; ++i)
+ if (pTab[i] && pTab[i]->IsStreamValid())
+ pTab[i]->SetStreamValid( FALSE );
+ }
+ }
+ return bValid;
+}
+
+
+void ScDocument::SetVisible( SCTAB nTab, BOOL bVisible )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->SetVisible(bVisible);
+}
+
+
+BOOL ScDocument::IsVisible( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->IsVisible();
+
+ return FALSE;
+}
+
+
+BOOL ScDocument::IsStreamValid( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->IsStreamValid();
+
+ return FALSE;
+}
+
+
+void ScDocument::SetStreamValid( SCTAB nTab, BOOL bSet, BOOL bIgnoreLock )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetStreamValid( bSet, bIgnoreLock );
+}
+
+
+void ScDocument::LockStreamValid( bool bLock )
+{
+ mbStreamValidLocked = bLock;
+}
+
+
+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] )
+ {
+ if ( bImportingXML )
+ {
+ // #i57869# only set the LoadingRTL flag, the real setting (including mirroring)
+ // is applied in SetImportingXML(FALSE). This is so the shapes can be loaded in
+ // normal LTR mode.
+
+ pTab[nTab]->SetLoadingRTL( bRTL );
+ return;
+ }
+
+ pTab[nTab]->SetLayoutRTL( bRTL ); // only sets the flag
+ pTab[nTab]->SetDrawPageSize();
+
+ // mirror existing objects:
+
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ // objects with ScDrawObjData are re-positioned in SetPageSize,
+ // don't mirror again
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject );
+ if ( !pData )
+ pDrawLayer->MirrorRTL( pObject );
+
+ pObject->SetContextWritingMode( bRTL ? WritingMode2::RL_TB : WritingMode2::LR_TB );
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+}
+
+
+BOOL ScDocument::IsLayoutRTL( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->IsLayoutRTL();
+
+ return FALSE;
+}
+
+
+BOOL ScDocument::IsNegativePage( SCTAB nTab ) const
+{
+ // Negative page area is always used for RTL layout.
+ // The separate method is used to find all RTL handling of drawing objects.
+ return IsLayoutRTL( nTab );
+}
+
+
+/* ----------------------------------------------------------------------------
+ benutzten Bereich suchen:
+
+ GetCellArea - nur Daten
+ GetTableArea - Daten / Attribute
+ GetPrintArea - beruecksichtigt auch Zeichenobjekte,
+ streicht Attribute bis ganz rechts / unten
+---------------------------------------------------------------------------- */
+
+
+BOOL ScDocument::GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->GetCellArea( rEndCol, rEndRow );
+
+ rEndCol = 0;
+ rEndRow = 0;
+ return FALSE;
+}
+
+
+BOOL ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->GetTableArea( rEndCol, rEndRow );
+
+ rEndCol = 0;
+ rEndRow = 0;
+ return FALSE;
+}
+
+bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ pTab[nTab]->GetFirstDataPos(nCol1, nRow1);
+ pTab[nTab]->GetLastDataPos(nCol2, nRow2);
+
+ if (nCol1 > nCol2 || nRow1 > nRow2)
+ // invalid range.
+ return false;
+
+ // Make sure the area only shrinks, and doesn't grow.
+ if (rStartCol < nCol1)
+ rStartCol = nCol1;
+ if (nCol2 < rEndCol)
+ rEndCol = nCol2;
+ if (rStartRow < nRow1)
+ rStartRow = nRow1;
+ if (nRow2 < rEndRow)
+ rEndRow = nRow2;
+
+ if (rStartCol > rEndCol || rStartRow > rEndRow)
+ // invalid range.
+ return false;
+
+ return true; // success!
+}
+
+bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStartCol,
+ SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ o_bShrunk = false;
+ return false;
+ }
+ return pTab[nTab]->ShrinkToUsedDataArea( o_bShrunk, rStartCol, rStartRow, rEndCol, rEndRow, bColumnsOnly);
+}
+
+// zusammenhaengender Bereich
+
+void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld, bOnlyDown );
+}
+
+
+void ScDocument::LimitChartArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->LimitChartArea( rStartCol, rStartRow, rEndCol, rEndRow );
+}
+
+
+void ScDocument::LimitChartIfAll( ScRangeListRef& rRangeList )
+{
+ ScRangeListRef aNew = new ScRangeList;
+ if (rRangeList.Is())
+ {
+ ULONG nCount = rRangeList->Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange(*rRangeList->GetObject( i ));
+ if ( ( aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MAXCOL ) ||
+ ( aRange.aStart.Row() == 0 && aRange.aEnd.Row() == MAXROW ) )
+ {
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ SCTAB nTab = aRange.aStart.Tab();
+ if (pTab[nTab])
+ pTab[nTab]->LimitChartArea(nStartCol, nStartRow, nEndCol, nEndRow);
+ aRange.aStart.SetCol( nStartCol );
+ aRange.aStart.SetRow( nStartRow );
+ aRange.aEnd.SetCol( nEndCol );
+ aRange.aEnd.SetRow( nEndRow );
+ }
+ aNew->Append(aRange);
+ }
+ }
+ else
+ {
+ DBG_ERROR("LimitChartIfAll: Ref==0");
+ }
+ rRangeList = aNew;
+}
+
+
+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();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+ SCSIZE nSize = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
+
+ BOOL bTest = TRUE;
+ for (SCTAB i=nStartTab; i<=nEndTab && bTest; i++)
+ if (pTab[i])
+ bTest &= pTab[i]->TestInsertRow( nStartCol, nEndCol, nSize );
+
+ return bTest;
+}
+
+
+BOOL ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
+ SCCOL nEndCol, SCTAB nEndTab,
+ 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] && (!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
+
+ // 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] && (!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] && (!pTabMark || pTabMark->GetTableSelect(i)))
+ pTab[i]->UpdateDrawRef( URM_INSDEL,
+ nStartCol, nStartRow, nStartTab, nEndCol, MAXROW, nEndTab,
+ 0, static_cast<SCsROW>(nSize), 0 );
+
+ if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
+ { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
+ // ein neues Listening faellig, bisherige Listener wurden in
+ // FormulaCell UpdateReference abgehaengt
+ StartAllListeners();
+ }
+ else
+ { // Listeners have been removed in UpdateReference
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartNeededListeners();
+ // #69592# at least all cells using range names pointing relative
+ // to the moved range must recalculate
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->SetRelNameDirty();
+ }
+ bRet = TRUE;
+ }
+ SetAutoCalc( bOldAutoCalc );
+ if ( bRet )
+ pChartListenerCollection->UpdateDirtyCharts();
+ return bRet;
+}
+
+
+BOOL ScDocument::InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc )
+{
+ return InsertRow( rRange.aStart.Col(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Tab(),
+ rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1),
+ pRefUndoDoc );
+}
+
+
+void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
+ SCCOL nEndCol, SCTAB nEndTab,
+ SCROW nStartRow, SCSIZE nSize,
+ 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
+
+ // handle chunks of consecutive selected sheets together
+ SCTAB nTabRangeStart = nStartTab;
+ SCTAB nTabRangeEnd = nEndTab;
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ 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 ) ) );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
+ if ( ValidRow(nStartRow+nSize) )
+ {
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nTabRangeStart,
+ nEndCol, MAXROW, nTabRangeEnd,
+ 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc, TRUE, false );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+ }
+
+ if (pUndoOutline)
+ *pUndoOutline = FALSE;
+
+ for ( i = nStartTab; i <= nEndTab; i++)
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
+ pTab[i]->DeleteRow( nStartCol, nEndCol, nStartRow, nSize, pUndoOutline );
+
+ if ( ValidRow(nStartRow+nSize) )
+ { // Listeners have been removed in UpdateReference
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartNeededListeners();
+ // #69592# at least all cells using range names pointing relative to
+ // the moved range must recalculate
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->SetRelNameDirty();
+ }
+
+ SetAutoCalc( bOldAutoCalc );
+ pChartListenerCollection->UpdateDirtyCharts();
+}
+
+
+void ScDocument::DeleteRow( const ScRange& rRange, ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
+{
+ DeleteRow( rRange.aStart.Col(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Tab(),
+ rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1),
+ pRefUndoDoc, pUndoOutline );
+}
+
+
+BOOL ScDocument::CanInsertCol( const ScRange& rRange ) const
+{
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+ SCSIZE nSize = static_cast<SCSIZE>(nEndCol - nStartCol + 1);
+
+ BOOL bTest = TRUE;
+ for (SCTAB i=nStartTab; i<=nEndTab && bTest; i++)
+ if (pTab[i])
+ bTest &= pTab[i]->TestInsertCol( nStartRow, nEndRow, nSize );
+
+ return bTest;
+}
+
+
+BOOL ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
+ SCROW nEndRow, SCTAB nEndTab,
+ 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] && (!pTabMark || pTabMark->GetTableSelect(i)))
+ bTest &= pTab[i]->TestInsertCol( nStartRow, nEndRow, nSize );
+ if (bTest)
+ {
+ // 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, TRUE, false );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
+ for (i=nStartTab; i<=nEndTab; i++)
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
+ pTab[i]->InsertCol( nStartCol, nStartRow, nEndRow, nSize );
+
+ if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
+ { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
+ // ein neues Listening faellig, bisherige Listener wurden in
+ // FormulaCell UpdateReference abgehaengt
+ StartAllListeners();
+ }
+ else
+ { // Listeners have been removed in UpdateReference
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartNeededListeners();
+ // #69592# at least all cells using range names pointing relative
+ // to the moved range must recalculate
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->SetRelNameDirty();
+ }
+ bRet = TRUE;
+ }
+ SetAutoCalc( bOldAutoCalc );
+ if ( bRet )
+ pChartListenerCollection->UpdateDirtyCharts();
+ return bRet;
+}
+
+
+BOOL ScDocument::InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc )
+{
+ return InsertCol( rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Row(), rRange.aEnd.Tab(),
+ rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1),
+ pRefUndoDoc );
+}
+
+
+void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab,
+ SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
+ 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
+
+ // handle chunks of consecutive selected sheets together
+ SCTAB nTabRangeStart = nStartTab;
+ SCTAB nTabRangeEnd = nEndTab;
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ 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 ) ) );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
+ if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
+ {
+ 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, TRUE, false );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+ }
+
+ if (pUndoOutline)
+ *pUndoOutline = FALSE;
+
+ for ( i = nStartTab; i <= nEndTab; 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)) )
+ { // Listeners have been removed in UpdateReference
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StartNeededListeners();
+ // #69592# at least all cells using range names pointing relative to
+ // the moved range must recalculate
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->SetRelNameDirty();
+ }
+
+ SetAutoCalc( bOldAutoCalc );
+ pChartListenerCollection->UpdateDirtyCharts();
+}
+
+
+void ScDocument::DeleteCol( const ScRange& rRange, ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
+{
+ DeleteCol( rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Row(), rRange.aEnd.Tab(),
+ rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1),
+ pRefUndoDoc, pUndoOutline );
+}
+
+
+// fuer Area-Links: Zellen einuegen/loeschen, wenn sich der Bereich veraendert
+// (ohne Paint)
+
+
+void lcl_GetInsDelRanges( const ScRange& rOld, const ScRange& rNew,
+ ScRange& rColRange, BOOL& rInsCol, BOOL& rDelCol,
+ ScRange& rRowRange, BOOL& rInsRow, BOOL& rDelRow )
+{
+ DBG_ASSERT( rOld.aStart == rNew.aStart, "FitBlock: Anfang unterschiedlich" );
+
+ rInsCol = rDelCol = rInsRow = rDelRow = FALSE;
+
+ SCCOL nStartX = rOld.aStart.Col();
+ SCROW nStartY = rOld.aStart.Row();
+ SCCOL nOldEndX = rOld.aEnd.Col();
+ SCROW nOldEndY = rOld.aEnd.Row();
+ SCCOL nNewEndX = rNew.aEnd.Col();
+ SCROW nNewEndY = rNew.aEnd.Row();
+ SCTAB nTab = rOld.aStart.Tab();
+
+ // wenn es mehr Zeilen werden, werden Spalten auf der alten Hoehe eingefuegt/geloescht
+ BOOL bGrowY = ( nNewEndY > nOldEndY );
+ SCROW nColEndY = bGrowY ? nOldEndY : nNewEndY;
+ SCCOL nRowEndX = bGrowY ? nNewEndX : nOldEndX;
+
+ // Spalten
+
+ if ( nNewEndX > nOldEndX ) // Spalten einfuegen
+ {
+ rColRange = ScRange( nOldEndX+1, nStartY, nTab, nNewEndX, nColEndY, nTab );
+ rInsCol = TRUE;
+ }
+ else if ( nNewEndX < nOldEndX ) // Spalten loeschen
+ {
+ rColRange = ScRange( nNewEndX+1, nStartY, nTab, nOldEndX, nColEndY, nTab );
+ rDelCol = TRUE;
+ }
+
+ // Zeilen
+
+ if ( nNewEndY > nOldEndY ) // Zeilen einfuegen
+ {
+ rRowRange = ScRange( nStartX, nOldEndY+1, nTab, nRowEndX, nNewEndY, nTab );
+ rInsRow = TRUE;
+ }
+ else if ( nNewEndY < nOldEndY ) // Zeilen loeschen
+ {
+ rRowRange = ScRange( nStartX, nNewEndY+1, nTab, nRowEndX, nOldEndY, nTab );
+ rDelRow = TRUE;
+ }
+}
+
+
+BOOL ScDocument::HasPartOfMerged( const ScRange& rRange )
+{
+ BOOL bPart = FALSE;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ SCCOL nStartX = rRange.aStart.Col();
+ SCROW nStartY = rRange.aStart.Row();
+ SCCOL nEndX = rRange.aEnd.Col();
+ SCROW nEndY = rRange.aEnd.Row();
+
+ if (HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
+ ExtendOverlapped( nStartX, nStartY, nEndX, nEndY, nTab );
+
+ bPart = ( nStartX != rRange.aStart.Col() || nEndX != rRange.aEnd.Col() ||
+ nStartY != rRange.aStart.Row() || nEndY != rRange.aEnd.Row() );
+ }
+ return bPart;
+}
+
+
+BOOL ScDocument::CanFitBlock( const ScRange& rOld, const ScRange& rNew )
+{
+ if ( rOld == rNew )
+ return TRUE;
+
+ BOOL bOk = TRUE;
+ BOOL bInsCol,bDelCol,bInsRow,bDelRow;
+ ScRange aColRange,aRowRange;
+ lcl_GetInsDelRanges( rOld, rNew, aColRange,bInsCol,bDelCol, aRowRange,bInsRow,bDelRow );
+
+ if ( bInsCol && !CanInsertCol( aColRange ) ) // Zellen am Rand ?
+ bOk = FALSE;
+ if ( bInsRow && !CanInsertRow( aRowRange ) ) // Zellen am Rand ?
+ bOk = FALSE;
+
+ if ( bInsCol || bDelCol )
+ {
+ aColRange.aEnd.SetCol(MAXCOL);
+ if ( HasPartOfMerged(aColRange) )
+ bOk = FALSE;
+ }
+ if ( bInsRow || bDelRow )
+ {
+ aRowRange.aEnd.SetRow(MAXROW);
+ if ( HasPartOfMerged(aRowRange) )
+ bOk = FALSE;
+ }
+
+ return bOk;
+}
+
+
+void ScDocument::FitBlock( const ScRange& rOld, const ScRange& rNew, BOOL bClear )
+{
+ if (bClear)
+ DeleteAreaTab( rOld, IDF_ALL );
+
+ BOOL bInsCol,bDelCol,bInsRow,bDelRow;
+ ScRange aColRange,aRowRange;
+ lcl_GetInsDelRanges( rOld, rNew, aColRange,bInsCol,bDelCol, aRowRange,bInsRow,bDelRow );
+
+ if ( bInsCol )
+ InsertCol( aColRange ); // Spalten zuerst einfuegen
+ if ( bInsRow )
+ InsertRow( aRowRange );
+
+ if ( bDelRow )
+ DeleteRow( aRowRange ); // Zeilen zuerst loeschen
+ if ( bDelCol )
+ DeleteCol( aColRange );
+
+ // Referenzen um eingefuegte Zeilen erweitern
+
+ if ( bInsCol || bInsRow )
+ {
+ ScRange aGrowSource = rOld;
+ aGrowSource.aEnd.SetCol(Min( rOld.aEnd.Col(), rNew.aEnd.Col() ));
+ aGrowSource.aEnd.SetRow(Min( rOld.aEnd.Row(), rNew.aEnd.Row() ));
+ SCCOL nGrowX = bInsCol ? ( rNew.aEnd.Col() - rOld.aEnd.Col() ) : 0;
+ SCROW nGrowY = bInsRow ? ( rNew.aEnd.Row() - rOld.aEnd.Row() ) : 0;
+ UpdateGrow( aGrowSource, nGrowX, nGrowY );
+ }
+}
+
+
+void ScDocument::DeleteArea(SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark, USHORT nDelFlag)
+{
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCTAB i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if ( rMark.GetTableSelect(i) || bIsUndo )
+ pTab[i]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag);
+ SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::DeleteAreaTab(SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ SCTAB nTab, USHORT nDelFlag)
+{
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ {
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ pTab[nTab]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag);
+ SetAutoCalc( bOldAutoCalc );
+ }
+}
+
+
+void ScDocument::DeleteAreaTab( const ScRange& rRange, USHORT nDelFlag )
+{
+ for ( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); nTab++ )
+ DeleteAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(),
+ nTab, nDelFlag );
+}
+
+
+void ScDocument::InitUndoSelected( ScDocument* pSrcDoc, const ScMarkData& rTabSelection,
+ BOOL bColInfo, BOOL bRowInfo )
+{
+ if (bIsUndo)
+ {
+ Clear();
+
+ xPoolHelper = pSrcDoc->xPoolHelper;
+
+ String aString;
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if ( rTabSelection.GetTableSelect( nTab ) )
+ {
+ pTab[nTab] = new ScTable(this, nTab, aString, bColInfo, bRowInfo);
+ nMaxTableNumber = nTab + 1;
+ }
+ }
+ else
+ {
+ DBG_ERROR("InitUndo");
+ }
+}
+
+
+void ScDocument::InitUndo( ScDocument* pSrcDoc, SCTAB nTab1, SCTAB nTab2,
+ BOOL bColInfo, BOOL bRowInfo )
+{
+ if (bIsUndo)
+ {
+ Clear();
+
+ xPoolHelper = pSrcDoc->xPoolHelper;
+
+ String aString;
+ for (SCTAB nTab = nTab1; nTab <= nTab2; nTab++)
+ pTab[nTab] = new ScTable(this, nTab, aString, bColInfo, bRowInfo);
+
+ nMaxTableNumber = nTab2 + 1;
+ }
+ else
+ {
+ DBG_ERROR("InitUndo");
+ }
+}
+
+
+void ScDocument::AddUndoTab( SCTAB nTab1, SCTAB nTab2, BOOL bColInfo, BOOL bRowInfo )
+{
+ if (bIsUndo)
+ {
+ String aString;
+ for (SCTAB nTab = nTab1; nTab <= nTab2; nTab++)
+ if (!pTab[nTab])
+ pTab[nTab] = new ScTable(this, nTab, aString, bColInfo, bRowInfo);
+
+ if ( nMaxTableNumber <= nTab2 )
+ nMaxTableNumber = nTab2 + 1;
+ }
+ else
+ {
+ DBG_ERROR("InitUndo");
+ }
+}
+
+
+void ScDocument::SetCutMode( BOOL bVal )
+{
+ if (bIsClip)
+ GetClipParam().mbCutMode = bVal;
+ else
+ {
+ DBG_ERROR("SetCutMode without bIsClip");
+ }
+}
+
+
+BOOL ScDocument::IsCutMode()
+{
+ if (bIsClip)
+ return GetClipParam().mbCutMode;
+ else
+ {
+ DBG_ERROR("IsCutMode ohne bIsClip");
+ return FALSE;
+ }
+}
+
+
+void ScDocument::CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ USHORT nFlags, BOOL bOnlyMarked, ScDocument* pDestDoc,
+ const ScMarkData* pMarks, BOOL bColRowFlags )
+{
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ PutInOrder( nTab1, nTab2 );
+ if( !pDestDoc->aDocName.Len() )
+ pDestDoc->aDocName = aDocName;
+ if (VALIDTAB(nTab1) && VALIDTAB(nTab2))
+ {
+ BOOL bOldAutoCalc = pDestDoc->GetAutoCalc();
+ pDestDoc->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCTAB i = nTab1; i <= nTab2; i++)
+ {
+ if (pTab[i] && pDestDoc->pTab[i])
+ pTab[i]->CopyToTable( nCol1, nRow1, nCol2, nRow2, nFlags,
+ bOnlyMarked, pDestDoc->pTab[i], pMarks,
+ FALSE, bColRowFlags );
+ }
+ pDestDoc->SetAutoCalc( bOldAutoCalc );
+ }
+}
+
+
+void ScDocument::UndoToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ USHORT nFlags, BOOL bOnlyMarked, ScDocument* pDestDoc,
+ const ScMarkData* pMarks)
+{
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ PutInOrder( nTab1, nTab2 );
+ if (VALIDTAB(nTab1) && VALIDTAB(nTab2))
+ {
+ BOOL bOldAutoCalc = pDestDoc->GetAutoCalc();
+ pDestDoc->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ if (nTab1 > 0)
+ CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, FALSE, pDestDoc, pMarks );
+
+ for (SCTAB i = nTab1; i <= nTab2; i++)
+ {
+ if (pTab[i] && pDestDoc->pTab[i])
+ pTab[i]->UndoToTable(nCol1, nRow1, nCol2, nRow2, nFlags,
+ bOnlyMarked, pDestDoc->pTab[i], pMarks);
+ }
+
+ if (nTab2 < MAXTAB)
+ CopyToDocument( 0,0,nTab2+1, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA, FALSE, pDestDoc, pMarks );
+ pDestDoc->SetAutoCalc( bOldAutoCalc );
+ }
+}
+
+
+void ScDocument::CopyToDocument(const ScRange& rRange,
+ USHORT nFlags, BOOL bOnlyMarked, ScDocument* pDestDoc,
+ const ScMarkData* pMarks, BOOL bColRowFlags)
+{
+ ScRange aNewRange = rRange;
+ aNewRange.Justify();
+
+ if( !pDestDoc->aDocName.Len() )
+ pDestDoc->aDocName = aDocName;
+ BOOL bOldAutoCalc = pDestDoc->GetAutoCalc();
+ pDestDoc->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCTAB i = aNewRange.aStart.Tab(); i <= aNewRange.aEnd.Tab(); i++)
+ if (pTab[i] && pDestDoc->pTab[i])
+ pTab[i]->CopyToTable(aNewRange.aStart.Col(), aNewRange.aStart.Row(),
+ aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
+ nFlags, bOnlyMarked, pDestDoc->pTab[i],
+ pMarks, FALSE, bColRowFlags);
+ pDestDoc->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::UndoToDocument(const ScRange& rRange,
+ USHORT nFlags, BOOL bOnlyMarked, ScDocument* pDestDoc,
+ const ScMarkData* pMarks)
+{
+ ScRange aNewRange = rRange;
+ aNewRange.Justify();
+ SCTAB nTab1 = aNewRange.aStart.Tab();
+ SCTAB nTab2 = aNewRange.aEnd.Tab();
+
+ BOOL bOldAutoCalc = pDestDoc->GetAutoCalc();
+ pDestDoc->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ if (nTab1 > 0)
+ CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, FALSE, pDestDoc, pMarks );
+
+ for (SCTAB i = nTab1; i <= nTab2; i++)
+ {
+ if (pTab[i] && pDestDoc->pTab[i])
+ pTab[i]->UndoToTable(aNewRange.aStart.Col(), aNewRange.aStart.Row(),
+ aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
+ nFlags, bOnlyMarked, pDestDoc->pTab[i], pMarks);
+ }
+
+ if (nTab2 < MAXTAB)
+ CopyToDocument( 0,0,nTab2+1, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA, FALSE, pDestDoc, pMarks );
+ pDestDoc->SetAutoCalc( bOldAutoCalc );
+}
+
+void ScDocument::CopyToClip(const ScClipParam& rClipParam,
+ ScDocument* pClipDoc, const ScMarkData* pMarks,
+ bool bAllTabs, bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions)
+{
+ DBG_ASSERT( bAllTabs || pMarks, "CopyToClip: ScMarkData fehlt" );
+
+ if (bIsClip)
+ return;
+
+ if (!pClipDoc)
+ {
+ DBG_ERROR("CopyToClip: no ClipDoc");
+ pClipDoc = SC_MOD()->GetClipDoc();
+ }
+
+ pClipDoc->aDocName = aDocName;
+ pClipDoc->SetClipParam(rClipParam);
+ pClipDoc->ResetClip(this, pMarks);
+
+ ScRange aClipRange = rClipParam.getWholeRange();
+ CopyRangeNamesToClip(pClipDoc, aClipRange, pMarks, bAllTabs);
+
+ for (SCTAB i = 0; i <= MAXTAB; ++i)
+ {
+ if (!pTab[i] || !pClipDoc->pTab[i])
+ continue;
+
+ if (pMarks && !pMarks->GetTableSelect(i))
+ continue;
+
+ pTab[i]->CopyToClip(rClipParam.maRanges, pClipDoc->pTab[i], bKeepScenarioFlags, bCloneNoteCaptions);
+
+ if (pDrawLayer && bIncludeObjects)
+ {
+ // also copy drawing objects
+ Rectangle aObjRect = GetMMRect(
+ aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i);
+ pDrawLayer->CopyToClip(pClipDoc, i, aObjRect);
+ }
+ }
+
+ // Make sure to mark overlapped cells.
+ pClipDoc->ExtendMerge(aClipRange, true);
+}
+
+void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ SCTAB nTab, ScDocument* pClipDoc)
+{
+ if (!bIsClip)
+ {
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ if (!pClipDoc)
+ {
+ DBG_ERROR("CopyTabToClip: no ClipDoc");
+ pClipDoc = SC_MOD()->GetClipDoc();
+ }
+
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ pClipDoc->aDocName = aDocName;
+ rClipParam.maRanges.RemoveAll();
+ rClipParam.maRanges.Append(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0));
+ pClipDoc->ResetClip( this, nTab );
+
+ if (pTab[nTab] && pClipDoc->pTab[nTab])
+ pTab[nTab]->CopyToClip(nCol1, nRow1, nCol2, nRow2, pClipDoc->pTab[nTab], FALSE, TRUE);
+
+ pClipDoc->GetClipParam().mbCutMode = false;
+ }
+}
+
+
+void ScDocument::TransposeClip( ScDocument* pTransClip, USHORT nFlags, BOOL bAsLink )
+{
+ DBG_ASSERT( bIsClip && pTransClip && pTransClip->bIsClip,
+ "TransposeClip mit falschem Dokument" );
+
+ // initialisieren
+ // -> pTransClip muss vor dem Original-Dokument geloescht werden!
+
+ pTransClip->ResetClip(this, (ScMarkData*)NULL); // alle
+
+ // Bereiche uebernehmen
+
+ pTransClip->pRangeName->FreeAll();
+ for (USHORT i = 0; i < pRangeName->GetCount(); i++) //! DB-Bereiche Pivot-Bereiche auch !!!
+ {
+ USHORT nIndex = ((ScRangeData*)((*pRangeName)[i]))->GetIndex();
+ ScRangeData* pData = new ScRangeData(*((*pRangeName)[i]));
+ if (!pTransClip->pRangeName->Insert(pData))
+ delete pData;
+ else
+ pData->SetIndex(nIndex);
+ }
+
+ // Daten
+
+ ScRange aClipRange = GetClipParam().getWholeRange();
+ if ( ValidRow(aClipRange.aEnd.Row()-aClipRange.aStart.Row()) )
+ {
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ {
+ DBG_ASSERT( pTransClip->pTab[i], "TransposeClip: Tabelle nicht da" );
+ pTab[i]->TransposeClip( aClipRange.aStart.Col(), aClipRange.aStart.Row(),
+ aClipRange.aEnd.Col(), aClipRange.aEnd.Row(),
+ pTransClip->pTab[i], nFlags, bAsLink );
+
+ if ( pDrawLayer && ( nFlags & IDF_OBJECTS ) )
+ {
+ // Drawing objects are copied to the new area without transposing.
+ // CopyFromClip is used to adjust the objects to the transposed block's
+ // cell range area.
+ // (pDrawLayer in the original clipboard document is set only if there
+ // are drawing objects to copy)
+
+ pTransClip->InitDrawLayer();
+ Rectangle aSourceRect = GetMMRect( aClipRange.aStart.Col(), aClipRange.aStart.Row(),
+ aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i );
+ Rectangle aDestRect = pTransClip->GetMMRect( 0, 0,
+ static_cast<SCCOL>(aClipRange.aEnd.Row() - aClipRange.aStart.Row()),
+ static_cast<SCROW>(aClipRange.aEnd.Col() - aClipRange.aStart.Col()), i );
+ pTransClip->pDrawLayer->CopyFromClip( pDrawLayer, i, aSourceRect, ScAddress(0,0,i), aDestRect );
+ }
+ }
+
+ pTransClip->SetClipParam(GetClipParam());
+ pTransClip->GetClipParam().transpose();
+ }
+ else
+ {
+ DBG_ERROR("TransposeClip: zu gross");
+ }
+
+ // Dies passiert erst beim Einfuegen...
+
+ GetClipParam().mbCutMode = false;
+}
+
+void ScDocument::CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, const ScMarkData* pMarks, bool bAllTabs)
+{
+ std::set<USHORT> aUsedNames; // indexes of named ranges that are used in the copied cells
+ for (SCTAB i = 0; i <= MAXTAB; ++i)
+ if (pTab[i] && pClipDoc->pTab[i])
+ if ( bAllTabs || !pMarks || pMarks->GetTableSelect(i) )
+ pTab[i]->FindRangeNamesInUse(
+ rClipRange.aStart.Col(), rClipRange.aStart.Row(),
+ rClipRange.aEnd.Col(), rClipRange.aEnd.Row(), aUsedNames);
+
+ pClipDoc->pRangeName->FreeAll();
+ for (USHORT i = 0; i < pRangeName->GetCount(); i++) //! DB-Bereiche Pivot-Bereiche auch !!!
+ {
+ USHORT nIndex = ((ScRangeData*)((*pRangeName)[i]))->GetIndex();
+ bool bInUse = ( aUsedNames.find(nIndex) != aUsedNames.end() );
+ if (bInUse)
+ {
+ ScRangeData* pData = new ScRangeData(*((*pRangeName)[i]));
+ if (!pClipDoc->pRangeName->Insert(pData))
+ delete pData;
+ else
+ pData->SetIndex(nIndex);
+ }
+ }
+}
+
+ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument* pDoc, ScDocument* pSrcDoc) :
+ mpDoc(pDoc)
+{
+ mpDoc->MergeNumberFormatter(pSrcDoc);
+}
+
+ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
+{
+ mpDoc->pFormatExchangeList = NULL;
+}
+
+void ScDocument::MergeNumberFormatter(ScDocument* pSrcDoc)
+{
+ SvNumberFormatter* pThisFormatter = xPoolHelper->GetFormTable();
+ SvNumberFormatter* pOtherFormatter = pSrcDoc->xPoolHelper->GetFormTable();
+ if (pOtherFormatter && pOtherFormatter != pThisFormatter)
+ {
+ SvNumberFormatterIndexTable* pExchangeList =
+ pThisFormatter->MergeFormatter(*(pOtherFormatter));
+ if (pExchangeList->Count() > 0)
+ pFormatExchangeList = pExchangeList;
+ }
+}
+
+void ScDocument::CopyRangeNamesFromClip(ScDocument* pClipDoc, ScClipRangeNameData& rRangeNames)
+{
+ sal_uInt16 nClipRangeNameCount = pClipDoc->pRangeName->GetCount();
+ ScClipRangeNameData aClipRangeNames;
+
+ // array containing range names which might need update of indices
+ aClipRangeNames.mpRangeNames.resize(nClipRangeNameCount, NULL);
+
+ for (sal_uInt16 i = 0; i < nClipRangeNameCount; ++i) //! DB-Bereiche Pivot-Bereiche auch
+ {
+ /* Copy only if the name doesn't exist in this document.
+ If it exists we use the already existing name instead,
+ another possibility could be to create new names if
+ documents differ.
+ A proper solution would ask the user how to proceed.
+ The adjustment of the indices in the formulas is done later.
+ */
+ ScRangeData* pClipRangeData = (*pClipDoc->pRangeName)[i];
+ USHORT k;
+ if ( pRangeName->SearchName( pClipRangeData->GetName(), k ) )
+ {
+ aClipRangeNames.mpRangeNames[i] = NULL; // range name not inserted
+ USHORT nOldIndex = pClipRangeData->GetIndex();
+ USHORT nNewIndex = ((*pRangeName)[k])->GetIndex();
+ aClipRangeNames.insert(nOldIndex, nNewIndex);
+ if ( !aClipRangeNames.mbReplace )
+ aClipRangeNames.mbReplace = ( nOldIndex != nNewIndex );
+ }
+ else
+ {
+ ScRangeData* pData = new ScRangeData( *pClipRangeData );
+ pData->SetDocument(this);
+ if ( pRangeName->FindIndex( pData->GetIndex() ) )
+ pData->SetIndex(0); // need new index, done in Insert
+ if ( pRangeName->Insert( pData ) )
+ {
+ aClipRangeNames.mpRangeNames[i] = pData;
+ USHORT nOldIndex = pClipRangeData->GetIndex();
+ USHORT nNewIndex = pData->GetIndex();
+ aClipRangeNames.insert(nOldIndex, nNewIndex);
+ if ( !aClipRangeNames.mbReplace )
+ aClipRangeNames.mbReplace = ( nOldIndex != nNewIndex );
+ }
+ else
+ { // must be an overflow
+ delete pData;
+ aClipRangeNames.mpRangeNames[i] = NULL;
+ aClipRangeNames.insert(pClipRangeData->GetIndex(), 0);
+ aClipRangeNames.mbReplace = true;
+ }
+ }
+ }
+ rRangeNames = aClipRangeNames;
+}
+
+void ScDocument::UpdateRangeNamesInFormulas(
+ ScClipRangeNameData& rRangeNames, const ScRangeList& rDestRanges, const ScMarkData& rMark,
+ SCCOL nXw, SCROW nYw)
+{
+ // nXw and nYw are the extra width and height of the destination range
+ // extended due to presence of merged cell(s).
+
+ if (!rRangeNames.mbReplace)
+ return;
+
+ // first update all inserted named formulas if they contain other
+ // range names and used indices changed
+ size_t nRangeNameCount = rRangeNames.mpRangeNames.size();
+ for (size_t i = 0; i < nRangeNameCount; ++i) //! DB-Bereiche Pivot-Bereiche auch
+ {
+ if ( rRangeNames.mpRangeNames[i] )
+ rRangeNames.mpRangeNames[i]->ReplaceRangeNamesInUse(rRangeNames.maRangeMap);
+ }
+ // then update the formulas, they might need just the updated range names
+ for (ULONG nRange = 0; nRange < rDestRanges.Count(); ++nRange)
+ {
+ const ScRange* pRange = rDestRanges.GetObject( nRange);
+ SCCOL nCol1 = pRange->aStart.Col();
+ SCROW nRow1 = pRange->aStart.Row();
+ SCCOL nCol2 = pRange->aEnd.Col();
+ SCROW nRow2 = pRange->aEnd.Row();
+
+ SCCOL nC1 = nCol1;
+ SCROW nR1 = nRow1;
+ SCCOL nC2 = nC1 + nXw;
+ if (nC2 > nCol2)
+ nC2 = nCol2;
+ SCROW nR2 = nR1 + nYw;
+ if (nR2 > nRow2)
+ nR2 = nRow2;
+ do
+ {
+ do
+ {
+ for (SCTAB k = 0; k <= MAXTAB; k++)
+ {
+ if ( pTab[k] && rMark.GetTableSelect(k) )
+ pTab[k]->ReplaceRangeNamesInUse(nC1, nR1,
+ nC2, nR2, rRangeNames.maRangeMap);
+ }
+ nC1 = nC2 + 1;
+ nC2 = Min((SCCOL)(nC1 + nXw), nCol2);
+ } while (nC1 <= nCol2);
+ nC1 = nCol1;
+ nC2 = nC1 + nXw;
+ if (nC2 > nCol2)
+ nC2 = nCol2;
+ nR1 = nR2 + 1;
+ nR2 = Min((SCROW)(nR1 + nYw), nRow2);
+ } while (nR1 <= nRow2);
+ }
+}
+
+ScClipParam& ScDocument::GetClipParam()
+{
+ if (!mpClipParam.get())
+ mpClipParam.reset(new ScClipParam);
+
+ return *mpClipParam;
+}
+
+void ScDocument::SetClipParam(const ScClipParam& rParam)
+{
+ mpClipParam.reset(new ScClipParam(rParam));
+}
+
+BOOL ScDocument::IsClipboardSource() const
+{
+ ScDocument* pClipDoc = SC_MOD()->GetClipDoc();
+ return pClipDoc && pClipDoc->xPoolHelper.isValid() &&
+ xPoolHelper->GetDocPool() == pClipDoc->xPoolHelper->GetDocPool();
+}
+
+
+void ScDocument::StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark, USHORT nInsFlag )
+{
+ if (nInsFlag & IDF_CONTENTS)
+ {
+ for (SCTAB i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->StartListeningInArea( nCol1, nRow1, nCol2, nRow2 );
+ }
+}
+
+
+void ScDocument::BroadcastFromClip( SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark, USHORT nInsFlag )
+{
+ if (nInsFlag & IDF_CONTENTS)
+ {
+ ScBulkBroadcast aBulkBroadcast( GetBASM());
+ for (SCTAB i = 0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->BroadcastInArea( nCol1, nRow1, nCol2, nRow2 );
+ }
+}
+
+
+void ScDocument::CopyBlockFromClip( SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark,
+ SCsCOL nDx, SCsROW nDy,
+ const ScCopyBlockFromClipParams* pCBFCP )
+{
+ ScTable** ppClipTab = pCBFCP->pClipDoc->pTab;
+ SCTAB nTabEnd = pCBFCP->nTabEnd;
+ SCTAB nClipTab = 0;
+ for (SCTAB i = pCBFCP->nTabStart; i <= nTabEnd; i++)
+ {
+ if (pTab[i] && rMark.GetTableSelect(i) )
+ {
+ while (!ppClipTab[nClipTab]) nClipTab = (nClipTab+1) % (MAXTAB+1);
+
+ pTab[i]->CopyFromClip( nCol1, nRow1, nCol2, nRow2, nDx, nDy,
+ pCBFCP->nInsFlag, pCBFCP->bAsLink, pCBFCP->bSkipAttrForEmpty, ppClipTab[nClipTab] );
+
+ if ( pCBFCP->pClipDoc->pDrawLayer && ( pCBFCP->nInsFlag & IDF_OBJECTS ) )
+ {
+ // also copy drawing objects
+
+ // drawing layer must be created before calling CopyFromClip
+ // (ScDocShell::MakeDrawLayer also does InitItems etc.)
+ DBG_ASSERT( pDrawLayer, "CopyBlockFromClip: No drawing layer" );
+ if ( pDrawLayer )
+ {
+ // For GetMMRect, the row heights in the target document must already be valid
+ // (copied in an extra step before pasting, or updated after pasting cells, but
+ // before pasting objects).
+
+ Rectangle aSourceRect = pCBFCP->pClipDoc->GetMMRect(
+ nCol1-nDx, nRow1-nDy, nCol2-nDx, nRow2-nDy, nClipTab );
+ Rectangle aDestRect = GetMMRect( nCol1, nRow1, nCol2, nRow2, i );
+ pDrawLayer->CopyFromClip( pCBFCP->pClipDoc->pDrawLayer, nClipTab, aSourceRect,
+ ScAddress( nCol1, nRow1, i ), aDestRect );
+ }
+ }
+
+ nClipTab = (nClipTab+1) % (MAXTAB+1);
+ }
+ }
+ if ( pCBFCP->nInsFlag & IDF_CONTENTS )
+ {
+ nClipTab = 0;
+ for (SCTAB i = pCBFCP->nTabStart; i <= nTabEnd; i++)
+ {
+ if (pTab[i] && rMark.GetTableSelect(i) )
+ {
+ while (!ppClipTab[nClipTab]) nClipTab = (nClipTab+1) % (MAXTAB+1);
+ SCsTAB nDz = ((SCsTAB)i) - nClipTab;
+
+ // #89081# ranges of consecutive selected tables (in clipboard and dest. doc)
+ // must be handled in one UpdateReference call
+ SCTAB nFollow = 0;
+ while ( i + nFollow < nTabEnd
+ && rMark.GetTableSelect( i + nFollow + 1 )
+ && nClipTab + nFollow < MAXTAB
+ && ppClipTab[nClipTab + nFollow + 1] )
+ ++nFollow;
+
+ if ( pCBFCP->pClipDoc->GetClipParam().mbCutMode )
+ {
+ BOOL bOldInserting = IsInsertingFromOtherDoc();
+ SetInsertingFromOtherDoc( TRUE);
+ UpdateReference( URM_MOVE,
+ nCol1, nRow1, i, nCol2, nRow2, i+nFollow,
+ nDx, nDy, nDz, pCBFCP->pRefUndoDoc );
+ SetInsertingFromOtherDoc( bOldInserting);
+ }
+ else
+ UpdateReference( URM_COPY,
+ nCol1, nRow1, i, nCol2, nRow2, i+nFollow,
+ nDx, nDy, nDz, pCBFCP->pRefUndoDoc, FALSE );
+
+ nClipTab = (nClipTab+nFollow+1) % (MAXTAB+1);
+ i = sal::static_int_cast<SCTAB>( i + nFollow );
+ }
+ }
+ }
+}
+
+
+void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rMark,
+ SCsCOL nDx, SCsROW /* nDy */,
+ const ScCopyBlockFromClipParams* pCBFCP,
+ SCROW & rClipStartRow )
+{
+ // call CopyBlockFromClip for ranges of consecutive non-filtered rows
+ // nCol1/nRow1 etc. is in target doc
+
+ // filtered state is taken from first used table in clipboard (as in GetClipArea)
+ SCTAB nFlagTab = 0;
+ ScTable** ppClipTab = pCBFCP->pClipDoc->pTab;
+ while ( nFlagTab < MAXTAB && !ppClipTab[nFlagTab] )
+ ++nFlagTab;
+
+ SCROW nSourceRow = rClipStartRow;
+ SCROW nSourceEnd = 0;
+ if (pCBFCP->pClipDoc->GetClipParam().maRanges.Count())
+ nSourceEnd = pCBFCP->pClipDoc->GetClipParam().maRanges.First()->aEnd.Row();
+ SCROW nDestRow = nRow1;
+
+ while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
+ {
+ // skip filtered rows
+ nSourceRow = pCBFCP->pClipDoc->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab);
+
+ if ( nSourceRow <= nSourceEnd )
+ {
+ // look for more non-filtered rows following
+ SCROW nLastRow = nSourceRow;
+ pCBFCP->pClipDoc->RowFiltered(nSourceRow, nFlagTab, NULL, &nLastRow);
+ SCROW nFollow = nLastRow - nSourceRow;
+
+ if (nFollow > nSourceEnd - nSourceRow)
+ nFollow = nSourceEnd - nSourceRow;
+ if (nFollow > nRow2 - nDestRow)
+ nFollow = nRow2 - nDestRow;
+
+ SCsROW nNewDy = ((SCsROW)nDestRow) - nSourceRow;
+ CopyBlockFromClip( nCol1, nDestRow, nCol2, nDestRow + nFollow, rMark, nDx, nNewDy, pCBFCP );
+
+ nSourceRow += nFollow + 1;
+ nDestRow += nFollow + 1;
+ }
+ }
+ rClipStartRow = nSourceRow;
+}
+
+
+void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMark,
+ USHORT nInsFlag,
+ ScDocument* pRefUndoDoc, ScDocument* pClipDoc, BOOL bResetCut,
+ BOOL bAsLink, BOOL bIncludeFiltered, BOOL bSkipAttrForEmpty,
+ const ScRangeList * pDestRanges )
+{
+ if (!bIsClip)
+ {
+ if (!pClipDoc)
+ {
+ DBG_ERROR("CopyFromClip: no ClipDoc");
+ pClipDoc = SC_MOD()->GetClipDoc();
+ }
+ if (pClipDoc->bIsClip && pClipDoc->GetTableCount())
+ {
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // avoid multiple recalculations
+
+ NumFmtMergeHandler aNumFmtMergeHdl(this, pClipDoc);
+
+ ScClipRangeNameData aClipRangeNames;
+ CopyRangeNamesFromClip(pClipDoc, aClipRangeNames);
+
+ SCCOL nAllCol1 = rDestRange.aStart.Col();
+ SCROW nAllRow1 = rDestRange.aStart.Row();
+ SCCOL nAllCol2 = rDestRange.aEnd.Col();
+ SCROW nAllRow2 = rDestRange.aEnd.Row();
+
+ SCCOL nXw = 0;
+ SCROW nYw = 0;
+ ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) // find largest merge overlap
+ if (pClipDoc->pTab[nTab]) // all sheets of the clipboard content
+ {
+ SCCOL nThisEndX = aClipRange.aEnd.Col();
+ SCROW nThisEndY = aClipRange.aEnd.Row();
+ pClipDoc->ExtendMerge( aClipRange.aStart.Col(),
+ aClipRange.aStart.Row(),
+ nThisEndX, nThisEndY, nTab );
+ // only extra value from ExtendMerge
+ nThisEndX = sal::static_int_cast<SCCOL>( nThisEndX - aClipRange.aEnd.Col() );
+ nThisEndY = sal::static_int_cast<SCROW>( nThisEndY - aClipRange.aEnd.Row() );
+ if ( nThisEndX > nXw )
+ nXw = nThisEndX;
+ if ( nThisEndY > nYw )
+ nYw = nThisEndY;
+ }
+
+ SCCOL nDestAddX;
+ SCROW nDestAddY;
+ pClipDoc->GetClipArea( nDestAddX, nDestAddY, bIncludeFiltered );
+ nXw = sal::static_int_cast<SCCOL>( nXw + nDestAddX );
+ nYw = sal::static_int_cast<SCROW>( nYw + nDestAddY ); // ClipArea, plus ExtendMerge value
+
+ /* 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 | 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.
+ if ( ( nInsFlag & IDF_ATTRIB ) && !bSkipAttrForEmpty )
+ nDelFlag |= IDF_ATTRIB;
+
+ ScCopyBlockFromClipParams aCBFCP;
+ aCBFCP.pRefUndoDoc = pRefUndoDoc;
+ aCBFCP.pClipDoc = pClipDoc;
+ aCBFCP.nInsFlag = nInsFlag;
+ aCBFCP.bAsLink = bAsLink;
+ aCBFCP.bSkipAttrForEmpty = bSkipAttrForEmpty;
+ aCBFCP.nTabStart = MAXTAB; // wird in der Schleife angepasst
+ aCBFCP.nTabEnd = 0; // wird in der Schleife angepasst
+
+ // Inc/DecRecalcLevel einmal aussen, damit nicht fuer jeden Block
+ // die Draw-Seitengroesse neu berechnet werden muss
+ //! nur wenn ganze Zeilen/Spalten kopiert werden?
+
+ for (SCTAB j = 0; j <= MAXTAB; j++)
+ if (pTab[j] && rMark.GetTableSelect(j))
+ {
+ if ( j < aCBFCP.nTabStart )
+ aCBFCP.nTabStart = j;
+ aCBFCP.nTabEnd = j;
+ pTab[j]->IncRecalcLevel();
+ }
+
+ ScRangeList aLocalRangeList;
+ if (!pDestRanges)
+ {
+ aLocalRangeList.Append( rDestRange);
+ pDestRanges = &aLocalRangeList;
+ }
+
+ bInsertingFromOtherDoc = TRUE; // kein Broadcast/Listener aufbauen bei Insert
+
+ // bei mindestens 64 Zeilen wird in ScColumn::CopyFromClip voralloziert
+ BOOL bDoDouble = ( nYw < 64 && nAllRow2 - nAllRow1 > 64);
+ BOOL bOldDouble = ScColumn::bDoubleAlloc;
+ if (bDoDouble)
+ ScColumn::bDoubleAlloc = TRUE;
+
+ SCCOL nClipStartCol = aClipRange.aStart.Col();
+ SCROW nClipStartRow = aClipRange.aStart.Row();
+ // WaE: commented because unused: SCCOL nClipEndCol = pClipDoc->aClipRange.aEnd.Col();
+ SCROW nClipEndRow = aClipRange.aEnd.Row();
+ for (ULONG nRange = 0; nRange < pDestRanges->Count(); ++nRange)
+ {
+ const ScRange* pRange = pDestRanges->GetObject( nRange);
+ SCCOL nCol1 = pRange->aStart.Col();
+ SCROW nRow1 = pRange->aStart.Row();
+ SCCOL nCol2 = pRange->aEnd.Col();
+ SCROW nRow2 = pRange->aEnd.Row();
+
+ DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag);
+
+ SCCOL nC1 = nCol1;
+ SCROW nR1 = nRow1;
+ SCCOL nC2 = nC1 + nXw;
+ if (nC2 > nCol2)
+ nC2 = nCol2;
+ SCROW nR2 = nR1 + nYw;
+ if (nR2 > nRow2)
+ nR2 = nRow2;
+
+ do
+ {
+ // Pasting is done column-wise, when pasting to a filtered
+ // area this results in partitioning and we have to
+ // remember and reset the start row for each column until
+ // it can be advanced for the next chunk of unfiltered
+ // rows.
+ SCROW nSaveClipStartRow = nClipStartRow;
+ do
+ {
+ nClipStartRow = nSaveClipStartRow;
+ SCsCOL nDx = ((SCsCOL)nC1) - nClipStartCol;
+ SCsROW nDy = ((SCsROW)nR1) - nClipStartRow;
+ if ( bIncludeFiltered )
+ {
+ CopyBlockFromClip( nC1, nR1, nC2, nR2, rMark, nDx,
+ nDy, &aCBFCP );
+ nClipStartRow += nR2 - nR1 + 1;
+ }
+ else
+ {
+ CopyNonFilteredFromClip( nC1, nR1, nC2, nR2, rMark,
+ nDx, nDy, &aCBFCP, nClipStartRow );
+ }
+ // Not needed for columns, but if it was this would be how to.
+ //if (nClipStartCol > nClipEndCol)
+ // nClipStartCol = pClipDoc->aClipRange.aStart.Col();
+ nC1 = nC2 + 1;
+ nC2 = Min((SCCOL)(nC1 + nXw), nCol2);
+ } while (nC1 <= nCol2);
+ if (nClipStartRow > nClipEndRow)
+ nClipStartRow = aClipRange.aStart.Row();
+ nC1 = nCol1;
+ nC2 = nC1 + nXw;
+ if (nC2 > nCol2)
+ nC2 = nCol2;
+ nR1 = nR2 + 1;
+ nR2 = Min((SCROW)(nR1 + nYw), nRow2);
+ } while (nR1 <= nRow2);
+ }
+
+ ScColumn::bDoubleAlloc = bOldDouble;
+
+ for (SCTAB k = 0; k <= MAXTAB; k++)
+ if (pTab[k] && rMark.GetTableSelect(k))
+ pTab[k]->DecRecalcLevel();
+
+ bInsertingFromOtherDoc = FALSE;
+
+ UpdateRangeNamesInFormulas(aClipRangeNames, *pDestRanges, rMark, nXw, nYw);
+
+ // Listener aufbauen nachdem alles inserted wurde
+ StartListeningFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
+ // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
+ BroadcastFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
+ if (bResetCut)
+ pClipDoc->GetClipParam().mbCutMode = false;
+ SetAutoCalc( bOldAutoCalc );
+ }
+ }
+}
+
+static SCROW lcl_getLastNonFilteredRow(
+ const ScBitMaskCompressedArray<SCROW, BYTE>& rFlags, SCROW nBegRow, SCROW nEndRow,
+ SCROW nRowCount)
+{
+ SCROW nFilteredRow = rFlags.GetFirstForCondition(
+ nBegRow, nEndRow, CR_FILTERED, CR_FILTERED);
+
+ SCROW nRow = nFilteredRow - 1;
+ if (nRow - nBegRow + 1 > nRowCount)
+ // make sure the row range stays within the data size.
+ nRow = nBegRow + nRowCount - 1;
+
+ return nRow;
+}
+
+void ScDocument::CopyMultiRangeFromClip(
+ const ScAddress& rDestPos, const ScMarkData& rMark, sal_uInt16 nInsFlag, ScDocument* pClipDoc,
+ bool bResetCut, bool bAsLink, bool /*bIncludeFiltered*/, bool bSkipAttrForEmpty)
+{
+ if (bIsClip)
+ return;
+
+ if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount())
+ // There is nothing in the clip doc to copy.
+ return;
+
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // avoid multiple recalculations
+
+ NumFmtMergeHandler aNumFmtMergeHdl(this, pClipDoc);
+
+ ScClipRangeNameData aClipRangeNames;
+ CopyRangeNamesFromClip(pClipDoc, aClipRangeNames);
+
+ SCCOL nCol1 = rDestPos.Col();
+ SCROW nRow1 = rDestPos.Row();
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+
+ ScCopyBlockFromClipParams aCBFCP;
+ aCBFCP.pRefUndoDoc = NULL;
+ aCBFCP.pClipDoc = pClipDoc;
+ aCBFCP.nInsFlag = nInsFlag;
+ aCBFCP.bAsLink = bAsLink;
+ aCBFCP.bSkipAttrForEmpty = bSkipAttrForEmpty;
+ aCBFCP.nTabStart = MAXTAB;
+ aCBFCP.nTabEnd = 0;
+
+ for (SCTAB j = 0; j <= MAXTAB; ++j)
+ {
+ if (pTab[j] && rMark.GetTableSelect(j))
+ {
+ if ( j < aCBFCP.nTabStart )
+ aCBFCP.nTabStart = j;
+ aCBFCP.nTabEnd = j;
+ pTab[j]->IncRecalcLevel();
+ }
+ }
+
+ ScRange aDestRange;
+ rMark.GetMarkArea(aDestRange);
+ SCROW nLastMarkedRow = aDestRange.aEnd.Row();
+
+ bInsertingFromOtherDoc = TRUE; // kein Broadcast/Listener aufbauen bei Insert
+
+ SCROW nBegRow = nRow1;
+ sal_uInt16 nDelFlag = IDF_CONTENTS;
+ const ScBitMaskCompressedArray<SCROW, BYTE>& rFlags = GetRowFlagsArray(aCBFCP.nTabStart);
+
+ for (ScRange* p = rClipParam.maRanges.First(); p; p = rClipParam.maRanges.Next())
+ {
+ // The begin row must not be filtered.
+
+ SCROW nRowCount = p->aEnd.Row() - p->aStart.Row() + 1;
+
+ SCsCOL nDx = static_cast<SCsCOL>(nCol1 - p->aStart.Col());
+ SCsROW nDy = static_cast<SCsROW>(nBegRow - p->aStart.Row());
+ SCCOL nCol2 = nCol1 + p->aEnd.Col() - p->aStart.Col();
+
+ SCROW nEndRow = lcl_getLastNonFilteredRow(rFlags, nBegRow, nLastMarkedRow, nRowCount);
+
+ if (!bSkipAttrForEmpty)
+ DeleteArea(nCol1, nBegRow, nCol2, nEndRow, rMark, nDelFlag);
+
+ CopyBlockFromClip(nCol1, nBegRow, nCol2, nEndRow, rMark, nDx, nDy, &aCBFCP);
+ nRowCount -= nEndRow - nBegRow + 1;
+
+ while (nRowCount > 0)
+ {
+ // Get the first non-filtered row.
+ SCROW nNonFilteredRow = rFlags.GetFirstForCondition(nEndRow+1, nLastMarkedRow, CR_FILTERED, 0);
+ if (nNonFilteredRow > nLastMarkedRow)
+ return;
+
+ SCROW nRowsSkipped = nNonFilteredRow - nEndRow - 1;
+ nDy += nRowsSkipped;
+
+ nBegRow = nNonFilteredRow;
+ nEndRow = lcl_getLastNonFilteredRow(rFlags, nBegRow, nLastMarkedRow, nRowCount);
+
+ if (!bSkipAttrForEmpty)
+ DeleteArea(nCol1, nBegRow, nCol2, nEndRow, rMark, nDelFlag);
+
+ CopyBlockFromClip(nCol1, nBegRow, nCol2, nEndRow, rMark, nDx, nDy, &aCBFCP);
+ nRowCount -= nEndRow - nBegRow + 1;
+ }
+
+ if (rClipParam.meDirection == ScClipParam::Row)
+ // Begin row for the next range being pasted.
+ nBegRow = rFlags.GetFirstForCondition(nEndRow+1, nLastMarkedRow, CR_FILTERED, 0);
+ else
+ nBegRow = nRow1;
+
+ if (rClipParam.meDirection == ScClipParam::Column)
+ nCol1 += p->aEnd.Col() - p->aStart.Col() + 1;
+ }
+
+ for (SCTAB i = 0; i <= MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->DecRecalcLevel();
+
+ bInsertingFromOtherDoc = FALSE;
+
+ ScRangeList aRanges;
+ aRanges.Append(aDestRange);
+ SCCOL nCols = aDestRange.aEnd.Col() - aDestRange.aStart.Col() + 1;
+ SCROW nRows = aDestRange.aEnd.Row() - aDestRange.aStart.Row() + 1;
+ UpdateRangeNamesInFormulas(aClipRangeNames, aRanges, rMark, nCols-1, nRows-1);
+
+ // Listener aufbauen nachdem alles inserted wurde
+ StartListeningFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
+ aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
+ // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
+ BroadcastFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
+ aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
+
+ if (bResetCut)
+ pClipDoc->GetClipParam().mbCutMode = false;
+ SetAutoCalc( bOldAutoCalc );
+}
+
+void ScDocument::SetClipArea( const ScRange& rArea, BOOL bCut )
+{
+ if (bIsClip)
+ {
+ ScClipParam& rClipParam = GetClipParam();
+ rClipParam.maRanges.RemoveAll();
+ rClipParam.maRanges.Append(rArea);
+ rClipParam.mbCutMode = bCut;
+ }
+ else
+ {
+ DBG_ERROR("SetClipArea: kein Clip");
+ }
+}
+
+
+void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, BOOL bIncludeFiltered)
+{
+ if (!bIsClip)
+ {
+ DBG_ERROR("GetClipArea: kein Clip");
+ return;
+ }
+
+ ScRangeList& rClipRanges = GetClipParam().maRanges;
+ if (!rClipRanges.Count())
+ // No clip range. Bail out.
+ return;
+
+ ScRangePtr p = rClipRanges.First();
+ SCCOL nStartCol = p->aStart.Col();
+ SCCOL nEndCol = p->aEnd.Col();
+ SCROW nStartRow = p->aStart.Row();
+ SCROW nEndRow = p->aEnd.Row();
+ for (p = rClipRanges.Next(); p; p = rClipRanges.Next())
+ {
+ if (p->aStart.Col() < nStartCol)
+ nStartCol = p->aStart.Col();
+ if (p->aStart.Row() < nStartRow)
+ nStartRow = p->aStart.Row();
+ if (p->aEnd.Col() > nEndCol)
+ nEndCol = p->aEnd.Col();
+ if (p->aEnd.Row() < nEndRow)
+ nEndRow = p->aEnd.Row();
+ }
+
+ nClipX = nEndCol - nStartCol;
+
+ if ( bIncludeFiltered )
+ nClipY = nEndRow - nStartRow;
+ else
+ {
+ // count non-filtered rows
+ // count on first used table in clipboard
+ SCTAB nCountTab = 0;
+ while ( nCountTab < MAXTAB && !pTab[nCountTab] )
+ ++nCountTab;
+
+ SCROW nResult = CountNonFilteredRows(nStartRow, nEndRow, nCountTab);
+
+ if ( nResult > 0 )
+ nClipY = nResult - 1;
+ else
+ nClipY = 0; // always return at least 1 row
+ }
+}
+
+
+void ScDocument::GetClipStart(SCCOL& nClipX, SCROW& nClipY)
+{
+ if (bIsClip)
+ {
+ ScRangeList& rClipRanges = GetClipParam().maRanges;
+ if (rClipRanges.Count())
+ {
+ nClipX = rClipRanges.First()->aStart.Col();
+ nClipY = rClipRanges.First()->aStart.Row();
+ }
+ }
+ else
+ {
+ DBG_ERROR("GetClipStart: kein Clip");
+ }
+}
+
+
+BOOL ScDocument::HasClipFilteredRows()
+{
+ // count on first used table in clipboard
+ SCTAB nCountTab = 0;
+ while ( nCountTab < MAXTAB && !pTab[nCountTab] )
+ ++nCountTab;
+
+ ScRangeList& rClipRanges = GetClipParam().maRanges;
+ if (!rClipRanges.Count())
+ return false;
+
+ for (ScRange* p = rClipRanges.First(); p; p = rClipRanges.Next())
+ {
+ bool bAnswer = pTab[nCountTab]->HasFilteredRows(p->aStart.Row(), p->aEnd.Row());
+ if (bAnswer)
+ return true;
+ }
+ return false;
+}
+
+
+void ScDocument::MixDocument( const ScRange& rRange, USHORT nFunction, BOOL bSkipEmpty,
+ ScDocument* pSrcDoc )
+{
+ SCTAB nTab1 = rRange.aStart.Tab();
+ SCTAB nTab2 = rRange.aEnd.Tab();
+ for (SCTAB i = nTab1; i <= nTab2; i++)
+ if (pTab[i] && pSrcDoc->pTab[i])
+ pTab[i]->MixData( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(),
+ nFunction, bSkipEmpty, pSrcDoc->pTab[i] );
+}
+
+
+void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
+ USHORT nFlags, USHORT nFunction,
+ BOOL bSkipEmpty, BOOL bAsLink )
+{
+ USHORT nDelFlags = nFlags;
+ if (nDelFlags & IDF_CONTENTS)
+ nDelFlags |= IDF_CONTENTS; // immer alle Inhalte oder keine loeschen!
+
+ SCTAB nSrcTab = rSrcArea.aStart.Tab();
+
+ if (ValidTab(nSrcTab) && pTab[nSrcTab])
+ {
+ SCCOL nStartCol = rSrcArea.aStart.Col();
+ SCROW nStartRow = rSrcArea.aStart.Row();
+ SCCOL nEndCol = rSrcArea.aEnd.Col();
+ SCROW nEndRow = rSrcArea.aEnd.Row();
+ ScDocument* pMixDoc = NULL;
+ BOOL bDoMix = ( bSkipEmpty || nFunction ) && ( nFlags & IDF_CONTENTS );
+
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+
+ SCTAB nCount = GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ if ( i!=nSrcTab && pTab[i] && rMark.GetTableSelect(i) )
+ {
+ if (bDoMix)
+ {
+ if (!pMixDoc)
+ {
+ pMixDoc = new ScDocument( SCDOCMODE_UNDO );
+ pMixDoc->InitUndo( this, i, i );
+ }
+ else
+ pMixDoc->AddUndoTab( i, i );
+ pTab[i]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+ IDF_CONTENTS, FALSE, pMixDoc->pTab[i] );
+ }
+ pTab[i]->DeleteArea( nStartCol,nStartRow, nEndCol,nEndRow, nDelFlags);
+ pTab[nSrcTab]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+ nFlags, FALSE, pTab[i], NULL, bAsLink );
+
+ if (bDoMix)
+ pTab[i]->MixData( nStartCol,nStartRow, nEndCol,nEndRow,
+ nFunction, bSkipEmpty, pMixDoc->pTab[i] );
+ }
+
+ delete pMixDoc;
+
+ SetAutoCalc( bOldAutoCalc );
+ }
+ else
+ {
+ DBG_ERROR("falsche Tabelle");
+ }
+}
+
+
+void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
+ USHORT nFlags, USHORT nFunction,
+ BOOL bSkipEmpty, BOOL bAsLink )
+{
+ USHORT nDelFlags = nFlags;
+ if (nDelFlags & IDF_CONTENTS)
+ nDelFlags |= IDF_CONTENTS; // immer alle Inhalte oder keine loeschen!
+
+ if (ValidTab(nSrcTab) && pTab[nSrcTab])
+ {
+ ScDocument* pMixDoc = NULL;
+ BOOL bDoMix = ( bSkipEmpty || nFunction ) && ( nFlags & IDF_CONTENTS );
+
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+
+ ScRange aArea;
+ rMark.GetMultiMarkArea( aArea );
+ SCCOL nStartCol = aArea.aStart.Col();
+ SCROW nStartRow = aArea.aStart.Row();
+ SCCOL nEndCol = aArea.aEnd.Col();
+ SCROW nEndRow = aArea.aEnd.Row();
+
+ SCTAB nCount = GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ if ( i!=nSrcTab && pTab[i] && rMark.GetTableSelect(i) )
+ {
+ if (bDoMix)
+ {
+ if (!pMixDoc)
+ {
+ pMixDoc = new ScDocument( SCDOCMODE_UNDO );
+ pMixDoc->InitUndo( this, i, i );
+ }
+ else
+ pMixDoc->AddUndoTab( i, i );
+ pTab[i]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+ IDF_CONTENTS, TRUE, pMixDoc->pTab[i], &rMark );
+ }
+
+ pTab[i]->DeleteSelection( nDelFlags, rMark );
+ pTab[nSrcTab]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+ nFlags, TRUE, pTab[i], &rMark, bAsLink );
+
+ if (bDoMix)
+ pTab[i]->MixMarked( rMark, nFunction, bSkipEmpty, pMixDoc->pTab[i] );
+ }
+
+ delete pMixDoc;
+
+ SetAutoCalc( bOldAutoCalc );
+ }
+ else
+ {
+ DBG_ERROR("falsche Tabelle");
+ }
+}
+
+
+void ScDocument::PutCell( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell, BOOL bForceTab )
+{
+ if (VALIDTAB(nTab))
+ {
+ if ( bForceTab && !pTab[nTab] )
+ {
+ BOOL bExtras = !bIsUndo; // Spaltenbreiten, Zeilenhoehen, Flags
+
+ pTab[nTab] = new ScTable(this, nTab,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
+ bExtras, bExtras);
+ ++nMaxTableNumber;
+ }
+
+ if (pTab[nTab])
+ pTab[nTab]->PutCell( nCol, nRow, pCell );
+ }
+}
+
+
+void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell, BOOL bForceTab )
+{
+ SCTAB nTab = rPos.Tab();
+ if ( bForceTab && !pTab[nTab] )
+ {
+ BOOL bExtras = !bIsUndo; // Spaltenbreiten, Zeilenhoehen, Flags
+
+ pTab[nTab] = new ScTable(this, nTab,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
+ bExtras, bExtras);
+ ++nMaxTableNumber;
+ }
+
+ if (pTab[nTab])
+ pTab[nTab]->PutCell( rPos, pCell );
+}
+
+
+BOOL ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
+ SvNumberFormatter* pFormatter, bool bDetectNumberFormat )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->SetString( nCol, nRow, nTab, rString, pFormatter, bDetectNumberFormat );
+ else
+ return FALSE;
+}
+
+
+void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->SetValue( nCol, nRow, rVal );
+}
+
+
+void ScDocument::GetString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString )
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ pTab[nTab]->GetString( nCol, nRow, rString );
+ else
+ rString.Erase();
+}
+
+
+void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString )
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ pTab[nTab]->GetInputString( nCol, nRow, rString );
+ else
+ rString.Erase();
+}
+
+
+void ScDocument::GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue )
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ rValue = pTab[nTab]->GetValue( nCol, nRow );
+ else
+ rValue = 0.0;
+}
+
+
+double ScDocument::GetValue( const ScAddress& rPos )
+{
+ SCTAB nTab = rPos.Tab();
+ if ( pTab[nTab] )
+ return pTab[nTab]->GetValue( rPos );
+ return 0.0;
+}
+
+
+void ScDocument::GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ sal_uInt32& rFormat )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ {
+ rFormat = pTab[nTab]->GetNumberFormat( nCol, nRow );
+ return ;
+ }
+ rFormat = 0;
+}
+
+
+sal_uInt32 ScDocument::GetNumberFormat( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if ( pTab[nTab] )
+ return pTab[nTab]->GetNumberFormat( rPos );
+ return 0;
+}
+
+
+void ScDocument::GetNumberFormatInfo( short& nType, ULONG& nIndex,
+ const ScAddress& rPos, const ScBaseCell* pCell ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if ( pTab[nTab] )
+ {
+ nIndex = pTab[nTab]->GetNumberFormat( rPos );
+ if ( (nIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && pCell &&
+ pCell->GetCellType() == CELLTYPE_FORMULA )
+ static_cast<const ScFormulaCell*>(pCell)->GetFormatInfo( nType, nIndex );
+ else
+ nType = GetFormatTable()->GetType( nIndex );
+ }
+ else
+ {
+ nType = NUMBERFORMAT_UNDEFINED;
+ nIndex = 0;
+ }
+}
+
+
+void ScDocument::GetFormula( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rFormula,
+ BOOL bAsciiExport ) const
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ pTab[nTab]->GetFormula( nCol, nRow, rFormula, bAsciiExport );
+ else
+ rFormula.Erase();
+}
+
+
+CellType ScDocument::GetCellType( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if ( pTab[nTab] )
+ return pTab[nTab]->GetCellType( rPos );
+ return CELLTYPE_NONE;
+}
+
+
+void ScDocument::GetCellType( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ CellType& rCellType ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ rCellType = pTab[nTab]->GetCellType( nCol, nRow );
+ else
+ rCellType = CELLTYPE_NONE;
+}
+
+
+void ScDocument::GetCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScBaseCell*& rpCell ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ rpCell = pTab[nTab]->GetCell( nCol, nRow );
+ else
+ {
+ DBG_ERROR("GetCell ohne Tabelle");
+ rpCell = NULL;
+ }
+}
+
+
+ScBaseCell* ScDocument::GetCell( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetCell( rPos );
+
+ DBG_ERROR("GetCell ohne Tabelle");
+ return NULL;
+}
+
+
+BOOL ScDocument::HasStringData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ return pTab[nTab]->HasStringData( nCol, nRow );
+ else
+ return FALSE;
+}
+
+
+BOOL ScDocument::HasValueData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ return pTab[nTab]->HasValueData( nCol, nRow );
+ else
+ return FALSE;
+}
+
+
+BOOL ScDocument::HasStringCells( const ScRange& rRange ) const
+{
+ // TRUE, wenn String- oder Editzellen im Bereich
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ for ( SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++ )
+ if ( pTab[nTab] && pTab[nTab]->HasStringCells( nStartCol, nStartRow, nEndCol, nEndRow ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL ScDocument::HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA ) )->GetValue();
+ if( nValidation )
+ {
+ const ScValidationData* pData = GetValidationEntry( nValidation );
+ if( pData && pData->HasSelectionList() )
+ return TRUE;
+ }
+ return HasStringCells( ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ) );
+}
+
+
+ScPostIt* ScDocument::GetNote( const ScAddress& rPos )
+{
+ ScTable* pTable = ValidTab( rPos.Tab() ) ? pTab[ rPos.Tab() ] : 0;
+ return pTable ? pTable->GetNote( rPos.Col(), rPos.Row() ) : 0;
+}
+
+
+void ScDocument::TakeNote( const ScAddress& rPos, ScPostIt*& rpNote )
+{
+ if( ValidTab( rPos.Tab() ) && pTab[ rPos.Tab() ] )
+ pTab[ rPos.Tab() ]->TakeNote( rPos.Col(), rPos.Row(), rpNote );
+ else
+ DELETEZ( rpNote );
+}
+
+
+ScPostIt* ScDocument::ReleaseNote( const ScAddress& rPos )
+{
+ ScTable* pTable = ValidTab( rPos.Tab() ) ? pTab[ rPos.Tab() ] : 0;
+ return pTable ? pTable->ReleaseNote( rPos.Col(), rPos.Row() ) : 0;
+}
+
+
+ScPostIt* ScDocument::GetOrCreateNote( const ScAddress& rPos )
+{
+ ScPostIt* pNote = GetNote( rPos );
+ if( !pNote )
+ {
+ pNote = new ScPostIt( *this, rPos, false );
+ TakeNote( rPos, pNote );
+ }
+ return pNote;
+}
+
+
+void ScDocument::DeleteNote( const ScAddress& rPos )
+{
+ if( ValidTab( rPos.Tab() ) && pTab[ rPos.Tab() ] )
+ pTab[ rPos.Tab() ]->DeleteNote( rPos.Col(), rPos.Row() );
+}
+
+
+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();
+ bAutoCalc = FALSE; // keine Mehrfachberechnung
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( GetBASM());
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i]) pTab[i]->SetDirty();
+ }
+
+ // Charts werden zwar auch ohne AutoCalc im Tracking auf Dirty gesetzt,
+ // wenn alle Formeln dirty sind, werden die Charts aber nicht mehr erwischt
+ // (#45205#) - darum alle Charts nochmal explizit
+ if (pChartListenerCollection)
+ pChartListenerCollection->SetDirty();
+
+ SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::SetDirty( const ScRange& rRange )
+{
+ BOOL bOldAutoCalc = GetAutoCalc();
+ bAutoCalc = FALSE; // keine Mehrfachberechnung
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( GetBASM());
+ SCTAB nTab2 = rRange.aEnd.Tab();
+ for (SCTAB i=rRange.aStart.Tab(); i<=nTab2; i++)
+ if (pTab[i]) pTab[i]->SetDirty( rRange );
+ }
+ SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::SetTableOpDirty( const ScRange& rRange )
+{
+ BOOL bOldAutoCalc = GetAutoCalc();
+ bAutoCalc = FALSE; // no multiple recalculation
+ SCTAB nTab2 = rRange.aEnd.Tab();
+ for (SCTAB i=rRange.aStart.Tab(); i<=nTab2; i++)
+ if (pTab[i]) pTab[i]->SetTableOpDirty( rRange );
+ SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::InterpretDirtyCells( const ScRangeList& rRanges )
+{
+ ULONG nRangeCount = rRanges.Count();
+ for (ULONG nPos=0; nPos<nRangeCount; nPos++)
+ {
+ ScCellIterator aIter( this, *rRanges.GetObject(nPos) );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ if ( static_cast<ScFormulaCell*>(pCell)->GetDirty() && GetAutoCalc() )
+ static_cast<ScFormulaCell*>(pCell)->Interpret();
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+}
+
+
+void ScDocument::AddTableOpFormulaCell( ScFormulaCell* pCell )
+{
+ ScInterpreterTableOpParams* p = aTableOpList.Last();
+ if ( p && p->bCollectNotifications )
+ {
+ if ( p->bRefresh )
+ { // refresh pointers only
+ p->aNotifiedFormulaCells.push_back( pCell );
+ }
+ else
+ { // init both, address and pointer
+ p->aNotifiedFormulaCells.push_back( pCell );
+ p->aNotifiedFormulaPos.push_back( pCell->aPos );
+ }
+ }
+}
+
+
+void ScDocument::CalcAll()
+{
+ ClearLookupCaches(); // Ensure we don't deliver zombie data.
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( TRUE );
+ SCTAB i;
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i]) pTab[i]->SetDirtyVar();
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i]) pTab[i]->CalcAll();
+ ClearFormulaTree();
+ SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::CompileAll()
+{
+ if ( pCondFormList )
+ pCondFormList->CompileAll();
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i]) pTab[i]->CompileAll();
+ SetDirty();
+}
+
+
+void ScDocument::CompileXML()
+{
+ BOOL bOldAutoCalc = GetAutoCalc();
+ SetAutoCalc( FALSE );
+ ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(
+ STR_PROGRESS_CALCULATING ), GetXMLImportedFormulaCount() );
+
+ // #b6355215# set AutoNameCache to speed up automatic name lookup
+ DBG_ASSERT( !pAutoNameCache, "AutoNameCache already set" );
+ pAutoNameCache = new ScAutoNameCache( this );
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i]) pTab[i]->CompileXML( aProgress );
+
+ DELETEZ( pAutoNameCache ); // valid only during CompileXML, where cell contents don't change
+
+ if ( pCondFormList )
+ pCondFormList->CompileXML();
+ if ( pValidationList )
+ pValidationList->CompileXML();
+
+ SetDirty();
+ SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScDocument::CalcAfterLoad()
+{
+ SCTAB i;
+
+ if (bIsClip) // Excel-Dateien werden aus dem Clipboard in ein Clip-Doc geladen
+ return; // dann wird erst beim Einfuegen in das richtige Doc berechnet
+
+ bCalcingAfterLoad = TRUE;
+ for ( i = 0; i <= MAXTAB; i++)
+ if (pTab[i]) pTab[i]->CalcAfterLoad();
+ for (i=0; i<=MAXTAB; i++)
+ if (pTab[i]) pTab[i]->SetDirtyAfterLoad();
+ bCalcingAfterLoad = FALSE;
+
+ SetDetectiveDirty(FALSE); // noch keine wirklichen Aenderungen
+
+ // #i112436# If formula cells are already dirty, they don't broadcast further changes.
+ // So the source ranges of charts must be interpreted even if they are not visible,
+ // similar to ScMyShapeResizer::CreateChartListener for loading own files (i104899).
+ if (pChartListenerCollection)
+ {
+ sal_uInt16 nChartCount = pChartListenerCollection->GetCount();
+ for ( sal_uInt16 nIndex = 0; nIndex < nChartCount; nIndex++ )
+ {
+ ScChartListener* pChartListener = static_cast<ScChartListener*>(pChartListenerCollection->At(nIndex));
+ InterpretDirtyCells(*pChartListener->GetRangeList());
+ }
+ }
+}
+
+
+USHORT ScDocument::GetErrCode( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if ( pTab[nTab] )
+ return pTab[nTab]->GetErrCode( rPos );
+ return 0;
+}
+
+
+void ScDocument::ResetChanged( const ScRange& rRange )
+{
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ if (pTab[nTab])
+ pTab[nTab]->ResetChanged( rRange );
+}
+
+//
+// Spaltenbreiten / Zeilenhoehen --------------------------------------
+//
+
+
+void ScDocument::SetColWidth( SCCOL nCol, SCTAB nTab, USHORT nNewWidth )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetColWidth( nCol, nNewWidth );
+}
+
+
+void ScDocument::SetRowHeight( SCROW nRow, SCTAB nTab, USHORT nNewHeight )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRowHeight( nRow, nNewHeight );
+}
+
+
+void ScDocument::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nNewHeight )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRowHeightRange
+ ( nStartRow, nEndRow, nNewHeight, 1.0, 1.0 );
+}
+
+void ScDocument::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nNewHeight )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRowHeightOnly( nStartRow, nEndRow, nNewHeight );
+}
+
+void ScDocument::SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetManualHeight( nStartRow, nEndRow, bManual );
+}
+
+
+USHORT ScDocument::GetColWidth( SCCOL nCol, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetColWidth( nCol );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+USHORT ScDocument::GetOriginalWidth( SCCOL nCol, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetOriginalWidth( nCol );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+USHORT ScDocument::GetCommonWidth( SCCOL nEndCol, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetCommonWidth( nEndCol );
+ DBG_ERROR("Wrong table number");
+ return 0;
+}
+
+
+USHORT ScDocument::GetOriginalHeight( SCROW nRow, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetOriginalHeight( nRow );
+ DBG_ERROR("Wrong table number");
+ return 0;
+}
+
+
+USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetRowHeight( nRow, NULL, NULL, bHiddenAsZero );
+ DBG_ERROR("Wrong sheet number");
+ return 0;
+}
+
+
+USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetRowHeight( nRow, pStartRow, pEndRow, bHiddenAsZero );
+ DBG_ERROR("Wrong sheet number");
+ return 0;
+}
+
+
+ULONG ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const
+{
+ if (nStartRow == nEndRow)
+ return GetRowHeight( nStartRow, nTab); // faster for a single row
+
+ // check bounds because this method replaces former for(i=start;i<=end;++i) loops
+ if (nStartRow > nEndRow)
+ return 0;
+
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetRowHeight( nStartRow, nEndRow);
+
+ DBG_ERROR("wrong sheet number");
+ return 0;
+}
+
+SCROW ScDocument::GetRowForHeight( SCTAB nTab, ULONG nHeight ) const
+{
+ return pTab[nTab]->GetRowForHeight(nHeight);
+}
+
+ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
+ SCTAB nTab, double fScale ) const
+{
+ // faster for a single row
+ if (nStartRow == nEndRow)
+ return (ULONG) (GetRowHeight( nStartRow, nTab) * fScale);
+
+ // check bounds because this method replaces former for(i=start;i<=end;++i) loops
+ if (nStartRow > nEndRow)
+ return 0;
+
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetScaledRowHeight( nStartRow, nEndRow, fScale);
+
+ DBG_ERROR("wrong sheet number");
+ return 0;
+}
+
+SCROW ScDocument::GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetHiddenRowCount( nRow );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+ULONG ScDocument::GetColOffset( SCCOL nCol, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetColOffset( nCol );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+ULONG ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetRowOffset( nRow );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+USHORT ScDocument::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula, const ScMarkData* pMarkData,
+ BOOL bSimpleTextImport )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetOptimalColWidth( nCol, pDev, nPPTX, nPPTY,
+ rZoomX, rZoomY, bFormula, pMarkData, bSimpleTextImport );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+long ScDocument::GetNeededSize( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bWidth, BOOL bTotalSize )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetNeededSize
+ ( nCol, nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, bTotalSize );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+
+BOOL ScDocument::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nExtra,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bShrink )
+{
+//! MarkToMulti();
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->SetOptimalHeight( nStartRow, nEndRow, nExtra,
+ pDev, nPPTX, nPPTY, rZoomX, rZoomY, bShrink );
+ DBG_ERROR("Falsche Tabellennummer");
+ return FALSE;
+}
+
+
+void ScDocument::UpdateAllRowHeights( OutputDevice* pDev, double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY, const ScMarkData* pTabMark )
+{
+ // 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] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
+ {
+ pTab[nTab]->SetOptimalHeight( 0, MAXROW, 0,
+ pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE, &aProgress, nProgressStart );
+ nProgressStart += pTab[nTab]->GetWeightedCount();
+ }
+}
+
+
+//
+// Spalten-/Zeilen-Flags ----------------------------------------------
+//
+
+void ScDocument::ShowCol(SCCOL nCol, SCTAB nTab, BOOL bShow)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ShowCol( nCol, bShow );
+}
+
+
+void ScDocument::ShowRow(SCROW nRow, SCTAB nTab, BOOL bShow)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ShowRow( nRow, bShow );
+}
+
+
+void ScDocument::ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, BOOL bShow)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ShowRows( nRow1, nRow2, bShow );
+}
+
+
+void ScDocument::SetColFlags( SCCOL nCol, SCTAB nTab, BYTE nNewFlags )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetColFlags( nCol, nNewFlags );
+}
+
+
+void ScDocument::SetRowFlags( SCROW nRow, SCTAB nTab, BYTE nNewFlags )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRowFlags( nRow, nNewFlags );
+}
+
+
+void ScDocument::SetRowFlags( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BYTE nNewFlags )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRowFlags( nStartRow, nEndRow, nNewFlags );
+}
+
+
+BYTE ScDocument::GetColFlags( SCCOL nCol, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetColFlags( nCol );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+BYTE ScDocument::GetRowFlags( SCROW nRow, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetRowFlags( nRow );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+}
+
+ScBitMaskCompressedArray< SCROW, BYTE> & ScDocument::GetRowFlagsArrayModifiable(
+ SCTAB nTab )
+{
+ return const_cast< ScBitMaskCompressedArray< SCROW, BYTE> & >(
+ GetRowFlagsArray( nTab));
+}
+
+const ScBitMaskCompressedArray< SCROW, BYTE> & ScDocument::GetRowFlagsArray(
+ SCTAB nTab ) const
+{
+ const ScBitMaskCompressedArray< SCROW, BYTE> * pFlags;
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pFlags = pTab[nTab]->GetRowFlagsArray();
+ else
+ {
+ DBG_ERROR("wrong sheet number");
+ pFlags = 0;
+ }
+ if (!pFlags)
+ {
+ DBG_ERROR("no row flags at sheet");
+ static ScBitMaskCompressedArray< SCROW, BYTE> aDummy( MAXROW, 0);
+ pFlags = &aDummy;
+ }
+ return *pFlags;
+}
+
+void ScDocument::GetAllRowBreaks(set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->GetAllRowBreaks(rBreaks, bPage, bManual);
+}
+
+void ScDocument::GetAllColBreaks(set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->GetAllColBreaks(rBreaks, bPage, bManual);
+}
+
+ScBreakType ScDocument::HasRowBreak(SCROW nRow, SCTAB nTab) const
+{
+ ScBreakType nType = BREAK_NONE;
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
+ return nType;
+
+ if (pTab[nTab]->HasRowPageBreak(nRow))
+ nType |= BREAK_PAGE;
+
+ if (pTab[nTab]->HasRowManualBreak(nRow))
+ nType |= BREAK_MANUAL;
+
+ return nType;
+}
+
+ScBreakType ScDocument::HasColBreak(SCCOL nCol, SCTAB nTab) const
+{
+ ScBreakType nType = BREAK_NONE;
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
+ return nType;
+
+ if (pTab[nTab]->HasColPageBreak(nCol))
+ nType |= BREAK_PAGE;
+
+ if (pTab[nTab]->HasColManualBreak(nCol))
+ nType |= BREAK_MANUAL;
+
+ return nType;
+}
+
+void ScDocument::SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
+ return;
+
+ pTab[nTab]->SetRowBreak(nRow, bPage, bManual);
+}
+
+void ScDocument::SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
+ return;
+
+ pTab[nTab]->SetColBreak(nCol, bPage, bManual);
+}
+
+void ScDocument::RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
+ return;
+
+ pTab[nTab]->RemoveRowBreak(nRow, bPage, bManual);
+}
+
+void ScDocument::RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
+ return;
+
+ pTab[nTab]->RemoveColBreak(nCol, bPage, bManual);
+}
+
+Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return Sequence<TablePageBreakData>();
+
+ return pTab[nTab]->GetRowBreakData();
+}
+
+bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->RowHidden(nRow, pFirstRow, pLastRow);
+}
+
+bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW& rLastRow)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ rLastRow = nRow;
+ return false;
+ }
+
+ return pTab[nTab]->RowHidden(nRow, rLastRow);
+}
+
+
+bool ScDocument::HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->HasHiddenRows(nStartRow, nEndRow);
+}
+
+bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL& rLastCol)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ rLastCol = nCol;
+ return false;
+ }
+
+ return pTab[nTab]->ColHidden(nCol, rLastCol);
+}
+
+bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ if (pFirstCol)
+ *pFirstCol = nCol;
+ if (pLastCol)
+ *pLastCol = nCol;
+ return false;
+ }
+
+ return pTab[nTab]->ColHidden(nCol, pFirstCol, pLastCol);
+}
+
+void ScDocument::SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetRowHidden(nStartRow, nEndRow, bHidden);
+}
+
+void ScDocument::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetColHidden(nStartCol, nEndCol, bHidden);
+}
+
+SCROW ScDocument::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->FirstVisibleRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->LastVisibleRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return 0;
+
+ return pTab[nTab]->CountVisibleRows(nStartRow, nEndRow);
+}
+
+bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->RowFiltered(nRow, pFirstRow, pLastRow);
+}
+
+bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->HasFilteredRows(nStartRow, nEndRow);
+}
+
+bool ScDocument::ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->ColFiltered(nCol, pFirstCol, pLastCol);
+}
+
+void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetRowFiltered(nStartRow, nEndRow, bFiltered);
+}
+
+void ScDocument::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bFiltered)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetColFiltered(nStartCol, nEndCol, bFiltered);
+}
+
+SCROW ScDocument::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->FirstNonFilteredRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->LastNonFilteredRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return 0;
+
+ return pTab[nTab]->CountNonFilteredRows(nStartRow, nEndRow);
+}
+
+void ScDocument::SyncColRowFlags()
+{
+ for (SCTAB i = 0; i <= nMaxTableNumber; ++i)
+ {
+ if (!ValidTab(i) || !pTab[i])
+ continue;
+
+ pTab[i]->SyncColRowFlags();
+ }
+}
+
+SCROW ScDocument::GetLastFlaggedRow( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetLastFlaggedRow();
+ return 0;
+}
+
+
+SCCOL ScDocument::GetLastChangedCol( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetLastChangedCol();
+ return 0;
+}
+
+SCROW ScDocument::GetLastChangedRow( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetLastChangedRow();
+ return 0;
+}
+
+
+SCCOL ScDocument::GetNextDifferentChangedCol( SCTAB nTab, SCCOL nStart) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ {
+ BYTE nStartFlags = pTab[nTab]->GetColFlags(nStart);
+ USHORT nStartWidth = pTab[nTab]->GetOriginalWidth(nStart);
+ for (SCCOL nCol = nStart + 1; nCol <= MAXCOL; nCol++)
+ {
+ if (((nStartFlags & CR_MANUALBREAK) != (pTab[nTab]->GetColFlags(nCol) & CR_MANUALBREAK)) ||
+ (nStartWidth != pTab[nTab]->GetOriginalWidth(nCol)) ||
+ ((nStartFlags & CR_HIDDEN) != (pTab[nTab]->GetColFlags(nCol) & CR_HIDDEN)) )
+ return nCol;
+ }
+ return MAXCOL+1;
+ }
+ return 0;
+}
+
+SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCareManualSize) const
+{
+ const ScBitMaskCompressedArray< SCROW, BYTE> * pRowFlagsArray;
+ if ( ValidTab(nTab) && pTab[nTab] && ((pRowFlagsArray = pTab[nTab]->GetRowFlagsArray()) != NULL) &&
+ pTab[nTab]->mpRowHeights && pTab[nTab]->mpHiddenRows )
+ {
+ size_t nIndex; // ignored
+ SCROW nFlagsEndRow;
+ SCROW nHiddenEndRow;
+ SCROW nHeightEndRow;
+ BYTE nFlags;
+ bool bHidden;
+ USHORT nHeight;
+ BYTE nStartFlags = nFlags = pRowFlagsArray->GetValue( nStart, nIndex, nFlagsEndRow);
+ bool bStartHidden = bHidden = pTab[nTab]->RowHidden( nStart, NULL, &nHiddenEndRow);
+ USHORT nStartHeight = nHeight = pTab[nTab]->GetRowHeight( nStart, NULL, &nHeightEndRow, false);
+ SCROW nRow;
+ while ((nRow = std::min( nHiddenEndRow, std::min( nFlagsEndRow, nHeightEndRow)) + 1) <= MAXROW)
+ {
+ if (nFlagsEndRow < nRow)
+ nFlags = pRowFlagsArray->GetValue( nRow, nIndex, nFlagsEndRow);
+ if (nHiddenEndRow < nRow)
+ bHidden = pTab[nTab]->RowHidden( nRow, NULL, &nHiddenEndRow);
+ if (nHeightEndRow < nRow)
+ nHeight = pTab[nTab]->GetRowHeight( nRow, NULL, &nHeightEndRow, false);
+ if ( ((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) ||
+ ((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) ||
+ (bStartHidden != bHidden) ||
+ (bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) ||
+ (!bCareManualSize && ((nStartHeight != nHeight))))
+ return nRow;
+ }
+ return MAXROW+1;
+ }
+ return 0;
+}
+
+BOOL ScDocument::GetColDefault( SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW& nDefault)
+{
+ BOOL bRet(FALSE);
+ nDefault = 0;
+ ScDocAttrIterator aDocAttrItr(this, nTab, nCol, 0, nCol, nLastRow);
+ SCCOL nColumn;
+ SCROW nStartRow;
+ SCROW nEndRow;
+ const ScPatternAttr* pAttr = aDocAttrItr.GetNext(nColumn, nStartRow, nEndRow);
+ if (nEndRow < nLastRow)
+ {
+ ScDefaultAttrSet aSet;
+ ScDefaultAttrSet::iterator aItr = aSet.end();
+ while (pAttr)
+ {
+ ScDefaultAttr aAttr(pAttr);
+ aItr = aSet.find(aAttr);
+ if (aItr == aSet.end())
+ {
+ aAttr.nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
+ aAttr.nFirst = nStartRow;
+ aSet.insert(aAttr);
+ }
+ else
+ {
+ aAttr.nCount = aItr->nCount + static_cast<SCSIZE>(nEndRow - nStartRow + 1);
+ aAttr.nFirst = aItr->nFirst;
+ aSet.erase(aItr);
+ aSet.insert(aAttr);
+ }
+ pAttr = aDocAttrItr.GetNext(nColumn, nStartRow, nEndRow);
+ }
+ ScDefaultAttrSet::iterator aDefaultItr = aSet.begin();
+ aItr = aDefaultItr;
+ aItr++;
+ while (aItr != aSet.end())
+ {
+ // for entries with equal count, use the one with the lowest start row,
+ // don't use the random order of pointer comparisons
+ if ( aItr->nCount > aDefaultItr->nCount ||
+ ( aItr->nCount == aDefaultItr->nCount && aItr->nFirst < aDefaultItr->nFirst ) )
+ aDefaultItr = aItr;
+ aItr++;
+ }
+ nDefault = aDefaultItr->nFirst;
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE;
+ return bRet;
+}
+
+BOOL ScDocument::GetRowDefault( SCTAB /* nTab */, SCROW /* nRow */, SCCOL /* nLastCol */, SCCOL& /* nDefault */ )
+{
+ BOOL bRet(FALSE);
+ return bRet;
+}
+
+void ScDocument::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->StripHidden( rX1, rY1, rX2, rY2 );
+}
+
+
+void ScDocument::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ExtendHidden( rX1, rY1, rX2, rY2 );
+}
+
+//
+// Attribute ----------------------------------------------------------
+//
+
+const SfxPoolItem* ScDocument::GetAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, USHORT nWhich ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ {
+ const SfxPoolItem* pTemp = pTab[nTab]->GetAttr( nCol, nRow, nWhich );
+ if (pTemp)
+ return pTemp;
+ else
+ {
+ DBG_ERROR( "Attribut Null" );
+ }
+ }
+ return &xPoolHelper->GetDocPool()->GetDefaultItem( nWhich );
+}
+
+
+const ScPatternAttr* ScDocument::GetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetPattern( nCol, nRow );
+ return NULL;
+}
+
+
+const ScPatternAttr* ScDocument::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetMostUsedPattern( nCol, nStartRow, nEndRow );
+ return NULL;
+}
+
+
+void ScDocument::ApplyAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem& rAttr )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ApplyAttr( nCol, nRow, rAttr );
+}
+
+
+void ScDocument::ApplyPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->ApplyPattern( nCol, nRow, rAttr );
+}
+
+
+void ScDocument::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark,
+ const ScPatternAttr& rAttr )
+{
+ for (SCTAB i=0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr );
+}
+
+
+void ScDocument::ApplyPatternAreaTab( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr& rAttr )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr );
+}
+
+void ScDocument::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
+ const ScMarkData& rMark, const ScPatternAttr& rPattern, short nNewType )
+{
+ for (SCTAB i=0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
+}
+
+
+void ScDocument::ApplyStyle( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScStyleSheet& rStyle)
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->ApplyStyle( nCol, nRow, rStyle );
+}
+
+
+void ScDocument::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark,
+ const ScStyleSheet& rStyle)
+{
+ for (SCTAB i=0; i <= MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->ApplyStyleArea( nStartCol, nStartRow, nEndCol, nEndRow, rStyle );
+}
+
+
+void ScDocument::ApplyStyleAreaTab( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScStyleSheet& rStyle)
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->ApplyStyleArea( nStartCol, nStartRow, nEndCol, nEndRow, rStyle );
+}
+
+
+void ScDocument::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
+{
+ // ApplySelectionStyle needs multi mark
+ if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ ScRange aRange;
+ rMark.GetMarkArea( aRange );
+ ApplyStyleArea( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rStyle );
+ }
+ else
+ {
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if ( pTab[i] && rMark.GetTableSelect(i) )
+ pTab[i]->ApplySelectionStyle( rStyle, rMark );
+ }
+}
+
+
+void ScDocument::ApplySelectionLineStyle( const ScMarkData& rMark,
+ const SvxBorderLine* pLine, BOOL bColorOnly )
+{
+ if ( bColorOnly && !pLine )
+ return;
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ pTab[i]->ApplySelectionLineStyle( rMark, pLine, bColorOnly );
+}
+
+
+const ScStyleSheet* ScDocument::GetStyle( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ if ( VALIDTAB(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetStyle(nCol, nRow);
+ else
+ return NULL;
+}
+
+
+const ScStyleSheet* ScDocument::GetSelectionStyle( const ScMarkData& rMark ) const
+{
+ BOOL bEqual = TRUE;
+ BOOL bFound;
+
+ const ScStyleSheet* pStyle = NULL;
+ const ScStyleSheet* pNewStyle;
+
+ if ( rMark.IsMultiMarked() )
+ for (SCTAB i=0; i<=MAXTAB && bEqual; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ {
+ pNewStyle = pTab[i]->GetSelectionStyle( rMark, bFound );
+ if (bFound)
+ {
+ if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
+ bEqual = FALSE; // unterschiedliche
+ pStyle = pNewStyle;
+ }
+ }
+ if ( rMark.IsMarked() )
+ {
+ ScRange aRange;
+ rMark.GetMarkArea( aRange );
+ for (SCTAB i=aRange.aStart.Tab(); i<=aRange.aEnd.Tab() && bEqual; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ {
+ pNewStyle = pTab[i]->GetAreaStyle( bFound,
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() );
+ if (bFound)
+ {
+ if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
+ bEqual = FALSE; // unterschiedliche
+ pStyle = pNewStyle;
+ }
+ }
+ }
+
+ return bEqual ? pStyle : NULL;
+}
+
+
+void ScDocument::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRemoved,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY )
+{
+ for (SCTAB i=0; i <= MAXTAB; i++)
+ if (pTab[i])
+ pTab[i]->StyleSheetChanged
+ ( pStyleSheet, bRemoved, pDev, nPPTX, nPPTY, rZoomX, rZoomY );
+
+ if ( pStyleSheet && pStyleSheet->GetName() == ScGlobal::GetRscString(STR_STYLENAME_STANDARD) )
+ {
+ // update attributes for all note objects
+ ScDetectiveFunc::UpdateAllComments( *this );
+ }
+}
+
+
+BOOL ScDocument::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
+{
+ if ( bStyleSheetUsageInvalid || rStyle.GetUsage() == ScStyleSheet::UNKNOWN )
+ {
+ if ( bGatherAllStyles )
+ {
+ SfxStyleSheetIterator aIter( xPoolHelper->GetStylePool(),
+ SFX_STYLE_FAMILY_PARA );
+ for ( const SfxStyleSheetBase* pStyle = aIter.First(); pStyle;
+ pStyle = aIter.Next() )
+ {
+ const ScStyleSheet* pScStyle = PTR_CAST( ScStyleSheet, pStyle );
+ if ( pScStyle )
+ pScStyle->SetUsage( ScStyleSheet::NOTUSED );
+ }
+ }
+
+ BOOL bIsUsed = FALSE;
+
+ for ( SCTAB i=0; i<=MAXTAB; i++ )
+ {
+ if ( pTab[i] )
+ {
+ if ( pTab[i]->IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
+ {
+ if ( !bGatherAllStyles )
+ return TRUE;
+ bIsUsed = TRUE;
+ }
+ }
+ }
+
+ if ( bGatherAllStyles )
+ bStyleSheetUsageInvalid = FALSE;
+
+ return bIsUsed;
+ }
+
+ return rStyle.GetUsage() == ScStyleSheet::USED;
+}
+
+
+BOOL ScDocument::ApplyFlagsTab( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, INT16 nFlags )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->ApplyFlags( nStartCol, nStartRow, nEndCol, nEndRow, nFlags );
+
+ DBG_ERROR("ApplyFlags: falsche Tabelle");
+ return FALSE;
+}
+
+
+BOOL ScDocument::RemoveFlagsTab( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, INT16 nFlags )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->RemoveFlags( nStartCol, nStartRow, nEndCol, nEndRow, nFlags );
+
+ DBG_ERROR("RemoveFlags: falsche Tabelle");
+ return FALSE;
+}
+
+
+void ScDocument::SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr,
+ BOOL bPutToPool )
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ pTab[nTab]->SetPattern( nCol, nRow, rAttr, bPutToPool );
+}
+
+
+void ScDocument::SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr,
+ BOOL bPutToPool )
+{
+ SCTAB nTab = rPos.Tab();
+ if (pTab[nTab])
+ pTab[nTab]->SetPattern( rPos, rAttr, bPutToPool );
+}
+
+
+ScPatternAttr* ScDocument::CreateSelectionPattern( const ScMarkData& rMark, BOOL bDeep )
+{
+ ScMergePatternState aState;
+
+ if ( rMark.IsMultiMarked() ) // multi selection
+ {
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->MergeSelectionPattern( aState, rMark, bDeep );
+ }
+ if ( rMark.IsMarked() ) // simle selection
+ {
+ ScRange aRange;
+ rMark.GetMarkArea(aRange);
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->MergePatternArea( aState,
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), bDeep );
+ }
+
+ DBG_ASSERT( aState.pItemSet, "SelectionPattern Null" );
+ if (aState.pItemSet)
+ return new ScPatternAttr( aState.pItemSet );
+ else
+ return new ScPatternAttr( GetPool() ); // empty
+}
+
+
+const ScPatternAttr* ScDocument::GetSelectionPattern( const ScMarkData& rMark, BOOL bDeep )
+{
+ delete pSelectionAttr;
+ pSelectionAttr = CreateSelectionPattern( rMark, bDeep );
+ return pSelectionAttr;
+}
+
+
+void ScDocument::GetSelectionFrame( const ScMarkData& rMark,
+ SvxBoxItem& rLineOuter,
+ SvxBoxInfoItem& rLineInner )
+{
+ rLineOuter.SetLine(NULL, BOX_LINE_TOP);
+ rLineOuter.SetLine(NULL, BOX_LINE_BOTTOM);
+ rLineOuter.SetLine(NULL, BOX_LINE_LEFT);
+ rLineOuter.SetLine(NULL, BOX_LINE_RIGHT);
+ rLineOuter.SetDistance(0);
+
+ rLineInner.SetLine(NULL, BOXINFO_LINE_HORI);
+ rLineInner.SetLine(NULL, BOXINFO_LINE_VERT);
+ rLineInner.SetTable(TRUE);
+ rLineInner.SetDist(TRUE);
+ rLineInner.SetMinDist(FALSE);
+
+ ScLineFlags aFlags;
+
+ if (rMark.IsMarked())
+ {
+ ScRange aRange;
+ rMark.GetMarkArea(aRange);
+ rLineInner.EnableHor( aRange.aStart.Row() != aRange.aEnd.Row() );
+ rLineInner.EnableVer( aRange.aStart.Col() != aRange.aEnd.Col() );
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->MergeBlockFrame( &rLineOuter, &rLineInner, aFlags,
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() );
+ }
+
+ // Don't care Status auswerten
+
+ rLineInner.SetValid( VALID_LEFT, ( aFlags.nLeft != SC_LINE_DONTCARE ) );
+ rLineInner.SetValid( VALID_RIGHT, ( aFlags.nRight != SC_LINE_DONTCARE ) );
+ rLineInner.SetValid( VALID_TOP, ( aFlags.nTop != SC_LINE_DONTCARE ) );
+ rLineInner.SetValid( VALID_BOTTOM, ( aFlags.nBottom != SC_LINE_DONTCARE ) );
+ rLineInner.SetValid( VALID_HORI, ( aFlags.nHori != SC_LINE_DONTCARE ) );
+ rLineInner.SetValid( VALID_VERT, ( aFlags.nVert != SC_LINE_DONTCARE ) );
+}
+
+
+bool ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask )
+{
+ if ( nMask & HASATTR_ROTATE )
+ {
+ // Attribut im Dokument ueberhaupt verwendet?
+ // (wie in fillinfo)
+
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+
+ BOOL bAnyItem = FALSE;
+ USHORT nRotCount = pPool->GetItemCount( ATTR_ROTATE_VALUE );
+ for (USHORT nItem=0; nItem<nRotCount; nItem++)
+ {
+ const SfxPoolItem* pItem = pPool->GetItem( ATTR_ROTATE_VALUE, nItem );
+ if ( pItem )
+ {
+ // 90 or 270 degrees is former SvxOrientationItem - only look for other values
+ // (see ScPatternAttr::GetCellOrientation)
+ INT32 nAngle = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 )
+ {
+ bAnyItem = TRUE;
+ break;
+ }
+ }
+ }
+ if (!bAnyItem)
+ nMask &= ~HASATTR_ROTATE;
+ }
+
+ if ( nMask & HASATTR_RTL )
+ {
+ // first check if right-to left is in the pool at all
+ // (the same item is used in cell and page format)
+
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+
+ BOOL bHasRtl = FALSE;
+ USHORT nDirCount = pPool->GetItemCount( ATTR_WRITINGDIR );
+ for (USHORT nItem=0; nItem<nDirCount; nItem++)
+ {
+ const SfxPoolItem* pItem = pPool->GetItem( ATTR_WRITINGDIR, nItem );
+ if ( pItem && ((const SvxFrameDirectionItem*)pItem)->GetValue() == FRMDIR_HORI_RIGHT_TOP )
+ {
+ bHasRtl = TRUE;
+ break;
+ }
+ }
+ if (!bHasRtl)
+ nMask &= ~HASATTR_RTL;
+ }
+
+ if (!nMask)
+ return false;
+
+ bool bFound = false;
+ for (SCTAB i=nTab1; i<=nTab2 && !bFound; i++)
+ if (pTab[i])
+ {
+ if ( nMask & HASATTR_RTL )
+ {
+ if ( GetEditTextDirection(i) == EE_HTEXTDIR_R2L ) // sheet default
+ bFound = true;
+ }
+ if ( nMask & HASATTR_RIGHTORCENTER )
+ {
+ // On a RTL sheet, don't start to look for the default left value
+ // (which is then logically right), instead always assume TRUE.
+ // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
+
+ if ( IsLayoutRTL(i) )
+ bFound = true;
+ }
+
+ if ( !bFound )
+ bFound = pTab[i]->HasAttrib( nCol1, nRow1, nCol2, nRow2, nMask );
+ }
+
+ return bFound;
+}
+
+bool ScDocument::HasAttrib( const ScRange& rRange, USHORT nMask )
+{
+ return HasAttrib( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(),
+ nMask );
+}
+
+void ScDocument::FindMaxRotCol( SCTAB nTab, RowInfo* pRowInfo, SCSIZE nArrCount,
+ SCCOL nX1, SCCOL nX2 ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->FindMaxRotCol( pRowInfo, nArrCount, nX1, nX2 );
+ else
+ {
+ DBG_ERRORFILE("FindMaxRotCol: falsche Tabelle");
+ }
+}
+
+void ScDocument::GetBorderLines( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop,
+ const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const
+{
+ //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
+
+ const SvxBoxItem* pThisAttr = (const SvxBoxItem*) GetEffItem( nCol, nRow, nTab, ATTR_BORDER );
+ DBG_ASSERT(pThisAttr,"wo ist das Attribut?");
+
+ const SvxBorderLine* pLeftLine = pThisAttr->GetLeft();
+ const SvxBorderLine* pTopLine = pThisAttr->GetTop();
+ const SvxBorderLine* pRightLine = pThisAttr->GetRight();
+ const SvxBorderLine* pBottomLine = pThisAttr->GetBottom();
+
+ if ( nCol > 0 )
+ {
+ const SvxBorderLine* pOther = ((const SvxBoxItem*)
+ GetEffItem( nCol-1, nRow, nTab, ATTR_BORDER ))->GetRight();
+ if ( ScHasPriority( pOther, pLeftLine ) )
+ pLeftLine = pOther;
+ }
+ if ( nRow > 0 )
+ {
+ const SvxBorderLine* pOther = ((const SvxBoxItem*)
+ GetEffItem( nCol, nRow-1, nTab, ATTR_BORDER ))->GetBottom();
+ if ( ScHasPriority( pOther, pTopLine ) )
+ pTopLine = pOther;
+ }
+ if ( nCol < MAXCOL )
+ {
+ const SvxBorderLine* pOther = ((const SvxBoxItem*)
+ GetEffItem( nCol+1, nRow, nTab, ATTR_BORDER ))->GetLeft();
+ if ( ScHasPriority( pOther, pRightLine ) )
+ pRightLine = pOther;
+ }
+ if ( nRow < MAXROW )
+ {
+ const SvxBorderLine* pOther = ((const SvxBoxItem*)
+ GetEffItem( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
+ if ( ScHasPriority( pOther, pBottomLine ) )
+ pBottomLine = pOther;
+ }
+
+ if (ppLeft)
+ *ppLeft = pLeftLine;
+ if (ppTop)
+ *ppTop = pTopLine;
+ if (ppRight)
+ *ppRight = pRightLine;
+ if (ppBottom)
+ *ppBottom = pBottomLine;
+}
+
+BOOL ScDocument::IsBlockEmpty( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, bool bIgnoreNotes ) const
+{
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->IsBlockEmpty( nStartCol, nStartRow, nEndCol, nEndRow, bIgnoreNotes );
+
+ DBG_ERROR("Falsche Tabellennummer");
+ return FALSE;
+}
+
+
+void ScDocument::LockTable(SCTAB nTab)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->LockTable();
+ else
+ {
+ DBG_ERROR("Falsche Tabellennummer");
+ }
+}
+
+
+void ScDocument::UnlockTable(SCTAB nTab)
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->UnlockTable();
+ else
+ {
+ DBG_ERROR("Falsche Tabellennummer");
+ }
+}
+
+
+BOOL ScDocument::IsBlockEditable( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow,
+ BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
+{
+ // import into read-only document is possible
+ if ( !bImportingXML && !mbChangeReadOnlyEnabled && pShell && pShell->IsReadOnly() )
+ {
+ if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ return FALSE;
+ }
+
+ if (VALIDTAB(nTab))
+ if (pTab[nTab])
+ return pTab[nTab]->IsBlockEditable( nStartCol, nStartRow, nEndCol,
+ nEndRow, pOnlyNotBecauseOfMatrix );
+
+ DBG_ERROR("Falsche Tabellennummer");
+ if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ return FALSE;
+}
+
+
+BOOL ScDocument::IsSelectionEditable( const ScMarkData& rMark,
+ BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
+{
+ // import into read-only document is possible
+ if ( !bImportingXML && !mbChangeReadOnlyEnabled && pShell && pShell->IsReadOnly() )
+ {
+ if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ return FALSE;
+ }
+
+ ScRange aRange;
+ rMark.GetMarkArea(aRange);
+
+ BOOL bOk = TRUE;
+ BOOL bMatrix = ( pOnlyNotBecauseOfMatrix != NULL );
+ for ( SCTAB i=0; i<=MAXTAB && (bOk || bMatrix); i++ )
+ {
+ if ( pTab[i] && rMark.GetTableSelect(i) )
+ {
+ if (rMark.IsMarked())
+ {
+ if ( !pTab[i]->IsBlockEditable( aRange.aStart.Col(),
+ aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aEnd.Row(), pOnlyNotBecauseOfMatrix ) )
+ {
+ bOk = FALSE;
+ if ( pOnlyNotBecauseOfMatrix )
+ bMatrix = *pOnlyNotBecauseOfMatrix;
+ }
+ }
+ if (rMark.IsMultiMarked())
+ {
+ if ( !pTab[i]->IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix ) )
+ {
+ bOk = FALSE;
+ if ( pOnlyNotBecauseOfMatrix )
+ bMatrix = *pOnlyNotBecauseOfMatrix;
+ }
+ }
+ }
+ }
+
+ if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = ( !bOk && bMatrix );
+
+ return bOk;
+}
+
+
+BOOL ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark ) const
+{
+ BOOL bOk = TRUE;
+ for (SCTAB i=0; i<=MAXTAB && bOk; i++)
+ if (pTab[i])
+ if (rMark.GetTableSelect(i))
+ if (pTab[i]->HasBlockMatrixFragment( nStartCol, nStartRow, nEndCol, nEndRow ))
+ bOk = FALSE;
+
+ return !bOk;
+}
+
+
+BOOL ScDocument::GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix )
+{
+ // if rCell is part of a matrix formula, return its complete range
+
+ BOOL bRet = FALSE;
+ ScBaseCell* pCell = GetCell( rCellPos );
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScAddress aOrigin = rCellPos;
+ if ( ((ScFormulaCell*)pCell)->GetMatrixOrigin( aOrigin ) )
+ {
+ if ( aOrigin != rCellPos )
+ pCell = GetCell( aOrigin );
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ SCCOL nSizeX;
+ SCROW nSizeY;
+ ((ScFormulaCell*)pCell)->GetMatColsRows(nSizeX,nSizeY);
+ if ( !(nSizeX > 0 && nSizeY > 0) )
+ {
+ // GetMatrixEdge computes also dimensions of the matrix
+ // if not already done (may occur if document is loaded
+ // from old file format).
+ // Needs an "invalid" initialized address.
+ aOrigin.SetInvalid();
+ ((ScFormulaCell*)pCell)->GetMatrixEdge(aOrigin);
+ ((ScFormulaCell*)pCell)->GetMatColsRows(nSizeX,nSizeY);
+ }
+ if ( nSizeX > 0 && nSizeY > 0 )
+ {
+ ScAddress aEnd( aOrigin.Col() + nSizeX - 1,
+ aOrigin.Row() + nSizeY - 1,
+ aOrigin.Tab() );
+
+ rMatrix.aStart = aOrigin;
+ rMatrix.aEnd = aEnd;
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+
+BOOL ScDocument::ExtendOverlapped( SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
+{
+ BOOL bFound = FALSE;
+ if ( ValidColRow(rStartCol,rStartRow) && ValidColRow(nEndCol,nEndRow) && ValidTab(nTab) )
+ {
+ if (pTab[nTab])
+ {
+ SCCOL nCol;
+ SCCOL nOldCol = rStartCol;
+ SCROW nOldRow = rStartRow;
+ for (nCol=nOldCol; nCol<=nEndCol; nCol++)
+ while (((ScMergeFlagAttr*)GetAttr(nCol,rStartRow,nTab,ATTR_MERGE_FLAG))->
+ IsVerOverlapped())
+ --rStartRow;
+
+ //! weiterreichen ?
+
+ ScAttrArray* pAttrArray = pTab[nTab]->aCol[nOldCol].pAttrArray;
+ SCSIZE nIndex;
+ pAttrArray->Search( nOldRow, nIndex );
+ SCROW nAttrPos = nOldRow;
+ while (nAttrPos<=nEndRow)
+ {
+ DBG_ASSERT( nIndex < pAttrArray->nCount, "Falscher Index im AttrArray" );
+
+ if (((ScMergeFlagAttr&)pAttrArray->pData[nIndex].pPattern->
+ GetItem(ATTR_MERGE_FLAG)).IsHorOverlapped())
+ {
+ SCROW nLoopEndRow = Min( nEndRow, pAttrArray->pData[nIndex].nRow );
+ for (SCROW nAttrRow = nAttrPos; nAttrRow <= nLoopEndRow; nAttrRow++)
+ {
+ SCCOL nTempCol = nOldCol;
+ do
+ --nTempCol;
+ while (((ScMergeFlagAttr*)GetAttr(nTempCol,nAttrRow,nTab,ATTR_MERGE_FLAG))
+ ->IsHorOverlapped());
+ if (nTempCol < rStartCol)
+ rStartCol = nTempCol;
+ }
+ }
+ nAttrPos = pAttrArray->pData[nIndex].nRow + 1;
+ ++nIndex;
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("ExtendOverlapped: falscher Bereich");
+ }
+
+ return bFound;
+}
+
+
+BOOL ScDocument::ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow,
+ const ScMarkData& rMark, BOOL bRefresh, BOOL bAttrs )
+{
+ // use all selected sheets from rMark
+
+ BOOL bFound = FALSE;
+ SCCOL nOldEndCol = rEndCol;
+ SCROW nOldEndRow = rEndRow;
+
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if ( pTab[nTab] && rMark.GetTableSelect(nTab) )
+ {
+ SCCOL nThisEndCol = nOldEndCol;
+ SCROW nThisEndRow = nOldEndRow;
+ if ( ExtendMerge( nStartCol, nStartRow, nThisEndCol, nThisEndRow, nTab, bRefresh, bAttrs ) )
+ bFound = TRUE;
+ if ( nThisEndCol > rEndCol )
+ rEndCol = nThisEndCol;
+ if ( nThisEndRow > rEndRow )
+ rEndRow = nThisEndRow;
+ }
+
+ return bFound;
+}
+
+
+BOOL ScDocument::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow,
+ SCTAB nTab, BOOL bRefresh, BOOL bAttrs )
+{
+ BOOL bFound = FALSE;
+ if ( ValidColRow(nStartCol,nStartRow) && ValidColRow(rEndCol,rEndRow) && ValidTab(nTab) )
+ {
+ if (pTab[nTab])
+ bFound = pTab[nTab]->ExtendMerge( nStartCol, nStartRow, rEndCol, rEndRow, bRefresh, bAttrs );
+
+ if (bRefresh)
+ RefreshAutoFilter( nStartCol, nStartRow, rEndCol, rEndRow, nTab );
+ }
+ else
+ {
+ DBG_ERROR("ExtendMerge: falscher Bereich");
+ }
+
+ return bFound;
+}
+
+
+BOOL ScDocument::ExtendMerge( ScRange& rRange, BOOL bRefresh, BOOL bAttrs )
+{
+ BOOL bFound = FALSE;
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+
+ PutInOrder( nStartTab, nEndTab );
+ for (SCTAB nTab = nStartTab; nTab <= nEndTab; nTab++ )
+ {
+ SCCOL nExtendCol = rRange.aEnd.Col();
+ SCROW nExtendRow = rRange.aEnd.Row();
+ if (ExtendMerge( rRange.aStart.Col(), rRange.aStart.Row(),
+ nExtendCol, nExtendRow,
+ nTab, bRefresh, bAttrs ) )
+ {
+ bFound = TRUE;
+ if (nExtendCol > nEndCol) nEndCol = nExtendCol;
+ if (nExtendRow > nEndRow) nEndRow = nExtendRow;
+ }
+ }
+
+ rRange.aEnd.SetCol(nEndCol);
+ rRange.aEnd.SetRow(nEndRow);
+
+ return bFound;
+}
+
+BOOL ScDocument::ExtendTotalMerge( ScRange& rRange )
+{
+ // Bereich genau dann auf zusammengefasste Zellen erweitern, wenn
+ // dadurch keine neuen nicht-ueberdeckten Zellen getroffen werden
+
+ BOOL bRet = FALSE;
+ ScRange aExt = rRange;
+ if (ExtendMerge(aExt))
+ {
+ if ( aExt.aEnd.Row() > rRange.aEnd.Row() )
+ {
+ ScRange aTest = aExt;
+ aTest.aStart.SetRow( rRange.aEnd.Row() + 1 );
+ if ( HasAttrib( aTest, HASATTR_NOTOVERLAPPED ) )
+ aExt.aEnd.SetRow(rRange.aEnd.Row());
+ }
+ if ( aExt.aEnd.Col() > rRange.aEnd.Col() )
+ {
+ ScRange aTest = aExt;
+ aTest.aStart.SetCol( rRange.aEnd.Col() + 1 );
+ if ( HasAttrib( aTest, HASATTR_NOTOVERLAPPED ) )
+ aExt.aEnd.SetCol(rRange.aEnd.Col());
+ }
+
+ bRet = ( aExt.aEnd != rRange.aEnd );
+ rRange = aExt;
+ }
+ return bRet;
+}
+
+BOOL ScDocument::ExtendOverlapped( ScRange& rRange )
+{
+ BOOL bFound = FALSE;
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+
+ PutInOrder( nStartTab, nEndTab );
+ for (SCTAB nTab = nStartTab; nTab <= nEndTab; nTab++ )
+ {
+ SCCOL nExtendCol = rRange.aStart.Col();
+ SCROW nExtendRow = rRange.aStart.Row();
+ ExtendOverlapped( nExtendCol, nExtendRow,
+ rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
+ if (nExtendCol < nStartCol)
+ {
+ nStartCol = nExtendCol;
+ bFound = TRUE;
+ }
+ if (nExtendRow < nStartRow)
+ {
+ nStartRow = nExtendRow;
+ bFound = TRUE;
+ }
+ }
+
+ rRange.aStart.SetCol(nStartCol);
+ rRange.aStart.SetRow(nStartRow);
+
+ return bFound;
+}
+
+BOOL ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
+{
+ USHORT nCount = pDBCollection->GetCount();
+ USHORT i;
+ ScDBData* pData;
+ SCTAB nDBTab;
+ SCCOL nDBStartCol;
+ SCROW nDBStartRow;
+ SCCOL nDBEndCol;
+ SCROW nDBEndRow;
+
+ // Autofilter loeschen
+
+ BOOL bChange = RemoveFlagsTab( nStartCol,nStartRow, nEndCol,nEndRow, nTab, SC_MF_AUTO );
+
+ // Autofilter setzen
+
+ for (i=0; i<nCount; i++)
+ {
+ pData = (*pDBCollection)[i];
+ if (pData->HasAutoFilter())
+ {
+ pData->GetArea( nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow );
+ if ( nDBTab==nTab && nDBStartRow<=nEndRow && nDBEndRow>=nStartRow &&
+ nDBStartCol<=nEndCol && nDBEndCol>=nStartCol )
+ {
+ if (ApplyFlagsTab( nDBStartCol,nDBStartRow, nDBEndCol,nDBStartRow,
+ nDBTab, SC_MF_AUTO ))
+ bChange = TRUE;
+ }
+ }
+ }
+ return bChange;
+}
+
+
+BOOL ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ const ScMergeFlagAttr* pAttr = (const ScMergeFlagAttr*)
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG );
+ if (pAttr)
+ return pAttr->IsHorOverlapped();
+ else
+ {
+ DBG_ERROR("Overlapped: Attr==0");
+ return FALSE;
+ }
+}
+
+
+BOOL ScDocument::IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ const ScMergeFlagAttr* pAttr = (const ScMergeFlagAttr*)
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG );
+ if (pAttr)
+ return pAttr->IsVerOverlapped();
+ else
+ {
+ DBG_ERROR("Overlapped: Attr==0");
+ return FALSE;
+ }
+}
+
+
+void ScDocument::ApplySelectionFrame( const ScMarkData& rMark,
+ const SvxBoxItem* pLineOuter,
+ const SvxBoxInfoItem* pLineInner )
+{
+ ScRangeList aRangeList;
+ rMark.FillRangeListWithMarks( &aRangeList, FALSE );
+ ULONG nRangeCount = aRangeList.Count();
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ {
+ 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() );
+ }
+ }
+ }
+}
+
+
+void ScDocument::ApplyFrameAreaTab( const ScRange& rRange,
+ const SvxBoxItem* pLineOuter,
+ const SvxBoxInfoItem* pLineInner )
+{
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCTAB nEndTab = rRange.aStart.Tab();
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ if (pTab[nTab])
+ pTab[nTab]->ApplyBlockFrame( pLineOuter, pLineInner,
+ rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row() );
+}
+
+
+void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark )
+{
+ const SfxItemSet* pSet = &rAttr.GetItemSet();
+ BOOL bSet = FALSE;
+ USHORT i;
+ for (i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END && !bSet; i++)
+ if (pSet->GetItemState(i) == SFX_ITEM_SET)
+ bSet = TRUE;
+
+ if (bSet)
+ {
+ // ApplySelectionCache needs multi mark
+ if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ ScRange aRange;
+ rMark.GetMarkArea( aRange );
+ ApplyPatternArea( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rAttr );
+ }
+ else
+ {
+ SfxItemPoolCache aCache( xPoolHelper->GetDocPool(), pSet );
+ for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
+ if (pTab[nTab])
+ if (rMark.GetTableSelect(nTab))
+ pTab[nTab]->ApplySelectionCache( &aCache, rMark );
+ }
+ }
+}
+
+
+void ScDocument::ChangeSelectionIndent( BOOL bIncrement, const ScMarkData& rMark )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->ChangeSelectionIndent( bIncrement, rMark );
+}
+
+
+void ScDocument::ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->ClearSelectionItems( pWhich, rMark );
+}
+
+
+void ScDocument::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTab[i] && rMark.GetTableSelect(i))
+ pTab[i]->DeleteSelection( nDelFlag, rMark );
+}
+
+
+void ScDocument::DeleteSelectionTab( SCTAB nTab, USHORT nDelFlag, const ScMarkData& rMark )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->DeleteSelection( nDelFlag, rMark );
+ else
+ {
+ DBG_ERROR("Falsche Tabelle");
+ }
+}
+
+
+ScPatternAttr* ScDocument::GetDefPattern() const
+{
+ return (ScPatternAttr*) &xPoolHelper->GetDocPool()->GetDefaultItem(ATTR_PATTERN);
+}
+
+
+ScDocumentPool* ScDocument::GetPool()
+{
+ return xPoolHelper->GetDocPool();
+}
+
+
+
+ScStyleSheetPool* ScDocument::GetStyleSheetPool() const
+{
+ return xPoolHelper->GetStylePool();
+}
+
+
+SCSIZE ScDocument::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir )
+{
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ PutInOrder(nStartTab, nEndTab);
+ if (VALIDTAB(nStartTab))
+ {
+ if (pTab[nStartTab])
+ return pTab[nStartTab]->GetEmptyLinesInBlock(nStartCol, nStartRow, nEndCol, nEndRow, eDir);
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+
+void ScDocument::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCsCOL nMovX, SCsROW nMovY )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->FindAreaPos( rCol, rRow, nMovX, nMovY );
+}
+
+
+void ScDocument::GetNextPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCsCOL nMovX, SCsROW nMovY,
+ BOOL bMarked, BOOL bUnprotected, const ScMarkData& rMark )
+{
+ DBG_ASSERT( !nMovX || !nMovY, "GetNextPos: nur X oder Y" );
+
+ ScMarkData aCopyMark = rMark;
+ aCopyMark.SetMarking(FALSE);
+ aCopyMark.MarkToMulti();
+
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->GetNextPos( rCol, rRow, nMovX, nMovY, bMarked, bUnprotected, aCopyMark );
+}
+
+//
+// Datei-Operationen
+//
+
+
+void ScDocument::UpdStlShtPtrsFrmNms()
+{
+ ScPatternAttr::pDoc = this;
+
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+
+ USHORT nCount = pPool->GetItemCount(ATTR_PATTERN);
+ ScPatternAttr* pPattern;
+ for (USHORT i=0; i<nCount; i++)
+ {
+ pPattern = (ScPatternAttr*)pPool->GetItem(ATTR_PATTERN, i);
+ if (pPattern)
+ pPattern->UpdateStyleSheet();
+ }
+ ((ScPatternAttr&)pPool->GetDefaultItem(ATTR_PATTERN)).UpdateStyleSheet();
+}
+
+
+void ScDocument::StylesToNames()
+{
+ ScPatternAttr::pDoc = this;
+
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+
+ USHORT nCount = pPool->GetItemCount(ATTR_PATTERN);
+ ScPatternAttr* pPattern;
+ for (USHORT i=0; i<nCount; i++)
+ {
+ pPattern = (ScPatternAttr*)pPool->GetItem(ATTR_PATTERN, i);
+ if (pPattern)
+ pPattern->StyleToName();
+ }
+ ((ScPatternAttr&)pPool->GetDefaultItem(ATTR_PATTERN)).StyleToName();
+}
+
+
+ULONG ScDocument::GetCellCount() const
+{
+ ULONG nCellCount = 0L;
+
+ for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
+ if ( pTab[nTab] )
+ nCellCount += pTab[nTab]->GetCellCount();
+
+ return nCellCount;
+}
+
+SCSIZE ScDocument::GetCellCount(SCTAB nTab, SCCOL nCol) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return 0;
+
+ return pTab[nTab]->GetCellCount(nCol);
+}
+
+ULONG ScDocument::GetCodeCount() const
+{
+ ULONG nCodeCount = 0;
+
+ for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
+ if ( pTab[nTab] )
+ nCodeCount += pTab[nTab]->GetCodeCount();
+
+ return nCodeCount;
+}
+
+
+ULONG ScDocument::GetWeightedCount() const
+{
+ ULONG nCellCount = 0L;
+
+ for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
+ if ( pTab[nTab] )
+ nCellCount += pTab[nTab]->GetWeightedCount();
+
+ return nCellCount;
+}
+
+
+void ScDocument::PageStyleModified( SCTAB nTab, const String& rNewName )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->PageStyleModified( rNewName );
+}
+
+
+void ScDocument::SetPageStyle( SCTAB nTab, const String& rName )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetPageStyle( rName );
+}
+
+
+const String& ScDocument::GetPageStyle( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetPageStyle();
+
+ return EMPTY_STRING;
+}
+
+
+void ScDocument::SetPageSize( SCTAB nTab, const Size& rSize )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetPageSize( rSize );
+}
+
+Size ScDocument::GetPageSize( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetPageSize();
+
+ DBG_ERROR("falsche Tab");
+ return Size();
+}
+
+
+void ScDocument::SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRepeatArea( nStartCol, nEndCol, nStartRow, nEndRow );
+}
+
+void ScDocument::InvalidatePageBreaks(SCTAB nTab)
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->InvalidatePageBreaks();
+}
+
+void ScDocument::UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->UpdatePageBreaks( pUserArea );
+}
+
+void ScDocument::RemoveManualBreaks( SCTAB nTab )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->RemoveManualBreaks();
+}
+
+BOOL ScDocument::HasManualBreaks( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->HasManualBreaks();
+
+ DBG_ERROR("falsche Tab");
+ return FALSE;
+}
+
+
+void ScDocument::GetDocStat( ScDocStat& rDocStat )
+{
+ rDocStat.nTableCount = GetTableCount();
+ rDocStat.aDocName = aDocName;
+ rDocStat.nCellCount = GetCellCount();
+}
+
+
+BOOL ScDocument::HasPrintRange()
+{
+ BOOL bResult = FALSE;
+
+ for ( SCTAB i=0; !bResult && i<nMaxTableNumber; i++ )
+ if ( pTab[i] )
+ bResult = pTab[i]->IsPrintEntireSheet() || (pTab[i]->GetPrintRangeCount() > 0);
+
+ return bResult;
+}
+
+
+BOOL ScDocument::IsPrintEntireSheet( SCTAB nTab ) const
+{
+ return (ValidTab(nTab) ) && pTab[nTab] && pTab[nTab]->IsPrintEntireSheet();
+}
+
+
+USHORT ScDocument::GetPrintRangeCount( SCTAB nTab )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetPrintRangeCount();
+
+ return 0;
+}
+
+
+const ScRange* ScDocument::GetPrintRange( SCTAB nTab, USHORT nPos )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetPrintRange(nPos);
+
+ return NULL;
+}
+
+
+const ScRange* ScDocument::GetRepeatColRange( SCTAB nTab )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetRepeatColRange();
+
+ return NULL;
+}
+
+
+const ScRange* ScDocument::GetRepeatRowRange( SCTAB nTab )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetRepeatRowRange();
+
+ return NULL;
+}
+
+
+void ScDocument::ClearPrintRanges( SCTAB nTab )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->ClearPrintRanges();
+}
+
+
+void ScDocument::AddPrintRange( SCTAB nTab, const ScRange& rNew )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->AddPrintRange( rNew );
+}
+
+
+//UNUSED2009-05 void ScDocument::SetPrintRange( SCTAB nTab, const ScRange& rNew )
+//UNUSED2009-05 {
+//UNUSED2009-05 if (ValidTab(nTab) && pTab[nTab])
+//UNUSED2009-05 pTab[nTab]->SetPrintRange( rNew );
+//UNUSED2009-05 }
+
+
+void ScDocument::SetPrintEntireSheet( SCTAB nTab )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetPrintEntireSheet();
+}
+
+
+void ScDocument::SetRepeatColRange( SCTAB nTab, const ScRange* pNew )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetRepeatColRange( pNew );
+}
+
+
+void ScDocument::SetRepeatRowRange( SCTAB nTab, const ScRange* pNew )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetRepeatRowRange( pNew );
+}
+
+
+ScPrintRangeSaver* ScDocument::CreatePrintRangeSaver() const
+{
+ SCTAB nCount = GetTableCount();
+ ScPrintRangeSaver* pNew = new ScPrintRangeSaver( nCount );
+ for (SCTAB i=0; i<nCount; i++)
+ if (pTab[i])
+ pTab[i]->FillPrintSaver( pNew->GetTabData(i) );
+ return pNew;
+}
+
+
+void ScDocument::RestorePrintRanges( const ScPrintRangeSaver& rSaver )
+{
+ SCTAB nCount = rSaver.GetTabCount();
+ for (SCTAB i=0; i<nCount; i++)
+ if (pTab[i])
+ pTab[i]->RestorePrintRanges( rSaver.GetTabData(i) );
+}
+
+
+BOOL ScDocument::NeedPageResetAfterTab( SCTAB nTab ) const
+{
+ // Die Seitennummern-Zaehlung faengt bei einer Tabelle neu an, wenn eine
+ // andere Vorlage als bei der vorherigen gesetzt ist (nur Namen vergleichen)
+ // und eine Seitennummer angegeben ist (nicht 0)
+
+ if ( nTab < MAXTAB && pTab[nTab] && pTab[nTab+1] )
+ {
+ String aNew = pTab[nTab+1]->GetPageStyle();
+ if ( aNew != pTab[nTab]->GetPageStyle() )
+ {
+ SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aNew, SFX_STYLE_FAMILY_PAGE );
+ if ( pStyle )
+ {
+ const SfxItemSet& rSet = pStyle->GetItemSet();
+ USHORT nFirst = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_FIRSTPAGENO)).GetValue();
+ if ( nFirst != 0 )
+ return TRUE; // Seitennummer in neuer Vorlage angegeben
+ }
+ }
+ }
+
+ return FALSE; // sonst nicht
+}
+
+SfxUndoManager* ScDocument::GetUndoManager()
+{
+ if (!mpUndoManager)
+ mpUndoManager = new SfxUndoManager;
+ return mpUndoManager;
+}
+
+ScRowBreakIterator* ScDocument::GetRowBreakIterator(SCTAB nTab) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return new ScRowBreakIterator(pTab[nTab]->maRowPageBreaks);
+ return NULL;
+}
+
+void ScDocument::EnableUndo( bool bVal )
+{
+ GetUndoManager()->EnableUndo(bVal);
+ mbUndoEnabled = bVal;
+}
+
+bool ScDocument::IsInVBAMode() const
+{
+ bool bResult = false;
+ if ( pShell )
+ {
+ com::sun::star::uno::Reference< com::sun::star::script::vba::XVBACompatibility > xVBA( pShell->GetBasicContainer(), com::sun::star::uno::UNO_QUERY );
+ bResult = xVBA.is() && xVBA->getVBACompatibilityMode();
+ }
+ return bResult;
+}
diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx
new file mode 100644
index 000000000000..d97900e6b904
--- /dev/null
+++ b/sc/source/core/data/dpcachetable.cxx
@@ -0,0 +1,468 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpcachetable.hxx"
+#include "document.hxx"
+#include "address.hxx"
+#include "cell.hxx"
+#include "dptabdat.hxx"
+#include "dptabsrc.hxx"
+#include "dpobject.hxx"
+#include "queryparam.hxx"
+
+#include <com/sun/star/i18n/LocaleDataItem.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::std::vector;
+using ::std::pair;
+using ::std::hash_map;
+using ::std::hash_set;
+using ::std::auto_ptr;
+using ::com::sun::star::i18n::LocaleDataItem;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::sheet::DataPilotFieldFilter;
+
+
+static BOOL lcl_HasQueryEntry( const ScQueryParam& rParam )
+{
+ return rParam.GetEntryCount() > 0 &&
+ rParam.GetEntry(0).bDoQuery;
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPCacheTable::FilterItem::FilterItem() :
+ mfValue(0.0),
+ mbHasValue(false)
+{
+}
+bool ScDPCacheTable::FilterItem::match( const ScDPItemData& rCellData ) const
+{
+ if (rCellData.GetString()!= maString &&
+ (!rCellData.IsValue()|| rCellData.GetValue()!= mfValue))
+ return false;
+ return true;
+}
+// ----------------------------------------------------------------------------
+
+ScDPCacheTable::SingleFilter::SingleFilter(String aString, double fValue, bool bHasValue)
+{
+ maItem.maString = aString;
+ maItem.mfValue = fValue;
+ maItem.mbHasValue = bHasValue;
+}
+
+bool ScDPCacheTable::SingleFilter::match( const ScDPItemData& rCellData ) const
+{
+ return maItem.match(rCellData);
+}
+
+const String ScDPCacheTable::SingleFilter::getMatchString()
+{
+ return maItem.maString;
+}
+
+double ScDPCacheTable::SingleFilter::getMatchValue() const
+{
+ return maItem.mfValue;
+}
+
+bool ScDPCacheTable::SingleFilter::hasValue() const
+{
+ return maItem.mbHasValue;
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPCacheTable::GroupFilter::GroupFilter()
+{
+}
+
+bool ScDPCacheTable::GroupFilter::match( const ScDPItemData& rCellData ) const
+{
+ vector<FilterItem>::const_iterator itrEnd = maItems.end();
+ for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr)
+ {
+ bool bMatch = itr->match( rCellData);
+ if (bMatch)
+ return true;
+ }
+ return false;
+}
+
+void ScDPCacheTable::GroupFilter::addMatchItem(const String& rStr, double fVal, bool bHasValue)
+{
+ FilterItem aItem;
+ aItem.maString = rStr;
+ aItem.mfValue = fVal;
+ aItem.mbHasValue = bHasValue;
+ maItems.push_back(aItem);
+}
+
+size_t ScDPCacheTable::GroupFilter::getMatchItemCount() const
+{
+ return maItems.size();
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPCacheTable::Criterion::Criterion() :
+ mnFieldIndex(-1),
+ mpFilter(static_cast<FilterBase*>(NULL))
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPCacheTable::ScDPCacheTable( ScDocument* pDoc,long nId ) :
+ mpCache( NULL ),
+ mpNoneCache( NULL )
+{
+ if ( nId >= 0 )
+ mpCache = pDoc->GetDPObjectCache( nId );
+ else
+ { //create a temp cache object
+ InitNoneCache( NULL );
+ }
+}
+
+ScDPCacheTable::~ScDPCacheTable()
+{
+}
+
+sal_Int32 ScDPCacheTable::getRowSize() const
+{
+ return GetCache()->GetRowCount();
+}
+
+sal_Int32 ScDPCacheTable::getColSize() const
+{
+ return GetCache()->GetColumnCount();
+}
+
+void ScDPCacheTable::fillTable( const ScQueryParam& rQuery, BOOL* pSpecial,
+ bool bIgnoreEmptyRows, bool bRepeatIfEmpty )
+{
+ if ( mpCache == NULL )
+ InitNoneCache( NULL );
+//check cache
+ const SCROW nRowCount = getRowSize();
+ const SCCOL nColCount = (SCCOL) getColSize();
+ if ( nRowCount <= 0 || nColCount <= 0)
+ return;
+
+ maRowsVisible.clear();
+ maRowsVisible.reserve(nRowCount);
+
+
+ // Initialize field entries container.
+ maFieldEntries.clear();
+ maFieldEntries.reserve(nColCount);
+
+ // Data rows
+ for (SCCOL nCol = 0; nCol < nColCount; ++nCol)
+ {
+ SCROW nMemCount = GetCache()->GetDimMemberCount( nCol );
+ if ( nMemCount )
+ {
+ std::vector< SCROW > pAdded( nMemCount, -1 );
+
+ for (SCROW nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, bRepeatIfEmpty );
+ SCROW nOrder = GetCache()->GetOrder( nCol, nIndex );
+
+ if ( nCol == 0 )
+ maRowsVisible.push_back(false);
+
+ if ( lcl_HasQueryEntry(rQuery) &&
+ !GetCache()->ValidQuery( nRow , rQuery, pSpecial ) )
+ continue;
+ if ( bIgnoreEmptyRows && GetCache()->IsRowEmpty( nRow ) )
+ continue;
+ // Insert a new row into cache table.
+ if ( nCol == 0 )
+ maRowsVisible.back() = true;
+
+ pAdded[nOrder] = nIndex;
+ }
+ maFieldEntries.push_back( vector<SCROW>() );
+ for ( SCROW nRow = 0; nRow < nMemCount; nRow++ )
+ {
+ if ( pAdded[nRow] != -1 )
+ maFieldEntries.back().push_back( pAdded[nRow] );
+ }
+ }
+ }
+}
+
+void ScDPCacheTable::fillTable()
+{
+ if ( mpCache == NULL )
+ InitNoneCache( NULL );
+//check cache
+ const SCROW nRowCount = getRowSize();
+ const SCCOL nColCount = (SCCOL) getColSize();
+ if ( nRowCount <= 0 || nColCount <= 0)
+ return;
+
+ maRowsVisible.clear();
+ maRowsVisible.reserve(nRowCount);
+
+
+ // Initialize field entries container.
+ maFieldEntries.clear();
+ maFieldEntries.reserve(nColCount);
+
+ // Data rows
+ for (SCCOL nCol = 0; nCol < nColCount; ++nCol)
+ {
+ SCROW nMemCount = GetCache()->GetDimMemberCount( nCol );
+ if ( nMemCount )
+ {
+ std::vector< SCROW > pAdded( nMemCount, -1 );
+
+ for (SCROW nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, false );
+ SCROW nOrder = GetCache()->GetOrder( nCol, nIndex );
+
+ if ( nCol == 0 )
+ maRowsVisible.push_back(true);
+
+
+ pAdded[nOrder] = nIndex;
+ }
+ maFieldEntries.push_back( vector<SCROW>() );
+ for ( SCROW nRow = 0; nRow < nMemCount; nRow++ )
+ {
+ if ( pAdded[nRow] != -1 )
+ maFieldEntries.back().push_back( pAdded[nRow] );
+ }
+ }
+ }
+ return;
+}
+
+bool ScDPCacheTable::isRowActive(sal_Int32 nRow) const
+{
+ if (nRow < 0 || static_cast<size_t>(nRow) >= maRowsVisible.size())
+ // row index out of bound
+ return false;
+
+ return maRowsVisible[nRow];
+}
+
+void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, const hash_set<sal_Int32>& rRepeatIfEmptyDims)
+{
+ sal_Int32 nRowSize = getRowSize();
+ if (nRowSize != static_cast<sal_Int32>(maRowsVisible.size()))
+ {
+ // sizes of the two tables differ!
+ return;
+ }
+
+ for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
+ maRowsVisible[nRow] = isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims);
+}
+
+const ScDPItemData* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const
+{
+ SCROW nId= GetCache()->GetItemDataId(nCol, nRow, bRepeatIfEmpty);
+ return GetCache()->GetItemDataById( nCol, nId );
+}
+
+void ScDPCacheTable::getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const
+{
+ const ScDPItemData* pData = getCell( nCol, nRow, bRepeatIfEmpty );
+
+ if (pData)
+ {
+ rVal.fValue = pData->IsValue() ? pData->GetValue() : 0.0;
+ rVal.nType = pData->GetType();
+ }
+ else
+ rVal.Set(0.0, SC_VALTYPE_EMPTY);
+}
+String ScDPCacheTable::getFieldName(SCCOL nIndex) const
+{
+ return (GetCache()->GetDimensionName( nIndex ));
+}
+
+sal_Int32 ScDPCacheTable::getFieldIndex(const String& rStr) const
+{
+ return GetCache()->GetDimensionIndex( rStr );
+}
+
+const ::std::vector<SCROW>& ScDPCacheTable::getFieldEntries( sal_Int32 nColumn ) const
+{
+ if (nColumn < 0 || static_cast<size_t>(nColumn) >= maFieldEntries.size())
+ {
+ // index out of bound. Hopefully this code will never be reached.
+ static const ::std::vector<SCROW> emptyEntries;
+ return emptyEntries;
+ }
+ return maFieldEntries[nColumn];
+}
+
+void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< Sequence<Any> >& rTabData,
+ const hash_set<sal_Int32>& rRepeatIfEmptyDims)
+{
+ sal_Int32 nRowSize = getRowSize();
+ sal_Int32 nColSize = getColSize();
+
+ if (!nRowSize)
+ // no data to filter.
+ return;
+
+ // Row first, then column.
+ vector< Sequence<Any> > tableData;
+ tableData.reserve(nRowSize+1);
+
+ // Header first.
+ Sequence<Any> headerRow(nColSize);
+ for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
+ {
+ OUString str;
+ str = getFieldName( nCol);
+ Any any;
+ any <<= str;
+ headerRow[nCol] = any;
+ }
+ tableData.push_back(headerRow);
+
+
+ for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
+ {
+ if (!maRowsVisible[nRow])
+ // This row is filtered out.
+ continue;
+
+ if (!isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims))
+ continue;
+
+ // Insert this row into table.
+
+ Sequence<Any> row(nColSize);
+ for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
+ {
+ Any any;
+ bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(nCol) > 0;
+ // Wang Xu Ming - DataPilot migration
+ const ScDPItemData* pData= getCell(nCol, nRow, bRepeatIfEmpty);
+ if ( pData->IsValue() )
+ any <<= pData->GetValue();
+ else
+ {
+ OUString string (pData->GetString() );
+ any <<= string;
+ }
+ row[nCol] = any;
+ }
+ tableData.push_back(row);
+ }
+
+ // convert vector to Seqeunce
+ sal_Int32 nTabSize = static_cast<sal_Int32>(tableData.size());
+ rTabData.realloc(nTabSize);
+ for (sal_Int32 i = 0; i < nTabSize; ++i)
+ rTabData[i] = tableData[i];
+}
+
+void ScDPCacheTable::clear()
+{
+ maFieldEntries.clear();
+ maRowsVisible.clear();
+}
+
+void ScDPCacheTable::swap(ScDPCacheTable& rOther)
+{
+ maFieldEntries.swap(rOther.maFieldEntries);
+ maRowsVisible.swap(rOther.maRowsVisible);
+}
+
+bool ScDPCacheTable::empty() const
+{
+ return ( mpCache == NULL&& mpNoneCache == NULL ) || maFieldEntries.size()==0;
+}
+
+bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCriteria,
+ const hash_set<sal_Int32>& rRepeatIfEmptyDims) const
+{
+ sal_Int32 nColSize = getColSize();
+ vector<Criterion>::const_iterator itrEnd = rCriteria.end();
+ for (vector<Criterion>::const_iterator itr = rCriteria.begin(); itr != itrEnd; ++itr)
+ {
+ if (itr->mnFieldIndex >= nColSize)
+ // specified field is outside the source data columns. Don't
+ // use this criterion.
+ continue;
+
+ // Check if the 'repeat if empty' flag is set for this field.
+ bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(itr->mnFieldIndex) > 0;
+ const ScDPItemData* pCellData = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty);
+ if (!itr->mpFilter->match(*pCellData))
+ return false;
+ }
+ return true;
+}
+
+
+void ScDPCacheTable::InitNoneCache( ScDocument* pDoc )
+{
+ mpCache = NULL;
+ if ( mpNoneCache )
+ delete mpNoneCache;
+ mpNoneCache = new ScDPTableDataCache( pDoc );
+}
+
+ScDPTableDataCache* ScDPCacheTable::GetCache() const
+{
+ if ( mpCache )
+ return mpCache;
+ return mpNoneCache;
+}
+// End Comments
diff --git a/sc/source/core/data/dpdimsave.cxx b/sc/source/core/data/dpdimsave.cxx
new file mode 100644
index 000000000000..21669eb7a435
--- /dev/null
+++ b/sc/source/core/data/dpdimsave.cxx
@@ -0,0 +1,584 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpdimsave.hxx"
+#include "dpgroup.hxx"
+#include "dpobject.hxx"
+#include "document.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+#include <svl/zforlist.hxx>
+#include <tools/debug.hxx>
+#include <rtl/math.hxx>
+#include <algorithm>
+
+// ============================================================================
+
+ScDPSaveGroupItem::ScDPSaveGroupItem( const String& rName ) :
+ aGroupName( rName )
+{
+}
+
+ScDPSaveGroupItem::~ScDPSaveGroupItem()
+{
+}
+
+void ScDPSaveGroupItem::AddElement( const String& rName )
+{
+ aElements.push_back( rName );
+}
+
+void ScDPSaveGroupItem::AddElementsFromGroup( const ScDPSaveGroupItem& rGroup )
+{
+ // add all elements of the other group (used for nested grouping)
+
+ for ( std::vector<String>::const_iterator aIter(rGroup.aElements.begin());
+ aIter != rGroup.aElements.end(); aIter++ )
+ aElements.push_back( *aIter );
+}
+
+bool ScDPSaveGroupItem::RemoveElement( const String& rName )
+{
+ for ( std::vector<String>::iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
+ if ( *aIter == rName ) //! ignore case
+ {
+ aElements.erase( aIter ); // found -> remove
+ return true; // don't have to look further
+ }
+
+ return false; // not found
+}
+
+bool ScDPSaveGroupItem::IsEmpty() const
+{
+ return aElements.empty();
+}
+
+size_t ScDPSaveGroupItem::GetElementCount() const
+{
+ return aElements.size();
+}
+
+const String* ScDPSaveGroupItem::GetElementByIndex( size_t nIndex ) const
+{
+ return (nIndex < aElements.size()) ? &aElements[ nIndex ] : 0;
+}
+
+void ScDPSaveGroupItem::Rename( const String& rNewName )
+{
+ aGroupName = rNewName;
+}
+
+void ScDPSaveGroupItem::RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const
+{
+ // remove this group's elements from their groups in rDimension
+ // (rDimension must be a different dimension from the one which contains this)
+
+ for ( std::vector<String>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
+ rDimension.RemoveFromGroups( *aIter );
+}
+
+void ScDPSaveGroupItem::AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatter* pFormatter ) const
+{
+ ScDPGroupItem aGroup( aGroupName );
+ ScDPItemData aData;
+
+ for ( std::vector<String>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
+ {
+ sal_uInt32 nFormat = 0; //! ...
+ double fValue;
+ if ( pFormatter->IsNumberFormat( *aIter, nFormat, fValue ) )
+ aData = ScDPItemData( *aIter, fValue, TRUE );
+ else
+ aData.SetString( *aIter );
+
+ aGroup.AddElement( aData );
+ //! for numeric data, look at source members?
+ }
+
+ rDataDim.AddItem( aGroup );
+}
+
+// ============================================================================
+
+ScDPSaveGroupDimension::ScDPSaveGroupDimension( const String& rSource, const String& rName ) :
+ aSourceDim( rSource ),
+ aGroupDimName( rName ),
+ nDatePart( 0 )
+{
+}
+
+ScDPSaveGroupDimension::ScDPSaveGroupDimension( const String& rSource, const String& rName, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nPart ) :
+ aSourceDim( rSource ),
+ aGroupDimName( rName ),
+ aDateInfo( rDateInfo ),
+ nDatePart( nPart )
+{
+}
+
+ScDPSaveGroupDimension::~ScDPSaveGroupDimension()
+{
+}
+
+void ScDPSaveGroupDimension::SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
+{
+ aDateInfo = rInfo;
+ nDatePart = nPart;
+}
+
+void ScDPSaveGroupDimension::AddGroupItem( const ScDPSaveGroupItem& rItem )
+{
+ aGroups.push_back( rItem );
+}
+
+String ScDPSaveGroupDimension::CreateGroupName( const String& rPrefix )
+{
+ // create a name for a new group, using "Group1", "Group2" etc. (translated prefix in rPrefix)
+
+ //! look in all dimensions, to avoid clashes with automatic groups (=name of base element)?
+ //! (only dimensions for the same base)
+
+ sal_Int32 nAdd = 1; // first try is "Group1"
+ const sal_Int32 nMaxAdd = nAdd + aGroups.size(); // limit the loop
+ while ( nAdd <= nMaxAdd )
+ {
+ String aGroupName( rPrefix );
+ aGroupName.Append( String::CreateFromInt32( nAdd ) );
+ bool bExists = false;
+
+ // look for existing groups
+ for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin());
+ aIter != aGroups.end() && !bExists; aIter++ )
+ if ( aIter->GetGroupName() == aGroupName ) //! ignore case
+ bExists = true;
+
+ if ( !bExists )
+ return aGroupName; // found a new name
+
+ ++nAdd; // continue with higher number
+ }
+
+ DBG_ERROR("CreateGroupName: no valid name found");
+ return EMPTY_STRING;
+}
+
+const ScDPSaveGroupItem* ScDPSaveGroupDimension::GetNamedGroup( const String& rGroupName ) const
+{
+ return const_cast< ScDPSaveGroupDimension* >( this )->GetNamedGroupAcc( rGroupName );
+}
+
+ScDPSaveGroupItem* ScDPSaveGroupDimension::GetNamedGroupAcc( const String& rGroupName )
+{
+ for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ if ( aIter->GetGroupName() == rGroupName ) //! ignore case
+ return &*aIter;
+
+ return NULL; // none found
+}
+
+long ScDPSaveGroupDimension::GetGroupCount() const
+{
+ return aGroups.size();
+}
+
+const ScDPSaveGroupItem* ScDPSaveGroupDimension::GetGroupByIndex( long nIndex ) const
+{
+ return const_cast< ScDPSaveGroupDimension* >( this )->GetGroupAccByIndex( nIndex );
+}
+
+ScDPSaveGroupItem* ScDPSaveGroupDimension::GetGroupAccByIndex( long nIndex )
+{
+ return &aGroups[nIndex];
+}
+
+void ScDPSaveGroupDimension::RemoveFromGroups( const String& rItemName )
+{
+ // if the item is in any group, remove it from the group,
+ // also remove the group if it is empty afterwards
+
+ for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ if ( aIter->RemoveElement( rItemName ) )
+ {
+ if ( aIter->IsEmpty() ) // removed last item from the group?
+ aGroups.erase( aIter ); // then remove the group
+
+ return; // don't have to look further
+ }
+}
+
+void ScDPSaveGroupDimension::RemoveGroup( const String& rGroupName )
+{
+ for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ if ( aIter->GetGroupName() == rGroupName ) //! ignore case
+ {
+ aGroups.erase( aIter );
+ return; // don't have to look further
+ }
+}
+
+bool ScDPSaveGroupDimension::IsEmpty() const
+{
+ return aGroups.empty();
+}
+
+bool ScDPSaveGroupDimension::HasOnlyHidden( const ScStrCollection& rVisible )
+{
+ // check if there are only groups that don't appear in the list of visible names
+
+ bool bAllHidden = true;
+ for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end() && bAllHidden; aIter++ )
+ {
+ StrData aSearch( aIter->GetGroupName() );
+ USHORT nCollIndex;
+ if ( rVisible.Search( &aSearch, nCollIndex ) )
+ bAllHidden = false; // found one that is visible
+ }
+ return bAllHidden;
+}
+
+void ScDPSaveGroupDimension::Rename( const String& rNewName )
+{
+ aGroupDimName = rNewName;
+}
+
+void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const
+{
+ long nSourceIndex = rData.GetDimensionIndex( aSourceDim );
+ if ( nSourceIndex >= 0 )
+ {
+ ScDPGroupDimension aDim( nSourceIndex, aGroupDimName );
+ if ( nDatePart )
+ {
+ // date grouping
+
+ aDim.MakeDateHelper( aDateInfo, nDatePart );
+ }
+ else
+ {
+ // normal (manual) grouping
+
+ SvNumberFormatter* pFormatter = rData.GetDocument()->GetFormatTable();
+
+ for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ aIter->AddToData( aDim, pFormatter );
+ }
+
+ rData.AddGroupDimension( aDim );
+ }
+}
+
+// ============================================================================
+
+ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const String& rName, const ScDPNumGroupInfo& rInfo ) :
+ aDimensionName( rName ),
+ aGroupInfo( rInfo ),
+ nDatePart( 0 )
+{
+}
+
+ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const String& rName, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nPart ) :
+ aDimensionName( rName ),
+ aDateInfo( rDateInfo ),
+ nDatePart( nPart )
+{
+}
+
+ScDPSaveNumGroupDimension::~ScDPSaveNumGroupDimension()
+{
+}
+
+void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const
+{
+ long nSource = rData.GetDimensionIndex( aDimensionName );
+ if ( nSource >= 0 )
+ {
+ ScDPNumGroupDimension aDim( aGroupInfo ); // aGroupInfo: value grouping
+ if ( nDatePart )
+ aDim.MakeDateHelper( aDateInfo, nDatePart ); // date grouping
+
+ rData.SetNumGroupDimension( nSource, aDim );
+ }
+}
+
+void ScDPSaveNumGroupDimension::SetGroupInfo( const ScDPNumGroupInfo& rNew )
+{
+ aGroupInfo = rNew;
+}
+
+void ScDPSaveNumGroupDimension::SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
+{
+ aDateInfo = rInfo;
+ nDatePart = nPart;
+}
+
+// ============================================================================
+
+namespace {
+
+struct ScDPSaveGroupDimNameFunc
+{
+ String maDimName;
+ inline explicit ScDPSaveGroupDimNameFunc( const String& rDimName ) : maDimName( rDimName ) {}
+ inline bool operator()( const ScDPSaveGroupDimension& rGroupDim ) const { return rGroupDim.GetGroupDimName() == maDimName; }
+};
+
+struct ScDPSaveGroupSourceNameFunc
+{
+ String maSrcDimName;
+ inline explicit ScDPSaveGroupSourceNameFunc( const String& rSrcDimName ) : maSrcDimName( rSrcDimName ) {}
+ inline bool operator()( const ScDPSaveGroupDimension& rGroupDim ) const { return rGroupDim.GetSourceDimName() == maSrcDimName; }
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ScDPDimensionSaveData::ScDPDimensionSaveData()
+{
+}
+
+ScDPDimensionSaveData::~ScDPDimensionSaveData()
+{
+}
+
+bool ScDPDimensionSaveData::operator==( const ScDPDimensionSaveData& ) const
+{
+ return false;
+}
+
+void ScDPDimensionSaveData::AddGroupDimension( const ScDPSaveGroupDimension& rGroupDim )
+{
+ DBG_ASSERT( ::std::find_if( maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDim.GetGroupDimName() ) ) == maGroupDims.end(),
+ "ScDPDimensionSaveData::AddGroupDimension - group dimension exists already" );
+ // ReplaceGroupDimension() adds new or replaces existing
+ ReplaceGroupDimension( rGroupDim );
+}
+
+void ScDPDimensionSaveData::ReplaceGroupDimension( const ScDPSaveGroupDimension& rGroupDim )
+{
+ ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
+ maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDim.GetGroupDimName() ) );
+ if( aIt == maGroupDims.end() )
+ maGroupDims.push_back( rGroupDim );
+ else
+ *aIt = rGroupDim;
+}
+
+void ScDPDimensionSaveData::RemoveGroupDimension( const String& rGroupDimName )
+{
+ ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
+ maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
+ if( aIt != maGroupDims.end() )
+ maGroupDims.erase( aIt );
+}
+
+void ScDPDimensionSaveData::AddNumGroupDimension( const ScDPSaveNumGroupDimension& rGroupDim )
+{
+ DBG_ASSERT( maNumGroupDims.count( rGroupDim.GetDimensionName() ) == 0,
+ "ScDPDimensionSaveData::AddNumGroupDimension - numeric group dimension exists already" );
+ // ReplaceNumGroupDimension() adds new or replaces existing
+ ReplaceNumGroupDimension( rGroupDim );
+}
+
+void ScDPDimensionSaveData::ReplaceNumGroupDimension( const ScDPSaveNumGroupDimension& rGroupDim )
+{
+ ScDPSaveNumGroupDimMap::iterator aIt = maNumGroupDims.find( rGroupDim.GetDimensionName() );
+ if( aIt == maNumGroupDims.end() )
+ maNumGroupDims.insert( ScDPSaveNumGroupDimMap::value_type( rGroupDim.GetDimensionName(), rGroupDim ) );
+ else
+ aIt->second = rGroupDim;
+}
+
+void ScDPDimensionSaveData::RemoveNumGroupDimension( const String& rGroupDimName )
+{
+ maNumGroupDims.erase( rGroupDimName );
+}
+
+void ScDPDimensionSaveData::WriteToData( ScDPGroupTableData& rData ) const
+{
+ // rData is assumed to be empty
+ // AddToData also handles date grouping
+
+ for( ScDPSaveGroupDimVec::const_iterator aIt = maGroupDims.begin(), aEnd = maGroupDims.end(); aIt != aEnd; ++aIt )
+ aIt->AddToData( rData );
+
+ for( ScDPSaveNumGroupDimMap::const_iterator aIt = maNumGroupDims.begin(), aEnd = maNumGroupDims.end(); aIt != aEnd; ++aIt )
+ aIt->second.AddToData( rData );
+}
+
+const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimForBase( const String& rBaseDimName ) const
+{
+ return const_cast< ScDPDimensionSaveData* >( this )->GetGroupDimAccForBase( rBaseDimName );
+}
+
+const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNamedGroupDim( const String& rGroupDimName ) const
+{
+ return const_cast< ScDPDimensionSaveData* >( this )->GetNamedGroupDimAcc( rGroupDimName );
+}
+
+const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetFirstNamedGroupDim( const String& rBaseDimName ) const
+{
+ return const_cast< ScDPDimensionSaveData* >( this )->GetFirstNamedGroupDimAcc( rBaseDimName );
+}
+
+const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDim( const String& rGroupDimName ) const
+{
+ return const_cast< ScDPDimensionSaveData* >( this )->GetNextNamedGroupDimAcc( rGroupDimName );
+}
+
+const ScDPSaveNumGroupDimension* ScDPDimensionSaveData::GetNumGroupDim( const String& rGroupDimName ) const
+{
+ return const_cast< ScDPDimensionSaveData* >( this )->GetNumGroupDimAcc( rGroupDimName );
+}
+
+ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimAccForBase( const String& rBaseDimName )
+{
+ ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDimAcc( rBaseDimName );
+ return pGroupDim ? pGroupDim : GetNextNamedGroupDimAcc( rBaseDimName );
+}
+
+ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNamedGroupDimAcc( const String& rGroupDimName )
+{
+ ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
+ maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
+ return (aIt == maGroupDims.end()) ? 0 : &*aIt;
+}
+
+ScDPSaveGroupDimension* ScDPDimensionSaveData::GetFirstNamedGroupDimAcc( const String& rBaseDimName )
+{
+ ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
+ maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupSourceNameFunc( rBaseDimName ) );
+ return (aIt == maGroupDims.end()) ? 0 : &*aIt;
+}
+
+ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDimAcc( const String& rGroupDimName )
+{
+ // find the group dimension with the passed name
+ ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
+ maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
+ // find next group dimension based on the same source dimension name
+ if( aIt != maGroupDims.end() )
+ aIt = ::std::find_if( aIt + 1, maGroupDims.end(), ScDPSaveGroupSourceNameFunc( aIt->GetSourceDimName() ) );
+ return (aIt == maGroupDims.end()) ? 0 : &*aIt;
+}
+
+ScDPSaveNumGroupDimension* ScDPDimensionSaveData::GetNumGroupDimAcc( const String& rGroupDimName )
+{
+ ScDPSaveNumGroupDimMap::iterator aIt = maNumGroupDims.find( rGroupDimName );
+ return (aIt == maNumGroupDims.end()) ? 0 : &aIt->second;
+}
+
+bool ScDPDimensionSaveData::HasGroupDimensions() const
+{
+ return !maGroupDims.empty() || !maNumGroupDims.empty();
+}
+
+sal_Int32 ScDPDimensionSaveData::CollectDateParts( const String& rBaseDimName ) const
+{
+ sal_Int32 nParts = 0;
+ // start with part of numeric group
+ if( const ScDPSaveNumGroupDimension* pNumDim = GetNumGroupDim( rBaseDimName ) )
+ nParts |= pNumDim->GetDatePart();
+ // collect parts from all matching group dimensions
+ for( const ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDim( rBaseDimName ); pGroupDim; pGroupDim = GetNextNamedGroupDim( pGroupDim->GetGroupDimName() ) )
+ nParts |= pGroupDim->GetDatePart();
+
+ return nParts;
+}
+
+String ScDPDimensionSaveData::CreateGroupDimName( const String& rSourceName,
+ const ScDPObject& rObject, bool bAllowSource,
+ const std::vector<String>* pDeletedNames )
+{
+ // create a name for the new dimension by appending a number to the original
+ // dimension's name
+
+ bool bUseSource = bAllowSource; // if set, try the unchanged original name first
+
+ sal_Int32 nAdd = 2; // first try is "Name2"
+ const sal_Int32 nMaxAdd = 1000; // limit the loop
+ while ( nAdd <= nMaxAdd )
+ {
+ String aDimName( rSourceName );
+ if ( !bUseSource )
+ aDimName.Append( String::CreateFromInt32( nAdd ) );
+ bool bExists = false;
+
+ // look for existing group dimensions
+ for( ScDPSaveGroupDimVec::const_iterator aIt = maGroupDims.begin(), aEnd = maGroupDims.end(); (aIt != aEnd) && !bExists; ++aIt )
+ if( aIt->GetGroupDimName() == aDimName ) //! ignore case
+ bExists = true;
+
+ // look for base dimensions that happen to have that name
+ if ( !bExists && rObject.IsDimNameInUse( aDimName ) )
+ {
+ if ( pDeletedNames &&
+ std::find( pDeletedNames->begin(), pDeletedNames->end(), aDimName ) != pDeletedNames->end() )
+ {
+ // allow the name anyway if the name is in pDeletedNames
+ }
+ else
+ bExists = true;
+ }
+
+ if ( !bExists )
+ return aDimName; // found a new name
+
+ if ( bUseSource )
+ bUseSource = false;
+ else
+ ++nAdd; // continue with higher number
+ }
+ DBG_ERROR("CreateGroupDimName: no valid name found");
+ return EMPTY_STRING;
+}
+
+String ScDPDimensionSaveData::CreateDateGroupDimName( sal_Int32 nDatePart, const ScDPObject& rObject, bool bAllowSource, const ::std::vector< String >* pDeletedNames )
+{
+ using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
+ String aPartName;
+ switch( nDatePart )
+ {
+ //! use translated strings from globstr.src
+ case SECONDS: aPartName = String::CreateFromAscii( "Seconds" ); break;
+ case MINUTES: aPartName = String::CreateFromAscii( "Minutes" ); break;
+ case HOURS: aPartName = String::CreateFromAscii( "Hours" ); break;
+ case DAYS: aPartName = String::CreateFromAscii( "Days" ); break;
+ case MONTHS: aPartName = String::CreateFromAscii( "Months" ); break;
+ case QUARTERS: aPartName = String::CreateFromAscii( "Quarters" ); break;
+ case YEARS: aPartName = String::CreateFromAscii( "Years" ); break;
+ }
+ DBG_ASSERT( aPartName.Len() > 0, "ScDPDimensionSaveData::CreateDateGroupDimName - invalid date part" );
+ return CreateGroupDimName( aPartName, rObject, bAllowSource, pDeletedNames );
+}
+
+// ============================================================================
+
diff --git a/sc/source/core/data/dpglobal.cxx b/sc/source/core/data/dpglobal.cxx
new file mode 100755
index 000000000000..6b84d37d8d0f
--- /dev/null
+++ b/sc/source/core/data/dpglobal.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright IBM Corporation 2009.
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dpglobal.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpglobal.hxx"
+#include "document.hxx"
+
+#include <stdio.h>
+
+namespace ScDPGlobal
+{
+ Rectangle operator *( const Rectangle &rLeft, const std::pair<double,double> & rRight )
+ {
+ Rectangle rcResult( rLeft );
+ rcResult.Bottom() = rcResult.Top() + static_cast<long>( rcResult.GetHeight() * rRight.second );
+ rcResult.Right() = rcResult.Left() + static_cast<long>( rcResult.GetWidth() * rRight.first);
+ return rcResult;
+ }
+
+ String GetFuncString( const String &rString, const USHORT nIndex )
+ {
+ if ( nIndex <= 1 ) return rString;
+ ULONG uch = rString.Len() ? rString.GetChar( rString.Len()-1 ) : (L'9'+1);
+ bool bEndWithDigital = ( L'0'<=uch && uch<=L'9');
+ char szTemp[__MAX_NUM_LEN+1];
+ int nLen = sprintf( szTemp, bEndWithDigital ? DATA_RENAME_SEPARATOR"%hu" : "%hu", nIndex );
+ String strRet = rString;
+ strRet.Append( String::CreateFromAscii( szTemp, static_cast<USHORT>(nLen) ));
+ return strRet;
+ }
+
+ bool ChkDPTableOverlap( ScDocument *pDestDoc, std::list<ScDPObject> & rClipboard, SCCOL nClipStartCol, SCROW nClipStartRow, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, USHORT nEndTab, BOOL bExcludeClip /*= FALSE*/ )
+ {
+ if ( ScDPCollection* pDPCollection = pDestDoc->GetDPCollection() )
+ {
+ USHORT nCount = pDPCollection->GetCount();
+ SCsCOL nOffsetX = nStartCol - nClipStartCol;
+ SCsROW nOffsetY = nStartRow - nClipStartRow;
+
+ for( std::list<ScDPObject>::iterator iter = rClipboard.begin(); iter!=rClipboard.end(); iter++ )
+ {
+ ScRange aRange = iter->GetOutRange();
+
+ for( USHORT nCurrTab = nStartTab; nCurrTab<=nEndTab; nCurrTab++ )
+ {
+ SCsTAB nOffsetZ = nCurrTab - aRange.aStart.Tab();
+ aRange.Move( nOffsetX, nOffsetY, nOffsetZ );
+
+ for ( USHORT i = 0; i<nCount; i++)
+ {
+ if ( (*pDPCollection)[i] && aRange.Intersects( (*pDPCollection)[i]->GetOutRange()))
+ {
+ if ( bExcludeClip && iter->GetOutRange() == (*pDPCollection)[i]->GetOutRange() )
+ {
+ continue;
+ }
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+//end
+
+}
+// --------------------------------------------------------------------
+// ScDPItemDataPool
+// Construct
+ScDPItemDataPool::ScDPItemDataPool(void)
+{
+}
+//
+ScDPItemDataPool::ScDPItemDataPool(const ScDPItemDataPool& r):
+ maItems(r.maItems),
+ maItemIds(r.maItemIds)
+{
+}
+
+ScDPItemDataPool::~ScDPItemDataPool(void)
+{
+}
+
+
+const ScDPItemData* ScDPItemDataPool::getData( sal_Int32 nId )
+{
+ if ( nId >= static_cast<sal_Int32>(maItems.size()) )
+ return NULL;
+ else
+ return &(maItems[nId]);
+}
+
+sal_Int32 ScDPItemDataPool::getDataId( const ScDPItemData& aData )
+{
+ DataHash::const_iterator itr = maItemIds.find( aData),
+ itrEnd = maItemIds.end();
+ if ( itr == itrEnd )
+ // not exist
+ return -1;
+
+ else //exist
+ return itr->second;
+
+}
+
+sal_Int32 ScDPItemDataPool::insertData( const ScDPItemData& aData )
+{
+ sal_Int32 nResult = getDataId( aData );
+
+ if( nResult < 0 )
+ {
+ maItemIds.insert( DataHash::value_type( aData, nResult = maItems.size() ) );
+ maItems.push_back( aData );
+ }
+
+ return nResult;
+}
+
+
diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx
new file mode 100644
index 000000000000..edb3b787b9b2
--- /dev/null
+++ b/sc/source/core/data/dpgroup.cxx
@@ -0,0 +1,1589 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/i18n/CalendarDisplayIndex.hpp>
+
+#include <tools/debug.hxx>
+#include <rtl/math.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <svl/zforlist.hxx>
+
+#include "dpgroup.hxx"
+#include "collect.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "dpcachetable.hxx"
+#include "dptabsrc.hxx"
+#include "dptabres.hxx"
+#include "dpobject.hxx"
+#include "dpglobal.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include <vector>
+#include <hash_set>
+#include <hash_map>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+
+using ::std::vector;
+using ::std::hash_set;
+using ::std::hash_map;
+using ::boost::shared_ptr;
+
+#define D_TIMEFACTOR 86400.0
+
+const USHORT SC_DP_LEAPYEAR = 1648; // arbitrary leap year for date calculations
+
+// part values for the extra "<" and ">" entries (same for all parts)
+const sal_Int32 SC_DP_DATE_FIRST = -1;
+const sal_Int32 SC_DP_DATE_LAST = 10000;
+
+// ============================================================================
+namespace
+{
+ BOOL lcl_Search( SCCOL nSourceDim, ScDPTableDataCache* pCache , const std::vector< SCROW >& vIdx, SCROW nNew , SCROW& rIndex)
+ {
+ rIndex = vIdx.size();
+ BOOL bFound = FALSE;
+ SCROW nLo = 0;
+ SCROW nHi = vIdx.size() - 1;
+ SCROW nIndex;
+ long nCompare;
+ while (nLo <= nHi)
+ {
+ nIndex = (nLo + nHi) / 2;
+
+ const ScDPItemData* pData = pCache->GetItemDataById( nSourceDim, vIdx[nIndex] );
+ const ScDPItemData* pDataInsert = pCache->GetItemDataById( nSourceDim, nNew );
+
+ nCompare = ScDPItemData::Compare( *pData, *pDataInsert );
+ if (nCompare < 0)
+ nLo = nIndex + 1;
+ else
+ {
+ nHi = nIndex - 1;
+ if (nCompare == 0)
+ {
+ bFound = TRUE;
+ nLo = nIndex;
+ }
+ }
+ }
+ rIndex = nLo;
+ return bFound;
+ }
+
+ void lcl_Insert( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, SCROW nNew )
+ {
+ SCROW nIndex = 0;
+ if ( !lcl_Search( nSourceDim, pCache, vIdx, nNew ,nIndex ) )
+ vIdx.insert( vIdx.begin()+nIndex, nNew );
+ }
+
+ template<bool bUpdateData>
+ SCROW lcl_InsertValue( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData );
+
+ template<>
+ SCROW lcl_InsertValue<false>( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData )
+ {
+ SCROW nNewID = pCache->GetAdditionalItemID( rData );
+ lcl_Insert( nSourceDim, pCache, vIdx, nNewID );
+ return nNewID;
+ }
+
+ template<>
+ SCROW lcl_InsertValue<true>( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData )
+ {
+ SCROW nItemId = lcl_InsertValue<false>( nSourceDim, pCache, vIdx, rData );
+
+ if( const ScDPItemData *pData = pCache->GetItemDataById( nSourceDim, nItemId ) )
+ const_cast<ScDPItemData&>(*pData) = rData;
+
+ return nItemId;
+ }
+
+ template<bool bUpdateData>
+ void lcl_InsertValue ( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const String& rString, const double& fValue )
+ {
+ lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( rString, fValue, TRUE ) );
+ }
+
+ template<bool bUpdateData>
+ void lcl_InsertValue ( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const String& rString, const double& fValue, sal_Int32 nDatePart )
+ {
+ lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( nDatePart, rString, fValue, ScDPItemData::MK_DATA|ScDPItemData::MK_VAL|ScDPItemData::MK_DATEPART ) );
+ }
+
+ void lcl_AppendDateStr( rtl::OUStringBuffer& rBuffer, double fValue, SvNumberFormatter* pFormatter )
+ {
+ ULONG nFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge );
+ String aString;
+ pFormatter->GetInputLineString( fValue, nFormat, aString );
+ rBuffer.append( aString );
+ }
+
+ String lcl_GetNumGroupName( double fStartValue, const ScDPNumGroupInfo& rInfo,
+ bool bHasNonInteger, sal_Unicode cDecSeparator, SvNumberFormatter* pFormatter )
+ {
+ DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" );
+
+ double fStep = rInfo.Step;
+ double fEndValue = fStartValue + fStep;
+ if ( !bHasNonInteger && ( rInfo.DateValues || !rtl::math::approxEqual( fEndValue, rInfo.End ) ) )
+ {
+ // The second number of the group label is
+ // (first number + size - 1) if there are only integer numbers,
+ // (first number + size) if any non-integer numbers are involved.
+ // Exception: The last group (containing the end value) is always
+ // shown as including the end value (but not for dates).
+
+ fEndValue -= 1.0;
+ }
+
+ if ( fEndValue > rInfo.End && !rInfo.AutoEnd )
+ {
+ // limit the last group to the end value
+
+ fEndValue = rInfo.End;
+ }
+
+ rtl::OUStringBuffer aBuffer;
+ if ( rInfo.DateValues )
+ {
+ lcl_AppendDateStr( aBuffer, fStartValue, pFormatter );
+ aBuffer.appendAscii( " - " ); // with spaces
+ lcl_AppendDateStr( aBuffer, fEndValue, pFormatter );
+ }
+ else
+ {
+ rtl::math::doubleToUStringBuffer( aBuffer, fStartValue, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, cDecSeparator, true );
+ aBuffer.append( (sal_Unicode) '-' );
+ rtl::math::doubleToUStringBuffer( aBuffer, fEndValue, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, cDecSeparator, true );
+ }
+
+ return aBuffer.makeStringAndClear();
+ }
+
+ String lcl_GetSpecialNumGroupName( double fValue, bool bFirst, sal_Unicode cDecSeparator,
+ bool bDateValues, SvNumberFormatter* pFormatter )
+ {
+ DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" );
+
+ rtl::OUStringBuffer aBuffer;
+ aBuffer.append((sal_Unicode)( bFirst ? '<' : '>' ));
+ if ( bDateValues )
+ lcl_AppendDateStr( aBuffer, fValue, pFormatter );
+ else
+ rtl::math::doubleToUStringBuffer( aBuffer, fValue, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, cDecSeparator, true );
+ return aBuffer.makeStringAndClear();
+ }
+
+ inline bool IsInteger( double fValue )
+ {
+ return rtl::math::approxEqual( fValue, rtl::math::approxFloor(fValue) );
+ }
+
+ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bool bHasNonInteger,
+ sal_Unicode cDecSeparator, double& rGroupValue, ScDocument* pDoc )
+ {
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ if ( fValue < rInfo.Start && !rtl::math::approxEqual( fValue, rInfo.Start ) )
+ {
+ rGroupValue = rInfo.Start - rInfo.Step;
+ return lcl_GetSpecialNumGroupName( rInfo.Start, true, cDecSeparator, rInfo.DateValues, pFormatter );
+ }
+
+ if ( fValue > rInfo.End && !rtl::math::approxEqual( fValue, rInfo.End ) )
+ {
+ rGroupValue = rInfo.End + rInfo.Step;
+ return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter );
+ }
+
+ double fDiff = fValue - rInfo.Start;
+ double fDiv = rtl::math::approxFloor( fDiff / rInfo.Step );
+ double fGroupStart = rInfo.Start + fDiv * rInfo.Step;
+
+ if ( rtl::math::approxEqual( fGroupStart, rInfo.End ) &&
+ !rtl::math::approxEqual( fGroupStart, rInfo.Start ) )
+ {
+ if ( !rInfo.DateValues )
+ {
+ // A group that would consist only of the end value is not created,
+ // instead the value is included in the last group before. So the
+ // previous group is used if the calculated group start value is the
+ // selected end value.
+
+ fDiv -= 1.0;
+ fGroupStart = rInfo.Start + fDiv * rInfo.Step;
+ }
+ else
+ {
+ // For date values, the end value is instead treated as above the limit
+ // if it would be a group of its own.
+
+ rGroupValue = rInfo.End + rInfo.Step;
+ return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter );
+ }
+ }
+
+ rGroupValue = fGroupStart;
+
+ return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter );
+ }
+}
+
+class ScDPGroupDateFilter : public ScDPCacheTable::FilterBase
+{
+public:
+ ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart,
+ const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo);
+
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ virtual bool match(const ScDPItemData & rCellData) const;
+ // End Comments
+
+private:
+ ScDPGroupDateFilter(); // disabled
+
+ const Date* mpNullDate;
+ const ScDPNumGroupInfo* mpNumInfo;
+ double mfMatchValue;
+ sal_Int32 mnDatePart;
+};
+
+// ----------------------------------------------------------------------------
+
+ScDPGroupDateFilter::ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart,
+ const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo) :
+ mpNullDate(pNullDate),
+ mpNumInfo(pNumInfo),
+ mfMatchValue(fMatchValue),
+ mnDatePart(nDatePart)
+{
+// fprintf(stdout, "ScDPCacheTable:DateGroupFilter::DateGroupFilter: match value = %g; date part = %ld\n",
+// mfMatchValue, mnDatePart);
+}
+bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const
+{
+ using namespace ::com::sun::star::sheet;
+ using ::rtl::math::approxFloor;
+ using ::rtl::math::approxEqual;
+
+ if ( !rCellData.IsValue() )
+ return false;
+// ScDPCacheCell rCell( rCellData.fValue );
+ if (!mpNumInfo)
+ return false;
+
+ // Start and end dates are inclusive. (An end date without a time value
+ // is included, while an end date with a time value is not.)
+
+ if ( rCellData.GetValue() < mpNumInfo->Start && !approxEqual(rCellData.GetValue(), mpNumInfo->Start) )
+ return static_cast<sal_Int32>(mfMatchValue) == SC_DP_DATE_FIRST;
+
+ if ( rCellData.GetValue() > mpNumInfo->End && !approxEqual(rCellData.GetValue(), mpNumInfo->End) )
+ return static_cast<sal_Int32>(mfMatchValue) == SC_DP_DATE_LAST;
+
+ if (mnDatePart == DataPilotFieldGroupBy::HOURS || mnDatePart == DataPilotFieldGroupBy::MINUTES ||
+ mnDatePart == DataPilotFieldGroupBy::SECONDS)
+ {
+ // handle time
+ // (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded)
+
+ double time = rCellData.GetValue() - approxFloor(rCellData.GetValue());
+ long seconds = static_cast<long>(approxFloor(time*D_TIMEFACTOR + 0.5));
+
+ switch (mnDatePart)
+ {
+ case DataPilotFieldGroupBy::HOURS:
+ {
+ sal_Int32 hrs = seconds / 3600;
+ sal_Int32 matchHrs = static_cast<sal_Int32>(mfMatchValue);
+ return hrs == matchHrs;
+ }
+ case DataPilotFieldGroupBy::MINUTES:
+ {
+ sal_Int32 minutes = (seconds % 3600) / 60;
+ sal_Int32 matchMinutes = static_cast<sal_Int32>(mfMatchValue);
+ return minutes == matchMinutes;
+ }
+ case DataPilotFieldGroupBy::SECONDS:
+ {
+ sal_Int32 sec = seconds % 60;
+ sal_Int32 matchSec = static_cast<sal_Int32>(mfMatchValue);
+ return sec == matchSec;
+ }
+ default:
+ DBG_ERROR("invalid time part");
+ }
+ return false;
+ }
+
+ Date date = *mpNullDate + static_cast<long>(approxFloor(rCellData.GetValue()));
+ switch (mnDatePart)
+ {
+ case DataPilotFieldGroupBy::YEARS:
+ {
+ sal_Int32 year = static_cast<sal_Int32>(date.GetYear());
+ sal_Int32 matchYear = static_cast<sal_Int32>(mfMatchValue);
+ return year == matchYear;
+ }
+ case DataPilotFieldGroupBy::QUARTERS:
+ {
+ sal_Int32 qtr = 1 + (static_cast<sal_Int32>(date.GetMonth()) - 1) / 3;
+ sal_Int32 matchQtr = static_cast<sal_Int32>(mfMatchValue);
+ return qtr == matchQtr;
+ }
+ case DataPilotFieldGroupBy::MONTHS:
+ {
+ sal_Int32 month = static_cast<sal_Int32>(date.GetMonth());
+ sal_Int32 matchMonth = static_cast<sal_Int32>(mfMatchValue);
+ return month == matchMonth;
+ }
+ case DataPilotFieldGroupBy::DAYS:
+ {
+ Date yearStart(1, 1, date.GetYear());
+ sal_Int32 days = (date - yearStart) + 1; // Jan 01 has value 1
+ if (days >= 60 && !date.IsLeapYear())
+ {
+ // This is not a leap year. Adjust the value accordingly.
+ ++days;
+ }
+ sal_Int32 matchDays = static_cast<sal_Int32>(mfMatchValue);
+ return days == matchDays;
+ }
+ default:
+ DBG_ERROR("invalid date part");
+ }
+
+ return false;
+}
+// -----------------------------------------------------------------------
+
+ScDPDateGroupHelper::ScDPDateGroupHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ) :
+ aNumInfo( rInfo ),
+ nDatePart( nPart )
+{
+}
+
+ScDPDateGroupHelper::~ScDPDateGroupHelper()
+{
+}
+
+String lcl_GetTwoDigitString( sal_Int32 nValue )
+{
+ String aRet = String::CreateFromInt32( nValue );
+ if ( aRet.Len() < 2 )
+ aRet.Insert( (sal_Unicode)'0', 0 );
+ return aRet;
+}
+
+String lcl_GetDateGroupName( sal_Int32 nDatePart, sal_Int32 nValue, SvNumberFormatter* pFormatter )
+{
+ String aRet;
+ switch ( nDatePart )
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
+ aRet = String::CreateFromInt32( nValue );
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS:
+ aRet = ScGlobal::pLocaleData->getQuarterAbbreviation( (sal_Int16)(nValue - 1) ); // nValue is 1-based
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
+ //! cache getMonths() result?
+ aRet = ScGlobal::GetCalendar()->getDisplayName(
+ ::com::sun::star::i18n::CalendarDisplayIndex::MONTH,
+ sal_Int16(nValue-1), 0 ); // 0-based, get short name
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS:
+ {
+ Date aDate( 1, 1, SC_DP_LEAPYEAR );
+ aDate += ( nValue - 1 ); // nValue is 1-based
+ Date aNullDate = *(pFormatter->GetNullDate());
+ long nDays = aDate - aNullDate;
+
+ ULONG nFormat = pFormatter->GetFormatIndex( NF_DATE_SYS_DDMMM, ScGlobal::eLnge );
+ Color* pColor;
+ pFormatter->GetOutputString( nDays, nFormat, aRet, &pColor );
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS:
+ //! allow am/pm format?
+ aRet = lcl_GetTwoDigitString( nValue );
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES:
+ case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS:
+ aRet = ScGlobal::pLocaleData->getTimeSep();
+ aRet.Append( lcl_GetTwoDigitString( nValue ) );
+ break;
+ default:
+ DBG_ERROR("invalid date part");
+ }
+ return aRet;
+}
+
+sal_Int32 lcl_GetDatePartValue( double fValue, sal_Int32 nDatePart, SvNumberFormatter* pFormatter,
+ const ScDPNumGroupInfo* pNumInfo )
+{
+ // Start and end are inclusive
+ // (End date without a time value is included, with a time value it's not)
+
+ if ( pNumInfo )
+ {
+ if ( fValue < pNumInfo->Start && !rtl::math::approxEqual( fValue, pNumInfo->Start ) )
+ return SC_DP_DATE_FIRST;
+ if ( fValue > pNumInfo->End && !rtl::math::approxEqual( fValue, pNumInfo->End ) )
+ return SC_DP_DATE_LAST;
+ }
+
+ sal_Int32 nResult = 0;
+
+ if ( nDatePart == com::sun::star::sheet::DataPilotFieldGroupBy::HOURS || nDatePart == com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES || nDatePart == com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS )
+ {
+ // handle time
+ // (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded)
+
+ double fTime = fValue - ::rtl::math::approxFloor(fValue);
+ long nSeconds = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5);
+
+ switch ( nDatePart )
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS:
+ nResult = nSeconds / 3600;
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES:
+ nResult = ( nSeconds % 3600 ) / 60;
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS:
+ nResult = nSeconds % 60;
+ break;
+ }
+ }
+ else
+ {
+ Date aDate = *(pFormatter->GetNullDate());
+ aDate += (long)::rtl::math::approxFloor( fValue );
+
+ switch ( nDatePart )
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
+ nResult = aDate.GetYear();
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS:
+ nResult = 1 + ( aDate.GetMonth() - 1 ) / 3; // 1..4
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
+ nResult = aDate.GetMonth(); // 1..12
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS:
+ {
+ Date aYearStart( 1, 1, aDate.GetYear() );
+ nResult = ( aDate - aYearStart ) + 1; // Jan 01 has value 1
+ if ( nResult >= 60 && !aDate.IsLeapYear() )
+ {
+ // days are counted from 1 to 366 - if not from a leap year, adjust
+ ++nResult;
+ }
+ }
+ break;
+ default:
+ DBG_ERROR("invalid date part");
+ }
+ }
+
+ return nResult;
+}
+
+BOOL lcl_DateContained( sal_Int32 nGroupPart, const ScDPItemData& rGroupData,
+ sal_Int32 nBasePart, const ScDPItemData& rBaseData )
+{
+ if ( !rGroupData.IsValue() || !rBaseData.IsValue() )
+ {
+ // non-numeric entries involved: only match equal entries
+ return rGroupData.IsCaseInsEqual( rBaseData );
+ }
+
+ // no approxFloor needed, values were created from integers
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+ sal_Int32 nGroupValue = (sal_Int32) rGroupData.GetValue();
+ sal_Int32 nBaseValue = (sal_Int32) rBaseData.GetValue();
+// End Comments
+ if ( nBasePart > nGroupPart )
+ {
+ // switch, so the base part is the smaller (inner) part
+
+ ::std::swap( nGroupPart, nBasePart );
+ ::std::swap( nGroupValue, nBaseValue );
+ }
+
+ if ( nGroupValue == SC_DP_DATE_FIRST || nGroupValue == SC_DP_DATE_LAST ||
+ nBaseValue == SC_DP_DATE_FIRST || nBaseValue == SC_DP_DATE_LAST )
+ {
+ // first/last entry matches only itself
+ return ( nGroupValue == nBaseValue );
+ }
+
+ BOOL bContained = TRUE;
+ switch ( nBasePart ) // inner part
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
+ // a month is only contained in its quarter
+ if ( nGroupPart == com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS )
+ {
+ // months and quarters are both 1-based
+ bContained = ( nGroupValue - 1 == ( nBaseValue - 1 ) / 3 );
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS:
+ // a day is only contained in its quarter or month
+ if ( nGroupPart == com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS || nGroupPart == com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS )
+ {
+ Date aDate( 1, 1, SC_DP_LEAPYEAR );
+ aDate += ( nBaseValue - 1 ); // days are 1-based
+ sal_Int32 nCompare = aDate.GetMonth();
+ if ( nGroupPart == com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS )
+ nCompare = ( ( nCompare - 1 ) / 3 ) + 1; // get quarter from date
+
+ bContained = ( nGroupValue == nCompare );
+ }
+ break;
+
+ // other parts: everything is contained
+ }
+
+ return bContained;
+}
+
+String lcl_GetSpecialDateName( double fValue, bool bFirst, SvNumberFormatter* pFormatter )
+{
+ rtl::OUStringBuffer aBuffer;
+ aBuffer.append((sal_Unicode)( bFirst ? '<' : '>' ));
+ lcl_AppendDateStr( aBuffer, fValue, pFormatter );
+ return aBuffer.makeStringAndClear();
+}
+
+void ScDPDateGroupHelper::FillColumnEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, std::vector< SCROW >& rEntries, const std::vector< SCROW >& rOriginal ) const
+{
+ // auto min/max is only used for "Years" part, but the loop is always needed
+ double fSourceMin = 0.0;
+ double fSourceMax = 0.0;
+ bool bFirst = true;
+
+ size_t nOriginalCount = rOriginal.size();
+ for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++)
+ {
+ const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim, rOriginal[nOriginalPos] );
+ if ( pItemData->HasStringData() )
+ {
+ // string data: just copy
+ lcl_Insert( nSourceDim, pCache , rEntries, rOriginal[nOriginalPos] );
+ }
+ else
+ {
+ double fSourceValue = pItemData->GetValue();
+ if ( bFirst )
+ {
+ fSourceMin = fSourceMax = fSourceValue;
+ bFirst = false;
+ }
+ else
+ {
+ if ( fSourceValue < fSourceMin )
+ fSourceMin = fSourceValue;
+ if ( fSourceValue > fSourceMax )
+ fSourceMax = fSourceValue;
+ }
+ }
+ }
+
+ // For the start/end values, use the same date rounding as in ScDPNumGroupDimension::GetNumEntries
+ // (but not for the list of available years):
+ if ( aNumInfo.AutoStart )
+ const_cast<ScDPDateGroupHelper*>(this)->aNumInfo.Start = rtl::math::approxFloor( fSourceMin );
+ if ( aNumInfo.AutoEnd )
+ const_cast<ScDPDateGroupHelper*>(this)->aNumInfo.End = rtl::math::approxFloor( fSourceMax ) + 1;
+
+ //! if not automatic, limit fSourceMin/fSourceMax for list of year values?
+ SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable();
+
+ long nStart = 0;
+ long nEnd = 0; // including
+
+ switch ( nDatePart )
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
+ nStart = lcl_GetDatePartValue( fSourceMin, com::sun::star::sheet::DataPilotFieldGroupBy::YEARS, pFormatter, NULL );
+ nEnd = lcl_GetDatePartValue( fSourceMax, com::sun::star::sheet::DataPilotFieldGroupBy::YEARS, pFormatter, NULL );
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS: nStart = 1; nEnd = 4; break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS: nStart = 1; nEnd = 12; break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS: nStart = 1; nEnd = 366; break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS: nStart = 0; nEnd = 23; break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES: nStart = 0; nEnd = 59; break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS: nStart = 0; nEnd = 59; break;
+ default:
+ DBG_ERROR("invalid date part");
+ }
+
+ for ( sal_Int32 nValue = nStart; nValue <= nEnd; nValue++ )
+ {
+ String aName = lcl_GetDateGroupName( nDatePart, nValue, pFormatter );
+ lcl_InsertValue<false>( nSourceDim, pCache, rEntries, aName, nValue, nDatePart );
+ }
+
+ // add first/last entry (min/max)
+ String aFirstName = lcl_GetSpecialDateName( aNumInfo.Start, true, pFormatter );
+ lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aFirstName, SC_DP_DATE_FIRST, nDatePart );
+
+ String aLastName = lcl_GetSpecialDateName( aNumInfo.End, false, pFormatter );
+ lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aLastName, SC_DP_DATE_LAST, nDatePart );
+}
+
+// -----------------------------------------------------------------------
+
+ScDPGroupItem::ScDPGroupItem( const ScDPItemData& rName ) :
+ aGroupName( rName )
+{
+}
+
+ScDPGroupItem::~ScDPGroupItem()
+{
+}
+
+void ScDPGroupItem::AddElement( const ScDPItemData& rName )
+{
+ aElements.push_back( rName );
+}
+
+bool ScDPGroupItem::HasElement( const ScDPItemData& rData ) const
+{
+ for ( ScDPItemDataVec::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
+ if ( aIter->IsCaseInsEqual( rData ) )
+ return true;
+
+ return false;
+}
+
+bool ScDPGroupItem::HasCommonElement( const ScDPGroupItem& rOther ) const
+{
+ for ( ScDPItemDataVec::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
+ if ( rOther.HasElement( *aIter ) )
+ return true;
+
+ return false;
+}
+
+void ScDPGroupItem::FillGroupFilter( ScDPCacheTable::GroupFilter& rFilter ) const
+{
+ ScDPItemDataVec::const_iterator itrEnd = aElements.end();
+ for (ScDPItemDataVec::const_iterator itr = aElements.begin(); itr != itrEnd; ++itr)
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+ rFilter.addMatchItem(itr->GetString(), itr->GetValue(), itr->IsValue());
+// End Comments
+}
+
+// -----------------------------------------------------------------------
+
+ScDPGroupDimension::ScDPGroupDimension( long nSource, const String& rNewName ) :
+ nSourceDim( nSource ),
+ nGroupDim( -1 ),
+ aGroupName( rNewName ),
+ pDateHelper( NULL )/*,
+ pCollection( NULL )*/
+{
+}
+
+ScDPGroupDimension::~ScDPGroupDimension()
+{
+ delete pDateHelper;
+ maMemberEntries.clear();
+}
+
+ScDPGroupDimension::ScDPGroupDimension( const ScDPGroupDimension& rOther ) :
+ nSourceDim( rOther.nSourceDim ),
+ nGroupDim( rOther.nGroupDim ),
+ aGroupName( rOther.aGroupName ),
+ pDateHelper( NULL ),
+ aItems( rOther.aItems )
+{
+ if ( rOther.pDateHelper )
+ pDateHelper = new ScDPDateGroupHelper( *rOther.pDateHelper );
+}
+
+ScDPGroupDimension& ScDPGroupDimension::operator=( const ScDPGroupDimension& rOther )
+{
+ nSourceDim = rOther.nSourceDim;
+ nGroupDim = rOther.nGroupDim;
+ aGroupName = rOther.aGroupName;
+ aItems = rOther.aItems;
+
+ delete pDateHelper;
+ if ( rOther.pDateHelper )
+ pDateHelper = new ScDPDateGroupHelper( *rOther.pDateHelper );
+ else
+ pDateHelper = NULL;
+
+ return *this;
+}
+
+void ScDPGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
+{
+ delete pDateHelper;
+ pDateHelper = new ScDPDateGroupHelper( rInfo, nPart );
+}
+
+void ScDPGroupDimension::AddItem( const ScDPGroupItem& rItem )
+{
+ aItems.push_back( rItem );
+}
+
+void ScDPGroupDimension::SetGroupDim( long nDim )
+{
+ nGroupDim = nDim;
+}
+// Wang Xu Ming -- 2009-9-2
+// DataPilot Migration - Cache&&Performance
+const std::vector< SCROW >& ScDPGroupDimension::GetColumnEntries( const ScDPCacheTable& rCacheTable, const std::vector< SCROW >& rOriginal ) const
+{
+ if ( maMemberEntries.empty() )
+ {
+ if ( pDateHelper )
+ {
+ pDateHelper->FillColumnEntries( (SCCOL)GetSourceDim(), rCacheTable.GetCache(), maMemberEntries, rOriginal );
+ }
+ else
+ {
+ for (size_t i =0; i < rOriginal.size( ); i ++)
+ {
+ const ScDPItemData* pItemData = rCacheTable.GetCache()->GetItemDataById( (SCCOL)GetSourceDim(), rOriginal[i] );
+ if ( !pItemData || !GetGroupForData( *pItemData ) )
+ {
+ // not in any group -> add as its own group
+ maMemberEntries.push_back( rOriginal[i] );
+ }
+ }
+
+ long nCount = aItems.size();
+ for (long i=0; i<nCount; i++)
+ {
+ SCROW nNew = rCacheTable.GetCache()->GetAdditionalItemID( aItems[i].GetName() );
+ lcl_Insert ( (SCCOL)GetSourceDim(), rCacheTable.GetCache(), maMemberEntries, nNew );
+ }
+ }
+ }
+ return maMemberEntries;
+}
+
+// End Comments
+
+
+const ScDPGroupItem* ScDPGroupDimension::GetGroupForData( const ScDPItemData& rData ) const
+{
+ for ( ScDPGroupItemVec::const_iterator aIter(aItems.begin()); aIter != aItems.end(); aIter++ )
+ if ( aIter->HasElement( rData ) )
+ return &*aIter;
+
+ return NULL;
+}
+
+const ScDPGroupItem* ScDPGroupDimension::GetGroupForName( const ScDPItemData& rName ) const
+{
+ for ( ScDPGroupItemVec::const_iterator aIter(aItems.begin()); aIter != aItems.end(); aIter++ )
+ if ( aIter->GetName().IsCaseInsEqual( rName ) )
+ return &*aIter;
+
+ return NULL;
+}
+
+const ScDPGroupItem* ScDPGroupDimension::GetGroupByIndex( size_t nIndex ) const
+{
+ if (nIndex >= aItems.size())
+ return NULL;
+
+ return &aItems[nIndex];
+}
+
+void ScDPGroupDimension::DisposeData()
+{
+ maMemberEntries.clear();
+}
+
+// -----------------------------------------------------------------------
+
+ScDPNumGroupDimension::ScDPNumGroupDimension() :
+ pDateHelper( NULL ),
+ bHasNonInteger( false ),
+ cDecSeparator( 0 )
+{
+}
+
+ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupInfo& rInfo ) :
+ aGroupInfo( rInfo ),
+ pDateHelper( NULL ),
+ bHasNonInteger( false ),
+ cDecSeparator( 0 )
+{
+}
+
+ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupDimension& rOther ) :
+ aGroupInfo( rOther.aGroupInfo ),
+ pDateHelper( NULL ),
+ bHasNonInteger( false ),
+ cDecSeparator( 0 )
+{
+ if ( rOther.pDateHelper )
+ pDateHelper = new ScDPDateGroupHelper( *rOther.pDateHelper );
+}
+
+ScDPNumGroupDimension& ScDPNumGroupDimension::operator=( const ScDPNumGroupDimension& rOther )
+{
+ aGroupInfo = rOther.aGroupInfo;
+
+ delete pDateHelper;
+ if ( rOther.pDateHelper )
+ pDateHelper = new ScDPDateGroupHelper( *rOther.pDateHelper );
+ else
+ pDateHelper = NULL;
+
+ bHasNonInteger = false;
+ return *this;
+}
+
+void ScDPNumGroupDimension::DisposeData()
+{
+ bHasNonInteger = false;
+ maMemberEntries.clear();
+}
+
+ScDPNumGroupDimension::~ScDPNumGroupDimension()
+{
+ delete pDateHelper;
+}
+
+void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
+{
+ delete pDateHelper;
+ pDateHelper = new ScDPDateGroupHelper( rInfo, nPart );
+
+ aGroupInfo.Enable = sal_True; //! or query both?
+}
+
+const std::vector< SCROW >& ScDPNumGroupDimension::GetNumEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache,
+ const std::vector< SCROW >& rOriginal ) const
+{
+ if ( maMemberEntries.empty() )
+ {
+ SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable();
+
+ if ( pDateHelper )
+ pDateHelper->FillColumnEntries( nSourceDim, pCache, maMemberEntries,rOriginal );
+ else
+ {
+ // Copy textual entries.
+ // Also look through the source entries for non-integer numbers, minimum and maximum.
+ // GetNumEntries (GetColumnEntries) must be called before accessing the groups
+ // (this in ensured by calling ScDPLevel::GetMembersObject for all column/row/page
+ // dimensions before iterating over the values).
+
+ cDecSeparator = ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0);
+
+ // non-integer GroupInfo values count, too
+ bHasNonInteger = ( !aGroupInfo.AutoStart && !IsInteger( aGroupInfo.Start ) ) ||
+ ( !aGroupInfo.AutoEnd && !IsInteger( aGroupInfo.End ) ) ||
+ !IsInteger( aGroupInfo.Step );
+ double fSourceMin = 0.0;
+ double fSourceMax = 0.0;
+ bool bFirst = true;
+
+ size_t nOriginalCount = rOriginal.size();
+ for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++)
+ {
+ const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim , rOriginal[nOriginalPos] );
+
+ if ( pItemData && pItemData ->HasStringData() )
+ {
+ lcl_Insert( nSourceDim, pCache, maMemberEntries, rOriginal[nOriginalPos] );
+ }
+ else
+ {
+ double fSourceValue = pItemData->GetValue();
+ if ( bFirst )
+ {
+ fSourceMin = fSourceMax = fSourceValue;
+ bFirst = false;
+ }
+ else
+ {
+ if ( fSourceValue < fSourceMin )
+ fSourceMin = fSourceValue;
+ if ( fSourceValue > fSourceMax )
+ fSourceMax = fSourceValue;
+ }
+ if ( !bHasNonInteger && !IsInteger( fSourceValue ) )
+ {
+ // if any non-integer numbers are involved, the group labels are
+ // shown including their upper limit
+ bHasNonInteger = true;
+ }
+ }
+ }
+
+ if ( aGroupInfo.DateValues )
+ {
+ // special handling for dates: always integer, round down limits
+ bHasNonInteger = false;
+ fSourceMin = rtl::math::approxFloor( fSourceMin );
+ fSourceMax = rtl::math::approxFloor( fSourceMax ) + 1;
+ }
+
+ if ( aGroupInfo.AutoStart )
+ const_cast<ScDPNumGroupDimension*>(this)->aGroupInfo.Start = fSourceMin;
+ if ( aGroupInfo.AutoEnd )
+ const_cast<ScDPNumGroupDimension*>(this)->aGroupInfo.End = fSourceMax;
+
+ //! limit number of entries?
+
+ long nLoopCount = 0;
+ double fLoop = aGroupInfo.Start;
+
+ // Use "less than" instead of "less or equal" for the loop - don't create a group
+ // that consists only of the end value. Instead, the end value is then included
+ // in the last group (last group is bigger than the others).
+ // The first group has to be created nonetheless. GetNumGroupForValue has corresponding logic.
+
+ bool bFirstGroup = true;
+ while ( bFirstGroup || ( fLoop < aGroupInfo.End && !rtl::math::approxEqual( fLoop, aGroupInfo.End ) ) )
+ {
+ String aName = lcl_GetNumGroupName( fLoop, aGroupInfo, bHasNonInteger, cDecSeparator, pFormatter );
+ // create a numerical entry to ensure proper sorting
+ // (in FillMemberResults this needs special handling)
+ lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aName, fLoop );
+ ++nLoopCount;
+ fLoop = aGroupInfo.Start + nLoopCount * aGroupInfo.Step;
+ bFirstGroup = false;
+
+ // ScDPItemData values are compared with approxEqual
+ }
+
+ String aFirstName = lcl_GetSpecialNumGroupName( aGroupInfo.Start, true, cDecSeparator, aGroupInfo.DateValues, pFormatter );
+ lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aFirstName, aGroupInfo.Start - aGroupInfo.Step );
+
+ String aLastName = lcl_GetSpecialNumGroupName( aGroupInfo.End, false, cDecSeparator, aGroupInfo.DateValues, pFormatter );
+ lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aLastName, aGroupInfo.End + aGroupInfo.Step );
+ }
+ }
+ return maMemberEntries;
+}
+
+ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) :
+ ScDPTableData(pDocument, pSource->GetCacheId() ),
+ pSourceData( pSource ),
+ pDoc( pDocument )
+{
+ DBG_ASSERT( pSource, "ScDPGroupTableData: pSource can't be NULL" );
+
+ CreateCacheTable();
+ nSourceCount = pSource->GetColumnCount(); // real columns, excluding data layout
+ pNumGroups = new ScDPNumGroupDimension[nSourceCount];
+}
+
+ScDPGroupTableData::~ScDPGroupTableData()
+{
+ delete[] pNumGroups;
+}
+
+void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
+{
+ ScDPGroupDimension aNewGroup( rGroup );
+ aNewGroup.SetGroupDim( GetColumnCount() ); // new dimension will be at the end
+ aGroups.push_back( aNewGroup );
+ aGroupNames.insert( OUString(aNewGroup.GetName()) );
+}
+
+void ScDPGroupTableData::SetNumGroupDimension( long nIndex, const ScDPNumGroupDimension& rGroup )
+{
+ if ( nIndex < nSourceCount )
+ {
+ pNumGroups[nIndex] = rGroup;
+
+ // automatic minimum / maximum is handled in GetNumEntries
+ }
+}
+
+long ScDPGroupTableData::GetDimensionIndex( const String& rName )
+{
+ for (long i=0; i<nSourceCount; i++) // nSourceCount excludes data layout
+ if ( pSourceData->getDimensionName(i) == rName ) //! ignore case?
+ return i;
+ return -1; // none
+}
+
+long ScDPGroupTableData::GetColumnCount()
+{
+ return nSourceCount + aGroups.size();
+}
+
+bool ScDPGroupTableData::IsNumGroupDimension( long nDimension ) const
+{
+ return ( nDimension < nSourceCount && pNumGroups[nDimension].GetInfo().Enable );
+}
+
+void ScDPGroupTableData::GetNumGroupInfo( long nDimension, ScDPNumGroupInfo& rInfo,
+ bool& rNonInteger, sal_Unicode& rDecimal )
+{
+ if ( nDimension < nSourceCount )
+ {
+ rInfo = pNumGroups[nDimension].GetInfo();
+ rNonInteger = pNumGroups[nDimension].HasNonInteger();
+ rDecimal = pNumGroups[nDimension].GetDecSeparator();
+ }
+}
+// Wang Xu Ming - DataPilot migration
+long ScDPGroupTableData::GetMembersCount( long nDim )
+{
+ const std::vector< SCROW >& members = GetColumnEntries( nDim );
+ return members.size();
+}
+const std::vector< SCROW >& ScDPGroupTableData::GetColumnEntries( long nColumn )
+{
+ if ( nColumn >= nSourceCount )
+ {
+ if ( getIsDataLayoutDimension( nColumn) ) // data layout dimension?
+ nColumn = nSourceCount; // index of data layout in source data
+ else
+ {
+ const ScDPGroupDimension& rGroupDim = aGroups[nColumn - nSourceCount];
+ long nSourceDim = rGroupDim.GetSourceDim();
+ // collection is cached at pSourceData, GetColumnEntries can be called every time
+ const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nSourceDim );
+ return rGroupDim.GetColumnEntries( GetCacheTable(), rOriginal );
+ }
+ }
+
+ if ( IsNumGroupDimension( nColumn ) )
+ {
+ // dimension number is unchanged for numerical groups
+ const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nColumn );
+ return pNumGroups[nColumn].GetNumEntries( (SCCOL)nColumn, GetCacheTable().GetCache(), rOriginal );
+ }
+
+ return pSourceData->GetColumnEntries( nColumn );
+}
+
+const ScDPItemData* ScDPGroupTableData::GetMemberById( long nDim, long nId )
+{
+ if ( nDim >= nSourceCount )
+ {
+ if ( getIsDataLayoutDimension( nDim) )
+ nDim = nSourceCount;
+ else
+ {
+ const ScDPGroupDimension& rGroupDim = aGroups[nDim - nSourceCount];
+ nDim = rGroupDim.GetSourceDim();
+ }
+ }
+ return pSourceData->GetMemberById( nDim, nId );
+}
+
+String ScDPGroupTableData::getDimensionName(long nColumn)
+{
+ if ( nColumn >= nSourceCount )
+ {
+ if ( nColumn == sal::static_int_cast<long>( nSourceCount + aGroups.size() ) ) // data layout dimension?
+ nColumn = nSourceCount; // index of data layout in source data
+ else
+ return aGroups[nColumn - nSourceCount].GetName();
+ }
+
+ return pSourceData->getDimensionName( nColumn );
+}
+
+BOOL ScDPGroupTableData::getIsDataLayoutDimension(long nColumn)
+{
+ // position of data layout dimension is moved from source data
+ return ( nColumn == sal::static_int_cast<long>( nSourceCount + aGroups.size() ) ); // data layout dimension?
+}
+
+BOOL ScDPGroupTableData::IsDateDimension(long nDim)
+{
+ if ( nDim >= nSourceCount )
+ {
+ if ( nDim == sal::static_int_cast<long>( nSourceCount + aGroups.size() ) ) // data layout dimension?
+ nDim = nSourceCount; // index of data layout in source data
+ else
+ nDim = aGroups[nDim - nSourceCount].GetSourceDim(); // look at original dimension
+ }
+
+ return pSourceData->IsDateDimension( nDim );
+}
+
+ULONG ScDPGroupTableData::GetNumberFormat(long nDim)
+{
+ if ( nDim >= nSourceCount )
+ {
+ if ( nDim == sal::static_int_cast<long>( nSourceCount + aGroups.size() ) ) // data layout dimension?
+ nDim = nSourceCount; // index of data layout in source data
+ else
+ nDim = aGroups[nDim - nSourceCount].GetSourceDim(); // look at original dimension
+ }
+
+ return pSourceData->GetNumberFormat( nDim );
+}
+
+void ScDPGroupTableData::DisposeData()
+{
+ for ( ScDPGroupDimensionVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ aIter->DisposeData();
+
+ for ( long i=0; i<nSourceCount; i++ )
+ pNumGroups[i].DisposeData();
+
+ pSourceData->DisposeData();
+}
+
+void ScDPGroupTableData::SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty )
+{
+ pSourceData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
+}
+
+bool ScDPGroupTableData::IsRepeatIfEmpty()
+{
+ return pSourceData->IsRepeatIfEmpty();
+}
+
+void ScDPGroupTableData::CreateCacheTable()
+{
+ pSourceData->CreateCacheTable();
+}
+
+void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>& rCriteria)
+{
+ typedef hash_map<long, const ScDPGroupDimension*> GroupFieldMapType;
+ GroupFieldMapType aGroupFieldIds;
+ {
+ ScDPGroupDimensionVec::const_iterator itr = aGroups.begin(), itrEnd = aGroups.end();
+ for (; itr != itrEnd; ++itr)
+ aGroupFieldIds.insert( hash_map<long, const ScDPGroupDimension*>::value_type(itr->GetGroupDim(), &(*itr)) );
+ }
+
+ vector<ScDPCacheTable::Criterion> aNewCriteria;
+ aNewCriteria.reserve(rCriteria.size() + aGroups.size());
+
+ // Go through all the filtered field names and process them appropriately.
+
+ vector<ScDPCacheTable::Criterion>::const_iterator itrEnd = rCriteria.end();
+ GroupFieldMapType::const_iterator itrGrpEnd = aGroupFieldIds.end();
+ for (vector<ScDPCacheTable::Criterion>::const_iterator itr = rCriteria.begin(); itr != itrEnd; ++itr)
+ {
+ ScDPCacheTable::SingleFilter* pFilter = dynamic_cast<ScDPCacheTable::SingleFilter*>(itr->mpFilter.get());
+ if (!pFilter)
+ // We expect this to be a single filter.
+ continue;
+
+ GroupFieldMapType::const_iterator itrGrp = aGroupFieldIds.find(itr->mnFieldIndex);
+ if (itrGrp == itrGrpEnd)
+ {
+ if (IsNumGroupDimension(itr->mnFieldIndex))
+ {
+ // internal number group field
+ const ScDPNumGroupDimension& rNumGrpDim = pNumGroups[itr->mnFieldIndex];
+ const ScDPDateGroupHelper* pDateHelper = rNumGrpDim.GetDateHelper();
+ if (!pDateHelper)
+ {
+ // What do we do here !?
+ continue;
+ }
+
+ ScDPCacheTable::Criterion aCri;
+ aCri.mnFieldIndex = itr->mnFieldIndex;
+ aCri.mpFilter.reset(new ScDPGroupDateFilter(
+ pFilter->getMatchValue(), pDateHelper->GetDatePart(),
+ pDoc->GetFormatTable()->GetNullDate(), &pDateHelper->GetNumInfo()));
+
+ aNewCriteria.push_back(aCri);
+ }
+ else
+ {
+ // This is a regular source field.
+ aNewCriteria.push_back(*itr);
+ }
+ }
+ else
+ {
+ // This is an ordinary group field or external number group field.
+
+ const ScDPGroupDimension* pGrpDim = itrGrp->second;
+ long nSrcDim = pGrpDim->GetSourceDim();
+ const ScDPDateGroupHelper* pDateHelper = pGrpDim->GetDateHelper();
+
+ if (pDateHelper)
+ {
+ // external number group
+ ScDPCacheTable::Criterion aCri;
+ aCri.mnFieldIndex = nSrcDim; // use the source dimension, not the group dimension.
+ aCri.mpFilter.reset(new ScDPGroupDateFilter(
+ pFilter->getMatchValue(), pDateHelper->GetDatePart(),
+ pDoc->GetFormatTable()->GetNullDate(), &pDateHelper->GetNumInfo()));
+
+ aNewCriteria.push_back(aCri);
+ }
+ else
+ {
+ // normal group
+
+ // Note that each group dimension may have multiple group names!
+ size_t nGroupItemCount = pGrpDim->GetItemCount();
+ for (size_t i = 0; i < nGroupItemCount; ++i)
+ {
+ const ScDPGroupItem* pGrpItem = pGrpDim->GetGroupByIndex(i);
+ // Wang Xu Ming -- 2009-6-9
+ // DataPilot Migration
+ ScDPItemData aName( pFilter->getMatchString(),pFilter->getMatchValue(),pFilter->hasValue()) ;
+ /*aName.aString = pFilter->getMatchString();
+ aName.fValue = pFilter->getMatchValue();
+ aName.bHasValue = pFilter->hasValue();*/
+ // End Comments
+ if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName))
+ continue;
+
+ ScDPCacheTable::Criterion aCri;
+ aCri.mnFieldIndex = nSrcDim;
+ aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter());
+ ScDPCacheTable::GroupFilter* pGrpFilter =
+ static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get());
+
+ pGrpItem->FillGroupFilter(*pGrpFilter);
+ aNewCriteria.push_back(aCri);
+ }
+ }
+ }
+ }
+ rCriteria.swap(aNewCriteria);
+}
+
+void ScDPGroupTableData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
+{
+ vector<ScDPCacheTable::Criterion> aNewCriteria(rCriteria);
+ ModifyFilterCriteria(aNewCriteria);
+ pSourceData->FilterCacheTable(aNewCriteria, rCatDims);
+}
+
+void ScDPGroupTableData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
+{
+ vector<ScDPCacheTable::Criterion> aNewCriteria(rCriteria);
+ ModifyFilterCriteria(aNewCriteria);
+ pSourceData->GetDrillDownData(aNewCriteria, rCatDims, rData);
+}
+
+void ScDPGroupTableData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
+{
+ // #i111435# Inside FillRowDataFromCacheTable/GetItemData, virtual methods
+ // getIsDataLayoutDimension and GetSourceDim are used, so it has to be called
+ // with original rInfo, containing dimension indexes of the grouped data.
+
+ const ScDPCacheTable& rCacheTable = pSourceData->GetCacheTable();
+ sal_Int32 nRowSize = rCacheTable.getRowSize();
+ for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
+ {
+ if (!rCacheTable.isRowActive(nRow))
+ continue;
+
+ CalcRowData aData;
+ FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData);
+
+ if ( !rInfo.aColLevelDims.empty() )
+ FillGroupValues(&aData.aColData[0], rInfo.aColLevelDims.size(), &rInfo.aColLevelDims[0]);
+ if ( !rInfo.aRowLevelDims.empty() )
+ FillGroupValues(&aData.aRowData[0], rInfo.aRowLevelDims.size(), &rInfo.aRowLevelDims[0]);
+ if ( !rInfo.aPageDims.empty() )
+ FillGroupValues(&aData.aPageData[0], rInfo.aPageDims.size(), &rInfo.aPageDims[0]);
+
+ ProcessRowData(rInfo, aData, bAutoShow);
+ }
+}
+
+const ScDPCacheTable& ScDPGroupTableData::GetCacheTable() const
+{
+ return pSourceData->GetCacheTable();
+}
+
+void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pItemDataIndex, long nCount, const long* pDims )
+{
+ long nGroupedColumns = aGroups.size();
+
+ ScDPTableDataCache* pCache = GetCacheTable().GetCache();
+ for (long nDim=0; nDim<nCount; nDim++)
+ {
+ const ScDPDateGroupHelper* pDateHelper = NULL;
+
+ long nColumn = pDims[nDim];
+ long nSourceDim = nColumn;
+ if ( nColumn >= nSourceCount && nColumn < nSourceCount + nGroupedColumns )
+ {
+ const ScDPGroupDimension& rGroupDim = aGroups[nColumn - nSourceCount];
+ nSourceDim= rGroupDim.GetSourceDim();
+ pDateHelper = rGroupDim.GetDateHelper();
+ if ( !pDateHelper ) // date is handled below
+ {
+ const ScDPGroupItem* pGroupItem = rGroupDim.GetGroupForData( *GetMemberById( nSourceDim, pItemDataIndex[nDim] ));
+ if ( pGroupItem )
+ pItemDataIndex[nDim] = pCache->GetAdditionalItemID( pGroupItem->GetName() );
+ }
+ }
+ else if ( IsNumGroupDimension( nColumn ) )
+ {
+ pDateHelper = pNumGroups[nColumn].GetDateHelper();
+ if ( !pDateHelper ) // date is handled below
+ {
+ const ScDPItemData* pData = pCache->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]);
+ if ( pData ->IsValue() )
+ {
+ ScDPNumGroupInfo aNumInfo;
+ bool bHasNonInteger = false;
+ sal_Unicode cDecSeparator = 0;
+ GetNumGroupInfo( nColumn, aNumInfo, bHasNonInteger, cDecSeparator );
+ double fGroupValue;
+ String aGroupName = lcl_GetNumGroupForValue( pData->GetValue(),
+ aNumInfo, bHasNonInteger, cDecSeparator, fGroupValue, pDoc );
+ ScDPItemData aItemData ( aGroupName, fGroupValue, TRUE ) ;
+ pItemDataIndex[nDim] = pCache->GetAdditionalItemID( aItemData );
+ }
+ // else (textual) keep original value
+ }
+ }
+
+ if ( pDateHelper )
+ {
+ const ScDPItemData* pData = GetCacheTable().GetCache()->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]);
+ if ( pData ->IsValue() )
+ {
+ sal_Int32 nPartValue = lcl_GetDatePartValue(
+ pData->GetValue(), pDateHelper->GetDatePart(), pDoc->GetFormatTable(),
+ &pDateHelper->GetNumInfo() );
+// Wang Xu Ming -- 2009-9-7
+// DataPilot Migration - Cache&&Performance
+ //String aName = lcl_GetDateGroupName( pDateHelper, nPartValue, pDoc->GetFormatTable() );
+ ScDPItemData aItemData( pDateHelper->GetDatePart(), String(), nPartValue, ScDPItemData::MK_DATA|ScDPItemData::MK_VAL|ScDPItemData::MK_DATEPART );
+ pItemDataIndex[nDim] = GetCacheTable().GetCache()->GetAdditionalItemID( aItemData );
+// End Comments
+ }
+ }
+ }
+}
+
+BOOL ScDPGroupTableData::IsBaseForGroup(long nDim) const
+{
+ for ( ScDPGroupDimensionVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ {
+ const ScDPGroupDimension& rDim = *aIter;
+ if ( rDim.GetSourceDim() == nDim )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+long ScDPGroupTableData::GetGroupBase(long nGroupDim) const
+{
+ for ( ScDPGroupDimensionVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ {
+ const ScDPGroupDimension& rDim = *aIter;
+ if ( rDim.GetGroupDim() == nGroupDim )
+ return rDim.GetSourceDim();
+ }
+
+ return -1; // none
+}
+
+BOOL ScDPGroupTableData::IsNumOrDateGroup(long nDimension) const
+{
+ // Virtual method from ScDPTableData, used in result data to force text labels.
+
+ if ( nDimension < nSourceCount )
+ {
+ return pNumGroups[nDimension].GetInfo().Enable ||
+ pNumGroups[nDimension].GetDateHelper();
+ }
+
+ for ( ScDPGroupDimensionVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ {
+ const ScDPGroupDimension& rDim = *aIter;
+ if ( rDim.GetGroupDim() == nDimension )
+ return ( rDim.GetDateHelper() != NULL );
+ }
+
+ return FALSE;
+}
+
+BOOL ScDPGroupTableData::IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex,
+ const ScDPItemData& rBaseData, long nBaseIndex ) const
+{
+ for ( ScDPGroupDimensionVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ {
+ const ScDPGroupDimension& rDim = *aIter;
+ if ( rDim.GetGroupDim() == nGroupIndex && rDim.GetSourceDim() == nBaseIndex )
+ {
+ const ScDPDateGroupHelper* pGroupDateHelper = rDim.GetDateHelper();
+ if ( pGroupDateHelper )
+ {
+ //! transform rBaseData (innermost date part)
+ //! -> always do "HasCommonElement" style comparison
+ //! (only Quarter, Month, Day affected)
+
+ const ScDPDateGroupHelper* pBaseDateHelper = NULL;
+ if ( nBaseIndex < nSourceCount )
+ pBaseDateHelper = pNumGroups[nBaseIndex].GetDateHelper();
+
+ // If there's a date group dimension, the base dimension must have
+ // date group information, too.
+ if ( !pBaseDateHelper )
+ {
+ DBG_ERROR( "mix of date and non-date groups" );
+ return TRUE;
+ }
+
+ sal_Int32 nGroupPart = pGroupDateHelper->GetDatePart();
+ sal_Int32 nBasePart = pBaseDateHelper->GetDatePart();
+ return lcl_DateContained( nGroupPart, rGroupData, nBasePart, rBaseData );
+ }
+ else
+ {
+ // If the item is in a group, only that group is valid.
+ // If the item is not in any group, its own name is valid.
+
+ const ScDPGroupItem* pGroup = rDim.GetGroupForData( rBaseData );
+ return pGroup ? pGroup->GetName().IsCaseInsEqual( rGroupData ) :
+ rGroupData.IsCaseInsEqual( rBaseData );
+ }
+ }
+ }
+
+ DBG_ERROR("IsInGroup: no group dimension found");
+ return TRUE;
+}
+
+BOOL ScDPGroupTableData::HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex,
+ const ScDPItemData& rSecondData, long nSecondIndex ) const
+{
+ const ScDPGroupDimension* pFirstDim = NULL;
+ const ScDPGroupDimension* pSecondDim = NULL;
+ for ( ScDPGroupDimensionVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
+ {
+ const ScDPGroupDimension* pDim = &(*aIter);
+ if ( pDim->GetGroupDim() == nFirstIndex )
+ pFirstDim = pDim;
+ else if ( pDim->GetGroupDim() == nSecondIndex )
+ pSecondDim = pDim;
+ }
+ if ( pFirstDim && pSecondDim )
+ {
+ const ScDPDateGroupHelper* pFirstDateHelper = pFirstDim->GetDateHelper();
+ const ScDPDateGroupHelper* pSecondDateHelper = pSecondDim->GetDateHelper();
+ if ( pFirstDateHelper || pSecondDateHelper )
+ {
+ // If one is a date group dimension, the other one must be, too.
+ if ( !pFirstDateHelper || !pSecondDateHelper )
+ {
+ DBG_ERROR( "mix of date and non-date groups" );
+ return TRUE;
+ }
+
+ sal_Int32 nFirstPart = pFirstDateHelper->GetDatePart();
+ sal_Int32 nSecondPart = pSecondDateHelper->GetDatePart();
+ return lcl_DateContained( nFirstPart, rFirstData, nSecondPart, rSecondData );
+ }
+
+ const ScDPGroupItem* pFirstItem = pFirstDim->GetGroupForName( rFirstData );
+ const ScDPGroupItem* pSecondItem = pSecondDim->GetGroupForName( rSecondData );
+ if ( pFirstItem && pSecondItem )
+ {
+ // two existing groups -> TRUE if they have a common element
+ return pFirstItem->HasCommonElement( *pSecondItem );
+ }
+ else if ( pFirstItem )
+ {
+ // "automatic" group contains only its own name
+ return pFirstItem->HasElement( rSecondData );
+ }
+ else if ( pSecondItem )
+ {
+ // "automatic" group contains only its own name
+ return pSecondItem->HasElement( rFirstData );
+ }
+ else
+ {
+ // no groups -> TRUE if equal
+ return rFirstData.IsCaseInsEqual( rSecondData );
+ }
+ }
+
+ DBG_ERROR("HasCommonElement: no group dimension found");
+ return TRUE;
+}
+
+long ScDPGroupTableData::GetSourceDim( long nDim )
+{
+ if ( getIsDataLayoutDimension( nDim ) )
+ return nSourceCount;
+ if ( nDim >= nSourceCount && nDim < nSourceCount +(long) aGroups.size() )
+ {
+ const ScDPGroupDimension& rGroupDim = aGroups[nDim - nSourceCount];
+ return rGroupDim.GetSourceDim();
+ }
+ return nDim;
+}
+ long ScDPGroupTableData::Compare( long nDim, long nDataId1, long nDataId2)
+{
+ if ( getIsDataLayoutDimension(nDim) )
+ return 0;
+ return ScDPItemData::Compare( *GetMemberById(nDim, nDataId1),*GetMemberById(nDim, nDataId2) );
+}
+// -----------------------------------------------------------------------
+
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
new file mode 100644
index 000000000000..29ba9f15dc92
--- /dev/null
+++ b/sc/source/core/data/dpobject.cxx
@@ -0,0 +1,2642 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpobject.hxx"
+#include "dptabsrc.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dpoutput.hxx"
+#include "dpshttab.hxx"
+#include "dpsdbtab.hxx"
+#include "dpgroup.hxx"
+#include "document.hxx"
+#include "rechead.hxx"
+#include "pivot.hxx" // PIVOT_DATA_FIELD
+#include "dapiuno.hxx" // ScDataPilotConversion
+#include "miscuno.hxx"
+#include "scerrors.hxx"
+#include "refupdat.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "attrib.hxx"
+#include "scitems.hxx"
+#include "unonames.hxx"
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+#include "dpglobal.hxx"
+#include "globstr.hrc"
+// End Comments
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
+#include <com/sun/star/sheet/DimensionFlags.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <svl/zforlist.hxx> // IsNumberFormat
+
+#include <vector>
+#include <stdio.h>
+
+using namespace com::sun::star;
+using ::std::vector;
+using ::boost::shared_ptr;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::lang::XComponent;
+using ::com::sun::star::sheet::DataPilotTableHeaderData;
+using ::com::sun::star::sheet::DataPilotTablePositionData;
+using ::com::sun::star::beans::XPropertySet;
+using ::rtl::OUString;
+
+
+// -----------------------------------------------------------------------
+
+#define SCDPSOURCE_SERVICE "com.sun.star.sheet.DataPilotSource"
+
+// -----------------------------------------------------------------------
+
+// incompatible versions of data pilot files
+#define SC_DP_VERSION_CURRENT 6
+
+// type of source data
+#define SC_DP_SOURCE_SHEET 0
+#define SC_DP_SOURCE_DATABASE 1
+#define SC_DP_SOURCE_SERVICE 2
+
+// -----------------------------------------------------------------------
+
+//! move to a header file
+#define DP_PROP_COLUMNGRAND "ColumnGrand"
+#define DP_PROP_FUNCTION "Function"
+#define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows"
+#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
+//#define DP_PROP_ISVISIBLE "IsVisible"
+#define DP_PROP_ORIENTATION "Orientation"
+#define DP_PROP_ORIGINAL "Original"
+#define DP_PROP_POSITION "Position"
+#define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty"
+#define DP_PROP_ROWGRAND "RowGrand"
+#define DP_PROP_SHOWDETAILS "ShowDetails"
+#define DP_PROP_SHOWEMPTY "ShowEmpty"
+#define DP_PROP_SUBTOTALS "SubTotals"
+#define DP_PROP_USEDHIERARCHY "UsedHierarchy"
+
+// -----------------------------------------------------------------------
+
+USHORT lcl_GetDataGetOrientation( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
+{
+ long nRet = sheet::DataPilotFieldOrientation_HIDDEN;
+ if ( xSource.is() )
+ {
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ long nIntCount = xIntDims->getCount();
+ BOOL bFound = FALSE;
+ for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
+ {
+ uno::Reference<uno::XInterface> xIntDim =
+ ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+ if ( xDimProp.is() )
+ {
+ bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ //! error checking -- is "IsDataLayoutDimension" property required??
+ if (bFound)
+ nRet = ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ }
+ }
+ }
+ return static_cast< USHORT >( nRet );
+}
+
+// -----------------------------------------------------------------------
+
+ScDPObject::ScDPObject( ScDocument* pD ) :
+ pDoc( pD ),
+ pSaveData( NULL ),
+ pSheetDesc( NULL ),
+ pImpDesc( NULL ),
+ pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
+ pOutput( NULL ),
+ bSettingsChanged( FALSE ),
+ bAlive( FALSE ),
+ mnAutoFormatIndex( 65535 ),
+ bAllowMove( FALSE ),
+ nHeaderRows( 0 ),
+ mbHeaderLayout(false),
+ bRefresh( FALSE ), // Wang Xu Ming - DataPilot migration
+ mnCacheId( -1) // Wang Xu Ming - DataPilot migration
+{
+}
+
+ScDPObject::ScDPObject(const ScDPObject& r) :
+ ScDataObject(),
+ pDoc( r.pDoc ),
+ pSaveData( NULL ),
+ aTableName( r.aTableName ),
+ aTableTag( r.aTableTag ),
+ aOutRange( r.aOutRange ),
+ pSheetDesc( NULL ),
+ pImpDesc( NULL ),
+ pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
+ pOutput( NULL ),
+ bSettingsChanged( FALSE ),
+ bAlive( FALSE ),
+ mnAutoFormatIndex( r.mnAutoFormatIndex ),
+ bAllowMove( FALSE ),
+ nHeaderRows( r.nHeaderRows ),
+ mbHeaderLayout( r.mbHeaderLayout ),
+ bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration
+ mnCacheId ( r.mnCacheId ) // Wang Xu Ming - DataPilot migration
+{
+ if (r.pSaveData)
+ pSaveData = new ScDPSaveData(*r.pSaveData);
+ if (r.pSheetDesc)
+ pSheetDesc = new ScSheetSourceDesc(*r.pSheetDesc);
+ if (r.pImpDesc)
+ pImpDesc = new ScImportSourceDesc(*r.pImpDesc);
+ if (r.pServDesc)
+ pServDesc = new ScDPServiceDesc(*r.pServDesc);
+ // xSource (and pOutput) is not copied
+}
+
+ScDPObject::~ScDPObject()
+{
+ delete pOutput;
+ delete pSaveData;
+ delete pSheetDesc;
+ delete pImpDesc;
+ delete pServDesc;
+ mnCacheId = -1; // Wang Xu Ming - DataPilot migration
+ InvalidateSource();
+}
+
+ScDataObject* ScDPObject::Clone() const
+{
+ return new ScDPObject(*this);
+}
+
+void ScDPObject::SetAlive(BOOL bSet)
+{
+ bAlive = bSet;
+}
+
+void ScDPObject::SetAllowMove(BOOL bSet)
+{
+ bAllowMove = bSet;
+}
+
+void ScDPObject::SetSaveData(const ScDPSaveData& rData)
+{
+ if ( pSaveData != &rData ) // API implementation modifies the original SaveData object
+ {
+ delete pSaveData;
+ pSaveData = new ScDPSaveData( rData );
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ if ( rData.GetCacheId() >= 0 )
+ mnCacheId = rData.GetCacheId();
+ else if ( mnCacheId >= 0 )
+ pSaveData->SetCacheId( mnCacheId );
+ // End Comments
+ }
+
+ InvalidateData(); // re-init source from SaveData
+}
+
+void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex)
+{
+ mnAutoFormatIndex = nIndex;
+}
+
+sal_uInt16 ScDPObject::GetAutoFormatIndex() const
+{
+ return mnAutoFormatIndex;
+}
+
+void ScDPObject::SetHeaderLayout (bool bUseGrid)
+{
+ mbHeaderLayout = bUseGrid;
+}
+
+bool ScDPObject::GetHeaderLayout() const
+{
+ return mbHeaderLayout;
+}
+
+void ScDPObject::SetOutRange(const ScRange& rRange)
+{
+ aOutRange = rRange;
+
+ if ( pOutput )
+ pOutput->SetPosition( rRange.aStart );
+}
+
+void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc)
+{
+ if ( pSheetDesc && rDesc == *pSheetDesc )
+ return; // nothing to do
+
+ DELETEZ( pImpDesc );
+ DELETEZ( pServDesc );
+
+ delete pImpDesc;
+ pSheetDesc = new ScSheetSourceDesc(rDesc);
+
+ // make valid QueryParam
+
+ pSheetDesc->aQueryParam.nCol1 = pSheetDesc->aSourceRange.aStart.Col();
+ pSheetDesc->aQueryParam.nRow1 = pSheetDesc->aSourceRange.aStart.Row();
+ pSheetDesc->aQueryParam.nCol2 = pSheetDesc->aSourceRange.aEnd.Col();
+ pSheetDesc->aQueryParam.nRow2 = pSheetDesc->aSourceRange.aEnd.Row();;
+ pSheetDesc->aQueryParam.bHasHeader = TRUE;
+
+ InvalidateSource(); // new source must be created
+}
+
+void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc)
+{
+ if ( pImpDesc && rDesc == *pImpDesc )
+ return; // nothing to do
+
+ DELETEZ( pSheetDesc );
+ DELETEZ( pServDesc );
+
+ delete pImpDesc;
+ pImpDesc = new ScImportSourceDesc(rDesc);
+
+ InvalidateSource(); // new source must be created
+}
+
+void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc)
+{
+ if ( pServDesc && rDesc == *pServDesc )
+ return; // nothing to do
+
+ DELETEZ( pSheetDesc );
+ DELETEZ( pImpDesc );
+
+ delete pServDesc;
+ pServDesc = new ScDPServiceDesc(rDesc);
+
+ InvalidateSource(); // new source must be created
+}
+
+void ScDPObject::WriteSourceDataTo( ScDPObject& rDest ) const
+{
+ if ( pSheetDesc )
+ rDest.SetSheetDesc( *pSheetDesc );
+ else if ( pImpDesc )
+ rDest.SetImportDesc( *pImpDesc );
+ else if ( pServDesc )
+ rDest.SetServiceData( *pServDesc );
+
+ // name/tag are not source data, but needed along with source data
+
+ rDest.aTableName = aTableName;
+ rDest.aTableTag = aTableTag;
+}
+
+void ScDPObject::WriteTempDataTo( ScDPObject& rDest ) const
+{
+ rDest.nHeaderRows = nHeaderRows;
+}
+
+BOOL ScDPObject::IsSheetData() const
+{
+ return ( pSheetDesc != NULL );
+}
+
+void ScDPObject::SetName(const String& rNew)
+{
+ aTableName = rNew;
+}
+
+void ScDPObject::SetTag(const String& rNew)
+{
+ aTableTag = rNew;
+}
+
+bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
+{
+ if (!pSaveData)
+ return false;
+
+ long nDataDimCount = pSaveData->GetDataDimensionCount();
+ if (nDataDimCount != 1)
+ // There has to be exactly one data dimension for the description to
+ // appear at top-left corner.
+ return false;
+
+ CreateOutput();
+ ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
+ return (rPos == aTabRange.aStart);
+}
+
+uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
+{
+ CreateObjects();
+ return xSource;
+}
+
+void ScDPObject::CreateOutput()
+{
+ CreateObjects();
+ if (!pOutput)
+ {
+ BOOL bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton();
+ pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton );
+ pOutput->SetHeaderLayout ( mbHeaderLayout );
+
+ long nOldRows = nHeaderRows;
+ nHeaderRows = pOutput->GetHeaderRows();
+
+ if ( bAllowMove && nHeaderRows != nOldRows )
+ {
+ long nDiff = nOldRows - nHeaderRows;
+ if ( nOldRows == 0 )
+ --nDiff;
+ if ( nHeaderRows == 0 )
+ ++nDiff;
+
+ long nNewRow = aOutRange.aStart.Row() + nDiff;
+ if ( nNewRow < 0 )
+ nNewRow = 0;
+
+ ScAddress aStart( aOutRange.aStart );
+ aStart.SetRow(nNewRow);
+ pOutput->SetPosition( aStart );
+
+ //! modify aOutRange?
+
+ bAllowMove = FALSE; // use only once
+ }
+ }
+}
+
+ScDPTableData* ScDPObject::GetTableData()
+{
+ if (!mpTableData)
+ {
+ shared_ptr<ScDPTableData> pData;
+ if ( pImpDesc )
+ {
+ // database data
+ pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc, GetCacheId()));
+ }
+ else
+ {
+ // cell data
+ if (!pSheetDesc)
+ {
+ DBG_ERROR("no source descriptor");
+ pSheetDesc = new ScSheetSourceDesc; // dummy defaults
+ }
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ pData.reset(new ScSheetDPData(pDoc, *pSheetDesc, GetCacheId()));
+ // End Comments
+ }
+
+ // grouping (for cell or database data)
+ if ( pSaveData && pSaveData->GetExistingDimensionData() )
+ {
+ shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pData, pDoc));
+ pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData);
+ pData = pGroupData;
+ }
+
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ if ( pData )
+ SetCacheId( pData->GetCacheId()); // resets mpTableData
+ // End Comments
+
+ mpTableData = pData; // after SetCacheId
+ }
+
+ return mpTableData.get();
+}
+
+void ScDPObject::CreateObjects()
+{
+ // if groups are involved, create a new source with the ScDPGroupTableData
+ if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() )
+ InvalidateSource();
+
+ if (!xSource.is())
+ {
+ //! cache DPSource and/or Output?
+
+ DBG_ASSERT( bAlive, "CreateObjects on non-inserted DPObject" );
+
+ DELETEZ( pOutput ); // not valid when xSource is changed
+
+ if ( pServDesc )
+ {
+ xSource = CreateSource( *pServDesc );
+ }
+
+ if ( !xSource.is() ) // database or sheet data, or error in CreateSource
+ {
+ DBG_ASSERT( !pServDesc, "DPSource could not be created" );
+ ScDPTableData* pData = GetTableData();
+
+ ScDPSource* pSource = new ScDPSource( pData );
+ xSource = pSource;
+
+ if ( pSaveData && bRefresh )
+ {
+ pSaveData->Refresh( xSource );
+ bRefresh = FALSE;
+ }
+ }
+ if (pSaveData )
+ pSaveData->WriteToSource( xSource );
+ }
+ else if (bSettingsChanged)
+ {
+ DELETEZ( pOutput ); // not valid when xSource is changed
+
+ uno::Reference<util::XRefreshable> xRef( xSource, uno::UNO_QUERY );
+ if (xRef.is())
+ {
+ try
+ {
+ xRef->refresh();
+ }
+ catch(uno::Exception&)
+ {
+ DBG_ERROR("exception in refresh");
+ }
+ }
+
+ if (pSaveData)
+ pSaveData->WriteToSource( xSource );
+ }
+ bSettingsChanged = FALSE;
+}
+
+void ScDPObject::InvalidateData()
+{
+ bSettingsChanged = TRUE;
+}
+
+void ScDPObject::InvalidateSource()
+{
+ Reference< XComponent > xObjectComp( xSource, UNO_QUERY );
+ if ( xObjectComp.is() )
+ {
+ try
+ {
+ xObjectComp->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ xSource = NULL;
+ mpTableData.reset();
+}
+
+ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow )
+{
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ rOverflow = pOutput->HasError(); // range overflow or exception from source
+ if ( rOverflow )
+ return ScRange( aOutRange.aStart );
+ else
+ {
+ // don't store the result in aOutRange, because nothing has been output yet
+ return pOutput->GetOutputRange();
+ }
+}
+
+void ScDPObject::Output( const ScAddress& rPos )
+{
+ // clear old output area
+ pDoc->DeleteAreaTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
+ aOutRange.aEnd.Col(), aOutRange.aEnd.Row(),
+ aOutRange.aStart.Tab(), IDF_ALL );
+ pDoc->RemoveFlagsTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
+ aOutRange.aEnd.Col(), aOutRange.aEnd.Row(),
+ aOutRange.aStart.Tab(), SC_MF_AUTO );
+
+ 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
+ aOutRange = pOutput->GetOutputRange();
+ const ScAddress& s = aOutRange.aStart;
+ const ScAddress& e = aOutRange.aEnd;
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+}
+
+const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
+{
+ CreateOutput();
+
+ if (pOutput->HasError())
+ return ScRange(aOutRange.aStart);
+
+ return pOutput->GetOutputRange(nType);
+}
+
+BOOL lcl_HasButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasButton();
+}
+
+void ScDPObject::RefreshAfterLoad()
+{
+ // apply drop-down attribute, initialize nHeaderRows, without accessing the source
+ // (button attribute must be present)
+
+ // simple test: block of button cells at the top, followed by an empty cell
+
+ SCCOL nFirstCol = aOutRange.aStart.Col();
+ SCROW nFirstRow = aOutRange.aStart.Row();
+ SCTAB nTab = aOutRange.aStart.Tab();
+
+ SCROW nInitial = 0;
+ SCROW nOutRows = aOutRange.aEnd.Row() + 1 - aOutRange.aStart.Row();
+ while ( nInitial + 1 < nOutRows && lcl_HasButton( pDoc, nFirstCol, nFirstRow + nInitial, nTab ) )
+ ++nInitial;
+
+ if ( nInitial + 1 < nOutRows &&
+ pDoc->IsBlockEmpty( nTab, nFirstCol, nFirstRow + nInitial, nFirstCol, nFirstRow + nInitial ) &&
+ aOutRange.aEnd.Col() > nFirstCol )
+ {
+ BOOL bFilterButton = IsSheetData(); // when available, filter button setting must be checked here
+
+ SCROW nSkip = bFilterButton ? 1 : 0;
+ for (SCROW nPos=nSkip; nPos<nInitial; nPos++)
+ pDoc->ApplyAttr( nFirstCol + 1, nFirstRow + nPos, nTab, ScMergeFlagAttr(SC_MF_AUTO) );
+
+ nHeaderRows = nInitial;
+ }
+ else
+ nHeaderRows = 0; // nothing found, no drop-down lists
+}
+
+void ScDPObject::BuildAllDimensionMembers()
+{
+ if (!pSaveData)
+ return;
+
+ // #i111857# don't always create empty mpTableData for external service.
+ // Ideally, xSource should be used instead of mpTableData.
+ if (pServDesc)
+ return;
+
+ pSaveData->BuildAllDimensionMembers(GetTableData());
+}
+
+bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
+{
+ vector<ScDPLabelData::Member> aMembers;
+ if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers))
+ return false;
+
+ size_t n = aMembers.size();
+ rNames.realloc(n);
+ for (size_t i = 0; i < n; ++i)
+ rNames[i] = aMembers[i].maName;
+
+ return true;
+}
+
+bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
+{
+ Reference< container::XNameAccess > xMembersNA;
+ if (!GetMembersNA( nDim, nHier, xMembersNA ))
+ return false;
+
+ Reference<container::XIndexAccess> xMembersIA( new ScNameToIndexAccess(xMembersNA) );
+ sal_Int32 nCount = xMembersIA->getCount();
+ vector<ScDPLabelData::Member> aMembers;
+ aMembers.reserve(nCount);
+
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
+ ScDPLabelData::Member aMem;
+
+ if (xMember.is())
+ aMem.maName = xMember->getName();
+
+ Reference<beans::XPropertySet> xMemProp(xMember, UNO_QUERY);
+ if (xMemProp.is())
+ {
+ aMem.mbVisible = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_ISVISIBL));
+ aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_SHOWDETA));
+
+ aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xMemProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+ }
+
+ aMembers.push_back(aMem);
+ }
+ rMembers.swap(aMembers);
+ return true;
+}
+
+void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ // Output area
+
+ SCCOL nCol1 = aOutRange.aStart.Col();
+ SCROW nRow1 = aOutRange.aStart.Row();
+ SCTAB nTab1 = aOutRange.aStart.Tab();
+ SCCOL nCol2 = aOutRange.aEnd.Col();
+ SCROW nRow2 = aOutRange.aEnd.Row();
+ SCTAB nTab2 = aOutRange.aEnd.Tab();
+
+ ScRefUpdateRes eRes =
+ ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if ( eRes != UR_NOTHING )
+ SetOutRange( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
+
+ // sheet source data
+
+ if ( pSheetDesc )
+ {
+ nCol1 = pSheetDesc->aSourceRange.aStart.Col();
+ nRow1 = pSheetDesc->aSourceRange.aStart.Row();
+ nTab1 = pSheetDesc->aSourceRange.aStart.Tab();
+ nCol2 = pSheetDesc->aSourceRange.aEnd.Col();
+ nRow2 = pSheetDesc->aSourceRange.aEnd.Row();
+ nTab2 = pSheetDesc->aSourceRange.aEnd.Tab();
+
+ eRes = ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if ( eRes != UR_NOTHING )
+ {
+ ScSheetSourceDesc aNewDesc;
+ aNewDesc.aSourceRange = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+
+ SCsCOL nDiffX = nCol1 - (SCsCOL) pSheetDesc->aSourceRange.aStart.Col();
+ SCsROW nDiffY = nRow1 - (SCsROW) pSheetDesc->aSourceRange.aStart.Row();
+
+ aNewDesc.aQueryParam = pSheetDesc->aQueryParam;
+ aNewDesc.aQueryParam.nCol1 = sal::static_int_cast<SCCOL>( aNewDesc.aQueryParam.nCol1 + nDiffX );
+ aNewDesc.aQueryParam.nCol2 = sal::static_int_cast<SCCOL>( aNewDesc.aQueryParam.nCol2 + nDiffX );
+ aNewDesc.aQueryParam.nRow1 += nDiffY; //! used?
+ aNewDesc.aQueryParam.nRow2 += nDiffY; //! used?
+ SCSIZE nEC = aNewDesc.aQueryParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ if (aNewDesc.aQueryParam.GetEntry(i).bDoQuery)
+ aNewDesc.aQueryParam.GetEntry(i).nField += nDiffX;
+
+ SetSheetDesc( aNewDesc ); // allocates new pSheetDesc
+ }
+ }
+}
+
+BOOL ScDPObject::RefsEqual( const ScDPObject& r ) const
+{
+ if ( aOutRange != r.aOutRange )
+ return FALSE;
+
+ if ( pSheetDesc && r.pSheetDesc )
+ {
+ if ( pSheetDesc->aSourceRange != r.pSheetDesc->aSourceRange )
+ return FALSE;
+ }
+ else if ( pSheetDesc || r.pSheetDesc )
+ {
+ DBG_ERROR("RefsEqual: SheetDesc set at only one object");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void ScDPObject::WriteRefsTo( ScDPObject& r ) const
+{
+ r.SetOutRange( aOutRange );
+ if ( pSheetDesc )
+ r.SetSheetDesc( *pSheetDesc );
+}
+
+void ScDPObject::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
+{
+ CreateOutput();
+ pOutput->GetPositionData(rPos, rPosData);
+}
+
+bool ScDPObject::GetDataFieldPositionData(
+ const ScAddress& rPos, Sequence<sheet::DataPilotFieldFilter>& rFilters)
+{
+ CreateOutput();
+
+ vector<sheet::DataPilotFieldFilter> aFilters;
+ if (!pOutput->GetDataResultPositionData(aFilters, rPos))
+ return false;
+
+ sal_Int32 n = static_cast<sal_Int32>(aFilters.size());
+ rFilters.realloc(n);
+ for (sal_Int32 i = 0; i < n; ++i)
+ rFilters[i] = aFilters[i];
+
+ return true;
+}
+
+void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any> >& rTableData)
+{
+ CreateOutput();
+
+ Reference<sheet::XDrillDownDataSupplier> xDrillDownData(xSource, UNO_QUERY);
+ if (!xDrillDownData.is())
+ return;
+
+ Sequence<sheet::DataPilotFieldFilter> filters;
+ if (!GetDataFieldPositionData(rPos, filters))
+ return;
+
+ rTableData = xDrillDownData->getDrillDownData(filters);
+}
+
+bool ScDPObject::IsDimNameInUse(const OUString& rName) const
+{
+ if (!xSource.is())
+ return false;
+
+ Reference<container::XNameAccess> xDims = xSource->getDimensions();
+ Sequence<OUString> aDimNames = xDims->getElementNames();
+ sal_Int32 n = aDimNames.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const OUString& rDimName = aDimNames[i];
+ if (rDimName.equalsIgnoreAsciiCase(rName))
+ return true;
+
+ Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
+ if (!xPropSet.is())
+ continue;
+
+ OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xPropSet, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+ if (aLayoutName.equalsIgnoreAsciiCase(rName))
+ return true;
+ }
+ return false;
+}
+
+String ScDPObject::GetDimName( long nDim, BOOL& rIsDataLayout, sal_Int32* pFlags )
+{
+ rIsDataLayout = FALSE;
+ String aRet;
+
+ if ( xSource.is() )
+ {
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
+ long nDimCount = xDims->getCount();
+ if ( nDim < nDimCount )
+ {
+ uno::Reference<uno::XInterface> xIntDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+ if ( xDimName.is() && xDimProp.is() )
+ {
+ BOOL bData = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ //! error checking -- is "IsDataLayoutDimension" property required??
+
+ rtl::OUString aName;
+ try
+ {
+ aName = xDimName->getName();
+ }
+ catch(uno::Exception&)
+ {
+ }
+ if ( bData )
+ rIsDataLayout = TRUE;
+ else
+ aRet = String( aName );
+
+ if (pFlags)
+ *pFlags = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(SC_UNO_FLAGS), 0 );
+ }
+ }
+ }
+
+ return aRet;
+}
+
+BOOL ScDPObject::IsDuplicated( long nDim )
+{
+ BOOL bDuplicated = FALSE;
+ if ( xSource.is() )
+ {
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
+ long nDimCount = xDims->getCount();
+ if ( nDim < nDimCount )
+ {
+ uno::Reference<uno::XInterface> xIntDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+ if ( xDimProp.is() )
+ {
+ try
+ {
+ uno::Any aOrigAny = xDimProp->getPropertyValue(
+ rtl::OUString::createFromAscii(DP_PROP_ORIGINAL) );
+ uno::Reference<uno::XInterface> xIntOrig;
+ if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() )
+ bDuplicated = TRUE;
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ return bDuplicated;
+}
+
+long ScDPObject::GetDimCount()
+{
+ long nRet = 0;
+ if ( xSource.is() )
+ {
+ try
+ {
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ if ( xDimsName.is() )
+ nRet = xDimsName->getElementNames().getLength();
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ return nRet;
+}
+
+void ScDPObject::FillPageList( TypedScStrCollection& rStrings, long nField )
+{
+ //! merge members access with ToggleDetails?
+
+ //! convert field index to dimension index?
+
+ DBG_ASSERT( xSource.is(), "no source" );
+ if ( !xSource.is() ) return;
+
+ uno::Reference<container::XNamed> xDim;
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ long nIntCount = xIntDims->getCount();
+ if ( nField < nIntCount )
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
+ xIntDims->getByIndex(nField) );
+ xDim = uno::Reference<container::XNamed>( xIntDim, uno::UNO_QUERY );
+ }
+ DBG_ASSERT( xDim.is(), "dimension not found" );
+ if ( !xDim.is() ) return;
+
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
+ long nLevel = 0;
+
+ long nHierCount = 0;
+ uno::Reference<container::XIndexAccess> xHiers;
+ uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
+ xHiers = new ScNameToIndexAccess( xHiersName );
+ nHierCount = xHiers->getCount();
+ }
+ uno::Reference<uno::XInterface> xHier;
+ if ( nHierarchy < nHierCount )
+ xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHierarchy) );
+ DBG_ASSERT( xHier.is(), "hierarchy not found" );
+ if ( !xHier.is() ) return;
+
+ long nLevCount = 0;
+ uno::Reference<container::XIndexAccess> xLevels;
+ uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
+ if ( xLevSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
+ xLevels = new ScNameToIndexAccess( xLevsName );
+ nLevCount = xLevels->getCount();
+ }
+ uno::Reference<uno::XInterface> xLevel;
+ if ( nLevel < nLevCount )
+ xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLevel) );
+ DBG_ASSERT( xLevel.is(), "level not found" );
+ if ( !xLevel.is() ) return;
+
+ uno::Reference<container::XNameAccess> xMembers;
+ uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
+ if ( xMbrSupp.is() )
+ xMembers = xMbrSupp->getMembers();
+ DBG_ASSERT( xMembers.is(), "members not found" );
+ if ( !xMembers.is() ) return;
+
+ uno::Sequence<rtl::OUString> aNames = xMembers->getElementNames();
+ long nNameCount = aNames.getLength();
+ const rtl::OUString* pNameArr = aNames.getConstArray();
+ for (long nPos = 0; nPos < nNameCount; ++nPos)
+ {
+ // Make sure to insert only visible members.
+ Reference<XPropertySet> xPropSet(xMembers->getByName(pNameArr[nPos]), UNO_QUERY);
+ sal_Bool bVisible = false;
+ if (xPropSet.is())
+ {
+ Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_ISVISIBL));
+ any >>= bVisible;
+ }
+
+ if (bVisible)
+ {
+ // use the order from getElementNames
+ TypedStrData* pData = new TypedStrData( pNameArr[nPos] );
+ if ( !rStrings.AtInsert( rStrings.GetCount(), pData ) )
+ delete pData;
+ }
+ }
+
+ // add "-all-" entry to the top (unsorted)
+ TypedStrData* pAllData = new TypedStrData( String( ScResId( SCSTR_ALL ) ) ); //! separate string? (also output)
+ if ( !rStrings.AtInsert( 0, pAllData ) )
+ delete pAllData;
+}
+
+void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHeaderData& rData)
+{
+ using namespace ::com::sun::star::sheet::DataPilotTablePositionType;
+
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ // Reset member values to invalid state.
+ rData.Dimension = rData.Hierarchy = rData.Level = -1;
+ rData.Flags = 0;
+
+ DataPilotTablePositionData aPosData;
+ pOutput->GetPositionData(rPos, aPosData);
+ const sal_Int32 nPosType = aPosData.PositionType;
+ if (nPosType == COLUMN_HEADER || nPosType == ROW_HEADER)
+ aPosData.PositionData >>= rData;
+}
+
+// Returns TRUE on success and stores the result in rTarget
+BOOL ScDPObject::GetPivotData( ScDPGetPivotDataField& rTarget,
+ const std::vector< ScDPGetPivotDataField >& rFilters )
+{
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ return pOutput->GetPivotData( rTarget, rFilters );
+}
+
+BOOL ScDPObject::IsFilterButton( const ScAddress& rPos )
+{
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ return pOutput->IsFilterButton( rPos );
+}
+
+long ScDPObject::GetHeaderDim( const ScAddress& rPos, USHORT& rOrient )
+{
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ return pOutput->GetHeaderDim( rPos, rOrient );
+}
+
+BOOL ScDPObject::GetHeaderDrag( const ScAddress& rPos, BOOL bMouseLeft, BOOL bMouseTop, long nDragDim,
+ Rectangle& rPosRect, USHORT& rOrient, long& rDimPos )
+{
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ return pOutput->GetHeaderDrag( rPos, bMouseLeft, bMouseTop, nDragDim, rPosRect, rOrient, rDimPos );
+}
+
+void ScDPObject::GetMemberResultNames( ScStrCollection& rNames, long nDimension )
+{
+ CreateOutput(); // create xSource and pOutput if not already done
+
+ pOutput->GetMemberResultNames( rNames, nDimension ); // used only with table data -> level not needed
+}
+
+bool lcl_Dequote( const String& rSource, xub_StrLen nStartPos, xub_StrLen& rEndPos, String& rResult )
+{
+ // nStartPos has to point to opening quote
+
+ bool bRet = false;
+ const sal_Unicode cQuote = '\'';
+
+ if ( rSource.GetChar(nStartPos) == cQuote )
+ {
+ rtl::OUStringBuffer aBuffer;
+ xub_StrLen nPos = nStartPos + 1;
+ const xub_StrLen nLen = rSource.Len();
+
+ while ( nPos < nLen )
+ {
+ const sal_Unicode cNext = rSource.GetChar(nPos);
+ if ( cNext == cQuote )
+ {
+ if ( nPos+1 < nLen && rSource.GetChar(nPos+1) == cQuote )
+ {
+ // double quote is used for an embedded quote
+ aBuffer.append( cNext ); // append one quote
+ ++nPos; // skip the next one
+ }
+ else
+ {
+ // end of quoted string
+ rResult = aBuffer.makeStringAndClear();
+ rEndPos = nPos + 1; // behind closing quote
+ return true;
+ }
+ }
+ else
+ aBuffer.append( cNext );
+
+ ++nPos;
+ }
+ // no closing quote before the end of the string -> error (bRet still false)
+ }
+
+ return bRet;
+}
+
+struct ScGetPivotDataFunctionEntry
+{
+ const sal_Char* pName;
+ sheet::GeneralFunction eFunc;
+};
+
+bool lcl_ParseFunction( const String& rList, xub_StrLen nStartPos, xub_StrLen& rEndPos, sheet::GeneralFunction& rFunc )
+{
+ static const ScGetPivotDataFunctionEntry aFunctions[] =
+ {
+ // our names
+ { "Sum", sheet::GeneralFunction_SUM },
+ { "Count", sheet::GeneralFunction_COUNT },
+ { "Average", sheet::GeneralFunction_AVERAGE },
+ { "Max", sheet::GeneralFunction_MAX },
+ { "Min", sheet::GeneralFunction_MIN },
+ { "Product", sheet::GeneralFunction_PRODUCT },
+ { "CountNums", sheet::GeneralFunction_COUNTNUMS },
+ { "StDev", sheet::GeneralFunction_STDEV },
+ { "StDevp", sheet::GeneralFunction_STDEVP },
+ { "Var", sheet::GeneralFunction_VAR },
+ { "VarP", sheet::GeneralFunction_VARP },
+ // compatibility names
+ { "Count Nums", sheet::GeneralFunction_COUNTNUMS },
+ { "StdDev", sheet::GeneralFunction_STDEV },
+ { "StdDevp", sheet::GeneralFunction_STDEVP }
+ };
+
+ const xub_StrLen nListLen = rList.Len();
+ while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' )
+ ++nStartPos;
+
+ bool bParsed = false;
+ bool bFound = false;
+ String aFuncStr;
+ xub_StrLen nFuncEnd = 0;
+ if ( nStartPos < nListLen && rList.GetChar(nStartPos) == '\'' )
+ bParsed = lcl_Dequote( rList, nStartPos, nFuncEnd, aFuncStr );
+ else
+ {
+ nFuncEnd = rList.Search( static_cast<sal_Unicode>(']'), nStartPos );
+ if ( nFuncEnd != STRING_NOTFOUND )
+ {
+ aFuncStr = rList.Copy( nStartPos, nFuncEnd - nStartPos );
+ bParsed = true;
+ }
+ }
+
+ if ( bParsed )
+ {
+ aFuncStr.EraseLeadingAndTrailingChars( ' ' );
+
+ const sal_Int32 nFuncCount = sizeof(aFunctions) / sizeof(aFunctions[0]);
+ for ( sal_Int32 nFunc=0; nFunc<nFuncCount && !bFound; nFunc++ )
+ {
+ if ( aFuncStr.EqualsIgnoreCaseAscii( aFunctions[nFunc].pName ) )
+ {
+ rFunc = aFunctions[nFunc].eFunc;
+ bFound = true;
+
+ while ( nFuncEnd < nListLen && rList.GetChar(nFuncEnd) == ' ' )
+ ++nFuncEnd;
+ rEndPos = nFuncEnd;
+ }
+ }
+ }
+
+ return bFound;
+}
+
+bool lcl_IsAtStart( const String& rList, const String& rSearch, sal_Int32& rMatched,
+ bool bAllowBracket, sheet::GeneralFunction* pFunc )
+{
+ sal_Int32 nMatchList = 0;
+ sal_Int32 nMatchSearch = 0;
+ sal_Unicode cFirst = rList.GetChar(0);
+ if ( cFirst == '\'' || cFirst == '[' )
+ {
+ // quoted string or string in brackets must match completely
+
+ String aDequoted;
+ xub_StrLen nQuoteEnd = 0;
+ bool bParsed = false;
+
+ if ( cFirst == '\'' )
+ bParsed = lcl_Dequote( rList, 0, nQuoteEnd, aDequoted );
+ else if ( cFirst == '[' )
+ {
+ // skip spaces after the opening bracket
+
+ xub_StrLen nStartPos = 1;
+ const xub_StrLen nListLen = rList.Len();
+ while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' )
+ ++nStartPos;
+
+ if ( rList.GetChar(nStartPos) == '\'' ) // quoted within the brackets?
+ {
+ if ( lcl_Dequote( rList, nStartPos, nQuoteEnd, aDequoted ) )
+ {
+ // after the quoted string, there must be the closing bracket, optionally preceded by spaces,
+ // and/or a function name
+ while ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ' ' )
+ ++nQuoteEnd;
+
+ // semicolon separates function name
+ if ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ';' && pFunc )
+ {
+ xub_StrLen nFuncEnd = 0;
+ if ( lcl_ParseFunction( rList, nQuoteEnd + 1, nFuncEnd, *pFunc ) )
+ nQuoteEnd = nFuncEnd;
+ }
+ if ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ']' )
+ {
+ ++nQuoteEnd; // include the closing bracket for the matched length
+ bParsed = true;
+ }
+ }
+ }
+ else
+ {
+ // implicit quoting to the closing bracket
+
+ xub_StrLen nClosePos = rList.Search( static_cast<sal_Unicode>(']'), nStartPos );
+ if ( nClosePos != STRING_NOTFOUND )
+ {
+ xub_StrLen nNameEnd = nClosePos;
+ xub_StrLen nSemiPos = rList.Search( static_cast<sal_Unicode>(';'), nStartPos );
+ if ( nSemiPos != STRING_NOTFOUND && nSemiPos < nClosePos && pFunc )
+ {
+ xub_StrLen nFuncEnd = 0;
+ if ( lcl_ParseFunction( rList, nSemiPos + 1, nFuncEnd, *pFunc ) )
+ nNameEnd = nSemiPos;
+ }
+
+ aDequoted = rList.Copy( nStartPos, nNameEnd - nStartPos );
+ aDequoted.EraseTrailingChars( ' ' ); // spaces before the closing bracket or semicolon
+ nQuoteEnd = nClosePos + 1;
+ bParsed = true;
+ }
+ }
+ }
+
+ if ( bParsed && ScGlobal::GetpTransliteration()->isEqual( aDequoted, rSearch ) )
+ {
+ nMatchList = nQuoteEnd; // match count in the list string, including quotes
+ nMatchSearch = rSearch.Len();
+ }
+ }
+ else
+ {
+ // otherwise look for search string at the start of rList
+ ScGlobal::GetpTransliteration()->equals( rList, 0, rList.Len(), nMatchList,
+ rSearch, 0, rSearch.Len(), nMatchSearch );
+ }
+
+ if ( nMatchSearch == rSearch.Len() )
+ {
+ // search string is at start of rList - look for following space or end of string
+
+ bool bValid = false;
+ if ( sal::static_int_cast<xub_StrLen>(nMatchList) >= rList.Len() )
+ bValid = true;
+ else
+ {
+ sal_Unicode cNext = rList.GetChar(sal::static_int_cast<xub_StrLen>(nMatchList));
+ if ( cNext == ' ' || ( bAllowBracket && cNext == '[' ) )
+ bValid = true;
+ }
+
+ if ( bValid )
+ {
+ rMatched = nMatchList;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+BOOL ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget,
+ std::vector< ScDPGetPivotDataField >& rFilters,
+ const String& rFilterList )
+{
+ // parse the string rFilterList into parameters for GetPivotData
+
+ CreateObjects(); // create xSource if not already done
+
+ std::vector<String> aDataNames; // data fields (source name)
+ std::vector<String> aGivenNames; // data fields (compound name)
+ std::vector<String> aFieldNames; // column/row/data fields
+ std::vector< uno::Sequence<rtl::OUString> > aFieldValues;
+
+ //
+ // get all the field and item names
+ //
+
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ sal_Int32 nDimCount = xIntDims->getCount();
+ for ( sal_Int32 nDim = 0; nDim<nDimCount; nDim++ )
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nDim) );
+ uno::Reference<container::XNamed> xDim( xIntDim, uno::UNO_QUERY );
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
+ BOOL bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ sal_Int32 nOrient = ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ if ( !bDataLayout )
+ {
+ if ( nOrient == sheet::DataPilotFieldOrientation_DATA )
+ {
+ String aSourceName;
+ String aGivenName;
+ ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xIntDim );
+ aDataNames.push_back( aSourceName );
+ aGivenNames.push_back( aGivenName );
+ }
+ else if ( nOrient != sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ // get level names, as in ScDPOutput
+
+ uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
+ sal_Int32 nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
+ if ( nHierarchy >= xHiers->getCount() )
+ nHierarchy = 0;
+
+ uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
+ xHiers->getByIndex(nHierarchy) );
+ uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
+ sal_Int32 nLevCount = xLevels->getCount();
+ for (sal_Int32 nLev=0; nLev<nLevCount; nLev++)
+ {
+ uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(
+ xLevels->getByIndex(nLev) );
+ uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
+ uno::Reference<sheet::XMembersSupplier> xLevSupp( xLevel, uno::UNO_QUERY );
+ if ( xLevNam.is() && xLevSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xMembers = xLevSupp->getMembers();
+
+ String aFieldName( xLevNam->getName() );
+ uno::Sequence<rtl::OUString> aMemberNames( xMembers->getElementNames() );
+
+ aFieldNames.push_back( aFieldName );
+ aFieldValues.push_back( aMemberNames );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // compare and build filters
+ //
+
+ SCSIZE nDataFields = aDataNames.size();
+ SCSIZE nFieldCount = aFieldNames.size();
+ DBG_ASSERT( aGivenNames.size() == nDataFields && aFieldValues.size() == nFieldCount, "wrong count" );
+
+ bool bError = false;
+ bool bHasData = false;
+ String aRemaining( rFilterList );
+ aRemaining.EraseLeadingAndTrailingChars( ' ' );
+ while ( aRemaining.Len() && !bError )
+ {
+ bool bUsed = false;
+
+ // look for data field name
+
+ for ( SCSIZE nDataPos=0; nDataPos<nDataFields && !bUsed; nDataPos++ )
+ {
+ String aFound;
+ sal_Int32 nMatched = 0;
+ if ( lcl_IsAtStart( aRemaining, aDataNames[nDataPos], nMatched, false, NULL ) )
+ aFound = aDataNames[nDataPos];
+ else if ( lcl_IsAtStart( aRemaining, aGivenNames[nDataPos], nMatched, false, NULL ) )
+ aFound = aGivenNames[nDataPos];
+
+ if ( aFound.Len() )
+ {
+ rTarget.maFieldName = aFound;
+ aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
+ bHasData = true;
+ bUsed = true;
+ }
+ }
+
+ // look for field name
+
+ String aSpecField;
+ bool bHasFieldName = false;
+ if ( !bUsed )
+ {
+ sal_Int32 nMatched = 0;
+ for ( SCSIZE nField=0; nField<nFieldCount && !bHasFieldName; nField++ )
+ {
+ if ( lcl_IsAtStart( aRemaining, aFieldNames[nField], nMatched, true, NULL ) )
+ {
+ aSpecField = aFieldNames[nField];
+ aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
+ aRemaining.EraseLeadingChars( ' ' );
+
+ // field name has to be followed by item name in brackets
+ if ( aRemaining.GetChar(0) == '[' )
+ {
+ bHasFieldName = true;
+ // bUsed remains false - still need the item
+ }
+ else
+ {
+ bUsed = true;
+ bError = true;
+ }
+ }
+ }
+ }
+
+ // look for field item
+
+ if ( !bUsed )
+ {
+ bool bItemFound = false;
+ sal_Int32 nMatched = 0;
+ String aFoundName;
+ String aFoundValue;
+ sheet::GeneralFunction eFunc = sheet::GeneralFunction_NONE;
+ sheet::GeneralFunction eFoundFunc = sheet::GeneralFunction_NONE;
+
+ for ( SCSIZE nField=0; nField<nFieldCount; nField++ )
+ {
+ // If a field name is given, look in that field only, otherwise in all fields.
+ // aSpecField is initialized from aFieldNames array, so exact comparison can be used.
+ if ( !bHasFieldName || aFieldNames[nField] == aSpecField )
+ {
+ const uno::Sequence<rtl::OUString>& rItems = aFieldValues[nField];
+ sal_Int32 nItemCount = rItems.getLength();
+ const rtl::OUString* pItemArr = rItems.getConstArray();
+ for ( sal_Int32 nItem=0; nItem<nItemCount; nItem++ )
+ {
+ if ( lcl_IsAtStart( aRemaining, pItemArr[nItem], nMatched, false, &eFunc ) )
+ {
+ if ( bItemFound )
+ bError = true; // duplicate (also across fields)
+ else
+ {
+ aFoundName = aFieldNames[nField];
+ aFoundValue = pItemArr[nItem];
+ eFoundFunc = eFunc;
+ bItemFound = true;
+ bUsed = true;
+ }
+ }
+ }
+ }
+ }
+
+ if ( bItemFound && !bError )
+ {
+ ScDPGetPivotDataField aField;
+ aField.maFieldName = aFoundName;
+ aField.meFunction = eFoundFunc;
+ aField.mbValIsStr = true;
+ aField.maValStr = aFoundValue;
+ aField.mnValNum = 0.0;
+ rFilters.push_back( aField );
+
+ aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
+ }
+ }
+
+ if ( !bUsed )
+ bError = true;
+
+ aRemaining.EraseLeadingChars( ' ' ); // remove any number of spaces between entries
+ }
+
+ if ( !bError && !bHasData && aDataNames.size() == 1 )
+ {
+ // if there's only one data field, its name need not be specified
+ rTarget.maFieldName = aDataNames[0];
+ bHasData = true;
+ }
+
+ return bHasData && !bError;
+}
+
+void ScDPObject::ToggleDetails(const DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj)
+{
+ CreateObjects(); // create xSource if not already done
+
+ // find dimension name
+
+ uno::Reference<container::XNamed> xDim;
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ long nIntCount = xIntDims->getCount();
+ if ( rElemDesc.Dimension < nIntCount )
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
+ xIntDims->getByIndex(rElemDesc.Dimension) );
+ xDim = uno::Reference<container::XNamed>( xIntDim, uno::UNO_QUERY );
+ }
+ DBG_ASSERT( xDim.is(), "dimension not found" );
+ if ( !xDim.is() ) return;
+ String aDimName = xDim->getName();
+
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ BOOL bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ if (bDataLayout)
+ {
+ // the elements of the data layout dimension can't be found by their names
+ // -> don't change anything
+ return;
+ }
+
+ // query old state
+
+ long nHierCount = 0;
+ uno::Reference<container::XIndexAccess> xHiers;
+ uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
+ xHiers = new ScNameToIndexAccess( xHiersName );
+ nHierCount = xHiers->getCount();
+ }
+ uno::Reference<uno::XInterface> xHier;
+ if ( rElemDesc.Hierarchy < nHierCount )
+ xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(rElemDesc.Hierarchy) );
+ DBG_ASSERT( xHier.is(), "hierarchy not found" );
+ if ( !xHier.is() ) return;
+
+ long nLevCount = 0;
+ uno::Reference<container::XIndexAccess> xLevels;
+ uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
+ if ( xLevSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
+ xLevels = new ScNameToIndexAccess( xLevsName );
+ nLevCount = xLevels->getCount();
+ }
+ uno::Reference<uno::XInterface> xLevel;
+ if ( rElemDesc.Level < nLevCount )
+ xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(rElemDesc.Level) );
+ DBG_ASSERT( xLevel.is(), "level not found" );
+ if ( !xLevel.is() ) return;
+
+ uno::Reference<container::XNameAccess> xMembers;
+ uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
+ if ( xMbrSupp.is() )
+ xMembers = xMbrSupp->getMembers();
+
+ BOOL bFound = FALSE;
+ BOOL bShowDetails = TRUE;
+
+ if ( xMembers.is() )
+ {
+ if ( xMembers->hasByName(rElemDesc.MemberName) )
+ {
+ uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
+ xMembers->getByName(rElemDesc.MemberName) );
+ uno::Reference<beans::XPropertySet> xMbrProp( xMemberInt, uno::UNO_QUERY );
+ if ( xMbrProp.is() )
+ {
+ bShowDetails = ScUnoHelpFunctions::GetBoolProperty( xMbrProp,
+ rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS) );
+ //! don't set bFound if property is unknown?
+ bFound = TRUE;
+ }
+ }
+ }
+
+ DBG_ASSERT( bFound, "member not found" );
+
+ //! use Hierarchy and Level in SaveData !!!!
+
+ // modify pDestObj if set, this object otherwise
+ ScDPSaveData* pModifyData = pDestObj ? ( pDestObj->pSaveData ) : pSaveData;
+ DBG_ASSERT( pModifyData, "no data?" );
+ if ( pModifyData )
+ {
+ const String aName = rElemDesc.MemberName;
+ pModifyData->GetDimensionByName(aDimName)->
+ GetMemberByName(aName)->SetShowDetails( !bShowDetails ); // toggle
+
+ if ( pDestObj )
+ pDestObj->InvalidateData(); // re-init source from SaveData
+ else
+ InvalidateData(); // re-init source from SaveData
+ }
+}
+
+long lcl_FindName( const rtl::OUString& rString, const uno::Reference<container::XNameAccess>& xCollection )
+{
+ if ( xCollection.is() )
+ {
+ uno::Sequence<rtl::OUString> aSeq = xCollection->getElementNames();
+ long nCount = aSeq.getLength();
+ const rtl::OUString* pArr = aSeq.getConstArray();
+ for (long nPos=0; nPos<nCount; nPos++)
+ if ( pArr[nPos] == rString )
+ return nPos;
+ }
+ return -1; // not found
+}
+
+USHORT lcl_FirstSubTotal( const uno::Reference<beans::XPropertySet>& xDimProp ) // PIVOT_FUNC mask
+{
+ uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
+ if ( xDimProp.is() && xDimSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
+ long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
+ if ( nHierarchy >= xHiers->getCount() )
+ nHierarchy = 0;
+
+ uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
+ xHiers->getByIndex(nHierarchy) );
+ uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
+ uno::Reference<uno::XInterface> xLevel =
+ ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( 0 ) );
+ uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
+ if ( xLevProp.is() )
+ {
+ uno::Any aSubAny;
+ try
+ {
+ aSubAny = xLevProp->getPropertyValue(
+ rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS) );
+ }
+ catch(uno::Exception&)
+ {
+ }
+ uno::Sequence<sheet::GeneralFunction> aSeq;
+ if ( aSubAny >>= aSeq )
+ {
+ USHORT nMask = 0;
+ const sheet::GeneralFunction* pArray = aSeq.getConstArray();
+ long nCount = aSeq.getLength();
+ for (long i=0; i<nCount; i++)
+ nMask |= ScDataPilotConversion::FunctionBit(pArray[i]);
+ return nMask;
+ }
+ }
+ }
+ }
+
+ DBG_ERROR("FirstSubTotal: NULL");
+ return 0;
+}
+
+USHORT lcl_CountBits( USHORT nBits )
+{
+ if (!nBits) return 0;
+
+ USHORT nCount = 0;
+ USHORT nMask = 1;
+ for (USHORT i=0; i<16; i++)
+ {
+ if ( nBits & nMask )
+ ++nCount;
+ nMask <<= 1;
+ }
+ return nCount;
+}
+
+SCSIZE lcl_FillOldFields( PivotField* pFields,
+ const uno::Reference<sheet::XDimensionsSupplier>& xSource,
+ USHORT nOrient, SCCOL nColAdd, BOOL bAddData )
+{
+ SCSIZE nOutCount = 0;
+ BOOL bDataFound = FALSE;
+
+ SCSIZE nCount = (nOrient == sheet::DataPilotFieldOrientation_PAGE) ? PIVOT_MAXPAGEFIELD : PIVOT_MAXFIELD;
+
+ //! merge multiple occurences (data field with different functions)
+ //! force data field in one dimension
+
+ std::vector< long > aPos( nCount, 0 );
+
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
+ long nDimCount = xDims->getCount();
+ for (long nDim=0; nDim < nDimCount && nOutCount < nCount; nDim++)
+ {
+ uno::Reference<uno::XInterface> xIntDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+ long nDimOrient = ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ if ( xDimProp.is() && nDimOrient == nOrient )
+ {
+ USHORT nMask = 0;
+ if ( nOrient == sheet::DataPilotFieldOrientation_DATA )
+ {
+ sheet::GeneralFunction eFunc = (sheet::GeneralFunction)ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_FUNCTION),
+ sheet::GeneralFunction_NONE );
+ if ( eFunc == sheet::GeneralFunction_AUTO )
+ {
+ //! test for numeric data
+ eFunc = sheet::GeneralFunction_SUM;
+ }
+ nMask = ScDataPilotConversion::FunctionBit(eFunc);
+ }
+ else
+ nMask = lcl_FirstSubTotal( xDimProp ); // from first hierarchy
+
+ BOOL bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ uno::Any aOrigAny;
+ try
+ {
+ aOrigAny = xDimProp->getPropertyValue(
+ rtl::OUString::createFromAscii(DP_PROP_ORIGINAL) );
+ }
+ catch(uno::Exception&)
+ {
+ }
+
+ long nDupSource = -1;
+ uno::Reference<uno::XInterface> xIntOrig = ScUnoHelpFunctions::AnyToInterface( aOrigAny );
+ if ( xIntOrig.is() )
+ {
+ uno::Reference<container::XNamed> xNameOrig( xIntOrig, uno::UNO_QUERY );
+ if ( xNameOrig.is() )
+ nDupSource = lcl_FindName( xNameOrig->getName(), xDimsName );
+ }
+
+ BOOL bDupUsed = FALSE;
+ if ( nDupSource >= 0 )
+ {
+ // add function bit to previous entry
+
+ SCsCOL nCompCol;
+ if ( bDataLayout )
+ nCompCol = PIVOT_DATA_FIELD;
+ else
+ nCompCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek source column from name
+
+ for (SCSIZE nOld=0; nOld<nOutCount && !bDupUsed; nOld++)
+ if ( pFields[nOld].nCol == nCompCol )
+ {
+ // add to previous column only if new bits aren't already set there
+ if ( ( pFields[nOld].nFuncMask & nMask ) == 0 )
+ {
+ pFields[nOld].nFuncMask |= nMask;
+ pFields[nOld].nFuncCount = lcl_CountBits( pFields[nOld].nFuncMask );
+ bDupUsed = TRUE;
+ }
+ }
+ }
+
+ if ( !bDupUsed ) // also for duplicated dim if original has different orientation
+ {
+ if ( bDataLayout )
+ {
+ pFields[nOutCount].nCol = PIVOT_DATA_FIELD;
+ bDataFound = TRUE;
+ }
+ else if ( nDupSource >= 0 ) // if source was not found (different orientation)
+ pFields[nOutCount].nCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek from name
+ else
+ pFields[nOutCount].nCol = static_cast<SCsCOL>(nDim)+nColAdd; //! seek source column from name
+
+ pFields[nOutCount].nFuncMask = nMask;
+ pFields[nOutCount].nFuncCount = lcl_CountBits( nMask );
+ aPos[nOutCount] = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_POSITION) );
+
+ try
+ {
+ if( nOrient == sheet::DataPilotFieldOrientation_DATA )
+ xDimProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_REFVALUE ) ) )
+ >>= pFields[nOutCount].maFieldRef;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ ++nOutCount;
+ }
+ }
+ }
+
+ // sort by getPosition() value
+
+ for (SCSIZE i=0; i+1<nOutCount; i++)
+ {
+ for (SCSIZE j=0; j+i+1<nOutCount; j++)
+ if ( aPos[j+1] < aPos[j] )
+ {
+ std::swap( aPos[j], aPos[j+1] );
+ std::swap( pFields[j], pFields[j+1] );
+ }
+ }
+
+ if ( bAddData && !bDataFound )
+ {
+ if ( nOutCount >= nCount ) // space for data field?
+ --nOutCount; //! error?
+ pFields[nOutCount].nCol = PIVOT_DATA_FIELD;
+ pFields[nOutCount].nFuncMask = 0;
+ pFields[nOutCount].nFuncCount = 0;
+ ++nOutCount;
+ }
+
+ return nOutCount;
+}
+
+BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const
+{
+ ((ScDPObject*)this)->CreateObjects(); // xSource is needed for field numbers
+
+ rParam.nCol = aOutRange.aStart.Col();
+ rParam.nRow = aOutRange.aStart.Row();
+ rParam.nTab = aOutRange.aStart.Tab();
+ // ppLabelArr / nLabels is not changed
+
+ SCCOL nColAdd = 0;
+ if ( bForFile )
+ {
+ // in old file format, columns are within document, not within source range
+
+ DBG_ASSERT( pSheetDesc, "FillOldParam: bForFile, !pSheetDesc" );
+ nColAdd = pSheetDesc->aSourceRange.aStart.Col();
+ }
+
+ BOOL bAddData = ( lcl_GetDataGetOrientation( xSource ) == sheet::DataPilotFieldOrientation_HIDDEN );
+ rParam.nPageCount = lcl_FillOldFields( rParam.aPageArr,
+ xSource, sheet::DataPilotFieldOrientation_PAGE, nColAdd, FALSE );
+ rParam.nColCount = lcl_FillOldFields( rParam.aColArr,
+ xSource, sheet::DataPilotFieldOrientation_COLUMN, nColAdd, bAddData );
+ rParam.nRowCount = lcl_FillOldFields( rParam.aRowArr,
+ xSource, sheet::DataPilotFieldOrientation_ROW, nColAdd, FALSE );
+ rParam.nDataCount = lcl_FillOldFields( rParam.aDataArr,
+ xSource, sheet::DataPilotFieldOrientation_DATA, nColAdd, FALSE );
+
+ uno::Reference<beans::XPropertySet> xProp( xSource, uno::UNO_QUERY );
+ if (xProp.is())
+ {
+ try
+ {
+ rParam.bMakeTotalCol = ScUnoHelpFunctions::GetBoolProperty( xProp,
+ rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND), TRUE );
+ rParam.bMakeTotalRow = ScUnoHelpFunctions::GetBoolProperty( xProp,
+ rtl::OUString::createFromAscii(DP_PROP_ROWGRAND), TRUE );
+
+ // following properties may be missing for external sources
+ rParam.bIgnoreEmptyRows = ScUnoHelpFunctions::GetBoolProperty( xProp,
+ rtl::OUString::createFromAscii(DP_PROP_IGNOREEMPTY) );
+ rParam.bDetectCategories = ScUnoHelpFunctions::GetBoolProperty( xProp,
+ rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY) );
+ }
+ catch(uno::Exception&)
+ {
+ // no error
+ }
+ }
+ return TRUE;
+}
+
+void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
+{
+ uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
+ if ( xDimProp.is() && xDimSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
+ long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
+ if ( nHierarchy >= xHiers->getCount() )
+ nHierarchy = 0;
+ rData.mnUsedHier = nHierarchy;
+
+ uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
+ xHiers->getByIndex(nHierarchy) );
+
+ uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
+ uno::Reference<uno::XInterface> xLevel =
+ ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( 0 ) );
+ uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
+ if ( xLevProp.is() )
+ {
+ rData.mbShowAll = ScUnoHelpFunctions::GetBoolProperty( xLevProp,
+ rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY) );
+
+ try
+ {
+ xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SORTING ) ) )
+ >>= rData.maSortInfo;
+ xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_LAYOUT ) ) )
+ >>= rData.maLayoutInfo;
+ xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AUTOSHOW ) ) )
+ >>= rData.maShowInfo;
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+}
+
+BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
+{
+ rParam.maLabelArray.clear();
+
+ ((ScDPObject*)this)->CreateObjects();
+
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
+ long nDimCount = xDims->getCount();
+ if ( nDimCount > MAX_LABELS )
+ nDimCount = MAX_LABELS;
+ if (!nDimCount)
+ return FALSE;
+
+ for (long nDim=0; nDim < nDimCount; nDim++)
+ {
+ String aFieldName;
+ uno::Reference<uno::XInterface> xIntDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+
+ if ( xDimName.is() && xDimProp.is() )
+ {
+ BOOL bDuplicated = FALSE;
+ BOOL bData = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ //! error checking -- is "IsDataLayoutDimension" property required??
+
+ try
+ {
+ aFieldName = String( xDimName->getName() );
+
+ uno::Any aOrigAny = xDimProp->getPropertyValue(
+ rtl::OUString::createFromAscii(DP_PROP_ORIGINAL) );
+ uno::Reference<uno::XInterface> xIntOrig;
+ if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() )
+ bDuplicated = TRUE;
+ }
+ catch(uno::Exception&)
+ {
+ }
+
+ OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xDimProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+
+ if ( aFieldName.Len() && !bData && !bDuplicated )
+ {
+ SCsCOL nCol = static_cast< SCsCOL >( nDim ); //! ???
+ bool bIsValue = true; //! check
+
+ ScDPLabelDataRef pNewLabel(new ScDPLabelData(aFieldName, nCol, bIsValue));
+ pNewLabel->maLayoutName = aLayoutName;
+ GetHierarchies(nDim, pNewLabel->maHiers);
+ GetMembers(nDim, GetUsedHierarchy(nDim), pNewLabel->maMembers);
+ lcl_FillLabelData(*pNewLabel, xDimProp);
+ pNewLabel->mnFlags = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(SC_UNO_FLAGS), 0 );
+ rParam.maLabelArray.push_back(pNewLabel);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL ScDPObject::GetHierarchiesNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xHiers )
+{
+ BOOL bRet = FALSE;
+ uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
+ uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
+ if( xIntDims.is() )
+ {
+ uno::Reference<sheet::XHierarchiesSupplier> xHierSup(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
+ if (xHierSup.is())
+ {
+ xHiers.set( xHierSup->getHierarchies() );
+ bRet = xHiers.is();
+ }
+ }
+ return bRet;
+}
+
+BOOL ScDPObject::GetHierarchies( sal_Int32 nDim, uno::Sequence< rtl::OUString >& rHiers )
+{
+ BOOL bRet = FALSE;
+ uno::Reference< container::XNameAccess > xHiersNA;
+ if( GetHierarchiesNA( nDim, xHiersNA ) )
+ {
+ rHiers = xHiersNA->getElementNames();
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+sal_Int32 ScDPObject::GetUsedHierarchy( sal_Int32 nDim )
+{
+ sal_Int32 nHier = 0;
+ uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
+ uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
+ uno::Reference<beans::XPropertySet> xDim(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
+ if (xDim.is())
+ nHier = ScUnoHelpFunctions::GetLongProperty( xDim, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_USEDHIER ) ) );
+ return nHier;
+}
+
+BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xMembers )
+{
+ return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
+}
+
+BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
+{
+ BOOL bRet = FALSE;
+ uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
+ uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
+ uno::Reference<beans::XPropertySet> xDim(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
+ if (xDim.is())
+ {
+ uno::Reference<sheet::XHierarchiesSupplier> xHierSup(xDim, uno::UNO_QUERY);
+ if (xHierSup.is())
+ {
+ uno::Reference<container::XIndexAccess> xHiers(new ScNameToIndexAccess(xHierSup->getHierarchies()));
+ uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHiers->getByIndex(nHier), uno::UNO_QUERY );
+ if ( xLevSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xLevels(new ScNameToIndexAccess( xLevSupp->getLevels()));
+ if (xLevels.is())
+ {
+ sal_Int32 nLevCount = xLevels->getCount();
+ if (nLevCount > 0)
+ {
+ uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevels->getByIndex(0), uno::UNO_QUERY );
+ if ( xMembSupp.is() )
+ {
+ xMembers.set(xMembSupp->getMembers());
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+// convert old pivot tables into new datapilot tables
+
+String lcl_GetDimName( const uno::Reference<sheet::XDimensionsSupplier>& xSource, long nDim )
+{
+ rtl::OUString aName;
+ if ( xSource.is() )
+ {
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
+ long nDimCount = xDims->getCount();
+ if ( nDim < nDimCount )
+ {
+ uno::Reference<uno::XInterface> xIntDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
+ if (xDimName.is())
+ {
+ try
+ {
+ aName = xDimName->getName();
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ return aName;
+}
+
+// static
+void ScDPObject::ConvertOrientation( ScDPSaveData& rSaveData,
+ PivotField* pFields, SCSIZE nCount, USHORT nOrient,
+ ScDocument* pDoc, SCROW nRow, SCTAB nTab,
+ const uno::Reference<sheet::XDimensionsSupplier>& xSource,
+ BOOL bOldDefaults,
+ PivotField* pRefColFields, SCSIZE nRefColCount,
+ PivotField* pRefRowFields, SCSIZE nRefRowCount,
+ PivotField* pRefPageFields, SCSIZE nRefPageCount )
+{
+ // pDoc or xSource must be set
+ DBG_ASSERT( pDoc || xSource.is(), "missing string source" );
+
+ String aDocStr;
+ ScDPSaveDimension* pDim;
+
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ SCCOL nCol = pFields[i].nCol;
+ USHORT nFuncs = pFields[i].nFuncMask;
+ const sheet::DataPilotFieldReference& rFieldRef = pFields[i].maFieldRef;
+
+ if ( nCol == PIVOT_DATA_FIELD )
+ pDim = rSaveData.GetDataLayoutDimension();
+ else
+ {
+ if ( pDoc )
+ pDoc->GetString( nCol, nRow, nTab, aDocStr );
+ else
+ aDocStr = lcl_GetDimName( xSource, nCol ); // cols must start at 0
+
+ if ( aDocStr.Len() )
+ pDim = rSaveData.GetDimensionByName(aDocStr);
+ else
+ pDim = NULL;
+ }
+
+ if ( pDim )
+ {
+ if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) // set summary function
+ {
+ // generate an individual entry for each function
+ BOOL bFirst = TRUE;
+
+ // if a dimension is used for column/row/page and data,
+ // use duplicated dimensions for all data occurrences
+ if (pRefColFields)
+ for (SCSIZE nRefCol=0; nRefCol<nRefColCount; nRefCol++)
+ if (pRefColFields[nRefCol].nCol == nCol)
+ bFirst = FALSE;
+ if (pRefRowFields)
+ for (SCSIZE nRefRow=0; nRefRow<nRefRowCount; nRefRow++)
+ if (pRefRowFields[nRefRow].nCol == nCol)
+ bFirst = FALSE;
+ if (pRefPageFields)
+ for (USHORT nRefPage=0; nRefPage<nRefPageCount; ++nRefPage)
+ if (pRefPageFields[nRefPage].nCol == nCol)
+ bFirst = FALSE;
+
+ // if set via api, a data column may occur several times
+ // (if the function hasn't been changed yet) -> also look for duplicate data column
+ for (SCSIZE nPrevData=0; nPrevData<i; nPrevData++)
+ if (pFields[nPrevData].nCol == nCol)
+ bFirst = FALSE;
+
+ USHORT nMask = 1;
+ for (USHORT nBit=0; nBit<16; nBit++)
+ {
+ if ( nFuncs & nMask )
+ {
+ sheet::GeneralFunction eFunc = ScDataPilotConversion::FirstFunc( nMask );
+ ScDPSaveDimension* pCurrDim = bFirst ? pDim : rSaveData.DuplicateDimension(pDim->GetName());
+ pCurrDim->SetOrientation( nOrient );
+ pCurrDim->SetFunction( sal::static_int_cast<USHORT>(eFunc) );
+
+ if( rFieldRef.ReferenceType == sheet::DataPilotFieldReferenceType::NONE )
+ pCurrDim->SetReferenceValue( 0 );
+ else
+ pCurrDim->SetReferenceValue( &rFieldRef );
+
+ bFirst = FALSE;
+ }
+ nMask *= 2;
+ }
+ }
+ else // set SubTotals
+ {
+ pDim->SetOrientation( nOrient );
+
+ USHORT nFuncArray[16];
+ USHORT nFuncCount = 0;
+ USHORT nMask = 1;
+ for (USHORT nBit=0; nBit<16; nBit++)
+ {
+ if ( nFuncs & nMask )
+ nFuncArray[nFuncCount++] = sal::static_int_cast<USHORT>(ScDataPilotConversion::FirstFunc( nMask ));
+ nMask *= 2;
+ }
+ pDim->SetSubTotals( nFuncCount, nFuncArray );
+
+ // ShowEmpty was implicit in old tables,
+ // must be set for data layout dimension (not accessible in dialog)
+ if ( bOldDefaults || nCol == PIVOT_DATA_FIELD )
+ pDim->SetShowEmpty( TRUE );
+ }
+ }
+ }
+}
+
+// static
+bool ScDPObject::IsOrientationAllowed( USHORT nOrient, sal_Int32 nDimFlags )
+{
+ bool bAllowed = true;
+ switch (nOrient)
+ {
+ case sheet::DataPilotFieldOrientation_PAGE:
+ bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_PAGE_ORIENTATION ) == 0;
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_COLUMN_ORIENTATION ) == 0;
+ break;
+ case sheet::DataPilotFieldOrientation_ROW:
+ bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_ROW_ORIENTATION ) == 0;
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_DATA_ORIENTATION ) == 0;
+ break;
+ default:
+ {
+ // allowed to remove from previous orientation
+ }
+ }
+ return bAllowed;
+}
+
+// -----------------------------------------------------------------------
+
+// static
+BOOL ScDPObject::HasRegisteredSources()
+{
+ BOOL bFound = FALSE;
+
+ uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
+ uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
+ if ( xEnAc.is() )
+ {
+ uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
+ rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE ) );
+ if ( xEnum.is() && xEnum->hasMoreElements() )
+ bFound = TRUE;
+ }
+
+ return bFound;
+}
+
+// static
+uno::Sequence<rtl::OUString> ScDPObject::GetRegisteredSources()
+{
+ long nCount = 0;
+ uno::Sequence<rtl::OUString> aSeq(0);
+
+ // use implementation names...
+
+ uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
+ uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
+ if ( xEnAc.is() )
+ {
+ uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
+ rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE ) );
+ if ( xEnum.is() )
+ {
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Any aAddInAny = xEnum->nextElement();
+// if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
+ {
+ uno::Reference<uno::XInterface> xIntFac;
+ aAddInAny >>= xIntFac;
+ if ( xIntFac.is() )
+ {
+ uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
+ if ( xInfo.is() )
+ {
+ rtl::OUString sName = xInfo->getImplementationName();
+
+ aSeq.realloc( nCount+1 );
+ aSeq.getArray()[nCount] = sName;
+ ++nCount;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return aSeq;
+}
+
+// use getContext from addincol.cxx
+uno::Reference<uno::XComponentContext> getContext(uno::Reference<lang::XMultiServiceFactory> xMSF);
+
+// static
+uno::Reference<sheet::XDimensionsSupplier> ScDPObject::CreateSource( const ScDPServiceDesc& rDesc )
+{
+ rtl::OUString aImplName = rDesc.aServiceName;
+ uno::Reference<sheet::XDimensionsSupplier> xRet = NULL;
+
+ uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
+ uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
+ if ( xEnAc.is() )
+ {
+ uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
+ rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE ) );
+ if ( xEnum.is() )
+ {
+ while ( xEnum->hasMoreElements() && !xRet.is() )
+ {
+ uno::Any aAddInAny = xEnum->nextElement();
+// if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
+ {
+ uno::Reference<uno::XInterface> xIntFac;
+ aAddInAny >>= xIntFac;
+ if ( xIntFac.is() )
+ {
+ uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
+ if ( xInfo.is() && xInfo->getImplementationName() == aImplName )
+ {
+ try
+ {
+ // #i113160# try XSingleComponentFactory in addition to (old) XSingleServiceFactory,
+ // passing the context to the component (see ScUnoAddInCollection::Initialize)
+
+ uno::Reference<uno::XInterface> xInterface;
+ uno::Reference<uno::XComponentContext> xCtx = getContext(xManager);
+ uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
+ if (xCtx.is() && xCFac.is())
+ xInterface = xCFac->createInstanceWithContext(xCtx);
+
+ if (!xInterface.is())
+ {
+ uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
+ if ( xFac.is() )
+ xInterface = xFac->createInstance();
+ }
+
+ uno::Reference<lang::XInitialization> xInit( xInterface, uno::UNO_QUERY );
+ if (xInit.is())
+ {
+ // initialize
+ uno::Sequence<uno::Any> aSeq(4);
+ uno::Any* pArray = aSeq.getArray();
+ pArray[0] <<= rtl::OUString( rDesc.aParSource );
+ pArray[1] <<= rtl::OUString( rDesc.aParName );
+ pArray[2] <<= rtl::OUString( rDesc.aParUser );
+ pArray[3] <<= rtl::OUString( rDesc.aParPass );
+ xInit->initialize( aSeq );
+ }
+ xRet = uno::Reference<sheet::XDimensionsSupplier>( xInterface, uno::UNO_QUERY );
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return xRet;
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPCollection::ScDPCollection(ScDocument* pDocument) :
+ pDoc( pDocument )
+{
+}
+
+ScDPCollection::ScDPCollection(const ScDPCollection& r) :
+ ScCollection(r),
+ pDoc(r.pDoc)
+{
+}
+
+ScDPCollection::~ScDPCollection()
+{
+}
+
+ScDataObject* ScDPCollection::Clone() const
+{
+ return new ScDPCollection(*this);
+}
+
+void ScDPCollection::DeleteOnTab( SCTAB nTab )
+{
+ USHORT nPos = 0;
+ while ( nPos < nCount )
+ {
+ // look for output positions on the deleted sheet
+ if ( static_cast<const ScDPObject*>(At(nPos))->GetOutRange().aStart.Tab() == nTab )
+ AtFree(nPos);
+ else
+ ++nPos;
+ }
+}
+
+void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ for (USHORT i=0; i<nCount; i++)
+ ((ScDPObject*)At(i))->UpdateReference( eUpdateRefMode, r, nDx, nDy, nDz );
+}
+
+BOOL ScDPCollection::RefsEqual( const ScDPCollection& r ) const
+{
+ if ( nCount != r.nCount )
+ return FALSE;
+
+ for (USHORT i=0; i<nCount; i++)
+ if ( ! ((const ScDPObject*)At(i))->RefsEqual( *((const ScDPObject*)r.At(i)) ) )
+ return FALSE;
+
+ return TRUE; // all equal
+}
+
+void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
+{
+ if ( nCount == r.nCount )
+ {
+ //! assert equal names?
+ for (USHORT i=0; i<nCount; i++)
+ ((const ScDPObject*)At(i))->WriteRefsTo( *((ScDPObject*)r.At(i)) );
+ }
+ else
+ {
+ // #i8180# If data pilot tables were deleted with their sheet,
+ // this collection contains extra entries that must be restored.
+ // Matching objects are found by their names.
+
+ DBG_ASSERT( nCount >= r.nCount, "WriteRefsTo: missing entries in document" );
+ for (USHORT nSourcePos=0; nSourcePos<nCount; nSourcePos++)
+ {
+ const ScDPObject* pSourceObj = static_cast<const ScDPObject*>(At(nSourcePos));
+ String aName = pSourceObj->GetName();
+ bool bFound = false;
+ for (USHORT nDestPos=0; nDestPos<r.nCount && !bFound; nDestPos++)
+ {
+ ScDPObject* pDestObj = static_cast<ScDPObject*>(r.At(nDestPos));
+ if ( pDestObj->GetName() == aName )
+ {
+ pSourceObj->WriteRefsTo( *pDestObj ); // found object, copy refs
+ bFound = true;
+ }
+ }
+ if ( !bFound )
+ {
+ // none found, re-insert deleted object (see ScUndoDataPilot::Undo)
+
+ ScDPObject* pDestObj = new ScDPObject( *pSourceObj );
+ pDestObj->SetAlive(TRUE);
+ if ( !r.InsertNewTable(pDestObj) )
+ {
+ DBG_ERROR("cannot insert DPObject");
+ DELETEZ( pDestObj );
+ }
+ }
+ }
+ DBG_ASSERT( nCount == r.nCount, "WriteRefsTo: couldn't restore all entries" );
+ }
+}
+
+ScDPObject* ScDPCollection::GetByName(const String& rName) const
+{
+ for (USHORT i=0; i<nCount; i++)
+ if (static_cast<const ScDPObject*>(pItems[i])->GetName() == rName)
+ return static_cast<ScDPObject*>(pItems[i]);
+ return NULL;
+}
+
+String ScDPCollection::CreateNewName( USHORT nMin ) const
+{
+ String aBase = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DataPilot"));
+ //! from Resource?
+
+ for (USHORT nAdd=0; nAdd<=nCount; nAdd++) // nCount+1 tries
+ {
+ String aNewName = aBase;
+ aNewName += String::CreateFromInt32( nMin + nAdd );
+ BOOL bFound = FALSE;
+ for (USHORT i=0; i<nCount && !bFound; i++)
+ if (((const ScDPObject*)pItems[i])->GetName() == aNewName)
+ bFound = TRUE;
+ if (!bFound)
+ return aNewName; // found unused Name
+ }
+ return String(); // should not happen
+}
+
+
+
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+long ScDPObject::GetCacheId() const
+{
+ if ( GetSaveData() )
+ return GetSaveData()->GetCacheId();
+ else
+ return mnCacheId;
+}
+ULONG ScDPObject::RefreshCache()
+{
+ if ( pServDesc )
+ {
+ // cache table isn't used for external service - do nothing, no error
+ return 0;
+ }
+
+ CreateObjects();
+ ULONG nErrId = 0;
+ if ( pSheetDesc)
+ nErrId = pSheetDesc->CheckValidate( pDoc );
+ if ( nErrId == 0 )
+ {
+ long nOldId = GetCacheId();
+ long nNewId = pDoc->GetNewDPObjectCacheId();
+ if ( nOldId >= 0 )
+ pDoc->RemoveDPObjectCache( nOldId );
+
+ ScDPTableDataCache* pCache = NULL;
+ if ( pSheetDesc )
+ pCache = pSheetDesc->CreateCache( pDoc, nNewId );
+ else if ( pImpDesc )
+ pCache = pImpDesc->CreateCache( pDoc, nNewId );
+
+ if ( pCache == NULL )
+ {
+ //cache failed
+ DBG_ASSERT( pCache , " pCache == NULL" );
+ return STR_ERR_DATAPILOTSOURCE;
+ }
+
+ nNewId = pCache->GetId();
+
+ bRefresh = TRUE;
+ ScDPCollection* pDPCollection = pDoc->GetDPCollection();
+ USHORT nCount = pDPCollection->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ { //set new cache id
+ if ( (*pDPCollection)[i]->GetCacheId() == nOldId )
+ {
+ (*pDPCollection)[i]->SetCacheId( nNewId );
+ (*pDPCollection)[i]->SetRefresh();
+
+ }
+ }
+ DBG_ASSERT( GetCacheId() >= 0, " GetCacheId() >= 0 " );
+ }
+ return nErrId;
+}
+void ScDPObject::SetCacheId( long nCacheId )
+{
+ if ( GetCacheId() != nCacheId )
+ {
+ InvalidateSource();
+ if ( GetSaveData() )
+ GetSaveData()->SetCacheId( nCacheId );
+
+ mnCacheId = nCacheId;
+ }
+}
+const ScDPTableDataCache* ScDPObject::GetCache() const
+{
+ return pDoc->GetDPObjectCache( GetCacheId() );
+}
+// End Comments
+
+void ScDPCollection::FreeTable(ScDPObject* pDPObj)
+{
+ const ScRange& rOutRange = pDPObj->GetOutRange();
+ const ScAddress& s = rOutRange.aStart;
+ const ScAddress& e = rOutRange.aEnd;
+ pDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ Free(pDPObj);
+}
+
+bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
+{
+ bool bSuccess = Insert(pDPObj);
+ if (bSuccess)
+ {
+ const ScRange& rOutRange = pDPObj->GetOutRange();
+ const ScAddress& s = rOutRange.aStart;
+ const ScAddress& e = rOutRange.aEnd;
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ }
+ return bSuccess;
+}
+
+bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const
+{
+ const ScMergeFlagAttr* pMergeAttr = static_cast<const ScMergeFlagAttr*>(
+ pDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG));
+
+ if (!pMergeAttr)
+ return false;
+
+ return pMergeAttr->HasDPTable();
+}
+
+
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
new file mode 100755
index 000000000000..bdd6fd555b89
--- /dev/null
+++ b/sc/source/core/data/dpoutput.cxx
@@ -0,0 +1,2060 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "dpoutput.hxx"
+#include "dptabsrc.hxx"
+#include "dpcachetable.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "markdata.hxx"
+#include "attrib.hxx"
+#include "formula/errorcodes.hxx" // errNoValue
+#include "miscuno.hxx"
+#include "globstr.hrc"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "collect.hxx"
+#include "scresid.hxx"
+#include "unonames.hxx"
+#include "sc.hrc"
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+#include "scdpoutputimpl.hxx"
+#include "dpglobal.hxx"
+// End Comments
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <vector>
+
+using namespace com::sun::star;
+using ::std::vector;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::sheet::DataPilotTablePositionData;
+using ::com::sun::star::sheet::DataPilotTableResultData;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+
+// -----------------------------------------------------------------------
+
+//! move to a header file
+//! use names from unonames.hxx?
+#define DP_PROP_FUNCTION "Function"
+#define DP_PROP_ORIENTATION "Orientation"
+#define DP_PROP_POSITION "Position"
+#define DP_PROP_USEDHIERARCHY "UsedHierarchy"
+#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
+#define DP_PROP_NUMBERFORMAT "NumberFormat"
+#define DP_PROP_FILTER "Filter"
+#define DP_PROP_COLUMNGRAND "ColumnGrand"
+#define DP_PROP_ROWGRAND "RowGrand"
+#define DP_PROP_SUBTOTALS "SubTotals"
+
+// -----------------------------------------------------------------------
+
+//! dynamic!!!
+#define SC_DPOUT_MAXLEVELS 256
+
+
+struct ScDPOutLevelData
+{
+ long nDim;
+ long nHier;
+ long nLevel;
+ long nDimPos;
+ uno::Sequence<sheet::MemberResult> aResult;
+ String maName; /// Name is the internal field name.
+ String aCaption; /// Caption is the name visible in the output table.
+ bool mbHasHiddenMember;
+
+ ScDPOutLevelData()
+ {
+ nDim = nHier = nLevel = nDimPos = -1;
+ mbHasHiddenMember = false;
+ }
+
+ BOOL operator<(const ScDPOutLevelData& r) const
+ { return nDimPos<r.nDimPos || ( nDimPos==r.nDimPos && nHier<r.nHier ) ||
+ ( nDimPos==r.nDimPos && nHier==r.nHier && nLevel<r.nLevel ); }
+
+ void Swap(ScDPOutLevelData& r)
+//! { ScDPOutLevelData aTemp = r; r = *this; *this = aTemp; }
+ { ScDPOutLevelData aTemp; aTemp = r; r = *this; *this = aTemp; }
+
+ //! bug (73840) in uno::Sequence - copy and then assign doesn't work!
+};
+
+// -----------------------------------------------------------------------
+
+void lcl_SetStyleById( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nStrId )
+{
+ if ( nCol1 > nCol2 || nRow1 > nRow2 )
+ {
+ DBG_ERROR("SetStyleById: invalid range");
+ return;
+ }
+
+ String aStyleName = ScGlobal::GetRscString( nStrId );
+ ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
+ ScStyleSheet* pStyle = (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
+ if (!pStyle)
+ {
+ // create new style (was in ScPivot::SetStyle)
+
+ pStyle = (ScStyleSheet*) &pStlPool->Make( aStyleName, SFX_STYLE_FAMILY_PARA,
+ SFXSTYLEBIT_USERDEF );
+ pStyle->SetParent( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
+ SfxItemSet& rSet = pStyle->GetItemSet();
+ if ( nStrId==STR_PIVOT_STYLE_RESULT || nStrId==STR_PIVOT_STYLE_TITLE )
+ rSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ if ( nStrId==STR_PIVOT_STYLE_CATEGORY || nStrId==STR_PIVOT_STYLE_TITLE )
+ rSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
+ }
+
+ pDoc->ApplyStyleAreaTab( nCol1, nRow1, nCol2, nRow2, nTab, *pStyle );
+}
+
+void lcl_SetFrame( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nWidth )
+{
+ SvxBorderLine aLine;
+ aLine.SetOutWidth(nWidth);
+ SvxBoxItem aBox( ATTR_BORDER );
+ aBox.SetLine(&aLine, BOX_LINE_LEFT);
+ aBox.SetLine(&aLine, BOX_LINE_TOP);
+ aBox.SetLine(&aLine, BOX_LINE_RIGHT);
+ aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
+ SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER );
+ aBoxInfo.SetValid(VALID_HORI,FALSE);
+ aBoxInfo.SetValid(VALID_VERT,FALSE);
+ aBoxInfo.SetValid(VALID_DISTANCE,FALSE);
+
+ pDoc->ApplyFrameAreaTab( ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ), &aBox, &aBoxInfo );
+}
+
+// -----------------------------------------------------------------------
+
+void lcl_FillNumberFormats( UINT32*& rFormats, long& rCount,
+ const uno::Reference<sheet::XDataPilotMemberResults>& xLevRes,
+ const uno::Reference<container::XIndexAccess>& xDims )
+{
+ if ( rFormats )
+ return; // already set
+
+ // xLevRes is from the data layout dimension
+ //! use result sequence from ScDPOutLevelData!
+
+ uno::Sequence<sheet::MemberResult> aResult = xLevRes->getResults();
+
+ long nSize = aResult.getLength();
+ if (nSize)
+ {
+ // get names/formats for all data dimensions
+ //! merge this with the loop to collect ScDPOutLevelData?
+
+ String aDataNames[SC_DPOUT_MAXLEVELS];
+ UINT32 nDataFormats[SC_DPOUT_MAXLEVELS];
+ long nDataCount = 0;
+ BOOL bAnySet = FALSE;
+
+ long nDimCount = xDims->getCount();
+ for (long nDim=0; nDim<nDimCount; nDim++)
+ {
+ uno::Reference<uno::XInterface> xDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
+ if ( xDimProp.is() && xDimName.is() )
+ {
+ sheet::DataPilotFieldOrientation eDimOrient =
+ (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
+ {
+ aDataNames[nDataCount] = String( xDimName->getName() );
+ long nFormat = ScUnoHelpFunctions::GetLongProperty(
+ xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_NUMBERFORMAT) );
+ nDataFormats[nDataCount] = nFormat;
+ if ( nFormat != 0 )
+ bAnySet = TRUE;
+ ++nDataCount;
+ }
+ }
+ }
+
+ if ( bAnySet ) // forget everything if all formats are 0 (or no data dimensions)
+ {
+ const sheet::MemberResult* pArray = aResult.getConstArray();
+
+ String aName;
+ UINT32* pNumFmt = new UINT32[nSize];
+ if (nDataCount == 1)
+ {
+ // only one data dimension -> use its numberformat everywhere
+ long nFormat = nDataFormats[0];
+ for (long nPos=0; nPos<nSize; nPos++)
+ pNumFmt[nPos] = nFormat;
+ }
+ else
+ {
+ for (long nPos=0; nPos<nSize; nPos++)
+ {
+ // if CONTINUE bit is set, keep previous name
+ //! keep number format instead!
+ if ( !(pArray[nPos].Flags & sheet::MemberResultFlags::CONTINUE) )
+ aName = String( pArray[nPos].Name );
+
+ UINT32 nFormat = 0;
+ for (long i=0; i<nDataCount; i++)
+ if (aName == aDataNames[i]) //! search more efficiently?
+ {
+ nFormat = nDataFormats[i];
+ break;
+ }
+ pNumFmt[nPos] = nFormat;
+ }
+ }
+
+ rFormats = pNumFmt;
+ rCount = nSize;
+ }
+ }
+}
+
+UINT32 lcl_GetFirstNumberFormat( const uno::Reference<container::XIndexAccess>& xDims )
+{
+ long nDimCount = xDims->getCount();
+ for (long nDim=0; nDim<nDimCount; nDim++)
+ {
+ uno::Reference<uno::XInterface> xDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ if ( xDimProp.is() )
+ {
+ sheet::DataPilotFieldOrientation eDimOrient =
+ (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
+ {
+ long nFormat = ScUnoHelpFunctions::GetLongProperty(
+ xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_NUMBERFORMAT) );
+
+ return nFormat; // use format from first found data dimension
+ }
+ }
+ }
+
+ return 0; // none found
+}
+
+void lcl_SortFields( ScDPOutLevelData* pFields, long nFieldCount )
+{
+ for (long i=0; i+1<nFieldCount; i++)
+ {
+ for (long j=0; j+i+1<nFieldCount; j++)
+ if ( pFields[j+1] < pFields[j] )
+ pFields[j].Swap( pFields[j+1] );
+ }
+}
+
+BOOL lcl_MemberEmpty( const uno::Sequence<sheet::MemberResult>& rSeq )
+{
+ // used to skip levels that have no members
+
+ long nLen = rSeq.getLength();
+ const sheet::MemberResult* pArray = rSeq.getConstArray();
+ for (long i=0; i<nLen; i++)
+ if (pArray[i].Flags & sheet::MemberResultFlags::HASMEMBER)
+ return FALSE;
+
+ return TRUE; // no member data -> empty
+}
+
+uno::Sequence<sheet::MemberResult> lcl_GetSelectedPageAsResult( const uno::Reference<beans::XPropertySet>& xDimProp )
+{
+ uno::Sequence<sheet::MemberResult> aRet;
+ if ( xDimProp.is() )
+ {
+ try
+ {
+ //! merge with ScDPDimension::setPropertyValue?
+
+ uno::Any aValue = xDimProp->getPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER) );
+
+ uno::Sequence<sheet::TableFilterField> aSeq;
+ if (aValue >>= aSeq)
+ {
+ if ( aSeq.getLength() == 1 )
+ {
+ const sheet::TableFilterField& rField = aSeq[0];
+ if ( rField.Field == 0 && rField.Operator == sheet::FilterOperator_EQUAL && !rField.IsNumeric )
+ {
+ rtl::OUString aSelectedPage( rField.StringValue );
+ //! different name/caption string?
+ sheet::MemberResult aResult( aSelectedPage, aSelectedPage, 0 );
+ aRet = uno::Sequence<sheet::MemberResult>( &aResult, 1 );
+ }
+ }
+ // else return empty sequence
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // recent addition - allow source to not handle it (no error)
+ }
+ }
+ return aRet;
+}
+
+ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsSupplier>& xSrc,
+ const ScAddress& rPos, BOOL bFilter ) :
+ pDoc( pD ),
+ xSource( xSrc ),
+ aStartPos( rPos ),
+ bDoFilter( bFilter ),
+ bResultsError( FALSE ),
+ mbHasDataLayout(false),
+ pColNumFmt( NULL ),
+ pRowNumFmt( NULL ),
+ nColFmtCount( 0 ),
+ nRowFmtCount( 0 ),
+ nSingleNumFmt( 0 ),
+ bSizesValid( FALSE ),
+ bSizeOverflow( FALSE ),
+ mbHeaderLayout( false )
+{
+ nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
+ nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
+
+ pColFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
+ pRowFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
+ pPageFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
+ nColFieldCount = 0;
+ nRowFieldCount = 0;
+ nPageFieldCount = 0;
+
+ uno::Reference<sheet::XDataPilotResults> xResult( xSource, uno::UNO_QUERY );
+ if ( xSource.is() && xResult.is() )
+ {
+ // get dimension results:
+
+ uno::Reference<container::XIndexAccess> xDims =
+ new ScNameToIndexAccess( xSource->getDimensions() );
+ long nDimCount = xDims->getCount();
+ for (long nDim=0; nDim<nDimCount; nDim++)
+ {
+ uno::Reference<uno::XInterface> xDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
+ if ( xDimProp.is() && xDimSupp.is() )
+ {
+ sheet::DataPilotFieldOrientation eDimOrient =
+ (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ long nDimPos = ScUnoHelpFunctions::GetLongProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_POSITION) );
+ BOOL bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(
+ xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ bool bHasHiddenMember = ScUnoHelpFunctions::GetBoolProperty(
+ xDimProp, OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER));
+
+ if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ uno::Reference<container::XIndexAccess> xHiers =
+ new ScNameToIndexAccess( xDimSupp->getHierarchies() );
+ long nHierarchy = ScUnoHelpFunctions::GetLongProperty(
+ xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
+ if ( nHierarchy >= xHiers->getCount() )
+ nHierarchy = 0;
+
+ uno::Reference<uno::XInterface> xHier =
+ ScUnoHelpFunctions::AnyToInterface(
+ xHiers->getByIndex(nHierarchy) );
+ uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XIndexAccess> xLevels =
+ new ScNameToIndexAccess( xHierSupp->getLevels() );
+ long nLevCount = xLevels->getCount();
+ for (long nLev=0; nLev<nLevCount; nLev++)
+ {
+ uno::Reference<uno::XInterface> xLevel =
+ ScUnoHelpFunctions::AnyToInterface(
+ xLevels->getByIndex(nLev) );
+ uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
+ uno::Reference<sheet::XDataPilotMemberResults> xLevRes(
+ xLevel, uno::UNO_QUERY );
+ if ( xLevNam.is() && xLevRes.is() )
+ {
+ String aName = xLevNam->getName();
+ Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
+ // Caption equals the field name by default.
+ // #i108948# use ScUnoHelpFunctions::GetStringProperty, because
+ // LayoutName is new and may not be present in external implementation
+ OUString aCaption = ScUnoHelpFunctions::GetStringProperty( xPropSet,
+ OUString::createFromAscii(SC_UNO_LAYOUTNAME), aName );
+
+ bool bRowFieldHasMember = false;
+ switch ( eDimOrient )
+ {
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ pColFields[nColFieldCount].nDim = nDim;
+ pColFields[nColFieldCount].nHier = nHierarchy;
+ pColFields[nColFieldCount].nLevel = nLev;
+ pColFields[nColFieldCount].nDimPos = nDimPos;
+ pColFields[nColFieldCount].aResult = xLevRes->getResults();
+ pColFields[nColFieldCount].maName = aName;
+ pColFields[nColFieldCount].aCaption= aCaption;
+ pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
+ if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
+ ++nColFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_ROW:
+ pRowFields[nRowFieldCount].nDim = nDim;
+ pRowFields[nRowFieldCount].nHier = nHierarchy;
+ pRowFields[nRowFieldCount].nLevel = nLev;
+ pRowFields[nRowFieldCount].nDimPos = nDimPos;
+ pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
+ pRowFields[nRowFieldCount].maName = aName;
+ pRowFields[nRowFieldCount].aCaption= aCaption;
+ pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
+ if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
+ {
+ ++nRowFieldCount;
+ bRowFieldHasMember = true;
+ }
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ pPageFields[nPageFieldCount].nDim = nDim;
+ pPageFields[nPageFieldCount].nHier = nHierarchy;
+ pPageFields[nPageFieldCount].nLevel = nLev;
+ pPageFields[nPageFieldCount].nDimPos = nDimPos;
+ pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
+ pPageFields[nPageFieldCount].maName = aName;
+ pPageFields[nPageFieldCount].aCaption= aCaption;
+ pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
+ // no check on results for page fields
+ ++nPageFieldCount;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ // get number formats from data dimensions
+ if ( bIsDataLayout )
+ {
+ if (bRowFieldHasMember)
+ mbHasDataLayout = true;
+
+ DBG_ASSERT( nLevCount == 1, "data layout: multiple levels?" );
+ if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
+ lcl_FillNumberFormats( pColNumFmt, nColFmtCount, xLevRes, xDims );
+ else if ( eDimOrient == sheet::DataPilotFieldOrientation_ROW )
+ lcl_FillNumberFormats( pRowNumFmt, nRowFmtCount, xLevRes, xDims );
+ }
+ }
+ }
+ }
+ }
+ else if ( bIsDataLayout )
+ {
+ // data layout dimension is hidden (allowed if there is only one data dimension)
+ // -> use the number format from the first data dimension for all results
+
+ nSingleNumFmt = lcl_GetFirstNumberFormat( xDims );
+ }
+ }
+ }
+ lcl_SortFields( pColFields, nColFieldCount );
+ lcl_SortFields( pRowFields, nRowFieldCount );
+ lcl_SortFields( pPageFields, nPageFieldCount );
+
+ // get data results:
+
+ try
+ {
+ aData = xResult->getResults();
+ }
+ catch (uno::RuntimeException&)
+ {
+ bResultsError = TRUE;
+ }
+ }
+
+ // get "DataDescription" property (may be missing in external sources)
+
+ uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY );
+ if ( xSrcProp.is() )
+ {
+ try
+ {
+ uno::Any aAny = xSrcProp->getPropertyValue(
+ rtl::OUString::createFromAscii(SC_UNO_DATADESC) );
+ rtl::OUString aUStr;
+ aAny >>= aUStr;
+ aDataDescription = String( aUStr );
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+}
+
+ScDPOutput::~ScDPOutput()
+{
+ delete[] pColFields;
+ delete[] pRowFields;
+ delete[] pPageFields;
+
+ delete[] pColNumFmt;
+ delete[] pRowNumFmt;
+}
+
+void ScDPOutput::SetPosition( const ScAddress& rPos )
+{
+ aStartPos = rPos;
+ bSizesValid = bSizeOverflow = FALSE;
+}
+
+void ScDPOutput::DataCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const sheet::DataResult& rData )
+{
+ long nFlags = rData.Flags;
+ if ( nFlags & sheet::DataResultFlags::ERROR )
+ {
+ pDoc->SetError( nCol, nRow, nTab, errNoValue );
+ }
+ else if ( nFlags & sheet::DataResultFlags::HASDATA )
+ {
+ pDoc->SetValue( nCol, nRow, nTab, rData.Value );
+
+ // use number formats from source
+
+ DBG_ASSERT( bSizesValid, "DataCell: !bSizesValid" );
+ UINT32 nFormat = 0;
+ if ( pColNumFmt )
+ {
+ if ( nCol >= nDataStartCol )
+ {
+ long nIndex = nCol - nDataStartCol;
+ if ( nIndex < nColFmtCount )
+ nFormat = pColNumFmt[nIndex];
+ }
+ }
+ else if ( pRowNumFmt )
+ {
+ if ( nRow >= nDataStartRow )
+ {
+ long nIndex = nRow - nDataStartRow;
+ if ( nIndex < nRowFmtCount )
+ nFormat = pRowNumFmt[nIndex];
+ }
+ }
+ else if ( nSingleNumFmt != 0 )
+ nFormat = nSingleNumFmt; // single format is used everywhere
+ if ( nFormat != 0 )
+ pDoc->ApplyAttr( nCol, nRow, nTab, SfxUInt32Item( ATTR_VALUE_FORMAT, nFormat ) );
+ }
+ else
+ {
+ //pDoc->SetString( nCol, nRow, nTab, EMPTY_STRING );
+ }
+
+ // SubTotal formatting is controlled by headers
+}
+
+void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ const sheet::MemberResult& rData, BOOL bColHeader, long nLevel )
+{
+ long nFlags = rData.Flags;
+
+ rtl::OUStringBuffer aCaptionBuf;
+ if (!(nFlags & sheet::MemberResultFlags::NUMERIC))
+ // This caption is not a number. Make sure it won't get parsed as one.
+ aCaptionBuf.append(sal_Unicode('\''));
+ aCaptionBuf.append(rData.Caption);
+
+ if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
+ {
+ pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() );
+ }
+ else
+ {
+ //pDoc->SetString( nCol, nRow, nTab, EMPTY_STRING );
+ }
+
+ if ( nFlags & sheet::MemberResultFlags::SUBTOTAL )
+ {
+// SvxWeightItem aItem( WEIGHT_BOLD ); // weight is in the style
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ OutputImpl outputimp( pDoc, nTab,
+ nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow,
+ nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow );
+ // End Comments
+ //! limit frames to horizontal or vertical?
+ if (bColHeader)
+ {
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ //lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, SC_DP_FRAME_INNER_BOLD );
+ outputimp.OutputBlockFrame( nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1 );
+ // End Comments
+
+ lcl_SetStyleById( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1,
+ STR_PIVOT_STYLE_TITLE );
+ lcl_SetStyleById( pDoc,nTab, nCol,nDataStartRow, nCol,nTabEndRow,
+ STR_PIVOT_STYLE_RESULT );
+ }
+ else
+ {
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ //lcl_SetFrame( pDoc,nTab, nMemberStartCol+(USHORT)nLevel,nRow, nTabEndCol,nRow, SC_DP_FRAME_INNER_BOLD );
+ outputimp.OutputBlockFrame( nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow );
+ // End Comments
+ lcl_SetStyleById( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow,
+ STR_PIVOT_STYLE_TITLE );
+ lcl_SetStyleById( pDoc,nTab, nDataStartCol,nRow, nTabEndCol,nRow,
+ STR_PIVOT_STYLE_RESULT );
+ }
+ }
+}
+
+void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
+ bool bInTable, bool bPopup, bool bHasHiddenMember )
+{
+ pDoc->SetString( nCol, nRow, nTab, rCaption );
+ if (bInTable)
+ lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
+
+ // Button
+ sal_uInt16 nMergeFlag = SC_MF_BUTTON;
+ if (bPopup)
+ nMergeFlag |= SC_MF_BUTTON_POPUP;
+ if (bHasHiddenMember)
+ nMergeFlag |= SC_MF_HIDDEN_MEMBER;
+ pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag);
+
+ lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME );
+}
+
+void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) );
+ pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
+}
+
+void ScDPOutput::CalcSizes()
+{
+ if (!bSizesValid)
+ {
+ // get column size of data from first row
+ //! allow different sizes (and clear following areas) ???
+
+ nRowCount = aData.getLength();
+ const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
+ nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
+
+ nHeaderSize = 1;
+ if (GetHeaderLayout() && nColFieldCount == 0)
+ // Insert an extra header row only when there is no column field.
+ nHeaderSize = 2;
+
+ // calculate output positions and sizes
+
+ long nPageSize = 0; //! use page fields!
+ if ( bDoFilter || nPageFieldCount )
+ {
+ nPageSize += nPageFieldCount + 1; // plus one empty row
+ if ( bDoFilter )
+ ++nPageSize; // filter button above the page fields
+ }
+
+ if ( aStartPos.Col() + nRowFieldCount + nColCount - 1 > MAXCOL ||
+ aStartPos.Row() + nPageSize + nHeaderSize + nColFieldCount + nRowCount > MAXROW )
+ {
+ bSizeOverflow = TRUE;
+ }
+
+ nTabStartCol = aStartPos.Col();
+ nTabStartRow = aStartPos.Row() + (SCROW)nPageSize; // below page fields
+ nMemberStartCol = nTabStartCol;
+ nMemberStartRow = nTabStartRow + (SCROW) nHeaderSize;
+ nDataStartCol = nMemberStartCol + (SCCOL)nRowFieldCount;
+ nDataStartRow = nMemberStartRow + (SCROW)nColFieldCount;
+ if ( nColCount > 0 )
+ nTabEndCol = nDataStartCol + (SCCOL)nColCount - 1;
+ else
+ nTabEndCol = nDataStartCol; // single column will remain empty
+ // if page fields are involved, include the page selection cells
+ if ( nPageFieldCount > 0 && nTabEndCol < nTabStartCol + 1 )
+ nTabEndCol = nTabStartCol + 1;
+ if ( nRowCount > 0 )
+ nTabEndRow = nDataStartRow + (SCROW)nRowCount - 1;
+ else
+ nTabEndRow = nDataStartRow; // single row will remain empty
+ bSizesValid = TRUE;
+ }
+}
+
+sal_Int32 ScDPOutput::GetPositionType(const ScAddress& rPos)
+{
+ using namespace ::com::sun::star::sheet;
+
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ if ( nTab != aStartPos.Tab() )
+ return DataPilotTablePositionType::NOT_IN_TABLE;
+
+ CalcSizes();
+
+ // Make sure the cursor is within the table.
+ if (nCol < nTabStartCol || nRow < nTabStartRow || nCol > nTabEndCol || nRow > nTabEndRow)
+ return DataPilotTablePositionType::NOT_IN_TABLE;
+
+ // test for result data area.
+ if (nCol >= nDataStartCol && nCol <= nTabEndCol && nRow >= nDataStartRow && nRow <= nTabEndRow)
+ return DataPilotTablePositionType::RESULT;
+
+ bool bInColHeader = (nRow >= nTabStartRow && nRow < nDataStartRow);
+ bool bInRowHeader = (nCol >= nTabStartCol && nCol < nDataStartCol);
+
+ if (bInColHeader && bInRowHeader)
+ // probably in that ugly little box at the upper-left corner of the table.
+ return DataPilotTablePositionType::OTHER;
+
+ if (bInColHeader)
+ {
+ if (nRow == nTabStartRow)
+ // first row in the column header area is always used for column
+ // field buttons.
+ return DataPilotTablePositionType::OTHER;
+
+ return DataPilotTablePositionType::COLUMN_HEADER;
+ }
+
+ if (bInRowHeader)
+ return DataPilotTablePositionType::ROW_HEADER;
+
+ return DataPilotTablePositionType::OTHER;
+}
+
+void ScDPOutput::Output()
+{
+ long nField;
+ SCTAB nTab = aStartPos.Tab();
+ const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
+
+ // calculate output positions and sizes
+
+ CalcSizes();
+ if ( bSizeOverflow || bResultsError ) // does output area exceed sheet limits?
+ return; // nothing
+
+ // clear whole (new) output area
+ //! when modifying table, clear old area
+ //! include IDF_OBJECTS ???
+ pDoc->DeleteAreaTab( aStartPos.Col(), aStartPos.Row(), nTabEndCol, nTabEndRow, nTab, IDF_ALL );
+
+ if ( bDoFilter )
+ lcl_DoFilterButton( pDoc, aStartPos.Col(), aStartPos.Row(), nTab );
+
+ // output data results:
+
+ for (long nRow=0; nRow<nRowCount; nRow++)
+ {
+ SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow
+ const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray();
+ long nThisColCount = pRowAry[nRow].getLength();
+ DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ???
+ for (long nCol=0; nCol<nThisColCount; nCol++)
+ {
+ SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow
+ DataCell( nColPos, nRowPos, nTab, pColAry[nCol] );
+ }
+ }
+ // output page fields:
+
+ for (nField=0; nField<nPageFieldCount; nField++)
+ {
+ SCCOL nHdrCol = aStartPos.Col();
+ SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 );
+ // draw without frame for consistency with filter button:
+ FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, false, false, pPageFields[nField].mbHasHiddenMember );
+ SCCOL nFldCol = nHdrCol + 1;
+
+ String aPageValue;
+ if ( pPageFields[nField].aResult.getLength() == 1 )
+ aPageValue = pPageFields[nField].aResult[0].Caption;
+ else
+ aPageValue = String( ScResId( SCSTR_ALL ) ); //! separate string?
+
+ pDoc->SetString( nFldCol, nHdrRow, nTab, aPageValue );
+
+ lcl_SetFrame( pDoc,nTab, nFldCol,nHdrRow, nFldCol,nHdrRow, 20 );
+ pDoc->ApplyAttr( nFldCol, nHdrRow, nTab, ScMergeFlagAttr(SC_MF_AUTO) );
+ //! which style?
+ }
+
+ // data description
+ // (may get overwritten by first row field)
+
+ String aDesc = aDataDescription;
+ if ( !aDesc.Len() )
+ {
+ //! use default string ("result") ?
+ }
+ pDoc->SetString( nTabStartCol, nTabStartRow, nTab, aDesc );
+
+ // set STR_PIVOT_STYLE_INNER for whole data area (subtotals are overwritten)
+
+ if ( nDataStartRow > nTabStartRow )
+ lcl_SetStyleById( pDoc, nTab, nTabStartCol, nTabStartRow, nTabEndCol, nDataStartRow-1,
+ STR_PIVOT_STYLE_TOP );
+ lcl_SetStyleById( pDoc, nTab, nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow,
+ STR_PIVOT_STYLE_INNER );
+
+ // output column headers:
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ OutputImpl outputimp( pDoc, nTab,
+ nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow,
+ nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow );
+ // End Comments
+ for (nField=0; nField<nColFieldCount; nField++)
+ {
+ SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow
+ FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption, true, true, pColFields[nField].mbHasHiddenMember );
+
+ SCROW nRowPos = nMemberStartRow + (SCROW)nField; //! check for overflow
+ const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+ long nThisColCount = rSequence.getLength();
+ DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ???
+ for (long nCol=0; nCol<nThisColCount; nCol++)
+ {
+ SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow
+ HeaderCell( nColPos, nRowPos, nTab, pArray[nCol], TRUE, nField );
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ if ( ( pArray[nCol].Flags & sheet::MemberResultFlags::HASMEMBER ) &&
+ !( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) )
+ {
+ long nEnd = nCol;
+ while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) )
+ ++nEnd;
+ SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow
+ if ( nField+1 < nColFieldCount )
+ {
+ // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, SC_DP_FRAME_INNER_BOLD );
+ // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, SC_DP_FRAME_INNER_BOLD );
+ if ( nField == nColFieldCount - 2 )
+ {
+ outputimp.AddCol( nColPos );
+ if ( nColPos + 1 == nEndColPos )
+ outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos+1, TRUE );
+ }
+ else
+ outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos );
+
+ lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nEndColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY );
+ }
+ else
+ lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY );
+ }
+ else if ( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL )
+ outputimp.AddCol( nColPos );
+ }
+ if ( nField== 0 && nColFieldCount == 1 )
+ outputimp.OutputBlockFrame( nDataStartCol,nTabStartRow, nTabEndCol,nRowPos-1 );
+ // End Comments
+ }
+
+ // output row headers:
+ std::vector<BOOL> vbSetBorder;
+ vbSetBorder.resize( nTabEndRow - nDataStartRow + 1, FALSE );
+ for (nField=0; nField<nRowFieldCount; nField++)
+ {
+ bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1);
+
+ SCCOL nHdrCol = nTabStartCol + (SCCOL)nField; //! check for overflow
+ SCROW nHdrRow = nDataStartRow - 1;
+ FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption, true, !bDataLayout,
+ pRowFields[nField].mbHasHiddenMember );
+
+ SCCOL nColPos = nMemberStartCol + (SCCOL)nField; //! check for overflow
+ const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+ long nThisRowCount = rSequence.getLength();
+ DBG_ASSERT( nThisRowCount == nRowCount, "count mismatch" ); //! ???
+ for (long nRow=0; nRow<nThisRowCount; nRow++)
+ {
+ SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow
+ HeaderCell( nColPos, nRowPos, nTab, pArray[nRow], FALSE, nField );
+ if ( ( pArray[nRow].Flags & sheet::MemberResultFlags::HASMEMBER ) &&
+ !( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL ) )
+ {
+ if ( nField+1 < nRowFieldCount )
+ {
+ long nEnd = nRow;
+ while ( nEnd+1 < nThisRowCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) )
+ ++nEnd;
+ SCROW nEndRowPos = nDataStartRow + (SCROW)nEnd; //! check for overflow
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, SC_DP_FRAME_INNER_BOLD );
+ //lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, SC_DP_FRAME_INNER_BOLD );
+ outputimp.AddRow( nRowPos );
+ if ( vbSetBorder[ nRow ] == FALSE )
+ {
+ outputimp.OutputBlockFrame( nColPos, nRowPos, nTabEndCol, nEndRowPos );
+ vbSetBorder[ nRow ] = TRUE;
+ }
+ outputimp.OutputBlockFrame( nColPos, nRowPos, nColPos, nEndRowPos );
+
+ if ( nField == nRowFieldCount - 2 )
+ outputimp.OutputBlockFrame( nColPos+1, nRowPos, nColPos+1, nEndRowPos );
+ // End Comments
+
+ lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nEndRowPos, STR_PIVOT_STYLE_CATEGORY );
+ }
+ else
+ lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nRowPos, STR_PIVOT_STYLE_CATEGORY );
+ }
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ else if ( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL )
+ outputimp.AddRow( nRowPos );
+ // End Comments
+ }
+ }
+
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+ outputimp.OutputDataArea();
+// End Comments
+}
+
+ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType )
+{
+ using namespace ::com::sun::star::sheet;
+
+ CalcSizes();
+
+// fprintf(stdout, "ScDPOutput::GetOutputRange: aStartPos = (%ld, %d)\n", aStartPos.Row(), aStartPos.Col());fflush(stdout);
+// fprintf(stdout, "ScDPOutput::GetOutputRange: nTabStart (Row = %ld, Col = %ld)\n", nTabStartRow, nTabStartCol);fflush(stdout);
+// fprintf(stdout, "ScDPOutput::GetOutputRange: nMemberStart (Row = %ld, Col = %ld)\n", nMemberStartRow, nMemberStartCol);fflush(stdout);
+// fprintf(stdout, "ScDPOutput::GetOutputRange: nDataStart (Row = %ld, Col = %ld)\n", nDataStartRow, nDataStartCol);fflush(stdout);
+// fprintf(stdout, "ScDPOutput::GetOutputRange: nTabEnd (Row = %ld, Col = %ld)\n", nTabEndRow, nTabStartCol);fflush(stdout);
+
+ SCTAB nTab = aStartPos.Tab();
+ switch (nRegionType)
+ {
+ case DataPilotOutputRangeType::RESULT:
+ return ScRange(nDataStartCol, nDataStartRow, nTab, nTabEndCol, nTabEndRow, nTab);
+ case DataPilotOutputRangeType::TABLE:
+ return ScRange(aStartPos.Col(), nTabStartRow, nTab, nTabEndCol, nTabEndRow, nTab);
+ default:
+ DBG_ASSERT(nRegionType == DataPilotOutputRangeType::WHOLE, "ScDPOutput::GetOutputRange: unknown region type");
+ break;
+ }
+ return ScRange(aStartPos.Col(), aStartPos.Row(), nTab, nTabEndCol, nTabEndRow, nTab);
+}
+
+BOOL ScDPOutput::HasError()
+{
+ CalcSizes();
+
+ return bSizeOverflow || bResultsError;
+}
+
+long ScDPOutput::GetHeaderRows()
+{
+ return nPageFieldCount + ( bDoFilter ? 1 : 0 );
+}
+
+void ScDPOutput::GetMemberResultNames( ScStrCollection& rNames, long nDimension )
+{
+ // Return the list of all member names in a dimension's MemberResults.
+ // Only the dimension has to be compared because this is only used with table data,
+ // where each dimension occurs only once.
+
+ uno::Sequence<sheet::MemberResult> aMemberResults;
+ bool bFound = false;
+ long nField;
+
+ // look in column fields
+
+ for (nField=0; nField<nColFieldCount && !bFound; nField++)
+ if ( pColFields[nField].nDim == nDimension )
+ {
+ aMemberResults = pColFields[nField].aResult;
+ bFound = true;
+ }
+
+ // look in row fields
+
+ for (nField=0; nField<nRowFieldCount && !bFound; nField++)
+ if ( pRowFields[nField].nDim == nDimension )
+ {
+ aMemberResults = pRowFields[nField].aResult;
+ bFound = true;
+ }
+
+ // collect the member names
+
+ if ( bFound )
+ {
+ const sheet::MemberResult* pArray = aMemberResults.getConstArray();
+ long nResultCount = aMemberResults.getLength();
+
+ for (long nItem=0; nItem<nResultCount; nItem++)
+ {
+ if ( pArray[nItem].Flags & sheet::MemberResultFlags::HASMEMBER )
+ {
+ StrData* pNew = new StrData( pArray[nItem].Name );
+ if ( !rNames.Insert( pNew ) )
+ delete pNew;
+ }
+ }
+ }
+}
+
+void ScDPOutput::SetHeaderLayout(bool bUseGrid)
+{
+ mbHeaderLayout = bUseGrid;
+ bSizesValid = false;
+}
+
+bool ScDPOutput::GetHeaderLayout() const
+{
+ return mbHeaderLayout;
+}
+
+void lcl_GetTableVars( sal_Int32& rGrandTotalCols, sal_Int32& rGrandTotalRows, sal_Int32& rDataLayoutIndex,
+ std::vector<String>& rDataNames, std::vector<String>& rGivenNames,
+ sheet::DataPilotFieldOrientation& rDataOrient,
+ const uno::Reference<sheet::XDimensionsSupplier>& xSource )
+{
+ rDataLayoutIndex = -1; // invalid
+ rGrandTotalCols = 0;
+ rGrandTotalRows = 0;
+ rDataOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY );
+ BOOL bColGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp,
+ rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND) );
+ if ( bColGrand )
+ rGrandTotalCols = 1; // default if data layout not in columns
+
+ BOOL bRowGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp,
+ rtl::OUString::createFromAscii(DP_PROP_ROWGRAND) );
+ if ( bRowGrand )
+ rGrandTotalRows = 1; // default if data layout not in rows
+
+ if ( xSource.is() )
+ {
+ // find index and orientation of "data layout" dimension, count data dimensions
+
+ sal_Int32 nDataCount = 0;
+
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xSource->getDimensions() );
+ long nDimCount = xDims->getCount();
+ for (long nDim=0; nDim<nDimCount; nDim++)
+ {
+ uno::Reference<uno::XInterface> xDim =
+ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ if ( xDimProp.is() )
+ {
+ sheet::DataPilotFieldOrientation eDimOrient =
+ (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
+ sheet::DataPilotFieldOrientation_HIDDEN );
+ if ( ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) ) )
+ {
+ rDataLayoutIndex = nDim;
+ rDataOrient = eDimOrient;
+ }
+ if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
+ {
+ String aSourceName;
+ String aGivenName;
+ ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xDim );
+ rDataNames.push_back( aSourceName );
+ rGivenNames.push_back( aGivenName );
+
+ ++nDataCount;
+ }
+ }
+ }
+
+ if ( ( rDataOrient == sheet::DataPilotFieldOrientation_COLUMN ) && bColGrand )
+ rGrandTotalCols = nDataCount;
+ else if ( ( rDataOrient == sheet::DataPilotFieldOrientation_ROW ) && bRowGrand )
+ rGrandTotalRows = nDataCount;
+ }
+}
+
+void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
+{
+ using namespace ::com::sun::star::sheet;
+
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ if ( nTab != aStartPos.Tab() )
+ return; // wrong sheet
+
+ // calculate output positions and sizes
+
+ CalcSizes();
+
+ rPosData.PositionType = GetPositionType(rPos);
+ switch (rPosData.PositionType)
+ {
+ case DataPilotTablePositionType::RESULT:
+ {
+ vector<DataPilotFieldFilter> aFilters;
+ GetDataResultPositionData(aFilters, rPos);
+ sal_Int32 nSize = aFilters.size();
+
+ DataPilotTableResultData aResData;
+ aResData.FieldFilters.realloc(nSize);
+ for (sal_Int32 i = 0; i < nSize; ++i)
+ aResData.FieldFilters[i] = aFilters[i];
+
+ aResData.DataFieldIndex = 0;
+ Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY);
+ if (xPropSet.is())
+ {
+ sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet,
+ rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) );
+ if (nDataFieldCount > 0)
+ aResData.DataFieldIndex = (nRow - nDataStartRow) % nDataFieldCount;
+ }
+
+ // Copy appropriate DataResult object from the cached sheet::DataResult table.
+ if (aData.getLength() > nRow - nDataStartRow &&
+ aData[nRow-nDataStartRow].getLength() > nCol-nDataStartCol)
+ aResData.Result = aData[nRow-nDataStartRow][nCol-nDataStartCol];
+
+ rPosData.PositionData = makeAny(aResData);
+ return;
+ }
+ case DataPilotTablePositionType::COLUMN_HEADER:
+ {
+ long nField = nRow - nTabStartRow - 1; // 1st line is used for the buttons
+ if (nField < 0)
+ break;
+
+ const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
+ if (rSequence.getLength() == 0)
+ break;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+
+ long nItem = nCol - nDataStartCol;
+ // get origin of "continue" fields
+ while (nItem > 0 && ( pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
+ --nItem;
+
+ if (nItem < 0)
+ break;
+
+ DataPilotTableHeaderData aHeaderData;
+ aHeaderData.MemberName = OUString(pArray[nItem].Name);
+ aHeaderData.Flags = pArray[nItem].Flags;
+ aHeaderData.Dimension = static_cast<sal_Int32>(pColFields[nField].nDim);
+ aHeaderData.Hierarchy = static_cast<sal_Int32>(pColFields[nField].nHier);
+ aHeaderData.Level = static_cast<sal_Int32>(pColFields[nField].nLevel);
+
+ rPosData.PositionData = makeAny(aHeaderData);
+ return;
+ }
+ case DataPilotTablePositionType::ROW_HEADER:
+ {
+ long nField = nCol - nTabStartCol;
+ if (nField < 0)
+ break;
+
+ const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
+ if (rSequence.getLength() == 0)
+ break;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+
+ long nItem = nRow - nDataStartRow;
+ // get origin of "continue" fields
+ while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
+ --nItem;
+
+ if (nItem < 0)
+ break;
+
+ DataPilotTableHeaderData aHeaderData;
+ aHeaderData.MemberName = OUString(pArray[nItem].Name);
+ aHeaderData.Flags = pArray[nItem].Flags;
+ aHeaderData.Dimension = static_cast<sal_Int32>(pRowFields[nField].nDim);
+ aHeaderData.Hierarchy = static_cast<sal_Int32>(pRowFields[nField].nHier);
+ aHeaderData.Level = static_cast<sal_Int32>(pRowFields[nField].nLevel);
+
+ rPosData.PositionData = makeAny(aHeaderData);
+ return;
+ }
+ }
+}
+
+bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>& rFilters, const ScAddress& rPos)
+{
+ // Check to make sure there is at least one data field.
+ Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY);
+ if (!xPropSet.is())
+ return false;
+
+ sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet,
+ rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) );
+ if (nDataFieldCount == 0)
+ // No data field is present in this datapilot table.
+ return false;
+
+ // #i111421# use lcl_GetTableVars for correct size of totals and data layout position
+ sal_Int32 nGrandTotalCols;
+ sal_Int32 nGrandTotalRows;
+ sal_Int32 nDataLayoutIndex;
+ std::vector<String> aDataNames;
+ std::vector<String> aGivenNames;
+ sheet::DataPilotFieldOrientation eDataOrient;
+ lcl_GetTableVars( nGrandTotalCols, nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, eDataOrient, xSource );
+
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ if ( nTab != aStartPos.Tab() )
+ return false; // wrong sheet
+
+ CalcSizes();
+
+ // test for data area.
+ if (nCol < nDataStartCol || nCol > nTabEndCol || nRow < nDataStartRow || nRow > nTabEndRow)
+ {
+ // Cell is outside the data field area.
+ return false;
+ }
+
+ bool bFilterByCol = (nCol <= static_cast<SCCOL>(nTabEndCol - nGrandTotalCols));
+ bool bFilterByRow = (nRow <= static_cast<SCROW>(nTabEndRow - nGrandTotalRows));
+
+ // column fields
+ for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
+ {
+ if (pColFields[nColField].nDim == nDataLayoutIndex)
+ // There is no sense including the data layout field for filtering.
+ continue;
+
+ sheet::DataPilotFieldFilter filter;
+ filter.FieldName = pColFields[nColField].maName;
+
+ const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+
+ DBG_ASSERT(nDataStartCol + rSequence.getLength() - 1 == nTabEndCol, "ScDPOutput::GetDataFieldCellData: error in geometric assumption");
+
+ long nItem = nCol - nDataStartCol;
+ // get origin of "continue" fields
+ while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
+ --nItem;
+
+ filter.MatchValue = pArray[nItem].Name;
+ rFilters.push_back(filter);
+ }
+
+ // row fields
+ for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
+ {
+ if (pRowFields[nRowField].nDim == nDataLayoutIndex)
+ // There is no sense including the data layout field for filtering.
+ continue;
+
+ sheet::DataPilotFieldFilter filter;
+ filter.FieldName = pRowFields[nRowField].maName;
+
+ const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+
+ DBG_ASSERT(nDataStartRow + rSequence.getLength() - 1 == nTabEndRow, "ScDPOutput::GetDataFieldCellData: error in geometric assumption");
+
+ long nItem = nRow - nDataStartRow;
+ // get origin of "continue" fields
+ while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
+ --nItem;
+
+ filter.MatchValue = pArray[nItem].Name;
+ rFilters.push_back(filter);
+ }
+
+ return true;
+}
+
+//
+// helper functions for ScDPOutput::GetPivotData
+//
+
+bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& rSourceName, const String& rGivenName )
+{
+ // match one of the names, ignoring case
+ return ScGlobal::GetpTransliteration()->isEqual( rTarget.maFieldName, rSourceName ) ||
+ ScGlobal::GetpTransliteration()->isEqual( rTarget.maFieldName, rGivenName );
+}
+
+bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField )
+{
+ return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.maName );
+}
+
+bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter )
+{
+ //! handle numeric conditions?
+ return ScGlobal::GetpTransliteration()->isEqual( rResultEntry.Name, rFilter.maValStr );
+}
+
+bool lcl_CheckPageField( const ScDPOutLevelData& rField,
+ const std::vector< ScDPGetPivotDataField >& rFilters,
+ std::vector< BOOL >& rFilterUsed )
+{
+ for (SCSIZE nFilterPos = 0; nFilterPos < rFilters.size(); ++nFilterPos)
+ {
+ if ( lcl_IsNamedCategoryField( rFilters[nFilterPos], rField ) )
+ {
+ rFilterUsed[nFilterPos] = TRUE;
+
+ // page field result is empty or the selection as single entry (see lcl_GetSelectedPageAsResult)
+ if ( rField.aResult.getLength() == 1 &&
+ lcl_IsCondition( rField.aResult[0], rFilters[nFilterPos] ) )
+ {
+ return true; // condition matches page selection
+ }
+ else
+ {
+ return false; // no page selection or different entry
+ }
+ }
+ }
+
+ return true; // valid if the page field doesn't have a filter
+}
+
+uno::Sequence<sheet::GeneralFunction> lcl_GetSubTotals(
+ const uno::Reference<sheet::XDimensionsSupplier>& xSource, const ScDPOutLevelData& rField )
+{
+ uno::Sequence<sheet::GeneralFunction> aSubTotals;
+
+ uno::Reference<sheet::XHierarchiesSupplier> xHierSupp;
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ sal_Int32 nIntCount = xIntDims->getCount();
+ if ( rField.nDim < nIntCount )
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
+ xIntDims->getByIndex( rField.nDim ) );
+ xHierSupp = uno::Reference<sheet::XHierarchiesSupplier>( xIntDim, uno::UNO_QUERY );
+ }
+ DBG_ASSERT( xHierSupp.is(), "dimension not found" );
+
+ sal_Int32 nHierCount = 0;
+ uno::Reference<container::XIndexAccess> xHiers;
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
+ xHiers = new ScNameToIndexAccess( xHiersName );
+ nHierCount = xHiers->getCount();
+ }
+ uno::Reference<uno::XInterface> xHier;
+ if ( rField.nHier < nHierCount )
+ xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex( rField.nHier ) );
+ DBG_ASSERT( xHier.is(), "hierarchy not found" );
+
+ sal_Int32 nLevCount = 0;
+ uno::Reference<container::XIndexAccess> xLevels;
+ uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
+ if ( xLevSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
+ xLevels = new ScNameToIndexAccess( xLevsName );
+ nLevCount = xLevels->getCount();
+ }
+ uno::Reference<uno::XInterface> xLevel;
+ if ( rField.nLevel < nLevCount )
+ xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( rField.nLevel ) );
+ DBG_ASSERT( xLevel.is(), "level not found" );
+
+ uno::Reference<beans::XPropertySet> xLevelProp( xLevel, uno::UNO_QUERY );
+ if ( xLevelProp.is() )
+ {
+ try
+ {
+ uno::Any aValue = xLevelProp->getPropertyValue( rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS) );
+ aValue >>= aSubTotals;
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+
+ return aSubTotals;
+}
+
+void lcl_FilterInclude( std::vector< BOOL >& rResult, std::vector< sal_Int32 >& rSubtotal,
+ const ScDPOutLevelData& rField,
+ const std::vector< ScDPGetPivotDataField >& rFilters,
+ std::vector< BOOL >& rFilterUsed,
+ bool& rBeforeDataLayout,
+ sal_Int32 nGrandTotals, sal_Int32 nDataLayoutIndex,
+ const std::vector<String>& rDataNames, const std::vector<String>& rGivenNames,
+ const ScDPGetPivotDataField& rTarget, const uno::Reference<sheet::XDimensionsSupplier>& xSource )
+{
+ // returns true if a filter was given for the field
+
+ DBG_ASSERT( rFilters.size() == rFilterUsed.size(), "wrong size" );
+
+ const bool bIsDataLayout = ( rField.nDim == nDataLayoutIndex );
+ if (bIsDataLayout)
+ rBeforeDataLayout = false;
+
+ bool bHasFilter = false;
+ ScDPGetPivotDataField aFilter;
+ if ( !bIsDataLayout ) // selection of data field is handled separately
+ {
+ for (SCSIZE nFilterPos = 0; nFilterPos < rFilters.size() && !bHasFilter; ++nFilterPos)
+ {
+ if ( lcl_IsNamedCategoryField( rFilters[nFilterPos], rField ) )
+ {
+ aFilter = rFilters[nFilterPos];
+ rFilterUsed[nFilterPos] = TRUE;
+ bHasFilter = true;
+ }
+ }
+ }
+
+ bool bHasFunc = bHasFilter && aFilter.meFunction != sheet::GeneralFunction_NONE;
+
+ uno::Sequence<sheet::GeneralFunction> aSubTotals;
+ if ( !bIsDataLayout )
+ aSubTotals = lcl_GetSubTotals( xSource, rField );
+ bool bManualSub = ( aSubTotals.getLength() > 0 && aSubTotals[0] != sheet::GeneralFunction_AUTO );
+
+ const uno::Sequence<sheet::MemberResult>& rSequence = rField.aResult;
+ const sheet::MemberResult* pArray = rSequence.getConstArray();
+ sal_Int32 nSize = rSequence.getLength();
+
+ DBG_ASSERT( (sal_Int32)rResult.size() == nSize, "Number of fields do not match result count" );
+
+ sal_Int32 nContCount = 0;
+ sal_Int32 nSubTotalCount = 0;
+ sheet::MemberResult aPrevious;
+ for( sal_Int32 j=0; j < nSize; j++ )
+ {
+ sheet::MemberResult aResultEntry = pArray[j];
+ if ( aResultEntry.Flags & sheet::MemberResultFlags::CONTINUE )
+ {
+ aResultEntry = aPrevious;
+ ++nContCount;
+ }
+ else if ( ( aResultEntry.Flags & sheet::MemberResultFlags::SUBTOTAL ) == 0 )
+ {
+ // count the CONTINUE entries before a SUBTOTAL
+ nContCount = 0;
+ }
+
+ if ( j >= nSize - nGrandTotals )
+ {
+ // mark as subtotal for the preceding data
+ if ( ( aResultEntry.Flags & sheet::MemberResultFlags::SUBTOTAL ) != 0 )
+ {
+ rSubtotal[j] = nSize - nGrandTotals;
+
+ if ( rResult[j] && nGrandTotals > 1 )
+ {
+ // grand total is always automatic
+ sal_Int32 nDataPos = j - ( nSize - nGrandTotals );
+ DBG_ASSERT( nDataPos < (sal_Int32)rDataNames.size(), "wrong data count" );
+ String aSourceName( rDataNames[nDataPos] ); // vector contains source names
+ String aGivenName( rGivenNames[nDataPos] );
+
+ rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName );
+ }
+ }
+
+ // treat "grand total" columns/rows as empty description, as if they were marked
+ // in a previous field
+
+ DBG_ASSERT( ( aResultEntry.Flags &
+ ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL ) ) == 0 ||
+ ( aResultEntry.Flags &
+ ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL ) ) ==
+ ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL ),
+ "non-subtotal member found in grand total result" );
+ aResultEntry.Flags = 0;
+ }
+
+ // mark subtotals (not grand total) for preceding data (assume CONTINUE is set)
+ if ( ( aResultEntry.Flags & sheet::MemberResultFlags::SUBTOTAL ) != 0 )
+ {
+ rSubtotal[j] = nContCount + 1 + nSubTotalCount;
+
+ if ( rResult[j] )
+ {
+ if ( bManualSub )
+ {
+ if ( rBeforeDataLayout )
+ {
+ // manual subtotals and several data fields
+
+ sal_Int32 nDataCount = rDataNames.size();
+ sal_Int32 nFuncPos = nSubTotalCount / nDataCount; // outer order: subtotal functions
+ sal_Int32 nDataPos = nSubTotalCount % nDataCount; // inner order: data fields
+
+ String aSourceName( rDataNames[nDataPos] ); // vector contains source names
+ String aGivenName( rGivenNames[nDataPos] );
+
+ DBG_ASSERT( nFuncPos < aSubTotals.getLength(), "wrong subtotal count" );
+ rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName ) &&
+ aSubTotals[nFuncPos] == aFilter.meFunction;
+ }
+ else
+ {
+ // manual subtotals for a single data field
+
+ DBG_ASSERT( nSubTotalCount < aSubTotals.getLength(), "wrong subtotal count" );
+ rResult[j] = ( aSubTotals[nSubTotalCount] == aFilter.meFunction );
+ }
+ }
+ else // automatic subtotals
+ {
+ if ( rBeforeDataLayout )
+ {
+ DBG_ASSERT( nSubTotalCount < (sal_Int32)rDataNames.size(), "wrong data count" );
+ String aSourceName( rDataNames[nSubTotalCount] ); // vector contains source names
+ String aGivenName( rGivenNames[nSubTotalCount] );
+
+ rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName );
+ }
+
+ // if a function was specified, automatic subtotals never match
+ if ( bHasFunc )
+ rResult[j] = FALSE;
+ }
+ }
+
+ ++nSubTotalCount;
+ }
+ else
+ nSubTotalCount = 0;
+
+ if( rResult[j] )
+ {
+ if ( bIsDataLayout )
+ {
+ if ( ( aResultEntry.Flags & sheet::MemberResultFlags::HASMEMBER ) != 0 )
+ {
+ // Asterisks are added in ScDPSaveData::WriteToSource to create unique names.
+ //! preserve original name there?
+ String aSourceName( aResultEntry.Name );
+ aSourceName.EraseTrailingChars( '*' );
+
+ String aGivenName( aResultEntry.Caption ); //! Should use a stored name when available
+ aGivenName.EraseLeadingChars( '\'' );
+
+ rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName );
+ }
+ }
+ else if ( bHasFilter )
+ {
+ // name must match (simple value or subtotal)
+ rResult[j] = ( ( aResultEntry.Flags & sheet::MemberResultFlags::HASMEMBER ) != 0 ) &&
+ lcl_IsCondition( aResultEntry, aFilter );
+
+ // if a function was specified, simple (non-subtotal) values never match
+ if ( bHasFunc && nSubTotalCount == 0 )
+ rResult[j] = FALSE;
+ }
+ // if no condition is given, keep the columns/rows included
+ }
+ aPrevious = aResultEntry;
+ }
+}
+
+void lcl_StripSubTotals( std::vector< BOOL >& rResult, const std::vector< sal_Int32 >& rSubtotal )
+{
+ sal_Int32 nSize = rResult.size();
+ DBG_ASSERT( (sal_Int32)rSubtotal.size() == nSize, "sizes don't match" );
+
+ for (sal_Int32 nPos=0; nPos<nSize; nPos++)
+ if ( rResult[nPos] && rSubtotal[nPos] )
+ {
+ // if a subtotal is included, clear the result flag for the columns/rows that the subtotal includes
+ sal_Int32 nStart = nPos - rSubtotal[nPos];
+ DBG_ASSERT( nStart >= 0, "invalid subtotal count" );
+
+ for (sal_Int32 nPrev = nStart; nPrev < nPos; nPrev++)
+ rResult[nPrev] = FALSE;
+ }
+}
+
+String lcl_GetDataFieldName( const String& rSourceName, sheet::GeneralFunction eFunc )
+{
+ USHORT nStrId = 0;
+ switch ( eFunc )
+ {
+ case sheet::GeneralFunction_SUM: nStrId = STR_FUN_TEXT_SUM; break;
+ case sheet::GeneralFunction_COUNT:
+ case sheet::GeneralFunction_COUNTNUMS: nStrId = STR_FUN_TEXT_COUNT; break;
+ case sheet::GeneralFunction_AVERAGE: nStrId = STR_FUN_TEXT_AVG; break;
+ case sheet::GeneralFunction_MAX: nStrId = STR_FUN_TEXT_MAX; break;
+ case sheet::GeneralFunction_MIN: nStrId = STR_FUN_TEXT_MIN; break;
+ case sheet::GeneralFunction_PRODUCT: nStrId = STR_FUN_TEXT_PRODUCT; break;
+ case sheet::GeneralFunction_STDEV:
+ case sheet::GeneralFunction_STDEVP: nStrId = STR_FUN_TEXT_STDDEV; break;
+ case sheet::GeneralFunction_VAR:
+ case sheet::GeneralFunction_VARP: nStrId = STR_FUN_TEXT_VAR; break;
+ case sheet::GeneralFunction_NONE:
+ case sheet::GeneralFunction_AUTO:
+ default:
+ {
+ DBG_ERRORFILE("wrong function");
+ }
+ }
+ if ( !nStrId )
+ return String();
+
+ String aRet( ScGlobal::GetRscString( nStrId ) );
+ aRet.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
+ aRet.Append( rSourceName );
+ return aRet;
+}
+
+// static
+void ScDPOutput::GetDataDimensionNames( String& rSourceName, String& rGivenName,
+ const uno::Reference<uno::XInterface>& xDim )
+{
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
+ if ( xDimProp.is() && xDimName.is() )
+ {
+ // Asterisks are added in ScDPSaveData::WriteToSource to create unique names.
+ //! preserve original name there?
+ rSourceName = xDimName->getName();
+ rSourceName.EraseTrailingChars( '*' );
+
+ // Generate "given name" the same way as in dptabres.
+ //! Should use a stored name when available
+
+ sheet::GeneralFunction eFunc = (sheet::GeneralFunction)ScUnoHelpFunctions::GetEnumProperty(
+ xDimProp, rtl::OUString::createFromAscii(DP_PROP_FUNCTION),
+ sheet::GeneralFunction_NONE );
+ rGivenName = lcl_GetDataFieldName( rSourceName, eFunc );
+ }
+}
+
+// Returns TRUE on success and stores the result in rTarget
+// Returns FALSE if rFilters or rTarget describes something that is not visible
+BOOL ScDPOutput::GetPivotData( ScDPGetPivotDataField& rTarget,
+ const std::vector< ScDPGetPivotDataField >& rFilters )
+{
+ CalcSizes();
+
+ // need to know about grand total columns/rows:
+ sal_Int32 nGrandTotalCols;
+ sal_Int32 nGrandTotalRows;
+ sal_Int32 nDataLayoutIndex;
+ std::vector<String> aDataNames;
+ std::vector<String> aGivenNames;
+ sheet::DataPilotFieldOrientation eDataOrient;
+ lcl_GetTableVars( nGrandTotalCols, nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, eDataOrient, xSource );
+
+ if ( aDataNames.empty() )
+ return FALSE; // incomplete table without data fields -> no result
+
+ if ( eDataOrient == sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ // no data layout field -> single data field -> must match the selected field in rTarget
+
+ DBG_ASSERT( aDataNames.size() == 1, "several data fields but no data layout field" );
+ if ( !lcl_IsNamedDataField( rTarget, aDataNames[0], aGivenNames[0] ) )
+ return FALSE;
+ }
+
+ std::vector< BOOL > aIncludeCol( nColCount, TRUE );
+ std::vector< sal_Int32 > aSubtotalCol( nColCount, 0 );
+ std::vector< BOOL > aIncludeRow( nRowCount, TRUE );
+ std::vector< sal_Int32 > aSubtotalRow( nRowCount, 0 );
+
+ std::vector< BOOL > aFilterUsed( rFilters.size(), FALSE );
+
+ long nField;
+ long nCol;
+ long nRow;
+ bool bBeforeDataLayout;
+
+ // look in column fields
+
+ bBeforeDataLayout = ( eDataOrient == sheet::DataPilotFieldOrientation_COLUMN );
+ for (nField=0; nField<nColFieldCount; nField++)
+ lcl_FilterInclude( aIncludeCol, aSubtotalCol, pColFields[nField], rFilters, aFilterUsed, bBeforeDataLayout,
+ nGrandTotalCols, nDataLayoutIndex, aDataNames, aGivenNames, rTarget, xSource );
+
+ // look in row fields
+
+ bBeforeDataLayout = ( eDataOrient == sheet::DataPilotFieldOrientation_ROW );
+ for (nField=0; nField<nRowFieldCount; nField++)
+ lcl_FilterInclude( aIncludeRow, aSubtotalRow, pRowFields[nField], rFilters, aFilterUsed, bBeforeDataLayout,
+ nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, rTarget, xSource );
+
+ // page fields
+
+ for (nField=0; nField<nPageFieldCount; nField++)
+ if ( !lcl_CheckPageField( pPageFields[nField], rFilters, aFilterUsed ) )
+ return FALSE;
+
+ // all filter fields must be used
+ for (SCSIZE nFilter=0; nFilter<aFilterUsed.size(); nFilter++)
+ if (!aFilterUsed[nFilter])
+ return FALSE;
+
+ lcl_StripSubTotals( aIncludeCol, aSubtotalCol );
+ lcl_StripSubTotals( aIncludeRow, aSubtotalRow );
+
+ long nColPos = 0;
+ long nColIncluded = 0;
+ for (nCol=0; nCol<nColCount; nCol++)
+ if (aIncludeCol[nCol])
+ {
+ nColPos = nCol;
+ ++nColIncluded;
+ }
+
+ long nRowPos = 0;
+ long nRowIncluded = 0;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ if (aIncludeRow[nRow])
+ {
+ nRowPos = nRow;
+ ++nRowIncluded;
+ }
+
+ if ( nColIncluded != 1 || nRowIncluded != 1 )
+ return FALSE;
+
+ const uno::Sequence<sheet::DataResult>& rDataRow = aData[nRowPos];
+ if ( nColPos >= rDataRow.getLength() )
+ return FALSE;
+
+ const sheet::DataResult& rResult = rDataRow[nColPos];
+ if ( rResult.Flags & sheet::DataResultFlags::ERROR )
+ return FALSE; //! different error?
+
+ rTarget.mbValIsStr = FALSE;
+ rTarget.mnValNum = rResult.Value;
+
+ return TRUE;
+}
+
+BOOL ScDPOutput::IsFilterButton( const ScAddress& rPos )
+{
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ if ( nTab != aStartPos.Tab() || !bDoFilter )
+ return FALSE; // wrong sheet or no button at all
+
+ // filter button is at top left
+ return ( nCol == aStartPos.Col() && nRow == aStartPos.Row() );
+}
+
+long ScDPOutput::GetHeaderDim( const ScAddress& rPos, USHORT& rOrient )
+{
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ if ( nTab != aStartPos.Tab() )
+ return -1; // wrong sheet
+
+ // calculate output positions and sizes
+
+ CalcSizes();
+
+ // test for column header
+
+ if ( nRow == nTabStartRow && nCol >= nDataStartCol && nCol < nDataStartCol + nColFieldCount )
+ {
+ rOrient = sheet::DataPilotFieldOrientation_COLUMN;
+ long nField = nCol - nDataStartCol;
+ return pColFields[nField].nDim;
+ }
+
+ // test for row header
+
+ if ( nRow+1 == nDataStartRow && nCol >= nTabStartCol && nCol < nTabStartCol + nRowFieldCount )
+ {
+ rOrient = sheet::DataPilotFieldOrientation_ROW;
+ long nField = nCol - nTabStartCol;
+ return pRowFields[nField].nDim;
+ }
+
+ // test for page field
+
+ SCROW nPageStartRow = aStartPos.Row() + ( bDoFilter ? 1 : 0 );
+ if ( nCol == aStartPos.Col() && nRow >= nPageStartRow && nRow < nPageStartRow + nPageFieldCount )
+ {
+ rOrient = sheet::DataPilotFieldOrientation_PAGE;
+ long nField = nRow - nPageStartRow;
+ return pPageFields[nField].nDim;
+ }
+
+ //! single data field (?)
+
+ rOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ return -1; // invalid
+}
+
+BOOL ScDPOutput::GetHeaderDrag( const ScAddress& rPos, BOOL bMouseLeft, BOOL bMouseTop,
+ long nDragDim,
+ Rectangle& rPosRect, USHORT& rOrient, long& rDimPos )
+{
+ // Rectangle instead of ScRange for rPosRect to allow for negative values
+
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ if ( nTab != aStartPos.Tab() )
+ return FALSE; // wrong sheet
+
+ // calculate output positions and sizes
+
+ CalcSizes();
+
+ // test for column header
+
+ if ( nCol >= nDataStartCol && nCol <= nTabEndCol &&
+ nRow + 1 >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount )
+ {
+ long nField = nRow - nMemberStartRow;
+ if (nField < 0)
+ {
+ nField = 0;
+ bMouseTop = TRUE;
+ }
+ //! find start of dimension
+
+ rPosRect = Rectangle( nDataStartCol, nMemberStartRow + nField,
+ nTabEndCol, nMemberStartRow + nField -1 );
+
+ BOOL bFound = FALSE; // is this within the same orientation?
+ BOOL bBeforeDrag = FALSE;
+ BOOL bAfterDrag = FALSE;
+ for (long nPos=0; nPos<nColFieldCount && !bFound; nPos++)
+ {
+ if (pColFields[nPos].nDim == nDragDim)
+ {
+ bFound = TRUE;
+ if ( nField < nPos )
+ bBeforeDrag = TRUE;
+ else if ( nField > nPos )
+ bAfterDrag = TRUE;
+ }
+ }
+
+ if ( bFound )
+ {
+ if (!bBeforeDrag)
+ {
+ ++rPosRect.Bottom();
+ if (bAfterDrag)
+ ++rPosRect.Top();
+ }
+ }
+ else
+ {
+ if ( !bMouseTop )
+ {
+ ++rPosRect.Top();
+ ++rPosRect.Bottom();
+ ++nField;
+ }
+ }
+
+ rOrient = sheet::DataPilotFieldOrientation_COLUMN;
+ rDimPos = nField; //!...
+ return TRUE;
+ }
+
+ // test for row header
+
+ // special case if no row fields
+ BOOL bSpecial = ( nRow+1 >= nDataStartRow && nRow <= nTabEndRow &&
+ nRowFieldCount == 0 && nCol == nTabStartCol && bMouseLeft );
+
+ if ( bSpecial || ( nRow+1 >= nDataStartRow && nRow <= nTabEndRow &&
+ nCol + 1 >= nTabStartCol && nCol < nTabStartCol + nRowFieldCount ) )
+ {
+ long nField = nCol - nTabStartCol;
+ //! find start of dimension
+
+ rPosRect = Rectangle( nTabStartCol + nField, nDataStartRow - 1,
+ nTabStartCol + nField - 1, nTabEndRow );
+
+ BOOL bFound = FALSE; // is this within the same orientation?
+ BOOL bBeforeDrag = FALSE;
+ BOOL bAfterDrag = FALSE;
+ for (long nPos=0; nPos<nRowFieldCount && !bFound; nPos++)
+ {
+ if (pRowFields[nPos].nDim == nDragDim)
+ {
+ bFound = TRUE;
+ if ( nField < nPos )
+ bBeforeDrag = TRUE;
+ else if ( nField > nPos )
+ bAfterDrag = TRUE;
+ }
+ }
+
+ if ( bFound )
+ {
+ if (!bBeforeDrag)
+ {
+ ++rPosRect.Right();
+ if (bAfterDrag)
+ ++rPosRect.Left();
+ }
+ }
+ else
+ {
+ if ( !bMouseLeft )
+ {
+ ++rPosRect.Left();
+ ++rPosRect.Right();
+ ++nField;
+ }
+ }
+
+ rOrient = sheet::DataPilotFieldOrientation_ROW;
+ rDimPos = nField; //!...
+ return TRUE;
+ }
+
+ // test for page fields
+
+ SCROW nPageStartRow = aStartPos.Row() + ( bDoFilter ? 1 : 0 );
+ if ( nCol >= aStartPos.Col() && nCol <= nTabEndCol &&
+ nRow + 1 >= nPageStartRow && nRow < nPageStartRow + nPageFieldCount )
+ {
+ long nField = nRow - nPageStartRow;
+ if (nField < 0)
+ {
+ nField = 0;
+ bMouseTop = TRUE;
+ }
+ //! find start of dimension
+
+ rPosRect = Rectangle( aStartPos.Col(), nPageStartRow + nField,
+ nTabEndCol, nPageStartRow + nField - 1 );
+
+ BOOL bFound = FALSE; // is this within the same orientation?
+ BOOL bBeforeDrag = FALSE;
+ BOOL bAfterDrag = FALSE;
+ for (long nPos=0; nPos<nPageFieldCount && !bFound; nPos++)
+ {
+ if (pPageFields[nPos].nDim == nDragDim)
+ {
+ bFound = TRUE;
+ if ( nField < nPos )
+ bBeforeDrag = TRUE;
+ else if ( nField > nPos )
+ bAfterDrag = TRUE;
+ }
+ }
+
+ if ( bFound )
+ {
+ if (!bBeforeDrag)
+ {
+ ++rPosRect.Bottom();
+ if (bAfterDrag)
+ ++rPosRect.Top();
+ }
+ }
+ else
+ {
+ if ( !bMouseTop )
+ {
+ ++rPosRect.Top();
+ ++rPosRect.Bottom();
+ ++nField;
+ }
+ }
+
+ rOrient = sheet::DataPilotFieldOrientation_PAGE;
+ rDimPos = nField; //!...
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx
new file mode 100644
index 000000000000..fd9bee0ed572
--- /dev/null
+++ b/sc/source/core/data/dpoutputgeometry.cxx
@@ -0,0 +1,214 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpoutputgeometry.hxx"
+#include "address.hxx"
+
+#include <vector>
+
+using ::std::vector;
+
+ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType) :
+ maOutRange(rOutRange),
+ mnRowFields(0),
+ mnColumnFields(0),
+ mnPageFields(0),
+ mnDataFields(0),
+ meImportType(eImportType),
+ mbShowFilter(bShowFilter)
+{
+}
+
+ScDPOutputGeometry::~ScDPOutputGeometry()
+{
+}
+
+void ScDPOutputGeometry::setRowFieldCount(sal_uInt32 nCount)
+{
+ mnRowFields = nCount;
+}
+
+void ScDPOutputGeometry::setColumnFieldCount(sal_uInt32 nCount)
+{
+ mnColumnFields = nCount;
+}
+
+void ScDPOutputGeometry::setPageFieldCount(sal_uInt32 nCount)
+{
+ mnPageFields = nCount;
+}
+
+void ScDPOutputGeometry::setDataFieldCount(sal_uInt32 nCount)
+{
+ mnDataFields = nCount;
+}
+
+void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnColumnFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ bool bDataLayout = mnDataFields > 1;
+
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ SCROW nRow = nCurRow;
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0));
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
+
+ for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnRowFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ SCROW nRow = getRowFieldHeaderRow();
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nColStart = maOutRange.aStart.Col();
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
+
+ for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+void ScDPOutputGeometry::getPageFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnPageFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nCol = maOutRange.aStart.Col();
+
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+
+ for (SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const
+{
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ if (mnColumnFields)
+ nCurRow += static_cast<SCROW>(mnColumnFields);
+ else if (mnRowFields)
+ ++nCurRow;
+
+ return nCurRow;
+}
+
+ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const
+{
+ // We will ignore the table position for now.
+
+ bool bExtraTitleRow = (mnColumnFields == 0 && meImportType == ScDPOutputGeometry::XLS);
+ bool bDataLayout = mnDataFields > 1;
+
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCCOL nCol = maOutRange.aStart.Col();
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ if (rPos.Col() == nCol && nRowStart <= rPos.Row() && rPos.Row() <= nRowEnd)
+ return Page;
+
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ if (mnColumnFields)
+ {
+ SCROW nRow = nCurRow;
+ SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0));
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
+ if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
+ return Column;
+
+ nCurRow += static_cast<SCROW>(mnColumnFields);
+ }
+
+ if (bExtraTitleRow)
+ ++nCurRow;
+
+ if (mnRowFields)
+ {
+ SCCOL nColStart = maOutRange.aStart.Col();
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
+ if (rPos.Row() == nCurRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
+ return Row;
+ }
+
+ return None;
+}
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
new file mode 100644
index 000000000000..bad05968bf72
--- /dev/null
+++ b/sc/source/core/data/dpsave.cxx
@@ -0,0 +1,1480 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "miscuno.hxx"
+#include "scerrors.hxx"
+#include "unonames.hxx"
+#include "global.hxx"
+
+#include <tools/debug.hxx>
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/TableFilterField.hpp>
+#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
+#include <com/sun/star/sheet/XLevelsSupplier.hpp>
+#include <com/sun/star/sheet/XMembersSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+#include "dptabsrc.hxx"
+#include "dpglobal.hxx"
+using namespace ScDPGlobal;
+#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCETYPE_HPP_
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCEITEMTYPE_HPP_
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#endif
+using namespace com::sun::star::sheet;
+// End Comments
+
+#include <hash_map>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::std::hash_map;
+using ::std::auto_ptr;
+
+// -----------------------------------------------------------------------
+
+#define SC_DPSAVEMODE_NO 0
+#define SC_DPSAVEMODE_YES 1
+#define SC_DPSAVEMODE_DONTKNOW 2
+
+// -----------------------------------------------------------------------
+
+void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
+ const rtl::OUString& rName, sal_Bool bValue )
+{
+ //! move to ScUnoHelpFunctions?
+
+ xProp->setPropertyValue( rName, uno::Any( &bValue, getBooleanCppuType() ) );
+}
+
+// -----------------------------------------------------------------------
+
+ScDPSaveMember::ScDPSaveMember(const String& rName) :
+ aName( rName ),
+ mpLayoutName(NULL),
+ nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
+ nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
+{
+}
+
+ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
+ aName( r.aName ),
+ mpLayoutName(NULL),
+ nVisibleMode( r.nVisibleMode ),
+ nShowDetailsMode( r.nShowDetailsMode )
+{
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
+}
+
+ScDPSaveMember::~ScDPSaveMember()
+{
+}
+
+BOOL ScDPSaveMember::operator== ( const ScDPSaveMember& r ) const
+{
+ if ( aName != r.aName ||
+ nVisibleMode != r.nVisibleMode ||
+ nShowDetailsMode != r.nShowDetailsMode )
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL ScDPSaveMember::HasIsVisible() const
+{
+ return nVisibleMode != SC_DPSAVEMODE_DONTKNOW;
+}
+
+void ScDPSaveMember::SetIsVisible(BOOL bSet)
+{
+ nVisibleMode = bSet;
+}
+
+BOOL ScDPSaveMember::HasShowDetails() const
+{
+ return nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW;
+}
+
+void ScDPSaveMember::SetShowDetails(BOOL bSet)
+{
+ nShowDetailsMode = bSet;
+}
+
+void ScDPSaveMember::SetName( const String& rNew )
+{
+ // Used only if the source member was renamed (groups).
+ // For UI renaming of members, a layout name must be used.
+
+ aName = rNew;
+}
+
+void ScDPSaveMember::SetLayoutName( const OUString& rName )
+{
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+void ScDPSaveMember::RemoveLayoutName()
+{
+ mpLayoutName.reset(NULL);
+}
+
+void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
+{
+ uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
+ DBG_ASSERT( xMembProp.is(), "no properties at member" );
+ if ( xMembProp.is() )
+ {
+ // exceptions are caught at ScDPSaveData::WriteToSource
+
+ if ( nVisibleMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xMembProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISVISIBLE), (BOOL)nVisibleMode );
+
+ if ( nShowDetailsMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xMembProp,
+ rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode );
+
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
+ if ( nPosition >= 0 )
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
+ aName( rName ),
+ pSelectedPage( NULL ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
+ bIsDataLayout( bDataLayout ),
+ bDupFlag( FALSE ),
+ nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
+ nFunction( sheet::GeneralFunction_AUTO ),
+ nUsedHierarchy( -1 ),
+ nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
+ bSubTotalDefault( TRUE ),
+ nSubTotalCount( 0 ),
+ pSubTotalFuncs( NULL ),
+ pReferenceValue( NULL ),
+ pSortInfo( NULL ),
+ pAutoShowInfo( NULL ),
+ pLayoutInfo( NULL )
+{
+}
+
+ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
+ aName( r.aName ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
+ bIsDataLayout( r.bIsDataLayout ),
+ bDupFlag( r.bDupFlag ),
+ nOrientation( r.nOrientation ),
+ nFunction( r.nFunction ),
+ nUsedHierarchy( r.nUsedHierarchy ),
+ nShowEmptyMode( r.nShowEmptyMode ),
+ bSubTotalDefault( r.bSubTotalDefault ),
+ nSubTotalCount( r.nSubTotalCount ),
+ pSubTotalFuncs( NULL )
+{
+ if ( nSubTotalCount && r.pSubTotalFuncs )
+ {
+ pSubTotalFuncs = new USHORT[nSubTotalCount];
+ for (long nSub=0; nSub<nSubTotalCount; nSub++)
+ pSubTotalFuncs[nSub] = r.pSubTotalFuncs[nSub];
+ }
+
+ for (MemberList::const_iterator i=r.maMemberList.begin(); i != r.maMemberList.end() ; i++)
+ {
+ const String& rName = (*i)->GetName();
+ ScDPSaveMember* pNew = new ScDPSaveMember( **i );
+ maMemberHash[rName] = pNew;
+ maMemberList.push_back( pNew );
+ }
+ if (r.pReferenceValue)
+ pReferenceValue = new sheet::DataPilotFieldReference( *(r.pReferenceValue) );
+ else
+ pReferenceValue = NULL;
+ if (r.pSortInfo)
+ pSortInfo = new sheet::DataPilotFieldSortInfo( *(r.pSortInfo) );
+ else
+ pSortInfo = NULL;
+ if (r.pAutoShowInfo)
+ pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo( *(r.pAutoShowInfo) );
+ else
+ pAutoShowInfo = NULL;
+ if (r.pLayoutInfo)
+ pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
+ else
+ pLayoutInfo = NULL;
+ if (r.pSelectedPage)
+ pSelectedPage = new String( *(r.pSelectedPage) );
+ else
+ pSelectedPage = NULL;
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
+ if (r.mpSubtotalName.get())
+ mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
+}
+
+ScDPSaveDimension::~ScDPSaveDimension()
+{
+ for (MemberHash::const_iterator i=maMemberHash.begin(); i != maMemberHash.end() ; i++)
+ delete i->second;
+ delete pReferenceValue;
+ delete pSortInfo;
+ delete pAutoShowInfo;
+ delete pLayoutInfo;
+ delete pSelectedPage;
+ delete [] pSubTotalFuncs;
+}
+
+BOOL ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const
+{
+ if ( aName != r.aName ||
+ bIsDataLayout != r.bIsDataLayout ||
+ bDupFlag != r.bDupFlag ||
+ nOrientation != r.nOrientation ||
+ nFunction != r.nFunction ||
+ nUsedHierarchy != r.nUsedHierarchy ||
+ nShowEmptyMode != r.nShowEmptyMode ||
+ bSubTotalDefault != r.bSubTotalDefault ||
+ nSubTotalCount != r.nSubTotalCount )
+ return FALSE;
+
+ if ( nSubTotalCount && ( !pSubTotalFuncs || !r.pSubTotalFuncs ) ) // should not happen
+ return FALSE;
+
+ long i;
+ for (i=0; i<nSubTotalCount; i++)
+ if ( pSubTotalFuncs[i] != r.pSubTotalFuncs[i] )
+ return FALSE;
+
+ if (maMemberHash.size() != r.maMemberHash.size() )
+ return FALSE;
+
+ MemberList::const_iterator a=maMemberList.begin();
+ MemberList::const_iterator b=r.maMemberList.begin();
+ for (; a != maMemberList.end() ; ++a, ++b)
+ if (!(**a == **b))
+ return FALSE;
+
+ if ( this->HasCurrentPage() && r.HasCurrentPage() )
+ {
+ if ( this->GetCurrentPage() != r.GetCurrentPage() )
+ {
+ return FALSE;
+ }
+ }
+ else if ( this->HasCurrentPage() || r.HasCurrentPage() )
+ {
+ return FALSE;
+ }
+ if( pReferenceValue && r.pReferenceValue )
+ {
+ if ( !(*pReferenceValue == *r.pReferenceValue) )
+ {
+ return FALSE;
+ }
+ }
+ else if ( pReferenceValue || r.pReferenceValue )
+ {
+ return FALSE;
+ }
+ if( this->pSortInfo && r.pSortInfo )
+ {
+ if ( !(*this->pSortInfo == *r.pSortInfo) )
+ {
+ return FALSE;
+ }
+ }
+ else if ( this->pSortInfo || r.pSortInfo )
+ {
+ return FALSE;
+ }
+ if( this->pAutoShowInfo && r.pAutoShowInfo )
+ {
+ if ( !(*this->pAutoShowInfo == *r.pAutoShowInfo) )
+ {
+ return FALSE;
+ }
+ }
+ else if ( this->pAutoShowInfo || r.pAutoShowInfo )
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void ScDPSaveDimension::AddMember(ScDPSaveMember* pMember)
+{
+ const String & rName = pMember->GetName();
+ MemberHash::iterator aExisting = maMemberHash.find( rName );
+ if ( aExisting == maMemberHash.end() )
+ {
+ std::pair< const String, ScDPSaveMember *> key( rName, pMember );
+ maMemberHash.insert ( key );
+ }
+ else
+ {
+ maMemberList.remove( aExisting->second );
+ delete aExisting->second;
+ aExisting->second = pMember;
+ }
+ maMemberList.push_back( pMember );
+}
+
+void ScDPSaveDimension::SetName( const String& rNew )
+{
+ // Used only if the source dim was renamed (groups).
+ // For UI renaming of dimensions, the layout name must be used.
+
+ aName = rNew;
+}
+
+void ScDPSaveDimension::SetOrientation(USHORT nNew)
+{
+ nOrientation = nNew;
+}
+
+void ScDPSaveDimension::SetSubTotals(long nCount, const USHORT* pFuncs)
+{
+ if (pSubTotalFuncs)
+ delete [] pSubTotalFuncs;
+ nSubTotalCount = nCount;
+ if ( nCount && pFuncs )
+ {
+ pSubTotalFuncs = new USHORT[nCount];
+ for (long i=0; i<nCount; i++)
+ pSubTotalFuncs[i] = pFuncs[i];
+ }
+ else
+ pSubTotalFuncs = NULL;
+
+ bSubTotalDefault = FALSE;
+}
+
+bool ScDPSaveDimension::HasShowEmpty() const
+{
+ return nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW;
+}
+
+void ScDPSaveDimension::SetShowEmpty(BOOL bSet)
+{
+ nShowEmptyMode = bSet;
+}
+
+void ScDPSaveDimension::SetFunction(USHORT nNew)
+{
+ nFunction = nNew;
+}
+
+void ScDPSaveDimension::SetUsedHierarchy(long nNew)
+{
+ nUsedHierarchy = nNew;
+}
+
+void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
+{
+ mpSubtotalName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveDimension::GetSubtotalName() const
+{
+ return mpSubtotalName.get();
+}
+
+bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
+{
+ MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pMem = *itr;
+ if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
+ return true;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
+ return true;
+ }
+ return false;
+}
+
+void ScDPSaveDimension::SetLayoutName(const OUString& rName)
+{
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+void ScDPSaveDimension::RemoveLayoutName()
+{
+ mpLayoutName.reset(NULL);
+}
+
+void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
+{
+ delete pReferenceValue;
+ if (pNew)
+ pReferenceValue = new sheet::DataPilotFieldReference(*pNew);
+ else
+ pReferenceValue = NULL;
+}
+
+void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo* pNew)
+{
+ delete pSortInfo;
+ if (pNew)
+ pSortInfo = new sheet::DataPilotFieldSortInfo(*pNew);
+ else
+ pSortInfo = NULL;
+}
+
+void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo* pNew)
+{
+ delete pAutoShowInfo;
+ if (pNew)
+ pAutoShowInfo = new sheet::DataPilotFieldAutoShowInfo(*pNew);
+ else
+ pAutoShowInfo = NULL;
+}
+
+void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo* pNew)
+{
+ delete pLayoutInfo;
+ if (pNew)
+ pLayoutInfo = new sheet::DataPilotFieldLayoutInfo(*pNew);
+ else
+ pLayoutInfo = NULL;
+}
+
+void ScDPSaveDimension::SetCurrentPage( const String* pPage )
+{
+ delete pSelectedPage;
+ if (pPage)
+ pSelectedPage = new String( *pPage );
+ else
+ pSelectedPage = NULL;
+}
+
+BOOL ScDPSaveDimension::HasCurrentPage() const
+{
+ return ( pSelectedPage != NULL );
+}
+
+const String& ScDPSaveDimension::GetCurrentPage() const
+{
+ if (pSelectedPage)
+ return *pSelectedPage;
+ return EMPTY_STRING;
+}
+
+ScDPSaveMember* ScDPSaveDimension::GetExistingMemberByName(const String& rName)
+{
+ MemberHash::const_iterator res = maMemberHash.find (rName);
+ if (res != maMemberHash.end())
+ return res->second;
+ return NULL;
+}
+
+
+ScDPSaveMember* ScDPSaveDimension::GetMemberByName(const String& rName)
+{
+ MemberHash::const_iterator res = maMemberHash.find (rName);
+ if (res != maMemberHash.end())
+ return res->second;
+
+ ScDPSaveMember* pNew = new ScDPSaveMember( rName );
+ maMemberHash[rName] = pNew;
+ maMemberList.push_back( pNew );
+ return pNew;
+}
+
+void ScDPSaveDimension::SetMemberPosition( const String& rName, sal_Int32 nNewPos )
+{
+ ScDPSaveMember* pMember = GetMemberByName( rName ); // make sure it exists and is in the hash
+
+ maMemberList.remove( pMember );
+
+ MemberList::iterator aIter = maMemberList.begin();
+ for (sal_Int32 i=0; i<nNewPos && aIter != maMemberList.end(); i++)
+ ++aIter;
+ maMemberList.insert( aIter, pMember );
+}
+
+void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xDim )
+{
+ uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
+ DBG_ASSERT( xDimProp.is(), "no properties at dimension" );
+ if ( xDimProp.is() )
+ {
+ // exceptions are caught at ScDPSaveData::WriteToSource
+ uno::Any aAny;
+
+ sheet::DataPilotFieldOrientation eOrient = (sheet::DataPilotFieldOrientation)nOrientation;
+ aAny <<= eOrient;
+ xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_ORIENTATION), aAny );
+
+ sheet::GeneralFunction eFunc = (sheet::GeneralFunction)nFunction;
+ aAny <<= eFunc;
+ xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FUNCTION), aAny );
+
+ if ( nUsedHierarchy >= 0 )
+ {
+ aAny <<= (INT32)nUsedHierarchy;
+ xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY), aAny );
+ }
+
+ if ( pReferenceValue )
+ {
+ aAny <<= *pReferenceValue;
+ xDimProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_REFVALUE), aAny );
+ }
+
+ uno::Sequence<sheet::TableFilterField> aFilter;
+ // set the selected page field only if the dimension is used as page dimension
+ if ( pSelectedPage && nOrientation == sheet::DataPilotFieldOrientation_PAGE )
+ {
+ // single filter field: first field equal to selected string
+ sheet::TableFilterField aField( sheet::FilterConnection_AND, 0,
+ sheet::FilterOperator_EQUAL, sal_False, 0.0, *pSelectedPage );
+ aFilter = uno::Sequence<sheet::TableFilterField>( &aField, 1 );
+ }
+ // else keep empty sequence
+
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter);
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
+ const OUString* pSubTotalName = GetSubtotalName();
+ if (pSubTotalName)
+ // Custom subtotal name, with '?' being replaced by the visible field name later.
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_FIELD_SUBTOTALNAME, *pSubTotalName);
+ }
+
+ // Level loop outside of maMemberList loop
+ // because SubTotals have to be set independently of known members
+
+ long nCount = maMemberHash.size();
+
+ long nHierCount = 0;
+ uno::Reference<container::XIndexAccess> xHiers;
+ uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
+ if ( xHierSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
+ xHiers = new ScNameToIndexAccess( xHiersName );
+ nHierCount = xHiers->getCount();
+ }
+
+ sal_Bool bHasHiddenMember = false;
+
+ for (long nHier=0; nHier<nHierCount; nHier++)
+ {
+ uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
+
+ long nLevCount = 0;
+ uno::Reference<container::XIndexAccess> xLevels;
+ uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHierarchy, uno::UNO_QUERY );
+ if ( xLevSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xLevelsName = xLevSupp->getLevels();
+ xLevels = new ScNameToIndexAccess( xLevelsName );
+ nLevCount = xLevels->getCount();
+ }
+
+ for (long nLev=0; nLev<nLevCount; nLev++)
+ {
+ uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLev) );
+ uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
+ DBG_ASSERT( xLevProp.is(), "no properties at level" );
+ if ( xLevProp.is() )
+ {
+ uno::Any aAny;
+ if ( !bSubTotalDefault )
+ {
+ if ( !pSubTotalFuncs )
+ nSubTotalCount = 0;
+
+ uno::Sequence<sheet::GeneralFunction> aSeq(nSubTotalCount);
+ sheet::GeneralFunction* pArray = aSeq.getArray();
+ for (long i=0; i<nSubTotalCount; i++)
+ pArray[i] = (sheet::GeneralFunction)pSubTotalFuncs[i];
+ aAny <<= aSeq;
+ xLevProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS), aAny );
+ }
+ if ( nShowEmptyMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xLevProp,
+ rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode );
+
+ if ( pSortInfo )
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo);
+
+ if ( pAutoShowInfo )
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo);
+
+ if ( pLayoutInfo )
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo);
+
+ // exceptions are caught at ScDPSaveData::WriteToSource
+ }
+
+ if ( nCount > 0 )
+ {
+ uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevel, uno::UNO_QUERY );
+ if ( xMembSupp.is() )
+ {
+ uno::Reference<container::XNameAccess> xMembers = xMembSupp->getMembers();
+ if ( xMembers.is() )
+ {
+ sal_Int32 nPosition = -1; // set position only in manual mode
+ if ( !pSortInfo || pSortInfo->Mode == sheet::DataPilotFieldSortMode::MANUAL )
+ nPosition = 0;
+
+ for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; i++)
+ {
+ ScDPSaveMember* pMember = *i;
+ if (!pMember->GetIsVisible())
+ bHasHiddenMember = true;
+ rtl::OUString aMemberName = pMember->GetName();
+ if ( xMembers->hasByName( aMemberName ) )
+ {
+ uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
+ xMembers->getByName( aMemberName ) );
+ pMember->WriteToSource( xMemberInt, nPosition );
+
+ if ( nPosition >= 0 )
+ ++nPosition; // increase if initialized
+ }
+ // missing member is no error
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (xDimProp.is())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_HAS_HIDDEN_MEMBER, bHasHiddenMember);
+}
+
+void ScDPSaveDimension::UpdateMemberVisibility(const hash_map<OUString, bool, OUStringHash>& rData)
+{
+ typedef hash_map<OUString, bool, OUStringHash> DataMap;
+ MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ ScDPSaveMember* pMem = *itrMem;
+ const String& rMemName = pMem->GetName();
+ DataMap::const_iterator itr = rData.find(rMemName);
+ if (itr != rData.end())
+ pMem->SetIsVisible(itr->second);
+ }
+}
+
+bool ScDPSaveDimension::HasInvisibleMember() const
+{
+ MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ const ScDPSaveMember* pMem = *itrMem;
+ if (!pMem->GetIsVisible())
+ return true;
+ }
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+ScDPSaveData::ScDPSaveData() :
+ pDimensionData( NULL ),
+ nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW ),
+ nRowGrandMode( SC_DPSAVEMODE_DONTKNOW ),
+ nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
+ nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
+ bFilterButton( TRUE ),
+ bDrillDown( TRUE ),
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ mnCacheId( -1),
+ // End Comments
+ mbDimensionMembersBuilt(false),
+ mpGrandTotalName(NULL)
+{
+}
+
+ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
+ nColumnGrandMode( r.nColumnGrandMode ),
+ nRowGrandMode( r.nRowGrandMode ),
+ nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
+ nRepeatEmptyMode( r.nRepeatEmptyMode ),
+ bFilterButton( r.bFilterButton ),
+ bDrillDown( r.bDrillDown ),
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ mnCacheId( r.mnCacheId ),
+ // End Comments
+ mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
+ mpGrandTotalName(NULL)
+{
+ if ( r.pDimensionData )
+ pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
+ else
+ pDimensionData = NULL;
+
+ long nCount = r.aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
+ aDimList.Insert( pNew, LIST_APPEND );
+ }
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
+}
+
+ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
+{
+ if ( &r != this )
+ {
+ // Wang Xu Ming -- 2009-8-17
+ // DataPilot Migration - Cache&&Performance
+ this->~ScDPSaveData();
+ new( this ) ScDPSaveData ( r );
+ // End Comments
+ }
+ return *this;
+}
+
+BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
+{
+ if ( nColumnGrandMode != r.nColumnGrandMode ||
+ nRowGrandMode != r.nRowGrandMode ||
+ nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
+ nRepeatEmptyMode != r.nRepeatEmptyMode ||
+ bFilterButton != r.bFilterButton ||
+ mnCacheId != r.mnCacheId ||/// Wang Xu Ming -- 2009-6-18 DataPilot Migration
+ bDrillDown != r.bDrillDown ||
+ mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
+ return FALSE;
+
+ if ( pDimensionData || r.pDimensionData )
+ if ( !pDimensionData || !r.pDimensionData || !( *pDimensionData == *r.pDimensionData ) )
+ return FALSE;
+
+ ULONG nCount = aDimList.Count();
+ if ( nCount != r.aDimList.Count() )
+ return FALSE;
+
+ for (ULONG i=0; i<nCount; i++)
+ if ( !( *(ScDPSaveDimension*)aDimList.GetObject(i) ==
+ *(ScDPSaveDimension*)r.aDimList.GetObject(i) ) )
+ return FALSE;
+
+ if (mpGrandTotalName.get())
+ {
+ if (!r.mpGrandTotalName.get())
+ return false;
+ if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
+ return false;
+ }
+ else if (r.mpGrandTotalName.get())
+ return false;
+
+ return TRUE;
+}
+
+ScDPSaveData::~ScDPSaveData()
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ delete (ScDPSaveDimension*)aDimList.GetObject(i);
+ aDimList.Clear();
+
+ delete pDimensionData;
+}
+
+void ScDPSaveData::SetGrandTotalName(const OUString& rName)
+{
+ mpGrandTotalName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveData::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
+ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ if ( pDim->GetName() == rName && !pDim->IsDataLayout() )
+ return pDim;
+ }
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, FALSE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ if ( pDim->GetName() == rName && !pDim->IsDataLayout() )
+ return pDim;
+ }
+ return NULL; // don't create new
+}
+
+ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName)
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ if ( pDim->GetName() == rName && !pDim->IsDataLayout() )
+ return DuplicateDimension(rName);
+ }
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, FALSE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
+{
+ ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
+ if (pDim)
+ return pDim;
+
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ if ( pDim->IsDataLayout() )
+ return pDim;
+ }
+ return NULL;
+}
+
+ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName)
+{
+ // always insert new
+ //! check if dimension is there?
+
+ ScDPSaveDimension* pOld = GetDimensionByName( rName );
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
+ pNew->SetDupFlag( TRUE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+void ScDPSaveData::RemoveDimensionByName(const String& rName)
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ if ( pDim->GetName() == rName && !pDim->IsDataLayout() )
+ {
+ delete pDim;
+ aDimList.Remove(i);
+ break;
+ }
+ }
+}
+
+ScDPSaveDimension& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension& rDim )
+{
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim );
+ pNew->SetDupFlag( TRUE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return *pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation)
+{
+ // return the innermost dimension for the given orientation,
+ // excluding data layout dimension
+
+ ScDPSaveDimension* pInner = NULL;
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ if ( pDim->GetOrientation() == nOrientation && !pDim->IsDataLayout() )
+ pInner = pDim;
+ }
+ return pInner; // the last matching one
+}
+
+ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
+{
+ long nCount = aDimList.Count();
+ for (long i = 0; i < nCount; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout())
+ return pDim;
+ }
+ return NULL;
+}
+
+long ScDPSaveData::GetDataDimensionCount() const
+{
+ long nDataCount = 0;
+
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ const ScDPSaveDimension* pDim = static_cast<const ScDPSaveDimension*>(aDimList.GetObject(i));
+ if ( pDim->GetOrientation() == sheet::DataPilotFieldOrientation_DATA )
+ ++nDataCount;
+ }
+
+ return nDataCount;
+}
+
+void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
+{
+ // position (nNew) is counted within dimensions of the same orientation
+
+ USHORT nOrient = pDim->GetOrientation();
+
+ aDimList.Remove( pDim );
+ ULONG nCount = aDimList.Count(); // after remove
+
+ ULONG nInsPos = 0;
+ while ( nNew > 0 && nInsPos < nCount )
+ {
+ if ( ((ScDPSaveDimension*)aDimList.GetObject(nInsPos))->GetOrientation() == nOrient )
+ --nNew;
+ ++nInsPos;
+ }
+
+ aDimList.Insert( pDim, nInsPos );
+}
+
+void ScDPSaveData::SetColumnGrand(BOOL bSet)
+{
+ nColumnGrandMode = bSet;
+}
+
+void ScDPSaveData::SetRowGrand(BOOL bSet)
+{
+ nRowGrandMode = bSet;
+}
+
+void ScDPSaveData::SetIgnoreEmptyRows(BOOL bSet)
+{
+ nIgnoreEmptyMode = bSet;
+}
+
+void ScDPSaveData::SetRepeatIfEmpty(BOOL bSet)
+{
+ nRepeatEmptyMode = bSet;
+}
+
+void ScDPSaveData::SetFilterButton(BOOL bSet)
+{
+ bFilterButton = bSet;
+}
+
+void ScDPSaveData::SetDrillDown(BOOL bSet)
+{
+ bDrillDown = bSet;
+}
+
+void lcl_ResetOrient( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
+{
+ sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ long nIntCount = xIntDims->getCount();
+ for (long nIntDim=0; nIntDim<nIntCount; nIntDim++)
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+ if (xDimProp.is())
+ {
+ uno::Any aAny;
+ aAny <<= eOrient;
+ xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_ORIENTATION), aAny );
+ }
+ }
+}
+
+void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
+{
+ if (!xSource.is())
+ return;
+
+ // source options must be first!
+
+ uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
+ DBG_ASSERT( xSourceProp.is(), "no properties at source" );
+ if ( xSourceProp.is() )
+ {
+ // source options are not available for external sources
+ //! use XPropertySetInfo to test for availability?
+
+ try
+ {
+ if ( nIgnoreEmptyMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xSourceProp,
+ rtl::OUString::createFromAscii(DP_PROP_IGNOREEMPTY), (BOOL)nIgnoreEmptyMode );
+ if ( nRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xSourceProp,
+ rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY), (BOOL)nRepeatEmptyMode );
+ }
+ catch(uno::Exception&)
+ {
+ // no error
+ }
+
+ const OUString* pGrandTotalName = GetGrandTotalName();
+ if (pGrandTotalName)
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_GRANDTOTAL_NAME, *pGrandTotalName);
+ }
+
+ // exceptions in the other calls are errors
+ try
+ {
+ // reset all orientations
+ //! "forgetSettings" or similar at source ?????
+ //! reset all duplicated dimensions, or reuse them below !!!
+ DBG_TRACE( "ScDPSaveData::WriteToSource" );
+
+ lcl_ResetOrient( xSource );
+
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ rtl::OUString aName = pDim->GetName();
+
+ DBG_TRACESTR(pDim->GetName());
+
+ BOOL bData = pDim->IsDataLayout();
+
+ //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
+
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ long nIntCount = xIntDims->getCount();
+ BOOL bFound = FALSE;
+ for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
+ if ( bData )
+ {
+ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
+ if ( xDimProp.is() )
+ {
+ bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
+ rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ //! error checking -- is "IsDataLayoutDimension" property required??
+ }
+ }
+ else
+ {
+ uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
+ if ( xDimName.is() && xDimName->getName() == aName )
+ bFound = TRUE;
+ }
+
+ if ( bFound )
+ {
+ if ( pDim->GetDupFlag() )
+ {
+ String aNewName = pDim->GetName();
+
+ // different name for each duplication of a (real) dimension...
+ for (long j=0; j<=i; j++) //! Test !!!!!!
+ aNewName += '*'; //! modify name at creation of SaveDimension
+
+ uno::Reference<util::XCloneable> xCloneable( xIntDim, uno::UNO_QUERY );
+ DBG_ASSERT( xCloneable.is(), "cannot clone dimension" );
+ if (xCloneable.is())
+ {
+ uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
+ uno::Reference<container::XNamed> xNewName( xNew, uno::UNO_QUERY );
+ if (xNewName.is())
+ {
+ xNewName->setName( aNewName );
+ pDim->WriteToSource( xNew );
+ }
+ }
+ }
+ else
+ pDim->WriteToSource( xIntDim );
+ }
+ }
+ DBG_ASSERT(bFound, "WriteToSource: Dimension not found");
+ }
+
+ if ( xSourceProp.is() )
+ {
+ if ( nColumnGrandMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xSourceProp,
+ rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND), (BOOL)nColumnGrandMode );
+ if ( nRowGrandMode != SC_DPSAVEMODE_DONTKNOW )
+ lcl_SetBoolProperty( xSourceProp,
+ rtl::OUString::createFromAscii(DP_PROP_ROWGRAND), (BOOL)nRowGrandMode );
+ }
+ }
+ catch(uno::Exception&)
+ {
+ DBG_ERROR("exception in WriteToSource");
+ }
+}
+
+BOOL ScDPSaveData::IsEmpty() const
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+ if ( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !pDim->IsDataLayout() )
+ return FALSE;
+ }
+ return TRUE; // no entries that are not hidden
+}
+
+ScDPDimensionSaveData* ScDPSaveData::GetDimensionData()
+{
+ if (!pDimensionData)
+ pDimensionData = new ScDPDimensionSaveData;
+ return pDimensionData;
+}
+
+void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
+{
+ delete pDimensionData;
+ if ( pNew )
+ pDimensionData = new ScDPDimensionSaveData( *pNew );
+ else
+ pDimensionData = NULL;
+}
+
+void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
+{
+ if (mbDimensionMembersBuilt)
+ return;
+
+ // First, build a dimension name-to-index map.
+ typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
+ NameIndexMap aMap;
+ long nColCount = pData->GetColumnCount();
+ for (long i = 0; i < nColCount; ++i)
+ aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
+
+ NameIndexMap::const_iterator itrEnd = aMap.end();
+
+ sal_uInt32 n = aDimList.Count();
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ const String& rDimName = pDim->GetName();
+ if (!rDimName.Len())
+ // empty dimension name. It must be data layout.
+ continue;
+
+ NameIndexMap::const_iterator itr = aMap.find(rDimName);
+ if (itr == itrEnd)
+ // dimension name not in the data. This should never happen!
+ continue;
+
+ long nDimIndex = itr->second;
+ const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
+ size_t mMemberCount = rMembers.size();
+ for (size_t j = 0; j < mMemberCount; ++j)
+ {
+ const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
+ String aMemName = pMemberData->GetString();
+ if (pDim->GetExistingMemberByName(aMemName))
+ // this member instance already exists. nothing to do.
+ continue;
+
+ auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
+ pNewMember->SetIsVisible(true);
+ pDim->AddMember(pNewMember.release());
+ }
+ }
+
+ mbDimensionMembersBuilt = true;
+}
+
+bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
+{
+ ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
+ if (!pDim)
+ return false;
+
+ return pDim->HasInvisibleMember();
+}
+
+void ScDPSaveData::Refresh( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
+{
+ try
+ {
+ long nCount = aDimList.Count();
+ std::list<String> deletedDims;
+ for (long i=nCount-1; i >=0 ; i--)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+
+ rtl::OUString aName = pDim->GetName();
+ if ( pDim->IsDataLayout() )
+ continue;
+
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
+ long nIntCount = xIntDims->getCount();
+ BOOL bFound = FALSE;
+ for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
+ {
+ uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
+ uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
+ if ( xDimName.is() && xDimName->getName() == aName )
+ bFound = TRUE;
+ }
+ if ( !bFound )
+ {
+ deletedDims.push_back( aName );
+ aDimList.Remove(i);
+ DBG_TRACE( "\n Remove dim: \t" );
+ DBG_TRACESTR( String( aName ) );
+ }
+
+ }
+
+ nCount = aDimList.Count();
+ for (long i=nCount-1; i >=0 ; i--) //check every dimension ??
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
+
+ rtl::OUString aName = pDim->GetName();
+ if ( pDim->IsDataLayout() )
+ continue;
+ pDim->Refresh( xSource, deletedDims );
+
+ }
+
+ mbDimensionMembersBuilt = false; // there may be new members
+ }
+ catch(uno::Exception&)
+ {
+ DBG_ERROR("error in ScDPSaveData::Refresh");
+ }
+
+}
+void ScDPSaveDimension::Refresh( const com::sun::star::uno::Reference<
+ com::sun::star::sheet::XDimensionsSupplier>& xSource ,
+ const std::list<String>& deletedDims)
+{
+ if ( xSource.is() )
+ {
+ ScDPSource* pTabSource = static_cast<ScDPSource*>( xSource.get() );
+ ScDPTableDataCache* pCache = pTabSource->GetCache();
+ if ( pCache->GetId() == -1 )
+ return;
+
+ SCCOL nSrcDim = pCache->GetDimensionIndex( GetName() );
+
+ if ( nSrcDim == -1 )
+ return;
+ if ( pSelectedPage )
+ {//check pSelected page
+ DBG_TRACESTR( (*pSelectedPage) );
+ if ( pCache->GetIdByItemData( nSrcDim, *pSelectedPage ) == -1 )
+ {
+ delete pSelectedPage;
+ pSelectedPage = NULL;
+ }
+
+ };
+
+ if ( pReferenceValue && pReferenceValue->ReferenceItemType == DataPilotFieldReferenceItemType::NAMED )
+ {//check pReferenceValue
+#ifdef DEBUG
+ switch( pReferenceValue->ReferenceType)
+ {
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: //both
+ DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE \n" );
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE: //both
+ DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE \n" );
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: //both
+ DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE \n" );
+ break;
+ case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL:
+ DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::RUNNING_TOTAL \n" ); //enable name
+ break;
+ }
+#endif
+ switch( pReferenceValue->ReferenceType)
+ {
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE:
+ case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE:
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
+ case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL:
+ {
+ if( pReferenceValue->ReferenceItemType == DataPilotFieldReferenceItemType::NAMED )
+ {
+ const String& sReferenceFieldName = pReferenceValue->ReferenceField;
+ DBG_TRACESTR( sReferenceFieldName );
+ SCCOL nRefDim = pCache->GetDimensionIndex( sReferenceFieldName );
+ bool bValid = true;
+ if ( nRefDim == -1 )
+ bValid = false;
+ else if ( pReferenceValue->ReferenceType != sheet::DataPilotFieldReferenceType::RUNNING_TOTAL )
+ { //running total has not reference item
+ const String& sReferenceItemName = pReferenceValue->ReferenceItemName;
+ DBG_TRACESTR( sReferenceItemName );
+ if ( pCache->GetIdByItemData( nRefDim, sReferenceItemName ) == -1 )
+ bValid = false;
+ }
+ if ( !bValid )
+ {
+ delete pReferenceValue;
+ pReferenceValue = NULL;
+ }
+ }
+ }
+ break;
+ }
+
+ };
+
+ if ( pSortInfo )
+ { //check sortinfo
+ if ( pSortInfo->Mode == DataPilotFieldSortMode::DATA )
+ {
+ DBG_TRACE( "\n DataPilotFieldSortMode::DATA \n" );
+ const String& sFieldDimName = pSortInfo->Field;
+ std::list<String>::const_iterator iter = std::find( deletedDims.begin(), deletedDims.end(), sFieldDimName );
+ if ( iter != deletedDims.end() && pCache->GetDimensionIndex( sFieldDimName ) == -1 )
+ {
+ pSortInfo->Mode = DataPilotFieldSortMode::MANUAL;
+ pSortInfo->Field = GetName();
+ }
+ }
+
+ };
+
+ if ( pAutoShowInfo )
+ { //check autoshow
+ const String& sFieldDimName = pAutoShowInfo->DataField;
+ std::list<String>::const_iterator iter = std::find( deletedDims.begin(), deletedDims.end(), sFieldDimName );
+ if ( iter != deletedDims.end() && pCache->GetDimensionIndex( sFieldDimName ) == -1 )
+ {
+ delete pAutoShowInfo;
+ pAutoShowInfo = NULL;
+ }
+
+ };
+
+ //remove unused members
+ //SODC_19124
+ for (MemberList::iterator i=maMemberList.begin(); i != maMemberList.end() ; )
+ {
+ rtl::OUString aMemberName = (*i)->GetName();
+ if ( pCache->GetIdByItemData( nSrcDim, aMemberName ) == -1 )
+ i = maMemberList.erase( i );
+ else
+ i++;
+ }
+ }
+}
+// End Comments
+bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r )
+{
+ return l.Field == r.Field && l.IsAscending == r.IsAscending && l.Mode == r.Mode;
+}
+bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r )
+{
+ return l.IsEnabled == r.IsEnabled &&
+ l.ShowItemsMode == r.ShowItemsMode &&
+ l.ItemCount == r.ItemCount &&
+ l.DataField == r.DataField;
+}
+bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r )
+{
+ return l.ReferenceType == r.ReferenceType &&
+ l.ReferenceField == r.ReferenceField &&
+ l.ReferenceItemType == r.ReferenceItemType &&
+ l.ReferenceItemName == r.ReferenceItemName;
+}
+
diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx
new file mode 100644
index 000000000000..b966d9d458ea
--- /dev/null
+++ b/sc/source/core/data/dpsdbtab.cxx
@@ -0,0 +1,312 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/zforlist.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/types.hxx>
+
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/XCompletedExecution.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include "dpsdbtab.hxx"
+#include "collect.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "dpcachetable.hxx"
+#include "dptabres.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+
+using namespace com::sun::star;
+
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+
+#define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
+#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler"
+
+//! move to a header file?
+#define SC_DBPROP_DATASOURCENAME "DataSourceName"
+#define SC_DBPROP_COMMAND "Command"
+#define SC_DBPROP_COMMANDTYPE "CommandType"
+// -----------------------------------------------------------------------
+// Wang Xu Ming -- 2009-9-15
+// DataPilot Migration - Cache&&Performance
+ ScDPTableDataCache* ScImportSourceDesc::GetExistDPObjectCache( ScDocument* pDoc ) const
+{
+ ScDPTableDataCache* pCache = NULL;
+ ScDPCollection* pDPCollection= pDoc->GetDPCollection();
+ USHORT nCount = pDPCollection->GetCount();
+
+ for ( short i=nCount-1; i>=0 ; i--)
+ {
+ if ( const ScImportSourceDesc* pUsedDesc = (*pDPCollection)[i]->GetImportSourceDesc() )
+ if ( *this == *pUsedDesc )
+ {
+ long nID = (*pDPCollection)[i]->GetCacheId();
+ if ( nID >= 0 )
+ pCache= pDoc->GetDPObjectCache( nID );
+ if ( pCache )
+ return pCache;
+ }
+ }
+ return NULL;
+}
+
+ScDPTableDataCache* ScImportSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const
+{
+ if ( !pDoc )
+ return NULL;
+
+ sal_Int32 nSdbType = -1;
+
+ switch ( nType )
+ {
+ case sheet::DataImportMode_SQL: nSdbType = sdb::CommandType::COMMAND; break;
+ case sheet::DataImportMode_TABLE: nSdbType = sdb::CommandType::TABLE; break;
+ case sheet::DataImportMode_QUERY: nSdbType = sdb::CommandType::QUERY; break;
+ default:
+ return NULL;
+ }
+
+
+ ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc );
+
+ if ( pCache && ( nID < 0 || nID == pCache->GetId() ) )
+ return pCache;
+
+ if ( pCache == NULL )
+ pCache = new ScDPTableDataCache( pDoc );
+
+ uno::Reference<sdbc::XRowSet> xRowSet ;
+ try
+ {
+ xRowSet = uno::Reference<sdbc::XRowSet>(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
+ if ( xRowProp.is() )
+ {
+ //
+ // set source parameters
+ //
+ uno::Any aAny;
+ aAny <<= rtl::OUString( aDBName );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny );
+
+ aAny <<= rtl::OUString( aObject );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
+
+ aAny <<= nSdbType;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
+
+ uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
+ if ( xExecute.is() )
+ {
+ uno::Reference<task::XInteractionHandler> xHandler(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
+ uno::UNO_QUERY);
+ xExecute->executeWithCompletion( xHandler );
+ }
+ else
+ xRowSet->execute();
+ SvNumberFormatter aFormat( pDoc->GetServiceManager(), ScGlobal::eLnge);
+ pCache->InitFromDataBase( xRowSet, *aFormat.GetNullDate() );
+ pCache->SetId( nID );
+ pDoc->AddDPObjectCache( pCache );
+ DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() );
+ }
+ }
+ catch ( sdbc::SQLException& rError )
+ {
+ //! store error message
+ delete pCache;
+ pCache = NULL;
+ InfoBox aInfoBox( 0, String(rError.Message) );
+ aInfoBox.Execute();
+ }
+ catch ( uno::Exception& )
+ {
+ delete pCache;
+ pCache = NULL;
+ DBG_ERROR("Unexpected exception in database");
+ }
+
+
+ ::comphelper::disposeComponent( xRowSet );
+ return pCache;
+}
+
+ScDPTableDataCache* ScImportSourceDesc::GetCache( ScDocument* pDoc, long nID ) const
+{
+ ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID );
+ if ( NULL == pCache && pDoc )
+ pCache = GetExistDPObjectCache( pDoc);
+ if ( NULL == pCache )
+ pCache = CreateCache( pDoc , nID );
+ return pCache;
+}
+
+long ScImportSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const
+{
+ ScDPTableDataCache* pCache = GetCache( pDoc, nID);
+ if ( NULL == pCache )
+ return -1;
+ else
+ return pCache->GetId();
+}
+
+// -----------------------------------------------------------------------
+
+ScDatabaseDPData::ScDatabaseDPData(
+ ScDocument* pDoc,
+ const ScImportSourceDesc& rImport, long nCacheId /*=-1 */ ) :
+ ScDPTableData(pDoc, rImport.GetCacheId( pDoc, nCacheId) ),
+ aCacheTable( pDoc, rImport.GetCacheId( pDoc, nCacheId))
+{
+
+}
+
+ScDatabaseDPData::~ScDatabaseDPData()
+{
+}
+
+void ScDatabaseDPData::DisposeData()
+{
+ //! use OpenDatabase here?
+ aCacheTable.clear();
+}
+
+long ScDatabaseDPData::GetColumnCount()
+{
+ CreateCacheTable();
+ return GetCacheTable().getColSize();
+}
+
+// End Comments
+
+String ScDatabaseDPData::getDimensionName(long nColumn)
+{
+ if (getIsDataLayoutDimension(nColumn))
+ {
+ //! different internal and display names?
+ //return "Data";
+ return ScGlobal::GetRscString(STR_PIVOT_DATA);
+ }
+
+ CreateCacheTable();
+ return aCacheTable.getFieldName((SCCOL)nColumn);
+}
+
+BOOL ScDatabaseDPData::getIsDataLayoutDimension(long nColumn)
+{
+ return ( nColumn == GetCacheTable().getColSize());
+}
+
+BOOL ScDatabaseDPData::IsDateDimension(long /* nDim */)
+{
+ //! later...
+ return FALSE;
+}
+
+void ScDatabaseDPData::SetEmptyFlags( BOOL /* bIgnoreEmptyRows */, BOOL /* bRepeatIfEmpty */ )
+{
+ // not used for database data
+ //! disable flags
+}
+
+void ScDatabaseDPData::CreateCacheTable()
+{
+ if (!aCacheTable.empty())
+ return;
+
+ aCacheTable.fillTable();
+}
+
+void ScDatabaseDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
+{
+ CreateCacheTable();
+ aCacheTable.filterByPageDimension(
+ rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
+}
+
+void ScDatabaseDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
+{
+ CreateCacheTable();
+ sal_Int32 nRowSize = aCacheTable.getRowSize();
+ if (!nRowSize)
+ return;
+
+ aCacheTable.filterTable(
+ rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
+}
+
+void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
+{
+ CreateCacheTable();
+ CalcResultsFromCacheTable( aCacheTable, rInfo, bAutoShow);
+}
+
+const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const
+{
+ return aCacheTable;
+}
+
+// -----------------------------------------------------------------------
+
+
+
+
+
diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx
new file mode 100755
index 000000000000..a1fa9d2d60a6
--- /dev/null
+++ b/sc/source/core/data/dpshttab.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+#include <svl/zforlist.hxx>
+
+#include "dpshttab.hxx"
+#include "dptabres.hxx"
+#include "document.hxx"
+#include "collect.hxx"
+#include "cell.hxx"
+#include "dpcachetable.hxx"
+#include "dpobject.hxx"
+#include "globstr.hrc"
+// Wang Xu Ming -- 2009-8-17
+// DataPilot Migration - Cache&&Performance
+#include "dpglobal.hxx"
+// End Comments
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include <vector>
+#include <set>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Sequence;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
+
+// -----------------------------------------------------------------------
+
+ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc , long nCacheId) :
+ ScDPTableData(pD, rDesc.GetCacheId( pD, nCacheId) ), // DataPilot Migration - Cache&&Performance
+ aQuery ( rDesc.aQueryParam ),
+ pSpecial(NULL),
+ bIgnoreEmptyRows( FALSE ),
+ bRepeatIfEmpty(FALSE),
+ aCacheTable( pD, rDesc.GetCacheId( pD, nCacheId))
+{
+ SCSIZE nEntryCount( aQuery.GetEntryCount());
+ pSpecial = new BOOL[nEntryCount];
+ for (SCSIZE j = 0; j < nEntryCount; ++j )
+ {
+ ScQueryEntry& rEntry = aQuery.GetEntry(j);
+ if (rEntry.bDoQuery)
+ {
+ pSpecial[j] = false;
+ if (!rEntry.bQueryByString)
+ {
+ if (*rEntry.pStr == EMPTY_STRING &&
+ ((rEntry.nVal == SC_EMPTYFIELDS) || (rEntry.nVal == SC_NONEMPTYFIELDS)))
+ pSpecial[j] = true;
+ }
+ else
+ {
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString =
+ !(pD->GetFormatTable()->
+ IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal));
+ }
+ }
+ }
+}
+
+ScSheetDPData::~ScSheetDPData()
+{
+ delete[] pSpecial;
+}
+
+void ScSheetDPData::DisposeData()
+{
+ aCacheTable.clear();
+}
+
+long ScSheetDPData::GetColumnCount()
+{
+ CreateCacheTable();
+ return aCacheTable.getColSize();
+}
+
+String ScSheetDPData::getDimensionName(long nColumn)
+{
+ CreateCacheTable();
+ if (getIsDataLayoutDimension(nColumn))
+ {
+ //! different internal and display names?
+ //return "Data";
+ return ScGlobal::GetRscString(STR_PIVOT_DATA);
+ }
+ else if (nColumn >= aCacheTable.getColSize())
+ {
+ DBG_ERROR("getDimensionName: invalid dimension");
+ return String();
+ }
+ else
+ {
+ return aCacheTable.getFieldName((SCCOL)nColumn);
+ }
+}
+
+BOOL ScSheetDPData::IsDateDimension(long nDim)
+{
+ CreateCacheTable();
+ long nColCount = aCacheTable.getColSize();
+ if (getIsDataLayoutDimension(nDim))
+ {
+ return FALSE;
+ }
+ else if (nDim >= nColCount)
+ {
+ DBG_ERROR("IsDateDimension: invalid dimension");
+ return FALSE;
+ }
+ else
+ {
+ return aCacheTable.GetCache()->IsDateDimension( nDim);
+ }
+}
+
+ULONG ScSheetDPData::GetNumberFormat(long nDim)
+{
+ CreateCacheTable();
+ if (getIsDataLayoutDimension(nDim))
+ {
+ return 0;
+ }
+ else if (nDim >= GetCacheTable().getColSize())
+ {
+ DBG_ERROR("GetNumberFormat: invalid dimension");
+ return 0;
+ }
+ else
+ {
+ return GetCacheTable().GetCache()->GetNumberFormat( nDim );
+ }
+}
+UINT32 ScDPTableData::GetNumberFormatByIdx( NfIndexTableOffset eIdx )
+{
+ if( !mpDoc )
+ return 0;
+
+ if ( SvNumberFormatter* pFormatter = mpDoc->GetFormatTable() )
+ return pFormatter->GetFormatIndex( eIdx, LANGUAGE_SYSTEM );
+
+ return 0;
+}
+
+BOOL ScSheetDPData::getIsDataLayoutDimension(long nColumn)
+{
+ CreateCacheTable();
+ return (nColumn ==(long)( aCacheTable.getColSize()));
+}
+
+void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRowsP, BOOL bRepeatIfEmptyP )
+{
+ bIgnoreEmptyRows = bIgnoreEmptyRowsP;
+ bRepeatIfEmpty = bRepeatIfEmptyP;
+}
+
+bool ScSheetDPData::IsRepeatIfEmpty()
+{
+ return bRepeatIfEmpty;
+}
+
+void ScSheetDPData::CreateCacheTable()
+{
+ // Scan and store the data from the source range.
+ if (!aCacheTable.empty())
+ // already cached.
+ return;
+
+ aCacheTable.fillTable( aQuery, pSpecial,
+ bIgnoreEmptyRows, bRepeatIfEmpty );
+}
+
+void ScSheetDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
+{
+ CreateCacheTable();
+ aCacheTable.filterByPageDimension(
+ rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
+}
+
+void ScSheetDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
+{
+ CreateCacheTable();
+ sal_Int32 nRowSize = aCacheTable.getRowSize();
+ if (!nRowSize)
+ return;
+
+ aCacheTable.filterTable(
+ rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
+}
+
+void ScSheetDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
+{
+ CreateCacheTable();
+ CalcResultsFromCacheTable(aCacheTable, rInfo, bAutoShow);
+}
+
+const ScDPCacheTable& ScSheetDPData::GetCacheTable() const
+{
+ return aCacheTable;
+}
+
+
+// Wang Xu Ming -- 2009-8-5
+// DataPilot Migration - Cache&&Performance
+ScDPTableDataCache* ScSheetSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const
+{
+ if ( pDoc )
+ {
+ ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc );
+ if ( pCache && ( nID < 0 || nID == pCache->GetId() ) )
+ return pCache;
+
+ ULONG nErrId = CheckValidate( pDoc );
+ if ( !nErrId )
+ {
+ pCache = new ScDPTableDataCache( pDoc );
+
+ pCache->InitFromDoc( pDoc, aSourceRange );
+ pCache->SetId( nID );
+ pDoc->AddDPObjectCache( pCache );
+
+ DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() );
+ }
+ else
+ DBG_ERROR( "\n Error Create Cache" );
+ return pCache;
+ }
+ return NULL;
+}
+
+ScDPTableDataCache* ScSheetSourceDesc::GetExistDPObjectCache ( ScDocument* pDoc ) const
+{
+ return pDoc->GetUsedDPObjectCache( aSourceRange );
+}
+ScDPTableDataCache* ScSheetSourceDesc::GetCache( ScDocument* pDoc, long nID ) const
+{
+ ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID );
+ if ( NULL == pCache && pDoc )
+ pCache = GetExistDPObjectCache( pDoc );
+ if ( NULL == pCache )
+ pCache = CreateCache( pDoc );
+ return pCache;
+}
+
+long ScSheetSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const
+{
+ ScDPTableDataCache* pCache = GetCache( pDoc, nID);
+ if ( NULL == pCache )
+ return -1;
+ else
+ return pCache->GetId();
+}
+
+ULONG ScSheetSourceDesc::CheckValidate( ScDocument* pDoc ) const
+{
+ ScRange aSrcRange( aSourceRange);
+ if ( !pDoc )
+ return STR_ERR_DATAPILOTSOURCE;
+ for(USHORT i= aSrcRange.aStart.Col();i <= aSrcRange.aEnd.Col();i++)
+ {
+ if ( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(),
+ i, aSrcRange.aStart.Row(),i, aSrcRange.aStart.Row()))
+ return STR_PIVOT_FIRSTROWEMPTYERR;
+ }
+ if( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), aSrcRange.aStart.Col(), aSrcRange.aStart.Row()+1, aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row() ) )
+ {
+ return STR_PIVOT_ONLYONEROWERR;
+ }
+ return 0;
+}
+// End Comments
+
+// -----------------------------------------------------------------------
+
+
+
+
+
+
+
diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx
new file mode 100755
index 000000000000..cb68732a237f
--- /dev/null
+++ b/sc/source/core/data/dptabdat.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <stdio.h>
+#include <rtl/math.hxx>
+#include <tools/debug.hxx>
+#include <tools/date.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <unotools/collatorwrapper.hxx>
+
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include "dptabdat.hxx"
+#include "global.hxx"
+#include "dpcachetable.hxx"
+#include "dptabres.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+using ::std::vector;
+// ---------------------------------------------------------------------------
+
+ScDPTableData::CalcInfo::CalcInfo() :
+ bRepeatIfEmpty(false)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+ScDPTableData::ScDPTableData(ScDocument* pDoc, long nCacheId ) :
+ mnCacheId( nCacheId ),
+ mpDoc ( pDoc )
+{
+ nLastDateVal = nLastHier = nLastLevel = nLastRet = -1; // invalid
+
+ //! reset before new calculation (in case the base date is changed)
+}
+
+ScDPTableData::~ScDPTableData()
+{
+}
+
+long ScDPTableData::GetDatePart( long nDateVal, long nHierarchy, long nLevel )
+{
+ if ( nDateVal == nLastDateVal && nHierarchy == nLastHier && nLevel == nLastLevel )
+ return nLastRet;
+
+ Date aDate( 30,12,1899 ); //! get from source data (and cache here)
+ aDate += nDateVal;
+
+ long nRet = 0;
+ switch (nHierarchy)
+ {
+ case SC_DAPI_HIERARCHY_QUARTER:
+ switch (nLevel)
+ {
+ case 0: nRet = aDate.GetYear(); break;
+ case 1: nRet = (aDate.GetMonth()-1) / 3 + 1; break;
+ case 2: nRet = aDate.GetMonth(); break;
+ case 3: nRet = aDate.GetDay(); break;
+ default:
+ DBG_ERROR("GetDatePart: wrong level");
+ }
+ break;
+ case SC_DAPI_HIERARCHY_WEEK:
+ switch (nLevel)
+ {
+ //! use settings for different definitions
+ case 0: nRet = aDate.GetYear(); break; //!...
+ case 1: nRet = aDate.GetWeekOfYear(); break;
+ case 2: nRet = (long)aDate.GetDayOfWeek(); break;
+ default:
+ DBG_ERROR("GetDatePart: wrong level");
+ }
+ break;
+ default:
+ DBG_ERROR("GetDatePart: wrong hierarchy");
+ }
+
+ nLastDateVal = nDateVal;
+ nLastHier = nHierarchy;
+ nLastLevel = nLevel;
+ nLastRet = nRet;
+
+ return nRet;
+}
+
+bool ScDPTableData::IsRepeatIfEmpty()
+{
+ return false;
+}
+
+ULONG ScDPTableData::GetNumberFormat(long)
+{
+ return 0; // default format
+}
+
+BOOL ScDPTableData::IsBaseForGroup(long) const
+{
+ return FALSE; // always false
+}
+
+long ScDPTableData::GetGroupBase(long) const
+{
+ return -1; // always none
+}
+
+BOOL ScDPTableData::IsNumOrDateGroup(long) const
+{
+ return FALSE; // always false
+}
+
+BOOL ScDPTableData::IsInGroup( const ScDPItemData&, long,
+ const ScDPItemData&, long ) const
+{
+ DBG_ERROR("IsInGroup shouldn't be called for non-group data");
+ return FALSE;
+}
+
+BOOL ScDPTableData::HasCommonElement( const ScDPItemData&, long,
+ const ScDPItemData&, long ) const
+{
+ DBG_ERROR("HasCommonElement shouldn't be called for non-group data");
+ return FALSE;
+}
+void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTable& rCacheTable,
+ const CalcInfo& rInfo, CalcRowData& rData)
+{
+ // column dimensions
+ GetItemData(rCacheTable, nRow, rInfo.aColLevelDims, rData.aColData);
+
+ // row dimensions
+ GetItemData(rCacheTable, nRow, rInfo.aRowLevelDims, rData.aRowData);
+
+ // page dimensions
+ GetItemData(rCacheTable, nRow, rInfo.aPageDims, rData.aPageData);
+
+ long nCacheColumnCount = rCacheTable.GetCache()->GetColumnCount();
+ sal_Int32 n = rInfo.aDataSrcCols.size();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ long nDim = rInfo.aDataSrcCols[i];
+ rData.aValues.push_back( ScDPValueData() );
+ // #i111435# GetItemData needs dimension indexes including groups,
+ // so the index must be checked here (groups aren't useful as data fields).
+ if ( nDim < nCacheColumnCount )
+ {
+ ScDPValueData& rVal = rData.aValues.back();
+ rCacheTable.getValue( rVal, static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false);
+ }
+ }
+}
+
+void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAutoShow)
+{
+ // Wang Xu Ming -- 2009-6-16
+ // DataPilot Migration
+ if (!bAutoShow)
+ {
+ LateInitParams aColParams( rInfo.aColDims, rInfo.aColLevels, FALSE );
+ LateInitParams aRowParams ( rInfo.aRowDims, rInfo.aRowLevels, TRUE );
+ // root always init child
+ aColParams.SetInitChild( TRUE );
+ aColParams.SetInitAllChildren( FALSE);
+ aRowParams.SetInitChild( TRUE );
+ aRowParams.SetInitAllChildren( FALSE);
+
+ rInfo.pColRoot->LateInitFrom( aColParams, rData.aColData,0, *rInfo.pInitState);
+ rInfo.pRowRoot->LateInitFrom( aRowParams, rData.aRowData, 0, *rInfo.pInitState);
+ }
+ // End Comments
+
+ if ( ( !rInfo.pColRoot->GetChildDimension() || rInfo.pColRoot->GetChildDimension()->IsValidEntry(rData.aColData) ) &&
+ ( !rInfo.pRowRoot->GetChildDimension() || rInfo.pRowRoot->GetChildDimension()->IsValidEntry(rData.aRowData) ) )
+ {
+ //! single process method with ColMembers, RowMembers and data !!!
+ if (rInfo.pColRoot->GetChildDimension())
+ {
+// Wang Xu Ming -- 2009-6-10
+// DataPilot Migration
+ vector</*ScDPItemData*/ SCROW > aEmptyData;
+ rInfo.pColRoot->GetChildDimension()->ProcessData(rData.aColData, NULL, aEmptyData, rData.aValues);
+// End Comments
+ }
+
+ rInfo.pRowRoot->ProcessData(rData.aRowData, rInfo.pColRoot->GetChildDimension(),
+ rData.aColData, rData.aValues);
+ }
+}
+
+void ScDPTableData::CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, CalcInfo& rInfo, bool bAutoShow)
+{
+ sal_Int32 nRowSize = rCacheTable.getRowSize();
+ for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
+ {
+ if (!rCacheTable.isRowActive(nRow))
+ continue;
+
+ CalcRowData aData;
+ FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData);
+ ProcessRowData(rInfo, aData, bAutoShow);
+ }
+}
+
+// Wang Xu Ming -- 2009-6-10
+// DataPilot Migration
+void ScDPTableData::GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow,
+ const vector<long>& rDims, vector< SCROW/*ScDPItemData*/>& rItemData)
+// End Comments
+{
+ sal_Int32 nDimSize = rDims.size();
+ for (sal_Int32 i = 0; i < nDimSize; ++i)
+ {
+ long nDim = rDims[i];
+
+ if (getIsDataLayoutDimension(nDim))
+ {
+ rItemData.push_back( -1 );
+ continue;
+ }
+
+ nDim = GetSourceDim( nDim );
+ if ( nDim >= rCacheTable.GetCache()->GetColumnCount() )
+ continue;
+
+ SCROW nId= rCacheTable.GetCache()->GetItemDataId( static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty());
+ rItemData.push_back( nId );
+
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// Wang Xu Ming -- 2009-6-8
+// DataPilot Migration
+long ScDPTableData::GetMembersCount( long nDim )
+{
+ if ( nDim > MAXCOL )
+ return 0;
+ return GetCacheTable().getFieldEntries( nDim ).size();
+}
+
+long ScDPTableData::GetCacheId() const
+{
+ return mnCacheId;
+}
+
+const ScDPItemData* ScDPTableData::GetMemberByIndex( long nDim, long nIndex )
+{
+ if ( nIndex >= GetMembersCount( nDim ) )
+ return NULL;
+
+ const ::std::vector<SCROW>& nMembers = GetCacheTable().getFieldEntries( nDim );
+
+ return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nMembers[nIndex] );
+}
+
+const ScDPItemData* ScDPTableData::GetMemberById( long nDim, long nId)
+{
+
+ return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nId);
+}
+
+SCROW ScDPTableData::GetIdOfItemData( long nDim, const ScDPItemData& rData )
+{
+ return GetCacheTable().GetCache()->GetIdByItemData((SCCOL) nDim, rData );
+ }
+
+const std::vector< SCROW >& ScDPTableData::GetColumnEntries( long nColumn )
+{
+ return GetCacheTable().getFieldEntries( nColumn );
+}
+
+long ScDPTableData::GetSourceDim( long nDim )
+{
+ return nDim;
+
+}
+
+ long ScDPTableData::Compare( long nDim, long nDataId1, long nDataId2)
+{
+ if ( getIsDataLayoutDimension(nDim) )
+ return 0;
+
+ long n1 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId1);
+ long n2 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId2);
+ if ( n1 > n2 )
+ return 1;
+ else if ( n1 == n2 )
+ return 0;
+ else
+ return -1;
+}
+// End Comments
+// -----------------------------------------------------------------------
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
new file mode 100644
index 000000000000..8d2a5ec070f5
--- /dev/null
+++ b/sc/source/core/data/dptablecache.cxx
@@ -0,0 +1,1135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright IBM Corporation 2009.
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dptablecache.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dptablecache.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+
+#include <rtl/math.hxx>
+#include "queryparam.hxx"
+#include "dpglobal.hxx"
+
+#include "docoptio.hxx" //for ValidQuery
+#include <unotools/textsearch.hxx> //for ValidQuery
+
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+const double D_TIMEFACTOR = 86400.0;
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+// -----------------------------------------------------------------------
+namespace
+{
+ BOOL lcl_isDate( ULONG nNumType )
+ {
+ return ( (nNumType & NUMBERFORMAT_DATE) != 0 )? 1:0 ;
+ }
+
+ BOOL lcl_Search( const std::vector<ScDPItemData*>& list, const ::std::vector<SCROW>& rOrder, const ScDPItemData& item, SCROW& rIndex)
+ {
+ rIndex = list.size();
+ BOOL bFound = FALSE;
+ SCROW nLo = 0;
+ SCROW nHi = list.size() - 1;
+ SCROW nIndex;
+ long nCompare;
+ while (nLo <= nHi)
+ {
+ nIndex = (nLo + nHi) / 2;
+ nCompare = ScDPItemData::Compare( *list[rOrder[nIndex]], item );
+ if (nCompare < 0)
+ nLo = nIndex + 1;
+ else
+ {
+ nHi = nIndex - 1;
+ if (nCompare == 0)
+ {
+ bFound = TRUE;
+ nLo = nIndex;
+ }
+ }
+ }
+ rIndex = nLo;
+ return bFound;
+ }
+
+ ScDPItemData* lcl_GetItemValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol,
+ const Date& rNullDate )
+ {
+ short nNumType = NUMBERFORMAT_NUMBER;
+ try
+ {
+ String rStr = xRow->getString(nCol);
+ double fValue = 0.0;
+ switch (nType)
+ {
+ case sdbc::DataType::BIT:
+ case sdbc::DataType::BOOLEAN:
+ {
+ nNumType = NUMBERFORMAT_LOGICAL;
+ fValue = xRow->getBoolean(nCol) ? 1 : 0;
+ return new ScDPItemData( rStr, fValue,TRUE,nNumType);
+ }
+ //break;
+
+ case sdbc::DataType::TINYINT:
+ case sdbc::DataType::SMALLINT:
+ case sdbc::DataType::INTEGER:
+ case sdbc::DataType::BIGINT:
+ case sdbc::DataType::FLOAT:
+ case sdbc::DataType::REAL:
+ case sdbc::DataType::DOUBLE:
+ case sdbc::DataType::NUMERIC:
+ case sdbc::DataType::DECIMAL:
+ {
+ //! do the conversion here?
+ fValue = xRow->getDouble(nCol);
+ return new ScDPItemData( rStr, fValue,TRUE);
+ }
+ //break;
+
+ case sdbc::DataType::DATE:
+ {
+ nNumType = NUMBERFORMAT_DATE;
+
+ util::Date aDate = xRow->getDate(nCol);
+ fValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate;
+ return new ScDPItemData( rStr, fValue, TRUE, nNumType );
+ }
+ //break;
+
+ case sdbc::DataType::TIME:
+ {
+ nNumType = NUMBERFORMAT_TIME;
+
+ util::Time aTime = xRow->getTime(nCol);
+ fValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 +
+ aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
+ return new ScDPItemData( rStr,fValue, TRUE, nNumType );
+ }
+ //break;
+
+ case sdbc::DataType::TIMESTAMP:
+ {
+ nNumType = NUMBERFORMAT_DATETIME;
+
+ util::DateTime aStamp = xRow->getTimestamp(nCol);
+ fValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) +
+ ( aStamp.Hours * 3600 + aStamp.Minutes * 60 +
+ aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
+ return new ScDPItemData( rStr,fValue, TRUE, nNumType );
+ }
+ //break;
+ case sdbc::DataType::CHAR:
+ case sdbc::DataType::VARCHAR:
+ case sdbc::DataType::LONGVARCHAR:
+ case sdbc::DataType::SQLNULL:
+ case sdbc::DataType::BINARY:
+ case sdbc::DataType::VARBINARY:
+ case sdbc::DataType::LONGVARBINARY:
+ default:
+ return new ScDPItemData ( rStr );
+ //break;
+ }
+ }
+ catch (uno::Exception&)
+ {
+ }
+ catch ( ... )
+ {
+
+ }
+ return NULL;
+ }
+}
+// Wang Xu Ming -- 12/23/2008
+//Refactor cache data
+ScDPItemData::ScDPItemData( const String& rS, double fV/* = 0.0*/, BOOL bHV/* = FALSE*/, const ULONG nNumFormatP /*= 0*/ , BOOL bData/* = TRUE*/) :
+nNumFormat( nNumFormatP ), aString(rS), fValue(fV),
+mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!FALSE) | (MK_DATE*!!lcl_isDate( nNumFormat ) ) )
+{
+}
+
+ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, USHORT nCol, USHORT nDocTab ):
+ nNumFormat( 0 ), fValue(0.0), mbFlag( 0 )
+{
+ String aDocStr;
+ pDoc->GetString( nCol, nRow, nDocTab, aDocStr );
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ ScAddress aPos( nCol, nRow, nDocTab );
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() )
+ {
+ SetString ( aDocStr ); //[SODC_19347] add liyi
+ //bErr = TRUE; //[SODC_19347] del liyi
+ mbFlag |= MK_ERR;
+ }
+ else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) )
+ {
+ double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab));
+ ULONG nFormat = NUMBERFORMAT_NUMBER;
+ if ( pFormatter )
+ nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) );
+ aString = aDocStr;
+ fValue = fVal;
+ mbFlag |= MK_VAL|MK_DATA;
+ nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) );
+ lcl_isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE);
+ }
+ else if ( pDoc->HasData( nCol,nRow, nDocTab ) )
+ SetString ( aDocStr );
+}
+// End Comments
+
+BOOL ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const
+{ //TODO: indified Date?
+ //! pass Transliteration?
+ //! inline?
+ return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( fValue, r.fValue ) ) :
+ ( !r.IsValue() &&
+ ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) );
+}
+
+size_t ScDPItemData::Hash() const
+{
+ if ( IsValue() )
+ return (size_t) rtl::math::approxFloor( fValue );
+ else
+ // If we do unicode safe case insensitive hash we can drop
+ // ScDPItemData::operator== and use ::IsCasInsEqual
+ return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() );
+}
+
+BOOL ScDPItemData::operator==( const ScDPItemData& r ) const
+{
+ if ( IsValue() )
+ {
+ if( (HasDatePart() != r.HasDatePart()) || (HasDatePart() && mnDatePart != r.mnDatePart) )
+ return FALSE;
+
+// Wang Xu Ming -- 1/9/2009
+// Add Data Cache Support.
+// Identify date
+ if ( IsDate() != r.IsDate() )
+ return FALSE;
+ else
+ if ( r.IsValue() )
+ return rtl::math::approxEqual( fValue, r.fValue );
+ else
+ return FALSE;
+// End Comments
+ }
+ else if ( r.IsValue() )
+ return FALSE;
+ else
+ // need exact equality until we have a safe case insensitive string hash
+ return aString == r.aString;
+}
+
+sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
+ const ScDPItemData& rB )
+{
+ if ( rA.IsValue() )
+ {
+ if ( rB.IsValue() )
+ {
+ if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) )
+ {
+// Wang Xu Ming -- 1/9/2009
+// Add Data Cache Support.
+// Date > number
+ if ( rA.IsDate() == rB.IsDate() )
+ return 0;
+ else
+ return rA.IsDate() ? 1: -1;
+// End Comments
+ }
+ else if ( rA.fValue < rB.fValue )
+ return -1;
+ else
+ return 1;
+ }
+ else
+ return -1; // values first
+ }
+ else if ( rB.IsValue() )
+ return 1; // values first
+ else
+ return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString );
+}
+//
+//Wang Xu Ming SODC_17561
+#ifdef DEBUG
+void ScDPItemData::dump() const
+{
+ DBG_TRACE1( "Numberformat= %o", nNumFormat );
+ DBG_TRACESTR(aString );
+ DBG_TRACE1( "fValue= %f", fValue );
+ DBG_TRACE1( "mbFlag= %d", mbFlag);
+}
+#endif
+//End
+
+TypedStrData* ScDPItemData::CreateTypeString( )
+{
+ if ( IsValue() )
+ return new TypedStrData( aString, fValue, SC_STRTYPE_VALUE );
+ else
+ return new TypedStrData( aString );
+}
+
+sal_uInt8 ScDPItemData::GetType() const
+{
+
+ if ( IsHasErr() )
+ return SC_VALTYPE_ERROR;
+ else if ( !IsHasData() )
+ return SC_VALTYPE_EMPTY;
+ else if ( IsValue())
+ return SC_VALTYPE_VALUE;
+ else
+ return SC_VALTYPE_STRING;
+
+}
+
+BOOL ScDPItemData::IsHasData() const
+{
+ return !!(mbFlag&MK_DATA);
+}
+
+BOOL ScDPItemData::IsHasErr() const
+{
+ return !!(mbFlag&MK_ERR);
+}
+
+BOOL ScDPItemData::IsValue() const
+{
+ return !!(mbFlag&MK_VAL);
+}
+
+String ScDPItemData::GetString() const
+{
+
+ return aString;
+}
+
+double ScDPItemData::GetValue() const
+{
+ return fValue;
+}
+ULONG ScDPItemData::GetNumFormat() const
+{
+ return nNumFormat;
+}
+
+BOOL ScDPItemData::HasStringData() const
+
+{
+ return IsHasData()&&!IsHasErr()&&!IsValue();
+}
+BOOL ScDPItemData::IsDate() const
+{
+ return !!(mbFlag&MK_DATE);
+}
+BOOL ScDPItemData::HasDatePart() const
+{
+ return !!(mbFlag&MK_DATEPART);
+}
+void ScDPItemData::SetDate( BOOL b )
+{
+ b ? ( mbFlag |= MK_DATE ) : ( mbFlag &= ~MK_DATE );
+}
+
+// -----------------------------------------------------------------------
+//class ScDPTableDataCache
+//To cache the pivot table data source
+
+BOOL ScDPTableDataCache::operator== ( const ScDPTableDataCache& r ) const
+{
+ if ( GetColumnCount() == r.GetColumnCount() )
+ {
+ for ( SCCOL i = 0 ; i < GetColumnCount(); i++ )
+ { //check dim names
+ if ( GetDimensionName( i ) != r.GetDimensionName( i ) )
+ return FALSE;
+ //check rows count
+ if ( GetRowCount() != r.GetRowCount() )
+ return FALSE;
+ //check dim member values
+ size_t nMembersCount = GetDimMemberValues( i ).size();
+ if ( GetDimMemberValues( i ).size() == r. GetDimMemberValues( i ).size() )
+ {
+ for ( size_t j = 0; j < nMembersCount; j++ )
+ {
+ if ( *( GetDimMemberValues( i )[j] ) == *( r.GetDimMemberValues( i )[j] ) )
+ continue;
+ else
+ return FALSE;
+ }
+ }
+ else
+ return FALSE;
+ //check source table index
+ for ( SCROW k=0 ; k < GetRowCount(); k ++ )
+ {
+ if ( GetItemDataId( i, k, FALSE ) == r.GetItemDataId( i,k,FALSE) )
+ continue;
+ else
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+ScDPTableDataCache::ScDPTableDataCache( ScDocument* pDoc ) :
+mpDoc( pDoc ),
+mnColumnCount ( 0 ),
+mpTableDataValues ( NULL ),
+mpSourceData ( NULL ),
+mpGlobalOrder( NULL ),
+mpIndexOrder( NULL)
+{
+ mnID = -1;
+}
+
+ScDPTableDataCache::~ScDPTableDataCache()
+{
+ if ( IsValid() )
+ {
+// Wang Xu Ming -- 2/17/2009
+// Performance issue
+ USHORT nCol;
+ for ( nCol=0; nCol < GetColumnCount() ; nCol++ )
+ {
+ for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ )
+ delete mpTableDataValues[nCol][row];
+ }
+ for ( nCol =0; nCol < mrLabelNames.size(); nCol++ )
+ delete mrLabelNames[nCol];
+// End Comments
+
+ mnColumnCount = 0;
+ delete [] mpTableDataValues;
+ mpTableDataValues = NULL;
+ delete [] mpSourceData;
+ mpSourceData = NULL;
+ delete [] mpGlobalOrder;
+ mpGlobalOrder = NULL;
+ delete [] mpIndexOrder;
+ mpIndexOrder = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+void ScDPTableDataCache::AddRow( ScDPItemData* pRow, USHORT nCount )
+{
+ DBG_ASSERT( pRow , " empty pointer" );
+ if ( !mrLabelNames.size() )
+ {
+ mnColumnCount= nCount;
+ mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ];
+ mpSourceData = new std::vector<SCROW>[ mnColumnCount ];
+ mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ];
+ mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ];
+
+ for ( USHORT i = 0; i < nCount ; i ++ )
+ AddLabel( new ScDPItemData( pRow[i] ) );
+ }
+ else
+ {
+ for ( USHORT i = 0; i < nCount && i < mnColumnCount; i ++ )
+ AddData( i, new ScDPItemData( pRow[i] ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+bool ScDPTableDataCache::IsValid() const
+{ //TODO: continue check valid
+ return mpTableDataValues!=NULL && mpSourceData!= NULL && mnColumnCount>0;
+}
+
+// -----------------------------------------------------------------------
+
+namespace {
+
+/**
+ * While the macro interpret level is incremented, the formula cells are
+ * (semi-)guaranteed to be interpreted.
+ */
+class MacroInterpretIncrementer
+{
+public:
+ MacroInterpretIncrementer(ScDocument* pDoc) :
+ mpDoc(pDoc)
+ {
+ mpDoc->IncMacroInterpretLevel();
+ }
+ ~MacroInterpretIncrementer()
+ {
+ mpDoc->DecMacroInterpretLevel();
+ }
+private:
+ ScDocument* mpDoc;
+};
+
+}
+
+// -----------------------------------------------------------------------
+bool ScDPTableDataCache::InitFromDoc( ScDocument* pDoc, const ScRange& rRange )
+{
+ // Make sure the formula cells within the data range are interpreted
+ // during this call, for this method may be called from the interpretation
+ // of GETPIVOTDATA, which disables nested formula interpretation without
+ // increasing the macro level.
+ MacroInterpretIncrementer aMacroInc(pDoc);
+
+ //
+ SCROW nStartRow = rRange.aStart.Row(); // start of data
+ SCROW nEndRow = rRange.aEnd.Row();
+ USHORT nStartCol = rRange.aStart.Col();
+ USHORT nEndCol = rRange.aEnd.Col();
+ USHORT nDocTab = rRange.aStart.Tab();
+
+ //init
+ long nOldColumCount = mnColumnCount;
+ mnColumnCount = nEndCol - nStartCol + 1;
+ if ( IsValid() )
+ {
+ for ( USHORT nCol=0; nCol < nOldColumCount ; nCol++ )
+ {
+ for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ )
+ delete mpTableDataValues[nCol][row];
+ delete mrLabelNames[nCol];
+ }
+ delete [] mpTableDataValues;
+ delete [] mpSourceData;
+ delete [] mpGlobalOrder;
+ delete [] mpIndexOrder;
+ mrLabelNames.clear();
+ }
+
+ mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ];
+ mpSourceData = new std::vector<SCROW>[ mnColumnCount ];
+ mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ];
+ mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ];
+ //check valid
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow ++ )
+ {
+ for ( USHORT nCol = nStartCol; nCol <= nEndCol; nCol++ )
+ {
+ if ( nRow == nStartRow )
+ AddLabel( new ScDPItemData( pDoc, nRow, nCol, nDocTab ) );
+ else
+ AddData( nCol - nStartCol, new ScDPItemData( pDoc, nRow, nCol, nDocTab ) );
+ }
+ }
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+bool ScDPTableDataCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate)
+{
+ if (!xRowSet.is())
+ // Dont' even waste time to go any further.
+ return false;
+ try
+ {
+ Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(xRowSet, UNO_QUERY_THROW);
+ Reference<sdbc::XResultSetMetaData> xMeta = xMetaSupp->getMetaData();
+ if (!xMeta.is())
+ return false;
+
+ long nOldColumCount = mnColumnCount;
+ mnColumnCount = xMeta->getColumnCount();
+ if ( IsValid() )
+ {
+ for ( USHORT nCol=0; nCol < nOldColumCount ; nCol++ )
+ {
+ for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ )
+ delete mpTableDataValues[nCol][row];
+ delete mrLabelNames[nCol];
+ }
+ delete [] mpTableDataValues;
+ delete [] mpSourceData;
+ delete [] mpGlobalOrder;
+ delete [] mpIndexOrder;
+ mrLabelNames.clear();
+ }
+ // Get column titles and types.
+ mrLabelNames.reserve(mnColumnCount);
+ mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ];
+ mpSourceData = new std::vector<SCROW>[ mnColumnCount ];
+ mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ];
+ mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ];
+
+ std::vector<sal_Int32> aColTypes(mnColumnCount);
+
+ for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol)
+ {
+ String aColTitle = xMeta->getColumnLabel(nCol+1);
+ aColTypes[nCol] = xMeta->getColumnType(nCol+1);
+ AddLabel( new ScDPItemData( aColTitle) );
+ }
+
+ // Now get the data rows.
+ Reference<sdbc::XRow> xRow(xRowSet, UNO_QUERY_THROW);
+ xRowSet->first();
+ do
+ {
+ for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol)
+ {
+ ScDPItemData * pNew = lcl_GetItemValue( xRow, aColTypes[nCol], nCol+1, rNullDate );
+ if ( pNew )
+ AddData( nCol , pNew );
+ }
+ }
+ while (xRowSet->next());
+
+ xRowSet->beforeFirst();
+
+ return true;
+ }
+ catch (const Exception&)
+ {
+ return false;
+ }
+}
+// -----------------------------------------------------------------------
+ULONG ScDPTableDataCache::GetDimNumType( SCCOL nDim) const
+{
+ DBG_ASSERT( IsValid(), " IsValid() == false " );
+ DBG_ASSERT( nDim < mnColumnCount && nDim >=0, " dimention out of bound " );
+ if ( mpTableDataValues[nDim].size()==0 )
+ return NUMBERFORMAT_UNDEFINED;
+ else
+ return GetNumType(mpTableDataValues[nDim][0]->nNumFormat);
+}
+
+// -----------------------------------------------------------------------
+bool ScDPTableDataCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, BOOL *pSpecial)
+{ //Copied and modified from ScTable::ValidQuery
+ if (!rParam.GetEntry(0).bDoQuery)
+ return TRUE;
+ BOOL bMatchWholeCell = mpDoc->GetDocOptions().IsMatchWholeCell();
+
+ //---------------------------------------------------------------
+
+ const SCSIZE nFixedBools = 32;
+ BOOL aBool[nFixedBools];
+ BOOL aTest[nFixedBools];
+ SCSIZE nEntryCount = rParam.GetEntryCount();
+ BOOL* pPasst = ( nEntryCount <= nFixedBools ? &aBool[0] : new BOOL[nEntryCount] );
+ BOOL* pTest = ( nEntryCount <= nFixedBools ? &aTest[0] : new BOOL[nEntryCount] );
+
+ long nPos = -1;
+ SCSIZE i = 0;
+ CollatorWrapper* pCollator = (rParam.bCaseSens ? ScGlobal::GetCaseCollator() :
+ ScGlobal::GetCollator() );
+ ::utl::TransliterationWrapper* pTransliteration = (rParam.bCaseSens ?
+ ScGlobal::GetCaseTransliteration() : ScGlobal::GetpTransliteration());
+
+ while ( (i < nEntryCount) && rParam.GetEntry(i).bDoQuery )
+ {
+ ScQueryEntry& rEntry = rParam.GetEntry(i);
+ // we can only handle one single direct query
+ // #i115431# nField in QueryParam is the sheet column, not the field within the source range
+ SCCOL nQueryCol = (SCCOL)rEntry.nField;
+ if ( nQueryCol < rParam.nCol1 )
+ nQueryCol = rParam.nCol1;
+ if ( nQueryCol > rParam.nCol2 )
+ nQueryCol = rParam.nCol2;
+ SCCOL nSourceField = nQueryCol - rParam.nCol1;
+ SCROW nId = GetItemDataId( nSourceField, nRow, FALSE );
+ const ScDPItemData* pCellData = GetItemDataById( nSourceField, nId );
+
+ BOOL bOk = FALSE;
+ BOOL bTestEqual = FALSE;
+
+ if ( pSpecial && pSpecial[i] )
+ {
+ if (rEntry.nVal == SC_EMPTYFIELDS)
+ bOk = ! pCellData->IsHasData();
+ else // if (rEntry.nVal == SC_NONEMPTYFIELDS)
+ bOk = pCellData->IsHasData();
+ }
+ else if ( !rEntry.bQueryByString && pCellData->IsValue() )
+ { // by Value
+ double nCellVal = pCellData->GetValue();
+
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL :
+ bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_LESS :
+ bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_GREATER :
+ bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_LESS_EQUAL :
+ bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_GREATER_EQUAL :
+ bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_NOT_EQUAL :
+ bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ default:
+ bOk= FALSE;
+ break;
+ }
+ }
+ else if ( (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
+ || (rEntry.bQueryByString
+ && pCellData->HasStringData() )
+ )
+ { // by String
+ String aCellStr = pCellData->GetString();
+
+ BOOL bRealRegExp = (rParam.bRegExp && ((rEntry.eOp == SC_EQUAL)
+ || (rEntry.eOp == SC_NOT_EQUAL)));
+ BOOL bTestRegExp = FALSE;
+ if ( bRealRegExp || bTestRegExp )
+ {
+ 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
+ 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);
+ else
+ bTestEqual = bMatch;
+ }
+ if ( !bRealRegExp )
+ {
+ if ( rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL )
+ {
+ if ( bMatchWholeCell )
+ {
+ bOk = pTransliteration->isEqual( aCellStr, *rEntry.pStr );
+ //Added by zhaosz,for sodc_2702,20060808
+ String aStr = *rEntry.pStr;//"f*"
+ //modified by weihuaw,for SODC_16698
+ //use another way to find "*" in aStr
+ sal_Bool bHasStar = sal_False;
+ xub_StrLen nIndex;
+ if( ( nIndex = aStr.Search('*') ) != STRING_NOTFOUND )
+ bHasStar = sal_True;
+ if(bHasStar && (nIndex>0))
+ {
+ for(i=0;(i<nIndex) && (i< aCellStr.Len()) ; i++)
+ {
+ if(aCellStr.GetChar( (USHORT)i ) == aStr.GetChar((USHORT) i ))
+ {
+ bOk=1;
+ }
+ else
+ {
+ bOk=0;
+ break;
+ }
+ }
+ }
+ //end modified
+ //Added end,20060808
+ }
+ else
+ {
+ ::com::sun::star::uno::Sequence< sal_Int32 > xOff;
+ String aCell( pTransliteration->transliterate(
+ aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(),
+ &xOff ) );
+ String aQuer( pTransliteration->transliterate(
+ *rEntry.pStr, ScGlobal::eLnge, 0, rEntry.pStr->Len(),
+ &xOff ) );
+ bOk = (aCell.Search( aQuer ) != STRING_NOTFOUND);
+ }
+ if ( rEntry.eOp == SC_NOT_EQUAL )
+ bOk = !bOk;
+ }
+ else
+ { // use collator here because data was probably sorted
+ sal_Int32 nCompare = pCollator->compareString(
+ aCellStr, *rEntry.pStr );
+ switch (rEntry.eOp)
+ {
+ case SC_LESS :
+ bOk = (nCompare < 0);
+ break;
+ case SC_GREATER :
+ bOk = (nCompare > 0);
+ break;
+ case SC_LESS_EQUAL :
+ bOk = (nCompare <= 0);
+ break;
+ case SC_GREATER_EQUAL :
+ bOk = (nCompare >= 0);
+ break;
+ case SC_NOT_EQUAL:
+ DBG_ASSERT( false , "SC_NOT_EQUAL");
+ break;
+ case SC_TOPVAL:
+ case SC_BOTVAL:
+ case SC_TOPPERC:
+ case SC_BOTPERC:
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ if (nPos == -1)
+ {
+ nPos++;
+ pPasst[nPos] = bOk;
+ pTest[nPos] = bTestEqual;
+ }
+ else
+ {
+ if (rEntry.eConnect == SC_AND)
+ {
+ pPasst[nPos] = pPasst[nPos] && bOk;
+ pTest[nPos] = pTest[nPos] && bTestEqual;
+ }
+ else
+ {
+ nPos++;
+ pPasst[nPos] = bOk;
+ pTest[nPos] = bTestEqual;
+ }
+ }
+ i++;
+ }
+
+ for ( long j=1; j <= nPos; j++ )
+ {
+ pPasst[0] = pPasst[0] || pPasst[j];
+ pTest[0] = pTest[0] || pTest[j];
+ }
+
+ BOOL bRet = pPasst[0];
+ if ( pPasst != &aBool[0] )
+ delete [] pPasst;
+ if ( pTest != &aTest[0] )
+ delete [] pTest;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+bool ScDPTableDataCache::IsRowEmpty( SCROW nRow ) const
+{
+ return mbEmptyRow[ nRow ];
+
+}
+
+// -----------------------------------------------------------------------
+bool ScDPTableDataCache::IsEmptyMember( SCROW nRow, USHORT nColumn ) const
+{
+ return !GetItemDataById( nColumn, GetItemDataId( nColumn, nRow, FALSE ) )->IsHasData();
+}
+
+BOOL ScDPTableDataCache::AddData(long nDim, ScDPItemData* pitemData)
+{
+ DBG_ASSERT( IsValid(), " IsValid() == false " );
+ DBG_ASSERT( nDim < mnColumnCount && nDim >=0 , "dimension out of bound" );
+ SCROW nIndex = 0;
+
+ BOOL bInserted = FALSE;
+
+ pitemData->SetDate( lcl_isDate( GetNumType( pitemData->nNumFormat ) ) );
+
+ if ( !lcl_Search( mpTableDataValues[nDim], mpGlobalOrder[nDim], *pitemData, nIndex ) )
+ {
+ mpTableDataValues[nDim].push_back( pitemData );
+ mpGlobalOrder[nDim].insert( mpGlobalOrder[nDim].begin()+nIndex, mpTableDataValues[nDim].size()-1 );
+ DBG_ASSERT( (size_t) mpGlobalOrder[nDim][nIndex] == mpTableDataValues[nDim].size()-1 ,"ScDPTableDataCache::AddData ");
+ mpSourceData[nDim].push_back( mpTableDataValues[nDim].size()-1 );
+ bInserted = TRUE;
+ }
+ else
+ mpSourceData[nDim].push_back( mpGlobalOrder[nDim][nIndex] );
+//init empty row tag
+ size_t nCurRow = mpSourceData[nDim].size() -1 ;
+
+ while ( mbEmptyRow.size() <= nCurRow )
+ mbEmptyRow.push_back( TRUE );
+
+ if ( pitemData->IsHasData() )
+ mbEmptyRow[ nCurRow ] = FALSE;
+
+ if ( !bInserted )
+ delete pitemData;
+
+ return TRUE;
+}
+
+
+String ScDPTableDataCache::GetDimensionName( USHORT nColumn ) const
+{
+ DBG_ASSERT( /* nColumn>=0 && */ nColumn < mrLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName");
+ DBG_ASSERT( mrLabelNames.size() == static_cast <USHORT> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName");
+ if ( static_cast<size_t>(nColumn+1) < mrLabelNames.size() )
+ {
+ return mrLabelNames[nColumn+1]->aString;
+ }
+ else
+ return String();
+}
+
+void ScDPTableDataCache::AddLabel(ScDPItemData *pData)
+{
+ DBG_ASSERT( IsValid(), " IsValid() == false " );
+
+ if ( mrLabelNames.size() == 0 )
+ mrLabelNames.push_back( new ScDPItemData( ScGlobal::GetRscString(STR_PIVOT_DATA) ) );
+
+
+ //reset name if needed
+ String strNewName = pData->aString;
+ BOOL bFound = FALSE;
+ long nIndex = 1;
+ do
+ {
+ for ( long i= mrLabelNames.size()-1; i>=0; i-- )
+ {
+ if( mrLabelNames[i]->aString == strNewName )
+ {
+ strNewName = pData->aString;
+ strNewName += String::CreateFromInt32( nIndex );
+ nIndex ++ ;
+ bFound = TRUE;
+ }
+ }
+ bFound = !bFound;
+ }
+ while ( !bFound );
+
+ pData->aString = strNewName;
+ mrLabelNames.push_back( pData );
+}
+
+SCROW ScDPTableDataCache::GetItemDataId(USHORT nDim, SCROW nRow, BOOL bRepeatIfEmpty) const
+{ //
+ DBG_ASSERT( IsValid(), " IsValid() == false " );
+ DBG_ASSERT( /* nDim >= 0 && */ nDim < mnColumnCount, "ScDPTableDataCache::GetItemDataId " );
+
+ if ( bRepeatIfEmpty )
+ {
+ while ( nRow >0 && !mpTableDataValues[nDim][ mpSourceData[nDim][nRow] ]->IsHasData() )
+ --nRow;
+ }
+
+ return mpSourceData[nDim][nRow];
+}
+
+const ScDPItemData* ScDPTableDataCache::GetItemDataById(long nDim, SCROW nId) const
+{
+ if ( nId >= GetRowCount() )
+ return maAdditionalDatas.getData( nId - GetRowCount() );
+
+ if ( (size_t)nId >= mpTableDataValues[nDim].size() || nDim >= mnColumnCount || nId < 0 )
+ return NULL;
+ else
+ return mpTableDataValues[nDim][nId];
+}
+
+SCROW ScDPTableDataCache::GetRowCount() const
+{
+ if ( IsValid() )
+ return mpSourceData[0].size();
+ else
+ return 0;
+}
+
+const std::vector<ScDPItemData*>& ScDPTableDataCache::GetDimMemberValues(SCCOL nDim) const
+{
+ DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount ");
+ return mpTableDataValues[nDim];
+}
+
+SCROW ScDPTableDataCache::GetSortedItemDataId(SCCOL nDim, SCROW nOrder) const
+{
+ DBG_ASSERT ( IsValid(), "IsValid");
+ DBG_ASSERT( nDim>=0 && nDim < mnColumnCount, "nDim < mnColumnCount");
+ DBG_ASSERT( nOrder >= 0 && (size_t) nOrder < mpGlobalOrder[nDim].size(), "nOrder < mpGlobalOrder[nDim].size()" );
+
+ return mpGlobalOrder[nDim][nOrder];
+}
+
+ULONG ScDPTableDataCache::GetNumType(ULONG nFormat) const
+{
+ SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
+ ULONG nType = NUMBERFORMAT_NUMBER;
+ if ( pFormatter )
+ nType = pFormatter->GetType( nFormat );
+ return nType;
+}
+
+ULONG ScDPTableDataCache::GetNumberFormat( long nDim ) const
+{
+ if ( nDim >= mnColumnCount )
+ return 0;
+ if ( mpTableDataValues[nDim].size()==0 )
+ return 0;
+ else
+ return mpTableDataValues[nDim][0]->nNumFormat;
+}
+
+BOOL ScDPTableDataCache::IsDateDimension( long nDim ) const
+{
+ if ( nDim >= mnColumnCount )
+ return false;
+ else if ( mpTableDataValues[nDim].size()==0 )
+ return false;
+ else
+ return mpTableDataValues[nDim][0]->IsDate();
+
+}
+
+SCROW ScDPTableDataCache::GetDimMemberCount( SCCOL nDim ) const
+{
+ DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," ScDPTableDataCache::GetDimMemberCount : out of bound ");
+ return mpTableDataValues[nDim].size();
+}
+
+const ScDPItemData* ScDPTableDataCache::GetSortedItemData(SCCOL nDim, SCROW nOrder) const
+{
+ SCROW n = GetSortedItemDataId( nDim, nOrder );
+ return GetItemDataById( nDim, n );
+}
+
+SCCOL ScDPTableDataCache::GetDimensionIndex(String sName) const
+{
+ for ( size_t n = 1; n < mrLabelNames.size(); n ++ ) //defects, label name map wrong SODC_17590, SODC_18932,SODC_18827,SODC_18960,SODC_18923
+ {
+ if ( mrLabelNames[n]->GetString() == sName )
+ return (SCCOL)(n-1);
+ }
+ return -1;
+}
+
+SCROW ScDPTableDataCache::GetIdByItemData(long nDim, String sItemData ) const
+{
+ if ( nDim < mnColumnCount && nDim >=0 )
+ {
+ for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ )
+ {
+ if ( mpTableDataValues[nDim][n]->GetString() == sItemData )
+ return n;
+ }
+ }
+
+ ScDPItemData rData ( sItemData );
+ return GetRowCount() +maAdditionalDatas.getDataId(rData);
+}
+
+SCROW ScDPTableDataCache::GetIdByItemData( long nDim, const ScDPItemData& rData ) const
+{
+ if ( nDim < mnColumnCount && nDim >=0 )
+ {
+ for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ )
+ {
+ if ( *mpTableDataValues[nDim][n] == rData )
+ return n;
+ }
+ }
+ return GetRowCount() + maAdditionalDatas.getDataId(rData);
+}
+
+SCROW ScDPTableDataCache::GetAdditionalItemID ( String sItemData )
+{
+ ScDPItemData rData ( sItemData );
+ return GetAdditionalItemID( rData );
+}
+
+SCROW ScDPTableDataCache::GetAdditionalItemID( const ScDPItemData& rData )
+{
+ return GetRowCount() + maAdditionalDatas.insertData( rData );
+}
+
+
+SCROW ScDPTableDataCache::GetOrder(long nDim, SCROW nIndex) const
+{
+ DBG_ASSERT( IsValid(), " IsValid() == false " );
+ DBG_ASSERT( nDim >=0 && nDim < mnColumnCount, "ScDPTableDataCache::GetOrder : out of bound" );
+
+ if ( mpIndexOrder[nDim].size() != mpGlobalOrder[nDim].size() )
+ { //not inited
+ SCROW i = 0;
+ mpIndexOrder[nDim].resize( mpGlobalOrder[nDim].size(), 0 );
+ for ( size_t n = 0 ; n< mpGlobalOrder[nDim].size(); n++ )
+ {
+ i = mpGlobalOrder[nDim][n];
+ mpIndexOrder[nDim][ i ] = n;
+ }
+ }
+
+ DBG_ASSERT( nIndex>=0 && (size_t)nIndex < mpIndexOrder[nDim].size() , "ScDPTableDataCache::GetOrder");
+ return mpIndexOrder[nDim][nIndex];
+}
+
+ScDocument* ScDPTableDataCache::GetDoc() const
+{
+ return mpDoc;
+};
+
+long ScDPTableDataCache::GetColumnCount() const
+{
+ return mnColumnCount;
+}
+long ScDPTableDataCache::GetId() const
+{
+ return mnID;
+}
+
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
new file mode 100755
index 000000000000..c79f7c1b17a6
--- /dev/null
+++ b/sc/source/core/data/dptabres.cxx
@@ -0,0 +1,4109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+#include <rtl/math.hxx>
+
+#include "dptabdat.hxx"
+#include "dptabres.hxx"
+#include "dptabsrc.hxx"
+#include "global.hxx"
+#include "subtotal.hxx"
+#include "globstr.hrc"
+#include "datauno.hxx" // ScDataUnoConversion
+
+#include "document.hxx" // for DumpState only!
+
+#include <math.h>
+#include <float.h> //! Test !!!
+#include <algorithm>
+#include <hash_map>
+
+#include <com/sun/star/sheet/DataResultFlags.hpp>
+#include <com/sun/star/sheet/MemberResultFlags.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+using namespace com::sun::star;
+using ::std::vector;
+using ::std::pair;
+using ::std::hash_map;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+// -----------------------------------------------------------------------
+
+SV_IMPL_PTRARR( ScDPDataMembers, ScDPDataMemberPtr );
+
+// -----------------------------------------------------------------------
+
+static USHORT nFuncStrIds[12] = // passend zum enum ScSubTotalFunc
+{
+ 0, // SUBTOTAL_FUNC_NONE
+ STR_FUN_TEXT_AVG, // SUBTOTAL_FUNC_AVE
+ STR_FUN_TEXT_COUNT, // SUBTOTAL_FUNC_CNT
+ STR_FUN_TEXT_COUNT, // SUBTOTAL_FUNC_CNT2
+ STR_FUN_TEXT_MAX, // SUBTOTAL_FUNC_MAX
+ STR_FUN_TEXT_MIN, // SUBTOTAL_FUNC_MIN
+ STR_FUN_TEXT_PRODUCT, // SUBTOTAL_FUNC_PROD
+ STR_FUN_TEXT_STDDEV, // SUBTOTAL_FUNC_STD
+ STR_FUN_TEXT_STDDEV, // SUBTOTAL_FUNC_STDP
+ STR_FUN_TEXT_SUM, // SUBTOTAL_FUNC_SUM
+ STR_FUN_TEXT_VAR, // SUBTOTAL_FUNC_VAR
+ STR_FUN_TEXT_VAR // SUBTOTAL_FUNC_VARP
+};
+namespace {
+ template < typename T >
+ void lcl_ResizePointVector( T & vec, size_t nSize )
+ {
+
+ for ( size_t i = 0 ; i < vec.size(); i++ )
+ {
+ if ( vec[i] )
+ delete vec[i];
+ }
+ vec.resize( nSize, NULL );
+ }
+ BOOL lcl_SearchMember( const std::vector <ScDPResultMember *>& list, SCROW nOrder, SCROW& rIndex)
+ {
+ rIndex = list.size();
+ BOOL bFound = FALSE;
+ SCROW nLo = 0;
+ SCROW nHi = list.size() - 1;
+ SCROW nIndex;
+ while (nLo <= nHi)
+ {
+ nIndex = (nLo + nHi) / 2;
+ if ( list[nIndex]->GetOrder() < nOrder )
+ nLo = nIndex + 1;
+ else
+ {
+ nHi = nIndex - 1;
+ if ( list[nIndex]->GetOrder() == nOrder )
+ {
+ bFound = TRUE;
+ nLo = nIndex;
+ }
+ }
+ }
+ rIndex = nLo;
+ return bFound;
+ }
+}
+// -----------------------------------------------------------------------
+
+//
+// function objects for sorting of the column and row members:
+//
+
+class ScDPRowMembersOrder
+{
+ ScDPResultDimension& rDimension;
+ long nMeasure;
+ BOOL bAscending;
+
+public:
+ ScDPRowMembersOrder( ScDPResultDimension& rDim, long nM, BOOL bAsc ) :
+ rDimension(rDim),
+ nMeasure(nM),
+ bAscending(bAsc)
+ {}
+ ~ScDPRowMembersOrder() {}
+
+ BOOL operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const;
+};
+
+class ScDPColMembersOrder
+{
+ ScDPDataDimension& rDimension;
+ long nMeasure;
+ BOOL bAscending;
+
+public:
+ ScDPColMembersOrder( ScDPDataDimension& rDim, long nM, BOOL bAsc ) :
+ rDimension(rDim),
+ nMeasure(nM),
+ bAscending(bAsc)
+ {}
+ ~ScDPColMembersOrder() {}
+
+ BOOL operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const;
+};
+
+static BOOL lcl_IsLess( const ScDPDataMember* pDataMember1, const ScDPDataMember* pDataMember2, long nMeasure, BOOL bAscending )
+{
+ // members can be NULL if used for rows
+
+ ScDPSubTotalState aEmptyState;
+ const ScDPAggData* pAgg1 = pDataMember1 ? pDataMember1->GetConstAggData( nMeasure, aEmptyState ) : NULL;
+ const ScDPAggData* pAgg2 = pDataMember2 ? pDataMember2->GetConstAggData( nMeasure, aEmptyState ) : NULL;
+
+ BOOL bError1 = pAgg1 && pAgg1->HasError();
+ BOOL bError2 = pAgg2 && pAgg2->HasError();
+ if ( bError1 )
+ {
+ if ( bError2 )
+ return FALSE; // equal
+ else
+ return FALSE; // errors are always sorted at the end
+ }
+ else if ( bError2 )
+ return TRUE; // errors are always sorted at the end
+ else
+ {
+ double fVal1 = ( pAgg1 && pAgg1->HasData() ) ? pAgg1->GetResult() : 0.0; // no data is sorted as 0
+ double fVal2 = ( pAgg2 && pAgg2->HasData() ) ? pAgg2->GetResult() : 0.0;
+
+ // compare values
+ // don't have to check approxEqual, as this is the only sort criterion
+
+ return bAscending ? ( fVal1 < fVal2 ) : ( fVal1 > fVal2 );
+ }
+}
+
+static BOOL lcl_IsEqual( const ScDPDataMember* pDataMember1, const ScDPDataMember* pDataMember2, long nMeasure )
+{
+ // members can be NULL if used for rows
+
+ ScDPSubTotalState aEmptyState;
+ const ScDPAggData* pAgg1 = pDataMember1 ? pDataMember1->GetConstAggData( nMeasure, aEmptyState ) : NULL;
+ const ScDPAggData* pAgg2 = pDataMember2 ? pDataMember2->GetConstAggData( nMeasure, aEmptyState ) : NULL;
+
+ BOOL bError1 = pAgg1 && pAgg1->HasError();
+ BOOL bError2 = pAgg2 && pAgg2->HasError();
+ if ( bError1 )
+ {
+ if ( bError2 )
+ return TRUE; // equal
+ else
+ return FALSE;
+ }
+ else if ( bError2 )
+ return FALSE;
+ else
+ {
+ double fVal1 = ( pAgg1 && pAgg1->HasData() ) ? pAgg1->GetResult() : 0.0; // no data is sorted as 0
+ double fVal2 = ( pAgg2 && pAgg2->HasData() ) ? pAgg2->GetResult() : 0.0;
+
+ // compare values
+ // this is used to find equal data at the end of the AutoShow range, so approxEqual must be used
+
+ return rtl::math::approxEqual( fVal1, fVal2 );
+ }
+}
+
+BOOL ScDPRowMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const
+{
+ const ScDPResultMember* pMember1 = rDimension.GetMember(nIndex1);
+ const ScDPResultMember* pMember2 = rDimension.GetMember(nIndex2);
+// Wang Xu Ming -- 3/17/2009
+
+// make the hide item to the largest order.
+ if ( !pMember1->IsVisible() || !pMember2->IsVisible() )
+ return pMember1->IsVisible();
+ const ScDPDataMember* pDataMember1 = pMember1->GetDataRoot() ;
+ const ScDPDataMember* pDataMember2 = pMember2->GetDataRoot();
+// End Comments
+ // GetDataRoot can be NULL if there was no data.
+ // IsVisible == FALSE can happen after AutoShow.
+ return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending );
+}
+
+BOOL ScDPColMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const
+{
+ ScDPDataMember* pDataMember1 = rDimension.GetMember(nIndex1);
+ ScDPDataMember* pDataMember2 = rDimension.GetMember(nIndex2);
+ // Wang Xu Ming -- 2009-6-17
+ BOOL bHide1 = pDataMember1 && !pDataMember1->IsVisible();
+ BOOL bHide2 = pDataMember2 && !pDataMember2->IsVisible();
+ if ( bHide1 || bHide2 )
+ return !bHide1;
+ // End Comments
+ return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending );
+}
+
+// -----------------------------------------------------------------------
+
+ScDPInitState::ScDPInitState() :
+ nCount( 0 )
+{
+ pIndex = new long[SC_DAPI_MAXFIELDS];
+ pData = new SCROW[SC_DAPI_MAXFIELDS];
+}
+
+ScDPInitState::~ScDPInitState()
+{
+ delete[] pIndex;
+ delete[] pData;
+}
+
+void ScDPInitState::AddMember( long nSourceIndex, SCROW nMember )
+{
+ DBG_ASSERT( nCount < SC_DAPI_MAXFIELDS, "too many InitState members" );
+ if ( nCount < SC_DAPI_MAXFIELDS )
+ {
+ pIndex[nCount] = nSourceIndex;
+ pData[nCount] = nMember;
+ ++nCount;
+ }
+}
+
+void ScDPInitState::RemoveMember()
+{
+ DBG_ASSERT( nCount > 0, "RemoveColIndex without index" );
+ if ( nCount > 0 )
+ --nCount;
+}
+
+SCROW ScDPInitState::GetNameIdForIndex( long nIndexValue ) const
+{
+ for (long i=0; i<nCount; i++)
+ if ( pIndex[i] == nIndexValue )
+ return pData[i];
+
+ return -1; // not found
+}
+
+// -----------------------------------------------------------------------
+
+void lcl_DumpRow( const String& rType, const String& rName, const ScDPAggData* pAggData,
+ ScDocument* pDoc, ScAddress& rPos )
+{
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+ pDoc->SetString( nCol++, nRow, nTab, rType );
+ pDoc->SetString( nCol++, nRow, nTab, rName );
+ while ( pAggData )
+ {
+ pDoc->SetValue( nCol++, nRow, nTab, pAggData->GetResult() );
+ pAggData = pAggData->GetExistingChild();
+ }
+ rPos.SetRow( nRow + 1 );
+}
+
+void lcl_Indent( ScDocument* pDoc, SCROW nStartRow, const ScAddress& rPos )
+{
+ SCCOL nCol = rPos.Col();
+ SCTAB nTab = rPos.Tab();
+
+ String aString;
+ for (SCROW nRow = nStartRow; nRow < rPos.Row(); nRow++)
+ {
+ pDoc->GetString( nCol, nRow, nTab, aString );
+ if ( aString.Len() )
+ {
+ aString.InsertAscii( " ", 0 );
+ pDoc->SetString( nCol, nRow, nTab, aString );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScDPRunningTotalState::ScDPRunningTotalState( ScDPResultMember* pColRoot, ScDPResultMember* pRowRoot ) :
+ pColResRoot( pColRoot ),
+ pRowResRoot( pRowRoot ),
+ nColIndexPos( 0 ),
+ nRowIndexPos( 0 )
+{
+ pColVisible = new long[SC_DAPI_MAXFIELDS+1];
+ pColIndexes = new long[SC_DAPI_MAXFIELDS+1];
+ pRowVisible = new long[SC_DAPI_MAXFIELDS+1];
+ pRowIndexes = new long[SC_DAPI_MAXFIELDS+1];
+ pColIndexes[0] = -1;
+ pRowIndexes[0] = -1;
+}
+
+ScDPRunningTotalState::~ScDPRunningTotalState()
+{
+ delete[] pColVisible;
+ delete[] pColIndexes;
+ delete[] pRowVisible;
+ delete[] pRowIndexes;
+}
+
+void ScDPRunningTotalState::AddColIndex( long nVisible, long nSorted )
+{
+ DBG_ASSERT( nColIndexPos < SC_DAPI_MAXFIELDS, "too many column indexes" );
+ if ( nColIndexPos < SC_DAPI_MAXFIELDS )
+ {
+ pColVisible[nColIndexPos] = nVisible;
+ pColIndexes[nColIndexPos] = nSorted;
+ pColVisible[nColIndexPos+1] = -1;
+ pColIndexes[nColIndexPos+1] = -1;
+ ++nColIndexPos;
+ }
+}
+
+void ScDPRunningTotalState::AddRowIndex( long nVisible, long nSorted )
+{
+ DBG_ASSERT( nRowIndexPos < SC_DAPI_MAXFIELDS, "too many row indexes" );
+ if ( nRowIndexPos < SC_DAPI_MAXFIELDS )
+ {
+ pRowVisible[nRowIndexPos] = nVisible;
+ pRowIndexes[nRowIndexPos] = nSorted;
+ pRowVisible[nRowIndexPos+1] = -1;
+ pRowIndexes[nRowIndexPos+1] = -1;
+ ++nRowIndexPos;
+ }
+}
+
+void ScDPRunningTotalState::RemoveColIndex()
+{
+ DBG_ASSERT( nColIndexPos > 0, "RemoveColIndex without index" );
+ if ( nColIndexPos > 0 )
+ {
+ --nColIndexPos;
+ pColVisible[nColIndexPos] = -1;
+ pColIndexes[nColIndexPos] = -1;
+ }
+}
+
+void ScDPRunningTotalState::RemoveRowIndex()
+{
+ DBG_ASSERT( nRowIndexPos > 0, "RemoveRowIndex without index" );
+ if ( nRowIndexPos > 0 )
+ {
+ --nRowIndexPos;
+ pRowVisible[nRowIndexPos] = -1;
+ pRowIndexes[nRowIndexPos] = -1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScDPRelativePos::ScDPRelativePos( long nBase, long nDir ) :
+ nBasePos( nBase ),
+ nDirection( nDir )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ScDPAggData::Update( const ScDPValueData& rNext, ScSubTotalFunc eFunc, const ScDPSubTotalState& rSubState )
+{
+ if (nCount<0) // error?
+ return; // nothing more...
+
+ if ( rNext.nType == SC_VALTYPE_EMPTY )
+ return;
+
+ if ( rSubState.eColForce != SUBTOTAL_FUNC_NONE && rSubState.eRowForce != SUBTOTAL_FUNC_NONE &&
+ rSubState.eColForce != rSubState.eRowForce )
+ return;
+ if ( rSubState.eColForce != SUBTOTAL_FUNC_NONE ) eFunc = rSubState.eColForce;
+ if ( rSubState.eRowForce != SUBTOTAL_FUNC_NONE ) eFunc = rSubState.eRowForce;
+
+ if ( eFunc == SUBTOTAL_FUNC_NONE )
+ return;
+
+ if ( eFunc != SUBTOTAL_FUNC_CNT2 ) // CNT2 counts everything, incl. strings and errors
+ {
+ if ( rNext.nType == SC_VALTYPE_ERROR )
+ {
+ nCount = -1; // -1 for error (not for CNT2)
+ return;
+ }
+ if ( rNext.nType == SC_VALTYPE_STRING )
+ return; // ignore
+ }
+
+ ++nCount; // for all functions
+
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_SUM:
+ case SUBTOTAL_FUNC_AVE:
+ if ( !SubTotal::SafePlus( fVal, rNext.fValue ) )
+ nCount = -1; // -1 for error
+ break;
+ case SUBTOTAL_FUNC_PROD:
+ if ( nCount == 1 ) // copy first value (fVal is initialized to 0)
+ fVal = rNext.fValue;
+ else if ( !SubTotal::SafeMult( fVal, rNext.fValue ) )
+ nCount = -1; // -1 for error
+ break;
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2:
+ // nothing more than incrementing nCount
+ break;
+ case SUBTOTAL_FUNC_MAX:
+ if ( nCount == 1 || rNext.fValue > fVal )
+ fVal = rNext.fValue;
+ break;
+ case SUBTOTAL_FUNC_MIN:
+ if ( nCount == 1 || rNext.fValue < fVal )
+ fVal = rNext.fValue;
+ break;
+ case SUBTOTAL_FUNC_STD:
+ case SUBTOTAL_FUNC_STDP:
+ case SUBTOTAL_FUNC_VAR:
+ case SUBTOTAL_FUNC_VARP:
+ {
+ // fAux is used to sum up squares
+ if ( !SubTotal::SafePlus( fVal, rNext.fValue ) )
+ nCount = -1; // -1 for error
+ double fAdd = rNext.fValue;
+ if ( !SubTotal::SafeMult( fAdd, rNext.fValue ) ||
+ !SubTotal::SafePlus( fAux, fAdd ) )
+ nCount = -1; // -1 for error
+ }
+ break;
+ default:
+ DBG_ERROR("invalid function");
+ }
+}
+
+void ScDPAggData::Calculate( ScSubTotalFunc eFunc, const ScDPSubTotalState& rSubState )
+{
+ // calculate the original result
+ // (without reference value, used as the basis for reference value calculation)
+
+ // called several times at the cross-section of several subtotals - don't calculate twice then
+ if ( IsCalculated() )
+ return;
+
+ if ( rSubState.eColForce != SUBTOTAL_FUNC_NONE ) eFunc = rSubState.eColForce;
+ if ( rSubState.eRowForce != SUBTOTAL_FUNC_NONE ) eFunc = rSubState.eRowForce;
+
+ if ( eFunc == SUBTOTAL_FUNC_NONE ) // this happens when there is no data dimension
+ {
+ nCount = SC_DPAGG_RESULT_EMPTY; // make sure there's a valid state for HasData etc.
+ return;
+ }
+
+ // check the error conditions for the selected function
+
+ BOOL bError = FALSE;
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_SUM:
+ case SUBTOTAL_FUNC_PROD:
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2:
+ bError = ( nCount < 0 ); // only real errors
+ break;
+
+ case SUBTOTAL_FUNC_AVE:
+ case SUBTOTAL_FUNC_MAX:
+ case SUBTOTAL_FUNC_MIN:
+ case SUBTOTAL_FUNC_STDP:
+ case SUBTOTAL_FUNC_VARP:
+ bError = ( nCount <= 0 ); // no data is an error
+ break;
+
+ case SUBTOTAL_FUNC_STD:
+ case SUBTOTAL_FUNC_VAR:
+ bError = ( nCount < 2 ); // need at least 2 values
+ break;
+
+ default:
+ DBG_ERROR("invalid function");
+ }
+
+ // calculate the selected function
+
+ double fResult = 0.0;
+ if ( !bError )
+ {
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_MAX:
+ case SUBTOTAL_FUNC_MIN:
+ case SUBTOTAL_FUNC_SUM:
+ case SUBTOTAL_FUNC_PROD:
+ // different error conditions are handled above
+ fResult = fVal;
+ break;
+
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2:
+ fResult = nCount;
+ break;
+
+ case SUBTOTAL_FUNC_AVE:
+ if ( nCount > 0 )
+ fResult = fVal / (double) nCount;
+ break;
+
+ //! use safe mul for fVal * fVal
+
+ case SUBTOTAL_FUNC_STD:
+ if ( nCount >= 2 )
+ fResult = sqrt((fAux - fVal*fVal/(double)(nCount)) / (double)(nCount-1));
+ break;
+ case SUBTOTAL_FUNC_VAR:
+ if ( nCount >= 2 )
+ fResult = (fAux - fVal*fVal/(double)(nCount)) / (double)(nCount-1);
+ break;
+ case SUBTOTAL_FUNC_STDP:
+ if ( nCount > 0 )
+ fResult = sqrt((fAux - fVal*fVal/(double)(nCount)) / (double)nCount);
+ break;
+ case SUBTOTAL_FUNC_VARP:
+ if ( nCount > 0 )
+ fResult = (fAux - fVal*fVal/(double)(nCount)) / (double)nCount;
+ break;
+ default:
+ DBG_ERROR("invalid function");
+ }
+ }
+
+ BOOL bEmpty = ( nCount == 0 ); // no data
+
+ // store the result
+ // Empty is checked first, so empty results are shown empty even for "average" etc.
+ // If these results should be treated as errors in reference value calculations,
+ // a separate state value (EMPTY_ERROR) is needed.
+ // Now, for compatibility, empty "average" results are counted as 0.
+
+ if ( bEmpty )
+ nCount = SC_DPAGG_RESULT_EMPTY;
+ else if ( bError )
+ nCount = SC_DPAGG_RESULT_ERROR;
+ else
+ nCount = SC_DPAGG_RESULT_VALID;
+
+ if ( bEmpty || bError )
+ fResult = 0.0; // default, in case the state is later modified
+
+// fprintf(stdout, "ScDPAggData::Calculate: result = %g\n", fResult);fflush(stdout);
+ fVal = fResult; // used directly from now on
+ fAux = 0.0; // used for running total or original result of reference value
+}
+
+BOOL ScDPAggData::IsCalculated() const
+{
+ return ( nCount <= SC_DPAGG_RESULT_EMPTY );
+}
+
+double ScDPAggData::GetResult() const
+{
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ return fVal; // use calculated value
+}
+
+BOOL ScDPAggData::HasError() const
+{
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ return ( nCount == SC_DPAGG_RESULT_ERROR );
+}
+
+BOOL ScDPAggData::HasData() const
+{
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ return ( nCount != SC_DPAGG_RESULT_EMPTY ); // values or error
+}
+
+void ScDPAggData::SetResult( double fNew )
+{
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ fVal = fNew; // don't reset error flag
+}
+
+void ScDPAggData::SetError()
+{
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ nCount = SC_DPAGG_RESULT_ERROR;
+}
+
+void ScDPAggData::SetEmpty( BOOL bSet )
+{
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ if ( bSet )
+ nCount = SC_DPAGG_RESULT_EMPTY;
+ else
+ nCount = SC_DPAGG_RESULT_VALID;
+}
+
+double ScDPAggData::GetAuxiliary() const
+{
+ // after Calculate, fAux is used as auxiliary value for running totals and reference values
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ return fAux;
+}
+
+void ScDPAggData::SetAuxiliary( double fNew )
+{
+ // after Calculate, fAux is used as auxiliary value for running totals and reference values
+ DBG_ASSERT( IsCalculated(), "ScDPAggData not calculated" );
+
+ fAux = fNew;
+}
+
+ScDPAggData* ScDPAggData::GetChild()
+{
+ if (!pChild)
+ pChild = new ScDPAggData;
+ return pChild;
+}
+
+void ScDPAggData::Reset()
+{
+ fVal = 0.0;
+ fAux = 0.0;
+ nCount = SC_DPAGG_EMPTY;
+ delete pChild;
+ pChild = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ScDPRowTotals::ScDPRowTotals() :
+ bIsInColRoot( FALSE )
+{
+}
+
+ScDPRowTotals::~ScDPRowTotals()
+{
+}
+
+ScDPAggData* lcl_GetChildTotal( ScDPAggData* pFirst, long nMeasure )
+{
+ DBG_ASSERT( nMeasure >= 0, "GetColTotal: no measure" );
+
+ ScDPAggData* pAgg = pFirst;
+ long nSkip = nMeasure;
+
+ // subtotal settings are ignored - colum/row totals exist once per measure
+
+ for ( long nPos=0; nPos<nSkip; nPos++ )
+ pAgg = pAgg->GetChild(); // column total is constructed empty - children need to be created
+
+ if ( !pAgg->IsCalculated() )
+ {
+ // for first use, simulate an empty calculation
+ ScDPSubTotalState aEmptyState;
+ pAgg->Calculate( SUBTOTAL_FUNC_SUM, aEmptyState );
+ }
+
+ return pAgg;
+}
+
+ScDPAggData* ScDPRowTotals::GetRowTotal( long nMeasure )
+{
+ return lcl_GetChildTotal( &aRowTotal, nMeasure );
+}
+
+ScDPAggData* ScDPRowTotals::GetGrandTotal( long nMeasure )
+{
+ return lcl_GetChildTotal( &aGrandTotal, nMeasure );
+}
+
+// -----------------------------------------------------------------------
+
+static ScSubTotalFunc lcl_GetForceFunc( const ScDPLevel* pLevel, long nFuncNo )
+{
+ ScSubTotalFunc eRet = SUBTOTAL_FUNC_NONE;
+ if ( pLevel )
+ {
+ //! direct access via ScDPLevel
+
+ uno::Sequence<sheet::GeneralFunction> aSeq = pLevel->getSubTotals();
+ long nSequence = aSeq.getLength();
+ if ( nSequence && aSeq[0] != sheet::GeneralFunction_AUTO )
+ {
+ // For manual subtotals, "automatic" is added as first function.
+ // ScDPResultMember::GetSubTotalCount adds to the count, here NONE has to be
+ // returned as the first function then.
+
+ --nFuncNo; // keep NONE for first (check below), move the other entries
+ }
+
+ if ( nFuncNo >= 0 && nFuncNo < nSequence )
+ {
+ sheet::GeneralFunction eUser = aSeq.getConstArray()[nFuncNo];
+ if (eUser != sheet::GeneralFunction_AUTO)
+ eRet = ScDataUnoConversion::GeneralToSubTotal( eUser );
+ }
+ }
+ return eRet;
+}
+
+// -----------------------------------------------------------------------
+
+ScDPResultData::ScDPResultData( ScDPSource* pSrc ) : //! Ref
+ pSource( pSrc ),
+ nMeasCount( 0 ),
+ pMeasFuncs( NULL ),
+ pMeasRefs( NULL ),
+ pMeasRefOrient( NULL ),
+ pMeasNames( NULL ),
+ bLateInit( FALSE ),
+ bDataAtCol( FALSE ),
+ bDataAtRow( FALSE )
+{
+
+ lcl_ResizePointVector( mpDimMembers , SC_DAPI_MAXFIELDS );
+}
+
+ScDPResultData::~ScDPResultData()
+{
+ delete[] pMeasFuncs;
+ delete[] pMeasRefs;
+ delete[] pMeasRefOrient;
+ delete[] pMeasNames;
+
+ lcl_ResizePointVector( mpDimMembers , 0 );
+}
+
+void ScDPResultData::SetMeasureData( long nCount, const ScSubTotalFunc* pFunctions,
+ const sheet::DataPilotFieldReference* pRefs, const USHORT* pRefOrient,
+ const String* pNames )
+{
+ delete[] pMeasFuncs;
+ delete[] pMeasRefs;
+ delete[] pMeasRefOrient;
+ delete[] pMeasNames;
+ if ( nCount )
+ {
+ nMeasCount = nCount;
+ pMeasFuncs = new ScSubTotalFunc[nCount];
+ pMeasRefs = new sheet::DataPilotFieldReference[nCount];
+ pMeasRefOrient = new USHORT[nCount];
+ pMeasNames = new String[nCount];
+ for (long i=0; i<nCount; i++)
+ {
+ pMeasFuncs[i] = pFunctions[i];
+ pMeasRefs[i] = pRefs[i];
+ pMeasRefOrient[i] = pRefOrient[i];
+ pMeasNames[i] = pNames[i];
+ }
+ }
+ else
+ {
+ // use one dummy measure
+ nMeasCount = 1;
+ pMeasFuncs = new ScSubTotalFunc[1];
+ pMeasFuncs[0] = SUBTOTAL_FUNC_NONE;
+ pMeasRefs = new sheet::DataPilotFieldReference[1]; // default ctor is ok
+ pMeasRefOrient = new USHORT[1];
+ pMeasRefOrient[0] = sheet::DataPilotFieldOrientation_HIDDEN;
+ pMeasNames = new String[1];
+ pMeasNames[0] = ScGlobal::GetRscString( STR_EMPTYDATA );
+ }
+}
+
+void ScDPResultData::SetDataLayoutOrientation( USHORT nOrient )
+{
+ bDataAtCol = ( nOrient == sheet::DataPilotFieldOrientation_COLUMN );
+ bDataAtRow = ( nOrient == sheet::DataPilotFieldOrientation_ROW );
+}
+
+void ScDPResultData::SetLateInit( BOOL bSet )
+{
+ bLateInit = bSet;
+}
+
+long ScDPResultData::GetColStartMeasure() const
+{
+ if ( nMeasCount == 1 ) return 0;
+ return bDataAtCol ? SC_DPMEASURE_ALL : SC_DPMEASURE_ANY;
+}
+
+long ScDPResultData::GetRowStartMeasure() const
+{
+ if ( nMeasCount == 1 ) return 0;
+ return bDataAtRow ? SC_DPMEASURE_ALL : SC_DPMEASURE_ANY;
+}
+
+ScSubTotalFunc ScDPResultData::GetMeasureFunction(long nMeasure) const
+{
+ DBG_ASSERT( pMeasFuncs && nMeasure < nMeasCount, "bumm" );
+ return pMeasFuncs[nMeasure];
+}
+
+const sheet::DataPilotFieldReference& ScDPResultData::GetMeasureRefVal(long nMeasure) const
+{
+ DBG_ASSERT( pMeasRefs && nMeasure < nMeasCount, "bumm" );
+ return pMeasRefs[nMeasure];
+}
+
+USHORT ScDPResultData::GetMeasureRefOrient(long nMeasure) const
+{
+ DBG_ASSERT( pMeasRefOrient && nMeasure < nMeasCount, "bumm" );
+ return pMeasRefOrient[nMeasure];
+}
+
+String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const
+{
+ // with bForce==TRUE, return function instead of "result" for single measure
+ // with eForceFunc != SUBTOTAL_FUNC_NONE, always use eForceFunc
+ rbTotalResult = false;
+ if ( nMeasure < 0 || ( nMeasCount == 1 && !bForce && eForceFunc == SUBTOTAL_FUNC_NONE ) )
+ {
+ // for user-specified subtotal function with all measures,
+ // display only function name
+ if ( eForceFunc != SUBTOTAL_FUNC_NONE )
+ return ScGlobal::GetRscString(nFuncStrIds[eForceFunc]);
+
+ rbTotalResult = true;
+ return ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
+ }
+ else
+ {
+ DBG_ASSERT( pMeasNames && nMeasure < nMeasCount, "bumm" );
+ ScDPDimension* pDataDim = pSource->GetDataDimension(nMeasure);
+ if (pDataDim)
+ {
+ const OUString* pLayoutName = pDataDim->GetLayoutName();
+ if (pLayoutName)
+ return *pLayoutName;
+ }
+ String aRet;
+ ScSubTotalFunc eFunc = ( eForceFunc == SUBTOTAL_FUNC_NONE ) ?
+ GetMeasureFunction(nMeasure) : eForceFunc;
+ USHORT nId = nFuncStrIds[eFunc];
+ if (nId)
+ {
+ aRet += ScGlobal::GetRscString(nId); // function name
+ aRet.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
+ }
+ aRet += pMeasNames[nMeasure]; // field name
+
+ return aRet;
+ }
+}
+
+String ScDPResultData::GetMeasureDimensionName(long nMeasure) const
+{
+ if ( nMeasure < 0 )
+ {
+ DBG_ERROR("GetMeasureDimensionName: negative");
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("***"));
+ }
+
+ return pSource->GetDataDimName( nMeasure );
+}
+
+BOOL ScDPResultData::IsBaseForGroup( long nDim ) const
+{
+ return pSource->GetData()->IsBaseForGroup( nDim );
+}
+
+long ScDPResultData::GetGroupBase( long nGroupDim ) const
+{
+ return pSource->GetData()->GetGroupBase( nGroupDim );
+}
+
+BOOL ScDPResultData::IsNumOrDateGroup( long nDim ) const
+{
+ return pSource->GetData()->IsNumOrDateGroup( nDim );
+}
+
+BOOL ScDPResultData::IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex,
+ long nBaseDataId, long nBaseIndex ) const
+{
+ const ScDPItemData* pData = pSource->GetItemDataById( nGroupIndex , nBaseDataId);
+ if ( pData )
+ return pSource->GetData()->IsInGroup( rGroupData, nGroupIndex, *pData , nBaseIndex );
+ else
+ return FALSE;
+}
+BOOL ScDPResultData::IsInGroup( SCROW nGroupDataId, long nGroupIndex,
+ const ScDPItemData& rBaseData, long nBaseIndex ) const
+{
+ const ScDPItemData* pGroupData = pSource->GetItemDataById( nGroupIndex , nGroupDataId);
+ if ( pGroupData )
+ return pSource->GetData()->IsInGroup( *pGroupData, nGroupIndex, rBaseData , nBaseIndex );
+ else
+ return FALSE;
+}
+
+BOOL ScDPResultData::HasCommonElement(/* const ScDPItemData& rFirstData*/SCROW nFirstDataId, long nFirstIndex,
+ const ScDPItemData& rSecondData, long nSecondIndex ) const
+{
+ const ScDPItemData* pFirstData = pSource->GetItemDataById( nFirstIndex , nFirstDataId);
+ if ( pFirstData )
+ return pSource->GetData()->HasCommonElement( *pFirstData, nFirstIndex, rSecondData, nSecondIndex );
+ else
+ return FALSE;
+}
+
+const ScDPSource* ScDPResultData::GetSource() const
+{
+ return pSource;
+}
+
+ResultMembers* ScDPResultData::GetDimResultMembers( long nDim , ScDPDimension* pDim, ScDPLevel* pLevel) const
+{
+ if ( mpDimMembers[ nDim ] == NULL )
+ {
+
+ //long nDimSource = pDim->GetDimension();
+
+ ResultMembers* pResultMembers = new ResultMembers();
+ // global order is used to initialize aMembers, so it doesn't have to be looked at later
+ const ScMemberSortOrder& rGlobalOrder = pLevel->GetGlobalOrder();
+
+ ScDPMembers* pMembers = pLevel->GetMembersObject();
+ long nMembCount = pMembers->getCount();
+ for ( long i=0; i<nMembCount; i++ )
+ {
+ long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i];
+ ScDPMember* pMember = pMembers->getByIndex(nSorted);
+ if ( NULL == pResultMembers->FindMember( pMember->GetItemDataId() ) )
+ {
+ ScDPParentDimData* pNew = new ScDPParentDimData( i, pDim, pLevel, pMember );
+ pResultMembers->InsertMember( pNew );
+ }
+ }
+
+ mpDimMembers[ nDim ] = pResultMembers;
+ }
+ return mpDimMembers[ nDim ];
+
+}
+
+// -----------------------------------------------------------------------
+
+
+ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData ,
+ BOOL bForceSub ) :
+ pResultData( pData ),
+ aParentDimData( rParentDimData ),
+ pChildDimension( NULL ),
+ pDataRoot( NULL ),
+ bHasElements( FALSE ),
+ bForceSubTotal( bForceSub ),
+ bHasHiddenDetails( FALSE ),
+ bInitialized( FALSE ),
+ bAutoHidden( FALSE ),
+ nMemberStep( 1 )
+{
+ // pParentLevel/pMemberDesc is 0 for root members
+}
+
+ScDPResultMember::ScDPResultMember( const ScDPResultData* pData,
+ BOOL bForceSub ) :
+ pResultData( pData ),
+ pChildDimension( NULL ),
+ pDataRoot( NULL ),
+ bHasElements( FALSE ),
+ bForceSubTotal( bForceSub ),
+ bHasHiddenDetails( FALSE ),
+ bInitialized( FALSE ),
+ bAutoHidden( FALSE ),
+ nMemberStep( 1 )
+{
+}
+ScDPResultMember::~ScDPResultMember()
+{
+ delete pChildDimension;
+ delete pDataRoot;
+}
+
+String ScDPResultMember::GetName() const
+{
+ const ScDPMember* pMemberDesc = GetDPMember();
+ if (pMemberDesc)
+ return pMemberDesc->GetNameStr();
+ else
+ return ScGlobal::GetRscString(STR_PIVOT_TOTAL); // root member
+}
+
+void ScDPResultMember::FillItemData( ScDPItemData& rData ) const
+{
+ const ScDPMember* pMemberDesc = GetDPMember();
+ if (pMemberDesc)
+ pMemberDesc->FillItemData( rData );
+ else
+ rData.SetString( ScGlobal::GetRscString(STR_PIVOT_TOTAL) ); // root member
+}
+
+BOOL ScDPResultMember::IsNamedItem( SCROW nIndex ) const
+{
+ //! store ScDPMember pointer instead of ScDPMember ???
+ const ScDPMember* pMemberDesc = GetDPMember();
+ if (pMemberDesc)
+ return ((ScDPMember*)pMemberDesc)->IsNamedItem( nIndex );
+ return FALSE;
+}
+
+bool ScDPResultMember::IsValidEntry( const vector< SCROW >& aMembers ) const
+{
+ if ( !IsValid() )
+ return false;
+
+ const ScDPResultDimension* pChildDim = GetChildDimension();
+ if (pChildDim)
+ {
+ if (aMembers.size() < 2)
+ return false;
+
+ vector<SCROW>::const_iterator itr = aMembers.begin();
+ vector<SCROW> aChildMembers(++itr, aMembers.end());
+ return pChildDim->IsValidEntry(aChildMembers);
+ }
+ else
+ return true;
+}
+
+void ScDPResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev,
+ size_t nPos, ScDPInitState& rInitState ,
+ BOOL bInitChild /*= TRUE */)
+{
+ // with LateInit, initialize only those members that have data
+ if ( pResultData->IsLateInit() )
+ return;
+
+ bInitialized = TRUE;
+
+ if (nPos >= ppDim.size())
+ return;
+
+ // skip child dimension if details are not shown
+ if ( GetDPMember() && !GetDPMember()->getShowDetails() )
+ {
+ // Wang Xu Ming -- 2009-6-16
+ // Show DataLayout dimention
+ nMemberStep = 1;
+ while ( nPos < ppDim.size() )
+ {
+ if ( ppDim[nPos] ->getIsDataLayoutDimension() )
+ {
+ if ( !pChildDimension )
+ pChildDimension = new ScDPResultDimension( pResultData );
+ pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState , FALSE );
+ return;
+ }
+ else
+ { //find next dim
+ nPos ++;
+ nMemberStep ++;
+ }
+ }
+ // End Comments
+ bHasHiddenDetails = TRUE; // only if there is a next dimension
+ return;
+ }
+
+ if ( bInitChild )
+ {
+ pChildDimension = new ScDPResultDimension( pResultData );
+ pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState, TRUE );
+ }
+}
+
+void ScDPResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/,
+ const vector< SCROW >& pItemData, size_t nPos,
+ ScDPInitState& rInitState )
+{
+ // without LateInit, everything has already been initialized
+ if ( !pResultData->IsLateInit() )
+ return;
+
+ bInitialized = TRUE;
+
+ if ( rParams.IsEnd( nPos ) /*nPos >= ppDim.size()*/)
+ // No next dimension. Bail out.
+ return;
+
+ // skip child dimension if details are not shown
+ if ( GetDPMember() && !GetDPMember()->getShowDetails() )
+ {
+ // Wang Xu Ming -- 2009-6-16
+ // DataPilot Migration
+ // Show DataLayout dimention
+ nMemberStep = 1;
+ while ( !rParams.IsEnd( nPos ) )
+ {
+ if ( rParams.GetDim( nPos ) ->getIsDataLayoutDimension() )
+ {
+ if ( !pChildDimension )
+ pChildDimension = new ScDPResultDimension( pResultData );
+
+ // #i111462# reset InitChild flag only for this child dimension's LateInitFrom call,
+ // not for following members of parent dimensions
+ BOOL bWasInitChild = rParams.GetInitChild();
+ rParams.SetInitChild( FALSE );
+ pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState );
+ rParams.SetInitChild( bWasInitChild );
+ return;
+ }
+ else
+ { //find next dim
+ nPos ++;
+ nMemberStep ++;
+ }
+ }
+ // End Comments
+ bHasHiddenDetails = TRUE; // only if there is a next dimension
+ return;
+ }
+
+ // LateInitFrom is called several times...
+ if ( rParams.GetInitChild() )
+ {
+ if ( !pChildDimension )
+ pChildDimension = new ScDPResultDimension( pResultData );
+ pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState );
+ }
+}
+
+BOOL ScDPResultMember::IsSubTotalInTitle(long nMeasure) const
+{
+ BOOL bRet = FALSE;
+ if ( pChildDimension && /*pParentLevel*/GetParentLevel() &&
+ /*pParentLevel*/GetParentLevel()->IsOutlineLayout() && /*pParentLevel*/GetParentLevel()->IsSubtotalsAtTop() )
+ {
+ long nUserSubStart;
+ long nSubTotals = GetSubTotalCount( &nUserSubStart );
+ nSubTotals -= nUserSubStart; // visible count
+ if ( nSubTotals )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nSubTotals *= pResultData->GetMeasureCount(); // number of subtotals that will be inserted
+
+ // only a single subtotal row will be shown in the outline title row
+ if ( nSubTotals == 1 )
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+long ScDPResultMember::GetSize(long nMeasure) const
+{
+ if ( !IsVisible() )
+ return 0;
+ const ScDPLevel* pParentLevel = GetParentLevel();
+ long nExtraSpace = 0;
+ if ( pParentLevel && pParentLevel->IsAddEmpty() )
+ ++nExtraSpace;
+
+ if ( pChildDimension )
+ {
+ // outline layout takes up an extra row for the title only if subtotals aren't shown in that row
+ if ( pParentLevel && pParentLevel->IsOutlineLayout() && !IsSubTotalInTitle( nMeasure ) )
+ ++nExtraSpace;
+
+ long nSize = pChildDimension->GetSize(nMeasure);
+ long nUserSubStart;
+ long nUserSubCount = GetSubTotalCount( &nUserSubStart );
+ nUserSubCount -= nUserSubStart; // for output size, use visible count
+ if ( nUserSubCount )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nSize += pResultData->GetMeasureCount() * nUserSubCount;
+ else
+ nSize += nUserSubCount;
+ }
+ return nSize + nExtraSpace;
+ }
+ else
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ return pResultData->GetMeasureCount() + nExtraSpace;
+ else
+ return 1 + nExtraSpace;
+ }
+}
+
+BOOL ScDPResultMember::IsVisible() const
+{
+ // not initialized -> shouldn't be there at all
+ // (allocated only to preserve ordering)
+ const ScDPLevel* pParentLevel = GetParentLevel();
+ return ( bHasElements || ( pParentLevel && pParentLevel->getShowEmpty() ) ) && IsValid() && bInitialized;
+}
+
+BOOL ScDPResultMember::IsValid() const
+{
+ // non-Valid members are left out of calculation
+
+ // was member set no invisible at the DataPilotSource?
+ const ScDPMember* pMemberDesc =GetDPMember();
+ if ( pMemberDesc && !pMemberDesc->getIsVisible() )
+ return FALSE;
+
+ if ( bAutoHidden )
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL ScDPResultMember::HasHiddenDetails() const
+{
+ // bHasHiddenDetails is set only if the "show details" flag is off,
+ // and there was a child dimension to skip
+
+ return bHasHiddenDetails;
+}
+
+long ScDPResultMember::GetSubTotalCount( long* pUserSubStart ) const
+{
+ if ( pUserSubStart )
+ *pUserSubStart = 0; // default
+
+ const ScDPLevel* pParentLevel = GetParentLevel();
+
+ if ( bForceSubTotal ) // set if needed for root members
+ return 1; // grand total is always "automatic"
+ else if ( pParentLevel )
+ {
+ //! direct access via ScDPLevel
+
+ uno::Sequence<sheet::GeneralFunction> aSeq = pParentLevel->getSubTotals();
+ long nSequence = aSeq.getLength();
+ if ( nSequence && aSeq[0] != sheet::GeneralFunction_AUTO )
+ {
+ // For manual subtotals, always add "automatic" as first function
+ // (used for calculation, but not for display, needed for sorting, see lcl_GetForceFunc)
+
+ ++nSequence;
+ if ( pUserSubStart )
+ *pUserSubStart = 1; // visible subtotals start at 1
+ }
+ return nSequence;
+ }
+ else
+ return 0;
+}
+
+void ScDPResultMember::ProcessData( const vector< SCROW >& aChildMembers, const ScDPResultDimension* pDataDim,
+ const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues )
+{
+ SetHasElements();
+
+ if (pChildDimension)
+ pChildDimension->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues );
+
+ if ( !pDataRoot )
+ {
+ pDataRoot = new ScDPDataMember( pResultData, NULL );
+ if ( pDataDim )
+ pDataRoot->InitFrom( pDataDim ); // recursive
+ }
+
+ ScDPSubTotalState aSubState; // initial state
+
+ long nUserSubCount = GetSubTotalCount();
+
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !pChildDimension )
+ nUserSubCount = 1;
+
+ const ScDPLevel* pParentLevel = GetParentLevel();
+
+ for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
+ {
+ // #i68338# if nUserSubCount is 1 (automatic only), don't set nRowSubTotalFunc
+ if ( pChildDimension && nUserSubCount > 1 )
+ {
+ aSubState.nRowSubTotalFunc = nUserPos;
+ aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos );
+ }
+
+ pDataRoot->ProcessData( aDataMembers, aValues, aSubState );
+ }
+}
+
+/**
+ * Parse subtotal string and replace all occurrences of '?' with the caption
+ * string. Do ensure that escaped characters are not translated.
+ */
+static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption)
+{
+ String aNewStr;
+ xub_StrLen n = rSubStr.Len();
+ bool bEscaped = false;
+ for (xub_StrLen i = 0; i < n; ++i)
+ {
+ sal_Unicode c = rSubStr.GetChar(i);
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ if (!bEscaped && c == sal_Unicode('?'))
+ aNewStr.Append(rCaption);
+ else
+ aNewStr.Append(c);
+ bEscaped = false;
+ }
+ return aNewStr;
+}
+
+void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
+ long& rPos, long nMeasure, BOOL bRoot,
+ const String* pMemberName,
+ const String* pMemberCaption )
+{
+ // IsVisible() test is in ScDPResultDimension::FillMemberResults
+ // (not on data layout dimension)
+
+ long nSize = GetSize(nMeasure);
+ sheet::MemberResult* pArray = pSequences->getArray();
+ DBG_ASSERT( rPos+nSize <= pSequences->getLength(), "bumm" );
+
+ BOOL bIsNumeric = FALSE;
+ String aName;
+ if ( pMemberName ) // if pMemberName != NULL, use instead of real member name
+ aName = *pMemberName;
+ else
+ {
+ ScDPItemData aItemData;
+ FillItemData( aItemData );
+ aName = aItemData.GetString();
+ bIsNumeric = aItemData.IsValue();
+ }
+ const ScDPDimension* pParentDim = GetParentDim();
+ if ( bIsNumeric && pParentDim && pResultData->IsNumOrDateGroup( pParentDim->GetDimension() ) )
+ {
+ // Numeric group dimensions use numeric entries for proper sorting,
+ // but the group titles must be output as text.
+ bIsNumeric = FALSE;
+ }
+
+ String aCaption = aName;
+ const ScDPMember* pMemberDesc = GetDPMember();
+ if (pMemberDesc)
+ {
+ const OUString* pLayoutName = pMemberDesc->GetLayoutName();
+ if (pLayoutName)
+ {
+ aCaption = *pLayoutName;
+ bIsNumeric = false; // layout name is always non-numeric.
+ }
+ }
+
+ if ( pMemberCaption ) // use pMemberCaption if != NULL
+ aCaption = *pMemberCaption;
+ if (!aCaption.Len())
+ aCaption = ScGlobal::GetRscString(STR_EMPTYDATA);
+
+ if (bIsNumeric)
+ pArray[rPos].Flags |= sheet::MemberResultFlags::NUMERIC;
+ else
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC;
+
+ if ( nSize && !bRoot ) // root is overwritten by first dimension
+ {
+ pArray[rPos].Name = rtl::OUString(aName);
+ pArray[rPos].Caption = rtl::OUString(aCaption);
+ pArray[rPos].Flags |= sheet::MemberResultFlags::HASMEMBER;
+
+ // set "continue" flag (removed for subtotals later)
+ for (long i=1; i<nSize; i++)
+ pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE;
+ }
+
+ const ScDPLevel* pParentLevel = GetParentLevel();
+ long nExtraSpace = 0;
+ if ( pParentLevel && pParentLevel->IsAddEmpty() )
+ ++nExtraSpace;
+
+ BOOL bTitleLine = FALSE;
+ if ( pParentLevel && pParentLevel->IsOutlineLayout() )
+ bTitleLine = TRUE;
+
+ // if the subtotals are shown at the top (title row) in outline layout,
+ // no extra row for the subtotals is needed
+ BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure );
+
+ BOOL bHasChild = ( pChildDimension != NULL );
+ if (bHasChild)
+ {
+ if ( bTitleLine ) // in tabular layout the title is on a separate row
+ ++rPos; // -> fill child dimension one row below
+
+ if (bRoot) // same sequence for root member
+ pChildDimension->FillMemberResults( pSequences, rPos, nMeasure );
+ else
+ //pChildDimension->FillMemberResults( pSequences + 1, rPos, nMeasure );
+ pChildDimension->FillMemberResults( pSequences + nMemberStep/*1*/, rPos, nMeasure );
+
+ if ( bTitleLine ) // title row is included in GetSize, so the following
+ --rPos; // positions are calculated with the normal values
+ }
+
+ rPos += nSize;
+
+ long nUserSubStart;
+ long nUserSubCount = GetSubTotalCount(&nUserSubStart);
+ if ( nUserSubCount && pChildDimension && !bSubTotalInTitle )
+ {
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+
+ rPos -= nSubSize * (nUserSubCount - nUserSubStart); // GetSize includes space for SubTotal
+ rPos -= nExtraSpace; // GetSize includes the empty line
+
+ for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++)
+ {
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+
+ ScSubTotalFunc eForce = SUBTOTAL_FUNC_NONE;
+ if (bHasChild)
+ eForce = lcl_GetForceFunc( pParentLevel, nUserPos );
+
+ bool bTotalResult = false;
+ String aSubStr = aCaption;
+ aSubStr += ' ';
+ aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce, bTotalResult);
+
+ if (bTotalResult)
+ {
+ if (pMemberDesc)
+ {
+ // single data field layout.
+ const OUString* pSubtotalName = pParentDim->GetSubtotalName();
+ if (pSubtotalName)
+ aSubStr = lcl_parseSubtotalName(*pSubtotalName, aCaption);
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ else
+ {
+ // root member - subtotal (grand total?) for multi-data field layout.
+ const rtl::OUString* pGrandTotalName = pResultData->GetSource()->GetGrandTotalName();
+ if (pGrandTotalName)
+ aSubStr = *pGrandTotalName;
+ pArray[rPos].Flags |= sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ }
+
+ pArray[rPos].Name = rtl::OUString(aName);
+ pArray[rPos].Caption = rtl::OUString(aSubStr);
+ pArray[rPos].Flags = ( pArray[rPos].Flags |
+ ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL) ) &
+ ~sheet::MemberResultFlags::CONTINUE;
+
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ {
+ // data layout dimension is (direct/indirect) child of this.
+ // data layout dimension must have name for all entries.
+
+ uno::Sequence<sheet::MemberResult>* pLayoutSeq = pSequences;
+ if (!bRoot)
+ ++pLayoutSeq;
+ ScDPResultDimension* pLayoutDim = pChildDimension;
+ while ( pLayoutDim && !pLayoutDim->IsDataLayout() )
+ {
+ pLayoutDim = pLayoutDim->GetFirstChildDimension();
+ ++pLayoutSeq;
+ }
+ if ( pLayoutDim )
+ {
+ sheet::MemberResult* pLayoutArray = pLayoutSeq->getArray();
+ String aDataName = pResultData->GetMeasureDimensionName(nMemberMeasure);
+ pLayoutArray[rPos].Name = rtl::OUString(aDataName);
+ }
+ }
+
+ rPos += 1;
+ }
+ }
+
+ rPos += nExtraSpace; // add again (subtracted above)
+ }
+}
+
+void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember,
+ uno::Sequence< uno::Sequence<sheet::DataResult> >& rSequence,
+ long& rRow, long nMeasure ) const
+{
+ // IsVisible() test is in ScDPResultDimension::FillDataResults
+ // (not on data layout dimension)
+ const ScDPLevel* pParentLevel = GetParentLevel();
+ long nStartRow = rRow;
+
+ long nExtraSpace = 0;
+ if ( pParentLevel && pParentLevel->IsAddEmpty() )
+ ++nExtraSpace;
+
+ BOOL bTitleLine = FALSE;
+ if ( pParentLevel && pParentLevel->IsOutlineLayout() )
+ bTitleLine = TRUE;
+
+ BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure );
+
+ BOOL bHasChild = ( pChildDimension != NULL );
+ if (bHasChild)
+ {
+ if ( bTitleLine ) // in tabular layout the title is on a separate row
+ ++rRow; // -> fill child dimension one row below
+
+ pChildDimension->FillDataResults( pRefMember, rSequence, rRow, nMeasure ); // doesn't modify rRow
+ rRow += GetSize( nMeasure );
+
+ if ( bTitleLine ) // title row is included in GetSize, so the following
+ --rRow; // positions are calculated with the normal values
+ }
+
+ long nUserSubStart;
+ long nUserSubCount = GetSubTotalCount(&nUserSubStart);
+ if ( nUserSubCount || !bHasChild )
+ {
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !bHasChild )
+ {
+ nUserSubCount = 1;
+ nUserSubStart = 0;
+ }
+
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+ if (bHasChild)
+ {
+ rRow -= nSubSize * ( nUserSubCount - nUserSubStart ); // GetSize includes space for SubTotal
+ rRow -= nExtraSpace; // GetSize includes the empty line
+ }
+
+ long nMoveSubTotal = 0;
+ if ( bSubTotalInTitle )
+ {
+ nMoveSubTotal = rRow - nStartRow; // force to first (title) row
+ rRow = nStartRow;
+ }
+
+ if ( pDataRoot )
+ {
+ ScDPSubTotalState aSubState; // initial state
+
+ for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++)
+ {
+ if ( bHasChild && nUserSubCount > 1 )
+ {
+ aSubState.nRowSubTotalFunc = nUserPos;
+ aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos );
+ }
+
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+ else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL )
+ nMemberMeasure = SC_DPMEASURE_ALL;
+
+ DBG_ASSERT( rRow < rSequence.getLength(), "bumm" );
+ uno::Sequence<sheet::DataResult>& rSubSeq = rSequence.getArray()[rRow];
+ long nSeqCol = 0;
+ pDataRoot->FillDataRow( pRefMember, rSubSeq, nSeqCol, nMemberMeasure, bHasChild, aSubState );
+
+ rRow += 1;
+ }
+ }
+ }
+ else
+ rRow += nSubSize * ( nUserSubCount - nUserSubStart ); // empty rows occur when ShowEmpty is true
+
+ // add extra space again if subtracted from GetSize above,
+ // add to own size if no children
+ rRow += nExtraSpace;
+
+ rRow += nMoveSubTotal;
+ }
+}
+
+void ScDPResultMember::UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const
+{
+ // IsVisible() test is in ScDPResultDimension::FillDataResults
+ // (not on data layout dimension)
+
+ BOOL bHasChild = ( pChildDimension != NULL );
+
+ long nUserSubCount = GetSubTotalCount();
+ // process subtotals even if not shown
+// if ( nUserSubCount || !bHasChild )
+ {
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !bHasChild )
+ nUserSubCount = 1;
+
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+
+ if ( pDataRoot )
+ {
+ ScDPSubTotalState aSubState; // initial state
+
+ for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
+ {
+ if ( bHasChild && nUserSubCount > 1 )
+ {
+ aSubState.nRowSubTotalFunc = nUserPos;
+ aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos );
+ }
+
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+ else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL )
+ nMemberMeasure = SC_DPMEASURE_ALL;
+
+ pDataRoot->UpdateDataRow( pRefMember, nMemberMeasure, bHasChild, aSubState );
+ }
+ }
+ }
+ }
+
+ if (bHasChild) // child dimension must be processed last, so the column total is known
+ {
+ pChildDimension->UpdateDataResults( pRefMember, nMeasure );
+ }
+}
+
+void ScDPResultMember::SortMembers( ScDPResultMember* pRefMember )
+{
+ BOOL bHasChild = ( pChildDimension != NULL );
+ if (bHasChild)
+ pChildDimension->SortMembers( pRefMember ); // sorting is done at the dimension
+
+ if ( IsRoot() && pDataRoot )
+ {
+ // use the row root member to sort columns
+ // sub total count is always 1
+
+ pDataRoot->SortMembers( pRefMember );
+ }
+}
+
+void ScDPResultMember::DoAutoShow( ScDPResultMember* pRefMember )
+{
+ BOOL bHasChild = ( pChildDimension != NULL );
+ if (bHasChild)
+ pChildDimension->DoAutoShow( pRefMember ); // sorting is done at the dimension
+
+ if ( IsRoot()&& pDataRoot )
+ {
+ // use the row root member to sort columns
+ // sub total count is always 1
+
+ pDataRoot->DoAutoShow( pRefMember );
+ }
+}
+
+void ScDPResultMember::ResetResults( BOOL /*bRoot*/ )
+{
+ if (pDataRoot)
+ pDataRoot->ResetResults();
+
+ if (pChildDimension)
+ pChildDimension->ResetResults();
+
+ // if (!bRoot)
+ // bHasElements = FALSE;
+}
+
+void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure,
+ ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const
+{
+ // IsVisible() test is in ScDPResultDimension::FillDataResults
+ // (not on data layout dimension)
+
+ rTotals.SetInColRoot( IsRoot() );
+
+ BOOL bHasChild = ( pChildDimension != NULL );
+
+ long nUserSubCount = GetSubTotalCount();
+ //if ( nUserSubCount || !bHasChild )
+ {
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !bHasChild )
+ nUserSubCount = 1;
+
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+
+ if ( pDataRoot )
+ {
+ ScDPSubTotalState aSubState; // initial state
+
+ for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
+ {
+ if ( bHasChild && nUserSubCount > 1 )
+ {
+ aSubState.nRowSubTotalFunc = nUserPos;
+ aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel(), nUserPos );
+ }
+
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+ else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL )
+ nMemberMeasure = SC_DPMEASURE_ALL;
+
+ pDataRoot->UpdateRunningTotals( pRefMember, nMemberMeasure,
+ bHasChild, aSubState, rRunning, rTotals, *this );
+ }
+ }
+ }
+ }
+
+ if (bHasChild) // child dimension must be processed last, so the column total is known
+ {
+ pChildDimension->UpdateRunningTotals( pRefMember, nMeasure, rRunning, rTotals );
+ }
+}
+
+void ScDPResultMember::DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const
+{
+ lcl_DumpRow( String::CreateFromAscii("ScDPResultMember"), GetName(), NULL, pDoc, rPos );
+ SCROW nStartRow = rPos.Row();
+
+ if (pDataRoot)
+ pDataRoot->DumpState( pRefMember, pDoc, rPos );
+
+ if (pChildDimension)
+ pChildDimension->DumpState( pRefMember, pDoc, rPos );
+
+ lcl_Indent( pDoc, nStartRow, rPos );
+}
+
+ScDPAggData* ScDPResultMember::GetColTotal( long nMeasure ) const
+{
+ return lcl_GetChildTotal( const_cast<ScDPAggData*>(&aColTotal), nMeasure );
+}
+
+void ScDPResultMember::FillVisibilityData(ScDPResultVisibilityData& rData) const
+{
+ if (pChildDimension)
+ pChildDimension->FillVisibilityData(rData);
+}
+
+// -----------------------------------------------------------------------
+
+ScDPDataMember::ScDPDataMember( const ScDPResultData* pData, const ScDPResultMember* pRes ) :
+ pResultData( pData ),
+ pResultMember( pRes ),
+ pChildDimension( NULL )
+{
+ // pResultMember is 0 for root members
+}
+
+ScDPDataMember::~ScDPDataMember()
+{
+ delete pChildDimension;
+}
+
+String ScDPDataMember::GetName() const
+{
+ if (pResultMember)
+ return pResultMember->GetName();
+ else
+ return EMPTY_STRING;
+}
+
+BOOL ScDPDataMember::IsVisible() const
+{
+ if (pResultMember)
+ return pResultMember->IsVisible();
+ else
+ return FALSE;
+}
+
+BOOL ScDPDataMember::IsNamedItem( /*const ScDPItemData& r*/SCROW r ) const
+{
+ if (pResultMember)
+ return pResultMember->IsNamedItem(r);
+ else
+ return FALSE;
+}
+
+BOOL ScDPDataMember::HasHiddenDetails() const
+{
+ if (pResultMember)
+ return pResultMember->HasHiddenDetails();
+ else
+ return FALSE;
+}
+
+void ScDPDataMember::InitFrom( const ScDPResultDimension* pDim )
+{
+ if ( !pChildDimension )
+ pChildDimension = new ScDPDataDimension(pResultData);
+ pChildDimension->InitFrom(pDim);
+}
+
+const long SC_SUBTOTALPOS_AUTO = -1; // default
+const long SC_SUBTOTALPOS_SKIP = -2; // don't use
+
+long lcl_GetSubTotalPos( const ScDPSubTotalState& rSubState )
+{
+ if ( rSubState.nColSubTotalFunc >= 0 && rSubState.nRowSubTotalFunc >= 0 &&
+ rSubState.nColSubTotalFunc != rSubState.nRowSubTotalFunc )
+ {
+ // #i68338# don't return the same index for different combinations (leading to repeated updates),
+ // return a "don't use" value instead
+
+ return SC_SUBTOTALPOS_SKIP;
+ }
+
+ long nRet = SC_SUBTOTALPOS_AUTO;
+ if ( rSubState.nColSubTotalFunc >= 0 ) nRet = rSubState.nColSubTotalFunc;
+ if ( rSubState.nRowSubTotalFunc >= 0 ) nRet = rSubState.nRowSubTotalFunc;
+ return nRet;
+}
+
+void ScDPDataMember::UpdateValues( const vector<ScDPValueData>& aValues, const ScDPSubTotalState& rSubState )
+{
+ //! find out how many and which subtotals are used
+
+ ScDPAggData* pAgg = &aAggregate;
+
+ long nSubPos = lcl_GetSubTotalPos(rSubState);
+ if (nSubPos == SC_SUBTOTALPOS_SKIP)
+ return;
+ if (nSubPos > 0)
+ {
+ long nSkip = nSubPos * pResultData->GetMeasureCount();
+ for (long i=0; i<nSkip; i++)
+ pAgg = pAgg->GetChild(); // created if not there
+ }
+
+ size_t nCount = aValues.size();
+ for (size_t nPos = 0; nPos < nCount; ++nPos)
+ {
+ pAgg->Update(aValues[nPos], pResultData->GetMeasureFunction(nPos), rSubState);
+ pAgg = pAgg->GetChild();
+ }
+}
+
+void ScDPDataMember::ProcessData( const vector< SCROW >& aChildMembers, const vector<ScDPValueData>& aValues,
+ const ScDPSubTotalState& rSubState )
+{
+ if ( pResultData->IsLateInit() && !pChildDimension && pResultMember && pResultMember->GetChildDimension() )
+ {
+ // if this DataMember doesn't have a child dimension because the ResultMember's
+ // child dimension wasn't there yet during this DataMembers's creation,
+ // create the child dimension now
+ InitFrom( pResultMember->GetChildDimension() );
+ }
+
+ ScDPSubTotalState aLocalSubState(rSubState); // keep row state, modify column
+
+ long nUserSubCount = pResultMember ? pResultMember->GetSubTotalCount() : 0;
+
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !pChildDimension )
+ nUserSubCount = 1;
+
+ for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
+ {
+ if ( pChildDimension && nUserSubCount > 1 )
+ {
+ const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+ aLocalSubState.nColSubTotalFunc = nUserPos;
+ aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
+ }
+
+ UpdateValues( aValues, aLocalSubState );
+ }
+
+ if (pChildDimension)
+ pChildDimension->ProcessData( aChildMembers, aValues, rSubState ); // with unmodified subtotal state
+}
+
+BOOL ScDPDataMember::HasData( long nMeasure, const ScDPSubTotalState& rSubState ) const
+{
+ if ( rSubState.eColForce != SUBTOTAL_FUNC_NONE && rSubState.eRowForce != SUBTOTAL_FUNC_NONE &&
+ rSubState.eColForce != rSubState.eRowForce )
+ return FALSE;
+
+ // #74542# HasData can be different between measures!
+
+ const ScDPAggData* pAgg = GetConstAggData( nMeasure, rSubState );
+ if (!pAgg)
+ return FALSE; //! error?
+
+ return pAgg->HasData();
+}
+
+BOOL ScDPDataMember::HasError( long nMeasure, const ScDPSubTotalState& rSubState ) const
+{
+ const ScDPAggData* pAgg = GetConstAggData( nMeasure, rSubState );
+ if (!pAgg)
+ return TRUE;
+
+ return pAgg->HasError();
+}
+
+double ScDPDataMember::GetAggregate( long nMeasure, const ScDPSubTotalState& rSubState ) const
+{
+ const ScDPAggData* pAgg = GetConstAggData( nMeasure, rSubState );
+ if (!pAgg)
+ return DBL_MAX; //! error?
+
+ return pAgg->GetResult();
+}
+
+ScDPAggData* ScDPDataMember::GetAggData( long nMeasure, const ScDPSubTotalState& rSubState )
+{
+ DBG_ASSERT( nMeasure >= 0, "GetAggData: no measure" );
+
+ ScDPAggData* pAgg = &aAggregate;
+ long nSkip = nMeasure;
+ long nSubPos = lcl_GetSubTotalPos(rSubState);
+ if (nSubPos == SC_SUBTOTALPOS_SKIP)
+ return NULL;
+ if (nSubPos > 0)
+ nSkip += nSubPos * pResultData->GetMeasureCount();
+
+ for ( long nPos=0; nPos<nSkip; nPos++ )
+ pAgg = pAgg->GetChild(); //! need to create children here?
+
+ return pAgg;
+}
+
+const ScDPAggData* ScDPDataMember::GetConstAggData( long nMeasure, const ScDPSubTotalState& rSubState ) const
+{
+ DBG_ASSERT( nMeasure >= 0, "GetConstAggData: no measure" );
+
+ const ScDPAggData* pAgg = &aAggregate;
+ long nSkip = nMeasure;
+ long nSubPos = lcl_GetSubTotalPos(rSubState);
+ if (nSubPos == SC_SUBTOTALPOS_SKIP)
+ return NULL;
+ if (nSubPos > 0)
+ nSkip += nSubPos * pResultData->GetMeasureCount();
+
+ for ( long nPos=0; nPos<nSkip; nPos++ )
+ {
+ pAgg = pAgg->GetExistingChild();
+ if (!pAgg)
+ return NULL;
+ }
+
+ return pAgg;
+}
+
+void ScDPDataMember::FillDataRow( const ScDPResultMember* pRefMember,
+ uno::Sequence<sheet::DataResult>& rSequence,
+ long& rCol, long nMeasure, BOOL bIsSubTotalRow,
+ const ScDPSubTotalState& rSubState ) const
+{
+ DBG_ASSERT( pRefMember == pResultMember || !pResultMember, "bla" );
+
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataDimension::FillDataRow ???
+ {
+ long nStartCol = rCol;
+
+ const ScDPDataDimension* pDataChild = GetChildDimension();
+ const ScDPResultDimension* pRefChild = pRefMember->GetChildDimension();
+
+ const ScDPLevel* pRefParentLevel = const_cast<ScDPResultMember*>(pRefMember)->GetParentLevel();
+
+ long nExtraSpace = 0;
+ if ( pRefParentLevel && pRefParentLevel->IsAddEmpty() )
+ ++nExtraSpace;
+
+ BOOL bTitleLine = FALSE;
+ if ( pRefParentLevel && pRefParentLevel->IsOutlineLayout() )
+ bTitleLine = TRUE;
+
+ BOOL bSubTotalInTitle = pRefMember->IsSubTotalInTitle( nMeasure );
+
+ // leave space for children even if the DataMember hasn't been initialized
+ // (pDataChild is null then, this happens when no values for it are in this row)
+ BOOL bHasChild = ( pRefChild != NULL );
+
+ if ( bHasChild )
+ {
+ if ( bTitleLine ) // in tabular layout the title is on a separate column
+ ++rCol; // -> fill child dimension one column below
+
+ if ( pDataChild )
+ pDataChild->FillDataRow( pRefChild, rSequence, rCol, nMeasure, bIsSubTotalRow, rSubState );
+ rCol += (USHORT)pRefMember->GetSize( nMeasure );
+
+ if ( bTitleLine ) // title column is included in GetSize, so the following
+ --rCol; // positions are calculated with the normal values
+ }
+
+ long nUserSubStart;
+ long nUserSubCount = pRefMember->GetSubTotalCount(&nUserSubStart);
+ if ( nUserSubCount || !bHasChild )
+ {
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !bHasChild )
+ {
+ nUserSubCount = 1;
+ nUserSubStart = 0;
+ }
+
+ ScDPSubTotalState aLocalSubState(rSubState); // keep row state, modify column
+
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+ if (bHasChild)
+ {
+ rCol -= nSubSize * ( nUserSubCount - nUserSubStart ); // GetSize includes space for SubTotal
+ rCol -= nExtraSpace; // GetSize includes the empty line
+ }
+
+ long nMoveSubTotal = 0;
+ if ( bSubTotalInTitle )
+ {
+ nMoveSubTotal = rCol - nStartCol; // force to first (title) column
+ rCol = nStartCol;
+ }
+
+ for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++)
+ {
+ if ( pChildDimension && nUserSubCount > 1 )
+ {
+ const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+ aLocalSubState.nColSubTotalFunc = nUserPos;
+ aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
+ }
+
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+
+ DBG_ASSERT( rCol < rSequence.getLength(), "bumm" );
+ sheet::DataResult& rRes = rSequence.getArray()[rCol];
+
+ if ( HasData( nMemberMeasure, aLocalSubState ) )
+ {
+ if ( HasError( nMemberMeasure, aLocalSubState ) )
+ {
+ rRes.Value = 0;
+ rRes.Flags |= sheet::DataResultFlags::ERROR;
+ }
+ else
+ {
+ rRes.Value = GetAggregate( nMemberMeasure, aLocalSubState );
+ rRes.Flags |= sheet::DataResultFlags::HASDATA;
+ }
+ }
+
+ if ( bHasChild || bIsSubTotalRow )
+ rRes.Flags |= sheet::DataResultFlags::SUBTOTAL;
+
+ rCol += 1;
+ }
+ }
+
+ // add extra space again if subtracted from GetSize above,
+ // add to own size if no children
+ rCol += nExtraSpace;
+
+ rCol += nMoveSubTotal;
+ }
+ }
+}
+
+void ScDPDataMember::UpdateDataRow( const ScDPResultMember* pRefMember,
+ long nMeasure, BOOL bIsSubTotalRow,
+ const ScDPSubTotalState& rSubState )
+{
+ DBG_ASSERT( pRefMember == pResultMember || !pResultMember, "bla" );
+
+ // Calculate must be called even if not visible (for use as reference value)
+ const ScDPDataDimension* pDataChild = GetChildDimension();
+ const ScDPResultDimension* pRefChild = pRefMember->GetChildDimension();
+
+ // leave space for children even if the DataMember hasn't been initialized
+ // (pDataChild is null then, this happens when no values for it are in this row)
+ BOOL bHasChild = ( pRefChild != NULL );
+
+ // process subtotals even if not shown
+ long nUserSubCount = pRefMember->GetSubTotalCount();
+
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !bHasChild )
+ nUserSubCount = 1;
+
+ ScDPSubTotalState aLocalSubState(rSubState); // keep row state, modify column
+
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+
+ for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
+ {
+ if ( pChildDimension && nUserSubCount > 1 )
+ {
+ const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+ aLocalSubState.nColSubTotalFunc = nUserPos;
+ aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
+ }
+
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+
+ // update data...
+ ScDPAggData* pAggData = GetAggData( nMemberMeasure, aLocalSubState );
+ if (pAggData)
+ {
+ //! aLocalSubState?
+ ScSubTotalFunc eFunc = pResultData->GetMeasureFunction( nMemberMeasure );
+ sheet::DataPilotFieldReference aReferenceValue = pResultData->GetMeasureRefVal( nMemberMeasure );
+ sal_Int32 eRefType = aReferenceValue.ReferenceType;
+
+ // calculate the result first - for all members, regardless of reference value
+ pAggData->Calculate( eFunc, aLocalSubState );
+
+ if ( eRefType == sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE )
+ {
+ // copy the result into auxiliary value, so differences can be
+ // calculated in any order
+ pAggData->SetAuxiliary( pAggData->GetResult() );
+ }
+ // column/row percentage/index is now in UpdateRunningTotals, so it doesn't disturb sorting
+ }
+ }
+ }
+
+ if ( bHasChild ) // child dimension must be processed last, so the row total is known
+ {
+ if ( pDataChild )
+ pDataChild->UpdateDataRow( pRefChild, nMeasure, bIsSubTotalRow, rSubState );
+ }
+}
+
+void ScDPDataMember::SortMembers( ScDPResultMember* pRefMember )
+{
+ DBG_ASSERT( pRefMember == pResultMember || !pResultMember, "bla" );
+
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataDimension ???
+ {
+ ScDPDataDimension* pDataChild = GetChildDimension();
+ ScDPResultDimension* pRefChild = pRefMember->GetChildDimension();
+ if ( pRefChild && pDataChild )
+ pDataChild->SortMembers( pRefChild ); // sorting is done at the dimension
+ }
+}
+
+void ScDPDataMember::DoAutoShow( ScDPResultMember* pRefMember )
+{
+ DBG_ASSERT( pRefMember == pResultMember || !pResultMember, "bla" );
+
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataDimension ???
+ {
+ ScDPDataDimension* pDataChild = GetChildDimension();
+ ScDPResultDimension* pRefChild = pRefMember->GetChildDimension();
+ if ( pRefChild && pDataChild )
+ pDataChild->DoAutoShow( pRefChild ); // sorting is done at the dimension
+ }
+}
+
+void ScDPDataMember::ResetResults()
+{
+ aAggregate.Reset();
+
+ ScDPDataDimension* pDataChild = GetChildDimension();
+ if ( pDataChild )
+ pDataChild->ResetResults();
+}
+
+void ScDPDataMember::UpdateRunningTotals( const ScDPResultMember* pRefMember,
+ long nMeasure, BOOL bIsSubTotalRow,
+ const ScDPSubTotalState& rSubState, ScDPRunningTotalState& rRunning,
+ ScDPRowTotals& rTotals, const ScDPResultMember& rRowParent )
+{
+ DBG_ASSERT( pRefMember == pResultMember || !pResultMember, "bla" );
+
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataDimension::UpdateRunningTotals ???
+ {
+ const ScDPDataDimension* pDataChild = GetChildDimension();
+ const ScDPResultDimension* pRefChild = pRefMember->GetChildDimension();
+
+ BOOL bIsRoot = ( pResultMember == NULL || pResultMember->GetParentLevel() == NULL );
+
+ // leave space for children even if the DataMember hasn't been initialized
+ // (pDataChild is null then, this happens when no values for it are in this row)
+ BOOL bHasChild = ( pRefChild != NULL );
+
+ long nUserSubCount = pRefMember->GetSubTotalCount();
+ //if ( nUserSubCount || !bHasChild )
+ {
+ // Calculate at least automatic if no subtotals are selected,
+ // show only own values if there's no child dimension (innermost).
+ if ( !nUserSubCount || !bHasChild )
+ nUserSubCount = 1;
+
+ ScDPSubTotalState aLocalSubState(rSubState); // keep row state, modify column
+
+ long nMemberMeasure = nMeasure;
+ long nSubSize = pResultData->GetCountForMeasure(nMeasure);
+
+ for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
+ {
+ if ( pChildDimension && nUserSubCount > 1 )
+ {
+ const ScDPLevel* pForceLevel = pResultMember ? pResultMember->GetParentLevel() : NULL;
+ aLocalSubState.nColSubTotalFunc = nUserPos;
+ aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
+ }
+
+ for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
+ {
+ if ( nMeasure == SC_DPMEASURE_ALL )
+ nMemberMeasure = nSubCount;
+
+ // update data...
+ ScDPAggData* pAggData = GetAggData( nMemberMeasure, aLocalSubState );
+ if (pAggData)
+ {
+ //! aLocalSubState?
+ sheet::DataPilotFieldReference aReferenceValue = pResultData->GetMeasureRefVal( nMemberMeasure );
+ sal_Int32 eRefType = aReferenceValue.ReferenceType;
+
+ if ( eRefType == sheet::DataPilotFieldReferenceType::RUNNING_TOTAL ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE )
+ {
+ BOOL bRunningTotal = ( eRefType == sheet::DataPilotFieldReferenceType::RUNNING_TOTAL );
+ BOOL bRelative =
+ ( aReferenceValue.ReferenceItemType != sheet::DataPilotFieldReferenceItemType::NAMED && !bRunningTotal );
+ long nRelativeDir = bRelative ?
+ ( ( aReferenceValue.ReferenceItemType == sheet::DataPilotFieldReferenceItemType::PREVIOUS ) ? -1 : 1 ) : 0;
+
+ const long* pColVisible = rRunning.GetColVisible();
+ const long* pColIndexes = rRunning.GetColIndexes();
+ const long* pRowVisible = rRunning.GetRowVisible();
+ const long* pRowIndexes = rRunning.GetRowIndexes();
+
+ String aRefFieldName = aReferenceValue.ReferenceField;
+
+ //! aLocalSubState?
+ USHORT nRefOrient = pResultData->GetMeasureRefOrient( nMemberMeasure );
+ BOOL bRefDimInCol = ( nRefOrient == sheet::DataPilotFieldOrientation_COLUMN );
+ BOOL bRefDimInRow = ( nRefOrient == sheet::DataPilotFieldOrientation_ROW );
+
+ const ScDPResultDimension* pSelectDim = NULL;
+ long nRowPos = 0;
+ long nColPos = 0;
+
+ //
+ // find the reference field in column or row dimensions
+ //
+
+ if ( bRefDimInRow ) // look in row dimensions
+ {
+ pSelectDim = rRunning.GetRowResRoot()->GetChildDimension();
+ while ( pSelectDim && pSelectDim->GetName() != aRefFieldName )
+ {
+ long nIndex = pRowIndexes[nRowPos];
+ if ( nIndex >= 0 && nIndex < pSelectDim->GetMemberCount() )
+ pSelectDim = pSelectDim->GetMember(nIndex)->GetChildDimension();
+ else
+ pSelectDim = NULL;
+ ++nRowPos;
+ }
+ // child dimension of innermost member?
+ if ( pSelectDim && pRowIndexes[nRowPos] < 0 )
+ pSelectDim = NULL;
+ }
+
+ if ( bRefDimInCol ) // look in column dimensions
+ {
+ pSelectDim = rRunning.GetColResRoot()->GetChildDimension();
+ while ( pSelectDim && pSelectDim->GetName() != aRefFieldName )
+ {
+ long nIndex = pColIndexes[nColPos];
+ if ( nIndex >= 0 && nIndex < pSelectDim->GetMemberCount() )
+ pSelectDim = pSelectDim->GetMember(nIndex)->GetChildDimension();
+ else
+ pSelectDim = NULL;
+ ++nColPos;
+ }
+ // child dimension of innermost member?
+ if ( pSelectDim && pColIndexes[nColPos] < 0 )
+ pSelectDim = NULL;
+ }
+
+ BOOL bNoDetailsInRef = FALSE;
+ if ( pSelectDim && bRunningTotal )
+ {
+ // Running totals:
+ // If details are hidden for this member in the reference dimension,
+ // don't show or sum up the value. Otherwise, for following members,
+ // the running totals of details and subtotals wouldn't match.
+
+ long nMyIndex = bRefDimInCol ? pColIndexes[nColPos] : pRowIndexes[nRowPos];
+ if ( nMyIndex >= 0 && nMyIndex < pSelectDim->GetMemberCount() )
+ {
+ const ScDPResultMember* pMyRefMember = pSelectDim->GetMember(nMyIndex);
+ if ( pMyRefMember && pMyRefMember->HasHiddenDetails() )
+ {
+ pSelectDim = NULL; // don't calculate
+ bNoDetailsInRef = TRUE; // show error, not empty
+ }
+ }
+ }
+
+ if ( bRelative )
+ {
+ // Difference/Percentage from previous/next:
+ // If details are hidden for this member in the innermost column/row
+ // dimension (the orientation of the reference dimension), show an
+ // error value.
+ // - If the no-details dimension is the reference dimension, its
+ // members will be skipped when finding the previous/next member,
+ // so there must be no results for its members.
+ // - If the no-details dimension is outside of the reference dimension,
+ // no calculation in the reference dimension is possible.
+ // - Otherwise, the error isn't strictly necessary, but shown for
+ // consistency.
+
+ BOOL bInnerNoDetails = bRefDimInCol ? HasHiddenDetails() :
+ ( bRefDimInRow ? rRowParent.HasHiddenDetails() : TRUE );
+ if ( bInnerNoDetails )
+ {
+ pSelectDim = NULL;
+ bNoDetailsInRef = TRUE; // show error, not empty
+ }
+ }
+
+ if ( !bRefDimInCol && !bRefDimInRow ) // invalid dimension specified
+ bNoDetailsInRef = TRUE; // pSelectDim is then already NULL
+
+ //
+ // get the member for the reference item and do the calculation
+ //
+
+ if ( bRunningTotal )
+ {
+ // running total in (dimension) -> find first existing member
+
+ if ( pSelectDim )
+ {
+ ScDPDataMember* pSelectMember;
+ if ( bRefDimInCol )
+ pSelectMember = ScDPResultDimension::GetColReferenceMember( NULL, NULL,
+ nColPos, rRunning );
+ else
+ {
+ long nSkip = nRowPos + 1; // including the reference dimension
+ pSelectMember = pSelectDim->GetRowReferenceMember( NULL, NULL,
+ pRowIndexes+nSkip, pColIndexes );
+ }
+
+ if ( pSelectMember )
+ {
+ // The running total is kept as the auxiliary value in
+ // the first available member for the reference dimension.
+ // Members are visited in final order, so each one's result
+ // can be used and then modified.
+
+ ScDPAggData* pSelectData = pSelectMember->
+ GetAggData( nMemberMeasure, aLocalSubState );
+ if ( pSelectData )
+ {
+ double fTotal = pSelectData->GetAuxiliary();
+ fTotal += pAggData->GetResult();
+ pSelectData->SetAuxiliary( fTotal );
+ pAggData->SetResult( fTotal );
+ pAggData->SetEmpty(FALSE); // always display
+ }
+ }
+ else
+ pAggData->SetError();
+ }
+ else if (bNoDetailsInRef)
+ pAggData->SetError();
+ else
+ pAggData->SetEmpty(TRUE); // empty (dim set to 0 above)
+ }
+ else
+ {
+ // difference/percentage -> find specified member
+
+ if ( pSelectDim )
+ {
+ String aRefItemName = aReferenceValue.ReferenceItemName;
+ ScDPRelativePos aRefItemPos( 0, nRelativeDir ); // nBasePos is modified later
+
+ const String* pRefName = NULL;
+ const ScDPRelativePos* pRefPos = NULL;
+ if ( bRelative )
+ pRefPos = &aRefItemPos;
+ else
+ pRefName = &aRefItemName;
+
+ ScDPDataMember* pSelectMember;
+ if ( bRefDimInCol )
+ {
+ aRefItemPos.nBasePos = pColVisible[nColPos]; // without sort order applied
+ pSelectMember = ScDPResultDimension::GetColReferenceMember( pRefPos, pRefName,
+ nColPos, rRunning );
+ }
+ else
+ {
+ aRefItemPos.nBasePos = pRowVisible[nRowPos]; // without sort order applied
+ long nSkip = nRowPos + 1; // including the reference dimension
+ pSelectMember = pSelectDim->GetRowReferenceMember( pRefPos, pRefName,
+ pRowIndexes+nSkip, pColIndexes );
+ }
+
+ // difference or perc.difference is empty for the reference item itself
+ if ( pSelectMember == this &&
+ eRefType != sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE )
+ {
+ pAggData->SetEmpty(TRUE);
+ }
+ else if ( pSelectMember )
+ {
+ const ScDPAggData* pOtherAggData = pSelectMember->
+ GetConstAggData( nMemberMeasure, aLocalSubState );
+ DBG_ASSERT( pOtherAggData, "no agg data" );
+ if ( pOtherAggData )
+ {
+ // Reference member may be visited before or after this one,
+ // so the auxiliary value is used for the original result.
+
+ double fOtherResult = pOtherAggData->GetAuxiliary();
+ double fThisResult = pAggData->GetResult();
+ BOOL bError = FALSE;
+ switch ( eRefType )
+ {
+ case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE:
+ fThisResult = fThisResult - fOtherResult;
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE:
+ if ( fOtherResult == 0.0 )
+ bError = TRUE;
+ else
+ fThisResult = fThisResult / fOtherResult;
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
+ if ( fOtherResult == 0.0 )
+ bError = TRUE;
+ else
+ fThisResult = ( fThisResult - fOtherResult ) / fOtherResult;
+ break;
+ default:
+ DBG_ERROR("invalid calculation type");
+ }
+ if ( bError )
+ {
+ pAggData->SetError();
+ }
+ else
+ {
+ pAggData->SetResult(fThisResult);
+ pAggData->SetEmpty(FALSE); // always display
+ }
+ //! errors in data?
+ }
+ }
+ else if (bRelative && !bNoDetailsInRef)
+ pAggData->SetEmpty(TRUE); // empty
+ else
+ pAggData->SetError(); // error
+ }
+ else if (bNoDetailsInRef)
+ pAggData->SetError(); // error
+ else
+ pAggData->SetEmpty(TRUE); // empty
+ }
+ }
+ else if ( eRefType == sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE ||
+ eRefType == sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE ||
+ eRefType == sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE ||
+ eRefType == sheet::DataPilotFieldReferenceType::INDEX )
+ {
+ //
+ // set total values when they are encountered (always before their use)
+ //
+
+ ScDPAggData* pColTotalData = pRefMember->GetColTotal( nMemberMeasure );
+ ScDPAggData* pRowTotalData = rTotals.GetRowTotal( nMemberMeasure );
+ ScDPAggData* pGrandTotalData = rTotals.GetGrandTotal( nMemberMeasure );
+
+ double fTotalValue = pAggData->HasError() ? 0 : pAggData->GetResult();
+
+ if ( bIsRoot && rTotals.IsInColRoot() && pGrandTotalData )
+ pGrandTotalData->SetAuxiliary( fTotalValue );
+
+ if ( bIsRoot && pRowTotalData )
+ pRowTotalData->SetAuxiliary( fTotalValue );
+
+ if ( rTotals.IsInColRoot() && pColTotalData )
+ pColTotalData->SetAuxiliary( fTotalValue );
+
+ //
+ // find relation to total values
+ //
+
+ switch ( eRefType )
+ {
+ case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE:
+ case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE:
+ case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE:
+ {
+ double nTotal;
+ if ( eRefType == sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE )
+ nTotal = pRowTotalData->GetAuxiliary();
+ else if ( eRefType == sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE )
+ nTotal = pColTotalData->GetAuxiliary();
+ else
+ nTotal = pGrandTotalData->GetAuxiliary();
+
+ if ( nTotal == 0.0 )
+ pAggData->SetError();
+ else
+ pAggData->SetResult( pAggData->GetResult() / nTotal );
+ }
+ break;
+ case sheet::DataPilotFieldReferenceType::INDEX:
+ {
+ double nColTotal = pColTotalData->GetAuxiliary();
+ double nRowTotal = pRowTotalData->GetAuxiliary();
+ double nGrandTotal = pGrandTotalData->GetAuxiliary();
+ if ( nRowTotal == 0.0 || nColTotal == 0.0 )
+ pAggData->SetError();
+ else
+ pAggData->SetResult(
+ ( pAggData->GetResult() * nGrandTotal ) /
+ ( nRowTotal * nColTotal ) );
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( bHasChild ) // child dimension must be processed last, so the row total is known
+ {
+ if ( pDataChild )
+ pDataChild->UpdateRunningTotals( pRefChild, nMeasure,
+ bIsSubTotalRow, rSubState, rRunning, rTotals, rRowParent );
+ }
+ }
+}
+
+void ScDPDataMember::DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const
+{
+ lcl_DumpRow( String::CreateFromAscii("ScDPDataMember"), GetName(), &aAggregate, pDoc, rPos );
+ SCROW nStartRow = rPos.Row();
+
+ const ScDPDataDimension* pDataChild = GetChildDimension();
+ const ScDPResultDimension* pRefChild = pRefMember->GetChildDimension();
+ if ( pDataChild && pRefChild )
+ pDataChild->DumpState( pRefChild, pDoc, rPos );
+
+ lcl_Indent( pDoc, nStartRow, rPos );
+}
+
+// -----------------------------------------------------------------------
+
+// Helper class to select the members to include in
+// ScDPResultDimension::InitFrom or LateInitFrom if groups are used
+
+class ScDPGroupCompare
+{
+private:
+ const ScDPResultData* pResultData;
+ const ScDPInitState& rInitState;
+ long nDimSource;
+ BOOL bIncludeAll;
+ BOOL bIsBase;
+ long nGroupBase;
+ // Wang Xu Ming -- 2009-8-6
+ // DataPilot Migration - Cache&&Performance
+ SCROW nBaseDataId;
+ // End Comments
+public:
+ ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitState& rState, long nDimension );
+ ~ScDPGroupCompare() {}
+
+ BOOL IsIncluded( const ScDPMember& rMember ) { return bIncludeAll || TestIncluded( rMember ); }
+ BOOL TestIncluded( const ScDPMember& rMember );
+};
+
+ScDPGroupCompare::ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitState& rState, long nDimension ) :
+ pResultData( pData ),
+ rInitState( rState ),
+ nDimSource( nDimension ),
+ nBaseDataId( -1 )
+{
+ bIsBase = pResultData->IsBaseForGroup( nDimSource );
+ nGroupBase = pResultData->GetGroupBase( nDimSource ); //! get together in one call?
+ if ( nGroupBase >= 0 )
+ nBaseDataId = rInitState.GetNameIdForIndex( nGroupBase );
+
+ // if bIncludeAll is set, TestIncluded doesn't need to be called
+ bIncludeAll = !( bIsBase || nGroupBase >= 0 );
+}
+
+BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember )
+{
+ BOOL bInclude = TRUE;
+ if ( nBaseDataId >=0 )
+ {
+ ScDPItemData aMemberData;
+ rMember.FillItemData( aMemberData );
+ bInclude = pResultData->IsInGroup( aMemberData, nDimSource, nBaseDataId, nGroupBase );
+ }
+ else if ( bIsBase )
+ {
+ // need to check all previous groups
+ //! get array of groups (or indexes) before loop?
+ ScDPItemData aMemberData;
+ rMember.FillItemData( aMemberData );
+ long nInitCount = rInitState.GetCount();
+ const long* pInitSource = rInitState.GetSource();
+ /*const ScDPItemData* pInitNames = rInitState.GetNames();*/
+ const SCROW* pInitNames = rInitState.GetNameIds();
+ for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++)
+ if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nDimSource )
+ {
+ bInclude = pResultData->IsInGroup( pInitNames[nInitPos], pInitSource[nInitPos],
+ aMemberData, nDimSource );
+ }
+ }
+ else if ( nGroupBase >= 0 )
+ {
+ // base isn't used in preceding fields
+ // -> look for other groups using the same base
+
+ //! get array of groups (or indexes) before loop?
+ ScDPItemData aMemberData;
+ rMember.FillItemData( aMemberData );
+ long nInitCount = rInitState.GetCount();
+ const long* pInitSource = rInitState.GetSource();
+ /*const ScDPItemData* pInitNames = rInitState.GetNames();*/
+ const SCROW* pInitNames = rInitState.GetNameIds();
+ for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++)
+ if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nGroupBase )
+ {
+ // same base (hierarchy between the two groups is irrelevant)
+ bInclude = pResultData->HasCommonElement( pInitNames[nInitPos], pInitSource[nInitPos],
+ aMemberData, nDimSource );
+ }
+ }
+
+ return bInclude;
+}
+
+// -----------------------------------------------------------------------
+
+ScDPResultDimension::ScDPResultDimension( const ScDPResultData* pData ) :
+ pResultData( pData ),
+ bInitialized( FALSE ),
+ bIsDataLayout( FALSE ),
+ bSortByData( FALSE ),
+ bSortAscending( FALSE ),
+ nSortMeasure( 0 ),
+ bAutoShow( FALSE ),
+ bAutoTopItems( FALSE ),
+ nAutoMeasure( 0 ),
+ nAutoCount( 0 )
+{
+}
+
+ScDPResultDimension::~ScDPResultDimension()
+{
+ for( int i = maMemberArray.size () ; i-- > 0 ; )
+ delete maMemberArray[i];
+}
+
+ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const
+{
+ if( bIsDataLayout )
+ return maMemberArray[0];
+
+ MemberHash::const_iterator aRes = maMemberHash.find( iData );
+ if( aRes != maMemberHash.end()) {
+ if ( aRes->second->IsNamedItem( iData ) )
+ return aRes->second;
+ DBG_ERROR("problem! hash result is not the same as IsNamedItem");
+ }
+
+ unsigned int i;
+ unsigned int nCount = maMemberArray.size();
+ ScDPResultMember* pResultMember;
+ for( i = 0; i < nCount ; i++ )
+ {
+ pResultMember = maMemberArray[i];
+ if ( pResultMember->IsNamedItem( iData ) )
+ return pResultMember;
+ }
+ return NULL;
+}
+
+void ScDPResultDimension::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev,
+ size_t nPos, ScDPInitState& rInitState, BOOL bInitChild /*= TRUE */ )
+{
+ if (nPos >= ppDim.size() || nPos >= ppLev.size())
+ {
+ bInitialized = true;
+ return;
+ }
+
+ ScDPDimension* pThisDim = ppDim[nPos];
+ ScDPLevel* pThisLevel = ppLev[nPos];
+
+ if (!pThisDim || !pThisLevel)
+ {
+ bInitialized = true;
+ return;
+ }
+
+ bIsDataLayout = pThisDim->getIsDataLayoutDimension(); // member
+ aDimensionName = pThisDim->getName(); // member
+
+ // Check the autoshow setting. If it's enabled, store the settings.
+ const sheet::DataPilotFieldAutoShowInfo& rAutoInfo = pThisLevel->GetAutoShow();
+ if ( rAutoInfo.IsEnabled )
+ {
+ bAutoShow = TRUE;
+ bAutoTopItems = ( rAutoInfo.ShowItemsMode == sheet::DataPilotFieldShowItemsMode::FROM_TOP );
+ nAutoMeasure = pThisLevel->GetAutoMeasure();
+ nAutoCount = rAutoInfo.ItemCount;
+ }
+
+ // Check the sort info, and store the settings if appropriate.
+ const sheet::DataPilotFieldSortInfo& rSortInfo = pThisLevel->GetSortInfo();
+ if ( rSortInfo.Mode == sheet::DataPilotFieldSortMode::DATA )
+ {
+ bSortByData = TRUE;
+ bSortAscending = rSortInfo.IsAscending;
+ nSortMeasure = pThisLevel->GetSortMeasure();
+ }
+
+ // global order is used to initialize aMembers, so it doesn't have to be looked at later
+ const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder();
+
+ long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim?
+ ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource );
+
+ // Now, go through all members and initialize them.
+ ScDPMembers* pMembers = pThisLevel->GetMembersObject();
+ long nMembCount = pMembers->getCount();
+ for ( long i=0; i<nMembCount; i++ )
+ {
+ long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i];
+
+ ScDPMember* pMember = pMembers->getByIndex(nSorted);
+ if ( aCompare.IsIncluded( *pMember ) )
+ {
+ ScDPParentDimData aData( i, pThisDim, pThisLevel, pMember);
+ ScDPResultMember* pNew = AddMember( aData );
+
+ rInitState.AddMember( nDimSource, /*aMemberData*/pNew->GetDataId() );
+ pNew->InitFrom( ppDim, ppLev, nPos+1, rInitState, bInitChild );
+ rInitState.RemoveMember();
+ }
+ }
+ bInitialized = TRUE;
+}
+
+void ScDPResultDimension::LateInitFrom( LateInitParams& rParams/* const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/,
+ const vector<SCROW>& pItemData, size_t nPos,
+ ScDPInitState& rInitState )
+// End Comments
+{
+ if ( rParams.IsEnd( nPos ) )
+ return;
+#ifdef DBG_UTIL
+ DBG_ASSERT( nPos <= pItemData.size(), ByteString::CreateFromInt32( pItemData.size()).GetBuffer() );
+#endif
+ ScDPDimension* pThisDim = rParams.GetDim( nPos );
+ ScDPLevel* pThisLevel = rParams.GetLevel( nPos );
+ SCROW rThisData = pItemData[nPos];
+
+ if (!pThisDim || !pThisLevel)
+ return;
+
+ long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim?
+
+ BOOL bShowEmpty = pThisLevel->getShowEmpty();
+
+ if ( !bInitialized )
+ { // init some values
+ // create all members at the first call (preserve order)
+ bIsDataLayout = pThisDim->getIsDataLayoutDimension();
+ aDimensionName = pThisDim->getName();
+
+ const sheet::DataPilotFieldAutoShowInfo& rAutoInfo = pThisLevel->GetAutoShow();
+ if ( rAutoInfo.IsEnabled )
+ {
+ bAutoShow = TRUE;
+ bAutoTopItems = ( rAutoInfo.ShowItemsMode == sheet::DataPilotFieldShowItemsMode::FROM_TOP );
+ nAutoMeasure = pThisLevel->GetAutoMeasure();
+ nAutoCount = rAutoInfo.ItemCount;
+ }
+
+ const sheet::DataPilotFieldSortInfo& rSortInfo = pThisLevel->GetSortInfo();
+ if ( rSortInfo.Mode == sheet::DataPilotFieldSortMode::DATA )
+ {
+ bSortByData = TRUE;
+ bSortAscending = rSortInfo.IsAscending;
+ nSortMeasure = pThisLevel->GetSortMeasure();
+ }
+ }
+
+ bool bLateInitAllMembers= bIsDataLayout || rParams.GetInitAllChild() || bShowEmpty;
+
+ if ( !bLateInitAllMembers )
+ {
+ ResultMembers* pMembers = pResultData->GetDimResultMembers(nDimSource, pThisDim, pThisLevel);
+ bLateInitAllMembers = pMembers->IsHasHideDetailsMembers();
+#ifdef DBG_UTIL
+ DBG_TRACESTR( aDimensionName )
+ if ( pMembers->IsHasHideDetailsMembers() )
+ DBG_TRACE ( "HasHideDetailsMembers" );
+#endif
+ pMembers->SetHasHideDetailsMembers( FALSE );
+ }
+
+ bool bNewAllMembers =(!rParams.IsRow()) || nPos == 0 || bLateInitAllMembers ;
+
+ if (bNewAllMembers )
+ {
+ // global order is used to initialize aMembers, so it doesn't have to be looked at later
+ if ( !bInitialized )
+ { //init all members
+ const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder();
+
+ ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource );
+ ScDPMembers* pMembers = pThisLevel->GetMembersObject();
+ long nMembCount = pMembers->getCount();
+ for ( long i=0; i<nMembCount; i++ )
+ {
+ long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i];
+
+ ScDPMember* pMember = pMembers->getByIndex(nSorted);
+ if ( aCompare.IsIncluded( *pMember ) )
+ { // add all members
+ ScDPParentDimData aData( i, pThisDim, pThisLevel, pMember );
+ AddMember( aData );
+ }
+ }
+ bInitialized = TRUE; // don't call again, even if no members were included
+ }
+ // initialize only specific member (or all if "show empty" flag is set)
+ if ( bLateInitAllMembers )
+ {
+ long nCount = maMemberArray.size();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPResultMember* pResultMember = maMemberArray[i];
+
+ // check show empty
+ BOOL bAllChildren = FALSE;
+ if( bShowEmpty )
+ {
+ if ( pResultMember->IsNamedItem( rThisData ) )
+ bAllChildren = FALSE;
+ else
+ bAllChildren = TRUE;
+ }
+ rParams.SetInitAllChildren( bAllChildren );
+ rInitState.AddMember( nDimSource, pResultMember->GetDataId() );
+ pResultMember->LateInitFrom( rParams, pItemData, nPos+1, rInitState );
+ rInitState.RemoveMember();
+ }
+ }
+ else
+ {
+ ScDPResultMember* pResultMember = FindMember( rThisData );
+ if( NULL != pResultMember )
+ {
+ //DBG_TRACE( "ScDPResultDimension::LateInitFrom");
+ // DBG_TRACESTR( pResultMember->GetDPMember()->GetNameStr());
+
+ rInitState.AddMember( nDimSource, pResultMember->GetDataId() );
+ pResultMember->LateInitFrom( rParams, pItemData, nPos+1, rInitState );
+ rInitState.RemoveMember();
+ }
+ }
+ }
+ else
+ InitWithMembers( rParams, pItemData, nPos, rInitState );
+}
+
+long ScDPResultDimension::GetSize(long nMeasure) const
+{
+ long nTotal = 0;
+ long nMemberCount = maMemberArray.size();
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ // repeat first member...
+ nTotal = nMemberCount * maMemberArray[0]->GetSize(0); // all measures have equal size
+ }
+ else
+ {
+ // add all members
+ for (long nMem=0; nMem<nMemberCount; nMem++)
+ nTotal += maMemberArray[nMem]->GetSize(nMeasure);
+ }
+ return nTotal;
+}
+
+bool ScDPResultDimension::IsValidEntry( const vector< SCROW >& aMembers ) const
+{
+ if (aMembers.empty())
+ return false;
+
+ const ScDPResultMember* pMember = FindMember( aMembers[0] );
+ if ( NULL != pMember )
+ return pMember->IsValidEntry( aMembers );
+#ifdef DBG_UTIL
+ ByteString strTemp ("IsValidEntry: Member not found, DimName = " );
+ strTemp += ByteString( GetName(), RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( strTemp.GetBuffer() );
+ // DBG_ERROR("IsValidEntry: Member not found");
+#endif
+ return false;
+}
+
+void ScDPResultDimension::ProcessData( const vector< SCROW >& aMembers,
+ const ScDPResultDimension* pDataDim,
+ const vector< SCROW >& aDataMembers,
+ const vector<ScDPValueData>& aValues ) const
+{
+ if (aMembers.empty())
+ return;
+
+ ScDPResultMember* pMember = FindMember( aMembers[0] );
+ if ( NULL != pMember )
+ {
+ vector</*ScDPItemData*/SCROW > aChildMembers;
+ if (aMembers.size() > 1)
+ {
+ vector</*ScDPItemData*/SCROW >::const_iterator itr = aMembers.begin();
+ aChildMembers.insert(aChildMembers.begin(), ++itr, aMembers.end());
+ }
+ pMember->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues );
+ return;
+ }
+
+ DBG_ERROR("ProcessData: Member not found");
+}
+
+void ScDPResultDimension::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
+ long nStart, long nMeasure )
+{
+ long nPos = nStart;
+ long nCount = maMemberArray.size();
+
+ for (long i=0; i<nCount; i++)
+ {
+ long nSorted = aMemberOrder.empty() ? i : aMemberOrder[i];
+
+ ScDPResultMember* pMember = maMemberArray[nSorted];
+ // in data layout dimension, use first member with different measures/names
+ if ( bIsDataLayout )
+ {
+ bool bTotalResult = false;
+ String aMbrName = pResultData->GetMeasureDimensionName( nSorted );
+ String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE, bTotalResult );
+ maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
+ }
+ else if ( pMember->IsVisible() )
+ pMember->FillMemberResults( pSequences, nPos, nMeasure, FALSE, NULL, NULL );
+ // nPos is modified
+ }
+}
+
+void ScDPResultDimension::FillDataResults( const ScDPResultMember* pRefMember,
+ uno::Sequence< uno::Sequence<sheet::DataResult> >& rSequence,
+ long nRow, long nMeasure ) const
+{
+ long nMemberRow = nRow;
+ long nMemberMeasure = nMeasure;
+ long nCount = maMemberArray.size();
+ for (long i=0; i<nCount; i++)
+ {
+ long nSorted = aMemberOrder.empty() ? i : aMemberOrder[i];
+
+ const ScDPResultMember* pMember;
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ pMember = maMemberArray[0];
+ nMemberMeasure = nSorted;
+ }
+ else
+ pMember = maMemberArray[nSorted];
+
+ if ( pMember->IsVisible() )
+ pMember->FillDataResults( pRefMember, rSequence, nMemberRow, nMemberMeasure );
+ // nMemberRow is modified
+ }
+}
+
+void ScDPResultDimension::UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const
+{
+ long nMemberMeasure = nMeasure;
+ long nCount = maMemberArray.size();
+ for (long i=0; i<nCount; i++)
+ {
+ const ScDPResultMember* pMember;
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ pMember = maMemberArray[0];
+ nMemberMeasure = i;
+ }
+ else
+ pMember = maMemberArray[i];
+
+ if ( pMember->IsVisible() )
+ pMember->UpdateDataResults( pRefMember, nMemberMeasure );
+ }
+}
+
+void ScDPResultDimension::SortMembers( ScDPResultMember* pRefMember )
+{
+ long nCount = maMemberArray.size();
+
+ if ( bSortByData )
+ {
+ // sort members
+
+ DBG_ASSERT( aMemberOrder.empty(), "sort twice?" );
+ aMemberOrder.resize( nCount );
+ for (long nPos=0; nPos<nCount; nPos++)
+ aMemberOrder[nPos] = nPos;
+
+ ScDPRowMembersOrder aComp( *this, nSortMeasure, bSortAscending );
+ ::std::sort( aMemberOrder.begin(), aMemberOrder.end(), aComp );
+ }
+
+ // handle children
+
+ // for data layout, call only once - sorting measure is always taken from settings
+ long nLoopCount = bIsDataLayout ? 1 : nCount;
+ for (long i=0; i<nLoopCount; i++)
+ {
+ ScDPResultMember* pMember = maMemberArray[i];
+ if ( pMember->IsVisible() )
+ pMember->SortMembers( pRefMember );
+ }
+}
+
+void ScDPResultDimension::DoAutoShow( ScDPResultMember* pRefMember )
+{
+ long nCount = maMemberArray.size();
+
+ // handle children first, before changing the visible state
+
+ // for data layout, call only once - sorting measure is always taken from settings
+ long nLoopCount = bIsDataLayout ? 1 : nCount;
+ for (long i=0; i<nLoopCount; i++)
+ {
+ ScDPResultMember* pMember = maMemberArray[i];
+ if ( pMember->IsVisible() )
+ pMember->DoAutoShow( pRefMember );
+ }
+
+ if ( bAutoShow && nAutoCount > 0 && nAutoCount < nCount )
+ {
+ // establish temporary order, hide remaining members
+
+ ScMemberSortOrder aAutoOrder;
+ aAutoOrder.resize( nCount );
+ long nPos;
+ for (nPos=0; nPos<nCount; nPos++)
+ aAutoOrder[nPos] = nPos;
+
+ ScDPRowMembersOrder aComp( *this, nAutoMeasure, !bAutoTopItems );
+ ::std::sort( aAutoOrder.begin(), aAutoOrder.end(), aComp );
+
+ // look for equal values to the last included one
+
+ long nIncluded = nAutoCount;
+ const ScDPResultMember* pMember1 = maMemberArray[aAutoOrder[nIncluded - 1]];
+ const ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL;
+ BOOL bContinue = TRUE;
+ while ( bContinue )
+ {
+ bContinue = FALSE;
+ if ( nIncluded < nCount )
+ {
+ const ScDPResultMember* pMember2 = maMemberArray[aAutoOrder[nIncluded]];
+ const ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL;
+
+ if ( lcl_IsEqual( pDataMember1, pDataMember2, nAutoMeasure ) )
+ {
+ ++nIncluded; // include more members if values are equal
+ bContinue = TRUE;
+ }
+ }
+ }
+
+ // hide the remaining members
+
+ for (nPos = nIncluded; nPos < nCount; nPos++)
+ {
+ ScDPResultMember* pMember = maMemberArray[aAutoOrder[nPos]];
+ pMember->SetAutoHidden();
+ }
+ }
+}
+
+void ScDPResultDimension::ResetResults()
+{
+ long nCount = maMemberArray.size();
+ for (long i=0; i<nCount; i++)
+ {
+ // sort order doesn't matter
+ ScDPResultMember* pMember = maMemberArray[bIsDataLayout ? 0 : i];
+ pMember->ResetResults( FALSE );
+ }
+}
+
+long ScDPResultDimension::GetSortedIndex( long nUnsorted ) const
+{
+ return aMemberOrder.empty() ? nUnsorted : aMemberOrder[nUnsorted];
+}
+
+void ScDPResultDimension::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure,
+ ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const
+{
+ const ScDPResultMember* pMember;
+ long nMemberMeasure = nMeasure;
+ long nCount = maMemberArray.size();
+ for (long i=0; i<nCount; i++)
+ {
+ long nSorted = aMemberOrder.empty() ? i : aMemberOrder[i];
+
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ pMember = maMemberArray[0];
+ nMemberMeasure = nSorted;
+ }
+ else
+ pMember = maMemberArray[nSorted];
+
+ if ( pMember->IsVisible() )
+ {
+ if ( bIsDataLayout )
+ rRunning.AddRowIndex( 0, 0 );
+ else
+ rRunning.AddRowIndex( i, nSorted );
+ pMember->UpdateRunningTotals( pRefMember, nMemberMeasure, rRunning, rTotals );
+ rRunning.RemoveRowIndex();
+ }
+ }
+}
+
+ScDPDataMember* ScDPResultDimension::GetRowReferenceMember( const ScDPRelativePos* pRelativePos, const String* pName,
+ const long* pRowIndexes, const long* pColIndexes ) const
+{
+ // get named, previous/next, or first member of this dimension (first existing if pRelativePos and pName are NULL)
+
+ DBG_ASSERT( pRelativePos == NULL || pName == NULL, "can't use position and name" );
+
+ ScDPDataMember* pColMember = NULL;
+
+ BOOL bFirstExisting = ( pRelativePos == NULL && pName == NULL );
+ long nMemberCount = maMemberArray.size();
+ long nMemberIndex = 0; // unsorted
+ long nDirection = 1; // forward if no relative position is used
+ if ( pRelativePos )
+ {
+ nDirection = pRelativePos->nDirection;
+ nMemberIndex = pRelativePos->nBasePos + nDirection; // bounds are handled below
+
+ DBG_ASSERT( nDirection == 1 || nDirection == -1, "Direction must be 1 or -1" );
+ }
+ else if ( pName )
+ {
+ // search for named member
+
+ const ScDPResultMember* pRowMember = maMemberArray[GetSortedIndex(nMemberIndex)];
+
+ //! use ScDPItemData, as in ScDPDimension::IsValidPage?
+ while ( pRowMember && pRowMember->GetName() != *pName )
+ {
+ ++nMemberIndex;
+ if ( nMemberIndex < nMemberCount )
+ pRowMember = maMemberArray[GetSortedIndex(nMemberIndex)];
+ else
+ pRowMember = NULL;
+ }
+ }
+
+ BOOL bContinue = TRUE;
+ while ( bContinue && nMemberIndex >= 0 && nMemberIndex < nMemberCount )
+ {
+ const ScDPResultMember* pRowMember = maMemberArray[GetSortedIndex(nMemberIndex)];
+
+ // get child members by given indexes
+
+ const long* pNextRowIndex = pRowIndexes;
+ while ( *pNextRowIndex >= 0 && pRowMember )
+ {
+ const ScDPResultDimension* pRowChild = pRowMember->GetChildDimension();
+ if ( pRowChild && *pNextRowIndex < pRowChild->GetMemberCount() )
+ pRowMember = pRowChild->GetMember( *pNextRowIndex );
+ else
+ pRowMember = NULL;
+ ++pNextRowIndex;
+ }
+
+ if ( pRowMember && pRelativePos )
+ {
+ // Skip the member if it has hidden details
+ // (because when looking for the details, it is skipped, too).
+ // Also skip if the member is invisible because it has no data,
+ // for consistent ordering.
+ if ( pRowMember->HasHiddenDetails() || !pRowMember->IsVisible() )
+ pRowMember = NULL;
+ }
+
+ if ( pRowMember )
+ {
+ pColMember = pRowMember->GetDataRoot();
+
+ const long* pNextColIndex = pColIndexes;
+ while ( *pNextColIndex >= 0 && pColMember )
+ {
+ const ScDPDataDimension* pColChild = pColMember->GetChildDimension();
+ if ( pColChild && *pNextColIndex < pColChild->GetMemberCount() )
+ pColMember = pColChild->GetMember( *pNextColIndex );
+ else
+ pColMember = NULL;
+ ++pNextColIndex;
+ }
+ }
+
+ // continue searching only if looking for first existing or relative position
+ bContinue = ( pColMember == NULL && ( bFirstExisting || pRelativePos ) );
+ nMemberIndex += nDirection;
+ }
+
+ return pColMember;
+}
+
+// static
+ScDPDataMember* ScDPResultDimension::GetColReferenceMember( const ScDPRelativePos* pRelativePos, const String* pName,
+ long nRefDimPos, const ScDPRunningTotalState& rRunning )
+{
+ DBG_ASSERT( pRelativePos == NULL || pName == NULL, "can't use position and name" );
+
+ const long* pColIndexes = rRunning.GetColIndexes();
+ const long* pRowIndexes = rRunning.GetRowIndexes();
+
+ // get own row member using all indexes
+
+ const ScDPResultMember* pRowMember = rRunning.GetRowResRoot();
+ ScDPDataMember* pColMember = NULL;
+
+ const long* pNextRowIndex = pRowIndexes;
+ while ( *pNextRowIndex >= 0 && pRowMember )
+ {
+ const ScDPResultDimension* pRowChild = pRowMember->GetChildDimension();
+ if ( pRowChild && *pNextRowIndex < pRowChild->GetMemberCount() )
+ pRowMember = pRowChild->GetMember( *pNextRowIndex );
+ else
+ pRowMember = NULL;
+ ++pNextRowIndex;
+ }
+
+ // get column (data) members before the reference field
+ //! pass rRowParent from ScDPDataMember::UpdateRunningTotals instead
+
+ if ( pRowMember )
+ {
+ pColMember = pRowMember->GetDataRoot();
+
+ const long* pNextColIndex = pColIndexes;
+ long nColSkipped = 0;
+ while ( *pNextColIndex >= 0 && pColMember && nColSkipped < nRefDimPos )
+ {
+ const ScDPDataDimension* pColChild = pColMember->GetChildDimension();
+ if ( pColChild && *pNextColIndex < pColChild->GetMemberCount() )
+ pColMember = pColChild->GetMember( *pNextColIndex );
+ else
+ pColMember = NULL;
+ ++pNextColIndex;
+ ++nColSkipped;
+ }
+ }
+
+ // get column member for the reference field
+
+ if ( pColMember )
+ {
+ const ScDPDataDimension* pReferenceDim = pColMember->GetChildDimension();
+ if ( pReferenceDim )
+ {
+ long nReferenceCount = pReferenceDim->GetMemberCount();
+
+ BOOL bFirstExisting = ( pRelativePos == NULL && pName == NULL );
+ long nMemberIndex = 0; // unsorted
+ long nDirection = 1; // forward if no relative position is used
+ pColMember = NULL; // don't use parent dimension's member if none found
+ if ( pRelativePos )
+ {
+ nDirection = pRelativePos->nDirection;
+ nMemberIndex = pRelativePos->nBasePos + nDirection; // bounds are handled below
+ }
+ else if ( pName )
+ {
+ // search for named member
+
+ pColMember = pReferenceDim->GetMember( pReferenceDim->GetSortedIndex( nMemberIndex ) );
+
+ //! use ScDPItemData, as in ScDPDimension::IsValidPage?
+ while ( pColMember && pColMember->GetName() != *pName )
+ {
+ ++nMemberIndex;
+ if ( nMemberIndex < nReferenceCount )
+ pColMember = pReferenceDim->GetMember( pReferenceDim->GetSortedIndex( nMemberIndex ) );
+ else
+ pColMember = NULL;
+ }
+ }
+
+ BOOL bContinue = TRUE;
+ while ( bContinue && nMemberIndex >= 0 && nMemberIndex < nReferenceCount )
+ {
+ pColMember = pReferenceDim->GetMember( pReferenceDim->GetSortedIndex( nMemberIndex ) );
+
+ // get column members below the reference field
+
+ const long* pNextColIndex = pColIndexes + nRefDimPos + 1;
+ while ( *pNextColIndex >= 0 && pColMember )
+ {
+ const ScDPDataDimension* pColChild = pColMember->GetChildDimension();
+ if ( pColChild && *pNextColIndex < pColChild->GetMemberCount() )
+ pColMember = pColChild->GetMember( *pNextColIndex );
+ else
+ pColMember = NULL;
+ ++pNextColIndex;
+ }
+
+ if ( pColMember && pRelativePos )
+ {
+ // Skip the member if it has hidden details
+ // (because when looking for the details, it is skipped, too).
+ // Also skip if the member is invisible because it has no data,
+ // for consistent ordering.
+ if ( pColMember->HasHiddenDetails() || !pColMember->IsVisible() )
+ pColMember = NULL;
+ }
+
+ // continue searching only if looking for first existing or relative position
+ bContinue = ( pColMember == NULL && ( bFirstExisting || pRelativePos ) );
+ nMemberIndex += nDirection;
+ }
+ }
+ else
+ pColMember = NULL;
+ }
+
+ return pColMember;
+}
+
+void ScDPResultDimension::DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const
+{
+ String aDimName = bIsDataLayout ? String::CreateFromAscii("(data layout)") : GetName();
+ lcl_DumpRow( String::CreateFromAscii("ScDPResultDimension"), aDimName, NULL, pDoc, rPos );
+
+ SCROW nStartRow = rPos.Row();
+
+ long nCount = bIsDataLayout ? 1 : maMemberArray.size();
+ for (long i=0; i<nCount; i++)
+ {
+ const ScDPResultMember* pMember = maMemberArray[i];
+ pMember->DumpState( pRefMember, pDoc, rPos );
+ }
+
+ lcl_Indent( pDoc, nStartRow, rPos );
+}
+
+long ScDPResultDimension::GetMemberCount() const
+{
+ return maMemberArray.size();
+}
+
+const ScDPResultMember* ScDPResultDimension::GetMember(long n) const
+{
+ return maMemberArray[n];
+}
+ScDPResultMember* ScDPResultDimension::GetMember(long n)
+{
+ return maMemberArray[n];
+}
+
+ScDPResultDimension* ScDPResultDimension::GetFirstChildDimension() const
+{
+ if ( maMemberArray.size() > 0 )
+ return maMemberArray[0]->GetChildDimension();
+ else
+ return NULL;
+}
+
+void ScDPResultDimension::FillVisibilityData(ScDPResultVisibilityData& rData) const
+{
+ if (IsDataLayout())
+ return;
+
+ MemberArray::const_iterator itr = maMemberArray.begin(), itrEnd = maMemberArray.end();
+
+ for (;itr != itrEnd; ++itr)
+ {
+ ScDPResultMember* pMember = *itr;
+ if (pMember->IsValid())
+ {
+ ScDPItemData aItem;
+ pMember->FillItemData(aItem);
+ rData.addVisibleMember(GetName(), aItem);
+ pMember->FillVisibilityData(rData);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScDPDataDimension::ScDPDataDimension( const ScDPResultData* pData ) :
+ pResultData( pData ),
+ pResultDimension( NULL ),
+ bIsDataLayout( FALSE )
+{
+}
+
+ScDPDataDimension::~ScDPDataDimension()
+{
+}
+
+void ScDPDataDimension::InitFrom( const ScDPResultDimension* pDim )
+{
+ if (!pDim)
+ return;
+
+ pResultDimension = pDim;
+ bIsDataLayout = pDim->IsDataLayout();
+
+ // Go through all result members under the given result dimension, and
+ // create a new data member instance for each result member.
+ long nCount = pDim->GetMemberCount();
+ for (long i=0; i<nCount; i++)
+ {
+ const ScDPResultMember* pResMem = pDim->GetMember(i);
+
+ ScDPDataMember* pNew = new ScDPDataMember( pResultData, pResMem );
+ aMembers.Insert( pNew, aMembers.Count() );
+
+ if ( !pResultData->IsLateInit() )
+ {
+ // with LateInit, pResMem hasn't necessarily been initialized yet,
+ // so InitFrom for the new result member is called from its ProcessData method
+
+ const ScDPResultDimension* pChildDim = pResMem->GetChildDimension();
+ if ( pChildDim )
+ pNew->InitFrom( pChildDim );
+ }
+ }
+}
+
+void ScDPDataDimension::ProcessData( const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues,
+ const ScDPSubTotalState& rSubState )
+{
+ // the ScDPItemData array must contain enough entries for all dimensions - this isn't checked
+
+ long nCount = aMembers.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ ScDPDataMember* pMember = aMembers[(USHORT)i];
+
+ // always first member for data layout dim
+ if ( bIsDataLayout || ( !aDataMembers.empty() && pMember->IsNamedItem(aDataMembers[0]) ) )
+ {
+ vector</*ScDPItemData*/SCROW> aChildDataMembers;
+ if (aDataMembers.size() > 1)
+ {
+ vector</*ScDPItemData*/SCROW >::const_iterator itr = aDataMembers.begin();
+ aChildDataMembers.insert(aChildDataMembers.begin(), ++itr, aDataMembers.end());
+ }
+ pMember->ProcessData( aChildDataMembers, aValues, rSubState );
+ return;
+ }
+ }
+
+ DBG_ERROR("ProcessData: Member not found");
+}
+
+void ScDPDataDimension::FillDataRow( const ScDPResultDimension* pRefDim,
+ uno::Sequence<sheet::DataResult>& rSequence,
+ long nCol, long nMeasure, BOOL bIsSubTotalRow,
+ const ScDPSubTotalState& rSubState ) const
+{
+ DBG_ASSERT( pRefDim && pRefDim->GetMemberCount() == aMembers.Count(), "dimensions don't match" );
+ DBG_ASSERT( pRefDim == pResultDimension, "wrong dim" );
+
+ const ScMemberSortOrder& rMemberOrder = pRefDim->GetMemberOrder();
+
+ long nMemberMeasure = nMeasure;
+ long nMemberCol = nCol;
+ long nCount = aMembers.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ long nSorted = rMemberOrder.empty() ? i : rMemberOrder[i];
+
+ long nMemberPos = nSorted;
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ nMemberPos = 0;
+ nMemberMeasure = nSorted;
+ }
+
+ const ScDPResultMember* pRefMember = pRefDim->GetMember(nMemberPos);
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataMember::FillDataRow ???
+ {
+ const ScDPDataMember* pDataMember = aMembers[(USHORT)nMemberPos];
+ pDataMember->FillDataRow( pRefMember, rSequence, nMemberCol, nMemberMeasure, bIsSubTotalRow, rSubState );
+ // nMemberCol is modified
+ }
+ }
+}
+
+void ScDPDataDimension::UpdateDataRow( const ScDPResultDimension* pRefDim,
+ long nMeasure, BOOL bIsSubTotalRow,
+ const ScDPSubTotalState& rSubState ) const
+{
+ DBG_ASSERT( pRefDim && pRefDim->GetMemberCount() == aMembers.Count(), "dimensions don't match" );
+ DBG_ASSERT( pRefDim == pResultDimension, "wrong dim" );
+
+ long nMemberMeasure = nMeasure;
+ long nCount = aMembers.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ long nMemberPos = i;
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ nMemberPos = 0;
+ nMemberMeasure = i;
+ }
+
+ // Calculate must be called even if the member is not visible (for use as reference value)
+ const ScDPResultMember* pRefMember = pRefDim->GetMember(nMemberPos);
+ ScDPDataMember* pDataMember = aMembers[(USHORT)nMemberPos];
+ pDataMember->UpdateDataRow( pRefMember, nMemberMeasure, bIsSubTotalRow, rSubState );
+ }
+}
+
+void ScDPDataDimension::SortMembers( ScDPResultDimension* pRefDim )
+{
+ long nCount = aMembers.Count();
+
+ if ( pRefDim->IsSortByData() )
+ {
+ // sort members
+
+ ScMemberSortOrder& rMemberOrder = pRefDim->GetMemberOrder();
+ DBG_ASSERT( rMemberOrder.empty(), "sort twice?" );
+ rMemberOrder.resize( nCount );
+ for (long nPos=0; nPos<nCount; nPos++)
+ rMemberOrder[nPos] = nPos;
+
+ ScDPColMembersOrder aComp( *this, pRefDim->GetSortMeasure(), pRefDim->IsSortAscending() );
+ ::std::sort( rMemberOrder.begin(), rMemberOrder.end(), aComp );
+ }
+
+ // handle children
+
+ DBG_ASSERT( pRefDim && pRefDim->GetMemberCount() == aMembers.Count(), "dimensions don't match" );
+ DBG_ASSERT( pRefDim == pResultDimension, "wrong dim" );
+
+ // for data layout, call only once - sorting measure is always taken from settings
+ long nLoopCount = bIsDataLayout ? 1 : nCount;
+ for (long i=0; i<nLoopCount; i++)
+ {
+ ScDPResultMember* pRefMember = pRefDim->GetMember(i);
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataMember ???
+ {
+ ScDPDataMember* pDataMember = aMembers[(USHORT)i];
+ pDataMember->SortMembers( pRefMember );
+ }
+ }
+}
+
+void ScDPDataDimension::DoAutoShow( ScDPResultDimension* pRefDim )
+{
+ long nCount = aMembers.Count();
+
+ // handle children first, before changing the visible state
+
+ DBG_ASSERT( pRefDim && pRefDim->GetMemberCount() == aMembers.Count(), "dimensions don't match" );
+ DBG_ASSERT( pRefDim == pResultDimension, "wrong dim" );
+
+ // for data layout, call only once - sorting measure is always taken from settings
+ long nLoopCount = bIsDataLayout ? 1 : nCount;
+ for (long i=0; i<nLoopCount; i++)
+ {
+ ScDPResultMember* pRefMember = pRefDim->GetMember(i);
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataMember ???
+ {
+ ScDPDataMember* pDataMember = aMembers[(USHORT)i];
+ pDataMember->DoAutoShow( pRefMember );
+ }
+ }
+
+ if ( pRefDim->IsAutoShow() && pRefDim->GetAutoCount() > 0 && pRefDim->GetAutoCount() < nCount )
+ {
+ // establish temporary order, hide remaining members
+
+ ScMemberSortOrder aAutoOrder;
+ aAutoOrder.resize( nCount );
+ long nPos;
+ for (nPos=0; nPos<nCount; nPos++)
+ aAutoOrder[nPos] = nPos;
+
+ ScDPColMembersOrder aComp( *this, pRefDim->GetAutoMeasure(), !pRefDim->IsAutoTopItems() );
+ ::std::sort( aAutoOrder.begin(), aAutoOrder.end(), aComp );
+
+ // look for equal values to the last included one
+
+ long nIncluded = pRefDim->GetAutoCount();
+ ScDPDataMember* pDataMember1 = aMembers[(USHORT)aAutoOrder[nIncluded - 1]];
+ if ( !pDataMember1->IsVisible() )
+ pDataMember1 = NULL;
+ BOOL bContinue = TRUE;
+ while ( bContinue )
+ {
+ bContinue = FALSE;
+ if ( nIncluded < nCount )
+ {
+ ScDPDataMember* pDataMember2 = aMembers[(USHORT)aAutoOrder[nIncluded]];
+ if ( !pDataMember2->IsVisible() )
+ pDataMember2 = NULL;
+
+ if ( lcl_IsEqual( pDataMember1, pDataMember2, pRefDim->GetAutoMeasure() ) )
+ {
+ ++nIncluded; // include more members if values are equal
+ bContinue = TRUE;
+ }
+ }
+ }
+
+ // hide the remaining members
+
+ for (nPos = nIncluded; nPos < nCount; nPos++)
+ {
+ ScDPResultMember* pMember = pRefDim->GetMember(aAutoOrder[nPos]);
+ pMember->SetAutoHidden();
+ }
+ }
+}
+
+void ScDPDataDimension::ResetResults()
+{
+ long nCount = aMembers.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ // sort order doesn't matter
+
+ long nMemberPos = bIsDataLayout ? 0 : i;
+ ScDPDataMember* pDataMember = aMembers[(USHORT)nMemberPos];
+ pDataMember->ResetResults();
+ }
+}
+
+long ScDPDataDimension::GetSortedIndex( long nUnsorted ) const
+{
+ if (!pResultDimension)
+ return nUnsorted;
+
+ const ScMemberSortOrder& rMemberOrder = pResultDimension->GetMemberOrder();
+ return rMemberOrder.empty() ? nUnsorted : rMemberOrder[nUnsorted];
+}
+
+void ScDPDataDimension::UpdateRunningTotals( const ScDPResultDimension* pRefDim,
+ long nMeasure, BOOL bIsSubTotalRow,
+ const ScDPSubTotalState& rSubState, ScDPRunningTotalState& rRunning,
+ ScDPRowTotals& rTotals, const ScDPResultMember& rRowParent ) const
+{
+ DBG_ASSERT( pRefDim && pRefDim->GetMemberCount() == aMembers.Count(), "dimensions don't match" );
+ DBG_ASSERT( pRefDim == pResultDimension, "wrong dim" );
+
+ long nMemberMeasure = nMeasure;
+ long nCount = aMembers.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ const ScMemberSortOrder& rMemberOrder = pRefDim->GetMemberOrder();
+ long nSorted = rMemberOrder.empty() ? i : rMemberOrder[i];
+
+ long nMemberPos = nSorted;
+ if (bIsDataLayout)
+ {
+ DBG_ASSERT(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
+ "DataLayout dimension twice?");
+ nMemberPos = 0;
+ nMemberMeasure = nSorted;
+ }
+
+ const ScDPResultMember* pRefMember = pRefDim->GetMember(nMemberPos);
+ if ( pRefMember->IsVisible() ) //! here or in ScDPDataMember::UpdateRunningTotals ???
+ {
+ if ( bIsDataLayout )
+ rRunning.AddColIndex( 0, 0 );
+ else
+ rRunning.AddColIndex( i, nSorted );
+
+ ScDPDataMember* pDataMember = aMembers[(USHORT)nMemberPos];
+ pDataMember->UpdateRunningTotals( pRefMember, nMemberMeasure,
+ bIsSubTotalRow, rSubState, rRunning, rTotals, rRowParent );
+
+ rRunning.RemoveColIndex();
+ }
+ }
+}
+
+void ScDPDataDimension::DumpState( const ScDPResultDimension* pRefDim, ScDocument* pDoc, ScAddress& rPos ) const
+{
+ String aDimName = String::CreateFromAscii( bIsDataLayout ? "(data layout)" : "(unknown)" );
+ lcl_DumpRow( String::CreateFromAscii("ScDPDataDimension"), aDimName, NULL, pDoc, rPos );
+
+ SCROW nStartRow = rPos.Row();
+
+ long nCount = bIsDataLayout ? 1 : aMembers.Count();
+ for (long i=0; i<nCount; i++)
+ {
+ const ScDPResultMember* pRefMember = pRefDim->GetMember(i);
+ const ScDPDataMember* pDataMember = aMembers[(USHORT)i];
+ pDataMember->DumpState( pRefMember, pDoc, rPos );
+ }
+
+ lcl_Indent( pDoc, nStartRow, rPos );
+}
+
+long ScDPDataDimension::GetMemberCount() const
+{
+ return aMembers.Count();
+}
+
+ScDPDataMember* ScDPDataDimension::GetMember(long n) const
+{
+ return aMembers[(USHORT)n];
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPResultVisibilityData::ScDPResultVisibilityData(
+ ScDPSource* pSource) :
+ mpSource(pSource)
+{
+}
+
+ScDPResultVisibilityData::~ScDPResultVisibilityData()
+{
+}
+
+void ScDPResultVisibilityData::addVisibleMember(const String& rDimName, const ScDPItemData& rMemberItem)
+{
+ DimMemberType::iterator itr = maDimensions.find(rDimName);
+ if (itr == maDimensions.end())
+ {
+ pair<DimMemberType::iterator, bool> r = maDimensions.insert(
+ DimMemberType::value_type(rDimName, VisibleMemberType()));
+
+ if (!r.second)
+ // insertion failed.
+ return;
+
+ itr = r.first;
+ }
+ VisibleMemberType& rMem = itr->second;
+ VisibleMemberType::iterator itrMem = rMem.find(rMemberItem);
+ if (itrMem == rMem.end())
+ rMem.insert(rMemberItem);
+}
+
+void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion>& rFilters) const
+{
+ typedef hash_map<String, long, ScStringHashCode> FieldNameMapType;
+ FieldNameMapType aFieldNames;
+ ScDPTableData* pData = mpSource->GetData();
+ long nColumnCount = pData->GetColumnCount();
+ for (long i = 0; i < nColumnCount; ++i)
+ {
+ aFieldNames.insert(
+ FieldNameMapType::value_type(pData->getDimensionName(i), i));
+ }
+
+ const ScDPDimensions* pDims = mpSource->GetDimensionsObject();
+ for (DimMemberType::const_iterator itr = maDimensions.begin(), itrEnd = maDimensions.end();
+ itr != itrEnd; ++itr)
+ {
+ const String& rDimName = itr->first;
+ ScDPCacheTable::Criterion aCri;
+ FieldNameMapType::const_iterator itrField = aFieldNames.find(rDimName);
+ if (itrField == aFieldNames.end())
+ // This should never happen!
+ continue;
+
+ long nDimIndex = itrField->second;
+ aCri.mnFieldIndex = static_cast<sal_Int32>(nDimIndex);
+ aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(/*mrSharedString*/));
+
+ ScDPCacheTable::GroupFilter* pGrpFilter =
+ static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get());
+
+ const VisibleMemberType& rMem = itr->second;
+ for (VisibleMemberType::const_iterator itrMem = rMem.begin(), itrMemEnd = rMem.end();
+ itrMem != itrMemEnd; ++itrMem)
+ {
+ const ScDPItemData& rMemItem = *itrMem;
+ pGrpFilter->addMatchItem(rMemItem.GetString(), rMemItem.GetValue(), rMemItem.IsValue());
+ }
+
+ ScDPDimension* pDim = pDims->getByIndex(nDimIndex);
+ ScDPMembers* pMembers = pDim->GetHierarchiesObject()->getByIndex(0)->
+ GetLevelsObject()->getByIndex(0)->GetMembersObject();
+ if (pGrpFilter->getMatchItemCount() < static_cast<size_t>(pMembers->getCount()))
+ rFilters.push_back(aCri);
+ }
+}
+
+size_t ScDPResultVisibilityData::MemberHash::operator() (const ScDPItemData& r) const
+{
+ if (r.IsValue())
+ return static_cast<size_t>(::rtl::math::approxFloor(r.GetValue()));
+ else
+ return rtl_ustr_hashCode_WithLength(r.GetString().GetBuffer(), r.GetString().Len());
+}
+// Wang Xu Ming -- 2009-6-10
+// DataPilot Migration
+SCROW ScDPResultMember::GetDataId( ) const
+{
+ const ScDPMember* pMemberDesc = GetDPMember();
+ if (pMemberDesc)
+ return pMemberDesc->GetItemDataId();
+ return -1;
+}
+
+ScDPResultMember* ScDPResultDimension::AddMember(const ScDPParentDimData &aData )
+{
+ ScDPResultMember* pMember = new ScDPResultMember( pResultData, aData, FALSE );
+ SCROW nDataIndex = pMember->GetDataId();
+ maMemberArray.push_back( pMember );
+
+ if ( maMemberHash.end() == maMemberHash.find( nDataIndex ) )
+ maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pMember ) );
+ return pMember;
+}
+
+ResultMembers* ScDPResultDimension::GetResultMember( ScDPDimension* pThisDim, ScDPLevel* pThisLevel )
+{
+ ResultMembers* pResultMembers = new ResultMembers();
+ // global order is used to initialize aMembers, so it doesn't have to be looked at later
+ const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder();
+
+ ScDPMembers* pMembers = pThisLevel->GetMembersObject();
+ long nMembCount = pMembers->getCount();
+ for ( long i=0; i<nMembCount; i++ )
+ {
+ long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i];
+ ScDPMember* pMember = pMembers->getByIndex(nSorted);
+ if ( NULL == pResultMembers->FindMember( pMember->GetItemDataId() ) )
+ {
+ ScDPParentDimData* pNew = new ScDPParentDimData( i, pThisDim, pThisLevel, pMember );
+ pResultMembers->InsertMember( pNew );
+ }
+ }
+ return pResultMembers;
+}
+
+ScDPResultMember* ScDPResultDimension::InsertMember(ScDPParentDimData *pMemberData)
+{
+ SCROW nInsert = 0;
+ if ( !lcl_SearchMember( maMemberArray, pMemberData->mnOrder , nInsert ) )
+ { //Member not exist
+ ScDPResultMember* pNew = new ScDPResultMember( pResultData, *pMemberData, FALSE );
+ maMemberArray.insert( maMemberArray.begin()+nInsert, pNew );
+
+ SCROW nDataIndex = pMemberData->mpMemberDesc->GetItemDataId();
+ if ( maMemberHash.end() == maMemberHash.find( nDataIndex ) )
+ maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pNew ) );
+ return pNew;
+ }
+ return maMemberArray[ nInsert ];
+}
+
+void ScDPResultDimension:: InitWithMembers( LateInitParams& rParams,
+ const ::std::vector< SCROW >& pItemData,
+ size_t nPos,
+ ScDPInitState& rInitState )
+{
+ if ( rParams.IsEnd( nPos ) )
+ return;
+ ScDPDimension* pThisDim = rParams.GetDim( nPos );
+ ScDPLevel* pThisLevel = rParams.GetLevel( nPos );
+ SCROW nDataID = pItemData[nPos];
+
+ if (pThisDim && pThisLevel)
+ {
+ long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim?
+
+ // create all members at the first call (preserve order)
+ ResultMembers* pMembers = pResultData->GetDimResultMembers(nDimSource, pThisDim, pThisLevel);
+ ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource );
+ // initialize only specific member (or all if "show empty" flag is set)
+ ScDPResultMember* pResultMember = NULL;
+ if ( bInitialized )
+ pResultMember = FindMember( nDataID );
+ else
+ bInitialized = TRUE;
+
+ if ( pResultMember == NULL )
+ { //only insert found item
+ ScDPParentDimData* pMemberData = pMembers->FindMember( nDataID );
+ if ( pMemberData && aCompare.IsIncluded( *( pMemberData->mpMemberDesc ) ) )
+ pResultMember = InsertMember( pMemberData );
+ }
+ if ( pResultMember )
+ {
+ // DBG_TRACE( "ScDPResultDimension::InitWithMembers");
+ // DBG_TRACESTR( pResultMember->GetDPMember()->GetNameStr());
+ rInitState.AddMember( nDimSource, pResultMember->GetDataId() );
+ pResultMember->LateInitFrom( rParams /*ppDim, ppLev*/, pItemData, nPos+1 , rInitState );
+ rInitState.RemoveMember();
+ }
+ }
+}
+
+ScDPParentDimData* ResultMembers::FindMember( const SCROW& nIndex ) const
+{
+ DimMemberHash::const_iterator aRes = maMemberHash.find( nIndex );
+ if( aRes != maMemberHash.end()) {
+ if ( aRes->second->mpMemberDesc && aRes->second->mpMemberDesc->GetItemDataId()==nIndex )
+ return aRes->second;
+ }
+ return NULL;
+}
+void ResultMembers::InsertMember( ScDPParentDimData* pNew )
+{
+ if ( !pNew->mpMemberDesc->getShowDetails() )
+ mbHasHideDetailsMember = TRUE;
+ maMemberHash.insert( std::pair< const SCROW, ScDPParentDimData *>( pNew->mpMemberDesc->GetItemDataId(), pNew ) );
+}
+
+ResultMembers::ResultMembers():
+ mbHasHideDetailsMember( FALSE )
+{
+}
+ResultMembers::~ResultMembers()
+{
+ for ( DimMemberHash::const_iterator iter = maMemberHash.begin(); iter != maMemberHash.end(); iter++ )
+ delete iter->second;
+}
+// -----------------------------------------------------------------------
+LateInitParams::LateInitParams( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, BOOL bRow, BOOL bInitChild, BOOL bAllChildren ):
+ mppDim( ppDim ),
+ mppLev( ppLev ),
+ mbRow( bRow ),
+ mbInitChild( bInitChild ),
+ mbAllChildren( bAllChildren )
+{
+}
+
+LateInitParams::~LateInitParams()
+{
+}
+
+BOOL LateInitParams::IsEnd( size_t nPos ) const
+{
+ return nPos >= mppDim.size();
+}
+
+// End Comments
+// Wang Xu Ming -- 2009-8-4
+// DataPilot Migration - old defects merge
+void ScDPResultDimension::CheckShowEmpty( BOOL bShow )
+{
+ long nCount = maMemberArray.size();
+
+ ScDPResultMember* pMember = NULL;
+ for (long i=0; i<nCount; i++)
+ {
+ pMember = maMemberArray.at(i);
+ pMember->CheckShowEmpty( bShow );
+ }
+
+}
+
+void ScDPResultMember::CheckShowEmpty( BOOL bShow )
+{
+ if ( bHasElements )
+ {
+ ScDPResultDimension* pChildDim = GetChildDimension();
+ if (pChildDim )
+ pChildDim->CheckShowEmpty();
+ }
+ else if ( IsValid() && bInitialized )
+ {
+ bShow = bShow || ( GetParentLevel() && GetParentLevel()->getShowEmpty() );
+ if ( bShow )
+ {
+ SetHasElements();
+ ScDPResultDimension* pChildDim = GetChildDimension();
+ if (pChildDim )
+ pChildDim->CheckShowEmpty( TRUE );
+ }
+ }
+}// End Comments
diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx
new file mode 100644
index 000000000000..b4ca5dbc7330
--- /dev/null
+++ b/sc/source/core/data/dptabsrc.cxx
@@ -0,0 +1,2927 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <algorithm>
+#include <vector>
+#include <set>
+#include <hash_map>
+#include <hash_set>
+
+#include <tools/debug.hxx>
+#include <rtl/math.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/intitem.hxx>
+
+#include "scitems.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+
+#include "dptabsrc.hxx"
+#include "dptabres.hxx"
+#include "dptabdat.hxx"
+#include "global.hxx"
+#include "collect.hxx"
+#include "datauno.hxx" // ScDataUnoConversion
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "unonames.hxx"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/calendarwrapper.hxx>
+#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
+
+using namespace com::sun::star;
+using ::std::vector;
+using ::std::set;
+using ::std::hash_map;
+using ::std::hash_set;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::rtl::OUString;
+
+// -----------------------------------------------------------------------
+
+#define SC_MINCOUNT_LIMIT 1000000
+
+// -----------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScDPSource, "ScDPSource", "com.sun.star.sheet.DataPilotSource" )
+SC_SIMPLE_SERVICE_INFO( ScDPDimensions, "ScDPDimensions", "com.sun.star.sheet.DataPilotSourceDimensions" )
+SC_SIMPLE_SERVICE_INFO( ScDPDimension, "ScDPDimension", "com.sun.star.sheet.DataPilotSourceDimension" )
+SC_SIMPLE_SERVICE_INFO( ScDPHierarchies, "ScDPHierarchies", "com.sun.star.sheet.DataPilotSourceHierarcies" )
+SC_SIMPLE_SERVICE_INFO( ScDPHierarchy, "ScDPHierarchy", "com.sun.star.sheet.DataPilotSourceHierarcy" )
+SC_SIMPLE_SERVICE_INFO( ScDPLevels, "ScDPLevels", "com.sun.star.sheet.DataPilotSourceLevels" )
+SC_SIMPLE_SERVICE_INFO( ScDPLevel, "ScDPLevel", "com.sun.star.sheet.DataPilotSourceLevel" )
+SC_SIMPLE_SERVICE_INFO( ScDPMembers, "ScDPMembers", "com.sun.star.sheet.DataPilotSourceMembers" )
+SC_SIMPLE_SERVICE_INFO( ScDPMember, "ScDPMember", "com.sun.star.sheet.DataPilotSourceMember" )
+
+// -----------------------------------------------------------------------
+
+// property maps for PropertySetInfo
+// DataDescription / NumberFormat are internal
+
+// -----------------------------------------------------------------------
+
+//! move to a header?
+BOOL lcl_GetBoolFromAny( const uno::Any& aAny )
+{
+ if ( aAny.getValueTypeClass() == uno::TypeClass_BOOLEAN )
+ return *(sal_Bool*)aAny.getValue();
+ return FALSE;
+}
+
+void lcl_SetBoolInAny( uno::Any& rAny, BOOL bValue )
+{
+ rAny.setValue( &bValue, getBooleanCppuType() );
+}
+
+// -----------------------------------------------------------------------
+
+ScDPSource::ScDPSource( ScDPTableData* pD ) :
+ pData( pD ),
+ pDimensions( NULL ),
+ nColDimCount( 0 ),
+ nRowDimCount( 0 ),
+ nDataDimCount( 0 ),
+ nPageDimCount( 0 ),
+ bColumnGrand( TRUE ), // default is true
+ bRowGrand( TRUE ),
+ bIgnoreEmptyRows( FALSE ),
+ bRepeatIfEmpty( FALSE ),
+ nDupCount( 0 ),
+ pResData( NULL ),
+ pColResRoot( NULL ),
+ pRowResRoot( NULL ),
+ pColResults( NULL ),
+ pRowResults( NULL ),
+ bResultOverflow( FALSE ),
+ mpGrandTotalName(NULL)
+{
+ pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
+}
+
+ScDPSource::~ScDPSource()
+{
+ if (pDimensions)
+ pDimensions->release(); // ref-counted
+
+ //! free lists
+
+ delete[] pColResults;
+ delete[] pRowResults;
+
+ delete pColResRoot;
+ delete pRowResRoot;
+ delete pResData;
+}
+
+void ScDPSource::SetGrandTotalName(const ::rtl::OUString& rName)
+{
+ mpGrandTotalName.reset(new ::rtl::OUString(rName));
+}
+
+const ::rtl::OUString* ScDPSource::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
+USHORT ScDPSource::GetOrientation(long nColumn)
+{
+ long i;
+ for (i=0; i<nColDimCount; i++)
+ if (nColDims[i] == nColumn)
+ return sheet::DataPilotFieldOrientation_COLUMN;
+ for (i=0; i<nRowDimCount; i++)
+ if (nRowDims[i] == nColumn)
+ return sheet::DataPilotFieldOrientation_ROW;
+ for (i=0; i<nDataDimCount; i++)
+ if (nDataDims[i] == nColumn)
+ return sheet::DataPilotFieldOrientation_DATA;
+ for (i=0; i<nPageDimCount; i++)
+ if (nPageDims[i] == nColumn)
+ return sheet::DataPilotFieldOrientation_PAGE;
+ return sheet::DataPilotFieldOrientation_HIDDEN;
+}
+
+long ScDPSource::GetDataDimensionCount()
+{
+ return nDataDimCount;
+}
+
+ScDPDimension* ScDPSource::GetDataDimension(long nIndex)
+{
+ if (nIndex < 0 || nIndex >= nDataDimCount)
+ return NULL;
+
+ long nDimIndex = nDataDims[nIndex];
+ return GetDimensionsObject()->getByIndex(nDimIndex);
+}
+
+String ScDPSource::GetDataDimName( long nIndex )
+{
+ String aRet;
+ ScDPDimension* pDim = GetDataDimension(nIndex);
+ if (pDim)
+ aRet = String(pDim->getName());
+ return aRet;
+}
+
+long ScDPSource::GetPosition(long nColumn)
+{
+ long i;
+ for (i=0; i<nColDimCount; i++)
+ if (nColDims[i] == nColumn)
+ return i;
+ for (i=0; i<nRowDimCount; i++)
+ if (nRowDims[i] == nColumn)
+ return i;
+ for (i=0; i<nDataDimCount; i++)
+ if (nDataDims[i] == nColumn)
+ return i;
+ for (i=0; i<nPageDimCount; i++)
+ if (nPageDims[i] == nColumn)
+ return i;
+ return 0;
+}
+
+BOOL lcl_TestSubTotal( BOOL& rAllowed, long nColumn, long* pArray, long nCount, ScDPSource* pSource )
+{
+ for (long i=0; i<nCount; i++)
+ if (pArray[i] == nColumn)
+ {
+ // no subtotals for data layout dim, no matter where
+ if ( pSource->IsDataLayoutDimension(nColumn) )
+ rAllowed = FALSE;
+ else
+ {
+ // no subtotals if no other dim but data layout follows
+ long nNextIndex = i+1;
+ if ( nNextIndex < nCount && pSource->IsDataLayoutDimension(pArray[nNextIndex]) )
+ ++nNextIndex;
+ if ( nNextIndex >= nCount )
+ rAllowed = FALSE;
+ }
+
+ return TRUE; // found
+ }
+ return FALSE;
+}
+
+BOOL ScDPSource::SubTotalAllowed(long nColumn)
+{
+ //! cache this at ScDPResultData
+ BOOL bAllowed = TRUE;
+ if ( lcl_TestSubTotal( bAllowed, nColumn, nColDims, nColDimCount, this ) )
+ return bAllowed;
+ if ( lcl_TestSubTotal( bAllowed, nColumn, nRowDims, nRowDimCount, this ) )
+ return bAllowed;
+ return bAllowed;
+}
+
+void lcl_RemoveDim( long nRemove, long* pDims, long& rCount )
+{
+ for (long i=0; i<rCount; i++)
+ if ( pDims[i] == nRemove )
+ {
+ for (long j=i; j+1<rCount; j++)
+ pDims[j] = pDims[j+1];
+ --rCount;
+ return;
+ }
+}
+
+void ScDPSource::SetOrientation(long nColumn, USHORT nNew)
+{
+ //! change to no-op if new orientation is equal to old?
+
+ // remove from old list
+ lcl_RemoveDim( nColumn, nColDims, nColDimCount );
+ lcl_RemoveDim( nColumn, nRowDims, nRowDimCount );
+ lcl_RemoveDim( nColumn, nDataDims, nDataDimCount );
+ lcl_RemoveDim( nColumn, nPageDims, nPageDimCount );
+
+ // add to new list
+ switch (nNew)
+ {
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ nColDims[nColDimCount++] = nColumn;
+ break;
+ case sheet::DataPilotFieldOrientation_ROW:
+ nRowDims[nRowDimCount++] = nColumn;
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ nDataDims[nDataDimCount++] = nColumn;
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ nPageDims[nPageDimCount++] = nColumn;
+ break;
+ // Wang Xu Ming -- 2009-9-1
+ // DataPilot Migration - Cache&&Performance
+ case sheet::DataPilotFieldOrientation_HIDDEN:
+ break;
+ // End Comments
+ default:
+ DBG_ERROR( "ScDPSource::SetOrientation: unexpected orientation" );
+ break;
+ }
+}
+
+BOOL ScDPSource::IsDataLayoutDimension(long nDim)
+{
+ return nDim == pData->GetColumnCount();
+}
+
+USHORT ScDPSource::GetDataLayoutOrientation()
+{
+ return GetOrientation(pData->GetColumnCount());
+}
+
+BOOL ScDPSource::IsDateDimension(long nDim)
+{
+ return pData->IsDateDimension(nDim);
+}
+
+UINT32 ScDPSource::GetNumberFormat(long nDim)
+{
+ return pData->GetNumberFormat( nDim );
+}
+
+ScDPDimensions* ScDPSource::GetDimensionsObject()
+{
+ if (!pDimensions)
+ {
+ pDimensions = new ScDPDimensions(this);
+ pDimensions->acquire(); // ref-counted
+ }
+ return pDimensions;
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScDPSource::getDimensions() throw(uno::RuntimeException)
+{
+ return GetDimensionsObject();
+}
+
+void ScDPSource::SetDupCount( long nNew )
+{
+ nDupCount = nNew;
+}
+
+ScDPDimension* ScDPSource::AddDuplicated(long /* nSource */, const String& rNewName)
+{
+ DBG_ASSERT( pDimensions, "AddDuplicated without dimensions?" );
+
+ // re-use
+
+ long nOldDimCount = pDimensions->getCount();
+ for (long i=0; i<nOldDimCount; i++)
+ {
+ ScDPDimension* pDim = pDimensions->getByIndex(i);
+ if (pDim && String(pDim->getName()) == rNewName)
+ {
+ //! test if pDim is a duplicate of source
+ return pDim;
+ }
+ }
+
+ SetDupCount( nDupCount + 1 );
+ pDimensions->CountChanged(); // uses nDupCount
+
+ return pDimensions->getByIndex( pDimensions->getCount() - 1 );
+}
+
+long ScDPSource::GetSourceDim(long nDim)
+{
+ // original source dimension or data layout dimension?
+ if ( nDim <= pData->GetColumnCount() )
+ return nDim;
+
+ if ( nDim < pDimensions->getCount() )
+ {
+ ScDPDimension* pDimObj = pDimensions->getByIndex( nDim );
+ if ( pDimObj )
+ {
+ long nSource = pDimObj->GetSourceDim();
+ if ( nSource >= 0 )
+ return nSource;
+ }
+ }
+
+ DBG_ERROR("GetSourceDim: wrong dim");
+ return nDim;
+}
+
+uno::Sequence< uno::Sequence<sheet::DataResult> > SAL_CALL ScDPSource::getResults()
+ throw(uno::RuntimeException)
+{
+ CreateRes_Impl(); // create pColResRoot and pRowResRoot
+
+ if ( bResultOverflow ) // set in CreateRes_Impl
+ {
+ // no results available
+ throw uno::RuntimeException();
+ }
+
+ long nColCount = pColResRoot->GetSize(pResData->GetColStartMeasure());
+ long nRowCount = pRowResRoot->GetSize(pResData->GetRowStartMeasure());
+
+ // allocate full sequence
+ //! leave out empty rows???
+
+ uno::Sequence< uno::Sequence<sheet::DataResult> > aSeq( nRowCount );
+ uno::Sequence<sheet::DataResult>* pRowAry = aSeq.getArray();
+ for (long nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<sheet::DataResult> aColSeq( nColCount );
+ // use default values of DataResult
+ pRowAry[nRow] = aColSeq;
+ }
+
+ long nSeqRow = 0;
+ pRowResRoot->FillDataResults( pColResRoot, aSeq, nSeqRow, pResData->GetRowStartMeasure() );
+
+ return aSeq;
+}
+
+void SAL_CALL ScDPSource::refresh() throw(uno::RuntimeException)
+{
+ disposeData();
+}
+
+void SAL_CALL ScDPSource::addRefreshListener( const uno::Reference<util::XRefreshListener >& )
+ throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented"); //! exception?
+}
+
+void SAL_CALL ScDPSource::removeRefreshListener( const uno::Reference<util::XRefreshListener >& )
+ throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented"); //! exception?
+}
+
+Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& aFilters)
+ throw (uno::RuntimeException)
+{
+ long nColumnCount = GetData()->GetColumnCount();
+
+ typedef hash_map<String, long, ScStringHashCode> FieldNameMapType;
+ FieldNameMapType aFieldNames;
+ for (long i = 0; i < nColumnCount; ++i)
+ {
+ aFieldNames.insert(
+ FieldNameMapType::value_type(GetData()->getDimensionName(i), i));
+ }
+
+ // collect ScDPItemData for each filtered column
+ vector<ScDPCacheTable::Criterion> aFilterCriteria;
+ sal_Int32 nFilterCount = aFilters.getLength();
+ for (sal_Int32 i = 0; i < nFilterCount; ++i)
+ {
+ const sheet::DataPilotFieldFilter& rFilter = aFilters[i];
+ String aFieldName( rFilter.FieldName );
+ for (long nCol = 0; nCol < nColumnCount; ++nCol)
+ {
+ if ( aFieldName == pData->getDimensionName(nCol) )
+ {
+ ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nCol );
+ ScDPMembers* pMembers = pDim->GetHierarchiesObject()->getByIndex(0)->
+ GetLevelsObject()->getByIndex(0)->GetMembersObject();
+ sal_Int32 nIndex = pMembers->GetIndexFromName( rFilter.MatchValue );
+ if ( nIndex >= 0 )
+ {
+ ScDPItemData aItem;
+ pMembers->getByIndex(nIndex)->FillItemData( aItem );
+ aFilterCriteria.push_back( ScDPCacheTable::Criterion() );
+ aFilterCriteria.back().mnFieldIndex = nCol;
+ aFilterCriteria.back().mpFilter.reset(
+ new ScDPCacheTable::SingleFilter(aItem.GetString()/*rSharedString, nMatchStrId*/, aItem.GetValue(), aItem.IsValue()) );
+ }
+ }
+ }
+ }
+
+ // Take into account the visibilities of field members.
+ ScDPResultVisibilityData aResVisData(/*rSharedString, */this);
+ pRowResRoot->FillVisibilityData(aResVisData);
+ pColResRoot->FillVisibilityData(aResVisData);
+ aResVisData.fillFieldFilters(aFilterCriteria);
+
+ Sequence< Sequence<Any> > aTabData;
+ hash_set<sal_Int32> aCatDims;
+ GetCategoryDimensionIndices(aCatDims);
+ pData->GetDrillDownData(aFilterCriteria, aCatDims, aTabData);
+ return aTabData;
+}
+
+String ScDPSource::getDataDescription()
+{
+ CreateRes_Impl(); // create pResData
+
+ String aRet;
+ if ( pResData->GetMeasureCount() == 1 )
+ {
+ bool bTotalResult = false;
+ aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE, bTotalResult );
+ }
+
+ // empty for more than one measure
+
+ return aRet;
+}
+
+BOOL ScDPSource::getColumnGrand() const
+{
+ return bColumnGrand;
+}
+
+void ScDPSource::setColumnGrand(BOOL bSet)
+{
+ bColumnGrand = bSet;
+}
+
+BOOL ScDPSource::getRowGrand() const
+{
+ return bRowGrand;
+}
+
+void ScDPSource::setRowGrand(BOOL bSet)
+{
+ bRowGrand = bSet;
+}
+
+BOOL ScDPSource::getIgnoreEmptyRows() const
+{
+ return bIgnoreEmptyRows;
+}
+
+void ScDPSource::setIgnoreEmptyRows(BOOL bSet)
+{
+ bIgnoreEmptyRows = bSet;
+ pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
+}
+
+BOOL ScDPSource::getRepeatIfEmpty() const
+{
+ return bRepeatIfEmpty;
+}
+
+void ScDPSource::setRepeatIfEmpty(BOOL bSet)
+{
+ bRepeatIfEmpty = bSet;
+ pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
+}
+
+void ScDPSource::validate() //! ???
+{
+ CreateRes_Impl();
+}
+
+void ScDPSource::disposeData()
+{
+ if ( pResData )
+ {
+ // reset all data...
+
+ DELETEZ(pColResRoot);
+ DELETEZ(pRowResRoot);
+ DELETEZ(pResData);
+ delete[] pColResults;
+ delete[] pRowResults;
+ pColResults = NULL;
+ pRowResults = NULL;
+ aColLevelList.Clear();
+ aRowLevelList.Clear();
+ }
+
+ if ( pDimensions )
+ {
+ pDimensions->release(); // ref-counted
+ pDimensions = NULL; // settings have to be applied (from SaveData) again!
+ }
+ SetDupCount( 0 );
+
+ //! Test ????
+ nColDimCount = nRowDimCount = nDataDimCount = nPageDimCount = 0;
+
+ pData->DisposeData(); // cached entries etc.
+ bResultOverflow = FALSE;
+}
+
+long lcl_CountMinMembers(const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLevel, long nLevels )
+{
+ // Calculate the product of the member count for those consecutive levels that
+ // have the "show all" flag, one following level, and the data layout dimension.
+
+ long nTotal = 1;
+ long nDataCount = 1;
+ BOOL bWasShowAll = TRUE;
+ long nPos = nLevels;
+ while ( nPos > 0 )
+ {
+ --nPos;
+
+ if ( nPos+1 < nLevels && ppDim[nPos] == ppDim[nPos+1] )
+ {
+ DBG_ERROR("lcl_CountMinMembers: multiple levels from one dimension not implemented");
+ return 0;
+ }
+
+ BOOL bDo = FALSE;
+ if ( ppDim[nPos]->getIsDataLayoutDimension() )
+ {
+ // data layout dim doesn't interfere with "show all" flags
+ nDataCount = ppLevel[nPos]->GetMembersObject()->getCount();
+ if ( nDataCount == 0 )
+ nDataCount = 1;
+ }
+ else if ( bWasShowAll ) // "show all" set for all following levels?
+ {
+ bDo = TRUE;
+ if ( !ppLevel[nPos]->getShowEmpty() )
+ {
+ // this level is counted, following ones are not
+ bWasShowAll = FALSE;
+ }
+ }
+ if ( bDo )
+ {
+ long nThisCount = ppLevel[nPos]->GetMembersObject()->getMinMembers();
+ if ( nThisCount == 0 )
+ {
+ nTotal = 1; // empty level -> start counting from here
+ //! start with visible elements in this level?
+ }
+ else
+ {
+ if ( nTotal >= LONG_MAX / nThisCount )
+ return LONG_MAX; // overflow
+ nTotal *= nThisCount;
+ }
+ }
+ }
+
+ // always include data layout dim, even after restarting
+ if ( nTotal >= LONG_MAX / nDataCount )
+ return LONG_MAX; // overflow
+ nTotal *= nDataCount;
+
+ return nTotal;
+}
+
+long lcl_GetIndexFromName( const rtl::OUString rName, const uno::Sequence<rtl::OUString>& rElements )
+{
+ long nCount = rElements.getLength();
+ const rtl::OUString* pArray = rElements.getConstArray();
+ for (long nPos=0; nPos<nCount; nPos++)
+ if (pArray[nPos] == rName)
+ return nPos;
+
+ return -1; // not found
+}
+
+void ScDPSource::FillCalcInfo(bool bIsRow, ScDPTableData::CalcInfo& rInfo, bool &rHasAutoShow)
+{
+ long* nDims = bIsRow ? nRowDims : nColDims;
+ long nDimCount = bIsRow ? nRowDimCount : nColDimCount;
+
+ for (long i = 0; i < nDimCount; ++i)
+ {
+ ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nDims[i] );
+ long nHierarchy = pDim->getUsedHierarchy();
+ if ( nHierarchy >= pDim->GetHierarchiesObject()->getCount() )
+ nHierarchy = 0;
+ ScDPLevels* pLevels = pDim->GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
+ long nCount = pLevels->getCount();
+
+ //! Test
+ if ( pDim->getIsDataLayoutDimension() && nDataDimCount < 2 )
+ nCount = 0;
+ //! Test
+
+ for (long j = 0; j < nCount; ++j)
+ {
+ ScDPLevel* pLevel = pLevels->getByIndex(j);
+ pLevel->EvaluateSortOrder();
+
+ // no layout flags for column fields, only for row fields
+ pLevel->SetEnableLayout( bIsRow );
+
+ if ( pLevel->GetAutoShow().IsEnabled )
+ rHasAutoShow = TRUE;
+
+ if (bIsRow)
+ {
+ rInfo.aRowLevelDims.push_back(nDims[i]);
+ rInfo.aRowDims.push_back(pDim);
+ rInfo.aRowLevels.push_back(pLevel);
+ }
+ else
+ {
+ rInfo.aColLevelDims.push_back(nDims[i]);
+ rInfo.aColDims.push_back(pDim);
+ rInfo.aColLevels.push_back(pLevel);
+ }
+
+ pLevel->GetMembersObject(); // initialize for groups
+ }
+ }
+}
+
+void ScDPSource::GetCategoryDimensionIndices(hash_set<sal_Int32>& rCatDims)
+{
+ hash_set<sal_Int32> aCatDims;
+ for (long i = 0; i < nColDimCount; ++i)
+ {
+ sal_Int32 nDim = static_cast<sal_Int32>(nColDims[i]);
+ if (!IsDataLayoutDimension(nDim))
+ aCatDims.insert(nDim);
+ }
+
+ for (long i = 0; i < nRowDimCount; ++i)
+ {
+ sal_Int32 nDim = static_cast<sal_Int32>(nRowDims[i]);
+ if (!IsDataLayoutDimension(nDim))
+ aCatDims.insert(nDim);
+ }
+
+ for (long i = 0; i < nPageDimCount; ++i)
+ {
+ sal_Int32 nDim = static_cast<sal_Int32>(nPageDims[i]);
+ if (!IsDataLayoutDimension(nDim))
+ aCatDims.insert(nDim);
+ }
+
+ rCatDims.swap(aCatDims);
+}
+
+void ScDPSource::FilterCacheTableByPageDimensions()
+{
+
+ // filter table by page dimensions.
+ vector<ScDPCacheTable::Criterion> aCriteria;
+ for (long i = 0; i < nPageDimCount; ++i)
+ {
+ ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nPageDims[i]);
+ long nField = pDim->GetDimension();
+
+ ScDPMembers* pMems = pDim->GetHierarchiesObject()->getByIndex(0)->
+ GetLevelsObject()->getByIndex(0)->GetMembersObject();
+
+ long nMemCount = pMems->getCount();
+ ScDPCacheTable::Criterion aFilter;
+ aFilter.mnFieldIndex = static_cast<sal_Int32>(nField);
+ aFilter.mpFilter.reset(new ScDPCacheTable::GroupFilter(/*rSharedString*/));
+ ScDPCacheTable::GroupFilter* pGrpFilter =
+ static_cast<ScDPCacheTable::GroupFilter*>(aFilter.mpFilter.get());
+ for (long j = 0; j < nMemCount; ++j)
+ {
+ ScDPMember* pMem = pMems->getByIndex(j);
+ if (pMem->getIsVisible())
+ {
+ ScDPItemData aData;
+ pMem->FillItemData(aData);
+ pGrpFilter->addMatchItem(aData.GetString(), aData.GetValue(), aData.IsValue());
+ }
+ }
+ if (pGrpFilter->getMatchItemCount() < static_cast<size_t>(nMemCount))
+ // there is at least one invisible item. Add this filter criterion to the mix.
+ aCriteria.push_back(aFilter);
+
+ if (!pDim || !pDim->HasSelectedPage())
+ continue;
+
+ const ScDPItemData& rData = pDim->GetSelectedData();
+ aCriteria.push_back(ScDPCacheTable::Criterion());
+ ScDPCacheTable::Criterion& r = aCriteria.back();
+ r.mnFieldIndex = static_cast<sal_Int32>(nField);
+ r.mpFilter.reset(
+ new ScDPCacheTable::SingleFilter(rData.GetString()/*rSharedString, nStrId*/, rData.GetValue(), rData.IsValue()));
+ }
+ if (!aCriteria.empty())
+ {
+ hash_set<sal_Int32> aCatDims;
+ GetCategoryDimensionIndices(aCatDims);
+ pData->FilterCacheTable(aCriteria, aCatDims);
+ }
+}
+
+void ScDPSource::CreateRes_Impl()
+{
+ if ( !pResData )
+ {
+ USHORT nDataOrient = GetDataLayoutOrientation();
+ if ( nDataDimCount > 1 && ( nDataOrient != sheet::DataPilotFieldOrientation_COLUMN &&
+ nDataOrient != sheet::DataPilotFieldOrientation_ROW ) )
+ {
+ // if more than one data dimension, data layout orientation must be set
+ SetOrientation( pData->GetColumnCount(), sheet::DataPilotFieldOrientation_ROW );
+ nDataOrient = sheet::DataPilotFieldOrientation_ROW;
+ }
+
+ // TODO: Aggreate pDataNames, pDataRefValues, nDataRefOrient, and
+ // eDataFunctions into a structure and use vector instead of static
+ // or pointer arrays.
+ String* pDataNames = NULL;
+ sheet::DataPilotFieldReference* pDataRefValues = NULL;
+ ScSubTotalFunc eDataFunctions[SC_DAPI_MAXFIELDS];
+ USHORT nDataRefOrient[SC_DAPI_MAXFIELDS];
+ if (nDataDimCount)
+ {
+ pDataNames = new String[nDataDimCount];
+ pDataRefValues = new sheet::DataPilotFieldReference[nDataDimCount];
+ }
+
+ ScDPTableData::CalcInfo aInfo;
+
+
+ // LateInit (initialize only those rows/children that are used) can be used unless
+ // any data dimension needs reference values from column/row dimensions
+ BOOL bLateInit = TRUE;
+
+ // Go through all data dimensions (i.e. fields) and build their meta data
+ // so that they can be passed on to ScDPResultData instance later.
+ // TODO: aggregate all of data dimension info into a structure.
+ long i;
+ for (i=0; i<nDataDimCount; i++)
+ {
+ // Get function for each data field.
+ long nDimIndex = nDataDims[i];
+ ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
+ sheet::GeneralFunction eUser = (sheet::GeneralFunction)pDim->getFunction();
+ if (eUser == sheet::GeneralFunction_AUTO)
+ {
+ //! test for numeric data
+ eUser = sheet::GeneralFunction_SUM;
+ }
+
+ // Map UNO's enum to internal enum ScSubTotalFunc.
+ eDataFunctions[i] = ScDataUnoConversion::GeneralToSubTotal( eUser );
+
+ // Get reference field/item information.
+ pDataRefValues[i] = pDim->GetReferenceValue();
+ nDataRefOrient[i] = sheet::DataPilotFieldOrientation_HIDDEN; // default if not used
+ sal_Int32 eRefType = pDataRefValues[i].ReferenceType;
+ if ( eRefType == sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE ||
+ eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE ||
+ eRefType == sheet::DataPilotFieldReferenceType::RUNNING_TOTAL )
+ {
+ long nColumn = lcl_GetIndexFromName( pDataRefValues[i].ReferenceField,
+ GetDimensionsObject()->getElementNames() );
+ if ( nColumn >= 0 )
+ {
+ nDataRefOrient[i] = GetOrientation( nColumn );
+ // need fully initialized results to find reference values
+ // (both in column or row dimensions), so updated values or
+ // differences to 0 can be displayed even for empty results.
+ bLateInit = FALSE;
+ }
+ }
+
+ pDataNames[i] = String( pDim->getName() ); //! label?
+
+ // asterisk is added to duplicated dimension names by ScDPSaveData::WriteToSource
+ //! modify user visible strings as in ScDPResultData::GetMeasureString instead!
+
+ pDataNames[i].EraseTrailingChars('*');
+
+ //! if the name is overridden by user, a flag must be set
+ //! so the user defined name replaces the function string and field name.
+
+ //! the complete name (function and field) must be stored at the dimension
+
+ long nSource = ((ScDPDimension*)pDim)->GetSourceDim();
+ if (nSource >= 0)
+ aInfo.aDataSrcCols.push_back(nSource);
+ else
+ aInfo.aDataSrcCols.push_back(nDimIndex);
+ }
+
+ pResData = new ScDPResultData( this );
+ pResData->SetMeasureData( nDataDimCount, eDataFunctions, pDataRefValues, nDataRefOrient, pDataNames );
+ pResData->SetDataLayoutOrientation(nDataOrient);
+ pResData->SetLateInit( bLateInit );
+
+ delete[] pDataNames;
+ delete[] pDataRefValues;
+
+ bool bHasAutoShow = false;
+
+ ScDPInitState aInitState;
+
+ // Page field selections restrict the members shown in related fields
+ // (both in column and row fields). aInitState is filled with the page
+ // field selections, they are kept across the data iterator loop.
+
+ for (i=0; i<nPageDimCount; i++)
+ {
+ ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nPageDims[i] );
+ if ( pDim->HasSelectedPage() )
+ aInitState.AddMember( nPageDims[i], GetMemberId( nPageDims[i], pDim->GetSelectedData() ) );
+ }
+
+ pColResRoot = new ScDPResultMember( pResData, /*NULL, NULL, NULL, */bColumnGrand );
+ pRowResRoot = new ScDPResultMember( pResData, /*NULL, NULL, NULL, */bRowGrand );
+
+ FillCalcInfo(false, aInfo, bHasAutoShow);
+ long nColLevelCount = aInfo.aColLevels.size();
+
+ pColResRoot->InitFrom( aInfo.aColDims, aInfo.aColLevels, 0, aInitState );
+ pColResRoot->SetHasElements();
+
+ FillCalcInfo(true, aInfo, bHasAutoShow);
+ long nRowLevelCount = aInfo.aRowLevels.size();
+
+ if ( nRowLevelCount > 0 )
+ {
+ // disable layout flags for the innermost row field (level)
+ aInfo.aRowLevels[nRowLevelCount-1]->SetEnableLayout( FALSE );
+ }
+
+ pRowResRoot->InitFrom( aInfo.aRowDims, aInfo.aRowLevels, 0, aInitState );
+ pRowResRoot->SetHasElements();
+
+ // initialize members object also for all page dimensions (needed for numeric groups)
+ for (i=0; i<nPageDimCount; i++)
+ {
+ ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nPageDims[i] );
+ long nHierarchy = pDim->getUsedHierarchy();
+ if ( nHierarchy >= pDim->GetHierarchiesObject()->getCount() )
+ nHierarchy = 0;
+
+ ScDPLevels* pLevels = pDim->GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
+ long nCount = pLevels->getCount();
+ for (long j=0; j<nCount; j++)
+ pLevels->getByIndex(j)->GetMembersObject(); // initialize for groups
+ }
+
+ // pre-check: calculate minimum number of result columns / rows from
+ // levels that have the "show all" flag set
+
+ long nMinColMembers = lcl_CountMinMembers( aInfo.aColDims, aInfo.aColLevels, nColLevelCount );
+ long nMinRowMembers = lcl_CountMinMembers( aInfo.aRowDims, aInfo.aRowLevels, nRowLevelCount );
+
+ if ( nMinColMembers > MAXCOLCOUNT/*SC_MINCOUNT_LIMIT*/ || nMinRowMembers > SC_MINCOUNT_LIMIT )
+ {
+ // resulting table is too big -> abort before calculating
+ // (this relies on late init, so no members are allocated in InitFrom above)
+
+ bResultOverflow = TRUE;
+ }
+ else
+ {
+ FilterCacheTableByPageDimensions();
+
+ aInfo.aPageDims.reserve(nPageDimCount);
+ for (i = 0; i < nPageDimCount; ++i)
+ aInfo.aPageDims.push_back(nPageDims[i]);
+
+ aInfo.pInitState = &aInitState;
+ aInfo.pColRoot = pColResRoot;
+ aInfo.pRowRoot = pRowResRoot;
+ pData->CalcResults(aInfo, false);
+
+ pColResRoot->CheckShowEmpty();
+ pRowResRoot->CheckShowEmpty();
+ // ----------------------------------------------------------------
+ // With all data processed, calculate the final results:
+
+ // UpdateDataResults calculates all original results from the collected values,
+ // and stores them as reference values if needed.
+ pRowResRoot->UpdateDataResults( pColResRoot, pResData->GetRowStartMeasure() );
+
+ if ( bHasAutoShow ) // do the double calculation only if AutoShow is used
+ {
+ // Find the desired members and set bAutoHidden flag for the others
+ pRowResRoot->DoAutoShow( pColResRoot );
+
+ // Reset all results to empty, so they can be built again with data for the
+ // desired members only.
+ pColResRoot->ResetResults( TRUE );
+ pRowResRoot->ResetResults( TRUE );
+ pData->CalcResults(aInfo, true);
+
+ // Call UpdateDataResults again, with the new (limited) values.
+ pRowResRoot->UpdateDataResults( pColResRoot, pResData->GetRowStartMeasure() );
+ }
+
+ // SortMembers does the sorting by a result dimension, using the orginal results,
+ // but not running totals etc.
+ pRowResRoot->SortMembers( pColResRoot );
+
+ // UpdateRunningTotals calculates running totals along column/row dimensions,
+ // differences from other members (named or relative), and column/row percentages
+ // or index values.
+ // Running totals and relative differences need to be done using the sorted values.
+ // Column/row percentages and index values must be done after sorting, because the
+ // results may no longer be in the right order (row total for percentage of row is
+ // always 1).
+ ScDPRunningTotalState aRunning( pColResRoot, pRowResRoot );
+ ScDPRowTotals aTotals;
+ pRowResRoot->UpdateRunningTotals( pColResRoot, pResData->GetRowStartMeasure(), aRunning, aTotals );
+
+ // ----------------------------------------------------------------
+ }
+ }
+}
+
+//UNUSED2009-05 void ScDPSource::DumpState( ScDocument* pDoc, const ScAddress& rPos )
+//UNUSED2009-05 {
+//UNUSED2009-05 CreateRes_Impl();
+//UNUSED2009-05
+//UNUSED2009-05 ScAddress aDocPos( rPos );
+//UNUSED2009-05
+//UNUSED2009-05 if (pColResRoot->GetChildDimension())
+//UNUSED2009-05 pColResRoot->GetChildDimension()->DumpState( NULL, pDoc, aDocPos );
+//UNUSED2009-05 pRowResRoot->DumpState( pColResRoot, pDoc, aDocPos );
+//UNUSED2009-05 }
+
+void ScDPSource::FillLevelList( USHORT nOrientation, List& rList )
+{
+ rList.Clear();
+
+ long nDimCount = 0;
+ long* pDimIndex = NULL;
+ switch (nOrientation)
+ {
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ pDimIndex = nColDims;
+ nDimCount = nColDimCount;
+ break;
+ case sheet::DataPilotFieldOrientation_ROW:
+ pDimIndex = nRowDims;
+ nDimCount = nRowDimCount;
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ pDimIndex = nDataDims;
+ nDimCount = nDataDimCount;
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ pDimIndex = nPageDims;
+ nDimCount = nPageDimCount;
+ break;
+ default:
+ DBG_ERROR( "ScDPSource::FillLevelList: unexpected orientation" );
+ break;
+ }
+ if (!pDimIndex)
+ {
+ DBG_ERROR("invalid orientation");
+ return;
+ }
+
+ ScDPDimensions* pDims = GetDimensionsObject();
+ for (long nDim=0; nDim<nDimCount; nDim++)
+ {
+ ScDPDimension* pDim = pDims->getByIndex(pDimIndex[nDim]);
+ DBG_ASSERT( pDim->getOrientation() == nOrientation, "orientations are wrong" );
+
+ ScDPHierarchies* pHiers = pDim->GetHierarchiesObject();
+ long nHierarchy = pDim->getUsedHierarchy();
+ if ( nHierarchy >= pHiers->getCount() )
+ nHierarchy = 0;
+ ScDPHierarchy* pHier = pHiers->getByIndex(nHierarchy);
+ ScDPLevels* pLevels = pHier->GetLevelsObject();
+ long nLevCount = pLevels->getCount();
+ for (long nLev=0; nLev<nLevCount; nLev++)
+ {
+ ScDPLevel* pLevel = pLevels->getByIndex(nLev);
+ rList.Insert( pLevel, LIST_APPEND );
+ }
+ }
+}
+
+void ScDPSource::FillMemberResults()
+{
+ if ( !pColResults && !pRowResults )
+ {
+ CreateRes_Impl();
+
+ if ( bResultOverflow ) // set in CreateRes_Impl
+ {
+ // no results available -> abort (leave empty)
+ // exception is thrown in ScDPSource::getResults
+ return;
+ }
+
+ FillLevelList( sheet::DataPilotFieldOrientation_COLUMN, aColLevelList );
+ long nColLevelCount = aColLevelList.Count();
+ if (nColLevelCount)
+ {
+ long nColDimSize = pColResRoot->GetSize(pResData->GetColStartMeasure());
+ pColResults = new uno::Sequence<sheet::MemberResult>[nColLevelCount];
+ for (long i=0; i<nColLevelCount; i++)
+ pColResults[i].realloc(nColDimSize);
+
+ // ScDPResultDimension* pColResDim = pColResRoot->GetChildDimension();
+ // pColResDim->FillMemberResults( pColResults, 0, pResData->GetColStartMeasure() );
+ long nPos = 0;
+ pColResRoot->FillMemberResults( pColResults, nPos, pResData->GetColStartMeasure(),
+ TRUE, NULL, NULL );
+ }
+
+ FillLevelList( sheet::DataPilotFieldOrientation_ROW, aRowLevelList );
+ long nRowLevelCount = aRowLevelList.Count();
+ if (nRowLevelCount)
+ {
+ long nRowDimSize = pRowResRoot->GetSize(pResData->GetRowStartMeasure());
+ pRowResults = new uno::Sequence<sheet::MemberResult>[nRowLevelCount];
+ for (long i=0; i<nRowLevelCount; i++)
+ pRowResults[i].realloc(nRowDimSize);
+
+ // ScDPResultDimension* pRowResDim = pRowResRoot->GetChildDimension();
+ // pRowResDim->FillMemberResults( pRowResults, 0, pResData->GetRowStartMeasure() );
+ long nPos = 0;
+ pRowResRoot->FillMemberResults( pRowResults, nPos, pResData->GetRowStartMeasure(),
+ TRUE, NULL, NULL );
+ }
+ }
+}
+
+const uno::Sequence<sheet::MemberResult>* ScDPSource::GetMemberResults( ScDPLevel* pLevel )
+{
+ FillMemberResults();
+
+ long i;
+ long nColCount = aColLevelList.Count();
+ for (i=0; i<nColCount; i++)
+ {
+ ScDPLevel* pColLevel = (ScDPLevel*)aColLevelList.GetObject(i);
+ if ( pColLevel == pLevel )
+ return pColResults+i;
+ }
+ long nRowCount = aRowLevelList.Count();
+ for (i=0; i<nRowCount; i++)
+ {
+ ScDPLevel* pRowLevel = (ScDPLevel*)aRowLevelList.GetObject(i);
+ if ( pRowLevel == pLevel )
+ return pRowResults+i;
+ }
+ return NULL;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ using beans::PropertyAttribute::READONLY;
+
+ static SfxItemPropertyMapEntry aDPSourceMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_COLGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_DATADESC), 0, &getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_IGNOREEM), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
+ {MAP_CHAR_LEN(SC_UNO_REPEATIF), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
+ {MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME), 0, &getCppuType(static_cast<OUString*>(0)), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( aDPSourceMap_Impl );
+ return aRef;
+}
+
+void SAL_CALL ScDPSource::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_COLGRAND ) )
+ setColumnGrand( lcl_GetBoolFromAny( aValue ) );
+ else if ( aNameStr.EqualsAscii( SC_UNO_ROWGRAND ) )
+ setRowGrand( lcl_GetBoolFromAny( aValue ) );
+ else if ( aNameStr.EqualsAscii( SC_UNO_IGNOREEM ) )
+ setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue ) );
+ else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) )
+ setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) );
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ OUString aName;
+ if (aValue >>= aName)
+ mpGrandTotalName.reset(new OUString(aName));
+ }
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+}
+
+uno::Any SAL_CALL ScDPSource::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ uno::Any aRet;
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_COLGRAND ) )
+ lcl_SetBoolInAny( aRet, getColumnGrand() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_ROWGRAND ) )
+ lcl_SetBoolInAny( aRet, getRowGrand() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_IGNOREEM ) )
+ lcl_SetBoolInAny( aRet, getIgnoreEmptyRows() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) )
+ lcl_SetBoolInAny( aRet, getRepeatIfEmpty() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_DATADESC ) ) // read-only
+ aRet <<= rtl::OUString( getDataDescription() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_ROWFIELDCOUNT ) ) // read-only
+ aRet <<= static_cast<sal_Int32>(nRowDimCount);
+ else if ( aNameStr.EqualsAscii( SC_UNO_COLUMNFIELDCOUNT ) ) // read-only
+ aRet <<= static_cast<sal_Int32>(nColDimCount);
+ else if ( aNameStr.EqualsAscii( SC_UNO_DATAFIELDCOUNT ) ) // read-only
+ aRet <<= static_cast<sal_Int32>(nDataDimCount);
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ if (mpGrandTotalName.get())
+ aRet <<= *mpGrandTotalName;
+ }
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPSource )
+
+// -----------------------------------------------------------------------
+
+ScDPDimensions::ScDPDimensions( ScDPSource* pSrc ) :
+ pSource( pSrc ),
+ ppDims( NULL )
+{
+ //! hold pSource
+
+ // include data layout dimension and duplicated dimensions
+ nDimCount = pSource->GetData()->GetColumnCount() + 1 + pSource->GetDupCount();
+}
+
+ScDPDimensions::~ScDPDimensions()
+{
+ //! release pSource
+
+ if (ppDims)
+ {
+ for (long i=0; i<nDimCount; i++)
+ if ( ppDims[i] )
+ ppDims[i]->release(); // ref-counted
+ delete[] ppDims;
+ }
+}
+
+void ScDPDimensions::CountChanged()
+{
+ // include data layout dimension and duplicated dimensions
+ long nNewCount = pSource->GetData()->GetColumnCount() + 1 + pSource->GetDupCount();
+ if ( ppDims )
+ {
+ long i;
+ long nCopy = Min( nNewCount, nDimCount );
+ ScDPDimension** ppNew = new ScDPDimension*[nNewCount];
+
+ for (i=0; i<nCopy; i++) // copy existing dims
+ ppNew[i] = ppDims[i];
+ for (i=nCopy; i<nNewCount; i++) // clear additional pointers
+ ppNew[i] = NULL;
+ for (i=nCopy; i<nDimCount; i++) // delete old dims if count is decreased
+ if ( ppDims[i] )
+ ppDims[i]->release(); // ref-counted
+
+ delete[] ppDims;
+ ppDims = ppNew;
+ }
+ nDimCount = nNewCount;
+}
+
+// very simple XNameAccess implementation using getCount/getByIndex
+
+uno::Any SAL_CALL ScDPDimensions::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ long nCount = getCount();
+ for (long i=0; i<nCount; i++)
+ if ( getByIndex(i)->getName() == aName )
+ {
+ uno::Reference<container::XNamed> xNamed = getByIndex(i);
+ uno::Any aRet;
+ aRet <<= xNamed;
+ return aRet;
+ }
+
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDPDimensions::getElementNames() throw(uno::RuntimeException)
+{
+ long nCount = getCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pArr = aSeq.getArray();
+ for (long i=0; i<nCount; i++)
+ pArr[i] = getByIndex(i)->getName();
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScDPDimensions::hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ long nCount = getCount();
+ for (long i=0; i<nCount; i++)
+ if ( getByIndex(i)->getName() == aName )
+ return TRUE;
+ return FALSE;
+}
+
+uno::Type SAL_CALL ScDPDimensions::getElementType() throw(uno::RuntimeException)
+{
+ return getCppuType((uno::Reference<container::XNamed>*)0);
+}
+
+sal_Bool SAL_CALL ScDPDimensions::hasElements() throw(uno::RuntimeException)
+{
+ return ( getCount() > 0 );
+}
+
+// end of XNameAccess implementation
+
+long ScDPDimensions::getCount() const
+{
+ // in tabular data, every column of source data is a dimension
+
+ return nDimCount;
+}
+
+ScDPDimension* ScDPDimensions::getByIndex(long nIndex) const
+{
+ if ( nIndex >= 0 && nIndex < nDimCount )
+ {
+ if ( !ppDims )
+ {
+ ((ScDPDimensions*)this)->ppDims = new ScDPDimension*[nDimCount];
+ for (long i=0; i<nDimCount; i++)
+ ppDims[i] = NULL;
+ }
+ if ( !ppDims[nIndex] )
+ {
+ ppDims[nIndex] = new ScDPDimension( pSource, nIndex );
+ ppDims[nIndex]->acquire(); // ref-counted
+ }
+
+ return ppDims[nIndex];
+ }
+
+ return NULL; //! exception?
+}
+
+// -----------------------------------------------------------------------
+
+ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ pHierarchies( NULL ),
+ nUsedHier( 0 ),
+ nFunction( SUBTOTAL_FUNC_SUM ), // sum is default
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
+ nSourceDim( -1 ),
+ bHasSelectedPage( FALSE ),
+ pSelectedData( NULL ),
+ mbHasHiddenMember(false)
+{
+ //! hold pSource
+}
+
+ScDPDimension::~ScDPDimension()
+{
+ //! release pSource
+
+ if ( pHierarchies )
+ pHierarchies->release(); // ref-counted
+
+ delete pSelectedData;
+}
+
+ScDPHierarchies* ScDPDimension::GetHierarchiesObject()
+{
+ if (!pHierarchies)
+ {
+ pHierarchies = new ScDPHierarchies( pSource, nDim );
+ pHierarchies->acquire(); // ref-counted
+ }
+ return pHierarchies;
+}
+
+const rtl::OUString* ScDPDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+const rtl::OUString* ScDPDimension::GetSubtotalName() const
+{
+ return mpSubtotalName.get();
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScDPDimension::getHierarchies()
+ throw(uno::RuntimeException)
+{
+ return GetHierarchiesObject();
+}
+
+::rtl::OUString SAL_CALL ScDPDimension::getName() throw(uno::RuntimeException)
+{
+ if (aName.Len())
+ return aName;
+ else
+ return pSource->GetData()->getDimensionName( nDim );
+}
+
+void SAL_CALL ScDPDimension::setName( const ::rtl::OUString& rNewName ) throw(uno::RuntimeException)
+{
+ // used after cloning
+ aName = String( rNewName );
+}
+
+USHORT ScDPDimension::getOrientation() const
+{
+ return pSource->GetOrientation( nDim );
+}
+
+void ScDPDimension::setOrientation(USHORT nNew)
+{
+ pSource->SetOrientation( nDim, nNew );
+}
+
+long ScDPDimension::getPosition() const
+{
+ return pSource->GetPosition( nDim );
+}
+
+void ScDPDimension::setPosition(long /* nNew */)
+{
+ //! ...
+}
+
+BOOL ScDPDimension::getIsDataLayoutDimension() const
+{
+ return pSource->GetData()->getIsDataLayoutDimension( nDim );
+}
+
+USHORT ScDPDimension::getFunction() const
+{
+ return nFunction;
+}
+
+void ScDPDimension::setFunction(USHORT nNew)
+{
+ nFunction = nNew;
+}
+
+long ScDPDimension::getUsedHierarchy() const
+{
+ return nUsedHier;
+}
+
+void ScDPDimension::setUsedHierarchy(long /* nNew */)
+{
+ // #i52547# don't use the incomplete date hierarchy implementation - ignore the call
+ // nUsedHier = nNew;
+}
+
+ScDPDimension* ScDPDimension::CreateCloneObject()
+{
+ DBG_ASSERT( nSourceDim < 0, "recursive duplicate - not implemented" );
+
+ //! set new name here, or temporary name ???
+ String aNewName = aName;
+
+ ScDPDimension* pNew = pSource->AddDuplicated( nDim, aNewName );
+
+ pNew->aName = aNewName; //! here or in source?
+ pNew->nSourceDim = nDim; //! recursive?
+
+ return pNew;
+}
+
+uno::Reference<util::XCloneable> SAL_CALL ScDPDimension::createClone() throw(uno::RuntimeException)
+{
+ return CreateCloneObject();
+}
+
+BOOL ScDPDimension::isDuplicated() const
+{
+ return (nSourceDim >= 0);
+}
+
+const sheet::DataPilotFieldReference& ScDPDimension::GetReferenceValue() const
+{
+ return aReferenceValue;
+}
+
+const ScDPItemData& ScDPDimension::GetSelectedData()
+{
+ if ( !pSelectedData )
+ {
+ // find the named member to initialize pSelectedData from it, with name and value
+
+ long nLevel = 0; // same as in ScDPObject::FillPageList
+
+ long nHierarchy = getUsedHierarchy();
+ if ( nHierarchy >= GetHierarchiesObject()->getCount() )
+ nHierarchy = 0;
+ ScDPLevels* pLevels = GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
+ long nLevCount = pLevels->getCount();
+ if ( nLevel < nLevCount )
+ {
+ ScDPMembers* pMembers = pLevels->getByIndex(nLevel)->GetMembersObject();
+
+ //! merge with ScDPMembers::getByName
+ long nCount = pMembers->getCount();
+ for (long i=0; i<nCount && !pSelectedData; i++)
+ {
+ ScDPMember* pMember = pMembers->getByIndex(i);
+ if ( pMember->GetNameStr() == aSelectedPage )
+ {
+ pSelectedData = new ScDPItemData();
+ pMember->FillItemData( *pSelectedData );
+ }
+ }
+ }
+
+ if ( !pSelectedData )
+ pSelectedData = new ScDPItemData( aSelectedPage, 0.0, FALSE ); // default - name only
+ }
+
+ return *pSelectedData;
+}
+
+//UNUSED2009-05 BOOL ScDPDimension::IsValidPage( const ScDPItemData& rData )
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( bHasSelectedPage )
+//UNUSED2009-05 return rData.IsCaseInsEqual( GetSelectedData() );
+//UNUSED2009-05
+//UNUSED2009-05 return TRUE; // no selection -> all data
+//UNUSED2009-05 }
+
+BOOL ScDPDimension::IsVisible( const ScDPItemData& rData )
+{
+ if( ScDPMembers* pMembers = this->GetHierarchiesObject()->getByIndex(0)->
+ GetLevelsObject()->getByIndex(0)->GetMembersObject() )
+ {
+ for( long i = pMembers->getCount()-1; i>=0; i-- )
+ if( ScDPMember *pDPMbr = pMembers->getByIndex( i ) )
+ if( rData.IsCaseInsEqual( pDPMbr->GetItemData() ) && !pDPMbr->getIsVisible() )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ static SfxItemPropertyMapEntry aDPDimensionMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_FILTER), 0, &getCppuType((uno::Sequence<sheet::TableFilterField>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_FLAGS), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_FUNCTION), 0, &getCppuType((sheet::GeneralFunction*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ISDATALA), 0, &getBooleanCppuType(), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_NUMBERFO), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ORIENTAT), 0, &getCppuType((sheet::DataPilotFieldOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ORIGINAL), 0, &getCppuType((uno::Reference<container::XNamed>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_REFVALUE), 0, &getCppuType((sheet::DataPilotFieldReference*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_HAS_HIDDEN_MEMBER), 0, &getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( aDPDimensionMap_Impl );
+ return aRef;
+}
+
+void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
+ {
+ INT32 nInt = 0;
+ if (aValue >>= nInt)
+ setPosition( nInt );
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_USEDHIER ) )
+ {
+ INT32 nInt = 0;
+ if (aValue >>= nInt)
+ setUsedHierarchy( nInt );
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_ORIENTAT ) )
+ {
+ sheet::DataPilotFieldOrientation eEnum;
+ if (aValue >>= eEnum)
+ setOrientation( sal::static_int_cast<USHORT>(eEnum) );
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_FUNCTION ) )
+ {
+ sheet::GeneralFunction eEnum;
+ if (aValue >>= eEnum)
+ setFunction( sal::static_int_cast<USHORT>(eEnum) );
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_REFVALUE ) )
+ aValue >>= aReferenceValue;
+ else if ( aNameStr.EqualsAscii( SC_UNO_FILTER ) )
+ {
+ BOOL bDone = FALSE;
+ uno::Sequence<sheet::TableFilterField> aSeq;
+ if (aValue >>= aSeq)
+ {
+ sal_Int32 nLength = aSeq.getLength();
+ if ( nLength == 0 )
+ {
+ aSelectedPage.Erase();
+ bHasSelectedPage = FALSE;
+ bDone = TRUE;
+ }
+ else if ( nLength == 1 )
+ {
+ const sheet::TableFilterField& rField = aSeq[0];
+ if ( rField.Field == 0 && rField.Operator == sheet::FilterOperator_EQUAL && !rField.IsNumeric )
+ {
+ aSelectedPage = rField.StringValue;
+ bHasSelectedPage = TRUE;
+ bDone = TRUE;
+ }
+ }
+ }
+ if ( !bDone )
+ {
+ DBG_ERROR("Filter property is not a single string");
+ throw lang::IllegalArgumentException();
+ }
+ DELETEZ( pSelectedData ); // invalid after changing aSelectedPage
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpLayoutName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpSubtotalName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
+ aValue >>= mbHasHiddenMember;
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+}
+
+uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ uno::Any aRet;
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
+ aRet <<= (sal_Int32) getPosition();
+ else if ( aNameStr.EqualsAscii( SC_UNO_USEDHIER ) )
+ aRet <<= (sal_Int32) getUsedHierarchy();
+ else if ( aNameStr.EqualsAscii( SC_UNO_ORIENTAT ) )
+ {
+ sheet::DataPilotFieldOrientation eVal = (sheet::DataPilotFieldOrientation)getOrientation();
+ aRet <<= eVal;
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_FUNCTION ) )
+ {
+ sheet::GeneralFunction eVal = (sheet::GeneralFunction)getFunction();
+ aRet <<= eVal;
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_REFVALUE ) )
+ aRet <<= aReferenceValue;
+ else if ( aNameStr.EqualsAscii( SC_UNO_ISDATALA ) ) // read-only properties
+ lcl_SetBoolInAny( aRet, getIsDataLayoutDimension() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_NUMBERFO ) )
+ {
+ sal_Int32 nFormat = 0;
+ sheet::GeneralFunction eFunc = (sheet::GeneralFunction)getFunction();
+ // #i63745# don't use source format for "count"
+ if ( eFunc != sheet::GeneralFunction_COUNT && eFunc != sheet::GeneralFunction_COUNTNUMS )
+ nFormat = pSource->GetData()->GetNumberFormat( ( nSourceDim >= 0 ) ? nSourceDim : nDim );
+
+ switch ( aReferenceValue.ReferenceType )
+ {
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE:
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
+ case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE:
+ case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE:
+ case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE:
+ nFormat = pSource->GetData()->GetNumberFormatByIdx( (NfIndexTableOffset)NF_PERCENT_DEC2 );
+ break;
+ case sheet::DataPilotFieldReferenceType::INDEX:
+ nFormat = pSource->GetData()->GetNumberFormatByIdx( (NfIndexTableOffset)NF_NUMBER_SYSTEM );
+ break;
+ default:
+ break;
+ }
+
+ aRet <<= nFormat;
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_ORIGINAL ) )
+ {
+ uno::Reference<container::XNamed> xOriginal;
+ if (nSourceDim >= 0)
+ xOriginal = pSource->GetDimensionsObject()->getByIndex(nSourceDim);
+ aRet <<= xOriginal;
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_FILTER ) )
+ {
+ if ( bHasSelectedPage )
+ {
+ // single filter field: first field equal to selected string
+ sheet::TableFilterField aField( sheet::FilterConnection_AND, 0,
+ sheet::FilterOperator_EQUAL, sal_False, 0.0, aSelectedPage );
+ aRet <<= uno::Sequence<sheet::TableFilterField>( &aField, 1 );
+ }
+ else
+ aRet <<= uno::Sequence<sheet::TableFilterField>(0);
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
+ aRet <<= mbHasHiddenMember;
+ else if (aNameStr.EqualsAscii(SC_UNO_FLAGS))
+ {
+ sal_Int32 nFlags = 0; // tabular data: all orientations are possible
+ aRet <<= nFlags;
+ }
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPDimension )
+
+// -----------------------------------------------------------------------
+
+ScDPHierarchies::ScDPHierarchies( ScDPSource* pSrc, long nD ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ ppHiers( NULL )
+{
+ //! hold pSource
+
+#if 0
+ // date columns have 3 hierarchies (flat/quarter/week), other columns only one
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( pSource->IsDateDimension( nSrcDim ) )
+ nHierCount = SC_DAPI_DATE_HIERARCHIES;
+ else
+ nHierCount = 1;
+#endif
+
+ // #i52547# don't offer the incomplete date hierarchy implementation
+ nHierCount = 1;
+}
+
+ScDPHierarchies::~ScDPHierarchies()
+{
+ //! release pSource
+
+ if (ppHiers)
+ {
+ for (long i=0; i<nHierCount; i++)
+ if ( ppHiers[i] )
+ ppHiers[i]->release(); // ref-counted
+ delete[] ppHiers;
+ }
+}
+
+// very simple XNameAccess implementation using getCount/getByIndex
+
+uno::Any SAL_CALL ScDPHierarchies::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ long nCount = getCount();
+ for (long i=0; i<nCount; i++)
+ if ( getByIndex(i)->getName() == aName )
+ {
+ uno::Reference<container::XNamed> xNamed = getByIndex(i);
+ uno::Any aRet;
+ aRet <<= xNamed;
+ return aRet;
+ }
+
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDPHierarchies::getElementNames() throw(uno::RuntimeException)
+{
+ long nCount = getCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pArr = aSeq.getArray();
+ for (long i=0; i<nCount; i++)
+ pArr[i] = getByIndex(i)->getName();
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScDPHierarchies::hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ long nCount = getCount();
+ for (long i=0; i<nCount; i++)
+ if ( getByIndex(i)->getName() == aName )
+ return TRUE;
+ return FALSE;
+}
+
+uno::Type SAL_CALL ScDPHierarchies::getElementType() throw(uno::RuntimeException)
+{
+ return getCppuType((uno::Reference<container::XNamed>*)0);
+}
+
+sal_Bool SAL_CALL ScDPHierarchies::hasElements() throw(uno::RuntimeException)
+{
+ return ( getCount() > 0 );
+}
+
+// end of XNameAccess implementation
+
+long ScDPHierarchies::getCount() const
+{
+ return nHierCount;
+}
+
+ScDPHierarchy* ScDPHierarchies::getByIndex(long nIndex) const
+{
+ // pass hierarchy index to new object in case the implementation
+ // will be extended to more than one hierarchy
+
+ if ( nIndex >= 0 && nIndex < nHierCount )
+ {
+ if ( !ppHiers )
+ {
+ ((ScDPHierarchies*)this)->ppHiers = new ScDPHierarchy*[nHierCount];
+ for (long i=0; i<nHierCount; i++)
+ ppHiers[i] = NULL;
+ }
+ if ( !ppHiers[nIndex] )
+ {
+ ppHiers[nIndex] = new ScDPHierarchy( pSource, nDim, nIndex );
+ ppHiers[nIndex]->acquire(); // ref-counted
+ }
+
+ return ppHiers[nIndex];
+ }
+
+ return NULL; //! exception?
+}
+
+// -----------------------------------------------------------------------
+
+ScDPHierarchy::ScDPHierarchy( ScDPSource* pSrc, long nD, long nH ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ nHier( nH ),
+ pLevels( NULL )
+{
+ //! hold pSource
+}
+
+ScDPHierarchy::~ScDPHierarchy()
+{
+ //! release pSource
+
+ if (pLevels)
+ pLevels->release(); // ref-counted
+}
+
+ScDPLevels* ScDPHierarchy::GetLevelsObject()
+{
+ if (!pLevels)
+ {
+ pLevels = new ScDPLevels( pSource, nDim, nHier );
+ pLevels->acquire(); // ref-counted
+ }
+ return pLevels;
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScDPHierarchy::getLevels()
+ throw(uno::RuntimeException)
+{
+ return GetLevelsObject();
+}
+
+::rtl::OUString SAL_CALL ScDPHierarchy::getName() throw(uno::RuntimeException)
+{
+ String aRet; //! globstr-ID !!!!
+ switch (nHier)
+ {
+ case SC_DAPI_HIERARCHY_FLAT:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("flat"));
+ break; //! name ???????
+ case SC_DAPI_HIERARCHY_QUARTER:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Quarter"));
+ break; //! name ???????
+ case SC_DAPI_HIERARCHY_WEEK:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Week"));
+ break; //! name ???????
+ default:
+ DBG_ERROR( "ScDPHierarchy::getName: unexpected hierarchy" );
+ break;
+ }
+ return aRet;
+}
+
+void SAL_CALL ScDPHierarchy::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented"); //! exception?
+}
+
+// -----------------------------------------------------------------------
+
+ScDPLevels::ScDPLevels( ScDPSource* pSrc, long nD, long nH ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ nHier( nH ),
+ ppLevs( NULL )
+{
+ //! hold pSource
+
+ // text columns have only one level
+
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( pSource->IsDateDimension( nSrcDim ) )
+ {
+ switch ( nHier )
+ {
+ case SC_DAPI_HIERARCHY_FLAT: nLevCount = SC_DAPI_FLAT_LEVELS; break;
+ case SC_DAPI_HIERARCHY_QUARTER: nLevCount = SC_DAPI_QUARTER_LEVELS; break;
+ case SC_DAPI_HIERARCHY_WEEK: nLevCount = SC_DAPI_WEEK_LEVELS; break;
+ default:
+ DBG_ERROR("wrong hierarchy");
+ nLevCount = 0;
+ }
+ }
+ else
+ nLevCount = 1;
+}
+
+ScDPLevels::~ScDPLevels()
+{
+ //! release pSource
+
+ if (ppLevs)
+ {
+ for (long i=0; i<nLevCount; i++)
+ if ( ppLevs[i] )
+ ppLevs[i]->release(); // ref-counted
+ delete[] ppLevs;
+ }
+}
+
+// very simple XNameAccess implementation using getCount/getByIndex
+
+uno::Any SAL_CALL ScDPLevels::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ long nCount = getCount();
+ for (long i=0; i<nCount; i++)
+ if ( getByIndex(i)->getName() == aName )
+ {
+ uno::Reference<container::XNamed> xNamed = getByIndex(i);
+ uno::Any aRet;
+ aRet <<= xNamed;
+ return aRet;
+ }
+
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDPLevels::getElementNames() throw(uno::RuntimeException)
+{
+ long nCount = getCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pArr = aSeq.getArray();
+ for (long i=0; i<nCount; i++)
+ pArr[i] = getByIndex(i)->getName();
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScDPLevels::hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ long nCount = getCount();
+ for (long i=0; i<nCount; i++)
+ if ( getByIndex(i)->getName() == aName )
+ return TRUE;
+ return FALSE;
+}
+
+uno::Type SAL_CALL ScDPLevels::getElementType() throw(uno::RuntimeException)
+{
+ return getCppuType((uno::Reference<container::XNamed>*)0);
+}
+
+sal_Bool SAL_CALL ScDPLevels::hasElements() throw(uno::RuntimeException)
+{
+ return ( getCount() > 0 );
+}
+
+// end of XNameAccess implementation
+
+long ScDPLevels::getCount() const
+{
+ return nLevCount;
+}
+
+ScDPLevel* ScDPLevels::getByIndex(long nIndex) const
+{
+ if ( nIndex >= 0 && nIndex < nLevCount )
+ {
+ if ( !ppLevs )
+ {
+ ((ScDPLevels*)this)->ppLevs = new ScDPLevel*[nLevCount];
+ for (long i=0; i<nLevCount; i++)
+ ppLevs[i] = NULL;
+ }
+ if ( !ppLevs[nIndex] )
+ {
+ ppLevs[nIndex] = new ScDPLevel( pSource, nDim, nHier, nIndex );
+ ppLevs[nIndex]->acquire(); // ref-counted
+ }
+
+ return ppLevs[nIndex];
+ }
+
+ return NULL; //! exception?
+}
+
+// -----------------------------------------------------------------------
+
+class ScDPGlobalMembersOrder
+{
+ ScDPLevel& rLevel;
+ BOOL bAscending;
+
+public:
+ ScDPGlobalMembersOrder( ScDPLevel& rLev, BOOL bAsc ) :
+ rLevel(rLev),
+ bAscending(bAsc)
+ {}
+ ~ScDPGlobalMembersOrder() {}
+
+ BOOL operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const;
+};
+
+BOOL ScDPGlobalMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const
+{
+ sal_Int32 nCompare = 0;
+ // seems that some ::std::sort() implementations pass the same index twice
+ if( nIndex1 != nIndex2 )
+ {
+ ScDPMembers* pMembers = rLevel.GetMembersObject();
+ ScDPMember* pMember1 = pMembers->getByIndex(nIndex1);
+ ScDPMember* pMember2 = pMembers->getByIndex(nIndex2);
+ nCompare = pMember1->Compare( *pMember2 );
+ }
+ return bAscending ? (nCompare < 0) : (nCompare > 0);
+}
+
+// -----------------------------------------------------------------------
+
+ScDPLevel::ScDPLevel( ScDPSource* pSrc, long nD, long nH, long nL ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ nHier( nH ),
+ nLev( nL ),
+ pMembers( NULL ),
+ bShowEmpty( FALSE ),
+ aSortInfo( EMPTY_STRING, sal_True, sheet::DataPilotFieldSortMode::NAME ), // default: sort by name
+ nSortMeasure( 0 ),
+ nAutoMeasure( 0 ),
+ bEnableLayout( FALSE )
+{
+ //! hold pSource
+ // aSubTotals is empty
+}
+
+ScDPLevel::~ScDPLevel()
+{
+ //! release pSource
+
+ if ( pMembers )
+ pMembers->release(); // ref-counted
+}
+
+void ScDPLevel::EvaluateSortOrder()
+{
+ switch (aSortInfo.Mode)
+ {
+ case sheet::DataPilotFieldSortMode::DATA:
+ {
+ // find index of measure (index among data dimensions)
+
+ String aDataFieldName = aSortInfo.Field;
+ long nMeasureCount = pSource->GetDataDimensionCount();
+ for (long nMeasure=0; nMeasure<nMeasureCount; nMeasure++)
+ {
+ if ( pSource->GetDataDimName(nMeasure) == aDataFieldName )
+ {
+ nSortMeasure = nMeasure;
+ break;
+ }
+ }
+
+ //! error if not found?
+ }
+ break;
+ case sheet::DataPilotFieldSortMode::MANUAL:
+ case sheet::DataPilotFieldSortMode::NAME:
+ {
+ ScDPMembers* pLocalMembers = GetMembersObject();
+ long nCount = pLocalMembers->getCount();
+
+// DBG_ASSERT( aGlobalOrder.empty(), "sort twice?" );
+ aGlobalOrder.resize( nCount );
+ for (long nPos=0; nPos<nCount; nPos++)
+ aGlobalOrder[nPos] = nPos;
+
+ // allow manual or name (manual is always ascending)
+ BOOL bAscending = ( aSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL || aSortInfo.IsAscending );
+ ScDPGlobalMembersOrder aComp( *this, bAscending );
+ ::std::sort( aGlobalOrder.begin(), aGlobalOrder.end(), aComp );
+ }
+ break;
+ }
+
+ if ( aAutoShowInfo.IsEnabled )
+ {
+ // find index of measure (index among data dimensions)
+
+ String aDataFieldName = aAutoShowInfo.DataField;
+ long nMeasureCount = pSource->GetDataDimensionCount();
+ for (long nMeasure=0; nMeasure<nMeasureCount; nMeasure++)
+ {
+ if ( pSource->GetDataDimName(nMeasure) == aDataFieldName )
+ {
+ nAutoMeasure = nMeasure;
+ break;
+ }
+ }
+
+ //! error if not found?
+ }
+}
+
+void ScDPLevel::SetEnableLayout( BOOL bSet )
+{
+ bEnableLayout = bSet;
+}
+
+ScDPMembers* ScDPLevel::GetMembersObject()
+{
+ if (!pMembers)
+ {
+ pMembers = new ScDPMembers( pSource, nDim, nHier, nLev );
+ pMembers->acquire(); // ref-counted
+ }
+ return pMembers;
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScDPLevel::getMembers() throw(uno::RuntimeException)
+{
+ return GetMembersObject();
+}
+
+uno::Sequence<sheet::MemberResult> SAL_CALL ScDPLevel::getResults() throw(uno::RuntimeException)
+{
+ const uno::Sequence<sheet::MemberResult>* pRes = pSource->GetMemberResults( this );
+ if (pRes)
+ return *pRes;
+
+ return uno::Sequence<sheet::MemberResult>(0); //! Error?
+}
+
+::rtl::OUString SAL_CALL ScDPLevel::getName() throw(uno::RuntimeException)
+{
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( pSource->IsDateDimension( nSrcDim ) )
+ {
+ String aRet; //! globstr-ID !!!!
+
+ if ( nHier == SC_DAPI_HIERARCHY_QUARTER )
+ {
+ switch ( nLev )
+ {
+ case SC_DAPI_LEVEL_YEAR:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Year"));
+ break;
+ case SC_DAPI_LEVEL_QUARTER:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Quarter"));
+ break;
+ case SC_DAPI_LEVEL_MONTH:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Month"));
+ break;
+ case SC_DAPI_LEVEL_DAY:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Day"));
+ break;
+ default:
+ DBG_ERROR( "ScDPLevel::getName: unexpected level" );
+ break;
+ }
+ }
+ else if ( nHier == SC_DAPI_HIERARCHY_WEEK )
+ {
+ switch ( nLev )
+ {
+ case SC_DAPI_LEVEL_YEAR:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Year"));
+ break;
+ case SC_DAPI_LEVEL_WEEK:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Week"));
+ break;
+ case SC_DAPI_LEVEL_WEEKDAY:
+ aRet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Weekday"));
+ break;
+ default:
+ DBG_ERROR( "ScDPLevel::getName: unexpected level" );
+ break;
+ }
+ }
+ if (aRet.Len())
+ return aRet;
+ }
+
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return rtl::OUString();
+
+ return pDim->getName();
+}
+
+void SAL_CALL ScDPLevel::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented"); //! exception?
+}
+
+uno::Sequence<sheet::GeneralFunction> ScDPLevel::getSubTotals() const
+{
+ //! separate functions for settings and evaluation?
+
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( !pSource->SubTotalAllowed( nSrcDim ) )
+ return uno::Sequence<sheet::GeneralFunction>(0);
+
+ return aSubTotals;
+}
+
+void ScDPLevel::setSubTotals(const uno::Sequence<sheet::GeneralFunction>& rNew)
+{
+ aSubTotals = rNew;
+ //! set "manual change" flag?
+}
+
+BOOL ScDPLevel::getShowEmpty() const
+{
+ return bShowEmpty;
+}
+
+void ScDPLevel::setShowEmpty(BOOL bSet)
+{
+ bShowEmpty = bSet;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPLevel::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ static SfxItemPropertyMapEntry aDPLevelMap_Impl[] =
+ {
+ //! change type of AutoShow/Layout/Sorting to API struct when available
+ {MAP_CHAR_LEN(SC_UNO_AUTOSHOW), 0, &getCppuType((sheet::DataPilotFieldAutoShowInfo*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUT), 0, &getCppuType((sheet::DataPilotFieldLayoutInfo*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SHOWEMPT), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SORTING), 0, &getCppuType((sheet::DataPilotFieldSortInfo*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SUBTOTAL), 0, &getCppuType((uno::Sequence<sheet::GeneralFunction>*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( aDPLevelMap_Impl );
+ return aRef;
+}
+
+void SAL_CALL ScDPLevel::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_SHOWEMPT ) )
+ setShowEmpty( lcl_GetBoolFromAny( aValue ) );
+ else if ( aNameStr.EqualsAscii( SC_UNO_SUBTOTAL ) )
+ {
+ uno::Sequence<sheet::GeneralFunction> aSeq;
+ if ( aValue >>= aSeq )
+ setSubTotals( aSeq );
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_SORTING ) )
+ aValue >>= aSortInfo;
+ else if ( aNameStr.EqualsAscii( SC_UNO_AUTOSHOW ) )
+ aValue >>= aAutoShowInfo;
+ else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) )
+ aValue >>= aLayoutInfo;
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+}
+
+uno::Any SAL_CALL ScDPLevel::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ uno::Any aRet;
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_SHOWEMPT ) )
+ lcl_SetBoolInAny( aRet, getShowEmpty() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_SUBTOTAL ) )
+ {
+ uno::Sequence<sheet::GeneralFunction> aSeq = getSubTotals(); //! avoid extra copy?
+ aRet <<= aSeq;
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNO_SORTING ) )
+ aRet <<= aSortInfo;
+ else if ( aNameStr.EqualsAscii( SC_UNO_AUTOSHOW ) )
+ aRet <<= aAutoShowInfo;
+ else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) )
+ aRet <<= aLayoutInfo;
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ // read only property
+ long nSrcDim = pSource->GetSourceDim(nDim);
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return aRet;
+
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (!pLayoutName)
+ return aRet;
+
+ aRet <<= *pLayoutName;
+ }
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPLevel )
+
+// -----------------------------------------------------------------------
+
+ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ nHier( nH ),
+ nLev( nL ),
+ ppMbrs( NULL )
+{
+ //! hold pSource
+
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( pSource->IsDataLayoutDimension(nSrcDim) )
+ nMbrCount = pSource->GetDataDimensionCount();
+ else if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
+ {
+ nMbrCount = 0;
+ if ( nHier == SC_DAPI_HIERARCHY_QUARTER )
+ {
+ switch (nLev)
+ {
+ case SC_DAPI_LEVEL_YEAR:
+ {
+ // Wang Xu Ming - DataPilot migration
+ const ScDPItemData* pLastNumData = NULL;
+ for ( SCROW n = 0 ;n <GetSrcItemsCount() ; n-- )
+ {
+ const ScDPItemData* pData = GetSrcItemDataByIndex( n );
+ if ( pData && pData->HasStringData() )
+ break;
+ else
+ pLastNumData = pData;
+ }
+ // End Comments
+
+ if ( pLastNumData )
+ {
+ const ScDPItemData* pFirstData = GetSrcItemDataByIndex( 0 );
+ double fFirstVal = pFirstData->GetValue();
+ double fLastVal = pLastNumData->GetValue();
+
+ long nFirstYear = pSource->GetData()->GetDatePart(
+ (long)::rtl::math::approxFloor( fFirstVal ),
+ nHier, nLev );
+ long nLastYear = pSource->GetData()->GetDatePart(
+ (long)::rtl::math::approxFloor( fLastVal ),
+ nHier, nLev );
+
+ nMbrCount = nLastYear + 1 - nFirstYear;
+ }
+ else
+ nMbrCount = 0; // no values
+ }
+ break;
+ case SC_DAPI_LEVEL_QUARTER: nMbrCount = 4; break;
+ case SC_DAPI_LEVEL_MONTH: nMbrCount = 12; break;
+ case SC_DAPI_LEVEL_DAY: nMbrCount = 31; break;
+ default:
+ DBG_ERROR( "ScDPMembers::ScDPMembers: unexpected level" );
+ break;
+ }
+ }
+ else if ( nHier == SC_DAPI_HIERARCHY_WEEK )
+ {
+ switch (nLev)
+ {
+ case SC_DAPI_LEVEL_YEAR: nMbrCount = 1; break; //! get years from source
+ case SC_DAPI_LEVEL_WEEK: nMbrCount = 53; break;
+ case SC_DAPI_LEVEL_WEEKDAY: nMbrCount = 7; break;
+ default:
+ DBG_ERROR( "ScDPMembers::ScDPMembers: unexpected level" );
+ break;
+ }
+ }
+ }
+ else
+ nMbrCount = pSource->GetData()->GetMembersCount( nSrcDim );
+}
+
+ScDPMembers::~ScDPMembers()
+{
+ //! release pSource
+
+ if (ppMbrs)
+ {
+ for (long i=0; i<nMbrCount; i++)
+ if ( ppMbrs[i] )
+ ppMbrs[i]->release(); // ref-counted
+ delete[] ppMbrs;
+ }
+}
+
+// XNameAccess implementation using getCount/getByIndex
+
+sal_Int32 ScDPMembers::GetIndexFromName( const ::rtl::OUString& rName ) const
+{
+ if ( aHashMap.empty() )
+ {
+ // store the index for each name
+
+ sal_Int32 nCount = getCount();
+ for (sal_Int32 i=0; i<nCount; i++)
+ aHashMap[ getByIndex(i)->getName() ] = i;
+ }
+
+ ScDPMembersHashMap::const_iterator aIter = aHashMap.find( rName );
+ if ( aIter != aHashMap.end() )
+ return aIter->second; // found index
+ else
+ return -1; // not found
+}
+
+uno::Any SAL_CALL ScDPMembers::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ sal_Int32 nIndex = GetIndexFromName( aName );
+ if ( nIndex >= 0 )
+ {
+ uno::Reference<container::XNamed> xNamed = getByIndex(nIndex);
+ uno::Any aRet;
+ aRet <<= xNamed;
+ return aRet;
+ }
+
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDPMembers::getElementNames() throw(uno::RuntimeException)
+{
+ // Return list of names in sorted order,
+ // so it's displayed in that order in the field options dialog.
+ // Sorting is done at the level object (parent of this).
+
+ ScDPLevel* pLevel = pSource->GetDimensionsObject()->getByIndex(nDim)->
+ GetHierarchiesObject()->getByIndex(nHier)->GetLevelsObject()->getByIndex(nLev);
+ pLevel->EvaluateSortOrder();
+ const std::vector<sal_Int32>& rGlobalOrder = pLevel->GetGlobalOrder();
+ bool bSort = !rGlobalOrder.empty();
+
+ long nCount = getCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pArr = aSeq.getArray();
+ for (long i=0; i<nCount; i++)
+ pArr[i] = getByIndex(bSort ? rGlobalOrder[i] : i)->getName();
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScDPMembers::hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ return ( GetIndexFromName( aName ) >= 0 );
+}
+
+uno::Type SAL_CALL ScDPMembers::getElementType() throw(uno::RuntimeException)
+{
+ return getCppuType((uno::Reference<container::XNamed>*)0);
+}
+
+sal_Bool SAL_CALL ScDPMembers::hasElements() throw(uno::RuntimeException)
+{
+ return ( getCount() > 0 );
+}
+
+// end of XNameAccess implementation
+
+long ScDPMembers::getCount() const
+{
+ return nMbrCount;
+}
+
+long ScDPMembers::getMinMembers() const
+{
+ // used in lcl_CountMinMembers
+
+ long nVisCount = 0;
+ if ( ppMbrs )
+ {
+ for (long i=0; i<nMbrCount; i++)
+ {
+ // count only visible with details (default is true for both)
+ const ScDPMember* pMbr = ppMbrs[i];
+ if ( !pMbr || ( pMbr->getIsVisible() && pMbr->getShowDetails() ) )
+ ++nVisCount;
+ }
+ }
+ else
+ nVisCount = nMbrCount; // default for all
+
+ return nVisCount;
+}
+
+ScDPMember* ScDPMembers::getByIndex(long nIndex) const
+{
+ // result of GetColumnEntries must not change between ScDPMembers ctor
+ // and all calls to getByIndex
+
+ if ( nIndex >= 0 && nIndex < nMbrCount )
+ {
+ if ( !ppMbrs )
+ {
+ ((ScDPMembers*)this)->ppMbrs = new ScDPMember*[nMbrCount];
+ for (long i=0; i<nMbrCount; i++)
+ ppMbrs[i] = NULL;
+ }
+ if ( !ppMbrs[nIndex] )
+ {
+ ScDPMember* pNew;
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( pSource->IsDataLayoutDimension(nSrcDim) )
+ {
+ // empty name (never shown, not used for lookup)
+ pNew = new ScDPMember( pSource, nDim, nHier, nLev, 0 );
+ }
+ else if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
+ {
+ long nVal = 0;
+ String aName;
+
+ if ( nLev == SC_DAPI_LEVEL_YEAR ) // YEAR is in both hierarchies
+ {
+ //! cache year range here!
+
+ // Wang Xu Ming - DataPilot migration
+ double fFirstVal = pSource->GetData()->GetMemberByIndex( nSrcDim, 0 )->GetValue();
+ long nFirstYear = pSource->GetData()->GetDatePart(
+ (long)::rtl::math::approxFloor( fFirstVal ),
+ nHier, nLev );
+
+ // End Comments
+ nVal = nFirstYear + nIndex;
+ }
+ else if ( nHier == SC_DAPI_HIERARCHY_WEEK && nLev == SC_DAPI_LEVEL_WEEKDAY )
+ {
+ nVal = nIndex; // DayOfWeek is 0-based
+ aName = ScGlobal::GetCalendar()->getDisplayName(
+ ::com::sun::star::i18n::CalendarDisplayIndex::DAY,
+ sal::static_int_cast<sal_Int16>(nVal), 0 );
+ }
+ else if ( nHier == SC_DAPI_HIERARCHY_QUARTER && nLev == SC_DAPI_LEVEL_MONTH )
+ {
+ nVal = nIndex; // Month is 0-based
+ aName = ScGlobal::GetCalendar()->getDisplayName(
+ ::com::sun::star::i18n::CalendarDisplayIndex::MONTH,
+ sal::static_int_cast<sal_Int16>(nVal), 0 );
+ }
+ else
+ nVal = nIndex + 1; // Quarter, Day, Week are 1-based
+
+ if ( !aName.Len() )
+ aName = String::CreateFromInt32(nVal);
+
+ ScDPItemData rData( aName, nVal, TRUE, 0 ) ;
+ pNew = new ScDPMember( pSource, nDim, nHier, nLev, pSource->GetCache()->GetAdditionalItemID(rData));
+ }
+ else
+ {
+ const std::vector< SCROW >& memberIndexs = pSource->GetData()->GetColumnEntries( nSrcDim );
+ pNew = new ScDPMember( pSource, nDim, nHier, nLev, memberIndexs[nIndex] );
+ }
+ pNew->acquire(); // ref-counted
+ ppMbrs[nIndex] = pNew;
+ }
+
+ DBG_ASSERT( ppMbrs[nIndex] ," member is not initialized " );
+
+ return ppMbrs[nIndex];
+ }
+
+ return NULL; //! exception?
+}
+
+// -----------------------------------------------------------------------
+
+ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL,
+ SCROW nIndex /*const String& rN, double fV, BOOL bHV*/ ) :
+ pSource( pSrc ),
+ nDim( nD ),
+ nHier( nH ),
+ nLev( nL ),
+ mnDataId( nIndex ),
+ mpLayoutName(NULL),
+ nPosition( -1 ),
+ bVisible( TRUE ),
+ bShowDet( TRUE )
+{
+ //! hold pSource
+}
+
+ScDPMember::~ScDPMember()
+{
+ //! release pSource
+}
+
+BOOL ScDPMember::IsNamedItem( const ScDPItemData& r ) const
+{
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) && r.IsValue() )
+ {
+ long nComp = pSource->GetData()->GetDatePart(
+ (long)::rtl::math::approxFloor( r.GetValue() ),
+ nHier, nLev );
+
+ // fValue is converted from integer, so simple comparison works
+ return nComp == GetItemData().GetValue();
+ }
+
+ return r.IsCaseInsEqual( GetItemData() );
+}
+
+BOOL ScDPMember::IsNamedItem( SCROW nIndex ) const
+{
+ long nSrcDim = pSource->GetSourceDim( nDim );
+ if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
+ {
+ const ScDPItemData* pData = pSource->GetCache()->GetItemDataById( (SCCOL) nSrcDim, nIndex );
+ if ( pData->IsValue() )
+ {
+ long nComp = pSource->GetData()->GetDatePart(
+ (long)::rtl::math::approxFloor( pData->GetValue() ),
+ nHier, nLev );
+ // fValue is converted from integer, so simple comparison works
+ return nComp == GetItemData().GetValue();
+ }
+ }
+
+ return nIndex == mnDataId;
+}
+
+sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const
+{
+ if ( nPosition >= 0 )
+ {
+ if ( rOther.nPosition >= 0 )
+ {
+ DBG_ASSERT( nPosition != rOther.nPosition, "same position for two members" );
+ return ( nPosition < rOther.nPosition ) ? -1 : 1;
+ }
+ else
+ {
+ // only this has a position - members with specified positions come before those without
+ return -1;
+ }
+ }
+ else if ( rOther.nPosition >= 0 )
+ {
+ // only rOther has a position
+ return 1;
+ }
+
+ // no positions set - compare names
+ return pSource->GetData()->Compare( pSource->GetSourceDim(nDim),mnDataId,rOther.GetItemDataId());
+}
+
+void ScDPMember::FillItemData( ScDPItemData& rData ) const
+{
+ //! handle date hierarchy...
+
+ rData = GetItemData() ;
+}
+
+const OUString* ScDPMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+String ScDPMember::GetNameStr() const
+{
+ return GetItemData().GetString();
+}
+
+::rtl::OUString SAL_CALL ScDPMember::getName() throw(uno::RuntimeException)
+{
+ return GetItemData().GetString();
+}
+
+void SAL_CALL ScDPMember::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented"); //! exception?
+}
+
+BOOL ScDPMember::getIsVisible() const
+{
+ return bVisible;
+}
+
+void ScDPMember::setIsVisible(BOOL bSet)
+{
+ bVisible = bSet;
+ //! set "manual change" flag
+}
+
+BOOL ScDPMember::getShowDetails() const
+{
+ return bShowDet;
+}
+
+void ScDPMember::setShowDetails(BOOL bSet)
+{
+ bShowDet = bSet;
+ //! set "manual change" flag
+}
+
+sal_Int32 ScDPMember::getPosition() const
+{
+ return nPosition;
+}
+
+void ScDPMember::setPosition(sal_Int32 nNew)
+{
+ nPosition = nNew;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPMember::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ static SfxItemPropertyMapEntry aDPMemberMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_ISVISIBL), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SHOWDETA), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( aDPMemberMap_Impl );
+ return aRef;
+}
+
+void SAL_CALL ScDPMember::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_ISVISIBL ) )
+ setIsVisible( lcl_GetBoolFromAny( aValue ) );
+ else if ( aNameStr.EqualsAscii( SC_UNO_SHOWDETA ) )
+ setShowDetails( lcl_GetBoolFromAny( aValue ) );
+ else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
+ {
+ sal_Int32 nInt = 0;
+ if (aValue >>= nInt)
+ setPosition( nInt );
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ rtl::OUString aName;
+ if (aValue >>= aName)
+ mpLayoutName.reset(new rtl::OUString(aName));
+ }
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+}
+
+uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ uno::Any aRet;
+ String aNameStr = aPropertyName;
+ if ( aNameStr.EqualsAscii( SC_UNO_ISVISIBL ) )
+ lcl_SetBoolInAny( aRet, getIsVisible() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_SHOWDETA ) )
+ lcl_SetBoolInAny( aRet, getShowDetails() );
+ else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
+ aRet <<= (sal_Int32) getPosition();
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : rtl::OUString();
+ else
+ {
+ DBG_ERROR("unknown property");
+ //! THROW( UnknownPropertyException() );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPMember )
+
+
+ScDPTableDataCache* ScDPSource::GetCache()
+{
+ DBG_ASSERT( GetData() , "empty ScDPTableData pointer");
+ return ( GetData()!=NULL) ? GetData()->GetCacheTable().GetCache() : NULL ;
+}
+
+const ScDPItemData& ScDPMember::GetItemData() const
+{
+ return *pSource->GetItemDataById( (SCCOL)nDim, mnDataId );//ms-cache-core
+}
+
+const ScDPItemData* ScDPSource::GetItemDataById(long nDim, long nId)
+{
+ long nSrcDim = GetSourceDim( nDim );
+ const ScDPItemData* pItemData = GetData()->GetMemberById( nSrcDim, nId );
+ if ( !pItemData )
+ { //todo:
+ ScDPItemData item;
+ nId = GetCache()->GetAdditionalItemID( item );
+ pItemData = GetData()->GetMemberById( nSrcDim, nId );
+ }
+ return pItemData;
+}
+
+SCROW ScDPSource::GetMemberId( long nDim, const ScDPItemData& rData )
+{
+ long nSrcDim = GetSourceDim( nDim );
+ return GetCache()->GetIdByItemData( nSrcDim, rData );
+}
+
+const ScDPItemData* ScDPMembers::GetSrcItemDataByIndex( SCROW nIndex)
+{
+ const std::vector< SCROW >& memberIds = pSource->GetData()->GetColumnEntries( nDim );
+ if ( nIndex >= (long )(memberIds.size()) || nIndex < 0 )
+ return NULL;
+ SCROW nId = memberIds[ nIndex ];
+ return pSource->GetItemDataById( nDim, nId );
+}
+
+ SCROW ScDPMembers::GetSrcItemsCount()
+ {
+ return pSource->GetData()->GetColumnEntries( nDim ).size();
+ }
+// End Comments
+
diff --git a/sc/source/core/data/drawpage.cxx b/sc/source/core/data/drawpage.cxx
new file mode 100644
index 000000000000..715b99f362a1
--- /dev/null
+++ b/sc/source/core/data/drawpage.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/objsh.hxx>
+
+#include "drawpage.hxx"
+#include "drwlayer.hxx"
+#include "document.hxx"
+#include "pageuno.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+ScDrawPage::ScDrawPage(ScDrawLayer& rNewModel, StarBASIC* pBasic, BOOL bMasterPage) :
+ FmFormPage(rNewModel, pBasic, bMasterPage)
+{
+ SetSize( Size( LONG_MAX, LONG_MAX ) );
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScDrawPage::~ScDrawPage()
+{
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > ScDrawPage::createUnoPage()
+{
+ return static_cast<cppu::OWeakObject*>( new ScPageObj( this ) );
+}
+
+
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
new file mode 100644
index 000000000000..b4e1cc71dc3d
--- /dev/null
+++ b/sc/source/core/data/drwlayer.cxx
@@ -0,0 +1,2109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/embed/XClassifiedObject.hpp>
+#include <com/sun/star/embed/XComponentSupplier.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <sot/exchange.hxx>
+#include <svx/objfac3d.hxx>
+#include <svx/xtable.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdundo.hxx>
+#include <editeng/unolingu.hxx>
+#include <svx/drawitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <svx/shapepropertynotifier.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <sot/storage.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/itempool.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include "drwlayer.hxx"
+#include "drawpage.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "rechead.hxx"
+#include "userdat.hxx"
+#include "markdata.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "chartarr.hxx"
+#include "postit.hxx"
+#include "attrib.hxx"
+#include "charthelper.hxx"
+
+#define DET_ARROW_OFFSET 1000
+
+// Abstand zur naechsten Zelle beim Loeschen (bShrink), damit der Anker
+// immer an der richtigen Zelle angezeigt wird
+//#define SHRINK_DIST 3
+// und noch etwas mehr, damit das Objekt auch sichtbar in der Zelle liegt
+#define SHRINK_DIST 25
+
+#define SHRINK_DIST_TWIPS 15
+
+using namespace ::com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScTabDeletedHint, SfxHint);
+TYPEINIT1(ScTabSizeChangedHint, SfxHint);
+
+static ScDrawObjFactory* pFac = NULL;
+static E3dObjFactory* pF3d = NULL;
+static USHORT nInst = 0;
+
+SfxObjectShell* ScDrawLayer::pGlobalDrawPersist = NULL;
+//REMOVE SvPersist* ScDrawLayer::pGlobalDrawPersist = NULL;
+
+BOOL bDrawIsInUndo = FALSE; //! Member
+
+// -----------------------------------------------------------------------
+
+ScUndoObjData::ScUndoObjData( SdrObject* pObjP, const ScAddress& rOS, const ScAddress& rOE,
+ const ScAddress& rNS, const ScAddress& rNE ) :
+ SdrUndoObj( *pObjP ),
+ aOldStt( rOS ),
+ aOldEnd( rOE ),
+ aNewStt( rNS ),
+ aNewEnd( rNE )
+{
+}
+
+__EXPORT ScUndoObjData::~ScUndoObjData()
+{
+}
+
+void ScUndoObjData::Undo()
+{
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
+ DBG_ASSERT(pData,"ScUndoObjData: Daten nicht da");
+ if (pData)
+ {
+ pData->maStart = aOldStt;
+ pData->maEnd = aOldEnd;
+ }
+}
+
+void __EXPORT ScUndoObjData::Redo()
+{
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
+ DBG_ASSERT(pData,"ScUndoObjData: Daten nicht da");
+ if (pData)
+ {
+ pData->maStart = aNewStt;
+ pData->maEnd = aNewEnd;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScTabDeletedHint::ScTabDeletedHint( SCTAB nTabNo ) :
+ nTab( nTabNo )
+{
+}
+
+__EXPORT ScTabDeletedHint::~ScTabDeletedHint()
+{
+}
+
+ScTabSizeChangedHint::ScTabSizeChangedHint( SCTAB nTabNo ) :
+ nTab( nTabNo )
+{
+}
+
+__EXPORT ScTabSizeChangedHint::~ScTabSizeChangedHint()
+{
+}
+
+// -----------------------------------------------------------------------
+
+#define MAXMM 10000000
+
+inline void TwipsToMM( long& nVal )
+{
+ nVal = (long) ( nVal * HMM_PER_TWIPS );
+}
+
+inline void ReverseTwipsToMM( long& nVal )
+{
+ // reverse the effect of TwipsToMM - round up here (add 1)
+
+ nVal = ((long) ( nVal / HMM_PER_TWIPS )) + 1;
+}
+
+void lcl_TwipsToMM( Point& rPoint )
+{
+ TwipsToMM( rPoint.X() );
+ TwipsToMM( rPoint.Y() );
+}
+
+void lcl_ReverseTwipsToMM( Point& rPoint )
+{
+ ReverseTwipsToMM( rPoint.X() );
+ ReverseTwipsToMM( rPoint.Y() );
+}
+
+void lcl_ReverseTwipsToMM( Rectangle& rRect )
+{
+ ReverseTwipsToMM( rRect.Left() );
+ ReverseTwipsToMM( rRect.Right() );
+ ReverseTwipsToMM( rRect.Top() );
+ ReverseTwipsToMM( rRect.Bottom() );
+}
+
+// -----------------------------------------------------------------------
+
+
+ScDrawLayer::ScDrawLayer( ScDocument* pDocument, const String& rName ) :
+ FmFormModel( SvtPathOptions().GetPalettePath(),
+ NULL, // SfxItemPool* Pool
+ pGlobalDrawPersist ?
+ pGlobalDrawPersist :
+ ( pDocument ? pDocument->GetDocumentShell() : NULL ),
+ TRUE ), // bUseExtColorTable (is set below)
+ aName( rName ),
+ pDoc( pDocument ),
+ pUndoGroup( NULL ),
+ bRecording( FALSE ),
+ bAdjustEnabled( TRUE ),
+ bHyphenatorSet( FALSE )
+{
+ pGlobalDrawPersist = NULL; // nur einmal benutzen
+
+ SfxObjectShell* pObjSh = pDocument ? pDocument->GetDocumentShell() : NULL;
+ if ( pObjSh )
+ {
+ SetObjectShell( pObjSh );
+
+ // set color table
+ SvxColorTableItem* pColItem = (SvxColorTableItem*) pObjSh->GetItem( SID_COLOR_TABLE );
+ XColorTable* pXCol = pColItem ? pColItem->GetColorTable() : XColorTable::GetStdColorTable();
+ SetColorTable( pXCol );
+ }
+ else
+ SetColorTable( XColorTable::GetStdColorTable() );
+
+ SetSwapGraphics(TRUE);
+// SetSwapAsynchron(TRUE); // an der View
+
+ SetScaleUnit(MAP_100TH_MM);
+ SfxItemPool& rPool = GetItemPool();
+ rPool.SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
+ SvxFrameDirectionItem aModeItem( FRMDIR_ENVIRONMENT, EE_PARA_WRITINGDIR );
+ rPool.SetPoolDefaultItem( aModeItem );
+
+ // #i33700#
+ // Set shadow distance defaults as PoolDefaultItems. Details see bug.
+ rPool.SetPoolDefaultItem(SdrShadowXDistItem(300));
+ rPool.SetPoolDefaultItem(SdrShadowYDistItem(300));
+
+ // #111216# default for script spacing depends on locale, see SdDrawDocument ctor in sd
+ LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage();
+ if ( eOfficeLanguage == LANGUAGE_KOREAN || eOfficeLanguage == LANGUAGE_KOREAN_JOHAB ||
+ eOfficeLanguage == LANGUAGE_JAPANESE )
+ {
+ // secondary is edit engine pool
+ rPool.GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( FALSE, EE_PARA_ASIANCJKSPACING ) );
+ }
+
+ rPool.FreezeIdRanges(); // the pool is also used directly
+
+ SdrLayerAdmin& rAdmin = GetLayerAdmin();
+ rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("vorne")), SC_LAYER_FRONT);
+ rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("hinten")), SC_LAYER_BACK);
+ rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("intern")), SC_LAYER_INTERN);
+ rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Controls")), SC_LAYER_CONTROLS);
+ rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("hidden")), SC_LAYER_HIDDEN);
+ // "Controls" is new - must also be created when loading
+
+ // Link fuer URL-Fields setzen
+ ScModule* pScMod = SC_MOD();
+ Outliner& rOutliner = GetDrawOutliner();
+ rOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
+
+ Outliner& rHitOutliner = GetHitTestOutliner();
+ rHitOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
+
+ // #95129# SJ: set FontHeight pool defaults without changing static SdrEngineDefaults
+ SfxItemPool* pOutlinerPool = rOutliner.GetEditTextObjectPool();
+ if ( pOutlinerPool )
+ pItemPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT )); // 12Pt
+ SfxItemPool* pHitOutlinerPool = rHitOutliner.GetEditTextObjectPool();
+ if ( pHitOutlinerPool )
+ pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT )); // 12Pt
+
+ // URL-Buttons haben keinen Handler mehr, machen alles selber
+
+ if( !nInst++ )
+ {
+ pFac = new ScDrawObjFactory;
+ pF3d = new E3dObjFactory;
+ }
+}
+
+__EXPORT ScDrawLayer::~ScDrawLayer()
+{
+ Broadcast(SdrHint(HINT_MODELCLEARED));
+
+ // #116168#
+ //Clear();
+ ClearModel(sal_True);
+
+ delete pUndoGroup;
+ if( !--nInst )
+ {
+ delete pFac, pFac = NULL;
+ delete pF3d, pF3d = NULL;
+ }
+}
+
+void ScDrawLayer::UseHyphenator()
+{
+ if (!bHyphenatorSet)
+ {
+ com::sun::star::uno::Reference< com::sun::star::linguistic2::XHyphenator >
+ xHyphenator = LinguMgr::GetHyphenator();
+
+ GetDrawOutliner().SetHyphenator( xHyphenator );
+ GetHitTestOutliner().SetHyphenator( xHyphenator );
+
+ bHyphenatorSet = TRUE;
+ }
+}
+
+SdrPage* __EXPORT ScDrawLayer::AllocPage(FASTBOOL bMasterPage)
+{
+ // don't create basic until it is needed
+ StarBASIC* pBasic = NULL;
+ ScDrawPage* pPage = new ScDrawPage( *this, pBasic, sal::static_int_cast<BOOL>(bMasterPage) );
+ return pPage;
+}
+
+BOOL ScDrawLayer::HasObjects() const
+{
+ BOOL bFound = FALSE;
+
+ USHORT nCount = GetPageCount();
+ for (USHORT i=0; i<nCount && !bFound; i++)
+ if (GetPage(i)->GetObjCount())
+ bFound = TRUE;
+
+ return bFound;
+}
+
+void ScDrawLayer::UpdateBasic()
+{
+ // don't create basic until it is needed
+ //! remove this method?
+}
+
+SdrModel* __EXPORT ScDrawLayer::AllocModel() const
+{
+ // #103849# Allocated model (for clipboard etc) must not have a pointer
+ // to the original model's document, pass NULL as document:
+
+ return new ScDrawLayer( NULL, aName );
+}
+
+Window* __EXPORT ScDrawLayer::GetCurDocViewWin()
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::GetCurDocViewWin without document" );
+ if ( !pDoc )
+ return NULL;
+
+ SfxViewShell* pViewSh = SfxViewShell::Current();
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+
+ if (pViewSh && pViewSh->GetObjectShell() == pObjSh)
+ return pViewSh->GetWindow();
+
+ return NULL;
+}
+
+BOOL ScDrawLayer::ScAddPage( SCTAB nTab )
+{
+ if (bDrawIsInUndo)
+ return FALSE; // not inserted
+
+ ScDrawPage* pPage = (ScDrawPage*)AllocPage( FALSE );
+ InsertPage(pPage, static_cast<sal_uInt16>(nTab));
+ if (bRecording)
+ AddCalcUndo(new SdrUndoNewPage(*pPage));
+
+ return TRUE; // inserted
+}
+
+void ScDrawLayer::ScRemovePage( SCTAB nTab )
+{
+ if (bDrawIsInUndo)
+ return;
+
+ Broadcast( ScTabDeletedHint( nTab ) );
+ if (bRecording)
+ {
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ AddCalcUndo(new SdrUndoDelPage(*pPage)); // Undo-Action wird Owner der Page
+ RemovePage( static_cast<sal_uInt16>(nTab) ); // nur austragen, nicht loeschen
+ }
+ else
+ DeletePage( static_cast<sal_uInt16>(nTab) ); // einfach weg damit
+}
+
+void ScDrawLayer::ScRenamePage( SCTAB nTab, const String& rNewName )
+{
+ ScDrawPage* pPage = (ScDrawPage*) GetPage(static_cast<sal_uInt16>(nTab));
+ if (pPage)
+ pPage->SetName(rNewName);
+}
+
+void ScDrawLayer::ScMovePage( USHORT nOldPos, USHORT nNewPos )
+{
+ MovePage( nOldPos, nNewPos );
+}
+
+void ScDrawLayer::ScCopyPage( USHORT nOldPos, USHORT nNewPos, BOOL bAlloc )
+{
+ //! remove argument bAlloc (always FALSE)
+
+ if (bDrawIsInUndo)
+ return;
+
+ SdrPage* pOldPage = GetPage(nOldPos);
+ SdrPage* pNewPage = bAlloc ? AllocPage(FALSE) : GetPage(nNewPos);
+
+ // kopieren
+
+ if (pOldPage && pNewPage)
+ {
+ SdrObjListIter aIter( *pOldPage, IM_FLAT );
+ SdrObject* pOldObject = aIter.Next();
+ while (pOldObject)
+ {
+ // #116235#
+ SdrObject* pNewObject = pOldObject->Clone();
+ //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this );
+ pNewObject->SetModel(this);
+ pNewObject->SetPage(pNewPage);
+
+ pNewObject->NbcMove(Size(0,0));
+ pNewPage->InsertObject( pNewObject );
+ if (bRecording)
+ AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+
+ pOldObject = aIter.Next();
+ }
+ }
+
+ if (bAlloc)
+ InsertPage(pNewPage, nNewPos);
+}
+
+inline BOOL IsInBlock( const ScAddress& rPos, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2 )
+{
+ return rPos.Col() >= nCol1 && rPos.Col() <= nCol2 &&
+ rPos.Row() >= nRow1 && rPos.Row() <= nRow2;
+}
+
+void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
+ SCsCOL nDx,SCsROW nDy, bool bUpdateNoteCaptionPos )
+{
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page nicht gefunden");
+ if (!pPage)
+ return;
+
+ BOOL bNegativePage = pDoc && pDoc->IsNegativePage( nTab );
+
+ ULONG nCount = pPage->GetObjCount();
+ for ( ULONG i = 0; i < nCount; i++ )
+ {
+ SdrObject* pObj = pPage->GetObj( i );
+ ScDrawObjData* pData = GetObjDataTab( pObj, nTab );
+ if( pData )
+ {
+ const ScAddress aOldStt = pData->maStart;
+ const ScAddress aOldEnd = pData->maEnd;
+ BOOL bChange = FALSE;
+ if ( aOldStt.IsValid() && IsInBlock( aOldStt, nCol1,nRow1, nCol2,nRow2 ) )
+ {
+ pData->maStart.IncCol( nDx );
+ pData->maStart.IncRow( nDy );
+ bChange = TRUE;
+ }
+ if ( aOldEnd.IsValid() && IsInBlock( aOldEnd, nCol1,nRow1, nCol2,nRow2 ) )
+ {
+ pData->maEnd.IncCol( nDx );
+ pData->maEnd.IncRow( nDy );
+ bChange = TRUE;
+ }
+ if (bChange)
+ {
+ 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, bNegativePage, bUpdateNoteCaptionPos );
+ }
+ }
+ }
+}
+
+void ScDrawLayer::SetPageSize( USHORT nPageNo, const Size& rSize, bool bUpdateNoteCaptionPos )
+{
+ SdrPage* pPage = GetPage(nPageNo);
+ if (pPage)
+ {
+ if ( rSize != pPage->GetSize() )
+ {
+ pPage->SetSize( rSize );
+ Broadcast( ScTabSizeChangedHint( static_cast<SCTAB>(nPageNo) ) ); // SetWorkArea() an den Views
+ }
+
+ // Detektivlinien umsetzen (an neue Hoehen/Breiten anpassen)
+ // auch wenn Groesse gleich geblieben ist
+ // (einzelne Zeilen/Spalten koennen geaendert sein)
+
+ BOOL bNegativePage = pDoc && pDoc->IsNegativePage( static_cast<SCTAB>(nPageNo) );
+
+ ULONG nCount = pPage->GetObjCount();
+ for ( ULONG i = 0; i < nCount; i++ )
+ {
+ SdrObject* pObj = pPage->GetObj( i );
+ ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) );
+ if( pData )
+ RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
+ }
+ }
+}
+
+void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::RecalcPos - missing document" );
+ if( !pDoc )
+ return;
+
+ if( rData.mbNote )
+ {
+ DBG_ASSERT( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
+ /* #i109372# On insert/remove rows/columns/cells: Updating the caption
+ position must not be done, if the cell containing the note has not
+ been moved yet in the document. The calling code now passes an
+ additional boolean stating if the cells are already moved. */
+ if( bUpdateNoteCaptionPos )
+ /* When inside an undo action, there may be pending note captions
+ where cell note is already deleted (thus document cannot find
+ the note object anymore). The caption will be deleted later
+ with drawing undo. */
+ if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) )
+ pNote->UpdateCaptionPos( rData.maStart );
+ return;
+ }
+
+ bool bValid1 = rData.maStart.IsValid();
+ SCCOL nCol1 = rData.maStart.Col();
+ SCROW nRow1 = rData.maStart.Row();
+ SCTAB nTab1 = rData.maStart.Tab();
+ bool bValid2 = rData.maEnd.IsValid();
+ SCCOL nCol2 = rData.maEnd.Col();
+ SCROW nRow2 = rData.maEnd.Row();
+ SCTAB nTab2 = rData.maEnd.Tab();
+
+ // validation circle
+ bool bCircle = pObj->ISA( SdrCircObj );
+ // detective arrow
+ bool bArrow = pObj->IsPolyObj() && (pObj->GetPointCount() == 2);
+
+ if( bCircle )
+ {
+ Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
+ TwipsToMM( aPos.X() );
+ TwipsToMM( aPos.Y() );
+
+ // Berechnung und Werte wie in detfunc.cxx
+
+ Size aSize( (long)(pDoc->GetColWidth( nCol1, nTab1 ) * HMM_PER_TWIPS),
+ (long)(pDoc->GetRowHeight( nRow1, nTab1 ) * HMM_PER_TWIPS) );
+ Rectangle aRect( aPos, aSize );
+ aRect.Left() -= 250;
+ aRect.Right() += 250;
+ aRect.Top() -= 70;
+ aRect.Bottom() += 70;
+ if ( bNegativePage )
+ MirrorRectRTL( aRect );
+
+ if ( pObj->GetLogicRect() != aRect )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetLogicRect(aRect);
+ }
+ }
+ else if( bArrow )
+ {
+ //! nicht mehrere Undos fuer ein Objekt erzeugen (hinteres kann dann weggelassen werden)
+
+ SCCOL nLastCol;
+ SCROW nLastRow;
+ if( bValid1 )
+ {
+ Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
+ if (!pDoc->ColHidden(nCol1, nTab1, nLastCol))
+ aPos.X() += pDoc->GetColWidth( nCol1, nTab1 ) / 4;
+ if (!pDoc->RowHidden(nRow1, nTab1, nLastRow))
+ aPos.Y() += pDoc->GetRowHeight( nRow1, nTab1 ) / 2;
+ TwipsToMM( aPos.X() );
+ TwipsToMM( aPos.Y() );
+ Point aStartPos = aPos;
+ if ( bNegativePage )
+ aStartPos.X() = -aStartPos.X(); // don't modify aPos - used below
+ if ( pObj->GetPoint( 0 ) != aStartPos )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetPoint( aStartPos, 0 );
+ }
+
+ if( !bValid2 )
+ {
+ Point aEndPos( aPos.X() + DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
+ if (aEndPos.Y() < 0)
+ aEndPos.Y() += (2 * DET_ARROW_OFFSET);
+ if ( bNegativePage )
+ aEndPos.X() = -aEndPos.X();
+ if ( pObj->GetPoint( 1 ) != aEndPos )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetPoint( aEndPos, 1 );
+ }
+ }
+ }
+ if( bValid2 )
+ {
+ Point aPos( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
+ if (!pDoc->ColHidden(nCol2, nTab2, nLastCol))
+ aPos.X() += pDoc->GetColWidth( nCol2, nTab2 ) / 4;
+ if (!pDoc->RowHidden(nRow2, nTab2, nLastRow))
+ aPos.Y() += pDoc->GetRowHeight( nRow2, nTab2 ) / 2;
+ TwipsToMM( aPos.X() );
+ TwipsToMM( aPos.Y() );
+ Point aEndPos = aPos;
+ if ( bNegativePage )
+ aEndPos.X() = -aEndPos.X(); // don't modify aPos - used below
+ if ( pObj->GetPoint( 1 ) != aEndPos )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetPoint( aEndPos, 1 );
+ }
+
+ if( !bValid1 )
+ {
+ Point aStartPos( aPos.X() - DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
+ if (aStartPos.X() < 0)
+ aStartPos.X() += (2 * DET_ARROW_OFFSET);
+ if (aStartPos.Y() < 0)
+ aStartPos.Y() += (2 * DET_ARROW_OFFSET);
+ if ( bNegativePage )
+ aStartPos.X() = -aStartPos.X();
+ if ( pObj->GetPoint( 0 ) != aStartPos )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetPoint( aStartPos, 0 );
+ }
+ }
+ }
+ }
+ else // Referenz-Rahmen
+ {
+ DBG_ASSERT( bValid1, "ScDrawLayer::RecalcPos - invalid start position" );
+ Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
+ TwipsToMM( aPos.X() );
+ TwipsToMM( aPos.Y() );
+
+ if( bValid2 )
+ {
+ Point aEnd( pDoc->GetColOffset( nCol2 + 1, nTab2 ), pDoc->GetRowOffset( nRow2 + 1, nTab2 ) );
+ TwipsToMM( aEnd.X() );
+ TwipsToMM( aEnd.Y() );
+
+ Rectangle aNew( aPos, aEnd );
+ if ( bNegativePage )
+ MirrorRectRTL( aNew );
+ if ( pObj->GetLogicRect() != aNew )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetLogicRect(aNew);
+ }
+ }
+ else
+ {
+ if ( bNegativePage )
+ aPos.X() = -aPos.X();
+ if ( pObj->GetRelativePos() != aPos )
+ {
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->SetRelativePos( aPos );
+ }
+ }
+ }
+}
+
+BOOL ScDrawLayer::GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) const
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::GetPrintArea without document" );
+ if ( !pDoc )
+ return FALSE;
+
+ SCTAB nTab = rRange.aStart.Tab();
+ DBG_ASSERT( rRange.aEnd.Tab() == nTab, "GetPrintArea: Tab unterschiedlich" );
+
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+
+ BOOL bAny = FALSE;
+ long nEndX = 0;
+ long nEndY = 0;
+ long nStartX = LONG_MAX;
+ long nStartY = LONG_MAX;
+
+ // Grenzen ausrechnen
+
+ if (!bSetHor)
+ {
+ nStartX = 0;
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCCOL i;
+ for (i=0; i<nStartCol; i++)
+ nStartX +=pDoc->GetColWidth(i,nTab);
+ nEndX = nStartX;
+ SCCOL nEndCol = rRange.aEnd.Col();
+ for (i=nStartCol; i<=nEndCol; i++)
+ nEndX += pDoc->GetColWidth(i,nTab);
+ nStartX = (long)(nStartX * HMM_PER_TWIPS);
+ nEndX = (long)(nEndX * HMM_PER_TWIPS);
+ }
+ if (!bSetVer)
+ {
+ nStartY = pDoc->GetRowHeight( 0, rRange.aStart.Row()-1, nTab);
+ nEndY = nStartY + pDoc->GetRowHeight( rRange.aStart.Row(),
+ rRange.aEnd.Row(), nTab);
+ nStartY = (long)(nStartY * HMM_PER_TWIPS);
+ nEndY = (long)(nEndY * HMM_PER_TWIPS);
+ }
+
+ if ( bNegativePage )
+ {
+ nStartX = -nStartX; // positions are negative, swap start/end so the same comparisons work
+ nEndX = -nEndX;
+ ::std::swap( nStartX, nEndX );
+ }
+
+ const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page nicht gefunden");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ //! Flags (ausgeblendet?) testen
+
+ Rectangle aObjRect = pObject->GetCurrentBoundRect();
+ BOOL bFit = TRUE;
+ if ( !bSetHor && ( aObjRect.Right() < nStartX || aObjRect.Left() > nEndX ) )
+ bFit = FALSE;
+ if ( !bSetVer && ( aObjRect.Bottom() < nStartY || aObjRect.Top() > nEndY ) )
+ bFit = FALSE;
+ if ( bFit )
+ {
+ if (bSetHor)
+ {
+ if (aObjRect.Left() < nStartX) nStartX = aObjRect.Left();
+ if (aObjRect.Right() > nEndX) nEndX = aObjRect.Right();
+ }
+ if (bSetVer)
+ {
+ if (aObjRect.Top() < nStartY) nStartY = aObjRect.Top();
+ if (aObjRect.Bottom() > nEndY) nEndY = aObjRect.Bottom();
+ }
+ bAny = TRUE;
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+
+ if ( bNegativePage )
+ {
+ nStartX = -nStartX; // reverse transformation, so the same cell address calculation works
+ nEndX = -nEndX;
+ ::std::swap( nStartX, nEndX );
+ }
+
+ if (bAny)
+ {
+ DBG_ASSERT( nStartX<=nEndX && nStartY<=nEndY, "Start/End falsch in ScDrawLayer::GetPrintArea" );
+
+ if (bSetHor)
+ {
+ nStartX = (long) (nStartX / HMM_PER_TWIPS);
+ nEndX = (long) (nEndX / HMM_PER_TWIPS);
+ long nWidth;
+ SCCOL i;
+
+ nWidth = 0;
+ for (i=0; i<=MAXCOL && nWidth<=nStartX; i++)
+ nWidth += pDoc->GetColWidth(i,nTab);
+ rRange.aStart.SetCol( i>0 ? (i-1) : 0 );
+
+ nWidth = 0;
+ for (i=0; i<=MAXCOL && nWidth<=nEndX; i++) //! bei Start anfangen
+ nWidth += pDoc->GetColWidth(i,nTab);
+ rRange.aEnd.SetCol( i>0 ? (i-1) : 0 );
+ }
+
+ if (bSetVer)
+ {
+ nStartY = (long) (nStartY / HMM_PER_TWIPS);
+ nEndY = (long) (nEndY / HMM_PER_TWIPS);
+ SCROW nRow = pDoc->GetRowForHeight( nTab, nStartY);
+ rRange.aStart.SetRow( nRow>0 ? (nRow-1) : 0);
+ nRow = pDoc->GetRowForHeight( nTab, nEndY);
+ rRange.aEnd.SetRow( nRow == MAXROW ? MAXROW :
+ (nRow>0 ? (nRow-1) : 0));
+ }
+ }
+ else
+ {
+ if (bSetHor)
+ {
+ rRange.aStart.SetCol(0);
+ rRange.aEnd.SetCol(0);
+ }
+ if (bSetVer)
+ {
+ rRange.aStart.SetRow(0);
+ rRange.aEnd.SetRow(0);
+ }
+ }
+ return bAny;
+}
+
+void ScDrawLayer::AddCalcUndo( SdrUndoAction* pUndo )
+{
+ if (bRecording)
+ {
+ if (!pUndoGroup)
+ pUndoGroup = new SdrUndoGroup(*this);
+
+ pUndoGroup->AddAction( pUndo );
+ }
+ else
+ delete pUndo;
+}
+
+void ScDrawLayer::BeginCalcUndo()
+{
+//! DBG_ASSERT( !bRecording, "BeginCalcUndo ohne GetCalcUndo" );
+
+ DELETEZ(pUndoGroup);
+ bRecording = TRUE;
+}
+
+SdrUndoGroup* ScDrawLayer::GetCalcUndo()
+{
+//! DBG_ASSERT( bRecording, "GetCalcUndo ohne BeginCalcUndo" );
+
+ SdrUndoGroup* pRet = pUndoGroup;
+ pUndoGroup = NULL;
+ bRecording = FALSE;
+ return pRet;
+}
+
+// MoveAreaTwips: all measures are kept in twips
+void ScDrawLayer::MoveAreaTwips( SCTAB nTab, const Rectangle& rArea,
+ const Point& rMove, const Point& rTopLeft )
+{
+ if (!rMove.X() && !rMove.Y())
+ return; // nix
+
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page nicht gefunden");
+ if (!pPage)
+ return;
+
+ BOOL bNegativePage = pDoc && pDoc->IsNegativePage( nTab );
+
+ // fuer Shrinking!
+ Rectangle aNew( rArea );
+ BOOL bShrink = FALSE;
+ if ( rMove.X() < 0 || rMove.Y() < 0 ) // verkleinern
+ {
+ if ( rTopLeft != rArea.TopLeft() ) // sind gleich beim Verschieben von Zellen
+ {
+ bShrink = TRUE;
+ aNew.Left() = rTopLeft.X();
+ aNew.Top() = rTopLeft.Y();
+ }
+ }
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if( GetAnchor( pObject ) == SCA_CELL )
+ {
+ if ( GetObjData( pObject ) ) // Detektiv-Pfeil ?
+ {
+ // hier nichts
+ }
+ else if ( pObject->ISA( SdrEdgeObj ) ) // Verbinder?
+ {
+ // hier auch nichts
+ //! nicht verbundene Enden wie bei Linien (s.u.) behandeln?
+ }
+ else if ( pObject->IsPolyObj() && pObject->GetPointCount()==2 )
+ {
+ for (USHORT i=0; i<2; i++)
+ {
+ BOOL bMoved = FALSE;
+ Point aPoint = pObject->GetPoint(i);
+ lcl_ReverseTwipsToMM( aPoint );
+ if (rArea.IsInside(aPoint))
+ {
+ aPoint += rMove; bMoved = TRUE;
+ }
+ else if (bShrink && aNew.IsInside(aPoint))
+ {
+ // Punkt ist in betroffener Zelle - Test auf geloeschten Bereich
+ if ( rMove.X() && aPoint.X() >= rArea.Left() + rMove.X() )
+ {
+ aPoint.X() = rArea.Left() + rMove.X() - SHRINK_DIST_TWIPS;
+ if ( aPoint.X() < 0 ) aPoint.X() = 0;
+ bMoved = TRUE;
+ }
+ if ( rMove.Y() && aPoint.Y() >= rArea.Top() + rMove.Y() )
+ {
+ aPoint.Y() = rArea.Top() + rMove.Y() - SHRINK_DIST_TWIPS;
+ if ( aPoint.Y() < 0 ) aPoint.Y() = 0;
+ bMoved = TRUE;
+ }
+ }
+ if( bMoved )
+ {
+ AddCalcUndo( new SdrUndoGeoObj( *pObject ) );
+ lcl_TwipsToMM( aPoint );
+ pObject->SetPoint( aPoint, i );
+ }
+ }
+ }
+ else
+ {
+ Rectangle aObjRect = pObject->GetLogicRect();
+ // aOldMMPos: not converted, millimeters
+ Point aOldMMPos = bNegativePage ? aObjRect.TopRight() : aObjRect.TopLeft();
+ lcl_ReverseTwipsToMM( aObjRect );
+ Point aTopLeft = bNegativePage ? aObjRect.TopRight() : aObjRect.TopLeft(); // logical left
+ Size aMoveSize;
+ BOOL bDoMove = FALSE;
+ if (rArea.IsInside(aTopLeft))
+ {
+ aMoveSize = Size(rMove.X(),rMove.Y());
+ bDoMove = TRUE;
+ }
+ else if (bShrink && aNew.IsInside(aTopLeft))
+ {
+ // Position ist in betroffener Zelle - Test auf geloeschten Bereich
+ if ( rMove.X() && aTopLeft.X() >= rArea.Left() + rMove.X() )
+ {
+ aMoveSize.Width() = rArea.Left() + rMove.X() - SHRINK_DIST - aTopLeft.X();
+ bDoMove = TRUE;
+ }
+ if ( rMove.Y() && aTopLeft.Y() >= rArea.Top() + rMove.Y() )
+ {
+ aMoveSize.Height() = rArea.Top() + rMove.Y() - SHRINK_DIST - aTopLeft.Y();
+ bDoMove = TRUE;
+ }
+ }
+ if ( bDoMove )
+ {
+ if ( bNegativePage )
+ {
+ if ( aTopLeft.X() + aMoveSize.Width() > 0 )
+ aMoveSize.Width() = -aTopLeft.X();
+ }
+ else
+ {
+ if ( aTopLeft.X() + aMoveSize.Width() < 0 )
+ aMoveSize.Width() = -aTopLeft.X();
+ }
+ if ( aTopLeft.Y() + aMoveSize.Height() < 0 )
+ aMoveSize.Height() = -aTopLeft.Y();
+
+ // get corresponding move size in millimeters:
+ Point aNewPos( aTopLeft.X() + aMoveSize.Width(), aTopLeft.Y() + aMoveSize.Height() );
+ lcl_TwipsToMM( aNewPos );
+ aMoveSize = Size( aNewPos.X() - aOldMMPos.X(), aNewPos.Y() - aOldMMPos.Y() ); // millimeters
+
+ AddCalcUndo( new SdrUndoMoveObj( *pObject, aMoveSize ) );
+ pObject->Move( aMoveSize );
+ }
+ else if ( rArea.IsInside( bNegativePage ? aObjRect.BottomLeft() : aObjRect.BottomRight() ) &&
+ !pObject->IsResizeProtect() )
+ {
+ // geschuetzte Groessen werden nicht veraendert
+ // (Positionen schon, weil sie ja an der Zelle "verankert" sind)
+ AddCalcUndo( new SdrUndoGeoObj( *pObject ) );
+ long nOldSizeX = aObjRect.Right() - aObjRect.Left() + 1;
+ long nOldSizeY = aObjRect.Bottom() - aObjRect.Top() + 1;
+ long nLogMoveX = rMove.X() * ( bNegativePage ? -1 : 1 ); // logical direction
+ pObject->Resize( aOldMMPos, Fraction( nOldSizeX+nLogMoveX, nOldSizeX ),
+ Fraction( nOldSizeY+rMove.Y(), nOldSizeY ) );
+ }
+ }
+ }
+ pObject = aIter.Next();
+ }
+}
+
+void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
+ SCsCOL nDx,SCsROW nDy, BOOL bInsDel, bool bUpdateNoteCaptionPos )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::MoveArea without document" );
+ if ( !pDoc )
+ return;
+
+ if (!bAdjustEnabled)
+ return;
+
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+
+ Rectangle aRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
+ lcl_ReverseTwipsToMM( aRect );
+ //! use twips directly?
+
+ Point aMove;
+
+ if (nDx > 0)
+ for (SCsCOL s=0; s<nDx; s++)
+ aMove.X() += pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
+ else
+ for (SCsCOL s=-1; s>=nDx; s--)
+ aMove.X() -= pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
+ if (nDy > 0)
+ aMove.Y() += pDoc->GetRowHeight( nRow1, nRow1+nDy-1, nTab);
+ else
+ aMove.Y() -= pDoc->GetRowHeight( nRow1+nDy, nRow1-1, nTab);
+
+ if ( bNegativePage )
+ aMove.X() = -aMove.X();
+
+ Point aTopLeft = aRect.TopLeft(); // Anfang beim Verkleinern
+ if (bInsDel)
+ {
+ if ( aMove.X() != 0 && nDx < 0 ) // nDx counts cells, sign is independent of RTL
+ aTopLeft.X() += aMove.X();
+ if ( aMove.Y() < 0 )
+ aTopLeft.Y() += aMove.Y();
+ }
+
+ // drawing objects are now directly included in cut&paste
+ // -> only update references when inserting/deleting (or changing widths or heights)
+ if ( bInsDel )
+ MoveAreaTwips( nTab, aRect, aMove, aTopLeft );
+
+ //
+ // Detektiv-Pfeile: Zellpositionen anpassen
+ //
+
+ MoveCells( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy, bUpdateNoteCaptionPos );
+}
+
+void ScDrawLayer::WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::WidthChanged without document" );
+ if ( !pDoc )
+ return;
+
+ if (!bAdjustEnabled)
+ return;
+
+ Rectangle aRect;
+ Point aTopLeft;
+
+ for (SCCOL i=0; i<nCol; i++)
+ aRect.Left() += pDoc->GetColWidth(i,nTab);
+ aTopLeft.X() = aRect.Left();
+ aRect.Left() += pDoc->GetColWidth(nCol,nTab);
+
+ aRect.Right() = MAXMM;
+ aRect.Top() = 0;
+ aRect.Bottom() = MAXMM;
+
+ //! aTopLeft ist falsch, wenn mehrere Spalten auf einmal ausgeblendet werden
+
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+ if ( bNegativePage )
+ {
+ MirrorRectRTL( aRect );
+ aTopLeft.X() = -aTopLeft.X();
+ nDifTwips = -nDifTwips;
+ }
+
+ MoveAreaTwips( nTab, aRect, Point( nDifTwips,0 ), aTopLeft );
+}
+
+void ScDrawLayer::HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::HeightChanged without document" );
+ if ( !pDoc )
+ return;
+
+ if (!bAdjustEnabled)
+ return;
+
+ Rectangle aRect;
+ Point aTopLeft;
+
+ aRect.Top() += pDoc->GetRowHeight( 0, nRow-1, nTab);
+ aTopLeft.Y() = aRect.Top();
+ aRect.Top() += pDoc->GetRowHeight(nRow, nTab);
+
+ aRect.Bottom() = MAXMM;
+ aRect.Left() = 0;
+ aRect.Right() = MAXMM;
+
+ //! aTopLeft ist falsch, wenn mehrere Zeilen auf einmal ausgeblendet werden
+
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+ if ( bNegativePage )
+ {
+ MirrorRectRTL( aRect );
+ aTopLeft.X() = -aTopLeft.X();
+ }
+
+ MoveAreaTwips( nTab, aRect, Point( 0,nDifTwips ), aTopLeft );
+}
+
+BOOL ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow, bool bIncludeNotes )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::HasObjectsInRows without document" );
+ if ( !pDoc )
+ return FALSE;
+
+ Rectangle aTestRect;
+
+ aTestRect.Top() += pDoc->GetRowHeight( 0, nStartRow-1, nTab);
+
+ if (nEndRow==MAXROW)
+ aTestRect.Bottom() = MAXMM;
+ else
+ {
+ aTestRect.Bottom() = aTestRect.Top();
+ aTestRect.Bottom() += pDoc->GetRowHeight( nStartRow, nEndRow, nTab);
+ TwipsToMM( aTestRect.Bottom() );
+ }
+
+ TwipsToMM( aTestRect.Top() );
+
+ aTestRect.Left() = 0;
+ aTestRect.Right() = MAXMM;
+
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+ if ( bNegativePage )
+ MirrorRectRTL( aTestRect );
+
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page nicht gefunden");
+ if (!pPage)
+ return FALSE;
+
+ BOOL bFound = FALSE;
+
+ Rectangle aObjRect;
+ SdrObjListIter aIter( *pPage );
+ SdrObject* pObject = aIter.Next();
+ while ( pObject && !bFound )
+ {
+ aObjRect = pObject->GetSnapRect(); //! GetLogicRect ?
+ // #i116164# note captions are handled separately, don't have to be included for each single row height change
+ if ( (aTestRect.IsInside(aObjRect.TopLeft()) || aTestRect.IsInside(aObjRect.BottomLeft())) &&
+ (bIncludeNotes || !IsNoteCaption(pObject)) )
+ bFound = TRUE;
+
+ pObject = aIter.Next();
+ }
+
+ return bFound;
+}
+
+#if 0
+void ScDrawLayer::DeleteObjects( SCTAB nTab )
+{
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (!pPage)
+ return;
+
+ pPage->RecalcObjOrdNums();
+
+ long nDelCount = 0;
+ ULONG nObjCount = pPage->GetObjCount();
+ if (nObjCount)
+ {
+ SdrObject** ppObj = new SdrObject*[nObjCount];
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ // alle loeschen
+ ppObj[nDelCount++] = pObject;
+ pObject = aIter.Next();
+ }
+
+ long i;
+ if (bRecording)
+ for (i=1; i<=nDelCount; i++)
+ AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
+
+ for (i=1; i<=nDelCount; i++)
+ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
+
+ delete[] ppObj;
+ }
+}
+#endif
+
+void ScDrawLayer::DeleteObjectsInArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1,
+ SCCOL nCol2,SCROW nRow2 )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::DeleteObjectsInArea without document" );
+ if ( !pDoc )
+ return;
+
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (!pPage)
+ return;
+
+ pPage->RecalcObjOrdNums();
+
+ long nDelCount = 0;
+ ULONG nObjCount = pPage->GetObjCount();
+ if (nObjCount)
+ {
+ Rectangle aDelRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
+
+ SdrObject** ppObj = new SdrObject*[nObjCount];
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ // do not delete note caption, they are always handled by the cell note
+ // TODO: detective objects are still deleted, is this desired?
+ if (!IsNoteCaption( pObject ))
+ {
+ Rectangle aObjRect = pObject->GetCurrentBoundRect();
+ if ( aDelRect.IsInside( aObjRect ) )
+ ppObj[nDelCount++] = pObject;
+ }
+
+ pObject = aIter.Next();
+ }
+
+ long i;
+ if (bRecording)
+ for (i=1; i<=nDelCount; i++)
+ AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
+
+ for (i=1; i<=nDelCount; i++)
+ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
+
+ delete[] ppObj;
+ }
+}
+
+void ScDrawLayer::DeleteObjectsInSelection( const ScMarkData& rMark )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::DeleteObjectsInSelection without document" );
+ if ( !pDoc )
+ return;
+
+ if ( !rMark.IsMultiMarked() )
+ return;
+
+ ScRange aMarkRange;
+ rMark.GetMultiMarkArea( aMarkRange );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<=nTabCount; nTab++)
+ if ( rMark.GetTableSelect( nTab ) )
+ {
+ SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
+ if (pPage)
+ {
+ pPage->RecalcObjOrdNums();
+ long nDelCount = 0;
+ ULONG nObjCount = pPage->GetObjCount();
+ if (nObjCount)
+ {
+ // Rechteck um die ganze Selektion
+ Rectangle aMarkBound = pDoc->GetMMRect(
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab );
+
+ SdrObject** ppObj = new SdrObject*[nObjCount];
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ // do not delete note caption, they are always handled by the cell note
+ // TODO: detective objects are still deleted, is this desired?
+ if (!IsNoteCaption( pObject ))
+ {
+ Rectangle aObjRect = pObject->GetCurrentBoundRect();
+ if ( aMarkBound.IsInside( aObjRect ) )
+ {
+ ScRange aRange = pDoc->GetRange( nTab, aObjRect );
+ if (rMark.IsAllMarked(aRange))
+ ppObj[nDelCount++] = pObject;
+ }
+ }
+
+ pObject = aIter.Next();
+ }
+
+ // Objekte loeschen (rueckwaerts)
+
+ long i;
+ if (bRecording)
+ for (i=1; i<=nDelCount; i++)
+ AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
+
+ for (i=1; i<=nDelCount; i++)
+ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
+
+ delete[] ppObj;
+ }
+ }
+ else
+ {
+ DBG_ERROR("pPage?");
+ }
+ }
+}
+
+void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& rRange )
+{
+ // copy everything in the specified range into the same page (sheet) in the clipboard doc
+
+ SdrPage* pSrcPage = GetPage(static_cast<sal_uInt16>(nTab));
+ if (pSrcPage)
+ {
+ ScDrawLayer* pDestModel = NULL;
+ SdrPage* pDestPage = NULL;
+
+ SdrObjListIter aIter( *pSrcPage, IM_FLAT );
+ SdrObject* pOldObject = aIter.Next();
+ while (pOldObject)
+ {
+ Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
+ // do not copy internal objects (detective) and note captions
+ if ( rRange.IsInside( aObjRect ) && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption( pOldObject ) )
+ {
+ if ( !pDestModel )
+ {
+ pDestModel = pClipDoc->GetDrawLayer(); // does the document already have a drawing layer?
+ if ( !pDestModel )
+ {
+ // allocate drawing layer in clipboard document only if there are objects to copy
+
+ pClipDoc->InitDrawLayer(); //! create contiguous pages
+ pDestModel = pClipDoc->GetDrawLayer();
+ }
+ if (pDestModel)
+ pDestPage = pDestModel->GetPage( static_cast<sal_uInt16>(nTab) );
+ }
+
+ DBG_ASSERT( pDestPage, "no page" );
+ if (pDestPage)
+ {
+ // #116235#
+ SdrObject* pNewObject = pOldObject->Clone();
+ //SdrObject* pNewObject = pOldObject->Clone( pDestPage, pDestModel );
+ pNewObject->SetModel(pDestModel);
+ pNewObject->SetPage(pDestPage);
+
+ uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) );
+ if(!xOldChart.is())//#i110034# do not move charts as they loose all their data references otherwise
+ pNewObject->NbcMove(Size(0,0));
+ pDestPage->InsertObject( pNewObject );
+
+ // no undo needed in clipboard document
+ // charts are not updated
+ }
+ }
+
+ pOldObject = aIter.Next();
+ }
+ }
+}
+
+BOOL lcl_IsAllInRange( const ::std::vector< ScRangeList >& rRangesVector, const ScRange& rClipRange )
+{
+ // check if every range of rRangesVector is completely in rClipRange
+
+ ::std::vector< ScRangeList >::const_iterator aIt = rRangesVector.begin();
+ for( ;aIt!=rRangesVector.end(); ++aIt )
+ {
+ const ScRangeList& rRanges = *aIt;
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *rRanges.GetObject(i);
+ if ( !rClipRange.In( aRange ) )
+ {
+ return FALSE; // at least one range is not valid
+ }
+ }
+ }
+
+ return TRUE; // everything is fine
+}
+
+BOOL lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const ScRange& rSourceRange, const ScAddress& rDestPos )
+{
+ BOOL bChanged = FALSE;
+
+ ::std::vector< ScRangeList >::iterator aIt = rRangesVector.begin();
+ for( ;aIt!=rRangesVector.end(); ++aIt )
+ {
+ ScRangeList& rRanges = *aIt;
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange* pRange = rRanges.GetObject(i);
+ if ( rSourceRange.In( *pRange ) )
+ {
+ SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col();
+ SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row();
+ SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab();
+ pRange->Move( nDiffX, nDiffY, nDiffZ );
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ return bChanged;
+}
+
+void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const Rectangle& rSourceRange,
+ const ScAddress& rDestPos, const Rectangle& rDestRange )
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::CopyFromClip without document" );
+ if ( !pDoc )
+ return;
+
+ if (!pClipModel)
+ return;
+
+ if (bDrawIsInUndo) //! can this happen?
+ {
+ DBG_ERROR("CopyFromClip, bDrawIsInUndo");
+ return;
+ }
+
+ BOOL bMirrorObj = ( rSourceRange.Left() < 0 && rSourceRange.Right() < 0 &&
+ rDestRange.Left() > 0 && rDestRange.Right() > 0 ) ||
+ ( rSourceRange.Left() > 0 && rSourceRange.Right() > 0 &&
+ rDestRange.Left() < 0 && rDestRange.Right() < 0 );
+ Rectangle aMirroredSource = rSourceRange;
+ if ( bMirrorObj )
+ MirrorRectRTL( aMirroredSource );
+
+ SCTAB nDestTab = rDestPos.Tab();
+
+ SdrPage* pSrcPage = pClipModel->GetPage(static_cast<sal_uInt16>(nSourceTab));
+ SdrPage* pDestPage = GetPage(static_cast<sal_uInt16>(nDestTab));
+ DBG_ASSERT( pSrcPage && pDestPage, "draw page missing" );
+ if ( !pSrcPage || !pDestPage )
+ return;
+
+ SdrObjListIter aIter( *pSrcPage, IM_FLAT );
+ SdrObject* pOldObject = aIter.Next();
+
+ ScDocument* pClipDoc = pClipModel->GetDocument();
+ // a clipboard document and its source share the same document item pool,
+ // so the pointers can be compared to see if this is copy&paste within
+ // the same document
+ BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool();
+ BOOL bDestClip = pDoc && pDoc->IsClipboard();
+
+ //#i110034# charts need correct sheet names for xml range conversion during load
+ //so the target sheet name is temporarily renamed (if we have any SdrObjects)
+ String aDestTabName;
+ BOOL bRestoreDestTabName = FALSE;
+ if( pOldObject && !bSameDoc && !bDestClip )
+ {
+ if( pDoc && pClipDoc )
+ {
+ String aSourceTabName;
+ if( pClipDoc->GetName( nSourceTab, aSourceTabName )
+ && pDoc->GetName( nDestTab, aDestTabName ) )
+ {
+ if( !(aSourceTabName==aDestTabName) &&
+ pDoc->ValidNewTabName(aSourceTabName) )
+ {
+ bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName ); //BOOL bUpdateRef = TRUE, BOOL bExternalDocument = FALSE
+ }
+ }
+ }
+ }
+
+ // first mirror, then move
+ Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() );
+
+ long nDestWidth = rDestRange.GetWidth();
+ long nDestHeight = rDestRange.GetHeight();
+ long nSourceWidth = rSourceRange.GetWidth();
+ long nSourceHeight = rSourceRange.GetHeight();
+
+ long nWidthDiff = nDestWidth - nSourceWidth;
+ long nHeightDiff = nDestHeight - nSourceHeight;
+
+ Fraction aHorFract(1,1);
+ Fraction aVerFract(1,1);
+ BOOL bResize = FALSE;
+ // sizes can differ by 1 from twips->1/100mm conversion for equal cell sizes,
+ // don't resize to empty size when pasting into hidden columns or rows
+ if ( Abs(nWidthDiff) > 1 && nDestWidth > 1 && nSourceWidth > 1 )
+ {
+ aHorFract = Fraction( nDestWidth, nSourceWidth );
+ bResize = TRUE;
+ }
+ if ( Abs(nHeightDiff) > 1 && nDestHeight > 1 && nSourceHeight > 1 )
+ {
+ aVerFract = Fraction( nDestHeight, nSourceHeight );
+ bResize = TRUE;
+ }
+ Point aRefPos = rDestRange.TopLeft(); // for resizing (after moving)
+
+ while (pOldObject)
+ {
+ Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
+ // do not copy internal objects (detective) and note captions
+ if ( rSourceRange.IsInside( aObjRect ) && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption( pOldObject ) )
+ {
+ // #116235#
+ SdrObject* pNewObject = pOldObject->Clone();
+ //SdrObject* pNewObject = pOldObject->Clone( pDestPage, this );
+ pNewObject->SetModel(this);
+ pNewObject->SetPage(pDestPage);
+
+ if ( bMirrorObj )
+ MirrorRTL( pNewObject ); // first mirror, then move
+
+ pNewObject->NbcMove( aMove );
+ if ( bResize )
+ pNewObject->NbcResize( aRefPos, aHorFract, aVerFract );
+
+ pDestPage->InsertObject( pNewObject );
+ if (bRecording)
+ AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+
+ //#i110034# handle chart data references (after InsertObject)
+
+ if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pNewObject)->GetObjRef();
+ uno::Reference< embed::XClassifiedObject > xClassified( xIPObj, uno::UNO_QUERY );
+ SvGlobalName aObjectClassName;
+ if ( xClassified.is() )
+ {
+ try {
+ aObjectClassName = SvGlobalName( xClassified->getClassID() );
+ } catch( uno::Exception& )
+ {
+ // TODO: handle error?
+ }
+ }
+
+ if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) )
+ {
+ uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) );
+ if( xNewChart.is() && !xNewChart->hasInternalDataProvider() )
+ {
+ String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName();
+ ::std::vector< ScRangeList > aRangesVector;
+ pDoc->GetChartRanges( aChartName, aRangesVector, pDoc );
+ if( !aRangesVector.empty() )
+ {
+ BOOL bInSourceRange = FALSE;
+ ScRange aClipRange;
+ if ( pClipDoc )
+ {
+ SCCOL nClipStartX;
+ SCROW nClipStartY;
+ SCCOL nClipEndX;
+ SCROW nClipEndY;
+ pClipDoc->GetClipStart( nClipStartX, nClipStartY );
+ pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE );
+ nClipEndX = nClipEndX + nClipStartX;
+ nClipEndY += nClipStartY; // GetClipArea returns the difference
+
+ SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab;
+ aClipRange = ScRange( nClipStartX, nClipStartY, nClipTab,
+ nClipEndX, nClipEndY, nClipTab );
+
+ bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange );
+ }
+
+ // always lose references when pasting into a clipboard document (transpose)
+ if ( ( bInSourceRange || bSameDoc ) && !bDestClip )
+ {
+ if ( bInSourceRange )
+ {
+ if ( rDestPos != aClipRange.aStart )
+ {
+ // update the data ranges to the new (copied) position
+ if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) )
+ pDoc->SetChartRanges( aChartName, aRangesVector );
+ }
+ }
+ else
+ {
+ // leave the ranges unchanged
+ }
+ }
+ else
+ {
+ // pasting into a new document without the complete source data
+ // -> break connection to source data and switch to own data
+
+ uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY );
+ uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY );
+ if( xOldChartDoc.is() && xNewChartDoc.is() )
+ xNewChartDoc->attachData( xOldChartDoc->getData() );
+
+ // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ pOldObject = aIter.Next();
+ }
+
+ if( bRestoreDestTabName )
+ pDoc->RenameTab( nDestTab, aDestTabName );
+}
+
+void ScDrawLayer::MirrorRTL( SdrObject* pObj )
+{
+ UINT16 nIdent = pObj->GetObjIdentifier();
+
+ // don't mirror OLE or graphics, otherwise ask the object
+ // if it can be mirrored
+ BOOL bCanMirror = ( nIdent != OBJ_GRAF && nIdent != OBJ_OLE2 );
+ if (bCanMirror)
+ {
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo( aInfo );
+ bCanMirror = aInfo.bMirror90Allowed;
+ }
+
+ if (bCanMirror)
+ {
+ Point aRef1( 0, 0 );
+ Point aRef2( 0, 1 );
+ if (bRecording)
+ AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
+ pObj->Mirror( aRef1, aRef2 );
+ }
+ else
+ {
+ // Move instead of mirroring:
+ // New start position is negative of old end position
+ // -> move by sum of start and end position
+ Rectangle aObjRect = pObj->GetLogicRect();
+ Size aMoveSize( -(aObjRect.Left() + aObjRect.Right()), 0 );
+ if (bRecording)
+ AddCalcUndo( new SdrUndoMoveObj( *pObj, aMoveSize ) );
+ pObj->Move( aMoveSize );
+ }
+}
+
+// static
+void ScDrawLayer::MirrorRectRTL( Rectangle& rRect )
+{
+ // mirror and swap left/right
+ long nTemp = rRect.Left();
+ rRect.Left() = -rRect.Right();
+ rRect.Right() = -nTemp;
+}
+
+Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, bool bMergedCell )
+{
+ Rectangle aCellRect;
+ DBG_ASSERT( ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ), "ScDrawLayer::GetCellRect - invalid cell address" );
+ if( ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ) )
+ {
+ // find top left position of passed cell address
+ Point aTopLeft;
+ for( SCCOL nCol = 0; nCol < rPos.Col(); ++nCol )
+ aTopLeft.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
+ if( rPos.Row() > 0 )
+ aTopLeft.Y() += rDoc.GetRowHeight( 0, rPos.Row() - 1, rPos.Tab() );
+
+ // find bottom-right position of passed cell address
+ ScAddress aEndPos = rPos;
+ if( bMergedCell )
+ {
+ const ScMergeAttr* pMerge = static_cast< const ScMergeAttr* >( rDoc.GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), ATTR_MERGE ) );
+ if( pMerge->GetColMerge() > 1 )
+ aEndPos.IncCol( pMerge->GetColMerge() - 1 );
+ if( pMerge->GetRowMerge() > 1 )
+ aEndPos.IncRow( pMerge->GetRowMerge() - 1 );
+ }
+ Point aBotRight = aTopLeft;
+ for( SCCOL nCol = rPos.Col(); nCol <= aEndPos.Col(); ++nCol )
+ aBotRight.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
+ aBotRight.Y() += rDoc.GetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() );
+
+ // twips -> 1/100 mm
+ aTopLeft.X() = static_cast< long >( aTopLeft.X() * HMM_PER_TWIPS );
+ aTopLeft.Y() = static_cast< long >( aTopLeft.Y() * HMM_PER_TWIPS );
+ aBotRight.X() = static_cast< long >( aBotRight.X() * HMM_PER_TWIPS );
+ aBotRight.Y() = static_cast< long >( aBotRight.Y() * HMM_PER_TWIPS );
+
+ aCellRect = Rectangle( aTopLeft, aBotRight );
+ if( rDoc.IsNegativePage( rPos.Tab() ) )
+ MirrorRectRTL( aCellRect );
+ }
+ return aCellRect;
+}
+
+// static
+String ScDrawLayer::GetVisibleName( SdrObject* pObj )
+{
+ String aName = pObj->GetName();
+ if ( pObj->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ // #95575# For OLE, the user defined name (GetName) is used
+ // if it's not empty (accepting possibly duplicate names),
+ // otherwise the persist name is used so every object appears
+ // in the Navigator at all.
+
+ if ( !aName.Len() )
+ aName = static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
+ }
+ return aName;
+}
+
+inline sal_Bool IsNamedObject( SdrObject* pObj, const String& rName )
+{
+ // TRUE if rName is the object's Name or PersistName
+ // (used to find a named object)
+
+ return ( pObj->GetName() == rName ||
+ ( pObj->GetObjIdentifier() == OBJ_OLE2 &&
+ static_cast<SdrOle2Obj*>(pObj)->GetPersistName() == rName ) );
+}
+
+SdrObject* ScDrawLayer::GetNamedObject( const String& rName, USHORT nId, SCTAB& rFoundTab ) const
+{
+ sal_uInt16 nTabCount = GetPageCount();
+ for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
+ {
+ const SdrPage* pPage = GetPage(nTab);
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( nId == 0 || pObject->GetObjIdentifier() == nId )
+ if ( IsNamedObject( pObject, rName ) )
+ {
+ rFoundTab = static_cast<SCTAB>(nTab);
+ return pObject;
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ return NULL;
+}
+
+String ScDrawLayer::GetNewGraphicName( long* pnCounter ) const
+{
+ String aBase = ScGlobal::GetRscString(STR_GRAPHICNAME);
+ aBase += ' ';
+
+ BOOL bThere = TRUE;
+ String aGraphicName;
+ SCTAB nDummy;
+ long nId = pnCounter ? *pnCounter : 0;
+ while (bThere)
+ {
+ ++nId;
+ aGraphicName = aBase;
+ aGraphicName += String::CreateFromInt32( nId );
+ bThere = ( GetNamedObject( aGraphicName, 0, nDummy ) != NULL );
+ }
+
+ if ( pnCounter )
+ *pnCounter = nId;
+
+ return aGraphicName;
+}
+
+void ScDrawLayer::EnsureGraphicNames()
+{
+ // make sure all graphic objects have names (after Excel import etc.)
+
+ sal_uInt16 nTabCount = GetPageCount();
+ for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
+ {
+ SdrPage* pPage = GetPage(nTab);
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+
+ /* #101799# The index passed to GetNewGraphicName() will be set to
+ the used index in each call. This prevents the repeated search
+ for all names from 1 to current index. */
+ long nCounter = 0;
+
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_GRAF && pObject->GetName().Len() == 0 )
+ pObject->SetName( GetNewGraphicName( &nCounter ) );
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+}
+
+void ScDrawLayer::SetAnchor( SdrObject* pObj, ScAnchorType eType )
+{
+ ScAnchorType eOldAnchorType = GetAnchor( pObj );
+
+ // Ein an der Seite verankertes Objekt zeichnet sich durch eine Anker-Pos
+ // von (0,1) aus. Das ist ein shabby Trick, der aber funktioniert!
+ Point aAnchor( 0, eType == SCA_PAGE ? 1 : 0 );
+ pObj->SetAnchorPos( aAnchor );
+
+ if ( eOldAnchorType != eType )
+ pObj->notifyShapePropertyChange( ::svx::eSpreadsheetAnchor );
+}
+
+ScAnchorType ScDrawLayer::GetAnchor( const SdrObject* pObj )
+{
+ Point aAnchor( pObj->GetAnchorPos() );
+ return ( aAnchor.Y() != 0 ) ? SCA_PAGE : SCA_CELL;
+}
+
+ScDrawObjData* ScDrawLayer::GetObjData( SdrObject* pObj, BOOL bCreate ) // static
+{
+ USHORT nCount = pObj ? pObj->GetUserDataCount() : 0;
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ SdrObjUserData* pData = pObj->GetUserData( i );
+ if( pData && pData->GetInventor() == SC_DRAWLAYER
+ && pData->GetId() == SC_UD_OBJDATA )
+ return (ScDrawObjData*) pData;
+ }
+ if( pObj && bCreate )
+ {
+ ScDrawObjData* pData = new ScDrawObjData;
+ pObj->InsertUserData( pData, 0 );
+ return pData;
+ }
+ return 0;
+}
+
+ScDrawObjData* ScDrawLayer::GetObjDataTab( SdrObject* pObj, SCTAB nTab ) // static
+{
+ ScDrawObjData* pData = GetObjData( pObj );
+ if ( pData )
+ {
+ if ( pData->maStart.IsValid() )
+ pData->maStart.SetTab( nTab );
+ if ( pData->maEnd.IsValid() )
+ pData->maEnd.SetTab( nTab );
+ }
+ return pData;
+}
+
+bool ScDrawLayer::IsNoteCaption( SdrObject* pObj )
+{
+ ScDrawObjData* pData = pObj ? GetObjData( pObj ) : 0;
+ return pData && pData->mbNote;
+}
+
+ScDrawObjData* ScDrawLayer::GetNoteCaptionData( SdrObject* pObj, SCTAB nTab )
+{
+ ScDrawObjData* pData = pObj ? GetObjDataTab( pObj, nTab ) : 0;
+ return (pData && pData->mbNote) ? pData : 0;
+}
+
+ScIMapInfo* ScDrawLayer::GetIMapInfo( SdrObject* pObj ) // static
+{
+ USHORT nCount = pObj->GetUserDataCount();
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ SdrObjUserData* pData = pObj->GetUserData( i );
+ if( pData && pData->GetInventor() == SC_DRAWLAYER
+ && pData->GetId() == SC_UD_IMAPDATA )
+ return (ScIMapInfo*) pData;
+ }
+ return NULL;
+}
+
+// static:
+IMapObject* ScDrawLayer::GetHitIMapObject( SdrObject* pObj,
+ const Point& rWinPoint, const Window& rCmpWnd )
+{
+ const MapMode aMap100( MAP_100TH_MM );
+ MapMode aWndMode = rCmpWnd.GetMapMode();
+ Point aRelPoint( rCmpWnd.LogicToLogic( rWinPoint, &aWndMode, &aMap100 ) );
+ Rectangle aLogRect = rCmpWnd.LogicToLogic( pObj->GetLogicRect(), &aWndMode, &aMap100 );
+ ScIMapInfo* pIMapInfo = GetIMapInfo( pObj );
+ IMapObject* pIMapObj = NULL;
+
+ if ( pIMapInfo )
+ {
+ Size aGraphSize;
+ ImageMap& rImageMap = (ImageMap&) pIMapInfo->GetImageMap();
+ Graphic aGraphic;
+ BOOL bObjSupported = FALSE;
+
+ if ( pObj->ISA( SdrGrafObj ) ) // einfaches Grafik-Objekt
+ {
+ const SdrGrafObj* pGrafObj = (const SdrGrafObj*) pObj;
+ const GeoStat& rGeo = pGrafObj->GetGeoStat();
+ const Graphic& rGraphic = pGrafObj->GetGraphic();
+
+ // Drehung rueckgaengig
+ if ( rGeo.nDrehWink )
+ RotatePoint( aRelPoint, aLogRect.TopLeft(), -rGeo.nSin, rGeo.nCos );
+
+ // Spiegelung rueckgaengig
+ if ( ( (const SdrGrafObjGeoData*) pGrafObj->GetGeoData() )->bMirrored )
+ aRelPoint.X() = aLogRect.Right() + aLogRect.Left() - aRelPoint.X();
+
+ // ggf. Unshear:
+ if ( rGeo.nShearWink )
+ ShearPoint( aRelPoint, aLogRect.TopLeft(), -rGeo.nTan );
+
+
+ if ( rGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
+ aGraphSize = rCmpWnd.PixelToLogic( rGraphic.GetPrefSize(),
+ aMap100 );
+ else
+ aGraphSize = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(),
+ rGraphic.GetPrefMapMode(),
+ aMap100 );
+
+ bObjSupported = TRUE;
+ }
+ else if ( pObj->ISA( SdrOle2Obj ) ) // OLE-Objekt
+ {
+ // TODO/LEAN: working with visual area needs running state
+ aGraphSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize();
+ bObjSupported = TRUE;
+ }
+
+ // hat alles geklappt, dann HitTest ausfuehren
+ if ( bObjSupported )
+ {
+ // relativen Mauspunkt berechnen
+ aRelPoint -= aLogRect.TopLeft();
+ pIMapObj = rImageMap.GetHitIMapObject( aGraphSize, aLogRect.GetSize(), aRelPoint );
+ }
+ }
+
+ return pIMapObj;
+}
+
+ScMacroInfo* ScDrawLayer::GetMacroInfo( SdrObject* pObj, BOOL bCreate ) // static
+{
+ USHORT nCount = pObj->GetUserDataCount();
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ SdrObjUserData* pData = pObj->GetUserData( i );
+ if( pData && pData->GetInventor() == SC_DRAWLAYER
+ && pData->GetId() == SC_UD_MACRODATA )
+ return (ScMacroInfo*) pData;
+ }
+ if ( bCreate )
+ {
+ ScMacroInfo* pData = new ScMacroInfo;
+ pObj->InsertUserData( pData, 0 );
+ return pData;
+ }
+ return 0;
+}
+
+void ScDrawLayer::SetGlobalDrawPersist(SfxObjectShell* pPersist) // static
+{
+ DBG_ASSERT(!pGlobalDrawPersist,"SetGlobalDrawPersist mehrfach");
+ pGlobalDrawPersist = pPersist;
+}
+
+void __EXPORT ScDrawLayer::SetChanged( sal_Bool bFlg /* = sal_True */ )
+{
+ if ( bFlg && pDoc )
+ pDoc->SetChartListenerCollectionNeedsUpdate( TRUE );
+ FmFormModel::SetChanged( bFlg );
+}
+
+SvStream* __EXPORT ScDrawLayer::GetDocumentStream(SdrDocumentStreamInfo& rStreamInfo) const
+{
+ DBG_ASSERT( pDoc, "ScDrawLayer::GetDocumentStream without document" );
+ if ( !pDoc )
+ return NULL;
+
+ uno::Reference< embed::XStorage > xStorage = pDoc->GetDocumentShell() ?
+ pDoc->GetDocumentShell()->GetStorage() :
+ NULL;
+ SvStream* pRet = NULL;
+
+ if( xStorage.is() )
+ {
+ if( rStreamInfo.maUserData.Len() &&
+ ( rStreamInfo.maUserData.GetToken( 0, ':' ) ==
+ String( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package" ) ) ) )
+ {
+ const String aPicturePath( rStreamInfo.maUserData.GetToken( 1, ':' ) );
+
+ // graphic from picture stream in picture storage in XML package
+ if( aPicturePath.GetTokenCount( '/' ) == 2 )
+ {
+ const String aPictureStreamName( aPicturePath.GetToken( 1, '/' ) );
+ const String aPictureStorageName( aPicturePath.GetToken( 0, '/' ) );
+
+ try {
+ if ( xStorage->isStorageElement( aPictureStorageName ) )
+ {
+ uno::Reference< embed::XStorage > xPictureStorage =
+ xStorage->openStorageElement( aPictureStorageName, embed::ElementModes::READ );
+
+ if( xPictureStorage.is() &&
+ xPictureStorage->isStreamElement( aPictureStreamName ) )
+ {
+ uno::Reference< io::XStream > xStream =
+ xPictureStorage->openStreamElement( aPictureStreamName, embed::ElementModes::READ );
+ if ( xStream.is() )
+ pRet = ::utl::UcbStreamHelper::CreateStream( xStream );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+ }
+ }
+ // the following code seems to be related to binary format
+//REMOVE else
+//REMOVE {
+//REMOVE pRet = pStor->OpenStream( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STRING_SCSTREAM)),
+//REMOVE STREAM_READ | STREAM_WRITE | STREAM_TRUNC );
+//REMOVE
+//REMOVE if( pRet )
+//REMOVE {
+//REMOVE pRet->SetVersion( pStor->GetVersion() );
+//REMOVE pRet->SetKey( pStor->GetKey() );
+//REMOVE }
+//REMOVE }
+
+ rStreamInfo.mbDeleteAfterUse = ( pRet != NULL );
+ }
+
+ return pRet;
+}
+
+//REMOVE void ScDrawLayer::ReleasePictureStorage()
+//REMOVE {
+//REMOVE xPictureStorage.Clear();
+//REMOVE }
+
+SdrLayerID __EXPORT ScDrawLayer::GetControlExportLayerId( const SdrObject & ) const
+{
+ // Layer fuer Export von Form-Controls in Versionen vor 5.0 - immer SC_LAYER_FRONT
+ return SC_LAYER_FRONT;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > ScDrawLayer::createUnoModel()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRet;
+ if( pDoc && pDoc->GetDocumentShell() )
+ xRet = pDoc->GetDocumentShell()->GetModel();
+
+ return xRet;
+}
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
new file mode 100644
index 000000000000..99da4979a1b6
--- /dev/null
+++ b/sc/source/core/data/fillinfo.cxx
@@ -0,0 +1,1079 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/editdata.hxx> // can be removed if table has a bLayoutRTL flag
+#include <editeng/shaditem.hxx>
+
+#include "fillinfo.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "table.hxx"
+#include "attrib.hxx"
+#include "attarray.hxx"
+#include "markarr.hxx"
+#include "markdata.hxx"
+#include "patattr.hxx"
+#include "poolhelp.hxx"
+#include "docpool.hxx"
+#include "conditio.hxx"
+#include "stlpool.hxx"
+
+// -----------------------------------------------------------------------
+
+const USHORT ROWINFO_MAX = 1024;
+
+
+enum FillInfoLinePos
+ {
+ FILP_TOP,
+ FILP_BOTTOM,
+ FILP_LEFT,
+ FILP_RIGHT
+ };
+
+
+inline const SvxBorderLine* GetNullOrLine( const SvxBoxItem* pBox, FillInfoLinePos eWhich )
+{
+ if (pBox)
+ {
+ if (eWhich==FILP_TOP)
+ return pBox->GetTop();
+ else if (eWhich==FILP_BOTTOM)
+ return pBox->GetBottom();
+ else if (eWhich==FILP_LEFT)
+ return pBox->GetLeft();
+ else
+ return pBox->GetRight();
+ }
+ else
+ return NULL;
+}
+
+// aehnlich wie in output.cxx
+
+void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
+ ScDocument* pDoc, RowInfo* pRowInfo,
+ SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab,
+ SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY )
+{
+ CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
+
+ rStartX = nX;
+ rStartY = nY;
+ BOOL bHOver = pInfo->bHOverlapped;
+ BOOL bVOver = pInfo->bVOverlapped;
+ SCCOL nLastCol;
+ SCROW nLastRow;
+
+ while (bHOver) // nY konstant
+ {
+ --rStartX;
+ if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, nLastCol))
+ {
+ bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
+ bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
+ }
+ else
+ {
+ USHORT nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ bHOver = ((nOverlap & SC_MF_HOR) != 0);
+ bVOver = ((nOverlap & SC_MF_VER) != 0);
+ }
+ }
+
+ while (bVOver)
+ {
+ --rStartY;
+
+ if (nArrY>0)
+ --nArrY; // lokale Kopie !
+
+ if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
+ !pDoc->ColHidden(rStartX, nTab, nLastCol) &&
+ !pDoc->RowHidden(rStartY, nTab, nLastRow) &&
+ (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
+ {
+ bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
+ bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
+ }
+ else
+ {
+ USHORT nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ bHOver = ((nOverlap & SC_MF_HOR) != 0);
+ bVOver = ((nOverlap & SC_MF_VER) != 0);
+ }
+ }
+
+ const ScMergeAttr* pMerge;
+ if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
+ !pDoc->ColHidden(rStartX, nTab, nLastCol) &&
+ !pDoc->RowHidden(rStartY, nTab, nLastRow) &&
+ (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
+ {
+ pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
+ GetItem(ATTR_MERGE);
+ }
+ else
+ pMerge = (const ScMergeAttr*) pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE);
+
+ rEndX = rStartX + pMerge->GetColMerge() - 1;
+ rEndY = rStartY + pMerge->GetRowMerge() - 1;
+}
+
+#define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x]
+
+void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ SCTAB nTab, double nScaleX, double nScaleY,
+ BOOL bPageMode, BOOL bFormulaMode, const ScMarkData* pMarkData )
+{
+ DBG_ASSERT( pTab[nTab], "Tabelle existiert nicht" );
+
+ BOOL bLayoutRTL = IsLayoutRTL( nTab );
+
+ ScDocumentPool* pPool = xPoolHelper->GetDocPool();
+ ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
+
+ RowInfo* pRowInfo = rTabInfo.mpRowInfo;
+
+ const SvxBrushItem* pDefBackground =
+ (const SvxBrushItem*) &pPool->GetDefaultItem( ATTR_BACKGROUND );
+ const ScMergeAttr* pDefMerge =
+ (const ScMergeAttr*) &pPool->GetDefaultItem( ATTR_MERGE );
+ const SvxShadowItem* pDefShadow =
+ (const SvxShadowItem*) &pPool->GetDefaultItem( ATTR_SHADOW );
+
+ SCROW nThisRow;
+ SCCOL nX;
+ SCROW nY;
+ SCsROW nSignedY;
+ SCCOL nArrX;
+ SCSIZE nArrY;
+ SCSIZE nArrCount;
+ BOOL bAnyMerged = FALSE;
+ BOOL bAnyShadow = FALSE;
+ BOOL bAnyCondition = FALSE;
+
+ BOOL bTabProtect = IsTabProtected(nTab);
+
+ // fuer Blockmarken von zusammengefassten Zellen mit
+ // versteckter erster Zeile / Spalte
+ BOOL bPaintMarks = FALSE;
+ BOOL bSkipMarks = FALSE;
+ SCCOL nBlockStartX = 0, nBlockEndX = 0;
+ SCROW nBlockEndY = 0, nBlockStartY = 0;
+ if (pMarkData && pMarkData->IsMarked())
+ {
+ ScRange aTmpRange;
+ pMarkData->GetMarkArea(aTmpRange);
+ if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
+ {
+ nBlockStartX = aTmpRange.aStart.Col();
+ nBlockStartY = aTmpRange.aStart.Row();
+ nBlockEndX = aTmpRange.aEnd.Col();
+ nBlockEndY = aTmpRange.aEnd.Row();
+ ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab ); //? noetig ?
+ if (pMarkData->IsMarkNegative())
+ bSkipMarks = TRUE;
+ else
+ bPaintMarks = TRUE;
+ }
+ }
+
+ // zuerst nur die Eintraege fuer die ganze Spalte
+
+ nArrY=0;
+ SCROW nYExtra = nY2+1;
+ USHORT nDocHeight = ScGlobal::nStdRowHeight;
+ SCROW nDocHeightEndRow = -1;
+ for (nSignedY=((SCsROW)nY1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
+ {
+ if (nSignedY >= 0)
+ nY = (SCROW) nSignedY;
+ else
+ nY = MAXROW+1; // ungueltig
+
+ if (nY > nDocHeightEndRow)
+ {
+ if (ValidRow(nY))
+ nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
+ else
+ nDocHeight = ScGlobal::nStdRowHeight;
+ }
+
+ if ( nArrY==0 || nDocHeight || nY > MAXROW )
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ pThisRowInfo->pCellInfo = NULL; // wird unten belegt
+
+ USHORT nHeight = (USHORT) ( nDocHeight * nScaleY );
+ if (!nHeight)
+ nHeight = 1;
+
+ pThisRowInfo->nRowNo = nY; //! Fall < 0 ?
+ pThisRowInfo->nHeight = nHeight;
+ pThisRowInfo->bEmptyBack = TRUE;
+ pThisRowInfo->bEmptyText = TRUE;
+ pThisRowInfo->bChanged = TRUE;
+ pThisRowInfo->bAutoFilter = FALSE;
+ pThisRowInfo->bPushButton = FALSE;
+ pThisRowInfo->nRotMaxCol = SC_ROTMAX_NONE;
+
+ ++nArrY;
+ if (nArrY >= ROWINFO_MAX)
+ {
+ DBG_ERROR("Zu grosser Bereich bei FillInfo" );
+ nYExtra = nSignedY; // Ende
+ nY2 = nYExtra - 1; // Bereich anpassen
+ }
+ }
+ else
+ if (nSignedY==(SCsROW) nYExtra) // zusaetzliche Zeile verdeckt ?
+ ++nYExtra;
+ }
+ nArrCount = nArrY; // incl. Dummys
+
+ // rotierter Text...
+
+ // Attribut im Dokument ueberhaupt verwendet?
+ BOOL bAnyItem = FALSE;
+ USHORT nRotCount = pPool->GetItemCount( ATTR_ROTATE_VALUE );
+ for (USHORT nItem=0; nItem<nRotCount; nItem++)
+ if (pPool->GetItem( ATTR_ROTATE_VALUE, nItem ))
+ {
+ bAnyItem = TRUE;
+ break;
+ }
+
+ SCCOL nRotMax = nX2;
+ if ( bAnyItem && HasAttrib( 0,nY1,nTab, MAXCOL,nY2+1,nTab,
+ HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
+ {
+ //! Conditionals auch bei HASATTR_ROTATE abfragen ????
+
+ DBG_ASSERT( nArrCount>2, "nArrCount zu klein" );
+// FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-2, nX1, nX2 );
+ FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nX1, nX2 );
+ // FindMaxRotCol setzt nRotMaxCol
+
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ if (pRowInfo[nArrY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nArrY].nRotMaxCol;
+ }
+
+ // Zell-Infos erst nach dem Test auf gedrehte allozieren
+ // bis nRotMax wegen nRotateDir Flag
+
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ nY = pThisRowInfo->nRowNo;
+ pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ]; // vom Aufrufer zu loeschen !
+
+ for (nArrX=0; nArrX<=nRotMax+2; nArrX++) // Zell-Infos vorbelegen
+ {
+ if (nArrX>0)
+ nX = nArrX-1;
+ else
+ nX = MAXCOL+1; // ungueltig
+
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
+ pInfo->bEmptyCellText = TRUE;
+ pInfo->pCell = NULL;
+ if (bPaintMarks)
+ pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
+ && nY >= nBlockStartY && nY <= nBlockEndY );
+ else
+ pInfo->bMarked = FALSE;
+ pInfo->nWidth = 0;
+
+ pInfo->nClipMark = SC_CLIPMARK_NONE;
+ pInfo->bMerged = FALSE;
+ pInfo->bHOverlapped = FALSE;
+ pInfo->bVOverlapped = FALSE;
+ pInfo->bAutoFilter = FALSE;
+ pInfo->bPushButton = FALSE;
+ pInfo->bPopupButton = false;
+ pInfo->bFilterActive = false;
+ pInfo->nRotateDir = SC_ROTDIR_NONE;
+
+ pInfo->bPrinted = FALSE; // view-intern
+ pInfo->bHideGrid = FALSE; // view-intern
+ pInfo->bEditEngine = FALSE; // view-intern
+
+ pInfo->pBackground = NULL; //! weglassen?
+ pInfo->pPatternAttr = NULL;
+ pInfo->pConditionSet= NULL;
+
+ pInfo->pLinesAttr = NULL;
+ pInfo->mpTLBRLine = NULL;
+ pInfo->mpBLTRLine = NULL;
+
+ pInfo->pShadowAttr = pDefShadow;
+ pInfo->pHShadowOrigin = NULL;
+ pInfo->pVShadowOrigin = NULL;
+ }
+ }
+
+ for (nArrX=nX2+3; nArrX<=nRotMax+2; nArrX++) // restliche Breiten eintragen
+ {
+ nX = nArrX-1;
+ if ( ValidCol(nX) )
+ {
+ if (!ColHidden(nX, nTab))
+ {
+ USHORT nThisWidth = (USHORT) (GetColWidth( nX, nTab ) * nScaleX);
+ if (!nThisWidth)
+ nThisWidth = 1;
+
+ pRowInfo[0].pCellInfo[nArrX].nWidth = nThisWidth;
+ }
+ }
+ }
+
+ for (nArrX=0; nArrX<=nX2+2; nArrX++) // links & rechts + 1
+ {
+ nX = (nArrX>0) ? nArrX-1 : MAXCOL+1; // negativ -> ungueltig
+
+ if ( ValidCol(nX) )
+ {
+ // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
+ // will disturb the output
+
+ // TODO: Optimize this loop.
+ if (!ColHidden(nX, nTab))
+ {
+ USHORT nThisWidth = (USHORT) (GetColWidth( nX, nTab ) * nScaleX);
+ if (!nThisWidth)
+ nThisWidth = 1;
+
+ pRowInfo[0].pCellInfo[nArrX].nWidth = nThisWidth; //! dies sollte reichen
+
+ ScColumn* pThisCol = &pTab[nTab]->aCol[nX]; // Spalten-Daten
+
+ nArrY = 1;
+ SCSIZE nUIndex;
+ bool bHiddenRow = true;
+ SCROW nHiddenEndRow = -1;
+ (void) pThisCol->Search( nY1, nUIndex );
+ while ( nUIndex < pThisCol->nCount &&
+ (nThisRow=pThisCol->pItems[nUIndex].nRow) <= nY2 )
+ {
+ if (nThisRow > nHiddenEndRow)
+ bHiddenRow = RowHidden( nThisRow, nTab, nHiddenEndRow);
+ if ( !bHiddenRow )
+ {
+ while ( pRowInfo[nArrY].nRowNo < nThisRow )
+ ++nArrY;
+ DBG_ASSERT( pRowInfo[nArrY].nRowNo == nThisRow, "Zeile nicht gefunden in FillInfo" );
+
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
+ pInfo->pCell = pThisCol->pItems[nUIndex].pCell;
+ if (pInfo->pCell->GetCellType() != CELLTYPE_NOTE)
+ {
+ pThisRowInfo->bEmptyText = FALSE; // Zeile nicht leer
+ pInfo->bEmptyCellText = FALSE; // Zelle nicht leer
+ }
+ ++nArrY;
+ }
+ ++nUIndex;
+ }
+
+ if (nX+1 >= nX1) // Attribute/Blockmarken ab nX1-1
+ {
+ ScAttrArray* pThisAttrArr = pThisCol->pAttrArray; // Attribute
+
+ nArrY = 0;
+ const ScPatternAttr* pPattern;
+ SCROW nCurRow=nY1; // einzelne Zeile
+ if (nCurRow>0)
+ --nCurRow; // oben 1 mehr
+ else
+ nArrY = 1;
+ nThisRow=nCurRow; // Ende des Bereichs
+ SCSIZE nIndex;
+ (void) pThisAttrArr->Search( nCurRow, nIndex );
+
+
+ do
+ {
+ nThisRow=pThisAttrArr->pData[nIndex].nRow; // Ende des Bereichs
+ pPattern=pThisAttrArr->pData[nIndex].pPattern;
+
+ const SvxBrushItem* pBackground = (const SvxBrushItem*)
+ &pPattern->GetItem(ATTR_BACKGROUND);
+ const SvxBoxItem* pLinesAttr = (const SvxBoxItem*)
+ &pPattern->GetItem(ATTR_BORDER);
+
+ const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
+ &pPattern->GetItem( ATTR_BORDER_TLBR ) );
+ const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
+ &pPattern->GetItem( ATTR_BORDER_BLTR ) );
+
+ const SvxShadowItem* pShadowAttr = (const SvxShadowItem*)
+ &pPattern->GetItem(ATTR_SHADOW);
+ if (pShadowAttr != pDefShadow)
+ bAnyShadow = TRUE;
+
+ const ScMergeAttr* pMergeAttr = (const ScMergeAttr*)
+ &pPattern->GetItem(ATTR_MERGE);
+ BOOL bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
+ USHORT nOverlap = ((const ScMergeFlagAttr*) &pPattern->GetItemSet().
+ Get(ATTR_MERGE_FLAG))->GetValue();
+ BOOL bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
+ BOOL bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
+ BOOL bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
+ BOOL bPushButton = ((nOverlap & SC_MF_BUTTON) != 0);
+ BOOL bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
+ bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
+ bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
+ if (bMerged||bHOverlapped||bVOverlapped)
+ bAnyMerged = TRUE; // intern
+
+ BOOL bHidden, bHideFormula;
+ if (bTabProtect)
+ {
+ const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)
+ pPattern->GetItem(ATTR_PROTECTION);
+ bHidden = rProtAttr.GetHideCell();
+ bHideFormula = rProtAttr.GetHideFormula();
+ }
+ else
+ bHidden = bHideFormula = FALSE;
+
+ ULONG nConditional = ((const SfxUInt32Item&)pPattern->
+ GetItem(ATTR_CONDITIONAL)).GetValue();
+ const ScConditionalFormat* pCondForm = NULL;
+ if ( nConditional && pCondFormList )
+ pCondForm = pCondFormList->GetFormat( nConditional );
+
+ do
+ {
+ SCROW nLastHiddenRow = -1;
+ bool bRowHidden = RowHidden(nCurRow, nTab, nLastHiddenRow);
+ if ( nArrY==0 || !bRowHidden )
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if (pBackground != pDefBackground) // Spalten-HG == Standard ?
+ pThisRowInfo->bEmptyBack = FALSE;
+ if (bAutoFilter)
+ pThisRowInfo->bAutoFilter = TRUE;
+ if (bPushButton)
+ pThisRowInfo->bPushButton = TRUE;
+
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
+ pInfo->pBackground = pBackground;
+ pInfo->pPatternAttr = pPattern;
+ pInfo->bMerged = bMerged;
+ pInfo->bHOverlapped = bHOverlapped;
+ pInfo->bVOverlapped = bVOverlapped;
+ pInfo->bAutoFilter = bAutoFilter;
+ pInfo->bPushButton = bPushButton;
+ pInfo->bPopupButton = bPopupButton;
+ pInfo->bFilterActive = bFilterActive;
+ pInfo->pLinesAttr = pLinesAttr;
+ pInfo->mpTLBRLine = pTLBRLine;
+ pInfo->mpBLTRLine = pBLTRLine;
+ pInfo->pShadowAttr = pShadowAttr;
+ // nWidth wird nicht mehr einzeln gesetzt
+
+ BOOL bEmbed = FALSE; //bIsEmbedded &&
+ nTab >= aEmbedRange.aStart.Tab() &&
+ nTab <= aEmbedRange.aEnd.Tab() &&
+ nX >= aEmbedRange.aStart.Col() &&
+ nX <= aEmbedRange.aEnd.Col() &&
+ nCurRow >= aEmbedRange.aStart.Row() &&
+ nCurRow <= aEmbedRange.aEnd.Row();
+
+ if (bScenario)
+ {
+ pInfo->pBackground = ScGlobal::GetButtonBrushItem();
+ pThisRowInfo->bEmptyBack = FALSE;
+ }
+ else if (bEmbed)
+ {
+ pInfo->pBackground = ScGlobal::GetEmbeddedBrushItem();
+ pThisRowInfo->bEmptyBack = FALSE;
+ }
+
+ if (bHidden || ( bFormulaMode && bHideFormula && pInfo->pCell
+ && pInfo->pCell->GetCellType()
+ == CELLTYPE_FORMULA ))
+ pInfo->bEmptyCellText = TRUE;
+
+ if ( pCondForm )
+ {
+ String aStyle = pCondForm->GetCellStyle( pInfo->pCell,
+ ScAddress( nX, nCurRow, nTab ) );
+ if (aStyle.Len())
+ {
+ SfxStyleSheetBase* pStyleSheet =
+ pStlPool->Find( aStyle, SFX_STYLE_FAMILY_PARA );
+ if ( pStyleSheet )
+ {
+ //! Style-Sets cachen !!!
+ pInfo->pConditionSet = &pStyleSheet->GetItemSet();
+ bAnyCondition = TRUE;
+ }
+ // if style is not there, treat like no condition
+ }
+ }
+
+ ++nArrY;
+ }
+ else if (bRowHidden && nLastHiddenRow >= 0)
+ {
+ nCurRow = nLastHiddenRow;
+ if (nCurRow > nThisRow)
+ nCurRow = nThisRow;
+ }
+ ++nCurRow;
+ }
+ while (nCurRow <= nThisRow && nCurRow <= nYExtra);
+ ++nIndex;
+ }
+ while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
+
+
+ if (pMarkData && pMarkData->IsMultiMarked())
+ {
+ // Blockmarken
+ const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
+ BOOL bThisMarked;
+ nArrY = 1;
+ nCurRow = nY1; // einzelne Zeile
+ nThisRow = nY1; // Ende des Bereichs
+
+ if ( pThisMarkArr->Search( nY1, nIndex ) )
+ {
+ do
+ {
+ nThisRow=pThisMarkArr->pData[nIndex].nRow; // Ende des Bereichs
+ bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
+
+ do
+ {
+ if ( !RowHidden( nCurRow,nTab ) )
+ {
+ if ( bThisMarked )
+ {
+ BOOL bSkip = bSkipMarks &&
+ nX >= nBlockStartX &&
+ nX <= nBlockEndX &&
+ nCurRow >= nBlockStartY &&
+ nCurRow <= nBlockEndY;
+ if (!bSkip)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
+ pInfo->bMarked = TRUE;
+ }
+ }
+ ++nArrY;
+ }
+ ++nCurRow;
+ }
+ while (nCurRow <= nThisRow && nCurRow <= nY2);
+ ++nIndex;
+ }
+ while ( nIndex < pThisMarkArr->nCount && nThisRow < nY2 );
+ }
+ }
+ }
+ else // vordere Spalten
+ {
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
+
+ pInfo->nWidth = nThisWidth; //! oder nur 0 abfragen ??
+ }
+ }
+ }
+ }
+ else
+ pRowInfo[0].pCellInfo[nArrX].nWidth = STD_COL_WIDTH;
+ // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
+ }
+
+ //-------------------------------------------------------------------------
+ // bedingte Formatierung auswerten
+
+ if (bAnyCondition)
+ {
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr
+ {
+ CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nArrX];
+ const SfxItemSet* pCondSet = pInfo->pConditionSet;
+ if (pCondSet)
+ {
+ const SfxPoolItem* pItem;
+
+ // Hintergrund
+ if ( pCondSet->GetItemState( ATTR_BACKGROUND, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ pInfo->pBackground = (const SvxBrushItem*) pItem;
+ pRowInfo[nArrY].bEmptyBack = FALSE;
+ }
+
+ // Umrandung
+ if ( pCondSet->GetItemState( ATTR_BORDER, TRUE, &pItem ) == SFX_ITEM_SET )
+ pInfo->pLinesAttr = (const SvxBoxItem*) pItem;
+
+ if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, TRUE, &pItem ) == SFX_ITEM_SET )
+ pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
+ if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, TRUE, &pItem ) == SFX_ITEM_SET )
+ pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
+
+ // Schatten
+ if ( pCondSet->GetItemState( ATTR_SHADOW, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
+ bAnyShadow = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ // bedingte Formatierung Ende
+ //-------------------------------------------------------------------------
+
+ //
+ // Daten von zusammengefassten Zellen anpassen
+ //
+
+ if (bAnyMerged)
+ {
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ nSignedY = nArrY ? pThisRowInfo->nRowNo : ((SCsROW)nY1)-1;
+
+ for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr
+ {
+ SCsCOL nSignedX = ((SCsCOL) nArrX) - 1;
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
+
+ if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
+ {
+ SCsCOL nStartX;
+ SCsROW nStartY;
+ SCsCOL nEndX;
+ SCsROW nEndY;
+ lcl_GetMergeRange( nSignedX,nSignedY, nArrY, this,pRowInfo, nX1,nY1,nX2,nY2,nTab,
+ nStartX,nStartY, nEndX,nEndY );
+ const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
+ const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
+ const SfxPoolItem* pItem;
+
+ // Hintergrund kopieren (oder in output.cxx)
+
+ if ( !pStartCond || pStartCond->
+ GetItemState(ATTR_BACKGROUND,TRUE,&pItem) != SFX_ITEM_SET )
+ pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
+ pInfo->pBackground = (const SvxBrushItem*) pItem;
+ pRowInfo[nArrY].bEmptyBack = FALSE;
+
+ // Schatten
+
+ if ( !pStartCond || pStartCond->
+ GetItemState(ATTR_SHADOW,TRUE,&pItem) != SFX_ITEM_SET )
+ pItem = &pStartPattern->GetItem(ATTR_SHADOW);
+ pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
+ if (pInfo->pShadowAttr != pDefShadow)
+ bAnyShadow = TRUE;
+
+ // Blockmarken - wieder mit Original-Merge-Werten
+
+ BOOL bCellMarked = FALSE;
+ if (bPaintMarks)
+ bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
+ && nStartX <= (SCsCOL) nBlockEndX
+ && nStartY >= (SCsROW) nBlockStartY
+ && nStartY <= (SCsROW) nBlockEndY );
+ if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
+ {
+ const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
+ SCSIZE nIndex;
+ if ( pThisMarkArr->Search( nStartY, nIndex ) )
+ bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
+ }
+
+ pInfo->bMarked = bCellMarked;
+ }
+ }
+ }
+ }
+
+ if (bAnyShadow) // Schatten verteilen
+ {
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ BOOL bTop = ( nArrY == 0 );
+ BOOL bBottom = ( nArrY+1 == nArrCount );
+
+ for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr
+ {
+ BOOL bLeft = ( nArrX == nX1 );
+ BOOL bRight = ( nArrX == nX2+2 );
+
+ CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nArrX];
+ const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
+ SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
+ if (eLoc != SVX_SHADOW_NONE)
+ {
+ // oder Test auf != eLoc
+
+ SCsCOL nDxPos = 1;
+ SCsCOL nDxNeg = -1;
+
+ while ( nArrX+nDxPos < nX2+2 && pRowInfo[0].pCellInfo[nArrX+nDxPos].nWidth == 0 )
+ ++nDxPos;
+ while ( nArrX+nDxNeg > nX1 && pRowInfo[0].pCellInfo[nArrX+nDxNeg].nWidth == 0 )
+ --nDxNeg;
+
+ BOOL bLeftDiff = !bLeft &&
+ CELLINFO(nDxNeg,0).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
+ BOOL bRightDiff = !bRight &&
+ CELLINFO(nDxPos,0).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
+ BOOL bTopDiff = !bTop &&
+ CELLINFO(0,-1).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
+ BOOL bBottomDiff = !bBottom &&
+ CELLINFO(0,1).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
+
+ if ( bLayoutRTL )
+ {
+ switch (eLoc)
+ {
+ case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
+ case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
+ case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break;
+ case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ switch (eLoc)
+ {
+ case SVX_SHADOW_BOTTOMRIGHT:
+ if (bBottomDiff)
+ {
+ CELLINFO(0,1).pHShadowOrigin = pThisAttr;
+ CELLINFO(0,1).eHShadowPart =
+ bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
+ }
+ if (bRightDiff)
+ {
+ CELLINFO(1,0).pVShadowOrigin = pThisAttr;
+ CELLINFO(1,0).eVShadowPart =
+ bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
+ }
+ if (bBottomDiff && bRightDiff)
+ {
+ CELLINFO(1,1).pHShadowOrigin = pThisAttr;
+ CELLINFO(1,1).eHShadowPart = SC_SHADOW_CORNER;
+ }
+ break;
+
+ case SVX_SHADOW_BOTTOMLEFT:
+ if (bBottomDiff)
+ {
+ CELLINFO(0,1).pHShadowOrigin = pThisAttr;
+ CELLINFO(0,1).eHShadowPart =
+ bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
+ }
+ if (bLeftDiff)
+ {
+ CELLINFO(-1,0).pVShadowOrigin = pThisAttr;
+ CELLINFO(-1,0).eVShadowPart =
+ bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
+ }
+ if (bBottomDiff && bLeftDiff)
+ {
+ CELLINFO(-1,1).pHShadowOrigin = pThisAttr;
+ CELLINFO(-1,1).eHShadowPart = SC_SHADOW_CORNER;
+ }
+ break;
+
+ case SVX_SHADOW_TOPRIGHT:
+ if (bTopDiff)
+ {
+ CELLINFO(0,-1).pHShadowOrigin = pThisAttr;
+ CELLINFO(0,-1).eHShadowPart =
+ bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
+ }
+ if (bRightDiff)
+ {
+ CELLINFO(1,0).pVShadowOrigin = pThisAttr;
+ CELLINFO(1,0).eVShadowPart =
+ bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
+ }
+ if (bTopDiff && bRightDiff)
+ {
+ CELLINFO(1,-1).pHShadowOrigin = pThisAttr;
+ CELLINFO(1,-1).eHShadowPart = SC_SHADOW_CORNER;
+ }
+ break;
+
+ case SVX_SHADOW_TOPLEFT:
+ if (bTopDiff)
+ {
+ CELLINFO(0,-1).pHShadowOrigin = pThisAttr;
+ CELLINFO(0,-1).eHShadowPart =
+ bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
+ }
+ if (bLeftDiff)
+ {
+ CELLINFO(-1,0).pVShadowOrigin = pThisAttr;
+ CELLINFO(-1,0).eVShadowPart =
+ bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
+ }
+ if (bTopDiff && bLeftDiff)
+ {
+ CELLINFO(-1,-1).pHShadowOrigin = pThisAttr;
+ CELLINFO(-1,-1).eHShadowPart = SC_SHADOW_CORNER;
+ }
+ break;
+
+ default:
+ DBG_ERROR("falscher Shadow-Enum");
+ }
+ }
+ }
+ }
+ }
+
+ rTabInfo.mnArrCount = sal::static_int_cast<USHORT>(nArrCount);
+ rTabInfo.mbPageMode = bPageMode;
+
+ // ========================================================================
+ // *** create the frame border array ***
+
+ // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
+ // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
+
+ size_t nColCount = nX2 - nX1 + 3;
+ size_t nRowCount = nArrCount;
+
+ svx::frame::Array& rArray = rTabInfo.maArray;
+ rArray.Initialize( nColCount, nRowCount );
+ rArray.SetUseDiagDoubleClipping( false );
+
+ for( size_t nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ USHORT nCellInfoY = static_cast< USHORT >( nRow );
+ RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
+
+ for( size_t nCol = 0; nCol < nColCount; ++nCol )
+ {
+ USHORT nCellInfoX = static_cast< USHORT >( nCol + nX1 );
+ const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
+
+ const SvxBoxItem* pBox = rInfo.pLinesAttr;
+ const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
+ const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
+
+ size_t nFirstCol = nCol;
+ size_t nFirstRow = nRow;
+
+ // *** merged cells *** -------------------------------------------
+
+ if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
+ {
+ // *** insert merged range in svx::frame::Array ***
+
+ /* #i69369# top-left cell of a merged range may be located in
+ a hidden column or row. Use lcl_GetMergeRange() to find the
+ complete merged range, then calculate dimensions and
+ document position of the visible range. */
+
+ // note: document columns are always one less than CellInfoX coords
+ // note: document rows must be looked up in RowInfo structs
+
+ // current column and row in document coordinates
+ SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
+ SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nY1 - 1) );
+
+ // find entire merged range in document, returns signed document coordinates
+ SCsCOL nFirstRealDocColS, nLastRealDocColS;
+ SCsROW nFirstRealDocRowS, nLastRealDocRowS;
+ lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
+ nCellInfoY, this, pRowInfo, nX1,nY1,nX2,nY2,nTab,
+ nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
+
+ // *complete* merged range in document coordinates
+ SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
+ SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
+ SCCOL nLastRealDocCol = static_cast< SCCOL >( nLastRealDocColS );
+ SCROW nLastRealDocRow = static_cast< SCROW >( nLastRealDocRowS );
+
+ // first visible column (nX1-1 is first processed document column)
+ SCCOL nFirstDocCol = (nX1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nX1 - 1 ) : nFirstRealDocCol;
+ USHORT nFirstCellInfoX = static_cast< USHORT >( nFirstDocCol + 1 );
+ nFirstCol = static_cast< size_t >( nFirstCellInfoX - nX1 );
+
+ // last visible column (nX2+1 is last processed document column)
+ SCCOL nLastDocCol = (nX2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nX2 + 1 ) : nLastRealDocCol;
+ USHORT nLastCellInfoX = static_cast< USHORT >( nLastDocCol + 1 );
+ size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nX1 );
+
+ // first visible row
+ USHORT nFirstCellInfoY = nCellInfoY;
+ while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
+ ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nY1 - 1 ) >= nFirstRealDocRow)) )
+ --nFirstCellInfoY;
+ SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nY1 - 1 );
+ nFirstRow = static_cast< size_t >( nFirstCellInfoY );
+
+ // last visible row
+ USHORT nLastCellInfoY = nCellInfoY;
+ while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
+ (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
+ ++nLastCellInfoY;
+ SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nY1 - 1 );
+ size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
+
+ // insert merged range
+ rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
+
+ // *** find additional size not included in svx::frame::Array ***
+
+ // additional space before first column
+ if( nFirstCol == 0 )
+ {
+ long nSize = 0;
+ for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
+ nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * nScaleX ), 1L );
+ rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
+ }
+ // additional space after last column
+ if( nLastCol + 1 == nColCount )
+ {
+ long nSize = 0;
+ for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
+ nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * nScaleX ), 1L );
+ rArray.SetAddMergedRightSize( nCol, nRow, nSize );
+ }
+ // additional space above first row
+ if( nFirstRow == 0 )
+ {
+ long nSize = 0;
+ for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
+ nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * nScaleY ), 1L );
+ rArray.SetAddMergedTopSize( nCol, nRow, nSize );
+ }
+ // additional space beyond last row
+ if( nLastRow + 1 == nRowCount )
+ {
+ long nSize = 0;
+ for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
+ nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * nScaleY ), 1L );
+ rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
+ }
+
+ // *** use line attributes from real origin cell ***
+
+ if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
+ {
+ if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
+ {
+ const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
+ pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
+ pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
+ pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
+ }
+ else
+ {
+ pBox = 0;
+ pTLBR = pBLTR = 0;
+ }
+ }
+ }
+
+ // *** borders *** ------------------------------------------------
+
+ if( pBox )
+ {
+ rArray.SetCellStyleLeft( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(), nScaleX ) );
+ rArray.SetCellStyleRight( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(), nScaleX ) );
+ rArray.SetCellStyleTop( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(), nScaleY ) );
+ rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), nScaleY ) );
+ }
+
+ if( pTLBR )
+ rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), nScaleY ) );
+ if( rInfo.mpBLTRLine )
+ rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), nScaleY ) );
+ }
+ }
+
+ /* Mirror the entire frame array.
+ 1st param = Mirror the vertical double line styles as well.
+ 2nd param = Do not swap diagonal lines.
+ */
+ if( bLayoutRTL )
+ rArray.MirrorSelfX( true, false );
+}
+
+// ============================================================================
+
+ScTableInfo::ScTableInfo() :
+ mpRowInfo( new RowInfo[ ROWINFO_MAX ] ),
+ mbPageMode( false )
+{
+ for( USHORT nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
+ mpRowInfo[ nIdx ].pCellInfo = 0;
+}
+
+ScTableInfo::~ScTableInfo()
+{
+ for( USHORT nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
+ delete [] mpRowInfo[ nIdx ].pCellInfo;
+ delete [] mpRowInfo;
+}
+
+// ============================================================================
+
diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx
new file mode 100644
index 000000000000..48879bcdec93
--- /dev/null
+++ b/sc/source/core/data/global.cxx
@@ -0,0 +1,1992 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svl/srchitem.hxx>
+#include <editeng/langitem.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/image.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/rcid.h>
+#include <unotools/charclass.hxx>
+#include <stdlib.h>
+#include <time.h>
+#include <ctype.h>
+#include <numeric>
+
+
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <comphelper/processfactory.hxx>
+#include <unotools/calendarwrapper.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <com/sun/star/i18n/CollatorOptions.hpp>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "global.hxx"
+#include "scresid.hxx"
+#include "autoform.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "addincol.hxx"
+#include "adiasync.hxx"
+#include "userlist.hxx"
+#include "interpre.hxx"
+#include "strload.hxx"
+#include "docpool.hxx"
+#include "unitconv.hxx"
+#include "compiler.hxx"
+#include "parclass.hxx"
+#include "funcdesc.hxx"
+#include "globstr.hrc"
+#include "scfuncs.hrc"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+
+// -----------------------------------------------------------------------
+
+#define CLIPST_AVAILABLE 0
+#define CLIPST_CAPTURED 1
+#define CLIPST_DELETE 2
+#define CLIPST_DRAW 3
+
+ScDocShellRef* ScGlobal::pDrawClipDocShellRef = NULL;
+SvxSearchItem* ScGlobal::pSearchItem = NULL;
+ScAutoFormat* ScGlobal::pAutoFormat = NULL;
+FuncCollection* ScGlobal::pFuncCollection = NULL;
+ScUnoAddInCollection* ScGlobal::pAddInCollection = NULL;
+ScUserList* ScGlobal::pUserList = NULL;
+String** ScGlobal::ppRscString = NULL;
+LanguageType ScGlobal::eLnge = LANGUAGE_SYSTEM;
+::com::sun::star::lang::Locale* ScGlobal::pLocale = NULL;
+SvtSysLocale* ScGlobal::pSysLocale = NULL;
+const CharClass* ScGlobal::pCharClass = NULL;
+const LocaleDataWrapper* ScGlobal::pLocaleData = NULL;
+CalendarWrapper* ScGlobal::pCalendar = NULL;
+CollatorWrapper* ScGlobal::pCollator = NULL;
+CollatorWrapper* ScGlobal::pCaseCollator = NULL;
+::utl::TransliterationWrapper* ScGlobal::pTransliteration = NULL;
+::utl::TransliterationWrapper* ScGlobal::pCaseTransliteration = NULL;
+::com::sun::star::uno::Reference< ::com::sun::star::i18n::XOrdinalSuffix> ScGlobal::xOrdinalSuffix = NULL;
+IntlWrapper* ScGlobal::pScIntlWrapper = NULL;
+sal_Unicode ScGlobal::cListDelimiter = ',';
+String* ScGlobal::pEmptyString = NULL;
+String* ScGlobal::pStrClipDocName = NULL;
+
+SvxBrushItem* ScGlobal::pEmptyBrushItem = NULL;
+SvxBrushItem* ScGlobal::pButtonBrushItem = NULL;
+SvxBrushItem* ScGlobal::pEmbeddedBrushItem = NULL;
+SvxBrushItem* ScGlobal::pProtectedBrushItem = NULL;
+
+ImageList* ScGlobal::pOutlineBitmaps = NULL;
+ImageList* ScGlobal::pOutlineBitmapsHC = NULL;
+
+ScFunctionList* ScGlobal::pStarCalcFunctionList = NULL;
+ScFunctionMgr* ScGlobal::pStarCalcFunctionMgr = NULL;
+
+ScUnitConverter* ScGlobal::pUnitConverter = NULL;
+SvNumberFormatter* ScGlobal::pEnglishFormatter = NULL;
+
+double ScGlobal::nScreenPPTX = 96.0;
+double ScGlobal::nScreenPPTY = 96.0;
+
+USHORT ScGlobal::nDefFontHeight = 240;
+USHORT ScGlobal::nStdRowHeight = 257;
+
+long ScGlobal::nLastRowHeightExtra = 0;
+long ScGlobal::nLastColWidthExtra = STD_EXTRA_WIDTH;
+
+static USHORT nPPTZoom = 0; // ScreenZoom used to determine nScreenPPTX/Y
+
+
+class SfxViewShell;
+SfxViewShell* pScActiveViewShell = NULL; //! als Member !!!!!
+USHORT nScClickMouseModifier = 0; //! dito
+USHORT nScFillModeMouseModifier = 0; //! dito
+
+// Hack: ScGlobal::GetUserList() muss InitAppOptions in der UI aufrufen,
+// damit UserList aus Cfg geladen wird
+
+void global_InitAppOptions();
+
+//========================================================================
+//
+// statische Funktionen
+//
+//========================================================================
+
+BOOL ScGlobal::HasAttrChanged( const SfxItemSet& rNewAttrs,
+ const SfxItemSet& rOldAttrs,
+ const USHORT nWhich )
+{
+ BOOL bInvalidate = FALSE;
+ const SfxItemState eNewState = rNewAttrs.GetItemState( nWhich );
+ const SfxItemState eOldState = rOldAttrs.GetItemState( nWhich );
+
+ //----------------------------------------------------------
+
+ if ( eNewState == eOldState )
+ {
+ // beide Items gesetzt
+ // PoolItems, d.h. Pointer-Vergleich zulaessig
+ if ( SFX_ITEM_SET == eOldState )
+ bInvalidate = (&rNewAttrs.Get( nWhich ) != &rOldAttrs.Get( nWhich ));
+ }
+ else
+ {
+ // ein Default-Item dabei
+ // PoolItems, d.h. Item-Vergleich noetig
+
+ const SfxPoolItem& rOldItem = ( SFX_ITEM_SET == eOldState )
+ ? rOldAttrs.Get( nWhich )
+ : rOldAttrs.GetPool()->GetDefaultItem( nWhich );
+
+ const SfxPoolItem& rNewItem = ( SFX_ITEM_SET == eNewState )
+ ? rNewAttrs.Get( nWhich )
+ : rNewAttrs.GetPool()->GetDefaultItem( nWhich );
+
+ bInvalidate = sal::static_int_cast<BOOL>(rNewItem != rOldItem);
+ }
+
+ return bInvalidate;
+}
+
+ULONG ScGlobal::GetStandardFormat( SvNumberFormatter& rFormatter,
+ ULONG nFormat, short nType )
+{
+ const SvNumberformat* pFormat = rFormatter.GetEntry( nFormat );
+ if ( pFormat )
+ return rFormatter.GetStandardFormat( nFormat, nType, pFormat->GetLanguage() );
+ return rFormatter.GetStandardFormat( nType, eLnge );
+}
+
+ULONG ScGlobal::GetStandardFormat( double fNumber, SvNumberFormatter& rFormatter,
+ ULONG nFormat, short nType )
+{
+ const SvNumberformat* pFormat = rFormatter.GetEntry( nFormat );
+ if ( pFormat )
+ return rFormatter.GetStandardFormat( fNumber, nFormat, nType,
+ pFormat->GetLanguage() );
+ return rFormatter.GetStandardFormat( nType, eLnge );
+}
+
+
+// static
+SvNumberFormatter* ScGlobal::GetEnglishFormatter()
+{
+ if ( !pEnglishFormatter )
+ {
+ pEnglishFormatter = new SvNumberFormatter(
+ ::comphelper::getProcessServiceFactory(), LANGUAGE_ENGLISH_US );
+ pEnglishFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT );
+ }
+ return pEnglishFormatter;
+}
+
+
+//------------------------------------------------------------------------
+
+BOOL ScGlobal::CheckWidthInvalidate( BOOL& bNumFormatChanged,
+ const SfxItemSet& rNewAttrs,
+ const SfxItemSet& rOldAttrs )
+{
+ // Ueberpruefen, ob Attributaenderungen in rNewAttrs gegnueber
+ // rOldAttrs die Textbreite an einer Zelle ungueltig machen
+
+ bNumFormatChanged =
+ HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_VALUE_FORMAT );
+ return ( bNumFormatChanged
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_LANGUAGE_FORMAT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_HEIGHT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_HEIGHT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_HEIGHT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_WEIGHT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_WEIGHT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_WEIGHT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_POSTURE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_POSTURE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_POSTURE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_UNDERLINE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_OVERLINE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_CROSSEDOUT )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_CONTOUR )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_SHADOWED )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_STACKED )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_ROTATE_VALUE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_ROTATE_MODE )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_LINEBREAK )
+ || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_MARGIN )
+ );
+}
+
+const SvxSearchItem& ScGlobal::GetSearchItem()
+{
+ if (!pSearchItem)
+ {
+ pSearchItem = new SvxSearchItem( SID_SEARCH_ITEM );
+ pSearchItem->SetAppFlag( SVX_SEARCHAPP_CALC );
+ }
+ return *pSearchItem;
+}
+
+void ScGlobal::SetSearchItem( const SvxSearchItem& rNew )
+{
+ // Hier waere ein Zuweisungsoperator ganz nett:
+ delete pSearchItem;
+ pSearchItem = (SvxSearchItem*)rNew.Clone();
+
+ pSearchItem->SetWhich( SID_SEARCH_ITEM );
+}
+
+void ScGlobal::ClearAutoFormat()
+{
+ if (pAutoFormat!=NULL)
+ {
+ delete pAutoFormat;
+ pAutoFormat=NULL;
+ }
+}
+
+ScAutoFormat* ScGlobal::GetAutoFormat()
+{
+ if ( !pAutoFormat )
+ {
+ pAutoFormat = new ScAutoFormat;
+ pAutoFormat->Load();
+ }
+
+ return pAutoFormat;
+}
+
+FuncCollection* ScGlobal::GetFuncCollection()
+{
+ if (!pFuncCollection)
+ pFuncCollection = new FuncCollection();
+ return pFuncCollection;
+}
+
+ScUnoAddInCollection* ScGlobal::GetAddInCollection()
+{
+ if (!pAddInCollection)
+ pAddInCollection = new ScUnoAddInCollection();
+ return pAddInCollection;
+}
+
+ScUserList* ScGlobal::GetUserList()
+{
+ // Hack: Cfg-Item an der App ggF. laden
+
+ global_InitAppOptions();
+
+ if (!pUserList)
+ pUserList = new ScUserList();
+ return pUserList;
+}
+
+void ScGlobal::SetUserList( const ScUserList* pNewList )
+{
+ if ( pNewList )
+ {
+ if ( !pUserList )
+ pUserList = new ScUserList( *pNewList );
+ else
+ *pUserList = *pNewList;
+ }
+ else
+ {
+ delete pUserList;
+ pUserList = NULL;
+ }
+}
+
+const String& ScGlobal::GetRscString( USHORT nIndex )
+{
+ DBG_ASSERT( nIndex < STR_COUNT, "ScGlobal::GetRscString - invalid string index");
+ if( !ppRscString[ nIndex ] )
+ {
+ OpCode eOp = ocNone;
+ // Map former globstr.src strings moved to compiler.src
+ switch (nIndex)
+ {
+ case STR_NULL_ERROR:
+ eOp = ocErrNull;
+ break;
+ case STR_DIV_ZERO:
+ eOp = ocErrDivZero;
+ break;
+ case STR_NO_VALUE:
+ eOp = ocErrValue;
+ break;
+ case STR_NOREF_STR:
+ eOp = ocErrRef;
+ break;
+ case STR_NO_NAME_REF:
+ eOp = ocErrName;
+ break;
+ case STR_NUM_ERROR:
+ eOp = ocErrNum;
+ break;
+ case STR_NV_STR:
+ eOp = ocErrNA;
+ break;
+ default:
+ ; // nothing
+ }
+ if (eOp != ocNone)
+ ppRscString[ nIndex ] = new String(
+ ScCompiler::GetNativeSymbol( eOp));
+ else
+ ppRscString[ nIndex ] = new String(
+ ScRscStrLoader( RID_GLOBSTR, nIndex ).GetString());
+ }
+ return *ppRscString[ nIndex ];
+}
+
+String ScGlobal::GetErrorString(USHORT nErrNumber)
+{
+ String sResStr;
+ switch (nErrNumber)
+ {
+ case NOTAVAILABLE : nErrNumber = STR_NV_STR; break;
+ case errNoRef : nErrNumber = STR_NO_REF_TABLE; break;
+ case errNoName : nErrNumber = STR_NO_NAME_REF; break;
+ case errNoAddin : nErrNumber = STR_NO_ADDIN; break;
+ case errNoMacro : nErrNumber = STR_NO_MACRO; break;
+ case errDoubleRef :
+ case errNoValue : nErrNumber = STR_NO_VALUE; break;
+ case errNoCode : nErrNumber = STR_NULL_ERROR; break;
+ case errDivisionByZero : nErrNumber = STR_DIV_ZERO; break;
+ case errIllegalFPOperation : nErrNumber = STR_NUM_ERROR; break;
+
+ default : sResStr = GetRscString(STR_ERROR_STR);
+ sResStr += String::CreateFromInt32( nErrNumber );
+ nErrNumber = 0;
+ break;
+ }
+ if( nErrNumber )
+ sResStr = GetRscString( nErrNumber );
+ return sResStr;
+}
+
+String ScGlobal::GetLongErrorString(USHORT nErrNumber)
+{
+ switch (nErrNumber)
+ {
+ case 0:
+ break;
+ case 1:
+ case errIllegalArgument:
+ nErrNumber = STR_LONG_ERR_ILL_ARG;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case errIllegalFPOperation:
+ nErrNumber = STR_LONG_ERR_ILL_FPO;
+ break;
+ case errIllegalChar:
+ nErrNumber = STR_LONG_ERR_ILL_CHAR;
+ break;
+ case errIllegalParameter:
+ nErrNumber = STR_LONG_ERR_ILL_PAR;
+ break;
+ case errSeparator:
+ nErrNumber = STR_LONG_ERR_ILL_SEP;
+ break;
+ case errPair:
+ case errPairExpected:
+ nErrNumber = STR_LONG_ERR_PAIR;
+ break;
+ case errOperatorExpected:
+ nErrNumber = STR_LONG_ERR_OP_EXP;
+ break;
+ case errVariableExpected:
+ case errParameterExpected:
+ nErrNumber = STR_LONG_ERR_VAR_EXP;
+ break;
+ case errCodeOverflow:
+ nErrNumber = STR_LONG_ERR_CODE_OVF;
+ break;
+ case errStringOverflow:
+ nErrNumber = STR_LONG_ERR_STR_OVF;
+ break;
+ case errStackOverflow:
+ case errInterpOverflow:
+ nErrNumber = STR_LONG_ERR_STACK_OVF;
+ break;
+ case errIllegalJump:
+ case errUnknownState:
+ case errUnknownVariable:
+ case errUnknownOpCode:
+ case errUnknownStackVariable:
+ case errUnknownToken:
+ case errNoCode:
+ case errDoubleRef:
+ nErrNumber = STR_LONG_ERR_SYNTAX;
+ break;
+ case errCircularReference:
+ nErrNumber = STR_LONG_ERR_CIRC_REF;
+ break;
+ case errNoConvergence:
+ nErrNumber = STR_LONG_ERR_NO_CONV;
+ break;
+ case errNoRef:
+ nErrNumber = STR_LONG_ERR_NO_REF;
+ break;
+ case errNoName:
+ nErrNumber = STR_LONG_ERR_NO_NAME;
+ break;
+ case errNoAddin:
+ nErrNumber = STR_LONG_ERR_NO_ADDIN;
+ break;
+ case errNoMacro:
+ nErrNumber = STR_LONG_ERR_NO_MACRO;
+ break;
+ case errDivisionByZero:
+ nErrNumber = STR_LONG_ERR_DIV_ZERO;
+ break;
+ case errNestedArray:
+ nErrNumber = STR_ERR_LONG_NESTED_ARRAY;
+ break;
+ case errNoValue:
+ nErrNumber = STR_LONG_ERR_NO_VALUE;
+ break;
+ case NOTAVAILABLE:
+ nErrNumber = STR_LONG_ERR_NV;
+ break;
+ default:
+ nErrNumber = STR_ERROR_STR;
+ break;
+ }
+ String aRes( GetRscString( nErrNumber ) );
+ return aRes;
+}
+
+SvxBrushItem* ScGlobal::GetButtonBrushItem()
+{
+ pButtonBrushItem->SetColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
+ return pButtonBrushItem;
+}
+
+const String& ScGlobal::GetEmptyString()
+{
+ return *pEmptyString;
+}
+
+ImageList* ScGlobal::GetOutlineSymbols( bool bHC )
+{
+ ImageList*& rpImageList = bHC ? pOutlineBitmapsHC : pOutlineBitmaps;
+ if( !rpImageList )
+ rpImageList = new ImageList( ScResId( bHC ? RID_OUTLINEBITMAPS_H : RID_OUTLINEBITMAPS ) );
+ return rpImageList;
+}
+
+void ScGlobal::Init()
+{
+ pEmptyString = new String;
+
+ // Die Default-Sprache fuer Zahlenformate (ScGlobal::eLnge)
+ // muss immer LANGUAGE_SYSTEM sein
+ //! Dann kann auch die Variable raus
+ eLnge = LANGUAGE_SYSTEM;
+
+ //! Wenn Sortierung etc. von der Sprache der installierten Offfice-Version
+ //! abhaengen sollen, hier "Application::GetSettings().GetUILanguage()"
+ pSysLocale = new SvtSysLocale;
+ pCharClass = pSysLocale->GetCharClassPtr();
+ pLocaleData = pSysLocale->GetLocaleDataPtr();
+
+ ppRscString = new String *[ STR_COUNT ];
+ for( USHORT nC = 0 ; nC < STR_COUNT ; nC++ ) ppRscString[ nC ] = NULL;
+
+ pEmptyBrushItem = new SvxBrushItem( Color( COL_TRANSPARENT ), ATTR_BACKGROUND );
+ pButtonBrushItem = new SvxBrushItem( Color(), ATTR_BACKGROUND );
+ pEmbeddedBrushItem = new SvxBrushItem( Color( COL_LIGHTCYAN ), ATTR_BACKGROUND );
+ pProtectedBrushItem = new SvxBrushItem( Color( COL_LIGHTGRAY ), ATTR_BACKGROUND );
+
+ UpdatePPT(NULL);
+ //ScCompiler::InitSymbolsNative();
+ // ScParameterClassification _after_ Compiler, needs function resources if
+ // arguments are to be merged in, which in turn need strings of function
+ // names from the compiler.
+ ScParameterClassification::Init();
+ srand( (unsigned) time( NULL ) ); // Random Seed Init fuer Interpreter
+
+ InitAddIns();
+
+ pStrClipDocName = new String( ScResId( SCSTR_NONAME ) );
+ *pStrClipDocName += '1';
+
+ // ScDocumentPool::InitVersionMaps() ist schon vorher gerufen worden
+}
+
+void ScGlobal::UpdatePPT( OutputDevice* pDev )
+{
+ USHORT nCurrentZoom = Application::GetSettings().GetStyleSettings().GetScreenZoom();
+ if ( nCurrentZoom != nPPTZoom )
+ {
+ // Screen PPT values must be updated when ScreenZoom has changed.
+ // If called from Window::DataChanged, the window is passed as pDev,
+ // to make sure LogicToPixel uses a device which already uses the new zoom.
+ // For the initial settings, NULL is passed and GetDefaultDevice used.
+
+ if ( !pDev )
+ pDev = Application::GetDefaultDevice();
+ Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ nScreenPPTX = aPix1000.X() / 1000.0;
+ nScreenPPTY = aPix1000.Y() / 1000.0;
+ nPPTZoom = nCurrentZoom;
+ }
+}
+
+const String& ScGlobal::GetClipDocName()
+{
+ return *pStrClipDocName;
+}
+
+void ScGlobal::SetClipDocName( const String& rNew )
+{
+ *pStrClipDocName = rNew;
+}
+
+
+void ScGlobal::InitTextHeight(SfxItemPool* pPool)
+{
+ if (!pPool)
+ {
+ DBG_ERROR("kein Pool bei ScGlobal::InitTextHeight");
+ return;
+ }
+
+ const ScPatternAttr* pPattern = (const ScPatternAttr*)&pPool->GetDefaultItem(ATTR_PATTERN);
+ if (!pPattern)
+ {
+ DBG_ERROR("kein Default-Pattern bei ScGlobal::InitTextHeight");
+ return;
+ }
+
+// String aTestString('X');
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ VirtualDevice aVirtWindow( *pDefaultDev );
+ aVirtWindow.SetMapMode(MAP_PIXEL);
+ Font aDefFont;
+ pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, &aVirtWindow); // font color doesn't matter here
+ aVirtWindow.SetFont(aDefFont);
+ nDefFontHeight = (USHORT) aVirtWindow.PixelToLogic(Size(0, aVirtWindow.GetTextHeight()),
+ MAP_TWIP).Height();
+
+ const SvxMarginItem* pMargin = (const SvxMarginItem*)&pPattern->GetItem(ATTR_MARGIN);
+
+ nStdRowHeight = (USHORT) ( nDefFontHeight +
+ pMargin->GetTopMargin() + pMargin->GetBottomMargin()
+ - STD_ROWHEIGHT_DIFF );
+}
+
+void ScGlobal::Clear()
+{
+ // asyncs _vor_ ExitExternalFunc zerstoeren!
+ theAddInAsyncTbl.DeleteAndDestroy( 0, theAddInAsyncTbl.Count() );
+ ExitExternalFunc();
+ DELETEZ(pAutoFormat);
+ DELETEZ(pSearchItem);
+ DELETEZ(pFuncCollection);
+ DELETEZ(pAddInCollection);
+ DELETEZ(pUserList);
+
+ for( USHORT nC = 0 ; nC < STR_COUNT ; nC++ )
+ if( ppRscString ) delete ppRscString[ nC ];
+ delete[] ppRscString;
+ ppRscString = NULL;
+
+ DELETEZ(pStarCalcFunctionList); // vor ResMgr zerstoeren!
+ DELETEZ(pStarCalcFunctionMgr);
+ ScParameterClassification::Exit();
+ ScCompiler::DeInit();
+ ScInterpreter::GlobalExit(); // statischen Stack loeschen
+
+ DELETEZ(pEmptyBrushItem);
+ DELETEZ(pButtonBrushItem);
+ DELETEZ(pEmbeddedBrushItem);
+ DELETEZ(pProtectedBrushItem);
+ DELETEZ(pOutlineBitmaps);
+ DELETEZ(pOutlineBitmapsHC);
+// DELETEZ(pAnchorBitmap);
+// DELETEZ(pGrayAnchorBitmap);
+ DELETEZ(pEnglishFormatter);
+ DELETEZ(pCaseTransliteration);
+ DELETEZ(pTransliteration);
+ DELETEZ(pCaseCollator);
+ DELETEZ(pCollator);
+ DELETEZ(pCalendar);
+ //! do NOT delete pCharClass since it is a pointer to the single SvtSysLocale instance
+ pCharClass = NULL;
+ //! do NOT delete pLocaleData since it is a pointer to the single SvtSysLocale instance
+ pLocaleData = NULL;
+ DELETEZ(pSysLocale);
+ DELETEZ(pLocale);
+ DELETEZ(pScIntlWrapper);
+ DELETEZ(pStrClipDocName);
+
+ DELETEZ(pUnitConverter);
+
+ ScDocumentPool::DeleteVersionMaps();
+
+ DELETEZ(pEmptyString);
+}
+
+//------------------------------------------------------------------------
+
+// static
+CharSet ScGlobal::GetCharsetValue( const String& rCharSet )
+{
+ // new TextEncoding values
+ if ( CharClass::isAsciiNumeric( rCharSet ) )
+ {
+ sal_Int32 nVal = rCharSet.ToInt32();
+ if ( !nVal || nVal == RTL_TEXTENCODING_DONTKNOW )
+ return gsl_getSystemTextEncoding();
+ return (CharSet) nVal;
+ }
+ // old CharSet values for compatibility
+ else if (rCharSet.EqualsIgnoreCaseAscii("ANSI") ) return RTL_TEXTENCODING_MS_1252;
+ else if (rCharSet.EqualsIgnoreCaseAscii("MAC") ) return RTL_TEXTENCODING_APPLE_ROMAN;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC") ) return RTL_TEXTENCODING_IBM_850;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_437")) return RTL_TEXTENCODING_IBM_437;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_850")) return RTL_TEXTENCODING_IBM_850;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_860")) return RTL_TEXTENCODING_IBM_860;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_861")) return RTL_TEXTENCODING_IBM_861;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_863")) return RTL_TEXTENCODING_IBM_863;
+ else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_865")) return RTL_TEXTENCODING_IBM_865;
+// else if (rCharSet.EqualsIgnoreCaseAscii("SYSTEM") ) return gsl_getSystemTextEncoding();
+ else return gsl_getSystemTextEncoding();
+}
+
+//------------------------------------------------------------------------
+
+// static
+String ScGlobal::GetCharsetString( CharSet eVal )
+{
+ const sal_Char* pChar;
+ switch ( eVal )
+ {
+ // old CharSet strings for compatibility
+ case RTL_TEXTENCODING_MS_1252: pChar = "ANSI"; break;
+ case RTL_TEXTENCODING_APPLE_ROMAN: pChar = "MAC"; break;
+ // IBMPC == IBMPC_850
+ case RTL_TEXTENCODING_IBM_437: pChar = "IBMPC_437"; break;
+ case RTL_TEXTENCODING_IBM_850: pChar = "IBMPC_850"; break;
+ case RTL_TEXTENCODING_IBM_860: pChar = "IBMPC_860"; break;
+ case RTL_TEXTENCODING_IBM_861: pChar = "IBMPC_861"; break;
+ case RTL_TEXTENCODING_IBM_863: pChar = "IBMPC_863"; break;
+ case RTL_TEXTENCODING_IBM_865: pChar = "IBMPC_865"; break;
+ case RTL_TEXTENCODING_DONTKNOW: pChar = "SYSTEM"; break;
+ // new string of TextEncoding value
+ default:
+ return String::CreateFromInt32( eVal );
+ }
+ return String::CreateFromAscii(pChar);
+}
+
+//------------------------------------------------------------------------
+
+bool ScGlobal::HasStarCalcFunctionList()
+{
+ return ( pStarCalcFunctionList != NULL );
+}
+
+ScFunctionList* ScGlobal::GetStarCalcFunctionList()
+{
+ if ( !pStarCalcFunctionList )
+ pStarCalcFunctionList = new ScFunctionList;
+
+ return pStarCalcFunctionList;
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionMgr* ScGlobal::GetStarCalcFunctionMgr()
+{
+ if ( !pStarCalcFunctionMgr )
+ pStarCalcFunctionMgr = new ScFunctionMgr;
+
+ return pStarCalcFunctionMgr;
+}
+
+void ScGlobal::ResetFunctionList()
+{
+ // FunctionMgr has pointers into FunctionList, must also be updated
+
+ DELETEZ( pStarCalcFunctionMgr );
+ DELETEZ( pStarCalcFunctionList );
+}
+
+//------------------------------------------------------------------------
+
+// static
+ScUnitConverter* ScGlobal::GetUnitConverter()
+{
+ if ( !pUnitConverter )
+ pUnitConverter = new ScUnitConverter;
+
+ return pUnitConverter;
+}
+
+
+//------------------------------------------------------------------------
+
+// static
+const sal_Unicode* ScGlobal::UnicodeStrChr( const sal_Unicode* pStr,
+ sal_Unicode c )
+{
+ if ( !pStr )
+ return NULL;
+ while ( *pStr )
+ {
+ if ( *pStr == c )
+ return pStr;
+ pStr++;
+ }
+ return NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+void ScGlobal::AddToken( String& rTokenList, const String& rToken, sal_Unicode cSep, xub_StrLen nSepCount, bool bForceSep )
+{
+ if( bForceSep || (rToken.Len() && rTokenList.Len()) )
+ rTokenList.Expand( rTokenList.Len() + nSepCount, cSep );
+ rTokenList.Append( rToken );
+}
+
+bool ScGlobal::IsQuoted( const String& rString, sal_Unicode cQuote )
+{
+ return (rString.Len() >= 2) && (rString.GetChar( 0 ) == cQuote) && (rString.GetChar( rString.Len() - 1 ) == cQuote);
+}
+
+void ScGlobal::AddQuotes( String& rString, sal_Unicode cQuote, bool bEscapeEmbedded )
+{
+ if (bEscapeEmbedded)
+ {
+ sal_Unicode pQ[3];
+ pQ[0] = pQ[1] = cQuote;
+ pQ[2] = 0;
+ String aQuotes( pQ );
+ rString.SearchAndReplaceAll( cQuote, aQuotes);
+ }
+ rString.Insert( cQuote, 0 ).Append( cQuote );
+}
+
+void ScGlobal::EraseQuotes( String& rString, sal_Unicode cQuote, bool bUnescapeEmbedded )
+{
+ if ( IsQuoted( rString, cQuote ) )
+ {
+ rString.Erase( rString.Len() - 1 ).Erase( 0, 1 );
+ if (bUnescapeEmbedded)
+ {
+ sal_Unicode pQ[3];
+ pQ[0] = pQ[1] = cQuote;
+ pQ[2] = 0;
+ String aQuotes( pQ );
+ rString.SearchAndReplaceAll( aQuotes, cQuote);
+ }
+ }
+}
+
+xub_StrLen ScGlobal::FindUnquoted( const String& rString, sal_Unicode cChar, xub_StrLen nStart, sal_Unicode cQuote )
+{
+ const sal_Unicode* const pStart = rString.GetBuffer();
+ const sal_Unicode* const pStop = pStart + rString.Len();
+ const sal_Unicode* p = pStart + nStart;
+ bool bQuoted = false;
+ while (p < pStop)
+ {
+ if (*p == cChar && !bQuoted)
+ return sal::static_int_cast< xub_StrLen >( p - pStart );
+ else if (*p == cQuote)
+ {
+ if (!bQuoted)
+ bQuoted = true;
+ else if (p < pStop-1 && *(p+1) == cQuote)
+ ++p;
+ else
+ bQuoted = false;
+ }
+ ++p;
+ }
+ return STRING_NOTFOUND;
+}
+
+const sal_Unicode* ScGlobal::FindUnquoted( const sal_Unicode* pString, sal_Unicode cChar, sal_Unicode cQuote )
+{
+ const sal_Unicode* p = pString;
+ bool bQuoted = false;
+ while (*p)
+ {
+ if (*p == cChar && !bQuoted)
+ return p;
+ else if (*p == cQuote)
+ {
+ if (!bQuoted)
+ bQuoted = true;
+ else if (*(p+1) == cQuote)
+ ++p;
+ else
+ bQuoted = false;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScGlobal::EETextObjEqual( const EditTextObject* pObj1,
+ const EditTextObject* pObj2 )
+{
+ if ( pObj1 == pObj2 ) // both empty or the same object
+ return TRUE;
+
+ if ( pObj1 && pObj2 )
+ {
+ // first test for equal text content
+ USHORT nParCount = pObj1->GetParagraphCount();
+ if ( nParCount != pObj2->GetParagraphCount() )
+ return FALSE;
+ for (USHORT nPar=0; nPar<nParCount; nPar++)
+ if ( pObj1->GetText(nPar) != pObj2->GetText(nPar) )
+ return FALSE;
+
+ SvMemoryStream aStream1;
+ SvMemoryStream aStream2;
+ pObj1->Store( aStream1 );
+ pObj2->Store( aStream2 );
+ ULONG nSize = aStream1.Tell();
+ if ( aStream2.Tell() == nSize )
+ if ( !memcmp( aStream1.GetData(), aStream2.GetData(), (USHORT) nSize ) )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ScGlobal::OpenURL( const String& rURL, const String& rTarget )
+{
+ // OpenURL wird immer ueber irgendwelche Umwege durch Mausklicks im GridWindow
+ // aufgerufen, darum stimmen pScActiveViewShell und nScClickMouseModifier.
+
+ SfxStringItem aUrl( SID_FILE_NAME, rURL );
+ SfxStringItem aTarget( SID_TARGETNAME, rTarget );
+
+ if ( nScClickMouseModifier & KEY_MOD1 ) // control-click -> into new window
+ aTarget.SetValue(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("_blank")) );
+
+ SfxViewFrame* pFrame = NULL;
+ String aReferName;
+ if ( pScActiveViewShell )
+ {
+ pFrame = pScActiveViewShell->GetViewFrame();
+ SfxMedium* pMed = pFrame->GetObjectShell()->GetMedium();
+ if (pMed)
+ aReferName = pMed->GetName();
+ }
+
+ SfxFrameItem aFrm( SID_DOCFRAME, pFrame );
+ SfxStringItem aReferer( SID_REFERER, aReferName );
+
+ SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, FALSE );
+ SfxBoolItem aBrowsing( SID_BROWSE, TRUE );
+
+ // kein SID_SILENT mehr wegen Bug #42525# (war angeblich sowieso falsch)
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ pViewFrm->GetDispatcher()->Execute( SID_OPENDOC,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ &aUrl, &aTarget,
+ &aFrm, &aReferer,
+ &aNewView, &aBrowsing,
+ 0L );
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScGlobal::IsSystemRTL()
+{
+ return MsLangId::isRightToLeft( Application::GetSettings().GetLanguage() );
+}
+
+BYTE ScGlobal::GetDefaultScriptType()
+{
+ // Used when text contains only WEAK characters.
+ // Script type of office language is used then (same as GetEditDefaultLanguage,
+ // to get consistent behavior of text in simple cells and EditEngine,
+ // also same as GetAppLanguage() in Writer)
+
+ return (BYTE) SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
+}
+
+LanguageType ScGlobal::GetEditDefaultLanguage()
+{
+ // used for EditEngine::SetDefaultLanguage
+
+ return Application::GetSettings().GetLanguage();
+}
+
+USHORT ScGlobal::GetScriptedWhichID( BYTE nScriptType, USHORT nWhich )
+{
+ switch ( nScriptType )
+ {
+ case SCRIPTTYPE_LATIN:
+ case SCRIPTTYPE_ASIAN:
+ case SCRIPTTYPE_COMPLEX:
+ break; // take exact matches
+ default: // prefer one, first COMPLEX, then ASIAN
+ if ( nScriptType & SCRIPTTYPE_COMPLEX )
+ nScriptType = SCRIPTTYPE_COMPLEX;
+ else if ( nScriptType & SCRIPTTYPE_ASIAN )
+ nScriptType = SCRIPTTYPE_ASIAN;
+ }
+ switch ( nScriptType )
+ {
+ case SCRIPTTYPE_COMPLEX:
+ {
+ switch ( nWhich )
+ {
+ case ATTR_FONT:
+ case ATTR_CJK_FONT:
+ nWhich = ATTR_CTL_FONT;
+ break;
+ case ATTR_FONT_HEIGHT:
+ case ATTR_CJK_FONT_HEIGHT:
+ nWhich = ATTR_CTL_FONT_HEIGHT;
+ break;
+ case ATTR_FONT_WEIGHT:
+ case ATTR_CJK_FONT_WEIGHT:
+ nWhich = ATTR_CTL_FONT_WEIGHT;
+ break;
+ case ATTR_FONT_POSTURE:
+ case ATTR_CJK_FONT_POSTURE:
+ nWhich = ATTR_CTL_FONT_POSTURE;
+ break;
+ }
+ }
+ break;
+ case SCRIPTTYPE_ASIAN:
+ {
+ switch ( nWhich )
+ {
+ case ATTR_FONT:
+ case ATTR_CTL_FONT:
+ nWhich = ATTR_CJK_FONT;
+ break;
+ case ATTR_FONT_HEIGHT:
+ case ATTR_CTL_FONT_HEIGHT:
+ nWhich = ATTR_CJK_FONT_HEIGHT;
+ break;
+ case ATTR_FONT_WEIGHT:
+ case ATTR_CTL_FONT_WEIGHT:
+ nWhich = ATTR_CJK_FONT_WEIGHT;
+ break;
+ case ATTR_FONT_POSTURE:
+ case ATTR_CTL_FONT_POSTURE:
+ nWhich = ATTR_CJK_FONT_POSTURE;
+ break;
+ }
+ }
+ break;
+ default:
+ {
+ switch ( nWhich )
+ {
+ case ATTR_CTL_FONT:
+ case ATTR_CJK_FONT:
+ nWhich = ATTR_FONT;
+ break;
+ case ATTR_CTL_FONT_HEIGHT:
+ case ATTR_CJK_FONT_HEIGHT:
+ nWhich = ATTR_FONT_HEIGHT;
+ break;
+ case ATTR_CTL_FONT_WEIGHT:
+ case ATTR_CJK_FONT_WEIGHT:
+ nWhich = ATTR_FONT_WEIGHT;
+ break;
+ case ATTR_CTL_FONT_POSTURE:
+ case ATTR_CJK_FONT_POSTURE:
+ nWhich = ATTR_FONT_POSTURE;
+ break;
+ }
+ }
+ }
+ return nWhich;
+}
+
+//------------------------------------------------------------------------
+
+void ScGlobal::AddLanguage( SfxItemSet& rSet, SvNumberFormatter& rFormatter )
+{
+ DBG_ASSERT( rSet.GetItemState( ATTR_LANGUAGE_FORMAT, FALSE ) == SFX_ITEM_DEFAULT,
+ "ScGlobal::AddLanguage - language already added");
+
+ const SfxPoolItem* pHardItem;
+ if ( rSet.GetItemState( ATTR_VALUE_FORMAT, FALSE, &pHardItem ) == SFX_ITEM_SET )
+ {
+ const SvNumberformat* pHardFormat = rFormatter.GetEntry(
+ ((const SfxUInt32Item*)pHardItem)->GetValue() );
+
+ ULONG nParentFmt = 0; // pool default
+ const SfxItemSet* pParent = rSet.GetParent();
+ if ( pParent )
+ nParentFmt = ((const SfxUInt32Item&)pParent->Get( ATTR_VALUE_FORMAT )).GetValue();
+ const SvNumberformat* pParFormat = rFormatter.GetEntry( nParentFmt );
+
+ if ( pHardFormat && pParFormat &&
+ (pHardFormat->GetLanguage() != pParFormat->GetLanguage()) )
+ rSet.Put( SvxLanguageItem( pHardFormat->GetLanguage(), ATTR_LANGUAGE_FORMAT ) );
+ }
+}
+
+
+
+
+
+//===================================================================
+// class ScFunctionList:
+//===================================================================
+
+//===================================================================
+// class ScFuncRes
+// fuer temporaere Objekte zum Holen der Resourcen
+
+class ScFuncRes : public Resource
+{
+public:
+ ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
+
+private:
+ USHORT GetNum();
+};
+
+//--------------------------------------------------------------------
+
+ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
+ : Resource(aRes)
+{
+ rbSuppressed = (bool)GetNum();
+ pDesc->nCategory = GetNum();
+ pDesc->nHelpId = GetNum() + 32768; //! Hack, see scfuncs.src
+ pDesc->nArgCount = GetNum();
+ USHORT nArgs = pDesc->nArgCount;
+ if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
+ if (nArgs)
+ {
+ pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
+ for (USHORT i = 0; i < nArgs; i++)
+ {
+ pDesc->pDefArgFlags[i].bOptional = (bool)GetNum();
+ }
+ }
+ // Need to read the value from the resource even if nArgs==0 to advance the
+ // resource position pointer, so this can't be in the if(nArgs) block above.
+ USHORT nSuppressed = GetNum();
+ if (nSuppressed)
+ {
+ if (nSuppressed > nArgs)
+ {
+ DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
+ aRes.GetId(), (int)nSuppressed, (int)nArgs);
+ nSuppressed = nArgs; // sanitize
+ }
+ for (USHORT i=0; i < nSuppressed; ++i)
+ {
+ USHORT nParam = GetNum();
+ if (nParam < nArgs)
+ {
+ if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
+ {
+ DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
+ aRes.GetId(), (int)nParam, (int)nArgs);
+ }
+ else
+ {
+ pDesc->pDefArgFlags[nParam].bSuppress = true;
+ pDesc->bHasSuppressedArgs = true;
+ }
+ }
+ else
+ {
+ DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
+ aRes.GetId(), (int)nParam, (int)nArgs);
+ }
+ }
+ }
+
+ pDesc->pFuncName = new String( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId())));
+ pDesc->pFuncDesc = new String(ScResId(1));
+
+ if (nArgs)
+ {
+ pDesc->ppDefArgNames = new String*[nArgs];
+ pDesc->ppDefArgDescs = new String*[nArgs];
+ for (USHORT i = 0; i < nArgs; i++)
+ {
+ pDesc->ppDefArgNames[i] = new String(ScResId(2*(i+1) ));
+ pDesc->ppDefArgDescs[i] = new String(ScResId(2*(i+1)+1));
+ }
+ }
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScFuncRes::GetNum()
+{
+ return ReadShortRes();
+}
+
+//=========================================================================
+
+// um an die protected von Resource ranzukommen
+class ScResourcePublisher : public Resource
+{
+private:
+ void FreeResource() { Resource::FreeResource(); }
+public:
+ ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
+ ~ScResourcePublisher() { FreeResource(); }
+ BOOL IsAvailableRes( const ResId& rId ) const
+ { return Resource::IsAvailableRes( rId ); }
+
+};
+
+
+ScFunctionList::ScFunctionList() :
+ nMaxFuncNameLen ( 0 )
+{
+ ScFuncDesc* pDesc = NULL;
+ xub_StrLen nStrLen = 0;
+ FuncCollection* pFuncColl;
+ USHORT i,j;
+ USHORT nDescBlock[] =
+ {
+ RID_SC_FUNCTION_DESCRIPTIONS1,
+ RID_SC_FUNCTION_DESCRIPTIONS2
+ };
+ const USHORT nBlocks = sizeof(nDescBlock) / sizeof(USHORT);
+
+ aFunctionList.Clear();
+
+ for ( USHORT k = 0; k < nBlocks; k++ )
+ {
+ ::std::auto_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) );
+ // Browse for all possible OpCodes. This is not the fastest method, but
+ // otherwise the sub resources within the resource blocks and the
+ // resource blocks themselfs would had to be ordered according to
+ // OpCodes, which is utopian..
+ for (i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++)
+ {
+ ScResId aRes(i);
+ aRes.SetRT(RSC_RESOURCE);
+ // Sub resource of OpCode available?
+ if (pBlock->IsAvailableRes(aRes))
+ {
+ pDesc = new ScFuncDesc;
+ bool bSuppressed = false;
+ ScFuncRes aSubRes( aRes, pDesc, bSuppressed);
+ // Instead of dealing with this exceptional case at 1001 places
+ // we simply don't add an entirely suppressed function to the
+ // list and delete it.
+ if (bSuppressed)
+ delete pDesc;
+ else
+ {
+ pDesc->nFIndex = i;
+ aFunctionList.Insert( pDesc, LIST_APPEND );
+
+ nStrLen = (*(pDesc->pFuncName)).Len();
+ if (nStrLen > nMaxFuncNameLen)
+ nMaxFuncNameLen = nStrLen;
+ }
+ }
+ }
+ }
+
+ USHORT nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions
+
+ // Auswertung AddIn-Liste
+ String aDefArgNameValue(RTL_CONSTASCII_STRINGPARAM("value"));
+ String aDefArgNameString(RTL_CONSTASCII_STRINGPARAM("string"));
+ String aDefArgNameValues(RTL_CONSTASCII_STRINGPARAM("values"));
+ String aDefArgNameStrings(RTL_CONSTASCII_STRINGPARAM("strings"));
+ String aDefArgNameCells(RTL_CONSTASCII_STRINGPARAM("cells"));
+ String aDefArgNameNone(RTL_CONSTASCII_STRINGPARAM("none"));
+ String aDefArgDescValue(RTL_CONSTASCII_STRINGPARAM("a value"));
+ String aDefArgDescString(RTL_CONSTASCII_STRINGPARAM("a string"));
+ String aDefArgDescValues(RTL_CONSTASCII_STRINGPARAM("array of values"));
+ String aDefArgDescStrings(RTL_CONSTASCII_STRINGPARAM("array of strings"));
+ String aDefArgDescCells(RTL_CONSTASCII_STRINGPARAM("range of cells"));
+ String aDefArgDescNone(RTL_CONSTASCII_STRINGPARAM("none"));
+ String aArgName, aArgDesc;
+ pFuncColl = ScGlobal::GetFuncCollection();
+ for (i = 0; i < pFuncColl->GetCount(); i++)
+ {
+ pDesc = new ScFuncDesc;
+ FuncData *pAddInFuncData = (FuncData*)pFuncColl->At(i);
+ USHORT nArgs = pAddInFuncData->GetParamCount() - 1;
+ pAddInFuncData->GetParamDesc( aArgName, aArgDesc, 0 );
+ pDesc->nFIndex = nNextId++; // ??? OpCode vergeben
+ pDesc->nCategory = ID_FUNCTION_GRP_ADDINS;
+ pDesc->pFuncName = new String(pAddInFuncData->GetInternalName());
+ pDesc->pFuncName->ToUpperAscii();
+ pDesc->pFuncDesc = new String( aArgDesc );
+ *(pDesc->pFuncDesc) += '\n';
+ pDesc->pFuncDesc->AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( AddIn: " ));
+ *(pDesc->pFuncDesc) += pAddInFuncData->GetModuleName();
+ pDesc->pFuncDesc->AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" ));
+ pDesc->nArgCount = nArgs;
+ if (nArgs)
+ {
+ pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
+ pDesc->ppDefArgNames = new String*[nArgs];
+ pDesc->ppDefArgDescs = new String*[nArgs];
+ for (j = 0; j < nArgs; j++)
+ {
+ pDesc->pDefArgFlags[j].bOptional = false;
+ pDesc->pDefArgFlags[j].bSuppress = false;
+ pAddInFuncData->GetParamDesc( aArgName, aArgDesc, j+1 );
+ if ( aArgName.Len() )
+ pDesc->ppDefArgNames[j] = new String( aArgName );
+ else
+ {
+ switch (pAddInFuncData->GetParamType(j+1))
+ {
+ case PTR_DOUBLE:
+ pDesc->ppDefArgNames[j] = new String( aDefArgNameValue );
+ break;
+ case PTR_STRING:
+ pDesc->ppDefArgNames[j] = new String( aDefArgNameString );
+ break;
+ case PTR_DOUBLE_ARR:
+ pDesc->ppDefArgNames[j] = new String( aDefArgNameValues );
+ break;
+ case PTR_STRING_ARR:
+ pDesc->ppDefArgNames[j] = new String( aDefArgNameStrings );
+ break;
+ case PTR_CELL_ARR:
+ pDesc->ppDefArgNames[j] = new String( aDefArgNameCells );
+ break;
+ default:
+ pDesc->ppDefArgNames[j] = new String( aDefArgNameNone );
+ break;
+ }
+ }
+ if ( aArgDesc.Len() )
+ pDesc->ppDefArgDescs[j] = new String( aArgDesc );
+ else
+ {
+ switch (pAddInFuncData->GetParamType(j+1))
+ {
+ case PTR_DOUBLE:
+ pDesc->ppDefArgDescs[j] = new String( aDefArgDescValue );
+ break;
+ case PTR_STRING:
+ pDesc->ppDefArgDescs[j] = new String( aDefArgDescString );
+ break;
+ case PTR_DOUBLE_ARR:
+ pDesc->ppDefArgDescs[j] = new String( aDefArgDescValues );
+ break;
+ case PTR_STRING_ARR:
+ pDesc->ppDefArgDescs[j] = new String( aDefArgDescStrings );
+ break;
+ case PTR_CELL_ARR:
+ pDesc->ppDefArgDescs[j] = new String( aDefArgDescCells );
+ break;
+ default:
+ pDesc->ppDefArgDescs[j] = new String( aDefArgDescNone );
+ break;
+ }
+ }
+ }
+ }
+// pDesc->nHelpId = 0;
+
+ aFunctionList.Insert(pDesc, LIST_APPEND);
+ nStrLen = (*(pDesc->pFuncName)).Len();
+ if ( nStrLen > nMaxFuncNameLen)
+ nMaxFuncNameLen = nStrLen;
+ }
+
+ // StarOne AddIns
+
+ ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection();
+ long nUnoCount = pUnoAddIns->GetFuncCount();
+ for (long nFunc=0; nFunc<nUnoCount; nFunc++)
+ {
+ pDesc = new ScFuncDesc;
+ pDesc->nFIndex = nNextId++;
+
+ if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) )
+ {
+ aFunctionList.Insert(pDesc, LIST_APPEND);
+ nStrLen = (*(pDesc->pFuncName)).Len();
+ if (nStrLen > nMaxFuncNameLen)
+ nMaxFuncNameLen = nStrLen;
+ }
+ else
+ delete pDesc;
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionList::~ScFunctionList()
+{
+ const ScFuncDesc* pDesc = First();
+ while (pDesc)
+ {
+ delete pDesc;
+ pDesc = Next();
+ }
+}
+
+
+//========================================================================
+// class ScFuncDesc:
+
+ScFuncDesc::ScFuncDesc() :
+ pFuncName (NULL),
+ pFuncDesc (NULL),
+ ppDefArgNames (NULL),
+ ppDefArgDescs (NULL),
+ pDefArgFlags (NULL),
+ nFIndex (0),
+ nCategory (0),
+ nArgCount (0),
+ nHelpId (0),
+ bIncomplete (false),
+ bHasSuppressedArgs(false)
+{}
+
+//------------------------------------------------------------------------
+
+ScFuncDesc::~ScFuncDesc()
+{
+ Clear();
+}
+
+//------------------------------------------------------------------------
+
+void ScFuncDesc::Clear()
+{
+ USHORT nArgs = nArgCount;
+ if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1;
+ if (nArgs)
+ {
+ for (USHORT i=0; i<nArgs; i++ )
+ {
+ delete ppDefArgNames[i];
+ delete ppDefArgDescs[i];
+ }
+ delete [] ppDefArgNames;
+ delete [] ppDefArgDescs;
+ delete [] pDefArgFlags;
+ }
+ nArgCount = 0;
+ ppDefArgNames = NULL;
+ ppDefArgDescs = NULL;
+ pDefArgFlags = NULL;
+
+ delete pFuncName;
+ pFuncName = NULL;
+
+ delete pFuncDesc;
+ pFuncDesc = NULL;
+
+ nFIndex = 0;
+ nCategory = 0;
+ nHelpId = 0;
+ bIncomplete = false;
+ bHasSuppressedArgs = false;
+}
+
+//------------------------------------------------------------------------
+
+String ScFuncDesc::GetParamList() const
+{
+ const String& sep = ScCompiler::GetNativeSymbol(ocSep);
+
+ String aSig;
+
+ if ( nArgCount > 0 )
+ {
+ if ( nArgCount < VAR_ARGS )
+ {
+ USHORT nLastSuppressed = nArgCount;
+ USHORT nLastAdded = nArgCount;
+ for ( USHORT i=0; i<nArgCount; i++ )
+ {
+ if (pDefArgFlags[i].bSuppress)
+ nLastSuppressed = i;
+ else
+ {
+ nLastAdded = i;
+ aSig += *(ppDefArgNames[i]);
+ if ( i != nArgCount-1 )
+ {
+ aSig.Append(sep);
+ aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " ));
+ }
+ }
+ }
+ // If only suppressed parameters follow the last added parameter,
+ // remove one "; "
+ if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed &&
+ aSig.Len() >= 2)
+ aSig.Erase( aSig.Len() - 2 );
+ }
+ else
+ {
+ USHORT nFix = nArgCount - VAR_ARGS;
+ for ( USHORT nArg = 0; nArg < nFix; nArg++ )
+ {
+ if (!pDefArgFlags[nArg].bSuppress)
+ {
+ aSig += *(ppDefArgNames[nArg]);
+ aSig.Append(sep);
+ aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " ));
+ }
+ }
+ /* NOTE: Currently there are no suppressed var args parameters. If
+ * there were, we'd have to cope with it here and above for the fix
+ * parameters. For now parameters are always added, so no special
+ * treatment of a trailing "; " necessary. */
+ aSig += *(ppDefArgNames[nFix]);
+ aSig += '1';
+ aSig.Append(sep);
+ aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " ));
+ aSig += *(ppDefArgNames[nFix]);
+ aSig += '2';
+ aSig.Append(sep);
+ aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ... " ));
+ }
+ }
+
+ return aSig;
+}
+
+//------------------------------------------------------------------------
+
+String ScFuncDesc::GetSignature() const
+{
+ String aSig;
+
+ if(pFuncName)
+ {
+ aSig = *pFuncName;
+
+ String aParamList( GetParamList() );
+ if( aParamList.Len() )
+ {
+ aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( " ));
+ aSig.Append( aParamList );
+ // U+00A0 (NBSP) prevents automatic line break
+ aSig.Append( static_cast< sal_Unicode >(0xA0) ).Append( ')' );
+ }
+ else
+ aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
+ }
+ return aSig;
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const
+{
+ const String& sep = ScCompiler::GetNativeSymbol(ocSep);
+
+ ::rtl::OUStringBuffer aFormula;
+
+ if(pFuncName)
+ {
+ aFormula.append( *pFuncName );
+
+ aFormula.appendAscii( "(" );
+ ::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin();
+ ::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end();
+
+ if ( nArgCount > 0 && aIter != aEnd )
+ {
+ BOOL bLastArg = ( aIter->getLength() == 0 );
+
+ while( aIter != aEnd && !bLastArg )
+ {
+ aFormula.append( *(aIter) );
+ if ( aIter != (aEnd-1) )
+ {
+ bLastArg = !( (aIter+1)->getLength() > 0 );
+ if ( !bLastArg )
+ aFormula.append( sep );
+ }
+
+ ++aIter;
+ }
+ }
+
+ aFormula.appendAscii( ")" );
+ }
+ return aFormula.makeStringAndClear();
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScFuncDesc::GetSuppressedArgCount() const
+{
+ if (!bHasSuppressedArgs || !pDefArgFlags)
+ return nArgCount;
+
+ USHORT nArgs = nArgCount;
+ if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
+ USHORT nCount = nArgs;
+ for (USHORT i=0; i < nArgs; ++i)
+ {
+ if (pDefArgFlags[i].bSuppress)
+ --nCount;
+ }
+ if (nArgCount >= VAR_ARGS)
+ nCount += VAR_ARGS - 1;
+ return nCount;
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString ScFuncDesc::getFunctionName() const
+{
+ ::rtl::OUString sRet;
+ if ( pFuncName )
+ sRet = *pFuncName;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionCategory* ScFuncDesc::getCategory() const
+{
+ return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getDescription() const
+{
+ ::rtl::OUString sRet;
+ if ( pFuncDesc )
+ sRet = *pFuncDesc;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+// GetSuppressedArgCount
+xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
+{
+ return GetSuppressedArgCount();
+}
+// -----------------------------------------------------------------------------
+//
+void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<USHORT>& _rArguments) const
+{
+ if (!bHasSuppressedArgs || !pDefArgFlags)
+ {
+ _rArguments.resize( nArgCount);
+ ::std::iota( _rArguments.begin(), _rArguments.end(), 0);
+ }
+
+ _rArguments.reserve( nArgCount);
+ USHORT nArgs = nArgCount;
+ if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
+ for (USHORT i=0; i < nArgs; ++i)
+ {
+ if (!pDefArgFlags[i].bSuppress)
+ _rArguments.push_back(i);
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFuncDesc::initArgumentInfo() const
+{
+ // get the full argument description
+ // (add-in has to be instantiated to get the type information)
+
+ if ( bIncomplete && pFuncName )
+ {
+ ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection();
+ String aIntName = rAddIns.FindFunction( *pFuncName, TRUE ); // pFuncName is upper-case
+
+ if ( aIntName.Len() )
+ {
+ // GetFuncData with bComplete=true loads the component and updates
+ // the global function list if needed.
+
+ rAddIns.GetFuncData( aIntName, true );
+ }
+
+ if ( bIncomplete )
+ {
+ DBG_ERRORFILE( "couldn't initialize add-in function" );
+ const_cast<ScFuncDesc*>(this)->bIncomplete = FALSE; // even if there was an error, don't try again
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getSignature() const
+{
+ return GetSignature();
+}
+// -----------------------------------------------------------------------------
+long ScFuncDesc::getHelpId() const
+{
+ return nHelpId;
+}
+// -----------------------------------------------------------------------------
+
+// parameter
+sal_uInt32 ScFuncDesc::getParameterCount() const
+{
+ return nArgCount;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
+{
+ return *(ppDefArgNames[_nPos]);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
+{
+ return *(ppDefArgDescs[_nPos]);
+}
+// -----------------------------------------------------------------------------
+bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
+{
+ return pDefArgFlags[_nPos].bOptional;
+}
+// -----------------------------------------------------------------------------
+//========================================================================
+// class ScFunctionMgr:
+
+ScFunctionMgr::ScFunctionMgr()
+ : pFuncList ( ScGlobal::GetStarCalcFunctionList() ),
+ pCurCatList ( NULL )
+{
+ DBG_ASSERT( pFuncList, "Funktionsliste nicht gefunden." );
+ ULONG nCount = pFuncList->GetCount();
+ const ScFuncDesc* pDesc;
+ List* pRootList;
+ ULONG n;
+
+ for ( USHORT i=0; i<MAX_FUNCCAT; i++ ) // Kategorie-Listen erstellen
+ aCatLists[i] = new List;
+
+ pRootList = aCatLists[0]; // Gesamtliste ("Alle") erstellen
+ CollatorWrapper* pCaseCollator = ScGlobal::GetCaseCollator();
+ for ( n=0; n<nCount; n++ )
+ {
+ ULONG nTmpCnt=0;
+ pDesc = pFuncList->GetFunction(n);
+ for (nTmpCnt = 0; nTmpCnt < n; nTmpCnt++)
+ {
+ // ist zwar case-sensitiv, aber Umlaute muessen richtig einsortiert werden
+
+ const ScFuncDesc* pTmpDesc = (const ScFuncDesc*)pRootList->GetObject(nTmpCnt);
+ if ( pCaseCollator->compareString(*pDesc->pFuncName, *pTmpDesc->pFuncName ) == COMPARE_LESS )
+ break;
+ }
+ pRootList->Insert((void*)pDesc, nTmpCnt); // Einsortieren
+ }
+
+ for ( n=0; n<nCount; n++ ) // in Gruppenlisten kopieren
+ {
+ pDesc = (const ScFuncDesc*)pRootList->GetObject(n);
+ DBG_ASSERT((pDesc->nCategory) < MAX_FUNCCAT, "Unbekannte Kategorie");
+ if ((pDesc->nCategory) < MAX_FUNCCAT)
+ aCatLists[pDesc->nCategory]->Insert((void*)pDesc, LIST_APPEND);
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionMgr::~ScFunctionMgr()
+{
+ for (USHORT i = 0; i < MAX_FUNCCAT; i++)
+ delete aCatLists[i];
+// delete pFuncList; // Macht spaeter die App
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::Get( const String& rFName ) const
+{
+ const ScFuncDesc* pDesc = NULL;
+ if (rFName.Len() <= pFuncList->GetMaxFuncNameLen())
+ for (pDesc = First(0); pDesc; pDesc = Next())
+ if (rFName.EqualsIgnoreCaseAscii(*(pDesc->pFuncName)))
+ break;
+ return pDesc;
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::Get( USHORT nFIndex ) const
+{
+ const ScFuncDesc* pDesc;
+ for (pDesc = First(0); pDesc; pDesc = Next())
+ if (pDesc->nFIndex == nFIndex)
+ break;
+ return pDesc;
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::First( USHORT nCategory ) const
+{
+ DBG_ASSERT( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" );
+
+ if ( nCategory < MAX_FUNCCAT )
+ {
+ pCurCatList = aCatLists[nCategory];
+ return (const ScFuncDesc*)pCurCatList->First();
+ }
+ else
+ {
+ pCurCatList = NULL;
+ return NULL;
+ }
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::Next() const
+{
+ if ( pCurCatList )
+ return (const ScFuncDesc*)pCurCatList->Next();
+ else
+ return NULL;
+}
+sal_uInt32 ScFunctionMgr::getCount() const
+{
+ return MAX_FUNCCAT - 1;
+}
+const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
+{
+ formula::IFunctionCategory* pRet = NULL;
+ if ( nCategory < (MAX_FUNCCAT-1) )
+ {
+ pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all"
+ }
+ return pRet;
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
+{
+ return Get(_sFunctionName);
+}
+// -----------------------------------------------------------------------------
+void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const
+{
+#define LRU_MAX 10
+
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+ USHORT nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (USHORT)LRU_MAX );
+ USHORT* pLRUListIds = rAppOpt.GetLRUFuncList();
+
+ if ( pLRUListIds )
+ {
+ for ( USHORT i=0; i<nLRUFuncCount; i++ )
+ _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) );
+ }
+}
+// -----------------------------------------------------------------------------
+String ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
+{
+ if ( _nCategoryNumber > SC_FUNCGROUP_COUNT )
+ {
+ DBG_ERROR("Invalid category number!");
+ return String();
+ } // if ( _nCategoryNumber >= SC_FUNCGROUP_COUNT )
+
+ ::std::auto_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) );
+ return String(ScResId((USHORT)_nCategoryNumber));
+}
+sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
+{
+ switch(_eToken)
+ {
+ case eOk:
+ return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0);
+ case eClose:
+ return ScCompiler::GetNativeSymbol(ocClose).GetChar(0);
+ case eSep:
+ return ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ case eArrayOpen:
+ return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0);
+ case eArrayClose:
+ return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0);
+ } // switch(_eToken)
+ return 0;
+}
+// -----------------------------------------------------------------------------
+sal_uInt32 ScFunctionCategory::getCount() const
+{
+ return m_pCategory->Count();
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
+{
+ return m_pMgr;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFunctionCategory::getName() const
+{
+ if ( !m_sName.getLength() )
+ m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1);
+ return m_sName;
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const
+{
+ const ScFuncDesc* pDesc = NULL;
+ sal_uInt32 i = 0;
+ for (pDesc = (const ScFuncDesc*)m_pCategory->First(); i < _nPos && pDesc; pDesc = (const ScFuncDesc*)m_pCategory->Next(),++i)
+ ;
+ return pDesc;
+}
+// -----------------------------------------------------------------------------
+sal_uInt32 ScFunctionCategory::getNumber() const
+{
+ return m_nCategory;
+}
+// -----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------
+
+utl::TransliterationWrapper* ScGlobal::GetpTransliteration() //add by CHINA001
+{
+ if ( !pTransliteration )
+ {
+ const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage();
+ pTransliteration = new ::utl::TransliterationWrapper(
+ ::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_IGNORECASE );
+ pTransliteration->loadModuleIfNeeded( eOfficeLanguage );
+ }
+ DBG_ASSERT(
+ pTransliteration,
+ "ScGlobal::GetpTransliteration() called before ScGlobal::Init()");
+ return pTransliteration;
+}
+
+const LocaleDataWrapper* ScGlobal::GetpLocaleData()
+{
+ DBG_ASSERT(
+ pLocaleData,
+ "ScGlobal::GetpLocaleData() called before ScGlobal::Init()");
+ return pLocaleData;
+}
+CalendarWrapper* ScGlobal::GetCalendar()
+{
+ if ( !pCalendar )
+ {
+ pCalendar = new CalendarWrapper( ::comphelper::getProcessServiceFactory() );
+ pCalendar->loadDefaultCalendar( *GetLocale() );
+ }
+ return pCalendar;
+}
+CollatorWrapper* ScGlobal::GetCollator()
+{
+ if ( !pCollator )
+ {
+ pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
+ pCollator->loadDefaultCollator( *GetLocale(), SC_COLLATOR_IGNORES );
+ } // if ( !pCollator )
+ return pCollator;
+}
+CollatorWrapper* ScGlobal::GetCaseCollator()
+{
+ if ( !pCaseCollator )
+ {
+ pCaseCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
+ pCaseCollator->loadDefaultCollator( *GetLocale(), 0 );
+ } // if ( !pCaseCollator )
+ return pCaseCollator;
+}
+::utl::TransliterationWrapper* ScGlobal::GetCaseTransliteration()
+{
+ if ( !pCaseTransliteration )
+ {
+ const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage();
+ pCaseTransliteration = new ::utl::TransliterationWrapper(::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_CASESENSE );
+ pCaseTransliteration->loadModuleIfNeeded( eOfficeLanguage );
+ } // if ( !pCaseTransliteration )
+ return pCaseTransliteration;
+}
+IntlWrapper* ScGlobal::GetScIntlWrapper()
+{
+ if ( !pScIntlWrapper )
+ {
+ pScIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), *GetLocale() );
+ }
+ return pScIntlWrapper;
+}
+::com::sun::star::lang::Locale* ScGlobal::GetLocale()
+{
+ if ( !pLocale )
+ {
+ pLocale = new ::com::sun::star::lang::Locale( Application::GetSettings().GetLocale());
+ }
+ return pLocale;
+}
+
diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx
new file mode 100644
index 000000000000..3234340ae9dd
--- /dev/null
+++ b/sc/source/core/data/global2.cxx
@@ -0,0 +1,915 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/textsearch.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/charclass.hxx>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unotools/syslocale.hxx>
+
+#include "global.hxx"
+#include "rangeutl.hxx"
+#include "pivot.hxx"
+#include "rechead.hxx"
+#include "compiler.hxx"
+#include "paramisc.hxx"
+// Wang Xu Ming -- 2009-5-18
+// DataPilot Migration
+#include "dpglobal.hxx"
+// End Comments
+
+#include "sc.hrc"
+#include "globstr.hrc"
+
+using ::std::vector;
+
+// -----------------------------------------------------------------------
+
+
+
+
+//------------------------------------------------------------------------
+// struct ScImportParam:
+
+ScImportParam::ScImportParam() :
+ nCol1(0),
+ nRow1(0),
+ nCol2(0),
+ nRow2(0),
+ bImport(FALSE),
+ bNative(FALSE),
+ bSql(TRUE),
+ nType(ScDbTable)
+{
+}
+
+ScImportParam::ScImportParam( const ScImportParam& r ) :
+ nCol1 (r.nCol1),
+ nRow1 (r.nRow1),
+ nCol2 (r.nCol2),
+ nRow2 (r.nRow2),
+ bImport (r.bImport),
+ aDBName (r.aDBName),
+ aStatement (r.aStatement),
+ bNative (r.bNative),
+ bSql (r.bSql),
+ nType (r.nType)
+{
+}
+
+ScImportParam::~ScImportParam()
+{
+}
+
+//UNUSED2009-05 void ScImportParam::Clear()
+//UNUSED2009-05 {
+//UNUSED2009-05 nCol1 = nCol2 = 0;
+//UNUSED2009-05 nRow1 = nRow2 = 0;
+//UNUSED2009-05 bImport = FALSE;
+//UNUSED2009-05 bNative = FALSE;
+//UNUSED2009-05 bSql = TRUE;
+//UNUSED2009-05 nType = ScDbTable;
+//UNUSED2009-05 aDBName.Erase();
+//UNUSED2009-05 aStatement.Erase();
+//UNUSED2009-05 }
+
+ScImportParam& ScImportParam::operator=( const ScImportParam& r )
+{
+ nCol1 = r.nCol1;
+ nRow1 = r.nRow1;
+ nCol2 = r.nCol2;
+ nRow2 = r.nRow2;
+ bImport = r.bImport;
+ aDBName = r.aDBName;
+ aStatement = r.aStatement;
+ bNative = r.bNative;
+ bSql = r.bSql;
+ nType = r.nType;
+
+ return *this;
+}
+
+BOOL ScImportParam::operator==( const ScImportParam& rOther ) const
+{
+ return( nCol1 == rOther.nCol1 &&
+ nRow1 == rOther.nRow1 &&
+ nCol2 == rOther.nCol2 &&
+ nRow2 == rOther.nRow2 &&
+ bImport == rOther.bImport &&
+ aDBName == rOther.aDBName &&
+ aStatement == rOther.aStatement &&
+ bNative == rOther.bNative &&
+ bSql == rOther.bSql &&
+ nType == rOther.nType );
+
+ //! nQuerySh und pConnection sind gleich ?
+}
+
+
+//------------------------------------------------------------------------
+// struct ScQueryParam:
+
+ScQueryEntry::ScQueryEntry() :
+ bDoQuery(FALSE),
+ bQueryByString(FALSE),
+ bQueryByDate(false),
+ nField(0),
+ eOp(SC_EQUAL),
+ eConnect(SC_AND),
+ pStr(new String),
+ nVal(0.0),
+ pSearchParam(NULL),
+ pSearchText(NULL)
+{
+}
+
+ScQueryEntry::ScQueryEntry(const ScQueryEntry& r) :
+ bDoQuery(r.bDoQuery),
+ bQueryByString(r.bQueryByString),
+ bQueryByDate(r.bQueryByDate),
+ nField(r.nField),
+ eOp(r.eOp),
+ eConnect(r.eConnect),
+ pStr(new String(*r.pStr)),
+ nVal(r.nVal),
+ pSearchParam(NULL),
+ pSearchText(NULL)
+{
+}
+
+ScQueryEntry::~ScQueryEntry()
+{
+ delete pStr;
+ if ( pSearchParam )
+ {
+ delete pSearchParam;
+ delete pSearchText;
+ }
+}
+
+ScQueryEntry& ScQueryEntry::operator=( const ScQueryEntry& r )
+{
+ bDoQuery = r.bDoQuery;
+ bQueryByString = r.bQueryByString;
+ bQueryByDate = r.bQueryByDate;
+ eOp = r.eOp;
+ eConnect = r.eConnect;
+ nField = r.nField;
+ nVal = r.nVal;
+ *pStr = *r.pStr;
+ if ( pSearchParam )
+ {
+ delete pSearchParam;
+ delete pSearchText;
+ }
+ pSearchParam = NULL;
+ pSearchText = NULL;
+
+ return *this;
+}
+
+void ScQueryEntry::Clear()
+{
+ bDoQuery = FALSE;
+ bQueryByString = FALSE;
+ bQueryByDate = false;
+ eOp = SC_EQUAL;
+ eConnect = SC_AND;
+ nField = 0;
+ nVal = 0.0;
+ pStr->Erase();
+ if ( pSearchParam )
+ {
+ delete pSearchParam;
+ delete pSearchText;
+ }
+ pSearchParam = NULL;
+ pSearchText = NULL;
+}
+
+BOOL ScQueryEntry::operator==( const ScQueryEntry& r ) const
+{
+ return bDoQuery == r.bDoQuery
+ && bQueryByString == r.bQueryByString
+ && bQueryByDate == r.bQueryByDate
+ && eOp == r.eOp
+ && eConnect == r.eConnect
+ && nField == r.nField
+ && nVal == r.nVal
+ && *pStr == *r.pStr;
+ //! pSearchParam und pSearchText nicht vergleichen
+}
+
+utl::TextSearch* ScQueryEntry::GetSearchTextPtr( BOOL bCaseSens )
+{
+ if ( !pSearchParam )
+ {
+ pSearchParam = new utl::SearchParam( *pStr, utl::SearchParam::SRCH_REGEXP,
+ bCaseSens, FALSE, FALSE );
+ pSearchText = new utl::TextSearch( *pSearchParam, *ScGlobal::pCharClass );
+ }
+ return pSearchText;
+}
+
+//------------------------------------------------------------------------
+// struct ScSubTotalParam:
+
+ScSubTotalParam::ScSubTotalParam()
+{
+ for ( USHORT i=0; i<MAXSUBTOTAL; i++ )
+ {
+ nSubTotals[i] = 0;
+ pSubTotals[i] = NULL;
+ pFunctions[i] = NULL;
+ }
+
+ Clear();
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalParam::ScSubTotalParam( const ScSubTotalParam& r ) :
+ nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),
+ bRemoveOnly(r.bRemoveOnly),bReplace(r.bReplace),bPagebreak(r.bPagebreak),bCaseSens(r.bCaseSens),
+ bDoSort(r.bDoSort),bAscending(r.bAscending),bUserDef(r.bUserDef),nUserIndex(r.nUserIndex),
+ bIncludePattern(r.bIncludePattern)
+{
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ bGroupActive[i] = r.bGroupActive[i];
+ nField[i] = r.nField[i];
+
+ if ( (r.nSubTotals[i] > 0) && r.pSubTotals[i] && r.pFunctions[i] )
+ {
+ nSubTotals[i] = r.nSubTotals[i];
+ pSubTotals[i] = new SCCOL [r.nSubTotals[i]];
+ pFunctions[i] = new ScSubTotalFunc [r.nSubTotals[i]];
+
+ for (SCCOL j=0; j<r.nSubTotals[i]; j++)
+ {
+ pSubTotals[i][j] = r.pSubTotals[i][j];
+ pFunctions[i][j] = r.pFunctions[i][j];
+ }
+ }
+ else
+ {
+ nSubTotals[i] = 0;
+ pSubTotals[i] = NULL;
+ pFunctions[i] = NULL;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScSubTotalParam::Clear()
+{
+ nCol1=nCol2= 0;
+ nRow1=nRow2 = 0;
+ nUserIndex = 0;
+ bPagebreak=bCaseSens=bUserDef=bIncludePattern=bRemoveOnly = FALSE;
+ bAscending=bReplace=bDoSort = TRUE;
+
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ bGroupActive[i] = FALSE;
+ nField[i] = 0;
+
+ if ( (nSubTotals[i] > 0) && pSubTotals[i] && pFunctions[i] )
+ {
+ for ( SCCOL j=0; j<nSubTotals[i]; j++ ) {
+ pSubTotals[i][j] = 0;
+ pFunctions[i][j] = SUBTOTAL_FUNC_NONE;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalParam& ScSubTotalParam::operator=( const ScSubTotalParam& r )
+{
+ nCol1 = r.nCol1;
+ nRow1 = r.nRow1;
+ nCol2 = r.nCol2;
+ nRow2 = r.nRow2;
+ bRemoveOnly = r.bRemoveOnly;
+ bReplace = r.bReplace;
+ bPagebreak = r.bPagebreak;
+ bCaseSens = r.bCaseSens;
+ bDoSort = r.bDoSort;
+ bAscending = r.bAscending;
+ bUserDef = r.bUserDef;
+ nUserIndex = r.nUserIndex;
+ bIncludePattern = r.bIncludePattern;
+
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ bGroupActive[i] = r.bGroupActive[i];
+ nField[i] = r.nField[i];
+ nSubTotals[i] = r.nSubTotals[i];
+
+ if ( pSubTotals[i] ) delete [] pSubTotals[i];
+ if ( pFunctions[i] ) delete [] pFunctions[i];
+
+ if ( r.nSubTotals[i] > 0 )
+ {
+ pSubTotals[i] = new SCCOL [r.nSubTotals[i]];
+ pFunctions[i] = new ScSubTotalFunc [r.nSubTotals[i]];
+
+ for (SCCOL j=0; j<r.nSubTotals[i]; j++)
+ {
+ pSubTotals[i][j] = r.pSubTotals[i][j];
+ pFunctions[i][j] = r.pFunctions[i][j];
+ }
+ }
+ else
+ {
+ nSubTotals[i] = 0;
+ pSubTotals[i] = NULL;
+ pFunctions[i] = NULL;
+ }
+ }
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSubTotalParam::operator==( const ScSubTotalParam& rOther ) const
+{
+ BOOL bEqual = (nCol1 == rOther.nCol1)
+ && (nRow1 == rOther.nRow1)
+ && (nCol2 == rOther.nCol2)
+ && (nRow2 == rOther.nRow2)
+ && (bRemoveOnly == rOther.bRemoveOnly)
+ && (bReplace == rOther.bReplace)
+ && (bPagebreak == rOther.bPagebreak)
+ && (bDoSort == rOther.bDoSort)
+ && (bCaseSens == rOther.bCaseSens)
+ && (bAscending == rOther.bAscending)
+ && (bUserDef == rOther.bUserDef)
+ && (nUserIndex == rOther.nUserIndex)
+ && (bIncludePattern== rOther.bIncludePattern);
+
+ if ( bEqual )
+ {
+ bEqual = TRUE;
+ for ( USHORT i=0; i<MAXSUBTOTAL && bEqual; i++ )
+ {
+ bEqual = (bGroupActive[i] == rOther.bGroupActive[i])
+ && (nField[i] == rOther.nField[i])
+ && (nSubTotals[i] == rOther.nSubTotals[i]);
+
+ if ( bEqual && (nSubTotals[i] > 0) )
+ {
+ bEqual = (pSubTotals != NULL) && (pFunctions != NULL);
+
+ for (SCCOL j=0; (j<nSubTotals[i]) && bEqual; j++)
+ {
+ bEqual = bEqual
+ && (pSubTotals[i][j] == rOther.pSubTotals[i][j])
+ && (pFunctions[i][j] == rOther.pFunctions[i][j]);
+ }
+ }
+ }
+ }
+
+ return bEqual;
+}
+
+//------------------------------------------------------------------------
+
+void ScSubTotalParam::SetSubTotals( USHORT nGroup,
+ const SCCOL* ptrSubTotals,
+ const ScSubTotalFunc* ptrFunctions,
+ USHORT nCount )
+{
+ DBG_ASSERT( (nGroup <= MAXSUBTOTAL),
+ "ScSubTotalParam::SetSubTotals(): nGroup > MAXSUBTOTAL!" );
+ DBG_ASSERT( ptrSubTotals,
+ "ScSubTotalParam::SetSubTotals(): ptrSubTotals == NULL!" );
+ DBG_ASSERT( ptrFunctions,
+ "ScSubTotalParam::SetSubTotals(): ptrFunctions == NULL!" );
+ DBG_ASSERT( (nCount > 0),
+ "ScSubTotalParam::SetSubTotals(): nCount <= 0!" );
+
+ if ( ptrSubTotals && ptrFunctions && (nCount > 0) && (nGroup <= MAXSUBTOTAL) )
+ {
+ // 0 wird als 1 aufgefasst, sonst zum Array-Index dekrementieren
+ if (nGroup != 0)
+ nGroup--;
+
+ delete [] pSubTotals[nGroup];
+ delete [] pFunctions[nGroup];
+
+ pSubTotals[nGroup] = new SCCOL [nCount];
+ pFunctions[nGroup] = new ScSubTotalFunc [nCount];
+ nSubTotals[nGroup] = static_cast<SCCOL>(nCount);
+
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ pSubTotals[nGroup][i] = ptrSubTotals[i];
+ pFunctions[nGroup][i] = ptrFunctions[i];
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// struct ScConsolidateParam:
+
+ScConsolidateParam::ScConsolidateParam() :
+ ppDataAreas( NULL )
+{
+ Clear();
+}
+
+//------------------------------------------------------------------------
+
+ScConsolidateParam::ScConsolidateParam( const ScConsolidateParam& r ) :
+ nCol(r.nCol),nRow(r.nRow),nTab(r.nTab),
+ eFunction(r.eFunction),nDataAreaCount(0),
+ ppDataAreas( NULL ),
+ bByCol(r.bByCol),bByRow(r.bByRow),bReferenceData(r.bReferenceData)
+{
+ if ( r.nDataAreaCount > 0 )
+ {
+ nDataAreaCount = r.nDataAreaCount;
+ ppDataAreas = new ScArea*[nDataAreaCount];
+ for ( USHORT i=0; i<nDataAreaCount; i++ )
+ ppDataAreas[i] = new ScArea( *(r.ppDataAreas[i]) );
+ }
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScConsolidateParam::~ScConsolidateParam()
+{
+ ClearDataAreas();
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScConsolidateParam::ClearDataAreas()
+{
+ if ( ppDataAreas )
+ {
+ for ( USHORT i=0; i<nDataAreaCount; i++ )
+ delete ppDataAreas[i];
+ delete [] ppDataAreas;
+ ppDataAreas = NULL;
+ }
+ nDataAreaCount = 0;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScConsolidateParam::Clear()
+{
+ ClearDataAreas();
+
+ nCol = 0;
+ nRow = 0;
+ nTab = 0;
+ bByCol = bByRow = bReferenceData = FALSE;
+ eFunction = SUBTOTAL_FUNC_SUM;
+}
+
+//------------------------------------------------------------------------
+
+ScConsolidateParam& __EXPORT ScConsolidateParam::operator=( const ScConsolidateParam& r )
+{
+ nCol = r.nCol;
+ nRow = r.nRow;
+ nTab = r.nTab;
+ bByCol = r.bByCol;
+ bByRow = r.bByRow;
+ bReferenceData = r.bReferenceData;
+ eFunction = r.eFunction;
+ SetAreas( r.ppDataAreas, r.nDataAreaCount );
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScConsolidateParam::operator==( const ScConsolidateParam& r ) const
+{
+ BOOL bEqual = (nCol == r.nCol)
+ && (nRow == r.nRow)
+ && (nTab == r.nTab)
+ && (bByCol == r.bByCol)
+ && (bByRow == r.bByRow)
+ && (bReferenceData == r.bReferenceData)
+ && (nDataAreaCount == r.nDataAreaCount)
+ && (eFunction == r.eFunction);
+
+ if ( nDataAreaCount == 0 )
+ bEqual = bEqual && (ppDataAreas == NULL) && (r.ppDataAreas == NULL);
+ else
+ bEqual = bEqual && (ppDataAreas != NULL) && (r.ppDataAreas != NULL);
+
+ if ( bEqual && (nDataAreaCount > 0) )
+ for ( USHORT i=0; i<nDataAreaCount && bEqual; i++ )
+ bEqual = *(ppDataAreas[i]) == *(r.ppDataAreas[i]);
+
+ return bEqual;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScConsolidateParam::SetAreas( ScArea* const* ppAreas, USHORT nCount )
+{
+ ClearDataAreas();
+ if ( ppAreas && nCount > 0 )
+ {
+ ppDataAreas = new ScArea*[nCount];
+ for ( USHORT i=0; i<nCount; i++ )
+ ppDataAreas[i] = new ScArea( *(ppAreas[i]) );
+ nDataAreaCount = nCount;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+PivotField::PivotField( SCsCOL nNewCol, USHORT nNewFuncMask ) :
+ nCol( nNewCol ),
+ nFuncMask( nNewFuncMask ),
+ nFuncCount( 0 )
+{
+}
+
+bool PivotField::operator==( const PivotField& r ) const
+{
+ return (nCol == r.nCol)
+ && (nFuncMask == r.nFuncMask)
+ && (nFuncCount == r.nFuncCount)
+ && (maFieldRef.ReferenceType == r.maFieldRef.ReferenceType)
+ && (maFieldRef.ReferenceField == r.maFieldRef.ReferenceField)
+ && (maFieldRef.ReferenceItemType == r.maFieldRef.ReferenceItemType)
+ && (maFieldRef.ReferenceItemName == r.maFieldRef.ReferenceItemName);
+}
+
+//------------------------------------------------------------------------
+// struct ScPivotParam:
+
+ScPivotParam::ScPivotParam()
+ : nCol(0), nRow(0), nTab(0),
+ nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
+ bIgnoreEmptyRows(FALSE), bDetectCategories(FALSE),
+ bMakeTotalCol(TRUE), bMakeTotalRow(TRUE)
+{
+}
+
+//------------------------------------------------------------------------
+
+ScPivotParam::ScPivotParam( const ScPivotParam& r )
+ : nCol( r.nCol ), nRow( r.nRow ), nTab( r.nTab ),
+ nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
+ bIgnoreEmptyRows(r.bIgnoreEmptyRows),
+ bDetectCategories(r.bDetectCategories),
+ bMakeTotalCol(r.bMakeTotalCol),
+ bMakeTotalRow(r.bMakeTotalRow)
+{
+ SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
+ r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
+
+ SetLabelData(r.maLabelArray);
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScPivotParam::~ScPivotParam()
+{
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2009-05 void __EXPORT ScPivotParam::Clear()
+//UNUSED2009-05 {
+//UNUSED2009-05 nCol = 0;
+//UNUSED2009-05 nRow = 0;
+//UNUSED2009-05 nTab = 0;
+//UNUSED2009-05 bIgnoreEmptyRows = bDetectCategories = FALSE;
+//UNUSED2009-05 bMakeTotalCol = bMakeTotalRow = TRUE;
+//UNUSED2009-05 ClearLabelData();
+//UNUSED2009-05 ClearPivotArrays();
+//UNUSED2009-05 }
+
+void __EXPORT ScPivotParam::ClearPivotArrays()
+{
+ memset( aPageArr, 0, PIVOT_MAXPAGEFIELD * sizeof(PivotField) );
+ memset( aColArr, 0, PIVOT_MAXFIELD * sizeof(PivotField) );
+ memset( aRowArr, 0, PIVOT_MAXFIELD * sizeof(PivotField) );
+ memset( aDataArr, 0, PIVOT_MAXFIELD * sizeof(PivotField) );
+ nPageCount = 0;
+ nColCount = 0;
+ nRowCount = 0;
+ nDataCount = 0;
+}
+
+void ScPivotParam::SetLabelData(const vector<ScDPLabelDataRef>& r)
+{
+ vector<ScDPLabelDataRef> aNewArray;
+ aNewArray.reserve(r.size());
+ for (vector<ScDPLabelDataRef>::const_iterator itr = r.begin(), itrEnd = r.end();
+ itr != itrEnd; ++itr)
+ {
+ ScDPLabelDataRef p(new ScDPLabelData(**itr));
+ aNewArray.push_back(p);
+ }
+ maLabelArray.swap(aNewArray);
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScPivotParam::SetPivotArrays ( const PivotField* pPageArr,
+ const PivotField* pColArr,
+ const PivotField* pRowArr,
+ const PivotField* pDataArr,
+ SCSIZE nPageCnt,
+ SCSIZE nColCnt,
+ SCSIZE nRowCnt,
+ SCSIZE nDataCnt )
+{
+ ClearPivotArrays();
+
+ if ( pPageArr && pColArr && pRowArr && pDataArr )
+ {
+ nPageCount = (nPageCnt>PIVOT_MAXPAGEFIELD) ? PIVOT_MAXPAGEFIELD : nPageCnt;
+ nColCount = (nColCnt>PIVOT_MAXFIELD) ? PIVOT_MAXFIELD : nColCnt;
+ nRowCount = (nRowCnt>PIVOT_MAXFIELD) ? PIVOT_MAXFIELD : nRowCnt;
+ nDataCount = (nDataCnt>PIVOT_MAXFIELD) ? PIVOT_MAXFIELD : nDataCnt;
+
+ memcpy( aPageArr, pPageArr, nPageCount * sizeof(PivotField) );
+ memcpy( aColArr, pColArr, nColCount * sizeof(PivotField) );
+ memcpy( aRowArr, pRowArr, nRowCount * sizeof(PivotField) );
+ memcpy( aDataArr, pDataArr, nDataCount * sizeof(PivotField) );
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScPivotParam& __EXPORT ScPivotParam::operator=( const ScPivotParam& r )
+{
+ nCol = r.nCol;
+ nRow = r.nRow;
+ nTab = r.nTab;
+ bIgnoreEmptyRows = r.bIgnoreEmptyRows;
+ bDetectCategories = r.bDetectCategories;
+ bMakeTotalCol = r.bMakeTotalCol;
+ bMakeTotalRow = r.bMakeTotalRow;
+
+ SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
+ r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
+ SetLabelData(r.maLabelArray);
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScPivotParam::operator==( const ScPivotParam& r ) const
+{
+ BOOL bEqual = (nCol == r.nCol)
+ && (nRow == r.nRow)
+ && (nTab == r.nTab)
+ && (bIgnoreEmptyRows == r.bIgnoreEmptyRows)
+ && (bDetectCategories == r.bDetectCategories)
+ && (bMakeTotalCol == r.bMakeTotalCol)
+ && (bMakeTotalRow == r.bMakeTotalRow)
+ && (maLabelArray.size() == r.maLabelArray.size())
+ && (nPageCount == r.nPageCount)
+ && (nColCount == r.nColCount)
+ && (nRowCount == r.nRowCount)
+ && (nDataCount == r.nDataCount);
+
+ if ( bEqual )
+ {
+ SCSIZE i;
+
+ for ( i=0; i<nPageCount && bEqual; i++ )
+ bEqual = ( aPageArr[i] == r.aPageArr[i] );
+
+ for ( i=0; i<nColCount && bEqual; i++ )
+ bEqual = ( aColArr[i] == r.aColArr[i] );
+
+ for ( i=0; i<nRowCount && bEqual; i++ )
+ bEqual = ( aRowArr[i] == r.aRowArr[i] );
+
+ for ( i=0; i<nDataCount && bEqual; i++ )
+ bEqual = ( aDataArr[i] == r.aDataArr[i] );
+ }
+
+ return bEqual;
+}
+
+//------------------------------------------------------------------------
+// struct ScSolveParam
+
+ScSolveParam::ScSolveParam()
+ : pStrTargetVal( NULL )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScSolveParam::ScSolveParam( const ScSolveParam& r )
+ : aRefFormulaCell ( r.aRefFormulaCell ),
+ aRefVariableCell( r.aRefVariableCell ),
+ pStrTargetVal ( r.pStrTargetVal
+ ? new String(*r.pStrTargetVal)
+ : NULL )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScSolveParam::ScSolveParam( const ScAddress& rFormulaCell,
+ const ScAddress& rVariableCell,
+ const String& rTargetValStr )
+ : aRefFormulaCell ( rFormulaCell ),
+ aRefVariableCell( rVariableCell ),
+ pStrTargetVal ( new String(rTargetValStr) )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScSolveParam::~ScSolveParam()
+{
+ delete pStrTargetVal;
+}
+
+//------------------------------------------------------------------------
+
+ScSolveParam& __EXPORT ScSolveParam::operator=( const ScSolveParam& r )
+{
+ delete pStrTargetVal;
+
+ aRefFormulaCell = r.aRefFormulaCell;
+ aRefVariableCell = r.aRefVariableCell;
+ pStrTargetVal = r.pStrTargetVal
+ ? new String(*r.pStrTargetVal)
+ : NULL;
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSolveParam::operator==( const ScSolveParam& r ) const
+{
+ BOOL bEqual = (aRefFormulaCell == r.aRefFormulaCell)
+ && (aRefVariableCell == r.aRefVariableCell);
+
+ if ( bEqual )
+ {
+ if ( !pStrTargetVal && !r.pStrTargetVal )
+ bEqual = TRUE;
+ else if ( !pStrTargetVal || !r.pStrTargetVal )
+ bEqual = FALSE;
+ else if ( pStrTargetVal && r.pStrTargetVal )
+ bEqual = ( *pStrTargetVal == *(r.pStrTargetVal) );
+ }
+
+ return bEqual;
+}
+
+
+//------------------------------------------------------------------------
+// struct ScTabOpParam
+
+ScTabOpParam::ScTabOpParam( const ScTabOpParam& r )
+ : aRefFormulaCell ( r.aRefFormulaCell ),
+ aRefFormulaEnd ( r.aRefFormulaEnd ),
+ aRefRowCell ( r.aRefRowCell ),
+ aRefColCell ( r.aRefColCell ),
+ nMode ( r.nMode )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScTabOpParam::ScTabOpParam( const ScRefAddress& rFormulaCell,
+ const ScRefAddress& rFormulaEnd,
+ const ScRefAddress& rRowCell,
+ const ScRefAddress& rColCell,
+ BYTE nMd)
+ : aRefFormulaCell ( rFormulaCell ),
+ aRefFormulaEnd ( rFormulaEnd ),
+ aRefRowCell ( rRowCell ),
+ aRefColCell ( rColCell ),
+ nMode ( nMd )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScTabOpParam& ScTabOpParam::operator=( const ScTabOpParam& r )
+{
+ aRefFormulaCell = r.aRefFormulaCell;
+ aRefFormulaEnd = r.aRefFormulaEnd;
+ aRefRowCell = r.aRefRowCell;
+ aRefColCell = r.aRefColCell;
+ nMode = r.nMode;
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScTabOpParam::operator==( const ScTabOpParam& r ) const
+{
+ return ( (aRefFormulaCell == r.aRefFormulaCell)
+ && (aRefFormulaEnd == r.aRefFormulaEnd)
+ && (aRefRowCell == r.aRefRowCell)
+ && (aRefColCell == r.aRefColCell)
+ && (nMode == r.nMode) );
+}
+
+String ScGlobal::GetAbsDocName( const String& rFileName,
+ SfxObjectShell* pShell )
+{
+ String aAbsName;
+ if ( !pShell->HasName() )
+ { // maybe relative to document path working directory
+ INetURLObject aObj;
+ SvtPathOptions aPathOpt;
+ aObj.SetSmartURL( aPathOpt.GetWorkPath() );
+ aObj.setFinalSlash(); // it IS a path
+ bool bWasAbs = true;
+ aAbsName = aObj.smartRel2Abs( rFileName, bWasAbs ).GetMainURL(INetURLObject::NO_DECODE);
+ // returned string must be encoded because it's used directly to create SfxMedium
+ }
+ else
+ {
+ const SfxMedium* pMedium = pShell->GetMedium();
+ if ( pMedium )
+ {
+ bool bWasAbs = true;
+ aAbsName = pMedium->GetURLObject().smartRel2Abs( rFileName, bWasAbs ).GetMainURL(INetURLObject::NO_DECODE);
+ }
+ else
+ { // This can't happen, but ...
+ // just to be sure to have the same encoding
+ INetURLObject aObj;
+ aObj.SetSmartURL( aAbsName );
+ aAbsName = aObj.GetMainURL(INetURLObject::NO_DECODE);
+ }
+ }
+ return aAbsName;
+}
+
+
+String ScGlobal::GetDocTabName( const String& rFileName,
+ const String& rTabName )
+{
+ String aDocTab( '\'' );
+ aDocTab += rFileName;
+ xub_StrLen nPos = 1;
+ while( (nPos = aDocTab.Search( '\'', nPos ))
+ != STRING_NOTFOUND )
+ { // escape Quotes
+ aDocTab.Insert( '\\', nPos );
+ nPos += 2;
+ }
+ aDocTab += '\'';
+ aDocTab += SC_COMPILER_FILE_TAB_SEP;
+ aDocTab += rTabName; // "'Doc'#Tab"
+ return aDocTab;
+}
+
diff --git a/sc/source/core/data/globalx.cxx b/sc/source/core/data/globalx.cxx
new file mode 100644
index 000000000000..2accdadeb781
--- /dev/null
+++ b/sc/source/core/data/globalx.cxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "callform.hxx"
+#include "global.hxx"
+#include <tools/urlobj.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/content.hxx>
+#include <unotools/localfilehelper.hxx>
+
+#include <tools/debug.hxx>
+#include <unotools/pathoptions.hxx>
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+
+#include <com/sun/star/i18n/XOrdinalSuffix.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+
+
+// static
+void ScGlobal::InitAddIns()
+{
+ // multi paths separated by semicolons
+ SvtPathOptions aPathOpt;
+ String aMultiPath = aPathOpt.GetAddinPath();
+ if ( aMultiPath.Len() > 0 )
+ {
+ xub_StrLen nTokens = aMultiPath.GetTokenCount( ';' );
+ xub_StrLen nIndex = 0;
+ for ( xub_StrLen j=0; j<nTokens; j++ )
+ {
+ String aPath( aMultiPath.GetToken( 0, ';', nIndex ) );
+ if ( aPath.Len() > 0 )
+ {
+ // use LocalFileHelper to convert the path to a URL that always points
+ // to the file on the server
+ String aUrl;
+ if ( utl::LocalFileHelper::ConvertPhysicalNameToURL( aPath, aUrl ) )
+ aPath = aUrl;
+
+ INetURLObject aObj;
+ aObj.SetSmartURL( aPath );
+ aObj.setFinalSlash();
+ try
+ {
+ ::ucbhelper::Content aCnt( aObj.GetMainURL(INetURLObject::NO_DECODE),
+ Reference< XCommandEnvironment > () );
+ Reference< sdbc::XResultSet > xResultSet;
+ Sequence< rtl::OUString > aProps;
+ try
+ {
+ xResultSet = aCnt.createCursor(
+ aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY );
+ }
+ catch ( Exception& )
+ {
+ // ucb may throw different exceptions on failure now
+ // no assertion if AddIn directory doesn't exist
+ }
+
+ if ( xResultSet.is() )
+ {
+ Reference< sdbc::XRow > xRow( xResultSet, UNO_QUERY );
+ Reference< XContentAccess >
+ xContentAccess( xResultSet, UNO_QUERY );
+ try
+ {
+ if ( xResultSet->first() )
+ {
+ do
+ {
+ rtl::OUString aId( xContentAccess->queryContentIdentifierString() );
+ InitExternalFunc( aId );
+ }
+ while ( xResultSet->next() );
+ }
+ }
+ catch ( Exception& )
+ {
+ DBG_ERRORFILE( "ResultSetException catched!" );
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ DBG_ERRORFILE( "Exception catched!" );
+ }
+ catch ( ... )
+ {
+
+ DBG_ERRORFILE( "unexpected exception caught!" );
+ }
+ }
+ }
+ }
+}
+
+
+// static
+String ScGlobal::GetOrdinalSuffix( sal_Int32 nNumber)
+{
+ if (!xOrdinalSuffix.is())
+ {
+ try
+ {
+ Reference< lang::XMultiServiceFactory > xServiceManager =
+ ::comphelper::getProcessServiceFactory();
+ Reference< XInterface > xInterface =
+ xServiceManager->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.i18n.OrdinalSuffix"));
+ if (xInterface.is())
+ xOrdinalSuffix = Reference< i18n::XOrdinalSuffix >( xInterface, UNO_QUERY);
+ }
+ catch ( Exception& )
+ {
+ DBG_ERRORFILE( "GetOrdinalSuffix: exception caught during init" );
+ }
+ }
+ DBG_ASSERT( xOrdinalSuffix.is(), "GetOrdinalSuffix: createInstance failed");
+ if (xOrdinalSuffix.is())
+ {
+ try
+ {
+ return xOrdinalSuffix->getOrdinalSuffix( nNumber,
+ ScGlobal::pLocaleData->getLocale());
+ }
+ catch ( Exception& )
+ {
+ DBG_ERRORFILE( "GetOrdinalSuffix: exception caught during getOrdinalSuffix" );
+ }
+ }
+ return String();
+}
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
new file mode 100644
index 000000000000..95ce6bcec179
--- /dev/null
+++ b/sc/source/core/data/makefile.mk
@@ -0,0 +1,179 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=data
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=core_pch
+PROJECTPCHSOURCE=..\pch\core_pch
+
+AUTOSEG=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/attarray.obj \
+ $(SLO)$/attrib.obj \
+ $(SLO)$/autonamecache.obj \
+ $(SLO)$/bcaslot.obj \
+ $(SLO)$/cell.obj \
+ $(SLO)$/cell2.obj \
+ $(SLO)$/clipparam.obj \
+ $(SLO)$/column.obj \
+ $(SLO)$/column2.obj \
+ $(SLO)$/column3.obj \
+ $(SLO)$/compressedarray.obj \
+ $(SLO)$/conditio.obj \
+ $(SLO)$/dbdocutl.obj \
+ $(SLO)$/dociter.obj \
+ $(SLO)$/docpool.obj \
+ $(SLO)$/documen2.obj \
+ $(SLO)$/documen3.obj \
+ $(SLO)$/documen4.obj \
+ $(SLO)$/documen5.obj \
+ $(SLO)$/documen6.obj \
+ $(SLO)$/documen7.obj \
+ $(SLO)$/documen8.obj \
+ $(SLO)$/documen9.obj \
+ $(SLO)$/document.obj \
+ $(SLO)$/dpcachetable.obj \
+ $(SLO)$/dpdimsave.obj \
+ $(SLO)$/dpglobal.obj \
+ $(SLO)$/dpgroup.obj \
+ $(SLO)$/dpobject.obj \
+ $(SLO)$/dpoutput.obj \
+ $(SLO)$/dpoutputgeometry.obj \
+ $(SLO)$/dpsave.obj \
+ $(SLO)$/dpsdbtab.obj \
+ $(SLO)$/dpshttab.obj \
+ $(SLO)$/dptabdat.obj \
+ $(SLO)$/dptabres.obj \
+ $(SLO)$/dptabsrc.obj \
+ $(SLO)$/dptablecache.obj\
+ $(SLO)$/scdpoutputimpl.obj\
+ $(SLO)$/drawpage.obj \
+ $(SLO)$/drwlayer.obj \
+ $(SLO)$/fillinfo.obj \
+ $(SLO)$/global.obj \
+ $(SLO)$/global2.obj \
+ $(SLO)$/globalx.obj \
+ $(SLO)$/markarr.obj \
+ $(SLO)$/markdata.obj \
+ $(SLO)$/olinetab.obj \
+ $(SLO)$/pagepar.obj \
+ $(SLO)$/patattr.obj \
+ $(SLO)$/pivot2.obj \
+ $(SLO)$/poolhelp.obj \
+ $(SLO)$/sheetevents.obj \
+ $(SLO)$/segmenttree.obj \
+ $(SLO)$/sortparam.obj \
+ $(SLO)$/stlpool.obj \
+ $(SLO)$/stlsheet.obj \
+ $(SLO)$/tabbgcolor.obj \
+ $(SLO)$/table1.obj \
+ $(SLO)$/table2.obj \
+ $(SLO)$/table3.obj \
+ $(SLO)$/table4.obj \
+ $(SLO)$/table5.obj \
+ $(SLO)$/table6.obj \
+ $(SLO)$/tabprotection.obj \
+ $(SLO)$/userdat.obj \
+ $(SLO)$/validat.obj \
+ $(SLO)$/postit.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/autonamecache.obj \
+ $(SLO)$/bcaslot.obj \
+ $(SLO)$/cell2.obj \
+ $(SLO)$/clipparam.obj \
+ $(SLO)$/column.obj \
+ $(SLO)$/column3.obj \
+ $(SLO)$/documen2.obj \
+ $(SLO)$/document.obj \
+ $(SLO)$/dpdimsave.obj \
+ $(SLO)$/dpglobal.obj \
+ $(SLO)$/dpgroup.obj \
+ $(SLO)$/dpshttab.obj \
+ $(SLO)$/dptabres.obj \
+ $(SLO)$/dptabdat.obj \
+ $(SLO)$/global2.obj \
+ $(SLO)$/tabbgcolor.obj \
+ $(SLO)$/table1.obj \
+ $(SLO)$/table2.obj \
+ $(SLO)$/table3.obj \
+ $(SLO)$/tabprotection.obj \
+ $(SLO)$/postit.obj \
+ $(SLO)$/documen3.obj \
+ $(SLO)$/documen5.obj \
+ $(SLO)$/documen6.obj \
+ $(SLO)$/documen9.obj \
+ $(SLO)$/dpcachetable.obj \
+ $(SLO)$/dptablecache.obj \
+ $(SLO)$/scdpoutputimpl.obj \
+ $(SLO)$/dpsdbtab.obj \
+ $(SLO)$/dpobject.obj \
+ $(SLO)$/dpoutput.obj \
+ $(SLO)$/dpoutputgeometry.obj \
+ $(SLO)$/dpsave.obj \
+ $(SLO)$/dbdocutl.obj \
+ $(SLO)$/dptabsrc.obj \
+ $(SLO)$/drwlayer.obj \
+ $(SLO)$/globalx.obj \
+ $(SLO)$/segmenttree.obj
+
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
+NOOPTFILES= \
+ $(SLO)$/column2.obj \
+ $(SLO)$/column3.obj \
+ $(SLO)$/table3.obj \
+ $(SLO)$/table4.obj \
+ $(SLO)$/documen4.obj \
+ $(SLO)$/conditio.obj \
+ $(SLO)$/validat.obj
+EXCEPTIONSNOOPTFILES= \
+ $(SLO)$/cell.obj
+.ELSE
+EXCEPTIONSFILES+= \
+ $(SLO)$/cell.obj \
+ $(SLO)$/global.obj \
+ $(SLO)$/table5.obj
+.ENDIF
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/core/data/markarr.cxx b/sc/source/core/data/markarr.cxx
new file mode 100644
index 000000000000..aeca394437cd
--- /dev/null
+++ b/sc/source/core/data/markarr.cxx
@@ -0,0 +1,410 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+
+#include "markarr.hxx"
+#include "global.hxx"
+#include "address.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+//------------------------------------------------------------------------
+
+ScMarkArray::ScMarkArray() :
+ nCount( 0 ),
+ nLimit( 0 ),
+ pData( NULL )
+{
+ // special case "no marks" with pData = NULL
+}
+
+//------------------------------------------------------------------------
+
+ScMarkArray::~ScMarkArray()
+{
+ delete[] pData;
+}
+
+//------------------------------------------------------------------------
+
+void ScMarkArray::Reset( BOOL bMarked )
+{
+ // always create pData here
+ // (or have separate method to ensure pData)
+
+ delete[] pData;
+
+ nCount = nLimit = 1;
+ pData = new ScMarkEntry[1];
+ pData[0].nRow = MAXROW;
+ pData[0].bMarked = bMarked;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
+{
+ long nLo = 0;
+ long nHi = static_cast<long>(nCount) - 1;
+ long nStartRow = 0;
+ long nEndRow = 0;
+ long i = 0;
+ BOOL bFound = (nCount == 1);
+ if (pData)
+ {
+ while ( !bFound && nLo <= nHi )
+ {
+ i = (nLo + nHi) / 2;
+ if (i > 0)
+ nStartRow = (long) pData[i - 1].nRow;
+ else
+ nStartRow = -1;
+ nEndRow = (long) pData[i].nRow;
+ if (nEndRow < (long) nRow)
+ nLo = ++i;
+ else
+ if (nStartRow >= (long) nRow)
+ nHi = --i;
+ else
+ bFound = TRUE;
+ }
+ }
+ else
+ bFound = FALSE;
+
+ if (bFound)
+ nIndex=(SCSIZE)i;
+ else
+ nIndex=0;
+ return bFound;
+}
+
+BOOL ScMarkArray::GetMark( SCROW nRow ) const
+{
+ SCSIZE i;
+ if (Search( nRow, i ))
+ return pData[i].bMarked;
+ else
+ return FALSE;
+
+}
+
+//------------------------------------------------------------------------
+
+void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, BOOL bMarked )
+{
+ if (ValidRow(nStartRow) && ValidRow(nEndRow))
+ {
+ if ((nStartRow == 0) && (nEndRow == MAXROW))
+ {
+ Reset(bMarked);
+ }
+ else
+ {
+ if (!pData)
+ Reset(FALSE); // create pData for further processing - could use special case handling!
+
+ SCSIZE nNeeded = nCount + 2;
+ if ( nLimit < nNeeded )
+ {
+ nLimit += SC_MARKARRAY_DELTA;
+ if ( nLimit < nNeeded )
+ nLimit = nNeeded;
+ ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
+ memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
+ delete[] pData;
+ pData = pNewData;
+ }
+
+ SCSIZE ni; // number of entries in beginning
+ SCSIZE nInsert; // insert position (MAXROW+1 := no insert)
+ BOOL bCombined = FALSE;
+ BOOL bSplit = FALSE;
+ if ( nStartRow > 0 )
+ {
+ // skip beginning
+ SCSIZE nIndex;
+ Search( nStartRow, nIndex );
+ ni = nIndex;
+
+ nInsert = MAXROWCOUNT;
+ if ( pData[ni].bMarked != bMarked )
+ {
+ if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
+ { // may be a split or a simple insert or just a shrink,
+ // row adjustment is done further down
+ if ( pData[ni].nRow > nEndRow )
+ bSplit = TRUE;
+ ni++;
+ nInsert = ni;
+ }
+ else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
+ nInsert = ni;
+ }
+ if ( ni > 0 && pData[ni-1].bMarked == bMarked )
+ { // combine
+ pData[ni-1].nRow = nEndRow;
+ nInsert = MAXROWCOUNT;
+ bCombined = TRUE;
+ }
+ }
+ else
+ {
+ nInsert = 0;
+ ni = 0;
+ }
+
+ SCSIZE nj = ni; // stop position of range to replace
+ while ( nj < nCount && pData[nj].nRow <= nEndRow )
+ nj++;
+ if ( !bSplit )
+ {
+ if ( nj < nCount && pData[nj].bMarked == bMarked )
+ { // combine
+ if ( ni > 0 )
+ {
+ if ( pData[ni-1].bMarked == bMarked )
+ { // adjacent entries
+ pData[ni-1].nRow = pData[nj].nRow;
+ nj++;
+ }
+ else if ( ni == nInsert )
+ pData[ni-1].nRow = nStartRow - 1; // shrink
+ }
+ nInsert = MAXROWCOUNT;
+ bCombined = TRUE;
+ }
+ else if ( ni > 0 && ni == nInsert )
+ pData[ni-1].nRow = nStartRow - 1; // shrink
+ }
+ if ( ni < nj )
+ { // remove middle entries
+ if ( !bCombined )
+ { // replace one entry
+ pData[ni].nRow = nEndRow;
+ pData[ni].bMarked = bMarked;
+ ni++;
+ nInsert = MAXROWCOUNT;
+ }
+ if ( ni < nj )
+ { // remove entries
+ memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
+ nCount -= nj - ni;
+ }
+ }
+
+ if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+ { // insert or append new entry
+ if ( nInsert <= nCount )
+ {
+ if ( !bSplit )
+ memmove( pData + nInsert + 1, pData + nInsert,
+ (nCount - nInsert) * sizeof(ScMarkEntry) );
+ else
+ {
+ memmove( pData + nInsert + 2, pData + nInsert,
+ (nCount - nInsert) * sizeof(ScMarkEntry) );
+ pData[nInsert+1] = pData[nInsert-1];
+ nCount++;
+ }
+ }
+ if ( nInsert )
+ pData[nInsert-1].nRow = nStartRow - 1;
+ pData[nInsert].nRow = nEndRow;
+ pData[nInsert].bMarked = bMarked;
+ nCount++;
+ }
+ }
+ }
+// InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
+}
+
+//UNUSED2009-05 void ScMarkArray::DeleteArea(SCROW nStartRow, SCROW nEndRow)
+//UNUSED2009-05 {
+//UNUSED2009-05 SetMarkArea(nStartRow, nEndRow, FALSE);
+//UNUSED2009-05 }
+
+BOOL ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
+{
+ SCSIZE nStartIndex;
+ SCSIZE nEndIndex;
+
+ if (Search( nStartRow, nStartIndex ))
+ if (pData[nStartIndex].bMarked)
+ if (Search( nEndRow, nEndIndex ))
+ if (nEndIndex==nStartIndex)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
+{
+ BOOL bRet = FALSE;
+ if ( nCount == 1 )
+ {
+ if ( pData[0].bMarked )
+ {
+ rStartRow = 0;
+ rEndRow = MAXROW;
+ bRet = TRUE;
+ }
+ }
+ else if ( nCount == 2 )
+ {
+ if ( pData[0].bMarked )
+ {
+ rStartRow = 0;
+ rEndRow = pData[0].nRow;
+ }
+ else
+ {
+ rStartRow = pData[0].nRow + 1;
+ rEndRow = MAXROW;
+ }
+ bRet = TRUE;
+ }
+ else if ( nCount == 3 )
+ {
+ if ( pData[1].bMarked )
+ {
+ rStartRow = pData[0].nRow + 1;
+ rEndRow = pData[1].nRow;
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
+{
+ delete[] rDestMarkArray.pData;
+
+ if (pData)
+ {
+ rDestMarkArray.pData = new ScMarkEntry[nCount];
+ memmove( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
+ }
+ else
+ rDestMarkArray.pData = NULL;
+
+ rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
+}
+
+SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, BOOL bUp ) const
+{
+ if (!pData)
+ const_cast<ScMarkArray*>(this)->Reset(FALSE); // create pData for further processing
+
+ SCsROW nRet = nRow;
+ if (VALIDROW(nRow))
+ {
+ SCSIZE nIndex;
+ Search(nRow, nIndex);
+ if (!pData[nIndex].bMarked)
+ {
+ if (bUp)
+ {
+ if (nIndex>0)
+ nRet = pData[nIndex-1].nRow;
+ else
+ nRet = -1;
+ }
+ else
+ nRet = pData[nIndex].nRow + 1;
+ }
+ }
+ return nRet;
+}
+
+SCROW ScMarkArray::GetMarkEnd( SCROW nRow, BOOL bUp ) const
+{
+ if (!pData)
+ const_cast<ScMarkArray*>(this)->Reset(FALSE); // create pData for further processing
+
+ SCROW nRet;
+ SCSIZE nIndex;
+ Search(nRow, nIndex);
+ DBG_ASSERT( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
+ if (bUp)
+ {
+ if (nIndex>0)
+ nRet = pData[nIndex-1].nRow + 1;
+ else
+ nRet = 0;
+ }
+ else
+ nRet = pData[nIndex].nRow;
+
+ return nRet;
+}
+
+//
+// -------------- Iterator ----------------------------------------------
+//
+
+ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
+ pArray( pNewArray ),
+ nPos( 0 )
+{
+}
+
+ScMarkArrayIter::~ScMarkArrayIter()
+{
+}
+
+BOOL ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
+{
+ if ( nPos >= pArray->nCount )
+ return FALSE;
+ while (!pArray->pData[nPos].bMarked)
+ {
+ ++nPos;
+ if ( nPos >= pArray->nCount )
+ return FALSE;
+ }
+ rBottom = pArray->pData[nPos].nRow;
+ if (nPos==0)
+ rTop = 0;
+ else
+ rTop = pArray->pData[nPos-1].nRow + 1;
+ ++nPos;
+ return TRUE;
+}
+
+
+
+
+
diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx
new file mode 100644
index 000000000000..4401ac19d199
--- /dev/null
+++ b/sc/source/core/data/markdata.cxx
@@ -0,0 +1,608 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+
+#include "markdata.hxx"
+#include "markarr.hxx"
+#include "rangelst.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+//------------------------------------------------------------------------
+
+ScMarkData::ScMarkData() :
+ pMultiSel( NULL )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ bTabMarked[i] = FALSE;
+
+ ResetMark();
+}
+
+ScMarkData::ScMarkData(const ScMarkData& rData) :
+ aMarkRange( rData.aMarkRange ),
+ aMultiRange( rData.aMultiRange ),
+ pMultiSel( NULL )
+{
+ bMarked = rData.bMarked;
+ bMultiMarked = rData.bMultiMarked;
+ bMarking = rData.bMarking;
+ bMarkIsNeg = rData.bMarkIsNeg;
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ bTabMarked[i] = rData.bTabMarked[i];
+
+ if (rData.pMultiSel)
+ {
+ pMultiSel = new ScMarkArray[MAXCOLCOUNT];
+ for (SCCOL j=0; j<MAXCOLCOUNT; j++)
+ rData.pMultiSel[j].CopyMarksTo( pMultiSel[j] );
+ }
+}
+
+ScMarkData& ScMarkData::operator=(const ScMarkData& rData)
+{
+ if ( &rData == this )
+ return *this;
+
+ delete[] pMultiSel;
+ pMultiSel = NULL;
+
+ aMarkRange = rData.aMarkRange;
+ aMultiRange = rData.aMultiRange;
+ bMarked = rData.bMarked;
+ bMultiMarked = rData.bMultiMarked;
+ bMarking = rData.bMarking;
+ bMarkIsNeg = rData.bMarkIsNeg;
+
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ bTabMarked[i] = rData.bTabMarked[i];
+
+ if (rData.pMultiSel)
+ {
+ pMultiSel = new ScMarkArray[MAXCOLCOUNT];
+ for (SCCOL j=0; j<MAXCOLCOUNT; j++)
+ rData.pMultiSel[j].CopyMarksTo( pMultiSel[j] );
+ }
+
+ return *this;
+}
+
+ScMarkData::~ScMarkData()
+{
+ delete[] pMultiSel;
+}
+
+void ScMarkData::ResetMark()
+{
+ delete[] pMultiSel;
+ pMultiSel = NULL;
+
+ bMarked = bMultiMarked = FALSE;
+ bMarking = bMarkIsNeg = FALSE;
+}
+
+void ScMarkData::SetMarkArea( const ScRange& rRange )
+{
+ aMarkRange = rRange;
+ aMarkRange.Justify();
+ if ( !bMarked )
+ {
+ // #77987# Upon creation of a document ScFormatShell GetTextAttrState
+ // may query (default) attributes although no sheet is marked yet.
+ // => mark that one.
+ if ( !GetSelectCount() )
+ bTabMarked[ aMarkRange.aStart.Tab() ] = TRUE;
+ bMarked = TRUE;
+ }
+}
+
+void ScMarkData::GetMarkArea( ScRange& rRange ) const
+{
+ rRange = aMarkRange; //! inline ?
+}
+
+void ScMarkData::GetMultiMarkArea( ScRange& rRange ) const
+{
+ rRange = aMultiRange;
+}
+
+void ScMarkData::SetMultiMarkArea( const ScRange& rRange, BOOL bMark )
+{
+ if (!pMultiSel)
+ {
+ pMultiSel = new ScMarkArray[MAXCOL+1];
+
+ // if simple mark range is set, copy to multi marks
+ if ( bMarked && !bMarkIsNeg )
+ {
+ bMarked = FALSE;
+ SetMultiMarkArea( aMarkRange, TRUE );
+ }
+ }
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartCol, nEndCol );
+
+ SCCOL nCol;
+ for (nCol=nStartCol; nCol<=nEndCol; nCol++)
+ pMultiSel[nCol].SetMarkArea( nStartRow, nEndRow, bMark );
+
+ if ( bMultiMarked ) // aMultiRange updaten
+ {
+ if ( nStartCol < aMultiRange.aStart.Col() )
+ aMultiRange.aStart.SetCol( nStartCol );
+ if ( nStartRow < aMultiRange.aStart.Row() )
+ aMultiRange.aStart.SetRow( nStartRow );
+ if ( nEndCol > aMultiRange.aEnd.Col() )
+ aMultiRange.aEnd.SetCol( nEndCol );
+ if ( nEndRow > aMultiRange.aEnd.Row() )
+ aMultiRange.aEnd.SetRow( nEndRow );
+ }
+ else
+ {
+ aMultiRange = rRange; // neu
+ bMultiMarked = TRUE;
+ }
+}
+
+void ScMarkData::SetAreaTab( SCTAB nTab )
+{
+ aMarkRange.aStart.SetTab(nTab);
+ aMarkRange.aEnd.SetTab(nTab);
+ aMultiRange.aStart.SetTab(nTab);
+ aMultiRange.aEnd.SetTab(nTab);
+}
+
+void ScMarkData::SelectOneTable( SCTAB nTab )
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ bTabMarked[i] = ( nTab == i );
+}
+
+SCTAB ScMarkData::GetSelectCount() const
+{
+ SCTAB nCount = 0;
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (bTabMarked[i])
+ ++nCount;
+
+ return nCount;
+}
+
+SCTAB ScMarkData::GetFirstSelected() const
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (bTabMarked[i])
+ return i;
+
+ DBG_ERROR("GetFirstSelected: keine markiert");
+ return 0;
+}
+
+void ScMarkData::MarkToMulti()
+{
+ if ( bMarked && !bMarking )
+ {
+ SetMultiMarkArea( aMarkRange, !bMarkIsNeg );
+ bMarked = FALSE;
+
+ // check if all multi mark ranges have been removed
+ if ( bMarkIsNeg && !HasAnyMultiMarks() )
+ ResetMark();
+ }
+}
+
+void ScMarkData::MarkToSimple()
+{
+ if ( bMarking )
+ return;
+
+ if ( bMultiMarked && bMarked )
+ MarkToMulti(); // may result in bMarked and bMultiMarked reset
+
+ if ( bMultiMarked )
+ {
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+
+ ScRange aNew = aMultiRange;
+
+ BOOL bOk = FALSE;
+ SCCOL nStartCol = aNew.aStart.Col();
+ SCCOL nEndCol = aNew.aEnd.Col();
+
+ while ( nStartCol < nEndCol && !pMultiSel[nStartCol].HasMarks() )
+ ++nStartCol;
+ while ( nStartCol < nEndCol && !pMultiSel[nEndCol].HasMarks() )
+ --nEndCol;
+
+ // Zeilen werden nur aus MarkArray genommen
+ SCROW nStartRow, nEndRow;
+ if ( pMultiSel[nStartCol].HasOneMark( nStartRow, nEndRow ) )
+ {
+ bOk = TRUE;
+ SCROW nCmpStart, nCmpEnd;
+ for (SCCOL nCol=nStartCol+1; nCol<=nEndCol && bOk; nCol++)
+ if ( !pMultiSel[nCol].HasOneMark( nCmpStart, nCmpEnd )
+ || nCmpStart != nStartRow || nCmpEnd != nEndRow )
+ bOk = FALSE;
+ }
+
+ if (bOk)
+ {
+ aNew.aStart.SetCol(nStartCol);
+ aNew.aStart.SetRow(nStartRow);
+ aNew.aEnd.SetCol(nEndCol);
+ aNew.aEnd.SetRow(nEndRow);
+
+ ResetMark();
+ aMarkRange = aNew;
+ bMarked = TRUE;
+ bMarkIsNeg = FALSE;
+ }
+ }
+}
+
+BOOL ScMarkData::IsCellMarked( SCCOL nCol, SCROW nRow, BOOL bNoSimple ) const
+{
+ if ( bMarked && !bNoSimple && !bMarkIsNeg )
+ if ( aMarkRange.aStart.Col() <= nCol && aMarkRange.aEnd.Col() >= nCol &&
+ aMarkRange.aStart.Row() <= nRow && aMarkRange.aEnd.Row() >= nRow )
+ return TRUE;
+
+ if (bMultiMarked)
+ {
+ //! hier auf negative Markierung testen ?
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+ return pMultiSel[nCol].GetMark( nRow );
+ }
+
+ return FALSE;
+}
+
+BOOL ScMarkData::IsColumnMarked( SCCOL nCol ) const
+{
+ // bMarkIsNeg inzwischen auch fuer Spaltenkoepfe
+ //! GetMarkColumnRanges fuer komplett markierte Spalten
+
+ if ( bMarked && !bMarkIsNeg &&
+ aMarkRange.aStart.Col() <= nCol && aMarkRange.aEnd.Col() >= nCol &&
+ aMarkRange.aStart.Row() == 0 && aMarkRange.aEnd.Row() == MAXROW )
+ return TRUE;
+
+ if ( bMultiMarked && pMultiSel[nCol].IsAllMarked(0,MAXROW) )
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL ScMarkData::IsRowMarked( SCROW nRow ) const
+{
+ // bMarkIsNeg inzwischen auch fuer Zeilenkoepfe
+ //! GetMarkRowRanges fuer komplett markierte Zeilen
+
+ if ( bMarked && !bMarkIsNeg &&
+ aMarkRange.aStart.Col() == 0 && aMarkRange.aEnd.Col() == MAXCOL &&
+ aMarkRange.aStart.Row() <= nRow && aMarkRange.aEnd.Row() >= nRow )
+ return TRUE;
+
+ if ( bMultiMarked )
+ {
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+ for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
+ if (!pMultiSel[nCol].GetMark(nRow))
+ return FALSE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ScMarkData::MarkFromRangeList( const ScRangeList& rList, BOOL bReset )
+{
+ if (bReset)
+ {
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ bTabMarked[i] = FALSE; // Tabellen sind nicht in ResetMark
+ ResetMark();
+ }
+
+ ULONG nCount = rList.Count();
+ if ( nCount == 1 && !bMarked && !bMultiMarked )
+ {
+ ScRange aRange = *rList.GetObject(0);
+ SetMarkArea( aRange );
+ SelectTable( aRange.aStart.Tab(), TRUE );
+ }
+ else
+ {
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *rList.GetObject(i);
+ SetMultiMarkArea( aRange, TRUE );
+ SelectTable( aRange.aStart.Tab(), TRUE );
+ }
+ }
+}
+
+void ScMarkData::FillRangeListWithMarks( ScRangeList* pList, BOOL bClear ) const
+{
+ if (!pList)
+ return;
+
+ if (bClear)
+ pList->RemoveAll();
+
+ //! bei mehreren selektierten Tabellen mehrere Ranges eintragen !!!
+
+ if ( bMultiMarked )
+ {
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+
+ SCTAB nTab = aMultiRange.aStart.Tab();
+
+ SCCOL nStartCol = aMultiRange.aStart.Col();
+ SCCOL nEndCol = aMultiRange.aEnd.Col();
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
+ if (pMultiSel[nCol].HasMarks())
+ {
+ SCROW nTop, nBottom;
+ ScRange aRange( nCol, 0, nTab );
+ ScMarkArrayIter aMarkIter( &pMultiSel[nCol] );
+ while ( aMarkIter.Next( nTop, nBottom ) )
+ {
+ aRange.aStart.SetRow( nTop );
+ aRange.aEnd.SetRow( nBottom );
+ pList->Join( aRange );
+ }
+ }
+ }
+
+ if ( bMarked )
+ pList->Append( aMarkRange );
+}
+
+void ScMarkData::ExtendRangeListTables( ScRangeList* pList ) const
+{
+ if (!pList)
+ return;
+
+ ScRangeList aOldList(*pList);
+ pList->RemoveAll(); //! oder die vorhandenen unten weglassen
+
+ for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
+ if (bTabMarked[nTab])
+ {
+ ULONG nCount = aOldList.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *aOldList.GetObject(i);
+ aRange.aStart.SetTab(nTab);
+ aRange.aEnd.SetTab(nTab);
+ pList->Append( aRange );
+ }
+ }
+}
+
+SCCOLROW ScMarkData::GetMarkColumnRanges( SCCOLROW* pRanges )
+{
+ if (bMarked)
+ MarkToMulti();
+
+ if (!bMultiMarked)
+ return 0;
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, but pMultiSel == 0");
+
+ const SCCOLROW nMultiStart = aMultiRange.aStart.Col();
+ const SCCOLROW nMultiEnd = aMultiRange.aEnd.Col();
+ if (nMultiStart == 0 && nMultiEnd == MAXCOL)
+ {
+ // One or more entire rows.
+ pRanges[0] = 0;
+ pRanges[1] = MAXCOL;
+ return 1;
+ }
+
+ SCCOLROW nRangeCnt = 0;
+ SCCOLROW nStart = nMultiStart;
+ while (nStart <= nMultiEnd)
+ {
+ while (nStart < nMultiEnd && !pMultiSel[nStart].HasMarks())
+ ++nStart;
+ if (pMultiSel[nStart].HasMarks())
+ {
+ SCCOLROW nEnd = nStart;
+ while (nEnd < nMultiEnd && pMultiSel[nEnd].HasMarks())
+ ++nEnd;
+ if (!pMultiSel[nEnd].HasMarks())
+ --nEnd;
+ pRanges[2*nRangeCnt ] = nStart;
+ pRanges[2*nRangeCnt+1] = nEnd;
+ ++nRangeCnt;
+ nStart = nEnd+1;
+ }
+ else
+ nStart = nMultiEnd+1;
+ }
+
+ return nRangeCnt;
+}
+
+SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges )
+{
+ if (bMarked)
+ MarkToMulti();
+
+ if (!bMultiMarked)
+ return 0;
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, but pMultiSel == 0");
+
+ // Which rows are marked?
+
+ // Optimized to not loop over MAXCOL*MAXROW as worst case, i.e. Ctrl+A
+
+ const SCCOLROW nMultiStart = aMultiRange.aStart.Row();
+ const SCCOLROW nMultiEnd = aMultiRange.aEnd.Row();
+
+ BOOL* bRowMarked = new BOOL[MAXROWCOUNT];
+ memset( bRowMarked, 0, sizeof(BOOL) * MAXROWCOUNT);
+ SCROW nRow;
+ SCCOL nCol;
+
+ SCROW nTop = -1, nBottom = -1;
+ for (nCol = aMultiRange.aStart.Col(); nCol <= aMultiRange.aEnd.Col(); ++nCol)
+ {
+ ScMarkArrayIter aMarkIter( &pMultiSel[nCol] );
+ while (aMarkIter.Next( nTop, nBottom ))
+ for (nRow=nTop; nRow<=nBottom; nRow++)
+ bRowMarked[nRow] = TRUE;
+ if (nTop == nMultiStart && nBottom == nMultiEnd)
+ break; // for, all relevant rows marked
+ }
+
+ if (nTop == nMultiStart && nBottom == nMultiEnd)
+ {
+ pRanges[0] = nTop;
+ pRanges[1] = nBottom;
+ delete[] bRowMarked;
+ return 1;
+ }
+
+ // Combine to ranges of rows.
+
+ SCCOLROW nRangeCnt = 0;
+ SCCOLROW nStart = nMultiStart;
+ while (nStart <= nMultiEnd)
+ {
+ while (nStart < nMultiEnd && !bRowMarked[nStart])
+ ++nStart;
+ if (bRowMarked[nStart])
+ {
+ SCCOLROW nEnd = nStart;
+ while (nEnd < nMultiEnd && bRowMarked[nEnd])
+ ++nEnd;
+ if (!bRowMarked[nEnd])
+ --nEnd;
+ pRanges[2*nRangeCnt ] = nStart;
+ pRanges[2*nRangeCnt+1] = nEnd;
+ ++nRangeCnt;
+ nStart = nEnd+1;
+ }
+ else
+ nStart = nMultiEnd+1;
+ }
+
+ delete[] bRowMarked;
+ return nRangeCnt;
+}
+
+BOOL ScMarkData::IsAllMarked( const ScRange& rRange ) const
+{
+ if ( !bMultiMarked )
+ return FALSE;
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ BOOL bOk = TRUE;
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol && bOk; nCol++)
+ if ( !pMultiSel[nCol].IsAllMarked( nStartRow, nEndRow ) )
+ bOk = FALSE;
+
+ return bOk;
+}
+
+SCsROW ScMarkData::GetNextMarked( SCCOL nCol, SCsROW nRow, BOOL bUp ) const
+{
+ if ( !bMultiMarked )
+ return nRow;
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+
+ return pMultiSel[nCol].GetNextMarked( nRow, bUp );
+}
+
+BOOL ScMarkData::HasMultiMarks( SCCOL nCol ) const
+{
+ if ( !bMultiMarked )
+ return FALSE;
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+
+ return pMultiSel[nCol].HasMarks();
+}
+
+BOOL ScMarkData::HasAnyMultiMarks() const
+{
+ if ( !bMultiMarked )
+ return FALSE;
+
+ DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+
+ for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
+ if ( pMultiSel[nCol].HasMarks() )
+ return TRUE;
+
+ return FALSE; // nix
+}
+
+void ScMarkData::InsertTab( SCTAB nTab )
+{
+ for (SCTAB i=MAXTAB; i>nTab; i--)
+ bTabMarked[i] = bTabMarked[i-1];
+ bTabMarked[nTab] = FALSE;
+}
+
+void ScMarkData::DeleteTab( SCTAB nTab )
+{
+ for (SCTAB i=nTab; i<MAXTAB; i++)
+ bTabMarked[i] = bTabMarked[i+1];
+ bTabMarked[MAXTAB] = FALSE;
+}
+
+
+
+
+
diff --git a/sc/source/core/data/olinetab.cxx b/sc/source/core/data/olinetab.cxx
new file mode 100644
index 000000000000..af444c4b2123
--- /dev/null
+++ b/sc/source/core/data/olinetab.cxx
@@ -0,0 +1,806 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+#include <tools/debug.hxx>
+#include <limits.h>
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "olinetab.hxx"
+#include "global.hxx"
+#include "rechead.hxx"
+#include "address.hxx"
+#include "table.hxx"
+
+//------------------------------------------------------------------------
+
+ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
+ nStart ( nNewStart ),
+ nSize ( nNewSize ),
+ bHidden ( bNewHidden ),
+ bVisible( TRUE )
+{
+}
+
+ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
+ ScDataObject(),
+ nStart ( rEntry.nStart ),
+ nSize ( rEntry.nSize ),
+ bHidden ( rEntry.bHidden ),
+ bVisible( rEntry.bVisible )
+{
+}
+
+ScDataObject* ScOutlineEntry::Clone() const
+{
+ return new ScOutlineEntry( *this );
+}
+
+void ScOutlineEntry::Move( SCsCOLROW nDelta )
+{
+ SCCOLROW nNewPos = nStart + nDelta;
+ if (nNewPos<0)
+ {
+ DBG_ERROR("OutlineEntry < 0");
+ nNewPos = 0;
+ }
+ nStart = nNewPos;
+}
+
+void ScOutlineEntry::SetSize( SCSIZE nNewSize )
+{
+ if (nNewSize>0)
+ nSize = nNewSize;
+ else
+ {
+ DBG_ERROR("ScOutlineEntry Size == 0");
+ }
+}
+
+void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
+{
+ nStart = nNewPos;
+ SetSize( nNewSize );
+}
+
+void ScOutlineEntry::SetHidden( bool bNewHidden )
+{
+ bHidden = bNewHidden;
+}
+
+void ScOutlineEntry::SetVisible( bool bNewVisible )
+{
+ bVisible = bNewVisible;
+}
+
+//------------------------------------------------------------------------
+
+ScOutlineCollection::ScOutlineCollection() :
+ ScSortedCollection( 4,4,FALSE )
+{
+}
+
+inline short IntCompare( SCCOLROW nX, SCCOLROW nY )
+{
+ if ( nX==nY ) return 0;
+ else if ( nX<nY ) return -1;
+ else return 1;
+}
+
+short ScOutlineCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return IntCompare( ((ScOutlineEntry*)pKey1)->GetStart(),
+ ((ScOutlineEntry*)pKey2)->GetStart() );
+}
+
+USHORT ScOutlineCollection::FindStart( SCCOLROW nMinStart )
+{
+ //! binaer suchen ?
+
+ USHORT nPos = 0;
+ USHORT nLocalCount = GetCount();
+ while ( (nPos<nLocalCount) ? (((ScOutlineEntry*)At(nPos))->GetStart() < nMinStart) : FALSE )
+ ++nPos;
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------
+
+ScOutlineArray::ScOutlineArray() :
+ nDepth( 0 )
+{
+}
+
+ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
+ nDepth( rArray.nDepth )
+{
+ for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
+ {
+ USHORT nCount = rArray.aCollections[nLevel].GetCount();
+ for (USHORT nEntry=0; nEntry<nCount; nEntry++)
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) rArray.aCollections[nLevel].At(nEntry);
+ aCollections[nLevel].Insert( new ScOutlineEntry( *pEntry ) );
+ }
+ }
+}
+
+void ScOutlineArray::FindEntry( SCCOLROW nSearchPos, USHORT& rFindLevel, USHORT& rFindIndex,
+ USHORT nMaxLevel )
+{
+ rFindLevel = rFindIndex = 0;
+
+ if (nMaxLevel > nDepth)
+ nMaxLevel = nDepth;
+
+ for (USHORT nLevel=0; nLevel<nMaxLevel; nLevel++) //! rueckwaerts suchen ?
+ {
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ if ( pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos )
+ {
+ rFindLevel = nLevel + 1; // naechster Level (zum Einfuegen)
+ rFindIndex = i;
+ }
+ }
+ }
+}
+
+BOOL ScOutlineArray::Insert( SCCOLROW nStartCol, SCCOLROW nEndCol, BOOL& rSizeChanged,
+ BOOL bHidden, BOOL bVisible )
+{
+ rSizeChanged = FALSE;
+
+ USHORT nStartLevel;
+ USHORT nStartIndex;
+ USHORT nEndLevel;
+ USHORT nEndIndex;
+ BOOL bFound = FALSE;
+
+ BOOL bCont;
+ USHORT nFindMax;
+ FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = neuer Level (alter+1) !!!
+ FindEntry( nEndCol, nEndLevel, nEndIndex );
+ nFindMax = Max(nStartLevel,nEndLevel);
+ do
+ {
+ bCont = FALSE;
+
+ if ( nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH )
+ bFound = TRUE;
+
+ if (!bFound)
+ {
+ if (nFindMax>0)
+ {
+ --nFindMax;
+ if (nStartLevel)
+ if ( ((ScOutlineEntry*)aCollections[nStartLevel-1].At(nStartIndex))->
+ GetStart() == nStartCol )
+ FindEntry( nStartCol, nStartLevel, nStartIndex, nFindMax );
+ if (nEndLevel)
+ if ( ((ScOutlineEntry*)aCollections[nEndLevel-1].At(nEndIndex))->
+ GetEnd() == nEndCol )
+ FindEntry( nEndCol, nEndLevel, nEndIndex, nFindMax );
+ bCont = TRUE;
+ }
+ }
+ }
+ while ( !bFound && bCont );
+
+ if (!bFound)
+ return FALSE;
+
+ USHORT nLevel = nStartLevel;
+
+ // untere verschieben
+
+ BOOL bNeedSize = FALSE;
+ for ( short nMoveLevel = nDepth-1; nMoveLevel >= (short) nLevel; nMoveLevel-- )
+ {
+ USHORT nCount = aCollections[nMoveLevel].GetCount();
+ BOOL bMoved = FALSE;
+ for ( USHORT i=0; i<nCount; i += bMoved ? 0 : 1 )
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) aCollections[nMoveLevel].At(i);
+ SCCOLROW nEntryStart = pEntry->GetStart();
+ if ( nEntryStart >= nStartCol && nEntryStart <= nEndCol )
+ {
+ if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
+ {
+ rSizeChanged = FALSE; // kein Platz
+ return FALSE;
+ }
+ aCollections[nMoveLevel+1].Insert( new ScOutlineEntry( *pEntry ) );
+ aCollections[nMoveLevel].AtFree( i );
+ nCount = aCollections[nMoveLevel].GetCount();
+ bMoved = TRUE;
+ if (nMoveLevel == (short) nDepth - 1)
+ bNeedSize = TRUE;
+ }
+ else
+ bMoved = FALSE;
+ }
+ }
+
+ if (bNeedSize)
+ {
+ ++nDepth;
+ rSizeChanged = TRUE;
+ }
+
+ if (nDepth <= nLevel)
+ {
+ nDepth = nLevel+1;
+ rSizeChanged = TRUE;
+ }
+
+/* nicht zusammenfassen!
+
+ // zusammenfassen
+
+ USHORT nCount = aCollections[nLevel].GetCount();
+ USHORT nIndex;
+ bFound = FALSE;
+ for ( nIndex=0; nIndex<nCount && !bFound; nIndex++ )
+ {
+ if ( ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetEnd() + 1 == nStartCol )
+ {
+ nStartCol = ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetStart();
+ aCollections[nLevel].AtFree(nIndex);
+ nCount = aCollections[nLevel].GetCount(); // Daten geaendert
+ bFound = TRUE;
+ }
+ }
+
+ bFound = FALSE;
+ for ( nIndex=0; nIndex<nCount && !bFound; nIndex++ )
+ {
+ if ( ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetStart() == nEndCol + 1 )
+ {
+ nEndCol = ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetEnd();
+ aCollections[nLevel].AtFree(nIndex);
+ bFound = TRUE;
+ }
+ }
+*/
+ ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
+ pNewEntry->SetVisible( bVisible );
+ aCollections[nLevel].Insert( pNewEntry );
+
+ return TRUE;
+}
+
+BOOL ScOutlineArray::FindTouchedLevel( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rFindLevel ) const
+{
+ BOOL bFound = FALSE;
+ rFindLevel = 0;
+
+ for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
+ {
+ const ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
+ ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
+ {
+ rFindLevel = nLevel; // wirklicher Level
+ bFound = TRUE;
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScOutlineArray::RemoveSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nLevel )
+{
+ if ( nLevel >= nDepth )
+ return;
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ BOOL bFound = FALSE;
+ for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
+ {
+ bFound = FALSE;
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( nStart>=nStartPos && nEnd<=nEndPos )
+ {
+ RemoveSub( nStart, nEnd, nLevel+1 );
+ pCollect->AtFree(i);
+ nCount = pCollect->GetCount();
+ bFound = TRUE;
+ }
+ }
+}
+
+void ScOutlineArray::PromoteSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nStartLevel )
+{
+ if (nStartLevel==0)
+ {
+ DBG_ERROR("PromoteSub mit Level 0");
+ return;
+ }
+
+ for (USHORT nLevel = nStartLevel; nLevel < nDepth; nLevel++)
+ {
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ BOOL bFound = FALSE;
+ for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
+ {
+ bFound = FALSE;
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( nStart>=nStartPos && nEnd<=nEndPos )
+ {
+ aCollections[nLevel-1].Insert( new ScOutlineEntry( *pEntry ) );
+ pCollect->AtFree(i);
+ nCount = pCollect->GetCount();
+ bFound = TRUE;
+ }
+ }
+ }
+}
+
+BOOL ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
+{
+ BOOL bChanged = FALSE;
+ BOOL bCont;
+ do
+ {
+ bCont = FALSE;
+ if (nDepth)
+ if (aCollections[nDepth-1].GetCount() == 0)
+ {
+ --nDepth;
+ bChanged = TRUE;
+ bCont = TRUE;
+ }
+ }
+ while (bCont);
+ return bChanged;
+}
+
+BOOL ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, BOOL& rSizeChanged )
+{
+ USHORT nLevel;
+ FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
+
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ BOOL bFound = FALSE;
+ BOOL bAny = FALSE;
+ for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
+ {
+ bFound = FALSE;
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( nBlockStart<=nEnd && nBlockEnd>=nStart )
+ {
+// RemoveSub( nStart, nEnd, nLevel+1 );
+ pCollect->AtFree(i);
+ PromoteSub( nStart, nEnd, nLevel+1 );
+ nCount = pCollect->GetCount();
+ i = pCollect->FindStart( nEnd+1 );
+ bFound = TRUE;
+ bAny = TRUE;
+ }
+ }
+
+ if (bAny) // Depth anpassen
+ if (DecDepth())
+ rSizeChanged = TRUE;
+
+ return bAny;
+}
+
+ScOutlineEntry* ScOutlineArray::GetEntry( USHORT nLevel, USHORT nIndex ) const
+{
+ return (ScOutlineEntry*)((nLevel < nDepth) ? aCollections[nLevel].At(nIndex) : NULL);
+}
+
+USHORT ScOutlineArray::GetCount( USHORT nLevel ) const
+{
+ return (nLevel < nDepth) ? aCollections[nLevel].GetCount() : 0;
+}
+
+ScOutlineEntry* ScOutlineArray::GetEntryByPos( USHORT nLevel, SCCOLROW nPos ) const
+{
+ USHORT nCount = GetCount( nLevel );
+ ScOutlineEntry* pEntry;
+
+ for (USHORT nIndex = 0; nIndex < nCount; nIndex++)
+ {
+ pEntry = GetEntry( nLevel, nIndex );
+ if ((pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()))
+ return pEntry;
+ }
+ return NULL;
+}
+
+BOOL ScOutlineArray::GetEntryIndex( USHORT nLevel, SCCOLROW nPos, USHORT& rnIndex ) const
+{
+ // found entry contains passed position
+ USHORT nCount = GetCount( nLevel );
+ for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
+ {
+ const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
+ if ( (pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ScOutlineArray::GetEntryIndexInRange(
+ USHORT nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rnIndex ) const
+{
+ // found entry will be completely inside of passed range
+ USHORT nCount = GetCount( nLevel );
+ for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
+ {
+ const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
+ if ( (nBlockStart <= pEntry->GetStart()) && (pEntry->GetEnd() <= nBlockEnd) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ScOutlineArray::SetVisibleBelow( USHORT nLevel, USHORT nEntry, BOOL bValue, BOOL bSkipHidden )
+{
+ ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
+ if( pEntry )
+ {
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ for (USHORT nSubLevel=nLevel+1; nSubLevel<nDepth; nSubLevel++)
+ {
+ USHORT i = 0;
+ pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
+ while (pEntry)
+ {
+ if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
+ {
+ pEntry->SetVisible(bValue);
+
+ if (bSkipHidden)
+ if (!pEntry->IsHidden())
+ SetVisibleBelow( nSubLevel, i, bValue, TRUE );
+ }
+
+ ++i;
+ pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
+ }
+
+ if (bSkipHidden)
+ nSubLevel = nDepth; // Abbruch
+ }
+ }
+}
+
+void ScOutlineArray::GetRange( SCCOLROW& rStart, SCCOLROW& rEnd ) const
+{
+ USHORT nCount = aCollections[0].GetCount();
+ if (nCount)
+ {
+ rStart = ((ScOutlineEntry*) aCollections[0].At(0))->GetStart();
+ rEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
+ }
+ else
+ rStart = rEnd = 0;
+}
+
+void ScOutlineArray::ExtendBlock( USHORT nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd )
+{
+ USHORT nCount;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ USHORT i;
+ ScOutlineEntry* pEntry;
+
+ nCount = GetCount(nLevel);
+ for ( i=0; i<nCount; i++ )
+ {
+ pEntry = (ScOutlineEntry*) aCollections[nLevel].At(i);
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+
+ if ( rBlkStart<=nEnd && rBlkEnd>=nStart )
+ {
+ if (nStart<rBlkStart) rBlkStart = nStart;
+ if (nEnd>rBlkEnd) rBlkEnd = nEnd;
+ }
+ }
+}
+
+BOOL ScOutlineArray::TestInsertSpace( SCSIZE nSize, SCCOLROW nMaxVal ) const
+{
+ USHORT nCount = aCollections[0].GetCount();
+ if (nCount)
+ {
+ SCCOLROW nEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
+ return ( sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal );
+ }
+
+ return TRUE;
+}
+
+void ScOutlineArray::InsertSpace( SCCOLROW nStartPos, SCSIZE nSize )
+{
+ ScSubOutlineIterator aIter( this );
+ ScOutlineEntry* pEntry;
+ while((pEntry=aIter.GetNext())!=NULL)
+ {
+ if ( pEntry->GetStart() >= nStartPos )
+ pEntry->Move(static_cast<SCsCOLROW>(nSize));
+ else
+ {
+ SCCOLROW nEnd = pEntry->GetEnd();
+ // immer erweitern, wenn innerhalb der Gruppe eingefuegt
+ // beim Einfuegen am Ende nur, wenn die Gruppe nicht ausgeblendet ist
+ if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
+ {
+ SCSIZE nEntrySize = pEntry->GetSize();
+ nEntrySize += nSize;
+ pEntry->SetSize( nEntrySize );
+ }
+ }
+ }
+}
+
+BOOL ScOutlineArray::DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize )
+{
+ SCCOLROW nEndPos = nStartPos + nSize - 1;
+ BOOL bNeedSave = FALSE; // Original fuer Undo benoetigt?
+ BOOL bChanged = FALSE; // fuer Test auf Level
+
+ ScSubOutlineIterator aIter( this );
+ ScOutlineEntry* pEntry;
+ while((pEntry=aIter.GetNext())!=NULL)
+ {
+ SCCOLROW nEntryStart = pEntry->GetStart();
+ SCCOLROW nEntryEnd = pEntry->GetEnd();
+ SCSIZE nEntrySize = pEntry->GetSize();
+
+ if ( nEntryEnd >= nStartPos )
+ {
+ if ( nEntryStart > nEndPos ) // rechts
+ pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
+ else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // aussen
+ pEntry->SetSize( nEntrySize-nSize );
+ else
+ {
+ bNeedSave = TRUE;
+ if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // innen
+ {
+ aIter.DeleteLast();
+ bChanged = TRUE;
+ }
+ else if ( nEntryStart >= nStartPos ) // rechts ueber
+ pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
+ else // links ueber
+ pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
+ }
+ }
+ }
+
+ if (bChanged)
+ DecDepth();
+
+ return bNeedSave;
+}
+
+bool ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, ScTable& rTable, bool bCol )
+{
+ bool bModified = false;
+ ScSubOutlineIterator aIter( this );
+ ScOutlineEntry* pEntry;
+ while((pEntry=aIter.GetNext())!=NULL)
+ {
+ SCCOLROW nEntryStart = pEntry->GetStart();
+ SCCOLROW nEntryEnd = pEntry->GetEnd();
+
+ if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
+ {
+ if ( pEntry->IsHidden() == bShow )
+ {
+ // #i12341# hide if all columns/rows are hidden, show if at least one
+ // is visible
+ SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
+ bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
+ ::std::numeric_limits<SCCOLROW>::max());
+
+ bool bToggle = ( bShow != bAllHidden );
+ if ( bToggle )
+ {
+ pEntry->SetHidden( !bShow );
+ SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
+ bModified = true;
+ }
+ }
+ }
+ }
+ return bModified;
+}
+
+void ScOutlineArray::RemoveAll()
+{
+ for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
+ aCollections[nLevel].FreeAll();
+
+ nDepth = 0;
+}
+
+//------------------------------------------------------------------------
+
+ScOutlineTable::ScOutlineTable()
+{
+}
+
+ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
+ aColOutline( rOutline.aColOutline ),
+ aRowOutline( rOutline.aRowOutline )
+{
+}
+
+BOOL ScOutlineTable::TestInsertCol( SCSIZE nSize )
+{
+ return aColOutline.TestInsertSpace( nSize, MAXCOL );
+}
+
+void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
+{
+ aColOutline.InsertSpace( nStartCol, nSize );
+}
+
+BOOL ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
+{
+ return aColOutline.DeleteSpace( nStartCol, nSize );
+}
+
+BOOL ScOutlineTable::TestInsertRow( SCSIZE nSize )
+{
+ return aRowOutline.TestInsertSpace( nSize, MAXROW );
+}
+
+void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
+{
+ aRowOutline.InsertSpace( nStartRow, nSize );
+}
+
+BOOL ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
+{
+ return aRowOutline.DeleteSpace( nStartRow, nSize );
+}
+
+//------------------------------------------------------------------------
+
+ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
+ pArray( pOutlineArray ),
+ nStart( 0 ),
+ nEnd( SCCOLROW_MAX ), // alle durchgehen
+ nSubLevel( 0 ),
+ nSubEntry( 0 )
+{
+ nDepth = pArray->nDepth;
+}
+
+ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray,
+ USHORT nLevel, USHORT nEntry ) :
+ pArray( pOutlineArray )
+{
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pArray->aCollections[nLevel].At(nEntry);
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ nSubLevel = nLevel + 1;
+ nSubEntry = 0;
+ nDepth = pArray->nDepth;
+}
+
+ScOutlineEntry* ScSubOutlineIterator::GetNext()
+{
+ ScOutlineEntry* pEntry;
+ BOOL bFound = FALSE;
+ do
+ {
+ if (nSubLevel >= nDepth)
+ return NULL;
+
+ pEntry = (ScOutlineEntry*) pArray->aCollections[nSubLevel].At(nSubEntry);
+ if (!pEntry)
+ {
+ nSubEntry = 0;
+ ++nSubLevel;
+ }
+ else
+ {
+ if ( pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd )
+ bFound = TRUE;
+ ++nSubEntry;
+ }
+ }
+ while (!bFound);
+ return pEntry; // nSubLevel gueltig, wenn pEntry != 0
+}
+
+USHORT ScSubOutlineIterator::LastLevel() const
+{
+ return nSubLevel;
+}
+
+USHORT ScSubOutlineIterator::LastEntry() const
+{
+ if (nSubEntry == 0)
+ {
+ DBG_ERROR("ScSubOutlineIterator::LastEntry vor GetNext");
+ return 0;
+ }
+ return nSubEntry-1;
+}
+
+void ScSubOutlineIterator::DeleteLast()
+{
+ if (nSubLevel >= nDepth)
+ {
+ DBG_ERROR("ScSubOutlineIterator::DeleteLast nach Ende");
+ return;
+ }
+ if (nSubEntry == 0)
+ {
+ DBG_ERROR("ScSubOutlineIterator::DeleteLast vor GetNext");
+ return;
+ }
+
+ --nSubEntry;
+ pArray->aCollections[nSubLevel].AtFree(nSubEntry);
+}
+
+
diff --git a/sc/source/core/data/pagepar.cxx b/sc/source/core/data/pagepar.cxx
new file mode 100644
index 000000000000..318f5c19501b
--- /dev/null
+++ b/sc/source/core/data/pagepar.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+// System - Includes -----------------------------------------------------
+
+
+
+#include <string.h>
+
+#include "pagepar.hxx"
+
+
+//========================================================================
+// struct ScPageTableParam:
+
+ScPageTableParam::ScPageTableParam()
+{
+ Reset();
+}
+
+//------------------------------------------------------------------------
+
+ScPageTableParam::~ScPageTableParam()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScPageTableParam::Reset()
+{
+ bCellContent = TRUE;
+ bNotes=bGrid=bHeaders=bDrawings=
+ bLeftRight=bScaleAll=bScaleTo=bScalePageNum=
+ bFormulas=bNullVals=bSkipEmpty = FALSE;
+ bTopDown=bScaleNone=bCharts=bObjects = TRUE;
+ nScaleAll = 100;
+ nScalePageNum = nScaleWidth = nScaleHeight = 0;
+ nFirstPageNo = 1;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScPageTableParam::operator==( const ScPageTableParam& r ) const
+{
+ return ( memcmp( this, &r, sizeof(ScPageTableParam) ) == 0 );
+}
+
+//========================================================================
+// struct ScPageAreaParam:
+
+ScPageAreaParam::ScPageAreaParam()
+{
+ Reset();
+}
+
+//------------------------------------------------------------------------
+
+ScPageAreaParam::~ScPageAreaParam()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScPageAreaParam::Reset()
+{
+ bPrintArea = bRepeatRow = bRepeatCol = FALSE;
+
+ memset( &aPrintArea, 0, sizeof(ScRange) );
+ memset( &aRepeatRow, 0, sizeof(ScRange) );
+ memset( &aRepeatCol, 0, sizeof(ScRange) );
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScPageAreaParam::operator==( const ScPageAreaParam& r ) const
+{
+ BOOL bEqual =
+ bPrintArea == r.bPrintArea
+ && bRepeatRow == r.bRepeatRow
+ && bRepeatCol == r.bRepeatCol;
+
+ if ( bEqual )
+ if ( bPrintArea )
+ bEqual = bEqual && ( aPrintArea == r.aPrintArea );
+ if ( bEqual )
+ if ( bRepeatRow )
+ bEqual = bEqual && ( aRepeatRow == r.aRepeatRow );
+ if ( bEqual )
+ if ( bRepeatCol )
+ bEqual = bEqual && ( aRepeatCol == r.aRepeatCol );
+
+ return bEqual;
+}
diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
new file mode 100644
index 000000000000..b66aea63dd05
--- /dev/null
+++ b/sc/source/core/data/patattr.cxx
@@ -0,0 +1,1347 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/postitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/svapp.hxx>
+
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "conditio.hxx"
+#include "validat.hxx"
+#include "scmod.hxx"
+#include "fillinfo.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+ScDocument* ScPatternAttr::pDoc = NULL;
+
+// -----------------------------------------------------------------------
+
+//! move to some header file
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+
+// -----------------------------------------------------------------------
+
+ScPatternAttr::ScPatternAttr( SfxItemSet* pItemSet, const String& rStyleName )
+ : SfxSetItem ( ATTR_PATTERN, pItemSet ),
+ pName ( new String( rStyleName ) ),
+ pStyle ( NULL )
+{
+}
+
+ScPatternAttr::ScPatternAttr( SfxItemSet* pItemSet, ScStyleSheet* pStyleSheet )
+ : SfxSetItem ( ATTR_PATTERN, pItemSet ),
+ pName ( NULL ),
+ pStyle ( pStyleSheet )
+{
+ if ( pStyleSheet )
+ GetItemSet().SetParent( &pStyleSheet->GetItemSet() );
+}
+
+ScPatternAttr::ScPatternAttr( SfxItemPool* pItemPool )
+ : SfxSetItem ( ATTR_PATTERN, new SfxItemSet( *pItemPool, ATTR_PATTERN_START, ATTR_PATTERN_END ) ),
+ pName ( NULL ),
+ pStyle ( NULL )
+{
+}
+
+ScPatternAttr::ScPatternAttr( const ScPatternAttr& rPatternAttr )
+ : SfxSetItem ( rPatternAttr ),
+ pStyle ( rPatternAttr.pStyle )
+{
+ if (rPatternAttr.pName)
+ pName = new String(*rPatternAttr.pName);
+ else
+ pName = NULL;
+}
+
+__EXPORT ScPatternAttr::~ScPatternAttr()
+{
+ delete pName;
+}
+
+SfxPoolItem* __EXPORT ScPatternAttr::Clone( SfxItemPool *pPool ) const
+{
+ ScPatternAttr* pPattern = new ScPatternAttr( GetItemSet().Clone(TRUE, pPool) );
+
+ pPattern->pStyle = pStyle;
+ pPattern->pName = pName ? new String(*pName) : NULL;
+
+ return pPattern;
+}
+
+inline int StrCmp( const String* pStr1, const String* pStr2 )
+{
+ return ( pStr1 ? ( pStr2 ? ( *pStr1 == *pStr2 ) : FALSE ) : ( pStr2 ? FALSE : TRUE ) );
+}
+
+inline bool EqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 )
+{
+ // #i62090# The SfxItemSet in the SfxSetItem base class always has the same ranges
+ // (single range from ATTR_PATTERN_START to ATTR_PATTERN_END), and the items are pooled,
+ // so it's enough to compare just the pointers (Count just because it's even faster).
+
+ if ( rSet1.Count() != rSet2.Count() )
+ return false;
+
+ SfxItemArray pItems1 = rSet1.GetItems_Impl(); // inline method of SfxItemSet
+ SfxItemArray pItems2 = rSet2.GetItems_Impl();
+
+ return ( 0 == memcmp( pItems1, pItems2, (ATTR_PATTERN_END - ATTR_PATTERN_START + 1) * sizeof(pItems1[0]) ) );
+}
+
+int __EXPORT ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const
+{
+ // #i62090# Use quick comparison between ScPatternAttr's ItemSets
+
+ return ( EqualPatternSets( GetItemSet(), static_cast<const ScPatternAttr&>(rCmp).GetItemSet() ) &&
+ StrCmp( GetStyleName(), static_cast<const ScPatternAttr&>(rCmp).GetStyleName() ) );
+}
+
+SfxPoolItem* __EXPORT ScPatternAttr::Create( SvStream& rStream, USHORT /* nVersion */ ) const
+{
+ String* pStr;
+ BOOL bHasStyle;
+ short eFamDummy;
+
+ rStream >> bHasStyle;
+
+ if ( bHasStyle )
+ {
+ pStr = new String;
+ rStream.ReadByteString( *pStr, rStream.GetStreamCharSet() );
+ rStream >> eFamDummy; // wg. altem Dateiformat
+ }
+ else
+ pStr = new String( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
+
+ SfxItemSet *pNewSet = new SfxItemSet( *GetItemSet().GetPool(),
+ ATTR_PATTERN_START, ATTR_PATTERN_END );
+ pNewSet->Load( rStream );
+
+ ScPatternAttr* pPattern = new ScPatternAttr( pNewSet );
+
+ pPattern->pName = pStr;
+
+ return pPattern;
+}
+
+SvStream& __EXPORT ScPatternAttr::Store(SvStream& rStream, USHORT /* nItemVersion */) const
+{
+ rStream << (BOOL)TRUE;
+
+ if ( pStyle )
+ rStream.WriteByteString( pStyle->GetName(), rStream.GetStreamCharSet() );
+ else if ( pName ) // wenn Style geloescht ist/war
+ rStream.WriteByteString( *pName, rStream.GetStreamCharSet() );
+ else
+ rStream.WriteByteString( ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
+ rStream.GetStreamCharSet() );
+
+ rStream << (short)SFX_STYLE_FAMILY_PARA; // wg. altem Dateiformat
+
+ GetItemSet().Store( rStream );
+
+ return rStream;
+}
+
+SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
+{
+ SvxCellOrientation eOrient = SVX_ORIENTATION_STANDARD;
+
+ if( ((const SfxBoolItem&)GetItem( ATTR_STACKED, rItemSet, pCondSet )).GetValue() )
+ {
+ eOrient = SVX_ORIENTATION_STACKED;
+ }
+ else
+ {
+ INT32 nAngle = ((const SfxInt32Item&)GetItem( ATTR_ROTATE_VALUE, rItemSet, pCondSet )).GetValue();
+ if( nAngle == 9000 )
+ eOrient = SVX_ORIENTATION_BOTTOMTOP;
+ else if( nAngle == 27000 )
+ eOrient = SVX_ORIENTATION_TOPBOTTOM;
+ }
+
+ return eOrient;
+}
+
+SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet* pCondSet ) const
+{
+ return GetCellOrientation( GetItemSet(), pCondSet );
+}
+
+void ScPatternAttr::GetFont(
+ Font& rFont, const SfxItemSet& rItemSet, ScAutoFontColorMode eAutoMode,
+ OutputDevice* pOutDev, const Fraction* pScale,
+ const SfxItemSet* pCondSet, BYTE nScript,
+ const Color* pBackConfigColor, const Color* pTextConfigColor )
+{
+ // Items auslesen
+
+ const SvxFontItem* pFontAttr;
+ UINT32 nFontHeight;
+ FontWeight eWeight;
+ FontItalic eItalic;
+ FontUnderline eUnder;
+ FontUnderline eOver;
+ BOOL bWordLine;
+ FontStrikeout eStrike;
+ BOOL bOutline;
+ BOOL bShadow;
+ FontEmphasisMark eEmphasis;
+ FontRelief eRelief;
+ Color aColor;
+ LanguageType eLang;
+
+ USHORT nFontId, nHeightId, nWeightId, nPostureId, nLangId;
+ if ( nScript == SCRIPTTYPE_ASIAN )
+ {
+ nFontId = ATTR_CJK_FONT;
+ nHeightId = ATTR_CJK_FONT_HEIGHT;
+ nWeightId = ATTR_CJK_FONT_WEIGHT;
+ nPostureId = ATTR_CJK_FONT_POSTURE;
+ nLangId = ATTR_CJK_FONT_LANGUAGE;
+ }
+ else if ( nScript == SCRIPTTYPE_COMPLEX )
+ {
+ nFontId = ATTR_CTL_FONT;
+ nHeightId = ATTR_CTL_FONT_HEIGHT;
+ nWeightId = ATTR_CTL_FONT_WEIGHT;
+ nPostureId = ATTR_CTL_FONT_POSTURE;
+ nLangId = ATTR_CTL_FONT_LANGUAGE;
+ }
+ else
+ {
+ nFontId = ATTR_FONT;
+ nHeightId = ATTR_FONT_HEIGHT;
+ nWeightId = ATTR_FONT_WEIGHT;
+ nPostureId = ATTR_FONT_POSTURE;
+ nLangId = ATTR_FONT_LANGUAGE;
+ }
+
+ if ( pCondSet )
+ {
+ const SfxPoolItem* pItem;
+
+ if ( pCondSet->GetItemState( nFontId, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( nFontId );
+ pFontAttr = (const SvxFontItem*) pItem;
+
+ if ( pCondSet->GetItemState( nHeightId, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( nHeightId );
+ nFontHeight = ((const SvxFontHeightItem*)pItem)->GetHeight();
+
+ if ( pCondSet->GetItemState( nWeightId, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( nWeightId );
+ eWeight = (FontWeight)((const SvxWeightItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( nPostureId, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( nPostureId );
+ eItalic = (FontItalic)((const SvxPostureItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_UNDERLINE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_UNDERLINE );
+ eUnder = (FontUnderline)((const SvxUnderlineItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_OVERLINE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_OVERLINE );
+ eOver = (FontUnderline)((const SvxOverlineItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_WORDLINE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_WORDLINE );
+ bWordLine = ((const SvxWordLineModeItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_CROSSEDOUT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_CROSSEDOUT );
+ eStrike = (FontStrikeout)((const SvxCrossedOutItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_CONTOUR, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_CONTOUR );
+ bOutline = ((const SvxContourItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_SHADOWED, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_SHADOWED );
+ bShadow = ((const SvxShadowedItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_EMPHASISMARK, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_EMPHASISMARK );
+ eEmphasis = ((const SvxEmphasisMarkItem*)pItem)->GetEmphasisMark();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_RELIEF, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_RELIEF );
+ eRelief = (FontRelief)((const SvxCharReliefItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_COLOR, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_FONT_COLOR );
+ aColor = ((const SvxColorItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( nLangId, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( nLangId );
+ eLang = ((const SvxLanguageItem*)pItem)->GetLanguage();
+ }
+ else // alles aus rItemSet
+ {
+ pFontAttr = &(const SvxFontItem&)rItemSet.Get( nFontId );
+ nFontHeight = ((const SvxFontHeightItem&)
+ rItemSet.Get( nHeightId )).GetHeight();
+ eWeight = (FontWeight)((const SvxWeightItem&)
+ rItemSet.Get( nWeightId )).GetValue();
+ eItalic = (FontItalic)((const SvxPostureItem&)
+ rItemSet.Get( nPostureId )).GetValue();
+ eUnder = (FontUnderline)((const SvxUnderlineItem&)
+ rItemSet.Get( ATTR_FONT_UNDERLINE )).GetValue();
+ eOver = (FontUnderline)((const SvxOverlineItem&)
+ rItemSet.Get( ATTR_FONT_OVERLINE )).GetValue();
+ bWordLine = ((const SvxWordLineModeItem&)
+ rItemSet.Get( ATTR_FONT_WORDLINE )).GetValue();
+ eStrike = (FontStrikeout)((const SvxCrossedOutItem&)
+ rItemSet.Get( ATTR_FONT_CROSSEDOUT )).GetValue();
+ bOutline = ((const SvxContourItem&)
+ rItemSet.Get( ATTR_FONT_CONTOUR )).GetValue();
+ bShadow = ((const SvxShadowedItem&)
+ rItemSet.Get( ATTR_FONT_SHADOWED )).GetValue();
+ eEmphasis = ((const SvxEmphasisMarkItem&)
+ rItemSet.Get( ATTR_FONT_EMPHASISMARK )).GetEmphasisMark();
+ eRelief = (FontRelief)((const SvxCharReliefItem&)
+ rItemSet.Get( ATTR_FONT_RELIEF )).GetValue();
+ aColor = ((const SvxColorItem&)
+ rItemSet.Get( ATTR_FONT_COLOR )).GetValue();
+ // for graphite language features
+ eLang =
+ ((const SvxLanguageItem&)rItemSet.Get( nLangId )).GetLanguage();
+ }
+ DBG_ASSERT(pFontAttr,"nanu?");
+
+ // auswerten
+
+ // FontItem:
+
+ if (rFont.GetName() != pFontAttr->GetFamilyName())
+ rFont.SetName( pFontAttr->GetFamilyName() );
+ if (rFont.GetStyleName() != pFontAttr->GetStyleName())
+ rFont.SetStyleName( pFontAttr->GetStyleName() );
+
+ rFont.SetFamily( pFontAttr->GetFamily() );
+ rFont.SetCharSet( pFontAttr->GetCharSet() );
+ rFont.SetPitch( pFontAttr->GetPitch() );
+
+ rFont.SetLanguage(eLang);
+
+ // Groesse
+
+ if ( pOutDev != NULL )
+ {
+ Size aEffSize;
+ Fraction aFraction( 1,1 );
+ if (pScale)
+ aFraction = *pScale;
+ Size aSize( 0, (long) nFontHeight );
+ MapMode aDestMode = pOutDev->GetMapMode();
+ MapMode aSrcMode( MAP_TWIP, Point(), aFraction, aFraction );
+ if (aDestMode.GetMapUnit() == MAP_PIXEL)
+ aEffSize = pOutDev->LogicToPixel( aSize, aSrcMode );
+ else
+ {
+ Fraction aFractOne(1,1);
+ aDestMode.SetScaleX( aFractOne );
+ aDestMode.SetScaleY( aFractOne );
+ aEffSize = OutputDevice::LogicToLogic( aSize, aSrcMode, aDestMode );
+ }
+ rFont.SetSize( aEffSize );
+ }
+ else /* if pOutDev != NULL */
+ {
+ rFont.SetSize( Size( 0, (long) nFontHeight ) );
+ }
+
+ // determine effective font color
+
+ if ( ( aColor.GetColor() == COL_AUTO && eAutoMode != SC_AUTOCOL_RAW ) ||
+ eAutoMode == SC_AUTOCOL_IGNOREFONT || eAutoMode == SC_AUTOCOL_IGNOREALL )
+ {
+ if ( eAutoMode == SC_AUTOCOL_BLACK )
+ aColor.SetColor( COL_BLACK );
+ else
+ {
+ // get background color from conditional or own set
+ Color aBackColor;
+ if ( pCondSet )
+ {
+ const SfxPoolItem* pItem;
+ if ( pCondSet->GetItemState( ATTR_BACKGROUND, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rItemSet.Get( ATTR_BACKGROUND );
+ aBackColor = ((const SvxBrushItem*)pItem)->GetColor();
+ }
+ else
+ aBackColor = ((const SvxBrushItem&)rItemSet.Get( ATTR_BACKGROUND )).GetColor();
+
+ // if background color attribute is transparent, use window color for brightness comparisons
+ if ( aBackColor == COL_TRANSPARENT ||
+ eAutoMode == SC_AUTOCOL_IGNOREBACK || eAutoMode == SC_AUTOCOL_IGNOREALL )
+ {
+ if ( eAutoMode == SC_AUTOCOL_PRINT )
+ aBackColor.SetColor( COL_WHITE );
+ else if ( pBackConfigColor )
+ {
+ // pBackConfigColor can be used to avoid repeated lookup of the configured color
+ aBackColor = *pBackConfigColor;
+ }
+ else
+ aBackColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+ }
+
+ // get system text color for comparison
+ Color aSysTextColor;
+ if ( eAutoMode == SC_AUTOCOL_PRINT )
+ aSysTextColor.SetColor( COL_BLACK );
+ else if ( pTextConfigColor )
+ {
+ // pTextConfigColor can be used to avoid repeated lookup of the configured color
+ aSysTextColor = *pTextConfigColor;
+ }
+ else
+ aSysTextColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ // select the resulting color
+ if ( aBackColor.IsDark() && aSysTextColor.IsDark() )
+ {
+ // use white instead of dark on dark
+ aColor.SetColor( COL_WHITE );
+ }
+ else if ( aBackColor.IsBright() && aSysTextColor.IsBright() )
+ {
+ // use black instead of bright on bright
+ aColor.SetColor( COL_BLACK );
+ }
+ else
+ {
+ // use aSysTextColor (black for SC_AUTOCOL_PRINT, from style settings otherwise)
+ aColor = aSysTextColor;
+ }
+ }
+ }
+
+ // set font effects
+ rFont.SetWeight( eWeight );
+ rFont.SetItalic( eItalic );
+ rFont.SetUnderline( eUnder );
+ rFont.SetOverline( eOver );
+ rFont.SetWordLineMode( bWordLine );
+ rFont.SetStrikeout( eStrike );
+ rFont.SetOutline( bOutline );
+ rFont.SetShadow( bShadow );
+ rFont.SetEmphasisMark( eEmphasis );
+ rFont.SetRelief( eRelief );
+ rFont.SetColor( aColor );
+ rFont.SetTransparent( TRUE );
+}
+
+void ScPatternAttr::GetFont(
+ Font& rFont, ScAutoFontColorMode eAutoMode,
+ OutputDevice* pOutDev, const Fraction* pScale,
+ const SfxItemSet* pCondSet, BYTE nScript,
+ const Color* pBackConfigColor, const Color* pTextConfigColor ) const
+{
+ GetFont( rFont, GetItemSet(), eAutoMode, pOutDev, pScale, pCondSet, nScript, pBackConfigColor, pTextConfigColor );
+}
+
+
+void ScPatternAttr::FillToEditItemSet( SfxItemSet& rEditSet, const SfxItemSet& rSrcSet, const SfxItemSet* pCondSet )
+{
+ // Items auslesen
+
+ SvxColorItem aColorItem(EE_CHAR_COLOR); // use item as-is
+ SvxFontItem aFontItem(EE_CHAR_FONTINFO); // use item as-is
+ SvxFontItem aCjkFontItem(EE_CHAR_FONTINFO_CJK);
+ SvxFontItem aCtlFontItem(EE_CHAR_FONTINFO_CTL);
+ long nTHeight, nCjkTHeight, nCtlTHeight; // Twips
+ FontWeight eWeight, eCjkWeight, eCtlWeight;
+ SvxUnderlineItem aUnderlineItem(UNDERLINE_NONE, EE_CHAR_UNDERLINE);
+ SvxOverlineItem aOverlineItem(UNDERLINE_NONE, EE_CHAR_OVERLINE);
+ BOOL bWordLine;
+ FontStrikeout eStrike;
+ FontItalic eItalic, eCjkItalic, eCtlItalic;
+ BOOL bOutline;
+ BOOL bShadow;
+ BOOL bForbidden;
+ FontEmphasisMark eEmphasis;
+ FontRelief eRelief;
+ LanguageType eLang, eCjkLang, eCtlLang;
+ BOOL bHyphenate;
+ SvxFrameDirection eDirection;
+
+ //! additional parameter to control if language is needed?
+
+ if ( pCondSet )
+ {
+ const SfxPoolItem* pItem;
+
+ if ( pCondSet->GetItemState( ATTR_FONT_COLOR, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_COLOR );
+ aColorItem = *(const SvxColorItem*)pItem;
+
+ if ( pCondSet->GetItemState( ATTR_FONT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT );
+ aFontItem = *(const SvxFontItem*)pItem;
+ if ( pCondSet->GetItemState( ATTR_CJK_FONT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CJK_FONT );
+ aCjkFontItem = *(const SvxFontItem*)pItem;
+ if ( pCondSet->GetItemState( ATTR_CTL_FONT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CTL_FONT );
+ aCtlFontItem = *(const SvxFontItem*)pItem;
+
+ if ( pCondSet->GetItemState( ATTR_FONT_HEIGHT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_HEIGHT );
+ nTHeight = ((const SvxFontHeightItem*)pItem)->GetHeight();
+ if ( pCondSet->GetItemState( ATTR_CJK_FONT_HEIGHT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CJK_FONT_HEIGHT );
+ nCjkTHeight = ((const SvxFontHeightItem*)pItem)->GetHeight();
+ if ( pCondSet->GetItemState( ATTR_CTL_FONT_HEIGHT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CTL_FONT_HEIGHT );
+ nCtlTHeight = ((const SvxFontHeightItem*)pItem)->GetHeight();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_WEIGHT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_WEIGHT );
+ eWeight = (FontWeight)((const SvxWeightItem*)pItem)->GetValue();
+ if ( pCondSet->GetItemState( ATTR_CJK_FONT_WEIGHT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CJK_FONT_WEIGHT );
+ eCjkWeight = (FontWeight)((const SvxWeightItem*)pItem)->GetValue();
+ if ( pCondSet->GetItemState( ATTR_CTL_FONT_WEIGHT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CTL_FONT_WEIGHT );
+ eCtlWeight = (FontWeight)((const SvxWeightItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_POSTURE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_POSTURE );
+ eItalic = (FontItalic)((const SvxPostureItem*)pItem)->GetValue();
+ if ( pCondSet->GetItemState( ATTR_CJK_FONT_POSTURE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CJK_FONT_POSTURE );
+ eCjkItalic = (FontItalic)((const SvxPostureItem*)pItem)->GetValue();
+ if ( pCondSet->GetItemState( ATTR_CTL_FONT_POSTURE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CTL_FONT_POSTURE );
+ eCtlItalic = (FontItalic)((const SvxPostureItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_UNDERLINE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_UNDERLINE );
+ aUnderlineItem = *(const SvxUnderlineItem*)pItem;
+
+ if ( pCondSet->GetItemState( ATTR_FONT_OVERLINE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_OVERLINE );
+ aOverlineItem = *(const SvxOverlineItem*)pItem;
+
+ if ( pCondSet->GetItemState( ATTR_FONT_WORDLINE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_WORDLINE );
+ bWordLine = ((const SvxWordLineModeItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_CROSSEDOUT, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_CROSSEDOUT );
+ eStrike = (FontStrikeout)((const SvxCrossedOutItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_CONTOUR, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_CONTOUR );
+ bOutline = ((const SvxContourItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_SHADOWED, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_SHADOWED );
+ bShadow = ((const SvxShadowedItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FORBIDDEN_RULES, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FORBIDDEN_RULES );
+ bForbidden = ((const SvxForbiddenRuleItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_EMPHASISMARK, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_EMPHASISMARK );
+ eEmphasis = ((const SvxEmphasisMarkItem*)pItem)->GetEmphasisMark();
+ if ( pCondSet->GetItemState( ATTR_FONT_RELIEF, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_RELIEF );
+ eRelief = (FontRelief)((const SvxCharReliefItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_FONT_LANGUAGE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_FONT_LANGUAGE );
+ eLang = ((const SvxLanguageItem*)pItem)->GetLanguage();
+ if ( pCondSet->GetItemState( ATTR_CJK_FONT_LANGUAGE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CJK_FONT_LANGUAGE );
+ eCjkLang = ((const SvxLanguageItem*)pItem)->GetLanguage();
+ if ( pCondSet->GetItemState( ATTR_CTL_FONT_LANGUAGE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_CTL_FONT_LANGUAGE );
+ eCtlLang = ((const SvxLanguageItem*)pItem)->GetLanguage();
+
+ if ( pCondSet->GetItemState( ATTR_HYPHENATE, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_HYPHENATE );
+ bHyphenate = ((const SfxBoolItem*)pItem)->GetValue();
+
+ if ( pCondSet->GetItemState( ATTR_WRITINGDIR, TRUE, &pItem ) != SFX_ITEM_SET )
+ pItem = &rSrcSet.Get( ATTR_WRITINGDIR );
+ eDirection = (SvxFrameDirection)((const SvxFrameDirectionItem*)pItem)->GetValue();
+ }
+ else // alles direkt aus Pattern
+ {
+ aColorItem = (const SvxColorItem&) rSrcSet.Get( ATTR_FONT_COLOR );
+ aFontItem = (const SvxFontItem&) rSrcSet.Get( ATTR_FONT );
+ aCjkFontItem = (const SvxFontItem&) rSrcSet.Get( ATTR_CJK_FONT );
+ aCtlFontItem = (const SvxFontItem&) rSrcSet.Get( ATTR_CTL_FONT );
+ nTHeight = ((const SvxFontHeightItem&)
+ rSrcSet.Get( ATTR_FONT_HEIGHT )).GetHeight();
+ nCjkTHeight = ((const SvxFontHeightItem&)
+ rSrcSet.Get( ATTR_CJK_FONT_HEIGHT )).GetHeight();
+ nCtlTHeight = ((const SvxFontHeightItem&)
+ rSrcSet.Get( ATTR_CTL_FONT_HEIGHT )).GetHeight();
+ eWeight = (FontWeight)((const SvxWeightItem&)
+ rSrcSet.Get( ATTR_FONT_WEIGHT )).GetValue();
+ eCjkWeight = (FontWeight)((const SvxWeightItem&)
+ rSrcSet.Get( ATTR_CJK_FONT_WEIGHT )).GetValue();
+ eCtlWeight = (FontWeight)((const SvxWeightItem&)
+ rSrcSet.Get( ATTR_CTL_FONT_WEIGHT )).GetValue();
+ eItalic = (FontItalic)((const SvxPostureItem&)
+ rSrcSet.Get( ATTR_FONT_POSTURE )).GetValue();
+ eCjkItalic = (FontItalic)((const SvxPostureItem&)
+ rSrcSet.Get( ATTR_CJK_FONT_POSTURE )).GetValue();
+ eCtlItalic = (FontItalic)((const SvxPostureItem&)
+ rSrcSet.Get( ATTR_CTL_FONT_POSTURE )).GetValue();
+ aUnderlineItem = (const SvxUnderlineItem&) rSrcSet.Get( ATTR_FONT_UNDERLINE );
+ aOverlineItem = (const SvxOverlineItem&) rSrcSet.Get( ATTR_FONT_OVERLINE );
+ bWordLine = ((const SvxWordLineModeItem&)
+ rSrcSet.Get( ATTR_FONT_WORDLINE )).GetValue();
+ eStrike = (FontStrikeout)((const SvxCrossedOutItem&)
+ rSrcSet.Get( ATTR_FONT_CROSSEDOUT )).GetValue();
+ bOutline = ((const SvxContourItem&)
+ rSrcSet.Get( ATTR_FONT_CONTOUR )).GetValue();
+ bShadow = ((const SvxShadowedItem&)
+ rSrcSet.Get( ATTR_FONT_SHADOWED )).GetValue();
+ bForbidden = ((const SvxForbiddenRuleItem&)
+ rSrcSet.Get( ATTR_FORBIDDEN_RULES )).GetValue();
+ eEmphasis = ((const SvxEmphasisMarkItem&)
+ rSrcSet.Get( ATTR_FONT_EMPHASISMARK )).GetEmphasisMark();
+ eRelief = (FontRelief)((const SvxCharReliefItem&)
+ rSrcSet.Get( ATTR_FONT_RELIEF )).GetValue();
+ eLang = ((const SvxLanguageItem&)
+ rSrcSet.Get( ATTR_FONT_LANGUAGE )).GetLanguage();
+ eCjkLang = ((const SvxLanguageItem&)
+ rSrcSet.Get( ATTR_CJK_FONT_LANGUAGE )).GetLanguage();
+ eCtlLang = ((const SvxLanguageItem&)
+ rSrcSet.Get( ATTR_CTL_FONT_LANGUAGE )).GetLanguage();
+ bHyphenate = ((const SfxBoolItem&)
+ rSrcSet.Get( ATTR_HYPHENATE )).GetValue();
+ eDirection = (SvxFrameDirection)((const SvxFrameDirectionItem&)
+ rSrcSet.Get( ATTR_WRITINGDIR )).GetValue();
+ }
+
+ // kompatibel zu LogicToLogic rechnen, also 2540/1440 = 127/72, und runden
+
+ long nHeight = TwipsToHMM(nTHeight);
+ long nCjkHeight = TwipsToHMM(nCjkTHeight);
+ long nCtlHeight = TwipsToHMM(nCtlTHeight);
+
+ // put items into EditEngine ItemSet
+
+ if ( aColorItem.GetValue().GetColor() == COL_AUTO )
+ {
+ // #108979# When cell attributes are converted to EditEngine paragraph attributes,
+ // don't create a hard item for automatic color, because that would be converted
+ // to black when the item's Store method is used in CreateTransferable/WriteBin.
+ // COL_AUTO is the EditEngine's pool default, so ClearItem will result in automatic
+ // color, too, without having to store the item.
+ rEditSet.ClearItem( EE_CHAR_COLOR );
+ }
+ else
+ rEditSet.Put( aColorItem );
+ rEditSet.Put( aFontItem );
+ rEditSet.Put( aCjkFontItem );
+ rEditSet.Put( aCtlFontItem );
+ rEditSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ rEditSet.Put( SvxFontHeightItem( nCjkHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ rEditSet.Put( SvxFontHeightItem( nCtlHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+ rEditSet.Put( SvxWeightItem ( eWeight, EE_CHAR_WEIGHT ) );
+ rEditSet.Put( SvxWeightItem ( eCjkWeight, EE_CHAR_WEIGHT_CJK ) );
+ rEditSet.Put( SvxWeightItem ( eCtlWeight, EE_CHAR_WEIGHT_CTL ) );
+ rEditSet.Put( aUnderlineItem );
+ rEditSet.Put( aOverlineItem );
+ rEditSet.Put( SvxWordLineModeItem( bWordLine, EE_CHAR_WLM ) );
+ rEditSet.Put( SvxCrossedOutItem( eStrike, EE_CHAR_STRIKEOUT ) );
+ rEditSet.Put( SvxPostureItem ( eItalic, EE_CHAR_ITALIC ) );
+ rEditSet.Put( SvxPostureItem ( eCjkItalic, EE_CHAR_ITALIC_CJK ) );
+ rEditSet.Put( SvxPostureItem ( eCtlItalic, EE_CHAR_ITALIC_CTL ) );
+ rEditSet.Put( SvxContourItem ( bOutline, EE_CHAR_OUTLINE ) );
+ rEditSet.Put( SvxShadowedItem ( bShadow, EE_CHAR_SHADOW ) );
+ rEditSet.Put( SfxBoolItem ( EE_PARA_FORBIDDENRULES, bForbidden ) );
+ rEditSet.Put( SvxEmphasisMarkItem( eEmphasis, EE_CHAR_EMPHASISMARK ) );
+ rEditSet.Put( SvxCharReliefItem( eRelief, EE_CHAR_RELIEF ) );
+ rEditSet.Put( SvxLanguageItem ( eLang, EE_CHAR_LANGUAGE ) );
+ rEditSet.Put( SvxLanguageItem ( eCjkLang, EE_CHAR_LANGUAGE_CJK ) );
+ rEditSet.Put( SvxLanguageItem ( eCtlLang, EE_CHAR_LANGUAGE_CTL ) );
+ rEditSet.Put( SfxBoolItem ( EE_PARA_HYPHENATE, bHyphenate ) );
+ rEditSet.Put( SvxFrameDirectionItem( eDirection, EE_PARA_WRITINGDIR ) );
+
+ // #111216# Script spacing is always off.
+ // The cell attribute isn't used here as long as there is no UI to set it
+ // (don't evaluate attributes that can't be changed).
+ // If a locale-dependent default is needed, it has to go into the cell
+ // style, like the fonts.
+ rEditSet.Put( SvxScriptSpaceItem( FALSE, EE_PARA_ASIANCJKSPACING ) );
+}
+
+void ScPatternAttr::FillEditItemSet( SfxItemSet* pEditSet, const SfxItemSet* pCondSet ) const
+{
+ if( pEditSet )
+ FillToEditItemSet( *pEditSet, GetItemSet(), pCondSet );
+}
+
+
+void ScPatternAttr::GetFromEditItemSet( SfxItemSet& rDestSet, const SfxItemSet& rEditSet )
+{
+ const SfxPoolItem* pItem;
+
+ if (rEditSet.GetItemState(EE_CHAR_COLOR,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxColorItem(ATTR_FONT_COLOR) = *(const SvxColorItem*)pItem );
+
+ if (rEditSet.GetItemState(EE_CHAR_FONTINFO,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxFontItem(ATTR_FONT) = *(const SvxFontItem*)pItem );
+ if (rEditSet.GetItemState(EE_CHAR_FONTINFO_CJK,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxFontItem(ATTR_CJK_FONT) = *(const SvxFontItem*)pItem );
+ if (rEditSet.GetItemState(EE_CHAR_FONTINFO_CTL,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxFontItem(ATTR_CTL_FONT) = *(const SvxFontItem*)pItem );
+
+ if (rEditSet.GetItemState(EE_CHAR_FONTHEIGHT,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxFontHeightItem( HMMToTwips( ((const SvxFontHeightItem*)pItem)->GetHeight() ),
+ 100, ATTR_FONT_HEIGHT ) );
+ if (rEditSet.GetItemState(EE_CHAR_FONTHEIGHT_CJK,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxFontHeightItem( HMMToTwips( ((const SvxFontHeightItem*)pItem)->GetHeight() ),
+ 100, ATTR_CJK_FONT_HEIGHT ) );
+ if (rEditSet.GetItemState(EE_CHAR_FONTHEIGHT_CTL,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxFontHeightItem( HMMToTwips( ((const SvxFontHeightItem*)pItem)->GetHeight() ),
+ 100, ATTR_CTL_FONT_HEIGHT ) );
+
+ if (rEditSet.GetItemState(EE_CHAR_WEIGHT,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxWeightItem( (FontWeight)((const SvxWeightItem*)pItem)->GetValue(),
+ ATTR_FONT_WEIGHT) );
+ if (rEditSet.GetItemState(EE_CHAR_WEIGHT_CJK,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxWeightItem( (FontWeight)((const SvxWeightItem*)pItem)->GetValue(),
+ ATTR_CJK_FONT_WEIGHT) );
+ if (rEditSet.GetItemState(EE_CHAR_WEIGHT_CTL,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxWeightItem( (FontWeight)((const SvxWeightItem*)pItem)->GetValue(),
+ ATTR_CTL_FONT_WEIGHT) );
+
+ // SvxTextLineItem contains enum and color
+ if (rEditSet.GetItemState(EE_CHAR_UNDERLINE,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxUnderlineItem(UNDERLINE_NONE,ATTR_FONT_UNDERLINE) = *(const SvxUnderlineItem*)pItem );
+ if (rEditSet.GetItemState(EE_CHAR_OVERLINE,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxOverlineItem(UNDERLINE_NONE,ATTR_FONT_OVERLINE) = *(const SvxOverlineItem*)pItem );
+ if (rEditSet.GetItemState(EE_CHAR_WLM,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxWordLineModeItem( ((const SvxWordLineModeItem*)pItem)->GetValue(),
+ ATTR_FONT_WORDLINE) );
+
+ if (rEditSet.GetItemState(EE_CHAR_STRIKEOUT,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxCrossedOutItem( (FontStrikeout)((const SvxCrossedOutItem*)pItem)->GetValue(),
+ ATTR_FONT_CROSSEDOUT) );
+
+ if (rEditSet.GetItemState(EE_CHAR_ITALIC,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxPostureItem( (FontItalic)((const SvxPostureItem*)pItem)->GetValue(),
+ ATTR_FONT_POSTURE) );
+ if (rEditSet.GetItemState(EE_CHAR_ITALIC_CJK,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxPostureItem( (FontItalic)((const SvxPostureItem*)pItem)->GetValue(),
+ ATTR_CJK_FONT_POSTURE) );
+ if (rEditSet.GetItemState(EE_CHAR_ITALIC_CTL,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxPostureItem( (FontItalic)((const SvxPostureItem*)pItem)->GetValue(),
+ ATTR_CTL_FONT_POSTURE) );
+
+ if (rEditSet.GetItemState(EE_CHAR_OUTLINE,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxContourItem( ((const SvxContourItem*)pItem)->GetValue(),
+ ATTR_FONT_CONTOUR) );
+ if (rEditSet.GetItemState(EE_CHAR_SHADOW,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxShadowedItem( ((const SvxShadowedItem*)pItem)->GetValue(),
+ ATTR_FONT_SHADOWED) );
+ if (rEditSet.GetItemState(EE_CHAR_EMPHASISMARK,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxEmphasisMarkItem( ((const SvxEmphasisMarkItem*)pItem)->GetEmphasisMark(),
+ ATTR_FONT_EMPHASISMARK) );
+ if (rEditSet.GetItemState(EE_CHAR_RELIEF,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxCharReliefItem( (FontRelief)((const SvxCharReliefItem*)pItem)->GetValue(),
+ ATTR_FONT_RELIEF) );
+
+ if (rEditSet.GetItemState(EE_CHAR_LANGUAGE,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxLanguageItem(static_cast<const SvxLanguageItem*>(pItem)->GetValue(), ATTR_FONT_LANGUAGE) );
+ if (rEditSet.GetItemState(EE_CHAR_LANGUAGE_CJK,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxLanguageItem(static_cast<const SvxLanguageItem*>(pItem)->GetValue(), ATTR_CJK_FONT_LANGUAGE) );
+ if (rEditSet.GetItemState(EE_CHAR_LANGUAGE_CTL,TRUE,&pItem) == SFX_ITEM_SET)
+ rDestSet.Put( SvxLanguageItem(static_cast<const SvxLanguageItem*>(pItem)->GetValue(), ATTR_CTL_FONT_LANGUAGE) );
+
+ if (rEditSet.GetItemState(EE_PARA_JUST,TRUE,&pItem) == SFX_ITEM_SET)
+ {
+ SvxCellHorJustify eVal;
+ switch ( ((const SvxAdjustItem*)pItem)->GetAdjust() )
+ {
+ case SVX_ADJUST_LEFT:
+ // #30154# EditEngine Default ist bei dem GetAttribs() ItemSet
+ // immer gesetzt!
+ // ob links oder rechts entscheiden wir selbst bei Text/Zahl
+ eVal = SVX_HOR_JUSTIFY_STANDARD;
+ break;
+ case SVX_ADJUST_RIGHT:
+ eVal = SVX_HOR_JUSTIFY_RIGHT;
+ break;
+ case SVX_ADJUST_BLOCK:
+ eVal = SVX_HOR_JUSTIFY_BLOCK;
+ break;
+ case SVX_ADJUST_CENTER:
+ eVal = SVX_HOR_JUSTIFY_CENTER;
+ break;
+ case SVX_ADJUST_BLOCKLINE:
+ eVal = SVX_HOR_JUSTIFY_BLOCK;
+ break;
+ case SVX_ADJUST_END:
+ eVal = SVX_HOR_JUSTIFY_RIGHT;
+ break;
+ default:
+ eVal = SVX_HOR_JUSTIFY_STANDARD;
+ }
+ if ( eVal != SVX_HOR_JUSTIFY_STANDARD )
+ rDestSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY) );
+ }
+}
+
+void ScPatternAttr::GetFromEditItemSet( const SfxItemSet* pEditSet )
+{
+ if( pEditSet )
+ GetFromEditItemSet( GetItemSet(), *pEditSet );
+}
+
+void ScPatternAttr::FillEditParaItems( SfxItemSet* pEditSet ) const
+{
+ // in GetFromEditItemSet schon dabei, in FillEditItemSet aber nicht
+ // Hor. Ausrichtung Standard wird immer als "links" umgesetzt
+
+ const SfxItemSet& rMySet = GetItemSet();
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)
+ ((const SvxHorJustifyItem&)rMySet.Get(ATTR_HOR_JUSTIFY)).GetValue();
+
+ SvxAdjust eSvxAdjust;
+ switch (eHorJust)
+ {
+ case SVX_HOR_JUSTIFY_RIGHT: eSvxAdjust = SVX_ADJUST_RIGHT; break;
+ case SVX_HOR_JUSTIFY_CENTER: eSvxAdjust = SVX_ADJUST_CENTER; break;
+ case SVX_HOR_JUSTIFY_BLOCK: eSvxAdjust = SVX_ADJUST_BLOCK; break;
+ default: eSvxAdjust = SVX_ADJUST_LEFT; break;
+ }
+ pEditSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+}
+
+void ScPatternAttr::DeleteUnchanged( const ScPatternAttr* pOldAttrs )
+{
+ SfxItemSet& rThisSet = GetItemSet();
+ const SfxItemSet& rOldSet = pOldAttrs->GetItemSet();
+
+ const SfxPoolItem* pThisItem;
+ const SfxPoolItem* pOldItem;
+
+ for ( USHORT nSubWhich=ATTR_PATTERN_START; nSubWhich<=ATTR_PATTERN_END; nSubWhich++ )
+ {
+ // only items that are set are interesting
+ if ( rThisSet.GetItemState( nSubWhich, FALSE, &pThisItem ) == SFX_ITEM_SET )
+ {
+ SfxItemState eOldState = rOldSet.GetItemState( nSubWhich, TRUE, &pOldItem );
+ if ( eOldState == SFX_ITEM_SET )
+ {
+ // item is set in OldAttrs (or its parent) -> compare pointers
+ if ( pThisItem == pOldItem )
+ rThisSet.ClearItem( nSubWhich );
+ }
+ else if ( eOldState != SFX_ITEM_DONTCARE )
+ {
+ // not set in OldAttrs -> compare item value to default item
+ if ( *pThisItem == rThisSet.GetPool()->GetDefaultItem( nSubWhich ) )
+ rThisSet.ClearItem( nSubWhich );
+ }
+ }
+ }
+}
+
+BOOL ScPatternAttr::HasItemsSet( const USHORT* pWhich ) const
+{
+ const SfxItemSet& rSet = GetItemSet();
+ for (USHORT i=0; pWhich[i]; i++)
+ if ( rSet.GetItemState( pWhich[i], FALSE ) == SFX_ITEM_SET )
+ return TRUE;
+ return FALSE;
+}
+
+void ScPatternAttr::ClearItems( const USHORT* pWhich )
+{
+ SfxItemSet& rSet = GetItemSet();
+ for (USHORT i=0; pWhich[i]; i++)
+ rSet.ClearItem(pWhich[i]);
+}
+
+SfxStyleSheetBase* lcl_CopyStyleToPool
+ (
+ SfxStyleSheetBase* pSrcStyle,
+ SfxStyleSheetBasePool* pSrcPool,
+ SfxStyleSheetBasePool* pDestPool,
+ const SvNumberFormatterIndexTable* pFormatExchangeList
+ )
+{
+ if ( !pSrcStyle || !pDestPool || !pSrcPool )
+ {
+ DBG_ERROR( "CopyStyleToPool: Invalid Arguments :-/" );
+ return NULL;
+ }
+
+ //--------------------------------------------------------
+
+ const String aStrSrcStyle = pSrcStyle->GetName();
+ const SfxStyleFamily eFamily = pSrcStyle->GetFamily();
+ SfxStyleSheetBase* pDestStyle = pDestPool->Find( aStrSrcStyle, eFamily );
+
+ if ( !pDestStyle )
+ {
+ const String aStrParent = pSrcStyle->GetParent();
+ const SfxItemSet& rSrcSet = pSrcStyle->GetItemSet();
+
+ pDestStyle = &pDestPool->Make( aStrSrcStyle, eFamily, SFXSTYLEBIT_USERDEF );
+ SfxItemSet& rDestSet = pDestStyle->GetItemSet();
+ rDestSet.Put( rSrcSet );
+
+ // #b5017505# number format exchange list has to be handled here, too
+ // (only called for cell styles)
+
+ const SfxPoolItem* pSrcItem;
+ if ( pFormatExchangeList &&
+ rSrcSet.GetItemState( ATTR_VALUE_FORMAT, FALSE, &pSrcItem ) == SFX_ITEM_SET )
+ {
+ ULONG nOldFormat = static_cast<const SfxUInt32Item*>(pSrcItem)->GetValue();
+ sal_uInt32* pNewFormat = static_cast<sal_uInt32*>(pFormatExchangeList->Get( nOldFormat ));
+ if (pNewFormat)
+ rDestSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, *pNewFormat ) );
+ }
+
+ // ggF. abgeleitete Styles erzeugen, wenn nicht vorhanden:
+
+ if ( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) != aStrParent &&
+ aStrSrcStyle != aStrParent &&
+ !pDestPool->Find( aStrParent, eFamily ) )
+ {
+ lcl_CopyStyleToPool( pSrcPool->Find( aStrParent, eFamily ),
+ pSrcPool, pDestPool, pFormatExchangeList );
+ }
+
+ pDestStyle->SetParent( aStrParent );
+ }
+
+ return pDestStyle;
+}
+
+ScPatternAttr* ScPatternAttr::PutInPool( ScDocument* pDestDoc, ScDocument* pSrcDoc ) const
+{
+ const SfxItemSet* pSrcSet = &GetItemSet();
+
+ ScPatternAttr* pDestPattern = new ScPatternAttr(pDestDoc->GetPool());
+ SfxItemSet* pDestSet = &pDestPattern->GetItemSet();
+
+ // Zellformatvorlage in anderes Dokument kopieren:
+
+ if ( pDestDoc != pSrcDoc )
+ {
+ DBG_ASSERT( pStyle, "Missing Pattern-Style! :-/" );
+
+ // wenn Vorlage im DestDoc vorhanden, dieses benutzen, sonst Style
+ // mit Parent-Vorlagen kopieren/ggF. erzeugen und dem DestDoc hinzufuegen
+
+ SfxStyleSheetBase* pStyleCpy = lcl_CopyStyleToPool( pStyle,
+ pSrcDoc->GetStyleSheetPool(),
+ pDestDoc->GetStyleSheetPool(),
+ pDestDoc->GetFormatExchangeList() );
+
+ pDestPattern->SetStyleSheet( (ScStyleSheet*)pStyleCpy );
+ }
+
+ for ( USHORT nAttrId = ATTR_PATTERN_START; nAttrId <= ATTR_PATTERN_END; nAttrId++ )
+ {
+ const SfxPoolItem* pSrcItem;
+ SfxItemState eItemState = pSrcSet->GetItemState( nAttrId, FALSE, &pSrcItem );
+ if (eItemState==SFX_ITEM_ON)
+ {
+ SfxPoolItem* pNewItem = NULL;
+
+ if ( nAttrId == ATTR_CONDITIONAL )
+ {
+ // Bedingte Formate ins neue Dokument kopieren
+
+ ULONG nNewIndex = 0;
+ ScConditionalFormatList* pSrcList = pSrcDoc->GetCondFormList();
+ if ( pSrcList )
+ {
+ ULONG nOldIndex = ((const SfxUInt32Item*)pSrcItem)->GetValue();
+ const ScConditionalFormat* pOldData = pSrcList->GetFormat( nOldIndex );
+ if ( pOldData )
+ {
+ nNewIndex = pDestDoc->AddCondFormat( *pOldData );
+
+ // zugehoerige Styles auch mitkopieren
+ //! nur wenn Format bei Add neu angelegt
+
+ ScStyleSheetPool* pSrcSPool = pSrcDoc->GetStyleSheetPool();
+ ScStyleSheetPool* pDestSPool = pDestDoc->GetStyleSheetPool();
+ const SvNumberFormatterIndexTable* pFormatExchangeList = pDestDoc->GetFormatExchangeList();
+ USHORT nStlCnt = pOldData->Count();
+ for (USHORT i=0; i<nStlCnt; i++)
+ {
+ String aName = pOldData->GetEntry(i)->GetStyle();
+ SfxStyleSheetBase* pSrcStl =
+ pSrcDoc->GetStyleSheetPool()->Find(aName, SFX_STYLE_FAMILY_PARA);
+ lcl_CopyStyleToPool( pSrcStl, pSrcSPool, pDestSPool, pFormatExchangeList );
+ }
+ }
+ }
+ pNewItem = new SfxUInt32Item( ATTR_CONDITIONAL, nNewIndex );
+ }
+ else if ( nAttrId == ATTR_VALIDDATA )
+ {
+ // Gueltigkeit ins neue Dokument kopieren
+
+ ULONG nNewIndex = 0;
+ ScValidationDataList* pSrcList = pSrcDoc->GetValidationList();
+ if ( pSrcList )
+ {
+ ULONG nOldIndex = ((const SfxUInt32Item*)pSrcItem)->GetValue();
+ const ScValidationData* pOldData = pSrcList->GetData( nOldIndex );
+ if ( pOldData )
+ nNewIndex = pDestDoc->AddValidationEntry( *pOldData );
+ }
+ pNewItem = new SfxUInt32Item( ATTR_VALIDDATA, nNewIndex );
+ }
+ else if ( nAttrId == ATTR_VALUE_FORMAT && pDestDoc->GetFormatExchangeList() )
+ {
+ // Zahlformate nach Exchange-Liste
+
+ ULONG nOldFormat = ((const SfxUInt32Item*)pSrcItem)->GetValue();
+ sal_uInt32* pNewFormat = static_cast<sal_uInt32*>(pDestDoc->GetFormatExchangeList()->Get(nOldFormat));
+ if (pNewFormat)
+ pNewItem = new SfxUInt32Item( ATTR_VALUE_FORMAT, (UINT32) (*pNewFormat) );
+ }
+
+ if ( pNewItem )
+ {
+ pDestSet->Put(*pNewItem);
+ delete pNewItem;
+ }
+ else
+ pDestSet->Put(*pSrcItem);
+ }
+ }
+
+ ScPatternAttr* pPatternAttr =
+ (ScPatternAttr*) &pDestDoc->GetPool()->Put(*pDestPattern);
+ delete pDestPattern;
+ return pPatternAttr;
+}
+
+BOOL ScPatternAttr::IsVisible() const
+{
+ const SfxItemSet& rSet = GetItemSet();
+
+ const SfxPoolItem* pItem;
+ SfxItemState eState;
+
+ eState = rSet.GetItemState( ATTR_BACKGROUND, TRUE, &pItem );
+ if ( eState == SFX_ITEM_SET )
+ if ( ((const SvxBrushItem*)pItem)->GetColor().GetColor() != COL_TRANSPARENT )
+ return TRUE;
+
+ eState = rSet.GetItemState( ATTR_BORDER, TRUE, &pItem );
+ if ( eState == SFX_ITEM_SET )
+ {
+ const SvxBoxItem* pBoxItem = (SvxBoxItem*) pItem;
+ if ( pBoxItem->GetTop() || pBoxItem->GetBottom() ||
+ pBoxItem->GetLeft() || pBoxItem->GetRight() )
+ return TRUE;
+ }
+
+ eState = rSet.GetItemState( ATTR_BORDER_TLBR, TRUE, &pItem );
+ if ( eState == SFX_ITEM_SET )
+ if( static_cast< const SvxLineItem* >( pItem )->GetLine() )
+ return TRUE;
+
+ eState = rSet.GetItemState( ATTR_BORDER_BLTR, TRUE, &pItem );
+ if ( eState == SFX_ITEM_SET )
+ if( static_cast< const SvxLineItem* >( pItem )->GetLine() )
+ return TRUE;
+
+ eState = rSet.GetItemState( ATTR_SHADOW, TRUE, &pItem );
+ if ( eState == SFX_ITEM_SET )
+ if ( ((const SvxShadowItem*)pItem)->GetLocation() != SVX_SHADOW_NONE )
+ return TRUE;
+
+ return FALSE;
+}
+
+inline BOOL OneEqual( const SfxItemSet& rSet1, const SfxItemSet& rSet2, USHORT nId )
+{
+ const SfxPoolItem* pItem1 = &rSet1.Get(nId);
+ const SfxPoolItem* pItem2 = &rSet2.Get(nId);
+ return ( pItem1 == pItem2 || *pItem1 == *pItem2 );
+}
+
+BOOL ScPatternAttr::IsVisibleEqual( const ScPatternAttr& rOther ) const
+{
+ const SfxItemSet& rThisSet = GetItemSet();
+ const SfxItemSet& rOtherSet = rOther.GetItemSet();
+
+ return OneEqual( rThisSet, rOtherSet, ATTR_BACKGROUND ) &&
+ OneEqual( rThisSet, rOtherSet, ATTR_BORDER ) &&
+ OneEqual( rThisSet, rOtherSet, ATTR_BORDER_TLBR ) &&
+ OneEqual( rThisSet, rOtherSet, ATTR_BORDER_BLTR ) &&
+ OneEqual( rThisSet, rOtherSet, ATTR_SHADOW );
+
+ //! auch hier nur wirklich sichtbare Werte testen !!!
+}
+
+const String* ScPatternAttr::GetStyleName() const
+{
+ return pName ? pName : ( pStyle ? &pStyle->GetName() : NULL );
+}
+
+
+void ScPatternAttr::SetStyleSheet( ScStyleSheet* pNewStyle )
+{
+ if (pNewStyle)
+ {
+ SfxItemSet& rPatternSet = GetItemSet();
+ const SfxItemSet& rStyleSet = pNewStyle->GetItemSet();
+
+ for (USHORT i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END; i++)
+ {
+ if (rStyleSet.GetItemState(i, TRUE) == SFX_ITEM_SET)
+ rPatternSet.ClearItem(i);
+ }
+ rPatternSet.SetParent(&pNewStyle->GetItemSet());
+ pStyle = pNewStyle;
+ DELETEZ( pName );
+ }
+ else
+ {
+ DBG_ERROR( "ScPatternAttr::SetStyleSheet( NULL ) :-|" );
+ GetItemSet().SetParent(NULL);
+ pStyle = NULL;
+ }
+}
+
+void ScPatternAttr::UpdateStyleSheet()
+{
+ if (pName)
+ {
+ pStyle = (ScStyleSheet*)pDoc->GetStyleSheetPool()->Find(*pName, SFX_STYLE_FAMILY_PARA);
+
+ // wenn Style nicht gefunden, Standard nehmen,
+ // damit keine leere Anzeige im Toolbox-Controller
+ //! es wird vorausgesetzt, dass "Standard" immer der erste Eintrag ist!
+ if (!pStyle)
+ {
+ SfxStyleSheetIterator* pIter = pDoc->GetStyleSheetPool()->CreateIterator(
+ SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
+ pStyle = (ScStyleSheet*)pIter->First();
+ }
+
+ if (pStyle)
+ {
+ GetItemSet().SetParent(&pStyle->GetItemSet());
+ DELETEZ( pName );
+ }
+ }
+ else
+ pStyle = NULL;
+}
+
+void ScPatternAttr::StyleToName()
+{
+ // Style wurde geloescht, Namen merken:
+
+ if ( pStyle )
+ {
+ if ( pName )
+ *pName = pStyle->GetName();
+ else
+ pName = new String( pStyle->GetName() );
+
+ pStyle = NULL;
+ GetItemSet().SetParent( NULL );
+ }
+}
+
+BOOL ScPatternAttr::IsSymbolFont() const
+{
+ const SfxPoolItem* pItem;
+ if( GetItemSet().GetItemState( ATTR_FONT, TRUE, &pItem ) == SFX_ITEM_SET )
+ return BOOL( ((const SvxFontItem*) pItem)->GetCharSet()
+ == RTL_TEXTENCODING_SYMBOL );
+ else
+ return FALSE;
+}
+
+//UNUSED2008-05 FontToSubsFontConverter ScPatternAttr::GetSubsFontConverter( ULONG nFlags ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 const SfxPoolItem* pItem;
+//UNUSED2008-05 if( GetItemSet().GetItemState( ATTR_FONT, TRUE, &pItem ) == SFX_ITEM_SET )
+//UNUSED2008-05 return CreateFontToSubsFontConverter(
+//UNUSED2008-05 ((const SvxFontItem*) pItem)->GetFamilyName(), nFlags );
+//UNUSED2008-05 else
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+
+ULONG ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter ) const
+{
+ ULONG nFormat =
+ ((SfxUInt32Item*)&GetItemSet().Get( ATTR_VALUE_FORMAT ))->GetValue();
+ LanguageType eLang =
+ ((SvxLanguageItem*)&GetItemSet().Get( ATTR_LANGUAGE_FORMAT ))->GetLanguage();
+ if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLang == LANGUAGE_SYSTEM )
+ ; // es bleibt wie es ist
+ else if ( pFormatter )
+ nFormat = pFormatter->GetFormatForLanguageIfBuiltIn( nFormat, eLang );
+ return nFormat;
+}
+
+// dasselbe, wenn bedingte Formatierung im Spiel ist:
+
+ULONG ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter,
+ const SfxItemSet* pCondSet ) const
+{
+ DBG_ASSERT(pFormatter,"GetNumberFormat ohne Formatter");
+
+ const SfxPoolItem* pFormItem;
+ if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,TRUE,&pFormItem) != SFX_ITEM_SET )
+ pFormItem = &GetItemSet().Get(ATTR_VALUE_FORMAT);
+
+ const SfxPoolItem* pLangItem;
+ if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,TRUE,&pLangItem) != SFX_ITEM_SET )
+ pLangItem = &GetItemSet().Get(ATTR_LANGUAGE_FORMAT);
+
+ return pFormatter->GetFormatForLanguageIfBuiltIn(
+ ((SfxUInt32Item*)pFormItem)->GetValue(),
+ ((SvxLanguageItem*)pLangItem)->GetLanguage() );
+}
+
+const SfxPoolItem& ScPatternAttr::GetItem( USHORT nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
+{
+ const SfxPoolItem* pCondItem;
+ if ( pCondSet && pCondSet->GetItemState( nWhich, TRUE, &pCondItem ) == SFX_ITEM_SET )
+ return *pCondItem;
+ return rItemSet.Get(nWhich);
+}
+
+const SfxPoolItem& ScPatternAttr::GetItem( USHORT nSubWhich, const SfxItemSet* pCondSet ) const
+{
+ return GetItem( nSubWhich, GetItemSet(), pCondSet );
+}
+
+// GetRotateVal testet vorher ATTR_ORIENTATION
+
+long ScPatternAttr::GetRotateVal( const SfxItemSet* pCondSet ) const
+{
+ long nAttrRotate = 0;
+ if ( GetCellOrientation() == SVX_ORIENTATION_STANDARD )
+ {
+ BOOL bRepeat = ( static_cast<const SvxHorJustifyItem&>(GetItem(ATTR_HOR_JUSTIFY, pCondSet)).
+ GetValue() == SVX_HOR_JUSTIFY_REPEAT );
+ // ignore orientation/rotation if "repeat" is active
+ if ( !bRepeat )
+ nAttrRotate = ((const SfxInt32Item&)GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
+ }
+ return nAttrRotate;
+}
+
+BYTE ScPatternAttr::GetRotateDir( const SfxItemSet* pCondSet ) const
+{
+ BYTE nRet = SC_ROTDIR_NONE;
+
+ long nAttrRotate = GetRotateVal( pCondSet );
+ if ( nAttrRotate )
+ {
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD || nAttrRotate == 18000 )
+ nRet = SC_ROTDIR_STANDARD;
+ else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
+ nRet = SC_ROTDIR_CENTER;
+ else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
+ {
+ long nRot180 = nAttrRotate % 18000; // 1/100 Grad
+ if ( nRot180 == 9000 )
+ nRet = SC_ROTDIR_CENTER;
+ else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
+ ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
+ nRet = SC_ROTDIR_LEFT;
+ else
+ nRet = SC_ROTDIR_RIGHT;
+ }
+ }
+
+ return nRet;
+}
+
+
+
+
diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx
new file mode 100644
index 000000000000..ddac72f0230b
--- /dev/null
+++ b/sc/source/core/data/pivot2.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svx/algitem.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "globstr.hrc"
+#include "subtotal.hxx"
+#include "rangeutl.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "document.hxx"
+#include "userlist.hxx"
+#include "pivot.hxx"
+#include "rechead.hxx"
+#include "formula/errorcodes.hxx" // fuer errNoValue
+#include "refupdat.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+
+using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
+
+// STATIC DATA -----------------------------------------------------------
+// ============================================================================
+
+ScDPLabelData::Member::Member() :
+ mbVisible(true),
+ mbShowDetails(true)
+{
+}
+
+OUString ScDPLabelData::Member::getDisplayName() const
+{
+ if (maLayoutName.getLength())
+ return maLayoutName;
+
+ return maName;
+}
+
+ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) :
+ maName( rName ),
+ mnCol( nCol ),
+ mnFuncMask( PIVOT_FUNC_NONE ),
+ mnUsedHier( 0 ),
+ mnFlags( 0 ),
+ mbShowAll( false ),
+ mbIsValue( bIsValue )
+{
+}
+
+OUString ScDPLabelData::getDisplayName() const
+{
+ if (maLayoutName.getLength())
+ return maLayoutName;
+
+ return maName;
+}
+
+// ============================================================================
+
+ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask ) :
+ mnCol( nCol ),
+ mnFuncMask( nFuncMask )
+{
+}
+
+ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask, const DataPilotFieldReference& rFieldRef ) :
+ mnCol( nCol ),
+ mnFuncMask( nFuncMask ),
+ maFieldRef( rFieldRef )
+{
+}
+
+// ============================================================================
+
diff --git a/sc/source/core/data/poolhelp.cxx b/sc/source/core/data/poolhelp.cxx
new file mode 100644
index 000000000000..010cc502798b
--- /dev/null
+++ b/sc/source/core/data/poolhelp.cxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/zforlist.hxx>
+#include <editeng/editeng.hxx>
+
+#include "poolhelp.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+
+// -----------------------------------------------------------------------
+
+ScPoolHelper::ScPoolHelper( ScDocument* pSourceDoc )
+:pFormTable(NULL)
+,pEditPool(NULL)
+,pEnginePool(NULL)
+,m_pSourceDoc(pSourceDoc)
+{
+ DBG_ASSERT( pSourceDoc, "ScPoolHelper: no document" );
+ pDocPool = new ScDocumentPool;
+ pDocPool->FreezeIdRanges();
+
+ mxStylePool = new ScStyleSheetPool( *pDocPool, pSourceDoc );
+}
+
+ScPoolHelper::~ScPoolHelper()
+{
+ SfxItemPool::Free(pEnginePool);
+ SfxItemPool::Free(pEditPool);
+ delete pFormTable;
+ mxStylePool.clear();
+ SfxItemPool::Free(pDocPool);
+}
+SfxItemPool* ScPoolHelper::GetEditPool() const
+{
+ if ( !pEditPool )
+ {
+ pEditPool = EditEngine::CreatePool();
+ pEditPool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
+ pEditPool->FreezeIdRanges();
+ pEditPool->SetFileFormatVersion( SOFFICE_FILEFORMAT_50 ); // used in ScGlobal::EETextObjEqual
+ }
+ return pEditPool;
+}
+SfxItemPool* ScPoolHelper::GetEnginePool() const
+{
+ if ( !pEnginePool )
+ {
+ pEnginePool = EditEngine::CreatePool();
+ pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
+ pEnginePool->FreezeIdRanges();
+ } // ifg ( pEnginePool )
+ return pEnginePool;
+}
+SvNumberFormatter* ScPoolHelper::GetFormTable() const
+{
+ if ( !pFormTable )
+ {
+ pFormTable = new SvNumberFormatter( m_pSourceDoc->GetServiceManager(), ScGlobal::eLnge );
+ pFormTable->SetColorLink( LINK( m_pSourceDoc, ScDocument, GetUserDefinedColor ) );
+ pFormTable->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT );
+
+ UseDocOptions(); // null date, year2000, std precision
+ }
+ return pFormTable;
+}
+
+void ScPoolHelper::UseDocOptions() const
+{
+ if (pFormTable)
+ {
+ USHORT d,m,y;
+ aOpt.GetDate( d,m,y );
+ pFormTable->ChangeNullDate( d,m,y );
+ pFormTable->ChangeStandardPrec( (USHORT)aOpt.GetStdPrecision() );
+ pFormTable->SetYear2000( aOpt.GetYear2000() );
+ }
+}
+
+void ScPoolHelper::SetFormTableOpt(const ScDocOptions& rOpt)
+{
+ aOpt = rOpt;
+ UseDocOptions(); // #i105512# if the number formatter exists, update its settings
+}
+
+void ScPoolHelper::SourceDocumentGone()
+{
+ // reset all pointers to the source document
+ mxStylePool->SetDocument( NULL );
+ if ( pFormTable )
+ pFormTable->SetColorLink( Link() );
+}
+
+// -----------------------------------------------------------------------
+
+
diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
new file mode 100644
index 000000000000..a4bc9a473768
--- /dev/null
+++ b/sc/source/core/data/postit.cxx
@@ -0,0 +1,920 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "postit.hxx"
+
+#include <rtl/ustrbuf.hxx>
+#include <unotools/useroptions.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#include "scitems.hxx"
+#include <svx/xlnstit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/sdshitm.hxx>
+#include <svx/sdsxyitm.hxx>
+
+#include "document.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "detfunc.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const long SC_NOTECAPTION_WIDTH = 2900; /// Default width of note caption textbox.
+const long SC_NOTECAPTION_MAXWIDTH_TEMP = 12000; /// Maximum width of temporary note caption textbox.
+const long SC_NOTECAPTION_HEIGHT = 1800; /// Default height of note caption textbox.
+const long SC_NOTECAPTION_CELLDIST = 600; /// Default distance of note captions to border of anchor cell.
+const long SC_NOTECAPTION_OFFSET_Y = -1500; /// Default Y offset of note captions to top border of anchor cell.
+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:
+ /** Create a new caption. The caption will not be inserted into the document. */
+ explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bShown, bool bTailFront );
+ /** 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 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 );
+
+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; }
+
+private:
+ ScDocument& mrDoc;
+ ScAddress maPos;
+ SdrCaptionObj* mpCaption;
+ Rectangle maPageRect;
+ Rectangle maCellRect;
+ bool mbNegPage;
+};
+
+// ----------------------------------------------------------------------------
+
+ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bShown, bool bTailFront ) :
+ mrDoc( rDoc ),
+ maPos( rPos ),
+ mpCaption( 0 )
+{
+ Initialize();
+ CreateCaption( bShown, bTailFront );
+}
+
+ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption ) :
+ mrDoc( rDoc ),
+ maPos( rPos ),
+ mpCaption( &rCaption )
+{
+ 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 );
+
+ // tail position
+ Point aTailPos = mpCaption->GetTailPos();
+ aTailPos.X() = ::std::max( ::std::min( aTailPos.X(), rVisRect.Right() ), rVisRect.Left() );
+ aTailPos.Y() = ::std::max( ::std::min( aTailPos.Y(), rVisRect.Bottom() ), rVisRect.Top() );
+ mpCaption->SetTailPos( aTailPos );
+
+ // caption rectangle
+ Rectangle aCaptRect = mpCaption->GetLogicRect();
+ Point aCaptPos = aCaptRect.TopLeft();
+ // move textbox inside right border of visible area
+ aCaptPos.X() = ::std::min< long >( aCaptPos.X(), rVisRect.Right() - aCaptRect.GetWidth() );
+ // move textbox inside left border of visible area (this may move it outside on right side again)
+ aCaptPos.X() = ::std::max< long >( aCaptPos.X(), rVisRect.Left() );
+ // move textbox inside bottom border of visible area
+ aCaptPos.Y() = ::std::min< long >( aCaptPos.Y(), rVisRect.Bottom() - aCaptRect.GetHeight() );
+ // move textbox inside top border of visible area (this may move it outside on bottom side again)
+ aCaptPos.Y() = ::std::max< long >( aCaptPos.Y(), rVisRect.Top() );
+ // update caption
+ aCaptRect.SetPos( aCaptPos );
+ mpCaption->SetLogicRect( aCaptRect );
+}
+
+void ScCaptionCreator::AutoPlaceCaption( const Rectangle* pVisRect )
+{
+ const Rectangle& rVisRect = GetVisRect( pVisRect );
+
+ // caption rectangle
+ Rectangle aCaptRect = mpCaption->GetLogicRect();
+ long nWidth = aCaptRect.GetWidth();
+ long nHeight = aCaptRect.GetHeight();
+
+ // n***Space contains available space between border of visible area and cell
+ long nLeftSpace = maCellRect.Left() - rVisRect.Left() + 1;
+ long nRightSpace = rVisRect.Right() - maCellRect.Right() + 1;
+ long nTopSpace = maCellRect.Top() - rVisRect.Top() + 1;
+ long nBottomSpace = rVisRect.Bottom() - maCellRect.Bottom() + 1;
+
+ // nNeeded*** contains textbox dimensions plus needed distances to cell or border of visible area
+ long nNeededSpaceX = nWidth + SC_NOTECAPTION_CELLDIST;
+ long nNeededSpaceY = nHeight + SC_NOTECAPTION_CELLDIST;
+
+ // bFitsWidth*** == true means width of textbox fits into horizontal free space of visible area
+ bool bFitsWidthLeft = nNeededSpaceX <= nLeftSpace; // text box width fits into the width left of cell
+ bool bFitsWidthRight = nNeededSpaceX <= nRightSpace; // text box width fits into the width right of cell
+ bool bFitsWidth = nWidth <= rVisRect.GetWidth(); // text box width fits into width of visible area
+
+ // bFitsHeight*** == true means height of textbox fits into vertical free space of visible area
+ bool bFitsHeightTop = nNeededSpaceY <= nTopSpace; // text box height fits into the height above cell
+ bool bFitsHeightBottom = nNeededSpaceY <= nBottomSpace; // text box height fits into the height below cell
+ bool bFitsHeight = nHeight <= rVisRect.GetHeight(); // text box height fits into height of visible area
+
+ // bFits*** == true means the textbox fits completely into free space of visible area
+ bool bFitsLeft = bFitsWidthLeft && bFitsHeight;
+ bool bFitsRight = bFitsWidthRight && bFitsHeight;
+ bool bFitsTop = bFitsWidth && bFitsHeightTop;
+ bool bFitsBottom = bFitsWidth && bFitsHeightBottom;
+
+ Point aCaptPos;
+ // use left/right placement if possible, or if top/bottom placement not possible
+ if( bFitsLeft || bFitsRight || (!bFitsTop && !bFitsBottom) )
+ {
+ // prefer left in RTL sheet and right in LTR sheets
+ bool bPreferLeft = bFitsLeft && (mbNegPage || !bFitsRight);
+ bool bPreferRight = bFitsRight && (!mbNegPage || !bFitsLeft);
+ // move to left, if left is preferred, or if neither left nor right fit and there is more space to the left
+ if( bPreferLeft || (!bPreferRight && (nLeftSpace > nRightSpace)) )
+ aCaptPos.X() = maCellRect.Left() - SC_NOTECAPTION_CELLDIST - nWidth;
+ else // to right
+ aCaptPos.X() = maCellRect.Right() + SC_NOTECAPTION_CELLDIST;
+ // Y position according to top cell border
+ aCaptPos.Y() = maCellRect.Top() + SC_NOTECAPTION_OFFSET_Y;
+ }
+ else // top or bottom placement
+ {
+ // X position
+ aCaptPos.X() = maCellRect.Left() + SC_NOTECAPTION_OFFSET_X;
+ // top placement, if possible
+ if( bFitsTop )
+ aCaptPos.Y() = maCellRect.Top() - SC_NOTECAPTION_CELLDIST - nHeight;
+ else // bottom placement
+ aCaptPos.Y() = maCellRect.Bottom() + SC_NOTECAPTION_CELLDIST;
+ }
+
+ // update textbox position in note caption object
+ aCaptRect.SetPos( aCaptPos );
+ mpCaption->SetLogicRect( aCaptRect );
+ FitCaptionToRect( pVisRect );
+}
+
+void ScCaptionCreator::UpdateCaptionPos( const Rectangle* pVisRect )
+{
+ ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
+
+ // update caption position
+ const Point& rOldTailPos = mpCaption->GetTailPos();
+ Point aTailPos = CalcTailPos( false );
+ if( rOldTailPos != aTailPos )
+ {
+ // create drawing undo action
+ if( pDrawLayer && pDrawLayer->IsRecording() )
+ pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoGeoObject( *mpCaption ) );
+ // calculate new caption rectangle (#i98141# handle LTR<->RTL switch correctly)
+ Rectangle aCaptRect = mpCaption->GetLogicRect();
+ long nDiffX = (rOldTailPos.X() >= 0) ? (aCaptRect.Left() - rOldTailPos.X()) : (rOldTailPos.X() - aCaptRect.Right());
+ if( mbNegPage ) nDiffX = -nDiffX - aCaptRect.GetWidth();
+ long nDiffY = aCaptRect.Top() - rOldTailPos.Y();
+ aCaptRect.SetPos( aTailPos + Point( nDiffX, nDiffY ) );
+ // set new tail position and caption rectangle
+ mpCaption->SetTailPos( aTailPos );
+ mpCaption->SetLogicRect( aCaptRect );
+ // fit caption into draw page
+ FitCaptionToRect( pVisRect );
+ }
+
+ // update cell position in caption user data
+ ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( mpCaption, maPos.Tab() );
+ if( pCaptData && (maPos != pCaptData->maStart) )
+ {
+ // create drawing undo action
+ if( pDrawLayer && pDrawLayer->IsRecording() )
+ pDrawLayer->AddCalcUndo( new ScUndoObjData( mpCaption, pCaptData->maStart, pCaptData->maEnd, maPos, pCaptData->maEnd ) );
+ // set new position
+ pCaptData->maStart = maPos;
+ }
+}
+
+Point ScCaptionCreator::CalcTailPos( bool bTailFront )
+{
+ // 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::CreateCaption( bool bShown, bool bTailFront )
+{
+ // 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();
+ }
+}
+
+// ============================================================================
+
+/** 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 )
+ {
+ // create the caption drawing object
+ CreateCaption( rNoteData.mbShown, false );
+ rNoteData.mpCaption = GetCaption();
+ OSL_ENSURE( rNoteData.mpCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
+ if( rNoteData.mpCaption )
+ {
+ // store note position in user data of caption object
+ ScCaptionUtil::SetCaptionUserData( *rNoteData.mpCaption, rPos );
+ // insert object into draw page
+ pDrawPage->InsertObject( rNoteData.mpCaption );
+ }
+ }
+}
+
+ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown ) :
+ ScCaptionCreator( rDoc, rPos, rCaption )
+{
+ 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 ) :
+ mrDoc( rDoc ),
+ maNoteData( bShown )
+{
+ AutoStamp();
+ CreateCaption( rPos );
+}
+
+ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote ) :
+ mrDoc( rDoc ),
+ maNoteData( rNote.maNoteData )
+{
+ maNoteData.mpCaption = 0;
+ CreateCaption( rPos, rNote.maNoteData.mpCaption );
+}
+
+ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScNoteData& rNoteData, bool bAlwaysCreateCaption ) :
+ mrDoc( rDoc ),
+ maNoteData( rNoteData )
+{
+ if( bAlwaysCreateCaption || maNoteData.mbShown )
+ CreateCaptionFromInitData( rPos );
+}
+
+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 OutlinerParaObject* ScPostIt::GetOutlinerObject() const
+{
+ if( maNoteData.mpCaption )
+ return maNoteData.mpCaption->GetOutlinerParaObject();
+ if( maNoteData.mxInitData.get() )
+ return maNoteData.mxInitData->mxOutlinerObj.get();
+ return 0;
+}
+
+const EditTextObject* ScPostIt::GetEditTextObject() const
+{
+ const OutlinerParaObject* pOPO = GetOutlinerObject();
+ return pOPO ? &pOPO->GetTextObject() : 0;
+}
+
+OUString ScPostIt::GetText() const
+{
+ if( const EditTextObject* pEditObj = GetEditTextObject() )
+ {
+ OUStringBuffer aBuffer;
+ for( USHORT nPara = 0, nParaCount = pEditObj->GetParagraphCount(); nPara < nParaCount; ++nPara )
+ {
+ if( nPara > 0 )
+ aBuffer.append( sal_Unicode( '\n' ) );
+ aBuffer.append( pEditObj->GetText( nPara ) );
+ }
+ return aBuffer.makeStringAndClear();
+ }
+ if( maNoteData.mxInitData.get() )
+ return maNoteData.mxInitData->maSimpleText;
+ return OUString();
+}
+
+bool ScPostIt::HasMultiLineText() const
+{
+ 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 ScAddress& rPos, const OUString& rText )
+{
+ CreateCaptionFromInitData( rPos );
+ if( maNoteData.mpCaption )
+ maNoteData.mpCaption->SetText( rText );
+}
+
+SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const
+{
+ CreateCaptionFromInitData( rPos );
+ return maNoteData.mpCaption;
+}
+
+void ScPostIt::ForgetCaption()
+{
+ /* 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::ShowCaption( const ScAddress& rPos, bool bShow )
+{
+ CreateCaptionFromInitData( rPos );
+ // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
+ maNoteData.mbShown = bShow;
+ if( maNoteData.mpCaption )
+ ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, bShow );
+}
+
+void ScPostIt::ShowCaptionTemp( const ScAddress& rPos, bool bShow )
+{
+ CreateCaptionFromInitData( rPos );
+ if( maNoteData.mpCaption )
+ ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, maNoteData.mbShown || bShow );
+}
+
+void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
+{
+ CreateCaptionFromInitData( rPos );
+ if( maNoteData.mpCaption )
+ {
+ 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" );
+
+ /* #i104915# Never try to create notes in Undo document, leads to
+ crash due to missing document members (e.g. row height array). */
+ if( !maNoteData.mpCaption && !mrDoc.IsUndo() )
+ {
+ // 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 )
+{
+ OSL_ENSURE( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
+ maNoteData.mpCaption = 0;
+
+ /* #i104915# Never try to create notes in Undo document, leads to
+ crash due to missing document members (e.g. row height array). */
+ OSL_ENSURE( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
+ if( mrDoc.IsUndo() )
+ return;
+
+ // drawing layer may be missing, if a note is copied into a clipboard document
+ if( mrDoc.IsClipboard() )
+ mrDoc.InitDrawLayer();
+
+ // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
+ ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
+ if( 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
+ ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
+ aCreator.AutoPlaceCaption();
+ }
+
+ // 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). */
+ 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();
+ OSL_ENSURE( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
+ if( pDrawPage )
+ {
+ 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() );
+ }
+ }
+ maNoteData.mpCaption = 0;
+}
+
+// ============================================================================
+
+void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange )
+{
+ // do not use ScCellIterator, it skips filtered and subtotal cells
+ for( ScAddress aPos( rRange.aStart ); aPos.Tab() <= rRange.aEnd.Tab(); aPos.IncTab() )
+ for( aPos.SetCol( rRange.aStart.Col() ); aPos.Col() <= rRange.aEnd.Col(); aPos.IncCol() )
+ for( aPos.SetRow( rRange.aStart.Row() ); aPos.Row() <= rRange.aEnd.Row(); aPos.IncRow() )
+ if( ScPostIt* pNote = rDoc.GetNote( aPos ) )
+ pNote->UpdateCaptionPos( aPos );
+}
+
+SdrCaptionObj* ScNoteUtil::CreateTempCaption(
+ ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage,
+ const OUString& rUserText, const Rectangle& rVisRect, bool bTailFront )
+{
+ OUStringBuffer aBuffer( rUserText );
+ // add plain text of invisible (!) cell note (no formatting etc.)
+ SdrCaptionObj* pNoteCaption = 0;
+ const ScPostIt* pNote = rDoc.GetNote( rPos );
+ if( pNote && !pNote->IsCaptionShown() )
+ {
+ if( aBuffer.getLength() > 0 )
+ aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) ).append( pNote->GetText() );
+ pNoteCaption = pNote->GetOrCreateCaption( rPos );
+ }
+
+ // create a caption if any text exists
+ if( !pNoteCaption && (aBuffer.getLength() == 0) )
+ return 0;
+
+ // prepare visible rectangle (add default distance to all borders)
+ Rectangle aVisRect(
+ rVisRect.Left() + SC_NOTECAPTION_BORDERDIST_TEMP,
+ rVisRect.Top() + SC_NOTECAPTION_BORDERDIST_TEMP,
+ rVisRect.Right() - SC_NOTECAPTION_BORDERDIST_TEMP,
+ rVisRect.Bottom() - SC_NOTECAPTION_BORDERDIST_TEMP );
+
+ // create the caption object
+ ScCaptionCreator aCreator( rDoc, rPos, true, bTailFront );
+ SdrCaptionObj* pCaption = aCreator.GetCaption();
+
+ // insert caption into page (needed to set caption text)
+ rDrawPage.InsertObject( pCaption );
+
+ // clone the edit text object, unless user text is present, then set this text
+ if( pNoteCaption && (rUserText.getLength() == 0) )
+ {
+ if( OutlinerParaObject* pOPO = pNoteCaption->GetOutlinerParaObject() )
+ pCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
+ // set formatting (must be done after setting text) and resize the box to fit the text
+ pCaption->SetMergedItemSetAndBroadcast( pNoteCaption->GetMergedItemSet() );
+ Rectangle aCaptRect( pCaption->GetLogicRect().TopLeft(), pNoteCaption->GetLogicRect().GetSize() );
+ pCaption->SetLogicRect( aCaptRect );
+ }
+ else
+ {
+ // if pNoteCaption is null, then aBuffer contains some text
+ pCaption->SetText( aBuffer.makeStringAndClear() );
+ 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 ) );
+ pCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
+ pCaption->SetMergedItem( SdrTextMaxFrameWidthItem( nMaxWidth ) );
+ pCaption->SetMergedItem( SdrTextAutoGrowHeightItem( TRUE ) );
+ pCaption->AdjustTextFrameWidthAndHeight();
+ }
+
+ // move caption into visible area
+ aCreator.AutoPlaceCaption( &aVisRect );
+ return pCaption;
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromCaption(
+ ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown )
+{
+ ScNoteData aNoteData( bShown );
+ aNoteData.mpCaption = &rCaption;
+ ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false );
+ pNote->AutoStamp();
+ rDoc.TakeNote( rPos, pNote );
+ // if pNote still points to the note after TakeNote(), insertion was successful
+ if( pNote )
+ {
+ // 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/scdpoutputimpl.cxx b/sc/source/core/data/scdpoutputimpl.cxx
new file mode 100644
index 000000000000..6a667806e097
--- /dev/null
+++ b/sc/source/core/data/scdpoutputimpl.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright IBM Corporation 2009.
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: scdpoutputimpl.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "scdpoutputimpl.hxx"
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+// -----------------------------------------------------------------------
+
+namespace
+{
+ bool lcl_compareColfuc ( SCCOL i, SCCOL j) { return (i<j); }
+ bool lcl_compareRowfuc ( SCROW i, SCROW j) { return (i<j); }
+}
+
+
+void OutputImpl::OutputDataArea()
+{
+ AddRow( mnDataStartRow );
+ AddCol( mnDataStartCol );
+
+ mnCols.push_back( mnTabEndCol+1); //set last row bottom
+ mnRows.push_back( mnTabEndRow+1); //set last col bottom
+
+ BOOL bAllRows = ( ( mnTabEndRow - mnDataStartRow + 2 ) == (SCROW) mnRows.size() );
+
+ std::sort( mnCols.begin(), mnCols.end(), lcl_compareColfuc );
+ std::sort( mnRows.begin(), mnRows.end(), lcl_compareRowfuc );
+
+ for( SCCOL nCol = 0; nCol < (SCCOL)mnCols.size()-1; nCol ++ )
+ {
+ if ( !bAllRows )
+ {
+ if ( nCol < (SCCOL)mnCols.size()-2)
+ {
+ for ( SCROW i = nCol%2; i < (SCROW)mnRows.size()-2; i +=2 )
+ OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 );
+ if ( mnRows.size()>=2 )
+ OutputBlockFrame( mnCols[nCol], mnRows[mnRows.size()-2], mnCols[nCol+1]-1, mnRows[mnRows.size()-1]-1 );
+ }
+ else
+ {
+ for ( SCROW i = 0 ; i < (SCROW)mnRows.size()-1; i++ )
+ OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 );
+ }
+ }
+ else
+ OutputBlockFrame( mnCols[nCol], mnRows.front(), mnCols[nCol+1]-1, mnRows.back()-1, bAllRows );
+ }
+ //out put rows area outer framer
+ if ( mnTabStartCol != mnDataStartCol )
+ {
+ if ( mnTabStartRow != mnDataStartRow )
+ OutputBlockFrame( mnTabStartCol, mnTabStartRow, mnDataStartCol-1, mnDataStartRow-1 );
+ OutputBlockFrame( mnTabStartCol, mnDataStartRow, mnDataStartCol-1, mnTabEndRow );
+ }
+ //out put cols area outer framer
+ OutputBlockFrame( mnDataStartCol, mnTabStartRow, mnTabEndCol, mnDataStartRow-1 );
+}
+
+OutputImpl::OutputImpl( ScDocument* pDoc, USHORT nTab,
+ SCCOL nTabStartCol,
+ SCROW nTabStartRow,
+ SCCOL nMemberStartCol,
+ SCROW nMemberStartRow,
+ SCCOL nDataStartCol,
+ SCROW nDataStartRow,
+ SCCOL nTabEndCol,
+ SCROW nTabEndRow ):
+ mpDoc( pDoc ),
+ mnTab( nTab ),
+ mnTabStartCol( nTabStartCol ),
+ mnTabStartRow( nTabStartRow ),
+ mnMemberStartCol( nMemberStartCol),
+ mnMemberStartRow( nMemberStartRow),
+ mnDataStartCol ( nDataStartCol ),
+ mnDataStartRow ( nDataStartRow ),
+ mnTabEndCol( nTabEndCol ),
+ mnTabEndRow( nTabEndRow )
+{
+ mbNeedLineCols.resize( nTabEndCol-nDataStartCol+1, false );
+ mbNeedLineRows.resize( nTabEndRow-nDataStartRow+1, false );
+
+}
+
+BOOL OutputImpl::AddRow( SCROW nRow )
+{
+ if ( !mbNeedLineRows[ nRow - mnDataStartRow ] )
+ {
+ mbNeedLineRows[ nRow - mnDataStartRow ] = true;
+ mnRows.push_back( nRow );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+BOOL OutputImpl::AddCol( SCCOL nCol )
+{
+
+ if ( !mbNeedLineCols[ nCol - mnDataStartCol ] )
+ {
+ mbNeedLineCols[ nCol - mnDataStartCol ] = true;
+ mnCols.push_back( nCol );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void OutputImpl::OutputBlockFrame ( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, BOOL bHori )
+{
+
+ SvxBorderLine aLine, aOutLine;
+ aLine.SetColor( SC_DP_FRAME_COLOR );
+ aLine.SetOutWidth( SC_DP_FRAME_INNER_BOLD );
+ aOutLine.SetColor( SC_DP_FRAME_COLOR );
+ aOutLine.SetOutWidth( SC_DP_FRAME_OUTER_BOLD );
+
+ SvxBoxItem aBox( ATTR_BORDER );
+
+ if ( nStartCol == mnTabStartCol )
+ aBox.SetLine(&aOutLine, BOX_LINE_LEFT);
+ else
+ aBox.SetLine(&aLine, BOX_LINE_LEFT);
+
+ if ( nStartRow == mnTabStartRow )
+ aBox.SetLine(&aOutLine, BOX_LINE_TOP);
+ else
+ aBox.SetLine(&aLine, BOX_LINE_TOP);
+
+ if ( nEndCol == mnTabEndCol ) //bottom row
+ aBox.SetLine(&aOutLine, BOX_LINE_RIGHT);
+ else
+ aBox.SetLine(&aLine, BOX_LINE_RIGHT);
+
+ if ( nEndRow == mnTabEndRow ) //bottom
+ aBox.SetLine(&aOutLine, BOX_LINE_BOTTOM);
+ else
+ aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
+
+
+ SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER );
+ aBoxInfo.SetValid(VALID_VERT,FALSE );
+ if ( bHori )
+ {
+ aBoxInfo.SetValid(VALID_HORI,TRUE);
+ aBoxInfo.SetLine( &aLine, BOXINFO_LINE_HORI );
+ }
+ else
+ aBoxInfo.SetValid(VALID_HORI,FALSE );
+
+ aBoxInfo.SetValid(VALID_DISTANCE,FALSE);
+
+ mpDoc->ApplyFrameAreaTab( ScRange( nStartCol, nStartRow, mnTab, nEndCol, nEndRow , mnTab ), &aBox, &aBoxInfo );
+
+}
diff --git a/sc/source/core/data/scdpoutputimpl.hxx b/sc/source/core/data/scdpoutputimpl.hxx
new file mode 100755
index 000000000000..9148fe91ba02
--- /dev/null
+++ b/sc/source/core/data/scdpoutputimpl.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright IBM Corporation 2009.
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: scdpoutputimpl.hxx,v $
+ * $Revision: 1.0 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SCDPOUTPUTIMPL_HXX
+#define SCDPOUTPUTIMPL_HXX
+
+#include "document.hxx"
+
+#define SC_DP_FRAME_INNER_BOLD 20
+#define SC_DP_FRAME_OUTER_BOLD 40
+
+#define SC_DP_FRAME_COLOR Color(0,0,0) //( 0x20, 0x40, 0x68 )
+
+class OutputImpl
+{
+ ScDocument* mpDoc;
+ USHORT mnTab;
+ ::std::vector< bool > mbNeedLineCols;
+ ::std::vector< SCCOL > mnCols;
+
+ ::std::vector< bool > mbNeedLineRows;
+ ::std::vector< SCROW > mnRows;
+
+ SCCOL mnTabStartCol;
+ SCROW mnTabStartRow;
+ SCCOL mnMemberStartCol;
+ SCROW mnMemberStartRow;
+
+ SCCOL mnDataStartCol;
+ SCROW mnDataStartRow;
+ SCCOL mnTabEndCol;
+ SCROW mnTabEndRow;
+
+public:
+ OutputImpl( ScDocument* pDoc, USHORT nTab,
+ SCCOL nTabStartCol,
+ SCROW nTabStartRow,
+ SCCOL nMemberStartCol,
+ SCROW nMemberStartRow,
+ SCCOL nDataStartCol,
+ SCROW nDataStartRow,
+ SCCOL nTabEndCol,
+ SCROW nTabEndRow );
+ BOOL AddRow( SCROW nRow );
+ BOOL AddCol( SCCOL nCol );
+
+ void OutputDataArea();
+ void OutputBlockFrame ( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, BOOL bHori = FALSE );
+
+};
+
+#endif
diff --git a/sc/source/core/data/segmenttree.cxx b/sc/source/core/data/segmenttree.cxx
new file mode 100644
index 000000000000..86b53582d1d4
--- /dev/null
+++ b/sc/source/core/data/segmenttree.cxx
@@ -0,0 +1,582 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "segmenttree.hxx"
+
+#include <mdds/flat_segment_tree.hpp>
+
+#include <limits>
+
+using ::std::numeric_limits;
+
+// ============================================================================
+
+template<typename _ValueType, typename _ExtValueType = _ValueType>
+class ScFlatSegmentsImpl
+{
+public:
+ typedef _ValueType ValueType;
+ typedef _ExtValueType ExtValueType;
+
+ struct RangeData
+ {
+ SCCOLROW mnPos1;
+ SCCOLROW mnPos2;
+ ValueType mnValue;
+ };
+
+ ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault);
+ ScFlatSegmentsImpl(const ScFlatSegmentsImpl& r);
+ ~ScFlatSegmentsImpl();
+
+ void setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue);
+ ValueType getValue(SCCOLROW nPos);
+ ExtValueType getSumValue(SCCOLROW nPos1, SCCOLROW nPos2);
+ bool getRangeData(SCCOLROW nPos, RangeData& rData);
+ void removeSegment(SCCOLROW nPos1, SCCOLROW nPos2);
+ void insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary);
+
+ SCROW findLastNotOf(ValueType nValue) const;
+
+ // range iteration
+ bool getFirst(RangeData& rData);
+ bool getNext(RangeData& rData);
+
+ void enableTreeSearch(bool b)
+ {
+ mbTreeSearchEnabled = b;
+ }
+
+ void setInsertFromBack(bool b)
+ {
+ mbInsertFromBack = b;
+ }
+
+private:
+ typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
+ fst_type maSegments;
+ typename fst_type::const_iterator maItr;
+
+ bool mbTreeSearchEnabled:1;
+ bool mbInsertFromBack:1;
+};
+
+template<typename _ValueType, typename _ExtValueType>
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault) :
+ maSegments(0, nMax+1, nDefault),
+ mbTreeSearchEnabled(true),
+ mbInsertFromBack(false)
+{
+}
+
+template<typename _ValueType, typename _ExtValueType>
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(const ScFlatSegmentsImpl<_ValueType, _ExtValueType>& r) :
+ maSegments(r.maSegments),
+ mbTreeSearchEnabled(r.mbTreeSearchEnabled),
+ mbInsertFromBack(r.mbInsertFromBack)
+{
+}
+
+template<typename _ValueType, typename _ExtValueType>
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::~ScFlatSegmentsImpl()
+{
+}
+
+template<typename _ValueType, typename _ExtValueType>
+void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue)
+{
+ if (mbInsertFromBack)
+ maSegments.insert_back(nPos1, nPos2+1, nValue);
+ else
+ maSegments.insert_front(nPos1, nPos2+1, nValue);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ValueType ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getValue(SCCOLROW nPos)
+{
+ ValueType nValue = 0;
+ if (!mbTreeSearchEnabled)
+ {
+ maSegments.search(nPos, nValue);
+ return nValue;
+ }
+
+ if (!maSegments.is_tree_valid())
+ maSegments.build_tree();
+
+ maSegments.search_tree(nPos, nValue);
+ return nValue;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ExtValueType
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getSumValue(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ RangeData aData;
+ if (!getRangeData(nPos1, aData))
+ return 0;
+
+ sal_uInt32 nValue = 0;
+
+ SCROW nCurPos = nPos1;
+ SCROW nEndPos = aData.mnPos2;
+ while (nEndPos <= nPos2)
+ {
+ nValue += aData.mnValue * (nEndPos - nCurPos + 1);
+ nCurPos = nEndPos + 1;
+ if (!getRangeData(nCurPos, aData))
+ break;
+
+ nEndPos = aData.mnPos2;
+ }
+ if (nCurPos <= nPos2)
+ {
+ nEndPos = ::std::min(nEndPos, nPos2);
+ nValue += aData.mnValue * (nEndPos - nCurPos + 1);
+ }
+ return nValue;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getRangeData(SCCOLROW nPos, RangeData& rData)
+{
+ ValueType nValue;
+ SCCOLROW nPos1, nPos2;
+
+ if (mbTreeSearchEnabled)
+ {
+ if (!maSegments.is_tree_valid())
+ maSegments.build_tree();
+
+ if (!maSegments.search_tree(nPos, nValue, &nPos1, &nPos2))
+ return false;
+ }
+ else
+ {
+ // Conduct leaf-node only search. Faster when searching between range insertion.
+ if (!maSegments.search(nPos, nValue, &nPos1, &nPos2))
+ return false;
+ }
+
+ rData.mnPos1 = nPos1;
+ rData.mnPos2 = nPos2-1; // end point is not inclusive.
+ rData.mnValue = nValue;
+ return true;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::removeSegment(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ maSegments.shift_left(nPos1, nPos2);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary)
+{
+ maSegments.shift_right(nPos, nSize, bSkipStartBoundary);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType nValue) const
+{
+ SCCOLROW nPos = numeric_limits<SCCOLROW>::max(); // position not found.
+ typename fst_type::const_reverse_iterator itr = maSegments.rbegin(), itrEnd = maSegments.rend();
+ // Note that when searching in reverse direction, we need to skip the first
+ // node, since the right-most leaf node does not store a valid value.
+ for (++itr; itr != itrEnd; ++itr)
+ {
+ if (itr->second != nValue)
+ {
+ nPos = (--itr)->first - 1;
+ break;
+ }
+ }
+ return nPos;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData)
+{
+ maItr = maSegments.begin();
+ return getNext(rData);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData)
+{
+ typename fst_type::const_iterator itrEnd = maSegments.end();
+ if (maItr == itrEnd)
+ return false;
+
+ rData.mnPos1 = maItr->first;
+ rData.mnValue = maItr->second;
+
+ ++maItr;
+ if (maItr == itrEnd)
+ return false;
+
+ rData.mnPos2 = maItr->first - 1;
+ return true;
+}
+
+// ============================================================================
+
+class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
+{
+public:
+ explicit ScFlatUInt16SegmentsImpl(SCCOLROW nMax, sal_uInt16 nDefault) :
+ ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>(nMax, nDefault)
+ {
+ }
+};
+
+// ----------------------------------------------------------------------------
+
+class ScFlatBoolSegmentsImpl : public ScFlatSegmentsImpl<bool>
+{
+public:
+ explicit ScFlatBoolSegmentsImpl(SCCOLROW nMax) :
+ ScFlatSegmentsImpl<bool>(nMax, false)
+ {
+ }
+
+ void setTrue(SCCOLROW nPos1, SCCOLROW nPos2);
+ void setFalse(SCCOLROW nPos1, SCCOLROW nPos2);
+};
+
+void ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ setValue(nPos1, nPos2, true);
+}
+
+void ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ setValue(nPos1, nPos2, false);
+}
+
+// ============================================================================
+
+ScFlatBoolRowSegments::ForwardIterator::ForwardIterator(ScFlatBoolRowSegments& rSegs) :
+ mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mbCurValue(false)
+{
+}
+
+bool ScFlatBoolRowSegments::ForwardIterator::getValue(SCROW nPos, bool& rVal)
+{
+ if (nPos >= mnCurPos)
+ // It can only go in a forward direction.
+ mnCurPos = nPos;
+
+ if (mnCurPos > mnLastPos)
+ {
+ // position not in the current segment. Update the current value.
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mrSegs.getRangeData(mnCurPos, aData))
+ return false;
+
+ mbCurValue = aData.mbValue;
+ mnLastPos = aData.mnRow2;
+ }
+
+ rVal = mbCurValue;
+ return true;
+}
+
+SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
+{
+ return mnLastPos;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) :
+ mrSegs(rSegs)
+{
+}
+
+bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mrSegs.mpImpl->getFirst(aData))
+ return false;
+
+ rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1);
+ rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2);
+ rRange.mbValue = static_cast<bool>(aData.mnValue);
+ return true;
+}
+
+bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mrSegs.mpImpl->getNext(aData))
+ return false;
+
+ rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1);
+ rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2);
+ rRange.mbValue = static_cast<bool>(aData.mnValue);
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+ mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW)))
+{
+}
+
+ScFlatBoolRowSegments::ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r) :
+ mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
+{
+}
+
+ScFlatBoolRowSegments::~ScFlatBoolRowSegments()
+{
+}
+
+void ScFlatBoolRowSegments::setTrue(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->setTrue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+void ScFlatBoolRowSegments::setFalse(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->setFalse(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+bool ScFlatBoolRowSegments::getValue(SCROW nRow)
+{
+ return mpImpl->getValue(static_cast<SCCOLROW>(nRow));
+}
+
+bool ScFlatBoolRowSegments::getRangeData(SCROW nRow, RangeData& rData)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData))
+ return false;
+
+ rData.mbValue = aData.mnValue;
+ rData.mnRow1 = static_cast<SCROW>(aData.mnPos1);
+ rData.mnRow2 = static_cast<SCROW>(aData.mnPos2);
+ return true;
+}
+
+void ScFlatBoolRowSegments::removeSegment(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+void ScFlatBoolRowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary)
+{
+ mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
+}
+
+SCROW ScFlatBoolRowSegments::findLastNotOf(bool bValue) const
+{
+ return static_cast<SCROW>(mpImpl->findLastNotOf(bValue));
+}
+
+void ScFlatBoolRowSegments::enableTreeSearch(bool bEnable)
+{
+ mpImpl->enableTreeSearch(bEnable);
+}
+
+void ScFlatBoolRowSegments::setInsertFromBack(bool bInsertFromBack)
+{
+ mpImpl->setInsertFromBack(bInsertFromBack);
+}
+
+// ============================================================================
+
+ScFlatBoolColSegments::ScFlatBoolColSegments() :
+ mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXCOL)))
+{
+}
+
+ScFlatBoolColSegments::ScFlatBoolColSegments(const ScFlatBoolColSegments& r) :
+ mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
+{
+}
+
+ScFlatBoolColSegments::~ScFlatBoolColSegments()
+{
+}
+
+void ScFlatBoolColSegments::setTrue(SCCOL nCol1, SCCOL nCol2)
+{
+ mpImpl->setTrue(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
+}
+
+void ScFlatBoolColSegments::setFalse(SCCOL nCol1, SCCOL nCol2)
+{
+ mpImpl->setFalse(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
+}
+
+bool ScFlatBoolColSegments::getValue(SCCOL nCol)
+{
+ return mpImpl->getValue(static_cast<SCCOLROW>(nCol));
+}
+
+bool ScFlatBoolColSegments::getRangeData(SCCOL nCol, RangeData& rData)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nCol), aData))
+ return false;
+
+ rData.mbValue = aData.mnValue;
+ rData.mnCol1 = static_cast<SCCOL>(aData.mnPos1);
+ rData.mnCol2 = static_cast<SCCOL>(aData.mnPos2);
+ return true;
+}
+
+void ScFlatBoolColSegments::removeSegment(SCCOL nCol1, SCCOL nCol2)
+{
+ mpImpl->removeSegment(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
+}
+
+void ScFlatBoolColSegments::insertSegment(SCCOL nCol, SCCOL nSize, bool bSkipStartBoundary)
+{
+ mpImpl->insertSegment(static_cast<SCCOLROW>(nCol), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
+}
+
+void ScFlatBoolColSegments::enableTreeSearch(bool bEnable)
+{
+ mpImpl->enableTreeSearch(bEnable);
+}
+
+void ScFlatBoolColSegments::setInsertFromBack(bool bInsertFromBack)
+{
+ mpImpl->setInsertFromBack(bInsertFromBack);
+}
+
+// ============================================================================
+
+
+// ============================================================================
+
+ScFlatUInt16RowSegments::ForwardIterator::ForwardIterator(ScFlatUInt16RowSegments& rSegs) :
+ mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mnCurValue(0)
+{
+}
+
+bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos, sal_uInt16& rVal)
+{
+ if (nPos >= mnCurPos)
+ // It can only go in a forward direction.
+ mnCurPos = nPos;
+
+ if (mnCurPos > mnLastPos)
+ {
+ // position not in the current segment. Update the current value.
+ ScFlatUInt16RowSegments::RangeData aData;
+ if (!mrSegs.getRangeData(mnCurPos, aData))
+ return false;
+
+ mnCurValue = aData.mnValue;
+ mnLastPos = aData.mnRow2;
+ }
+
+ rVal = mnCurValue;
+ return true;
+}
+
+SCROW ScFlatUInt16RowSegments::ForwardIterator::getLastPos() const
+{
+ return mnLastPos;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(sal_uInt16 nDefault) :
+ mpImpl(new ScFlatUInt16SegmentsImpl(static_cast<SCCOLROW>(MAXROW), nDefault))
+{
+}
+
+ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r) :
+ mpImpl(new ScFlatUInt16SegmentsImpl(*r.mpImpl))
+{
+}
+
+ScFlatUInt16RowSegments::~ScFlatUInt16RowSegments()
+{
+}
+
+void ScFlatUInt16RowSegments::setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue)
+{
+ mpImpl->setValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2), nValue);
+}
+
+sal_uInt16 ScFlatUInt16RowSegments::getValue(SCROW nRow)
+{
+ return mpImpl->getValue(static_cast<SCCOLROW>(nRow));
+}
+
+sal_uInt32 ScFlatUInt16RowSegments::getSumValue(SCROW nRow1, SCROW nRow2)
+{
+ return mpImpl->getSumValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+bool ScFlatUInt16RowSegments::getRangeData(SCROW nRow, RangeData& rData)
+{
+ ScFlatUInt16SegmentsImpl::RangeData aData;
+ if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData))
+ return false;
+
+ rData.mnRow1 = aData.mnPos1;
+ rData.mnRow2 = aData.mnPos2;
+ rData.mnValue = aData.mnValue;
+ return true;
+}
+
+void ScFlatUInt16RowSegments::removeSegment(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+void ScFlatUInt16RowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary)
+{
+ mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
+}
+
+SCROW ScFlatUInt16RowSegments::findLastNotOf(sal_uInt16 nValue) const
+{
+ return static_cast<SCROW>(mpImpl->findLastNotOf(nValue));
+}
+
+void ScFlatUInt16RowSegments::enableTreeSearch(bool bEnable)
+{
+ mpImpl->enableTreeSearch(bEnable);
+}
+
+void ScFlatUInt16RowSegments::setInsertFromBack(bool bInsertFromBack)
+{
+ mpImpl->setInsertFromBack(bInsertFromBack);
+}
+
diff --git a/sc/source/core/data/sheetevents.cxx b/sc/source/core/data/sheetevents.cxx
new file mode 100644
index 000000000000..e1875b5db15b
--- /dev/null
+++ b/sc/source/core/data/sheetevents.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * 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: sheetdata.cxx,v $
+ * $Revision: 1.69.32.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "sheetevents.hxx"
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <tools/debug.hxx>
+
+// -----------------------------------------------------------------------
+
+// static
+rtl::OUString ScSheetEvents::GetEventName(sal_Int32 nEvent)
+{
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return rtl::OUString();
+ }
+
+ static const sal_Char* aEventNames[] =
+ {
+ "OnFocus", // SC_SHEETEVENT_FOCUS
+ "OnUnfocus", // SC_SHEETEVENT_UNFOCUS
+ "OnSelect", // SC_SHEETEVENT_SELECT
+ "OnDoubleClick", // SC_SHEETEVENT_DOUBLECLICK
+ "OnRightClick", // SC_SHEETEVENT_RIGHTCLICK
+ "OnChange", // SC_SHEETEVENT_CHANGE
+ "OnCalculate" // SC_SHEETEVENT_CALCULATE
+ };
+ return rtl::OUString::createFromAscii(aEventNames[nEvent]);
+}
+
+// static
+sal_Int32 ScSheetEvents::GetVbaSheetEventId(sal_Int32 nEvent)
+{
+ using namespace ::com::sun::star::script::vba::VBAEventId;
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return NO_EVENT;
+ }
+
+ static const sal_Int32 nVbaEventIds[] =
+ {
+ WORKSHEET_ACTIVATE, // SC_SHEETEVENT_FOCUS
+ WORKSHEET_DEACTIVATE, // SC_SHEETEVENT_UNFOCUS
+ WORKSHEET_SELECTIONCHANGE, // SC_SHEETEVENT_SELECT
+ WORKSHEET_BEFOREDOUBLECLICK, // SC_SHEETEVENT_DOUBLECLICK
+ WORKSHEET_BEFORERIGHTCLICK, // SC_SHEETEVENT_RIGHTCLICK
+ WORKSHEET_CHANGE, // SC_SHEETEVENT_CHANGE
+ WORKSHEET_CALCULATE // SC_SHEETEVENT_CALCULATE
+ };
+ return nVbaEventIds[nEvent];
+}
+
+// static
+sal_Int32 ScSheetEvents::GetVbaDocumentEventId(sal_Int32 nEvent)
+{
+ using namespace ::com::sun::star::script::vba::VBAEventId;
+ sal_Int32 nSheetEventId = GetVbaSheetEventId(nEvent);
+ return (nSheetEventId != NO_EVENT) ? (nSheetEventId + USERDEFINED_START) : NO_EVENT;
+}
+
+// -----------------------------------------------------------------------
+
+ScSheetEvents::ScSheetEvents() :
+ mpScriptNames(NULL)
+{
+}
+
+ScSheetEvents::~ScSheetEvents()
+{
+ Clear();
+}
+
+void ScSheetEvents::Clear()
+{
+ if (mpScriptNames)
+ {
+ for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent)
+ delete mpScriptNames[nEvent];
+ delete[] mpScriptNames;
+ mpScriptNames = NULL;
+ }
+}
+
+ScSheetEvents::ScSheetEvents(const ScSheetEvents& rOther) :
+ mpScriptNames(NULL)
+{
+ *this = rOther;
+}
+
+const ScSheetEvents& ScSheetEvents::operator=(const ScSheetEvents& rOther)
+{
+ Clear();
+ if (rOther.mpScriptNames)
+ {
+ mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT];
+ for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent)
+ if (rOther.mpScriptNames[nEvent])
+ mpScriptNames[nEvent] = new rtl::OUString(*rOther.mpScriptNames[nEvent]);
+ else
+ mpScriptNames[nEvent] = NULL;
+ }
+ return *this;
+}
+
+const rtl::OUString* ScSheetEvents::GetScript(sal_Int32 nEvent) const
+{
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return NULL;
+ }
+
+ if (mpScriptNames)
+ return mpScriptNames[nEvent];
+ return NULL;
+}
+
+void ScSheetEvents::SetScript(sal_Int32 nEvent, const rtl::OUString* pNew)
+{
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return;
+ }
+
+ if (!mpScriptNames)
+ {
+ mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT];
+ for (sal_Int32 nEventIdx=0; nEventIdx<SC_SHEETEVENT_COUNT; ++nEventIdx)
+ mpScriptNames[nEventIdx] = NULL;
+ }
+ delete mpScriptNames[nEvent];
+ if (pNew)
+ mpScriptNames[nEvent] = new rtl::OUString(*pNew);
+ else
+ mpScriptNames[nEvent] = NULL;
+}
+
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
new file mode 100644
index 000000000000..9e8d355e74fa
--- /dev/null
+++ b/sc/source/core/data/sortparam.cxx
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "sortparam.hxx"
+#include "global.hxx"
+#include "address.hxx"
+#include "queryparam.hxx"
+#include <tools/debug.hxx>
+
+
+//------------------------------------------------------------------------
+
+ScSortParam::ScSortParam()
+{
+ Clear();
+}
+
+//------------------------------------------------------------------------
+
+ScSortParam::ScSortParam( const ScSortParam& r ) :
+ nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),
+ bHasHeader(r.bHasHeader),bByRow(r.bByRow),bCaseSens(r.bCaseSens),
+ bUserDef(r.bUserDef),nUserIndex(r.nUserIndex),bIncludePattern(r.bIncludePattern),
+ bInplace(r.bInplace),
+ nDestTab(r.nDestTab),nDestCol(r.nDestCol),nDestRow(r.nDestRow),
+ aCollatorLocale( r.aCollatorLocale ), aCollatorAlgorithm( r.aCollatorAlgorithm )
+{
+ for (USHORT i=0; i<MAXSORT; i++)
+ {
+ bDoSort[i] = r.bDoSort[i];
+ nField[i] = r.nField[i];
+ bAscending[i] = r.bAscending[i];
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScSortParam::Clear()
+{
+ nCol1=nCol2=nDestCol = 0;
+ nRow1=nRow2=nDestRow = 0;
+ nCompatHeader = 2;
+ nDestTab = 0;
+ nUserIndex = 0;
+ bHasHeader=bCaseSens=bUserDef = FALSE;
+ bByRow=bIncludePattern=bInplace = TRUE;
+ aCollatorLocale = ::com::sun::star::lang::Locale();
+ aCollatorAlgorithm.Erase();
+
+ for (USHORT i=0; i<MAXSORT; i++)
+ {
+ bDoSort[i] = FALSE;
+ nField[i] = 0;
+ bAscending[i] = TRUE;
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScSortParam& ScSortParam::operator=( const ScSortParam& r )
+{
+ nCol1 = r.nCol1;
+ nRow1 = r.nRow1;
+ nCol2 = r.nCol2;
+ nRow2 = r.nRow2;
+ bHasHeader = r.bHasHeader;
+ bCaseSens = r.bCaseSens;
+ bByRow = r.bByRow;
+ bUserDef = r.bUserDef;
+ nUserIndex = r.nUserIndex;
+ bIncludePattern = r.bIncludePattern;
+ bInplace = r.bInplace;
+ nDestTab = r.nDestTab;
+ nDestCol = r.nDestCol;
+ nDestRow = r.nDestRow;
+ aCollatorLocale = r.aCollatorLocale;
+ aCollatorAlgorithm = r.aCollatorAlgorithm;
+
+ for (USHORT i=0; i<MAXSORT; i++)
+ {
+ bDoSort[i] = r.bDoSort[i];
+ nField[i] = r.nField[i];
+ bAscending[i] = r.bAscending[i];
+ }
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSortParam::operator==( const ScSortParam& rOther ) const
+{
+ BOOL bEqual = FALSE;
+ // Anzahl der Sorts gleich?
+ USHORT nLast = 0;
+ USHORT nOtherLast = 0;
+ while ( bDoSort[nLast++] && nLast < MAXSORT ) ;
+ while ( rOther.bDoSort[nOtherLast++] && nOtherLast < MAXSORT ) ;
+ nLast--;
+ nOtherLast--;
+ if ( (nLast == nOtherLast)
+ && (nCol1 == rOther.nCol1)
+ && (nRow1 == rOther.nRow1)
+ && (nCol2 == rOther.nCol2)
+ && (nRow2 == rOther.nRow2)
+ && (bHasHeader == rOther.bHasHeader)
+ && (bByRow == rOther.bByRow)
+ && (bCaseSens == rOther.bCaseSens)
+ && (bUserDef == rOther.bUserDef)
+ && (nUserIndex == rOther.nUserIndex)
+ && (bIncludePattern == rOther.bIncludePattern)
+ && (bInplace == rOther.bInplace)
+ && (nDestTab == rOther.nDestTab)
+ && (nDestCol == rOther.nDestCol)
+ && (nDestRow == rOther.nDestRow)
+ && (aCollatorLocale.Language == rOther.aCollatorLocale.Language)
+ && (aCollatorLocale.Country == rOther.aCollatorLocale.Country)
+ && (aCollatorLocale.Variant == rOther.aCollatorLocale.Variant)
+ && (aCollatorAlgorithm == rOther.aCollatorAlgorithm)
+ )
+ {
+ bEqual = TRUE;
+ for ( USHORT i=0; i<=nLast && bEqual; i++ )
+ {
+ bEqual = (nField[i] == rOther.nField[i]) && (bAscending[i] == rOther.bAscending[i]);
+ }
+ }
+ return bEqual;
+}
+
+//------------------------------------------------------------------------
+
+ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld ) :
+ nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),
+ bHasHeader(TRUE),bByRow(TRUE),bCaseSens(rSub.bCaseSens),
+ bUserDef(rSub.bUserDef),nUserIndex(rSub.nUserIndex),bIncludePattern(rSub.bIncludePattern),
+ bInplace(TRUE),
+ nDestTab(0),nDestCol(0),nDestRow(0),
+ aCollatorLocale( rOld.aCollatorLocale ), aCollatorAlgorithm( rOld.aCollatorAlgorithm )
+{
+ USHORT nNewCount = 0;
+ USHORT i;
+
+ // zuerst die Gruppen aus den Teilergebnissen
+ if (rSub.bDoSort)
+ for (i=0; i<MAXSUBTOTAL; i++)
+ if (rSub.bGroupActive[i])
+ {
+ if (nNewCount < MAXSORT)
+ {
+ bDoSort[nNewCount] = TRUE;
+ nField[nNewCount] = rSub.nField[i];
+ bAscending[nNewCount] = rSub.bAscending;
+ ++nNewCount;
+ }
+ }
+
+ // dann dahinter die alten Einstellungen
+ for (i=0; i<MAXSORT; i++)
+ if (rOld.bDoSort[i])
+ {
+ SCCOLROW nThisField = rOld.nField[i];
+ BOOL bDouble = FALSE;
+ for (USHORT j=0; j<nNewCount; j++)
+ if ( nField[j] == nThisField )
+ bDouble = TRUE;
+ if (!bDouble) // ein Feld nicht zweimal eintragen
+ {
+ if (nNewCount < MAXSORT)
+ {
+ bDoSort[nNewCount] = TRUE;
+ nField[nNewCount] = nThisField;
+ bAscending[nNewCount] = rOld.bAscending[i];
+ ++nNewCount;
+ }
+ }
+ }
+
+ for (i=nNewCount; i<MAXSORT; i++) // Rest loeschen
+ {
+ bDoSort[i] = FALSE;
+ nField[i] = 0;
+ bAscending[i] = TRUE;
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
+ nCol1(nCol),nRow1(rParam.nRow1),nCol2(nCol),nRow2(rParam.nRow2),
+ bHasHeader(rParam.bHasHeader),bByRow(TRUE),bCaseSens(rParam.bCaseSens),
+//! TODO: what about Locale and Algorithm?
+ bUserDef(FALSE),nUserIndex(0),bIncludePattern(FALSE),
+ bInplace(TRUE),
+ nDestTab(0),nDestCol(0),nDestRow(0)
+{
+ bDoSort[0] = TRUE;
+ nField[0] = nCol;
+ bAscending[0] = TRUE;
+ for (USHORT i=1; i<MAXSORT; i++)
+ {
+ bDoSort[i] = FALSE;
+ nField[i] = 0;
+ bAscending[i] = TRUE;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScSortParam::MoveToDest()
+{
+ if (!bInplace)
+ {
+ SCsCOL nDifX = ((SCsCOL) nDestCol) - ((SCsCOL) nCol1);
+ SCsROW nDifY = ((SCsROW) nDestRow) - ((SCsROW) nRow1);
+
+ nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nDifX );
+ nRow1 = sal::static_int_cast<SCROW>( nRow1 + nDifY );
+ nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX );
+ nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY );
+ for (USHORT i=0; i<MAXSORT; i++)
+ if (bByRow)
+ nField[i] += nDifX;
+ else
+ nField[i] += nDifY;
+
+ bInplace = TRUE;
+ }
+ else
+ {
+ DBG_ERROR("MoveToDest, bInplace == TRUE");
+ }
+}
+
diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx
new file mode 100644
index 000000000000..d722856dc80a
--- /dev/null
+++ b/sc/source/core/data/stlpool.cxx
@@ -0,0 +1,641 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svl/itemset.hxx>
+#include <svl/zforlist.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/fontcvt.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/svapp.hxx>
+
+#include "sc.hrc"
+#include "attrib.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "rechead.hxx"
+#include "editutil.hxx"
+#include "patattr.hxx"
+
+
+//========================================================================
+
+ScStyleSheetPool::ScStyleSheetPool( SfxItemPool& rPoolP,
+ ScDocument* pDocument )
+ : SfxStyleSheetPool( rPoolP ),
+ pActualStyleSheet( NULL ),
+ pDoc( pDocument ),
+ pForceStdName( NULL )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScStyleSheetPool::~ScStyleSheetPool()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScStyleSheetPool::SetDocument( ScDocument* pDocument )
+{
+ pDoc = pDocument;
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2009-05 void ScStyleSheetPool::SetForceStdName( const String* pSet )
+//UNUSED2009-05 {
+//UNUSED2009-05 pForceStdName = pSet;
+//UNUSED2009-05 }
+
+//------------------------------------------------------------------------
+
+SfxStyleSheetBase& ScStyleSheetPool::Make( const String& rName,
+ SfxStyleFamily eFam, USHORT mask, USHORT nPos )
+{
+ // When updating styles from a template, Office 5.1 sometimes created
+ // files with multiple default styles.
+ // Create new styles in that case:
+
+ //! only when loading?
+
+ if ( rName.EqualsAscii(STRING_STANDARD) && Find( rName, eFam ) != NULL )
+ {
+ DBG_ERROR("renaming additional default style");
+ sal_uInt32 nCount = aStyles.size();
+ for ( sal_uInt32 nAdd = 1; nAdd <= nCount; nAdd++ )
+ {
+ String aNewName = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
+ aNewName += String::CreateFromInt32( nAdd );
+ if ( Find( aNewName, eFam ) == NULL )
+ return SfxStyleSheetPool::Make( aNewName, eFam, mask, nPos );
+ }
+ }
+
+ return SfxStyleSheetPool::Make( rName, eFam, mask, nPos );
+}
+
+//------------------------------------------------------------------------
+
+SfxStyleSheetBase* __EXPORT ScStyleSheetPool::Create(
+ const String& rName,
+ SfxStyleFamily eFamily,
+ USHORT nMaskP )
+{
+ ScStyleSheet* pSheet = new ScStyleSheet( rName, *this, eFamily, nMaskP );
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && ScGlobal::GetRscString(STR_STYLENAME_STANDARD) != rName )
+ pSheet->SetParent( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
+
+ return pSheet;
+}
+
+//------------------------------------------------------------------------
+
+SfxStyleSheetBase* __EXPORT ScStyleSheetPool::Create( const SfxStyleSheetBase& rStyle )
+{
+ DBG_ASSERT( rStyle.ISA(ScStyleSheet), "Invalid StyleSheet-class! :-/" );
+ return new ScStyleSheet( (const ScStyleSheet&) rStyle );
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScStyleSheetPool::Remove( SfxStyleSheetBase* pStyle )
+{
+ if ( pStyle )
+ {
+ DBG_ASSERT( IS_SET( SFXSTYLEBIT_USERDEF, pStyle->GetMask() ),
+ "SFXSTYLEBIT_USERDEF not set!" );
+
+ ((ScDocumentPool&)rPool).StyleDeleted((ScStyleSheet*)pStyle);
+ SfxStyleSheetPool::Remove(pStyle);
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScStyleSheetPool::CopyStyleFrom( ScStyleSheetPool* pSrcPool,
+ const String& rName, SfxStyleFamily eFamily )
+{
+ // this ist Dest-Pool
+
+ SfxStyleSheetBase* pStyleSheet = pSrcPool->Find( rName, eFamily );
+ if (pStyleSheet)
+ {
+ const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet();
+ SfxStyleSheetBase* pDestSheet = Find( rName, eFamily );
+ if (!pDestSheet)
+ pDestSheet = &Make( rName, eFamily );
+ SfxItemSet& rDestSet = pDestSheet->GetItemSet();
+ rDestSet.PutExtended( rSourceSet, SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT );
+
+ const SfxPoolItem* pItem;
+ if ( eFamily == SFX_STYLE_FAMILY_PAGE )
+ {
+ // Set-Items
+
+ if ( rSourceSet.GetItemState( ATTR_PAGE_HEADERSET, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ const SfxItemSet& rSrcSub = ((const SvxSetItem*) pItem)->GetItemSet();
+ SfxItemSet aDestSub( *rDestSet.GetPool(), rSrcSub.GetRanges() );
+ aDestSub.PutExtended( rSrcSub, SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT );
+ rDestSet.Put( SvxSetItem( ATTR_PAGE_HEADERSET, aDestSub ) );
+ }
+ if ( rSourceSet.GetItemState( ATTR_PAGE_FOOTERSET, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ const SfxItemSet& rSrcSub = ((const SvxSetItem*) pItem)->GetItemSet();
+ SfxItemSet aDestSub( *rDestSet.GetPool(), rSrcSub.GetRanges() );
+ aDestSub.PutExtended( rSrcSub, SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT );
+ rDestSet.Put( SvxSetItem( ATTR_PAGE_FOOTERSET, aDestSub ) );
+ }
+ }
+ else // cell styles
+ {
+ // #b5017505# number format exchange list has to be handled here, too
+
+ if ( pDoc && pDoc->GetFormatExchangeList() &&
+ rSourceSet.GetItemState( ATTR_VALUE_FORMAT, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ ULONG nOldFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
+ sal_uInt32* pNewFormat = static_cast<sal_uInt32*>(pDoc->GetFormatExchangeList()->Get( nOldFormat ));
+ if (pNewFormat)
+ rDestSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, *pNewFormat ) );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+//
+// Standard-Vorlagen
+//
+//------------------------------------------------------------------------
+
+#define SCSTR(id) ScGlobal::GetRscString(id)
+
+void ScStyleSheetPool::CopyStdStylesFrom( ScStyleSheetPool* pSrcPool )
+{
+ // Default-Styles kopieren
+
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA );
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_RESULT), SFX_STYLE_FAMILY_PARA );
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_RESULT1), SFX_STYLE_FAMILY_PARA );
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_HEADLINE), SFX_STYLE_FAMILY_PARA );
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_HEADLINE1), SFX_STYLE_FAMILY_PARA );
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PAGE );
+ CopyStyleFrom( pSrcPool, SCSTR(STR_STYLENAME_REPORT), SFX_STYLE_FAMILY_PAGE );
+}
+
+//------------------------------------------------------------------------
+
+void lcl_CheckFont( SfxItemSet& rSet, LanguageType eLang, USHORT nFontType, USHORT nItemId )
+{
+ if ( eLang != LANGUAGE_NONE && eLang != LANGUAGE_DONTKNOW && eLang != LANGUAGE_SYSTEM )
+ {
+ Font aDefFont = OutputDevice::GetDefaultFont( nFontType, eLang, DEFAULTFONT_FLAGS_ONLYONE );
+ SvxFontItem aNewItem( aDefFont.GetFamily(), aDefFont.GetName(), aDefFont.GetStyleName(),
+ aDefFont.GetPitch(), aDefFont.GetCharSet(), nItemId );
+ if ( aNewItem != rSet.Get( nItemId ) )
+ {
+ // put item into style's ItemSet only if different from (static) default
+ rSet.Put( aNewItem );
+ }
+ }
+}
+
+void ScStyleSheetPool::CreateStandardStyles()
+{
+ // neue Eintraege auch bei CopyStdStylesFrom eintragen
+
+ Color aColBlack ( COL_BLACK );
+ Color aColGrey ( COL_LIGHTGRAY );
+ String aStr;
+ xub_StrLen nStrLen;
+ String aHelpFile;//XXX JN welcher Text???
+ //ULONG nNumFmt = 0L;
+ SfxItemSet* pSet = NULL;
+ SfxItemSet* pHFSet = NULL;
+ SvxSetItem* pHFSetItem = NULL;
+ ScEditEngineDefaulter* pEdEngine = new ScEditEngineDefaulter( EditEngine::CreatePool(), TRUE );
+ pEdEngine->SetUpdateMode( FALSE );
+ EditTextObject* pEmptyTxtObj = pEdEngine->CreateTextObject();
+ EditTextObject* pTxtObj = NULL;
+ ScPageHFItem* pHeaderItem = new ScPageHFItem( ATTR_PAGE_HEADERRIGHT );
+ ScPageHFItem* pFooterItem = new ScPageHFItem( ATTR_PAGE_FOOTERRIGHT );
+ ScStyleSheet* pSheet = NULL;
+ SvxBorderLine aBorderLine ( &aColBlack, DEF_LINE_WIDTH_2 );
+ SvxBoxItem aBoxItem ( ATTR_BORDER );
+ SvxBoxInfoItem aBoxInfoItem ( ATTR_BORDER_INNER );
+
+ String aStrStandard = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
+
+ //==========================================================
+ // Zellformatvorlagen:
+ //==========================================================
+
+ //------------
+ // 1. Standard
+ //------------
+ pSheet = (ScStyleSheet*) &Make( aStrStandard, SFX_STYLE_FAMILY_PARA, SCSTYLEBIT_STANDARD );
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_CELL_STD );
+
+ // if default fonts for the document's languages are different from the pool default,
+ // put them into the default style
+ // (not as pool defaults, because pool defaults can't be changed by the user)
+ // the document languages must be set before creating the default styles!
+
+ pSet = &pSheet->GetItemSet();
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+
+ // #108374# / #107782#: If the UI language is Korean, the default Latin font has to
+ // be queried for Korean, too (the Latin language from the document can't be Korean).
+ // This is the same logic as in SwDocShell::InitNew.
+ LanguageType eUiLanguage = Application::GetSettings().GetUILanguage();
+ switch( eUiLanguage )
+ {
+ case LANGUAGE_KOREAN:
+ case LANGUAGE_KOREAN_JOHAB:
+ eLatin = eUiLanguage;
+ break;
+ }
+
+ lcl_CheckFont( *pSet, eLatin, DEFAULTFONT_LATIN_SPREADSHEET, ATTR_FONT );
+ lcl_CheckFont( *pSet, eCjk, DEFAULTFONT_CJK_SPREADSHEET, ATTR_CJK_FONT );
+ lcl_CheckFont( *pSet, eCtl, DEFAULTFONT_CTL_SPREADSHEET, ATTR_CTL_FONT );
+
+ // #i55300# default CTL font size for Thai has to be larger
+ // #i59408# The 15 point size causes problems with row heights, so no different
+ // size is used for Thai in Calc for now.
+// if ( eCtl == LANGUAGE_THAI )
+// pSet->Put( SvxFontHeightItem( 300, 100, ATTR_CTL_FONT_HEIGHT ) ); // 15 pt
+
+ //------------
+ // 2. Ergebnis
+ //------------
+
+ pSheet = (ScStyleSheet*) &Make( SCSTR( STR_STYLENAME_RESULT ),
+ SFX_STYLE_FAMILY_PARA,
+ SCSTYLEBIT_STANDARD );
+ pSheet->SetParent( aStrStandard );
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_CELL_ERG );
+ pSet = &pSheet->GetItemSet();
+ pSet->Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ pSet->Put( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ pSet->Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+
+ //-------------
+ // 3. Ergebnis1
+ //-------------
+
+ pSheet = (ScStyleSheet*) &Make( SCSTR( STR_STYLENAME_RESULT1 ),
+ SFX_STYLE_FAMILY_PARA,
+ SCSTYLEBIT_STANDARD );
+
+ pSheet->SetParent( SCSTR( STR_STYLENAME_RESULT ) );
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_CELL_ERG1 );
+ // will now be done in GetItemSet();
+ // pSet = &pSheet->GetItemSet();
+ // nNumFmt = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_CURRENCY,
+ // ScGlobal::eLnge );
+ // pSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumFmt ) );
+
+ //----------------
+ // 4. Ueberschrift
+ //----------------
+
+ pSheet = (ScStyleSheet*) &Make( SCSTR( STR_STYLENAME_HEADLINE ),
+ SFX_STYLE_FAMILY_PARA,
+ SCSTYLEBIT_STANDARD );
+
+ pSheet->SetParent( aStrStandard );
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_CELL_UEB );
+ pSet = &pSheet->GetItemSet();
+ pSet->Put( SvxFontHeightItem( 320, 100, ATTR_FONT_HEIGHT ) ); // 16pt
+ pSet->Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ pSet->Put( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ pSet->Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+
+ //-----------------
+ // 5. Ueberschrift1
+ //-----------------
+
+ pSheet = (ScStyleSheet*) &Make( SCSTR( STR_STYLENAME_HEADLINE1 ),
+ SFX_STYLE_FAMILY_PARA,
+ SCSTYLEBIT_STANDARD );
+
+ pSheet->SetParent( SCSTR( STR_STYLENAME_HEADLINE ) );
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_CELL_UEB1 );
+ pSet = &pSheet->GetItemSet();
+ pSet->Put( SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
+
+ //==========================================================
+ // Seitenformat-Vorlagen:
+ //==========================================================
+
+ //------------
+ // 1. Standard
+ //------------
+
+ pSheet = (ScStyleSheet*) &Make( aStrStandard,
+ SFX_STYLE_FAMILY_PAGE,
+ SCSTYLEBIT_STANDARD );
+
+ pSet = &pSheet->GetItemSet();
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_PAGE_STD );
+
+ // Abstand der Kopf-/Fusszeilen von der Tabelle
+ pHFSetItem = new SvxSetItem( ((SvxSetItem&)pSet->Get( ATTR_PAGE_HEADERSET ) ) );
+ pSet->Put( *pHFSetItem, ATTR_PAGE_HEADERSET );
+ pSet->Put( *pHFSetItem, ATTR_PAGE_FOOTERSET );
+ DELETEZ( pHFSetItem );
+
+ //----------------------------------------
+ // Kopfzeile:
+ // [leer][\TABELLE\][leer]
+ //----------------------------------------
+ pEdEngine->SetText(EMPTY_STRING);
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), ESelection() );
+ pTxtObj = pEdEngine->CreateTextObject();
+ pHeaderItem->SetLeftArea ( *pEmptyTxtObj );
+ pHeaderItem->SetCenterArea( *pTxtObj );
+ pHeaderItem->SetRightArea ( *pEmptyTxtObj );
+ pSet->Put( *pHeaderItem );
+ DELETEZ( pTxtObj );
+
+ //----------------------------------------
+ // Fusszeile:
+ // [leer][Seite \SEITE\][leer]
+ //----------------------------------------
+ aStr = SCSTR( STR_PAGE ); aStr += ' ';
+ pEdEngine->SetText( aStr );
+ nStrLen = aStr.Len();
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(0,nStrLen,0,nStrLen) );
+ pTxtObj = pEdEngine->CreateTextObject();
+ pFooterItem->SetLeftArea ( *pEmptyTxtObj );
+ pFooterItem->SetCenterArea( *pTxtObj );
+ pFooterItem->SetRightArea ( *pEmptyTxtObj );
+ pSet->Put( *pFooterItem );
+ DELETEZ( pTxtObj );
+
+ //----------
+ // 2. Report
+ //----------
+
+ pSheet = (ScStyleSheet*) &Make( SCSTR( STR_STYLENAME_REPORT ),
+ SFX_STYLE_FAMILY_PAGE,
+ SCSTYLEBIT_STANDARD );
+ pSet = &pSheet->GetItemSet();
+ pSheet->SetHelpId( aHelpFile, HID_SC_SHEET_PAGE_REP );
+
+ // Hintergrund und Umrandung
+ aBoxItem.SetLine( &aBorderLine, BOX_LINE_TOP );
+ aBoxItem.SetLine( &aBorderLine, BOX_LINE_BOTTOM );
+ aBoxItem.SetLine( &aBorderLine, BOX_LINE_LEFT );
+ aBoxItem.SetLine( &aBorderLine, BOX_LINE_RIGHT );
+ aBoxItem.SetDistance( 10 ); // 0.2mm
+ aBoxInfoItem.SetValid( VALID_TOP, TRUE );
+ aBoxInfoItem.SetValid( VALID_BOTTOM, TRUE );
+ aBoxInfoItem.SetValid( VALID_LEFT, TRUE );
+ aBoxInfoItem.SetValid( VALID_RIGHT, TRUE );
+ aBoxInfoItem.SetValid( VALID_DISTANCE, TRUE );
+ aBoxInfoItem.SetTable( FALSE );
+ aBoxInfoItem.SetDist ( TRUE );
+
+ pHFSetItem = new SvxSetItem( ((SvxSetItem&)pSet->Get( ATTR_PAGE_HEADERSET ) ) );
+ pHFSet = &(pHFSetItem->GetItemSet());
+
+ pHFSet->Put( SvxBrushItem( aColGrey, ATTR_BACKGROUND ) );
+ pHFSet->Put( aBoxItem );
+ pHFSet->Put( aBoxInfoItem );
+ pSet->Put( *pHFSetItem, ATTR_PAGE_HEADERSET );
+ pSet->Put( *pHFSetItem, ATTR_PAGE_FOOTERSET );
+ DELETEZ( pHFSetItem );
+
+ //----------------------------------------
+ // Kopfzeile:
+ // [\TABELLE\ (\DATEI\)][leer][\DATUM\, \ZEIT\]
+ //----------------------------------------
+ aStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" ()"));
+ pEdEngine->SetText( aStr );
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD), ESelection(0,2,0,2) );
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), ESelection() );
+ pTxtObj = pEdEngine->CreateTextObject();
+ pHeaderItem->SetLeftArea( *pTxtObj );
+ pHeaderItem->SetCenterArea( *pEmptyTxtObj );
+ DELETEZ( pTxtObj );
+ aStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ pEdEngine->SetText( aStr );
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxTimeField(), EE_FEATURE_FIELD), ESelection(0,2,0,2) );
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR), EE_FEATURE_FIELD),
+ ESelection() );
+ pTxtObj = pEdEngine->CreateTextObject();
+ pHeaderItem->SetRightArea( *pTxtObj );
+ DELETEZ( pTxtObj );
+ pSet->Put( *pHeaderItem );
+
+ //----------------------------------------
+ // Fusszeile:
+ // [leer][Seite: \SEITE\ / \SEITEN\][leer]
+ //----------------------------------------
+ aStr = SCSTR( STR_PAGE ); aStr += ' ';
+ nStrLen = aStr.Len();
+ aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" / "));
+ xub_StrLen nStrLen2 = aStr.Len();
+ pEdEngine->SetText( aStr );
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD), ESelection(0,nStrLen2,0,nStrLen2) );
+ pEdEngine->QuickInsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(0,nStrLen,0,nStrLen) );
+ pTxtObj = pEdEngine->CreateTextObject();
+ pFooterItem->SetLeftArea ( *pEmptyTxtObj );
+ pFooterItem->SetCenterArea( *pTxtObj );
+ pFooterItem->SetRightArea ( *pEmptyTxtObj );
+ pSet->Put( *pFooterItem );
+ DELETEZ( pTxtObj );
+
+ //----------------------------------------------------
+ DELETEZ( pEmptyTxtObj );
+ DELETEZ( pHeaderItem );
+ DELETEZ( pFooterItem );
+ DELETEZ( pEdEngine );
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScStyleSheetPool::UpdateStdNames()
+//UNUSED2008-05 {
+//UNUSED2008-05 // Standard-Styles den richtigen Namen in der Programm-Sprache geben
+//UNUSED2008-05
+//UNUSED2008-05 String aHelpFile;
+//UNUSED2008-05 sal_uInt32 nCount = aStyles.size();
+//UNUSED2008-05 for (sal_uInt32 n=0; n<nCount; n++)
+//UNUSED2008-05 {
+//UNUSED2008-05 SfxStyleSheetBase* pStyle = aStyles[n].get();
+//UNUSED2008-05 if (!pStyle->IsUserDefined())
+//UNUSED2008-05 {
+//UNUSED2008-05 String aOldName = pStyle->GetName();
+//UNUSED2008-05 ULONG nHelpId = pStyle->GetHelpId( aHelpFile );
+//UNUSED2008-05 SfxStyleFamily eFam = pStyle->GetFamily();
+//UNUSED2008-05
+//UNUSED2008-05 BOOL bHelpKnown = TRUE;
+//UNUSED2008-05 String aNewName;
+//UNUSED2008-05 USHORT nNameId = 0;
+//UNUSED2008-05 switch( nHelpId )
+//UNUSED2008-05 {
+//UNUSED2008-05 case HID_SC_SHEET_CELL_STD:
+//UNUSED2008-05 case HID_SC_SHEET_PAGE_STD: nNameId = STR_STYLENAME_STANDARD; break;
+//UNUSED2008-05 case HID_SC_SHEET_CELL_ERG: nNameId = STR_STYLENAME_RESULT; break;
+//UNUSED2008-05 case HID_SC_SHEET_CELL_ERG1: nNameId = STR_STYLENAME_RESULT1; break;
+//UNUSED2008-05 case HID_SC_SHEET_CELL_UEB: nNameId = STR_STYLENAME_HEADLINE; break;
+//UNUSED2008-05 case HID_SC_SHEET_CELL_UEB1: nNameId = STR_STYLENAME_HEADLINE1; break;
+//UNUSED2008-05 case HID_SC_SHEET_PAGE_REP: nNameId = STR_STYLENAME_REPORT; break;
+//UNUSED2008-05 default:
+//UNUSED2008-05 // 0 oder falsche (alte) HelpId
+//UNUSED2008-05 bHelpKnown = FALSE;
+//UNUSED2008-05 }
+//UNUSED2008-05 if (bHelpKnown)
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( nNameId )
+//UNUSED2008-05 aNewName = SCSTR( nNameId );
+//UNUSED2008-05
+//UNUSED2008-05 if ( aNewName.Len() && aNewName != aOldName && !Find( aNewName, eFam ) )
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_TRACE( "Renaming style..." );
+//UNUSED2008-05
+//UNUSED2008-05 pStyle->SetName( aNewName ); // setzt auch Parents um
+//UNUSED2008-05
+//UNUSED2008-05 // Styles in Patterns sind schon auf Pointer umgesetzt
+//UNUSED2008-05 if (eFam == SFX_STYLE_FAMILY_PAGE)
+//UNUSED2008-05 {
+//UNUSED2008-05 // Page-Styles umsetzen
+//UNUSED2008-05 // TableCount am Doc ist noch nicht initialisiert
+//UNUSED2008-05 for (SCTAB nTab=0; nTab<=MAXTAB && pDoc->HasTable(nTab); nTab++)
+//UNUSED2008-05 if (pDoc->GetPageStyle(nTab) == aOldName)
+//UNUSED2008-05 pDoc->SetPageStyle(nTab, aNewName);
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 // wrong or no HelpId -> set new HelpId
+//UNUSED2008-05
+//UNUSED2008-05 // no assertion for wrong HelpIds because this happens
+//UNUSED2008-05 // with old files (#67218#) or with old files that were
+//UNUSED2008-05 // saved again with a new version in a different language
+//UNUSED2008-05 // (so SrcVersion doesn't help)
+//UNUSED2008-05
+//UNUSED2008-05 USHORT nNewId = 0;
+//UNUSED2008-05 if ( eFam == SFX_STYLE_FAMILY_PARA )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aOldName == SCSTR( STR_STYLENAME_STANDARD ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_CELL_STD;
+//UNUSED2008-05 else if ( aOldName == SCSTR( STR_STYLENAME_RESULT ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_CELL_ERG;
+//UNUSED2008-05 else if ( aOldName == SCSTR( STR_STYLENAME_RESULT1 ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_CELL_ERG1;
+//UNUSED2008-05 else if ( aOldName == SCSTR( STR_STYLENAME_HEADLINE ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_CELL_UEB;
+//UNUSED2008-05 else if ( aOldName == SCSTR( STR_STYLENAME_HEADLINE1 ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_CELL_UEB1;
+//UNUSED2008-05 }
+//UNUSED2008-05 else // PAGE
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aOldName == SCSTR( STR_STYLENAME_STANDARD ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_PAGE_STD;
+//UNUSED2008-05 else if ( aOldName == SCSTR( STR_STYLENAME_REPORT ) )
+//UNUSED2008-05 nNewId = HID_SC_SHEET_PAGE_REP;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 if ( nNewId ) // new ID found from name -> set ID
+//UNUSED2008-05 {
+//UNUSED2008-05 pStyle->SetHelpId( aHelpFile, nNewId );
+//UNUSED2008-05 }
+//UNUSED2008-05 else if ( nHelpId == 0 ) // no old and no new ID
+//UNUSED2008-05 {
+//UNUSED2008-05 // #71471# probably user defined style without SFXSTYLEBIT_USERDEF set
+//UNUSED2008-05 // (from StarCalc 1.0 import), fixed in src563 and above
+//UNUSED2008-05 //! may also be default style from a different language
+//UNUSED2008-05 //! test if name was generated from StarCalc 1.0 import?
+//UNUSED2008-05 DBG_ASSERT(pDoc->GetSrcVersion() <= SC_SUBTOTAL_BUGFIX,
+//UNUSED2008-05 "user defined style without SFXSTYLEBIT_USERDEF");
+//UNUSED2008-05 pStyle->SetMask( pStyle->GetMask() | SFXSTYLEBIT_USERDEF );
+//UNUSED2008-05 }
+//UNUSED2008-05 // else: wrong old ID and no new ID found:
+//UNUSED2008-05 // probably default style from a different language
+//UNUSED2008-05 // -> leave unchanged (HelpId will be set if loaded with matching
+//UNUSED2008-05 // language version later)
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------------
+
+ScStyleSheet* ScStyleSheetPool::FindCaseIns( const String& rName, SfxStyleFamily eFam )
+{
+ String aUpSearch = rName;
+ ScGlobal::pCharClass->toUpper(aUpSearch);
+
+ sal_uInt32 nCount = aStyles.size();
+ for (sal_uInt32 n=0; n<nCount; n++)
+ {
+ SfxStyleSheetBase* pStyle = aStyles[n].get();
+ if ( pStyle->GetFamily() == eFam )
+ {
+ String aUpName = pStyle->GetName();
+ ScGlobal::pCharClass->toUpper(aUpName);
+ if (aUpName == aUpSearch)
+ return (ScStyleSheet*)pStyle;
+ }
+ }
+
+ return NULL;
+}
+
diff --git a/sc/source/core/data/stlsheet.cxx b/sc/source/core/data/stlsheet.cxx
new file mode 100644
index 000000000000..a3319eafd3fd
--- /dev/null
+++ b/sc/source/core/data/stlsheet.cxx
@@ -0,0 +1,346 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+#include "document.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <sfx2/printer.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/smplhint.hxx>
+#include "attrib.hxx"
+
+
+#include <vcl/svapp.hxx> // GetSettings()
+
+#include "globstr.hrc"
+#include "sc.hrc"
+//------------------------------------------------------------------------
+
+TYPEINIT1(ScStyleSheet, SfxStyleSheet);
+
+#define TWO_CM 1134
+#define HFDIST_CM 142
+
+//========================================================================
+
+ScStyleSheet::ScStyleSheet( const String& rName,
+ ScStyleSheetPool& rPoolP,
+ SfxStyleFamily eFamily,
+ USHORT nMaskP )
+
+ : SfxStyleSheet ( rName, rPoolP, eFamily, nMaskP )
+ , eUsage( UNKNOWN )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScStyleSheet::ScStyleSheet( const ScStyleSheet& rStyle )
+ : SfxStyleSheet ( rStyle )
+ , eUsage( UNKNOWN )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScStyleSheet::~ScStyleSheet()
+{
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScStyleSheet::HasFollowSupport() const
+{
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScStyleSheet::HasParentSupport () const
+{
+ BOOL bHasParentSupport = FALSE;
+
+ switch ( GetFamily() )
+ {
+ case SFX_STYLE_FAMILY_PARA: bHasParentSupport = TRUE; break;
+ case SFX_STYLE_FAMILY_PAGE: bHasParentSupport = FALSE; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ return bHasParentSupport;
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScStyleSheet::SetParent( const String& rParentName )
+{
+ BOOL bResult = FALSE;
+ String aEffName = rParentName;
+ SfxStyleSheetBase* pStyle = rPool.Find( aEffName, nFamily );
+ if (!pStyle)
+ {
+ SfxStyleSheetIterator* pIter = rPool.CreateIterator( nFamily, SFXSTYLEBIT_ALL );
+ pStyle = pIter->First();
+ if (pStyle)
+ aEffName = pStyle->GetName();
+ }
+
+ if ( pStyle && aEffName != GetName() )
+ {
+ bResult = SfxStyleSheet::SetParent( aEffName );
+ if (bResult)
+ {
+ SfxItemSet& rParentSet = pStyle->GetItemSet();
+ GetItemSet().SetParent( &rParentSet );
+ }
+ }
+
+ return bResult;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemSet& __EXPORT ScStyleSheet::GetItemSet()
+{
+ if ( !pSet )
+ {
+ switch ( GetFamily() )
+ {
+ case SFX_STYLE_FAMILY_PAGE:
+ {
+ // Seitenvorlagen sollen nicht ableitbar sein,
+ // deshalb werden an dieser Stelle geeignete
+ // Werte eingestellt. (==Standard-Seitenvorlage)
+
+ SfxItemPool& rItemPool = GetPool().GetPool();
+ pSet = new SfxItemSet( rItemPool,
+ ATTR_BACKGROUND, ATTR_BACKGROUND,
+ ATTR_BORDER, ATTR_SHADOW,
+ ATTR_LRSPACE, ATTR_PAGE_SCALETO,
+ ATTR_WRITINGDIR, ATTR_WRITINGDIR,
+ ATTR_USERDEF, ATTR_USERDEF,
+ 0 );
+
+ // Wenn gerade geladen wird, wird auch der Set hinterher aus der Datei
+ // gefuellt, es brauchen also keine Defaults gesetzt zu werden.
+ // GetPrinter wuerde dann auch einen neuen Printer anlegen, weil der
+ // gespeicherte Printer noch nicht geladen ist!
+
+ ScDocument* pDoc = ((ScStyleSheetPool&)GetPool()).GetDocument();
+ if ( pDoc )
+ {
+ // Setzen von sinnvollen Default-Werten:
+ SvxPageItem aPageItem( ATTR_PAGE );
+ SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetDefaultPaperSize() );
+
+ SvxSetItem aHFSetItem(
+ (const SvxSetItem&)
+ rItemPool.GetDefaultItem(ATTR_PAGE_HEADERSET) );
+
+ SfxItemSet& rHFSet = aHFSetItem.GetItemSet();
+ SvxSizeItem aHFSizeItem( // 0,5 cm + Abstand
+ ATTR_PAGE_SIZE,
+ Size( 0, (long)( 500 / HMM_PER_TWIPS ) + HFDIST_CM ) );
+
+ SvxULSpaceItem aHFDistItem ( HFDIST_CM,// nUp
+ HFDIST_CM,// nLow
+ ATTR_ULSPACE );
+
+ SvxLRSpaceItem aLRSpaceItem( TWO_CM, // nLeft
+ TWO_CM, // nRight
+ TWO_CM, // nTLeft
+ 0, // nFirstLineOffset
+ ATTR_LRSPACE );
+ SvxULSpaceItem aULSpaceItem( TWO_CM, // nUp
+ TWO_CM, // nLow
+ ATTR_ULSPACE );
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+
+ aBoxInfoItem.SetTable( FALSE );
+ aBoxInfoItem.SetDist( TRUE );
+ aBoxInfoItem.SetValid( VALID_DISTANCE, TRUE );
+
+ // aPageItem.SetLandscape( ORIENTATION_LANDSCAPE == pPrinter->GetOrientation() );
+ aPageItem.SetLandscape( FALSE );
+
+ rHFSet.Put( aBoxInfoItem );
+ rHFSet.Put( aHFSizeItem );
+ rHFSet.Put( aHFDistItem );
+ rHFSet.Put( SvxLRSpaceItem( 0,0,0,0, ATTR_LRSPACE ) ); // Rand auf Null setzen
+
+ pSet->Put( aHFSetItem, ATTR_PAGE_HEADERSET );
+ pSet->Put( aHFSetItem, ATTR_PAGE_FOOTERSET );
+ pSet->Put( aBoxInfoItem ); // PoolDefault wg. Formatvorlagen
+ // nicht ueberschreiben!
+
+ // Writing direction: not as pool default because the default for cells
+ // must remain FRMDIR_ENVIRONMENT, and each page style's setting is
+ // supposed to be saved in the file format.
+ // The page default depends on the system language.
+ SvxFrameDirection eDirection = ScGlobal::IsSystemRTL() ?
+ FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP;
+ pSet->Put( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ), ATTR_WRITINGDIR );
+
+ rItemPool.SetPoolDefaultItem( aPageItem );
+ rItemPool.SetPoolDefaultItem( aPaperSizeItem );
+ rItemPool.SetPoolDefaultItem( aLRSpaceItem );
+ rItemPool.SetPoolDefaultItem( aULSpaceItem );
+ rItemPool.SetPoolDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALE, 100 ) );
+ ScPageScaleToItem aScaleToItem;
+ rItemPool.SetPoolDefaultItem( aScaleToItem );
+ rItemPool.SetPoolDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, 0 ) );
+ }
+ }
+ break;
+
+ case SFX_STYLE_FAMILY_PARA:
+ default:
+ pSet = new SfxItemSet( GetPool().GetPool(),
+ ATTR_PATTERN_START, ATTR_PATTERN_END,
+ 0 );
+ break;
+ }
+ bMySet = TRUE;
+ } // if ( !pSet )
+ if ( nHelpId == HID_SC_SHEET_CELL_ERG1 )
+ {
+ if ( !pSet->Count() )
+ {
+ ScDocument* pDoc = ((ScStyleSheetPool&)GetPool()).GetDocument();
+ if ( pDoc )
+ {
+ ULONG nNumFmt = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_CURRENCY,ScGlobal::eLnge );
+ pSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumFmt ) );
+ } // if ( pDoc && pDoc->IsLoadingDone() )
+ }
+ }
+
+ return *pSet;
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScStyleSheet::IsUsed() const
+{
+ if ( GetFamily() == SFX_STYLE_FAMILY_PARA )
+ {
+ // Always query the document to let it decide if a rescan is necessary,
+ // and store the state.
+ ScDocument* pDoc = ((ScStyleSheetPool&)rPool).GetDocument();
+ if ( pDoc && pDoc->IsStyleSheetUsed( *this, TRUE ) )
+ eUsage = USED;
+ else
+ eUsage = NOTUSED;
+ return eUsage == USED;
+ }
+ else
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScStyleSheet::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA(SfxSimpleHint) )
+ if ( ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ GetItemSet().SetParent( NULL );
+}
+
+//------------------------------------------------------------------------
+
+// #66123# schmutzige Tricks, um die Standard-Vorlage immer als "Standard" zu speichern,
+// obwohl der fuer den Benutzer sichtbare Name uebersetzt ist:
+
+const String& ScStyleSheet::GetName() const
+{
+ const String& rBase = SfxStyleSheet::GetName();
+ const String* pForceStdName = ((ScStyleSheetPool&)rPool).GetForceStdName();
+ if ( pForceStdName && rBase == ScGlobal::GetRscString(STR_STYLENAME_STANDARD) )
+ return *pForceStdName;
+ else
+ return rBase;
+}
+
+const String& ScStyleSheet::GetParent() const
+{
+ const String& rBase = SfxStyleSheet::GetParent();
+ const String* pForceStdName = ((ScStyleSheetPool&)rPool).GetForceStdName();
+ if ( pForceStdName && rBase == ScGlobal::GetRscString(STR_STYLENAME_STANDARD) )
+ return *pForceStdName;
+ else
+ return rBase;
+}
+
+const String& ScStyleSheet::GetFollow() const
+{
+ const String& rBase = SfxStyleSheet::GetFollow();
+ const String* pForceStdName = ((ScStyleSheetPool&)rPool).GetForceStdName();
+ if ( pForceStdName && rBase == ScGlobal::GetRscString(STR_STYLENAME_STANDARD) )
+ return *pForceStdName;
+ else
+ return rBase;
+}
+
+// Verhindern, dass ein Style "Standard" angelegt wird, wenn das nicht der
+// Standard-Name ist, weil sonst beim Speichern zwei Styles denselben Namen haetten
+// (Beim Laden wird der Style direkt per Make mit dem Namen erzeugt, so dass diese
+// Abfrage dann nicht gilt)
+//! Wenn irgendwann aus dem Laden SetName aufgerufen wird, muss fuer das Laden ein
+//! Flag gesetzt und abgefragt werden.
+//! Die ganze Abfrage muss raus, wenn fuer eine neue Datei-Version die Namens-Umsetzung wegfaellt.
+
+BOOL ScStyleSheet::SetName( const String& rNew )
+{
+ String aFileStdName = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STRING_STANDARD));
+ if ( rNew == aFileStdName && aFileStdName != ScGlobal::GetRscString(STR_STYLENAME_STANDARD) )
+ return FALSE;
+ else
+ return SfxStyleSheet::SetName( rNew );
+}
+
+
+
diff --git a/sc/source/core/data/tabbgcolor.cxx b/sc/source/core/data/tabbgcolor.cxx
new file mode 100644
index 000000000000..a3d9eec16d99
--- /dev/null
+++ b/sc/source/core/data/tabbgcolor.cxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * 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: tabbgcolor.hxx,v $
+ * $Revision: 1.00 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "tabbgcolor.hxx"
+
+bool ScUndoTabColorInfo::IsDefaultOldTabBgColor() const
+{
+ return maOldTabBgColor == Color(COL_AUTO);
+}
+
+bool ScUndoTabColorInfo::IsDefaultNewTabBgColor() const
+{
+ return maOldTabBgColor == Color(COL_AUTO);
+}
+
+ScUndoTabColorInfo::ScUndoTabColorInfo(SCTAB nTab) :
+ mnTabId(nTab),
+ maOldTabBgColor(COL_AUTO),
+ maNewTabBgColor(COL_AUTO)
+{
+}
+
+ScUndoTabColorInfo::ScUndoTabColorInfo(const ScUndoTabColorInfo& r) :
+ mnTabId(r.mnTabId),
+ maOldTabBgColor(r.maOldTabBgColor),
+ maNewTabBgColor(r.maNewTabBgColor)
+{
+}
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
new file mode 100644
index 000000000000..7abebea23686
--- /dev/null
+++ b/sc/source/core/data/table1.cxx
@@ -0,0 +1,1721 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <unotools/textsearch.hxx>
+#include <sfx2/objsh.hxx>
+
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "table.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "olinetab.hxx"
+#include "stlsheet.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "refupdat.hxx"
+#include "markdata.hxx"
+#include "progress.hxx"
+#include "hints.hxx" // fuer Paint-Broadcast
+#include "prnsave.hxx"
+#include "tabprotection.hxx"
+#include "sheetevents.hxx"
+#include "segmenttree.hxx"
+
+// -----------------------------------------------------------------------
+
+ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
+ BOOL bColInfo, BOOL bRowInfo ) :
+ aName( rNewName ),
+ aCodeName( rNewName ),
+ bScenario( FALSE ),
+ bLayoutRTL( FALSE ),
+ bLoadingRTL( FALSE ),
+ nLinkMode( 0 ),
+ aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
+ bPageSizeValid( FALSE ),
+ nRepeatStartX( SCCOL_REPEAT_NONE ),
+ nRepeatStartY( SCROW_REPEAT_NONE ),
+ pTabProtection( NULL ),
+ pColWidth( NULL ),
+ mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
+ pColFlags( NULL ),
+ pRowFlags( NULL ),
+ mpHiddenCols(new ScFlatBoolColSegments),
+ mpHiddenRows(new ScFlatBoolRowSegments),
+ mpFilteredCols(new ScFlatBoolColSegments),
+ mpFilteredRows(new ScFlatBoolRowSegments),
+ pOutlineTable( NULL ),
+ pSheetEvents( NULL ),
+ bTableAreaValid( FALSE ),
+ bVisible( TRUE ),
+ bStreamValid( FALSE ),
+ bPendingRowHeights( FALSE ),
+ bCalcNotification( FALSE ),
+ nTab( nNewTab ),
+ nRecalcLvl( 0 ),
+ pDocument( pDoc ),
+ pSearchParam( NULL ),
+ pSearchText ( NULL ),
+ pSortCollator( NULL ),
+ bPrintEntireSheet( FALSE ),
+ pRepeatColRange( NULL ),
+ pRepeatRowRange( NULL ),
+ nLockCount( 0 ),
+ pScenarioRanges( NULL ),
+ aScenarioColor( COL_LIGHTGRAY ),
+ aTabBgColor( COL_AUTO ),
+ nScenarioFlags( 0 ),
+ bActiveScenario( FALSE ),
+ mbPageBreaksValid(false)
+{
+
+ if (bColInfo)
+ {
+ pColWidth = new USHORT[ MAXCOL+1 ];
+ pColFlags = new BYTE[ MAXCOL+1 ];
+
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ {
+ pColWidth[i] = STD_COL_WIDTH;
+ pColFlags[i] = 0;
+ }
+ }
+
+ if (bRowInfo)
+ {
+ mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
+ pRowFlags = new ScBitMaskCompressedArray< SCROW, BYTE>( MAXROW, 0);
+ }
+
+ if ( pDocument->IsDocVisible() )
+ {
+ // when a sheet is added to a visible document,
+ // initialize its RTL flag from the system locale
+ bLayoutRTL = ScGlobal::IsSystemRTL();
+ }
+
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ if ( pDrawLayer->ScAddPage( nTab ) ) // FALSE (not inserted) during Undo
+ {
+ pDrawLayer->ScRenamePage( nTab, aName );
+ ULONG nx = (ULONG) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
+ ULONG ny = (ULONG) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
+ pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
+ }
+ }
+
+ for (SCCOL k=0; k<=MAXCOL; k++)
+ aCol[k].Init( k, nTab, pDocument );
+}
+
+ScTable::~ScTable()
+{
+ if (!pDocument->IsInDtorClear())
+ {
+ // nicht im dtor die Pages in der falschen Reihenfolge loeschen
+ // (nTab stimmt dann als Page-Number nicht!)
+ // In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
+
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ pDrawLayer->ScRemovePage( nTab );
+ }
+
+ delete[] pColWidth;
+ delete[] pColFlags;
+ delete pRowFlags;
+ delete pSheetEvents;
+ delete pOutlineTable;
+ delete pSearchParam;
+ delete pSearchText;
+ delete pRepeatColRange;
+ delete pRepeatRowRange;
+ delete pScenarioRanges;
+ DestroySortCollator();
+}
+
+void ScTable::GetName( String& rName ) const
+{
+ rName = aName;
+}
+
+void ScTable::SetName( const String& rNewName )
+{
+ aName = rNewName;
+ aUpperName.Erase(); // invalidated if the name is changed
+
+ // SetStreamValid is handled in ScDocument::RenameTab
+}
+
+const String& ScTable::GetUpperName() const
+{
+ if ( !aUpperName.Len() && aName.Len() )
+ aUpperName = ScGlobal::pCharClass->upper( aName );
+ return aUpperName;
+}
+
+void ScTable::SetVisible( BOOL bVis )
+{
+ if (bVisible != bVis && IsStreamValid())
+ SetStreamValid(FALSE);
+
+ bVisible = bVis;
+}
+
+void ScTable::SetStreamValid( BOOL bSet, BOOL bIgnoreLock )
+{
+ if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
+ bStreamValid = bSet;
+}
+
+void ScTable::SetPendingRowHeights( BOOL bSet )
+{
+ bPendingRowHeights = bSet;
+}
+
+void ScTable::SetLayoutRTL( BOOL bSet )
+{
+ bLayoutRTL = bSet;
+}
+
+void ScTable::SetLoadingRTL( BOOL bSet )
+{
+ bLoadingRTL = bSet;
+}
+
+const Color& ScTable::GetTabBgColor() const
+{
+ return aTabBgColor;
+}
+
+void ScTable::SetTabBgColor(const Color& rColor)
+{
+ if (aTabBgColor != rColor)
+ {
+ // The tab color has changed. Set this table 'modified'.
+ aTabBgColor = rColor;
+ if (IsStreamValid())
+ SetStreamValid(false);
+ }
+}
+
+void ScTable::SetScenario( BOOL bFlag )
+{
+ bScenario = bFlag;
+}
+
+void ScTable::SetLink( BYTE nMode,
+ const String& rDoc, const String& rFlt, const String& rOpt,
+ const String& rTab, ULONG nRefreshDelay )
+{
+ nLinkMode = nMode;
+ aLinkDoc = rDoc; // Datei
+ aLinkFlt = rFlt; // Filter
+ aLinkOpt = rOpt; // Filter-Optionen
+ aLinkTab = rTab; // Tabellenname in Quelldatei
+ nLinkRefreshDelay = nRefreshDelay; // refresh delay in seconds, 0==off
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+USHORT ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula, const ScMarkData* pMarkData,
+ BOOL bSimpleTextImport )
+{
+ return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
+ bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, bSimpleTextImport );
+}
+
+long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bWidth, BOOL bTotalSize )
+{
+ ScNeededSizeOptions aOptions;
+ aOptions.bSkipMerged = FALSE; // zusammengefasste mitzaehlen
+ aOptions.bTotalSize = bTotalSize;
+
+ return aCol[nCol].GetNeededSize
+ ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions );
+}
+
+BOOL ScTable::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT nExtra,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bForce, ScProgress* pOuterProgress, ULONG nProgressStart )
+{
+ DBG_ASSERT( nExtra==0 || bForce, "autom. OptimalHeight mit Extra" );
+
+ if ( !pDocument->IsAdjustHeightEnabled() )
+ {
+ return FALSE;
+ }
+
+ BOOL bChanged = FALSE;
+ SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
+
+ ScProgress* pProgress = NULL;
+ if ( pOuterProgress )
+ pProgress = pOuterProgress;
+ else if ( nCount > 1 )
+ pProgress = new ScProgress( pDocument->GetDocumentShell(),
+ ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), GetWeightedCount() );
+
+ USHORT* pHeight = new USHORT[nCount]; // Twips !
+ memset( pHeight, 0, sizeof(USHORT) * nCount );
+
+ // zuerst einmal ueber den ganzen Bereich
+ // (mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
+ // Standard formatiert ist)
+
+ aCol[MAXCOL].GetOptimalHeight(
+ nStartRow, nEndRow, pHeight, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce, 0, 0 );
+
+ // daraus Standardhoehe suchen, die im unteren Bereich gilt
+
+ USHORT nMinHeight = pHeight[nCount-1];
+ SCSIZE nPos = nCount-1;
+ while ( nPos && pHeight[nPos-1] >= nMinHeight )
+ --nPos;
+ SCROW nMinStart = nStartRow + nPos;
+
+ ULONG nWeightedCount = 0;
+ for (SCCOL nCol=0; nCol<MAXCOL; nCol++) // MAXCOL schon oben
+ {
+ aCol[nCol].GetOptimalHeight(
+ nStartRow, nEndRow, pHeight, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
+ nMinHeight, nMinStart );
+
+ if (pProgress)
+ {
+ ULONG nWeight = aCol[nCol].GetWeightedCount();
+ if (nWeight) // nochmal denselben Status muss auch nicht sein
+ {
+ nWeightedCount += nWeight;
+ pProgress->SetState( nWeightedCount + nProgressStart );
+ }
+ }
+ }
+
+ SCROW nRngStart = 0;
+ SCROW nRngEnd = 0;
+ USHORT nLast = 0;
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ size_t nIndex;
+ SCROW nRegionEndRow;
+ BYTE nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
+ if ( nRegionEndRow > nEndRow )
+ nRegionEndRow = nEndRow;
+ SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i ); // additional equal rows after first
+
+ bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
+ if ( bAutoSize || bForce )
+ {
+ if (nExtra)
+ {
+ if (bAutoSize)
+ pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
+ }
+ else if (!bAutoSize)
+ pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
+
+ for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
+ {
+ if (nLast)
+ {
+ if (pHeight[nInner]+nExtra == nLast)
+ nRngEnd = nStartRow+nInner;
+ else
+ {
+ bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
+ nLast = 0;
+ }
+ }
+ if (!nLast)
+ {
+ nLast = pHeight[nInner]+nExtra;
+ nRngStart = nStartRow+nInner;
+ nRngEnd = nStartRow+nInner;
+ }
+ }
+ }
+ else
+ {
+ if (nLast)
+ bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
+ nLast = 0;
+ }
+ i += nMoreRows; // already handled - skip
+ }
+ if (nLast)
+ bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
+
+ delete[] pHeight;
+ if ( pProgress != pOuterProgress )
+ delete pProgress;
+
+ return bChanged;
+}
+
+BOOL ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
+{
+ BOOL bFound = FALSE;
+ SCCOL nMaxX = 0;
+ SCROW nMaxY = 0;
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ if (!aCol[i].IsEmptyVisData(TRUE)) // TRUE = Notizen zaehlen auch
+ {
+ bFound = TRUE;
+ nMaxX = i;
+ SCROW nColY = aCol[i].GetLastVisDataPos(TRUE);
+ if (nColY > nMaxY)
+ nMaxY = nColY;
+ }
+
+ rEndCol = nMaxX;
+ rEndRow = nMaxY;
+ return bFound;
+}
+
+BOOL ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const
+{
+ BOOL bRet = TRUE; //! merken?
+ if (!bTableAreaValid)
+ {
+ bRet = GetPrintArea( ((ScTable*)this)->nTableAreaX,
+ ((ScTable*)this)->nTableAreaY, TRUE );
+ ((ScTable*)this)->bTableAreaValid = TRUE;
+ }
+ rEndCol = nTableAreaX;
+ rEndRow = nTableAreaY;
+ return bRet;
+}
+
+/* vorher:
+
+ BOOL bFound = FALSE;
+ SCCOL nMaxX = 0;
+ SCROW nMaxY = 0;
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ if (!aCol[i].IsEmpty())
+ {
+ bFound = TRUE;
+ nMaxX = i;
+ SCCOL nColY = aCol[i].GetLastEntryPos();
+ if (nColY > nMaxY)
+ nMaxY = nColY;
+ }
+
+ rEndCol = nMaxX;
+ rEndRow = nMaxY;
+ return bFound;
+*/
+
+const SCCOL SC_COLUMNS_STOP = 30;
+
+BOOL ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, BOOL bNotes ) const
+{
+ BOOL bFound = FALSE;
+ SCCOL nMaxX = 0;
+ SCROW nMaxY = 0;
+ SCCOL i;
+
+ for (i=0; i<=MAXCOL; i++) // Daten testen
+ if (!aCol[i].IsEmptyVisData(bNotes))
+ {
+ bFound = TRUE;
+ if (i>nMaxX)
+ nMaxX = i;
+ SCROW nColY = aCol[i].GetLastVisDataPos(bNotes);
+ if (nColY > nMaxY)
+ nMaxY = nColY;
+ }
+
+ SCCOL nMaxDataX = nMaxX;
+
+ for (i=0; i<=MAXCOL; i++) // Attribute testen
+ {
+ SCROW nLastRow;
+ if (aCol[i].GetLastVisibleAttr( nLastRow ))
+ {
+ bFound = TRUE;
+ nMaxX = i;
+ if (nLastRow > nMaxY)
+ nMaxY = nLastRow;
+ }
+ }
+
+ if (nMaxX == MAXCOL) // Attribute rechts weglassen
+ {
+ --nMaxX;
+ while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1]) )
+ --nMaxX;
+ }
+
+ if ( nMaxX < nMaxDataX )
+ {
+ nMaxX = nMaxDataX;
+ }
+ else if ( nMaxX > nMaxDataX )
+ {
+ SCCOL nAttrStartX = nMaxDataX + 1;
+ while ( nAttrStartX < MAXCOL )
+ {
+ SCCOL nAttrEndX = nAttrStartX;
+ while ( nAttrEndX < MAXCOL && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1]) )
+ ++nAttrEndX;
+ if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
+ {
+ // found equally-formatted columns behind data -> stop before these columns
+ nMaxX = nAttrStartX - 1;
+
+ // also don't include default-formatted columns before that
+ SCROW nDummyRow;
+ while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow ) )
+ --nMaxX;
+ break;
+ }
+ nAttrStartX = nAttrEndX + 1;
+ }
+ }
+
+ rEndCol = nMaxX;
+ rEndRow = nMaxY;
+ return bFound;
+}
+
+BOOL ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
+ SCCOL& rEndCol, BOOL /* bNotes */ ) const
+{
+ BOOL bFound = FALSE;
+ SCCOL nMaxX = 0;
+ SCCOL i;
+
+ for (i=0; i<=MAXCOL; i++) // Attribute testen
+ {
+ if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
+ {
+ bFound = TRUE;
+ nMaxX = i;
+ }
+ }
+
+ if (nMaxX == MAXCOL) // Attribute rechts weglassen
+ {
+ --nMaxX;
+ while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
+ --nMaxX;
+ }
+
+ for (i=0; i<=MAXCOL; i++) // Daten testen
+ {
+ if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow )) //! bNotes ??????
+ {
+ bFound = TRUE;
+ if (i>nMaxX)
+ nMaxX = i;
+ }
+ }
+
+ rEndCol = nMaxX;
+ return bFound;
+}
+
+BOOL ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
+ SCROW& rEndRow, BOOL bNotes ) const
+{
+ BOOL bFound = FALSE;
+ SCROW nMaxY = 0;
+ SCCOL i;
+
+ for (i=nStartCol; i<=nEndCol; i++) // Attribute testen
+ {
+ SCROW nLastRow;
+ if (aCol[i].GetLastVisibleAttr( nLastRow ))
+ {
+ bFound = TRUE;
+ if (nLastRow > nMaxY)
+ nMaxY = nLastRow;
+ }
+ }
+
+ for (i=nStartCol; i<=nEndCol; i++) // Daten testen
+ if (!aCol[i].IsEmptyVisData(bNotes))
+ {
+ bFound = TRUE;
+ SCROW nColY = aCol[i].GetLastVisDataPos(bNotes);
+ if (nColY > nMaxY)
+ nMaxY = nColY;
+ }
+
+ rEndRow = nMaxY;
+ return bFound;
+}
+
+BOOL ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
+{
+ BOOL bFound = FALSE;
+ SCCOL nMinX = MAXCOL;
+ SCROW nMinY = MAXROW;
+ SCCOL i;
+
+ for (i=0; i<=MAXCOL; i++) // Attribute testen
+ {
+ SCROW nFirstRow;
+ if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
+ {
+ if (!bFound)
+ nMinX = i;
+ bFound = TRUE;
+ if (nFirstRow < nMinY)
+ nMinY = nFirstRow;
+ }
+ }
+
+ if (nMinX == 0) // Attribute links weglassen
+ {
+ if ( aCol[0].IsVisibleAttrEqual(aCol[1]) ) // keine einzelnen
+ {
+ ++nMinX;
+ while ( nMinX<MAXCOL && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1]) )
+ ++nMinX;
+ }
+ }
+
+ BOOL bDatFound = FALSE;
+ for (i=0; i<=MAXCOL; i++) // Daten testen
+ if (!aCol[i].IsEmptyVisData(TRUE))
+ {
+ if (!bDatFound && i<nMinX)
+ nMinX = i;
+ bFound = bDatFound = TRUE;
+ SCROW nColY = aCol[i].GetFirstVisDataPos(TRUE);
+ if (nColY < nMinY)
+ nMinY = nColY;
+ }
+
+ rStartCol = nMinX;
+ rStartRow = nMinY;
+ return bFound;
+}
+
+void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
+ BOOL bIncludeOld, bool bOnlyDown ) const
+{
+ BOOL bLeft = FALSE;
+ BOOL bRight = FALSE;
+ BOOL bTop = FALSE;
+ BOOL bBottom = FALSE;
+ BOOL bChanged;
+ BOOL bFound;
+ SCCOL i;
+ SCROW nTest;
+
+ do
+ {
+ bChanged = FALSE;
+
+ if (!bOnlyDown)
+ {
+ SCROW nStart = rStartRow;
+ SCROW nEnd = rEndRow;
+ if (nStart>0) --nStart;
+ if (nEnd<MAXROW) ++nEnd;
+
+ if (rEndCol < MAXCOL)
+ if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
+ {
+ ++rEndCol;
+ bChanged = TRUE;
+ bRight = TRUE;
+ }
+
+ if (rStartCol > 0)
+ if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd))
+ {
+ --rStartCol;
+ bChanged = TRUE;
+ bLeft = TRUE;
+ }
+
+ if (rStartRow > 0)
+ {
+ nTest = rStartRow-1;
+ bFound = FALSE;
+ for (i=rStartCol; i<=rEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt(nTest))
+ bFound = TRUE;
+ if (bFound)
+ {
+ --rStartRow;
+ bChanged = TRUE;
+ bTop = TRUE;
+ }
+ }
+ }
+
+ if (rEndRow < MAXROW)
+ {
+ nTest = rEndRow+1;
+ bFound = FALSE;
+ for (i=rStartCol; i<=rEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt(nTest))
+ bFound = TRUE;
+ if (bFound)
+ {
+ ++rEndRow;
+ bChanged = TRUE;
+ bBottom = TRUE;
+ }
+ }
+ }
+ while( bChanged );
+
+ if ( !bIncludeOld )
+ {
+ if ( !bLeft && rStartCol < MAXCOL && rStartCol < rEndCol )
+ if ( aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
+ ++rStartCol;
+ if ( !bRight && rEndCol > 0 && rStartCol < rEndCol )
+ if ( aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
+ --rEndCol;
+ if ( !bTop && rStartRow < MAXROW && rStartRow < rEndRow )
+ {
+ bFound = FALSE;
+ for (i=rStartCol; i<=rEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt(rStartRow))
+ bFound = TRUE;
+ if (!bFound)
+ ++rStartRow;
+ }
+ if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
+ {
+ bFound = FALSE;
+ for (i=rStartCol; i<=rEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt(rEndRow))
+ bFound = TRUE;
+ if (!bFound)
+ --rEndRow;
+ }
+ }
+}
+
+
+bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
+{
+ o_bShrunk = false;
+
+ PutInOrder( rStartCol, rEndCol);
+ PutInOrder( rStartRow, rEndRow);
+ if (rStartCol < 0)
+ rStartCol = 0, o_bShrunk = true;
+ if (rStartRow < 0)
+ rStartRow = 0, o_bShrunk = true;
+ if (rEndCol > MAXCOL)
+ rEndCol = MAXCOL, o_bShrunk = true;
+ if (rEndRow > MAXROW)
+ rEndRow = MAXROW, o_bShrunk = true;
+
+ bool bChanged;
+ do
+ {
+ bChanged = false;
+
+ while (rStartCol < rEndCol)
+ {
+ if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
+ {
+ --rEndCol;
+ bChanged = true;
+ }
+ else
+ break; // while
+ }
+
+ while (rStartCol < rEndCol)
+ {
+ if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
+ {
+ ++rStartCol;
+ bChanged = true;
+ }
+ else
+ break; // while
+ }
+
+ if (!bColumnsOnly)
+ {
+ if (rStartRow < rEndRow)
+ {
+ bool bFound = false;
+ for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt( rStartRow))
+ bFound = true;
+ if (!bFound)
+ {
+ ++rStartRow;
+ bChanged = true;
+ }
+ }
+
+ if (rStartRow < rEndRow)
+ {
+ bool bFound = false;
+ for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt( rEndRow))
+ bFound = true;
+ if (!bFound)
+ {
+ --rEndRow;
+ bChanged = true;
+ }
+ }
+ }
+
+ if (bChanged)
+ o_bShrunk = true;
+ } while( bChanged );
+
+ return rStartCol != rEndCol || (bColumnsOnly ?
+ !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
+ (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
+}
+
+
+SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, ScDirection eDir )
+{
+ SCSIZE nCount = 0;
+ SCCOL nCol;
+ if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
+ {
+ nCount = static_cast<SCSIZE>(nEndRow - nStartRow);
+ for (nCol = nStartCol; nCol <= nEndCol; nCol++)
+ nCount = Min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
+ }
+ else if (eDir == DIR_RIGHT)
+ {
+ nCol = nEndCol;
+ while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
+ aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
+ {
+ nCount++;
+ nCol--;
+ }
+ }
+ else
+ {
+ nCol = nStartCol;
+ while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
+ {
+ nCount++;
+ nCol++;
+ }
+ }
+ return nCount;
+}
+
+BOOL ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol )
+{
+ BOOL bFound = FALSE;
+ for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
+ if (aCol[i].HasDataAt(nRow))
+ bFound = TRUE;
+ return !bFound;
+}
+
+void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow )
+{
+ while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
+ ++rStartCol;
+
+ while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
+ --rEndCol;
+
+ while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
+ ++rStartRow;
+
+ while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
+ --rEndRow;
+}
+
+void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY )
+{
+ if (nMovX)
+ {
+ SCsCOL nNewCol = (SCsCOL) rCol;
+ BOOL bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
+ BOOL bFnd;
+ if (bThere)
+ {
+ do
+ {
+ nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX );
+ bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : FALSE;
+ }
+ while (bFnd);
+ nNewCol = sal::static_int_cast<SCsCOL>( nNewCol - nMovX );
+
+ if (nNewCol == (SCsCOL)rCol)
+ bThere = FALSE;
+ }
+
+ if (!bThere)
+ {
+ do
+ {
+ nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX );
+ bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : TRUE;
+ }
+ while (!bFnd);
+ }
+
+ if (nNewCol<0) nNewCol=0;
+ if (nNewCol>MAXCOL) nNewCol=MAXCOL;
+ rCol = (SCCOL) nNewCol;
+ }
+
+ if (nMovY)
+ aCol[rCol].FindDataAreaPos(rRow,nMovY);
+}
+
+BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
+ BOOL bMarked, BOOL bUnprotected )
+{
+ 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;
+
+ if (bUnprotected && ((const ScProtectionAttr*)
+ GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
+ return FALSE;
+
+ if (bMarked || bUnprotected) //! auch sonst ???
+ {
+ // #53697# ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
+ // auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
+ //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
+
+ if (RowHidden(nRow))
+ return FALSE;
+
+ if (ColHidden(nCol))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
+ BOOL bMarked, BOOL bUnprotected, const ScMarkData& rMark )
+{
+ if (bUnprotected && !IsProtected()) // Tabelle ueberhaupt geschuetzt?
+ bUnprotected = FALSE;
+
+ USHORT nWrap = 0;
+ SCsCOL nCol = rCol;
+ SCsROW nRow = rRow;
+
+ nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
+ nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
+
+ DBG_ASSERT( !nMovY || !bUnprotected,
+ "GetNextPos mit bUnprotected horizontal nicht implementiert" );
+
+ if ( nMovY && bMarked )
+ {
+ BOOL bUp = ( nMovY < 0 );
+ nRow = rMark.GetNextMarked( nCol, nRow, bUp );
+ while ( VALIDROW(nRow) &&
+ (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
+ {
+ // #53697# ausgeblendete ueberspringen (s.o.)
+ nRow += nMovY;
+ nRow = rMark.GetNextMarked( nCol, nRow, bUp );
+ }
+
+ while ( nRow < 0 || nRow > MAXROW )
+ {
+ nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
+ while ( VALIDCOL(nCol) && ColHidden(nCol) )
+ nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // #53697# skip hidden rows (see above)
+ if (nCol < 0)
+ {
+ nCol = MAXCOL;
+ if (++nWrap >= 2)
+ return;
+ }
+ else if (nCol > MAXCOL)
+ {
+ nCol = 0;
+ if (++nWrap >= 2)
+ return;
+ }
+ if (nRow < 0)
+ nRow = MAXROW;
+ else if (nRow > MAXROW)
+ nRow = 0;
+ nRow = rMark.GetNextMarked( nCol, nRow, bUp );
+ while ( VALIDROW(nRow) &&
+ (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
+ {
+ // #53697# ausgeblendete ueberspringen (s.o.)
+ nRow += nMovY;
+ nRow = rMark.GetNextMarked( nCol, nRow, bUp );
+ }
+ }
+ }
+
+ if ( nMovX && ( bMarked || bUnprotected ) )
+ {
+ // initiales Weiterzaehlen wrappen:
+ if (nCol<0)
+ {
+ nCol = MAXCOL;
+ --nRow;
+ if (nRow<0)
+ nRow = MAXROW;
+ }
+ if (nCol>MAXCOL)
+ {
+ nCol = 0;
+ ++nRow;
+ if (nRow>MAXROW)
+ nRow = 0;
+ }
+
+ if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
+ {
+ SCsROW* pNextRows = new SCsROW[MAXCOL+1];
+ SCCOL i;
+
+ if ( nMovX > 0 ) // vorwaerts
+ {
+ for (i=0; i<=MAXCOL; i++)
+ pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
+ do
+ {
+ SCsROW nNextRow = pNextRows[nCol] + 1;
+ if ( bMarked )
+ nNextRow = rMark.GetNextMarked( nCol, nNextRow, FALSE );
+ if ( bUnprotected )
+ nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, FALSE );
+ pNextRows[nCol] = nNextRow;
+
+ SCsROW nMinRow = MAXROW+1;
+ for (i=0; i<=MAXCOL; i++)
+ if (pNextRows[i] < nMinRow) // bei gleichen den linken
+ {
+ nMinRow = pNextRows[i];
+ nCol = i;
+ }
+ nRow = nMinRow;
+
+ if ( nRow > MAXROW )
+ {
+ if (++nWrap >= 2) break; // ungueltigen Wert behalten
+ nCol = 0;
+ nRow = 0;
+ for (i=0; i<=MAXCOL; i++)
+ pNextRows[i] = 0; // alles ganz von vorne
+ }
+ }
+ while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
+ }
+ else // rueckwaerts
+ {
+ for (i=0; i<=MAXCOL; i++)
+ pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
+ do
+ {
+ SCsROW nNextRow = pNextRows[nCol] - 1;
+ if ( bMarked )
+ nNextRow = rMark.GetNextMarked( nCol, nNextRow, TRUE );
+ if ( bUnprotected )
+ nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, TRUE );
+ pNextRows[nCol] = nNextRow;
+
+ SCsROW nMaxRow = -1;
+ for (i=0; i<=MAXCOL; i++)
+ if (pNextRows[i] >= nMaxRow) // bei gleichen den rechten
+ {
+ nMaxRow = pNextRows[i];
+ nCol = i;
+ }
+ nRow = nMaxRow;
+
+ if ( nRow < 0 )
+ {
+ if (++nWrap >= 2) break; // ungueltigen Wert behalten
+ nCol = MAXCOL;
+ nRow = MAXROW;
+ for (i=0; i<=MAXCOL; i++)
+ pNextRows[i] = MAXROW; // alles ganz von vorne
+ }
+ }
+ while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
+ }
+
+ delete[] pNextRows;
+ }
+ }
+
+ // ungueltige Werte kommen z.b. bei Tab heraus,
+ // wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
+ // dann Werte unveraendert lassen
+
+ if (VALIDCOLROW(nCol,nRow))
+ {
+ rCol = nCol;
+ rRow = nRow;
+ }
+}
+
+BOOL ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark )
+{
+ const ScMarkArray* pMarkArray = rMark.GetArray();
+ DBG_ASSERT(pMarkArray,"GetNextMarkedCell ohne MarkArray");
+ if ( !pMarkArray )
+ return FALSE;
+
+ ++rRow; // naechste Zelle ist gesucht
+
+ while ( rCol <= MAXCOL )
+ {
+ const ScMarkArray& rArray = pMarkArray[rCol];
+ while ( rRow <= MAXROW )
+ {
+ SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, FALSE );
+ if ( nStart <= MAXROW )
+ {
+ SCROW nEnd = rArray.GetMarkEnd( nStart, FALSE );
+ ScColumnIterator aColIter( &aCol[rCol], nStart, nEnd );
+ SCROW nCellRow;
+ ScBaseCell* pCell = NULL;
+ while ( aColIter.Next( nCellRow, pCell ) )
+ {
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ rRow = nCellRow;
+ return TRUE; // Zelle gefunden
+ }
+ }
+ rRow = nEnd + 1; // naechsten markierten Bereich suchen
+ }
+ else
+ rRow = MAXROW + 1; // Ende der Spalte
+ }
+ rRow = 0;
+ ++rCol; // naechste Spalte testen
+ }
+
+ return FALSE; // alle Spalten durch
+}
+
+void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos )
+{
+ if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table
+ {
+ InitializeNoteCaptions();
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if ( eUpdateRefMode != URM_COPY && pDrawLayer )
+ {
+ if ( eUpdateRefMode == URM_MOVE )
+ { // source range
+ nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
+ nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
+ nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
+ nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
+ }
+ pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
+ (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
+ }
+ }
+}
+
+void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScDocument* pUndoDoc, BOOL bIncludeDraw, bool bUpdateNoteCaptionPos )
+{
+ SCCOL i;
+ SCCOL iMax;
+ if ( eUpdateRefMode == URM_COPY )
+ {
+ i = nCol1;
+ iMax = nCol2;
+ }
+ else
+ {
+ i = 0;
+ iMax = MAXCOL;
+ }
+ for ( ; i<=iMax; i++)
+ aCol[i].UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
+ nDx, nDy, nDz, pUndoDoc );
+
+ if ( bIncludeDraw )
+ UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
+
+ if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
+ {
+ SCTAB nSTab = nTab;
+ SCTAB nETab = nTab;
+ SCCOL nSCol = 0;
+ SCROW nSRow = 0;
+ SCCOL nECol = 0;
+ SCROW nERow = 0;
+ BOOL bRecalcPages = FALSE;
+
+ for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
+ {
+ nSCol = aIt->aStart.Col();
+ nSRow = aIt->aStart.Row();
+ nECol = aIt->aEnd.Col();
+ nERow = aIt->aEnd.Row();
+
+ // do not try to modify sheet index of print range
+ if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
+ nCol1,nRow1,nTab, nCol2,nRow2,nTab,
+ nDx,nDy,0,
+ nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
+ {
+ *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
+ bRecalcPages = TRUE;
+ }
+ }
+
+ if ( pRepeatColRange )
+ {
+ nSCol = pRepeatColRange->aStart.Col();
+ nSRow = pRepeatColRange->aStart.Row();
+ nECol = pRepeatColRange->aEnd.Col();
+ nERow = pRepeatColRange->aEnd.Row();
+
+ // do not try to modify sheet index of repeat range
+ if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
+ nCol1,nRow1,nTab, nCol2,nRow2,nTab,
+ nDx,nDy,0,
+ nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
+ {
+ *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
+ bRecalcPages = TRUE;
+ nRepeatStartX = nSCol; // fuer UpdatePageBreaks
+ nRepeatEndX = nECol;
+ }
+ }
+
+ if ( pRepeatRowRange )
+ {
+ nSCol = pRepeatRowRange->aStart.Col();
+ nSRow = pRepeatRowRange->aStart.Row();
+ nECol = pRepeatRowRange->aEnd.Col();
+ nERow = pRepeatRowRange->aEnd.Row();
+
+ // do not try to modify sheet index of repeat range
+ if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
+ nCol1,nRow1,nTab, nCol2,nRow2,nTab,
+ nDx,nDy,0,
+ nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
+ {
+ *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
+ bRecalcPages = TRUE;
+ nRepeatStartY = nSRow; // fuer UpdatePageBreaks
+ nRepeatEndY = nERow;
+ }
+ }
+
+ // updating print ranges is not necessary with multiple print ranges
+ if ( bRecalcPages && GetPrintRangeCount() <= 1 )
+ {
+ UpdatePageBreaks(NULL);
+
+ SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
+ if (pDocSh)
+ pDocSh->Broadcast( ScPaintHint(
+ ScRange(0,0,nTab,MAXCOL,MAXROW,nTab),
+ PAINT_GRID ) );
+ }
+ }
+}
+
+void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
+ ScDocument* pUndoDoc )
+{
+ for ( SCCOL i=0; i<=MAXCOL; i++ )
+ aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
+}
+
+void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
+{
+ for ( SCCOL i=0; i<=MAXCOL; i++ )
+ aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
+}
+
+void ScTable::UpdateInsertTab(SCTAB nTable)
+{
+ if (nTab >= nTable) nTab++;
+ for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable);
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+//UNUSED2008-05 void ScTable::UpdateInsertTabOnlyCells(SCTAB nTable)
+//UNUSED2008-05 {
+//UNUSED2008-05 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTabOnlyCells(nTable);
+//UNUSED2008-05 }
+
+void ScTable::UpdateDeleteTab( SCTAB nTable, BOOL bIsMove, ScTable* pRefUndo )
+{
+ if (nTab > nTable) nTab--;
+
+ SCCOL i;
+ if (pRefUndo)
+ for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i]);
+ else
+ for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL);
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo,
+ ScProgress& rProgress )
+{
+ nTab = nTabNo;
+ for ( SCCOL i=0; i <= MAXCOL; i++ )
+ {
+ aCol[i].UpdateMoveTab( nOldPos, nNewPos, nTabNo );
+ rProgress.SetState( rProgress.GetState() + aCol[i].GetCodeCount() );
+ }
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::UpdateCompile( BOOL bForceIfNameInUse )
+{
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ {
+ aCol[i].UpdateCompile( bForceIfNameInUse );
+ }
+}
+
+void ScTable::SetTabNo(SCTAB nNewTab)
+{
+ nTab = nNewTab;
+ for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
+}
+
+BOOL ScTable::IsRangeNameInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nIndex) const
+{
+ BOOL bInUse = FALSE;
+ for (SCCOL i = nCol1; !bInUse && (i <= nCol2) && (ValidCol(i)); i++)
+ bInUse = aCol[i].IsRangeNameInUse(nRow1, nRow2, nIndex);
+ return bInUse;
+}
+
+void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ std::set<USHORT>& rIndexes) const
+{
+ for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
+ aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
+}
+
+void ScTable::ReplaceRangeNamesInUse(SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2,
+ const ScRangeData::IndexMap& rMap )
+{
+ for (SCCOL i = nCol1; i <= nCol2 && (ValidCol(i)); i++)
+ {
+ aCol[i].ReplaceRangeNamesInUse( nRow1, nRow2, rMap );
+ }
+}
+
+void ScTable::ExtendPrintArea( OutputDevice* pDev,
+ SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
+{
+ if ( !pColFlags || !pRowFlags )
+ {
+ DBG_ERROR("keine ColInfo oder RowInfo in ExtendPrintArea");
+ return;
+ }
+
+ Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = aPix1000.X() / 1000.0;
+ double nPPTY = aPix1000.Y() / 1000.0;
+
+ // First, mark those columns that we need to skip i.e. hidden and empty columns.
+
+ ScFlatBoolColSegments aSkipCols;
+ aSkipCols.setInsertFromBack(true); // speed optimazation.
+ aSkipCols.setFalse(0, MAXCOL);
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ {
+ SCCOL nLastCol = i;
+ if (ColHidden(i, NULL, &nLastCol))
+ {
+ // Columns are hidden in this range.
+ aSkipCols.setTrue(i, nLastCol);
+ }
+ else
+ {
+ // These columns are visible. Check for empty columns.
+ for (SCCOL j = i; j <= nLastCol; ++j)
+ {
+ if (aCol[j].GetCellCount() == 0)
+ // empty
+ aSkipCols.setTrue(j,j);
+ }
+ }
+ i = nLastCol;
+ }
+
+ ScFlatBoolColSegments::RangeData aColData;
+ for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
+ {
+ if (!aSkipCols.getRangeData(nCol, aColData))
+ // Failed to get the data. This should never happen!
+ return;
+
+ if (aColData.mbValue)
+ {
+ // Skip these columns.
+ nCol = aColData.mnCol1; // move toward 0.
+ continue;
+ }
+
+ // These are visible and non-empty columns.
+ for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
+ {
+ SCCOL nPrintCol = nDataCol;
+ VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
+ ScBaseCell* pCell = aIter.reset(nStartRow);
+ if (!pCell)
+ // No visible cells found in this column. Skip it.
+ continue;
+
+ while (pCell)
+ {
+ SCCOL nNewCol = nDataCol;
+ SCROW nRow = aIter.getRow();
+ if (nRow > nEndRow)
+ // Went past the last row position. Bail out.
+ break;
+
+ MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
+ if (nNewCol > nPrintCol)
+ nPrintCol = nNewCol;
+ pCell = aIter.next();
+ }
+
+ if (nPrintCol > rEndCol)
+ // Make sure we don't shrink the print area.
+ rEndCol = nPrintCol;
+ }
+ nCol = aColData.mnCol1; // move toward 0.
+ }
+}
+
+void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
+{
+ ScBaseCell* pCell = aCol[rCol].GetCell(nRow);
+ if (!pCell || !pCell->HasStringData())
+ return;
+
+ bool bFormula = false; //! ueberge
+ long nPixel = pCell->GetTextWidth();
+
+ // Breite bereits im Idle-Handler berechnet?
+ if ( TEXTWIDTH_DIRTY == nPixel )
+ {
+ ScNeededSizeOptions aOptions;
+ aOptions.bTotalSize = TRUE;
+ aOptions.bFormula = bFormula;
+ aOptions.bSkipMerged = FALSE;
+
+ Fraction aZoom(1,1);
+ nPixel = aCol[rCol].GetNeededSize(
+ nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
+ pCell->SetTextWidth( (USHORT)nPixel );
+ }
+
+ long nTwips = (long) (nPixel / nPPTX);
+ long nDocW = GetColWidth( rCol );
+
+ long nMissing = nTwips - nDocW;
+ if ( nMissing > 0 )
+ {
+ // look at alignment
+
+ const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
+ const SfxItemSet* pCondSet = NULL;
+ if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
+ pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
+ if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
+ nMissing /= 2; // distributed into both directions
+ else
+ {
+ // STANDARD is LEFT (only text is handled here)
+ bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
+ if ( IsLayoutRTL() )
+ bRight = !bRight;
+ if ( bRight )
+ nMissing = 0; // extended only to the left (logical)
+ }
+ }
+
+ SCCOL nNewCol = rCol;
+ while (nMissing > 0 && nNewCol < MAXCOL)
+ {
+ ScBaseCell* pNextCell = aCol[nNewCol+1].GetCell(nRow);
+ if (pNextCell && pNextCell->GetCellType() != CELLTYPE_NOTE)
+ // Cell content in a next column ends display of this string.
+ nMissing = 0;
+ else
+ nMissing -= GetColWidth(++nNewCol);
+ }
+ rCol = nNewCol;
+}
+
+void ScTable::DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd )
+{
+ for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
+ aCol[nCol].Resize(aCol[nCol].GetCellCount() + nAdd);
+}
+
+#define SET_PRINTRANGE( p1, p2 ) \
+ if ( (p2) ) \
+ { \
+ if ( (p1) ) \
+ *(p1) = *(p2); \
+ else \
+ (p1) = new ScRange( *(p2) ); \
+ } \
+ else \
+ DELETEZ( (p1) )
+
+void ScTable::SetRepeatColRange( const ScRange* pNew )
+{
+ SET_PRINTRANGE( pRepeatColRange, pNew );
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::SetRepeatRowRange( const ScRange* pNew )
+{
+ SET_PRINTRANGE( pRepeatRowRange, pNew );
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::ClearPrintRanges()
+{
+ aPrintRanges.clear();
+ bPrintEntireSheet = FALSE;
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::AddPrintRange( const ScRange& rNew )
+{
+ bPrintEntireSheet = FALSE;
+ if( aPrintRanges.size() < 0xFFFF )
+ aPrintRanges.push_back( rNew );
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+//UNUSED2009-05 void ScTable::SetPrintRange( const ScRange& rNew )
+//UNUSED2009-05 {
+//UNUSED2009-05 ClearPrintRanges();
+//UNUSED2009-05 AddPrintRange( rNew );
+//UNUSED2009-05 }
+
+void ScTable::SetPrintEntireSheet()
+{
+ if( !IsPrintEntireSheet() )
+ {
+ ClearPrintRanges();
+ bPrintEntireSheet = TRUE;
+ }
+}
+
+const ScRange* ScTable::GetPrintRange(USHORT nPos) const
+{
+ return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
+}
+
+void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
+{
+ rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
+ rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
+}
+
+void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
+{
+ aPrintRanges = rSaveTab.GetPrintRanges();
+ bPrintEntireSheet = rSaveTab.IsEntireSheet();
+ SetRepeatColRange( rSaveTab.GetRepeatCol() );
+ SetRepeatRowRange( rSaveTab.GetRepeatRow() );
+
+ UpdatePageBreaks(NULL);
+}
+
+SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
+
+ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
+ mrRowSegs(rRowSegs),
+ mrColumn(rColumn),
+ mpCell(NULL),
+ mnCurRow(ROW_NOT_FOUND),
+ mnUBound(ROW_NOT_FOUND)
+{
+}
+
+ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
+{
+}
+
+ScBaseCell* ScTable::VisibleDataCellIterator::reset(SCROW nRow)
+{
+ if (nRow > MAXROW)
+ {
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mrRowSegs.getRangeData(nRow, aData))
+ {
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+
+ if (!aData.mbValue)
+ {
+ // specified row is visible. Take it.
+ mnCurRow = nRow;
+ mnUBound = aData.mnRow2;
+ }
+ else
+ {
+ // specified row is not-visible. The first visible row is the start of
+ // the next segment.
+ mnCurRow = aData.mnRow2 + 1;
+ mnUBound = mnCurRow; // get range data on the next iteration.
+ if (mnCurRow > MAXROW)
+ {
+ // Make sure the row doesn't exceed our current limit.
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+ }
+
+ mpCell = mrColumn.GetCell(mnCurRow);
+ if (mpCell)
+ // First visible cell found.
+ return mpCell;
+
+ // Find a first visible cell below this row (if any).
+ return next();
+}
+
+ScBaseCell* ScTable::VisibleDataCellIterator::next()
+{
+ if (mnCurRow == ROW_NOT_FOUND)
+ return NULL;
+
+ while (mrColumn.GetNextDataPos(mnCurRow))
+ {
+ if (mnCurRow > mnUBound)
+ {
+ // We don't know the visibility of this row range. Query it.
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mrRowSegs.getRangeData(mnCurRow, aData))
+ {
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+
+ if (aData.mbValue)
+ {
+ // This row is invisible. Skip to the last invisible row and
+ // try again.
+ mnCurRow = mnUBound = aData.mnRow2;
+ continue;
+ }
+
+ // This row is visible.
+ mnUBound = aData.mnRow2;
+ }
+
+ mpCell = mrColumn.GetCell(mnCurRow);
+ if (mpCell)
+ return mpCell;
+ }
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+}
+
+SCROW ScTable::VisibleDataCellIterator::getRow() const
+{
+ return mnCurRow;
+}
+
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
new file mode 100644
index 000000000000..9eaaf6c070e7
--- /dev/null
+++ b/sc/source/core/data/table2.cxx
@@ -0,0 +1,3246 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/poolcach.hxx>
+#include <unotools/charclass.hxx>
+#include <math.h>
+#include <svl/PasswordHelper.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "olinetab.hxx"
+#include "rechead.hxx"
+#include "stlpool.hxx"
+#include "attarray.hxx" // Iterator
+#include "markdata.hxx"
+#include "progress.hxx"
+#include "dociter.hxx"
+#include "conditio.hxx"
+#include "chartlis.hxx"
+#include "fillinfo.hxx"
+#include "bcaslot.hxx"
+#include "postit.hxx"
+#include "sheetevents.hxx"
+#include "globstr.hrc"
+#include "segmenttree.hxx"
+
+#include <math.h>
+
+// STATIC DATA -----------------------------------------------------------
+
+
+BOOL ScTable::SetOutlineTable( const ScOutlineTable* pNewOutline )
+{
+ USHORT nOldSizeX = 0;
+ USHORT nOldSizeY = 0;
+ USHORT nNewSizeX = 0;
+ USHORT nNewSizeY = 0;
+
+ if (pOutlineTable)
+ {
+ nOldSizeX = pOutlineTable->GetColArray()->GetDepth();
+ nOldSizeY = pOutlineTable->GetRowArray()->GetDepth();
+ delete pOutlineTable;
+ }
+
+ if (pNewOutline)
+ {
+ pOutlineTable = new ScOutlineTable( *pNewOutline );
+ nNewSizeX = pOutlineTable->GetColArray()->GetDepth();
+ nNewSizeY = pOutlineTable->GetRowArray()->GetDepth();
+ }
+ else
+ pOutlineTable = NULL;
+
+ return ( nNewSizeX != nOldSizeX || nNewSizeY != nOldSizeY ); // Groesse geaendert ?
+}
+
+
+void ScTable::StartOutlineTable()
+{
+ if (!pOutlineTable)
+ pOutlineTable = new ScOutlineTable;
+}
+
+
+void ScTable::SetSheetEvents( const ScSheetEvents* pNew )
+{
+ delete pSheetEvents;
+ if (pNew)
+ pSheetEvents = new ScSheetEvents(*pNew);
+ else
+ pSheetEvents = NULL;
+
+ SetCalcNotification( FALSE ); // discard notifications before the events were set
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+
+void ScTable::SetCalcNotification( BOOL bSet )
+{
+ bCalcNotification = bSet;
+}
+
+
+BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize )
+{
+ BOOL bTest = TRUE;
+
+ if ( nStartCol==0 && nEndCol==MAXCOL && pOutlineTable )
+ bTest = pOutlineTable->TestInsertRow(nSize);
+
+ for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
+ bTest = aCol[i].TestInsertRow( nSize );
+
+ return bTest;
+}
+
+
+void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
+{
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ if (nStartCol==0 && nEndCol==MAXCOL)
+ {
+ if (mpRowHeights && pRowFlags)
+ {
+ mpRowHeights->insertSegment(nStartRow, nSize, false);
+ BYTE nNewFlags = pRowFlags->Insert( nStartRow, nSize);
+ // only copy manual size flag, clear all others
+ if (nNewFlags && (nNewFlags != CR_MANUALSIZE))
+ pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
+ nNewFlags & CR_MANUALSIZE);
+ }
+
+ if (pOutlineTable)
+ pOutlineTable->InsertRow( nStartRow, nSize );
+
+ mpFilteredRows->insertSegment(nStartRow, nSize, true);
+ mpHiddenRows->insertSegment(nStartRow, nSize, true);
+
+ if (!maRowManualBreaks.empty())
+ {
+ std::set<SCROW>::reverse_iterator rit = maRowManualBreaks.rbegin();
+ while (rit != maRowManualBreaks.rend())
+ {
+ SCROW nRow = *rit;
+ if (nRow < nStartRow)
+ break; // while
+ else
+ {
+ maRowManualBreaks.erase( (++rit).base());
+ maRowManualBreaks.insert( static_cast<SCROW>( nRow + nSize));
+ }
+ }
+ }
+ }
+
+ for (SCCOL j=nStartCol; j<=nEndCol; j++)
+ aCol[j].InsertRow( nStartRow, nSize );
+ DecRecalcLevel( false );
+
+ InvalidatePageBreaks();
+}
+
+
+void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
+ BOOL* pUndoOutline )
+{
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ if (nStartCol==0 && nEndCol==MAXCOL)
+ {
+ if (pRowFlags)
+ pRowFlags->Remove( nStartRow, nSize);
+
+ if (mpRowHeights)
+ mpRowHeights->removeSegment(nStartRow, nStartRow+nSize);
+
+ if (pOutlineTable)
+ if (pOutlineTable->DeleteRow( nStartRow, nSize ))
+ if (pUndoOutline)
+ *pUndoOutline = TRUE;
+
+ mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
+ mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
+
+ if (!maRowManualBreaks.empty())
+ {
+ std::set<SCROW>::iterator it = maRowManualBreaks.upper_bound( static_cast<SCROW>( nStartRow + nSize - 1));
+ maRowManualBreaks.erase( maRowManualBreaks.lower_bound( nStartRow), it);
+ while (it != maRowManualBreaks.end())
+ {
+ SCROW nRow = *it;
+ maRowManualBreaks.erase( it++);
+ maRowManualBreaks.insert( static_cast<SCROW>( nRow - nSize));
+ }
+ }
+ }
+
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
+ for (SCCOL j=nStartCol; j<=nEndCol; j++)
+ aCol[j].DeleteRow( nStartRow, nSize );
+ }
+ DecRecalcLevel();
+
+ InvalidatePageBreaks();
+}
+
+
+BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
+{
+ BOOL bTest = TRUE;
+
+ if ( nStartRow==0 && nEndRow==MAXROW && pOutlineTable )
+ bTest = pOutlineTable->TestInsertCol(nSize);
+
+ if ( nSize > static_cast<SCSIZE>(MAXCOL) )
+ bTest = FALSE;
+
+ for (SCCOL i=MAXCOL; (i+static_cast<SCCOL>(nSize)>MAXCOL) && bTest; i--)
+ bTest = aCol[i].TestInsertCol(nStartRow, nEndRow);
+
+ return bTest;
+}
+
+
+void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
+{
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ if (nStartRow==0 && nEndRow==MAXROW)
+ {
+ if (pColWidth && pColFlags)
+ {
+ memmove( &pColWidth[nStartCol+nSize], &pColWidth[nStartCol],
+ (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
+ memmove( &pColFlags[nStartCol+nSize], &pColFlags[nStartCol],
+ (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
+ }
+ if (pOutlineTable)
+ pOutlineTable->InsertCol( nStartCol, nSize );
+
+ mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
+ mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
+
+ if (!maColManualBreaks.empty())
+ {
+ std::set<SCCOL>::reverse_iterator rit = maColManualBreaks.rbegin();
+ while (rit != maColManualBreaks.rend())
+ {
+ SCCOL nCol = *rit;
+ if (nCol < nStartCol)
+ break; // while
+ else
+ {
+ maColManualBreaks.erase( (++rit).base());
+ maColManualBreaks.insert( static_cast<SCCOL>( nCol + nSize));
+ }
+ }
+ }
+ }
+
+
+ if ((nStartRow == 0) && (nEndRow == MAXROW))
+ {
+ for (SCSIZE i=0; i < nSize; i++)
+ for (SCCOL nCol = MAXCOL; nCol > nStartCol; nCol--)
+ aCol[nCol].SwapCol(aCol[nCol-1]);
+ }
+ else
+ {
+ for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
+ aCol[MAXCOL - nSize - i].MoveTo(nStartRow, nEndRow, aCol[MAXCOL - i]);
+ }
+
+ if (nStartCol>0) // copy old attributes
+ {
+ USHORT nWhichArray[2];
+ nWhichArray[0] = ATTR_MERGE;
+ nWhichArray[1] = 0;
+
+ for (SCSIZE i=0; i<nSize; i++)
+ {
+ aCol[nStartCol-1].CopyToColumn( nStartRow, nEndRow, IDF_ATTRIB,
+ FALSE, aCol[nStartCol+i] );
+ aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
+ SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
+ aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
+ }
+ }
+ DecRecalcLevel();
+
+ InvalidatePageBreaks();
+}
+
+
+void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize,
+ BOOL* pUndoOutline )
+{
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ if (nStartRow==0 && nEndRow==MAXROW)
+ {
+ if (pColWidth && pColFlags)
+ {
+ memmove( &pColWidth[nStartCol], &pColWidth[nStartCol+nSize],
+ (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
+ memmove( &pColFlags[nStartCol], &pColFlags[nStartCol+nSize],
+ (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
+ }
+ if (pOutlineTable)
+ if (pOutlineTable->DeleteCol( nStartCol, nSize ))
+ if (pUndoOutline)
+ *pUndoOutline = TRUE;
+
+ SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize);
+ mpHiddenCols->removeSegment(nStartCol, nRmSize);
+ mpFilteredCols->removeSegment(nStartCol, nRmSize);
+
+ if (!maColManualBreaks.empty())
+ {
+ std::set<SCCOL>::iterator it = maColManualBreaks.upper_bound( static_cast<SCCOL>( nStartCol + nSize - 1));
+ maColManualBreaks.erase( maColManualBreaks.lower_bound( nStartCol), it);
+ while (it != maColManualBreaks.end())
+ {
+ SCCOL nCol = *it;
+ maColManualBreaks.erase( it++);
+ maColManualBreaks.insert( static_cast<SCCOL>( nCol - nSize));
+ }
+ }
+ }
+
+
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
+ for (SCSIZE i = 0; i < nSize; i++)
+ aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, IDF_ALL);
+ }
+
+ if ((nStartRow == 0) && (nEndRow == MAXROW))
+ {
+ for (SCSIZE i=0; i < nSize; i++)
+ for (SCCOL nCol = nStartCol; nCol < MAXCOL; nCol++)
+ aCol[nCol].SwapCol(aCol[nCol+1]);
+ }
+ else
+ {
+ for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
+ aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
+ }
+ DecRecalcLevel();
+
+ InvalidatePageBreaks();
+}
+
+
+void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nDelFlag)
+{
+ if (nCol2 > MAXCOL) nCol2 = MAXCOL;
+ if (nRow2 > MAXROW) nRow2 = MAXROW;
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ {
+// IncRecalcLevel();
+
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
+ for (SCCOL i = nCol1; i <= nCol2; i++)
+ aCol[i].DeleteArea(nRow1, nRow2, nDelFlag);
+ }
+
+ //
+ // Zellschutz auf geschuetzter Tabelle nicht setzen
+ //
+
+ if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
+ {
+ ScPatternAttr aPattern(pDocument->GetPool());
+ aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
+ ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
+ }
+
+// DecRecalcLevel();
+ }
+}
+
+
+void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
+{
+ { // scope for bulk broadcast
+ ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].DeleteSelection( nDelFlag, rMark );
+ }
+
+ //
+ // Zellschutz auf geschuetzter Tabelle nicht setzen
+ //
+
+ if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
+ {
+ ScDocumentPool* pPool = pDocument->GetPool();
+ SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
+ aSet.Put( ScProtectionAttr( FALSE ) );
+ SfxItemPoolCache aCache( pPool, &aSet );
+ ApplySelectionCache( &aCache, rMark );
+ }
+}
+
+
+// pTable = Clipboard
+void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ ScTable* pTable, BOOL bKeepScenarioFlags, BOOL bCloneNoteCaptions)
+{
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ {
+ // Inhalte kopieren
+ SCCOL i;
+
+ for ( i = nCol1; i <= nCol2; i++)
+ aCol[i].CopyToClip(nRow1, nRow2, pTable->aCol[i], bKeepScenarioFlags, bCloneNoteCaptions);
+
+ // copy widths/heights, and only "hidden", "filtered" and "manual" flags
+ // also for all preceding columns/rows, to have valid positions for drawing objects
+
+ if (pColWidth && pTable->pColWidth)
+ for (i=0; i<=nCol2; i++)
+ pTable->pColWidth[i] = pColWidth[i];
+
+ pTable->CopyColHidden(*this, 0, nCol2);
+ pTable->CopyColFiltered(*this, 0, nCol2);
+
+ if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights)
+ {
+ pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
+ pTable->CopyRowHeight(*this, 0, nRow2, 0);
+ }
+
+ pTable->CopyRowHidden(*this, 0, nRow2);
+ pTable->CopyRowFiltered(*this, 0, nRow2);
+
+ // ggf. Formeln durch Werte ersetzen
+
+ if ( IsProtected() )
+ for (i = nCol1; i <= nCol2; i++)
+ pTable->aCol[i].RemoveProtected(nRow1, nRow2);
+ }
+}
+
+void ScTable::CopyToClip(const ScRangeList& rRanges, ScTable* pTable,
+ bool bKeepScenarioFlags, bool bCloneNoteCaptions)
+{
+ ScRangeList aRanges(rRanges);
+ for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
+ {
+ CopyToClip(p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(),
+ pTable, bKeepScenarioFlags, bCloneNoteCaptions);
+ }
+}
+
+void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ SCsCOL nDx, SCsROW nDy, USHORT nInsFlag,
+ BOOL bAsLink, BOOL bSkipAttrForEmpty, ScTable* pTable)
+{
+ SCCOL i;
+
+ if (nCol2 > MAXCOL) nCol2 = MAXCOL;
+ if (nRow2 > MAXROW) nRow2 = MAXROW;
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ {
+ IncRecalcLevel();
+ for ( i = nCol1; i <= nCol2; i++)
+ aCol[i].CopyFromClip(nRow1, nRow2, nDy, nInsFlag, bAsLink, bSkipAttrForEmpty, pTable->aCol[i - nDx]);
+
+ if ((nInsFlag & IDF_ATTRIB) != 0)
+ {
+ if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth)
+ for (i=nCol1; i<=nCol2; i++)
+ pColWidth[i] = pTable->pColWidth[i-nDx];
+
+ if (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pTable->mpRowHeights &&
+ pRowFlags && pTable->pRowFlags)
+ {
+ CopyRowHeight(*pTable, nRow1, nRow2, -nDy);
+ // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
+ for (SCROW j=nRow1; j<=nRow2; j++)
+ {
+ if ( pTable->pRowFlags->GetValue(j-nDy) & CR_MANUALSIZE )
+ pRowFlags->OrValue( j, CR_MANUALSIZE);
+ else
+ pRowFlags->AndValue( j, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
+ }
+ }
+
+ //
+ // Zellschutz auf geschuetzter Tabelle nicht setzen
+ //
+
+ if ( IsProtected() && (nInsFlag & IDF_ATTRIB) )
+ {
+ ScPatternAttr aPattern(pDocument->GetPool());
+ aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
+ ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
+ }
+ }
+ DecRecalcLevel();
+ }
+}
+
+
+void ScTable::MixData( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nFunction, BOOL bSkipEmpty, ScTable* pSrcTab )
+{
+ for (SCCOL i=nCol1; i<=nCol2; i++)
+ aCol[i].MixData( nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
+}
+
+
+// Markierung von diesem Dokument
+void ScTable::MixMarked( const ScMarkData& rMark, USHORT nFunction,
+ BOOL bSkipEmpty, ScTable* pSrcTab )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].MixMarked( rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i] );
+}
+
+
+void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ ScTable* pTransClip, USHORT nFlags, BOOL bAsLink )
+{
+ BOOL bWasCut = pDocument->IsCutMode();
+
+ ScDocument* pDestDoc = pTransClip->pDocument;
+
+ for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
+ {
+ SCROW nRow;
+ ScBaseCell* pCell;
+
+ if ( bAsLink && nFlags == IDF_ALL )
+ {
+ // #68989# with IDF_ALL, also create links (formulas) for empty cells
+
+ for ( nRow=nRow1; nRow<=nRow2; nRow++ )
+ {
+ // create simple formula, as in ScColumn::CreateRefCell
+
+ ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+ ScSingleRefData aRef;
+ aRef.nCol = nCol;
+ aRef.nRow = nRow;
+ aRef.nTab = nTab;
+ aRef.InitFlags(); // -> all absolute
+ aRef.SetFlag3D(TRUE);
+ aRef.CalcRelFromAbs( aDestPos );
+ ScTokenArray aArr;
+ aArr.AddSingleReference( aRef );
+
+ ScBaseCell* pNew = new ScFormulaCell( pDestDoc, aDestPos, &aArr );
+ pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
+ }
+ }
+ else
+ {
+ ScColumnIterator aIter( &aCol[nCol], nRow1, nRow2 );
+ while (aIter.Next( nRow, pCell ))
+ {
+ ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+ ScBaseCell* pNew;
+ if ( bAsLink ) // Referenz erzeugen ?
+ {
+ pNew = aCol[nCol].CreateRefCell( pDestDoc, aDestPos, aIter.GetIndex(), nFlags );
+ }
+ else // kopieren
+ {
+ ScAddress aOwnPos( nCol, nRow, nTab );
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
+
+ // Referenzen drehen
+ // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
+
+ if (!bWasCut)
+ ((ScFormulaCell*)pNew)->TransposeReference();
+ }
+ else
+ {
+ pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos );
+ }
+ }
+ pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
+ }
+ }
+
+ // Attribute
+
+ SCROW nAttrRow1;
+ SCROW nAttrRow2;
+ const ScPatternAttr* pPattern;
+ ScAttrIterator* pAttrIter = aCol[nCol].CreateAttrIterator( nRow1, nRow2 );
+ while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != 0 )
+ {
+ if ( !IsDefaultItem( pPattern ) )
+ {
+ const SfxItemSet& rSet = pPattern->GetItemSet();
+ if ( rSet.GetItemState( ATTR_MERGE, FALSE ) == SFX_ITEM_DEFAULT &&
+ rSet.GetItemState( ATTR_MERGE_FLAG, FALSE ) == SFX_ITEM_DEFAULT &&
+ rSet.GetItemState( ATTR_BORDER, FALSE ) == SFX_ITEM_DEFAULT )
+ {
+ // no borders or merge items involved - use pattern as-is
+ for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
+ pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern, TRUE );
+ }
+ else
+ {
+ // transpose borders and merge values, remove merge flags (refreshed after pasting)
+ ScPatternAttr aNewPattern( *pPattern );
+ SfxItemSet& rNewSet = aNewPattern.GetItemSet();
+
+ const SvxBoxItem& rOldBox = (const SvxBoxItem&)rSet.Get(ATTR_BORDER);
+ if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
+ {
+ SvxBoxItem aNew( ATTR_BORDER );
+ aNew.SetLine( rOldBox.GetLine( BOX_LINE_TOP ), BOX_LINE_LEFT );
+ aNew.SetLine( rOldBox.GetLine( BOX_LINE_LEFT ), BOX_LINE_TOP );
+ aNew.SetLine( rOldBox.GetLine( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
+ aNew.SetLine( rOldBox.GetLine( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
+ aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_TOP ), BOX_LINE_LEFT );
+ aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_LEFT ), BOX_LINE_TOP );
+ aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_BOTTOM ), BOX_LINE_RIGHT );
+ aNew.SetDistance( rOldBox.GetDistance( BOX_LINE_RIGHT ), BOX_LINE_BOTTOM );
+ rNewSet.Put( aNew );
+ }
+
+ const ScMergeAttr& rOldMerge = (const ScMergeAttr&)rSet.Get(ATTR_MERGE);
+ if (rOldMerge.IsMerged())
+ rNewSet.Put( ScMergeAttr( Min(
+ static_cast<SCsCOL>(rOldMerge.GetRowMerge()),
+ static_cast<SCsCOL>(MAXCOL+1 - (nAttrRow2-nRow1))),
+ Min(
+ static_cast<SCsROW>(rOldMerge.GetColMerge()),
+ static_cast<SCsROW>(MAXROW+1 - (nCol-nCol1)))));
+ const ScMergeFlagAttr& rOldFlag = (const ScMergeFlagAttr&)rSet.Get(ATTR_MERGE_FLAG);
+ if (rOldFlag.IsOverlapped())
+ {
+ INT16 nNewFlags = rOldFlag.GetValue() & ~( SC_MF_HOR | SC_MF_VER );
+ if ( nNewFlags )
+ rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
+ else
+ rNewSet.ClearItem( ATTR_MERGE_FLAG );
+ }
+
+ for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
+ pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
+ static_cast<SCROW>(nCol-nCol1), aNewPattern, TRUE);
+ }
+ }
+ }
+
+ delete pAttrIter;
+ }
+}
+
+
+void ScTable::StartAllListeners()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].StartAllListeners();
+}
+
+
+void ScTable::StartNeededListeners()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].StartNeededListeners();
+}
+
+
+void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2 )
+{
+ if (nCol2 > MAXCOL) nCol2 = MAXCOL;
+ if (nRow2 > MAXROW) nRow2 = MAXROW;
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ for (SCCOL i = nCol1; i <= nCol2; i++)
+ aCol[i].BroadcastInArea( nRow1, nRow2 );
+}
+
+
+void ScTable::StartListeningInArea( SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2 )
+{
+ if (nCol2 > MAXCOL) nCol2 = MAXCOL;
+ if (nRow2 > MAXROW) nRow2 = MAXROW;
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ for (SCCOL i = nCol1; i <= nCol2; i++)
+ aCol[i].StartListeningInArea( nRow1, nRow2 );
+}
+
+
+void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
+ const ScMarkData* pMarkData,
+ BOOL bAsLink, BOOL bColRowFlags)
+{
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ {
+ if (nFlags)
+ for (SCCOL i = nCol1; i <= nCol2; i++)
+ aCol[i].CopyToColumn(nRow1, nRow2, nFlags, bMarked,
+ pDestTab->aCol[i], pMarkData, bAsLink);
+
+ if (bColRowFlags) // Spaltenbreiten/Zeilenhoehen/Flags
+ {
+ // Charts muessen beim Ein-/Ausblenden angepasst werden
+ ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
+
+ bool bFlagChange = false;
+
+ BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
+ BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
+
+ if (bWidth||bHeight)
+ {
+ pDestTab->IncRecalcLevel();
+
+ if (bWidth)
+ {
+ for (SCCOL i=nCol1; i<=nCol2; i++)
+ {
+ bool bThisHidden = ColHidden(i);
+ bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
+ bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
+ pDestTab->pColWidth[i] = pColWidth[i];
+ pDestTab->pColFlags[i] = pColFlags[i];
+ pDestTab->SetColHidden(i, i, bThisHidden);
+ //! Aenderungen zusammenfassen?
+ if (bHiddenChange && pCharts)
+ pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
+
+ if (bChange)
+ bFlagChange = true;
+ }
+ pDestTab->SetColManualBreaks( maColManualBreaks);
+ }
+
+ if (bHeight)
+ {
+ bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2);
+
+ if (bChange)
+ bFlagChange = true;
+
+ pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
+ pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
+
+ // Hidden flags.
+ // #i116164# Collect information first, then apply the changes,
+ // so RowHidden doesn't rebuild the tree for each row range.
+ std::vector<ScShowRowsEntry> aEntries;
+ for (SCROW i = nRow1; i <= nRow2; ++i)
+ {
+ SCROW nThisLastRow, nDestLastRow;
+ bool bThisHidden = RowHidden(i, NULL, &nThisLastRow);
+ bool bDestHidden = pDestTab->RowHidden(i, NULL, &nDestLastRow);
+
+ // If the segment sizes differ, we take the shorter segment of the two.
+ SCROW nLastRow = ::std::min(nThisLastRow, nDestLastRow);
+ if (nLastRow >= nRow2)
+ // the last row shouldn't exceed the upper bound the caller specified.
+ nLastRow = nRow2;
+
+ //pDestTab->SetRowHidden(i, nLastRow, bThisHidden);
+ aEntries.push_back(ScShowRowsEntry(i, nLastRow, !bThisHidden));
+
+ bool bThisHiddenChange = (bThisHidden != bDestHidden);
+ if (bThisHiddenChange && pCharts)
+ {
+ // Hidden flags differ.
+ pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab));
+ }
+
+ if (bThisHiddenChange)
+ bFlagChange = true;
+
+ // Jump to the last row of the identical flag segment.
+ i = nLastRow;
+ }
+
+ std::vector<ScShowRowsEntry>::const_iterator aEnd = aEntries.end();
+ std::vector<ScShowRowsEntry>::const_iterator aIter = aEntries.begin();
+ if ( aIter != aEnd )
+ {
+ pDestTab->mpHiddenRows->setInsertFromBack(true); // important for undo document
+ while (aIter != aEnd)
+ {
+ pDestTab->SetRowHidden(aIter->mnRow1, aIter->mnRow2, !aIter->mbShow);
+ ++aIter;
+ }
+ pDestTab->mpHiddenRows->setInsertFromBack(false);
+ }
+
+ // Filtered flags.
+ for (SCROW i = nRow1; i <= nRow2; ++i)
+ {
+ SCROW nLastRow;
+ bool bFiltered = RowFiltered(i, NULL, &nLastRow);
+ if (nLastRow >= nRow2)
+ // the last row shouldn't exceed the upper bound the caller specified.
+ nLastRow = nRow2;
+ pDestTab->SetRowFiltered(i, nLastRow, bFiltered);
+ i = nLastRow;
+ }
+ pDestTab->SetRowManualBreaks( maRowManualBreaks);
+ }
+ pDestTab->DecRecalcLevel();
+ }
+
+ if (bFlagChange)
+ pDestTab->InvalidatePageBreaks();
+
+ pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags
+ }
+ }
+}
+
+
+void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nFlags, BOOL bMarked, ScTable* pDestTab,
+ const ScMarkData* pMarkData)
+{
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ {
+ BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
+ BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
+
+ if (bWidth||bHeight)
+ IncRecalcLevel();
+
+ for ( SCCOL i = 0; i <= MAXCOL; i++)
+ {
+ if ( i >= nCol1 && i <= nCol2 )
+ aCol[i].UndoToColumn(nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i],
+ pMarkData);
+ else
+ aCol[i].CopyToColumn(0, MAXROW, IDF_FORMULA, FALSE, pDestTab->aCol[i]);
+ }
+
+ if (bWidth||bHeight)
+ {
+ if (bWidth)
+ {
+ for (SCCOL i=nCol1; i<=nCol2; i++)
+ pDestTab->pColWidth[i] = pColWidth[i];
+ pDestTab->SetColManualBreaks( maColManualBreaks);
+ }
+ if (bHeight)
+ {
+ pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
+ pDestTab->SetRowManualBreaks( maRowManualBreaks);
+ }
+ DecRecalcLevel();
+ }
+ }
+}
+
+
+void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
+}
+
+void ScTable::InvalidateTableArea()
+{
+ bTableAreaValid = FALSE;
+}
+
+void ScTable::InvalidatePageBreaks()
+{
+ mbPageBreaksValid = false;
+}
+
+void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
+{
+ DBG_ASSERT( bScenario, "bScenario == FALSE" );
+
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
+}
+
+void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
+{
+ DBG_ASSERT( bScenario, "bScenario == FALSE" );
+
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
+}
+
+void ScTable::MarkScenarioIn( ScMarkData& rDestMark, USHORT nNeededBits ) const
+{
+ DBG_ASSERT( bScenario, "bScenario == FALSE" );
+
+ if ( ( nScenarioFlags & nNeededBits ) != nNeededBits ) // alle Bits gesetzt?
+ return;
+
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].MarkScenarioIn( rDestMark );
+}
+
+BOOL ScTable::HasScenarioRange( const ScRange& rRange ) const
+{
+ DBG_ASSERT( bScenario, "bScenario == FALSE" );
+
+// ScMarkData aMark;
+// MarkScenarioIn( aMark, 0 ); //! Bits als Parameter von HasScenarioRange?
+// return aMark.IsAllMarked( rRange );
+
+ ScRange aTabRange = rRange;
+ aTabRange.aStart.SetTab( nTab );
+ aTabRange.aEnd.SetTab( nTab );
+
+ const ScRangeList* pList = GetScenarioRanges();
+// return ( pList && pList->Find( aTabRange ) );
+
+ if (pList)
+ {
+ ULONG nCount = pList->Count();
+ for ( ULONG j = 0; j < nCount; j++ )
+ {
+ ScRange* pR = pList->GetObject( j );
+ if ( pR->Intersects( aTabRange ) )
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void ScTable::InvalidateScenarioRanges()
+{
+ delete pScenarioRanges;
+ pScenarioRanges = NULL;
+}
+
+const ScRangeList* ScTable::GetScenarioRanges() const
+{
+ DBG_ASSERT( bScenario, "bScenario == FALSE" );
+
+ if (!pScenarioRanges)
+ {
+ ((ScTable*)this)->pScenarioRanges = new ScRangeList;
+ ScMarkData aMark;
+ MarkScenarioIn( aMark, 0 ); // immer
+ aMark.FillRangeListWithMarks( pScenarioRanges, FALSE );
+ }
+ return pScenarioRanges;
+}
+
+BOOL ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
+{
+ DBG_ASSERT( bScenario, "bScenario == FALSE" );
+
+ if (!pDestTab->IsProtected())
+ return TRUE;
+
+ BOOL bOk = TRUE;
+ for (SCCOL i=0; i<=MAXCOL && bOk; i++)
+ bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
+ return bOk;
+}
+
+void ScTable::PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell )
+{
+ if (ValidColRow(nCol,nRow))
+ {
+ if (pCell)
+ aCol[nCol].Insert( nRow, pCell );
+ else
+ aCol[nCol].Delete( nRow );
+ }
+}
+
+
+void ScTable::PutCell( SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell )
+{
+ if (ValidColRow(nCol,nRow))
+ {
+ if (pCell)
+ aCol[nCol].Insert( nRow, nFormatIndex, pCell );
+ else
+ aCol[nCol].Delete( nRow );
+ }
+}
+
+
+void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell )
+{
+ if (pCell)
+ aCol[rPos.Col()].Insert( rPos.Row(), pCell );
+ else
+ aCol[rPos.Col()].Delete( rPos.Row() );
+}
+
+
+//UNUSED2009-05 void ScTable::PutCell( const ScAddress& rPos, ULONG nFormatIndex, ScBaseCell* pCell )
+//UNUSED2009-05 {
+//UNUSED2009-05 if (pCell)
+//UNUSED2009-05 aCol[rPos.Col()].Insert( rPos.Row(), nFormatIndex, pCell );
+//UNUSED2009-05 else
+//UNUSED2009-05 aCol[rPos.Col()].Delete( rPos.Row() );
+//UNUSED2009-05 }
+
+
+BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString,
+ SvNumberFormatter* pFormatter, bool bDetectNumberFormat )
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].SetString(
+ nRow, nTabP, rString, pDocument->GetAddressConvention(), pFormatter, bDetectNumberFormat );
+ else
+ return FALSE;
+}
+
+
+void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
+{
+ if (ValidColRow(nCol, nRow))
+ aCol[nCol].SetValue( nRow, rVal );
+}
+
+
+void ScTable::GetString( SCCOL nCol, SCROW nRow, String& rString )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].GetString( nRow, rString );
+ else
+ rString.Erase();
+}
+
+
+void ScTable::GetInputString( SCCOL nCol, SCROW nRow, String& rString )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].GetInputString( nRow, rString );
+ else
+ rString.Erase();
+}
+
+
+double ScTable::GetValue( SCCOL nCol, SCROW nRow )
+{
+ if (ValidColRow( nCol, nRow ))
+ return aCol[nCol].GetValue( nRow );
+ return 0.0;
+}
+
+
+void ScTable::GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
+ BOOL bAsciiExport )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].GetFormula( nRow, rFormula, bAsciiExport );
+ else
+ rFormula.Erase();
+}
+
+
+ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
+{
+ return ValidColRow( nCol, nRow ) ? aCol[ nCol ].GetNote( nRow ) : 0;
+}
+
+
+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 );
+}
+
+
+ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
+{
+ return ValidColRow( nCol, nRow ) ? aCol[ nCol ].ReleaseNote( nRow ) : 0;
+}
+
+
+void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
+{
+ if( ValidColRow( nCol, nRow ) )
+ aCol[ nCol ].DeleteNote( 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 ))
+ return aCol[nCol].GetCellType( nRow );
+ return CELLTYPE_NONE;
+}
+
+
+ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
+{
+ if (ValidColRow( nCol, nRow ))
+ return aCol[nCol].GetCell( nRow );
+
+ DBG_ERROR("GetCell ausserhalb");
+ return NULL;
+}
+
+void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
+{
+ rCol = 0;
+ rRow = MAXROW+1;
+ while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
+ ++rCol;
+ SCCOL nCol = rCol;
+ while (nCol <= MAXCOL && rRow > 0)
+ {
+ if (!aCol[nCol].IsEmptyData())
+ rRow = ::std::min( rRow, aCol[nCol].GetFirstDataPos());
+ ++nCol;
+ }
+}
+
+void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
+{
+ rCol = MAXCOL;
+ rRow = 0;
+ while (aCol[rCol].IsEmptyData() && (rCol > 0))
+ rCol--;
+ SCCOL nCol = rCol;
+ while (nCol >= 0 && rRow < MAXROW)
+ rRow = ::std::max( rRow, aCol[nCol--].GetLastDataPos());
+}
+
+
+BOOL ScTable::HasData( SCCOL nCol, SCROW nRow )
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].HasDataAt( nRow );
+ else
+ return FALSE;
+}
+
+
+BOOL ScTable::HasStringData( SCCOL nCol, SCROW nRow )
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].HasStringData( nRow );
+ else
+ return FALSE;
+}
+
+
+BOOL ScTable::HasValueData( SCCOL nCol, SCROW nRow )
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].HasValueData( nRow );
+ else
+ return FALSE;
+}
+
+
+BOOL ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow ) const
+{
+ if ( ValidCol(nEndCol) )
+ for ( SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+//UNUSED2008-05 USHORT ScTable::GetErrCode( SCCOL nCol, SCROW nRow ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 if (ValidColRow( nCol, nRow ))
+//UNUSED2008-05 return aCol[nCol].GetErrCode( nRow );
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+
+void ScTable::SetDirtyVar()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].SetDirtyVar();
+}
+
+
+void ScTable::SetDirty()
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].SetDirty();
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScTable::SetDirty( const ScRange& rRange )
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ SCCOL nCol2 = rRange.aEnd.Col();
+ for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
+ aCol[i].SetDirty( rRange );
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScTable::SetTableOpDirty( const ScRange& rRange )
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // no multiple recalculation
+ SCCOL nCol2 = rRange.aEnd.Col();
+ for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
+ aCol[i].SetTableOpDirty( rRange );
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScTable::SetDirtyAfterLoad()
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].SetDirtyAfterLoad();
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScTable::SetRelNameDirty()
+{
+ BOOL bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].SetRelNameDirty();
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScTable::SetLoadingMedium(bool bLoading)
+{
+ mpRowHeights->enableTreeSearch(!bLoading);
+
+ // When loading a medium, prefer inserting row heights from the back
+ // position since the row heights are stored and read in ascending order
+ // during import.
+ mpRowHeights->setInsertFromBack(bLoading);
+}
+
+
+void ScTable::CalcAll()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
+}
+
+
+void ScTable::CompileAll()
+{
+ for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CompileAll();
+}
+
+
+void ScTable::CompileXML( ScProgress& rProgress )
+{
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ {
+ aCol[i].CompileXML( rProgress );
+ }
+}
+
+void ScTable::CalcAfterLoad()
+{
+ for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad();
+}
+
+
+void ScTable::ResetChanged( const ScRange& rRange )
+{
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
+ aCol[nCol].ResetChanged(nStartRow, nEndRow);
+}
+
+// Attribute
+
+const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, USHORT nWhich ) const
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].GetAttr( nRow, nWhich );
+ else
+ return NULL;
+}
+
+
+ULONG ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].GetNumberFormat( nRow );
+ else
+ return 0;
+}
+
+
+const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
+{
+ if (ValidColRow(nCol,nRow))
+ return aCol[nCol].GetPattern( nRow );
+ else
+ {
+ DBG_ERROR("wrong column or row");
+ return pDocument->GetDefPattern(); // for safety
+ }
+}
+
+
+const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
+{
+ if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
+ return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
+ else
+ return NULL;
+}
+
+
+bool ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const
+{
+ bool bFound = false;
+ for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
+ bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
+ return bFound;
+}
+
+
+//UNUSED2009-05 BOOL ScTable::HasLines( const ScRange& rRange, Rectangle& rSizes ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 SCCOL nCol1 = rRange.aStart.Col();
+//UNUSED2009-05 SCROW nRow1 = rRange.aStart.Row();
+//UNUSED2009-05 SCCOL nCol2 = rRange.aEnd.Col();
+//UNUSED2009-05 SCROW nRow2 = rRange.aEnd.Row();
+//UNUSED2009-05 PutInOrder( nCol1, nCol2 );
+//UNUSED2009-05 PutInOrder( nRow1, nRow2 );
+//UNUSED2009-05
+//UNUSED2009-05 BOOL bFound = FALSE;
+//UNUSED2009-05 for (SCCOL i=nCol1; i<=nCol2; i++)
+//UNUSED2009-05 if (aCol[i].HasLines( nRow1, nRow2, rSizes, (i==nCol1), (i==nCol2) ))
+//UNUSED2009-05 bFound = TRUE;
+//UNUSED2009-05
+//UNUSED2009-05 return bFound;
+//UNUSED2009-05 }
+
+
+BOOL ScTable::HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const
+{
+ BOOL bFound=FALSE;
+ for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
+ bFound |= aCol[i].HasAttribSelection( rMark, nMask );
+ return bFound;
+}
+
+
+BOOL ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow,
+ BOOL bRefresh, BOOL bAttrs )
+{
+ if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
+ {
+ DBG_ERRORFILE("ScTable::ExtendMerge: invalid column number");
+ return FALSE;
+ }
+ BOOL bFound=FALSE;
+ SCCOL nOldEndX = rEndCol;
+ SCROW nOldEndY = rEndRow;
+ for (SCCOL i=nStartCol; i<=nOldEndX; i++)
+ bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh, bAttrs );
+ return bFound;
+}
+
+
+BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
+{
+ if (!(ValidCol(nCol1) && ValidCol(nCol2)))
+ {
+ DBG_ERRORFILE("ScTable::IsBlockEmpty: invalid column number");
+ return FALSE;
+ }
+ BOOL bEmpty = TRUE;
+ for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
+ bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2, bIgnoreNotes );
+ return bEmpty;
+}
+
+SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
+ SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
+ const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
+{
+ // Rueckgabe = neues nArrY
+
+ BYTE nRotDir = pPattern->GetRotateDir( pCondSet );
+ if ( nRotDir != SC_ROTDIR_NONE )
+ {
+ BOOL bHit = TRUE;
+ if ( nCol+1 < nX1 ) // column to the left
+ bHit = ( nRotDir != SC_ROTDIR_LEFT );
+ else if ( nCol > nX2+1 ) // column to the right
+ bHit = ( nRotDir != SC_ROTDIR_RIGHT ); // SC_ROTDIR_STANDARD may now also be extended to the left
+
+ if ( bHit )
+ {
+ double nFactor = 0.0;
+ if ( nCol > nX2+1 )
+ {
+ long nRotVal = ((const SfxInt32Item&) pPattern->
+ GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
+ double nRealOrient = nRotVal * F_PI18000; // 1/100 Grad
+ double nCos = cos( nRealOrient );
+ double nSin = sin( nRealOrient );
+ //! begrenzen !!!
+ //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
+
+ // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
+ // wenn der Modus beruecksichtigt wird
+ nFactor = -fabs( nCos / nSin );
+ }
+
+ for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
+ {
+ if (!RowHidden(nRow))
+ {
+ BOOL bHitOne = TRUE;
+ if ( nCol > nX2+1 )
+ {
+ // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
+
+ SCCOL nTouchedCol = nCol;
+ long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor);
+ DBG_ASSERT(nWidth <= 0, "Richtung falsch");
+ while ( nWidth < 0 && nTouchedCol > 0 )
+ {
+ --nTouchedCol;
+ nWidth += GetColWidth( nTouchedCol );
+ }
+ if ( nTouchedCol > nX2 )
+ bHitOne = FALSE;
+ }
+
+ if (bHitOne)
+ {
+ while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
+ ++nArrY;
+ if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
+ pRowInfo[nArrY].nRotMaxCol = nCol;
+ }
+ }
+ }
+ }
+ }
+
+ return nArrY;
+}
+
+void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
+{
+ if ( !pColWidth || !mpRowHeights || !pColFlags || !pRowFlags )
+ {
+ DBG_ERROR( "Spalten-/Zeileninfo fehlt" );
+ return;
+ }
+
+ // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
+
+ SCROW nY1 = pRowInfo[0].nRowNo;
+ SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
+
+ for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
+ {
+ if (!ColHidden(nCol))
+ {
+ SCSIZE nArrY = 0;
+ ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
+ SCCOL nAttrCol;
+ SCROW nAttrRow1, nAttrRow2;
+ const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
+ while ( pPattern )
+ {
+ const SfxPoolItem* pCondItem;
+ if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, TRUE, &pCondItem )
+ == SFX_ITEM_SET )
+ {
+ // alle Formate durchgehen, damit die Zellen nicht einzeln
+ // angeschaut werden muessen
+
+ ULONG nIndex = ((const SfxUInt32Item*)pCondItem)->GetValue();
+ ScConditionalFormatList* pList = pDocument->GetCondFormList();
+ ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool();
+ if (pList && pStylePool && nIndex)
+ {
+ const ScConditionalFormat* pFormat = pList->GetFormat(nIndex);
+ if ( pFormat )
+ {
+ USHORT nEntryCount = pFormat->Count();
+ for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aStyleName = pFormat->GetEntry(nEntry)->GetStyle();
+ if (aStyleName.Len())
+ {
+ SfxStyleSheetBase* pStyleSheet =
+ pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
+ if ( pStyleSheet )
+ {
+ FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
+ nCol, nAttrRow1, nAttrRow2,
+ nArrY, pPattern, &pStyleSheet->GetItemSet() );
+ // nArrY nicht veraendern
+ }
+ }
+ }
+ }
+ }
+ }
+
+ nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
+ nCol, nAttrRow1, nAttrRow2,
+ nArrY, pPattern, NULL );
+
+ pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
+ }
+ }
+ }
+}
+
+BOOL ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
+{
+ // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
+ USHORT nEdges;
+
+ if ( nCol1 == nCol2 )
+ { // linke und rechte Spalte
+ const USHORT n = 4 | 16;
+ nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
+ // nicht (4 und 16) oder 1 oder 32
+ if ( nEdges && (((nEdges & n) != n) || (nEdges & 33)) )
+ return TRUE; // linke oder rechte Kante fehlt oder offen
+ }
+ else
+ { // linke Spalte
+ nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, 4 );
+ // nicht 4 oder 1 oder 32
+ if ( nEdges && (((nEdges & 4) != 4) || (nEdges & 33)) )
+ return TRUE; // linke Kante fehlt oder offen
+ // rechte Spalte
+ nEdges = aCol[nCol2].GetBlockMatrixEdges( nRow1, nRow2, 16 );
+ // nicht 16 oder 1 oder 32
+ if ( nEdges && (((nEdges & 16) != 16) || (nEdges & 33)) )
+ return TRUE; // rechte Kante fehlt oder offen
+ }
+
+ if ( nRow1 == nRow2 )
+ { // obere und untere Zeile
+ BOOL bOpen = FALSE;
+ const USHORT n = 2 | 8;
+ for ( SCCOL i=nCol1; i<=nCol2; i++)
+ {
+ nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
+ if ( nEdges )
+ {
+ if ( (nEdges & n) != n )
+ return TRUE; // obere oder untere Kante fehlt
+ if ( nEdges & 4 )
+ bOpen = TRUE; // linke Kante oeffnet, weitersehen
+ else if ( !bOpen )
+ return TRUE; // es gibt was, was nicht geoeffnet wurde
+ if ( nEdges & 16 )
+ bOpen = FALSE; // rechte Kante schliesst
+ }
+ }
+ if ( bOpen )
+ return TRUE; // es geht noch weiter
+ }
+ else
+ {
+ USHORT j, n;
+ SCROW nR;
+ // erst obere Zeile, dann untere Zeile
+ for ( j=0, nR=nRow1, n=8; j<2; j++, nR=nRow2, n=2 )
+ {
+ BOOL bOpen = FALSE;
+ for ( SCCOL i=nCol1; i<=nCol2; i++)
+ {
+ nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
+ if ( nEdges )
+ {
+ // in oberere Zeile keine obere Kante bzw.
+ // in unterer Zeile keine untere Kante
+ if ( (nEdges & n) != n )
+ return TRUE;
+ if ( nEdges & 4 )
+ bOpen = TRUE; // linke Kante oeffnet, weitersehen
+ else if ( !bOpen )
+ return TRUE; // es gibt was, was nicht geoeffnet wurde
+ if ( nEdges & 16 )
+ bOpen = FALSE; // rechte Kante schliesst
+ }
+ }
+ if ( bOpen )
+ return TRUE; // es geht noch weiter
+ }
+ }
+ return FALSE;
+}
+
+
+BOOL ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
+{
+ BOOL bFound=FALSE;
+ for (SCCOL i=0; i<=MAXCOL && !bFound; i++)
+ bFound |= aCol[i].HasSelectionMatrixFragment(rMark);
+ return bFound;
+}
+
+
+BOOL ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
+ SCROW nRow2, BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
+{
+ if ( !ValidColRow( nCol2, nRow2 ) )
+ {
+ DBG_ERRORFILE("IsBlockEditable: invalid column or row");
+ if (pOnlyNotBecauseOfMatrix)
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ return FALSE;
+ }
+
+ BOOL bIsEditable = TRUE;
+ if ( nLockCount )
+ bIsEditable = FALSE;
+ else if ( IsProtected() && !pDocument->IsScenario(nTab) )
+ {
+ if((bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED )) != FALSE)
+ {
+ // If Sheet is protected and cells are not protected then
+ // check the active scenario protect flag if this range is
+ // on the active scenario range. Note the 'copy back' must also
+ // be set to apply protection.
+ USHORT nScenTab = nTab+1;
+ while(pDocument->IsScenario(nScenTab))
+ {
+ ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
+ if(pDocument->IsActiveScenario(nScenTab) && pDocument->HasScenarioRange(nScenTab, aEditRange))
+ {
+ USHORT nFlags;
+ pDocument->GetScenarioFlags(nScenTab,nFlags);
+ bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
+ break;
+ }
+ nScenTab++;
+ }
+ }
+ }
+ else if (pDocument->IsScenario(nTab))
+ {
+ // Determine if the preceding sheet is protected
+ SCTAB nActualTab = nTab;
+ do
+ {
+ nActualTab--;
+ }
+ while(pDocument->IsScenario(nActualTab));
+
+ if(pDocument->IsTabProtected(nActualTab))
+ {
+ ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
+ if(pDocument->HasScenarioRange(nTab, aEditRange))
+ {
+ USHORT nFlags;
+ pDocument->GetScenarioFlags(nTab,nFlags);
+ bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
+ }
+ }
+ }
+ if ( bIsEditable )
+ {
+ if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
+ {
+ bIsEditable = FALSE;
+ if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = TRUE;
+ }
+ else if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ }
+ else if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ return bIsEditable;
+}
+
+
+BOOL ScTable::IsSelectionEditable( const ScMarkData& rMark,
+ BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
+{
+ BOOL bIsEditable = TRUE;
+ if ( nLockCount )
+ bIsEditable = FALSE;
+ else if ( IsProtected() && !pDocument->IsScenario(nTab) )
+ {
+ if((bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED )) != FALSE)
+ {
+ // If Sheet is protected and cells are not protected then
+ // check the active scenario protect flag if this area is
+ // in the active scenario range.
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, FALSE );
+ ULONG nRangeCount = aRanges.Count();
+ SCTAB nScenTab = nTab+1;
+ while(pDocument->IsScenario(nScenTab) && bIsEditable)
+ {
+ if(pDocument->IsActiveScenario(nScenTab))
+ {
+ for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+ if(pDocument->HasScenarioRange(nScenTab, aRange))
+ {
+ USHORT nFlags;
+ pDocument->GetScenarioFlags(nScenTab,nFlags);
+ bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
+ }
+ }
+ }
+ nScenTab++;
+ }
+ }
+ }
+ else if (pDocument->IsScenario(nTab))
+ {
+ // Determine if the preceding sheet is protected
+ SCTAB nActualTab = nTab;
+ do
+ {
+ nActualTab--;
+ }
+ while(pDocument->IsScenario(nActualTab));
+
+ if(pDocument->IsTabProtected(nActualTab))
+ {
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, FALSE );
+ ULONG nRangeCount = aRanges.Count();
+ for (ULONG i=0; i<nRangeCount && bIsEditable; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+ if(pDocument->HasScenarioRange(nTab, aRange))
+ {
+ USHORT nFlags;
+ pDocument->GetScenarioFlags(nTab,nFlags);
+ bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
+ }
+ }
+ }
+ }
+ if ( bIsEditable )
+ {
+ if ( HasSelectionMatrixFragment( rMark ) )
+ {
+ bIsEditable = FALSE;
+ if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = TRUE;
+ }
+ else if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ }
+ else if ( pOnlyNotBecauseOfMatrix )
+ *pOnlyNotBecauseOfMatrix = FALSE;
+ return bIsEditable;
+}
+
+
+
+void ScTable::LockTable()
+{
+ ++nLockCount;
+}
+
+
+void ScTable::UnlockTable()
+{
+ if (nLockCount)
+ --nLockCount;
+ else
+ {
+ DBG_ERROR("UnlockTable ohne LockTable");
+ }
+}
+
+
+void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
+}
+
+
+void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2, BOOL bDeep ) const
+{
+ for (SCCOL i=nCol1; i<=nCol2; i++)
+ aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
+}
+
+
+void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ for (SCCOL i=nStartCol; i<=nEndCol; i++)
+ aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
+ nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
+ }
+}
+
+
+void ScTable::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ for (SCCOL i=nStartCol; i<=nEndCol; i++)
+ aCol[i].ApplyBlockFrame( pLineOuter, pLineInner,
+ nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
+ }
+}
+
+
+void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].ApplyPattern( nRow, rAttr );
+}
+
+
+void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScPatternAttr& rAttr )
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ for (SCCOL i = nStartCol; i <= nEndCol; i++)
+ aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr);
+ }
+}
+
+void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
+ const ScPatternAttr& rPattern, short nNewType )
+{
+ SCCOL nEndCol = rRange.aEnd.Col();
+ for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
+ }
+}
+
+
+
+void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet& rStyle )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].ApplyStyle( nRow, rStyle );
+}
+
+
+void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ for (SCCOL i = nStartCol; i <= nEndCol; i++)
+ aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
+ }
+}
+
+
+void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].ApplySelectionStyle( rStyle, rMark );
+}
+
+
+void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark,
+ const SvxBorderLine* pLine, BOOL bColorOnly )
+{
+ if ( bColorOnly && !pLine )
+ return;
+
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
+}
+
+
+const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
+{
+ if (ValidColRow(nCol, nRow))
+ return aCol[nCol].GetStyle(nRow);
+ else
+ return NULL;
+}
+
+
+const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, BOOL& rFound ) const
+{
+ rFound = FALSE;
+
+ BOOL bEqual = TRUE;
+ BOOL bColFound;
+
+ const ScStyleSheet* pStyle = NULL;
+ const ScStyleSheet* pNewStyle;
+
+ for (SCCOL i=0; i<=MAXCOL && bEqual; i++)
+ if (rMark.HasMultiMarks(i))
+ {
+ pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
+ if (bColFound)
+ {
+ rFound = TRUE;
+ if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
+ bEqual = FALSE; // unterschiedliche
+ pStyle = pNewStyle;
+ }
+ }
+
+ return bEqual ? pStyle : NULL;
+}
+
+
+const ScStyleSheet* ScTable::GetAreaStyle( BOOL& rFound, SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2 ) const
+{
+ rFound = FALSE;
+
+ BOOL bEqual = TRUE;
+ BOOL bColFound;
+
+ const ScStyleSheet* pStyle = NULL;
+ const ScStyleSheet* pNewStyle;
+
+ for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
+ {
+ pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
+ if (bColFound)
+ {
+ rFound = TRUE;
+ if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
+ bEqual = FALSE; // unterschiedliche
+ pStyle = pNewStyle;
+ }
+ }
+
+ return bEqual ? pStyle : NULL;
+}
+
+
+BOOL ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
+{
+ BOOL bIsUsed = FALSE;
+
+ for ( SCCOL i=0; i<=MAXCOL; i++ )
+ {
+ if ( aCol[i].IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
+ {
+ if ( !bGatherAllStyles )
+ return TRUE;
+ bIsUsed = TRUE;
+ }
+ }
+
+ return bIsUsed;
+}
+
+
+void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRemoved,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY )
+{
+ ScFlatBoolRowSegments aUsedRows;
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
+
+ SCROW nRow = 0;
+ while (nRow <= MAXROW)
+ {
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!aUsedRows.getRangeData(nRow, aData))
+ // search failed!
+ return;
+
+ SCROW nEndRow = aData.mnRow2;
+ if (aData.mbValue)
+ SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE);
+
+ nRow = nEndRow + 1;
+ }
+}
+
+
+BOOL ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ INT16 nFlags )
+{
+ BOOL bChanged = FALSE;
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ for (SCCOL i = nStartCol; i <= nEndCol; i++)
+ bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
+ return bChanged;
+}
+
+
+BOOL ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ INT16 nFlags )
+{
+ BOOL bChanged = FALSE;
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ for (SCCOL i = nStartCol; i <= nEndCol; i++)
+ bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
+ return bChanged;
+}
+
+
+void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, BOOL bPutToPool )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].SetPattern( nRow, rAttr, bPutToPool );
+}
+
+
+void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
+{
+ if (ValidColRow(nCol,nRow))
+ aCol[nCol].ApplyAttr( nRow, rAttr );
+}
+
+
+void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].ApplySelectionCache( pCache, rMark );
+}
+
+
+void ScTable::ChangeSelectionIndent( BOOL bIncrement, const ScMarkData& rMark )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].ChangeSelectionIndent( bIncrement, rMark );
+}
+
+
+void ScTable::ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ aCol[i].ClearSelectionItems( pWhich, rMark );
+}
+
+
+// Spaltenbreiten / Zeilenhoehen
+
+void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
+{
+ if (VALIDCOL(nCol) && pColWidth)
+ {
+ if (!nNewWidth)
+ {
+// DBG_ERROR("Spaltenbreite 0 in SetColWidth");
+ nNewWidth = STD_COL_WIDTH;
+ }
+
+ if ( nNewWidth != pColWidth[nCol] )
+ {
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
+ pColWidth[nCol] = nNewWidth;
+ DecRecalcLevel();
+
+ InvalidatePageBreaks();
+ }
+ }
+ else
+ {
+ DBG_ERROR("Falsche Spaltennummer oder keine Breiten");
+ }
+}
+
+
+void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
+{
+ if (VALIDROW(nRow) && mpRowHeights)
+ {
+ if (!nNewHeight)
+ {
+ DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
+ nNewHeight = ScGlobal::nStdRowHeight;
+ }
+
+ sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow);
+ if ( nNewHeight != nOldHeight )
+ {
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
+ mpRowHeights->setValue(nRow, nRow, nNewHeight);
+ DecRecalcLevel();
+
+ InvalidatePageBreaks();
+ }
+ }
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
+ }
+}
+
+namespace {
+
+/**
+ * Check if the new pixel size is different from the old size between
+ * specified ranges.
+ */
+bool lcl_pixelSizeChanged(
+ ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow,
+ sal_uInt16 nNewHeight, double nPPTY)
+{
+ long nNewPix = static_cast<long>(nNewHeight * nPPTY);
+
+ ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights);
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ sal_uInt16 nHeight;
+ if (!aFwdIter.getValue(nRow, nHeight))
+ break;
+
+ if (nHeight != nNewHeight)
+ {
+ bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY));
+ if (bChanged)
+ return true;
+ }
+
+ // Skip ahead to the last position of the current range.
+ nRow = aFwdIter.getLastPos();
+ }
+ return false;
+}
+
+}
+
+BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
+ double /* nPPTX */, double nPPTY )
+{
+ BOOL bChanged = FALSE;
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights)
+ {
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ if (!nNewHeight)
+ {
+ DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
+ nNewHeight = ScGlobal::nStdRowHeight;
+ }
+
+ BOOL bSingle = FALSE; // TRUE = process every row for its own
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
+ bSingle = TRUE;
+
+ if (bSingle)
+ {
+ ScFlatUInt16RowSegments::RangeData aData;
+ mpRowHeights->getRangeData(nStartRow, aData);
+ if (nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2)
+ bSingle = FALSE; // no difference in this range
+ }
+ if (bSingle)
+ {
+ if (nEndRow-nStartRow < 20)
+ {
+ if (!bChanged)
+ bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
+
+ /* #i94028# #i94991# If drawing objects are involved, each row
+ has to be changed for its own, because each call to
+ ScDrawLayer::HeightChanged expects correct row heights
+ above passed row in the document. Cannot use array iterator
+ because array changes in every cycle. */
+ if( pDrawLayer )
+ {
+ for( SCROW nRow = nStartRow; nRow <= nEndRow ; ++nRow )
+ {
+ pDrawLayer->HeightChanged( nTab, nRow,
+ static_cast<long>(nNewHeight) - static_cast<long>(mpRowHeights->getValue(nRow)));
+ mpRowHeights->setValue(nRow, nRow, nNewHeight);
+ }
+ }
+ else
+ mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
+ }
+ else
+ {
+ SCROW nMid = (nStartRow+nEndRow) / 2;
+ if (SetRowHeightRange( nStartRow, nMid, nNewHeight, 1.0, 1.0 ))
+ bChanged = TRUE;
+ if (SetRowHeightRange( nMid+1, nEndRow, nNewHeight, 1.0, 1.0 ))
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ if (pDrawLayer)
+ {
+ // #i115025# When comparing to nNewHeight for the whole range, the height
+ // including hidden rows has to be used (same behavior as 3.2).
+ unsigned long nOldHeights = mpRowHeights->getSumValue(nStartRow, nEndRow);
+ // FIXME: should we test for overflows?
+ long nHeightDif = (long) (unsigned long) nNewHeight *
+ (nEndRow - nStartRow + 1) - nOldHeights;
+ pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif );
+ }
+
+ if (!bChanged)
+ bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
+
+ mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
+ }
+ DecRecalcLevel();
+
+ if (bChanged)
+ InvalidatePageBreaks();
+ }
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer oder keine Hoehen");
+ }
+
+ return bChanged;
+}
+
+void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight )
+{
+ if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights)
+ return;
+
+ if (!nNewHeight)
+ nNewHeight = ScGlobal::nStdRowHeight;
+
+ mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
+}
+
+void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
+{
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
+ {
+ if (bManual)
+ pRowFlags->OrValue( nStartRow, nEndRow, CR_MANUALSIZE);
+ else
+ pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_MANUALSIZE));
+ }
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer oder keine Zeilenflags");
+ }
+}
+
+
+USHORT ScTable::GetColWidth( SCCOL nCol ) const
+{
+ DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
+
+ if (VALIDCOL(nCol) && pColFlags && pColWidth)
+ {
+ if (ColHidden(nCol))
+ return 0;
+ else
+ return pColWidth[nCol];
+ }
+ else
+ return (USHORT) STD_COL_WIDTH;
+}
+
+
+USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingestellte
+{
+ DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
+
+ if (VALIDCOL(nCol) && pColWidth)
+ return pColWidth[nCol];
+ else
+ return (USHORT) STD_COL_WIDTH;
+}
+
+
+USHORT ScTable::GetCommonWidth( SCCOL nEndCol )
+{
+ // get the width that is used in the largest continuous column range (up to nEndCol)
+
+ if ( !ValidCol(nEndCol) )
+ {
+ DBG_ERROR("wrong column");
+ nEndCol = MAXCOL;
+ }
+
+ USHORT nMaxWidth = 0;
+ USHORT nMaxCount = 0;
+ SCCOL nRangeStart = 0;
+ while ( nRangeStart <= nEndCol )
+ {
+ // skip hidden columns
+ while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
+ ++nRangeStart;
+ if ( nRangeStart <= nEndCol )
+ {
+ USHORT nThisCount = 0;
+ USHORT nThisWidth = pColWidth[nRangeStart];
+ SCCOL nRangeEnd = nRangeStart;
+ while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
+ {
+ ++nThisCount;
+ ++nRangeEnd;
+
+ // skip hidden columns
+ while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
+ ++nRangeEnd;
+ }
+
+ if ( nThisCount > nMaxCount )
+ {
+ nMaxCount = nThisCount;
+ nMaxWidth = nThisWidth;
+ }
+
+ nRangeStart = nRangeEnd; // next range
+ }
+ }
+
+ return nMaxWidth;
+}
+
+
+USHORT ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
+{
+ DBG_ASSERT(VALIDROW(nRow),"Invalid row number");
+
+ if (VALIDROW(nRow) && mpRowHeights)
+ {
+ if (bHiddenAsZero && RowHidden( nRow, pStartRow, pEndRow))
+ return 0;
+ else
+ {
+ ScFlatUInt16RowSegments::RangeData aData;
+ if (!mpRowHeights->getRangeData(nRow, aData))
+ {
+ if (pStartRow)
+ *pStartRow = nRow;
+ if (pEndRow)
+ *pEndRow = nRow;
+ // TODO: What should we return in case the search fails?
+ return 0;
+ }
+
+ // If bHiddenAsZero, pStartRow and pEndRow were initialized to
+ // boundaries of a non-hidden segment. Assume that the previous and
+ // next segment are hidden then and limit the current height
+ // segment.
+ if (pStartRow)
+ *pStartRow = (bHiddenAsZero ? std::max( *pStartRow, aData.mnRow1) : aData.mnRow1);
+ if (pEndRow)
+ *pEndRow = (bHiddenAsZero ? std::min( *pEndRow, aData.mnRow2) : aData.mnRow2);
+ return aData.mnValue;
+ }
+ }
+ else
+ {
+ if (pStartRow)
+ *pStartRow = nRow;
+ if (pEndRow)
+ *pEndRow = nRow;
+ return (USHORT) ScGlobal::nStdRowHeight;
+ }
+}
+
+
+ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const
+{
+ DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
+
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights)
+ {
+ ULONG nHeight = 0;
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ if (!RowHidden(nRow, nLastRow))
+ {
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ nHeight += mpRowHeights->getSumValue(nRow, nLastRow);
+ }
+ nRow = nLastRow + 1;
+ }
+ return nHeight;
+ }
+ else
+ return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight);
+}
+
+
+ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const
+{
+ DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
+
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights)
+ {
+ ULONG nHeight = 0;
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ if (!RowHidden(nRow, nLastRow))
+ {
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ sal_uInt32 nThisHeight = mpRowHeights->getSumValue(nRow, nLastRow);
+ nHeight += static_cast<ULONG>(nThisHeight * fScale);
+ }
+ nRow = nLastRow + 1;
+ }
+ return nHeight;
+ }
+ else
+ return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
+}
+
+
+USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hidden
+{
+ DBG_ASSERT(VALIDROW(nRow),"wrong row number");
+
+ if (VALIDROW(nRow) && mpRowHeights)
+ return mpRowHeights->getValue(nRow);
+ else
+ return (USHORT) ScGlobal::nStdRowHeight;
+}
+
+
+// Spalten-/Zeilen-Flags
+
+
+SCROW ScTable::GetHiddenRowCount( SCROW nRow )
+{
+ if (!ValidRow(nRow))
+ return 0;
+
+ SCROW nLastRow = -1;
+ if (!RowHidden(nRow, nLastRow) || !ValidRow(nLastRow))
+ return 0;
+
+ return nLastRow - nRow + 1;
+}
+
+
+//! ShowRows / DBShowRows zusammenfassen
+
+void ScTable::ShowCol(SCCOL nCol, bool bShow)
+{
+ if (VALIDCOL(nCol))
+ {
+ bool bWasVis = !ColHidden(nCol);
+ if (bWasVis != bShow)
+ {
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ if (bShow)
+ pDrawLayer->WidthChanged( nTab, nCol, (long) pColWidth[nCol] );
+ else
+ pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] );
+ }
+
+ SetColHidden(nCol, nCol, !bShow);
+ DecRecalcLevel();
+
+ ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+ if ( pCharts )
+ pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ));
+ }
+ }
+ else
+ {
+ DBG_ERROR("Falsche Spaltennummer oder keine Flags");
+ }
+}
+
+
+void ScTable::ShowRow(SCROW nRow, bool bShow)
+{
+ if (VALIDROW(nRow) && pRowFlags)
+ {
+ bool bWasVis = !RowHidden(nRow);
+ if (bWasVis != bShow)
+ {
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ if (bShow)
+ pDrawLayer->HeightChanged(
+ nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow)));
+ else
+ pDrawLayer->HeightChanged(
+ nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow)));
+ }
+
+ SetRowHidden(nRow, nRow, !bShow);
+ if (bShow)
+ SetRowFiltered(nRow, nRow, false);
+ DecRecalcLevel();
+
+ ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+ if ( pCharts )
+ pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
+
+ InvalidatePageBreaks();
+ }
+ }
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer oder keine Flags");
+ }
+}
+
+
+void ScTable::DBShowRow(SCROW nRow, bool bShow)
+{
+ if (VALIDROW(nRow) && pRowFlags)
+ {
+ bool bWasVis = !RowHidden(nRow);
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+ if (bWasVis != bShow)
+ {
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ if (bShow)
+ pDrawLayer->HeightChanged(
+ nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow)));
+ else
+ pDrawLayer->HeightChanged(
+ nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow)));
+ }
+ }
+
+ // Filter-Flag immer setzen, auch wenn Hidden unveraendert
+ SetRowHidden(nRow, nRow, !bShow);
+ SetRowFiltered(nRow, nRow, !bShow);
+ DecRecalcLevel();
+
+ if (bWasVis != bShow)
+ {
+ ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+ if ( pCharts )
+ pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
+
+ if (pOutlineTable)
+ UpdateOutlineRow( nRow, nRow, bShow );
+
+ InvalidatePageBreaks();
+ }
+ }
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer oder keine Flags");
+ }
+}
+
+
+void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bSetFlags)
+{
+ // #i116164# IncRecalcLevel/DecRecalcLevel is in ScTable::Query
+ SCROW nStartRow = nRow1;
+ InitializeNoteCaptions();
+ while (nStartRow <= nRow2)
+ {
+ SCROW nEndRow = -1;
+ bool bWasVis = !RowHidden(nStartRow, nEndRow);
+ if (nEndRow > nRow2)
+ nEndRow = nRow2;
+
+ BOOL bChanged = ( bWasVis != bShow );
+ if ( bChanged && bSetFlags )
+ {
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow));
+ if (bShow)
+ pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
+ else
+ pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
+ }
+ }
+
+ // #i116164# Directly modify the flags only if there are drawing objects within the area.
+ // Otherwise, all modifications are made together in ScTable::Query, so the tree isn't constantly rebuilt.
+ if ( bSetFlags )
+ {
+ SetRowHidden(nStartRow, nEndRow, !bShow);
+ SetRowFiltered(nStartRow, nEndRow, !bShow);
+ }
+
+ if ( bChanged )
+ {
+ ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+ if ( pCharts )
+ pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
+ }
+
+ nStartRow = nEndRow + 1;
+ }
+
+ // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
+ // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
+ // to be done here.
+ if (pOutlineTable)
+ UpdateOutlineRow( nRow1, nRow2, bShow );
+}
+
+
+void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
+{
+ SCROW nStartRow = nRow1;
+ IncRecalcLevel();
+ InitializeNoteCaptions();
+
+ // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, nRow1, nRow2, false );
+ long nOldHeight = 0;
+ if ( pDrawLayer && !bHasObjects )
+ nOldHeight = static_cast<long>(GetRowHeight(nRow1, nRow2));
+
+ while (nStartRow <= nRow2)
+ {
+ SCROW nEndRow = -1;
+ bool bWasVis = !RowHidden(nStartRow, nEndRow);
+ if (nEndRow > nRow2)
+ nEndRow = nRow2;
+
+ BOOL bChanged = ( bWasVis != bShow );
+ if ( bChanged && bHasObjects )
+ {
+ if (pDrawLayer)
+ {
+ long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow));
+ if (bShow)
+ pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
+ else
+ pDrawLayer->HeightChanged( nTab, nStartRow, -nHeight );
+ }
+ }
+
+ // #i116164# Directly modify the flags only if there are drawing objects within the area.
+ // Otherwise, all rows are modified together after the loop, so the tree isn't constantly rebuilt.
+ if ( bHasObjects )
+ {
+ SetRowHidden(nStartRow, nEndRow, !bShow);
+ if (bShow)
+ SetRowFiltered(nStartRow, nEndRow, false);
+ }
+
+ if ( bChanged )
+ {
+ ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+ if ( pCharts )
+ pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
+
+ InvalidatePageBreaks();
+ }
+
+ nStartRow = nEndRow + 1;
+ }
+
+ if ( !bHasObjects )
+ {
+ // #i116164# set the flags for the whole range at once
+ SetRowHidden(nRow1, nRow2, !bShow);
+ if (bShow)
+ SetRowFiltered(nRow1, nRow2, false);
+
+ if ( pDrawLayer )
+ {
+ // if there are no objects in the range, a single HeightChanged call is enough
+ long nNewHeight = 0;
+ if ( bShow )
+ nNewHeight = static_cast<long>(GetRowHeight(nRow1, nRow2));
+ if ( nNewHeight != nOldHeight )
+ pDrawLayer->HeightChanged( nTab, nRow1, nNewHeight - nOldHeight );
+ }
+ }
+
+ DecRecalcLevel();
+}
+
+
+void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags )
+{
+ if (VALIDCOL(nCol) && pColFlags)
+ pColFlags[nCol] = nNewFlags;
+ else
+ {
+ DBG_ERROR("Falsche Spaltennummer oder keine Flags");
+ }
+}
+
+
+void ScTable::SetRowFlags( SCROW nRow, BYTE nNewFlags )
+{
+ if (VALIDROW(nRow) && pRowFlags)
+ pRowFlags->SetValue( nRow, nNewFlags);
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer oder keine Flags");
+ }
+}
+
+
+void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, BYTE nNewFlags )
+{
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags)
+ pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
+ else
+ {
+ DBG_ERROR("Falsche Zeilennummer(n) oder keine Flags");
+ }
+}
+
+
+BYTE ScTable::GetColFlags( SCCOL nCol ) const
+{
+ if (VALIDCOL(nCol) && pColFlags)
+ return pColFlags[nCol];
+ else
+ return 0;
+}
+
+
+BYTE ScTable::GetRowFlags( SCROW nRow ) const
+{
+ if (VALIDROW(nRow) && pRowFlags)
+ return pRowFlags->GetValue(nRow);
+ else
+ return 0;
+}
+
+
+SCROW ScTable::GetLastFlaggedRow() const
+{
+ SCROW nLastFound = 0;
+ if (pRowFlags)
+ {
+ SCROW nRow = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
+ if (ValidRow(nRow))
+ nLastFound = nRow;
+ }
+
+ if (!maRowManualBreaks.empty())
+ nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin());
+
+ if (mpHiddenRows)
+ {
+ SCROW nRow = mpHiddenRows->findLastNotOf(false);
+ if (ValidRow(nRow))
+ nLastFound = ::std::max(nLastFound, nRow);
+ }
+
+ if (mpFilteredRows)
+ {
+ SCROW nRow = mpFilteredRows->findLastNotOf(false);
+ if (ValidRow(nRow))
+ nLastFound = ::std::max(nLastFound, nRow);
+ }
+
+ return nLastFound;
+}
+
+
+SCCOL ScTable::GetLastChangedCol() const
+{
+ if ( !pColFlags )
+ return 0;
+
+ SCCOL nLastFound = 0;
+ for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
+ if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
+ nLastFound = nCol;
+
+ return nLastFound;
+}
+
+
+SCROW ScTable::GetLastChangedRow() const
+{
+ if ( !pRowFlags )
+ return 0;
+
+ SCROW nLastFlags = GetLastFlaggedRow();
+
+ // Find the last row position where the height is NOT the standard row
+ // height.
+ // KOHEI: Test this to make sure it does what it's supposed to.
+ SCROW nLastHeight = mpRowHeights->findLastNotOf(ScGlobal::nStdRowHeight);
+ if (!ValidRow(nLastHeight))
+ nLastHeight = 0;
+
+ return std::max( nLastFlags, nLastHeight);
+}
+
+
+BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
+{
+ if (pOutlineTable && pColFlags)
+ {
+ ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
+ return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, *this, true );
+ }
+ else
+ return FALSE;
+}
+
+
+BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
+{
+ if (pOutlineTable && pRowFlags)
+ return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *this, false );
+ else
+ return FALSE;
+}
+
+
+void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
+{
+ // Column-wise expansion
+
+ while (rX1 > 0 && ColHidden(rX1-1))
+ --rX1;
+
+ while (rX2 < MAXCOL && ColHidden(rX2+1))
+ ++rX2;
+
+ // Row-wise expansion
+
+ if (rY1 > 0)
+ {
+ ScFlatBoolRowSegments::RangeData aData;
+ if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
+ {
+ SCROW nStartRow = aData.mnRow1;
+ if (ValidRow(nStartRow))
+ rY1 = nStartRow;
+ }
+ }
+ if (rY2 < MAXROW)
+ {
+ SCROW nEndRow = -1;
+ if (RowHidden(rY2+1, nEndRow) && ValidRow(nEndRow))
+ rY2 = nEndRow;
+ }
+}
+
+
+void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
+{
+ while ( rX2>rX1 && ColHidden(rX2) )
+ --rX2;
+ while ( rX2>rX1 && ColHidden(rX1) )
+ ++rX1;
+
+ if (rY1 < rY2)
+ {
+ ScFlatBoolRowSegments::RangeData aData;
+ if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
+ {
+ SCROW nStartRow = aData.mnRow1;
+ if (ValidRow(nStartRow) && nStartRow >= rY1)
+ rY2 = nStartRow;
+ }
+ }
+
+ if (rY1 < rY2)
+ {
+ SCROW nEndRow = -1;
+ if (RowHidden(rY1, nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
+ rY1 = nEndRow;
+ }
+}
+
+
+// Auto-Outline
+
+template< typename T >
+short DiffSign( T a, T b )
+{
+ return (a<b) ? -1 :
+ (a>b) ? 1 : 0;
+}
+
+
+void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ BOOL bSizeChanged = FALSE;
+ BOOL bMissed = FALSE;
+
+ SCCOL nCol;
+ SCROW nRow;
+ SCROW i;
+ BOOL bFound;
+ ScOutlineArray* pArray;
+ ScBaseCell* pCell;
+ ScRange aRef;
+/* ScPatternAttr aBoldPattern( pDocument->GetPool() ); //! spezielle Format-Vorlage
+ aBoldPattern.GetItemSet().Put( SvxWeightItem( WEIGHT_BOLD ) );
+*/
+
+ StartOutlineTable();
+
+ // Zeilen
+
+ SCROW nCount = nEndRow-nStartRow+1;
+ BOOL* pUsed = new BOOL[nCount];
+ for (i=0; i<nCount; i++)
+ pUsed[i] = FALSE;
+ for (nCol=nStartCol; nCol<=nEndCol; nCol++)
+ if (!aCol[nCol].IsEmptyData())
+ aCol[nCol].FindUsed( nStartRow, nEndRow, pUsed );
+
+ pArray = pOutlineTable->GetRowArray();
+ for (nRow=nStartRow; nRow<=nEndRow; nRow++)
+ if (pUsed[nRow-nStartRow])
+ {
+ bFound = FALSE;
+ for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
+ if (!aCol[nCol].IsEmptyData())
+ {
+ pCell = aCol[nCol].GetCell( nRow );
+ if (pCell)
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ 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 ) ==
+ DiffSign( aRef.aEnd.Row(), nRow ) )
+ {
+ if (pArray->Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
+ {
+// ApplyPatternArea( nStartCol, nRow, nEndCol, nRow, aBoldPattern );
+ bFound = TRUE;
+ }
+ else
+ bMissed = TRUE;
+ }
+ }
+ }
+
+ delete[] pUsed;
+
+ // Spalten
+
+ pArray = pOutlineTable->GetColArray();
+ for (nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ if (!aCol[nCol].IsEmptyData())
+ {
+ bFound = FALSE;
+ ScColumnIterator aIter( &aCol[nCol], nStartRow, nEndRow );
+ while ( aIter.Next( nRow, pCell ) && !bFound )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ 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 ) ==
+ DiffSign( aRef.aEnd.Col(), nCol ) )
+ {
+ if (pArray->Insert( aRef.aStart.Col(), aRef.aEnd.Col(), bSizeChanged ))
+ {
+// ApplyPatternArea( nCol, nStartRow, nCol, nEndRow, aBoldPattern );
+ bFound = TRUE;
+ }
+ else
+ bMissed = TRUE;
+ }
+ }
+ }
+ }
+}
+
+ // CopyData - fuer Query in anderen Bereich
+
+void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
+{
+ //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
+
+ ScAddress aSrc( nStartCol, nStartRow, nTab );
+ ScAddress aDest( nDestCol, nDestRow, nDestTab );
+ ScRange aRange( aSrc, aDest );
+ BOOL bThisTab = ( nDestTab == nTab );
+ SCROW nDestY = nDestRow;
+ for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
+ {
+ aSrc.SetRow( nRow );
+ aDest.SetRow( nDestY );
+ SCCOL nDestX = nDestCol;
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ aSrc.SetCol( nCol );
+ aDest.SetCol( nDestX );
+ ScBaseCell* pCell = GetCell( nCol, nRow );
+ if (pCell)
+ {
+ pCell = pCell->CloneWithoutNote( *pDocument );
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ((ScFormulaCell*)pCell)->UpdateReference( URM_COPY, aRange,
+ ((SCsCOL) nDestCol) - ((SCsCOL) nStartCol),
+ ((SCsROW) nDestRow) - ((SCsROW) nStartRow),
+ ((SCsTAB) nDestTab) - ((SCsTAB) nTab) );
+ ((ScFormulaCell*)pCell)->aPos = aDest;
+ }
+ }
+ if (bThisTab)
+ {
+ PutCell( nDestX, nDestY, pCell );
+ SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ), TRUE );
+ }
+ else
+ {
+ pDocument->PutCell( aDest, pCell );
+ pDocument->SetPattern( aDest, *GetPattern( nCol, nRow ), TRUE );
+ }
+
+ ++nDestX;
+ }
+ ++nDestY;
+ }
+}
+
+
+BOOL ScTable::RefVisible(ScFormulaCell* pCell)
+{
+ ScRange aRef;
+
+ if (pCell->HasOneReference(aRef))
+ {
+ if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
+ {
+ SCROW nEndRow;
+ if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
+ // row not filtered.
+ nEndRow = ::std::numeric_limits<SCROW>::max();
+
+ if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
+ return TRUE; // at least partly visible
+ return FALSE; // completely invisible
+ }
+ }
+
+ return TRUE; // irgendwie anders
+}
+
+
+void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, String& rStr)
+{
+ GetInputString(nCol, nRow, rStr);
+ rStr.EraseTrailingChars();
+ rStr.EraseLeadingChars();
+ ScGlobal::pCharClass->toUpper(rStr);
+}
+
+
+// Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
+
+void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos)
+{
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ if( pDrawLayer )
+ {
+ double fValX = GetColOffset( MAXCOL + 1 ) * HMM_PER_TWIPS;
+ double fValY = GetRowOffset( MAXROW + 1 ) * HMM_PER_TWIPS;
+ const long nMax = ::std::numeric_limits<long>::max();
+ // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
+ // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
+ long x = ( fValX > (double)nMax ) ? nMax : (long) fValX;
+ long y = ( fValY > (double)nMax ) ? nMax : (long) fValY;
+
+ if ( IsLayoutRTL() ) // IsNegativePage
+ x = -x;
+
+ pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ), bUpdateNoteCaptionPos );
+ }
+
+ // #i102616# actions that modify the draw page size count as sheet modification
+ // (exception: InitDrawLayer)
+ if (bResetStreamValid && IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+
+ULONG ScTable::GetRowOffset( SCROW nRow ) const
+{
+ ULONG n = 0;
+ if ( mpHiddenRows && mpRowHeights )
+ {
+ if (nRow == 0)
+ return 0;
+ else if (nRow == 1)
+ return GetRowHeight(0);
+
+ n = GetTotalRowHeight(0, nRow-1);
+#ifdef DBG_UTIL
+ if (n == ::std::numeric_limits<unsigned long>::max())
+ DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
+#endif
+ }
+ else
+ {
+ DBG_ERROR("GetRowOffset: Daten fehlen");
+ }
+ return n;
+}
+
+SCROW ScTable::GetRowForHeight(ULONG nHeight) const
+{
+ sal_uInt32 nSum = 0;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ for (SCROW nRow = 0; nRow <= MAXROW; ++nRow)
+ {
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mbValue)
+ {
+ nRow = aData.mnRow2;
+ continue;
+ }
+
+ sal_uInt32 nNew = mpRowHeights->getValue(nRow);
+ nSum += nNew;
+ if (nSum > nHeight)
+ {
+ return nRow < MAXROW ? nRow + 1 : MAXROW;
+ }
+ }
+ return -1;
+}
+
+
+ULONG ScTable::GetColOffset( SCCOL nCol ) const
+{
+ ULONG n = 0;
+ if ( pColWidth )
+ {
+ SCCOL i;
+ for( i = 0; i < nCol; i++ )
+ if (!ColHidden(i))
+ n += pColWidth[i];
+ }
+ else
+ {
+ DBG_ERROR("GetColumnOffset: Daten fehlen");
+ }
+ return n;
+}
+
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
new file mode 100644
index 000000000000..8828d8ab2449
--- /dev/null
+++ b/sc/source/core/data/table3.cxx
@@ -0,0 +1,2022 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <rtl/math.hxx>
+#include <unotools/textsearch.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <com/sun/star/i18n/CollatorOptions.hpp>
+#include <stdlib.h>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "table.hxx"
+#include "scitems.hxx"
+#include "collect.hxx"
+#include "attrib.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "stlpool.hxx"
+#include "compiler.hxx"
+#include "patattr.hxx"
+#include "subtotal.hxx"
+#include "docoptio.hxx"
+#include "markdata.hxx"
+#include "rangelst.hxx"
+#include "attarray.hxx"
+#include "userlist.hxx"
+#include "progress.hxx"
+#include "cellform.hxx"
+#include "postit.hxx"
+#include "queryparam.hxx"
+#include "segmenttree.hxx"
+#include "drwlayer.hxx"
+
+#include <vector>
+
+// STATIC DATA -----------------------------------------------------------
+
+const USHORT nMaxSorts = 3; // maximale Anzahl Sortierkriterien in aSortParam
+
+struct ScSortInfo
+{
+ ScBaseCell* pCell;
+ SCCOLROW nOrg;
+ DECL_FIXEDMEMPOOL_NEWDEL( ScSortInfo );
+};
+const USHORT nMemPoolSortInfo = (0x8000 - 64) / sizeof(ScSortInfo);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScSortInfo, nMemPoolSortInfo, nMemPoolSortInfo )
+
+// END OF STATIC DATA -----------------------------------------------------
+
+
+class ScSortInfoArray
+{
+private:
+ ScSortInfo** pppInfo[nMaxSorts];
+ SCSIZE nCount;
+ SCCOLROW nStart;
+ USHORT nUsedSorts;
+
+public:
+ ScSortInfoArray( USHORT nSorts, SCCOLROW nInd1, SCCOLROW nInd2 ) :
+ nCount( nInd2 - nInd1 + 1 ), nStart( nInd1 ),
+ nUsedSorts( Min( nSorts, nMaxSorts ) )
+ {
+ for ( USHORT nSort = 0; nSort < nUsedSorts; nSort++ )
+ {
+ ScSortInfo** ppInfo = new ScSortInfo* [nCount];
+ for ( SCSIZE j = 0; j < nCount; j++ )
+ ppInfo[j] = new ScSortInfo;
+ pppInfo[nSort] = ppInfo;
+ }
+ }
+ ~ScSortInfoArray()
+ {
+ for ( USHORT nSort = 0; nSort < nUsedSorts; nSort++ )
+ {
+ ScSortInfo** ppInfo = pppInfo[nSort];
+ for ( SCSIZE j = 0; j < nCount; j++ )
+ delete ppInfo[j];
+ delete [] ppInfo;
+ }
+ }
+ ScSortInfo* Get( USHORT nSort, SCCOLROW nInd )
+ { return (pppInfo[nSort])[ nInd - nStart ]; }
+ void Swap( SCCOLROW nInd1, SCCOLROW nInd2 )
+ {
+ SCSIZE n1 = static_cast<SCSIZE>(nInd1 - nStart);
+ SCSIZE n2 = static_cast<SCSIZE>(nInd2 - nStart);
+ for ( USHORT nSort = 0; nSort < nUsedSorts; nSort++ )
+ {
+ ScSortInfo** ppInfo = pppInfo[nSort];
+ ScSortInfo* pTmp = ppInfo[n1];
+ ppInfo[n1] = ppInfo[n2];
+ ppInfo[n2] = pTmp;
+ }
+ }
+ USHORT GetUsedSorts() { return nUsedSorts; }
+ ScSortInfo** GetFirstArray() { return pppInfo[0]; }
+ SCCOLROW GetStart() { return nStart; }
+ SCSIZE GetCount() { return nCount; }
+};
+
+ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
+{
+ USHORT nUsedSorts = 1;
+ while ( nUsedSorts < nMaxSorts && aSortParam.bDoSort[nUsedSorts] )
+ nUsedSorts++;
+ ScSortInfoArray* pArray = new ScSortInfoArray( nUsedSorts, nInd1, nInd2 );
+ if ( aSortParam.bByRow )
+ {
+ for ( USHORT nSort = 0; nSort < nUsedSorts; nSort++ )
+ {
+ SCCOL nCol = static_cast<SCCOL>(aSortParam.nField[nSort]);
+ ScColumn* pCol = &aCol[nCol];
+ for ( SCROW nRow = nInd1; nRow <= nInd2; nRow++ )
+ {
+//2do: FillSortInfo an ScColumn und Array abklappern statt Search in GetCell
+ ScSortInfo* pInfo = pArray->Get( nSort, nRow );
+ pInfo->pCell = pCol->GetCell( nRow );
+ pInfo->nOrg = nRow;
+ }
+ }
+ }
+ else
+ {
+ for ( USHORT nSort = 0; nSort < nUsedSorts; nSort++ )
+ {
+ SCROW nRow = aSortParam.nField[nSort];
+ for ( SCCOL nCol = static_cast<SCCOL>(nInd1);
+ nCol <= static_cast<SCCOL>(nInd2); nCol++ )
+ {
+ ScSortInfo* pInfo = pArray->Get( nSort, nCol );
+ pInfo->pCell = GetCell( nCol, nRow );
+ pInfo->nOrg = nCol;
+ }
+ }
+ }
+ return pArray;
+}
+
+
+BOOL ScTable::IsSortCollatorGlobal() const
+{
+ return pSortCollator == ScGlobal::GetCollator() ||
+ pSortCollator == ScGlobal::GetCaseCollator();
+}
+
+
+void ScTable::InitSortCollator( const ScSortParam& rPar )
+{
+ if ( rPar.aCollatorLocale.Language.getLength() )
+ {
+ if ( !pSortCollator || IsSortCollatorGlobal() )
+ pSortCollator = new CollatorWrapper( pDocument->GetServiceManager() );
+ pSortCollator->loadCollatorAlgorithm( rPar.aCollatorAlgorithm,
+ rPar.aCollatorLocale, (rPar.bCaseSens ? 0 : SC_COLLATOR_IGNORES) );
+ }
+ else
+ { // SYSTEM
+ DestroySortCollator();
+ pSortCollator = (rPar.bCaseSens ? ScGlobal::GetCaseCollator() :
+ ScGlobal::GetCollator());
+ }
+}
+
+
+void ScTable::DestroySortCollator()
+{
+ if ( pSortCollator )
+ {
+ if ( !IsSortCollatorGlobal() )
+ delete pSortCollator;
+ pSortCollator = NULL;
+ }
+}
+
+
+void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress& rProgress )
+{
+ BOOL bByRow = aSortParam.bByRow;
+ SCSIZE nCount = pArray->GetCount();
+ SCCOLROW nStart = pArray->GetStart();
+ ScSortInfo** ppInfo = pArray->GetFirstArray();
+ ::std::vector<ScSortInfo*> aTable(nCount);
+ SCSIZE nPos;
+ for ( nPos = 0; nPos < nCount; nPos++ )
+ aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
+
+ SCCOLROW nDest = nStart;
+ for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
+ {
+ SCCOLROW nOrg = ppInfo[nPos]->nOrg;
+ if ( nDest != nOrg )
+ {
+ if ( bByRow )
+ SwapRow( nDest, nOrg );
+ else
+ SwapCol( static_cast<SCCOL>(nDest), static_cast<SCCOL>(nOrg) );
+ // neue Position des weggeswapten eintragen
+ ScSortInfo* p = ppInfo[nPos];
+ p->nOrg = nDest;
+ ::std::swap(p, aTable[nDest-nStart]);
+ p->nOrg = nOrg;
+ ::std::swap(p, aTable[nOrg-nStart]);
+ DBG_ASSERT( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" );
+ }
+ rProgress.SetStateOnPercent( nPos );
+ }
+}
+
+short ScTable::CompareCell( USHORT nSort,
+ ScBaseCell* pCell1, SCCOL nCell1Col, SCROW nCell1Row,
+ ScBaseCell* pCell2, SCCOL nCell2Col, SCROW nCell2Row )
+{
+ short nRes = 0;
+
+ CellType eType1 = CELLTYPE_NONE, eType2 = CELLTYPE_NONE;
+ if (pCell1)
+ {
+ eType1 = pCell1->GetCellType();
+ if (eType1 == CELLTYPE_NOTE)
+ pCell1 = NULL;
+ }
+ if (pCell2)
+ {
+ eType2 = pCell2->GetCellType();
+ if (eType2 == CELLTYPE_NOTE)
+ pCell2 = NULL;
+ }
+
+ if (pCell1)
+ {
+ if (pCell2)
+ {
+ BOOL bStr1 = ( eType1 != CELLTYPE_VALUE );
+ if ( eType1 == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell1)->IsValue() )
+ bStr1 = FALSE;
+ BOOL bStr2 = ( eType2 != CELLTYPE_VALUE );
+ if ( eType2 == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell2)->IsValue() )
+ bStr2 = FALSE;
+
+ if ( bStr1 && bStr2 ) // nur Strings untereinander als String vergleichen!
+ {
+ String aStr1;
+ String aStr2;
+ if (eType1 == CELLTYPE_STRING)
+ ((ScStringCell*)pCell1)->GetString(aStr1);
+ else
+ GetString(nCell1Col, nCell1Row, aStr1);
+ if (eType2 == CELLTYPE_STRING)
+ ((ScStringCell*)pCell2)->GetString(aStr2);
+ else
+ GetString(nCell2Col, nCell2Row, aStr2);
+ BOOL bUserDef = aSortParam.bUserDef;
+ if (bUserDef)
+ {
+ ScUserListData* pData =
+ (ScUserListData*)(ScGlobal::GetUserList()->At(
+ aSortParam.nUserIndex));
+ if (pData)
+ {
+ if ( aSortParam.bCaseSens )
+ nRes = sal::static_int_cast<short>( pData->Compare(aStr1, aStr2) );
+ else
+ nRes = sal::static_int_cast<short>( pData->ICompare(aStr1, aStr2) );
+ }
+ else
+ bUserDef = FALSE;
+
+ }
+ if (!bUserDef)
+ nRes = (short) pSortCollator->compareString( aStr1, aStr2 );
+ }
+ else if ( bStr1 ) // String <-> Zahl
+ nRes = 1; // Zahl vorne
+ else if ( bStr2 ) // Zahl <-> String
+ nRes = -1; // Zahl vorne
+ else // Zahlen untereinander
+ {
+ double nVal1;
+ double nVal2;
+ if (eType1 == CELLTYPE_VALUE)
+ nVal1 = ((ScValueCell*)pCell1)->GetValue();
+ else if (eType1 == CELLTYPE_FORMULA)
+ nVal1 = ((ScFormulaCell*)pCell1)->GetValue();
+ else
+ nVal1 = 0;
+ if (eType2 == CELLTYPE_VALUE)
+ nVal2 = ((ScValueCell*)pCell2)->GetValue();
+ else if (eType2 == CELLTYPE_FORMULA)
+ nVal2 = ((ScFormulaCell*)pCell2)->GetValue();
+ else
+ nVal2 = 0;
+ if (nVal1 < nVal2)
+ nRes = -1;
+ else if (nVal1 > nVal2)
+ nRes = 1;
+ }
+ if ( !aSortParam.bAscending[nSort] )
+ nRes = -nRes;
+ }
+ else
+ nRes = -1;
+ }
+ else
+ {
+ if ( pCell2 )
+ nRes = 1;
+ else
+ nRes = 0; // beide leer
+ }
+ return nRes;
+}
+
+short ScTable::Compare( ScSortInfoArray* pArray, SCCOLROW nIndex1, SCCOLROW nIndex2 )
+{
+ short nRes;
+ USHORT nSort = 0;
+ do
+ {
+ ScSortInfo* pInfo1 = pArray->Get( nSort, nIndex1 );
+ ScSortInfo* pInfo2 = pArray->Get( nSort, nIndex2 );
+ if ( aSortParam.bByRow )
+ nRes = CompareCell( nSort,
+ pInfo1->pCell, static_cast<SCCOL>(aSortParam.nField[nSort]), pInfo1->nOrg,
+ pInfo2->pCell, static_cast<SCCOL>(aSortParam.nField[nSort]), pInfo2->nOrg );
+ else
+ nRes = CompareCell( nSort,
+ pInfo1->pCell, static_cast<SCCOL>(pInfo1->nOrg), aSortParam.nField[nSort],
+ pInfo2->pCell, static_cast<SCCOL>(pInfo2->nOrg), aSortParam.nField[nSort] );
+ } while ( nRes == 0 && ++nSort < pArray->GetUsedSorts() );
+ if( nRes == 0 )
+ {
+ ScSortInfo* pInfo1 = pArray->Get( 0, nIndex1 );
+ ScSortInfo* pInfo2 = pArray->Get( 0, nIndex2 );
+ if( pInfo1->nOrg < pInfo2->nOrg )
+ nRes = -1;
+ else if( pInfo1->nOrg > pInfo2->nOrg )
+ nRes = 1;
+ }
+ return nRes;
+}
+
+void ScTable::QuickSort( ScSortInfoArray* pArray, SCsCOLROW nLo, SCsCOLROW nHi )
+{
+ if ((nHi - nLo) == 1)
+ {
+ if (Compare(pArray, nLo, nHi) > 0)
+ pArray->Swap( nLo, nHi );
+ }
+ else
+ {
+ SCsCOLROW ni = nLo;
+ SCsCOLROW nj = nHi;
+ do
+ {
+ while ((ni <= nHi) && (Compare(pArray, ni, nLo)) < 0)
+ ni++;
+ while ((nj >= nLo) && (Compare(pArray, nLo, nj)) < 0)
+ nj--;
+ if (ni <= nj)
+ {
+ if (ni != nj)
+ pArray->Swap( ni, nj );
+ ni++;
+ nj--;
+ }
+ } while (ni < nj);
+ if ((nj - nLo) < (nHi - ni))
+ {
+ if (nLo < nj)
+ QuickSort(pArray, nLo, nj);
+ if (ni < nHi)
+ QuickSort(pArray, ni, nHi);
+ }
+ else
+ {
+ if (ni < nHi)
+ QuickSort(pArray, ni, nHi);
+ if (nLo < nj)
+ QuickSort(pArray, nLo, nj);
+ }
+ }
+}
+
+void ScTable::SwapCol(SCCOL nCol1, SCCOL nCol2)
+{
+ for (SCROW nRow = aSortParam.nRow1; nRow <= aSortParam.nRow2; nRow++)
+ {
+ aCol[nCol1].SwapCell(nRow, aCol[nCol2]);
+ if (aSortParam.bIncludePattern)
+ {
+ const ScPatternAttr* pPat1 = GetPattern(nCol1, nRow);
+ const ScPatternAttr* pPat2 = GetPattern(nCol2, nRow);
+ if (pPat1 != pPat2)
+ {
+ SetPattern(nCol1, nRow, *pPat2, TRUE);
+ SetPattern(nCol2, nRow, *pPat1, TRUE);
+ }
+ }
+ }
+}
+
+void ScTable::SwapRow(SCROW nRow1, SCROW nRow2)
+{
+ for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; nCol++)
+ {
+ aCol[nCol].SwapRow(nRow1, nRow2);
+ if (aSortParam.bIncludePattern)
+ {
+ const ScPatternAttr* pPat1 = GetPattern(nCol, nRow1);
+ const ScPatternAttr* pPat2 = GetPattern(nCol, nRow2);
+ if (pPat1 != pPat2)
+ {
+ SetPattern(nCol, nRow1, *pPat2, TRUE);
+ SetPattern(nCol, nRow2, *pPat1, TRUE);
+ }
+ }
+ }
+ if (bGlobalKeepQuery)
+ {
+ bool bRow1Hidden = RowHidden(nRow1);
+ bool bRow2Hidden = RowHidden(nRow2);
+ SetRowHidden(nRow1, nRow1, bRow2Hidden);
+ SetRowHidden(nRow2, nRow2, bRow1Hidden);
+
+ bool bRow1Filtered = RowFiltered(nRow1);
+ bool bRow2Filtered = RowFiltered(nRow2);
+ SetRowFiltered(nRow1, nRow1, bRow2Filtered);
+ SetRowFiltered(nRow2, nRow2, bRow1Filtered);
+ }
+}
+
+short ScTable::Compare(SCCOLROW nIndex1, SCCOLROW nIndex2)
+{
+ short nRes;
+ USHORT nSort = 0;
+ if (aSortParam.bByRow)
+ {
+ do
+ {
+ SCCOL nCol = static_cast<SCCOL>(aSortParam.nField[nSort]);
+ ScBaseCell* pCell1 = aCol[nCol].GetCell( nIndex1 );
+ ScBaseCell* pCell2 = aCol[nCol].GetCell( nIndex2 );
+ nRes = CompareCell( nSort, pCell1, nCol, nIndex1, pCell2, nCol, nIndex2 );
+ } while ( nRes == 0 && ++nSort < nMaxSorts && aSortParam.bDoSort[nSort] );
+ }
+ else
+ {
+ do
+ {
+ SCROW nRow = aSortParam.nField[nSort];
+ ScBaseCell* pCell1 = aCol[nIndex1].GetCell( nRow );
+ ScBaseCell* pCell2 = aCol[nIndex2].GetCell( nRow );
+ nRes = CompareCell( nSort, pCell1, static_cast<SCCOL>(nIndex1),
+ nRow, pCell2, static_cast<SCCOL>(nIndex2), nRow );
+ } while ( nRes == 0 && ++nSort < nMaxSorts && aSortParam.bDoSort[nSort] );
+ }
+ return nRes;
+}
+
+BOOL ScTable::IsSorted( SCCOLROW nStart, SCCOLROW nEnd ) // ueber aSortParam
+{
+ for (SCCOLROW i=nStart; i<nEnd; i++)
+ {
+ if (Compare( i, i+1 ) > 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void ScTable::DecoladeRow( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2 )
+{
+ SCROW nRow;
+ SCROW nMax = nRow2 - nRow1;
+ for (SCROW i = nRow1; (i + 4) <= nRow2; i += 4)
+ {
+ nRow = rand() % nMax;
+ pArray->Swap(i, nRow1 + nRow);
+ }
+}
+
+void ScTable::Sort(const ScSortParam& rSortParam, BOOL bKeepQuery)
+{
+ aSortParam = rSortParam;
+ InitSortCollator( rSortParam );
+ bGlobalKeepQuery = bKeepQuery;
+ if (rSortParam.bByRow)
+ {
+ SCROW nLastRow = 0;
+ for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; nCol++)
+ nLastRow = Max(nLastRow, aCol[nCol].GetLastDataPos());
+ nLastRow = Min(nLastRow, aSortParam.nRow2);
+ SCROW nRow1 = (rSortParam.bHasHeader ?
+ aSortParam.nRow1 + 1 : aSortParam.nRow1);
+ if (!IsSorted(nRow1, nLastRow))
+ {
+ ScProgress aProgress( pDocument->GetDocumentShell(),
+ ScGlobal::GetRscString(STR_PROGRESS_SORTING), nLastRow - nRow1 );
+ ScSortInfoArray* pArray = CreateSortInfoArray( nRow1, nLastRow );
+ if ( nLastRow - nRow1 > 255 )
+ DecoladeRow( pArray, nRow1, nLastRow );
+ QuickSort( pArray, nRow1, nLastRow );
+ SortReorder( pArray, aProgress );
+ delete pArray;
+ // #158377# #i59745# update position of caption objects of cell notes
+ ScNoteUtil::UpdateCaptionPositions( *pDocument, ScRange( aSortParam.nCol1, nRow1, nTab, aSortParam.nCol2, nLastRow, nTab ) );
+ }
+ }
+ else
+ {
+ SCCOL nLastCol;
+ for (nLastCol = aSortParam.nCol2;
+ (nLastCol > aSortParam.nCol1) && aCol[nLastCol].IsEmptyBlock(aSortParam.nRow1, aSortParam.nRow2); nLastCol--)
+ {
+ }
+ SCCOL nCol1 = (rSortParam.bHasHeader ?
+ aSortParam.nCol1 + 1 : aSortParam.nCol1);
+ if (!IsSorted(nCol1, nLastCol))
+ {
+ ScProgress aProgress( pDocument->GetDocumentShell(),
+ ScGlobal::GetRscString(STR_PROGRESS_SORTING), nLastCol - nCol1 );
+ ScSortInfoArray* pArray = CreateSortInfoArray( nCol1, nLastCol );
+ QuickSort( pArray, nCol1, nLastCol );
+ SortReorder( pArray, aProgress );
+ delete pArray;
+ // #158377# #i59745# update position of caption objects of cell notes
+ ScNoteUtil::UpdateCaptionPositions( *pDocument, ScRange( nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab ) );
+ }
+ }
+ DestroySortCollator();
+}
+
+
+// Testen, ob beim Loeschen von Zwischenergebnissen andere Daten mit geloescht werden
+// (fuer Hinweis-Box)
+
+BOOL ScTable::TestRemoveSubTotals( const ScSubTotalParam& rParam )
+{
+ SCCOL nStartCol = rParam.nCol1;
+ SCROW nStartRow = rParam.nRow1 + 1; // Header
+ SCCOL nEndCol = rParam.nCol2;
+ SCROW nEndRow = rParam.nRow2;
+
+ SCCOL nCol;
+ SCROW nRow;
+ ScBaseCell* pCell;
+
+ BOOL bWillDelete = FALSE;
+ for ( nCol=nStartCol; nCol<=nEndCol && !bWillDelete; nCol++ )
+ {
+ ScColumnIterator aIter( &aCol[nCol],nStartRow,nEndRow );
+ while ( aIter.Next( nRow, pCell ) && !bWillDelete )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ if (((ScFormulaCell*)pCell)->IsSubTotal())
+ {
+ for (SCCOL nTestCol=0; nTestCol<=MAXCOL; nTestCol++)
+ if (nTestCol<nStartCol || nTestCol>nEndCol)
+ if (aCol[nTestCol].HasDataAt(nRow))
+ bWillDelete = TRUE;
+ }
+ }
+ }
+ return bWillDelete;
+}
+
+// alte Ergebnisse loeschen
+// rParam.nRow2 wird veraendert !
+
+void ScTable::RemoveSubTotals( ScSubTotalParam& rParam )
+{
+ SCCOL nStartCol = rParam.nCol1;
+ SCROW nStartRow = rParam.nRow1 + 1; // Header
+ SCCOL nEndCol = rParam.nCol2;
+ SCROW nEndRow = rParam.nRow2; // wird veraendert
+
+ SCCOL nCol;
+ SCROW nRow;
+ ScBaseCell* pCell;
+
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ ScColumnIterator aIter( &aCol[nCol],nStartRow,nEndRow );
+ while ( aIter.Next( nRow, pCell ) )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ if (((ScFormulaCell*)pCell)->IsSubTotal())
+ {
+ RemoveRowBreak(nRow+1, false, true);
+ pDocument->DeleteRow( 0,nTab, MAXCOL,nTab, nRow, 1 );
+ --nEndRow;
+ aIter = ScColumnIterator( &aCol[nCol],nRow,nEndRow );
+ }
+ }
+ }
+
+ rParam.nRow2 = nEndRow; // neues Ende
+}
+
+// harte Zahlenformate loeschen (fuer Ergebnisformeln)
+
+void lcl_RemoveNumberFormat( ScTable* pTab, SCCOL nCol, SCROW nRow )
+{
+ const ScPatternAttr* pPattern = pTab->GetPattern( nCol, nRow );
+ if ( pPattern->GetItemSet().GetItemState( ATTR_VALUE_FORMAT, FALSE )
+ == SFX_ITEM_SET )
+ {
+ ScPatternAttr aNewPattern( *pPattern );
+ SfxItemSet& rSet = aNewPattern.GetItemSet();
+ rSet.ClearItem( ATTR_VALUE_FORMAT );
+ rSet.ClearItem( ATTR_LANGUAGE_FORMAT );
+ pTab->SetPattern( nCol, nRow, aNewPattern, TRUE );
+ }
+}
+
+
+// at least MSC needs this at linkage level to be able to use it in a template
+typedef struct lcl_ScTable_DoSubTotals_RowEntry
+{
+ USHORT nGroupNo;
+ SCROW nSubStartRow;
+ SCROW nDestRow;
+ SCROW nFuncStart;
+ SCROW nFuncEnd;
+} RowEntry;
+
+// neue Zwischenergebnisse
+// rParam.nRow2 wird veraendert !
+
+BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam )
+{
+ SCCOL nStartCol = rParam.nCol1;
+ SCROW nStartRow = rParam.nRow1 + 1; // Header
+ SCCOL nEndCol = rParam.nCol2;
+ SCROW nEndRow = rParam.nRow2; // wird veraendert
+ USHORT i;
+
+ // Leerzeilen am Ende weglassen,
+ // damit alle Ueberlaeufe (MAXROW) bei InsertRow gefunden werden (#35180#)
+ // Wenn sortiert wurde, sind alle Leerzeilen am Ende.
+ SCSIZE nEmpty = GetEmptyLinesInBlock( nStartCol, nStartRow, nEndCol, nEndRow, DIR_BOTTOM );
+ nEndRow -= nEmpty;
+
+ USHORT nLevelCount = 0; // Anzahl Gruppierungen
+ BOOL bDoThis = TRUE;
+ for (i=0; i<MAXSUBTOTAL && bDoThis; i++)
+ if (rParam.bGroupActive[i])
+ nLevelCount = i+1;
+ else
+ bDoThis = FALSE;
+
+ if (nLevelCount==0) // nichts tun
+ return TRUE;
+
+ SCCOL* nGroupCol = rParam.nField; // Spalten nach denen
+ // gruppiert wird
+
+ // #44444# Durch (leer) als eigene Kategorie muss immer auf
+ // Teilergebniszeilen aus den anderen Spalten getestet werden
+ // (frueher nur, wenn eine Spalte mehrfach vorkam)
+ BOOL bTestPrevSub = ( nLevelCount > 1 );
+
+ String aSubString;
+ String aOutString;
+
+ BOOL bIgnoreCase = !rParam.bCaseSens;
+
+ String *pCompString[MAXSUBTOTAL]; // Pointer wegen Compiler-Problemen
+ for (i=0; i<MAXSUBTOTAL; i++)
+ pCompString[i] = new String;
+
+ //! sortieren?
+
+ ScStyleSheet* pStyle = (ScStyleSheet*) pDocument->GetStyleSheetPool()->Find(
+ ScGlobal::GetRscString(STR_STYLENAME_RESULT), SFX_STYLE_FAMILY_PARA );
+
+ BOOL bSpaceLeft = TRUE; // Erfolg beim Einfuegen?
+
+ // #90279# For performance reasons collect formula entries so their
+ // references don't have to be tested for updates each time a new row is
+ // inserted
+ RowEntry aRowEntry;
+ ::std::vector< RowEntry > aRowVector;
+
+ for (USHORT nLevel=0; nLevel<=nLevelCount && bSpaceLeft; nLevel++) // incl. Gesamtergebnis
+ {
+ BOOL bTotal = ( nLevel == nLevelCount );
+ aRowEntry.nGroupNo = bTotal ? 0 : (nLevelCount-nLevel-1);
+
+ // how many results per level
+ SCCOL nResCount = rParam.nSubTotals[aRowEntry.nGroupNo];
+ // result functions
+ ScSubTotalFunc* eResFunc = rParam.pFunctions[aRowEntry.nGroupNo];
+
+ if (nResCount > 0) // sonst nur sortieren
+ {
+ for (i=0; i<=aRowEntry.nGroupNo; i++)
+ {
+ GetString( nGroupCol[i], nStartRow, aSubString );
+ if ( bIgnoreCase )
+ *pCompString[i] = ScGlobal::pCharClass->upper( aSubString );
+ else
+ *pCompString[i] = aSubString;
+ } // aSubString bleibt auf dem letzten stehen
+
+ BOOL bBlockVis = FALSE; // Gruppe eingeblendet?
+ aRowEntry.nSubStartRow = nStartRow;
+ for (SCROW nRow=nStartRow; nRow<=nEndRow+1 && bSpaceLeft; nRow++)
+ {
+ BOOL bChanged;
+ if (nRow>nEndRow)
+ bChanged = TRUE;
+ else
+ {
+ bChanged = FALSE;
+ if (!bTotal)
+ {
+ String aString;
+ for (i=0; i<=aRowEntry.nGroupNo && !bChanged; i++)
+ {
+ GetString( nGroupCol[i], nRow, aString );
+ if (bIgnoreCase)
+ ScGlobal::pCharClass->toUpper( aString );
+ // #41427# wenn sortiert, ist "leer" eine eigene Gruppe
+ // sonst sind leere Zellen unten erlaubt
+ bChanged = ( ( aString.Len() || rParam.bDoSort ) &&
+ aString != *pCompString[i] );
+ }
+ if ( bChanged && bTestPrevSub )
+ {
+ // No group change on rows that will contain subtotal formulas
+ for ( ::std::vector< RowEntry >::const_iterator
+ iEntry( aRowVector.begin());
+ iEntry != aRowVector.end(); ++iEntry)
+ {
+ if ( iEntry->nDestRow == nRow )
+ {
+ bChanged = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( bChanged )
+ {
+ aRowEntry.nDestRow = nRow;
+ aRowEntry.nFuncStart = aRowEntry.nSubStartRow;
+ aRowEntry.nFuncEnd = nRow-1;
+
+ bSpaceLeft = pDocument->InsertRow( 0, nTab, MAXCOL, nTab,
+ aRowEntry.nDestRow, 1 );
+ DBShowRow( aRowEntry.nDestRow, bBlockVis );
+ bBlockVis = FALSE;
+ if ( rParam.bPagebreak && nRow < MAXROW &&
+ aRowEntry.nSubStartRow != nStartRow && nLevel == 0)
+ SetRowBreak(aRowEntry.nSubStartRow, false, true);
+
+ if (bSpaceLeft)
+ {
+ for ( ::std::vector< RowEntry >::iterator iMove(
+ aRowVector.begin() );
+ iMove != aRowVector.end(); ++iMove)
+ {
+ if ( aRowEntry.nDestRow <= iMove->nSubStartRow )
+ ++iMove->nSubStartRow;
+ if ( aRowEntry.nDestRow <= iMove->nDestRow )
+ ++iMove->nDestRow;
+ if ( aRowEntry.nDestRow <= iMove->nFuncStart )
+ ++iMove->nFuncStart;
+ if ( aRowEntry.nDestRow <= iMove->nFuncEnd )
+ ++iMove->nFuncEnd;
+ }
+ // collect formula positions
+ aRowVector.push_back( aRowEntry );
+
+ if (bTotal) // "Gesamtergebnis"
+ aOutString = ScGlobal::GetRscString( STR_TABLE_GESAMTERGEBNIS );
+ else
+ { // " Ergebnis"
+ aOutString = aSubString;
+ if (!aOutString.Len())
+ aOutString = ScGlobal::GetRscString( STR_EMPTYDATA );
+ aOutString += ' ';
+ USHORT nStrId = STR_TABLE_ERGEBNIS;
+ if ( nResCount == 1 )
+ switch ( eResFunc[0] )
+ {
+ case SUBTOTAL_FUNC_AVE: nStrId = STR_FUN_TEXT_AVG; break;
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2: nStrId = STR_FUN_TEXT_COUNT; break;
+ case SUBTOTAL_FUNC_MAX: nStrId = STR_FUN_TEXT_MAX; break;
+ case SUBTOTAL_FUNC_MIN: nStrId = STR_FUN_TEXT_MIN; break;
+ case SUBTOTAL_FUNC_PROD: nStrId = STR_FUN_TEXT_PRODUCT; break;
+ case SUBTOTAL_FUNC_STD:
+ case SUBTOTAL_FUNC_STDP: nStrId = STR_FUN_TEXT_STDDEV; break;
+ case SUBTOTAL_FUNC_SUM: nStrId = STR_FUN_TEXT_SUM; break;
+ case SUBTOTAL_FUNC_VAR:
+ case SUBTOTAL_FUNC_VARP: nStrId = STR_FUN_TEXT_VAR; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ aOutString += ScGlobal::GetRscString( nStrId );
+ }
+ SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString );
+ ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, *pStyle );
+
+ ++nRow;
+ ++nEndRow;
+ aRowEntry.nSubStartRow = nRow;
+ for (i=0; i<=aRowEntry.nGroupNo; i++)
+ {
+ GetString( nGroupCol[i], nRow, aSubString );
+ if ( bIgnoreCase )
+ *pCompString[i] = ScGlobal::pCharClass->upper( aSubString );
+ else
+ *pCompString[i] = aSubString;
+ }
+ }
+ }
+ bBlockVis = !RowFiltered(nRow);
+ }
+ }
+ else
+ {
+// DBG_ERROR( "nSubTotals==0 bei DoSubTotals" );
+ }
+ }
+
+ // now insert the formulas
+ ScComplexRefData aRef;
+ aRef.InitFlags();
+ aRef.Ref1.nTab = nTab;
+ aRef.Ref2.nTab = nTab;
+ for ( ::std::vector< RowEntry >::const_iterator iEntry( aRowVector.begin());
+ iEntry != aRowVector.end(); ++iEntry)
+ {
+ SCCOL nResCount = rParam.nSubTotals[iEntry->nGroupNo];
+ SCCOL* nResCols = rParam.pSubTotals[iEntry->nGroupNo];
+ ScSubTotalFunc* eResFunc = rParam.pFunctions[iEntry->nGroupNo];
+ for ( SCCOL nResult=0; nResult < nResCount; ++nResult )
+ {
+ aRef.Ref1.nCol = nResCols[nResult];
+ aRef.Ref1.nRow = iEntry->nFuncStart;
+ aRef.Ref2.nCol = nResCols[nResult];
+ aRef.Ref2.nRow = iEntry->nFuncEnd;
+
+ ScTokenArray aArr;
+ aArr.AddOpCode( ocSubTotal );
+ aArr.AddOpCode( ocOpen );
+ aArr.AddDouble( (double) eResFunc[nResult] );
+ aArr.AddOpCode( ocSep );
+ aArr.AddDoubleReference( aRef );
+ aArr.AddOpCode( ocClose );
+ aArr.AddOpCode( ocStop );
+ ScBaseCell* pCell = new ScFormulaCell( pDocument, ScAddress(
+ nResCols[nResult], iEntry->nDestRow, nTab), &aArr );
+ PutCell( nResCols[nResult], iEntry->nDestRow, pCell );
+
+ if ( nResCols[nResult] != nGroupCol[iEntry->nGroupNo] )
+ {
+ ApplyStyle( nResCols[nResult], iEntry->nDestRow, *pStyle );
+
+ // Zahlformat loeschen
+ lcl_RemoveNumberFormat( this, nResCols[nResult], iEntry->nDestRow );
+ }
+ }
+
+ }
+
+ //! je nach Einstellung Zwischensummen-Zeilen nach oben verschieben ?
+
+ //! Outlines direkt erzeugen?
+
+ if (bSpaceLeft)
+ DoAutoOutline( nStartCol, nStartRow, nEndCol, nEndRow );
+
+ for (i=0; i<MAXSUBTOTAL; i++)
+ delete pCompString[i];
+
+ rParam.nRow2 = nEndRow; // neues Ende
+ return bSpaceLeft;
+}
+
+
+BOOL ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
+ BOOL* pSpecial /* =NULL */ , ScBaseCell* pCell /* =NULL */ ,
+ BOOL* pbTestEqualCondition /* = NULL */ )
+{
+ if (!rParam.GetEntry(0).bDoQuery)
+ return TRUE;
+
+ //---------------------------------------------------------------
+
+ const SCSIZE nFixedBools = 32;
+ BOOL aBool[nFixedBools];
+ BOOL aTest[nFixedBools];
+ SCSIZE nEntryCount = rParam.GetEntryCount();
+ BOOL* pPasst = ( nEntryCount <= nFixedBools ? &aBool[0] : new BOOL[nEntryCount] );
+ BOOL* pTest = ( nEntryCount <= nFixedBools ? &aTest[0] : new BOOL[nEntryCount] );
+
+ long nPos = -1;
+ SCSIZE i = 0;
+ BOOL bMatchWholeCell = pDocument->GetDocOptions().IsMatchWholeCell();
+ CollatorWrapper* pCollator = (rParam.bCaseSens ? ScGlobal::GetCaseCollator() :
+ ScGlobal::GetCollator());
+ ::utl::TransliterationWrapper* pTransliteration = (rParam.bCaseSens ?
+ ScGlobal::GetCaseTransliteration() : ScGlobal::GetpTransliteration());
+
+ while ( (i < nEntryCount) && rParam.GetEntry(i).bDoQuery )
+ {
+ ScQueryEntry& rEntry = rParam.GetEntry(i);
+ // we can only handle one single direct query
+ if ( !pCell || i > 0 )
+ pCell = GetCell( static_cast<SCCOL>(rEntry.nField), nRow );
+
+ BOOL bOk = FALSE;
+ BOOL bTestEqual = FALSE;
+
+ if ( pSpecial && pSpecial[i] )
+ {
+ if (rEntry.nVal == SC_EMPTYFIELDS)
+ bOk = !( aCol[rEntry.nField].HasDataAt( nRow ) );
+ else // if (rEntry.nVal == SC_NONEMPTYFIELDS)
+ bOk = aCol[rEntry.nField].HasDataAt( nRow );
+ }
+ else if ( !rEntry.bQueryByString && (pCell ? pCell->HasValueData() :
+ HasValueData( static_cast<SCCOL>(rEntry.nField), nRow)))
+ { // by Value
+ double nCellVal;
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ nCellVal = ((ScValueCell*)pCell)->GetValue();
+ break;
+ case CELLTYPE_FORMULA :
+ nCellVal = ((ScFormulaCell*)pCell)->GetValue();
+ break;
+ default:
+ nCellVal = 0.0;
+ }
+
+ }
+ else
+ nCellVal = GetValue( static_cast<SCCOL>(rEntry.nField), nRow );
+
+ /* NOTE: lcl_PrepareQuery() prepares a filter query such that if a
+ * date+time format was queried rEntry.bQueryByDate is not set. In
+ * case other queries wanted to use this mechanism they should do
+ * the same, in other words only if rEntry.nVal is an integer value
+ * rEntry.bQueryByDate should be true and the time fraction be
+ * stripped here. */
+ if (rEntry.bQueryByDate)
+ {
+ sal_uInt32 nNumFmt = GetNumberFormat(static_cast<SCCOL>(rEntry.nField), nRow);
+ const SvNumberformat* pEntry = pDocument->GetFormatTable()->GetEntry(nNumFmt);
+ if (pEntry)
+ {
+ short nNumFmtType = pEntry->GetType();
+ /* NOTE: Omitting the check for absence of
+ * NUMBERFORMAT_TIME would include also date+time formatted
+ * values of the same day. That may be desired in some
+ * cases, querying all time values of a day, but confusing
+ * in other cases. A user can always setup a standard
+ * filter query for x >= date AND x < date+1 */
+ if ((nNumFmtType & NUMBERFORMAT_DATE) && !(nNumFmtType & NUMBERFORMAT_TIME))
+ {
+ // The format is of date type. Strip off the time
+ // element.
+ nCellVal = ::rtl::math::approxFloor(nCellVal);
+ }
+ }
+ }
+
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL :
+ bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_LESS :
+ bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_GREATER :
+ bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_LESS_EQUAL :
+ bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ if ( bOk && pbTestEqualCondition )
+ bTestEqual = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_GREATER_EQUAL :
+ bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ if ( bOk && pbTestEqualCondition )
+ bTestEqual = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ case SC_NOT_EQUAL :
+ bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ 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)
+ {
+ ULONG nFormat = GetNumberFormat( static_cast<SCCOL>(rEntry.nField), nRow );
+ ScCellFormat::GetInputString( pCell, nFormat, aCellStr, *(pDocument->GetFormatTable()) );
+ }
+ }
+ else
+ GetInputString( static_cast<SCCOL>(rEntry.nField), nRow, aCellStr );
+
+ BOOL bRealRegExp = (rParam.bRegExp && ((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)));
+ BOOL bTestRegExp = (pbTestEqualCondition && rParam.bRegExp
+ && ((rEntry.eOp == SC_LESS_EQUAL)
+ || (rEntry.eOp == SC_GREATER_EQUAL)));
+ if ( bRealRegExp || bTestRegExp )
+ {
+ xub_StrLen nStart = 0;
+ xub_StrLen nEnd = aCellStr.Len();
+
+ // 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 )
+ 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
+ || 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 )
+ {
+ // #i18374# When used from functions (match, countif, sumif, vlookup, hlookup, lookup),
+ // 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
+ {
+ String aCell( pTransliteration->transliterate(
+ aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(),
+ NULL ) );
+ String aQuer( pTransliteration->transliterate(
+ *rEntry.pStr, ScGlobal::eLnge, 0, rEntry.pStr->Len(),
+ 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
+ }
+ }
+ }
+ }
+ else
+ { // use collator here because data was probably sorted
+ sal_Int32 nCompare = pCollator->compareString(
+ aCellStr, *rEntry.pStr );
+ switch (rEntry.eOp)
+ {
+ case SC_LESS :
+ bOk = (nCompare < 0);
+ break;
+ case SC_GREATER :
+ bOk = (nCompare > 0);
+ break;
+ case SC_LESS_EQUAL :
+ bOk = (nCompare <= 0);
+ if ( bOk && pbTestEqualCondition && !bTestEqual )
+ bTestEqual = (nCompare == 0);
+ break;
+ case SC_GREATER_EQUAL :
+ bOk = (nCompare >= 0);
+ if ( bOk && pbTestEqualCondition && !bTestEqual )
+ bTestEqual = (nCompare == 0);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ }
+ else if (rParam.bMixedComparison)
+ {
+ if (rEntry.bQueryByString &&
+ (rEntry.eOp == SC_LESS || rEntry.eOp == SC_LESS_EQUAL) &&
+ (pCell ? pCell->HasValueData() :
+ HasValueData( static_cast<SCCOL>(rEntry.nField), nRow)))
+ {
+ bOk = TRUE;
+ }
+ else if (!rEntry.bQueryByString &&
+ (rEntry.eOp == SC_GREATER || rEntry.eOp == SC_GREATER_EQUAL) &&
+ (pCell ? pCell->HasStringData() :
+ HasStringData( static_cast<SCCOL>(rEntry.nField), nRow)))
+ {
+ bOk = TRUE;
+ }
+ }
+
+ if (nPos == -1)
+ {
+ nPos++;
+ pPasst[nPos] = bOk;
+ pTest[nPos] = bTestEqual;
+ }
+ else
+ {
+ if (rEntry.eConnect == SC_AND)
+ {
+ pPasst[nPos] = pPasst[nPos] && bOk;
+ pTest[nPos] = pTest[nPos] && bTestEqual;
+ }
+ else
+ {
+ nPos++;
+ pPasst[nPos] = bOk;
+ pTest[nPos] = bTestEqual;
+ }
+ }
+ i++;
+ }
+
+ for ( long j=1; j <= nPos; j++ )
+ {
+ pPasst[0] = pPasst[0] || pPasst[j];
+ pTest[0] = pTest[0] || pTest[j];
+ }
+
+ BOOL bRet = pPasst[0];
+ if ( pPasst != &aBool[0] )
+ delete [] pPasst;
+ if ( pbTestEqualCondition )
+ *pbTestEqualCondition = pTest[0];
+ if ( pTest != &aTest[0] )
+ delete [] pTest;
+
+ return bRet;
+}
+
+void ScTable::TopTenQuery( ScQueryParam& rParam )
+{
+ BOOL bSortCollatorInitialized = FALSE;
+ SCSIZE nEntryCount = rParam.GetEntryCount();
+ SCROW nRow1 = (rParam.bHasHeader ? rParam.nRow1 + 1 : rParam.nRow1);
+ SCSIZE nCount = static_cast<SCSIZE>(rParam.nRow2 - nRow1 + 1);
+ for ( SCSIZE i=0; (i<nEntryCount) && (rParam.GetEntry(i).bDoQuery); i++ )
+ {
+ ScQueryEntry& rEntry = rParam.GetEntry(i);
+ switch ( rEntry.eOp )
+ {
+ case SC_TOPVAL:
+ case SC_BOTVAL:
+ case SC_TOPPERC:
+ case SC_BOTPERC:
+ {
+ ScSortParam aLocalSortParam( rParam, static_cast<SCCOL>(rEntry.nField) );
+ aSortParam = aLocalSortParam; // used in CreateSortInfoArray, Compare
+ if ( !bSortCollatorInitialized )
+ {
+ bSortCollatorInitialized = TRUE;
+ InitSortCollator( aLocalSortParam );
+ }
+ ScSortInfoArray* pArray = CreateSortInfoArray( nRow1, rParam.nRow2 );
+ DecoladeRow( pArray, nRow1, rParam.nRow2 );
+ QuickSort( pArray, nRow1, rParam.nRow2 );
+ ScSortInfo** ppInfo = pArray->GetFirstArray();
+ SCSIZE nValidCount = nCount;
+ // keine Note-/Leerzellen zaehlen, sind ans Ende sortiert
+ while ( nValidCount > 0 && ( ppInfo[nValidCount-1]->pCell == NULL ||
+ ppInfo[nValidCount-1]->pCell->GetCellType() == CELLTYPE_NOTE ) )
+ nValidCount--;
+ // keine Strings zaehlen, sind zwischen Value und Leer
+ while ( nValidCount > 0
+ && ppInfo[nValidCount-1]->pCell->HasStringData() )
+ nValidCount--;
+ if ( nValidCount > 0 )
+ {
+ if ( rEntry.bQueryByString )
+ { // dat wird nix
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = 10; // 10 bzw. 10%
+ }
+ SCSIZE nVal = (rEntry.nVal >= 1 ? static_cast<SCSIZE>(rEntry.nVal) : 1);
+ SCSIZE nOffset = 0;
+ switch ( rEntry.eOp )
+ {
+ case SC_TOPVAL:
+ {
+ rEntry.eOp = SC_GREATER_EQUAL;
+ if ( nVal > nValidCount )
+ nVal = nValidCount;
+ nOffset = nValidCount - nVal; // 1 <= nVal <= nValidCount
+ }
+ break;
+ case SC_BOTVAL:
+ {
+ rEntry.eOp = SC_LESS_EQUAL;
+ if ( nVal > nValidCount )
+ nVal = nValidCount;
+ nOffset = nVal - 1; // 1 <= nVal <= nValidCount
+ }
+ break;
+ case SC_TOPPERC:
+ {
+ rEntry.eOp = SC_GREATER_EQUAL;
+ if ( nVal > 100 )
+ nVal = 100;
+ nOffset = nValidCount - (nValidCount * nVal / 100);
+ if ( nOffset >= nValidCount )
+ nOffset = nValidCount - 1;
+ }
+ break;
+ case SC_BOTPERC:
+ {
+ rEntry.eOp = SC_LESS_EQUAL;
+ if ( nVal > 100 )
+ nVal = 100;
+ nOffset = (nValidCount * nVal / 100);
+ if ( nOffset >= nValidCount )
+ nOffset = nValidCount - 1;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScBaseCell* pCell = ppInfo[nOffset]->pCell;
+ if ( pCell->HasValueData() )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_VALUE )
+ rEntry.nVal = ((ScValueCell*)pCell)->GetValue();
+ else
+ rEntry.nVal = ((ScFormulaCell*)pCell)->GetValue();
+ }
+ else
+ {
+ DBG_ERRORFILE( "TopTenQuery: pCell kein ValueData" );
+ rEntry.eOp = SC_GREATER_EQUAL;
+ rEntry.nVal = 0;
+ }
+ }
+ else
+ {
+ rEntry.eOp = SC_GREATER_EQUAL;
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = 0;
+ }
+ delete pArray;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ if ( bSortCollatorInitialized )
+ DestroySortCollator();
+}
+
+static void lcl_PrepareQuery( ScDocument* pDoc, ScTable* pTab, ScQueryParam& rParam, BOOL* pSpecial )
+{
+ bool bTopTen = false;
+ SCSIZE nEntryCount = rParam.GetEntryCount();
+
+ for ( SCSIZE i = 0; i < nEntryCount; ++i )
+ {
+ pSpecial[i] = FALSE;
+ ScQueryEntry& rEntry = rParam.GetEntry(i);
+ if ( rEntry.bDoQuery )
+ {
+ if ( rEntry.bQueryByString )
+ {
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString = !( pDoc->GetFormatTable()->
+ IsNumberFormat( *rEntry.pStr, nIndex, rEntry.nVal ) );
+ if (rEntry.bQueryByDate)
+ {
+ if (!rEntry.bQueryByString && ((nIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0))
+ {
+ const SvNumberformat* pEntry = pDoc->GetFormatTable()->GetEntry(nIndex);
+ if (pEntry)
+ {
+ short nNumFmtType = pEntry->GetType();
+ if (!((nNumFmtType & NUMBERFORMAT_DATE) && !(nNumFmtType & NUMBERFORMAT_TIME)))
+ rEntry.bQueryByDate = false; // not a date only
+ }
+ else
+ rEntry.bQueryByDate = false; // what the ... not a date
+ }
+ else
+ rEntry.bQueryByDate = false; // not a date
+ }
+ }
+ else
+ {
+ // #58736# call from UNO or second call from autofilter
+ if ( rEntry.nVal == SC_EMPTYFIELDS || rEntry.nVal == SC_NONEMPTYFIELDS )
+ {
+ pSpecial[i] = TRUE;
+ }
+ }
+ if ( !bTopTen )
+ {
+ switch ( rEntry.eOp )
+ {
+ case SC_TOPVAL:
+ case SC_BOTVAL:
+ case SC_TOPPERC:
+ case SC_BOTPERC:
+ {
+ bTopTen = true;
+ }
+ break;
+ default:
+ {
+ }
+ }
+ }
+ }
+ }
+
+ if ( bTopTen )
+ {
+ pTab->TopTenQuery( rParam );
+ }
+}
+
+SCSIZE ScTable::Query(ScQueryParam& rParamOrg, BOOL bKeepSub)
+{
+ ScQueryParam aParam( rParamOrg );
+ ScStrCollection aScStrCollection;
+ StrData* pStrData = NULL;
+
+ BOOL bStarted = FALSE;
+ BOOL bOldResult = TRUE;
+ SCROW nOldStart = 0;
+ SCROW nOldEnd = 0;
+
+ SCSIZE nCount = 0;
+ SCROW nOutRow = 0;
+ SCROW nHeader = aParam.bHasHeader ? 1 : 0;
+
+ SCSIZE nEntryCount = aParam.GetEntryCount();
+ BOOL* pSpecial = new BOOL[nEntryCount];
+ lcl_PrepareQuery( pDocument, this, aParam, pSpecial );
+
+ if (!aParam.bInplace)
+ {
+ nOutRow = aParam.nDestRow + nHeader;
+ if (nHeader > 0)
+ CopyData( aParam.nCol1, aParam.nRow1, aParam.nCol2, aParam.nRow1,
+ aParam.nDestCol, aParam.nDestRow, aParam.nDestTab );
+ }
+
+ if (aParam.bInplace)
+ IncRecalcLevel(); // #i116164# once for all entries
+
+ // #i116164# If there are no drawing objects within the area, call SetRowHidden/SetRowFiltered for all rows at the end
+ std::vector<ScShowRowsEntry> aEntries;
+ ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+ bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, aParam.nRow1 + nHeader, aParam.nRow2, false );
+
+ for (SCROW j=aParam.nRow1 + nHeader; j<=aParam.nRow2; j++)
+ {
+ BOOL bResult; // Filterergebnis
+ BOOL bValid = ValidQuery(j, aParam, pSpecial);
+ if (!bValid && bKeepSub) // Subtotals stehenlassen
+ {
+ for (SCCOL nCol=aParam.nCol1; nCol<=aParam.nCol2 && !bValid; nCol++)
+ {
+ ScBaseCell* pCell;
+ pCell = GetCell( nCol, j );
+ if ( pCell )
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ if (((ScFormulaCell*)pCell)->IsSubTotal())
+ if (RefVisible((ScFormulaCell*)pCell))
+ bValid = TRUE;
+ }
+ }
+ if (bValid)
+ {
+ if (aParam.bDuplicate)
+ bResult = TRUE;
+ else
+ {
+ String aStr;
+ for (SCCOL k=aParam.nCol1; k <= aParam.nCol2; k++)
+ {
+ String aCellStr;
+ GetString(k, j, aCellStr);
+ aStr += aCellStr;
+ aStr += (sal_Unicode)1;
+ }
+ pStrData = new StrData(aStr);
+
+ BOOL bIsUnique = TRUE;
+ if (pStrData)
+ bIsUnique = aScStrCollection.Insert(pStrData);
+ if (bIsUnique)
+ bResult = TRUE;
+ else
+ {
+ delete pStrData;
+ bResult = FALSE;
+ }
+ }
+ }
+ else
+ bResult = FALSE;
+
+ if (aParam.bInplace)
+ {
+ if (bResult == bOldResult && bStarted)
+ nOldEnd = j;
+ else
+ {
+ if (bStarted)
+ {
+ DBShowRows(nOldStart,nOldEnd, bOldResult, bHasObjects);
+ if (!bHasObjects)
+ aEntries.push_back(ScShowRowsEntry(nOldStart, nOldEnd, bOldResult));
+ }
+ nOldStart = nOldEnd = j;
+ bOldResult = bResult;
+ }
+ bStarted = TRUE;
+ }
+ else
+ {
+ if (bResult)
+ {
+ CopyData( aParam.nCol1,j, aParam.nCol2,j, aParam.nDestCol,nOutRow,aParam.nDestTab );
+ ++nOutRow;
+ }
+ }
+ if (bResult)
+ ++nCount;
+ }
+
+ if (aParam.bInplace && bStarted)
+ {
+ DBShowRows(nOldStart,nOldEnd, bOldResult, bHasObjects);
+ if (!bHasObjects)
+ aEntries.push_back(ScShowRowsEntry(nOldStart, nOldEnd, bOldResult));
+ }
+
+ // #i116164# execute the collected SetRowHidden/SetRowFiltered calls
+ if (!bHasObjects)
+ {
+ std::vector<ScShowRowsEntry>::const_iterator aEnd = aEntries.end();
+ std::vector<ScShowRowsEntry>::const_iterator aIter = aEntries.begin();
+ if ( aIter != aEnd )
+ {
+ // do only one HeightChanged call with the final difference in heights
+ long nOldHeight = 0;
+ if ( pDrawLayer )
+ nOldHeight = static_cast<long>(GetRowHeight(aParam.nRow1 + nHeader, aParam.nRow2));
+
+ // clear the range first instead of many changes in the middle of the filled array
+ SetRowHidden(aParam.nRow1 + nHeader, aParam.nRow2, false);
+ SetRowFiltered(aParam.nRow1 + nHeader, aParam.nRow2, false);
+
+ // insert from back, in case the filter range is large
+ mpHiddenRows->setInsertFromBack(true);
+ mpFilteredRows->setInsertFromBack(true);
+
+ while (aIter != aEnd)
+ {
+ if (!aIter->mbShow)
+ {
+ SCROW nStartRow = aIter->mnRow1;
+ SCROW nEndRow = aIter->mnRow2;
+ SetRowHidden(nStartRow, nEndRow, true);
+ SetRowFiltered(nStartRow, nEndRow, true);
+ }
+ ++aIter;
+ }
+
+ mpHiddenRows->setInsertFromBack(false);
+ mpFilteredRows->setInsertFromBack(false);
+
+ if ( pDrawLayer )
+ {
+ // if there are no objects in the filtered range, a single HeightChanged call is enough
+ long nNewHeight = static_cast<long>(GetRowHeight(aParam.nRow1 + nHeader, aParam.nRow2));
+ pDrawLayer->HeightChanged( nTab, aParam.nRow1 + nHeader, nNewHeight - nOldHeight );
+ }
+ }
+ }
+
+ if (aParam.bInplace)
+ DecRecalcLevel();
+
+ delete[] pSpecial;
+
+ return nCount;
+}
+
+BOOL ScTable::CreateExcelQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam)
+{
+ BOOL bValid = TRUE;
+ SCCOL* pFields = new SCCOL[nCol2-nCol1+1];
+ String aCellStr;
+ SCCOL nCol = nCol1;
+ DBG_ASSERT( rQueryParam.nTab != SCTAB_MAX, "rQueryParam.nTab no value, not bad but no good" );
+ SCTAB nDBTab = (rQueryParam.nTab == SCTAB_MAX ? nTab : rQueryParam.nTab);
+ SCROW nDBRow1 = rQueryParam.nRow1;
+ SCCOL nDBCol2 = rQueryParam.nCol2;
+ // Erste Zeile muessen Spaltenkoepfe sein
+ while (bValid && (nCol <= nCol2))
+ {
+ String aQueryStr;
+ GetUpperCellString(nCol, nRow1, aQueryStr);
+ BOOL bFound = FALSE;
+ SCCOL i = rQueryParam.nCol1;
+ while (!bFound && (i <= nDBCol2))
+ {
+ if ( nTab == nDBTab )
+ GetUpperCellString(i, nDBRow1, aCellStr);
+ else
+ pDocument->GetUpperCellString(i, nDBRow1, nDBTab, aCellStr);
+ bFound = (aCellStr == aQueryStr);
+ if (!bFound) i++;
+ }
+ if (bFound)
+ pFields[nCol - nCol1] = i;
+ else
+ bValid = FALSE;
+ nCol++;
+ }
+ if (bValid)
+ {
+ ULONG nVisible = 0;
+ for ( nCol=nCol1; nCol<=nCol2; nCol++ )
+ nVisible += aCol[nCol].VisibleCount( nRow1+1, nRow2 );
+
+ if ( nVisible > SCSIZE_MAX / sizeof(void*) )
+ {
+ DBG_ERROR("zu viele Filterkritierien");
+ nVisible = 0;
+ }
+
+ SCSIZE nNewEntries = nVisible;
+ rQueryParam.Resize( nNewEntries );
+
+ SCSIZE nIndex = 0;
+ SCROW nRow = nRow1 + 1;
+ while (nRow <= nRow2)
+ {
+ nCol = nCol1;
+ while (nCol <= nCol2)
+ {
+ GetInputString( nCol, nRow, aCellStr );
+ ScGlobal::pCharClass->toUpper( aCellStr );
+ if (aCellStr.Len() > 0)
+ {
+ if (nIndex < nNewEntries)
+ {
+ rQueryParam.GetEntry(nIndex).nField = pFields[nCol - nCol1];
+ rQueryParam.FillInExcelSyntax(aCellStr, nIndex);
+ nIndex++;
+ if (nIndex < nNewEntries)
+ rQueryParam.GetEntry(nIndex).eConnect = SC_AND;
+ }
+ else
+ bValid = FALSE;
+ }
+ nCol++;
+ }
+ nRow++;
+ if (nIndex < nNewEntries)
+ rQueryParam.GetEntry(nIndex).eConnect = SC_OR;
+ }
+ }
+ delete [] pFields;
+ return bValid;
+}
+
+BOOL ScTable::CreateStarQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam)
+{
+ // A valid StarQuery must be at least 4 columns wide. To be precise it
+ // should be exactly 4 columns ...
+ // Additionally, if this wasn't checked, a formula pointing to a valid 1-3
+ // column Excel style query range immediately left to itself would result
+ // in a circular reference when the field name or operator or value (first
+ // to third query range column) is obtained (#i58354#). Furthermore, if the
+ // range wasn't sufficiently specified data changes wouldn't flag formula
+ // cells for recalculation.
+ if (nCol2 - nCol1 < 3)
+ return FALSE;
+
+ BOOL bValid;
+ BOOL bFound;
+ String aCellStr;
+ SCSIZE nIndex = 0;
+ SCROW nRow = nRow1;
+ DBG_ASSERT( rQueryParam.nTab != SCTAB_MAX, "rQueryParam.nTab no value, not bad but no good" );
+ SCTAB nDBTab = (rQueryParam.nTab == SCTAB_MAX ? nTab : rQueryParam.nTab);
+ SCROW nDBRow1 = rQueryParam.nRow1;
+ SCCOL nDBCol2 = rQueryParam.nCol2;
+
+ SCSIZE nNewEntries = static_cast<SCSIZE>(nRow2-nRow1+1);
+ rQueryParam.Resize( nNewEntries );
+
+ do
+ {
+ ScQueryEntry& rEntry = rQueryParam.GetEntry(nIndex);
+
+ bValid = FALSE;
+ // Erste Spalte UND/ODER
+ if (nIndex > 0)
+ {
+ GetUpperCellString(nCol1, nRow, aCellStr);
+ if ( aCellStr == ScGlobal::GetRscString(STR_TABLE_UND) )
+ {
+ rEntry.eConnect = SC_AND;
+ bValid = TRUE;
+ }
+ else if ( aCellStr == ScGlobal::GetRscString(STR_TABLE_ODER) )
+ {
+ rEntry.eConnect = SC_OR;
+ bValid = TRUE;
+ }
+ }
+ // Zweite Spalte FeldName
+ if ((nIndex < 1) || bValid)
+ {
+ bFound = FALSE;
+ GetUpperCellString(nCol1 + 1, nRow, aCellStr);
+ for (SCCOL i=rQueryParam.nCol1; (i <= nDBCol2) && (!bFound); i++)
+ {
+ String aFieldStr;
+ if ( nTab == nDBTab )
+ GetUpperCellString(i, nDBRow1, aFieldStr);
+ else
+ pDocument->GetUpperCellString(i, nDBRow1, nDBTab, aFieldStr);
+ bFound = (aCellStr == aFieldStr);
+ if (bFound)
+ {
+ rEntry.nField = i;
+ bValid = TRUE;
+ }
+ else
+ bValid = FALSE;
+ }
+ }
+ // Dritte Spalte Operator =<>...
+ if (bValid)
+ {
+ bFound = FALSE;
+ GetUpperCellString(nCol1 + 2, nRow, aCellStr);
+ if (aCellStr.GetChar(0) == '<')
+ {
+ if (aCellStr.GetChar(1) == '>')
+ rEntry.eOp = SC_NOT_EQUAL;
+ else if (aCellStr.GetChar(1) == '=')
+ rEntry.eOp = SC_LESS_EQUAL;
+ else
+ rEntry.eOp = SC_LESS;
+ }
+ else if (aCellStr.GetChar(0) == '>')
+ {
+ if (aCellStr.GetChar(1) == '=')
+ rEntry.eOp = SC_GREATER_EQUAL;
+ else
+ rEntry.eOp = SC_GREATER;
+ }
+ else if (aCellStr.GetChar(0) == '=')
+ rEntry.eOp = SC_EQUAL;
+
+ }
+ // Vierte Spalte Wert
+ if (bValid)
+ {
+ GetString(nCol1 + 3, nRow, *rEntry.pStr);
+ rEntry.bDoQuery = TRUE;
+ }
+ nIndex++;
+ nRow++;
+ }
+ while (bValid && (nRow <= nRow2) /* && (nIndex < MAXQUERY) */ );
+ return bValid;
+}
+
+BOOL ScTable::CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam)
+{
+ SCSIZE i, nCount;
+ PutInOrder(nCol1, nCol2);
+ PutInOrder(nRow1, nRow2);
+
+ nCount = rQueryParam.GetEntryCount();
+ for (i=0; i < nCount; i++)
+ rQueryParam.GetEntry(i).Clear();
+
+ // Standard QueryTabelle
+ BOOL bValid = CreateStarQuery(nCol1, nRow1, nCol2, nRow2, rQueryParam);
+ // Excel QueryTabelle
+ if (!bValid)
+ bValid = CreateExcelQuery(nCol1, nRow1, nCol2, nRow2, rQueryParam);
+
+ nCount = rQueryParam.GetEntryCount();
+ if (bValid)
+ {
+ // bQueryByString muss gesetzt sein
+ for (i=0; i < nCount; i++)
+ rQueryParam.GetEntry(i).bQueryByString = TRUE;
+ }
+ else
+ {
+ // nix
+ for (i=0; i < nCount; i++)
+ rQueryParam.GetEntry(i).Clear();
+ }
+ return bValid;
+}
+
+BOOL ScTable::HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW /* nEndRow */ )
+{
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ CellType eType = GetCellType( nCol, nStartRow );
+ if (eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL ScTable::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL /* nEndCol */, SCROW nEndRow )
+{
+ for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
+ {
+ CellType eType = GetCellType( nStartCol, nRow );
+ if (eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void ScTable::GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, TypedScStrCollection& rStrings, bool& rHasDates)
+{
+ aCol[nCol].GetFilterEntries( nRow1, nRow2, rStrings, rHasDates );
+}
+
+void ScTable::GetFilteredFilterEntries(
+ SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, TypedScStrCollection& rStrings, bool& rHasDates )
+{
+ // remove the entry for this column from the query parameter
+ ScQueryParam aParam( rParam );
+ SCSIZE nEntryCount = aParam.GetEntryCount();
+ for ( SCSIZE i = 0; i < nEntryCount && aParam.GetEntry(i).bDoQuery; ++i )
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if ( rEntry.nField == nCol )
+ {
+ aParam.DeleteQuery(i);
+ break;
+ }
+ }
+ nEntryCount = aParam.GetEntryCount();
+
+ BOOL* pSpecial = new BOOL[nEntryCount];
+ lcl_PrepareQuery( pDocument, this, aParam, pSpecial );
+ bool bHasDates = false;
+ for ( SCROW j = nRow1; j <= nRow2; ++j )
+ {
+ if ( ValidQuery( j, aParam, pSpecial ) )
+ {
+ bool bThisHasDates = false;
+ aCol[nCol].GetFilterEntries( j, j, rStrings, bThisHasDates );
+ bHasDates |= bThisHasDates;
+ }
+ }
+
+ rHasDates = bHasDates;
+ delete[] pSpecial;
+}
+
+BOOL ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, TypedScStrCollection& rStrings, BOOL bLimit)
+{
+ return aCol[nCol].GetDataEntries( nRow, rStrings, bLimit );
+}
+
+SCSIZE ScTable::GetCellCount(SCCOL nCol) const
+{
+ return aCol[nCol].GetCellCount();
+}
+
+ULONG ScTable::GetCellCount() const
+{
+ ULONG nCellCount = 0;
+
+ for ( SCCOL nCol=0; nCol<=MAXCOL; nCol++ )
+ nCellCount += aCol[nCol].GetCellCount();
+
+ return nCellCount;
+}
+
+ULONG ScTable::GetWeightedCount() const
+{
+ ULONG nCellCount = 0;
+
+ for ( SCCOL nCol=0; nCol<=MAXCOL; nCol++ )
+ if ( aCol[nCol].GetCellCount() ) // GetCellCount ist inline
+ nCellCount += aCol[nCol].GetWeightedCount();
+
+ return nCellCount;
+}
+
+ULONG ScTable::GetCodeCount() const
+{
+ ULONG nCodeCount = 0;
+
+ for ( SCCOL nCol=0; nCol<=MAXCOL; nCol++ )
+ if ( aCol[nCol].GetCellCount() ) // GetCellCount ist inline
+ nCodeCount += aCol[nCol].GetCodeCount();
+
+ return nCodeCount;
+}
+
+sal_Int32 ScTable::GetMaxStringLen( SCCOL nCol, SCROW nRowStart,
+ SCROW nRowEnd, CharSet eCharSet ) const
+{
+ if ( ValidCol(nCol) )
+ return aCol[nCol].GetMaxStringLen( nRowStart, nRowEnd, eCharSet );
+ else
+ return 0;
+}
+
+xub_StrLen ScTable::GetMaxNumberStringLen(
+ sal_uInt16& nPrecision, SCCOL nCol, SCROW nRowStart, SCROW nRowEnd ) const
+{
+ if ( ValidCol(nCol) )
+ return aCol[nCol].GetMaxNumberStringLen( nPrecision, nRowStart, nRowEnd );
+ else
+ return 0;
+}
+
+void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark )
+{
+ // Cursor neben einer Markierung nicht beruecksichtigen:
+ //! nur noch MarkData uebergeben, Cursorposition ggf. hineinselektieren!!!
+ BOOL bSingle = ( rMark.IsMarked() || !rMark.IsMultiMarked() );
+
+ // Mehrfachselektion:
+
+ SCCOL nCol;
+ if ( rMark.IsMultiMarked() )
+ for (nCol=0; nCol<=MAXCOL && !rData.bError; nCol++)
+ if ( !pColFlags || !ColHidden(nCol) )
+ aCol[nCol].UpdateSelectionFunction( rMark, rData, *mpHiddenRows,
+ bSingle && ( nCol >= nStartCol && nCol <= nEndCol ),
+ nStartRow, nEndRow );
+
+ // Einfachselektion (oder Cursor) nur wenn nicht negativ (und s.o.):
+
+ if ( bSingle && !rMark.IsMarkNegative() )
+ for (nCol=nStartCol; nCol<=nEndCol && !rData.bError; nCol++)
+ if ( !pColFlags || !ColHidden(nCol) )
+ aCol[nCol].UpdateAreaFunction( rData, *mpHiddenRows, nStartRow, nEndRow );
+}
+
+void ScTable::FindConditionalFormat( ULONG nKey, ScRangeList& rList )
+{
+ SCROW nStartRow = 0, nEndRow = 0;
+ for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
+ {
+ ScAttrIterator* pIter = aCol[nCol].CreateAttrIterator( 0, MAXROW );
+ const ScPatternAttr* pPattern = pIter->Next( nStartRow, nEndRow );
+ while (pPattern)
+ {
+ if (((SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() == nKey)
+ rList.Join( ScRange(nCol,nStartRow,nTab, nCol,nEndRow,nTab) );
+ pPattern = pIter->Next( nStartRow, nEndRow );
+ }
+ delete pIter;
+ }
+}
+
+
+
+
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
new file mode 100644
index 000000000000..434144d06e00
--- /dev/null
+++ b/sc/source/core/data/table4.cxx
@@ -0,0 +1,1990 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+ // sonst Absturz Win beim Fuellen
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/keycodes.hxx>
+#include <rtl/math.hxx>
+#include <unotools/charclass.hxx>
+
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "table.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "document.hxx"
+#include "autoform.hxx"
+#include "userlist.hxx"
+#include "zforauto.hxx"
+#include "subtotal.hxx"
+#include "formula/errorcodes.hxx"
+#include "rangenam.hxx"
+#include "docpool.hxx"
+#include "progress.hxx"
+
+#include <math.h>
+
+// STATIC DATA -----------------------------------------------------------
+
+#define _D_MAX_LONG_ (double) 0x7fffffff
+
+extern USHORT nScFillModeMouseModifier; // global.cxx
+
+// -----------------------------------------------------------------------
+
+short lcl_DecompValueString( String& aValue, sal_Int32& nVal, USHORT* pMinDigits = NULL )
+{
+ if ( !aValue.Len() )
+ {
+ nVal = 0;
+ return 0;
+ }
+ const sal_Unicode* p = aValue.GetBuffer();
+ xub_StrLen nNeg = 0;
+ xub_StrLen nNum = 0;
+ if ( p[nNum] == '-' )
+ nNum = nNeg = 1;
+ while ( p[nNum] && CharClass::isAsciiNumeric( p[nNum] ) )
+ nNum++;
+
+ sal_Unicode cNext = p[nNum]; // 0 if at the end
+ sal_Unicode cLast = p[aValue.Len()-1];
+
+ // #i5550# If there are numbers at the beginning and the end,
+ // prefer the one at the beginning only if it's followed by a space.
+ // Otherwise, use the number at the end, to enable things like IP addresses.
+ if ( nNum > nNeg && ( cNext == 0 || cNext == ' ' || !CharClass::isAsciiNumeric(cLast) ) )
+ { // number at the beginning
+ nVal = aValue.Copy( 0, nNum ).ToInt32();
+ // #60893# any number with a leading zero sets the minimum number of digits
+ if ( p[nNeg] == '0' && pMinDigits && ( nNum - nNeg > *pMinDigits ) )
+ *pMinDigits = nNum - nNeg;
+ aValue.Erase( 0, nNum );
+ return -1;
+ }
+ else
+ {
+ nNeg = 0;
+ xub_StrLen nEnd = nNum = aValue.Len() - 1;
+ while ( nNum && CharClass::isAsciiNumeric( p[nNum] ) )
+ nNum--;
+ if ( p[nNum] == '-' )
+ {
+ nNum--;
+ nNeg = 1;
+ }
+ if ( nNum < nEnd - nNeg )
+ { // number at the end
+ nVal = aValue.Copy( nNum + 1 ).ToInt32();
+ // #60893# any number with a leading zero sets the minimum number of digits
+ if ( p[nNum+1+nNeg] == '0' && pMinDigits && ( nEnd - nNum - nNeg > *pMinDigits ) )
+ *pMinDigits = nEnd - nNum - nNeg;
+ aValue.Erase( nNum + 1 );
+ return 1;
+ }
+ }
+ nVal = 0;
+ return 0;
+}
+
+String lcl_ValueString( sal_Int32 nValue, USHORT nMinDigits )
+{
+ if ( nMinDigits <= 1 )
+ return String::CreateFromInt32( nValue ); // simple case...
+ else
+ {
+ String aStr = String::CreateFromInt32( Abs( nValue ) );
+ if ( aStr.Len() < nMinDigits )
+ {
+ String aZero;
+ aZero.Fill( nMinDigits - aStr.Len(), '0' );
+ aStr.Insert( aZero, 0 );
+ }
+ // nMinDigits doesn't include the '-' sign -> add after inserting zeros
+ if ( nValue < 0 )
+ aStr.Insert( '-', 0 );
+ return aStr;
+ }
+}
+
+static ScBaseCell * lcl_getSuffixCell( ScDocument* pDocument, sal_Int32 nValue,
+ USHORT nDigits, const String& rSuffix, CellType eCellType,
+ BOOL bIsOrdinalSuffix )
+{
+ String aValue( lcl_ValueString( nValue, nDigits ));
+ if (!bIsOrdinalSuffix)
+ return new ScStringCell( aValue += rSuffix);
+
+ String aOrdinalSuffix( ScGlobal::GetOrdinalSuffix( nValue));
+ if (eCellType != CELLTYPE_EDIT)
+ return new ScStringCell( aValue += aOrdinalSuffix);
+
+ EditEngine aEngine( pDocument->GetEnginePool() );
+ SfxItemSet aAttr = aEngine.GetEmptyItemSet();
+ aAttr.Put( SvxEscapementItem( SVX_ESCAPEMENT_SUPERSCRIPT, EE_CHAR_ESCAPEMENT));
+ aEngine.SetText( aValue );
+ aEngine.QuickInsertText( aOrdinalSuffix, ESelection( 0, aValue.Len(), 0,
+ aValue.Len() + aOrdinalSuffix.Len()));
+ aEngine.QuickSetAttribs( aAttr, ESelection( 0, aValue.Len(), 0, aValue.Len() +
+ aOrdinalSuffix.Len()));
+ return new ScEditCell( aEngine.CreateTextObject(), pDocument, NULL );
+}
+
+void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ FillCmd& rCmd, FillDateCmd& rDateCmd,
+ double& rInc, USHORT& rMinDigits,
+ ScUserListData*& rListData, USHORT& rListIndex)
+{
+ DBG_ASSERT( nCol1==nCol2 || nRow1==nRow2, "FillAnalyse: falscher Bereich" );
+
+ rInc = 0.0;
+ rMinDigits = 0;
+ rListData = NULL;
+ rCmd = FILL_SIMPLE;
+ if ( nScFillModeMouseModifier & KEY_MOD1 )
+ return ; // Ctrl-Taste: Copy
+
+ SCCOL nAddX;
+ SCROW nAddY;
+ SCSIZE nCount;
+ if (nCol1 == nCol2)
+ {
+ nAddX = 0;
+ nAddY = 1;
+ nCount = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
+ }
+ else
+ {
+ nAddX = 1;
+ nAddY = 0;
+ nCount = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
+ }
+
+ SCCOL nCol = nCol1;
+ SCROW nRow = nRow1;
+
+ ScBaseCell* pFirstCell = GetCell( nCol, nRow );
+ CellType eCellType = pFirstCell ? pFirstCell->GetCellType() : CELLTYPE_NONE;
+
+ if (eCellType == CELLTYPE_VALUE)
+ {
+ UINT32 nFormat = ((const SfxUInt32Item*)GetAttr(nCol,nRow,ATTR_VALUE_FORMAT))->GetValue();
+ BOOL bDate = ( pDocument->GetFormatTable()->GetType(nFormat) == NUMBERFORMAT_DATE );
+ if (bDate)
+ {
+ if (nCount > 1)
+ {
+ long nCmpInc = 0;
+ double nVal;
+ Date aNullDate = *pDocument->GetFormatTable()->GetNullDate();
+ Date aDate1 = aNullDate;
+ nVal = ((ScValueCell*)pFirstCell)->GetValue();
+ aDate1 += (long)nVal;
+ Date aDate2 = aNullDate;
+ nVal = GetValue(nCol+nAddX, nRow+nAddY);
+ aDate2 += (long)nVal;
+ if ( aDate1 != aDate2 )
+ {
+ FillDateCmd eType;
+ long nDDiff = aDate2.GetDay() - (long) aDate1.GetDay();
+ long nMDiff = aDate2.GetMonth() - (long) aDate1.GetMonth();
+ long nYDiff = aDate2.GetYear() - (long) aDate1.GetYear();
+ if ( nDDiff )
+ {
+ eType = FILL_DAY;
+ nCmpInc = aDate2 - aDate1;
+ }
+ else
+ {
+ eType = FILL_MONTH;
+ nCmpInc = nMDiff + 12 * nYDiff;
+ }
+
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ BOOL bVal = TRUE;
+ for (USHORT i=1; i<nCount && bVal; i++)
+ {
+ ScBaseCell* pCell = GetCell(nCol,nRow);
+ if (pCell && pCell->GetCellType() == CELLTYPE_VALUE)
+ {
+ nVal = ((ScValueCell*)pCell)->GetValue();
+ aDate2 = aNullDate + (long) nVal;
+ if ( eType == FILL_DAY )
+ {
+ if ( aDate2-aDate1 != nCmpInc )
+ bVal = FALSE;
+ }
+ else
+ {
+ nDDiff = aDate2.GetDay() - (long) aDate1.GetDay();
+ nMDiff = aDate2.GetMonth() - (long) aDate1.GetMonth();
+ nYDiff = aDate2.GetYear() - (long) aDate1.GetYear();
+ if (nDDiff || ( nMDiff + 12 * nYDiff != nCmpInc ))
+ bVal = FALSE;
+ }
+ aDate1 = aDate2;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ else
+ bVal = FALSE; // #50965# kein Datum passt auch nicht
+ }
+ if (bVal)
+ {
+ if ( eType == FILL_MONTH && ( nCmpInc % 12 == 0 ) )
+ {
+ eType = FILL_YEAR;
+ nCmpInc /= 12;
+ }
+ rCmd = FILL_DATE;
+ rDateCmd = eType;
+ rInc = nCmpInc;
+ }
+ }
+ }
+ else // einzelnes Datum -> Tage hochzaehlen
+ {
+ rCmd = FILL_DATE;
+ rDateCmd = FILL_DAY;
+ rInc = 1.0;
+ }
+ }
+ else
+ {
+ if (nCount > 1)
+ {
+ double nVal1 = ((ScValueCell*)pFirstCell)->GetValue();
+ double nVal2 = GetValue(nCol+nAddX, nRow+nAddY);
+ rInc = nVal2 - nVal1;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ BOOL bVal = TRUE;
+ for (USHORT i=1; i<nCount && bVal; i++)
+ {
+ ScBaseCell* pCell = GetCell(nCol,nRow);
+ if (pCell && pCell->GetCellType() == CELLTYPE_VALUE)
+ {
+ nVal2 = ((ScValueCell*)pCell)->GetValue();
+ double nDiff = nVal2 - nVal1;
+ if ( !::rtl::math::approxEqual( nDiff, rInc ) )
+ bVal = FALSE;
+ nVal1 = nVal2;
+ }
+ else
+ bVal = FALSE;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ if (bVal)
+ rCmd = FILL_LINEAR;
+ }
+ }
+ }
+ else if (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT)
+ {
+ String aStr;
+ GetString(nCol, nRow, aStr);
+ rListData = (ScUserListData*)(ScGlobal::GetUserList()->GetData(aStr));
+ if (rListData)
+ {
+ rListData->GetSubIndex(aStr, rListIndex);
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ for (USHORT i=1; i<nCount && rListData; i++)
+ {
+ GetString(nCol, nRow, aStr);
+ if (!rListData->GetSubIndex(aStr, rListIndex))
+ rListData = NULL;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ }
+ else if ( nCount > 1 )
+ {
+ // pass rMinDigits to all DecompValueString calls
+ // -> longest number defines rMinDigits
+
+ sal_Int32 nVal1;
+ short nFlag1 = lcl_DecompValueString( aStr, nVal1, &rMinDigits );
+ if ( nFlag1 )
+ {
+ sal_Int32 nVal2;
+ GetString( nCol+nAddX, nRow+nAddY, aStr );
+ short nFlag2 = lcl_DecompValueString( aStr, nVal2, &rMinDigits );
+ if ( nFlag1 == nFlag2 )
+ {
+ rInc = (double)nVal2 - (double)nVal1;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ BOOL bVal = TRUE;
+ for (USHORT i=1; i<nCount && bVal; i++)
+ {
+ ScBaseCell* pCell = GetCell(nCol,nRow);
+ CellType eType = pCell ? pCell->GetCellType() : CELLTYPE_NONE;
+ if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
+ {
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aStr );
+ else
+ ((ScEditCell*)pCell)->GetString( aStr );
+ nFlag2 = lcl_DecompValueString( aStr, nVal2, &rMinDigits );
+ if ( nFlag1 == nFlag2 )
+ {
+ double nDiff = (double)nVal2 - (double)nVal1;
+ if ( !::rtl::math::approxEqual( nDiff, rInc ) )
+ bVal = FALSE;
+ nVal1 = nVal2;
+ }
+ else
+ bVal = FALSE;
+ }
+ else
+ bVal = FALSE;
+ nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
+ nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
+ }
+ if (bVal)
+ rCmd = FILL_LINEAR;
+ }
+ }
+ }
+ else
+ {
+ // call DecompValueString to set rMinDigits
+ sal_Int32 nDummy;
+ lcl_DecompValueString( aStr, nDummy, &rMinDigits );
+ }
+ }
+}
+
+void ScTable::FillFormula(ULONG& /* nFormulaCounter */, BOOL /* bFirst */, ScFormulaCell* pSrcCell,
+ SCCOL nDestCol, SCROW nDestRow, BOOL bLast )
+{
+/* USHORT nTokArrLen = pSrcCell->GetTokenArrayLen();
+ if ( nTokArrLen > 15 ) // mehr als =A1 oder =67
+ {
+ ScRangeName* pRangeName = pDocument->GetRangeName();
+ String aName("___SC_"); // Wird dieser String veraendert,
+ // auch in document2 EraseNonUsed...
+ // mitaendern!!
+ aName += pRangeName->GetSharedMaxIndex() + 1;
+ aName += '_';
+ aName += nFormulaCounter;
+ nFormulaCounter++;
+ if (bFirst)
+ {
+ ScRangeData *pAktRange = new ScRangeData(
+ pDocument, aName, pSrcCell->GetTokenArray(), nTokArrLen,
+ pSrcCell->GetCol(), pSrcCell->GetRow(), nTab ,RT_SHARED);
+ if (!pRangeName->Insert( pAktRange ))
+ delete pAktRange;
+ else
+ bSharedNameInserted = TRUE;
+ }
+ USHORT nIndex;
+ pRangeName->SearchName(aName, nIndex);
+ if (!pRangeName)
+ {
+ DBG_ERROR("ScTable::FillFormula: Falscher Name");
+ return;
+ }
+ nIndex = ((ScRangeData*) ((*pRangeName)[nIndex]))->GetIndex();
+ ScTokenArray aArr;
+ aArr.AddName(nIndex);
+ aArr.AddOpCode(ocStop);
+ ScFormulaCell* pDestCell = new ScFormulaCell
+ (pDocument, ScAddress( nDestCol, nDestRow, nTab ), aArr );
+ aCol[nDestCol].Insert(nDestRow, pDestCell);
+ }
+ else
+*/ {
+ pDocument->SetNoListening( TRUE ); // noch falsche Referenzen
+ ScAddress aAddr( nDestCol, nDestRow, nTab );
+ ScFormulaCell* pDestCell = new ScFormulaCell( *pSrcCell, *pDocument, aAddr );
+ aCol[nDestCol].Insert(nDestRow, pDestCell);
+#if 0
+// mit RelRefs unnoetig
+ pDestCell->UpdateReference(URM_COPY,
+ ScRange( aAddr, aAddr ),
+ nDestCol - pSrcCell->aPos.Col(),
+ nDestRow - pSrcCell->aPos.Row(), 0);
+#endif
+ if ( bLast && pDestCell->GetMatrixFlag() )
+ {
+ ScAddress aOrg;
+ if ( pDestCell->GetMatrixOrigin( aOrg ) )
+ {
+ if ( nDestCol >= aOrg.Col() && nDestRow >= aOrg.Row() )
+ {
+ ScBaseCell* pOrgCell = pDocument->GetCell( aOrg );
+ if ( pOrgCell && pOrgCell->GetCellType() == CELLTYPE_FORMULA
+ && ((ScFormulaCell*)pOrgCell)->GetMatrixFlag() == MM_FORMULA )
+ {
+ ((ScFormulaCell*)pOrgCell)->SetMatColsRows(
+ nDestCol - aOrg.Col() + 1,
+ nDestRow - aOrg.Row() + 1 );
+ }
+ else
+ {
+ DBG_ERRORFILE( "FillFormula: MatrixOrigin keine Formelzelle mit MM_FORMULA" );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "FillFormula: MatrixOrigin rechts unten" );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "FillFormula: kein MatrixOrigin" );
+ }
+ }
+ pDocument->SetNoListening( FALSE );
+ pDestCell->StartListeningTo( pDocument );
+ }
+}
+
+void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ ULONG nFillCount, FillDir eFillDir, ScProgress& rProgress )
+{
+ if ( (nFillCount == 0) || !ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2) )
+ return;
+
+ //
+ // Richtung auswerten
+ //
+
+ BOOL bVertical = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP);
+ BOOL bPositive = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_RIGHT);
+
+ ULONG nCol = 0;
+ ULONG nRow = 0;
+ ULONG& rInner = bVertical ? nRow : nCol; // Schleifenvariablen
+ ULONG& rOuter = bVertical ? nCol : nRow;
+ ULONG nOStart;
+ ULONG nOEnd;
+ ULONG nIStart;
+ ULONG nIEnd;
+ ULONG nISrcStart;
+ ULONG nISrcEnd;
+
+ if (bVertical)
+ {
+ nOStart = nCol1;
+ nOEnd = nCol2;
+ if (bPositive)
+ {
+ nISrcStart = nRow1;
+ nISrcEnd = nRow2;
+ nIStart = nRow2 + 1;
+ nIEnd = nRow2 + nFillCount;
+ }
+ else
+ {
+ nISrcStart = nRow2;
+ nISrcEnd = nRow1;
+ nIStart = nRow1 - 1;
+ nIEnd = nRow1 - nFillCount;
+ }
+ }
+ else
+ {
+ nOStart = nRow1;
+ nOEnd = nRow2;
+ if (bPositive)
+ {
+ nISrcStart = nCol1;
+ nISrcEnd = nCol2;
+ nIStart = nCol2 + 1;
+ nIEnd = nCol2 + nFillCount;
+ }
+ else
+ {
+ nISrcStart = nCol2;
+ nISrcEnd = nCol1;
+ nIStart = nCol1 - 1;
+ nIEnd = nCol1 - nFillCount;
+ }
+ }
+ ULONG nIMin = nIStart;
+ ULONG nIMax = nIEnd;
+ PutInOrder(nIMin,nIMax);
+ if (bVertical)
+ DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL);
+ else
+ DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL);
+
+ ULONG nProgress = rProgress.GetState();
+
+ //
+ // ausfuehren
+ //
+
+ ULONG nActFormCnt = 0;
+ for (rOuter = nOStart; rOuter <= nOEnd; rOuter++)
+ {
+ ULONG nMaxFormCnt = 0; // fuer Formeln
+
+ // Attributierung uebertragen
+
+ const ScPatternAttr* pSrcPattern = NULL;
+ const ScStyleSheet* pStyleSheet = NULL;
+ ULONG nAtSrc = nISrcStart;
+ ScPatternAttr* pNewPattern = NULL;
+ BOOL bGetPattern = TRUE;
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if ( bGetPattern )
+ {
+ if ( pNewPattern )
+ delete pNewPattern;
+ if (bVertical) // rInner&:=nRow, rOuter&:=nCol
+ pSrcPattern = aCol[nCol].GetPattern(static_cast<SCROW>(nAtSrc));
+ else // rInner&:=nCol, rOuter&:=nRow
+ pSrcPattern = aCol[nAtSrc].GetPattern(static_cast<SCROW>(nRow));
+ bGetPattern = FALSE;
+ pStyleSheet = pSrcPattern->GetStyleSheet();
+ // Merge/Mergeflag nicht uebernehmen,
+ const SfxItemSet& rSet = pSrcPattern->GetItemSet();
+ if ( rSet.GetItemState(ATTR_MERGE, FALSE) == SFX_ITEM_SET
+ || rSet.GetItemState(ATTR_MERGE_FLAG, FALSE) == SFX_ITEM_SET )
+ {
+ pNewPattern = new ScPatternAttr( *pSrcPattern );
+ SfxItemSet& rNewSet = pNewPattern->GetItemSet();
+ rNewSet.ClearItem(ATTR_MERGE);
+ rNewSet.ClearItem(ATTR_MERGE_FLAG);
+ }
+ else
+ pNewPattern = NULL;
+ }
+
+ if ( bVertical && nISrcStart == nISrcEnd )
+ {
+ // Attribute komplett am Stueck setzen
+ if (pNewPattern || pSrcPattern != pDocument->GetDefPattern())
+ {
+ // Default steht schon da (DeleteArea)
+ SCROW nY1 = static_cast<SCROW>(Min( nIStart, nIEnd ));
+ SCROW nY2 = static_cast<SCROW>(Max( nIStart, nIEnd ));
+ if ( pStyleSheet )
+ aCol[nCol].ApplyStyleArea( nY1, nY2, *pStyleSheet );
+ if ( pNewPattern )
+ aCol[nCol].ApplyPatternArea( nY1, nY2, *pNewPattern );
+ else
+ aCol[nCol].ApplyPatternArea( nY1, nY2, *pSrcPattern );
+ }
+ break; // Schleife abbrechen
+ }
+
+ if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) )
+ {
+ // Vorlage auch uebernehmen
+ //! am AttrArray mit ApplyPattern zusammenfassen ??
+ if ( pStyleSheet )
+ aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet );
+
+ // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen
+ if ( pNewPattern )
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern );
+ else
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern );
+ }
+
+ if (nAtSrc==nISrcEnd)
+ {
+ if ( nAtSrc != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nAtSrc = nISrcStart;
+ bGetPattern = TRUE;
+ }
+ }
+ else if (bPositive)
+ {
+ ++nAtSrc;
+ bGetPattern = TRUE;
+ }
+ else
+ {
+ --nAtSrc;
+ bGetPattern = TRUE;
+ }
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ if ( pNewPattern )
+ delete pNewPattern;
+
+ // Analyse
+
+ FillCmd eFillCmd;
+ FillDateCmd eDateCmd;
+ double nInc;
+ USHORT nMinDigits;
+ ScUserListData* pListData = NULL;
+ USHORT nListIndex;
+ if (bVertical)
+ FillAnalyse(static_cast<SCCOL>(nCol),nRow1,
+ static_cast<SCCOL>(nCol),nRow2, eFillCmd,eDateCmd,
+ nInc,nMinDigits, pListData,nListIndex);
+ else
+ FillAnalyse(nCol1,static_cast<SCROW>(nRow),
+ nCol2,static_cast<SCROW>(nRow), eFillCmd,eDateCmd,
+ nInc,nMinDigits, pListData,nListIndex);
+
+ if (bVertical)
+ aCol[nCol].Resize( aCol[nCol].GetCellCount() + nFillCount );
+
+ if (pListData)
+ {
+ USHORT nListCount = pListData->GetSubCount();
+ if ( !bPositive )
+ {
+ // nListIndex auf FillAnalyse zeigt auf den letzten Eintrag -> anpassen
+ ULONG nSub = nISrcStart - nISrcEnd;
+ for (ULONG i=0; i<nSub; i++)
+ {
+ if (nListIndex == 0) nListIndex = nListCount;
+ --nListIndex;
+ }
+ }
+
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if (bPositive)
+ {
+ ++nListIndex;
+ if (nListIndex >= nListCount) nListIndex = 0;
+ }
+ else
+ {
+ if (nListIndex == 0) nListIndex = nListCount;
+ --nListIndex;
+ }
+ aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScStringCell(pListData->GetSubStr(nListIndex)));
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ else if (eFillCmd == FILL_SIMPLE) // Auffuellen mit Muster
+ {
+ ULONG nSource = nISrcStart;
+ double nDelta;
+ if ( nScFillModeMouseModifier & KEY_MOD1 )
+ nDelta = 0.0;
+ else if ( bPositive )
+ nDelta = 1.0;
+ else
+ nDelta = -1.0;
+ double nVal = 0.0;
+ ULONG nFormulaCounter = nActFormCnt;
+ BOOL bFirst = TRUE;
+ BOOL bGetCell = TRUE;
+ USHORT nCellDigits = 0;
+ short nHeadNoneTail = 0;
+ sal_Int32 nStringValue = 0;
+ String aValue;
+ ScBaseCell* pSrcCell = NULL;
+ CellType eCellType = CELLTYPE_NONE;
+ BOOL bIsOrdinalSuffix = FALSE;
+
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if ( bGetCell )
+ {
+ if (bVertical) // rInner&:=nRow, rOuter&:=nCol
+ pSrcCell = aCol[nCol].GetCell( static_cast<SCROW>(nSource) );
+ else // rInner&:=nCol, rOuter&:=nRow
+ pSrcCell = aCol[nSource].GetCell( static_cast<SCROW>(nRow) );
+ bGetCell = FALSE;
+ if ( pSrcCell )
+ {
+ eCellType = pSrcCell->GetCellType();
+ switch ( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ nVal = ((ScValueCell*)pSrcCell)->GetValue();
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if ( eCellType == CELLTYPE_STRING )
+ ((ScStringCell*)pSrcCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pSrcCell)->GetString( aValue );
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ {
+ nCellDigits = 0; // look at each source cell individually
+ nHeadNoneTail = lcl_DecompValueString(
+ aValue, nStringValue, &nCellDigits );
+
+ bIsOrdinalSuffix = aValue.Equals(
+ ScGlobal::GetOrdinalSuffix( nStringValue));
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ eCellType = CELLTYPE_NONE;
+ }
+ switch (eCellType)
+ {
+ case CELLTYPE_VALUE:
+ aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta));
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if ( nHeadNoneTail )
+ {
+ // #i48009# with the "nStringValue+(long)nDelta" expression within the
+ // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
+ // so nNextValue is now calculated ahead.
+ sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
+
+ String aStr;
+ if ( nHeadNoneTail < 0 )
+ {
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ lcl_getSuffixCell( pDocument,
+ nNextValue, nCellDigits, aValue,
+ eCellType, bIsOrdinalSuffix));
+ }
+ else
+ {
+ aStr = aValue;
+ aStr += lcl_ValueString( nNextValue, nCellDigits );
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ new ScStringCell( aStr));
+ }
+ }
+ else
+ {
+ ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
+ switch ( eCellType )
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ break;
+ case CELLTYPE_FORMULA :
+ FillFormula( nFormulaCounter, bFirst,
+ (ScFormulaCell*) pSrcCell,
+ static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow), (rInner == nIEnd) );
+ if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
+ nMaxFormCnt = nFormulaCounter - nActFormCnt;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nSource==nISrcEnd)
+ {
+ if ( nSource != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nSource = nISrcStart;
+ bGetCell = TRUE;
+ }
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ {
+ if ( bPositive )
+ nDelta += 1.0;
+ else
+ nDelta -= 1.0;
+ }
+ nFormulaCounter = nActFormCnt;
+ bFirst = FALSE;
+ }
+ else if (bPositive)
+ {
+ ++nSource;
+ bGetCell = TRUE;
+ }
+ else
+ {
+ --nSource;
+ bGetCell = TRUE;
+ }
+
+ // Progress in der inneren Schleife nur bei teuren Zellen,
+ // und auch dann nicht fuer jede einzelne
+
+ ++nProgress;
+ if ( eCellType == CELLTYPE_FORMULA || eCellType == CELLTYPE_EDIT )
+ rProgress.SetStateOnPercent( nProgress );
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ else
+ {
+ if (!bPositive)
+ nInc = -nInc;
+ double nEndVal = (nInc>=0.0) ? MAXDOUBLE : -MAXDOUBLE;
+ if (bVertical)
+ FillSeries( static_cast<SCCOL>(nCol), nRow1,
+ static_cast<SCCOL>(nCol), nRow2, nFillCount, eFillDir,
+ eFillCmd, eDateCmd, nInc, nEndVal, nMinDigits, FALSE,
+ rProgress );
+ else
+ FillSeries( nCol1, static_cast<SCROW>(nRow), nCol2,
+ static_cast<SCROW>(nRow), nFillCount, eFillDir,
+ eFillCmd, eDateCmd, nInc, nEndVal, nMinDigits, FALSE,
+ rProgress );
+ nProgress = rProgress.GetState();
+ }
+
+ nActFormCnt += nMaxFormCnt;
+ }
+}
+
+String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
+{
+ String aValue;
+
+ SCCOL nCol1 = rSource.aStart.Col();
+ SCROW nRow1 = rSource.aStart.Row();
+ SCCOL nCol2 = rSource.aEnd.Col();
+ SCROW nRow2 = rSource.aEnd.Row();
+ BOOL bOk = TRUE;
+ long nIndex = 0;
+ ULONG nSrcCount = 0;
+ FillDir eFillDir = FILL_TO_BOTTOM;
+ if ( nEndX == nCol2 && nEndY == nRow2 ) // leer
+ bOk = FALSE;
+ else if ( nEndX == nCol2 ) // nach oben/unten
+ {
+ nEndX = nCol2 = nCol1; // nur erste Spalte ansehen
+ nSrcCount = nRow2 - nRow1 + 1;
+ nIndex = ((long)nEndY) - nRow1; // kann negativ werden
+ if ( nEndY >= nRow1 )
+ eFillDir = FILL_TO_BOTTOM;
+ else
+ eFillDir = FILL_TO_TOP;
+ }
+ else if ( nEndY == nRow2 ) // nach links/rechts
+ {
+ nEndY = nRow2 = nRow1; // nur erste Zeile ansehen
+ nSrcCount = nCol2 - nCol1 + 1;
+ nIndex = ((long)nEndX) - nCol1; // kann negativ werden
+ if ( nEndX >= nCol1 )
+ eFillDir = FILL_TO_RIGHT;
+ else
+ eFillDir = FILL_TO_LEFT;
+ }
+ else // Richtung nicht eindeutig
+ bOk = FALSE;
+
+ if ( bOk )
+ {
+ FillCmd eFillCmd;
+ FillDateCmd eDateCmd;
+ double nInc;
+ USHORT nMinDigits;
+ ScUserListData* pListData = NULL;
+ USHORT nListIndex;
+
+ FillAnalyse(nCol1,nRow1, nCol2,nRow2, eFillCmd,eDateCmd, nInc,nMinDigits, pListData,nListIndex);
+
+ if ( pListData ) // benutzerdefinierte Liste
+ {
+ USHORT nListCount = pListData->GetSubCount();
+ if ( nListCount )
+ {
+ ULONG nSub = nSrcCount - 1; // nListIndex ist vom letzten Source-Eintrag
+ while ( nIndex < sal::static_int_cast<long>(nSub) )
+ nIndex += nListCount;
+ ULONG nPos = ( nListIndex + nIndex - nSub ) % nListCount;
+ aValue = pListData->GetSubStr(sal::static_int_cast<USHORT>(nPos));
+ }
+ }
+ else if ( eFillCmd == FILL_SIMPLE ) // Auffuellen mit Muster
+ {
+ long nPosIndex = nIndex;
+ while ( nPosIndex < 0 )
+ nPosIndex += nSrcCount;
+ ULONG nPos = nPosIndex % nSrcCount;
+ SCCOL nSrcX = nCol1;
+ SCROW nSrcY = nRow1;
+ if ( eFillDir == FILL_TO_TOP || eFillDir == FILL_TO_BOTTOM )
+ nSrcY = sal::static_int_cast<SCROW>( nSrcY + static_cast<SCROW>(nPos) );
+ else
+ nSrcX = sal::static_int_cast<SCCOL>( nSrcX + static_cast<SCCOL>(nPos) );
+
+ ScBaseCell* pCell = GetCell( nSrcX, nSrcY );
+ if ( pCell )
+ {
+ sal_Int32 nDelta;
+ if (nIndex >= 0)
+ nDelta = nIndex / nSrcCount;
+ else
+ nDelta = ( nIndex - nSrcCount + 1 ) / nSrcCount; // -1 -> -1
+
+ CellType eType = pCell->GetCellType();
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pCell)->GetString( aValue );
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ {
+ sal_Int32 nVal;
+ USHORT nCellDigits = 0; // look at each source cell individually
+ short nFlag = lcl_DecompValueString( aValue, nVal, &nCellDigits );
+ if ( nFlag < 0 )
+ {
+ if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
+ aValue = ScGlobal::GetOrdinalSuffix( nVal + nDelta);
+
+ aValue.Insert( lcl_ValueString( nVal + nDelta, nCellDigits ), 0 );
+ }
+ else if ( nFlag > 0 )
+ aValue += lcl_ValueString( nVal + nDelta, nCellDigits );
+ }
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ // dabei kann's keinen Ueberlauf geben...
+ double nVal = ((ScValueCell*)pCell)->GetValue();
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ nVal += (double) nDelta;
+
+ Color* pColor;
+ ULONG nNumFmt = GetNumberFormat( nSrcX, nSrcY );
+ pDocument->GetFormatTable()->
+ GetOutputString( nVal, nNumFmt, aValue, &pColor );
+ }
+ break;
+ // Formeln nicht
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ else if ( eFillCmd == FILL_LINEAR || eFillCmd == FILL_DATE ) // Werte
+ {
+ BOOL bValueOk;
+ double nStart;
+ sal_Int32 nVal = 0;
+ short nHeadNoneTail = 0;
+ ScBaseCell* pCell = GetCell( nCol1, nRow1 );
+ if ( pCell )
+ {
+ CellType eType = pCell->GetCellType();
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pCell)->GetString( aValue );
+ nHeadNoneTail = lcl_DecompValueString( aValue, nVal );
+ if ( nHeadNoneTail )
+ nStart = (double)nVal;
+ else
+ nStart = 0.0;
+ }
+ break;
+ case CELLTYPE_VALUE:
+ nStart = ((ScValueCell*)pCell)->GetValue();
+ break;
+ case CELLTYPE_FORMULA:
+ nStart = ((ScFormulaCell*)pCell)->GetValue();
+ break;
+ default:
+ nStart = 0.0;
+ }
+ }
+ else
+ nStart = 0.0;
+ if ( eFillCmd == FILL_LINEAR )
+ {
+ double nAdd = nInc;
+ bValueOk = ( SubTotal::SafeMult( nAdd, (double) nIndex ) &&
+ SubTotal::SafePlus( nStart, nAdd ) );
+ }
+ else // Datum
+ {
+ bValueOk = TRUE;
+ USHORT nDayOfMonth = 0;
+ if ( nIndex < 0 )
+ {
+ nIndex = -nIndex;
+ nInc = -nInc;
+ }
+ for (long i=0; i<nIndex; i++)
+ IncDate( nStart, nDayOfMonth, nInc, eDateCmd );
+ }
+
+ if (bValueOk)
+ {
+ if ( nHeadNoneTail )
+ {
+ if ( nHeadNoneTail < 0 )
+ {
+ if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
+ aValue = ScGlobal::GetOrdinalSuffix( (sal_Int32)nStart );
+
+ aValue.Insert( lcl_ValueString( (sal_Int32)nStart, nMinDigits ), 0 );
+ }
+ else
+ aValue += lcl_ValueString( (sal_Int32)nStart, nMinDigits );
+ }
+ else
+ {
+ //! Zahlformat je nach Index holen?
+ Color* pColor;
+ ULONG nNumFmt = GetNumberFormat( nCol1, nRow1 );
+ pDocument->GetFormatTable()->
+ GetOutputString( nStart, nNumFmt, aValue, &pColor );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("GetAutoFillPreview: falscher Modus");
+ }
+ }
+
+ return aValue;
+}
+
+void ScTable::IncDate(double& rVal, USHORT& nDayOfMonth, double nStep, FillDateCmd eCmd)
+{
+ if (eCmd == FILL_DAY)
+ {
+ rVal += nStep;
+ return;
+ }
+
+ // class Date Grenzen
+ const USHORT nMinYear = 1583;
+ const USHORT nMaxYear = 9956;
+
+ long nInc = (long) nStep; // nach oben/unten begrenzen ?
+ Date aNullDate = *pDocument->GetFormatTable()->GetNullDate();
+ Date aDate = aNullDate;
+ aDate += (long)rVal;
+ switch (eCmd)
+ {
+ case FILL_WEEKDAY:
+ {
+ aDate += nInc;
+ DayOfWeek eWeekDay = aDate.GetDayOfWeek();
+ if (nInc >= 0)
+ {
+ if (eWeekDay == SATURDAY)
+ aDate += 2;
+ else if (eWeekDay == SUNDAY)
+ aDate += 1;
+ }
+ else
+ {
+ if (eWeekDay == SATURDAY)
+ aDate -= 1;
+ else if (eWeekDay == SUNDAY)
+ aDate -= 2;
+ }
+ }
+ break;
+ case FILL_MONTH:
+ {
+ if ( nDayOfMonth == 0 )
+ nDayOfMonth = aDate.GetDay(); // init
+ long nMonth = aDate.GetMonth();
+ long nYear = aDate.GetYear();
+
+ nMonth += nInc;
+
+ if (nInc >= 0)
+ {
+ if (nMonth > 12)
+ {
+ long nYAdd = (nMonth-1) / 12;
+ nMonth -= nYAdd * 12;
+ nYear += nYAdd;
+ }
+ }
+ else
+ {
+ if (nMonth < 1)
+ {
+ long nYAdd = 1 - nMonth / 12; // positiv
+ nMonth += nYAdd * 12;
+ nYear -= nYAdd;
+ }
+ }
+
+ if ( nYear < nMinYear )
+ aDate = Date( 1,1, nMinYear );
+ else if ( nYear > nMaxYear )
+ aDate = Date( 31,12, nMaxYear );
+ else
+ {
+ aDate.SetMonth((USHORT) nMonth);
+ aDate.SetYear((USHORT) nYear);
+ if ( nDayOfMonth > 28 )
+ aDate.SetDay( Min( aDate.GetDaysInMonth(), nDayOfMonth ) );
+ }
+ }
+ break;
+ case FILL_YEAR:
+ {
+ long nYear = aDate.GetYear();
+ nYear += nInc;
+ if ( nYear < nMinYear )
+ aDate = Date( 1,1, nMinYear );
+ else if ( nYear > nMaxYear )
+ aDate = Date( 31,12, nMaxYear );
+ else
+ aDate.SetYear((USHORT) nYear);
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ rVal = aDate - aNullDate;
+}
+
+void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
+ double nStepValue, double nMaxValue, USHORT nArgMinDigits,
+ BOOL bAttribs, ScProgress& rProgress )
+{
+ //
+ // Richtung auswerten
+ //
+
+ BOOL bVertical = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP);
+ BOOL bPositive = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_RIGHT);
+
+ ULONG nCol = 0;
+ ULONG nRow = 0;
+ ULONG& rInner = bVertical ? nRow : nCol; // Schleifenvariablen
+ ULONG& rOuter = bVertical ? nCol : nRow;
+ ULONG nOStart;
+ ULONG nOEnd;
+ ULONG nIStart;
+ ULONG nIEnd;
+ ULONG nISource;
+
+ if (bVertical)
+ {
+ nFillCount += (nRow2 - nRow1);
+ if (nFillCount == 0)
+ return;
+ nOStart = nCol1;
+ nOEnd = nCol2;
+ if (bPositive)
+ {
+ nISource = nRow1;
+ nIStart = nRow1 + 1;
+ nIEnd = nRow1 + nFillCount;
+ }
+ else
+ {
+ nISource = nRow2;
+ nIStart = nRow2 - 1;
+ nIEnd = nRow2 - nFillCount;
+ }
+ }
+ else
+ {
+ nFillCount += (nCol2 - nCol1);
+ if (nFillCount == 0)
+ return;
+ nOStart = nRow1;
+ nOEnd = nRow2;
+ if (bPositive)
+ {
+ nISource = nCol1;
+ nIStart = nCol1 + 1;
+ nIEnd = nCol1 + nFillCount;
+ }
+ else
+ {
+ nISource = nCol2;
+ nIStart = nCol2 - 1;
+ nIEnd = nCol2 - nFillCount;
+ }
+ }
+
+ ULONG nIMin = nIStart;
+ ULONG nIMax = nIEnd;
+ PutInOrder(nIMin,nIMax);
+ USHORT nDel = bAttribs ? IDF_AUTOFILL : (IDF_AUTOFILL & IDF_CONTENTS);
+ if (bVertical)
+ DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), nDel);
+ else
+ DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, nDel);
+
+ ULONG nProgress = rProgress.GetState();
+
+ //
+ // ausfuehren
+ //
+
+ ULONG nActFormCnt = 0;
+ for (rOuter = nOStart; rOuter <= nOEnd; rOuter++)
+ {
+ BOOL bFirst = TRUE;
+ rInner = nISource;
+ ScBaseCell* pSrcCell = aCol[nCol].GetCell(static_cast<SCROW>(nRow));
+
+ if (bVertical && bAttribs)
+ aCol[nCol].Resize( aCol[nCol].GetCellCount() + nFillCount );
+
+ if (bAttribs)
+ {
+ const ScPatternAttr* pSrcPattern = aCol[nCol].GetPattern(static_cast<SCROW>(nRow));
+ if (bVertical)
+ aCol[nCol].SetPatternArea( static_cast<SCROW>(nIMin),
+ static_cast<SCROW>(nIMax), *pSrcPattern, TRUE );
+ else
+ for (SCCOL nAtCol = static_cast<SCCOL>(nIMin); nAtCol <= sal::static_int_cast<SCCOL>(nIMax); nAtCol++)
+ aCol[nAtCol].SetPattern(static_cast<SCROW>(nRow), *pSrcPattern, TRUE);
+ }
+
+ if (pSrcCell)
+ {
+ CellType eCellType = pSrcCell->GetCellType();
+
+ if (eFillCmd == FILL_SIMPLE) // kopieren
+ {
+ if (eCellType == CELLTYPE_FORMULA)
+ {
+ for (rInner = nIMin; rInner <= nIMax; rInner++)
+ {
+ ULONG nInd = nActFormCnt;
+ FillFormula(nInd, bFirst, (ScFormulaCell*)pSrcCell,
+ static_cast<SCCOL>(nCol), nRow, (rInner == nIEnd) );
+ bFirst = FALSE;
+ rProgress.SetStateOnPercent( ++nProgress );
+ }
+ }
+ else if (eCellType != CELLTYPE_NOTE)
+ {
+ for (rInner = nIMin; rInner <= nIMax; rInner++)
+ {
+ ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
+ aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ }
+ else if (eCellType == CELLTYPE_VALUE || eCellType == CELLTYPE_FORMULA)
+ {
+ double nStartVal;
+ if (eCellType == CELLTYPE_VALUE)
+ nStartVal = ((ScValueCell*)pSrcCell)->GetValue();
+ else
+ nStartVal = ((ScFormulaCell*)pSrcCell)->GetValue();
+ double nVal = nStartVal;
+ long nIndex = 0;
+
+ BOOL bError = FALSE;
+ BOOL bOverflow = FALSE;
+
+ USHORT nDayOfMonth = 0;
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if (!bError && !bOverflow)
+ {
+ switch (eFillCmd)
+ {
+ case FILL_LINEAR:
+ {
+ // #86365# use multiplication instead of repeated addition
+ // to avoid accumulating rounding errors
+ nVal = nStartVal;
+ double nAdd = nStepValue;
+ if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
+ !SubTotal::SafePlus( nVal, nAdd ) )
+ bError = TRUE;
+ }
+ break;
+ case FILL_GROWTH:
+ if (!SubTotal::SafeMult(nVal, nStepValue))
+ bError = TRUE;
+ break;
+ case FILL_DATE:
+ if (fabs(nVal) > _D_MAX_LONG_)
+ bError = TRUE;
+ else
+ IncDate(nVal, nDayOfMonth, nStepValue, eFillDateCmd);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nStepValue >= 0)
+ {
+ if (nVal > nMaxValue) // Zielwert erreicht?
+ {
+ nVal = nMaxValue;
+ bOverflow = TRUE;
+ }
+ }
+ else
+ {
+ if (nVal < nMaxValue)
+ {
+ nVal = nMaxValue;
+ bOverflow = TRUE;
+ }
+ }
+ }
+
+ if (bError)
+ aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue);
+ else if (!bOverflow)
+ aCol[nCol].SetValue(static_cast<SCROW>(nRow), nVal);
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ else if (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT)
+ {
+ if ( nStepValue >= 0 )
+ {
+ if ( nMaxValue >= (double)LONG_MAX )
+ nMaxValue = (double)LONG_MAX - 1;
+ }
+ else
+ {
+ if ( nMaxValue <= (double)LONG_MIN )
+ nMaxValue = (double)LONG_MIN + 1;
+ }
+ String aValue;
+ if (eCellType == CELLTYPE_STRING)
+ ((ScStringCell*)pSrcCell)->GetString( aValue );
+ else
+ ((ScEditCell*)pSrcCell)->GetString( aValue );
+ sal_Int32 nStringValue;
+ USHORT nMinDigits = nArgMinDigits;
+ short nHeadNoneTail = lcl_DecompValueString( aValue, nStringValue, &nMinDigits );
+ if ( nHeadNoneTail )
+ {
+ double nStartVal = (double)nStringValue;
+ double nVal = nStartVal;
+ long nIndex = 0;
+ BOOL bError = FALSE;
+ BOOL bOverflow = FALSE;
+
+ BOOL bIsOrdinalSuffix = aValue.Equals( ScGlobal::GetOrdinalSuffix(
+ (sal_Int32)nStartVal));
+
+ rInner = nIStart;
+ while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
+ {
+ if (!bError && !bOverflow)
+ {
+ switch (eFillCmd)
+ {
+ case FILL_LINEAR:
+ {
+ // #86365# use multiplication instead of repeated addition
+ // to avoid accumulating rounding errors
+ nVal = nStartVal;
+ double nAdd = nStepValue;
+ if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
+ !SubTotal::SafePlus( nVal, nAdd ) )
+ bError = TRUE;
+ }
+ break;
+ case FILL_GROWTH:
+ if (!SubTotal::SafeMult(nVal, nStepValue))
+ bError = TRUE;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nStepValue >= 0)
+ {
+ if (nVal > nMaxValue) // Zielwert erreicht?
+ {
+ nVal = nMaxValue;
+ bOverflow = TRUE;
+ }
+ }
+ else
+ {
+ if (nVal < nMaxValue)
+ {
+ nVal = nMaxValue;
+ bOverflow = TRUE;
+ }
+ }
+ }
+
+ if (bError)
+ aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue);
+ else if (!bOverflow)
+ {
+ nStringValue = (sal_Int32)nVal;
+ String aStr;
+ if ( nHeadNoneTail < 0 )
+ {
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ lcl_getSuffixCell( pDocument,
+ nStringValue, nMinDigits, aValue,
+ eCellType, bIsOrdinalSuffix ));
+ }
+ else
+ {
+ aStr = aValue;
+ aStr += lcl_ValueString( nStringValue, nMinDigits );
+ ScStringCell* pCell = new ScStringCell( aStr );
+ aCol[nCol].Insert( static_cast<SCROW>(nRow), pCell );
+ }
+ }
+
+ if (rInner == nIEnd) break;
+ if (bPositive) ++rInner; else --rInner;
+ }
+ }
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ }
+ else
+ {
+ nProgress += nIMax - nIMin + 1;
+ rProgress.SetStateOnPercent( nProgress );
+ }
+ ++nActFormCnt;
+ }
+}
+
+void ScTable::Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
+ double nStepValue, double nMaxValue)
+{
+ ULONG nProgCount;
+ if (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP)
+ nProgCount = nCol2 - nCol1 + 1;
+ else
+ nProgCount = nRow2 - nRow1 + 1;
+ nProgCount *= nFillCount;
+ ScProgress aProgress( pDocument->GetDocumentShell(),
+ ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
+
+ bSharedNameInserted = FALSE;
+
+ if (eFillCmd == FILL_AUTO)
+ FillAuto(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir, aProgress);
+ else
+ FillSeries(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir,
+ eFillCmd, eFillDateCmd, nStepValue, nMaxValue, 0, TRUE, aProgress);
+
+ if (bSharedNameInserted) // Wurde Shared-Name eingefuegt?
+ pDocument->GetRangeName()->SetSharedMaxIndex(
+ pDocument->GetRangeName()->GetSharedMaxIndex()+1); // dann hochzaehlen
+}
+
+
+void ScTable::AutoFormatArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScPatternAttr& rAttr, USHORT nFormatNo)
+{
+ ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
+ if (pAutoFormat)
+ {
+ ScAutoFormatData* pData = (*pAutoFormat)[nFormatNo];
+ if (pData)
+ {
+// ScPatternAttr aPattern(pDocument->GetPool());
+// pData->FillToItemSet(nIndex, aPattern.GetItemSet(), *pDocument);
+ ApplyPatternArea(nStartCol, nStartRow, nEndCol, nEndRow, rAttr);
+ }
+ }
+}
+
+void ScTable::AutoFormat( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ USHORT nFormatNo )
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
+ if (pAutoFormat)
+ {
+ ScAutoFormatData* pData = (*pAutoFormat)[nFormatNo];
+ if (pData)
+ {
+ ScPatternAttr* pPatternAttrs[16];
+ for (sal_uInt8 i = 0; i < 16; ++i)
+ {
+ pPatternAttrs[i] = new ScPatternAttr(pDocument->GetPool());
+ pData->FillToItemSet(i, pPatternAttrs[i]->GetItemSet(), *pDocument);
+ }
+
+ SCCOL nCol = nStartCol;
+ SCROW nRow = nStartRow;
+ USHORT nIndex = 0;
+ // Linke obere Ecke
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ // Linke Spalte
+ if (pData->IsEqualData(4, 8))
+ AutoFormatArea(nStartCol, nStartRow + 1, nStartCol, nEndRow - 1, *pPatternAttrs[4], nFormatNo);
+ else
+ {
+ nIndex = 4;
+ for (nRow = nStartRow + 1; nRow < nEndRow; nRow++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 4)
+ nIndex = 8;
+ else
+ nIndex = 4;
+ }
+ }
+ // Linke untere Ecke
+ nRow = nEndRow;
+ nIndex = 12;
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ // Rechte obere Ecke
+ nCol = nEndCol;
+ nRow = nStartRow;
+ nIndex = 3;
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ // Rechte Spalte
+ if (pData->IsEqualData(7, 11))
+ AutoFormatArea(nEndCol, nStartRow + 1, nEndCol, nEndRow - 1, *pPatternAttrs[7], nFormatNo);
+ else
+ {
+ nIndex = 7;
+ for (nRow = nStartRow + 1; nRow < nEndRow; nRow++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 7)
+ nIndex = 11;
+ else
+ nIndex = 7;
+ }
+ }
+ // Rechte untere Ecke
+ nRow = nEndRow;
+ nIndex = 15;
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ nRow = nStartRow;
+ nIndex = 1;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 1)
+ nIndex = 2;
+ else
+ nIndex = 1;
+ }
+ // Untere Zeile
+ nRow = nEndRow;
+ nIndex = 13;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 13)
+ nIndex = 14;
+ else
+ nIndex = 13;
+ }
+ // Boddy
+ if ((pData->IsEqualData(5, 6)) && (pData->IsEqualData(9, 10)) && (pData->IsEqualData(5, 9)))
+ AutoFormatArea(nStartCol + 1, nStartRow + 1, nEndCol-1, nEndRow - 1, *pPatternAttrs[5], nFormatNo);
+ else
+ {
+ if ((pData->IsEqualData(5, 9)) && (pData->IsEqualData(6, 10)))
+ {
+ nIndex = 5;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ AutoFormatArea(nCol, nStartRow + 1, nCol, nEndRow - 1, *pPatternAttrs[nIndex], nFormatNo);
+ if (nIndex == 5)
+ nIndex = 6;
+ else
+ nIndex = 5;
+ }
+ }
+ else
+ {
+ nIndex = 5;
+ for (nCol = nStartCol + 1; nCol < nEndCol; nCol++)
+ {
+ for (nRow = nStartRow + 1; nRow < nEndRow; nRow++)
+ {
+ AutoFormatArea(nCol, nRow, nCol, nRow, *pPatternAttrs[nIndex], nFormatNo);
+ if ((nIndex == 5) || (nIndex == 9))
+ {
+ if (nIndex == 5)
+ nIndex = 9;
+ else
+ nIndex = 5;
+ }
+ else
+ {
+ if (nIndex == 6)
+ nIndex = 10;
+ else
+ nIndex = 6;
+ }
+ } // for nRow
+ if ((nIndex == 5) || (nIndex == 9))
+ nIndex = 6;
+ else
+ nIndex = 5;
+ } // for nCol
+ } // if not equal Column
+ } // if not all equal
+
+ for (sal_uInt8 j = 0; j < 16; ++j)
+ delete pPatternAttrs[j];
+ } // if AutoFormatData != NULL
+ } // if AutoFormat != NULL
+ } // if ValidColRow
+}
+
+void ScTable::GetAutoFormatAttr(SCCOL nCol, SCROW nRow, USHORT nIndex, ScAutoFormatData& rData)
+{
+ UINT32 nFormatIndex = GetNumberFormat( nCol, nRow );
+ ScNumFormatAbbrev aNumFormat( nFormatIndex, *pDocument->GetFormatTable() );
+ rData.GetFromItemSet( nIndex, GetPattern( nCol, nRow )->GetItemSet(), aNumFormat );
+}
+
+#define LF_LEFT 1
+#define LF_TOP 2
+#define LF_RIGHT 4
+#define LF_BOTTOM 8
+#define LF_ALL (LF_LEFT | LF_TOP | LF_RIGHT | LF_BOTTOM)
+
+void ScTable::GetAutoFormatFrame(SCCOL nCol, SCROW nRow, USHORT nFlags, USHORT nIndex, ScAutoFormatData& rData)
+{
+ const SvxBoxItem* pTheBox = (SvxBoxItem*)GetAttr(nCol, nRow, ATTR_BORDER);
+ const SvxBoxItem* pLeftBox = (SvxBoxItem*)GetAttr(nCol - 1, nRow, ATTR_BORDER);
+ const SvxBoxItem* pTopBox = (SvxBoxItem*)GetAttr(nCol, nRow - 1, ATTR_BORDER);
+ const SvxBoxItem* pRightBox = (SvxBoxItem*)GetAttr(nCol + 1, nRow, ATTR_BORDER);
+ const SvxBoxItem* pBottomBox = (SvxBoxItem*)GetAttr(nCol, nRow + 1, ATTR_BORDER);
+
+ SvxBoxItem aBox( ATTR_BORDER );
+ if (nFlags & LF_LEFT)
+ {
+ if (pLeftBox)
+ {
+ if (ScHasPriority(pTheBox->GetLeft(), pLeftBox->GetRight()))
+ aBox.SetLine(pTheBox->GetLeft(), BOX_LINE_LEFT);
+ else
+ aBox.SetLine(pLeftBox->GetRight(), BOX_LINE_LEFT);
+ }
+ else
+ aBox.SetLine(pTheBox->GetLeft(), BOX_LINE_LEFT);
+ }
+ if (nFlags & LF_TOP)
+ {
+ if (pTopBox)
+ {
+ if (ScHasPriority(pTheBox->GetTop(), pTopBox->GetBottom()))
+ aBox.SetLine(pTheBox->GetTop(), BOX_LINE_TOP);
+ else
+ aBox.SetLine(pTopBox->GetBottom(), BOX_LINE_TOP);
+ }
+ else
+ aBox.SetLine(pTheBox->GetTop(), BOX_LINE_TOP);
+ }
+ if (nFlags & LF_RIGHT)
+ {
+ if (pRightBox)
+ {
+ if (ScHasPriority(pTheBox->GetRight(), pRightBox->GetLeft()))
+ aBox.SetLine(pTheBox->GetRight(), BOX_LINE_RIGHT);
+ else
+ aBox.SetLine(pRightBox->GetLeft(), BOX_LINE_RIGHT);
+ }
+ else
+ aBox.SetLine(pTheBox->GetRight(), BOX_LINE_RIGHT);
+ }
+ if (nFlags & LF_BOTTOM)
+ {
+ if (pBottomBox)
+ {
+ if (ScHasPriority(pTheBox->GetBottom(), pBottomBox->GetTop()))
+ aBox.SetLine(pTheBox->GetBottom(), BOX_LINE_BOTTOM);
+ else
+ aBox.SetLine(pBottomBox->GetTop(), BOX_LINE_BOTTOM);
+ }
+ else
+ aBox.SetLine(pTheBox->GetBottom(), BOX_LINE_BOTTOM);
+ }
+ rData.PutItem( nIndex, aBox );
+}
+
+void ScTable::GetAutoFormatData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScAutoFormatData& rData)
+{
+ if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
+ {
+ if ((nEndCol - nStartCol >= 3) && (nEndRow - nStartRow >= 3))
+ {
+ // Linke obere Ecke
+ GetAutoFormatAttr(nStartCol, nStartRow, 0, rData);
+ GetAutoFormatFrame(nStartCol, nStartRow, LF_ALL, 0, rData);
+ // Linke Spalte
+ GetAutoFormatAttr(nStartCol, nStartRow + 1, 4, rData);
+ GetAutoFormatAttr(nStartCol, nStartRow + 2, 8, rData);
+ GetAutoFormatFrame(nStartCol, nStartRow + 1, LF_LEFT | LF_RIGHT | LF_BOTTOM, 4, rData);
+ if (nEndRow - nStartRow >= 4)
+ GetAutoFormatFrame(nStartCol, nStartRow + 2, LF_LEFT | LF_RIGHT | LF_BOTTOM, 8, rData);
+ else
+ rData.CopyItem( 8, 4, ATTR_BORDER );
+ // Linke untere Ecke
+ GetAutoFormatAttr(nStartCol, nEndRow, 12, rData);
+ GetAutoFormatFrame(nStartCol, nEndRow, LF_ALL, 12, rData);
+ // Rechte obere Ecke
+ GetAutoFormatAttr(nEndCol, nStartRow, 3, rData);
+ GetAutoFormatFrame(nEndCol, nStartRow, LF_ALL, 3, rData);
+ // Rechte Spalte
+ GetAutoFormatAttr(nEndCol, nStartRow + 1, 7, rData);
+ GetAutoFormatAttr(nEndCol, nStartRow + 2, 11, rData);
+ GetAutoFormatFrame(nEndCol, nStartRow + 1, LF_LEFT | LF_RIGHT | LF_BOTTOM, 7, rData);
+ if (nEndRow - nStartRow >= 4)
+ GetAutoFormatFrame(nEndCol, nStartRow + 2, LF_LEFT | LF_RIGHT | LF_BOTTOM, 11, rData);
+ else
+ rData.CopyItem( 11, 7, ATTR_BORDER );
+ // Rechte untere Ecke
+ GetAutoFormatAttr(nEndCol, nEndRow, 15, rData);
+ GetAutoFormatFrame(nEndCol, nEndRow, LF_ALL, 15, rData);
+ // Ober Zeile
+ GetAutoFormatAttr(nStartCol + 1, nStartRow, 1, rData);
+ GetAutoFormatAttr(nStartCol + 2, nStartRow, 2, rData);
+ GetAutoFormatFrame(nStartCol + 1, nStartRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 1, rData);
+ if (nEndCol - nStartCol >= 4)
+ GetAutoFormatFrame(nStartCol + 2, nStartRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 2, rData);
+ else
+ rData.CopyItem( 2, 1, ATTR_BORDER );
+ // Untere Zeile
+ GetAutoFormatAttr(nStartCol + 1, nEndRow, 13, rData);
+ GetAutoFormatAttr(nStartCol + 2, nEndRow, 14, rData);
+ GetAutoFormatFrame(nStartCol + 1, nEndRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 13, rData);
+ if (nEndCol - nStartCol >= 4)
+ GetAutoFormatFrame(nStartCol + 2, nEndRow, LF_TOP | LF_BOTTOM | LF_RIGHT, 14, rData);
+ else
+ rData.CopyItem( 14, 13, ATTR_BORDER );
+ // Body
+ GetAutoFormatAttr(nStartCol + 1, nStartRow + 1, 5, rData);
+ GetAutoFormatAttr(nStartCol + 2, nStartRow + 1, 6, rData);
+ GetAutoFormatAttr(nStartCol + 1, nStartRow + 2, 9, rData);
+ GetAutoFormatAttr(nStartCol + 2, nStartRow + 2, 10, rData);
+ GetAutoFormatFrame(nStartCol + 1, nStartRow + 1, LF_RIGHT | LF_BOTTOM, 5, rData);
+ if ((nEndCol - nStartCol >= 4) && (nEndRow - nStartRow >= 4))
+ {
+ GetAutoFormatFrame(nStartCol + 2, nStartRow + 1, LF_RIGHT | LF_BOTTOM, 6, rData);
+ GetAutoFormatFrame(nStartCol + 1, nStartRow + 2, LF_RIGHT | LF_BOTTOM, 9, rData);
+ GetAutoFormatFrame(nStartCol + 2, nStartRow + 2, LF_RIGHT | LF_BOTTOM, 10, rData);
+ }
+ else
+ {
+ rData.CopyItem( 6, 5, ATTR_BORDER );
+ rData.CopyItem( 9, 5, ATTR_BORDER );
+ rData.CopyItem( 10, 5, ATTR_BORDER );
+ }
+ }
+ }
+}
+
+void ScTable::SetError( SCCOL nCol, SCROW nRow, USHORT nError)
+{
+ if (ValidColRow(nCol, nRow))
+ aCol[nCol].SetError( nRow, nError );
+}
+
+void ScTable::UpdateInsertTabAbs(SCTAB nTable)
+{
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ aCol[i].UpdateInsertTabAbs(nTable);
+}
+
+//UNUSED2008-05 USHORT ScTable::GetErrorData( SCCOL nCol, SCROW nRow ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 if (ValidColRow(nCol,nRow))
+//UNUSED2008-05 return aCol[nCol].GetErrorData( nRow );
+//UNUSED2008-05 else
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+BOOL ScTable::GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, BOOL bInSel,
+ const ScMarkData& rMark) const
+{
+ if (rRow == MAXROW+2) // Tabellenende
+ {
+ rRow = 0;
+ rCol = 0;
+ }
+ else
+ {
+ rRow++;
+ if (rRow == MAXROW+1)
+ {
+ rCol++;
+ rRow = 0;
+ }
+ }
+ if (rCol == MAXCOL+1)
+ return TRUE;
+ else
+ {
+ BOOL bStop = FALSE;
+ while (!bStop)
+ {
+ if (ValidCol(rCol))
+ {
+ bStop = aCol[rCol].GetNextSpellingCell(rRow, bInSel, rMark);
+ if (bStop)
+ return TRUE;
+ else /*if (rRow == MAXROW+1) */
+ {
+ rCol++;
+ rRow = 0;
+ }
+ }
+ else
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void ScTable::RemoveAutoSpellObj()
+{
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ aCol[i].RemoveAutoSpellObj();
+}
+
+BOOL ScTable::TestTabRefAbs(SCTAB nTable)
+{
+ BOOL bRet = FALSE;
+ for (SCCOL i=0; i <= MAXCOL; i++)
+ if (aCol[i].TestTabRefAbs(nTable))
+ bRet = TRUE;
+ return bRet;
+}
+
+void ScTable::CompileDBFormula()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula();
+}
+
+void ScTable::CompileDBFormula( BOOL bCreateFormulaString )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula( bCreateFormulaString );
+}
+
+void ScTable::CompileNameFormula( BOOL bCreateFormulaString )
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileNameFormula( bCreateFormulaString );
+}
+
+void ScTable::CompileColRowNameFormula()
+{
+ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula();
+}
+
+
+
+
+
+
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
new file mode 100644
index 000000000000..7c13756aab38
--- /dev/null
+++ b/sc/source/core/data/table5.cxx
@@ -0,0 +1,1195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include "collect.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "cell.hxx"
+#include "table.hxx"
+#include "column.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "olinetab.hxx"
+#include "userlist.hxx"
+#include "stlsheet.hxx"
+#include "global.hxx"
+#include "rechead.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "brdcst.hxx"
+#include "tabprotection.hxx"
+#include "globstr.hrc"
+#include "segmenttree.hxx"
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+
+#include <algorithm>
+#include <limits>
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::sheet::TablePageBreakData;
+using ::std::set;
+
+// STATIC DATA -----------------------------------------------------------
+
+#define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
+
+
+void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
+{
+ if ( pDocument->IsImportingXML() )
+ return;
+
+ // pUserArea != NULL -> print area is specified. We need to force-update
+ // the page breaks.
+
+ if (!pUserArea)
+ {
+ if (!bPageSizeValid)
+ return;
+
+ if (mbPageBreaksValid)
+ return;
+ }
+
+ SfxStyleSheetBase* pStyle = pDocument->GetStyleSheetPool()->
+ Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+ if ( !pStyle )
+ {
+ DBG_ERROR("UpdatePageBreaks: Style nicht gefunden");
+ return;
+ }
+ SfxItemSet* pStyleSet = &pStyle->GetItemSet();
+ const SfxPoolItem* pItem;
+
+ SCCOL nX;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+ if (pUserArea)
+ {
+ nStartCol = pUserArea->aStart.Col();
+ nStartRow = pUserArea->aStart.Row();
+ nEndCol = pUserArea->aEnd.Col();
+ nEndRow = pUserArea->aEnd.Row();
+ }
+ else
+ {
+ USHORT nAreaCount = GetPrintRangeCount();
+ if ( nAreaCount > 1 )
+ {
+ // bei mehreren Bereichen nichts anzeigen:
+
+ for (nX=0; nX<MAXCOL; nX++)
+ RemoveColBreak(nX, true, false);
+
+ RemoveRowPageBreaks(0, MAXROW-1);
+
+ return;
+ }
+ else if ( nAreaCount == 1 )
+ {
+ const ScRange* pArea = GetPrintRange( 0 );
+ if (pArea)
+ {
+ nStartCol = pArea->aStart.Col();
+ nStartRow = pArea->aStart.Row();
+ nEndCol = pArea->aEnd.Col();
+ nEndRow = pArea->aEnd.Row();
+ }
+ } // sonst alles
+ }
+
+ // get bSkipColBreaks/bSkipRowBreaks flags:
+
+ bool bSkipColBreaks = false;
+ bool bSkipRowBreaks = false;
+
+ if ( pStyleSet->GetItemState( ATTR_PAGE_SCALETOPAGES, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ DBG_ASSERT( pItem->ISA(SfxUInt16Item), "falsches Item" );
+ bSkipColBreaks = bSkipRowBreaks = ( ((const SfxUInt16Item*)pItem)->GetValue() > 0 );
+ }
+
+ if ( !bSkipColBreaks && pStyleSet->GetItemState(ATTR_PAGE_SCALETO, FALSE, &pItem) == SFX_ITEM_SET )
+ {
+ // #i54993# when fitting to width or height, ignore only manual breaks in that direction
+ const ScPageScaleToItem* pScaleToItem = static_cast<const ScPageScaleToItem*>(pItem);
+ if ( pScaleToItem->GetWidth() > 0 )
+ bSkipColBreaks = true;
+ if ( pScaleToItem->GetHeight() > 0 )
+ bSkipRowBreaks = true;
+ }
+
+ //--------------------------------------------------------------------------
+
+ long nPageSizeX = aPageSizeTwips.Width();
+ long nPageSizeY = aPageSizeTwips.Height();
+
+ // Anfang: Breaks loeschen
+
+ for (nX=0; nX<nStartCol; nX++)
+ RemoveColBreak(nX, true, false);
+ RemoveRowPageBreaks(0, nStartRow-1);
+
+ if (nStartCol > 0)
+ SetColBreak(nStartCol, true, false); // AREABREAK
+ if (nStartRow > 0)
+ SetRowBreak(nStartRow, true, false); // AREABREAK
+
+ // Mittelteil: Breaks verteilen
+
+ BOOL bRepeatCol = ( nRepeatStartX != SCCOL_REPEAT_NONE );
+ BOOL bColFound = FALSE;
+ long nSizeX = 0;
+ for (nX=nStartCol; nX<=nEndCol; nX++)
+ {
+ BOOL bStartOfPage = FALSE;
+ long nThisX = ColHidden(nX) ? 0 : pColWidth[nX];
+ bool bManualBreak = HasColManualBreak(nX);
+ if ( (nSizeX+nThisX > nPageSizeX) || (bManualBreak && !bSkipColBreaks) )
+ {
+ SetColBreak(nX, true, false);
+ nSizeX = 0;
+ bStartOfPage = TRUE;
+ }
+ else if (nX != nStartCol)
+ RemoveColBreak(nX, true, false);
+ else
+ bStartOfPage = TRUE;
+
+ if ( bStartOfPage && bRepeatCol && nX>nRepeatStartX && !bColFound )
+ {
+ // subtract size of repeat columns from page size
+ for (SCCOL i=nRepeatStartX; i<=nRepeatEndX; i++)
+ nPageSizeX -= ColHidden(i) ? 0 : pColWidth[i];
+ while (nX<=nRepeatEndX)
+ RemoveColBreak(++nX, true, false);
+ bColFound = TRUE;
+ }
+
+ nSizeX += nThisX;
+ }
+
+ // Remove all page breaks in range.
+ RemoveRowPageBreaks(nStartRow+1, nEndRow);
+
+ // And set new page breaks.
+ BOOL bRepeatRow = ( nRepeatStartY != SCROW_REPEAT_NONE );
+ BOOL bRowFound = FALSE;
+ long nSizeY = 0;
+ ScFlatBoolRowSegments::ForwardIterator aIterHidden(*mpHiddenRows);
+ ScFlatUInt16RowSegments::ForwardIterator aIterHeights(*mpRowHeights);
+ SCROW nNextManualBreak = GetNextManualBreak(nStartRow); // -1 => no more manual breaks
+ for (SCROW nY = nStartRow; nY <= nEndRow; ++nY)
+ {
+ BOOL bStartOfPage = FALSE;
+ bool bThisRowHidden = false;
+ aIterHidden.getValue(nY, bThisRowHidden);
+ long nThisY = 0;
+ if (!bThisRowHidden)
+ {
+ sal_uInt16 nTmp;
+ aIterHeights.getValue(nY, nTmp);
+ nThisY = static_cast<long>(nTmp);
+ }
+
+ bool bManualBreak = false;
+ if (nNextManualBreak >= 0)
+ {
+ bManualBreak = (nY == nNextManualBreak);
+ if (nY >= nNextManualBreak)
+ // Query the next menual break position.
+ nNextManualBreak = GetNextManualBreak(nY+1);
+ }
+
+ if ( (nSizeY+nThisY > nPageSizeY) || (bManualBreak && !bSkipRowBreaks) )
+ {
+ SetRowBreak(nY, true, false);
+ nSizeY = 0;
+ bStartOfPage = TRUE;
+ }
+ else if (nY != nStartRow)
+ ; // page break already removed
+ else
+ bStartOfPage = TRUE;
+
+ if ( bStartOfPage && bRepeatRow && nY>nRepeatStartY && !bRowFound )
+ {
+ // subtract size of repeat rows from page size
+ unsigned long nHeights = GetTotalRowHeight(nRepeatStartY, nRepeatEndY);
+#ifdef DBG_UTIL
+ if (nHeights == ::std::numeric_limits<unsigned long>::max())
+ DBG_ERRORFILE("ScTable::UpdatePageBreaks: row heights overflow");
+#endif
+ nPageSizeY -= nHeights;
+ if (nY <= nRepeatEndY)
+ RemoveRowPageBreaks(nY, nRepeatEndY);
+ bRowFound = TRUE;
+ }
+
+ if (bThisRowHidden)
+ {
+ // Hidden row range. Skip them unless there is a manual break.
+ SCROW nLastCommon = aIterHidden.getLastPos();
+ if (nNextManualBreak >= 0)
+ nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1);
+ nY = nLastCommon;
+ }
+ else
+ {
+ // Visible row range.
+
+ SCROW nLastHidden = aIterHidden.getLastPos();
+ SCROW nLastHeight = aIterHeights.getLastPos();
+ SCROW nLastCommon = ::std::min(nLastHidden, nLastHeight);
+ if (nNextManualBreak >= 0)
+ nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1);
+
+ if (nLastCommon > nY)
+ {
+ long nMaxMultiple = static_cast<long>(nLastCommon - nY);
+ long nMultiple = (nPageSizeY - nSizeY) / nThisY;
+ if (nMultiple > nMaxMultiple)
+ nMultiple = nMaxMultiple;
+ if (nMultiple > 1)
+ {
+ nSizeY += nThisY * (nMultiple - 1);
+ nY += nMultiple - 1;
+ }
+ }
+ }
+
+ nSizeY += nThisY;
+ }
+
+ // Ende: Breaks loeschen
+
+ if (nEndCol < MAXCOL)
+ {
+ SetColBreak(nEndCol+1, true, false); // AREABREAK
+ for (nX=nEndCol+2; nX<=MAXCOL; nX++)
+ RemoveColBreak(nX, true, false);
+ }
+ if (nEndRow < MAXROW)
+ {
+ SetRowBreak(nEndRow+1, true, false); // AREABREAK
+ if (nEndRow+2 <= MAXROW)
+ RemoveRowPageBreaks(nEndRow+2, MAXROW);
+ }
+ mbPageBreaksValid = true;
+}
+
+void ScTable::RemoveManualBreaks()
+{
+ maRowManualBreaks.clear();
+ maColManualBreaks.clear();
+ InvalidatePageBreaks();
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+BOOL ScTable::HasManualBreaks() const
+{
+ return !maRowManualBreaks.empty() || !maColManualBreaks.empty();
+}
+
+void ScTable::SetRowManualBreaks( const ::std::set<SCROW>& rBreaks )
+{
+ maRowManualBreaks = rBreaks;
+ InvalidatePageBreaks();
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::SetColManualBreaks( const ::std::set<SCCOL>& rBreaks )
+{
+ maColManualBreaks = rBreaks;
+ InvalidatePageBreaks();
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+void ScTable::GetAllRowBreaks(set<SCROW>& rBreaks, bool bPage, bool bManual) const
+{
+ if (bPage)
+ rBreaks = maRowPageBreaks;
+
+ if (bManual)
+ {
+ using namespace std;
+ copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
+ }
+}
+
+void ScTable::GetAllColBreaks(set<SCCOL>& rBreaks, bool bPage, bool bManual) const
+{
+ if (bPage)
+ rBreaks = maColPageBreaks;
+
+ if (bManual)
+ {
+ using namespace std;
+ copy(maColManualBreaks.begin(), maColManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
+ }
+}
+
+bool ScTable::HasRowPageBreak(SCROW nRow) const
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ return maRowPageBreaks.find(nRow) != maRowPageBreaks.end();
+}
+
+bool ScTable::HasColPageBreak(SCCOL nCol) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return maColPageBreaks.find(nCol) != maColPageBreaks.end();
+}
+
+bool ScTable::HasRowManualBreak(SCROW nRow) const
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ return maRowManualBreaks.find(nRow) != maRowManualBreaks.end();
+}
+
+bool ScTable::HasColManualBreak(SCCOL nCol) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return maColManualBreaks.find(nCol) != maColManualBreaks.end();
+}
+
+SCROW ScTable::GetNextManualBreak(SCROW nRow) const
+{
+ set<SCROW>::const_iterator itr = maRowManualBreaks.lower_bound(nRow);
+ return itr == maRowManualBreaks.end() ? -1 : *itr;
+}
+
+void ScTable::RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow)
+{
+ using namespace std;
+
+ if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
+ return;
+
+ set<SCROW>::iterator low = maRowPageBreaks.lower_bound(nStartRow);
+ set<SCROW>::iterator high = maRowPageBreaks.upper_bound(nEndRow);
+ maRowPageBreaks.erase(low, high);
+}
+
+void ScTable::RemoveRowBreak(SCROW nRow, bool bPage, bool bManual)
+{
+ if (!ValidRow(nRow))
+ return;
+
+ if (bPage)
+ maRowPageBreaks.erase(nRow);
+
+ if (bManual)
+ {
+ maRowManualBreaks.erase(nRow);
+ InvalidatePageBreaks();
+ }
+}
+
+void ScTable::RemoveColBreak(SCCOL nCol, bool bPage, bool bManual)
+{
+ if (!ValidCol(nCol))
+ return;
+
+ if (bPage)
+ maColPageBreaks.erase(nCol);
+
+ if (bManual)
+ {
+ maColManualBreaks.erase(nCol);
+ InvalidatePageBreaks();
+ }
+}
+
+void ScTable::SetRowBreak(SCROW nRow, bool bPage, bool bManual)
+{
+ if (!ValidRow(nRow))
+ return;
+
+ if (bPage)
+ maRowPageBreaks.insert(nRow);
+
+ if (bManual)
+ {
+ maRowManualBreaks.insert(nRow);
+ InvalidatePageBreaks();
+ }
+}
+
+void ScTable::SetColBreak(SCCOL nCol, bool bPage, bool bManual)
+{
+ if (!ValidCol(nCol))
+ return;
+
+ if (bPage)
+ maColPageBreaks.insert(nCol);
+
+ if (bManual)
+ {
+ maColManualBreaks.insert(nCol);
+ InvalidatePageBreaks();
+ }
+}
+
+Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
+{
+ using ::std::copy;
+ using ::std::inserter;
+
+ set<SCROW> aRowBreaks = maRowPageBreaks;
+ copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(aRowBreaks, aRowBreaks.begin()));
+
+ set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end();
+ Sequence<TablePageBreakData> aSeq(aRowBreaks.size());
+
+ for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i)
+ {
+ SCROW nRow = *itr;
+ TablePageBreakData aData;
+ aData.Position = nRow;
+ aData.ManualBreak = HasRowManualBreak(nRow);
+ aSeq[i] = aData;
+ }
+
+ return aSeq;
+}
+
+bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
+{
+ if (!ValidRow(nRow))
+ {
+ if (pFirstRow)
+ *pFirstRow = nRow;
+ if (pLastRow)
+ *pLastRow = nRow;
+ return true;
+ }
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ {
+ // search failed.
+ if (pFirstRow)
+ *pFirstRow = nRow;
+ if (pLastRow)
+ *pLastRow = nRow;
+ return true;
+ }
+
+ if (pFirstRow)
+ *pFirstRow = aData.mnRow1;
+ if (pLastRow)
+ *pLastRow = aData.mnRow2;
+
+ return aData.mbValue;
+}
+
+
+bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow) const
+{
+ rLastRow = nRow;
+ if (!ValidRow(nRow))
+ return true;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // search failed.
+ return true;
+
+ rLastRow = aData.mnRow2;
+ return aData.mbValue;
+}
+
+bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ bool bHidden = RowHidden(nRow, nLastRow);
+ if (bHidden)
+ return true;
+
+ nRow = nLastRow + 1;
+ }
+ return false;
+}
+
+bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol) const
+{
+ rLastCol = nCol;
+ if (!ValidCol(nCol))
+ return true;
+
+ ScFlatBoolColSegments::RangeData aData;
+ if (!mpHiddenCols->getRangeData(nCol, aData))
+ return true;
+
+ rLastCol = aData.mnCol2;
+ return aData.mbValue;
+}
+
+bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
+{
+ if (!ValidCol(nCol))
+ return true;
+
+ ScFlatBoolColSegments::RangeData aData;
+ if (!mpHiddenCols->getRangeData(nCol, aData))
+ return true;
+
+ if (pFirstCol)
+ *pFirstCol = aData.mnCol1;
+ if (pLastCol)
+ *pLastCol = aData.mnCol2;
+
+ return aData.mbValue;
+}
+
+void ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
+{
+ if (bHidden)
+ mpHiddenRows->setTrue(nStartRow, nEndRow);
+ else
+ mpHiddenRows->setFalse(nStartRow, nEndRow);
+}
+
+void ScTable::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden)
+{
+ if (bHidden)
+ mpHiddenCols->setTrue(nStartCol, nEndCol);
+ else
+ mpHiddenCols->setFalse(nStartCol, nEndCol);
+}
+
+void ScTable::CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
+{
+ SCCOL nCol = nStartCol;
+ while (nCol <= nEndCol)
+ {
+ SCCOL nLastCol;
+ bool bHidden = rTable.ColHidden(nCol, NULL, &nLastCol);
+ if (nLastCol > nEndCol)
+ nLastCol = nEndCol;
+
+ SetColHidden(nCol, nLastCol, bHidden);
+ nCol = nLastCol + 1;
+ }
+}
+
+void ScTable::CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ bool bHidden = rTable.RowHidden(nRow, nLastRow);
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ SetRowHidden(nRow, nLastRow, bHidden);
+ nRow = nLastRow + 1;
+ }
+}
+
+void ScTable::CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset)
+{
+ SCROW nRow = nStartRow;
+ ScFlatUInt16RowSegments::RangeData aSrcData;
+ while (nRow <= nEndRow)
+ {
+ if (!rSrcTable.mpRowHeights->getRangeData(nRow + nSrcOffset, aSrcData))
+ // Something is wrong !
+ return;
+
+ SCROW nLastRow = aSrcData.mnRow2 - nSrcOffset;
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+
+ mpRowHeights->setValue(nRow, nLastRow, aSrcData.mnValue);
+ nRow = nLastRow + 1;
+ }
+}
+
+SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // visible row found
+ return nRow;
+
+ nRow = aData.mnRow2 + 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nRow = nEndRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow >= nStartRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // visible row found
+ return nRow;
+
+ nRow = aData.mnRow1 - 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nCount = 0;
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mnRow2 > nEndRow)
+ aData.mnRow2 = nEndRow;
+
+ if (!aData.mbValue)
+ nCount += aData.mnRow2 - nRow + 1;
+
+ nRow = aData.mnRow2 + 1;
+ }
+ return nCount;
+}
+
+sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const
+{
+ sal_uInt32 nHeight = 0;
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mnRow2 > nEndRow)
+ aData.mnRow2 = nEndRow;
+
+ if (!aData.mbValue)
+ // visible row range.
+ nHeight += mpRowHeights->getSumValue(nRow, aData.mnRow2);
+
+ nRow = aData.mnRow2 + 1;
+ }
+
+ return nHeight;
+}
+
+SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol) const
+{
+ if (bCol)
+ {
+ SCCOL nCol = static_cast<SCCOL>(nPos);
+ if (ColHidden(nCol))
+ {
+ for (SCCOL i = nCol+1; i <= MAXCOL; ++i)
+ {
+ if (!ColHidden(nCol))
+ return nCol - 1;
+ }
+ }
+ }
+ else
+ {
+ SCROW nRow = static_cast<SCROW>(nPos);
+ SCROW nLastRow;
+ if (RowHidden(nRow, NULL, &nLastRow))
+ return static_cast<SCCOLROW>(nLastRow);
+ }
+ return ::std::numeric_limits<SCCOLROW>::max();
+}
+
+bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ // search failed.
+ return false;
+
+ if (pFirstRow)
+ *pFirstRow = aData.mnRow1;
+ if (pLastRow)
+ *pLastRow = aData.mnRow2;
+
+ return aData.mbValue;
+}
+
+bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ ScFlatBoolColSegments::RangeData aData;
+ if (!mpFilteredCols->getRangeData(nCol, aData))
+ // search failed.
+ return false;
+
+ if (pFirstCol)
+ *pFirstCol = aData.mnCol1;
+ if (pLastCol)
+ *pLastCol = aData.mnCol2;
+
+ return aData.mbValue;
+}
+
+bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = nRow;
+ bool bFiltered = RowFiltered(nRow, NULL, &nLastRow);
+ if (bFiltered)
+ return true;
+
+ nRow = nLastRow + 1;
+ }
+ return false;
+}
+
+void ScTable::CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
+{
+ SCCOL nCol = nStartCol;
+ while (nCol <= nEndCol)
+ {
+ SCCOL nLastCol;
+ bool bFiltered = rTable.ColFiltered(nCol, NULL, &nLastCol);
+ if (nLastCol > nEndCol)
+ nLastCol = nEndCol;
+
+ SetColFiltered(nCol, nLastCol, bFiltered);
+ nCol = nLastCol + 1;
+ }
+}
+
+void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ bool bFiltered = rTable.RowFiltered(nRow, NULL, &nLastRow);
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ SetRowFiltered(nRow, nLastRow, bFiltered);
+ nRow = nLastRow + 1;
+ }
+}
+
+void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered)
+{
+ if (bFiltered)
+ mpFilteredRows->setTrue(nStartRow, nEndRow);
+ else
+ mpFilteredRows->setFalse(nStartRow, nEndRow);
+}
+
+void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
+{
+ if (bFiltered)
+ mpFilteredCols->setTrue(nStartCol, nEndCol);
+ else
+ mpFilteredCols->setFalse(nStartCol, nEndCol);
+}
+
+SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // non-filtered row found
+ return nRow;
+
+ nRow = aData.mnRow2 + 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nRow = nEndRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow >= nStartRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // non-filtered row found
+ return nRow;
+
+ nRow = aData.mnRow1 - 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const
+{
+ SCROW nCount = 0;
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mnRow2 > nEndRow)
+ aData.mnRow2 = nEndRow;
+
+ if (!aData.mbValue)
+ nCount += aData.mnRow2 - nRow + 1;
+
+ nRow = aData.mnRow2 + 1;
+ }
+ return nCount;
+}
+
+namespace {
+
+void lcl_syncFlags(ScFlatBoolColSegments& rColSegments, ScFlatBoolRowSegments& rRowSegments,
+ BYTE* pColFlags, ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, const BYTE nFlagMask)
+{
+ using ::sal::static_int_cast;
+
+ pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~nFlagMask));
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ pColFlags[i] &= static_int_cast<BYTE>(~nFlagMask);
+
+ {
+ // row hidden flags.
+
+ SCROW nRow = 0;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= MAXROW)
+ {
+ if (!rRowSegments.getRangeData(nRow, aData))
+ break;
+
+ if (aData.mbValue)
+ pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast<BYTE>(nFlagMask));
+
+ nRow = aData.mnRow2 + 1;
+ }
+ }
+
+ {
+ // column hidden flags.
+
+ SCCOL nCol = 0;
+ ScFlatBoolColSegments::RangeData aData;
+ while (nCol <= MAXCOL)
+ {
+ if (!rColSegments.getRangeData(nCol, aData))
+ break;
+
+ if (aData.mbValue)
+ {
+ for (SCCOL i = nCol; i <= aData.mnCol2; ++i)
+ pColFlags[i] |= nFlagMask;
+ }
+
+ nCol = aData.mnCol2 + 1;
+ }
+ }
+}
+
+}
+
+void ScTable::SyncColRowFlags()
+{
+ using ::sal::static_int_cast;
+
+ // Manual breaks.
+ pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK));
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK);
+
+ if (!maRowManualBreaks.empty())
+ {
+ for (set<SCROW>::const_iterator itr = maRowManualBreaks.begin(), itrEnd = maRowManualBreaks.end();
+ itr != itrEnd; ++itr)
+ pRowFlags->OrValue(*itr, static_int_cast<BYTE>(CR_MANUALBREAK));
+ }
+
+ if (!maColManualBreaks.empty())
+ {
+ for (set<SCCOL>::const_iterator itr = maColManualBreaks.begin(), itrEnd = maColManualBreaks.end();
+ itr != itrEnd; ++itr)
+ pColFlags[*itr] |= CR_MANUALBREAK;
+ }
+
+ // Hidden flags.
+ lcl_syncFlags(*mpHiddenCols, *mpHiddenRows, pColFlags, pRowFlags, CR_HIDDEN);
+ lcl_syncFlags(*mpFilteredCols, *mpFilteredRows, pColFlags, pRowFlags, CR_FILTERED);
+}
+
+void ScTable::SetPageSize( const Size& rSize )
+{
+ if ( rSize.Width() != 0 && rSize.Height() != 0 )
+ {
+ if (aPageSizeTwips != rSize)
+ InvalidatePageBreaks();
+
+ bPageSizeValid = TRUE;
+ aPageSizeTwips = rSize;
+ }
+ else
+ 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);
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+ScTableProtection* ScTable::GetProtection()
+{
+ return pTabProtection.get();
+}
+
+Size ScTable::GetPageSize() const
+{
+ if ( bPageSizeValid )
+ return aPageSizeTwips;
+ else
+ return Size(); // leer
+}
+
+void ScTable::SetRepeatArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow )
+{
+ nRepeatStartX = nStartCol;
+ nRepeatEndX = nEndCol;
+ nRepeatStartY = nStartRow;
+ nRepeatEndY = nEndRow;
+}
+
+void ScTable::StartListening( const ScAddress& rAddress, SvtListener* pListener )
+{
+ aCol[rAddress.Col()].StartListening( *pListener, rAddress.Row() );
+}
+
+void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener )
+{
+ aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() );
+}
+
+void ScTable::SetPageStyle( const String& rName )
+{
+ if ( aPageStyle != rName )
+ {
+ String aStrNew = rName;
+ SfxStyleSheetBasePool* pStylePool = pDocument->GetStyleSheetPool();
+ SfxStyleSheetBase* pNewStyle = pStylePool->Find( aStrNew, SFX_STYLE_FAMILY_PAGE );
+
+ if ( !pNewStyle )
+ {
+ aStrNew = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
+ pNewStyle = pStylePool->Find( aStrNew, SFX_STYLE_FAMILY_PAGE );
+ }
+
+ if ( aPageStyle != aStrNew )
+ {
+ SfxStyleSheetBase* pOldStyle = pStylePool->Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+
+ if ( pOldStyle && pNewStyle )
+ {
+ SfxItemSet& rOldSet = pOldStyle->GetItemSet();
+ SfxItemSet& rNewSet = pNewStyle->GetItemSet();
+ const USHORT nOldScale = GET_SCALEVALUE(rOldSet,ATTR_PAGE_SCALE);
+ const USHORT nOldScaleToPages = GET_SCALEVALUE(rOldSet,ATTR_PAGE_SCALETOPAGES);
+ const USHORT nNewScale = GET_SCALEVALUE(rNewSet,ATTR_PAGE_SCALE);
+ const USHORT nNewScaleToPages = GET_SCALEVALUE(rNewSet,ATTR_PAGE_SCALETOPAGES);
+
+ if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) )
+ InvalidateTextWidth(NULL, NULL, FALSE, FALSE);
+ }
+
+ if ( pNewStyle ) // auch ohne den alten (fuer UpdateStdNames)
+ aPageStyle = aStrNew;
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+ }
+ }
+}
+
+void ScTable::PageStyleModified( const String& rNewName )
+{
+ aPageStyle = rNewName;
+ InvalidateTextWidth(NULL, NULL, FALSE, FALSE); // don't know what was in the style before
+}
+
+void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
+ BOOL bNumFormatChanged, BOOL bBroadcast )
+{
+ if ( pAdrFrom && !pAdrTo )
+ {
+ ScBaseCell* pCell = aCol[pAdrFrom->Col()].GetCell( pAdrFrom->Row() );
+ if ( pCell )
+ {
+ pCell->SetTextWidth( TEXTWIDTH_DIRTY );
+ if ( bNumFormatChanged )
+ pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+ if ( bBroadcast )
+ { // nur bei CalcAsShown
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ pDocument->Broadcast( SC_HINT_DATACHANGED,
+ ScAddress( pAdrFrom->Col(), pAdrFrom->Row(), nTab ),
+ pCell );
+ break;
+ case CELLTYPE_FORMULA :
+ ((ScFormulaCell*)pCell)->SetDirty();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ const SCCOL nColStart = pAdrFrom ? pAdrFrom->Col() : 0;
+ const SCROW nRowStart = pAdrFrom ? pAdrFrom->Row() : 0;
+ const SCCOL nColEnd = pAdrTo ? pAdrTo->Col() : MAXCOL;
+ const SCROW nRowEnd = pAdrTo ? pAdrTo->Row() : MAXROW;
+
+ for ( SCCOL nCol=nColStart; nCol<=nColEnd; nCol++ )
+ {
+ ScColumnIterator aIter( &aCol[nCol], nRowStart, nRowEnd );
+ ScBaseCell* pCell = NULL;
+ SCROW nRow = nRowStart;
+
+ while ( aIter.Next( nRow, pCell ) )
+ {
+ pCell->SetTextWidth( TEXTWIDTH_DIRTY );
+ if ( bNumFormatChanged )
+ pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+ if ( bBroadcast )
+ { // nur bei CalcAsShown
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ pDocument->Broadcast( SC_HINT_DATACHANGED,
+ ScAddress( nCol, nRow, nTab ), pCell );
+ break;
+ case CELLTYPE_FORMULA :
+ ((ScFormulaCell*)pCell)->SetDirty();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
new file mode 100644
index 000000000000..500ac1bb3614
--- /dev/null
+++ b/sc/source/core/data/table6.cxx
@@ -0,0 +1,690 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/i18n/TransliterationModules.hpp>
+
+#include <unotools/textsearch.hxx>
+#include <svl/srchitem.hxx>
+#include <editeng/editobj.hxx>
+
+#include "table.hxx"
+#include "collect.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "markdata.hxx"
+#include "editutil.hxx"
+#include "detfunc.hxx"
+#include "postit.hxx"
+
+//--------------------------------------------------------------------------
+
+
+BOOL lcl_GetTextWithBreaks( const ScEditCell& rCell, ScDocument* pDoc, String& rVal )
+{
+ // TRUE = more than 1 paragraph
+
+ const EditTextObject* pData = NULL;
+ rCell.GetData( pData );
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ rVal = rEngine.GetText( LINEEND_LF );
+ return ( rEngine.GetParagraphCount() > 1 );
+}
+
+BOOL ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRow,
+ const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
+{
+ BOOL bFound = FALSE;
+ BOOL bDoSearch = TRUE;
+ BOOL bDoBack = rSearchItem.GetBackward();
+
+ String aString;
+ ScBaseCell* pCell;
+ if (rSearchItem.GetSelection())
+ bDoSearch = rMark.IsCellMarked(nCol, nRow);
+ if ( bDoSearch && ((pCell = aCol[nCol].GetCell( nRow )) != NULL) )
+ {
+ BOOL bMultiLine = FALSE;
+ CellType eCellType = pCell->GetCellType();
+ switch (rSearchItem.GetCellType())
+ {
+ case SVX_SEARCHIN_FORMULA:
+ {
+ if ( eCellType == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->GetFormula( aString,
+ formula::FormulaGrammar::GRAM_NATIVE_UI);
+ else if ( eCellType == CELLTYPE_EDIT )
+ bMultiLine = lcl_GetTextWithBreaks(
+ *(const ScEditCell*)pCell, pDocument, aString );
+ else
+ aCol[nCol].GetInputString( nRow, aString );
+ }
+ break;
+ case SVX_SEARCHIN_VALUE:
+ if ( eCellType == CELLTYPE_EDIT )
+ bMultiLine = lcl_GetTextWithBreaks(
+ *(const ScEditCell*)pCell, pDocument, aString );
+ else
+ aCol[nCol].GetInputString( nRow, aString );
+ break;
+ case SVX_SEARCHIN_NOTE:
+ {
+ if(const ScPostIt* pNote = pCell->GetNote())
+ {
+ aString = pNote->GetText();
+ bMultiLine = pNote->HasMultiLineText();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ xub_StrLen nStart = 0;
+ xub_StrLen nEnd = aString.Len();
+ ::com::sun::star::util::SearchResult aSearchResult;
+ if (pSearchText)
+ {
+ if ( bDoBack )
+ {
+ xub_StrLen nTemp=nStart; nStart=nEnd; nEnd=nTemp;
+ bFound = (BOOL)(pSearchText->SearchBkwrd(aString, &nStart, &nEnd, &aSearchResult));
+ // change results to definition before 614:
+ --nEnd;
+ }
+ else
+ {
+ bFound = (BOOL)(pSearchText->SearchFrwrd(aString, &nStart, &nEnd, &aSearchResult));
+ // change results to definition before 614:
+ --nEnd;
+ }
+
+ if (bFound && rSearchItem.GetWordOnly())
+ bFound = (nStart == 0 && nEnd == aString.Len() - 1);
+ }
+ else
+ {
+ DBG_ERROR("pSearchText == NULL");
+ return bFound;
+ }
+
+ BYTE cMatrixFlag = MM_NONE;
+ if ( bFound &&
+ ( (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE)
+ ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) ) &&
+ // #60558# Matrix nicht zerreissen, nur Matrixformel ersetzen
+ !( (eCellType == CELLTYPE_FORMULA &&
+ ((cMatrixFlag = ((ScFormulaCell*)pCell)->GetMatrixFlag()) == MM_REFERENCE))
+ // kein UndoDoc => Matrix nicht wiederherstellbar => nicht ersetzen
+ || (cMatrixFlag != MM_NONE && !pUndoDoc) )
+ )
+ {
+ if ( cMatrixFlag == MM_NONE && rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE )
+ rUndoStr = aString;
+ else if (pUndoDoc)
+ {
+ ScAddress aAdr( nCol, nRow, nTab );
+ ScBaseCell* pUndoCell = pCell->CloneWithoutNote( *pUndoDoc );
+ pUndoDoc->PutCell( aAdr, pUndoCell);
+ }
+ BOOL bRepeat = !rSearchItem.GetWordOnly();
+ do
+ {
+ // wenn der gefundene Text leer ist, nicht weitersuchen,
+ // sonst wuerde man nie mehr aufhoeren (#35410#)
+ if ( nEnd < nStart || nEnd == STRING_MAXLEN )
+ bRepeat = FALSE;
+
+ String sReplStr = rSearchItem.GetReplaceString();
+ if (rSearchItem.GetRegExp())
+ {
+ String sFndStr = aString.Copy(nStart, nEnd-nStart+1);
+ pSearchText->ReplaceBackReferences( sReplStr, aString, aSearchResult );
+ aString.Erase(nStart, nEnd-nStart+1);
+ aString.Insert(sReplStr, nStart);
+ }
+ else
+ {
+ aString.Erase(nStart, nEnd - nStart + 1);
+ aString.Insert(rSearchItem.GetReplaceString(), nStart);
+ }
+
+ // Indizes anpassen
+ if (bDoBack)
+ {
+ nEnd = nStart;
+ nStart = 0;
+ }
+ else
+ {
+ nStart = sal::static_int_cast<xub_StrLen>( nStart + sReplStr.Len() );
+ nEnd = aString.Len();
+ }
+
+ // weitersuchen ?
+ if (bRepeat)
+ {
+ if ( rSearchItem.GetCommand() != SVX_SEARCHCMD_REPLACE_ALL || nStart >= nEnd )
+ bRepeat = FALSE;
+ else if (bDoBack)
+ {
+ xub_StrLen nTemp=nStart; nStart=nEnd; nEnd=nTemp;
+ bRepeat = ((BOOL)(pSearchText->SearchBkwrd(aString, &nStart, &nEnd)));
+ // change results to definition before 614:
+ --nEnd;
+ }
+ else
+ {
+ bRepeat = ((BOOL)(pSearchText->SearchFrwrd(aString, &nStart, &nEnd)));
+ // change results to definition before 614:
+ --nEnd;
+ }
+ }
+ }
+ while (bRepeat);
+ if (rSearchItem.GetCellType() == SVX_SEARCHIN_NOTE)
+ {
+ // NB: rich text format is lost.
+ // This is also true of Cells.
+ if( ScPostIt* pNote = pCell->GetNote() )
+ pNote->SetText( ScAddress( nCol, nRow, nTab ), aString );
+ }
+ else if ( cMatrixFlag != MM_NONE )
+ { // #60558# Matrix nicht zerreissen
+ if ( aString.Len() > 2 )
+ { // {} raus, erst hier damit auch "{=" durch "{=..." ersetzt werden kann
+ if ( aString.GetChar( aString.Len()-1 ) == '}' )
+ aString.Erase( aString.Len()-1, 1 );
+ if ( aString.GetChar(0) == '{' )
+ aString.Erase( 0, 1 );
+ }
+ ScAddress aAdr( nCol, nRow, nTab );
+ ScFormulaCell* pFCell = new ScFormulaCell( pDocument, aAdr,
+ aString,formula::FormulaGrammar::GRAM_NATIVE_UI, cMatrixFlag );
+ SCCOL nMatCols;
+ SCROW nMatRows;
+ ((ScFormulaCell*)pCell)->GetMatColsRows( nMatCols, nMatRows );
+ pFCell->SetMatColsRows( nMatCols, nMatRows );
+ aCol[nCol].Insert( nRow, pFCell );
+ }
+ else if ( bMultiLine && aString.Search('\n') != STRING_NOTFOUND )
+ PutCell( nCol, nRow, new ScEditCell( aString, pDocument ) );
+ else
+ aCol[nCol].SetString(nRow, nTab, aString);
+ // pCell is invalid now (deleted)
+ }
+ }
+ return bFound;
+}
+
+BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+ const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
+{
+ BOOL bFound = FALSE;
+ BOOL bAll = (rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL)
+ ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL);
+ SCCOL nCol = rCol;
+ SCROW nRow = rRow;
+ SCCOL nLastCol;
+ SCROW nLastRow;
+ GetLastDataPos(nLastCol, nLastRow);
+ if (!bAll && rSearchItem.GetBackward())
+ {
+ nCol = Min(nCol, (SCCOL)(nLastCol + 1));
+ nRow = Min(nRow, (SCROW)(nLastRow + 1));
+ if (rSearchItem.GetRowDirection())
+ {
+ nCol--;
+ while (!bFound && ((SCsROW)nRow >= 0))
+ {
+ while (!bFound && ((SCsCOL)nCol >= 0))
+ {
+ bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (!bFound)
+ {
+ BOOL bIsEmpty;
+ do
+ {
+ nCol--;
+ if ((SCsCOL)nCol >= 0)
+ bIsEmpty = aCol[nCol].IsEmptyData();
+ else
+ bIsEmpty = TRUE;
+ }
+ while (((SCsCOL)nCol >= 0) && bIsEmpty);
+ }
+ }
+ if (!bFound)
+ {
+ nCol = nLastCol;
+ nRow--;
+ }
+ }
+ }
+ else
+ {
+ nRow--;
+ while (!bFound && ((SCsCOL)nCol >= 0))
+ {
+ while (!bFound && ((SCsROW)nRow >= 0))
+ {
+ bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (!bFound)
+ {
+ if (!aCol[nCol].GetPrevDataPos(nRow))
+ nRow = -1;
+ }
+ }
+ if (!bFound)
+ {
+ BOOL bIsEmpty;
+ nRow = nLastRow;
+ do
+ {
+ nCol--;
+ if ((SCsCOL)nCol >= 0)
+ bIsEmpty = aCol[nCol].IsEmptyData();
+ else
+ bIsEmpty = TRUE;
+ }
+ while (((SCsCOL)nCol >= 0) && bIsEmpty);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!bAll && rSearchItem.GetRowDirection())
+ {
+ nCol++;
+ while (!bFound && (nRow <= nLastRow))
+ {
+ while (!bFound && (nCol <= nLastCol))
+ {
+ bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (!bFound)
+ {
+ nCol++;
+ while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
+ }
+ }
+ if (!bFound)
+ {
+ nCol = 0;
+ nRow++;
+ }
+ }
+ }
+ else
+ {
+ nRow++;
+ while (!bFound && (nCol <= nLastCol))
+ {
+ while (!bFound && (nRow <= nLastRow))
+ {
+ bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (!bFound)
+ {
+ if (!aCol[nCol].GetNextDataPos(nRow))
+ nRow = MAXROW + 1;
+ }
+ }
+ if (!bFound)
+ {
+ nRow = 0;
+ nCol++;
+ while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
+ }
+ }
+ }
+ }
+ if (bFound)
+ {
+ rCol = nCol;
+ rRow = nRow;
+ }
+ return bFound;
+}
+
+BOOL ScTable::SearchAll(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
+ String& rUndoStr, ScDocument* pUndoDoc)
+{
+ BOOL bFound = TRUE;
+ SCCOL nCol = 0;
+ SCROW nRow = -1;
+
+ ScMarkData aNewMark( rMark ); // Tabellen-Markierungen kopieren
+ aNewMark.ResetMark();
+ do
+ {
+ bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (bFound)
+ aNewMark.SetMultiMarkArea( ScRange( nCol, nRow, nTab ) );
+ }
+ while (bFound);
+
+ rMark = aNewMark; // Markierung kopieren
+ //! pro Tabelle
+
+ return (aNewMark.IsMultiMarked());
+}
+
+BOOL ScTable::Replace(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+ const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
+{
+ BOOL bFound = FALSE;
+ SCCOL nCol = rCol;
+ SCROW nRow = rRow;
+ if (rSearchItem.GetBackward())
+ {
+ if (rSearchItem.GetRowDirection())
+ nCol += 1;
+ else
+ nRow += 1;
+ }
+ else
+ {
+ if (rSearchItem.GetRowDirection())
+ nCol -= 1;
+ else
+ nRow -= 1;
+ }
+ bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (bFound)
+ {
+ rCol = nCol;
+ rRow = nRow;
+ }
+ return bFound;
+}
+
+BOOL ScTable::ReplaceAll(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
+ String& rUndoStr, ScDocument* pUndoDoc)
+{
+ BOOL bOldDouble = ScColumn::bDoubleAlloc; // sollte immer FALSE sein?
+ DBG_ASSERT(!bOldDouble,"bDoubleAlloc ???");
+ ScColumn::bDoubleAlloc = TRUE; // fuer Undo-Doc
+
+ BOOL bFound = TRUE;
+ SCCOL nCol = 0;
+ SCROW nRow = -1;
+
+ ScMarkData aNewMark( rMark ); // Tabellen-Markierungen kopieren
+ aNewMark.ResetMark();
+ do
+ {
+ bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+ if (bFound)
+ aNewMark.SetMultiMarkArea( ScRange( nCol, nRow, nTab ) );
+ }
+ while (bFound);
+
+ ScColumn::bDoubleAlloc = bOldDouble;
+
+ rMark = aNewMark; // Markierung kopieren
+ //! pro Tabelle
+
+ return (aNewMark.IsMultiMarked());
+}
+
+BOOL ScTable::SearchStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+ ScMarkData& rMark)
+{
+ const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
+ pDocument->GetStyleSheetPool()->Find(
+ rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
+
+ SCsCOL nCol = rCol;
+ SCsROW nRow = rRow;
+ BOOL bFound = FALSE;
+
+ BOOL bSelect = rSearchItem.GetSelection();
+ BOOL bRows = rSearchItem.GetRowDirection();
+ BOOL bBack = rSearchItem.GetBackward();
+ short nAdd = bBack ? -1 : 1;
+
+ if (bRows) // zeilenweise
+ {
+ nRow += nAdd;
+ do
+ {
+ SCsROW nNextRow = aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
+ if (!ValidRow(nNextRow))
+ {
+ nRow = bBack ? MAXROW : 0;
+ nCol = sal::static_int_cast<SCsCOL>( nCol + nAdd );
+ }
+ else
+ {
+ nRow = nNextRow;
+ bFound = TRUE;
+ }
+ }
+ while (!bFound && ValidCol(nCol));
+ }
+ else // spaltenweise
+ {
+ SCsROW nNextRows[MAXCOLCOUNT];
+ SCsCOL i;
+ for (i=0; i<=MAXCOL; i++)
+ {
+ SCsROW nSRow = nRow;
+ if (bBack) { if (i>=nCol) --nSRow; }
+ else { if (i<=nCol) ++nSRow; }
+ nNextRows[i] = aCol[i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
+ }
+ if (bBack) // rueckwaerts
+ {
+ nRow = -1;
+ for (i=MAXCOL; i>=0; i--)
+ if (nNextRows[i]>nRow)
+ {
+ nCol = i;
+ nRow = nNextRows[i];
+ bFound = TRUE;
+ }
+ }
+ else // vorwaerts
+ {
+ nRow = MAXROW+1;
+ for (i=0; i<=MAXCOL; i++)
+ if (nNextRows[i]<nRow)
+ {
+ nCol = i;
+ nRow = nNextRows[i];
+ bFound = TRUE;
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ rCol = (SCCOL) nCol;
+ rRow = (SCROW) nRow;
+ }
+ return bFound;
+}
+
+//! einzelnes Pattern fuer Undo zurueckgeben
+
+BOOL ScTable::ReplaceStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+ ScMarkData& rMark, BOOL bIsUndo)
+{
+ BOOL bRet;
+ if (bIsUndo)
+ bRet = TRUE;
+ else
+ bRet = SearchStyle(rSearchItem, rCol, rRow, rMark);
+ if (bRet)
+ {
+ const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
+ pDocument->GetStyleSheetPool()->Find(
+ rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
+
+ if (pReplaceStyle)
+ ApplyStyle( rCol, rRow, *pReplaceStyle );
+ else
+ {
+ DBG_ERROR("pReplaceStyle==0");
+ }
+ }
+
+ return bRet;
+}
+
+BOOL ScTable::SearchAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark)
+{
+ const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
+ pDocument->GetStyleSheetPool()->Find(
+ rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
+ BOOL bSelect = rSearchItem.GetSelection();
+ BOOL bBack = rSearchItem.GetBackward();
+
+ ScMarkData aNewMark( rMark ); // Tabellen-Markierungen kopieren
+ aNewMark.ResetMark();
+ for (SCCOL i=0; i<=MAXCOL; i++)
+ {
+ BOOL bFound = TRUE;
+ SCsROW nRow = 0;
+ SCsROW nEndRow;
+ while (bFound && nRow <= MAXROW)
+ {
+ bFound = aCol[i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
+ if (bFound)
+ {
+ if (nEndRow<nRow)
+ {
+ SCsROW nTemp = nRow;
+ nRow = nEndRow;
+ nEndRow = nTemp;
+ }
+ aNewMark.SetMultiMarkArea( ScRange( i,nRow,nTab, i,nEndRow,nTab ) );
+ nRow = nEndRow + 1;
+ }
+ }
+ }
+
+ rMark = aNewMark; // Markierung kopieren
+ //! pro Tabelle
+
+ return (aNewMark.IsMultiMarked());
+}
+
+BOOL ScTable::ReplaceAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
+ ScDocument* pUndoDoc)
+{
+ BOOL bRet = SearchAllStyle(rSearchItem, rMark);
+ if (bRet)
+ {
+ const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
+ pDocument->GetStyleSheetPool()->Find(
+ rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
+
+ if (pReplaceStyle)
+ {
+ if (pUndoDoc)
+ pDocument->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ IDF_ATTRIB, TRUE, pUndoDoc, &rMark );
+ ApplySelectionStyle( *pReplaceStyle, rMark );
+ }
+ else
+ {
+ DBG_ERROR("pReplaceStyle==0");
+ }
+ }
+
+ return bRet;
+}
+
+BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem,
+ SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
+ String& rUndoStr, ScDocument* pUndoDoc)
+{
+ USHORT nCommand = rSearchItem.GetCommand();
+ BOOL bFound = FALSE;
+ if ( ValidColRow(rCol, rRow) ||
+ ((nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE) &&
+ (((rCol == MAXCOLCOUNT || rCol == -1) && VALIDROW(rRow)) ||
+ ((rRow == MAXROWCOUNT || rRow == -1) && VALIDCOL(rCol))
+ )
+ )
+ )
+ {
+ BOOL bStyles = rSearchItem.GetPattern();
+ if (bStyles)
+ {
+ if (nCommand == SVX_SEARCHCMD_FIND)
+ bFound = SearchStyle(rSearchItem, rCol, rRow, rMark);
+ else if (nCommand == SVX_SEARCHCMD_REPLACE)
+ bFound = ReplaceStyle(rSearchItem, rCol, rRow, rMark, FALSE);
+ else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
+ bFound = SearchAllStyle(rSearchItem, rMark);
+ else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
+ bFound = ReplaceAllStyle(rSearchItem, rMark, pUndoDoc);
+ }
+ else
+ {
+ // SearchParam no longer needed - SearchOptions contains all settings
+ com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
+ aSearchOptions.Locale = *ScGlobal::GetLocale();
+
+ // #107259# reflect UseAsianOptions flag in SearchOptions
+ // (use only ignore case and width if asian options are disabled).
+ // This is also done in SvxSearchDialog CommandHdl, but not in API object.
+ if ( !rSearchItem.IsUseAsianOptions() )
+ aSearchOptions.transliterateFlags &=
+ ( com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
+ com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
+
+ pSearchText = new utl::TextSearch( aSearchOptions );
+
+ if (nCommand == SVX_SEARCHCMD_FIND)
+ bFound = Search(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
+ else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
+ bFound = SearchAll(rSearchItem, rMark, rUndoStr, pUndoDoc);
+ else if (nCommand == SVX_SEARCHCMD_REPLACE)
+ bFound = Replace(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
+ else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
+ bFound = ReplaceAll(rSearchItem, rMark, rUndoStr, pUndoDoc);
+
+ delete pSearchText;
+ pSearchText = NULL;
+ }
+ }
+ return bFound;
+}
+
+
+
+
+
+
diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx
new file mode 100644
index 000000000000..2709dd54d1fb
--- /dev/null
+++ b/sc/source/core/data/tabprotection.cxx
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "svl/PasswordHelper.hxx"
+#include <comphelper/docpasswordhelper.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()
+{
+}
+
+// ============================================================================
+
+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 = ::comphelper::DocPasswordHelper::GetXLHashAsSequence( aPassText, RTL_TEXTENCODING_UTF8 );
+ 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/userdat.cxx b/sc/source/core/data/userdat.cxx
new file mode 100644
index 000000000000..466e83b15fad
--- /dev/null
+++ b/sc/source/core/data/userdat.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// -----------------------------------------------------------------------
+
+#include "userdat.hxx"
+#include <tools/debug.hxx>
+#include "drwlayer.hxx"
+#include "rechead.hxx"
+
+// -----------------------------------------------------------------------
+
+ScDrawObjFactory::ScDrawObjFactory()
+{
+ SdrObjFactory::InsertMakeUserDataHdl( LINK ( this, ScDrawObjFactory, MakeUserData ) );
+}
+
+ScDrawObjFactory::~ScDrawObjFactory()
+{
+ SdrObjFactory::RemoveMakeUserDataHdl( LINK ( this, ScDrawObjFactory, MakeUserData ) );
+}
+
+IMPL_LINK_INLINE_START( ScDrawObjFactory, MakeUserData, SdrObjFactory *, pObjFactory )
+{
+ if ( pObjFactory->nInventor == SC_DRAWLAYER )
+ {
+ if ( pObjFactory->nIdentifier == SC_UD_OBJDATA )
+ pObjFactory->pNewData = new ScDrawObjData;
+ else if ( pObjFactory->nIdentifier == SC_UD_IMAPDATA )
+ pObjFactory->pNewData = new ScIMapInfo;
+ else if ( pObjFactory->nIdentifier == SC_UD_MACRODATA )
+ pObjFactory->pNewData = new ScMacroInfo;
+ else
+ {
+ DBG_ERROR("MakeUserData: falsche ID");
+ }
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScDrawObjFactory, MakeUserData, SdrObjFactory *, pObjFactory )
+
+//------------------------------------------------------------------------
+
+ScDrawObjData::ScDrawObjData() :
+ SdrObjUserData( SC_DRAWLAYER, SC_UD_OBJDATA, 0 ),
+ maStart( ScAddress::INITIALIZE_INVALID ),
+ maEnd( ScAddress::INITIALIZE_INVALID ),
+ mbNote( false )
+{
+}
+
+ScDrawObjData* ScDrawObjData::Clone( SdrObject* ) const
+{
+ return new ScDrawObjData( *this );
+}
+
+//------------------------------------------------------------------------
+
+ScIMapInfo::ScIMapInfo() :
+ SdrObjUserData( SC_DRAWLAYER, SC_UD_IMAPDATA, 0 )
+{
+}
+
+ScIMapInfo::ScIMapInfo( const ImageMap& rImageMap ) :
+ SdrObjUserData( SC_DRAWLAYER, SC_UD_IMAPDATA, 0 ),
+ aImageMap( rImageMap )
+{
+}
+
+ScIMapInfo::ScIMapInfo( const ScIMapInfo& rIMapInfo ) :
+ SdrObjUserData( rIMapInfo ),
+ aImageMap( rIMapInfo.aImageMap )
+{
+}
+
+ScIMapInfo::~ScIMapInfo()
+{
+}
+
+SdrObjUserData* ScIMapInfo::Clone( SdrObject* ) const
+{
+ return new ScIMapInfo( *this );
+}
+
+//------------------------------------------------------------------------
+
+ScMacroInfo::ScMacroInfo() :
+ SdrObjUserData( SC_DRAWLAYER, SC_UD_MACRODATA, 0 )
+{
+}
+
+ScMacroInfo::~ScMacroInfo()
+{
+}
+
+SdrObjUserData* ScMacroInfo::Clone( SdrObject* /*pObj*/ ) const
+{
+ return new ScMacroInfo( *this );
+}
+
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
new file mode 100644
index 000000000000..2239b1d0f773
--- /dev/null
+++ b/sc/source/core/data/validat.cxx
@@ -0,0 +1,996 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/basmgr.hxx>
+
+#include <basic/sbx.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/math.hxx>
+
+#include "validat.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "rechead.hxx"
+#include "globstr.hrc"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+
+#include <math.h>
+#include <memory>
+
+using namespace formula;
+//------------------------------------------------------------------------
+
+SV_IMPL_OP_PTRARR_SORT( ScValidationEntries_Impl, ScValidationDataPtr );
+
+//------------------------------------------------------------------------
+
+//
+// Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
+//
+
+ScValidationData::ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
+ const String& rExpr1, const String& rExpr2,
+ ScDocument* pDocument, const ScAddress& rPos,
+ 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 ),
+ mnListType( ValidListType::UNSORTED )
+{
+ bShowInput = bShowError = FALSE;
+}
+
+ScValidationData::ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
+ const ScTokenArray* pArr1, const ScTokenArray* pArr2,
+ ScDocument* pDocument, const ScAddress& rPos ) :
+ ScConditionEntry( eOper, pArr1, pArr2, pDocument, rPos ),
+ nKey( 0 ),
+ eDataMode( eMode ),
+ eErrorStyle( SC_VALERR_STOP ),
+ mnListType( ValidListType::UNSORTED )
+{
+ bShowInput = bShowError = FALSE;
+}
+
+ScValidationData::ScValidationData( const ScValidationData& r ) :
+ ScConditionEntry( r ),
+ nKey( r.nKey ),
+ eDataMode( r.eDataMode ),
+ bShowInput( r.bShowInput ),
+ bShowError( r.bShowError ),
+ eErrorStyle( r.eErrorStyle ),
+ mnListType( r.mnListType ),
+ aInputTitle( r.aInputTitle ),
+ aInputMessage( r.aInputMessage ),
+ aErrorTitle( r.aErrorTitle ),
+ aErrorMessage( r.aErrorMessage )
+{
+ // Formeln per RefCount kopiert
+}
+
+ScValidationData::ScValidationData( ScDocument* pDocument, const ScValidationData& r ) :
+ ScConditionEntry( pDocument, r ),
+ nKey( r.nKey ),
+ eDataMode( r.eDataMode ),
+ bShowInput( r.bShowInput ),
+ bShowError( r.bShowError ),
+ eErrorStyle( r.eErrorStyle ),
+ mnListType( r.mnListType ),
+ aInputTitle( r.aInputTitle ),
+ aInputMessage( r.aInputMessage ),
+ aErrorTitle( r.aErrorTitle ),
+ aErrorMessage( r.aErrorMessage )
+{
+ // Formeln wirklich kopiert
+}
+
+ScValidationData::~ScValidationData()
+{
+}
+
+BOOL ScValidationData::IsEmpty() const
+{
+ String aEmpty;
+ ScValidationData aDefault( SC_VALID_ANY, SC_COND_EQUAL, aEmpty, aEmpty, GetDocument(), ScAddress() );
+ return EqualEntries( aDefault );
+}
+
+BOOL ScValidationData::EqualEntries( const ScValidationData& r ) const
+{
+ // gleiche Parameter eingestellt (ohne Key)
+
+ return ScConditionEntry::operator==(r) &&
+ eDataMode == r.eDataMode &&
+ bShowInput == r.bShowInput &&
+ bShowError == r.bShowError &&
+ eErrorStyle == r.eErrorStyle &&
+ mnListType == r.mnListType &&
+ aInputTitle == r.aInputTitle &&
+ aInputMessage == r.aInputMessage &&
+ aErrorTitle == r.aErrorTitle &&
+ aErrorMessage == r.aErrorMessage;
+}
+
+void ScValidationData::ResetInput()
+{
+ bShowInput = FALSE;
+}
+
+void ScValidationData::ResetError()
+{
+ bShowError = FALSE;
+}
+
+void ScValidationData::SetInput( const String& rTitle, const String& rMsg )
+{
+ bShowInput = TRUE;
+ aInputTitle = rTitle;
+ aInputMessage = rMsg;
+}
+
+void ScValidationData::SetError( const String& rTitle, const String& rMsg,
+ ScValidErrorStyle eStyle )
+{
+ bShowError = TRUE;
+ eErrorStyle = eStyle;
+ aErrorTitle = rTitle;
+ aErrorMessage = rMsg;
+}
+
+BOOL ScValidationData::GetErrMsg( String& rTitle, String& rMsg,
+ ScValidErrorStyle& rStyle ) const
+{
+ rTitle = aErrorTitle;
+ rMsg = aErrorMessage;
+ rStyle = eErrorStyle;
+ return bShowError;
+}
+
+BOOL ScValidationData::DoScript( const ScAddress& rPos, const String& rInput,
+ ScFormulaCell* pCell, Window* pParent ) const
+{
+ ScDocument* pDocument = GetDocument();
+ SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
+ if ( !pDocSh || !pDocument->CheckMacroWarn() )
+ return FALSE;
+
+ BOOL bScriptReturnedFalse = FALSE; // Standard: kein Abbruch
+
+ // Set up parameters
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aParams(2);
+
+ // 1) eingegebener / berechneter Wert
+ String aValStr = rInput;
+ double nValue;
+ BOOL bIsValue = FALSE;
+ if ( pCell ) // wenn Zelle gesetzt, aus Interpret gerufen
+ {
+ bIsValue = pCell->IsValue();
+ if ( bIsValue )
+ nValue = pCell->GetValue();
+ else
+ pCell->GetString( aValStr );
+ }
+ if ( bIsValue )
+ aParams[0] = ::com::sun::star::uno::makeAny( nValue );
+ else
+ aParams[0] = ::com::sun::star::uno::makeAny( ::rtl::OUString( aValStr ) );
+
+ // 2) Position der Zelle
+ String aPosStr;
+ rPos.Format( aPosStr, SCA_VALID | SCA_TAB_3D, pDocument, pDocument->GetAddressConvention() );
+ aParams[1] = ::com::sun::star::uno::makeAny( ::rtl::OUString( aPosStr ) );
+
+ // use link-update flag to prevent closing the document
+ // while the macro is running
+ BOOL bWasInLinkUpdate = pDocument->IsInLinkUpdate();
+ if ( !bWasInLinkUpdate )
+ pDocument->SetInLinkUpdate( TRUE );
+
+ if ( pCell )
+ pDocument->LockTable( rPos.Tab() );
+
+ ::com::sun::star::uno::Any aRet;
+ ::com::sun::star::uno::Sequence< sal_Int16 > aOutArgsIndex;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aOutArgs;
+
+ ErrCode eRet = pDocSh->CallXScript(
+ aErrorTitle, aParams, aRet, aOutArgsIndex, aOutArgs );
+
+ if ( pCell )
+ pDocument->UnlockTable( rPos.Tab() );
+
+ if ( !bWasInLinkUpdate )
+ pDocument->SetInLinkUpdate( FALSE );
+
+ // Check the return value from the script
+ // The contents of the cell get reset if the script returns false
+ BOOL bTmp = FALSE;
+ if ( eRet == ERRCODE_NONE &&
+ aRet.getValueType() == getCppuBooleanType() &&
+ sal_True == ( aRet >>= bTmp ) &&
+ bTmp == FALSE )
+ {
+ bScriptReturnedFalse = TRUE;
+ }
+
+ if ( eRet == ERRCODE_BASIC_METHOD_NOT_FOUND && !pCell )
+ // Makro nicht gefunden (nur bei Eingabe)
+ {
+ //! andere Fehlermeldung, wenn gefunden, aber nicht bAllowed ??
+
+ ErrorBox aBox( pParent, WinBits(WB_OK),
+ ScGlobal::GetRscString( STR_VALID_MACRONOTFOUND ) );
+ aBox.Execute();
+ }
+
+ return bScriptReturnedFalse;
+}
+
+ // TRUE -> Abbruch
+
+BOOL ScValidationData::DoMacro( const ScAddress& rPos, const String& rInput,
+ ScFormulaCell* pCell, Window* pParent ) const
+{
+ if ( SfxApplication::IsXScriptURL( aErrorTitle ) )
+ {
+ return DoScript( rPos, rInput, pCell, pParent );
+ }
+
+ ScDocument* pDocument = GetDocument();
+ SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
+ if ( !pDocSh || !pDocument->CheckMacroWarn() )
+ return FALSE;
+
+ BOOL bDone = FALSE;
+ BOOL bRet = FALSE; // Standard: kein Abbruch
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->EnterBasicCall(); // Dok-Basic anlegen etc.
+
+ // Wenn das Dok waehrend eines Basic-Calls geladen wurde,
+ // ist das Sbx-Objekt evtl. nicht angelegt (?)
+// pDocSh->GetSbxObject();
+
+ // keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic
+
+#if 0
+ // Makro-Name liegt in folgender Form vor:
+ // "Macroname.Modulname.Libname.Dokumentname" oder
+ // "Macroname.Modulname.Libname.Applikationsname"
+ String aMacroName = aErrorTitle.GetToken(0, '.');
+ String aModulName = aErrorTitle.GetToken(1, '.');
+ String aLibName = aErrorTitle.GetToken(2, '.');
+ String aDocName = aErrorTitle.GetToken(3, '.');
+#endif
+
+ // Funktion ueber den einfachen Namen suchen,
+ // dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen
+
+ StarBASIC* pRoot = pDocSh->GetBasic();
+ SbxVariable* pVar = pRoot->Find( aErrorTitle, SbxCLASS_METHOD );
+ if ( pVar && pVar->ISA(SbMethod) )
+ {
+ SbMethod* pMethod = (SbMethod*)pVar;
+ SbModule* pModule = pMethod->GetModule();
+ SbxObject* pObject = pModule->GetParent();
+ String aMacroStr = pObject->GetName();
+ aMacroStr += '.';
+ aMacroStr += pModule->GetName();
+ aMacroStr += '.';
+ aMacroStr += pMethod->GetName();
+ String aBasicStr;
+
+ // #95867# the distinction between document- and app-basic has to be done
+ // by checking the parent (as in ScInterpreter::ScMacro), not by looping
+ // over all open documents, because this may be called from within loading,
+ // when SfxObjectShell::GetFirst/GetNext won't find the document.
+
+ if ( pObject->GetParent() )
+ aBasicStr = pObject->GetParent()->GetName(); // Dokumentenbasic
+ else
+ aBasicStr = SFX_APP()->GetName(); // Applikationsbasic
+
+ // Parameter fuer Makro
+ SbxArrayRef refPar = new SbxArray;
+
+ // 1) eingegebener / berechneter Wert
+ String aValStr = rInput;
+ double nValue = 0.0;
+ BOOL bIsValue = FALSE;
+ if ( pCell ) // wenn Zelle gesetzt, aus Interpret gerufen
+ {
+ bIsValue = pCell->IsValue();
+ if ( bIsValue )
+ nValue = pCell->GetValue();
+ else
+ pCell->GetString( aValStr );
+ }
+ if ( bIsValue )
+ refPar->Get(1)->PutDouble( nValue );
+ else
+ refPar->Get(1)->PutString( aValStr );
+
+ // 2) Position der Zelle
+ String aPosStr;
+ rPos.Format( aPosStr, SCA_VALID | SCA_TAB_3D, pDocument, pDocument->GetAddressConvention() );
+ refPar->Get(2)->PutString( aPosStr );
+
+ // use link-update flag to prevent closing the document
+ // while the macro is running
+ BOOL bWasInLinkUpdate = pDocument->IsInLinkUpdate();
+ if ( !bWasInLinkUpdate )
+ pDocument->SetInLinkUpdate( TRUE );
+
+ if ( pCell )
+ pDocument->LockTable( rPos.Tab() );
+ SbxVariableRef refRes = new SbxVariable;
+ ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, NULL, refPar, refRes );
+ if ( pCell )
+ pDocument->UnlockTable( rPos.Tab() );
+
+ if ( !bWasInLinkUpdate )
+ pDocument->SetInLinkUpdate( FALSE );
+
+ // Eingabe abbrechen, wenn Basic-Makro FALSE zurueckgibt
+ if ( eRet == ERRCODE_NONE && refRes->GetType() == SbxBOOL && refRes->GetBool() == FALSE )
+ bRet = TRUE;
+ bDone = TRUE;
+ }
+ pSfxApp->LeaveBasicCall();
+
+ if ( !bDone && !pCell ) // Makro nicht gefunden (nur bei Eingabe)
+ {
+ //! andere Fehlermeldung, wenn gefunden, aber nicht bAllowed ??
+
+ ErrorBox aBox( pParent, WinBits(WB_OK),
+ ScGlobal::GetRscString( STR_VALID_MACRONOTFOUND ) );
+ aBox.Execute();
+ }
+
+ return bRet;
+}
+
+void ScValidationData::DoCalcError( ScFormulaCell* pCell ) const
+{
+ if ( eErrorStyle == SC_VALERR_MACRO )
+ DoMacro( pCell->aPos, EMPTY_STRING, pCell, NULL );
+}
+
+ // TRUE -> Abbruch
+
+BOOL ScValidationData::DoError( Window* pParent, const String& rInput,
+ const ScAddress& rPos ) const
+{
+ if ( eErrorStyle == SC_VALERR_MACRO )
+ return DoMacro( rPos, rInput, NULL, pParent );
+
+ // Fehlermeldung ausgeben
+
+ String aTitle = aErrorTitle;
+ if (!aTitle.Len())
+ aTitle = ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ); // application title
+ String aMessage = aErrorMessage;
+ if (!aMessage.Len())
+ aMessage = ScGlobal::GetRscString( STR_VALID_DEFERROR );
+
+ //! ErrorBox / WarningBox / InfoBox ?
+ //! (bei InfoBox immer nur OK-Button)
+
+ WinBits nStyle = 0;
+ switch (eErrorStyle)
+ {
+ case SC_VALERR_STOP:
+ nStyle = WB_OK | WB_DEF_OK;
+ break;
+ case SC_VALERR_WARNING:
+ nStyle = WB_OK_CANCEL | WB_DEF_CANCEL;
+ break;
+ case SC_VALERR_INFO:
+ nStyle = WB_OK_CANCEL | WB_DEF_OK;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ MessBox aBox( pParent, WinBits(nStyle), aTitle, aMessage );
+ USHORT nRet = aBox.Execute();
+
+ return ( eErrorStyle == SC_VALERR_STOP || nRet == RET_CANCEL );
+}
+
+
+BOOL ScValidationData::IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
+ const ScAddress& rPos ) const
+{
+ if ( eDataMode == SC_VALID_ANY )
+ return TRUE; // alles erlaubt
+
+ if ( rTest.GetChar(0) == '=' )
+ return FALSE; // Formeln sind sonst immer ungueltig
+
+ if ( !rTest.Len() )
+ return IsIgnoreBlank(); // leer: wie eingestellt
+
+ SvNumberFormatter* pFormatter = GetDocument()->GetFormatTable();
+
+ // Test, was es denn ist - wie in ScColumn::SetString
+
+ sal_uInt32 nFormat = rPattern.GetNumberFormat( pFormatter );
+
+ double nVal;
+ BOOL bIsVal = pFormatter->IsNumberFormat( rTest, nFormat, nVal );
+ ScBaseCell* pCell;
+ if (bIsVal)
+ pCell = new ScValueCell( nVal );
+ else
+ pCell = new ScStringCell( rTest );
+
+ BOOL bRet = IsDataValid( pCell, rPos );
+
+ pCell->Delete();
+ return bRet;
+}
+
+BOOL ScValidationData::IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const
+{
+ if( eDataMode == SC_VALID_LIST )
+ return IsListValid( pCell, rPos );
+
+ double nVal = 0.0;
+ String aString;
+ BOOL bIsVal = TRUE;
+
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ nVal = ((ScValueCell*)pCell)->GetValue();
+ break;
+ case CELLTYPE_STRING:
+ ((ScStringCell*)pCell)->GetString( aString );
+ bIsVal = FALSE;
+ break;
+ case CELLTYPE_EDIT:
+ ((ScEditCell*)pCell)->GetString( aString );
+ bIsVal = FALSE;
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ bIsVal = pFCell->IsValue();
+ if ( bIsVal )
+ nVal = pFCell->GetValue();
+ else
+ pFCell->GetString( aString );
+ }
+ break;
+ default: // Notizen, Broadcaster
+ return IsIgnoreBlank(); // wie eingestellt
+ }
+
+ BOOL bOk = TRUE;
+ switch (eDataMode)
+ {
+ // SC_VALID_ANY schon oben
+
+ case SC_VALID_WHOLE:
+ case SC_VALID_DECIMAL:
+ case SC_VALID_DATE: // Date/Time ist nur Formatierung
+ case SC_VALID_TIME:
+ bOk = bIsVal;
+ if ( bOk && eDataMode == SC_VALID_WHOLE )
+ bOk = ::rtl::math::approxEqual( nVal, floor(nVal+0.5) ); // ganze Zahlen
+ if ( bOk )
+ bOk = IsCellValid( pCell, rPos );
+ break;
+
+ case SC_VALID_CUSTOM:
+ // fuer Custom muss eOp == SC_COND_DIRECT sein
+ //! der Wert muss im Dokument stehen !!!!!!!!!!!!!!!!!!!!
+ bOk = IsCellValid( pCell, rPos );
+ break;
+
+ case SC_VALID_TEXTLEN:
+ bOk = !bIsVal; // nur Text
+ if ( bOk )
+ {
+ double nLenVal = (double) aString.Len();
+ ScValueCell aTmpCell( nLenVal );
+ bOk = IsCellValid( &aTmpCell, rPos );
+ }
+ break;
+
+ default:
+ DBG_ERROR("hammanochnich");
+ break;
+ }
+
+ return bOk;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Token array helper. Iterates over all string tokens.
+ @descr The token array must contain separated string tokens only.
+ @param bSkipEmpty true = Ignores string tokens with empty strings. */
+class ScStringTokenIterator
+{
+public:
+ inline explicit ScStringTokenIterator( ScTokenArray& rTokArr, bool bSkipEmpty = true ) :
+ mrTokArr( rTokArr ), mbSkipEmpty( bSkipEmpty ), mbOk( true ) {}
+
+ /** Returns the string of the first string token or NULL on error or empty token array. */
+ const String* First();
+ /** Returns the string of the next string token or NULL on error or end of token array. */
+ const String* Next();
+
+ /** Returns false, if a wrong token has been found. Does NOT return false on end of token array. */
+ inline bool Ok() const { return mbOk; }
+
+private:
+ ScTokenArray& mrTokArr; /// The token array for iteration.
+ bool mbSkipEmpty; /// Ignore empty strings.
+ bool mbOk; /// true = correct token or end of token array.
+};
+
+const String* ScStringTokenIterator::First()
+{
+ mrTokArr.Reset();
+ mbOk = true;
+ return Next();
+}
+
+const String* ScStringTokenIterator::Next()
+{
+ if( !mbOk )
+ return NULL;
+
+ // seek to next non-separator token
+ const FormulaToken* pToken = mrTokArr.NextNoSpaces();
+ while( pToken && (pToken->GetOpCode() == ocSep) )
+ pToken = mrTokArr.NextNoSpaces();
+
+ mbOk = !pToken || (pToken->GetType() == formula::svString);
+ const String* pString = (mbOk && pToken) ? &pToken->GetString() : NULL;
+ // string found but empty -> get next token; otherwise return it
+ return (mbSkipEmpty && pString && !pString->Len()) ? Next() : pString;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Returns the number format of the passed cell, or the standard format. */
+ULONG lclGetCellFormat( ScDocument& rDoc, const ScAddress& rPos )
+{
+ const ScPatternAttr* pPattern = rDoc.GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() );
+ if( !pPattern )
+ pPattern = rDoc.GetDefPattern();
+ return pPattern->GetNumberFormat( rDoc.GetFormatTable() );
+}
+
+/** Inserts the passed string object. Always takes ownership. pData is invalid after this call! */
+void lclInsertStringToCollection( TypedScStrCollection& rStrColl, TypedStrData* pData, bool bSorted )
+{
+ if( !(bSorted ? rStrColl.Insert( pData ) : rStrColl.AtInsert( rStrColl.GetCount(), pData )) )
+ delete pData;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+bool ScValidationData::HasSelectionList() const
+{
+ return (eDataMode == SC_VALID_LIST) && (mnListType != ValidListType::INVISIBLE);
+}
+
+bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings,
+ ScBaseCell* pCell,
+ const ScAddress& rPos,
+ const ScTokenArray& rTokArr,
+ int& rMatch ) const
+{
+ bool bOk = true;
+
+ // pDoc is private in condition, use an accessor and a long winded name.
+ ScDocument* pDocument = GetDocument();
+ if( NULL == pDocument )
+ return false;
+
+ ScFormulaCell aValidationSrc( pDocument, rPos, &rTokArr,
+ formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA);
+
+ // Make sure the formula gets interpreted and a result is delivered,
+ // regardless of the AutoCalc setting.
+ aValidationSrc.Interpret();
+
+ ScMatrixRef xMatRef;
+ const ScMatrix *pValues = aValidationSrc.GetMatrix();
+ if (!pValues)
+ {
+ // The somewhat nasty case of either an error occured, or the
+ // dereferenced value of a single cell reference or an immediate result
+ // is stored as a single value.
+
+ // Use an interim matrix to create the TypedStrData below.
+ xMatRef = new ScMatrix(1,1);
+
+ USHORT nErrCode = aValidationSrc.GetErrCode();
+ if (nErrCode)
+ {
+ /* TODO : to use later in an alert box?
+ * String rStrResult = "...";
+ * rStrResult += ScGlobal::GetLongErrorString(nErrCode);
+ */
+
+ xMatRef->PutError( nErrCode, 0);
+ bOk = false;
+ }
+ else if (aValidationSrc.HasValueData())
+ xMatRef->PutDouble( aValidationSrc.GetValue(), 0);
+ else
+ {
+ String aStr;
+ aValidationSrc.GetString( aStr);
+ xMatRef->PutString( aStr, 0);
+ }
+
+ pValues = xMatRef;
+ }
+
+ // which index matched. We will want it eventually to pre-select that item.
+ rMatch = -1;
+
+ SvNumberFormatter* pFormatter = GetDocument()->GetFormatTable();
+
+ bool bSortList = (mnListType == ValidListType::SORTEDASCENDING);
+ 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
+ * to 2D, it is evaluated fine and also stored and loaded. Lets get ahead
+ * of the curve and support 2d. In XL, values are listed row-wise, do the
+ * same. */
+ for( nRow = 0; nRow < nRows ; nRow++ )
+ {
+ for( nCol = 0; nCol < nCols ; nCol++ )
+ {
+ ScTokenArray aCondTokArr;
+ TypedStrData* pEntry = NULL;
+ ScMatValType nMatValType;
+ String aValStr;
+ const ScMatrixValue* pMatVal = pValues->Get( nCol, nRow, nMatValType);
+
+ // strings and empties
+ if( NULL == pMatVal || ScMatrix::IsNonValueType( nMatValType ) )
+ {
+ if( NULL != pMatVal )
+ aValStr = pMatVal->GetString();
+
+ if( NULL != pStrings )
+ pEntry = new TypedStrData( aValStr, 0.0, SC_STRTYPE_STANDARD);
+
+ if( pCell && rMatch < 0 )
+ aCondTokArr.AddString( aValStr );
+ }
+ else
+ {
+ USHORT nErr = pMatVal->GetError();
+
+ if( 0 != nErr )
+ {
+ aValStr = ScGlobal::GetErrorString( nErr );
+ }
+ else
+ {
+ // FIXME FIXME FIXME
+ // Feature regression. Date formats are lost passing through the matrix
+ //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 )
+ {
+ // I am not sure errors will work here, but a user can no
+ // manually enter an error yet so the point is somewhat moot.
+ aCondTokArr.AddDouble( pMatVal->fVal );
+ }
+ if( NULL != pStrings )
+ pEntry = new TypedStrData( aValStr, pMatVal->fVal, SC_STRTYPE_VALUE);
+ }
+
+ if( rMatch < 0 && NULL != pCell && IsEqualToTokenArray( pCell, rPos, aCondTokArr ) )
+ {
+ rMatch = n;
+ // short circuit on the first match if not filling the list
+ if( NULL == pStrings )
+ return true;
+ }
+
+ if( NULL != pEntry )
+ {
+ lclInsertStringToCollection( *pStrings, pEntry, bSortList );
+ n++;
+ }
+ }
+ }
+
+ // In case of no match needed and an error occurred, return that error
+ // entry as valid instead of silently failing.
+ return bOk || NULL == pCell;
+}
+
+bool ScValidationData::FillSelectionList( TypedScStrCollection& rStrColl, const ScAddress& rPos ) const
+{
+ bool bOk = false;
+
+ if( HasSelectionList() )
+ {
+ ::std::auto_ptr< ScTokenArray > pTokArr( CreateTokenArry( 0 ) );
+
+ // *** try if formula is a string list ***
+
+ bool bSortList = (mnListType == ValidListType::SORTEDASCENDING);
+ UINT32 nFormat = lclGetCellFormat( *GetDocument(), rPos );
+ ScStringTokenIterator aIt( *pTokArr );
+ for( const String* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next() )
+ {
+ double fValue;
+ bool bIsValue = GetDocument()->GetFormatTable()->IsNumberFormat( *pString, nFormat, fValue );
+ TypedStrData* pData = new TypedStrData( *pString, fValue, bIsValue ? SC_STRTYPE_VALUE : SC_STRTYPE_STANDARD );
+ lclInsertStringToCollection( rStrColl, pData, bSortList );
+ }
+ bOk = aIt.Ok();
+
+ // *** if not a string list, try if formula results in a cell range or
+ // anything else we recognize as valid ***
+
+ if (!bOk)
+ {
+ int nMatch;
+ bOk = GetSelectionFromFormula( &rStrColl, NULL, rPos, *pTokArr, nMatch );
+ }
+ }
+
+ return bOk;
+}
+
+// ----------------------------------------------------------------------------
+
+bool ScValidationData::IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const
+{
+ // create a condition entry that tests on equality and set the passed token array
+ ScConditionEntry aCondEntry( SC_COND_EQUAL, &rTokArr, NULL, GetDocument(), rPos );
+ return aCondEntry.IsCellValid( pCell, rPos );
+}
+
+bool ScValidationData::IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const
+{
+ bool bIsValid = false;
+
+ /* Compare input cell with all supported tokens from the formula.
+ Currently a formula may contain:
+ 1) A list of strings (at least one string).
+ 2) A single cell or range reference.
+ 3) A single defined name (must contain a cell/range reference, another
+ name, or DB range, or a formula resulting in a cell/range reference
+ or matrix/array).
+ 4) A single database range.
+ 5) A formula resulting in a cell/range reference or matrix/array.
+ */
+
+ ::std::auto_ptr< ScTokenArray > pTokArr( CreateTokenArry( 0 ) );
+
+ // *** try if formula is a string list ***
+
+ UINT32 nFormat = lclGetCellFormat( *GetDocument(), rPos );
+ ScStringTokenIterator aIt( *pTokArr );
+ for( const String* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next() )
+ {
+ /* Do not break the loop, if a valid string has been found.
+ This is to find invalid tokens following in the formula. */
+ if( !bIsValid )
+ {
+ // create a formula containing a single string or number
+ ScTokenArray aCondTokArr;
+ double fValue;
+ if( GetDocument()->GetFormatTable()->IsNumberFormat( *pString, nFormat, fValue ) )
+ aCondTokArr.AddDouble( fValue );
+ else
+ aCondTokArr.AddString( *pString );
+
+ bIsValid = IsEqualToTokenArray( pCell, rPos, aCondTokArr );
+ }
+ }
+
+ if( !aIt.Ok() )
+ bIsValid = false;
+
+ // *** if not a string list, try if formula results in a cell range or
+ // anything else we recognize as valid ***
+
+ if (!bIsValid)
+ {
+ int nMatch;
+ bIsValid = GetSelectionFromFormula( NULL, pCell, rPos, *pTokArr, nMatch );
+ bIsValid = bIsValid && nMatch >= 0;
+ }
+
+ return bIsValid;
+}
+
+// ============================================================================
+// ============================================================================
+
+ScValidationDataList::ScValidationDataList(const ScValidationDataList& rList) :
+ ScValidationEntries_Impl()
+{
+ // fuer Ref-Undo - echte Kopie mit neuen Tokens!
+
+ USHORT nCount = rList.Count();
+
+ for (USHORT i=0; i<nCount; i++)
+ InsertNew( rList[i]->Clone() );
+
+ //! sortierte Eintraege aus rList schneller einfuegen ???
+}
+
+ScValidationDataList::ScValidationDataList(ScDocument* pNewDoc,
+ const ScValidationDataList& rList)
+{
+ // fuer neues Dokument - echte Kopie mit neuen Tokens!
+
+ USHORT nCount = rList.Count();
+
+ for (USHORT i=0; i<nCount; i++)
+ InsertNew( rList[i]->Clone(pNewDoc) );
+
+ //! sortierte Eintraege aus rList schneller einfuegen ???
+}
+
+ScValidationData* ScValidationDataList::GetData( sal_uInt32 nKey )
+{
+ //! binaer suchen
+
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ if ((*this)[i]->GetKey() == nKey)
+ return (*this)[i];
+
+ DBG_ERROR("ScValidationDataList: Eintrag nicht gefunden");
+ return NULL;
+}
+
+void ScValidationDataList::CompileXML()
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->CompileXML();
+}
+
+void ScValidationDataList::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz);
+}
+
+void ScValidationDataList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ (*this)[i]->UpdateMoveTab( nOldPos, nNewPos );
+}
+
+bool ScValidationDataList::MarkUsedExternalReferences() const
+{
+ bool bAllMarked = false;
+ USHORT nCount = Count();
+ for (USHORT i=0; !bAllMarked && i<nCount; i++)
+ bAllMarked = (*this)[i]->MarkUsedExternalReferences();
+ return bAllMarked;
+}
+
+BOOL ScValidationDataList::operator==( const ScValidationDataList& r ) const
+{
+ // fuer Ref-Undo - interne Variablen werden nicht verglichen
+
+ USHORT nCount = Count();
+ BOOL bEqual = ( nCount == r.Count() );
+ for (USHORT i=0; i<nCount && bEqual; i++) // Eintraege sind sortiert
+ if ( !(*this)[i]->EqualEntries(*r[i]) ) // Eintraege unterschiedlich ?
+ bEqual = FALSE;
+
+ return bEqual;
+}
+
diff --git a/sc/source/core/inc/addinhelpid.hxx b/sc/source/core/inc/addinhelpid.hxx
new file mode 100644
index 000000000000..b2f085ed64e5
--- /dev/null
+++ b/sc/source/core/inc/addinhelpid.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ADDINHELPID_HXX
+#define SC_ADDINHELPID_HXX
+
+#include <rtl/ustring.hxx>
+
+
+// ============================================================================
+
+struct ScUnoAddInHelpId;
+
+/** Generates help IDs for standard Calc AddIns. */
+class ScUnoAddInHelpIdGenerator
+{
+private:
+ const ScUnoAddInHelpId* pCurrHelpIds; /// Array of function names and help IDs.
+ sal_uInt32 nArrayCount; /// Count of array entries.
+
+ ScUnoAddInHelpIdGenerator(); // disabled
+public:
+ ScUnoAddInHelpIdGenerator( const ::rtl::OUString& rServiceName );
+
+ /** Sets service name of the AddIn. Has to be done before requesting help IDs. */
+ void SetServiceName( const ::rtl::OUString& rServiceName );
+
+ /** @return The help ID of the function with given built-in name or 0 if not found. */
+ sal_uInt16 GetHelpId( const ::rtl::OUString& rFuncName ) const;
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/core/inc/addinlis.hxx b/sc/source/core/inc/addinlis.hxx
new file mode 100644
index 000000000000..6c0f98386920
--- /dev/null
+++ b/sc/source/core/inc/addinlis.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ADDINLIS_HXX
+#define SC_ADDINLIS_HXX
+
+#include "adiasync.hxx" // for ScAddInDocs PtrArr
+#include <tools/list.hxx>
+#include <com/sun/star/sheet/XResultListener.hpp>
+#include <com/sun/star/sheet/XVolatileResult.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+
+
+class ScDocument;
+
+
+class ScAddInListener : public cppu::WeakImplHelper2<
+ com::sun::star::sheet::XResultListener,
+ com::sun::star::lang::XServiceInfo >,
+ public SvtBroadcaster
+{
+private:
+ com::sun::star::uno::Reference<com::sun::star::sheet::XVolatileResult> xVolRes;
+ com::sun::star::uno::Any aResult;
+ ScAddInDocs* pDocs; // documents where this is used
+
+ static List aAllListeners;
+
+ // always allocated via CreateListener
+ ScAddInListener(
+ com::sun::star::uno::Reference<
+ com::sun::star::sheet::XVolatileResult> xVR,
+ ScDocument* pD );
+
+public:
+ virtual ~ScAddInListener();
+
+ // create Listener and put it into global list
+ static ScAddInListener* CreateListener(
+ com::sun::star::uno::Reference<
+ com::sun::star::sheet::XVolatileResult> xVR,
+ ScDocument* pDoc );
+
+ static ScAddInListener* Get( com::sun::star::uno::Reference<
+ com::sun::star::sheet::XVolatileResult> xVR );
+ static void RemoveDocument( ScDocument* pDocument );
+
+ BOOL HasDocument( ScDocument* pDoc ) const { return pDocs->Seek_Entry( pDoc ); }
+ void AddDocument( ScDocument* pDoc ) { pDocs->Insert( pDoc ); }
+ const com::sun::star::uno::Any& GetResult() const { return aResult; }
+
+
+ // XResultListener
+ virtual void SAL_CALL modified( const ::com::sun::star::sheet::ResultEvent& aEvent )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw(::com::sun::star::uno::RuntimeException);
+};
+
+
+#endif
+
diff --git a/sc/source/core/inc/adiasync.hxx b/sc/source/core/inc/adiasync.hxx
new file mode 100644
index 000000000000..4d0997fce63d
--- /dev/null
+++ b/sc/source/core/inc/adiasync.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ADIASYNC_HXX
+#define SC_ADIASYNC_HXX
+
+#include <svl/broadcast.hxx>
+#include <svl/svarray.hxx>
+
+#include "callform.hxx"
+
+extern "C" {
+void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData );
+}
+
+
+class ScAddInAsync;
+typedef ScAddInAsync* ScAddInAsyncPtr;
+SV_DECL_PTRARR_SORT( ScAddInAsyncs, ScAddInAsyncPtr, 4, 4 )
+extern ScAddInAsyncs theAddInAsyncTbl; // in adiasync.cxx
+
+class ScDocument;
+typedef ScDocument* ScAddInDocPtr;
+SV_DECL_PTRARR_SORT( ScAddInDocs, ScAddInDocPtr, 1, 1 )
+
+class String;
+
+class ScAddInAsync : public SvtBroadcaster
+{
+private:
+ union
+ {
+ double nVal; // aktueller Wert
+ String* pStr;
+ };
+ ScAddInDocs* pDocs; // Liste der benutzenden Dokumente
+ FuncData* pFuncData; // Zeiger auf die Daten in der Collection
+ ULONG nHandle; // wird von double auf ULONG gecasted
+ ParamType eType; // PTR_DOUBLE oder PTR_STRING Ergebnis
+ BOOL bValid; // ob Wert gueltig
+
+public:
+ // cTor nur wenn ScAddInAsync::Get fehlschlaegt!
+ // nIndex: Index aus der FunctionCollection
+ ScAddInAsync( ULONG nHandle, USHORT nIndex,
+ ScDocument* pDoc );
+ // default-cTor nur fuer das eine globale aSeekObj !!!
+ ScAddInAsync();
+ virtual ~ScAddInAsync();
+ static ScAddInAsync* Get( ULONG nHandle );
+ static void CallBack( ULONG nHandle, void* pData );
+ static void RemoveDocument( ScDocument* pDocument );
+ BOOL IsValid() const { return bValid; }
+ ParamType GetType() const { return eType; }
+ double GetValue() const { return nVal; }
+ const String& GetString() const { return *pStr; }
+ BOOL HasDocument( ScDocument* pDoc ) const
+ { return pDocs->Seek_Entry( pDoc ); }
+ void AddDocument( ScDocument* pDoc ) { pDocs->Insert( pDoc ); }
+
+ // Vergleichsoperatoren fuer PtrArrSort
+ BOOL operator < ( const ScAddInAsync& r ) { return nHandle < r.nHandle; }
+ BOOL operator ==( const ScAddInAsync& r ) { return nHandle == r.nHandle; }
+};
+
+
+
+#endif
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
new file mode 100644
index 000000000000..13384b033628
--- /dev/null
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -0,0 +1,306 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_BCASLOT_HXX
+#define SC_BCASLOT_HXX
+
+#include <set>
+#include <hash_set>
+#include <functional>
+#include <svl/broadcast.hxx>
+#include <svl/svarray.hxx>
+
+#include "global.hxx"
+#include "brdcst.hxx"
+
+/**
+ Used in a Unique Associative Container.
+ */
+
+class ScBroadcastArea
+{
+private:
+ ScBroadcastArea* pUpdateChainNext;
+ SvtBroadcaster aBroadcaster;
+ ScRange aRange;
+ ULONG nRefCount;
+ BOOL bInUpdateChain;
+
+public:
+ ScBroadcastArea( const ScRange& rRange )
+ : pUpdateChainNext( NULL ), aRange( rRange ),
+ nRefCount( 0 ), bInUpdateChain( FALSE ) {}
+ inline SvtBroadcaster& GetBroadcaster() { return aBroadcaster; }
+ inline const SvtBroadcaster& GetBroadcaster() const { return aBroadcaster; }
+ inline void UpdateRange( const ScRange& rNewRange )
+ { aRange = rNewRange; }
+ inline const ScRange& GetRange() const { return aRange; }
+ inline const ScAddress& GetStart() const { return aRange.aStart; }
+ inline const ScAddress& GetEnd() const { return aRange.aEnd; }
+ inline void IncRef() { ++nRefCount; }
+ inline ULONG DecRef() { return nRefCount ? --nRefCount : 0; }
+ inline ULONG GetRef() { return nRefCount; }
+ inline ScBroadcastArea* GetUpdateChainNext() const { return pUpdateChainNext; }
+ inline void SetUpdateChainNext( ScBroadcastArea* p ) { pUpdateChainNext = p; }
+ inline BOOL IsInUpdateChain() const { return bInUpdateChain; }
+ inline void SetInUpdateChain( BOOL b ) { bInUpdateChain = b; }
+
+ /** Equalness of this or range. */
+ inline bool operator==( const ScBroadcastArea & rArea ) const;
+};
+
+inline bool ScBroadcastArea::operator==( const ScBroadcastArea & rArea ) const
+{
+ return aRange == rArea.aRange;
+}
+
+//=============================================================================
+
+struct ScBroadcastAreaHash
+{
+ size_t operator()( const ScBroadcastArea* p ) const
+ {
+ return p->GetRange().hashArea();
+ }
+};
+
+struct ScBroadcastAreaEqual
+{
+ bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
+ {
+ return *p1 == *p2;
+ }
+};
+
+typedef ::std::hash_set< ScBroadcastArea*, ScBroadcastAreaHash, ScBroadcastAreaEqual > ScBroadcastAreas;
+
+//=============================================================================
+
+struct ScBroadcastAreaBulkHash
+{
+ size_t operator()( const ScBroadcastArea* p ) const
+ {
+ return reinterpret_cast<size_t>(p);
+ }
+};
+
+struct ScBroadcastAreaBulkEqual
+{
+ bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
+ {
+ return p1 == p2;
+ }
+};
+
+typedef ::std::hash_set< const ScBroadcastArea*, ScBroadcastAreaBulkHash,
+ ScBroadcastAreaBulkEqual > ScBroadcastAreasBulk;
+
+//=============================================================================
+
+class ScBroadcastAreaSlotMachine;
+
+/// Collection of BroadcastAreas
+class ScBroadcastAreaSlot
+{
+private:
+ ScBroadcastAreas aBroadcastAreaTbl;
+ mutable ScBroadcastArea aTmpSeekBroadcastArea; // for FindBroadcastArea()
+ ScDocument* pDoc;
+ ScBroadcastAreaSlotMachine* pBASM;
+
+ ScBroadcastAreas::iterator FindBroadcastArea( const ScRange& rRange ) const;
+
+ /**
+ More hypothetical (memory would probably be doomed anyway) check
+ whether there would be an overflow when adding an area, setting the
+ proper state if so.
+
+ @return TRUE if a HardRecalcState is effective and area is not to be
+ added.
+ */
+ bool CheckHardRecalcStateCondition() const;
+
+public:
+ ScBroadcastAreaSlot( ScDocument* pDoc,
+ ScBroadcastAreaSlotMachine* pBASM );
+ ~ScBroadcastAreaSlot();
+ const ScBroadcastAreas& GetBroadcastAreas() const
+ { return aBroadcastAreaTbl; }
+
+ /**
+ Only here new ScBroadcastArea objects are created, prevention of dupes.
+
+ @param rpArea
+ If NULL, a new ScBroadcastArea is created and assigned ton the
+ reference if a matching area wasn't found. If a matching area was
+ found, that is assigned. In any case, the SvtListener is added to
+ the broadcaster.
+
+ If not NULL then no listeners are startet, only the area is
+ inserted and the reference count incremented. Effectively the same
+ as InsertListeningArea(), so use that instead.
+
+ @return
+ TRUE if rpArea passed was NULL and ScBroadcastArea is newly
+ created.
+ */
+ bool StartListeningArea( const ScRange& rRange,
+ SvtListener* pListener,
+ ScBroadcastArea*& rpArea );
+
+ /**
+ Insert a ScBroadcastArea obtained via StartListeningArea() to
+ subsequent slots.
+ */
+ void InsertListeningArea( ScBroadcastArea* pArea );
+
+ void EndListeningArea( const ScRange& rRange,
+ SvtListener* pListener,
+ ScBroadcastArea*& rpArea );
+ BOOL AreaBroadcast( const ScHint& rHint ) const;
+ /// @return TRUE if at least one broadcast occurred.
+ BOOL AreaBroadcastInRange( const ScRange& rRange,
+ const ScHint& rHint ) const;
+ void DelBroadcastAreasInRange( const ScRange& rRange );
+ void UpdateRemove( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
+ void UpdateRemoveArea( ScBroadcastArea* pArea );
+ void UpdateInsert( ScBroadcastArea* pArea );
+};
+
+
+/**
+ BroadcastAreaSlots and their management, once per document.
+ */
+
+class ScBroadcastAreaSlotMachine
+{
+private:
+
+ /**
+ Slot offset arrangement of columns and rows, once per sheet.
+
+ +---+---+
+ | 0 | 3 |
+ +---+---+
+ | 1 | 4 |
+ +---+---+
+ | 2 | 5 |
+ +---+---+
+ */
+
+ class TableSlots
+ {
+ public:
+ TableSlots();
+ ~TableSlots();
+ inline ScBroadcastAreaSlot** getSlots() { return ppSlots; }
+
+ /**
+ Obtain slot pointer, no check on validity! It is assumed that
+ all calls are made with the results of ComputeSlotOffset(),
+ ComputeAreaPoints() and ComputeNextSlot()
+ */
+ inline ScBroadcastAreaSlot* getAreaSlot( SCSIZE nOff ) { return *(ppSlots + nOff); }
+
+ private:
+ ScBroadcastAreaSlot** ppSlots;
+
+ // prevent usage
+ TableSlots( const TableSlots& );
+ TableSlots& operator=( const TableSlots& );
+ };
+
+ typedef ::std::map< SCTAB, TableSlots* > TableSlotsMap;
+
+private:
+ ScBroadcastAreasBulk aBulkBroadcastAreas;
+ TableSlotsMap aTableSlotsMap;
+ SvtBroadcaster *pBCAlways; // for the RC_ALWAYS special range
+ ScDocument *pDoc;
+ ScBroadcastArea *pUpdateChain;
+ ScBroadcastArea *pEOUpdateChain;
+ ULONG nInBulkBroadcast;
+
+ inline SCSIZE ComputeSlotOffset( const ScAddress& rAddress ) const;
+ void ComputeAreaPoints( const ScRange& rRange,
+ SCSIZE& nStart, SCSIZE& nEnd,
+ SCSIZE& nRowBreak ) const;
+
+public:
+ ScBroadcastAreaSlotMachine( ScDocument* pDoc );
+ ~ScBroadcastAreaSlotMachine();
+ void StartListeningArea( const ScRange& rRange,
+ SvtListener* pListener );
+ void EndListeningArea( const ScRange& rRange,
+ SvtListener* pListener );
+ BOOL AreaBroadcast( const ScHint& rHint ) const;
+ // return: at least one broadcast occurred
+ BOOL AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint ) const;
+ void DelBroadcastAreasInRange( const ScRange& rRange );
+ void UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
+ void EnterBulkBroadcast();
+ void LeaveBulkBroadcast();
+ bool InsertBulkArea( const ScBroadcastArea* p );
+ /// @return: how many removed
+ size_t RemoveBulkArea( const ScBroadcastArea* p );
+ inline ScBroadcastArea* GetUpdateChain() const { return pUpdateChain; }
+ inline void SetUpdateChain( ScBroadcastArea* p ) { pUpdateChain = p; }
+ inline ScBroadcastArea* GetEOUpdateChain() const { return pEOUpdateChain; }
+ inline void SetEOUpdateChain( ScBroadcastArea* p ) { pEOUpdateChain = p; }
+ inline bool IsInBulkBroadcast() const { return nInBulkBroadcast > 0; }
+};
+
+
+class ScBulkBroadcast
+{
+ ScBroadcastAreaSlotMachine* pBASM;
+public:
+ explicit ScBulkBroadcast( ScBroadcastAreaSlotMachine* p ) : pBASM(p)
+ {
+ if (pBASM)
+ pBASM->EnterBulkBroadcast();
+ }
+ ~ScBulkBroadcast()
+ {
+ if (pBASM)
+ pBASM->LeaveBulkBroadcast();
+ }
+ void LeaveBulkBroadcast()
+ {
+ if (pBASM)
+ {
+ pBASM->LeaveBulkBroadcast();
+ pBASM = NULL;
+ }
+ }
+};
+
+#endif
diff --git a/sc/source/core/inc/cellkeytranslator.hxx b/sc/source/core/inc/cellkeytranslator.hxx
new file mode 100644
index 000000000000..536e521a78da
--- /dev/null
+++ b/sc/source/core/inc/cellkeytranslator.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CELLKEY_TRANSLATOR_HXX
+#define SC_CELLKEY_TRANSLATOR_HXX
+
+#include "global.hxx"
+#include "formula/opcode.hxx"
+#include "unotools/transliterationwrapper.hxx"
+#include <hash_map>
+#include <list>
+#include <memory>
+
+#include <com/sun/star/lang/Locale.hpp>
+
+struct TransItem;
+
+struct ScCellKeyword
+{
+ const sal_Char* mpName;
+ OpCode meOpCode;
+ const ::com::sun::star::lang::Locale& mrLocale;
+
+ ScCellKeyword(const sal_Char* pName, OpCode eOpCode, const ::com::sun::star::lang::Locale& rLocale);
+};
+
+typedef ::std::hash_map< String, ::std::list<ScCellKeyword>, ScStringHashCode, ::std::equal_to<String> > ScCellKeywordHashMap;
+
+/** Translate cell function keywords.
+
+ This class provides a convenient way to translate a string keyword used as
+ a cell function argument. Since Calc's built-in cell functions don't
+ localize string keywords, this class is used mainly to deal with an Excel
+ document where string names may be localized.
+
+ To use, simply call the
+
+ ScCellKeywordTranslator::transKeyword(...)
+
+ function.
+
+ Note that when the locale and/or the opcode is specified, the function
+ tries to find a string with matching locale and/or opcode. But when it
+ fails to find one that satisfies the specified locale and/or opcode, it
+ returns a translated string with non-matching locale and/or opcode if
+ available. */
+class ScCellKeywordTranslator
+{
+public:
+ static void transKeyword(String& rName, const ::com::sun::star::lang::Locale* pLocale = NULL, OpCode eOpCode = ocNone);
+ ~ScCellKeywordTranslator();
+
+private:
+ ScCellKeywordTranslator();
+
+ void init();
+ void addToMap(const String& rKey, const sal_Char* pName,
+ const ::com::sun::star::lang::Locale& rLocale,
+ OpCode eOpCode = ocNone);
+ void addToMap(const TransItem* pItems, const ::com::sun::star::lang::Locale& rLocale);
+
+ static ::std::auto_ptr<ScCellKeywordTranslator> spInstance;
+ ScCellKeywordHashMap maStringNameMap;
+ ::utl::TransliterationWrapper maTransWrapper;
+};
+
+#endif
diff --git a/sc/source/core/inc/core_pch.hxx b/sc/source/core/inc/core_pch.hxx
new file mode 100644
index 000000000000..899169154d8d
--- /dev/null
+++ b/sc/source/core/inc/core_pch.hxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ItemID-Defines etc. muessen immer ganz vorne stehen
+
+#include "scitems.hxx"
+
+
+#define _ZFORLIST_DECLARE_TABLE
+
+#define SC_PROGRESS_CXX
+
+// ab hier automatisch per makepch generiert
+// folgende duerfen nicht aufgenommen werden:
+// setjmp.h
+
+#include <tools/solar.h>
+#include <string.h>
+#include <tools/string.hxx>
+#include <tools/rtti.hxx>
+#include <limits.h>
+#include <tools/ref.hxx>
+#include <tools/list.hxx>
+#include <tools/contnr.hxx>
+#include <tools/link.hxx>
+#include <tools/stream.hxx>
+#include <tools/errinf.hxx>
+#include <tools/errcode.hxx>
+#include <vcl/sv.h>
+#include <global.hxx>
+#include <tools/color.hxx>
+#include <i18npool/lang.h>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svl/svarray.hxx>
+#include <markarr.hxx>
+#include <vcl/timer.hxx>
+#include <rangelst.hxx>
+#include <document.hxx>
+#include <vcl/prntypes.hxx>
+#include <table.hxx>
+#include <column.hxx>
+#include <svl/hint.hxx>
+#include <svl/lstner.hxx>
+#include <svl/poolitem.hxx>
+#include <tools/time.hxx>
+#include <svl/solar.hrc>
+#include <tools/date.hxx>
+#include <svl/brdcst.hxx>
+#include <svx/svxids.hrc>
+#include <svl/memberid.hrc>
+#include <sfx2/sfx.hrc>
+#include <sfx2/sfxsids.hrc>
+#include <svl/cntwids.hrc>
+#include <tools/resid.hxx>
+#include <tools/table.hxx>
+#include <stdarg.h>
+#include <tools/rc.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/unqidx.hxx>
+#include <rsc/rscsfx.hxx>
+#include <basic/sbxdef.hxx>
+#include <svl/itemset.hxx>
+#include <stddef.h>
+#include <collect.hxx>
+#include <scitems.hxx>
+#include <tools/globname.hxx>
+#include <tools/fract.hxx>
+#include <sfx2/shell.hxx>
+#include <cell.hxx>
+#include <tools/mempool.hxx>
+#include <vcl/color.hxx>
+#include <vcl/region.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/bitmap.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <sot/object.hxx>
+#include <sot/factory.hxx>
+#include <sot/sotdata.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/keycodes.hxx>
+#include <sot/sotref.hxx>
+#include <rechead.hxx>
+#include <tools/unqid.hxx>
+#include <vcl/apptypes.hxx>
+#include <vcl/vclenum.hxx>
+#include <globstr.hrc>
+#include <formula/compiler.hrc>
+#include <tools/shl.hxx>
+#include <compiler.hxx>
+#include <vcl/font.hxx>
+#include <svl/smplhint.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/accel.hxx>
+#include <patattr.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/pstm.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/pointr.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/wintypes.hxx>
+#include <vcl/event.hxx>
+#include <tools/ownlist.hxx>
+#include <svl/itempool.hxx>
+#include <tools/datetime.hxx>
+#include <attrib.hxx>
+#include <docpool.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/window.hxx>
+#include <svtools/confitem.hxx>
+#include <vcl/syswin.hxx>
+#include <sc.hrc>
+#include <svx/dialogs.hrc>
+#include <math.h>
+#include <svl/style.hxx>
+#include <svl/style.hrc>
+#include <stdlib.h>
+#include <vcl/prntypes.hxx>
+#include <vcl/jobset.hxx>
+#include <vcl/gdimtf.hxx>
+//#include <setjmp.h>
+#include <tools/urlobj.hxx>
+#include <vcl/print.hxx>
+#include <docoptio.hxx>
+#include <markdata.hxx>
+#include <vcl/wrkwin.hxx>
+#include <stlpool.hxx>
+#include <sfx2/app.hxx>
+#include <svl/inetmsg.hxx>
+#include <svtools/compat.hxx>
+#include <svl/inetdef.hxx>
+#include <svl/inethist.hxx>
+#include <vcl/accel.hxx>
+#include <sfx2/sfxdefs.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/imgdef.hxx>
+#include <vcl/ctrl.hxx>
+#include <vcl/field.hxx>
+#include <vcl/spinfld.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/combobox.h>
+#include <refupdat.hxx>
+#include <editeng/boxitem.hxx>
+#include <conditio.hxx>
+#include <brdcst.hxx>
+#include <editeng/svxenum.hxx>
+#include <dociter.hxx>
+#include <scdll.hxx>
+#include <stdio.h>
+#include <stlsheet.hxx>
+#include <vcl/gdiobj.hxx>
+#include <vcl/mapmod.hxx>
+#include <progress.hxx>
+#include <sfx2/progress.hxx>
+#include <vcl/event.hxx>
+#include <vcl/window.hxx>
+#include <svx/algitem.hxx>
+#include <vcl/field.hxx>
+#include <svx/svdtypes.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/animate.hxx>
+#include <vcl/graph.h>
+#include <drwlayer.hxx>
+#include <svx/svdmodel.hxx>
+#include <scresid.hxx>
+#include <vcl/print.hxx>
+#include <attarray.hxx>
+#include <svl/ownlist.hxx>
+#include <interpre.hxx>
+#include <subtotal.hxx>
+#include <rangenam.hxx>
+#include <scmatrix.hxx>
+#include <svx/pageitem.hxx>
+#include <dbcolect.hxx>
+#include <userlist.hxx>
+#include <editeng/editdata.hxx>
+#include <basic/sbxvar.hxx>
+#include <basic/sbxcore.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdsob.hxx>
+#include <svx/svdglue.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <callform.hxx>
+#include <validat.hxx>
+#include <editeng/brshitem.hxx>
+#include <sot/exchange.hxx>
+#include <editeng/editeng.hxx>
+#include <vcl/fonttype.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svl/stritem.hxx>
+#include <pivot.hxx>
+#include <vcl/gdimtf.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdlayer.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <ctype.h>
+#include <vcl/font.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <svx/svditer.hxx>
+#include <editeng/udlnitem.hxx>
+#include <adiasync.hxx>
+#include <sfx2/bindings.hxx>
+#include <ddelink.hxx>
+#include <chartlis.hxx>
+#include <sfx2/minarray.hxx>
+#include <svtools/txtcmp.hxx>
+#include <olinetab.hxx>
+#include <basic/sbxobj.hxx>
+#include <cfgids.hxx>
+
+
+
+
diff --git a/sc/source/core/inc/ddelink.hxx b/sc/source/core/inc/ddelink.hxx
new file mode 100644
index 000000000000..4f0652753e65
--- /dev/null
+++ b/sc/source/core/inc/ddelink.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_DDELINK_HXX
+#define SC_DDELINK_HXX
+
+#include "address.hxx"
+#include <sfx2/lnkbase.hxx>
+#include <svl/broadcast.hxx>
+#include "scmatrix.hxx"
+
+class ScDocument;
+class ScMultipleReadHeader;
+class ScMultipleWriteHeader;
+class SvStream;
+
+class ScDdeLink : public ::sfx2::SvBaseLink, public SvtBroadcaster
+{
+private:
+static BOOL bIsInUpdate;
+
+ ScDocument* pDoc;
+
+ String aAppl; // Verbindungsdaten
+ String aTopic;
+ String aItem;
+ BYTE nMode; // Zahlformat-Modus
+
+ BOOL bNeedUpdate; // wird gesetzt, wenn Update nicht moeglich war
+
+ ScMatrixRef pResult; // Ergebnis
+
+public:
+ TYPEINFO();
+
+ ScDdeLink( ScDocument* pD,
+ const String& rA, const String& rT, const String& rI,
+ BYTE nM );
+ ScDdeLink( ScDocument* pD, SvStream& rStream, ScMultipleReadHeader& rHdr );
+ ScDdeLink( ScDocument* pD, const ScDdeLink& rOther );
+ virtual ~ScDdeLink();
+
+ void Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const;
+
+ // von SvBaseLink ueberladen:
+ virtual void DataChanged( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue );
+
+ // von SvtBroadcaster ueberladen:
+ virtual void ListenersGone();
+
+ // fuer Interpreter:
+
+ const ScMatrix* GetResult() const { return pResult; }
+ void SetResult( ScMatrix* pRes ) { pResult = pRes; }
+
+ // XML and Excel import after NewData()
+ ScMatrixRef GetModifiableResult() { return pResult; }
+
+ const String& GetAppl() const { return aAppl; }
+ const String& GetTopic() const { return aTopic; }
+ const String& GetItem() const { return aItem; }
+ BYTE GetMode() const { return nMode; }
+
+ void ResetValue(); // Wert zuruecksetzen
+ void TryUpdate();
+
+ BOOL NeedsUpdate() const { return bNeedUpdate; }
+
+ static BOOL IsInUpdate() { return bIsInUpdate; }
+};
+
+
+#endif
+
diff --git a/sc/source/core/inc/doubleref.hxx b/sc/source/core/inc/doubleref.hxx
new file mode 100644
index 000000000000..10221d942c9c
--- /dev/null
+++ b/sc/source/core/inc/doubleref.hxx
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * 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: interpre.hxx,v $
+ * $Revision: 1.35.44.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.
+ *
+ ************************************************************************/
+
+#ifndef SC_DOUBLEREF_HXX
+#define SC_DOUBLEREF_HXX
+
+#include "address.hxx"
+#include "scmatrix.hxx"
+
+class ScDocument;
+class ScBaseCell;
+struct ScDBQueryParamBase;
+struct ScQueryParamBase;
+
+// ============================================================================
+
+/**
+ * Base class for abstracting range data backends for database functions.
+ */
+class ScDBRangeBase
+{
+public:
+ enum RefType { INTERNAL, EXTERNAL }; // TODO: We may not need this after all... (kohei)
+
+ virtual ~ScDBRangeBase() = 0;
+
+ bool fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const;
+
+ virtual SCCOL getColSize() const = 0;
+ virtual SCROW getRowSize() const = 0;
+ virtual SCSIZE getVisibleDataCellCount() const = 0;
+
+ /**
+ * Get a string value of a specified cell position. Note that the
+ * position of the upper left cell of the range is always (0, 0) even if
+ * the reference type is of internal range.
+ *
+ * @param nCol column position (0 to column size-1)
+ * @param nRow row position (0 to row size-1)
+ */
+ virtual ::rtl::OUString getString(SCCOL nCol, SCROW nRow) const = 0;
+
+ virtual SCCOL getFirstFieldColumn() const = 0;
+
+ /**
+ * Get a <i>0-based</i> column index that corresponds with the passed field
+ * index. Note that the field index passed as the 1st parameter is
+ * <i>1-based.</i>
+ *
+ * @param nIndex 1-based field index.
+ *
+ * @return 0-based column index
+ */
+ virtual SCCOL findFieldColumn(SCCOL nIndex) const = 0;
+ virtual SCCOL findFieldColumn(const ::rtl::OUString& rStr, sal_uInt16* pErr = NULL) const = 0;
+ virtual ScDBQueryParamBase* createQueryParam(const ScDBRangeBase* pQueryRef) const = 0;
+ virtual bool isRangeEqual(const ScRange& rRange) const = 0;
+
+protected:
+ ScDBRangeBase(ScDocument* pDoc, RefType eType);
+ ScDocument* getDoc() const;
+
+ /**
+ * Populate query options that are always the same for all database
+ * queries.
+ */
+ static void fillQueryOptions(ScQueryParamBase* pParam);
+
+private:
+ ScDBRangeBase(); // disabled
+
+ ScDocument* mpDoc;
+ RefType meType;
+};
+
+// ============================================================================
+
+class ScDBInternalRange : public ScDBRangeBase
+{
+public:
+ explicit ScDBInternalRange(ScDocument* pDoc, const ScRange& rRange);
+ virtual ~ScDBInternalRange();
+
+ const ScRange& getRange() const;
+
+ virtual SCCOL getColSize() const;
+ virtual SCROW getRowSize() const;
+ virtual SCSIZE getVisibleDataCellCount() const;
+
+ /**
+ * Get a string value of a specified cell position. Note that the
+ * position of the upper left cell of the range is always (0, 0) even if
+ * the reference type is of internal range.
+ *
+ * @param nCol column position (0 to column size-1)
+ * @param nRow row position (0 to row size-1)
+ */
+ virtual ::rtl::OUString getString(SCCOL nCol, SCROW nRow) const;
+
+ virtual SCCOL getFirstFieldColumn() const;
+ /**
+ * Get a <i>0-based</i> column index that corresponds with the passed field
+ * index. Note that the field index passed as the 1st parameter is
+ * <i>1-based.</i>
+ *
+ * @param nIndex 1-based field index.
+ *
+ * @return 0-based column index
+ */
+ virtual SCCOL findFieldColumn(SCCOL nIndex) const;
+ virtual SCCOL findFieldColumn(const ::rtl::OUString& rStr, sal_uInt16* pErr = NULL) const;
+ virtual ScDBQueryParamBase* createQueryParam(const ScDBRangeBase* pQueryRef) const;
+ virtual bool isRangeEqual(const ScRange& rRange) const;
+
+private:
+ sal_uInt16 getCellString(::rtl::OUString& rStr, ScBaseCell* pCell) const;
+
+private:
+ ScRange maRange;
+};
+
+// ============================================================================
+
+class ScDBExternalRange : public ScDBRangeBase
+{
+public:
+ explicit ScDBExternalRange(ScDocument* pDoc, const ScMatrixRef& pMat);
+ virtual ~ScDBExternalRange();
+
+ virtual SCCOL getColSize() const;
+ virtual SCROW getRowSize() const;
+ virtual SCSIZE getVisibleDataCellCount() const;
+
+ /**
+ * Get a string value of a specified cell position. Note that the
+ * position of the upper left cell of the range is always (0, 0) even if
+ * the reference type is of internal range.
+ *
+ * @param nCol column position (0 to column size-1)
+ * @param nRow row position (0 to row size-1)
+ */
+ virtual ::rtl::OUString getString(SCCOL nCol, SCROW nRow) const;
+
+ virtual SCCOL getFirstFieldColumn() const;
+
+ /**
+ * Get a <i>0-based</i> column index that corresponds with the passed field
+ * index. Note that the field index passed as the 1st parameter is
+ * <i>1-based.</i>
+ *
+ * @param nIndex 1-based field index.
+ *
+ * @return 0-based column index
+ */
+ virtual SCCOL findFieldColumn(SCCOL nIndex) const;
+ virtual SCCOL findFieldColumn(const ::rtl::OUString& rStr, sal_uInt16* pErr = NULL) const;
+ virtual ScDBQueryParamBase* createQueryParam(const ScDBRangeBase* pQueryRef) const;
+ virtual bool isRangeEqual(const ScRange& rRange) const;
+
+private:
+ const ScMatrixRef mpMatrix;
+ SCCOL mnCols;
+ SCROW mnRows;
+};
+
+#endif
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
new file mode 100644
index 000000000000..edecaadb39f0
--- /dev/null
+++ b/sc/source/core/inc/interpre.hxx
@@ -0,0 +1,905 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_INTERPRE_HXX
+#define SC_INTERPRE_HXX
+
+#include <math.h>
+#include <rtl/math.hxx>
+#include "formula/errorcodes.hxx"
+#include "cell.hxx"
+#include "scdll.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+
+#include <math.h>
+#include <map>
+
+class ScDocument;
+class SbxVariable;
+class ScBaseCell;
+class ScFormulaCell;
+class SvNumberFormatter;
+class ScDBRangeBase;
+struct MatrixDoubleOp;
+struct ScQueryParam;
+struct ScDBQueryParamBase;
+
+struct ScCompare
+{
+ double nVal[2];
+ String* pVal[2];
+ BOOL bVal[2];
+ BOOL bEmpty[2];
+ ScCompare( String* p1, String* p2 )
+ {
+ pVal[ 0 ] = p1;
+ pVal[ 1 ] = p2;
+ bEmpty[0] = FALSE;
+ bEmpty[1] = FALSE;
+ }
+};
+
+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*))
+
+class ScTokenStack
+{
+public:
+ DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack )
+ formula::FormulaToken* pPointer[ MAXSTACK ];
+};
+
+enum ScIterFunc {
+ ifSUM, // Aufsummieren
+ ifSUMSQ, // Quadratsummen
+ ifPRODUCT, // Multiplizieren
+ ifAVERAGE, // Durchschnitt
+ ifCOUNT, // Anzahl Werte
+ ifCOUNT2, // Anzahl Werte (nichtleer)
+ ifMIN, // Minimum
+ ifMAX // Maximum
+};
+
+struct FormulaTokenRef_less
+{
+ bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
+ { return &r1 < &r2; }
+};
+typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
+
+class ScInterpreter
+{
+ // distibution function objects need the GetxxxDist methods
+ friend class ScGammaDistFunction;
+ friend class ScBetaDistFunction;
+ friend class ScTDistFunction;
+ friend class ScFDistFunction;
+ friend class ScChiDistFunction;
+ friend class ScChiSqDistFunction;
+
+public:
+ DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter )
+
+ static void GlobalExit(); // aus ScGlobal::Clear() gerufen
+
+ /// Could string be a regular expression?
+ /// If pDoc!=NULL the document options are taken into account and if
+ /// RegularExpressions are disabled the function returns FALSE regardless
+ /// of the string content.
+ static BOOL MayBeRegExp( const String& rStr, const ScDocument* pDoc );
+
+ /// Fail safe division, returning an errDivisionByZero coded into a double
+ /// if denominator is 0.0
+ static inline double div( const double& fNumerator, const double& fDenominator );
+
+ ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR);
+private:
+ static ScTokenStack* pGlobalStack;
+ static BOOL bGlobalStackInUse;
+
+ formula::FormulaTokenIterator aCode;
+ ScAddress aPos;
+ ScTokenArray& rArr;
+ ScDocument* pDok;
+ formula::FormulaTokenRef xResult;
+ ScJumpMatrix* pJumpMatrix; // currently active array condition, if any
+ ScTokenMatrixMap* pTokenMatrixMap; // map ScToken* to formula::FormulaTokenRef if in array condition
+ ScFormulaCell* pMyFormulaCell; // the cell of this formula expression
+ SvNumberFormatter* pFormatter;
+
+ const formula::FormulaToken*
+ pCur; // current token
+ String aTempStr; // for GetString()
+ ScTokenStack* pStackObj; // contains the stacks
+ formula::FormulaToken** pStack; // the current stack
+ USHORT nGlobalError; // global (local to this formula expression) error
+ USHORT sp; // stack pointer
+ USHORT maxsp; // the maximal used stack pointer
+ ULONG nFuncFmtIndex; // NumberFormatIndex of a function
+ ULONG nCurFmtIndex; // current NumberFormatIndex
+ ULONG nRetFmtIndex; // NumberFormatIndex of an expression, if any
+ short nFuncFmtType; // NumberFormatType of a function
+ short nCurFmtType; // current NumberFormatType
+ short nRetFmtType; // NumberFormatType of an expression
+ USHORT mnStringNoValueError; // the error set in ConvertStringToValue() if no value
+ BOOL glSubTotal; // flag for subtotal functions
+ BYTE cPar; // current count of parameters
+ BOOL bCalcAsShown; // precision as shown
+ BOOL bMatrixFormula; // formula cell is a matrix formula
+
+//---------------------------------Funktionen in interpre.cxx---------
+// nMust <= nAct <= nMax ? ok : PushError
+inline BOOL MustHaveParamCount( short nAct, short nMust );
+inline BOOL MustHaveParamCount( short nAct, short nMust, short nMax );
+inline BOOL MustHaveParamCountMin( short nAct, short nMin );
+void PushParameterExpected();
+void PushIllegalParameter();
+void PushIllegalArgument();
+void PushNoValue();
+void PushNA();
+//-------------------------------------------------------------------------
+// Funktionen fuer den Zugriff auf das Document
+//-------------------------------------------------------------------------
+void ReplaceCell( ScAddress& ); // for TableOp
+void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab ); // for TableOp
+BOOL IsTableOpInRange( const ScRange& );
+ULONG GetCellNumberFormat( const ScAddress&, const ScBaseCell* );
+double ConvertStringToValue( const String& );
+double GetCellValue( const ScAddress&, const ScBaseCell* );
+double GetCellValueOrZero( const ScAddress&, const ScBaseCell* );
+double GetValueCellValue( const ScAddress&, const ScValueCell* );
+ScBaseCell* GetCell( const ScAddress& rPos )
+ { return pDok->GetCell( rPos ); }
+void GetCellString( String& rStr, const ScBaseCell* pCell );
+inline USHORT GetCellErrCode( const ScBaseCell* pCell )
+ { return pCell ? pCell->GetErrorCode() : 0; }
+inline CellType GetCellType( const ScBaseCell* pCell )
+ { return pCell ? pCell->GetCellType() : CELLTYPE_NONE; }
+/// Really empty or inherited emptiness.
+inline BOOL HasCellEmptyData( const ScBaseCell* pCell )
+ { return pCell ? pCell->HasEmptyData() : TRUE; }
+/// This includes inherited emptiness, which usually is regarded as value!
+inline BOOL HasCellValueData( const ScBaseCell* pCell )
+ { return pCell ? pCell->HasValueData() : FALSE; }
+/// Not empty and not value.
+inline BOOL HasCellStringData( const ScBaseCell* pCell )
+ { return pCell ? pCell->HasStringData() : FALSE; }
+
+BOOL CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr);
+BOOL CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr);
+BOOL CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr);
+
+//-----------------------------------------------------------------------------
+// Stack operations
+//-----------------------------------------------------------------------------
+
+/** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
+ passed is not formula::FormulaErrorToken.
+ Increments RefCount of the original token if not substituted. */
+void Push( formula::FormulaToken& r );
+
+/** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
+ Used to push RPN tokens or from within Push() or tokens that are already
+ explicit formula::FormulaErrorToken. Increments RefCount. */
+void PushWithoutError( formula::FormulaToken& r );
+
+/** Clones the token to be pushed or substitutes with formula::FormulaErrorToken if
+ nGlobalError is set and the token passed is not formula::FormulaErrorToken. */
+void PushTempToken( const formula::FormulaToken& );
+
+/** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
+ passed is not formula::FormulaErrorToken.
+ Increments RefCount of the original token if not substituted.
+ ATTENTION! The token had to be allocated with `new' and must not be used
+ after this call if no RefCount was set because possibly it gets immediately
+ deleted in case of an errStackOverflow or if substituted with formula::FormulaErrorToken! */
+void PushTempToken( formula::FormulaToken* );
+
+/** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
+ Used to push tokens from within PushTempToken() or tokens that are already
+ explicit formula::FormulaErrorToken. Increments RefCount.
+ ATTENTION! The token had to be allocated with `new' and must not be used
+ after this call if no RefCount was set because possibly it gets immediately
+ decremented again and thus deleted in case of an errStackOverflow! */
+void PushTempTokenWithoutError( formula::FormulaToken* );
+
+/** If nGlobalError is set push formula::FormulaErrorToken.
+ If nGlobalError is not set do nothing.
+ Used in PushTempToken() and alike to simplify handling.
+ @return: <TRUE/> if nGlobalError. */
+inline bool IfErrorPushError()
+{
+ if (nGlobalError)
+ {
+ PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError));
+ return true;
+ }
+ return false;
+}
+
+/** Obtain cell result / content from address and push as temp token.
+ bDisplayEmptyAsString is passed to ScEmptyCell in case of an empty cell
+ result. Also obtain number format and type if _both_, type and index
+ pointer, are not NULL. */
+void PushCellResultToken( bool bDisplayEmptyAsString, const ScAddress & rAddress,
+ short * pRetTypeExpr, ULONG * pRetIndexExpr );
+
+formula::FormulaTokenRef PopToken();
+void Pop();
+void PopError();
+double PopDouble();
+const String& PopString();
+void ValidateRef( const ScSingleRefData & rRef );
+void ValidateRef( const ScComplexRefData & rRef );
+void ValidateRef( const ScRefList & rRefList );
+void SingleRefToVars( const ScSingleRefData & rRef, SCCOL & rCol, SCROW & rRow, SCTAB & rTab );
+void PopSingleRef( ScAddress& );
+void PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab);
+void DoubleRefToRange( const ScComplexRefData&, ScRange&, BOOL bDontCheckForTableOp = FALSE );
+/** If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of
+ ScComplexRefData.
+ Else if StackVar svRefList return values of the ScComplexRefData where
+ rRefInList is pointing to. rRefInList is incremented. If rRefInList was the
+ last element in list pop ScRefListToken and set rRefInList to 0, else
+ rParam is incremented (!) to allow usage as in
+ while(nParamCount--) PopDoubleRef(aRange,nParamCount,nRefInList);
+ */
+void PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList );
+void PopDoubleRef( ScRange&, BOOL bDontCheckForTableOp = FALSE );
+void DoubleRefToVars( const ScToken* p,
+ SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
+ SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
+ BOOL bDontCheckForTableOp = FALSE );
+ScDBRangeBase* PopDoubleRef();
+void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
+ SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
+ BOOL bDontCheckForTableOp = FALSE );
+BOOL PopDoubleRefOrSingleRef( ScAddress& rAdr );
+void PopDoubleRefPushMatrix();
+// If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
+// Else convert area reference parameters marked as ForceArray to array.
+// Returns TRUE if JumpMatrix created.
+bool ConvertMatrixParameters();
+inline void MatrixDoubleRefToMatrix(); // if MatrixFormula: PopDoubleRefPushMatrix
+// If MatrixFormula or ForceArray: ConvertMatrixParameters()
+inline bool MatrixParameterConversion();
+ScMatrixRef PopMatrix();
+//void PushByte(BYTE nVal);
+void PushDouble(double nVal);
+void PushInt( int nVal );
+void PushStringBuffer( const sal_Unicode* pString );
+void PushString( const String& rString );
+void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab);
+void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
+void PushMatrix(ScMatrix* pMat);
+void PushError( USHORT nError );
+/// Raw stack type without default replacements.
+formula::StackVar GetRawStackType();
+/// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble.
+formula::StackVar GetStackType();
+// peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ...
+formula::StackVar GetStackType( BYTE nParam );
+BYTE GetByte() { return cPar; }
+// generiert aus DoubleRef positionsabhaengige SingleRef
+BOOL DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
+double GetDouble();
+double GetDoubleWithDefault(double nDefault);
+BOOL IsMissing();
+BOOL GetBool() { return GetDouble() != 0.0; }
+const String& GetString();
+// pop matrix and obtain one element, upper left or according to jump matrix
+ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, String& rString );
+ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2 );
+inline ScTokenMatrixMap& GetTokenMatrixMap();
+ScTokenMatrixMap* CreateTokenMatrixMap();
+ScMatrixRef GetMatrix();
+void ScTableOp(); // Mehrfachoperationen
+void ScErrCell(); // Sonderbehandlung
+ // Fehlerzelle
+//-----------------------------allgemeine Hilfsfunktionen
+void SetMaxIterationCount(USHORT n);
+inline void CurFmtToFuncFmt()
+ { nFuncFmtType = nCurFmtType; nFuncFmtIndex = nCurFmtIndex; }
+// Check for String overflow of rResult+rAdd and set error and erase rResult
+// if so. Return TRUE if ok, FALSE if overflow
+inline BOOL CheckStringResultLen( String& rResult, const String& rAdd );
+// Set error according to rVal, and set rVal to 0.0 if there was an error.
+inline void TreatDoubleError( double& rVal );
+// Lookup using ScLookupCache, @returns TRUE if found and result address
+bool LookupQueryWithCache( ScAddress & o_rResultPos,
+ const ScQueryParam & rParam ) const;
+
+//---------------------------------Funktionen in interpr1.cxx---------
+void ScIfJump();
+void ScChoseJump();
+
+// Be sure to only call this if pStack[sp-nStackLevel] really contains a
+// ScJumpMatrixToken, no further checks are applied!
+// Returns true if last jump was executed and result matrix pushed.
+bool JumpMatrix( short nStackLevel );
+
+/** @param pOptions
+ NULL means case sensitivity document option is to be used!
+ */
+double CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions = NULL );
+double Compare();
+/** @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();
+void ScGreater();
+void ScLessEqual();
+void ScGreaterEqual();
+void ScAnd();
+void ScOr();
+void ScNot();
+void ScNeg();
+void ScPercentSign();
+void ScIntersect();
+void ScRangeFunc();
+void ScUnionFunc();
+void ScPi();
+void ScRandom();
+void ScTrue();
+void ScFalse();
+void ScDeg();
+void ScRad();
+void ScSin();
+void ScCos();
+void ScTan();
+void ScCot();
+void ScArcSin();
+void ScArcCos();
+void ScArcTan();
+void ScArcCot();
+void ScSinHyp();
+void ScCosHyp();
+void ScTanHyp();
+void ScCotHyp();
+void ScArcSinHyp();
+void ScArcCosHyp();
+void ScArcTanHyp();
+void ScArcCotHyp();
+void ScExp();
+void ScLn();
+void ScLog10();
+void ScSqrt();
+void ScIsEmpty();
+short IsString();
+void ScIsString();
+void ScIsNonString();
+void ScIsLogical();
+void ScType();
+void ScCell();
+void ScIsRef();
+void ScIsValue();
+void ScIsFormula();
+void ScFormula();
+void ScRoman();
+void ScArabic();
+void ScIsNV();
+void ScIsErr();
+void ScIsError();
+short IsEven();
+void ScIsEven();
+void ScIsOdd();
+void ScN();
+void ScCode();
+void ScTrim();
+void ScUpper();
+void ScPropper();
+void ScLower();
+void ScLen();
+void ScT();
+void ScValue();
+void ScClean();
+void ScChar();
+void ScJis();
+void ScAsc();
+void ScUnicode();
+void ScUnichar();
+void ScMin( BOOL bTextAsZero = FALSE );
+void ScMax( BOOL bTextAsZero = FALSE );
+double IterateParameters( ScIterFunc, BOOL bTextAsZero = FALSE );
+void ScSumSQ();
+void ScSum();
+void ScProduct();
+void ScAverage( BOOL bTextAsZero = FALSE );
+void ScCount();
+void ScCount2();
+void GetStVarParams( double& rVal, double& rValCount, BOOL bTextAsZero = FALSE );
+void ScVar( BOOL bTextAsZero = FALSE );
+void ScVarP( BOOL bTextAsZero = FALSE );
+void ScStDev( BOOL bTextAsZero = FALSE );
+void ScStDevP( BOOL bTextAsZero = FALSE );
+void ScColumns();
+void ScRows();
+void ScTables();
+void ScColumn();
+void ScRow();
+void ScTable();
+void ScMatch();
+void ScCountIf();
+void ScSumIf();
+void ScCountEmptyCells();
+void ScLookup();
+void ScHLookup();
+void ScVLookup();
+void ScSubTotal();
+
+// If upon call rMissingField==TRUE then the database field parameter may be
+// missing (Xcl DCOUNT() syntax), or may be faked as missing by having the
+// value 0.0 or being exactly the entire database range reference (old SO
+// compatibility). If this was the case then rMissingField is set to TRUE upon
+// return. If rMissingField==FALSE upon call all "missing cases" are considered
+// to be an error.
+ScDBQueryParamBase* GetDBParams( BOOL& rMissingField );
+
+void DBIterator( ScIterFunc );
+void ScDBSum();
+void ScDBCount();
+void ScDBCount2();
+void ScDBAverage();
+void ScDBGet();
+void ScDBMax();
+void ScDBMin();
+void ScDBProduct();
+void GetDBStVarParams( double& rVal, double& rValCount );
+void ScDBStdDev();
+void ScDBStdDevP();
+void ScDBVar();
+void ScDBVarP();
+void ScIndirect();
+void ScAddressFunc();
+void ScOffset();
+void ScIndex();
+void ScMultiArea();
+void ScAreas();
+void ScCurrency();
+void ScReplace();
+void ScFixed();
+void ScFind();
+void ScExact();
+void ScLeft();
+void ScRight();
+void ScSearch();
+void ScMid();
+void ScText();
+void ScSubstitute();
+void ScRept();
+void ScConcat();
+void ScExternal();
+void ScMissing();
+void ScMacro();
+BOOL SetSbxVariable( SbxVariable* pVar, const ScAddress& );
+BOOL SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab );
+void ScErrorType();
+void ScDBArea();
+void ScColRowNameAuto();
+void ScExternalRef();
+void ScGetPivotData();
+void ScHyperLink();
+void ScBahtText();
+void ScTTT();
+
+//----------------Funktionen in interpr2.cxx---------------
+
+/** Obtain the date serial number for a given date.
+ @param bStrict
+ If FALSE, nYear < 100 takes the two-digit year setting into account,
+ and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
+ 1999-03-03.
+ If TRUE, the date passed must be a valid Gregorian calendar date. No
+ two-digit expanding or rollover is done.
+ */
+double GetDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, bool bStrict );
+
+void ScGetActDate();
+void ScGetActTime();
+void ScGetYear();
+void ScGetMonth();
+void ScGetDay();
+void ScGetDayOfWeek();
+void ScGetWeekOfYear();
+void ScEasterSunday();
+void ScGetHour();
+void ScGetMin();
+void ScGetSec();
+void ScPlusMinus();
+void ScAbs();
+void ScInt();
+void ScEven();
+void ScOdd();
+void ScCeil();
+void ScFloor();
+void RoundNumber( rtl_math_RoundingMode eMode );
+void ScRound();
+void ScRoundUp();
+void ScRoundDown();
+void ScGetDateValue();
+void ScGetTimeValue();
+void ScArcTan2();
+void ScLog();
+void ScGetDate();
+void ScGetTime();
+void ScGetDiffDate();
+void ScGetDiffDate360();
+void ScPower();
+void ScAmpersand();
+void ScAdd();
+void ScSub();
+void ScMul();
+void ScDiv();
+void ScPow();
+void ScCurrent();
+void ScStyle();
+void ScDde();
+void ScBase();
+void ScDecimal();
+void ScConvert();
+void ScEuroConvert();
+
+//----------------------- Finanzfunktionen ------------------------------------
+void ScNPV();
+void ScIRR();
+void ScMIRR();
+void ScISPMT();
+
+double ScGetBw(double fZins, double fZzr, double fRmz,
+ double fZw, double fF);
+void ScBW();
+void ScDIA();
+double ScGetGDA(double fWert, double fRest, double fDauer,
+ double fPeriode, double fFaktor);
+void ScGDA();
+void ScGDA2();
+double ScInterVDB(double fWert,double fRest,double fDauer,double fDauer1,
+ double fPeriode,double fFaktor);
+void ScVDB();
+void ScLaufz();
+void ScLIA();
+double ScGetRmz(double fZins, double fZzr, double fBw,
+ double fZw, double fF);
+void ScRMZ();
+void ScZGZ();
+double ScGetZw(double fZins, double fZzr, double fRmz,
+ double fBw, double fF);
+void ScZW();
+void ScZZR();
+bool RateIteration(double fNper, double fPayment, double fPv,
+ double fFv, double fPayType, double& fGuess);
+void ScZins();
+double ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw,
+ double fZw, double fF, double& fRmz);
+void ScZinsZ();
+void ScKapz();
+void ScKumZinsZ();
+void ScKumKapZ();
+void ScEffektiv();
+void ScNominal();
+void ScMod();
+void ScBackSolver();
+void ScIntercept();
+//-------------------------Funktionen in interpr5.cxx--------------------------
+double ScGetGCD(double fx, double fy);
+void ScGCD();
+void ScLCM();
+//-------------------------- Matrixfunktionen ---------------------------------
+
+void ScMatValue();
+void MEMat(ScMatrix* mM, SCSIZE n);
+void MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR, SCSIZE n, SCSIZE m, SCSIZE l);
+void ScMatDet();
+void ScMatInv();
+void ScMatMult();
+void ScMatTrans();
+void ScEMat();
+void ScMatRef();
+ScMatrixRef MatConcat(ScMatrix* pMat1, ScMatrix* pMat2);
+void ScSumProduct();
+void ScSumX2MY2();
+void ScSumX2DY2();
+void ScSumXMY2();
+void ScGrowth();
+// multiple Regression: Varianzen der Koeffizienten
+BOOL RGetVariances( ScMatrix* pV, ScMatrix* pX, SCSIZE nC, SCSIZE nR,
+ BOOL bSwapColRow, BOOL bZeroConstant );
+void Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef& pQ,ScMatrixRef& pV,ScMatrixRef& pMatX,BOOL bConstant,SCSIZE N,SCSIZE M,BYTE nCase);
+ScMatrixRef Calculate2(const BOOL bConstant,const SCSIZE M ,const SCSIZE N,ScMatrixRef& pMatX,ScMatrixRef& pMatY,BYTE nCase);
+bool Calculate3(const SCSIZE M ,ScMatrixRef& pQ);
+bool Calculate4(BOOL _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,BOOL bConstant,SCSIZE N,SCSIZE M);
+bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values);
+void CalculateSlopeIntercept(BOOL bSlope);
+void CalculateSmallLarge(BOOL bSmall);
+void CalculatePearsonCovar(BOOL _bPearson,BOOL _bStexy);
+bool CalculateTest( BOOL _bTemplin
+ ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2
+ ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
+ ,double& fT,double& fF);
+void CalculateLookup(BOOL HLookup);
+bool FillEntry(ScQueryEntry& rEntry);
+void CalculateAddSub(BOOL _bSub);
+void CalculateTrendGrowth(BOOL _bGrowth);
+void CalulateRGPRKP(BOOL _bRKP);
+void CalculateSumX2MY2SumX2DY2(BOOL _bSumX2DY2);
+void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR);
+bool CheckMatrix(BOOL _bLOG,BOOL _bTrendGrowth,BYTE& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY);
+
+void ScRGP();
+void ScRKP();
+void ScForecast();
+//------------------------- Functions in interpr3.cxx -------------------------
+void ScNoName();
+void ScBadName();
+// Statistik:
+double phi(double x);
+double integralPhi(double x);
+double taylor(double* pPolynom, USHORT nMax, double x);
+double gauss(double x);
+double gaussinv(double x);
+double GetBetaDist(double x, double alpha, double beta); //cumulative distribution function
+double GetBetaDistPDF(double fX, double fA, double fB); //probability density function)
+double GetChiDist(double fChi, double fDF); // for LEGACY.CHIDIST, returns right tail
+double GetChiSqDistCDF(double fX, double fDF); // for CHISQDIST, returns left tail
+double GetChiSqDistPDF(double fX, double fDF); // probability density function
+double GetFDist(double x, double fF1, double fF2);
+double GetTDist(double T, double fDF);
+double Fakultaet(double x);
+double BinomKoeff(double n, double k);
+double GetGamma(double x);
+double GetLogGamma(double x);
+double GetBeta(double fAlpha, double fBeta);
+double GetLogBeta(double fAlpha, double fBeta);
+void ScLogGamma();
+void ScGamma();
+void ScPhi();
+void ScGauss();
+void ScStdNormDist();
+void ScFisher();
+void ScFisherInv();
+void ScFact();
+void ScNormDist();
+void ScGammaDist();
+void ScGammaInv();
+void ScExpDist();
+void ScBinomDist();
+void ScPoissonDist();
+void ScKombin();
+void ScKombin2();
+void ScVariationen();
+void ScVariationen2();
+void ScB();
+void ScHypGeomDist();
+void ScLogNormDist();
+void ScLogNormInv();
+void ScTDist();
+void ScFDist();
+void ScChiDist(); // for LEGACY.CHIDIST, returns right tail
+void ScChiSqDist(); // returns left tail or density
+void ScChiSqInv(); //invers to CHISQDIST
+void ScWeibull();
+void ScBetaDist();
+void ScFInv();
+void ScTInv();
+void ScChiInv();
+void ScBetaInv();
+void ScCritBinom();
+void ScNegBinomDist();
+void ScKurt();
+void ScHarMean();
+void ScGeoMean();
+void ScStandard();
+void ScSkew();
+void ScMedian();
+double GetMedian( ::std::vector<double> & rArray );
+double GetPercentile( ::std::vector<double> & rArray, double fPercentile );
+void GetNumberSequenceArray( BYTE nParamCount, ::std::vector<double>& rArray );
+void GetSortArray(BYTE nParamCount, ::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
+void QuickSort(::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
+void ScModalValue();
+void ScAveDev();
+void ScDevSq();
+void ScZTest();
+void ScTTest();
+void ScFTest();
+void ScChiTest();
+void ScRank();
+void ScPercentile();
+void ScPercentrank();
+void ScLarge();
+void ScSmall();
+void ScFrequency();
+void ScQuartile();
+void ScNormInv();
+void ScSNormInv();
+void ScConfidence();
+void ScTrimMean();
+void ScProbability();
+void ScCorrel();
+void ScCovar();
+void ScPearson();
+void ScRSQ();
+void ScSTEXY();
+void ScSlope();
+void ScTrend();
+void ScInfo();
+
+//------------------------ Functions in interpr6.cxx -------------------------
+
+static const double fMaxGammaArgument; // defined in interpr3.cxx
+
+double GetGammaContFraction(double fA,double fX);
+double GetGammaSeries(double fA,double fX);
+double GetLowRegIGamma(double fA,double fX); // lower regularized incomplete gamma function, GAMMAQ
+double GetUpRegIGamma(double fA,double fX); // upper regularized incomplete gamma function, GAMMAP
+// probability density function; fLambda is "scale" parameter
+double GetGammaDistPDF(double fX, double fAlpha, double fLambda);
+// cumulative distribution function; fLambda is "scale" parameter
+double GetGammaDist(double fX, double fAlpha, double fLambda);
+
+//----------------------------------------------------------------------------
+public:
+ ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
+ const ScAddress&, ScTokenArray& );
+ ~ScInterpreter();
+
+ formula::StackVar Interpret();
+
+ void SetError(USHORT nError)
+ { if (nError && !nGlobalError) nGlobalError = nError; }
+
+ USHORT GetError() const { return nGlobalError; }
+ formula::StackVar GetResultType() const { return xResult->GetType(); }
+ const String& GetStringResult() const { return xResult->GetString(); }
+ double GetNumResult() const { return xResult->GetDouble(); }
+ formula::FormulaTokenRef
+ GetResultToken() const { return xResult; }
+ short GetRetFormatType() const { return nRetFmtType; }
+ ULONG GetRetFormatIndex() const { return nRetFmtIndex; }
+};
+
+
+inline void ScInterpreter::MatrixDoubleRefToMatrix()
+{
+ if ( bMatrixFormula && GetStackType() == formula::svDoubleRef )
+ {
+ GetTokenMatrixMap(); // make sure it exists, create if not.
+ PopDoubleRefPushMatrix();
+ }
+}
+
+
+inline bool ScInterpreter::MatrixParameterConversion()
+{
+ if ( (bMatrixFormula || pCur->HasForceArray()) && !pJumpMatrix && sp > 0 )
+ return ConvertMatrixParameters();
+ return false;
+}
+
+
+inline ScTokenMatrixMap& ScInterpreter::GetTokenMatrixMap()
+{
+ if (!pTokenMatrixMap)
+ pTokenMatrixMap = CreateTokenMatrixMap();
+ return *pTokenMatrixMap;
+}
+
+
+inline BOOL ScInterpreter::MustHaveParamCount( short nAct, short nMust )
+{
+ if ( nAct == nMust )
+ return TRUE;
+ if ( nAct < nMust )
+ PushParameterExpected();
+ else
+ PushIllegalParameter();
+ return FALSE;
+}
+
+
+inline BOOL ScInterpreter::MustHaveParamCount( short nAct, short nMust, short nMax )
+{
+ if ( nMust <= nAct && nAct <= nMax )
+ return TRUE;
+ if ( nAct < nMust )
+ PushParameterExpected();
+ else
+ PushIllegalParameter();
+ return FALSE;
+}
+
+
+inline BOOL ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
+{
+ if ( nAct >= nMin )
+ return TRUE;
+ PushParameterExpected();
+ return FALSE;
+}
+
+
+inline BOOL ScInterpreter::CheckStringResultLen( String& rResult, const String& rAdd )
+{
+ if ( (ULONG) rResult.Len() + rAdd.Len() > STRING_MAXLEN )
+ {
+ SetError( errStringOverflow );
+ rResult.Erase();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+inline void ScInterpreter::TreatDoubleError( double& rVal )
+{
+ if ( !::rtl::math::isFinite( rVal ) )
+ {
+ USHORT nErr = GetDoubleErrorValue( rVal );
+ if ( nErr )
+ SetError( nErr );
+ else
+ SetError( errNoValue );
+ rVal = 0.0;
+ }
+}
+
+
+// static
+inline double ScInterpreter::div( const double& fNumerator, const double& fDenominator )
+{
+ return (fDenominator != 0.0) ? (fNumerator / fDenominator) :
+ CreateDoubleError( errDivisionByZero);
+}
+
+#endif
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
new file mode 100644
index 000000000000..8089d6653730
--- /dev/null
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_JUMPMATRIX_HXX
+#define SC_JUMPMATRIX_HXX
+
+#include "formula/token.hxx"
+#include "formula/errorcodes.hxx"
+#include <tools/solar.h>
+#include <vector>
+#include "scmatrix.hxx"
+
+typedef ::std::vector< formula::FormulaToken*> ScTokenVec;
+
+struct ScJumpMatrixEntry
+{
+ double fBool; // 0:= false 1:= true also if no-path
+ // other values may contain error conditions like NAN and INF
+ short nStart; // start of path (actually start-1, see formula::FormulaTokenIterator)
+ short nNext; // next after path
+ // jump path exists if nStart != nNext, else no path
+ short nStop; // optional stop of path (nPC < nStop)
+
+ void SetJump( double fBoolP, short nStartP, short nNextP, short nStopP )
+ {
+ fBool = fBoolP;
+ nStart = nStartP;
+ nNext = nNextP;
+ nStop = nStopP;
+ }
+ void GetJump( double& rBool, short& rStart, short& rNext, short& rStop )
+ {
+ rBool = fBool;
+ rStart = nStart;
+ rNext = nNext;
+ rStop = nStop;
+ }
+};
+
+class ScJumpMatrix
+{
+ ScJumpMatrixEntry* pJump; // the jumps
+ ScMatrixRef pMat; // the results
+ ScTokenVec* pParams; // parameter stack
+ SCSIZE nCols;
+ SCSIZE nRows;
+ SCSIZE nCurCol;
+ SCSIZE nCurRow;
+ SCSIZE nResMatCols;
+ SCSIZE nResMatRows;
+ bool bStarted;
+
+ // not implemented, prevent usage
+ ScJumpMatrix( const ScJumpMatrix& );
+ ScJumpMatrix& operator=( const ScJumpMatrix& );
+
+public:
+ ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP )
+ : pJump( new ScJumpMatrixEntry[ nColsP * nRowsP ] )
+ , pMat( new ScMatrix( nColsP, nRowsP) )
+ , pParams( NULL )
+ , nCols( nColsP )
+ , nRows( nRowsP )
+ , nCurCol( 0 )
+ , nCurRow( 0 )
+ , nResMatCols( nColsP )
+ , nResMatRows( nRowsP )
+ , bStarted( false )
+ {
+ // Initialize result matrix in case of
+ // a premature end of the interpreter
+ // due to errors.
+ pMat->FillDouble( CreateDoubleError(
+ NOTAVAILABLE), 0, 0, nCols-1,
+ nRows-1);
+ /*! pJump not initialized */
+ }
+ ~ScJumpMatrix()
+ {
+ if ( pParams )
+ {
+ for ( ScTokenVec::iterator i =
+ pParams->begin(); i !=
+ pParams->end(); ++i )
+ {
+ (*i)->DecRef();
+ }
+ delete pParams;
+ }
+ delete [] pJump;
+ }
+ void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const
+ {
+ rCols = nCols;
+ rRows = nRows;
+ }
+ void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool,
+ short nStart, short nNext,
+ short nStop = SHRT_MAX )
+ {
+ pJump[ (ULONG)nCol * nRows + nRow ].
+ SetJump( fBool, nStart, nNext, nStop);
+ }
+ void GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool,
+ short& rStart, short& rNext,
+ short& rStop ) const
+ {
+ if (nCols == 1 && nRows == 1)
+ {
+ nCol = 0;
+ nRow = 0;
+ }
+ else if (nCols == 1 && nRow < nRows)
+ nCol = 0;
+ else if (nRows == 1 && nCol < nCols)
+ nRow = 0;
+ else if (nCols <= nCol || nRows <= nRow)
+ {
+ DBG_ERROR("ScJumpMatrix::GetJump: dimension error");
+ nCol = 0;
+ nRow = 0;
+ }
+ pJump[ (ULONG)nCol * nRows + nRow ].
+ GetJump( rBool, rStart, rNext, rStop);
+ }
+ void SetAllJumps( double fBool,
+ short nStart, short nNext,
+ short nStop = SHRT_MAX )
+ {
+ ULONG n = (ULONG)nCols * nRows;
+ for ( ULONG j=0; j<n; ++j )
+ {
+ pJump[ j ].SetJump( fBool, nStart,
+ nNext, nStop);
+ }
+ }
+ void SetJumpParameters( ScTokenVec* p )
+ { pParams = p; }
+ const ScTokenVec* GetJumpParameters() const { return pParams; }
+ ScMatrix* GetResultMatrix() const { return pMat; }
+ void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const
+ {
+ rCol = nCurCol;
+ rRow = nCurRow;
+ }
+ bool Next( SCSIZE& rCol, SCSIZE& rRow )
+ {
+ if ( !bStarted )
+ {
+ bStarted = true;
+ nCurCol = nCurRow = 0;
+ }
+ else
+ {
+ if ( ++nCurRow >= nResMatRows )
+ {
+ nCurRow = 0;
+ ++nCurCol;
+ }
+ }
+ GetPos( rCol, rRow );
+ return nCurCol < nResMatCols;
+ }
+ void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows )
+ {
+ rCols = nResMatCols;
+ rRows = nResMatRows;
+ }
+ void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows )
+ {
+ if ( nNewCols > nResMatCols || nNewRows > nResMatRows )
+ {
+ pMat = pMat->CloneAndExtend( nNewCols, nNewRows );
+ if ( nResMatCols < nNewCols )
+ {
+ pMat->FillDouble( CreateDoubleError(
+ NOTAVAILABLE), nResMatCols, 0, nNewCols-1,
+ nResMatRows-1);
+ }
+ if ( nResMatRows < nNewRows )
+ {
+ pMat->FillDouble( CreateDoubleError(
+ NOTAVAILABLE), 0, nResMatRows, nNewCols-1,
+ nNewRows-1);
+ }
+ if ( nRows == 1 && nCurCol != 0 )
+ {
+ nCurCol = 0;
+ nCurRow = nResMatRows - 1;
+ }
+ nResMatCols = nNewCols;
+ nResMatRows = nNewRows;
+ }
+ }
+};
+
+#endif // SC_JUMPMATRIX_HXX
+
diff --git a/sc/source/core/inc/makefile.mk b/sc/source/core/inc/makefile.mk
new file mode 100644
index 000000000000..1b35ca49549d
--- /dev/null
+++ b/sc/source/core/inc/makefile.mk
@@ -0,0 +1,26 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
diff --git a/sc/source/core/inc/parclass.hxx b/sc/source/core/inc/parclass.hxx
new file mode 100644
index 000000000000..39844de7ae22
--- /dev/null
+++ b/sc/source/core/inc/parclass.hxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PARCLASS_HXX
+#define SC_PARCLASS_HXX
+
+#include "formula/opcode.hxx"
+#include <sys/types.h> // size_t
+
+namespace formula
+{
+ class FormulaToken;
+}
+
+class ScParameterClassification
+{
+public:
+
+ enum Type
+ {
+ Unknown = 0, // MUST be zero for initialization mechanism!
+
+ /** Out of bounds, function doesn't expect that many parameters.
+ However, not necessarily returned. */
+ Bounds,
+
+ /** In array formula: single value to be passed. Results in JumpMatrix
+ being created and multiple calls to function. Functions handling a
+ formula::svDoubleRef by means of DoubleRefToPosSingleRef() or
+ PopDoubleRefOrSingleRef() or GetDouble() or GetString() should have
+ this. */
+ Value,
+
+ /** In array formula: area reference must stay reference. Otherwise
+ don't care. Functions handling a formula::svDoubleRef by means of
+ PopDoubleRefOrSingleRef() should not have this. */
+ Reference,
+
+ /** In array formula: convert area reference to array. Function will be
+ called only once if no Value type is involved. Functions able to
+ handle a svMatrix parameter but not a formula::svDoubleRef parameter as area
+ should have this. */
+ Array,
+
+ /** Area reference must be converted to array in any case, and must
+ also be propagated to subsequent operators and functions being part
+ of a parameter of this function. */
+ ForceArray,
+
+ /** Area reference is not converted to array, but ForceArray must be
+ propagated to subsequent operators and functions being part of a
+ parameter of this function. Used with functions that treat
+ references separately from arrays, but need the forced array
+ calculation of parameters that are not references.*/
+ ReferenceOrForceArray
+ };
+
+ /// MUST be called once before any other method.
+ static void Init();
+
+ static void Exit();
+
+ /** Get one parameter type for function eOp.
+ @param nParameter
+ Which parameter, 0-based */
+ static Type GetParameterType( const formula::FormulaToken* pToken,
+ USHORT nParameter);
+
+ /** Whether OpCode has a parameter of type
+ ForceArray or ReferenceOrForceArray. */
+ static inline bool HasForceArray( OpCode eOp)
+ {
+ return 0 <= (short)eOp &&
+ eOp <= SC_OPCODE_LAST_OPCODE_ID &&
+ pData[eOp].bHasForceArray;
+ }
+
+private:
+
+ struct CommonData
+ {
+ const static size_t nMaxParams = 7;
+
+ Type nParam[nMaxParams];
+ bool bRepeatLast;
+ };
+
+ // SUNWS7 needs a forward declared friend, otherwise members of the outer
+ // class are not accessible (in this case CommonData).
+ struct RawData;
+ friend struct ScParameterClassification::RawData;
+ struct RawData
+ {
+ OpCode eOp;
+ CommonData aData;
+ };
+
+ struct RunData;
+ friend struct ScParameterClassification::RunData;
+ struct RunData
+ {
+ CommonData aData;
+ BYTE nMinParams; // fix or minimum, or repeat start
+ bool bHasForceArray;
+ };
+
+ static const RawData pRawData[];
+ static RunData* pData;
+
+ // ocExternal AddIns
+ static Type GetExternalParameterType(
+ const formula::FormulaToken* pToken, USHORT nParameter);
+
+#if OSL_DEBUG_LEVEL > 1
+ // Generate documentation to stdout if environment variable
+ // OOO_CALC_GENPARCLASSDOC is set.
+ static void GenerateDocumentation();
+
+ /* OpCodes not specified in the implementation are taken from the global
+ * function list and all parameters, if any, are assumed to be of type
+ * Value. This could also be done in the product version if needed, but we
+ * don't want to spoil startup time. However, doing so could propagate the
+ * minimum parameter count to the formula compiler, which, together with
+ * additional information about optional parameters, could react on missing
+ * parameters then. */
+ static void MergeArgumentsFromFunctionResource();
+
+ /** Minimum number of parameters, or fix number
+ of parameters if HasRepeatParameters()
+ returns FALSE. For opcodes not specified in
+ the implementation a parameter count of 1
+ is assumed, for opcodes out of range 0 is
+ assumed. If HasRepeatParameters() returns
+ TRUE, information is NOT related to whether
+ any parameters are optional, only the type
+ of parameters is significant. */
+ static inline BYTE GetMinimumParameters( OpCode eOp)
+ {
+ if ( eOp <= SC_OPCODE_LAST_OPCODE_ID )
+ return pData[eOp].aData.nParam[0]
+ == Unknown ? 1 :
+ pData[eOp].nMinParams;
+ return 0;
+ }
+
+ /** Whether last parameter type is repeated. */
+ static inline bool HasRepeatParameters( OpCode eOp)
+ {
+ return eOp <= SC_OPCODE_LAST_OPCODE_ID
+ && pData[eOp].aData.bRepeatLast;
+ }
+#endif // OSL_DEBUG_LEVEL
+};
+
+#endif // SC_PARCLASS_HXX
+
diff --git a/sc/source/core/inc/poolhelp.hxx b/sc/source/core/inc/poolhelp.hxx
new file mode 100644
index 000000000000..f98963513c59
--- /dev/null
+++ b/sc/source/core/inc/poolhelp.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_POOLHELP_HXX
+#define SC_POOLHELP_HXX
+
+#include <rtl/ref.hxx>
+#include <vos/refernce.hxx>
+#include <tools/link.hxx>
+#include "docoptio.hxx"
+
+class ScDocument;
+class ScDocumentPool;
+class ScStyleSheetPool;
+class SvNumberFormatter;
+class SfxItemPool;
+
+
+class ScPoolHelper : public vos::OReference
+{
+private:
+ ScDocOptions aOpt;
+ ScDocumentPool* pDocPool;
+ rtl::Reference< ScStyleSheetPool > mxStylePool;
+ mutable SvNumberFormatter* pFormTable;
+ mutable SfxItemPool* pEditPool; // EditTextObjectPool
+ mutable SfxItemPool* pEnginePool; // EditEnginePool
+ ScDocument* m_pSourceDoc;
+
+ void UseDocOptions() const;
+
+public:
+ ScPoolHelper( ScDocument* pSourceDoc );
+ virtual ~ScPoolHelper();
+
+ // called in dtor of main document
+ void SourceDocumentGone();
+
+ // access to pointers (are never 0):
+ ScDocumentPool* GetDocPool() const { return pDocPool; }
+ ScStyleSheetPool* GetStylePool() const { return mxStylePool.get(); }
+ SvNumberFormatter* GetFormTable() const;
+ SfxItemPool* GetEditPool() const;
+ SfxItemPool* GetEnginePool() const;
+
+ void SetFormTableOpt(const ScDocOptions& rOpt);
+};
+
+#endif
+
diff --git a/sc/source/core/inc/refupdat.hxx b/sc/source/core/inc/refupdat.hxx
new file mode 100644
index 000000000000..17da3bf5e635
--- /dev/null
+++ b/sc/source/core/inc/refupdat.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_REFUPDAT_HXX
+#define SC_REFUPDAT_HXX
+
+#include "global.hxx"
+
+class ScDocument;
+class ScBigRange;
+struct ScComplexRefData;
+class ScAddress;
+class ScRange;
+
+enum ScRefUpdateRes {
+ UR_NOTHING = 0, // keine Anpassungen
+ UR_UPDATED = 1, // Anpassungen erfolgt
+ UR_INVALID = 2 // Referenz wurde ungueltig
+};
+
+class ScRefUpdate
+{
+public:
+
+ /// What type of reference is to be updated.
+ enum WhatType
+ {
+ ALL, /// all references
+ ABSOLUTE /// only absolute references
+ };
+
+ static ScRefUpdateRes Update
+ ( ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1,
+ SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 );
+
+ static ScRefUpdateRes Update( UpdateRefMode eUpdateRefMode,
+ const ScBigRange& rWhere,
+ INT32 nDx, INT32 nDy, INT32 nDz,
+ ScBigRange& rWhat );
+
+ /// Before calling, the absolute references must be up-to-date!
+ static ScRefUpdateRes Update( ScDocument* pDoc,
+ UpdateRefMode eUpdateRefMode,
+ const ScAddress& rPos, const ScRange& rRange,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScComplexRefData& rRef, WhatType eWhat = ALL );
+
+ /// Before calling, the absolute references must be up-to-date!
+ static ScRefUpdateRes Move( ScDocument* pDoc, const ScAddress& rPos,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScComplexRefData& rRef, BOOL bWrap, BOOL bAbsolute );
+
+ static void MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos,
+ SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef );
+
+ /// Before calling, the absolute references must be up-to-date!
+ static ScRefUpdateRes UpdateTranspose( ScDocument* pDoc,
+ const ScRange& rSource, const ScAddress& rDest,
+ ScComplexRefData& rRef );
+
+ static void DoTranspose( SCsCOL& rCol, SCsROW& rRow, SCsTAB& rTab, ScDocument* pDoc,
+ const ScRange& rSource, const ScAddress& rDest );
+
+ /// Before calling, the absolute references must be up-to-date!
+ static ScRefUpdateRes UpdateGrow(
+ const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY,
+ ScComplexRefData& rRef );
+};
+
+
+#endif
+
diff --git a/sc/source/core/inc/scrdata.hxx b/sc/source/core/inc/scrdata.hxx
new file mode 100644
index 000000000000..b569bddddd6b
--- /dev/null
+++ b/sc/source/core/inc/scrdata.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCRDATA_HXX
+#define SC_SCRDATA_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace com { namespace sun { namespace star { namespace i18n {
+ class XBreakIterator;
+} } } }
+
+
+class ScScriptTypeData
+{
+public:
+ ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xBreakIter;
+
+ ScScriptTypeData() {}
+ ~ScScriptTypeData() {}
+};
+
+#endif
+
+
diff --git a/sc/source/core/src/compiler.src b/sc/source/core/src/compiler.src
new file mode 100644
index 000000000000..a45c2b6aa458
--- /dev/null
+++ b/sc/source/core/src/compiler.src
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc" // Definition RID_XXX
+#include <formula/compiler.hrc> // Definition SC_OPCODE_XXX (interne OpCodes)
+
+
+
+Resource RID_FUNCTION_CATEGORIES
+{
+ String 1
+ {
+ Text[ en-US ] = "Database" ;
+ };
+ String 2
+ {
+ Text[ en-US ] = "Date&Time" ;
+ };
+ String 3
+ {
+ Text[ en-US ] = "Financial" ;
+ };
+ String 4
+ {
+ Text[ en-US ] = "Information" ;
+ };
+ String 5
+ {
+ Text[ en-US ] = "Logical" ;
+ };
+ String 6
+ {
+ Text[ en-US ] = "Mathematical" ;
+ };
+ String 7
+ {
+ Text[ en-US ] = "Array" ;
+ };
+ String 8
+ {
+ Text[ en-US ] = "Statistical" ;
+ };
+ String 9
+ {
+ Text[ en-US ] = "Spreadsheet" ;
+ };
+ String 10
+ {
+ Text[ en-US ] = "Text" ;
+ };
+ String 11
+ {
+ Text[ en-US ] = "Add-in" ;
+ };
+};
+
diff --git a/sc/source/core/src/makefile.mk b/sc/source/core/src/makefile.mk
new file mode 100644
index 000000000000..13d0c2127c6d
--- /dev/null
+++ b/sc/source/core/src/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=core
+
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ compiler.src
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/core/tool/addincfg.cxx b/sc/source/core/tool/addincfg.cxx
new file mode 100644
index 000000000000..c76b60eae077
--- /dev/null
+++ b/sc/source/core/tool/addincfg.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <tools/debug.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "global.hxx"
+#include "addincol.hxx"
+#include "addincfg.hxx"
+#include "scmod.hxx"
+#include "sc.hrc"
+
+using namespace com::sun::star;
+
+//==================================================================
+
+#define CFGPATH_ADDINS "Office.CalcAddIns/AddInInfo"
+
+ScAddInCfg::ScAddInCfg() :
+ ConfigItem( rtl::OUString::createFromAscii( CFGPATH_ADDINS ) )
+{
+ uno::Sequence<rtl::OUString> aNames(1); // one entry: empty string
+ EnableNotification( aNames );
+}
+
+void ScAddInCfg::Commit()
+{
+ DBG_ERROR("ScAddInCfg shouldn't be modified");
+}
+
+void ScAddInCfg::Notify( const uno::Sequence<rtl::OUString>& )
+{
+ // forget all add-in information, re-initialize when needed next time
+ ScGlobal::GetAddInCollection()->Clear();
+
+ // function list must also be rebuilt, but can't be modified while function
+ // autopilot is open (function list for autopilot is then still old)
+ if ( SC_MOD()->GetCurRefDlgId() != SID_OPENDLG_FUNCTION )
+ ScGlobal::ResetFunctionList();
+}
+
+
diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx
new file mode 100644
index 000000000000..07b79c11b373
--- /dev/null
+++ b/sc/source/core/tool/addincol.cxx
@@ -0,0 +1,1802 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <i18npool/mslangid.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/xception.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/charclass.hxx>
+
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/sheet/XCompatibilityNames.hpp>
+#include <com/sun/star/sheet/NoConvergenceException.hpp>
+
+#include "addincol.hxx"
+#include "addinhelpid.hxx"
+#include "compiler.hxx"
+#include "scmatrix.hxx"
+#include "addinlis.hxx"
+#include "formula/errorcodes.hxx"
+#include "scfuncs.hrc"
+#include "optutil.hxx"
+#include "addincfg.hxx"
+#include "scmod.hxx"
+#include "rangeseq.hxx"
+#include "funcdesc.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+#define SC_CALLERPOS_NONE (-1)
+
+#define SCADDINSUPPLIER_SERVICE "com.sun.star.sheet.AddIn"
+
+//------------------------------------------------------------------------
+
+
+
+
+//------------------------------------------------------------------------
+
+ScUnoAddInFuncData::ScUnoAddInFuncData( const String& rNam, const String& rLoc,
+ const String& rDesc,
+ USHORT nCat, USHORT nHelp,
+ const uno::Reference<reflection::XIdlMethod>& rFunc,
+ const uno::Any& rO,
+ long nAC, const ScAddInArgDesc* pAD,
+ long nCP ) :
+ aOriginalName( rNam ),
+ aLocalName( rLoc ),
+ aUpperName( rNam ),
+ aUpperLocal( rLoc ),
+ aDescription( rDesc ),
+ xFunction( rFunc ),
+ aObject( rO ),
+ nArgCount( nAC ),
+ nCallerPos( nCP ),
+ nCategory( nCat ),
+ nHelpId( nHelp ),
+ bCompInitialized( FALSE )
+{
+ if ( nArgCount )
+ {
+ pArgDescs = new ScAddInArgDesc[nArgCount];
+ for (long i=0; i<nArgCount; i++)
+ pArgDescs[i] = pAD[i];
+ }
+ else
+ pArgDescs = NULL;
+
+ ScGlobal::pCharClass->toUpper(aUpperName);
+ ScGlobal::pCharClass->toUpper(aUpperLocal);
+}
+
+ScUnoAddInFuncData::~ScUnoAddInFuncData()
+{
+ delete[] pArgDescs;
+}
+
+const uno::Sequence<sheet::LocalizedName>& ScUnoAddInFuncData::GetCompNames() const
+{
+ if ( !bCompInitialized )
+ {
+ // read sequence of compatibility names on demand
+
+ uno::Reference<sheet::XAddIn> xAddIn;
+ if ( aObject >>= xAddIn )
+ {
+ uno::Reference<sheet::XCompatibilityNames> xComp( xAddIn, uno::UNO_QUERY );
+ if ( xComp.is() && xFunction.is() )
+ {
+ rtl::OUString aMethodName = xFunction->getName();
+ aCompNames = xComp->getCompatibilityNames( aMethodName );
+
+ // change all locale entries to default case
+ // (language in lower case, country in upper case)
+ // for easier searching
+
+ long nSeqLen = aCompNames.getLength();
+ if ( nSeqLen )
+ {
+ sheet::LocalizedName* pArray = aCompNames.getArray();
+ for (long i=0; i<nSeqLen; i++)
+ {
+ lang::Locale& rLocale = pArray[i].Locale;
+ rLocale.Language = rLocale.Language.toAsciiLowerCase();
+ rLocale.Country = rLocale.Country.toAsciiUpperCase();
+ }
+ }
+ }
+ }
+
+ bCompInitialized = TRUE; // also if not successful
+ }
+ return aCompNames;
+}
+
+void ScUnoAddInFuncData::SetCompNames( const uno::Sequence< sheet::LocalizedName>& rNew )
+{
+ DBG_ASSERT( !bCompInitialized, "SetCompNames after initializing" );
+
+ aCompNames = rNew;
+
+ // change all locale entries to default case
+ // (language in lower case, country in upper case)
+ // for easier searching
+
+ long nSeqLen = aCompNames.getLength();
+ if ( nSeqLen )
+ {
+ sheet::LocalizedName* pArray = aCompNames.getArray();
+ for (long i=0; i<nSeqLen; i++)
+ {
+ lang::Locale& rLocale = pArray[i].Locale;
+ rLocale.Language = rLocale.Language.toAsciiLowerCase();
+ rLocale.Country = rLocale.Country.toAsciiUpperCase();
+ }
+ }
+
+ bCompInitialized = TRUE;
+}
+
+BOOL ScUnoAddInFuncData::GetExcelName( LanguageType eDestLang, String& rRetExcelName ) const
+{
+ const uno::Sequence<sheet::LocalizedName>& rSequence = GetCompNames();
+ long nSeqLen = rSequence.getLength();
+ if ( nSeqLen )
+ {
+ const sheet::LocalizedName* pArray = rSequence.getConstArray();
+ long i;
+
+ rtl::OUString aLangStr, aCountryStr;
+ MsLangId::convertLanguageToIsoNames( eDestLang, aLangStr, aCountryStr );
+ rtl::OUString aUserLang = aLangStr.toAsciiLowerCase();
+ rtl::OUString aUserCountry = aCountryStr.toAsciiUpperCase();
+
+ // first check for match of both language and country
+
+ for ( i=0; i<nSeqLen; i++)
+ if ( pArray[i].Locale.Language == aUserLang &&
+ pArray[i].Locale.Country == aUserCountry )
+ {
+ rRetExcelName = pArray[i].Name;
+ return TRUE;
+ }
+
+ // second: check only language
+
+ for ( i=0; i<nSeqLen; i++)
+ if ( pArray[i].Locale.Language == aUserLang )
+ {
+ rRetExcelName = pArray[i].Name;
+ return TRUE;
+ }
+
+ // third: #i57772# fall-back to en-US
+
+ if ( eDestLang != LANGUAGE_ENGLISH_US )
+ return GetExcelName( LANGUAGE_ENGLISH_US, rRetExcelName );
+
+ // forth: use first (default) entry
+
+ rRetExcelName = pArray[0].Name;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ScUnoAddInFuncData::SetFunction( const uno::Reference< reflection::XIdlMethod>& rNewFunc, const uno::Any& rNewObj )
+{
+ xFunction = rNewFunc;
+ aObject = rNewObj;
+}
+
+void ScUnoAddInFuncData::SetArguments( long nNewCount, const ScAddInArgDesc* pNewDescs )
+{
+ delete[] pArgDescs;
+
+ nArgCount = nNewCount;
+ if ( nArgCount )
+ {
+ pArgDescs = new ScAddInArgDesc[nArgCount];
+ for (long i=0; i<nArgCount; i++)
+ pArgDescs[i] = pNewDescs[i];
+ }
+ else
+ pArgDescs = NULL;
+}
+
+void ScUnoAddInFuncData::SetCallerPos( long nNewPos )
+{
+ nCallerPos = nNewPos;
+}
+
+//------------------------------------------------------------------------
+
+ScUnoAddInCollection::ScUnoAddInCollection() :
+ nFuncCount( 0 ),
+ ppFuncData( NULL ),
+ pExactHashMap( NULL ),
+ pNameHashMap( NULL ),
+ pLocalHashMap( NULL ),
+ bInitialized( FALSE )
+{
+}
+
+ScUnoAddInCollection::~ScUnoAddInCollection()
+{
+ Clear();
+}
+
+void ScUnoAddInCollection::Clear()
+{
+ DELETEZ( pExactHashMap );
+ DELETEZ( pNameHashMap );
+ DELETEZ( pLocalHashMap );
+ if ( ppFuncData )
+ {
+ for ( long i=0; i<nFuncCount; i++ )
+ delete ppFuncData[i];
+ delete[] ppFuncData;
+ }
+ ppFuncData = NULL;
+ nFuncCount = 0;
+
+ bInitialized = FALSE;
+}
+
+uno::Reference<uno::XComponentContext> getContext(uno::Reference<lang::XMultiServiceFactory> xMSF)
+{
+ uno::Reference<uno::XComponentContext> xCtx;
+ try {
+ uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY);
+ xPropset->getPropertyValue(
+ ::rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx;
+ }
+ catch ( uno::Exception & ) {
+ }
+ return xCtx;
+}
+
+void ScUnoAddInCollection::Initialize()
+{
+ DBG_ASSERT( !bInitialized, "Initialize twice?" );
+
+ uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
+ uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
+ if ( xEnAc.is() )
+ {
+ uno::Reference<container::XEnumeration> xEnum =
+ xEnAc->createContentEnumeration(
+ rtl::OUString::createFromAscii(SCADDINSUPPLIER_SERVICE) );
+ if ( xEnum.is() )
+ {
+ // loop through all AddIns
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Any aAddInAny = xEnum->nextElement();
+//? if ( aAddInAny.getReflection()->getTypeClass() == uno::TypeClass_INTERFACE )
+ {
+ uno::Reference<uno::XInterface> xIntFac;
+ aAddInAny >>= xIntFac;
+ if ( xIntFac.is() )
+ {
+ // #i59984# try XSingleComponentFactory in addition to (old) XSingleServiceFactory,
+ // passing the context to the component
+
+ uno::Reference<uno::XInterface> xInterface;
+ uno::Reference<uno::XComponentContext> xCtx = getContext(xManager);
+ uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
+ if (xCtx.is() && xCFac.is())
+ {
+ xInterface = xCFac->createInstanceWithContext(xCtx);
+ if (xInterface.is())
+ ReadFromAddIn( xInterface );
+ }
+
+ if (!xInterface.is())
+ {
+ uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
+ if ( xFac.is() )
+ {
+ xInterface = xFac->createInstance();
+ if (xInterface.is())
+ ReadFromAddIn( xInterface );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // ReadConfiguration is called after looking at the AddIn implementations.
+ // Duplicated are skipped (by using the service information, they don't have to be updated again
+ // when argument information is needed).
+ ReadConfiguration();
+
+ bInitialized = TRUE; // with or without functions
+}
+// -----------------------------------------------------------------------------
+
+USHORT lcl_GetCategory( const String& rName )
+{
+ static const sal_Char* aFuncNames[SC_FUNCGROUP_COUNT] =
+ {
+ // array index = ID - 1 (ID starts at 1)
+ // all upper case
+ "Database", // ID_FUNCTION_GRP_DATABASE
+ "Date&Time", // ID_FUNCTION_GRP_DATETIME
+ "Financial", // ID_FUNCTION_GRP_FINANZ
+ "Information", // ID_FUNCTION_GRP_INFO
+ "Logical", // ID_FUNCTION_GRP_LOGIC
+ "Mathematical", // ID_FUNCTION_GRP_MATH
+ "Matrix", // ID_FUNCTION_GRP_MATRIX
+ "Statistical", // ID_FUNCTION_GRP_STATISTIC
+ "Spreadsheet", // ID_FUNCTION_GRP_TABLE
+ "Text", // ID_FUNCTION_GRP_TEXT
+ "Add-In" // ID_FUNCTION_GRP_ADDINS
+ };
+ for (USHORT i=0; i<SC_FUNCGROUP_COUNT; i++)
+ if ( rName.EqualsAscii( aFuncNames[i] ) )
+ return i+1; // IDs start at 1
+
+ return ID_FUNCTION_GRP_ADDINS; // if not found, use Add-In group
+}
+
+
+#define CFGPATH_ADDINS "Office.CalcAddIns/AddInInfo"
+#define CFGSTR_ADDINFUNCTIONS "AddInFunctions"
+
+#define CFG_FUNCPROP_DISPLAYNAME 0
+#define CFG_FUNCPROP_DESCRIPTION 1
+#define CFG_FUNCPROP_CATEGORY 2
+#define CFG_FUNCPROP_COUNT 3
+#define CFGSTR_DISPLAYNAME "DisplayName"
+#define CFGSTR_DESCRIPTION "Description"
+#define CFGSTR_CATEGORY "Category"
+// CategoryDisplayName is ignored for now
+
+#define CFGSTR_COMPATIBILITYNAME "CompatibilityName"
+#define CFGSTR_PARAMETERS "Parameters"
+
+
+void ScUnoAddInCollection::ReadConfiguration()
+{
+ // called only from Initialize
+
+ ScAddInCfg& rAddInConfig = SC_MOD()->GetAddInCfg();
+
+ // additional, temporary config item for the compatibility names
+ ScLinkConfigItem aAllLocalesConfig( rtl::OUString::createFromAscii( CFGPATH_ADDINS ), CONFIG_MODE_ALL_LOCALES );
+ // CommitLink is not used (only reading values)
+
+ const rtl::OUString sSlash('/');
+
+ // get the list of add-ins (services)
+ rtl::OUString aEmptyString;
+ uno::Sequence<rtl::OUString> aServiceNames = rAddInConfig.GetNodeNames( aEmptyString );
+
+ sal_Int32 nServiceCount = aServiceNames.getLength();
+ for ( sal_Int32 nService = 0; nService < nServiceCount; nService++ )
+ {
+ rtl::OUString aServiceName = aServiceNames[nService];
+ ScUnoAddInHelpIdGenerator aHelpIdGenerator( aServiceName );
+
+ rtl::OUString aFunctionsPath = aServiceName;
+ aFunctionsPath += sSlash;
+ aFunctionsPath += rtl::OUString::createFromAscii( CFGSTR_ADDINFUNCTIONS );
+
+ uno::Sequence<rtl::OUString> aFunctionNames = rAddInConfig.GetNodeNames( aFunctionsPath );
+ sal_Int32 nNewCount = aFunctionNames.getLength();
+
+ // allocate pointers
+
+ long nOld = nFuncCount;
+ nFuncCount = nNewCount+nOld;
+ if ( nOld )
+ {
+ ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount];
+ for (long i=0; i<nOld; i++)
+ ppNew[i] = ppFuncData[i];
+ delete[] ppFuncData;
+ ppFuncData = ppNew;
+ }
+ else
+ ppFuncData = new ScUnoAddInFuncData*[nFuncCount];
+
+ //! TODO: adjust bucket count?
+ if ( !pExactHashMap )
+ pExactHashMap = new ScAddInHashMap;
+ if ( !pNameHashMap )
+ pNameHashMap = new ScAddInHashMap;
+ if ( !pLocalHashMap )
+ pLocalHashMap = new ScAddInHashMap;
+
+ //! get the function information in a single call for all functions?
+
+ const rtl::OUString* pFuncNameArray = aFunctionNames.getConstArray();
+ for ( sal_Int32 nFuncPos = 0; nFuncPos < nNewCount; nFuncPos++ )
+ {
+ ppFuncData[nFuncPos+nOld] = NULL;
+
+ // stored function name: (service name).(function)
+ String aFuncName( aServiceName );
+ aFuncName += '.';
+ aFuncName += String( pFuncNameArray[nFuncPos] );
+
+ // skip the function if already known (read from old AddIn service)
+
+ if ( pExactHashMap->find( aFuncName ) == pExactHashMap->end() )
+ {
+ rtl::OUString aLocalName;
+ rtl::OUString aDescription;
+ USHORT nCategory = ID_FUNCTION_GRP_ADDINS;
+
+ // get direct information on the function
+
+ rtl::OUString aFuncPropPath = aFunctionsPath;
+ aFuncPropPath += sSlash;
+ aFuncPropPath += pFuncNameArray[nFuncPos];
+ aFuncPropPath += sSlash;
+
+ uno::Sequence<rtl::OUString> aFuncPropNames(CFG_FUNCPROP_COUNT);
+ rtl::OUString* pNameArray = aFuncPropNames.getArray();
+ pNameArray[CFG_FUNCPROP_DISPLAYNAME] = aFuncPropPath;
+ pNameArray[CFG_FUNCPROP_DISPLAYNAME] += rtl::OUString::createFromAscii( CFGSTR_DISPLAYNAME );
+ pNameArray[CFG_FUNCPROP_DESCRIPTION] = aFuncPropPath;
+ pNameArray[CFG_FUNCPROP_DESCRIPTION] += rtl::OUString::createFromAscii( CFGSTR_DESCRIPTION );
+ pNameArray[CFG_FUNCPROP_CATEGORY] = aFuncPropPath;
+ pNameArray[CFG_FUNCPROP_CATEGORY] += rtl::OUString::createFromAscii( CFGSTR_CATEGORY );
+
+ uno::Sequence<uno::Any> aFuncProperties = rAddInConfig.GetProperties( aFuncPropNames );
+ if ( aFuncProperties.getLength() == CFG_FUNCPROP_COUNT )
+ {
+ aFuncProperties[CFG_FUNCPROP_DISPLAYNAME] >>= aLocalName;
+ aFuncProperties[CFG_FUNCPROP_DESCRIPTION] >>= aDescription;
+
+ rtl::OUString aCategoryName;
+ aFuncProperties[CFG_FUNCPROP_CATEGORY] >>= aCategoryName;
+ nCategory = lcl_GetCategory( aCategoryName );
+ }
+
+ // get compatibility names
+
+ uno::Sequence<sheet::LocalizedName> aCompNames;
+
+ rtl::OUString aCompPath = aFuncPropPath;
+ aCompPath += rtl::OUString::createFromAscii( CFGSTR_COMPATIBILITYNAME );
+ uno::Sequence<rtl::OUString> aCompPropNames( &aCompPath, 1 );
+
+ uno::Sequence<uno::Any> aCompProperties = aAllLocalesConfig.GetProperties( aCompPropNames );
+ if ( aCompProperties.getLength() == 1 )
+ {
+ uno::Sequence<beans::PropertyValue> aLocalEntries;
+ if ( aCompProperties[0] >>= aLocalEntries )
+ {
+ sal_Int32 nLocaleCount = aLocalEntries.getLength();
+ aCompNames.realloc( nLocaleCount );
+ const beans::PropertyValue* pConfigArray = aLocalEntries.getConstArray();
+ sheet::LocalizedName* pCompArray = aCompNames.getArray();
+
+ for ( sal_Int32 nLocale = 0; nLocale < nLocaleCount; nLocale++ )
+ {
+ const sal_Unicode cLocaleSep = '-'; // separator in configuration locale strings
+
+ // PropertyValue name is the locale (convert from string to Locale struct)
+
+ const rtl::OUString& rLocaleStr = pConfigArray[nLocale].Name;
+ lang::Locale& rLocale = pCompArray[nLocale].Locale;
+ sal_Int32 nSepPos = rLocaleStr.indexOf( cLocaleSep );
+ if ( nSepPos >= 0 )
+ {
+ rLocale.Language = rLocaleStr.copy( 0, nSepPos );
+ rLocale.Country = rLocaleStr.copy( nSepPos+1 );
+ }
+ else
+ rLocale.Language = rLocaleStr; // leave country empty (default ctor from sequence)
+
+ // PropertyValue value is the localized value (string in this case)
+
+ pConfigArray[nLocale].Value >>= pCompArray[nLocale].Name;
+ }
+ }
+ }
+
+ // get argument info
+
+ ScAddInArgDesc* pVisibleArgs = NULL;
+ long nVisibleCount = 0;
+ long nCallerPos = SC_CALLERPOS_NONE;
+
+ rtl::OUString aArgumentsPath = aFuncPropPath;
+ aArgumentsPath += rtl::OUString::createFromAscii( CFGSTR_PARAMETERS );
+
+ uno::Sequence<rtl::OUString> aArgumentNames = rAddInConfig.GetNodeNames( aArgumentsPath );
+ sal_Int32 nArgumentCount = aArgumentNames.getLength();
+ if ( nArgumentCount )
+ {
+ // get DisplayName and Description for each argument
+ uno::Sequence<rtl::OUString> aArgPropNames( nArgumentCount * 2 );
+ rtl::OUString* pPropNameArray = aArgPropNames.getArray();
+
+ sal_Int32 nArgument;
+ sal_Int32 nIndex = 0;
+ const rtl::OUString* pArgNameArray = aArgumentNames.getConstArray();
+ for ( nArgument = 0; nArgument < nArgumentCount; nArgument++ )
+ {
+ rtl::OUString aOneArgPath = aArgumentsPath;
+ aOneArgPath += sSlash;
+ aOneArgPath += pArgNameArray[nArgument];
+ aOneArgPath += sSlash;
+
+ pPropNameArray[nIndex] = aOneArgPath;
+ pPropNameArray[nIndex++] += rtl::OUString::createFromAscii( CFGSTR_DISPLAYNAME );
+ pPropNameArray[nIndex] = aOneArgPath;
+ pPropNameArray[nIndex++] += rtl::OUString::createFromAscii( CFGSTR_DESCRIPTION );
+ }
+
+ uno::Sequence<uno::Any> aArgProperties = rAddInConfig.GetProperties( aArgPropNames );
+ if ( aArgProperties.getLength() == aArgPropNames.getLength() )
+ {
+ const uno::Any* pPropArray = aArgProperties.getConstArray();
+ rtl::OUString sDisplayName;
+ rtl::OUString sDescription;
+
+ ScAddInArgDesc aDesc;
+ aDesc.eType = SC_ADDINARG_NONE; // arg type is not in configuration
+ aDesc.bOptional = FALSE;
+
+ nVisibleCount = nArgumentCount;
+ pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
+
+ nIndex = 0;
+ for ( nArgument = 0; nArgument < nArgumentCount; nArgument++ )
+ {
+ pPropArray[nIndex++] >>= sDisplayName;
+ pPropArray[nIndex++] >>= sDescription;
+
+ aDesc.aInternalName = pArgNameArray[nArgument];
+ aDesc.aName = sDisplayName;
+ aDesc.aDescription = sDescription;
+
+ pVisibleArgs[nArgument] = aDesc;
+ }
+ }
+ }
+
+ USHORT nHelpId = aHelpIdGenerator.GetHelpId( pFuncNameArray[nFuncPos] );
+
+ uno::Reference<reflection::XIdlMethod> xFunc; // remains empty
+ uno::Any aObject; // also empty
+
+ // create and insert into the array
+
+ ScUnoAddInFuncData* pData = new ScUnoAddInFuncData(
+ aFuncName, aLocalName, aDescription,
+ nCategory, nHelpId,
+ xFunc, aObject,
+ nVisibleCount, pVisibleArgs, nCallerPos );
+
+ pData->SetCompNames( aCompNames );
+
+ ppFuncData[nFuncPos+nOld] = pData;
+
+ pExactHashMap->insert(
+ ScAddInHashMap::value_type(
+ pData->GetOriginalName(),
+ pData ) );
+ pNameHashMap->insert(
+ ScAddInHashMap::value_type(
+ pData->GetUpperName(),
+ pData ) );
+ pLocalHashMap->insert(
+ ScAddInHashMap::value_type(
+ pData->GetUpperLocal(),
+ pData ) );
+
+ delete[] pVisibleArgs;
+ }
+ }
+ }
+}
+
+void ScUnoAddInCollection::LoadComponent( const ScUnoAddInFuncData& rFuncData )
+{
+ String aFullName = rFuncData.GetOriginalName();
+ xub_StrLen nPos = aFullName.SearchBackward( (sal_Unicode) '.' );
+ if ( nPos != STRING_NOTFOUND && nPos > 0 )
+ {
+ String aServiceName = aFullName.Copy( 0, nPos );
+
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory();
+ uno::Reference<uno::XInterface> xInterface( xServiceFactory->createInstance( aServiceName ) );
+
+ if (xInterface.is())
+ UpdateFromAddIn( xInterface, aServiceName );
+ }
+}
+
+BOOL ScUnoAddInCollection::GetExcelName( const String& rCalcName,
+ LanguageType eDestLang, String& rRetExcelName )
+{
+ const ScUnoAddInFuncData* pFuncData = GetFuncData( rCalcName );
+ if ( pFuncData )
+ return pFuncData->GetExcelName( eDestLang, rRetExcelName);
+ return FALSE;
+}
+
+BOOL ScUnoAddInCollection::GetCalcName( const String& rExcelName, String& rRetCalcName )
+{
+ if (!bInitialized)
+ Initialize();
+
+ String aUpperCmp = rExcelName;
+ ScGlobal::pCharClass->toUpper(aUpperCmp);
+
+ for (long i=0; i<nFuncCount; i++)
+ {
+ ScUnoAddInFuncData* pFuncData = ppFuncData[i];
+ if ( pFuncData )
+ {
+ const uno::Sequence<sheet::LocalizedName>& rSequence = pFuncData->GetCompNames();
+ long nSeqLen = rSequence.getLength();
+ if ( nSeqLen )
+ {
+ const sheet::LocalizedName* pArray = rSequence.getConstArray();
+ for ( long nName=0; nName<nSeqLen; nName++)
+ if ( ScGlobal::pCharClass->upper( pArray[nName].Name ) == aUpperCmp )
+ {
+ //! store upper case for comparing?
+
+ // use the first function that has this name for any language
+ rRetCalcName = pFuncData->GetOriginalName();
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+inline BOOL IsTypeName( const rtl::OUString& rName, const uno::Type& rType )
+{
+ return rName == rType.getTypeName();
+}
+
+BOOL lcl_ValidReturnType( const uno::Reference<reflection::XIdlClass>& xClass )
+{
+ // this must match with ScUnoAddInCall::SetResult
+
+ if ( !xClass.is() ) return FALSE;
+
+ switch (xClass->getTypeClass())
+ {
+ // case uno::TypeClass_VOID:
+ // ???
+
+ case uno::TypeClass_ANY: // variable type
+ case uno::TypeClass_ENUM: //! ???
+ case uno::TypeClass_BOOLEAN:
+ case uno::TypeClass_CHAR:
+ case uno::TypeClass_BYTE:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_UNSIGNED_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_UNSIGNED_LONG:
+ case uno::TypeClass_FLOAT:
+ case uno::TypeClass_DOUBLE:
+ case uno::TypeClass_STRING:
+ return TRUE; // values or string
+
+ case uno::TypeClass_INTERFACE:
+ {
+ // return type XInterface may contain a XVolatileResult
+ //! XIdlClass needs getType() method!
+
+ rtl::OUString sName = xClass->getName();
+ return (
+ IsTypeName( sName, getCppuType((uno::Reference<sheet::XVolatileResult>*)0) ) ||
+ IsTypeName( sName, getCppuType((uno::Reference<uno::XInterface>*)0) ) );
+ }
+
+ default:
+ {
+ // nested sequences for arrays
+ //! XIdlClass needs getType() method!
+
+ rtl::OUString sName = xClass->getName();
+ return (
+ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<INT32> >*)0) ) ||
+ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ) ||
+ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ) ||
+ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ) );
+ }
+ }
+ return FALSE;
+}
+
+ScAddInArgumentType lcl_GetArgType( const uno::Reference<reflection::XIdlClass>& xClass )
+{
+ if (!xClass.is())
+ return SC_ADDINARG_NONE;
+
+ uno::TypeClass eType = xClass->getTypeClass();
+
+ if ( eType == uno::TypeClass_LONG ) //! other integer types?
+ return SC_ADDINARG_INTEGER;
+
+ if ( eType == uno::TypeClass_DOUBLE )
+ return SC_ADDINARG_DOUBLE;
+
+ if ( eType == uno::TypeClass_STRING )
+ return SC_ADDINARG_STRING;
+
+ //! XIdlClass needs getType() method!
+ rtl::OUString sName = xClass->getName();
+
+ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<INT32> >*)0) ))
+ return SC_ADDINARG_INTEGER_ARRAY;
+
+ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ))
+ return SC_ADDINARG_DOUBLE_ARRAY;
+
+ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ))
+ return SC_ADDINARG_STRING_ARRAY;
+
+ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ))
+ return SC_ADDINARG_MIXED_ARRAY;
+
+ if (IsTypeName( sName, getCppuType((uno::Any*)0) ))
+ return SC_ADDINARG_VALUE_OR_ARRAY;
+
+ if (IsTypeName( sName, getCppuType((uno::Reference<table::XCellRange>*)0) ))
+ return SC_ADDINARG_CELLRANGE;
+
+ if (IsTypeName( sName, getCppuType((uno::Reference<beans::XPropertySet>*)0) ))
+ return SC_ADDINARG_CALLER;
+
+ if (IsTypeName( sName, getCppuType((uno::Sequence<uno::Any>*)0) ))
+ return SC_ADDINARG_VARARGS;
+
+ return SC_ADDINARG_NONE;
+}
+
+void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& xInterface )
+{
+ uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY );
+ uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY );
+ if ( xAddIn.is() && xName.is() )
+ {
+ // AddIns must use the language for which the office is installed
+ LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
+
+ lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
+ xAddIn->setLocale( aLocale );
+
+ String aServiceName = String( xName->getServiceName() );
+ ScUnoAddInHelpIdGenerator aHelpIdGenerator( xName->getServiceName() );
+
+ //! pass XIntrospection to ReadFromAddIn
+
+ uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
+ if ( xManager.is() )
+ {
+ uno::Reference<beans::XIntrospection> xIntro(
+ xManager->createInstance(rtl::OUString::createFromAscii(
+ "com.sun.star.beans.Introspection" )),
+ uno::UNO_QUERY );
+ if ( xIntro.is() )
+ {
+ uno::Any aObject;
+ aObject <<= xAddIn;
+ uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
+ if (xAcc.is())
+ {
+ uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
+ xAcc->getMethods( beans::MethodConcept::ALL );
+ long nNewCount = aMethods.getLength();
+ if ( nNewCount )
+ {
+ long nOld = nFuncCount;
+ nFuncCount = nNewCount+nOld;
+ if ( nOld )
+ {
+ ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount];
+ for (long i=0; i<nOld; i++)
+ ppNew[i] = ppFuncData[i];
+ delete[] ppFuncData;
+ ppFuncData = ppNew;
+ }
+ else
+ ppFuncData = new ScUnoAddInFuncData*[nFuncCount];
+
+ //! TODO: adjust bucket count?
+ if ( !pExactHashMap )
+ pExactHashMap = new ScAddInHashMap;
+ if ( !pNameHashMap )
+ pNameHashMap = new ScAddInHashMap;
+ if ( !pLocalHashMap )
+ pLocalHashMap = new ScAddInHashMap;
+
+ const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
+ for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++)
+ {
+ ppFuncData[nFuncPos+nOld] = NULL;
+
+ uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
+ if (xFunc.is())
+ {
+ // leave out internal functions
+ uno::Reference<reflection::XIdlClass> xClass =
+ xFunc->getDeclaringClass();
+ BOOL bSkip = TRUE;
+ if ( xClass.is() )
+ {
+ //! XIdlClass needs getType() method!
+ rtl::OUString sName = xClass->getName();
+ bSkip = (
+ IsTypeName( sName,
+ getCppuType((uno::Reference<uno::XInterface>*)0) ) ||
+ IsTypeName( sName,
+ getCppuType((uno::Reference<reflection::XIdlClassProvider>*)0) ) ||
+ IsTypeName( sName,
+ getCppuType((uno::Reference<lang::XServiceName>*)0) ) ||
+ IsTypeName( sName,
+ getCppuType((uno::Reference<lang::XServiceInfo>*)0) ) ||
+ IsTypeName( sName,
+ getCppuType((uno::Reference<sheet::XAddIn>*)0) ) );
+ }
+ if (!bSkip)
+ {
+ uno::Reference<reflection::XIdlClass> xReturn =
+ xFunc->getReturnType();
+ if ( !lcl_ValidReturnType( xReturn ) )
+ bSkip = TRUE;
+ }
+ if (!bSkip)
+ {
+ rtl::OUString aFuncU = xFunc->getName();
+
+ // stored function name: (service name).(function)
+ String aFuncName = aServiceName;
+ aFuncName += '.';
+ aFuncName += String( aFuncU );
+
+ BOOL bValid = TRUE;
+ long nVisibleCount = 0;
+ long nCallerPos = SC_CALLERPOS_NONE;
+
+ uno::Sequence<reflection::ParamInfo> aParams =
+ xFunc->getParameterInfos();
+ long nParamCount = aParams.getLength();
+ const reflection::ParamInfo* pParArr = aParams.getConstArray();
+ long nParamPos;
+ for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
+ {
+ if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
+ bValid = FALSE;
+ uno::Reference<reflection::XIdlClass> xParClass =
+ pParArr[nParamPos].aType;
+ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
+ if ( eArgType == SC_ADDINARG_NONE )
+ bValid = FALSE;
+ else if ( eArgType == SC_ADDINARG_CALLER )
+ nCallerPos = nParamPos;
+ else
+ ++nVisibleCount;
+ }
+ if (bValid)
+ {
+ USHORT nCategory = lcl_GetCategory(
+ String(
+ xAddIn->getProgrammaticCategoryName(
+ aFuncU ) ) );
+
+ USHORT nHelpId = aHelpIdGenerator.GetHelpId( aFuncU );
+
+ rtl::OUString aLocalU;
+ try
+ {
+ aLocalU = xAddIn->
+ getDisplayFunctionName( aFuncU );
+ }
+ catch(uno::Exception&)
+ {
+ aLocalU = rtl::OUString::createFromAscii( "###" );
+ }
+ String aLocalName = String( aLocalU );
+
+ rtl::OUString aDescU;
+ try
+ {
+ aDescU = xAddIn->
+ getFunctionDescription( aFuncU );
+ }
+ catch(uno::Exception&)
+ {
+ aDescU = rtl::OUString::createFromAscii( "###" );
+ }
+ String aDescription = String( aDescU );
+
+ ScAddInArgDesc* pVisibleArgs = NULL;
+ if ( nVisibleCount > 0 )
+ {
+ ScAddInArgDesc aDesc;
+ pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
+ long nDestPos = 0;
+ for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
+ {
+ uno::Reference<reflection::XIdlClass> xParClass =
+ pParArr[nParamPos].aType;
+ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
+ if ( eArgType != SC_ADDINARG_CALLER )
+ {
+ rtl::OUString aArgName;
+ try
+ {
+ aArgName = xAddIn->
+ getDisplayArgumentName( aFuncU, nParamPos );
+ }
+ catch(uno::Exception&)
+ {
+ aArgName = rtl::OUString::createFromAscii( "###" );
+ }
+ rtl::OUString aArgDesc;
+ try
+ {
+ aArgDesc = xAddIn->
+ getArgumentDescription( aFuncU, nParamPos );
+ }
+ catch(uno::Exception&)
+ {
+ aArgName = rtl::OUString::createFromAscii( "###" );
+ }
+
+ BOOL bOptional =
+ ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
+ eArgType == SC_ADDINARG_VARARGS );
+
+ aDesc.eType = eArgType;
+ aDesc.aName = String( aArgName );
+ aDesc.aDescription = String( aArgDesc );
+ aDesc.bOptional = bOptional;
+ //! initialize aInternalName only from config?
+ aDesc.aInternalName = pParArr[nParamPos].aName;
+
+ pVisibleArgs[nDestPos++] = aDesc;
+ }
+ }
+ DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
+ }
+
+ ppFuncData[nFuncPos+nOld] = new ScUnoAddInFuncData(
+ aFuncName, aLocalName, aDescription,
+ nCategory, nHelpId,
+ xFunc, aObject,
+ nVisibleCount, pVisibleArgs, nCallerPos );
+
+ const ScUnoAddInFuncData* pData =
+ ppFuncData[nFuncPos+nOld];
+ pExactHashMap->insert(
+ ScAddInHashMap::value_type(
+ pData->GetOriginalName(),
+ pData ) );
+ pNameHashMap->insert(
+ ScAddInHashMap::value_type(
+ pData->GetUpperName(),
+ pData ) );
+ pLocalHashMap->insert(
+ ScAddInHashMap::value_type(
+ pData->GetUpperLocal(),
+ pData ) );
+
+ delete[] pVisibleArgs;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void lcl_UpdateFunctionList( ScFunctionList& rFunctionList, const ScUnoAddInFuncData& rFuncData )
+{
+ String aCompare = rFuncData.GetUpperLocal(); // as used in FillFunctionDescFromData
+
+ ULONG nCount = rFunctionList.GetCount();
+ for (ULONG nPos=0; nPos<nCount; nPos++)
+ {
+ const ScFuncDesc* pDesc = rFunctionList.GetFunction( nPos );
+ if ( pDesc && pDesc->pFuncName && *pDesc->pFuncName == aCompare )
+ {
+ ScUnoAddInCollection::FillFunctionDescFromData( rFuncData, *const_cast<ScFuncDesc*>(pDesc) );
+ break;
+ }
+ }
+}
+
+const ScAddInArgDesc* lcl_FindArgDesc( const ScUnoAddInFuncData& rFuncData, const String& rArgIntName )
+{
+ long nArgCount = rFuncData.GetArgumentCount();
+ const ScAddInArgDesc* pArguments = rFuncData.GetArguments();
+ for (long nPos=0; nPos<nArgCount; nPos++)
+ {
+ if ( pArguments[nPos].aInternalName == rArgIntName )
+ return &pArguments[nPos];
+ }
+ return NULL;
+}
+
+void ScUnoAddInCollection::UpdateFromAddIn( const uno::Reference<uno::XInterface>& xInterface,
+ const String& rServiceName )
+{
+ uno::Reference<lang::XLocalizable> xLoc( xInterface, uno::UNO_QUERY );
+ if ( xLoc.is() ) // optional in new add-ins
+ {
+ LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
+ lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
+ xLoc->setLocale( aLocale );
+ }
+
+ // if function list was already initialized, it must be updated
+
+ ScFunctionList* pFunctionList = NULL;
+ if ( ScGlobal::HasStarCalcFunctionList() )
+ pFunctionList = ScGlobal::GetStarCalcFunctionList();
+
+ // only get the function information from Introspection
+
+ uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
+ if ( xManager.is() )
+ {
+ uno::Reference<beans::XIntrospection> xIntro(
+ xManager->createInstance(rtl::OUString::createFromAscii(
+ "com.sun.star.beans.Introspection" )),
+ uno::UNO_QUERY );
+ if ( xIntro.is() )
+ {
+ uno::Any aObject;
+ aObject <<= xInterface;
+ uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
+ if (xAcc.is())
+ {
+ uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
+ xAcc->getMethods( beans::MethodConcept::ALL );
+ long nMethodCount = aMethods.getLength();
+ const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
+ for (long nFuncPos=0; nFuncPos<nMethodCount; nFuncPos++)
+ {
+ uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
+ if (xFunc.is())
+ {
+ rtl::OUString aFuncU = xFunc->getName();
+
+ // stored function name: (service name).(function)
+ String aFuncName = rServiceName;
+ aFuncName += '.';
+ aFuncName += String( aFuncU );
+
+ // internal names are skipped because no FuncData exists
+ ScUnoAddInFuncData* pOldData = const_cast<ScUnoAddInFuncData*>( GetFuncData( aFuncName ) );
+ if ( pOldData )
+ {
+ // Create new (complete) argument info.
+ // As in ReadFromAddIn, the reflection information is authoritative.
+ // Local names and descriptions from pOldData are looked up using the
+ // internal argument name.
+
+ BOOL bValid = TRUE;
+ long nVisibleCount = 0;
+ long nCallerPos = SC_CALLERPOS_NONE;
+
+ uno::Sequence<reflection::ParamInfo> aParams =
+ xFunc->getParameterInfos();
+ long nParamCount = aParams.getLength();
+ const reflection::ParamInfo* pParArr = aParams.getConstArray();
+ long nParamPos;
+ for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
+ {
+ if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
+ bValid = FALSE;
+ uno::Reference<reflection::XIdlClass> xParClass =
+ pParArr[nParamPos].aType;
+ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
+ if ( eArgType == SC_ADDINARG_NONE )
+ bValid = FALSE;
+ else if ( eArgType == SC_ADDINARG_CALLER )
+ nCallerPos = nParamPos;
+ else
+ ++nVisibleCount;
+ }
+ if (bValid)
+ {
+ ScAddInArgDesc* pVisibleArgs = NULL;
+ if ( nVisibleCount > 0 )
+ {
+ ScAddInArgDesc aDesc;
+ pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
+ long nDestPos = 0;
+ for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
+ {
+ uno::Reference<reflection::XIdlClass> xParClass =
+ pParArr[nParamPos].aType;
+ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
+ if ( eArgType != SC_ADDINARG_CALLER )
+ {
+ const ScAddInArgDesc* pOldArgDesc =
+ lcl_FindArgDesc( *pOldData, pParArr[nParamPos].aName );
+ if ( pOldArgDesc )
+ {
+ aDesc.aName = pOldArgDesc->aName;
+ aDesc.aDescription = pOldArgDesc->aDescription;
+ }
+ else
+ aDesc.aName = aDesc.aDescription = String::CreateFromAscii( "###" );
+
+ BOOL bOptional =
+ ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
+ eArgType == SC_ADDINARG_VARARGS );
+
+ aDesc.eType = eArgType;
+ aDesc.bOptional = bOptional;
+ //! initialize aInternalName only from config?
+ aDesc.aInternalName = pParArr[nParamPos].aName;
+
+ pVisibleArgs[nDestPos++] = aDesc;
+ }
+ }
+ DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
+ }
+
+ pOldData->SetFunction( xFunc, aObject );
+ pOldData->SetArguments( nVisibleCount, pVisibleArgs );
+ pOldData->SetCallerPos( nCallerPos );
+
+ if ( pFunctionList )
+ lcl_UpdateFunctionList( *pFunctionList, *pOldData );
+
+ delete[] pVisibleArgs;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+String ScUnoAddInCollection::FindFunction( const String& rUpperName, BOOL bLocalFirst )
+{
+ if (!bInitialized)
+ Initialize();
+
+ if (nFuncCount == 0)
+ return EMPTY_STRING;
+
+ if ( bLocalFirst )
+ {
+ // first scan all local names (used for entering formulas)
+
+ ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) );
+ if ( iLook != pLocalHashMap->end() )
+ return iLook->second->GetOriginalName();
+
+#if 0
+ // after that, scan international names (really?)
+
+ iLook = pNameHashMap->find( rUpperName );
+ if ( iLook != pNameHashMap->end() )
+ return iLook->second->GetOriginalName();
+#endif
+ }
+ else
+ {
+ // first scan international names (used when calling a function)
+ //! before that, check for exact match???
+
+ ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) );
+ if ( iLook != pNameHashMap->end() )
+ return iLook->second->GetOriginalName();
+
+ // after that, scan all local names (to allow replacing old AddIns with Uno)
+
+ iLook = pLocalHashMap->find( rUpperName );
+ if ( iLook != pLocalHashMap->end() )
+ return iLook->second->GetOriginalName();
+ }
+
+ return EMPTY_STRING;
+}
+
+const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( const String& rName, bool bComplete )
+{
+ if (!bInitialized)
+ Initialize();
+
+ // rName must be the exact internal name
+
+ ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
+ if ( iLook != pExactHashMap->end() )
+ {
+ const ScUnoAddInFuncData* pFuncData = iLook->second;
+
+ if ( bComplete && !pFuncData->GetFunction().is() ) //! extra flag?
+ LoadComponent( *pFuncData );
+
+ return pFuncData;
+ }
+
+ return NULL;
+}
+
+const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( long nIndex )
+{
+ if (!bInitialized)
+ Initialize();
+
+ if (nIndex < nFuncCount)
+ return ppFuncData[nIndex];
+ return NULL;
+}
+
+void ScUnoAddInCollection::LocalizeString( String& rName )
+{
+ if (!bInitialized)
+ Initialize();
+
+ // modify rName - input: exact name
+
+ ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
+ if ( iLook != pExactHashMap->end() )
+ rName = iLook->second->GetUpperLocal(); //! upper?
+}
+
+
+long ScUnoAddInCollection::GetFuncCount()
+{
+ if (!bInitialized)
+ Initialize();
+
+ return nFuncCount;
+}
+
+BOOL ScUnoAddInCollection::FillFunctionDesc( long nFunc, ScFuncDesc& rDesc )
+{
+ if (!bInitialized)
+ Initialize();
+
+ if (nFunc >= nFuncCount || !ppFuncData[nFunc])
+ return FALSE;
+
+ const ScUnoAddInFuncData& rFuncData = *ppFuncData[nFunc];
+
+ return FillFunctionDescFromData( rFuncData, rDesc );
+}
+
+// static
+BOOL ScUnoAddInCollection::FillFunctionDescFromData( const ScUnoAddInFuncData& rFuncData, ScFuncDesc& rDesc )
+{
+ rDesc.Clear();
+
+ BOOL bIncomplete = !rFuncData.GetFunction().is(); //! extra flag?
+
+ long nArgCount = rFuncData.GetArgumentCount();
+ if ( nArgCount > USHRT_MAX )
+ return FALSE;
+
+ if ( bIncomplete )
+ nArgCount = 0; // if incomplete, fill without argument info (no wrong order)
+
+ // nFIndex is set from outside
+
+ rDesc.pFuncName = new String( rFuncData.GetUpperLocal() ); //! upper?
+ rDesc.nCategory = rFuncData.GetCategory();
+ rDesc.nHelpId = rFuncData.GetHelpId();
+
+ String aDesc = rFuncData.GetDescription();
+ if (!aDesc.Len())
+ aDesc = rFuncData.GetLocalName(); // use name if no description is available
+ rDesc.pFuncDesc = new String( aDesc );
+
+ // AddInArgumentType_CALLER is already left out in FuncData
+
+ rDesc.nArgCount = (USHORT)nArgCount;
+ if ( nArgCount )
+ {
+ BOOL bMultiple = FALSE;
+ const ScAddInArgDesc* pArgs = rFuncData.GetArguments();
+
+ rDesc.ppDefArgNames = new String*[nArgCount];
+ rDesc.ppDefArgDescs = new String*[nArgCount];
+ rDesc.pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgCount];
+ for ( long nArg=0; nArg<nArgCount; nArg++ )
+ {
+ rDesc.ppDefArgNames[nArg] = new String( pArgs[nArg].aName );
+ rDesc.ppDefArgDescs[nArg] = new String( pArgs[nArg].aDescription );
+ rDesc.pDefArgFlags[nArg].bOptional = pArgs[nArg].bOptional;
+ rDesc.pDefArgFlags[nArg].bSuppress = false;
+
+ // no empty names...
+ if ( rDesc.ppDefArgNames[nArg]->Len() == 0 )
+ {
+ String aDefName( RTL_CONSTASCII_USTRINGPARAM("arg") );
+ aDefName += String::CreateFromInt32( nArg+1 );
+ *rDesc.ppDefArgNames[nArg] = aDefName;
+ }
+
+ // last argument repeated?
+ if ( nArg+1 == nArgCount && ( pArgs[nArg].eType == SC_ADDINARG_VARARGS ) )
+ bMultiple = TRUE;
+ }
+
+ if ( bMultiple )
+ rDesc.nArgCount += VAR_ARGS - 1; // VAR_ARGS means just one repeated arg
+ }
+
+ rDesc.bIncomplete = bIncomplete;
+
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------
+
+ScUnoAddInCall::ScUnoAddInCall( ScUnoAddInCollection& rColl, const String& rName,
+ long nParamCount ) :
+ bValidCount( FALSE ),
+ nErrCode( errNoCode ), // before function was called
+ bHasString( TRUE ),
+ fValue( 0.0 ),
+ xMatrix( NULL )
+{
+ pFuncData = rColl.GetFuncData( rName, true ); // need fully initialized data
+ DBG_ASSERT( pFuncData, "Function Data missing" );
+ if ( pFuncData )
+ {
+ long nDescCount = pFuncData->GetArgumentCount();
+ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+
+ // is aVarArg sequence needed?
+ if ( nParamCount >= nDescCount && nDescCount > 0 &&
+ pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS )
+ {
+ long nVarCount = nParamCount - ( nDescCount - 1 ); // size of last argument
+ aVarArg.realloc( nVarCount );
+ bValidCount = TRUE;
+ }
+ else if ( nParamCount <= nDescCount )
+ {
+ // all args behind nParamCount must be optional
+ bValidCount = TRUE;
+ for (long i=nParamCount; i<nDescCount; i++)
+ if ( !pArgs[i].bOptional )
+ bValidCount = FALSE;
+ }
+ // else invalid (too many arguments)
+
+ if ( bValidCount )
+ aArgs.realloc( nDescCount ); // sequence must always match function signature
+ }
+}
+
+ScUnoAddInCall::~ScUnoAddInCall()
+{
+ // pFuncData is deleted with ScUnoAddInCollection
+}
+
+BOOL ScUnoAddInCall::ValidParamCount()
+{
+ return bValidCount;
+}
+
+ScAddInArgumentType ScUnoAddInCall::GetArgType( long nPos )
+{
+ if ( pFuncData )
+ {
+ long nCount = pFuncData->GetArgumentCount();
+ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+
+ // if last arg is sequence, use "any" type
+ if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+ return SC_ADDINARG_VALUE_OR_ARRAY;
+
+ if ( nPos < nCount )
+ return pArgs[nPos].eType;
+ }
+ return SC_ADDINARG_VALUE_OR_ARRAY; //! error code !!!!
+}
+
+BOOL ScUnoAddInCall::NeedsCaller() const
+{
+ return pFuncData && pFuncData->GetCallerPos() != SC_CALLERPOS_NONE;
+}
+
+void ScUnoAddInCall::SetCaller( const uno::Reference<uno::XInterface>& rInterface )
+{
+ xCaller = rInterface;
+}
+
+void ScUnoAddInCall::SetCallerFromObjectShell( SfxObjectShell* pObjSh )
+{
+ if (pObjSh)
+ {
+ uno::Reference<uno::XInterface> xInt( pObjSh->GetBaseModel(), uno::UNO_QUERY );
+ SetCaller( xInt );
+ }
+}
+
+void ScUnoAddInCall::SetParam( long nPos, const uno::Any& rValue )
+{
+ if ( pFuncData )
+ {
+ long nCount = pFuncData->GetArgumentCount();
+ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+ if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+ {
+ long nVarPos = nPos-(nCount-1);
+ if ( nVarPos < aVarArg.getLength() )
+ aVarArg.getArray()[nVarPos] = rValue;
+ else
+ {
+ DBG_ERROR("wrong argument number");
+ }
+ }
+ else if ( nPos < aArgs.getLength() )
+ aArgs.getArray()[nPos] = rValue;
+ else
+ {
+ DBG_ERROR("wrong argument number");
+ }
+ }
+}
+
+void ScUnoAddInCall::ExecuteCall()
+{
+ if ( !pFuncData )
+ return;
+
+ long nCount = pFuncData->GetArgumentCount();
+ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+ if ( nCount > 0 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+ {
+ // insert aVarArg as last argument
+ //! after inserting caller (to prevent copying twice)?
+
+ DBG_ASSERT( aArgs.getLength() == nCount, "wrong argument count" );
+ aArgs.getArray()[nCount-1] <<= aVarArg;
+ }
+
+ if ( pFuncData->GetCallerPos() != SC_CALLERPOS_NONE )
+ {
+ uno::Any aCallerAny;
+ aCallerAny <<= xCaller;
+
+ long nUserLen = aArgs.getLength();
+ long nCallPos = pFuncData->GetCallerPos();
+ if (nCallPos>nUserLen) // should not happen
+ {
+ DBG_ERROR("wrong CallPos");
+ nCallPos = nUserLen;
+ }
+
+ long nDestLen = nUserLen + 1;
+ uno::Sequence<uno::Any> aRealArgs( nDestLen );
+ uno::Any* pDest = aRealArgs.getArray();
+
+ const uno::Any* pSource = aArgs.getConstArray();
+ long nSrcPos = 0;
+
+ for ( long nDestPos = 0; nDestPos < nDestLen; nDestPos++ )
+ {
+ if ( nDestPos == nCallPos )
+ pDest[nDestPos] = aCallerAny;
+ else
+ pDest[nDestPos] = pSource[nSrcPos++];
+ }
+
+ ExecuteCallWithArgs( aRealArgs );
+ }
+ else
+ ExecuteCallWithArgs( aArgs );
+}
+
+void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs)
+{
+ // rCallArgs may not match argument descriptions (because of caller)
+
+ uno::Reference<reflection::XIdlMethod> xFunction;
+ uno::Any aObject;
+ if ( pFuncData )
+ {
+ xFunction = pFuncData->GetFunction();
+ aObject = pFuncData->GetObject();
+ }
+
+ if ( xFunction.is() )
+ {
+ uno::Any aAny;
+ nErrCode = 0;
+
+ try
+ {
+ aAny = xFunction->invoke( aObject, rCallArgs );
+ }
+ catch(lang::IllegalArgumentException&)
+ {
+ nErrCode = errIllegalArgument;
+ }
+#if 0
+ catch(FloatingPointException&)
+ {
+ nErrCode = errIllegalFPOperation;
+ }
+#endif
+ catch(reflection::InvocationTargetException& rWrapped)
+ {
+ if ( rWrapped.TargetException.getValueType().equals(
+ getCppuType( (lang::IllegalArgumentException*)0 ) ) )
+ nErrCode = errIllegalArgument;
+ else if ( rWrapped.TargetException.getValueType().equals(
+ getCppuType( (sheet::NoConvergenceException*)0 ) ) )
+ nErrCode = errNoConvergence;
+ else
+ nErrCode = errNoValue;
+ }
+
+ catch(uno::Exception&)
+ {
+ nErrCode = errNoValue;
+ }
+
+ if (!nErrCode)
+ SetResult( aAny ); // convert result to Calc types
+ }
+}
+
+void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
+{
+ nErrCode = 0;
+ xVarRes = NULL;
+
+ // Reflection* pRefl = rNewRes.getReflection();
+
+ uno::TypeClass eClass = rNewRes.getValueTypeClass();
+ uno::Type aType = rNewRes.getValueType();
+ switch (eClass)
+ {
+ case uno::TypeClass_VOID:
+ nErrCode = NOTAVAILABLE; // #NA
+ break;
+
+ case uno::TypeClass_ENUM:
+ case uno::TypeClass_BOOLEAN:
+ case uno::TypeClass_CHAR:
+ case uno::TypeClass_BYTE:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_UNSIGNED_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_UNSIGNED_LONG:
+ case uno::TypeClass_FLOAT:
+ case uno::TypeClass_DOUBLE:
+ {
+ uno::TypeClass eMyClass;
+ ScApiTypeConversion::ConvertAnyToDouble( fValue, eMyClass, rNewRes);
+ bHasString = FALSE;
+ }
+ break;
+
+ case uno::TypeClass_STRING:
+ {
+ rtl::OUString aUStr;
+ rNewRes >>= aUStr;
+ aString = String( aUStr );
+ bHasString = TRUE;
+ }
+ break;
+
+ case uno::TypeClass_INTERFACE:
+ {
+ //! directly extract XVolatileResult from any?
+ uno::Reference<uno::XInterface> xInterface;
+ rNewRes >>= xInterface;
+ if ( xInterface.is() )
+ xVarRes = uno::Reference<sheet::XVolatileResult>( xInterface, uno::UNO_QUERY );
+
+ if (!xVarRes.is())
+ nErrCode = errNoValue; // unknown interface
+ }
+ break;
+
+ default:
+ if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<INT32> > *)0 ) ) )
+ {
+ const uno::Sequence< uno::Sequence<INT32> >* pRowSeq = NULL;
+
+ //! use pointer from any!
+ uno::Sequence< uno::Sequence<INT32> > aSequence;
+ if ( rNewRes >>= aSequence )
+ pRowSeq = &aSequence;
+
+ if ( pRowSeq )
+ {
+ long nRowCount = pRowSeq->getLength();
+ const uno::Sequence<INT32>* pRowArr = pRowSeq->getConstArray();
+ long nMaxColCount = 0;
+ long nCol, nRow;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ long nTmp = pRowArr[nRow].getLength();
+ if ( nTmp > nMaxColCount )
+ nMaxColCount = nTmp;
+ }
+ if ( nMaxColCount && nRowCount )
+ {
+ xMatrix = new ScMatrix(
+ static_cast<SCSIZE>(nMaxColCount),
+ static_cast<SCSIZE>(nRowCount) );
+ ScMatrix* pMatrix = xMatrix;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ long nColCount = pRowArr[nRow].getLength();
+ const INT32* pColArr = pRowArr[nRow].getConstArray();
+ for (nCol=0; nCol<nColCount; nCol++)
+ pMatrix->PutDouble( pColArr[nCol],
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+ pMatrix->PutDouble( 0.0,
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ }
+ }
+ }
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
+ {
+ const uno::Sequence< uno::Sequence<double> >* pRowSeq = NULL;
+
+ //! use pointer from any!
+ uno::Sequence< uno::Sequence<double> > aSequence;
+ if ( rNewRes >>= aSequence )
+ pRowSeq = &aSequence;
+
+ if ( pRowSeq )
+ {
+ long nRowCount = pRowSeq->getLength();
+ const uno::Sequence<double>* pRowArr = pRowSeq->getConstArray();
+ long nMaxColCount = 0;
+ long nCol, nRow;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ long nTmp = pRowArr[nRow].getLength();
+ if ( nTmp > nMaxColCount )
+ nMaxColCount = nTmp;
+ }
+ if ( nMaxColCount && nRowCount )
+ {
+ xMatrix = new ScMatrix(
+ static_cast<SCSIZE>(nMaxColCount),
+ static_cast<SCSIZE>(nRowCount) );
+ ScMatrix* pMatrix = xMatrix;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ long nColCount = pRowArr[nRow].getLength();
+ const double* pColArr = pRowArr[nRow].getConstArray();
+ for (nCol=0; nCol<nColCount; nCol++)
+ pMatrix->PutDouble( pColArr[nCol],
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+ pMatrix->PutDouble( 0.0,
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ }
+ }
+ }
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) )
+ {
+ const uno::Sequence< uno::Sequence<rtl::OUString> >* pRowSeq = NULL;
+
+ //! use pointer from any!
+ uno::Sequence< uno::Sequence<rtl::OUString> > aSequence;
+ if ( rNewRes >>= aSequence )
+ pRowSeq = &aSequence;
+
+ if ( pRowSeq )
+ {
+ long nRowCount = pRowSeq->getLength();
+ const uno::Sequence<rtl::OUString>* pRowArr = pRowSeq->getConstArray();
+ long nMaxColCount = 0;
+ long nCol, nRow;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ long nTmp = pRowArr[nRow].getLength();
+ if ( nTmp > nMaxColCount )
+ nMaxColCount = nTmp;
+ }
+ if ( nMaxColCount && nRowCount )
+ {
+ xMatrix = new ScMatrix(
+ static_cast<SCSIZE>(nMaxColCount),
+ static_cast<SCSIZE>(nRowCount) );
+ ScMatrix* pMatrix = xMatrix;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ long nColCount = pRowArr[nRow].getLength();
+ const rtl::OUString* pColArr = pRowArr[nRow].getConstArray();
+ for (nCol=0; nCol<nColCount; nCol++)
+ pMatrix->PutString( String( pColArr[nCol] ),
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+ pMatrix->PutString( EMPTY_STRING,
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ }
+ }
+ }
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
+ {
+ xMatrix = ScSequenceToMatrix::CreateMixedMatrix( rNewRes );
+ }
+
+ if (!xMatrix) // no array found
+ nErrCode = errNoValue; //! code for error in return type???
+ }
+}
+
+
+
+//------------------------------------------------------------------------
+
+
+
diff --git a/sc/source/core/tool/addinhelpid.cxx b/sc/source/core/tool/addinhelpid.cxx
new file mode 100644
index 000000000000..a4de52e27b1b
--- /dev/null
+++ b/sc/source/core/tool/addinhelpid.cxx
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "addinhelpid.hxx"
+#include "sc.hrc"
+
+// ============================================================================
+
+// A struct containing the built-in function name and the built-in help ID.
+struct ScUnoAddInHelpId
+{
+ const sal_Char* pFuncName;
+ sal_uInt16 nHelpId;
+};
+
+
+// ----------------------------------------------------------------------------
+
+// Help IDs for Analysis AddIn. MUST BE SORTED for binary search.
+const ScUnoAddInHelpId pAnalysisHelpIds[] =
+{
+ { "getAccrint" , HID_AAI_FUNC_ACCRINT },
+ { "getAccrintm" , HID_AAI_FUNC_ACCRINTM },
+ { "getAmordegrc" , HID_AAI_FUNC_AMORDEGRC },
+ { "getAmorlinc" , HID_AAI_FUNC_AMORLINC },
+ { "getBesseli" , HID_AAI_FUNC_BESSELI },
+ { "getBesselj" , HID_AAI_FUNC_BESSELJ },
+ { "getBesselk" , HID_AAI_FUNC_BESSELK },
+ { "getBessely" , HID_AAI_FUNC_BESSELY },
+ { "getBin2Dec" , HID_AAI_FUNC_BIN2DEC },
+ { "getBin2Hex" , HID_AAI_FUNC_BIN2HEX },
+ { "getBin2Oct" , HID_AAI_FUNC_BIN2OCT },
+ { "getComplex" , HID_AAI_FUNC_COMPLEX },
+ { "getConvert" , HID_AAI_FUNC_CONVERT },
+ { "getCoupdaybs" , HID_AAI_FUNC_COUPDAYBS },
+ { "getCoupdays" , HID_AAI_FUNC_COUPDAYS },
+ { "getCoupdaysnc" , HID_AAI_FUNC_COUPDAYSNC },
+ { "getCoupncd" , HID_AAI_FUNC_COUPNCD },
+ { "getCoupnum" , HID_AAI_FUNC_COUPNUM },
+ { "getCouppcd" , HID_AAI_FUNC_COUPPCD },
+ { "getCumipmt" , HID_AAI_FUNC_CUMIPMT },
+ { "getCumprinc" , HID_AAI_FUNC_CUMPRINC },
+ { "getDec2Bin" , HID_AAI_FUNC_DEC2BIN },
+ { "getDec2Hex" , HID_AAI_FUNC_DEC2HEX },
+ { "getDec2Oct" , HID_AAI_FUNC_DEC2OCT },
+ { "getDelta" , HID_AAI_FUNC_DELTA },
+ { "getDisc" , HID_AAI_FUNC_DISC },
+ { "getDollarde" , HID_AAI_FUNC_DOLLARDE },
+ { "getDollarfr" , HID_AAI_FUNC_DOLLARFR },
+ { "getDuration" , HID_AAI_FUNC_DURATION },
+ { "getEdate" , HID_AAI_FUNC_EDATE },
+ { "getEffect" , HID_AAI_FUNC_EFFECT },
+ { "getEomonth" , HID_AAI_FUNC_EOMONTH },
+ { "getErf" , HID_AAI_FUNC_ERF },
+ { "getErfc" , HID_AAI_FUNC_ERFC },
+ { "getFactdouble" , HID_AAI_FUNC_FACTDOUBLE },
+ { "getFvschedule" , HID_AAI_FUNC_FVSCHEDULE },
+ { "getGcd" , HID_AAI_FUNC_GCD },
+ { "getGestep" , HID_AAI_FUNC_GESTEP },
+ { "getHex2Bin" , HID_AAI_FUNC_HEX2BIN },
+ { "getHex2Dec" , HID_AAI_FUNC_HEX2DEC },
+ { "getHex2Oct" , HID_AAI_FUNC_HEX2OCT },
+ { "getImabs" , HID_AAI_FUNC_IMABS },
+ { "getImaginary" , HID_AAI_FUNC_IMAGINARY },
+ { "getImargument" , HID_AAI_FUNC_IMARGUMENT },
+ { "getImconjugate" , HID_AAI_FUNC_IMCONJUGATE },
+ { "getImcos" , HID_AAI_FUNC_IMCOS },
+ { "getImdiv" , HID_AAI_FUNC_IMDIV },
+ { "getImexp" , HID_AAI_FUNC_IMEXP },
+ { "getImln" , HID_AAI_FUNC_IMLN },
+ { "getImlog10" , HID_AAI_FUNC_IMLOG10 },
+ { "getImlog2" , HID_AAI_FUNC_IMLOG2 },
+ { "getImpower" , HID_AAI_FUNC_IMPOWER },
+ { "getImproduct" , HID_AAI_FUNC_IMPRODUCT },
+ { "getImreal" , HID_AAI_FUNC_IMREAL },
+ { "getImsin" , HID_AAI_FUNC_IMSIN },
+ { "getImsqrt" , HID_AAI_FUNC_IMSQRT },
+ { "getImsub" , HID_AAI_FUNC_IMSUB },
+ { "getImsum" , HID_AAI_FUNC_IMSUM },
+ { "getIntrate" , HID_AAI_FUNC_INTRATE },
+ { "getIseven" , HID_AAI_FUNC_ISEVEN },
+ { "getIsodd" , HID_AAI_FUNC_ISODD },
+ { "getLcm" , HID_AAI_FUNC_LCM },
+ { "getMduration" , HID_AAI_FUNC_MDURATION },
+ { "getMround" , HID_AAI_FUNC_MROUND },
+ { "getMultinomial" , HID_AAI_FUNC_MULTINOMIAL },
+ { "getNetworkdays" , HID_AAI_FUNC_NETWORKDAYS },
+ { "getNominal" , HID_AAI_FUNC_NOMINAL },
+ { "getOct2Bin" , HID_AAI_FUNC_OCT2BIN },
+ { "getOct2Dec" , HID_AAI_FUNC_OCT2DEZ },
+ { "getOct2Hex" , HID_AAI_FUNC_OCT2HEX },
+ { "getOddfprice" , HID_AAI_FUNC_ODDFPRICE },
+ { "getOddfyield" , HID_AAI_FUNC_ODDFYIELD },
+ { "getOddlprice" , HID_AAI_FUNC_ODDLPRICE },
+ { "getOddlyield" , HID_AAI_FUNC_ODDLYIELD },
+ { "getPrice" , HID_AAI_FUNC_PRICE },
+ { "getPricedisc" , HID_AAI_FUNC_PRICEDISC },
+ { "getPricemat" , HID_AAI_FUNC_PRICEMAT },
+ { "getQuotient" , HID_AAI_FUNC_QUOTIENT },
+ { "getRandbetween" , HID_AAI_FUNC_RANDBETWEEN },
+ { "getReceived" , HID_AAI_FUNC_RECEIVED },
+ { "getSeriessum" , HID_AAI_FUNC_SERIESSUM },
+ { "getSqrtpi" , HID_AAI_FUNC_SQRTPI },
+ { "getTbilleq" , HID_AAI_FUNC_TBILLEQ },
+ { "getTbillprice" , HID_AAI_FUNC_TBILLPRICE },
+ { "getTbillyield" , HID_AAI_FUNC_TBILLYIELD },
+ { "getWeeknum" , HID_AAI_FUNC_WEEKNUM },
+ { "getWorkday" , HID_AAI_FUNC_WORKDAY },
+ { "getXirr" , HID_AAI_FUNC_XIRR },
+ { "getXnpv" , HID_AAI_FUNC_XNPV },
+ { "getYearfrac" , HID_AAI_FUNC_YEARFRAC },
+ { "getYield" , HID_AAI_FUNC_YIELD },
+ { "getYielddisc" , HID_AAI_FUNC_YIELDDISC },
+ { "getYieldmat" , HID_AAI_FUNC_YIELDMAT }
+};
+
+
+// ----------------------------------------------------------------------------
+
+// Help IDs for DateFunc AddIn. MUST BE SORTED for binary search.
+const ScUnoAddInHelpId pDateFuncHelpIds[] =
+{
+ { "getDaysInMonth" , HID_DAI_FUNC_DAYSINMONTH },
+ { "getDaysInYear" , HID_DAI_FUNC_DAYSINYEAR },
+ { "getDiffMonths" , HID_DAI_FUNC_DIFFMONTHS },
+ { "getDiffWeeks" , HID_DAI_FUNC_DIFFWEEKS },
+ { "getDiffYears" , HID_DAI_FUNC_DIFFYEARS },
+ { "getRot13" , HID_DAI_FUNC_ROT13 },
+ { "getWeeksInYear" , HID_DAI_FUNC_WEEKSINYEAR }
+};
+
+
+// ============================================================================
+
+//UNUSED2008-05 ScUnoAddInHelpIdGenerator::ScUnoAddInHelpIdGenerator() :
+//UNUSED2008-05 pCurrHelpIds( NULL ),
+//UNUSED2008-05 nArrayCount( 0 )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScUnoAddInHelpIdGenerator::ScUnoAddInHelpIdGenerator( const ::rtl::OUString& rServiceName )
+{
+ SetServiceName( rServiceName );
+}
+
+void ScUnoAddInHelpIdGenerator::SetServiceName( const ::rtl::OUString& rServiceName )
+{
+ pCurrHelpIds = NULL;
+ sal_uInt32 nSize = 0;
+
+ if( rServiceName.equalsAscii( "com.sun.star.sheet.addin.Analysis" ) )
+ {
+ pCurrHelpIds = pAnalysisHelpIds;
+ nSize = sizeof( pAnalysisHelpIds );
+ }
+ else if( rServiceName.equalsAscii( "com.sun.star.sheet.addin.DateFunctions" ) )
+ {
+ pCurrHelpIds = pDateFuncHelpIds;
+ nSize = sizeof( pDateFuncHelpIds );
+ }
+
+ nArrayCount = nSize / sizeof( ScUnoAddInHelpId );
+}
+
+sal_uInt16 ScUnoAddInHelpIdGenerator::GetHelpId( const ::rtl::OUString& rFuncName ) const
+{
+ if( !pCurrHelpIds || !nArrayCount )
+ return 0;
+
+ const ScUnoAddInHelpId* pFirst = pCurrHelpIds;
+ const ScUnoAddInHelpId* pLast = pCurrHelpIds + nArrayCount - 1;
+
+ while( pFirst <= pLast )
+ {
+ const ScUnoAddInHelpId* pMiddle = pFirst + (pLast - pFirst) / 2;
+ sal_Int32 nResult = rFuncName.compareToAscii( pMiddle->pFuncName );
+ if( !nResult )
+ return pMiddle->nHelpId;
+ else if( nResult < 0 )
+ pLast = pMiddle - 1;
+ else
+ pFirst = pMiddle + 1;
+ }
+
+ return 0;
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/core/tool/addinlis.cxx b/sc/source/core/tool/addinlis.cxx
new file mode 100644
index 000000000000..ad6b60073ccb
--- /dev/null
+++ b/sc/source/core/tool/addinlis.cxx
@@ -0,0 +1,190 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+#include <sfx2/objsh.hxx>
+
+
+#include "addinlis.hxx"
+#include "miscuno.hxx" // SC_IMPL_SERVICE_INFO
+#include "document.hxx"
+#include "brdcst.hxx"
+#include "unoguard.hxx"
+#include "sc.hrc"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+//SMART_UNO_IMPLEMENTATION( ScAddInListener, UsrObject );
+
+SC_SIMPLE_SERVICE_INFO( ScAddInListener, "ScAddInListener", "stardiv.one.sheet.AddInListener" )
+
+//------------------------------------------------------------------------
+
+List ScAddInListener::aAllListeners;
+
+//------------------------------------------------------------------------
+
+// static
+ScAddInListener* ScAddInListener::CreateListener(
+ uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc )
+{
+ ScAddInListener* pNew = new ScAddInListener( xVR, pDoc );
+
+ pNew->acquire(); // for aAllListeners
+ aAllListeners.Insert( pNew, LIST_APPEND );
+
+ if ( xVR.is() )
+ xVR->addResultListener( pNew ); // after at least 1 ref exists!
+
+ return pNew;
+}
+
+ScAddInListener::ScAddInListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) :
+ xVolRes( xVR )
+{
+ pDocs = new ScAddInDocs( 1, 1 );
+ pDocs->Insert( pDoc );
+}
+
+ScAddInListener::~ScAddInListener()
+{
+ delete pDocs;
+}
+
+// static
+ScAddInListener* ScAddInListener::Get( uno::Reference<sheet::XVolatileResult> xVR )
+{
+ sheet::XVolatileResult* pComp = xVR.get();
+
+ ULONG nCount = aAllListeners.Count();
+ for (ULONG nPos=0; nPos<nCount; nPos++)
+ {
+ ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos);
+ if ( pComp == (sheet::XVolatileResult*)pLst->xVolRes.get() )
+ return pLst;
+ }
+ return NULL; // not found
+}
+
+//! move to some container object?
+// static
+void ScAddInListener::RemoveDocument( ScDocument* pDocumentP )
+{
+ ULONG nPos = aAllListeners.Count();
+ while (nPos)
+ {
+ // loop backwards because elements are removed
+ --nPos;
+ ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos);
+ ScAddInDocs* p = pLst->pDocs;
+ USHORT nFoundPos;
+ if ( p->Seek_Entry( pDocumentP, &nFoundPos ) )
+ {
+ p->Remove( nFoundPos );
+ if ( p->Count() == 0 )
+ {
+ // this AddIn is no longer used
+ // dont delete, just remove the ref for the list
+
+ aAllListeners.Remove( nPos );
+
+ if ( pLst->xVolRes.is() )
+ pLst->xVolRes->removeResultListener( pLst );
+
+ pLst->release(); // Ref for aAllListeners - pLst may be deleted here
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+// XResultListener
+
+void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard; //! or generate a UserEvent
+
+ aResult = aEvent.Value; // store result
+
+ if ( !HasListeners() )
+ {
+ //! remove from list and removeListener, as in RemoveDocument ???
+
+#if 0
+ //! this will crash if called before first StartListening !!!
+ aAllListeners.Remove( this );
+ if ( xVolRes.is() )
+ xVolRes->removeResultListener( this );
+ release(); // Ref for aAllListeners - this may be deleted here
+ return;
+#endif
+ }
+
+ // notify document of changes
+
+ Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
+
+ const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData();
+ USHORT nCount = pDocs->Count();
+ for ( USHORT j=0; j<nCount; j++, ppDoc++ )
+ {
+ ScDocument* pDoc = (ScDocument*)*ppDoc;
+ pDoc->TrackFormulas();
+ pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
+ pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
+ }
+}
+
+// XEventListener
+
+void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& /* Source */ )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ // hold a ref so this is not deleted at removeResultListener
+ uno::Reference<sheet::XResultListener> xRef( this );
+
+ if ( xVolRes.is() )
+ {
+ xVolRes->removeResultListener( this );
+ xVolRes = NULL;
+ }
+}
+
+
+//------------------------------------------------------------------------
+
+
+
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
new file mode 100644
index 000000000000..ccbecd52d9f2
--- /dev/null
+++ b/sc/source/core/tool/address.cxx
@@ -0,0 +1,2029 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "address.hxx"
+#include "global.hxx"
+#include "compiler.hxx"
+#include "document.hxx"
+#include "externalrefmgr.hxx"
+
+#include "globstr.hrc"
+#include <sal/alloca.h>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/ExternalLinkInfo.hpp>
+#include <com/sun/star/sheet/ExternalLinkType.hpp>
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+using namespace ::com::sun::star;
+
+////////////////////////////////////////////////////////////////////////////
+const ScAddress::Details ScAddress::detailsOOOa1( formula::FormulaGrammar::CONV_OOO, 0, 0 );
+
+ScAddress::Details::Details ( const ScDocument* pDoc,
+ const ScAddress & rAddr ) :
+ eConv( pDoc->GetAddressConvention() ),
+ nRow( rAddr.Row() ),
+ nCol( rAddr.Col() )
+{
+}
+
+//UNUSED2009-05 void ScAddress::Details::SetPos ( const ScDocument* pDoc,
+//UNUSED2009-05 const ScAddress & rAddr )
+//UNUSED2009-05 {
+//UNUSED2009-05 nRow = rAddr.Row();
+//UNUSED2009-05 nCol = rAddr.Col();
+//UNUSED2009-05 eConv = pDoc->GetAddressConvention();
+//UNUSED2009-05 }
+
+////////////////////////////////////////////////////////////////////////////
+
+#include <iostream>
+
+/**
+ * Parse from the opening single quote to the closing single quote. Inside
+ * the quotes, a single quote character is encoded by double single-quote
+ * characters.
+ *
+ * @param p pointer to the first character to begin parsing.
+ * @param rName (reference) parsed name within the quotes. If the name is
+ * empty, either the parsing failed or it's an empty quote.
+ *
+ * @return pointer to the character immediately after the closing single
+ * quote.
+ */
+static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, String& rName )
+{
+ rName.Erase();
+ if (*p != '\'')
+ return p;
+
+ const sal_Unicode* pStart = p;
+ sal_Unicode cPrev = 0;
+ for (++p; *p; ++p)
+ {
+ if (*p == '\'')
+ {
+ if (cPrev == '\'')
+ {
+ // double single-quote equals one single quote.
+ rName += *p;
+ cPrev = 0;
+ continue;
+ }
+ }
+ else if (cPrev == '\'')
+ // We are past the closing quote. We're done!
+ return p;
+ else
+ rName += *p;
+ cPrev = *p;
+ }
+ rName.Erase();
+ return pStart;
+}
+
+static long int
+sal_Unicode_strtol ( const sal_Unicode* p,
+ const sal_Unicode** pEnd )
+{
+ long int accum = 0, prev = 0;
+ bool is_neg = false;
+
+ if( *p == '-' )
+ {
+ is_neg = true;
+ p++;
+ }
+ else if( *p == '+' )
+ p++;
+
+ while (CharClass::isAsciiDigit( *p ))
+ {
+ accum = accum * 10 + *p - '0';
+ if( accum < prev )
+ {
+ *pEnd = NULL;
+ return 0;
+ }
+ prev = accum;
+ p++;
+ }
+
+ *pEnd = p;
+ return is_neg ? -accum : accum;
+}
+
+const sal_Unicode* lcl_eatWhiteSpace( const sal_Unicode* p )
+{
+ if ( p )
+ {
+ while( *p == ' ' )
+ ++p;
+ }
+ return p;
+}
+
+/** Determines the number of sheets an external reference spans and sets
+ rRange.aEnd.nTab accordingly. If a sheet is not found, the corresponding
+ bits in rFlags are cleared. pExtInfo is filled if it wasn't already. If in
+ cached order rStartTabName comes after rEndTabName, pExtInfo->maTabName
+ is set to rEndTabName.
+ @returns <FALSE/> if pExtInfo is already filled and rExternDocName does not
+ result in the identical file ID. Else <TRUE/>.
+ */
+static bool lcl_ScRange_External_TabSpan(
+ ScRange & rRange,
+ USHORT & rFlags,
+ ScAddress::ExternalInfo* pExtInfo,
+ const String & rExternDocName,
+ const String & rStartTabName,
+ const String & rEndTabName,
+ ScDocument* pDoc )
+{
+ if (!rExternDocName.Len())
+ return !pExtInfo || !pExtInfo->mbExternal;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ if (pRefMgr->isOwnDocument( rExternDocName))
+ return !pExtInfo || !pExtInfo->mbExternal;
+
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId( rExternDocName);
+
+ if (pExtInfo)
+ {
+ if (pExtInfo->mbExternal)
+ {
+ if (pExtInfo->mnFileId != nFileId)
+ return false;
+ }
+ else
+ {
+ pExtInfo->mbExternal = true;
+ pExtInfo->maTabName = rStartTabName;
+ pExtInfo->mnFileId = nFileId;
+ }
+ }
+
+ if (!rEndTabName.Len() || rStartTabName == rEndTabName)
+ {
+ rRange.aEnd.SetTab( rRange.aStart.Tab());
+ return true;
+ }
+
+ SCsTAB nSpan = pRefMgr->getCachedTabSpan( nFileId, rStartTabName, rEndTabName);
+ if (nSpan == -1)
+ rFlags &= ~(SCA_VALID_TAB | SCA_VALID_TAB2);
+ else if (nSpan == 0)
+ rFlags &= ~SCA_VALID_TAB2;
+ else if (nSpan >= 1)
+ rRange.aEnd.SetTab( rRange.aStart.Tab() + nSpan - 1);
+ else // (nSpan < -1)
+ {
+ rRange.aEnd.SetTab( rRange.aStart.Tab() - nSpan - 1);
+ if (pExtInfo)
+ pExtInfo->maTabName = rEndTabName;
+ }
+ return true;
+}
+
+/** Returns NULL if the string should be a sheet name, but is invalid.
+ Returns a pointer to the first character after the sheet name, if there was
+ any, else pointer to start.
+ @param pMsoxlQuoteStop
+ Starting _within_ a quoted name, but still may be 3D; quoted name stops
+ at pMsoxlQuoteStop
+ */
+static const sal_Unicode *
+lcl_XL_ParseSheetRef( const sal_Unicode* start,
+ String& rExternTabName,
+ bool allow_3d,
+ const sal_Unicode* pMsoxlQuoteStop )
+{
+ String aTabName;
+ const sal_Unicode *p = start;
+
+ // XL only seems to use single quotes for sheet names.
+ if (pMsoxlQuoteStop)
+ {
+ const sal_Unicode* pCurrentStart = p;
+ while (p < pMsoxlQuoteStop)
+ {
+ if (*p == '\'')
+ {
+ // We pre-analyzed the quoting, no checks needed here.
+ if (*++p == '\'')
+ {
+ aTabName.Append( pCurrentStart,
+ sal::static_int_cast<xub_StrLen>( p - pCurrentStart));
+ pCurrentStart = ++p;
+ }
+ }
+ else if (*p == ':')
+ {
+ break; // while
+ }
+ else
+ ++p;
+ }
+ if (pCurrentStart < p)
+ aTabName.Append( pCurrentStart, sal::static_int_cast<xub_StrLen>( p - pCurrentStart));
+ if (!aTabName.Len())
+ return NULL;
+ if (p == pMsoxlQuoteStop)
+ ++p; // position on ! of ...'!...
+ if( *p != '!' && ( !allow_3d || *p != ':' ) )
+ return (!allow_3d && *p == ':') ? p : start;
+ }
+ else if( *p == '\'')
+ {
+ p = lcl_ParseQuotedName(p, aTabName);
+ if (!aTabName.Len())
+ return NULL;
+ }
+ else
+ {
+ bool only_digits = TRUE;
+
+ /*
+ * Valid: Normal!a1
+ * Valid: x.y!a1
+ * Invalid: .y!a1
+ *
+ * Some names starting with digits are actually valid, but
+ * unparse quoted. Things are quite tricky: most sheet names
+ * starting with a digit are ok, but not those starting with
+ * "[0-9]*\." or "[0-9]+[eE]".
+ *
+ * Valid: 42!a1
+ * Valid: 4x!a1
+ * Invalid: 1.!a1
+ * Invalid: 1e!a1
+ */
+ while( 1 )
+ {
+ const sal_Unicode uc = *p;
+ if( CharClass::isAsciiAlpha( uc ) || uc == '_' )
+ {
+ if( only_digits && p != start &&
+ (uc == 'e' || uc == 'E' ) )
+ {
+ p = start;
+ break;
+ }
+ only_digits = FALSE;
+ p++;
+ }
+ else if( CharClass::isAsciiDigit( uc ))
+ {
+ p++;
+ }
+ else if( uc == '.' )
+ {
+ if( only_digits ) // Valid, except after only digits.
+ {
+ p = start;
+ break;
+ }
+ p++;
+ }
+ else if (uc > 127)
+ {
+ // non ASCII character is allowed.
+ ++p;
+ }
+ else
+ break;
+ }
+
+ if( *p != '!' && ( !allow_3d || *p != ':' ) )
+ return (!allow_3d && *p == ':') ? p : start;
+
+ aTabName.Append( start, sal::static_int_cast<xub_StrLen>( p - start ) );
+ }
+
+ rExternTabName = aTabName;
+ return p;
+}
+
+
+const sal_Unicode* ScRange::Parse_XL_Header(
+ const sal_Unicode* p,
+ const ScDocument* pDoc,
+ String& rExternDocName,
+ String& rStartTabName,
+ String& rEndTabName,
+ USHORT& nFlags,
+ bool bOnlyAcceptSingle,
+ const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
+{
+ const sal_Unicode* startTabs, *start = p;
+ USHORT nSaveFlags = nFlags;
+
+ // Is this an external reference ?
+ rStartTabName.Erase();
+ rEndTabName.Erase();
+ rExternDocName.Erase();
+ const sal_Unicode* pMsoxlQuoteStop = NULL;
+ if (*p == '[')
+ {
+ ++p;
+ // Only single quotes are correct, and a double single quote escapes a
+ // single quote text inside the quoted text.
+ if (*p == '\'')
+ {
+ p = lcl_ParseQuotedName(p, rExternDocName);
+ if (!*p || *p != ']' || !rExternDocName.Len())
+ {
+ rExternDocName.Erase();
+ return start;
+ }
+ }
+ else
+ {
+ // non-quoted file name.
+ p = ScGlobal::UnicodeStrChr( start+1, ']' );
+ if( p == NULL )
+ return start;
+ rExternDocName.Append( start+1, sal::static_int_cast<xub_StrLen>( p-(start+1) ) );
+ }
+ ++p;
+
+ // 1-based, sequence starts with an empty element.
+ if (pExternalLinks && pExternalLinks->getLength() > 1)
+ {
+ // A numeric "document name" is an index into the sequence.
+ if (CharClass::isAsciiNumeric( rExternDocName))
+ {
+ sal_Int32 i = rExternDocName.ToInt32();
+ if (i <= 0 || i >= pExternalLinks->getLength())
+ return start;
+ const sheet::ExternalLinkInfo & rInfo = (*pExternalLinks)[i];
+ switch (rInfo.Type)
+ {
+ case sheet::ExternalLinkType::DOCUMENT :
+ {
+ rtl::OUString aStr;
+ if (!(rInfo.Data >>= aStr))
+ {
+ DBG_ERROR1( "ScRange::Parse_XL_Header: Data type mismatch for ExternalLinkInfo %d", i);
+ return NULL;
+ }
+ rExternDocName = aStr;
+ }
+ break;
+ default:
+ DBG_ERROR2( "ScRange::Parse_XL_Header: unhandled ExternalLinkType %d for index %d",
+ rInfo.Type, i);
+ return NULL;
+ }
+ }
+ }
+ rExternDocName = ScGlobal::GetAbsDocName(rExternDocName, pDoc->GetDocumentShell());
+ }
+ else if (*p == '\'')
+ {
+ // Sickness in Excel's ODF msoxl namespace:
+ // 'E:\[EXTDATA8.XLS]Sheet1'!$A$7 or
+ // 'E:\[EXTDATA12B.XLSB]Sheet1:Sheet3'!$A$11
+ // But, 'Sheet1'!B3 would also be a valid!
+ // Excel does not allow [ and ] characters in sheet names though.
+ p = lcl_ParseQuotedName(p, rExternDocName);
+ if (!*p || *p != '!')
+ {
+ rExternDocName.Erase();
+ return start;
+ }
+ if (rExternDocName.Len())
+ {
+ xub_StrLen nOpen = rExternDocName.Search( '[');
+ if (nOpen == STRING_NOTFOUND)
+ rExternDocName.Erase();
+ else
+ {
+ xub_StrLen nClose = rExternDocName.Search( ']', nOpen+1);
+ if (nClose == STRING_NOTFOUND)
+ rExternDocName.Erase();
+ else
+ {
+ rExternDocName.Erase( nClose);
+ rExternDocName.Erase( nOpen, 1);
+ pMsoxlQuoteStop = p - 1; // the ' quote char
+ // There may be embedded escaped quotes, just matching the
+ // doc name's length may not work.
+ for (p = start; *p != '['; ++p)
+ ;
+ for ( ; *p != ']'; ++p)
+ ;
+ ++p;
+ }
+ }
+ }
+ if (!rExternDocName.Len())
+ p = start;
+ }
+
+ startTabs = p;
+ p = lcl_XL_ParseSheetRef( p, rStartTabName, !bOnlyAcceptSingle, pMsoxlQuoteStop);
+ if( NULL == p )
+ return start; // invalid tab
+ if (bOnlyAcceptSingle && *p == ':')
+ return NULL; // 3D
+ if( p != startTabs )
+ {
+ nFlags |= SCA_VALID_TAB | SCA_TAB_3D | SCA_TAB_ABSOLUTE;
+ if( *p == ':' ) // 3d ref
+ {
+ p = lcl_XL_ParseSheetRef( p+1, rEndTabName, false, pMsoxlQuoteStop);
+ if( p == NULL )
+ {
+ nFlags = nSaveFlags;
+ return start; // invalid tab
+ }
+ nFlags |= SCA_VALID_TAB2 | SCA_TAB2_3D | SCA_TAB2_ABSOLUTE;
+ }
+ else
+ {
+ // If only one sheet is given, the full reference is still valid,
+ // only the second 3D flag is not set.
+ nFlags |= SCA_VALID_TAB2 | SCA_TAB2_ABSOLUTE;
+ aEnd.SetTab( aStart.Tab() );
+ }
+
+ if( *p++ != '!' )
+ {
+ nFlags = nSaveFlags;
+ return start; // syntax error
+ }
+ else
+ p = lcl_eatWhiteSpace( p );
+ }
+ else
+ {
+ nFlags |= SCA_VALID_TAB | SCA_VALID_TAB2;
+ // Use the current tab, it needs to be passed in. : aEnd.SetTab( .. );
+ }
+
+ if (rExternDocName.Len())
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pRefMgr->convertToAbsName( rExternDocName);
+ }
+ else
+ {
+ // Internal reference.
+ if (!rStartTabName.Len())
+ {
+ nFlags = nSaveFlags;
+ return start;
+ }
+
+ SCTAB nTab;
+ if (!pDoc->GetTable(rStartTabName, nTab))
+ {
+ // invalid table name.
+ nFlags &= ~SCA_VALID_TAB;
+ nTab = -1;
+ }
+
+ aStart.SetTab(nTab);
+ aEnd.SetTab(nTab);
+
+ if (rEndTabName.Len())
+ {
+ if (!pDoc->GetTable(rEndTabName, nTab))
+ {
+ // invalid table name.
+ nFlags &= ~SCA_VALID_TAB2;
+ nTab = -1;
+ }
+
+ aEnd.SetTab(nTab);
+ }
+ }
+ return p;
+}
+
+
+static const sal_Unicode*
+lcl_r1c1_get_col( const sal_Unicode* p,
+ const ScAddress::Details& rDetails,
+ ScAddress* pAddr, USHORT* nFlags )
+{
+ const sal_Unicode *pEnd;
+ long int n;
+ bool isRelative;
+
+ if( p[0] == '\0' )
+ return NULL;
+
+ p++;
+ if( (isRelative = (*p == '[') ) != false )
+ p++;
+ n = sal_Unicode_strtol( p, &pEnd );
+ if( NULL == pEnd )
+ return NULL;
+
+ if( p == pEnd ) // C is a relative ref with offset 0
+ {
+ if( isRelative )
+ return NULL;
+ n = rDetails.nCol;
+ }
+ else if( isRelative )
+ {
+ if( *pEnd != ']' )
+ return NULL;
+ n += rDetails.nCol;
+ pEnd++;
+ }
+ else
+ {
+ *nFlags |= SCA_COL_ABSOLUTE;
+ n--;
+ }
+
+ if( n < 0 || n >= MAXCOLCOUNT )
+ return NULL;
+ pAddr->SetCol( static_cast<SCCOL>( n ) );
+ *nFlags |= SCA_VALID_COL;
+
+ return pEnd;
+}
+static inline const sal_Unicode*
+lcl_r1c1_get_row( const sal_Unicode* p,
+ const ScAddress::Details& rDetails,
+ ScAddress* pAddr, USHORT* nFlags )
+{
+ const sal_Unicode *pEnd;
+ long int n;
+ bool isRelative;
+
+ if( p[0] == '\0' )
+ return NULL;
+
+ p++;
+ if( (isRelative = (*p == '[') ) != false )
+ p++;
+ n = sal_Unicode_strtol( p, &pEnd );
+ if( NULL == pEnd )
+ return NULL;
+
+ if( p == pEnd ) // R is a relative ref with offset 0
+ {
+ if( isRelative )
+ return NULL;
+ n = rDetails.nRow;
+ }
+ else if( isRelative )
+ {
+ if( *pEnd != ']' )
+ return NULL;
+ n += rDetails.nRow;
+ pEnd++;
+ }
+ else
+ {
+ *nFlags |= SCA_ROW_ABSOLUTE;
+ n--;
+ }
+
+ if( n < 0 || n >= MAXROWCOUNT )
+ return NULL;
+ pAddr->SetRow( static_cast<SCROW>( n ) );
+ *nFlags |= SCA_VALID_ROW;
+
+ return pEnd;
+}
+
+static USHORT
+lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+ const sal_Unicode* p,
+ ScDocument* pDoc,
+ const ScAddress::Details& rDetails,
+ bool bOnlyAcceptSingle,
+ ScAddress::ExternalInfo* pExtInfo )
+{
+ const sal_Unicode* pTmp = NULL;
+ String aExternDocName, aStartTabName, aEndTabName;
+ USHORT nFlags = SCA_VALID | SCA_VALID_TAB;
+ // Keep in mind that nFlags2 gets left-shifted by 4 bits before being merged.
+ USHORT nFlags2 = SCA_VALID_TAB;
+
+#if 0
+ {
+ ByteString aStr(p, RTL_TEXTENCODING_UTF8);
+ aStr.Append(static_cast< char >(0));
+ std::cerr << "parse::XL::R1C1 \'" << aStr.GetBuffer() << '\'' << std::endl;
+ }
+#endif
+ p = r.Parse_XL_Header( p, pDoc, aExternDocName, aStartTabName,
+ aEndTabName, nFlags, bOnlyAcceptSingle, NULL );
+
+ if (aExternDocName.Len() > 0)
+ lcl_ScRange_External_TabSpan( r, nFlags, pExtInfo, aExternDocName,
+ aStartTabName, aEndTabName, pDoc);
+
+ if( NULL == p )
+ return 0;
+
+ if( *p == 'R' || *p == 'r' )
+ {
+ if( NULL == (p = lcl_r1c1_get_row( p, rDetails, &r.aStart, &nFlags )) )
+ goto failed;
+
+ if( *p != 'C' && *p != 'c' ) // full row R#
+ {
+ if( p[0] != ':' || (p[1] != 'R' && p[1] != 'r' ) ||
+ NULL == (pTmp = lcl_r1c1_get_row( p+1, rDetails, &r.aEnd, &nFlags2 )))
+ {
+ // Only the initial row number is given, or the second row
+ // number is invalid. Fallback to just the initial R
+ nFlags |= (nFlags << 4);
+ r.aEnd.SetRow( r.aStart.Row() );
+ }
+ else
+ {
+ // Full row range successfully parsed.
+ nFlags |= (nFlags2 << 4);
+ p = pTmp;
+ }
+
+ if (p && p[0] != 0)
+ {
+ // any trailing invalid character must invalidate the whole address.
+ nFlags &= ~(SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB |
+ SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2);
+ return nFlags;
+ }
+
+ nFlags |=
+ SCA_VALID_COL | SCA_VALID_COL2 |
+ SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE;
+ r.aStart.SetCol( 0 );
+ r.aEnd.SetCol( MAXCOL );
+
+ return bOnlyAcceptSingle ? 0 : nFlags;
+ }
+ else if( NULL == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags )))
+ goto failed;
+
+ if( p[0] != ':' ||
+ (p[1] != 'R' && p[1] != 'r') ||
+ NULL == (pTmp = lcl_r1c1_get_row( p+1, rDetails, &r.aEnd, &nFlags2 )) ||
+ (*pTmp != 'C' && *pTmp != 'c') ||
+ NULL == (pTmp = lcl_r1c1_get_col( pTmp, rDetails, &r.aEnd, &nFlags2 )))
+ {
+ // single cell reference
+
+ if (p && p[0] != 0)
+ {
+ // any trailing invalid character must invalidate the whole address.
+ nFlags &= ~(SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB);
+ return nFlags;
+ }
+
+ return bOnlyAcceptSingle ? nFlags : 0;
+ }
+ p = pTmp;
+
+ // double reference
+
+ if (p && p[0] != 0)
+ {
+ // any trailing invalid character must invalidate the whole range.
+ nFlags &= ~(SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB |
+ SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2);
+ return nFlags;
+ }
+
+ nFlags |= (nFlags2 << 4);
+ return bOnlyAcceptSingle ? 0 : nFlags;
+ }
+ else if( *p == 'C' || *p == 'c' ) // full col C#
+ {
+ if( NULL == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags )))
+ goto failed;
+
+ if( p[0] != ':' || (p[1] != 'C' && p[1] != 'c') ||
+ NULL == (pTmp = lcl_r1c1_get_col( p+1, rDetails, &r.aEnd, &nFlags2 )))
+ { // Fallback to just the initial C
+ nFlags |= (nFlags << 4);
+ r.aEnd.SetCol( r.aStart.Col() );
+ }
+ else
+ {
+ nFlags |= (nFlags2 << 4);
+ p = pTmp;
+ }
+
+ if (p && p[0] != 0)
+ {
+ // any trailing invalid character must invalidate the whole address.
+ nFlags &= ~(SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB |
+ SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2);
+ return nFlags;
+ }
+
+ nFlags |=
+ SCA_VALID_ROW | SCA_VALID_ROW2 |
+ SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE;
+ r.aStart.SetRow( 0 );
+ r.aEnd.SetRow( MAXROW );
+
+ return bOnlyAcceptSingle ? 0 : nFlags;
+ }
+
+failed :
+ return 0;
+}
+
+static inline const sal_Unicode*
+lcl_a1_get_col( const sal_Unicode* p, ScAddress* pAddr, USHORT* nFlags )
+{
+ SCCOL nCol;
+
+ if( *p == '$' )
+ *nFlags |= SCA_COL_ABSOLUTE, p++;
+
+ if( !CharClass::isAsciiAlpha( *p ) )
+ return NULL;
+
+ nCol = sal::static_int_cast<SCCOL>( toupper( char(*p++) ) - 'A' );
+ while (nCol <= MAXCOL && CharClass::isAsciiAlpha(*p))
+ nCol = sal::static_int_cast<SCCOL>( ((nCol + 1) * 26) + toupper( char(*p++) ) - 'A' );
+ if( nCol > MAXCOL || CharClass::isAsciiAlpha( *p ) )
+ return NULL;
+
+ *nFlags |= SCA_VALID_COL;
+ pAddr->SetCol( nCol );
+
+ return p;
+}
+
+static inline const sal_Unicode*
+lcl_a1_get_row( const sal_Unicode* p, ScAddress* pAddr, USHORT* nFlags )
+{
+ const sal_Unicode *pEnd;
+ long int n;
+
+ if( *p == '$' )
+ *nFlags |= SCA_ROW_ABSOLUTE, p++;
+
+ n = sal_Unicode_strtol( p, &pEnd ) - 1;
+ if( NULL == pEnd || p == pEnd || n < 0 || n > MAXROW )
+ return NULL;
+
+ *nFlags |= SCA_VALID_ROW;
+ pAddr->SetRow( static_cast<SCROW>(n) );
+
+ return pEnd;
+}
+
+static USHORT
+lcl_ScRange_Parse_XL_A1( ScRange& r,
+ const sal_Unicode* p,
+ ScDocument* pDoc,
+ bool bOnlyAcceptSingle,
+ ScAddress::ExternalInfo* pExtInfo,
+ const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
+{
+ const sal_Unicode* tmp1, *tmp2;
+ String aExternDocName, aStartTabName, aEndTabName; // for external link table
+ USHORT nFlags = SCA_VALID | SCA_VALID_TAB, nFlags2 = SCA_VALID_TAB;
+
+#if 0
+ {
+ ByteString aStr(p, RTL_TEXTENCODING_UTF8);
+ aStr.Append(static_cast< char >(0));
+ std::cerr << "parse::XL::A1 \'" << aStr.GetBuffer() << '\'' << std::endl;
+ }
+#endif
+ p = r.Parse_XL_Header( p, pDoc, aExternDocName, aStartTabName,
+ aEndTabName, nFlags, bOnlyAcceptSingle, pExternalLinks );
+
+ if (aExternDocName.Len() > 0)
+ lcl_ScRange_External_TabSpan( r, nFlags, pExtInfo, aExternDocName,
+ aStartTabName, aEndTabName, pDoc);
+
+ if( NULL == p )
+ return 0;
+
+ tmp1 = lcl_a1_get_col( p, &r.aStart, &nFlags );
+ if( tmp1 == NULL ) // Is it a row only reference 3:5
+ {
+ if( bOnlyAcceptSingle ) // by definition full row refs are ranges
+ return 0;
+
+ tmp1 = lcl_a1_get_row( p, &r.aStart, &nFlags );
+
+ tmp1 = lcl_eatWhiteSpace( tmp1 );
+ if( !tmp1 || *tmp1++ != ':' ) // Even a singleton requires ':' (eg 2:2)
+ return 0;
+
+ tmp1 = lcl_eatWhiteSpace( tmp1 );
+ tmp2 = lcl_a1_get_row( tmp1, &r.aEnd, &nFlags2 );
+ if( !tmp2 )
+ return 0;
+
+ r.aStart.SetCol( 0 ); r.aEnd.SetCol( MAXCOL );
+ nFlags |=
+ SCA_VALID_COL | SCA_VALID_COL2 |
+ SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE;
+ nFlags |= (nFlags2 << 4);
+ return nFlags;
+ }
+
+ tmp2 = lcl_a1_get_row( tmp1, &r.aStart, &nFlags );
+ if( tmp2 == NULL ) // check for col only reference F:H
+ {
+ if( bOnlyAcceptSingle ) // by definition full col refs are ranges
+ return 0;
+
+ tmp1 = lcl_eatWhiteSpace( tmp1 );
+ if( *tmp1++ != ':' ) // Even a singleton requires ':' (eg F:F)
+ return 0;
+
+ tmp1 = lcl_eatWhiteSpace( tmp1 );
+ tmp2 = lcl_a1_get_col( tmp1, &r.aEnd, &nFlags2 );
+ if( !tmp2 )
+ return 0;
+
+ r.aStart.SetRow( 0 ); r.aEnd.SetRow( MAXROW );
+ nFlags |=
+ SCA_VALID_ROW | SCA_VALID_ROW2 |
+ SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE;
+ nFlags |= (nFlags2 << 4);
+ return nFlags;
+ }
+
+ // prepare as if it's a singleton, in case we want to fall back */
+ r.aEnd.SetCol( r.aStart.Col() );
+ r.aEnd.SetRow( r.aStart.Row() ); // don't overwrite sheet number as parsed in Parse_XL_Header()
+
+ if ( bOnlyAcceptSingle )
+ {
+ if ( *tmp2 == 0 )
+ return nFlags;
+ else
+ {
+ // any trailing invalid character must invalidate the address.
+ nFlags &= ~(SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB);
+ return nFlags;
+ }
+ }
+
+ tmp2 = lcl_eatWhiteSpace( tmp2 );
+ if( *tmp2 != ':' )
+ {
+ // Sheet1:Sheet2!C4 is a valid range, without a second sheet it is
+ // not. Any trailing invalid character invalidates the range.
+ if (*tmp2 == 0 && (nFlags & SCA_TAB2_3D))
+ {
+ if (nFlags & SCA_COL_ABSOLUTE)
+ nFlags |= SCA_COL2_ABSOLUTE;
+ if (nFlags & SCA_ROW_ABSOLUTE)
+ nFlags |= SCA_ROW2_ABSOLUTE;
+ }
+ else
+ nFlags &= ~(SCA_VALID |
+ SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB |
+ SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2);
+ return nFlags;
+ }
+
+ p = tmp2;
+ p = lcl_eatWhiteSpace( p+1 );
+ tmp1 = lcl_a1_get_col( p, &r.aEnd, &nFlags2 );
+ if( !tmp1 ) // strange, but valid singleton
+ return nFlags;
+
+ tmp2 = lcl_a1_get_row( tmp1, &r.aEnd, &nFlags2 );
+ if( !tmp2 ) // strange, but valid singleton
+ return nFlags;
+
+ if ( *tmp2 != 0 )
+ {
+ // any trailing invalid character must invalidate the range.
+ nFlags &= ~(SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW | SCA_VALID_TAB |
+ SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2);
+ return nFlags;
+ }
+
+ nFlags |= (nFlags2 << 4);
+ return nFlags;
+}
+
+/**
+ @param pRange pointer to range where rAddr effectively is *pRange->aEnd,
+ used in conjunction with pExtInfo to determine the tab span
+ of a 3D reference.
+ */
+static USHORT
+lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
+ ScAddress::ExternalInfo* pExtInfo = NULL, ScRange* pRange = NULL )
+{
+ USHORT nRes = 0;
+ String aDocName; // der pure Dokumentenname
+ String aTab;
+ bool bExtDoc = false;
+ bool bExtDocInherited = false;
+ const ScAddress aCurPos(rAddr);
+
+ // Lets see if this is a reference to something in an external file. A
+ // document name is always quoted and has a trailing #.
+ if (*p == '\'')
+ {
+ const sal_Unicode* pStart = p;
+ p = lcl_ParseQuotedName(p, aDocName);
+ if (*p++ == SC_COMPILER_FILE_TAB_SEP)
+ bExtDoc = true;
+ else
+ // This is not a document name. Perhaps a quoted relative table
+ // name.
+ p = pStart;
+ }
+ else if (pExtInfo && pExtInfo->mbExternal)
+ {
+ // This is an external reference.
+ bExtDoc = bExtDocInherited = true;
+ }
+
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+ SCTAB nTab = 0;
+ USHORT nBits = SCA_VALID_TAB;
+ const sal_Unicode* q;
+ if ( ScGlobal::FindUnquoted( p, '.') )
+ {
+ nRes |= SCA_TAB_3D;
+ if ( bExtDoc )
+ nRes |= SCA_TAB_ABSOLUTE;
+ if (*p == '$')
+ nRes |= SCA_TAB_ABSOLUTE, p++;
+
+ if (*p == '\'')
+ {
+ // Tokens that start at ' can have anything in them until a final
+ // ' but '' marks an escaped '. We've earlier guaranteed that a
+ // string containing '' will be surrounded by '.
+ p = lcl_ParseQuotedName(p, aTab);
+ }
+ else
+ {
+ while (*p)
+ {
+ if( *p == '.')
+ break;
+
+ if( *p == '\'' )
+ {
+ p++; break;
+ }
+ aTab += *p++;
+ }
+ }
+ if( *p++ != '.' )
+ nBits = 0;
+
+ if (!bExtDoc && (!pDoc || !pDoc->GetTable( aTab, nTab )))
+ nBits = 0;
+ }
+ else
+ {
+ if (bExtDoc && !bExtDocInherited)
+ return nRes; // After a document a sheet must follow.
+ nTab = rAddr.Tab();
+ }
+ nRes |= nBits;
+
+ q = p;
+ if (*p)
+ {
+ nBits = SCA_VALID_COL;
+ if (*p == '$')
+ nBits |= SCA_COL_ABSOLUTE, p++;
+
+ if (CharClass::isAsciiAlpha( *p ))
+ {
+ nCol = sal::static_int_cast<SCCOL>( toupper( char(*p++) ) - 'A' );
+ while (nCol < MAXCOL && CharClass::isAsciiAlpha(*p))
+ nCol = sal::static_int_cast<SCCOL>( ((nCol + 1) * 26) + toupper( char(*p++) ) - 'A' );
+ }
+ else
+ nBits = 0;
+
+ if( nCol > MAXCOL || CharClass::isAsciiAlpha( *p ) )
+ nBits = 0;
+ nRes |= nBits;
+ if( !nBits )
+ p = q;
+ }
+
+ q = p;
+ if (*p)
+ {
+ nBits = SCA_VALID_ROW;
+ if (*p == '$')
+ nBits |= SCA_ROW_ABSOLUTE, p++;
+ if( !CharClass::isAsciiDigit( *p ) )
+ {
+ nBits = 0;
+ nRow = SCROW(-1);
+ }
+ else
+ {
+ String aTmp( p );
+ long n = aTmp.ToInt32() - 1;
+ while (CharClass::isAsciiDigit( *p ))
+ p++;
+ if( n < 0 || n > MAXROW )
+ nBits = 0;
+ nRow = static_cast<SCROW>(n);
+ }
+ nRes |= nBits;
+ if( !nBits )
+ p = q;
+ }
+
+ rAddr.Set( nCol, nRow, nTab );
+
+ if (!*p && bExtDoc)
+ {
+ if (!pDoc)
+ nRes = 0;
+ else
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+
+ // Need document name if inherited.
+ if (bExtDocInherited)
+ {
+ const String* pFileName = pRefMgr->getExternalFileName( pExtInfo->mnFileId);
+ if (pFileName)
+ aDocName = *pFileName;
+ else
+ nRes = 0;
+ }
+ pRefMgr->convertToAbsName(aDocName);
+
+ if ((!pExtInfo || !pExtInfo->mbExternal) && pRefMgr->isOwnDocument(aDocName))
+ {
+ if (!pDoc->GetTable( aTab, nTab ))
+ nRes = 0;
+ else
+ {
+ rAddr.SetTab( nTab);
+ nRes |= SCA_VALID_TAB;
+ }
+ }
+ else
+ {
+ if (!pExtInfo)
+ nRes = 0;
+ else
+ {
+ if (!pExtInfo->mbExternal)
+ {
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aDocName);
+
+ pExtInfo->mbExternal = true;
+ pExtInfo->maTabName = aTab;
+ pExtInfo->mnFileId = nFileId;
+
+ if (pRefMgr->getSingleRefToken(nFileId, aTab,
+ ScAddress(nCol, nRow, 0), NULL,
+ &nTab).get())
+ {
+ rAddr.SetTab( nTab);
+ nRes |= SCA_VALID_TAB;
+ }
+ else
+ nRes = 0;
+ }
+ else
+ {
+ // This is a call for the second part of the reference,
+ // we must have the range to adapt tab span.
+ if (!pRange)
+ nRes = 0;
+ else
+ {
+ USHORT nFlags = nRes | SCA_VALID_TAB2;
+ if (!lcl_ScRange_External_TabSpan( *pRange, nFlags,
+ pExtInfo, aDocName,
+ pExtInfo->maTabName, aTab, pDoc))
+ nRes &= ~SCA_VALID_TAB;
+ else
+ {
+ if (nFlags & SCA_VALID_TAB2)
+ {
+ rAddr.SetTab( pRange->aEnd.Tab());
+ nRes |= SCA_VALID_TAB;
+ }
+ else
+ nRes &= ~SCA_VALID_TAB;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( !(nRes & SCA_VALID_ROW) && (nRes & SCA_VALID_COL)
+ && !( (nRes & SCA_TAB_3D) && (nRes & SCA_VALID_TAB)) )
+ { // no Row, no Tab, but Col => DM (...), B (...) et al
+ nRes = 0;
+ }
+ if( !*p )
+ {
+ USHORT nMask = nRes & ( SCA_VALID_ROW | SCA_VALID_COL | SCA_VALID_TAB );
+ if( nMask == ( SCA_VALID_ROW | SCA_VALID_COL | SCA_VALID_TAB ) )
+ nRes |= SCA_VALID;
+ }
+ else
+ nRes = 0;
+ return nRes;
+}
+
+static USHORT
+lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
+ const ScAddress::Details& rDetails,
+ ScAddress::ExternalInfo* pExtInfo = NULL,
+ const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks = NULL )
+{
+ if( !*p )
+ return 0;
+
+ switch (rDetails.eConv)
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO:
+ {
+ return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, pExtInfo, NULL );
+ }
+
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ {
+ ScRange r = rAddr;
+ USHORT nFlags = lcl_ScRange_Parse_XL_A1( r, p, pDoc, true, pExtInfo,
+ (rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : NULL) );
+ rAddr = r.aStart;
+ return nFlags;
+ }
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ {
+ ScRange r = rAddr;
+ USHORT nFlags = lcl_ScRange_Parse_XL_R1C1( r, p, pDoc, rDetails, true, pExtInfo );
+ rAddr = r.aStart;
+ return nFlags;
+ }
+ }
+}
+
+
+bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
+ SCTAB nDefTab, ScRefAddress& rRefAddress,
+ const ScAddress::Details& rDetails,
+ ScAddress::ExternalInfo* pExtInfo /* = NULL */ )
+{
+ bool bRet = false;
+ if (pExtInfo || (ScGlobal::FindUnquoted( rRefString, SC_COMPILER_FILE_TAB_SEP) == STRING_NOTFOUND))
+ {
+ 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;
+ }
+ }
+ return bRet;
+}
+
+
+bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab,
+ ScRefAddress& rStartRefAddress, ScRefAddress& rEndRefAddress,
+ const ScAddress::Details& rDetails,
+ ScAddress::ExternalInfo* pExtInfo /* = NULL */ )
+{
+ bool bRet = false;
+ if (pExtInfo || (ScGlobal::FindUnquoted( rRefString, SC_COMPILER_FILE_TAB_SEP) == STRING_NOTFOUND))
+ {
+ ScRange aRange( ScAddress( 0, 0, nDefTab));
+ USHORT nRes = aRange.Parse( rRefString, pDoc, rDetails, pExtInfo);
+ if ( nRes & SCA_VALID )
+ {
+ 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;
+}
+
+
+USHORT ScAddress::Parse( const String& r, ScDocument* pDoc,
+ const Details& rDetails,
+ ExternalInfo* pExtInfo,
+ const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
+{
+ return lcl_ScAddress_Parse( r.GetBuffer(), pDoc, *this, rDetails, pExtInfo, pExternalLinks );
+}
+
+
+bool ScRange::Intersects( const ScRange& r ) const
+{
+ return !(
+ Min( aEnd.Col(), r.aEnd.Col() ) < Max( aStart.Col(), r.aStart.Col() )
+ || Min( aEnd.Row(), r.aEnd.Row() ) < Max( aStart.Row(), r.aStart.Row() )
+ || Min( aEnd.Tab(), r.aEnd.Tab() ) < Max( aStart.Tab(), r.aStart.Tab() )
+ );
+}
+
+
+void ScRange::Justify()
+{
+ SCCOL nTempCol;
+ if ( aEnd.Col() < (nTempCol = aStart.Col()) )
+ {
+ aStart.SetCol(aEnd.Col()); aEnd.SetCol(nTempCol);
+ }
+ SCROW nTempRow;
+ if ( aEnd.Row() < (nTempRow = aStart.Row()) )
+ {
+ aStart.SetRow(aEnd.Row()); aEnd.SetRow(nTempRow);
+ }
+ SCTAB nTempTab;
+ if ( aEnd.Tab() < (nTempTab = aStart.Tab()) )
+ {
+ aStart.SetTab(aEnd.Tab()); aEnd.SetTab(nTempTab);
+ }
+}
+
+void ScRange::ExtendTo( const ScRange& rRange )
+{
+ DBG_ASSERT( rRange.IsValid(), "ScRange::ExtendTo - cannot extend to invalid range" );
+ if( IsValid() )
+ {
+ aStart.SetCol( ::std::min( aStart.Col(), rRange.aStart.Col() ) );
+ aStart.SetRow( ::std::min( aStart.Row(), rRange.aStart.Row() ) );
+ aStart.SetTab( ::std::min( aStart.Tab(), rRange.aStart.Tab() ) );
+ aEnd.SetCol( ::std::max( aEnd.Col(), rRange.aEnd.Col() ) );
+ aEnd.SetRow( ::std::max( aEnd.Row(), rRange.aEnd.Row() ) );
+ aEnd.SetTab( ::std::max( aEnd.Tab(), rRange.aEnd.Tab() ) );
+ }
+ else
+ *this = rRange;
+}
+
+static USHORT
+lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc, ScAddress::ExternalInfo* pExtInfo = NULL )
+{
+ USHORT nRes1 = 0, nRes2 = 0;
+ xub_StrLen nPos = ScGlobal::FindUnquoted( r, ':');
+ if (nPos != STRING_NOTFOUND)
+ {
+ String aTmp( r );
+ sal_Unicode* p = aTmp.GetBufferAccess();
+ p[ nPos ] = 0;
+ if( (nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, aRange.aStart, pExtInfo, NULL ) ) != 0 )
+ {
+ aRange.aEnd = aRange.aStart; // sheet must be initialized identical to first sheet
+ if ( (nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, aRange.aEnd, pExtInfo, &aRange ) ) != 0 )
+ {
+ // PutInOrder / Justify
+ USHORT nMask, nBits1, nBits2;
+ SCCOL nTempCol;
+ if ( aRange.aEnd.Col() < (nTempCol = aRange.aStart.Col()) )
+ {
+ aRange.aStart.SetCol(aRange.aEnd.Col()); aRange.aEnd.SetCol(nTempCol);
+ nMask = (SCA_VALID_COL | SCA_COL_ABSOLUTE);
+ nBits1 = nRes1 & nMask;
+ nBits2 = nRes2 & nMask;
+ nRes1 = (nRes1 & ~nMask) | nBits2;
+ nRes2 = (nRes2 & ~nMask) | nBits1;
+ }
+ SCROW nTempRow;
+ if ( aRange.aEnd.Row() < (nTempRow = aRange.aStart.Row()) )
+ {
+ aRange.aStart.SetRow(aRange.aEnd.Row()); aRange.aEnd.SetRow(nTempRow);
+ nMask = (SCA_VALID_ROW | SCA_ROW_ABSOLUTE);
+ nBits1 = nRes1 & nMask;
+ nBits2 = nRes2 & nMask;
+ nRes1 = (nRes1 & ~nMask) | nBits2;
+ nRes2 = (nRes2 & ~nMask) | nBits1;
+ }
+ SCTAB nTempTab;
+ if ( aRange.aEnd.Tab() < (nTempTab = aRange.aStart.Tab()) )
+ {
+ aRange.aStart.SetTab(aRange.aEnd.Tab()); aRange.aEnd.SetTab(nTempTab);
+ nMask = (SCA_VALID_TAB | SCA_TAB_ABSOLUTE | SCA_TAB_3D);
+ nBits1 = nRes1 & nMask;
+ nBits2 = nRes2 & nMask;
+ nRes1 = (nRes1 & ~nMask) | nBits2;
+ nRes2 = (nRes2 & ~nMask) | nBits1;
+ }
+ if ( ((nRes1 & ( SCA_TAB_ABSOLUTE | SCA_TAB_3D ))
+ == ( SCA_TAB_ABSOLUTE | SCA_TAB_3D ))
+ && !(nRes2 & SCA_TAB_3D) )
+ nRes2 |= SCA_TAB_ABSOLUTE;
+ }
+ else
+ nRes1 = 0; // #38840# keine Tokens aus halben Sachen
+ }
+ }
+ nRes1 = ( ( nRes1 | nRes2 ) & SCA_VALID )
+ | nRes1
+ | ( ( nRes2 & 0x070F ) << 4 );
+ return nRes1;
+}
+
+USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
+ const ScAddress::Details& rDetails,
+ ScAddress::ExternalInfo* pExtInfo,
+ const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
+{
+ if ( r.Len() <= 0 )
+ return 0;
+
+ switch (rDetails.eConv)
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO:
+ return lcl_ScRange_Parse_OOo( *this, r, pDoc, pExtInfo );
+
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ return lcl_ScRange_Parse_XL_A1( *this, r.GetBuffer(), pDoc, false, pExtInfo,
+ (rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : NULL) );
+
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ return lcl_ScRange_Parse_XL_R1C1( *this, r.GetBuffer(), pDoc, rDetails, false, pExtInfo );
+ }
+}
+
+
+// Accept a full range, or an address
+USHORT ScRange::ParseAny( const String& r, ScDocument* pDoc,
+ const ScAddress::Details& rDetails )
+{
+ USHORT nRet = Parse( r, pDoc, rDetails );
+ const USHORT nValid = SCA_VALID | SCA_VALID_COL2 | SCA_VALID_ROW2 |
+ SCA_VALID_TAB2;
+
+ if ( (nRet & nValid) != nValid )
+ {
+ ScAddress aAdr;
+ nRet = aAdr.Parse( r, pDoc, rDetails );
+ if ( nRet & SCA_VALID )
+ aStart = aEnd = aAdr;
+ }
+ return nRet;
+}
+
+// Parse only full row references
+USHORT ScRange::ParseCols( const String& rStr, ScDocument* pDoc,
+ const ScAddress::Details& rDetails )
+{
+ const sal_Unicode* p = rStr.GetBuffer();
+ USHORT nRes = 0, ignored = 0;
+
+ if( NULL == p )
+ return 0;
+
+ pDoc = NULL; // make compiler shutup we may need this later
+
+ switch (rDetails.eConv)
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO: // No full col refs in OOO yet, assume XL notation
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ if (NULL != (p = lcl_a1_get_col( p, &aStart, &ignored ) ) )
+ {
+ if( p[0] == ':')
+ {
+ if( NULL != (p = lcl_a1_get_col( p+1, &aEnd, &ignored )))
+ {
+ nRes = SCA_VALID_COL;
+ }
+ }
+ else
+ {
+ aEnd = aStart;
+ nRes = SCA_VALID_COL;
+ }
+ }
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ if ((p[0] == 'C' || p[0] != 'c') &&
+ NULL != (p = lcl_r1c1_get_col( p, rDetails, &aStart, &ignored )))
+ {
+ if( p[0] == ':')
+ {
+ if( (p[1] == 'C' || p[1] == 'c') &&
+ NULL != (p = lcl_r1c1_get_col( p+1, rDetails, &aEnd, &ignored )))
+ {
+ nRes = SCA_VALID_COL;
+ }
+ }
+ else
+ {
+ aEnd = aStart;
+ nRes = SCA_VALID_COL;
+ }
+ }
+ break;
+ }
+
+ return (p != NULL && *p == '\0') ? nRes : 0;
+}
+
+// Parse only full row references
+USHORT ScRange::ParseRows( const String& rStr, ScDocument* pDoc,
+ const ScAddress::Details& rDetails )
+{
+ const sal_Unicode* p = rStr.GetBuffer();
+ USHORT nRes = 0, ignored = 0;
+
+ if( NULL == p )
+ return 0;
+
+ pDoc = NULL; // make compiler shutup we may need this later
+
+ switch (rDetails.eConv)
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO: // No full row refs in OOO yet, assume XL notation
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ if (NULL != (p = lcl_a1_get_row( p, &aStart, &ignored ) ) )
+ {
+ if( p[0] == ':')
+ {
+ if( NULL != (p = lcl_a1_get_row( p+1, &aEnd, &ignored )))
+ {
+ nRes = SCA_VALID_COL;
+ }
+ }
+ else
+ {
+ aEnd = aStart;
+ nRes = SCA_VALID_COL;
+ }
+ }
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ if ((p[0] == 'R' || p[0] != 'r') &&
+ NULL != (p = lcl_r1c1_get_row( p, rDetails, &aStart, &ignored )))
+ {
+ if( p[0] == ':')
+ {
+ if( (p[1] == 'R' || p[1] == 'r') &&
+ NULL != (p = lcl_r1c1_get_row( p+1, rDetails, &aEnd, &ignored )))
+ {
+ nRes = SCA_VALID_COL;
+ }
+ }
+ else
+ {
+ aEnd = aStart;
+ nRes = SCA_VALID_COL;
+ }
+ }
+ break;
+ }
+
+ return (p != NULL && *p == '\0') ? nRes : 0;
+}
+
+static inline void
+lcl_a1_append_c ( String &r, int nCol, bool bIsAbs )
+{
+ if( bIsAbs )
+ r += '$';
+ ScColToAlpha( r, sal::static_int_cast<SCCOL>(nCol) );
+}
+
+static inline void
+lcl_a1_append_r ( String &r, int nRow, bool bIsAbs )
+{
+ if ( bIsAbs )
+ r += '$';
+ r += String::CreateFromInt32( nRow+1 );
+}
+
+static inline void
+lcl_r1c1_append_c ( String &r, int nCol, bool bIsAbs,
+ const ScAddress::Details& rDetails )
+{
+ r += 'C';
+ if (bIsAbs)
+ {
+ r += String::CreateFromInt32( nCol + 1 );
+ }
+ else
+ {
+ nCol -= rDetails.nCol;
+ if (nCol != 0) {
+ r += '[';
+ r += String::CreateFromInt32( nCol );
+ r += ']';
+ }
+ }
+}
+static inline void
+lcl_r1c1_append_r ( String &r, int nRow, bool bIsAbs,
+ const ScAddress::Details& rDetails )
+{
+ r += 'R';
+ if (bIsAbs)
+ {
+ r += String::CreateFromInt32( nRow + 1 );
+ }
+ else
+ {
+ nRow -= rDetails.nRow;
+ if (nRow != 0) {
+ r += '[';
+ r += String::CreateFromInt32( nRow );
+ r += ']';
+ }
+ }
+}
+
+static String
+getFileNameFromDoc( const ScDocument* pDoc )
+{
+ // TODO : er points at ScGlobal::GetAbsDocName()
+ // as a better template. Look into it
+ String sFileName;
+ SfxObjectShell* pShell;
+
+ if( NULL != pDoc &&
+ NULL != (pShell = pDoc->GetDocumentShell() ) )
+ {
+ uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY );
+ if( xModel.is() )
+ {
+ if( xModel->getURL().getLength() )
+ {
+ INetURLObject aURL( xModel->getURL() );
+ sFileName = aURL.GetLastName();
+ }
+ else
+ sFileName = pShell->GetTitle();
+ }
+ }
+#if 0
+ {
+ ByteString aStr( sFileName, RTL_TEXTENCODING_UTF8 );
+ aStr.Append(static_cast< char >(0));
+ std::cerr << "docname \'" << aStr.GetBuffer() << '\'' << std::endl;
+ }
+#endif
+ return sFileName;
+}
+
+void ScAddress::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+ const Details& rDetails) const
+{
+ r.Erase();
+ if( nFlags & SCA_VALID )
+ nFlags |= ( SCA_VALID_ROW | SCA_VALID_COL | SCA_VALID_TAB );
+ if( pDoc && (nFlags & SCA_VALID_TAB ) )
+ {
+ if ( nTab >= pDoc->GetTableCount() )
+ {
+ r = ScGlobal::GetRscString( STR_NOREF_STR );
+ return;
+ }
+// if( nFlags & ( SCA_TAB_ABSOLUTE | SCA_TAB_3D ) )
+ if( nFlags & SCA_TAB_3D )
+ {
+ String aTabName, aDocName;
+ pDoc->GetName( nTab, aTabName );
+ // External Reference, same as in ScCompiler::MakeTabStr()
+ if( aTabName.GetChar(0) == '\'' )
+ { // "'Doc'#Tab"
+ xub_StrLen nPos = ScGlobal::FindUnquoted( aTabName, SC_COMPILER_FILE_TAB_SEP);
+ if (nPos != STRING_NOTFOUND && nPos > 0 && aTabName.GetChar(nPos-1) == '\'')
+ {
+ aDocName = aTabName.Copy( 0, nPos + 1 );
+ aTabName.Erase( 0, nPos + 1 );
+ }
+ }
+ else if( nFlags & SCA_FORCE_DOC )
+ {
+ // VBA has an 'external' flag that forces the addition of the
+ // tab name _and_ the doc name. The VBA code would be
+ // needlessly complicated if it constructed an actual external
+ // reference so we add this somewhat cheesy kludge to force the
+ // addition of the document name even for non-external references
+ aDocName = getFileNameFromDoc( pDoc );
+ }
+ ScCompiler::CheckTabQuotes( aTabName, rDetails.eConv);
+
+ switch( rDetails.eConv )
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO:
+ r += aDocName;
+ if( nFlags & SCA_TAB_ABSOLUTE )
+ r += '$';
+ r += aTabName;
+ r += '.';
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ if (aDocName.Len() > 0)
+ {
+ r += '[';
+ r += aDocName;
+ r += ']';
+ }
+ r += aTabName;
+ r += '!';
+ break;
+ }
+ }
+ }
+ switch( rDetails.eConv )
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO:
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ if( nFlags & SCA_VALID_COL )
+ lcl_a1_append_c ( r, nCol, nFlags & SCA_COL_ABSOLUTE );
+ if( nFlags & SCA_VALID_ROW )
+ lcl_a1_append_r ( r, nRow, nFlags & SCA_ROW_ABSOLUTE );
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ if( nFlags & SCA_VALID_ROW )
+ lcl_r1c1_append_r ( r, nRow, nFlags & SCA_ROW_ABSOLUTE, rDetails );
+ if( nFlags & SCA_VALID_COL )
+ lcl_r1c1_append_c ( r, nCol, nFlags & SCA_COL_ABSOLUTE, rDetails );
+ break;
+ }
+}
+
+static void
+lcl_Split_DocTab( const ScDocument* pDoc, SCTAB nTab,
+ const ScAddress::Details& rDetails,
+ USHORT nFlags,
+ String& rTabName, String& rDocName )
+{
+ pDoc->GetName( nTab, rTabName );
+ rDocName.Erase();
+#if 0
+ {
+ ByteString aStr(rTabName, RTL_TEXTENCODING_UTF8);
+ aStr.Append(static_cast< char >(0));
+ std::cerr << "tabname \'" << aStr.GetBuffer() << '\'' << std::endl;
+ }
+#endif
+ // External reference, same as in ScCompiler::MakeTabStr()
+ if ( rTabName.GetChar(0) == '\'' )
+ { // "'Doc'#Tab"
+ xub_StrLen nPos = ScGlobal::FindUnquoted( rTabName, SC_COMPILER_FILE_TAB_SEP);
+ if (nPos != STRING_NOTFOUND && nPos > 0 && rTabName.GetChar(nPos-1) == '\'')
+ {
+ rDocName = rTabName.Copy( 0, nPos + 1 );
+ rTabName.Erase( 0, nPos + 1 );
+ }
+ }
+ else if( nFlags & SCA_FORCE_DOC )
+ {
+ // VBA has an 'external' flag that forces the addition of the
+ // tab name _and_ the doc name. The VBA code would be
+ // needlessly complicated if it constructed an actual external
+ // reference so we add this somewhat cheesy kludge to force the
+ // addition of the document name even for non-external references
+ rDocName = getFileNameFromDoc( pDoc );
+ }
+ ScCompiler::CheckTabQuotes( rTabName, rDetails.eConv);
+}
+
+static void
+lcl_ScRange_Format_XL_Header( String& r, const ScRange& rRange,
+ USHORT nFlags, ScDocument* pDoc,
+ const ScAddress::Details& rDetails )
+{
+ if( nFlags & SCA_TAB_3D )
+ {
+ String aTabName, aDocName;
+ lcl_Split_DocTab( pDoc, rRange.aStart.Tab(), rDetails, nFlags,
+ aTabName, aDocName );
+ if( aDocName.Len() > 0 )
+ {
+ r += '[';
+ r += aDocName;
+ r += ']';
+ }
+ r += aTabName;
+
+ if( nFlags & SCA_TAB2_3D )
+ {
+ lcl_Split_DocTab( pDoc, rRange.aEnd.Tab(), rDetails, nFlags,
+ aTabName, aDocName );
+ r += ':';
+ r += aTabName;
+ }
+ r += '!';
+ }
+}
+
+void ScRange::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+ const ScAddress::Details& rDetails ) const
+{
+ r.Erase();
+ if( !( nFlags & SCA_VALID ) )
+ {
+ r = ScGlobal::GetRscString( STR_NOREF_STR );
+ return;
+ }
+
+#define absrel_differ(nFlags, mask) (((nFlags) & (mask)) ^ (((nFlags) >> 4) & (mask)))
+ switch( rDetails.eConv ) {
+ default :
+ case formula::FormulaGrammar::CONV_OOO: {
+ BOOL bOneTab = (aStart.Tab() == aEnd.Tab());
+ if ( !bOneTab )
+ nFlags |= SCA_TAB_3D;
+ aStart.Format( r, nFlags, pDoc, rDetails );
+ if( aStart != aEnd ||
+ absrel_differ( nFlags, SCA_COL_ABSOLUTE ) ||
+ absrel_differ( nFlags, SCA_ROW_ABSOLUTE ))
+ {
+ String aName;
+ nFlags = ( nFlags & SCA_VALID ) | ( ( nFlags >> 4 ) & 0x070F );
+ if ( bOneTab )
+ pDoc = NULL;
+ else
+ nFlags |= SCA_TAB_3D;
+ aEnd.Format( aName, nFlags, pDoc, rDetails );
+ r += ':';
+ r += aName;
+ }
+ }
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ lcl_ScRange_Format_XL_Header( r, *this, nFlags, pDoc, rDetails );
+ if( aStart.Col() == 0 && aEnd.Col() >= MAXCOL )
+ {
+ // Full col refs always require 2 rows (2:2)
+ lcl_a1_append_r( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE );
+ r += ':';
+ lcl_a1_append_r( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE );
+ }
+ else if( aStart.Row() == 0 && aEnd.Row() >= MAXROW )
+ {
+ // Full row refs always require 2 cols (A:A)
+ lcl_a1_append_c( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE );
+ r += ':';
+ lcl_a1_append_c( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE );
+ }
+ else
+ {
+ lcl_a1_append_c ( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE );
+ lcl_a1_append_r ( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE );
+ if( aStart.Col() != aEnd.Col() ||
+ absrel_differ( nFlags, SCA_COL_ABSOLUTE ) ||
+ aStart.Row() != aEnd.Row() ||
+ absrel_differ( nFlags, SCA_ROW_ABSOLUTE )) {
+ r += ':';
+ lcl_a1_append_c ( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE );
+ lcl_a1_append_r ( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE );
+ }
+ }
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ lcl_ScRange_Format_XL_Header( r, *this, nFlags, pDoc, rDetails );
+ if( aStart.Col() == 0 && aEnd.Col() >= MAXCOL )
+ {
+ lcl_r1c1_append_r( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE, rDetails );
+ if( aStart.Row() != aEnd.Row() ||
+ absrel_differ( nFlags, SCA_ROW_ABSOLUTE )) {
+ r += ':';
+ lcl_r1c1_append_r( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE, rDetails );
+ }
+ }
+ else if( aStart.Row() == 0 && aEnd.Row() >= MAXROW )
+ {
+ lcl_r1c1_append_c( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE, rDetails );
+ if( aStart.Col() != aEnd.Col() ||
+ absrel_differ( nFlags, SCA_COL_ABSOLUTE )) {
+ r += ':';
+ lcl_r1c1_append_c( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE, rDetails );
+ }
+ }
+ else
+ {
+ lcl_r1c1_append_r( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE, rDetails );
+ lcl_r1c1_append_c( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE, rDetails );
+ if( aStart.Col() != aEnd.Col() ||
+ absrel_differ( nFlags, SCA_COL_ABSOLUTE ) ||
+ aStart.Row() != aEnd.Row() ||
+ absrel_differ( nFlags, SCA_ROW_ABSOLUTE )) {
+ r += ':';
+ lcl_r1c1_append_r( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE, rDetails );
+ lcl_r1c1_append_c( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE, rDetails );
+ }
+ }
+ }
+#undef absrel_differ
+}
+
+bool ScAddress::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc )
+{
+ SCsTAB nMaxTab = pDoc ? pDoc->GetTableCount() : MAXTAB+1;
+ dx = Col() + dx;
+ dy = Row() + dy;
+ dz = Tab() + dz;
+ BOOL bValid = TRUE;
+ if( dx < 0 )
+ dx = 0, bValid = FALSE;
+ else if( dx > MAXCOL )
+ dx = MAXCOL, bValid =FALSE;
+ if( dy < 0 )
+ dy = 0, bValid = FALSE;
+ else if( dy > MAXROW )
+ dy = MAXROW, bValid =FALSE;
+ if( dz < 0 )
+ dz = 0, bValid = FALSE;
+ else if( dz >= nMaxTab )
+ dz = nMaxTab-1, bValid =FALSE;
+ Set( dx, dy, dz );
+ return bValid;
+}
+
+
+bool ScRange::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc )
+{
+ // Einfahces &, damit beides ausgefuehrt wird!!
+ return aStart.Move( dx, dy, dz, pDoc ) & aEnd.Move( dx, dy, dz, pDoc );
+}
+
+
+String ScAddress::GetColRowString( bool bAbsolute,
+ const Details& rDetails ) const
+{
+ String aString;
+
+ switch( rDetails.eConv )
+ {
+ default :
+ case formula::FormulaGrammar::CONV_OOO:
+ case formula::FormulaGrammar::CONV_XL_A1:
+ case formula::FormulaGrammar::CONV_XL_OOX:
+ if (bAbsolute)
+ aString.Append( '$' );
+
+ ScColToAlpha( aString, nCol);
+
+ if ( bAbsolute )
+ aString.Append( '$' );
+
+ aString += String::CreateFromInt32(nRow+1);
+ break;
+
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ lcl_r1c1_append_r ( aString, nRow, bAbsolute, rDetails );
+ lcl_r1c1_append_c ( aString, nCol, bAbsolute, rDetails );
+ break;
+ }
+
+ return aString;
+}
+
+
+String ScRefAddress::GetRefString( ScDocument* pDoc, SCTAB nActTab,
+ const ScAddress::Details& rDetails ) const
+{
+ if ( !pDoc )
+ return EMPTY_STRING;
+ if ( Tab()+1 > pDoc->GetTableCount() )
+ return ScGlobal::GetRscString( STR_NOREF_STR );
+
+ String aString;
+ USHORT nFlags = SCA_VALID;
+ if ( nActTab != Tab() )
+ {
+ nFlags |= SCA_TAB_3D;
+ if ( !bRelTab )
+ nFlags |= SCA_TAB_ABSOLUTE;
+ }
+ if ( !bRelCol )
+ nFlags |= SCA_COL_ABSOLUTE;
+ if ( !bRelRow )
+ nFlags |= SCA_ROW_ABSOLUTE;
+
+ aAdr.Format( aString, nFlags, pDoc, rDetails );
+
+ return aString;
+}
+
+//------------------------------------------------------------------------
+
+void ScColToAlpha( rtl::OUStringBuffer& rBuf, SCCOL nCol )
+{
+ if (nCol < 26*26)
+ {
+ if (nCol < 26)
+ rBuf.append( static_cast<sal_Unicode>( 'A' +
+ static_cast<sal_uInt16>(nCol)));
+ else
+ {
+ rBuf.append( static_cast<sal_Unicode>( 'A' +
+ (static_cast<sal_uInt16>(nCol) / 26) - 1));
+ rBuf.append( static_cast<sal_Unicode>( 'A' +
+ (static_cast<sal_uInt16>(nCol) % 26)));
+ }
+ }
+ else
+ {
+ String aStr;
+ while (nCol >= 26)
+ {
+ SCCOL nC = nCol % 26;
+ aStr += static_cast<sal_Unicode>( 'A' +
+ static_cast<sal_uInt16>(nC));
+ nCol = sal::static_int_cast<SCCOL>( nCol - nC );
+ nCol = nCol / 26 - 1;
+ }
+ aStr += static_cast<sal_Unicode>( 'A' +
+ static_cast<sal_uInt16>(nCol));
+ aStr.Reverse();
+ rBuf.append( aStr);
+ }
+}
+
+
+bool AlphaToCol( SCCOL& rCol, const String& rStr)
+{
+ SCCOL nResult = 0;
+ xub_StrLen nStop = rStr.Len();
+ xub_StrLen nPos = 0;
+ sal_Unicode c;
+ while (nResult <= MAXCOL && nPos < nStop && (c = rStr.GetChar( nPos)) != 0 &&
+ CharClass::isAsciiAlpha(c))
+ {
+ if (nPos > 0)
+ nResult = (nResult + 1) * 26;
+ nResult += ScGlobal::ToUpperAlpha(c) - 'A';
+ ++nPos;
+ }
+ bool bOk = (ValidCol(nResult) && nPos > 0);
+ if (bOk)
+ rCol = nResult;
+ return bOk;
+}
diff --git a/sc/source/core/tool/adiasync.cxx b/sc/source/core/tool/adiasync.cxx
new file mode 100644
index 000000000000..4f19a043a34d
--- /dev/null
+++ b/sc/source/core/tool/adiasync.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <sfx2/objsh.hxx>
+
+#include "adiasync.hxx"
+#include "brdcst.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "sc.hrc" // FID_DATACHANGED
+#include <osl/thread.h>
+
+
+//------------------------------------------------------------------------
+
+ScAddInAsyncs theAddInAsyncTbl;
+static ScAddInAsync aSeekObj;
+
+
+SV_IMPL_OP_PTRARR_SORT( ScAddInAsyncs, ScAddInAsyncPtr );
+
+SV_IMPL_PTRARR_SORT( ScAddInDocs, ScAddInDocPtr );
+
+extern "C" {
+void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData )
+{
+ ScAddInAsync::CallBack( ULONG( nHandle ), pData );
+}
+}
+
+
+
+ScAddInAsync::ScAddInAsync() :
+ SvtBroadcaster(),
+ nHandle( 0 )
+{ // nur fuer aSeekObj !
+}
+
+
+
+ScAddInAsync::ScAddInAsync( ULONG nHandleP, USHORT nIndex, ScDocument* pDoc ) :
+ SvtBroadcaster(),
+ pStr( NULL ),
+ nHandle( nHandleP ),
+ bValid( FALSE )
+{
+ pDocs = new ScAddInDocs( 1, 1 );
+ pDocs->Insert( pDoc );
+ pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex);
+ eType = pFuncData->GetAsyncType();
+ theAddInAsyncTbl.Insert( this );
+}
+
+
+
+ScAddInAsync::~ScAddInAsync()
+{
+ // aSeekObj hat das alles nicht, Handle 0 gibt es sonst nicht
+ if ( nHandle )
+ {
+ // im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear
+ pFuncData->Unadvice( (double)nHandle );
+ if ( eType == PTR_STRING && pStr ) // mit Typvergleich wg. Union!
+ delete pStr;
+ delete pDocs;
+ }
+}
+
+
+
+ScAddInAsync* ScAddInAsync::Get( ULONG nHandleP )
+{
+ USHORT nPos;
+ ScAddInAsync* pRet = 0;
+ aSeekObj.nHandle = nHandleP;
+ if ( theAddInAsyncTbl.Seek_Entry( &aSeekObj, &nPos ) )
+ pRet = theAddInAsyncTbl[ nPos ];
+ aSeekObj.nHandle = 0;
+ return pRet;
+}
+
+
+
+void ScAddInAsync::CallBack( ULONG nHandleP, void* pData )
+{
+ ScAddInAsync* p;
+ if ( (p = Get( nHandleP )) == NULL )
+ return;
+ // keiner mehr dran? Unadvice und weg damit
+ if ( !p->HasListeners() )
+ {
+ // nicht im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear
+ theAddInAsyncTbl.Remove( p );
+ delete p;
+ return ;
+ }
+ switch ( p->eType )
+ {
+ case PTR_DOUBLE :
+ p->nVal = *(double*)pData;
+ break;
+ case PTR_STRING :
+ if ( p->pStr )
+ *p->pStr = String( (sal_Char*)pData, osl_getThreadTextEncoding() );
+ else
+ p->pStr = new String( (sal_Char*)pData, osl_getThreadTextEncoding() );
+ break;
+ default :
+ DBG_ERROR( "unbekannter AsyncType" );
+ return;
+ }
+ p->bValid = TRUE;
+ p->Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
+
+ const ScDocument** ppDoc = (const ScDocument**) p->pDocs->GetData();
+ USHORT nCount = p->pDocs->Count();
+ for ( USHORT j=0; j<nCount; j++, ppDoc++ )
+ {
+ ScDocument* pDoc = (ScDocument*)*ppDoc;
+ pDoc->TrackFormulas();
+ pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
+ pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
+ }
+}
+
+
+
+void ScAddInAsync::RemoveDocument( ScDocument* pDocumentP )
+{
+ USHORT nPos = theAddInAsyncTbl.Count();
+ if ( nPos )
+ {
+ const ScAddInAsync** ppAsync =
+ (const ScAddInAsync**) theAddInAsyncTbl.GetData() + nPos - 1;
+ for ( ; nPos-- >0; ppAsync-- )
+ { // rueckwaerts wg. Pointer-Aufrueckerei im Array
+ ScAddInDocs* p = ((ScAddInAsync*)*ppAsync)->pDocs;
+ USHORT nFoundPos;
+ if ( p->Seek_Entry( pDocumentP, &nFoundPos ) )
+ {
+ p->Remove( nFoundPos );
+ if ( p->Count() == 0 )
+ { // dieses AddIn wird nicht mehr benutzt
+ ScAddInAsync* pAsync = (ScAddInAsync*)*ppAsync;
+ theAddInAsyncTbl.Remove( nPos );
+ delete pAsync;
+ ppAsync = (const ScAddInAsync**) theAddInAsyncTbl.GetData()
+ + nPos;
+ }
+ }
+ }
+ }
+}
+
+
+
diff --git a/sc/source/core/tool/appoptio.cxx b/sc/source/core/tool/appoptio.cxx
new file mode 100644
index 000000000000..857efd972886
--- /dev/null
+++ b/sc/source/core/tool/appoptio.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "cfgids.hxx"
+#include "appoptio.hxx"
+#include "rechead.hxx"
+#include "scresid.hxx"
+#include "global.hxx"
+#include "userlist.hxx"
+#include "sc.hrc"
+#include <formula/compiler.hrc>
+#include "miscuno.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+// STATIC DATA -----------------------------------------------------------
+
+#define SC_VERSION ((USHORT)304)
+
+//========================================================================
+// ScAppOptions - Applikations-Optionen
+//========================================================================
+
+ScAppOptions::ScAppOptions() : pLRUList( NULL )
+{
+ SetDefaults();
+}
+
+//------------------------------------------------------------------------
+
+ScAppOptions::ScAppOptions( const ScAppOptions& rCpy ) : pLRUList( NULL )
+{
+ *this = rCpy;
+}
+
+//------------------------------------------------------------------------
+
+ScAppOptions::~ScAppOptions()
+{
+ delete [] pLRUList;
+}
+
+//------------------------------------------------------------------------
+
+void ScAppOptions::SetDefaults()
+{
+ if ( ScOptionsUtil::IsMetricSystem() )
+ eMetric = FUNIT_CM; // default for countries with metric system
+ else
+ eMetric = FUNIT_INCH; // default for others
+
+ nZoom = 100;
+ eZoomType = SVX_ZOOM_PERCENT;
+ bSynchronizeZoom = TRUE;
+ nStatusFunc = SUBTOTAL_FUNC_SUM;
+ bAutoComplete = TRUE;
+ bDetectiveAuto = TRUE;
+
+ delete [] pLRUList;
+ pLRUList = new USHORT[5]; // sinnvoll vorbelegen
+ pLRUList[0] = SC_OPCODE_SUM;
+ pLRUList[1] = SC_OPCODE_AVERAGE;
+ pLRUList[2] = SC_OPCODE_MIN;
+ pLRUList[3] = SC_OPCODE_MAX;
+ pLRUList[4] = SC_OPCODE_IF;
+ nLRUFuncCount = 5;
+
+ nTrackContentColor = COL_TRANSPARENT;
+ nTrackInsertColor = COL_TRANSPARENT;
+ nTrackDeleteColor = COL_TRANSPARENT;
+ nTrackMoveColor = COL_TRANSPARENT;
+ eLinkMode = LM_ON_DEMAND;
+
+ nDefaultObjectSizeWidth = 8000;
+ nDefaultObjectSizeHeight = 5000;
+
+ mbShowSharedDocumentWarning = true;
+}
+
+//------------------------------------------------------------------------
+
+const ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy )
+{
+ eMetric = rCpy.eMetric;
+ eZoomType = rCpy.eZoomType;
+ bSynchronizeZoom = rCpy.bSynchronizeZoom;
+ nZoom = rCpy.nZoom;
+ SetLRUFuncList( rCpy.pLRUList, rCpy.nLRUFuncCount );
+ nStatusFunc = rCpy.nStatusFunc;
+ bAutoComplete = rCpy.bAutoComplete;
+ bDetectiveAuto = rCpy.bDetectiveAuto;
+ nTrackContentColor = rCpy.nTrackContentColor;
+ nTrackInsertColor = rCpy.nTrackInsertColor;
+ nTrackDeleteColor = rCpy.nTrackDeleteColor;
+ nTrackMoveColor = rCpy.nTrackMoveColor;
+ eLinkMode = rCpy.eLinkMode;
+ nDefaultObjectSizeWidth = rCpy.nDefaultObjectSizeWidth;
+ nDefaultObjectSizeHeight = rCpy.nDefaultObjectSizeHeight;
+ mbShowSharedDocumentWarning = rCpy.mbShowSharedDocumentWarning;
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+void ScAppOptions::SetLRUFuncList( const USHORT* pList, const USHORT nCount )
+{
+ delete [] pLRUList;
+
+ nLRUFuncCount = nCount;
+
+ if ( nLRUFuncCount > 0 )
+ {
+ pLRUList = new USHORT[nLRUFuncCount];
+
+ for ( USHORT i=0; i<nLRUFuncCount; i++ )
+ pLRUList[i] = pList[i];
+ }
+ else
+ pLRUList = NULL;
+}
+
+//==================================================================
+// Config Item containing app options
+//==================================================================
+
+void lcl_SetLastFunctions( ScAppOptions& rOpt, const Any& rValue )
+{
+ Sequence<sal_Int32> aSeq;
+ if ( rValue >>= aSeq )
+ {
+ long nCount = aSeq.getLength();
+ if ( nCount < USHRT_MAX )
+ {
+ const sal_Int32* pArray = aSeq.getConstArray();
+ USHORT* pUShorts = new USHORT[nCount];
+ for (long i=0; i<nCount; i++)
+ pUShorts[i] = (USHORT) pArray[i];
+
+ rOpt.SetLRUFuncList( pUShorts, sal::static_int_cast<USHORT>(nCount) );
+
+ delete[] pUShorts;
+ }
+ }
+}
+
+void lcl_GetLastFunctions( Any& rDest, const ScAppOptions& rOpt )
+{
+ long nCount = rOpt.GetLRUFuncListCount();
+ USHORT* pUShorts = rOpt.GetLRUFuncList();
+ if ( nCount && pUShorts )
+ {
+ Sequence<sal_Int32> aSeq( nCount );
+ sal_Int32* pArray = aSeq.getArray();
+ for (long i=0; i<nCount; i++)
+ pArray[i] = pUShorts[i];
+ rDest <<= aSeq;
+ }
+ else
+ rDest <<= Sequence<sal_Int32>(0); // empty
+}
+
+void lcl_SetSortList( const Any& rValue )
+{
+ Sequence<OUString> aSeq;
+ if ( rValue >>= aSeq )
+ {
+ long nCount = aSeq.getLength();
+ const OUString* pArray = aSeq.getConstArray();
+ ScUserList aList;
+
+ // if setting is "default", keep default values from ScUserList ctor
+ //! mark "default" in a safe way
+ BOOL bDefault = ( nCount == 1 &&
+ pArray[0].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NULL" ) ) );
+
+ if (!bDefault)
+ {
+ aList.FreeAll();
+
+ for (long i=0; i<nCount; i++)
+ {
+ ScUserListData* pNew = new ScUserListData( pArray[i] );
+ if ( !aList.Insert(pNew) )
+ delete pNew;
+ }
+ }
+
+ ScGlobal::SetUserList( &aList );
+ }
+}
+
+void lcl_GetSortList( Any& rDest )
+{
+ const ScUserList* pUserList = ScGlobal::GetUserList();
+ if (pUserList)
+ {
+ long nCount = pUserList->GetCount();
+ Sequence<OUString> aSeq( nCount );
+ OUString* pArray = aSeq.getArray();
+ for (long i=0; i<nCount; i++)
+ pArray[i] = (*pUserList)[sal::static_int_cast<USHORT>(i)]->GetString();
+ rDest <<= aSeq;
+ }
+ else
+ rDest <<= Sequence<OUString>(0); // empty
+}
+
+//------------------------------------------------------------------
+
+#define CFGPATH_LAYOUT "Office.Calc/Layout"
+
+#define SCLAYOUTOPT_MEASURE 0
+#define SCLAYOUTOPT_STATUSBAR 1
+#define SCLAYOUTOPT_ZOOMVAL 2
+#define SCLAYOUTOPT_ZOOMTYPE 3
+#define SCLAYOUTOPT_SYNCZOOM 4
+#define SCLAYOUTOPT_COUNT 5
+
+#define CFGPATH_INPUT "Office.Calc/Input"
+
+#define SCINPUTOPT_LASTFUNCS 0
+#define SCINPUTOPT_AUTOINPUT 1
+#define SCINPUTOPT_DET_AUTO 2
+#define SCINPUTOPT_COUNT 3
+
+#define CFGPATH_REVISION "Office.Calc/Revision/Color"
+
+#define SCREVISOPT_CHANGE 0
+#define SCREVISOPT_INSERTION 1
+#define SCREVISOPT_DELETION 2
+#define SCREVISOPT_MOVEDENTRY 3
+#define SCREVISOPT_COUNT 4
+
+#define CFGPATH_CONTENT "Office.Calc/Content/Update"
+
+#define SCCONTENTOPT_LINK 0
+#define SCCONTENTOPT_COUNT 1
+
+#define CFGPATH_SORTLIST "Office.Calc/SortList"
+
+#define SCSORTLISTOPT_LIST 0
+#define SCSORTLISTOPT_COUNT 1
+
+#define CFGPATH_MISC "Office.Calc/Misc"
+
+#define SCMISCOPT_DEFOBJWIDTH 0
+#define SCMISCOPT_DEFOBJHEIGHT 1
+#define SCMISCOPT_SHOWSHAREDDOCWARN 2
+#define SCMISCOPT_COUNT 3
+
+
+Sequence<OUString> ScAppCfg::GetLayoutPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Other/MeasureUnit/NonMetric", // SCLAYOUTOPT_MEASURE
+ "Other/StatusbarFunction", // SCLAYOUTOPT_STATUSBAR
+ "Zoom/Value", // SCLAYOUTOPT_ZOOMVAL
+ "Zoom/Type", // SCLAYOUTOPT_ZOOMTYPE
+ "Zoom/Synchronize" // SCLAYOUTOPT_SYNCZOOM
+ };
+ Sequence<OUString> aNames(SCLAYOUTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCLAYOUTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ // adjust for metric system
+ if (ScOptionsUtil::IsMetricSystem())
+ pNames[SCLAYOUTOPT_MEASURE] = OUString::createFromAscii( "Other/MeasureUnit/Metric" );
+
+ return aNames;
+}
+
+Sequence<OUString> ScAppCfg::GetInputPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "LastFunctions", // SCINPUTOPT_LASTFUNCS
+ "AutoInput", // SCINPUTOPT_AUTOINPUT
+ "DetectiveAuto" // SCINPUTOPT_DET_AUTO
+ };
+ Sequence<OUString> aNames(SCINPUTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCINPUTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScAppCfg::GetRevisionPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Change", // SCREVISOPT_CHANGE
+ "Insertion", // SCREVISOPT_INSERTION
+ "Deletion", // SCREVISOPT_DELETION
+ "MovedEntry" // SCREVISOPT_MOVEDENTRY
+ };
+ Sequence<OUString> aNames(SCREVISOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCREVISOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScAppCfg::GetContentPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Link" // SCCONTENTOPT_LINK
+ };
+ Sequence<OUString> aNames(SCCONTENTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCCONTENTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScAppCfg::GetSortListPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "List" // SCSORTLISTOPT_LIST
+ };
+ Sequence<OUString> aNames(SCSORTLISTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCSORTLISTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScAppCfg::GetMiscPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "DefaultObjectSize/Width", // SCMISCOPT_DEFOBJWIDTH
+ "DefaultObjectSize/Height", // SCMISCOPT_DEFOBJHEIGHT
+ "SharedDocument/ShowWarning" // SCMISCOPT_SHOWSHAREDDOCWARN
+ };
+ Sequence<OUString> aNames(SCMISCOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCMISCOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+
+ScAppCfg::ScAppCfg() :
+ aLayoutItem( OUString::createFromAscii( CFGPATH_LAYOUT ) ),
+ aInputItem( OUString::createFromAscii( CFGPATH_INPUT ) ),
+ aRevisionItem( OUString::createFromAscii( CFGPATH_REVISION ) ),
+ aContentItem( OUString::createFromAscii( CFGPATH_CONTENT ) ),
+ aSortListItem( OUString::createFromAscii( CFGPATH_SORTLIST ) ),
+ aMiscItem( OUString::createFromAscii( CFGPATH_MISC ) )
+{
+ sal_Int32 nIntVal = 0;
+
+ Sequence<OUString> aNames;
+ Sequence<Any> aValues;
+ const Any* pValues = NULL;
+
+ aNames = GetLayoutPropertyNames();
+ aValues = aLayoutItem.GetProperties(aNames);
+ aLayoutItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCLAYOUTOPT_MEASURE:
+ if (pValues[nProp] >>= nIntVal) SetAppMetric( (FieldUnit) nIntVal );
+ break;
+ case SCLAYOUTOPT_STATUSBAR:
+ if (pValues[nProp] >>= nIntVal) SetStatusFunc( (USHORT) nIntVal );
+ break;
+ case SCLAYOUTOPT_ZOOMVAL:
+ if (pValues[nProp] >>= nIntVal) SetZoom( (USHORT) nIntVal );
+ break;
+ case SCLAYOUTOPT_ZOOMTYPE:
+ if (pValues[nProp] >>= nIntVal) SetZoomType( (SvxZoomType) nIntVal );
+ break;
+ case SCLAYOUTOPT_SYNCZOOM:
+ SetSynchronizeZoom( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+ aLayoutItem.SetCommitLink( LINK( this, ScAppCfg, LayoutCommitHdl ) );
+
+ aNames = GetInputPropertyNames();
+ aValues = aInputItem.GetProperties(aNames);
+ aInputItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCINPUTOPT_LASTFUNCS:
+ lcl_SetLastFunctions( *this, pValues[nProp] );
+ break;
+ case SCINPUTOPT_AUTOINPUT:
+ SetAutoComplete( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_DET_AUTO:
+ SetDetectiveAuto( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+ aInputItem.SetCommitLink( LINK( this, ScAppCfg, InputCommitHdl ) );
+
+ aNames = GetRevisionPropertyNames();
+ aValues = aRevisionItem.GetProperties(aNames);
+ aRevisionItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCREVISOPT_CHANGE:
+ if (pValues[nProp] >>= nIntVal) SetTrackContentColor( (sal_uInt32) nIntVal );
+ break;
+ case SCREVISOPT_INSERTION:
+ if (pValues[nProp] >>= nIntVal) SetTrackInsertColor( (sal_uInt32) nIntVal );
+ break;
+ case SCREVISOPT_DELETION:
+ if (pValues[nProp] >>= nIntVal) SetTrackDeleteColor( (sal_uInt32) nIntVal );
+ break;
+ case SCREVISOPT_MOVEDENTRY:
+ if (pValues[nProp] >>= nIntVal) SetTrackMoveColor( (sal_uInt32) nIntVal );
+ break;
+ }
+ }
+ }
+ }
+ aRevisionItem.SetCommitLink( LINK( this, ScAppCfg, RevisionCommitHdl ) );
+
+ aNames = GetContentPropertyNames();
+ aValues = aContentItem.GetProperties(aNames);
+ aContentItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCCONTENTOPT_LINK:
+ if (pValues[nProp] >>= nIntVal) SetLinkMode( (ScLkUpdMode) nIntVal );
+ break;
+ }
+ }
+ }
+ }
+ aContentItem.SetCommitLink( LINK( this, ScAppCfg, ContentCommitHdl ) );
+
+ aNames = GetSortListPropertyNames();
+ aValues = aSortListItem.GetProperties(aNames);
+ aSortListItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCSORTLISTOPT_LIST:
+ lcl_SetSortList( pValues[nProp] );
+ break;
+ }
+ }
+ }
+ }
+ aSortListItem.SetCommitLink( LINK( this, ScAppCfg, SortListCommitHdl ) );
+
+ aNames = GetMiscPropertyNames();
+ aValues = aMiscItem.GetProperties(aNames);
+ aMiscItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCMISCOPT_DEFOBJWIDTH:
+ if (pValues[nProp] >>= nIntVal) SetDefaultObjectSizeWidth( nIntVal );
+ break;
+ case SCMISCOPT_DEFOBJHEIGHT:
+ if (pValues[nProp] >>= nIntVal) SetDefaultObjectSizeHeight( nIntVal );
+ break;
+ case SCMISCOPT_SHOWSHAREDDOCWARN:
+ SetShowSharedDocumentWarning( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+ aMiscItem.SetCommitLink( LINK( this, ScAppCfg, MiscCommitHdl ) );
+}
+
+IMPL_LINK( ScAppCfg, LayoutCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetLayoutPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCLAYOUTOPT_MEASURE:
+ pValues[nProp] <<= (sal_Int32) GetAppMetric();
+ break;
+ case SCLAYOUTOPT_STATUSBAR:
+ pValues[nProp] <<= (sal_Int32) GetStatusFunc();
+ break;
+ case SCLAYOUTOPT_ZOOMVAL:
+ pValues[nProp] <<= (sal_Int32) GetZoom();
+ break;
+ case SCLAYOUTOPT_ZOOMTYPE:
+ pValues[nProp] <<= (sal_Int32) GetZoomType();
+ break;
+ case SCLAYOUTOPT_SYNCZOOM:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetSynchronizeZoom() );
+ break;
+ }
+ }
+ aLayoutItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScAppCfg, InputCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetInputPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCINPUTOPT_LASTFUNCS:
+ lcl_GetLastFunctions( pValues[nProp], *this );
+ break;
+ case SCINPUTOPT_AUTOINPUT:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetAutoComplete() );
+ break;
+ case SCINPUTOPT_DET_AUTO:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetDetectiveAuto() );
+ break;
+ }
+ }
+ aInputItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScAppCfg, RevisionCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetRevisionPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCREVISOPT_CHANGE:
+ pValues[nProp] <<= (sal_Int32) GetTrackContentColor();
+ break;
+ case SCREVISOPT_INSERTION:
+ pValues[nProp] <<= (sal_Int32) GetTrackInsertColor();
+ break;
+ case SCREVISOPT_DELETION:
+ pValues[nProp] <<= (sal_Int32) GetTrackDeleteColor();
+ break;
+ case SCREVISOPT_MOVEDENTRY:
+ pValues[nProp] <<= (sal_Int32) GetTrackMoveColor();
+ break;
+ }
+ }
+ aRevisionItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScAppCfg, ContentCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetContentPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCCONTENTOPT_LINK:
+ pValues[nProp] <<= (sal_Int32) GetLinkMode();
+ break;
+ }
+ }
+ aContentItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScAppCfg, SortListCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetSortListPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCSORTLISTOPT_LIST:
+ lcl_GetSortList( pValues[nProp] );
+ break;
+ }
+ }
+ aSortListItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScAppCfg, MiscCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetMiscPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCMISCOPT_DEFOBJWIDTH:
+ pValues[nProp] <<= (sal_Int32) GetDefaultObjectSizeWidth();
+ break;
+ case SCMISCOPT_DEFOBJHEIGHT:
+ pValues[nProp] <<= (sal_Int32) GetDefaultObjectSizeHeight();
+ break;
+ case SCMISCOPT_SHOWSHAREDDOCWARN:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetShowSharedDocumentWarning() );
+ break;
+ }
+ }
+ aMiscItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+void ScAppCfg::SetOptions( const ScAppOptions& rNew )
+{
+ *(ScAppOptions*)this = rNew;
+ OptionsChanged();
+}
+
+void ScAppCfg::OptionsChanged()
+{
+ aLayoutItem.SetModified();
+ aInputItem.SetModified();
+ aRevisionItem.SetModified();
+ aContentItem.SetModified();
+ aSortListItem.SetModified();
+ aMiscItem.SetModified();
+}
+
+
diff --git a/sc/source/core/tool/autoform.cxx b/sc/source/core/tool/autoform.cxx
new file mode 100644
index 000000000000..5a7f117e75d9
--- /dev/null
+++ b/sc/source/core/tool/autoform.cxx
@@ -0,0 +1,1200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+
+#define READ_OLDVERS
+
+#include "autoform.hxx"
+
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/itemset.hxx>
+#include <tools/shl.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/dialogs.hrc>
+#include <editeng/langitem.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <tools/tenccvt.hxx>
+
+#include "globstr.hrc"
+#include "document.hxx"
+
+//------------------------------------------------------------------------
+
+const sal_Char *linker_dummy = "";
+
+// Standard-Name ist jetzt STR_STYLENAME_STANDARD (wie Vorlagen)
+//static const sal_Char __FAR_DATA cStandardName[] = "Standard";
+
+static const sal_Char __FAR_DATA sAutoTblFmtName[] = "autotbl.fmt";
+
+// bis SO5PF
+const USHORT AUTOFORMAT_ID_X = 9501;
+const USHORT AUTOFORMAT_ID_358 = 9601;
+const USHORT AUTOFORMAT_DATA_ID_X = 9502;
+
+// ab SO5
+//! in nachfolgenden Versionen muss der Betrag dieser IDs groesser sein
+const USHORT AUTOFORMAT_ID_504 = 9801;
+const USHORT AUTOFORMAT_DATA_ID_504 = 9802;
+
+const USHORT AUTOFORMAT_ID_552 = 9901;
+const USHORT AUTOFORMAT_DATA_ID_552 = 9902;
+
+// --- from 641 on: CJK and CTL font settings
+const USHORT AUTOFORMAT_ID_641 = 10001;
+const USHORT AUTOFORMAT_DATA_ID_641 = 10002;
+
+// --- from 680/dr14 on: diagonal frame lines
+const USHORT AUTOFORMAT_ID_680DR14 = 10011;
+const USHORT AUTOFORMAT_DATA_ID_680DR14 = 10012;
+
+// --- from 680/dr25 on: #21549# store strings as UTF-8
+const USHORT AUTOFORMAT_ID_680DR25 = 10021;
+const USHORT AUTOFORMAT_DATA_ID_680DR25 = 10022;
+
+// --- from DEV300/overline2 on: #5991# overline support
+const USHORT AUTOFORMAT_ID_300OVRLN = 10031;
+const USHORT AUTOFORMAT_DATA_ID_300OVRLN = 10032;
+
+// aktuelle Version
+const USHORT AUTOFORMAT_ID = AUTOFORMAT_ID_300OVRLN;
+const USHORT AUTOFORMAT_DATA_ID = AUTOFORMAT_DATA_ID_300OVRLN;
+
+
+#ifdef READ_OLDVERS
+const USHORT AUTOFORMAT_OLD_ID_OLD = 4201;
+const USHORT AUTOFORMAT_OLD_DATA_ID = 4202;
+const USHORT AUTOFORMAT_OLD_ID_NEW = 4203;
+#endif
+
+
+// Struct mit Versionsnummern der Items
+
+struct ScAfVersions
+{
+public:
+ USHORT nFontVersion;
+ USHORT nFontHeightVersion;
+ USHORT nWeightVersion;
+ USHORT nPostureVersion;
+ USHORT nUnderlineVersion;
+ USHORT nOverlineVersion;
+ USHORT nCrossedOutVersion;
+ USHORT nContourVersion;
+ USHORT nShadowedVersion;
+ USHORT nColorVersion;
+ USHORT nBoxVersion;
+ USHORT nLineVersion;
+ USHORT nBrushVersion;
+
+ USHORT nAdjustVersion;
+
+ USHORT nHorJustifyVersion;
+ USHORT nVerJustifyVersion;
+ USHORT nOrientationVersion;
+ USHORT nMarginVersion;
+ USHORT nBoolVersion;
+ USHORT nInt32Version;
+ USHORT nRotateModeVersion;
+
+ USHORT nNumFmtVersion;
+
+ ScAfVersions();
+ void Load( SvStream& rStream, USHORT nVer );
+ static void Write(SvStream& rStream);
+};
+
+ScAfVersions::ScAfVersions() :
+ nFontVersion(0),
+ nFontHeightVersion(0),
+ nWeightVersion(0),
+ nPostureVersion(0),
+ nUnderlineVersion(0),
+ nOverlineVersion(0),
+ nCrossedOutVersion(0),
+ nContourVersion(0),
+ nShadowedVersion(0),
+ nColorVersion(0),
+ nBoxVersion(0),
+ nLineVersion(0),
+ nBrushVersion(0),
+ nAdjustVersion(0),
+ nHorJustifyVersion(0),
+ nVerJustifyVersion(0),
+ nOrientationVersion(0),
+ nMarginVersion(0),
+ nBoolVersion(0),
+ nInt32Version(0),
+ nRotateModeVersion(0),
+ nNumFmtVersion(0)
+{
+}
+
+void ScAfVersions::Load( SvStream& rStream, USHORT nVer )
+{
+ rStream >> nFontVersion;
+ rStream >> nFontHeightVersion;
+ rStream >> nWeightVersion;
+ rStream >> nPostureVersion;
+ rStream >> nUnderlineVersion;
+ if ( nVer >= AUTOFORMAT_ID_300OVRLN )
+ rStream >> nOverlineVersion;
+ rStream >> nCrossedOutVersion;
+ rStream >> nContourVersion;
+ rStream >> nShadowedVersion;
+ rStream >> nColorVersion;
+ rStream >> nBoxVersion;
+ if ( nVer >= AUTOFORMAT_ID_680DR14 )
+ rStream >> nLineVersion;
+ rStream >> nBrushVersion;
+ rStream >> nAdjustVersion;
+ rStream >> nHorJustifyVersion;
+ rStream >> nVerJustifyVersion;
+ rStream >> nOrientationVersion;
+ rStream >> nMarginVersion;
+ rStream >> nBoolVersion;
+ if ( nVer >= AUTOFORMAT_ID_504 )
+ {
+ rStream >> nInt32Version;
+ rStream >> nRotateModeVersion;
+ }
+ rStream >> nNumFmtVersion;
+}
+
+void ScAfVersions::Write(SvStream& rStream)
+{
+ rStream << SvxFontItem(ATTR_FONT).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxFontHeightItem(240, 100, ATTR_FONT_HEIGHT).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxWeightItem(WEIGHT_NORMAL, ATTR_FONT_WEIGHT).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxPostureItem(ITALIC_NONE, ATTR_FONT_POSTURE).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxUnderlineItem(UNDERLINE_NONE, ATTR_FONT_UNDERLINE).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxOverlineItem(UNDERLINE_NONE, ATTR_FONT_OVERLINE).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxCrossedOutItem(STRIKEOUT_NONE, ATTR_FONT_CROSSEDOUT).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxContourItem(sal_False, ATTR_FONT_CONTOUR).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxShadowedItem(sal_False, ATTR_FONT_SHADOWED).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxColorItem(ATTR_FONT_COLOR).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxBoxItem(ATTR_BORDER).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxLineItem(SID_FRAME_LINESTYLE).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxBrushItem(ATTR_BACKGROUND).GetVersion(SOFFICE_FILEFORMAT_40);
+
+ rStream << SvxAdjustItem(SVX_ADJUST_LEFT, 0).GetVersion(SOFFICE_FILEFORMAT_40);
+
+ rStream << SvxHorJustifyItem(SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxOrientationItem(SVX_ORIENTATION_STANDARD, 0).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxMarginItem(ATTR_MARGIN).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SfxBoolItem(ATTR_LINEBREAK).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SfxInt32Item(ATTR_ROTATE_VALUE).GetVersion(SOFFICE_FILEFORMAT_40);
+ rStream << SvxRotateModeItem(SVX_ROTATE_MODE_STANDARD,0).GetVersion(SOFFICE_FILEFORMAT_40);
+
+ rStream << (USHORT)0; // Num-Format
+}
+
+// ---------------------------------------------------------------------------
+
+ScAutoFormatDataField::ScAutoFormatDataField() :
+ aFont( ATTR_FONT ),
+ aHeight( 240, 100, ATTR_FONT_HEIGHT ),
+ aWeight( WEIGHT_NORMAL, ATTR_FONT_WEIGHT ),
+ aPosture( ITALIC_NONE, ATTR_FONT_POSTURE ),
+
+ aCJKFont( ATTR_CJK_FONT ),
+ aCJKHeight( 240, 100, ATTR_CJK_FONT_HEIGHT ),
+ aCJKWeight( WEIGHT_NORMAL, ATTR_CJK_FONT_WEIGHT ),
+ aCJKPosture( ITALIC_NONE, ATTR_CJK_FONT_POSTURE ),
+
+ aCTLFont( ATTR_CTL_FONT ),
+ aCTLHeight( 240, 100, ATTR_CTL_FONT_HEIGHT ),
+ aCTLWeight( WEIGHT_NORMAL, ATTR_CTL_FONT_WEIGHT ),
+ aCTLPosture( ITALIC_NONE, ATTR_CTL_FONT_POSTURE ),
+
+ aUnderline( UNDERLINE_NONE,ATTR_FONT_UNDERLINE ),
+ aOverline( UNDERLINE_NONE,ATTR_FONT_OVERLINE ),
+ aCrossedOut( STRIKEOUT_NONE, ATTR_FONT_CROSSEDOUT ),
+ aContour( sal_False, ATTR_FONT_CONTOUR ),
+ aShadowed( sal_False, ATTR_FONT_SHADOWED ),
+ aColor( ATTR_FONT_COLOR ),
+ aBox( ATTR_BORDER ),
+ aTLBR( ATTR_BORDER_TLBR ),
+ aBLTR( ATTR_BORDER_BLTR ),
+ aBackground( ATTR_BACKGROUND ),
+ aAdjust( SVX_ADJUST_LEFT, 0 ),
+ aHorJustify( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ),
+ aVerJustify( SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY ),
+ aMargin( ATTR_MARGIN ),
+ aLinebreak( ATTR_LINEBREAK ),
+ aRotateAngle( ATTR_ROTATE_VALUE ),
+ aRotateMode( SVX_ROTATE_MODE_STANDARD, ATTR_ROTATE_MODE )
+{
+}
+
+ScAutoFormatDataField::ScAutoFormatDataField( const ScAutoFormatDataField& rCopy ) :
+ aFont( rCopy.aFont ),
+ aHeight( rCopy.aHeight ),
+ aWeight( rCopy.aWeight ),
+ aPosture( rCopy.aPosture ),
+ aCJKFont( rCopy.aCJKFont ),
+ aCJKHeight( rCopy.aCJKHeight ),
+ aCJKWeight( rCopy.aCJKWeight ),
+ aCJKPosture( rCopy.aCJKPosture ),
+ aCTLFont( rCopy.aCTLFont ),
+ aCTLHeight( rCopy.aCTLHeight ),
+ aCTLWeight( rCopy.aCTLWeight ),
+ aCTLPosture( rCopy.aCTLPosture ),
+ aUnderline( rCopy.aUnderline ),
+ aOverline( rCopy.aOverline ),
+ aCrossedOut( rCopy.aCrossedOut ),
+ aContour( rCopy.aContour ),
+ aShadowed( rCopy.aShadowed ),
+ aColor( rCopy.aColor ),
+ aBox( rCopy.aBox ),
+ aTLBR( rCopy.aTLBR ),
+ aBLTR( rCopy.aBLTR ),
+ aBackground( rCopy.aBackground ),
+ aAdjust( rCopy.aAdjust ),
+ aHorJustify( rCopy.aHorJustify ),
+ aVerJustify( rCopy.aVerJustify ),
+ aStacked( rCopy.aStacked ),
+ aMargin( rCopy.aMargin ),
+ aLinebreak( rCopy.aLinebreak ),
+ aRotateAngle( rCopy.aRotateAngle ),
+ aRotateMode( rCopy.aRotateMode ),
+ aNumFormat( rCopy.aNumFormat )
+{
+}
+
+ScAutoFormatDataField::~ScAutoFormatDataField()
+{
+}
+
+void ScAutoFormatDataField::SetAdjust( const SvxAdjustItem& rAdjust )
+{
+ aAdjust.SetAdjust( rAdjust.GetAdjust() );
+ aAdjust.SetOneWord( rAdjust.GetOneWord() );
+ aAdjust.SetLastBlock( rAdjust.GetLastBlock() );
+}
+
+#define READ( aItem, ItemType, nVers ) \
+ pNew = aItem.Create( rStream, nVers ); \
+ aItem = *(ItemType*)pNew; \
+ delete pNew;
+
+BOOL ScAutoFormatDataField::Load( SvStream& rStream, const ScAfVersions& rVersions, USHORT nVer )
+{
+ SfxPoolItem* pNew;
+ SvxOrientationItem aOrientation( SVX_ORIENTATION_STANDARD, 0 );
+
+ READ( aFont, SvxFontItem, rVersions.nFontVersion)
+ READ( aHeight, SvxFontHeightItem, rVersions.nFontHeightVersion)
+ READ( aWeight, SvxWeightItem, rVersions.nWeightVersion)
+ READ( aPosture, SvxPostureItem, rVersions.nPostureVersion)
+ // --- from 641 on: CJK and CTL font settings
+ if( AUTOFORMAT_DATA_ID_641 <= nVer )
+ {
+ READ( aCJKFont, SvxFontItem, rVersions.nFontVersion)
+ READ( aCJKHeight, SvxFontHeightItem, rVersions.nFontHeightVersion)
+ READ( aCJKWeight, SvxWeightItem, rVersions.nWeightVersion)
+ READ( aCJKPosture, SvxPostureItem, rVersions.nPostureVersion)
+ READ( aCTLFont, SvxFontItem, rVersions.nFontVersion)
+ READ( aCTLHeight, SvxFontHeightItem, rVersions.nFontHeightVersion)
+ READ( aCTLWeight, SvxWeightItem, rVersions.nWeightVersion)
+ READ( aCTLPosture, SvxPostureItem, rVersions.nPostureVersion)
+ }
+ READ( aUnderline, SvxUnderlineItem, rVersions.nUnderlineVersion)
+ if ( nVer >= AUTOFORMAT_DATA_ID_300OVRLN )
+ {
+ READ( aOverline, SvxOverlineItem, rVersions.nOverlineVersion)
+ }
+ READ( aCrossedOut, SvxCrossedOutItem, rVersions.nCrossedOutVersion)
+ READ( aContour, SvxContourItem, rVersions.nContourVersion)
+ READ( aShadowed, SvxShadowedItem, rVersions.nShadowedVersion)
+ READ( aColor, SvxColorItem, rVersions.nColorVersion)
+ READ( aBox, SvxBoxItem, rVersions.nBoxVersion)
+
+ // --- from 680/dr14 on: diagonal frame lines
+ if( AUTOFORMAT_DATA_ID_680DR14 <= nVer )
+ {
+ READ( aTLBR, SvxLineItem, rVersions.nLineVersion)
+ READ( aBLTR, SvxLineItem, rVersions.nLineVersion)
+ }
+
+ READ( aBackground, SvxBrushItem, rVersions.nBrushVersion)
+
+ pNew = aAdjust.Create( rStream, rVersions.nAdjustVersion );
+ SetAdjust( *(SvxAdjustItem*)pNew );
+ delete pNew;
+
+ READ( aHorJustify, SvxHorJustifyItem, rVersions.nHorJustifyVersion)
+ READ( aVerJustify, SvxVerJustifyItem, rVersions.nVerJustifyVersion)
+ READ( aOrientation, SvxOrientationItem, rVersions.nOrientationVersion)
+ READ( aMargin, SvxMarginItem, rVersions.nMarginVersion)
+
+ pNew = aLinebreak.Create( rStream, rVersions.nBoolVersion );
+ SetLinebreak( *(SfxBoolItem*)pNew );
+ delete pNew;
+
+ if ( nVer >= AUTOFORMAT_DATA_ID_504 )
+ {
+ pNew = aRotateAngle.Create( rStream, rVersions.nInt32Version );
+ SetRotateAngle( *(SfxInt32Item*)pNew );
+ delete pNew;
+ pNew = aRotateMode.Create( rStream, rVersions.nRotateModeVersion );
+ SetRotateMode( *(SvxRotateModeItem*)pNew );
+ delete pNew;
+ }
+
+ if( 0 == rVersions.nNumFmtVersion )
+ {
+ // --- from 680/dr25 on: #21549# store strings as UTF-8
+ CharSet eCharSet = (nVer >= AUTOFORMAT_ID_680DR25) ? RTL_TEXTENCODING_UTF8 : rStream.GetStreamCharSet();
+ aNumFormat.Load( rStream, eCharSet );
+ }
+
+ // adjust charset in font
+ CharSet eSysSet = gsl_getSystemTextEncoding();
+ CharSet eSrcSet = rStream.GetStreamCharSet();
+ if( eSrcSet != eSysSet && aFont.GetCharSet() == eSrcSet )
+ aFont.GetCharSet() = eSysSet;
+
+ aStacked.SetValue( aOrientation.IsStacked() );
+ aRotateAngle.SetValue( aOrientation.GetRotation( aRotateAngle.GetValue() ) );
+
+ return (rStream.GetError() == 0);
+}
+
+#ifdef READ_OLDVERS
+BOOL ScAutoFormatDataField::LoadOld( SvStream& rStream, const ScAfVersions& rVersions )
+{
+ SfxPoolItem* pNew;
+ SvxOrientationItem aOrientation( SVX_ORIENTATION_STANDARD, 0 );
+
+ aNumFormat.Load(rStream, rStream.GetStreamCharSet());
+
+ READ( aFont, SvxFontItem, rVersions.nFontVersion)
+ READ( aHeight, SvxFontHeightItem, rVersions.nFontHeightVersion)
+ READ( aWeight, SvxWeightItem, rVersions.nWeightVersion)
+ READ( aPosture, SvxPostureItem, rVersions.nPostureVersion)
+ READ( aUnderline, SvxUnderlineItem, rVersions.nUnderlineVersion)
+ READ( aCrossedOut, SvxCrossedOutItem, rVersions.nCrossedOutVersion)
+ READ( aContour, SvxContourItem, rVersions.nContourVersion)
+ READ( aShadowed, SvxShadowedItem, rVersions.nShadowedVersion)
+ READ( aColor, SvxColorItem, rVersions.nColorVersion)
+ READ( aHorJustify, SvxHorJustifyItem, rVersions.nHorJustifyVersion)
+ READ( aVerJustify, SvxVerJustifyItem, rVersions.nVerJustifyVersion)
+ READ( aOrientation, SvxOrientationItem, rVersions.nOrientationVersion)
+ pNew = aLinebreak.Create( rStream, rVersions.nBoolVersion );
+ SetLinebreak( *(SfxBoolItem*)pNew );
+ delete pNew;
+ READ( aMargin, SvxMarginItem, rVersions.nMarginVersion)
+ READ( aBox, SvxBoxItem, rVersions.nBoxVersion)
+ READ( aBackground, SvxBrushItem, rVersions.nBrushVersion)
+
+ aStacked.SetValue( aOrientation.IsStacked() );
+ aRotateAngle.SetValue( aOrientation.GetRotation( aRotateAngle.GetValue() ) );
+
+ return (rStream.GetError() == 0);
+}
+#endif
+
+BOOL ScAutoFormatDataField::Save( SvStream& rStream )
+{
+ SvxOrientationItem aOrientation( aRotateAngle.GetValue(), aStacked.GetValue(), 0 );
+
+ aFont.Store ( rStream, aFont.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aHeight.Store ( rStream, aHeight.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aWeight.Store ( rStream, aWeight.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aPosture.Store ( rStream, aPosture.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ // --- from 641 on: CJK and CTL font settings
+ aCJKFont.Store ( rStream, aCJKFont.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCJKHeight.Store ( rStream, aCJKHeight.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCJKWeight.Store ( rStream, aCJKWeight.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCJKPosture.Store ( rStream, aCJKPosture.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCTLFont.Store ( rStream, aCTLFont.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCTLHeight.Store ( rStream, aCTLHeight.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCTLWeight.Store ( rStream, aCTLWeight.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCTLPosture.Store ( rStream, aCTLPosture.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+
+ aUnderline.Store ( rStream, aUnderline.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ // --- from DEV300/overline2 on: overline support
+ aOverline.Store ( rStream, aOverline.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aCrossedOut.Store ( rStream, aCrossedOut.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aContour.Store ( rStream, aContour.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aShadowed.Store ( rStream, aShadowed.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aColor.Store ( rStream, aColor.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aBox.Store ( rStream, aBox.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+
+ // --- from 680/dr14 on: diagonal frame lines
+ aTLBR.Store ( rStream, aTLBR.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aBLTR.Store ( rStream, aBLTR.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+
+ aBackground.Store ( rStream, aBackground.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+
+ aAdjust.Store ( rStream, aAdjust.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+
+ aHorJustify.Store ( rStream, aHorJustify.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aVerJustify.Store ( rStream, aVerJustify.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aOrientation.Store ( rStream, aOrientation.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aMargin.Store ( rStream, aMargin.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aLinebreak.Store ( rStream, aLinebreak.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ // Rotation ab SO5
+ aRotateAngle.Store ( rStream, aRotateAngle.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+ aRotateMode.Store ( rStream, aRotateMode.GetVersion( SOFFICE_FILEFORMAT_40 ) );
+
+ // --- from 680/dr25 on: #21549# store strings as UTF-8
+ aNumFormat.Save( rStream, RTL_TEXTENCODING_UTF8 );
+
+ return (rStream.GetError() == 0);
+}
+
+
+// ---------------------------------------------------------------------------
+
+ScAutoFormatData::ScAutoFormatData()
+{
+ nStrResId = USHRT_MAX;
+
+ bIncludeValueFormat =
+ bIncludeFont =
+ bIncludeJustify =
+ bIncludeFrame =
+ bIncludeBackground =
+ bIncludeWidthHeight = TRUE;
+
+ ppDataField = new ScAutoFormatDataField*[ 16 ];
+ for( USHORT nIndex = 0; nIndex < 16; ++nIndex )
+ ppDataField[ nIndex ] = new ScAutoFormatDataField;
+}
+
+ScAutoFormatData::ScAutoFormatData( const ScAutoFormatData& rData ) :
+ ScDataObject(),
+ aName( rData.aName ),
+ nStrResId( rData.nStrResId ),
+ bIncludeFont( rData.bIncludeFont ),
+ bIncludeJustify( rData.bIncludeJustify ),
+ bIncludeFrame( rData.bIncludeFrame ),
+ bIncludeBackground( rData.bIncludeBackground ),
+ bIncludeValueFormat( rData.bIncludeValueFormat ),
+ bIncludeWidthHeight( rData.bIncludeWidthHeight )
+{
+ ppDataField = new ScAutoFormatDataField*[ 16 ];
+ for( USHORT nIndex = 0; nIndex < 16; ++nIndex )
+ ppDataField[ nIndex ] = new ScAutoFormatDataField( rData.GetField( nIndex ) );
+}
+
+ScAutoFormatData::~ScAutoFormatData()
+{
+ for( USHORT nIndex = 0; nIndex < 16; ++nIndex )
+ delete ppDataField[ nIndex ];
+ delete[] ppDataField;
+}
+
+ScAutoFormatDataField& ScAutoFormatData::GetField( USHORT nIndex )
+{
+ DBG_ASSERT( nIndex < 16, "ScAutoFormatData::GetField - illegal index" );
+ DBG_ASSERT( ppDataField && ppDataField[ nIndex ], "ScAutoFormatData::GetField - no data" );
+ return *ppDataField[ nIndex ];
+}
+
+const ScAutoFormatDataField& ScAutoFormatData::GetField( USHORT nIndex ) const
+{
+ DBG_ASSERT( nIndex < 16, "ScAutoFormatData::GetField - illegal index" );
+ DBG_ASSERT( ppDataField && ppDataField[ nIndex ], "ScAutoFormatData::GetField - no data" );
+ return *ppDataField[ nIndex ];
+}
+
+const SfxPoolItem* ScAutoFormatData::GetItem( USHORT nIndex, USHORT nWhich ) const
+{
+ const ScAutoFormatDataField& rField = GetField( nIndex );
+ switch( nWhich )
+ {
+ case ATTR_FONT: return &rField.GetFont();
+ case ATTR_FONT_HEIGHT: return &rField.GetHeight();
+ case ATTR_FONT_WEIGHT: return &rField.GetWeight();
+ case ATTR_FONT_POSTURE: return &rField.GetPosture();
+ case ATTR_CJK_FONT: return &rField.GetCJKFont();
+ case ATTR_CJK_FONT_HEIGHT: return &rField.GetCJKHeight();
+ case ATTR_CJK_FONT_WEIGHT: return &rField.GetCJKWeight();
+ case ATTR_CJK_FONT_POSTURE: return &rField.GetCJKPosture();
+ case ATTR_CTL_FONT: return &rField.GetCTLFont();
+ case ATTR_CTL_FONT_HEIGHT: return &rField.GetCTLHeight();
+ case ATTR_CTL_FONT_WEIGHT: return &rField.GetCTLWeight();
+ case ATTR_CTL_FONT_POSTURE: return &rField.GetCTLPosture();
+ case ATTR_FONT_UNDERLINE: return &rField.GetUnderline();
+ case ATTR_FONT_OVERLINE: return &rField.GetOverline();
+ case ATTR_FONT_CROSSEDOUT: return &rField.GetCrossedOut();
+ case ATTR_FONT_CONTOUR: return &rField.GetContour();
+ case ATTR_FONT_SHADOWED: return &rField.GetShadowed();
+ case ATTR_FONT_COLOR: return &rField.GetColor();
+ case ATTR_BORDER: return &rField.GetBox();
+ case ATTR_BORDER_TLBR: return &rField.GetTLBR();
+ case ATTR_BORDER_BLTR: return &rField.GetBLTR();
+ case ATTR_BACKGROUND: return &rField.GetBackground();
+ case ATTR_HOR_JUSTIFY: return &rField.GetHorJustify();
+ case ATTR_VER_JUSTIFY: return &rField.GetVerJustify();
+ case ATTR_STACKED: return &rField.GetStacked();
+ case ATTR_MARGIN: return &rField.GetMargin();
+ case ATTR_LINEBREAK: return &rField.GetLinebreak();
+ case ATTR_ROTATE_VALUE: return &rField.GetRotateAngle();
+ case ATTR_ROTATE_MODE: return &rField.GetRotateMode();
+ }
+ return NULL;
+}
+
+void ScAutoFormatData::PutItem( USHORT nIndex, const SfxPoolItem& rItem )
+{
+ ScAutoFormatDataField& rField = GetField( nIndex );
+ switch( rItem.Which() )
+ {
+ case ATTR_FONT: rField.SetFont( (const SvxFontItem&)rItem ); break;
+ case ATTR_FONT_HEIGHT: rField.SetHeight( (const SvxFontHeightItem&)rItem ); break;
+ case ATTR_FONT_WEIGHT: rField.SetWeight( (const SvxWeightItem&)rItem ); break;
+ case ATTR_FONT_POSTURE: rField.SetPosture( (const SvxPostureItem&)rItem ); break;
+ case ATTR_CJK_FONT: rField.SetCJKFont( (const SvxFontItem&)rItem ); break;
+ case ATTR_CJK_FONT_HEIGHT: rField.SetCJKHeight( (const SvxFontHeightItem&)rItem ); break;
+ case ATTR_CJK_FONT_WEIGHT: rField.SetCJKWeight( (const SvxWeightItem&)rItem ); break;
+ case ATTR_CJK_FONT_POSTURE: rField.SetCJKPosture( (const SvxPostureItem&)rItem ); break;
+ case ATTR_CTL_FONT: rField.SetCTLFont( (const SvxFontItem&)rItem ); break;
+ case ATTR_CTL_FONT_HEIGHT: rField.SetCTLHeight( (const SvxFontHeightItem&)rItem ); break;
+ case ATTR_CTL_FONT_WEIGHT: rField.SetCTLWeight( (const SvxWeightItem&)rItem ); break;
+ case ATTR_CTL_FONT_POSTURE: rField.SetCTLPosture( (const SvxPostureItem&)rItem ); break;
+ case ATTR_FONT_UNDERLINE: rField.SetUnderline( (const SvxUnderlineItem&)rItem ); break;
+ case ATTR_FONT_OVERLINE: rField.SetOverline( (const SvxOverlineItem&)rItem ); break;
+ case ATTR_FONT_CROSSEDOUT: rField.SetCrossedOut( (const SvxCrossedOutItem&)rItem ); break;
+ case ATTR_FONT_CONTOUR: rField.SetContour( (const SvxContourItem&)rItem ); break;
+ case ATTR_FONT_SHADOWED: rField.SetShadowed( (const SvxShadowedItem&)rItem ); break;
+ case ATTR_FONT_COLOR: rField.SetColor( (const SvxColorItem&)rItem ); break;
+ case ATTR_BORDER: rField.SetBox( (const SvxBoxItem&)rItem ); break;
+ case ATTR_BORDER_TLBR: rField.SetTLBR( (const SvxLineItem&)rItem ); break;
+ case ATTR_BORDER_BLTR: rField.SetBLTR( (const SvxLineItem&)rItem ); break;
+ case ATTR_BACKGROUND: rField.SetBackground( (const SvxBrushItem&)rItem ); break;
+ case ATTR_HOR_JUSTIFY: rField.SetHorJustify( (const SvxHorJustifyItem&)rItem ); break;
+ case ATTR_VER_JUSTIFY: rField.SetVerJustify( (const SvxVerJustifyItem&)rItem ); break;
+ case ATTR_STACKED: rField.SetStacked( (const SfxBoolItem&)rItem ); break;
+ case ATTR_MARGIN: rField.SetMargin( (const SvxMarginItem&)rItem ); break;
+ case ATTR_LINEBREAK: rField.SetLinebreak( (const SfxBoolItem&)rItem ); break;
+ case ATTR_ROTATE_VALUE: rField.SetRotateAngle( (const SfxInt32Item&)rItem ); break;
+ case ATTR_ROTATE_MODE: rField.SetRotateMode( (const SvxRotateModeItem&)rItem ); break;
+ }
+}
+
+void ScAutoFormatData::CopyItem( USHORT nToIndex, USHORT nFromIndex, USHORT nWhich )
+{
+ const SfxPoolItem* pItem = GetItem( nFromIndex, nWhich );
+ if( pItem )
+ PutItem( nToIndex, *pItem );
+}
+
+const ScNumFormatAbbrev& ScAutoFormatData::GetNumFormat( USHORT nIndex ) const
+{
+ return GetField( nIndex ).GetNumFormat();
+}
+
+BOOL ScAutoFormatData::IsEqualData( USHORT nIndex1, USHORT nIndex2 ) const
+{
+ BOOL bEqual = TRUE;
+ const ScAutoFormatDataField& rField1 = GetField( nIndex1 );
+ const ScAutoFormatDataField& rField2 = GetField( nIndex2 );
+
+ if( bIncludeValueFormat )
+ {
+ bEqual = bEqual
+ && (rField1.GetNumFormat() == rField2.GetNumFormat());
+ }
+ if( bIncludeFont )
+ {
+ bEqual = bEqual
+ && (rField1.GetFont() == rField2.GetFont())
+ && (rField1.GetHeight() == rField2.GetHeight())
+ && (rField1.GetWeight() == rField2.GetWeight())
+ && (rField1.GetPosture() == rField2.GetPosture())
+ && (rField1.GetCJKFont() == rField2.GetCJKFont())
+ && (rField1.GetCJKHeight() == rField2.GetCJKHeight())
+ && (rField1.GetCJKWeight() == rField2.GetCJKWeight())
+ && (rField1.GetCJKPosture() == rField2.GetCJKPosture())
+ && (rField1.GetCTLFont() == rField2.GetCTLFont())
+ && (rField1.GetCTLHeight() == rField2.GetCTLHeight())
+ && (rField1.GetCTLWeight() == rField2.GetCTLWeight())
+ && (rField1.GetCTLPosture() == rField2.GetCTLPosture())
+ && (rField1.GetUnderline() == rField2.GetUnderline())
+ && (rField1.GetOverline() == rField2.GetOverline())
+ && (rField1.GetCrossedOut() == rField2.GetCrossedOut())
+ && (rField1.GetContour() == rField2.GetContour())
+ && (rField1.GetShadowed() == rField2.GetShadowed())
+ && (rField1.GetColor() == rField2.GetColor());
+ }
+ if( bIncludeJustify )
+ {
+ bEqual = bEqual
+ && (rField1.GetHorJustify() == rField2.GetHorJustify())
+ && (rField1.GetVerJustify() == rField2.GetVerJustify())
+ && (rField1.GetStacked() == rField2.GetStacked())
+ && (rField1.GetLinebreak() == rField2.GetLinebreak())
+ && (rField1.GetMargin() == rField2.GetMargin())
+ && (rField1.GetRotateAngle() == rField2.GetRotateAngle())
+ && (rField1.GetRotateMode() == rField2.GetRotateMode());
+ }
+ if( bIncludeFrame )
+ {
+ bEqual = bEqual
+ && (rField1.GetBox() == rField2.GetBox())
+ && (rField1.GetTLBR() == rField2.GetTLBR())
+ && (rField1.GetBLTR() == rField2.GetBLTR());
+ }
+ if( bIncludeBackground )
+ {
+ bEqual = bEqual
+ && (rField1.GetBackground() == rField2.GetBackground());
+ }
+ return bEqual;
+}
+
+void ScAutoFormatData::FillToItemSet( USHORT nIndex, SfxItemSet& rItemSet, ScDocument& rDoc ) const
+{
+ const ScAutoFormatDataField& rField = GetField( nIndex );
+
+ if( bIncludeValueFormat )
+ {
+ ScNumFormatAbbrev& rNumFormat = (ScNumFormatAbbrev&)rField.GetNumFormat();
+ SfxUInt32Item aValueFormat( ATTR_VALUE_FORMAT, 0 );
+ aValueFormat.SetValue( rNumFormat.GetFormatIndex( *rDoc.GetFormatTable() ) );
+ rItemSet.Put( aValueFormat );
+ rItemSet.Put( SvxLanguageItem( rNumFormat.GetLanguage(), ATTR_LANGUAGE_FORMAT ) );
+ }
+ if( bIncludeFont )
+ {
+ rItemSet.Put( rField.GetFont() );
+ rItemSet.Put( rField.GetHeight() );
+ rItemSet.Put( rField.GetWeight() );
+ rItemSet.Put( rField.GetPosture() );
+ // #103065# do not insert empty CJK font
+ const SvxFontItem& rCJKFont = rField.GetCJKFont();
+ if( rCJKFont.GetStyleName().Len() )
+ {
+ rItemSet.Put( rCJKFont );
+ rItemSet.Put( rField.GetCJKHeight() );
+ rItemSet.Put( rField.GetCJKWeight() );
+ rItemSet.Put( rField.GetCJKPosture() );
+ }
+ else
+ {
+ rItemSet.Put( rField.GetHeight(), ATTR_CJK_FONT_HEIGHT );
+ rItemSet.Put( rField.GetWeight(), ATTR_CJK_FONT_WEIGHT );
+ rItemSet.Put( rField.GetPosture(), ATTR_CJK_FONT_POSTURE );
+ }
+ // #103065# do not insert empty CTL font
+ const SvxFontItem& rCTLFont = rField.GetCTLFont();
+ if( rCTLFont.GetStyleName().Len() )
+ {
+ rItemSet.Put( rCTLFont );
+ rItemSet.Put( rField.GetCTLHeight() );
+ rItemSet.Put( rField.GetCTLWeight() );
+ rItemSet.Put( rField.GetCTLPosture() );
+ }
+ else
+ {
+ rItemSet.Put( rField.GetHeight(), ATTR_CTL_FONT_HEIGHT );
+ rItemSet.Put( rField.GetWeight(), ATTR_CTL_FONT_WEIGHT );
+ rItemSet.Put( rField.GetPosture(), ATTR_CTL_FONT_POSTURE );
+ }
+ rItemSet.Put( rField.GetUnderline() );
+ rItemSet.Put( rField.GetOverline() );
+ rItemSet.Put( rField.GetCrossedOut() );
+ rItemSet.Put( rField.GetContour() );
+ rItemSet.Put( rField.GetShadowed() );
+ rItemSet.Put( rField.GetColor() );
+ }
+ if( bIncludeJustify )
+ {
+ rItemSet.Put( rField.GetHorJustify() );
+ rItemSet.Put( rField.GetVerJustify() );
+ rItemSet.Put( rField.GetStacked() );
+ rItemSet.Put( rField.GetLinebreak() );
+ rItemSet.Put( rField.GetMargin() );
+ rItemSet.Put( rField.GetRotateAngle() );
+ rItemSet.Put( rField.GetRotateMode() );
+ }
+ if( bIncludeFrame )
+ {
+ rItemSet.Put( rField.GetBox() );
+ rItemSet.Put( rField.GetTLBR() );
+ rItemSet.Put( rField.GetBLTR() );
+ }
+ if( bIncludeBackground )
+ rItemSet.Put( rField.GetBackground() );
+}
+
+void ScAutoFormatData::GetFromItemSet( USHORT nIndex, const SfxItemSet& rItemSet, const ScNumFormatAbbrev& rNumFormat )
+{
+ ScAutoFormatDataField& rField = GetField( nIndex );
+
+ rField.SetNumFormat ( rNumFormat);
+ rField.SetFont ( (const SvxFontItem&) rItemSet.Get( ATTR_FONT ) );
+ rField.SetHeight ( (const SvxFontHeightItem&) rItemSet.Get( ATTR_FONT_HEIGHT ) );
+ rField.SetWeight ( (const SvxWeightItem&) rItemSet.Get( ATTR_FONT_WEIGHT ) );
+ rField.SetPosture ( (const SvxPostureItem&) rItemSet.Get( ATTR_FONT_POSTURE ) );
+ rField.SetCJKFont ( (const SvxFontItem&) rItemSet.Get( ATTR_CJK_FONT ) );
+ rField.SetCJKHeight ( (const SvxFontHeightItem&) rItemSet.Get( ATTR_CJK_FONT_HEIGHT ) );
+ rField.SetCJKWeight ( (const SvxWeightItem&) rItemSet.Get( ATTR_CJK_FONT_WEIGHT ) );
+ rField.SetCJKPosture ( (const SvxPostureItem&) rItemSet.Get( ATTR_CJK_FONT_POSTURE ) );
+ rField.SetCTLFont ( (const SvxFontItem&) rItemSet.Get( ATTR_CTL_FONT ) );
+ rField.SetCTLHeight ( (const SvxFontHeightItem&) rItemSet.Get( ATTR_CTL_FONT_HEIGHT ) );
+ rField.SetCTLWeight ( (const SvxWeightItem&) rItemSet.Get( ATTR_CTL_FONT_WEIGHT ) );
+ rField.SetCTLPosture ( (const SvxPostureItem&) rItemSet.Get( ATTR_CTL_FONT_POSTURE ) );
+ rField.SetUnderline ( (const SvxUnderlineItem&) rItemSet.Get( ATTR_FONT_UNDERLINE ) );
+ rField.SetOverline ( (const SvxOverlineItem&) rItemSet.Get( ATTR_FONT_OVERLINE ) );
+ rField.SetCrossedOut ( (const SvxCrossedOutItem&) rItemSet.Get( ATTR_FONT_CROSSEDOUT ) );
+ rField.SetContour ( (const SvxContourItem&) rItemSet.Get( ATTR_FONT_CONTOUR ) );
+ rField.SetShadowed ( (const SvxShadowedItem&) rItemSet.Get( ATTR_FONT_SHADOWED ) );
+ rField.SetColor ( (const SvxColorItem&) rItemSet.Get( ATTR_FONT_COLOR ) );
+ rField.SetTLBR ( (const SvxLineItem&) rItemSet.Get( ATTR_BORDER_TLBR ) );
+ rField.SetBLTR ( (const SvxLineItem&) rItemSet.Get( ATTR_BORDER_BLTR ) );
+ rField.SetHorJustify ( (const SvxHorJustifyItem&) rItemSet.Get( ATTR_HOR_JUSTIFY ) );
+ rField.SetVerJustify ( (const SvxVerJustifyItem&) rItemSet.Get( ATTR_VER_JUSTIFY ) );
+ rField.SetStacked ( (const SfxBoolItem&) rItemSet.Get( ATTR_STACKED ) );
+ rField.SetLinebreak ( (const SfxBoolItem&) rItemSet.Get( ATTR_LINEBREAK ) );
+ rField.SetMargin ( (const SvxMarginItem&) rItemSet.Get( ATTR_MARGIN ) );
+ rField.SetBackground ( (const SvxBrushItem&) rItemSet.Get( ATTR_BACKGROUND ) );
+ rField.SetRotateAngle ( (const SfxInt32Item&) rItemSet.Get( ATTR_ROTATE_VALUE ) );
+ rField.SetRotateMode ( (const SvxRotateModeItem&) rItemSet.Get( ATTR_ROTATE_MODE ) );
+}
+
+BOOL ScAutoFormatData::Load( SvStream& rStream, const ScAfVersions& rVersions )
+{
+ BOOL bRet = TRUE;
+ USHORT nVer = 0;
+ rStream >> nVer;
+ bRet = 0 == rStream.GetError();
+ if( bRet && (nVer == AUTOFORMAT_DATA_ID_X ||
+ (AUTOFORMAT_DATA_ID_504 <= nVer && nVer <= AUTOFORMAT_DATA_ID)) )
+ {
+ // --- from 680/dr25 on: #21549# store strings as UTF-8
+ CharSet eCharSet = (nVer >= AUTOFORMAT_ID_680DR25) ? RTL_TEXTENCODING_UTF8 : rStream.GetStreamCharSet();
+ rStream.ReadByteString( aName, eCharSet );
+ if( AUTOFORMAT_DATA_ID_552 <= nVer )
+ {
+ rStream >> nStrResId;
+ USHORT nId = RID_SVXSTR_TBLAFMT_BEGIN + nStrResId;
+ if( RID_SVXSTR_TBLAFMT_BEGIN <= nId &&
+ nId < RID_SVXSTR_TBLAFMT_END )
+ {
+ aName = SVX_RESSTR( nId );
+ }
+ else
+ nStrResId = USHRT_MAX;
+ }
+
+ BOOL b;
+ rStream >> b; bIncludeFont = b;
+ rStream >> b; bIncludeJustify = b;
+ rStream >> b; bIncludeFrame = b;
+ rStream >> b; bIncludeBackground = b;
+ rStream >> b; bIncludeValueFormat = b;
+ rStream >> b; bIncludeWidthHeight = b;
+
+ bRet = 0 == rStream.GetError();
+ for( USHORT i = 0; bRet && i < 16; ++i )
+ bRet = GetField( i ).Load( rStream, rVersions, nVer );
+ }
+ else
+ bRet = FALSE;
+ return bRet;
+}
+
+#ifdef READ_OLDVERS
+BOOL ScAutoFormatData::LoadOld( SvStream& rStream, const ScAfVersions& rVersions )
+{
+ BOOL bRet = TRUE;
+ USHORT nVal = 0;
+ rStream >> nVal;
+ bRet = (rStream.GetError() == 0);
+ if (bRet && (nVal == AUTOFORMAT_OLD_DATA_ID))
+ {
+ rStream.ReadByteString( aName, rStream.GetStreamCharSet() );
+ BOOL b;
+ rStream >> b; bIncludeFont = b;
+ rStream >> b; bIncludeJustify = b;
+ rStream >> b; bIncludeFrame = b;
+ rStream >> b; bIncludeBackground = b;
+ rStream >> b; bIncludeValueFormat = b;
+ rStream >> b; bIncludeWidthHeight = b;
+
+ bRet = 0 == rStream.GetError();
+ for (USHORT i=0; bRet && i < 16; i++)
+ bRet = GetField( i ).LoadOld( rStream, rVersions );
+ }
+ else
+ bRet = FALSE;
+ return bRet;
+}
+#endif
+
+BOOL ScAutoFormatData::Save(SvStream& rStream)
+{
+ USHORT nVal = AUTOFORMAT_DATA_ID;
+ BOOL b;
+ rStream << nVal;
+ // --- from 680/dr25 on: #21549# store strings as UTF-8
+ rStream.WriteByteString( aName, RTL_TEXTENCODING_UTF8 );
+
+#if 0
+ // This was an internal flag to allow creating AutoFormats with localized names
+
+ if ( USHRT_MAX == nStrResId )
+ {
+ String aIniVal( SFX_APP()->GetIniManager()->Get(
+ SFX_GROUP_WORKINGSET_IMPL,
+ String( RTL_CONSTASCII_USTRINGPARAM( "SaveTableAutoFmtNameId" ))));
+ if( 0 != aIniVal.ToInt32() )
+ {
+ // check Name for ResId
+ for( USHORT nId = RID_SVXSTR_TBLAFMT_BEGIN;
+ RID_SVXSTR_TBLAFMT_END > nId; ++nId )
+ {
+ String s( SVX_RES( nId ) );
+ if( s == aName )
+ {
+ nStrResId = nId - RID_SVXSTR_TBLAFMT_BEGIN;
+ break;
+ }
+ }
+ }
+ }
+#endif
+
+ rStream << nStrResId;
+ rStream << ( b = bIncludeFont );
+ rStream << ( b = bIncludeJustify );
+ rStream << ( b = bIncludeFrame );
+ rStream << ( b = bIncludeBackground );
+ rStream << ( b = bIncludeValueFormat );
+ rStream << ( b = bIncludeWidthHeight );
+
+ BOOL bRet = 0 == rStream.GetError();
+ for (USHORT i = 0; bRet && (i < 16); i++)
+ bRet = GetField( i ).Save( rStream );
+
+ return bRet;
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+ScAutoFormat::ScAutoFormat(USHORT nLim, USHORT nDel, BOOL bDup):
+ ScSortedCollection (nLim, nDel, bDup),
+ bSaveLater (FALSE)
+{
+ // create default autoformat
+ ScAutoFormatData* pData = new ScAutoFormatData;
+ String aName(ScGlobal::GetRscString(STR_STYLENAME_STANDARD));
+ pData->SetName(aName);
+
+ // default font, default height
+ Font aStdFont = OutputDevice::GetDefaultFont(
+ DEFAULTFONT_LATIN_SPREADSHEET, LANGUAGE_ENGLISH_US, DEFAULTFONT_FLAGS_ONLYONE );
+ SvxFontItem aFontItem(
+ aStdFont.GetFamily(), aStdFont.GetName(), aStdFont.GetStyleName(),
+ aStdFont.GetPitch(), aStdFont.GetCharSet(), ATTR_FONT );
+
+ aStdFont = OutputDevice::GetDefaultFont(
+ DEFAULTFONT_CJK_SPREADSHEET, LANGUAGE_ENGLISH_US, DEFAULTFONT_FLAGS_ONLYONE );
+ SvxFontItem aCJKFontItem(
+ aStdFont.GetFamily(), aStdFont.GetName(), aStdFont.GetStyleName(),
+ aStdFont.GetPitch(), aStdFont.GetCharSet(), ATTR_CJK_FONT );
+
+ aStdFont = OutputDevice::GetDefaultFont(
+ DEFAULTFONT_CTL_SPREADSHEET, LANGUAGE_ENGLISH_US, DEFAULTFONT_FLAGS_ONLYONE );
+ SvxFontItem aCTLFontItem(
+ aStdFont.GetFamily(), aStdFont.GetName(), aStdFont.GetStyleName(),
+ aStdFont.GetPitch(), aStdFont.GetCharSet(), ATTR_CTL_FONT );
+
+ SvxFontHeightItem aHeight( 200, 100, ATTR_FONT_HEIGHT ); // 10 pt;
+
+ // black thin border
+ Color aBlack( COL_BLACK );
+ SvxBorderLine aLine( &aBlack, DEF_LINE_WIDTH_0 );
+ SvxBoxItem aBox( ATTR_BORDER );
+ aBox.SetLine(&aLine, BOX_LINE_LEFT);
+ aBox.SetLine(&aLine, BOX_LINE_TOP);
+ aBox.SetLine(&aLine, BOX_LINE_RIGHT);
+ aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
+
+ Color aWhite(COL_WHITE);
+ Color aBlue(COL_BLUE);
+ SvxColorItem aWhiteText( aWhite, ATTR_FONT_COLOR );
+ SvxColorItem aBlackText( aBlack, ATTR_FONT_COLOR );
+ SvxBrushItem aBlueBack( aBlue, ATTR_BACKGROUND );
+ SvxBrushItem aWhiteBack( aWhite, ATTR_BACKGROUND );
+ SvxBrushItem aGray70Back( Color(0x4d, 0x4d, 0x4d), ATTR_BACKGROUND );
+ SvxBrushItem aGray20Back( Color(0xcc, 0xcc, 0xcc), ATTR_BACKGROUND );
+
+ for (USHORT i=0; i<16; i++)
+ {
+ pData->PutItem( i, aBox );
+ pData->PutItem( i, aFontItem );
+ pData->PutItem( i, aCJKFontItem );
+ pData->PutItem( i, aCTLFontItem );
+ aHeight.SetWhich( ATTR_FONT_HEIGHT );
+ pData->PutItem( i, aHeight );
+ aHeight.SetWhich( ATTR_CJK_FONT_HEIGHT );
+ pData->PutItem( i, aHeight );
+ aHeight.SetWhich( ATTR_CTL_FONT_HEIGHT );
+ pData->PutItem( i, aHeight );
+ if (i<4) // top: white on blue
+ {
+ pData->PutItem( i, aWhiteText );
+ pData->PutItem( i, aBlueBack );
+ }
+ else if ( i%4 == 0 ) // left: white on gray70
+ {
+ pData->PutItem( i, aWhiteText );
+ pData->PutItem( i, aGray70Back );
+ }
+ else if ( i%4 == 3 || i >= 12 ) // right and bottom: black on gray20
+ {
+ pData->PutItem( i, aBlackText );
+ pData->PutItem( i, aGray20Back );
+ }
+ else // center: black on white
+ {
+ pData->PutItem( i, aBlackText );
+ pData->PutItem( i, aWhiteBack );
+ }
+ }
+
+ Insert(pData);
+}
+
+ScAutoFormat::ScAutoFormat(const ScAutoFormat& rAutoFormat) :
+ ScSortedCollection (rAutoFormat),
+ bSaveLater (FALSE)
+{}
+
+ScAutoFormat::~ScAutoFormat()
+{
+ // Bei Aenderungen per StarOne wird nicht sofort gespeichert, sondern zuerst nur
+ // das SaveLater Flag gesetzt. Wenn das Flag noch gesetzt ist, jetzt speichern.
+
+ if (bSaveLater)
+ Save();
+}
+
+void ScAutoFormat::SetSaveLater( BOOL bSet )
+{
+ bSaveLater = bSet;
+}
+
+short ScAutoFormat::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ String aStr1;
+ String aStr2;
+ ((ScAutoFormatData*)pKey1)->GetName(aStr1);
+ ((ScAutoFormatData*)pKey2)->GetName(aStr2);
+ String aStrStandard = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
+ if ( ScGlobal::GetpTransliteration()->isEqual( aStr1, aStrStandard ) )
+ return -1;
+ if ( ScGlobal::GetpTransliteration()->isEqual( aStr2, aStrStandard ) )
+ return 1;
+ return (short) ScGlobal::GetpTransliteration()->compareString( aStr1, aStr2 );
+}
+
+BOOL ScAutoFormat::Load()
+{
+ BOOL bRet = TRUE;
+
+ INetURLObject aURL;
+ SvtPathOptions aPathOpt;
+ aURL.SetSmartURL( aPathOpt.GetUserConfigPath() );
+ aURL.setFinalSlash();
+ aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM( sAutoTblFmtName ) ) );
+
+ SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_READ, TRUE );
+ SvStream* pStream = aMedium.GetInStream();
+ bRet = (pStream && pStream->GetError() == 0);
+ if (bRet)
+ {
+ SvStream& rStream = *pStream;
+ // Achtung hier muss ein allgemeiner Header gelesen werden
+ USHORT nVal = 0;
+ rStream >> nVal;
+ bRet = 0 == rStream.GetError();
+
+ ScAfVersions aVersions;
+
+ if (bRet)
+ {
+ if( nVal == AUTOFORMAT_ID_358 ||
+ (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) )
+ {
+ UINT16 nFileVers = SOFFICE_FILEFORMAT_40;
+ BYTE nChrSet, nCnt;
+ long nPos = rStream.Tell();
+ rStream >> nCnt >> nChrSet;
+// if( 4 <= nCnt )
+// rStream >> nFileVers;
+ if( rStream.Tell() != ULONG(nPos + nCnt) )
+ {
+ DBG_ERRORFILE( "Der Header enthaelt mehr/neuere Daten" );
+ rStream.Seek( nPos + nCnt );
+ }
+ rStream.SetStreamCharSet( GetSOLoadTextEncoding( nChrSet, nFileVers ) );
+ rStream.SetVersion( nFileVers );
+ }
+
+ if( nVal == AUTOFORMAT_ID_358 || nVal == AUTOFORMAT_ID_X ||
+ (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) )
+ {
+ aVersions.Load( rStream, nVal ); // Item-Versionen
+
+ ScAutoFormatData* pData;
+ USHORT nAnz = 0;
+ rStream >> nAnz;
+ bRet = (rStream.GetError() == 0);
+ for (USHORT i=0; bRet && (i < nAnz); i++)
+ {
+ pData = new ScAutoFormatData();
+ bRet = pData->Load(rStream, aVersions);
+ Insert(pData);
+ }
+ }
+#ifdef READ_OLDVERS
+ else
+ {
+ if( AUTOFORMAT_OLD_ID_NEW == nVal )
+ {
+ // alte Version der Versions laden
+ rStream >> aVersions.nFontVersion;
+ rStream >> aVersions.nFontHeightVersion;
+ rStream >> aVersions.nWeightVersion;
+ rStream >> aVersions.nPostureVersion;
+ rStream >> aVersions.nUnderlineVersion;
+ rStream >> aVersions.nCrossedOutVersion;
+ rStream >> aVersions.nContourVersion;
+ rStream >> aVersions.nShadowedVersion;
+ rStream >> aVersions.nColorVersion;
+ rStream >> aVersions.nHorJustifyVersion;
+ rStream >> aVersions.nVerJustifyVersion;
+ rStream >> aVersions.nOrientationVersion;
+ rStream >> aVersions.nBoolVersion;
+ rStream >> aVersions.nMarginVersion;
+ rStream >> aVersions.nBoxVersion;
+ rStream >> aVersions.nBrushVersion;
+ }
+ if( AUTOFORMAT_OLD_ID_OLD == nVal ||
+ AUTOFORMAT_OLD_ID_NEW == nVal )
+ {
+ ScAutoFormatData* pData;
+ USHORT nAnz = 0;
+ rStream >> nAnz;
+ bRet = 0 == rStream.GetError();
+ for( USHORT i=0; bRet && (i < nAnz); ++i )
+ {
+ pData = new ScAutoFormatData();
+ bRet = pData->LoadOld( rStream, aVersions );
+ Insert( pData );
+ }
+ }
+ else
+ bRet = FALSE;
+ }
+#endif
+ }
+ }
+ bSaveLater = FALSE;
+ return bRet;
+}
+
+BOOL ScAutoFormat::Save()
+{
+ BOOL bRet = TRUE;
+
+ INetURLObject aURL;
+ SvtPathOptions aPathOpt;
+ aURL.SetSmartURL( aPathOpt.GetUserConfigPath() );
+ aURL.setFinalSlash();
+ aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM( sAutoTblFmtName ) ) );
+
+ SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_WRITE, TRUE );
+ SvStream* pStream = aMedium.GetOutStream();
+ bRet = (pStream && pStream->GetError() == 0);
+ if (bRet)
+ {
+ SvStream& rStream = *pStream;
+ rStream.SetVersion( SOFFICE_FILEFORMAT_40 );
+
+ // Achtung hier muss ein allgemeiner Header gespeichert werden
+ USHORT nVal = AUTOFORMAT_ID;
+ rStream << nVal
+ << (BYTE)2 // Anzahl von Zeichen des Headers incl. diesem
+ << (BYTE)::GetSOStoreTextEncoding(
+ gsl_getSystemTextEncoding(), sal::static_int_cast<USHORT>(rStream.GetVersion()) );
+// << (BYTE)4 // Anzahl von Zeichen des Headers incl. diesem
+// << (BYTE)::GetStoreCharSet(::GetSystemCharSet())
+// << (UNIT16)SOFFICE_FILEFORMAT_NOW;
+ ScAfVersions::Write(rStream); // Item-Versionen
+
+ bRet = (rStream.GetError() == 0);
+ //-----------------------------------------------------------
+ rStream << (USHORT)(nCount - 1);
+ bRet = (rStream.GetError() == 0);
+ for (USHORT i=1; bRet && (i < nCount); i++)
+ bRet = ((ScAutoFormatData*)pItems[i])->Save(rStream);
+ rStream.Flush();
+
+ aMedium.Commit();
+ }
+ bSaveLater = FALSE;
+ return bRet;
+}
+
+USHORT ScAutoFormat::FindIndexPerName( const String& rName ) const
+{
+ String aName;
+
+ for( USHORT i=0; i<nCount ; i++ )
+ {
+ ScAutoFormatData* pItem = (ScAutoFormatData*)pItems[i];
+ pItem->GetName( aName );
+
+ if( aName == rName )
+ return i;
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/sc/source/core/tool/callform.cxx b/sc/source/core/tool/callform.cxx
new file mode 100644
index 000000000000..e8e2b28f3f8e
--- /dev/null
+++ b/sc/source/core/tool/callform.cxx
@@ -0,0 +1,469 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+#include <osl/module.hxx>
+#include <osl/file.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "callform.hxx"
+#include "global.hxx"
+#include "adiasync.hxx"
+
+//------------------------------------------------------------------------
+
+extern "C" {
+
+typedef void (CALLTYPE* ExFuncPtr1)(void*);
+typedef void (CALLTYPE* ExFuncPtr2)(void*, void*);
+typedef void (CALLTYPE* ExFuncPtr3)(void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr4)(void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr5)(void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr6)(void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr7)(void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr8)(void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr9)(void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef void (CALLTYPE* ExFuncPtr16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+
+typedef void (CALLTYPE* GetFuncCountPtr)(USHORT& nCount);
+typedef void (CALLTYPE* GetFuncDataPtr)
+ (USHORT& nNo, sal_Char* pFuncName, USHORT& nParamCount, ParamType* peType, sal_Char* pInternalName);
+
+typedef void (CALLTYPE* SetLanguagePtr)( USHORT& nLanguage );
+typedef void (CALLTYPE* GetParamDesc)
+ (USHORT& nNo, USHORT& nParam, sal_Char* pName, sal_Char* pDesc );
+
+typedef void (CALLTYPE* IsAsync) ( USHORT& nNo,
+ ParamType* peType );
+typedef void (CALLTYPE* Advice) ( USHORT& nNo,
+ AdvData& pfCallback );
+typedef void (CALLTYPE* Unadvice)( double& nHandle );
+
+typedef void (CALLTYPE* FARPROC) ( void );
+
+}
+
+#if defined(OS2) && defined(BLC)
+#define GETFUNCTIONCOUNT "_GetFunctionCount"
+#define GETFUNCTIONDATA "_GetFunctionData"
+#define SETLANGUAGE "_SetLanguage"
+#define GETPARAMDESC "_GetParameterDescription"
+#define ISASYNC "_IsAsync"
+#define ADVICE "_Advice"
+#define UNADVICE "_Unadvice"
+#else // Pascal oder extern "C"
+#define GETFUNCTIONCOUNT "GetFunctionCount"
+#define GETFUNCTIONDATA "GetFunctionData"
+#define SETLANGUAGE "SetLanguage"
+#define GETPARAMDESC "GetParameterDescription"
+#define ISASYNC "IsAsync"
+#define ADVICE "Advice"
+#define UNADVICE "Unadvice"
+#endif
+
+#define LIBFUNCNAME( name ) \
+ (String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( name ) ))
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+FuncData::FuncData(const String& rIName) :
+ pModuleData (NULL),
+ aInternalName (rIName),
+// aFuncName (""),
+ nNumber (0),
+ nParamCount (0),
+ eAsyncType (NONE)
+{
+ for (USHORT i = 0; i < MAXFUNCPARAM; i++)
+ eParamType[i] = PTR_DOUBLE;
+}
+
+//------------------------------------------------------------------------
+
+FuncData::FuncData(const ModuleData*pModule,
+ const String& rIName,
+ const String& rFName,
+ USHORT nNo,
+ USHORT nCount,
+ const ParamType* peType,
+ ParamType eType) :
+ pModuleData (pModule),
+ aInternalName (rIName),
+ aFuncName (rFName),
+ nNumber (nNo),
+ nParamCount (nCount),
+ eAsyncType (eType)
+{
+ for (USHORT i = 0; i < MAXFUNCPARAM; i++)
+ eParamType[i] = peType[i];
+}
+
+//------------------------------------------------------------------------
+
+FuncData::FuncData(const FuncData& rData) :
+ ScDataObject(),
+ pModuleData (rData.pModuleData),
+ aInternalName (rData.aInternalName),
+ aFuncName (rData.aFuncName),
+ nNumber (rData.nNumber),
+ nParamCount (rData.nParamCount),
+ eAsyncType (rData.eAsyncType)
+{
+ for (USHORT i = 0; i < MAXFUNCPARAM; i++)
+ eParamType[i] = rData.eParamType[i];
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+short FuncCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return (short) ScGlobal::GetpTransliteration()->compareString(
+ ((FuncData*)pKey1)->aInternalName, ((FuncData*)pKey2)->aInternalName );
+}
+
+//------------------------------------------------------------------------
+
+BOOL FuncCollection::SearchFunc( const String& rName, USHORT& rIndex ) const
+{
+ FuncData aDataObj(rName);
+ return Search( &aDataObj, rIndex );
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class ModuleData : public ScDataObject
+{
+friend class ModuleCollection;
+ String aName;
+ osl::Module* pInstance;
+public:
+ ModuleData(const String& rStr, osl::Module* pInst) : aName (rStr), pInstance (pInst) {}
+ ModuleData(const ModuleData& rData) : ScDataObject(), aName (rData.aName) {pInstance = new osl::Module(aName);}
+ ~ModuleData() { delete pInstance; }
+ virtual ScDataObject* Clone() const { return new ModuleData(*this); }
+
+ const String& GetName() const { return aName; }
+ osl::Module* GetInstance() const { return pInstance; }
+ void FreeInstance() { delete pInstance; pInstance = 0; }
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class ModuleCollection : public ScSortedCollection
+{
+public:
+ ModuleCollection(USHORT nLim = 4, USHORT nDel = 4, BOOL bDup = FALSE) : ScSortedCollection ( nLim, nDel, bDup ) {}
+ ModuleCollection(const ModuleCollection& rModuleCollection) : ScSortedCollection ( rModuleCollection ) {}
+
+ virtual ScDataObject* Clone() const { return new ModuleCollection(*this); }
+ ModuleData* operator[]( const USHORT nIndex) const {return (ModuleData*)At(nIndex);}
+ virtual short Compare(ScDataObject* pKey1, ScDataObject* pKey2) const;
+ BOOL SearchModule( const String& rName,
+ const ModuleData*& rpModule ) const;
+};
+
+static ModuleCollection aModuleCollection;
+
+//------------------------------------------------------------------------
+
+short ModuleCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return (short) ScGlobal::GetpTransliteration()->compareString(
+ ((ModuleData*)pKey1)->aName, ((ModuleData*)pKey2)->aName );
+}
+
+//------------------------------------------------------------------------
+
+BOOL ModuleCollection::SearchModule( const String& rName,
+ const ModuleData*& rpModule ) const
+{
+ USHORT nIndex;
+ ModuleData aSearchModule(rName, 0);
+ BOOL bFound = Search( &aSearchModule, nIndex );
+ if (bFound)
+ rpModule = (ModuleData*)At(nIndex);
+ else
+ rpModule = 0;
+ return bFound;
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+BOOL InitExternalFunc(const rtl::OUString& rModuleName)
+{
+ String aModuleName( rModuleName );
+
+ // Module schon geladen?
+ const ModuleData* pTemp;
+ if (aModuleCollection.SearchModule(aModuleName, pTemp))
+ return FALSE;
+
+ rtl::OUString aNP;
+ aNP = rModuleName;
+
+ BOOL bRet = FALSE;
+ osl::Module* pLib = new osl::Module( aNP );
+ if (pLib->is())
+ {
+ FARPROC fpGetCount = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONCOUNT));
+ FARPROC fpGetData = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONDATA));
+ if ((fpGetCount != NULL) && (fpGetData != NULL))
+ {
+ FARPROC fpIsAsync = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ISASYNC));
+ FARPROC fpAdvice = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ADVICE));
+ FARPROC fpSetLanguage = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(SETLANGUAGE));
+ if ( fpSetLanguage )
+ {
+ LanguageType eLanguage = Application::GetSettings().GetUILanguage();
+ USHORT nLanguage = (USHORT) eLanguage;
+ (*((SetLanguagePtr)fpSetLanguage))( nLanguage );
+ }
+
+ // Module in die Collection aufnehmen
+ ModuleData* pModuleData = new ModuleData(aModuleName, pLib);
+ aModuleCollection.Insert(pModuleData);
+
+ // Schnittstelle initialisieren
+ AdvData pfCallBack = &ScAddInAsyncCallBack;
+ FuncData* pFuncData;
+ FuncCollection* pFuncCol = ScGlobal::GetFuncCollection();
+ USHORT nCount;
+ (*((GetFuncCountPtr)fpGetCount))(nCount);
+ for (USHORT i=0; i < nCount; i++)
+ {
+ sal_Char cFuncName[256];
+ sal_Char cInternalName[256];
+ USHORT nParamCount;
+ ParamType eParamType[MAXFUNCPARAM];
+ ParamType eAsyncType = NONE;
+ // #62113# alles initialisieren, falls das AddIn sich schlecht verhaelt
+ cFuncName[0] = 0;
+ cInternalName[0] = 0;
+ nParamCount = 0;
+ for ( USHORT j=0; j<MAXFUNCPARAM; j++ )
+ {
+ eParamType[j] = NONE;
+ }
+ (*((GetFuncDataPtr)fpGetData))(i, cFuncName, nParamCount,
+ eParamType, cInternalName);
+ if( fpIsAsync )
+ {
+ (*((IsAsync)fpIsAsync))(i, &eAsyncType);
+ if ( fpAdvice && eAsyncType != NONE )
+ (*((Advice)fpAdvice))( i, pfCallBack );
+ }
+ String aInternalName( cInternalName, osl_getThreadTextEncoding() );
+ String aFuncName( cFuncName, osl_getThreadTextEncoding() );
+ pFuncData = new FuncData( pModuleData,
+ aInternalName,
+ aFuncName,
+ i,
+ nParamCount,
+ eParamType,
+ eAsyncType );
+ pFuncCol->Insert(pFuncData);
+ }
+ bRet = TRUE;
+ }
+ else
+ delete pLib;
+ }
+ else
+ delete pLib;
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+void ExitExternalFunc()
+{
+ USHORT nCount = aModuleCollection.GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ModuleData* pData = aModuleCollection[i];
+ pData->FreeInstance();
+ }
+}
+
+//------------------------------------------------------------------------
+
+BOOL FuncData::Call(void** ppParam)
+{
+ BOOL bRet = FALSE;
+ osl::Module* pLib = pModuleData->GetInstance();
+ FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(aFuncName);
+ if (fProc != NULL)
+ {
+ switch (nParamCount)
+ {
+ case 1 :
+ (*((ExFuncPtr1)fProc))(ppParam[0]);
+ bRet = TRUE;
+ break;
+ case 2 :
+ (*((ExFuncPtr2)fProc))(ppParam[0], ppParam[1]);
+ bRet = TRUE;
+ break;
+ case 3 :
+ (*((ExFuncPtr3)fProc))(ppParam[0], ppParam[1], ppParam[2]);
+ bRet = TRUE;
+ break;
+ case 4 :
+ (*((ExFuncPtr4)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]);
+ bRet = TRUE;
+ break;
+ case 5 :
+ (*((ExFuncPtr5)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]);
+ bRet = TRUE;
+ break;
+ case 6 :
+ (*((ExFuncPtr6)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]);
+ bRet = TRUE;
+ break;
+ case 7 :
+ (*((ExFuncPtr7)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6]);
+ bRet = TRUE;
+ break;
+ case 8 :
+ (*((ExFuncPtr8)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7]);
+ bRet = TRUE;
+ break;
+ case 9 :
+ (*((ExFuncPtr9)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8]);
+ bRet = TRUE;
+ break;
+ case 10 :
+ (*((ExFuncPtr10)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9]);
+ bRet = TRUE;
+ break;
+ case 11 :
+ (*((ExFuncPtr11)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]);
+ bRet = TRUE;
+ break;
+ case 12:
+ (*((ExFuncPtr12)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]);
+ bRet = TRUE;
+ break;
+ case 13:
+ (*((ExFuncPtr13)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
+ ppParam[12]);
+ bRet = TRUE;
+ break;
+ case 14 :
+ (*((ExFuncPtr14)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
+ ppParam[12], ppParam[13]);
+ bRet = TRUE;
+ break;
+ case 15 :
+ (*((ExFuncPtr15)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
+ ppParam[12], ppParam[13], ppParam[14]);
+ bRet = TRUE;
+ break;
+ case 16 :
+ (*((ExFuncPtr16)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
+ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
+ ppParam[12], ppParam[13], ppParam[14], ppParam[15]);
+ bRet = TRUE;
+ break;
+ default : break;
+ }
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+BOOL FuncData::Unadvice( double nHandle )
+{
+ BOOL bRet = FALSE;
+ osl::Module* pLib = pModuleData->GetInstance();
+ FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(UNADVICE));
+ if (fProc != NULL)
+ {
+ ((::Unadvice)fProc)(nHandle);
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+const String& FuncData::GetModuleName() const
+{
+ // DBG_ASSERT( pModuleData, "Keine Arme, keine Kekse" ):
+ return pModuleData->GetName();
+}
+
+//------------------------------------------------------------------------
+
+BOOL FuncData::GetParamDesc( String& aName, String& aDesc, USHORT nParam )
+{
+ BOOL bRet = FALSE;
+ if ( nParam <= nParamCount )
+ {
+ osl::Module* pLib = pModuleData->GetInstance();
+ FARPROC fProc = (FARPROC) pLib->getFunctionSymbol( LIBFUNCNAME(GETPARAMDESC) );
+ if ( fProc != NULL )
+ {
+ sal_Char pcName[256];
+ sal_Char pcDesc[256];
+ *pcName = *pcDesc = 0;
+ USHORT nFuncNo = nNumber; // nicht per Reference versauen lassen..
+ ((::GetParamDesc)fProc)( nFuncNo, nParam, pcName, pcDesc );
+ aName = String( pcName, osl_getThreadTextEncoding() );
+ aDesc = String( pcDesc, osl_getThreadTextEncoding() );
+ bRet = TRUE;
+ }
+ }
+ if ( !bRet )
+ {
+ aName.Erase();
+ aDesc.Erase();
+ }
+ return bRet;
+}
+
+
diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
new file mode 100644
index 000000000000..45d2c4a890bb
--- /dev/null
+++ b/sc/source/core/tool/cellform.cxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/objsh.hxx>
+#include <svl/smplhint.hxx>
+#include <svl/zforlist.hxx>
+
+#include "cellform.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "formula/errorcodes.hxx"
+#include "sc.hrc"
+
+// STATIC DATA -----------------------------------------------------------
+
+// Err527 Workaround
+const ScFormulaCell* pLastFormulaTreeTop = 0;
+
+// -----------------------------------------------------------------------
+
+void ScCellFormat::GetString( ScBaseCell* pCell, ULONG nFormat, String& rString,
+ Color** ppColor, SvNumberFormatter& rFormatter,
+ BOOL bNullVals,
+ BOOL bFormula,
+ ScForceTextFmt eForceTextFmt )
+{
+ *ppColor = NULL;
+ if (&rFormatter==NULL)
+ {
+ rString.Erase();
+ return;
+ }
+
+ CellType eType = pCell->GetCellType();
+ switch(eType)
+ {
+ case CELLTYPE_STRING:
+ {
+ String aCellString;
+ ((ScStringCell*)pCell)->GetString( aCellString );
+ rFormatter.GetOutputString( aCellString, nFormat, rString, ppColor );
+ }
+ break;
+ case CELLTYPE_EDIT:
+ {
+ String aCellString;
+ ((ScEditCell*)pCell)->GetString( aCellString );
+ rFormatter.GetOutputString( aCellString, nFormat, rString, ppColor );
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ double nValue = ((ScValueCell*)pCell)->GetValue();
+ if ( !bNullVals && nValue == 0.0 )
+ rString.Erase();
+ else
+ {
+ if( eForceTextFmt == ftCheck )
+ {
+ if( nFormat && rFormatter.IsTextFormat( nFormat ) )
+ eForceTextFmt = ftForce;
+ }
+ if( eForceTextFmt == ftForce )
+ {
+ String aTemp;
+ rFormatter.GetOutputString( nValue, 0, aTemp, ppColor );
+ rFormatter.GetOutputString( aTemp, nFormat, rString, ppColor );
+ }
+ else
+ rFormatter.GetOutputString( nValue, nFormat, rString, ppColor );
+ }
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( bFormula )
+ pFCell->GetFormula( rString );
+ else
+ {
+ // #62160# Ein via Interpreter gestartetes Makro, das hart
+ // auf Formelzellen zugreift, bekommt einen CellText, auch
+ // wenn dadurch ein weiterer Interpreter gestartet wird,
+ // aber nicht wenn diese Zelle gerade interpretiert wird.
+ // IdleCalc startet generell keine weiteren Interpreter,
+ // um keine Err522 (zirkulaer) zu bekommen.
+ if ( pFCell->GetDocument()->IsInInterpreter() &&
+ (!pFCell->GetDocument()->GetMacroInterpretLevel()
+ || pFCell->IsRunning()) )
+ {
+ rString.AssignAscii( RTL_CONSTASCII_STRINGPARAM("...") );
+ }
+ else
+ {
+ USHORT nErrCode = pFCell->GetErrCode();
+
+ // erst nach dem Interpretieren (GetErrCode) das Zahlformat holen:
+ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nFormat = pFCell->GetStandardFormat( rFormatter,
+ nFormat );
+
+ if (nErrCode != 0)
+ rString = ScGlobal::GetErrorString(nErrCode);
+ else if ( pFCell->IsEmptyDisplayedAsString() )
+ rString.Erase();
+ else if ( pFCell->IsValue() )
+ {
+ double fValue = pFCell->GetValue();
+ if ( !bNullVals && fValue == 0.0 )
+ rString.Erase();
+ else
+ rFormatter.GetOutputString( fValue, nFormat, rString, ppColor );
+ }
+ else
+ {
+ String aCellString;
+ pFCell->GetString( aCellString );
+ rFormatter.GetOutputString( aCellString, nFormat, rString, ppColor );
+ }
+ }
+ }
+ }
+ break;
+ default:
+ rString.Erase();
+ break;
+ }
+}
+
+void ScCellFormat::GetInputString( ScBaseCell* pCell, ULONG nFormat, String& rString,
+ SvNumberFormatter& rFormatter )
+{
+ if (&rFormatter==NULL)
+ {
+ rString.Erase();
+ return;
+ }
+
+ CellType eType = pCell->GetCellType();
+ switch(eType)
+ {
+ case CELLTYPE_STRING:
+ {
+ ((ScStringCell*)pCell)->GetString( rString );
+ }
+ break;
+ case CELLTYPE_EDIT:
+ {
+ ((ScEditCell*)pCell)->GetString( rString );
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ double nValue = ((ScValueCell*)pCell)->GetValue();
+ rFormatter.GetInputLineString( nValue, nFormat, rString );
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ if (((ScFormulaCell*)pCell)->IsEmptyDisplayedAsString())
+ {
+ rString.Erase();
+ }
+ else if (((ScFormulaCell*)pCell)->IsValue())
+ {
+ double nValue = ((ScFormulaCell*)pCell)->GetValue();
+ rFormatter.GetInputLineString( nValue, nFormat, rString );
+ }
+ else
+ {
+ ((ScFormulaCell*)pCell)->GetString( rString );
+ }
+
+ USHORT nErrCode = ((ScFormulaCell*)pCell)->GetErrCode();
+ if (nErrCode != 0)
+ {
+ rString.Erase();
+ }
+ }
+ break;
+ default:
+ rString.Erase();
+ break;
+ }
+}
+
+
+
diff --git a/sc/source/core/tool/cellkeytranslator.cxx b/sc/source/core/tool/cellkeytranslator.cxx
new file mode 100644
index 000000000000..4db8c22d19d8
--- /dev/null
+++ b/sc/source/core/tool/cellkeytranslator.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "cellkeytranslator.hxx"
+#include "comphelper/processfactory.hxx"
+#include "i18npool/mslangid.hxx"
+#include "i18npool/lang.h"
+#include "rtl/ustring.hxx"
+
+#include <com/sun/star/i18n/TransliterationModules.hpp>
+
+using ::com::sun::star::lang::Locale;
+using ::com::sun::star::uno::Sequence;
+using ::std::list;
+using ::std::hash_map;
+using ::rtl::OUString;
+
+using namespace ::com::sun::star;
+
+enum LocaleMatch
+{
+ LOCALE_MATCH_NONE = 0,
+ LOCALE_MATCH_LANG,
+ LOCALE_MATCH_LANG_COUNTRY,
+ LOCALE_MATCH_ALL
+};
+
+static LocaleMatch lclLocaleCompare(const Locale& rLocale1, const Locale& rLocale2)
+{
+ LocaleMatch eMatchLevel = LOCALE_MATCH_NONE;
+ if ( !rLocale1.Language.compareTo(rLocale1.Language) )
+ eMatchLevel = LOCALE_MATCH_LANG;
+ else
+ return eMatchLevel;
+
+ if ( !rLocale1.Country.compareTo(rLocale2.Country) )
+ eMatchLevel = LOCALE_MATCH_LANG_COUNTRY;
+ else
+ return eMatchLevel;
+
+ if ( !rLocale1.Variant.compareTo(rLocale2.Variant) )
+ eMatchLevel = LOCALE_MATCH_ALL;
+
+ return eMatchLevel;
+}
+
+ScCellKeyword::ScCellKeyword(const sal_Char* pName, OpCode eOpCode, const Locale& rLocale) :
+ mpName(pName),
+ meOpCode(eOpCode),
+ mrLocale(rLocale)
+{
+}
+
+::std::auto_ptr<ScCellKeywordTranslator> ScCellKeywordTranslator::spInstance(NULL);
+
+static void lclMatchKeyword(String& rName, const ScCellKeywordHashMap& aMap,
+ OpCode eOpCode = ocNone, const Locale* pLocale = NULL)
+{
+ ScCellKeywordHashMap::const_iterator itrEnd = aMap.end();
+ ScCellKeywordHashMap::const_iterator itr = aMap.find(rName);
+
+ if ( itr == itrEnd || itr->second.empty() )
+ // No candidate strings exist. Bail out.
+ return;
+
+ if ( eOpCode == ocNone && !pLocale )
+ {
+ // Since no locale nor opcode matching is needed, simply return
+ // the first item on the list.
+ rName = String::CreateFromAscii( itr->second.front().mpName );
+ return;
+ }
+
+ const sal_Char* aBestMatchName = itr->second.front().mpName;
+ LocaleMatch eLocaleMatchLevel = LOCALE_MATCH_NONE;
+ bool bOpCodeMatched = false;
+
+ list<ScCellKeyword>::const_iterator itrListEnd = itr->second.end();
+ list<ScCellKeyword>::const_iterator itrList = itr->second.begin();
+ for ( ; itrList != itrListEnd; ++itrList )
+ {
+ if ( eOpCode != ocNone && pLocale )
+ {
+ if ( itrList->meOpCode == eOpCode )
+ {
+ LocaleMatch eLevel = lclLocaleCompare(itrList->mrLocale, *pLocale);
+ if ( eLevel == LOCALE_MATCH_ALL )
+ {
+ // Name with matching opcode and locale found.
+ rName = String::CreateFromAscii( itrList->mpName );
+ return;
+ }
+ else if ( eLevel > eLocaleMatchLevel )
+ {
+ // Name with a better matching locale.
+ eLocaleMatchLevel = eLevel;
+ aBestMatchName = itrList->mpName;
+ }
+ else if ( !bOpCodeMatched )
+ // At least the opcode matches.
+ aBestMatchName = itrList->mpName;
+
+ bOpCodeMatched = true;
+ }
+ }
+ else if ( eOpCode != ocNone && !pLocale )
+ {
+ if ( itrList->meOpCode == eOpCode )
+ {
+ // Name with a matching opcode preferred.
+ rName = String::CreateFromAscii( itrList->mpName );
+ return;
+ }
+ }
+ else if ( !eOpCode && pLocale )
+ {
+ LocaleMatch eLevel = lclLocaleCompare(itrList->mrLocale, *pLocale);
+ if ( eLevel == LOCALE_MATCH_ALL )
+ {
+ // Name with matching locale preferred.
+ rName = String::CreateFromAscii( itrList->mpName );
+ return;
+ }
+ else if ( eLevel > eLocaleMatchLevel )
+ {
+ // Name with a better matching locale.
+ eLocaleMatchLevel = eLevel;
+ aBestMatchName = itrList->mpName;
+ }
+ }
+ }
+
+ // No preferred strings found. Return the best matching name.
+ rName = String::CreateFromAscii(aBestMatchName);
+}
+
+void ScCellKeywordTranslator::transKeyword(String& rName, const Locale* pLocale, OpCode eOpCode)
+{
+ if ( !spInstance.get() )
+ spInstance.reset( new ScCellKeywordTranslator );
+
+ LanguageType eLang = pLocale ? MsLangId::convertLocaleToLanguageWithFallback(*pLocale) : LANGUAGE_SYSTEM;
+ Sequence<sal_Int32> aOffsets;
+ rName = spInstance->maTransWrapper.transliterate(rName, eLang, 0, rName.Len(), &aOffsets);
+ lclMatchKeyword(rName, spInstance->maStringNameMap, eOpCode, pLocale);
+}
+
+ScCellKeywordTranslator::ScCellKeywordTranslator() :
+ maTransWrapper( ::comphelper::getProcessServiceFactory(),
+ i18n::TransliterationModules_LOWERCASE_UPPERCASE )
+{
+ init();
+}
+
+ScCellKeywordTranslator::~ScCellKeywordTranslator()
+{
+}
+
+struct TransItem
+{
+ const sal_Unicode* from;
+ const sal_Char* to;
+ OpCode func;
+};
+
+void ScCellKeywordTranslator::init()
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+
+ // The file below has been autogenerated by sc/workben/celltrans/parse.py.
+ // To add new locale keywords, edit sc/workben/celltrans/keywords_utf16.txt
+ // and re-run the parse.py script.
+ //
+ // All keywords must be uppercase, and the mapping must be from the
+ // localized keyword to the English keyword.
+ //
+ // Make sure that the original keyword file (keywords_utf16.txt) is
+ // encoded in UCS-2/UTF-16!
+
+ #include "cellkeywords.inl"
+}
+
+void ScCellKeywordTranslator::addToMap(const String& rKey, const sal_Char* pName, const Locale& rLocale, OpCode eOpCode)
+{
+ ScCellKeyword aKeyItem( pName, eOpCode, rLocale );
+
+ ScCellKeywordHashMap::iterator itrEnd = maStringNameMap.end();
+ ScCellKeywordHashMap::iterator itr = maStringNameMap.find(rKey);
+
+ if ( itr == itrEnd )
+ {
+ // New keyword.
+ list<ScCellKeyword> aList;
+ aList.push_back(aKeyItem);
+ maStringNameMap.insert( ScCellKeywordHashMap::value_type(rKey, aList) );
+ }
+ else
+ itr->second.push_back(aKeyItem);
+}
+
+void ScCellKeywordTranslator::addToMap(const TransItem* pItems, const Locale& rLocale)
+{
+ for (sal_uInt16 i = 0; pItems[i].from != NULL; ++i)
+ addToMap(String(pItems[i].from), pItems[i].to, rLocale, pItems[i].func);
+}
diff --git a/sc/source/core/tool/cellkeywords.inl b/sc/source/core/tool/cellkeywords.inl
new file mode 100644
index 000000000000..9fb58c02797b
--- /dev/null
+++ b/sc/source/core/tool/cellkeywords.inl
@@ -0,0 +1,181 @@
+// This file has been automatically generated. Do not hand-edit this!
+
+// ---------------------------------------------------------------------------
+// French language locale (automatically generated)
+// ---------------------------------------------------------------------------
+static const Locale aFr(OUString::createFromAscii("fr"), OUString(), OUString());
+
+// pre instantiations of localized function names
+static const sal_Unicode cell_address_fr[] = {
+ 0x0041, 0x0044, 0x0052, 0x0045, 0x0053, 0x0053, 0x0045, 0x0000};
+static const sal_Unicode cell_col_fr[] = {
+ 0x0043, 0x004F, 0x004C, 0x004F, 0x004E, 0x004E, 0x0045, 0x0000};
+static const sal_Unicode cell_contents_fr[] = {
+ 0x0043, 0x004F, 0x004E, 0x0054, 0x0045, 0x004E, 0x0055, 0x0000};
+static const sal_Unicode cell_color_fr[] = {
+ 0x0043, 0x004F, 0x0055, 0x004C, 0x0045, 0x0055, 0x0052, 0x0000};
+static const sal_Unicode cell_width_fr[] = {
+ 0x004C, 0x0041, 0x0052, 0x0047, 0x0045, 0x0055, 0x0052, 0x0000};
+static const sal_Unicode cell_row_fr[] = {
+ 0x004C, 0x0049, 0x0047, 0x004E, 0x0045, 0x0000};
+static const sal_Unicode cell_filename_fr[] = {
+ 0x004E, 0x004F, 0x004D, 0x0046, 0x0049, 0x0043, 0x0048, 0x0049, 0x0045, 0x0052, 0x0000};
+static const sal_Unicode cell_prefix_fr[] = {
+ 0x0050, 0x0052, 0x0045, 0x0046, 0x0049, 0x0058, 0x0045, 0x0000};
+static const sal_Unicode cell_protect_fr[] = {
+ 0x0050, 0x0052, 0x004F, 0x0054, 0x0045, 0x0047, 0x0045, 0x0000};
+static const sal_Unicode info_numfile_fr[] = {
+ 0x004E, 0x0042, 0x0046, 0x0049, 0x0043, 0x0048, 0x0000};
+static const sal_Unicode info_recalc_fr[] = {
+ 0x0052, 0x0045, 0x0043, 0x0041, 0x004C, 0x0043, 0x0055, 0x004C, 0x0000};
+static const sal_Unicode info_system_fr[] = {
+ 0x0053, 0x0059, 0x0053, 0x0054, 0x0045, 0x0058, 0x0050, 0x004C, 0x0000};
+static const sal_Unicode info_release_fr[] = {
+ 0x0056, 0x0045, 0x0052, 0x0053, 0x0049, 0x004F, 0x004E, 0x0000};
+static const sal_Unicode info_osversion_fr[] = {
+ 0x0056, 0x0045, 0x0052, 0x0053, 0x0049, 0x004F, 0x004E, 0x0053, 0x0045, 0x0000};
+
+static const TransItem pFr[] = {
+ {cell_address_fr, "ADDRESS", ocCell},
+ {cell_col_fr, "COL", ocCell},
+ {cell_contents_fr, "CONTENTS", ocCell},
+ {cell_color_fr, "COLOR", ocCell},
+ {cell_width_fr, "WIDTH", ocCell},
+ {cell_row_fr, "ROW", ocCell},
+ {cell_filename_fr, "FILENAME", ocCell},
+ {cell_prefix_fr, "PREFIX", ocCell},
+ {cell_protect_fr, "PROTECT", ocCell},
+ {info_numfile_fr, "NUMFILE", ocInfo},
+ {info_recalc_fr, "RECALC", ocInfo},
+ {info_system_fr, "SYSTEM", ocInfo},
+ {info_release_fr, "RELEASE", ocInfo},
+ {info_osversion_fr, "OSVERSION", ocInfo},
+ {NULL, NULL, ocNone}
+};
+
+addToMap(pFr, aFr);
+
+// ---------------------------------------------------------------------------
+// Hungarian language locale (automatically generated)
+// ---------------------------------------------------------------------------
+static const Locale aHu(OUString::createFromAscii("hu"), OUString(), OUString());
+
+// pre instantiations of localized function names
+static const sal_Unicode cell_address_hu[] = {
+ 0x0043, 0x00CD, 0x004D, 0x0000};
+static const sal_Unicode cell_col_hu[] = {
+ 0x004F, 0x0053, 0x005A, 0x004C, 0x004F, 0x0050, 0x0000};
+static const sal_Unicode cell_color_hu[] = {
+ 0x0053, 0x005A, 0x00CD, 0x004E, 0x0000};
+static const sal_Unicode cell_contents_hu[] = {
+ 0x0054, 0x0041, 0x0052, 0x0054, 0x0041, 0x004C, 0x004F, 0x004D, 0x0000};
+static const sal_Unicode cell_width_hu[] = {
+ 0x0053, 0x005A, 0x00C9, 0x004C, 0x0045, 0x0053, 0x0000};
+static const sal_Unicode cell_row_hu[] = {
+ 0x0053, 0x004F, 0x0052, 0x0000};
+static const sal_Unicode cell_filename_hu[] = {
+ 0x0046, 0x0049, 0x004C, 0x0045, 0x004E, 0x00C9, 0x0056, 0x0000};
+static const sal_Unicode cell_prefix_hu[] = {
+ 0x0050, 0x0052, 0x0045, 0x0046, 0x0049, 0x0058, 0x0000};
+static const sal_Unicode cell_protect_hu[] = {
+ 0x0056, 0x00C9, 0x0044, 0x0045, 0x0054, 0x0054, 0x0000};
+static const sal_Unicode cell_coord_hu[] = {
+ 0x004B, 0x004F, 0x004F, 0x0052, 0x0044, 0x0000};
+static const sal_Unicode cell_format_hu[] = {
+ 0x0046, 0x004F, 0x0052, 0x004D, 0x0041, 0x0000};
+static const sal_Unicode cell_parentheses_hu[] = {
+ 0x005A, 0x00C1, 0x0052, 0x00D3, 0x004A, 0x0045, 0x004C, 0x0045, 0x004B, 0x0000};
+static const sal_Unicode cell_sheet_hu[] = {
+ 0x004C, 0x0041, 0x0050, 0x0000};
+static const sal_Unicode cell_type_hu[] = {
+ 0x0054, 0x00CD, 0x0050, 0x0055, 0x0053, 0x0000};
+static const sal_Unicode info_numfile_hu[] = {
+ 0x0046, 0x0049, 0x004C, 0x0045, 0x0053, 0x005A, 0x00C1, 0x004D, 0x0000};
+static const sal_Unicode info_recalc_hu[] = {
+ 0x0053, 0x005A, 0x00C1, 0x004D, 0x004F, 0x004C, 0x00C1, 0x0053, 0x0000};
+static const sal_Unicode info_system_hu[] = {
+ 0x0052, 0x0045, 0x004E, 0x0044, 0x0053, 0x005A, 0x0045, 0x0052, 0x0000};
+static const sal_Unicode info_release_hu[] = {
+ 0x0056, 0x0045, 0x0052, 0x005A, 0x0049, 0x00D3, 0x0000};
+static const sal_Unicode info_osversion_hu[] = {
+ 0x004F, 0x0050, 0x0052, 0x0045, 0x004E, 0x0044, 0x0053, 0x005A, 0x0045, 0x0052, 0x0000};
+
+static const TransItem pHu[] = {
+ {cell_address_hu, "ADDRESS", ocCell},
+ {cell_col_hu, "COL", ocCell},
+ {cell_color_hu, "COLOR", ocCell},
+ {cell_contents_hu, "CONTENTS", ocCell},
+ {cell_width_hu, "WIDTH", ocCell},
+ {cell_row_hu, "ROW", ocCell},
+ {cell_filename_hu, "FILENAME", ocCell},
+ {cell_prefix_hu, "PREFIX", ocCell},
+ {cell_protect_hu, "PROTECT", ocCell},
+ {cell_coord_hu, "COORD", ocCell},
+ {cell_format_hu, "FORMAT", ocCell},
+ {cell_parentheses_hu, "PARENTHESES", ocCell},
+ {cell_sheet_hu, "SHEET", ocCell},
+ {cell_type_hu, "TYPE", ocCell},
+ {info_numfile_hu, "NUMFILE", ocInfo},
+ {info_recalc_hu, "RECALC", ocInfo},
+ {info_system_hu, "SYSTEM", ocInfo},
+ {info_release_hu, "RELEASE", ocInfo},
+ {info_osversion_hu, "OSVERSION", ocInfo},
+ {NULL, NULL, ocNone}
+};
+
+addToMap(pHu, aHu);
+
+// ---------------------------------------------------------------------------
+// German language locale (automatically generated)
+// ---------------------------------------------------------------------------
+static const Locale aDe(OUString::createFromAscii("de"), OUString(), OUString());
+
+// pre instantiations of localized function names
+static const sal_Unicode cell_row_de[] = {
+ 0x005A, 0x0045, 0x0049, 0x004C, 0x0045, 0x0000};
+static const sal_Unicode cell_col_de[] = {
+ 0x0053, 0x0050, 0x0041, 0x004C, 0x0054, 0x0045, 0x0000};
+static const sal_Unicode cell_width_de[] = {
+ 0x0042, 0x0052, 0x0045, 0x0049, 0x0054, 0x0045, 0x0000};
+static const sal_Unicode cell_address_de[] = {
+ 0x0041, 0x0044, 0x0052, 0x0045, 0x0053, 0x0053, 0x0045, 0x0000};
+static const sal_Unicode cell_filename_de[] = {
+ 0x0044, 0x0041, 0x0054, 0x0045, 0x0049, 0x004E, 0x0041, 0x004D, 0x0045, 0x0000};
+static const sal_Unicode cell_color_de[] = {
+ 0x0046, 0x0041, 0x0052, 0x0042, 0x0045, 0x0000};
+static const sal_Unicode cell_format_de[] = {
+ 0x0046, 0x004F, 0x0052, 0x004D, 0x0041, 0x0054, 0x0000};
+static const sal_Unicode cell_contents_de[] = {
+ 0x0049, 0x004E, 0x0048, 0x0041, 0x004C, 0x0054, 0x0000};
+static const sal_Unicode cell_parentheses_de[] = {
+ 0x004B, 0x004C, 0x0041, 0x004D, 0x004D, 0x0045, 0x0052, 0x004E, 0x0000};
+static const sal_Unicode cell_protect_de[] = {
+ 0x0053, 0x0043, 0x0048, 0x0055, 0x0054, 0x005A, 0x0000};
+static const sal_Unicode cell_type_de[] = {
+ 0x0054, 0x0059, 0x0050, 0x0000};
+static const sal_Unicode cell_prefix_de[] = {
+ 0x0050, 0x0052, 0x00C4, 0x0046, 0x0049, 0x0058, 0x0000};
+static const sal_Unicode cell_sheet_de[] = {
+ 0x0042, 0x004C, 0x0041, 0x0054, 0x0054, 0x0000};
+static const sal_Unicode cell_coord_de[] = {
+ 0x004B, 0x004F, 0x004F, 0x0052, 0x0044, 0x0000};
+
+static const TransItem pDe[] = {
+ {cell_row_de, "ROW", ocCell},
+ {cell_col_de, "COL", ocCell},
+ {cell_width_de, "WIDTH", ocCell},
+ {cell_address_de, "ADDRESS", ocCell},
+ {cell_filename_de, "FILENAME", ocCell},
+ {cell_color_de, "COLOR", ocCell},
+ {cell_format_de, "FORMAT", ocCell},
+ {cell_contents_de, "CONTENTS", ocCell},
+ {cell_parentheses_de, "PARENTHESES", ocCell},
+ {cell_protect_de, "PROTECT", ocCell},
+ {cell_type_de, "TYPE", ocCell},
+ {cell_prefix_de, "PREFIX", ocCell},
+ {cell_sheet_de, "SHEET", ocCell},
+ {cell_coord_de, "COORD", ocCell},
+ {NULL, NULL, ocNone}
+};
+
+addToMap(pDe, aDe);
diff --git a/sc/source/core/tool/chartarr.cxx b/sc/source/core/tool/chartarr.cxx
new file mode 100644
index 000000000000..573763141b18
--- /dev/null
+++ b/sc/source/core/tool/chartarr.cxx
@@ -0,0 +1,615 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include <float.h> // DBL_MIN
+
+#include "chartarr.hxx"
+#include "document.hxx"
+#include "rechead.hxx"
+#include "globstr.hrc"
+#include "cell.hxx"
+#include "docoptio.hxx"
+
+#include <vector>
+
+using ::std::vector;
+
+// -----------------------------------------------------------------------
+
+ScMemChart::ScMemChart(short nCols, short nRows)
+{
+ nRowCnt = nRows;
+ nColCnt = nCols;
+ pData = new double[nColCnt * nRowCnt];
+
+ if (pData)
+ {
+ double *pFill = pData;
+
+ for (short i = 0; i < nColCnt; i++)
+ for (short j = 0; j < nRowCnt; j++)
+ *(pFill ++) = 0.0;
+ }
+
+ pColText = new String[nColCnt];
+ pRowText = new String[nRowCnt];
+}
+
+ScMemChart::~ScMemChart()
+{
+ delete[] pRowText;
+ delete[] pColText;
+ delete[] pData;
+}
+
+// -----------------------------------------------------------------------
+
+ScChartArray::ScChartArray( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP,
+ const String& rChartName ) :
+ aName( rChartName ),
+ pDocument( pDoc ),
+ aPositioner(pDoc, nTab, nStartColP, nStartRowP, nEndColP, nEndRowP),
+ bValid( TRUE )
+{
+}
+
+ScChartArray::ScChartArray( ScDocument* pDoc, const ScRangeListRef& rRangeList,
+ const String& rChartName ) :
+ aName( rChartName ),
+ pDocument( pDoc ),
+ aPositioner(pDoc, rRangeList),
+ bValid( TRUE )
+{
+}
+
+ScChartArray::ScChartArray( const ScChartArray& rArr ) :
+ ScDataObject(),
+ aName(rArr.aName),
+ pDocument(rArr.pDocument),
+ aPositioner(rArr.aPositioner),
+ bValid(rArr.bValid)
+{
+}
+
+ScChartArray::~ScChartArray()
+{
+}
+
+ScDataObject* ScChartArray::Clone() const
+{
+ return new ScChartArray(*this);
+}
+
+BOOL ScChartArray::operator==(const ScChartArray& rCmp) const
+{
+ return aPositioner == rCmp.aPositioner
+ && aName == rCmp.aName;
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+ScMemChart* ScChartArray::CreateMemChart()
+{
+ ScRangeListRef aRangeListRef(GetRangeList());
+ ULONG nCount = aRangeListRef->Count();
+ if ( nCount > 1 )
+ return CreateMemChartMulti();
+ else if ( nCount == 1 )
+ {
+ ScRange* pR = aRangeListRef->First();
+ if ( pR->aStart.Tab() != pR->aEnd.Tab() )
+ return CreateMemChartMulti();
+ else
+ return CreateMemChartSingle();
+ }
+ else
+ return CreateMemChartMulti(); // kann 0 Range besser ab als Single
+}
+
+ScMemChart* ScChartArray::CreateMemChartSingle()
+{
+ SCSIZE nCol;
+ SCSIZE nRow;
+
+ //
+ // wirkliche Groesse (ohne versteckte Zeilen/Spalten)
+ //
+
+ SCCOL nColAdd = HasRowHeaders() ? 1 : 0;
+ SCROW nRowAdd = HasColHeaders() ? 1 : 0;
+
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ ScRangeListRef aRangeListRef(GetRangeList());
+ aRangeListRef->First()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+
+ SCCOL nStrCol = nCol1; // fuer Beschriftung merken
+ SCROW nStrRow = nRow1;
+ // Skip hidden columns.
+ // TODO: make use of last column value once implemented.
+ SCCOL nLastCol = -1;
+ while (pDocument->ColHidden(nCol1, nTab1, nLastCol))
+ ++nCol1;
+
+ // Skip hidden rows.
+ SCROW nLastRow = -1;
+ if (pDocument->RowHidden(nRow1, nTab1, nLastRow))
+ nRow1 = nLastRow + 1;
+
+ // falls alles hidden ist, bleibt die Beschriftung am Anfang
+ if ( nCol1 <= nCol2 )
+ {
+ nStrCol = nCol1;
+ nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nColAdd );
+ }
+ if ( nRow1 <= nRow2 )
+ {
+ nStrRow = nRow1;
+ nRow1 = sal::static_int_cast<SCROW>( nRow1 + nRowAdd );
+ }
+
+ SCSIZE nTotalCols = ( nCol1 <= nCol2 ? nCol2 - nCol1 + 1 : 0 );
+ vector<SCCOL> aCols;
+ aCols.reserve(nTotalCols);
+ for (SCSIZE i=0; i<nTotalCols; i++)
+ {
+ SCCOL nThisCol = sal::static_int_cast<SCCOL>(nCol1+i);
+ if (!pDocument->ColHidden(nThisCol, nTab1, nLastCol))
+ aCols.push_back(nThisCol);
+ }
+ SCSIZE nColCount = aCols.size();
+
+ SCSIZE nTotalRows = ( nRow1 <= nRow2 ? nRow2 - nRow1 + 1 : 0 );
+ vector<SCROW> aRows;
+ aRows.reserve(nTotalRows);
+ if (nRow1 <= nRow2)
+ {
+ // Get all visible rows between nRow1 and nRow2.
+ SCROW nThisRow = nRow1;
+ while (nThisRow <= nRow2)
+ {
+ if (pDocument->RowHidden(nThisRow, nTab1, nLastRow))
+ nThisRow = nLastRow;
+ else
+ aRows.push_back(nThisRow);
+ ++nThisRow;
+ }
+ }
+ SCSIZE nRowCount = aRows.size();
+
+ // May happen at least with more than 32k rows.
+ if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
+ {
+ nColCount = 0;
+ nRowCount = 0;
+ }
+
+ BOOL bValidData = TRUE;
+ if ( !nColCount )
+ {
+ bValidData = FALSE;
+ nColCount = 1;
+ aCols.push_back(nStrCol);
+ }
+ if ( !nRowCount )
+ {
+ bValidData = FALSE;
+ nRowCount = 1;
+ aRows.push_back(nStrRow);
+ }
+
+ //
+ // Daten
+ //
+
+ ScMemChart* pMemChart = new ScMemChart(
+ static_cast<short>(nColCount), static_cast<short>(nRowCount) );
+ if (pMemChart)
+ {
+// SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+// pMemChart->SetNumberFormatter( pFormatter );
+ if ( bValidData )
+ {
+ BOOL bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown();
+ ScBaseCell* pCell;
+ for (nCol=0; nCol<nColCount; nCol++)
+ {
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
+
+ pDocument->GetCell( aCols[nCol], aRows[nRow], nTab1, pCell );
+ if (pCell)
+ {
+ CellType eType = pCell->GetCellType();
+ if (eType == CELLTYPE_VALUE)
+ {
+ nVal = ((ScValueCell*)pCell)->GetValue();
+ if ( bCalcAsShown && nVal != 0.0 )
+ {
+ sal_uInt32 nFormat;
+ pDocument->GetNumberFormat( aCols[nCol],
+ aRows[nRow], nTab1, nFormat );
+ nVal = pDocument->RoundValueAsShown( nVal, nFormat );
+ }
+ }
+ else if (eType == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() )
+ nVal = pFCell->GetValue();
+ }
+ }
+ pMemChart->SetData(static_cast<short>(nCol), static_cast<short>(nRow), nVal);
+ }
+ }
+ }
+ else
+ {
+ //! Flag, dass Daten ungueltig ??
+
+ for (nCol=0; nCol<nColCount; nCol++)
+ for (nRow=0; nRow<nRowCount; nRow++)
+ pMemChart->SetData( static_cast<short>(nCol), static_cast<short>(nRow), DBL_MIN );
+ }
+
+ //
+ // Spalten-Header
+ //
+
+ for (nCol=0; nCol<nColCount; nCol++)
+ {
+ String aString, aColStr;
+ if (HasColHeaders())
+ pDocument->GetString( aCols[nCol], nStrRow, nTab1, aString );
+ if ( !aString.Len() )
+ {
+ aString = ScGlobal::GetRscString(STR_COLUMN);
+ aString += ' ';
+// aString += String::CreateFromInt32( pCols[nCol]+1 );
+ ScAddress aPos( aCols[ nCol ], 0, 0 );
+ aPos.Format( aColStr, SCA_VALID_COL, NULL );
+ aString += aColStr;
+ }
+ pMemChart->SetColText( static_cast<short>(nCol), aString);
+
+// ULONG nNumberAttr = (nTotalRows ? pDocument->GetNumberFormat(
+// ScAddress( pCols[nCol], nRow1, nTab1)) : 0);
+// pMemChart->SetNumFormatIdCol( static_cast<long>(nCol), nNumberAttr );
+ }
+
+ //
+ // Zeilen-Header
+ //
+
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ String aString;
+ if (HasRowHeaders())
+ {
+ ScAddress aAddr( nStrCol, aRows[nRow], nTab1 );
+ pDocument->GetString( nStrCol, aRows[nRow], nTab1, aString );
+ }
+ if ( !aString.Len() )
+ {
+ aString = ScGlobal::GetRscString(STR_ROW);
+ aString += ' ';
+ aString += String::CreateFromInt32( aRows[nRow]+1 );
+ }
+ pMemChart->SetRowText( static_cast<short>(nRow), aString);
+
+// ULONG nNumberAttr = (nTotalCols ? pDocument->GetNumberFormat(
+// ScAddress( nCol1, pRows[nRow], nTab1)) : 0);
+// pMemChart->SetNumFormatIdRow( static_cast<long>(nRow), nNumberAttr );
+ }
+
+ //
+ // Titel
+ //
+
+// pMemChart->SetMainTitle(ScGlobal::GetRscString(STR_CHART_MAINTITLE));
+// pMemChart->SetSubTitle(ScGlobal::GetRscString(STR_CHART_SUBTITLE));
+// pMemChart->SetXAxisTitle(ScGlobal::GetRscString(STR_CHART_XTITLE));
+// pMemChart->SetYAxisTitle(ScGlobal::GetRscString(STR_CHART_YTITLE));
+// pMemChart->SetZAxisTitle(ScGlobal::GetRscString(STR_CHART_ZTITLE));
+
+ //
+ // Zahlen-Typ
+ //
+
+// ULONG nNumberAttr = (nTotalCols && nTotalRows ?
+// pDocument->GetNumberFormat( ScAddress( nCol1, nRow1, nTab1)) :
+// 0);
+// if (pFormatter)
+// pMemChart->SetDataType(pFormatter->GetType( nNumberAttr ));
+
+ //
+ // Parameter-Strings
+ //
+
+// SetExtraStrings( *pMemChart );
+ }
+
+ return pMemChart;
+}
+
+ScMemChart* ScChartArray::CreateMemChartMulti()
+{
+ SCSIZE nColCount = GetPositionMap()->GetColCount();
+ SCSIZE nRowCount = GetPositionMap()->GetRowCount();
+
+ SCSIZE nCol = 0;
+ SCSIZE nRow = 0;
+
+ // May happen at least with more than 32k rows.
+ if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
+ {
+ nColCount = 0;
+ nRowCount = 0;
+ }
+
+ BOOL bValidData = TRUE;
+ if ( !nColCount )
+ {
+ bValidData = FALSE;
+ nColCount = 1;
+ }
+ if ( !nRowCount )
+ {
+ bValidData = FALSE;
+ nRowCount = 1;
+ }
+
+ //
+ // Daten
+ //
+
+ ScMemChart* pMemChart = new ScMemChart(
+ static_cast<short>(nColCount), static_cast<short>(nRowCount) );
+ if (pMemChart)
+ {
+// pMemChart->SetNumberFormatter( pDocument->GetFormatTable() );
+ BOOL bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown();
+ ULONG nIndex = 0;
+ if (bValidData)
+ {
+ for ( nCol = 0; nCol < nColCount; nCol++ )
+ {
+ for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
+ {
+ double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
+ const ScAddress* pPos = GetPositionMap()->GetPosition( nIndex );
+ if ( pPos )
+ { // sonst: Luecke
+ ScBaseCell* pCell = pDocument->GetCell( *pPos );
+ if (pCell)
+ {
+ CellType eType = pCell->GetCellType();
+ if (eType == CELLTYPE_VALUE)
+ {
+ nVal = ((ScValueCell*)pCell)->GetValue();
+ if ( bCalcAsShown && nVal != 0.0 )
+ {
+ ULONG nFormat = pDocument->GetNumberFormat( *pPos );
+ nVal = pDocument->RoundValueAsShown( nVal, nFormat );
+ }
+ }
+ else if (eType == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() )
+ nVal = pFCell->GetValue();
+ }
+ }
+ }
+ pMemChart->SetData(static_cast<short>(nCol), static_cast<short>(nRow), nVal);
+ }
+ }
+ }
+ else
+ {
+ for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
+ {
+ double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
+ const ScAddress* pPos = GetPositionMap()->GetPosition( nIndex );
+ if ( pPos )
+ { // sonst: Luecke
+ ScBaseCell* pCell = pDocument->GetCell( *pPos );
+ if (pCell)
+ {
+ CellType eType = pCell->GetCellType();
+ if (eType == CELLTYPE_VALUE)
+ {
+ nVal = ((ScValueCell*)pCell)->GetValue();
+ if ( bCalcAsShown && nVal != 0.0 )
+ {
+ ULONG nFormat = pDocument->GetNumberFormat( *pPos );
+ nVal = pDocument->RoundValueAsShown( nVal, nFormat );
+ }
+ }
+ else if (eType == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() )
+ nVal = pFCell->GetValue();
+ }
+ }
+ }
+ pMemChart->SetData(static_cast<short>(nCol), static_cast<short>(nRow), nVal);
+ }
+ }
+
+//2do: Beschriftung bei Luecken
+
+ //
+ // Spalten-Header
+ //
+
+ SCCOL nPosCol = 0;
+ for ( nCol = 0; nCol < nColCount; nCol++ )
+ {
+ String aString, aColStr;
+ const ScAddress* pPos = GetPositionMap()->GetColHeaderPosition( static_cast<SCCOL>(nCol) );
+ if ( HasColHeaders() && pPos )
+ pDocument->GetString(
+ pPos->Col(), pPos->Row(), pPos->Tab(), aString );
+ if ( !aString.Len() )
+ {
+ aString = ScGlobal::GetRscString(STR_COLUMN);
+ aString += ' ';
+ if ( pPos )
+ nPosCol = pPos->Col() + 1;
+ else
+ nPosCol++;
+ ScAddress aPos( nPosCol - 1, 0, 0 );
+ aPos.Format( aColStr, SCA_VALID_COL, NULL );
+// aString += String::CreateFromInt32( nPosCol );
+ aString += aColStr;
+ }
+ pMemChart->SetColText( static_cast<short>(nCol), aString);
+
+// ULONG nNumberAttr = 0;
+// pPos = GetPositionMap()->GetPosition( nCol, 0 );
+// if ( pPos )
+// nNumberAttr = pDocument->GetNumberFormat( *pPos );
+// pMemChart->SetNumFormatIdCol( static_cast<long>(nCol), nNumberAttr );
+ }
+
+ //
+ // Zeilen-Header
+ //
+
+ SCROW nPosRow = 0;
+ for ( nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ String aString;
+ const ScAddress* pPos = GetPositionMap()->GetRowHeaderPosition( nRow );
+ if ( HasRowHeaders() && pPos )
+ {
+ pDocument->GetString(
+ pPos->Col(), pPos->Row(), pPos->Tab(), aString );
+ }
+ if ( !aString.Len() )
+ {
+ aString = ScGlobal::GetRscString(STR_ROW);
+ aString += ' ';
+ if ( pPos )
+ nPosRow = pPos->Row() + 1;
+ else
+ nPosRow++;
+ aString += String::CreateFromInt32( nPosRow );
+ }
+ pMemChart->SetRowText( static_cast<short>(nRow), aString);
+
+// ULONG nNumberAttr = 0;
+// pPos = GetPositionMap()->GetPosition( 0, nRow );
+// if ( pPos )
+// nNumberAttr = pDocument->GetNumberFormat( *pPos );
+// pMemChart->SetNumFormatIdRow( static_cast<long>(nRow), nNumberAttr );
+ }
+
+ //
+ // Titel
+ //
+
+// pMemChart->SetMainTitle(ScGlobal::GetRscString(STR_CHART_MAINTITLE));
+// pMemChart->SetSubTitle(ScGlobal::GetRscString(STR_CHART_SUBTITLE));
+// pMemChart->SetXAxisTitle(ScGlobal::GetRscString(STR_CHART_XTITLE));
+// pMemChart->SetYAxisTitle(ScGlobal::GetRscString(STR_CHART_YTITLE));
+// pMemChart->SetZAxisTitle(ScGlobal::GetRscString(STR_CHART_ZTITLE));
+
+ //
+ // Zahlen-Typ
+ //
+
+// SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+// if (pFormatter)
+// {
+// ULONG nIndex = 0;
+// ULONG nCount = GetPositionMap()->GetCount();
+// const ScAddress* pPos;
+// do
+// {
+// pPos = GetPositionMap()->GetPosition( nIndex );
+// } while ( !pPos && ++nIndex < nCount );
+// ULONG nFormat = ( pPos ? pDocument->GetNumberFormat( *pPos ) : 0 );
+// pMemChart->SetDataType( pFormatter->GetType( nFormat ) );
+// }
+
+ //
+ // Parameter-Strings
+ //
+
+// SetExtraStrings( *pMemChart );
+ }
+
+ return pMemChart;
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",on)
+#endif
+
+
+//
+// Collection
+//
+
+ScDataObject* ScChartCollection::Clone() const
+{
+ return new ScChartCollection(*this);
+}
+
+BOOL ScChartCollection::operator==(const ScChartCollection& rCmp) const
+{
+ if (nCount != rCmp.nCount)
+ return FALSE;
+
+ for (USHORT i=0; i<nCount; i++)
+ if (!((*(const ScChartArray*)pItems[i]) == (*(const ScChartArray*)rCmp.pItems[i])))
+ return FALSE;
+
+ return TRUE;
+}
+
diff --git a/sc/source/core/tool/charthelper.cxx b/sc/source/core/tool/charthelper.cxx
new file mode 100644
index 000000000000..1b2cde3d4a6d
--- /dev/null
+++ b/sc/source/core/tool/charthelper.cxx
@@ -0,0 +1,298 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "charthelper.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "rangelst.hxx"
+#include "chartlis.hxx"
+
+//#include <vcl/svapp.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+
+
+// ====================================================================
+
+namespace
+{
+
+
+USHORT lcl_DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, BOOL bAllCharts )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return 0;
+
+ USHORT nFound = 0;
+
+ USHORT nPageCount = pModel->GetPageCount();
+ for (USHORT nPageNo=0; nPageNo<nPageCount; nPageNo++)
+ {
+ SdrPage* pPage = pModel->GetPage(nPageNo);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart( pObject ) )
+ {
+ String aName = ((SdrOle2Obj*)pObject)->GetPersistName();
+ BOOL bHit = TRUE;
+ if ( !bAllCharts )
+ {
+ ScRangeList aRanges;
+ BOOL bColHeaders = FALSE;
+ BOOL bRowHeaders = FALSE;
+ pDoc->GetOldChartParameters( aName, aRanges, bColHeaders, bRowHeaders );
+ bHit = aRanges.In( rPos );
+ }
+ if ( bHit )
+ {
+ pDoc->UpdateChart( aName );
+ ++nFound;
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ return nFound;
+}
+
+BOOL lcl_AdjustRanges( ScRangeList& rRanges, SCTAB nSourceTab, SCTAB nDestTab, SCTAB nTabCount )
+{
+ //! if multiple sheets are copied, update references into the other copied sheets?
+
+ BOOL bChanged = FALSE;
+
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange* pRange = rRanges.GetObject(i);
+ if ( pRange->aStart.Tab() == nSourceTab && pRange->aEnd.Tab() == nSourceTab )
+ {
+ pRange->aStart.SetTab( nDestTab );
+ pRange->aEnd.SetTab( nDestTab );
+ bChanged = TRUE;
+ }
+ if ( pRange->aStart.Tab() >= nTabCount )
+ {
+ pRange->aStart.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 );
+ bChanged = TRUE;
+ }
+ if ( pRange->aEnd.Tab() >= nTabCount )
+ {
+ pRange->aEnd.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 );
+ bChanged = TRUE;
+ }
+ }
+
+ return bChanged;
+}
+
+}//end anonymous namespace
+
+// === ScChartHelper ======================================
+
+//static
+USHORT ScChartHelper::DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc )
+{
+ return lcl_DoUpdateCharts( rPos, pDoc, FALSE );
+}
+
+//static
+USHORT ScChartHelper::DoUpdateAllCharts( ScDocument* pDoc )
+{
+ return lcl_DoUpdateCharts( ScAddress(), pDoc, TRUE );
+}
+
+//static
+void ScChartHelper::AdjustRangesOfChartsOnDestinationPage( ScDocument* pSrcDoc, ScDocument* pDestDoc, const SCTAB nSrcTab, const SCTAB nDestTab )
+{
+ if( !pSrcDoc || !pDestDoc )
+ return;
+ ScDrawLayer* pDrawLayer = pDestDoc->GetDrawLayer();
+ if( !pDrawLayer )
+ return;
+
+ SdrPage* pDestPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestTab));
+ if( pDestPage )
+ {
+ SdrObjListIter aIter( *pDestPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while( pObject )
+ {
+ if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() )
+ {
+ String aChartName = ((SdrOle2Obj*)pObject)->GetPersistName();
+
+ Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) );
+ Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
+ if( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider() )
+ {
+ ::std::vector< ScRangeList > aRangesVector;
+ pDestDoc->GetChartRanges( aChartName, aRangesVector, pSrcDoc );
+
+ ::std::vector< ScRangeList >::iterator aIt( aRangesVector.begin() );
+ for( ; aIt!=aRangesVector.end(); aIt++ )
+ {
+ ScRangeList& rScRangeList( *aIt );
+ lcl_AdjustRanges( rScRangeList, nSrcTab, nDestTab, pDestDoc->GetTableCount() );
+ }
+ pDestDoc->SetChartRanges( aChartName, aRangesVector );
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+
+//static
+uno::Reference< chart2::XChartDocument > ScChartHelper::GetChartFromSdrObject( SdrObject* pObject )
+{
+ uno::Reference< chart2::XChartDocument > xReturn;
+ if( pObject )
+ {
+ if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() )
+ {
+ uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if( xIPObj.is() )
+ {
+ svt::EmbeddedObjectRef::TryRunningState( xIPObj );
+ uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent();
+ xReturn.set( uno::Reference< chart2::XChartDocument >( xComponent, uno::UNO_QUERY ) );
+ }
+ }
+ }
+ return xReturn;
+}
+
+void ScChartHelper::GetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc,
+ uno::Sequence< rtl::OUString >& rRanges )
+{
+ rRanges.realloc(0);
+ uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY );
+ if( !xDataSource.is() )
+ return;
+ //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
+
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() );
+ rRanges.realloc(2*aLabeledDataSequences.getLength());
+ sal_Int32 nRealCount=0;
+ for( sal_Int32 nN=0;nN<aLabeledDataSequences.getLength();nN++)
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] );
+ if(!xLabeledSequence.is())
+ continue;
+ uno::Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel());
+ uno::Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues());
+
+ if( xLabel.is())
+ rRanges[nRealCount++] = xLabel->getSourceRangeRepresentation();
+ if( xValues.is())
+ rRanges[nRealCount++] = xValues->getSourceRangeRepresentation();
+ }
+ rRanges.realloc(nRealCount);
+}
+
+void ScChartHelper::SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc,
+ const uno::Sequence< rtl::OUString >& rRanges )
+{
+ uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY );
+ if( !xDataSource.is() )
+ return;
+ uno::Reference< chart2::data::XDataProvider > xDataProvider = xChartDoc->getDataProvider();
+ if( !xDataProvider.is() )
+ return;
+
+ uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY );
+ if( xModel.is() )
+ xModel->lockControllers();
+
+ try
+ {
+ rtl::OUString aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") );
+
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() );
+ sal_Int32 nRange=0;
+ for( sal_Int32 nN=0; (nN<aLabeledDataSequences.getLength()) && (nRange<rRanges.getLength()); nN++ )
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] );
+ if(!xLabeledSequence.is())
+ continue;
+ uno::Reference< beans::XPropertySet > xLabel( xLabeledSequence->getLabel(), uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySet > xValues( xLabeledSequence->getValues(), uno::UNO_QUERY );
+
+ if( xLabel.is())
+ {
+ // the range string must be in Calc A1 format.
+ uno::Reference< chart2::data::XDataSequence > xNewSeq(
+ xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] ));
+
+ uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY );
+ if( xNewProps.is() )
+ xNewProps->setPropertyValue( aPropertyNameRole, xLabel->getPropertyValue( aPropertyNameRole ) );
+
+ xLabeledSequence->setLabel( xNewSeq );
+ }
+
+ if( !(nRange<rRanges.getLength()) )
+ break;
+
+ if( xValues.is())
+ {
+ // the range string must be in Calc A1 format.
+ uno::Reference< chart2::data::XDataSequence > xNewSeq(
+ xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] ));
+
+ uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY );
+ if( xNewProps.is() )
+ xNewProps->setPropertyValue( aPropertyNameRole, xValues->getPropertyValue( aPropertyNameRole ) );
+
+ xLabeledSequence->setValues( xNewSeq );
+ }
+ }
+ }
+ catch ( uno::Exception& ex )
+ {
+ (void)ex;
+ DBG_ERROR("Exception in ScChartHelper::SetChartRanges - invalid range string?");
+ }
+
+ if( xModel.is() )
+ xModel->unlockControllers();
+}
diff --git a/sc/source/core/tool/chartlis.cxx b/sc/source/core/tool/chartlis.cxx
new file mode 100644
index 000000000000..b729ce0b30b5
--- /dev/null
+++ b/sc/source/core/tool/chartlis.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+
+#include "chartlis.hxx"
+#include "brdcst.hxx"
+#include "document.hxx"
+#include "reftokenhelper.hxx"
+
+using namespace com::sun::star;
+using ::std::vector;
+using ::std::list;
+using ::std::hash_set;
+using ::std::auto_ptr;
+using ::std::unary_function;
+using ::std::for_each;
+
+//2do: DocOption TimeOut?
+//#define SC_CHARTTIMEOUT 1000 // eine Sekunde keine Aenderung/KeyEvent
+
+// Update chart listeners quickly, to get a similar behavior to loaded charts
+// which register UNO listeners.
+#define SC_CHARTTIMEOUT 10
+
+
+// ====================================================================
+
+class ScChartUnoData
+{
+ uno::Reference< chart::XChartDataChangeEventListener > xListener;
+ uno::Reference< chart::XChartData > xSource;
+
+public:
+ ScChartUnoData( const uno::Reference< chart::XChartDataChangeEventListener >& rL,
+ const uno::Reference< chart::XChartData >& rS ) :
+ xListener( rL ), xSource( rS ) {}
+ ~ScChartUnoData() {}
+
+ const uno::Reference< chart::XChartDataChangeEventListener >& GetListener() const { return xListener; }
+ const uno::Reference< chart::XChartData >& GetSource() const { return xSource; }
+};
+
+
+// === ScChartListener ================================================
+
+ScChartListener::ExternalRefListener::ExternalRefListener(ScChartListener& rParent, ScDocument* pDoc) :
+ mrParent(rParent), mpDoc(pDoc)
+{
+}
+
+ScChartListener::ExternalRefListener::~ExternalRefListener()
+{
+ if (!mpDoc || mpDoc->IsInDtorClear())
+ // The document is being destroyed. Do nothing.
+ return;
+
+ // Make sure to remove all pointers to this object.
+ mpDoc->GetExternalRefManager()->removeLinkListener(this);
+}
+
+void ScChartListener::ExternalRefListener::notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType)
+{
+ switch (eType)
+ {
+ case ScExternalRefManager::LINK_MODIFIED:
+ {
+ if (maFileIds.count(nFileId))
+ // We are listening to this external document. Send an update
+ // requst to the chart.
+ mrParent.SetUpdateQueue();
+ }
+ break;
+ case ScExternalRefManager::LINK_BROKEN:
+ removeFileId(nFileId);
+ break;
+ }
+}
+
+void ScChartListener::ExternalRefListener::addFileId(sal_uInt16 nFileId)
+{
+ maFileIds.insert(nFileId);
+}
+
+void ScChartListener::ExternalRefListener::removeFileId(sal_uInt16 nFileId)
+{
+ maFileIds.erase(nFileId);
+}
+
+hash_set<sal_uInt16>& ScChartListener::ExternalRefListener::getAllFileIds()
+{
+ return maFileIds;
+}
+
+// ----------------------------------------------------------------------------
+
+ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
+ const ScRange& rRange ) :
+ StrData( rName ),
+ SvtListener(),
+ mpExtRefListener(NULL),
+ mpTokens(new vector<ScSharedTokenRef>),
+ pUnoData( NULL ),
+ pDoc( pDocP ),
+ bUsed( FALSE ),
+ bDirty( FALSE ),
+ bSeriesRangesScheduled( FALSE )
+{
+ SetRangeList( rRange );
+}
+
+ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
+ const ScRangeListRef& rRangeList ) :
+ StrData( rName ),
+ SvtListener(),
+ mpExtRefListener(NULL),
+ mpTokens(new vector<ScSharedTokenRef>),
+ pUnoData( NULL ),
+ pDoc( pDocP ),
+ bUsed( FALSE ),
+ bDirty( FALSE ),
+ bSeriesRangesScheduled( FALSE )
+{
+ ScRefTokenHelper::getTokensFromRangeList(*mpTokens, *rRangeList);
+}
+
+ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP, vector<ScSharedTokenRef>* pTokens ) :
+ StrData( rName ),
+ SvtListener(),
+ mpExtRefListener(NULL),
+ mpTokens(pTokens),
+ pUnoData( NULL ),
+ pDoc( pDocP ),
+ bUsed( FALSE ),
+ bDirty( FALSE ),
+ bSeriesRangesScheduled( FALSE )
+{
+}
+
+ScChartListener::ScChartListener( const ScChartListener& r ) :
+ StrData( r ),
+ SvtListener(),
+ mpExtRefListener(NULL),
+ mpTokens(new vector<ScSharedTokenRef>(*r.mpTokens)),
+ pUnoData( NULL ),
+ pDoc( r.pDoc ),
+ bUsed( FALSE ),
+ bDirty( r.bDirty ),
+ bSeriesRangesScheduled( r.bSeriesRangesScheduled )
+{
+ if ( r.pUnoData )
+ pUnoData = new ScChartUnoData( *r.pUnoData );
+
+ if (r.mpExtRefListener.get())
+ {
+ // Re-register this new listener for the files that the old listener
+ // was listening to.
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const hash_set<sal_uInt16>& rFileIds = r.mpExtRefListener->getAllFileIds();
+ mpExtRefListener.reset(new ExternalRefListener(*this, pDoc));
+ hash_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ pRefMgr->addLinkListener(*itr, mpExtRefListener.get());
+ mpExtRefListener->addFileId(*itr);
+ }
+ }
+}
+
+ScChartListener::~ScChartListener()
+{
+ if ( HasBroadcaster() )
+ EndListeningTo();
+ delete pUnoData;
+
+ if (mpExtRefListener.get())
+ {
+ // Stop listening to all external files.
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const hash_set<sal_uInt16>& rFileIds = mpExtRefListener->getAllFileIds();
+ hash_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
+ for (; itr != itrEnd; ++itr)
+ pRefMgr->removeLinkListener(*itr, mpExtRefListener.get());
+ }
+}
+
+ScDataObject* ScChartListener::Clone() const
+{
+ return new ScChartListener( *this );
+}
+
+void ScChartListener::SetUno(
+ const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
+ const uno::Reference< chart::XChartData >& rSource )
+{
+// DBG_ASSERT( rListener.is() && rSource.is(), "Nullpointer bei SetUno" );
+ delete pUnoData;
+ pUnoData = new ScChartUnoData( rListener, rSource );
+}
+
+uno::Reference< chart::XChartDataChangeEventListener > ScChartListener::GetUnoListener() const
+{
+ if ( pUnoData )
+ return pUnoData->GetListener();
+ return uno::Reference< chart::XChartDataChangeEventListener >();
+}
+
+uno::Reference< chart::XChartData > ScChartListener::GetUnoSource() const
+{
+ if ( pUnoData )
+ return pUnoData->GetSource();
+ return uno::Reference< chart::XChartData >();
+}
+
+void ScChartListener::Notify( SvtBroadcaster&, const SfxHint& rHint )
+{
+ const ScHint* p = dynamic_cast<const ScHint*>(&rHint);
+ if (p && (p->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)))
+ SetUpdateQueue();
+}
+
+void ScChartListener::Update()
+{
+ if ( pDoc->IsInInterpreter() )
+ { // #73482# If interpreting do nothing and restart timer so we don't
+ // interfere with interpreter and don't produce an Err522 or similar.
+ // This may happen if we are rescheduled via Basic function.
+ pDoc->GetChartListenerCollection()->StartTimer();
+ return ;
+ }
+ if ( pUnoData )
+ {
+ bDirty = FALSE;
+ //! irgendwann mal erkennen, was sich innerhalb des Charts geaendert hat
+ chart::ChartDataChangeEvent aEvent( pUnoData->GetSource(),
+ chart::ChartDataChangeType_ALL,
+ 0, 0, 0, 0 );
+ pUnoData->GetListener()->chartDataChanged( aEvent );
+ }
+ else if ( pDoc->GetAutoCalc() )
+ {
+ bDirty = FALSE;
+ pDoc->UpdateChart( GetString());
+ }
+}
+
+ScRangeListRef ScChartListener::GetRangeList() const
+{
+ ScRangeListRef aRLRef(new ScRangeList);
+ ScRefTokenHelper::getRangeListFromTokens(*aRLRef, *mpTokens);
+ return aRLRef;
+}
+
+void ScChartListener::SetRangeList( const ScRangeListRef& rNew )
+{
+ vector<ScSharedTokenRef> aTokens;
+ ScRefTokenHelper::getTokensFromRangeList(aTokens, *rNew);
+ mpTokens->swap(aTokens);
+}
+
+void ScChartListener::SetRangeList( const ScRange& rRange )
+{
+ ScSharedTokenRef pToken;
+ ScRefTokenHelper::getTokenFromRange(pToken, rRange);
+ mpTokens->push_back(pToken);
+}
+
+namespace {
+
+class StartEndListening : public unary_function<ScSharedTokenRef, void>
+{
+public:
+ StartEndListening(ScDocument* pDoc, ScChartListener& rParent, bool bStart) :
+ mpDoc(pDoc), mrParent(rParent), mbStart(bStart) {}
+
+ void operator() (const ScSharedTokenRef& pToken)
+ {
+ if (!ScRefTokenHelper::isRef(pToken))
+ return;
+
+ bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
+ if (bExternal)
+ {
+ sal_uInt16 nFileId = pToken->GetIndex();
+ ScExternalRefManager* pRefMgr = mpDoc->GetExternalRefManager();
+ ScChartListener::ExternalRefListener* pExtRefListener = mrParent.GetExtRefListener();
+ if (mbStart)
+ {
+ pRefMgr->addLinkListener(nFileId, pExtRefListener);
+ pExtRefListener->addFileId(nFileId);
+ }
+ else
+ {
+ pRefMgr->removeLinkListener(nFileId, pExtRefListener);
+ pExtRefListener->removeFileId(nFileId);
+ }
+ }
+ else
+ {
+ ScRange aRange;
+ ScRefTokenHelper::getRangeFromToken(aRange, pToken, bExternal);
+ if (mbStart)
+ startListening(aRange);
+ else
+ endListening(aRange);
+ }
+ }
+
+private:
+ void startListening(const ScRange& rRange)
+ {
+ if (rRange.aStart == rRange.aEnd)
+ mpDoc->StartListeningCell(rRange.aStart, &mrParent);
+ else
+ mpDoc->StartListeningArea(rRange, &mrParent);
+ }
+
+ void endListening(const ScRange& rRange)
+ {
+ if (rRange.aStart == rRange.aEnd)
+ mpDoc->EndListeningCell(rRange.aStart, &mrParent);
+ else
+ mpDoc->EndListeningArea(rRange, &mrParent);
+ }
+
+private:
+ ScDocument* mpDoc;
+ ScChartListener& mrParent;
+ bool mbStart;
+};
+
+}
+
+void ScChartListener::StartListeningTo()
+{
+ if (!mpTokens.get() || mpTokens->empty())
+ // no references to listen to.
+ return;
+
+ for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(pDoc, *this, true));
+}
+
+void ScChartListener::EndListeningTo()
+{
+ if (!mpTokens.get() || mpTokens->empty())
+ // no references to listen to.
+ return;
+
+ for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(pDoc, *this, false));
+}
+
+
+void ScChartListener::ChangeListening( const ScRangeListRef& rRangeListRef,
+ BOOL bDirtyP )
+{
+ EndListeningTo();
+ SetRangeList( rRangeListRef );
+ StartListeningTo();
+ if ( bDirtyP )
+ SetDirty( TRUE );
+}
+
+
+void ScChartListener::UpdateScheduledSeriesRanges()
+{
+ if ( bSeriesRangesScheduled )
+ {
+ bSeriesRangesScheduled = FALSE;
+ UpdateSeriesRanges();
+ }
+}
+
+
+void ScChartListener::UpdateChartIntersecting( const ScRange& rRange )
+{
+ ScSharedTokenRef pToken;
+ ScRefTokenHelper::getTokenFromRange(pToken, rRange);
+
+ if (ScRefTokenHelper::intersects(*mpTokens, pToken))
+ {
+ // force update (chart has to be loaded), don't use ScChartListener::Update
+ pDoc->UpdateChart( GetString());
+ }
+}
+
+
+void ScChartListener::UpdateSeriesRanges()
+{
+ ScRangeListRef pRangeList(new ScRangeList);
+ ScRefTokenHelper::getRangeListFromTokens(*pRangeList, *mpTokens);
+ pDoc->SetChartRangeList(GetString(), pRangeList);
+}
+
+ScChartListener::ExternalRefListener* ScChartListener::GetExtRefListener()
+{
+ if (!mpExtRefListener.get())
+ mpExtRefListener.reset(new ExternalRefListener(*this, pDoc));
+
+ return mpExtRefListener.get();
+}
+
+void ScChartListener::SetUpdateQueue()
+{
+ bDirty = true;
+ pDoc->GetChartListenerCollection()->StartTimer();
+}
+
+BOOL ScChartListener::operator==( const ScChartListener& r )
+{
+ bool b1 = (mpTokens.get() && !mpTokens->empty());
+ bool b2 = (r.mpTokens.get() && !r.mpTokens->empty());
+
+ if (pDoc != r.pDoc || bUsed != r.bUsed || bDirty != r.bDirty ||
+ bSeriesRangesScheduled != r.bSeriesRangesScheduled ||
+ GetString() != r.GetString() || b1 != b2)
+ return false;
+
+ if (!b1 && !b2)
+ // both token list instances are empty.
+ return true;
+
+ return *mpTokens == *r.mpTokens;
+}
+
+// ============================================================================
+
+ScChartHiddenRangeListener::ScChartHiddenRangeListener()
+{
+}
+
+ScChartHiddenRangeListener::~ScChartHiddenRangeListener()
+{
+ // empty d'tor
+}
+
+// === ScChartListenerCollection ======================================
+
+ScChartListenerCollection::RangeListenerItem::RangeListenerItem(const ScRange& rRange, ScChartHiddenRangeListener* p) :
+ maRange(rRange), mpListener(p)
+{
+}
+
+ScChartListenerCollection::ScChartListenerCollection( ScDocument* pDocP ) :
+ ScStrCollection( 4, 4, FALSE ),
+ pDoc( pDocP )
+{
+ aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
+}
+
+ScChartListenerCollection::ScChartListenerCollection(
+ const ScChartListenerCollection& rColl ) :
+ ScStrCollection( rColl ),
+ pDoc( rColl.pDoc )
+{
+ aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
+}
+
+ScChartListenerCollection::~ScChartListenerCollection()
+{
+ // #96783# remove ChartListener objects before aTimer dtor is called, because
+ // ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer
+ // to be called if an empty ScNoteCell is deleted
+
+ if (GetCount())
+ FreeAll();
+}
+
+ScDataObject* ScChartListenerCollection::Clone() const
+{
+ return new ScChartListenerCollection( *this );
+}
+
+void ScChartListenerCollection::StartAllListeners()
+{
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ((ScChartListener*) pItems[ nIndex ])->StartListeningTo();
+ }
+}
+
+void ScChartListenerCollection::ChangeListening( const String& rName,
+ const ScRangeListRef& rRangeListRef, BOOL bDirty )
+{
+ ScChartListener aCLSearcher( rName, pDoc, rRangeListRef );
+ ScChartListener* pCL;
+ USHORT nIndex;
+ if ( Search( &aCLSearcher, nIndex ) )
+ {
+ pCL = (ScChartListener*) pItems[ nIndex ];
+ pCL->EndListeningTo();
+ pCL->SetRangeList( rRangeListRef );
+ }
+ else
+ {
+ pCL = new ScChartListener( aCLSearcher );
+ Insert( pCL );
+ }
+ pCL->StartListeningTo();
+ if ( bDirty )
+ pCL->SetDirty( TRUE );
+}
+
+void ScChartListenerCollection::FreeUnused()
+{
+ // rueckwaerts wg. Pointer-Aufrueckerei im Array
+ for ( USHORT nIndex = nCount; nIndex-- >0; )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ // Uno-Charts nicht rauskicken
+ // (werden per FreeUno von aussen geloescht)
+ if ( !pCL->IsUno() )
+ {
+ if ( pCL->IsUsed() )
+ pCL->SetUsed( FALSE );
+ else
+ Free( pCL );
+ }
+ }
+}
+
+void ScChartListenerCollection::FreeUno( const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
+ const uno::Reference< chart::XChartData >& rSource )
+{
+ // rueckwaerts wg. Pointer-Aufrueckerei im Array
+ for ( USHORT nIndex = nCount; nIndex-- >0; )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ if ( pCL->IsUno() &&
+ pCL->GetUnoListener() == rListener &&
+ pCL->GetUnoSource() == rSource )
+ {
+ Free( pCL );
+ }
+ //! sollte nur einmal vorkommen?
+ }
+}
+
+void ScChartListenerCollection::StartTimer()
+{
+ aTimer.SetTimeout( SC_CHARTTIMEOUT );
+ aTimer.Start();
+}
+
+IMPL_LINK( ScChartListenerCollection, TimerHdl, Timer*, EMPTYARG )
+{
+ if ( Application::AnyInput( INPUT_KEYBOARD ) )
+ {
+ aTimer.Start();
+ return 0;
+ }
+ UpdateDirtyCharts();
+ return 0;
+}
+
+void ScChartListenerCollection::UpdateDirtyCharts()
+{
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ if ( pCL->IsDirty() )
+ pCL->Update();
+ if ( aTimer.IsActive() && !pDoc->IsImportingXML())
+ break; // da kam einer dazwischen
+ }
+}
+
+
+void ScChartListenerCollection::SetDirty()
+{
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ pCL->SetDirty( TRUE );
+ }
+ StartTimer();
+}
+
+
+void ScChartListenerCollection::SetDiffDirty(
+ const ScChartListenerCollection& rCmp, BOOL bSetChartRangeLists )
+{
+ BOOL bDirty = FALSE;
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ USHORT nFound;
+ BOOL bFound = rCmp.Search( pCL, nFound );
+ if ( !bFound || (*pCL != *((const ScChartListener*) rCmp.pItems[ nFound ])) )
+ {
+ if ( bSetChartRangeLists )
+ {
+ if ( bFound )
+ {
+ const ScRangeListRef& rList1 = pCL->GetRangeList();
+ const ScRangeListRef& rList2 =
+ ((const ScChartListener*) rCmp.pItems[ nFound ])->GetRangeList();
+ BOOL b1 = rList1.Is();
+ BOOL b2 = rList2.Is();
+ if ( b1 != b2 || (b1 && b2 && (*rList1 != *rList2)) )
+ pDoc->SetChartRangeList( pCL->GetString(), rList1 );
+ }
+ else
+ pDoc->SetChartRangeList( pCL->GetString(), pCL->GetRangeList() );
+ }
+ bDirty = TRUE;
+ pCL->SetDirty( TRUE );
+ }
+ }
+ if ( bDirty )
+ StartTimer();
+}
+
+
+void ScChartListenerCollection::SetRangeDirty( const ScRange& rRange )
+{
+ BOOL bDirty = FALSE;
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ const ScRangeListRef& rList = pCL->GetRangeList();
+ if ( rList.Is() && rList->Intersects( rRange ) )
+ {
+ bDirty = TRUE;
+ pCL->SetDirty( TRUE );
+ }
+ }
+ if ( bDirty )
+ StartTimer();
+
+ // New hidden range listener implementation
+ for (list<RangeListenerItem>::iterator itr = maHiddenListeners.begin(), itrEnd = maHiddenListeners.end();
+ itr != itrEnd; ++itr)
+ {
+ if (itr->maRange.Intersects(rRange))
+ itr->mpListener->notify();
+ }
+}
+
+
+void ScChartListenerCollection::UpdateScheduledSeriesRanges()
+{
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ pCL->UpdateScheduledSeriesRanges();
+ }
+}
+
+
+void ScChartListenerCollection::UpdateChartsContainingTab( SCTAB nTab )
+{
+ ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
+ pCL->UpdateChartIntersecting( aRange );
+ }
+}
+
+
+BOOL ScChartListenerCollection::operator==( const ScChartListenerCollection& r )
+{
+ // hier nicht ScStrCollection::operator==() verwenden, der umstaendlich via
+ // IsEqual und Compare laeuft, stattdessen ScChartListener::operator==()
+ if ( pDoc != r.pDoc || nCount != r.nCount )
+ return FALSE;
+ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ if ( *((ScChartListener*) pItems[ nIndex ]) !=
+ *((ScChartListener*) r.pItems[ nIndex ]) )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void ScChartListenerCollection::StartListeningHiddenRange( const ScRange& rRange, ScChartHiddenRangeListener* pListener )
+{
+ RangeListenerItem aItem(rRange, pListener);
+ maHiddenListeners.push_back(aItem);
+}
+
+namespace {
+
+struct MatchListener : public ::std::unary_function<
+ ScChartListenerCollection::RangeListenerItem, bool>
+{
+ MatchListener(const ScChartHiddenRangeListener* pMatch) :
+ mpMatch(pMatch)
+ {
+ }
+
+ bool operator() (const ScChartListenerCollection::RangeListenerItem& rItem) const
+ {
+ return mpMatch == rItem.mpListener;
+ }
+
+private:
+ const ScChartHiddenRangeListener* mpMatch;
+};
+
+}
+void ScChartListenerCollection::EndListeningHiddenRange( ScChartHiddenRangeListener* pListener )
+{
+ maHiddenListeners.remove_if(MatchListener(pListener));
+}
+
diff --git a/sc/source/core/tool/chartlock.cxx b/sc/source/core/tool/chartlock.cxx
new file mode 100644
index 000000000000..54a49fb4b4aa
--- /dev/null
+++ b/sc/source/core/tool/chartlock.cxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <vcl/svapp.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+
+#include "chartlock.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::WeakReference;
+
+#define SC_CHARTLOCKTIMEOUT 660
+
+// ====================================================================
+
+namespace
+{
+
+std::vector< WeakReference< frame::XModel > > lcl_getAllLivingCharts( ScDocument* pDoc )
+{
+ std::vector< WeakReference< frame::XModel > > aRet;
+ if( !pDoc )
+ return aRet;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (!pDrawLayer)
+ return aRet;
+
+ for (SCTAB nTab=0; nTab<=pDoc->GetMaxTableNumber(); nTab++)
+ {
+ if (pDoc->HasTable(nTab))
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if( pDoc->IsChart( pObject ) )
+ {
+ uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ uno::Reference< embed::XComponentSupplier > xCompSupp( xIPObj, uno::UNO_QUERY );
+ if( xCompSupp.is())
+ {
+ Reference< frame::XModel > xModel( xCompSupp->getComponent(), uno::UNO_QUERY );
+ if( xModel.is() )
+ aRet.push_back( xModel );
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ return aRet;
+}
+
+}//end anonymous namespace
+
+// === ScChartLockGuard ======================================
+
+ScChartLockGuard::ScChartLockGuard( ScDocument* pDoc ) :
+ maChartModels( lcl_getAllLivingCharts( pDoc ) )
+{
+ std::vector< WeakReference< frame::XModel > >::const_iterator aIter = maChartModels.begin();
+ const std::vector< WeakReference< frame::XModel > >::const_iterator aEnd = maChartModels.end();
+ for( ; aIter != aEnd; ++aIter )
+ {
+ try
+ {
+ Reference< frame::XModel > xModel( *aIter );
+ if( xModel.is())
+ xModel->lockControllers();
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in ScChartLockGuard");
+ }
+ }
+}
+
+ScChartLockGuard::~ScChartLockGuard()
+{
+ std::vector< WeakReference< frame::XModel > >::const_iterator aIter = maChartModels.begin();
+ const std::vector< WeakReference< frame::XModel > >::const_iterator aEnd = maChartModels.end();
+ for( ; aIter != aEnd; ++aIter )
+ {
+ try
+ {
+ Reference< frame::XModel > xModel( *aIter );
+ if( xModel.is())
+ xModel->unlockControllers();
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in ScChartLockGuard");
+ }
+ }
+}
+
+void ScChartLockGuard::AlsoLockThisChart( const Reference< frame::XModel >& xModel )
+{
+ if(!xModel.is())
+ return;
+
+ WeakReference< frame::XModel > xWeakModel(xModel);
+
+ std::vector< WeakReference< frame::XModel > >::iterator aFindIter(
+ ::std::find( maChartModels.begin(), maChartModels.end(), xWeakModel ) );
+
+ if( aFindIter == maChartModels.end() )
+ {
+ try
+ {
+ xModel->lockControllers();
+ maChartModels.push_back( xModel );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in ScChartLockGuard");
+ }
+ }
+}
+
+// === ScTemporaryChartLock ======================================
+
+ScTemporaryChartLock::ScTemporaryChartLock( ScDocument* pDocP ) :
+ mpDoc( pDocP )
+{
+ maTimer.SetTimeout( SC_CHARTLOCKTIMEOUT );
+ maTimer.SetTimeoutHdl( LINK( this, ScTemporaryChartLock, TimeoutHdl ) );
+}
+
+
+ScTemporaryChartLock::~ScTemporaryChartLock()
+{
+ mpDoc = 0;
+ StopLocking();
+}
+
+void ScTemporaryChartLock::StartOrContinueLocking()
+{
+ if(!mapScChartLockGuard.get())
+ mapScChartLockGuard = std::auto_ptr< ScChartLockGuard >( new ScChartLockGuard(mpDoc) );
+ maTimer.Start();
+}
+
+void ScTemporaryChartLock::StopLocking()
+{
+ maTimer.Stop();
+ mapScChartLockGuard.reset();
+}
+
+void ScTemporaryChartLock::AlsoLockThisChart( const Reference< frame::XModel >& xModel )
+{
+ if(mapScChartLockGuard.get())
+ mapScChartLockGuard->AlsoLockThisChart( xModel );
+}
+
+IMPL_LINK( ScTemporaryChartLock, TimeoutHdl, Timer*, EMPTYARG )
+{
+ mapScChartLockGuard.reset();
+ return 0;
+}
diff --git a/sc/source/core/tool/chartpos.cxx b/sc/source/core/tool/chartpos.cxx
new file mode 100644
index 000000000000..fc3d9bf51be2
--- /dev/null
+++ b/sc/source/core/tool/chartpos.cxx
@@ -0,0 +1,646 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/table.hxx>
+
+#include "chartpos.hxx"
+#include "document.hxx"
+#include "rechead.hxx"
+
+
+ScChartPositioner::ScChartPositioner( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP) :
+ pDocument( pDoc ),
+ pPositionMap( NULL ),
+ eGlue( SC_CHARTGLUE_NA ),
+ nStartCol(0),
+ nStartRow(0),
+ bColHeaders( FALSE ),
+ bRowHeaders( FALSE ),
+ bDummyUpperLeft( FALSE )
+{
+ SetRangeList( ScRange( nStartColP, nStartRowP, nTab, nEndColP, nEndRowP, nTab ) );
+ CheckColRowHeaders();
+}
+
+ScChartPositioner::ScChartPositioner( ScDocument* pDoc, const ScRangeListRef& rRangeList ) :
+ aRangeListRef( rRangeList ),
+ pDocument( pDoc ),
+ pPositionMap( NULL ),
+ eGlue( SC_CHARTGLUE_NA ),
+ nStartCol(0),
+ nStartRow(0),
+ bColHeaders( FALSE ),
+ bRowHeaders( FALSE ),
+ bDummyUpperLeft( FALSE )
+{
+ if ( aRangeListRef.Is() )
+ CheckColRowHeaders();
+}
+
+ScChartPositioner::ScChartPositioner( const ScChartPositioner& rPositioner ) :
+ aRangeListRef( rPositioner.aRangeListRef ),
+ pDocument(rPositioner.pDocument),
+ pPositionMap( NULL ),
+ eGlue(rPositioner.eGlue),
+ nStartCol(rPositioner.nStartCol),
+ nStartRow(rPositioner.nStartRow),
+ bColHeaders(rPositioner.bColHeaders),
+ bRowHeaders(rPositioner.bRowHeaders),
+ bDummyUpperLeft( rPositioner.bDummyUpperLeft )
+{
+}
+
+ScChartPositioner::~ScChartPositioner()
+{
+ delete pPositionMap;
+}
+
+BOOL ScChartPositioner::operator==(const ScChartPositioner& rCmp) const
+{
+ return bColHeaders == rCmp.bColHeaders
+ && bRowHeaders == rCmp.bRowHeaders
+ && *aRangeListRef == *rCmp.aRangeListRef;
+}
+
+void ScChartPositioner::SetRangeList( const ScRange& rRange )
+{
+ aRangeListRef = new ScRangeList;
+ aRangeListRef->Append( rRange );
+ InvalidateGlue();
+}
+
+void ScChartPositioner::GlueState()
+{
+ if ( eGlue != SC_CHARTGLUE_NA )
+ return;
+ bDummyUpperLeft = FALSE;
+ ScRangePtr pR;
+ if ( aRangeListRef->Count() <= 1 )
+ {
+ if ( (pR = aRangeListRef->First())!=NULL )
+ {
+ if ( pR->aStart.Tab() == pR->aEnd.Tab() )
+ eGlue = SC_CHARTGLUE_NONE;
+ else
+ eGlue = SC_CHARTGLUE_COLS; // mehrere Tabellen spaltenweise
+ nStartCol = pR->aStart.Col();
+ nStartRow = pR->aStart.Row();
+ }
+ else
+ {
+ InvalidateGlue();
+ nStartCol = 0;
+ nStartRow = 0;
+ }
+ return;
+ }
+// ULONG nOldPos = aRangeListRef->GetCurPos();
+
+ pR = aRangeListRef->First();
+ nStartCol = pR->aStart.Col();
+ nStartRow = pR->aStart.Row();
+ SCCOL nMaxCols, nEndCol;
+ SCROW nMaxRows, nEndRow;
+ nMaxCols = nEndCol = 0;
+ nMaxRows = nEndRow = 0;
+ do
+ { // umspannenden Bereich etc. feststellen
+ SCCOLROW nTmp, n1, n2;
+ if ( (n1 = pR->aStart.Col()) < nStartCol )
+ nStartCol = static_cast<SCCOL>(n1);
+ if ( (n2 = pR->aEnd.Col()) > nEndCol )
+ nEndCol = static_cast<SCCOL>(n2);
+ if ( (nTmp = n2 - n1 + 1) > nMaxCols )
+ nMaxCols = static_cast<SCCOL>(nTmp);
+ if ( (n1 = pR->aStart.Row()) < nStartRow )
+ nStartRow = static_cast<SCROW>(n1);
+ if ( (n2 = pR->aEnd.Row()) > nEndRow )
+ nEndRow = static_cast<SCROW>(n2);
+ if ( (nTmp = n2 - n1 + 1) > nMaxRows )
+ nMaxRows = static_cast<SCROW>(nTmp);
+ } while ( (pR = aRangeListRef->Next())!=NULL );
+ SCCOL nC = nEndCol - nStartCol + 1;
+ if ( nC == 1 )
+ {
+ eGlue = SC_CHARTGLUE_ROWS;
+ return;
+ }
+ SCROW nR = nEndRow - nStartRow + 1;
+ if ( nR == 1 )
+ {
+ eGlue = SC_CHARTGLUE_COLS;
+ return;
+ }
+ ULONG nCR = (ULONG)nC * nR;
+//2do:
+/*
+ Erstmal simpel ohne Bitmaskiererei, maximal koennten so 8MB alloziert
+ werden (256 Cols mal 32000 Rows), das liesse sich mit 2 Bit je Eintrag
+ auf 2MB reduzieren, andererseits ist es so schneller.
+ Weitere Platz-Optimierung waere, in dem Array nur die wirklich benutzten
+ Zeilen/Spalten abzulegen, wuerde aber ein weiteres durchlaufen der
+ RangeList und indirekten Zugriff auf das Array bedeuten.
+ */
+ const BYTE nHole = 0;
+ const BYTE nOccu = 1;
+ const BYTE nFree = 2;
+ const BYTE nGlue = 3;
+#ifdef WIN
+ // we hate 16bit, don't we?
+ BYTE huge* p;
+ BYTE huge* pA = (BYTE huge*) SvMemAlloc( nCR );
+ if ( nCR > (ULONG)((USHORT)~0) )
+ { // in 32k Bloecken initialisieren
+ ULONG j;
+ for ( j=0; j<nCR; j+=0x8000 )
+ {
+ memset( pA+j, nHole, Min( (ULONG)0x8000, nCR-j ) );
+ }
+ }
+ else
+ memset( pA, nHole, nCR * sizeof(BYTE) );
+#else
+ BYTE* p;
+ BYTE* pA = new BYTE[ nCR ];
+ memset( pA, 0, nCR * sizeof(BYTE) );
+#endif
+
+ SCCOL nCol, nCol1, nCol2;
+ SCROW nRow, nRow1, nRow2;
+ for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() )
+ { // Selektionen 2D als belegt markieren
+ nCol1 = pR->aStart.Col() - nStartCol;
+ nCol2 = pR->aEnd.Col() - nStartCol;
+ nRow1 = pR->aStart.Row() - nStartRow;
+ nRow2 = pR->aEnd.Row() - nStartRow;
+ for ( nCol = nCol1; nCol <= nCol2; nCol++ )
+ {
+ p = pA + (ULONG)nCol * nR + nRow1;
+ for ( nRow = nRow1; nRow <= nRow2; nRow++, p++ )
+ *p = nOccu;
+ }
+ }
+ BOOL bGlue = TRUE;
+
+ BOOL bGlueCols = FALSE;
+ for ( nCol = 0; bGlue && nCol < nC; nCol++ )
+ { // Spalten probieren durchzugehen und als frei markieren
+ p = pA + (ULONG)nCol * nR;
+ for ( nRow = 0; bGlue && nRow < nR; nRow++, p++ )
+ {
+ if ( *p == nOccu )
+ { // Wenn einer mittendrin liegt ist keine Zusammenfassung
+ // moeglich. Am Rand koennte ok sein, wenn in dieser Spalte
+ // in jeder belegten Zeile einer belegt ist.
+ if ( nRow > 0 && nCol > 0 )
+ bGlue = FALSE; // nCol==0 kann DummyUpperLeft sein
+ else
+ nRow = nR;
+ }
+ else
+ *p = nFree;
+ }
+ if ( bGlue && *(p = (pA + ((((ULONG)nCol+1) * nR) - 1))) == nFree )
+ { // Spalte als komplett frei markieren
+ *p = nGlue;
+ bGlueCols = TRUE; // mindestens eine freie Spalte
+ }
+ }
+
+ BOOL bGlueRows = FALSE;
+ for ( nRow = 0; bGlue && nRow < nR; nRow++ )
+ { // Zeilen probieren durchzugehen und als frei markieren
+ p = pA + nRow;
+ for ( nCol = 0; bGlue && nCol < nC; nCol++, p+=nR )
+ {
+ if ( *p == nOccu )
+ {
+ if ( nCol > 0 && nRow > 0 )
+ bGlue = FALSE; // nRow==0 kann DummyUpperLeft sein
+ else
+ nCol = nC;
+ }
+ else
+ *p = nFree;
+ }
+ if ( bGlue && *(p = (pA + ((((ULONG)nC-1) * nR) + nRow))) == nFree )
+ { // Zeile als komplett frei markieren
+ *p = nGlue;
+ bGlueRows = TRUE; // mindestens eine freie Zeile
+ }
+ }
+
+ // n=1: die linke obere Ecke koennte bei Beschriftung automagisch
+ // hinzugezogen werden
+ p = pA + 1;
+ for ( ULONG n = 1; bGlue && n < nCR; n++, p++ )
+ { // ein unberuehrtes Feld heisst, dass es weder spaltenweise noch
+ // zeilenweise zu erreichen war, also nichts zusamenzufassen
+ if ( *p == nHole )
+ bGlue = FALSE;
+ }
+ if ( bGlue )
+ {
+ if ( bGlueCols && bGlueRows )
+ eGlue = SC_CHARTGLUE_BOTH;
+ else if ( bGlueRows )
+ eGlue = SC_CHARTGLUE_ROWS;
+ else
+ eGlue = SC_CHARTGLUE_COLS;
+ if ( *pA != nOccu )
+ bDummyUpperLeft = TRUE;
+ }
+ else
+ {
+ eGlue = SC_CHARTGLUE_NONE;
+ }
+
+#ifdef WIN
+ SvMemFree( pA );
+#else
+ delete [] pA;
+#endif
+}
+
+void ScChartPositioner::CheckColRowHeaders()
+{
+ SCCOL nCol1, nCol2, iCol;
+ SCROW nRow1, nRow2, iRow;
+ SCTAB nTab1, nTab2;
+
+ BOOL bColStrings = TRUE;
+ BOOL bRowStrings = TRUE;
+ GlueState();
+ if ( aRangeListRef->Count() == 1 )
+ {
+ aRangeListRef->First()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if ( nCol1 > nCol2 || nRow1 > nRow2 )
+ bColStrings = bRowStrings = FALSE;
+ else
+ {
+ for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++)
+ {
+ if (pDocument->HasValueData( iCol, nRow1, nTab1 ))
+ bColStrings = FALSE;
+ }
+ for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++)
+ {
+ if (pDocument->HasValueData( nCol1, iRow, nTab1 ))
+ bRowStrings = FALSE;
+ }
+ }
+ }
+ else
+ {
+ BOOL bVert = (eGlue == SC_CHARTGLUE_NONE || eGlue == SC_CHARTGLUE_ROWS);
+ for ( ScRangePtr pR = aRangeListRef->First();
+ pR && (bColStrings || bRowStrings);
+ pR = aRangeListRef->Next() )
+ {
+ pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ BOOL bTopRow = (nRow1 == nStartRow);
+ if ( bRowStrings && (bVert || nCol1 == nStartCol) )
+ { // NONE oder ROWS: RowStrings in jeder Selektion moeglich
+ // COLS oder BOTH: nur aus der ersten Spalte
+ if ( nCol1 <= nCol2 )
+ for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++)
+ {
+ if (pDocument->HasValueData( nCol1, iRow, nTab1 ))
+ bRowStrings = FALSE;
+ }
+ }
+ if ( bColStrings && bTopRow )
+ { // ColStrings nur aus der ersten Zeile
+ if ( nRow1 <= nRow2 )
+ for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++)
+ {
+ if (pDocument->HasValueData( iCol, nRow1, nTab1 ))
+ bColStrings = FALSE;
+ }
+ }
+ }
+ }
+ bColHeaders = bColStrings;
+ bRowHeaders = bRowStrings;
+}
+
+const ScChartPositionMap* ScChartPositioner::GetPositionMap()
+{
+ CreatePositionMap();
+ return pPositionMap;
+}
+
+
+void ScChartPositioner::CreatePositionMap()
+{
+ if ( eGlue == SC_CHARTGLUE_NA && pPositionMap )
+ {
+ delete pPositionMap;
+ pPositionMap = NULL;
+ }
+
+ if ( pPositionMap )
+ return ;
+
+ SCSIZE nColAdd = bRowHeaders ? 1 : 0;
+ SCSIZE nRowAdd = bColHeaders ? 1 : 0;
+
+ SCCOL nCol, nCol1, nCol2;
+ SCROW nRow, nRow1, nRow2;
+ SCTAB nTab, nTab1, nTab2;
+
+ //
+ // wirkliche Groesse (ohne versteckte Zeilen/Spalten)
+ //
+
+ SCSIZE nColCount = 0;
+ SCSIZE nRowCount = 0;
+
+ GlueState();
+
+ BOOL bNoGlue = (eGlue == SC_CHARTGLUE_NONE);
+ Table* pCols = new Table;
+ Table* pNewRowTable = new Table;
+ ScAddress* pNewAddress = new ScAddress;
+ ScRangePtr pR;
+ Table* pCol;
+ ScAddress* pPos;
+ SCROW nNoGlueRow = 0;
+ for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() )
+ {
+ pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ for ( nTab = nTab1; nTab <= nTab2; nTab++ )
+ {
+ // nTab im ColKey, um gleiche Col/Row in anderer Table haben zu koennen
+ ULONG nInsCol = (static_cast<ULONG>(nTab) << 16) | (bNoGlue ? 0 :
+ static_cast<ULONG>(nCol1));
+ for ( nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol )
+ {
+ if ( bNoGlue || eGlue == SC_CHARTGLUE_ROWS )
+ { // meistens gleiche Cols
+ if ( (pCol = (Table*) pCols->Get( nInsCol ))==NULL )
+ {
+ pCols->Insert( nInsCol, pNewRowTable );
+ pCol = pNewRowTable;
+ pNewRowTable = new Table;
+ }
+ }
+ else
+ { // meistens neue Cols
+ if ( pCols->Insert( nInsCol, pNewRowTable ) )
+ {
+ pCol = pNewRowTable;
+ pNewRowTable = new Table;
+ }
+ else
+ pCol = (Table*) pCols->Get( nInsCol );
+ }
+ // bei anderer Tabelle wurde bereits neuer ColKey erzeugt,
+ // die Zeilen muessen fuer's Dummy fuellen gleich sein!
+ ULONG nInsRow = (bNoGlue ? nNoGlueRow : nRow1);
+ for ( nRow = nRow1; nRow <= nRow2; nRow++, nInsRow++ )
+ {
+ if ( pCol->Insert( nInsRow, pNewAddress ) )
+ {
+ pNewAddress->Set( nCol, nRow, nTab );
+ pNewAddress = new ScAddress;
+ }
+ }
+ }
+ }
+ // bei NoGlue werden zusammengehoerige Tabellen als ColGlue dargestellt
+ nNoGlueRow += nRow2 - nRow1 + 1;
+ }
+ delete pNewAddress;
+ delete pNewRowTable;
+
+ // Anzahl der Daten
+ nColCount = static_cast< SCSIZE >( pCols->Count());
+ if ( (pCol = (Table*) pCols->First())!=NULL )
+ {
+ if ( bDummyUpperLeft )
+ pCol->Insert( 0, (void*)0 ); // Dummy fuer Beschriftung
+ nRowCount = static_cast< SCSIZE >( pCol->Count());
+ }
+ else
+ nRowCount = 0;
+ if ( nColCount > 0 )
+ nColCount -= nColAdd;
+ if ( nRowCount > 0 )
+ nRowCount -= nRowAdd;
+
+ if ( nColCount==0 || nRowCount==0 )
+ { // einen Eintrag ohne Daten erzeugen
+ pR = aRangeListRef->First();
+ if ( pCols->Count() > 0 )
+ pCol = (Table*) pCols->First();
+ else
+ {
+ pCol = new Table;
+ pCols->Insert( 0, pCol );
+ }
+ nColCount = 1;
+ if ( pCol->Count() > 0 )
+ { // kann ja eigentlich nicht sein, wenn nColCount==0 || nRowCount==0
+ pPos = (ScAddress*) pCol->First();
+ if ( pPos )
+ {
+ delete pPos;
+ pCol->Replace( pCol->GetCurKey(), (void*)0 );
+ }
+ }
+ else
+ pCol->Insert( 0, (void*)0 );
+ nRowCount = 1;
+ nColAdd = 0;
+ nRowAdd = 0;
+ }
+ else
+ {
+ if ( bNoGlue )
+ { // Luecken mit Dummies fuellen, erste Spalte ist Master
+ Table* pFirstCol = (Table*) pCols->First();
+ ULONG nCount = pFirstCol->Count();
+ pFirstCol->First();
+ for ( ULONG n = 0; n < nCount; n++, pFirstCol->Next() )
+ {
+ ULONG nKey = pFirstCol->GetCurKey();
+ pCols->First();
+ while ( (pCol = (Table*) pCols->Next())!=NULL )
+ pCol->Insert( nKey, (void*)0 ); // keine Daten
+ }
+ }
+ }
+
+ pPositionMap = new ScChartPositionMap( static_cast<SCCOL>(nColCount), static_cast<SCROW>(nRowCount),
+ static_cast<SCCOL>(nColAdd), static_cast<SCROW>(nRowAdd), *pCols );
+
+ // Aufraeumen
+ for ( pCol = (Table*) pCols->First(); pCol; pCol = (Table*) pCols->Next() )
+ { //! nur Tables loeschen, nicht die ScAddress*
+ delete pCol;
+ }
+ delete pCols;
+}
+
+
+ScChartPositionMap::ScChartPositionMap( SCCOL nChartCols, SCROW nChartRows,
+ SCCOL nColAdd, SCROW nRowAdd, Table& rCols ) :
+ ppData( new ScAddress* [ nChartCols * nChartRows ] ),
+ ppColHeader( new ScAddress* [ nChartCols ] ),
+ ppRowHeader( new ScAddress* [ nChartRows ] ),
+ nCount( (ULONG) nChartCols * nChartRows ),
+ nColCount( nChartCols ),
+ nRowCount( nChartRows )
+{
+ DBG_ASSERT( nColCount && nRowCount, "ScChartPositionMap without dimension" );
+#ifdef WIN
+#error ScChartPositionMap not implemented for 16-bit dumdums
+#endif
+
+ ScAddress* pPos;
+ SCCOL nCol;
+ SCROW nRow;
+
+ Table* pCol = (Table*) rCols.First();
+
+ // Zeilen-Header
+ pPos = (ScAddress*) pCol->First();
+ if ( nRowAdd )
+ pPos = (ScAddress*) pCol->Next();
+ if ( nColAdd )
+ { // eigenstaendig
+ for ( nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ ppRowHeader[ nRow ] = pPos;
+ pPos = (ScAddress*) pCol->Next();
+ }
+ }
+ else
+ { // Kopie
+ for ( nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ ppRowHeader[ nRow ] = ( pPos ? new ScAddress( *pPos ) : NULL );
+ pPos = (ScAddress*) pCol->Next();
+ }
+ }
+ if ( nColAdd )
+ pCol = (Table*) rCols.Next();
+
+ // Daten spaltenweise und Spalten-Header
+ ULONG nIndex = 0;
+ for ( nCol = 0; nCol < nColCount; nCol++ )
+ {
+ if ( pCol )
+ {
+ pPos = (ScAddress*) pCol->First();
+ if ( nRowAdd )
+ {
+ ppColHeader[ nCol ] = pPos; // eigenstaendig
+ pPos = (ScAddress*) pCol->Next();
+ }
+ else
+ ppColHeader[ nCol ] = ( pPos ? new ScAddress( *pPos ) : NULL );
+ for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
+ {
+ ppData[ nIndex ] = pPos;
+ pPos = (ScAddress*) pCol->Next();
+ }
+ }
+ else
+ {
+ ppColHeader[ nCol ] = NULL;
+ for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
+ {
+ ppData[ nIndex ] = NULL;
+ }
+ }
+ pCol = (Table*) rCols.Next();
+ }
+}
+
+
+ScChartPositionMap::~ScChartPositionMap()
+{
+ for ( ULONG nIndex=0; nIndex < nCount; nIndex++ )
+ {
+ delete ppData[nIndex];
+ }
+ delete [] ppData;
+
+ SCCOL j;
+ for ( j=0; j < nColCount; j++ )
+ {
+ delete ppColHeader[j];
+ }
+ delete [] ppColHeader;
+ SCROW i;
+ for ( i=0; i < nRowCount; i++ )
+ {
+ delete ppRowHeader[i];
+ }
+ delete [] ppRowHeader;
+}
+
+
+//UNUSED2009-05 ScRangeListRef ScChartPositionMap::GetColRanges( SCCOL nChartCol ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 ScRangeListRef xRangeList = new ScRangeList;
+//UNUSED2009-05 if ( nChartCol < nColCount )
+//UNUSED2009-05 {
+//UNUSED2009-05 ULONG nStop = GetIndex( nChartCol, nRowCount );
+//UNUSED2009-05 for ( ULONG nIndex = GetIndex( nChartCol, 0 ); nIndex < nStop; nIndex++ )
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( ppData[ nIndex ] )
+//UNUSED2009-05 xRangeList->Join( *ppData[ nIndex ] );
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 return xRangeList;
+//UNUSED2009-05 }
+
+
+//UNUSED2009-05 ScRangeListRef ScChartPositionMap::GetRowRanges( SCROW nChartRow ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 ScRangeListRef xRangeList = new ScRangeList;
+//UNUSED2009-05 if ( nChartRow < nRowCount )
+//UNUSED2009-05 {
+//UNUSED2009-05 ULONG nStop = GetIndex( nColCount, nChartRow );
+//UNUSED2009-05 for ( ULONG nIndex = GetIndex( 0, nChartRow ); nIndex < nStop;
+//UNUSED2009-05 nIndex += nRowCount )
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( ppData[ nIndex ] )
+//UNUSED2009-05 xRangeList->Join( *ppData[ nIndex ] );
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 return xRangeList;
+//UNUSED2009-05 }
diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx
new file mode 100644
index 000000000000..ba3f3e47bfb7
--- /dev/null
+++ b/sc/source/core/tool/chgtrack.cxx
@@ -0,0 +1,4869 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <tools/debug.hxx>
+#include <tools/shl.hxx> // SHL_CALC
+#include <tools/stack.hxx>
+#include <tools/rtti.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/itemset.hxx>
+#include <svl/isethint.hxx>
+#include <svl/itempool.hxx>
+#include <sfx2/app.hxx>
+#include <unotools/useroptions.hxx>
+#include <sfx2/sfxsids.hrc>
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "global.hxx"
+#include "rechead.hxx"
+#include "scerrors.hxx"
+#include "scmod.hxx" // SC_MOD
+#include "inputopt.hxx" // GetExpandRefs
+#include "patattr.hxx"
+#include "hints.hxx"
+
+#include "globstr.hrc"
+
+#include <stack>
+
+#define SC_CHGTRACK_CXX
+#include "chgtrack.hxx"
+
+DECLARE_STACK( ScChangeActionStack, ScChangeAction* )
+
+const USHORT nMemPoolChangeActionCellListEntry = (0x2000 - 64) / sizeof(ScChangeActionCellListEntry);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry, nMemPoolChangeActionCellListEntry, nMemPoolChangeActionCellListEntry )
+
+const USHORT nMemPoolChangeActionLinkEntry = (0x8000 - 64) / sizeof(ScChangeActionLinkEntry);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry, nMemPoolChangeActionLinkEntry, nMemPoolChangeActionLinkEntry )
+
+// loaded MSB > eigenes => inkompatibel
+#define SC_CHGTRACK_FILEFORMAT_FIRST 0x0001
+#define SC_CHGTRACK_FILEFORMAT 0x0001
+
+// --- ScChangeActionLinkEntry ---------------------------------------------
+
+#if DEBUG_CHANGETRACK
+String ScChangeActionLinkEntry::ToString() const
+{
+ String aReturn;
+ if ( pAction )
+ {
+ aReturn = String::CreateFromInt64( static_cast< sal_Int64 >( pAction->GetActionNumber() ) );
+ }
+ else if ( pLink && pLink->pAction )
+ {
+ aReturn = String::CreateFromAscii( "*" );
+ aReturn += String::CreateFromInt64( static_cast< sal_Int64 >( pLink->pAction->GetActionNumber() ) );
+ }
+ else
+ {
+ aReturn = String::CreateFromAscii( "-" );
+ }
+
+ return aReturn;
+}
+#endif // DEBUG_CHANGETRACK
+
+// --- ScChangeAction ------------------------------------------------------
+
+ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScRange& rRange )
+ :
+ aBigRange( rRange ),
+ pNext( NULL ),
+ pPrev( NULL ),
+ pLinkAny( NULL ),
+ pLinkDeletedIn( NULL ),
+ pLinkDeleted( NULL ),
+ pLinkDependent( NULL ),
+ nAction( 0 ),
+ nRejectAction( 0 ),
+ eType( eTypeP ),
+ eState( SC_CAS_VIRGIN )
+{
+ aDateTime.ConvertToUTC();
+}
+
+ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScBigRange& rRange,
+ const ULONG nTempAction, const ULONG nTempRejectAction,
+ const ScChangeActionState eTempState, const DateTime& aTempDateTime,
+ const String& aTempUser, const String& aTempComment)
+ :
+ aBigRange( rRange ),
+ aDateTime( aTempDateTime ),
+ aUser( aTempUser ),
+ aComment( aTempComment ),
+ pNext( NULL ),
+ pPrev( NULL ),
+ pLinkAny( NULL ),
+ pLinkDeletedIn( NULL ),
+ pLinkDeleted( NULL ),
+ pLinkDependent( NULL ),
+ nAction( nTempAction ),
+ nRejectAction( nTempRejectAction ),
+ eType( eTypeP ),
+ eState( eTempState )
+{
+}
+
+ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScBigRange& rRange,
+ const ULONG nTempAction)
+ :
+ aBigRange( rRange ),
+ pNext( NULL ),
+ pPrev( NULL ),
+ pLinkAny( NULL ),
+ pLinkDeletedIn( NULL ),
+ pLinkDeleted( NULL ),
+ pLinkDependent( NULL ),
+ nAction( nTempAction ),
+ nRejectAction( 0 ),
+ eType( eTypeP ),
+ eState( SC_CAS_VIRGIN )
+{
+ aDateTime.ConvertToUTC();
+}
+
+
+ScChangeAction::~ScChangeAction()
+{
+ RemoveAllLinks();
+}
+
+
+BOOL ScChangeAction::IsVisible() const
+{
+ //! sequence order of execution is significant
+ if ( IsRejected() || GetType() == SC_CAT_DELETE_TABS || IsDeletedIn() )
+ return FALSE;
+ if ( GetType() == SC_CAT_CONTENT )
+ return ((ScChangeActionContent*)this)->IsTopContent();
+ return TRUE;
+}
+
+
+BOOL ScChangeAction::IsTouchable() const
+{
+ //! sequence order of execution is significant
+ if ( IsRejected() || GetType() == SC_CAT_REJECT || IsDeletedIn() )
+ return FALSE;
+ // content may reject and be touchable if on top
+ if ( GetType() == SC_CAT_CONTENT )
+ return ((ScChangeActionContent*)this)->IsTopContent();
+ if ( IsRejecting() )
+ return FALSE;
+ return TRUE;
+}
+
+
+BOOL ScChangeAction::IsClickable() const
+{
+ //! sequence order of execution is significant
+ if ( !IsVirgin() )
+ return FALSE;
+ if ( IsDeletedIn() )
+ return FALSE;
+ if ( GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContentCellType eCCT =
+ ScChangeActionContent::GetContentCellType(
+ ((ScChangeActionContent*)this)->GetNewCell() );
+ if ( eCCT == SC_CACCT_MATREF )
+ return FALSE;
+ if ( eCCT == SC_CACCT_MATORG )
+ { // no Accept-Select if one of the references is in a deleted col/row
+ const ScChangeActionLinkEntry* pL =
+ ((ScChangeActionContent*)this)->GetFirstDependentEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p && p->IsDeletedIn() )
+ return FALSE;
+ pL = pL->GetNext();
+ }
+ }
+ return TRUE; // for Select() a content doesn't have to be touchable
+ }
+ return IsTouchable(); // Accept()/Reject() only on touchables
+}
+
+
+BOOL ScChangeAction::IsRejectable() const
+{
+ //! sequence order of execution is significant
+ if ( !IsClickable() )
+ return FALSE;
+ if ( GetType() == SC_CAT_CONTENT )
+ {
+ if ( ((ScChangeActionContent*)this)->IsOldMatrixReference() )
+ return FALSE;
+ ScChangeActionContent* pNextContent =
+ ((ScChangeActionContent*)this)->GetNextContent();
+ if ( pNextContent == NULL )
+ return TRUE; // *this is TopContent
+ return pNextContent->IsRejected(); // *this is next rejectable
+ }
+ return IsTouchable();
+}
+
+
+BOOL ScChangeAction::IsInternalRejectable() const
+{
+ //! sequence order of execution is significant
+ if ( !IsVirgin() )
+ return FALSE;
+ if ( IsDeletedIn() )
+ return FALSE;
+ if ( GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContent* pNextContent =
+ ((ScChangeActionContent*)this)->GetNextContent();
+ if ( pNextContent == NULL )
+ return TRUE; // *this is TopContent
+ return pNextContent->IsRejected(); // *this is next rejectable
+ }
+ return IsTouchable();
+}
+
+
+BOOL ScChangeAction::IsDialogRoot() const
+{
+ return IsInternalRejectable(); // only rejectables in root
+}
+
+
+BOOL ScChangeAction::IsDialogParent() const
+{
+ //! sequence order of execution is significant
+ if ( GetType() == SC_CAT_CONTENT )
+ {
+ if ( !IsDialogRoot() )
+ return FALSE;
+ if ( ((ScChangeActionContent*)this)->IsMatrixOrigin() && HasDependent() )
+ return TRUE;
+ ScChangeActionContent* pPrevContent =
+ ((ScChangeActionContent*)this)->GetPrevContent();
+ return pPrevContent && pPrevContent->IsVirgin();
+ }
+ if ( HasDependent() )
+ return IsDeleteType() ? TRUE : !IsDeletedIn();
+ if ( HasDeleted() )
+ {
+ if ( IsDeleteType() )
+ {
+ if ( IsDialogRoot() )
+ return TRUE;
+ ScChangeActionLinkEntry* pL = pLinkDeleted;
+ while ( pL )
+ {
+ ScChangeAction* p = pL->GetAction();
+ if ( p && p->GetType() != eType )
+ return TRUE;
+ pL = pL->GetNext();
+ }
+ }
+ else
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL ScChangeAction::IsMasterDelete() const
+{
+ if ( !IsDeleteType() )
+ return FALSE;
+ ScChangeActionDel* pDel = (ScChangeActionDel*) this;
+ return pDel->IsMultiDelete() && (pDel->IsTopDelete() || pDel->IsRejectable());
+}
+
+
+void ScChangeAction::RemoveAllLinks()
+{
+ RemoveAllAnyLinks();
+ RemoveAllDeletedIn();
+ RemoveAllDeleted();
+ RemoveAllDependent();
+}
+
+
+void ScChangeAction::RemoveAllAnyLinks()
+{
+ while ( pLinkAny )
+ delete pLinkAny; // rueckt sich selbst hoch
+}
+
+
+BOOL ScChangeAction::RemoveDeletedIn( const ScChangeAction* p )
+{
+ BOOL bRemoved = FALSE;
+ ScChangeActionLinkEntry* pL = GetDeletedIn();
+ while ( pL )
+ {
+ ScChangeActionLinkEntry* pNextLink = pL->GetNext();
+ if ( pL->GetAction() == p )
+ {
+ delete pL;
+ bRemoved = TRUE;
+ }
+ pL = pNextLink;
+ }
+ return bRemoved;
+}
+
+
+BOOL ScChangeAction::IsDeletedIn( const ScChangeAction* p ) const
+{
+ ScChangeActionLinkEntry* pL = GetDeletedIn();
+ while ( pL )
+ {
+ if ( pL->GetAction() == p )
+ return TRUE;
+ pL = pL->GetNext();
+ }
+ return FALSE;
+}
+
+
+void ScChangeAction::RemoveAllDeletedIn()
+{
+ //! nicht vom evtl. TopContent sondern wirklich dieser
+ while ( pLinkDeletedIn )
+ delete pLinkDeletedIn; // rueckt sich selbst hoch
+}
+
+
+BOOL ScChangeAction::IsDeletedInDelType( ScChangeActionType eDelType ) const
+{
+ ScChangeAction* p;
+ ScChangeActionLinkEntry* pL = GetDeletedIn();
+ if ( pL )
+ {
+ // InsertType fuer MergePrepare/MergeOwn
+ ScChangeActionType eInsType;
+ switch ( eDelType )
+ {
+ case SC_CAT_DELETE_COLS :
+ eInsType = SC_CAT_INSERT_COLS;
+ break;
+ case SC_CAT_DELETE_ROWS :
+ eInsType = SC_CAT_INSERT_ROWS;
+ break;
+ case SC_CAT_DELETE_TABS :
+ eInsType = SC_CAT_INSERT_TABS;
+ break;
+ default:
+ eInsType = SC_CAT_NONE;
+ }
+ while ( pL )
+ {
+ if ( (p = pL->GetAction()) != NULL &&
+ (p->GetType() == eDelType || p->GetType() == eInsType) )
+ return TRUE;
+ pL = pL->GetNext();
+ }
+ }
+ return FALSE;
+}
+
+
+void ScChangeAction::SetDeletedIn( ScChangeAction* p )
+{
+ ScChangeActionLinkEntry* pLink1 = AddDeletedIn( p );
+ ScChangeActionLinkEntry* pLink2;
+ if ( GetType() == SC_CAT_CONTENT )
+ pLink2 = p->AddDeleted( ((ScChangeActionContent*)this)->GetTopContent() );
+ else
+ pLink2 = p->AddDeleted( this );
+ pLink1->SetLink( pLink2 );
+}
+
+
+void ScChangeAction::RemoveAllDeleted()
+{
+ while ( pLinkDeleted )
+ delete pLinkDeleted; // rueckt sich selbst hoch
+}
+
+
+void ScChangeAction::RemoveAllDependent()
+{
+ while ( pLinkDependent )
+ delete pLinkDependent; // rueckt sich selbst hoch
+}
+
+
+DateTime ScChangeAction::GetDateTime() const
+{
+ DateTime aDT( aDateTime );
+ aDT.ConvertToLocalTime();
+ return aDT;
+}
+
+
+void ScChangeAction::UpdateReference( const ScChangeTrack* /* pTrack */,
+ UpdateRefMode eMode, const ScBigRange& rRange,
+ INT32 nDx, INT32 nDy, INT32 nDz )
+{
+ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() );
+}
+
+
+void ScChangeAction::GetDescription( String& rStr, ScDocument* /* pDoc */,
+ BOOL /* bSplitRange */, bool bWarning ) const
+{
+ if ( IsRejecting() && bWarning )
+ {
+ // #112261# Add comment if rejection may have resulted in references
+ // not properly restored in formulas. See specification at
+ // http://specs.openoffice.org/calc/ease-of-use/redlining_comment.sxw
+ if (GetType() == SC_CAT_MOVE)
+ {
+ rStr += ScGlobal::GetRscString(
+ STR_CHANGED_MOVE_REJECTION_WARNING);
+ rStr += ' ';
+ }
+ else if (IsInsertType())
+ {
+ rStr += ScGlobal::GetRscString(
+ STR_CHANGED_DELETE_REJECTION_WARNING);
+ rStr += ' ';
+ }
+ else
+ {
+ const ScChangeTrack* pCT = GetChangeTrack();
+ if (pCT)
+ {
+ ScChangeAction* pReject = pCT->GetActionOrGenerated(
+ GetRejectAction());
+ if (pReject)
+ {
+ if (pReject->GetType() == SC_CAT_MOVE)
+ {
+ rStr += ScGlobal::GetRscString(
+ STR_CHANGED_MOVE_REJECTION_WARNING);
+ rStr += ' ';
+ }
+ else if (pReject->IsDeleteType())
+ {
+ rStr += ScGlobal::GetRscString(
+ STR_CHANGED_DELETE_REJECTION_WARNING);
+ rStr += ' ';
+ }
+ else if (pReject->HasDependent())
+ {
+ ScChangeActionTable aTable;
+ pCT->GetDependents( pReject, aTable, FALSE, TRUE );
+ for ( const ScChangeAction* p = aTable.First(); p;
+ p = aTable.Next() )
+ {
+ if (p->GetType() == SC_CAT_MOVE)
+ {
+ rStr += ScGlobal::GetRscString(
+ STR_CHANGED_MOVE_REJECTION_WARNING);
+ rStr += ' ';
+ break; // for
+ }
+ else if (pReject->IsDeleteType())
+ {
+ rStr += ScGlobal::GetRscString(
+ STR_CHANGED_DELETE_REJECTION_WARNING);
+ rStr += ' ';
+ break; // for
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+String ScChangeAction::GetRefString( const ScBigRange& rRange,
+ ScDocument* pDoc, BOOL bFlag3D ) const
+{
+ String aStr;
+ USHORT nFlags = ( rRange.IsValid( pDoc ) ? SCA_VALID : 0 );
+ if ( !nFlags )
+ aStr = ScGlobal::GetRscString( STR_NOREF_STR );
+ else
+ {
+ ScRange aTmpRange( rRange.MakeRange() );
+ switch ( GetType() )
+ {
+ case SC_CAT_INSERT_COLS :
+ case SC_CAT_DELETE_COLS :
+ if ( bFlag3D )
+ {
+ pDoc->GetName( aTmpRange.aStart.Tab(), aStr );
+ aStr += '.';
+ }
+ aStr += ::ScColToAlpha( aTmpRange.aStart.Col() );
+ aStr += ':';
+ aStr += ::ScColToAlpha( aTmpRange.aEnd.Col() );
+ break;
+ case SC_CAT_INSERT_ROWS :
+ case SC_CAT_DELETE_ROWS :
+ if ( bFlag3D )
+ {
+ pDoc->GetName( aTmpRange.aStart.Tab(), aStr );
+ aStr += '.';
+ }
+ aStr += String::CreateFromInt32( aTmpRange.aStart.Row() + 1 );
+ aStr += ':';
+ aStr += String::CreateFromInt32( aTmpRange.aEnd.Row() + 1 );
+ break;
+ default:
+ if ( bFlag3D || GetType() == SC_CAT_INSERT_TABS )
+ nFlags |= SCA_TAB_3D;
+ aTmpRange.Format( aStr, nFlags, pDoc, pDoc->GetAddressConvention() );
+ }
+ if ( (bFlag3D && IsDeleteType()) || IsDeletedIn() )
+ {
+ aStr.Insert( '(', 0 );
+ aStr += ')';
+ }
+ }
+ return aStr;
+}
+
+
+void ScChangeAction::GetRefString( String& rStr, ScDocument* pDoc,
+ BOOL bFlag3D ) const
+{
+ rStr = GetRefString( GetBigRange(), pDoc, bFlag3D );
+}
+
+
+void ScChangeAction::Accept()
+{
+ if ( IsVirgin() )
+ {
+ SetState( SC_CAS_ACCEPTED );
+ DeleteCellEntries();
+ }
+}
+
+
+void ScChangeAction::SetRejected()
+{
+ if ( IsVirgin() )
+ {
+ SetState( SC_CAS_REJECTED );
+ RemoveAllLinks();
+ DeleteCellEntries();
+ }
+}
+
+
+void ScChangeAction::RejectRestoreContents( ScChangeTrack* pTrack,
+ SCsCOL nDx, SCsROW nDy )
+{
+ // Liste der Contents aufbauen
+ ScChangeActionCellListEntry* pListContents = NULL;
+ for ( ScChangeActionLinkEntry* pL = pLinkDeleted; pL; pL = pL->GetNext() )
+ {
+ ScChangeAction* p = pL->GetAction();
+ if ( p && p->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry(
+ (ScChangeActionContent*) p, pListContents );
+ pListContents = pE;
+ }
+ }
+ SetState( SC_CAS_REJECTED ); // vor UpdateReference fuer Move
+ pTrack->UpdateReference( this, TRUE ); // LinkDeleted freigeben
+ DBG_ASSERT( !pLinkDeleted, "ScChangeAction::RejectRestoreContents: pLinkDeleted != NULL" );
+ // Liste der Contents abarbeiten und loeschen
+ ScDocument* pDoc = pTrack->GetDocument();
+ ScChangeActionCellListEntry* pE = pListContents;
+ while ( pE )
+ {
+ if ( !pE->pContent->IsDeletedIn() &&
+ pE->pContent->GetBigRange().aStart.IsValid( pDoc ) )
+ pE->pContent->PutNewValueToDoc( pDoc, nDx, nDy );
+ ScChangeActionCellListEntry* pNextEntry;
+ pNextEntry = pE->pNext;
+ delete pE;
+ pE = pNextEntry;
+ }
+ DeleteCellEntries(); // weg mit den generierten
+}
+
+
+void ScChangeAction::SetDeletedInThis( ULONG nActionNumber,
+ const ScChangeTrack* pTrack )
+{
+ if ( nActionNumber )
+ {
+ ScChangeAction* pAct = pTrack->GetActionOrGenerated( nActionNumber );
+ DBG_ASSERT( pAct, "ScChangeAction::SetDeletedInThis: missing Action" );
+ if ( pAct )
+ pAct->SetDeletedIn( this );
+ }
+}
+
+
+void ScChangeAction::AddDependent( ULONG nActionNumber,
+ const ScChangeTrack* pTrack )
+{
+ if ( nActionNumber )
+ {
+ ScChangeAction* pAct = pTrack->GetActionOrGenerated( nActionNumber );
+ DBG_ASSERT( pAct, "ScChangeAction::AddDependent: missing Action" );
+ if ( pAct )
+ {
+ ScChangeActionLinkEntry* pLink = AddDependent( pAct );
+ pAct->AddLink( this, pLink );
+ }
+ }
+}
+
+
+#if DEBUG_CHANGETRACK
+String ScChangeAction::ToString( ScDocument* pDoc ) const
+{
+ String aReturn;
+
+ String aNumber = String::CreateFromInt64( static_cast< sal_Int64 >( GetActionNumber() ) );
+
+ String aActionState;
+ ScChangeActionState eActionState = GetState();
+ switch ( eActionState )
+ {
+ case SC_CAS_VIRGIN:
+ {
+ aActionState = String::CreateFromAscii( " " );
+ }
+ break;
+ case SC_CAS_ACCEPTED:
+ {
+ aActionState = String::CreateFromAscii( "+" );
+ }
+ break;
+ case SC_CAS_REJECTED:
+ {
+ aActionState = String::CreateFromAscii( "-" );
+ }
+ break;
+ }
+
+ String aRejectAction;
+ if ( IsRejecting() )
+ {
+ aRejectAction += 'r';
+ aRejectAction += String::CreateFromInt64( static_cast< sal_Int64 >( GetRejectAction() ) );
+ }
+
+ String aReference;
+ GetRefString( aReference, pDoc, TRUE );
+
+ String aAuthor = GetUser();
+
+ DateTime aDT = GetDateTime();
+ String aDate = ScGlobal::pLocaleData->getDate( aDT );
+ aDate += ' ';
+ aDate += ScGlobal::pLocaleData->getTime( aDT, FALSE, FALSE );
+
+ String aDescription;
+ GetDescription( aDescription, pDoc );
+
+ String aLinkAny;
+ const ScChangeActionLinkEntry* pLinkA = pLinkAny;
+ while ( pLinkA )
+ {
+ if ( !aLinkAny.Len() )
+ {
+ aLinkAny = String::CreateFromAscii( "(Any:" );
+ }
+ aLinkAny += String::CreateFromAscii( " ->" );
+ aLinkAny += pLinkA->ToString();
+ pLinkA = pLinkA->GetNext();
+ }
+ if ( aLinkAny.Len() )
+ {
+ aLinkAny += ')';
+ }
+
+ String aLinkDeletedIn;
+ const ScChangeActionLinkEntry* pLinkDI = pLinkDeletedIn;
+ while ( pLinkDI )
+ {
+ if ( !aLinkDeletedIn.Len() )
+ {
+ aLinkDeletedIn = String::CreateFromAscii( "(DeletedIn:" );
+ }
+ aLinkDeletedIn += String::CreateFromAscii( " ->" );
+ aLinkDeletedIn += pLinkDI->ToString();
+ pLinkDI = pLinkDI->GetNext();
+ }
+ if ( aLinkDeletedIn.Len() )
+ {
+ aLinkDeletedIn += ')';
+ }
+
+ String aLinkDeleted;
+ const ScChangeActionLinkEntry* pLinkD = pLinkDeleted;
+ while ( pLinkD )
+ {
+ if ( !aLinkDeleted.Len() )
+ {
+ aLinkDeleted = String::CreateFromAscii( "(Deleted:" );
+ }
+ aLinkDeleted += String::CreateFromAscii( " ->" );
+ aLinkDeleted += pLinkD->ToString();
+ pLinkD = pLinkD->GetNext();
+ }
+ if ( aLinkDeleted.Len() )
+ {
+ aLinkDeleted += ')';
+ }
+
+ String aLinkDependent;
+ const ScChangeActionLinkEntry* pLinkDp = pLinkDependent;
+ while ( pLinkDp )
+ {
+ if ( !aLinkDependent.Len() )
+ {
+ aLinkDependent = String::CreateFromAscii( "(Dependent:" );
+ }
+ aLinkDependent += String::CreateFromAscii( " ->" );
+ aLinkDependent += pLinkDp->ToString();
+ pLinkDp = pLinkDp->GetNext();
+ }
+ if ( aLinkDependent.Len() )
+ {
+ aLinkDependent += ')';
+ }
+
+ aReturn += aNumber;
+ aReturn += aActionState;
+ aReturn += aRejectAction;
+ aReturn += String::CreateFromAscii( ": " );
+ aReturn += aReference;
+ aReturn += ' ';
+ aReturn += aAuthor;
+ aReturn += ' ';
+ aReturn += aDate;
+ aReturn += ' ';
+ aReturn += aDescription;
+ aReturn += ' ';
+ aReturn += aLinkAny;
+ aReturn += ' ';
+ aReturn += aLinkDeletedIn;
+ aReturn += ' ';
+ aReturn += aLinkDeleted;
+ aReturn += ' ';
+ aReturn += aLinkDependent;
+
+ return aReturn;
+}
+#endif // DEBUG_CHANGETRACK
+
+
+// --- ScChangeActionIns ---------------------------------------------------
+
+ScChangeActionIns::ScChangeActionIns( const ScRange& rRange )
+ : ScChangeAction( SC_CAT_NONE, rRange )
+{
+ if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
+ {
+ aBigRange.aStart.SetCol( nInt32Min );
+ aBigRange.aEnd.SetCol( nInt32Max );
+ if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+ {
+ SetType( SC_CAT_INSERT_TABS );
+ aBigRange.aStart.SetRow( nInt32Min );
+ aBigRange.aEnd.SetRow( nInt32Max );
+ }
+ else
+ SetType( SC_CAT_INSERT_ROWS );
+ }
+ else if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+ {
+ SetType( SC_CAT_INSERT_COLS );
+ aBigRange.aStart.SetRow( nInt32Min );
+ aBigRange.aEnd.SetRow( nInt32Max );
+ }
+ else
+ {
+ DBG_ERROR( "ScChangeActionIns: Block not supported!" );
+ }
+}
+
+
+ScChangeActionIns::ScChangeActionIns(const ULONG nActionNumber, const ScChangeActionState eStateP, const ULONG nRejectingNumber,
+ const ScBigRange& aBigRangeP, const String& aUserP, const DateTime& aDateTimeP, const String& sComment,
+ const ScChangeActionType eTypeP)
+ :
+ ScChangeAction(eTypeP, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment)
+{
+}
+
+ScChangeActionIns::~ScChangeActionIns()
+{
+}
+
+
+void ScChangeActionIns::GetDescription( String& rStr, ScDocument* pDoc,
+ BOOL bSplitRange, bool bWarning ) const
+{
+ ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
+
+ USHORT nWhatId;
+ switch ( GetType() )
+ {
+ case SC_CAT_INSERT_COLS :
+ nWhatId = STR_COLUMN;
+ break;
+ case SC_CAT_INSERT_ROWS :
+ nWhatId = STR_ROW;
+ break;
+ default:
+ nWhatId = STR_AREA;
+ }
+
+ String aRsc( ScGlobal::GetRscString( STR_CHANGED_INSERT ) );
+ xub_StrLen nPos = aRsc.SearchAscii( "#1" );
+ rStr += aRsc.Copy( 0, nPos );
+ rStr += ScGlobal::GetRscString( nWhatId );
+ rStr += ' ';
+ rStr += GetRefString( GetBigRange(), pDoc );
+ rStr += aRsc.Copy( nPos+2 );
+}
+
+
+BOOL ScChangeActionIns::Reject( ScDocument* pDoc )
+{
+ if ( !aBigRange.IsValid( pDoc ) )
+ return FALSE;
+
+ ScRange aRange( aBigRange.MakeRange() );
+ if ( !pDoc->IsBlockEditable( aRange.aStart.Tab(), aRange.aStart.Col(),
+ aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() ) )
+ return FALSE;
+
+ switch ( GetType() )
+ {
+ case SC_CAT_INSERT_COLS :
+ pDoc->DeleteCol( aRange );
+ break;
+ case SC_CAT_INSERT_ROWS :
+ pDoc->DeleteRow( aRange );
+ break;
+ case SC_CAT_INSERT_TABS :
+ pDoc->DeleteTab( aRange.aStart.Tab() );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ SetState( SC_CAS_REJECTED );
+ RemoveAllLinks();
+ return TRUE;
+}
+
+
+// --- ScChangeActionDel ---------------------------------------------------
+
+ScChangeActionDel::ScChangeActionDel( const ScRange& rRange,
+ SCsCOL nDxP, SCsROW nDyP, ScChangeTrack* pTrackP )
+ :
+ ScChangeAction( SC_CAT_NONE, rRange ),
+ pTrack( pTrackP ),
+ pFirstCell( NULL ),
+ pCutOff( NULL ),
+ nCutOff( 0 ),
+ pLinkMove( NULL ),
+ nDx( nDxP ),
+ nDy( nDyP )
+{
+ if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
+ {
+ aBigRange.aStart.SetCol( nInt32Min );
+ aBigRange.aEnd.SetCol( nInt32Max );
+ if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+ {
+ SetType( SC_CAT_DELETE_TABS );
+ aBigRange.aStart.SetRow( nInt32Min );
+ aBigRange.aEnd.SetRow( nInt32Max );
+ }
+ else
+ SetType( SC_CAT_DELETE_ROWS );
+ }
+ else if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+ {
+ SetType( SC_CAT_DELETE_COLS );
+ aBigRange.aStart.SetRow( nInt32Min );
+ aBigRange.aEnd.SetRow( nInt32Max );
+ }
+ else
+ {
+ DBG_ERROR( "ScChangeActionDel: Block not supported!" );
+ }
+}
+
+
+ScChangeActionDel::ScChangeActionDel(const ULONG nActionNumber, const ScChangeActionState eStateP, const ULONG nRejectingNumber,
+ const ScBigRange& aBigRangeP, const String& aUserP, const DateTime& aDateTimeP, const String &sComment,
+ const ScChangeActionType eTypeP, const SCsCOLROW nD, ScChangeTrack* pTrackP) // wich of nDx and nDy is set is depend on the type
+ :
+ ScChangeAction(eTypeP, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment),
+ pTrack( pTrackP ),
+ pFirstCell( NULL ),
+ pCutOff( NULL ),
+ nCutOff( 0 ),
+ pLinkMove( NULL ),
+ nDx( 0 ),
+ nDy( 0 )
+{
+ if (eType == SC_CAT_DELETE_COLS)
+ nDx = static_cast<SCsCOL>(nD);
+ else if (eType == SC_CAT_DELETE_ROWS)
+ nDy = static_cast<SCsROW>(nD);
+}
+
+ScChangeActionDel::~ScChangeActionDel()
+{
+ DeleteCellEntries();
+ while ( pLinkMove )
+ delete pLinkMove;
+}
+
+void ScChangeActionDel::AddContent( ScChangeActionContent* pContent )
+{
+ ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry(
+ pContent, pFirstCell );
+ pFirstCell = pE;
+}
+
+
+void ScChangeActionDel::DeleteCellEntries()
+{
+ pTrack->DeleteCellEntries( pFirstCell, this );
+}
+
+
+BOOL ScChangeActionDel::IsBaseDelete() const
+{
+ return !GetDx() && !GetDy();
+}
+
+
+BOOL ScChangeActionDel::IsTopDelete() const
+{
+ const ScChangeAction* p = GetNext();
+ if ( !p || p->GetType() != GetType() )
+ return TRUE;
+ return ((ScChangeActionDel*)p)->IsBaseDelete();
+}
+
+
+BOOL ScChangeActionDel::IsMultiDelete() const
+{
+ if ( GetDx() || GetDy() )
+ return TRUE;
+ const ScChangeAction* p = GetNext();
+ if ( !p || p->GetType() != GetType() )
+ return FALSE;
+ const ScChangeActionDel* pDel = (const ScChangeActionDel*) p;
+ if ( (pDel->GetDx() > GetDx() || pDel->GetDy() > GetDy()) &&
+ pDel->GetBigRange() == aBigRange )
+ return TRUE;
+ return FALSE;
+}
+
+
+BOOL ScChangeActionDel::IsTabDeleteCol() const
+{
+ if ( GetType() != SC_CAT_DELETE_COLS )
+ return FALSE;
+ const ScChangeAction* p = this;
+ while ( p && p->GetType() == SC_CAT_DELETE_COLS &&
+ !((const ScChangeActionDel*)p)->IsTopDelete() )
+ p = p->GetNext();
+ return p && p->GetType() == SC_CAT_DELETE_TABS;
+}
+
+
+void ScChangeActionDel::UpdateReference( const ScChangeTrack* /* pTrack */,
+ UpdateRefMode eMode, const ScBigRange& rRange,
+ INT32 nDxP, INT32 nDyP, INT32 nDz )
+{
+ ScRefUpdate::Update( eMode, rRange, nDxP, nDyP, nDz, GetBigRange() );
+ if ( !IsDeletedIn() )
+ return ;
+ // evtl. in "druntergerutschten" anpassen
+ for ( ScChangeActionLinkEntry* pL = pLinkDeleted; pL; pL = pL->GetNext() )
+ {
+ ScChangeAction* p = pL->GetAction();
+ if ( p && p->GetType() == SC_CAT_CONTENT &&
+ !GetBigRange().In( p->GetBigRange() ) )
+ {
+ switch ( GetType() )
+ {
+ case SC_CAT_DELETE_COLS :
+ p->GetBigRange().aStart.SetCol( GetBigRange().aStart.Col() );
+ p->GetBigRange().aEnd.SetCol( GetBigRange().aStart.Col() );
+ break;
+ case SC_CAT_DELETE_ROWS :
+ p->GetBigRange().aStart.SetRow( GetBigRange().aStart.Row() );
+ p->GetBigRange().aEnd.SetRow( GetBigRange().aStart.Row() );
+ break;
+ case SC_CAT_DELETE_TABS :
+ p->GetBigRange().aStart.SetTab( GetBigRange().aStart.Tab() );
+ p->GetBigRange().aEnd.SetTab( GetBigRange().aStart.Tab() );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+}
+
+
+ScBigRange ScChangeActionDel::GetOverAllRange() const
+{
+ ScBigRange aTmpRange( GetBigRange() );
+ aTmpRange.aEnd.SetCol( aTmpRange.aEnd.Col() + GetDx() );
+ aTmpRange.aEnd.SetRow( aTmpRange.aEnd.Row() + GetDy() );
+ return aTmpRange;
+}
+
+
+void ScChangeActionDel::GetDescription( String& rStr, ScDocument* pDoc,
+ BOOL bSplitRange, bool bWarning ) const
+{
+ ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
+
+ USHORT nWhatId;
+ switch ( GetType() )
+ {
+ case SC_CAT_DELETE_COLS :
+ nWhatId = STR_COLUMN;
+ break;
+ case SC_CAT_DELETE_ROWS :
+ nWhatId = STR_ROW;
+ break;
+ default:
+ nWhatId = STR_AREA;
+ }
+
+ ScBigRange aTmpRange( GetBigRange() );
+ if ( !IsRejected() )
+ {
+ if ( bSplitRange )
+ {
+ aTmpRange.aStart.SetCol( aTmpRange.aStart.Col() + GetDx() );
+ aTmpRange.aStart.SetRow( aTmpRange.aStart.Row() + GetDy() );
+ }
+ aTmpRange.aEnd.SetCol( aTmpRange.aEnd.Col() + GetDx() );
+ aTmpRange.aEnd.SetRow( aTmpRange.aEnd.Row() + GetDy() );
+ }
+
+ String aRsc( ScGlobal::GetRscString( STR_CHANGED_DELETE ) );
+ xub_StrLen nPos = aRsc.SearchAscii( "#1" );
+ rStr += aRsc.Copy( 0, nPos );
+ rStr += ScGlobal::GetRscString( nWhatId );
+ rStr += ' ';
+ rStr += GetRefString( aTmpRange, pDoc );
+ rStr += aRsc.Copy( nPos+2 );
+}
+
+
+BOOL ScChangeActionDel::Reject( ScDocument* pDoc )
+{
+ if ( !aBigRange.IsValid( pDoc ) && GetType() != SC_CAT_DELETE_TABS )
+ return FALSE;
+
+ BOOL bOk = TRUE;
+
+ if ( IsTopDelete() )
+ { // den kompletten Bereich in einem Rutsch restaurieren
+ ScBigRange aTmpRange( GetOverAllRange() );
+ if ( !aTmpRange.IsValid( pDoc ) )
+ {
+ if ( GetType() == SC_CAT_DELETE_TABS )
+ { // wird Tab angehaengt?
+ if ( aTmpRange.aStart.Tab() > pDoc->GetMaxTableNumber() )
+ bOk = FALSE;
+ }
+ else
+ bOk = FALSE;
+ }
+ if ( bOk )
+ {
+ ScRange aRange( aTmpRange.MakeRange() );
+ // InDelete... fuer Formel UpdateReference in Document
+ pTrack->SetInDeleteRange( aRange );
+ pTrack->SetInDeleteTop( TRUE );
+ pTrack->SetInDeleteUndo( TRUE );
+ pTrack->SetInDelete( TRUE );
+ switch ( GetType() )
+ {
+ case SC_CAT_DELETE_COLS :
+ if ( !(aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MAXCOL) )
+ { // nur wenn nicht TabDelete
+ if ( ( bOk = pDoc->CanInsertCol( aRange ) ) != FALSE )
+ bOk = pDoc->InsertCol( aRange );
+ }
+ break;
+ case SC_CAT_DELETE_ROWS :
+ if ( ( bOk = pDoc->CanInsertRow( aRange ) ) != FALSE )
+ bOk = pDoc->InsertRow( aRange );
+ break;
+ case SC_CAT_DELETE_TABS :
+ {
+//2do: Tabellennamen merken?
+ String aName;
+ pDoc->CreateValidTabName( aName );
+ if ( ( bOk = pDoc->ValidNewTabName( aName ) ) != FALSE )
+ bOk = pDoc->InsertTab( aRange.aStart.Tab(), aName );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ pTrack->SetInDelete( FALSE );
+ pTrack->SetInDeleteUndo( FALSE );
+ }
+ if ( !bOk )
+ {
+ pTrack->SetInDeleteTop( FALSE );
+ return FALSE;
+ }
+ // InDeleteTop fuer UpdateReference-Undo behalten
+ }
+
+ // setzt rejected und ruft UpdateReference-Undo und DeleteCellEntries
+ RejectRestoreContents( pTrack, GetDx(), GetDy() );
+
+ pTrack->SetInDeleteTop( FALSE );
+ RemoveAllLinks();
+ return TRUE;
+}
+
+
+void ScChangeActionDel::UndoCutOffMoves()
+{ // abgeschnittene Moves wiederherstellen, Entries/Links deleten
+ while ( pLinkMove )
+ {
+ ScChangeActionMove* pMove = pLinkMove->GetMove();
+ short nFrom = pLinkMove->GetCutOffFrom();
+ short nTo = pLinkMove->GetCutOffTo();
+ switch ( GetType() )
+ {
+ case SC_CAT_DELETE_COLS :
+ if ( nFrom > 0 )
+ pMove->GetFromRange().aStart.IncCol( -nFrom );
+ else if ( nFrom < 0 )
+ pMove->GetFromRange().aEnd.IncCol( -nFrom );
+ if ( nTo > 0 )
+ pMove->GetBigRange().aStart.IncCol( -nTo );
+ else if ( nTo < 0 )
+ pMove->GetBigRange().aEnd.IncCol( -nTo );
+ break;
+ case SC_CAT_DELETE_ROWS :
+ if ( nFrom > 0 )
+ pMove->GetFromRange().aStart.IncRow( -nFrom );
+ else if ( nFrom < 0 )
+ pMove->GetFromRange().aEnd.IncRow( -nFrom );
+ if ( nTo > 0 )
+ pMove->GetBigRange().aStart.IncRow( -nTo );
+ else if ( nTo < 0 )
+ pMove->GetBigRange().aEnd.IncRow( -nTo );
+ break;
+ case SC_CAT_DELETE_TABS :
+ if ( nFrom > 0 )
+ pMove->GetFromRange().aStart.IncTab( -nFrom );
+ else if ( nFrom < 0 )
+ pMove->GetFromRange().aEnd.IncTab( -nFrom );
+ if ( nTo > 0 )
+ pMove->GetBigRange().aStart.IncTab( -nTo );
+ else if ( nTo < 0 )
+ pMove->GetBigRange().aEnd.IncTab( -nTo );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ delete pLinkMove; // rueckt sich selbst hoch
+ }
+}
+
+void ScChangeActionDel::UndoCutOffInsert()
+{ // abgeschnittenes Insert wiederherstellen
+ if ( pCutOff )
+ {
+ switch ( pCutOff->GetType() )
+ {
+ case SC_CAT_INSERT_COLS :
+ if ( nCutOff < 0 )
+ pCutOff->GetBigRange().aEnd.IncCol( -nCutOff );
+ else
+ pCutOff->GetBigRange().aStart.IncCol( -nCutOff );
+ break;
+ case SC_CAT_INSERT_ROWS :
+ if ( nCutOff < 0 )
+ pCutOff->GetBigRange().aEnd.IncRow( -nCutOff );
+ else
+ pCutOff->GetBigRange().aStart.IncRow( -nCutOff );
+ break;
+ case SC_CAT_INSERT_TABS :
+ if ( nCutOff < 0 )
+ pCutOff->GetBigRange().aEnd.IncTab( -nCutOff );
+ else
+ pCutOff->GetBigRange().aStart.IncTab( -nCutOff );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ SetCutOffInsert( NULL, 0 );
+ }
+}
+
+
+// --- ScChangeActionMove --------------------------------------------------
+
+ScChangeActionMove::ScChangeActionMove(const ULONG nActionNumber, const ScChangeActionState eStateP, const ULONG nRejectingNumber,
+ const ScBigRange& aToBigRange, const String& aUserP, const DateTime& aDateTimeP, const String &sComment,
+ const ScBigRange& aFromBigRange, ScChangeTrack* pTrackP) // wich of nDx and nDy is set is depend on the type
+ :
+ ScChangeAction(SC_CAT_MOVE, aToBigRange, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment),
+ aFromRange(aFromBigRange),
+ pTrack( pTrackP ),
+ pFirstCell( NULL ),
+ nStartLastCut(0),
+ nEndLastCut(0)
+{
+}
+
+ScChangeActionMove::~ScChangeActionMove()
+{
+ DeleteCellEntries();
+}
+
+
+void ScChangeActionMove::AddContent( ScChangeActionContent* pContent )
+{
+ ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry(
+ pContent, pFirstCell );
+ pFirstCell = pE;
+}
+
+
+void ScChangeActionMove::DeleteCellEntries()
+{
+ pTrack->DeleteCellEntries( pFirstCell, this );
+}
+
+
+void ScChangeActionMove::UpdateReference( const ScChangeTrack* /* pTrack */,
+ UpdateRefMode eMode, const ScBigRange& rRange,
+ INT32 nDx, INT32 nDy, INT32 nDz )
+{
+ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aFromRange );
+ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() );
+}
+
+
+void ScChangeActionMove::GetDelta( INT32& nDx, INT32& nDy, INT32& nDz ) const
+{
+ const ScBigAddress& rToPos = GetBigRange().aStart;
+ const ScBigAddress& rFromPos = GetFromRange().aStart;
+ nDx = rToPos.Col() - rFromPos.Col();
+ nDy = rToPos.Row() - rFromPos.Row();
+ nDz = rToPos.Tab() - rFromPos.Tab();
+}
+
+
+void ScChangeActionMove::GetDescription( String& rStr, ScDocument* pDoc,
+ BOOL bSplitRange, bool bWarning ) const
+{
+ ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
+
+ BOOL bFlag3D = ( GetFromRange().aStart.Tab() != GetBigRange().aStart.Tab() );
+
+ String aRsc( ScGlobal::GetRscString( STR_CHANGED_MOVE ) );
+
+ xub_StrLen nPos = 0;
+ String aTmpStr = ScChangeAction::GetRefString( GetFromRange(), pDoc, bFlag3D );
+ nPos = aRsc.SearchAscii( "#1", nPos );
+ aRsc.Erase( nPos, 2 );
+ aRsc.Insert( aTmpStr, nPos );
+ nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
+
+ aTmpStr = ScChangeAction::GetRefString( GetBigRange(), pDoc, bFlag3D );
+ nPos = aRsc.SearchAscii( "#2", nPos );
+ aRsc.Erase( nPos, 2 );
+ aRsc.Insert( aTmpStr, nPos );
+ nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
+
+ rStr += aRsc;
+}
+
+
+void ScChangeActionMove::GetRefString( String& rStr, ScDocument* pDoc,
+ BOOL bFlag3D ) const
+{
+ if ( !bFlag3D )
+ bFlag3D = ( GetFromRange().aStart.Tab() != GetBigRange().aStart.Tab() );
+ rStr = ScChangeAction::GetRefString( GetFromRange(), pDoc, bFlag3D );
+ rStr += ',';
+ rStr += ' ';
+ rStr += ScChangeAction::GetRefString( GetBigRange(), pDoc, bFlag3D );
+}
+
+
+BOOL ScChangeActionMove::Reject( ScDocument* pDoc )
+{
+ if ( !(aBigRange.IsValid( pDoc ) && aFromRange.IsValid( pDoc )) )
+ return FALSE;
+
+ ScRange aToRange( aBigRange.MakeRange() );
+ ScRange aFrmRange( aFromRange.MakeRange() );
+
+ BOOL bOk = pDoc->IsBlockEditable( aToRange.aStart.Tab(),
+ aToRange.aStart.Col(), aToRange.aStart.Row(),
+ aToRange.aEnd.Col(), aToRange.aEnd.Row() );
+ if ( bOk )
+ bOk = pDoc->IsBlockEditable( aFrmRange.aStart.Tab(),
+ aFrmRange.aStart.Col(), aFrmRange.aStart.Row(),
+ aFrmRange.aEnd.Col(), aFrmRange.aEnd.Row() );
+ if ( !bOk )
+ return FALSE;
+
+ pTrack->LookUpContents( aToRange, pDoc, 0, 0, 0 ); // zu movende Contents
+
+ pDoc->DeleteAreaTab( aToRange, IDF_ALL );
+ pDoc->DeleteAreaTab( aFrmRange, IDF_ALL );
+ // Formeln im Dokument anpassen
+ pDoc->UpdateReference( URM_MOVE,
+ aFrmRange.aStart.Col(), aFrmRange.aStart.Row(), aFrmRange.aStart.Tab(),
+ aFrmRange.aEnd.Col(), aFrmRange.aEnd.Row(), aFrmRange.aEnd.Tab(),
+ (SCsCOL) aFrmRange.aStart.Col() - aToRange.aStart.Col(),
+ (SCsROW) aFrmRange.aStart.Row() - aToRange.aStart.Row(),
+ (SCsTAB) aFrmRange.aStart.Tab() - aToRange.aStart.Tab(), NULL );
+
+ // LinkDependent freigeben, nachfolgendes UpdateReference-Undo setzt
+ // ToRange->FromRange Dependents
+ RemoveAllDependent();
+
+ // setzt rejected und ruft UpdateReference-Undo und DeleteCellEntries
+ RejectRestoreContents( pTrack, 0, 0 );
+
+ while ( pLinkDependent )
+ {
+ ScChangeAction* p = pLinkDependent->GetAction();
+ if ( p && p->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContent* pContent = (ScChangeActionContent*) p;
+ if ( !pContent->IsDeletedIn() &&
+ pContent->GetBigRange().aStart.IsValid( pDoc ) )
+ pContent->PutNewValueToDoc( pDoc, 0, 0 );
+ // in LookUpContents generierte loeschen
+ if ( pTrack->IsGenerated( pContent->GetActionNumber() ) &&
+ !pContent->IsDeletedIn() )
+ {
+ pLinkDependent->UnLink(); //! sonst wird der mitgeloescht
+ pTrack->DeleteGeneratedDelContent( pContent );
+ }
+ }
+ delete pLinkDependent;
+ }
+
+ RemoveAllLinks();
+ return TRUE;
+}
+
+
+// --- ScChangeActionContent -----------------------------------------------
+
+const USHORT nMemPoolChangeActionContent = (0x8000 - 64) / sizeof(ScChangeActionContent);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent, nMemPoolChangeActionContent, nMemPoolChangeActionContent )
+
+ScChangeActionContent::ScChangeActionContent( const ULONG nActionNumber,
+ const ScChangeActionState eStateP, const ULONG nRejectingNumber,
+ const ScBigRange& aBigRangeP, const String& aUserP,
+ const DateTime& aDateTimeP, const String& sComment,
+ ScBaseCell* pTempOldCell, ScDocument* pDoc, const String& sOldValue )
+ :
+ ScChangeAction(SC_CAT_CONTENT, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment),
+ aOldValue(sOldValue),
+ pOldCell(pTempOldCell),
+ pNewCell(NULL),
+ pNextContent(NULL),
+ pPrevContent(NULL),
+ pNextInSlot(NULL),
+ ppPrevInSlot(NULL)
+
+{
+ if (pOldCell)
+ ScChangeActionContent::SetCell( aOldValue, pOldCell, 0, pDoc );
+ if ( sOldValue.Len() ) // #i40704# don't overwrite SetCell result with empty string
+ aOldValue = sOldValue; // set again, because SetCell removes it
+}
+
+ScChangeActionContent::ScChangeActionContent( const ULONG nActionNumber,
+ ScBaseCell* pTempNewCell, const ScBigRange& aBigRangeP,
+ ScDocument* pDoc, const String& sNewValue )
+ :
+ ScChangeAction(SC_CAT_CONTENT, aBigRangeP, nActionNumber),
+ aNewValue(sNewValue),
+ pOldCell(NULL),
+ pNewCell(pTempNewCell),
+ pNextContent(NULL),
+ pPrevContent(NULL),
+ pNextInSlot(NULL),
+ ppPrevInSlot(NULL)
+{
+ if (pNewCell)
+ ScChangeActionContent::SetCell( aNewValue, pNewCell, 0, pDoc );
+ if ( sNewValue.Len() ) // #i40704# don't overwrite SetCell result with empty string
+ aNewValue = sNewValue; // set again, because SetCell removes it
+}
+
+ScChangeActionContent::~ScChangeActionContent()
+{
+ ClearTrack();
+}
+
+
+void ScChangeActionContent::ClearTrack()
+{
+ RemoveFromSlot();
+ if ( pPrevContent )
+ pPrevContent->pNextContent = pNextContent;
+ if ( pNextContent )
+ pNextContent->pPrevContent = pPrevContent;
+}
+
+
+ScChangeActionContent* ScChangeActionContent::GetTopContent() const
+{
+ if ( pNextContent )
+ {
+ ScChangeActionContent* pContent = pNextContent;
+ while ( pContent->pNextContent && pContent != pContent->pNextContent )
+ pContent = pContent->pNextContent;
+ return pContent;
+ }
+ return (ScChangeActionContent*) this;
+}
+
+
+ScChangeActionLinkEntry* ScChangeActionContent::GetDeletedIn() const
+{
+ if ( pNextContent )
+ return GetTopContent()->pLinkDeletedIn;
+ return pLinkDeletedIn;
+}
+
+
+ScChangeActionLinkEntry** ScChangeActionContent::GetDeletedInAddress()
+{
+ if ( pNextContent )
+ return GetTopContent()->GetDeletedInAddress();
+ return &pLinkDeletedIn;
+}
+
+
+void ScChangeActionContent::SetOldValue( const ScBaseCell* pCell,
+ const ScDocument* pFromDoc, ScDocument* pToDoc, ULONG nFormat )
+{
+ ScChangeActionContent::SetValue( aOldValue, pOldCell,
+ nFormat, pCell, pFromDoc, pToDoc );
+}
+
+
+void ScChangeActionContent::SetOldValue( const ScBaseCell* pCell,
+ const ScDocument* pFromDoc, ScDocument* pToDoc )
+{
+ ScChangeActionContent::SetValue( aOldValue, pOldCell,
+ aBigRange.aStart.MakeAddress(), pCell, pFromDoc, pToDoc );
+}
+
+
+void ScChangeActionContent::SetNewValue( const ScBaseCell* pCell,
+ ScDocument* pDoc )
+{
+ ScChangeActionContent::SetValue( aNewValue, pNewCell,
+ aBigRange.aStart.MakeAddress(), pCell, pDoc, pDoc );
+}
+
+
+void ScChangeActionContent::SetOldNewCells( ScBaseCell* pOldCellP,
+ ULONG nOldFormat, ScBaseCell* pNewCellP,
+ ULONG nNewFormat, ScDocument* pDoc )
+{
+ pOldCell = pOldCellP;
+ pNewCell = pNewCellP;
+ ScChangeActionContent::SetCell( aOldValue, pOldCell, nOldFormat, pDoc );
+ ScChangeActionContent::SetCell( aNewValue, pNewCell, nNewFormat, pDoc );
+}
+
+void ScChangeActionContent::SetNewCell( ScBaseCell* pCell, ScDocument* pDoc, const String& rFormatted )
+{
+ DBG_ASSERT( !pNewCell, "ScChangeActionContent::SetNewCell: overwriting existing cell" );
+ pNewCell = pCell;
+ ScChangeActionContent::SetCell( aNewValue, pNewCell, 0, pDoc );
+
+ // #i40704# allow to set formatted text here - don't call SetNewValue with String from XML filter
+ if ( rFormatted.Len() )
+ aNewValue = rFormatted;
+}
+
+void ScChangeActionContent::SetValueString( String& rValue, ScBaseCell*& pCell,
+ const String& rStr, ScDocument* pDoc )
+{
+ if ( pCell )
+ {
+ pCell->Delete();
+ pCell = NULL;
+ }
+ if ( rStr.Len() > 1 && rStr.GetChar(0) == '=' )
+ {
+ rValue.Erase();
+ pCell = new ScFormulaCell(
+ pDoc, aBigRange.aStart.MakeAddress(), rStr, formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::CONV_OOO );
+ ((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE );
+ }
+ else
+ rValue = rStr;
+}
+
+
+void ScChangeActionContent::SetOldValue( const String& rOld, ScDocument* pDoc )
+{
+ SetValueString( aOldValue, pOldCell, rOld, pDoc );
+}
+
+
+void ScChangeActionContent::SetNewValue( const String& rNew, ScDocument* pDoc )
+{
+ SetValueString( aNewValue, pNewCell, rNew, pDoc );
+}
+
+
+void ScChangeActionContent::GetOldString( String& rStr ) const
+{
+ GetValueString( rStr, aOldValue, pOldCell );
+}
+
+
+void ScChangeActionContent::GetNewString( String& rStr ) const
+{
+ GetValueString( rStr, aNewValue, pNewCell );
+}
+
+
+void ScChangeActionContent::GetDescription( String& rStr, ScDocument* pDoc,
+ BOOL bSplitRange, bool bWarning ) const
+{
+ ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
+
+ String aRsc( ScGlobal::GetRscString( STR_CHANGED_CELL ) );
+
+ String aTmpStr;
+ GetRefString( aTmpStr, pDoc );
+
+ xub_StrLen nPos = 0;
+ nPos = aRsc.SearchAscii( "#1", nPos );
+ aRsc.Erase( nPos, 2 );
+ aRsc.Insert( aTmpStr, nPos );
+ nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
+
+ GetOldString( aTmpStr );
+ if ( !aTmpStr.Len() )
+ aTmpStr = ScGlobal::GetRscString( STR_CHANGED_BLANK );
+ nPos = aRsc.SearchAscii( "#2", nPos );
+ aRsc.Erase( nPos, 2 );
+ aRsc.Insert( aTmpStr, nPos );
+ nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
+
+ GetNewString( aTmpStr );
+ if ( !aTmpStr.Len() )
+ aTmpStr = ScGlobal::GetRscString( STR_CHANGED_BLANK );
+ nPos = aRsc.SearchAscii( "#3", nPos );
+ aRsc.Erase( nPos, 2 );
+ aRsc.Insert( aTmpStr, nPos );
+
+ rStr += aRsc;
+}
+
+
+void ScChangeActionContent::GetRefString( String& rStr, ScDocument* pDoc,
+ BOOL bFlag3D ) const
+{
+ USHORT nFlags = ( GetBigRange().IsValid( pDoc ) ? SCA_VALID : 0 );
+ if ( nFlags )
+ {
+ const ScBaseCell* pCell = GetNewCell();
+ if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATORG )
+ {
+ ScBigRange aLocalBigRange( GetBigRange() );
+ SCCOL nC;
+ SCROW nR;
+ ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR );
+ aLocalBigRange.aEnd.IncCol( nC-1 );
+ aLocalBigRange.aEnd.IncRow( nR-1 );
+ rStr = ScChangeAction::GetRefString( aLocalBigRange, pDoc, bFlag3D );
+
+ return ;
+ }
+
+ ScAddress aTmpAddress( GetBigRange().aStart.MakeAddress() );
+ if ( bFlag3D )
+ nFlags |= SCA_TAB_3D;
+ aTmpAddress.Format( rStr, nFlags, pDoc, pDoc->GetAddressConvention() );
+ if ( IsDeletedIn() )
+ {
+ rStr.Insert( '(', 0 );
+ rStr += ')';
+ }
+ }
+ else
+ rStr = ScGlobal::GetRscString( STR_NOREF_STR );
+}
+
+
+BOOL ScChangeActionContent::Reject( ScDocument* pDoc )
+{
+ if ( !aBigRange.IsValid( pDoc ) )
+ return FALSE;
+
+ PutOldValueToDoc( pDoc, 0, 0 );
+
+ SetState( SC_CAS_REJECTED );
+ RemoveAllLinks();
+
+ return TRUE;
+}
+
+
+BOOL ScChangeActionContent::Select( ScDocument* pDoc, ScChangeTrack* pTrack,
+ BOOL bOldest, Stack* pRejectActions )
+{
+ if ( !aBigRange.IsValid( pDoc ) )
+ return FALSE;
+
+ ScChangeActionContent* pContent = this;
+ // accept previous contents
+ while ( ( pContent = pContent->pPrevContent ) != NULL )
+ {
+ if ( pContent->IsVirgin() )
+ pContent->SetState( SC_CAS_ACCEPTED );
+ }
+ ScChangeActionContent* pEnd = pContent = this;
+ // reject subsequent contents
+ while ( ( pContent = pContent->pNextContent ) != NULL )
+ {
+ // MatrixOrigin may have dependents, no dependency recursion needed
+ const ScChangeActionLinkEntry* pL = pContent->GetFirstDependentEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p )
+ p->SetRejected();
+ pL = pL->GetNext();
+ }
+ pContent->SetRejected();
+ pEnd = pContent;
+ }
+
+ if ( bOldest || pEnd != this )
+ { // wenn nicht aeltester: ist es ueberhaupt ein anderer als der letzte?
+ ScRange aRange( aBigRange.aStart.MakeAddress() );
+ const ScAddress& rPos = aRange.aStart;
+
+ ScChangeActionContent* pNew = new ScChangeActionContent( aRange );
+ pNew->SetOldValue( pDoc->GetCell( rPos ), pDoc, pDoc );
+
+ if ( bOldest )
+ PutOldValueToDoc( pDoc, 0, 0 );
+ else
+ PutNewValueToDoc( pDoc, 0, 0 );
+
+ pNew->SetRejectAction( bOldest ? GetActionNumber() : pEnd->GetActionNumber() );
+ pNew->SetState( SC_CAS_ACCEPTED );
+ if ( pRejectActions )
+ pRejectActions->Push( pNew );
+ else
+ {
+ pNew->SetNewValue( pDoc->GetCell( rPos ), pDoc );
+ pTrack->Append( pNew );
+ }
+ }
+
+ if ( bOldest )
+ SetRejected();
+ else
+ SetState( SC_CAS_ACCEPTED );
+
+ return TRUE;
+}
+
+
+// static
+void ScChangeActionContent::GetStringOfCell( String& rStr,
+ const ScBaseCell* pCell, const ScDocument* pDoc, const ScAddress& rPos )
+{
+ if ( pCell )
+ {
+ if ( ScChangeActionContent::NeedsNumberFormat( pCell ) )
+ GetStringOfCell( rStr, pCell, pDoc, pDoc->GetNumberFormat( rPos ) );
+ else
+ GetStringOfCell( rStr, pCell, pDoc, 0 );
+ }
+ else
+ rStr.Erase();
+}
+
+
+// static
+void ScChangeActionContent::GetStringOfCell( String& rStr,
+ const ScBaseCell* pCell, const ScDocument* pDoc, ULONG nFormat )
+{
+ if ( ScChangeActionContent::GetContentCellType( pCell ) )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ {
+ double nValue = ((ScValueCell*)pCell)->GetValue();
+ pDoc->GetFormatTable()->GetInputLineString( nValue, nFormat,
+ rStr );
+ }
+ break;
+ case CELLTYPE_STRING :
+ ((ScStringCell*)pCell)->GetString( rStr );
+ break;
+ case CELLTYPE_EDIT :
+ ((ScEditCell*)pCell)->GetString( rStr );
+ break;
+ case CELLTYPE_FORMULA :
+ ((ScFormulaCell*)pCell)->GetFormula( rStr );
+ break;
+ default:
+ rStr.Erase();
+ }
+ }
+ else
+ rStr.Erase();
+}
+
+
+// static
+ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const ScBaseCell* pCell )
+{
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ return SC_CACCT_NORMAL;
+ //break;
+ case CELLTYPE_FORMULA :
+ switch ( ((const ScFormulaCell*)pCell)->GetMatrixFlag() )
+ {
+ case MM_NONE :
+ return SC_CACCT_NORMAL;
+ //break;
+ case MM_FORMULA :
+ case MM_FAKE :
+ return SC_CACCT_MATORG;
+ //break;
+ case MM_REFERENCE :
+ return SC_CACCT_MATREF;
+ //break;
+ }
+ return SC_CACCT_NORMAL;
+ //break;
+ default:
+ return SC_CACCT_NONE;
+ }
+ }
+ return SC_CACCT_NONE;
+}
+
+
+// static
+BOOL ScChangeActionContent::NeedsNumberFormat( const ScBaseCell* pCell )
+{
+ return pCell && pCell->GetCellType() == CELLTYPE_VALUE;
+}
+
+
+// static
+void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell,
+ const ScAddress& rPos, const ScBaseCell* pOrgCell,
+ const ScDocument* pFromDoc, ScDocument* pToDoc )
+{
+ ULONG nFormat = NeedsNumberFormat( pOrgCell ) ? pFromDoc->GetNumberFormat( rPos ) : 0;
+ SetValue( rStr, pCell, nFormat, pOrgCell, pFromDoc, pToDoc );
+}
+
+
+// static
+void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell,
+ ULONG nFormat, const ScBaseCell* pOrgCell,
+ const ScDocument* pFromDoc, ScDocument* pToDoc )
+{
+ rStr.Erase();
+ if ( pCell )
+ pCell->Delete();
+ if ( ScChangeActionContent::GetContentCellType( pOrgCell ) )
+ {
+ pCell = pOrgCell->CloneWithoutNote( *pToDoc );
+ switch ( pOrgCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ { // z.B. Datum auch als solches merken
+ double nValue = ((ScValueCell*)pOrgCell)->GetValue();
+ pFromDoc->GetFormatTable()->GetInputLineString( nValue,
+ nFormat, rStr );
+ }
+ break;
+ case CELLTYPE_FORMULA :
+ ((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ pCell = NULL;
+}
+
+
+// static
+void ScChangeActionContent::SetCell( String& rStr, ScBaseCell* pCell,
+ ULONG nFormat, const ScDocument* pDoc )
+{
+ rStr.Erase();
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ { // e.g. remember date as date string
+ double nValue = ((ScValueCell*)pCell)->GetValue();
+ pDoc->GetFormatTable()->GetInputLineString( nValue,
+ nFormat, rStr );
+ }
+ break;
+ case CELLTYPE_FORMULA :
+ ((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+
+void ScChangeActionContent::GetValueString( String& rStr,
+ const String& rValue, const ScBaseCell* pCell ) const
+{
+ if ( !rValue.Len() )
+ {
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_STRING :
+ ((ScStringCell*)pCell)->GetString( rStr );
+ break;
+ case CELLTYPE_EDIT :
+ ((ScEditCell*)pCell)->GetString( rStr );
+ break;
+ case CELLTYPE_VALUE : // ist immer in rValue
+ rStr = rValue;
+ break;
+ case CELLTYPE_FORMULA :
+ GetFormulaString( rStr, (ScFormulaCell*) pCell );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ rStr.Erase();
+ }
+ else
+ rStr = rValue;
+}
+
+
+void ScChangeActionContent::GetFormulaString( String& rStr,
+ const ScFormulaCell* pCell ) const
+{
+ ScAddress aPos( aBigRange.aStart.MakeAddress() );
+ if ( aPos == pCell->aPos || IsDeletedIn() )
+ pCell->GetFormula( rStr );
+ else
+ {
+ DBG_ERROR( "ScChangeActionContent::GetFormulaString: aPos != pCell->aPos" );
+ ScFormulaCell* pNew = new ScFormulaCell( *pCell, *pCell->GetDocument(), aPos );
+ pNew->GetFormula( rStr );
+ delete pNew;
+ }
+}
+
+
+void ScChangeActionContent::PutOldValueToDoc( ScDocument* pDoc,
+ SCsCOL nDx, SCsROW nDy ) const
+{
+ PutValueToDoc( pOldCell, aOldValue, pDoc, nDx, nDy );
+}
+
+
+void ScChangeActionContent::PutNewValueToDoc( ScDocument* pDoc,
+ SCsCOL nDx, SCsROW nDy ) const
+{
+ PutValueToDoc( pNewCell, aNewValue, pDoc, nDx, nDy );
+}
+
+
+void ScChangeActionContent::PutValueToDoc( ScBaseCell* pCell,
+ const String& rValue, ScDocument* pDoc, SCsCOL nDx, SCsROW nDy ) const
+{
+ ScAddress aPos( aBigRange.aStart.MakeAddress() );
+ if ( nDx )
+ aPos.IncCol( nDx );
+ if ( nDy )
+ aPos.IncRow( nDy );
+ if ( !rValue.Len() )
+ {
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE : // ist immer in rValue
+ pDoc->SetString( aPos.Col(), aPos.Row(), aPos.Tab(), rValue );
+ break;
+ default:
+ switch ( ScChangeActionContent::GetContentCellType( pCell ) )
+ {
+ case SC_CACCT_MATORG :
+ {
+ SCCOL nC;
+ SCROW nR;
+ ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR );
+ DBG_ASSERT( nC>0 && nR>0, "ScChangeActionContent::PutValueToDoc: MatColsRows?" );
+ ScRange aRange( aPos );
+ if ( nC > 1 )
+ aRange.aEnd.IncCol( nC-1 );
+ if ( nR > 1 )
+ aRange.aEnd.IncRow( nR-1 );
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( aPos.Tab() );
+ aDestMark.SetMarkArea( aRange );
+ pDoc->InsertMatrixFormula( aPos.Col(), aPos.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ aDestMark, EMPTY_STRING,
+ ((const ScFormulaCell*)pCell)->GetCode() );
+ }
+ break;
+ case SC_CACCT_MATREF :
+ // nothing
+ break;
+ default:
+ pDoc->PutCell( aPos, pCell->CloneWithoutNote( *pDoc ) );
+ }
+ }
+ }
+ else
+ pDoc->PutCell( aPos, NULL );
+ }
+ else
+ pDoc->SetString( aPos.Col(), aPos.Row(), aPos.Tab(), rValue );
+}
+
+
+void lcl_InvalidateReference( ScToken& rTok, const ScBigAddress& rPos )
+{
+ ScSingleRefData& rRef1 = rTok.GetSingleRef();
+ if ( rPos.Col() < 0 || MAXCOL < rPos.Col() )
+ {
+ rRef1.nCol = SCCOL_MAX;
+ rRef1.nRelCol = SCCOL_MAX;
+ rRef1.SetColDeleted( TRUE );
+ }
+ if ( rPos.Row() < 0 || MAXROW < rPos.Row() )
+ {
+ rRef1.nRow = SCROW_MAX;
+ rRef1.nRelRow = SCROW_MAX;
+ rRef1.SetRowDeleted( TRUE );
+ }
+ if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() )
+ {
+ rRef1.nTab = SCTAB_MAX;
+ rRef1.nRelTab = SCTAB_MAX;
+ rRef1.SetTabDeleted( TRUE );
+ }
+ if ( rTok.GetType() == formula::svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = rTok.GetDoubleRef().Ref2;
+ if ( rPos.Col() < 0 || MAXCOL < rPos.Col() )
+ {
+ rRef2.nCol = SCCOL_MAX;
+ rRef2.nRelCol = SCCOL_MAX;
+ rRef2.SetColDeleted( TRUE );
+ }
+ if ( rPos.Row() < 0 || MAXROW < rPos.Row() )
+ {
+ rRef2.nRow = SCROW_MAX;
+ rRef2.nRelRow = SCROW_MAX;
+ rRef2.SetRowDeleted( TRUE );
+ }
+ if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() )
+ {
+ rRef2.nTab = SCTAB_MAX;
+ rRef2.nRelTab = SCTAB_MAX;
+ rRef2.SetTabDeleted( TRUE );
+ }
+ }
+}
+
+
+void ScChangeActionContent::UpdateReference( const ScChangeTrack* pTrack,
+ UpdateRefMode eMode, const ScBigRange& rRange,
+ INT32 nDx, INT32 nDy, INT32 nDz )
+{
+ SCSIZE nOldSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() );
+ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aBigRange );
+ SCSIZE nNewSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() );
+ if ( nNewSlot != nOldSlot )
+ {
+ RemoveFromSlot();
+ InsertInSlot( &(pTrack->GetContentSlots()[nNewSlot]) );
+ }
+
+ if ( pTrack->IsInDelete() && !pTrack->IsInDeleteTop() )
+ return ; // Formeln nur kompletten Bereich updaten
+
+ BOOL bOldFormula = ( pOldCell && pOldCell->GetCellType() == CELLTYPE_FORMULA );
+ BOOL bNewFormula = ( pNewCell && pNewCell->GetCellType() == CELLTYPE_FORMULA );
+ if ( bOldFormula || bNewFormula )
+ { // via ScFormulaCell UpdateReference anpassen (dort)
+ if ( pTrack->IsInDelete() )
+ {
+ const ScRange& rDelRange = pTrack->GetInDeleteRange();
+ if ( nDx > 0 )
+ nDx = rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1;
+ else if ( nDx < 0 )
+ nDx = -(rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1);
+ if ( nDy > 0 )
+ nDy = rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1;
+ else if ( nDy < 0 )
+ nDy = -(rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1);
+ if ( nDz > 0 )
+ nDz = rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1;
+ else if ( nDz < 0 )
+ nDz = -(rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1);
+ }
+ ScBigRange aTmpRange( rRange );
+ switch ( eMode )
+ {
+ case URM_INSDEL :
+ if ( nDx < 0 || nDy < 0 || nDz < 0 )
+ { // Delete startet dort hinter geloeschtem Bereich,
+ // Position wird dort angepasst.
+ if ( nDx )
+ aTmpRange.aStart.IncCol( -nDx );
+ if ( nDy )
+ aTmpRange.aStart.IncRow( -nDy );
+ if ( nDz )
+ aTmpRange.aStart.IncTab( -nDz );
+ }
+ break;
+ case URM_MOVE :
+ // Move ist hier Quelle, dort Ziel,
+ // Position muss vorher angepasst sein.
+ if ( bOldFormula )
+ ((ScFormulaCell*)pOldCell)->aPos = aBigRange.aStart.MakeAddress();
+ if ( bNewFormula )
+ ((ScFormulaCell*)pNewCell)->aPos = aBigRange.aStart.MakeAddress();
+ if ( nDx )
+ {
+ aTmpRange.aStart.IncCol( nDx );
+ aTmpRange.aEnd.IncCol( nDx );
+ }
+ if ( nDy )
+ {
+ aTmpRange.aStart.IncRow( nDy );
+ aTmpRange.aEnd.IncRow( nDy );
+ }
+ if ( nDz )
+ {
+ aTmpRange.aStart.IncTab( nDz );
+ aTmpRange.aEnd.IncTab( nDz );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRange aRange( aTmpRange.MakeRange() );
+ if ( bOldFormula )
+ ((ScFormulaCell*)pOldCell)->UpdateReference( eMode, aRange,
+ (SCsCOL) nDx, (SCsROW) nDy, (SCsTAB) nDz, NULL );
+ if ( bNewFormula )
+ ((ScFormulaCell*)pNewCell)->UpdateReference( eMode, aRange,
+ (SCsCOL) nDx, (SCsROW) nDy, (SCsTAB) nDz, NULL );
+ if ( !aBigRange.aStart.IsValid( pTrack->GetDocument() ) )
+ { //! HACK!
+ //! UpdateReference kann nicht mit Positionen ausserhalb des
+ //! Dokuments umgehen, deswegen alles auf #REF! setzen
+//2do: make it possible! das bedeutet grossen Umbau von ScAddress etc.!
+ const ScBigAddress& rPos = aBigRange.aStart;
+ if ( bOldFormula )
+ {
+ ScToken* t;
+ ScTokenArray* pArr = ((ScFormulaCell*)pOldCell)->GetCode();
+ pArr->Reset();
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReference()) ) != NULL )
+ lcl_InvalidateReference( *t, rPos );
+ pArr->Reset();
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+ lcl_InvalidateReference( *t, rPos );
+ }
+ if ( bNewFormula )
+ {
+ ScToken* t;
+ ScTokenArray* pArr = ((ScFormulaCell*)pNewCell)->GetCode();
+ pArr->Reset();
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReference()) ) != NULL )
+ lcl_InvalidateReference( *t, rPos );
+ pArr->Reset();
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+ lcl_InvalidateReference( *t, rPos );
+ }
+ }
+ }
+}
+
+
+// --- ScChangeActionReject ------------------------------------------------
+
+ScChangeActionReject::ScChangeActionReject(const ULONG nActionNumber, const ScChangeActionState eStateP, const ULONG nRejectingNumber,
+ const ScBigRange& aBigRangeP, const String& aUserP, const DateTime& aDateTimeP, const String& sComment)
+ :
+ ScChangeAction(SC_CAT_CONTENT, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment)
+{
+}
+
+
+// --- ScChangeTrack -------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo, 16, 16 )
+
+const SCROW ScChangeTrack::nContentRowsPerSlot = InitContentRowsPerSlot();
+const SCSIZE ScChangeTrack::nContentSlots =
+ (MAXROWCOUNT) / InitContentRowsPerSlot() + 2;
+
+// static
+SCROW ScChangeTrack::InitContentRowsPerSlot()
+{
+ const SCSIZE nMaxSlots = 0xffe0 / sizeof( ScChangeActionContent* ) - 2;
+ SCROW nRowsPerSlot = (MAXROWCOUNT) / nMaxSlots;
+ if ( nRowsPerSlot * nMaxSlots < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+ ++nRowsPerSlot;
+ return nRowsPerSlot;
+}
+
+
+ScChangeTrack::ScChangeTrack( ScDocument* pDocP ) :
+ pDoc( pDocP )
+{
+ Init();
+ SC_MOD()->GetUserOptions().AddListener(this);
+
+ ppContentSlots = new ScChangeActionContent* [ nContentSlots ];
+ memset( ppContentSlots, 0, nContentSlots * sizeof( ScChangeActionContent* ) );
+}
+
+ScChangeTrack::ScChangeTrack( ScDocument* pDocP, const ScStrCollection& aTempUserCollection) :
+ aUserCollection(aTempUserCollection),
+ pDoc( pDocP )
+{
+ Init();
+ SC_MOD()->GetUserOptions().AddListener(this);
+ ppContentSlots = new ScChangeActionContent* [ nContentSlots ];
+ memset( ppContentSlots, 0, nContentSlots * sizeof( ScChangeActionContent* ) );
+}
+
+ScChangeTrack::~ScChangeTrack()
+{
+ SC_MOD()->GetUserOptions().RemoveListener(this);
+ DtorClear();
+ delete [] ppContentSlots;
+}
+
+
+void ScChangeTrack::Init()
+{
+ pFirst = NULL;
+ pLast = NULL;
+ pFirstGeneratedDelContent = NULL;
+ pLastCutMove = NULL;
+ pLinkInsertCol = NULL;
+ pLinkInsertRow = NULL;
+ pLinkInsertTab = NULL;
+ pLinkMove = NULL;
+ pBlockModifyMsg = NULL;
+ nActionMax = 0;
+ nGeneratedMin = SC_CHGTRACK_GENERATED_START;
+ nMarkLastSaved = 0;
+ nStartLastCut = 0;
+ nEndLastCut = 0;
+ nLastMerge = 0;
+ eMergeState = SC_CTMS_NONE;
+ nLoadedFileFormatVersion = SC_CHGTRACK_FILEFORMAT;
+ bLoadSave = FALSE;
+ bInDelete = FALSE;
+ bInDeleteTop = FALSE;
+ bInDeleteUndo = FALSE;
+ bInPasteCut = FALSE;
+ bUseFixDateTime = FALSE;
+ bTime100thSeconds = TRUE;
+
+ const SvtUserOptions& rUserOpt = SC_MOD()->GetUserOptions();
+ aUser = rUserOpt.GetFirstName();
+ aUser += ' ';
+ aUser += (String)rUserOpt.GetLastName();
+ aUserCollection.Insert( new StrData( aUser ) );
+}
+
+
+void ScChangeTrack::DtorClear()
+{
+ ScChangeAction* p;
+ ScChangeAction* pNext;
+ for ( p = GetFirst(); p; p = pNext )
+ {
+ pNext = p->GetNext();
+ delete p;
+ }
+ for ( p = pFirstGeneratedDelContent; p; p = pNext )
+ {
+ pNext = p->GetNext();
+ delete p;
+ }
+ for ( p = aPasteCutTable.First(); p; p = aPasteCutTable.Next() )
+ {
+ delete p;
+ }
+ delete pLastCutMove;
+ ClearMsgQueue();
+}
+
+
+void ScChangeTrack::ClearMsgQueue()
+{
+ if ( pBlockModifyMsg )
+ {
+ delete pBlockModifyMsg;
+ pBlockModifyMsg = NULL;
+ }
+ ScChangeTrackMsgInfo* pMsgInfo;
+ while ( ( pMsgInfo = aMsgStackTmp.Pop() ) != NULL )
+ delete pMsgInfo;
+ while ( ( pMsgInfo = aMsgStackFinal.Pop() ) != NULL )
+ delete pMsgInfo;
+ while ( ( pMsgInfo = aMsgQueue.Get() ) != NULL )
+ delete pMsgInfo;
+}
+
+
+void ScChangeTrack::Clear()
+{
+ DtorClear();
+ aTable.Clear();
+ aGeneratedTable.Clear();
+ aPasteCutTable.Clear();
+ aUserCollection.FreeAll();
+ aUser.Erase();
+ Init();
+}
+
+
+void __EXPORT ScChangeTrack::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
+{
+ if ( !pDoc->IsInDtorClear() )
+ {
+ const SvtUserOptions& rUserOptions = SC_MOD()->GetUserOptions();
+ USHORT nOldCount = aUserCollection.GetCount();
+
+ String aStr( rUserOptions.GetFirstName() );
+ aStr += ' ';
+ aStr += (String)rUserOptions.GetLastName();
+ SetUser( aStr );
+
+ if ( aUserCollection.GetCount() != nOldCount )
+ {
+ // New user in collection -> have to repaint because
+ // colors may be different now (#106697#).
+ // (Has to be done in the Notify handler, to be sure
+ // the user collection has already been updated)
+
+ SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
+ if (pDocSh)
+ pDocSh->Broadcast( ScPaintHint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB), PAINT_GRID ) );
+ }
+ }
+}
+
+
+void ScChangeTrack::SetUser( const String& rUser )
+{
+ if ( IsLoadSave() )
+ return ; // nicht die Collection zerschiessen
+
+ aUser = rUser;
+ StrData* pStrData = new StrData( aUser );
+ if ( !aUserCollection.Insert( pStrData ) )
+ delete pStrData;
+}
+
+
+void ScChangeTrack::StartBlockModify( ScChangeTrackMsgType eMsgType,
+ ULONG nStartAction )
+{
+ if ( aModifiedLink.IsSet() )
+ {
+ if ( pBlockModifyMsg )
+ aMsgStackTmp.Push( pBlockModifyMsg ); // Block im Block
+ pBlockModifyMsg = new ScChangeTrackMsgInfo;
+ pBlockModifyMsg->eMsgType = eMsgType;
+ pBlockModifyMsg->nStartAction = nStartAction;
+ }
+}
+
+
+void ScChangeTrack::EndBlockModify( ULONG nEndAction )
+{
+ if ( aModifiedLink.IsSet() )
+ {
+ if ( pBlockModifyMsg )
+ {
+ if ( pBlockModifyMsg->nStartAction <= nEndAction )
+ {
+ pBlockModifyMsg->nEndAction = nEndAction;
+ // Blocks in Blocks aufgeloest
+ aMsgStackFinal.Push( pBlockModifyMsg );
+ }
+ else
+ delete pBlockModifyMsg;
+ pBlockModifyMsg = aMsgStackTmp.Pop(); // evtl. Block im Block
+ }
+ if ( !pBlockModifyMsg )
+ {
+ BOOL bNew = FALSE;
+ ScChangeTrackMsgInfo* pMsg;
+ while ( ( pMsg = aMsgStackFinal.Pop() ) != NULL )
+ {
+ aMsgQueue.Put( pMsg );
+ bNew = TRUE;
+ }
+ if ( bNew )
+ aModifiedLink.Call( this );
+ }
+ }
+}
+
+
+void ScChangeTrack::NotifyModified( ScChangeTrackMsgType eMsgType,
+ ULONG nStartAction, ULONG nEndAction )
+{
+ if ( aModifiedLink.IsSet() )
+ {
+ if ( !pBlockModifyMsg || pBlockModifyMsg->eMsgType != eMsgType ||
+ (IsGenerated( nStartAction ) &&
+ (eMsgType == SC_CTM_APPEND || eMsgType == SC_CTM_REMOVE)) )
+ { // Append innerhalb von Append z.B. nicht
+ StartBlockModify( eMsgType, nStartAction );
+ EndBlockModify( nEndAction );
+ }
+ }
+}
+
+
+void ScChangeTrack::MasterLinks( ScChangeAction* pAppend )
+{
+ ScChangeActionType eType = pAppend->GetType();
+
+ if ( eType == SC_CAT_CONTENT )
+ {
+ if ( !IsGenerated( pAppend->GetActionNumber() ) )
+ {
+ SCSIZE nSlot = ComputeContentSlot(
+ pAppend->GetBigRange().aStart.Row() );
+ ((ScChangeActionContent*)pAppend)->InsertInSlot(
+ &ppContentSlots[nSlot] );
+ }
+ return ;
+ }
+
+ if ( pAppend->IsRejecting() )
+ return ; // Rejects haben keine Abhaengigkeiten
+
+ switch ( eType )
+ {
+ case SC_CAT_INSERT_COLS :
+ {
+ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
+ &pLinkInsertCol, pAppend );
+ pAppend->AddLink( NULL, pLink );
+ }
+ break;
+ case SC_CAT_INSERT_ROWS :
+ {
+ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
+ &pLinkInsertRow, pAppend );
+ pAppend->AddLink( NULL, pLink );
+ }
+ break;
+ case SC_CAT_INSERT_TABS :
+ {
+ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
+ &pLinkInsertTab, pAppend );
+ pAppend->AddLink( NULL, pLink );
+ }
+ break;
+ case SC_CAT_MOVE :
+ {
+ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
+ &pLinkMove, pAppend );
+ pAppend->AddLink( NULL, pLink );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+
+void ScChangeTrack::AppendLoaded( ScChangeAction* pAppend )
+{
+ aTable.Insert( pAppend->GetActionNumber(), pAppend );
+ if ( !pLast )
+ pFirst = pLast = pAppend;
+ else
+ {
+ pLast->pNext = pAppend;
+ pAppend->pPrev = pLast;
+ pLast = pAppend;
+ }
+ MasterLinks( pAppend );
+}
+
+
+void ScChangeTrack::Append( ScChangeAction* pAppend, ULONG nAction )
+{
+ if ( nActionMax < nAction )
+ nActionMax = nAction;
+ pAppend->SetUser( aUser );
+ if ( bUseFixDateTime )
+ pAppend->SetDateTimeUTC( aFixDateTime );
+ pAppend->SetActionNumber( nAction );
+ aTable.Insert( nAction, pAppend );
+ // UpdateReference Inserts vor Dependencies.
+ // Delete rejectendes Insert hatte UpdateReference mit Delete-Undo.
+ // UpdateReference auch wenn pLast==NULL, weil pAppend ein Delete sein
+ // kann, dass DelContents generiert haben kann
+ if ( pAppend->IsInsertType() && !pAppend->IsRejecting() )
+ UpdateReference( pAppend, FALSE );
+ if ( !pLast )
+ pFirst = pLast = pAppend;
+ else
+ {
+ pLast->pNext = pAppend;
+ pAppend->pPrev = pLast;
+ pLast = pAppend;
+ Dependencies( pAppend );
+ }
+ // UpdateReference Inserts nicht nach Dependencies.
+ // Move rejectendes Move hatte UpdateReference mit Move-Undo, Inhalt in
+ // ToRange nicht deleten.
+ if ( !pAppend->IsInsertType() &&
+ !(pAppend->GetType() == SC_CAT_MOVE && pAppend->IsRejecting()) )
+ UpdateReference( pAppend, FALSE );
+ MasterLinks( pAppend );
+
+ if ( aModifiedLink.IsSet() )
+ {
+ NotifyModified( SC_CTM_APPEND, nAction, nAction );
+ if ( pAppend->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContent* pContent = (ScChangeActionContent*) pAppend;
+ if ( ( pContent = pContent->GetPrevContent() ) != NULL )
+ {
+ ULONG nMod = pContent->GetActionNumber();
+ NotifyModified( SC_CTM_CHANGE, nMod, nMod );
+ }
+ }
+ else
+ NotifyModified( SC_CTM_CHANGE, pFirst->GetActionNumber(),
+ pLast->GetActionNumber() );
+ }
+}
+
+
+void ScChangeTrack::Append( ScChangeAction* pAppend )
+{
+ Append( pAppend, ++nActionMax );
+}
+
+
+void ScChangeTrack::AppendDeleteRange( const ScRange& rRange,
+ ScDocument* pRefDoc, ULONG& nStartAction, ULONG& nEndAction, SCsTAB nDz )
+{
+ nStartAction = GetActionMax() + 1;
+ AppendDeleteRange( rRange, pRefDoc, nDz, 0 );
+ nEndAction = GetActionMax();
+}
+
+
+void ScChangeTrack::AppendDeleteRange( const ScRange& rRange,
+ ScDocument* pRefDoc, SCsTAB nDz, ULONG nRejectingInsert )
+{
+ SetInDeleteRange( rRange );
+ StartBlockModify( SC_CTM_APPEND, GetActionMax() + 1 );
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ for ( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
+ {
+ if ( !pRefDoc || nTab < pRefDoc->GetTableCount() )
+ {
+ if ( nCol1 == 0 && nCol2 == MAXCOL )
+ { // ganze Zeilen und/oder Tabellen
+ if ( nRow1 == 0 && nRow2 == MAXROW )
+ { // ganze Tabellen
+//2do: geht nicht auch komplette Tabelle als ganzes?
+ ScRange aRange( 0, 0, nTab, 0, MAXROW, nTab );
+ for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ )
+ { // spaltenweise ist weniger als zeilenweise
+ aRange.aStart.SetCol( nCol );
+ aRange.aEnd.SetCol( nCol );
+ if ( nCol == nCol2 )
+ SetInDeleteTop( TRUE );
+ AppendOneDeleteRange( aRange, pRefDoc, nCol-nCol1, 0,
+ nTab-nTab1 + nDz, nRejectingInsert );
+ }
+ //! immer noch InDeleteTop
+ AppendOneDeleteRange( rRange, pRefDoc, 0, 0,
+ nTab-nTab1 + nDz, nRejectingInsert );
+ }
+ else
+ { // ganze Zeilen
+ ScRange aRange( 0, 0, nTab, MAXCOL, 0, nTab );
+ for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
+ {
+ aRange.aStart.SetRow( nRow );
+ aRange.aEnd.SetRow( nRow );
+ if ( nRow == nRow2 )
+ SetInDeleteTop( TRUE );
+ AppendOneDeleteRange( aRange, pRefDoc, 0, nRow-nRow1,
+ 0, nRejectingInsert );
+ }
+ }
+ }
+ else if ( nRow1 == 0 && nRow2 == MAXROW )
+ { // ganze Spalten
+ ScRange aRange( 0, 0, nTab, 0, MAXROW, nTab );
+ for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ )
+ {
+ aRange.aStart.SetCol( nCol );
+ aRange.aEnd.SetCol( nCol );
+ if ( nCol == nCol2 )
+ SetInDeleteTop( TRUE );
+ AppendOneDeleteRange( aRange, pRefDoc, nCol-nCol1, 0,
+ 0, nRejectingInsert );
+ }
+ }
+ else
+ {
+ DBG_ERROR( "ScChangeTrack::AppendDeleteRange: Block not supported!" );
+ }
+ SetInDeleteTop( FALSE );
+ }
+ }
+ EndBlockModify( GetActionMax() );
+}
+
+
+void ScChangeTrack::AppendOneDeleteRange( const ScRange& rOrgRange,
+ ScDocument* pRefDoc, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ULONG nRejectingInsert )
+{
+ ScRange aTrackRange( rOrgRange );
+ if ( nDx )
+ {
+ aTrackRange.aStart.IncCol( -nDx );
+ aTrackRange.aEnd.IncCol( -nDx );
+ }
+ if ( nDy )
+ {
+ aTrackRange.aStart.IncRow( -nDy );
+ aTrackRange.aEnd.IncRow( -nDy );
+ }
+ if ( nDz )
+ {
+ aTrackRange.aStart.IncTab( -nDz );
+ aTrackRange.aEnd.IncTab( -nDz );
+ }
+ ScChangeActionDel* pAct = new ScChangeActionDel( aTrackRange, nDx, nDy,
+ this );
+ // TabDelete keine Contents, sind in einzelnen Spalten
+ if ( !(rOrgRange.aStart.Col() == 0 && rOrgRange.aStart.Row() == 0 &&
+ rOrgRange.aEnd.Col() == MAXCOL && rOrgRange.aEnd.Row() == MAXROW) )
+ LookUpContents( rOrgRange, pRefDoc, -nDx, -nDy, -nDz );
+ if ( nRejectingInsert )
+ {
+ pAct->SetRejectAction( nRejectingInsert );
+ pAct->SetState( SC_CAS_ACCEPTED );
+ }
+ Append( pAct );
+}
+
+
+void ScChangeTrack::LookUpContents( const ScRange& rOrgRange,
+ ScDocument* pRefDoc, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ if ( pRefDoc )
+ {
+ ScAddress aPos;
+ ScBigAddress aBigPos;
+ ScCellIterator aIter( pRefDoc, rOrgRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ if ( ScChangeActionContent::GetContentCellType( pCell ) )
+ {
+ aBigPos.Set( aIter.GetCol() + nDx, aIter.GetRow() + nDy,
+ aIter.GetTab() + nDz );
+ ScChangeActionContent* pContent = SearchContentAt( aBigPos, NULL );
+ if ( !pContent )
+ { // nicht getrackte Contents
+ aPos.Set( aIter.GetCol() + nDx, aIter.GetRow() + nDy,
+ aIter.GetTab() + nDz );
+ GenerateDelContent( aPos, pCell, pRefDoc );
+ //! der Content wird hier _nicht_ per AddContent hinzugefuegt,
+ //! sondern in UpdateReference, um z.B. auch kreuzende Deletes
+ //! korrekt zu erfassen
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+}
+
+
+void ScChangeTrack::AppendMove( const ScRange& rFromRange,
+ const ScRange& rToRange, ScDocument* pRefDoc )
+{
+ ScChangeActionMove* pAct = new ScChangeActionMove( rFromRange, rToRange, this );
+ LookUpContents( rToRange, pRefDoc, 0, 0, 0 ); // ueberschriebene Contents
+ Append( pAct );
+}
+
+
+// static
+BOOL ScChangeTrack::IsMatrixFormulaRangeDifferent( const ScBaseCell* pOldCell,
+ const ScBaseCell* pNewCell )
+{
+ SCCOL nC1, nC2;
+ SCROW nR1, nR2;
+ nC1 = nC2 = 0;
+ nR1 = nR2 = 0;
+ if ( pOldCell && (pOldCell->GetCellType() == CELLTYPE_FORMULA) &&
+ ((const ScFormulaCell*)pOldCell)->GetMatrixFlag() == MM_FORMULA )
+ ((const ScFormulaCell*)pOldCell)->GetMatColsRows( nC1, nR1 );
+ if ( pNewCell && (pNewCell->GetCellType() == CELLTYPE_FORMULA) &&
+ ((const ScFormulaCell*)pNewCell)->GetMatrixFlag() == MM_FORMULA )
+ ((const ScFormulaCell*)pNewCell)->GetMatColsRows( nC1, nR1 );
+ return nC1 != nC2 || nR1 != nR2;
+}
+
+
+void ScChangeTrack::AppendContent( const ScAddress& rPos,
+ const String& rNewValue, ScBaseCell* pOldCell )
+{
+ String aOldValue;
+ ScChangeActionContent::GetStringOfCell( aOldValue, pOldCell, pDoc, rPos );
+ if ( aOldValue != rNewValue ||
+ IsMatrixFormulaRangeDifferent( pOldCell, NULL ) )
+ { // nur wirkliche Aenderung tracken
+ ScRange aRange( rPos );
+ ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
+ pAct->SetOldValue( pOldCell, pDoc, pDoc );
+ pAct->SetNewValue( rNewValue, pDoc );
+ Append( pAct );
+ }
+}
+
+
+void ScChangeTrack::AppendContent( const ScAddress& rPos,
+ const ScBaseCell* pOldCell, ULONG nOldFormat, ScDocument* pRefDoc )
+{
+ if ( !pRefDoc )
+ pRefDoc = pDoc;
+ String aOldValue;
+ ScChangeActionContent::GetStringOfCell( aOldValue, pOldCell, pRefDoc, nOldFormat );
+ String aNewValue;
+ ScBaseCell* pNewCell = pDoc->GetCell( rPos );
+ ScChangeActionContent::GetStringOfCell( aNewValue, pNewCell, pDoc, rPos );
+ if ( aOldValue != aNewValue ||
+ IsMatrixFormulaRangeDifferent( pOldCell, pNewCell ) )
+ { // nur wirkliche Aenderung tracken
+ ScRange aRange( rPos );
+ ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
+ pAct->SetOldValue( pOldCell, pRefDoc, pDoc, nOldFormat );
+ pAct->SetNewValue( pNewCell, pDoc );
+ Append( pAct );
+ }
+}
+
+
+void ScChangeTrack::AppendContent( const ScAddress& rPos,
+ ScDocument* pRefDoc )
+{
+ String aOldValue;
+ ScBaseCell* pOldCell = pRefDoc->GetCell( rPos );
+ ScChangeActionContent::GetStringOfCell( aOldValue, pOldCell, pRefDoc, rPos );
+ String aNewValue;
+ ScBaseCell* pNewCell = pDoc->GetCell( rPos );
+ ScChangeActionContent::GetStringOfCell( aNewValue, pNewCell, pDoc, rPos );
+ if ( aOldValue != aNewValue ||
+ IsMatrixFormulaRangeDifferent( pOldCell, pNewCell ) )
+ { // nur wirkliche Aenderung tracken
+ ScRange aRange( rPos );
+ ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
+ pAct->SetOldValue( pOldCell, pRefDoc, pDoc );
+ pAct->SetNewValue( pNewCell, pDoc );
+ Append( pAct );
+ }
+}
+
+
+void ScChangeTrack::AppendContent( const ScAddress& rPos,
+ const ScBaseCell* pOldCell )
+{
+ if ( ScChangeActionContent::NeedsNumberFormat( pOldCell ) )
+ AppendContent( rPos, pOldCell, pDoc->GetNumberFormat( rPos ), pDoc );
+ else
+ AppendContent( rPos, pOldCell, 0, pDoc );
+}
+
+
+void ScChangeTrack::SetLastCutMoveRange( const ScRange& rRange,
+ ScDocument* pRefDoc )
+{
+ if ( pLastCutMove )
+ {
+ // ToRange nicht mit Deletes linken und nicht in der Groesse aendern,
+ // eigentlich unnoetig, da ein Delete vorher in
+ // ScViewFunc::PasteFromClip ein ResetLastCut ausloest
+ ScBigRange& r = pLastCutMove->GetBigRange();
+ r.aEnd.SetCol( -1 );
+ r.aEnd.SetRow( -1 );
+ r.aEnd.SetTab( -1 );
+ r.aStart.SetCol( -1 - (rRange.aEnd.Col() - rRange.aStart.Col()) );
+ r.aStart.SetRow( -1 - (rRange.aEnd.Row() - rRange.aStart.Row()) );
+ r.aStart.SetTab( -1 - (rRange.aEnd.Tab() - rRange.aStart.Tab()) );
+ // zu ueberschreibende Contents im FromRange
+ LookUpContents( rRange, pRefDoc, 0, 0, 0 );
+ }
+}
+
+
+void ScChangeTrack::AppendContentRange( const ScRange& rRange,
+ ScDocument* pRefDoc, ULONG& nStartAction, ULONG& nEndAction,
+ ScChangeActionClipMode eClipMode )
+{
+ if ( eClipMode == SC_CACM_CUT )
+ {
+ ResetLastCut();
+ pLastCutMove = new ScChangeActionMove( rRange, rRange, this );
+ SetLastCutMoveRange( rRange, pRefDoc );
+ }
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ BOOL bDoContents;
+ if ( eClipMode == SC_CACM_PASTE && HasLastCut() )
+ {
+ bDoContents = FALSE;
+ SetInPasteCut( TRUE );
+ // Paste und Cut abstimmen, Paste kann groesserer Range sein
+ ScRange aRange( rRange );
+ ScBigRange& r = pLastCutMove->GetBigRange();
+ SCCOL nTmpCol;
+ if ( (nTmpCol = (SCCOL) (r.aEnd.Col() - r.aStart.Col())) != (nCol2 - nCol1) )
+ {
+ aRange.aEnd.SetCol( aRange.aStart.Col() + nTmpCol );
+ nCol1 += nTmpCol + 1;
+ bDoContents = TRUE;
+ }
+ SCROW nTmpRow;
+ if ( (nTmpRow = (SCROW) (r.aEnd.Row() - r.aStart.Row())) != (nRow2 - nRow1) )
+ {
+ aRange.aEnd.SetRow( aRange.aStart.Row() + nTmpRow );
+ nRow1 += nTmpRow + 1;
+ bDoContents = TRUE;
+ }
+ SCTAB nTmpTab;
+ if ( (nTmpTab = (SCTAB) (r.aEnd.Tab() - r.aStart.Tab())) != (nTab2 - nTab1) )
+ {
+ aRange.aEnd.SetTab( aRange.aStart.Tab() + nTmpTab );
+ nTab1 += nTmpTab + 1;
+ bDoContents = TRUE;
+ }
+ r = aRange;
+ Undo( nStartLastCut, nEndLastCut ); // hier werden sich die Cuts gemerkt
+ //! StartAction erst nach Undo
+ nStartAction = GetActionMax() + 1;
+ StartBlockModify( SC_CTM_APPEND, nStartAction );
+ // zu ueberschreibende Contents im ToRange
+ LookUpContents( aRange, pRefDoc, 0, 0, 0 );
+ pLastCutMove->SetStartLastCut( nStartLastCut );
+ pLastCutMove->SetEndLastCut( nEndLastCut );
+ Append( pLastCutMove );
+ pLastCutMove = NULL;
+ ResetLastCut();
+ SetInPasteCut( FALSE );
+ }
+ else
+ {
+ bDoContents = TRUE;
+ nStartAction = GetActionMax() + 1;
+ StartBlockModify( SC_CTM_APPEND, nStartAction );
+ }
+ if ( bDoContents )
+ {
+ ScAddress aPos;
+ for ( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
+ {
+ aPos.SetTab( nTab );
+ for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ )
+ {
+ aPos.SetCol( nCol );
+ for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
+ {
+ aPos.SetRow( nRow );
+ AppendContent( aPos, pRefDoc );
+ }
+ }
+ }
+ }
+ nEndAction = GetActionMax();
+ EndBlockModify( nEndAction );
+ if ( eClipMode == SC_CACM_CUT )
+ {
+ nStartLastCut = nStartAction;
+ nEndLastCut = nEndAction;
+ }
+}
+
+
+void ScChangeTrack::AppendContentsIfInRefDoc( ScDocument* pRefDoc,
+ ULONG& nStartAction, ULONG& nEndAction )
+{
+ ScDocumentIterator aIter( pRefDoc, 0, MAXTAB );
+ if ( aIter.GetFirst() )
+ {
+ nStartAction = GetActionMax() + 1;
+ StartBlockModify( SC_CTM_APPEND, nStartAction );
+ SvNumberFormatter* pFormatter = pRefDoc->GetFormatTable();
+ do
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ aIter.GetPos( nCol, nRow, nTab );
+ ScAddress aPos( nCol, nRow, nTab );
+ AppendContent( aPos, aIter.GetCell(),
+ aIter.GetPattern()->GetNumberFormat( pFormatter ), pRefDoc );
+ } while ( aIter.GetNext() );
+ nEndAction = GetActionMax();
+ EndBlockModify( nEndAction );
+ }
+ else
+ nStartAction = nEndAction = 0;
+}
+
+
+ScChangeActionContent* ScChangeTrack::AppendContentOnTheFly(
+ const ScAddress& rPos, ScBaseCell* pOldCell, ScBaseCell* pNewCell,
+ ULONG nOldFormat, ULONG nNewFormat )
+{
+ ScRange aRange( rPos );
+ ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
+ pAct->SetOldNewCells( pOldCell, nOldFormat, pNewCell, nNewFormat, pDoc );
+ Append( pAct );
+ return pAct;
+}
+
+
+void ScChangeTrack::AppendInsert( const ScRange& rRange )
+{
+ ScChangeActionIns* pAct = new ScChangeActionIns( rRange );
+ Append( pAct );
+}
+
+
+void ScChangeTrack::DeleteCellEntries( ScChangeActionCellListEntry*& pCellList,
+ ScChangeAction* pDeletor )
+{
+ ScChangeActionCellListEntry* pE = pCellList;
+ while ( pE )
+ {
+ ScChangeActionCellListEntry* pNext = pE->pNext;
+ pE->pContent->RemoveDeletedIn( pDeletor );
+ if ( IsGenerated( pE->pContent->GetActionNumber() ) &&
+ !pE->pContent->IsDeletedIn() )
+ DeleteGeneratedDelContent( pE->pContent );
+ delete pE;
+ pE = pNext;
+ }
+ pCellList = NULL;
+}
+
+
+ScChangeActionContent* ScChangeTrack::GenerateDelContent(
+ const ScAddress& rPos, const ScBaseCell* pCell,
+ const ScDocument* pFromDoc )
+{
+ ScChangeActionContent* pContent = new ScChangeActionContent(
+ ScRange( rPos ) );
+ pContent->SetActionNumber( --nGeneratedMin );
+ // nur NewValue
+ ScChangeActionContent::SetValue( pContent->aNewValue, pContent->pNewCell,
+ rPos, pCell, pFromDoc, pDoc );
+ // pNextContent und pPrevContent werden nicht gesetzt
+ if ( pFirstGeneratedDelContent )
+ { // vorne reinhaengen
+ pFirstGeneratedDelContent->pPrev = pContent;
+ pContent->pNext = pFirstGeneratedDelContent;
+ }
+ pFirstGeneratedDelContent = pContent;
+ aGeneratedTable.Insert( nGeneratedMin, pContent );
+ NotifyModified( SC_CTM_APPEND, nGeneratedMin, nGeneratedMin );
+ return pContent;
+}
+
+
+void ScChangeTrack::DeleteGeneratedDelContent( ScChangeActionContent* pContent )
+{
+ ULONG nAct = pContent->GetActionNumber();
+ aGeneratedTable.Remove( nAct );
+ if ( pFirstGeneratedDelContent == pContent )
+ pFirstGeneratedDelContent = (ScChangeActionContent*) pContent->pNext;
+ if ( pContent->pNext )
+ pContent->pNext->pPrev = pContent->pPrev;
+ if ( pContent->pPrev )
+ pContent->pPrev->pNext = pContent->pNext;
+ delete pContent;
+ NotifyModified( SC_CTM_REMOVE, nAct, nAct );
+ if ( nAct == nGeneratedMin )
+ ++nGeneratedMin; //! erst nach NotifyModified wg. IsGenerated
+}
+
+
+ScChangeActionContent* ScChangeTrack::SearchContentAt(
+ const ScBigAddress& rPos, ScChangeAction* pButNotThis ) const
+{
+ SCSIZE nSlot = ComputeContentSlot( rPos.Row() );
+ for ( ScChangeActionContent* p = ppContentSlots[nSlot]; p;
+ p = p->GetNextInSlot() )
+ {
+ if ( p != pButNotThis && !p->IsDeletedIn() &&
+ p->GetBigRange().aStart == rPos )
+ {
+ ScChangeActionContent* pContent = p->GetTopContent();
+ if ( !pContent->IsDeletedIn() )
+ return pContent;
+ }
+ }
+ return NULL;
+}
+
+
+void ScChangeTrack::AddDependentWithNotify( ScChangeAction* pParent,
+ ScChangeAction* pDependent )
+{
+ ScChangeActionLinkEntry* pLink = pParent->AddDependent( pDependent );
+ pDependent->AddLink( pParent, pLink );
+ if ( aModifiedLink.IsSet() )
+ {
+ ULONG nMod = pParent->GetActionNumber();
+ NotifyModified( SC_CTM_PARENT, nMod, nMod );
+ }
+}
+
+
+void ScChangeTrack::Dependencies( ScChangeAction* pAct )
+{
+ // Finde die letzte Abhaengigkeit fuer jeweils Col/Row/Tab.
+ // Content an gleicher Position verketten.
+ // Move Abhaengigkeiten.
+ ScChangeActionType eActType = pAct->GetType();
+ if ( eActType == SC_CAT_REJECT ||
+ (eActType == SC_CAT_MOVE && pAct->IsRejecting()) )
+ return ; // diese Rejects sind nicht abhaengig
+
+ if ( eActType == SC_CAT_CONTENT )
+ {
+ if ( !(((ScChangeActionContent*)pAct)->GetNextContent() ||
+ ((ScChangeActionContent*)pAct)->GetPrevContent()) )
+ { // Contents an gleicher Position verketten
+ ScChangeActionContent* pContent = SearchContentAt(
+ pAct->GetBigRange().aStart, pAct );
+ if ( pContent )
+ {
+ pContent->SetNextContent( (ScChangeActionContent*) pAct );
+ ((ScChangeActionContent*)pAct)->SetPrevContent( pContent );
+ }
+ }
+ const ScBaseCell* pCell = ((ScChangeActionContent*)pAct)->GetNewCell();
+ if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATREF )
+ {
+ ScAddress aOrg;
+ ((const ScFormulaCell*)pCell)->GetMatrixOrigin( aOrg );
+ ScChangeActionContent* pContent = SearchContentAt( aOrg, pAct );
+ if ( pContent && pContent->IsMatrixOrigin() )
+ {
+ AddDependentWithNotify( pContent, pAct );
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScChangeTrack::Dependencies: MatOrg not found" );
+ }
+ }
+ }
+
+ if ( !(pLinkInsertCol || pLinkInsertRow || pLinkInsertTab || pLinkMove) )
+ return ; // keine Dependencies
+ if ( pAct->IsRejecting() )
+ return ; // ausser Content keine Dependencies
+
+ // Insert in einem entsprechenden Insert haengt davon ab, sonst muesste
+ // der vorherige Insert gesplittet werden.
+ // Sich kreuzende Inserts und Deletes sind nicht abhaengig.
+ // Alles andere ist abhaengig.
+
+ // Der zuletzt eingelinkte Insert steht am Anfang einer Kette,
+ // also genau richtig
+
+ const ScBigRange& rRange = pAct->GetBigRange();
+ BOOL bActNoInsert = !pAct->IsInsertType();
+ BOOL bActColDel = ( eActType == SC_CAT_DELETE_COLS );
+ BOOL bActRowDel = ( eActType == SC_CAT_DELETE_ROWS );
+ BOOL bActTabDel = ( eActType == SC_CAT_DELETE_TABS );
+
+ if ( pLinkInsertCol && (eActType == SC_CAT_INSERT_COLS ||
+ (bActNoInsert && !bActRowDel && !bActTabDel)) )
+ {
+ for ( ScChangeActionLinkEntry* pL = pLinkInsertCol; pL; pL = pL->GetNext() )
+ {
+ ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction();
+ if ( !pTest->IsRejected() &&
+ pTest->GetBigRange().Intersects( rRange ) )
+ {
+ AddDependentWithNotify( pTest, pAct );
+ break; // for
+ }
+ }
+ }
+ if ( pLinkInsertRow && (eActType == SC_CAT_INSERT_ROWS ||
+ (bActNoInsert && !bActColDel && !bActTabDel)) )
+ {
+ for ( ScChangeActionLinkEntry* pL = pLinkInsertRow; pL; pL = pL->GetNext() )
+ {
+ ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction();
+ if ( !pTest->IsRejected() &&
+ pTest->GetBigRange().Intersects( rRange ) )
+ {
+ AddDependentWithNotify( pTest, pAct );
+ break; // for
+ }
+ }
+ }
+ if ( pLinkInsertTab && (eActType == SC_CAT_INSERT_TABS ||
+ (bActNoInsert && !bActColDel && !bActRowDel)) )
+ {
+ for ( ScChangeActionLinkEntry* pL = pLinkInsertTab; pL; pL = pL->GetNext() )
+ {
+ ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction();
+ if ( !pTest->IsRejected() &&
+ pTest->GetBigRange().Intersects( rRange ) )
+ {
+ AddDependentWithNotify( pTest, pAct );
+ break; // for
+ }
+ }
+ }
+
+ if ( pLinkMove )
+ {
+ if ( eActType == SC_CAT_CONTENT )
+ { // Content ist von FromRange abhaengig
+ const ScBigAddress& rPos = rRange.aStart;
+ for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() )
+ {
+ ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction();
+ if ( !pTest->IsRejected() &&
+ pTest->GetFromRange().In( rPos ) )
+ {
+ AddDependentWithNotify( pTest, pAct );
+ }
+ }
+ }
+ else if ( eActType == SC_CAT_MOVE )
+ { // Move FromRange ist von ToRange abhaengig
+ const ScBigRange& rFromRange = ((ScChangeActionMove*)pAct)->GetFromRange();
+ for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() )
+ {
+ ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction();
+ if ( !pTest->IsRejected() &&
+ pTest->GetBigRange().Intersects( rFromRange ) )
+ {
+ AddDependentWithNotify( pTest, pAct );
+ }
+ }
+ }
+ else
+ { // Inserts und Deletes sind abhaengig, sobald sie FromRange oder
+ // ToRange kreuzen
+ for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() )
+ {
+ ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction();
+ if ( !pTest->IsRejected() &&
+ (pTest->GetFromRange().Intersects( rRange ) ||
+ pTest->GetBigRange().Intersects( rRange )) )
+ {
+ AddDependentWithNotify( pTest, pAct );
+ }
+ }
+ }
+ }
+}
+
+
+void ScChangeTrack::Remove( ScChangeAction* pRemove )
+{
+ // aus Track ausklinken
+ ULONG nAct = pRemove->GetActionNumber();
+ aTable.Remove( nAct );
+ if ( nAct == nActionMax )
+ --nActionMax;
+ if ( pRemove == pLast )
+ pLast = pRemove->pPrev;
+ if ( pRemove == pFirst )
+ pFirst = pRemove->pNext;
+ if ( nAct == nMarkLastSaved )
+ nMarkLastSaved =
+ ( pRemove->pPrev ? pRemove->pPrev->GetActionNumber() : 0 );
+
+ // aus der globalen Kette ausklinken
+ if ( pRemove->pNext )
+ pRemove->pNext->pPrev = pRemove->pPrev;
+ if ( pRemove->pPrev )
+ pRemove->pPrev->pNext = pRemove->pNext;
+
+ // Dependencies nicht loeschen, passiert on delete automatisch durch
+ // LinkEntry, ohne Listen abzuklappern
+
+ if ( aModifiedLink.IsSet() )
+ {
+ NotifyModified( SC_CTM_REMOVE, nAct, nAct );
+ if ( pRemove->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContent* pContent = (ScChangeActionContent*) pRemove;
+ if ( ( pContent = pContent->GetPrevContent() ) != NULL )
+ {
+ ULONG nMod = pContent->GetActionNumber();
+ NotifyModified( SC_CTM_CHANGE, nMod, nMod );
+ }
+ }
+ else if ( pLast )
+ NotifyModified( SC_CTM_CHANGE, pFirst->GetActionNumber(),
+ pLast->GetActionNumber() );
+ }
+
+ if ( IsInPasteCut() && pRemove->GetType() == SC_CAT_CONTENT )
+ { //! Content wird wiederverwertet
+ ScChangeActionContent* pContent = (ScChangeActionContent*) pRemove;
+ pContent->RemoveAllLinks();
+ pContent->ClearTrack();
+ pContent->pNext = pContent->pPrev = NULL;
+ pContent->pNextContent = pContent->pPrevContent = NULL;
+ }
+}
+
+
+void ScChangeTrack::Undo( ULONG nStartAction, ULONG nEndAction, bool bMerge )
+{
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( bMerge )
+ {
+ SetMergeState( SC_CTMS_UNDO );
+ }
+
+ if ( nStartAction == 0 )
+ ++nStartAction;
+ if ( nEndAction > nActionMax )
+ nEndAction = nActionMax;
+ if ( nEndAction && nStartAction <= nEndAction )
+ {
+ if ( nStartAction == nStartLastCut && nEndAction == nEndLastCut &&
+ !IsInPasteCut() )
+ ResetLastCut();
+ StartBlockModify( SC_CTM_REMOVE, nStartAction );
+ for ( ULONG j = nEndAction; j >= nStartAction; --j )
+ { // rueckwaerts um evtl. nActionMax zu recyclen und schnelleren
+ // Zugriff via pLast, Deletes in richtiger Reihenfolge
+ ScChangeAction* pAct = ( (j == nActionMax && pLast &&
+ pLast->GetActionNumber() == j) ? pLast : GetAction( j ) );
+ if ( pAct )
+ {
+ if ( pAct->IsDeleteType() )
+ {
+ if ( j == nEndAction || (pAct != pLast &&
+ ((ScChangeActionDel*)pAct)->IsTopDelete()) )
+ {
+ SetInDeleteTop( TRUE );
+ SetInDeleteRange( ((ScChangeActionDel*)pAct)->
+ GetOverAllRange().MakeRange() );
+ }
+ }
+ UpdateReference( pAct, TRUE );
+ SetInDeleteTop( FALSE );
+ Remove( pAct );
+ if ( IsInPasteCut() )
+ aPasteCutTable.Insert( pAct->GetActionNumber(), pAct );
+ else
+ {
+ if ( j == nStartAction && pAct->GetType() == SC_CAT_MOVE )
+ {
+ ScChangeActionMove* pMove = (ScChangeActionMove*) pAct;
+ ULONG nStart = pMove->GetStartLastCut();
+ ULONG nEnd = pMove->GetEndLastCut();
+ if ( nStart && nStart <= nEnd )
+ { // LastCut wiederherstellen
+ //! Links vor Cut-Append aufloesen
+ pMove->RemoveAllLinks();
+ StartBlockModify( SC_CTM_APPEND, nStart );
+ for ( ULONG nCut = nStart; nCut <= nEnd; nCut++ )
+ {
+ ScChangeAction* pCut = aPasteCutTable.Remove( nCut );
+ if ( pCut )
+ {
+ DBG_ASSERT( !aTable.Get( nCut ), "ScChangeTrack::Undo: nCut dup" );
+ Append( pCut, nCut );
+ }
+ else
+ {
+ DBG_ERROR( "ScChangeTrack::Undo: nCut not found" );
+ }
+ }
+ EndBlockModify( nEnd );
+ ResetLastCut();
+ nStartLastCut = nStart;
+ nEndLastCut = nEnd;
+ pLastCutMove = pMove;
+ SetLastCutMoveRange(
+ pMove->GetFromRange().MakeRange(), pDoc );
+ }
+ else
+ delete pMove;
+ }
+ else
+ delete pAct;
+ }
+ }
+ }
+ EndBlockModify( nEndAction );
+ }
+
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( bMerge )
+ {
+ SetMergeState( SC_CTMS_OTHER );
+ }
+}
+
+
+// static
+BOOL ScChangeTrack::MergeIgnore( const ScChangeAction& rAction, ULONG nFirstMerge )
+{
+ if ( rAction.IsRejected() )
+ return TRUE; // da kommt noch eine passende Reject-Action
+
+ if ( rAction.IsRejecting() && rAction.GetRejectAction() >= nFirstMerge )
+ return TRUE; // da ist sie
+
+ return FALSE; // alles andere
+}
+
+
+void ScChangeTrack::MergePrepare( ScChangeAction* pFirstMerge, bool bShared )
+{
+ SetMergeState( SC_CTMS_PREPARE );
+ ULONG nFirstMerge = pFirstMerge->GetActionNumber();
+ ScChangeAction* pAct = GetLast();
+ if ( pAct )
+ {
+ SetLastMerge( pAct->GetActionNumber() );
+ while ( pAct )
+ { // rueckwaerts, Deletes in richtiger Reihenfolge
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( bShared || !ScChangeTrack::MergeIgnore( *pAct, nFirstMerge ) )
+ {
+ if ( pAct->IsDeleteType() )
+ {
+ if ( ((ScChangeActionDel*)pAct)->IsTopDelete() )
+ {
+ SetInDeleteTop( TRUE );
+ SetInDeleteRange( ((ScChangeActionDel*)pAct)->
+ GetOverAllRange().MakeRange() );
+ }
+ }
+ UpdateReference( pAct, TRUE );
+ SetInDeleteTop( FALSE );
+ pAct->DeleteCellEntries(); // sonst GPF bei Track Clear()
+ }
+ pAct = ( pAct == pFirstMerge ? NULL : pAct->GetPrev() );
+ }
+ }
+ SetMergeState( SC_CTMS_OTHER ); //! nachfolgende per default MergeOther
+}
+
+
+void ScChangeTrack::MergeOwn( ScChangeAction* pAct, ULONG nFirstMerge, bool bShared )
+{
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( bShared || !ScChangeTrack::MergeIgnore( *pAct, nFirstMerge ) )
+ {
+ SetMergeState( SC_CTMS_OWN );
+ if ( pAct->IsDeleteType() )
+ {
+ if ( ((ScChangeActionDel*)pAct)->IsTopDelete() )
+ {
+ SetInDeleteTop( TRUE );
+ SetInDeleteRange( ((ScChangeActionDel*)pAct)->
+ GetOverAllRange().MakeRange() );
+ }
+ }
+ UpdateReference( pAct, FALSE );
+ SetInDeleteTop( FALSE );
+ SetMergeState( SC_CTMS_OTHER ); //! nachfolgende per default MergeOther
+ }
+}
+
+
+void ScChangeTrack::UpdateReference( ScChangeAction* pAct, BOOL bUndo )
+{
+ ScChangeActionType eActType = pAct->GetType();
+ if ( eActType == SC_CAT_CONTENT || eActType == SC_CAT_REJECT )
+ return ;
+
+ //! Formelzellen haengen nicht im Dokument
+ BOOL bOldAutoCalc = pDoc->GetAutoCalc();
+ pDoc->SetAutoCalc( FALSE );
+ BOOL bOldNoListening = pDoc->GetNoListening();
+ pDoc->SetNoListening( TRUE );
+ //! Formelzellen ExpandRefs synchronisiert zu denen im Dokument
+ BOOL bOldExpandRefs = pDoc->IsExpandRefs();
+ if ( (!bUndo && pAct->IsInsertType()) || (bUndo && pAct->IsDeleteType()) )
+ pDoc->SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
+
+ if ( pAct->IsDeleteType() )
+ {
+ SetInDeleteUndo( bUndo );
+ SetInDelete( TRUE );
+ }
+ else if ( GetMergeState() == SC_CTMS_OWN )
+ {
+ // Referenzen von Formelzellen wiederherstellen,
+ // vorheriges MergePrepare war bei einem Insert wie ein Delete
+ if ( pAct->IsInsertType() )
+ SetInDeleteUndo( TRUE );
+ }
+
+ //! erst die generated, als waeren sie vorher getrackt worden
+ if ( pFirstGeneratedDelContent )
+ UpdateReference( (ScChangeAction**)&pFirstGeneratedDelContent, pAct,
+ bUndo );
+ UpdateReference( &pFirst, pAct, bUndo );
+
+ SetInDelete( FALSE );
+ SetInDeleteUndo( FALSE );
+
+ pDoc->SetExpandRefs( bOldExpandRefs );
+ pDoc->SetNoListening( bOldNoListening );
+ pDoc->SetAutoCalc( bOldAutoCalc );
+}
+
+
+void ScChangeTrack::UpdateReference( ScChangeAction** ppFirstAction,
+ ScChangeAction* pAct, BOOL bUndo )
+{
+ ScChangeActionType eActType = pAct->GetType();
+ BOOL bGeneratedDelContents =
+ ( ppFirstAction == (ScChangeAction**)&pFirstGeneratedDelContent );
+ const ScBigRange& rOrgRange = pAct->GetBigRange();
+ ScBigRange aRange( rOrgRange );
+ ScBigRange aDelRange( rOrgRange );
+ INT32 nDx, nDy, nDz;
+ nDx = nDy = nDz = 0;
+ UpdateRefMode eMode = URM_INSDEL;
+ BOOL bDel = FALSE;
+ switch ( eActType )
+ {
+ case SC_CAT_INSERT_COLS :
+ aRange.aEnd.SetCol( nInt32Max );
+ nDx = rOrgRange.aEnd.Col() - rOrgRange.aStart.Col() + 1;
+ break;
+ case SC_CAT_INSERT_ROWS :
+ aRange.aEnd.SetRow( nInt32Max );
+ nDy = rOrgRange.aEnd.Row() - rOrgRange.aStart.Row() + 1;
+ break;
+ case SC_CAT_INSERT_TABS :
+ aRange.aEnd.SetTab( nInt32Max );
+ nDz = rOrgRange.aEnd.Tab() - rOrgRange.aStart.Tab() + 1;
+ break;
+ case SC_CAT_DELETE_COLS :
+ aRange.aEnd.SetCol( nInt32Max );
+ nDx = -(rOrgRange.aEnd.Col() - rOrgRange.aStart.Col() + 1);
+ aDelRange.aEnd.SetCol( aDelRange.aStart.Col() - nDx - 1 );
+ bDel = TRUE;
+ break;
+ case SC_CAT_DELETE_ROWS :
+ aRange.aEnd.SetRow( nInt32Max );
+ nDy = -(rOrgRange.aEnd.Row() - rOrgRange.aStart.Row() + 1);
+ aDelRange.aEnd.SetRow( aDelRange.aStart.Row() - nDy - 1 );
+ bDel = TRUE;
+ break;
+ case SC_CAT_DELETE_TABS :
+ aRange.aEnd.SetTab( nInt32Max );
+ nDz = -(rOrgRange.aEnd.Tab() - rOrgRange.aStart.Tab() + 1);
+ aDelRange.aEnd.SetTab( aDelRange.aStart.Tab() - nDz - 1 );
+ bDel = TRUE;
+ break;
+ case SC_CAT_MOVE :
+ eMode = URM_MOVE;
+ ((ScChangeActionMove*)pAct)->GetDelta( nDx, nDy, nDz );
+ break;
+ default:
+ DBG_ERROR( "ScChangeTrack::UpdateReference: unknown Type" );
+ }
+ if ( bUndo )
+ {
+ nDx = -nDx;
+ nDy = -nDy;
+ nDz = -nDz;
+ }
+ if ( bDel )
+ { //! fuer diesen Mechanismus gilt:
+ //! es gibt nur ganze, einfache geloeschte Spalten/Zeilen
+ ScChangeActionDel* pActDel = (ScChangeActionDel*) pAct;
+ if ( !bUndo )
+ { // Delete
+ ScChangeActionType eInsType = SC_CAT_NONE; // for Insert-Undo-"Deletes"
+ switch ( eActType )
+ {
+ case SC_CAT_DELETE_COLS :
+ eInsType = SC_CAT_INSERT_COLS;
+ break;
+ case SC_CAT_DELETE_ROWS :
+ eInsType = SC_CAT_INSERT_ROWS;
+ break;
+ case SC_CAT_DELETE_TABS :
+ eInsType = SC_CAT_INSERT_TABS;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ BOOL bUpdate = TRUE;
+ if ( GetMergeState() == SC_CTMS_OTHER &&
+ p->GetActionNumber() <= GetLastMerge() )
+ { // Delete in mergendem Dokument, Action im zu mergenden
+ if ( p->IsInsertType() )
+ {
+ // Bei Insert Referenzen nur anpassen, wenn das Delete
+ // das Insert nicht schneidet.
+ if ( !aDelRange.Intersects( p->GetBigRange() ) )
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ bUpdate = FALSE;
+ }
+ else if ( p->GetType() == SC_CAT_CONTENT &&
+ p->IsDeletedInDelType( eInsType ) )
+ { // Content in Insert-Undo-"Delete"
+ // Nicht anpassen, wenn dieses Delete in dem
+ // Insert-"Delete" sein wuerde (ist nur verschoben).
+ if ( aDelRange.In( p->GetBigRange().aStart ) )
+ bUpdate = FALSE;
+ else
+ {
+ const ScChangeActionLinkEntry* pLink = p->GetDeletedIn();
+ while ( pLink && bUpdate )
+ {
+ const ScChangeAction* pDel = pLink->GetAction();
+ if ( pDel && pDel->GetType() == eInsType &&
+ pDel->GetBigRange().In( aDelRange ) )
+ bUpdate = FALSE;
+ pLink = pLink->GetNext();
+ }
+ }
+ }
+ if ( !bUpdate )
+ continue; // for
+ }
+ if ( aDelRange.In( p->GetBigRange() ) )
+ {
+ // Innerhalb eines gerade geloeschten Bereiches nicht
+ // anpassen, stattdessen dem Bereich zuordnen.
+ // Mehrfache geloeschte Bereiche "stapeln".
+ // Kreuzende Deletes setzen mehrfach geloescht.
+ if ( !p->IsDeletedInDelType( eActType ) )
+ {
+ p->SetDeletedIn( pActDel );
+ // GeneratedDelContent in zu loeschende Liste aufnehmen
+ if ( bGeneratedDelContents )
+ pActDel->AddContent( (ScChangeActionContent*) p );
+ }
+ bUpdate = FALSE;
+ }
+ else
+ {
+ // Eingefuegte Bereiche abschneiden, wenn Start/End im
+ // Delete liegt, aber das Insert nicht komplett innerhalb
+ // des Delete liegt bzw. das Delete nicht komplett im
+ // Insert. Das Delete merkt sich, welchem Insert es was
+ // abgeschnitten hat, es kann auch nur ein einziges Insert
+ // sein (weil Delete einspaltig/einzeilig ist).
+ // Abgeschnittene Moves kann es viele geben.
+ //! Ein Delete ist immer einspaltig/einzeilig, deswegen 1
+ //! ohne die Ueberlappung auszurechnen.
+ switch ( p->GetType() )
+ {
+ case SC_CAT_INSERT_COLS :
+ if ( eActType == SC_CAT_DELETE_COLS )
+ {
+ if ( aDelRange.In( p->GetBigRange().aStart ) )
+ {
+ pActDel->SetCutOffInsert(
+ (ScChangeActionIns*) p, 1 );
+ p->GetBigRange().aStart.IncCol( 1 );
+ }
+ else if ( aDelRange.In( p->GetBigRange().aEnd ) )
+ {
+ pActDel->SetCutOffInsert(
+ (ScChangeActionIns*) p, -1 );
+ p->GetBigRange().aEnd.IncCol( -1 );
+ }
+ }
+ break;
+ case SC_CAT_INSERT_ROWS :
+ if ( eActType == SC_CAT_DELETE_ROWS )
+ {
+ if ( aDelRange.In( p->GetBigRange().aStart ) )
+ {
+ pActDel->SetCutOffInsert(
+ (ScChangeActionIns*) p, 1 );
+ p->GetBigRange().aStart.IncRow( 1 );
+ }
+ else if ( aDelRange.In( p->GetBigRange().aEnd ) )
+ {
+ pActDel->SetCutOffInsert(
+ (ScChangeActionIns*) p, -1 );
+ p->GetBigRange().aEnd.IncRow( -1 );
+ }
+ }
+ break;
+ case SC_CAT_INSERT_TABS :
+ if ( eActType == SC_CAT_DELETE_TABS )
+ {
+ if ( aDelRange.In( p->GetBigRange().aStart ) )
+ {
+ pActDel->SetCutOffInsert(
+ (ScChangeActionIns*) p, 1 );
+ p->GetBigRange().aStart.IncTab( 1 );
+ }
+ else if ( aDelRange.In( p->GetBigRange().aEnd ) )
+ {
+ pActDel->SetCutOffInsert(
+ (ScChangeActionIns*) p, -1 );
+ p->GetBigRange().aEnd.IncTab( -1 );
+ }
+ }
+ break;
+ case SC_CAT_MOVE :
+ {
+ ScChangeActionMove* pMove = (ScChangeActionMove*) p;
+ short nFrom = 0;
+ short nTo = 0;
+ if ( aDelRange.In( pMove->GetBigRange().aStart ) )
+ nTo = 1;
+ else if ( aDelRange.In( pMove->GetBigRange().aEnd ) )
+ nTo = -1;
+ if ( aDelRange.In( pMove->GetFromRange().aStart ) )
+ nFrom = 1;
+ else if ( aDelRange.In( pMove->GetFromRange().aEnd ) )
+ nFrom = -1;
+ if ( nFrom )
+ {
+ switch ( eActType )
+ {
+ case SC_CAT_DELETE_COLS :
+ if ( nFrom > 0 )
+ pMove->GetFromRange().aStart.IncCol( nFrom );
+ else
+ pMove->GetFromRange().aEnd.IncCol( nFrom );
+ break;
+ case SC_CAT_DELETE_ROWS :
+ if ( nFrom > 0 )
+ pMove->GetFromRange().aStart.IncRow( nFrom );
+ else
+ pMove->GetFromRange().aEnd.IncRow( nFrom );
+ break;
+ case SC_CAT_DELETE_TABS :
+ if ( nFrom > 0 )
+ pMove->GetFromRange().aStart.IncTab( nFrom );
+ else
+ pMove->GetFromRange().aEnd.IncTab( nFrom );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ if ( nTo )
+ {
+ switch ( eActType )
+ {
+ case SC_CAT_DELETE_COLS :
+ if ( nTo > 0 )
+ pMove->GetBigRange().aStart.IncCol( nTo );
+ else
+ pMove->GetBigRange().aEnd.IncCol( nTo );
+ break;
+ case SC_CAT_DELETE_ROWS :
+ if ( nTo > 0 )
+ pMove->GetBigRange().aStart.IncRow( nTo );
+ else
+ pMove->GetBigRange().aEnd.IncRow( nTo );
+ break;
+ case SC_CAT_DELETE_TABS :
+ if ( nTo > 0 )
+ pMove->GetBigRange().aStart.IncTab( nTo );
+ else
+ pMove->GetBigRange().aEnd.IncTab( nTo );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ if ( nFrom || nTo )
+ {
+ ScChangeActionDelMoveEntry* pLink =
+ pActDel->AddCutOffMove( pMove, nFrom, nTo );
+ pMove->AddLink( pActDel, pLink );
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ if ( bUpdate )
+ {
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ if ( p->GetType() == eActType && !p->IsRejected() &&
+ !pActDel->IsDeletedIn() &&
+ p->GetBigRange().In( aDelRange ) )
+ pActDel->SetDeletedIn( p ); // "druntergerutscht"
+ }
+ }
+ }
+ else
+ { // Undo Delete
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ BOOL bUpdate = TRUE;
+ if ( aDelRange.In( p->GetBigRange() ) )
+ {
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( GetMergeState() == SC_CTMS_UNDO && !p->IsDeletedIn( pAct ) && pAct->IsDeleteType() &&
+ ( p->GetType() == SC_CAT_CONTENT ||
+ p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
+ p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) )
+ {
+ p->SetDeletedIn( pAct );
+ }
+
+ if ( p->IsDeletedInDelType( eActType ) )
+ {
+ if ( p->IsDeletedIn( pActDel ) )
+ {
+ if ( p->GetType() != SC_CAT_CONTENT ||
+ ((ScChangeActionContent*)p)->IsTopContent() )
+ { // erst der TopContent wird wirklich entfernt
+ p->RemoveDeletedIn( pActDel );
+ // GeneratedDelContent _nicht_ aus Liste loeschen,
+ // wir brauchen ihn evtl. noch fuer Reject,
+ // geloescht wird in DeleteCellEntries
+ }
+ }
+ bUpdate = FALSE;
+ }
+ else if ( eActType != SC_CAT_DELETE_TABS &&
+ p->IsDeletedInDelType( SC_CAT_DELETE_TABS ) )
+ { // in geloeschten Tabellen nicht updaten,
+ // ausser wenn Tabelle verschoben wird
+ bUpdate = FALSE;
+ }
+ if ( p->GetType() == eActType && pActDel->IsDeletedIn( p ) )
+ {
+ pActDel->RemoveDeletedIn( p ); // "druntergerutscht"
+ bUpdate = TRUE;
+ }
+ }
+ if ( bUpdate )
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ }
+ if ( !bGeneratedDelContents )
+ { // die werden sonst noch fuer das echte Undo gebraucht
+ pActDel->UndoCutOffInsert();
+ pActDel->UndoCutOffMoves();
+ }
+ }
+ }
+ else if ( eActType == SC_CAT_MOVE )
+ {
+ ScChangeActionMove* pActMove = (ScChangeActionMove*) pAct;
+ BOOL bLastCutMove = ( pActMove == pLastCutMove );
+ const ScBigRange& rTo = pActMove->GetBigRange();
+ const ScBigRange& rFrom = pActMove->GetFromRange();
+ if ( !bUndo )
+ { // Move
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ if ( p->GetType() == SC_CAT_CONTENT )
+ {
+ // Inhalt in Ziel deleten (Inhalt in Quelle moven)
+ if ( rTo.In( p->GetBigRange() ) )
+ {
+ if ( !p->IsDeletedIn( pActMove ) )
+ {
+ p->SetDeletedIn( pActMove );
+ // GeneratedDelContent in zu loeschende Liste aufnehmen
+ if ( bGeneratedDelContents )
+ pActMove->AddContent( (ScChangeActionContent*) p );
+ }
+ }
+ else if ( bLastCutMove &&
+ p->GetActionNumber() > nEndLastCut &&
+ rFrom.In( p->GetBigRange() ) )
+ { // Paste Cut: neuer Content nach Cut eingefuegt, bleibt.
+ // Aufsplitten der ContentChain
+ ScChangeActionContent *pHere, *pTmp;
+ pHere = (ScChangeActionContent*) p;
+ while ( (pTmp = pHere->GetPrevContent()) != NULL &&
+ pTmp->GetActionNumber() > nEndLastCut )
+ pHere = pTmp;
+ if ( pTmp )
+ { // wird TopContent des Move
+ pTmp->SetNextContent( NULL );
+ pHere->SetPrevContent( NULL );
+ }
+ do
+ { // Abhaengigkeit vom FromRange herstellen
+ AddDependentWithNotify( pActMove, pHere );
+ } while ( ( pHere = pHere->GetNextContent() ) != NULL );
+ }
+ // #i87003# [Collaboration] Move range and insert content in FromRange is not merged correctly
+ else if ( ( GetMergeState() != SC_CTMS_PREPARE && GetMergeState() != SC_CTMS_OWN ) || p->GetActionNumber() <= pAct->GetActionNumber() )
+ p->UpdateReference( this, eMode, rFrom, nDx, nDy, nDz );
+ }
+ }
+ }
+ else
+ { // Undo Move
+ BOOL bActRejected = pActMove->IsRejected();
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ if ( p->GetType() == SC_CAT_CONTENT )
+ {
+ // Inhalt in Ziel moven, wenn nicht deleted, sonst undelete
+ if ( p->IsDeletedIn( pActMove ) )
+ {
+ if ( ((ScChangeActionContent*)p)->IsTopContent() )
+ { // erst der TopContent wird wirklich entfernt
+ p->RemoveDeletedIn( pActMove );
+ // GeneratedDelContent _nicht_ aus Liste loeschen,
+ // wir brauchen ihn evtl. noch fuer Reject,
+ // geloescht wird in DeleteCellEntries
+ }
+ }
+ // #i87003# [Collaboration] Move range and insert content in FromRange is not merged correctly
+ else if ( ( GetMergeState() != SC_CTMS_PREPARE && GetMergeState() != SC_CTMS_OWN ) || p->GetActionNumber() <= pAct->GetActionNumber() )
+ p->UpdateReference( this, eMode, rTo, nDx, nDy, nDz );
+ if ( bActRejected &&
+ ((ScChangeActionContent*)p)->IsTopContent() &&
+ rFrom.In( p->GetBigRange() ) )
+ { // Abhaengigkeit herstellen, um Content zu schreiben
+ ScChangeActionLinkEntry* pLink =
+ pActMove->AddDependent( p );
+ p->AddLink( pActMove, pLink );
+ }
+ }
+ }
+ }
+ }
+ else
+ { // Insert / Undo Insert
+ switch ( GetMergeState() )
+ {
+ case SC_CTMS_NONE :
+ case SC_CTMS_OTHER :
+ {
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ }
+ }
+ break;
+ case SC_CTMS_PREPARE :
+ {
+ // in Insert-Undo "Deleten"
+ const ScChangeActionLinkEntry* pLink = pAct->GetFirstDependentEntry();
+ while ( pLink )
+ {
+ ScChangeAction* p = (ScChangeAction*) pLink->GetAction();
+ if ( p )
+ p->SetDeletedIn( pAct );
+ pLink = pLink->GetNext();
+ }
+
+ // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( !p->IsDeletedIn( pAct ) && pAct->IsInsertType() &&
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ ( p->GetType() == SC_CAT_CONTENT ||
+ p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
+ p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) &&
+ pAct->GetBigRange().Intersects( p->GetBigRange() ) )
+ {
+ p->SetDeletedIn( pAct );
+ }
+ }
+
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ if ( !p->IsDeletedIn( pAct )
+ // #i95212# [Collaboration] Bad handling of row insertion in shared spreadsheet
+ && p->GetActionNumber() <= pAct->GetActionNumber() )
+ {
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ }
+ }
+ }
+ break;
+ case SC_CTMS_OWN :
+ {
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ continue; // for
+ if ( !p->IsDeletedIn( pAct )
+ // #i95212# [Collaboration] Bad handling of row insertion in shared spreadsheet
+ && p->GetActionNumber() <= pAct->GetActionNumber() )
+ {
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ }
+ }
+ // in Insert-Undo "Delete" rueckgaengig
+ const ScChangeActionLinkEntry* pLink = pAct->GetFirstDependentEntry();
+ while ( pLink )
+ {
+ ScChangeAction* p = (ScChangeAction*) pLink->GetAction();
+ if ( p )
+ p->RemoveDeletedIn( pAct );
+ pLink = pLink->GetNext();
+ }
+
+ // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p->IsDeletedIn( pAct ) && pAct->IsInsertType() &&
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ ( p->GetType() == SC_CAT_CONTENT ||
+ p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
+ p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) &&
+ pAct->GetBigRange().Intersects( p->GetBigRange() ) )
+ {
+ p->RemoveDeletedIn( pAct );
+ }
+ }
+ }
+ break;
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ case SC_CTMS_UNDO :
+ {
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( !p->IsDeletedIn( pAct ) && pAct->IsInsertType() &&
+ ( p->GetType() == SC_CAT_CONTENT ||
+ p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
+ p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) &&
+ pAct->GetBigRange().Intersects( p->GetBigRange() ) )
+ {
+ p->SetDeletedIn( pAct );
+ }
+ }
+
+ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
+ {
+ if ( p == pAct )
+ {
+ continue;
+ }
+ if ( !p->IsDeletedIn( pAct ) && p->GetActionNumber() <= pAct->GetActionNumber() )
+ {
+ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+void ScChangeTrack::GetDependents( ScChangeAction* pAct,
+ ScChangeActionTable& rTable, BOOL bListMasterDelete, BOOL bAllFlat ) const
+{
+ //! bAllFlat==TRUE: intern aus Accept oder Reject gerufen,
+ //! => Generated werden nicht aufgenommen
+
+ BOOL bIsDelete = pAct->IsDeleteType();
+ BOOL bIsMasterDelete = ( bListMasterDelete && pAct->IsMasterDelete() );
+
+ const ScChangeAction* pCur = pAct;
+ ScChangeActionStack* pStack = new ScChangeActionStack;
+ do
+ {
+ if ( pCur->IsInsertType() )
+ {
+ const ScChangeActionLinkEntry* pL = pCur->GetFirstDependentEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p != pAct )
+ {
+ if ( bAllFlat )
+ {
+ ULONG n = p->GetActionNumber();
+ if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
+ if ( p->HasDependent() )
+ pStack->Push( p );
+ }
+ else
+ {
+ if ( p->GetType() == SC_CAT_CONTENT )
+ {
+ if ( ((ScChangeActionContent*)p)->IsTopContent() )
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ else
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ }
+ pL = pL->GetNext();
+ }
+ }
+ else if ( pCur->IsDeleteType() )
+ {
+ if ( bIsDelete )
+ { // Inhalte geloeschter Bereiche interessieren nur bei Delete
+ ScChangeActionDel* pDel = (ScChangeActionDel*) pCur;
+ if ( !bAllFlat && bIsMasterDelete && pCur == pAct )
+ {
+ // zu diesem Delete gehoerende Deletes in gleiche Ebene,
+ // wenn dieses Delete das momentan oberste einer Reihe ist,
+ ScChangeActionType eType = pDel->GetType();
+ ScChangeAction* p = pDel;
+ while ( (p = p->GetPrev()) != NULL && p->GetType() == eType &&
+ !((ScChangeActionDel*)p)->IsTopDelete() )
+ rTable.Insert( p->GetActionNumber(), p );
+ // dieses Delete auch in Table!
+ rTable.Insert( pAct->GetActionNumber(), pAct );
+ }
+ else
+ {
+ const ScChangeActionLinkEntry* pL = pCur->GetFirstDeletedEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p != pAct )
+ {
+ if ( bAllFlat )
+ {
+ // nur ein TopContent einer Kette ist in LinkDeleted
+ ULONG n = p->GetActionNumber();
+ if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
+ if ( p->HasDeleted() ||
+ p->GetType() == SC_CAT_CONTENT )
+ pStack->Push( p );
+ }
+ else
+ {
+ if ( p->IsDeleteType() )
+ { // weiteres TopDelete in gleiche Ebene,
+ // es ist nicht rejectable
+ if ( ((ScChangeActionDel*)p)->IsTopDelete() )
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ else
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ }
+ pL = pL->GetNext();
+ }
+ }
+ }
+ }
+ else if ( pCur->GetType() == SC_CAT_MOVE )
+ {
+ // geloeschte Contents im ToRange
+ const ScChangeActionLinkEntry* pL = pCur->GetFirstDeletedEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p != pAct && rTable.Insert( p->GetActionNumber(), p ) )
+ {
+ // nur ein TopContent einer Kette ist in LinkDeleted
+ if ( bAllFlat && (p->HasDeleted() ||
+ p->GetType() == SC_CAT_CONTENT) )
+ pStack->Push( p );
+ }
+ pL = pL->GetNext();
+ }
+ // neue Contents im FromRange oder neuer FromRange im ToRange
+ // oder Inserts/Deletes in FromRange/ToRange
+ pL = pCur->GetFirstDependentEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p != pAct )
+ {
+ if ( bAllFlat )
+ {
+ ULONG n = p->GetActionNumber();
+ if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
+ if ( p->HasDependent() || p->HasDeleted() )
+ pStack->Push( p );
+ }
+ else
+ {
+ if ( p->GetType() == SC_CAT_CONTENT )
+ {
+ if ( ((ScChangeActionContent*)p)->IsTopContent() )
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ else
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ }
+ pL = pL->GetNext();
+ }
+ }
+ else if ( pCur->GetType() == SC_CAT_CONTENT )
+ { // alle Aenderungen an gleicher Position
+ ScChangeActionContent* pContent = (ScChangeActionContent*) pCur;
+ // alle vorherigen
+ while ( ( pContent = pContent->GetPrevContent() ) != NULL )
+ {
+ if ( !pContent->IsRejected() )
+ rTable.Insert( pContent->GetActionNumber(), pContent );
+ }
+ pContent = (ScChangeActionContent*) pCur;
+ // alle nachfolgenden
+ while ( ( pContent = pContent->GetNextContent() ) != NULL )
+ {
+ if ( !pContent->IsRejected() )
+ rTable.Insert( pContent->GetActionNumber(), pContent );
+ }
+ // all MatrixReferences of a MatrixOrigin
+ const ScChangeActionLinkEntry* pL = pCur->GetFirstDependentEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p != pAct )
+ {
+ if ( bAllFlat )
+ {
+ ULONG n = p->GetActionNumber();
+ if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
+ if ( p->HasDependent() )
+ pStack->Push( p );
+ }
+ else
+ rTable.Insert( p->GetActionNumber(), p );
+ }
+ pL = pL->GetNext();
+ }
+ }
+ else if ( pCur->GetType() == SC_CAT_REJECT )
+ {
+ if ( bAllFlat )
+ {
+ ScChangeAction* p = GetAction(
+ ((ScChangeActionReject*)pCur)->GetRejectAction() );
+ if ( p != pAct && !rTable.Get( p->GetActionNumber() ) )
+ pStack->Push( p );
+ }
+ }
+ } while ( ( pCur = pStack->Pop() ) != NULL );
+ delete pStack;
+}
+
+
+BOOL ScChangeTrack::SelectContent( ScChangeAction* pAct, BOOL bOldest )
+{
+ if ( pAct->GetType() != SC_CAT_CONTENT )
+ return FALSE;
+
+ ScChangeActionContent* pContent = (ScChangeActionContent*) pAct;
+ if ( bOldest )
+ {
+ pContent = pContent->GetTopContent();
+ ScChangeActionContent* pPrevContent;
+ while ( (pPrevContent = pContent->GetPrevContent()) != NULL &&
+ pPrevContent->IsVirgin() )
+ pContent = pPrevContent;
+ }
+
+ if ( !pContent->IsClickable() )
+ return FALSE;
+
+ ScBigRange aBigRange( pContent->GetBigRange() );
+ const ScBaseCell* pCell = (bOldest ? pContent->GetOldCell() :
+ pContent->GetNewCell());
+ if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATORG )
+ {
+ SCCOL nC;
+ SCROW nR;
+ ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR );
+ aBigRange.aEnd.IncCol( nC-1 );
+ aBigRange.aEnd.IncRow( nR-1 );
+ }
+
+ if ( !aBigRange.IsValid( pDoc ) )
+ return FALSE;
+
+ ScRange aRange( aBigRange.MakeRange() );
+ if ( !pDoc->IsBlockEditable( aRange.aStart.Tab(), aRange.aStart.Col(),
+ aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() ) )
+ return FALSE;
+
+ if ( pContent->HasDependent() )
+ {
+ BOOL bOk = TRUE;
+ Stack aRejectActions;
+ const ScChangeActionLinkEntry* pL = pContent->GetFirstDependentEntry();
+ while ( pL )
+ {
+ ScChangeAction* p = (ScChangeAction*) pL->GetAction();
+ if ( p != pContent )
+ {
+ if ( p->GetType() == SC_CAT_CONTENT )
+ {
+ // we don't need no recursion here, do we?
+ bOk &= ((ScChangeActionContent*)p)->Select( pDoc, this,
+ bOldest, &aRejectActions );
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScChangeTrack::SelectContent: content dependent no content" );
+ }
+ }
+ pL = pL->GetNext();
+ }
+
+ bOk &= pContent->Select( pDoc, this, bOldest, NULL );
+ // now the matrix is inserted and new content values are ready
+
+ ScChangeActionContent* pNew;
+ while ( ( pNew = (ScChangeActionContent*) aRejectActions.Pop() ) != NULL )
+ {
+ ScAddress aPos( pNew->GetBigRange().aStart.MakeAddress() );
+ pNew->SetNewValue( pDoc->GetCell( aPos ), pDoc );
+ Append( pNew );
+ }
+ return bOk;
+ }
+ else
+ return pContent->Select( pDoc, this, bOldest, NULL );
+}
+
+
+void ScChangeTrack::AcceptAll()
+{
+ for ( ScChangeAction* p = GetFirst(); p; p = p->GetNext() )
+ {
+ p->Accept();
+ }
+}
+
+
+BOOL ScChangeTrack::Accept( ScChangeAction* pAct )
+{
+ if ( !pAct->IsClickable() )
+ return FALSE;
+
+ if ( pAct->IsDeleteType() || pAct->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionTable aActionTable;
+ GetDependents( pAct, aActionTable, FALSE, TRUE );
+ for ( ScChangeAction* p = aActionTable.First(); p; p = aActionTable.Next() )
+ {
+ p->Accept();
+ }
+ }
+ pAct->Accept();
+ return TRUE;
+}
+
+
+BOOL ScChangeTrack::RejectAll()
+{
+ BOOL bOk = TRUE;
+ for ( ScChangeAction* p = GetLast(); p && bOk; p = p->GetPrev() )
+ { //! rueckwaerts, weil abhaengige hinten und RejectActions angehaengt
+ if ( p->IsInternalRejectable() )
+ bOk = Reject( p );
+ }
+ return bOk;
+}
+
+
+BOOL ScChangeTrack::Reject( ScChangeAction* pAct, bool bShared )
+{
+ // #i100895# When collaboration changes are reversed, it must be possible
+ // to reject a deleted row above another deleted row.
+ if ( bShared && pAct->IsDeletedIn() )
+ pAct->RemoveAllDeletedIn();
+
+ if ( !pAct->IsRejectable() )
+ return FALSE;
+
+ ScChangeActionTable* pTable = NULL;
+ if ( pAct->HasDependent() )
+ {
+ pTable = new ScChangeActionTable;
+ GetDependents( pAct, *pTable, FALSE, TRUE );
+ }
+ BOOL bRejected = Reject( pAct, pTable, FALSE );
+ if ( pTable )
+ delete pTable;
+ return bRejected;
+}
+
+
+BOOL ScChangeTrack::Reject( ScChangeAction* pAct, ScChangeActionTable* pTable,
+ BOOL bRecursion )
+{
+ if ( !pAct->IsInternalRejectable() )
+ return FALSE;
+
+ BOOL bOk = TRUE;
+ BOOL bRejected = FALSE;
+ if ( pAct->IsInsertType() )
+ {
+ if ( pAct->HasDependent() && !bRecursion )
+ {
+ DBG_ASSERT( pTable, "ScChangeTrack::Reject: Insert ohne Table" );
+ for ( ScChangeAction* p = pTable->Last(); p && bOk; p = pTable->Prev() )
+ {
+ // keine Contents restoren, die eh geloescht werden wuerden
+ if ( p->GetType() == SC_CAT_CONTENT )
+ p->SetRejected();
+ else if ( p->IsDeleteType() )
+ p->Accept(); // geloeschtes ins Nirvana
+ else
+ bOk = Reject( p, NULL, TRUE ); //! rekursiv
+ }
+ }
+ if ( bOk && (bRejected = pAct->Reject( pDoc )) != FALSE )
+ {
+ // pRefDoc NULL := geloeschte Zellen nicht speichern
+ AppendDeleteRange( pAct->GetBigRange().MakeRange(), NULL, (short) 0,
+ pAct->GetActionNumber() );
+ }
+ }
+ else if ( pAct->IsDeleteType() )
+ {
+ DBG_ASSERT( !pTable, "ScChangeTrack::Reject: Delete mit Table" );
+ ScBigRange aDelRange;
+ ULONG nRejectAction = pAct->GetActionNumber();
+ BOOL bTabDel, bTabDelOk;
+ if ( pAct->GetType() == SC_CAT_DELETE_TABS )
+ {
+ bTabDel = TRUE;
+ aDelRange = pAct->GetBigRange();
+ bOk = bTabDelOk = pAct->Reject( pDoc );
+ if ( bOk )
+ {
+ pAct = pAct->GetPrev();
+ bOk = ( pAct && pAct->GetType() == SC_CAT_DELETE_COLS );
+ }
+ }
+ else
+ bTabDel = bTabDelOk = FALSE;
+ ScChangeActionDel* pDel = (ScChangeActionDel*) pAct;
+ if ( bOk )
+ {
+ aDelRange = pDel->GetOverAllRange();
+ bOk = aDelRange.IsValid( pDoc );
+ }
+ BOOL bOneOk = FALSE;
+ if ( bOk )
+ {
+ ScChangeActionType eActType = pAct->GetType();
+ switch ( eActType )
+ {
+ case SC_CAT_DELETE_COLS :
+ aDelRange.aStart.SetCol( aDelRange.aEnd.Col() );
+ break;
+ case SC_CAT_DELETE_ROWS :
+ aDelRange.aStart.SetRow( aDelRange.aEnd.Row() );
+ break;
+ case SC_CAT_DELETE_TABS :
+ aDelRange.aStart.SetTab( aDelRange.aEnd.Tab() );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScChangeAction* p = pAct;
+ BOOL bLoop = TRUE;
+ do
+ {
+ pDel = (ScChangeActionDel*) p;
+ bOk = pDel->Reject( pDoc );
+ if ( bOk )
+ {
+ if ( bOneOk )
+ {
+ switch ( pDel->GetType() )
+ {
+ case SC_CAT_DELETE_COLS :
+ aDelRange.aStart.IncCol( -1 );
+ break;
+ case SC_CAT_DELETE_ROWS :
+ aDelRange.aStart.IncRow( -1 );
+ break;
+ case SC_CAT_DELETE_TABS :
+ aDelRange.aStart.IncTab( -1 );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ bOneOk = TRUE;
+ }
+ if ( pDel->IsBaseDelete() )
+ bLoop = FALSE;
+ else
+ p = p->GetPrev();
+ } while ( bOk && bLoop && p && p->GetType() == eActType &&
+ !((ScChangeActionDel*)p)->IsTopDelete() );
+ }
+ bRejected = bOk;
+ if ( bOneOk || (bTabDel && bTabDelOk) )
+ {
+ // Delete-Reject machte UpdateReference Undo
+ ScChangeActionIns* pReject = new ScChangeActionIns(
+ aDelRange.MakeRange() );
+ pReject->SetRejectAction( nRejectAction );
+ pReject->SetState( SC_CAS_ACCEPTED );
+ Append( pReject );
+ }
+ }
+ else if ( pAct->GetType() == SC_CAT_MOVE )
+ {
+ if ( pAct->HasDependent() && !bRecursion )
+ {
+ DBG_ASSERT( pTable, "ScChangeTrack::Reject: Move ohne Table" );
+ for ( ScChangeAction* p = pTable->Last(); p && bOk; p = pTable->Prev() )
+ {
+ bOk = Reject( p, NULL, TRUE ); //! rekursiv
+ }
+ }
+ if ( bOk && (bRejected = pAct->Reject( pDoc )) != FALSE )
+ {
+ ScChangeActionMove* pReject = new ScChangeActionMove(
+ pAct->GetBigRange().MakeRange(),
+ ((ScChangeActionMove*)pAct)->GetFromRange().MakeRange(), this );
+ pReject->SetRejectAction( pAct->GetActionNumber() );
+ pReject->SetState( SC_CAS_ACCEPTED );
+ Append( pReject );
+ }
+ }
+ else if ( pAct->GetType() == SC_CAT_CONTENT )
+ {
+ ScRange aRange;
+ ScChangeActionContent* pReject;
+ if ( bRecursion )
+ pReject = NULL;
+ else
+ {
+ aRange = pAct->GetBigRange().aStart.MakeAddress();
+ pReject = new ScChangeActionContent( aRange );
+ pReject->SetOldValue( pDoc->GetCell( aRange.aStart ), pDoc, pDoc );
+ }
+ if ( (bRejected = pAct->Reject( pDoc )) != FALSE && !bRecursion )
+ {
+ pReject->SetNewValue( pDoc->GetCell( aRange.aStart ), pDoc );
+ pReject->SetRejectAction( pAct->GetActionNumber() );
+ pReject->SetState( SC_CAS_ACCEPTED );
+ Append( pReject );
+ }
+ else if ( pReject )
+ delete pReject;
+ }
+ else
+ {
+ DBG_ERROR( "ScChangeTrack::Reject: say what?" );
+ }
+
+ return bRejected;
+}
+
+
+ULONG ScChangeTrack::AddLoadedGenerated(ScBaseCell* pNewCell, const ScBigRange& aBigRange, const String& sNewValue )
+{
+ ScChangeActionContent* pAct = new ScChangeActionContent( --nGeneratedMin, pNewCell, aBigRange, pDoc, sNewValue );
+ if ( pAct )
+ {
+ if ( pFirstGeneratedDelContent )
+ pFirstGeneratedDelContent->pPrev = pAct;
+ pAct->pNext = pFirstGeneratedDelContent;
+ pFirstGeneratedDelContent = pAct;
+ aGeneratedTable.Insert( pAct->GetActionNumber(), pAct );
+ return pAct->GetActionNumber();
+ }
+ return 0;
+}
+
+void ScChangeTrack::AppendCloned( ScChangeAction* pAppend )
+{
+ aTable.Insert( pAppend->GetActionNumber(), pAppend );
+ if ( !pLast )
+ pFirst = pLast = pAppend;
+ else
+ {
+ pLast->pNext = pAppend;
+ pAppend->pPrev = pLast;
+ pLast = pAppend;
+ }
+}
+
+ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const
+{
+ if ( !pDocument )
+ {
+ return NULL;
+ }
+
+ ScChangeTrack* pClonedTrack = new ScChangeTrack( pDocument );
+ pClonedTrack->SetTime100thSeconds( IsTime100thSeconds() );
+
+ // clone generated actions
+ ::std::stack< const ScChangeAction* > aGeneratedStack;
+ const ScChangeAction* pGenerated = GetFirstGenerated();
+ while ( pGenerated )
+ {
+ aGeneratedStack.push( pGenerated );
+ pGenerated = pGenerated->GetNext();
+ }
+ while ( !aGeneratedStack.empty() )
+ {
+ pGenerated = aGeneratedStack.top();
+ aGeneratedStack.pop();
+ const ScChangeActionContent* pContent = dynamic_cast< const ScChangeActionContent* >( pGenerated );
+ DBG_ASSERT( pContent, "ScChangeTrack::Clone: pContent is null!" );
+ const ScBaseCell* pNewCell = pContent->GetNewCell();
+ if ( pNewCell )
+ {
+ ScBaseCell* pClonedNewCell = pNewCell->CloneWithoutNote( *pDocument );
+ String aNewValue;
+ pContent->GetNewString( aNewValue );
+ pClonedTrack->nGeneratedMin = pGenerated->GetActionNumber() + 1;
+ pClonedTrack->AddLoadedGenerated( pClonedNewCell, pGenerated->GetBigRange(), aNewValue );
+ }
+ }
+
+ // clone actions
+ const ScChangeAction* pAction = GetFirst();
+ while ( pAction )
+ {
+ ScChangeAction* pClonedAction = NULL;
+
+ switch ( pAction->GetType() )
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ {
+ pClonedAction = new ScChangeActionIns(
+ pAction->GetActionNumber(),
+ pAction->GetState(),
+ pAction->GetRejectAction(),
+ pAction->GetBigRange(),
+ pAction->GetUser(),
+ pAction->GetDateTimeUTC(),
+ pAction->GetComment(),
+ pAction->GetType() );
+ }
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ const ScChangeActionDel* pDelete = dynamic_cast< const ScChangeActionDel* >( pAction );
+ DBG_ASSERT( pDelete, "ScChangeTrack::Clone: pDelete is null!" );
+
+ SCsCOLROW nD = 0;
+ ScChangeActionType eType = pAction->GetType();
+ if ( eType == SC_CAT_DELETE_COLS )
+ {
+ nD = static_cast< SCsCOLROW >( pDelete->GetDx() );
+ }
+ else if ( eType == SC_CAT_DELETE_ROWS )
+ {
+ nD = static_cast< SCsCOLROW >( pDelete->GetDy() );
+ }
+
+ pClonedAction = new ScChangeActionDel(
+ pAction->GetActionNumber(),
+ pAction->GetState(),
+ pAction->GetRejectAction(),
+ pAction->GetBigRange(),
+ pAction->GetUser(),
+ pAction->GetDateTimeUTC(),
+ pAction->GetComment(),
+ eType,
+ nD,
+ pClonedTrack );
+ }
+ break;
+ case SC_CAT_MOVE:
+ {
+ const ScChangeActionMove* pMove = dynamic_cast< const ScChangeActionMove* >( pAction );
+ DBG_ASSERT( pMove, "ScChangeTrack::Clone: pMove is null!" );
+
+ pClonedAction = new ScChangeActionMove(
+ pAction->GetActionNumber(),
+ pAction->GetState(),
+ pAction->GetRejectAction(),
+ pAction->GetBigRange(),
+ pAction->GetUser(),
+ pAction->GetDateTimeUTC(),
+ pAction->GetComment(),
+ pMove->GetFromRange(),
+ pClonedTrack );
+ }
+ break;
+ case SC_CAT_CONTENT:
+ {
+ const ScChangeActionContent* pContent = dynamic_cast< const ScChangeActionContent* >( pAction );
+ DBG_ASSERT( pContent, "ScChangeTrack::Clone: pContent is null!" );
+ const ScBaseCell* pOldCell = pContent->GetOldCell();
+ ScBaseCell* pClonedOldCell = pOldCell ? pOldCell->CloneWithoutNote( *pDocument ) : 0;
+ String aOldValue;
+ pContent->GetOldString( aOldValue );
+
+ ScChangeActionContent* pClonedContent = new ScChangeActionContent(
+ pAction->GetActionNumber(),
+ pAction->GetState(),
+ pAction->GetRejectAction(),
+ pAction->GetBigRange(),
+ pAction->GetUser(),
+ pAction->GetDateTimeUTC(),
+ pAction->GetComment(),
+ pClonedOldCell,
+ pDocument,
+ aOldValue );
+
+ const ScBaseCell* pNewCell = pContent->GetNewCell();
+ if ( pNewCell )
+ {
+ ScBaseCell* pClonedNewCell = pNewCell->CloneWithoutNote( *pDocument );
+ pClonedContent->SetNewValue( pClonedNewCell, pDocument );
+ }
+
+ pClonedAction = pClonedContent;
+ }
+ break;
+ case SC_CAT_REJECT:
+ {
+ pClonedAction = new ScChangeActionReject(
+ pAction->GetActionNumber(),
+ pAction->GetState(),
+ pAction->GetRejectAction(),
+ pAction->GetBigRange(),
+ pAction->GetUser(),
+ pAction->GetDateTimeUTC(),
+ pAction->GetComment() );
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+
+ if ( pClonedAction )
+ {
+ pClonedTrack->AppendCloned( pClonedAction );
+ }
+
+ pAction = pAction->GetNext();
+ }
+
+ if ( pClonedTrack->GetLast() )
+ {
+ pClonedTrack->SetActionMax( pClonedTrack->GetLast()->GetActionNumber() );
+ }
+
+ // set dependencies for Deleted/DeletedIn
+ pAction = GetFirst();
+ while ( pAction )
+ {
+ if ( pAction->HasDeleted() )
+ {
+ ::std::stack< ULONG > aStack;
+ const ScChangeActionLinkEntry* pL = pAction->GetFirstDeletedEntry();
+ while ( pL )
+ {
+ const ScChangeAction* pDeleted = pL->GetAction();
+ if ( pDeleted )
+ {
+ aStack.push( pDeleted->GetActionNumber() );
+ }
+ pL = pL->GetNext();
+ }
+ ScChangeAction* pClonedAction = pClonedTrack->GetAction( pAction->GetActionNumber() );
+ if ( pClonedAction )
+ {
+ while ( !aStack.empty() )
+ {
+ ScChangeAction* pClonedDeleted = pClonedTrack->GetActionOrGenerated( aStack.top() );
+ aStack.pop();
+ if ( pClonedDeleted )
+ {
+ pClonedDeleted->SetDeletedIn( pClonedAction );
+ }
+ }
+ }
+ }
+ pAction = pAction->GetNext();
+ }
+
+ // set dependencies for Dependent/Any
+ pAction = GetLast();
+ while ( pAction )
+ {
+ if ( pAction->HasDependent() )
+ {
+ ::std::stack< ULONG > aStack;
+ const ScChangeActionLinkEntry* pL = pAction->GetFirstDependentEntry();
+ while ( pL )
+ {
+ const ScChangeAction* pDependent = pL->GetAction();
+ if ( pDependent )
+ {
+ aStack.push( pDependent->GetActionNumber() );
+ }
+ pL = pL->GetNext();
+ }
+ ScChangeAction* pClonedAction = pClonedTrack->GetAction( pAction->GetActionNumber() );
+ if ( pClonedAction )
+ {
+ while ( !aStack.empty() )
+ {
+ ScChangeAction* pClonedDependent = pClonedTrack->GetActionOrGenerated( aStack.top() );
+ aStack.pop();
+ if ( pClonedDependent )
+ {
+ ScChangeActionLinkEntry* pLink = pClonedAction->AddDependent( pClonedDependent );
+ pClonedDependent->AddLink( pClonedAction, pLink );
+ }
+ }
+ }
+ }
+ pAction = pAction->GetPrev();
+ }
+
+ // masterlinks
+ ScChangeAction* pClonedAction = pClonedTrack->GetFirst();
+ while ( pClonedAction )
+ {
+ pClonedTrack->MasterLinks( pClonedAction );
+ pClonedAction = pClonedAction->GetNext();
+ }
+
+ if ( IsProtected() )
+ {
+ pClonedTrack->SetProtection( GetProtection() );
+ }
+
+ if ( pClonedTrack->GetLast() )
+ {
+ pClonedTrack->SetLastSavedActionNumber( pClonedTrack->GetLast()->GetActionNumber() );
+ }
+
+ pDocument->SetChangeTrack( pClonedTrack );
+
+ return pClonedTrack;
+}
+
+void ScChangeTrack::MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct )
+{
+ if ( pAct->IsVirgin() )
+ {
+ if ( pOtherAct->IsAccepted() )
+ {
+ pAct->Accept();
+ if ( pOtherAct->IsRejecting() )
+ {
+ pAct->SetRejectAction( pOtherAct->GetRejectAction() );
+ }
+ }
+ else if ( pOtherAct->IsRejected() )
+ {
+ pAct->SetRejected();
+ }
+ }
+}
+
+#if DEBUG_CHANGETRACK
+String ScChangeTrack::ToString() const
+{
+ String aReturn;
+
+ aReturn += String::CreateFromAscii( "============================================================\n" );
+
+ const ScChangeAction* pGenerated = GetFirstGenerated();
+ while ( pGenerated )
+ {
+ aReturn += pGenerated->ToString( pDoc );
+ aReturn += '\n';
+ pGenerated = pGenerated->GetNext();
+ }
+
+ aReturn += String::CreateFromAscii( "------------------------------------------------------------\n" );
+
+ const ScChangeAction* pAction = GetFirst();
+ while ( pAction )
+ {
+ aReturn += pAction->ToString( pDoc );
+ aReturn += '\n';
+ pAction = pAction->GetNext();
+ }
+ aReturn += String::CreateFromAscii( "============================================================\n" );
+
+ return aReturn;
+}
+#endif // DEBUG_CHANGETRACK
diff --git a/sc/source/core/tool/chgviset.cxx b/sc/source/core/tool/chgviset.cxx
new file mode 100644
index 000000000000..ac587db2bd12
--- /dev/null
+++ b/sc/source/core/tool/chgviset.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <unotools/textsearch.hxx>
+
+#include "chgviset.hxx"
+#include "rechead.hxx"
+#include "chgtrack.hxx"
+
+// -----------------------------------------------------------------------
+ScChangeViewSettings::~ScChangeViewSettings()
+{
+ if(pCommentSearcher!=NULL)
+ delete pCommentSearcher;
+}
+
+ScChangeViewSettings::ScChangeViewSettings( const ScChangeViewSettings& r )
+{
+ SetTheComment(r.aComment);
+
+ aFirstDateTime =r.aFirstDateTime;
+ aLastDateTime =r.aLastDateTime;
+ aAuthorToShow =r.aAuthorToShow;
+ aRangeList =r.aRangeList;
+ eDateMode =r.eDateMode;
+ bShowIt =r.bShowIt;
+ bIsDate =r.bIsDate;
+ bIsAuthor =r.bIsAuthor;
+ bIsComment =r.bIsComment;
+ bIsRange =r.bIsRange;
+ bEveryoneButMe =r.bEveryoneButMe;
+ bShowAccepted =r.bShowAccepted;
+ bShowRejected =r.bShowRejected;
+ mbIsActionRange = r.mbIsActionRange;
+ mnFirstAction = r.mnFirstAction;
+ mnLastAction = r.mnLastAction;
+
+}
+
+ScChangeViewSettings& ScChangeViewSettings::operator=( const ScChangeViewSettings& r )
+{
+ SetTheComment(r.aComment);
+
+ aFirstDateTime =r.aFirstDateTime;
+ aLastDateTime =r.aLastDateTime;
+ aAuthorToShow =r.aAuthorToShow;
+ aRangeList =r.aRangeList;
+ eDateMode =r.eDateMode;
+ bShowIt =r.bShowIt;
+ bIsDate =r.bIsDate;
+ bIsAuthor =r.bIsAuthor;
+ bIsComment =r.bIsComment;
+ bIsRange =r.bIsRange;
+ bEveryoneButMe =r.bEveryoneButMe;
+ bShowAccepted =r.bShowAccepted;
+ bShowRejected =r.bShowRejected;
+ mbIsActionRange = r.mbIsActionRange;
+ mnFirstAction = r.mnFirstAction;
+ mnLastAction = r.mnLastAction;
+
+ return *this;
+}
+
+BOOL ScChangeViewSettings::IsValidComment(const String* pCommentStr) const
+{
+ BOOL nTheFlag=TRUE;
+
+ if(pCommentSearcher!=NULL)
+ {
+ xub_StrLen nStartPos = 0;
+ xub_StrLen nEndPos = pCommentStr->Len();
+
+ nTheFlag=sal::static_int_cast<BOOL>(pCommentSearcher->SearchFrwrd( *pCommentStr, &nStartPos, &nEndPos));
+ }
+ return nTheFlag;
+}
+
+void ScChangeViewSettings::SetTheComment(const String& rString)
+{
+ aComment=rString;
+ if(pCommentSearcher!=NULL)
+ {
+ delete pCommentSearcher;
+ pCommentSearcher=NULL;
+ }
+
+ if(rString.Len()>0)
+ {
+ utl::SearchParam aSearchParam( rString,
+ utl::SearchParam::SRCH_REGEXP,FALSE,FALSE,FALSE );
+
+ pCommentSearcher = new utl::TextSearch( aSearchParam, *ScGlobal::pCharClass );
+ }
+}
+
+void ScChangeViewSettings::AdjustDateMode( const ScDocument& rDoc )
+{
+ switch ( eDateMode )
+ { // corresponds with ScViewUtil::IsActionShown
+ case SCDM_DATE_EQUAL :
+ case SCDM_DATE_NOTEQUAL :
+ aFirstDateTime.SetTime( 0 );
+ aLastDateTime = aFirstDateTime;
+ aLastDateTime.SetTime( 23595999 );
+ break;
+ case SCDM_DATE_SAVE:
+ {
+ const ScChangeAction* pLast = 0;
+ ScChangeTrack* pTrack = rDoc.GetChangeTrack();
+ if ( pTrack )
+ {
+ pLast = pTrack->GetLastSaved();
+ if ( pLast )
+ {
+ aFirstDateTime = pLast->GetDateTime();
+#if 0
+// This would be the proper handling. But since the SvxTPFilter dialog uses
+// DateField/TimeField, and the filter dialog is used in ScAcceptChgDlg as the
+// controlling instance, and the TimeFields are used there without seconds or
+// 100ths, we'd display some extra entries between the floor of the minute and
+// the start of the next minute.
+ // add one 100th second to point past last saved
+ aFirstDateTime += Time( 0, 0, 0, 1 );
+#else
+ // Set the next minute as the start time and assume that
+ // the document isn't saved, reloaded, edited and filter set
+ // all together during the gap between those two times.
+ aFirstDateTime += Time( 0, 1 );
+ aFirstDateTime.SetSec(0);
+ aFirstDateTime.Set100Sec(0);
+#endif
+ }
+ }
+ if ( !pLast )
+ {
+ aFirstDateTime.SetDate( 18990101 );
+ aFirstDateTime.SetTime( 0 );
+ }
+ aLastDateTime = Date();
+ aLastDateTime.SetYear( aLastDateTime.GetYear() + 100 );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
diff --git a/sc/source/core/tool/collect.cxx b/sc/source/core/tool/collect.cxx
new file mode 100644
index 000000000000..c7aa72343fbb
--- /dev/null
+++ b/sc/source/core/tool/collect.cxx
@@ -0,0 +1,522 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <string.h>
+#include <tools/stream.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "rechead.hxx"
+#include "collect.hxx"
+#include "document.hxx" // fuer TypedStrData Konstruktor
+
+// -----------------------------------------------------------------------
+
+ScDataObject::~ScDataObject()
+{
+}
+
+//------------------------------------------------------------------------
+// Collection
+//------------------------------------------------------------------------
+
+void lcl_DeleteScDataObjects( ScDataObject** p, USHORT nCount )
+{
+ if ( p )
+ {
+ for (USHORT i = 0; i < nCount; i++) delete p[i];
+ delete[] p;
+ p = NULL;
+ }
+}
+
+ScCollection::ScCollection(USHORT nLim, USHORT nDel) :
+ nCount ( 0 ),
+ nLimit ( nLim ),
+ nDelta ( nDel ),
+ pItems ( NULL )
+{
+ if (nDelta > MAXDELTA)
+ nDelta = MAXDELTA;
+ else if (nDelta == 0)
+ nDelta = 1;
+ if (nLimit > MAXCOLLECTIONSIZE)
+ nLimit = MAXCOLLECTIONSIZE;
+ else if (nLimit < nDelta)
+ nLimit = nDelta;
+ pItems = new ScDataObject*[nLimit];
+}
+
+ScCollection::ScCollection(const ScCollection& rCollection)
+ : ScDataObject(),
+ nCount ( 0 ),
+ nLimit ( 0 ),
+ nDelta ( 0 ),
+ pItems ( NULL )
+{
+ *this = rCollection;
+}
+
+//------------------------------------------------------------------------
+
+ScCollection::~ScCollection()
+{
+ lcl_DeleteScDataObjects( pItems, nCount );
+}
+
+//------------------------------------------------------------------------
+USHORT ScCollection::GetCount() const { return nCount; }
+void ScCollection::AtFree(USHORT nIndex)
+{
+ if ((pItems) && (nIndex < nCount))
+ {
+ delete pItems[nIndex];
+ --nCount; // before memmove
+ memmove ( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(ScDataObject*));
+ pItems[nCount] = NULL;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScCollection::Free(ScDataObject* pScDataObject)
+{
+ AtFree(IndexOf(pScDataObject));
+}
+
+//------------------------------------------------------------------------
+
+void ScCollection::FreeAll()
+{
+ lcl_DeleteScDataObjects( pItems, nCount );
+ nCount = 0;
+ pItems = new ScDataObject*[nLimit];
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScCollection::AtInsert(USHORT nIndex, ScDataObject* pScDataObject)
+{
+ if ((nCount < MAXCOLLECTIONSIZE) && (nIndex <= nCount) && pItems)
+ {
+ if (nCount == nLimit)
+ {
+ ScDataObject** pNewItems = new ScDataObject*[nLimit + nDelta];
+ if (!pNewItems)
+ return FALSE;
+ nLimit = sal::static_int_cast<USHORT>( nLimit + nDelta );
+ memmove(pNewItems, pItems, nCount * sizeof(ScDataObject*));
+ delete[] pItems;
+ pItems = pNewItems;
+ }
+ if (nCount > nIndex)
+ memmove(&pItems[nIndex + 1], &pItems[nIndex], (nCount - nIndex) * sizeof(ScDataObject*));
+ pItems[nIndex] = pScDataObject;
+ nCount++;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScCollection::Insert(ScDataObject* pScDataObject)
+{
+ return AtInsert(nCount, pScDataObject);
+}
+
+//------------------------------------------------------------------------
+
+ScDataObject* ScCollection::At(USHORT nIndex) const
+{
+ if (nIndex < nCount)
+ return pItems[nIndex];
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScCollection::IndexOf(ScDataObject* pScDataObject) const
+{
+ USHORT nIndex = 0xffff;
+ for (USHORT i = 0; ((i < nCount) && (nIndex == 0xffff)); i++)
+ {
+ if (pItems[i] == pScDataObject) nIndex = i;
+ }
+ return nIndex;
+}
+
+//------------------------------------------------------------------------
+
+ScCollection& ScCollection::operator=( const ScCollection& r )
+{
+ lcl_DeleteScDataObjects( pItems, nCount );
+
+ nCount = r.nCount;
+ nLimit = r.nLimit;
+ nDelta = r.nDelta;
+ pItems = new ScDataObject*[nLimit];
+ for ( USHORT i=0; i<nCount; i++ )
+ pItems[i] = r.pItems[i]->Clone();
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+ScDataObject* ScCollection::Clone() const
+{
+ return new ScCollection(*this);
+}
+
+//------------------------------------------------------------------------
+// ScSortedCollection
+//------------------------------------------------------------------------
+
+ScSortedCollection::ScSortedCollection(USHORT nLim, USHORT nDel, BOOL bDup) :
+ ScCollection (nLim, nDel),
+ bDuplicates ( bDup)
+{
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScSortedCollection::IndexOf(ScDataObject* pScDataObject) const
+{
+ USHORT nIndex;
+ if (Search(pScDataObject, nIndex))
+ return nIndex;
+ else
+ return 0xffff;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSortedCollection::Search(ScDataObject* pScDataObject, USHORT& rIndex) const
+{
+ rIndex = nCount;
+ BOOL bFound = FALSE;
+ short nLo = 0;
+ short nHi = nCount - 1;
+ short nIndex;
+ short nCompare;
+ while (nLo <= nHi)
+ {
+ nIndex = (nLo + nHi) / 2;
+ nCompare = Compare(pItems[nIndex], pScDataObject);
+ if (nCompare < 0)
+ nLo = nIndex + 1;
+ else
+ {
+ nHi = nIndex - 1;
+ if (nCompare == 0)
+ {
+ bFound = TRUE;
+ nLo = nIndex;
+ }
+ }
+ }
+ rIndex = nLo;
+ return bFound;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSortedCollection::Insert(ScDataObject* pScDataObject)
+{
+ USHORT nIndex;
+ BOOL bFound = Search(pScDataObject, nIndex);
+ if (bFound)
+ {
+ if (bDuplicates)
+ return AtInsert(nIndex, pScDataObject);
+ else
+ return FALSE;
+ }
+ else
+ return AtInsert(nIndex, pScDataObject);
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSortedCollection::InsertPos(ScDataObject* pScDataObject, USHORT& nIndex)
+{
+ BOOL bFound = Search(pScDataObject, nIndex);
+ if (bFound)
+ {
+ if (bDuplicates)
+ return AtInsert(nIndex, pScDataObject);
+ else
+ return FALSE;
+ }
+ else
+ return AtInsert(nIndex, pScDataObject);
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScSortedCollection::operator==(const ScSortedCollection& rCmp) const
+{
+ if ( nCount != rCmp.nCount )
+ return FALSE;
+ for (USHORT i=0; i<nCount; i++)
+ if ( !IsEqual(pItems[i],rCmp.pItems[i]) )
+ return FALSE;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+// IsEqual - komplette Inhalte vergleichen
+
+BOOL ScSortedCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return ( Compare(pKey1, pKey2) == 0 ); // Default: nur Index vergleichen
+}
+
+//------------------------------------------------------------------------
+
+ScDataObject* StrData::Clone() const
+{
+ return new StrData(*this);
+}
+
+//------------------------------------------------------------------------
+
+short ScStrCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ StringCompare eComp = ((StrData*)pKey1)->aStr.CompareTo(((StrData*)pKey2)->aStr);
+ if (eComp == COMPARE_EQUAL)
+ return 0;
+ else if (eComp == COMPARE_LESS)
+ return -1;
+ else
+ return 1;
+}
+
+//------------------------------------------------------------------------
+
+ScDataObject* ScStrCollection::Clone() const
+{
+ return new ScStrCollection(*this);
+}
+
+//------------------------------------------------------------------------
+// TypedScStrCollection
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 TypedStrData::TypedStrData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+//UNUSED2008-05 BOOL bAllStrings )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( pDoc->HasValueData( nCol, nRow, nTab ) )
+//UNUSED2008-05 {
+//UNUSED2008-05 pDoc->GetValue( nCol, nRow, nTab, nValue );
+//UNUSED2008-05 if (bAllStrings)
+//UNUSED2008-05 pDoc->GetString( nCol, nRow, nTab, aStrValue );
+//UNUSED2008-05 nStrType = 0;
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 pDoc->GetString( nCol, nRow, nTab, aStrValue );
+//UNUSED2008-05 nValue = 0.0;
+//UNUSED2008-05 nStrType = 1; //! Typ uebergeben ?
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+
+ScDataObject* TypedStrData::Clone() const
+{
+ return new TypedStrData(*this);
+}
+
+TypedScStrCollection::TypedScStrCollection( USHORT nLim , USHORT nDel , BOOL bDup )
+ : ScSortedCollection( nLim, nDel, bDup )
+{
+ bCaseSensitive = FALSE;
+}
+
+TypedScStrCollection::~TypedScStrCollection()
+{}
+ScDataObject* TypedScStrCollection::Clone() const
+{
+ return new TypedScStrCollection(*this);
+}
+
+TypedStrData* TypedScStrCollection::operator[]( const USHORT nIndex) const
+{
+ return (TypedStrData*)At(nIndex);
+}
+
+void TypedScStrCollection::SetCaseSensitive( BOOL bSet )
+{
+ bCaseSensitive = bSet;
+}
+
+short TypedScStrCollection::Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const
+{
+ short nResult = 0;
+
+ if ( pKey1 && pKey2 )
+ {
+ TypedStrData& rData1 = (TypedStrData&)*pKey1;
+ TypedStrData& rData2 = (TypedStrData&)*pKey2;
+
+ if ( rData1.nStrType > rData2.nStrType )
+ nResult = 1;
+ else if ( rData1.nStrType < rData2.nStrType )
+ nResult = -1;
+ else if ( !rData1.nStrType /* && !rData2.nStrType */ )
+ {
+ //--------------------
+ // Zahlen vergleichen:
+ //--------------------
+ if ( rData1.nValue == rData2.nValue )
+ nResult = 0;
+ else if ( rData1.nValue < rData2.nValue )
+ nResult = -1;
+ else
+ nResult = 1;
+ }
+ else /* if ( rData1.nStrType && rData2.nStrType ) */
+ {
+ //---------------------
+ // Strings vergleichen:
+ //---------------------
+ if ( bCaseSensitive )
+ nResult = (short) ScGlobal::GetCaseTransliteration()->compareString(
+ rData1.aStrValue, rData2.aStrValue );
+ else
+ nResult = (short) ScGlobal::GetpTransliteration()->compareString(
+ rData1.aStrValue, rData2.aStrValue );
+ }
+ }
+
+ return nResult;
+}
+
+BOOL TypedScStrCollection::FindText( const String& rStart, String& rResult,
+ USHORT& rPos, BOOL bBack ) const
+{
+ // Die Collection ist nach String-Vergleichen sortiert, darum muss hier
+ // alles durchsucht werden
+
+ BOOL bFound = FALSE;
+
+ String aOldResult;
+ if ( rPos != SCPOS_INVALID && rPos < nCount )
+ {
+ TypedStrData* pData = (TypedStrData*) pItems[rPos];
+ if (pData->nStrType)
+ aOldResult = pData->aStrValue;
+ }
+
+ if ( bBack ) // rueckwaerts
+ {
+ USHORT nStartPos = nCount;
+ if ( rPos != SCPOS_INVALID )
+ nStartPos = rPos; // weitersuchen...
+
+ for ( USHORT i=nStartPos; i>0; )
+ {
+ --i;
+ TypedStrData* pData = (TypedStrData*) pItems[i];
+ if (pData->nStrType)
+ {
+ if ( ScGlobal::GetpTransliteration()->isMatch( rStart, pData->aStrValue ) )
+ {
+ // If the collection is case sensitive, it may contain several entries
+ // that are equal when compared case-insensitive. They are skipped here.
+ if ( !bCaseSensitive || !aOldResult.Len() ||
+ !ScGlobal::GetpTransliteration()->isEqual(
+ pData->aStrValue, aOldResult ) )
+ {
+ rResult = pData->aStrValue;
+ rPos = i;
+ bFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else // vorwaerts
+ {
+ USHORT nStartPos = 0;
+ if ( rPos != SCPOS_INVALID )
+ nStartPos = rPos + 1; // weitersuchen...
+
+ for ( USHORT i=nStartPos; i<nCount; i++ )
+ {
+ TypedStrData* pData = (TypedStrData*) pItems[i];
+ if (pData->nStrType)
+ {
+ if ( ScGlobal::GetpTransliteration()->isMatch( rStart, pData->aStrValue ) )
+ {
+ // If the collection is case sensitive, it may contain several entries
+ // that are equal when compared case-insensitive. They are skipped here.
+ if ( !bCaseSensitive || !aOldResult.Len() ||
+ !ScGlobal::GetpTransliteration()->isEqual(
+ pData->aStrValue, aOldResult ) )
+ {
+ rResult = pData->aStrValue;
+ rPos = i;
+ bFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return bFound;
+}
+
+ // Gross-/Kleinschreibung anpassen
+
+BOOL TypedScStrCollection::GetExactMatch( String& rString ) const
+{
+ for (USHORT i=0; i<nCount; i++)
+ {
+ TypedStrData* pData = (TypedStrData*) pItems[i];
+ if ( pData->nStrType && ScGlobal::GetpTransliteration()->isEqual(
+ pData->aStrValue, rString ) )
+ {
+ rString = pData->aStrValue; // String anpassen
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
new file mode 100644
index 000000000000..828c9ae64c7d
--- /dev/null
+++ b/sc/source/core/tool/compiler.cxx
@@ -0,0 +1,5484 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbstar.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/rcid.h>
+#include <tools/rc.hxx>
+#include <tools/solar.h>
+#include <unotools/charclass.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
+#include <com/sun/star/sheet/FormulaLanguage.hpp>
+#include <com/sun/star/sheet/FormulaMapGroup.hpp>
+#include <comphelper/processfactory.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/math.hxx>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "compiler.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "document.hxx"
+#include "callform.hxx"
+#include "addincol.hxx"
+#include "refupdat.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "cell.hxx"
+#include "dociter.hxx"
+#include "docoptio.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;
+using rtl::OUString;
+using ::std::vector;
+
+#if OSL_DEBUG_LEVEL > 1
+// For some unknown reason the identical dbg_dump utilities in
+// tools/source/string/debugprint.cxx tend to crash when called from within
+// gdb. Having them here also comes handy as libtl*.so doesn't have to be
+// replaced.
+const char* dbg_sc_dump( const ByteString & rStr )
+{
+ static ByteString aStr;
+ aStr = rStr;
+ aStr.Append(static_cast<char>(0));
+ return aStr.GetBuffer();
+}
+const char* dbg_sc_dump( const UniString & rStr )
+{
+ return dbg_sc_dump(ByteString(rStr, RTL_TEXTENCODING_UTF8));
+}
+const char* dbg_sc_dump( const sal_Unicode * pBuf )
+{
+ return dbg_sc_dump( UniString( pBuf));
+}
+const char* dbg_sc_dump( const sal_Unicode c )
+{
+ return dbg_sc_dump( UniString( c));
+}
+#endif
+
+CharClass* ScCompiler::pCharClassEnglish = NULL;
+const ScCompiler::Convention* ScCompiler::pConventions[ ] = { NULL, NULL, NULL, NULL, NULL, NULL };
+
+enum ScanState
+{
+ ssGetChar,
+ ssGetBool,
+ ssGetValue,
+ ssGetString,
+ ssSkipString,
+ ssGetIdent,
+ ssGetReference,
+ ssSkipReference,
+ ssStop
+};
+
+static const sal_Char* pInternal[ 1 ] = { "TTT" };
+
+using namespace ::com::sun::star::i18n;
+
+/////////////////////////////////////////////////////////////////////////
+
+
+
+class ScCompilerRecursionGuard
+{
+private:
+ short& rRecursion;
+public:
+ ScCompilerRecursionGuard( short& rRec )
+ : rRecursion( rRec ) { ++rRecursion; }
+ ~ScCompilerRecursionGuard() { --rRecursion; }
+};
+
+
+void ScCompiler::fillFromAddInMap( NonConstOpCodeMapPtr xMap,FormulaGrammar::Grammar _eGrammar ) const
+{
+ size_t nSymbolOffset;
+ switch( _eGrammar )
+ {
+ case FormulaGrammar::GRAM_PODF:
+ nSymbolOffset = offsetof( AddInMap, pUpper);
+ break;
+ default:
+ case FormulaGrammar::GRAM_ODFF:
+ nSymbolOffset = offsetof( AddInMap, pODFF);
+ break;
+ case FormulaGrammar::GRAM_ENGLISH:
+ nSymbolOffset = offsetof( AddInMap, pEnglish);
+ break;
+ }
+ const AddInMap* pMap = GetAddInMap();
+ const AddInMap* const pStop = pMap + GetAddInMapCount();
+ for ( ; pMap < pStop; ++pMap)
+ {
+ char const * const * ppSymbol =
+ reinterpret_cast< char const * const * >(
+ reinterpret_cast< char const * >(pMap) + nSymbolOffset);
+ xMap->putExternal( String::CreateFromAscii( *ppSymbol),
+ String::CreateFromAscii( pMap->pOriginal));
+ }
+}
+
+void ScCompiler::fillFromAddInCollectionUpperName( NonConstOpCodeMapPtr xMap ) const
+{
+ ScUnoAddInCollection* pColl = ScGlobal::GetAddInCollection();
+ long nCount = pColl->GetFuncCount();
+ for (long i=0; i < nCount; ++i)
+ {
+ const ScUnoAddInFuncData* pFuncData = pColl->GetFuncData(i);
+ if (pFuncData)
+ xMap->putExternalSoftly( pFuncData->GetUpperName(),
+ pFuncData->GetOriginalName());
+ }
+}
+
+void ScCompiler::fillFromAddInCollectionEnglishName( NonConstOpCodeMapPtr xMap ) const
+{
+ ScUnoAddInCollection* pColl = ScGlobal::GetAddInCollection();
+ long nCount = pColl->GetFuncCount();
+ for (long i=0; i < nCount; ++i)
+ {
+ const ScUnoAddInFuncData* pFuncData = pColl->GetFuncData(i);
+ if (pFuncData)
+ {
+ String aName;
+ if (pFuncData->GetExcelName( LANGUAGE_ENGLISH_US, aName))
+ xMap->putExternalSoftly( aName, pFuncData->GetOriginalName());
+ else
+ xMap->putExternalSoftly( pFuncData->GetUpperName(),
+ pFuncData->GetOriginalName());
+ }
+ }
+}
+
+
+#ifdef erGENERATEMAPPING
+// Run in en-US UI by calling from within gdb, edit pODFF entries afterwards.
+void dbg_call_generateMappingODFF()
+{
+ // static ScCompiler members
+ fprintf( stdout, "%s", "static struct AddInMap\n{\n const char* pODFF;\n const char* pEnglish;\n bool bMapDupToInternal;\n const char* pOriginal;\n const char* pUpper;\n} maAddInMap[];\n");
+ fprintf( stdout, "%s", "static const AddInMap* GetAddInMap();\n");
+ fprintf( stdout, "%s", "static size_t GetAddInMapCount();\n");
+ fprintf( stdout, "addinfuncdata___:%s", "ScCompiler::AddInMap ScCompiler::maAddInMap[] =\n{\n");
+ ScUnoAddInCollection* pColl = ScGlobal::GetAddInCollection();
+ long nCount = pColl->GetFuncCount();
+ for (long i=0; i < nCount; ++i)
+ {
+ const ScUnoAddInFuncData* pFuncData = pColl->GetFuncData(i);
+ if (pFuncData)
+ {
+#define out(rStr) (ByteString( rStr, RTL_TEXTENCODING_UTF8).GetBuffer())
+ String aL = pFuncData->GetUpperLocal();
+ String aP = pFuncData->GetOriginalName();
+ String aU = pFuncData->GetUpperName();
+ fprintf( stdout, "addinfuncdata%3ld: { \"%s\", \"%s\", false, \"%s\", \"%s\" },\n",
+ i, out(aL), out(aL), out(aP), out(aU));
+#undef out
+ }
+ }
+ fprintf( stdout, "addinfuncdata___:%s", "};\n");
+ fprintf( stdout, "%s", "\n// static\nconst ScCompiler::AddInMap* ScCompiler::GetAddInMap()\n{\n return maAddInMap;\n}\n");
+ fprintf( stdout, "%s", "\n// static\nsize_t ScCompiler::GetAddInMapCount()\n{\n return sizeof(maAddInMap)/sizeof(maAddInMap[0]);\n}\n");
+ fflush( stdout);
+}
+#endif // erGENERATEMAPPING
+
+#ifdef erGENERATEMAPPINGDIFF
+// Run in en-US UI by calling from within gdb.
+void dbg_call_generateMappingDiff()
+{
+ using namespace ::com::sun::star::sheet;
+ ScCompiler::OpCodeMapPtr xPODF = ScCompiler::GetOpCodeMap(
+ FormulaLanguage::ODF_11);
+ ScCompiler::OpCodeMapPtr xODFF = ScCompiler::GetOpCodeMap(
+ FormulaLanguage::ODFF);
+ ScCompiler::OpCodeMapPtr xENUS = ScCompiler::GetOpCodeMap(
+ FormulaLanguage::ENGLISH);
+ USHORT nPODF = xPODF->getSymbolCount();
+ USHORT nODFF = xODFF->getSymbolCount();
+ USHORT nENUS = xENUS->getSymbolCount();
+ printf( "%s\n", "This is a semicolon separated file, you may import it as such to Calc.");
+ printf( "%s\n", "Spreadsheet functions name differences between PODF (ODF < 1.2) and ODFF (ODF >= 1.2), plus English UI names.");
+ printf( "\nInternal OpCodes; PODF: %d; ODFF: %d; ENUS: %d\n",
+ (int)nPODF, (int)nODFF, (int)nENUS);
+ USHORT nMax = ::std::max( ::std::max( nPODF, nODFF), nENUS);
+#define out(rStr) (ByteString( rStr, RTL_TEXTENCODING_UTF8).GetBuffer())
+ for (USHORT i=0; i < nMax; ++i)
+ {
+ const String& rPODF = xPODF->getSymbol(static_cast<OpCode>(i));
+ const String& rODFF = xODFF->getSymbol(static_cast<OpCode>(i));
+ const String& rENUS = xENUS->getSymbol(static_cast<OpCode>(i));
+ if (rPODF != rODFF)
+ printf( "%d;%s;%s;%s\n", (int)i, out(rPODF), out(rODFF), out(rENUS));
+ }
+ // Actually they should all differ, so we could simply list them all, but
+ // this is correct and we would find odd things, if any.
+ const ExternalHashMap* pPODF = xPODF->getReverseExternalHashMap();
+ const ExternalHashMap* pODFF = xODFF->getReverseExternalHashMap();
+ const ExternalHashMap* pENUS = xENUS->getReverseExternalHashMap();
+ printf( "\n%s\n", "Add-In mapping");
+ for (ExternalHashMap::const_iterator it = pPODF->begin(); it != pPODF->end(); ++it)
+ {
+ ExternalHashMap::const_iterator iLookODFF = pODFF->find( (*it).first);
+ ExternalHashMap::const_iterator iLookENUS = pENUS->find( (*it).first);
+ String aNative( iLookENUS == pENUS->end() ?
+ String::CreateFromAscii( "ENGLISH_SYMBOL_NOT_FOUND") :
+ (*iLookENUS).second);
+ if (iLookODFF == pODFF->end())
+ printf( "NOT FOUND;%s;;%s\n", out((*it).first), out(aNative));
+ else if((*it).second == (*iLookODFF).second) // upper equal
+ printf( "EQUAL;%s;%s;%s\n", out((*it).first), out((*iLookODFF).second), out(aNative));
+ else
+ printf( ";%s;%s;%s\n", out((*it).first), out((*iLookODFF).second), out(aNative));
+ }
+#undef out
+ fflush( stdout);
+}
+#endif // erGENERATEMAPPINGDIFF
+
+// static
+void ScCompiler::DeInit()
+{
+ if (pCharClassEnglish)
+ {
+ delete pCharClassEnglish;
+ pCharClassEnglish = NULL;
+ }
+}
+
+bool ScCompiler::IsEnglishSymbol( const String& rName )
+{
+ // function names are always case-insensitive
+ String aUpper( ScGlobal::pCharClass->upper( rName ) );
+
+ // 1. built-in function name
+ OpCode eOp = ScCompiler::GetEnglishOpCode( aUpper );
+ if ( eOp != ocNone )
+ {
+ return true;
+ }
+ // 2. old add in functions
+ USHORT nIndex;
+ if ( ScGlobal::GetFuncCollection()->SearchFunc( aUpper, nIndex ) )
+ {
+ return true;
+ }
+
+ // 3. new (uno) add in functions
+ String aIntName(ScGlobal::GetAddInCollection()->FindFunction( aUpper, FALSE ));
+ if (aIntName.Len())
+ {
+ return true;
+ }
+ return false; // no valid function name
+}
+
+// static
+void ScCompiler::InitCharClassEnglish()
+{
+ ::com::sun::star::lang::Locale aLocale(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "en")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "US")),
+ OUString());
+ pCharClassEnglish = new CharClass(
+ ::comphelper::getProcessServiceFactory(), aLocale);
+}
+
+
+void ScCompiler::SetGrammar( const FormulaGrammar::Grammar eGrammar )
+{
+ DBG_ASSERT( eGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "ScCompiler::SetGrammar: don't pass FormulaGrammar::GRAM_UNSPECIFIED");
+ if (eGrammar == GetGrammar())
+ return; // nothing to be done
+
+ if( eGrammar == FormulaGrammar::GRAM_EXTERNAL )
+ {
+ 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);
+
+ // Override if necessary.
+ if (eMyGrammar != GetGrammar())
+ SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
+ }
+}
+
+void ScCompiler::SetEncodeUrlMode( EncodeUrlMode eMode )
+{
+ meEncodeUrlMode = eMode;
+}
+
+ScCompiler::EncodeUrlMode ScCompiler::GetEncodeUrlMode() const
+{
+ return meEncodeUrlMode;
+}
+
+void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap )
+{
+ if (xMap.get())
+ {
+ mxSymbols = xMap;
+ if (mxSymbols->isEnglish())
+ {
+ if (!pCharClassEnglish)
+ InitCharClassEnglish();
+ pCharClass = pCharClassEnglish;
+ }
+ else
+ pCharClass = ScGlobal::pCharClass;
+ SetGrammarAndRefConvention( mxSymbols->getGrammar(), GetGrammar());
+ }
+}
+
+
+void ScCompiler::SetGrammarAndRefConvention(
+ const FormulaGrammar::Grammar eNewGrammar, const FormulaGrammar::Grammar eOldGrammar )
+{
+ meGrammar = eNewGrammar; //! SetRefConvention needs the new grammar set!
+ FormulaGrammar::AddressConvention eConv = FormulaGrammar::extractRefConvention( meGrammar);
+ if (eConv == FormulaGrammar::CONV_UNSPECIFIED && eOldGrammar == FormulaGrammar::GRAM_UNSPECIFIED)
+ {
+ if (pDoc)
+ SetRefConvention( pDoc->GetAddressConvention());
+ else
+ SetRefConvention( pConvOOO_A1);
+ }
+ else
+ SetRefConvention( eConv );
+}
+
+String ScCompiler::FindAddInFunction( const String& rUpperName, BOOL bLocalFirst ) const
+{
+ return ScGlobal::GetAddInCollection()->FindFunction(rUpperName, bLocalFirst); // bLocalFirst=FALSE for english
+}
+
+
+#ifdef erDEBUG
+void dbg_call_testcreatemapping()
+{
+ using namespace ::com::sun::star::sheet;
+ ScCompiler::OpCodeMapPtr xMap = ScCompiler::GetOpCodeMap( FormulaLanguage::ODFF);
+ xMap->createSequenceOfAvailableMappings( FormulaMapGroup::FUNCTIONS);
+}
+#endif
+
+//-----------------------------------------------------------------------------
+
+ScCompiler::Convention::~Convention()
+{
+ delete [] mpCharTable;
+ mpCharTable = NULL;
+}
+
+ScCompiler::Convention::Convention( FormulaGrammar::AddressConvention eConv )
+ :
+ meConv( eConv )
+{
+ int i;
+ ULONG *t= new ULONG [128];
+
+ ScCompiler::pConventions[ meConv ] = this;
+ mpCharTable = t;
+
+ for (i = 0; i < 128; i++)
+ t[i] = SC_COMPILER_C_ILLEGAL;
+
+/* */ t[32] = SC_COMPILER_C_CHAR_DONTCARE | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* ! */ t[33] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+ if (FormulaGrammar::CONV_ODF == meConv)
+/* ! */ t[33] |= SC_COMPILER_C_ODF_LABEL_OP;
+/* " */ t[34] = SC_COMPILER_C_CHAR_STRING | SC_COMPILER_C_STRING_SEP;
+/* # */ t[35] = SC_COMPILER_C_WORD_SEP;
+/* $ */ t[36] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
+ if (FormulaGrammar::CONV_ODF == meConv)
+/* $ */ t[36] |= SC_COMPILER_C_ODF_NAME_MARKER;
+/* % */ t[37] = SC_COMPILER_C_VALUE;
+/* & */ t[38] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* ' */ t[39] = SC_COMPILER_C_NAME_SEP;
+/* ( */ t[40] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* ) */ t[41] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* * */ t[42] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* + */ t[43] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
+/* , */ t[44] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE;
+/* - */ t[45] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
+/* . */ t[46] = SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE | SC_COMPILER_C_IDENT | SC_COMPILER_C_NAME;
+/* / */ t[47] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+
+ for (i = 48; i < 58; i++)
+/* 0-9 */ t[i] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_WORD | SC_COMPILER_C_VALUE | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_VALUE | SC_COMPILER_C_IDENT | SC_COMPILER_C_NAME;
+
+/* : */ t[58] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD;
+/* ; */ t[59] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* < */ t[60] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* = */ t[61] = SC_COMPILER_C_CHAR | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* > */ t[62] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* ? */ t[63] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_NAME;
+/* @ */ // FREE
+
+ for (i = 65; i < 91; i++)
+/* A-Z */ t[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT | SC_COMPILER_C_CHAR_NAME | SC_COMPILER_C_NAME;
+
+ if (FormulaGrammar::CONV_ODF == meConv)
+ {
+/* [ */ t[91] = SC_COMPILER_C_ODF_LBRACKET;
+/* \ */ // FREE
+/* ] */ t[93] = SC_COMPILER_C_ODF_RBRACKET;
+ }
+ else
+ {
+/* [ */ // FREE
+/* \ */ // FREE
+/* ] */ // FREE
+ }
+/* ^ */ t[94] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* _ */ t[95] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT | SC_COMPILER_C_CHAR_NAME | SC_COMPILER_C_NAME;
+/* ` */ // FREE
+
+ for (i = 97; i < 123; i++)
+/* a-z */ t[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT | SC_COMPILER_C_CHAR_NAME | SC_COMPILER_C_NAME;
+
+/* { */ t[123] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; // array open
+/* | */ t[124] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; // array row sep (Should be OOo specific)
+/* } */ t[125] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; // array close
+/* ~ */ t[126] = SC_COMPILER_C_CHAR; // OOo specific
+/* 127 */ // FREE
+
+ if( FormulaGrammar::CONV_XL_A1 == meConv || FormulaGrammar::CONV_XL_R1C1 == meConv || FormulaGrammar::CONV_XL_OOX == meConv )
+ {
+/* */ t[32] |= SC_COMPILER_C_WORD;
+/* ! */ t[33] |= SC_COMPILER_C_IDENT | SC_COMPILER_C_WORD;
+/* " */ t[34] |= SC_COMPILER_C_WORD;
+/* # */ t[35] &= (~SC_COMPILER_C_WORD_SEP);
+/* # */ t[35] |= SC_COMPILER_C_WORD;
+/* % */ t[37] |= SC_COMPILER_C_WORD;
+/* ' */ t[39] |= SC_COMPILER_C_WORD;
+
+/* % */ t[37] |= SC_COMPILER_C_WORD;
+/* & */ t[38] |= SC_COMPILER_C_WORD;
+/* ' */ t[39] |= SC_COMPILER_C_WORD;
+/* ( */ t[40] |= SC_COMPILER_C_WORD;
+/* ) */ t[41] |= SC_COMPILER_C_WORD;
+/* * */ t[42] |= SC_COMPILER_C_WORD;
+/* + */ t[43] |= SC_COMPILER_C_WORD;
+#if 0 /* this really needs to be locale specific. */
+/* , */ t[44] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+#else
+/* , */ t[44] |= SC_COMPILER_C_WORD;
+#endif
+/* - */ t[45] |= SC_COMPILER_C_WORD;
+
+/* ; */ t[59] |= SC_COMPILER_C_WORD;
+/* < */ t[60] |= SC_COMPILER_C_WORD;
+/* = */ t[61] |= SC_COMPILER_C_WORD;
+/* > */ t[62] |= SC_COMPILER_C_WORD;
+/* ? */ // question really is not permitted in sheet name
+/* @ */ t[64] |= SC_COMPILER_C_WORD;
+/* [ */ t[91] |= SC_COMPILER_C_WORD;
+/* ] */ t[93] |= SC_COMPILER_C_WORD;
+/* { */ t[123]|= SC_COMPILER_C_WORD;
+/* | */ t[124]|= SC_COMPILER_C_WORD;
+/* } */ t[125]|= SC_COMPILER_C_WORD;
+/* ~ */ t[126]|= SC_COMPILER_C_WORD;
+
+ if( FormulaGrammar::CONV_XL_R1C1 == meConv )
+ {
+/* - */ t[45] |= SC_COMPILER_C_IDENT;
+/* [ */ t[91] |= SC_COMPILER_C_IDENT;
+/* ] */ t[93] |= SC_COMPILER_C_IDENT;
+ }
+ if( FormulaGrammar::CONV_XL_OOX == meConv )
+ {
+/* [ */ t[91] |= SC_COMPILER_C_CHAR_IDENT;
+/* ] */ t[93] |= SC_COMPILER_C_IDENT;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, ParseResult& rRes )
+{
+ // Tokens that start at ' can have anything in them until a final '
+ // but '' marks an escaped '
+ // We've earlier guaranteed that a string containing '' will be
+ // surrounded by '
+ if (rFormula.GetChar(nSrcPos) == '\'')
+ {
+ xub_StrLen nPos = nSrcPos+1;
+ while (nPos < rFormula.Len())
+ {
+ if (rFormula.GetChar(nPos) == '\'')
+ {
+ if ( (nPos+1 == rFormula.Len()) || (rFormula.GetChar(nPos+1) != '\'') )
+ {
+ rRes.TokenType = KParseType::SINGLE_QUOTE_NAME;
+ rRes.EndPos = nPos+1;
+ return true;
+ }
+ ++nPos;
+ }
+ ++nPos;
+ }
+ }
+
+ return false;
+}
+
+static bool lcl_parseExternalName(
+ const String& rSymbol,
+ String& rFile,
+ String& rName,
+ const sal_Unicode cSep,
+ const ScDocument* pDoc = NULL,
+ const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks = NULL )
+{
+ /* TODO: future versions will have to support sheet-local names too, thus
+ * return a possible sheet name as well. */
+ const sal_Unicode* const pStart = rSymbol.GetBuffer();
+ const sal_Unicode* p = pStart;
+ xub_StrLen nLen = rSymbol.Len();
+ sal_Unicode cPrev = 0;
+ String aTmpFile, aTmpName;
+ xub_StrLen i = 0;
+ bool bInName = false;
+ if (cSep == '!')
+ {
+ // For XL use existing parser that resolves bracketed and quoted and
+ // indexed external document names.
+ ScRange aRange;
+ String aStartTabName, aEndTabName;
+ USHORT nFlags = 0;
+ p = aRange.Parse_XL_Header( p, pDoc, aTmpFile, aStartTabName,
+ aEndTabName, nFlags, true, pExternalLinks );
+ if (!p || p == pStart)
+ return false;
+ i = xub_StrLen(p - pStart);
+ cPrev = *(p-1);
+ }
+ for ( ; i < nLen; ++i, ++p)
+ {
+ sal_Unicode c = *p;
+ if (i == 0)
+ {
+ if (c == '.' || c == cSep)
+ return false;
+
+ if (c == '\'')
+ {
+ // Move to the next chart and loop until the second single
+ // quote.
+ cPrev = c;
+ ++i; ++p;
+ for (xub_StrLen j = i; j < nLen; ++j, ++p)
+ {
+ c = *p;
+ if (c == '\'')
+ {
+ if (j == i)
+ {
+ // empty quote e.g. (=''!Name)
+ return false;
+ }
+
+ if (cPrev == '\'')
+ {
+ // two consecutive quotes equals a single
+ // quote in the file name.
+ aTmpFile.Append(c);
+ cPrev = 'a';
+ }
+ else
+ cPrev = c;
+
+ continue;
+ }
+
+ if (cPrev == '\'' && j != i)
+ {
+ // this is not a quote but the previous one
+ // is. This ends the parsing of the quoted
+ // segment.
+
+ i = j;
+ bInName = true;
+ break;
+ }
+ aTmpFile.Append(c);
+ cPrev = c;
+ }
+
+ if (!bInName)
+ {
+ // premature ending of the quoted segment.
+ return false;
+ }
+
+ if (c != cSep)
+ {
+ // only the separator is allowed after the closing quote.
+ return false;
+ }
+
+ cPrev = c;
+ continue;
+ }
+ }
+
+ if (bInName)
+ {
+ if (c == cSep)
+ {
+ // A second separator ? Not a valid external name.
+ return false;
+ }
+ aTmpName.Append(c);
+ }
+ else
+ {
+ if (c == cSep)
+ {
+ bInName = true;
+ }
+ else
+ {
+ do
+ {
+ if (CharClass::isAsciiAlphaNumeric(c))
+ // allowed.
+ break;
+
+ if (c > 128)
+ // non-ASCII character is allowed.
+ break;
+
+ bool bValid = false;
+ switch (c)
+ {
+ case '_':
+ case '-':
+ case '.':
+ // these special characters are allowed.
+ bValid = true;
+ break;
+ }
+ if (bValid)
+ break;
+
+ return false;
+ }
+ while (false);
+ aTmpFile.Append(c);
+ }
+ }
+ cPrev = c;
+ }
+
+ if (!bInName)
+ {
+ // No name found - most likely the symbol has no '!'s.
+ return false;
+ }
+
+ rFile = aTmpFile;
+ rName = aTmpName;
+ return true;
+}
+
+static String lcl_makeExternalNameStr( const String& rFile, const String& rName,
+ const sal_Unicode cSep, bool bODF )
+{
+ String aFile( rFile), aName( rName), aEscQuote( RTL_CONSTASCII_USTRINGPARAM("''"));
+ aFile.SearchAndReplaceAllAscii( "'", aEscQuote);
+ if (bODF)
+ aName.SearchAndReplaceAllAscii( "'", aEscQuote);
+ rtl::OUStringBuffer aBuf( aFile.Len() + aName.Len() + 9);
+ if (bODF)
+ aBuf.append( sal_Unicode( '['));
+ aBuf.append( sal_Unicode( '\''));
+ aBuf.append( aFile);
+ aBuf.append( sal_Unicode( '\''));
+ aBuf.append( cSep);
+ if (bODF)
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "$$'"));
+ aBuf.append( aName);
+ if (bODF)
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "']"));
+ return String( aBuf.makeStringAndClear());
+}
+
+static bool lcl_getLastTabName( String& rTabName2, const String& rTabName1,
+ const vector<String>& rTabNames, const ScComplexRefData& rRef )
+{
+ SCsTAB nTabSpan = rRef.Ref2.nTab - rRef.Ref1.nTab;
+ if (nTabSpan > 0)
+ {
+ size_t nCount = rTabNames.size();
+ vector<String>::const_iterator itrBeg = rTabNames.begin(), itrEnd = rTabNames.end();
+ vector<String>::const_iterator itr = ::std::find(itrBeg, itrEnd, rTabName1);
+ if (itr == rTabNames.end())
+ {
+ rTabName2 = ScGlobal::GetRscString(STR_NO_REF_TABLE);
+ return false;
+ }
+
+ size_t nDist = ::std::distance(itrBeg, itr);
+ if (nDist + static_cast<size_t>(nTabSpan) >= nCount)
+ {
+ rTabName2 = ScGlobal::GetRscString(STR_NO_REF_TABLE);
+ return false;
+ }
+
+ rTabName2 = rTabNames[nDist+nTabSpan];
+ }
+ else
+ rTabName2 = rTabName1;
+
+ return true;
+}
+
+struct Convention_A1 : public ScCompiler::Convention
+{
+ Convention_A1( FormulaGrammar::AddressConvention eConv ) : ScCompiler::Convention( eConv ) { }
+ static void MakeColStr( rtl::OUStringBuffer& rBuffer, SCCOL nCol );
+ static void MakeRowStr( rtl::OUStringBuffer& rBuffer, SCROW nRow );
+
+ ParseResult parseAnyToken( const String& rFormula,
+ xub_StrLen nSrcPos,
+ const CharClass* pCharClass) const
+ {
+ ParseResult aRet;
+ if ( lcl_isValidQuotedText(rFormula, nSrcPos, aRet) )
+ return aRet;
+
+ static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
+ KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
+ static const sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
+ // '?' allowed in range names because of Xcl :-/
+ static const String aAddAllowed(String::CreateFromAscii("?#"));
+ return pCharClass->parseAnyToken( rFormula,
+ nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
+ }
+};
+
+void Convention_A1::MakeColStr( rtl::OUStringBuffer& rBuffer, SCCOL nCol )
+{
+ if ( !ValidCol( nCol) )
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ else
+ ::ScColToAlpha( rBuffer, nCol);
+}
+
+void Convention_A1::MakeRowStr( rtl::OUStringBuffer& rBuffer, SCROW nRow )
+{
+ if ( !ValidRow(nRow) )
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ else
+ rBuffer.append(sal_Int32(nRow + 1));
+}
+
+//-----------------------------------------------------------------------------
+
+struct ConventionOOO_A1 : public Convention_A1
+{
+ ConventionOOO_A1() : Convention_A1 (FormulaGrammar::CONV_OOO) { }
+ ConventionOOO_A1( FormulaGrammar::AddressConvention eConv ) : Convention_A1 (eConv) { }
+ static String MakeTabStr( const ScCompiler& rComp, SCTAB nTab, String& aDoc )
+ {
+ String aString;
+ if (!rComp.GetDoc()->GetName( nTab, aString ))
+ aString = ScGlobal::GetRscString(STR_NO_REF_TABLE);
+ else
+ {
+ if ( aString.GetChar(0) == '\'' )
+ { // "'Doc'#Tab"
+ xub_StrLen nPos = ScGlobal::FindUnquoted( aString, SC_COMPILER_FILE_TAB_SEP);
+ if (nPos != STRING_NOTFOUND && nPos > 0 && aString.GetChar(nPos-1) == '\'')
+ {
+ aDoc = aString.Copy( 0, nPos + 1 );
+ aString.Erase( 0, nPos + 1 );
+ aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_UNAMBIGUOUS );
+ }
+ else
+ aDoc.Erase();
+ }
+ else
+ aDoc.Erase();
+ ScCompiler::CheckTabQuotes( aString, FormulaGrammar::CONV_OOO );
+ }
+ aString += '.';
+ return aString;
+ }
+
+ void MakeRefStrImpl( rtl::OUStringBuffer& rBuffer,
+ const ScCompiler& rComp,
+ const ScComplexRefData& rRef,
+ bool bSingleRef,
+ bool bODF ) const
+ {
+ if (bODF)
+ rBuffer.append(sal_Unicode('['));
+ ScComplexRefData aRef( rRef );
+ // In case absolute/relative positions weren't separately available:
+ // transform relative to absolute!
+ // AdjustReference( aRef.Ref1 );
+ // if( !bSingleRef )
+ // AdjustReference( aRef.Ref2 );
+ aRef.Ref1.CalcAbsIfRel( rComp.GetPos() );
+ if( !bSingleRef )
+ aRef.Ref2.CalcAbsIfRel( rComp.GetPos() );
+ if( aRef.Ref1.IsFlag3D() )
+ {
+ if (aRef.Ref1.IsTabDeleted())
+ {
+ if (!aRef.Ref1.IsTabRel())
+ rBuffer.append(sal_Unicode('$'));
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ rBuffer.append(sal_Unicode('.'));
+ }
+ else
+ {
+ String aDoc;
+ String aRefStr( MakeTabStr( rComp, aRef.Ref1.nTab, aDoc ) );
+ rBuffer.append(aDoc);
+ if (!aRef.Ref1.IsTabRel()) rBuffer.append(sal_Unicode('$'));
+ rBuffer.append(aRefStr);
+ }
+ }
+ else if (bODF)
+ rBuffer.append(sal_Unicode('.'));
+ if (!aRef.Ref1.IsColRel())
+ rBuffer.append(sal_Unicode('$'));
+ if ( aRef.Ref1.IsColDeleted() )
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ else
+ MakeColStr(rBuffer, aRef.Ref1.nCol );
+ if (!aRef.Ref1.IsRowRel())
+ rBuffer.append(sal_Unicode('$'));
+ if ( aRef.Ref1.IsRowDeleted() )
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ else
+ MakeRowStr( rBuffer, aRef.Ref1.nRow );
+ if (!bSingleRef)
+ {
+ rBuffer.append(sal_Unicode(':'));
+ if (aRef.Ref2.IsFlag3D() || aRef.Ref2.nTab != aRef.Ref1.nTab)
+ {
+ if (aRef.Ref2.IsTabDeleted())
+ {
+ if (!aRef.Ref2.IsTabRel())
+ rBuffer.append(sal_Unicode('$'));
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ rBuffer.append(sal_Unicode('.'));
+ }
+ else
+ {
+ String aDoc;
+ String aRefStr( MakeTabStr( rComp, aRef.Ref2.nTab, aDoc ) );
+ rBuffer.append(aDoc);
+ if (!aRef.Ref2.IsTabRel()) rBuffer.append(sal_Unicode('$'));
+ rBuffer.append(aRefStr);
+ }
+ }
+ else if (bODF)
+ rBuffer.append(sal_Unicode('.'));
+ if (!aRef.Ref2.IsColRel())
+ rBuffer.append(sal_Unicode('$'));
+ if ( aRef.Ref2.IsColDeleted() )
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ else
+ MakeColStr( rBuffer, aRef.Ref2.nCol );
+ if (!aRef.Ref2.IsRowRel())
+ rBuffer.append(sal_Unicode('$'));
+ if ( aRef.Ref2.IsRowDeleted() )
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ else
+ MakeRowStr( rBuffer, aRef.Ref2.nRow );
+ }
+ if (bODF)
+ rBuffer.append(sal_Unicode(']'));
+ }
+
+ void MakeRefStr( rtl::OUStringBuffer& rBuffer,
+ const ScCompiler& rComp,
+ const ScComplexRefData& rRef,
+ BOOL bSingleRef ) const
+ {
+ MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, false);
+ }
+
+ virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType ) const
+ {
+ switch (eSymType)
+ {
+ case ScCompiler::Convention::ABS_SHEET_PREFIX:
+ return '$';
+ case ScCompiler::Convention::SHEET_SEPARATOR:
+ return '.';
+ }
+
+ return sal_Unicode(0);
+ }
+
+ virtual bool parseExternalName( const String& rSymbol, String& rFile, String& rName,
+ const ScDocument* pDoc,
+ const ::com::sun::star::uno::Sequence<
+ const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks ) const
+ {
+ return lcl_parseExternalName(rSymbol, rFile, rName, sal_Unicode('#'), pDoc, pExternalLinks);
+ }
+
+ virtual String makeExternalNameStr( const String& rFile, const String& rName ) const
+ {
+ return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('#'), false);
+ }
+
+ bool makeExternalSingleRefStr( ::rtl::OUStringBuffer& rBuffer, sal_uInt16 nFileId,
+ const String& rTabName, const ScSingleRefData& rRef,
+ ScExternalRefManager* pRefMgr, bool bDisplayTabName, bool bEncodeUrl ) const
+ {
+ if (bDisplayTabName)
+ {
+ String aFile;
+ const String* p = pRefMgr->getExternalFileName(nFileId);
+ if (p)
+ {
+ if (bEncodeUrl)
+ aFile = *p;
+ else
+ aFile = INetURLObject::decode(*p, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
+ }
+ aFile.SearchAndReplaceAllAscii("'", String::CreateFromAscii("''"));
+
+ rBuffer.append(sal_Unicode('\''));
+ rBuffer.append(aFile);
+ rBuffer.append(sal_Unicode('\''));
+ rBuffer.append(sal_Unicode('#'));
+
+ if (!rRef.IsTabRel())
+ rBuffer.append(sal_Unicode('$'));
+ ScRangeStringConverter::AppendTableName(rBuffer, rTabName);
+
+ rBuffer.append(sal_Unicode('.'));
+ }
+
+ if (!rRef.IsColRel())
+ rBuffer.append(sal_Unicode('$'));
+ MakeColStr( rBuffer, rRef.nCol);
+ if (!rRef.IsRowRel())
+ rBuffer.append(sal_Unicode('$'));
+ MakeRowStr( rBuffer, rRef.nRow);
+
+ return true;
+ }
+
+ void makeExternalRefStrImpl( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef,
+ ScExternalRefManager* pRefMgr, bool bODF ) const
+ {
+ ScSingleRefData aRef(rRef);
+ aRef.CalcAbsIfRel(rCompiler.GetPos());
+
+ if (bODF)
+ rBuffer.append( sal_Unicode('['));
+
+ bool bEncodeUrl = true;
+ switch (rCompiler.GetEncodeUrlMode())
+ {
+ case ScCompiler::ENCODE_BY_GRAMMAR:
+ bEncodeUrl = bODF;
+ break;
+ case ScCompiler::ENCODE_ALWAYS:
+ bEncodeUrl = true;
+ break;
+ case ScCompiler::ENCODE_NEVER:
+ bEncodeUrl = false;
+ break;
+ default:
+ ;
+ }
+ makeExternalSingleRefStr(rBuffer, nFileId, rTabName, aRef, pRefMgr, true, bEncodeUrl);
+ if (bODF)
+ rBuffer.append( sal_Unicode(']'));
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, false);
+ }
+
+ void makeExternalRefStrImpl( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef,
+ ScExternalRefManager* pRefMgr, bool bODF ) const
+ {
+ ScComplexRefData aRef(rRef);
+ aRef.CalcAbsIfRel(rCompiler.GetPos());
+
+ if (bODF)
+ rBuffer.append( sal_Unicode('['));
+ // Ensure that there's always a closing bracket, no premature returns.
+ bool bEncodeUrl = true;
+ switch (rCompiler.GetEncodeUrlMode())
+ {
+ case ScCompiler::ENCODE_BY_GRAMMAR:
+ bEncodeUrl = bODF;
+ break;
+ case ScCompiler::ENCODE_ALWAYS:
+ bEncodeUrl = true;
+ break;
+ case ScCompiler::ENCODE_NEVER:
+ bEncodeUrl = false;
+ break;
+ default:
+ ;
+ }
+
+ do
+ {
+ if (!makeExternalSingleRefStr(rBuffer, nFileId, rTabName, aRef.Ref1, pRefMgr, true, bEncodeUrl))
+ break;
+
+ rBuffer.append(sal_Unicode(':'));
+
+ String aLastTabName;
+ bool bDisplayTabName = (aRef.Ref1.nTab != aRef.Ref2.nTab);
+ if (bDisplayTabName)
+ {
+ // Get the name of the last table.
+ vector<String> aTabNames;
+ pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+ if (aTabNames.empty())
+ {
+ DBG_ERROR1( "ConventionOOO_A1::makeExternalRefStrImpl: no sheet names for document ID %s", nFileId);
+ }
+
+ if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aRef))
+ {
+ DBG_ERROR( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
+ // aLastTabName contains #REF!, proceed.
+ }
+ }
+ else if (bODF)
+ rBuffer.append( sal_Unicode('.')); // need at least the sheet separator in ODF
+ makeExternalSingleRefStr( rBuffer, nFileId, aLastTabName,
+ aRef.Ref2, pRefMgr, bDisplayTabName, bEncodeUrl);
+ } while (0);
+ if (bODF)
+ rBuffer.append( sal_Unicode(']'));
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, false);
+ }
+};
+
+
+static const ConventionOOO_A1 ConvOOO_A1;
+const ScCompiler::Convention * const ScCompiler::pConvOOO_A1 = &ConvOOO_A1;
+
+//-----------------------------------------------------------------------------
+
+struct ConventionOOO_A1_ODF : public ConventionOOO_A1
+{
+ ConventionOOO_A1_ODF() : ConventionOOO_A1 (FormulaGrammar::CONV_ODF) { }
+ void MakeRefStr( rtl::OUStringBuffer& rBuffer,
+ const ScCompiler& rComp,
+ const ScComplexRefData& rRef,
+ BOOL bSingleRef ) const
+ {
+ MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, true);
+ }
+
+ virtual String makeExternalNameStr( const String& rFile, const String& rName ) const
+ {
+ return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('#'), true);
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, true);
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, true);
+ }
+};
+
+static const ConventionOOO_A1_ODF ConvOOO_A1_ODF;
+const ScCompiler::Convention * const ScCompiler::pConvOOO_A1_ODF = &ConvOOO_A1_ODF;
+
+//-----------------------------------------------------------------------------
+
+struct ConventionXL
+{
+ static bool GetDocAndTab( const ScCompiler& rComp,
+ const ScSingleRefData& rRef,
+ String& rDocName,
+ String& rTabName )
+ {
+ bool bHasDoc = false;
+
+ rDocName.Erase();
+ if (rRef.IsTabDeleted() ||
+ !rComp.GetDoc()->GetName( rRef.nTab, rTabName ))
+ {
+ rTabName = ScGlobal::GetRscString( STR_NO_REF_TABLE );
+ return false;
+ }
+
+ // Cheesy hack to unparse the OOO style "'Doc'#Tab"
+ if ( rTabName.GetChar(0) == '\'' )
+ {
+ xub_StrLen nPos = ScGlobal::FindUnquoted( rTabName, SC_COMPILER_FILE_TAB_SEP);
+ if (nPos != STRING_NOTFOUND && nPos > 0 && rTabName.GetChar(nPos-1) == '\'')
+ {
+ rDocName = rTabName.Copy( 0, nPos );
+ // TODO : More research into how XL escapes the doc path
+ rDocName = INetURLObject::decode( rDocName, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_UNAMBIGUOUS );
+ rTabName.Erase( 0, nPos + 1 );
+ bHasDoc = true;
+ }
+ }
+
+ // XL uses the same sheet name quoting conventions in both modes
+ // it is safe to use A1 here
+ ScCompiler::CheckTabQuotes( rTabName, FormulaGrammar::CONV_XL_A1 );
+ return bHasDoc;
+ }
+
+ static void MakeDocStr( rtl::OUStringBuffer& rBuf,
+ const ScCompiler& rComp,
+ const ScComplexRefData& rRef,
+ bool bSingleRef )
+ {
+ if( rRef.Ref1.IsFlag3D() )
+ {
+ String aStartTabName, aStartDocName, aEndTabName, aEndDocName;
+ bool bStartHasDoc = false, bEndHasDoc = false;
+
+ bStartHasDoc = GetDocAndTab( rComp, rRef.Ref1,
+ aStartDocName, aStartTabName);
+
+ if( !bSingleRef && rRef.Ref2.IsFlag3D() )
+ {
+ bEndHasDoc = GetDocAndTab( rComp, rRef.Ref2,
+ aEndDocName, aEndTabName);
+ }
+ else
+ bEndHasDoc = bStartHasDoc;
+
+ if( bStartHasDoc )
+ {
+ // A ref across multipled workbooks ?
+ if( !bEndHasDoc )
+ return;
+
+ rBuf.append( sal_Unicode( '[' ) );
+ rBuf.append( aStartDocName );
+ rBuf.append( sal_Unicode( ']' ) );
+ }
+
+ rBuf.append( aStartTabName );
+ if( !bSingleRef && rRef.Ref2.IsFlag3D() && aStartTabName != aEndTabName )
+ {
+ rBuf.append( sal_Unicode( ':' ) );
+ rBuf.append( aEndTabName );
+ }
+
+ rBuf.append( sal_Unicode( '!' ) );
+ }
+ }
+
+ static sal_Unicode getSpecialSymbol( ScCompiler::Convention::SpecialSymbolType eSymType )
+ {
+ switch (eSymType)
+ {
+ case ScCompiler::Convention::ABS_SHEET_PREFIX:
+ return sal_Unicode(0);
+ case ScCompiler::Convention::SHEET_SEPARATOR:
+ return '!';
+ }
+ return sal_Unicode(0);
+ }
+
+ static bool parseExternalName( const String& rSymbol, String& rFile, String& rName,
+ const ScDocument* pDoc,
+ const ::com::sun::star::uno::Sequence<
+ const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks )
+ {
+ return lcl_parseExternalName( rSymbol, rFile, rName, sal_Unicode('!'), pDoc, pExternalLinks);
+ }
+
+ static String makeExternalNameStr( const String& rFile, const String& rName )
+ {
+ return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('!'), false);
+ }
+
+ static void makeExternalDocStr( ::rtl::OUStringBuffer& rBuffer, const String& rFullName, bool bEncodeUrl )
+ {
+ // Format that is easier to deal with inside OOo, because we use file
+ // URL, and all characetrs are allowed. Check if it makes sense to do
+ // it the way Gnumeric does it. Gnumeric doesn't use the URL form
+ // and allows relative file path.
+ //
+ // ['file:///path/to/source/filename.xls']
+
+ rBuffer.append(sal_Unicode('['));
+ rBuffer.append(sal_Unicode('\''));
+ String aFullName;
+ if (bEncodeUrl)
+ aFullName = rFullName;
+ else
+ aFullName = INetURLObject::decode(rFullName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
+
+ const sal_Unicode* pBuf = aFullName.GetBuffer();
+ xub_StrLen nLen = aFullName.Len();
+ for (xub_StrLen i = 0; i < nLen; ++i)
+ {
+ const sal_Unicode c = pBuf[i];
+ if (c == sal_Unicode('\''))
+ rBuffer.append(c);
+ rBuffer.append(c);
+ }
+ rBuffer.append(sal_Unicode('\''));
+ rBuffer.append(sal_Unicode(']'));
+ }
+
+ static void makeExternalTabNameRange( ::rtl::OUStringBuffer& rBuf, const String& rTabName,
+ const vector<String>& rTabNames,
+ const ScComplexRefData& rRef )
+ {
+ String aLastTabName;
+ if (!lcl_getLastTabName(aLastTabName, rTabName, rTabNames, rRef))
+ {
+ ScRangeStringConverter::AppendTableName(rBuf, aLastTabName);
+ return;
+ }
+
+ ScRangeStringConverter::AppendTableName(rBuf, rTabName);
+ if (rTabName != aLastTabName)
+ {
+ rBuf.append(sal_Unicode(':'));
+ ScRangeStringConverter::AppendTableName(rBuf, rTabName);
+ }
+ }
+
+ static void parseExternalDocName( const String& rFormula, xub_StrLen& rSrcPos )
+ {
+ xub_StrLen nLen = rFormula.Len();
+ const sal_Unicode* p = rFormula.GetBuffer();
+ sal_Unicode cPrev = 0;
+ for (xub_StrLen i = rSrcPos; i < nLen; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (i == rSrcPos)
+ {
+ // first character must be '['.
+ if (c != '[')
+ return;
+ }
+ else if (i == rSrcPos + 1)
+ {
+ // second character must be a single quote.
+ if (c != '\'')
+ return;
+ }
+ else if (c == '\'')
+ {
+ if (cPrev == '\'')
+ // two successive single quote is treated as a single
+ // valid character.
+ c = 'a';
+ }
+ else if (c == ']')
+ {
+ if (cPrev == '\'')
+ {
+ // valid source document path found. Increment the
+ // current position to skip the source path.
+ rSrcPos = i + 1;
+ if (rSrcPos >= nLen)
+ rSrcPos = nLen - 1;
+ return;
+ }
+ else
+ return;
+ }
+ else
+ {
+ // any other character
+ if (i > rSrcPos + 2 && cPrev == '\'')
+ // unless it's the 3rd character, a normal character
+ // following immediately a single quote is invalid.
+ return;
+ }
+ cPrev = c;
+ }
+ }
+};
+
+struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+{
+ ConventionXL_A1() : Convention_A1( FormulaGrammar::CONV_XL_A1 ) { }
+ ConventionXL_A1( FormulaGrammar::AddressConvention eConv ) : Convention_A1( eConv ) { }
+
+ void makeSingleCellStr( ::rtl::OUStringBuffer& rBuf, const ScSingleRefData& rRef ) const
+ {
+ if (!rRef.IsColRel())
+ rBuf.append(sal_Unicode('$'));
+ MakeColStr(rBuf, rRef.nCol);
+ if (!rRef.IsRowRel())
+ rBuf.append(sal_Unicode('$'));
+ MakeRowStr(rBuf, rRef.nRow);
+ }
+
+ void MakeRefStr( rtl::OUStringBuffer& rBuf,
+ const ScCompiler& rComp,
+ const ScComplexRefData& rRef,
+ BOOL bSingleRef ) const
+ {
+ ScComplexRefData aRef( rRef );
+
+ // Play fast and loose with invalid refs. There is not much point in producing
+ // Foo!A1:#REF! versus #REF! at this point
+ aRef.Ref1.CalcAbsIfRel( rComp.GetPos() );
+
+ MakeDocStr( rBuf, rComp, aRef, bSingleRef );
+
+ if( aRef.Ref1.IsColDeleted() || aRef.Ref1.IsRowDeleted() )
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ return;
+ }
+
+ if( !bSingleRef )
+ {
+ aRef.Ref2.CalcAbsIfRel( rComp.GetPos() );
+ if( aRef.Ref2.IsColDeleted() || aRef.Ref2.IsRowDeleted() )
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ return;
+ }
+
+ if( aRef.Ref1.nCol == 0 && aRef.Ref2.nCol >= MAXCOL )
+ {
+ if (!aRef.Ref1.IsRowRel())
+ rBuf.append(sal_Unicode( '$' ));
+ MakeRowStr( rBuf, aRef.Ref1.nRow );
+ rBuf.append(sal_Unicode( ':' ));
+ if (!aRef.Ref2.IsRowRel())
+ rBuf.append(sal_Unicode( '$' ));
+ MakeRowStr( rBuf, aRef.Ref2.nRow );
+ return;
+ }
+
+ if( aRef.Ref1.nRow == 0 && aRef.Ref2.nRow >= MAXROW )
+ {
+ if (!aRef.Ref1.IsColRel())
+ rBuf.append(sal_Unicode( '$' ));
+ MakeColStr(rBuf, aRef.Ref1.nCol );
+ rBuf.append(sal_Unicode( ':' ));
+ if (!aRef.Ref2.IsColRel())
+ rBuf.append(sal_Unicode( '$' ));
+ MakeColStr(rBuf, aRef.Ref2.nCol );
+ return;
+ }
+ }
+
+ makeSingleCellStr(rBuf, aRef.Ref1);
+ if (!bSingleRef)
+ {
+ rBuf.append(sal_Unicode( ':' ));
+ makeSingleCellStr(rBuf, aRef.Ref2);
+ }
+ }
+
+ virtual ParseResult parseAnyToken( const String& rFormula,
+ xub_StrLen nSrcPos,
+ const CharClass* pCharClass) const
+ {
+ ParseResult aRet;
+ if ( lcl_isValidQuotedText(rFormula, nSrcPos, aRet) )
+ return aRet;
+
+ static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
+ KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
+ static const sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
+ // '?' allowed in range names
+ static const String aAddAllowed = String::CreateFromAscii("?!");
+ return pCharClass->parseAnyToken( rFormula,
+ nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
+ }
+
+ virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType ) const
+ {
+ return ConventionXL::getSpecialSymbol(eSymType);
+ }
+
+ virtual bool parseExternalName( const String& rSymbol, String& rFile, String& rName,
+ const ScDocument* pDoc,
+ const ::com::sun::star::uno::Sequence<
+ const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks ) const
+ {
+ return ConventionXL::parseExternalName( rSymbol, rFile, rName, pDoc, pExternalLinks);
+ }
+
+ virtual String makeExternalNameStr( const String& rFile, const String& rName ) const
+ {
+ return ConventionXL::makeExternalNameStr(rFile, rName);
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1
+ // This is a little different from the format Excel uses, as Excel
+ // puts [] only around the file name. But we need to enclose the
+ // whole file path with [] because the file name can contain any
+ // characters.
+
+ const String* pFullName = pRefMgr->getExternalFileName(nFileId);
+ if (!pFullName)
+ return;
+
+ ScSingleRefData aRef(rRef);
+ aRef.CalcAbsIfRel(rCompiler.GetPos());
+
+ ConventionXL::makeExternalDocStr(
+ rBuffer, *pFullName, rCompiler.GetEncodeUrlMode() == ScCompiler::ENCODE_ALWAYS);
+ ScRangeStringConverter::AppendTableName(rBuffer, rTabName);
+ rBuffer.append(sal_Unicode('!'));
+
+ makeSingleCellStr(rBuffer, aRef);
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ const String* pFullName = pRefMgr->getExternalFileName(nFileId);
+ if (!pFullName)
+ return;
+
+ vector<String> aTabNames;
+ pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+ if (aTabNames.empty())
+ return;
+
+ ScComplexRefData aRef(rRef);
+ aRef.CalcAbsIfRel(rCompiler.GetPos());
+
+ ConventionXL::makeExternalDocStr(
+ rBuffer, *pFullName, rCompiler.GetEncodeUrlMode() == ScCompiler::ENCODE_ALWAYS);
+ ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, aTabNames, aRef);
+ rBuffer.append(sal_Unicode('!'));
+
+ makeSingleCellStr(rBuffer, aRef.Ref1);
+ if (aRef.Ref1 != aRef.Ref2)
+ {
+ rBuffer.append(sal_Unicode(':'));
+ makeSingleCellStr(rBuffer, aRef.Ref2);
+ }
+ }
+};
+
+static const ConventionXL_A1 ConvXL_A1;
+const ScCompiler::Convention * const ScCompiler::pConvXL_A1 = &ConvXL_A1;
+
+
+struct ConventionXL_OOX : public ConventionXL_A1
+{
+ ConventionXL_OOX() : ConventionXL_A1( FormulaGrammar::CONV_XL_OOX ) { }
+};
+
+static const ConventionXL_OOX ConvXL_OOX;
+const ScCompiler::Convention * const ScCompiler::pConvXL_OOX = &ConvXL_OOX;
+
+
+//-----------------------------------------------------------------------------
+
+static void
+r1c1_add_col( rtl::OUStringBuffer &rBuf, const ScSingleRefData& rRef )
+{
+ rBuf.append( sal_Unicode( 'C' ) );
+ if( rRef.IsColRel() )
+ {
+ if (rRef.nRelCol != 0)
+ {
+ rBuf.append( sal_Unicode( '[' ) );
+ rBuf.append( String::CreateFromInt32( rRef.nRelCol ) );
+ rBuf.append( sal_Unicode( ']' ) );
+ }
+ }
+ else
+ rBuf.append( String::CreateFromInt32( rRef.nCol + 1 ) );
+}
+static void
+r1c1_add_row( rtl::OUStringBuffer &rBuf, const ScSingleRefData& rRef )
+{
+ rBuf.append( sal_Unicode( 'R' ) );
+ if( rRef.IsRowRel() )
+ {
+ if (rRef.nRelRow != 0)
+ {
+ rBuf.append( sal_Unicode( '[' ) );
+ rBuf.append( String::CreateFromInt32( rRef.nRelRow ) );
+ rBuf.append( sal_Unicode( ']' ) );
+ }
+ }
+ else
+ rBuf.append( String::CreateFromInt32( rRef.nRow + 1 ) );
+}
+
+struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+{
+ ConventionXL_R1C1() : ScCompiler::Convention( FormulaGrammar::CONV_XL_R1C1 ) { }
+ void MakeRefStr( rtl::OUStringBuffer& rBuf,
+ const ScCompiler& rComp,
+ const ScComplexRefData& rRef,
+ BOOL bSingleRef ) const
+ {
+ ScComplexRefData aRef( rRef );
+
+ MakeDocStr( rBuf, rComp, aRef, bSingleRef );
+
+ // Play fast and loose with invalid refs. There is not much point in producing
+ // Foo!A1:#REF! versus #REF! at this point
+ aRef.Ref1.CalcAbsIfRel( rComp.GetPos() );
+ if( aRef.Ref1.IsColDeleted() || aRef.Ref1.IsRowDeleted() )
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ return;
+ }
+
+ if( !bSingleRef )
+ {
+ aRef.Ref2.CalcAbsIfRel( rComp.GetPos() );
+ if( aRef.Ref2.IsColDeleted() || aRef.Ref2.IsRowDeleted() )
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ return;
+ }
+
+ if( aRef.Ref1.nCol == 0 && aRef.Ref2.nCol >= MAXCOL )
+ {
+ r1c1_add_row( rBuf, rRef.Ref1 );
+ if( rRef.Ref1.nRow != rRef.Ref2.nRow ||
+ rRef.Ref1.IsRowRel() != rRef.Ref2.IsRowRel() ) {
+ rBuf.append (sal_Unicode ( ':' ) );
+ r1c1_add_row( rBuf, rRef.Ref2 );
+ }
+ return;
+
+ }
+
+ if( aRef.Ref1.nRow == 0 && aRef.Ref2.nRow >= MAXROW )
+ {
+ r1c1_add_col( rBuf, rRef.Ref1 );
+ if( rRef.Ref1.nCol != rRef.Ref2.nCol ||
+ rRef.Ref1.IsColRel() != rRef.Ref2.IsColRel() )
+ {
+ rBuf.append (sal_Unicode ( ':' ) );
+ r1c1_add_col( rBuf, rRef.Ref2 );
+ }
+ return;
+ }
+ }
+
+ r1c1_add_row( rBuf, rRef.Ref1 );
+ r1c1_add_col( rBuf, rRef.Ref1 );
+ if (!bSingleRef)
+ {
+ rBuf.append (sal_Unicode ( ':' ) );
+ r1c1_add_row( rBuf, rRef.Ref2 );
+ r1c1_add_col( rBuf, rRef.Ref2 );
+ }
+ }
+
+ ParseResult parseAnyToken( const String& rFormula,
+ xub_StrLen nSrcPos,
+ const CharClass* pCharClass) const
+ {
+ ConventionXL::parseExternalDocName(rFormula, nSrcPos);
+
+ ParseResult aRet;
+ if ( lcl_isValidQuotedText(rFormula, nSrcPos, aRet) )
+ return aRet;
+
+ static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
+ KParseTokens::ASC_UNDERSCORE ;
+ static const sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
+ // '?' allowed in range names
+ static const String aAddAllowed = String::CreateFromAscii( "?-[]!" );
+
+ return pCharClass->parseAnyToken( rFormula,
+ nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
+ }
+
+ virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType ) const
+ {
+ return ConventionXL::getSpecialSymbol(eSymType);
+ }
+
+ virtual bool parseExternalName( const String& rSymbol, String& rFile, String& rName,
+ const ScDocument* pDoc,
+ const ::com::sun::star::uno::Sequence<
+ const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks ) const
+ {
+ return ConventionXL::parseExternalName( rSymbol, rFile, rName, pDoc, pExternalLinks);
+ }
+
+ virtual String makeExternalNameStr( const String& rFile, const String& rName ) const
+ {
+ return ConventionXL::makeExternalNameStr(rFile, rName);
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1
+ // This is a little different from the format Excel uses, as Excel
+ // puts [] only around the file name. But we need to enclose the
+ // whole file path with [] because the file name can contain any
+ // characters.
+
+ const String* pFullName = pRefMgr->getExternalFileName(nFileId);
+ if (!pFullName)
+ return;
+
+ ScSingleRefData aRef(rRef);
+ aRef.CalcAbsIfRel(rCompiler.GetPos());
+
+ ConventionXL::makeExternalDocStr(
+ rBuffer, *pFullName, rCompiler.GetEncodeUrlMode() == ScCompiler::ENCODE_ALWAYS);
+ ScRangeStringConverter::AppendTableName(rBuffer, rTabName);
+ rBuffer.append(sal_Unicode('!'));
+
+ r1c1_add_row(rBuffer, aRef);
+ r1c1_add_col(rBuffer, aRef);
+ }
+
+ virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
+ sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef,
+ ScExternalRefManager* pRefMgr ) const
+ {
+ const String* pFullName = pRefMgr->getExternalFileName(nFileId);
+ if (!pFullName)
+ return;
+
+ vector<String> aTabNames;
+ pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+ if (aTabNames.empty())
+ return;
+
+ ScComplexRefData aRef(rRef);
+ aRef.CalcAbsIfRel(rCompiler.GetPos());
+
+ ConventionXL::makeExternalDocStr(
+ rBuffer, *pFullName, rCompiler.GetEncodeUrlMode() == ScCompiler::ENCODE_ALWAYS);
+ ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, aTabNames, aRef);
+ rBuffer.append(sal_Unicode('!'));
+
+ if (aRef.Ref2.IsColDeleted() || aRef.Ref2.IsRowDeleted())
+ {
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+ return;
+ }
+
+ if (aRef.Ref1.nCol == 0 && aRef.Ref2.nCol >= MAXCOL)
+ {
+ r1c1_add_row(rBuffer, rRef.Ref1);
+ if (rRef.Ref1.nRow != rRef.Ref2.nRow || rRef.Ref1.IsRowRel() != rRef.Ref2.IsRowRel())
+ {
+ rBuffer.append (sal_Unicode(':'));
+ r1c1_add_row(rBuffer, rRef.Ref2);
+ }
+ return;
+ }
+
+ if (aRef.Ref1.nRow == 0 && aRef.Ref2.nRow >= MAXROW)
+ {
+ r1c1_add_col(rBuffer, aRef.Ref1);
+ if (aRef.Ref1.nCol != aRef.Ref2.nCol || aRef.Ref1.IsColRel() != aRef.Ref2.IsColRel())
+ {
+ rBuffer.append (sal_Unicode(':'));
+ r1c1_add_col(rBuffer, aRef.Ref2);
+ }
+ return;
+ }
+
+ r1c1_add_row(rBuffer, aRef.Ref1);
+ r1c1_add_col(rBuffer, aRef.Ref1);
+ rBuffer.append (sal_Unicode (':'));
+ r1c1_add_row(rBuffer, aRef.Ref2);
+ r1c1_add_col(rBuffer, aRef.Ref2);
+ }
+};
+
+static const ConventionXL_R1C1 ConvXL_R1C1;
+const ScCompiler::Convention * const ScCompiler::pConvXL_R1C1 = &ConvXL_R1C1;
+
+//-----------------------------------------------------------------------------
+ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArray& rArr)
+ : FormulaCompiler(rArr),
+ pDoc( pDocument ),
+ aPos( rPos ),
+ pCharClass( ScGlobal::pCharClass ),
+ mnPredetectedReference(0),
+ mnRangeOpPosInSymbol(-1),
+ pConv( pConvOOO_A1 ),
+ meEncodeUrlMode( ENCODE_BY_GRAMMAR ),
+ mbCloseBrackets( true ),
+ mbExtendedErrorDetection( false ),
+ mbRewind( false )
+{
+ nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
+}
+
+ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos)
+ :
+ pDoc( pDocument ),
+ aPos( rPos ),
+ pCharClass( ScGlobal::pCharClass ),
+ mnPredetectedReference(0),
+ mnRangeOpPosInSymbol(-1),
+ pConv( pConvOOO_A1 ),
+ meEncodeUrlMode( ENCODE_BY_GRAMMAR ),
+ mbCloseBrackets( true ),
+ mbExtendedErrorDetection( false ),
+ mbRewind( false )
+{
+ nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
+}
+
+void ScCompiler::CheckTabQuotes( String& rString,
+ const FormulaGrammar::AddressConvention eConv )
+{
+ using namespace ::com::sun::star::i18n;
+ sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER | KParseTokens::ASC_UNDERSCORE;
+ sal_Int32 nContFlags = nStartFlags;
+ ParseResult aRes = ScGlobal::pCharClass->parsePredefinedToken(
+ KParseType::IDENTNAME, rString, 0, nStartFlags, EMPTY_STRING, nContFlags, EMPTY_STRING);
+ bool bNeedsQuote = !((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.Len());
+
+ switch ( eConv )
+ {
+ default :
+ case FormulaGrammar::CONV_UNSPECIFIED :
+ break;
+ case FormulaGrammar::CONV_OOO :
+ case FormulaGrammar::CONV_XL_A1 :
+ case FormulaGrammar::CONV_XL_R1C1 :
+ case FormulaGrammar::CONV_XL_OOX :
+ if( bNeedsQuote )
+ {
+ static const String one_quote = static_cast<sal_Unicode>( '\'' );
+ static const String two_quote = String::CreateFromAscii( "''" );
+ // escape embedded quotes
+ rString.SearchAndReplaceAll( one_quote, two_quote );
+ }
+ break;
+ }
+
+ if ( !bNeedsQuote && CharClass::isAsciiNumeric( rString ) )
+ {
+ // Prevent any possible confusion resulting from pure numeric sheet names.
+ bNeedsQuote = true;
+ }
+
+ if( bNeedsQuote )
+ {
+ rString.Insert( '\'', 0 );
+ rString += '\'';
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void ScCompiler::SetRefConvention( FormulaGrammar::AddressConvention eConv )
+{
+ switch ( eConv ) {
+ case FormulaGrammar::CONV_UNSPECIFIED :
+ break;
+ default :
+ case FormulaGrammar::CONV_OOO : SetRefConvention( pConvOOO_A1 ); break;
+ case FormulaGrammar::CONV_ODF : SetRefConvention( pConvOOO_A1_ODF ); break;
+ case FormulaGrammar::CONV_XL_A1 : SetRefConvention( pConvXL_A1 ); break;
+ case FormulaGrammar::CONV_XL_R1C1 : SetRefConvention( pConvXL_R1C1 ); break;
+ case FormulaGrammar::CONV_XL_OOX : SetRefConvention( pConvXL_OOX ); break;
+ }
+}
+
+void ScCompiler::SetRefConvention( const ScCompiler::Convention *pConvP )
+{
+ pConv = pConvP;
+ meGrammar = FormulaGrammar::mergeToGrammar( meGrammar, pConv->meConv);
+ DBG_ASSERT( FormulaGrammar::isSupported( meGrammar),
+ "ScCompiler::SetRefConvention: unsupported grammar resulting");
+}
+
+void ScCompiler::SetError(USHORT nError)
+{
+ if( !pArr->GetCodeError() )
+ pArr->SetCodeError( nError);
+}
+
+
+sal_Unicode* lcl_UnicodeStrNCpy( sal_Unicode* pDst, const sal_Unicode* pSrc, xub_StrLen nMax )
+{
+ const sal_Unicode* const pStop = pDst + nMax;
+ while ( *pSrc && pDst < pStop )
+ {
+ *pDst++ = *pSrc++;
+ }
+ *pDst = 0;
+ return pDst;
+}
+
+
+//---------------------------------------------------------------------------
+// NextSymbol
+//---------------------------------------------------------------------------
+// Zerlegt die Formel in einzelne Symbole fuer die weitere
+// Verarbeitung (Turing-Maschine).
+//---------------------------------------------------------------------------
+// Ausgangs Zustand = GetChar
+//---------------+-------------------+-----------------------+---------------
+// Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand
+//---------------+-------------------+-----------------------+---------------
+// GetChar | ;()+-*/^=& | Symbol=Zeichen | Stop
+// | <> | Symbol=Zeichen | GetBool
+// | $ Buchstabe | Symbol=Zeichen | GetWord
+// | Ziffer | Symbol=Zeichen | GetValue
+// | " | Keine | GetString
+// | Sonst | Keine | GetChar
+//---------------+-------------------+-----------------------+---------------
+// GetBool | => | Symbol=Symbol+Zeichen | Stop
+// | Sonst | Dec(CharPos) | Stop
+//---------------+-------------------+-----------------------+---------------
+// GetWord | SepSymbol | Dec(CharPos) | Stop
+// | ()+-*/^=<>&~ | |
+// | Leerzeichen | Dec(CharPos) | Stop
+// | $_:. | |
+// | Buchstabe,Ziffer | Symbol=Symbol+Zeichen | GetWord
+// | Sonst | Fehler | Stop
+//---------------|-------------------+-----------------------+---------------
+// GetValue | ;()*/^=<>& | |
+// | Leerzeichen | Dec(CharPos) | Stop
+// | Ziffer E+-%,. | Symbol=Symbol+Zeichen | GetValue
+// | Sonst | Fehler | Stop
+//---------------+-------------------+-----------------------+---------------
+// GetString | " | Keine | Stop
+// | Sonst | Symbol=Symbol+Zeichen | GetString
+//---------------+-------------------+-----------------------+---------------
+
+xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+{
+ cSymbol[MAXSTRLEN-1] = 0; // Stopper
+ sal_Unicode* pSym = cSymbol;
+ const sal_Unicode* const pStart = aFormula.GetBuffer();
+ const sal_Unicode* pSrc = pStart + nSrcPos;
+ bool bi18n = false;
+ sal_Unicode c = *pSrc;
+ sal_Unicode cLast = 0;
+ bool bQuote = false;
+ mnRangeOpPosInSymbol = -1;
+ ScanState eState = ssGetChar;
+ xub_StrLen nSpaces = 0;
+ sal_Unicode cSep = mxSymbols->getSymbol( ocSep).GetChar(0);
+ sal_Unicode cArrayColSep = mxSymbols->getSymbol( ocArrayColSep).GetChar(0);
+ sal_Unicode cArrayRowSep = mxSymbols->getSymbol( ocArrayRowSep).GetChar(0);
+ sal_Unicode cDecSep = (mxSymbols->isEnglish() ? '.' :
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0));
+
+ // special symbols specific to address convention used
+ sal_Unicode cSheetPrefix = pConv->getSpecialSymbol(ScCompiler::Convention::ABS_SHEET_PREFIX);
+ sal_Unicode cSheetSep = pConv->getSpecialSymbol(ScCompiler::Convention::SHEET_SEPARATOR);
+
+ int nDecSeps = 0;
+ bool bAutoIntersection = false;
+ int nRefInName = 0;
+ mnPredetectedReference = 0;
+ // try to parse simple tokens before calling i18n parser
+ while ((c != 0) && (eState != ssStop) )
+ {
+ pSrc++;
+ ULONG nMask = GetCharTableFlags( c );
+ // The parameter separator and the array column and row separators end
+ // things unconditionally if not in string or reference.
+ if (c == cSep || (bInArray && (c == cArrayColSep || c == cArrayRowSep)))
+ {
+ switch (eState)
+ {
+ // these are to be continued
+ case ssGetString:
+ case ssSkipString:
+ case ssGetReference:
+ case ssSkipReference:
+ break;
+ default:
+ if (eState == ssGetChar)
+ *pSym++ = c;
+ else
+ pSrc--;
+ eState = ssStop;
+ }
+ }
+Label_MaskStateMachine:
+ switch (eState)
+ {
+ case ssGetChar :
+ {
+ // Order is important!
+ if( nMask & SC_COMPILER_C_ODF_LABEL_OP )
+ {
+ // '!!' automatic intersection
+ if (GetCharTableFlags( pSrc[0] ) & SC_COMPILER_C_ODF_LABEL_OP)
+ {
+ /* TODO: For now the UI "space operator" is used, this
+ * could be enhanced using a specialized OpCode to get
+ * rid of the space ambiguity, which would need some
+ * places to be adapted though. And we would still need
+ * to support the ambiguous space operator for UI
+ * purposes anyway. However, we then could check for
+ * invalid usage of '!!', which currently isn't
+ * possible. */
+ if (!bAutoIntersection)
+ {
+ ++pSrc;
+ nSpaces += 2; // must match the character count
+ bAutoIntersection = true;
+ }
+ else
+ {
+ pSrc--;
+ eState = ssStop;
+ }
+ }
+ else
+ {
+ nMask &= ~SC_COMPILER_C_ODF_LABEL_OP;
+ goto Label_MaskStateMachine;
+ }
+ }
+ else if( nMask & SC_COMPILER_C_ODF_NAME_MARKER )
+ {
+ // '$$' defined name marker
+ if (GetCharTableFlags( pSrc[0] ) & SC_COMPILER_C_ODF_NAME_MARKER)
+ {
+ // both eaten, not added to pSym
+ ++pSrc;
+ }
+ else
+ {
+ nMask &= ~SC_COMPILER_C_ODF_NAME_MARKER;
+ goto Label_MaskStateMachine;
+ }
+ }
+ else if( nMask & SC_COMPILER_C_CHAR )
+ {
+ *pSym++ = c;
+ eState = ssStop;
+ }
+ else if( nMask & SC_COMPILER_C_ODF_LBRACKET )
+ {
+ // eaten, not added to pSym
+ eState = ssGetReference;
+ mnPredetectedReference = 1;
+ }
+ else if( nMask & SC_COMPILER_C_CHAR_BOOL )
+ {
+ *pSym++ = c;
+ eState = ssGetBool;
+ }
+ else if( nMask & SC_COMPILER_C_CHAR_VALUE )
+ {
+ *pSym++ = c;
+ eState = ssGetValue;
+ }
+ else if( nMask & SC_COMPILER_C_CHAR_STRING )
+ {
+ *pSym++ = c;
+ eState = ssGetString;
+ }
+ else if( nMask & SC_COMPILER_C_CHAR_DONTCARE )
+ {
+ nSpaces++;
+ }
+ else if( nMask & SC_COMPILER_C_CHAR_IDENT )
+ { // try to get a simple ASCII identifier before calling
+ // i18n, to gain performance during import
+ *pSym++ = c;
+ eState = ssGetIdent;
+ }
+ else
+ {
+ bi18n = true;
+ eState = ssStop;
+ }
+ }
+ break;
+ case ssGetIdent:
+ {
+ if ( nMask & SC_COMPILER_C_IDENT )
+ { // This catches also $Sheet1.A$1, for example.
+ if( pSym == &cSymbol[ MAXSTRLEN-1 ] )
+ {
+ SetError(errStringOverflow);
+ eState = ssStop;
+ }
+ else
+ *pSym++ = c;
+ }
+ else if (c == ':' && mnRangeOpPosInSymbol < 0)
+ {
+ // One range operator may form Sheet1.A:A, which we need to
+ // pass as one entity to IsReference().
+ mnRangeOpPosInSymbol = pSym - &cSymbol[0];
+ if( pSym == &cSymbol[ MAXSTRLEN-1 ] )
+ {
+ SetError(errStringOverflow);
+ eState = ssStop;
+ }
+ else
+ *pSym++ = c;
+ }
+ else if ( 128 <= c || '\'' == c )
+ { // High values need reparsing with i18n,
+ // single quoted $'sheet' names too (otherwise we'd had to
+ // implement everything twice).
+ bi18n = true;
+ eState = ssStop;
+ }
+ else
+ {
+ pSrc--;
+ eState = ssStop;
+ }
+ }
+ break;
+ case ssGetBool :
+ {
+ if( nMask & SC_COMPILER_C_BOOL )
+ {
+ *pSym++ = c;
+ eState = ssStop;
+ }
+ else
+ {
+ pSrc--;
+ eState = ssStop;
+ }
+ }
+ break;
+ case ssGetValue :
+ {
+ if( pSym == &cSymbol[ MAXSTRLEN-1 ] )
+ {
+ SetError(errStringOverflow);
+ eState = ssStop;
+ }
+ else if (c == cDecSep)
+ {
+ if (++nDecSeps > 1)
+ {
+ // reparse with i18n, may be numeric sheet name as well
+ bi18n = true;
+ eState = ssStop;
+ }
+ else
+ *pSym++ = c;
+ }
+ else if( nMask & SC_COMPILER_C_VALUE )
+ *pSym++ = c;
+ else if( nMask & SC_COMPILER_C_VALUE_SEP )
+ {
+ pSrc--;
+ eState = ssStop;
+ }
+ else if (c == 'E' || c == 'e')
+ {
+ if (GetCharTableFlags( pSrc[0] ) & SC_COMPILER_C_VALUE_EXP)
+ *pSym++ = c;
+ else
+ {
+ // reparse with i18n
+ bi18n = true;
+ eState = ssStop;
+ }
+ }
+ else if( nMask & SC_COMPILER_C_VALUE_SIGN )
+ {
+ if (((cLast == 'E') || (cLast == 'e')) &&
+ (GetCharTableFlags( pSrc[0] ) & SC_COMPILER_C_VALUE_VALUE))
+ {
+ *pSym++ = c;
+ }
+ else
+ {
+ pSrc--;
+ eState = ssStop;
+ }
+ }
+ else
+ {
+ // reparse with i18n
+ bi18n = true;
+ eState = ssStop;
+ }
+ }
+ break;
+ case ssGetString :
+ {
+ if( nMask & SC_COMPILER_C_STRING_SEP )
+ {
+ if ( !bQuote )
+ {
+ if ( *pSrc == '"' )
+ bQuote = true; // "" => literal "
+ else
+ eState = ssStop;
+ }
+ else
+ bQuote = false;
+ }
+ if ( !bQuote )
+ {
+ if( pSym == &cSymbol[ MAXSTRLEN-1 ] )
+ {
+ SetError(errStringOverflow);
+ eState = ssSkipString;
+ }
+ else
+ *pSym++ = c;
+ }
+ }
+ break;
+ case ssSkipString:
+ if( nMask & SC_COMPILER_C_STRING_SEP )
+ eState = ssStop;
+ break;
+ case ssGetReference:
+ if( pSym == &cSymbol[ MAXSTRLEN-1 ] )
+ {
+ SetError( errStringOverflow);
+ eState = ssSkipReference;
+ }
+ // fall through and follow logic
+ case ssSkipReference:
+ // ODF reference: ['External'#$'Sheet'.A1:.B2] with dots being
+ // mandatory also if no sheet name. 'External'# is optional,
+ // sheet name is optional, quotes around sheet name are
+ // optional if no quote contained.
+ // 2nd usage: ['Sheet'.$$'DefinedName']
+ // 3rd usage: ['External'#$$'DefinedName']
+ // 4th usage: ['External'#$'Sheet'.$$'DefinedName']
+ // Also for all these names quotes are optional if no quote
+ // contained.
+ {
+
+ // nRefInName: 0 := not in sheet name yet. 'External'
+ // is parsed as if it was a sheet name and nRefInName
+ // is reset when # is encountered immediately after closing
+ // quote. Same with 'DefinedName', nRefInName is cleared
+ // when : is encountered.
+
+ // Encountered leading $ before sheet name.
+ static const int kDollar = (1 << 1);
+ // Encountered ' opening quote, which may be after $ or
+ // not.
+ static const int kOpen = (1 << 2);
+ // Somewhere in name.
+ static const int kName = (1 << 3);
+ // Encountered ' in name, will be cleared if double or
+ // transformed to kClose if not, in which case kOpen is
+ // cleared.
+ static const int kQuote = (1 << 4);
+ // Past ' closing quote.
+ static const int kClose = (1 << 5);
+ // Encountered # file/sheet separator.
+ static const int kFileSep = (1 << 6);
+ // Past . sheet name separator.
+ static const int kPast = (1 << 7);
+ // Marked name $$ follows sheet name separator, detected
+ // while we're still on the separator. Will be cleared when
+ // entering the name.
+ static const int kMarkAhead = (1 << 8);
+ // In marked defined name.
+ static const int kDefName = (1 << 9);
+
+ bool bAddToSymbol = true;
+ if ((nMask & SC_COMPILER_C_ODF_RBRACKET) && !(nRefInName & kOpen))
+ {
+ DBG_ASSERT( nRefInName & (kPast | kDefName),
+ "ScCompiler::NextSymbol: reference: "
+ "closing bracket ']' without prior sheet name separator '.' violates ODF spec");
+ // eaten, not added to pSym
+ bAddToSymbol = false;
+ eState = ssStop;
+ }
+ else if (cSheetSep == c && nRefInName == 0)
+ {
+ // eat it, no sheet name [.A1]
+ bAddToSymbol = false;
+ nRefInName |= kPast;
+ if ('$' == pSrc[0] && '$' == pSrc[1])
+ nRefInName |= kMarkAhead;
+ }
+ else if (!(nRefInName & kPast) || (nRefInName & (kMarkAhead | kDefName)))
+ {
+ // Not in col/row yet.
+
+ if (SC_COMPILER_FILE_TAB_SEP == c && (nRefInName & kFileSep))
+ nRefInName = 0;
+ else if ('$' == c && '$' == pSrc[0] && !(nRefInName & kOpen))
+ {
+ nRefInName &= ~kMarkAhead;
+ if (!(nRefInName & kDefName))
+ {
+ // eaten, not added to pSym (2 chars)
+ bAddToSymbol = false;
+ ++pSrc;
+ nRefInName &= kPast;
+ nRefInName |= kDefName;
+ }
+ else
+ {
+ // ScAddress::Parse() will recognize this as
+ // invalid later.
+ if (eState != ssSkipReference)
+ {
+ *pSym++ = c;
+ *pSym++ = *pSrc++;
+ }
+ bAddToSymbol = false;
+ }
+ }
+ else if (cSheetPrefix == c && nRefInName == 0)
+ nRefInName |= kDollar;
+ else if ('\'' == c)
+ {
+ // TODO: The conventions' parseExternalName()
+ // should handle quoted names, but as long as they
+ // don't remove non-embedded quotes here.
+ if (!(nRefInName & kName))
+ {
+ nRefInName |= (kOpen | kName);
+ bAddToSymbol = !(nRefInName & kDefName);
+ }
+ else if (!(nRefInName & kOpen))
+ {
+ DBG_ERRORFILE("ScCompiler::NextSymbol: reference: "
+ "a ''' without the name being enclosed in '...' violates ODF spec");
+ }
+ else if (nRefInName & kQuote)
+ {
+ // escaped embedded quote
+ nRefInName &= ~kQuote;
+ }
+ else
+ {
+ switch (pSrc[0])
+ {
+ case '\'':
+ // escapes embedded quote
+ nRefInName |= kQuote;
+ break;
+ case SC_COMPILER_FILE_TAB_SEP:
+ // sheet name should follow
+ nRefInName |= kFileSep;
+ // fallthru
+ default:
+ // quote not followed by quote => close
+ nRefInName |= kClose;
+ nRefInName &= ~kOpen;
+ }
+ bAddToSymbol = !(nRefInName & kDefName);
+ }
+ }
+ else if (cSheetSep == c && !(nRefInName & kOpen))
+ {
+ // unquoted sheet name separator
+ nRefInName |= kPast;
+ if ('$' == pSrc[0] && '$' == pSrc[1])
+ nRefInName |= kMarkAhead;
+ }
+ else if (':' == c && !(nRefInName & kOpen))
+ {
+ DBG_ERRORFILE("ScCompiler::NextSymbol: reference: "
+ "range operator ':' without prior sheet name separator '.' violates ODF spec");
+ nRefInName = 0;
+ ++mnPredetectedReference;
+ }
+ else if (!(nRefInName & kName))
+ {
+ // start unquoted name
+ nRefInName |= kName;
+ }
+ }
+ else if (':' == c)
+ {
+ // range operator
+ nRefInName = 0;
+ ++mnPredetectedReference;
+ }
+ if (bAddToSymbol && eState != ssSkipReference)
+ *pSym++ = c; // everything is part of reference
+ }
+ break;
+ case ssStop:
+ ; // nothing, prevent warning
+ break;
+ }
+ cLast = c;
+ c = *pSrc;
+ }
+ if ( bi18n )
+ {
+ nSrcPos = sal::static_int_cast<xub_StrLen>( nSrcPos + nSpaces );
+ String aSymbol;
+ mnRangeOpPosInSymbol = -1;
+ USHORT nErr = 0;
+ do
+ {
+ bi18n = false;
+ // special case (e.g. $'sheetname' in OOO A1)
+ if ( pStart[nSrcPos] == cSheetPrefix && pStart[nSrcPos+1] == '\'' )
+ aSymbol += pStart[nSrcPos++];
+
+ ParseResult aRes = pConv->parseAnyToken( aFormula, nSrcPos, pCharClass );
+
+ if ( !aRes.TokenType )
+ SetError( nErr = errIllegalChar ); // parsed chars as string
+ if ( aRes.EndPos <= nSrcPos )
+ { // ?!?
+ SetError( nErr = errIllegalChar );
+ nSrcPos = aFormula.Len();
+ aSymbol.Erase();
+ }
+ else
+ {
+ aSymbol.Append( pStart + nSrcPos, (xub_StrLen)aRes.EndPos - nSrcPos );
+ nSrcPos = (xub_StrLen) aRes.EndPos;
+ c = pStart[nSrcPos];
+ if ( aRes.TokenType & KParseType::SINGLE_QUOTE_NAME )
+ { // special cases (e.g. 'sheetname'. or 'filename'# in OOO A1)
+ bi18n = (c == cSheetSep || c == SC_COMPILER_FILE_TAB_SEP);
+ }
+ // One range operator restarts parsing for second reference.
+ if (c == ':' && mnRangeOpPosInSymbol < 0)
+ {
+ mnRangeOpPosInSymbol = aSymbol.Len();
+ bi18n = true;
+ }
+ if ( bi18n )
+ aSymbol += pStart[nSrcPos++];
+ }
+ } while ( bi18n && !nErr );
+ xub_StrLen nLen = aSymbol.Len();
+ if ( nLen >= MAXSTRLEN )
+ {
+ SetError( errStringOverflow );
+ nLen = MAXSTRLEN-1;
+ }
+ lcl_UnicodeStrNCpy( cSymbol, aSymbol.GetBuffer(), nLen );
+ }
+ else
+ {
+ 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)
+ --nSpaces; // replace '!!' with only one space
+ return nSpaces;
+}
+
+//---------------------------------------------------------------------------
+// Convert symbol to token
+//---------------------------------------------------------------------------
+
+BOOL ScCompiler::IsOpCode( const String& rName, bool bInArray )
+{
+ OpCodeHashMap::const_iterator iLook( mxSymbols->getHashMap()->find( rName));
+ BOOL bFound = (iLook != mxSymbols->getHashMap()->end());
+ if (bFound)
+ {
+ ScRawToken aToken;
+ OpCode eOp = iLook->second;
+ if (bInArray)
+ {
+ if (rName.Equals(mxSymbols->getSymbol(ocArrayColSep)))
+ eOp = ocArrayColSep;
+ else if (rName.Equals(mxSymbols->getSymbol(ocArrayRowSep)))
+ eOp = ocArrayRowSep;
+ }
+ aToken.SetOpCode(eOp);
+ pRawToken = aToken.Clone();
+ }
+ else if (mxSymbols->isODFF())
+ {
+ // ODFF names that are not written in the current mapping but to be
+ // recognized. New names will be written in a future relase, then
+ // exchange (!) with the names in
+ // formula/source/core/resource/core_resource.src to be able to still
+ // read the old names as well.
+ struct FunctionName
+ {
+ const sal_Char* pName;
+ OpCode eOp;
+ };
+ static const FunctionName aOdffAliases[] = {
+ // Renamed old names:
+ // XXX none yet.
+ // Renamed new names:
+ { "BINOM.DIST.RANGE", ocB }, // B -> BINOM.DIST.RANGE
+ { "LEGACY.TDIST", ocTDist }, // TDIST -> LEGACY.TDIST
+ { "ORG.OPENOFFICE.EASTERSUNDAY", ocEasterSunday } // EASTERSUNDAY -> ORG.OPENOFFICE.EASTERSUNDAY
+ };
+ static const size_t nOdffAliases = sizeof(aOdffAliases) / sizeof(aOdffAliases[0]);
+ for (size_t i=0; i<nOdffAliases; ++i)
+ {
+ if (rName.EqualsIgnoreCaseAscii( aOdffAliases[i].pName))
+ {
+ ScRawToken aToken;
+ aToken.SetOpCode( aOdffAliases[i].eOp);
+ pRawToken = aToken.Clone();
+ bFound = TRUE;
+ break; // for
+ }
+ }
+ }
+ if (!bFound)
+ {
+ String aIntName;
+ if (mxSymbols->hasExternals())
+ {
+ // If symbols are set by filters get mapping to exact name.
+ ExternalHashMap::const_iterator iExt(
+ mxSymbols->getExternalHashMap()->find( rName));
+ if (iExt != mxSymbols->getExternalHashMap()->end())
+ {
+ if (ScGlobal::GetAddInCollection()->GetFuncData( (*iExt).second))
+ aIntName = (*iExt).second;
+ }
+ if (!aIntName.Len())
+ {
+ // If that isn't found we might continue with rName lookup as a
+ // last resort by just falling through to FindFunction(), but
+ // it shouldn't happen if the map was setup correctly. Don't
+ // waste time and bail out.
+ return FALSE;
+ }
+ }
+ if (!aIntName.Len())
+ {
+ // Old (deprecated) addins first for legacy.
+ USHORT nIndex;
+ bFound = ScGlobal::GetFuncCollection()->SearchFunc( cSymbol, nIndex);
+ if (bFound)
+ {
+ ScRawToken aToken;
+ aToken.SetExternal( cSymbol );
+ pRawToken = aToken.Clone();
+ }
+ else
+ // bLocalFirst=FALSE for (English) upper full original name
+ // (service.function)
+ aIntName = ScGlobal::GetAddInCollection()->FindFunction(
+ rName, !mxSymbols->isEnglish());
+ }
+ if (aIntName.Len())
+ {
+ ScRawToken aToken;
+ aToken.SetExternal( aIntName.GetBuffer() ); // international name
+ pRawToken = aToken.Clone();
+ bFound = TRUE;
+ }
+ }
+ OpCode eOp;
+ if (bFound && ((eOp = pRawToken->GetOpCode()) == ocSub || eOp == ocNegSub))
+ {
+ bool bShouldBeNegSub =
+ (eLastOp == ocOpen || eLastOp == ocSep || eLastOp == ocNegSub ||
+ (SC_OPCODE_START_BIN_OP <= eLastOp && eLastOp < SC_OPCODE_STOP_BIN_OP) ||
+ eLastOp == ocArrayOpen ||
+ eLastOp == ocArrayColSep || eLastOp == ocArrayRowSep);
+ if (bShouldBeNegSub && eOp == ocSub)
+ pRawToken->NewOpCode( ocNegSub );
+ //! if ocNegSub had ForceArray we'd have to set it here
+ else if (!bShouldBeNegSub && eOp == ocNegSub)
+ pRawToken->NewOpCode( ocSub );
+ }
+ return bFound;
+}
+
+BOOL ScCompiler::IsOpCode2( const String& rName )
+{
+ BOOL bFound = FALSE;
+ USHORT i;
+
+ for( i = ocInternalBegin; i <= ocInternalEnd && !bFound; i++ )
+ bFound = rName.EqualsAscii( pInternal[ i-ocInternalBegin ] );
+
+ if (bFound)
+ {
+ ScRawToken aToken;
+ aToken.SetOpCode( (OpCode) --i );
+ pRawToken = aToken.Clone();
+ }
+ return bFound;
+}
+
+BOOL ScCompiler::IsValue( const String& rSym )
+{
+ double fVal;
+ sal_uInt32 nIndex = ( mxSymbols->isEnglish() ?
+ pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US ) : 0 );
+// ULONG nIndex = 0;
+//// ULONG nIndex = pDoc->GetFormatTable()->GetStandardIndex(ScGlobal::eLnge);
+ if (pDoc->GetFormatTable()->IsNumberFormat( rSym, nIndex, fVal ) )
+ {
+ USHORT nType = pDoc->GetFormatTable()->GetType(nIndex);
+
+ // Don't accept 3:3 as time, it is a reference to entire row 3 instead.
+ // Dates should never be entered directly and automatically converted
+ // to serial, because the serial would be wrong if null-date changed.
+ // Usually it wouldn't be accepted anyway because the date separator
+ // clashed with other separators or operators.
+ if (nType & (NUMBERFORMAT_TIME | NUMBERFORMAT_DATE))
+ return FALSE;
+
+ if (nType == NUMBERFORMAT_LOGICAL)
+ {
+ const sal_Unicode* p = aFormula.GetBuffer() + nSrcPos;
+ while( *p == ' ' )
+ p++;
+ if (*p == '(')
+ return FALSE; // Boolean function instead.
+ }
+
+ if( aFormula.GetChar(nSrcPos) == '.' )
+ // numerical sheet name?
+ return FALSE;
+
+ if( nType == NUMBERFORMAT_TEXT )
+ // HACK: number too big!
+ SetError( errIllegalArgument );
+ ScRawToken aToken;
+ aToken.SetDouble( fVal );
+ pRawToken = aToken.Clone();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+BOOL ScCompiler::IsString()
+{
+ register const sal_Unicode* p = cSymbol;
+ while ( *p )
+ p++;
+ xub_StrLen nLen = sal::static_int_cast<xub_StrLen>( p - cSymbol - 1 );
+ BOOL bQuote = ((cSymbol[0] == '"') && (cSymbol[nLen] == '"'));
+ if ((bQuote ? nLen-2 : nLen) > MAXSTRLEN-1)
+ {
+ SetError(errStringOverflow);
+ return FALSE;
+ }
+ if ( bQuote )
+ {
+ cSymbol[nLen] = '\0';
+ ScRawToken aToken;
+ aToken.SetString( cSymbol+1 );
+ pRawToken = aToken.Clone();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL ScCompiler::IsPredetectedReference( const String& rName )
+{
+ // Speedup documents with lots of broken references, e.g. sheet deleted.
+ xub_StrLen nPos = rName.SearchAscii( "#REF!");
+ if (nPos != STRING_NOTFOUND)
+ {
+ /* TODO: this may be enhanced by reusing scan information from
+ * NextSymbol(), the positions of quotes and special characters found
+ * there for $'sheet'.A1:... could be stored in a vector. We don't
+ * fully rescan here whether found positions are within single quotes
+ * for performance reasons. This code does not check for possible
+ * occurrences of insane "valid" sheet names like
+ * 'haha.#REF!1fooledyou' and will generate an error on such. */
+ if (nPos == 0)
+ return false; // #REF!.AB42 or #REF!42 or #REF!#REF!
+ sal_Unicode c = rName.GetChar(nPos-1); // before #REF!
+ if ('$' == c)
+ {
+ if (nPos == 1)
+ return false; // $#REF!.AB42 or $#REF!42 or $#REF!#REF!
+ c = rName.GetChar(nPos-2); // before $#REF!
+ }
+ sal_Unicode c2 = rName.GetChar(nPos+5); // after #REF!
+ switch (c)
+ {
+ case '.':
+ if ('$' == c2 || '#' == c2 || ('0' <= c2 && c2 <= '9'))
+ return false; // sheet.#REF!42 or sheet.#REF!#REF!
+ break;
+ case ':':
+ if (mnPredetectedReference > 1 &&
+ ('.' == c2 || '$' == c2 || '#' == c2 ||
+ ('0' <= c2 && c2 <= '9')))
+ return false; // :#REF!.AB42 or :#REF!42 or :#REF!#REF!
+ break;
+ default:
+ if ((('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) &&
+ ((mnPredetectedReference > 1 && ':' == c2) || 0 == c2))
+ return false; // AB#REF!: or AB#REF!
+ }
+ }
+ switch (mnPredetectedReference)
+ {
+ case 1:
+ return IsSingleReference( rName);
+ case 2:
+ return IsDoubleReference( rName);
+ }
+ return false;
+}
+
+
+BOOL ScCompiler::IsDoubleReference( const String& rName )
+{
+ ScRange aRange( aPos, aPos );
+ const ScAddress::Details aDetails( pConv->meConv, aPos );
+ ScAddress::ExternalInfo aExtInfo;
+ USHORT nFlags = aRange.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks );
+ if( nFlags & SCA_VALID )
+ {
+ ScRawToken aToken;
+ ScComplexRefData aRef;
+ aRef.InitRange( aRange );
+ aRef.Ref1.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 );
+ aRef.Ref1.SetRowRel( (nFlags & SCA_ROW_ABSOLUTE) == 0 );
+ aRef.Ref1.SetTabRel( (nFlags & SCA_TAB_ABSOLUTE) == 0 );
+ if ( !(nFlags & SCA_VALID_TAB) )
+ aRef.Ref1.SetTabDeleted( TRUE ); // #REF!
+ aRef.Ref1.SetFlag3D( ( nFlags & SCA_TAB_3D ) != 0 );
+ aRef.Ref2.SetColRel( (nFlags & SCA_COL2_ABSOLUTE) == 0 );
+ aRef.Ref2.SetRowRel( (nFlags & SCA_ROW2_ABSOLUTE) == 0 );
+ aRef.Ref2.SetTabRel( (nFlags & SCA_TAB2_ABSOLUTE) == 0 );
+ if ( !(nFlags & SCA_VALID_TAB2) )
+ aRef.Ref2.SetTabDeleted( TRUE ); // #REF!
+ aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 );
+ aRef.CalcRelFromAbs( aPos );
+ if (aExtInfo.mbExternal)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const String* pRealTab = pRefMgr->getRealTableName(aExtInfo.mnFileId, aExtInfo.maTabName);
+ aToken.SetExternalDoubleRef(
+ aExtInfo.mnFileId, pRealTab ? *pRealTab : aExtInfo.maTabName, aRef);
+ }
+ else
+ {
+ aToken.SetDoubleReference(aRef);
+ }
+ pRawToken = aToken.Clone();
+ }
+
+ return ( nFlags & SCA_VALID ) != 0;
+}
+
+
+BOOL ScCompiler::IsSingleReference( const String& rName )
+{
+ ScAddress aAddr( aPos );
+ const ScAddress::Details aDetails( pConv->meConv, aPos );
+ ScAddress::ExternalInfo aExtInfo;
+ USHORT nFlags = aAddr.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks );
+ // Something must be valid in order to recognize Sheet1.blah or blah.a1
+ // as a (wrong) reference.
+ if( nFlags & ( SCA_VALID_COL|SCA_VALID_ROW|SCA_VALID_TAB ) )
+ {
+ ScRawToken aToken;
+ ScSingleRefData aRef;
+ aRef.InitAddress( aAddr );
+ aRef.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 );
+ aRef.SetRowRel( (nFlags & SCA_ROW_ABSOLUTE) == 0 );
+ aRef.SetTabRel( (nFlags & SCA_TAB_ABSOLUTE) == 0 );
+ aRef.SetFlag3D( ( nFlags & SCA_TAB_3D ) != 0 );
+ // the reference is really invalid
+ if( !( nFlags & SCA_VALID ) )
+ {
+ if( !( nFlags & SCA_VALID_COL ) )
+ aRef.nCol = MAXCOL+1;
+ if( !( nFlags & SCA_VALID_ROW ) )
+ aRef.nRow = MAXROW+1;
+ if( !( nFlags & SCA_VALID_TAB ) )
+ aRef.nTab = MAXTAB+3;
+ nFlags |= SCA_VALID;
+ }
+ aRef.CalcRelFromAbs( aPos );
+
+ if (aExtInfo.mbExternal)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const String* pRealTab = pRefMgr->getRealTableName(aExtInfo.mnFileId, aExtInfo.maTabName);
+ aToken.SetExternalSingleRef(
+ aExtInfo.mnFileId, pRealTab ? *pRealTab : aExtInfo.maTabName, aRef);
+ }
+ else
+ aToken.SetSingleReference(aRef);
+ pRawToken = aToken.Clone();
+ }
+
+ return ( nFlags & SCA_VALID ) != 0;
+}
+
+
+BOOL ScCompiler::IsReference( const String& rName )
+{
+ // Has to be called before IsValue
+ sal_Unicode ch1 = rName.GetChar(0);
+ sal_Unicode cDecSep = ( mxSymbols->isEnglish() ? '.' :
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0) );
+ if ( ch1 == cDecSep )
+ return FALSE;
+ // Who was that imbecile introducing '.' as the sheet name separator!?!
+ if ( CharClass::isAsciiNumeric( ch1 ) )
+ {
+ // Numerical sheet name is valid.
+ // But English 1.E2 or 1.E+2 is value 100, 1.E-2 is 0.01
+ // Don't create a #REF! of values. But also do not bail out on
+ // something like 3:3, meaning entire row 3.
+ do
+ {
+ const xub_StrLen nPos = ScGlobal::FindUnquoted( rName, '.');
+ if ( nPos == STRING_NOTFOUND )
+ {
+ if (ScGlobal::FindUnquoted( rName, ':') != STRING_NOTFOUND)
+ break; // may be 3:3, continue as usual
+ return FALSE;
+ }
+ sal_Unicode const * const pTabSep = rName.GetBuffer() + nPos;
+ sal_Unicode ch2 = pTabSep[1]; // maybe a column identifier
+ if ( !(ch2 == '$' || CharClass::isAsciiAlpha( ch2 )) )
+ return FALSE;
+ if ( cDecSep == '.' && (ch2 == 'E' || ch2 == 'e') // E + - digit
+ && (GetCharTableFlags( pTabSep[2] ) & SC_COMPILER_C_VALUE_EXP) )
+ { // #91053#
+ // If it is an 1.E2 expression check if "1" is an existent sheet
+ // name. If so, a desired value 1.E2 would have to be entered as
+ // 1E2 or 1.0E2 or 1.E+2, sorry. Another possibility would be to
+ // require numerical sheet names always being entered quoted, which
+ // is not desirable (too many 1999, 2000, 2001 sheets in use).
+ // Furthermore, XML files created with versions prior to SRC640e
+ // wouldn't contain the quotes added by MakeTabStr()/CheckTabQuotes()
+ // and would produce wrong formulas if the conditions here are met.
+ // If you can live with these restrictions you may remove the
+ // check and return an unconditional FALSE.
+ String aTabName( rName.Copy( 0, nPos ) );
+ SCTAB nTab;
+ if ( !pDoc->GetTable( aTabName, nTab ) )
+ return FALSE;
+ // If sheet "1" exists and the expression is 1.E+2 continue as
+ // usual, the ScRange/ScAddress parser will take care of it.
+ }
+ } while(0);
+ }
+
+ if (IsSingleReference( rName))
+ return true;
+
+ // 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 (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
+ }
+ else
+ {
+ // Special treatment for the 'E:\[doc]Sheet1:Sheet3'!D5 Excel sickness,
+ // mnRangeOpPosInSymbol did not catch the range operator as it is
+ // within a quoted name.
+ switch (pConv->meConv)
+ {
+ case FormulaGrammar::CONV_XL_A1:
+ case FormulaGrammar::CONV_XL_R1C1:
+ case FormulaGrammar::CONV_XL_OOX:
+ if (rName.GetChar(0) == '\'' && IsDoubleReference( rName))
+ return true;
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ return false;
+}
+
+BOOL ScCompiler::IsMacro( const String& rName )
+{
+ String aName( rName);
+ StarBASIC* pObj = 0;
+ SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
+
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->EnterBasicCall(); // initialize document's BASIC
+
+ if( pDocSh )//XXX
+ pObj = pDocSh->GetBasic();
+ else
+ pObj = pSfxApp->GetBasic();
+
+ // ODFF recommends to store user-defined functions prefixed with "USER.",
+ // use only unprefixed name if encountered. BASIC doesn't allow '.' in a
+ // function name so a function "USER.FOO" could not exist, and macro check
+ // is assigned the lowest priority in function name check.
+ if (FormulaGrammar::isODFF( GetGrammar()) && aName.EqualsIgnoreCaseAscii( "USER.", 0, 5))
+ aName.Erase( 0, 5);
+
+ SbxMethod* pMeth = (SbxMethod*) pObj->Find( aName, SbxCLASS_METHOD );
+ if( !pMeth )
+ {
+ pSfxApp->LeaveBasicCall();
+ return FALSE;
+ }
+ // It really should be a BASIC function!
+ if( pMeth->GetType() == SbxVOID
+ || ( pMeth->IsFixed() && pMeth->GetType() == SbxEMPTY )
+ || !pMeth->ISA(SbMethod) )
+ {
+ pSfxApp->LeaveBasicCall();
+ return FALSE;
+ }
+ ScRawToken aToken;
+ aToken.SetExternal( aName.GetBuffer() );
+ aToken.eOp = ocMacro;
+ pRawToken = aToken.Clone();
+ pSfxApp->LeaveBasicCall();
+ return TRUE;
+}
+
+BOOL ScCompiler::IsNamedRange( const String& rUpperName )
+{
+ // IsNamedRange is called only from NextNewToken, with an upper-case string
+
+ USHORT n;
+ ScRangeName* pRangeName = pDoc->GetRangeName();
+ if (pRangeName->SearchNameUpper( rUpperName, n ) )
+ {
+ ScRangeData* pData = (*pRangeName)[n];
+ ScRawToken aToken;
+ aToken.SetName( pData->GetIndex() );
+ pRawToken = aToken.Clone();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+bool ScCompiler::IsExternalNamedRange( const String& rSymbol )
+{
+ /* FIXME: This code currently (2008-12-02T15:41+0100 in CWS mooxlsc)
+ * correctly parses external named references in OOo, as required per RFE
+ * #i3740#, just that we can't store them in ODF yet. We will need an OASIS
+ * spec first. Until then don't pretend to support external names that
+ * wouldn't survive a save and reload cycle, return false instead. */
+
+#if 0
+ if (!pConv)
+ return false;
+
+ String aFile, aName;
+ if (!pConv->parseExternalName( rSymbol, aFile, aName, pDoc, &maExternalLinks))
+ return false;
+
+ ScRawToken aToken;
+ if (aFile.Len() > MAXSTRLEN || aName.Len() > MAXSTRLEN)
+ return false;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pRefMgr->convertToAbsName(aFile);
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFile);
+ if (!pRefMgr->getRangeNameTokens(nFileId, aName).get())
+ // range name doesn't exist in the source document.
+ return false;
+
+ const String* pRealName = pRefMgr->getRealRangeName(nFileId, aName);
+ aToken.SetExternalName(nFileId, pRealName ? *pRealName : aName);
+ pRawToken = aToken.Clone();
+ return true;
+#else
+ (void)rSymbol;
+ return false;
+#endif
+}
+
+BOOL ScCompiler::IsDBRange( const String& rName )
+{
+ USHORT n;
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ if (pDBColl->SearchName( rName, n ) )
+ {
+ ScDBData* pData = (*pDBColl)[n];
+ ScRawToken aToken;
+ aToken.SetName( pData->GetIndex() );
+ aToken.eOp = ocDBArea;
+ pRawToken = aToken.Clone();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+BOOL ScCompiler::IsColRowName( const String& rName )
+{
+ BOOL bInList = FALSE;
+ BOOL bFound = FALSE;
+ ScSingleRefData aRef;
+ String aName( rName );
+ DeQuote( aName );
+ SCTAB nThisTab = aPos.Tab();
+ for ( short jThisTab = 1; jThisTab >= 0 && !bInList; jThisTab-- )
+ { // #50300# first check ranges on this sheet, in case of duplicated names
+ for ( short jRow=0; jRow<2 && !bInList; jRow++ )
+ {
+ ScRangePairList* pRL;
+ if ( !jRow )
+ pRL = pDoc->GetColNameRanges();
+ else
+ pRL = pDoc->GetRowNameRanges();
+ for ( ScRangePair* pR = pRL->First(); pR && !bInList; pR = pRL->Next() )
+ {
+ const ScRange& rNameRange = pR->GetRange(0);
+ if ( jThisTab && !(rNameRange.aStart.Tab() <= nThisTab &&
+ nThisTab <= rNameRange.aEnd.Tab()) )
+ continue; // for
+ ScCellIterator aIter( pDoc, rNameRange );
+ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell && !bInList;
+ pCell = aIter.GetNext() )
+ {
+ // Don't crash if cell (via CompileNameFormula) encounters
+ // a formula cell without code and
+ // HasStringData/Interpret/Compile is executed and all that
+ // recursive..
+ // Furthermore, *this* cell won't be touched, since no RPN exists yet.
+ CellType eType = pCell->GetCellType();
+ BOOL bOk = sal::static_int_cast<BOOL>( (eType == CELLTYPE_FORMULA ?
+ ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen() > 0
+ && ((ScFormulaCell*)pCell)->aPos != aPos // noIter
+ : TRUE ) );
+ if ( bOk && pCell->HasStringData() )
+ {
+ String aStr;
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ ((ScStringCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_FORMULA:
+ ((ScFormulaCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_EDIT:
+ ((ScEditCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_NONE:
+ case CELLTYPE_VALUE:
+ case CELLTYPE_NOTE:
+ case CELLTYPE_SYMBOLS:
+#if DBG_UTIL
+ case CELLTYPE_DESTROYED:
+#endif
+ ; // nothing, prevent compiler warning
+ break;
+ }
+ if ( ScGlobal::GetpTransliteration()->isEqual( aStr, aName ) )
+ {
+ aRef.InitFlags();
+ aRef.nCol = aIter.GetCol();
+ aRef.nRow = aIter.GetRow();
+ aRef.nTab = aIter.GetTab();
+ if ( !jRow )
+ aRef.SetColRel( TRUE ); // ColName
+ else
+ aRef.SetRowRel( TRUE ); // RowName
+ aRef.CalcRelFromAbs( aPos );
+ bInList = bFound = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() )
+ { // search in current sheet
+ long nDistance = 0, nMax = 0;
+ long nMyCol = (long) aPos.Col();
+ long nMyRow = (long) aPos.Row();
+ BOOL bTwo = FALSE;
+ ScAddress aOne( 0, 0, aPos.Tab() );
+ ScAddress aTwo( MAXCOL, MAXROW, aPos.Tab() );
+
+ ScAutoNameCache* pNameCache = pDoc->GetAutoNameCache();
+ if ( pNameCache )
+ {
+ // #b6355215# use GetNameOccurences to collect all positions of aName on the sheet
+ // (only once), similar to the outer part of the loop in the "else" branch.
+
+ const ScAutoNameAddresses& rAddresses = pNameCache->GetNameOccurences( aName, aPos.Tab() );
+
+ // Loop through the found positions, similar to the inner part of the loop in the "else" branch.
+ // The order of addresses in the vector is the same as from ScCellIterator.
+
+ ScAutoNameAddresses::const_iterator aEnd(rAddresses.end());
+ for ( ScAutoNameAddresses::const_iterator aAdrIter(rAddresses.begin()); aAdrIter != aEnd; ++aAdrIter )
+ {
+ ScAddress aAddress( *aAdrIter ); // cell address with an equal string
+
+ if ( bFound )
+ { // stop if everything else is further away
+ if ( nMax < (long)aAddress.Col() )
+ break; // aIter
+ }
+ if ( aAddress != aPos )
+ {
+ // same treatment as in isEqual case below
+
+ SCCOL nCol = aAddress.Col();
+ SCROW nRow = aAddress.Row();
+ long nC = nMyCol - nCol;
+ long nR = nMyRow - nRow;
+ if ( bFound )
+ {
+ long nD = nC * nC + nR * nR;
+ if ( nD < nDistance )
+ {
+ if ( nC < 0 || nR < 0 )
+ { // right or below
+ bTwo = TRUE;
+ aTwo.Set( nCol, nRow, aAddress.Tab() );
+ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) );
+ nDistance = nD;
+ }
+ else if ( !(nRow < aOne.Row() && nMyRow >= (long)aOne.Row()) )
+ {
+ // upper left, only if not further up than the
+ // current entry and nMyRow is below (CellIter
+ // runs column-wise)
+ bTwo = FALSE;
+ aOne.Set( nCol, nRow, aAddress.Tab() );
+ nMax = Max( nMyCol + nC, nMyRow + nR );
+ nDistance = nD;
+ }
+ }
+ }
+ else
+ {
+ aOne.Set( nCol, nRow, aAddress.Tab() );
+ nDistance = nC * nC + nR * nR;
+ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) );
+ }
+ bFound = TRUE;
+ }
+ }
+ }
+ else
+ {
+ ScCellIterator aIter( pDoc, ScRange( aOne, aTwo ) );
+ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
+ {
+ if ( bFound )
+ { // stop if everything else is further away
+ if ( nMax < (long)aIter.GetCol() )
+ break; // aIter
+ }
+ CellType eType = pCell->GetCellType();
+ BOOL bOk = sal::static_int_cast<BOOL>( (eType == CELLTYPE_FORMULA ?
+ ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen() > 0
+ && ((ScFormulaCell*)pCell)->aPos != aPos // noIter
+ : TRUE ) );
+ if ( bOk && pCell->HasStringData() )
+ {
+ String aStr;
+ switch ( eType )
+ {
+ case CELLTYPE_STRING:
+ ((ScStringCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_FORMULA:
+ ((ScFormulaCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_EDIT:
+ ((ScEditCell*)pCell)->GetString( aStr );
+ break;
+ case CELLTYPE_NONE:
+ case CELLTYPE_VALUE:
+ case CELLTYPE_NOTE:
+ case CELLTYPE_SYMBOLS:
+#if DBG_UTIL
+ case CELLTYPE_DESTROYED:
+#endif
+ ; // nothing, prevent compiler warning
+ break;
+ }
+ if ( ScGlobal::GetpTransliteration()->isEqual( aStr, aName ) )
+ {
+ SCCOL nCol = aIter.GetCol();
+ SCROW nRow = aIter.GetRow();
+ long nC = nMyCol - nCol;
+ long nR = nMyRow - nRow;
+ if ( bFound )
+ {
+ long nD = nC * nC + nR * nR;
+ if ( nD < nDistance )
+ {
+ if ( nC < 0 || nR < 0 )
+ { // right or below
+ bTwo = TRUE;
+ aTwo.Set( nCol, nRow, aIter.GetTab() );
+ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) );
+ nDistance = nD;
+ }
+ else if ( !(nRow < aOne.Row() && nMyRow >= (long)aOne.Row()) )
+ {
+ // upper left, only if not further up than the
+ // current entry and nMyRow is below (CellIter
+ // runs column-wise)
+ bTwo = FALSE;
+ aOne.Set( nCol, nRow, aIter.GetTab() );
+ nMax = Max( nMyCol + nC, nMyRow + nR );
+ nDistance = nD;
+ }
+ }
+ }
+ else
+ {
+ aOne.Set( nCol, nRow, aIter.GetTab() );
+ nDistance = nC * nC + nR * nR;
+ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) );
+ }
+ bFound = TRUE;
+ }
+ }
+ }
+ }
+
+ if ( bFound )
+ {
+ ScAddress aAdr;
+ if ( bTwo )
+ {
+ if ( nMyCol >= (long)aOne.Col() && nMyRow >= (long)aOne.Row() )
+ aAdr = aOne; // upper left takes precedence
+ else
+ {
+ if ( nMyCol < (long)aOne.Col() )
+ { // two to the right
+ if ( nMyRow >= (long)aTwo.Row() )
+ aAdr = aTwo; // directly right
+ else
+ aAdr = aOne;
+ }
+ else
+ { // two below or below and right, take the nearest
+ long nC1 = nMyCol - aOne.Col();
+ long nR1 = nMyRow - aOne.Row();
+ long nC2 = nMyCol - aTwo.Col();
+ long nR2 = nMyRow - aTwo.Row();
+ if ( nC1 * nC1 + nR1 * nR1 <= nC2 * nC2 + nR2 * nR2 )
+ aAdr = aOne;
+ else
+ aAdr = aTwo;
+ }
+ }
+ }
+ else
+ aAdr = aOne;
+ aRef.InitAddress( aAdr );
+ if ( (aRef.nRow != MAXROW && pDoc->HasStringData(
+ aRef.nCol, aRef.nRow + 1, aRef.nTab ))
+ || (aRef.nRow != 0 && pDoc->HasStringData(
+ aRef.nCol, aRef.nRow - 1, aRef.nTab )) )
+ aRef.SetRowRel( TRUE ); // RowName
+ else
+ aRef.SetColRel( TRUE ); // ColName
+ aRef.CalcRelFromAbs( aPos );
+ }
+ }
+ if ( bFound )
+ {
+ ScRawToken aToken;
+ aToken.SetSingleReference( aRef );
+ aToken.eOp = ocColRowName;
+ pRawToken = aToken.Clone();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+BOOL ScCompiler::IsBoolean( const String& rName )
+{
+ OpCodeHashMap::const_iterator iLook( mxSymbols->getHashMap()->find( rName ) );
+ if( iLook != mxSymbols->getHashMap()->end() &&
+ ((*iLook).second == ocTrue ||
+ (*iLook).second == ocFalse) )
+ {
+ ScRawToken aToken;
+ aToken.SetOpCode( (*iLook).second );
+ pRawToken = aToken.Clone();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+void ScCompiler::AutoCorrectParsedSymbol()
+{
+ xub_StrLen nPos = aCorrectedSymbol.Len();
+ if ( nPos )
+ {
+ nPos--;
+ const sal_Unicode cQuote = '\"';
+ const sal_Unicode cx = 'x';
+ const sal_Unicode cX = 'X';
+ sal_Unicode c1 = aCorrectedSymbol.GetChar( 0 );
+ sal_Unicode c2 = aCorrectedSymbol.GetChar( nPos );
+ if ( c1 == cQuote && c2 != cQuote )
+ { // "...
+ // What's not a word doesn't belong to it.
+ // Don't be pedantic: c < 128 should be sufficient here.
+ while ( nPos && ((aCorrectedSymbol.GetChar(nPos) < 128) &&
+ ((GetCharTableFlags( aCorrectedSymbol.GetChar(nPos) ) &
+ (SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_DONTCARE)) == 0)) )
+ nPos--;
+ if ( nPos == MAXSTRLEN - 2 )
+ aCorrectedSymbol.SetChar( nPos, cQuote ); // '"' the 255th character
+ else
+ aCorrectedSymbol.Insert( cQuote, nPos + 1 );
+ bCorrected = TRUE;
+ }
+ else if ( c1 != cQuote && c2 == cQuote )
+ { // ..."
+ aCorrectedSymbol.Insert( cQuote, 0 );
+ bCorrected = TRUE;
+ }
+ else if ( nPos == 0 && (c1 == cx || c1 == cX) )
+ { // x => *
+ aCorrectedSymbol = mxSymbols->getSymbol(ocMul);
+ bCorrected = TRUE;
+ }
+ else if ( (GetCharTableFlags( c1 ) & SC_COMPILER_C_CHAR_VALUE)
+ && (GetCharTableFlags( c2 ) & SC_COMPILER_C_CHAR_VALUE) )
+ {
+ xub_StrLen nXcount;
+ if ( (nXcount = aCorrectedSymbol.GetTokenCount( cx )) > 1 )
+ { // x => *
+ xub_StrLen nIndex = 0;
+ sal_Unicode c = mxSymbols->getSymbol(ocMul).GetChar(0);
+ while ( (nIndex = aCorrectedSymbol.SearchAndReplace(
+ cx, c, nIndex )) != STRING_NOTFOUND )
+ nIndex++;
+ bCorrected = TRUE;
+ }
+ if ( (nXcount = aCorrectedSymbol.GetTokenCount( cX )) > 1 )
+ { // X => *
+ xub_StrLen nIndex = 0;
+ sal_Unicode c = mxSymbols->getSymbol(ocMul).GetChar(0);
+ while ( (nIndex = aCorrectedSymbol.SearchAndReplace(
+ cX, c, nIndex )) != STRING_NOTFOUND )
+ nIndex++;
+ bCorrected = TRUE;
+ }
+ }
+ else
+ {
+ String aSymbol( aCorrectedSymbol );
+ String aDoc;
+ xub_StrLen nPosition;
+ if ( aSymbol.GetChar(0) == '\''
+ && ((nPosition = aSymbol.SearchAscii( "'#" )) != STRING_NOTFOUND) )
+ { // Split off 'Doc'#, may be d:\... or whatever
+ aDoc = aSymbol.Copy( 0, nPosition + 2 );
+ aSymbol.Erase( 0, nPosition + 2 );
+ }
+ xub_StrLen nRefs = aSymbol.GetTokenCount( ':' );
+ BOOL bColons;
+ if ( nRefs > 2 )
+ { // duplicated or too many ':'? B:2::C10 => B2:C10
+ bColons = TRUE;
+ xub_StrLen nIndex = 0;
+ String aTmp1( aSymbol.GetToken( 0, ':', nIndex ) );
+ xub_StrLen nLen1 = aTmp1.Len();
+ String aSym, aTmp2;
+ BOOL bLastAlp, bNextNum;
+ bLastAlp = bNextNum = TRUE;
+ xub_StrLen nStrip = 0;
+ xub_StrLen nCount = nRefs;
+ for ( xub_StrLen j=1; j<nCount; j++ )
+ {
+ aTmp2 = aSymbol.GetToken( 0, ':', nIndex );
+ xub_StrLen nLen2 = aTmp2.Len();
+ if ( nLen1 || nLen2 )
+ {
+ if ( nLen1 )
+ {
+ aSym += aTmp1;
+ bLastAlp = CharClass::isAsciiAlpha( aTmp1 );
+ }
+ if ( nLen2 )
+ {
+ bNextNum = CharClass::isAsciiNumeric( aTmp2 );
+ if ( bLastAlp == bNextNum && nStrip < 1 )
+ {
+ // Must be alternating number/string, only
+ // strip within a reference.
+ nRefs--;
+ nStrip++;
+ }
+ else
+ {
+ xub_StrLen nSymLen = aSym.Len();
+ if ( nSymLen
+ && (aSym.GetChar( nSymLen - 1 ) != ':') )
+ aSym += ':';
+ nStrip = 0;
+ }
+ bLastAlp = !bNextNum;
+ }
+ else
+ { // ::
+ nRefs--;
+ if ( nLen1 )
+ { // B10::C10 ? append ':' on next round
+ if ( !bLastAlp && !CharClass::isAsciiNumeric( aTmp1 ) )
+ nStrip++;
+ }
+ bNextNum = !bLastAlp;
+ }
+ aTmp1 = aTmp2;
+ nLen1 = nLen2;
+ }
+ else
+ nRefs--;
+ }
+ aSymbol = aSym;
+ aSymbol += aTmp1;
+ }
+ else
+ bColons = FALSE;
+ if ( nRefs && nRefs <= 2 )
+ { // reference twisted? 4A => A4 etc.
+ String aTab[2], aRef[2];
+ const ScAddress::Details aDetails( pConv->meConv, aPos );
+ if ( nRefs == 2 )
+ {
+ aRef[0] = aSymbol.GetToken( 0, ':' );
+ aRef[1] = aSymbol.GetToken( 1, ':' );
+ }
+ else
+ aRef[0] = aSymbol;
+
+ BOOL bChanged = FALSE;
+ BOOL bOk = TRUE;
+ USHORT nMask = SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW;
+ for ( int j=0; j<nRefs; j++ )
+ {
+ xub_StrLen nTmp = 0;
+ xub_StrLen nDotPos = STRING_NOTFOUND;
+ while ( (nTmp = aRef[j].Search( '.', nTmp )) != STRING_NOTFOUND )
+ nDotPos = nTmp++; // the last one counts
+ if ( nDotPos != STRING_NOTFOUND )
+ {
+ aTab[j] = aRef[j].Copy( 0, nDotPos + 1 ); // with '.'
+ aRef[j].Erase( 0, nDotPos + 1 );
+ }
+ String aOld( aRef[j] );
+ String aStr2;
+ const sal_Unicode* p = aRef[j].GetBuffer();
+ while ( *p && CharClass::isAsciiNumeric( *p ) )
+ aStr2 += *p++;
+ aRef[j] = String( p );
+ aRef[j] += aStr2;
+ if ( bColons || aRef[j] != aOld )
+ {
+ bChanged = TRUE;
+ ScAddress aAdr;
+ bOk &= ((aAdr.Parse( aRef[j], pDoc, aDetails ) & nMask) == nMask);
+ }
+ }
+ if ( bChanged && bOk )
+ {
+ aCorrectedSymbol = aDoc;
+ aCorrectedSymbol += aTab[0];
+ aCorrectedSymbol += aRef[0];
+ if ( nRefs == 2 )
+ {
+ aCorrectedSymbol += ':';
+ aCorrectedSymbol += aTab[1];
+ aCorrectedSymbol += aRef[1];
+ }
+ bCorrected = TRUE;
+ }
+ }
+ }
+ }
+}
+
+inline bool lcl_UpperAsciiOrI18n( String& rUpper, const String& rOrg, FormulaGrammar::Grammar eGrammar )
+{
+ if (FormulaGrammar::isODFF( eGrammar ))
+ {
+ // ODFF has a defined set of English function names, avoid i18n
+ // overhead.
+ rUpper = rOrg;
+ rUpper.ToUpperAscii();
+ return true;
+ }
+ else
+ {
+ rUpper = ScGlobal::pCharClass->upper( rOrg );
+ return false;
+ }
+}
+
+BOOL ScCompiler::NextNewToken( bool bInArray )
+{
+ bool bAllowBooleans = bInArray;
+ xub_StrLen nSpaces = NextSymbol(bInArray);
+
+#if 0
+ fprintf( stderr, "NextNewToken '%s' (spaces = %d)\n",
+ rtl::OUStringToOString( cSymbol, RTL_TEXTENCODING_UTF8 ).getStr(), nSpaces );
+#endif
+
+ if (!cSymbol[0])
+ return false;
+
+ if( nSpaces )
+ {
+ ScRawToken aToken;
+ aToken.SetOpCode( ocSpaces );
+ aToken.sbyte.cByte = (BYTE) ( nSpaces > 255 ? 255 : nSpaces );
+ if( !static_cast<ScTokenArray*>(pArr)->AddRawToken( aToken ) )
+ {
+ SetError(errCodeOverflow);
+ return false;
+ }
+ }
+
+ // Short cut for references when reading ODF to speedup things.
+ if (mnPredetectedReference)
+ {
+ String aStr( cSymbol);
+ if (!IsPredetectedReference( aStr) && !IsExternalNamedRange( aStr))
+ {
+ /* TODO: it would be nice to generate a #REF! error here, which
+ * would need an ocBad token with additional error value.
+ * FormulaErrorToken wouldn't do because we want to preserve the
+ * original string containing partial valid address
+ * information. */
+ ScRawToken aToken;
+ aToken.SetString( aStr.GetBuffer() );
+ aToken.NewOpCode( ocBad );
+ pRawToken = aToken.Clone();
+ }
+ return true;
+ }
+
+ if ( (cSymbol[0] == '#' || cSymbol[0] == '$') && cSymbol[1] == 0 &&
+ !bAutoCorrect )
+ { // #101100# special case to speed up broken [$]#REF documents
+ /* FIXME: ISERROR(#REF!) would be valid and TRUE and the formula to
+ * be processed as usual. That would need some special treatment,
+ * also in NextSymbol() because of possible combinations of
+ * #REF!.#REF!#REF! parts. In case of reading ODF that is all
+ * handled by IsPredetectedReference(), this case here remains for
+ * manual/API input. */
+ String aBad( aFormula.Copy( nSrcPos-1 ) );
+ eLastOp = pArr->AddBad( aBad )->GetOpCode();
+ return false;
+ }
+
+ if( IsString() )
+ return true;
+
+ bool bMayBeFuncName;
+ bool bAsciiNonAlnum; // operators, separators, ...
+ if ( cSymbol[0] < 128 )
+ {
+ bMayBeFuncName = CharClass::isAsciiAlpha( cSymbol[0] );
+ bAsciiNonAlnum = !bMayBeFuncName && !CharClass::isAsciiDigit( cSymbol[0] );
+ }
+ else
+ {
+ String aTmpStr( cSymbol[0] );
+ bMayBeFuncName = ScGlobal::pCharClass->isLetter( aTmpStr, 0 );
+ bAsciiNonAlnum = false;
+ }
+ if ( bMayBeFuncName )
+ {
+ // a function name must be followed by a parenthesis
+ const sal_Unicode* p = aFormula.GetBuffer() + nSrcPos;
+ while( *p == ' ' )
+ p++;
+ bMayBeFuncName = ( *p == '(' );
+ }
+
+#if 0
+ fprintf( stderr, "Token '%s'\n",
+ rtl::OUStringToOString( aUpper, RTL_TEXTENCODING_UTF8 ).getStr() );
+#endif
+
+ // #42016# Italian ARCTAN.2 resulted in #REF! => IsOpcode() before
+ // IsReference().
+
+ String aUpper;
+
+ do
+ {
+ mbRewind = false;
+ const String aOrg( cSymbol );
+
+ if (bAsciiNonAlnum && IsOpCode( aOrg, bInArray ))
+ return true;
+
+ aUpper.Erase();
+ bool bAsciiUpper = false;
+ if (bMayBeFuncName)
+ {
+ bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
+ if (IsOpCode( aUpper, 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 ))
+ {
+ if (mbRewind) // Range operator, but no direct reference.
+ continue; // do; up to range operator.
+ return true;
+ }
+
+ if (!aUpper.Len())
+ bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
+
+ // IsBoolean() before IsValue() to catch inline bools without the kludge
+ // for inline arrays.
+ if (bAllowBooleans && IsBoolean( aUpper ))
+ return true;
+
+ if (IsValue( 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 )
+ {
+ // set an error and end compilation
+ SetError( errNoName );
+ return false;
+ }
+
+ // Provide single token information and continue. Do not set an error, that
+ // would prematurely end compilation. Simple unknown names are handled by
+ // the interpreter.
+ ScGlobal::pCharClass->toLower( aUpper );
+ ScRawToken aToken;
+ aToken.SetString( aUpper.GetBuffer() );
+ aToken.NewOpCode( ocBad );
+ pRawToken = aToken.Clone();
+ if ( bAutoCorrect )
+ AutoCorrectParsedSymbol();
+ 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
+ fprintf( stderr, "CompileString '%s'\n",
+ 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;
+
+ aFormula.EraseLeadingChars();
+ aFormula.EraseTrailingChars();
+ nSrcPos = 0;
+ bCorrected = FALSE;
+ if ( bAutoCorrect )
+ {
+ aCorrectedFormula.Erase();
+ aCorrectedSymbol.Erase();
+ }
+ BYTE nForced = 0; // ==formula forces recalc even if cell is not visible
+ if( aFormula.GetChar(nSrcPos) == '=' )
+ {
+ nSrcPos++;
+ nForced++;
+ if ( bAutoCorrect )
+ aCorrectedFormula += '=';
+ }
+ if( aFormula.GetChar(nSrcPos) == '=' )
+ {
+ nSrcPos++;
+ nForced++;
+ if ( bAutoCorrect )
+ aCorrectedFormula += '=';
+ }
+ struct FunctionStack
+ {
+ OpCode eOp;
+ short nPar;
+ };
+ // FunctionStack only used if PODF!
+ bool bPODF = FormulaGrammar::isPODF( meGrammar);
+ const size_t nAlloc = 512;
+ FunctionStack aFuncs[ nAlloc ];
+ FunctionStack* pFunctionStack = (bPODF && rFormula.Len() > nAlloc ?
+ new FunctionStack[ rFormula.Len() ] : &aFuncs[0]);
+ pFunctionStack[0].eOp = ocNone;
+ pFunctionStack[0].nPar = 0;
+ size_t nFunction = 0;
+ short nBrackets = 0;
+ bool bInArray = false;
+ eLastOp = ocOpen;
+ while( NextNewToken( bInArray ) )
+ {
+ const OpCode eOp = pRawToken->GetOpCode();
+ switch (eOp)
+ {
+ case ocOpen:
+ {
+ ++nBrackets;
+ if (bPODF)
+ {
+ ++nFunction;
+ pFunctionStack[ nFunction ].eOp = eLastOp;
+ pFunctionStack[ nFunction ].nPar = 0;
+ }
+ }
+ break;
+ case ocClose:
+ {
+ if( !nBrackets )
+ {
+ SetError( errPairExpected );
+ if ( bAutoCorrect )
+ {
+ bCorrected = TRUE;
+ aCorrectedSymbol.Erase();
+ }
+ }
+ else
+ nBrackets--;
+ if (bPODF && nFunction)
+ --nFunction;
+ }
+ break;
+ case ocSep:
+ {
+ if (bPODF)
+ ++pFunctionStack[ nFunction ].nPar;
+ }
+ break;
+ case ocArrayOpen:
+ {
+ if( bInArray )
+ SetError( errNestedArray );
+ else
+ bInArray = true;
+ // Don't count following column separator as parameter separator.
+ if (bPODF)
+ {
+ ++nFunction;
+ pFunctionStack[ nFunction ].eOp = eOp;
+ pFunctionStack[ nFunction ].nPar = 0;
+ }
+ }
+ break;
+ case ocArrayClose:
+ {
+ if( bInArray )
+ {
+ bInArray = false;
+ }
+ else
+ {
+ SetError( errPairExpected );
+ if ( bAutoCorrect )
+ {
+ bCorrected = TRUE;
+ aCorrectedSymbol.Erase();
+ }
+ }
+ if (bPODF && nFunction)
+ --nFunction;
+ }
+ default:
+ break;
+ }
+ if( (eLastOp == ocSep ||
+ eLastOp == ocArrayRowSep ||
+ eLastOp == ocArrayColSep ||
+ eLastOp == ocArrayOpen) &&
+ (eOp == ocSep ||
+ eOp == ocArrayRowSep ||
+ eOp == ocArrayColSep ||
+ eOp == ocArrayClose) )
+ {
+ // FIXME: should we check for known functions with optional empty
+ // args so the correction dialog can do better?
+ if ( !static_cast<ScTokenArray*>(pArr)->Add( new FormulaMissingToken ) )
+ {
+ SetError(errCodeOverflow); break;
+ }
+ }
+ if (bPODF)
+ {
+ /* TODO: for now this is the only PODF adapter. If there were more,
+ * factor this out. */
+ // Insert ADDRESS() new empty parameter 4 if there is a 4th, now to be 5th.
+ if (eOp == ocSep &&
+ pFunctionStack[ nFunction ].eOp == ocAddress &&
+ pFunctionStack[ nFunction ].nPar == 3)
+ {
+ if (!static_cast<ScTokenArray*>(pArr)->Add( new FormulaToken( svSep,ocSep)) ||
+ !static_cast<ScTokenArray*>(pArr)->Add( new FormulaDoubleToken( 1.0)))
+ {
+ SetError(errCodeOverflow); break;
+ }
+ ++pFunctionStack[ nFunction ].nPar;
+ }
+ }
+ FormulaToken* pNewToken = static_cast<ScTokenArray*>(pArr)->Add( pRawToken->CreateToken());
+ if (!pNewToken)
+ {
+ SetError(errCodeOverflow); break;
+ }
+ else if (eLastOp == ocRange && pNewToken->GetOpCode() == ocPush &&
+ pNewToken->GetType() == svSingleRef)
+ static_cast<ScTokenArray*>(pArr)->MergeRangeReference( aPos);
+ eLastOp = pRawToken->GetOpCode();
+ if ( bAutoCorrect )
+ aCorrectedFormula += aCorrectedSymbol;
+ }
+ if ( mbCloseBrackets )
+ {
+ if( bInArray )
+ {
+ FormulaByteToken aToken( ocArrayClose );
+ if( !pArr->AddToken( aToken ) )
+ {
+ SetError(errCodeOverflow);
+ }
+ else if ( bAutoCorrect )
+ aCorrectedFormula += mxSymbols->getSymbol(ocArrayClose);
+ }
+
+ FormulaByteToken aToken( ocClose );
+ while( nBrackets-- )
+ {
+ if( !pArr->AddToken( aToken ) )
+ {
+ SetError(errCodeOverflow); break;
+ }
+ if ( bAutoCorrect )
+ aCorrectedFormula += mxSymbols->getSymbol(ocClose);
+ }
+ }
+ if ( nForced >= 2 )
+ pArr->SetRecalcModeForced();
+
+ if (pFunctionStack != &aFuncs[0])
+ delete [] pFunctionStack;
+
+ // remember pArr, in case a subsequent CompileTokenArray() is executed.
+ ScTokenArray* pNew = new ScTokenArray( aArr );
+ pArr = pNew;
+ return pNew;
+}
+
+
+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() );
+ if (pRangeData)
+ {
+ USHORT nErr = pRangeData->GetErrCode();
+ if( nErr )
+ SetError( errNoName );
+ else if ( !bCompileForFAP )
+ {
+ ScTokenArray* pNew;
+ // #35168# put named formula into parentheses.
+ // #37680# But only if there aren't any yet, parenthetical
+ // ocSep doesn't work, e.g. SUM((...;...))
+ // or if not directly between ocSep/parenthesis,
+ // e.g. SUM(...;(...;...)) no, SUM(...;(...)*3) yes,
+ // in short: if it isn't a self-contained expression.
+ FormulaToken* p1 = pArr->PeekPrevNoSpaces();
+ FormulaToken* p2 = pArr->PeekNextNoSpaces();
+ OpCode eOp1 = (p1 ? p1->GetOpCode() : static_cast<OpCode>( ocSep ) );
+ OpCode eOp2 = (p2 ? p2->GetOpCode() : static_cast<OpCode>( ocSep ) );
+ BOOL bBorder1 = (eOp1 == ocSep || eOp1 == ocOpen);
+ BOOL bBorder2 = (eOp2 == ocSep || eOp2 == ocClose);
+ BOOL bAddPair = !(bBorder1 && bBorder2);
+ if ( bAddPair )
+ {
+ pNew = new ScTokenArray();
+ pNew->AddOpCode( ocClose );
+ PushTokenArray( pNew, TRUE );
+ pNew->Reset();
+ }
+ pNew = pRangeData->GetCode()->Clone();
+ PushTokenArray( pNew, TRUE );
+ if( pRangeData->HasReferences() )
+ {
+ SetRelNameReference();
+ MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+ }
+ pNew->Reset();
+ if ( bAddPair )
+ {
+ pNew = new ScTokenArray();
+ pNew->AddOpCode( ocOpen );
+ PushTokenArray( pNew, TRUE );
+ pNew->Reset();
+ }
+ return GetToken();
+ }
+ }
+ else
+ SetError(errNoName);
+ return TRUE;
+}
+// -----------------------------------------------------------------------------
+BOOL ScCompiler::HandleExternalReference(const FormulaToken& _aToken)
+{
+ // Handle external range names.
+ switch (_aToken.GetType())
+ {
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ pArr->IncrementRefs();
+ break;
+ case svExternalName:
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const String* pFile = pRefMgr->getExternalFileName(_aToken.GetIndex());
+ if (!pFile)
+ {
+ SetError(errNoName);
+ return true;
+ }
+
+ const String& rName = _aToken.GetString();
+ ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getRangeNameTokens(
+ _aToken.GetIndex(), rName, &aPos);
+
+ if (!xNew)
+ {
+ SetError(errNoName);
+ return true;
+ }
+
+ ScTokenArray* pNew = xNew->Clone();
+ PushTokenArray( pNew, true);
+ if (pNew->GetNextReference() != NULL)
+ {
+ SetRelNameReference();
+ MoveRelWrap(MAXCOL, MAXROW);
+ }
+ pNew->Reset();
+ return GetToken();
+ }
+ default:
+ DBG_ERROR("Wrong type for external reference!");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// Append token to RPN code
+//---------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// RPN creation by recursion
+//---------------------------------------------------------------------------
+
+
+
+//-----------------------------------------------------------------------------
+
+BOOL ScCompiler::HasModifiedRange()
+{
+ pArr->Reset();
+ for ( FormulaToken* t = pArr->Next(); t; t = pArr->Next() )
+ {
+ OpCode eOpCode = t->GetOpCode();
+ if ( eOpCode == ocName )
+ {
+ ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex(t->GetIndex());
+
+ if (pRangeData && pRangeData->IsModified())
+ return TRUE;
+ }
+ else if ( eOpCode == ocDBArea )
+ {
+ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex(t->GetIndex());
+
+ if (pDBData && pDBData->IsModified())
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+//---------------------------------------------------------------------------
+
+template< typename T, typename S >
+S lcl_adjval( S& n, T pos, T max, BOOL bRel )
+{
+ max++;
+ if( bRel )
+ n = sal::static_int_cast<S>( n + pos );
+ if( n < 0 )
+ n = sal::static_int_cast<S>( n + max );
+ else if( n >= max )
+ n = sal::static_int_cast<S>( n - max );
+ if( bRel )
+ n = sal::static_int_cast<S>( n - pos );
+ return n;
+}
+
+// reference of named range with relative references
+
+void ScCompiler::SetRelNameReference()
+{
+ pArr->Reset();
+ for( ScToken* t = static_cast<ScToken*>(pArr->GetNextReference()); t;
+ t = static_cast<ScToken*>(pArr->GetNextReference()) )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() )
+ rRef1.SetRelName( TRUE );
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() )
+ rRef2.SetRelName( TRUE );
+ }
+ }
+}
+
+// Wrap-adjust relative references of a RangeName to current position,
+// don't call for other token arrays!
+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, nMaxCol, nMaxRow, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
+ else
+ 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,
+ 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, nMaxCol, nMaxRow, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
+ else
+ ScRefUpdate::MoveRelWrap( pDoc, rPos, nMaxCol, nMaxRow, t->GetDoubleRef() );
+ }
+}
+
+ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
+ const ScAddress& rOldPos, const ScRange& r,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ BOOL& rChanged, BOOL& rRefSizeChanged )
+{
+ rChanged = rRefSizeChanged = FALSE;
+ if ( eUpdateRefMode == URM_COPY )
+ { // Normally nothing has to be done here since RelRefs are used, also
+ // SharedFormulas don't need any special handling, except if they
+ // wrapped around sheet borders.
+ // #67383# But ColRowName tokens pointing to a ColRow header which was
+ // copied along with this formula need to be updated to point to the
+ // copied header instead of the old position's new intersection.
+ ScToken* t;
+ pArr->Reset();
+ while( (t = static_cast<ScToken*>(pArr->GetNextColRowName())) != NULL )
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ rRef.CalcAbsIfRel( rOldPos );
+ ScAddress aNewRef( rRef.nCol + nDx, rRef.nRow + nDy, rRef.nTab + nDz );
+ if ( r.In( aNewRef ) )
+ { // yes, this is URM_MOVE
+ if ( ScRefUpdate::Update( pDoc, URM_MOVE, aPos,
+ r, nDx, nDy, nDz,
+ SingleDoubleRefModifier( rRef ).Ref() )
+ != UR_NOTHING
+ )
+ rChanged = TRUE;
+ }
+ }
+ // Check for SharedFormulas.
+ ScRangeData* pRangeData = NULL;
+ pArr->Reset();
+ for( FormulaToken* j = pArr->GetNextName(); j && !pRangeData;
+ j = pArr->GetNextName() )
+ {
+ if( j->GetOpCode() == ocName )
+ {
+ ScRangeData* pName = pDoc->GetRangeName()->FindIndex( j->GetIndex() );
+ if (pName && pName->HasType(RT_SHARED))
+ pRangeData = pName;
+ }
+ }
+ // Check SharedFormulas for wraps.
+ if (pRangeData)
+ {
+ ScRangeData* pName = pRangeData;
+ pRangeData = NULL;
+ pArr->Reset();
+ for( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()); t && !pRangeData;
+ t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) )
+ {
+ BOOL bRelName = (t->GetType() == svSingleRef ?
+ t->GetSingleRef().IsRelName() :
+ (t->GetDoubleRef().Ref1.IsRelName() ||
+ t->GetDoubleRef().Ref2.IsRelName()));
+ if (bRelName)
+ {
+ t->CalcAbsIfRel( rOldPos);
+ BOOL bValid = (t->GetType() == svSingleRef ?
+ t->GetSingleRef().Valid() :
+ t->GetDoubleRef().Valid());
+ // If the reference isn't valid, copying the formula
+ // wrapped it. Replace SharedFormula.
+ if (!bValid)
+ {
+ pRangeData = pName;
+ rChanged = TRUE;
+ }
+ }
+ }
+ }
+ return pRangeData;
+ }
+ else
+ {
+/*
+ * Set SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE to 1 if we wanted to preserve as
+ * many shared formulas as possible instead of replacing them with direct code.
+ * Note that this may produce shared formula usage Excel doesn't understand,
+ * which would have to be adapted for in the export filter. Advisable as a long
+ * term goal, since it could decrease memory footprint.
+ */
+#define SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE 0
+ ScRangeData* pRangeData = NULL;
+ ScToken* t;
+ pArr->Reset();
+ while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
+ {
+ if( t->GetOpCode() == ocName )
+ {
+ ScRangeData* pName = pDoc->GetRangeName()->FindIndex( t->GetIndex() );
+ if (pName && pName->HasType(RT_SHAREDMOD))
+ {
+ pRangeData = pName; // maybe need a replacement of shared with own code
+#if ! SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ rChanged = TRUE;
+#endif
+ }
+ }
+ else if( t->GetType() != svIndex ) // it may be a DB area!!!
+ {
+ t->CalcAbsIfRel( rOldPos );
+ switch (t->GetType())
+ {
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ // External references never change their positioning
+ // nor point to parts that will be removed or expanded.
+ // In fact, calling ScRefUpdate::Update() for URM_MOVE
+ // may have negative side effects. Simply adapt
+ // relative references to the new position.
+ t->CalcRelFromAbs( aPos);
+ break;
+ case svSingleRef:
+ {
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ aPos, r, nDx, nDy, nDz,
+ SingleDoubleRefModifier(
+ t->GetSingleRef()).Ref())
+ != UR_NOTHING)
+ rChanged = TRUE;
+ }
+ break;
+ default:
+ {
+ ScComplexRefData& rRef = t->GetDoubleRef();
+ SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
+ SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
+ SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ aPos, r, nDx, nDy, nDz,
+ t->GetDoubleRef()) != UR_NOTHING)
+ {
+ rChanged = TRUE;
+ if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
+ rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
+ rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
+ rRefSizeChanged = TRUE;
+ }
+ }
+ }
+ }
+ }
+#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ BOOL bEasyShared, bPosInRange;
+ if ( !pRangeData )
+ bEasyShared = bPosInRange = FALSE;
+ else
+ {
+ bEasyShared = TRUE;
+ bPosInRange = r.In( eUpdateRefMode == URM_MOVE ? aPos : rOldPos );
+ }
+#endif
+ pArr->Reset();
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+ {
+ if ( t->GetRef() != 1 )
+ {
+#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ bEasyShared = FALSE;
+#endif
+ }
+ else
+ { // if nRefCnt>1 it's already updated in token code
+ if ( t->GetType() == svSingleRef )
+ {
+ ScSingleRefData& rRef = t->GetSingleRef();
+ SingleDoubleRefModifier aMod( rRef );
+ if ( rRef.IsRelName() )
+ {
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, aMod.Ref() );
+ rChanged = TRUE;
+ }
+ else
+ {
+ aMod.Ref().CalcAbsIfRel( rOldPos );
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
+ r, nDx, nDy, nDz, aMod.Ref() )
+ != UR_NOTHING
+ )
+ rChanged = TRUE;
+ }
+#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ if ( bEasyShared )
+ {
+ const ScSingleRefData& rSRD = aMod.Ref().Ref1;
+ ScAddress aRef( rSRD.nCol, rSRD.nRow, rSRD.nTab );
+ if ( r.In( aRef ) != bPosInRange )
+ bEasyShared = FALSE;
+ }
+#endif
+ }
+ else
+ {
+ ScComplexRefData& rRef = t->GetDoubleRef();
+ SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
+ SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
+ SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
+ if ( rRef.Ref1.IsRelName() || rRef.Ref2.IsRelName() )
+ {
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, rRef );
+ rChanged = TRUE;
+ }
+ else
+ {
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
+ r, nDx, nDy, nDz, rRef )
+ != UR_NOTHING
+ )
+ {
+ rChanged = TRUE;
+ if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
+ rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
+ rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
+ {
+ rRefSizeChanged = TRUE;
+#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ bEasyShared = FALSE;
+#endif
+ }
+ }
+ }
+#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ if ( bEasyShared )
+ {
+ ScRange aRef( rRef.Ref1.nCol, rRef.Ref1.nRow,
+ rRef.Ref1.nTab, rRef.Ref2.nCol, rRef.Ref2.nRow,
+ rRef.Ref2.nTab );
+ if ( r.In( aRef ) != bPosInRange )
+ bEasyShared = FALSE;
+ }
+#endif
+ }
+ }
+ }
+#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ if ( pRangeData )
+ {
+ if ( bEasyShared )
+ pRangeData = 0;
+ else
+ rChanged = TRUE;
+ }
+#endif
+#undef SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+ return pRangeData;
+ }
+}
+
+BOOL ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode,
+ const ScRange& r,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ BOOL& rChanged, BOOL bSharedFormula)
+{
+ BOOL bRelRef = FALSE; // set if relative reference
+ rChanged = FALSE;
+ pArr->Reset();
+ ScToken* t;
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReference())) != NULL )
+ {
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ bRelRef = rRef.Ref1.IsColRel() || rRef.Ref1.IsRowRel() ||
+ rRef.Ref1.IsTabRel();
+ if (!bRelRef && t->GetType() == svDoubleRef)
+ bRelRef = rRef.Ref2.IsColRel() || rRef.Ref2.IsRowRel() ||
+ rRef.Ref2.IsTabRel();
+ bool bUpdate = !rRef.Ref1.IsColRel() || !rRef.Ref1.IsRowRel() ||
+ !rRef.Ref1.IsTabRel();
+ if (!bUpdate && t->GetType() == svDoubleRef)
+ bUpdate = !rRef.Ref2.IsColRel() || !rRef.Ref2.IsRowRel() ||
+ !rRef.Ref2.IsTabRel();
+ if (!bSharedFormula)
+ {
+ // We cannot update names with sheet-relative references, they may
+ // be used on other sheets as well and the resulting reference
+ // would be wrong. This is a dilemma if col/row would need to be
+ // updated for the current usage.
+ // TODO: seems the only way out of this would be to not allow
+ // relative sheet references and have sheet-local names that can be
+ // copied along with sheets.
+ bUpdate = bUpdate && !rRef.Ref1.IsTabRel() && !rRef.Ref2.IsTabRel();
+ }
+ if (bUpdate)
+ {
+ rRef.CalcAbsIfRel( aPos);
+ if (ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos, r,
+ nDx, nDy, nDz, rRef, ScRefUpdate::ABSOLUTE)
+ != UR_NOTHING )
+ rChanged = TRUE;
+ }
+ }
+ return bRelRef;
+}
+
+
+void ScCompiler::UpdateSharedFormulaReference( UpdateRefMode eUpdateRefMode,
+ const ScAddress& rOldPos, const ScRange& r,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ if ( eUpdateRefMode == URM_COPY )
+ return ;
+ else
+ {
+ ScToken* t;
+ pArr->Reset();
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReference())) != NULL )
+ {
+ if( t->GetType() != svIndex ) // it may be a DB area!!!
+ {
+ t->CalcAbsIfRel( rOldPos );
+ // Absolute references have been already adjusted in the named
+ // shared formula itself prior to breaking the shared formula
+ // and calling this function. Don't readjust them again.
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ ScComplexRefData aBkp = rRef;
+ ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
+ r, nDx, nDy, nDz, rRef );
+ // restore absolute parts
+ if ( !aBkp.Ref1.IsColRel() )
+ {
+ rRef.Ref1.nCol = aBkp.Ref1.nCol;
+ rRef.Ref1.nRelCol = aBkp.Ref1.nRelCol;
+ rRef.Ref1.SetColDeleted( aBkp.Ref1.IsColDeleted() );
+ }
+ if ( !aBkp.Ref1.IsRowRel() )
+ {
+ rRef.Ref1.nRow = aBkp.Ref1.nRow;
+ rRef.Ref1.nRelRow = aBkp.Ref1.nRelRow;
+ rRef.Ref1.SetRowDeleted( aBkp.Ref1.IsRowDeleted() );
+ }
+ if ( !aBkp.Ref1.IsTabRel() )
+ {
+ rRef.Ref1.nTab = aBkp.Ref1.nTab;
+ rRef.Ref1.nRelTab = aBkp.Ref1.nRelTab;
+ rRef.Ref1.SetTabDeleted( aBkp.Ref1.IsTabDeleted() );
+ }
+ if ( t->GetType() == svDoubleRef )
+ {
+ if ( !aBkp.Ref2.IsColRel() )
+ {
+ rRef.Ref2.nCol = aBkp.Ref2.nCol;
+ rRef.Ref2.nRelCol = aBkp.Ref2.nRelCol;
+ rRef.Ref2.SetColDeleted( aBkp.Ref2.IsColDeleted() );
+ }
+ if ( !aBkp.Ref2.IsRowRel() )
+ {
+ rRef.Ref2.nRow = aBkp.Ref2.nRow;
+ rRef.Ref2.nRelRow = aBkp.Ref2.nRelRow;
+ rRef.Ref2.SetRowDeleted( aBkp.Ref2.IsRowDeleted() );
+ }
+ if ( !aBkp.Ref2.IsTabRel() )
+ {
+ rRef.Ref2.nTab = aBkp.Ref2.nTab;
+ rRef.Ref2.nRelTab = aBkp.Ref2.nRelTab;
+ rRef.Ref2.SetTabDeleted( aBkp.Ref2.IsTabDeleted() );
+ }
+ }
+ }
+ }
+ }
+}
+
+
+ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, BOOL bIsName )
+{
+ ScRangeData* pRangeData = NULL;
+ SCTAB nPosTab = aPos.Tab(); // _after_ incremented!
+ SCTAB nOldPosTab = ((nPosTab > nTable) ? (nPosTab - 1) : nPosTab);
+ BOOL bIsRel = FALSE;
+ ScToken* t;
+ pArr->Reset();
+ if (bIsName)
+ t = static_cast<ScToken*>(pArr->GetNextReference());
+ else
+ t = static_cast<ScToken*>(pArr->GetNextReferenceOrName());
+ while( t )
+ {
+ if( t->GetOpCode() == ocName )
+ {
+ if (!bIsName)
+ {
+ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex());
+ if (pName && pName->HasType(RT_SHAREDMOD))
+ pRangeData = pName;
+ }
+ }
+ else if( t->GetType() != svIndex ) // it may be a DB area!!!
+ {
+ if ( !(bIsName && t->GetSingleRef().IsTabRel()) )
+ { // of names only adjust absolute references
+ ScSingleRefData& rRef = t->GetSingleRef();
+ if ( rRef.IsTabRel() )
+ {
+ rRef.nTab = rRef.nRelTab + nOldPosTab;
+ if ( rRef.nTab < 0 )
+ rRef.nTab = sal::static_int_cast<SCsTAB>( rRef.nTab + pDoc->GetTableCount() ); // was a wrap
+ }
+ if (nTable <= rRef.nTab)
+ ++rRef.nTab;
+ rRef.nRelTab = rRef.nTab - nPosTab;
+ }
+ else
+ bIsRel = TRUE;
+ if ( t->GetType() == svDoubleRef )
+ {
+ if ( !(bIsName && t->GetDoubleRef().Ref2.IsTabRel()) )
+ { // of names only adjust absolute references
+ ScSingleRefData& rRef = t->GetDoubleRef().Ref2;
+ if ( rRef.IsTabRel() )
+ {
+ rRef.nTab = rRef.nRelTab + nOldPosTab;
+ if ( rRef.nTab < 0 )
+ rRef.nTab = sal::static_int_cast<SCsTAB>( rRef.nTab + pDoc->GetTableCount() ); // was a wrap
+ }
+ if (nTable <= rRef.nTab)
+ ++rRef.nTab;
+ rRef.nRelTab = rRef.nTab - nPosTab;
+ }
+ else
+ bIsRel = TRUE;
+ }
+ if ( bIsName && bIsRel )
+ pRangeData = (ScRangeData*) this; // not dereferenced in rangenam
+ }
+ if (bIsName)
+ t = static_cast<ScToken*>(pArr->GetNextReference());
+ else
+ t = static_cast<ScToken*>(pArr->GetNextReferenceOrName());
+ }
+ if ( !bIsName )
+ {
+ pArr->Reset();
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+ {
+ if ( t->GetRef() == 1 )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( !(rRef1.IsRelName() && rRef1.IsTabRel()) )
+ { // of names only adjust absolute references
+ if ( rRef1.IsTabRel() )
+ {
+ rRef1.nTab = rRef1.nRelTab + nOldPosTab;
+ if ( rRef1.nTab < 0 )
+ rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + pDoc->GetTableCount() ); // was a wrap
+ }
+ if (nTable <= rRef1.nTab)
+ ++rRef1.nTab;
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ }
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( !(rRef2.IsRelName() && rRef2.IsTabRel()) )
+ { // of names only adjust absolute references
+ if ( rRef2.IsTabRel() )
+ {
+ rRef2.nTab = rRef2.nRelTab + nOldPosTab;
+ if ( rRef2.nTab < 0 )
+ rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + pDoc->GetTableCount() ); // was a wrap
+ }
+ if (nTable <= rRef2.nTab)
+ ++rRef2.nTab;
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ }
+ }
+ }
+ }
+ }
+ return pRangeData;
+}
+
+ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, BOOL /* bIsMove */, BOOL bIsName,
+ BOOL& rChanged)
+{
+ ScRangeData* pRangeData = NULL;
+ SCTAB nTab, nTab2;
+ SCTAB nPosTab = aPos.Tab(); // _after_ decremented!
+ SCTAB nOldPosTab = ((nPosTab >= nTable) ? (nPosTab + 1) : nPosTab);
+ rChanged = FALSE;
+ BOOL bIsRel = FALSE;
+ ScToken* t;
+ pArr->Reset();
+ if (bIsName)
+ t = static_cast<ScToken*>(pArr->GetNextReference());
+ else
+ t = static_cast<ScToken*>(pArr->GetNextReferenceOrName());
+ while( t )
+ {
+ if( t->GetOpCode() == ocName )
+ {
+ if (!bIsName)
+ {
+ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex());
+ if (pName && pName->HasType(RT_SHAREDMOD))
+ pRangeData = pName;
+ }
+ rChanged = TRUE;
+ }
+ else if( t->GetType() != svIndex ) // it may be a DB area!!!
+ {
+ if ( !(bIsName && t->GetSingleRef().IsTabRel()) )
+ { // of names only adjust absolute references
+ ScSingleRefData& rRef = t->GetSingleRef();
+ if ( rRef.IsTabRel() )
+ nTab = rRef.nTab = rRef.nRelTab + nOldPosTab;
+ else
+ nTab = rRef.nTab;
+ if ( nTable < nTab )
+ {
+ rRef.nTab = nTab - 1;
+ rChanged = TRUE;
+ }
+ else if ( nTable == nTab )
+ {
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsTabRel() )
+ nTab2 = rRef2.nRelTab + nOldPosTab;
+ else
+ nTab2 = rRef2.nTab;
+ if ( nTab == nTab2
+ || (nTab+1) >= pDoc->GetTableCount() )
+ {
+ rRef.nTab = MAXTAB+1;
+ rRef.SetTabDeleted( TRUE );
+ }
+ // else: nTab later points to what's nTable+1 now
+ // => area shrunk
+ }
+ else
+ {
+ rRef.nTab = MAXTAB+1;
+ rRef.SetTabDeleted( TRUE );
+ }
+ rChanged = TRUE;
+ }
+ rRef.nRelTab = rRef.nTab - nPosTab;
+ }
+ else
+ bIsRel = TRUE;
+ if ( t->GetType() == svDoubleRef )
+ {
+ if ( !(bIsName && t->GetDoubleRef().Ref2.IsTabRel()) )
+ { // of names only adjust absolute references
+ ScSingleRefData& rRef = t->GetDoubleRef().Ref2;
+ if ( rRef.IsTabRel() )
+ nTab = rRef.nTab = rRef.nRelTab + nOldPosTab;
+ else
+ nTab = rRef.nTab;
+ if ( nTable < nTab )
+ {
+ rRef.nTab = nTab - 1;
+ rChanged = TRUE;
+ }
+ else if ( nTable == nTab )
+ {
+ if ( !t->GetDoubleRef().Ref1.IsTabDeleted() )
+ rRef.nTab = nTab - 1; // shrink area
+ else
+ {
+ rRef.nTab = MAXTAB+1;
+ rRef.SetTabDeleted( TRUE );
+ }
+ rChanged = TRUE;
+ }
+ rRef.nRelTab = rRef.nTab - nPosTab;
+ }
+ else
+ bIsRel = TRUE;
+ }
+ if ( bIsName && bIsRel )
+ pRangeData = (ScRangeData*) this; // not dereferenced in rangenam
+ }
+ if (bIsName)
+ t = static_cast<ScToken*>(pArr->GetNextReference());
+ else
+ t = static_cast<ScToken*>(pArr->GetNextReferenceOrName());
+ }
+ if ( !bIsName )
+ {
+ pArr->Reset();
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+ {
+ if ( t->GetRef() == 1 )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( !(rRef1.IsRelName() && rRef1.IsTabRel()) )
+ { // of names only adjust absolute references
+ if ( rRef1.IsTabRel() )
+ nTab = rRef1.nTab = rRef1.nRelTab + nOldPosTab;
+ else
+ nTab = rRef1.nTab;
+ if ( nTable < nTab )
+ {
+ rRef1.nTab = nTab - 1;
+ rChanged = TRUE;
+ }
+ else if ( nTable == nTab )
+ {
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsTabRel() )
+ nTab2 = rRef2.nRelTab + nOldPosTab;
+ else
+ nTab2 = rRef2.nTab;
+ if ( nTab == nTab2
+ || (nTab+1) >= pDoc->GetTableCount() )
+ {
+ rRef1.nTab = MAXTAB+1;
+ rRef1.SetTabDeleted( TRUE );
+ }
+ // else: nTab later points to what's nTable+1 now
+ // => area shrunk
+ }
+ else
+ {
+ rRef1.nTab = MAXTAB+1;
+ rRef1.SetTabDeleted( TRUE );
+ }
+ rChanged = TRUE;
+ }
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ }
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( !(rRef2.IsRelName() && rRef2.IsTabRel()) )
+ { // of names only adjust absolute references
+ if ( rRef2.IsTabRel() )
+ nTab = rRef2.nTab = rRef2.nRelTab + nOldPosTab;
+ else
+ nTab = rRef2.nTab;
+ if ( nTable < nTab )
+ {
+ rRef2.nTab = nTab - 1;
+ rChanged = TRUE;
+ }
+ else if ( nTable == nTab )
+ {
+ if ( !rRef1.IsTabDeleted() )
+ rRef2.nTab = nTab - 1; // shrink area
+ else
+ {
+ rRef2.nTab = MAXTAB+1;
+ rRef2.SetTabDeleted( TRUE );
+ }
+ rChanged = TRUE;
+ }
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ }
+ }
+ }
+ }
+ }
+ return pRangeData;
+}
+
+// aPos.Tab() must be already adjusted!
+ScRangeData* ScCompiler::UpdateMoveTab( SCTAB nOldTab, SCTAB nNewTab,
+ BOOL bIsName )
+{
+ ScRangeData* pRangeData = NULL;
+ SCsTAB nTab;
+
+ SCTAB nStart, nEnd;
+ short nDir; // direction in which others move
+ if ( nOldTab < nNewTab )
+ {
+ nDir = -1;
+ nStart = nOldTab;
+ nEnd = nNewTab;
+ }
+ else
+ {
+ nDir = 1;
+ nStart = nNewTab;
+ nEnd = nOldTab;
+ }
+ SCTAB nPosTab = aPos.Tab(); // current sheet
+ SCTAB nOldPosTab; // previously it was this one
+ if ( nPosTab == nNewTab )
+ nOldPosTab = nOldTab; // look, it's me!
+ else if ( nPosTab < nStart || nEnd < nPosTab )
+ nOldPosTab = nPosTab; // wasn't moved
+ else
+ nOldPosTab = nPosTab - nDir; // moved by one
+
+ BOOL bIsRel = FALSE;
+ ScToken* t;
+ pArr->Reset();
+ if (bIsName)
+ t = static_cast<ScToken*>(pArr->GetNextReference());
+ else
+ t = static_cast<ScToken*>(pArr->GetNextReferenceOrName());
+ while( t )
+ {
+ if( t->GetOpCode() == ocName )
+ {
+ if (!bIsName)
+ {
+ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex());
+ if (pName && pName->HasType(RT_SHAREDMOD))
+ pRangeData = pName;
+ }
+ }
+ else if( t->GetType() != svIndex ) // it may be a DB area!!!
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( !(bIsName && rRef1.IsTabRel()) )
+ { // of names only adjust absolute references
+ if ( rRef1.IsTabRel() )
+ nTab = rRef1.nRelTab + nOldPosTab;
+ else
+ nTab = rRef1.nTab;
+ if ( nTab == nOldTab )
+ rRef1.nTab = nNewTab;
+ else if ( nStart <= nTab && nTab <= nEnd )
+ rRef1.nTab = nTab + nDir;
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ }
+ else
+ bIsRel = TRUE;
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( !(bIsName && rRef2.IsTabRel()) )
+ { // of names only adjust absolute references
+ if ( rRef2.IsTabRel() )
+ nTab = rRef2.nRelTab + nOldPosTab;
+ else
+ nTab = rRef2.nTab;
+ if ( nTab == nOldTab )
+ rRef2.nTab = nNewTab;
+ else if ( nStart <= nTab && nTab <= nEnd )
+ rRef2.nTab = nTab + nDir;
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ }
+ else
+ bIsRel = TRUE;
+ SCsTAB nTab1, nTab2;
+ if ( rRef1.IsTabRel() )
+ nTab1 = rRef1.nRelTab + nPosTab;
+ else
+ nTab1 = rRef1.nTab;
+ if ( rRef2.IsTabRel() )
+ nTab2 = rRef2.nRelTab + nPosTab;
+ else
+ nTab2 = rRef1.nTab;
+ if ( nTab2 < nTab1 )
+ { // PutInOrder
+ rRef1.nTab = nTab2;
+ rRef2.nTab = nTab1;
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ }
+ }
+ if ( bIsName && bIsRel )
+ pRangeData = (ScRangeData*) this; // not dereferenced in rangenam
+ }
+ if (bIsName)
+ t = static_cast<ScToken*>(pArr->GetNextReference());
+ else
+ t = static_cast<ScToken*>(pArr->GetNextReferenceOrName());
+ }
+ if ( !bIsName )
+ {
+ SCsTAB nMaxTabMod = (SCsTAB) pDoc->GetTableCount();
+ pArr->Reset();
+ while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+ {
+ if ( t->GetRef() == 1 )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsRelName() && rRef1.IsTabRel() )
+ { // possibly wrap RelName, like lcl_MoveItWrap in refupdat.cxx
+ nTab = rRef1.nRelTab + nPosTab;
+ if ( nTab < 0 )
+ nTab = sal::static_int_cast<SCsTAB>( nTab + nMaxTabMod );
+ else if ( nTab > nMaxTab )
+ nTab = sal::static_int_cast<SCsTAB>( nTab - nMaxTabMod );
+ rRef1.nRelTab = nTab - nPosTab;
+ }
+ else
+ {
+ if ( rRef1.IsTabRel() )
+ nTab = rRef1.nRelTab + nOldPosTab;
+ else
+ nTab = rRef1.nTab;
+ if ( nTab == nOldTab )
+ rRef1.nTab = nNewTab;
+ else if ( nStart <= nTab && nTab <= nEnd )
+ rRef1.nTab = nTab + nDir;
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ }
+ if( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsRelName() && rRef2.IsTabRel() )
+ { // possibly wrap RelName, like lcl_MoveItWrap in refupdat.cxx
+ nTab = rRef2.nRelTab + nPosTab;
+ if ( nTab < 0 )
+ nTab = sal::static_int_cast<SCsTAB>( nTab + nMaxTabMod );
+ else if ( nTab > nMaxTab )
+ nTab = sal::static_int_cast<SCsTAB>( nTab - nMaxTabMod );
+ rRef2.nRelTab = nTab - nPosTab;
+ }
+ else
+ {
+ if ( rRef2.IsTabRel() )
+ nTab = rRef2.nRelTab + nOldPosTab;
+ else
+ nTab = rRef2.nTab;
+ if ( nTab == nOldTab )
+ rRef2.nTab = nNewTab;
+ else if ( nStart <= nTab && nTab <= nEnd )
+ rRef2.nTab = nTab + nDir;
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ }
+ SCsTAB nTab1, nTab2;
+ if ( rRef1.IsTabRel() )
+ nTab1 = rRef1.nRelTab + nPosTab;
+ else
+ nTab1 = rRef1.nTab;
+ if ( rRef2.IsTabRel() )
+ nTab2 = rRef2.nRelTab + nPosTab;
+ else
+ nTab2 = rRef1.nTab;
+ if ( nTab2 < nTab1 )
+ { // PutInOrder
+ rRef1.nTab = nTab2;
+ rRef2.nTab = nTab1;
+ rRef1.nRelTab = rRef1.nTab - nPosTab;
+ rRef2.nRelTab = rRef2.nTab - nPosTab;
+ }
+ }
+ }
+ }
+ }
+ return pRangeData;
+}
+
+
+void ScCompiler::CreateStringFromExternal(rtl::OUStringBuffer& rBuffer, FormulaToken* pTokenP)
+{
+ FormulaToken* t = pTokenP;
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ switch (t->GetType())
+ {
+ case svExternalName:
+ {
+ const String *pStr = pRefMgr->getExternalFileName(t->GetIndex());
+ String aFileName = pStr ? *pStr : ScGlobal::GetRscString(STR_NO_NAME_REF);
+ rBuffer.append(pConv->makeExternalNameStr( aFileName, t->GetString()));
+ }
+ break;
+ case svExternalSingleRef:
+ pConv->makeExternalRefStr(
+ rBuffer, *this, t->GetIndex(), t->GetString(), static_cast<ScToken*>(t)->GetSingleRef(), pRefMgr);
+ break;
+ case svExternalDoubleRef:
+ pConv->makeExternalRefStr(
+ rBuffer, *this, t->GetIndex(), t->GetString(), static_cast<ScToken*>(t)->GetDoubleRef(), pRefMgr);
+ break;
+ default:
+ // warning, not error, otherwise we may end up with a never
+ // ending message box loop if this was the cursor cell to be redrawn.
+ DBG_WARNING("ScCompiler::CreateStringFromToken: unknown type of ocExternalRef");
+ }
+}
+
+void ScCompiler::CreateStringFromMatrix( rtl::OUStringBuffer& rBuffer,
+ FormulaToken* pTokenP)
+{
+ const ScMatrix* pMatrix = static_cast<ScToken*>(pTokenP)->GetMatrix();
+ SCSIZE nC, nMaxC, nR, nMaxR;
+
+ pMatrix->GetDimensions( nMaxC, nMaxR);
+
+ rBuffer.append( mxSymbols->getSymbol(ocArrayOpen) );
+ for( nR = 0 ; nR < nMaxR ; nR++)
+ {
+ if( nR > 0)
+ {
+ rBuffer.append( mxSymbols->getSymbol(ocArrayRowSep) );
+ }
+
+ for( nC = 0 ; nC < nMaxC ; nC++)
+ {
+ if( nC > 0)
+ {
+ rBuffer.append( mxSymbols->getSymbol(ocArrayColSep) );
+ }
+
+ if( pMatrix->IsValue( nC, nR ) )
+ {
+ ScMatValType nType;
+ const ScMatrixValue* pVal = pMatrix->Get( nC, nR, nType);
+
+ if( nType == SC_MATVAL_BOOLEAN )
+ AppendBoolean( rBuffer, pVal->GetBoolean() );
+ else
+ {
+ USHORT nErr = pVal->GetError();
+ if( nErr )
+ rBuffer.append( ScGlobal::GetErrorString( nErr ) );
+ else
+ AppendDouble( rBuffer, pVal->fVal );
+ }
+ }
+ else if( pMatrix->IsEmpty( nC, nR ) )
+ ;
+ else if( pMatrix->IsString( nC, nR ) )
+ AppendString( rBuffer, pMatrix->GetString( nC, nR ) );
+ }
+ }
+ rBuffer.append( mxSymbols->getSymbol(ocArrayClose) );
+}
+
+void ScCompiler::CreateStringFromSingleRef(rtl::OUStringBuffer& rBuffer,FormulaToken* _pTokenP)
+{
+ const OpCode eOp = _pTokenP->GetOpCode();
+ ScSingleRefData& rRef = static_cast<ScToken*>(_pTokenP)->GetSingleRef();
+ ScComplexRefData aRef;
+ aRef.Ref1 = aRef.Ref2 = rRef;
+ if ( eOp == ocColRowName )
+ {
+ rRef.CalcAbsIfRel( aPos );
+ if ( pDoc->HasStringData( rRef.nCol, rRef.nRow, rRef.nTab ) )
+ {
+ String aStr;
+ pDoc->GetString( rRef.nCol, rRef.nRow, rRef.nTab, aStr );
+ EnQuote( aStr );
+ rBuffer.append(aStr);
+ }
+ else
+ {
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
+ pConv->MakeRefStr (rBuffer, *this, aRef, TRUE );
+ }
+ }
+ else
+ pConv->MakeRefStr( rBuffer, *this, aRef, TRUE );
+}
+// -----------------------------------------------------------------------------
+void ScCompiler::CreateStringFromDoubleRef(rtl::OUStringBuffer& rBuffer,FormulaToken* _pTokenP)
+{
+ pConv->MakeRefStr( rBuffer, *this, static_cast<ScToken*>(_pTokenP)->GetDoubleRef(), FALSE );
+}
+// -----------------------------------------------------------------------------
+void ScCompiler::CreateStringFromIndex(rtl::OUStringBuffer& rBuffer,FormulaToken* _pTokenP)
+{
+ const OpCode eOp = _pTokenP->GetOpCode();
+ rtl::OUStringBuffer aBuffer;
+ switch ( eOp )
+ {
+ case ocName:
+ {
+ ScRangeData* pData = pDoc->GetRangeName()->FindIndex(_pTokenP->GetIndex());
+ if (pData)
+ {
+ if (pData->HasType(RT_SHARED))
+ pData->UpdateSymbol( aBuffer, aPos, GetGrammar());
+ else
+ aBuffer.append(pData->GetName());
+ }
+ }
+ break;
+ case ocDBArea:
+ {
+ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex(_pTokenP->GetIndex());
+ if (pDBData)
+ aBuffer.append(pDBData->GetName());
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ if ( aBuffer.getLength() )
+ rBuffer.append(aBuffer);
+ else
+ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
+}
+// -----------------------------------------------------------------------------
+void ScCompiler::LocalizeString( String& rName )
+{
+ ScGlobal::GetAddInCollection()->LocalizeString( rName );
+}
+// -----------------------------------------------------------------------------
+BOOL ScCompiler::IsImportingXML() const
+{
+ return pDoc->IsImportingXML();
+}
+
+// Put quotes around string if non-alphanumeric characters are contained,
+// quote characters contained within are escaped by '\\'.
+BOOL ScCompiler::EnQuote( String& rStr )
+{
+ sal_Int32 nType = ScGlobal::pCharClass->getStringType( rStr, 0, rStr.Len() );
+ if ( !CharClass::isNumericType( nType )
+ && CharClass::isAlphaNumericType( nType ) )
+ return FALSE;
+
+ xub_StrLen nPos = 0;
+ while ( (nPos = rStr.Search( '\'', nPos)) != STRING_NOTFOUND )
+ {
+ rStr.Insert( '\\', nPos );
+ nPos += 2;
+ }
+ rStr.Insert( '\'', 0 );
+ 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.
+ sheet::FormulaOpCodeMapEntry aEntry;
+ aEntry.Token.OpCode = ocExternal;
+
+ ScUnoAddInCollection* pColl = ScGlobal::GetAddInCollection();
+ const long nCount = pColl->GetFuncCount();
+ for (long i=0; i < nCount; ++i)
+ {
+ const ScUnoAddInFuncData* pFuncData = pColl->GetFuncData(i);
+ if (pFuncData)
+ {
+ if ( _bIsEnglish )
+ {
+ String aName;
+ if (pFuncData->GetExcelName( LANGUAGE_ENGLISH_US, aName))
+ aEntry.Name = aName;
+ else
+ aEntry.Name = pFuncData->GetUpperName();
+ }
+ else
+ aEntry.Name = pFuncData->GetUpperLocal();
+ aEntry.Token.Data <<= ::rtl::OUString( pFuncData->GetOriginalName());
+ _rVec.push_back( aEntry);
+ }
+ }
+ // FIXME: what about those old non-UNO AddIns?
+}
+// -----------------------------------------------------------------------------
+BOOL ScCompiler::HandleSingleRef()
+{
+ ScSingleRefData& rRef = static_cast<ScToken*>((FormulaToken*)pToken)->GetSingleRef();
+ rRef.CalcAbsIfRel( aPos );
+ if ( !rRef.Valid() )
+ {
+ SetError( errNoRef );
+ return TRUE;
+ }
+ SCCOL nCol = rRef.nCol;
+ SCROW nRow = rRef.nRow;
+ SCTAB nTab = rRef.nTab;
+ ScAddress aLook( nCol, nRow, nTab );
+ BOOL bColName = rRef.IsColRel();
+ SCCOL nMyCol = aPos.Col();
+ SCROW nMyRow = aPos.Row();
+ BOOL bInList = FALSE;
+ BOOL bValidName = FALSE;
+ ScRangePairList* pRL = (bColName ?
+ pDoc->GetColNameRanges() : pDoc->GetRowNameRanges());
+ ScRange aRange;
+ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() )
+ {
+ if ( pR->GetRange(0).In( aLook ) )
+ {
+ bInList = bValidName = TRUE;
+ aRange = pR->GetRange(1);
+ if ( bColName )
+ {
+ aRange.aStart.SetCol( nCol );
+ aRange.aEnd.SetCol( nCol );
+ }
+ else
+ {
+ aRange.aStart.SetRow( nRow );
+ aRange.aEnd.SetRow( nRow );
+ }
+ break; // for
+ }
+ }
+ if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() )
+ { // automagically or created by copying and NamePos isn't in list
+ BOOL bString = pDoc->HasStringData( nCol, nRow, nTab );
+ if ( !bString && !pDoc->GetCell( aLook ) )
+ bString = TRUE; // empty cell is ok
+ if ( bString )
+ { //! coresponds with ScInterpreter::ScColRowNameAuto()
+ bValidName = TRUE;
+ if ( bColName )
+ { // ColName
+ SCROW nStartRow = nRow + 1;
+ if ( nStartRow > MAXROW )
+ nStartRow = MAXROW;
+ SCROW nMaxRow = MAXROW;
+ if ( nMyCol == nCol )
+ { // formula cell in same column
+ if ( nMyRow == nStartRow )
+ { // take remainder under name cell
+ nStartRow++;
+ if ( nStartRow > MAXROW )
+ nStartRow = MAXROW;
+ }
+ else if ( nMyRow > nStartRow )
+ { // from name cell down to formula cell
+ nMaxRow = nMyRow - 1;
+ }
+ }
+ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() )
+ { // next defined ColNameRange below limits row
+ const ScRange& rRange = pR->GetRange(1);
+ if ( rRange.aStart.Col() <= nCol && nCol <= rRange.aEnd.Col() )
+ { // identical column range
+ SCROW nTmp = rRange.aStart.Row();
+ if ( nStartRow < nTmp && nTmp <= nMaxRow )
+ nMaxRow = nTmp - 1;
+ }
+ }
+ aRange.aStart.Set( nCol, nStartRow, nTab );
+ aRange.aEnd.Set( nCol, nMaxRow, nTab );
+ }
+ else
+ { // RowName
+ SCCOL nStartCol = nCol + 1;
+ if ( nStartCol > MAXCOL )
+ nStartCol = MAXCOL;
+ SCCOL nMaxCol = MAXCOL;
+ if ( nMyRow == nRow )
+ { // formula cell in same row
+ if ( nMyCol == nStartCol )
+ { // take remainder right from name cell
+ nStartCol++;
+ if ( nStartCol > MAXCOL )
+ nStartCol = MAXCOL;
+ }
+ else if ( nMyCol > nStartCol )
+ { // from name cell right to formula cell
+ nMaxCol = nMyCol - 1;
+ }
+ }
+ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() )
+ { // next defined RowNameRange to the right limits column
+ const ScRange& rRange = pR->GetRange(1);
+ if ( rRange.aStart.Row() <= nRow && nRow <= rRange.aEnd.Row() )
+ { // identical row range
+ SCCOL nTmp = rRange.aStart.Col();
+ if ( nStartCol < nTmp && nTmp <= nMaxCol )
+ nMaxCol = nTmp - 1;
+ }
+ }
+ aRange.aStart.Set( nStartCol, nRow, nTab );
+ aRange.aEnd.Set( nMaxCol, nRow, nTab );
+ }
+ }
+ }
+ if ( bValidName )
+ {
+ // And now the magic to distinguish between a range and a single
+ // cell thereof, which is picked position-dependent of the formula
+ // cell. If a direct neighbor is a binary operator (ocAdd, ...) a
+ // SingleRef matching the column/row of the formula cell is
+ // generated. A ocColRowName or ocIntersect as a neighbor results
+ // in a range. Special case: if label is valid for a single cell, a
+ // position independent SingleRef is generated.
+ BOOL bSingle = (aRange.aStart == aRange.aEnd);
+ BOOL bFound;
+ if ( bSingle )
+ bFound = TRUE;
+ else
+ {
+ FormulaToken* p1 = pArr->PeekPrevNoSpaces();
+ FormulaToken* p2 = pArr->PeekNextNoSpaces();
+ // begin/end of a formula => single
+ OpCode eOp1 = p1 ? p1->GetOpCode() : static_cast<OpCode>( ocAdd );
+ OpCode eOp2 = p2 ? p2->GetOpCode() : static_cast<OpCode>( ocAdd );
+ if ( eOp1 != ocColRowName && eOp1 != ocIntersect
+ && eOp2 != ocColRowName && eOp2 != ocIntersect )
+ {
+ if ( (SC_OPCODE_START_BIN_OP <= eOp1 && eOp1 < SC_OPCODE_STOP_BIN_OP) ||
+ (SC_OPCODE_START_BIN_OP <= eOp2 && eOp2 < SC_OPCODE_STOP_BIN_OP))
+ bSingle = TRUE;
+ }
+ if ( bSingle )
+ { // column and/or row must match range
+ if ( bColName )
+ {
+ bFound = (aRange.aStart.Row() <= nMyRow
+ && nMyRow <= aRange.aEnd.Row());
+ if ( bFound )
+ aRange.aStart.SetRow( nMyRow );
+ }
+ else
+ {
+ bFound = (aRange.aStart.Col() <= nMyCol
+ && nMyCol <= aRange.aEnd.Col());
+ if ( bFound )
+ aRange.aStart.SetCol( nMyCol );
+ }
+ }
+ else
+ bFound = TRUE;
+ }
+ if ( !bFound )
+ SetError(errNoRef);
+ else if ( !bCompileForFAP )
+ {
+ ScTokenArray* pNew = new ScTokenArray();
+ if ( bSingle )
+ {
+ ScSingleRefData aRefData;
+ aRefData.InitAddress( aRange.aStart );
+ if ( bColName )
+ aRefData.SetColRel( TRUE );
+ else
+ aRefData.SetRowRel( TRUE );
+ aRefData.CalcRelFromAbs( aPos );
+ pNew->AddSingleReference( aRefData );
+ }
+ else
+ {
+ ScComplexRefData aRefData;
+ aRefData.InitRange( aRange );
+ if ( bColName )
+ {
+ aRefData.Ref1.SetColRel( TRUE );
+ aRefData.Ref2.SetColRel( TRUE );
+ }
+ else
+ {
+ aRefData.Ref1.SetRowRel( TRUE );
+ aRefData.Ref2.SetRowRel( TRUE );
+ }
+ aRefData.CalcRelFromAbs( aPos );
+ if ( bInList )
+ pNew->AddDoubleReference( aRefData );
+ else
+ { // automagically
+ pNew->Add( new ScDoubleRefToken( aRefData, ocColRowNameAuto ) );
+ }
+ }
+ PushTokenArray( pNew, TRUE );
+ pNew->Reset();
+ return GetToken();
+ }
+ }
+ else
+ SetError(errNoName);
+ return TRUE;
+}
+// -----------------------------------------------------------------------------
+BOOL ScCompiler::HandleDbData()
+{
+ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex( pToken->GetIndex() );
+ if ( !pDBData )
+ SetError(errNoName);
+ else if ( !bCompileForFAP )
+ {
+ ScComplexRefData aRefData;
+ aRefData.InitFlags();
+ pDBData->GetArea( (SCTAB&) aRefData.Ref1.nTab,
+ (SCCOL&) aRefData.Ref1.nCol,
+ (SCROW&) aRefData.Ref1.nRow,
+ (SCCOL&) aRefData.Ref2.nCol,
+ (SCROW&) aRefData.Ref2.nRow);
+ aRefData.Ref2.nTab = aRefData.Ref1.nTab;
+ aRefData.CalcRelFromAbs( aPos );
+ ScTokenArray* pNew = new ScTokenArray();
+ pNew->AddDoubleReference( aRefData );
+ PushTokenArray( pNew, TRUE );
+ pNew->Reset();
+ return GetToken();
+ }
+ return TRUE;
+}
+
+String GetScCompilerNativeSymbol( OpCode eOp )
+{
+ return ScCompiler::GetNativeSymbol( eOp );
+}
+// -----------------------------------------------------------------------------
+FormulaTokenRef ScCompiler::ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2, bool bReuseDoubleRef )
+{
+ return ScToken::ExtendRangeReference( rTok1, rTok2, aPos,bReuseDoubleRef );
+}
diff --git a/sc/source/core/tool/consoli.cxx b/sc/source/core/tool/consoli.cxx
new file mode 100644
index 000000000000..addd92082cfd
--- /dev/null
+++ b/sc/source/core/tool/consoli.cxx
@@ -0,0 +1,858 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+
+#include "consoli.hxx"
+#include "document.hxx"
+#include "olinetab.hxx"
+#include "globstr.hrc"
+#include "subtotal.hxx"
+#include "formula/errorcodes.hxx"
+#include "cell.hxx"
+
+#include <math.h>
+#include <string.h>
+
+#define SC_CONS_NOTFOUND -1
+
+// STATIC DATA -----------------------------------------------------------
+
+/* Strings bei Gelegenheit ganz raus...
+static USHORT nFuncRes[] = { // Reihenfolge wie bei enum ScSubTotalFunc
+ 0, // none
+ STR_PIVOTFUNC_AVG,
+ STR_PIVOTFUNC_COUNT,
+ STR_PIVOTFUNC_COUNT2,
+ STR_PIVOTFUNC_MAX,
+ STR_PIVOTFUNC_MIN,
+ STR_PIVOTFUNC_PROD,
+ STR_PIVOTFUNC_STDDEV,
+ STR_PIVOTFUNC_STDDEV2,
+ STR_PIVOTFUNC_SUM,
+ STR_PIVOTFUNC_VAR,
+ STR_PIVOTFUNC_VAR2 };
+*/
+
+static OpCode eOpCodeTable[] = { // Reihenfolge wie bei enum ScSubTotalFunc
+ ocBad, // none
+ ocAverage,
+ ocCount,
+ ocCount2,
+ ocMax,
+ ocMin,
+ ocProduct,
+ ocStDev,
+ ocStDevP,
+ ocSum,
+ ocVar,
+ ocVarP };
+
+// -----------------------------------------------------------------------
+
+void ScReferenceList::AddEntry( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ ScReferenceEntry* pOldData = pData;
+ pData = new ScReferenceEntry[ nFullSize+1 ];
+ if (pOldData)
+ {
+ memmove( pData, pOldData, nCount * sizeof(ScReferenceEntry) );
+ delete[] pOldData;
+ }
+ while (nCount < nFullSize)
+ {
+ pData[nCount].nCol = SC_CONS_NOTFOUND;
+ pData[nCount].nRow = SC_CONS_NOTFOUND;
+ pData[nCount].nTab = SC_CONS_NOTFOUND;
+ ++nCount;
+ }
+ pData[nCount].nCol = nCol;
+ pData[nCount].nRow = nRow;
+ pData[nCount].nTab = nTab;
+ ++nCount;
+ nFullSize = nCount;
+}
+
+template< typename T >
+void lcl_AddString( String**& pData, T& nCount, const String& rInsert )
+{
+ String** pOldData = pData;
+ pData = new String*[ nCount+1 ];
+ if (pOldData)
+ {
+ memmove( pData, pOldData, nCount * sizeof(String*) );
+ delete[] pOldData;
+ }
+ pData[nCount] = new String(rInsert);
+ ++nCount;
+}
+
+// -----------------------------------------------------------------------
+
+ScConsData::ScConsData() :
+ eFunction(SUBTOTAL_FUNC_SUM),
+ bReference(FALSE),
+ bColByName(FALSE),
+ bRowByName(FALSE),
+ bSubTitles(FALSE),
+ nColCount(0),
+ nRowCount(0),
+ ppUsed(NULL),
+ ppSum(NULL),
+ ppCount(NULL),
+ ppSumSqr(NULL),
+ ppRefs(NULL),
+ ppColHeaders(NULL),
+ ppRowHeaders(NULL),
+ nDataCount(0),
+ nTitleCount(0),
+ ppTitles(NULL),
+ ppTitlePos(NULL),
+ bCornerUsed(FALSE)
+{
+}
+
+ScConsData::~ScConsData()
+{
+ DeleteData();
+}
+
+
+#define DELETEARR(ppArray,nCount) \
+{ \
+ ULONG i; \
+ if (ppArray) \
+ for(i=0; i<nCount; i++) \
+ delete[] ppArray[i]; \
+ delete[] ppArray; \
+ ppArray = NULL; \
+}
+
+#define DELETESTR(ppArray,nCount) \
+{ \
+ ULONG i; \
+ if (ppArray) \
+ for(i=0; i<nCount; i++) \
+ delete ppArray[i]; \
+ delete[] ppArray; \
+ ppArray = NULL; \
+}
+
+void ScConsData::DeleteData()
+{
+ if (ppRefs)
+ {
+ for (SCSIZE i=0; i<nColCount; i++)
+ {
+ for (SCSIZE j=0; j<nRowCount; j++)
+ if (ppUsed[i][j])
+ ppRefs[i][j].Clear();
+ delete[] ppRefs[i];
+ }
+ delete[] ppRefs;
+ ppRefs = NULL;
+ }
+
+// DELETEARR( ppData1, nColCount );
+// DELETEARR( ppData2, nColCount );
+ DELETEARR( ppCount, nColCount );
+ DELETEARR( ppSum, nColCount );
+ DELETEARR( ppSumSqr,nColCount );
+ DELETEARR( ppUsed, nColCount ); // erst nach ppRefs !!!
+ DELETEARR( ppTitlePos, nRowCount );
+ DELETESTR( ppColHeaders, nColCount );
+ DELETESTR( ppRowHeaders, nRowCount );
+ DELETESTR( ppTitles, nTitleCount );
+ nTitleCount = 0;
+ nDataCount = 0;
+
+ if (bColByName) nColCount = 0; // sonst stimmt ppColHeaders nicht
+ if (bRowByName) nRowCount = 0;
+
+ bCornerUsed = FALSE;
+ aCornerText.Erase();
+}
+
+#undef DELETEARR
+#undef DELETESTR
+
+void ScConsData::InitData( BOOL bDelete )
+{
+ if (bDelete)
+ DeleteData();
+
+ if (bReference && nColCount && !ppRefs)
+ {
+ ppRefs = new ScReferenceList*[nColCount];
+ for (SCSIZE i=0; i<nColCount; i++)
+ ppRefs[i] = new ScReferenceList[nRowCount];
+ }
+ else if (nColCount && !ppCount)
+ {
+ ppCount = new double*[nColCount];
+ ppSum = new double*[nColCount];
+ ppSumSqr = new double*[nColCount];
+ for (SCSIZE i=0; i<nColCount; i++)
+ {
+ ppCount[i] = new double[nRowCount];
+ ppSum[i] = new double[nRowCount];
+ ppSumSqr[i] = new double[nRowCount];
+ }
+ }
+
+ if (nColCount && !ppUsed)
+ {
+ ppUsed = new BOOL*[nColCount];
+ for (SCSIZE i=0; i<nColCount; i++)
+ {
+ ppUsed[i] = new BOOL[nRowCount];
+ memset( ppUsed[i], 0, nRowCount * sizeof(BOOL) );
+ }
+ }
+
+ if (nRowCount && nDataCount && !ppTitlePos)
+ {
+ ppTitlePos = new SCSIZE*[nRowCount];
+ for (SCSIZE i=0; i<nRowCount; i++)
+ {
+ ppTitlePos[i] = new SCSIZE[nDataCount];
+ memset( ppTitlePos[i], 0, nDataCount * sizeof(SCSIZE) ); //! unnoetig ?
+ }
+ }
+
+ // CornerText: einzelner String
+}
+
+void ScConsData::DoneFields()
+{
+ InitData(FALSE);
+}
+
+void ScConsData::SetSize( SCCOL nCols, SCROW nRows )
+{
+ DeleteData();
+ nColCount = static_cast<SCSIZE>(nCols);
+ nRowCount = static_cast<SCSIZE>(nRows);
+}
+
+void ScConsData::GetSize( SCCOL& rCols, SCROW& rRows ) const
+{
+ rCols = static_cast<SCCOL>(nColCount);
+ rRows = static_cast<SCROW>(nRowCount);
+}
+
+void ScConsData::SetFlags( ScSubTotalFunc eFunc, BOOL bColName, BOOL bRowName, BOOL bRef )
+{
+ DeleteData();
+ bReference = bRef;
+ bColByName = bColName;
+ if (bColName) nColCount = 0;
+ bRowByName = bRowName;
+ if (bRowName) nRowCount = 0;
+ eFunction = eFunc;
+}
+
+void ScConsData::AddFields( ScDocument* pSrcDoc, SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ ++nDataCount;
+
+ String aTitle;
+
+ SCCOL nStartCol = nCol1;
+ SCROW nStartRow = nRow1;
+ if (bColByName) ++nStartRow;
+ if (bRowByName) ++nStartCol;
+
+ if (bColByName)
+ {
+ for (SCCOL nCol=nStartCol; nCol<=nCol2; nCol++)
+ {
+ pSrcDoc->GetString( nCol, nRow1, nTab, aTitle );
+ if (aTitle.Len())
+ {
+ BOOL bFound = FALSE;
+ for (SCSIZE i=0; i<nColCount && !bFound; i++)
+ if ( *ppColHeaders[i] == aTitle )
+ bFound = TRUE;
+ if (!bFound)
+ lcl_AddString( ppColHeaders, nColCount, aTitle );
+ }
+ }
+ }
+
+ if (bRowByName)
+ {
+ for (SCROW nRow=nStartRow; nRow<=nRow2; nRow++)
+ {
+ pSrcDoc->GetString( nCol1, nRow, nTab, aTitle );
+ if (aTitle.Len())
+ {
+ BOOL bFound = FALSE;
+ for (SCSIZE i=0; i<nRowCount && !bFound; i++)
+ if ( *ppRowHeaders[i] == aTitle )
+ bFound = TRUE;
+ if (!bFound)
+ lcl_AddString( ppRowHeaders, nRowCount, aTitle );
+ }
+ }
+ }
+}
+
+void ScConsData::AddName( const String& rName )
+{
+ SCSIZE nArrX;
+ SCSIZE nArrY;
+
+ if (bReference)
+ {
+ lcl_AddString( ppTitles, nTitleCount, rName );
+
+ for (nArrY=0; nArrY<nRowCount; nArrY++)
+ {
+ // Daten auf gleiche Laenge bringen
+
+ SCSIZE nMax = 0;
+ for (nArrX=0; nArrX<nColCount; nArrX++)
+ if (ppUsed[nArrX][nArrY])
+ nMax = Max( nMax, ppRefs[nArrX][nArrY].GetCount() );
+
+ for (nArrX=0; nArrX<nColCount; nArrX++)
+ {
+ if (!ppUsed[nArrX][nArrY])
+ {
+ ppUsed[nArrX][nArrY] = TRUE;
+ ppRefs[nArrX][nArrY].Init();
+ }
+ ppRefs[nArrX][nArrY].SetFullSize(nMax);
+ }
+
+ // Positionen eintragen
+
+ if (ppTitlePos)
+ if (nTitleCount < nDataCount)
+ ppTitlePos[nArrY][nTitleCount] = nMax;
+ }
+ }
+}
+
+ // rCount < 0 <=> Fehler aufgetreten
+
+void lcl_UpdateArray( ScSubTotalFunc eFunc,
+ double& rCount, double& rSum, double& rSumSqr, double nVal )
+{
+ if (rCount < 0.0)
+ return;
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_SUM:
+ if (!SubTotal::SafePlus(rSum, nVal))
+ rCount = -MAXDOUBLE;
+ break;
+ case SUBTOTAL_FUNC_PROD:
+ if (!SubTotal::SafeMult(rSum, nVal))
+ rCount = -MAXDOUBLE;
+ break;
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2:
+ rCount += 1.0;
+ break;
+ case SUBTOTAL_FUNC_AVE:
+ if (!SubTotal::SafePlus(rSum, nVal))
+ rCount = -MAXDOUBLE;
+ else
+ rCount += 1.0;
+ break;
+ case SUBTOTAL_FUNC_MAX:
+ if (nVal > rSum)
+ rSum = nVal;
+ break;
+ case SUBTOTAL_FUNC_MIN:
+ if (nVal < rSum)
+ rSum = nVal;
+ break;
+ case SUBTOTAL_FUNC_STD:
+ case SUBTOTAL_FUNC_STDP:
+ case SUBTOTAL_FUNC_VAR:
+ case SUBTOTAL_FUNC_VARP:
+ {
+ BOOL bOk = SubTotal::SafePlus(rSum, nVal);
+ bOk = bOk && SubTotal::SafeMult(nVal, nVal);
+ bOk = bOk && SubTotal::SafePlus(rSumSqr, nVal);
+ if (!bOk)
+ rCount = -MAXDOUBLE;
+ else
+ rCount += 1.0;
+ break;
+ }
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+void lcl_InitArray( ScSubTotalFunc eFunc,
+ double& rCount, double& rSum, double& rSumSqr, double nVal )
+{
+ rCount = 1.0;
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_SUM:
+ case SUBTOTAL_FUNC_MAX:
+ case SUBTOTAL_FUNC_MIN:
+ case SUBTOTAL_FUNC_PROD:
+ case SUBTOTAL_FUNC_AVE:
+ rSum = nVal;
+ break;
+ case SUBTOTAL_FUNC_STD:
+ case SUBTOTAL_FUNC_STDP:
+ case SUBTOTAL_FUNC_VAR:
+ case SUBTOTAL_FUNC_VARP:
+ {
+ rSum = nVal;
+ BOOL bOk = SubTotal::SafeMult(nVal, nVal);
+ if (bOk)
+ rSumSqr = nVal;
+ else
+ rCount = -MAXDOUBLE;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+double lcl_CalcData( ScSubTotalFunc eFunc,
+ double fCount, double fSum, double fSumSqr)
+{
+ if (fCount < 0.0)
+ return 0.0;
+ double fVal = 0.0;
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_CNT:
+ case SUBTOTAL_FUNC_CNT2:
+ fVal = fCount;
+ break;
+ case SUBTOTAL_FUNC_SUM:
+ case SUBTOTAL_FUNC_MAX:
+ case SUBTOTAL_FUNC_MIN:
+ case SUBTOTAL_FUNC_PROD:
+ fVal = fSum;
+ break;
+ case SUBTOTAL_FUNC_AVE:
+ if (fCount > 0.0)
+ fVal = fSum / fCount;
+ else
+ fCount = -MAXDOUBLE;
+ break;
+ case SUBTOTAL_FUNC_STD:
+ {
+ if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
+ fVal = sqrt((fSumSqr - fSum/fCount)/(fCount-1.0));
+ else
+ fCount = -MAXDOUBLE;
+ }
+ break;
+ case SUBTOTAL_FUNC_STDP:
+ {
+ if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
+ fVal = sqrt((fSumSqr - fSum/fCount)/fCount);
+ else
+ fCount = -MAXDOUBLE;
+ }
+ break;
+ case SUBTOTAL_FUNC_VAR:
+ {
+ if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
+ fVal = (fSumSqr - fSum/fCount)/(fCount-1.0);
+ else
+ fCount = -MAXDOUBLE;
+ }
+ break;
+ case SUBTOTAL_FUNC_VARP:
+ {
+ if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
+ fVal = (fSumSqr - fSum/fCount)/fCount;
+ else
+ fCount = -MAXDOUBLE;
+ }
+ break;
+ default:
+ {
+ DBG_ERROR("unbekannte Funktion bei Consoli::CalcData");
+ fCount = -MAXDOUBLE;
+ }
+ break;
+ }
+ return fVal;
+}
+
+void ScConsData::AddData( ScDocument* pSrcDoc, SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ PutInOrder(nCol1,nCol2);
+ PutInOrder(nRow1,nRow2);
+ if ( nCol2 >= sal::static_int_cast<SCCOL>(nCol1 + nColCount) && !bColByName )
+ {
+ DBG_ASSERT(0,"Bereich zu gross");
+ nCol2 = sal::static_int_cast<SCCOL>( nCol1 + nColCount - 1 );
+ }
+ if ( nRow2 >= sal::static_int_cast<SCROW>(nRow1 + nRowCount) && !bRowByName )
+ {
+ DBG_ASSERT(0,"Bereich zu gross");
+ nRow2 = sal::static_int_cast<SCROW>( nRow1 + nRowCount - 1 );
+ }
+
+ SCCOL nCol;
+ SCROW nRow;
+
+ // Ecke links oben
+
+ if ( bColByName && bRowByName )
+ {
+ String aThisCorner;
+ pSrcDoc->GetString(nCol1,nRow1,nTab,aThisCorner);
+ if (bCornerUsed)
+ {
+ if (aCornerText != aThisCorner)
+ aCornerText.Erase();
+ }
+ else
+ {
+ aCornerText = aThisCorner;
+ bCornerUsed = TRUE;
+ }
+ }
+
+ // Titel suchen
+
+ SCCOL nStartCol = nCol1;
+ SCROW nStartRow = nRow1;
+ if (bColByName) ++nStartRow;
+ if (bRowByName) ++nStartCol;
+ String aTitle;
+ SCCOL* pDestCols = NULL;
+ SCROW* pDestRows = NULL;
+ if (bColByName)
+ {
+ pDestCols = new SCCOL[nCol2-nStartCol+1];
+ for (nCol=nStartCol; nCol<=nCol2; nCol++)
+ {
+ pSrcDoc->GetString(nCol,nRow1,nTab,aTitle);
+ SCCOL nPos = SC_CONS_NOTFOUND;
+ if (aTitle.Len())
+ {
+ BOOL bFound = FALSE;
+ for (SCSIZE i=0; i<nColCount && !bFound; i++)
+ if ( *ppColHeaders[i] == aTitle )
+ {
+ nPos = static_cast<SCCOL>(i);
+ bFound = TRUE;
+ }
+ DBG_ASSERT(bFound, "Spalte nicht gefunden");
+ }
+ pDestCols[nCol-nStartCol] = nPos;
+ }
+ }
+ if (bRowByName)
+ {
+ pDestRows = new SCROW[nRow2-nStartRow+1];
+ for (nRow=nStartRow; nRow<=nRow2; nRow++)
+ {
+ pSrcDoc->GetString(nCol1,nRow,nTab,aTitle);
+ SCROW nPos = SC_CONS_NOTFOUND;
+ if (aTitle.Len())
+ {
+ BOOL bFound = FALSE;
+ for (SCSIZE i=0; i<nRowCount && !bFound; i++)
+ if ( *ppRowHeaders[i] == aTitle )
+ {
+ nPos = static_cast<SCROW>(i);
+ bFound = TRUE;
+ }
+ DBG_ASSERT(bFound, "Zeile nicht gefunden");
+ }
+ pDestRows[nRow-nStartRow] = nPos;
+ }
+ }
+ nCol1 = nStartCol;
+ nRow1 = nStartRow;
+
+ // Daten
+
+ BOOL bAnyCell = ( eFunction == SUBTOTAL_FUNC_CNT2 );
+ for (nCol=nCol1; nCol<=nCol2; nCol++)
+ {
+ SCCOL nArrX = nCol-nCol1;
+ if (bColByName) nArrX = pDestCols[nArrX];
+ if (nArrX != SC_CONS_NOTFOUND)
+ {
+ for (nRow=nRow1; nRow<=nRow2; nRow++)
+ {
+ SCROW nArrY = nRow-nRow1;
+ if (bRowByName) nArrY = pDestRows[nArrY];
+ if ( nArrY != SC_CONS_NOTFOUND && (
+ bAnyCell ? pSrcDoc->HasData( nCol, nRow, nTab )
+ : pSrcDoc->HasValueData( nCol, nRow, nTab ) ) )
+ {
+ if (bReference)
+ {
+ if (ppUsed[nArrX][nArrY])
+ ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
+ else
+ {
+ ppUsed[nArrX][nArrY] = TRUE;
+ ppRefs[nArrX][nArrY].Init();
+ ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
+ }
+ }
+ else
+ {
+ double nVal;
+ pSrcDoc->GetValue( nCol, nRow, nTab, nVal );
+ if (ppUsed[nArrX][nArrY])
+ lcl_UpdateArray( eFunction, ppCount[nArrX][nArrY],
+ ppSum[nArrX][nArrY], ppSumSqr[nArrX][nArrY],
+ nVal);
+ else
+ {
+ ppUsed[nArrX][nArrY] = TRUE;
+ lcl_InitArray( eFunction, ppCount[nArrX][nArrY],
+ ppSum[nArrX][nArrY],
+ ppSumSqr[nArrX][nArrY], nVal );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ delete[] pDestCols;
+ delete[] pDestRows;
+}
+
+// vorher testen, wieviele Zeilen eingefuegt werden (fuer Undo)
+
+SCROW ScConsData::GetInsertCount() const
+{
+ SCROW nInsert = 0;
+ SCSIZE nArrX;
+ SCSIZE nArrY;
+ if ( ppRefs && ppUsed )
+ {
+ for (nArrY=0; nArrY<nRowCount; nArrY++)
+ {
+ SCSIZE nNeeded = 0;
+ for (nArrX=0; nArrX<nColCount; nArrX++)
+ if (ppUsed[nArrX][nArrY])
+ nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
+
+ nInsert += nNeeded;
+ }
+ }
+ return nInsert;
+}
+
+// fertige Daten ins Dokument schreiben
+//! optimieren nach Spalten?
+
+void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ OpCode eOpCode = eOpCodeTable[eFunction];
+
+ SCSIZE nArrX;
+ SCSIZE nArrY;
+
+ // Ecke links oben
+
+ if ( bColByName && bRowByName && aCornerText.Len() )
+ pDestDoc->SetString( nCol, nRow, nTab, aCornerText );
+
+ // Titel
+
+ SCCOL nStartCol = nCol;
+ SCROW nStartRow = nRow;
+ if (bColByName) ++nStartRow;
+ if (bRowByName) ++nStartCol;
+
+ if (bColByName)
+ for (SCSIZE i=0; i<nColCount; i++)
+ pDestDoc->SetString( sal::static_int_cast<SCCOL>(nStartCol+i), nRow, nTab, *ppColHeaders[i] );
+ if (bRowByName)
+ for (SCSIZE j=0; j<nRowCount; j++)
+ pDestDoc->SetString( nCol, sal::static_int_cast<SCROW>(nStartRow+j), nTab, *ppRowHeaders[j] );
+
+ nCol = nStartCol;
+ nRow = nStartRow;
+
+ // Daten
+
+ if ( ppCount && ppUsed ) // Werte direkt einfuegen
+ {
+ for (nArrX=0; nArrX<nColCount; nArrX++)
+ for (nArrY=0; nArrY<nRowCount; nArrY++)
+ if (ppUsed[nArrX][nArrY])
+ {
+ double fVal = lcl_CalcData( eFunction, ppCount[nArrX][nArrY],
+ ppSum[nArrX][nArrY],
+ ppSumSqr[nArrX][nArrY]);
+ if (ppCount[nArrX][nArrY] < 0.0)
+ pDestDoc->SetError( sal::static_int_cast<SCCOL>(nCol+nArrX),
+ sal::static_int_cast<SCROW>(nRow+nArrY), nTab, errNoValue );
+ else
+ pDestDoc->SetValue( sal::static_int_cast<SCCOL>(nCol+nArrX),
+ sal::static_int_cast<SCROW>(nRow+nArrY), nTab, fVal );
+ }
+ }
+
+ if ( ppRefs && ppUsed ) // Referenzen einfuegen
+ {
+ //! unterscheiden, ob nach Kategorien aufgeteilt
+ String aString;
+
+ ScSingleRefData aSRef; // Daten fuer Referenz-Formelzellen
+ aSRef.InitFlags();
+ aSRef.SetFlag3D(TRUE);
+
+ ScComplexRefData aCRef; // Daten fuer Summen-Zellen
+ aCRef.InitFlags();
+ aCRef.Ref1.SetColRel(TRUE); aCRef.Ref1.SetRowRel(TRUE); aCRef.Ref1.SetTabRel(TRUE);
+ aCRef.Ref2.SetColRel(TRUE); aCRef.Ref2.SetRowRel(TRUE); aCRef.Ref2.SetTabRel(TRUE);
+
+ for (nArrY=0; nArrY<nRowCount; nArrY++)
+ {
+ SCSIZE nNeeded = 0;
+ for (nArrX=0; nArrX<nColCount; nArrX++)
+ if (ppUsed[nArrX][nArrY])
+ nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
+
+ if (nNeeded)
+ {
+ pDestDoc->InsertRow( 0,nTab, MAXCOL,nTab, nRow+nArrY, nNeeded );
+
+ for (nArrX=0; nArrX<nColCount; nArrX++)
+ if (ppUsed[nArrX][nArrY])
+ {
+ ScReferenceList& rList = ppRefs[nArrX][nArrY];
+ SCSIZE nCount = rList.GetCount();
+ if (nCount)
+ {
+ for (SCSIZE nPos=0; nPos<nCount; nPos++)
+ {
+ ScReferenceEntry aRef = rList.GetEntry(nPos);
+ if (aRef.nTab != SC_CONS_NOTFOUND)
+ {
+ // Referenz einfuegen (absolut, 3d)
+
+ aSRef.nCol = aRef.nCol;
+ aSRef.nRow = aRef.nRow;
+ aSRef.nTab = aRef.nTab;
+
+ ScTokenArray aRefArr;
+ aRefArr.AddSingleReference(aSRef);
+ aRefArr.AddOpCode(ocStop);
+ ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
+ sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab );
+ ScBaseCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aRefArr );
+ pDestDoc->PutCell( aDest.Col(), aDest.Row(), aDest.Tab(), pCell );
+ }
+ }
+
+ // Summe einfuegen (relativ, nicht 3d)
+
+ ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
+ sal::static_int_cast<SCROW>(nRow+nArrY+nNeeded), nTab );
+
+ aCRef.Ref1.nTab = aCRef.Ref2.nTab = nTab;
+ aCRef.Ref1.nCol = aCRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( nCol+nArrX );
+ aCRef.Ref1.nRow = nRow+nArrY;
+ aCRef.Ref2.nRow = nRow+nArrY+nNeeded-1;
+ aCRef.CalcRelFromAbs( aDest );
+
+ ScTokenArray aArr;
+ aArr.AddOpCode(eOpCode); // ausgewaehlte Funktion
+ aArr.AddOpCode(ocOpen);
+ aArr.AddDoubleReference(aCRef);
+ aArr.AddOpCode(ocClose);
+ aArr.AddOpCode(ocStop);
+ ScBaseCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aArr );
+ pDestDoc->PutCell( aDest.Col(), aDest.Row(), aDest.Tab(), pCell );
+ }
+ }
+
+ // Gliederung einfuegen
+
+ ScOutlineArray* pOutArr = pDestDoc->GetOutlineTable( nTab, TRUE )->GetRowArray();
+ SCROW nOutStart = nRow+nArrY;
+ SCROW nOutEnd = nRow+nArrY+nNeeded-1;
+ BOOL bSize = FALSE;
+ pOutArr->Insert( nOutStart, nOutEnd, bSize );
+ for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++)
+ pDestDoc->ShowRow( nOutRow, nTab, FALSE );
+ pDestDoc->UpdateOutlineRow( nOutStart, nOutEnd, nTab, FALSE );
+
+ // Zwischentitel
+
+ if (ppTitlePos && ppTitles && ppRowHeaders)
+ {
+ String aDelim( RTL_CONSTASCII_USTRINGPARAM(" / ") );
+ for (SCSIZE nPos=0; nPos<nDataCount; nPos++)
+ {
+ SCSIZE nTPos = ppTitlePos[nArrY][nPos];
+ BOOL bDo = TRUE;
+ if (nPos+1<nDataCount)
+ if (ppTitlePos[nArrY][nPos+1] == nTPos)
+ bDo = FALSE; // leer
+ if ( bDo && nTPos < nNeeded )
+ {
+ aString = *ppRowHeaders[nArrY];
+ aString += aDelim;
+ aString += *ppTitles[nPos];
+ pDestDoc->SetString( nCol-1, nRow+nArrY+nTPos, nTab, aString );
+ }
+ }
+ }
+
+ nRow += nNeeded;
+ }
+ }
+ }
+}
+
+
+
+
+
diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx
new file mode 100644
index 000000000000..7f94cb64c827
--- /dev/null
+++ b/sc/source/core/tool/dbcolect.cxx
@@ -0,0 +1,891 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <tools/debug.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "dbcolect.hxx"
+#include "global.hxx"
+#include "refupdat.hxx"
+#include "rechead.hxx"
+#include "document.hxx"
+#include "queryparam.hxx"
+#include "globstr.hrc"
+
+
+//---------------------------------------------------------------------------------------
+
+ScDBData::ScDBData( const String& rName,
+ SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ BOOL bByR, BOOL bHasH) :
+ aName (rName),
+ nTable (nTab),
+ nStartCol (nCol1),
+ nStartRow (nRow1),
+ nEndCol (nCol2),
+ nEndRow (nRow2),
+ bByRow (bByR),
+ bHasHeader (bHasH),
+ bDoSize (FALSE),
+ bKeepFmt (FALSE),
+ bStripData (FALSE),
+ bIsAdvanced (FALSE),
+ bDBSelection(FALSE),
+ nIndex (0),
+ bAutoFilter (FALSE),
+ bModified (FALSE)
+{
+ USHORT i;
+
+ ScSortParam aSortParam;
+ ScQueryParam aQueryParam;
+ ScSubTotalParam aSubTotalParam;
+ ScImportParam aImportParam;
+
+ for (i=0; i<MAXQUERY; i++)
+ pQueryStr[i] = new String;
+
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ nSubTotals[i] = 0;
+ pSubTotals[i] = NULL;
+ pFunctions[i] = NULL;
+ }
+
+ SetSortParam( aSortParam );
+ SetQueryParam( aQueryParam );
+ SetSubTotalParam( aSubTotalParam );
+ SetImportParam( aImportParam );
+}
+
+ScDBData::ScDBData( const ScDBData& rData ) :
+ ScDataObject(),
+ ScRefreshTimer ( rData ),
+ aName (rData.aName),
+ nTable (rData.nTable),
+ nStartCol (rData.nStartCol),
+ nStartRow (rData.nStartRow),
+ nEndCol (rData.nEndCol),
+ nEndRow (rData.nEndRow),
+ bByRow (rData.bByRow),
+ bHasHeader (rData.bHasHeader),
+ bDoSize (rData.bDoSize),
+ bKeepFmt (rData.bKeepFmt),
+ bStripData (rData.bStripData),
+ bSortCaseSens (rData.bSortCaseSens),
+ bIncludePattern (rData.bIncludePattern),
+ bSortInplace (rData.bSortInplace),
+ bSortUserDef (rData.bSortUserDef),
+ nSortUserIndex (rData.nSortUserIndex),
+ nSortDestTab (rData.nSortDestTab),
+ nSortDestCol (rData.nSortDestCol),
+ nSortDestRow (rData.nSortDestRow),
+ aSortLocale (rData.aSortLocale),
+ aSortAlgorithm (rData.aSortAlgorithm),
+ bQueryInplace (rData.bQueryInplace),
+ bQueryCaseSens (rData.bQueryCaseSens),
+ bQueryRegExp (rData.bQueryRegExp),
+ bQueryDuplicate (rData.bQueryDuplicate),
+ nQueryDestTab (rData.nQueryDestTab),
+ nQueryDestCol (rData.nQueryDestCol),
+ nQueryDestRow (rData.nQueryDestRow),
+ bIsAdvanced (rData.bIsAdvanced),
+ aAdvSource (rData.aAdvSource),
+ bSubRemoveOnly (rData.bSubRemoveOnly),
+ bSubReplace (rData.bSubReplace),
+ bSubPagebreak (rData.bSubPagebreak),
+ bSubCaseSens (rData.bSubCaseSens),
+ bSubDoSort (rData.bSubDoSort),
+ bSubAscending (rData.bSubAscending),
+ bSubIncludePattern (rData.bSubIncludePattern),
+ bSubUserDef (rData.bSubUserDef),
+ nSubUserIndex (rData.nSubUserIndex),
+ bDBImport (rData.bDBImport),
+ aDBName (rData.aDBName),
+ aDBStatement (rData.aDBStatement),
+ bDBNative (rData.bDBNative),
+ bDBSelection (rData.bDBSelection),
+ bDBSql (rData.bDBSql),
+ nDBType (rData.nDBType),
+ nIndex (rData.nIndex),
+ bAutoFilter (rData.bAutoFilter),
+ bModified (rData.bModified)
+{
+ USHORT i;
+ USHORT j;
+
+ for (i=0; i<MAXSORT; i++)
+ {
+ bDoSort[i] = rData.bDoSort[i];
+ nSortField[i] = rData.nSortField[i];
+ bAscending[i] = rData.bAscending[i];
+ }
+ for (i=0; i<MAXQUERY; i++)
+ {
+ bDoQuery[i] = rData.bDoQuery[i];
+ nQueryField[i] = rData.nQueryField[i];
+ eQueryOp[i] = rData.eQueryOp[i];
+ bQueryByString[i] = rData.bQueryByString[i];
+ bQueryByDate[i] = rData.bQueryByDate[i];
+ pQueryStr[i] = new String( *(rData.pQueryStr[i]) );
+ nQueryVal[i] = rData.nQueryVal[i];
+ eQueryConnect[i] = rData.eQueryConnect[i];
+ }
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ bDoSubTotal[i] = rData.bDoSubTotal[i];
+ nSubField[i] = rData.nSubField[i];
+
+ SCCOL nCount = rData.nSubTotals[i];
+ nSubTotals[i] = nCount;
+ pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
+ pSubTotals[i] = nCount > 0 ? new SCCOL [nCount] : NULL;
+
+ for (j=0; j<nCount; j++)
+ {
+ pSubTotals[i][j] = rData.pSubTotals[i][j];
+ pFunctions[i][j] = rData.pFunctions[i][j];
+ }
+ }
+}
+
+ScDBData& ScDBData::operator= (const ScDBData& rData)
+{
+ USHORT i;
+ USHORT j;
+
+ ScRefreshTimer::operator=( rData );
+ aName = rData.aName;
+ nTable = rData.nTable;
+ nStartCol = rData.nStartCol;
+ nStartRow = rData.nStartRow;
+ nEndCol = rData.nEndCol;
+ nEndRow = rData.nEndRow;
+ bByRow = rData.bByRow;
+ bHasHeader = rData.bHasHeader;
+ bDoSize = rData.bDoSize;
+ bKeepFmt = rData.bKeepFmt;
+ bStripData = rData.bStripData;
+ bSortCaseSens = rData.bSortCaseSens;
+ bIncludePattern = rData.bIncludePattern;
+ bSortInplace = rData.bSortInplace;
+ nSortDestTab = rData.nSortDestTab;
+ nSortDestCol = rData.nSortDestCol;
+ nSortDestRow = rData.nSortDestRow;
+ bSortUserDef = rData.bSortUserDef;
+ nSortUserIndex = rData.nSortUserIndex;
+ aSortLocale = rData.aSortLocale;
+ aSortAlgorithm = rData.aSortAlgorithm;
+ bQueryInplace = rData.bQueryInplace;
+ bQueryCaseSens = rData.bQueryCaseSens;
+ bQueryRegExp = rData.bQueryRegExp;
+ bQueryDuplicate = rData.bQueryDuplicate;
+ nQueryDestTab = rData.nQueryDestTab;
+ nQueryDestCol = rData.nQueryDestCol;
+ nQueryDestRow = rData.nQueryDestRow;
+ bIsAdvanced = rData.bIsAdvanced;
+ aAdvSource = rData.aAdvSource;
+ bSubRemoveOnly = rData.bSubRemoveOnly;
+ bSubReplace = rData.bSubReplace;
+ bSubPagebreak = rData.bSubPagebreak;
+ bSubCaseSens = rData.bSubCaseSens;
+ bSubDoSort = rData.bSubDoSort;
+ bSubAscending = rData.bSubAscending;
+ bSubIncludePattern = rData.bSubIncludePattern;
+ bSubUserDef = rData.bSubUserDef;
+ nSubUserIndex = rData.nSubUserIndex;
+ bDBImport = rData.bDBImport;
+ aDBName = rData.aDBName;
+ aDBStatement = rData.aDBStatement;
+ bDBNative = rData.bDBNative;
+ bDBSelection = rData.bDBSelection;
+ bDBSql = rData.bDBSql;
+ nDBType = rData.nDBType;
+ nIndex = rData.nIndex;
+ bAutoFilter = rData.bAutoFilter;
+
+ for (i=0; i<MAXSORT; i++)
+ {
+ bDoSort[i] = rData.bDoSort[i];
+ nSortField[i] = rData.nSortField[i];
+ bAscending[i] = rData.bAscending[i];
+ }
+ for (i=0; i<MAXQUERY; i++)
+ {
+ bDoQuery[i] = rData.bDoQuery[i];
+ nQueryField[i] = rData.nQueryField[i];
+ eQueryOp[i] = rData.eQueryOp[i];
+ bQueryByString[i] = rData.bQueryByString[i];
+ bQueryByDate[i] = rData.bQueryByDate[i];
+ *pQueryStr[i] = *rData.pQueryStr[i];
+ nQueryVal[i] = rData.nQueryVal[i];
+ eQueryConnect[i] = rData.eQueryConnect[i];
+ }
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ bDoSubTotal[i] = rData.bDoSubTotal[i];
+ nSubField[i] = rData.nSubField[i];
+ SCCOL nCount = rData.nSubTotals[i];
+ nSubTotals[i] = nCount;
+
+ delete[] pSubTotals[i];
+ delete[] pFunctions[i];
+
+ pSubTotals[i] = nCount > 0 ? new SCCOL [nCount] : NULL;
+ pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
+ for (j=0; j<nCount; j++)
+ {
+ pSubTotals[i][j] = rData.pSubTotals[i][j];
+ pFunctions[i][j] = rData.pFunctions[i][j];
+ }
+ }
+
+ return *this;
+}
+
+BOOL ScDBData::operator== (const ScDBData& rData) const
+{
+ // Daten, die nicht in den Params sind
+
+ if ( nTable != rData.nTable ||
+ bDoSize != rData.bDoSize ||
+ bKeepFmt != rData.bKeepFmt ||
+ bIsAdvanced!= rData.bIsAdvanced||
+ bStripData != rData.bStripData ||
+// SAB: I think this should be here, but I don't want to break something
+// bAutoFilter!= rData.bAutoFilter||
+ ScRefreshTimer::operator!=( rData )
+ )
+ return FALSE;
+
+ if ( bIsAdvanced && aAdvSource != rData.aAdvSource )
+ return FALSE;
+
+ ScSortParam aSort1, aSort2;
+ GetSortParam(aSort1);
+ rData.GetSortParam(aSort2);
+ if (!(aSort1 == aSort2))
+ return FALSE;
+
+ ScQueryParam aQuery1, aQuery2;
+ GetQueryParam(aQuery1);
+ rData.GetQueryParam(aQuery2);
+ if (!(aQuery1 == aQuery2))
+ return FALSE;
+
+ ScSubTotalParam aSubTotal1, aSubTotal2;
+ GetSubTotalParam(aSubTotal1);
+ rData.GetSubTotalParam(aSubTotal2);
+ if (!(aSubTotal1 == aSubTotal2))
+ return FALSE;
+
+ ScImportParam aImport1, aImport2;
+ GetImportParam(aImport1);
+ rData.GetImportParam(aImport2);
+ if (!(aImport1 == aImport2))
+ return FALSE;
+
+ return TRUE;
+}
+
+ScDBData::~ScDBData()
+{
+ StopRefreshTimer();
+ USHORT i;
+
+ for (i=0; i<MAXQUERY; i++)
+ delete pQueryStr[i];
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ delete[] pSubTotals[i];
+ delete[] pFunctions[i];
+ }
+}
+
+//UNUSED2008-05 BOOL ScDBData::IsBeyond(SCROW nMaxRow) const
+//UNUSED2008-05 {
+//UNUSED2008-05 return ( nStartRow > nMaxRow ||
+//UNUSED2008-05 nEndRow > nMaxRow ||
+//UNUSED2008-05 nQueryDestRow > nMaxRow );
+//UNUSED2008-05 }
+
+String ScDBData::GetSourceString() const
+{
+ String aVal;
+ if (bDBImport)
+ {
+ aVal = aDBName;
+ aVal += '/';
+ aVal += aDBStatement;
+ }
+ return aVal;
+}
+
+String ScDBData::GetOperations() const
+{
+ String aVal;
+ if (bDoQuery[0])
+ aVal = ScGlobal::GetRscString(STR_OPERATION_FILTER);
+
+ if (bDoSort[0])
+ {
+ if (aVal.Len())
+ aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ aVal += ScGlobal::GetRscString(STR_OPERATION_SORT);
+ }
+
+ if (bDoSubTotal[0] && !bSubRemoveOnly)
+ {
+ if (aVal.Len())
+ aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ aVal += ScGlobal::GetRscString(STR_OPERATION_SUBTOTAL);
+ }
+
+ if (!aVal.Len())
+ aVal = ScGlobal::GetRscString(STR_OPERATION_NONE);
+
+ return aVal;
+}
+
+void ScDBData::GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const
+{
+ rTab = nTable;
+ rCol1 = nStartCol;
+ rRow1 = nStartRow;
+ rCol2 = nEndCol;
+ rRow2 = nEndRow;
+}
+
+void ScDBData::GetArea(ScRange& rRange) const
+{
+ rRange = ScRange( nStartCol,nStartRow,nTable, nEndCol,nEndRow,nTable );
+}
+
+void ScDBData::SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
+{
+ nTable = nTab;
+ nStartCol = nCol1;
+ nStartRow = nRow1;
+ nEndCol = nCol2;
+ nEndRow = nRow2;
+}
+
+void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
+{
+ USHORT i;
+ long nDifX = ((long) nCol1) - ((long) nStartCol);
+ long nDifY = ((long) nRow1) - ((long) nStartRow);
+
+ long nSortDif = bByRow ? nDifX : nDifY;
+ long nSortEnd = bByRow ? static_cast<long>(nCol2) : static_cast<long>(nRow2);
+
+ for (i=0; i<MAXSORT; i++)
+ {
+ nSortField[i] += nSortDif;
+ if (nSortField[i] > nSortEnd)
+ {
+ nSortField[i] = 0;
+ bDoSort[i] = FALSE;
+ }
+ }
+ for (i=0; i<MAXQUERY; i++)
+ {
+ nQueryField[i] += nDifX;
+ if (nQueryField[i] > nCol2)
+ {
+ nQueryField[i] = 0;
+ bDoQuery[i] = FALSE;
+ }
+ }
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ nSubField[i] = sal::static_int_cast<SCCOL>( nSubField[i] + nDifX );
+ if (nSubField[i] > nCol2)
+ {
+ nSubField[i] = 0;
+ bDoSubTotal[i] = FALSE;
+ }
+ }
+
+ SetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
+}
+
+void ScDBData::GetSortParam( ScSortParam& rSortParam ) const
+{
+ rSortParam.nCol1 = nStartCol;
+ rSortParam.nRow1 = nStartRow;
+ rSortParam.nCol2 = nEndCol;
+ rSortParam.nRow2 = nEndRow;
+ rSortParam.bByRow = bByRow;
+ rSortParam.bHasHeader = bHasHeader;
+ rSortParam.bCaseSens = bSortCaseSens;
+ rSortParam.bInplace = bSortInplace;
+ rSortParam.nDestTab = nSortDestTab;
+ rSortParam.nDestCol = nSortDestCol;
+ rSortParam.nDestRow = nSortDestRow;
+ rSortParam.bIncludePattern = bIncludePattern;
+ rSortParam.bUserDef = bSortUserDef;
+ rSortParam.nUserIndex = nSortUserIndex;
+ for (USHORT i=0; i<MAXSORT; i++)
+ {
+ rSortParam.bDoSort[i] = bDoSort[i];
+ rSortParam.nField[i] = nSortField[i];
+ rSortParam.bAscending[i] = bAscending[i];
+ }
+ rSortParam.aCollatorLocale = aSortLocale;
+ rSortParam.aCollatorAlgorithm = aSortAlgorithm;
+}
+
+void ScDBData::SetSortParam( const ScSortParam& rSortParam )
+{
+ bSortCaseSens = rSortParam.bCaseSens;
+ bIncludePattern = rSortParam.bIncludePattern;
+ bSortInplace = rSortParam.bInplace;
+ nSortDestTab = rSortParam.nDestTab;
+ nSortDestCol = rSortParam.nDestCol;
+ nSortDestRow = rSortParam.nDestRow;
+ bSortUserDef = rSortParam.bUserDef;
+ nSortUserIndex = rSortParam.nUserIndex;
+ for (USHORT i=0; i<MAXSORT; i++)
+ {
+ bDoSort[i] = rSortParam.bDoSort[i];
+ nSortField[i] = rSortParam.nField[i];
+ bAscending[i] = rSortParam.bAscending[i];
+ }
+ aSortLocale = rSortParam.aCollatorLocale;
+ aSortAlgorithm = rSortParam.aCollatorAlgorithm;
+
+ //#98317#; set the orientation
+ bByRow = rSortParam.bByRow;
+}
+
+void ScDBData::GetQueryParam( ScQueryParam& rQueryParam ) const
+{
+ rQueryParam.nCol1 = nStartCol;
+ rQueryParam.nRow1 = nStartRow;
+ rQueryParam.nCol2 = nEndCol;
+ rQueryParam.nRow2 = nEndRow;
+ rQueryParam.nTab = nTable;
+ rQueryParam.bByRow = bByRow;
+ rQueryParam.bHasHeader = bHasHeader;
+ rQueryParam.bInplace = bQueryInplace;
+ rQueryParam.bCaseSens = bQueryCaseSens;
+ rQueryParam.bRegExp = bQueryRegExp;
+ rQueryParam.bDuplicate = bQueryDuplicate;
+ rQueryParam.nDestTab = nQueryDestTab;
+ rQueryParam.nDestCol = nQueryDestCol;
+ rQueryParam.nDestRow = nQueryDestRow;
+
+ rQueryParam.Resize( MAXQUERY );
+ for (SCSIZE i=0; i<MAXQUERY; i++)
+ {
+ ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
+
+ rEntry.bDoQuery = bDoQuery[i];
+ rEntry.nField = nQueryField[i];
+ rEntry.eOp = eQueryOp[i];
+ rEntry.bQueryByString = bQueryByString[i];
+ rEntry.bQueryByDate = bQueryByDate[i];
+ *rEntry.pStr = *pQueryStr[i];
+ rEntry.nVal = nQueryVal[i];
+ rEntry.eConnect = eQueryConnect[i];
+ }
+}
+
+void ScDBData::SetQueryParam(const ScQueryParam& rQueryParam)
+{
+ DBG_ASSERT( rQueryParam.GetEntryCount() <= MAXQUERY ||
+ !rQueryParam.GetEntry(MAXQUERY).bDoQuery,
+ "zuviele Eintraege bei ScDBData::SetQueryParam" );
+
+ // set bIsAdvanced to FALSE for everything that is not from the
+ // advanced filter dialog
+ bIsAdvanced = FALSE;
+
+ bQueryInplace = rQueryParam.bInplace;
+ bQueryCaseSens = rQueryParam.bCaseSens;
+ bQueryRegExp = rQueryParam.bRegExp;
+ bQueryDuplicate = rQueryParam.bDuplicate;
+ nQueryDestTab = rQueryParam.nDestTab;
+ nQueryDestCol = rQueryParam.nDestCol;
+ nQueryDestRow = rQueryParam.nDestRow;
+ for (SCSIZE i=0; i<MAXQUERY; i++)
+ {
+ ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
+
+ bDoQuery[i] = rEntry.bDoQuery;
+ nQueryField[i] = rEntry.nField;
+ eQueryOp[i] = rEntry.eOp;
+ bQueryByString[i] = rEntry.bQueryByString;
+ bQueryByDate[i] = rEntry.bQueryByDate;
+ *pQueryStr[i] = *rEntry.pStr;
+ nQueryVal[i] = rEntry.nVal;
+ eQueryConnect[i] = rEntry.eConnect;
+ }
+}
+
+void ScDBData::SetAdvancedQuerySource(const ScRange* pSource)
+{
+ if (pSource)
+ {
+ aAdvSource = *pSource;
+ bIsAdvanced = TRUE;
+ }
+ else
+ bIsAdvanced = FALSE;
+}
+
+BOOL ScDBData::GetAdvancedQuerySource(ScRange& rSource) const
+{
+ rSource = aAdvSource;
+ return bIsAdvanced;
+}
+
+void ScDBData::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
+{
+ USHORT i;
+ USHORT j;
+
+ rSubTotalParam.nCol1 = nStartCol;
+ rSubTotalParam.nRow1 = nStartRow;
+ rSubTotalParam.nCol2 = nEndCol;
+ rSubTotalParam.nRow2 = nEndRow;
+
+ rSubTotalParam.bRemoveOnly = bSubRemoveOnly;
+ rSubTotalParam.bReplace = bSubReplace;
+ rSubTotalParam.bPagebreak = bSubPagebreak;
+ rSubTotalParam.bCaseSens = bSubCaseSens;
+ rSubTotalParam.bDoSort = bSubDoSort;
+ rSubTotalParam.bAscending = bSubAscending;
+ rSubTotalParam.bIncludePattern = bSubIncludePattern;
+ rSubTotalParam.bUserDef = bSubUserDef;
+ rSubTotalParam.nUserIndex = nSubUserIndex;
+
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ rSubTotalParam.bGroupActive[i] = bDoSubTotal[i];
+ rSubTotalParam.nField[i] = nSubField[i];
+ SCCOL nCount = nSubTotals[i];
+
+ rSubTotalParam.nSubTotals[i] = nCount;
+ delete[] rSubTotalParam.pSubTotals[i];
+ delete[] rSubTotalParam.pFunctions[i];
+ rSubTotalParam.pSubTotals[i] = nCount > 0 ? new SCCOL[nCount] : NULL;
+ rSubTotalParam.pFunctions[i] = nCount > 0 ? new ScSubTotalFunc[nCount]
+ : NULL;
+ for (j=0; j<nCount; j++)
+ {
+ rSubTotalParam.pSubTotals[i][j] = pSubTotals[i][j];
+ rSubTotalParam.pFunctions[i][j] = pFunctions[i][j];
+ }
+ }
+}
+
+void ScDBData::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam)
+{
+ USHORT i;
+ USHORT j;
+
+ bSubRemoveOnly = rSubTotalParam.bRemoveOnly;
+ bSubReplace = rSubTotalParam.bReplace;
+ bSubPagebreak = rSubTotalParam.bPagebreak;
+ bSubCaseSens = rSubTotalParam.bCaseSens;
+ bSubDoSort = rSubTotalParam.bDoSort;
+ bSubAscending = rSubTotalParam.bAscending;
+ bSubIncludePattern = rSubTotalParam.bIncludePattern;
+ bSubUserDef = rSubTotalParam.bUserDef;
+ nSubUserIndex = rSubTotalParam.nUserIndex;
+
+ for (i=0; i<MAXSUBTOTAL; i++)
+ {
+ bDoSubTotal[i] = rSubTotalParam.bGroupActive[i];
+ nSubField[i] = rSubTotalParam.nField[i];
+ SCCOL nCount = rSubTotalParam.nSubTotals[i];
+
+ nSubTotals[i] = nCount;
+ delete[] pSubTotals[i];
+ delete[] pFunctions[i];
+ pSubTotals[i] = nCount > 0 ? new SCCOL [nCount] : NULL;
+ pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
+ for (j=0; j<nCount; j++)
+ {
+ pSubTotals[i][j] = rSubTotalParam.pSubTotals[i][j];
+ pFunctions[i][j] = rSubTotalParam.pFunctions[i][j];
+ }
+ }
+}
+
+void ScDBData::GetImportParam(ScImportParam& rImportParam) const
+{
+ rImportParam.nCol1 = nStartCol;
+ rImportParam.nRow1 = nStartRow;
+ rImportParam.nCol2 = nEndCol;
+ rImportParam.nRow2 = nEndRow;
+
+ rImportParam.bImport = bDBImport;
+ rImportParam.aDBName = aDBName;
+ rImportParam.aStatement = aDBStatement;
+ rImportParam.bNative = bDBNative;
+ rImportParam.bSql = bDBSql;
+ rImportParam.nType = nDBType;
+}
+
+void ScDBData::SetImportParam(const ScImportParam& rImportParam)
+{
+ bDBImport = rImportParam.bImport;
+ aDBName = rImportParam.aDBName;
+ aDBStatement = rImportParam.aStatement;
+ bDBNative = rImportParam.bNative;
+ bDBSql = rImportParam.bSql;
+ nDBType = rImportParam.nType;
+}
+
+BOOL ScDBData::IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bStartOnly) const
+{
+ if (nTab == nTable)
+ {
+ if ( bStartOnly )
+ return ( nCol == nStartCol && nRow == nStartRow );
+ else
+ return ( nCol >= nStartCol && nCol <= nEndCol &&
+ nRow >= nStartRow && nRow <= nEndRow );
+ }
+
+ return FALSE;
+}
+
+BOOL ScDBData::IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
+{
+ return (BOOL)((nTab == nTable)
+ && (nCol1 == nStartCol) && (nRow1 == nStartRow)
+ && (nCol2 == nEndCol) && (nRow2 == nEndRow));
+}
+
+ScDataObject* ScDBData::Clone() const
+{
+ return new ScDBData(*this);
+}
+
+
+//---------------------------------------------------------------------------------------
+// Compare zum Sortieren
+
+short ScDBCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ const String& rStr1 = ((ScDBData*)pKey1)->GetName();
+ const String& rStr2 = ((ScDBData*)pKey2)->GetName();
+ return (short) ScGlobal::GetpTransliteration()->compareString( rStr1, rStr2 );
+}
+
+// IsEqual - alles gleich
+
+BOOL ScDBCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return *(ScDBData*)pKey1 == *(ScDBData*)pKey2;
+}
+
+ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bStartOnly) const
+{
+ ScDBData* pNoNameData = NULL;
+ if (pItems)
+ {
+ const String& rNoName = ScGlobal::GetRscString( STR_DB_NONAME );
+
+ for (USHORT i = 0; i < nCount; i++)
+ if (((ScDBData*)pItems[i])->IsDBAtCursor(nCol, nRow, nTab, bStartOnly))
+ {
+ ScDBData* pDB = (ScDBData*)pItems[i];
+ if ( pDB->GetName() == rNoName )
+ pNoNameData = pDB;
+ else
+ return pDB;
+ }
+ }
+ return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden
+}
+
+ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
+{
+ ScDBData* pNoNameData = NULL;
+ if (pItems)
+ {
+ const String& rNoName = ScGlobal::GetRscString( STR_DB_NONAME );
+
+ for (USHORT i = 0; i < nCount; i++)
+ if (((ScDBData*)pItems[i])->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
+ {
+ ScDBData* pDB = (ScDBData*)pItems[i];
+ if ( pDB->GetName() == rNoName )
+ pNoNameData = pDB;
+ else
+ return pDB;
+ }
+ }
+ return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden
+}
+
+BOOL ScDBCollection::SearchName( const String& rName, USHORT& rIndex ) const
+{
+ ScDBData aDataObj( rName, 0,0,0,0,0 );
+ return Search( &aDataObj, rIndex );
+}
+
+void ScDBCollection::DeleteOnTab( SCTAB nTab )
+{
+ USHORT nPos = 0;
+ while ( nPos < nCount )
+ {
+ // look for output positions on the deleted sheet
+
+ SCCOL nEntryCol1, nEntryCol2;
+ SCROW nEntryRow1, nEntryRow2;
+ SCTAB nEntryTab;
+ static_cast<const ScDBData*>(At(nPos))->GetArea( nEntryTab, nEntryCol1, nEntryRow1, nEntryCol2, nEntryRow2 );
+ if ( nEntryTab == nTab )
+ AtFree(nPos);
+ else
+ ++nPos;
+ }
+}
+
+void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ for (USHORT i=0; i<nCount; i++)
+ {
+ SCCOL theCol1;
+ SCROW theRow1;
+ SCTAB theTab1;
+ SCCOL theCol2;
+ SCROW theRow2;
+ SCTAB theTab2;
+ ((ScDBData*)pItems[i])->GetArea( theTab1, theCol1, theRow1, theCol2, theRow2 );
+ theTab2 = theTab1;
+
+ BOOL bDoUpdate = ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
+ theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) != UR_NOTHING;
+ if (bDoUpdate)
+ ((ScDBData*)pItems[i])->MoveTo( theTab1, theCol1, theRow1, theCol2, theRow2 );
+
+ ScRange aAdvSource;
+ if ( ((ScDBData*)pItems[i])->GetAdvancedQuerySource(aAdvSource) )
+ {
+ aAdvSource.GetVars( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
+ theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) )
+ {
+ aAdvSource.aStart.Set( theCol1,theRow1,theTab1 );
+ aAdvSource.aEnd.Set( theCol2,theRow2,theTab2 );
+ ((ScDBData*)pItems[i])->SetAdvancedQuerySource( &aAdvSource );
+
+ bDoUpdate = TRUE; // DBData is modified
+ }
+ }
+
+ ((ScDBData*)pItems[i])->SetModified(bDoUpdate);
+
+ //! Testen, ob mitten aus dem Bereich geloescht/eingefuegt wurde !!!
+ }
+}
+
+
+void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
+{
+ // wenn nOldPos vor nNewPos liegt, ist nNewPos schon angepasst
+
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScRange aRange;
+ ScDBData* pData = (ScDBData*)pItems[i];
+ pData->GetArea( aRange );
+ SCTAB nTab = aRange.aStart.Tab(); // hat nur eine Tabelle
+
+ // anpassen wie die aktuelle Tabelle bei ScTablesHint (tabvwsh5.cxx)
+
+ if ( nTab == nOldPos ) // verschobene Tabelle
+ nTab = nNewPos;
+ else if ( nOldPos < nNewPos ) // nach hinten verschoben
+ {
+ if ( nTab > nOldPos && nTab <= nNewPos ) // nachrueckender Bereich
+ --nTab;
+ }
+ else // nach vorne verschoben
+ {
+ if ( nTab >= nNewPos && nTab < nOldPos ) // nachrueckender Bereich
+ ++nTab;
+ }
+
+ BOOL bChanged = ( nTab != aRange.aStart.Tab() );
+ if (bChanged)
+ pData->SetArea( nTab, aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(),aRange.aEnd .Row() );
+
+ // MoveTo ist nicht noetig, wenn nur die Tabelle geaendert ist
+
+ pData->SetModified(bChanged);
+ }
+}
+
+
+ScDBData* ScDBCollection::FindIndex(USHORT nIndex)
+{
+ USHORT i = 0;
+ while (i < nCount)
+ {
+ if ((*this)[i]->GetIndex() == nIndex)
+ return (*this)[i];
+ i++;
+ }
+ return NULL;
+}
+
+BOOL ScDBCollection::Insert(ScDataObject* pScDataObject)
+{
+ ScDBData* pData = (ScDBData*) pScDataObject;
+ if (!pData->GetIndex()) // schon gesetzt?
+ pData->SetIndex(nEntryIndex++);
+ BOOL bInserted = ScSortedCollection::Insert(pScDataObject);
+ if ( bInserted && pData->HasImportParam() && !pData->HasImportSelection() )
+ {
+ pData->SetRefreshHandler( GetRefreshHandler() );
+ pData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() );
+ }
+ return bInserted;
+}
+
+
+
+
diff --git a/sc/source/core/tool/ddelink.cxx b/sc/source/core/tool/ddelink.cxx
new file mode 100644
index 000000000000..977161760eb0
--- /dev/null
+++ b/sc/source/core/tool/ddelink.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <tools/list.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/zforlist.hxx>
+
+#include "ddelink.hxx"
+#include "brdcst.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include "patattr.hxx"
+#include "rechead.hxx"
+#include "rangeseq.hxx"
+#include "sc.hrc"
+#include "hints.hxx"
+
+TYPEINIT2(ScDdeLink,::sfx2::SvBaseLink,SfxBroadcaster);
+
+#define DDE_TXT_ENCODING gsl_getSystemTextEncoding()
+
+BOOL ScDdeLink::bIsInUpdate = FALSE;
+
+//------------------------------------------------------------------------
+
+ScDdeLink::ScDdeLink( ScDocument* pD, const String& rA, const String& rT, const String& rI,
+ BYTE nM ) :
+ ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ALWAYS,FORMAT_STRING),
+ pDoc( pD ),
+ aAppl( rA ),
+ aTopic( rT ),
+ aItem( rI ),
+ nMode( nM ),
+ bNeedUpdate( FALSE ),
+ pResult( NULL )
+{
+}
+
+__EXPORT ScDdeLink::~ScDdeLink()
+{
+ // Verbindung aufheben
+
+ // pResult is refcounted
+}
+
+ScDdeLink::ScDdeLink( ScDocument* pD, const ScDdeLink& rOther ) :
+ ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ALWAYS,FORMAT_STRING),
+ pDoc ( pD ),
+ aAppl ( rOther.aAppl ),
+ aTopic ( rOther.aTopic ),
+ aItem ( rOther.aItem ),
+ nMode ( rOther.nMode ),
+ bNeedUpdate( FALSE ),
+ pResult ( NULL )
+{
+ if (rOther.pResult)
+ pResult = rOther.pResult->Clone();
+}
+
+ScDdeLink::ScDdeLink( ScDocument* pD, SvStream& rStream, ScMultipleReadHeader& rHdr ) :
+ ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ALWAYS,FORMAT_STRING),
+ pDoc( pD ),
+ bNeedUpdate( FALSE ),
+ pResult( NULL )
+{
+ rHdr.StartEntry();
+
+ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
+ rStream.ReadByteString( aAppl, eCharSet );
+ rStream.ReadByteString( aTopic, eCharSet );
+ rStream.ReadByteString( aItem, eCharSet );
+
+ BOOL bHasValue;
+ rStream >> bHasValue;
+ if ( bHasValue )
+ pResult = new ScMatrix( rStream );
+
+ if (rHdr.BytesLeft()) // neu in 388b und der 364w (RealTime-Client) Version
+ rStream >> nMode;
+ else
+ nMode = SC_DDE_DEFAULT;
+
+ rHdr.EndEntry();
+}
+
+void ScDdeLink::Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const
+{
+ rHdr.StartEntry();
+
+ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
+ rStream.WriteByteString( aAppl, eCharSet );
+ rStream.WriteByteString( aTopic, eCharSet );
+ rStream.WriteByteString( aItem, eCharSet );
+
+ BOOL bHasValue = ( pResult != NULL );
+ rStream << bHasValue;
+ if (bHasValue)
+ pResult->Store( rStream );
+
+ if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // nicht bei 4.0 Export
+ rStream << nMode; // seit 388b
+
+ // Links mit Mode != SC_DDE_DEFAULT werden bei 4.0 Export komplett weggelassen
+ // (aus ScDocument::SaveDdeLinks)
+
+ rHdr.EndEntry();
+}
+
+void __EXPORT ScDdeLink::DataChanged( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue )
+{
+ // wir koennen nur Strings...
+ if ( FORMAT_STRING != SotExchange::GetFormatIdFromMimeType( rMimeType ))
+ return;
+
+ String aLinkStr;
+ ScByteSequenceToString::GetString( aLinkStr, rValue, DDE_TXT_ENCODING );
+ aLinkStr.ConvertLineEnd(LINEEND_LF);
+
+ // wenn String mit Zeilenende aufhoert, streichen:
+
+ xub_StrLen nLen = aLinkStr.Len();
+ if (nLen && aLinkStr.GetChar(nLen-1) == '\n')
+ aLinkStr.Erase(nLen-1);
+
+ String aLine;
+ SCSIZE nCols = 1; // Leerstring -> eine leere Zelle
+ SCSIZE nRows = 1;
+ if (aLinkStr.Len())
+ {
+ nRows = static_cast<SCSIZE>(aLinkStr.GetTokenCount( '\n' ));
+ aLine = aLinkStr.GetToken( 0, '\n' );
+ if (aLine.Len())
+ nCols = static_cast<SCSIZE>(aLine.GetTokenCount( '\t' ));
+ }
+
+ if (!nRows || !nCols) // keine Daten
+ {
+ pResult.Clear();
+ }
+ else // Daten aufteilen
+ {
+ // Matrix immer neu anlegen, damit bIsString nicht durcheinanderkommt
+ pResult = new ScMatrix( nCols, nRows );
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ // nMode bestimmt, wie der Text interpretiert wird (#44455#/#49783#):
+ // SC_DDE_DEFAULT - Zahlformat aus Zellvorlage "Standard"
+ // SC_DDE_ENGLISH - Standard-Zahlformat fuer English/US
+ // SC_DDE_TEXT - ohne NumberFormatter direkt als String
+ ULONG nStdFormat = 0;
+ if ( nMode == SC_DDE_DEFAULT )
+ {
+ ScPatternAttr* pDefPattern = pDoc->GetDefPattern(); // enthaelt Standard-Vorlage
+ if ( pDefPattern )
+ nStdFormat = pDefPattern->GetNumberFormat( pFormatter );
+ }
+ else if ( nMode == SC_DDE_ENGLISH )
+ nStdFormat = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
+
+ String aEntry;
+ for (SCSIZE nR=0; nR<nRows; nR++)
+ {
+ aLine = aLinkStr.GetToken( (xub_StrLen) nR, '\n' );
+ for (SCSIZE nC=0; nC<nCols; nC++)
+ {
+ aEntry = aLine.GetToken( (xub_StrLen) nC, '\t' );
+ sal_uInt32 nIndex = nStdFormat;
+ double fVal;
+ if ( nMode != SC_DDE_TEXT && pFormatter->IsNumberFormat( aEntry, nIndex, fVal ) )
+ pResult->PutDouble( fVal, nC, nR );
+ else
+ pResult->PutString( aEntry, nC, nR );
+ }
+ }
+ }
+
+ // Es hat sich was getan...
+
+ if (HasListeners())
+ {
+ Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
+ pDoc->TrackFormulas(); // muss sofort passieren
+ pDoc->StartTrackTimer();
+
+ // StartTrackTimer ruft asynchron TrackFormulas, Broadcast(FID_DATACHANGED),
+ // ResetChanged, SetModified und Invalidate(SID_SAVEDOC/SID_DOC_MODIFIED)
+ // TrackFormulas zusaetzlich nochmal sofort, damit nicht z.B. durch IdleCalc
+ // eine Formel berechnet wird, die noch im FormulaTrack steht (#61676#)
+
+ // notify Uno objects (for XRefreshListener)
+ // must be after TrackFormulas
+ //! do this asynchronously?
+ ScLinkRefreshedHint aHint;
+ aHint.SetDdeLink( aAppl, aTopic, aItem, nMode );
+ pDoc->BroadcastUno( aHint );
+ }
+}
+
+void ScDdeLink::ResetValue()
+{
+ pResult.Clear();
+
+ // Es hat sich was getan...
+ // Tracking, FID_DATACHANGED etc. passiert von aussen
+
+ if (HasListeners())
+ Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
+}
+
+void __EXPORT ScDdeLink::ListenersGone()
+{
+ BOOL bWas = bIsInUpdate;
+ bIsInUpdate = TRUE; // Remove() kann Reschedule ausloesen??!?
+
+ ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link
+
+ sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager();
+ pLinkMgr->Remove( this); // deletes this
+
+ if ( !pLinkMgr->GetLinks().Count() ) // letzten geloescht ?
+ {
+ SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc!
+ if (pBindings)
+ pBindings->Invalidate( SID_LINKS );
+ }
+
+ bIsInUpdate = bWas;
+}
+
+void ScDdeLink::TryUpdate()
+{
+ if (bIsInUpdate)
+ bNeedUpdate = TRUE; // kann jetzt nicht ausgefuehrt werden
+ else
+ {
+ bIsInUpdate = TRUE;
+ //Application::Reschedule(); //! OS/2-Simulation
+ pDoc->IncInDdeLinkUpdate();
+ Update();
+ pDoc->DecInDdeLinkUpdate();
+ bIsInUpdate = FALSE;
+ bNeedUpdate = FALSE;
+ }
+}
+
+
diff --git a/sc/source/core/tool/detdata.cxx b/sc/source/core/tool/detdata.cxx
new file mode 100644
index 000000000000..a1add9ca6939
--- /dev/null
+++ b/sc/source/core/tool/detdata.cxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "detdata.hxx"
+#include "refupdat.hxx"
+#include "rechead.hxx"
+
+//------------------------------------------------------------------------
+
+SV_IMPL_PTRARR( ScDetOpArr_Impl, ScDetOpDataPtr );
+
+//------------------------------------------------------------------------
+
+ScDetOpList::ScDetOpList(const ScDetOpList& rList) :
+ ScDetOpArr_Impl(),
+ bHasAddError( FALSE )
+{
+ USHORT nCount = rList.Count();
+
+ for (USHORT i=0; i<nCount; i++)
+ Append( new ScDetOpData(*rList[i]) );
+}
+
+void ScDetOpList::DeleteOnTab( SCTAB nTab )
+{
+ USHORT nPos = 0;
+ while ( nPos < Count() )
+ {
+ // look for operations on the deleted sheet
+
+ if ( (*this)[nPos]->GetPos().Tab() == nTab )
+ Remove(nPos);
+ else
+ ++nPos;
+ }
+}
+
+void ScDetOpList::UpdateReference( ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ USHORT nCount = Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScAddress aPos = (*this)[i]->GetPos();
+ SCCOL nCol1 = aPos.Col();
+ SCROW nRow1 = aPos.Row();
+ SCTAB nTab1 = aPos.Tab();
+ SCCOL nCol2 = nCol1;
+ SCROW nRow2 = nRow1;
+ SCTAB nTab2 = nTab1;
+
+ ScRefUpdateRes eRes =
+ ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if ( eRes != UR_NOTHING )
+ (*this)[i]->SetPos( ScAddress( nCol1, nRow1, nTab1 ) );
+ }
+}
+
+void ScDetOpList::Append( ScDetOpData* pDetOpData )
+{
+ if ( pDetOpData->GetOperation() == SCDETOP_ADDERROR )
+ bHasAddError = TRUE;
+
+ Insert( pDetOpData, Count() );
+}
+
+
+BOOL ScDetOpList::operator==( const ScDetOpList& r ) const
+{
+ // fuer Ref-Undo
+
+ USHORT nCount = Count();
+ BOOL bEqual = ( nCount == r.Count() );
+ for (USHORT i=0; i<nCount && bEqual; i++) // Reihenfolge muss auch gleich sein
+ if ( !(*(*this)[i] == *r[i]) ) // Eintraege unterschiedlich ?
+ bEqual = FALSE;
+
+ return bEqual;
+}
+
+
+
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
new file mode 100644
index 000000000000..e86bb22646c8
--- /dev/null
+++ b/sc/source/core/tool/detfunc.cxx
@@ -0,0 +1,1712 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svtools/colorcfg.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/sdshitm.hxx>
+#include <svx/sdsxyitm.hxx>
+#include <svx/sdtditm.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnedcit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xtable.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editobj.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svl/whiter.hxx>
+#include <editeng/writingmodeitem.hxx>
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#include "detfunc.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "validat.hxx"
+#include "cell.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "scmod.hxx"
+#include "postit.hxx"
+
+//------------------------------------------------------------------------
+
+// #99319# line ends are now created with an empty name.
+// The checkForUniqueItem method then finds a unique name for the item's value.
+#define SC_LINEEND_NAME EMPTY_STRING
+
+//------------------------------------------------------------------------
+
+enum DetInsertResult { // Return-Werte beim Einfuegen in einen Level
+ DET_INS_CONTINUE,
+ DET_INS_INSERTED,
+ DET_INS_EMPTY,
+ DET_INS_CIRCULAR };
+
+
+//------------------------------------------------------------------------
+
+class ScDetectiveData
+{
+private:
+ SfxItemSet aBoxSet;
+ SfxItemSet aArrowSet;
+ SfxItemSet aToTabSet;
+ SfxItemSet aFromTabSet;
+ SfxItemSet aCircleSet; //! einzeln ?
+ USHORT nMaxLevel;
+
+public:
+ ScDetectiveData( SdrModel* pModel );
+
+ SfxItemSet& GetBoxSet() { return aBoxSet; }
+ SfxItemSet& GetArrowSet() { return aArrowSet; }
+ SfxItemSet& GetToTabSet() { return aToTabSet; }
+ SfxItemSet& GetFromTabSet() { return aFromTabSet; }
+ SfxItemSet& GetCircleSet() { return aCircleSet; }
+
+ void SetMaxLevel( USHORT nVal ) { nMaxLevel = nVal; }
+ USHORT GetMaxLevel() const { return nMaxLevel; }
+};
+
+class ScCommentData
+{
+public:
+ ScCommentData( ScDocument& rDoc, SdrModel* pModel );
+
+ SfxItemSet& GetCaptionSet() { return aCaptionSet; }
+ void UpdateCaptionSet( const SfxItemSet& rItemSet );
+
+private:
+ SfxItemSet aCaptionSet;
+};
+
+//------------------------------------------------------------------------
+
+ColorData ScDetectiveFunc::nArrowColor = 0;
+ColorData ScDetectiveFunc::nErrorColor = 0;
+ColorData ScDetectiveFunc::nCommentColor = 0;
+BOOL ScDetectiveFunc::bColorsInitialized = FALSE;
+
+//------------------------------------------------------------------------
+
+BOOL lcl_HasThickLine( SdrObject& rObj )
+{
+ // thin lines get width 0 -> everything greater 0 is a thick line
+
+ return ( ((const XLineWidthItem&)rObj.GetMergedItem(XATTR_LINEWIDTH)).GetValue() > 0 );
+}
+
+//------------------------------------------------------------------------
+
+ScDetectiveData::ScDetectiveData( SdrModel* pModel ) :
+ aBoxSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
+ aArrowSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
+ aToTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
+ aFromTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
+ aCircleSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END )
+{
+ nMaxLevel = 0;
+
+ aBoxSet.Put( XLineColorItem( EMPTY_STRING, Color( ScDetectiveFunc::GetArrowColor() ) ) );
+ aBoxSet.Put( XFillStyleItem( XFILL_NONE ) );
+
+ // #66479# Standard-Linienenden (wie aus XLineEndList::Create) selber zusammenbasteln,
+ // um von den konfigurierten Linienenden unabhaengig zu sein
+
+ 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);
+
+ basegfx::B2DPolygon aSquare;
+ aSquare.append(basegfx::B2DPoint(0.0, 0.0));
+ aSquare.append(basegfx::B2DPoint(10.0, 0.0));
+ aSquare.append(basegfx::B2DPoint(10.0, 10.0));
+ aSquare.append(basegfx::B2DPoint(0.0, 10.0));
+ aSquare.setClosed(true);
+
+ basegfx::B2DPolygon aCircle(basegfx::tools::createPolygonFromEllipse(basegfx::B2DPoint(0.0, 0.0), 100.0, 100.0));
+ aCircle.setClosed(true);
+
+ String aName = SC_LINEEND_NAME;
+
+ aArrowSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aCircle) ) );
+ aArrowSet.Put( XLineStartWidthItem( 200 ) );
+ aArrowSet.Put( XLineStartCenterItem( TRUE ) );
+ aArrowSet.Put( XLineEndItem( aName, basegfx::B2DPolyPolygon(aTriangle) ) );
+ aArrowSet.Put( XLineEndWidthItem( 200 ) );
+ aArrowSet.Put( XLineEndCenterItem( FALSE ) );
+
+ aToTabSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aCircle) ) );
+ aToTabSet.Put( XLineStartWidthItem( 200 ) );
+ aToTabSet.Put( XLineStartCenterItem( TRUE ) );
+ aToTabSet.Put( XLineEndItem( aName, basegfx::B2DPolyPolygon(aSquare) ) );
+ aToTabSet.Put( XLineEndWidthItem( 300 ) );
+ aToTabSet.Put( XLineEndCenterItem( FALSE ) );
+
+ aFromTabSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aSquare) ) );
+ aFromTabSet.Put( XLineStartWidthItem( 300 ) );
+ aFromTabSet.Put( XLineStartCenterItem( TRUE ) );
+ aFromTabSet.Put( XLineEndItem( aName, basegfx::B2DPolyPolygon(aTriangle) ) );
+ aFromTabSet.Put( XLineEndWidthItem( 200 ) );
+ aFromTabSet.Put( XLineEndCenterItem( FALSE ) );
+
+ aCircleSet.Put( XLineColorItem( String(), Color( ScDetectiveFunc::GetErrorColor() ) ) );
+ aCircleSet.Put( XFillStyleItem( XFILL_NONE ) );
+ USHORT nWidth = 55; // 54 = 1 Pixel
+ aCircleSet.Put( XLineWidthItem( nWidth ) );
+}
+
+ScCommentData::ScCommentData( ScDocument& rDoc, SdrModel* pModel ) :
+ aCaptionSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END, EE_ITEMS_START, EE_ITEMS_END, 0, 0 )
+{
+ 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);
+
+ String aName = SC_LINEEND_NAME;
+
+ aCaptionSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aTriangle) ) );
+ aCaptionSet.Put( XLineStartWidthItem( 200 ) );
+ aCaptionSet.Put( XLineStartCenterItem( FALSE ) );
+ aCaptionSet.Put( XFillStyleItem( XFILL_SOLID ) );
+ Color aYellow( ScDetectiveFunc::GetCommentColor() );
+ aCaptionSet.Put( XFillColorItem( String(), aYellow ) );
+
+ // 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)
+ aCaptionSet.Put( SdrShadowItem( FALSE ) );
+ aCaptionSet.Put( SdrShadowXDistItem( 100 ) );
+ aCaptionSet.Put( SdrShadowYDistItem( 100 ) );
+
+ // text attributes
+ aCaptionSet.Put( SdrTextLeftDistItem( 100 ) );
+ aCaptionSet.Put( SdrTextRightDistItem( 100 ) );
+ aCaptionSet.Put( SdrTextUpperDistItem( 100 ) );
+ aCaptionSet.Put( SdrTextLowerDistItem( 100 ) );
+
+ aCaptionSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ aCaptionSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
+
+ // #78943# do use the default cell style, so the user has a chance to
+ // modify the font for the annotations
+ ((const ScPatternAttr&)rDoc.GetPool()->GetDefaultItem(ATTR_PATTERN)).
+ FillEditItemSet( &aCaptionSet );
+
+ // support the best position for the tail connector now that
+ // that notes can be resized and repositioned.
+ aCaptionSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT) );
+}
+
+void ScCommentData::UpdateCaptionSet( const SfxItemSet& rItemSet )
+{
+ SfxWhichIter aWhichIter( rItemSet );
+ const SfxPoolItem* pPoolItem = 0;
+
+ for( USHORT nWhich = aWhichIter.FirstWhich(); nWhich > 0; nWhich = aWhichIter.NextWhich() )
+ {
+ if(rItemSet.GetItemState(nWhich, FALSE, &pPoolItem) == SFX_ITEM_SET)
+ {
+ switch(nWhich)
+ {
+ case SDRATTR_SHADOW:
+ // use existing Caption default - appears that setting this
+ // to true screws up the tail appearance. See also comment
+ // for default setting above.
+ break;
+ case SDRATTR_SHADOWXDIST:
+ // use existing Caption default - svx sets a value of 35
+ // but default 100 gives a better appearance.
+ break;
+ case SDRATTR_SHADOWYDIST:
+ // use existing Caption default - svx sets a value of 35
+ // but default 100 gives a better appearance.
+ break;
+
+ default:
+ aCaptionSet.Put(*pPoolItem);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScDetectiveFunc::Modified()
+{
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+}
+
+inline BOOL Intersect( SCCOL nStartCol1, SCROW nStartRow1, SCCOL nEndCol1, SCROW nEndRow1,
+ SCCOL nStartCol2, SCROW nStartRow2, SCCOL nEndCol2, SCROW nEndRow2 )
+{
+ return nEndCol1 >= nStartCol2 && nEndCol2 >= nStartCol1 &&
+ nEndRow1 >= nStartRow2 && nEndRow2 >= nStartRow1;
+}
+
+BOOL ScDetectiveFunc::HasError( const ScRange& rRange, ScAddress& rErrPos )
+{
+ rErrPos = rRange.aStart;
+ USHORT nError = 0;
+
+ ScCellIterator aCellIter( pDoc, rRange);
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ nError = ((ScFormulaCell*)pCell)->GetErrCode();
+ if (nError)
+ rErrPos.Set( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
+ }
+ pCell = aCellIter.GetNext();
+ }
+
+ return (nError != 0);
+}
+
+Point ScDetectiveFunc::GetDrawPos( SCCOL nCol, SCROW nRow, DrawPosMode eMode ) const
+{
+ DBG_ASSERT( ValidColRow( nCol, nRow ), "ScDetectiveFunc::GetDrawPos - invalid cell address" );
+ SanitizeCol( nCol );
+ SanitizeRow( nRow );
+
+ Point aPos;
+
+ switch( eMode )
+ {
+ case DRAWPOS_TOPLEFT:
+ break;
+ case DRAWPOS_BOTTOMRIGHT:
+ ++nCol;
+ ++nRow;
+ break;
+ case DRAWPOS_DETARROW:
+ aPos.X() += pDoc->GetColWidth( nCol, nTab ) / 4;
+ aPos.Y() += pDoc->GetRowHeight( nRow, nTab ) / 2;
+ break;
+ case DRAWPOS_CAPTIONLEFT:
+ aPos.X() += 6;
+ break;
+ case DRAWPOS_CAPTIONRIGHT:
+ {
+ // find right end of passed cell position
+ const ScMergeAttr* pMerge = static_cast< const ScMergeAttr* >( pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE ) );
+ if ( pMerge->GetColMerge() > 1 )
+ nCol = nCol + pMerge->GetColMerge();
+ else
+ ++nCol;
+ aPos.X() -= 6;
+ }
+ break;
+ }
+
+ for ( SCCOL i = 0; i < nCol; ++i )
+ aPos.X() += pDoc->GetColWidth( i, nTab );
+ aPos.Y() += pDoc->GetRowHeight( 0, nRow - 1, nTab );
+
+ aPos.X() = static_cast< long >( aPos.X() * HMM_PER_TWIPS );
+ aPos.Y() = static_cast< long >( aPos.Y() * HMM_PER_TWIPS );
+
+ if ( pDoc->IsNegativePage( nTab ) )
+ aPos.X() *= -1;
+
+ return aPos;
+}
+
+Rectangle ScDetectiveFunc::GetDrawRect( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
+{
+ Rectangle aRect(
+ GetDrawPos( ::std::min( nCol1, nCol2 ), ::std::min( nRow1, nRow2 ), DRAWPOS_TOPLEFT ),
+ GetDrawPos( ::std::max( nCol1, nCol2 ), ::std::max( nRow1, nRow2 ), DRAWPOS_BOTTOMRIGHT ) );
+ aRect.Justify(); // reorder left/right in RTL sheets
+ return aRect;
+}
+
+Rectangle ScDetectiveFunc::GetDrawRect( SCCOL nCol, SCROW nRow ) const
+{
+ return GetDrawRect( nCol, nRow, nCol, nRow );
+}
+
+BOOL lcl_IsOtherTab( const basegfx::B2DPolyPolygon& rPolyPolygon )
+{
+ // test if rPolygon is the line end for "other table" (rectangle)
+ if(1L == rPolyPolygon.count())
+ {
+ const basegfx::B2DPolygon aSubPoly(rPolyPolygon.getB2DPolygon(0L));
+
+ // #i73305# circle consists of 4 segments, too, distinguishable from square by
+ // the use of control points
+ if(4L == aSubPoly.count() && aSubPoly.isClosed() && !aSubPoly.areControlPointsUsed())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+BOOL ScDetectiveFunc::HasArrow( const ScAddress& rStart,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
+{
+ BOOL bStartAlien = ( rStart.Tab() != nTab );
+ BOOL bEndAlien = ( nEndTab != nTab );
+
+ if (bStartAlien && bEndAlien)
+ {
+ DBG_ERROR("bStartAlien && bEndAlien");
+ return TRUE;
+ }
+
+ Rectangle aStartRect;
+ Rectangle aEndRect;
+ if (!bStartAlien)
+ aStartRect = GetDrawRect( rStart.Col(), rStart.Row() );
+ if (!bEndAlien)
+ aEndRect = GetDrawRect( nEndCol, nEndRow );
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ BOOL bFound = FALSE;
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if ( pObject->GetLayer()==SC_LAYER_INTERN &&
+ pObject->IsPolyObj() && pObject->GetPointCount()==2 )
+ {
+ const SfxItemSet& rSet = pObject->GetMergedItemSet();
+
+ BOOL bObjStartAlien =
+ lcl_IsOtherTab( ((const XLineStartItem&)rSet.Get(XATTR_LINESTART)).GetLineStartValue() );
+ BOOL bObjEndAlien =
+ lcl_IsOtherTab( ((const XLineEndItem&)rSet.Get(XATTR_LINEEND)).GetLineEndValue() );
+
+ BOOL bStartHit = bStartAlien ? bObjStartAlien :
+ ( !bObjStartAlien && aStartRect.IsInside(pObject->GetPoint(0)) );
+ BOOL bEndHit = bEndAlien ? bObjEndAlien :
+ ( !bObjEndAlien && aEndRect.IsInside(pObject->GetPoint(1)) );
+
+ if ( bStartHit && bEndHit )
+ bFound = TRUE;
+ }
+ pObject = aIter.Next();
+ }
+
+ return bFound;
+}
+
+BOOL ScDetectiveFunc::IsNonAlienArrow( SdrObject* pObject ) // static
+{
+ if ( pObject->GetLayer()==SC_LAYER_INTERN &&
+ pObject->IsPolyObj() && pObject->GetPointCount()==2 )
+ {
+ const SfxItemSet& rSet = pObject->GetMergedItemSet();
+
+ BOOL bObjStartAlien =
+ lcl_IsOtherTab( ((const XLineStartItem&)rSet.Get(XATTR_LINESTART)).GetLineStartValue() );
+ BOOL bObjEndAlien =
+ lcl_IsOtherTab( ((const XLineEndItem&)rSet.Get(XATTR_LINEEND)).GetLineEndValue() );
+
+ return !bObjStartAlien && !bObjEndAlien;
+ }
+
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+// InsertXXX: called from DrawEntry/DrawAlienEntry and InsertObject
+
+BOOL ScDetectiveFunc::InsertArrow( SCCOL nCol, SCROW nRow,
+ SCCOL nRefStartCol, SCROW nRefStartRow,
+ SCCOL nRefEndCol, SCROW nRefEndRow,
+ BOOL bFromOtherTab, BOOL bRed,
+ ScDetectiveData& rData )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+
+ BOOL bArea = ( nRefStartCol != nRefEndCol || nRefStartRow != nRefEndRow );
+ if (bArea && !bFromOtherTab)
+ {
+ // insert the rectangle before the arrow - this is relied on in FindFrameForObject
+
+ Rectangle aRect = GetDrawRect( nRefStartCol, nRefStartRow, nRefEndCol, nRefEndRow );
+ SdrRectObj* pBox = new SdrRectObj( aRect );
+
+ pBox->SetMergedItemSetAndBroadcast(rData.GetBoxSet());
+
+ ScDrawLayer::SetAnchor( pBox, SCA_CELL );
+ pBox->SetLayer( SC_LAYER_INTERN );
+ pPage->InsertObject( pBox );
+ pModel->AddCalcUndo( new SdrUndoInsertObj( *pBox ) );
+
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox, TRUE );
+ pData->maStart.Set( nRefStartCol, nRefStartRow, nTab);
+ pData->maEnd.Set( nRefEndCol, nRefEndRow, nTab);
+ }
+
+ Point aStartPos = GetDrawPos( nRefStartCol, nRefStartRow, DRAWPOS_DETARROW );
+ Point aEndPos = GetDrawPos( nCol, nRow, DRAWPOS_DETARROW );
+
+ if (bFromOtherTab)
+ {
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+ long nPageSign = bNegativePage ? -1 : 1;
+
+ aStartPos = Point( aEndPos.X() - 1000 * nPageSign, aEndPos.Y() - 1000 );
+ if (aStartPos.X() * nPageSign < 0)
+ aStartPos.X() += 2000 * nPageSign;
+ if (aStartPos.Y() < 0)
+ aStartPos.Y() += 2000;
+ }
+
+ SfxItemSet& rAttrSet = bFromOtherTab ? rData.GetFromTabSet() : rData.GetArrowSet();
+
+ if (bArea && !bFromOtherTab)
+ rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich
+ else
+ rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz
+
+ ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() );
+ rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) );
+
+ basegfx::B2DPolygon aTempPoly;
+ aTempPoly.append(basegfx::B2DPoint(aStartPos.X(), aStartPos.Y()));
+ aTempPoly.append(basegfx::B2DPoint(aEndPos.X(), aEndPos.Y()));
+ SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aTempPoly));
+ pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ???
+ pArrow->SetMergedItemSetAndBroadcast(rAttrSet);
+
+ ScDrawLayer::SetAnchor( pArrow, SCA_CELL );
+ pArrow->SetLayer( SC_LAYER_INTERN );
+ pPage->InsertObject( pArrow );
+ pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) );
+
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, TRUE );
+ if (bFromOtherTab)
+ pData->maStart.SetInvalid();
+ else
+ pData->maStart.Set( nRefStartCol, nRefStartRow, nTab);
+
+ pData->maEnd.Set( nCol, nRow, nTab);
+
+ Modified();
+ return TRUE;
+}
+
+BOOL ScDetectiveFunc::InsertToOtherTab( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, BOOL bRed,
+ ScDetectiveData& rData )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+
+ BOOL bArea = ( nStartCol != nEndCol || nStartRow != nEndRow );
+ if (bArea)
+ {
+ Rectangle aRect = GetDrawRect( nStartCol, nStartRow, nEndCol, nEndRow );
+ SdrRectObj* pBox = new SdrRectObj( aRect );
+
+ pBox->SetMergedItemSetAndBroadcast(rData.GetBoxSet());
+
+ ScDrawLayer::SetAnchor( pBox, SCA_CELL );
+ pBox->SetLayer( SC_LAYER_INTERN );
+ pPage->InsertObject( pBox );
+ pModel->AddCalcUndo( new SdrUndoInsertObj( *pBox ) );
+
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox, TRUE );
+ pData->maStart.Set( nStartCol, nStartRow, nTab);
+ pData->maEnd.Set( nEndCol, nEndRow, nTab);
+ }
+
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+ long nPageSign = bNegativePage ? -1 : 1;
+
+ Point aStartPos = GetDrawPos( nStartCol, nStartRow, DRAWPOS_DETARROW );
+ Point aEndPos = Point( aStartPos.X() + 1000 * nPageSign, aStartPos.Y() - 1000 );
+ if (aEndPos.Y() < 0)
+ aEndPos.Y() += 2000;
+
+ SfxItemSet& rAttrSet = rData.GetToTabSet();
+ if (bArea)
+ rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich
+ else
+ rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz
+
+ ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() );
+ rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) );
+
+ basegfx::B2DPolygon aTempPoly;
+ aTempPoly.append(basegfx::B2DPoint(aStartPos.X(), aStartPos.Y()));
+ aTempPoly.append(basegfx::B2DPoint(aEndPos.X(), aEndPos.Y()));
+ SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aTempPoly));
+ pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ???
+
+ pArrow->SetMergedItemSetAndBroadcast(rAttrSet);
+
+ ScDrawLayer::SetAnchor( pArrow, SCA_CELL );
+ pArrow->SetLayer( SC_LAYER_INTERN );
+ pPage->InsertObject( pArrow );
+ pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) );
+
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, TRUE );
+ pData->maStart.Set( nStartCol, nStartRow, nTab);
+ pData->maEnd.SetInvalid();
+
+ Modified();
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+// DrawEntry: Formel auf dieser Tabelle,
+// Referenz auf dieser oder anderer
+// DrawAlienEntry: Formel auf anderer Tabelle,
+// Referenz auf dieser
+
+// return FALSE: da war schon ein Pfeil
+
+BOOL ScDetectiveFunc::DrawEntry( SCCOL nCol, SCROW nRow,
+ const ScRange& rRef,
+ ScDetectiveData& rData )
+{
+ if ( HasArrow( rRef.aStart, nCol, nRow, nTab ) )
+ return FALSE;
+
+ ScAddress aErrorPos;
+ BOOL bError = HasError( rRef, aErrorPos );
+ BOOL bAlien = ( rRef.aEnd.Tab() < nTab || rRef.aStart.Tab() > nTab );
+
+ return InsertArrow( nCol, nRow,
+ rRef.aStart.Col(), rRef.aStart.Row(),
+ rRef.aEnd.Col(), rRef.aEnd.Row(),
+ bAlien, bError, rData );
+}
+
+BOOL ScDetectiveFunc::DrawAlienEntry( const ScRange& rRef,
+ ScDetectiveData& rData )
+{
+ if ( HasArrow( rRef.aStart, 0, 0, nTab+1 ) )
+ return FALSE;
+
+ ScAddress aErrorPos;
+ BOOL bError = HasError( rRef, aErrorPos );
+
+ return InsertToOtherTab( rRef.aStart.Col(), rRef.aStart.Row(),
+ rRef.aEnd.Col(), rRef.aEnd.Row(),
+ bError, rData );
+}
+
+void ScDetectiveFunc::DrawCircle( SCCOL nCol, SCROW nRow, ScDetectiveData& rData )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+
+ Rectangle aRect = GetDrawRect( nCol, nRow );
+ aRect.Left() -= 250;
+ aRect.Right() += 250;
+ aRect.Top() -= 70;
+ aRect.Bottom() += 70;
+
+ SdrCircObj* pCircle = new SdrCircObj( OBJ_CIRC, aRect );
+ SfxItemSet& rAttrSet = rData.GetCircleSet();
+
+ pCircle->SetMergedItemSetAndBroadcast(rAttrSet);
+
+ ScDrawLayer::SetAnchor( pCircle, SCA_CELL );
+ pCircle->SetLayer( SC_LAYER_INTERN );
+ pPage->InsertObject( pCircle );
+ pModel->AddCalcUndo( new SdrUndoInsertObj( *pCircle ) );
+
+ ScDrawObjData* pData = ScDrawLayer::GetObjData( pCircle, TRUE );
+ pData->maStart.Set( nCol, nRow, nTab);
+ pData->maEnd.SetInvalid();
+
+ Modified();
+}
+
+void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, BOOL bDestPnt )
+{
+ Rectangle aRect = GetDrawRect( nCol, nRow );
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ pPage->RecalcObjOrdNums();
+
+ long nDelCount = 0;
+ ULONG nObjCount = pPage->GetObjCount();
+ if (nObjCount)
+ {
+ SdrObject** ppObj = new SdrObject*[nObjCount];
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetLayer()==SC_LAYER_INTERN &&
+ pObject->IsPolyObj() && pObject->GetPointCount()==2 )
+ {
+ if (aRect.IsInside(pObject->GetPoint(bDestPnt))) // Start/Zielpunkt
+ ppObj[nDelCount++] = pObject;
+ }
+
+ pObject = aIter.Next();
+ }
+
+ long i;
+ for (i=1; i<=nDelCount; i++)
+ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
+
+ for (i=1; i<=nDelCount; i++)
+ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
+
+ delete[] ppObj;
+
+ Modified();
+ }
+}
+
+ // Box um Referenz loeschen
+
+#define SC_DET_TOLERANCE 50
+
+inline BOOL RectIsPoints( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
+{
+ return rRect.Left() >= rStart.X() - SC_DET_TOLERANCE
+ && rRect.Left() <= rStart.X() + SC_DET_TOLERANCE
+ && rRect.Right() >= rEnd.X() - SC_DET_TOLERANCE
+ && rRect.Right() <= rEnd.X() + SC_DET_TOLERANCE
+ && rRect.Top() >= rStart.Y() - SC_DET_TOLERANCE
+ && rRect.Top() <= rStart.Y() + SC_DET_TOLERANCE
+ && rRect.Bottom() >= rEnd.Y() - SC_DET_TOLERANCE
+ && rRect.Bottom() <= rEnd.Y() + SC_DET_TOLERANCE;
+}
+
+#undef SC_DET_TOLERANCE
+
+void ScDetectiveFunc::DeleteBox( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+/* String aStr;
+ aStr += nCol1;
+ aStr += '/';
+ aStr += nRow1;
+ aStr += '/';
+ aStr += nCol2;
+ aStr += '/';
+ aStr += nRow2;
+ InfoBox(0,aStr).Execute();
+*/
+
+ Rectangle aCornerRect = GetDrawRect( nCol1, nRow1, nCol2, nRow2 );
+ Point aStartCorner = aCornerRect.TopLeft();
+ Point aEndCorner = aCornerRect.BottomRight();
+ Rectangle aObjRect;
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ pPage->RecalcObjOrdNums();
+
+ long nDelCount = 0;
+ ULONG nObjCount = pPage->GetObjCount();
+ if (nObjCount)
+ {
+ SdrObject** ppObj = new SdrObject*[nObjCount];
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetLayer() == SC_LAYER_INTERN &&
+ pObject->Type() == TYPE(SdrRectObj) )
+ {
+ aObjRect = ((SdrRectObj*)pObject)->GetLogicRect();
+ aObjRect.Justify();
+ if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) )
+ ppObj[nDelCount++] = pObject;
+ }
+
+ pObject = aIter.Next();
+ }
+
+ long i;
+ for (i=1; i<=nDelCount; i++)
+ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
+
+ for (i=1; i<=nDelCount; i++)
+ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
+
+ delete[] ppObj;
+
+ Modified();
+ }
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScDetectiveFunc::InsertPredLevelArea( const ScRange& rRef,
+ ScDetectiveData& rData, USHORT nLevel )
+{
+ USHORT nResult = DET_INS_EMPTY;
+
+ ScCellIterator aCellIter( pDoc, rRef);
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ switch( InsertPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), rData, nLevel ) )
+ {
+ case DET_INS_INSERTED:
+ nResult = DET_INS_INSERTED;
+ break;
+ case DET_INS_CONTINUE:
+ if (nResult != DET_INS_INSERTED)
+ nResult = DET_INS_CONTINUE;
+ break;
+ case DET_INS_CIRCULAR:
+ if (nResult == DET_INS_EMPTY)
+ nResult = DET_INS_CIRCULAR;
+ break;
+ }
+
+ pCell = aCellIter.GetNext();
+ }
+
+ return nResult;
+}
+
+USHORT ScDetectiveFunc::InsertPredLevel( SCCOL nCol, SCROW nRow, ScDetectiveData& rData,
+ USHORT nLevel )
+{
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if (!pCell)
+ return DET_INS_EMPTY;
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ return DET_INS_EMPTY;
+
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if (pFCell->IsRunning())
+ return DET_INS_CIRCULAR;
+
+ if (pFCell->GetDirty())
+ pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
+ pFCell->SetRunning(TRUE);
+
+ USHORT nResult = DET_INS_EMPTY;
+
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef ) )
+ {
+ if (DrawEntry( nCol, nRow, aRef, rData ))
+ {
+ nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen
+ }
+ else
+ {
+ // weiterverfolgen
+
+ if ( nLevel < rData.GetMaxLevel() )
+ {
+ USHORT nSubResult;
+ BOOL bArea = (aRef.aStart != aRef.aEnd);
+ if (bArea)
+ nSubResult = InsertPredLevelArea( aRef, rData, nLevel+1 );
+ else
+ nSubResult = InsertPredLevel( aRef.aStart.Col(), aRef.aStart.Row(),
+ rData, nLevel+1 );
+
+ switch (nSubResult)
+ {
+ case DET_INS_INSERTED:
+ nResult = DET_INS_INSERTED;
+ break;
+ case DET_INS_CONTINUE:
+ if (nResult != DET_INS_INSERTED)
+ nResult = DET_INS_CONTINUE;
+ break;
+ case DET_INS_CIRCULAR:
+ if (nResult == DET_INS_EMPTY)
+ nResult = DET_INS_CIRCULAR;
+ break;
+ // DET_INS_EMPTY: unveraendert lassen
+ }
+ }
+ else // nMaxLevel erreicht
+ if (nResult != DET_INS_INSERTED)
+ nResult = DET_INS_CONTINUE;
+ }
+ }
+
+ pFCell->SetRunning(FALSE);
+
+ return nResult;
+}
+
+USHORT ScDetectiveFunc::FindPredLevelArea( const ScRange& rRef,
+ USHORT nLevel, USHORT nDeleteLevel )
+{
+ USHORT nResult = nLevel;
+
+ ScCellIterator aCellIter( pDoc, rRef);
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ USHORT nTemp = FindPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), nLevel, nDeleteLevel );
+ if (nTemp > nResult)
+ nResult = nTemp;
+ }
+ pCell = aCellIter.GetNext();
+ }
+
+ return nResult;
+}
+
+ // nDeleteLevel != 0 -> loeschen
+
+USHORT ScDetectiveFunc::FindPredLevel( SCCOL nCol, SCROW nRow, USHORT nLevel, USHORT nDeleteLevel )
+{
+ DBG_ASSERT( nLevel<1000, "Level" );
+
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if (!pCell)
+ return nLevel;
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ return nLevel;
+
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if (pFCell->IsRunning())
+ return nLevel;
+
+ if (pFCell->GetDirty())
+ pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
+ pFCell->SetRunning(TRUE);
+
+ USHORT nResult = nLevel;
+ BOOL bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 );
+
+ if ( bDelete )
+ {
+ DeleteArrowsAt( nCol, nRow, TRUE ); // Pfeile, die hierher zeigen
+ }
+
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef) )
+ {
+ BOOL bArea = ( aRef.aStart != aRef.aEnd );
+
+ if ( bDelete ) // Rahmen loeschen ?
+ {
+ if (bArea)
+ {
+ DeleteBox( aRef.aStart.Col(), aRef.aStart.Row(), aRef.aEnd.Col(), aRef.aEnd.Row() );
+ }
+ }
+ else // weitersuchen
+ {
+ if ( HasArrow( aRef.aStart, nCol,nRow,nTab ) )
+ {
+ USHORT nTemp;
+ if (bArea)
+ nTemp = FindPredLevelArea( aRef, nLevel+1, nDeleteLevel );
+ else
+ nTemp = FindPredLevel( aRef.aStart.Col(),aRef.aStart.Row(),
+ nLevel+1, nDeleteLevel );
+ if (nTemp > nResult)
+ nResult = nTemp;
+ }
+ }
+ }
+
+ pFCell->SetRunning(FALSE);
+
+ return nResult;
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScDetectiveFunc::InsertErrorLevel( SCCOL nCol, SCROW nRow, ScDetectiveData& rData,
+ USHORT nLevel )
+{
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if (!pCell)
+ return DET_INS_EMPTY;
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ return DET_INS_EMPTY;
+
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if (pFCell->IsRunning())
+ return DET_INS_CIRCULAR;
+
+ if (pFCell->GetDirty())
+ pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
+ pFCell->SetRunning(TRUE);
+
+ USHORT nResult = DET_INS_EMPTY;
+
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ ScAddress aErrorPos;
+ BOOL bHasError = FALSE;
+ while ( aIter.GetNextRef( aRef ) )
+ {
+ if (HasError( aRef, aErrorPos ))
+ {
+ bHasError = TRUE;
+ if (DrawEntry( nCol, nRow, ScRange( aErrorPos), rData ))
+ nResult = DET_INS_INSERTED;
+
+ // und weiterverfolgen
+
+ if ( nLevel < rData.GetMaxLevel() ) // praktisch immer
+ {
+ if (InsertErrorLevel( aErrorPos.Col(), aErrorPos.Row(),
+ rData, nLevel+1 ) == DET_INS_INSERTED)
+ nResult = DET_INS_INSERTED;
+ }
+ }
+ }
+
+ pFCell->SetRunning(FALSE);
+
+ // Blaetter ?
+ if (!bHasError)
+ if (InsertPredLevel( nCol, nRow, rData, rData.GetMaxLevel() ) == DET_INS_INSERTED)
+ nResult = DET_INS_INSERTED;
+
+ return nResult;
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScDetectiveFunc::InsertSuccLevel( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ ScDetectiveData& rData, USHORT nLevel )
+{
+ // ueber ganzes Dokument
+
+ USHORT nResult = DET_INS_EMPTY;
+// ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
+ ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB ); // alle Tabellen
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ BOOL bRunning = pFCell->IsRunning();
+
+ if (pFCell->GetDirty())
+ pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
+ pFCell->SetRunning(TRUE);
+
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef) )
+ {
+ if (aRef.aStart.Tab() <= nTab && aRef.aEnd.Tab() >= nTab)
+ {
+ if (Intersect( nCol1,nRow1,nCol2,nRow2,
+ aRef.aStart.Col(),aRef.aStart.Row(),
+ aRef.aEnd.Col(),aRef.aEnd.Row() ))
+ {
+ BOOL bAlien = ( aCellIter.GetTab() != nTab );
+ BOOL bDrawRet;
+ if (bAlien)
+ bDrawRet = DrawAlienEntry( aRef, rData );
+ else
+ bDrawRet = DrawEntry( aCellIter.GetCol(), aCellIter.GetRow(),
+ aRef, rData );
+ if (bDrawRet)
+ {
+ nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen
+ }
+ else
+ {
+ if (bRunning)
+ {
+ if (nResult == DET_INS_EMPTY)
+ nResult = DET_INS_CIRCULAR;
+ }
+ else
+ {
+ // weiterverfolgen
+
+ if ( nLevel < rData.GetMaxLevel() )
+ {
+ USHORT nSubResult = InsertSuccLevel(
+ aCellIter.GetCol(), aCellIter.GetRow(),
+ aCellIter.GetCol(), aCellIter.GetRow(),
+ rData, nLevel+1 );
+ switch (nSubResult)
+ {
+ case DET_INS_INSERTED:
+ nResult = DET_INS_INSERTED;
+ break;
+ case DET_INS_CONTINUE:
+ if (nResult != DET_INS_INSERTED)
+ nResult = DET_INS_CONTINUE;
+ break;
+ case DET_INS_CIRCULAR:
+ if (nResult == DET_INS_EMPTY)
+ nResult = DET_INS_CIRCULAR;
+ break;
+ // DET_INS_EMPTY: unveraendert lassen
+ }
+ }
+ else // nMaxLevel erreicht
+ if (nResult != DET_INS_INSERTED)
+ nResult = DET_INS_CONTINUE;
+ }
+ }
+ }
+ }
+ }
+ pFCell->SetRunning(bRunning);
+ }
+ pCell = aCellIter.GetNext();
+ }
+
+ return nResult;
+}
+
+USHORT ScDetectiveFunc::FindSuccLevel( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ USHORT nLevel, USHORT nDeleteLevel )
+{
+ DBG_ASSERT( nLevel<1000, "Level" );
+
+ USHORT nResult = nLevel;
+ BOOL bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 );
+
+ ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ BOOL bRunning = pFCell->IsRunning();
+
+ if (pFCell->GetDirty())
+ pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
+ pFCell->SetRunning(TRUE);
+
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef) )
+ {
+ if (aRef.aStart.Tab() <= nTab && aRef.aEnd.Tab() >= nTab)
+ {
+ if (Intersect( nCol1,nRow1,nCol2,nRow2,
+ aRef.aStart.Col(),aRef.aStart.Row(),
+ aRef.aEnd.Col(),aRef.aEnd.Row() ))
+ {
+ if ( bDelete ) // Pfeile, die hier anfangen
+ {
+ if (aRef.aStart != aRef.aEnd)
+ {
+ DeleteBox( aRef.aStart.Col(), aRef.aStart.Row(),
+ aRef.aEnd.Col(), aRef.aEnd.Row() );
+ }
+ DeleteArrowsAt( aRef.aStart.Col(), aRef.aStart.Row(), FALSE );
+ }
+ else if ( !bRunning &&
+ HasArrow( aRef.aStart,
+ aCellIter.GetCol(),aCellIter.GetRow(),aCellIter.GetTab() ) )
+ {
+ USHORT nTemp = FindSuccLevel( aCellIter.GetCol(), aCellIter.GetRow(),
+ aCellIter.GetCol(), aCellIter.GetRow(),
+ nLevel+1, nDeleteLevel );
+ if (nTemp > nResult)
+ nResult = nTemp;
+ }
+ }
+ }
+ }
+
+ pFCell->SetRunning(bRunning);
+ }
+ pCell = aCellIter.GetNext();
+ }
+
+ return nResult;
+}
+
+
+//
+// --------------------------------------------------------------------------------
+//
+
+BOOL ScDetectiveFunc::ShowPred( SCCOL nCol, SCROW nRow )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ ScDetectiveData aData( pModel );
+
+ USHORT nMaxLevel = 0;
+ USHORT nResult = DET_INS_CONTINUE;
+ while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000)
+ {
+ aData.SetMaxLevel( nMaxLevel );
+ nResult = InsertPredLevel( nCol, nRow, aData, 0 );
+ ++nMaxLevel;
+ }
+
+ return ( nResult == DET_INS_INSERTED );
+}
+
+BOOL ScDetectiveFunc::ShowSucc( SCCOL nCol, SCROW nRow )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ ScDetectiveData aData( pModel );
+
+ USHORT nMaxLevel = 0;
+ USHORT nResult = DET_INS_CONTINUE;
+ while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000)
+ {
+ aData.SetMaxLevel( nMaxLevel );
+ nResult = InsertSuccLevel( nCol, nRow, nCol, nRow, aData, 0 );
+ ++nMaxLevel;
+ }
+
+ return ( nResult == DET_INS_INSERTED );
+}
+
+BOOL ScDetectiveFunc::ShowError( SCCOL nCol, SCROW nRow )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ ScRange aRange( nCol, nRow, nTab );
+ ScAddress aErrPos;
+ if ( !HasError( aRange,aErrPos ) )
+ return FALSE;
+
+ ScDetectiveData aData( pModel );
+
+ aData.SetMaxLevel( 1000 );
+ USHORT nResult = InsertErrorLevel( nCol, nRow, aData, 0 );
+
+ return ( nResult == DET_INS_INSERTED );
+}
+
+BOOL ScDetectiveFunc::DeleteSucc( SCCOL nCol, SCROW nRow )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ USHORT nLevelCount = FindSuccLevel( nCol, nRow, nCol, nRow, 0, 0 );
+ if ( nLevelCount )
+ FindSuccLevel( nCol, nRow, nCol, nRow, 0, nLevelCount ); // loeschen
+
+ return ( nLevelCount != 0 );
+}
+
+BOOL ScDetectiveFunc::DeletePred( SCCOL nCol, SCROW nRow )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ USHORT nLevelCount = FindPredLevel( nCol, nRow, 0, 0 );
+ if ( nLevelCount )
+ FindPredLevel( nCol, nRow, 0, nLevelCount ); // loeschen
+
+ return ( nLevelCount != 0 );
+}
+
+BOOL ScDetectiveFunc::DeleteAll( ScDetectiveDelete eWhat )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
+ pPage->RecalcObjOrdNums();
+
+ long nDelCount = 0;
+ ULONG nObjCount = pPage->GetObjCount();
+ if (nObjCount)
+ {
+ SdrObject** ppObj = new SdrObject*[nObjCount];
+
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetLayer() == SC_LAYER_INTERN )
+ {
+ BOOL bDoThis = TRUE;
+ if ( eWhat != SC_DET_ALL )
+ {
+ BOOL bCircle = ( pObject->ISA(SdrCircObj) );
+ BOOL bCaption = ScDrawLayer::IsNoteCaption( pObject );
+ if ( eWhat == SC_DET_DETECTIVE ) // Detektiv, aus Menue
+ bDoThis = !bCaption; // auch Kreise
+ else if ( eWhat == SC_DET_CIRCLES ) // Kreise, wenn neue erzeugt werden
+ bDoThis = bCircle;
+ else if ( eWhat == SC_DET_ARROWS ) // DetectiveRefresh
+ bDoThis = !bCaption && !bCircle; // don't include circles
+ else
+ {
+ DBG_ERROR("wat?");
+ }
+ }
+ if ( bDoThis )
+ ppObj[nDelCount++] = pObject;
+ }
+
+ pObject = aIter.Next();
+ }
+
+ long i;
+ for (i=1; i<=nDelCount; i++)
+ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
+
+ for (i=1; i<=nDelCount; i++)
+ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
+
+ delete[] ppObj;
+
+ Modified();
+ }
+
+ return ( nDelCount != 0 );
+}
+
+BOOL ScDetectiveFunc::MarkInvalid(BOOL& rOverflow)
+{
+ rOverflow = FALSE;
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ BOOL bDeleted = DeleteAll( SC_DET_CIRCLES ); // nur die Kreise
+
+ ScDetectiveData aData( pModel );
+ long nInsCount = 0;
+
+ // Stellen suchen, wo Gueltigkeit definiert ist
+
+ ScDocAttrIterator aAttrIter( pDoc, nTab, 0,0,MAXCOL,MAXROW );
+ SCCOL nCol;
+ SCROW nRow1;
+ SCROW nRow2;
+ const ScPatternAttr* pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 );
+ while ( pPattern && nInsCount < SC_DET_MAXCIRCLE )
+ {
+ ULONG nIndex = ((const SfxUInt32Item&)pPattern->GetItem(ATTR_VALIDDATA)).GetValue();
+ if (nIndex)
+ {
+ const ScValidationData* pData = pDoc->GetValidationEntry( nIndex );
+ if ( pData )
+ {
+ // Zellen in dem Bereich durchgehen
+
+ BOOL bMarkEmpty = !pData->IsIgnoreBlank();
+ SCROW nNextRow = nRow1;
+ SCROW nRow;
+ ScCellIterator aCellIter( pDoc, nCol,nRow1,nTab, nCol,nRow2,nTab );
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while ( pCell && nInsCount < SC_DET_MAXCIRCLE )
+ {
+ SCROW nCellRow = aCellIter.GetRow();
+ if ( bMarkEmpty )
+ for ( nRow = nNextRow; nRow < nCellRow && nInsCount < SC_DET_MAXCIRCLE; nRow++ )
+ {
+ DrawCircle( nCol, nRow, aData );
+ ++nInsCount;
+ }
+ if ( !pData->IsDataValid( pCell, ScAddress( nCol, nCellRow, nTab ) ) )
+ {
+ DrawCircle( nCol, nCellRow, aData );
+ ++nInsCount;
+ }
+ nNextRow = nCellRow + 1;
+ pCell = aCellIter.GetNext();
+ }
+ if ( bMarkEmpty )
+ for ( nRow = nNextRow; nRow <= nRow2 && nInsCount < SC_DET_MAXCIRCLE; nRow++ )
+ {
+ DrawCircle( nCol, nRow, aData );
+ ++nInsCount;
+ }
+ }
+ }
+
+ pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 );
+ }
+
+ if ( nInsCount >= SC_DET_MAXCIRCLE )
+ rOverflow = TRUE;
+
+ return ( bDeleted || nInsCount != 0 );
+}
+
+void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
+{
+ // for all caption objects, update attributes and SpecialTextBoxShadow flag
+ // (on all tables - nTab is ignored!)
+
+ // no undo actions, this is refreshed after undo
+
+ ScDrawLayer* pModel = rDoc.GetDrawLayer();
+ if (!pModel)
+ return;
+
+ 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 )
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ for( SdrObject* pObject = aIter.Next(); pObject; pObject = aIter.Next() )
+ {
+ 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 )
+ {
+ ScCommentData aData( rDoc, pModel );
+ SfxItemSet aAttrColorSet = pObject->GetMergedItemSet();
+ aAttrColorSet.Put( XFillColorItem( String(), GetCommentColor() ) );
+ aData.UpdateCaptionSet( aAttrColorSet );
+ pObject->SetMergedItemSetAndBroadcast( aData.GetCaptionSet() );
+ if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
+ {
+ pCaption->SetSpecialTextBoxShadow();
+ pCaption->SetFixedTail();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScDetectiveFunc::UpdateAllArrowColors()
+{
+ // no undo actions necessary
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return;
+
+ for( SCTAB nObjTab = 0, nTabCount = pDoc->GetTableCount(); nObjTab < nTabCount; ++nObjTab )
+ {
+ SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
+ DBG_ASSERT( pPage, "Page ?" );
+ if( pPage )
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ for( SdrObject* pObject = aIter.Next(); pObject; pObject = aIter.Next() )
+ {
+ if ( pObject->GetLayer() == SC_LAYER_INTERN )
+ {
+ BOOL bArrow = FALSE;
+ BOOL bError = FALSE;
+
+ ScAddress aPos;
+ ScRange aSource;
+ BOOL bDummy;
+ ScDetectiveObjType eType = GetDetectiveObjectType( pObject, nObjTab, aPos, aSource, bDummy );
+ if ( eType == SC_DETOBJ_ARROW || eType == SC_DETOBJ_TOOTHERTAB )
+ {
+ // source is valid, determine error flag from source range
+
+ ScAddress aErrPos;
+ if ( HasError( aSource, aErrPos ) )
+ bError = TRUE;
+ else
+ bArrow = TRUE;
+ }
+ else if ( eType == SC_DETOBJ_FROMOTHERTAB )
+ {
+ // source range is no longer known, take error flag from formula itself
+ // (this means, if the formula has an error, all references to other tables
+ // are marked red)
+
+ ScAddress aErrPos;
+ if ( HasError( ScRange( aPos), aErrPos ) )
+ bError = TRUE;
+ else
+ bArrow = TRUE;
+ }
+ else if ( eType == SC_DETOBJ_CIRCLE )
+ {
+ // circles (error marks) are always red
+
+ bError = TRUE;
+ }
+ else if ( eType == SC_DETOBJ_NONE )
+ {
+ // frame for area reference has no ObjType, always gets arrow color
+
+ if ( pObject->ISA( SdrRectObj ) && !pObject->ISA( SdrCaptionObj ) )
+ {
+ bArrow = TRUE;
+ }
+ }
+
+ if ( bArrow || bError )
+ {
+ ColorData nColorData = ( bError ? GetErrorColor() : GetArrowColor() );
+ //pObject->SendRepaintBroadcast(pObject->GetBoundRect());
+ pObject->SetMergedItem( XLineColorItem( String(), Color( nColorData ) ) );
+
+ // repaint only
+ pObject->ActionChanged();
+ // pObject->SendRepaintBroadcast(pObject->GetBoundRect());
+ }
+ }
+ }
+ }
+ }
+}
+
+BOOL ScDetectiveFunc::FindFrameForObject( SdrObject* pObject, ScRange& rRange )
+{
+ // find the rectangle for an arrow (always the object directly before the arrow)
+ // rRange must be initialized to the source cell of the arrow (start of area)
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel) return FALSE;
+
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (!pPage) return FALSE;
+
+ // test if the object is a direct page member
+ if( pObject && pObject->GetPage() && (pObject->GetPage() == pObject->GetObjList()) )
+ {
+ // Is there a previous object?
+ const sal_uInt32 nOrdNum(pObject->GetOrdNum());
+
+ if(nOrdNum > 0)
+ {
+ SdrObject* pPrevObj = pPage->GetObj(nOrdNum - 1);
+
+ if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && pPrevObj->ISA(SdrRectObj) )
+ {
+ ScDrawObjData* pPrevData = ScDrawLayer::GetObjDataTab( pPrevObj, rRange.aStart.Tab() );
+ if ( pPrevData && pPrevData->maStart.IsValid() && pPrevData->maEnd.IsValid() && (pPrevData->maStart == rRange.aStart) )
+ {
+ rRange.aEnd = pPrevData->maEnd;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+ScDetectiveObjType ScDetectiveFunc::GetDetectiveObjectType( SdrObject* pObject, SCTAB nObjTab,
+ ScAddress& rPosition, ScRange& rSource, BOOL& rRedLine )
+{
+ rRedLine = FALSE;
+ ScDetectiveObjType eType = SC_DETOBJ_NONE;
+
+ if ( pObject && pObject->GetLayer() == SC_LAYER_INTERN )
+ {
+ if ( ScDrawObjData* pData = ScDrawLayer::GetObjDataTab( pObject, nObjTab ) )
+ {
+ bool bValidStart = pData->maStart.IsValid();
+ bool bValidEnd = pData->maEnd.IsValid();
+
+ if ( pObject->IsPolyObj() && pObject->GetPointCount() == 2 )
+ {
+ // line object -> arrow
+
+ if ( bValidStart )
+ eType = bValidEnd ? SC_DETOBJ_ARROW : SC_DETOBJ_TOOTHERTAB;
+ else if ( bValidEnd )
+ eType = SC_DETOBJ_FROMOTHERTAB;
+
+ if ( bValidStart )
+ rSource = pData->maStart;
+ if ( bValidEnd )
+ rPosition = pData->maEnd;
+
+ if ( bValidStart && lcl_HasThickLine( *pObject ) )
+ {
+ // thick line -> look for frame before this object
+
+ FindFrameForObject( pObject, rSource ); // modifies rSource
+ }
+
+ ColorData nObjColor = ((const XLineColorItem&)pObject->GetMergedItem(XATTR_LINECOLOR)).GetColorValue().GetColor();
+ if ( nObjColor == GetErrorColor() && nObjColor != GetArrowColor() )
+ rRedLine = TRUE;
+ }
+ else if ( pObject->ISA(SdrCircObj) )
+ {
+ if ( bValidStart )
+ {
+ // cell position is returned in rPosition
+
+ rPosition = pData->maStart;
+ eType = SC_DETOBJ_CIRCLE;
+ }
+ }
+ }
+ }
+
+ return eType;
+}
+
+void ScDetectiveFunc::InsertObject( ScDetectiveObjType eType,
+ const ScAddress& rPosition, const ScRange& rSource,
+ BOOL bRedLine )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel) return;
+ ScDetectiveData aData( pModel );
+
+ switch (eType)
+ {
+ case SC_DETOBJ_ARROW:
+ case SC_DETOBJ_FROMOTHERTAB:
+ InsertArrow( rPosition.Col(), rPosition.Row(),
+ rSource.aStart.Col(), rSource.aStart.Row(),
+ rSource.aEnd.Col(), rSource.aEnd.Row(),
+ (eType == SC_DETOBJ_FROMOTHERTAB), bRedLine, aData );
+ break;
+ case SC_DETOBJ_TOOTHERTAB:
+ InsertToOtherTab( rSource.aStart.Col(), rSource.aStart.Row(),
+ rSource.aEnd.Col(), rSource.aEnd.Row(),
+ bRedLine, aData );
+ break;
+ case SC_DETOBJ_CIRCLE:
+ DrawCircle( rPosition.Col(), rPosition.Row(), aData );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+// static
+ColorData ScDetectiveFunc::GetArrowColor()
+{
+ if (!bColorsInitialized)
+ InitializeColors();
+ return nArrowColor;
+}
+
+// static
+ColorData ScDetectiveFunc::GetErrorColor()
+{
+ if (!bColorsInitialized)
+ InitializeColors();
+ return nErrorColor;
+}
+
+// static
+ColorData ScDetectiveFunc::GetCommentColor()
+{
+ if (!bColorsInitialized)
+ InitializeColors();
+ return nCommentColor;
+}
+
+// static
+void ScDetectiveFunc::InitializeColors()
+{
+ // may be called several times to update colors from configuration
+
+ const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
+ nArrowColor = rColorCfg.GetColorValue(svtools::CALCDETECTIVE).nColor;
+ nErrorColor = rColorCfg.GetColorValue(svtools::CALCDETECTIVEERROR).nColor;
+ nCommentColor = rColorCfg.GetColorValue(svtools::CALCNOTESBACKGROUND).nColor;
+
+ bColorsInitialized = TRUE;
+}
+
+// static
+BOOL ScDetectiveFunc::IsColorsInitialized()
+{
+ return bColorsInitialized;
+}
+
diff --git a/sc/source/core/tool/docoptio.cxx b/sc/source/core/tool/docoptio.cxx
new file mode 100644
index 000000000000..95ce357b3217
--- /dev/null
+++ b/sc/source/core/tool/docoptio.cxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+#include <svl/zforlist.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "cfgids.hxx"
+#include "docoptio.hxx"
+#include "rechead.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "miscuno.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+//------------------------------------------------------------------------
+
+#define SC_VERSION ((USHORT)251)
+
+TYPEINIT1(ScTpCalcItem, SfxPoolItem);
+
+//------------------------------------------------------------------------
+
+//! these functions should be moved to some header file
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+
+inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; }
+
+//------------------------------------------------------------------------
+
+USHORT lcl_GetDefaultTabDist()
+{
+ if ( ScOptionsUtil::IsMetricSystem() )
+ return 709; // 1,25 cm
+ else
+ return 720; // 1/2"
+}
+
+//========================================================================
+// ScDocOptions - Dokument-Optionen
+//========================================================================
+
+ScDocOptions::ScDocOptions()
+{
+ ResetDocOptions();
+}
+
+//------------------------------------------------------------------------
+
+ScDocOptions::ScDocOptions( const ScDocOptions& rCpy )
+ : fIterEps( rCpy.fIterEps ),
+ nIterCount( rCpy.nIterCount ),
+ nPrecStandardFormat( rCpy.nPrecStandardFormat ),
+ nDay( rCpy.nDay ),
+ nMonth( rCpy.nMonth ),
+ nYear( rCpy.nYear ),
+ nYear2000( rCpy.nYear2000 ),
+ nTabDistance( rCpy.nTabDistance ),
+ bIsIgnoreCase( rCpy.bIsIgnoreCase ),
+ bIsIter( rCpy.bIsIter ),
+ bCalcAsShown( rCpy.bCalcAsShown ),
+ bMatchWholeCell( rCpy.bMatchWholeCell ),
+ bDoAutoSpell( rCpy.bDoAutoSpell ),
+ bLookUpColRowNames( rCpy.bLookUpColRowNames ),
+ bFormulaRegexEnabled( rCpy.bFormulaRegexEnabled )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScDocOptions::~ScDocOptions()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScDocOptions::ResetDocOptions()
+{
+ bIsIgnoreCase = FALSE;
+ bIsIter = FALSE;
+ nIterCount = 100;
+ fIterEps = 1.0E-3;
+ nPrecStandardFormat = SvNumberFormatter::UNLIMITED_PRECISION;
+ nDay = 30;
+ nMonth = 12;
+ nYear = 1899;
+ nYear2000 = SvNumberFormatter::GetYear2000Default();
+ nTabDistance = lcl_GetDefaultTabDist();
+ bCalcAsShown = FALSE;
+ bMatchWholeCell = TRUE;
+ bDoAutoSpell = FALSE;
+ bLookUpColRowNames = TRUE;
+ bFormulaRegexEnabled= TRUE;
+}
+
+//========================================================================
+// ScTpCalcItem - Daten fuer die CalcOptions-TabPage
+//========================================================================
+
+//UNUSED2008-05 ScTpCalcItem::ScTpCalcItem( USHORT nWhichP ) : SfxPoolItem( nWhichP )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------------
+
+ScTpCalcItem::ScTpCalcItem( USHORT nWhichP, const ScDocOptions& rOpt )
+ : SfxPoolItem ( nWhichP ),
+ theOptions ( rOpt )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScTpCalcItem::ScTpCalcItem( const ScTpCalcItem& rItem )
+ : SfxPoolItem ( rItem ),
+ theOptions ( rItem.theOptions )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScTpCalcItem::~ScTpCalcItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScTpCalcItem::GetValueText() const
+{
+ return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("ScTpCalcItem") );
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScTpCalcItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScTpCalcItem& rPItem = (const ScTpCalcItem&)rItem;
+
+ return ( theOptions == rPItem.theOptions );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScTpCalcItem::Clone( SfxItemPool * ) const
+{
+ return new ScTpCalcItem( *this );
+}
+
+//==================================================================
+// Config Item containing document options
+//==================================================================
+
+#define CFGPATH_CALC "Office.Calc/Calculate"
+
+#define SCCALCOPT_ITER_ITER 0
+#define SCCALCOPT_ITER_STEPS 1
+#define SCCALCOPT_ITER_MINCHG 2
+#define SCCALCOPT_DATE_DAY 3
+#define SCCALCOPT_DATE_MONTH 4
+#define SCCALCOPT_DATE_YEAR 5
+#define SCCALCOPT_DECIMALS 6
+#define SCCALCOPT_CASESENSITIVE 7
+#define SCCALCOPT_PRECISION 8
+#define SCCALCOPT_SEARCHCRIT 9
+#define SCCALCOPT_FINDLABEL 10
+#define SCCALCOPT_REGEX 11
+#define SCCALCOPT_COUNT 12
+
+#define CFGPATH_DOCLAYOUT "Office.Calc/Layout/Other"
+
+#define SCDOCLAYOUTOPT_TABSTOP 0
+#define SCDOCLAYOUTOPT_COUNT 1
+
+
+Sequence<OUString> ScDocCfg::GetCalcPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "IterativeReference/Iteration", // SCCALCOPT_ITER_ITER
+ "IterativeReference/Steps", // SCCALCOPT_ITER_STEPS
+ "IterativeReference/MinimumChange", // SCCALCOPT_ITER_MINCHG
+ "Other/Date/DD", // SCCALCOPT_DATE_DAY
+ "Other/Date/MM", // SCCALCOPT_DATE_MONTH
+ "Other/Date/YY", // SCCALCOPT_DATE_YEAR
+ "Other/DecimalPlaces", // SCCALCOPT_DECIMALS
+ "Other/CaseSensitive", // SCCALCOPT_CASESENSITIVE
+ "Other/Precision", // SCCALCOPT_PRECISION
+ "Other/SearchCriteria", // SCCALCOPT_SEARCHCRIT
+ "Other/FindLabel", // SCCALCOPT_FINDLABEL
+ "Other/RegularExpressions" // SCCALCOPT_REGEX
+ };
+ Sequence<OUString> aNames(SCCALCOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCCALCOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScDocCfg::GetLayoutPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "TabStop/NonMetric" // SCDOCLAYOUTOPT_TABSTOP
+ };
+ Sequence<OUString> aNames(SCDOCLAYOUTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCDOCLAYOUTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ // adjust for metric system
+ if (ScOptionsUtil::IsMetricSystem())
+ pNames[SCDOCLAYOUTOPT_TABSTOP] = OUString::createFromAscii( "TabStop/Metric" );
+
+ return aNames;
+}
+
+ScDocCfg::ScDocCfg() :
+ aCalcItem( OUString::createFromAscii( CFGPATH_CALC ) ),
+ aLayoutItem( OUString::createFromAscii( CFGPATH_DOCLAYOUT ) )
+{
+ sal_Int32 nIntVal = 0;
+ double fDoubleVal = 0;
+
+ Sequence<OUString> aNames;
+ Sequence<Any> aValues;
+ const Any* pValues = NULL;
+
+ USHORT nDateDay, nDateMonth, nDateYear;
+ GetDate( nDateDay, nDateMonth, nDateYear );
+
+ aNames = GetCalcPropertyNames();
+ aValues = aCalcItem.GetProperties(aNames);
+ aCalcItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCCALCOPT_ITER_ITER:
+ SetIter( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCCALCOPT_ITER_STEPS:
+ if (pValues[nProp] >>= nIntVal) SetIterCount( (USHORT) nIntVal );
+ break;
+ case SCCALCOPT_ITER_MINCHG:
+ if (pValues[nProp] >>= fDoubleVal) SetIterEps( fDoubleVal );
+ break;
+ case SCCALCOPT_DATE_DAY:
+ if (pValues[nProp] >>= nIntVal) nDateDay = (USHORT) nIntVal;
+ break;
+ case SCCALCOPT_DATE_MONTH:
+ if (pValues[nProp] >>= nIntVal) nDateMonth = (USHORT) nIntVal;
+ break;
+ case SCCALCOPT_DATE_YEAR:
+ if (pValues[nProp] >>= nIntVal) nDateYear = (USHORT) nIntVal;
+ break;
+ case SCCALCOPT_DECIMALS:
+ if (pValues[nProp] >>= nIntVal) SetStdPrecision( (USHORT) nIntVal );
+ break;
+ case SCCALCOPT_CASESENSITIVE:
+ // content is reversed
+ SetIgnoreCase( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCCALCOPT_PRECISION:
+ SetCalcAsShown( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCCALCOPT_SEARCHCRIT:
+ SetMatchWholeCell( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCCALCOPT_FINDLABEL:
+ SetLookUpColRowNames( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCCALCOPT_REGEX :
+ SetFormulaRegexEnabled( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+ aCalcItem.SetCommitLink( LINK( this, ScDocCfg, CalcCommitHdl ) );
+
+ SetDate( nDateDay, nDateMonth, nDateYear );
+
+ aNames = GetLayoutPropertyNames();
+ aValues = aLayoutItem.GetProperties(aNames);
+ aLayoutItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCDOCLAYOUTOPT_TABSTOP:
+ // TabDistance in ScDocOptions is in twips
+ if (pValues[nProp] >>= nIntVal)
+ SetTabDistance( (USHORT) HMMToTwips( nIntVal ) );
+ break;
+ }
+ }
+ }
+ }
+ aLayoutItem.SetCommitLink( LINK( this, ScDocCfg, LayoutCommitHdl ) );
+}
+
+IMPL_LINK( ScDocCfg, CalcCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetCalcPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ USHORT nDateDay, nDateMonth, nDateYear;
+ GetDate( nDateDay, nDateMonth, nDateYear );
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCCALCOPT_ITER_ITER:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsIter() );
+ break;
+ case SCCALCOPT_ITER_STEPS:
+ pValues[nProp] <<= (sal_Int32) GetIterCount();
+ break;
+ case SCCALCOPT_ITER_MINCHG:
+ pValues[nProp] <<= (double) GetIterEps();
+ break;
+ case SCCALCOPT_DATE_DAY:
+ pValues[nProp] <<= (sal_Int32) nDateDay;
+ break;
+ case SCCALCOPT_DATE_MONTH:
+ pValues[nProp] <<= (sal_Int32) nDateMonth;
+ break;
+ case SCCALCOPT_DATE_YEAR:
+ pValues[nProp] <<= (sal_Int32) nDateYear;
+ break;
+ case SCCALCOPT_DECIMALS:
+ pValues[nProp] <<= (sal_Int32) GetStdPrecision();
+ break;
+ case SCCALCOPT_CASESENSITIVE:
+ // content is reversed
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], !IsIgnoreCase() );
+ break;
+ case SCCALCOPT_PRECISION:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsCalcAsShown() );
+ break;
+ case SCCALCOPT_SEARCHCRIT:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsMatchWholeCell() );
+ break;
+ case SCCALCOPT_FINDLABEL:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsLookUpColRowNames() );
+ break;
+ case SCCALCOPT_REGEX :
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsFormulaRegexEnabled() );
+ }
+ }
+ aCalcItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScDocCfg, LayoutCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetLayoutPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCDOCLAYOUTOPT_TABSTOP:
+ // TabDistance in ScDocOptions is in twips
+ // use only even numbers, so defaults don't get changed
+ // by modifying other settings in the same config item
+ pValues[nProp] <<= (sal_Int32) TwipsToEvenHMM( GetTabDistance() );
+ break;
+ }
+ }
+ aLayoutItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+
+void ScDocCfg::SetOptions( const ScDocOptions& rNew )
+{
+ *(ScDocOptions*)this = rNew;
+
+ aCalcItem.SetModified();
+ aLayoutItem.SetModified();
+}
+
+
diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx
new file mode 100644
index 000000000000..740413ea8533
--- /dev/null
+++ b/sc/source/core/tool/doubleref.cxx
@@ -0,0 +1,565 @@
+/*************************************************************************
+ *
+ * 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: interpre.hxx,v $
+ * $Revision: 1.35.44.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "doubleref.hxx"
+#include "cell.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "queryparam.hxx"
+#include "globstr.hrc"
+
+#include <memory>
+#include <vector>
+
+using ::rtl::OUString;
+using ::std::auto_ptr;
+using ::std::vector;
+
+namespace {
+
+void lcl_toUpper(OUString& rStr)
+{
+ rStr = ScGlobal::pCharClass->toUpper(rStr.trim(), 0, static_cast<xub_StrLen>(rStr.getLength()));
+}
+
+bool lcl_createStarQuery(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
+{
+ // A valid StarQuery must be at least 4 columns wide. To be precise it
+ // should be exactly 4 columns ...
+ // Additionally, if this wasn't checked, a formula pointing to a valid 1-3
+ // column Excel style query range immediately left to itself would result
+ // in a circular reference when the field name or operator or value (first
+ // to third query range column) is obtained (#i58354#). Furthermore, if the
+ // range wasn't sufficiently specified data changes wouldn't flag formula
+ // cells for recalculation.
+
+ if (pQueryRef->getColSize() < 4)
+ return false;
+
+ BOOL bValid;
+ BOOL bFound;
+ OUString aCellStr;
+ SCSIZE nIndex = 0;
+ SCROW nRow = 0;
+ SCROW nRows = pDBRef->getRowSize();
+ SCSIZE nNewEntries = static_cast<SCSIZE>(nRows);
+ pParam->Resize(nNewEntries);
+
+ do
+ {
+ ScQueryEntry& rEntry = pParam->GetEntry(nIndex);
+
+ bValid = FALSE;
+
+ if (nIndex > 0)
+ {
+ // For all entries after the first one, check the and/or connector in the first column.
+ aCellStr = pQueryRef->getString(0, nRow);
+ lcl_toUpper(aCellStr);
+ if ( aCellStr.equals(ScGlobal::GetRscString(STR_TABLE_UND)) )
+ {
+ rEntry.eConnect = SC_AND;
+ bValid = TRUE;
+ }
+ else if ( aCellStr.equals(ScGlobal::GetRscString(STR_TABLE_ODER)) )
+ {
+ rEntry.eConnect = SC_OR;
+ bValid = TRUE;
+ }
+ }
+
+ if ((nIndex < 1) || bValid)
+ {
+ // field name in the 2nd column.
+ bFound = FALSE;
+ aCellStr = pQueryRef->getString(1, nRow);
+ SCCOL nField = pDBRef->findFieldColumn(aCellStr); // TODO: must be case insensitive comparison.
+ if (ValidCol(nField))
+ {
+ rEntry.nField = nField;
+ bValid = true;
+ }
+ else
+ bValid = false;
+ }
+
+ if (bValid)
+ {
+ // equality, non-equality operator in the 3rd column.
+ bFound = FALSE;
+ aCellStr = pQueryRef->getString(2, nRow);
+ lcl_toUpper(aCellStr);
+ const sal_Unicode* p = aCellStr.getStr();
+ if (p[0] == sal_Unicode('<'))
+ {
+ if (p[1] == sal_Unicode('>'))
+ rEntry.eOp = SC_NOT_EQUAL;
+ else if (p[1] == sal_Unicode('='))
+ rEntry.eOp = SC_LESS_EQUAL;
+ else
+ rEntry.eOp = SC_LESS;
+ }
+ else if (p[0] == sal_Unicode('>'))
+ {
+ if (p[1] == sal_Unicode('='))
+ rEntry.eOp = SC_GREATER_EQUAL;
+ else
+ rEntry.eOp = SC_GREATER;
+ }
+ else if (p[0] == sal_Unicode('='))
+ rEntry.eOp = SC_EQUAL;
+
+ }
+
+ if (bValid)
+ {
+ // Finally, the right-hand-side value in the 4th column.
+ *rEntry.pStr = pQueryRef->getString(3, nRow);
+ rEntry.bDoQuery = TRUE;
+ }
+ nIndex++;
+ nRow++;
+ }
+ while (bValid && (nRow < nRows) /* && (nIndex < MAXQUERY) */ );
+ return bValid;
+}
+
+bool lcl_createExcelQuery(
+ ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
+{
+ bool bValid = true;
+ SCCOL nCols = pQueryRef->getColSize();
+ SCROW nRows = pQueryRef->getRowSize();
+ vector<SCCOL> aFields(nCols);
+ SCCOL nCol = 0;
+ while (bValid && (nCol < nCols))
+ {
+ OUString aQueryStr = pQueryRef->getString(nCol, 0);
+ SCCOL nField = pDBRef->findFieldColumn(aQueryStr);
+ if (ValidCol(nField))
+ aFields[nCol] = nField;
+ else
+ bValid = false;
+ ++nCol;
+ }
+
+ if (bValid)
+ {
+// ULONG nVisible = 0;
+// for ( nCol=nCol1; nCol<=nCol2; nCol++ )
+// nVisible += aCol[nCol].VisibleCount( nRow1+1, nRow2 );
+
+ // Count the number of visible cells (excluding the header row). Each
+ // visible cell corresponds with a single query.
+ SCSIZE nVisible = pQueryRef->getVisibleDataCellCount();
+ if ( nVisible > SCSIZE_MAX / sizeof(void*) )
+ {
+ DBG_ERROR("zu viele Filterkritierien");
+ nVisible = 0;
+ }
+
+ SCSIZE nNewEntries = nVisible;
+ pParam->Resize( nNewEntries );
+
+ SCSIZE nIndex = 0;
+ SCROW nRow = 1;
+ String aCellStr;
+ while (nRow < nRows)
+ {
+ nCol = 0;
+ while (nCol < nCols)
+ {
+ aCellStr = pQueryRef->getString(nCol, nRow);
+ ScGlobal::pCharClass->toUpper( aCellStr );
+ if (aCellStr.Len() > 0)
+ {
+ if (nIndex < nNewEntries)
+ {
+ pParam->GetEntry(nIndex).nField = aFields[nCol];
+ pParam->FillInExcelSyntax(aCellStr, nIndex);
+ nIndex++;
+ if (nIndex < nNewEntries)
+ pParam->GetEntry(nIndex).eConnect = SC_AND;
+ }
+ else
+ bValid = FALSE;
+ }
+ nCol++;
+ }
+ nRow++;
+ if (nIndex < nNewEntries)
+ pParam->GetEntry(nIndex).eConnect = SC_OR;
+ }
+ }
+ return bValid;
+}
+
+bool lcl_fillQueryEntries(
+ ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
+{
+ SCSIZE nCount = pParam->GetEntryCount();
+ for (SCSIZE i = 0; i < nCount; ++i)
+ pParam->GetEntry(i).Clear();
+
+ // Standard QueryTabelle
+ bool bValid = lcl_createStarQuery(pParam, pDBRef, pQueryRef);
+ // Excel QueryTabelle
+ if (!bValid)
+ bValid = lcl_createExcelQuery(pParam, pDBRef, pQueryRef);
+
+ nCount = pParam->GetEntryCount();
+ if (bValid)
+ {
+ // bQueryByString muss gesetzt sein
+ for (SCSIZE i = 0; i < nCount; ++i)
+ pParam->GetEntry(i).bQueryByString = true;
+ }
+ else
+ {
+ // nix
+ for (SCSIZE i = 0; i < nCount; ++i)
+ pParam->GetEntry(i).Clear();
+ }
+ return bValid;
+}
+
+}
+
+// ============================================================================
+
+ScDBRangeBase::ScDBRangeBase(ScDocument* pDoc, RefType eType) :
+ mpDoc(pDoc), meType(eType)
+{
+}
+
+ScDBRangeBase::~ScDBRangeBase()
+{
+}
+
+bool ScDBRangeBase::fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const
+{
+ if (!pDBRef)
+ return false;
+
+ return lcl_fillQueryEntries(pParam, pDBRef, this);
+}
+
+void ScDBRangeBase::fillQueryOptions(ScQueryParamBase* pParam)
+{
+ pParam->bHasHeader = true;
+ pParam->bByRow = true;
+ pParam->bInplace = true;
+ pParam->bCaseSens = false;
+ pParam->bRegExp = false;
+ pParam->bDuplicate = true;
+ pParam->bMixedComparison = false;
+}
+
+ScDocument* ScDBRangeBase::getDoc() const
+{
+ return mpDoc;
+}
+
+// ============================================================================
+
+ScDBInternalRange::ScDBInternalRange(ScDocument* pDoc, const ScRange& rRange) :
+ ScDBRangeBase(pDoc, INTERNAL), maRange(rRange)
+{
+}
+
+ScDBInternalRange::~ScDBInternalRange()
+{
+}
+
+const ScRange& ScDBInternalRange::getRange() const
+{
+ return maRange;
+}
+
+SCCOL ScDBInternalRange::getColSize() const
+{
+ return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
+}
+
+SCROW ScDBInternalRange::getRowSize() const
+{
+ return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
+}
+
+SCSIZE ScDBInternalRange::getVisibleDataCellCount() const
+{
+ SCCOL nCols = getColSize();
+ SCROW nRows = getRowSize();
+ if (nRows <= 1)
+ return 0;
+
+ return (nRows-1)*nCols;
+}
+
+OUString ScDBInternalRange::getString(SCCOL nCol, SCROW nRow) const
+{
+ String aStr;
+ const ScAddress& s = maRange.aStart;
+ // #i109200# this is used in formula calculation, use GetInputString, not GetString
+ // (consistent with ScDBInternalRange::getCellString)
+ getDoc()->GetInputString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr);
+ return aStr;
+}
+
+SCCOL ScDBInternalRange::getFirstFieldColumn() const
+{
+ return getRange().aStart.Col();
+}
+
+SCCOL ScDBInternalRange::findFieldColumn(SCCOL nIndex) const
+{
+ const ScRange& rRange = getRange();
+ const ScAddress& s = rRange.aStart;
+ const ScAddress& e = rRange.aEnd;
+
+ SCCOL nDBCol1 = s.Col();
+ SCCOL nDBCol2 = e.Col();
+
+ if ( nIndex <= 0 || nIndex > (nDBCol2 - nDBCol1 + 1) )
+ return nDBCol1;
+
+ return Min(nDBCol2, static_cast<SCCOL>(nDBCol1 + nIndex - 1));
+}
+
+sal_uInt16 ScDBInternalRange::getCellString(OUString& rStr, ScBaseCell* pCell) const
+{
+ sal_uInt16 nErr = 0;
+ String aStr;
+ if (pCell)
+ {
+ SvNumberFormatter* pFormatter = getDoc()->GetFormatTable();
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_STRING:
+ ((ScStringCell*) pCell)->GetString(aStr);
+ break;
+ case CELLTYPE_EDIT:
+ ((ScEditCell*) pCell)->GetString(aStr);
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ nErr = pFCell->GetErrCode();
+ if (pFCell->IsValue())
+ {
+ double fVal = pFCell->GetValue();
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ pFormatter->GetInputLineString(fVal, nIndex, aStr);
+ }
+ else
+ pFCell->GetString(aStr);
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ double fVal = ((ScValueCell*) pCell)->GetValue();
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ pFormatter->GetInputLineString(fVal, nIndex, aStr);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ rStr = aStr;
+ return nErr;
+}
+
+SCCOL ScDBInternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const
+{
+ const ScAddress& s = maRange.aStart;
+ const ScAddress& e = maRange.aEnd;
+ OUString aUpper = rStr;
+ lcl_toUpper(aUpper);
+
+ SCCOL nDBCol1 = s.Col();
+ SCROW nDBRow1 = s.Row();
+ SCTAB nDBTab1 = s.Tab();
+ SCCOL nDBCol2 = e.Col();
+
+ SCCOL nField = nDBCol1;
+ BOOL bFound = TRUE;
+
+ bFound = FALSE;
+ OUString aCellStr;
+ ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 );
+ while (!bFound && (aLook.Col() <= nDBCol2))
+ {
+ ScBaseCell* pCell = getDoc()->GetCell( aLook );
+ sal_uInt16 nErr = getCellString( aCellStr, pCell );
+ if (pErr)
+ *pErr = nErr;
+ lcl_toUpper(aCellStr);
+ bFound = ScGlobal::GetpTransliteration()->isEqual(aCellStr, aUpper);
+ if (!bFound)
+ aLook.IncCol();
+ }
+ nField = aLook.Col();
+
+ return bFound ? nField : -1;
+}
+
+ScDBQueryParamBase* ScDBInternalRange::createQueryParam(const ScDBRangeBase* pQueryRef) const
+{
+ auto_ptr<ScDBQueryParamInternal> pParam(new ScDBQueryParamInternal);
+
+ // Set the database range first.
+ const ScAddress& s = maRange.aStart;
+ const ScAddress& e = maRange.aEnd;
+ pParam->nCol1 = s.Col();
+ pParam->nRow1 = s.Row();
+ pParam->nCol2 = e.Col();
+ pParam->nRow2 = e.Row();
+ pParam->nTab = s.Tab();
+
+ fillQueryOptions(pParam.get());
+
+ // Now construct the query entries from the query range.
+ if (!pQueryRef->fillQueryEntries(pParam.get(), this))
+ return NULL;
+
+ return pParam.release();
+}
+
+bool ScDBInternalRange::isRangeEqual(const ScRange& rRange) const
+{
+ return maRange == rRange;
+}
+
+// ============================================================================
+
+ScDBExternalRange::ScDBExternalRange(ScDocument* pDoc, const ScMatrixRef& pMat) :
+ ScDBRangeBase(pDoc, EXTERNAL), mpMatrix(pMat)
+{
+ SCSIZE nC, nR;
+ mpMatrix->GetDimensions(nC, nR);
+ mnCols = static_cast<SCCOL>(nC);
+ mnRows = static_cast<SCROW>(nR);
+}
+
+ScDBExternalRange::~ScDBExternalRange()
+{
+}
+
+SCCOL ScDBExternalRange::getColSize() const
+{
+ return mnCols;
+}
+
+SCROW ScDBExternalRange::getRowSize() const
+{
+ return mnRows;
+}
+
+SCSIZE ScDBExternalRange::getVisibleDataCellCount() const
+{
+ SCCOL nCols = getColSize();
+ SCROW nRows = getRowSize();
+ if (nRows <= 1)
+ return 0;
+
+ return (nRows-1)*nCols;
+}
+
+OUString ScDBExternalRange::getString(SCCOL nCol, SCROW nRow) const
+{
+ if (nCol >= mnCols || nRow >= mnRows)
+ return OUString();
+
+ return mpMatrix->GetString(nCol, nRow);
+}
+
+SCCOL ScDBExternalRange::getFirstFieldColumn() const
+{
+ return 0;
+}
+
+SCCOL ScDBExternalRange::findFieldColumn(SCCOL nIndex) const
+{
+ if (nIndex < 1)
+ // 1st field
+ return 0;
+
+ if (nIndex > mnCols)
+ // last field
+ return mnCols - 1;
+
+ return nIndex - 1;
+}
+
+SCCOL ScDBExternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const
+{
+ if (pErr)
+ pErr = 0;
+
+ OUString aUpper = rStr;
+ lcl_toUpper(aUpper);
+ for (SCCOL i = 0; i < mnCols; ++i)
+ {
+ OUString aUpperVal = mpMatrix->GetString(i, 0);
+ lcl_toUpper(aUpperVal);
+ if (aUpper.equals(aUpperVal))
+ return i;
+ }
+ return -1;
+}
+
+ScDBQueryParamBase* ScDBExternalRange::createQueryParam(const ScDBRangeBase* pQueryRef) const
+{
+ auto_ptr<ScDBQueryParamMatrix> pParam(new ScDBQueryParamMatrix);
+ pParam->mpMatrix = mpMatrix;
+ fillQueryOptions(pParam.get());
+
+ // Now construct the query entries from the query range.
+ if (!pQueryRef->fillQueryEntries(pParam.get(), this))
+ return NULL;
+
+ return pParam.release();
+}
+
+bool ScDBExternalRange::isRangeEqual(const ScRange& /*rRange*/) const
+{
+ return false;
+}
+
diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx
new file mode 100644
index 000000000000..483f0cea6b57
--- /dev/null
+++ b/sc/source/core/tool/editutil.cxx
@@ -0,0 +1,778 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/algitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/numitem.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+#include <svl/inethist.hxx>
+#include <unotools/syslocale.hxx>
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#endif
+
+#include "editutil.hxx"
+#include "global.hxx"
+#include "attrib.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#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[] = "=()+-*/^&<>";
+
+
+//------------------------------------------------------------------------
+
+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;
+}
+
+static String lcl_GetDelimitedString( const EditEngine& rEngine, const sal_Char c )
+{
+ String aRet;
+ USHORT nParCount = rEngine.GetParagraphCount();
+ for (USHORT nPar=0; nPar<nParCount; nPar++)
+ {
+ if (nPar > 0)
+ aRet += c;
+ aRet += rEngine.GetText( nPar );
+ }
+ return aRet;
+}
+
+String ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
+{
+ return lcl_GetDelimitedString(rEngine, ' ');
+}
+
+String ScEditUtil::GetMultilineString( const EditEngine& rEngine )
+{
+ return lcl_GetDelimitedString(rEngine, '\n');
+}
+
+//------------------------------------------------------------------------
+
+Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, BOOL bForceToTop )
+{
+ // bForceToTop = always align to top, for editing
+ // (FALSE for querying URLs etc.)
+
+ if (!pPattern)
+ pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+
+ Point aStartPos = aScrPos;
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ long nCellX = (long) ( pDoc->GetColWidth(nCol,nTab) * nPPTX );
+ if ( pMerge->GetColMerge() > 1 )
+ {
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nCellX += (long) ( pDoc->GetColWidth(nCol+i,nTab) * nPPTX );
+ }
+ long nCellY = (long) ( pDoc->GetRowHeight(nRow,nTab) * nPPTY );
+ if ( pMerge->GetRowMerge() > 1 )
+ {
+ SCROW nCountY = pMerge->GetRowMerge();
+ nCellY += (long) pDoc->GetScaledRowHeight( nRow+1, nRow+nCountY-1, nTab, nPPTY);
+ }
+
+ const SvxMarginItem* pMargin = (const SvxMarginItem*)&pPattern->GetItem(ATTR_MARGIN);
+ USHORT nIndent = 0;
+ if ( ((const SvxHorJustifyItem&)pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue() ==
+ SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue();
+ long nPixDifX = (long) ( ( pMargin->GetLeftMargin() + nIndent ) * nPPTX );
+ aStartPos.X() += nPixDifX * nLayoutSign;
+ nCellX -= nPixDifX + (long) ( pMargin->GetRightMargin() * nPPTX ); // wegen Umbruch etc.
+
+ // vertikale Position auf die in der Tabelle anpassen
+
+ long nPixDifY;
+ long nTopMargin = (long) ( pMargin->GetTopMargin() * nPPTY );
+ SvxCellVerJustify eJust = (SvxCellVerJustify) ((const SvxVerJustifyItem&)pPattern->
+ GetItem(ATTR_VER_JUSTIFY)).GetValue();
+
+ // asian vertical is always edited top-aligned
+ BOOL bAsianVertical = ((const SfxBoolItem&)pPattern->GetItem( ATTR_STACKED )).GetValue() &&
+ ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
+
+ if ( eJust == SVX_VER_JUSTIFY_TOP ||
+ ( bForceToTop && ( SC_MOD()->GetInputOptions().GetTextWysiwyg() || bAsianVertical ) ) )
+ nPixDifY = nTopMargin;
+ else
+ {
+ MapMode aMode = pDev->GetMapMode();
+ pDev->SetMapMode( MAP_PIXEL );
+
+ long nTextHeight = pDoc->GetNeededSize( nCol, nRow, nTab,
+ pDev, nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
+ if (!nTextHeight)
+ { // leere Zelle
+ Font aFont;
+ // font color doesn't matter here
+ pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aZoomY );
+ pDev->SetFont(aFont);
+ nTextHeight = pDev->GetTextHeight() + nTopMargin +
+ (long) ( pMargin->GetBottomMargin() * nPPTY );
+ }
+
+ pDev->SetMapMode(aMode);
+
+ if ( nTextHeight > nCellY + nTopMargin || bForceToTop )
+ nPixDifY = 0; // zu gross -> oben anfangen
+ else
+ {
+ if ( eJust == SVX_VER_JUSTIFY_CENTER )
+ nPixDifY = nTopMargin + ( nCellY - nTextHeight ) / 2;
+ else
+ nPixDifY = nCellY - nTextHeight + nTopMargin; // JUSTIFY_BOTTOM
+ }
+ }
+
+ aStartPos.Y() += nPixDifY;
+ nCellY -= nPixDifY;
+
+ if ( bLayoutRTL )
+ aStartPos.X() -= nCellX - 2; // excluding grid on both sides
+
+ // -1 -> Gitter nicht ueberschreiben
+ return Rectangle( aStartPos, Size(nCellX-1,nCellY-1) );
+}
+
+//------------------------------------------------------------------------
+
+ScEditAttrTester::ScEditAttrTester( ScEditEngineDefaulter* pEng ) :
+ pEngine( pEng ),
+ pEditAttrs( NULL ),
+ bNeedsObject( FALSE ),
+ bNeedsCellAttr( FALSE )
+{
+ if ( pEngine->GetParagraphCount() > 1 )
+ {
+ bNeedsObject = TRUE; //! Zellatribute finden ?
+ }
+ else
+ {
+ const SfxPoolItem* pItem = NULL;
+ pEditAttrs = new SfxItemSet( pEngine->GetAttribs(
+ ESelection(0,0,0,pEngine->GetTextLen(0)), EditEngineAttribs_OnlyHard ) );
+ const SfxItemSet& rEditDefaults = pEngine->GetDefaults();
+
+ for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
+ {
+ SfxItemState eState = pEditAttrs->GetItemState( nId, FALSE, &pItem );
+ if (eState == SFX_ITEM_DONTCARE)
+ bNeedsObject = TRUE;
+ else if (eState == SFX_ITEM_SET)
+ {
+ if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
+ nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
+ {
+ // Escapement and kerning are kept in EditEngine because there are no
+ // corresponding cell format items. User defined attributes are kept in
+ // EditEngine because "user attributes applied to all the text" is different
+ // from "user attributes applied to the cell".
+
+ if ( *pItem != rEditDefaults.Get(nId) )
+ bNeedsObject = TRUE;
+ }
+ else
+ if (!bNeedsCellAttr)
+ if ( *pItem != rEditDefaults.Get(nId) )
+ bNeedsCellAttr = TRUE;
+ // rEditDefaults contains the defaults from the cell format
+ }
+ }
+
+ // Feldbefehle enthalten?
+
+ SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, FALSE );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bNeedsObject = TRUE;
+
+ // not converted characters?
+
+ SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, FALSE );
+ if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
+ bNeedsObject = TRUE;
+ }
+}
+
+ScEditAttrTester::~ScEditAttrTester()
+{
+ delete pEditAttrs;
+}
+
+
+//------------------------------------------------------------------------
+
+ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
+ BOOL bDeleteEnginePoolP )
+ :
+ pEnginePool( pEnginePoolP ),
+ pDefaults( NULL ),
+ bDeleteEnginePool( bDeleteEnginePoolP ),
+ bDeleteDefaults( FALSE )
+{
+}
+
+
+ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg )
+ :
+ pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
+ pDefaults( NULL ),
+ bDeleteEnginePool( rOrg.bDeleteEnginePool ),
+ bDeleteDefaults( FALSE )
+{
+}
+
+
+ScEnginePoolHelper::~ScEnginePoolHelper()
+{
+ if ( bDeleteDefaults )
+ delete pDefaults;
+ if ( bDeleteEnginePool )
+ SfxItemPool::Free(pEnginePool);
+}
+
+
+//------------------------------------------------------------------------
+
+ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP,
+ BOOL bDeleteEnginePoolP )
+ :
+ ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
+ EditEngine( pEnginePoolP )
+{
+ // All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
+ // DefaultLanguage for InputHandler's EditEngine is updated later.
+
+ SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
+}
+
+
+ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg )
+ :
+ ScEnginePoolHelper( rOrg ),
+ EditEngine( pEnginePool )
+{
+ SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
+}
+
+
+ScEditEngineDefaulter::~ScEditEngineDefaulter()
+{
+}
+
+
+void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, BOOL bRememberCopy )
+{
+ if ( bRememberCopy )
+ {
+ if ( bDeleteDefaults )
+ delete pDefaults;
+ pDefaults = new SfxItemSet( rSet );
+ bDeleteDefaults = TRUE;
+ }
+ const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
+ BOOL bUndo = IsUndoEnabled();
+ EnableUndo( FALSE );
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ USHORT nPara = GetParagraphCount();
+ for ( USHORT j=0; j<nPara; j++ )
+ {
+ SetParaAttribs( j, rNewSet );
+ }
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+ if ( bUndo )
+ EnableUndo( TRUE );
+}
+
+
+void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, BOOL bTakeOwnership )
+{
+ if ( bDeleteDefaults )
+ delete pDefaults;
+ pDefaults = pSet;
+ bDeleteDefaults = bTakeOwnership;
+ if ( pDefaults )
+ SetDefaults( *pDefaults, FALSE );
+}
+
+
+void ScEditEngineDefaulter::SetDefaultItem( const SfxPoolItem& rItem )
+{
+ if ( !pDefaults )
+ {
+ pDefaults = new SfxItemSet( GetEmptyItemSet() );
+ bDeleteDefaults = TRUE;
+ }
+ pDefaults->Put( rItem );
+ SetDefaults( *pDefaults, FALSE );
+}
+
+const SfxItemSet& ScEditEngineDefaulter::GetDefaults()
+{
+ if ( !pDefaults )
+ {
+ pDefaults = new SfxItemSet( GetEmptyItemSet() );
+ bDeleteDefaults = TRUE;
+ }
+ return *pDefaults;
+}
+
+void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
+{
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ EditEngine::SetText( rTextObject );
+ if ( pDefaults )
+ SetDefaults( *pDefaults, FALSE );
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
+ const SfxItemSet& rSet, BOOL bRememberCopy )
+{
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ EditEngine::SetText( rTextObject );
+ SetDefaults( rSet, bRememberCopy );
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
+ SfxItemSet* pSet, BOOL bTakeOwnership )
+{
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ EditEngine::SetText( rTextObject );
+ SetDefaults( pSet, bTakeOwnership );
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+
+void ScEditEngineDefaulter::SetText( const String& rText )
+{
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ EditEngine::SetText( rText );
+ if ( pDefaults )
+ SetDefaults( *pDefaults, FALSE );
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText,
+ const SfxItemSet& rSet, BOOL bRememberCopy )
+{
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ EditEngine::SetText( rText );
+ SetDefaults( rSet, bRememberCopy );
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText,
+ SfxItemSet* pSet, BOOL bTakeOwnership )
+{
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ EditEngine::SetText( rText );
+ SetDefaults( pSet, bTakeOwnership );
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+void ScEditEngineDefaulter::RepeatDefaults()
+{
+ if ( pDefaults )
+ {
+ USHORT nPara = GetParagraphCount();
+ for ( USHORT j=0; j<nPara; j++ )
+ SetParaAttribs( j, *pDefaults );
+ }
+}
+
+void ScEditEngineDefaulter::RemoveParaAttribs()
+{
+ SfxItemSet* pCharItems = NULL;
+ BOOL bUpdateMode = GetUpdateMode();
+ if ( bUpdateMode )
+ SetUpdateMode( FALSE );
+ USHORT nParCount = GetParagraphCount();
+ for (USHORT nPar=0; nPar<nParCount; nPar++)
+ {
+ const SfxItemSet& rParaAttribs = GetParaAttribs( nPar );
+ USHORT nWhich;
+ for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
+ {
+ const SfxPoolItem* pParaItem;
+ if ( rParaAttribs.GetItemState( nWhich, FALSE, &pParaItem ) == SFX_ITEM_SET )
+ {
+ // if defaults are set, use only items that are different from default
+ if ( !pDefaults || *pParaItem != pDefaults->Get(nWhich) )
+ {
+ if (!pCharItems)
+ pCharItems = new SfxItemSet( GetEmptyItemSet() );
+ pCharItems->Put( *pParaItem );
+ }
+ }
+ }
+
+ if ( pCharItems )
+ {
+ SvUShorts aPortions;
+ GetPortions( nPar, aPortions );
+
+ // loop through the portions of the paragraph, and set only those items
+ // that are not overridden by existing character attributes
+
+ USHORT nPCount = aPortions.Count();
+ USHORT nStart = 0;
+ for ( USHORT nPos=0; nPos<nPCount; nPos++ )
+ {
+ USHORT nEnd = aPortions.GetObject( nPos );
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ SfxItemSet aOldCharAttrs = GetAttribs( aSel );
+ SfxItemSet aNewCharAttrs = *pCharItems;
+ for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
+ {
+ // Clear those items that are different from existing character attributes.
+ // Where no character attributes are set, GetAttribs returns the paragraph attributes.
+ const SfxPoolItem* pItem;
+ if ( aNewCharAttrs.GetItemState( nWhich, FALSE, &pItem ) == SFX_ITEM_SET &&
+ *pItem != aOldCharAttrs.Get(nWhich) )
+ {
+ aNewCharAttrs.ClearItem(nWhich);
+ }
+ }
+ if ( aNewCharAttrs.Count() )
+ QuickSetAttribs( aNewCharAttrs, aSel );
+
+ nStart = nEnd;
+ }
+
+ DELETEZ( pCharItems );
+ }
+
+ if ( rParaAttribs.Count() )
+ {
+ // clear all paragraph attributes (including defaults),
+ // so they are not contained in resulting EditTextObjects
+
+ SetParaAttribs( nPar, SfxItemSet( *rParaAttribs.GetPool(), rParaAttribs.GetRanges() ) );
+ }
+ }
+ if ( bUpdateMode )
+ SetUpdateMode( TRUE );
+}
+
+//------------------------------------------------------------------------
+
+ScTabEditEngine::ScTabEditEngine( ScDocument* pDoc )
+ : ScEditEngineDefaulter( pDoc->GetEnginePool() )
+{
+ SetEditTextObjectPool( pDoc->GetEditPool() );
+ Init((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
+}
+
+ScTabEditEngine::ScTabEditEngine( const ScPatternAttr& rPattern,
+ SfxItemPool* pEnginePoolP, SfxItemPool* pTextObjectPool )
+ : ScEditEngineDefaulter( pEnginePoolP )
+{
+ if ( pTextObjectPool )
+ SetEditTextObjectPool( pTextObjectPool );
+ Init( rPattern );
+}
+
+void ScTabEditEngine::Init( const ScPatternAttr& rPattern )
+{
+ SetRefMapMode(MAP_100TH_MM);
+ SfxItemSet* pEditDefaults = new SfxItemSet( GetEmptyItemSet() );
+ rPattern.FillEditItemSet( pEditDefaults );
+ SetDefaults( pEditDefaults );
+ // wir haben keine StyleSheets fuer Text
+ SetControlWord( GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
+}
+
+//------------------------------------------------------------------------
+// Feldbefehle fuer Kopf- und Fusszeilen
+//------------------------------------------------------------------------
+
+//
+// Zahlen aus \sw\source\core\doc\numbers.cxx
+//
+
+String lcl_GetCharStr( sal_Int32 nNo )
+{
+ DBG_ASSERT( nNo, "0 ist eine ungueltige Nummer !!" );
+ String aStr;
+
+ const sal_Int32 coDiff = 'Z' - 'A' +1;
+ sal_Int32 nCalc;
+
+ do {
+ nCalc = nNo % coDiff;
+ if( !nCalc )
+ nCalc = coDiff;
+ aStr.Insert( (sal_Unicode)('a' - 1 + nCalc ), 0 );
+ nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
+ if( nNo )
+ nNo /= coDiff;
+ } while( nNo );
+ return aStr;
+}
+
+String lcl_GetNumStr( sal_Int32 nNo, SvxNumType eType )
+{
+ String aTmpStr( '0' );
+ if( nNo )
+ {
+ switch( eType )
+ {
+ case SVX_CHARS_UPPER_LETTER:
+ case SVX_CHARS_LOWER_LETTER:
+ aTmpStr = lcl_GetCharStr( nNo );
+ break;
+
+ case SVX_ROMAN_UPPER:
+ case SVX_ROMAN_LOWER:
+ if( nNo < 4000 )
+ aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == SVX_ROMAN_UPPER ) );
+ else
+ aTmpStr.Erase();
+ break;
+
+ case SVX_NUMBER_NONE:
+ aTmpStr.Erase();
+ break;
+
+// CHAR_SPECIAL:
+// ????
+
+// case ARABIC: ist jetzt default
+ default:
+ aTmpStr = String::CreateFromInt32( nNo );
+ break;
+ }
+
+ if( SVX_CHARS_UPPER_LETTER == eType )
+ aTmpStr.ToUpperAscii();
+ }
+ return aTmpStr;
+}
+
+ScHeaderFieldData::ScHeaderFieldData()
+{
+ nPageNo = nTotalPages = 0;
+ eNumType = SVX_ARABIC;
+}
+
+ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePoolP, BOOL bDeleteEnginePoolP )
+ : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
+{
+}
+
+String __EXPORT ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
+ USHORT /* nPara */, USHORT /* nPos */,
+ Color*& /* rTxtColor */, Color*& /* rFldColor */ )
+{
+ String aRet;
+ const SvxFieldData* pFieldData = rField.GetField();
+ if ( pFieldData )
+ {
+ TypeId aType = pFieldData->Type();
+ if (aType == TYPE(SvxPageField))
+ aRet = lcl_GetNumStr( aData.nPageNo,aData.eNumType );
+ else if (aType == TYPE(SvxPagesField))
+ aRet = lcl_GetNumStr( aData.nTotalPages,aData.eNumType );
+ else if (aType == TYPE(SvxTimeField))
+ aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
+ else if (aType == TYPE(SvxFileField))
+ aRet = aData.aTitle;
+ else if (aType == TYPE(SvxExtFileField))
+ {
+ switch ( ((const SvxExtFileField*)pFieldData)->GetFormat() )
+ {
+ case SVXFILEFORMAT_FULLPATH :
+ aRet = aData.aLongDocName;
+ break;
+ default:
+ aRet = aData.aShortDocName;
+ }
+ }
+ else if (aType == TYPE(SvxTableField))
+ aRet = aData.aTabName;
+ else if (aType == TYPE(SvxDateField))
+ aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
+ else
+ {
+ //DBG_ERROR("unbekannter Feldbefehl");
+ aRet = '?';
+ }
+ }
+ else
+ {
+ DBG_ERROR("FieldData ist 0");
+ aRet = '?';
+ }
+
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+//
+// Feld-Daten
+//
+//------------------------------------------------------------------------
+
+ScFieldEditEngine::ScFieldEditEngine( SfxItemPool* pEnginePoolP,
+ SfxItemPool* pTextObjectPool, BOOL bDeleteEnginePoolP )
+ :
+ ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
+ bExecuteURL( TRUE )
+{
+ if ( pTextObjectPool )
+ SetEditTextObjectPool( pTextObjectPool );
+ // EE_CNTRL_URLSFXEXECUTE nicht, weil die Edit-Engine den ViewFrame nicht kennt
+ // wir haben keine StyleSheets fuer Text
+ SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
+}
+
+String __EXPORT ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
+ USHORT /* nPara */, USHORT /* nPos */,
+ Color*& rTxtColor, Color*& /* rFldColor */ )
+{
+ String aRet;
+ const SvxFieldData* pFieldData = rField.GetField();
+
+ if ( pFieldData )
+ {
+ TypeId aType = pFieldData->Type();
+
+ if (aType == TYPE(SvxURLField))
+ {
+ String aURL = ((const SvxURLField*)pFieldData)->GetURL();
+
+ switch ( ((const SvxURLField*)pFieldData)->GetFormat() )
+ {
+ case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
+ case SVXURLFORMAT_REPR:
+ aRet = ((const SvxURLField*)pFieldData)->GetRepresentation();
+ break;
+
+ case SVXURLFORMAT_URL:
+ aRet = aURL;
+ break;
+ }
+
+ svtools::ColorConfigEntry eEntry =
+ INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? svtools::LINKSVISITED : svtools::LINKS;
+ rTxtColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
+ }
+ else
+ {
+ //DBG_ERROR("unbekannter Feldbefehl");
+ aRet = '?';
+ }
+ }
+
+ if (!aRet.Len()) // leer ist baeh
+ aRet = ' '; // Space ist Default der Editengine
+
+ return aRet;
+}
+
+void __EXPORT ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, USHORT, USHORT )
+{
+ const SvxFieldData* pFld = rField.GetField();
+
+ if ( pFld && pFld->ISA( SvxURLField ) && bExecuteURL )
+ {
+ const SvxURLField* pURLField = (const SvxURLField*) pFld;
+ ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScNoteEditEngine::ScNoteEditEngine( SfxItemPool* pEnginePoolP,
+ SfxItemPool* pTextObjectPool, BOOL bDeleteEnginePoolP ) :
+ ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
+{
+ if ( pTextObjectPool )
+ SetEditTextObjectPool( pTextObjectPool );
+ SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
+}
diff --git a/sc/source/core/tool/filtopt.cxx b/sc/source/core/tool/filtopt.cxx
new file mode 100644
index 000000000000..7ac3d710b420
--- /dev/null
+++ b/sc/source/core/tool/filtopt.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "filtopt.hxx"
+#include "miscuno.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+//------------------------------------------------------------------
+
+#define CFGPATH_FILTER "Office.Calc/Filter/Import"
+
+#define SCFILTOPT_COLSCALE 0
+#define SCFILTOPT_ROWSCALE 1
+#define SCFILTOPT_WK3 2
+#define SCFILTOPT_COUNT 3
+
+Sequence<OUString> ScFilterOptions::GetPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "MS_Excel/ColScale", // SCFILTOPT_COLSCALE
+ "MS_Excel/RowScale", // SCFILTOPT_ROWSCALE
+ "Lotus123/WK3" // SCFILTOPT_WK3
+ };
+ Sequence<OUString> aNames(SCFILTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCFILTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+ScFilterOptions::ScFilterOptions() :
+ ConfigItem( OUString::createFromAscii( CFGPATH_FILTER ) ),
+ bWK3Flag( FALSE ),
+ fExcelColScale( 0 ),
+ fExcelRowScale( 0 )
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues = GetProperties(aNames);
+// EnableNotification(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCFILTOPT_COLSCALE:
+ pValues[nProp] >>= fExcelColScale;
+ break;
+ case SCFILTOPT_ROWSCALE:
+ pValues[nProp] >>= fExcelRowScale;
+ break;
+ case SCFILTOPT_WK3:
+ bWK3Flag = ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] );
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void ScFilterOptions::Commit()
+{
+ // options are never modified from office
+
+ DBG_ERROR("trying to commit changed ScFilterOptions?");
+}
+
+void ScFilterOptions::Notify( const Sequence<rtl::OUString>& /* aPropertyNames */ )
+{
+ DBG_ERROR("properties have been changed");
+}
+
+
diff --git a/sc/source/core/tool/formulaparserpool.cxx b/sc/source/core/tool/formulaparserpool.cxx
new file mode 100644
index 000000000000..75d1c874eba8
--- /dev/null
+++ b/sc/source/core/tool/formulaparserpool.cxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// 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/hints.cxx b/sc/source/core/tool/hints.cxx
new file mode 100644
index 000000000000..b2a8266705c7
--- /dev/null
+++ b/sc/source/core/tool/hints.cxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "hints.hxx"
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScPaintHint, SfxHint);
+TYPEINIT1(ScUpdateRefHint, SfxHint);
+TYPEINIT1(ScPointerChangedHint, SfxHint);
+TYPEINIT1(ScLinkRefreshedHint, SfxHint);
+TYPEINIT1(ScAutoStyleHint, SfxHint);
+TYPEINIT1(ScDBRangeRefreshedHint, SfxHint);
+TYPEINIT1(ScDataPilotModifiedHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScPaintHint - Angabe, was neu gezeichnet werden muss
+// -----------------------------------------------------------------------
+
+ScPaintHint::ScPaintHint( const ScRange& rRng, USHORT nPaint ) :
+ aRange( rRng ),
+ nParts( nPaint ),
+ bPrint( TRUE )
+{
+}
+
+ScPaintHint::~ScPaintHint()
+{
+}
+
+// -----------------------------------------------------------------------
+// ScUpdateRefHint - Referenz-Updaterei
+// -----------------------------------------------------------------------
+
+ScUpdateRefHint::ScUpdateRefHint( UpdateRefMode eMode, const ScRange& rR,
+ SCsCOL nX, SCsROW nY, SCsTAB nZ ) :
+ eUpdateRefMode( eMode ),
+ aRange( rR ),
+ nDx( nX ),
+ nDy( nY ),
+ nDz( nZ )
+{
+}
+
+ScUpdateRefHint::~ScUpdateRefHint()
+{
+}
+
+// -----------------------------------------------------------------------
+// ScPointerChangedHint - Pointer ist ungueltig geworden
+// -----------------------------------------------------------------------
+
+//UNUSED2008-05 ScPointerChangedHint::ScPointerChangedHint( USHORT nF ) :
+//UNUSED2008-05 nFlags( nF )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScPointerChangedHint::~ScPointerChangedHint()
+{
+}
+
+// -----------------------------------------------------------------------
+// ScLinkRefreshedHint - a link has been refreshed
+// -----------------------------------------------------------------------
+
+ScLinkRefreshedHint::ScLinkRefreshedHint() :
+ nLinkType( SC_LINKREFTYPE_NONE ),
+ nDdeMode( 0 )
+{
+}
+
+ScLinkRefreshedHint::~ScLinkRefreshedHint()
+{
+}
+
+void ScLinkRefreshedHint::SetSheetLink( const String& rSourceUrl )
+{
+ nLinkType = SC_LINKREFTYPE_SHEET;
+ aUrl = rSourceUrl;
+}
+
+void ScLinkRefreshedHint::SetDdeLink(
+ const String& rA, const String& rT, const String& rI, BYTE nM )
+{
+ nLinkType = SC_LINKREFTYPE_DDE;
+ aDdeAppl = rA;
+ aDdeTopic = rT;
+ aDdeItem = rI;
+ nDdeMode = nM;
+}
+
+void ScLinkRefreshedHint::SetAreaLink( const ScAddress& rPos )
+{
+ nLinkType = SC_LINKREFTYPE_AREA;
+ aDestPos = rPos;
+}
+
+// -----------------------------------------------------------------------
+// ScAutoStyleHint - STYLE() function has been called
+// -----------------------------------------------------------------------
+
+ScAutoStyleHint::ScAutoStyleHint( const ScRange& rR, const String& rSt1,
+ ULONG nT, const String& rSt2 ) :
+ aRange( rR ),
+ aStyle1( rSt1 ),
+ aStyle2( rSt2 ),
+ nTimeout( nT )
+{
+}
+
+ScAutoStyleHint::~ScAutoStyleHint()
+{
+}
+
+
+ScDBRangeRefreshedHint::ScDBRangeRefreshedHint( const ScImportParam& rP )
+ : aParam(rP)
+{
+}
+ScDBRangeRefreshedHint::~ScDBRangeRefreshedHint()
+{
+}
+
+
+ScDataPilotModifiedHint::ScDataPilotModifiedHint( const String& rName )
+ : maName(rName)
+{
+}
+ScDataPilotModifiedHint::~ScDataPilotModifiedHint()
+{
+}
+
+
diff --git a/sc/source/core/tool/inputopt.cxx b/sc/source/core/tool/inputopt.cxx
new file mode 100644
index 000000000000..ed5a74582348
--- /dev/null
+++ b/sc/source/core/tool/inputopt.cxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "cfgids.hxx"
+#include "inputopt.hxx"
+#include "rechead.hxx"
+#include "scresid.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "miscuno.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+//------------------------------------------------------------------
+
+// Version, ab der das Item kompatibel ist
+#define SC_VERSION ((USHORT)351)
+
+
+//========================================================================
+// ScInputOptions - Eingabe-Optionen
+//========================================================================
+
+ScInputOptions::ScInputOptions()
+{
+ SetDefaults();
+}
+
+//------------------------------------------------------------------------
+
+ScInputOptions::ScInputOptions( const ScInputOptions& rCpy )
+{
+ *this = rCpy;
+}
+
+//------------------------------------------------------------------------
+
+ScInputOptions::~ScInputOptions()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScInputOptions::SetDefaults()
+{
+ nMoveDir = DIR_BOTTOM;
+ bMoveSelection = TRUE;
+ bEnterEdit = FALSE;
+ bExtendFormat = FALSE;
+ bRangeFinder = TRUE;
+ bExpandRefs = FALSE;
+ bMarkHeader = TRUE;
+ bUseTabCol = FALSE;
+ bTextWysiwyg = FALSE;
+ bReplCellsWarn = TRUE;
+}
+
+//------------------------------------------------------------------------
+
+const ScInputOptions& ScInputOptions::operator=( const ScInputOptions& rCpy )
+{
+ nMoveDir = rCpy.nMoveDir;
+ bMoveSelection = rCpy.bMoveSelection;
+ bEnterEdit = rCpy.bEnterEdit;
+ bExtendFormat = rCpy.bExtendFormat;
+ bRangeFinder = rCpy.bRangeFinder;
+ bExpandRefs = rCpy.bExpandRefs;
+ bMarkHeader = rCpy.bMarkHeader;
+ bUseTabCol = rCpy.bUseTabCol;
+ bTextWysiwyg = rCpy.bTextWysiwyg;
+ bReplCellsWarn = rCpy.bReplCellsWarn;
+
+ return *this;
+}
+
+
+//==================================================================
+// Config Item containing input options
+//==================================================================
+
+#define CFGPATH_INPUT "Office.Calc/Input"
+
+#define SCINPUTOPT_MOVEDIR 0
+#define SCINPUTOPT_MOVESEL 1
+#define SCINPUTOPT_EDTEREDIT 2
+#define SCINPUTOPT_EXTENDFMT 3
+#define SCINPUTOPT_RANGEFIND 4
+#define SCINPUTOPT_EXPANDREFS 5
+#define SCINPUTOPT_MARKHEADER 6
+#define SCINPUTOPT_USETABCOL 7
+#define SCINPUTOPT_TEXTWYSIWYG 8
+#define SCINPUTOPT_REPLCELLSWARN 9
+#define SCINPUTOPT_COUNT 10
+
+Sequence<OUString> ScInputCfg::GetPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "MoveSelectionDirection", // SCINPUTOPT_MOVEDIR
+ "MoveSelection", // SCINPUTOPT_MOVESEL
+ "SwitchToEditMode", // SCINPUTOPT_EDTEREDIT
+ "ExpandFormatting", // SCINPUTOPT_EXTENDFMT
+ "ShowReference", // SCINPUTOPT_RANGEFIND
+ "ExpandReference", // SCINPUTOPT_EXPANDREFS
+ "HighlightSelection", // SCINPUTOPT_MARKHEADER
+ "UseTabCol", // SCINPUTOPT_USETABCOL
+ "UsePrinterMetrics", // SCINPUTOPT_TEXTWYSIWYG
+ "ReplaceCellsWarning" // SCINPUTOPT_REPLCELLSWARN
+ };
+ Sequence<OUString> aNames(SCINPUTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCINPUTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+ScInputCfg::ScInputCfg() :
+ ConfigItem( OUString::createFromAscii( CFGPATH_INPUT ) )
+{
+ sal_Int32 nIntVal = 0;
+
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues = GetProperties(aNames);
+ EnableNotification(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCINPUTOPT_MOVEDIR:
+ if ( pValues[nProp] >>= nIntVal )
+ SetMoveDir( (USHORT)nIntVal );
+ break;
+ case SCINPUTOPT_MOVESEL:
+ SetMoveSelection( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_EDTEREDIT:
+ SetEnterEdit( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_EXTENDFMT:
+ SetExtendFormat( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_RANGEFIND:
+ SetRangeFinder( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_EXPANDREFS:
+ SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_MARKHEADER:
+ SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_USETABCOL:
+ SetUseTabCol( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_TEXTWYSIWYG:
+ SetTextWysiwyg( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCINPUTOPT_REPLCELLSWARN:
+ SetReplaceCellsWarn( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void ScInputCfg::Commit()
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCINPUTOPT_MOVEDIR:
+ pValues[nProp] <<= (sal_Int32) GetMoveDir();
+ break;
+ case SCINPUTOPT_MOVESEL:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetMoveSelection() );
+ break;
+ case SCINPUTOPT_EDTEREDIT:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetEnterEdit() );
+ break;
+ case SCINPUTOPT_EXTENDFMT:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetExtendFormat() );
+ break;
+ case SCINPUTOPT_RANGEFIND:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetRangeFinder() );
+ break;
+ case SCINPUTOPT_EXPANDREFS:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetExpandRefs() );
+ break;
+ case SCINPUTOPT_MARKHEADER:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetMarkHeader() );
+ break;
+ case SCINPUTOPT_USETABCOL:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetUseTabCol() );
+ break;
+ case SCINPUTOPT_TEXTWYSIWYG:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetTextWysiwyg() );
+ break;
+ case SCINPUTOPT_REPLCELLSWARN:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetReplaceCellsWarn() );
+ break;
+ }
+ }
+ PutProperties(aNames, aValues);
+}
+
+void ScInputCfg::Notify( const Sequence<rtl::OUString>& /* aPropertyNames */ )
+{
+ DBG_ERROR("properties have been changed");
+}
+
+void ScInputCfg::SetOptions( const ScInputOptions& rNew )
+{
+ *(ScInputOptions*)this = rNew;
+ SetModified();
+}
+
+void ScInputCfg::OptionsChanged()
+{
+ SetModified();
+}
+
+
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
new file mode 100644
index 000000000000..1e4c02967152
--- /dev/null
+++ b/sc/source/core/tool/interpr1.cxx
@@ -0,0 +1,7460 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/langitem.hxx>
+#include <svx/algitem.hxx>
+#include <unotools/textsearch.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/charclass.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/logfile.hxx>
+
+#include "interpre.hxx"
+#include "patattr.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "scmatrix.hxx"
+#include "docoptio.hxx"
+#include "globstr.hrc"
+#include "attrib.hxx"
+#include "jumpmatrix.hxx"
+
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/processfactory.hxx>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <vector>
+#include <memory>
+#include "cellkeytranslator.hxx"
+#include "lookupcache.hxx"
+#include "rangenam.hxx"
+#include "compiler.hxx"
+#include "externalrefmgr.hxx"
+#include "doubleref.hxx"
+#include "queryparam.hxx"
+
+#define SC_DOUBLE_MAXVALUE 1.7e307
+
+IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 )
+IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 )
+
+ScTokenStack* ScInterpreter::pGlobalStack = NULL;
+BOOL ScInterpreter::bGlobalStackInUse = FALSE;
+
+using namespace formula;
+using ::std::auto_ptr;
+
+//-----------------------------------------------------------------------------
+// Funktionen
+//-----------------------------------------------------------------------------
+
+
+void ScInterpreter::ScIfJump()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIfJump" );
+ const short* pJump = pCur->GetJump();
+ short nJumpCount = pJump[ 0 ];
+ MatrixDoubleRefToMatrix();
+ switch ( GetStackType() )
+ {
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ FormulaTokenRef xNew;
+ ScTokenMatrixMap::const_iterator aMapIter;
+ // DoubleError handled by JumpMatrix
+ pMat->SetErrorInterpreter( NULL);
+ SCSIZE nCols, nRows;
+ pMat->GetDimensions( nCols, nRows );
+ if ( nCols == 0 || nRows == 0 )
+ PushIllegalArgument();
+ else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
+ pCur)) != pTokenMatrixMap->end()))
+ xNew = (*aMapIter).second;
+ else
+ {
+ ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
+ for ( SCSIZE nC=0; nC < nCols; ++nC )
+ {
+ for ( SCSIZE nR=0; nR < nRows; ++nR )
+ {
+ double fVal;
+ bool bTrue;
+ ScMatValType nType = 0;
+ const ScMatrixValue* pMatVal = pMat->Get( nC, nR,
+ nType);
+ bool bIsValue = ScMatrix::IsValueType( nType);
+ if ( bIsValue )
+ {
+ fVal = pMatVal->fVal;
+ bIsValue = ::rtl::math::isFinite( fVal );
+ bTrue = bIsValue && (fVal != 0.0);
+ if ( bTrue )
+ fVal = 1.0;
+ }
+ else
+ {
+ // Treat empty and empty path as 0, but string
+ // as error.
+ bIsValue = !ScMatrix::IsRealStringType( nType);
+ bTrue = false;
+ fVal = (bIsValue ? 0.0 : CreateDoubleError( errNoValue));
+ }
+ if ( bTrue )
+ { // TRUE
+ if( nJumpCount >= 2 )
+ { // THEN path
+ pJumpMat->SetJump( nC, nR, fVal,
+ pJump[ 1 ],
+ pJump[ nJumpCount ]);
+ }
+ else
+ { // no parameter given for THEN
+ pJumpMat->SetJump( nC, nR, fVal,
+ pJump[ nJumpCount ],
+ pJump[ nJumpCount ]);
+ }
+ }
+ else
+ { // FALSE
+ if( nJumpCount == 3 && bIsValue )
+ { // ELSE path
+ pJumpMat->SetJump( nC, nR, fVal,
+ pJump[ 2 ],
+ pJump[ nJumpCount ]);
+ }
+ else
+ { // no parameter given for ELSE,
+ // or DoubleError
+ pJumpMat->SetJump( nC, nR, fVal,
+ pJump[ nJumpCount ],
+ pJump[ nJumpCount ]);
+ }
+ }
+ }
+ }
+ xNew = new ScJumpMatrixToken( pJumpMat );
+ GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type(pCur, xNew));
+ }
+ PushTempToken( xNew);
+ // set endpoint of path for main code line
+ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
+ }
+ }
+ break;
+ default:
+ {
+ if ( GetBool() )
+ { // TRUE
+ if( nJumpCount >= 2 )
+ { // THEN path
+ aCode.Jump( pJump[ 1 ], pJump[ nJumpCount ] );
+ }
+ else
+ { // no parameter given for THEN
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ PushInt(1);
+ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
+ }
+ }
+ else
+ { // FALSE
+ if( nJumpCount == 3 )
+ { // ELSE path
+ aCode.Jump( pJump[ 2 ], pJump[ nJumpCount ] );
+ }
+ else
+ { // no parameter given for ELSE
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ PushInt(0);
+ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
+ }
+ }
+ }
+ }
+}
+
+
+void ScInterpreter::ScChoseJump()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChoseJump" );
+ // We have to set a jump, if there was none chosen because of an error set
+ // it to endpoint.
+ bool bHaveJump = false;
+ const short* pJump = pCur->GetJump();
+ short nJumpCount = pJump[ 0 ];
+ MatrixDoubleRefToMatrix();
+ switch ( GetStackType() )
+ {
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ FormulaTokenRef xNew;
+ ScTokenMatrixMap::const_iterator aMapIter;
+ // DoubleError handled by JumpMatrix
+ pMat->SetErrorInterpreter( NULL);
+ SCSIZE nCols, nRows;
+ pMat->GetDimensions( nCols, nRows );
+ if ( nCols == 0 || nRows == 0 )
+ PushIllegalParameter();
+ else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
+ pCur)) != pTokenMatrixMap->end()))
+ xNew = (*aMapIter).second;
+ else
+ {
+ ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
+ for ( SCSIZE nC=0; nC < nCols; ++nC )
+ {
+ for ( SCSIZE nR=0; nR < nRows; ++nR )
+ {
+ double fVal;
+ ScMatValType nType;
+ const ScMatrixValue* pMatVal = pMat->Get( nC, nR,
+ nType);
+ bool bIsValue = ScMatrix::IsValueType( nType);
+ if ( bIsValue )
+ {
+ fVal = pMatVal->fVal;
+ bIsValue = ::rtl::math::isFinite( fVal );
+ if ( bIsValue )
+ {
+ fVal = ::rtl::math::approxFloor( fVal);
+ if ( (fVal < 1) || (fVal >= nJumpCount))
+ {
+ bIsValue = FALSE;
+ fVal = CreateDoubleError(
+ errIllegalArgument);
+ }
+ }
+ }
+ else
+ {
+ fVal = CreateDoubleError( errNoValue);
+ }
+ if ( bIsValue )
+ {
+ pJumpMat->SetJump( nC, nR, fVal,
+ pJump[ (short)fVal ],
+ pJump[ nJumpCount ]);
+ }
+ else
+ {
+ pJumpMat->SetJump( nC, nR, fVal,
+ pJump[ nJumpCount ],
+ pJump[ nJumpCount ]);
+ }
+ }
+ }
+ xNew = new ScJumpMatrixToken( pJumpMat );
+ GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type(
+ pCur, xNew));
+ }
+ PushTempToken( xNew);
+ // set endpoint of path for main code line
+ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
+ bHaveJump = true;
+ }
+ }
+ break;
+ default:
+ {
+ double nJumpIndex = ::rtl::math::approxFloor( GetDouble() );
+ if (!nGlobalError && (nJumpIndex >= 1) && (nJumpIndex < nJumpCount))
+ {
+ aCode.Jump( pJump[ (short) nJumpIndex ], pJump[ nJumpCount ] );
+ bHaveJump = true;
+ }
+ else
+ PushIllegalArgument();
+ }
+ }
+ if (!bHaveJump)
+ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
+}
+
+void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SCSIZE nParmCols, SCSIZE nParmRows )
+{
+ SCSIZE nJumpCols, nJumpRows;
+ SCSIZE nResCols, nResRows;
+ SCSIZE nAdjustCols, nAdjustRows;
+ pJumpM->GetDimensions( nJumpCols, nJumpRows );
+ pJumpM->GetResMatDimensions( nResCols, nResRows );
+ if (( nJumpCols == 1 && nParmCols > nResCols ) ||
+ ( nJumpRows == 1 && nParmRows > nResRows ))
+ {
+ if ( nJumpCols == 1 && nJumpRows == 1 )
+ {
+ nAdjustCols = nParmCols > nResCols ? nParmCols : nResCols;
+ nAdjustRows = nParmRows > nResRows ? nParmRows : nResRows;
+ }
+ else if ( nJumpCols == 1 )
+ {
+ nAdjustCols = nParmCols;
+ nAdjustRows = nResRows;
+ }
+ else
+ {
+ nAdjustCols = nResCols;
+ nAdjustRows = nParmRows;
+ }
+ pJumpM->SetNewResMat( nAdjustCols, nAdjustRows );
+ pResMat = pJumpM->GetResultMatrix();
+ }
+}
+
+bool ScInterpreter::JumpMatrix( short nStackLevel )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::JumpMatrix" );
+ pJumpMatrix = static_cast<ScToken*>(pStack[sp-nStackLevel])->GetJumpMatrix();
+ ScMatrixRef pResMat = pJumpMatrix->GetResultMatrix();
+ SCSIZE nC, nR;
+ if ( nStackLevel == 2 )
+ {
+ if ( aCode.HasStacked() )
+ aCode.Pop(); // pop what Jump() pushed
+ else
+ {
+ DBG_ERRORFILE( "ScInterpreter::JumpMatrix: pop goes the weasel" );
+ }
+
+ if ( !pResMat )
+ {
+ Pop();
+ SetError( errUnknownStackVariable );
+ }
+ else
+ {
+ pJumpMatrix->GetPos( nC, nR );
+ switch ( GetStackType() )
+ {
+ case svDouble:
+ {
+ double fVal = GetDouble();
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError );
+ nGlobalError = 0;
+ }
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ break;
+ case svString:
+ {
+ const String& rStr = GetString();
+ if ( nGlobalError )
+ {
+ pResMat->PutDouble( CreateDoubleError( nGlobalError),
+ nC, nR);
+ nGlobalError = 0;
+ }
+ else
+ pResMat->PutString( rStr, nC, nR );
+ }
+ break;
+ case svSingleRef:
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if ( nGlobalError )
+ {
+ pResMat->PutDouble( CreateDoubleError( nGlobalError),
+ nC, nR);
+ nGlobalError = 0;
+ }
+ else
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData( pCell))
+ pResMat->PutEmpty( nC, nR );
+ else if (HasCellValueData( pCell))
+ {
+ double fVal = GetCellValue( aAdr, pCell);
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError(
+ nGlobalError);
+ nGlobalError = 0;
+ }
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else
+ {
+ String aStr;
+ GetCellString( aStr, pCell );
+ if ( nGlobalError )
+ {
+ pResMat->PutDouble( CreateDoubleError(
+ nGlobalError), nC, nR);
+ nGlobalError = 0;
+ }
+ else
+ pResMat->PutString( aStr, nC, nR);
+ }
+ }
+ }
+ break;
+ case svDoubleRef:
+ { // upper left plus offset within matrix
+ double fVal;
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError );
+ nGlobalError = 0;
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else
+ {
+ // Do not modify the original range because we use it
+ // to adjust the size of the result matrix if necessary.
+ ScAddress aAdr( aRange.aStart);
+ ULONG nCol = (ULONG)aAdr.Col() + nC;
+ ULONG nRow = (ULONG)aAdr.Row() + nR;
+ if ((nCol > static_cast<ULONG>(aRange.aEnd.Col()) &&
+ aRange.aEnd.Col() != aRange.aStart.Col())
+ || (nRow > static_cast<ULONG>(aRange.aEnd.Row()) &&
+ aRange.aEnd.Row() != aRange.aStart.Row()))
+ {
+ fVal = CreateDoubleError( NOTAVAILABLE );
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else
+ {
+ // Replicate column and/or row of a vector if it is
+ // one. Note that this could be a range reference
+ // that in fact consists of only one cell, e.g. A1:A1
+ if (aRange.aEnd.Col() == aRange.aStart.Col())
+ nCol = aRange.aStart.Col();
+ if (aRange.aEnd.Row() == aRange.aStart.Row())
+ nRow = aRange.aStart.Row();
+ aAdr.SetCol( static_cast<SCCOL>(nCol) );
+ aAdr.SetRow( static_cast<SCROW>(nRow) );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData( pCell))
+ pResMat->PutEmpty( nC, nR );
+ else if (HasCellValueData( pCell))
+ {
+ double fCellVal = GetCellValue( aAdr, pCell);
+ if ( nGlobalError )
+ {
+ fCellVal = CreateDoubleError(
+ nGlobalError);
+ nGlobalError = 0;
+ }
+ pResMat->PutDouble( fCellVal, nC, nR );
+ }
+ else
+ {
+ String aStr;
+ GetCellString( aStr, pCell );
+ if ( nGlobalError )
+ {
+ pResMat->PutDouble( CreateDoubleError(
+ nGlobalError), nC, nR);
+ nGlobalError = 0;
+ }
+ else
+ pResMat->PutString( aStr, nC, nR );
+ }
+ }
+ SCSIZE nParmCols = aRange.aEnd.Col() - aRange.aStart.Col() + 1;
+ SCSIZE nParmRows = aRange.aEnd.Row() - aRange.aStart.Row() + 1;
+ lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nParmCols, nParmRows );
+ }
+ }
+ break;
+ case svMatrix:
+ { // match matrix offsets
+ double fVal;
+ ScMatrixRef pMat = PopMatrix();
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError );
+ nGlobalError = 0;
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else if ( !pMat )
+ {
+ fVal = CreateDoubleError( errUnknownVariable );
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else
+ {
+ SCSIZE nCols, nRows;
+ pMat->GetDimensions( nCols, nRows );
+ if ((nCols <= nC && nCols != 1) ||
+ (nRows <= nR && nRows != 1))
+ {
+ fVal = CreateDoubleError( NOTAVAILABLE );
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else
+ {
+ if ( pMat->IsValue( nC, nR ) )
+ {
+ fVal = pMat->GetDouble( nC, nR );
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ else if ( pMat->IsEmpty( nC, nR ) )
+ pResMat->PutEmpty( nC, nR );
+ else
+ {
+ const String& rStr = pMat->GetString( nC, nR );
+ pResMat->PutString( rStr, nC, nR );
+ }
+ }
+ lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nCols, nRows );
+ }
+ }
+ break;
+ case svError:
+ {
+ PopError();
+ double fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ break;
+ default:
+ {
+ Pop();
+ double fVal = CreateDoubleError( errIllegalArgument);
+ pResMat->PutDouble( fVal, nC, nR );
+ }
+ }
+ }
+ }
+ bool bCont = pJumpMatrix->Next( nC, nR );
+ if ( bCont )
+ {
+ double fBool;
+ short nStart, nNext, nStop;
+ pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
+ while ( bCont && nStart == nNext )
+ { // push all results that have no jump path
+ if ( pResMat )
+ {
+ // a FALSE without path results in an empty path value
+ if ( fBool == 0.0 )
+ pResMat->PutEmptyPath( nC, nR );
+ else
+ pResMat->PutDouble( fBool, nC, nR );
+ }
+ bCont = pJumpMatrix->Next( nC, nR );
+ if ( bCont )
+ pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
+ }
+ if ( bCont && nStart != nNext )
+ {
+ const ScTokenVec* pParams = pJumpMatrix->GetJumpParameters();
+ if ( pParams )
+ {
+ for ( ScTokenVec::const_iterator i = pParams->begin();
+ i != pParams->end(); ++i )
+ {
+ // This is not the current state of the interpreter, so
+ // push without error, and elements' errors are coded into
+ // double.
+ PushWithoutError( *(*i));
+ }
+ }
+ aCode.Jump( nStart, nNext, nStop );
+ }
+ }
+ if ( !bCont )
+ { // we're done with it, throw away jump matrix, keep result
+ pJumpMatrix = NULL;
+ Pop();
+ PushMatrix( pResMat );
+ // Remove jump matrix from map and remember result matrix in case it
+ // could be reused in another path of the same condition.
+ if (pTokenMatrixMap)
+ {
+ pTokenMatrixMap->erase( pCur);
+ pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pCur,
+ pStack[sp-1]));
+ }
+ return true;
+ }
+ return false;
+}
+
+
+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", "er", "ScInterpreter::CompareFunc" );
+ // Keep DoubleError if encountered
+ // #i40539# if bEmpty is set, bVal/nVal are uninitialized
+ if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
+ return rComp.nVal[0];
+ if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
+ return rComp.nVal[1];
+
+ double fRes = 0;
+ if ( rComp.bEmpty[ 0 ] )
+ {
+ if ( rComp.bEmpty[ 1 ] )
+ ; // empty cell == empty cell, fRes 0
+ else if( rComp.bVal[ 1 ] )
+ {
+ if ( !::rtl::math::approxEqual( rComp.nVal[ 1 ], 0.0 ) )
+ {
+ if ( rComp.nVal[ 1 ] < 0.0 )
+ fRes = 1; // empty cell > -x
+ else
+ fRes = -1; // empty cell < x
+ }
+ // else: empty cell == 0.0
+ }
+ else
+ {
+ if ( rComp.pVal[ 1 ]->Len() )
+ fRes = -1; // empty cell < "..."
+ // else: empty cell == ""
+ }
+ }
+ else if ( rComp.bEmpty[ 1 ] )
+ {
+ if( rComp.bVal[ 0 ] )
+ {
+ if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], 0.0 ) )
+ {
+ if ( rComp.nVal[ 0 ] < 0.0 )
+ fRes = -1; // -x < empty cell
+ else
+ fRes = 1; // x > empty cell
+ }
+ // else: empty cell == 0.0
+ }
+ else
+ {
+ if ( rComp.pVal[ 0 ]->Len() )
+ fRes = 1; // "..." > empty cell
+ // else: "" == empty cell
+ }
+ }
+ else if( rComp.bVal[ 0 ] )
+ {
+ if( rComp.bVal[ 1 ] )
+ {
+ if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) )
+ {
+ if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 )
+ fRes = -1;
+ else
+ fRes = 1;
+ }
+ }
+ else
+ fRes = -1; // number is less than string
+ }
+ else if( rComp.bVal[ 1 ] )
+ fRes = 1; // number is less than string
+ else
+ {
+ // 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::GetpTransliteration() :
+ ScGlobal::GetCaseTransliteration());
+ 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::GetCollator()->compareString(
+ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+ else
+ fRes = (double) ScGlobal::GetCaseCollator()->compareString(
+ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+ }
+ else if (pDok->GetDocOptions().IsIgnoreCase())
+ fRes = (double) ScGlobal::GetCollator()->compareString(
+ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+ else
+ fRes = (double) ScGlobal::GetCaseCollator()->compareString(
+ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+ }
+ return fRes;
+}
+
+
+double ScInterpreter::Compare()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Compare" );
+ String aVal1, aVal2;
+ ScCompare aComp( &aVal1, &aVal2 );
+ for( short i = 1; i >= 0; i-- )
+ {
+ switch ( GetRawStackType() )
+ {
+ case svEmptyCell:
+ Pop();
+ aComp.bEmpty[ i ] = TRUE;
+ break;
+ case svMissing:
+ case svDouble:
+ aComp.nVal[ i ] = GetDouble();
+ aComp.bVal[ i ] = TRUE;
+ break;
+ case svString:
+ *aComp.pVal[ i ] = GetString();
+ aComp.bVal[ i ] = FALSE;
+ break;
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData( pCell))
+ aComp.bEmpty[ i ] = TRUE;
+ else if (HasCellStringData( pCell))
+ {
+ GetCellString( *aComp.pVal[ i ], pCell);
+ aComp.bVal[ i ] = FALSE;
+ }
+ else
+ {
+ aComp.nVal[ i ] = GetCellValue( aAdr, pCell );
+ aComp.bVal[ i ] = TRUE;
+ }
+ }
+ break;
+ default:
+ SetError( errIllegalParameter);
+ break;
+ }
+ }
+ if( nGlobalError )
+ return 0;
+ nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ return CompareFunc( aComp );
+}
+
+
+ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CompareMat" );
+ String aVal1, aVal2;
+ ScCompare aComp( &aVal1, &aVal2 );
+ ScMatrixRef pMat[2];
+ ScAddress aAdr;
+ for( short i = 1; i >= 0; i-- )
+ {
+ switch (GetRawStackType())
+ {
+ case svEmptyCell:
+ Pop();
+ aComp.bEmpty[ i ] = TRUE;
+ break;
+ case svMissing:
+ case svDouble:
+ aComp.nVal[ i ] = GetDouble();
+ aComp.bVal[ i ] = TRUE;
+ break;
+ case svString:
+ *aComp.pVal[ i ] = GetString();
+ aComp.bVal[ i ] = FALSE;
+ break;
+ case svSingleRef:
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData( pCell))
+ aComp.bEmpty[ i ] = TRUE;
+ else if (HasCellStringData( pCell))
+ {
+ GetCellString( *aComp.pVal[ i ], pCell);
+ aComp.bVal[ i ] = FALSE;
+ }
+ else
+ {
+ aComp.nVal[ i ] = GetCellValue( aAdr, pCell );
+ aComp.bVal[ i ] = TRUE;
+ }
+ }
+ break;
+ case svDoubleRef:
+ case svMatrix:
+ pMat[ i ] = GetMatrix();
+ if ( !pMat[ i ] )
+ SetError( errIllegalParameter);
+ else
+ pMat[i]->SetErrorInterpreter( NULL);
+ // errors are transported as DoubleError inside matrix
+ break;
+ default:
+ SetError( errIllegalParameter);
+ break;
+ }
+ }
+ ScMatrixRef pResMat = NULL;
+ if( !nGlobalError )
+ {
+ if ( pMat[0] && pMat[1] )
+ {
+ SCSIZE nC0, nC1;
+ SCSIZE nR0, nR1;
+ pMat[0]->GetDimensions( nC0, nR0 );
+ pMat[1]->GetDimensions( nC1, nR1 );
+ SCSIZE nC = Max( nC0, nC1 );
+ SCSIZE nR = Max( nR0, nR1 );
+ pResMat = GetNewMat( nC, nR);
+ if ( !pResMat )
+ return NULL;
+ for ( SCSIZE j=0; j<nC; j++ )
+ {
+ for ( SCSIZE k=0; k<nR; k++ )
+ {
+ SCSIZE nCol = j, nRow = k;
+ if ( pMat[0]->ValidColRowOrReplicated( nCol, nRow ) &&
+ pMat[1]->ValidColRowOrReplicated( nCol, nRow ))
+ {
+ for ( short i=1; i>=0; i-- )
+ {
+ if ( pMat[i]->IsString(j,k) )
+ {
+ aComp.bVal[i] = FALSE;
+ *aComp.pVal[i] = pMat[i]->GetString(j,k);
+ aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k);
+ }
+ else
+ {
+ aComp.bVal[i] = TRUE;
+ aComp.nVal[i] = pMat[i]->GetDouble(j,k);
+ aComp.bEmpty[i] = FALSE;
+ }
+ }
+ pResMat->PutDouble( CompareFunc( aComp, pOptions ), j,k );
+ }
+ else
+ pResMat->PutString( ScGlobal::GetRscString(STR_NO_VALUE), j,k );
+ }
+ }
+ }
+ else if ( pMat[0] || pMat[1] )
+ {
+ short i = ( pMat[0] ? 0 : 1);
+ SCSIZE nC, nR;
+ pMat[i]->GetDimensions( nC, nR );
+ pResMat = GetNewMat( nC, nR);
+ if ( !pResMat )
+ return NULL;
+ SCSIZE n = nC * nR;
+ for ( SCSIZE j=0; j<n; j++ )
+ {
+ if ( pMat[i]->IsValue(j) )
+ {
+ aComp.bVal[i] = TRUE;
+ aComp.nVal[i] = pMat[i]->GetDouble(j);
+ aComp.bEmpty[i] = FALSE;
+ }
+ else
+ {
+ aComp.bVal[i] = FALSE;
+ *aComp.pVal[i] = pMat[i]->GetString(j);
+ aComp.bEmpty[i] = pMat[i]->IsEmpty(j);
+ }
+ pResMat->PutDouble( CompareFunc( aComp, pOptions ), j );
+ }
+ }
+ }
+ nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ return pResMat;
+}
+
+
+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", "er", "ScInterpreter::ScEqual" );
+ if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
+ {
+ ScMatrixRef pMat = CompareMat();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ pMat->CompareEqual();
+ PushMatrix( pMat );
+ }
+ }
+ else
+ PushInt( Compare() == 0 );
+}
+
+
+void ScInterpreter::ScNotEqual()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNotEqual" );
+ if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
+ {
+ ScMatrixRef pMat = CompareMat();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ pMat->CompareNotEqual();
+ PushMatrix( pMat );
+ }
+ }
+ else
+ PushInt( Compare() != 0 );
+}
+
+
+void ScInterpreter::ScLess()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLess" );
+ if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
+ {
+ ScMatrixRef pMat = CompareMat();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ pMat->CompareLess();
+ PushMatrix( pMat );
+ }
+ }
+ else
+ PushInt( Compare() < 0 );
+}
+
+
+void ScInterpreter::ScGreater()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGreater" );
+ if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
+ {
+ ScMatrixRef pMat = CompareMat();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ pMat->CompareGreater();
+ PushMatrix( pMat );
+ }
+ }
+ else
+ PushInt( Compare() > 0 );
+}
+
+
+void ScInterpreter::ScLessEqual()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLessEqual" );
+ if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
+ {
+ ScMatrixRef pMat = CompareMat();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ pMat->CompareLessEqual();
+ PushMatrix( pMat );
+ }
+ }
+ else
+ PushInt( Compare() <= 0 );
+}
+
+
+void ScInterpreter::ScGreaterEqual()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGreaterEqual" );
+ if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
+ {
+ ScMatrixRef pMat = CompareMat();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ pMat->CompareGreaterEqual();
+ PushMatrix( pMat );
+ }
+ }
+ else
+ PushInt( Compare() >= 0 );
+}
+
+
+void ScInterpreter::ScAnd()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAnd" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nParamCount = GetByte();
+ if ( MustHaveParamCountMin( nParamCount, 1 ) )
+ {
+ BOOL bHaveValue = FALSE;
+ short nRes = TRUE;
+ size_t nRefInList = 0;
+ while( nParamCount-- > 0)
+ {
+ if ( !nGlobalError )
+ {
+ switch ( GetStackType() )
+ {
+ case svDouble :
+ bHaveValue = TRUE;
+ nRes &= ( PopDouble() != 0.0 );
+ break;
+ case svString :
+ Pop();
+ SetError( errNoValue );
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if ( !nGlobalError )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( HasCellValueData( pCell ) )
+ {
+ bHaveValue = TRUE;
+ nRes &= ( GetCellValue( aAdr, pCell ) != 0.0 );
+ }
+ // else: Xcl setzt hier keinen Fehler
+ }
+ }
+ break;
+ case svDoubleRef:
+ case svRefList:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ if ( !nGlobalError )
+ {
+ double fVal;
+ USHORT nErr = 0;
+ ScValueIterator aValIter( pDok, aRange );
+ if ( aValIter.GetFirst( fVal, nErr ) )
+ {
+ bHaveValue = TRUE;
+ do
+ {
+ nRes &= ( fVal != 0.0 );
+ } while ( (nErr == 0) &&
+ aValIter.GetNext( fVal, nErr ) );
+ }
+ SetError( nErr );
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if ( pMat )
+ {
+ bHaveValue = TRUE;
+ double fVal = pMat->And();
+ USHORT nErr = GetDoubleErrorValue( fVal );
+ if ( nErr )
+ {
+ SetError( nErr );
+ nRes = FALSE;
+ }
+ else
+ nRes &= (fVal != 0.0);
+ }
+ // else: GetMatrix did set errIllegalParameter
+ }
+ break;
+ default:
+ Pop();
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ Pop();
+ }
+ if ( bHaveValue )
+ PushInt( nRes );
+ else
+ PushNoValue();
+ }
+}
+
+
+void ScInterpreter::ScOr()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOr" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nParamCount = GetByte();
+ if ( MustHaveParamCountMin( nParamCount, 1 ) )
+ {
+ BOOL bHaveValue = FALSE;
+ short nRes = FALSE;
+ size_t nRefInList = 0;
+ while( nParamCount-- > 0)
+ {
+ if ( !nGlobalError )
+ {
+ switch ( GetStackType() )
+ {
+ case svDouble :
+ bHaveValue = TRUE;
+ nRes |= ( PopDouble() != 0.0 );
+ break;
+ case svString :
+ Pop();
+ SetError( errNoValue );
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if ( !nGlobalError )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( HasCellValueData( pCell ) )
+ {
+ bHaveValue = TRUE;
+ nRes |= ( GetCellValue( aAdr, pCell ) != 0.0 );
+ }
+ // else: Xcl setzt hier keinen Fehler
+ }
+ }
+ break;
+ case svDoubleRef:
+ case svRefList:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ if ( !nGlobalError )
+ {
+ double fVal;
+ USHORT nErr = 0;
+ ScValueIterator aValIter( pDok, aRange );
+ if ( aValIter.GetFirst( fVal, nErr ) )
+ {
+ bHaveValue = TRUE;
+ do
+ {
+ nRes |= ( fVal != 0.0 );
+ } while ( (nErr == 0) &&
+ aValIter.GetNext( fVal, nErr ) );
+ }
+ SetError( nErr );
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ bHaveValue = TRUE;
+ ScMatrixRef pMat = GetMatrix();
+ if ( pMat )
+ {
+ bHaveValue = TRUE;
+ double fVal = pMat->Or();
+ USHORT nErr = GetDoubleErrorValue( fVal );
+ if ( nErr )
+ {
+ SetError( nErr );
+ nRes = FALSE;
+ }
+ else
+ nRes |= (fVal != 0.0);
+ }
+ // else: GetMatrix did set errIllegalParameter
+ }
+ break;
+ default:
+ Pop();
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ Pop();
+ }
+ if ( bHaveValue )
+ PushInt( nRes );
+ else
+ PushNoValue();
+ }
+}
+
+
+void ScInterpreter::ScNeg()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNeg" );
+ // Simple negation doesn't change current format type to number, keep
+ // current type.
+ nFuncFmtType = nCurFmtType;
+ switch ( GetStackType() )
+ {
+ case svMatrix :
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions( nC, nR );
+ ScMatrixRef pResMat = GetNewMat( nC, nR);
+ if ( !pResMat )
+ PushIllegalArgument();
+ else
+ {
+ SCSIZE nCount = nC * nR;
+ for ( SCSIZE j=0; j<nCount; ++j )
+ {
+ if ( pMat->IsValueOrEmpty(j) )
+ pResMat->PutDouble( -pMat->GetDouble(j), j );
+ else
+ pResMat->PutString(
+ ScGlobal::GetRscString( STR_NO_VALUE ), j );
+ }
+ PushMatrix( pResMat );
+ }
+ }
+ }
+ break;
+ default:
+ PushDouble( -GetDouble() );
+ }
+}
+
+
+void ScInterpreter::ScPercentSign()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentSign" );
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ const FormulaToken* pSaveCur = pCur;
+ BYTE nSavePar = cPar;
+ PushInt( 100 );
+ cPar = 2;
+ FormulaByteToken aDivOp( ocDiv, cPar );
+ pCur = &aDivOp;
+ ScDiv();
+ pCur = pSaveCur;
+ cPar = nSavePar;
+}
+
+
+void ScInterpreter::ScNot()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNot" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ switch ( GetStackType() )
+ {
+ case svMatrix :
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if ( !pMat )
+ PushIllegalParameter();
+ else
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions( nC, nR );
+ ScMatrixRef pResMat = GetNewMat( nC, nR);
+ if ( !pResMat )
+ PushIllegalArgument();
+ else
+ {
+ SCSIZE nCount = nC * nR;
+ for ( SCSIZE j=0; j<nCount; ++j )
+ {
+ if ( pMat->IsValueOrEmpty(j) )
+ pResMat->PutDouble( (pMat->GetDouble(j) == 0.0), j );
+ else
+ pResMat->PutString(
+ ScGlobal::GetRscString( STR_NO_VALUE ), j );
+ }
+ PushMatrix( pResMat );
+ }
+ }
+ }
+ break;
+ default:
+ PushInt( GetDouble() == 0.0 );
+ }
+}
+
+
+void ScInterpreter::ScPi()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" );
+ PushDouble(F_PI);
+}
+
+
+void ScInterpreter::ScRandom()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRandom" );
+ PushDouble((double)rand() / ((double)RAND_MAX+1.0));
+}
+
+
+void ScInterpreter::ScTrue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrue" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ PushInt(1);
+}
+
+
+void ScInterpreter::ScFalse()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFalse" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ PushInt(0);
+}
+
+
+void ScInterpreter::ScDeg()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDeg" );
+ PushDouble((GetDouble() / F_PI) * 180.0);
+}
+
+
+void ScInterpreter::ScRad()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRad" );
+ PushDouble(GetDouble() * (F_PI / 180));
+}
+
+
+void ScInterpreter::ScSin()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSin" );
+ PushDouble(::rtl::math::sin(GetDouble()));
+}
+
+
+void ScInterpreter::ScCos()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCos" );
+ PushDouble(::rtl::math::cos(GetDouble()));
+}
+
+
+void ScInterpreter::ScTan()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTan" );
+ PushDouble(::rtl::math::tan(GetDouble()));
+}
+
+
+void ScInterpreter::ScCot()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCot" );
+ PushDouble(1.0 / ::rtl::math::tan(GetDouble()));
+}
+
+
+void ScInterpreter::ScArcSin()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSin" );
+ PushDouble(asin(GetDouble()));
+}
+
+
+void ScInterpreter::ScArcCos()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCos" );
+ PushDouble(acos(GetDouble()));
+}
+
+
+void ScInterpreter::ScArcTan()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTan" );
+ PushDouble(atan(GetDouble()));
+}
+
+
+void ScInterpreter::ScArcCot()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCot" );
+ PushDouble((F_PI2) - atan(GetDouble()));
+}
+
+
+void ScInterpreter::ScSinHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSinHyp" );
+ PushDouble(sinh(GetDouble()));
+}
+
+
+void ScInterpreter::ScCosHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCosHyp" );
+ PushDouble(cosh(GetDouble()));
+}
+
+
+void ScInterpreter::ScTanHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTanHyp" );
+ PushDouble(tanh(GetDouble()));
+}
+
+
+void ScInterpreter::ScCotHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCotHyp" );
+ PushDouble(1.0 / tanh(GetDouble()));
+}
+
+
+void ScInterpreter::ScArcSinHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSinHyp" );
+ PushDouble( ::rtl::math::asinh( GetDouble()));
+}
+
+void ScInterpreter::ScArcCosHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCosHyp" );
+ double fVal = GetDouble();
+ if (fVal < 1.0)
+ PushIllegalArgument();
+ else
+ PushDouble( ::rtl::math::acosh( fVal));
+}
+
+void ScInterpreter::ScArcTanHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTanHyp" );
+ double fVal = GetDouble();
+ if (fabs(fVal) >= 1.0)
+ PushIllegalArgument();
+ else
+ PushDouble( ::rtl::math::atanh( fVal));
+}
+
+
+void ScInterpreter::ScArcCotHyp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCotHyp" );
+ double nVal = GetDouble();
+ if (fabs(nVal) <= 1.0)
+ PushIllegalArgument();
+ else
+ PushDouble(0.5 * log((nVal + 1.0) / (nVal - 1.0)));
+}
+
+
+void ScInterpreter::ScExp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExp" );
+ PushDouble(exp(GetDouble()));
+}
+
+
+void ScInterpreter::ScSqrt()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSqrt" );
+ double fVal = GetDouble();
+ if (fVal >= 0.0)
+ PushDouble(sqrt(fVal));
+ else
+ PushIllegalArgument();
+}
+
+
+void ScInterpreter::ScIsEmpty()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsEmpty" );
+ short nRes = 0;
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ switch ( GetRawStackType() )
+ {
+ case svEmptyCell:
+ {
+ FormulaTokenRef p = PopToken();
+ if (!static_cast<const ScEmptyCellToken*>(p.get())->IsInherited())
+ nRes = 1;
+ }
+ break;
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ // NOTE: this could test also on inherited emptiness, but then the
+ // cell tested wouldn't be empty. Must correspond with
+ // ScCountEmptyCells().
+ // if (HasCellEmptyData( GetCell( aAdr)))
+ CellType eCellType = GetCellType( GetCell( aAdr ) );
+ if((eCellType == CELLTYPE_NONE) || (eCellType == CELLTYPE_NOTE))
+ nRes = 1;
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ ; // nothing
+ else if ( !pJumpMatrix )
+ nRes = pMat->IsEmpty( 0 );
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ nRes = pMat->IsEmpty( nC, nR);
+ // else: FALSE, not empty (which is what Xcl does)
+ }
+ }
+ break;
+ default:
+ Pop();
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+short ScInterpreter::IsString()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsString" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetRawStackType() )
+ {
+ case svString:
+ Pop();
+ nRes = 1;
+ break;
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (GetCellErrCode( pCell ) == 0)
+ {
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ nRes = 1;
+ break;
+ case CELLTYPE_FORMULA :
+ nRes = !((ScFormulaCell*)pCell)->IsValue() &&
+ !((ScFormulaCell*)pCell)->IsEmpty();
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ ; // nothing
+ else if ( !pJumpMatrix )
+ nRes = pMat->IsString(0) && !pMat->IsEmpty(0);
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ nRes = pMat->IsString( nC, nR) && !pMat->IsEmpty( nC, nR);
+ }
+ }
+ break;
+ default:
+ Pop();
+ }
+ nGlobalError = 0;
+ return nRes;
+}
+
+
+void ScInterpreter::ScIsString()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsString" );
+ PushInt( IsString() );
+}
+
+
+void ScInterpreter::ScIsNonString()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsNonString" );
+ PushInt( !IsString() );
+}
+
+
+void ScInterpreter::ScIsLogical()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsLogical" );
+ short nRes = 0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (GetCellErrCode( pCell ) == 0)
+ {
+ if (HasCellValueData(pCell))
+ {
+ ULONG nFormat = GetCellNumberFormat( aAdr, pCell );
+ nRes = ( pFormatter->GetType(nFormat)
+ == NUMBERFORMAT_LOGICAL);
+ }
+ }
+ }
+ break;
+ case svMatrix:
+ // TODO: we don't have type information for arrays except
+ // numerical/string.
+ // Fall thru
+ default:
+ PopError();
+ if ( !nGlobalError )
+ nRes = ( nCurFmtType == NUMBERFORMAT_LOGICAL );
+ }
+ nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+void ScInterpreter::ScType()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScType" );
+ short nType = 0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (GetCellErrCode( pCell ) == 0)
+ {
+ switch ( GetCellType( pCell ) )
+ {
+ // NOTE: this is Xcl nonsense!
+ case CELLTYPE_NOTE :
+ nType = 1; // empty cell is value (0)
+ break;
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ nType = 2;
+ break;
+ case CELLTYPE_VALUE :
+ {
+ ULONG nFormat = GetCellNumberFormat( aAdr, pCell );
+ if (pFormatter->GetType(nFormat)
+ == NUMBERFORMAT_LOGICAL)
+ nType = 4;
+ else
+ nType = 1;
+ }
+ break;
+ case CELLTYPE_FORMULA :
+ nType = 8;
+ break;
+ default:
+ PushIllegalArgument();
+ }
+ }
+ else
+ nType = 16;
+ }
+ break;
+ case svString:
+ PopError();
+ if ( nGlobalError )
+ {
+ nType = 16;
+ nGlobalError = 0;
+ }
+ else
+ nType = 2;
+ break;
+ case svMatrix:
+ PopMatrix();
+ if ( nGlobalError )
+ {
+ nType = 16;
+ nGlobalError = 0;
+ }
+ else
+ nType = 64;
+ // we could return the type of one element if in JumpMatrix or
+ // ForceArray mode, but Xcl doesn't ...
+ break;
+ default:
+ PopError();
+ if ( nGlobalError )
+ {
+ nType = 16;
+ nGlobalError = 0;
+ }
+ else
+ nType = 1;
+ }
+ PushInt( nType );
+}
+
+
+inline BOOL lcl_FormatHasNegColor( const SvNumberformat* pFormat )
+{
+ return pFormat && pFormat->GetColor( 1 );
+}
+
+
+inline BOOL lcl_FormatHasOpenPar( const SvNumberformat* pFormat )
+{
+ return pFormat && (pFormat->GetFormatstring().Search( '(' ) != STRING_NOTFOUND);
+}
+
+
+void ScInterpreter::ScCell()
+{ // ATTRIBUTE ; [REF]
+ BYTE nParamCount = GetByte();
+ if( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ ScAddress aCellPos( aPos );
+ BOOL bError = FALSE;
+ if( nParamCount == 2 )
+ bError = !PopDoubleRefOrSingleRef( aCellPos );
+ String aInfoType( GetString() );
+ if( bError || nGlobalError )
+ PushIllegalParameter();
+ else
+ {
+ String aFuncResult;
+ ScBaseCell* pCell = GetCell( aCellPos );
+
+ ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell);
+
+// *** ADDRESS INFO ***
+ if( aInfoType.EqualsAscii( "COL" ) )
+ { // column number (1-based)
+ PushInt( aCellPos.Col() + 1 );
+ }
+ else if( aInfoType.EqualsAscii( "ROW" ) )
+ { // row number (1-based)
+ PushInt( aCellPos.Row() + 1 );
+ }
+ else if( aInfoType.EqualsAscii( "SHEET" ) )
+ { // table number (1-based)
+ PushInt( aCellPos.Tab() + 1 );
+ }
+ else if( aInfoType.EqualsAscii( "ADDRESS" ) )
+ { // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW
+ USHORT nFlags = (aCellPos.Tab() == aPos.Tab()) ? (SCA_ABS) : (SCA_ABS_3D);
+ aCellPos.Format( aFuncResult, nFlags, pDok, pDok->GetAddressConvention() );
+ PushString( aFuncResult );
+ }
+ else if( aInfoType.EqualsAscii( "FILENAME" ) )
+ { // file name and table name: 'FILENAME'#$TABLE
+ SCTAB nTab = aCellPos.Tab();
+ if( nTab < pDok->GetTableCount() )
+ {
+ if( pDok->GetLinkMode( nTab ) == SC_LINK_VALUE )
+ pDok->GetName( nTab, aFuncResult );
+ else
+ {
+ SfxObjectShell* pShell = pDok->GetDocumentShell();
+ if( pShell && pShell->GetMedium() )
+ {
+ aFuncResult = (sal_Unicode) '\'';
+ const INetURLObject& rURLObj = pShell->GetMedium()->GetURLObject();
+ aFuncResult += String( rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) );
+ aFuncResult.AppendAscii( "'#$" );
+ String aTabName;
+ pDok->GetName( nTab, aTabName );
+ aFuncResult += aTabName;
+ }
+ }
+ }
+ PushString( aFuncResult );
+ }
+ else if( aInfoType.EqualsAscii( "COORD" ) )
+ { // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW
+ // Yes, passing tab as col is intentional!
+ ScAddress( static_cast<SCCOL>(aCellPos.Tab()), 0, 0 ).Format(
+ aFuncResult, (SCA_COL_ABSOLUTE|SCA_VALID_COL), NULL, pDok->GetAddressConvention() );
+ aFuncResult += ':';
+ String aCellStr;
+ aCellPos.Format( aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL|SCA_ROW_ABSOLUTE|SCA_VALID_ROW),
+ NULL, pDok->GetAddressConvention() );
+ aFuncResult += aCellStr;
+ PushString( aFuncResult );
+ }
+
+// *** CELL PROPERTIES ***
+ else if( aInfoType.EqualsAscii( "CONTENTS" ) )
+ { // contents of the cell, no formatting
+ if( pCell && pCell->HasStringData() )
+ {
+ GetCellString( aFuncResult, pCell );
+ PushString( aFuncResult );
+ }
+ else
+ PushDouble( GetCellValue( aCellPos, pCell ) );
+ }
+ else if( aInfoType.EqualsAscii( "TYPE" ) )
+ { // b = blank; l = string (label); v = otherwise (value)
+ if( HasCellStringData( pCell ) )
+ aFuncResult = 'l';
+ else
+ aFuncResult = HasCellValueData( pCell ) ? 'v' : 'b';
+ PushString( aFuncResult );
+ }
+ else if( aInfoType.EqualsAscii( "WIDTH" ) )
+ { // column width (rounded off as count of zero characters in standard font and size)
+ Printer* pPrinter = pDok->GetPrinter();
+ MapMode aOldMode( pPrinter->GetMapMode() );
+ Font aOldFont( pPrinter->GetFont() );
+ Font aDefFont;
+
+ pPrinter->SetMapMode( MAP_TWIP );
+ // font color doesn't matter here
+ pDok->GetDefPattern()->GetFont( aDefFont, SC_AUTOCOL_BLACK, pPrinter );
+ pPrinter->SetFont( aDefFont );
+ long nZeroWidth = pPrinter->GetTextWidth( String( '0' ) );
+ pPrinter->SetFont( aOldFont );
+ pPrinter->SetMapMode( aOldMode );
+ int nZeroCount = (int)(pDok->GetColWidth( aCellPos.Col(), aCellPos.Tab() ) / nZeroWidth);
+ PushInt( nZeroCount );
+ }
+ else if( aInfoType.EqualsAscii( "PREFIX" ) )
+ { // ' = left; " = right; ^ = centered
+ if( HasCellStringData( pCell ) )
+ {
+ const SvxHorJustifyItem* pJustAttr = (const SvxHorJustifyItem*)
+ pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY );
+ switch( pJustAttr->GetValue() )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_BLOCK: aFuncResult = '\''; break;
+ case SVX_HOR_JUSTIFY_CENTER: aFuncResult = '^'; break;
+ case SVX_HOR_JUSTIFY_RIGHT: aFuncResult = '"'; break;
+ case SVX_HOR_JUSTIFY_REPEAT: aFuncResult = '\\'; break;
+ }
+ }
+ PushString( aFuncResult );
+ }
+ else if( aInfoType.EqualsAscii( "PROTECT" ) )
+ { // 1 = cell locked
+ const ScProtectionAttr* pProtAttr = (const ScProtectionAttr*)
+ pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION );
+ PushInt( pProtAttr->GetProtection() ? 1 : 0 );
+ }
+
+// *** FORMATTING ***
+ else if( aInfoType.EqualsAscii( "FORMAT" ) )
+ { // specific format code for standard formats
+ ULONG nFormat = pDok->GetNumberFormat( aCellPos );
+ BOOL bAppendPrec = TRUE;
+ USHORT nPrec, nLeading;
+ BOOL bThousand, bIsRed;
+ pFormatter->GetFormatSpecialInfo( nFormat, bThousand, bIsRed, nPrec, nLeading );
+
+ switch( pFormatter->GetType( nFormat ) )
+ {
+ case NUMBERFORMAT_NUMBER: aFuncResult = (bThousand ? ',' : 'F'); break;
+ case NUMBERFORMAT_CURRENCY: aFuncResult = 'C'; break;
+ case NUMBERFORMAT_SCIENTIFIC: aFuncResult = 'S'; break;
+ case NUMBERFORMAT_PERCENT: aFuncResult = 'P'; break;
+ default:
+ {
+ bAppendPrec = FALSE;
+ switch( pFormatter->GetIndexTableOffset( nFormat ) )
+ {
+ case NF_DATE_SYSTEM_SHORT:
+ case NF_DATE_SYS_DMMMYY:
+ case NF_DATE_SYS_DDMMYY:
+ case NF_DATE_SYS_DDMMYYYY:
+ case NF_DATE_SYS_DMMMYYYY:
+ case NF_DATE_DIN_DMMMYYYY:
+ case NF_DATE_SYS_DMMMMYYYY:
+ case NF_DATE_DIN_DMMMMYYYY: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D1" ) ); break;
+ case NF_DATE_SYS_DDMMM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D2" ) ); break;
+ case NF_DATE_SYS_MMYY: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D3" ) ); break;
+ case NF_DATETIME_SYSTEM_SHORT_HHMM:
+ case NF_DATETIME_SYS_DDMMYYYY_HHMMSS:
+ aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D4" ) ); break;
+ case NF_DATE_DIN_MMDD: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D5" ) ); break;
+ case NF_TIME_HHMMSSAMPM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D6" ) ); break;
+ case NF_TIME_HHMMAMPM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D7" ) ); break;
+ case NF_TIME_HHMMSS: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D8" ) ); break;
+ case NF_TIME_HHMM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D9" ) ); break;
+ default: aFuncResult = 'G';
+ }
+ }
+ }
+ if( bAppendPrec )
+ aFuncResult += String::CreateFromInt32( nPrec );
+ const SvNumberformat* pFormat = pFormatter->GetEntry( nFormat );
+ if( lcl_FormatHasNegColor( pFormat ) )
+ aFuncResult += '-';
+ if( lcl_FormatHasOpenPar( pFormat ) )
+ aFuncResult.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "()" ) );
+ PushString( aFuncResult );
+ }
+ else if( aInfoType.EqualsAscii( "COLOR" ) )
+ { // 1 = negative values are colored, otherwise 0
+ const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) );
+ PushInt( lcl_FormatHasNegColor( pFormat ) ? 1 : 0 );
+ }
+ else if( aInfoType.EqualsAscii( "PARENTHESES" ) )
+ { // 1 = format string contains a '(' character, otherwise 0
+ const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) );
+ PushInt( lcl_FormatHasOpenPar( pFormat ) ? 1 : 0 );
+ }
+ else
+ PushIllegalArgument();
+ }
+ }
+}
+
+
+void ScInterpreter::ScIsRef()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCell" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetStackType() )
+ {
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if ( !nGlobalError )
+ nRes = 1;
+ }
+ break;
+ case svDoubleRef :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if ( !nGlobalError )
+ nRes = 1;
+ }
+ break;
+ case svRefList :
+ {
+ FormulaTokenRef x = PopToken();
+ if ( !nGlobalError )
+ nRes = !static_cast<ScToken*>(x.get())->GetRefList()->empty();
+ }
+ break;
+ default:
+ Pop();
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+void ScInterpreter::ScIsValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsValue" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetRawStackType() )
+ {
+ case svDouble:
+ Pop();
+ nRes = 1;
+ break;
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (GetCellErrCode( pCell ) == 0)
+ {
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_VALUE :
+ nRes = 1;
+ break;
+ case CELLTYPE_FORMULA :
+ nRes = ((ScFormulaCell*)pCell)->IsValue() &&
+ !((ScFormulaCell*)pCell)->IsEmpty();
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ ; // nothing
+ else if ( !pJumpMatrix )
+ {
+ if (pMat->GetErrorIfNotString( 0 ) == 0)
+ nRes = pMat->IsValue( 0 );
+ }
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ if (pMat->GetErrorIfNotString( nC, nR) == 0)
+ nRes = pMat->IsValue( nC, nR);
+ }
+ }
+ break;
+ default:
+ Pop();
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+void ScInterpreter::ScIsFormula()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsFormula" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ nRes = (GetCellType( GetCell( aAdr ) ) == CELLTYPE_FORMULA);
+ }
+ break;
+ default:
+ Pop();
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+void ScInterpreter::ScFormula()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFormula" );
+ String aFormula;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_FORMULA :
+ ((ScFormulaCell*)pCell)->GetFormula( aFormula );
+ break;
+ default:
+ SetError( NOTAVAILABLE );
+ }
+ }
+ break;
+ default:
+ Pop();
+ SetError( NOTAVAILABLE );
+ }
+ PushString( aFormula );
+}
+
+
+
+void ScInterpreter::ScIsNV()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsNV" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopDoubleRefOrSingleRef( aAdr );
+ if ( nGlobalError == NOTAVAILABLE )
+ nRes = 1;
+ else
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ USHORT nErr = GetCellErrCode( pCell );
+ nRes = (nErr == NOTAVAILABLE);
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ ; // nothing
+ else if ( !pJumpMatrix )
+ nRes = (pMat->GetErrorIfNotString( 0 ) == NOTAVAILABLE);
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ nRes = (pMat->GetErrorIfNotString( nC, nR) == NOTAVAILABLE);
+ }
+ }
+ break;
+ default:
+ PopError();
+ if ( nGlobalError == NOTAVAILABLE )
+ nRes = 1;
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+void ScInterpreter::ScIsErr()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsErr" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopDoubleRefOrSingleRef( aAdr );
+ if ( nGlobalError && nGlobalError != NOTAVAILABLE )
+ nRes = 1;
+ else
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ USHORT nErr = GetCellErrCode( pCell );
+ nRes = (nErr && nErr != NOTAVAILABLE);
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( nGlobalError || !pMat )
+ nRes = ((nGlobalError && nGlobalError != NOTAVAILABLE) || !pMat);
+ else if ( !pJumpMatrix )
+ {
+ USHORT nErr = pMat->GetErrorIfNotString( 0 );
+ nRes = (nErr && nErr != NOTAVAILABLE);
+ }
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ {
+ USHORT nErr = pMat->GetErrorIfNotString( nC, nR);
+ nRes = (nErr && nErr != NOTAVAILABLE);
+ }
+ }
+ }
+ break;
+ default:
+ PopError();
+ if ( nGlobalError && nGlobalError != NOTAVAILABLE )
+ nRes = 1;
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+void ScInterpreter::ScIsError()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsError" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ nRes = 1;
+ break;
+ }
+ if ( nGlobalError )
+ nRes = 1;
+ else
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ nRes = (GetCellErrCode( pCell ) != 0);
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( nGlobalError || !pMat )
+ nRes = 1;
+ else if ( !pJumpMatrix )
+ nRes = (pMat->GetErrorIfNotString( 0 ) != 0);
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ nRes = (pMat->GetErrorIfNotString( nC, nR) != 0);
+ }
+ }
+ break;
+ default:
+ PopError();
+ if ( nGlobalError )
+ nRes = 1;
+ }
+ nGlobalError = 0;
+ PushInt( nRes );
+}
+
+
+short ScInterpreter::IsEven()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsEven" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ short nRes = 0;
+ double fVal = 0.0;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ USHORT nErr = GetCellErrCode( pCell );
+ if (nErr != 0)
+ SetError(nErr);
+ else
+ {
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_VALUE :
+ fVal = GetCellValue( aAdr, pCell );
+ nRes = 1;
+ break;
+ case CELLTYPE_FORMULA :
+ if( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ nRes = 1;
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ break;
+ case svDouble:
+ {
+ fVal = PopDouble();
+ nRes = 1;
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ ; // nothing
+ else if ( !pJumpMatrix )
+ {
+ nRes = pMat->IsValue( 0 );
+ if ( nRes )
+ fVal = pMat->GetDouble( 0 );
+ }
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ {
+ nRes = pMat->IsValue( nC, nR);
+ if ( nRes )
+ fVal = pMat->GetDouble( nC, nR);
+ }
+ else
+ SetError( errNoValue);
+ }
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ if ( !nRes )
+ SetError( errIllegalParameter);
+ else
+ nRes = ( fmod( ::rtl::math::approxFloor( fabs( fVal ) ), 2.0 ) < 0.5 );
+ return nRes;
+}
+
+
+void ScInterpreter::ScIsEven()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsEven" );
+ PushInt( IsEven() );
+}
+
+
+void ScInterpreter::ScIsOdd()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsOdd" );
+ PushInt( !IsEven() );
+}
+
+
+void ScInterpreter::ScN()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScN" );
+ USHORT nErr = nGlobalError;
+ nGlobalError = 0;
+ // Temporarily override the ConvertStringToValue() error for
+ // GetCellValue() / GetCellValueOrZero()
+ USHORT nSErr = mnStringNoValueError;
+ mnStringNoValueError = errCellNoValue;
+ double fVal = GetDouble();
+ mnStringNoValueError = nSErr;
+ if ( nGlobalError == NOTAVAILABLE || nGlobalError == errCellNoValue )
+ nGlobalError = 0; // N(#NA) and N("text") are ok
+ if ( !nGlobalError && nErr != NOTAVAILABLE )
+ nGlobalError = nErr;
+ PushDouble( fVal );
+}
+
+
+void ScInterpreter::ScTrim()
+{ // trimmt nicht nur sondern schnibbelt auch doppelte raus!
+ String aVal( GetString() );
+ aVal.EraseLeadingChars();
+ aVal.EraseTrailingChars();
+ String aStr;
+ register const sal_Unicode* p = aVal.GetBuffer();
+ register const sal_Unicode* const pEnd = p + aVal.Len();
+ while ( p < pEnd )
+ {
+ if ( *p != ' ' || p[-1] != ' ' ) // erster kann kein ' ' sein, -1 ist also ok
+ aStr += *p;
+ p++;
+ }
+ PushString( aStr );
+}
+
+
+void ScInterpreter::ScUpper()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrim" );
+ String aString = GetString();
+ ScGlobal::pCharClass->toUpper(aString);
+ PushString(aString);
+}
+
+
+void ScInterpreter::ScPropper()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPropper" );
+//2do: what to do with I18N-CJK ?!?
+ String aStr( GetString() );
+ const xub_StrLen nLen = aStr.Len();
+ // #i82487# don't try to write to empty string's BufferAccess
+ // (would crash now that the empty string is const)
+ if ( nLen > 0 )
+ {
+ String aUpr( ScGlobal::pCharClass->upper( aStr ) );
+ String aLwr( ScGlobal::pCharClass->lower( aStr ) );
+ register sal_Unicode* pStr = aStr.GetBufferAccess();
+ const sal_Unicode* pUpr = aUpr.GetBuffer();
+ const sal_Unicode* pLwr = aLwr.GetBuffer();
+ *pStr = *pUpr;
+ String aTmpStr( 'x' );
+ xub_StrLen nPos = 1;
+ while( nPos < nLen )
+ {
+ aTmpStr.SetChar( 0, pStr[nPos-1] );
+ if ( !ScGlobal::pCharClass->isLetter( aTmpStr, 0 ) )
+ pStr[nPos] = pUpr[nPos];
+ else
+ pStr[nPos] = pLwr[nPos];
+ nPos++;
+ }
+ aStr.ReleaseBufferAccess( nLen );
+ }
+ PushString( aStr );
+}
+
+
+void ScInterpreter::ScLower()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLower" );
+ String aString( GetString() );
+ ScGlobal::pCharClass->toLower(aString);
+ PushString(aString);
+}
+
+
+void ScInterpreter::ScLen()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLen" );
+ String aStr( GetString() );
+ PushDouble( aStr.Len() );
+}
+
+
+void ScInterpreter::ScT()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScT" );
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ PushInt(0);
+ return ;
+ }
+ BOOL bValue = FALSE;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( GetCellErrCode( pCell ) == 0 )
+ {
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_VALUE :
+ bValue = TRUE;
+ break;
+ case CELLTYPE_FORMULA :
+ bValue = ((ScFormulaCell*)pCell)->IsValue();
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ if ( bValue )
+ PushString( EMPTY_STRING );
+ else
+ {
+ // wie GetString()
+ GetCellString( aTempStr, pCell );
+ PushString( aTempStr );
+ }
+ }
+ break;
+ case svDouble :
+ {
+ PopError();
+ PushString( EMPTY_STRING );
+ }
+ break;
+ case svString :
+ ; // leave on stack
+ break;
+ default :
+ PushError( errUnknownOpCode);
+ }
+}
+
+
+void ScInterpreter::ScValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScValue" );
+ String aInputString;
+ double fVal;
+
+ switch ( GetRawStackType() )
+ {
+ case svMissing:
+ case svEmptyCell:
+ Pop();
+ PushInt(0);
+ return;
+ case svDouble:
+ return; // leave on stack
+ //break;
+
+ case svSingleRef:
+ case svDoubleRef:
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ PushInt(0);
+ return;
+ }
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( pCell && pCell->HasStringData() )
+ GetCellString( aInputString, pCell );
+ else if ( pCell && pCell->HasValueData() )
+ {
+ PushDouble( GetCellValue(aAdr, pCell) );
+ return;
+ }
+ else
+ {
+ PushDouble(0.0);
+ return;
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
+ aInputString);
+ switch (nType)
+ {
+ case SC_MATVAL_EMPTY:
+ fVal = 0.0;
+ // fallthru
+ case SC_MATVAL_VALUE:
+ case SC_MATVAL_BOOLEAN:
+ PushDouble( fVal);
+ return;
+ //break;
+ case SC_MATVAL_STRING:
+ // evaluated below
+ break;
+ default:
+ PushIllegalArgument();
+ }
+ }
+ break;
+ default:
+ aInputString = GetString();
+ break;
+ }
+
+ sal_uInt32 nFIndex = 0; // 0 for default locale
+ if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
+ PushDouble(fVal);
+ else
+ PushIllegalArgument();
+}
+
+
+//2do: this should be a proper unicode string method
+inline BOOL lcl_ScInterpreter_IsPrintable( sal_Unicode c )
+{
+ return 0x20 <= c && c != 0x7f;
+}
+
+void ScInterpreter::ScClean()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScClean" );
+ String aStr( GetString() );
+ for ( xub_StrLen i = 0; i < aStr.Len(); i++ )
+ {
+ if ( !lcl_ScInterpreter_IsPrintable( aStr.GetChar( i ) ) )
+ aStr.Erase(i,1);
+ }
+ PushString(aStr);
+}
+
+
+void ScInterpreter::ScCode()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCode" );
+//2do: make it full range unicode?
+ const String& rStr = GetString();
+ PushInt( (sal_uChar) ByteString::ConvertFromUnicode( rStr.GetChar(0), gsl_getSystemTextEncoding() ) );
+}
+
+
+void ScInterpreter::ScChar()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChar" );
+//2do: make it full range unicode?
+ double fVal = GetDouble();
+ if (fVal < 0.0 || fVal >= 256.0)
+ PushIllegalArgument();
+ else
+ {
+ String aStr( '0' );
+ aStr.SetChar( 0, ByteString::ConvertToUnicode( (sal_Char) fVal, gsl_getSystemTextEncoding() ) );
+ PushString( aStr );
+ }
+}
+
+
+/* #i70213# fullwidth/halfwidth conversion provided by
+ * Takashi Nakamoto <bluedwarf@ooo>
+ * erAck: added Excel compatibility conversions as seen in issue's test case. */
+
+static ::rtl::OUString lcl_convertIntoHalfWidth( const ::rtl::OUString & rStr )
+{
+ static bool bFirstASCCall = true;
+ static utl::TransliterationWrapper aTrans( ::comphelper::getProcessServiceFactory(), 0 );
+
+ if( bFirstASCCall )
+ {
+ aTrans.loadModuleByImplName( ::rtl::OUString::createFromAscii( "FULLWIDTH_HALFWIDTH_LIKE_ASC" ), LANGUAGE_SYSTEM );
+ bFirstASCCall = false;
+ }
+
+ return aTrans.transliterate( rStr, 0, USHORT( rStr.getLength() ), NULL );
+}
+
+
+static ::rtl::OUString lcl_convertIntoFullWidth( const ::rtl::OUString & rStr )
+{
+ static bool bFirstJISCall = true;
+ static utl::TransliterationWrapper aTrans( ::comphelper::getProcessServiceFactory(), 0 );
+
+ if( bFirstJISCall )
+ {
+ aTrans.loadModuleByImplName( ::rtl::OUString::createFromAscii( "HALFWIDTH_FULLWIDTH_LIKE_JIS" ), LANGUAGE_SYSTEM );
+ bFirstJISCall = false;
+ }
+
+ return aTrans.transliterate( rStr, 0, USHORT( rStr.getLength() ), NULL );
+}
+
+
+/* ODFF:
+ * Summary: Converts half-width to full-width ASCII and katakana characters.
+ * Semantics: Conversion is done for half-width ASCII and katakana characters,
+ * other characters are simply copied from T to the result. This is the
+ * complementary function to ASC.
+ * For references regarding halfwidth and fullwidth characters see
+ * http://www.unicode.org/reports/tr11/
+ * http://www.unicode.org/charts/charindex2.html#H
+ * http://www.unicode.org/charts/charindex2.html#F
+ */
+void ScInterpreter::ScJis()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScJis" );
+ if (MustHaveParamCount( GetByte(), 1))
+ PushString( lcl_convertIntoFullWidth( GetString()));
+}
+
+
+/* ODFF:
+ * Summary: Converts full-width to half-width ASCII and katakana characters.
+ * Semantics: Conversion is done for full-width ASCII and katakana characters,
+ * other characters are simply copied from T to the result. This is the
+ * complementary function to JIS.
+ */
+void ScInterpreter::ScAsc()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAsc" );
+ if (MustHaveParamCount( GetByte(), 1))
+ PushString( lcl_convertIntoHalfWidth( GetString()));
+}
+
+void ScInterpreter::ScUnicode()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnicode" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ const rtl::OUString& rStr = GetString();
+ if (rStr.getLength() <= 0)
+ PushIllegalParameter();
+ else
+ {
+ sal_Int32 i = 0;
+ PushDouble( rStr.iterateCodePoints(&i) );
+ }
+ }
+}
+
+void ScInterpreter::ScUnichar()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnichar" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ double dVal = ::rtl::math::approxFloor( GetDouble() );
+ if ((dVal < 0x000000) || (dVal > 0x10FFFF))
+ PushIllegalArgument();
+ else
+ {
+ sal_uInt32 nCodePoint = static_cast<sal_uInt32>( dVal );
+ rtl::OUString aStr( &nCodePoint, 1 );
+ PushString( aStr );
+ }
+ }
+}
+
+
+void ScInterpreter::ScMin( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMin" );
+ short nParamCount = GetByte();
+ if (!MustHaveParamCountMin( nParamCount, 1))
+ return;
+ double nMin = ::std::numeric_limits<double>::max();
+ double nVal = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case svDouble :
+ {
+ nVal = GetDouble();
+ if (nMin > nVal) nMin = nVal;
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ }
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ nVal = GetCellValue( aAdr, pCell );
+ CurFmtToFuncFmt();
+ if (nMin > nVal) nMin = nVal;
+ }
+ else if ( bTextAsZero && HasCellStringData( pCell ) )
+ {
+ if ( nMin > 0.0 )
+ nMin = 0.0;
+ }
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
+ if (aValIter.GetFirst(nVal, nErr))
+ {
+ if (nMin > nVal)
+ nMin = nVal;
+ aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ while ((nErr == 0) && aValIter.GetNext(nVal, nErr))
+ {
+ if (nMin > nVal)
+ nMin = nVal;
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ pMat->GetDimensions(nC, nR);
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+ for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+ {
+ nVal = pMat->GetDouble(nMatCol,nMatRow);
+ if (nMin > nVal) nMin = nVal;
+ }
+ }
+ else
+ {
+ for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+ {
+ for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+ {
+ if (!pMat->IsString(nMatCol,nMatRow))
+ {
+ nVal = pMat->GetDouble(nMatCol,nMatRow);
+ if (nMin > nVal) nMin = nVal;
+ }
+ else if ( bTextAsZero )
+ {
+ if ( nMin > 0.0 )
+ nMin = 0.0;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case svString :
+ {
+ Pop();
+ if ( bTextAsZero )
+ {
+ if ( nMin > 0.0 )
+ nMin = 0.0;
+ }
+ else
+ SetError(errIllegalParameter);
+ }
+ break;
+ default :
+ Pop();
+ SetError(errIllegalParameter);
+ }
+ }
+ if ( nVal < nMin )
+ PushDouble(0.0);
+ else
+ PushDouble(nMin);
+}
+
+#if defined(WIN) && defined(MSC)
+#pragma optimize("",off)
+#endif
+
+void ScInterpreter::ScMax( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMax" );
+ short nParamCount = GetByte();
+ if (!MustHaveParamCountMin( nParamCount, 1))
+ return;
+ double nMax = -(::std::numeric_limits<double>::max());
+ double nVal = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case svDouble :
+ {
+ nVal = GetDouble();
+ if (nMax < nVal) nMax = nVal;
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ }
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ nVal = GetCellValue( aAdr, pCell );
+ CurFmtToFuncFmt();
+ if (nMax < nVal) nMax = nVal;
+ }
+ else if ( bTextAsZero && HasCellStringData( pCell ) )
+ {
+ if ( nMax < 0.0 )
+ nMax = 0.0;
+ }
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
+ if (aValIter.GetFirst(nVal, nErr))
+ {
+ if (nMax < nVal)
+ nMax = nVal;
+ aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ while ((nErr == 0) && aValIter.GetNext(nVal, nErr))
+ {
+ if (nMax < nVal)
+ nMax = nVal;
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+ for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+ {
+ nVal = pMat->GetDouble(nMatCol,nMatRow);
+ if (nMax < nVal) nMax = nVal;
+ }
+ }
+ else
+ {
+ for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+ {
+ for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+ {
+ if (!pMat->IsString(nMatCol,nMatRow))
+ {
+ nVal = pMat->GetDouble(nMatCol,nMatRow);
+ if (nMax < nVal) nMax = nVal;
+ }
+ else if ( bTextAsZero )
+ {
+ if ( nMax < 0.0 )
+ nMax = 0.0;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case svString :
+ {
+ Pop();
+ if ( bTextAsZero )
+ {
+ if ( nMax < 0.0 )
+ nMax = 0.0;
+ }
+ else
+ SetError(errIllegalParameter);
+ }
+ break;
+ default :
+ Pop();
+ SetError(errIllegalParameter);
+ }
+ }
+ if ( nVal > nMax )
+ PushDouble(0.0);
+ else
+ PushDouble(nMax);
+}
+#if defined(WIN) && defined(MSC)
+#pragma optimize("",on)
+#endif
+
+
+double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IterateParameters" );
+ short nParamCount = GetByte();
+ double fRes = ( eFunc == ifPRODUCT ) ? 1.0 : 0.0;
+ double fVal = 0.0;
+ double fMem = 0.0;
+ BOOL bNull = TRUE;
+ ULONG nCount = 0;
+ ScAddress aAdr;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) )
+ nGlobalError = 0;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+
+ case svString:
+ {
+ if( eFunc == ifCOUNT )
+ {
+ String aStr( PopString() );
+ sal_uInt32 nFIndex = 0; // damit default Land/Spr.
+ if ( bTextAsZero || pFormatter->IsNumberFormat(aStr, nFIndex, fVal))
+ nCount++;
+ }
+ else
+ {
+ switch ( eFunc )
+ {
+ case ifAVERAGE:
+ case ifSUM:
+ case ifSUMSQ:
+ case ifPRODUCT:
+ {
+ if ( bTextAsZero )
+ {
+ Pop();
+ nCount++;
+ if ( eFunc == ifPRODUCT )
+ fRes = 0.0;
+ }
+ else
+ {
+ while (nParamCount-- > 0)
+ Pop();
+ SetError( errNoValue );
+ }
+ }
+ break;
+ default:
+ Pop();
+ nCount++;
+ }
+ }
+ }
+ break;
+ case svDouble :
+ fVal = GetDouble();
+ nCount++;
+ switch( eFunc )
+ {
+ case ifAVERAGE:
+ case ifSUM:
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fRes += fVal;
+ break;
+ case ifSUMSQ: fRes += fVal * fVal; break;
+ case ifPRODUCT: fRes *= fVal; break;
+ default: ; // nothing
+ }
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) )
+ {
+ nGlobalError = 0;
+ if ( eFunc == ifCOUNT2 )
+ ++nCount;
+ break;
+ }
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( pCell )
+ {
+ if( eFunc == ifCOUNT2 )
+ {
+ CellType eCellType = pCell->GetCellType();
+ if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
+ nCount++;
+ if ( nGlobalError )
+ nGlobalError = 0;
+ }
+ else if ( pCell->HasValueData() )
+ {
+ nCount++;
+ fVal = GetCellValue( aAdr, pCell );
+ CurFmtToFuncFmt();
+ switch( eFunc )
+ {
+ case ifAVERAGE:
+ case ifSUM:
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fRes += fVal;
+ break;
+ case ifSUMSQ: fRes += fVal * fVal; break;
+ case ifPRODUCT: fRes *= fVal; break;
+ case ifCOUNT:
+ if ( nGlobalError )
+ {
+ nGlobalError = 0;
+ nCount--;
+ }
+ break;
+ default: ; // nothing
+ }
+ }
+ else if ( bTextAsZero && pCell->HasStringData() )
+ {
+ nCount++;
+ if ( eFunc == ifPRODUCT )
+ fRes = 0.0;
+ }
+ }
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) )
+ {
+ nGlobalError = 0;
+ if ( eFunc == ifCOUNT2 )
+ ++nCount;
+ break;
+ }
+ if( eFunc == ifCOUNT2 )
+ {
+ ScBaseCell* pCell;
+ ScCellIterator aIter( pDok, aRange, glSubTotal );
+ if ( (pCell = aIter.GetFirst()) != NULL )
+ {
+ do
+ {
+ CellType eType = pCell->GetCellType();
+ if( eType != CELLTYPE_NONE && eType != CELLTYPE_NOTE )
+ nCount++;
+ }
+ while ( (pCell = aIter.GetNext()) != NULL );
+ }
+ if ( nGlobalError )
+ nGlobalError = 0;
+ }
+ else
+ {
+ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
+ if (aValIter.GetFirst(fVal, nErr))
+ {
+ // Schleife aus Performance-Gruenden nach innen verlegt:
+ aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ switch( eFunc )
+ {
+ case ifAVERAGE:
+ case ifSUM:
+ do
+ {
+ SetError(nErr);
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fRes += fVal;
+ nCount++;
+ }
+ while (aValIter.GetNext(fVal, nErr));
+ break;
+ case ifSUMSQ:
+ do
+ {
+ SetError(nErr);
+ fRes += fVal * fVal;
+ nCount++;
+ }
+ while (aValIter.GetNext(fVal, nErr));
+ break;
+ case ifPRODUCT:
+ do
+ {
+ SetError(nErr);
+ fRes *= fVal;
+ nCount++;
+ }
+ while (aValIter.GetNext(fVal, nErr));
+ break;
+ case ifCOUNT:
+ do
+ {
+ if ( !nErr )
+ nCount++;
+ }
+ while (aValIter.GetNext(fVal, nErr));
+ break;
+ default: ; // nothing
+ }
+ SetError( nErr );
+ }
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ pMat->GetDimensions(nC, nR);
+ if( eFunc == ifCOUNT2 )
+ nCount += (ULONG) nC * nR;
+ else
+ {
+ for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+ {
+ for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+ {
+ if (!pMat->IsString(nMatCol,nMatRow))
+ {
+ nCount++;
+ fVal = pMat->GetDouble(nMatCol,nMatRow);
+ switch( eFunc )
+ {
+ case ifAVERAGE:
+ case ifSUM:
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fRes += fVal;
+ break;
+ case ifSUMSQ: fRes += fVal * fVal; break;
+ case ifPRODUCT: fRes *= fVal; break;
+ default: ; // nothing
+ }
+ }
+ else if ( bTextAsZero )
+ {
+ nCount++;
+ if ( eFunc == ifPRODUCT )
+ fRes = 0.0;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case svError:
+ {
+ Pop();
+ if ( eFunc == ifCOUNT )
+ {
+ nGlobalError = 0;
+ }
+ else if ( eFunc == ifCOUNT2 )
+ {
+ nCount++;
+ nGlobalError = 0;
+ }
+ }
+ break;
+ default :
+ while (nParamCount-- > 0)
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ }
+ switch( eFunc )
+ {
+ case ifSUM: fRes = ::rtl::math::approxAdd( fRes, fMem ); break;
+ case ifAVERAGE: fRes = div(::rtl::math::approxAdd( fRes, fMem ), nCount); break;
+ case ifCOUNT2:
+ case ifCOUNT: fRes = nCount; break;
+ case ifPRODUCT: if ( !nCount ) fRes = 0.0; break;
+ default: ; // nothing
+ }
+ // Bei Summen etc. macht ein BOOL-Ergebnis keinen Sinn
+ // und Anzahl ist immer Number (#38345#)
+ if( eFunc == ifCOUNT || nFuncFmtType == NUMBERFORMAT_LOGICAL )
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ return fRes;
+}
+
+
+void ScInterpreter::ScSumSQ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumSQ" );
+ PushDouble( IterateParameters( ifSUMSQ ) );
+}
+
+
+void ScInterpreter::ScSum()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSum" );
+ PushDouble( IterateParameters( ifSUM ) );
+}
+
+
+void ScInterpreter::ScProduct()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScProduct" );
+ PushDouble( IterateParameters( ifPRODUCT ) );
+}
+
+
+void ScInterpreter::ScAverage( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAverage" );
+ PushDouble( IterateParameters( ifAVERAGE, bTextAsZero ) );
+}
+
+
+void ScInterpreter::ScCount()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCount" );
+ PushDouble( IterateParameters( ifCOUNT ) );
+}
+
+
+void ScInterpreter::ScCount2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCount2" );
+ PushDouble( IterateParameters( ifCOUNT2 ) );
+}
+
+
+void ScInterpreter::GetStVarParams( double& rVal, double& rValCount,
+ BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStVarParams" );
+ short nParamCount = GetByte();
+
+ std::vector<double> values;
+ double fSum = 0.0;
+ double vSum = 0.0;
+ double vMean = 0.0;
+ double fVal = 0.0;
+ rValCount = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case svDouble :
+ {
+ fVal = GetDouble();
+ values.push_back(fVal);
+ fSum += fVal;
+ rValCount++;
+ }
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ values.push_back(fVal);
+ fSum += fVal;
+ rValCount++;
+ }
+ else if ( bTextAsZero && HasCellStringData( pCell ) )
+ {
+ values.push_back(0.0);
+ rValCount++;
+ }
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
+ if (aValIter.GetFirst(fVal, nErr))
+ {
+ do
+ {
+ values.push_back(fVal);
+ fSum += fVal;
+ rValCount++;
+ }
+ while ((nErr == 0) && aValIter.GetNext(fVal, nErr));
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+ {
+ for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+ {
+ if (!pMat->IsString(nMatCol,nMatRow))
+ {
+ fVal= pMat->GetDouble(nMatCol,nMatRow);
+ values.push_back(fVal);
+ fSum += fVal;
+ rValCount++;
+ }
+ else if ( bTextAsZero )
+ {
+ values.push_back(0.0);
+ rValCount++;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case svString :
+ {
+ Pop();
+ if ( bTextAsZero )
+ {
+ values.push_back(0.0);
+ rValCount++;
+ }
+ else
+ SetError(errIllegalParameter);
+ }
+ break;
+ default :
+ Pop();
+ SetError(errIllegalParameter);
+ }
+ }
+
+ ::std::vector<double>::size_type n = values.size();
+ vMean = fSum / n;
+ for (::std::vector<double>::size_type i = 0; i < n; i++)
+ vSum += ::rtl::math::approxSub( values[i], vMean) * ::rtl::math::approxSub( values[i], vMean);
+ rVal = vSum;
+}
+
+
+void ScInterpreter::ScVar( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVar" );
+ double nVal;
+ double nValCount;
+ GetStVarParams( nVal, nValCount, bTextAsZero );
+
+ if (nValCount <= 1.0)
+ PushError( errDivisionByZero );
+ else
+ PushDouble( nVal / (nValCount - 1.0));
+}
+
+
+void ScInterpreter::ScVarP( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVarP" );
+ double nVal;
+ double nValCount;
+ GetStVarParams( nVal, nValCount, bTextAsZero );
+
+ PushDouble( div( nVal, nValCount));
+}
+
+
+void ScInterpreter::ScStDev( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStDev" );
+ double nVal;
+ double nValCount;
+ GetStVarParams( nVal, nValCount, bTextAsZero );
+ if (nValCount <= 1.0)
+ PushError( errDivisionByZero );
+ else
+ PushDouble( sqrt( nVal / (nValCount - 1.0)));
+}
+
+
+void ScInterpreter::ScStDevP( BOOL bTextAsZero )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStDevP" );
+ double nVal;
+ double nValCount;
+ GetStVarParams( nVal, nValCount, bTextAsZero );
+ if (nValCount == 0.0)
+ PushError( errDivisionByZero );
+ else
+ PushDouble( sqrt( nVal / nValCount));
+
+ /* this was: PushDouble( sqrt( div( nVal, nValCount)));
+ *
+ * Besides that the special NAN gets lost in the call through sqrt(),
+ * unxlngi6.pro then looped back and forth somewhere between div() and
+ * ::rtl::math::setNan(). Tests showed that
+ *
+ * sqrt( div( 1, 0));
+ *
+ * produced a loop, but
+ *
+ * double f1 = div( 1, 0);
+ * sqrt( f1 );
+ *
+ * was fine. There seems to be some compiler optimization problem. It does
+ * not occur when compiled with debug=t.
+ */
+}
+
+
+void ScInterpreter::ScColumns()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColumns" );
+ BYTE nParamCount = GetByte();
+ ULONG nVal = 0;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ while (nParamCount-- > 0)
+ {
+ switch ( GetStackType() )
+ {
+ case svSingleRef:
+ PopError();
+ nVal++;
+ break;
+ case svDoubleRef:
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ nVal += static_cast<ULONG>(nTab2 - nTab1 + 1) *
+ static_cast<ULONG>(nCol2 - nCol1 + 1);
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ nVal += nC;
+ }
+ }
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ }
+ PushDouble((double)nVal);
+}
+
+
+void ScInterpreter::ScRows()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRows" );
+ BYTE nParamCount = GetByte();
+ ULONG nVal = 0;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ while (nParamCount-- > 0)
+ {
+ switch ( GetStackType() )
+ {
+ case svSingleRef:
+ PopError();
+ nVal++;
+ break;
+ case svDoubleRef:
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ nVal += static_cast<ULONG>(nTab2 - nTab1 + 1) *
+ static_cast<ULONG>(nRow2 - nRow1 + 1);
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ nVal += nR;
+ }
+ }
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ }
+ PushDouble((double)nVal);
+}
+
+void ScInterpreter::ScTables()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTables" );
+ BYTE nParamCount = GetByte();
+ ULONG nVal;
+ if ( nParamCount == 0 )
+ nVal = pDok->GetTableCount();
+ else
+ {
+ nVal = 0;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ while (nParamCount-- > 0)
+ {
+ switch ( GetStackType() )
+ {
+ case svSingleRef:
+ PopError();
+ nVal++;
+ break;
+ case svDoubleRef:
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ nVal += static_cast<ULONG>(nTab2 - nTab1 + 1);
+ break;
+ case svMatrix:
+ PopError();
+ nVal++;
+ break;
+ default:
+ PopError();
+ SetError( errIllegalParameter );
+ }
+ }
+ }
+ PushDouble( (double) nVal );
+}
+
+
+void ScInterpreter::ScColumn()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColumn" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 0, 1 ) )
+ {
+ double nVal = 0;
+ if (nParamCount == 0)
+ {
+ nVal = aPos.Col() + 1;
+ if (bMatrixFormula)
+ {
+ SCCOL nCols;
+ SCROW nRows;
+ pMyFormulaCell->GetMatColsRows( nCols, nRows);
+ ScMatrixRef pResMat = GetNewMat( static_cast<SCSIZE>(nCols), 1);
+ if (pResMat)
+ {
+ for (SCCOL i=0; i < nCols; ++i)
+ pResMat->PutDouble( nVal + i, static_cast<SCSIZE>(i), 0);
+ PushMatrix( pResMat);
+ return;
+ }
+ }
+ }
+ else
+ {
+ switch ( GetStackType() )
+ {
+ case svSingleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nVal = (double) (nCol1 + 1);
+ }
+ break;
+ case svDoubleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if (nCol2 > nCol1)
+ {
+ ScMatrixRef pResMat = GetNewMat(
+ static_cast<SCSIZE>(nCol2-nCol1+1), 1);
+ if (pResMat)
+ {
+ for (SCCOL i = nCol1; i <= nCol2; i++)
+ pResMat->PutDouble((double)(i+1),
+ static_cast<SCSIZE>(i-nCol1), 0);
+ PushMatrix(pResMat);
+ return;
+ }
+ else
+ nVal = 0.0;
+ }
+ else
+ nVal = (double) (nCol1 + 1);
+ }
+ break;
+ default:
+ SetError( errIllegalParameter );
+ nVal = 0.0;
+ }
+ }
+ PushDouble( nVal );
+ }
+}
+
+
+void ScInterpreter::ScRow()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRow" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 0, 1 ) )
+ {
+ double nVal = 0;
+ if (nParamCount == 0)
+ {
+ nVal = aPos.Row() + 1;
+ if (bMatrixFormula)
+ {
+ SCCOL nCols;
+ SCROW nRows;
+ pMyFormulaCell->GetMatColsRows( nCols, nRows);
+ ScMatrixRef pResMat = GetNewMat( 1, static_cast<SCSIZE>(nRows));
+ if (pResMat)
+ {
+ for (SCROW i=0; i < nRows; i++)
+ pResMat->PutDouble( nVal + i, 0, static_cast<SCSIZE>(i));
+ PushMatrix( pResMat);
+ return;
+ }
+ }
+ }
+ else
+ {
+ switch ( GetStackType() )
+ {
+ case svSingleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nVal = (double) (nRow1 + 1);
+ }
+ break;
+ case svDoubleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if (nRow2 > nRow1)
+ {
+ ScMatrixRef pResMat = GetNewMat( 1,
+ static_cast<SCSIZE>(nRow2-nRow1+1));
+ if (pResMat)
+ {
+ for (SCROW i = nRow1; i <= nRow2; i++)
+ pResMat->PutDouble((double)(i+1), 0,
+ static_cast<SCSIZE>(i-nRow1));
+ PushMatrix(pResMat);
+ return;
+ }
+ else
+ nVal = 0.0;
+ }
+ else
+ nVal = (double) (nRow1 + 1);
+ }
+ break;
+ default:
+ SetError( errIllegalParameter );
+ nVal = 0.0;
+ }
+ }
+ PushDouble( nVal );
+ }
+}
+
+void ScInterpreter::ScTable()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTable" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 0, 1 ) )
+ {
+ SCTAB nVal = 0;
+ if ( nParamCount == 0 )
+ nVal = aPos.Tab() + 1;
+ else
+ {
+ switch ( GetStackType() )
+ {
+ case svString :
+ {
+ String aStr( PopString() );
+ if ( pDok->GetTable( aStr, nVal ) )
+ ++nVal;
+ else
+ SetError( errIllegalArgument );
+ }
+ break;
+ case svSingleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nVal = nTab1 + 1;
+ }
+ break;
+ case svDoubleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ nVal = nTab1 + 1;
+ }
+ break;
+ default:
+ SetError( errIllegalParameter );
+ }
+ if ( nGlobalError )
+ nVal = 0;
+ }
+ PushDouble( (double) nVal );
+ }
+}
+
+/** returns -1 when the matrix value is smaller than the query value, 0 when
+ they are equal, and 1 when the matrix value is larger than the query
+ value. */
+static sal_Int32 lcl_CompareMatrix2Query( SCSIZE i, const ScMatrix& rMat,
+ const ScQueryEntry& rEntry)
+{
+ if (rMat.IsEmpty(i))
+ {
+ /* TODO: in case we introduced query for real empty this would have to
+ * be changed! */
+ return -1; // empty always less than anything else
+ }
+
+ /* FIXME: what is an empty path (result of IF(false;true_path) in
+ * comparisons? */
+
+ if (rMat.IsValue(i))
+ {
+ if (rEntry.bQueryByString)
+ return -1; // numeric always less than string
+
+ const double nVal1 = rMat.GetDouble(i);
+ const double nVal2 = rEntry.nVal;
+ if (nVal1 == nVal2)
+ return 0;
+
+ return nVal1 < nVal2 ? -1 : 1;
+ }
+
+ if (!rEntry.bQueryByString)
+ return 1; // string always greater than numeric
+
+ if (!rEntry.pStr)
+ // this should not happen!
+ return 1;
+
+ const String& rStr1 = rMat.GetString(i);
+ const String& rStr2 = *rEntry.pStr;
+
+ return ScGlobal::GetCollator()->compareString( rStr1, rStr2); // case-insensitive
+}
+
+/** returns the last item with the identical value as the original item
+ value. */
+static void lcl_GetLastMatch( SCSIZE& rIndex, const ScMatrix& rMat,
+ SCSIZE nMatCount, bool bReverse)
+{
+ if (rMat.IsValue(rIndex))
+ {
+ double nVal = rMat.GetDouble(rIndex);
+ if (bReverse)
+ while (rIndex > 0 && rMat.IsValue(rIndex-1) &&
+ nVal == rMat.GetDouble(rIndex-1))
+ --rIndex;
+ else
+ while (rIndex < nMatCount-1 && rMat.IsValue(rIndex+1) &&
+ nVal == rMat.GetDouble(rIndex+1))
+ ++rIndex;
+ }
+ //! Order of IsEmptyPath, IsEmpty, IsString is significant!
+ else if (rMat.IsEmptyPath(rIndex))
+ {
+ if (bReverse)
+ while (rIndex > 0 && rMat.IsEmptyPath(rIndex-1))
+ --rIndex;
+ else
+ while (rIndex < nMatCount-1 && rMat.IsEmptyPath(rIndex+1))
+ ++rIndex;
+ }
+ else if (rMat.IsEmpty(rIndex))
+ {
+ if (bReverse)
+ while (rIndex > 0 && rMat.IsEmpty(rIndex-1))
+ --rIndex;
+ else
+ while (rIndex < nMatCount-1 && rMat.IsEmpty(rIndex+1))
+ ++rIndex;
+ }
+ else if (rMat.IsString(rIndex))
+ {
+ String aStr( rMat.GetString(rIndex));
+ if (bReverse)
+ while (rIndex > 0 && rMat.IsString(rIndex-1) &&
+ aStr == rMat.GetString(rIndex-1))
+ --rIndex;
+ else
+ while (rIndex < nMatCount-1 && rMat.IsString(rIndex+1) &&
+ aStr == rMat.GetString(rIndex+1))
+ ++rIndex;
+ }
+ else
+ {
+ DBG_ERRORFILE("lcl_GetLastMatch: unhandled matrix type");
+ }
+}
+
+void ScInterpreter::ScMatch()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatch" );
+ ScMatrixRef pMatSrc = NULL;
+
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ double fTyp;
+ if (nParamCount == 3)
+ fTyp = GetDouble();
+ else
+ fTyp = 1.0;
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ SCCOL nCol2 = 0;
+ SCROW nRow2 = 0;
+ SCTAB nTab2 = 0;
+ if (GetStackType() == svDoubleRef)
+ {
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2))
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ else if (GetStackType() == svMatrix)
+ {
+ pMatSrc = PopMatrix();
+ if (!pMatSrc)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ else
+ {
+ PushIllegalParameter();
+ return;
+ }
+ if (nGlobalError == 0)
+ {
+ double fVal;
+ String sStr;
+ ScQueryParam rParam;
+ rParam.nCol1 = nCol1;
+ rParam.nRow1 = nRow1;
+ rParam.nCol2 = nCol2;
+ rParam.nTab = nTab1;
+ rParam.bMixedComparison = TRUE;
+
+ ScQueryEntry& rEntry = rParam.GetEntry(0);
+ rEntry.bDoQuery = TRUE;
+ if (fTyp < 0.0)
+ rEntry.eOp = SC_GREATER_EQUAL;
+ else if (fTyp > 0.0)
+ rEntry.eOp = SC_LESS_EQUAL;
+ switch ( GetStackType() )
+ {
+ case svDouble:
+ {
+ fVal = GetDouble();
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = fVal;
+ }
+ break;
+ case svString:
+ {
+ sStr = GetString();
+ rEntry.bQueryByString = TRUE;
+ *rEntry.pStr = sStr;
+ }
+ break;
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ PushInt(0);
+ return ;
+ }
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = fVal;
+ }
+ else
+ {
+ GetCellString(sStr, pCell);
+ rEntry.bQueryByString = TRUE;
+ *rEntry.pStr = sStr;
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatValType nType = GetDoubleOrStringFromMatrix(
+ rEntry.nVal, *rEntry.pStr);
+ rEntry.bQueryByString = ScMatrix::IsNonValueType( nType);
+ }
+ break;
+ default:
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ if ( rEntry.bQueryByString )
+ rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
+
+ if (pMatSrc) // The source data is matrix array.
+ {
+ SCSIZE nC, nR;
+ pMatSrc->GetDimensions( nC, nR);
+ if (nC > 1 && nR > 1)
+ {
+ // The source matrix must be a vector.
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nMatCount = (nC == 1) ? nR : nC;
+
+ // simple serial search for equality mode (source data doesn't
+ // need to be sorted).
+
+ if (rEntry.eOp == SC_EQUAL)
+ {
+ for (SCSIZE i = 0; i < nMatCount; ++i)
+ {
+ if (lcl_CompareMatrix2Query( i, *pMatSrc, rEntry) == 0)
+ {
+ PushDouble(i+1); // found !
+ return;
+ }
+ }
+ PushNA(); // not found
+ return;
+ }
+
+ // binary search for non-equality mode (the source data is
+ // assumed to be sorted).
+
+ bool bAscOrder = (rEntry.eOp == SC_LESS_EQUAL);
+ SCSIZE nFirst = 0, nLast = nMatCount-1, nHitIndex = 0;
+ for (SCSIZE nLen = nLast-nFirst; nLen > 0; nLen = nLast-nFirst)
+ {
+ SCSIZE nMid = nFirst + nLen/2;
+ sal_Int32 nCmp = lcl_CompareMatrix2Query( nMid, *pMatSrc, rEntry);
+ if (nCmp == 0)
+ {
+ // exact match. find the last item with the same value.
+ lcl_GetLastMatch( nMid, *pMatSrc, nMatCount, !bAscOrder);
+ PushDouble( nMid+1);
+ return;
+ }
+
+ if (nLen == 1) // first and last items are next to each other.
+ {
+ if (nCmp < 0)
+ nHitIndex = bAscOrder ? nLast : nFirst;
+ else
+ nHitIndex = bAscOrder ? nFirst : nLast;
+ break;
+ }
+
+ if (nCmp < 0)
+ {
+ if (bAscOrder)
+ nFirst = nMid;
+ else
+ nLast = nMid;
+ }
+ else
+ {
+ if (bAscOrder)
+ nLast = nMid;
+ else
+ nFirst = nMid;
+ }
+ }
+
+ if (nHitIndex == nMatCount-1) // last item
+ {
+ sal_Int32 nCmp = lcl_CompareMatrix2Query( nHitIndex, *pMatSrc, rEntry);
+ if ((bAscOrder && nCmp <= 0) || (!bAscOrder && nCmp >= 0))
+ {
+ // either the last item is an exact match or the real
+ // hit is beyond the last item.
+ PushDouble( nHitIndex+1);
+ return;
+ }
+ }
+
+ if (nHitIndex > 0) // valid hit must be 2nd item or higher
+ {
+ PushDouble( nHitIndex); // non-exact match
+ return;
+ }
+
+ PushNA();
+ return;
+ }
+
+ SCCOLROW nDelta = 0;
+ if (nCol1 == nCol2)
+ { // search row in column
+ rParam.nRow2 = nRow2;
+ rEntry.nField = nCol1;
+ ScAddress aResultPos( nCol1, nRow1, nTab1);
+ if (!LookupQueryWithCache( aResultPos, rParam))
+ {
+ PushNA();
+ return;
+ }
+ nDelta = aResultPos.Row() - nRow1;
+ }
+ else
+ { // search column in row
+ SCCOL nC;
+ rParam.bByRow = FALSE;
+ rParam.nRow2 = nRow1;
+ rEntry.nField = nCol1;
+ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
+ // Advance Entry.nField in Iterator if column changed
+ aCellIter.SetAdvanceQueryParamEntryField( TRUE );
+ if (fTyp == 0.0)
+ { // EQUAL
+ if ( aCellIter.GetFirst() )
+ nC = aCellIter.GetCol();
+ else
+ {
+ PushNA();
+ return;
+ }
+ }
+ else
+ { // <= or >=
+ SCROW nR;
+ if ( !aCellIter.FindEqualOrSortedLastInRange( nC, nR ) )
+ {
+ PushNA();
+ return;
+ }
+ }
+ nDelta = nC - nCol1;
+ }
+ PushDouble((double) (nDelta + 1));
+ }
+ else
+ PushIllegalParameter();
+ }
+}
+
+
+void ScInterpreter::ScCountEmptyCells()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountEmptyCells" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ ULONG nMaxCount = 0, nCount = 0;
+ CellType eCellType;
+ switch (GetStackType())
+ {
+ case svSingleRef :
+ {
+ nMaxCount = 1;
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ eCellType = GetCellType( GetCell( aAdr ) );
+ if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
+ nCount = 1;
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ ScRange aRange;
+ short nParam = 1;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ PopDoubleRef( aRange, nParam, nRefInList);
+ nMaxCount +=
+ static_cast<ULONG>(aRange.aEnd.Row() - aRange.aStart.Row() + 1) *
+ static_cast<ULONG>(aRange.aEnd.Col() - aRange.aStart.Col() + 1) *
+ static_cast<ULONG>(aRange.aEnd.Tab() - aRange.aStart.Tab() + 1);
+ ScBaseCell* pCell;
+ ScCellIterator aDocIter( pDok, aRange, glSubTotal);
+ if ( (pCell = aDocIter.GetFirst()) != NULL )
+ {
+ do
+ {
+ if ((eCellType = pCell->GetCellType()) != CELLTYPE_NONE
+ && eCellType != CELLTYPE_NOTE)
+ nCount++;
+ } while ( (pCell = aDocIter.GetNext()) != NULL );
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ PushDouble(nMaxCount - nCount);
+ }
+}
+
+
+void ScInterpreter::ScCountIf()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountIf" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ String rString;
+ double fVal = 0.0;
+ BOOL bIsString = TRUE;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ PushInt(0);
+ return ;
+ }
+ ScBaseCell* pCell = GetCell( aAdr );
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_VALUE :
+ fVal = GetCellValue( aAdr, pCell );
+ bIsString = FALSE;
+ break;
+ case CELLTYPE_FORMULA :
+ if( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ bIsString = FALSE;
+ }
+ else
+ GetCellString(rString, pCell);
+ break;
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ GetCellString(rString, pCell);
+ break;
+ default:
+ fVal = 0.0;
+ bIsString = FALSE;
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
+ rString);
+ bIsString = ScMatrix::IsNonValueType( nType);
+ }
+ break;
+ case svString:
+ rString = GetString();
+ break;
+ default:
+ {
+ fVal = GetDouble();
+ bIsString = FALSE;
+ }
+ }
+ double fSum = 0.0;
+ short nParam = 1;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ ScMatrixRef pQueryMatrix;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svRefList :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ }
+ break;
+ case svSingleRef :
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nCol2 = nCol1;
+ 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();
+ return;
+ }
+ if (nCol1 > nCol2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ if (nGlobalError == 0)
+ {
+ ScQueryParam rParam;
+ rParam.nRow1 = nRow1;
+ rParam.nRow2 = nRow2;
+
+ ScQueryEntry& rEntry = rParam.GetEntry(0);
+ rEntry.bDoQuery = TRUE;
+ if (!bIsString)
+ {
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = fVal;
+ rEntry.eOp = SC_EQUAL;
+ }
+ else
+ {
+ rParam.FillInExcelSyntax(rString, 0);
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString =
+ !(pFormatter->IsNumberFormat(
+ *rEntry.pStr, nIndex, rEntry.nVal));
+ if ( rEntry.bQueryByString )
+ rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
+ }
+ rParam.nCol1 = nCol1;
+ rParam.nCol2 = nCol2;
+ rEntry.nField = nCol1;
+ if (pQueryMatrix)
+ {
+ // Never case-sensitive.
+ ScCompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
+ ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
+ if (nGlobalError || !pResultMatrix)
+ {
+ 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
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ PushDouble(fSum);
+ }
+}
+
+
+void ScInterpreter::ScSumIf()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumIf" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ SCCOL nCol3 = 0;
+ SCROW nRow3 = 0;
+ SCTAB nTab3 = 0;
+
+ ScMatrixRef pSumExtraMatrix;
+ bool bSumExtraRange = (nParamCount == 3);
+ if (bSumExtraRange)
+ {
+ // Save only the upperleft cell in case of cell range. The geometry
+ // of the 3rd parameter is taken from the 1st parameter.
+
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ {
+ SCCOL nColJunk = 0;
+ SCROW nRowJunk = 0;
+ SCTAB nTabJunk = 0;
+ PopDoubleRef( nCol3, nRow3, nTab3, nColJunk, nRowJunk, nTabJunk );
+ if ( nTabJunk != nTab3 )
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ break;
+ case svSingleRef :
+ PopSingleRef( nCol3, nRow3, nTab3 );
+ break;
+ case svMatrix:
+ pSumExtraMatrix = PopMatrix();
+ //! nCol3, nRow3, nTab3 remain 0
+ break;
+ default:
+ PushIllegalParameter();
+ return ;
+ }
+ }
+ String rString;
+ double fVal = 0.0;
+ BOOL bIsString = TRUE;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ PushInt(0);
+ return ;
+ }
+ ScBaseCell* pCell = GetCell( aAdr );
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_VALUE :
+ fVal = GetCellValue( aAdr, pCell );
+ bIsString = FALSE;
+ break;
+ case CELLTYPE_FORMULA :
+ if( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ bIsString = FALSE;
+ }
+ else
+ GetCellString(rString, pCell);
+ break;
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ GetCellString(rString, pCell);
+ break;
+ default:
+ fVal = 0.0;
+ bIsString = FALSE;
+ }
+ }
+ break;
+ case svString:
+ rString = GetString();
+ break;
+ case svMatrix :
+ {
+ ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
+ rString);
+ bIsString = ScMatrix::IsNonValueType( nType);
+ }
+ break;
+ default:
+ {
+ fVal = GetDouble();
+ bIsString = FALSE;
+ }
+ }
+
+ double fSum = 0.0;
+ double fMem = 0.0;
+ BOOL bNull = TRUE;
+ short nParam = 1;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ ScMatrixRef pQueryMatrix;
+ switch ( GetStackType() )
+ {
+ case svRefList :
+ if (bSumExtraRange)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ else
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ }
+ break;
+ case svDoubleRef :
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ break;
+ case svSingleRef :
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nCol2 = nCol1;
+ 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 )
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ if (bSumExtraRange)
+ {
+ // Take the range geometry of the 1st parameter and apply it to
+ // the 3rd. If parts of the resulting range would point outside
+ // the sheet, don't complain but silently ignore and simply cut
+ // them away, this is what Xcl does :-/
+
+ // For the cut-away part we also don't need to determine the
+ // criteria match, so shrink the source range accordingly,
+ // instead of the result range.
+ SCCOL nColDelta = nCol2 - nCol1;
+ SCROW nRowDelta = nRow2 - nRow1;
+ SCCOL nMaxCol;
+ SCROW nMaxRow;
+ if (pSumExtraMatrix)
+ {
+ 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 > nMaxRow)
+ {
+ SCROW nNewDelta = nMaxRow - nRow3;
+ nRow2 = nRow1 + nNewDelta;
+ }
+ }
+ else
+ {
+ nCol3 = nCol1;
+ nRow3 = nRow1;
+ nTab3 = nTab1;
+ }
+
+ if (nGlobalError == 0)
+ {
+ ScQueryParam rParam;
+ rParam.nRow1 = nRow1;
+ rParam.nRow2 = nRow2;
+
+ ScQueryEntry& rEntry = rParam.GetEntry(0);
+ rEntry.bDoQuery = TRUE;
+ if (!bIsString)
+ {
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = fVal;
+ rEntry.eOp = SC_EQUAL;
+ }
+ else
+ {
+ rParam.FillInExcelSyntax(rString, 0);
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString =
+ !(pFormatter->IsNumberFormat(
+ *rEntry.pStr, nIndex, rEntry.nVal));
+ if ( rEntry.bQueryByString )
+ rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
+ }
+ ScAddress aAdr;
+ aAdr.SetTab( nTab3 );
+ rParam.nCol1 = nCol1;
+ rParam.nCol2 = nCol2;
+ rEntry.nField = nCol1;
+ SCsCOL nColDiff = nCol3 - nCol1;
+ SCsROW nRowDiff = nRow3 - nRow1;
+ if (pQueryMatrix)
+ {
+ // Never case-sensitive.
+ ScCompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
+ ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
+ if (nGlobalError || !pResultMatrix)
+ {
+ PushIllegalParameter();
+ return;
+ }
+
+ if (pSumExtraMatrix)
+ {
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ {
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ {
+ 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
+ {
+ 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
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ PushDouble( ::rtl::math::approxAdd( fSum, fMem ) );
+ }
+}
+
+
+void ScInterpreter::ScLookup()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLookup" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
+ return ;
+
+ ScMatrixRef pDataMat = NULL, pResMat = NULL;
+ SCCOL nCol1 = 0, nCol2 = 0, nResCol1 = 0, nResCol2 = 0;
+ SCROW nRow1 = 0, nRow2 = 0, nResRow1 = 0, nResRow2 = 0;
+ SCTAB nTab1 = 0, nResTab = 0;
+ SCSIZE nLenMajor = 0; // length of major direction
+ bool bVertical = true; // whether to lookup vertically or horizontally
+
+ // The third parameter, result array, for double, string and single reference.
+ double fResVal = 0.0;
+ String aResStr;
+ ScAddress aResAdr;
+ StackVar eResArrayType = svUnknown;
+
+ if (nParamCount == 3)
+ {
+ eResArrayType = GetStackType();
+ switch (eResArrayType)
+ {
+ case svDoubleRef:
+ {
+ SCTAB nTabJunk;
+ PopDoubleRef(nResCol1, nResRow1, nResTab,
+ nResCol2, nResRow2, nTabJunk);
+ if (nResTab != nTabJunk ||
+ ((nResRow2 - nResRow1) > 0 && (nResCol2 - nResCol1) > 0))
+ {
+ // The result array must be a vector.
+ PushIllegalParameter();
+ return;
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ pResMat = PopMatrix();
+ if (!pResMat)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC, nR;
+ pResMat->GetDimensions(nC, nR);
+ if (nC != 1 && nR != 1)
+ {
+ // Result matrix must be a vector.
+ PushIllegalParameter();
+ return;
+ }
+ }
+ break;
+ case svDouble:
+ fResVal = GetDouble();
+ break;
+ case svString:
+ aResStr = GetString();
+ break;
+ case svSingleRef:
+ PopSingleRef( aResAdr );
+ break;
+ default:
+ PushIllegalParameter();
+ return;
+ }
+ }
+
+ // For double, string and single reference.
+ double fDataVal = 0.0;
+ String aDataStr;
+ ScAddress aDataAdr;
+ bool bValueData = false;
+
+ // Get the data-result range and also determine whether this is vertical
+ // lookup or horizontal lookup.
+
+ StackVar eDataArrayType = GetStackType();
+ switch (eDataArrayType)
+ {
+ case svDoubleRef:
+ {
+ SCTAB nTabJunk;
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTabJunk);
+ if (nTab1 != nTabJunk)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ bVertical = (nRow2 - nRow1) >= (nCol2 - nCol1);
+ nLenMajor = bVertical ? nRow2 - nRow1 + 1 : nCol2 - nCol1 + 1;
+ }
+ break;
+ case svMatrix:
+ {
+ pDataMat = PopMatrix();
+ if (!pDataMat)
+ {
+ PushIllegalParameter();
+ return;
+ }
+
+ SCSIZE nC, nR;
+ pDataMat->GetDimensions(nC, nR);
+ bVertical = (nR >= nC);
+ nLenMajor = bVertical ? nR : nC;
+ }
+ break;
+ case svDouble:
+ {
+ fDataVal = GetDouble();
+ bValueData = true;
+ }
+ break;
+ case svString:
+ {
+ aDataStr = GetString();
+ }
+ break;
+ case svSingleRef:
+ {
+ PopSingleRef( aDataAdr );
+ const ScBaseCell* pDataCell = GetCell( aDataAdr );
+ if (HasCellEmptyData( pDataCell))
+ {
+ // Empty cells aren't found anywhere, bail out early.
+ SetError( NOTAVAILABLE);
+ }
+ else if (HasCellValueData( pDataCell))
+ {
+ fDataVal = GetCellValue( aDataAdr, pDataCell );
+ bValueData = true;
+ }
+ else
+ GetCellString( aDataStr, pDataCell );
+ }
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+
+
+ if (nGlobalError)
+ {
+ PushError( nGlobalError);
+ return;
+ }
+
+ // Get the lookup value.
+
+ ScQueryParam aParam;
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ if ( !FillEntry(rEntry) )
+ return;
+
+ if ( eDataArrayType == svDouble || eDataArrayType == svString ||
+ eDataArrayType == svSingleRef )
+ {
+ // Delta position for a single value is always 0.
+
+ // Found if data <= query, but not if query is string and found data is
+ // numeric or vice versa. This is how Excel does it but doesn't
+ // document it.
+
+ bool bFound = false;
+ if ( bValueData )
+ {
+ if ( rEntry.bQueryByString )
+ bFound = false;
+ else
+ bFound = (fDataVal <= rEntry.nVal);
+ }
+ else
+ {
+ if ( !rEntry.bQueryByString )
+ bFound = false;
+ else
+ bFound = (ScGlobal::GetCollator()->compareString( aDataStr, *rEntry.pStr) <= 0);
+ }
+
+ if (!bFound)
+ {
+ PushNA();
+ return;
+ }
+
+ if (pResMat)
+ {
+ if (pResMat->IsValue( 0 ))
+ PushDouble(pResMat->GetDouble( 0 ));
+ else
+ PushString(pResMat->GetString( 0 ));
+ }
+ else if (nParamCount == 3)
+ {
+ switch (eResArrayType)
+ {
+ case svDouble:
+ PushDouble( fResVal );
+ break;
+ case svString:
+ PushString( aResStr );
+ break;
+ case svDoubleRef:
+ aResAdr.Set( nResCol1, nResRow1, nResTab);
+ // fallthru
+ case svSingleRef:
+ PushCellResultToken( true, aResAdr, NULL, NULL);
+ break;
+ default:
+ DBG_ERRORFILE( "ScInterpreter::ScLookup: unhandled eResArrayType, single value data");
+ }
+ }
+ else
+ {
+ switch (eDataArrayType)
+ {
+ case svDouble:
+ PushDouble( fDataVal );
+ break;
+ case svString:
+ PushString( aDataStr );
+ break;
+ case svSingleRef:
+ PushCellResultToken( true, aDataAdr, NULL, NULL);
+ break;
+ default:
+ DBG_ERRORFILE( "ScInterpreter::ScLookup: unhandled eDataArrayType, single value data");
+ }
+ }
+ return;
+ }
+
+ // Now, perform the search to compute the delta position (nDelta).
+
+ if (pDataMat)
+ {
+ // Data array is given as a matrix.
+ rEntry.bDoQuery = true;
+ rEntry.eOp = SC_LESS_EQUAL;
+ bool bFound = false;
+
+ SCSIZE nC, nR;
+ pDataMat->GetDimensions(nC, nR);
+
+ // In case of non-vector matrix, only search the first row or column.
+ ScMatrixRef pDataMat2;
+ if (bVertical)
+ {
+ ScMatrixRef pTempMat(new ScMatrix(1, nR));
+ for (SCSIZE i = 0; i < nR; ++i)
+ if (pDataMat->IsValue(0, i))
+ pTempMat->PutDouble(pDataMat->GetDouble(0, i), 0, i);
+ else
+ pTempMat->PutString(pDataMat->GetString(0, i), 0, i);
+ pDataMat2 = pTempMat;
+ }
+ else
+ {
+ ScMatrixRef pTempMat(new ScMatrix(nC, 1));
+ for (SCSIZE i = 0; i < nC; ++i)
+ if (pDataMat->IsValue(i, 0))
+ pTempMat->PutDouble(pDataMat->GetDouble(i, 0), i, 0);
+ else
+ pTempMat->PutString(pDataMat->GetString(i, 0), i, 0);
+ pDataMat2 = pTempMat;
+ }
+
+ // binary search for non-equality mode (the source data is
+ // assumed to be sorted in ascending order).
+
+ SCCOLROW nDelta = -1;
+
+ SCSIZE nFirst = 0, nLast = nLenMajor-1; //, nHitIndex = 0;
+ for (SCSIZE nLen = nLast-nFirst; nLen > 0; nLen = nLast-nFirst)
+ {
+ SCSIZE nMid = nFirst + nLen/2;
+ sal_Int32 nCmp = lcl_CompareMatrix2Query( nMid, *pDataMat2, rEntry);
+ if (nCmp == 0)
+ {
+ // exact match. find the last item with the same value.
+ lcl_GetLastMatch( nMid, *pDataMat2, nLenMajor, false);
+ nDelta = nMid;
+ bFound = true;
+ break;
+ }
+
+ if (nLen == 1) // first and last items are next to each other.
+ {
+ nDelta = nCmp < 0 ? nLast - 1 : nFirst - 1;
+ // If already the 1st item is greater there's nothing found.
+ bFound = (nDelta >= 0);
+ break;
+ }
+
+ if (nCmp < 0)
+ nFirst = nMid;
+ else
+ nLast = nMid;
+ }
+
+ if (nDelta == static_cast<SCCOLROW>(nLenMajor-2)) // last item
+ {
+ sal_Int32 nCmp = lcl_CompareMatrix2Query(nDelta+1, *pDataMat2, rEntry);
+ if (nCmp <= 0)
+ {
+ // either the last item is an exact match or the real
+ // hit is beyond the last item.
+ nDelta += 1;
+ bFound = true;
+ }
+ }
+ else if (nDelta > 0) // valid hit must be 2nd item or higher
+ {
+ // non-exact match
+ bFound = true;
+ }
+
+ // With 0-9 < A-Z, if query is numeric and data found is string, or
+ // vice versa, the (yet another undocumented) Excel behavior is to
+ // return #N/A instead.
+
+ if (bFound)
+ {
+ SCCOLROW i = nDelta;
+ SCSIZE n = pDataMat->GetElementCount();
+ if (static_cast<SCSIZE>(i) >= n)
+ i = static_cast<SCCOLROW>(n);
+ if (bool(rEntry.bQueryByString) == bool(pDataMat->IsValue(i)))
+ bFound = false;
+ }
+
+ if (!bFound)
+ {
+ PushNA();
+ return;
+ }
+
+ // Now that we've found the delta, push the result back to the cell.
+
+ if (pResMat)
+ {
+ // result array is matrix.
+ if (static_cast<SCSIZE>(nDelta) >= pResMat->GetElementCount())
+ {
+ PushNA();
+ return;
+ }
+ if (pResMat->IsValue(nDelta))
+ PushDouble(pResMat->GetDouble(nDelta));
+ else
+ PushString(pResMat->GetString(nDelta));
+ }
+ else if (nParamCount == 3)
+ {
+ // result array is cell range.
+ ScAddress aAdr;
+ aAdr.SetTab(nResTab);
+ bool bResVertical = (nResRow2 - nResRow1) > 0;
+ if (bResVertical)
+ {
+ SCROW nTempRow = static_cast<SCROW>(nResRow1 + nDelta);
+ if (nTempRow > MAXROW)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nResCol1);
+ aAdr.SetRow(nTempRow);
+ }
+ else
+ {
+ SCCOL nTempCol = static_cast<SCCOL>(nResCol1 + nDelta);
+ if (nTempCol > MAXCOL)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nTempCol);
+ aAdr.SetRow(nResRow1);
+ }
+ PushCellResultToken(true, aAdr, NULL, NULL);
+ }
+ else
+ {
+ // no result array. Use the data array to get the final value from.
+ if (bVertical)
+ {
+ if (pDataMat->IsValue(nC-1, nDelta))
+ PushDouble(pDataMat->GetDouble(nC-1, nDelta));
+ else
+ PushString(pDataMat->GetString(nC-1, nDelta));
+ }
+ else
+ {
+ if (pDataMat->IsValue(nDelta, nR-1))
+ PushDouble(pDataMat->GetDouble(nDelta, nR-1));
+ else
+ PushString(pDataMat->GetString(nDelta, nR-1));
+ }
+ }
+
+ return;
+ }
+
+ // Perform cell range search.
+
+ aParam.nCol1 = nCol1;
+ aParam.nRow1 = nRow1;
+ aParam.nCol2 = bVertical ? nCol1 : nCol2;
+ aParam.nRow2 = bVertical ? nRow2 : nRow1;
+ aParam.bByRow = bVertical;
+ aParam.bMixedComparison = true;
+
+ rEntry.bDoQuery = TRUE;
+ rEntry.eOp = SC_LESS_EQUAL;
+ rEntry.nField = nCol1;
+ if ( rEntry.bQueryByString )
+ aParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
+
+ ScQueryCellIterator aCellIter(pDok, nTab1, aParam, FALSE);
+ SCCOL nC;
+ SCROW nR;
+ // Advance Entry.nField in iterator upon switching columns if
+ // lookup in row.
+ aCellIter.SetAdvanceQueryParamEntryField(!bVertical);
+ if ( !aCellIter.FindEqualOrSortedLastInRange(nC, nR) )
+ {
+ PushNA();
+ return;
+ }
+
+ SCCOLROW nDelta = bVertical ? static_cast<SCSIZE>(nR-nRow1) : static_cast<SCSIZE>(nC-nCol1);
+
+ if (pResMat)
+ {
+ // Use the matrix result array.
+ if (pResMat->IsValue(nDelta))
+ PushDouble(pResMat->GetDouble(nDelta));
+ else
+ PushString(pResMat->GetString(nDelta));
+ }
+ else if (nParamCount == 3)
+ {
+ switch (eResArrayType)
+ {
+ case svDoubleRef:
+ {
+ // Use the result array vector. Note that the result array is assumed
+ // to be a vector (i.e. 1-dimensinoal array).
+
+ ScAddress aAdr;
+ aAdr.SetTab(nResTab);
+ bool bResVertical = (nResRow2 - nResRow1) > 0;
+ if (bResVertical)
+ {
+ SCROW nTempRow = static_cast<SCROW>(nResRow1 + nDelta);
+ if (nTempRow > MAXROW)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nResCol1);
+ aAdr.SetRow(nTempRow);
+ }
+ else
+ {
+ SCCOL nTempCol = static_cast<SCCOL>(nResCol1 + nDelta);
+ if (nTempCol > MAXCOL)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nTempCol);
+ aAdr.SetRow(nResRow1);
+ }
+ PushCellResultToken( true, aAdr, NULL, NULL);
+ }
+ break;
+ case svDouble:
+ case svString:
+ case svSingleRef:
+ {
+ if (nDelta != 0)
+ PushNA();
+ else
+ {
+ switch (eResArrayType)
+ {
+ case svDouble:
+ PushDouble( fResVal );
+ break;
+ case svString:
+ PushString( aResStr );
+ break;
+ case svSingleRef:
+ PushCellResultToken( true, aResAdr, NULL, NULL);
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "ScInterpreter::ScLookup: unhandled eResArrayType, range search");
+ }
+ }
+ else
+ {
+ // Regardless of whether or not the result array exists, the last
+ // array is always used as the "result" array.
+
+ ScAddress aAdr;
+ aAdr.SetTab(nTab1);
+ if (bVertical)
+ {
+ SCROW nTempRow = static_cast<SCROW>(nRow1 + nDelta);
+ if (nTempRow > MAXROW)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nCol2);
+ aAdr.SetRow(nTempRow);
+ }
+ else
+ {
+ SCCOL nTempCol = static_cast<SCCOL>(nCol1 + nDelta);
+ if (nTempCol > MAXCOL)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nTempCol);
+ aAdr.SetRow(nRow2);
+ }
+ PushCellResultToken(true, aAdr, NULL, NULL);
+ }
+}
+
+
+void ScInterpreter::ScHLookup()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHLookup" );
+ CalculateLookup(TRUE);
+}
+void ScInterpreter::CalculateLookup(BOOL HLookup)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateLookup" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 3, 4 ) )
+ {
+ BOOL bSorted;
+ if (nParamCount == 4)
+ bSorted = GetBool();
+ else
+ bSorted = TRUE;
+ double fIndex = ::rtl::math::approxFloor( GetDouble() ) - 1.0;
+ ScMatrixRef pMat = NULL;
+ SCSIZE nC = 0, nR = 0;
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ SCCOL nCol2 = 0;
+ SCROW nRow2 = 0;
+ SCTAB nTab2;
+ if (GetStackType() == svDoubleRef)
+ {
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (nTab1 != nTab2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ else if (GetStackType() == svMatrix)
+ {
+ pMat = PopMatrix();
+ if (pMat)
+ pMat->GetDimensions(nC, nR);
+ else
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ else
+ {
+ PushIllegalParameter();
+ return;
+ }
+ if ( fIndex < 0.0 || (HLookup ? (pMat ? (fIndex >= nR) : (fIndex+nRow1 > nRow2)) : (pMat ? (fIndex >= nC) : (fIndex+nCol1 > nCol2)) ) )
+ {
+ PushIllegalArgument();
+ return;
+ }
+ SCROW nZIndex = static_cast<SCROW>(fIndex);
+ SCCOL nSpIndex = static_cast<SCCOL>(fIndex);
+
+ if (!pMat)
+ {
+ nZIndex += nRow1; // Wertzeile
+ nSpIndex = sal::static_int_cast<SCCOL>( nSpIndex + nCol1 ); // value column
+ }
+
+ if (nGlobalError == 0)
+ {
+ ScQueryParam rParam;
+ rParam.nCol1 = nCol1;
+ rParam.nRow1 = nRow1;
+ if ( HLookup )
+ {
+ rParam.nCol2 = nCol2;
+ rParam.nRow2 = nRow1; // nur in der ersten Zeile suchen
+ rParam.bByRow = FALSE;
+ } // if ( HLookup )
+ else
+ {
+ rParam.nCol2 = nCol1; // nur in der ersten Spalte suchen
+ rParam.nRow2 = nRow2;
+ rParam.nTab = nTab1;
+ }
+ rParam.bMixedComparison = TRUE;
+
+ ScQueryEntry& rEntry = rParam.GetEntry(0);
+ rEntry.bDoQuery = TRUE;
+ if ( bSorted )
+ rEntry.eOp = SC_LESS_EQUAL;
+ if ( !FillEntry(rEntry) )
+ return;
+ if ( rEntry.bQueryByString )
+ rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
+ if (pMat)
+ {
+ SCSIZE nMatCount = HLookup ? nC : nR;
+ SCSIZE nDelta = SCSIZE_MAX;
+ if (rEntry.bQueryByString)
+ {
+ //!!!!!!!
+ //! TODO: enable regex on matrix strings
+ //!!!!!!!
+ String aParamStr = *rEntry.pStr;
+ if ( bSorted )
+ {
+ static CollatorWrapper* pCollator = ScGlobal::GetCollator();
+ for (SCSIZE i = 0; i < nMatCount; i++)
+ {
+ if (HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i))
+ {
+ sal_Int32 nRes =
+ pCollator->compareString( HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), aParamStr);
+ if (nRes <= 0)
+ nDelta = i;
+ else if (i>0) // #i2168# ignore first mismatch
+ i = nMatCount+1;
+ }
+ else
+ nDelta = i;
+ }
+ }
+ else
+ {
+ for (SCSIZE i = 0; i < nMatCount; i++)
+ {
+ if (HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i))
+ {
+ if ( ScGlobal::GetpTransliteration()->isEqual(
+ HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), aParamStr ) )
+ {
+ nDelta = i;
+ i = nMatCount + 1;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( bSorted )
+ {
+ // #i2168# ignore strings
+ for (SCSIZE i = 0; i < nMatCount; i++)
+ {
+ if (!(HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i)))
+ {
+ if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) <= rEntry.nVal)
+ nDelta = i;
+ else
+ i = nMatCount+1;
+ }
+ }
+ }
+ else
+ {
+ for (SCSIZE i = 0; i < nMatCount; i++)
+ {
+ if (!(HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i)))
+ {
+ if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) == rEntry.nVal)
+ {
+ nDelta = i;
+ i = nMatCount + 1;
+ }
+ }
+ }
+ }
+ }
+ if ( nDelta != SCSIZE_MAX )
+ {
+ SCSIZE nX = static_cast<SCSIZE>(nSpIndex);
+ SCSIZE nY = nDelta;
+ if ( HLookup )
+ {
+ nX = nDelta;
+ nY = static_cast<SCSIZE>(nZIndex);
+ }
+ if ( pMat->IsString( nX, nY) )
+ PushString(pMat->GetString( nX,nY));
+ else
+ PushDouble(pMat->GetDouble( nX,nY));
+ }
+ else
+ PushNA();
+ }
+ else
+ {
+ rEntry.nField = nCol1;
+ BOOL bFound = FALSE;
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+ if ( bSorted )
+ rEntry.eOp = SC_LESS_EQUAL;
+ if ( HLookup )
+ {
+ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
+ // advance Entry.nField in Iterator upon switching columns
+ aCellIter.SetAdvanceQueryParamEntryField( TRUE );
+ if ( bSorted )
+ {
+ SCROW nRow1_temp;
+ bFound = aCellIter.FindEqualOrSortedLastInRange( nCol, nRow1_temp );
+ }
+ else if ( aCellIter.GetFirst() )
+ {
+ bFound = TRUE;
+ nCol = aCellIter.GetCol();
+ }
+ nRow = nZIndex;
+ } // if ( HLookup )
+ else
+ {
+ ScAddress aResultPos( nCol1, nRow1, nTab1);
+ bFound = LookupQueryWithCache( aResultPos, rParam);
+ nRow = aResultPos.Row();
+ nCol = nSpIndex;
+ }
+ if ( bFound )
+ {
+ ScAddress aAdr( nCol, nRow, nTab1 );
+ PushCellResultToken( true, aAdr, NULL, NULL);
+ }
+ else
+ PushNA();
+ }
+ }
+ else
+ PushIllegalParameter();
+ }
+}
+
+bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::FillEntry" );
+ switch ( GetStackType() )
+ {
+ case svDouble:
+ {
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = GetDouble();
+ }
+ break;
+ case svString:
+ {
+ const String sStr = GetString();
+ rEntry.bQueryByString = TRUE;
+ *rEntry.pStr = sStr;
+ }
+ break;
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ PushInt(0);
+ return false;
+ }
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = GetCellValue( aAdr, pCell );
+ }
+ else
+ {
+ if ( GetCellType( pCell ) == CELLTYPE_NOTE )
+ {
+ rEntry.bQueryByString = FALSE;
+ rEntry.nVal = 0.0;
+ }
+ else
+ {
+ String sStr;
+ GetCellString(sStr, pCell);
+ rEntry.bQueryByString = TRUE;
+ *rEntry.pStr = sStr;
+ }
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ const ScMatValType nType = GetDoubleOrStringFromMatrix(rEntry.nVal, *rEntry.pStr);
+ rEntry.bQueryByString = ScMatrix::IsNonValueType( nType);
+ }
+ break;
+ default:
+ {
+ PushIllegalParameter();
+ return false;
+ }
+ } // switch ( GetStackType() )
+ return true;
+}
+void ScInterpreter::ScVLookup()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVLookup" );
+ CalculateLookup(FALSE);
+}
+
+#if defined(WIN) && defined(MSC)
+#pragma optimize("",off)
+#endif
+
+void ScInterpreter::ScSubTotal()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSubTotal" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCountMin( nParamCount, 2 ) )
+ {
+ // We must fish the 1st parameter deep from the stack! And push it on top.
+ const FormulaToken* p = pStack[ sp - nParamCount ];
+ PushTempToken( *p );
+ int nFunc = (int) ::rtl::math::approxFloor( GetDouble() );
+ if( nFunc < 1 || nFunc > 11 )
+ PushIllegalArgument(); // simulate return on stack, not SetError(...)
+ else
+ {
+ cPar = nParamCount - 1;
+ glSubTotal = TRUE;
+ switch( nFunc )
+ {
+ case SUBTOTAL_FUNC_AVE : ScAverage(); break;
+ case SUBTOTAL_FUNC_CNT : ScCount(); break;
+ case SUBTOTAL_FUNC_CNT2 : ScCount2(); break;
+ case SUBTOTAL_FUNC_MAX : ScMax(); break;
+ case SUBTOTAL_FUNC_MIN : ScMin(); break;
+ case SUBTOTAL_FUNC_PROD : ScProduct(); break;
+ case SUBTOTAL_FUNC_STD : ScStDev(); break;
+ case SUBTOTAL_FUNC_STDP : ScStDevP(); break;
+ case SUBTOTAL_FUNC_SUM : ScSum(); break;
+ case SUBTOTAL_FUNC_VAR : ScVar(); break;
+ case SUBTOTAL_FUNC_VARP : ScVarP(); break;
+ default : PushIllegalArgument(); break;
+ }
+ glSubTotal = FALSE;
+ }
+ // Get rid of the 1st (fished) parameter.
+ double nVal = GetDouble();
+ Pop();
+ PushDouble( nVal );
+ }
+}
+#if defined(WIN) && defined(MSC)
+#pragma optimize("",on)
+#endif
+
+
+ScDBQueryParamBase* ScInterpreter::GetDBParams( BOOL& rMissingField )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDBParams" );
+ BOOL bAllowMissingField = FALSE;
+ if ( rMissingField )
+ {
+ bAllowMissingField = TRUE;
+ rMissingField = FALSE;
+ }
+ if ( GetByte() == 3 )
+ {
+ // First, get the query criteria range.
+ ::std::auto_ptr<ScDBRangeBase> pQueryRef( PopDoubleRef() );
+ if (!pQueryRef.get())
+ return NULL;
+
+ BOOL bByVal = TRUE;
+ double nVal = 0.0;
+ String aStr;
+ ScRange aMissingRange;
+ BOOL bRangeFake = FALSE;
+ switch (GetStackType())
+ {
+ case svDouble :
+ nVal = ::rtl::math::approxFloor( GetDouble() );
+ if ( bAllowMissingField && nVal == 0.0 )
+ rMissingField = TRUE; // fake missing parameter
+ break;
+ case svString :
+ bByVal = FALSE;
+ aStr = GetString();
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ nVal = GetCellValue( aAdr, pCell );
+ else
+ {
+ bByVal = FALSE;
+ GetCellString(aStr, pCell);
+ }
+ }
+ break;
+ case svDoubleRef :
+ if ( bAllowMissingField )
+ { // fake missing parameter for old SO compatibility
+ bRangeFake = TRUE;
+ PopDoubleRef( aMissingRange );
+ }
+ else
+ {
+ PopError();
+ SetError( errIllegalParameter );
+ }
+ break;
+ case svMissing :
+ PopError();
+ if ( bAllowMissingField )
+ rMissingField = TRUE;
+ else
+ SetError( errIllegalParameter );
+ break;
+ default:
+ PopError();
+ SetError( errIllegalParameter );
+ }
+
+ auto_ptr<ScDBRangeBase> pDBRef( PopDoubleRef() );
+
+ if (nGlobalError || !pDBRef.get())
+ return NULL;
+
+ if ( bRangeFake )
+ {
+ // range parameter must match entire database range
+ if (pDBRef->isRangeEqual(aMissingRange))
+ rMissingField = TRUE;
+ else
+ SetError( errIllegalParameter );
+ }
+
+ if (nGlobalError)
+ return NULL;
+
+ SCCOL nField = pDBRef->getFirstFieldColumn();
+ if (rMissingField)
+ ; // special case
+ else if (bByVal)
+ nField = pDBRef->findFieldColumn(static_cast<SCCOL>(nVal));
+ else
+ {
+ sal_uInt16 nErr = 0;
+ nField = pDBRef->findFieldColumn(aStr, &nErr);
+ SetError(nErr);
+ }
+
+ if (!ValidCol(nField))
+ return NULL;
+
+ auto_ptr<ScDBQueryParamBase> pParam( pDBRef->createQueryParam(pQueryRef.get()) );
+
+ if (pParam.get())
+ {
+ // An allowed missing field parameter sets the result field
+ // to any of the query fields, just to be able to return
+ // some cell from the iterator.
+ if ( rMissingField )
+ nField = static_cast<SCCOL>(pParam->GetEntry(0).nField);
+ pParam->mnField = nField;
+
+ SCSIZE nCount = pParam->GetEntryCount();
+ for ( SCSIZE i=0; i < nCount; i++ )
+ {
+ ScQueryEntry& rEntry = pParam->GetEntry(i);
+ if ( rEntry.bDoQuery )
+ {
+ sal_uInt32 nIndex = 0;
+ rEntry.bQueryByString = !pFormatter->IsNumberFormat(
+ *rEntry.pStr, nIndex, rEntry.nVal );
+ if ( rEntry.bQueryByString && !pParam->bRegExp )
+ pParam->bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
+ }
+ else
+ break; // for
+ }
+ return pParam.release();
+ }
+ }
+ return false;
+}
+
+
+void ScInterpreter::DBIterator( ScIterFunc eFunc )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DBIterator" );
+ double nErg = 0.0;
+ double fMem = 0.0;
+ BOOL bNull = TRUE;
+ ULONG nCount = 0;
+ BOOL bMissingField = FALSE;
+ auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
+ if (pQueryParam.get())
+ {
+ ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator::Value aValue;
+ if ( aValIter.GetFirst(aValue) && !aValue.mnError )
+ {
+ switch( eFunc )
+ {
+ case ifPRODUCT: nErg = 1; break;
+ case ifMAX: nErg = -MAXDOUBLE; break;
+ case ifMIN: nErg = MAXDOUBLE; break;
+ default: ; // nothing
+ }
+ do
+ {
+ nCount++;
+ switch( eFunc )
+ {
+ case ifAVERAGE:
+ case ifSUM:
+ if ( bNull && aValue.mfValue != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = aValue.mfValue;
+ }
+ else
+ nErg += aValue.mfValue;
+ break;
+ case ifSUMSQ: nErg += aValue.mfValue * aValue.mfValue; break;
+ case ifPRODUCT: nErg *= aValue.mfValue; break;
+ case ifMAX: if( aValue.mfValue > nErg ) nErg = aValue.mfValue; break;
+ case ifMIN: if( aValue.mfValue < nErg ) nErg = aValue.mfValue; break;
+ default: ; // nothing
+ }
+ }
+ while ( aValIter.GetNext(aValue) && !aValue.mnError );
+ }
+ SetError(aValue.mnError);
+ }
+ else
+ SetError( errIllegalParameter);
+ switch( eFunc )
+ {
+ case ifCOUNT: nErg = nCount; break;
+ case ifSUM: nErg = ::rtl::math::approxAdd( nErg, fMem ); break;
+ case ifAVERAGE: nErg = ::rtl::math::approxAdd( nErg, fMem ) / nCount; break;
+ default: ; // nothing
+ }
+ PushDouble( nErg );
+}
+
+
+void ScInterpreter::ScDBSum()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBSum" );
+ DBIterator( ifSUM );
+}
+
+
+void ScInterpreter::ScDBCount()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBCount" );
+ BOOL bMissingField = TRUE;
+ auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
+ if (pQueryParam.get())
+ {
+ ULONG nCount = 0;
+ if ( bMissingField && pQueryParam->GetType() == ScDBQueryParamBase::INTERNAL )
+ { // count all matching records
+ // TODO: currently the QueryIterators only return cell pointers of
+ // existing cells, so if a query matches an empty cell there's
+ // nothing returned, and therefor not counted!
+ // Since this has ever been the case and this code here only came
+ // into existance to fix #i6899 and it never worked before we'll
+ // have to live with it until we reimplement the iterators to also
+ // return empty cells, which would mean to adapt all callers of
+ // iterators.
+ ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pQueryParam.get());
+ SCTAB nTab = p->nTab;
+ // ScQueryCellIterator doesn't make use of ScDBQueryParamBase::mnField,
+ // so the source range has to be restricted, like before the introduction
+ // of ScDBQueryParamBase.
+ p->nCol1 = p->nCol2 = p->mnField;
+ ScQueryCellIterator aCellIter( pDok, nTab, *p);
+ if ( aCellIter.GetFirst() )
+ {
+ do
+ {
+ nCount++;
+ } while ( aCellIter.GetNext() );
+ }
+ }
+ else
+ { // count only matching records with a value in the "result" field
+ ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
+ ScDBQueryDataIterator::Value aValue;
+ if ( aValIter.GetFirst(aValue) && !aValue.mnError )
+ {
+ do
+ {
+ nCount++;
+ }
+ while ( aValIter.GetNext(aValue) && !aValue.mnError );
+ }
+ SetError(aValue.mnError);
+ }
+ PushDouble( nCount );
+ }
+ else
+ PushIllegalParameter();
+}
+
+
+void ScInterpreter::ScDBCount2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBCount2" );
+ BOOL bMissingField = TRUE;
+ auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
+ if (pQueryParam.get())
+ {
+ ULONG nCount = 0;
+ pQueryParam->mbSkipString = false;
+ ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
+ ScDBQueryDataIterator::Value aValue;
+ if ( aValIter.GetFirst(aValue) && !aValue.mnError )
+ {
+ do
+ {
+ nCount++;
+ }
+ while ( aValIter.GetNext(aValue) && !aValue.mnError );
+ }
+ SetError(aValue.mnError);
+ PushDouble( nCount );
+ }
+ else
+ PushIllegalParameter();
+}
+
+
+void ScInterpreter::ScDBAverage()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBAverage" );
+ DBIterator( ifAVERAGE );
+}
+
+
+void ScInterpreter::ScDBMax()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBMax" );
+ DBIterator( ifMAX );
+}
+
+
+void ScInterpreter::ScDBMin()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBMin" );
+ DBIterator( ifMIN );
+}
+
+
+void ScInterpreter::ScDBProduct()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBProduct" );
+ DBIterator( ifPRODUCT );
+}
+
+
+void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDBStVarParams" );
+ std::vector<double> values;
+ double vSum = 0.0;
+ double vMean = 0.0;
+
+ rValCount = 0.0;
+ double fSum = 0.0;
+ BOOL bMissingField = FALSE;
+ auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
+ if (pQueryParam.get())
+ {
+ ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator::Value aValue;
+ if (aValIter.GetFirst(aValue) && !aValue.mnError)
+ {
+ do
+ {
+ rValCount++;
+ values.push_back(aValue.mfValue);
+ fSum += aValue.mfValue;
+ }
+ while ((aValue.mnError == 0) && aValIter.GetNext(aValue));
+ }
+ SetError(aValue.mnError);
+ }
+ else
+ SetError( errIllegalParameter);
+
+ vMean = fSum / values.size();
+
+ for (size_t i = 0; i < values.size(); i++)
+ vSum += (values[i] - vMean) * (values[i] - vMean);
+
+ rVal = vSum;
+}
+
+
+void ScInterpreter::ScDBStdDev()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBStdDev" );
+ double fVal, fCount;
+ GetDBStVarParams( fVal, fCount );
+ PushDouble( sqrt(fVal/(fCount-1)));
+}
+
+
+void ScInterpreter::ScDBStdDevP()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBStdDevP" );
+ double fVal, fCount;
+ GetDBStVarParams( fVal, fCount );
+ PushDouble( sqrt(fVal/fCount));
+}
+
+
+void ScInterpreter::ScDBVar()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBVar" );
+ double fVal, fCount;
+ GetDBStVarParams( fVal, fCount );
+ PushDouble(fVal/(fCount-1));
+}
+
+
+void ScInterpreter::ScDBVarP()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBVarP" );
+ double fVal, fCount;
+ GetDBStVarParams( fVal, fCount );
+ PushDouble(fVal/fCount);
+}
+
+
+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", "er", "ScInterpreter::ScIndirect" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ bool bTryXlA1 = true; // whether to try XL_A1 style as well.
+ FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;
+ if (nParamCount == 2 && 0.0 == ::rtl::math::approxFloor( GetDouble()))
+ {
+ eConv = FormulaGrammar::CONV_XL_R1C1;
+ bTryXlA1 = false;
+ }
+ const ScAddress::Details aDetails( eConv, aPos );
+ const ScAddress::Details aDetailsXlA1( FormulaGrammar::CONV_XL_A1, aPos );
+ SCTAB nTab = aPos.Tab();
+ String sRefStr( GetString() );
+ ScRefAddress aRefAd, aRefAd2;
+ ScAddress::ExternalInfo aExtInfo;
+ if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2, aDetails, &aExtInfo) ||
+ (bTryXlA1 && ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd,
+ 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, &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
+ {
+ ScRangeName* pNames = pDok->GetRangeName();
+ if (!pNames)
+ break;
+
+ USHORT nPos = 0;
+ if (!pNames->SearchName( sRefStr, nPos))
+ break;
+
+ ScRangeData* rData = (*pNames)[nPos];
+ if (!rData)
+ break;
+
+ // We need this in order to obtain a good range.
+ rData->ValidateTabRefs();
+
+ ScRange aRange;
+#if 0
+ // This is some really odd Excel behavior and renders named
+ // ranges containing relative references totally useless.
+ if (!rData->IsReference(aRange, ScAddress( aPos.Tab(), 0, 0)))
+ break;
+#else
+ // This is the usual way to treat named ranges containing
+ // relative references.
+ if (!rData->IsReference( aRange, aPos))
+ break;
+#endif
+
+ if (aRange.aStart == aRange.aEnd)
+ PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab());
+ else
+ PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), aRange.aEnd.Col(),
+ aRange.aEnd.Row(), aRange.aEnd.Tab());
+
+ // success!
+ return;
+ }
+ while (false);
+
+ PushIllegalArgument();
+ }
+ }
+}
+
+
+void ScInterpreter::ScAddressFunc()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAddressFunc" );
+ String sTabStr;
+
+ BYTE nParamCount = GetByte();
+ if( !MustHaveParamCount( nParamCount, 2, 5 ) )
+ return;
+
+ if( nParamCount >= 5 )
+ sTabStr = GetString();
+
+ FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO; // default
+ if( nParamCount >= 4 && 0.0 == ::rtl::math::approxFloor( GetDoubleWithDefault( 1.0)))
+ eConv = FormulaGrammar::CONV_XL_R1C1;
+
+ USHORT nFlags = SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE; // default
+ if( nParamCount >= 3 )
+ {
+ USHORT n = (USHORT) ::rtl::math::approxFloor( GetDoubleWithDefault( 1.0));
+ switch ( n )
+ {
+ default :
+ PushNoValue();
+ return;
+
+ case 5:
+ case 1 : break; // default
+ case 6:
+ case 2 : nFlags = SCA_ROW_ABSOLUTE; break;
+ case 7:
+ case 3 : nFlags = SCA_COL_ABSOLUTE; break;
+ case 8:
+ case 4 : nFlags = 0; break; // both relative
+ }
+ }
+ nFlags |= SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
+
+ SCCOL nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
+ SCROW nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
+ if( eConv == FormulaGrammar::CONV_XL_R1C1 )
+ {
+ // YUCK! The XL interface actually treats rel R1C1 refs differently
+ // than A1
+ if( !(nFlags & SCA_COL_ABSOLUTE) )
+ nCol += aPos.Col() + 1;
+ if( !(nFlags & SCA_ROW_ABSOLUTE) )
+ nRow += aPos.Row() + 1;
+ }
+
+ --nCol;
+ --nRow;
+ if(!ValidCol( nCol) || !ValidRow( nRow))
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ String aRefStr;
+ const ScAddress::Details aDetails( eConv, aPos );
+ const ScAddress aAdr( nCol, nRow, 0);
+ aAdr.Format( aRefStr, nFlags, pDok, aDetails );
+
+ if( nParamCount >= 5 )
+ {
+ ScCompiler::CheckTabQuotes( sTabStr, eConv);
+ sTabStr += static_cast<sal_Unicode>(eConv == FormulaGrammar::CONV_XL_R1C1 ? '!' : '.');
+ sTabStr += aRefStr;
+ PushString( sTabStr );
+ }
+ else
+ PushString( aRefStr );
+}
+
+
+void ScInterpreter::ScOffset()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOffset" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 3, 5 ) )
+ {
+ long nColNew = -1, nRowNew = -1, nColPlus, nRowPlus;
+ if (nParamCount == 5)
+ nColNew = (long) ::rtl::math::approxFloor(GetDouble());
+ if (nParamCount >= 4)
+ nRowNew = (long) ::rtl::math::approxFloor(GetDoubleWithDefault( -1.0 ));
+ nColPlus = (long) ::rtl::math::approxFloor(GetDouble());
+ nRowPlus = (long) ::rtl::math::approxFloor(GetDouble());
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ if (nColNew == 0 || nRowNew == 0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (GetStackType() == svSingleRef)
+ {
+ PopSingleRef(nCol1, nRow1, nTab1);
+ if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
+ {
+ nCol1 = (SCCOL)((long) nCol1 + nColPlus);
+ nRow1 = (SCROW)((long) nRow1 + nRowPlus);
+ if (!ValidCol(nCol1) || !ValidRow(nRow1))
+ PushIllegalArgument();
+ else
+ PushSingleRef(nCol1, nRow1, nTab1);
+ }
+ else
+ {
+ if (nColNew < 0)
+ nColNew = 1;
+ if (nRowNew < 0)
+ nRowNew = 1;
+ nCol1 = (SCCOL)((long)nCol1+nColPlus); // ! nCol1 wird veraendert!
+ nRow1 = (SCROW)((long)nRow1+nRowPlus);
+ nCol2 = (SCCOL)((long)nCol1+nColNew-1);
+ nRow2 = (SCROW)((long)nRow1+nRowNew-1);
+ if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
+ !ValidCol(nCol2) || !ValidRow(nRow2))
+ PushIllegalArgument();
+ else
+ PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
+ }
+ }
+ else if (GetStackType() == svDoubleRef)
+ {
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (nColNew < 0)
+ nColNew = nCol2 - nCol1 + 1;
+ if (nRowNew < 0)
+ nRowNew = nRow2 - nRow1 + 1;
+ nCol1 = (SCCOL)((long)nCol1+nColPlus);
+ nRow1 = (SCROW)((long)nRow1+nRowPlus);
+ nCol2 = (SCCOL)((long)nCol1+nColNew-1);
+ nRow2 = (SCROW)((long)nRow1+nRowNew-1);
+ if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
+ !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
+ PushIllegalArgument();
+ else
+ PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
+ }
+ else
+ PushIllegalParameter();
+ }
+}
+
+
+void ScInterpreter::ScIndex()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIndex" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 4 ) )
+ {
+ long nArea;
+ size_t nAreaCount;
+ SCCOL nCol;
+ SCROW nRow;
+ if (nParamCount == 4)
+ nArea = (long) ::rtl::math::approxFloor(GetDouble());
+ else
+ nArea = 1;
+ if (nParamCount >= 3)
+ nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
+ else
+ nCol = 0;
+ if (nParamCount >= 2)
+ nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
+ else
+ nRow = 0;
+ if (GetStackType() == svRefList)
+ nAreaCount = (sp ? static_cast<ScToken*>(pStack[sp-1])->GetRefList()->size() : 0);
+ else
+ nAreaCount = 1; // one reference or array or whatever
+ if (nAreaCount == 0 || (size_t)nArea > nAreaCount)
+ {
+ PushError( errNoRef);
+ return;
+ }
+ else if (nArea < 1 || nCol < 0 || nRow < 0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ switch (GetStackType())
+ {
+ case svMatrix:
+ {
+ if (nArea != 1)
+ SetError(errIllegalArgument);
+ USHORT nOldSp = sp;
+ ScMatrixRef pMat = GetMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ // Access one element of a vector independent of col/row
+ // orientation?
+ bool bVector = ((nCol == 0 || nRow == 0) && (nC == 1 || nR == 1));
+ SCSIZE nElement = ::std::max( static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow));
+ if (nC == 0 || nR == 0 ||
+ (!bVector && (static_cast<SCSIZE>(nCol) > nC ||
+ static_cast<SCSIZE>(nRow) > nR)) ||
+ (bVector && nElement > nC * nR))
+ PushIllegalArgument();
+ else if (nCol == 0 && nRow == 0)
+ sp = nOldSp;
+ else if (bVector)
+ {
+ --nElement;
+ if (pMat->IsString( nElement))
+ PushString( pMat->GetString( nElement));
+ else
+ PushDouble( pMat->GetDouble( nElement));
+ }
+ else if (nCol == 0)
+ {
+ ScMatrixRef pResMat = GetNewMat(nC, 1);
+ if (pResMat)
+ {
+ SCSIZE nRowMinus1 = static_cast<SCSIZE>(nRow - 1);
+ for (SCSIZE i = 0; i < nC; i++)
+ if (!pMat->IsString(i, nRowMinus1))
+ pResMat->PutDouble(pMat->GetDouble(i,
+ nRowMinus1), i, 0);
+ else
+ pResMat->PutString(pMat->GetString(i,
+ nRowMinus1), i, 0);
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else if (nRow == 0)
+ {
+ ScMatrixRef pResMat = GetNewMat(1, nR);
+ if (pResMat)
+ {
+ SCSIZE nColMinus1 = static_cast<SCSIZE>(nCol - 1);
+ for (SCSIZE i = 0; i < nR; i++)
+ if (!pMat->IsString(nColMinus1, i))
+ pResMat->PutDouble(pMat->GetDouble(nColMinus1,
+ i), i);
+ else
+ pResMat->PutString(pMat->GetString(nColMinus1,
+ i), i);
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ {
+ if (!pMat->IsString( static_cast<SCSIZE>(nCol-1),
+ static_cast<SCSIZE>(nRow-1)))
+ PushDouble( pMat->GetDouble(
+ static_cast<SCSIZE>(nCol-1),
+ static_cast<SCSIZE>(nRow-1)));
+ else
+ PushString( pMat->GetString(
+ static_cast<SCSIZE>(nCol-1),
+ static_cast<SCSIZE>(nRow-1)));
+ }
+ }
+ }
+ break;
+ case svSingleRef:
+ {
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ PopSingleRef( nCol1, nRow1, nTab1);
+ if (nCol > 1 || nRow > 1)
+ PushIllegalArgument();
+ else
+ PushSingleRef( nCol1, nRow1, nTab1);
+ }
+ break;
+ case svDoubleRef:
+ case svRefList:
+ {
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ SCCOL nCol2 = 0;
+ SCROW nRow2 = 0;
+ SCTAB nTab2 = 0;
+ BOOL bRowArray = FALSE;
+ if (GetStackType() == svRefList)
+ {
+ FormulaTokenRef xRef = PopToken();
+ if (nGlobalError || !xRef)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ ScRange aRange( ScAddress::UNINITIALIZED);
+ DoubleRefToRange( (*(static_cast<ScToken*>(xRef.get())->GetRefList()))[nArea-1], aRange);
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if ( nParamCount == 2 && nRow1 == nRow2 )
+ bRowArray = TRUE;
+ }
+ else
+ {
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if ( nParamCount == 2 && nRow1 == nRow2 )
+ bRowArray = TRUE;
+ }
+ if ( nTab1 != nTab2 ||
+ (nCol > 0 && nCol1+nCol-1 > nCol2) ||
+ (nRow > 0 && nRow1+nRow-1 > nRow2 && !bRowArray ) ||
+ ( nRow > nCol2 - nCol1 + 1 && bRowArray ))
+ PushIllegalArgument();
+ else if (nCol == 0 && nRow == 0)
+ {
+ if ( nCol1 == nCol2 && nRow1 == nRow2 )
+ PushSingleRef( nCol1, nRow1, nTab1 );
+ else
+ PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab1 );
+ }
+ else if (nRow == 0)
+ {
+ if ( nRow1 == nRow2 )
+ PushSingleRef( nCol1+nCol-1, nRow1, nTab1 );
+ else
+ PushDoubleRef( nCol1+nCol-1, nRow1, nTab1,
+ nCol1+nCol-1, nRow2, nTab1 );
+ }
+ else if (nCol == 0)
+ {
+ if ( nCol1 == nCol2 )
+ PushSingleRef( nCol1, nRow1+nRow-1, nTab1 );
+ else if ( bRowArray )
+ {
+ nCol =(SCCOL) nRow;
+ nRow = 1;
+ PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1);
+ }
+ else
+ PushDoubleRef( nCol1, nRow1+nRow-1, nTab1,
+ nCol2, nRow1+nRow-1, nTab1);
+ }
+ else
+ PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1);
+ }
+ break;
+ default:
+ PushIllegalParameter();
+ }
+ }
+}
+
+
+void ScInterpreter::ScMultiArea()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMultiArea" );
+ // Legacy support, convert to RefList
+ BYTE nParamCount = GetByte();
+ if (MustHaveParamCountMin( nParamCount, 1))
+ {
+ while (!nGlobalError && nParamCount-- > 1)
+ {
+ ScUnionFunc();
+ }
+ }
+}
+
+
+void ScInterpreter::ScAreas()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAreas" );
+ BYTE nParamCount = GetByte();
+ if (MustHaveParamCount( nParamCount, 1))
+ {
+ size_t nCount = 0;
+ switch (GetStackType())
+ {
+ case svSingleRef:
+ {
+ FormulaTokenRef xT = PopToken();
+ ValidateRef( static_cast<ScToken*>(xT.get())->GetSingleRef());
+ ++nCount;
+ }
+ break;
+ case svDoubleRef:
+ {
+ FormulaTokenRef xT = PopToken();
+ ValidateRef( static_cast<ScToken*>(xT.get())->GetDoubleRef());
+ ++nCount;
+ }
+ break;
+ case svRefList:
+ {
+ FormulaTokenRef xT = PopToken();
+ ValidateRef( *(static_cast<ScToken*>(xT.get())->GetRefList()));
+ nCount += static_cast<ScToken*>(xT.get())->GetRefList()->size();
+ }
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ PushDouble( double(nCount));
+ }
+}
+
+
+void ScInterpreter::ScCurrency()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCurrency" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ String aStr;
+ double fDec;
+ if (nParamCount == 2)
+ {
+ fDec = ::rtl::math::approxFloor(GetDouble());
+ if (fDec < -15.0 || fDec > 15.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ else
+ fDec = 2.0;
+ double fVal = GetDouble();
+ double fFac;
+ if ( fDec != 0.0 )
+ fFac = pow( (double)10, fDec );
+ else
+ fFac = 1.0;
+ if (fVal < 0.0)
+ fVal = ceil(fVal*fFac-0.5)/fFac;
+ else
+ fVal = floor(fVal*fFac+0.5)/fFac;
+ Color* pColor = NULL;
+ if ( fDec < 0.0 )
+ fDec = 0.0;
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_CURRENCY,
+ ScGlobal::eLnge);
+ if ( (USHORT) fDec != pFormatter->GetFormatPrecision( nIndex ) )
+ {
+ String sFormatString;
+ pFormatter->GenerateFormat(sFormatString,
+ nIndex,
+ ScGlobal::eLnge,
+ TRUE, // mit Tausenderpunkt
+ FALSE, // nicht rot
+ (USHORT) fDec,// Nachkommastellen
+ 1); // 1 Vorkommanull
+ if (!pFormatter->GetPreviewString(sFormatString,
+ fVal,
+ aStr,
+ &pColor,
+ ScGlobal::eLnge))
+ SetError(errIllegalArgument);
+ }
+ else
+ {
+ pFormatter->GetOutputString(fVal, nIndex, aStr, &pColor);
+ }
+ PushString(aStr);
+ }
+}
+
+
+void ScInterpreter::ScReplace()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScReplace" );
+ if ( MustHaveParamCount( GetByte(), 4 ) )
+ {
+ String aNewStr( GetString() );
+ double fCount = ::rtl::math::approxFloor( GetDouble());
+ double fPos = ::rtl::math::approxFloor( GetDouble());
+ String aOldStr( GetString() );
+ if (fPos < 1.0 || fPos > static_cast<double>(STRING_MAXLEN)
+ || fCount < 0.0 || fCount > static_cast<double>(STRING_MAXLEN))
+ PushIllegalArgument();
+ else
+ {
+ xub_StrLen nCount = static_cast<xub_StrLen>(fCount);
+ xub_StrLen nPos = static_cast<xub_StrLen>(fPos);
+ xub_StrLen nLen = aOldStr.Len();
+ if (nPos > nLen + 1)
+ nPos = nLen + 1;
+ if (nCount > nLen - nPos + 1)
+ nCount = nLen - nPos + 1;
+ aOldStr.Erase( nPos-1, nCount );
+ if ( CheckStringResultLen( aOldStr, aNewStr ) )
+ aOldStr.Insert( aNewStr, nPos-1 );
+ PushString( aOldStr );
+ }
+ }
+}
+
+
+void ScInterpreter::ScFixed()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFixed" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 3 ) )
+ {
+ String aStr;
+ double fDec;
+ BOOL bThousand;
+ if (nParamCount == 3)
+ bThousand = !GetBool(); // Param TRUE: keine Tausenderpunkte
+ else
+ bThousand = TRUE;
+ if (nParamCount >= 2)
+ {
+ fDec = ::rtl::math::approxFloor(GetDoubleWithDefault( 2.0 ));
+ if (fDec < -15.0 || fDec > 15.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ else
+ fDec = 2.0;
+ double fVal = GetDouble();
+ double fFac;
+ if ( fDec != 0.0 )
+ fFac = pow( (double)10, fDec );
+ else
+ fFac = 1.0;
+ if (fVal < 0.0)
+ fVal = ceil(fVal*fFac-0.5)/fFac;
+ else
+ fVal = floor(fVal*fFac+0.5)/fFac;
+ Color* pColor = NULL;
+ String sFormatString;
+ if (fDec < 0.0)
+ fDec = 0.0;
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ pFormatter->GenerateFormat(sFormatString,
+ nIndex,
+ ScGlobal::eLnge,
+ bThousand, // mit Tausenderpunkt
+ FALSE, // nicht rot
+ (USHORT) fDec,// Nachkommastellen
+ 1); // 1 Vorkommanull
+ if (!pFormatter->GetPreviewString(sFormatString,
+ fVal,
+ aStr,
+ &pColor,
+ ScGlobal::eLnge))
+ PushIllegalArgument();
+ else
+ PushString(aStr);
+ }
+}
+
+
+void ScInterpreter::ScFind()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFind" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ double fAnz;
+ if (nParamCount == 3)
+ fAnz = GetDouble();
+ else
+ fAnz = 1.0;
+ String sStr = GetString();
+ if( fAnz < 1.0 || fAnz > (double) sStr.Len() )
+ PushNoValue();
+ else
+ {
+ xub_StrLen nPos = sStr.Search( GetString(), (xub_StrLen) fAnz - 1 );
+ if (nPos == STRING_NOTFOUND)
+ PushNoValue();
+ else
+ PushDouble((double)(nPos + 1));
+ }
+ }
+}
+
+
+void ScInterpreter::ScExact()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExact" );
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ String s1( GetString() );
+ String s2( GetString() );
+ PushInt( s1 == s2 );
+ }
+}
+
+
+void ScInterpreter::ScLeft()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLeft" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ xub_StrLen n;
+ if (nParamCount == 2)
+ {
+ double nVal = ::rtl::math::approxFloor(GetDouble());
+ if ( nVal < 0.0 || nVal > STRING_MAXLEN )
+ {
+ PushIllegalArgument();
+ return ;
+ }
+ else
+ n = (xub_StrLen) nVal;
+ }
+ else
+ n = 1;
+ String aStr( GetString() );
+ aStr.Erase( n );
+ PushString( aStr );
+ }
+}
+
+
+void ScInterpreter::ScRight()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRight" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ xub_StrLen n;
+ if (nParamCount == 2)
+ {
+ double nVal = ::rtl::math::approxFloor(GetDouble());
+ if ( nVal < 0.0 || nVal > STRING_MAXLEN )
+ {
+ PushIllegalArgument();
+ return ;
+ }
+ else
+ n = (xub_StrLen) nVal;
+ }
+ else
+ n = 1;
+ String aStr( GetString() );
+ if( n < aStr.Len() )
+ aStr.Erase( 0, aStr.Len() - n );
+ PushString( aStr );
+ }
+}
+
+
+void ScInterpreter::ScSearch()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSearch" );
+ double fAnz;
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ if (nParamCount == 3)
+ {
+ fAnz = ::rtl::math::approxFloor(GetDouble());
+ if (fAnz > double(STRING_MAXLEN))
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ else
+ fAnz = 1.0;
+ String sStr = GetString();
+ String SearchStr = GetString();
+ xub_StrLen nPos = (xub_StrLen) fAnz - 1;
+ xub_StrLen nEndPos = sStr.Len();
+ if( nPos >= nEndPos )
+ PushNoValue();
+ else
+ {
+ utl::SearchParam::SearchType eSearchType =
+ (MayBeRegExp( SearchStr, pDok ) ?
+ utl::SearchParam::SRCH_REGEXP : utl::SearchParam::SRCH_NORMAL);
+ utl::SearchParam sPar(SearchStr, eSearchType, FALSE, FALSE, FALSE);
+ utl::TextSearch sT( sPar, *ScGlobal::pCharClass );
+ int nBool = sT.SearchFrwrd(sStr, &nPos, &nEndPos);
+ if (!nBool)
+ PushNoValue();
+ else
+ PushDouble((double)(nPos) + 1);
+ }
+ }
+}
+
+
+void ScInterpreter::ScMid()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMid" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double fAnz = ::rtl::math::approxFloor(GetDouble());
+ double fAnfang = ::rtl::math::approxFloor(GetDouble());
+ const String& rStr = GetString();
+ if (fAnfang < 1.0 || fAnz < 0.0 || fAnfang > double(STRING_MAXLEN) || fAnz > double(STRING_MAXLEN))
+ PushIllegalArgument();
+ else
+ PushString(rStr.Copy( (xub_StrLen) fAnfang - 1, (xub_StrLen) fAnz ));
+ }
+}
+
+
+void ScInterpreter::ScText()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScText" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ String sFormatString = GetString();
+ String aStr;
+ bool bString = false;
+ double fVal = 0.0;
+ switch (GetStackType())
+ {
+ case svError:
+ PopError();
+ break;
+ case svDouble:
+ fVal = PopDouble();
+ break;
+ default:
+ {
+ FormulaTokenRef xTok( PopToken());
+ if (!nGlobalError)
+ {
+ PushTempToken( xTok);
+ // Temporarily override the ConvertStringToValue()
+ // error for GetCellValue() / GetCellValueOrZero()
+ USHORT nSErr = mnStringNoValueError;
+ mnStringNoValueError = errNotNumericString;
+ fVal = GetDouble();
+ mnStringNoValueError = nSErr;
+ if (nGlobalError == errNotNumericString)
+ {
+ // Not numeric.
+ nGlobalError = 0;
+ PushTempToken( xTok);
+ aStr = GetString();
+ bString = true;
+ }
+ }
+ }
+ }
+ if (nGlobalError)
+ PushError( nGlobalError);
+ else
+ {
+ String aResult;
+ Color* pColor = NULL;
+ LanguageType eCellLang;
+ const ScPatternAttr* pPattern = pDok->GetPattern(
+ aPos.Col(), aPos.Row(), aPos.Tab() );
+ if ( pPattern )
+ eCellLang = ((const SvxLanguageItem&)
+ pPattern->GetItem( ATTR_LANGUAGE_FORMAT )).GetValue();
+ else
+ eCellLang = ScGlobal::eLnge;
+ if (bString)
+ {
+ if (!pFormatter->GetPreviewString( sFormatString, aStr,
+ aResult, &pColor, eCellLang))
+ PushIllegalArgument();
+ else
+ PushString( aResult);
+ }
+ else
+ {
+ if (!pFormatter->GetPreviewStringGuess( sFormatString, fVal,
+ aResult, &pColor, eCellLang))
+ PushIllegalArgument();
+ else
+ PushString( aResult);
+ }
+ }
+ }
+}
+
+
+void ScInterpreter::ScSubstitute()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSubstitute" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 3, 4 ) )
+ {
+ xub_StrLen nAnz;
+ if (nParamCount == 4)
+ {
+ double fAnz = ::rtl::math::approxFloor(GetDouble());
+ if( fAnz < 1 || fAnz > STRING_MAXLEN )
+ {
+ PushIllegalArgument();
+ return;
+ }
+ else
+ nAnz = (xub_StrLen) fAnz;
+ }
+ else
+ nAnz = 0;
+ String sNewStr = GetString();
+ String sOldStr = GetString();
+ String sStr = GetString();
+ xub_StrLen nPos = 0;
+ xub_StrLen nCount = 0;
+ xub_StrLen nNewLen = sNewStr.Len();
+ xub_StrLen nOldLen = sOldStr.Len();
+ while( TRUE )
+ {
+ nPos = sStr.Search( sOldStr, nPos );
+ if (nPos != STRING_NOTFOUND)
+ {
+ nCount++;
+ if( !nAnz || nCount == nAnz )
+ {
+ sStr.Erase(nPos,nOldLen);
+ if ( CheckStringResultLen( sStr, sNewStr ) )
+ {
+ sStr.Insert(sNewStr,nPos);
+ nPos = sal::static_int_cast<xub_StrLen>( nPos + nNewLen );
+ }
+ else
+ break;
+ }
+ else
+ nPos++;
+ }
+ else
+ break;
+ }
+ PushString( sStr );
+ }
+}
+
+
+void ScInterpreter::ScRept()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRept" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double fAnz = ::rtl::math::approxFloor(GetDouble());
+ String aStr( GetString() );
+ if ( fAnz < 0.0 )
+ PushIllegalArgument();
+ else if ( fAnz * aStr.Len() > STRING_MAXLEN )
+ {
+ PushError( errStringOverflow );
+ }
+ else if ( fAnz == 0.0 )
+ PushString( EMPTY_STRING );
+ else
+ {
+ xub_StrLen n = (xub_StrLen) fAnz;
+ const xub_StrLen nLen = aStr.Len();
+ String aRes;
+ const sal_Unicode* const pSrc = aStr.GetBuffer();
+ sal_Unicode* pDst = aRes.AllocBuffer( n * nLen );
+ while( n-- )
+ {
+ memcpy( pDst, pSrc, nLen * sizeof(sal_Unicode) );
+ pDst += nLen;
+ }
+ PushString( aRes );
+ }
+ }
+}
+
+
+void ScInterpreter::ScConcat()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScConcat" );
+ BYTE nParamCount = GetByte();
+ String aRes;
+ while( nParamCount-- > 0)
+ {
+ const String& rStr = GetString();
+ aRes.Insert( rStr, 0 );
+ }
+ PushString( aRes );
+}
+
+
+void ScInterpreter::ScErrorType()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScErrorType" );
+ USHORT nErr;
+ USHORT nOldError = nGlobalError;
+ nGlobalError = 0;
+ switch ( GetStackType() )
+ {
+ case svRefList :
+ {
+ FormulaTokenRef x = PopToken();
+ if (nGlobalError)
+ nErr = nGlobalError;
+ else
+ {
+ const ScRefList* pRefList = static_cast<ScToken*>(x.get())->GetRefList();
+ size_t n = pRefList->size();
+ if (!n)
+ nErr = errNoRef;
+ else if (n > 1)
+ nErr = errNoValue;
+ else
+ {
+ ScRange aRange;
+ DoubleRefToRange( (*pRefList)[0], aRange);
+ if (nGlobalError)
+ nErr = nGlobalError;
+ else
+ {
+ ScAddress aAdr;
+ if ( DoubleRefToPosSingleRef( aRange, aAdr ) )
+ nErr = pDok->GetErrCode( aAdr );
+ else
+ nErr = nGlobalError;
+ }
+ }
+ }
+ }
+ break;
+ case svDoubleRef :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if ( nGlobalError )
+ nErr = nGlobalError;
+ else
+ {
+ ScAddress aAdr;
+ if ( DoubleRefToPosSingleRef( aRange, aAdr ) )
+ nErr = pDok->GetErrCode( aAdr );
+ else
+ nErr = nGlobalError;
+ }
+ }
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if ( nGlobalError )
+ nErr = nGlobalError;
+ else
+ nErr = pDok->GetErrCode( aAdr );
+ }
+ break;
+ default:
+ PopError();
+ nErr = nGlobalError;
+ }
+ if ( nErr )
+ {
+ nGlobalError = 0;
+ PushDouble( nErr );
+ }
+ else
+ {
+ nGlobalError = nOldError;
+ PushNA();
+ }
+}
+
+
+BOOL ScInterpreter::MayBeRegExp( const String& rStr, const ScDocument* pDoc )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MayBeRegExp" );
+ if ( pDoc && !pDoc->GetDocOptions().IsFormulaRegexEnabled() )
+ return FALSE;
+ if ( !rStr.Len() || (rStr.Len() == 1 && rStr.GetChar(0) != '.') )
+ return FALSE; // einzelnes Metazeichen kann keine RegExp sein
+ static const sal_Unicode cre[] = { '.','*','+','?','[',']','^','$','\\','<','>','(',')','|', 0 };
+ const sal_Unicode* p1 = rStr.GetBuffer();
+ sal_Unicode c1;
+ while ( ( c1 = *p1++ ) != 0 )
+ {
+ const sal_Unicode* p2 = cre;
+ while ( *p2 )
+ {
+ if ( c1 == *p2++ )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc,
+ const ScQueryParam & rParam, const ScQueryEntry & rEntry )
+{
+ bool bFound = false;
+ ScQueryCellIterator aCellIter( pDoc, rParam.nTab, rParam, FALSE);
+ if (rEntry.eOp != SC_EQUAL)
+ {
+ // range lookup <= or >=
+ SCCOL nCol;
+ SCROW nRow;
+ bFound = aCellIter.FindEqualOrSortedLastInRange( nCol, nRow);
+ if (bFound)
+ {
+ o_rResultPos.SetCol( nCol);
+ o_rResultPos.SetRow( nRow);
+ }
+ }
+ else if (aCellIter.GetFirst())
+ {
+ // EQUAL
+ bFound = true;
+ o_rResultPos.SetCol( aCellIter.GetCol());
+ o_rResultPos.SetRow( aCellIter.GetRow());
+ }
+ return bFound;
+}
+
+#define erDEBUG_LOOKUPCACHE 0
+#if erDEBUG_LOOKUPCACHE
+#include <cstdio>
+using ::std::fprintf;
+using ::std::fflush;
+static struct LookupCacheDebugCounter
+{
+ unsigned long nMiss;
+ unsigned long nHit;
+ LookupCacheDebugCounter() : nMiss(0), nHit(0) {}
+ ~LookupCacheDebugCounter()
+ {
+ fprintf( stderr, "\nmiss: %lu, hit: %lu, total: %lu, hit/miss: %lu, hit/total %lu%\n",
+ nMiss, nHit, nHit+nMiss, (nMiss>0 ? nHit/nMiss : 0),
+ ((nHit+nMiss)>0 ? (100*nHit)/(nHit+nMiss) : 0));
+ fflush( stderr);
+ }
+} aLookupCacheDebugCounter;
+#endif
+
+bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
+ const ScQueryParam & rParam ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::LookupQueryWithCache" );
+ bool bFound = false;
+ const ScQueryEntry& rEntry = rParam.GetEntry(0);
+ bool bColumnsMatch = (rParam.nCol1 == rEntry.nField);
+ DBG_ASSERT( bColumnsMatch, "ScInterpreter::LookupQueryWithCache: columns don't match");
+ if (!bColumnsMatch)
+ bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
+ else
+ {
+ ScRange aLookupRange( rParam.nCol1, rParam.nRow1, rParam.nTab,
+ rParam.nCol2, rParam.nRow2, rParam.nTab);
+ ScLookupCache& rCache = pDok->GetLookupCache( aLookupRange);
+ ScLookupCache::QueryCriteria aCriteria( rEntry);
+ ScLookupCache::Result eCacheResult = rCache.lookup( o_rResultPos,
+ aCriteria, aPos);
+ switch (eCacheResult)
+ {
+ case ScLookupCache::NOT_CACHED :
+ case ScLookupCache::CRITERIA_DIFFERENT :
+#if erDEBUG_LOOKUPCACHE
+ ++aLookupCacheDebugCounter.nMiss;
+#if erDEBUG_LOOKUPCACHE > 1
+ fprintf( stderr, "miss %d,%d,%d\n", (int)aPos.Col(), (int)aPos.Row(), (int)aPos.Tab());
+#endif
+#endif
+ bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
+ if (eCacheResult == ScLookupCache::NOT_CACHED)
+ rCache.insert( o_rResultPos, aCriteria, aPos, bFound);
+ break;
+ case ScLookupCache::FOUND :
+#if erDEBUG_LOOKUPCACHE
+ ++aLookupCacheDebugCounter.nHit;
+#if erDEBUG_LOOKUPCACHE > 1
+ fprintf( stderr, "hit %d,%d,%d\n", (int)aPos.Col(), (int)aPos.Row(), (int)aPos.Tab());
+#endif
+#endif
+ bFound = true;
+ break;
+ case ScLookupCache::NOT_AVAILABLE :
+ ; // nothing, bFound remains FALSE
+ break;
+ }
+ }
+ return bFound;
+}
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
new file mode 100644
index 000000000000..dac5f0c99ac5
--- /dev/null
+++ b/sc/source/core/tool/interpr2.cxx
@@ -0,0 +1,3032 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/linkmgr.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/zforlist.hxx>
+#include <rtl/logfile.hxx>
+
+#include "interpre.hxx"
+#include "attrib.hxx"
+#include "sc.hrc"
+#include "ddelink.hxx"
+#include "scmatrix.hxx"
+#include "compiler.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "docoptio.hxx"
+#include "unitconv.hxx"
+#include "globstr.hrc"
+#include "hints.hxx"
+#include "dpobject.hxx"
+#include "postit.hxx"
+
+#include <string.h>
+#include <math.h>
+
+using namespace formula;
+// STATIC DATA -----------------------------------------------------------
+
+#define D_TIMEFACTOR 86400.0
+#define SCdEpsilon 1.0E-7
+
+//-----------------------------------------------------------------------------
+// Datum und Zeit
+//-----------------------------------------------------------------------------
+
+double ScInterpreter::GetDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, bool bStrict )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDateSerial" );
+ if ( nYear < 100 && !bStrict )
+ nYear = pFormatter->ExpandTwoDigitYear( nYear );
+ // Do not use a default Date ctor here because it asks system time with a
+ // performance penalty.
+ INT16 nY, nM, nD;
+ if (bStrict)
+ nY = nYear, nM = nMonth, nD = nDay;
+ else
+ {
+ if (nMonth > 0)
+ {
+ nY = nYear + (nMonth-1) / 12;
+ nM = ((nMonth-1) % 12) + 1;
+ }
+ else
+ {
+ nY = nYear + (nMonth-12) / 12;
+ nM = 12 - (-nMonth) % 12;
+ }
+ nD = 1;
+ }
+ Date aDate( nD, nM, nY);
+ if (!bStrict)
+ aDate += nDay - 1;
+ if (aDate.IsValid())
+ return (double) (aDate - *(pFormatter->GetNullDate()));
+ else
+ {
+ SetError(errNoValue);
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Funktionen
+//-----------------------------------------------------------------------------
+
+void ScInterpreter::ScGetActDate()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetActDate" );
+ nFuncFmtType = NUMBERFORMAT_DATE;
+ Date aActDate;
+ long nDiff = aActDate - *(pFormatter->GetNullDate());
+ PushDouble((double) nDiff);
+}
+
+void ScInterpreter::ScGetActTime()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetActTime" );
+ nFuncFmtType = NUMBERFORMAT_DATETIME;
+ Date aActDate;
+ long nDiff = aActDate - *(pFormatter->GetNullDate());
+ Time aActTime;
+ double nTime = ((double)aActTime.Get100Sec() / 100 +
+ (double)(aActTime.GetSec() +
+ (aActTime.GetMin() * 60) +
+ (aActTime.GetHour() * 3600))) / D_TIMEFACTOR;
+ PushDouble( (double) nDiff + nTime );
+}
+
+void ScInterpreter::ScGetYear()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetYear" );
+ Date aDate = *(pFormatter->GetNullDate());
+ aDate += (long) ::rtl::math::approxFloor(GetDouble());
+ PushDouble( (double) aDate.GetYear() );
+}
+
+void ScInterpreter::ScGetMonth()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetMonth" );
+ Date aDate = *(pFormatter->GetNullDate());
+ aDate += (long) ::rtl::math::approxFloor(GetDouble());
+ PushDouble( (double) aDate.GetMonth() );
+}
+
+void ScInterpreter::ScGetDay()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDay" );
+ Date aDate = *(pFormatter->GetNullDate());
+ aDate += (long)::rtl::math::approxFloor(GetDouble());
+ PushDouble((double) aDate.GetDay());
+}
+
+void ScInterpreter::ScGetMin()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetMin" );
+ double fTime = GetDouble();
+ fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg
+ long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) % 3600;
+ PushDouble( (double) (nVal/60) );
+}
+
+void ScInterpreter::ScGetSec()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetSec" );
+ double fTime = GetDouble();
+ fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg
+ long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) % 60;
+ PushDouble( (double) nVal );
+}
+
+void ScInterpreter::ScGetHour()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetHour" );
+ double fTime = GetDouble();
+ fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg
+ long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) / 3600;
+ PushDouble((double) nVal);
+}
+
+void ScInterpreter::ScGetDateValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDateValue" );
+ String aInputString = GetString();
+ sal_uInt32 nFIndex = 0; // damit default Land/Spr.
+ double fVal;
+ if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
+ {
+ short eType = pFormatter->GetType(nFIndex);
+ if (eType == NUMBERFORMAT_DATE || eType == NUMBERFORMAT_DATETIME)
+ PushDouble(::rtl::math::approxFloor(fVal));
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushIllegalArgument();
+}
+
+void ScInterpreter::ScGetDayOfWeek()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDayOfWeek" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ short nFlag;
+ if (nParamCount == 2)
+ nFlag = (short) ::rtl::math::approxFloor(GetDouble());
+ else
+ nFlag = 1;
+
+ Date aDate = *(pFormatter->GetNullDate());
+ aDate += (long)::rtl::math::approxFloor(GetDouble());
+ int nVal = (int) aDate.GetDayOfWeek();
+ if (nFlag == 1)
+ {
+ if (nVal == 6)
+ nVal = 1;
+ else
+ nVal += 2;
+ }
+ else if (nFlag == 2)
+ nVal += 1;
+ PushInt( nVal );
+ }
+}
+
+void ScInterpreter::ScGetWeekOfYear()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetWeekOfYear" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ short nFlag = (short) ::rtl::math::approxFloor(GetDouble());
+
+ Date aDate = *(pFormatter->GetNullDate());
+ aDate += (long)::rtl::math::approxFloor(GetDouble());
+ PushInt( (int) aDate.GetWeekOfYear( nFlag == 1 ? SUNDAY : MONDAY ));
+ }
+}
+
+void ScInterpreter::ScEasterSunday()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEasterSunday" );
+ nFuncFmtType = NUMBERFORMAT_DATE;
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ INT16 nDay, nMonth, nYear;
+ nYear = (INT16) ::rtl::math::approxFloor( GetDouble() );
+ if ( nYear < 100 )
+ nYear = pFormatter->ExpandTwoDigitYear( nYear );
+ // don't worry, be happy :)
+ int B,C,D,E,F,G,H,I,K,L,M,N,O;
+ N = nYear % 19;
+ B = int(nYear / 100);
+ C = nYear % 100;
+ D = int(B / 4);
+ E = B % 4;
+ F = int((B + 8) / 25);
+ G = int((B - F + 1) / 3);
+ H = (19 * N + B - D - G + 15) % 30;
+ I = int(C / 4);
+ K = C % 4;
+ L = (32 + 2 * E + 2 * I - H - K) % 7;
+ M = int((N + 11 * H + 22 * L) / 451);
+ O = H + L - 7 * M + 114;
+ nDay = sal::static_int_cast<INT16>( O % 31 + 1 );
+ nMonth = sal::static_int_cast<INT16>( int(O / 31) );
+ PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) );
+ }
+}
+
+void ScInterpreter::ScGetDate()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDate" );
+ nFuncFmtType = NUMBERFORMAT_DATE;
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ INT16 nDay = (INT16) ::rtl::math::approxFloor(GetDouble());
+ INT16 nMonth = (INT16) ::rtl::math::approxFloor(GetDouble());
+ INT16 nYear = (INT16) ::rtl::math::approxFloor(GetDouble());
+ if (nYear < 0)
+ PushIllegalArgument();
+ else
+ {
+ PushDouble(GetDateSerial(nYear, nMonth, nDay, false));
+ }
+ }
+}
+
+void ScInterpreter::ScGetTime()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTime" );
+ nFuncFmtType = NUMBERFORMAT_TIME;
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double nSec = GetDouble();
+ double nMin = GetDouble();
+ double nHour = GetDouble();
+ PushDouble( ( (nHour * 3600) + (nMin * 60) + nSec ) / D_TIMEFACTOR );
+ }
+}
+
+void ScInterpreter::ScGetDiffDate()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDiffDate" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double nDate2 = GetDouble();
+ double nDate1 = GetDouble();
+ PushDouble(nDate1 - nDate2);
+ }
+}
+
+void ScInterpreter::ScGetDiffDate360()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDiffDate360" );
+ /* Implementation follows
+ * http://www.bondmarkets.com/eCommerce/SMD_Fields_030802.pdf
+ * Appendix B: Day-Count Bases, there are 7 different ways to calculate the
+ * 30-days count. That document also claims that Excel implements the "PSA
+ * 30" or "NASD 30" method (funny enough they also state that Excel is the
+ * only tool that does so).
+ *
+ * Note that the definiton given in
+ * http://msdn.microsoft.com/library/en-us/office97/html/SEB7C.asp
+ * is _not_ the way how it is actually calculated by Excel (that would not
+ * even match any of the 7 methods mentioned above) and would result in the
+ * following test cases producing wrong results according to that appendix B:
+ *
+ * 28-Feb-95 31-Aug-95 181 instead of 180
+ * 29-Feb-96 31-Aug-96 181 instead of 180
+ * 30-Jan-96 31-Mar-96 61 instead of 60
+ * 31-Jan-96 31-Mar-96 61 instead of 60
+ *
+ * Still, there is a difference between OOoCalc and Excel:
+ * In Excel:
+ * 02-Feb-99 31-Mar-00 results in 419
+ * 31-Mar-00 02-Feb-99 results in -418
+ * In Calc the result is 419 respectively -419. I consider the -418 a bug in Excel.
+ */
+
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ BOOL bFlag;
+ if (nParamCount == 3)
+ bFlag = GetBool();
+ else
+ bFlag = FALSE;
+ double nDate2 = GetDouble();
+ double nDate1 = GetDouble();
+ double fSign;
+ if (nGlobalError)
+ PushError( nGlobalError);
+ else
+ {
+ // #i84934# only for non-US European algorithm swap dates. Else
+ // follow Excel's meaningless extrapolation for "interoperability".
+ if (bFlag && (nDate2 < nDate1))
+ {
+ fSign = nDate1;
+ nDate1 = nDate2;
+ nDate2 = fSign;
+ fSign = -1.0;
+ }
+ else
+ fSign = 1.0;
+ Date aDate1 = *(pFormatter->GetNullDate());
+ aDate1 += (long) ::rtl::math::approxFloor(nDate1);
+ Date aDate2 = *(pFormatter->GetNullDate());
+ aDate2 += (long) ::rtl::math::approxFloor(nDate2);
+ if (aDate1.GetDay() == 31)
+ aDate1 -= (ULONG) 1;
+ else if (!bFlag)
+ {
+ if (aDate1.GetMonth() == 2)
+ {
+ switch ( aDate1.GetDay() )
+ {
+ case 28 :
+ if ( !aDate1.IsLeapYear() )
+ aDate1.SetDay(30);
+ break;
+ case 29 :
+ aDate1.SetDay(30);
+ break;
+ }
+ }
+ }
+ if (aDate2.GetDay() == 31)
+ {
+ if (!bFlag )
+ {
+ if (aDate1.GetDay() == 30)
+ aDate2 -= (ULONG) 1;
+ }
+ else
+ aDate2.SetDay(30);
+ }
+ PushDouble( fSign * (double)
+ ( (double) aDate2.GetDay() + (double) aDate2.GetMonth() * 30.0 +
+ (double) aDate2.GetYear() * 360.0
+ - (double) aDate1.GetDay() - (double) aDate1.GetMonth() * 30.0
+ - (double)aDate1.GetYear() * 360.0) );
+ }
+ }
+}
+
+void ScInterpreter::ScGetTimeValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTimeValue" );
+ String aInputString = GetString();
+ sal_uInt32 nFIndex = 0; // damit default Land/Spr.
+ double fVal;
+ if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
+ {
+ short eType = pFormatter->GetType(nFIndex);
+ if (eType == NUMBERFORMAT_TIME || eType == NUMBERFORMAT_DATETIME)
+ {
+ double fDateVal = rtl::math::approxFloor(fVal);
+ double fTimeVal = fVal - fDateVal;
+ PushDouble(fTimeVal);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushIllegalArgument();
+}
+
+void ScInterpreter::ScPlusMinus()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPlusMinus" );
+ double nVal = GetDouble();
+ short n = 0;
+ if (nVal < 0.0)
+ n = -1;
+ else if (nVal > 0.0)
+ n = 1;
+ PushInt( n );
+}
+
+void ScInterpreter::ScAbs()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAbs" );
+ PushDouble(fabs(GetDouble()));
+}
+
+void ScInterpreter::ScInt()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScInt" );
+ PushDouble(::rtl::math::approxFloor(GetDouble()));
+}
+
+
+void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RoundNumber" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ double fVal = 0.0;
+ if (nParamCount == 1)
+ fVal = ::rtl::math::round( GetDouble(), 0, eMode );
+ else
+ {
+ INT32 nDec = (INT32) ::rtl::math::approxFloor(GetDouble());
+ if( nDec < -20 || nDec > 20 )
+ PushIllegalArgument();
+ else
+ fVal = ::rtl::math::round( GetDouble(), (short)nDec, eMode );
+ }
+ PushDouble(fVal);
+ }
+}
+
+void ScInterpreter::ScRound()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRound" );
+ RoundNumber( rtl_math_RoundingMode_Corrected );
+}
+
+void ScInterpreter::ScRoundDown()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRoundDown" );
+ RoundNumber( rtl_math_RoundingMode_Down );
+}
+
+void ScInterpreter::ScRoundUp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRoundUp" );
+ RoundNumber( rtl_math_RoundingMode_Up );
+}
+
+void ScInterpreter::ScCeil()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCeil" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ BOOL bAbs = ( nParamCount == 3 ? GetBool() : FALSE );
+ double fDec = GetDouble();
+ double fVal = GetDouble();
+ if ( fDec == 0.0 )
+ PushInt(0);
+ else if (fVal*fDec < 0.0)
+ PushIllegalArgument();
+ else
+ {
+ if ( !bAbs && fVal < 0.0 )
+ PushDouble(::rtl::math::approxFloor(fVal/fDec) * fDec);
+ else
+ PushDouble(::rtl::math::approxCeil(fVal/fDec) * fDec);
+ }
+ }
+}
+
+void ScInterpreter::ScFloor()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFloor" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ BOOL bAbs = ( nParamCount == 3 ? GetBool() : FALSE );
+ double fDec = GetDouble();
+ double fVal = GetDouble();
+ if ( fDec == 0.0 )
+ PushInt(0);
+ else if (fVal*fDec < 0.0)
+ PushIllegalArgument();
+ else
+ {
+ if ( !bAbs && fVal < 0.0 )
+ PushDouble(::rtl::math::approxCeil(fVal/fDec) * fDec);
+ else
+ PushDouble(::rtl::math::approxFloor(fVal/fDec) * fDec);
+ }
+ }
+}
+
+void ScInterpreter::ScEven()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEven" );
+ double fVal = GetDouble();
+ if (fVal < 0.0)
+ PushDouble(::rtl::math::approxFloor(fVal/2.0) * 2.0);
+ else
+ PushDouble(::rtl::math::approxCeil(fVal/2.0) * 2.0);
+}
+
+void ScInterpreter::ScOdd()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOdd" );
+ double fVal = GetDouble();
+ if (fVal >= 0.0)
+ {
+ fVal = ::rtl::math::approxCeil(fVal);
+ if (fmod(fVal, 2.0) == 0.0)
+ fVal += 1.0;
+ }
+ else
+ {
+ fVal = ::rtl::math::approxFloor(fVal);
+ if (fmod(fVal, 2.0) == 0.0)
+ fVal -= 1.0;
+ }
+ PushDouble(fVal);
+}
+
+void ScInterpreter::ScArcTan2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTan2" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double nVal2 = GetDouble();
+ double nVal1 = GetDouble();
+ PushDouble(atan2(nVal2, nVal1));
+ }
+}
+
+void ScInterpreter::ScLog()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLog" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ double nBase;
+ if (nParamCount == 2)
+ nBase = GetDouble();
+ else
+ nBase = 10.0;
+ double nVal = GetDouble();
+ if (nVal > 0.0 && nBase > 0.0 && nBase != 1.0)
+ PushDouble(log(nVal) / log(nBase));
+ else
+ PushIllegalArgument();
+ }
+}
+
+void ScInterpreter::ScLn()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLn" );
+ double fVal = GetDouble();
+ if (fVal > 0.0)
+ PushDouble(log(fVal));
+ else
+ PushIllegalArgument();
+}
+
+void ScInterpreter::ScLog10()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLog10" );
+ double fVal = GetDouble();
+ if (fVal > 0.0)
+ PushDouble(log10(fVal));
+ else
+ PushIllegalArgument();
+}
+
+void ScInterpreter::ScNPV()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNPV" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ short nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 31 ) )
+ {
+ double nVal = 0.0;
+ // Wir drehen den Stack um!!
+ FormulaToken* pTemp[ 31 ];
+ for( short i = 0; i < nParamCount; i++ )
+ pTemp[ i ] = pStack[ sp - i - 1 ];
+ memcpy( &pStack[ sp - nParamCount ], pTemp, nParamCount * sizeof( FormulaToken* ) );
+ if (nGlobalError == 0)
+ {
+ double nCount = 1.0;
+ double nZins = GetDouble();
+ --nParamCount;
+ size_t nRefInList = 0;
+ ScRange aRange;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case svDouble :
+ {
+ nVal += (GetDouble() / pow(1.0 + nZins, (double)nCount));
+ nCount++;
+ }
+ break;
+ case svSingleRef :
+ {
+ nVal += (GetDouble() / pow(1.0 + nZins, (double)nCount));
+ nCount++;
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ double nCellVal;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ nVal += (nCellVal / pow(1.0 + nZins, (double)nCount));
+ nCount++;
+ while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr))
+ {
+ nVal += (nCellVal / pow(1.0 + nZins, (double)nCount));
+ nCount++;
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ }
+ }
+ PushDouble(nVal);
+ }
+}
+
+#if defined(WIN) && defined(MSC)
+#pragma optimize("",off)
+#endif
+
+void ScInterpreter::ScIRR()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIRR" );
+ double fSchaetzwert;
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+ if (nParamCount == 2)
+ fSchaetzwert = GetDouble();
+ else
+ fSchaetzwert = 0.1;
+ USHORT sPos = sp; // Stack-Position merken
+ double fEps = 1.0;
+ double x, xNeu, fWert, fZaehler, fNenner, nCount;
+ if (fSchaetzwert == -1.0)
+ x = 0.1; // default gegen Nulldivisionen
+ else
+ x = fSchaetzwert; // Startwert
+ switch (GetStackType())
+ {
+ case svDoubleRef :
+ break;
+ default:
+ {
+ PushIllegalParameter();
+ return;
+ }
+ }
+ const USHORT nIterationsMax = 20;
+ USHORT nItCount = 0;
+ ScRange aRange;
+ while (fEps > SCdEpsilon && nItCount < nIterationsMax)
+ { // Newton-Verfahren:
+ sp = sPos; // Stack zuruecksetzen
+ nCount = 0.0;
+ fZaehler = 0.0;
+ fNenner = 0.0;
+ USHORT nErr = 0;
+ PopDoubleRef( aRange );
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(fWert, nErr))
+ {
+ fZaehler += fWert / pow(1.0+x,(double)nCount);
+ fNenner += -nCount * fWert / pow(1.0+x,nCount+1.0);
+ nCount++;
+ while ((nErr == 0) && aValIter.GetNext(fWert, nErr))
+ {
+ fZaehler += fWert / pow(1.0+x,(double)nCount);
+ fNenner += -nCount * fWert / pow(1.0+x,nCount+1.0);
+ nCount++;
+ }
+ SetError(nErr);
+ }
+ xNeu = x - fZaehler / fNenner; // x(i+1) = x(i)-f(x(i))/f'(x(i))
+ nItCount++;
+ fEps = fabs(xNeu - x);
+ x = xNeu;
+ }
+ if (fSchaetzwert == 0.0 && fabs(x) < SCdEpsilon)
+ x = 0.0; // auf Null normieren
+ if (fEps < SCdEpsilon)
+ PushDouble(x);
+ else
+ PushError( errNoConvergence);
+}
+#if defined(WIN) && defined(MSC)
+#pragma optimize("",on)
+#endif
+
+
+void ScInterpreter::ScMIRR()
+{ // range_of_values ; rate_invest ; rate_reinvest
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ if( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double fRate1_reinvest = GetDouble() + 1;
+ double fNPV_reinvest = 0.0;
+ double fPow_reinvest = 1.0;
+
+ double fRate1_invest = GetDouble() + 1;
+ double fNPV_invest = 0.0;
+ double fPow_invest = 1.0;
+
+ ScRange aRange;
+ PopDoubleRef( aRange );
+
+ if( nGlobalError )
+ PushError( nGlobalError);
+ else
+ {
+ ScValueIterator aValIter( pDok, aRange, glSubTotal );
+ double fCellValue;
+ ULONG nCount = 0;
+ USHORT nIterError = 0;
+
+ BOOL bLoop = aValIter.GetFirst( fCellValue, nIterError );
+ while( bLoop )
+ {
+ if( fCellValue > 0.0 ) // reinvestments
+ fNPV_reinvest += fCellValue * fPow_reinvest;
+ else if( fCellValue < 0.0 ) // investments
+ fNPV_invest += fCellValue * fPow_invest;
+ fPow_reinvest /= fRate1_reinvest;
+ fPow_invest /= fRate1_invest;
+ nCount++;
+
+ bLoop = aValIter.GetNext( fCellValue, nIterError );
+ }
+ if( nIterError )
+ PushError( nIterError );
+ else
+ {
+ double fResult = -fNPV_reinvest / fNPV_invest;
+ fResult *= pow( fRate1_reinvest, (double) nCount - 1 );
+ fResult = pow( fResult, 1.0 / (nCount - 1) );
+ PushDouble( fResult - 1.0 );
+ }
+ }
+ }
+}
+
+
+void ScInterpreter::ScISPMT()
+{ // rate ; period ; total_periods ; invest
+ if( MustHaveParamCount( GetByte(), 4 ) )
+ {
+ double fInvest = GetDouble();
+ double fTotal = GetDouble();
+ double fPeriod = GetDouble();
+ double fRate = GetDouble();
+
+ if( nGlobalError )
+ PushError( nGlobalError);
+ else
+ PushDouble( fInvest * fRate * (fPeriod / fTotal - 1.0) );
+ }
+}
+
+
+//----------------------- Finanzfunktionen ------------------------------------
+
+double ScInterpreter::ScGetBw(double fZins, double fZzr, double fRmz,
+ double fZw, double fF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMIRR" );
+ double fBw;
+ if (fZins == 0.0)
+ fBw = fZw + fRmz * fZzr;
+ else if (fF > 0.0)
+ fBw = (fZw * pow(1.0 + fZins, -fZzr))
+ + (fRmz * (1.0 - pow(1.0 + fZins, -fZzr + 1.0)) / fZins)
+ + fRmz;
+ else
+ fBw = (fZw * pow(1.0 + fZins, -fZzr))
+ + (fRmz * (1.0 - pow(1.0 + fZins, -fZzr)) / fZins);
+ return -fBw;
+}
+
+void ScInterpreter::ScBW()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBW" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ double nRmz, nZzr, nZins, nZw = 0, nFlag = 0;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
+ return;
+ if (nParamCount == 5)
+ nFlag = GetDouble();
+ if (nParamCount >= 4)
+ nZw = GetDouble();
+ nRmz = GetDouble();
+ nZzr = GetDouble();
+ nZins = GetDouble();
+ PushDouble(ScGetBw(nZins, nZzr, nRmz, nZw, nFlag));
+}
+
+void ScInterpreter::ScDIA()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDIA" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ if ( MustHaveParamCount( GetByte(), 4 ) )
+ {
+ double nZr = GetDouble();
+ double nDauer = GetDouble();
+ double nRest = GetDouble();
+ double nWert = GetDouble();
+ double nDia = ((nWert - nRest) * (nDauer - nZr + 1.0)) /
+ ((nDauer * (nDauer + 1.0)) / 2.0);
+ PushDouble(nDia);
+ }
+}
+
+double ScInterpreter::ScGetGDA(double fWert, double fRest, double fDauer,
+ double fPeriode, double fFaktor)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetGDA" );
+ double fGda, fZins, fAlterWert, fNeuerWert;
+ fZins = fFaktor / fDauer;
+ if (fZins >= 1.0)
+ {
+ fZins = 1.0;
+ if (fPeriode == 1.0)
+ fAlterWert = fWert;
+ else
+ fAlterWert = 0.0;
+ }
+ else
+ fAlterWert = fWert * pow(1.0 - fZins, fPeriode - 1.0);
+ fNeuerWert = fWert * pow(1.0 - fZins, fPeriode);
+
+ if (fNeuerWert < fRest)
+ fGda = fAlterWert - fRest;
+ else
+ fGda = fAlterWert - fNeuerWert;
+ if (fGda < 0.0)
+ fGda = 0.0;
+ return fGda;
+}
+
+void ScInterpreter::ScGDA()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGDA" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 4, 5 ) )
+ {
+ double nFaktor;
+ if (nParamCount == 5)
+ nFaktor = GetDouble();
+ else
+ nFaktor = 2.0;
+ double nPeriode = GetDouble();
+ double nDauer = GetDouble();
+ double nRest = GetDouble();
+ double nWert = GetDouble();
+ if (nWert < 0.0 || nRest < 0.0 || nFaktor <= 0.0 || nRest > nWert
+ || nPeriode < 1.0 || nPeriode > nDauer)
+ PushIllegalArgument();
+ else
+ PushDouble(ScGetGDA(nWert, nRest, nDauer, nPeriode, nFaktor));
+ }
+}
+
+void ScInterpreter::ScGDA2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGDA2" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 4, 5 ) )
+ return ;
+ double nMonate;
+ if (nParamCount == 4)
+ nMonate = 12.0;
+ else
+ nMonate = ::rtl::math::approxFloor(GetDouble());
+ double nPeriode = GetDouble();
+ double nDauer = GetDouble();
+ double nRest = GetDouble();
+ double nWert = GetDouble();
+ if (nMonate < 1.0 || nMonate > 12.0 || nDauer > 1200.0 || nRest < 0.0 ||
+ nPeriode > (nDauer + 1.0) || nRest > nWert || nWert < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double nAbRate = 1.0 - pow(nRest / nWert, 1.0 / nDauer);
+ nAbRate = ::rtl::math::approxFloor((nAbRate * 1000.0) + 0.5) / 1000.0;
+ double nErsteAbRate = nWert * nAbRate * nMonate / 12.0;
+ double nGda2 = 0.0;
+ if (::rtl::math::approxFloor(nPeriode) == 1)
+ nGda2 = nErsteAbRate;
+ else
+ {
+ double nSummAbRate = nErsteAbRate;
+ double nMin = nDauer;
+ if (nMin > nPeriode) nMin = nPeriode;
+ USHORT iMax = (USHORT)::rtl::math::approxFloor(nMin);
+ for (USHORT i = 2; i <= iMax; i++)
+ {
+ nGda2 = (nWert - nSummAbRate) * nAbRate;
+ nSummAbRate += nGda2;
+ }
+ if (nPeriode > nDauer)
+ nGda2 = ((nWert - nSummAbRate) * nAbRate * (12.0 - nMonate)) / 12.0;
+ }
+ PushDouble(nGda2);
+}
+
+
+double ScInterpreter::ScInterVDB(double fWert,double fRest,double fDauer,
+ double fDauer1,double fPeriode,double fFaktor)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScInterVDB" );
+ double fVdb=0;
+ double fIntEnd = ::rtl::math::approxCeil(fPeriode);
+ ULONG nLoopEnd = (ULONG) fIntEnd;
+
+ double fTerm, fLia;
+ double fRestwert = fWert - fRest;
+ BOOL bNowLia = FALSE;
+
+ double fGda;
+ ULONG i;
+ fLia=0;
+ for ( i = 1; i <= nLoopEnd; i++)
+ {
+ if(!bNowLia)
+ {
+ fGda = ScGetGDA(fWert, fRest, fDauer, (double) i, fFaktor);
+ fLia = fRestwert/ (fDauer1 - (double) (i-1));
+
+ if (fLia > fGda)
+ {
+ fTerm = fLia;
+ bNowLia = TRUE;
+ }
+ else
+ {
+ fTerm = fGda;
+ fRestwert -= fGda;
+ }
+ }
+ else
+ {
+ fTerm = fLia;
+ }
+
+ if ( i == nLoopEnd)
+ fTerm *= ( fPeriode + 1.0 - fIntEnd );
+
+ fVdb += fTerm;
+ }
+ return fVdb;
+}
+
+
+inline double DblMin( double a, double b )
+{
+ return (a < b) ? a : b;
+}
+
+void ScInterpreter::ScVDB()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVDB" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 5, 7 ) )
+ {
+ double fWert, fRest, fDauer, fAnfang, fEnde, fFaktor, fVdb = 0.0;
+ BOOL bFlag;
+ if (nParamCount == 7)
+ bFlag = GetBool();
+ else
+ bFlag = FALSE;
+ if (nParamCount >= 6)
+ fFaktor = GetDouble();
+ else
+ fFaktor = 2.0;
+ fEnde = GetDouble();
+ fAnfang = GetDouble();
+ fDauer = GetDouble();
+ fRest = GetDouble();
+ fWert = GetDouble();
+ if (fAnfang < 0.0 || fEnde < fAnfang || fEnde > fDauer || fWert < 0.0
+ || fRest > fWert || fFaktor <= 0.0)
+ PushIllegalArgument();
+ else
+ {
+ double fIntStart = ::rtl::math::approxFloor(fAnfang);
+ double fIntEnd = ::rtl::math::approxCeil(fEnde);
+ ULONG nLoopStart = (ULONG) fIntStart;
+ ULONG nLoopEnd = (ULONG) fIntEnd;
+
+ fVdb = 0.0;
+ if (bFlag)
+ {
+ for (ULONG i = nLoopStart + 1; i <= nLoopEnd; i++)
+ {
+ double fTerm = ScGetGDA(fWert, fRest, fDauer, (double) i, fFaktor);
+
+ // Teilperioden am Anfang / Ende beruecksichtigen:
+ if ( i == nLoopStart+1 )
+ fTerm *= ( DblMin( fEnde, fIntStart + 1.0 ) - fAnfang );
+ else if ( i == nLoopEnd )
+ fTerm *= ( fEnde + 1.0 - fIntEnd );
+
+ fVdb += fTerm;
+ }
+ }
+ else
+ {
+
+ double fDauer1=fDauer;
+ double fPart;
+
+ //@Die Frage aller Fragen: "Ist das hier richtig"
+ if(!::rtl::math::approxEqual(fAnfang,::rtl::math::approxFloor(fAnfang)))
+ {
+ if(fFaktor>1)
+ {
+ if(fAnfang>fDauer/2 || ::rtl::math::approxEqual(fAnfang,fDauer/2))
+ {
+ fPart=fAnfang-fDauer/2;
+ fAnfang=fDauer/2;
+ fEnde-=fPart;
+ fDauer1+=1;
+ }
+ }
+ }
+
+ fWert-=ScInterVDB(fWert,fRest,fDauer,fDauer1,fAnfang,fFaktor);
+ fVdb=ScInterVDB(fWert,fRest,fDauer,fDauer-fAnfang,fEnde-fAnfang,fFaktor);
+ }
+ }
+ PushDouble(fVdb);
+ }
+}
+
+void ScInterpreter::ScLaufz()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLaufz" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double nZukunft = GetDouble();
+ double nGegenwart = GetDouble();
+ double nZins = GetDouble();
+ PushDouble(log(nZukunft / nGegenwart) / log(1.0 + nZins));
+ }
+}
+
+void ScInterpreter::ScLIA()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLIA" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double nDauer = GetDouble();
+ double nRest = GetDouble();
+ double nWert = GetDouble();
+ PushDouble((nWert - nRest) / nDauer);
+ }
+}
+
+double ScInterpreter::ScGetRmz(double fZins, double fZzr, double fBw,
+ double fZw, double fF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetRmz" );
+ double fRmz;
+ if (fZins == 0.0)
+ fRmz = (fBw + fZw) / fZzr;
+ else
+ {
+ double fTerm = pow(1.0 + fZins, fZzr);
+ if (fF > 0.0)
+ fRmz = (fZw * fZins / (fTerm - 1.0)
+ + fBw * fZins / (1.0 - 1.0 / fTerm)) / (1.0+fZins);
+ else
+ fRmz = fZw * fZins / (fTerm - 1.0)
+ + fBw * fZins / (1.0 - 1.0 / fTerm);
+ }
+ return -fRmz;
+}
+
+void ScInterpreter::ScRMZ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRMZ" );
+ double nZins, nZzr, nBw, nZw = 0, nFlag = 0;
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
+ return;
+ if (nParamCount == 5)
+ nFlag = GetDouble();
+ if (nParamCount >= 4)
+ nZw = GetDouble();
+ nBw = GetDouble();
+ nZzr = GetDouble();
+ nZins = GetDouble();
+ PushDouble(ScGetRmz(nZins, nZzr, nBw, nZw, nFlag));
+}
+
+void ScInterpreter::ScZGZ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZGZ" );
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double nZukunftswert = GetDouble();
+ double nGegenwartswert = GetDouble();
+ double nZeitraum = GetDouble();
+ PushDouble(pow(nZukunftswert / nGegenwartswert, 1.0 / nZeitraum) - 1.0);
+ }
+}
+
+double ScInterpreter::ScGetZw(double fZins, double fZzr, double fRmz,
+ double fBw, double fF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetZw" );
+ double fZw;
+ if (fZins == 0.0)
+ fZw = fBw + fRmz * fZzr;
+ else
+ {
+ double fTerm = pow(1.0 + fZins, fZzr);
+ if (fF > 0.0)
+ fZw = fBw * fTerm + fRmz*(1.0 + fZins)*(fTerm - 1.0)/fZins;
+ else
+ fZw = fBw * fTerm + fRmz*(fTerm - 1.0)/fZins;
+ }
+ return -fZw;
+}
+
+void ScInterpreter::ScZW()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZW" );
+ double nZins, nZzr, nRmz, nBw = 0, nFlag = 0;
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
+ return;
+ if (nParamCount == 5)
+ nFlag = GetDouble();
+ if (nParamCount >= 4)
+ nBw = GetDouble();
+ nRmz = GetDouble();
+ nZzr = GetDouble();
+ nZins = GetDouble();
+ PushDouble(ScGetZw(nZins, nZzr, nRmz, nBw, nFlag));
+}
+
+void ScInterpreter::ScZZR()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZZR" );
+ double nZins, nRmz, nBw, nZw = 0, nFlag = 0;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
+ return;
+ if (nParamCount == 5)
+ nFlag = GetDouble();
+ if (nParamCount >= 4)
+ nZw = GetDouble();
+ nBw = GetDouble();
+ nRmz = GetDouble();
+ nZins = GetDouble();
+ if (nZins == 0.0)
+ PushDouble(-(nBw + nZw)/nRmz);
+ else if (nFlag > 0.0)
+ PushDouble(log(-(nZins*nZw-nRmz*(1.0+nZins))/(nZins*nBw+nRmz*(1.0+nZins)))
+ /log(1.0+nZins));
+ else
+ PushDouble(log(-(nZins*nZw-nRmz)/(nZins*nBw+nRmz))/log(1.0+nZins));
+}
+
+bool ScInterpreter::RateIteration( double fNper, double fPayment, double fPv,
+ double fFv, double fPayType, double & fGuess )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RateIteration" );
+ // See also #i15090#
+ // Newton-Raphson method: x(i+1) = x(i) - f(x(i)) / f'(x(i))
+ // This solution handles integer and non-integer values of Nper different.
+ // If ODFF will constraint Nper to integer, the distinction of cases can be
+ // removed; only the integer-part is needed then.
+ bool bValid = true, bFound = false;
+ double fX, fXnew, fTerm, fTermDerivation;
+ double fGeoSeries, fGeoSeriesDerivation;
+ const USHORT nIterationsMax = 150;
+ USHORT nCount = 0;
+ const double fEpsilonSmall = 1.0E-14;
+ // convert any fPayType situation to fPayType == zero situation
+ fFv = fFv - fPayment * fPayType;
+ fPv = fPv + fPayment * fPayType;
+ if (fNper == ::rtl::math::round( fNper, 0, rtl_math_RoundingMode_Corrected ))
+ { // Nper is an integer value
+ fX = fGuess;
+ double fPowN, fPowNminus1; // for (1.0+fX)^Nper and (1.0+fX)^(Nper-1)
+ while (!bFound && nCount < nIterationsMax)
+ {
+ fPowNminus1 = pow( 1.0+fX, fNper-1.0);
+ fPowN = fPowNminus1 * (1.0+fX);
+ if (rtl::math::approxEqual( fabs(fX), 0.0))
+ {
+ fGeoSeries = fNper;
+ fGeoSeriesDerivation = fNper * (fNper-1.0)/2.0;
+ }
+ else
+ {
+ fGeoSeries = (fPowN-1.0)/fX;
+ fGeoSeriesDerivation = fNper * fPowNminus1 / fX - fGeoSeries / fX;
+ }
+ fTerm = fFv + fPv *fPowN+ fPayment * fGeoSeries;
+ fTermDerivation = fPv * fNper * fPowNminus1 + fPayment * fGeoSeriesDerivation;
+ if (fabs(fTerm) < fEpsilonSmall)
+ bFound = true; // will catch root which is at an extreme
+ else
+ {
+ if (rtl::math::approxEqual( fabs(fTermDerivation), 0.0))
+ fXnew = fX + 1.1 * SCdEpsilon; // move away from zero slope
+ else
+ fXnew = fX - fTerm / fTermDerivation;
+ nCount++;
+ // more accuracy not possible in oscillating cases
+ bFound = (fabs(fXnew - fX) < SCdEpsilon);
+ fX = fXnew;
+ }
+ }
+ // Gnumeric returns roots < -1, Excel gives an error in that cases,
+ // ODFF says nothing about it. Enable the statement, if you want Excel's
+ // behavior
+ //bValid =(fX >=-1.0);
+ }
+ else
+ { // Nper is not an integer value.
+ fX = (fGuess < -1.0) ? -1.0 : fGuess; // start with a valid fX
+ while (bValid && !bFound && nCount < nIterationsMax)
+ {
+ if (rtl::math::approxEqual( fabs(fX), 0.0))
+ {
+ fGeoSeries = fNper;
+ fGeoSeriesDerivation = fNper * (fNper-1.0)/2.0;
+ }
+ else
+ {
+ fGeoSeries = (pow( 1.0+fX, fNper) - 1.0) / fX;
+ fGeoSeriesDerivation = fNper * pow( 1.0+fX, fNper-1.0) / fX - fGeoSeries / fX;
+ }
+ fTerm = fFv + fPv *pow(1.0 + fX,fNper)+ fPayment * fGeoSeries;
+ fTermDerivation = fPv * fNper * pow( 1.0+fX, fNper-1.0) + fPayment * fGeoSeriesDerivation;
+ if (fabs(fTerm) < fEpsilonSmall)
+ bFound = true; // will catch root which is at an extreme
+ else
+ {
+ if (rtl::math::approxEqual( fabs(fTermDerivation), 0.0))
+ fXnew = fX + 1.1 * SCdEpsilon; // move away from zero slope
+ else
+ fXnew = fX - fTerm / fTermDerivation;
+ nCount++;
+ // more accuracy not possible in oscillating cases
+ bFound = (fabs(fXnew - fX) < SCdEpsilon);
+ fX = fXnew;
+ bValid = (fX >= -1.0); // otherwise pow(1.0+fX,fNper) will fail
+ }
+ }
+ }
+ fGuess = fX; // return approximate root
+ return bValid && bFound;
+}
+
+// In Calc UI it is the function RATE(Nper;Pmt;Pv;Fv;Type;Guess)
+void ScInterpreter::ScZins()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZins" );
+ double fPv, fPayment, fNper;
+ // defaults for missing arguments, see ODFF spec
+ double fFv = 0, fPayType = 0, fGuess = 0.1;
+ bool bValid = true;
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 6 ) )
+ return;
+ if (nParamCount == 6)
+ fGuess = GetDouble();
+ if (nParamCount >= 5)
+ fPayType = GetDouble();
+ if (nParamCount >= 4)
+ fFv = GetDouble();
+ fPv = GetDouble();
+ fPayment = GetDouble();
+ fNper = GetDouble();
+ if (fNper <= 0.0) // constraint from ODFF spec
+ {
+ PushIllegalArgument();
+ return;
+ }
+ // other values for fPayType might be meaningful,
+ // ODFF spec is not clear yet, enable statement if you want only 0 and 1
+ //if (fPayType != 0.0) fPayType = 1.0;
+ bValid = RateIteration(fNper, fPayment, fPv, fFv, fPayType, fGuess);
+ if (!bValid)
+ SetError(errNoConvergence);
+ PushDouble(fGuess);
+}
+
+double ScInterpreter::ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw,
+ double fZw, double fF, double& fRmz)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetZinsZ" );
+ fRmz = ScGetRmz(fZins, fZzr, fBw, fZw, fF); // fuer kapz auch bei fZr == 1
+ double fZinsZ;
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ if (fZr == 1.0)
+ {
+ if (fF > 0.0)
+ fZinsZ = 0.0;
+ else
+ fZinsZ = -fBw;
+ }
+ else
+ {
+ if (fF > 0.0)
+ fZinsZ = ScGetZw(fZins, fZr-2.0, fRmz, fBw, 1.0) - fRmz;
+ else
+ fZinsZ = ScGetZw(fZins, fZr-1.0, fRmz, fBw, 0.0);
+ }
+ return fZinsZ * fZins;
+}
+
+void ScInterpreter::ScZinsZ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZinsZ" );
+ double nZins, nZr, nRmz, nZzr, nBw, nZw = 0, nFlag = 0;
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 4, 6 ) )
+ return;
+ if (nParamCount == 6)
+ nFlag = GetDouble();
+ if (nParamCount >= 5)
+ nZw = GetDouble();
+ nBw = GetDouble();
+ nZzr = GetDouble();
+ nZr = GetDouble();
+ nZins = GetDouble();
+ if (nZr < 1.0 || nZr > nZzr)
+ PushIllegalArgument();
+ else
+ PushDouble(ScGetZinsZ(nZins, nZr, nZzr, nBw, nZw, nFlag, nRmz));
+}
+
+void ScInterpreter::ScKapz()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKapz" );
+ double nZins, nZr, nZzr, nBw, nZw = 0, nFlag = 0, nRmz, nZinsz;
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 4, 6 ) )
+ return;
+ if (nParamCount == 6)
+ nFlag = GetDouble();
+ if (nParamCount >= 5)
+ nZw = GetDouble();
+ nBw = GetDouble();
+ nZzr = GetDouble();
+ nZr = GetDouble();
+ nZins = GetDouble();
+ if (nZr < 1.0 || nZr > nZzr)
+ PushIllegalArgument();
+ else
+ {
+ nZinsz = ScGetZinsZ(nZins, nZr, nZzr, nBw, nZw, nFlag, nRmz);
+ PushDouble(nRmz - nZinsz);
+ }
+}
+
+void ScInterpreter::ScKumZinsZ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKumZinsZ" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ if ( MustHaveParamCount( GetByte(), 6 ) )
+ {
+ double fZins, fZzr, fBw, fAnfang, fEnde, fF, fRmz, fZinsZ;
+ fF = GetDouble();
+ fEnde = ::rtl::math::approxFloor(GetDouble());
+ fAnfang = ::rtl::math::approxFloor(GetDouble());
+ fBw = GetDouble();
+ fZzr = GetDouble();
+ fZins = GetDouble();
+ if (fAnfang < 1.0 || fEnde < fAnfang || fZins <= 0.0 ||
+ fEnde > fZzr || fZzr <= 0.0 || fBw <= 0.0)
+ PushIllegalArgument();
+ else
+ {
+ ULONG nAnfang = (ULONG) fAnfang;
+ ULONG nEnde = (ULONG) fEnde ;
+ fRmz = ScGetRmz(fZins, fZzr, fBw, 0.0, fF);
+ fZinsZ = 0.0;
+ if (nAnfang == 1)
+ {
+ if (fF <= 0.0)
+ fZinsZ = -fBw;
+ nAnfang++;
+ }
+ for (ULONG i = nAnfang; i <= nEnde; i++)
+ {
+ if (fF > 0.0)
+ fZinsZ += ScGetZw(fZins, (double)(i-2), fRmz, fBw, 1.0) - fRmz;
+ else
+ fZinsZ += ScGetZw(fZins, (double)(i-1), fRmz, fBw, 0.0);
+ }
+ fZinsZ *= fZins;
+ PushDouble(fZinsZ);
+ }
+ }
+}
+
+void ScInterpreter::ScKumKapZ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKumKapZ" );
+ nFuncFmtType = NUMBERFORMAT_CURRENCY;
+ if ( MustHaveParamCount( GetByte(), 6 ) )
+ {
+ double fZins, fZzr, fBw, fAnfang, fEnde, fF, fRmz, fKapZ;
+ fF = GetDouble();
+ fEnde = ::rtl::math::approxFloor(GetDouble());
+ fAnfang = ::rtl::math::approxFloor(GetDouble());
+ fBw = GetDouble();
+ fZzr = GetDouble();
+ fZins = GetDouble();
+ if (fAnfang < 1.0 || fEnde < fAnfang || fZins <= 0.0 ||
+ fEnde > fZzr || fZzr <= 0.0 || fBw <= 0.0)
+ PushIllegalArgument();
+ else
+ {
+ fRmz = ScGetRmz(fZins, fZzr, fBw, 0.0, fF);
+ fKapZ = 0.0;
+ ULONG nAnfang = (ULONG) fAnfang;
+ ULONG nEnde = (ULONG) fEnde;
+ if (nAnfang == 1)
+ {
+ if (fF <= 0.0)
+ fKapZ = fRmz + fBw * fZins;
+ else
+ fKapZ = fRmz;
+ nAnfang++;
+ }
+ for (ULONG i = nAnfang; i <= nEnde; i++)
+ {
+ if (fF > 0.0)
+ fKapZ += fRmz - (ScGetZw(fZins, (double)(i-2), fRmz, fBw, 1.0) - fRmz) * fZins;
+ else
+ fKapZ += fRmz - ScGetZw(fZins, (double)(i-1), fRmz, fBw, 0.0) * fZins;
+ }
+ PushDouble(fKapZ);
+ }
+ }
+}
+
+void ScInterpreter::ScEffektiv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEffektiv" );
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double fPerioden = GetDouble();
+ double fNominal = GetDouble();
+ if (fPerioden < 1.0 || fNominal <= 0.0)
+ PushIllegalArgument();
+ else
+ {
+ fPerioden = ::rtl::math::approxFloor(fPerioden);
+ PushDouble(pow(1.0 + fNominal/fPerioden, fPerioden) - 1.0);
+ }
+ }
+}
+
+void ScInterpreter::ScNominal()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNominal" );
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double fPerioden = GetDouble();
+ double fEffektiv = GetDouble();
+ if (fPerioden < 1.0 || fEffektiv <= 0.0)
+ PushIllegalArgument();
+ else
+ {
+ fPerioden = ::rtl::math::approxFloor(fPerioden);
+ PushDouble( (pow(fEffektiv + 1.0, 1.0 / fPerioden) - 1.0) * fPerioden );
+ }
+ }
+}
+
+void ScInterpreter::ScMod()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMod" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double fVal2 = GetDouble(); // Denominator
+ double fVal1 = GetDouble(); // Numerator
+ if (fVal2 == floor(fVal2)) // a pure integral number stored in double
+ {
+ double fResult = fmod(fVal1,fVal2);
+ if ( (fResult != 0.0) &&
+ ((fVal1 > 0.0 && fVal2 < 0.0) || (fVal1 < 0.0 && fVal2 > 0.0)))
+ fResult += fVal2 ;
+ PushDouble( fResult );
+ }
+ else
+ {
+ PushDouble( ::rtl::math::approxSub( fVal1,
+ ::rtl::math::approxFloor(fVal1 / fVal2) * fVal2));
+ }
+ }
+}
+
+/** (Goal Seek) Find a value of x that is a root of f(x)
+
+ This function is used internally for the goal seek operation. It uses the
+ Regula Falsi (aka false position) algorithm to find a root of f(x). The
+ start value and the target value are to be given by the user in the
+ goal seek dialog. The f(x) in this case is defined as the formula in the
+ formula cell minus target value. This function may also perform additional
+ search in the horizontal directions when the f(x) is discrete in order to
+ ensure a non-zero slope necessary for deriving a subsequent x that is
+ reasonably close to the root of interest.
+
+ @change 24.10.2004 by Kohei Yoshida (kohei@openoffice.org)
+
+ @see #i28955#
+*/
+void ScInterpreter::ScBackSolver()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBackSolver" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ BOOL bDoneIteration = FALSE;
+ ScAddress aValueAdr, aFormulaAdr;
+ double fTargetVal = GetDouble();
+ PopSingleRef( aFormulaAdr );
+ PopSingleRef( aValueAdr );
+
+ if (nGlobalError == 0)
+ {
+ ScBaseCell* pVCell = GetCell( aValueAdr );
+ // CELLTYPE_NOTE: kein Value aber von Formel referiert
+ BOOL bTempCell = (!pVCell || pVCell->GetCellType() == CELLTYPE_NOTE);
+ ScBaseCell* pFCell = GetCell( aFormulaAdr );
+
+ if ( ((pVCell && pVCell->GetCellType() == CELLTYPE_VALUE) || bTempCell)
+ && pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScRange aVRange( aValueAdr, aValueAdr ); // fuer SetDirty
+ double fSaveVal; // Original value to be restored later if necessary
+ ScPostIt* pNote = 0;
+
+ if ( bTempCell )
+ {
+ pNote = pVCell ? pVCell->ReleaseNote() : 0;
+ fSaveVal = 0.0;
+ pVCell = new ScValueCell( fSaveVal );
+ pDok->PutCell( aValueAdr, pVCell );
+ }
+ else
+ fSaveVal = GetCellValue( aValueAdr, pVCell );
+
+ const USHORT nMaxIter = 100;
+ const double fEps = 1E-10;
+ const double fDelta = 1E-6;
+
+ double fBestX, fXPrev;
+ double fBestF, fFPrev;
+ fBestX = fXPrev = fSaveVal;
+
+ ScFormulaCell* pFormula = (ScFormulaCell*) pFCell;
+ ScValueCell* pValue = (ScValueCell*) pVCell;
+
+ pFormula->Interpret();
+ BOOL bError = ( pFormula->GetErrCode() != 0 );
+ // bError always corresponds with fF
+
+ fFPrev = pFormula->GetValue() - fTargetVal;
+
+ fBestF = fabs( fFPrev );
+ if ( fBestF < fDelta )
+ bDoneIteration = TRUE;
+
+ double fX = fXPrev + fEps;
+ double fF = fFPrev;
+ double fSlope;
+
+ USHORT nIter = 0;
+
+ BOOL bHorMoveError = FALSE;
+ // Nach der Regula Falsi Methode
+ while ( !bDoneIteration && ( nIter++ < nMaxIter ) )
+ {
+ pValue->SetValue( fX );
+ pDok->SetDirty( aVRange );
+ pFormula->Interpret();
+ bError = ( pFormula->GetErrCode() != 0 );
+ fF = pFormula->GetValue() - fTargetVal;
+
+ if ( fF == fFPrev && !bError )
+ {
+ // HORIZONTAL SEARCH: Keep moving x in both directions until the f(x)
+ // becomes different from the previous f(x). This routine is needed
+ // when a given function is discrete, in which case the resulting slope
+ // may become zero which ultimately causes the goal seek operation
+ // to fail. #i28955#
+
+ USHORT nHorIter = 0;
+ const double fHorStepAngle = 5.0;
+ const double fHorMaxAngle = 80.0;
+ int nHorMaxIter = static_cast<int>( fHorMaxAngle / fHorStepAngle );
+ BOOL bDoneHorMove = FALSE;
+
+ while ( !bDoneHorMove && !bHorMoveError && nHorIter++ < nHorMaxIter )
+ {
+ double fHorAngle = fHorStepAngle * static_cast<double>( nHorIter );
+ double fHorTangent = ::rtl::math::tan( fHorAngle * F_PI / 180 );
+
+ USHORT nIdx = 0;
+ while( nIdx++ < 2 && !bDoneHorMove )
+ {
+ double fHorX;
+ if ( nIdx == 1 )
+ fHorX = fX + fabs(fF)*fHorTangent;
+ else
+ fHorX = fX - fabs(fF)*fHorTangent;
+
+ pValue->SetValue( fHorX );
+ pDok->SetDirty( aVRange );
+ pFormula->Interpret();
+ bHorMoveError = ( pFormula->GetErrCode() != 0 );
+ if ( bHorMoveError )
+ break;
+
+ fF = pFormula->GetValue() - fTargetVal;
+ if ( fF != fFPrev )
+ {
+ fX = fHorX;
+ bDoneHorMove = TRUE;
+ }
+ }
+ }
+ if ( !bDoneHorMove )
+ bHorMoveError = TRUE;
+ }
+
+ if ( bError )
+ {
+ // move closer to last valid value (fXPrev), keep fXPrev & fFPrev
+ double fDiff = ( fXPrev - fX ) / 2;
+ if (fabs(fDiff) < fEps)
+ fDiff = (fDiff < 0.0) ? - fEps : fEps;
+ fX += fDiff;
+ }
+ else if ( bHorMoveError )
+ break;
+ else if ( fabs(fF) < fDelta )
+ {
+ // converged to root
+ fBestX = fX;
+ bDoneIteration = TRUE;
+ }
+ else
+ {
+ if ( fabs(fF) + fDelta < fBestF )
+ {
+ fBestX = fX;
+ fBestF = fabs(fF);
+ }
+
+ if ( ( fXPrev - fX ) != 0 )
+ {
+ fSlope = ( fFPrev - fF ) / ( fXPrev - fX );
+ if ( fabs( fSlope ) < fEps )
+ fSlope = fSlope < 0.0 ? -fEps : fEps;
+ }
+ else
+ fSlope = fEps;
+
+ fXPrev = fX;
+ fFPrev = fF;
+ fX = fX - ( fF / fSlope );
+ }
+ }
+
+ // Try a nice rounded input value if possible.
+ const double fNiceDelta = (bDoneIteration && fabs(fBestX) >= 1e-3 ? 1e-3 : fDelta);
+ double nX = ::rtl::math::approxFloor((fBestX / fNiceDelta) + 0.5) * fNiceDelta;
+// double nX = ::rtl::math::approxFloor((fBestX / fDelta) + 0.5) * fDelta;
+
+ if ( bDoneIteration )
+ {
+ pValue->SetValue( nX );
+ pDok->SetDirty( aVRange );
+ pFormula->Interpret();
+ if ( fabs( pFormula->GetValue() - fTargetVal ) > fabs( fF ) )
+ nX = fBestX;
+ }
+ else if ( bError || bHorMoveError )
+ {
+ nX = fBestX;
+ }
+ if ( bTempCell )
+ {
+ pVCell = pNote ? new ScNoteCell( pNote ) : 0;
+ pDok->PutCell( aValueAdr, pVCell );
+ }
+ else
+ pValue->SetValue( fSaveVal );
+ pDok->SetDirty( aVRange );
+ pFormula->Interpret();
+ if ( !bDoneIteration )
+ SetError(NOTAVAILABLE);
+ PushDouble(nX);
+ }
+ else
+ {
+ if ( !bDoneIteration )
+ SetError(NOTAVAILABLE);
+ PushInt(0); // falsche Zelltypen
+ }
+ }
+ else
+ {
+ if ( !bDoneIteration )
+ SetError(NOTAVAILABLE);
+ PushInt(0); // nGlobalError
+ }
+ }
+}
+
+void ScInterpreter::ScIntersect()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIntersect" );
+ formula::FormulaTokenRef p2nd = PopToken();
+ formula::FormulaTokenRef p1st = PopToken();
+
+ if (nGlobalError || !p2nd || !p1st)
+ {
+ PushIllegalArgument();
+ return;
+ } // if (nGlobalError || !xT2 || !xT1)
+
+ StackVar sv1 = p1st->GetType();
+ StackVar sv2 = p2nd->GetType();
+ if ((sv1 != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList) ||
+ (sv2 != svSingleRef && sv2 != svDoubleRef && sv2 != svRefList))
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ ScToken* x1 = static_cast<ScToken*>(p1st.get());
+ ScToken* x2 = static_cast<ScToken*>(p2nd.get());
+ if (sv1 == svRefList || sv2 == svRefList)
+ {
+ // Now this is a bit nasty but it simplifies things, and having
+ // intersections with lists isn't too common, if at all..
+ // Convert a reference to list.
+ ScToken* xt[2] = { x1, x2 };
+ StackVar sv[2] = { sv1, sv2 };
+ for (size_t i=0; i<2; ++i)
+ {
+ if (sv[i] == svSingleRef)
+ {
+ ScComplexRefData aRef;
+ aRef.Ref1 = aRef.Ref2 = xt[i]->GetSingleRef();
+ xt[i] = new ScRefListToken;
+ xt[i]->GetRefList()->push_back( aRef);
+ }
+ else if (sv[i] == svDoubleRef)
+ {
+ ScComplexRefData aRef = xt[i]->GetDoubleRef();
+ xt[i] = new ScRefListToken;
+ xt[i]->GetRefList()->push_back( aRef);
+ }
+ }
+ x1 = xt[0], x2 = xt[1];
+
+ x1->CalcAbsIfRel( aPos);
+ x2->CalcAbsIfRel( aPos);
+ ScTokenRef xRes = new ScRefListToken;
+ ScRefList* pRefList = xRes->GetRefList();
+ ScRefList::const_iterator end1( x1->GetRefList()->end());
+ ScRefList::const_iterator end2( x2->GetRefList()->end());
+ for (ScRefList::const_iterator it1( x1->GetRefList()->begin());
+ it1 != end1; ++it1)
+ {
+ const ScSingleRefData& r11 = (*it1).Ref1;
+ const ScSingleRefData& r12 = (*it1).Ref2;
+ for (ScRefList::const_iterator it2( x2->GetRefList()->begin());
+ it2 != end2; ++it2)
+ {
+ const ScSingleRefData& r21 = (*it2).Ref1;
+ const ScSingleRefData& r22 = (*it2).Ref2;
+ SCCOL nCol1 = ::std::max( r11.nCol, r21.nCol);
+ SCROW nRow1 = ::std::max( r11.nRow, r21.nRow);
+ SCTAB nTab1 = ::std::max( r11.nTab, r21.nTab);
+ SCCOL nCol2 = ::std::min( r12.nCol, r22.nCol);
+ SCROW nRow2 = ::std::min( r12.nRow, r22.nRow);
+ SCTAB nTab2 = ::std::min( r12.nTab, r22.nTab);
+ if (nCol2 < nCol1 || nRow2 < nRow1 || nTab2 < nTab1)
+ ; // nothing
+ else
+ {
+ ScComplexRefData aRef;
+ aRef.InitRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ pRefList->push_back( aRef);
+ }
+ }
+ }
+ size_t n = pRefList->size();
+ if (!n)
+ PushError( errNoRef);
+ else if (n == 1)
+ {
+ const ScComplexRefData& rRef = (*pRefList)[0];
+ if (rRef.Ref1 == rRef.Ref2)
+ PushTempToken( new ScSingleRefToken( rRef.Ref1));
+ else
+ PushTempToken( new ScDoubleRefToken( rRef));
+ }
+ else
+ PushTempToken( xRes);
+ }
+ else
+ {
+ ScToken* pt[2] = { x1, x2 };
+ StackVar sv[2] = { sv1, sv2 };
+ SCCOL nC1[2], nC2[2];
+ SCROW nR1[2], nR2[2];
+ SCTAB nT1[2], nT2[2];
+ for (size_t i=0; i<2; ++i)
+ {
+ switch (sv[i])
+ {
+ case svSingleRef:
+ case svDoubleRef:
+ pt[i]->CalcAbsIfRel( aPos);
+ {
+ const ScSingleRefData& r = pt[i]->GetSingleRef();
+ nC1[i] = r.nCol;
+ nR1[i] = r.nRow;
+ nT1[i] = r.nTab;
+ }
+ if (sv[i] == svDoubleRef)
+ {
+ const ScSingleRefData& r = pt[i]->GetSingleRef2();
+ nC2[i] = r.nCol;
+ nR2[i] = r.nRow;
+ nT2[i] = r.nTab;
+ }
+ else
+ {
+ nC2[i] = nC1[i];
+ nR2[i] = nR1[i];
+ nT2[i] = nT1[i];
+ }
+ break;
+ default:
+ ; // nothing, prevent compiler warning
+ }
+ }
+ SCCOL nCol1 = ::std::max( nC1[0], nC1[1]);
+ SCROW nRow1 = ::std::max( nR1[0], nR1[1]);
+ SCTAB nTab1 = ::std::max( nT1[0], nT1[1]);
+ SCCOL nCol2 = ::std::min( nC2[0], nC2[1]);
+ SCROW nRow2 = ::std::min( nR2[0], nR2[1]);
+ SCTAB nTab2 = ::std::min( nT2[0], nT2[1]);
+ if (nCol2 < nCol1 || nRow2 < nRow1 || nTab2 < nTab1)
+ PushError( errNoRef);
+ else if (nCol2 == nCol1 && nRow2 == nRow1 && nTab2 == nTab1)
+ PushSingleRef( nCol1, nRow1, nTab1);
+ else
+ PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ }
+}
+
+
+void ScInterpreter::ScRangeFunc()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRangeFunc" );
+ formula::FormulaTokenRef x2 = PopToken();
+ formula::FormulaTokenRef x1 = PopToken();
+
+ if (nGlobalError || !x2 || !x1)
+ {
+ PushIllegalArgument();
+ return;
+ } // if (nGlobalError || !xT2 || !xT1)
+ FormulaTokenRef xRes = ScToken::ExtendRangeReference( *x1, *x2, aPos, false);
+ if (!xRes)
+ PushIllegalArgument();
+ else
+ PushTempToken( xRes);
+}
+
+
+void ScInterpreter::ScUnionFunc()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnionFunc" );
+ formula::FormulaTokenRef p2nd = PopToken();
+ formula::FormulaTokenRef p1st = PopToken();
+
+ if (nGlobalError || !p2nd || !p1st)
+ {
+ PushIllegalArgument();
+ return;
+ } // if (nGlobalError || !xT2 || !xT1)
+
+ StackVar sv1 = p1st->GetType();
+ StackVar sv2 = p2nd->GetType();
+ if ((sv1 != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList) ||
+ (sv2 != svSingleRef && sv2 != svDoubleRef && sv2 != svRefList))
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ ScToken* x1 = static_cast<ScToken*>(p1st.get());
+ ScToken* x2 = static_cast<ScToken*>(p2nd.get());
+
+
+ ScTokenRef xRes;
+ // Append to an existing RefList if there is one.
+ if (sv1 == svRefList)
+ {
+ xRes = x1;
+ sv1 = svUnknown; // mark as handled
+ }
+ else if (sv2 == svRefList)
+ {
+ xRes = x2;
+ sv2 = svUnknown; // mark as handled
+ }
+ else
+ xRes = new ScRefListToken;
+ ScRefList* pRes = xRes->GetRefList();
+ ScToken* pt[2] = { x1, x2 };
+ StackVar sv[2] = { sv1, sv2 };
+ for (size_t i=0; i<2; ++i)
+ {
+ if (pt[i] == xRes)
+ continue;
+ switch (sv[i])
+ {
+ case svSingleRef:
+ {
+ ScComplexRefData aRef;
+ aRef.Ref1 = aRef.Ref2 = pt[i]->GetSingleRef();
+ pRes->push_back( aRef);
+ }
+ break;
+ case svDoubleRef:
+ pRes->push_back( pt[i]->GetDoubleRef());
+ break;
+ case svRefList:
+ {
+ const ScRefList* p = pt[i]->GetRefList();
+ ScRefList::const_iterator it( p->begin());
+ ScRefList::const_iterator end( p->end());
+ for ( ; it != end; ++it)
+ {
+ pRes->push_back( *it);
+ }
+ }
+ break;
+ default:
+ ; // nothing, prevent compiler warning
+ }
+ }
+ ValidateRef( *pRes); // set #REF! if needed
+ PushTempToken( xRes);
+}
+
+
+void ScInterpreter::ScCurrent()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCurrent" );
+ FormulaTokenRef xTok( PopToken());
+ if (xTok)
+ {
+ PushTempToken( xTok);
+ PushTempToken( xTok);
+ }
+ else
+ PushError( errUnknownStackVariable);
+}
+
+void ScInterpreter::ScStyle()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStyle" );
+ BYTE nParamCount = GetByte();
+ if (nParamCount >= 1 && nParamCount <= 3)
+ {
+ String aStyle2; // Vorlage nach Timer
+ if (nParamCount >= 3)
+ aStyle2 = GetString();
+ long nTimeOut = 0; // Timeout
+ if (nParamCount >= 2)
+ nTimeOut = (long)(GetDouble()*1000.0);
+ String aStyle1 = GetString(); // Vorlage fuer sofort
+
+ if (nTimeOut < 0)
+ nTimeOut = 0;
+
+ //
+ // Request ausfuehren, um Vorlage anzuwenden
+ //
+
+ if ( !pDok->IsClipOrUndo() )
+ {
+ SfxObjectShell* pShell = pDok->GetDocumentShell();
+ if (pShell)
+ {
+ //! notify object shell directly
+
+ ScRange aRange(aPos);
+ ScAutoStyleHint aHint( aRange, aStyle1, nTimeOut, aStyle2 );
+ pShell->Broadcast( aHint );
+ }
+ }
+
+ PushDouble(0.0);
+ }
+ else
+ PushIllegalParameter();
+}
+
+ScDdeLink* lcl_GetDdeLink( sfx2::LinkManager* pLinkMgr,
+ const String& rA, const String& rT, const String& rI, BYTE nM )
+{
+ USHORT nCount = pLinkMgr->GetLinks().Count();
+ for (USHORT i=0; i<nCount; i++ )
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkMgr->GetLinks()[i];
+ if (pBase->ISA(ScDdeLink))
+ {
+ ScDdeLink* pLink = (ScDdeLink*)pBase;
+ if ( pLink->GetAppl() == rA &&
+ pLink->GetTopic() == rT &&
+ pLink->GetItem() == rI &&
+ pLink->GetMode() == nM )
+ return pLink;
+ }
+ }
+
+ return NULL;
+}
+
+void ScInterpreter::ScDde()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDde" );
+ // Applikation, Datei, Bereich
+ // Application, Topic, Item
+
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 3, 4 ) )
+ {
+ BYTE nMode = SC_DDE_DEFAULT;
+ if (nParamCount == 4)
+ nMode = (BYTE) ::rtl::math::approxFloor(GetDouble());
+ String aItem = GetString();
+ String aTopic = GetString();
+ String aAppl = GetString();
+
+ if (nMode > SC_DDE_TEXT)
+ nMode = SC_DDE_DEFAULT;
+
+ // temporary documents (ScFunctionAccess) have no DocShell
+ // and no LinkManager -> abort
+
+ sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager();
+ if (!pLinkMgr)
+ {
+ PushNoValue();
+ return;
+ }
+
+ // Nach dem Laden muss neu interpretiert werden (Verknuepfungen aufbauen)
+
+ if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() )
+ pMyFormulaCell->GetCode()->SetRecalcModeOnLoad();
+
+ // solange der Link nicht ausgewertet ist, Idle abklemmen
+ // (um zirkulaere Referenzen zu vermeiden)
+
+ BOOL bOldDis = pDok->IsIdleDisabled();
+ pDok->DisableIdle( TRUE );
+
+ // Link-Objekt holen / anlegen
+
+ ScDdeLink* pLink = lcl_GetDdeLink( pLinkMgr, aAppl, aTopic, aItem, nMode );
+
+ //! Dde-Links (zusaetzlich) effizienter am Dokument speichern !!!!!
+ // ScDdeLink* pLink = pDok->GetDdeLink( aAppl, aTopic, aItem );
+
+ BOOL bWasError = ( pMyFormulaCell->GetRawError() != 0 );
+
+ if (!pLink)
+ {
+ pLink = new ScDdeLink( pDok, aAppl, aTopic, aItem, nMode );
+ pLinkMgr->InsertDDELink( pLink, aAppl, aTopic, aItem );
+ if ( pLinkMgr->GetLinks().Count() == 1 ) // erster ?
+ {
+ SfxBindings* pBindings = pDok->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_LINKS ); // Link-Manager enablen
+ }
+
+ //! asynchron auswerten ???
+ pLink->TryUpdate(); // TryUpdate ruft Update nicht mehrfach auf
+
+ // StartListening erst nach dem Update, sonst circular reference
+ pMyFormulaCell->StartListening( *pLink );
+ }
+ else
+ {
+ pMyFormulaCell->StartListening( *pLink );
+ }
+
+ // Wenn aus dem Reschedule beim Ausfuehren des Links ein Fehler
+ // (z.B. zirkulaere Referenz) entstanden ist, der vorher nicht da war,
+ // das Fehler-Flag zuruecksetzen:
+
+ if ( pMyFormulaCell->GetRawError() && !bWasError )
+ pMyFormulaCell->SetErrCode(0);
+
+ // Wert abfragen
+
+ const ScMatrix* pLinkMat = pLink->GetResult();
+ if (pLinkMat)
+ {
+ SCSIZE nC, nR;
+ pLinkMat->GetDimensions(nC, nR);
+ ScMatrixRef pNewMat = GetNewMat( nC, nR);
+ if (pNewMat)
+ {
+ pLinkMat->MatCopy(*pNewMat); // kopieren
+ PushMatrix( pNewMat );
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushNA();
+
+ pDok->DisableIdle( bOldDis );
+ }
+}
+
+void ScInterpreter::ScBase()
+{ // Value, Base [, MinLen]
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ static const sal_Unicode __FAR_DATA pDigits[] = {
+ '0','1','2','3','4','5','6','7','8','9',
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M',
+ 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+ 0
+ };
+ static const int nDigits = (sizeof(pDigits)/sizeof(sal_Unicode))-1;
+ xub_StrLen nMinLen;
+ if ( nParamCount == 3 )
+ {
+ double fLen = ::rtl::math::approxFloor( GetDouble() );
+ if ( 1.0 <= fLen && fLen < STRING_MAXLEN )
+ nMinLen = (xub_StrLen) fLen;
+ else if ( fLen == 0.0 )
+ nMinLen = 1;
+ else
+ nMinLen = 0; // Error
+ }
+ else
+ nMinLen = 1;
+ double fBase = ::rtl::math::approxFloor( GetDouble() );
+ double fVal = ::rtl::math::approxFloor( GetDouble() );
+ double fChars = ((fVal > 0.0 && fBase > 0.0) ?
+ (ceil( log( fVal ) / log( fBase ) ) + 2.0) :
+ 2.0);
+ if ( fChars >= STRING_MAXLEN )
+ nMinLen = 0; // Error
+
+ if ( !nGlobalError && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal )
+ {
+ const xub_StrLen nConstBuf = 128;
+ sal_Unicode aBuf[nConstBuf];
+ xub_StrLen nBuf = Max( (xub_StrLen) fChars, (xub_StrLen) (nMinLen+1) );
+ sal_Unicode* pBuf = (nBuf <= nConstBuf ? aBuf : new sal_Unicode[nBuf]);
+ for ( xub_StrLen j = 0; j < nBuf; ++j )
+ {
+ pBuf[j] = '0';
+ }
+ sal_Unicode* p = pBuf + nBuf - 1;
+ *p = 0;
+ if ( fVal <= (ULONG)(~0) )
+ {
+ ULONG nVal = (ULONG) fVal;
+ ULONG nBase = (ULONG) fBase;
+ while ( nVal && p > pBuf )
+ {
+ *--p = pDigits[ nVal % nBase ];
+ nVal /= nBase;
+ }
+ fVal = (double) nVal;
+ }
+ else
+ {
+ BOOL bDirt = FALSE;
+ while ( fVal && p > pBuf )
+ {
+//! mit fmod Rundungsfehler ab 2**48
+// double fDig = ::rtl::math::approxFloor( fmod( fVal, fBase ) );
+// so ist es etwas besser
+ double fInt = ::rtl::math::approxFloor( fVal / fBase );
+ double fMult = fInt * fBase;
+#if OSL_DEBUG_LEVEL > 1
+ // #53943# =BASIS(1e308;36) => GPF mit
+ // nDig = (size_t) ::rtl::math::approxFloor( fVal - fMult );
+ // trotz vorheriger Pruefung ob fVal >= fMult
+ double fDebug1 = fVal - fMult;
+ // fVal := 7,5975311883090e+290
+ // fMult := 7,5975311883090e+290
+ // fDebug1 := 1,3848924157003e+275 <- RoundOff-Error
+ // fVal != fMult, aber: ::rtl::math::approxEqual( fVal, fMult ) == TRUE
+ double fDebug2 = ::rtl::math::approxSub( fVal, fMult );
+ // und ::rtl::math::approxSub( fVal, fMult ) == 0
+ double fDebug3 = ( fInt ? fVal / fInt : 0.0 );
+ // Nach dem strange fDebug1 und fVal < fMult ist eigentlich
+ // fDebug2 == fBase, trotzdem wird das mit einem Vergleich
+ // nicht erkannt, dann schlaegt bDirt zu und alles wird wieder gut..
+
+ // prevent compiler warnings
+ (void)fDebug1; (void)fDebug2; (void)fDebug3;
+#endif
+ size_t nDig;
+ if ( fVal < fMult )
+ { // da ist was gekippt
+ bDirt = TRUE;
+ nDig = 0;
+ }
+ else
+ {
+ double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) );
+ if ( bDirt )
+ {
+ bDirt = FALSE;
+ --fDig;
+ }
+ if ( fDig <= 0.0 )
+ nDig = 0;
+ else if ( fDig >= fBase )
+ nDig = ((size_t) fBase) - 1;
+ else
+ nDig = (size_t) fDig;
+ }
+ *--p = pDigits[ nDig ];
+ fVal = fInt;
+ }
+ }
+ if ( fVal )
+ PushError( errStringOverflow );
+ else
+ {
+ if ( nBuf - (p - pBuf) <= nMinLen )
+ p = pBuf + nBuf - 1 - nMinLen;
+ PushStringBuffer( p );
+ }
+ if ( pBuf != aBuf )
+ delete [] pBuf;
+ }
+ else
+ PushIllegalArgument();
+ }
+}
+
+
+void ScInterpreter::ScDecimal()
+{ // Text, Base
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double fBase = ::rtl::math::approxFloor( GetDouble() );
+ String aStr( GetString() );
+ if ( !nGlobalError && 2 <= fBase && fBase <= 36 )
+ {
+ double fVal = 0.0;
+ int nBase = (int) fBase;
+ register const sal_Unicode* p = aStr.GetBuffer();
+ while ( *p == ' ' || *p == '\t' )
+ p++; // strip leading white space
+ if ( nBase == 16 )
+ { // evtl. hex-prefix strippen
+ if ( *p == 'x' || *p == 'X' )
+ p++;
+ else if ( *p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') )
+ p += 2;
+ }
+ while ( *p )
+ {
+ int n;
+ if ( '0' <= *p && *p <= '9' )
+ n = *p - '0';
+ else if ( 'A' <= *p && *p <= 'Z' )
+ n = 10 + (*p - 'A');
+ else if ( 'a' <= *p && *p <= 'z' )
+ n = 10 + (*p - 'a');
+ else
+ n = nBase;
+ if ( nBase <= n )
+ {
+ if ( *(p+1) == 0 &&
+ ( (nBase == 2 && (*p == 'b' || *p == 'B'))
+ ||(nBase == 16 && (*p == 'h' || *p == 'H')) )
+ )
+ ; // 101b und F00Dh sind ok
+ else
+ {
+ PushIllegalArgument();
+ return ;
+ }
+ }
+ else
+ fVal = fVal * fBase + n;
+ p++;
+
+ }
+ PushDouble( fVal );
+ }
+ else
+ PushIllegalArgument();
+ }
+}
+
+
+void ScInterpreter::ScConvert()
+{ // Value, FromUnit, ToUnit
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ String aToUnit( GetString() );
+ String aFromUnit( GetString() );
+ double fVal = GetDouble();
+ if ( nGlobalError )
+ PushError( nGlobalError);
+ else
+ { // erst die angegebene Reihenfolge suchen, wenn nicht gefunden den Kehrwert
+ double fConv;
+ if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aFromUnit, aToUnit ) )
+ PushDouble( fVal * fConv );
+ else if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aToUnit, aFromUnit ) )
+ PushDouble( fVal / fConv );
+ else
+ PushNA();
+ }
+ }
+}
+
+
+void ScInterpreter::ScRoman()
+{ // Value [Mode]
+ BYTE nParamCount = GetByte();
+ if( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0;
+ double fVal = ::rtl::math::approxFloor( GetDouble() );
+ if( nGlobalError )
+ PushError( nGlobalError);
+ else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) )
+ {
+ static const sal_Unicode pChars[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
+ static const USHORT pValues[] = { 1000, 500, 100, 50, 10, 5, 1 };
+ static const USHORT nMaxIndex = (USHORT)(sizeof(pValues) / sizeof(pValues[0]) - 1);
+
+ String aRoman;
+ USHORT nVal = (USHORT) fVal;
+ USHORT nMode = (USHORT) fMode;
+
+ for( UINT16 i = 0; i <= nMaxIndex / 2; i++ )
+ {
+ USHORT nIndex = 2 * i;
+ USHORT nDigit = nVal / pValues[ nIndex ];
+
+ if( (nDigit % 5) == 4 )
+ {
+ USHORT nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2;
+ USHORT nSteps = 0;
+ while( (nSteps < nMode) && (nIndex < nMaxIndex) )
+ {
+ nSteps++;
+ if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal )
+ nIndex++;
+ else
+ nSteps = nMode;
+ }
+ aRoman += pChars[ nIndex ];
+ aRoman += pChars[ nIndex2 ];
+ nVal = sal::static_int_cast<USHORT>( nVal + pValues[ nIndex ] );
+ nVal = sal::static_int_cast<USHORT>( nVal - pValues[ nIndex2 ] );
+ }
+ else
+ {
+ if( nDigit > 4 )
+ aRoman += pChars[ nIndex - 1 ];
+ aRoman.Expand( aRoman.Len() + (nDigit % 5), pChars[ nIndex ] );
+ nVal %= pValues[ nIndex ];
+ }
+ }
+
+ PushString( aRoman );
+ }
+ else
+ PushIllegalArgument();
+ }
+}
+
+
+BOOL lcl_GetArabicValue( sal_Unicode cChar, USHORT& rnValue, BOOL& rbIsDec )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBase" );
+ switch( cChar )
+ {
+ case 'M': rnValue = 1000; rbIsDec = TRUE; break;
+ case 'D': rnValue = 500; rbIsDec = FALSE; break;
+ case 'C': rnValue = 100; rbIsDec = TRUE; break;
+ case 'L': rnValue = 50; rbIsDec = FALSE; break;
+ case 'X': rnValue = 10; rbIsDec = TRUE; break;
+ case 'V': rnValue = 5; rbIsDec = FALSE; break;
+ case 'I': rnValue = 1; rbIsDec = TRUE; break;
+ default: return FALSE;
+ }
+ return TRUE;
+}
+
+
+void ScInterpreter::ScArabic()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArabic" );
+ String aRoman( GetString() );
+ if( nGlobalError )
+ PushError( nGlobalError);
+ else
+ {
+ aRoman.ToUpperAscii();
+
+ USHORT nValue = 0;
+ USHORT nValidRest = 3999;
+ USHORT nCharIndex = 0;
+ USHORT nCharCount = aRoman.Len();
+ BOOL bValid = TRUE;
+
+ while( bValid && (nCharIndex < nCharCount) )
+ {
+ USHORT nDigit1 = 0;
+ USHORT nDigit2 = 0;
+ BOOL bIsDec1 = FALSE;
+ BOOL bIsDec2 = FALSE;
+ bValid = lcl_GetArabicValue( aRoman.GetChar( nCharIndex ), nDigit1, bIsDec1 );
+ if( bValid && (nCharIndex + 1 < nCharCount) )
+ bValid = lcl_GetArabicValue( aRoman.GetChar( nCharIndex + 1 ), nDigit2, bIsDec2 );
+ if( bValid )
+ {
+ if( nDigit1 >= nDigit2 )
+ {
+ nValue = sal::static_int_cast<USHORT>( nValue + nDigit1 );
+ nValidRest %= (nDigit1 * (bIsDec1 ? 5 : 2));
+ bValid = (nValidRest >= nDigit1);
+ if( bValid )
+ nValidRest = sal::static_int_cast<USHORT>( nValidRest - nDigit1 );
+ nCharIndex++;
+ }
+ else if( nDigit1 * 2 != nDigit2 )
+ {
+ USHORT nDiff = nDigit2 - nDigit1;
+ nValue = sal::static_int_cast<USHORT>( nValue + nDiff );
+ bValid = (nValidRest >= nDiff);
+ if( bValid )
+ nValidRest = nDigit1 - 1;
+ nCharIndex += 2;
+ }
+ else
+ bValid = FALSE;
+ }
+ }
+ if( bValid )
+ PushInt( nValue );
+ else
+ PushIllegalArgument();
+ }
+}
+
+
+void ScInterpreter::ScHyperLink()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHyperLink" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ {
+ double fVal = 0.0;
+ String aStr;
+ ScMatValType nResultType = SC_MATVAL_STRING;
+
+ if ( nParamCount == 2 )
+ {
+ switch ( GetStackType() )
+ {
+ case svDouble:
+ fVal = GetDouble();
+ nResultType = SC_MATVAL_VALUE;
+ break;
+ case svString:
+ aStr = GetString();
+ break;
+ case svSingleRef:
+ case svDoubleRef:
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData( pCell))
+ nResultType = SC_MATVAL_EMPTY;
+ else
+ {
+ USHORT nErr = GetCellErrCode( pCell );
+ if (nErr)
+ SetError( nErr);
+ else if (HasCellValueData( pCell))
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ nResultType = SC_MATVAL_VALUE;
+ }
+ else
+ GetCellString( aStr, pCell );
+ }
+ }
+ break;
+ case svMatrix:
+ nResultType = GetDoubleOrStringFromMatrix( fVal, aStr);
+ break;
+ case svMissing:
+ case svEmptyCell:
+ Pop();
+ // mimic xcl
+ fVal = 0.0;
+ nResultType = SC_MATVAL_VALUE;
+ break;
+ default:
+ PopError();
+ SetError( errIllegalArgument);
+ }
+ }
+ String aUrl = GetString();
+ ScMatrixRef pResMat = GetNewMat( 1, 2);
+ if (nGlobalError)
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nResultType = SC_MATVAL_VALUE;
+ }
+ if (nParamCount == 2 || nGlobalError)
+ {
+ if (ScMatrix::IsValueType( nResultType))
+ pResMat->PutDouble( fVal, 0);
+ else if (ScMatrix::IsRealStringType( nResultType))
+ pResMat->PutString( aStr, 0);
+ else // EmptyType, EmptyPathType, mimic xcl
+ pResMat->PutDouble( 0.0, 0 );
+ }
+ else
+ pResMat->PutString( aUrl, 0 );
+ pResMat->PutString( aUrl, 1 );
+ bMatrixFormula = true;
+ PushMatrix(pResMat);
+ }
+}
+
+
+BOOL lclConvertMoney( const String& aSearchUnit, double& rfRate, int& rnDec )
+{
+ struct ConvertInfo
+ {
+ const sal_Char* pCurrText;
+ double fRate;
+ int nDec;
+ };
+ ConvertInfo aConvertTable[] = {
+ { "EUR", 1.0, 2 },
+ { "ATS", 13.7603, 2 },
+ { "BEF", 40.3399, 0 },
+ { "DEM", 1.95583, 2 },
+ { "ESP", 166.386, 0 },
+ { "FIM", 5.94573, 2 },
+ { "FRF", 6.55957, 2 },
+ { "IEP", 0.787564, 2 },
+ { "ITL", 1936.27, 0 },
+ { "LUF", 40.3399, 0 },
+ { "NLG", 2.20371, 2 },
+ { "PTE", 200.482, 2 },
+ { "GRD", 340.750, 2 },
+ { "SIT", 239.640, 2 },
+ { "MTL", 0.429300, 2 },
+ { "CYP", 0.585274, 2 },
+ { "SKK", 30.1260, 2 }
+ };
+
+ const size_t nConversionCount = sizeof( aConvertTable ) / sizeof( aConvertTable[0] );
+ for ( size_t i = 0; i < nConversionCount; i++ )
+ if ( aSearchUnit.EqualsIgnoreCaseAscii( aConvertTable[i].pCurrText ) )
+ {
+ rfRate = aConvertTable[i].fRate;
+ rnDec = aConvertTable[i].nDec;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ScInterpreter::ScEuroConvert()
+{ //Value, FromUnit, ToUnit[, FullPrecision, [TriangulationPrecision]]
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 3, 5 ) )
+ {
+ double nPrecision = 0.0;
+ if ( nParamCount == 5 )
+ {
+ nPrecision = ::rtl::math::approxFloor(GetDouble());
+ if ( nPrecision < 3 )
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ BOOL bFullPrecision = FALSE;
+ if ( nParamCount >= 4 )
+ bFullPrecision = GetBool();
+ String aToUnit( GetString() );
+ String aFromUnit( GetString() );
+ double fVal = GetDouble();
+ if ( nGlobalError )
+ PushError( nGlobalError);
+ else
+ {
+ double fRes;
+ double fFromRate;
+ double fToRate;
+ int nFromDec;
+ int nToDec;
+ String aEur( RTL_CONSTASCII_USTRINGPARAM("EUR"));
+ if ( lclConvertMoney( aFromUnit, fFromRate, nFromDec )
+ && lclConvertMoney( aToUnit, fToRate, nToDec ) )
+ {
+ if ( aFromUnit.EqualsIgnoreCaseAscii( aToUnit ) )
+ fRes = fVal;
+ else
+ {
+ if ( aFromUnit.EqualsIgnoreCaseAscii( aEur ) )
+ fRes = fVal * fToRate;
+ else
+ {
+ double fIntermediate = fVal / fFromRate;
+ if ( nPrecision )
+ fIntermediate = ::rtl::math::round( fIntermediate,
+ (int) nPrecision );
+ fRes = fIntermediate * fToRate;
+ }
+ if ( !bFullPrecision )
+ fRes = ::rtl::math::round( fRes, nToDec );
+ }
+ PushDouble( fRes );
+ }
+ else
+ PushIllegalArgument();
+ }
+ }
+}
+
+
+// BAHTTEXT ===================================================================
+
+#define UTF8_TH_0 "\340\270\250\340\270\271\340\270\231\340\270\242\340\271\214"
+#define UTF8_TH_1 "\340\270\253\340\270\231\340\270\266\340\271\210\340\270\207"
+#define UTF8_TH_2 "\340\270\252\340\270\255\340\270\207"
+#define UTF8_TH_3 "\340\270\252\340\270\262\340\270\241"
+#define UTF8_TH_4 "\340\270\252\340\270\265\340\271\210"
+#define UTF8_TH_5 "\340\270\253\340\271\211\340\270\262"
+#define UTF8_TH_6 "\340\270\253\340\270\201"
+#define UTF8_TH_7 "\340\271\200\340\270\210\340\271\207\340\270\224"
+#define UTF8_TH_8 "\340\271\201\340\270\233\340\270\224"
+#define UTF8_TH_9 "\340\271\200\340\270\201\340\271\211\340\270\262"
+#define UTF8_TH_10 "\340\270\252\340\270\264\340\270\232"
+#define UTF8_TH_11 "\340\271\200\340\270\255\340\271\207\340\270\224"
+#define UTF8_TH_20 "\340\270\242\340\270\265\340\271\210"
+#define UTF8_TH_1E2 "\340\270\243\340\271\211\340\270\255\340\270\242"
+#define UTF8_TH_1E3 "\340\270\236\340\270\261\340\270\231"
+#define UTF8_TH_1E4 "\340\270\253\340\270\241\340\270\267\340\271\210\340\270\231"
+#define UTF8_TH_1E5 "\340\271\201\340\270\252\340\270\231"
+#define UTF8_TH_1E6 "\340\270\245\340\271\211\340\270\262\340\270\231"
+#define UTF8_TH_DOT0 "\340\270\226\340\271\211\340\270\247\340\270\231"
+#define UTF8_TH_BAHT "\340\270\232\340\270\262\340\270\227"
+#define UTF8_TH_SATANG "\340\270\252\340\270\225\340\270\262\340\270\207\340\270\204\340\271\214"
+#define UTF8_TH_MINUS "\340\270\245\340\270\232"
+
+#define UTF8_STRINGPARAM( ascii ) ascii, static_cast< xub_StrLen >( sizeof( ascii ) - 1 )
+#define UTF8_CREATE( ascii ) ByteString( UTF8_STRINGPARAM( ascii ) )
+#define UTF8_APPEND( ascii ) Append( UTF8_STRINGPARAM( ascii ) )
+#define UTF8_PREPEND( ascii ) Insert( UTF8_CREATE( ascii ), 0 )
+
+// local functions ------------------------------------------------------------
+
+namespace {
+
+inline void lclSplitBlock( double& rfInt, sal_Int32& rnBlock, double fValue, double fSize )
+{
+ rnBlock = static_cast< sal_Int32 >( modf( (fValue + 0.1) / fSize, &rfInt ) * fSize + 0.1 );
+}
+
+/** Appends a digit (0 to 9) to the passed string. */
+void lclAppendDigit( ByteString& rText, sal_Int32 nDigit )
+{
+ switch( nDigit )
+ {
+ case 0: rText.UTF8_APPEND( UTF8_TH_0 ); break;
+ case 1: rText.UTF8_APPEND( UTF8_TH_1 ); break;
+ case 2: rText.UTF8_APPEND( UTF8_TH_2 ); break;
+ case 3: rText.UTF8_APPEND( UTF8_TH_3 ); break;
+ case 4: rText.UTF8_APPEND( UTF8_TH_4 ); break;
+ case 5: rText.UTF8_APPEND( UTF8_TH_5 ); break;
+ case 6: rText.UTF8_APPEND( UTF8_TH_6 ); break;
+ case 7: rText.UTF8_APPEND( UTF8_TH_7 ); break;
+ case 8: rText.UTF8_APPEND( UTF8_TH_8 ); break;
+ case 9: rText.UTF8_APPEND( UTF8_TH_9 ); break;
+ default: DBG_ERRORFILE( "lclAppendDigit - illegal digit" );
+ }
+}
+
+/** Appends a value raised to a power of 10: nDigit*10^nPow10.
+ @param nDigit A digit in the range from 1 to 9.
+ @param nPow10 A value in the range from 2 to 5.
+ */
+void lclAppendPow10( ByteString& rText, sal_Int32 nDigit, sal_Int32 nPow10 )
+{
+ DBG_ASSERT( (1 <= nDigit) && (nDigit <= 9), "lclAppendPow10 - illegal digit" );
+ lclAppendDigit( rText, nDigit );
+ switch( nPow10 )
+ {
+ case 2: rText.UTF8_APPEND( UTF8_TH_1E2 ); break;
+ case 3: rText.UTF8_APPEND( UTF8_TH_1E3 ); break;
+ case 4: rText.UTF8_APPEND( UTF8_TH_1E4 ); break;
+ case 5: rText.UTF8_APPEND( UTF8_TH_1E5 ); break;
+ default: DBG_ERRORFILE( "lclAppendPow10 - illegal power" );
+ }
+}
+
+/** Appends a block of 6 digits (value from 1 to 999,999) to the passed string. */
+void lclAppendBlock( ByteString& rText, sal_Int32 nValue )
+{
+ DBG_ASSERT( (1 <= nValue) && (nValue <= 999999), "lclAppendBlock - illegal value" );
+ if( nValue >= 100000 )
+ {
+ lclAppendPow10( rText, nValue / 100000, 5 );
+ nValue %= 100000;
+ }
+ if( nValue >= 10000 )
+ {
+ lclAppendPow10( rText, nValue / 10000, 4 );
+ nValue %= 10000;
+ }
+ if( nValue >= 1000 )
+ {
+ lclAppendPow10( rText, nValue / 1000, 3 );
+ nValue %= 1000;
+ }
+ if( nValue >= 100 )
+ {
+ lclAppendPow10( rText, nValue / 100, 2 );
+ nValue %= 100;
+ }
+ if( nValue > 0 )
+ {
+ sal_Int32 nTen = nValue / 10;
+ sal_Int32 nOne = nValue % 10;
+ if( nTen >= 1 )
+ {
+ if( nTen >= 3 )
+ lclAppendDigit( rText, nTen );
+ else if( nTen == 2 )
+ rText.UTF8_APPEND( UTF8_TH_20 );
+ rText.UTF8_APPEND( UTF8_TH_10 );
+ }
+ if( (nTen > 0) && (nOne == 1) )
+ rText.UTF8_APPEND( UTF8_TH_11 );
+ else if( nOne > 0 )
+ lclAppendDigit( rText, nOne );
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+void ScInterpreter::ScBahtText()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBahtText" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 1 ) )
+ {
+ double fValue = GetDouble();
+ if( nGlobalError )
+ {
+ PushError( nGlobalError);
+ return;
+ }
+
+ // sign
+ bool bMinus = fValue < 0.0;
+ fValue = fabs( fValue );
+
+ // round to 2 digits after decimal point, fValue contains Satang as integer
+ fValue = ::rtl::math::approxFloor( fValue * 100.0 + 0.5 );
+
+ // split Baht and Satang
+ double fBaht = 0.0;
+ sal_Int32 nSatang = 0;
+ lclSplitBlock( fBaht, nSatang, fValue, 100.0 );
+
+ ByteString aText;
+
+ // generate text for Baht value
+ if( fBaht == 0.0 )
+ {
+ if( nSatang == 0 )
+ aText.UTF8_APPEND( UTF8_TH_0 );
+ }
+ else while( fBaht > 0.0 )
+ {
+ ByteString aBlock;
+ sal_Int32 nBlock = 0;
+ lclSplitBlock( fBaht, nBlock, fBaht, 1.0e6 );
+ if( nBlock > 0 )
+ lclAppendBlock( aBlock, nBlock );
+ // add leading "million", if there will come more blocks
+ if( fBaht > 0.0 )
+ aBlock.UTF8_PREPEND( UTF8_TH_1E6 );
+ aText.Insert( aBlock, 0 );
+ }
+ if( aText.Len() > 0 )
+ aText.UTF8_APPEND( UTF8_TH_BAHT );
+
+ // generate text for Satang value
+ if( nSatang == 0 )
+ {
+ aText.UTF8_APPEND( UTF8_TH_DOT0 );
+ }
+ else
+ {
+ lclAppendBlock( aText, nSatang );
+ aText.UTF8_APPEND( UTF8_TH_SATANG );
+ }
+
+ // add the minus sign
+ if( bMinus )
+ aText.UTF8_PREPEND( UTF8_TH_MINUS );
+
+ PushString( String( aText, RTL_TEXTENCODING_UTF8 ) );
+ }
+}
+
+// ============================================================================
+
+void ScInterpreter::ScGetPivotData()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetPivotData" );
+ BYTE nParamCount = GetByte();
+
+ if ( MustHaveParamCount( nParamCount, 2, 30 ) )
+ {
+ // there must be an even number of args
+ // target, ref, then field/item pairs
+ if( (nParamCount % 2) == 1)
+ goto failed;
+
+ bool bOldSyntax = false;
+ if ( nParamCount == 2 )
+ {
+ // if the first parameter is a ref, assume old syntax
+ StackVar eFirstType = GetStackType( 2 );
+ if ( eFirstType == svSingleRef || eFirstType == svDoubleRef )
+ bOldSyntax = true;
+ }
+
+ ScDPGetPivotDataField aTarget; // target field, and returns result
+ std::vector< ScDPGetPivotDataField > aFilters;
+ String aFilterList;
+ if ( bOldSyntax )
+ aFilterList = GetString(); // old syntax: second parameter is list of constraints
+ else
+ {
+ // new syntax: separate name/value pairs
+
+ USHORT nFilterCount = nParamCount / 2 - 1;
+ aFilters.resize( nFilterCount );
+
+ USHORT i = nFilterCount;
+ while( i-- > 0 )
+ {
+ //! should allow numeric constraint values
+ aFilters[i].mbValIsStr = TRUE;
+ aFilters[i].maValStr = GetString();
+
+ aFilters[i].maFieldName = GetString();
+ }
+ }
+
+ // common to both syntaxes: a reference to the data pilot table
+
+ ScRange aBlock;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ PopDoubleRef( aBlock );
+ break;
+
+ case svSingleRef :
+ {
+ ScAddress aAddr;
+ PopSingleRef( aAddr );
+ aBlock = aAddr;
+ break;
+ }
+ default:
+ goto failed;
+ }
+ // NOTE : MS Excel docs claim to use the 'most recent' which is not
+ // exactly the same as what we do in ScDocument::GetDPAtBlock
+ // However we do need to use GetDPABlock
+ ScDPObject* pDPObj = pDok->GetDPAtBlock ( aBlock );
+ if( NULL == pDPObj)
+ goto failed;
+
+ if ( bOldSyntax )
+ {
+ // fill aFilters / aTarget from aFilterList string
+ if ( !pDPObj->ParseFilters( aTarget, aFilters, aFilterList ) )
+ goto failed;
+ }
+ else
+ aTarget.maFieldName = GetString(); // new syntax: first parameter is data field name
+
+ if( pDPObj->GetPivotData( aTarget, aFilters ) )
+ {
+ if( aTarget.mbValIsStr )
+ PushString( aTarget.maValStr );
+ else
+ PushDouble( aTarget.mnValNum );
+ return;
+ }
+ }
+
+failed :
+ PushError( errNoRef );
+}
+
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
new file mode 100644
index 000000000000..bcea57703d78
--- /dev/null
+++ b/sc/source/core/tool/interpr3.cxx
@@ -0,0 +1,4244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/solar.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rtl/logfile.hxx>
+
+#include "interpre.hxx"
+#include "global.hxx"
+#include "compiler.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "scmatrix.hxx"
+#include "globstr.hrc"
+
+#include <math.h>
+#include <vector>
+#include <algorithm>
+
+using ::std::vector;
+using namespace formula;
+
+// STATIC DATA -----------------------------------------------------------
+
+#define SCdEpsilon 1.0E-7
+#define SC_MAX_ITERATION_COUNT 20
+#define MAX_ANZ_DOUBLE_FOR_SORT 100000
+// PI jetzt als F_PI aus solar.h
+//#define PI 3.1415926535897932
+
+const double ScInterpreter::fMaxGammaArgument = 171.624376956302; // found experimental
+const double fMachEps = ::std::numeric_limits<double>::epsilon();
+
+//-----------------------------------------------------------------------------
+
+class ScDistFunc
+{
+public:
+ virtual double GetValue(double x) const = 0;
+};
+
+// iteration for inverse distributions
+
+//template< class T > double lcl_IterateInverse( const T& rFunction, double x0, double x1, bool& rConvError )
+
+/** u*w<0.0 fails for values near zero */
+inline bool lcl_HasChangeOfSign( double u, double w )
+{
+ return (u < 0.0 && w > 0.0) || (u > 0.0 && w < 0.0);
+}
+
+double lcl_IterateInverse( const ScDistFunc& rFunction, double fAx, double fBx, bool& rConvError )
+{
+ rConvError = false;
+ const double fYEps = 1.0E-307;
+ const double fXEps = ::std::numeric_limits<double>::epsilon();
+
+ DBG_ASSERT(fAx<fBx, "IterateInverse: wrong interval");
+
+ // find enclosing interval
+
+ double fAy = rFunction.GetValue(fAx);
+ double fBy = rFunction.GetValue(fBx);
+ double fTemp;
+ unsigned short nCount;
+ for (nCount = 0; nCount < 1000 && !lcl_HasChangeOfSign(fAy,fBy); nCount++)
+ {
+ if (fabs(fAy) <= fabs(fBy))
+ {
+ fTemp = fAx;
+ fAx += 2.0 * (fAx - fBx);
+ if (fAx < 0.0)
+ fAx = 0.0;
+ fBx = fTemp;
+ fBy = fAy;
+ fAy = rFunction.GetValue(fAx);
+ }
+ else
+ {
+ fTemp = fBx;
+ fBx += 2.0 * (fBx - fAx);
+ fAx = fTemp;
+ fAy = fBy;
+ fBy = rFunction.GetValue(fBx);
+ }
+ }
+
+ if (fAy == 0.0)
+ return fAx;
+ if (fBy == 0.0)
+ return fBx;
+ if (!lcl_HasChangeOfSign( fAy, fBy))
+ {
+ rConvError = true;
+ return 0.0;
+ }
+ // inverse quadric interpolation with additional brackets
+ // set three points
+ double fPx = fAx;
+ double fPy = fAy;
+ double fQx = fBx;
+ double fQy = fBy;
+ double fRx = fAx;
+ double fRy = fAy;
+ double fSx = 0.5 * (fAx + fBx); // potential next point
+ bool bHasToInterpolate = true;
+ nCount = 0;
+ while ( nCount < 500 && fabs(fRy) > fYEps &&
+ (fBx-fAx) > ::std::max( fabs(fAx), fabs(fBx)) * fXEps )
+ {
+ if (bHasToInterpolate)
+ {
+ if (fPy!=fQy && fQy!=fRy && fRy!=fPy)
+ {
+ fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)
+ + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)
+ + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);
+ bHasToInterpolate = (fAx < fSx) && (fSx < fBx); // inside the brackets?
+ }
+ else
+ bHasToInterpolate = false;
+ }
+ if(!bHasToInterpolate)
+ {
+ fSx = 0.5 * (fAx + fBx);
+ // reset points
+ fPx = fAx; fPy = fAy;
+ fQx = fBx; fQy = fBy;
+ bHasToInterpolate = true;
+ }
+ // shift points for next interpolation
+ fPx = fQx; fQx = fRx; fRx = fSx;
+ fPy = fQy; fQy = fRy; fRy = rFunction.GetValue(fSx);
+ // update brackets
+ if (lcl_HasChangeOfSign( fAy, fRy))
+ {
+ fBx = fRx; fBy = fRy;
+ }
+ else
+ {
+ fAx = fRx; fAy = fRy;
+ }
+ // if last interration brought to small advance, then do bisection next
+ // time, for safety
+ bHasToInterpolate = bHasToInterpolate && (fabs(fRy) * 2.0 <= fabs(fQy));
+ ++nCount;
+ }
+ return fRx;
+}
+
+//-----------------------------------------------------------------------------
+// Allgemeine Funktionen
+//-----------------------------------------------------------------------------
+
+void ScInterpreter::ScNoName()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNoName" );
+ PushError(errNoName);
+}
+
+void ScInterpreter::ScBadName()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBadName" );
+ short nParamCount = GetByte();
+ while (nParamCount-- > 0)
+ {
+ PopError();
+ }
+ PushError( errNoName);
+}
+
+double ScInterpreter::phi(double x)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::phi" );
+ return 0.39894228040143268 * exp(-(x * x) / 2.0);
+}
+
+double ScInterpreter::integralPhi(double x)
+{ // Using gauss(x)+0.5 has severe cancellation errors for x<-4
+ return 0.5 * ::rtl::math::erfc(-x * 0.7071067811865475); // * 1/sqrt(2)
+}
+
+double ScInterpreter::taylor(double* pPolynom, USHORT nMax, double x)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::taylor" );
+ double nVal = pPolynom[nMax];
+ for (short i = nMax-1; i >= 0; i--)
+ {
+ nVal = pPolynom[i] + (nVal * x);
+ }
+ return nVal;
+}
+
+double ScInterpreter::gauss(double x)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::gauss" );
+ double t0[] =
+ { 0.39894228040143268, -0.06649038006690545, 0.00997355701003582,
+ -0.00118732821548045, 0.00011543468761616, -0.00000944465625950,
+ 0.00000066596935163, -0.00000004122667415, 0.00000000227352982,
+ 0.00000000011301172, 0.00000000000511243, -0.00000000000021218 };
+ double t2[] =
+ { 0.47724986805182079, 0.05399096651318805, -0.05399096651318805,
+ 0.02699548325659403, -0.00449924720943234, -0.00224962360471617,
+ 0.00134977416282970, -0.00011783742691370, -0.00011515930357476,
+ 0.00003704737285544, 0.00000282690796889, -0.00000354513195524,
+ 0.00000037669563126, 0.00000019202407921, -0.00000005226908590,
+ -0.00000000491799345, 0.00000000366377919, -0.00000000015981997,
+ -0.00000000017381238, 0.00000000002624031, 0.00000000000560919,
+ -0.00000000000172127, -0.00000000000008634, 0.00000000000007894 };
+ double t4[] =
+ { 0.49996832875816688, 0.00013383022576489, -0.00026766045152977,
+ 0.00033457556441221, -0.00028996548915725, 0.00018178605666397,
+ -0.00008252863922168, 0.00002551802519049, -0.00000391665839292,
+ -0.00000074018205222, 0.00000064422023359, -0.00000017370155340,
+ 0.00000000909595465, 0.00000000944943118, -0.00000000329957075,
+ 0.00000000029492075, 0.00000000011874477, -0.00000000004420396,
+ 0.00000000000361422, 0.00000000000143638, -0.00000000000045848 };
+ double asympt[] = { -1.0, 1.0, -3.0, 15.0, -105.0 };
+
+ double xAbs = fabs(x);
+ USHORT xShort = (USHORT)::rtl::math::approxFloor(xAbs);
+ double nVal = 0.0;
+ if (xShort == 0)
+ nVal = taylor(t0, 11, (xAbs * xAbs)) * xAbs;
+ else if ((xShort >= 1) && (xShort <= 2))
+ nVal = taylor(t2, 23, (xAbs - 2.0));
+ else if ((xShort >= 3) && (xShort <= 4))
+ nVal = taylor(t4, 20, (xAbs - 4.0));
+ else
+ nVal = 0.5 + phi(xAbs) * taylor(asympt, 4, 1.0 / (xAbs * xAbs)) / xAbs;
+ if (x < 0.0)
+ return -nVal;
+ else
+ return nVal;
+}
+
+//
+// #i26836# new gaussinv implementation by Martin Eitzenberger <m.eitzenberger@unix.net>
+//
+
+double ScInterpreter::gaussinv(double x)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::gaussinv" );
+ double q,t,z;
+
+ q=x-0.5;
+
+ if(fabs(q)<=.425)
+ {
+ t=0.180625-q*q;
+
+ z=
+ q*
+ (
+ (
+ (
+ (
+ (
+ (
+ (
+ t*2509.0809287301226727+33430.575583588128105
+ )
+ *t+67265.770927008700853
+ )
+ *t+45921.953931549871457
+ )
+ *t+13731.693765509461125
+ )
+ *t+1971.5909503065514427
+ )
+ *t+133.14166789178437745
+ )
+ *t+3.387132872796366608
+ )
+ /
+ (
+ (
+ (
+ (
+ (
+ (
+ (
+ t*5226.495278852854561+28729.085735721942674
+ )
+ *t+39307.89580009271061
+ )
+ *t+21213.794301586595867
+ )
+ *t+5394.1960214247511077
+ )
+ *t+687.1870074920579083
+ )
+ *t+42.313330701600911252
+ )
+ *t+1.0
+ );
+
+ }
+ else
+ {
+ if(q>0) t=1-x;
+ else t=x;
+
+ t=sqrt(-log(t));
+
+ if(t<=5.0)
+ {
+ t+=-1.6;
+
+ z=
+ (
+ (
+ (
+ (
+ (
+ (
+ (
+ t*7.7454501427834140764e-4+0.0227238449892691845833
+ )
+ *t+0.24178072517745061177
+ )
+ *t+1.27045825245236838258
+ )
+ *t+3.64784832476320460504
+ )
+ *t+5.7694972214606914055
+ )
+ *t+4.6303378461565452959
+ )
+ *t+1.42343711074968357734
+ )
+ /
+ (
+ (
+ (
+ (
+ (
+ (
+ (
+ t*1.05075007164441684324e-9+5.475938084995344946e-4
+ )
+ *t+0.0151986665636164571966
+ )
+ *t+0.14810397642748007459
+ )
+ *t+0.68976733498510000455
+ )
+ *t+1.6763848301838038494
+ )
+ *t+2.05319162663775882187
+ )
+ *t+1.0
+ );
+
+ }
+ else
+ {
+ t+=-5.0;
+
+ z=
+ (
+ (
+ (
+ (
+ (
+ (
+ (
+ t*2.01033439929228813265e-7+2.71155556874348757815e-5
+ )
+ *t+0.0012426609473880784386
+ )
+ *t+0.026532189526576123093
+ )
+ *t+0.29656057182850489123
+ )
+ *t+1.7848265399172913358
+ )
+ *t+5.4637849111641143699
+ )
+ *t+6.6579046435011037772
+ )
+ /
+ (
+ (
+ (
+ (
+ (
+ (
+ (
+ t*2.04426310338993978564e-15+1.4215117583164458887e-7
+ )
+ *t+1.8463183175100546818e-5
+ )
+ *t+7.868691311456132591e-4
+ )
+ *t+0.0148753612908506148525
+ )
+ *t+0.13692988092273580531
+ )
+ *t+0.59983220655588793769
+ )
+ *t+1.0
+ );
+
+ }
+
+ if(q<0.0) z=-z;
+ }
+
+ return z;
+}
+
+double ScInterpreter::Fakultaet(double x)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Fakultaet" );
+ x = ::rtl::math::approxFloor(x);
+ if (x < 0.0)
+ return 0.0;
+ else if (x == 0.0)
+ return 1.0;
+ else if (x <= 170.0)
+ {
+ double fTemp = x;
+ while (fTemp > 2.0)
+ {
+ fTemp--;
+ x *= fTemp;
+ }
+ }
+ else
+ SetError(errNoValue);
+/* // Stirlingsche Naeherung zu ungenau
+ else
+ x = pow(x/exp(1), x) * sqrt(x) * SQRT_2_PI * (1.0 + 1.0 / (12.0 * x));
+*/
+ return x;
+}
+
+double ScInterpreter::BinomKoeff(double n, double k)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::BinomKoeff" );
+ double nVal = 0.0;
+ k = ::rtl::math::approxFloor(k);
+ if (n < k)
+ nVal = 0.0;
+ else if (k == 0.0)
+ nVal = 1.0;
+ else
+ {
+ nVal = n/k;
+ n--;
+ k--;
+ while (k > 0.0)
+ {
+ nVal *= n/k;
+ k--;
+ n--;
+ }
+/*
+ double f1 = n; // Zaehler
+ double f2 = k; // Nenner
+ n--;
+ k--;
+ while (k > 0.0)
+ {
+ f2 *= k;
+ f1 *= n;
+ k--;
+ n--;
+ }
+ nVal = f1 / f2;
+*/
+ }
+ return nVal;
+}
+
+
+// The algorithm is based on lanczos13m53 in lanczos.hpp
+// in math library from http://www.boost.org
+/** you must ensure fZ>0
+ Uses a variant of the Lanczos sum with a rational function. */
+double lcl_getLanczosSum(double fZ)
+{
+ const double fNum[13] ={
+ 23531376880.41075968857200767445163675473,
+ 42919803642.64909876895789904700198885093,
+ 35711959237.35566804944018545154716670596,
+ 17921034426.03720969991975575445893111267,
+ 6039542586.35202800506429164430729792107,
+ 1439720407.311721673663223072794912393972,
+ 248874557.8620541565114603864132294232163,
+ 31426415.58540019438061423162831820536287,
+ 2876370.628935372441225409051620849613599,
+ 186056.2653952234950402949897160456992822,
+ 8071.672002365816210638002902272250613822,
+ 210.8242777515793458725097339207133627117,
+ 2.506628274631000270164908177133837338626
+ };
+ const double fDenom[13] = {
+ 0,
+ 39916800,
+ 120543840,
+ 150917976,
+ 105258076,
+ 45995730,
+ 13339535,
+ 2637558,
+ 357423,
+ 32670,
+ 1925,
+ 66,
+ 1
+ };
+ // Horner scheme
+ double fSumNum;
+ double fSumDenom;
+ int nI;
+ double fZInv;
+ if (fZ<=1.0)
+ {
+ fSumNum = fNum[12];
+ fSumDenom = fDenom[12];
+ for (nI = 11; nI >= 0; --nI)
+ {
+ fSumNum *= fZ;
+ fSumNum += fNum[nI];
+ fSumDenom *= fZ;
+ fSumDenom += fDenom[nI];
+ }
+ }
+ else
+ // Cancel down with fZ^12; Horner scheme with reverse coefficients
+ {
+ fZInv = 1/fZ;
+ fSumNum = fNum[0];
+ fSumDenom = fDenom[0];
+ for (nI = 1; nI <=12; ++nI)
+ {
+ fSumNum *= fZInv;
+ fSumNum += fNum[nI];
+ fSumDenom *= fZInv;
+ fSumDenom += fDenom[nI];
+ }
+ }
+ return fSumNum/fSumDenom;
+}
+
+// The algorithm is based on tgamma in gamma.hpp
+// in math library from http://www.boost.org
+/** You must ensure fZ>0; fZ>171.624376956302 will overflow. */
+double lcl_GetGammaHelper(double fZ)
+{
+ double fGamma = lcl_getLanczosSum(fZ);
+ const double fg = 6.024680040776729583740234375;
+ double fZgHelp = fZ + fg - 0.5;
+ // avoid intermediate overflow
+ double fHalfpower = pow( fZgHelp, fZ / 2 - 0.25);
+ fGamma *= fHalfpower;
+ fGamma /= exp(fZgHelp);
+ fGamma *= fHalfpower;
+ if (fZ <= 20.0 && fZ == ::rtl::math::approxFloor(fZ))
+ fGamma = ::rtl::math::round(fGamma);
+ return fGamma;
+}
+
+// The algorithm is based on tgamma in gamma.hpp
+// in math library from http://www.boost.org
+/** You must ensure fZ>0 */
+double lcl_GetLogGammaHelper(double fZ)
+{
+ const double fg = 6.024680040776729583740234375;
+ double fZgHelp = fZ + fg - 0.5;
+ return log( lcl_getLanczosSum(fZ)) + (fZ-0.5) * log(fZgHelp) - fZgHelp;
+}
+
+/** You must ensure non integer arguments for fZ<1 */
+double ScInterpreter::GetGamma(double fZ)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGamma" );
+ const double fLogPi = log(F_PI);
+ const double fLogDblMax = log( ::std::numeric_limits<double>::max());
+
+ if (fZ > fMaxGammaArgument)
+ {
+ SetError(errIllegalFPOperation);
+ return HUGE_VAL;
+ }
+
+ if (fZ >= 1.0)
+ return lcl_GetGammaHelper(fZ);
+
+ if (fZ >= 0.5) // shift to x>=1 using Gamma(x)=Gamma(x+1)/x
+ return lcl_GetGammaHelper(fZ+1) / fZ;
+
+ if (fZ >= -0.5) // shift to x>=1, might overflow
+ {
+ double fLogTest = lcl_GetLogGammaHelper(fZ+2) - log(fZ+1) - log( fabs(fZ));
+ if (fLogTest >= fLogDblMax)
+ {
+ SetError( errIllegalFPOperation);
+ return HUGE_VAL;
+ }
+ return lcl_GetGammaHelper(fZ+2) / (fZ+1) / fZ;
+ }
+ // fZ<-0.5
+ // Use Euler's reflection formula: gamma(x)= pi/ ( gamma(1-x)*sin(pi*x) )
+ double fLogDivisor = lcl_GetLogGammaHelper(1-fZ) + log( fabs( ::rtl::math::sin( F_PI*fZ)));
+ if (fLogDivisor - fLogPi >= fLogDblMax) // underflow
+ return 0.0;
+
+ if (fLogDivisor<0.0)
+ if (fLogPi - fLogDivisor > fLogDblMax) // overflow
+ {
+ SetError(errIllegalFPOperation);
+ return HUGE_VAL;
+ }
+
+ return exp( fLogPi - fLogDivisor) * ((::rtl::math::sin( F_PI*fZ) < 0.0) ? -1.0 : 1.0);
+}
+
+
+/** You must ensure fZ>0 */
+double ScInterpreter::GetLogGamma(double fZ)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetLogGamma" );
+ if (fZ >= fMaxGammaArgument)
+ return lcl_GetLogGammaHelper(fZ);
+ if (fZ >= 1.0)
+ return log(lcl_GetGammaHelper(fZ));
+ if (fZ >= 0.5)
+ return log( lcl_GetGammaHelper(fZ+1) / fZ);
+ return lcl_GetLogGammaHelper(fZ+2) - log(fZ+1) - log(fZ);
+}
+
+double ScInterpreter::GetFDist(double x, double fF1, double fF2)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetFDist" );
+ double arg = fF2/(fF2+fF1*x);
+ double alpha = fF2/2.0;
+ double beta = fF1/2.0;
+ return (GetBetaDist(arg, alpha, beta));
+/*
+ double Z = (pow(fF,1.0/3.0)*(1.0-2.0/(9.0*fF2)) - (1.0-2.0/(9.0*fF1))) /
+ sqrt(2.0/(9.0*fF1) + pow(fF,2.0/3.0)*2.0/(9.0*fF2));
+ return (0.5-gauss(Z));
+*/
+}
+
+double ScInterpreter::GetTDist(double T, double fDF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetTDist" );
+ return 0.5 * GetBetaDist(fDF/(fDF+T*T), fDF/2.0, 0.5);
+/*
+ USHORT DF = (USHORT) fDF;
+ double A = T / sqrt(DF);
+ double B = 1.0 + A*A;
+ double R;
+ if (DF == 1)
+ R = 0.5 + atan(A)/F_PI;
+ else if (DF % 2 == 0)
+ {
+ double S0 = A/(2.0 * sqrt(B));
+ double C0 = S0;
+ for (USHORT i = 2; i <= DF-2; i+=2)
+ {
+ C0 *= (1.0 - 1.0/(double)i)/B;
+ S0 += C0;
+ }
+ R = 0.5 + S0;
+ }
+ else
+ {
+ double S1 = A / (B * F_PI);
+ double C1 = S1;
+ for (USHORT i = 3; i <= DF-2; i+=2)
+ {
+ C1 *= (1.0 - 1.0/(double)i)/B;
+ S1 += C1;
+ }
+ R = 0.5 + atan(A)/F_PI + S1;
+ }
+ return 1.0 - R;
+*/
+}
+
+// for LEGACY.CHIDIST, returns right tail, fDF=degrees of freedom
+/** You must ensure fDF>0.0 */
+double ScInterpreter::GetChiDist(double fX, double fDF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetChiDist" );
+ if (fX <= 0.0)
+ return 1.0; // see ODFF
+ else
+ return GetUpRegIGamma( fDF/2.0, fX/2.0);
+}
+
+// ready for ODF 1.2
+// for ODF CHISQDIST; cumulative distribution function, fDF=degrees of freedom
+// returns left tail
+/** You must ensure fDF>0.0 */
+double ScInterpreter::GetChiSqDistCDF(double fX, double fDF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetChiSqDistCDF" );
+ if (fX <= 0.0)
+ return 0.0; // see ODFF
+ else
+ return GetLowRegIGamma( fDF/2.0, fX/2.0);
+}
+
+double ScInterpreter::GetChiSqDistPDF(double fX, double fDF)
+{
+ // you must ensure fDF is positive integer
+ double fValue;
+ double fCount;
+ if (fX <= 0.0)
+ return 0.0; // see ODFF
+ if (fDF*fX > 1391000.0)
+ {
+ // intermediate invalid values, use log
+ fValue = exp((0.5*fDF - 1) * log(fX*0.5) - 0.5 * fX - log(2.0) - GetLogGamma(0.5*fDF));
+ }
+ else // fDF is small in most cases, we can iterate
+ {
+ if (fmod(fDF,2.0)<0.5)
+ {
+ // even
+ fValue = 0.5;
+ fCount = 2.0;
+ }
+ else
+ {
+ fValue = 1/sqrt(fX*2*F_PI);
+ fCount = 1.0;
+ }
+ while ( fCount < fDF)
+ {
+ fValue *= (fX / fCount);
+ fCount += 2.0;
+ }
+ if (fX>=1425.0) // underflow in e^(-x/2)
+ fValue = exp(log(fValue)-fX/2);
+ else
+ fValue *= exp(-fX/2);
+ }
+ return fValue;
+}
+
+void ScInterpreter::ScChiSqDist()
+{
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
+ return;
+ double fX;
+ bool bCumulative;
+ if (nParamCount == 3)
+ bCumulative = GetBool();
+ else
+ bCumulative = true;
+ double fDF = ::rtl::math::approxFloor(GetDouble());
+ if (fDF < 1.0)
+ PushIllegalArgument();
+ else
+ {
+ fX = GetDouble();
+ if (bCumulative)
+ PushDouble(GetChiSqDistCDF(fX,fDF));
+ else
+ PushDouble(GetChiSqDistPDF(fX,fDF));
+ }
+}
+
+void ScInterpreter::ScGamma()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGamma" );
+ double x = GetDouble();
+ double fResult;
+ if (x <= 0.0 && x == ::rtl::math::approxFloor(x))
+ PushIllegalArgument();
+ else
+ {
+ fResult = GetGamma(x);
+ if (nGlobalError)
+ {
+ PushError( nGlobalError);
+ return;
+ }
+ PushDouble(fResult);
+ }
+}
+
+
+void ScInterpreter::ScLogGamma()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLogGamma" );
+ double x = GetDouble();
+ if (x > 0.0) // constraint from ODFF
+ PushDouble( GetLogGamma(x));
+ else
+ PushIllegalArgument();
+}
+
+double ScInterpreter::GetBeta(double fAlpha, double fBeta)
+{
+ double fA;
+ double fB;
+ if (fAlpha > fBeta)
+ {
+ fA = fAlpha; fB = fBeta;
+ }
+ else
+ {
+ fA = fBeta; fB = fAlpha;
+ }
+ if (fA+fB < fMaxGammaArgument) // simple case
+ return GetGamma(fA)/GetGamma(fA+fB)*GetGamma(fB);
+ // need logarithm
+ // GetLogGamma is not accurate enough, back to Lanczos for all three
+ // GetGamma and arrange factors newly.
+ const double fg = 6.024680040776729583740234375; //see GetGamma
+ double fgm = fg - 0.5;
+ double fLanczos = lcl_getLanczosSum(fA);
+ fLanczos /= lcl_getLanczosSum(fA+fB);
+ fLanczos *= lcl_getLanczosSum(fB);
+ double fABgm = fA+fB+fgm;
+ fLanczos *= sqrt((fABgm/(fA+fgm))/(fB+fgm));
+ double fTempA = fB/(fA+fgm); // (fA+fgm)/fABgm = 1 / ( 1 + fB/(fA+fgm))
+ double fTempB = fA/(fB+fgm);
+ double fResult = exp(-fA * ::rtl::math::log1p(fTempA)
+ -fB * ::rtl::math::log1p(fTempB)-fgm);
+ fResult *= fLanczos;
+ return fResult;
+}
+
+// Same as GetBeta but with logarithm
+double ScInterpreter::GetLogBeta(double fAlpha, double fBeta)
+{
+ double fA;
+ double fB;
+ if (fAlpha > fBeta)
+ {
+ fA = fAlpha; fB = fBeta;
+ }
+ else
+ {
+ fA = fBeta; fB = fAlpha;
+ }
+ const double fg = 6.024680040776729583740234375; //see GetGamma
+ double fgm = fg - 0.5;
+ double fLanczos = lcl_getLanczosSum(fA);
+ fLanczos /= lcl_getLanczosSum(fA+fB);
+ fLanczos *= lcl_getLanczosSum(fB);
+ double fLogLanczos = log(fLanczos);
+ double fABgm = fA+fB+fgm;
+ fLogLanczos += 0.5*(log(fABgm)-log(fA+fgm)-log(fB+fgm));
+ double fTempA = fB/(fA+fgm); // (fA+fgm)/fABgm = 1 / ( 1 + fB/(fA+fgm))
+ double fTempB = fA/(fB+fgm);
+ double fResult = -fA * ::rtl::math::log1p(fTempA)
+ -fB * ::rtl::math::log1p(fTempB)-fgm;
+ fResult += fLogLanczos;
+ return fResult;
+}
+
+// beta distribution probability density function
+double ScInterpreter::GetBetaDistPDF(double fX, double fA, double fB)
+{
+ // special cases
+ if (fA == 1.0) // result b*(1-x)^(b-1)
+ {
+ if (fB == 1.0)
+ return 1.0;
+ if (fB == 2.0)
+ return -2.0*fX + 2.0;
+ if (fX == 1.0 && fB < 1.0)
+ {
+ SetError(errIllegalArgument);
+ return HUGE_VAL;
+ }
+ if (fX <= 0.01)
+ return fB + fB * ::rtl::math::expm1((fB-1.0) * ::rtl::math::log1p(-fX));
+ else
+ return fB * pow(0.5-fX+0.5,fB-1.0);
+ }
+ if (fB == 1.0) // result a*x^(a-1)
+ {
+ if (fA == 2.0)
+ return fA * fX;
+ if (fX == 0.0 && fA < 1.0)
+ {
+ SetError(errIllegalArgument);
+ return HUGE_VAL;
+ }
+ return fA * pow(fX,fA-1);
+ }
+ if (fX <= 0.0)
+ {
+ if (fA < 1.0 && fX == 0.0)
+ {
+ SetError(errIllegalArgument);
+ return HUGE_VAL;
+ }
+ else
+ return 0.0;
+ }
+ if (fX >= 1.0)
+ {
+ if (fB < 1.0 && fX == 1.0)
+ {
+ SetError(errIllegalArgument);
+ return HUGE_VAL;
+ }
+ else
+ return 0.0;
+ }
+
+ // normal cases; result x^(a-1)*(1-x)^(b-1)/Beta(a,b)
+ const double fLogDblMax = log( ::std::numeric_limits<double>::max());
+ const double fLogDblMin = log( ::std::numeric_limits<double>::min());
+ double fLogY = (fX < 0.1) ? ::rtl::math::log1p(-fX) : log(0.5-fX+0.5);
+ double fLogX = log(fX);
+ double fAm1 = fA-1.0;
+ double fBm1 = fB-1.0;
+ double fLogBeta = GetLogBeta(fA,fB);
+ // check whether parts over- or underflow
+ if ( fAm1 * fLogX < fLogDblMax && fAm1 * fLogX > fLogDblMin
+ && fBm1 * fLogY < fLogDblMax && fBm1* fLogY > fLogDblMin
+ && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin )
+ return pow(fX,fA-1.0) * pow(0.5-fX+0.5,fB-1.0) / GetBeta(fA,fB);
+ else // need logarithm;
+ // might overflow as a whole, but seldom, not worth to pre-detect it
+ return exp((fA-1.0)*fLogX + (fB-1.0)* fLogY - fLogBeta);
+}
+
+
+/*
+ x^a * (1-x)^b
+ I_x(a,b) = ---------------- * result of ContFrac
+ a * Beta(a,b)
+*/
+double lcl_GetBetaHelperContFrac(double fX, double fA, double fB)
+{ // like old version
+ double a1, b1, a2, b2, fnorm, apl2m, d2m, d2m1, cfnew, cf;
+ a1 = 1.0; b1 = 1.0;
+ b2 = 1.0 - (fA+fB)/(fA+1.0)*fX;
+ if (b2 == 0.0)
+ {
+ a2 = 0.0;
+ fnorm = 1.0;
+ cf = 1.0;
+ }
+ else
+ {
+ a2 = 1.0;
+ fnorm = 1.0/b2;
+ cf = a2*fnorm;
+ }
+ cfnew = 1.0;
+ double rm = 1.0;
+
+ const double fMaxIter = 50000.0;
+ // loop security, normal cases converge in less than 100 iterations.
+ // FIXME: You will get so much iteratons for fX near mean,
+ // I do not know a better algorithm.
+ bool bfinished = false;
+ do
+ {
+ apl2m = fA + 2.0*rm;
+ d2m = rm*(fB-rm)*fX/((apl2m-1.0)*apl2m);
+ d2m1 = -(fA+rm)*(fA+fB+rm)*fX/(apl2m*(apl2m+1.0));
+ a1 = (a2+d2m*a1)*fnorm;
+ b1 = (b2+d2m*b1)*fnorm;
+ a2 = a1 + d2m1*a2*fnorm;
+ b2 = b1 + d2m1*b2*fnorm;
+ if (b2 != 0.0)
+ {
+ fnorm = 1.0/b2;
+ cfnew = a2*fnorm;
+ bfinished = (fabs(cf-cfnew) < fabs(cf)*fMachEps);
+ }
+ cf = cfnew;
+ rm += 1.0;
+ }
+ while (rm < fMaxIter && !bfinished);
+ return cf;
+}
+
+// cumulative distribution function, normalized
+double ScInterpreter::GetBetaDist(double fXin, double fAlpha, double fBeta)
+{
+// special cases
+ if (fXin <= 0.0) // values are valid, see spec
+ return 0.0;
+ if (fXin >= 1.0) // values are valid, see spec
+ return 1.0;
+ if (fBeta == 1.0)
+ return pow(fXin, fAlpha);
+ if (fAlpha == 1.0)
+ // 1.0 - pow(1.0-fX,fBeta) is not accurate enough
+ return -::rtl::math::expm1(fBeta * ::rtl::math::log1p(-fXin));
+ //FIXME: need special algorithm for fX near fP for large fA,fB
+ double fResult;
+ // I use always continued fraction, power series are neither
+ // faster nor more accurate.
+ double fY = (0.5-fXin)+0.5;
+ double flnY = ::rtl::math::log1p(-fXin);
+ double fX = fXin;
+ double flnX = log(fXin);
+ double fA = fAlpha;
+ double fB = fBeta;
+ bool bReflect = fXin > fAlpha/(fAlpha+fBeta);
+ if (bReflect)
+ {
+ fA = fBeta;
+ fB = fAlpha;
+ fX = fY;
+ fY = fXin;
+ flnX = flnY;
+ flnY = log(fXin);
+ }
+ fResult = lcl_GetBetaHelperContFrac(fX,fA,fB);
+ fResult = fResult/fA;
+ double fP = fA/(fA+fB);
+ double fQ = fB/(fA+fB);
+ double fTemp;
+ if (fA > 1.0 && fB > 1.0 && fP < 0.97 && fQ < 0.97) //found experimental
+ fTemp = GetBetaDistPDF(fX,fA,fB)*fX*fY;
+ else
+ fTemp = exp(fA*flnX + fB*flnY - GetLogBeta(fA,fB));
+ fResult *= fTemp;
+ if (bReflect)
+ fResult = 0.5 - fResult + 0.5;
+ if (fResult > 1.0) // ensure valid range
+ fResult = 1.0;
+ if (fResult < 0.0)
+ fResult = 0.0;
+ return fResult;
+}
+
+ void ScInterpreter::ScBetaDist()
+ {
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 6 ) ) // expanded, see #i91547#
+ return;
+ double fLowerBound, fUpperBound;
+ double alpha, beta, x;
+ bool bIsCumulative;
+ if (nParamCount == 6)
+ bIsCumulative = GetBool();
+ else
+ bIsCumulative = true;
+ if (nParamCount >= 5)
+ fUpperBound = GetDouble();
+ else
+ fUpperBound = 1.0;
+ if (nParamCount >= 4)
+ fLowerBound = GetDouble();
+ else
+ fLowerBound = 0.0;
+ beta = GetDouble();
+ alpha = GetDouble();
+ x = GetDouble();
+ double fScale = fUpperBound - fLowerBound;
+ if (fScale <= 0.0 || alpha <= 0.0 || beta <= 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (bIsCumulative) // cumulative distribution function
+ {
+ // special cases
+ if (x < fLowerBound)
+ {
+ PushDouble(0.0); return; //see spec
+ }
+ if (x > fUpperBound)
+ {
+ PushDouble(1.0); return; //see spec
+ }
+ // normal cases
+ x = (x-fLowerBound)/fScale; // convert to standard form
+ PushDouble(GetBetaDist(x, alpha, beta));
+ return;
+ }
+ else // probability density function
+ {
+ if (x < fLowerBound || x > fUpperBound)
+ {
+ PushDouble(0.0);
+ return;
+ }
+ x = (x-fLowerBound)/fScale;
+ PushDouble(GetBetaDistPDF(x, alpha, beta)/fScale);
+ return;
+ }
+}
+
+void ScInterpreter::ScPhi()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPhi" );
+ PushDouble(phi(GetDouble()));
+}
+
+void ScInterpreter::ScGauss()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGauss" );
+ PushDouble(gauss(GetDouble()));
+}
+
+void ScInterpreter::ScFisher()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFisher" );
+ double fVal = GetDouble();
+ if (fabs(fVal) >= 1.0)
+ PushIllegalArgument();
+ else
+ PushDouble( ::rtl::math::atanh( fVal));
+}
+
+void ScInterpreter::ScFisherInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFisherInv" );
+ PushDouble( tanh( GetDouble()));
+}
+
+void ScInterpreter::ScFact()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFact" );
+ double nVal = GetDouble();
+ if (nVal < 0.0)
+ PushIllegalArgument();
+ else
+ PushDouble(Fakultaet(nVal));
+}
+
+void ScInterpreter::ScKombin()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKombin" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double k = ::rtl::math::approxFloor(GetDouble());
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (k < 0.0 || n < 0.0 || k > n)
+ PushIllegalArgument();
+ else
+ PushDouble(BinomKoeff(n, k));
+ }
+}
+
+void ScInterpreter::ScKombin2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKombin2" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double k = ::rtl::math::approxFloor(GetDouble());
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (k < 0.0 || n < 0.0 || k > n)
+ PushIllegalArgument();
+ else
+ PushDouble(BinomKoeff(n + k - 1, k));
+ }
+}
+
+void ScInterpreter::ScVariationen()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVariationen" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double k = ::rtl::math::approxFloor(GetDouble());
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (n < 0.0 || k < 0.0 || k > n)
+ PushIllegalArgument();
+ else if (k == 0.0)
+ PushInt(1); // (n! / (n - 0)!) == 1
+ else
+ {
+ double nVal = n;
+ for (ULONG i = (ULONG)k-1; i >= 1; i--)
+ nVal *= n-(double)i;
+ PushDouble(nVal);
+ }
+ }
+}
+
+void ScInterpreter::ScVariationen2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVariationen2" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ double k = ::rtl::math::approxFloor(GetDouble());
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (n < 0.0 || k < 0.0 || k > n)
+ PushIllegalArgument();
+ else
+ PushDouble(pow(n,k));
+ }
+}
+
+void ScInterpreter::ScB()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScB" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
+ return ;
+ if (nParamCount == 3)
+ {
+ double x = ::rtl::math::approxFloor(GetDouble());
+ double p = GetDouble();
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0)
+ PushIllegalArgument();
+ else
+ {
+ double q = 1.0 - p;
+ double fFactor = pow(q, n);
+ if (fFactor == 0.0)
+ {
+ fFactor = pow(p, n);
+ if (fFactor == 0.0)
+ PushNoValue();
+ else
+ {
+ ULONG max = (ULONG) (n - x);
+ for (ULONG i = 0; i < max && fFactor > 0.0; i++)
+ fFactor *= (n-i)/(i+1)*q/p;
+ PushDouble(fFactor);
+ }
+ }
+ else
+ {
+ ULONG max = (ULONG) x;
+ for (ULONG i = 0; i < max && fFactor > 0.0; i++)
+ fFactor *= (n-i)/(i+1)*p/q;
+ PushDouble(fFactor);
+ }
+ }
+ }
+ else if (nParamCount == 4)
+ {
+ double xe = GetDouble();
+ double xs = GetDouble();
+ double p = GetDouble();
+ double n = GetDouble();
+// alter Stand 300-SC
+// if ((xs < n) && (xe < n) && (p < 1.0))
+// {
+// double Varianz = sqrt(n * p * (1.0 - p));
+// xs = fabs(xs - (n * p /* / 2.0 STE */ ));
+// xe = fabs(xe - (n * p /* / 2.0 STE */ ));
+//// STE double nVal = gauss((xs + 0.5) / Varianz) + gauss((xe + 0.5) / Varianz);
+// double nVal = fabs(gauss(xs / Varianz) - gauss(xe / Varianz));
+// PushDouble(nVal);
+// }
+ bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <= n);
+ if ( bIsValidX && 0.0 < p && p < 1.0 )
+ {
+ double q = 1.0 - p;
+ double fFactor = pow(q, n);
+ if (fFactor == 0.0)
+ {
+ fFactor = pow(p, n);
+ if (fFactor == 0.0)
+ PushNoValue();
+ else
+ {
+ double fSum = 0.0;
+ ULONG max;
+ if (xe < (ULONG) n)
+ max = (ULONG) (n-xe)-1;
+ else
+ max = 0;
+ ULONG i;
+ for (i = 0; i < max && fFactor > 0.0; i++)
+ fFactor *= (n-i)/(i+1)*q/p;
+ if (xs < (ULONG) n)
+ max = (ULONG) (n-xs);
+ else
+ fSum = fFactor;
+ for (; i < max && fFactor > 0.0; i++)
+ {
+ fFactor *= (n-i)/(i+1)*q/p;
+ fSum += fFactor;
+ }
+ PushDouble(fSum);
+ }
+ }
+ else
+ {
+ ULONG max;
+ double fSum;
+ if ( (ULONG) xs == 0)
+ {
+ fSum = fFactor;
+ max = 0;
+ }
+ else
+ {
+ max = (ULONG) xs-1;
+ fSum = 0.0;
+ }
+ ULONG i;
+ for (i = 0; i < max && fFactor > 0.0; i++)
+ fFactor *= (n-i)/(i+1)*p/q;
+ if ((ULONG)xe == 0) // beide 0
+ fSum = fFactor;
+ else
+ max = (ULONG) xe;
+ for (; i < max && fFactor > 0.0; i++)
+ {
+ fFactor *= (n-i)/(i+1)*p/q;
+ fSum += fFactor;
+ }
+ PushDouble(fSum);
+ }
+ }
+ else
+ {
+ if ( bIsValidX ) // not(0<p<1)
+ {
+ if ( p == 0.0 )
+ PushDouble( (xs == 0.0) ? 1.0 : 0.0 );
+ else if ( p == 1.0 )
+ PushDouble( (xe == n) ? 1.0 : 0.0 );
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushIllegalArgument();
+ }
+ }
+}
+
+void ScInterpreter::ScBinomDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBinomDist" );
+ if ( MustHaveParamCount( GetByte(), 4 ) )
+ {
+ double kum = GetDouble(); // 0 oder 1
+ double p = GetDouble(); // p
+ double n = ::rtl::math::approxFloor(GetDouble()); // n
+ double x = ::rtl::math::approxFloor(GetDouble()); // x
+ double fFactor, q, fSum;
+ if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0)
+ PushIllegalArgument();
+ else if (kum == 0.0) // Dichte
+ {
+ q = 1.0 - p;
+ fFactor = pow(q, n);
+ if (fFactor == 0.0)
+ {
+ fFactor = pow(p, n);
+ if (fFactor == 0.0)
+ PushNoValue();
+ else
+ {
+ ULONG max = (ULONG) (n - x);
+ for (ULONG i = 0; i < max && fFactor > 0.0; i++)
+ fFactor *= (n-i)/(i+1)*q/p;
+ PushDouble(fFactor);
+ }
+ }
+ else
+ {
+ ULONG max = (ULONG) x;
+ for (ULONG i = 0; i < max && fFactor > 0.0; i++)
+ fFactor *= (n-i)/(i+1)*p/q;
+ PushDouble(fFactor);
+ }
+ }
+ else // Verteilung
+ {
+ if (n == x)
+ PushDouble(1.0);
+ else
+ {
+ q = 1.0 - p;
+ fFactor = pow(q, n);
+ if (fFactor == 0.0)
+ {
+ fFactor = pow(p, n);
+ if (fFactor == 0.0)
+ PushNoValue();
+ else
+ {
+ fSum = 1.0 - fFactor;
+ ULONG max = (ULONG) (n - x) - 1;
+ for (ULONG i = 0; i < max && fFactor > 0.0; i++)
+ {
+ fFactor *= (n-i)/(i+1)*q/p;
+ fSum -= fFactor;
+ }
+ if (fSum < 0.0)
+ PushDouble(0.0);
+ else
+ PushDouble(fSum);
+ }
+ }
+ else
+ {
+ fSum = fFactor;
+ ULONG max = (ULONG) x;
+ for (ULONG i = 0; i < max && fFactor > 0.0; i++)
+ {
+ fFactor *= (n-i)/(i+1)*p/q;
+ fSum += fFactor;
+ }
+ PushDouble(fSum);
+ }
+ }
+ }
+ }
+}
+
+void ScInterpreter::ScCritBinom()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCritBinom" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double alpha = GetDouble(); // alpha
+ double p = GetDouble(); // p
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (n < 0.0 || alpha <= 0.0 || alpha >= 1.0 || p < 0.0 || p > 1.0)
+ PushIllegalArgument();
+ else
+ {
+ double q = 1.0 - p;
+ double fFactor = pow(q,n);
+ if (fFactor == 0.0)
+ {
+ fFactor = pow(p, n);
+ if (fFactor == 0.0)
+ PushNoValue();
+ else
+ {
+ double fSum = 1.0 - fFactor; ULONG max = (ULONG) n;
+ ULONG i;
+
+ for ( i = 0; i < max && fSum >= alpha; i++)
+ {
+ fFactor *= (n-i)/(i+1)*q/p;
+ fSum -= fFactor;
+ }
+ PushDouble(n-i);
+ }
+ }
+ else
+ {
+ double fSum = fFactor; ULONG max = (ULONG) n;
+ ULONG i;
+
+ for ( i = 0; i < max && fSum < alpha; i++)
+ {
+ fFactor *= (n-i)/(i+1)*p/q;
+ fSum += fFactor;
+ }
+ PushDouble(i);
+ }
+ }
+ }
+}
+
+void ScInterpreter::ScNegBinomDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNegBinomDist" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double p = GetDouble(); // p
+ double r = GetDouble(); // r
+ double x = GetDouble(); // x
+ if (r < 0.0 || x < 0.0 || p < 0.0 || p > 1.0)
+ PushIllegalArgument();
+ else
+ {
+ double q = 1.0 - p;
+ double fFactor = pow(p,r);
+ for (double i = 0.0; i < x; i++)
+ fFactor *= (i+r)/(i+1.0)*q;
+ PushDouble(fFactor);
+ }
+ }
+}
+
+void ScInterpreter::ScNormDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNormDist" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 4))
+ return;
+ bool bCumulative = nParamCount == 4 ? GetBool() : true;
+ double sigma = GetDouble(); // standard deviation
+ double mue = GetDouble(); // mean
+ double x = GetDouble(); // x
+ if (sigma <= 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (bCumulative)
+ PushDouble(integralPhi((x-mue)/sigma));
+ else
+ PushDouble(phi((x-mue)/sigma)/sigma);
+}
+
+void ScInterpreter::ScLogNormDist() //expanded, see #i100119#
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLogNormDist" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 1, 4))
+ return;
+ bool bCumulative = nParamCount == 4 ? GetBool() : true; // cumulative
+ double sigma = nParamCount >= 3 ? GetDouble() : 1.0; // standard deviation
+ double mue = nParamCount >= 2 ? GetDouble() : 0.0; // mean
+ double x = GetDouble(); // x
+ if (sigma <= 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (bCumulative)
+ { // cumulative
+ if (x <= 0.0)
+ PushDouble(0.0);
+ else
+ PushDouble(integralPhi((log(x)-mue)/sigma));
+ }
+ else
+ { // density
+ if (x <= 0.0)
+ PushIllegalArgument();
+ else
+ PushDouble(phi((log(x)-mue)/sigma)/sigma/x);
+ }
+}
+
+void ScInterpreter::ScStdNormDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStdNormDist" );
+ PushDouble(integralPhi(GetDouble()));
+}
+
+void ScInterpreter::ScExpDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExpDist" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double kum = GetDouble(); // 0 oder 1
+ double lambda = GetDouble(); // lambda
+ double x = GetDouble(); // x
+ if (lambda <= 0.0)
+ PushIllegalArgument();
+ else if (kum == 0.0) // Dichte
+ {
+ if (x >= 0.0)
+ PushDouble(lambda * exp(-lambda*x));
+ else
+ PushInt(0);
+ }
+ else // Verteilung
+ {
+ if (x > 0.0)
+ PushDouble(1.0 - exp(-lambda*x));
+ else
+ PushInt(0);
+ }
+ }
+}
+
+void ScInterpreter::ScTDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTDist" );
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+ double fFlag = ::rtl::math::approxFloor(GetDouble());
+ double fDF = ::rtl::math::approxFloor(GetDouble());
+ double T = GetDouble();
+ if (fDF < 1.0 || T < 0.0 || (fFlag != 1.0 && fFlag != 2.0) )
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double R = GetTDist(T, fDF);
+ if (fFlag == 1.0)
+ PushDouble(R);
+ else
+ PushDouble(2.0*R);
+}
+
+void ScInterpreter::ScFDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFDist" );
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+ double fF2 = ::rtl::math::approxFloor(GetDouble());
+ double fF1 = ::rtl::math::approxFloor(GetDouble());
+ double fF = GetDouble();
+ if (fF < 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ PushDouble(GetFDist(fF, fF1, fF2));
+}
+
+void ScInterpreter::ScChiDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChiDist" );
+ double fResult;
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double fDF = ::rtl::math::approxFloor(GetDouble());
+ double fChi = GetDouble();
+ if (fDF < 1.0) // x<=0 returns 1, see ODFF 6.17.10
+ {
+ PushIllegalArgument();
+ return;
+ }
+ fResult = GetChiDist( fChi, fDF);
+ if (nGlobalError)
+ {
+ PushError( nGlobalError);
+ return;
+ }
+ PushDouble(fResult);
+}
+
+void ScInterpreter::ScWeibull()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScWeibull" );
+ if ( MustHaveParamCount( GetByte(), 4 ) )
+ {
+ double kum = GetDouble(); // 0 oder 1
+ double beta = GetDouble(); // beta
+ double alpha = GetDouble(); // alpha
+ double x = GetDouble(); // x
+ if (alpha <= 0.0 || beta <= 0.0 || x < 0.0)
+ PushIllegalArgument();
+ else if (kum == 0.0) // Dichte
+ PushDouble(alpha/pow(beta,alpha)*pow(x,alpha-1.0)*
+ exp(-pow(x/beta,alpha)));
+ else // Verteilung
+ PushDouble(1.0 - exp(-pow(x/beta,alpha)));
+ }
+}
+
+void ScInterpreter::ScPoissonDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPoissonDist" );
+ BYTE nParamCount = GetByte();
+ if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ {
+ bool bCumulative = (nParamCount == 3 ? GetBool() : true); // default cumulative
+ double lambda = GetDouble(); // Mean
+ double x = ::rtl::math::approxFloor(GetDouble()); // discrete distribution
+ if (lambda < 0.0 || x < 0.0)
+ PushIllegalArgument();
+ else if (!bCumulative) // Probability mass function
+ {
+ if (lambda == 0.0)
+ PushInt(0);
+ else
+ {
+ if (lambda >712) // underflow in exp(-lambda)
+ { // accuracy 11 Digits
+ PushDouble( exp(x*log(lambda)-lambda-GetLogGamma(x+1.0)));
+ }
+ else
+ {
+ double fPoissonVar = 1.0;
+ for ( double f = 0.0; f < x; ++f )
+ fPoissonVar *= lambda / ( f + 1.0 );
+ PushDouble( fPoissonVar * exp( -lambda ) );
+ }
+ }
+ }
+ else // Cumulative distribution function
+ {
+ if (lambda == 0.0)
+ PushInt(1);
+ else
+ {
+ if (lambda > 712 ) // underflow in exp(-lambda)
+ { // accuracy 12 Digits
+ PushDouble(GetUpRegIGamma(x+1.0,lambda));
+ }
+ else
+ {
+ if (x >= 936.0) // result is always undistinghable from 1
+ PushDouble (1.0);
+ else
+ {
+ double fSummand = exp(-lambda);
+ double fSum = fSummand;
+ int nEnd = sal::static_int_cast<int>( x );
+ for (int i = 1; i <= nEnd; i++)
+ {
+ fSummand = (fSummand * lambda)/(double)i;
+ fSum += fSummand;
+ }
+ PushDouble(fSum);
+ }
+ }
+ }
+ }
+ }
+}
+
+/** Local function used in the calculation of the hypergeometric distribution.
+ */
+void lcl_PutFactorialElements( ::std::vector< double >& cn, double fLower, double fUpper, double fBase )
+{
+ for ( double i = fLower; i <= fUpper; ++i )
+ {
+ double fVal = fBase - i;
+ if ( fVal > 1.0 )
+ cn.push_back( fVal );
+ }
+}
+
+/** Calculates a value of the hypergeometric distribution.
+
+ The algorithm is designed to avoid unnecessary multiplications and division
+ by expanding all factorial elements (9 of them). It is done by excluding
+ those ranges that overlap in the numerator and the denominator. This allows
+ for a fast calculation for large values which would otherwise cause an overflow
+ in the intermediate values.
+
+ @author Kohei Yoshida <kohei@openoffice.org>
+
+ @see #i47296#
+
+ */
+void ScInterpreter::ScHypGeomDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHypGeomDist" );
+ const size_t nMaxArraySize = 500000; // arbitrary max array size
+
+ if ( !MustHaveParamCount( GetByte(), 4 ) )
+ return;
+
+ double N = ::rtl::math::approxFloor(GetDouble());
+ double M = ::rtl::math::approxFloor(GetDouble());
+ double n = ::rtl::math::approxFloor(GetDouble());
+ double x = ::rtl::math::approxFloor(GetDouble());
+
+ if( (x < 0.0) || (n < x) || (M < x) || (N < n) || (N < M) || (x < n - N + M) )
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ typedef ::std::vector< double > HypContainer;
+ HypContainer cnNumer, cnDenom;
+
+ size_t nEstContainerSize = static_cast<size_t>( x + ::std::min( n, M ) );
+ size_t nMaxSize = ::std::min( cnNumer.max_size(), nMaxArraySize );
+ if ( nEstContainerSize > nMaxSize )
+ {
+ PushNoValue();
+ return;
+ }
+ cnNumer.reserve( nEstContainerSize + 10 );
+ cnDenom.reserve( nEstContainerSize + 10 );
+
+ // Trim coefficient C first
+ double fCNumVarUpper = N - n - M + x - 1.0;
+ double fCDenomVarLower = 1.0;
+ if ( N - n - M + x >= M - x + 1.0 )
+ {
+ fCNumVarUpper = M - x - 1.0;
+ fCDenomVarLower = N - n - 2.0*(M - x) + 1.0;
+ }
+
+#ifdef DBG_UTIL
+ double fCNumLower = N - n - fCNumVarUpper;
+#endif
+ double fCDenomUpper = N - n - M + x + 1.0 - fCDenomVarLower;
+
+ double fDNumVarLower = n - M;
+
+ if ( n >= M + 1.0 )
+ {
+ if ( N - M < n + 1.0 )
+ {
+ // Case 1
+
+ if ( N - n < n + 1.0 )
+ {
+ // no overlap
+ lcl_PutFactorialElements( cnNumer, 0.0, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, N - n - 1.0, N );
+ }
+ else
+ {
+ // overlap
+ DBG_ASSERT( fCNumLower < n + 1.0, "ScHypGeomDist: wrong assertion" );
+ lcl_PutFactorialElements( cnNumer, N - 2.0*n, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, n - 1.0, N );
+ }
+
+ DBG_ASSERT( fCDenomUpper <= N - M, "ScHypGeomDist: wrong assertion" );
+
+ if ( fCDenomUpper < n - x + 1.0 )
+ // no overlap
+ lcl_PutFactorialElements( cnNumer, 1.0, N - M - n + x, N - M + 1.0 );
+ else
+ {
+ // overlap
+ lcl_PutFactorialElements( cnNumer, 1.0, N - M - fCDenomUpper, N - M + 1.0 );
+
+ fCDenomUpper = n - x;
+ fCDenomVarLower = N - M - 2.0*(n - x) + 1.0;
+ }
+ }
+ else
+ {
+ // Case 2
+
+ if ( n > M - 1.0 )
+ {
+ // no overlap
+ lcl_PutFactorialElements( cnNumer, 0.0, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, M - 1.0, N );
+ }
+ else
+ {
+ lcl_PutFactorialElements( cnNumer, M - n, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, n - 1.0, N );
+ }
+
+ DBG_ASSERT( fCDenomUpper <= n, "ScHypGeomDist: wrong assertion" );
+
+ if ( fCDenomUpper < n - x + 1.0 )
+ // no overlap
+ lcl_PutFactorialElements( cnNumer, N - M - n + 1.0, N - M - n + x, N - M + 1.0 );
+ else
+ {
+ lcl_PutFactorialElements( cnNumer, N - M - n + 1.0, N - M - fCDenomUpper, N - M + 1.0 );
+ fCDenomUpper = n - x;
+ fCDenomVarLower = N - M - 2.0*(n - x) + 1.0;
+ }
+ }
+
+ DBG_ASSERT( fCDenomUpper <= M, "ScHypGeomDist: wrong assertion" );
+ }
+ else
+ {
+ if ( N - M < M + 1.0 )
+ {
+ // Case 3
+
+ if ( N - n < M + 1.0 )
+ {
+ // No overlap
+ lcl_PutFactorialElements( cnNumer, 0.0, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, N - M - 1.0, N );
+ }
+ else
+ {
+ lcl_PutFactorialElements( cnNumer, N - n - M, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, n - 1.0, N );
+ }
+
+ if ( n - x + 1.0 > fCDenomUpper )
+ // No overlap
+ lcl_PutFactorialElements( cnNumer, 1.0, N - M - n + x, N - M + 1.0 );
+ else
+ {
+ // Overlap
+ lcl_PutFactorialElements( cnNumer, 1.0, N - M - fCDenomUpper, N - M + 1.0 );
+
+ fCDenomVarLower = N - M - 2.0*(n - x) + 1.0;
+ fCDenomUpper = n - x;
+ }
+ }
+ else
+ {
+ // Case 4
+
+ DBG_ASSERT( M >= n - x, "ScHypGeomDist: wrong assertion" );
+ DBG_ASSERT( M - x <= N - M + 1.0, "ScHypGeomDist: wrong assertion" );
+
+ if ( N - n < N - M + 1.0 )
+ {
+ // No overlap
+ lcl_PutFactorialElements( cnNumer, 0.0, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, M - 1.0, N );
+ }
+ else
+ {
+ // Overlap
+ DBG_ASSERT( fCNumLower <= N - M + 1.0, "ScHypGeomDist: wrong assertion" );
+
+ lcl_PutFactorialElements( cnNumer, M - n, fCNumVarUpper, N - n );
+ lcl_PutFactorialElements( cnDenom, 0.0, n - 1.0, N );
+ }
+
+ if ( n - x + 1.0 > fCDenomUpper )
+ // No overlap
+ lcl_PutFactorialElements( cnNumer, N - 2.0*M + 1.0, N - M - n + x, N - M + 1.0 );
+ else if ( M >= fCDenomUpper )
+ {
+ lcl_PutFactorialElements( cnNumer, N - 2.0*M + 1.0, N - M - fCDenomUpper, N - M + 1.0 );
+
+ fCDenomUpper = n - x;
+ fCDenomVarLower = N - M - 2.0*(n - x) + 1.0;
+ }
+ else
+ {
+ DBG_ASSERT( M <= fCDenomUpper, "ScHypGeomDist: wrong assertion" );
+ lcl_PutFactorialElements( cnDenom, fCDenomVarLower, N - n - 2.0*M + x,
+ N - n - M + x + 1.0 );
+
+ fCDenomUpper = n - x;
+ fCDenomVarLower = N - M - 2.0*(n - x) + 1.0;
+ }
+ }
+
+ DBG_ASSERT( fCDenomUpper <= n, "ScHypGeomDist: wrong assertion" );
+
+ fDNumVarLower = 0.0;
+ }
+
+ double nDNumVarUpper = fCDenomUpper < x + 1.0 ? n - x - 1.0 : n - fCDenomUpper - 1.0;
+ double nDDenomVarLower = fCDenomUpper < x + 1.0 ? fCDenomVarLower : N - n - M + 1.0;
+ lcl_PutFactorialElements( cnNumer, fDNumVarLower, nDNumVarUpper, n );
+ lcl_PutFactorialElements( cnDenom, nDDenomVarLower, N - n - M + x, N - n - M + x + 1.0 );
+
+ ::std::sort( cnNumer.begin(), cnNumer.end() );
+ ::std::sort( cnDenom.begin(), cnDenom.end() );
+ HypContainer::reverse_iterator it1 = cnNumer.rbegin(), it1End = cnNumer.rend();
+ HypContainer::reverse_iterator it2 = cnDenom.rbegin(), it2End = cnDenom.rend();
+
+ double fFactor = 1.0;
+ for ( ; it1 != it1End || it2 != it2End; )
+ {
+ double fEnum = 1.0, fDenom = 1.0;
+ if ( it1 != it1End )
+ fEnum = *it1++;
+ if ( it2 != it2End )
+ fDenom = *it2++;
+ fFactor *= fEnum / fDenom;
+ }
+
+ PushDouble(fFactor);
+}
+
+void ScInterpreter::ScGammaDist()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGammaDist" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
+ return;
+ double bCumulative;
+ if (nParamCount == 4)
+ bCumulative = GetBool();
+ else
+ bCumulative = true;
+ double fBeta = GetDouble(); // scale
+ double fAlpha = GetDouble(); // shape
+ double fX = GetDouble(); // x
+ if (fAlpha <= 0.0 || fBeta <= 0.0)
+ PushIllegalArgument();
+ else
+ {
+ if (bCumulative) // distribution
+ PushDouble( GetGammaDist( fX, fAlpha, fBeta));
+ else // density
+ PushDouble( GetGammaDistPDF( fX, fAlpha, fBeta));
+ }
+}
+
+void ScInterpreter::ScNormInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNormInv" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double sigma = GetDouble();
+ double mue = GetDouble();
+ double x = GetDouble();
+ if (sigma <= 0.0 || x < 0.0 || x > 1.0)
+ PushIllegalArgument();
+ else if (x == 0.0 || x == 1.0)
+ PushNoValue();
+ else
+ PushDouble(gaussinv(x)*sigma + mue);
+ }
+}
+
+void ScInterpreter::ScSNormInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSNormInv" );
+ double x = GetDouble();
+ if (x < 0.0 || x > 1.0)
+ PushIllegalArgument();
+ else if (x == 0.0 || x == 1.0)
+ PushNoValue();
+ else
+ PushDouble(gaussinv(x));
+}
+
+void ScInterpreter::ScLogNormInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLogNormInv" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double sigma = GetDouble(); // Stdabw
+ double mue = GetDouble(); // Mittelwert
+ double y = GetDouble(); // y
+ if (sigma <= 0.0 || y <= 0.0 || y >= 1.0)
+ PushIllegalArgument();
+ else
+ PushDouble(exp(mue+sigma*gaussinv(y)));
+ }
+}
+
+class ScGammaDistFunction : public ScDistFunc
+{
+ ScInterpreter& rInt;
+ double fp, fAlpha, fBeta;
+
+public:
+ ScGammaDistFunction( ScInterpreter& rI, double fpVal, double fAlphaVal, double fBetaVal ) :
+ rInt(rI), fp(fpVal), fAlpha(fAlphaVal), fBeta(fBetaVal) {}
+
+ double GetValue( double x ) const { return fp - rInt.GetGammaDist(x, fAlpha, fBeta); }
+};
+
+void ScInterpreter::ScGammaInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGammaInv" );
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+ double fBeta = GetDouble();
+ double fAlpha = GetDouble();
+ double fP = GetDouble();
+ if (fAlpha <= 0.0 || fBeta <= 0.0 || fP < 0.0 || fP >= 1.0 )
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (fP == 0.0)
+ PushInt(0);
+ else
+ {
+ bool bConvError;
+ ScGammaDistFunction aFunc( *this, fP, fAlpha, fBeta );
+ double fStart = fAlpha * fBeta;
+ double fVal = lcl_IterateInverse( aFunc, fStart*0.5, fStart, bConvError );
+ if (bConvError)
+ SetError(errNoConvergence);
+ PushDouble(fVal);
+ }
+}
+
+class ScBetaDistFunction : public ScDistFunc
+{
+ ScInterpreter& rInt;
+ double fp, fAlpha, fBeta;
+
+public:
+ ScBetaDistFunction( ScInterpreter& rI, double fpVal, double fAlphaVal, double fBetaVal ) :
+ rInt(rI), fp(fpVal), fAlpha(fAlphaVal), fBeta(fBetaVal) {}
+
+ double GetValue( double x ) const { return fp - rInt.GetBetaDist(x, fAlpha, fBeta); }
+};
+
+void ScInterpreter::ScBetaInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBetaInv" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
+ return;
+ double fP, fA, fB, fAlpha, fBeta;
+ if (nParamCount == 5)
+ fB = GetDouble();
+ else
+ fB = 1.0;
+ if (nParamCount >= 4)
+ fA = GetDouble();
+ else
+ fA = 0.0;
+ fBeta = GetDouble();
+ fAlpha = GetDouble();
+ fP = GetDouble();
+ if (fP < 0.0 || fP >= 1.0 || fA == fB || fAlpha <= 0.0 || fBeta <= 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (fP == 0.0)
+ PushInt(0);
+ else
+ {
+ bool bConvError;
+ ScBetaDistFunction aFunc( *this, fP, fAlpha, fBeta );
+ // 0..1 as range for iteration so it isn't extended beyond the valid range
+ double fVal = lcl_IterateInverse( aFunc, 0.0, 1.0, bConvError );
+ if (bConvError)
+ PushError( errNoConvergence);
+ else
+ PushDouble(fA + fVal*(fB-fA)); // scale to (A,B)
+ }
+}
+
+ // Achtung: T, F und Chi
+ // sind monoton fallend,
+ // deshalb 1-Dist als Funktion
+
+class ScTDistFunction : public ScDistFunc
+{
+ ScInterpreter& rInt;
+ double fp, fDF;
+
+public:
+ ScTDistFunction( ScInterpreter& rI, double fpVal, double fDFVal ) :
+ rInt(rI), fp(fpVal), fDF(fDFVal) {}
+
+ double GetValue( double x ) const { return fp - 2 * rInt.GetTDist(x, fDF); }
+};
+
+void ScInterpreter::ScTInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTInv" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double fDF = ::rtl::math::approxFloor(GetDouble());
+ double fP = GetDouble();
+ if (fDF < 1.0 || fDF >= 1.0E5 || fP <= 0.0 || fP > 1.0 )
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ bool bConvError;
+ ScTDistFunction aFunc( *this, fP, fDF );
+ double fVal = lcl_IterateInverse( aFunc, fDF*0.5, fDF, bConvError );
+ if (bConvError)
+ SetError(errNoConvergence);
+ PushDouble(fVal);
+}
+
+class ScFDistFunction : public ScDistFunc
+{
+ ScInterpreter& rInt;
+ double fp, fF1, fF2;
+
+public:
+ ScFDistFunction( ScInterpreter& rI, double fpVal, double fF1Val, double fF2Val ) :
+ rInt(rI), fp(fpVal), fF1(fF1Val), fF2(fF2Val) {}
+
+ double GetValue( double x ) const { return fp - rInt.GetFDist(x, fF1, fF2); }
+};
+
+void ScInterpreter::ScFInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFInv" );
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+ double fF2 = ::rtl::math::approxFloor(GetDouble());
+ double fF1 = ::rtl::math::approxFloor(GetDouble());
+ double fP = GetDouble();
+ if (fP <= 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10 || fP > 1.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ bool bConvError;
+ ScFDistFunction aFunc( *this, fP, fF1, fF2 );
+ double fVal = lcl_IterateInverse( aFunc, fF1*0.5, fF1, bConvError );
+ if (bConvError)
+ SetError(errNoConvergence);
+ PushDouble(fVal);
+}
+
+class ScChiDistFunction : public ScDistFunc
+{
+ ScInterpreter& rInt;
+ double fp, fDF;
+
+public:
+ ScChiDistFunction( ScInterpreter& rI, double fpVal, double fDFVal ) :
+ rInt(rI), fp(fpVal), fDF(fDFVal) {}
+
+ double GetValue( double x ) const { return fp - rInt.GetChiDist(x, fDF); }
+};
+
+void ScInterpreter::ScChiInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChiInv" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double fDF = ::rtl::math::approxFloor(GetDouble());
+ double fP = GetDouble();
+ if (fDF < 1.0 || fP <= 0.0 || fP > 1.0 )
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ bool bConvError;
+ ScChiDistFunction aFunc( *this, fP, fDF );
+ double fVal = lcl_IterateInverse( aFunc, fDF*0.5, fDF, bConvError );
+ if (bConvError)
+ SetError(errNoConvergence);
+ PushDouble(fVal);
+}
+
+/***********************************************/
+class ScChiSqDistFunction : public ScDistFunc
+{
+ ScInterpreter& rInt;
+ double fp, fDF;
+
+public:
+ ScChiSqDistFunction( ScInterpreter& rI, double fpVal, double fDFVal ) :
+ rInt(rI), fp(fpVal), fDF(fDFVal) {}
+
+ double GetValue( double x ) const { return fp - rInt.GetChiSqDistCDF(x, fDF); }
+};
+
+
+void ScInterpreter::ScChiSqInv()
+{
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double fDF = ::rtl::math::approxFloor(GetDouble());
+ double fP = GetDouble();
+ if (fDF < 1.0 || fP < 0.0 || fP >= 1.0 )
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ bool bConvError;
+ ScChiSqDistFunction aFunc( *this, fP, fDF );
+ double fVal = lcl_IterateInverse( aFunc, fDF*0.5, fDF, bConvError );
+ if (bConvError)
+ SetError(errNoConvergence);
+ PushDouble(fVal);
+}
+
+
+void ScInterpreter::ScConfidence()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScConfidence" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double n = ::rtl::math::approxFloor(GetDouble());
+ double sigma = GetDouble();
+ double alpha = GetDouble();
+ if (sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0 || n < 1.0)
+ PushIllegalArgument();
+ else
+ PushDouble( gaussinv(1.0-alpha/2.0) * sigma/sqrt(n) );
+ }
+}
+
+void ScInterpreter::ScZTest()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZTest" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
+ return;
+ double sigma = 0.0, mue, x;
+ if (nParamCount == 3)
+ {
+ sigma = GetDouble();
+ if (sigma <= 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ x = GetDouble();
+
+ double fSum = 0.0;
+ double fSumSqr = 0.0;
+ double fVal;
+ double rValCount = 0.0;
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ {
+ fVal = GetDouble();
+ fSum += fVal;
+ fSumSqr += fVal*fVal;
+ rValCount++;
+ }
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ fSum += fVal;
+ fSumSqr += fVal*fVal;
+ rValCount++;
+ }
+ }
+ break;
+ case svRefList :
+ case formula::svDoubleRef :
+ {
+ short nParam = 1;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ ScRange aRange;
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(fVal, nErr))
+ {
+ fSum += fVal;
+ fSumSqr += fVal*fVal;
+ rValCount++;
+ while ((nErr == 0) && aValIter.GetNext(fVal, nErr))
+ {
+ fSum += fVal;
+ fSumSqr += fVal*fVal;
+ rValCount++;
+ }
+ SetError(nErr);
+ }
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ {
+ fVal= pMat->GetDouble(i);
+ fSum += fVal;
+ fSumSqr += fVal * fVal;
+ rValCount++;
+ }
+ }
+ else
+ {
+ for (SCSIZE i = 0; i < nCount; i++)
+ if (!pMat->IsString(i))
+ {
+ fVal= pMat->GetDouble(i);
+ fSum += fVal;
+ fSumSqr += fVal * fVal;
+ rValCount++;
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ if (rValCount <= 1.0)
+ PushError( errDivisionByZero);
+ else
+ {
+ mue = fSum/rValCount;
+ if (nParamCount != 3)
+ {
+ sigma = (fSumSqr - fSum*fSum/rValCount)/(rValCount-1.0);
+ PushDouble(0.5 - gauss((mue-x)/sqrt(sigma/rValCount)));
+ }
+ else
+ PushDouble(0.5 - gauss((mue-x)*sqrt(rValCount)/sigma));
+ }
+}
+bool ScInterpreter::CalculateTest(BOOL _bTemplin
+ ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2
+ ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
+ ,double& fT,double& fF)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateTest" );
+ double fCount1 = 0.0;
+ double fCount2 = 0.0;
+ double fSum1 = 0.0;
+ double fSumSqr1 = 0.0;
+ double fSum2 = 0.0;
+ double fSumSqr2 = 0.0;
+ double fVal;
+ SCSIZE i,j;
+ for (i = 0; i < nC1; i++)
+ for (j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j))
+ {
+ fVal = pMat1->GetDouble(i,j);
+ fSum1 += fVal;
+ fSumSqr1 += fVal * fVal;
+ fCount1++;
+ }
+ }
+ for (i = 0; i < nC2; i++)
+ for (j = 0; j < nR2; j++)
+ {
+ if (!pMat2->IsString(i,j))
+ {
+ fVal = pMat2->GetDouble(i,j);
+ fSum2 += fVal;
+ fSumSqr2 += fVal * fVal;
+ fCount2++;
+ }
+ }
+ if (fCount1 < 2.0 || fCount2 < 2.0)
+ {
+ PushNoValue();
+ return false;
+ } // if (fCount1 < 2.0 || fCount2 < 2.0)
+ if ( _bTemplin )
+ {
+ double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)/(fCount1-1.0)/fCount1;
+ double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)/(fCount2-1.0)/fCount2;
+ if (fS1 + fS2 == 0.0)
+ {
+ PushNoValue();
+ return false;
+ }
+ fT = fabs(fSum1/fCount1 - fSum2/fCount2)/sqrt(fS1+fS2);
+ double c = fS1/(fS1+fS2);
+// s.u. fF = ::rtl::math::approxFloor(1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)/(fCount2-1.0)));
+// fF = ::rtl::math::approxFloor((fS1+fS2)*(fS1+fS2)/(fS1*fS1/(fCount1-1.0) + fS2*fS2/(fCount2-1.0)));
+
+ // GetTDist wird mit GetBetaDist berechnet und kommt auch mit nicht ganzzahligen
+ // Freiheitsgraden klar. Dann stimmt das Ergebnis auch mit Excel ueberein (#52406#):
+ fF = 1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)/(fCount2-1.0));
+ }
+ else
+ {
+ // laut Bronstein-Semendjajew
+ double fS1 = (fSumSqr1 - fSum1*fSum1/fCount1) / (fCount1 - 1.0); // Varianz
+ double fS2 = (fSumSqr2 - fSum2*fSum2/fCount2) / (fCount2 - 1.0);
+ fT = fabs( fSum1/fCount1 - fSum2/fCount2 ) /
+ sqrt( (fCount1-1.0)*fS1 + (fCount2-1.0)*fS2 ) *
+ sqrt( fCount1*fCount2*(fCount1+fCount2-2)/(fCount1+fCount2) );
+ fF = fCount1 + fCount2 - 2;
+ }
+ return true;
+}
+void ScInterpreter::ScTTest()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTest" );
+ if ( !MustHaveParamCount( GetByte(), 4 ) )
+ return;
+ double fTyp = ::rtl::math::approxFloor(GetDouble());
+ double fAnz = ::rtl::math::approxFloor(GetDouble());
+ if (fAnz != 1.0 && fAnz != 2.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ ScMatrixRef pMat2 = GetMatrix();
+ ScMatrixRef pMat1 = GetMatrix();
+ if (!pMat1 || !pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ double fT, fF;
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ SCSIZE i, j;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ if (fTyp == 1.0)
+ {
+ if (nC1 != nC2 || nR1 != nR2)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double fCount = 0.0;
+ double fSum1 = 0.0;
+ double fSum2 = 0.0;
+ double fSumSqrD = 0.0;
+ double fVal1, fVal2;
+ for (i = 0; i < nC1; i++)
+ for (j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ fVal1 = pMat1->GetDouble(i,j);
+ fVal2 = pMat2->GetDouble(i,j);
+ fSum1 += fVal1;
+ fSum2 += fVal2;
+ fSumSqrD += (fVal1 - fVal2)*(fVal1 - fVal2);
+ fCount++;
+ }
+ }
+ if (fCount < 1.0)
+ {
+ PushNoValue();
+ return;
+ }
+ fT = sqrt(fCount-1.0) * fabs(fSum1 - fSum2) /
+ sqrt(fCount * fSumSqrD - (fSum1-fSum2)*(fSum1-fSum2));
+ fF = fCount - 1.0;
+ }
+ else if (fTyp == 2.0)
+ {
+ CalculateTest(FALSE,nC1, nC2,nR1, nR2,pMat1,pMat2,fT,fF);
+ }
+ else if (fTyp == 3.0)
+ {
+ CalculateTest(TRUE,nC1, nC2,nR1, nR2,pMat1,pMat2,fT,fF);
+ }
+
+ else
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (fAnz == 1.0)
+ PushDouble(GetTDist(fT, fF));
+ else
+ PushDouble(2.0*GetTDist(fT, fF));
+}
+
+void ScInterpreter::ScFTest()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFTest" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ ScMatrixRef pMat2 = GetMatrix();
+ ScMatrixRef pMat1 = GetMatrix();
+ if (!pMat1 || !pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ SCSIZE i, j;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ double fCount1 = 0.0;
+ double fCount2 = 0.0;
+ double fSum1 = 0.0;
+ double fSumSqr1 = 0.0;
+ double fSum2 = 0.0;
+ double fSumSqr2 = 0.0;
+ double fVal;
+ for (i = 0; i < nC1; i++)
+ for (j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j))
+ {
+ fVal = pMat1->GetDouble(i,j);
+ fSum1 += fVal;
+ fSumSqr1 += fVal * fVal;
+ fCount1++;
+ }
+ }
+ for (i = 0; i < nC2; i++)
+ for (j = 0; j < nR2; j++)
+ {
+ if (!pMat2->IsString(i,j))
+ {
+ fVal = pMat2->GetDouble(i,j);
+ fSum2 += fVal;
+ fSumSqr2 += fVal * fVal;
+ fCount2++;
+ }
+ }
+ if (fCount1 < 2.0 || fCount2 < 2.0)
+ {
+ PushNoValue();
+ return;
+ }
+ double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)/(fCount1-1.0);
+ double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)/(fCount2-1.0);
+ if (fS1 == 0.0 || fS2 == 0.0)
+ {
+ PushNoValue();
+ return;
+ }
+ double fF, fF1, fF2;
+ if (fS1 > fS2)
+ {
+ fF = fS1/fS2;
+ fF1 = fCount1-1.0;
+ fF2 = fCount2-1.0;
+ }
+ else
+ {
+ fF = fS2/fS1;
+ fF1 = fCount2-1.0;
+ fF2 = fCount1-1.0;
+ }
+ PushDouble(2.0*GetFDist(fF, fF1, fF2));
+/*
+ double Z = (pow(fF,1.0/3.0)*(1.0-2.0/(9.0*fF2)) - (1.0-2.0/(9.0*fF1))) /
+ sqrt(2.0/(9.0*fF1) + pow(fF,2.0/3.0)*2.0/(9.0*fF2));
+ PushDouble(1.0-2.0*gauss(Z));
+*/
+}
+
+void ScInterpreter::ScChiTest()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChiTest" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ ScMatrixRef pMat2 = GetMatrix();
+ ScMatrixRef pMat1 = GetMatrix();
+ if (!pMat1 || !pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ if (nR1 != nR2 || nC1 != nC2)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double fChi = 0.0;
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ double fValX = pMat1->GetDouble(i,j);
+ double fValE = pMat2->GetDouble(i,j);
+ fChi += (fValX - fValE) * (fValX - fValE) / fValE;
+ }
+ else
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ }
+ double fDF;
+ if (nC1 == 1 || nR1 == 1)
+ {
+ fDF = (double)(nC1*nR1 - 1);
+ if (fDF == 0.0)
+ {
+ PushNoValue();
+ return;
+ }
+ }
+ else
+ fDF = (double)(nC1-1)*(double)(nR1-1);
+ PushDouble(GetChiDist(fChi, fDF));
+/*
+ double fX, fS, fT, fG;
+ fX = 1.0;
+ for (double fi = fDF; fi >= 2.0; fi -= 2.0)
+ fX *= fChi/fi;
+ fX *= exp(-fChi/2.0);
+ if (fmod(fDF, 2.0) != 0.0)
+ fX *= sqrt(2.0*fChi/F_PI);
+ fS = 1.0;
+ fT = 1.0;
+ fG = fDF;
+ while (fT >= 1.0E-7)
+ {
+ fG += 2.0;
+ fT *= fChi/fG;
+ fS += fT;
+ }
+ PushDouble(1.0 - fX*fS);
+*/
+}
+
+void ScInterpreter::ScKurt()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKurt" );
+ double fSum,fCount,vSum;
+ std::vector<double> values;
+ if ( !CalculateSkew(fSum,fCount,vSum,values) )
+ return;
+
+ if (fCount == 0.0)
+ {
+ PushError( errDivisionByZero);
+ return;
+ }
+
+ double fMean = fSum / fCount;
+
+ for (size_t i = 0; i < values.size(); i++)
+ vSum += (values[i] - fMean) * (values[i] - fMean);
+
+ double fStdDev = sqrt(vSum / (fCount - 1.0));
+ double dx = 0.0;
+ double xpower4 = 0.0;
+
+ if (fStdDev == 0.0)
+ {
+ PushError( errDivisionByZero);
+ return;
+ }
+
+ for (size_t i = 0; i < values.size(); i++)
+ {
+ dx = (values[i] - fMean) / fStdDev;
+ xpower4 = xpower4 + (dx * dx * dx * dx);
+ }
+
+ double k_d = (fCount - 2.0) * (fCount - 3.0);
+ double k_l = fCount * (fCount + 1.0) / ((fCount - 1.0) * k_d);
+ double k_t = 3.0 * (fCount - 1.0) * (fCount - 1.0) / k_d;
+
+ PushDouble(xpower4 * k_l - k_t);
+}
+
+void ScInterpreter::ScHarMean()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHarMean" );
+ short nParamCount = GetByte();
+ double nVal = 0.0;
+ double nValCount = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while ((nGlobalError == 0) && (nParamCount-- > 0))
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ {
+ double x = GetDouble();
+ if (x > 0.0)
+ {
+ nVal += 1.0/x;
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ break;
+ }
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ double x = GetCellValue( aAdr, pCell );
+ if (x > 0.0)
+ {
+ nVal += 1.0/x;
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ break;
+ }
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ double nCellVal;
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ if (nCellVal > 0.0)
+ {
+ nVal += 1.0/nCellVal;
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ SetError(nErr);
+ while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr))
+ {
+ if (nCellVal > 0.0)
+ {
+ nVal += 1.0/nCellVal;
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ {
+ double x = pMat->GetDouble(nElem);
+ if (x > 0.0)
+ {
+ nVal += 1.0/x;
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ }
+ else
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ if (!pMat->IsString(nElem))
+ {
+ double x = pMat->GetDouble(nElem);
+ if (x > 0.0)
+ {
+ nVal += 1.0/x;
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ }
+ if (nGlobalError == 0)
+ PushDouble((double)nValCount/nVal);
+ else
+ PushError( nGlobalError);
+}
+
+void ScInterpreter::ScGeoMean()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGeoMean" );
+ short nParamCount = GetByte();
+ double nVal = 0.0;
+ double nValCount = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+
+ size_t nRefInList = 0;
+ while ((nGlobalError == 0) && (nParamCount-- > 0))
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ {
+ double x = GetDouble();
+ if (x > 0.0)
+ {
+ nVal += log(x);
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ break;
+ }
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ double x = GetCellValue( aAdr, pCell );
+ if (x > 0.0)
+ {
+ nVal += log(x);
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ break;
+ }
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ double nCellVal;
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ if (nCellVal > 0.0)
+ {
+ nVal += log(nCellVal);
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ SetError(nErr);
+ while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr))
+ {
+ if (nCellVal > 0.0)
+ {
+ nVal += log(nCellVal);
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE ui = 0; ui < nCount; ui++)
+ {
+ double x = pMat->GetDouble(ui);
+ if (x > 0.0)
+ {
+ nVal += log(x);
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ }
+ else
+ {
+ for (SCSIZE ui = 0; ui < nCount; ui++)
+ if (!pMat->IsString(ui))
+ {
+ double x = pMat->GetDouble(ui);
+ if (x > 0.0)
+ {
+ nVal += log(x);
+ nValCount++;
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ }
+ if (nGlobalError == 0)
+ PushDouble(exp(nVal / nValCount));
+ else
+ PushError( nGlobalError);
+}
+
+void ScInterpreter::ScStandard()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStandard" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ double sigma = GetDouble();
+ double mue = GetDouble();
+ double x = GetDouble();
+ if (sigma < 0.0)
+ PushError( errIllegalArgument);
+ else if (sigma == 0.0)
+ PushError( errDivisionByZero);
+ else
+ PushDouble((x-mue)/sigma);
+ }
+}
+bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSkew" );
+ short nParamCount = GetByte();
+ if ( !MustHaveParamCountMin( nParamCount, 1 ) )
+ return false;
+
+ fSum = 0.0;
+ fCount = 0.0;
+ vSum = 0.0;
+ double fVal = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ {
+ fVal = GetDouble();
+ fSum += fVal;
+ values.push_back(fVal);
+ fCount++;
+ }
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ fSum += fVal;
+ values.push_back(fVal);
+ fCount++;
+ }
+ }
+ break;
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ USHORT nErr = 0;
+ ScValueIterator aValIter(pDok, aRange);
+ if (aValIter.GetFirst(fVal, nErr))
+ {
+ fSum += fVal;
+ values.push_back(fVal);
+ fCount++;
+ SetError(nErr);
+ while ((nErr == 0) && aValIter.GetNext(fVal, nErr))
+ {
+ fSum += fVal;
+ values.push_back(fVal);
+ fCount++;
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ {
+ fVal = pMat->GetDouble(nElem);
+ fSum += fVal;
+ values.push_back(fVal);
+ fCount++;
+ }
+ }
+ else
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ if (!pMat->IsString(nElem))
+ {
+ fVal = pMat->GetDouble(nElem);
+ fSum += fVal;
+ values.push_back(fVal);
+ fCount++;
+ }
+ }
+ }
+ }
+ break;
+ default :
+ SetError(errIllegalParameter);
+ break;
+ }
+ }
+
+ if (nGlobalError)
+ {
+ PushError( nGlobalError);
+ return false;
+ } // if (nGlobalError)
+ return true;
+}
+
+void ScInterpreter::ScSkew()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSkew" );
+ double fSum,fCount,vSum;
+ std::vector<double> values;
+ if ( !CalculateSkew(fSum,fCount,vSum,values) )
+ return;
+
+ double fMean = fSum / fCount;
+
+ for (size_t i = 0; i < values.size(); i++)
+ vSum += (values[i] - fMean) * (values[i] - fMean);
+
+ double fStdDev = sqrt(vSum / (fCount - 1.0));
+ double dx = 0.0;
+ double xcube = 0.0;
+
+ if (fStdDev == 0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ for (size_t i = 0; i < values.size(); i++)
+ {
+ dx = (values[i] - fMean) / fStdDev;
+ xcube = xcube + (dx * dx * dx);
+ }
+
+ PushDouble(((xcube * fCount) / (fCount - 1.0)) / (fCount - 2.0));
+}
+
+double ScInterpreter::GetMedian( vector<double> & rArray )
+{
+ size_t nSize = rArray.size();
+ if (rArray.empty() || nSize == 0 || nGlobalError)
+ {
+ SetError( errNoValue);
+ return 0.0;
+ }
+
+ // Upper median.
+ size_t nMid = nSize / 2;
+ vector<double>::iterator iMid = rArray.begin() + nMid;
+ ::std::nth_element( rArray.begin(), iMid, rArray.end());
+ if (nSize & 1)
+ return *iMid; // Lower and upper median are equal.
+ else
+ {
+ double fUp = *iMid;
+ // Lower median.
+ iMid = rArray.begin() + nMid - 1;
+ ::std::nth_element( rArray.begin(), iMid, rArray.end());
+ return (fUp + *iMid) / 2;
+ }
+}
+
+void ScInterpreter::ScMedian()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMedian" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCountMin( nParamCount, 1 ) )
+ return;
+ vector<double> aArray;
+ GetNumberSequenceArray( nParamCount, aArray);
+ PushDouble( GetMedian( aArray));
+}
+
+double ScInterpreter::GetPercentile( vector<double> & rArray, double fPercentile )
+{
+ size_t nSize = rArray.size();
+ if (rArray.empty() || nSize == 0 || nGlobalError)
+ {
+ SetError( errNoValue);
+ return 0.0;
+ }
+
+ if (nSize == 1)
+ return rArray[0];
+ else
+ {
+ size_t nIndex = (size_t)::rtl::math::approxFloor( fPercentile * (nSize-1));
+ double fDiff = fPercentile * (nSize-1) - ::rtl::math::approxFloor( fPercentile * (nSize-1));
+ DBG_ASSERT(nIndex < nSize, "GetPercentile: wrong index(1)");
+ vector<double>::iterator iter = rArray.begin() + nIndex;
+ ::std::nth_element( rArray.begin(), iter, rArray.end());
+ if (fDiff == 0.0)
+ return *iter;
+ else
+ {
+ DBG_ASSERT(nIndex < nSize-1, "GetPercentile: wrong index(2)");
+ double fVal = *iter;
+ iter = rArray.begin() + nIndex+1;
+ ::std::nth_element( rArray.begin(), iter, rArray.end());
+ return fVal + fDiff * (*iter - fVal);
+ }
+ }
+}
+
+void ScInterpreter::ScPercentile()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentile" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double alpha = GetDouble();
+ if (alpha < 0.0 || alpha > 1.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ vector<double> aArray;
+ GetNumberSequenceArray( 1, aArray);
+ PushDouble( GetPercentile( aArray, alpha));
+}
+
+void ScInterpreter::ScQuartile()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScQuartile" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double fFlag = ::rtl::math::approxFloor(GetDouble());
+ if (fFlag < 0.0 || fFlag > 4.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ vector<double> aArray;
+ GetNumberSequenceArray( 1, aArray);
+ PushDouble( fFlag == 2.0 ? GetMedian( aArray) : GetPercentile( aArray, 0.25 * fFlag));
+}
+
+void ScInterpreter::ScModalValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScModalValue" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCountMin( nParamCount, 1 ) )
+ return;
+ vector<double> aSortArray;
+ GetSortArray(nParamCount, aSortArray);
+ SCSIZE nSize = aSortArray.size();
+ if (aSortArray.empty() || nSize == 0 || nGlobalError)
+ PushNoValue();
+ else
+ {
+ SCSIZE nMaxIndex = 0, nMax = 1, nCount = 1;
+ double nOldVal = aSortArray[0];
+ SCSIZE i;
+
+ for ( i = 1; i < nSize; i++)
+ {
+ if (aSortArray[i] == nOldVal)
+ nCount++;
+ else
+ {
+ nOldVal = aSortArray[i];
+ if (nCount > nMax)
+ {
+ nMax = nCount;
+ nMaxIndex = i-1;
+ }
+ nCount = 1;
+ }
+ }
+ if (nCount > nMax)
+ {
+ nMax = nCount;
+ nMaxIndex = i-1;
+ }
+ if (nMax == 1 && nCount == 1)
+ PushNoValue();
+ else if (nMax == 1)
+ PushDouble(nOldVal);
+ else
+ PushDouble(aSortArray[nMaxIndex]);
+ }
+}
+
+void ScInterpreter::CalculateSmallLarge(BOOL bSmall)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSmallLarge" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double f = ::rtl::math::approxFloor(GetDouble());
+ if (f < 1.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ SCSIZE k = static_cast<SCSIZE>(f);
+ vector<double> aSortArray;
+ /* TODO: using nth_element() is best for one single value, but LARGE/SMALL
+ * actually are defined to return an array of values if an array of
+ * positions was passed, in which case, depending on the number of values,
+ * we may or will need a real sorted array again, see #i32345. */
+ //GetSortArray(1, aSortArray);
+ GetNumberSequenceArray(1, aSortArray);
+ SCSIZE nSize = aSortArray.size();
+ if (aSortArray.empty() || nSize == 0 || nGlobalError || nSize < k)
+ PushNoValue();
+ else
+ {
+ // TODO: the sorted case for array: PushDouble( aSortArray[ bSmall ? k-1 : nSize-k ] );
+ vector<double>::iterator iPos = aSortArray.begin() + (bSmall ? k-1 : nSize-k);
+ ::std::nth_element( aSortArray.begin(), iPos, aSortArray.end());
+ PushDouble( *iPos);
+ }
+}
+
+void ScInterpreter::ScLarge()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLarge" );
+ CalculateSmallLarge(FALSE);
+}
+
+void ScInterpreter::ScSmall()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSmall" );
+ CalculateSmallLarge(TRUE);
+}
+
+void ScInterpreter::ScPercentrank()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentrank" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 2 ) )
+ return;
+#if 0
+/* wird nicht unterstuetzt
+ double fPrec;
+ if (nParamCount == 3)
+ {
+ fPrec = ::rtl::math::approxFloor(GetDouble());
+ if (fPrec < 1.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ else
+ fPrec = 3.0;
+*/
+#endif
+ double fNum = GetDouble();
+ vector<double> aSortArray;
+ GetSortArray(1, aSortArray);
+ SCSIZE nSize = aSortArray.size();
+ if (aSortArray.empty() || nSize == 0 || nGlobalError)
+ PushNoValue();
+ else
+ {
+ if (fNum < aSortArray[0] || fNum > aSortArray[nSize-1])
+ PushNoValue();
+ else if ( nSize == 1 )
+ PushDouble(1.0); // fNum == pSortArray[0], see test above
+ else
+ {
+ double fRes;
+ SCSIZE nOldCount = 0;
+ double fOldVal = aSortArray[0];
+ SCSIZE i;
+ for (i = 1; i < nSize && aSortArray[i] < fNum; i++)
+ {
+ if (aSortArray[i] != fOldVal)
+ {
+ nOldCount = i;
+ fOldVal = aSortArray[i];
+ }
+ }
+ if (aSortArray[i] != fOldVal)
+ nOldCount = i;
+ if (fNum == aSortArray[i])
+ fRes = (double)nOldCount/(double)(nSize-1);
+ else
+ {
+ // #75312# nOldCount is the count of smaller entries
+ // fNum is between pSortArray[nOldCount-1] and pSortArray[nOldCount]
+ // use linear interpolation to find a position between the entries
+
+ if ( nOldCount == 0 )
+ {
+ DBG_ERROR("should not happen");
+ fRes = 0.0;
+ }
+ else
+ {
+ double fFract = ( fNum - aSortArray[nOldCount-1] ) /
+ ( aSortArray[nOldCount] - aSortArray[nOldCount-1] );
+ fRes = ( (double)(nOldCount-1)+fFract )/(double)(nSize-1);
+ }
+ }
+ PushDouble(fRes);
+ }
+ }
+}
+
+void ScInterpreter::ScTrimMean()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrimMean" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ double alpha = GetDouble();
+ if (alpha < 0.0 || alpha >= 1.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ vector<double> aSortArray;
+ GetSortArray(1, aSortArray);
+ SCSIZE nSize = aSortArray.size();
+ if (aSortArray.empty() || nSize == 0 || nGlobalError)
+ PushNoValue();
+ else
+ {
+ ULONG nIndex = (ULONG) ::rtl::math::approxFloor(alpha*(double)nSize);
+ if (nIndex % 2 != 0)
+ nIndex--;
+ nIndex /= 2;
+ DBG_ASSERT(nIndex < nSize, "ScTrimMean: falscher Index");
+ double fSum = 0.0;
+ for (SCSIZE i = nIndex; i < nSize-nIndex; i++)
+ fSum += aSortArray[i];
+ PushDouble(fSum/(double)(nSize-2*nIndex));
+ }
+}
+
+void ScInterpreter::GetNumberSequenceArray( BYTE nParamCount, vector<double>& rArray )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetSortArray" );
+ ScAddress aAdr;
+ ScRange aRange;
+ short nParam = nParamCount;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ rArray.push_back( PopDouble());
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ rArray.push_back( GetCellValue( aAdr, pCell));
+ }
+ break;
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ PopDoubleRef( aRange, nParam, nRefInList);
+ if (nGlobalError)
+ break;
+
+ aRange.Justify();
+ SCSIZE nCellCount = aRange.aEnd.Col() - aRange.aStart.Col() + 1;
+ nCellCount *= aRange.aEnd.Row() - aRange.aStart.Row() + 1;
+ rArray.reserve( rArray.size() + nCellCount);
+
+ USHORT nErr = 0;
+ double fCellVal;
+ ScValueIterator aValIter(pDok, aRange);
+ if (aValIter.GetFirst( fCellVal, nErr))
+ {
+ rArray.push_back( fCellVal);
+ SetError(nErr);
+ while ((nErr == 0) && aValIter.GetNext( fCellVal, nErr))
+ rArray.push_back( fCellVal);
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (!pMat)
+ break;
+
+ SCSIZE nCount = pMat->GetElementCount();
+ rArray.reserve( rArray.size() + nCount);
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE i = 0; i < nCount; ++i)
+ rArray.push_back( pMat->GetDouble(i));
+ }
+ else
+ {
+ for (SCSIZE i = 0; i < nCount; ++i)
+ if (!pMat->IsString(i))
+ rArray.push_back( pMat->GetDouble(i));
+ }
+ }
+ break;
+ default :
+ PopError();
+ SetError( errIllegalParameter);
+ break;
+ }
+ if (nGlobalError)
+ break; // while
+ }
+ // nParam > 0 in case of error, clean stack environment and obtain earlier
+ // error if there was one.
+ while (nParam-- > 0)
+ PopError();
+}
+
+void ScInterpreter::GetSortArray( BYTE nParamCount, vector<double>& rSortArray, vector<long>* pIndexOrder )
+{
+ GetNumberSequenceArray( nParamCount, rSortArray);
+
+ if (rSortArray.size() > MAX_ANZ_DOUBLE_FOR_SORT)
+ SetError( errStackOverflow);
+ else if (rSortArray.empty())
+ SetError( errNoValue);
+
+ if (nGlobalError == 0)
+ QuickSort( rSortArray, pIndexOrder);
+}
+
+static void lcl_QuickSort( long nLo, long nHi, vector<double>& rSortArray, vector<long>* pIndexOrder )
+{
+ // If pIndexOrder is not NULL, we assume rSortArray.size() == pIndexOrder->size().
+
+ using ::std::swap;
+
+ if (nHi - nLo == 1)
+ {
+ if (rSortArray[nLo] > rSortArray[nHi])
+ {
+ swap(rSortArray[nLo], rSortArray[nHi]);
+ if (pIndexOrder)
+ swap(pIndexOrder->at(nLo), pIndexOrder->at(nHi));
+ }
+ return;
+ }
+
+ long ni = nLo;
+ long nj = nHi;
+ do
+ {
+ double fLo = rSortArray[nLo];
+ while (ni <= nHi && rSortArray[ni] < fLo) ni++;
+ while (nj >= nLo && fLo < rSortArray[nj]) nj--;
+ if (ni <= nj)
+ {
+ if (ni != nj)
+ {
+ swap(rSortArray[ni], rSortArray[nj]);
+ if (pIndexOrder)
+ swap(pIndexOrder->at(ni), pIndexOrder->at(nj));
+ }
+
+ ++ni;
+ --nj;
+ }
+ }
+ while (ni < nj);
+
+ if ((nj - nLo) < (nHi - ni))
+ {
+ if (nLo < nj) lcl_QuickSort(nLo, nj, rSortArray, pIndexOrder);
+ if (ni < nHi) lcl_QuickSort(ni, nHi, rSortArray, pIndexOrder);
+ }
+ else
+ {
+ if (ni < nHi) lcl_QuickSort(ni, nHi, rSortArray, pIndexOrder);
+ if (nLo < nj) lcl_QuickSort(nLo, nj, rSortArray, pIndexOrder);
+ }
+}
+
+void ScInterpreter::QuickSort( vector<double>& rSortArray, vector<long>* pIndexOrder )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::QuickSort" );
+ long n = static_cast<long>(rSortArray.size());
+
+ if (pIndexOrder)
+ {
+ pIndexOrder->clear();
+ pIndexOrder->reserve(n);
+ for (long i = 0; i < n; ++i)
+ pIndexOrder->push_back(i);
+ }
+
+ if (n < 2)
+ return;
+
+ size_t nValCount = rSortArray.size();
+ for (size_t i = 0; (i + 4) <= nValCount-1; i += 4)
+ {
+ size_t nInd = rand() % (int) (nValCount-1);
+ ::std::swap( rSortArray[i], rSortArray[nInd]);
+ if (pIndexOrder)
+ ::std::swap( pIndexOrder->at(i), pIndexOrder->at(nInd));
+ }
+
+ lcl_QuickSort(0, n-1, rSortArray, pIndexOrder);
+}
+
+void ScInterpreter::ScRank()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRank" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
+ return;
+ BOOL bDescending;
+ if (nParamCount == 3)
+ bDescending = GetBool();
+ else
+ bDescending = FALSE;
+ double fCount = 1.0;
+ BOOL bValid = FALSE;
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ {
+ double x = GetDouble();
+ double fVal = GetDouble();
+ if (x == fVal)
+ bValid = TRUE;
+ break;
+ }
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ double fVal = GetDouble();
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ double x = GetCellValue( aAdr, pCell );
+ if (x == fVal)
+ bValid = TRUE;
+ }
+ break;
+ }
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ ScRange aRange;
+ short nParam = 1;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ USHORT nErr = 0;
+ // Preserve stack until all RefList elements are done!
+ USHORT nSaveSP = sp;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ if (nParam)
+ --sp; // simulate pop
+ double fVal = GetDouble();
+ if (nParam)
+ sp = nSaveSP;
+ double nCellVal;
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ if (nCellVal == fVal)
+ bValid = TRUE;
+ else if ((!bDescending && nCellVal > fVal) ||
+ (bDescending && nCellVal < fVal) )
+ fCount++;
+ SetError(nErr);
+ while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr))
+ {
+ if (nCellVal == fVal)
+ bValid = TRUE;
+ else if ((!bDescending && nCellVal > fVal) ||
+ (bDescending && nCellVal < fVal) )
+ fCount++;
+ }
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ double fVal = GetDouble();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ double x = pMat->GetDouble(i);
+ if (x == fVal)
+ bValid = TRUE;
+ else if ((!bDescending && x > fVal) ||
+ (bDescending && x < fVal) )
+ fCount++;
+ }
+ }
+ else
+ {
+ for (SCSIZE i = 0; i < nCount; i++)
+ if (!pMat->IsString(i))
+ {
+ double x = pMat->GetDouble(i);
+ if (x == fVal)
+ bValid = TRUE;
+ else if ((!bDescending && x > fVal) ||
+ (bDescending && x < fVal) )
+ fCount++;
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ if (bValid)
+ PushDouble(fCount);
+ else
+ PushNoValue();
+}
+
+void ScInterpreter::ScAveDev()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAveDev" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCountMin( nParamCount, 1 ) )
+ return;
+ USHORT SaveSP = sp;
+ double nMiddle = 0.0;
+ double rVal = 0.0;
+ double rValCount = 0.0;
+ ScAddress aAdr;
+ ScRange aRange;
+ short nParam = nParamCount;
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ rVal += GetDouble();
+ rValCount++;
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ {
+ rVal += GetCellValue( aAdr, pCell );
+ rValCount++;
+ }
+ }
+ break;
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ double nCellVal;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ ScValueIterator aValIter(pDok, aRange);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ rVal += nCellVal;
+ rValCount++;
+ SetError(nErr);
+ while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr))
+ {
+ rVal += nCellVal;
+ rValCount++;
+ }
+ SetError(nErr);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ {
+ rVal += pMat->GetDouble(nElem);
+ rValCount++;
+ }
+ }
+ else
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ if (!pMat->IsString(nElem))
+ {
+ rVal += pMat->GetDouble(nElem);
+ rValCount++;
+ }
+ }
+ }
+ }
+ break;
+ default :
+ SetError(errIllegalParameter);
+ break;
+ }
+ }
+ if (nGlobalError)
+ {
+ PushError( nGlobalError);
+ return;
+ }
+ nMiddle = rVal / rValCount;
+ sp = SaveSP;
+ rVal = 0.0;
+ nParam = nParamCount;
+ nRefInList = 0;
+ while (nParam-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble :
+ rVal += fabs(GetDouble() - nMiddle);
+ break;
+ case svSingleRef :
+ {
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ rVal += fabs(GetCellValue( aAdr, pCell ) - nMiddle);
+ }
+ break;
+ case formula::svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ double nCellVal;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ ScValueIterator aValIter(pDok, aRange);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ rVal += (fabs(nCellVal - nMiddle));
+ while (aValIter.GetNext(nCellVal, nErr))
+ rVal += fabs(nCellVal - nMiddle);
+ }
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nCount = pMat->GetElementCount();
+ if (pMat->IsNumeric())
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ {
+ rVal += fabs(pMat->GetDouble(nElem) - nMiddle);
+ }
+ }
+ else
+ {
+ for (SCSIZE nElem = 0; nElem < nCount; nElem++)
+ {
+ if (!pMat->IsString(nElem))
+ rVal += fabs(pMat->GetDouble(nElem) - nMiddle);
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ }
+ PushDouble(rVal / rValCount);
+}
+
+void ScInterpreter::ScDevSq()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDevSq" );
+ double nVal;
+ double nValCount;
+ GetStVarParams(nVal, nValCount);
+ PushDouble(nVal);
+}
+
+void ScInterpreter::ScProbability()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScProbability" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
+ return;
+ double fUp, fLo;
+ fUp = GetDouble();
+ if (nParamCount == 4)
+ fLo = GetDouble();
+ else
+ fLo = fUp;
+ if (fLo > fUp)
+ {
+ double fTemp = fLo;
+ fLo = fUp;
+ fUp = fTemp;
+ }
+ ScMatrixRef pMatP = GetMatrix();
+ ScMatrixRef pMatW = GetMatrix();
+ if (!pMatP || !pMatW)
+ PushIllegalParameter();
+ else
+ {
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMatP->GetDimensions(nC1, nR1);
+ pMatW->GetDimensions(nC2, nR2);
+ if (nC1 != nC2 || nR1 != nR2 || nC1 == 0 || nR1 == 0 ||
+ nC2 == 0 || nR2 == 0)
+ PushNA();
+ else
+ {
+ double fSum = 0.0;
+ double fRes = 0.0;
+ BOOL bStop = FALSE;
+ double fP, fW;
+ SCSIZE nCount1 = nC1 * nR1;
+ for ( SCSIZE i = 0; i < nCount1 && !bStop; i++ )
+ {
+ if (pMatP->IsValue(i) && pMatW->IsValue(i))
+ {
+ fP = pMatP->GetDouble(i);
+ fW = pMatW->GetDouble(i);
+ if (fP < 0.0 || fP > 1.0)
+ bStop = TRUE;
+ else
+ {
+ fSum += fP;
+ if (fW >= fLo && fW <= fUp)
+ fRes += fP;
+ }
+ }
+ else
+ SetError( errIllegalArgument);
+ }
+ if (bStop || fabs(fSum -1.0) > 1.0E-7)
+ PushNoValue();
+ else
+ PushDouble(fRes);
+ }
+ }
+}
+
+void ScInterpreter::ScCorrel()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCorrel" );
+ // This is identical to ScPearson()
+ ScPearson();
+}
+
+void ScInterpreter::ScCovar()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCovar" );
+ CalculatePearsonCovar(FALSE,FALSE);
+}
+
+void ScInterpreter::ScPearson()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPearson" );
+ CalculatePearsonCovar(TRUE,FALSE);
+}
+void ScInterpreter::CalculatePearsonCovar(BOOL _bPearson,BOOL _bStexy)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculatePearsonCovar" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ ScMatrixRef pMat1 = GetMatrix();
+ ScMatrixRef pMat2 = GetMatrix();
+ if (!pMat1 || !pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ if (nR1 != nR2 || nC1 != nC2)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ /* #i78250#
+ * (sum((X-MeanX)(Y-MeanY)))/N equals (SumXY)/N-MeanX*MeanY mathematically,
+ * but the latter produces wrong results if the absolute values are high,
+ * for example above 10^8
+ */
+ double fCount = 0.0;
+ double fSumX = 0.0;
+ double fSumY = 0.0;
+ double fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY)
+ double fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2
+ double fSumSqrDeltaY = 0.0; // sum of (ValY-MeanY)^2
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ double fValX = pMat1->GetDouble(i,j);
+ double fValY = pMat2->GetDouble(i,j);
+ fSumX += fValX;
+ fSumY += fValY;
+ fCount++;
+ }
+ }
+ }
+ if (fCount < (_bStexy ? 3.0 : 1.0)) // fCount==1 is handled by checking denominator later on
+ PushNoValue();
+ else
+ {
+ const double fMeanX = fSumX / fCount;
+ const double fMeanY = fSumY / fCount;
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ const double fValX = pMat1->GetDouble(i,j);
+ const double fValY = pMat2->GetDouble(i,j);
+ fSumDeltaXDeltaY += (fValX - fMeanX) * (fValY - fMeanY);
+ if ( _bPearson )
+ {
+ fSumSqrDeltaX += (fValX - fMeanX) * (fValX - fMeanX);
+ fSumSqrDeltaY += (fValY - fMeanY) * (fValY - fMeanY);
+ }
+ }
+ }
+ } // for (SCSIZE i = 0; i < nC1; i++)
+ if ( _bPearson )
+ {
+ if (fSumSqrDeltaX == 0.0 || ( !_bStexy && fSumSqrDeltaY == 0.0) )
+ PushError( errDivisionByZero);
+ else if ( _bStexy )
+ PushDouble( sqrt( (fSumSqrDeltaY - fSumDeltaXDeltaY *
+ fSumDeltaXDeltaY / fSumSqrDeltaX) / (fCount-2)));
+ else
+ PushDouble( fSumDeltaXDeltaY / sqrt( fSumSqrDeltaX * fSumSqrDeltaY));
+ } // if ( _bPearson )
+ else
+ {
+ PushDouble( fSumDeltaXDeltaY / fCount);
+ }
+ }
+}
+
+void ScInterpreter::ScRSQ()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRSQ" );
+ // Same as ScPearson()*ScPearson()
+ ScPearson();
+ if (!nGlobalError)
+ {
+ switch (GetStackType())
+ {
+ case formula::svDouble:
+ {
+ double fVal = PopDouble();
+ PushDouble( fVal * fVal);
+ }
+ break;
+ default:
+ PopError();
+ PushNoValue();
+ }
+ }
+}
+
+void ScInterpreter::ScSTEXY()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSTEXY" );
+ CalculatePearsonCovar(TRUE,TRUE);
+}
+void ScInterpreter::CalculateSlopeIntercept(BOOL bSlope)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSlopeIntercept" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+ ScMatrixRef pMat1 = GetMatrix();
+ ScMatrixRef pMat2 = GetMatrix();
+ if (!pMat1 || !pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ if (nR1 != nR2 || nC1 != nC2)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ // #i78250# numerical stability improved
+ double fCount = 0.0;
+ double fSumX = 0.0;
+ double fSumY = 0.0;
+ double fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY)
+ double fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ double fValX = pMat1->GetDouble(i,j);
+ double fValY = pMat2->GetDouble(i,j);
+ fSumX += fValX;
+ fSumY += fValY;
+ fCount++;
+ }
+ }
+ }
+ if (fCount < 1.0)
+ PushNoValue();
+ else
+ {
+ double fMeanX = fSumX / fCount;
+ double fMeanY = fSumY / fCount;
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ double fValX = pMat1->GetDouble(i,j);
+ double fValY = pMat2->GetDouble(i,j);
+ fSumDeltaXDeltaY += (fValX - fMeanX) * (fValY - fMeanY);
+ fSumSqrDeltaX += (fValX - fMeanX) * (fValX - fMeanX);
+ }
+ }
+ }
+ if (fSumSqrDeltaX == 0.0)
+ PushError( errDivisionByZero);
+ else
+ {
+ if ( bSlope )
+ PushDouble( fSumDeltaXDeltaY / fSumSqrDeltaX);
+ else
+ PushDouble( fMeanY - fSumDeltaXDeltaY / fSumSqrDeltaX * fMeanX);
+ }
+ }
+}
+
+void ScInterpreter::ScSlope()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSlope" );
+ CalculateSlopeIntercept(TRUE);
+}
+
+void ScInterpreter::ScIntercept()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIntercept" );
+ CalculateSlopeIntercept(FALSE);
+}
+
+void ScInterpreter::ScForecast()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScForecast" );
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+ ScMatrixRef pMat1 = GetMatrix();
+ ScMatrixRef pMat2 = GetMatrix();
+ if (!pMat1 || !pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ if (nR1 != nR2 || nC1 != nC2)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double fVal = GetDouble();
+ // #i78250# numerical stability improved
+ double fCount = 0.0;
+ double fSumX = 0.0;
+ double fSumY = 0.0;
+ double fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY)
+ double fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ double fValX = pMat1->GetDouble(i,j);
+ double fValY = pMat2->GetDouble(i,j);
+ fSumX += fValX;
+ fSumY += fValY;
+ fCount++;
+ }
+ }
+ }
+ if (fCount < 1.0)
+ PushNoValue();
+ else
+ {
+ double fMeanX = fSumX / fCount;
+ double fMeanY = fSumY / fCount;
+ for (SCSIZE i = 0; i < nC1; i++)
+ {
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ double fValX = pMat1->GetDouble(i,j);
+ double fValY = pMat2->GetDouble(i,j);
+ fSumDeltaXDeltaY += (fValX - fMeanX) * (fValY - fMeanY);
+ fSumSqrDeltaX += (fValX - fMeanX) * (fValX - fMeanX);
+ }
+ }
+ }
+ if (fSumSqrDeltaX == 0.0)
+ PushError( errDivisionByZero);
+ else
+ PushDouble( fMeanY + fSumDeltaXDeltaY / fSumSqrDeltaX * (fVal - fMeanX));
+ }
+}
+
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
new file mode 100644
index 000000000000..47cde7186067
--- /dev/null
+++ b/sc/source/core/tool/interpr4.cxx
@@ -0,0 +1,3979 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <rangelst.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbx.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/logfile.hxx>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include "interpre.hxx"
+#include "global.hxx"
+#include "dbcolect.hxx"
+#include "cell.hxx"
+#include "callform.hxx"
+#include "addincol.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "docoptio.hxx"
+#include "scmatrix.hxx"
+#include "adiasync.hxx"
+#include "sc.hrc"
+#include "cellsuno.hxx"
+#include "optuno.hxx"
+#include "rangeseq.hxx"
+#include "addinlis.hxx"
+#include "jumpmatrix.hxx"
+#include "parclass.hxx"
+#include "externalrefmgr.hxx"
+#include "doubleref.hxx"
+
+#include <math.h>
+#include <float.h>
+#include <map>
+#include <algorithm>
+#include <functional>
+#include <memory>
+
+using namespace com::sun::star;
+using namespace formula;
+using ::std::auto_ptr;
+
+#define ADDIN_MAXSTRLEN 256
+
+//-----------------------------static data -----------------
+
+//-------------------------------------------------------------------------
+// Funktionen fuer den Zugriff auf das Document
+//-------------------------------------------------------------------------
+
+
+void ScInterpreter::ReplaceCell( ScAddress& rPos )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ReplaceCell" );
+ ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
+ while (pTOp)
+ {
+ if ( rPos == pTOp->aOld1 )
+ {
+ rPos = pTOp->aNew1;
+ return ;
+ }
+ else if ( rPos == pTOp->aOld2 )
+ {
+ rPos = pTOp->aNew2;
+ return ;
+ }
+ else
+ pTOp = pDok->aTableOpList.Next();
+ }
+}
+
+
+void ScInterpreter::ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ReplaceCell" );
+ ScAddress aCellPos( rCol, rRow, rTab );
+ ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
+ while (pTOp)
+ {
+ if ( aCellPos == pTOp->aOld1 )
+ {
+ rCol = pTOp->aNew1.Col();
+ rRow = pTOp->aNew1.Row();
+ rTab = pTOp->aNew1.Tab();
+ return ;
+ }
+ else if ( aCellPos == pTOp->aOld2 )
+ {
+ rCol = pTOp->aNew2.Col();
+ rRow = pTOp->aNew2.Row();
+ rTab = pTOp->aNew2.Tab();
+ return ;
+ }
+ else
+ pTOp = pDok->aTableOpList.Next();
+ }
+}
+
+
+BOOL ScInterpreter::IsTableOpInRange( const ScRange& rRange )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsTableOpInRange" );
+ if ( rRange.aStart == rRange.aEnd )
+ return FALSE; // not considered to be a range in TableOp sense
+
+ // we can't replace a single cell in a range
+ ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
+ while (pTOp)
+ {
+ if ( rRange.In( pTOp->aOld1 ) )
+ return TRUE;
+ if ( rRange.In( pTOp->aOld2 ) )
+ return TRUE;
+ pTOp = pDok->aTableOpList.Next();
+ }
+ return FALSE;
+}
+
+
+ULONG ScInterpreter::GetCellNumberFormat( const ScAddress& rPos, const ScBaseCell* pCell)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellNumberFormat" );
+ ULONG nFormat;
+ USHORT nErr;
+ if ( pCell )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ nErr = ((ScFormulaCell*)pCell)->GetErrCode();
+ else
+ nErr = 0;
+ nFormat = pDok->GetNumberFormat( rPos );
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) )
+ nFormat = ((ScFormulaCell*)pCell)->GetStandardFormat( *pFormatter,
+ nFormat );
+ }
+ else
+ {
+ nFormat = pDok->GetNumberFormat( rPos );
+ nErr = 0;
+ }
+ SetError(nErr);
+ return nFormat;
+}
+
+
+/// Only ValueCell, formula cells already store the result rounded.
+double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCell* pCell )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetValueCellValue" );
+ double fVal = pCell->GetValue();
+ if ( bCalcAsShown && fVal != 0.0 )
+ {
+ ULONG nFormat = pDok->GetNumberFormat( rPos );
+ fVal = pDok->RoundValueAsShown( fVal, nFormat );
+ }
+ return fVal;
+}
+
+
+/** Convert string content to numeric value.
+
+ Converted are only integer numbers including exponent, and ISO 8601 dates
+ and times in their extended formats with separators. Anything else,
+ especially fractional numeric values with decimal separators or dates other
+ than ISO 8601 would be locale dependent and is a no-no. Leading and
+ trailing blanks are ignored.
+
+ The following ISO 8601 formats are converted:
+
+ CCYY-MM-DD
+ CCYY-MM-DDThh:mm
+ CCYY-MM-DDThh:mm:ss
+ CCYY-MM-DDThh:mm:ss,s
+ CCYY-MM-DDThh:mm:ss.s
+ hh:mm
+ hh:mm:ss
+ hh:mm:ss,s
+ hh:mm:ss.s
+
+ The century CC may not be omitted and the two-digit year setting is not
+ taken into account. Instead of the T date and time separator exactly one
+ blank may be used.
+
+ If a date is given, it must be a valid Gregorian calendar date. In this
+ case the optional time must be in the range 00:00 to 23:59:59.99999...
+ If only time is given, it may have any value for hours, taking elapsed time
+ into account; minutes and seconds are limited to the value 59 as well.
+ */
+
+double ScInterpreter::ConvertStringToValue( const String& rStr )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertStringToValue" );
+ double fValue = 0.0;
+ if (mnStringNoValueError == errCellNoValue)
+ {
+ // Requested that all strings result in 0, error handled by caller.
+ SetError( mnStringNoValueError);
+ return fValue;
+ }
+ ::rtl::OUString aStr( rStr);
+ rtl_math_ConversionStatus eStatus;
+ sal_Int32 nParseEnd;
+ // Decimal and group separator 0 => only integer and possibly exponent,
+ // stops at first non-digit non-sign.
+ fValue = ::rtl::math::stringToDouble( aStr, 0, 0, &eStatus, &nParseEnd);
+ sal_Int32 nLen;
+ if (eStatus == rtl_math_ConversionStatus_Ok && nParseEnd < (nLen = aStr.getLength()))
+ {
+ // Not at string end, check for trailing blanks or switch to date or
+ // time parsing or bail out.
+ const sal_Unicode* const pStart = aStr.getStr();
+ const sal_Unicode* p = pStart + nParseEnd;
+ const sal_Unicode* const pStop = pStart + nLen;
+ switch (*p++)
+ {
+ case ' ':
+ while (p < pStop && *p == ' ')
+ ++p;
+ if (p < pStop)
+ SetError( mnStringNoValueError);
+ break;
+ case '-':
+ case ':':
+ {
+ bool bDate = (*(p-1) == '-');
+ enum State { year = 0, month, day, hour, minute, second, fraction, done, blank, stop };
+ sal_Int32 nUnit[done] = {0,0,0,0,0,0,0};
+ const sal_Int32 nLimit[done] = {0,12,31,0,59,59,0};
+ State eState = (bDate ? month : minute);
+ nCurFmtType = (bDate ? NUMBERFORMAT_DATE : NUMBERFORMAT_TIME);
+ nUnit[eState-1] = aStr.copy( 0, nParseEnd).toInt32();
+ const sal_Unicode* pLastStart = p;
+ // Ensure there's no preceding sign. Negative dates
+ // currently aren't handled correctly. Also discard
+ // +CCYY-MM-DD
+ p = pStart;
+ while (p < pStop && *p == ' ')
+ ++p;
+ if (p < pStop && !CharClass::isAsciiDigit(*p))
+ SetError( mnStringNoValueError);
+ p = pLastStart;
+ while (p < pStop && !nGlobalError && eState < blank)
+ {
+ if (eState == minute)
+ nCurFmtType |= NUMBERFORMAT_TIME;
+ if (CharClass::isAsciiDigit(*p))
+ {
+ // Maximum 2 digits per unit, except fractions.
+ if (p - pLastStart >= 2 && eState != fraction)
+ SetError( mnStringNoValueError);
+ }
+ else if (p > pLastStart)
+ {
+ // We had at least one digit.
+ if (eState < done)
+ {
+ nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32();
+ if (nLimit[eState] && nLimit[eState] < nUnit[eState])
+ SetError( mnStringNoValueError);
+ }
+ pLastStart = p + 1; // hypothetical next start
+ // Delimiters must match, a trailing delimiter
+ // yields an invalid date/time.
+ switch (eState)
+ {
+ case month:
+ // Month must be followed by separator and
+ // day, no trailing blanks.
+ if (*p != '-' || (p+1 == pStop))
+ SetError( mnStringNoValueError);
+ break;
+ case day:
+ if ((*p != 'T' || (p+1 == pStop)) && *p != ' ')
+ SetError( mnStringNoValueError);
+ // Take one blank as a valid delimiter
+ // between date and time.
+ break;
+ case hour:
+ // Hour must be followed by separator and
+ // minute, no trailing blanks.
+ if (*p != ':' || (p+1 == pStop))
+ SetError( mnStringNoValueError);
+ break;
+ case minute:
+ if ((*p != ':' || (p+1 == pStop)) && *p != ' ')
+ SetError( mnStringNoValueError);
+ if (*p == ' ')
+ eState = done;
+ break;
+ case second:
+ if (((*p != ',' && *p != '.') || (p+1 == pStop)) && *p != ' ')
+ SetError( mnStringNoValueError);
+ if (*p == ' ')
+ eState = done;
+ break;
+ case fraction:
+ eState = done;
+ break;
+ case year:
+ case done:
+ case blank:
+ case stop:
+ SetError( mnStringNoValueError);
+ break;
+ }
+ eState = static_cast<State>(eState + 1);
+ }
+ else
+ SetError( mnStringNoValueError);
+ ++p;
+ }
+ if (eState == blank)
+ {
+ while (p < pStop && *p == ' ')
+ ++p;
+ if (p < pStop)
+ SetError( mnStringNoValueError);
+ eState = stop;
+ }
+
+ // Month without day, or hour without minute.
+ if (eState == month || (eState == day && p <= pLastStart) ||
+ eState == hour || (eState == minute && p <= pLastStart))
+ SetError( mnStringNoValueError);
+
+ if (!nGlobalError)
+ {
+ // Catch the very last unit at end of string.
+ if (p > pLastStart && eState < done)
+ {
+ nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32();
+ if (nLimit[eState] && nLimit[eState] < nUnit[eState])
+ SetError( mnStringNoValueError);
+ }
+ if (bDate && nUnit[hour] > 23)
+ SetError( mnStringNoValueError);
+ if (!nGlobalError)
+ {
+ if (bDate && nUnit[day] == 0)
+ nUnit[day] = 1;
+ double fFraction = (nUnit[fraction] <= 0 ? 0.0 :
+ ::rtl::math::pow10Exp( nUnit[fraction],
+ static_cast<int>( -ceil( log10( static_cast<double>( nUnit[fraction]))))));
+ fValue = (bDate ? GetDateSerial(
+ sal::static_int_cast<INT16>(nUnit[year]),
+ sal::static_int_cast<INT16>(nUnit[month]),
+ sal::static_int_cast<INT16>(nUnit[day]),
+ true) : 0.0);
+ fValue += ((nUnit[hour] * 3600) + (nUnit[minute] * 60) + nUnit[second] + fFraction) / 86400.0;
+ }
+ }
+ }
+ break;
+ default:
+ SetError( mnStringNoValueError);
+ }
+ if (nGlobalError)
+ fValue = 0.0;
+ }
+ return fValue;
+}
+
+
+double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCell )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValue" );
+ USHORT nErr = nGlobalError;
+ nGlobalError = 0;
+ double nVal = GetCellValueOrZero( rPos, pCell );
+ if ( !nGlobalError || nGlobalError == errCellNoValue )
+ nGlobalError = nErr;
+ return nVal;
+}
+
+
+double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCell* pCell )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValueOrZero" );
+ double fValue = 0.0;
+ if (pCell)
+ {
+ CellType eType = pCell->GetCellType();
+ switch ( eType )
+ {
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ USHORT nErr = pFCell->GetErrCode();
+ if( !nErr )
+ {
+ if (pFCell->IsValue())
+ {
+ fValue = pFCell->GetValue();
+ pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex,
+ rPos, pFCell );
+ }
+ else
+ {
+ String aStr;
+ pFCell->GetString( aStr );
+ fValue = ConvertStringToValue( aStr );
+ }
+ }
+ else
+ {
+ fValue = 0.0;
+ SetError(nErr);
+ }
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ fValue = ((ScValueCell*)pCell)->GetValue();
+ nCurFmtIndex = pDok->GetNumberFormat( rPos );
+ nCurFmtType = pFormatter->GetType( nCurFmtIndex );
+ if ( bCalcAsShown && fValue != 0.0 )
+ fValue = pDok->RoundValueAsShown( fValue, nCurFmtIndex );
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ // SUM(A1:A2) differs from A1+A2. No good. But people insist on
+ // it ... #i5658#
+ String aStr;
+ if ( eType == CELLTYPE_STRING )
+ ((ScStringCell*)pCell)->GetString( aStr );
+ else
+ ((ScEditCell*)pCell)->GetString( aStr );
+ fValue = ConvertStringToValue( aStr );
+ }
+ break;
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ fValue = 0.0; // empty or broadcaster cell
+ break;
+ case CELLTYPE_SYMBOLS:
+#if DBG_UTIL
+ case CELLTYPE_DESTROYED:
+#endif
+ SetError(errCellNoValue);
+ fValue = 0.0;
+ break;
+ }
+ }
+ else
+ fValue = 0.0;
+ return fValue;
+}
+
+
+void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellString" );
+ USHORT nErr = 0;
+ if (pCell)
+ {
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_STRING:
+ ((ScStringCell*) pCell)->GetString(rStr);
+ break;
+ case CELLTYPE_EDIT:
+ ((ScEditCell*) pCell)->GetString(rStr);
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ nErr = pFCell->GetErrCode();
+ if (pFCell->IsValue())
+ {
+ double fVal = pFCell->GetValue();
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ pFormatter->GetInputLineString(fVal, nIndex, rStr);
+ }
+ else
+ pFCell->GetString(rStr);
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ double fVal = ((ScValueCell*) pCell)->GetValue();
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ pFormatter->GetInputLineString(fVal, nIndex, rStr);
+ }
+ break;
+ default:
+ rStr = ScGlobal::GetEmptyString();
+ break;
+ }
+ }
+ else
+ rStr = ScGlobal::GetEmptyString();
+ SetError(nErr);
+}
+
+
+BOOL ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateDoubleArr" );
+
+ // Old Add-Ins are hard limited to USHORT values.
+#if MAXCOLCOUNT_DEFINE > USHRT_MAX
+#error Add check for columns > USHRT_MAX!
+#endif
+ if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ return FALSE;
+
+ USHORT nCount = 0;
+ USHORT* p = (USHORT*) pCellArr;
+ *p++ = static_cast<USHORT>(nCol1);
+ *p++ = static_cast<USHORT>(nRow1);
+ *p++ = static_cast<USHORT>(nTab1);
+ *p++ = static_cast<USHORT>(nCol2);
+ *p++ = static_cast<USHORT>(nRow2);
+ *p++ = static_cast<USHORT>(nTab2);
+ USHORT* pCount = p;
+ *p++ = 0;
+ USHORT nPos = 14;
+ SCTAB nTab = nTab1;
+ ScAddress aAdr;
+ while (nTab <= nTab2)
+ {
+ aAdr.SetTab( nTab );
+ SCROW nRow = nRow1;
+ while (nRow <= nRow2)
+ {
+ aAdr.SetRow( nRow );
+ SCCOL nCol = nCol1;
+ while (nCol <= nCol2)
+ {
+ aAdr.SetCol( nCol );
+ ScBaseCell* pCell = pDok->GetCell( aAdr );
+ if (pCell)
+ {
+ USHORT nErr = 0;
+ double nVal = 0.0;
+ BOOL bOk = TRUE;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ nVal = GetValueCellValue( aAdr, (ScValueCell*)pCell );
+ break;
+ case CELLTYPE_FORMULA :
+ if (((ScFormulaCell*)pCell)->IsValue())
+ {
+ nErr = ((ScFormulaCell*)pCell)->GetErrCode();
+ nVal = ((ScFormulaCell*)pCell)->GetValue();
+ }
+ else
+ bOk = FALSE;
+ break;
+ default :
+ bOk = FALSE;
+ break;
+ }
+ if (bOk)
+ {
+ if ((nPos + (4 * sizeof(USHORT)) + sizeof(double)) > MAXARRSIZE)
+ return FALSE;
+ *p++ = static_cast<USHORT>(nCol);
+ *p++ = static_cast<USHORT>(nRow);
+ *p++ = static_cast<USHORT>(nTab);
+ *p++ = nErr;
+ memcpy( p, &nVal, sizeof(double));
+ nPos += 8 + sizeof(double);
+ p = (USHORT*) ( pCellArr + nPos );
+ nCount++;
+ }
+ }
+ nCol++;
+ }
+ nRow++;
+ }
+ nTab++;
+ }
+ *pCount = nCount;
+ return TRUE;
+}
+
+
+BOOL ScInterpreter::CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ BYTE* pCellArr)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateStringArr" );
+
+ // Old Add-Ins are hard limited to USHORT values.
+#if MAXCOLCOUNT_DEFINE > USHRT_MAX
+#error Add check for columns > USHRT_MAX!
+#endif
+ if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ return FALSE;
+
+ USHORT nCount = 0;
+ USHORT* p = (USHORT*) pCellArr;
+ *p++ = static_cast<USHORT>(nCol1);
+ *p++ = static_cast<USHORT>(nRow1);
+ *p++ = static_cast<USHORT>(nTab1);
+ *p++ = static_cast<USHORT>(nCol2);
+ *p++ = static_cast<USHORT>(nRow2);
+ *p++ = static_cast<USHORT>(nTab2);
+ USHORT* pCount = p;
+ *p++ = 0;
+ USHORT nPos = 14;
+ SCTAB nTab = nTab1;
+ while (nTab <= nTab2)
+ {
+ SCROW nRow = nRow1;
+ while (nRow <= nRow2)
+ {
+ SCCOL nCol = nCol1;
+ while (nCol <= nCol2)
+ {
+ ScBaseCell* pCell;
+ pDok->GetCell(nCol, nRow, nTab, pCell);
+ if (pCell)
+ {
+ String aStr;
+ USHORT nErr = 0;
+ BOOL bOk = TRUE;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_STRING :
+ ((ScStringCell*)pCell)->GetString(aStr);
+ break;
+ case CELLTYPE_EDIT :
+ ((ScEditCell*)pCell)->GetString(aStr);
+ break;
+ case CELLTYPE_FORMULA :
+ if (!((ScFormulaCell*)pCell)->IsValue())
+ {
+ nErr = ((ScFormulaCell*)pCell)->GetErrCode();
+ ((ScFormulaCell*)pCell)->GetString(aStr);
+ }
+ else
+ bOk = FALSE;
+ break;
+ default :
+ bOk = FALSE;
+ break;
+ }
+ if (bOk)
+ {
+ ByteString aTmp( aStr, osl_getThreadTextEncoding() );
+ // In case the xub_StrLen will be longer than USHORT
+ // one day, and room for pad byte check.
+ if ( aTmp.Len() > ((USHORT)(~0)) - 2 )
+ return FALSE;
+ // Append a 0-pad-byte if string length is not even
+ //! MUST be USHORT and not xub_StrLen
+ USHORT nStrLen = (USHORT) aTmp.Len();
+ USHORT nLen = ( nStrLen + 2 ) & ~1;
+
+ if (((ULONG)nPos + (5 * sizeof(USHORT)) + nLen) > MAXARRSIZE)
+ return FALSE;
+ *p++ = static_cast<USHORT>(nCol);
+ *p++ = static_cast<USHORT>(nRow);
+ *p++ = static_cast<USHORT>(nTab);
+ *p++ = nErr;
+ *p++ = nLen;
+ memcpy( p, aTmp.GetBuffer(), nStrLen + 1);
+ nPos += 10 + nStrLen + 1;
+ BYTE* q = ( pCellArr + nPos );
+ if( !nStrLen & 1 )
+ *q++ = 0, nPos++;
+ p = (USHORT*) ( pCellArr + nPos );
+ nCount++;
+ }
+ }
+ nCol++;
+ }
+ nRow++;
+ }
+ nTab++;
+ }
+ *pCount = nCount;
+ return TRUE;
+}
+
+
+BOOL ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ BYTE* pCellArr)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateCellArr" );
+
+ // Old Add-Ins are hard limited to USHORT values.
+#if MAXCOLCOUNT_DEFINE > USHRT_MAX
+#error Add check for columns > USHRT_MAX!
+#endif
+ if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ return FALSE;
+
+ USHORT nCount = 0;
+ USHORT* p = (USHORT*) pCellArr;
+ *p++ = static_cast<USHORT>(nCol1);
+ *p++ = static_cast<USHORT>(nRow1);
+ *p++ = static_cast<USHORT>(nTab1);
+ *p++ = static_cast<USHORT>(nCol2);
+ *p++ = static_cast<USHORT>(nRow2);
+ *p++ = static_cast<USHORT>(nTab2);
+ USHORT* pCount = p;
+ *p++ = 0;
+ USHORT nPos = 14;
+ SCTAB nTab = nTab1;
+ ScAddress aAdr;
+ while (nTab <= nTab2)
+ {
+ aAdr.SetTab( nTab );
+ SCROW nRow = nRow1;
+ while (nRow <= nRow2)
+ {
+ aAdr.SetRow( nRow );
+ SCCOL nCol = nCol1;
+ while (nCol <= nCol2)
+ {
+ aAdr.SetCol( nCol );
+ ScBaseCell* pCell = pDok->GetCell( aAdr );
+ if (pCell)
+ {
+ USHORT nErr = 0;
+ USHORT nType = 0; // 0 = Zahl; 1 = String
+ double nVal = 0.0;
+ String aStr;
+ BOOL bOk = TRUE;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_STRING :
+ ((ScStringCell*)pCell)->GetString(aStr);
+ nType = 1;
+ break;
+ case CELLTYPE_EDIT :
+ ((ScEditCell*)pCell)->GetString(aStr);
+ nType = 1;
+ break;
+ case CELLTYPE_VALUE :
+ nVal = GetValueCellValue( aAdr, (ScValueCell*)pCell );
+ break;
+ case CELLTYPE_FORMULA :
+ nErr = ((ScFormulaCell*)pCell)->GetErrCode();
+ if (((ScFormulaCell*)pCell)->IsValue())
+ nVal = ((ScFormulaCell*)pCell)->GetValue();
+ else
+ ((ScFormulaCell*)pCell)->GetString(aStr);
+ break;
+ default :
+ bOk = FALSE;
+ break;
+ }
+ if (bOk)
+ {
+ if ((nPos + (5 * sizeof(USHORT))) > MAXARRSIZE)
+ return FALSE;
+ *p++ = static_cast<USHORT>(nCol);
+ *p++ = static_cast<USHORT>(nRow);
+ *p++ = static_cast<USHORT>(nTab);
+ *p++ = nErr;
+ *p++ = nType;
+ nPos += 10;
+ if (nType == 0)
+ {
+ if ((nPos + sizeof(double)) > MAXARRSIZE)
+ return FALSE;
+ memcpy( p, &nVal, sizeof(double));
+ nPos += sizeof(double);
+ }
+ else
+ {
+ ByteString aTmp( aStr, osl_getThreadTextEncoding() );
+ // In case the xub_StrLen will be longer than USHORT
+ // one day, and room for pad byte check.
+ if ( aTmp.Len() > ((USHORT)(~0)) - 2 )
+ return FALSE;
+ // Append a 0-pad-byte if string length is not even
+ //! MUST be USHORT and not xub_StrLen
+ USHORT nStrLen = (USHORT) aTmp.Len();
+ USHORT nLen = ( nStrLen + 2 ) & ~1;
+ if ( ((ULONG)nPos + 2 + nLen) > MAXARRSIZE)
+ return FALSE;
+ *p++ = nLen;
+ memcpy( p, aTmp.GetBuffer(), nStrLen + 1);
+ nPos += 2 + nStrLen + 1;
+ BYTE* q = ( pCellArr + nPos );
+ if( !nStrLen & 1 )
+ *q++ = 0, nPos++;
+ }
+ nCount++;
+ p = (USHORT*) ( pCellArr + nPos );
+ }
+ }
+ nCol++;
+ }
+ nRow++;
+ }
+ nTab++;
+ }
+ *pCount = nCount;
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Stack operations
+//-----------------------------------------------------------------------------
+
+
+// Also releases a TempToken if appropriate.
+
+void ScInterpreter::PushWithoutError( FormulaToken& r )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushWithoutError" );
+ if ( sp >= MAXSTACK )
+ SetError( errStackOverflow );
+ else
+ {
+ nCurFmtType = NUMBERFORMAT_UNDEFINED;
+ r.IncRef();
+ if( sp >= maxsp )
+ maxsp = sp + 1;
+ else
+ pStack[ sp ]->DecRef();
+ pStack[ sp ] = (ScToken*) &r;
+ ++sp;
+ }
+}
+
+void ScInterpreter::Push( FormulaToken& r )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Push" );
+ if ( sp >= MAXSTACK )
+ SetError( errStackOverflow );
+ else
+ {
+ if (nGlobalError)
+ {
+ if (r.GetType() == svError)
+ {
+ r.SetError( nGlobalError);
+ PushWithoutError( r);
+ }
+ else
+ PushWithoutError( *(new FormulaErrorToken( nGlobalError)));
+ }
+ else
+ PushWithoutError( r);
+ }
+}
+
+
+void ScInterpreter::PushTempToken( FormulaToken* p )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempToken" );
+ if ( sp >= MAXSTACK )
+ {
+ SetError( errStackOverflow );
+ if (!p->GetRef())
+ //! p is a dangling pointer hereafter!
+ p->Delete();
+ }
+ else
+ {
+ if (nGlobalError)
+ {
+ if (p->GetType() == svError)
+ {
+ p->SetError( nGlobalError);
+ PushTempTokenWithoutError( p);
+ }
+ else
+ {
+ if (!p->GetRef())
+ //! p is a dangling pointer hereafter!
+ p->Delete();
+ PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError));
+ }
+ }
+ else
+ PushTempTokenWithoutError( p);
+ }
+}
+
+
+void ScInterpreter::PushTempTokenWithoutError( FormulaToken* p )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempTokenWithoutError" );
+ p->IncRef();
+ if ( sp >= MAXSTACK )
+ {
+ SetError( errStackOverflow );
+ //! p may be a dangling pointer hereafter!
+ p->DecRef();
+ }
+ else
+ {
+ if( sp >= maxsp )
+ maxsp = sp + 1;
+ else
+ pStack[ sp ]->DecRef();
+ pStack[ sp ] = p;
+ ++sp;
+ }
+}
+
+
+void ScInterpreter::PushTempToken( const FormulaToken& r )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempToken" );
+ if (!IfErrorPushError())
+ PushTempTokenWithoutError( r.Clone());
+}
+
+
+void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
+ const ScAddress & rAddress, short * pRetTypeExpr, ULONG * pRetIndexExpr )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushCellResultToken" );
+ ScBaseCell* pCell = pDok->GetCell( rAddress);
+ if (!pCell || pCell->HasEmptyData())
+ {
+ if (pRetTypeExpr && pRetIndexExpr)
+ pDok->GetNumberFormatInfo( *pRetTypeExpr, *pRetIndexExpr, rAddress, pCell);
+ bool bInherited = (GetCellType( pCell) == CELLTYPE_FORMULA);
+ PushTempToken( new ScEmptyCellToken( bInherited, bDisplayEmptyAsString));
+ return;
+ }
+ USHORT nErr;
+ if ((nErr = pCell->GetErrorCode()) != 0)
+ {
+ PushError( nErr);
+ if (pRetTypeExpr)
+ *pRetTypeExpr = NUMBERFORMAT_UNDEFINED;
+ if (pRetIndexExpr)
+ *pRetIndexExpr = 0;
+ }
+ else if (pCell->HasStringData())
+ {
+ String aRes;
+ GetCellString( aRes, pCell);
+ PushString( aRes);
+ if (pRetTypeExpr)
+ *pRetTypeExpr = NUMBERFORMAT_TEXT;
+ if (pRetIndexExpr)
+ *pRetIndexExpr = 0;
+ }
+ else
+ {
+ double fVal = GetCellValue( rAddress, pCell);
+ PushDouble( fVal);
+ if (pRetTypeExpr)
+ *pRetTypeExpr = nCurFmtType;
+ if (pRetIndexExpr)
+ *pRetIndexExpr = nCurFmtIndex;
+ }
+}
+
+
+// Simply throw away TOS.
+
+void ScInterpreter::Pop()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Pop" );
+ if( sp )
+ sp--;
+ else
+ SetError(errUnknownStackVariable);
+}
+
+
+// Simply throw away TOS and set error code, used with ocIsError et al.
+
+void ScInterpreter::PopError()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopError" );
+ if( sp )
+ {
+ sp--;
+ if (pStack[sp]->GetType() == svError)
+ nGlobalError = pStack[sp]->GetError();
+ }
+ else
+ SetError(errUnknownStackVariable);
+}
+
+
+FormulaTokenRef ScInterpreter::PopToken()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopToken" );
+ if (sp)
+ {
+ sp--;
+ FormulaToken* p = pStack[ sp ];
+ if (p->GetType() == svError)
+ nGlobalError = p->GetError();
+ return p;
+ }
+ else
+ SetError(errUnknownStackVariable);
+ return NULL;
+}
+
+
+double ScInterpreter::PopDouble()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDouble" );
+ nCurFmtType = NUMBERFORMAT_NUMBER;
+ nCurFmtIndex = 0;
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svDouble:
+ return p->GetDouble();
+ case svEmptyCell:
+ case svMissing:
+ return 0.0;
+ default:
+ SetError( errIllegalArgument);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+ return 0.0;
+}
+
+
+const String& ScInterpreter::PopString()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopString" );
+ nCurFmtType = NUMBERFORMAT_TEXT;
+ nCurFmtIndex = 0;
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svString:
+ return p->GetString();
+ case svEmptyCell:
+ case svMissing:
+ return EMPTY_STRING;
+ default:
+ SetError( errIllegalArgument);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+ return EMPTY_STRING;
+}
+
+
+void ScInterpreter::ValidateRef( const ScSingleRefData & rRef )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ SingleRefToVars( rRef, nCol, nRow, nTab);
+}
+
+
+void ScInterpreter::ValidateRef( const ScComplexRefData & rRef )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
+ ValidateRef( rRef.Ref1);
+ ValidateRef( rRef.Ref2);
+}
+
+
+void ScInterpreter::ValidateRef( const ScRefList & rRefList )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
+ ScRefList::const_iterator it( rRefList.begin());
+ ScRefList::const_iterator end( rRefList.end());
+ for ( ; it != end; ++it)
+ {
+ ValidateRef( *it);
+ }
+}
+
+
+void ScInterpreter::SingleRefToVars( const ScSingleRefData & rRef,
+ SCCOL & rCol, SCROW & rRow, SCTAB & rTab )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::SingleRefToVars" );
+ if ( rRef.IsColRel() )
+ rCol = aPos.Col() + rRef.nRelCol;
+ else
+ rCol = rRef.nCol;
+ if ( rRef.IsRowRel() )
+ rRow = aPos.Row() + rRef.nRelRow;
+ else
+ rRow = rRef.nRow;
+ if ( rRef.IsTabRel() )
+ rTab = aPos.Tab() + rRef.nRelTab;
+ else
+ rTab = rRef.nTab;
+ if( !ValidCol( rCol) || rRef.IsColDeleted() )
+ SetError( errNoRef ), rCol = 0;
+ if( !ValidRow( rRow) || rRef.IsRowDeleted() )
+ SetError( errNoRef ), rRow = 0;
+ if( !ValidTab( rTab, pDok->GetTableCount() - 1) || rRef.IsTabDeleted() )
+ SetError( errNoRef ), rTab = 0;
+}
+
+
+void ScInterpreter::PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopSingleRef" );
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svSingleRef:
+ SingleRefToVars( static_cast<ScToken*>(p)->GetSingleRef(), rCol, rRow, rTab);
+ if ( pDok->aTableOpList.Count() > 0 )
+ ReplaceCell( rCol, rRow, rTab );
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+}
+
+
+void ScInterpreter::PopSingleRef( ScAddress& rAdr )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopSingleRef" );
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svSingleRef:
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ SingleRefToVars( static_cast<ScToken*>(p)->GetSingleRef(), nCol, nRow, nTab);
+ rAdr.Set( nCol, nRow, nTab );
+ if ( pDok->aTableOpList.Count() > 0 )
+ ReplaceCell( rAdr );
+ }
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+}
+
+
+void ScInterpreter::DoubleRefToVars( const ScToken* p,
+ SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
+ SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
+ BOOL bDontCheckForTableOp )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToVars" );
+ const ScComplexRefData& rCRef = p->GetDoubleRef();
+ SingleRefToVars( rCRef.Ref1, rCol1, rRow1, rTab1);
+ SingleRefToVars( rCRef.Ref2, rCol2, rRow2, rTab2);
+ if ( pDok->aTableOpList.Count() > 0 && !bDontCheckForTableOp )
+ {
+ ScRange aRange( rCol1, rRow1, rTab1, rCol2, rRow2, rTab2 );
+ if ( IsTableOpInRange( aRange ) )
+ SetError( errIllegalParameter );
+ }
+}
+
+ScDBRangeBase* ScInterpreter::PopDoubleRef()
+{
+ if (!sp)
+ {
+ SetError(errUnknownStackVariable);
+ return NULL;
+ }
+
+ --sp;
+ FormulaToken* p = pStack[sp];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svDoubleRef:
+ {
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ SCTAB nTab1, nTab2;
+ DoubleRefToVars(static_cast<ScToken*>(p),
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false);
+
+ return new ScDBInternalRange(pDok,
+ ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
+ }
+ case svMatrix:
+ {
+ ScMatrixRef pMat = static_cast<ScToken*>(p)->GetMatrix();
+ return new ScDBExternalRange(pDok, pMat);
+ }
+ default:
+ SetError( errIllegalParameter);
+ }
+ return NULL;
+}
+
+void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
+ SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
+ BOOL bDontCheckForTableOp )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svDoubleRef:
+ DoubleRefToVars( static_cast<ScToken*>(p), rCol1, rRow1, rTab1, rCol2, rRow2, rTab2,
+ bDontCheckForTableOp);
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+}
+
+
+void ScInterpreter::DoubleRefToRange( const ScComplexRefData & rCRef,
+ ScRange & rRange, BOOL bDontCheckForTableOp )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToRange" );
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ SingleRefToVars( rCRef.Ref1, nCol, nRow, nTab);
+ rRange.aStart.Set( nCol, nRow, nTab );
+ SingleRefToVars( rCRef.Ref2, nCol, nRow, nTab);
+ rRange.aEnd.Set( nCol, nRow, nTab );
+ if ( pDok->aTableOpList.Count() > 0 && !bDontCheckForTableOp )
+ {
+ if ( IsTableOpInRange( rRange ) )
+ SetError( errIllegalParameter );
+ }
+}
+
+
+void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
+ if (sp)
+ {
+ formula::FormulaToken* pToken = pStack[ sp-1 ];
+ ScToken* p = static_cast<ScToken*>(pToken);
+ switch (pToken->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svDoubleRef:
+ --sp;
+ DoubleRefToRange( p->GetDoubleRef(), rRange);
+ break;
+ case svRefList:
+ {
+ const ScRefList* pList = p->GetRefList();
+ if (rRefInList < pList->size())
+ {
+ DoubleRefToRange( (*pList)[rRefInList], rRange);
+ if (++rRefInList < pList->size())
+ ++rParam;
+ else
+ {
+ --sp;
+ rRefInList = 0;
+ }
+ }
+ else
+ {
+ --sp;
+ rRefInList = 0;
+ SetError( errIllegalParameter);
+ }
+ }
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+}
+
+
+void ScInterpreter::PopDoubleRef( ScRange& rRange, BOOL bDontCheckForTableOp )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svDoubleRef:
+ DoubleRefToRange( static_cast<ScToken*>(p)->GetDoubleRef(), rRange, bDontCheckForTableOp);
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+}
+
+
+BOOL ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefOrSingleRef" );
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, TRUE );
+ return DoubleRefToPosSingleRef( aRange, rAdr );
+ }
+ //break;
+ case svSingleRef :
+ {
+ PopSingleRef( rAdr );
+ return TRUE;
+ }
+ //break;
+ default:
+ PopError();
+ SetError( errNoRef );
+ }
+ return FALSE;
+}
+
+
+void ScInterpreter::PopDoubleRefPushMatrix()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefPushMatrix" );
+ if ( GetStackType() == svDoubleRef )
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if ( pMat )
+ PushMatrix( pMat );
+ else
+ PushIllegalParameter();
+ }
+ else
+ SetError( errNoRef );
+}
+
+
+ScTokenMatrixMap* ScInterpreter::CreateTokenMatrixMap()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateTokenMatrixMap" );
+ return new ScTokenMatrixMap;
+}
+
+
+bool ScInterpreter::ConvertMatrixParameters()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertMatrixParameters" );
+ USHORT nParams = pCur->GetParamCount();
+ DBG_ASSERT( nParams <= sp, "ConvertMatrixParameters: stack/param count mismatch");
+ SCSIZE nJumpCols = 0, nJumpRows = 0;
+ for ( USHORT i=1; i <= nParams && i <= sp; ++i )
+ {
+ FormulaToken* p = pStack[ sp - i ];
+ if ( p->GetOpCode() != ocPush )
+ {
+ DBG_ERRORFILE( "ConvertMatrixParameters: not a push");
+ }
+ else
+ {
+ switch ( p->GetType() )
+ {
+ case svDouble:
+ case svString:
+ case svSingleRef:
+ case svMissing:
+ case svError:
+ case svEmptyCell:
+ // nothing to do
+ break;
+ case svMatrix:
+ {
+ if ( ScParameterClassification::GetParameterType( pCur, nParams - i)
+ == ScParameterClassification::Value )
+ { // only if single value expected
+ ScMatrixRef pMat = static_cast<ScToken*>(p)->GetMatrix();
+ if ( !pMat )
+ SetError( errUnknownVariable);
+ else
+ {
+ SCSIZE nCols, nRows;
+ pMat->GetDimensions( nCols, nRows);
+ if ( nJumpCols < nCols )
+ nJumpCols = nCols;
+ if ( nJumpRows < nRows )
+ nJumpRows = nRows;
+ }
+ }
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScParameterClassification::Type eType =
+ ScParameterClassification::GetParameterType( pCur, nParams - i);
+ if ( eType != ScParameterClassification::Reference &&
+ eType != ScParameterClassification::ReferenceOrForceArray)
+ {
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ SCTAB nTab1, nTab2;
+ DoubleRefToVars( static_cast<const ScToken*>( p), nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ // Make sure the map exists, created if not.
+ GetTokenMatrixMap();
+ ScMatrixRef pMat = CreateMatrixFromDoubleRef( p,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (pMat)
+ {
+ if ( eType == ScParameterClassification::Value )
+ { // only if single value expected
+ if ( nJumpCols < static_cast<SCSIZE>(nCol2 - nCol1 + 1) )
+ nJumpCols = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
+ if ( nJumpRows < static_cast<SCSIZE>(nRow2 - nRow1 + 1) )
+ nJumpRows = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
+ }
+ ScToken* pNew = new ScMatrixToken( pMat);
+ pNew->IncRef();
+ pStack[ sp - i ] = pNew;
+ p->DecRef(); // p may be dead now!
+ }
+ }
+ }
+ break;
+ case svRefList:
+ {
+ ScParameterClassification::Type eType =
+ ScParameterClassification::GetParameterType( pCur, nParams - i);
+ if ( eType != ScParameterClassification::Reference &&
+ eType != ScParameterClassification::ReferenceOrForceArray)
+ {
+ // can't convert to matrix
+ SetError( errNoValue);
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "ConvertMatrixParameters: unknown parameter type");
+ }
+ }
+ }
+ if( nJumpCols && nJumpRows )
+ {
+ short nPC = aCode.GetPC();
+ short nStart = nPC - 1; // restart on current code (-1)
+ short nNext = nPC; // next instruction after subroutine
+ short nStop = nPC + 1; // stop subroutine before reaching that
+ FormulaTokenRef xNew;
+ ScTokenMatrixMap::const_iterator aMapIter;
+ if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find( pCur)) !=
+ pTokenMatrixMap->end()))
+ xNew = (*aMapIter).second;
+ else
+ {
+ ScJumpMatrix* pJumpMat = new ScJumpMatrix( nJumpCols, nJumpRows);
+ pJumpMat->SetAllJumps( 1.0, nStart, nNext, nStop);
+ // pop parameters and store in ScJumpMatrix, push in JumpMatrix()
+ ScTokenVec* pParams = new ScTokenVec( nParams);
+ for ( USHORT i=1; i <= nParams && sp > 0; ++i )
+ {
+ FormulaToken* p = pStack[ --sp ];
+ p->IncRef();
+ // store in reverse order such that a push may simply iterate
+ (*pParams)[ nParams - i ] = p;
+ }
+ pJumpMat->SetJumpParameters( pParams);
+ xNew = new ScJumpMatrixToken( pJumpMat );
+ GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur,
+ xNew));
+ }
+ PushTempToken( xNew);
+ // set continuation point of path for main code line
+ aCode.Jump( nNext, nNext);
+ return true;
+ }
+ return false;
+}
+
+
+ScMatrixRef ScInterpreter::PopMatrix()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopMatrix" );
+ if( sp )
+ {
+ --sp;
+ FormulaToken* p = pStack[ sp ];
+ switch (p->GetType())
+ {
+ case svError:
+ nGlobalError = p->GetError();
+ break;
+ case svMatrix:
+ {
+ ScMatrix* pMat = static_cast<ScToken*>(p)->GetMatrix();
+ if ( pMat )
+ pMat->SetErrorInterpreter( this);
+ else
+ SetError( errUnknownVariable);
+ return pMat;
+ }
+ default:
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+ return NULL;
+}
+
+
+void ScInterpreter::PushDouble(double nVal)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushDouble" );
+ TreatDoubleError( nVal );
+ if (!IfErrorPushError())
+ PushTempTokenWithoutError( new FormulaDoubleToken( nVal ) );
+}
+
+
+void ScInterpreter::PushInt(int nVal)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushInt" );
+ if (!IfErrorPushError())
+ PushTempTokenWithoutError( new FormulaDoubleToken( nVal ) );
+}
+
+
+void ScInterpreter::PushStringBuffer( const sal_Unicode* pString )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushStringBuffer" );
+ if ( pString )
+ PushString( String( pString ) );
+ else
+ PushString( EMPTY_STRING );
+}
+
+
+void ScInterpreter::PushString( const String& rString )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushString" );
+ if (!IfErrorPushError())
+ PushTempTokenWithoutError( new FormulaStringToken( rString ) );
+}
+
+
+void ScInterpreter::PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushSingleRef" );
+ if (!IfErrorPushError())
+ {
+ ScSingleRefData aRef;
+ aRef.InitFlags();
+ aRef.nCol = nCol;
+ aRef.nRow = nRow;
+ aRef.nTab = nTab;
+ PushTempTokenWithoutError( new ScSingleRefToken( aRef ) );
+ }
+}
+
+
+void ScInterpreter::PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushDoubleRef" );
+ if (!IfErrorPushError())
+ {
+ ScComplexRefData aRef;
+ aRef.InitFlags();
+ aRef.Ref1.nCol = nCol1;
+ aRef.Ref1.nRow = nRow1;
+ aRef.Ref1.nTab = nTab1;
+ aRef.Ref2.nCol = nCol2;
+ aRef.Ref2.nRow = nRow2;
+ aRef.Ref2.nTab = nTab2;
+ PushTempTokenWithoutError( new ScDoubleRefToken( aRef ) );
+ }
+}
+
+
+void ScInterpreter::PushMatrix(ScMatrix* pMat)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushMatrix" );
+ pMat->SetErrorInterpreter( NULL);
+ // No if (!IfErrorPushError()) because ScMatrix stores errors itself,
+ // but with notifying ScInterpreter via nGlobalError, substituting it would
+ // mean to inherit the error on all array elements in all following
+ // operations.
+ nGlobalError = 0;
+ PushTempTokenWithoutError( new ScMatrixToken( pMat ) );
+}
+
+
+void ScInterpreter::PushError( USHORT nError )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushError" );
+ SetError( nError ); // only sets error if not already set
+ PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError));
+}
+
+void ScInterpreter::PushParameterExpected()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushParameterExpected" );
+ PushError( errParameterExpected);
+}
+
+
+void ScInterpreter::PushIllegalParameter()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushIllegalParameter" );
+ PushError( errIllegalParameter);
+}
+
+
+void ScInterpreter::PushIllegalArgument()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushIllegalArgument" );
+ PushError( errIllegalArgument);
+}
+
+
+void ScInterpreter::PushNA()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushNA" );
+ PushError( NOTAVAILABLE);
+}
+
+
+void ScInterpreter::PushNoValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushNoValue" );
+ PushError( errNoValue);
+}
+
+
+BOOL ScInterpreter::IsMissing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsMissing" );
+ return sp && pStack[sp - 1]->GetType() == svMissing;
+}
+
+
+StackVar ScInterpreter::GetRawStackType()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetRawStackType" );
+ StackVar eRes;
+ if( sp )
+ {
+ eRes = pStack[sp - 1]->GetType();
+ }
+ else
+ {
+ SetError(errUnknownStackVariable);
+ eRes = svUnknown;
+ }
+ return eRes;
+}
+
+
+StackVar ScInterpreter::GetStackType()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStackType" );
+ StackVar eRes;
+ if( sp )
+ {
+ eRes = pStack[sp - 1]->GetType();
+ if( eRes == svMissing || eRes == svEmptyCell )
+ eRes = svDouble; // default!
+ }
+ else
+ {
+ SetError(errUnknownStackVariable);
+ eRes = svUnknown;
+ }
+ return eRes;
+}
+
+
+StackVar ScInterpreter::GetStackType( BYTE nParam )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStackType" );
+ StackVar eRes;
+ if( sp > nParam-1 )
+ {
+ eRes = pStack[sp - nParam]->GetType();
+ if( eRes == svMissing || eRes == svEmptyCell )
+ eRes = svDouble; // default!
+ }
+ else
+ eRes = svUnknown;
+ return eRes;
+}
+
+
+BOOL ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToPosSingleRef" );
+ // Check for a singleton first - no implicit intersection for them.
+ if( rRange.aStart == rRange.aEnd )
+ {
+ rAdr = rRange.aStart;
+ return TRUE;
+ }
+
+ BOOL bOk = FALSE;
+
+ if ( pJumpMatrix )
+ {
+ bOk = rRange.aStart.Tab() == rRange.aEnd.Tab();
+ if ( !bOk )
+ SetError( errIllegalArgument);
+ else
+ {
+ SCSIZE nC, nR;
+ pJumpMatrix->GetPos( nC, nR);
+ rAdr.SetCol( sal::static_int_cast<SCCOL>( rRange.aStart.Col() + nC ) );
+ rAdr.SetRow( sal::static_int_cast<SCROW>( rRange.aStart.Row() + nR ) );
+ rAdr.SetTab( rRange.aStart.Tab());
+ bOk = rRange.aStart.Col() <= rAdr.Col() && rAdr.Col() <=
+ rRange.aEnd.Col() && rRange.aStart.Row() <= rAdr.Row() &&
+ rAdr.Row() <= rRange.aEnd.Row();
+ if ( !bOk )
+ SetError( errNoValue);
+ }
+ return bOk;
+ }
+
+ SCCOL nMyCol = aPos.Col();
+ SCROW nMyRow = aPos.Row();
+ SCTAB nMyTab = aPos.Tab();
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+ SCTAB nTab;
+ nTab = rRange.aStart.Tab();
+ if ( rRange.aStart.Col() <= nMyCol && nMyCol <= rRange.aEnd.Col() )
+ {
+ nRow = rRange.aStart.Row();
+ if ( nRow == rRange.aEnd.Row() )
+ {
+ bOk = TRUE;
+ nCol = nMyCol;
+ }
+ else if ( nTab != nMyTab && nTab == rRange.aEnd.Tab()
+ && rRange.aStart.Row() <= nMyRow && nMyRow <= rRange.aEnd.Row() )
+ {
+ bOk = TRUE;
+ nCol = nMyCol;
+ nRow = nMyRow;
+ }
+ }
+ else if ( rRange.aStart.Row() <= nMyRow && nMyRow <= rRange.aEnd.Row() )
+ {
+ nCol = rRange.aStart.Col();
+ if ( nCol == rRange.aEnd.Col() )
+ {
+ bOk = TRUE;
+ nRow = nMyRow;
+ }
+ else if ( nTab != nMyTab && nTab == rRange.aEnd.Tab()
+ && rRange.aStart.Col() <= nMyCol && nMyCol <= rRange.aEnd.Col() )
+ {
+ bOk = TRUE;
+ nCol = nMyCol;
+ nRow = nMyRow;
+ }
+ }
+ if ( bOk )
+ {
+ if ( nTab == rRange.aEnd.Tab() )
+ ; // all done
+ else if ( nTab <= nMyTab && nMyTab <= rRange.aEnd.Tab() )
+ nTab = nMyTab;
+ else
+ bOk = FALSE;
+ if ( bOk )
+ rAdr.Set( nCol, nRow, nTab );
+ }
+ if ( !bOk )
+ SetError( errNoValue );
+ return bOk;
+}
+
+
+double ScInterpreter::GetDouble()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDouble" );
+ double nVal;
+ switch( GetRawStackType() )
+ {
+ case svDouble:
+ nVal = PopDouble();
+ break;
+ case svString:
+ nVal = ConvertStringToValue( PopString());
+ break;
+ case svSingleRef:
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ nVal = GetCellValue( aAdr, pCell );
+ }
+ break;
+ case svDoubleRef:
+ { // generate position dependent SingleRef
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ ScAddress aAdr;
+ if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ nVal = GetCellValue( aAdr, pCell );
+ }
+ else
+ nVal = 0.0;
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ nVal = 0.0;
+ else if ( !pJumpMatrix )
+ nVal = pMat->GetDouble( 0 );
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ nVal = pMat->GetDouble( nC, nR);
+ else
+ {
+ SetError( errNoValue);
+ nVal = 0.0;
+ }
+ }
+ }
+ break;
+ case svError:
+ PopError();
+ nVal = 0.0;
+ break;
+ case svEmptyCell:
+ case svMissing:
+ Pop();
+ nVal = 0.0;
+ break;
+ default:
+ PopError();
+ SetError( errIllegalParameter);
+ nVal = 0.0;
+ }
+ if ( nFuncFmtType == nCurFmtType )
+ nFuncFmtIndex = nCurFmtIndex;
+ return nVal;
+}
+
+
+double ScInterpreter::GetDoubleWithDefault(double nDefault)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDoubleWithDefault" );
+ bool bMissing = IsMissing();
+ double nResultVal = GetDouble();
+ if ( bMissing )
+ nResultVal = nDefault;
+ return nResultVal;
+}
+
+
+const String& ScInterpreter::GetString()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetString" );
+ switch (GetRawStackType())
+ {
+ case svError:
+ PopError();
+ return EMPTY_STRING;
+ //break;
+ case svMissing:
+ case svEmptyCell:
+ Pop();
+ return EMPTY_STRING;
+ //break;
+ case svDouble:
+ {
+ double fVal = PopDouble();
+ ULONG nIndex = pFormatter->GetStandardFormat(
+ NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ pFormatter->GetInputLineString(fVal, nIndex, aTempStr);
+ return aTempStr;
+ }
+ //break;
+ case svString:
+ return PopString();
+ //break;
+ case svSingleRef:
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if (nGlobalError == 0)
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ GetCellString( aTempStr, pCell );
+ return aTempStr;
+ }
+ else
+ return EMPTY_STRING;
+ }
+ //break;
+ case svDoubleRef:
+ { // generate position dependent SingleRef
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ ScAddress aAdr;
+ if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ GetCellString( aTempStr, pCell );
+ return aTempStr;
+ }
+ else
+ return EMPTY_STRING;
+ }
+ //break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if ( !pMat )
+ ; // nothing
+ else if ( !pJumpMatrix )
+ {
+ aTempStr = pMat->GetString( *pFormatter, 0, 0);
+ return aTempStr;
+ }
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ {
+ aTempStr = pMat->GetString( *pFormatter, nC, nR);
+ return aTempStr;
+ }
+ else
+ SetError( errNoValue);
+ }
+ }
+ break;
+ default:
+ PopError();
+ SetError( errIllegalArgument);
+ }
+ return EMPTY_STRING;
+}
+
+
+
+ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble,
+ String& rString )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDoubleOrStringFromMatrix" );
+ ScMatValType nMatValType = SC_MATVAL_EMPTY;
+ switch ( GetStackType() )
+ {
+ case svMatrix:
+ {
+ const ScMatrixValue* pMatVal = 0;
+ ScMatrixRef pMat = PopMatrix();
+ if (!pMat)
+ ; // nothing
+ else if (!pJumpMatrix)
+ pMatVal = pMat->Get( 0, 0, nMatValType);
+ else
+ {
+ SCSIZE nCols, nRows, nC, nR;
+ pMat->GetDimensions( nCols, nRows);
+ pJumpMatrix->GetPos( nC, nR);
+ if ( nC < nCols && nR < nRows )
+ pMatVal = pMat->Get( nC, nR, nMatValType);
+ else
+ SetError( errNoValue);
+ }
+ if (!pMatVal)
+ {
+ rDouble = 0.0;
+ rString.Erase();
+ }
+ else if (nMatValType == SC_MATVAL_VALUE)
+ rDouble = pMatVal->fVal;
+ else if (nMatValType == SC_MATVAL_BOOLEAN)
+ {
+ rDouble = pMatVal->fVal;
+ nMatValType = SC_MATVAL_VALUE;
+ }
+ else
+ rString = pMatVal->GetString();
+ }
+ break;
+ default:
+ PopError();
+ rDouble = 0.0;
+ rString.Erase();
+ SetError( errIllegalParameter);
+ }
+ return nMatValType;
+}
+
+
+void ScInterpreter::ScDBGet()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBGet" );
+ BOOL bMissingField = FALSE;
+ auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
+ if (!pQueryParam.get())
+ {
+ // Failed to create query param.
+ PushIllegalParameter();
+ return;
+ }
+
+ pQueryParam->mbSkipString = false;
+ ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator::Value aValue;
+ if (!aValIter.GetFirst(aValue) || aValue.mnError)
+ {
+ // No match found.
+ PushNoValue();
+ return;
+ }
+
+ ScDBQueryDataIterator::Value aValNext;
+ if (aValIter.GetNext(aValNext) && !aValNext.mnError)
+ {
+ // There should be only one unique match.
+ PushIllegalArgument();
+ return;
+ }
+
+ if (aValue.mbIsNumber)
+ PushDouble(aValue.mfValue);
+ else
+ PushString(aValue.maString);
+}
+
+
+void ScInterpreter::ScExternal()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExternal" );
+ USHORT nIndex;
+ BYTE nParamCount = GetByte();
+ String aUnoName;
+ String aFuncName( ScGlobal::pCharClass->upper( pCur->GetExternal() ) );
+ if (ScGlobal::GetFuncCollection()->SearchFunc(aFuncName, nIndex))
+ {
+ FuncData* pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex);
+ if (nParamCount <= MAXFUNCPARAM && nParamCount == pFuncData->GetParamCount() - 1)
+ {
+ ParamType eParamType[MAXFUNCPARAM];
+ void* ppParam[MAXFUNCPARAM];
+ double nVal[MAXFUNCPARAM];
+ sal_Char* pStr[MAXFUNCPARAM];
+ BYTE* pCellArr[MAXFUNCPARAM];
+ short i;
+
+ for (i = 0; i < MAXFUNCPARAM; i++)
+ {
+ eParamType[i] = pFuncData->GetParamType(i);
+ ppParam[i] = NULL;
+ nVal[i] = 0.0;
+ pStr[i] = NULL;
+ pCellArr[i] = NULL;
+ }
+
+ for (i = nParamCount; (i > 0) && (nGlobalError == 0); i--)
+ {
+ switch (eParamType[i])
+ {
+ case PTR_DOUBLE :
+ {
+ nVal[i-1] = GetDouble();
+ ppParam[i] = &nVal[i-1];
+ }
+ break;
+ case PTR_STRING :
+ {
+ ByteString aStr( GetString(), osl_getThreadTextEncoding() );
+ if ( aStr.Len() >= ADDIN_MAXSTRLEN )
+ SetError( errStringOverflow );
+ else
+ {
+ pStr[i-1] = new sal_Char[ADDIN_MAXSTRLEN];
+ strncpy( pStr[i-1], aStr.GetBuffer(), ADDIN_MAXSTRLEN );
+ pStr[i-1][ADDIN_MAXSTRLEN-1] = 0;
+ ppParam[i] = pStr[i-1];
+ }
+ }
+ break;
+ case PTR_DOUBLE_ARR :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ pCellArr[i-1] = new BYTE[MAXARRSIZE];
+ if (!CreateDoubleArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
+ SetError(errCodeOverflow);
+ else
+ ppParam[i] = pCellArr[i-1];
+ }
+ break;
+ case PTR_STRING_ARR :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ pCellArr[i-1] = new BYTE[MAXARRSIZE];
+ if (!CreateStringArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
+ SetError(errCodeOverflow);
+ else
+ ppParam[i] = pCellArr[i-1];
+ }
+ break;
+ case PTR_CELL_ARR :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ pCellArr[i-1] = new BYTE[MAXARRSIZE];
+ if (!CreateCellArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
+ SetError(errCodeOverflow);
+ else
+ ppParam[i] = pCellArr[i-1];
+ }
+ break;
+ default :
+ SetError(errIllegalParameter);
+ break;
+ }
+ }
+ while ( i-- )
+ Pop(); // im Fehlerfall (sonst ist i==0) Parameter wegpoppen
+
+ if (nGlobalError == 0)
+ {
+ if ( pFuncData->GetAsyncType() == NONE )
+ {
+ switch ( eParamType[0] )
+ {
+ case PTR_DOUBLE :
+ {
+ double nErg = 0.0;
+ ppParam[0] = &nErg;
+ pFuncData->Call(ppParam);
+ PushDouble(nErg);
+ }
+ break;
+ case PTR_STRING :
+ {
+ sal_Char* pcErg = new sal_Char[ADDIN_MAXSTRLEN];
+ ppParam[0] = pcErg;
+ pFuncData->Call(ppParam);
+ String aUni( pcErg, osl_getThreadTextEncoding() );
+ PushString( aUni );
+ delete[] pcErg;
+ }
+ break;
+ default:
+ PushError( errUnknownState );
+ }
+ }
+ else
+ {
+ // nach dem Laden Asyncs wieder anwerfen
+ if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() )
+ pMyFormulaCell->GetCode()->SetRecalcModeOnLoad();
+ // garantiert identischer Handle bei identischem Aufruf?!?
+ // sonst schei*e ...
+ double nErg = 0.0;
+ ppParam[0] = &nErg;
+ pFuncData->Call(ppParam);
+ ULONG nHandle = ULONG( nErg );
+ if ( nHandle >= 65536 )
+ {
+ ScAddInAsync* pAs = ScAddInAsync::Get( nHandle );
+ if ( !pAs )
+ {
+ pAs = new ScAddInAsync( nHandle, nIndex, pDok );
+ pMyFormulaCell->StartListening( *pAs );
+ }
+ else
+ {
+ // falls per cut/copy/paste
+ pMyFormulaCell->StartListening( *pAs );
+ // in anderes Dokument?
+ if ( !pAs->HasDocument( pDok ) )
+ pAs->AddDocument( pDok );
+ }
+ if ( pAs->IsValid() )
+ {
+ switch ( pAs->GetType() )
+ {
+ case PTR_DOUBLE :
+ PushDouble( pAs->GetValue() );
+ break;
+ case PTR_STRING :
+ PushString( pAs->GetString() );
+ break;
+ default:
+ PushError( errUnknownState );
+ }
+ }
+ else
+ PushNA();
+ }
+ else
+ PushNoValue();
+ }
+ }
+
+ for (i = 0; i < MAXFUNCPARAM; i++)
+ {
+ delete[] pStr[i];
+ delete[] pCellArr[i];
+ }
+ }
+ else
+ {
+ while( nParamCount-- > 0)
+ Pop();
+ PushIllegalParameter();
+ }
+ }
+ else if ( ( aUnoName = ScGlobal::GetAddInCollection()->FindFunction(aFuncName, FALSE) ).Len() )
+ {
+ // bLocalFirst=FALSE in FindFunction, cFunc should be the stored internal name
+
+ ScUnoAddInCall aCall( *ScGlobal::GetAddInCollection(), aUnoName, nParamCount );
+
+ if ( !aCall.ValidParamCount() )
+ SetError( errIllegalParameter );
+
+ if ( aCall.NeedsCaller() && !GetError() )
+ {
+ SfxObjectShell* pShell = pDok->GetDocumentShell();
+ if (pShell)
+ aCall.SetCallerFromObjectShell( pShell );
+ else
+ {
+ // use temporary model object (without document) to supply options
+ aCall.SetCaller( static_cast<beans::XPropertySet*>(
+ new ScDocOptionsObj( pDok->GetDocOptions() ) ) );
+ }
+ }
+
+ short nPar = nParamCount;
+ while ( nPar > 0 && !GetError() )
+ {
+ --nPar; // 0 .. (nParamCount-1)
+
+ ScAddInArgumentType eType = aCall.GetArgType( nPar );
+ BYTE nStackType = sal::static_int_cast<BYTE>( GetStackType() );
+
+ uno::Any aParam;
+ switch (eType)
+ {
+ case SC_ADDINARG_INTEGER:
+ {
+ double fVal = GetDouble();
+ double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) :
+ ::rtl::math::approxCeil( fVal );
+ if ( fInt >= LONG_MIN && fInt <= LONG_MAX )
+ aParam <<= (INT32)fInt;
+ else
+ SetError(errIllegalArgument);
+ }
+ break;
+
+ case SC_ADDINARG_DOUBLE:
+ aParam <<= (double) GetDouble();
+ break;
+
+ case SC_ADDINARG_STRING:
+ aParam <<= rtl::OUString( GetString() );
+ break;
+
+ case SC_ADDINARG_INTEGER_ARRAY:
+ switch( nStackType )
+ {
+ case svDouble:
+ case svString:
+ case svSingleRef:
+ {
+ double fVal = GetDouble();
+ double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) :
+ ::rtl::math::approxCeil( fVal );
+ if ( fInt >= LONG_MIN && fInt <= LONG_MAX )
+ {
+ INT32 nIntVal = (long)fInt;
+ uno::Sequence<INT32> aInner( &nIntVal, 1 );
+ uno::Sequence< uno::Sequence<INT32> > aOuter( &aInner, 1 );
+ aParam <<= aOuter;
+ }
+ else
+ SetError(errIllegalArgument);
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if (!ScRangeToSequence::FillLongArray( aParam, pDok, aRange ))
+ SetError(errIllegalParameter);
+ }
+ break;
+ case svMatrix:
+ if (!ScRangeToSequence::FillLongArray( aParam, PopMatrix() ))
+ SetError(errIllegalParameter);
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ break;
+
+ case SC_ADDINARG_DOUBLE_ARRAY:
+ switch( nStackType )
+ {
+ case svDouble:
+ case svString:
+ case svSingleRef:
+ {
+ double fVal = GetDouble();
+ uno::Sequence<double> aInner( &fVal, 1 );
+ uno::Sequence< uno::Sequence<double> > aOuter( &aInner, 1 );
+ aParam <<= aOuter;
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if (!ScRangeToSequence::FillDoubleArray( aParam, pDok, aRange ))
+ SetError(errIllegalParameter);
+ }
+ break;
+ case svMatrix:
+ if (!ScRangeToSequence::FillDoubleArray( aParam, PopMatrix() ))
+ SetError(errIllegalParameter);
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ break;
+
+ case SC_ADDINARG_STRING_ARRAY:
+ switch( nStackType )
+ {
+ case svDouble:
+ case svString:
+ case svSingleRef:
+ {
+ rtl::OUString aString = rtl::OUString( GetString() );
+ uno::Sequence<rtl::OUString> aInner( &aString, 1 );
+ uno::Sequence< uno::Sequence<rtl::OUString> > aOuter( &aInner, 1 );
+ aParam <<= aOuter;
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if (!ScRangeToSequence::FillStringArray( aParam, pDok, aRange ))
+ SetError(errIllegalParameter);
+ }
+ break;
+ case svMatrix:
+ if (!ScRangeToSequence::FillStringArray( aParam, PopMatrix(), pFormatter ))
+ SetError(errIllegalParameter);
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ break;
+
+ case SC_ADDINARG_MIXED_ARRAY:
+ switch( nStackType )
+ {
+ case svDouble:
+ case svString:
+ case svSingleRef:
+ {
+ uno::Any aElem;
+ if ( nStackType == svDouble )
+ aElem <<= (double) GetDouble();
+ else if ( nStackType == svString )
+ aElem <<= rtl::OUString( GetString() );
+ else
+ {
+ ScAddress aAdr;
+ if ( PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( pCell && pCell->HasStringData() )
+ {
+ String aStr;
+ GetCellString( aStr, pCell );
+ aElem <<= rtl::OUString( aStr );
+ }
+ else
+ aElem <<= (double) GetCellValue( aAdr, pCell );
+ }
+ }
+ uno::Sequence<uno::Any> aInner( &aElem, 1 );
+ uno::Sequence< uno::Sequence<uno::Any> > aOuter( &aInner, 1 );
+ aParam <<= aOuter;
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if (!ScRangeToSequence::FillMixedArray( aParam, pDok, aRange ))
+ SetError(errIllegalParameter);
+ }
+ break;
+ case svMatrix:
+ if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() ))
+ SetError(errIllegalParameter);
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ break;
+
+ case SC_ADDINARG_VALUE_OR_ARRAY:
+ if ( IsMissing() )
+ nStackType = svMissing;
+ switch( nStackType )
+ {
+ case svDouble:
+ aParam <<= (double) GetDouble();
+ break;
+ case svString:
+ aParam <<= rtl::OUString( GetString() );
+ break;
+ case svSingleRef:
+ {
+ ScAddress aAdr;
+ if ( PopDoubleRefOrSingleRef( aAdr ) )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( pCell && pCell->HasStringData() )
+ {
+ String aStr;
+ GetCellString( aStr, pCell );
+ aParam <<= rtl::OUString( aStr );
+ }
+ else
+ aParam <<= (double) GetCellValue( aAdr, pCell );
+ }
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ if (!ScRangeToSequence::FillMixedArray( aParam, pDok, aRange ))
+ SetError(errIllegalParameter);
+ }
+ break;
+ case svMatrix:
+ if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() ))
+ SetError(errIllegalParameter);
+ break;
+ case svMissing:
+ Pop();
+ aParam.clear();
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ break;
+
+ case SC_ADDINARG_CELLRANGE:
+ switch( nStackType )
+ {
+ case svSingleRef:
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScRange aRange( aAdr );
+ uno::Reference<table::XCellRange> xObj =
+ ScCellRangeObj::CreateRangeFromDoc( pDok, aRange );
+ if (xObj.is())
+ aParam <<= xObj;
+ else
+ SetError(errIllegalParameter);
+ }
+ break;
+ case svDoubleRef:
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ uno::Reference<table::XCellRange> xObj =
+ ScCellRangeObj::CreateRangeFromDoc( pDok, aRange );
+ if (xObj.is())
+ aParam <<= xObj;
+ else
+ SetError(errIllegalParameter);
+ }
+ break;
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ break;
+
+ default:
+ PopError();
+ SetError(errIllegalParameter);
+ }
+ aCall.SetParam( nPar, aParam );
+ }
+
+ while (nPar-- > 0)
+ Pop(); // in case of error, remove remaining args
+
+ if ( !GetError() )
+ {
+ aCall.ExecuteCall();
+
+ if ( aCall.HasVarRes() ) // handle async functions
+ {
+ if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() )
+ pMyFormulaCell->GetCode()->SetRecalcModeOnLoad();
+
+ uno::Reference<sheet::XVolatileResult> xRes = aCall.GetVarRes();
+ ScAddInListener* pLis = ScAddInListener::Get( xRes );
+ if ( !pLis )
+ {
+ pLis = ScAddInListener::CreateListener( xRes, pDok );
+ pMyFormulaCell->StartListening( *pLis );
+ }
+ else
+ {
+ pMyFormulaCell->StartListening( *pLis );
+ if ( !pLis->HasDocument( pDok ) )
+ pLis->AddDocument( pDok );
+ }
+
+ aCall.SetResult( pLis->GetResult() ); // use result from async
+ }
+
+ if ( aCall.GetErrCode() )
+ PushError( aCall.GetErrCode() );
+ else if ( aCall.HasMatrix() )
+ {
+ ScMatrixRef xMat = aCall.GetMatrix();
+ PushMatrix( xMat );
+ }
+ else if ( aCall.HasString() )
+ PushString( aCall.GetString() );
+ else
+ PushDouble( aCall.GetValue() );
+ }
+ else // error...
+ PushError( GetError());
+ }
+ else
+ {
+ while( nParamCount-- > 0)
+ Pop();
+ PushError( errNoAddin );
+ }
+}
+
+
+void ScInterpreter::ScMissing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMissing" );
+ PushTempToken( new FormulaMissingToken );
+}
+
+
+void ScInterpreter::ScMacro()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMacro" );
+ SbxBase::ResetError();
+
+ BYTE nParamCount = GetByte();
+ String aMacro( pCur->GetExternal() );
+
+ SfxObjectShell* pDocSh = pDok->GetDocumentShell();
+ if ( !pDocSh || !pDok->CheckMacroWarn() )
+ {
+ PushNoValue(); // ohne DocShell kein CallBasic
+ return;
+ }
+
+ // keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic
+
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->EnterBasicCall(); // Dok-Basic anlegen etc.
+
+ // Wenn das Dok waehrend eines Basic-Calls geladen wurde,
+ // ist das Sbx-Objekt evtl. nicht angelegt (?)
+// pDocSh->GetSbxObject();
+
+ // Funktion ueber den einfachen Namen suchen,
+ // dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen
+
+ StarBASIC* pRoot = pDocSh->GetBasic();
+ SbxVariable* pVar = pRoot->Find( aMacro, SbxCLASS_METHOD );
+ if( !pVar || pVar->GetType() == SbxVOID || !pVar->ISA(SbMethod) )
+ {
+ PushError( errNoMacro );
+ pSfxApp->LeaveBasicCall();
+ return;
+ }
+
+ SbMethod* pMethod = (SbMethod*)pVar;
+ SbModule* pModule = pMethod->GetModule();
+ SbxObject* pObject = pModule->GetParent();
+ DBG_ASSERT(pObject->IsA(TYPE(StarBASIC)), "Kein Basic gefunden!");
+ String aMacroStr = pObject->GetName();
+ aMacroStr += '.';
+ aMacroStr += pModule->GetName();
+ aMacroStr += '.';
+ aMacroStr += pMethod->GetName();
+ String aBasicStr;
+ if (pObject->GetParent())
+ aBasicStr = pObject->GetParent()->GetName(); // Dokumentenbasic
+ else
+ aBasicStr = SFX_APP()->GetName(); // Applikationsbasic
+
+ // Parameter-Array zusammenbauen
+
+ SbxArrayRef refPar = new SbxArray;
+ BOOL bOk = TRUE;
+ for( short i = nParamCount; i && bOk ; i-- )
+ {
+ SbxVariable* pPar = refPar->Get( (USHORT) i );
+ BYTE nStackType = sal::static_int_cast<BYTE>( GetStackType() );
+ switch( nStackType )
+ {
+ case svDouble:
+ pPar->PutDouble( GetDouble() );
+ break;
+ case svString:
+ pPar->PutString( GetString() );
+ break;
+ case svSingleRef:
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ bOk = SetSbxVariable( pPar, aAdr );
+ }
+ break;
+ case svDoubleRef:
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if( nTab1 != nTab2 )
+ {
+ SetError( errIllegalParameter );
+ bOk = FALSE;
+ }
+ else
+ {
+ SbxDimArrayRef refArray = new SbxDimArray;
+ refArray->AddDim32( 1, nRow2 - nRow1 + 1 );
+ refArray->AddDim32( 1, nCol2 - nCol1 + 1 );
+ ScAddress aAdr( nCol1, nRow1, nTab1 );
+ for( SCROW nRow = nRow1; bOk && nRow <= nRow2; nRow++ )
+ {
+ aAdr.SetRow( nRow );
+ INT32 nIdx[ 2 ];
+ nIdx[ 0 ] = nRow-nRow1+1;
+ for( SCCOL nCol = nCol1; bOk && nCol <= nCol2; nCol++ )
+ {
+ aAdr.SetCol( nCol );
+ nIdx[ 1 ] = nCol-nCol1+1;
+ SbxVariable* p = refArray->Get32( nIdx );
+ bOk = SetSbxVariable( p, aAdr );
+ }
+ }
+ pPar->PutObject( refArray );
+ }
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ SCSIZE nC, nR;
+ if (pMat)
+ {
+ pMat->GetDimensions(nC, nR);
+ SbxDimArrayRef refArray = new SbxDimArray;
+ refArray->AddDim32( 1, static_cast<INT32>(nR) );
+ refArray->AddDim32( 1, static_cast<INT32>(nC) );
+ for( SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++ )
+ {
+ INT32 nIdx[ 2 ];
+ nIdx[ 0 ] = static_cast<INT32>(nMatRow+1);
+ for( SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++ )
+ {
+ nIdx[ 1 ] = static_cast<INT32>(nMatCol+1);
+ SbxVariable* p = refArray->Get32( nIdx );
+ if (pMat->IsString(nMatCol, nMatRow))
+ p->PutString( pMat->GetString(nMatCol, nMatRow) );
+ else
+ p->PutDouble( pMat->GetDouble(nMatCol, nMatRow));
+ }
+ }
+ pPar->PutObject( refArray );
+ }
+ else
+ SetError( errIllegalParameter );
+ }
+ break;
+ default:
+ SetError( errIllegalParameter );
+ bOk = FALSE;
+ }
+ }
+ if( bOk )
+ {
+ pDok->LockTable( aPos.Tab() );
+ SbxVariableRef refRes = new SbxVariable;
+ pDok->IncMacroInterpretLevel();
+ ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, NULL, refPar, refRes );
+ pDok->DecMacroInterpretLevel();
+ pDok->UnlockTable( aPos.Tab() );
+
+ SbxDataType eResType = refRes->GetType();
+ if( pVar->GetError() )
+ SetError( errNoValue);
+ if ( eRet != ERRCODE_NONE )
+ PushNoValue();
+ else if( eResType >= SbxINTEGER && eResType <= SbxDOUBLE )
+ PushDouble( refRes->GetDouble() );
+ else if ( eResType & SbxARRAY )
+ {
+ SbxBase* pElemObj = refRes->GetObject();
+ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
+ short nDim = pDimArray->GetDims();
+ if ( 1 <= nDim && nDim <= 2 )
+ {
+ INT32 nCs, nCe, nRs, nRe;
+ SCSIZE nC, nR;
+ SCCOL nColIdx;
+ SCROW nRowIdx;
+ if ( nDim == 1 )
+ { // array( cols ) eine Zeile, mehrere Spalten
+ pDimArray->GetDim32( 1, nCs, nCe );
+ nC = static_cast<SCSIZE>(nCe - nCs + 1);
+ nRs = nRe = 0;
+ nR = 1;
+ nColIdx = 0;
+ nRowIdx = 1;
+ }
+ else
+ { // array( rows, cols )
+ pDimArray->GetDim32( 1, nRs, nRe );
+ nR = static_cast<SCSIZE>(nRe - nRs + 1);
+ pDimArray->GetDim32( 2, nCs, nCe );
+ nC = static_cast<SCSIZE>(nCe - nCs + 1);
+ nColIdx = 1;
+ nRowIdx = 0;
+ }
+ ScMatrixRef pMat = GetNewMat( nC, nR);
+ if ( pMat )
+ {
+ SbxVariable* pV;
+ SbxDataType eType;
+ for ( SCSIZE j=0; j < nR; j++ )
+ {
+ INT32 nIdx[ 2 ];
+ // bei eindimensionalem array( cols ) wird nIdx[1]
+ // von SbxDimArray::Get ignoriert
+ nIdx[ nRowIdx ] = nRs + static_cast<INT32>(j);
+ for ( SCSIZE i=0; i < nC; i++ )
+ {
+ nIdx[ nColIdx ] = nCs + static_cast<INT32>(i);
+ pV = pDimArray->Get32( nIdx );
+ eType = pV->GetType();
+ if ( eType >= SbxINTEGER && eType <= SbxDOUBLE )
+ pMat->PutDouble( pV->GetDouble(), i, j );
+ else
+ pMat->PutString( pV->GetString(), i, j );
+ }
+ }
+ PushMatrix( pMat );
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushNoValue();
+ }
+ else
+ PushString( refRes->GetString() );
+ }
+
+ pSfxApp->LeaveBasicCall();
+}
+
+
+BOOL ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::SetSbxVariable" );
+ BOOL bOk = TRUE;
+ ScBaseCell* pCell = pDok->GetCell( rPos );
+ if (pCell)
+ {
+ USHORT nErr;
+ double nVal;
+ switch( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE :
+ nVal = GetValueCellValue( rPos, (ScValueCell*)pCell );
+ pVar->PutDouble( nVal );
+ break;
+ case CELLTYPE_STRING :
+ {
+ String aVal;
+ ((ScStringCell*)pCell)->GetString( aVal );
+ pVar->PutString( aVal );
+ break;
+ }
+ case CELLTYPE_EDIT :
+ {
+ String aVal;
+ ((ScEditCell*) pCell)->GetString( aVal );
+ pVar->PutString( aVal );
+ break;
+ }
+ case CELLTYPE_FORMULA :
+ nErr = ((ScFormulaCell*)pCell)->GetErrCode();
+ if( !nErr )
+ {
+ if( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ nVal = ((ScFormulaCell*)pCell)->GetValue();
+ pVar->PutDouble( nVal );
+ }
+ else
+ {
+ String aVal;
+ ((ScFormulaCell*)pCell)->GetString( aVal );
+ pVar->PutString( aVal );
+ }
+ }
+ else
+ SetError( nErr ), bOk = FALSE;
+ break;
+ default :
+ pVar->PutDouble( 0.0 );
+ }
+ }
+ else
+ pVar->PutDouble( 0.0 );
+ return bOk;
+}
+
+
+void ScInterpreter::ScTableOp()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTableOp" );
+ BYTE nParamCount = GetByte();
+ if (nParamCount != 3 && nParamCount != 5)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ ScInterpreterTableOpParams* pTableOp = new ScInterpreterTableOpParams;
+ if (nParamCount == 5)
+ {
+ PopSingleRef( pTableOp->aNew2 );
+ PopSingleRef( pTableOp->aOld2 );
+ }
+ PopSingleRef( pTableOp->aNew1 );
+ PopSingleRef( pTableOp->aOld1 );
+ PopSingleRef( pTableOp->aFormulaPos );
+
+ pTableOp->bValid = TRUE;
+ pDok->aTableOpList.Insert( pTableOp );
+ pDok->IncInterpreterTableOpLevel();
+
+ BOOL bReuseLastParams = (pDok->aLastTableOpParams == *pTableOp);
+ if ( bReuseLastParams )
+ {
+ pTableOp->aNotifiedFormulaPos = pDok->aLastTableOpParams.aNotifiedFormulaPos;
+ pTableOp->bRefresh = TRUE;
+ for ( ::std::vector< ScAddress >::const_iterator iBroadcast(
+ pTableOp->aNotifiedFormulaPos.begin() );
+ iBroadcast != pTableOp->aNotifiedFormulaPos.end();
+ ++iBroadcast )
+ { // emulate broadcast and indirectly collect cell pointers
+ ScBaseCell* pCell = pDok->GetCell( *iBroadcast );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->SetTableOpDirty();
+ }
+ }
+ else
+ { // broadcast and indirectly collect cell pointers and positions
+ pDok->SetTableOpDirty( pTableOp->aOld1 );
+ if ( nParamCount == 5 )
+ pDok->SetTableOpDirty( pTableOp->aOld2 );
+ }
+ pTableOp->bCollectNotifications = FALSE;
+
+ ScBaseCell* pFCell = pDok->GetCell( pTableOp->aFormulaPos );
+ if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pFCell)->SetDirtyVar();
+ if ( HasCellValueData( pFCell ) )
+ PushDouble( GetCellValue( pTableOp->aFormulaPos, pFCell ));
+ else
+ {
+ String aCellString;
+ GetCellString( aCellString, pFCell );
+ PushString( aCellString );
+ }
+
+ pDok->aTableOpList.Remove( pTableOp );
+ // set dirty again once more to be able to recalculate original
+ for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast(
+ pTableOp->aNotifiedFormulaCells.begin() );
+ iBroadcast != pTableOp->aNotifiedFormulaCells.end();
+ ++iBroadcast )
+ {
+ (*iBroadcast)->SetTableOpDirty();
+ }
+
+ // save these params for next incarnation
+ if ( !bReuseLastParams )
+ pDok->aLastTableOpParams = *pTableOp;
+
+ if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ((ScFormulaCell*)pFCell)->SetDirtyVar();
+ ((ScFormulaCell*)pFCell)->GetErrCode(); // recalculate original
+ }
+
+ // Reset all dirty flags so next incarnation does really collect all cell
+ // pointers during notifications and not just non-dirty ones, which may
+ // happen if a formula cell is used by more than one TableOp block.
+ for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast2(
+ pTableOp->aNotifiedFormulaCells.begin() );
+ iBroadcast2 != pTableOp->aNotifiedFormulaCells.end();
+ ++iBroadcast2 )
+ {
+ (*iBroadcast2)->ResetTableOpDirtyVar();
+ }
+ delete pTableOp;
+
+ pDok->DecInterpreterTableOpLevel();
+}
+
+
+/*
+
+void ScInterpreter::ScErrCell()
+{
+RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScErrCell" );
+ double fErrNum = GetDouble();
+ PushError((USHORT) fErrNum);
+}
+*/
+
+void ScInterpreter::ScDBArea()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBArea" );
+ ScDBData* pDBData = pDok->GetDBCollection()->FindIndex( pCur->GetIndex());
+ if (pDBData)
+ {
+ ScComplexRefData aRefData;
+ aRefData.InitFlags();
+ pDBData->GetArea( (SCTAB&) aRefData.Ref1.nTab,
+ (SCCOL&) aRefData.Ref1.nCol,
+ (SCROW&) aRefData.Ref1.nRow,
+ (SCCOL&) aRefData.Ref2.nCol,
+ (SCROW&) aRefData.Ref2.nRow);
+ aRefData.Ref2.nTab = aRefData.Ref1.nTab;
+ aRefData.CalcRelFromAbs( aPos );
+ PushTempToken( new ScDoubleRefToken( aRefData ) );
+ }
+ else
+ PushError( errNoName);
+}
+
+
+void ScInterpreter::ScColRowNameAuto()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColRowNameAuto" );
+ ScComplexRefData aRefData( static_cast<const ScToken*>(pCur)->GetDoubleRef() );
+ aRefData.CalcAbsIfRel( aPos );
+ if ( aRefData.Valid() )
+ {
+ SCsCOL nStartCol;
+ SCsROW nStartRow;
+ SCsCOL nCol2;
+ SCsROW nRow2;
+ // evtl. Begrenzung durch definierte ColRowNameRanges merken
+ nCol2 = aRefData.Ref2.nCol;
+ nRow2 = aRefData.Ref2.nRow;
+ // DataArea der ersten Zelle
+ nStartCol = aRefData.Ref2.nCol = aRefData.Ref1.nCol;
+ nStartRow = aRefData.Ref2.nRow = aRefData.Ref1.nRow;
+ aRefData.Ref2.nTab = aRefData.Ref1.nTab;
+ pDok->GetDataArea( (SCTAB&) aRefData.Ref1.nTab,
+ (SCCOL&) aRefData.Ref1.nCol,
+ (SCROW&) aRefData.Ref1.nRow,
+ (SCCOL&) aRefData.Ref2.nCol,
+ (SCROW&) aRefData.Ref2.nRow,
+ TRUE, false );
+ // DataArea im Ursprung begrenzen
+ aRefData.Ref1.nCol = nStartCol;
+ aRefData.Ref1.nRow = nStartRow;
+
+ //! korrespondiert mit ScCompiler::GetToken
+ if ( aRefData.Ref1.IsColRel() )
+ { // ColName
+ aRefData.Ref2.nCol = nStartCol;
+ // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
+ if ( aRefData.Ref2.nRow > nRow2 )
+ aRefData.Ref2.nRow = nRow2;
+ SCROW nMyRow;
+ if ( aPos.Col() == nStartCol
+ && nStartRow <= (nMyRow = aPos.Row()) && nMyRow <= aRefData.Ref2.nRow )
+ { // Formel in gleicher Spalte und innerhalb des Range
+ if ( nMyRow == nStartRow )
+ { // direkt unter dem Namen den Rest nehmen
+ nStartRow++;
+ if ( nStartRow > MAXROW )
+ nStartRow = MAXROW;
+ aRefData.Ref1.nRow = nStartRow;
+ }
+ else
+ { // weiter unten vom Namen bis zur Formelzelle
+ aRefData.Ref2.nRow = nMyRow - 1;
+ }
+ }
+ }
+ else
+ { // RowName
+ aRefData.Ref2.nRow = nStartRow;
+ // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
+ if ( aRefData.Ref2.nCol > nCol2 )
+ aRefData.Ref2.nCol = nCol2;
+ SCCOL nMyCol;
+ if ( aPos.Row() == nStartRow
+ && nStartCol <= (nMyCol = aPos.Col()) && nMyCol <= aRefData.Ref2.nCol )
+ { // Formel in gleicher Zeile und innerhalb des Range
+ if ( nMyCol == nStartCol )
+ { // direkt neben dem Namen den Rest nehmen
+ nStartCol++;
+ if ( nStartCol > MAXCOL )
+ nStartCol = MAXCOL;
+ aRefData.Ref1.nCol = nStartCol;
+ }
+ else
+ { // weiter rechts vom Namen bis zur Formelzelle
+ aRefData.Ref2.nCol = nMyCol - 1;
+ }
+ }
+ }
+ aRefData.CalcRelFromAbs( aPos );
+ PushTempToken( new ScDoubleRefToken( aRefData ) );
+ }
+ else
+ PushError( errNoRef );
+}
+
+void ScInterpreter::ScExternalRef()
+{
+ ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
+ const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex());
+ if (!pFile)
+ PushError(errNoName);
+
+ switch (pCur->GetType())
+ {
+ case svExternalSingleRef:
+ {
+ ScSingleRefData aData(static_cast<const ScToken*>(pCur)->GetSingleRef());
+ if (aData.IsTabRel())
+ {
+ DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!");
+ break;
+ }
+
+ aData.CalcAbsIfRel(aPos);
+ ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
+ ScExternalRefCache::CellFormat aFmt;
+ ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
+ pCur->GetIndex(), pCur->GetString(), aAddr, &aPos, NULL, &aFmt);
+
+ if (!xNew)
+ break;
+
+ PushTempToken( *xNew); // push a clone
+
+ if (aFmt.mbIsSet)
+ {
+ nFuncFmtType = aFmt.mnType;
+ nFuncFmtIndex = aFmt.mnIndex;
+ }
+ return;
+ }
+ //break; // unreachable, prevent compiler warning
+ case svExternalDoubleRef:
+ {
+ ScComplexRefData aData(static_cast<const ScToken*>(pCur)->GetDoubleRef());
+ if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
+ {
+ DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!");
+ break;
+ }
+
+ aData.CalcAbsIfRel(aPos);
+ ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
+ aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
+ ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getDoubleRefTokens(
+ pCur->GetIndex(), pCur->GetString(), aRange, &aPos);
+
+ if (!xNew)
+ break;
+
+ ScToken* p = static_cast<ScToken*>(xNew->First());
+ if (p->GetType() != svMatrix)
+ break;
+
+ if (xNew->Next())
+ {
+ // Can't handle more than one matrix per parameter.
+ SetError( errIllegalArgument);
+ break;
+ }
+
+ PushMatrix(p->GetMatrix());
+ return;
+ }
+ //break; // unreachable, prevent compiler warning
+ default:
+ ;
+ }
+ PushError(errNoRef);
+}
+
+// --- internals ------------------------------------------------------------
+
+
+void ScInterpreter::ScTTT()
+{ // Temporaerer Test-Tanz, zum auspropieren von Funktionen etc.
+ BYTE nParamCount = GetByte();
+ // do something, nParamCount bei Pops runterzaehlen!
+
+ // Stack aufraeumen
+ while ( nParamCount-- > 0)
+ Pop();
+ PushError(errNoValue);
+}
+
+// -------------------------------------------------------------------------
+
+
+ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
+ const ScAddress& rPos, ScTokenArray& r ) :
+ aCode( r ),
+ aPos( rPos ),
+ rArr( r ),
+ pDok( pDoc ),
+ pTokenMatrixMap( NULL ),
+ pMyFormulaCell( pCell ),
+ pFormatter( pDoc->GetFormatTable() ),
+ mnStringNoValueError( errNoValue),
+ bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" );
+// pStack = new ScToken*[ MAXSTACK ];
+
+ BYTE cMatFlag = pMyFormulaCell->GetMatrixFlag();
+ bMatrixFormula = ( cMatFlag == MM_FORMULA || cMatFlag == MM_FAKE );
+ if (!bGlobalStackInUse)
+ {
+ bGlobalStackInUse = TRUE;
+ if (!pGlobalStack)
+ pGlobalStack = new ScTokenStack;
+ pStackObj = pGlobalStack;
+ }
+ else
+ {
+ pStackObj = new ScTokenStack;
+ }
+ pStack = pStackObj->pPointer;
+}
+
+ScInterpreter::~ScInterpreter()
+{
+// delete pStack;
+
+ if ( pStackObj == pGlobalStack )
+ bGlobalStackInUse = FALSE;
+ else
+ delete pStackObj;
+ if (pTokenMatrixMap)
+ delete pTokenMatrixMap;
+}
+
+
+void ScInterpreter::GlobalExit() // static
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GlobalExit" );
+ DBG_ASSERT(!bGlobalStackInUse, "wer benutzt noch den TokenStack?");
+ DELETEZ(pGlobalStack);
+}
+
+
+StackVar ScInterpreter::Interpret()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Interpret" );
+ short nRetTypeExpr = NUMBERFORMAT_UNDEFINED;
+ ULONG nRetIndexExpr = 0;
+ USHORT nErrorFunction = 0;
+ USHORT nErrorFunctionCount = 0;
+ USHORT nStackBase;
+
+ nGlobalError = 0;
+ nStackBase = sp = maxsp = 0;
+ nRetFmtType = NUMBERFORMAT_UNDEFINED;
+ nFuncFmtType = NUMBERFORMAT_UNDEFINED;
+ nFuncFmtIndex = nCurFmtIndex = nRetFmtIndex = 0;
+ xResult = NULL;
+ pJumpMatrix = NULL;
+ glSubTotal = FALSE;
+ ScTokenMatrixMap::const_iterator aTokenMatrixMapIter;
+
+ // Once upon a time we used to have FP exceptions on, and there was a
+ // Windows printer driver that kept switching off exceptions, so we had to
+ // switch them back on again every time. Who knows if there isn't a driver
+ // that keeps switching exceptions on, now that we run with exceptions off,
+ // so reassure exceptions are really off.
+ SAL_MATH_FPEXCEPTIONS_OFF();
+
+ aCode.Reset();
+ while( ( pCur = aCode.Next() ) != NULL
+ && (!nGlobalError || nErrorFunction <= nErrorFunctionCount) )
+ {
+ OpCode eOp = pCur->GetOpCode();
+ cPar = pCur->GetByte();
+ if ( eOp == ocPush )
+ {
+ // RPN code push without error
+ PushWithoutError( (FormulaToken&) *pCur );
+ }
+ else if (pTokenMatrixMap && !(eOp == ocIf || eOp == ocChose) &&
+ ((aTokenMatrixMapIter = pTokenMatrixMap->find( pCur)) !=
+ pTokenMatrixMap->end()) &&
+ (*aTokenMatrixMapIter).second->GetType() != svJumpMatrix)
+ {
+ // Path already calculated, reuse result.
+ nStackBase = sp - pCur->GetParamCount();
+ if ( nStackBase > sp )
+ nStackBase = sp; // underflow?!?
+ sp = nStackBase;
+ PushTempToken( (*aTokenMatrixMapIter).second);
+ }
+ else
+ {
+ // previous expression determines the current number format
+ nCurFmtType = nRetTypeExpr;
+ nCurFmtIndex = nRetIndexExpr;
+ // default function's format, others are set if needed
+ nFuncFmtType = NUMBERFORMAT_NUMBER;
+ nFuncFmtIndex = 0;
+
+ if ( eOp == ocIf || eOp == ocChose )
+ nStackBase = sp; // don't mess around with the jumps
+ else
+ {
+ // Convert parameters to matrix if in array/matrix formula and
+ // parameters of function indicate doing so. Create JumpMatrix
+ // if necessary.
+ if ( MatrixParameterConversion() )
+ {
+ eOp = ocNone; // JumpMatrix created
+ nStackBase = sp;
+ }
+ else
+ nStackBase = sp - pCur->GetParamCount();
+ }
+ if ( nStackBase > sp )
+ nStackBase = sp; // underflow?!?
+
+ switch( eOp )
+ {
+ case ocSep:
+ case ocClose: // pushed by the compiler
+ case ocMissing : ScMissing(); break;
+ case ocMacro : ScMacro(); break;
+ case ocDBArea : ScDBArea(); break;
+ case ocColRowNameAuto : ScColRowNameAuto(); break;
+// separated case ocPush : Push( (ScToken&) *pCur ); break;
+ case ocExternalRef : ScExternalRef(); break;
+ case ocIf : ScIfJump(); break;
+ case ocChose : ScChoseJump(); break;
+ case ocAdd : ScAdd(); break;
+ case ocSub : ScSub(); break;
+ case ocMul : ScMul(); break;
+ case ocDiv : ScDiv(); break;
+ case ocAmpersand : ScAmpersand(); break;
+ case ocPow : ScPow(); break;
+ case ocEqual : ScEqual(); break;
+ case ocNotEqual : ScNotEqual(); break;
+ case ocLess : ScLess(); break;
+ case ocGreater : ScGreater(); break;
+ case ocLessEqual : ScLessEqual(); break;
+ case ocGreaterEqual : ScGreaterEqual(); break;
+ case ocAnd : ScAnd(); break;
+ case ocOr : ScOr(); break;
+ case ocIntersect : ScIntersect(); break;
+ case ocRange : ScRangeFunc(); break;
+ case ocUnion : ScUnionFunc(); break;
+ case ocNot : ScNot(); break;
+ case ocNegSub :
+ case ocNeg : ScNeg(); break;
+ case ocPercentSign : ScPercentSign(); break;
+ case ocPi : ScPi(); break;
+// case ocDefPar : ScDefPar(); break;
+ case ocRandom : ScRandom(); break;
+ case ocTrue : ScTrue(); break;
+ case ocFalse : ScFalse(); break;
+ case ocGetActDate : ScGetActDate(); break;
+ case ocGetActTime : ScGetActTime(); break;
+ case ocNotAvail : PushError( NOTAVAILABLE); break;
+ case ocDeg : ScDeg(); break;
+ case ocRad : ScRad(); break;
+ case ocSin : ScSin(); break;
+ case ocCos : ScCos(); break;
+ case ocTan : ScTan(); break;
+ case ocCot : ScCot(); break;
+ case ocArcSin : ScArcSin(); break;
+ case ocArcCos : ScArcCos(); break;
+ case ocArcTan : ScArcTan(); break;
+ case ocArcCot : ScArcCot(); break;
+ case ocSinHyp : ScSinHyp(); break;
+ case ocCosHyp : ScCosHyp(); break;
+ case ocTanHyp : ScTanHyp(); break;
+ case ocCotHyp : ScCotHyp(); break;
+ case ocArcSinHyp : ScArcSinHyp(); break;
+ case ocArcCosHyp : ScArcCosHyp(); break;
+ case ocArcTanHyp : ScArcTanHyp(); break;
+ case ocArcCotHyp : ScArcCotHyp(); break;
+ case ocExp : ScExp(); break;
+ case ocLn : ScLn(); break;
+ case ocLog10 : ScLog10(); break;
+ case ocSqrt : ScSqrt(); break;
+ case ocFact : ScFact(); break;
+ case ocGetYear : ScGetYear(); break;
+ case ocGetMonth : ScGetMonth(); break;
+ case ocGetDay : ScGetDay(); break;
+ case ocGetDayOfWeek : ScGetDayOfWeek(); break;
+ case ocWeek : ScGetWeekOfYear(); break;
+ case ocEasterSunday : ScEasterSunday(); break;
+ case ocGetHour : ScGetHour(); break;
+ case ocGetMin : ScGetMin(); break;
+ case ocGetSec : ScGetSec(); break;
+ case ocPlusMinus : ScPlusMinus(); break;
+ case ocAbs : ScAbs(); break;
+ case ocInt : ScInt(); break;
+ case ocEven : ScEven(); break;
+ case ocOdd : ScOdd(); break;
+ case ocPhi : ScPhi(); break;
+ case ocGauss : ScGauss(); break;
+ case ocStdNormDist : ScStdNormDist(); break;
+ case ocFisher : ScFisher(); break;
+ case ocFisherInv : ScFisherInv(); break;
+ case ocIsEmpty : ScIsEmpty(); break;
+ case ocIsString : ScIsString(); break;
+ case ocIsNonString : ScIsNonString(); break;
+ case ocIsLogical : ScIsLogical(); break;
+ case ocType : ScType(); break;
+ case ocCell : ScCell(); break;
+ case ocIsRef : ScIsRef(); break;
+ case ocIsValue : ScIsValue(); break;
+ case ocIsFormula : ScIsFormula(); break;
+ case ocFormula : ScFormula(); break;
+ case ocIsNA : ScIsNV(); break;
+ case ocIsErr : ScIsErr(); break;
+ case ocIsError : ScIsError(); break;
+ case ocIsEven : ScIsEven(); break;
+ case ocIsOdd : ScIsOdd(); break;
+ case ocN : ScN(); break;
+ case ocGetDateValue : ScGetDateValue(); break;
+ case ocGetTimeValue : ScGetTimeValue(); break;
+ case ocCode : ScCode(); break;
+ case ocTrim : ScTrim(); break;
+ case ocUpper : ScUpper(); break;
+ case ocPropper : ScPropper(); break;
+ case ocLower : ScLower(); break;
+ case ocLen : ScLen(); break;
+ case ocT : ScT(); break;
+ case ocClean : ScClean(); break;
+ case ocValue : ScValue(); break;
+ case ocChar : ScChar(); break;
+ case ocArcTan2 : ScArcTan2(); break;
+ case ocMod : ScMod(); break;
+ case ocPower : ScPower(); break;
+ case ocRound : ScRound(); break;
+ case ocRoundUp : ScRoundUp(); break;
+ case ocTrunc :
+ case ocRoundDown : ScRoundDown(); break;
+ case ocCeil : ScCeil(); break;
+ case ocFloor : ScFloor(); break;
+ case ocSumProduct : ScSumProduct(); break;
+ case ocSumSQ : ScSumSQ(); break;
+ case ocSumX2MY2 : ScSumX2MY2(); break;
+ case ocSumX2DY2 : ScSumX2DY2(); break;
+ case ocSumXMY2 : ScSumXMY2(); break;
+ case ocLog : ScLog(); break;
+ case ocGCD : ScGCD(); break;
+ case ocLCM : ScLCM(); break;
+ case ocGetDate : ScGetDate(); break;
+ case ocGetTime : ScGetTime(); break;
+ case ocGetDiffDate : ScGetDiffDate(); break;
+ case ocGetDiffDate360 : ScGetDiffDate360(); break;
+ case ocMin : ScMin( FALSE ); break;
+ case ocMinA : ScMin( TRUE ); break;
+ case ocMax : ScMax( FALSE ); break;
+ case ocMaxA : ScMax( TRUE ); break;
+ case ocSum : ScSum(); break;
+ case ocProduct : ScProduct(); break;
+ case ocNPV : ScNPV(); break;
+ case ocIRR : ScIRR(); break;
+ case ocMIRR : ScMIRR(); break;
+ case ocISPMT : ScISPMT(); break;
+ case ocAverage : ScAverage( FALSE ); break;
+ case ocAverageA : ScAverage( TRUE ); break;
+ case ocCount : ScCount(); break;
+ case ocCount2 : ScCount2(); break;
+ case ocVar : ScVar( FALSE ); break;
+ case ocVarA : ScVar( TRUE ); break;
+ case ocVarP : ScVarP( FALSE ); break;
+ case ocVarPA : ScVarP( TRUE ); break;
+ case ocStDev : ScStDev( FALSE ); break;
+ case ocStDevA : ScStDev( TRUE ); break;
+ case ocStDevP : ScStDevP( FALSE ); break;
+ case ocStDevPA : ScStDevP( TRUE ); break;
+ case ocBW : ScBW(); break;
+ case ocDIA : ScDIA(); break;
+ case ocGDA : ScGDA(); break;
+ case ocGDA2 : ScGDA2(); break;
+ case ocVBD : ScVDB(); break;
+ case ocLaufz : ScLaufz(); break;
+ case ocLIA : ScLIA(); break;
+ case ocRMZ : ScRMZ(); break;
+ case ocColumns : ScColumns(); break;
+ case ocRows : ScRows(); break;
+ case ocTables : ScTables(); break;
+ case ocColumn : ScColumn(); break;
+ case ocRow : ScRow(); break;
+ case ocTable : ScTable(); break;
+ case ocZGZ : ScZGZ(); break;
+ case ocZW : ScZW(); break;
+ case ocZZR : ScZZR(); break;
+ case ocZins : ScZins(); break;
+ case ocZinsZ : ScZinsZ(); break;
+ case ocKapz : ScKapz(); break;
+ case ocKumZinsZ : ScKumZinsZ(); break;
+ case ocKumKapZ : ScKumKapZ(); break;
+ case ocEffektiv : ScEffektiv(); break;
+ case ocNominal : ScNominal(); break;
+ case ocSubTotal : ScSubTotal(); break;
+ case ocDBSum : ScDBSum(); break;
+ case ocDBCount : ScDBCount(); break;
+ case ocDBCount2 : ScDBCount2(); break;
+ case ocDBAverage : ScDBAverage(); break;
+ case ocDBGet : ScDBGet(); break;
+ case ocDBMax : ScDBMax(); break;
+ case ocDBMin : ScDBMin(); break;
+ case ocDBProduct : ScDBProduct(); break;
+ case ocDBStdDev : ScDBStdDev(); break;
+ case ocDBStdDevP : ScDBStdDevP(); break;
+ case ocDBVar : ScDBVar(); break;
+ case ocDBVarP : ScDBVarP(); break;
+ case ocIndirect : ScIndirect(); break;
+ case ocAddress : ScAddressFunc(); break;
+ case ocMatch : ScMatch(); break;
+ case ocCountEmptyCells : ScCountEmptyCells(); break;
+ case ocCountIf : ScCountIf(); break;
+ case ocSumIf : ScSumIf(); break;
+ case ocLookup : ScLookup(); break;
+ case ocVLookup : ScVLookup(); break;
+ case ocHLookup : ScHLookup(); break;
+ case ocIndex : ScIndex(); break;
+ case ocMultiArea : ScMultiArea(); break;
+ case ocOffset : ScOffset(); break;
+ case ocAreas : ScAreas(); break;
+ case ocCurrency : ScCurrency(); break;
+ case ocReplace : ScReplace(); break;
+ case ocFixed : ScFixed(); break;
+ case ocFind : ScFind(); break;
+ case ocExact : ScExact(); break;
+ case ocLeft : ScLeft(); break;
+ case ocRight : ScRight(); break;
+ case ocSearch : ScSearch(); break;
+ case ocMid : ScMid(); break;
+ case ocText : ScText(); break;
+ case ocSubstitute : ScSubstitute(); break;
+ case ocRept : ScRept(); break;
+ case ocConcat : ScConcat(); break;
+ case ocMatValue : ScMatValue(); break;
+ case ocMatrixUnit : ScEMat(); break;
+ case ocMatDet : ScMatDet(); break;
+ case ocMatInv : ScMatInv(); break;
+ case ocMatMult : ScMatMult(); break;
+ case ocMatTrans : ScMatTrans(); break;
+ case ocMatRef : ScMatRef(); break;
+ case ocBackSolver : ScBackSolver(); break;
+ case ocB : ScB(); break;
+ case ocNormDist : ScNormDist(); break;
+ case ocExpDist : ScExpDist(); break;
+ case ocBinomDist : ScBinomDist(); break;
+ case ocPoissonDist : ScPoissonDist(); break;
+ case ocKombin : ScKombin(); break;
+ case ocKombin2 : ScKombin2(); break;
+ case ocVariationen : ScVariationen(); break;
+ case ocVariationen2 : ScVariationen2(); break;
+ case ocHypGeomDist : ScHypGeomDist(); break;
+ case ocLogNormDist : ScLogNormDist(); break;
+ case ocTDist : ScTDist(); break;
+ case ocFDist : ScFDist(); break;
+ case ocChiDist : ScChiDist(); break;
+ case ocChiSqDist : ScChiSqDist(); break;
+ case ocStandard : ScStandard(); break;
+ case ocAveDev : ScAveDev(); break;
+ case ocDevSq : ScDevSq(); break;
+ case ocKurt : ScKurt(); break;
+ case ocSchiefe : ScSkew(); break;
+ case ocModalValue : ScModalValue(); break;
+ case ocMedian : ScMedian(); break;
+ case ocGeoMean : ScGeoMean(); break;
+ case ocHarMean : ScHarMean(); break;
+ case ocWeibull : ScWeibull(); break;
+ case ocKritBinom : ScCritBinom(); break;
+ case ocNegBinomVert : ScNegBinomDist(); break;
+ case ocNoName : ScNoName(); break;
+ case ocBad : ScBadName(); break;
+ case ocZTest : ScZTest(); break;
+ case ocTTest : ScTTest(); break;
+ case ocFTest : ScFTest(); break;
+ case ocRank : ScRank(); break;
+ case ocPercentile : ScPercentile(); break;
+ case ocPercentrank : ScPercentrank(); break;
+ case ocLarge : ScLarge(); break;
+ case ocSmall : ScSmall(); break;
+ case ocFrequency : ScFrequency(); break;
+ case ocQuartile : ScQuartile(); break;
+ case ocNormInv : ScNormInv(); break;
+ case ocSNormInv : ScSNormInv(); break;
+ case ocConfidence : ScConfidence(); break;
+ case ocTrimMean : ScTrimMean(); break;
+ case ocProb : ScProbability(); break;
+ case ocCorrel : ScCorrel(); break;
+ case ocCovar : ScCovar(); break;
+ case ocPearson : ScPearson(); break;
+ case ocRSQ : ScRSQ(); break;
+ case ocSTEYX : ScSTEXY(); break;
+ case ocSlope : ScSlope(); break;
+ case ocIntercept : ScIntercept(); break;
+ case ocTrend : ScTrend(); break;
+ case ocGrowth : ScGrowth(); break;
+ case ocRGP : ScRGP(); break;
+ case ocRKP : ScRKP(); break;
+ case ocForecast : ScForecast(); break;
+ case ocGammaLn : ScLogGamma(); break;
+ case ocGamma : ScGamma(); break;
+ case ocGammaDist : ScGammaDist(); break;
+ case ocGammaInv : ScGammaInv(); break;
+ case ocChiTest : ScChiTest(); break;
+ case ocChiInv : ScChiInv(); break;
+ case ocChiSqInv : ScChiSqInv(); break;
+ case ocTInv : ScTInv(); break;
+ case ocFInv : ScFInv(); break;
+ case ocLogInv : ScLogNormInv(); break;
+ case ocBetaDist : ScBetaDist(); break;
+ case ocBetaInv : ScBetaInv(); break;
+ case ocExternal : ScExternal(); break;
+ case ocTableOp : ScTableOp(); break;
+// case ocErrCell : ScErrCell(); break;
+ case ocStop : break;
+ case ocErrorType : ScErrorType(); break;
+ case ocCurrent : ScCurrent(); break;
+ case ocStyle : ScStyle(); break;
+ case ocDde : ScDde(); break;
+ case ocBase : ScBase(); break;
+ case ocDecimal : ScDecimal(); break;
+ case ocConvert : ScConvert(); break;
+ case ocEuroConvert : ScEuroConvert(); break;
+ case ocRoman : ScRoman(); break;
+ case ocArabic : ScArabic(); break;
+ case ocInfo : ScInfo(); break;
+ case ocHyperLink : ScHyperLink(); break;
+ case ocBahtText : ScBahtText(); break;
+ case ocGetPivotData : ScGetPivotData(); break;
+ case ocJis : ScJis(); break;
+ case ocAsc : ScAsc(); break;
+ case ocUnicode : ScUnicode(); break;
+ case ocUnichar : ScUnichar(); break;
+ case ocTTT : ScTTT(); break;
+ case ocNone : nFuncFmtType = NUMBERFORMAT_UNDEFINED; break;
+ 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,
+ pStack[sp-1]));
+
+ // outer function determines format of an expression
+ if ( nFuncFmtType != NUMBERFORMAT_UNDEFINED )
+ {
+ nRetTypeExpr = nFuncFmtType;
+ // inherit the format index only for currency formats
+ nRetIndexExpr = ( nFuncFmtType == NUMBERFORMAT_CURRENCY ?
+ nFuncFmtIndex : 0 );
+ }
+ }
+
+ // Need a clean stack environment for the JumpMatrix to work.
+ if (nGlobalError && eOp != ocPush && sp > nStackBase + 1)
+ {
+ // Not all functions pop all parameters in case an error is
+ // generated. Clean up stack. Assumes that every function pushes a
+ // result, may be arbitrary in case of error.
+ const FormulaToken* pLocalResult = pStack[ sp - 1 ];
+ while (sp > nStackBase)
+ Pop();
+ PushTempToken( *pLocalResult );
+ }
+
+ bool bGotResult;
+ do
+ {
+ bGotResult = false;
+ BYTE nLevel = 0;
+ if ( GetStackType( ++nLevel ) == svJumpMatrix )
+ ; // nothing
+ else if ( GetStackType( ++nLevel ) == svJumpMatrix )
+ ; // nothing
+ else
+ nLevel = 0;
+ if ( nLevel == 1 || (nLevel == 2 && aCode.IsEndOfPath()) )
+ bGotResult = JumpMatrix( nLevel );
+ else
+ pJumpMatrix = NULL;
+ } while ( bGotResult );
+
+
+// Functions that evaluate an error code and directly set nGlobalError to 0,
+// usage: switch( OpCode ) { CASE_OCERRFUNC statements; }
+#define CASE_OCERRFUNC \
+ case ocCount : \
+ case ocCount2 : \
+ case ocErrorType : \
+ case ocIsEmpty : \
+ case ocIsErr : \
+ case ocIsError : \
+ case ocIsFormula : \
+ case ocIsLogical : \
+ case ocIsNA : \
+ case ocIsNonString : \
+ case ocIsRef : \
+ case ocIsString : \
+ case ocIsValue : \
+ case ocN : \
+ case ocType :
+
+ switch ( eOp )
+ {
+ CASE_OCERRFUNC
+ ++ nErrorFunction;
+ default:
+ ; // nothing
+ }
+ if ( nGlobalError )
+ {
+ if ( !nErrorFunctionCount )
+ { // count of errorcode functions in formula
+ for ( FormulaToken* t = rArr.FirstRPN(); t; t = rArr.NextRPN() )
+ {
+ switch ( t->GetOpCode() )
+ {
+ CASE_OCERRFUNC
+ ++nErrorFunctionCount;
+ default:
+ ; // nothing
+ }
+ }
+ }
+ if ( nErrorFunction >= nErrorFunctionCount )
+ ++nErrorFunction; // that's it, error => terminate
+ }
+ }
+
+ // End: obtain result
+
+ if( sp )
+ {
+ pCur = pStack[ sp-1 ];
+ if( pCur->GetOpCode() == ocPush )
+ {
+ switch( pCur->GetType() )
+ {
+ case svEmptyCell:
+ ; // nothing
+ break;
+ case svError:
+ nGlobalError = pCur->GetError();
+ break;
+ case svDouble :
+ if ( nFuncFmtType == NUMBERFORMAT_UNDEFINED )
+ {
+ nRetTypeExpr = NUMBERFORMAT_NUMBER;
+ nRetIndexExpr = 0;
+ }
+ break;
+ case svString :
+ nRetTypeExpr = NUMBERFORMAT_TEXT;
+ nRetIndexExpr = 0;
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if( !nGlobalError )
+ PushCellResultToken( false, aAdr,
+ &nRetTypeExpr, &nRetIndexExpr);
+ }
+ break;
+ case svRefList :
+ PopError(); // maybe #REF! takes precedence over #VALUE!
+ PushError( errNoValue);
+ break;
+ case svDoubleRef :
+ {
+ if ( bMatrixFormula )
+ { // create matrix for {=A1:A5}
+ PopDoubleRefPushMatrix();
+ // no break, continue with svMatrix
+ }
+ else
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange );
+ ScAddress aAdr;
+ if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr))
+ PushCellResultToken( false, aAdr,
+ &nRetTypeExpr, &nRetIndexExpr);
+ break;
+ }
+ }
+ // no break
+ case svMatrix :
+ {
+ ScMatrixRef xMat = PopMatrix();
+ if (xMat)
+ {
+ ScMatValType nMatValType;
+ const ScMatrixValue* pMatVal = xMat->Get(0, 0, nMatValType);
+ if ( pMatVal )
+ {
+ if (ScMatrix::IsNonValueType( nMatValType))
+ {
+ if ( xMat->IsEmptyPath( 0, 0))
+ { // result of empty FALSE jump path
+ FormulaTokenRef xRes = new FormulaDoubleToken( 0.0);
+ PushTempToken( new ScMatrixCellResultToken( xMat, xRes));
+ nRetTypeExpr = NUMBERFORMAT_LOGICAL;
+ }
+ else
+ {
+ String aStr( pMatVal->GetString());
+ FormulaTokenRef xRes = new FormulaStringToken( aStr);
+ PushTempToken( new ScMatrixCellResultToken( xMat, xRes));
+ nRetTypeExpr = NUMBERFORMAT_TEXT;
+ }
+ }
+ else
+ {
+ USHORT nErr = GetDoubleErrorValue( pMatVal->fVal);
+ FormulaTokenRef xRes;
+ if (nErr)
+ xRes = new FormulaErrorToken( nErr);
+ else
+ xRes = new FormulaDoubleToken( pMatVal->fVal);
+ PushTempToken( new ScMatrixCellResultToken( xMat, xRes));
+ if ( nRetTypeExpr != NUMBERFORMAT_LOGICAL )
+ nRetTypeExpr = NUMBERFORMAT_NUMBER;
+ }
+ nRetIndexExpr = 0;
+ }
+ else
+ SetError( errUnknownStackVariable);
+ xMat->SetErrorInterpreter( NULL);
+ }
+ else
+ SetError( errUnknownStackVariable);
+ }
+ break;
+ default :
+ SetError( errUnknownStackVariable);
+ }
+ }
+ else
+ SetError( errUnknownStackVariable);
+ }
+ else
+ SetError( errNoCode);
+
+ if( nRetTypeExpr != NUMBERFORMAT_UNDEFINED )
+ {
+ nRetFmtType = nRetTypeExpr;
+ nRetFmtIndex = nRetIndexExpr;
+ }
+ else if( nFuncFmtType != NUMBERFORMAT_UNDEFINED )
+ {
+ nRetFmtType = nFuncFmtType;
+ nRetFmtIndex = nFuncFmtIndex;
+ }
+ else
+ nRetFmtType = NUMBERFORMAT_NUMBER;
+ // inherit the format index only for currency formats
+ if ( nRetFmtType != NUMBERFORMAT_CURRENCY )
+ nRetFmtIndex = 0;
+
+ if (nGlobalError && GetStackType() != svError )
+ PushError( nGlobalError);
+
+ // THE final result.
+ xResult = PopToken();
+ if (!xResult)
+ xResult = new FormulaErrorToken( errUnknownStackVariable);
+
+ // release tokens in expression stack
+ FormulaToken** p = pStack;
+ while( maxsp-- )
+ (*p++)->DecRef();
+
+ StackVar eType = xResult->GetType();
+ if (eType == svMatrix)
+ // Results are immutable in case they would be reused as input for new
+ // interpreters.
+ static_cast<ScToken*>(xResult.operator->())->GetMatrix()->SetImmutable( true);
+ return eType;
+}
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
new file mode 100644
index 000000000000..73794cf15b2d
--- /dev/null
+++ b/sc/source/core/tool/interpr5.cxx
@@ -0,0 +1,2815 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+
+#ifndef INCLUDED_RTL_MATH_HXX
+#include <rtl/math.hxx>
+#endif
+#include <rtl/logfile.hxx>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+#include <unotools/bootstrap.hxx>
+#include <svl/zforlist.hxx>
+
+#include "interpre.hxx"
+#include "global.hxx"
+#include "compiler.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "dociter.hxx"
+#include "scmatrix.hxx"
+#include "globstr.hrc"
+#include "cellkeytranslator.hxx"
+#include "osversiondef.hxx"
+
+#include <string.h>
+#include <math.h>
+#include <vector>
+
+using ::std::vector;
+using namespace formula;
+
+const double fInvEpsilon = 1.0E-7;
+
+// -----------------------------------------------------------------------
+ struct MatrixAdd : public ::std::binary_function<double,double,double>
+ {
+ inline double operator() (const double& lhs, const double& rhs) const
+ {
+ return ::rtl::math::approxAdd( lhs,rhs);
+ }
+ };
+ struct MatrixSub : public ::std::binary_function<double,double,double>
+ {
+ inline double operator() (const double& lhs, const double& rhs) const
+ {
+ return ::rtl::math::approxSub( lhs,rhs);
+ }
+ };
+ struct MatrixMul : public ::std::binary_function<double,double,double>
+ {
+ inline double operator() (const double& lhs, const double& rhs) const
+ {
+ return lhs * rhs;
+ }
+ };
+ struct MatrixDiv : public ::std::binary_function<double,double,double>
+ {
+ inline double operator() (const double& lhs, const double& rhs) const
+ {
+ return ScInterpreter::div( lhs,rhs);
+ }
+ };
+ struct MatrixPow : public ::std::binary_function<double,double,double>
+ {
+ inline double operator() (const double& lhs, const double& rhs) const
+ {
+ return ::pow( lhs,rhs);
+ }
+ };
+
+double ScInterpreter::ScGetGCD(double fx, double fy)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::div" );
+ // By ODFF definition GCD(0,a) => a. This is also vital for the code in
+ // ScGCD() to work correctly with a preset fy=0.0
+ if (fy == 0.0)
+ return fx;
+ else if (fx == 0.0)
+ return fy;
+ else
+ {
+ double fz = fmod(fx, fy);
+ while (fz > 0.0)
+ {
+ fx = fy;
+ fy = fz;
+ fz = fmod(fx, fy);
+ }
+ return fy;
+ }
+}
+
+void ScInterpreter::ScGCD()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGCD" );
+ short nParamCount = GetByte();
+ if ( MustHaveParamCountMin( nParamCount, 1 ) )
+ {
+ double fx, fy = 0.0;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while (!nGlobalError && nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case svDouble :
+ case svString:
+ case svSingleRef:
+ {
+ fx = ::rtl::math::approxFloor( GetDouble());
+ if (fx < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ fy = ScGetGCD(fx, fy);
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ double nCellVal;
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ do
+ {
+ fx = ::rtl::math::approxFloor( nCellVal);
+ if (fx < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ fy = ScGetGCD(fx, fy);
+ } while (nErr == 0 && aValIter.GetNext(nCellVal, nErr));
+ }
+ SetError(nErr);
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if (nC == 0 || nR == 0)
+ SetError(errIllegalArgument);
+ else
+ {
+ SCSIZE nCount = nC * nR;
+ for ( SCSIZE j = 0; j < nCount; j++ )
+ {
+ if (!pMat->IsValue(j))
+ {
+ PushIllegalArgument();
+ return;
+ }
+ fx = ::rtl::math::approxFloor( pMat->GetDouble(j));
+ if (fx < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ fy = ScGetGCD(fx, fy);
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ }
+ PushDouble(fy);
+ }
+}
+
+void ScInterpreter:: ScLCM()
+{
+ short nParamCount = GetByte();
+ if ( MustHaveParamCountMin( nParamCount, 1 ) )
+ {
+ double fx, fy = 1.0;
+ ScRange aRange;
+ size_t nRefInList = 0;
+ while (!nGlobalError && nParamCount-- > 0)
+ {
+ switch (GetStackType())
+ {
+ case svDouble :
+ case svString:
+ case svSingleRef:
+ {
+ fx = ::rtl::math::approxFloor( GetDouble());
+ if (fx < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (fx == 0.0 || fy == 0.0)
+ fy = 0.0;
+ else
+ fy = fx * fy / ScGetGCD(fx, fy);
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ USHORT nErr = 0;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ double nCellVal;
+ ScValueIterator aValIter(pDok, aRange, glSubTotal);
+ if (aValIter.GetFirst(nCellVal, nErr))
+ {
+ do
+ {
+ fx = ::rtl::math::approxFloor( nCellVal);
+ if (fx < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (fx == 0.0 || fy == 0.0)
+ fy = 0.0;
+ else
+ fy = fx * fy / ScGetGCD(fx, fy);
+ } while (nErr == 0 && aValIter.GetNext(nCellVal, nErr));
+ }
+ SetError(nErr);
+ }
+ break;
+ case svMatrix :
+ {
+ ScMatrixRef pMat = PopMatrix();
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if (nC == 0 || nR == 0)
+ SetError(errIllegalArgument);
+ else
+ {
+ SCSIZE nCount = nC * nR;
+ for ( SCSIZE j = 0; j < nCount; j++ )
+ {
+ if (!pMat->IsValue(j))
+ {
+ PushIllegalArgument();
+ return;
+ }
+ fx = ::rtl::math::approxFloor( pMat->GetDouble(j));
+ if (fx < 0.0)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ if (fx == 0.0 || fy == 0.0)
+ fy = 0.0;
+ else
+ fy = fx * fy / ScGetGCD(fx, fy);
+ }
+ }
+ }
+ }
+ break;
+ default : SetError(errIllegalParameter); break;
+ }
+ }
+ PushDouble(fy);
+ }
+}
+
+ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetNewMat" );
+ ScMatrix* pMat = new ScMatrix( nC, nR);
+ pMat->SetErrorInterpreter( this);
+ // A temporary matrix is mutable and ScMatrix::CloneIfConst() returns the
+ // very matrix.
+ pMat->SetImmutable( false);
+ SCSIZE nCols, nRows;
+ pMat->GetDimensions( nCols, nRows);
+ if ( nCols != nC || nRows != nR )
+ { // arbitray limit of elements exceeded
+ SetError( errStackOverflow);
+ pMat->Delete();
+ pMat = NULL;
+ }
+ return pMat;
+}
+
+ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateMatrixFromDoubleRef" );
+ ScMatrixRef pMat = NULL;
+ if (nTab1 == nTab2 && !nGlobalError)
+ {
+ ScTokenMatrixMap::const_iterator aIter;
+ if ( static_cast<SCSIZE>(nRow2 - nRow1 + 1) *
+ static_cast<SCSIZE>(nCol2 - nCol1 + 1) >
+ ScMatrix::GetElementsMax() )
+ SetError(errStackOverflow);
+ else if (pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken))
+ != pTokenMatrixMap->end()))
+ pMat = static_cast<ScToken*>((*aIter).second.get())->GetMatrix();
+ else
+ {
+ SCSIZE nMatCols = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
+ SCSIZE nMatRows = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
+ pMat = GetNewMat( nMatCols, nMatRows);
+ if (pMat && !nGlobalError)
+ {
+ // Set position where the next entry is expected.
+ SCROW nNextRow = nRow1;
+ SCCOL nNextCol = nCol1;
+ // Set last position as if there was a previous entry.
+ SCROW nThisRow = nRow2;
+ SCCOL nThisCol = nCol1 - 1;
+ ScCellIterator aCellIter( pDok, nCol1, nRow1, nTab1, nCol2,
+ nRow2, nTab2);
+ for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell =
+ aCellIter.GetNext())
+ {
+ nThisCol = aCellIter.GetCol();
+ nThisRow = aCellIter.GetRow();
+ if (nThisCol != nNextCol || nThisRow != nNextRow)
+ {
+ // Fill empty between iterator's positions.
+ for ( ; nNextCol <= nThisCol; ++nNextCol)
+ {
+ SCSIZE nC = nNextCol - nCol1;
+ SCSIZE nMatStopRow = ((nNextCol < nThisCol) ?
+ nMatRows : nThisRow - nRow1);
+ for (SCSIZE nR = nNextRow - nRow1; nR <
+ nMatStopRow; ++nR)
+ {
+ pMat->PutEmpty( nC, nR);
+ }
+ nNextRow = nRow1;
+ }
+ }
+ if (nThisRow == nRow2)
+ {
+ nNextCol = nThisCol + 1;
+ nNextRow = nRow1;
+ }
+ else
+ {
+ nNextCol = nThisCol;
+ nNextRow = nThisRow + 1;
+ }
+ if (HasCellEmptyData(pCell))
+ {
+ pMat->PutEmpty( static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
+ }
+ else if (HasCellValueData(pCell))
+ {
+ ScAddress aAdr( nThisCol, nThisRow, nTab1);
+ double fVal = GetCellValue( aAdr, pCell);
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
+ }
+ pMat->PutDouble( fVal,
+ static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
+ }
+ else
+ {
+ String aStr;
+ GetCellString( aStr, pCell);
+ if ( nGlobalError )
+ {
+ double fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
+ pMat->PutDouble( fVal,
+ static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
+ }
+ else
+ pMat->PutString( aStr,
+ static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
+ }
+ }
+ // Fill empty if iterator's last position wasn't the end.
+ if (nThisCol != nCol2 || nThisRow != nRow2)
+ {
+ for ( ; nNextCol <= nCol2; ++nNextCol)
+ {
+ SCSIZE nC = nNextCol - nCol1;
+ for (SCSIZE nR = nNextRow - nRow1; nR < nMatRows; ++nR)
+ {
+ pMat->PutEmpty( nC, nR);
+ }
+ nNextRow = nRow1;
+ }
+ }
+ if (pTokenMatrixMap)
+ pTokenMatrixMap->insert( ScTokenMatrixMap::value_type(
+ pToken, new ScMatrixToken( pMat)));
+ }
+ }
+ }
+ else // not a 2D matrix
+ SetError(errIllegalParameter);
+ return pMat;
+}
+
+
+ScMatrixRef ScInterpreter::GetMatrix()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetMatrix" );
+ ScMatrixRef pMat = NULL;
+ switch (GetRawStackType())
+ {
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ pMat = GetNewMat(1, 1);
+ if (pMat)
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData(pCell))
+ pMat->PutEmpty( 0 );
+ else if (HasCellValueData(pCell))
+ pMat->PutDouble(GetCellValue(aAdr, pCell), 0);
+ else
+ {
+ String aStr;
+ GetCellString(aStr, pCell);
+ pMat->PutString(aStr, 0);
+ }
+ }
+ }
+ break;
+ case svDoubleRef:
+ {
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ SCTAB nTab1, nTab2;
+ const ScToken* p = sp ? static_cast<const ScToken*>(pStack[sp-1]) : NULL;
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ pMat = CreateMatrixFromDoubleRef( p, nCol1, nRow1, nTab1,
+ nCol2, nRow2, nTab2);
+ }
+ break;
+ case svMatrix:
+ pMat = PopMatrix();
+ break;
+ case svError :
+ case svMissing :
+ case svDouble :
+ {
+ double fVal = GetDouble();
+ pMat = GetNewMat( 1, 1);
+ if ( pMat )
+ {
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
+ }
+ pMat->PutDouble( fVal, 0);
+ }
+ }
+ break;
+ case svString :
+ {
+ String aStr = GetString();
+ pMat = GetNewMat( 1, 1);
+ if ( pMat )
+ {
+ if ( nGlobalError )
+ {
+ double fVal = CreateDoubleError( nGlobalError);
+ pMat->PutDouble( fVal, 0);
+ nGlobalError = 0;
+ }
+ else
+ pMat->PutString( aStr, 0);
+ }
+ }
+ break;
+ default:
+ PopError();
+ SetError( errIllegalArgument);
+ break;
+ }
+ return pMat;
+}
+
+void ScInterpreter::ScMatValue()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatValue" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ // 0 to count-1
+ SCSIZE nR = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble()));
+ SCSIZE nC = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble()));
+ switch (GetStackType())
+ {
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ USHORT nErrCode = ((ScFormulaCell*)pCell)->GetErrCode();
+ if (nErrCode != 0)
+ PushError( nErrCode);
+ else
+ {
+ const ScMatrix* pMat = ((ScFormulaCell*)pCell)->GetMatrix();
+ CalculateMatrixValue(pMat,nC,nR);
+ }
+ }
+ else
+ PushIllegalParameter();
+ }
+ break;
+ case svDoubleRef :
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (nCol2 - nCol1 >= static_cast<SCCOL>(nR) &&
+ nRow2 - nRow1 >= static_cast<SCROW>(nC) &&
+ nTab1 == nTab2)
+ {
+ ScAddress aAdr( sal::static_int_cast<SCCOL>( nCol1 + nR ),
+ sal::static_int_cast<SCROW>( nRow1 + nC ), nTab1 );
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellValueData(pCell))
+ PushDouble(GetCellValue( aAdr, pCell ));
+ else
+ {
+ String aStr;
+ GetCellString(aStr, pCell);
+ PushString(aStr);
+ }
+ }
+ else
+ PushNoValue();
+ }
+ break;
+ case svMatrix:
+ {
+ ScMatrixRef pMat = PopMatrix();
+ CalculateMatrixValue(pMat,nC,nR);
+ }
+ break;
+ default:
+ PopError();
+ PushIllegalParameter();
+ break;
+ }
+ }
+}
+void ScInterpreter::CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateMatrixValue" );
+ if (pMat)
+ {
+ SCSIZE nCl, nRw;
+ pMat->GetDimensions(nCl, nRw);
+ if (nC < nCl && nR < nRw)
+ {
+ ScMatValType nMatValType;
+ const ScMatrixValue* pMatVal = pMat->Get( nC, nR,nMatValType);
+ if (ScMatrix::IsNonValueType( nMatValType))
+ PushString( pMatVal->GetString() );
+ else
+ PushDouble(pMatVal->fVal);
+ // also handles DoubleError
+ }
+ else
+ PushNoValue();
+ }
+ else
+ PushNoValue();
+}
+
+void ScInterpreter::ScEMat()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEMat" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ SCSIZE nDim = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble()));
+ if ( nDim * nDim > ScMatrix::GetElementsMax() || nDim == 0)
+ PushIllegalArgument();
+ else
+ {
+ ScMatrixRef pRMat = GetNewMat(nDim, nDim);
+ if (pRMat)
+ {
+ MEMat(pRMat, nDim);
+ PushMatrix(pRMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ }
+}
+
+void ScInterpreter::MEMat(ScMatrix* mM, SCSIZE n)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MEMat" );
+ mM->FillDouble(0.0, 0, 0, n-1, n-1);
+ for (SCSIZE i = 0; i < n; i++)
+ mM->PutDouble(1.0, i, i);
+}
+
+void ScInterpreter::MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR,
+ SCSIZE n, SCSIZE m, SCSIZE l)
+ // Multipliziert n x m Mat a mit m x l Mat b nach Mat r
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MFastMult" );
+ double sum;
+ for (SCSIZE i = 0; i < n; i++)
+ {
+ for (SCSIZE j = 0; j < l; j++)
+ {
+ sum = 0.0;
+ for (SCSIZE k = 0; k < m; k++)
+ sum += pA->GetDouble(i,k)*pB->GetDouble(k,j);
+ pR->PutDouble(sum, i, j);
+ }
+ }
+}
+
+
+/* Matrix LUP decomposition according to the pseudocode of "Introduction to
+ * Algorithms" by Cormen, Leiserson, Rivest, Stein.
+ *
+ * Added scaling for numeric stability.
+ *
+ * Given an n x n nonsingular matrix A, find a permutation matrix P, a unit
+ * lower-triangular matrix L, and an upper-triangular matrix U such that PA=LU.
+ * Compute L and U "in place" in the matrix A, the original content is
+ * destroyed. Note that the diagonal elements of the U triangular matrix
+ * replace the diagonal elements of the L-unit matrix (that are each ==1). The
+ * permutation matrix P is an array, where P[i]=j means that the i-th row of P
+ * contains a 1 in column j. Additionally keep track of the number of
+ * permutations (row exchanges).
+ *
+ * Returns 0 if a singular matrix is encountered, else +1 if an even number of
+ * permutations occured, or -1 if odd, which is the sign of the determinant.
+ * This may be used to calculate the determinant by multiplying the sign with
+ * the product of the diagonal elements of the LU matrix.
+ */
+static int lcl_LUP_decompose( ScMatrix* mA, const SCSIZE n,
+ ::std::vector< SCSIZE> & P )
+{
+ int nSign = 1;
+ // Find scale of each row.
+ ::std::vector< double> aScale(n);
+ for (SCSIZE i=0; i < n; ++i)
+ {
+ double fMax = 0.0;
+ for (SCSIZE j=0; j < n; ++j)
+ {
+ double fTmp = fabs( mA->GetDouble( j, i));
+ if (fMax < fTmp)
+ fMax = fTmp;
+ }
+ if (fMax == 0.0)
+ return 0; // singular matrix
+ aScale[i] = 1.0 / fMax;
+ }
+ // Represent identity permutation, P[i]=i
+ for (SCSIZE i=0; i < n; ++i)
+ P[i] = i;
+ // "Recursion" on the diagonale.
+ SCSIZE l = n - 1;
+ for (SCSIZE k=0; k < l; ++k)
+ {
+ // Implicit pivoting. With the scale found for a row, compare values of
+ // a column and pick largest.
+ double fMax = 0.0;
+ double fScale = aScale[k];
+ SCSIZE kp = k;
+ for (SCSIZE i = k; i < n; ++i)
+ {
+ double fTmp = fScale * fabs( mA->GetDouble( k, i));
+ if (fMax < fTmp)
+ {
+ fMax = fTmp;
+ kp = i;
+ }
+ }
+ if (fMax == 0.0)
+ return 0; // singular matrix
+ // Swap rows. The pivot element will be at mA[k,kp] (row,col notation)
+ if (k != kp)
+ {
+ // permutations
+ SCSIZE nTmp = P[k];
+ P[k] = P[kp];
+ P[kp] = nTmp;
+ nSign = -nSign;
+ // scales
+ double fTmp = aScale[k];
+ aScale[k] = aScale[kp];
+ aScale[kp] = fTmp;
+ // elements
+ for (SCSIZE i=0; i < n; ++i)
+ {
+ double fMatTmp = mA->GetDouble( i, k);
+ mA->PutDouble( mA->GetDouble( i, kp), i, k);
+ mA->PutDouble( fMatTmp, i, kp);
+ }
+ }
+ // Compute Schur complement.
+ for (SCSIZE i = k+1; i < n; ++i)
+ {
+ double fTmp = mA->GetDouble( k, i) / mA->GetDouble( k, k);
+ mA->PutDouble( fTmp, k, i);
+ for (SCSIZE j = k+1; j < n; ++j)
+ mA->PutDouble( mA->GetDouble( j, i) - fTmp * mA->GetDouble( j,
+ k), j, i);
+ }
+ }
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "\n%s\n", "lcl_LUP_decompose(): LU");
+ for (SCSIZE i=0; i < n; ++i)
+ {
+ for (SCSIZE j=0; j < n; ++j)
+ fprintf( stderr, "%8.2g ", mA->GetDouble( j, i));
+ fprintf( stderr, "\n%s\n", "");
+ }
+ fprintf( stderr, "\n%s\n", "lcl_LUP_decompose(): P");
+ for (SCSIZE j=0; j < n; ++j)
+ fprintf( stderr, "%5u ", (unsigned)P[j]);
+ fprintf( stderr, "\n%s\n", "");
+#endif
+ return nSign;
+}
+
+
+/* Solve a LUP decomposed equation Ax=b. LU is a combined matrix of L and U
+ * triangulars and P the permutation vector as obtained from
+ * lcl_LUP_decompose(). B is the right-hand side input vector, X is used to
+ * return the solution vector.
+ */
+static void lcl_LUP_solve( const ScMatrix* mLU, const SCSIZE n,
+ const ::std::vector< SCSIZE> & P, const ::std::vector< double> & B,
+ ::std::vector< double> & X )
+{
+ SCSIZE nFirst = SCSIZE_MAX;
+ // Ax=b => PAx=Pb, with decomposition LUx=Pb.
+ // Define y=Ux and solve for y in Ly=Pb using forward substitution.
+ for (SCSIZE i=0; i < n; ++i)
+ {
+ double fSum = B[P[i]];
+ // Matrix inversion comes with a lot of zeros in the B vectors, we
+ // don't have to do all the computing with results multiplied by zero.
+ // Until then, simply lookout for the position of the first nonzero
+ // value.
+ if (nFirst != SCSIZE_MAX)
+ {
+ for (SCSIZE j = nFirst; j < i; ++j)
+ fSum -= mLU->GetDouble( j, i) * X[j]; // X[j] === y[j]
+ }
+ else if (fSum)
+ nFirst = i;
+ X[i] = fSum; // X[i] === y[i]
+ }
+ // Solve for x in Ux=y using back substitution.
+ for (SCSIZE i = n; i--; )
+ {
+ double fSum = X[i]; // X[i] === y[i]
+ for (SCSIZE j = i+1; j < n; ++j)
+ fSum -= mLU->GetDouble( j, i) * X[j]; // X[j] === x[j]
+ X[i] = fSum / mLU->GetDouble( i, i); // X[i] === x[i]
+ }
+#if OSL_DEBUG_LEVEL >1
+ fprintf( stderr, "\n%s\n", "lcl_LUP_solve():");
+ for (SCSIZE i=0; i < n; ++i)
+ fprintf( stderr, "%8.2g ", X[i]);
+ fprintf( stderr, "%s\n", "");
+#endif
+}
+
+
+void ScInterpreter::ScMatDet()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatDet" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if (!pMat)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ if ( !pMat->IsNumeric() )
+ {
+ PushNoValue();
+ return;
+ }
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if ( nC != nR || nC == 0 || (ULONG) nC * nC > ScMatrix::GetElementsMax() )
+ PushIllegalArgument();
+ else
+ {
+ // LUP decomposition is done inplace, use copy.
+ ScMatrixRef xLU = pMat->Clone();
+ if (!xLU)
+ PushError( errCodeOverflow);
+ else
+ {
+ ::std::vector< SCSIZE> P(nR);
+ int nDetSign = lcl_LUP_decompose( xLU, nR, P);
+ if (!nDetSign)
+ PushInt(0); // singular matrix
+ else
+ {
+ // In an LU matrix the determinant is simply the product of
+ // all diagonal elements.
+ double fDet = nDetSign;
+ ScMatrix* pLU = xLU;
+ for (SCSIZE i=0; i < nR; ++i)
+ fDet *= pLU->GetDouble( i, i);
+ PushDouble( fDet);
+ }
+ }
+ }
+ }
+}
+
+void ScInterpreter::ScMatInv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatInv" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if (!pMat)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ if ( !pMat->IsNumeric() )
+ {
+ PushNoValue();
+ return;
+ }
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if ( nC != nR || nC == 0 || (ULONG) nC * nC > ScMatrix::GetElementsMax() )
+ PushIllegalArgument();
+ else
+ {
+ // LUP decomposition is done inplace, use copy.
+ ScMatrixRef xLU = pMat->Clone();
+ // The result matrix.
+ ScMatrixRef xY = GetNewMat( nR, nR);
+ if (!xLU || !xY)
+ PushError( errCodeOverflow);
+ else
+ {
+ ::std::vector< SCSIZE> P(nR);
+ int nDetSign = lcl_LUP_decompose( xLU, nR, P);
+ if (!nDetSign)
+ PushIllegalArgument();
+ else
+ {
+ // Solve equation for each column.
+ ScMatrix* pY = xY;
+ ::std::vector< double> B(nR);
+ ::std::vector< double> X(nR);
+ for (SCSIZE j=0; j < nR; ++j)
+ {
+ for (SCSIZE i=0; i < nR; ++i)
+ B[i] = 0.0;
+ B[j] = 1.0;
+ lcl_LUP_solve( xLU, nR, P, B, X);
+ for (SCSIZE i=0; i < nR; ++i)
+ pY->PutDouble( X[i], j, i);
+ }
+#if 0
+ /* Possible checks for ill-condition:
+ * 1. Scale matrix, invert scaled matrix. If there are
+ * elements of the inverted matrix that are several
+ * orders of magnitude greater than 1 =>
+ * ill-conditioned.
+ * Just how much is "several orders"?
+ * 2. Invert the inverted matrix and assess whether the
+ * result is sufficiently close to the original matrix.
+ * If not => ill-conditioned.
+ * Just what is sufficient?
+ * 3. Multiplying the inverse by the original matrix should
+ * produce a result sufficiently close to the identity
+ * matrix.
+ * Just what is sufficient?
+ *
+ * The following is #3.
+ */
+ ScMatrixRef xR = GetNewMat( nR, nR);
+ if (xR)
+ {
+ ScMatrix* pR = xR;
+ MFastMult( pMat, pY, pR, nR, nR, nR);
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "\n%s\n", "ScMatInv(): mult-identity");
+#endif
+ for (SCSIZE i=0; i < nR; ++i)
+ {
+ for (SCSIZE j=0; j < nR; ++j)
+ {
+ double fTmp = pR->GetDouble( j, i);
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "%8.2g ", fTmp);
+#endif
+ if (fabs( fTmp - (i == j)) > fInvEpsilon)
+ SetError( errIllegalArgument);
+ }
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "\n%s\n", "");
+#endif
+ }
+ }
+#endif
+ if (nGlobalError)
+ PushError( nGlobalError);
+ else
+ PushMatrix( pY);
+ }
+ }
+ }
+ }
+}
+
+void ScInterpreter::ScMatMult()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatMult" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ {
+ ScMatrixRef pMat2 = GetMatrix();
+ ScMatrixRef pMat1 = GetMatrix();
+ ScMatrixRef pRMat;
+ if (pMat1 && pMat2)
+ {
+ if ( pMat1->IsNumeric() && pMat2->IsNumeric() )
+ {
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ if (nC1 != nR2)
+ PushIllegalArgument();
+ else
+ {
+ pRMat = GetNewMat(nC2, nR1);
+ if (pRMat)
+ {
+ double sum;
+ for (SCSIZE i = 0; i < nR1; i++)
+ {
+ for (SCSIZE j = 0; j < nC2; j++)
+ {
+ sum = 0.0;
+ for (SCSIZE k = 0; k < nC1; k++)
+ {
+ sum += pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k);
+ }
+ pRMat->PutDouble(sum, j, i);
+ }
+ }
+ PushMatrix(pRMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ }
+ else
+ PushNoValue();
+ }
+ else
+ PushIllegalParameter();
+ }
+}
+
+void ScInterpreter::ScMatTrans()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatTrans" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ ScMatrixRef pMat = GetMatrix();
+ ScMatrixRef pRMat;
+ if (pMat)
+ {
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ pRMat = GetNewMat(nR, nC);
+ if ( pRMat )
+ {
+ pMat->MatTrans(*pRMat);
+ PushMatrix(pRMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushIllegalParameter();
+ }
+}
+
+
+/** Minimum extent of one result matrix dimension.
+ For a row or column vector to be replicated the larger matrix dimension is
+ returned, else the smaller dimension.
+ */
+inline SCSIZE lcl_GetMinExtent( SCSIZE n1, SCSIZE n2 )
+{
+ if (n1 == 1)
+ return n2;
+ else if (n2 == 1)
+ return n1;
+ else if (n1 < n2)
+ return n1;
+ else
+ return n2;
+}
+
+template<class _Function>
+ScMatrixRef lcl_MatrixCalculation(const _Function& _pOperation,ScMatrix* pMat1, ScMatrix* pMat2,ScInterpreter* _pIterpreter)
+{
+ SCSIZE nC1, nC2, nMinC;
+ SCSIZE nR1, nR2, nMinR;
+ SCSIZE i, j;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ nMinC = lcl_GetMinExtent( nC1, nC2);
+ nMinR = lcl_GetMinExtent( nR1, nR2);
+ ScMatrixRef xResMat = _pIterpreter->GetNewMat(nMinC, nMinR);
+ if (xResMat)
+ {
+ ScMatrix* pResMat = xResMat;
+ for (i = 0; i < nMinC; i++)
+ {
+ for (j = 0; j < nMinR; j++)
+ {
+ if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
+ {
+ double d = _pOperation(pMat1->GetDouble(i,j),pMat2->GetDouble(i,j));
+ pResMat->PutDouble( d, i, j);
+ }
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, j);
+ }
+ }
+ }
+ return xResMat;
+}
+
+ScMatrixRef ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MatConcat" );
+ SCSIZE nC1, nC2, nMinC;
+ SCSIZE nR1, nR2, nMinR;
+ SCSIZE i, j;
+ pMat1->GetDimensions(nC1, nR1);
+ pMat2->GetDimensions(nC2, nR2);
+ nMinC = lcl_GetMinExtent( nC1, nC2);
+ nMinR = lcl_GetMinExtent( nR1, nR2);
+ ScMatrixRef xResMat = GetNewMat(nMinC, nMinR);
+ if (xResMat)
+ {
+ ScMatrix* pResMat = xResMat;
+ for (i = 0; i < nMinC; i++)
+ {
+ for (j = 0; j < nMinR; j++)
+ {
+ USHORT nErr = pMat1->GetErrorIfNotString( i, j);
+ if (!nErr)
+ nErr = pMat2->GetErrorIfNotString( i, j);
+ if (nErr)
+ pResMat->PutError( nErr, i, j);
+ else
+ {
+ String aTmp( pMat1->GetString( *pFormatter, i, j));
+ aTmp += pMat2->GetString( *pFormatter, i, j);
+ pResMat->PutString( aTmp, i, j);
+ }
+ }
+ }
+ }
+ return xResMat;
+}
+
+
+// fuer DATE, TIME, DATETIME
+void lcl_GetDiffDateTimeFmtType( short& nFuncFmt, short nFmt1, short nFmt2 )
+{
+ if ( nFmt1 != NUMBERFORMAT_UNDEFINED || nFmt2 != NUMBERFORMAT_UNDEFINED )
+ {
+ if ( nFmt1 == nFmt2 )
+ {
+ if ( nFmt1 == NUMBERFORMAT_TIME || nFmt1 == NUMBERFORMAT_DATETIME )
+ nFuncFmt = NUMBERFORMAT_TIME; // Zeiten ergeben Zeit
+ // else: nichts besonderes, Zahl (Datum - Datum := Tage)
+ }
+ else if ( nFmt1 == NUMBERFORMAT_UNDEFINED )
+ nFuncFmt = nFmt2; // z.B. Datum + Tage := Datum
+ else if ( nFmt2 == NUMBERFORMAT_UNDEFINED )
+ nFuncFmt = nFmt1;
+ else
+ {
+ if ( nFmt1 == NUMBERFORMAT_DATE || nFmt2 == NUMBERFORMAT_DATE ||
+ nFmt1 == NUMBERFORMAT_DATETIME || nFmt2 == NUMBERFORMAT_DATETIME )
+ {
+ if ( nFmt1 == NUMBERFORMAT_TIME || nFmt2 == NUMBERFORMAT_TIME )
+ nFuncFmt = NUMBERFORMAT_DATETIME; // Datum + Zeit
+ }
+ }
+ }
+}
+
+
+void ScInterpreter::ScAdd()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAdd" );
+ CalculateAddSub(FALSE);
+}
+void ScInterpreter::CalculateAddSub(BOOL _bSub)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateAddSub" );
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ double fVal1 = 0.0, fVal2 = 0.0;
+ short nFmt1, nFmt2;
+ nFmt1 = nFmt2 = NUMBERFORMAT_UNDEFINED;
+ short nFmtCurrencyType = nCurFmtType;
+ ULONG nFmtCurrencyIndex = nCurFmtIndex;
+ short nFmtPercentType = nCurFmtType;
+ if ( GetStackType() == svMatrix )
+ pMat2 = GetMatrix();
+ else
+ {
+ fVal2 = GetDouble();
+ switch ( nCurFmtType )
+ {
+ case NUMBERFORMAT_DATE :
+ case NUMBERFORMAT_TIME :
+ case NUMBERFORMAT_DATETIME :
+ nFmt2 = nCurFmtType;
+ break;
+ case NUMBERFORMAT_CURRENCY :
+ nFmtCurrencyType = nCurFmtType;
+ nFmtCurrencyIndex = nCurFmtIndex;
+ break;
+ case NUMBERFORMAT_PERCENT :
+ nFmtPercentType = NUMBERFORMAT_PERCENT;
+ break;
+ }
+ }
+ if ( GetStackType() == svMatrix )
+ pMat1 = GetMatrix();
+ else
+ {
+ fVal1 = GetDouble();
+ switch ( nCurFmtType )
+ {
+ case NUMBERFORMAT_DATE :
+ case NUMBERFORMAT_TIME :
+ case NUMBERFORMAT_DATETIME :
+ nFmt1 = nCurFmtType;
+ break;
+ case NUMBERFORMAT_CURRENCY :
+ nFmtCurrencyType = nCurFmtType;
+ nFmtCurrencyIndex = nCurFmtIndex;
+ break;
+ case NUMBERFORMAT_PERCENT :
+ nFmtPercentType = NUMBERFORMAT_PERCENT;
+ break;
+ }
+ }
+ if (pMat1 && pMat2)
+ {
+ ScMatrixRef pResMat;
+ if ( _bSub )
+ {
+ MatrixSub aSub;
+ pResMat = lcl_MatrixCalculation(aSub ,pMat1, pMat2,this);
+ }
+ else
+ {
+ MatrixAdd aAdd;
+ pResMat = lcl_MatrixCalculation(aAdd ,pMat1, pMat2,this);
+ }
+
+ if (!pResMat)
+ PushNoValue();
+ else
+ PushMatrix(pResMat);
+ }
+ else if (pMat1 || pMat2)
+ {
+ double fVal;
+ BOOL bFlag;
+ ScMatrixRef pMat = pMat1;
+ if (!pMat)
+ {
+ fVal = fVal1;
+ pMat = pMat2;
+ bFlag = TRUE; // double - Matrix
+ }
+ else
+ {
+ fVal = fVal2;
+ bFlag = FALSE; // Matrix - double
+ }
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ ScMatrixRef pResMat = GetNewMat(nC, nR);
+ if (pResMat)
+ {
+ SCSIZE nCount = nC * nR;
+ if (bFlag || !_bSub )
+ {
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ {
+ if (pMat->IsValue(i))
+ pResMat->PutDouble( _bSub ? ::rtl::math::approxSub( fVal, pMat->GetDouble(i)) : ::rtl::math::approxAdd( pMat->GetDouble(i), fVal), i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ } // for ( SCSIZE i = 0; i < nCount; i++ )
+ } // if (bFlag || !_bSub )
+ else
+ {
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ { if (pMat->IsValue(i))
+ pResMat->PutDouble( ::rtl::math::approxSub( pMat->GetDouble(i), fVal), i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ } // for ( SCSIZE i = 0; i < nCount; i++ )
+ }
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else if ( _bSub )
+ PushDouble( ::rtl::math::approxSub( fVal1, fVal2 ) );
+ else
+ PushDouble( ::rtl::math::approxAdd( fVal1, fVal2 ) );
+ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY )
+ {
+ nFuncFmtType = nFmtCurrencyType;
+ nFuncFmtIndex = nFmtCurrencyIndex;
+ }
+ else
+ {
+ lcl_GetDiffDateTimeFmtType( nFuncFmtType, nFmt1, nFmt2 );
+ if ( nFmtPercentType == NUMBERFORMAT_PERCENT && nFuncFmtType == NUMBERFORMAT_NUMBER )
+ nFuncFmtType = NUMBERFORMAT_PERCENT;
+ }
+}
+
+void ScInterpreter::ScAmpersand()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAmpersand" );
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ String sStr1, sStr2;
+ if ( GetStackType() == svMatrix )
+ pMat2 = GetMatrix();
+ else
+ sStr2 = GetString();
+ if ( GetStackType() == svMatrix )
+ pMat1 = GetMatrix();
+ else
+ sStr1 = GetString();
+ if (pMat1 && pMat2)
+ {
+ ScMatrixRef pResMat = MatConcat(pMat1, pMat2);
+ if (!pResMat)
+ PushNoValue();
+ else
+ PushMatrix(pResMat);
+ }
+ else if (pMat1 || pMat2)
+ {
+ String sStr;
+ BOOL bFlag;
+ ScMatrixRef pMat = pMat1;
+ if (!pMat)
+ {
+ sStr = sStr1;
+ pMat = pMat2;
+ bFlag = TRUE; // double - Matrix
+ }
+ else
+ {
+ sStr = sStr2;
+ bFlag = FALSE; // Matrix - double
+ }
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ ScMatrixRef pResMat = GetNewMat(nC, nR);
+ if (pResMat)
+ {
+ SCSIZE nCount = nC * nR;
+ if (nGlobalError)
+ {
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ pResMat->PutError( nGlobalError, i);
+ }
+ else if (bFlag)
+ {
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ {
+ USHORT nErr = pMat->GetErrorIfNotString( i);
+ if (nErr)
+ pResMat->PutError( nErr, i);
+ else
+ {
+ String aTmp( sStr);
+ aTmp += pMat->GetString( *pFormatter, i);
+ pResMat->PutString( aTmp, i);
+ }
+ }
+ }
+ else
+ {
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ {
+ USHORT nErr = pMat->GetErrorIfNotString( i);
+ if (nErr)
+ pResMat->PutError( nErr, i);
+ else
+ {
+ String aTmp( pMat->GetString( *pFormatter, i));
+ aTmp += sStr;
+ pResMat->PutString( aTmp, i);
+ }
+ }
+ }
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ {
+ if ( CheckStringResultLen( sStr1, sStr2 ) )
+ sStr1 += sStr2;
+ PushString(sStr1);
+ }
+}
+
+void ScInterpreter::ScSub()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSub" );
+ CalculateAddSub(TRUE);
+}
+
+void ScInterpreter::ScMul()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMul" );
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ double fVal1 = 0.0, fVal2 = 0.0;
+ short nFmtCurrencyType = nCurFmtType;
+ ULONG nFmtCurrencyIndex = nCurFmtIndex;
+ if ( GetStackType() == svMatrix )
+ pMat2 = GetMatrix();
+ else
+ {
+ fVal2 = GetDouble();
+ switch ( nCurFmtType )
+ {
+ case NUMBERFORMAT_CURRENCY :
+ nFmtCurrencyType = nCurFmtType;
+ nFmtCurrencyIndex = nCurFmtIndex;
+ break;
+ }
+ }
+ if ( GetStackType() == svMatrix )
+ pMat1 = GetMatrix();
+ else
+ {
+ fVal1 = GetDouble();
+ switch ( nCurFmtType )
+ {
+ case NUMBERFORMAT_CURRENCY :
+ nFmtCurrencyType = nCurFmtType;
+ nFmtCurrencyIndex = nCurFmtIndex;
+ break;
+ }
+ }
+ if (pMat1 && pMat2)
+ {
+ MatrixMul aMul;
+ ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1, pMat2,this);
+ if (!pResMat)
+ PushNoValue();
+ else
+ PushMatrix(pResMat);
+ }
+ else if (pMat1 || pMat2)
+ {
+ double fVal;
+ ScMatrixRef pMat = pMat1;
+ if (!pMat)
+ {
+ fVal = fVal1;
+ pMat = pMat2;
+ }
+ else
+ fVal = fVal2;
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ ScMatrixRef pResMat = GetNewMat(nC, nR);
+ if (pResMat)
+ {
+ SCSIZE nCount = nC * nR;
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ if (pMat->IsValue(i))
+ pResMat->PutDouble(pMat->GetDouble(i)*fVal, i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushDouble(fVal1 * fVal2);
+ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY )
+ {
+ nFuncFmtType = nFmtCurrencyType;
+ nFuncFmtIndex = nFmtCurrencyIndex;
+ }
+}
+
+void ScInterpreter::ScDiv()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDiv" );
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ double fVal1 = 0.0, fVal2 = 0.0;
+ short nFmtCurrencyType = nCurFmtType;
+ ULONG nFmtCurrencyIndex = nCurFmtIndex;
+ short nFmtCurrencyType2 = NUMBERFORMAT_UNDEFINED;
+ if ( GetStackType() == svMatrix )
+ pMat2 = GetMatrix();
+ else
+ {
+ fVal2 = GetDouble();
+ // hier kein Currency uebernehmen, 123kg/456DM sind nicht DM
+ nFmtCurrencyType2 = nCurFmtType;
+ }
+ if ( GetStackType() == svMatrix )
+ pMat1 = GetMatrix();
+ else
+ {
+ fVal1 = GetDouble();
+ switch ( nCurFmtType )
+ {
+ case NUMBERFORMAT_CURRENCY :
+ nFmtCurrencyType = nCurFmtType;
+ nFmtCurrencyIndex = nCurFmtIndex;
+ break;
+ }
+ }
+ if (pMat1 && pMat2)
+ {
+ MatrixDiv aDiv;
+ ScMatrixRef pResMat = lcl_MatrixCalculation(aDiv,pMat1, pMat2,this);
+ if (!pResMat)
+ PushNoValue();
+ else
+ PushMatrix(pResMat);
+ }
+ else if (pMat1 || pMat2)
+ {
+ double fVal;
+ BOOL bFlag;
+ ScMatrixRef pMat = pMat1;
+ if (!pMat)
+ {
+ fVal = fVal1;
+ pMat = pMat2;
+ bFlag = TRUE; // double - Matrix
+ }
+ else
+ {
+ fVal = fVal2;
+ bFlag = FALSE; // Matrix - double
+ }
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ ScMatrixRef pResMat = GetNewMat(nC, nR);
+ if (pResMat)
+ {
+ SCSIZE nCount = nC * nR;
+ if (bFlag)
+ { for ( SCSIZE i = 0; i < nCount; i++ )
+ if (pMat->IsValue(i))
+ pResMat->PutDouble( div( fVal, pMat->GetDouble(i)), i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ }
+ else
+ { for ( SCSIZE i = 0; i < nCount; i++ )
+ if (pMat->IsValue(i))
+ pResMat->PutDouble( div( pMat->GetDouble(i), fVal), i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ }
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ {
+ PushDouble( div( fVal1, fVal2) );
+ }
+ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY && nFmtCurrencyType2 != NUMBERFORMAT_CURRENCY )
+ { // auch DM/DM ist nicht DM bzw. DEM/EUR nicht DEM
+ nFuncFmtType = nFmtCurrencyType;
+ nFuncFmtIndex = nFmtCurrencyIndex;
+ }
+}
+
+void ScInterpreter::ScPower()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPower" );
+ if ( MustHaveParamCount( GetByte(), 2 ) )
+ ScPow();
+}
+
+void ScInterpreter::ScPow()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPow" );
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ double fVal1 = 0.0, fVal2 = 0.0;
+ if ( GetStackType() == svMatrix )
+ pMat2 = GetMatrix();
+ else
+ fVal2 = GetDouble();
+ if ( GetStackType() == svMatrix )
+ pMat1 = GetMatrix();
+ else
+ fVal1 = GetDouble();
+ if (pMat1 && pMat2)
+ {
+ MatrixPow aPow;
+ ScMatrixRef pResMat = lcl_MatrixCalculation(aPow,pMat1, pMat2,this);
+ if (!pResMat)
+ PushNoValue();
+ else
+ PushMatrix(pResMat);
+ }
+ else if (pMat1 || pMat2)
+ {
+ double fVal;
+ BOOL bFlag;
+ ScMatrixRef pMat = pMat1;
+ if (!pMat)
+ {
+ fVal = fVal1;
+ pMat = pMat2;
+ bFlag = TRUE; // double - Matrix
+ }
+ else
+ {
+ fVal = fVal2;
+ bFlag = FALSE; // Matrix - double
+ }
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ ScMatrixRef pResMat = GetNewMat(nC, nR);
+ if (pResMat)
+ {
+ SCSIZE nCount = nC * nR;
+ if (bFlag)
+ { for ( SCSIZE i = 0; i < nCount; i++ )
+ if (pMat->IsValue(i))
+ pResMat->PutDouble(pow(fVal,pMat->GetDouble(i)), i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ }
+ else
+ { for ( SCSIZE i = 0; i < nCount; i++ )
+ if (pMat->IsValue(i))
+ pResMat->PutDouble(pow(pMat->GetDouble(i),fVal), i);
+ else
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i);
+ }
+ PushMatrix(pResMat);
+ }
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushDouble(pow(fVal1,fVal2));
+}
+
+void ScInterpreter::ScSumProduct()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumProduct" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 1, 30 ) )
+ return;
+
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ ScMatrixRef pMat = NULL;
+ pMat2 = GetMatrix();
+ if (!pMat2)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC, nC1;
+ SCSIZE nR, nR1;
+ pMat2->GetDimensions(nC, nR);
+ pMat = pMat2;
+ MatrixMul aMul;
+ for (USHORT i = 1; i < nParamCount; i++)
+ {
+ pMat1 = GetMatrix();
+ if (!pMat1)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ pMat1->GetDimensions(nC1, nR1);
+ if (nC1 != nC || nR1 != nR)
+ {
+ PushNoValue();
+ return;
+ }
+ ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1, pMat,this);
+ if (!pResMat)
+ {
+ PushNoValue();
+ return;
+ }
+ else
+ pMat = pResMat;
+ }
+ double fSum = 0.0;
+ SCSIZE nCount = pMat->GetElementCount();
+ for (SCSIZE j = 0; j < nCount; j++)
+ {
+ if (!pMat->IsString(j))
+ fSum += pMat->GetDouble(j);
+ }
+ PushDouble(fSum);
+}
+
+void ScInterpreter::ScSumX2MY2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumX2MY2" );
+ CalculateSumX2MY2SumX2DY2(FALSE);
+}
+void ScInterpreter::CalculateSumX2MY2SumX2DY2(BOOL _bSumX2DY2)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSumX2MY2SumX2DY2" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ SCSIZE i, j;
+ pMat2 = GetMatrix();
+ pMat1 = GetMatrix();
+ if (!pMat2 || !pMat1)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat2->GetDimensions(nC2, nR2);
+ pMat1->GetDimensions(nC1, nR1);
+ if (nC1 != nC2 || nR1 != nR2)
+ {
+ PushNoValue();
+ return;
+ }
+ double fVal, fSum = 0.0;
+ for (i = 0; i < nC1; i++)
+ for (j = 0; j < nR1; j++)
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ fVal = pMat1->GetDouble(i,j);
+ fSum += fVal * fVal;
+ fVal = pMat2->GetDouble(i,j);
+ if ( _bSumX2DY2 )
+ fSum += fVal * fVal;
+ else
+ fSum -= fVal * fVal;
+ }
+ PushDouble(fSum);
+}
+
+void ScInterpreter::ScSumX2DY2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumX2DY2" );
+ CalculateSumX2MY2SumX2DY2(TRUE);
+}
+
+void ScInterpreter::ScSumXMY2()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumXMY2" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ ScMatrixRef pMat1 = NULL;
+ ScMatrixRef pMat2 = NULL;
+ pMat2 = GetMatrix();
+ pMat1 = GetMatrix();
+ if (!pMat2 || !pMat1)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ SCSIZE nC1, nC2;
+ SCSIZE nR1, nR2;
+ pMat2->GetDimensions(nC2, nR2);
+ pMat1->GetDimensions(nC1, nR1);
+ if (nC1 != nC2 || nR1 != nR2)
+ {
+ PushNoValue();
+ return;
+ } // if (nC1 != nC2 || nR1 != nR2)
+ MatrixSub aSub;
+ ScMatrixRef pResMat = lcl_MatrixCalculation(aSub,pMat1, pMat2,this);
+ if (!pResMat)
+ {
+ PushNoValue();
+ }
+ else
+ {
+ double fVal, fSum = 0.0;
+ SCSIZE nCount = pResMat->GetElementCount();
+ for (SCSIZE i = 0; i < nCount; i++)
+ if (!pResMat->IsString(i))
+ {
+ fVal = pResMat->GetDouble(i);
+ fSum += fVal * fVal;
+ }
+ PushDouble(fSum);
+ }
+}
+
+void ScInterpreter::ScFrequency()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFrequency" );
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ vector<double> aBinArray;
+ vector<long> aBinIndexOrder;
+
+ GetSortArray(1, aBinArray, &aBinIndexOrder);
+ SCSIZE nBinSize = aBinArray.size();
+ if (nGlobalError)
+ {
+ PushNoValue();
+ return;
+ }
+
+ vector<double> aDataArray;
+ GetSortArray(1, aDataArray);
+ SCSIZE nDataSize = aDataArray.size();
+
+ if (aDataArray.empty() || nGlobalError)
+ {
+ PushNoValue();
+ return;
+ }
+ ScMatrixRef pResMat = GetNewMat(1, nBinSize+1);
+ if (!pResMat)
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ if (nBinSize != aBinIndexOrder.size())
+ {
+ PushIllegalArgument();
+ return;
+ }
+
+ SCSIZE j;
+ SCSIZE i = 0;
+ for (j = 0; j < nBinSize; ++j)
+ {
+ SCSIZE nCount = 0;
+ while (i < nDataSize && aDataArray[i] <= aBinArray[j])
+ {
+ ++nCount;
+ ++i;
+ }
+ pResMat->PutDouble(static_cast<double>(nCount), aBinIndexOrder[j]);
+ }
+ pResMat->PutDouble(static_cast<double>(nDataSize-i), j);
+ PushMatrix(pResMat);
+}
+
+BOOL ScInterpreter::RGetVariances( ScMatrix* pV, ScMatrix* pX,
+ SCSIZE nC, SCSIZE nR, BOOL bSwapColRow, BOOL bZeroConstant )
+{ // multiple Regression: Varianzen der Koeffizienten
+ // bSwapColRow==TRUE : Koeffizienten in Zeilen statt Spalten angeordnet
+ SCSIZE i, j, k;
+ double sum;
+ ScMatrixRef pC = GetNewMat(nC, nC);
+ if ( !pC )
+ return FALSE;
+ // X transformiert mit X multipziert, X'X Matrix
+ if ( !bZeroConstant )
+ { // in der X-Designmatrix existiert ein gedachtes X0j==1
+ if ( bSwapColRow )
+ {
+ for ( i=0; i<nC; i++ )
+ {
+ for ( j=0; j<nC; j++ )
+ {
+ sum = 0.0;
+ for ( k=0; k<nR; k++ )
+ {
+ sum += (j==0 ? 1 : pX->GetDouble(k,j-1))
+ * (i==0 ? 1 : pX->GetDouble(k,i-1));
+ }
+ pC->PutDouble(sum, i, j);
+ }
+ }
+ }
+ else
+ {
+ for ( i=0; i<nC; i++ )
+ {
+ for ( j=0; j<nC; j++ )
+ {
+ sum = 0.0;
+ for ( k=0; k<nR; k++ )
+ {
+ sum += (j==0 ? 1 : pX->GetDouble(j-1,k))
+ * (i==0 ? 1 : pX->GetDouble(i-1,k));
+ }
+ pC->PutDouble(sum, i, j);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( bSwapColRow )
+ {
+ for ( i=0; i<nC; i++ )
+ {
+ for ( j=0; j<nC; j++ )
+ {
+ sum = 0.0;
+ for ( k=0; k<nR; k++ )
+ {
+ sum += pX->GetDouble(k,j) * pX->GetDouble(k,i);
+ }
+ pC->PutDouble(sum, i, j);
+ }
+ }
+ }
+ else
+ {
+ for ( i=0; i<nC; i++ )
+ {
+ for ( j=0; j<nC; j++ )
+ {
+ sum = 0.0;
+ for ( k=0; k<nR; k++ )
+ {
+ sum += pX->GetDouble(j,k) * pX->GetDouble(i,k);
+ }
+ pC->PutDouble(sum, i, j);
+ }
+ }
+ }
+ }
+ // X'X Inverse
+ BOOL bOk = TRUE;
+ USHORT nErr = nGlobalError;
+ PushMatrix(pC);
+ BYTE nTmp = cPar;
+ cPar = 1;
+ ScMatInv();
+ cPar = nTmp;
+ if ( nGlobalError )
+ {
+ nGlobalError = nErr;
+ bOk = FALSE;
+ }
+ else
+ {
+ // #i61216# ScMatInv no longer modifies the original matrix, so just calling Pop() doesn't work
+ pC = PopMatrix();
+ if ( pC.Is() )
+ {
+ // Varianzen auf der Diagonalen, andere sind Kovarianzen
+ for (i = 0; i < nC; i++)
+ pV->PutDouble(pC->GetDouble(i, i), i);
+ }
+ }
+ return bOk;
+}
+// -----------------------------------------------------------------------------
+void ScInterpreter::Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef& pQ,ScMatrixRef& pV,ScMatrixRef& pMatX,BOOL bConstant,SCSIZE N,SCSIZE M,BYTE nCase)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RGetVariances" );
+ // pE[0] := Sigma i=1...n (Yi)
+ // pE[k] := Sigma i=1...n (Xki*Yi)
+ // pE[M+1] := Sigma i=1...n (Yi**2)
+ // pQ[0,M+1]:= B
+ // pQ[k,M+1]:= Mk
+ double fSQR, fSQT, fSQE;
+ fSQT = pE->GetDouble(M+1)
+ - pE->GetDouble(0) * pE->GetDouble(0) / (double)N;
+ fSQR = pE->GetDouble(M+1);
+ SCSIZE i, j;
+ for (i = 0; i < M+1; i++)
+ fSQR -= pQ->GetDouble(i, M+1) * pE->GetDouble(i);
+ fSQE = fSQT-fSQR;
+ // r2 (Bestimmtheitsmass, 0...1)
+ if (fSQT == 0.0)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2);
+ else
+ pResMat->PutDouble (fSQE/fSQT, 0, 2);
+ // ssReg (Regressions-Quadratsumme)
+ pResMat->PutDouble(fSQE, 0, 4);
+ // ssResid (Residual-Quadratsumme, Summe der Abweichungsquadrate)
+ pResMat->PutDouble(fSQR, 1, 4);
+ for (i = 2; i < 5; i++)
+ for (j = 2; j < M+1; j++)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i);
+ if (bConstant)
+ {
+ if (N-M-1 == 0)
+ {
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2);
+ for (i = 0; i < M+1; i++)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1);
+ }
+ else
+ {
+ double fSE2 = fSQR/(N-M-1);
+ // sey (Standardfehler des Schaetzwertes y)
+ pResMat->PutDouble(sqrt(fSE2), 1, 2);
+ // sen...se1 (Standardfehler der Koeffizienten mn...m1)
+ // seb (Standardfehler der Konstanten b)
+ if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, FALSE ) )
+ {
+ for (i = 0; i < M+1; i++)
+ pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 );
+ }
+ else
+ {
+ for (i = 0; i < M+1; i++)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1);
+ }
+ }
+ // F (F-Statistik)
+ if (fSQR == 0.0)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3);
+ else
+ pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3);
+ // df (Freiheitsgrad)
+ pResMat->PutDouble(((double)(N-M-1)), 1, 3);
+ }
+ else
+ {
+ if (N-M == 0)
+ {
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2);
+ for (i = 0; i < M+1; i++)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1);
+ }
+ else
+ {
+ double fSE2 = fSQR/(N-M);
+ pResMat->PutDouble(sqrt(fSE2), 1, 2);
+ if ( RGetVariances( pV, pMatX, M, N, nCase != 2, TRUE ) )
+ {
+ for (i = 0; i < M; i++)
+ pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 );
+ pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1);
+ }
+ else
+ {
+ for (i = 0; i < M+1; i++)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1);
+ }
+ }
+ if (fSQR == 0.0)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3);
+ else
+ pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3);
+ pResMat->PutDouble(((double)(N-M)), 1, 3);
+ }
+}
+
+void ScInterpreter::ScRGP()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRGP" );
+ CalulateRGPRKP(FALSE);
+}
+bool ScInterpreter::CheckMatrix(BOOL _bLOG,BOOL _bTrendGrowth,BYTE& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY)
+{
+ nCX = 0;
+ nCY = 0;
+ nRX = 0;
+ nRY = 0;
+ M = 0;
+ N = 0;
+ pMatY->GetDimensions(nCY, nRY);
+ const SCSIZE nCountY = nCY * nRY;
+ for ( SCSIZE i = 0; i < nCountY; i++ )
+ {
+ if (!pMatY->IsValue(i))
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ }
+
+ if ( _bLOG )
+ {
+ ScMatrixRef pNewY = pMatY->CloneIfConst();
+ for (SCSIZE nElem = 0; nElem < nCountY; nElem++)
+ {
+ const double fVal = pNewY->GetDouble(nElem);
+ if (fVal <= 0.0)
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ else
+ pNewY->PutDouble(log(fVal), nElem);
+ }
+ pMatY = pNewY;
+ }
+
+ if (pMatX)
+ {
+ pMatX->GetDimensions(nCX, nRX);
+ const SCSIZE nCountX = nCX * nRX;
+ for ( SCSIZE i = 0; i < nCountX; i++ )
+ if (!pMatX->IsValue(i))
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ if (nCX == nCY && nRX == nRY)
+ nCase = 1; // einfache Regression
+ else if (nCY != 1 && nRY != 1)
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ else if (nCY == 1)
+ {
+ if (nRX != nRY)
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ else
+ {
+ nCase = 2; // zeilenweise
+ N = nRY;
+ M = nCX;
+ }
+ }
+ else if (nCX != nCY)
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ else
+ {
+ nCase = 3; // spaltenweise
+ N = nCY;
+ M = nRX;
+ }
+ }
+ else
+ {
+ pMatX = GetNewMat(nCY, nRY);
+ if ( _bTrendGrowth )
+ {
+ nCX = nCY;
+ nRX = nRY;
+ }
+ if (!pMatX)
+ {
+ PushIllegalArgument();
+ return false;
+ }
+ for ( SCSIZE i = 1; i <= nCountY; i++ )
+ pMatX->PutDouble((double)i, i-1);
+ nCase = 1;
+ }
+ return true;
+}
+void ScInterpreter::CalulateRGPRKP(BOOL _bRKP)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CheckMatrix" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 1, 4 ) )
+ return;
+ BOOL bConstant, bStats;
+ if (nParamCount == 4)
+ bStats = GetBool();
+ else
+ bStats = FALSE;
+ if (nParamCount >= 3)
+ bConstant = GetBool();
+ else
+ bConstant = TRUE;
+ ScMatrixRef pMatX;
+ ScMatrixRef pMatY;
+ if (nParamCount >= 2)
+ pMatX = GetMatrix();
+ else
+ pMatX = NULL;
+ pMatY = GetMatrix();
+ if (!pMatY)
+ {
+ PushIllegalParameter();
+ return;
+ } // if (!pMatY)
+ BYTE nCase; // 1 = normal, 2,3 = mehrfach
+ SCSIZE nCX, nCY;
+ SCSIZE nRX, nRY;
+ SCSIZE M = 0, N = 0;
+ if ( !CheckMatrix(_bRKP,FALSE,nCase,nCX,nCY,nRX,nRY,M,N,pMatX,pMatY) )
+ return;
+
+ ScMatrixRef pResMat;
+ if (nCase == 1)
+ {
+ if (!bStats)
+ pResMat = GetNewMat(2,1);
+ else
+ pResMat = GetNewMat(2,5);
+ if (!pResMat)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double fCount = 0.0;
+ double fSumX = 0.0;
+ double fSumSqrX = 0.0;
+ double fSumY = 0.0;
+ double fSumSqrY = 0.0;
+ double fSumXY = 0.0;
+ double fValX, fValY;
+ for (SCSIZE i = 0; i < nCY; i++)
+ for (SCSIZE j = 0; j < nRY; j++)
+ {
+ fValX = pMatX->GetDouble(i,j);
+ fValY = pMatY->GetDouble(i,j);
+ fSumX += fValX;
+ fSumSqrX += fValX * fValX;
+ fSumY += fValY;
+ fSumSqrY += fValY * fValY;
+ fSumXY += fValX*fValY;
+ fCount++;
+ }
+ if (fCount < 1.0)
+ PushNoValue();
+ else
+ {
+ double f1 = fCount*fSumXY-fSumX*fSumY;
+ double fX = fCount*fSumSqrX-fSumX*fSumX;
+ double b, m;
+ if (bConstant)
+ {
+ b = fSumY/fCount - f1/fX*fSumX/fCount;
+ m = f1/fX;
+ }
+ else
+ {
+ b = 0.0;
+ m = fSumXY/fSumSqrX;
+ }
+ pResMat->PutDouble(_bRKP ? exp(m) : m, 0, 0);
+ pResMat->PutDouble(_bRKP ? exp(b) : b, 1, 0);
+ if (bStats)
+ {
+ double fY = fCount*fSumSqrY-fSumY*fSumY;
+ double fSyx = fSumSqrY-b*fSumY-m*fSumXY;
+ double fR2 = f1*f1/(fX*fY);
+ pResMat->PutDouble (fR2, 0, 2);
+ if (fCount < 3.0)
+ {
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 1 );
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 1 );
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2 );
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 );
+ }
+ else
+ {
+ pResMat->PutDouble(sqrt(fSyx*fCount/(fX*(fCount-2.0))), 0, 1);
+ pResMat->PutDouble(sqrt(fSyx*fSumSqrX/fX/(fCount-2.0)), 1, 1);
+ pResMat->PutDouble(
+ sqrt((fCount*fSumSqrY - fSumY*fSumY - f1*f1/fX)/
+ (fCount*(fCount-2.0))), 1, 2);
+ if (fR2 == 1.0)
+ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 );
+ else
+ pResMat->PutDouble(fR2*(fCount-2.0)/(1.0-fR2), 0, 3);
+ }
+ pResMat->PutDouble(((double)(nCY*nRY))-2.0, 1, 3);
+ pResMat->PutDouble(fY/fCount-fSyx, 0, 4);
+ pResMat->PutDouble(fSyx, 1, 4);
+ }
+ }
+ } // if (nCase == 1)
+ if ( nCase != 1 )
+ {
+ SCSIZE i, j, k;
+ if (!bStats)
+ pResMat = GetNewMat(M+1,1);
+ else
+ pResMat = GetNewMat(M+1,5);
+ if (!pResMat)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ ScMatrixRef pQ = GetNewMat(M+1, M+2);
+ ScMatrixRef pE = GetNewMat(M+2, 1);
+ ScMatrixRef pV = GetNewMat(M+1, 1);
+ pE->PutDouble(0.0, M+1);
+ pQ->FillDouble(0.0, 0, 0, M, M+1);
+ if (nCase == 2)
+ {
+ for (k = 0; k < N; k++)
+ {
+ double Yk = pMatY->GetDouble(k);
+ pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 );
+ double sumYk = pQ->GetDouble(0, M+1) + Yk;
+ pQ->PutDouble( sumYk, 0, M+1 );
+ pE->PutDouble( sumYk, 0 );
+ for (i = 0; i < M; i++)
+ {
+ double Xik = pMatX->GetDouble(i,k);
+ double sumXik = pQ->GetDouble(0, i+1) + Xik;
+ pQ->PutDouble( sumXik, 0, i+1);
+ pQ->PutDouble( sumXik, i+1, 0);
+ double sumXikYk = pQ->GetDouble(i+1, M+1) + Xik * Yk;
+ pQ->PutDouble( sumXikYk, i+1, M+1);
+ pE->PutDouble( sumXikYk, i+1);
+ for (j = i; j < M; j++)
+ {
+ const double fVal = pMatX->GetDouble(j,k);
+ double sumXikXjk = pQ->GetDouble(j+1, i+1) +
+ Xik * fVal;
+ pQ->PutDouble( sumXikXjk, j+1, i+1);
+ pQ->PutDouble( sumXikXjk, i+1, j+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (k = 0; k < N; k++)
+ {
+ double Yk = pMatY->GetDouble(k);
+ pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 );
+ double sumYk = pQ->GetDouble(0, M+1) + Yk;
+ pQ->PutDouble( sumYk, 0, M+1 );
+ pE->PutDouble( sumYk, 0 );
+ for (i = 0; i < M; i++)
+ {
+ double Xki = pMatX->GetDouble(k,i);
+ double sumXki = pQ->GetDouble(0, i+1) + Xki;
+ pQ->PutDouble( sumXki, 0, i+1);
+ pQ->PutDouble( sumXki, i+1, 0);
+ double sumXkiYk = pQ->GetDouble(i+1, M+1) + Xki * Yk;
+ pQ->PutDouble( sumXkiYk, i+1, M+1);
+ pE->PutDouble( sumXkiYk, i+1);
+ for (j = i; j < M; j++)
+ {
+ const double fVal = pMatX->GetDouble(k,j);
+ double sumXkiXkj = pQ->GetDouble(j+1, i+1) +
+ Xki * fVal;
+ pQ->PutDouble( sumXkiXkj, j+1, i+1);
+ pQ->PutDouble( sumXkiXkj, i+1, j+1);
+ }
+ }
+ }
+ }
+ if ( !Calculate4(_bRKP,pResMat,pQ,bConstant,N,M) )
+ return;
+
+ if (bStats)
+ Calculate(pResMat,pE,pQ,pV,pMatX,bConstant,N,M,nCase);
+ }
+ PushMatrix(pResMat);
+}
+
+void ScInterpreter::ScRKP()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRKP" );
+ CalulateRGPRKP(TRUE);
+}
+// -----------------------------------------------------------------------------
+bool ScInterpreter::Calculate4(BOOL _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,BOOL bConstant,SCSIZE N,SCSIZE M)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate4" );
+ pQ->PutDouble((double)N, 0, 0);
+ if (bConstant)
+ {
+ SCSIZE S, L;
+ for (S = 0; S < M+1; S++)
+ {
+ SCSIZE i = S;
+ while (i < M+1 && pQ->GetDouble(i, S) == 0.0)
+ i++;
+ if (i >= M+1)
+ {
+ PushNoValue();
+ return false;
+ }
+ double fVal;
+ for (L = 0; L < M+2; L++)
+ {
+ fVal = pQ->GetDouble(S, L);
+ pQ->PutDouble(pQ->GetDouble(i, L), S, L);
+ pQ->PutDouble(fVal, i, L);
+ }
+ fVal = 1.0/pQ->GetDouble(S, S);
+ for (L = 0; L < M+2; L++)
+ pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L);
+ for (i = 0; i < M+1; i++)
+ {
+ if (i != S)
+ {
+ fVal = -pQ->GetDouble(i, S);
+ for (L = 0; L < M+2; L++)
+ pQ->PutDouble(
+ pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( !Calculate3(M,pQ) )
+ return false;
+
+ }
+ for (SCSIZE i = 0; i < M+1; i++)
+ {
+ const double d = pQ->GetDouble(M-i,M+1);
+ pResMat->PutDouble(_bExp ? exp(d) : d, i, 0);
+ } // for (SCSIZE i = 0; i < M+1; i++)
+ return true;
+}
+
+ScMatrixRef ScInterpreter::Calculate2(const BOOL bConstant,const SCSIZE M ,const SCSIZE N,ScMatrixRef& pMatX,ScMatrixRef& pMatY,BYTE nCase)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate2" );
+ SCSIZE i, j, k;
+ ScMatrixRef pQ = GetNewMat(M+1, M+2);
+ ScMatrixRef pE = GetNewMat(M+2, 1);
+ pE->PutDouble(0.0, M+1);
+ pQ->FillDouble(0.0, 0, 0, M, M+1);
+ if (nCase == 2)
+ {
+ for (k = 0; k < N; k++)
+ {
+ pE->PutDouble(
+ pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1);
+ pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1);
+ pE->PutDouble(pQ->GetDouble(0, M+1), 0);
+ for (i = 0; i < M; i++)
+ {
+ pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1);
+ pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0);
+ pQ->PutDouble(pQ->GetDouble(i+1, M+1) +
+ pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1);
+ pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1);
+ for (j = i; j < M; j++)
+ {
+ pQ->PutDouble(pQ->GetDouble(j+1, i+1) +
+ pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1);
+ pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (k = 0; k < N; k++)
+ {
+ pE->PutDouble(
+ pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1);
+ pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1);
+ pE->PutDouble(pQ->GetDouble(0, M+1), 0);
+ for (i = 0; i < M; i++)
+ {
+ pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1);
+ pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0);
+ pQ->PutDouble(pQ->GetDouble(i+1, M+1) +
+ pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1);
+ pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1);
+ for (j = i; j < M; j++)
+ {
+ pQ->PutDouble(pQ->GetDouble(j+1, i+1) +
+ pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1);
+ pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1);
+ }
+ }
+ }
+ }
+ pQ->PutDouble((double)N, 0, 0);
+ if (bConstant)
+ {
+ SCSIZE S, L;
+ for (S = 0; S < M+1; S++)
+ {
+ i = S;
+ while (i < M+1 && pQ->GetDouble(i, S) == 0.0)
+ i++;
+ if (i >= M+1)
+ {
+ PushNoValue();
+ return ScMatrixRef();
+ }
+ double fVal;
+ for (L = 0; L < M+2; L++)
+ {
+ fVal = pQ->GetDouble(S, L);
+ pQ->PutDouble(pQ->GetDouble(i, L), S, L);
+ pQ->PutDouble(fVal, i, L);
+ }
+ fVal = 1.0/pQ->GetDouble(S, S);
+ for (L = 0; L < M+2; L++)
+ pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L);
+ for (i = 0; i < M+1; i++)
+ {
+ if (i != S)
+ {
+ fVal = -pQ->GetDouble(i, S);
+ for (L = 0; L < M+2; L++)
+ pQ->PutDouble(
+ pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( !Calculate3(M,pQ) )
+ return ScMatrixRef();
+ }
+ return pQ;
+}
+bool ScInterpreter::Calculate3(const SCSIZE M ,ScMatrixRef& pQ)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate3" );
+ SCSIZE S, L;
+ for (S = 1; S < M+1; S++)
+ {
+ SCSIZE i = S;
+ while (i < M+1 && pQ->GetDouble(i, S) == 0.0)
+ i++;
+ if (i >= M+1)
+ {
+ PushNoValue();
+ return ScMatrixRef();
+ }
+ double fVal;
+ for (L = 1; L < M+2; L++)
+ {
+ fVal = pQ->GetDouble(S, L);
+ pQ->PutDouble(pQ->GetDouble(i, L), S, L);
+ pQ->PutDouble(fVal, i, L);
+ }
+ fVal = 1.0/pQ->GetDouble(S, S);
+ for (L = 1; L < M+2; L++)
+ pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L);
+ for (i = 1; i < M+1; i++)
+ {
+ if (i != S)
+ {
+ fVal = -pQ->GetDouble(i, S);
+ for (L = 1; L < M+2; L++)
+ pQ->PutDouble(
+ pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L);
+ }
+ }
+ pQ->PutDouble(0.0, 0, M+1);
+ } // for (S = 1; S < M+1; S++)
+ return true;
+}
+
+void ScInterpreter::ScTrend()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrend" );
+ CalculateTrendGrowth(FALSE);
+}
+void ScInterpreter::CalculateTrendGrowth(BOOL _bGrowth)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateTrendGrowth" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 1, 4 ) )
+ return;
+ BOOL bConstant;
+ if (nParamCount == 4)
+ bConstant = GetBool();
+ else
+ bConstant = TRUE;
+ ScMatrixRef pMatX;
+ ScMatrixRef pMatY;
+ ScMatrixRef pMatNewX;
+ if (nParamCount >= 3)
+ pMatNewX = GetMatrix();
+ else
+ pMatNewX = NULL;
+ if (nParamCount >= 2)
+ pMatX = GetMatrix();
+ else
+ pMatX = NULL;
+ pMatY = GetMatrix();
+ if (!pMatY)
+ {
+ PushIllegalParameter();
+ return;
+ } // if (!pMatY)
+
+ BYTE nCase; // 1 = normal, 2,3 = mehrfach
+ SCSIZE nCX, nCY;
+ SCSIZE nRX, nRY;
+ SCSIZE M = 0, N = 0;
+ if ( !CheckMatrix(_bGrowth,TRUE,nCase,nCX,nCY,nRX,nRY,M,N,pMatX,pMatY) )
+ return;
+
+
+ SCSIZE nCXN, nRXN;
+ SCSIZE nCountXN;
+ if (!pMatNewX)
+ {
+ nCXN = nCX;
+ nRXN = nRX;
+ nCountXN = nCXN * nRXN;
+ pMatNewX = pMatX;
+ }
+ else
+ {
+ pMatNewX->GetDimensions(nCXN, nRXN);
+ if ((nCase == 2 && nCX != nCXN) || (nCase == 3 && nRX != nRXN))
+ {
+ PushIllegalArgument();
+ return;
+ }
+ nCountXN = nCXN * nRXN;
+ for ( SCSIZE i = 0; i < nCountXN; i++ )
+ if (!pMatNewX->IsValue(i))
+ {
+ PushIllegalArgument();
+ return;
+ }
+ }
+ ScMatrixRef pResMat;
+ if (nCase == 1)
+ {
+ double fCount = 0.0;
+ double fSumX = 0.0;
+ double fSumSqrX = 0.0;
+ double fSumY = 0.0;
+ double fSumSqrY = 0.0;
+ double fSumXY = 0.0;
+ double fValX, fValY;
+ SCSIZE i;
+ for (i = 0; i < nCY; i++)
+ for (SCSIZE j = 0; j < nRY; j++)
+ {
+ fValX = pMatX->GetDouble(i,j);
+ fValY = pMatY->GetDouble(i,j);
+ fSumX += fValX;
+ fSumSqrX += fValX * fValX;
+ fSumY += fValY;
+ fSumSqrY += fValY * fValY;
+ fSumXY += fValX*fValY;
+ fCount++;
+ }
+ if (fCount < 1.0)
+ {
+ PushNoValue();
+ return;
+ }
+ else
+ {
+ double f1 = fCount*fSumXY-fSumX*fSumY;
+ double fX = fCount*fSumSqrX-fSumX*fSumX;
+ double b, m;
+ if (bConstant)
+ {
+ b = fSumY/fCount - f1/fX*fSumX/fCount;
+ m = f1/fX;
+ }
+ else
+ {
+ b = 0.0;
+ m = fSumXY/fSumSqrX;
+ }
+ pResMat = GetNewMat(nCXN, nRXN);
+ if (!pResMat)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ for (i = 0; i < nCountXN; i++)
+ {
+ const double d = pMatNewX->GetDouble(i)*m+b;
+ pResMat->PutDouble(_bGrowth ? exp(d) : d, i);
+ }
+ }
+ }
+ else
+ {
+ ScMatrixRef pQ = Calculate2(bConstant,M ,N,pMatX,pMatY,nCase);
+ if ( !pQ.Is() )
+ return;
+ if (nCase == 2)
+ {
+ pResMat = GetNewMat(1, nRXN);
+ if (!pResMat)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double fVal;
+ for (SCSIZE i = 0; i < nRXN; i++)
+ {
+ fVal = pQ->GetDouble(0, M+1);
+ for (SCSIZE j = 0; j < M; j++)
+ fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(j, i);
+ pResMat->PutDouble(_bGrowth ? exp(fVal) : fVal, i);
+ }
+ }
+ else
+ {
+ pResMat = GetNewMat(nCXN, 1);
+ if (!pResMat)
+ {
+ PushIllegalArgument();
+ return;
+ }
+ double fVal;
+ for (SCSIZE i = 0; i < nCXN; i++)
+ {
+ fVal = pQ->GetDouble(0, M+1);
+ for (SCSIZE j = 0; j < M; j++)
+ fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(i, j);
+ pResMat->PutDouble(_bGrowth ? exp(fVal) : fVal, i);
+ }
+ }
+ }
+ PushMatrix(pResMat);
+}
+
+void ScInterpreter::ScGrowth()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGrowth" );
+ CalculateTrendGrowth(TRUE);
+}
+
+void ScInterpreter::ScMatRef()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatRef" );
+ // Falls Deltarefs drin sind...
+ Push( (FormulaToken&)*pCur );
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScFormulaCell* pCell = (ScFormulaCell*) GetCell( aAdr );
+ if( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ const ScMatrix* pMat = pCell->GetMatrix();
+ if( pMat )
+ {
+ SCSIZE nCols, nRows;
+ pMat->GetDimensions( nCols, nRows );
+ SCSIZE nC = static_cast<SCSIZE>(aPos.Col() - aAdr.Col());
+ SCSIZE nR = static_cast<SCSIZE>(aPos.Row() - aAdr.Row());
+ if ((nCols <= nC && nCols != 1) || (nRows <= nR && nRows != 1))
+ PushNA();
+ else
+ {
+ ScMatValType nMatValType;
+ const ScMatrixValue* pMatVal = pMat->Get( nC, nR, nMatValType);
+ if (ScMatrix::IsNonValueType( nMatValType))
+ {
+ if (ScMatrix::IsEmptyPathType( nMatValType))
+ { // result of empty FALSE jump path
+ nFuncFmtType = NUMBERFORMAT_LOGICAL;
+ PushInt(0);
+ }
+ else if (ScMatrix::IsEmptyType( nMatValType))
+ {
+ // Not inherited (really?) and display as empty string, not 0.
+ PushTempToken( new ScEmptyCellToken( false, true));
+ }
+ else
+ PushString( pMatVal->GetString() );
+ }
+ else
+ {
+ PushDouble(pMatVal->fVal); // handles DoubleError
+ pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex, aAdr, pCell );
+ nFuncFmtType = nCurFmtType;
+ nFuncFmtIndex = nCurFmtIndex;
+ }
+ }
+ }
+ else
+ {
+ // If not a result matrix, obtain the cell value.
+ USHORT nErr = pCell->GetErrCode();
+ if (nErr)
+ PushError( nErr );
+ else if( pCell->IsValue() )
+ PushDouble( pCell->GetValue() );
+ else
+ {
+ String aVal;
+ pCell->GetString( aVal );
+ PushString( aVal );
+ }
+ pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex, aAdr, pCell );
+ nFuncFmtType = nCurFmtType;
+ nFuncFmtIndex = nCurFmtIndex;
+ }
+ }
+ else
+ PushError( errNoRef );
+}
+
+void ScInterpreter::ScInfo()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScInfo" );
+ if( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ String aStr = GetString();
+ ScCellKeywordTranslator::transKeyword(aStr, ScGlobal::GetLocale(), ocInfo);
+ if( aStr.EqualsAscii( "SYSTEM" ) )
+ PushString( String( RTL_CONSTASCII_USTRINGPARAM( SC_INFO_OSVERSION ) ) );
+ else if( aStr.EqualsAscii( "OSVERSION" ) )
+ PushString( String( RTL_CONSTASCII_USTRINGPARAM( "Windows (32-bit) NT 5.01" ) ) );
+ else if( aStr.EqualsAscii( "RELEASE" ) )
+ PushString( ::utl::Bootstrap::getBuildIdData( ::rtl::OUString() ) );
+ else if( aStr.EqualsAscii( "NUMFILE" ) )
+ PushDouble( 1 );
+ else if( aStr.EqualsAscii( "RECALC" ) )
+ PushString( ScGlobal::GetRscString( pDok->GetAutoCalc() ? STR_RECALC_AUTO : STR_RECALC_MANUAL ) );
+ else
+ PushIllegalArgument();
+ }
+}
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
new file mode 100644
index 000000000000..1e3a9a292f16
--- /dev/null
+++ b/sc/source/core/tool/interpr6.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// #include <math.h>
+
+#include <tools/debug.hxx>
+#include <rtl/logfile.hxx>
+#include "interpre.hxx"
+
+double const fHalfMachEps = 0.5 * ::std::numeric_limits<double>::epsilon();
+
+// The idea how this group of gamma functions is calculated, is
+// based on the Cephes library
+// online http://www.moshier.net/#Cephes [called 2008-02]
+
+/** You must ensure fA>0.0 && fX>0.0
+ valid results only if fX > fA+1.0
+ uses continued fraction with odd items */
+double ScInterpreter::GetGammaContFraction( double fA, double fX )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaContFraction" );
+
+ double const fBigInv = ::std::numeric_limits<double>::epsilon();
+ double const fBig = 1.0/fBigInv;
+ double fCount = 0.0;
+ double fNum = 0.0; // dummy value
+ double fY = 1.0 - fA;
+ double fDenom = fX + 2.0-fA;
+ double fPk = 0.0; // dummy value
+ double fPkm1 = fX + 1.0;
+ double fPkm2 = 1.0;
+ double fQk = 1.0; // dummy value
+ double fQkm1 = fDenom * fX;
+ double fQkm2 = fX;
+ double fApprox = fPkm1/fQkm1;
+ bool bFinished = false;
+ double fR = 0.0; // dummy value
+ do
+ {
+ fCount = fCount +1.0;
+ fY = fY+ 1.0;
+ fNum = fY * fCount;
+ fDenom = fDenom +2.0;
+ fPk = fPkm1 * fDenom - fPkm2 * fNum;
+ fQk = fQkm1 * fDenom - fQkm2 * fNum;
+ if (fQk != 0.0)
+ {
+ fR = fPk/fQk;
+ bFinished = (fabs( (fApprox - fR)/fR ) <= fHalfMachEps);
+ fApprox = fR;
+ }
+ fPkm2 = fPkm1;
+ fPkm1 = fPk;
+ fQkm2 = fQkm1;
+ fQkm1 = fQk;
+ if (fabs(fPk) > fBig)
+ {
+ // reduce a fraction does not change the value
+ fPkm2 = fPkm2 * fBigInv;
+ fPkm1 = fPkm1 * fBigInv;
+ fQkm2 = fQkm2 * fBigInv;
+ fQkm1 = fQkm1 * fBigInv;
+ }
+ } while (!bFinished && fCount<10000);
+ // most iterations, if fX==fAlpha+1.0; approx sqrt(fAlpha) iterations then
+ if (!bFinished)
+ {
+ SetError(errNoConvergence);
+ }
+ return fApprox;
+}
+
+/** You must ensure fA>0.0 && fX>0.0
+ valid results only if fX <= fA+1.0
+ uses power series */
+double ScInterpreter::GetGammaSeries( double fA, double fX )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaSeries" );
+ double fDenomfactor = fA;
+ double fSummand = 1.0/fA;
+ double fSum = fSummand;
+ int nCount=1;
+ do
+ {
+ fDenomfactor = fDenomfactor + 1.0;
+ fSummand = fSummand * fX/fDenomfactor;
+ fSum = fSum + fSummand;
+ nCount = nCount+1;
+ } while ( fSummand/fSum > fHalfMachEps && nCount<=10000);
+ // large amount of iterations will be carried out for huge fAlpha, even
+ // if fX <= fAlpha+1.0
+ if (nCount>10000)
+ {
+ SetError(errNoConvergence);
+ }
+ return fSum;
+}
+
+/** You must ensure fA>0.0 && fX>0.0) */
+double ScInterpreter::GetLowRegIGamma( double fA, double fX )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetLowRegIGamma" );
+ double fLnFactor = fA * log(fX) - fX - GetLogGamma(fA);
+ double fFactor = exp(fLnFactor); // Do we need more accuracy than exp(ln()) has?
+ if (fX>fA+1.0) // includes fX>1.0; 1-GetUpRegIGamma, continued fraction
+ return 1.0 - fFactor * GetGammaContFraction(fA,fX);
+ else // fX<=1.0 || fX<=fA+1.0, series
+ return fFactor * GetGammaSeries(fA,fX);
+}
+
+/** You must ensure fA>0.0 && fX>0.0) */
+double ScInterpreter::GetUpRegIGamma( double fA, double fX )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetUpRegIGamma" );
+
+ double fLnFactor= fA*log(fX)-fX-GetLogGamma(fA);
+ double fFactor = exp(fLnFactor); //Do I need more accuracy than exp(ln()) has?;
+ if (fX>fA+1.0) // includes fX>1.0
+ return fFactor * GetGammaContFraction(fA,fX);
+ else //fX<=1 || fX<=fA+1, 1-GetLowRegIGamma, series
+ return 1.0 -fFactor * GetGammaSeries(fA,fX);
+}
+
+/** Gamma distribution, probability density function.
+ fLambda is "scale" parameter
+ You must ensure fAlpha>0.0 and fLambda>0.0 */
+double ScInterpreter::GetGammaDistPDF( double fX, double fAlpha, double fLambda )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaDistPDF" );
+ if (fX <= 0.0)
+ return 0.0; // see ODFF
+ else
+ {
+ double fXr = fX / fLambda;
+ // use exp(ln()) only for large arguments because of less accuracy
+ if (fXr > 1.0)
+ {
+ const double fLogDblMax = log( ::std::numeric_limits<double>::max());
+ if (log(fXr) * (fAlpha-1.0) < fLogDblMax && fAlpha < fMaxGammaArgument)
+ {
+ return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda / GetGamma(fAlpha);
+ }
+ else
+ {
+ return exp( (fAlpha-1.0) * log(fXr) - fXr - log(fLambda) - GetLogGamma(fAlpha));
+ }
+ }
+ else // fXr near to zero
+ {
+ if (fAlpha<fMaxGammaArgument)
+ {
+ return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda / GetGamma(fAlpha);
+ }
+ else
+ {
+ return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda / exp( GetLogGamma(fAlpha));
+ }
+ }
+ }
+}
+
+/** Gamma distribution, cumulative distribution function.
+ fLambda is "scale" parameter
+ You must ensure fAlpha>0.0 and fLambda>0.0 */
+double ScInterpreter::GetGammaDist( double fX, double fAlpha, double fLambda )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaDist" );
+ if (fX <= 0.0)
+ return 0.0;
+ else
+ return GetLowRegIGamma( fAlpha, fX / fLambda);
+}
diff --git a/sc/source/core/tool/lookupcache.cxx b/sc/source/core/tool/lookupcache.cxx
new file mode 100644
index 000000000000..3ba66011d0e4
--- /dev/null
+++ b/sc/source/core/tool/lookupcache.cxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "lookupcache.hxx"
+#include "document.hxx"
+
+#ifdef erDEBUG
+#include <cstdio>
+using ::std::fprintf;
+static long nCacheCount = 0;
+#endif
+
+
+ScLookupCache::ScLookupCache( ScDocument * pDoc, const ScRange & rRange ) :
+ maRange( rRange),
+ mpDoc( pDoc)
+{
+#ifdef erDEBUG
+ ++nCacheCount;
+ fprintf( stderr, "\nctor ScLookupCache %ld: %d, %d, %d, %d, %d, %d; buckets: %lu, size: %lu\n",
+ nCacheCount,
+ (int)getRange().aStart.Col(), (int)getRange().aStart.Row(),
+ (int)getRange().aStart.Tab(), (int)getRange().aEnd.Col(),
+ (int)getRange().aEnd.Row(), (int)getRange().aEnd.Tab(),
+ (unsigned long)maQueryMap.bucket_count(), (unsigned long)maQueryMap.size());
+#endif
+}
+
+
+ScLookupCache::~ScLookupCache()
+{
+#ifdef erDEBUG
+ fprintf( stderr, "\ndtor ScLookupCache %ld: %d, %d, %d, %d, %d, %d; buckets: %lu, size: %lu\n",
+ nCacheCount,
+ (int)getRange().aStart.Col(), (int)getRange().aStart.Row(),
+ (int)getRange().aStart.Tab(), (int)getRange().aEnd.Col(),
+ (int)getRange().aEnd.Row(), (int)getRange().aEnd.Tab(),
+ (unsigned long)maQueryMap.bucket_count(), (unsigned long)maQueryMap.size());
+ --nCacheCount;
+#endif
+}
+
+
+ScLookupCache::Result ScLookupCache::lookup( ScAddress & o_rResultAddress,
+ const QueryCriteria & rCriteria, const ScAddress & rQueryAddress ) const
+{
+ QueryMap::const_iterator it( maQueryMap.find( QueryKey( rQueryAddress,
+ rCriteria.getQueryOp())));
+ if (it == maQueryMap.end())
+ return NOT_CACHED;
+ const QueryCriteriaAndResult& rResult = (*it).second;
+ if (!(rResult.maCriteria == rCriteria))
+ return CRITERIA_DIFFERENT;
+ if (rResult.maAddress.Row() < 0 )
+ return NOT_AVAILABLE;
+ o_rResultAddress = rResult.maAddress;
+ return FOUND;
+}
+
+
+bool ScLookupCache::insert( const ScAddress & rResultAddress,
+ const QueryCriteria & rCriteria, const ScAddress & rQueryAddress,
+ const bool bAvailable )
+{
+#ifdef erDEBUG
+ size_t nBuckets = maQueryMap.bucket_count();
+#endif
+ QueryKey aKey( rQueryAddress, rCriteria.getQueryOp());
+ QueryCriteriaAndResult aResult( rCriteria, rResultAddress);
+ if (!bAvailable)
+ aResult.maAddress.SetRow(-1);
+ bool bInserted = maQueryMap.insert( ::std::pair< const QueryKey,
+ QueryCriteriaAndResult>( aKey, aResult)).second;
+#ifdef erDEBUG
+ if (nBuckets != maQueryMap.bucket_count())
+ {
+ fprintf( stderr, "\nbuck ScLookupCache: %d, %d, %d, %d, %d, %d; buckets: %lu, size: %lu\n",
+ (int)getRange().aStart.Col(), (int)getRange().aStart.Row(),
+ (int)getRange().aStart.Tab(), (int)getRange().aEnd.Col(),
+ (int)getRange().aEnd.Row(), (int)getRange().aEnd.Tab(),
+ (unsigned long)maQueryMap.bucket_count(), (unsigned long)maQueryMap.size());
+ }
+#endif
+ return bInserted;
+}
+
+
+void ScLookupCache::Notify( SvtBroadcaster & /* rBC */ , const SfxHint & rHint )
+{
+ if (!mpDoc->IsInDtorClear())
+ {
+ const ScHint* p = PTR_CAST( ScHint, &rHint );
+ if (p && (p->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)))
+ {
+ mpDoc->RemoveLookupCache( *this);
+ delete this;
+ }
+ }
+}
diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk
new file mode 100644
index 000000000000..c0258e6f0575
--- /dev/null
+++ b/sc/source/core/tool/makefile.mk
@@ -0,0 +1,167 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=tool
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=core_pch
+PROJECTPCHSOURCE=..\pch\core_pch
+
+AUTOSEG=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/addincfg.obj \
+ $(SLO)$/addincol.obj \
+ $(SLO)$/addinhelpid.obj \
+ $(SLO)$/addinlis.obj \
+ $(SLO)$/address.obj \
+ $(SLO)$/adiasync.obj \
+ $(SLO)$/appoptio.obj \
+ $(SLO)$/autoform.obj \
+ $(SLO)$/callform.obj \
+ $(SLO)$/cellform.obj \
+ $(SLO)$/cellkeytranslator.obj \
+ $(SLO)$/charthelper.obj \
+ $(SLO)$/chartarr.obj \
+ $(SLO)$/chartpos.obj \
+ $(SLO)$/chartlis.obj \
+ $(SLO)$/chartlock.obj \
+ $(SLO)$/chgtrack.obj \
+ $(SLO)$/chgviset.obj \
+ $(SLO)$/collect.obj \
+ $(SLO)$/compiler.obj \
+ $(SLO)$/consoli.obj \
+ $(SLO)$/dbcolect.obj \
+ $(SLO)$/ddelink.obj \
+ $(SLO)$/detdata.obj \
+ $(SLO)$/detfunc.obj \
+ $(SLO)$/docoptio.obj \
+ $(SLO)$/doubleref.obj \
+ $(SLO)$/editutil.obj \
+ $(SLO)$/filtopt.obj \
+ $(SLO)$/formulaparserpool.obj \
+ $(SLO)$/hints.obj \
+ $(SLO)$/inputopt.obj \
+ $(SLO)$/interpr1.obj \
+ $(SLO)$/interpr2.obj \
+ $(SLO)$/interpr3.obj \
+ $(SLO)$/interpr4.obj \
+ $(SLO)$/interpr5.obj \
+ $(SLO)$/interpr6.obj \
+ $(SLO)$/lookupcache.obj \
+ $(SLO)$/navicfg.obj \
+ $(SLO)$/odffmap.obj \
+ $(SLO)$/optutil.obj \
+ $(SLO)$/parclass.obj \
+ $(SLO)$/printopt.obj \
+ $(SLO)$/prnsave.obj \
+ $(SLO)$/progress.obj \
+ $(SLO)$/queryparam.obj \
+ $(SLO)$/rangelst.obj \
+ $(SLO)$/rangenam.obj \
+ $(SLO)$/rangeseq.obj \
+ $(SLO)$/rangeutl.obj \
+ $(SLO)$/rechead.obj \
+ $(SLO)$/refdata.obj \
+ $(SLO)$/reffind.obj \
+ $(SLO)$/refreshtimer.obj \
+ $(SLO)$/reftokenhelper.obj \
+ $(SLO)$/refupdat.obj \
+ $(SLO)$/scmatrix.obj \
+ $(SLO)$/stringutil.obj \
+ $(SLO)$/subtotal.obj \
+ $(SLO)$/token.obj \
+ $(SLO)$/unitconv.obj \
+ $(SLO)$/userlist.obj \
+ $(SLO)$/viewopti.obj \
+ $(SLO)$/zforauto.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/addincol.obj \
+ $(SLO)$/cellkeytranslator.obj \
+ $(SLO)$/charthelper.obj \
+ $(SLO)$/chartarr.obj \
+ $(SLO)$/chartlis.obj \
+ $(SLO)$/chartlock.obj \
+ $(SLO)$/chgtrack.obj \
+ $(SLO)$/compiler.obj \
+ $(SLO)$/doubleref.obj \
+ $(SLO)$/formulaparserpool.obj \
+ $(SLO)$/interpr1.obj \
+ $(SLO)$/interpr2.obj \
+ $(SLO)$/interpr3.obj \
+ $(SLO)$/interpr4.obj \
+ $(SLO)$/interpr5.obj \
+ $(SLO)$/lookupcache.obj \
+ $(SLO)$/prnsave.obj \
+ $(SLO)$/queryparam.obj \
+ $(SLO)$/reftokenhelper.obj \
+ $(SLO)$/stringutil.obj \
+ $(SLO)$/token.obj
+
+# [kh] POWERPC compiler problem
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCPOWERPC"
+NOOPTFILES= \
+ $(SLO)$/subtotal.obj
+.ENDIF
+
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
+NOOPTFILES= \
+ $(SLO)$/interpr2.obj \
+ $(SLO)$/interpr4.obj \
+ $(SLO)$/token.obj \
+ $(SLO)$/chartarr.obj
+.ENDIF
+
+.IF "$(GUI)"=="OS2"
+NOOPTFILES= \
+ $(SLO)$/interpr6.obj
+.ENDIF
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# avoid quotung problems
+$(INCCOM)$/osversiondef.hxx :
+ @@-$(RM) $@
+ @$(TYPE) $(mktmp #define SC_INFO_OSVERSION "$(OS)") > $@
+
+$(SLO)$/interpr5.obj : $(INCCOM)$/osversiondef.hxx
+
diff --git a/sc/source/core/tool/navicfg.cxx b/sc/source/core/tool/navicfg.cxx
new file mode 100644
index 000000000000..0991071774ed
--- /dev/null
+++ b/sc/source/core/tool/navicfg.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "navicfg.hxx"
+
+//------------------------------------------------------------------
+
+//! #define CFGPATH_NAVIPI "Office.Calc/Navigator"
+
+//------------------------------------------------------------------
+
+ScNavipiCfg::ScNavipiCfg() :
+//! ConfigItem( OUString::createFromAscii( CFGPATH_NAVIPI ) ),
+ nListMode(0),
+ nDragMode(0),
+ nRootType(0)
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScNavipiCfg::SetListMode(USHORT nNew)
+{
+ if ( nListMode != nNew )
+ {
+ nListMode = nNew;
+//! SetModified();
+ }
+}
+
+void ScNavipiCfg::SetDragMode(USHORT nNew)
+{
+ if ( nDragMode != nNew )
+ {
+ nDragMode = nNew;
+//! SetModified();
+ }
+}
+
+void ScNavipiCfg::SetRootType(USHORT nNew)
+{
+ if ( nRootType != nNew )
+ {
+ nRootType = nNew;
+//! SetModified();
+ }
+}
+
+
diff --git a/sc/source/core/tool/odffmap.cxx b/sc/source/core/tool/odffmap.cxx
new file mode 100644
index 000000000000..0ffaa4aae025
--- /dev/null
+++ b/sc/source/core/tool/odffmap.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "compiler.hxx"
+
+// ODFF, English, Programmatical, ODF_11
+ScCompiler::AddInMap ScCompiler::maAddInMap[] =
+{
+ { "ORG.OPENOFFICE.WEEKS", "WEEKS", false, "com.sun.star.sheet.addin.DateFunctions.getDiffWeeks", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDIFFWEEKS" },
+ { "ORG.OPENOFFICE.MONTHS", "MONTHS", false, "com.sun.star.sheet.addin.DateFunctions.getDiffMonths", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDIFFMONTHS" },
+ { "ORG.OPENOFFICE.YEARS", "YEARS", false, "com.sun.star.sheet.addin.DateFunctions.getDiffYears", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDIFFYEARS" },
+ { "ORG.OPENOFFICE.ISLEAPYEAR", "ISLEAPYEAR", false, "com.sun.star.sheet.addin.DateFunctions.getIsLeapYear", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETISLEAPYEAR" },
+ { "ORG.OPENOFFICE.DAYSINMONTH", "DAYSINMONTH", false, "com.sun.star.sheet.addin.DateFunctions.getDaysInMonth", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDAYSINMONTH" },
+ { "ORG.OPENOFFICE.DAYSINYEAR", "DAYSINYEAR", false, "com.sun.star.sheet.addin.DateFunctions.getDaysInYear", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDAYSINYEAR" },
+ { "ORG.OPENOFFICE.WEEKSINYEAR", "WEEKSINYEAR", false, "com.sun.star.sheet.addin.DateFunctions.getWeeksInYear", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETWEEKSINYEAR" },
+ { "ORG.OPENOFFICE.ROT13", "ROT13", false, "com.sun.star.sheet.addin.DateFunctions.getRot13", "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETROT13" },
+ { "WORKDAY", "WORKDAY", false, "com.sun.star.sheet.addin.Analysis.getWorkday", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWORKDAY" },
+ { "YEARFRAC", "YEARFRAC", false, "com.sun.star.sheet.addin.Analysis.getYearfrac", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETYEARFRAC" },
+ { "EDATE", "EDATE", false, "com.sun.star.sheet.addin.Analysis.getEdate", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEDATE" },
+ { "WEEKNUM", "WEEKNUM_ADD", false, "com.sun.star.sheet.addin.Analysis.getWeeknum", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWEEKNUM" },
+ { "EOMONTH", "EOMONTH", false, "com.sun.star.sheet.addin.Analysis.getEomonth", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEOMONTH" },
+ { "NETWORKDAYS", "NETWORKDAYS", false, "com.sun.star.sheet.addin.Analysis.getNetworkdays", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETNETWORKDAYS" },
+ { "ISEVEN", "ISEVEN_ADD", true, "com.sun.star.sheet.addin.Analysis.getIseven", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETISEVEN" },
+ { "ISODD", "ISODD_ADD", true, "com.sun.star.sheet.addin.Analysis.getIsodd", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETISODD" },
+ { "MULTINOMIAL", "MULTINOMIAL", false, "com.sun.star.sheet.addin.Analysis.getMultinomial", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETMULTINOMIAL" },
+ { "SERIESSUM", "SERIESSUM", false, "com.sun.star.sheet.addin.Analysis.getSeriessum", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETSERIESSUM" },
+ { "QUOTIENT", "QUOTIENT", false, "com.sun.star.sheet.addin.Analysis.getQuotient", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETQUOTIENT" },
+ { "MROUND", "MROUND", false, "com.sun.star.sheet.addin.Analysis.getMround", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETMROUND" },
+ { "SQRTPI", "SQRTPI", false, "com.sun.star.sheet.addin.Analysis.getSqrtpi", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETSQRTPI" },
+ { "RANDBETWEEN", "RANDBETWEEN", false, "com.sun.star.sheet.addin.Analysis.getRandbetween", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETRANDBETWEEN" },
+ { "GCD", "GCD_ADD", true, "com.sun.star.sheet.addin.Analysis.getGcd", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETGCD" },
+ { "LCM", "LCM_ADD", true, "com.sun.star.sheet.addin.Analysis.getLcm", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETLCM" },
+ { "BESSELI", "BESSELI", false, "com.sun.star.sheet.addin.Analysis.getBesseli", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBESSELI" },
+ { "BESSELJ", "BESSELJ", false, "com.sun.star.sheet.addin.Analysis.getBesselj", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBESSELJ" },
+ { "BESSELK", "BESSELK", false, "com.sun.star.sheet.addin.Analysis.getBesselk", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBESSELK" },
+ { "BESSELY", "BESSELY", false, "com.sun.star.sheet.addin.Analysis.getBessely", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBESSELY" },
+ { "BIN2OCT", "BIN2OCT", false, "com.sun.star.sheet.addin.Analysis.getBin2Oct", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBIN2OCT" },
+ { "BIN2DEC", "BIN2DEC", false, "com.sun.star.sheet.addin.Analysis.getBin2Dec", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBIN2DEC" },
+ { "BIN2HEX", "BIN2HEX", false, "com.sun.star.sheet.addin.Analysis.getBin2Hex", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETBIN2HEX" },
+ { "OCT2BIN", "OCT2BIN", false, "com.sun.star.sheet.addin.Analysis.getOct2Bin", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETOCT2BIN" },
+ { "OCT2DEC", "OCT2DEC", false, "com.sun.star.sheet.addin.Analysis.getOct2Dec", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETOCT2DEC" },
+ { "OCT2HEX", "OCT2HEX", false, "com.sun.star.sheet.addin.Analysis.getOct2Hex", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETOCT2HEX" },
+ { "DEC2BIN", "DEC2BIN", false, "com.sun.star.sheet.addin.Analysis.getDec2Bin", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDEC2BIN" },
+ { "DEC2OCT", "DEC2OCT", false, "com.sun.star.sheet.addin.Analysis.getDec2Oct", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDEC2OCT" },
+ { "DEC2HEX", "DEC2HEX", false, "com.sun.star.sheet.addin.Analysis.getDec2Hex", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDEC2HEX" },
+ { "HEX2BIN", "HEX2BIN", false, "com.sun.star.sheet.addin.Analysis.getHex2Bin", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETHEX2BIN" },
+ { "HEX2DEC", "HEX2DEC", false, "com.sun.star.sheet.addin.Analysis.getHex2Dec", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETHEX2DEC" },
+ { "HEX2OCT", "HEX2OCT", false, "com.sun.star.sheet.addin.Analysis.getHex2Oct", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETHEX2OCT" },
+ { "DELTA", "DELTA", false, "com.sun.star.sheet.addin.Analysis.getDelta", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDELTA" },
+ { "ERF", "ERF", false, "com.sun.star.sheet.addin.Analysis.getErf", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETERF" },
+ { "ERFC", "ERFC", false, "com.sun.star.sheet.addin.Analysis.getErfc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETERFC" },
+ { "GESTEP", "GESTEP", false, "com.sun.star.sheet.addin.Analysis.getGestep", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETGESTEP" },
+ { "FACTDOUBLE", "FACTDOUBLE", false, "com.sun.star.sheet.addin.Analysis.getFactdouble", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETFACTDOUBLE" },
+ { "IMABS", "IMABS", false, "com.sun.star.sheet.addin.Analysis.getImabs", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMABS" },
+ { "IMAGINARY", "IMAGINARY", false, "com.sun.star.sheet.addin.Analysis.getImaginary", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMAGINARY" },
+ { "IMPOWER", "IMPOWER", false, "com.sun.star.sheet.addin.Analysis.getImpower", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMPOWER" },
+ { "IMARGUMENT", "IMARGUMENT", false, "com.sun.star.sheet.addin.Analysis.getImargument", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMARGUMENT" },
+ { "IMCOS", "IMCOS", false, "com.sun.star.sheet.addin.Analysis.getImcos", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMCOS" },
+ { "IMDIV", "IMDIV", false, "com.sun.star.sheet.addin.Analysis.getImdiv", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMDIV" },
+ { "IMEXP", "IMEXP", false, "com.sun.star.sheet.addin.Analysis.getImexp", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMEXP" },
+ { "IMCONJUGATE", "IMCONJUGATE", false, "com.sun.star.sheet.addin.Analysis.getImconjugate", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMCONJUGATE" },
+ { "IMLN", "IMLN", false, "com.sun.star.sheet.addin.Analysis.getImln", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMLN" },
+ { "IMLOG10", "IMLOG10", false, "com.sun.star.sheet.addin.Analysis.getImlog10", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMLOG10" },
+ { "IMLOG2", "IMLOG2", false, "com.sun.star.sheet.addin.Analysis.getImlog2", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMLOG2" },
+ { "IMPRODUCT", "IMPRODUCT", false, "com.sun.star.sheet.addin.Analysis.getImproduct", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMPRODUCT" },
+ { "IMREAL", "IMREAL", false, "com.sun.star.sheet.addin.Analysis.getImreal", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMREAL" },
+ { "IMSIN", "IMSIN", false, "com.sun.star.sheet.addin.Analysis.getImsin", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMSIN" },
+ { "IMSUB", "IMSUB", false, "com.sun.star.sheet.addin.Analysis.getImsub", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMSUB" },
+ { "IMSUM", "IMSUM", false, "com.sun.star.sheet.addin.Analysis.getImsum", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMSUM" },
+ { "IMSQRT", "IMSQRT", false, "com.sun.star.sheet.addin.Analysis.getImsqrt", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETIMSQRT" },
+ { "COMPLEX", "COMPLEX", false, "com.sun.star.sheet.addin.Analysis.getComplex", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOMPLEX" },
+ { "CONVERT", "CONVERT_ADD", false, "com.sun.star.sheet.addin.Analysis.getConvert", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCONVERT" },
+ { "AMORDEGRC", "AMORDEGRC", false, "com.sun.star.sheet.addin.Analysis.getAmordegrc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETAMORDEGRC" },
+ { "AMORLINC", "AMORLINC", false, "com.sun.star.sheet.addin.Analysis.getAmorlinc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETAMORLINC" },
+ { "ACCRINT", "ACCRINT", false, "com.sun.star.sheet.addin.Analysis.getAccrint", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETACCRINT" },
+ { "ACCRINTM", "ACCRINTM", false, "com.sun.star.sheet.addin.Analysis.getAccrintm", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETACCRINTM" },
+ { "RECEIVED", "RECEIVED", false, "com.sun.star.sheet.addin.Analysis.getReceived", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETRECEIVED" },
+ { "DISC", "DISC", false, "com.sun.star.sheet.addin.Analysis.getDisc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDISC" },
+ { "DURATION", "DURATION_ADD", false, "com.sun.star.sheet.addin.Analysis.getDuration", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDURATION" },
+ { "EFFECT", "EFFECT_ADD", true, "com.sun.star.sheet.addin.Analysis.getEffect", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEFFECT" },
+ { "CUMPRINC", "CUMPRINC_ADD", true, "com.sun.star.sheet.addin.Analysis.getCumprinc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCUMPRINC" },
+ { "CUMIPMT", "CUMIPMT_ADD", true, "com.sun.star.sheet.addin.Analysis.getCumipmt", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCUMIPMT" },
+ { "PRICE", "PRICE", false, "com.sun.star.sheet.addin.Analysis.getPrice", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETPRICE" },
+ { "PRICEDISC", "PRICEDISC", false, "com.sun.star.sheet.addin.Analysis.getPricedisc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETPRICEDISC" },
+ { "PRICEMAT", "PRICEMAT", false, "com.sun.star.sheet.addin.Analysis.getPricemat", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETPRICEMAT" },
+ { "MDURATION", "MDURATION", false, "com.sun.star.sheet.addin.Analysis.getMduration", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETMDURATION" },
+ { "NOMINAL", "NOMINAL_ADD", true, "com.sun.star.sheet.addin.Analysis.getNominal", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETNOMINAL" },
+ { "DOLLARFR", "DOLLARFR", false, "com.sun.star.sheet.addin.Analysis.getDollarfr", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDOLLARFR" },
+ { "DOLLARDE", "DOLLARDE", false, "com.sun.star.sheet.addin.Analysis.getDollarde", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETDOLLARDE" },
+ { "YIELD", "YIELD", false, "com.sun.star.sheet.addin.Analysis.getYield", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETYIELD" },
+ { "YIELDDISC", "YIELDDISC", false, "com.sun.star.sheet.addin.Analysis.getYielddisc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETYIELDDISC" },
+ { "YIELDMAT", "YIELDMAT", false, "com.sun.star.sheet.addin.Analysis.getYieldmat", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETYIELDMAT" },
+ { "TBILLEQ", "TBILLEQ", false, "com.sun.star.sheet.addin.Analysis.getTbilleq", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETTBILLEQ" },
+ { "TBILLPRICE", "TBILLPRICE", false, "com.sun.star.sheet.addin.Analysis.getTbillprice", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETTBILLPRICE" },
+ { "TBILLYIELD", "TBILLYIELD", false, "com.sun.star.sheet.addin.Analysis.getTbillyield", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETTBILLYIELD" },
+ { "ODDFPRICE", "ODDFPRICE", false, "com.sun.star.sheet.addin.Analysis.getOddfprice", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETODDFPRICE" },
+ { "ODDFYIELD", "ODDFYIELD", false, "com.sun.star.sheet.addin.Analysis.getOddfyield", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETODDFYIELD" },
+ { "ODDLPRICE", "ODDLPRICE", false, "com.sun.star.sheet.addin.Analysis.getOddlprice", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETODDLPRICE" },
+ { "ODDLYIELD", "ODDLYIELD", false, "com.sun.star.sheet.addin.Analysis.getOddlyield", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETODDLYIELD" },
+ { "XIRR", "XIRR", false, "com.sun.star.sheet.addin.Analysis.getXirr", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETXIRR" },
+ { "XNPV", "XNPV", false, "com.sun.star.sheet.addin.Analysis.getXnpv", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETXNPV" },
+ { "INTRATE", "INTRATE", false, "com.sun.star.sheet.addin.Analysis.getIntrate", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETINTRATE" },
+ { "COUPNCD", "COUPNCD", false, "com.sun.star.sheet.addin.Analysis.getCoupncd", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOUPNCD" },
+ { "COUPDAYS", "COUPDAYS", false, "com.sun.star.sheet.addin.Analysis.getCoupdays", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOUPDAYS" },
+ { "COUPDAYSNC", "COUPDAYSNC", false, "com.sun.star.sheet.addin.Analysis.getCoupdaysnc", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOUPDAYSNC" },
+ { "COUPDAYBS", "COUPDAYBS", false, "com.sun.star.sheet.addin.Analysis.getCoupdaybs", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOUPDAYBS" },
+ { "COUPPCD", "COUPPCD", false, "com.sun.star.sheet.addin.Analysis.getCouppcd", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOUPPCD" },
+ { "COUPNUM", "COUPNUM", false, "com.sun.star.sheet.addin.Analysis.getCoupnum", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETCOUPNUM" },
+ { "FVSCHEDULE", "FVSCHEDULE", false, "com.sun.star.sheet.addin.Analysis.getFvschedule", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETFVSCHEDULE" },
+};
+
+// static
+const ScCompiler::AddInMap* ScCompiler::GetAddInMap()
+{
+ return maAddInMap;
+}
+
+// static
+size_t ScCompiler::GetAddInMapCount()
+{
+ return sizeof(maAddInMap)/sizeof(maAddInMap[0]);
+}
diff --git a/sc/source/core/tool/optutil.cxx b/sc/source/core/tool/optutil.cxx
new file mode 100644
index 000000000000..dc63c7819eff
--- /dev/null
+++ b/sc/source/core/tool/optutil.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <vcl/svapp.hxx>
+
+#include "optutil.hxx"
+#include "global.hxx" // for pSysLocale
+#include <unotools/syslocale.hxx>
+
+//------------------------------------------------------------------
+
+// static
+BOOL ScOptionsUtil::IsMetricSystem()
+{
+ //! which language should be used here - system language or installed office language?
+
+// MeasurementSystem eSys = Application::GetAppInternational().GetMeasurementSystem();
+ MeasurementSystem eSys = ScGlobal::pLocaleData->getMeasurementSystemEnum();
+
+ return ( eSys == MEASURE_METRIC );
+}
+
+//------------------------------------------------------------------
+
+ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString& rSubTree ) :
+ ConfigItem( rSubTree )
+{
+}
+
+ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString& rSubTree, sal_Int16 nMode ) :
+ ConfigItem( rSubTree, nMode )
+{
+}
+
+void ScLinkConfigItem::SetCommitLink( const Link& rLink )
+{
+ aCommitLink = rLink;
+}
+
+void ScLinkConfigItem::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& /* aPropertyNames */ )
+{
+ //! not implemented yet...
+}
+
+void ScLinkConfigItem::Commit()
+{
+ aCommitLink.Call( this );
+}
+
+
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
new file mode 100644
index 000000000000..a863bc0a68c2
--- /dev/null
+++ b/sc/source/core/tool/parclass.cxx
@@ -0,0 +1,578 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "parclass.hxx"
+#include "token.hxx"
+#include "global.hxx"
+#include "callform.hxx"
+#include "addincol.hxx"
+#include "funcdesc.hxx"
+#include <unotools/charclass.hxx>
+#include <tools/debug.hxx>
+#include <string.h>
+
+#if OSL_DEBUG_LEVEL > 1
+// the documentation thingy
+#include <stdio.h>
+#include <com/sun/star/sheet/FormulaLanguage.hpp>
+#include "compiler.hxx"
+#include "sc.hrc" // VAR_ARGS
+#endif
+
+
+/* Following assumptions are made:
+ * - OpCodes not specified at all will have at least one and only parameters of
+ * type Value, no check is done on the count of parameters => no Bounds type
+ * is returned.
+ * - For OpCodes with a variable number of parameters the type of the last
+ * parameter specified determines the type of all following parameters.
+ */
+
+const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
+{
+ // IF() and CHOOSE() are somewhat special, since the ScJumpMatrix is
+ // created inside those functions and ConvertMatrixParameters() is not
+ // called for them.
+ { ocIf, {{ Array, Reference, Reference }, false }},
+ { ocChose, {{ Array, Reference }, true }},
+ // Other specials.
+ { ocOpen, {{ Bounds }, false }},
+ { ocClose, {{ Bounds }, false }},
+ { ocSep, {{ Bounds }, false }},
+ { ocNoName, {{ Bounds }, false }},
+ { ocErrCell, {{ Bounds }, false }},
+ { ocStop, {{ Bounds }, false }},
+ { ocUnion, {{ Reference, Reference }, false }},
+ { ocRange, {{ Reference, Reference }, false }},
+ // Functions with Value parameters only but not in resource.
+ { ocBackSolver, {{ Value, Value, Value }, false }},
+ { ocTableOp, {{ Value, Value, Value, Value, Value }, false }},
+ // Operators and functions.
+ { ocAdd, {{ Array, Array }, false }},
+ { ocAmpersand, {{ Array, Array }, false }},
+ { ocAnd, {{ Reference }, true }},
+ { ocAreas, {{ Reference }, false }},
+ { ocAveDev, {{ Reference }, true }},
+ { ocAverage, {{ Reference }, true }},
+ { ocAverageA, {{ Reference }, true }},
+ { ocCell, {{ Value, Reference }, false }},
+ { ocColumn, {{ Reference }, false }},
+ { ocColumns, {{ Reference }, true }},
+ { ocCorrel, {{ ForceArray, ForceArray }, false }},
+ { ocCount, {{ Reference }, true }},
+ { ocCount2, {{ Reference }, true }},
+ { ocCountEmptyCells, {{ Reference }, false }},
+ { ocCountIf, {{ Reference, Value }, false }},
+ { ocCovar, {{ ForceArray, ForceArray }, false }},
+ { ocDBAverage, {{ Reference, Reference, Reference }, false }},
+ { ocDBCount, {{ Reference, Reference, Reference }, false }},
+ { ocDBCount2, {{ Reference, Reference, Reference }, false }},
+ { ocDBGet, {{ Reference, Reference, Reference }, false }},
+ { ocDBMax, {{ Reference, Reference, Reference }, false }},
+ { ocDBMin, {{ Reference, Reference, Reference }, false }},
+ { ocDBProduct, {{ Reference, Reference, Reference }, false }},
+ { ocDBStdDev, {{ Reference, Reference, Reference }, false }},
+ { ocDBStdDevP, {{ Reference, Reference, Reference }, false }},
+ { ocDBSum, {{ Reference, Reference, Reference }, false }},
+ { ocDBVar, {{ Reference, Reference, Reference }, false }},
+ { ocDBVarP, {{ Reference, Reference, Reference }, false }},
+ { ocDevSq, {{ Reference }, true }},
+ { ocDiv, {{ Array, Array }, false }},
+ { ocEqual, {{ Array, Array }, false }},
+ { ocForecast, {{ Value, ForceArray, ForceArray }, false }},
+ { ocFrequency, {{ Reference, Reference }, false }},
+ { ocFTest, {{ ForceArray, ForceArray }, false }},
+ { ocGeoMean, {{ Reference }, true }},
+ { ocGCD, {{ Reference }, true }},
+ { ocGreater, {{ Array, Array }, false }},
+ { ocGreaterEqual, {{ Array, Array }, false }},
+ { ocGrowth, {{ Reference, Reference, Reference, Value }, false }},
+ { ocHarMean, {{ Reference }, true }},
+ { ocHLookup, {{ Value, Reference, Value, Value }, false }},
+ { ocIRR, {{ Reference, Value }, false }},
+ { ocIndex, {{ Reference, Value, Value, Value }, false }},
+ { ocIntercept, {{ ForceArray, ForceArray }, false }},
+ { ocIntersect, {{ Reference, Reference }, false }},
+ { ocIsRef, {{ Reference }, false }},
+ { ocLCM, {{ Reference }, true }},
+ { ocKurt, {{ Reference }, true }},
+ { ocLarge, {{ Reference, Value }, false }},
+ { ocLess, {{ Array, Array }, false }},
+ { ocLessEqual, {{ Array, Array }, false }},
+ { ocLookup, {{ Value, ReferenceOrForceArray, ReferenceOrForceArray }, false }},
+ { ocMatch, {{ Value, Reference, Reference }, false }},
+ { ocMatDet, {{ ForceArray }, false }},
+ { ocMatInv, {{ ForceArray }, false }},
+ { ocMatMult, {{ ForceArray, ForceArray }, false }},
+ { ocMatTrans, {{ Array }, false }}, // strange, but Xcl doesn't force MatTrans array
+ { ocMatValue, {{ Reference, Value, Value }, false }},
+ { ocMax, {{ Reference }, true }},
+ { ocMaxA, {{ Reference }, true }},
+ { ocMedian, {{ Reference }, true }},
+ { ocMin, {{ Reference }, true }},
+ { ocMinA, {{ Reference }, true }},
+ { ocMIRR, {{ Reference, Value, Value }, false }},
+ { ocModalValue, {{ ForceArray }, true }},
+ { ocMul, {{ Array, Array }, false }},
+ { ocMultiArea, {{ Reference }, true }},
+ { ocN, {{ Reference }, false }},
+ { ocNPV, {{ Value, Reference }, true }},
+ { ocNeg, {{ Array }, false }},
+ { ocNegSub, {{ Array }, false }},
+ { ocNot, {{ Array }, false }},
+ { ocNotEqual, {{ Array, Array }, false }},
+ { ocOffset, {{ Reference, Value, Value, Value, Value }, false }},
+ { ocOr, {{ Reference }, true }},
+ { ocPearson, {{ ForceArray, ForceArray }, false }},
+ { ocPercentile, {{ Reference, Value }, false }},
+ { ocPercentrank, {{ Reference, Value }, false }},
+ { ocPow, {{ Array, Array }, false }},
+ { ocPower, {{ Array, Array }, false }},
+ { ocProb, {{ ForceArray, ForceArray, Value, Value }, false }},
+ { ocProduct, {{ Reference }, true }},
+ { ocQuartile, {{ Reference, Value }, false }},
+ { ocRank, {{ Value, Reference, Value }, false }},
+ { ocRGP, {{ Reference, Reference, Value, Value }, false }},
+ { ocRKP, {{ Reference, Reference, Value, Value }, false }},
+ { ocRow, {{ Reference }, false }},
+ { ocRows, {{ Reference }, true }},
+ { ocRSQ, {{ ForceArray, ForceArray }, false }},
+ { ocSchiefe, {{ Reference }, true }},
+ { ocSlope, {{ ForceArray, ForceArray }, false }},
+ { ocSmall, {{ Reference, Value }, false }},
+ { ocStDev, {{ Reference }, true }},
+ { ocStDevA, {{ Reference }, true }},
+ { ocStDevP, {{ Reference }, true }},
+ { ocStDevPA, {{ Reference }, true }},
+ { ocSTEYX, {{ ForceArray, ForceArray }, false }},
+ { ocSub, {{ Array, Array }, false }},
+ { ocSubTotal, {{ Value, Reference }, true }},
+ { ocSum, {{ Reference }, true }},
+ { ocSumIf, {{ Reference, Value, Reference }, false }},
+ { ocSumProduct, {{ ForceArray }, true }},
+ { ocSumSQ, {{ Reference }, true }},
+ { ocSumX2MY2, {{ ForceArray, ForceArray }, false }},
+ { ocSumX2DY2, {{ ForceArray, ForceArray }, false }},
+ { ocSumXMY2, {{ ForceArray, ForceArray }, false }},
+ { ocTable, {{ Reference }, false }},
+ { ocTables, {{ Reference }, true }},
+ { ocTrend, {{ Reference, Reference, Reference, Value }, false }},
+ { ocTrimMean, {{ Reference, Value }, false }},
+ { ocTTest, {{ ForceArray, ForceArray, Value, Value }, false }},
+ { ocVar, {{ Reference }, true }},
+ { ocVarA, {{ Reference }, true }},
+ { ocVarP, {{ Reference }, true }},
+ { ocVarPA, {{ Reference }, true }},
+ { ocVLookup, {{ Value, Reference, Value, Value }, false }},
+ { ocZTest, {{ Reference, Value, Value }, false }},
+ // Excel doubts:
+ // ocT: Excel says (and handles) Reference, error? This means no position
+ // dependent SingleRef if DoubleRef, and no array calculation, just the
+ // upper left corner. We never did that.
+ { ocT, {{ Value }, false }},
+ // The stopper.
+ { ocNone, {{ Bounds }, false } }
+};
+
+ScParameterClassification::RunData * ScParameterClassification::pData = NULL;
+
+
+void ScParameterClassification::Init()
+{
+ if ( pData )
+ return;
+ pData = new RunData[ SC_OPCODE_LAST_OPCODE_ID + 1 ];
+ memset( pData, 0, sizeof(RunData) * (SC_OPCODE_LAST_OPCODE_ID + 1));
+
+ // init from specified static data above
+ for ( size_t i=0; i < sizeof(pRawData) / sizeof(RawData); ++i )
+ {
+ const RawData* pRaw = &pRawData[i];
+ if ( pRaw->eOp > SC_OPCODE_LAST_OPCODE_ID )
+ {
+ DBG_ASSERT( pRaw->eOp == ocNone, "RawData OpCode error");
+ }
+ else
+ {
+ RunData* pRun = &pData[ pRaw->eOp ];
+#ifdef DBG_UTIL
+ if ( pRun->aData.nParam[0] != Unknown )
+ {
+ DBG_ERROR1( "already assigned: %d", pRaw->eOp);
+ }
+#endif
+ memcpy( &(pRun->aData), &(pRaw->aData), sizeof(CommonData));
+ // fill 0-initialized fields with real values
+ if ( pRun->aData.bRepeatLast )
+ {
+ Type eLast = Unknown;
+ for ( size_t j=0; j < CommonData::nMaxParams; ++j )
+ {
+ if ( pRun->aData.nParam[j] )
+ {
+ eLast = pRun->aData.nParam[j];
+ pRun->nMinParams = sal::static_int_cast<BYTE>( j+1 );
+ }
+ else
+ pRun->aData.nParam[j] = eLast;
+ }
+ }
+ else
+ {
+ for ( size_t j=0; j < CommonData::nMaxParams; ++j )
+ {
+ if ( !pRun->aData.nParam[j] )
+ {
+ if ( j == 0 || pRun->aData.nParam[j-1] != Bounds )
+ pRun->nMinParams = sal::static_int_cast<BYTE>( j );
+ pRun->aData.nParam[j] = Bounds;
+ }
+ }
+ if ( !pRun->nMinParams &&
+ pRun->aData.nParam[CommonData::nMaxParams-1] != Bounds)
+ pRun->nMinParams = CommonData::nMaxParams;
+ }
+ for ( size_t j=0; j < CommonData::nMaxParams; ++j )
+ {
+ if ( pRun->aData.nParam[j] == ForceArray || pRun->aData.nParam[j] == ReferenceOrForceArray )
+ {
+ pRun->bHasForceArray = true;
+ break; // for
+ }
+ }
+ }
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ GenerateDocumentation();
+#endif
+}
+
+
+void ScParameterClassification::Exit()
+{
+ delete [] pData;
+ pData = NULL;
+}
+
+
+ScParameterClassification::Type ScParameterClassification::GetParameterType(
+ const formula::FormulaToken* pToken, USHORT nParameter)
+{
+ OpCode eOp = pToken->GetOpCode();
+ switch ( eOp )
+ {
+ case ocExternal:
+ return GetExternalParameterType( pToken, nParameter);
+ //break;
+ case ocMacro:
+ return Reference;
+ //break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if ( 0 <= (short)eOp && eOp <= SC_OPCODE_LAST_OPCODE_ID )
+ {
+ if ( nParameter < CommonData::nMaxParams )
+ {
+ Type eT = pData[eOp].aData.nParam[nParameter];
+ return eT == Unknown ? Value : eT;
+ }
+ else if ( pData[eOp].aData.bRepeatLast )
+ return pData[eOp].aData.nParam[CommonData::nMaxParams-1];
+ else
+ return Bounds;
+ }
+ return Unknown;
+}
+
+
+ScParameterClassification::Type
+ScParameterClassification::GetExternalParameterType( const formula::FormulaToken* pToken,
+ USHORT nParameter)
+{
+ Type eRet = Unknown;
+ // similar to ScInterpreter::ScExternal()
+ USHORT nIndex;
+ String aUnoName;
+ String aFuncName( ScGlobal::pCharClass->upper( pToken->GetExternal()));
+ if ( ScGlobal::GetFuncCollection()->SearchFunc( aFuncName, nIndex) )
+ {
+ FuncData* pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(
+ nIndex);
+ if ( nParameter >= pFuncData->GetParamCount() )
+ eRet = Bounds;
+ else
+ {
+ switch ( pFuncData->GetParamType( nParameter) )
+ {
+ case PTR_DOUBLE:
+ case PTR_STRING:
+ eRet = Value;
+ break;
+ default:
+ eRet = Reference;
+ // also array types are created using an area reference
+ }
+ }
+ }
+ else if ( (aUnoName = ScGlobal::GetAddInCollection()->FindFunction(
+ aFuncName, FALSE)).Len() )
+ {
+ // the relevant parts of ScUnoAddInCall without having to create one
+ const ScUnoAddInFuncData* pFuncData =
+ ScGlobal::GetAddInCollection()->GetFuncData( aUnoName, true ); // need fully initialized data
+ if ( pFuncData )
+ {
+ long nCount = pFuncData->GetArgumentCount();
+ if ( nCount <= 0 )
+ eRet = Bounds;
+ else
+ {
+ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+ if ( nParameter >= nCount &&
+ pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+ eRet = Value;
+ // last arg is sequence, optional "any"s, we simply can't
+ // determine the type
+ if ( eRet == Unknown )
+ {
+ if ( nParameter >= nCount )
+ eRet = Bounds;
+ else
+ {
+ switch ( pArgs[nParameter].eType )
+ {
+ case SC_ADDINARG_INTEGER:
+ case SC_ADDINARG_DOUBLE:
+ case SC_ADDINARG_STRING:
+ eRet = Value;
+ break;
+ default:
+ eRet = Reference;
+ }
+ }
+ }
+ }
+ }
+ }
+ return eRet;
+}
+
+//-----------------------------------------------------------------------------
+
+#if OSL_DEBUG_LEVEL > 1
+
+// add remaining functions, all Value parameters
+void ScParameterClassification::MergeArgumentsFromFunctionResource()
+{
+ ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ for ( const ScFuncDesc* pDesc = pFuncList->First(); pDesc;
+ pDesc = pFuncList->Next() )
+ {
+ if ( pDesc->nFIndex > SC_OPCODE_LAST_OPCODE_ID ||
+ pData[pDesc->nFIndex].aData.nParam[0] != Unknown )
+ continue; // not an internal opcode or already done
+
+ RunData* pRun = &pData[ pDesc->nFIndex ];
+ USHORT nArgs = pDesc->GetSuppressedArgCount();
+ if ( nArgs >= VAR_ARGS )
+ {
+ nArgs -= VAR_ARGS - 1;
+ pRun->aData.bRepeatLast = true;
+ }
+ if ( nArgs > CommonData::nMaxParams )
+ {
+ DBG_ERROR2( "ScParameterClassification::Init: too many arguments in listed function: %s: %d",
+ ByteString( *(pDesc->pFuncName),
+ RTL_TEXTENCODING_UTF8).GetBuffer(), nArgs);
+ nArgs = CommonData::nMaxParams;
+ pRun->aData.bRepeatLast = true;
+ }
+ pRun->nMinParams = static_cast< BYTE >( nArgs );
+ for ( size_t j=0; j < nArgs; ++j )
+ {
+ pRun->aData.nParam[j] = Value;
+ }
+ if ( pRun->aData.bRepeatLast )
+ {
+ for ( size_t j = nArgs; j < CommonData::nMaxParams; ++j )
+ {
+ pRun->aData.nParam[j] = Value;
+ }
+ }
+ else
+ {
+ for ( size_t j = nArgs; j < CommonData::nMaxParams; ++j )
+ {
+ pRun->aData.nParam[j] = Bounds;
+ }
+ }
+ }
+}
+
+
+void ScParameterClassification::GenerateDocumentation()
+{
+ static const sal_Char aEnvVarName[] = "OOO_CALC_GENPARCLASSDOC";
+ if ( !getenv( aEnvVarName) )
+ return;
+ MergeArgumentsFromFunctionResource();
+ ScAddress aAddress;
+ ScCompiler aComp(NULL,aAddress);
+ ScCompiler::OpCodeMapPtr xMap( aComp.GetOpCodeMap(::com::sun::star::sheet::FormulaLanguage::ENGLISH));
+ if (!xMap)
+ return;
+ fflush( stderr);
+ size_t nCount = xMap->getSymbolCount();
+ for ( size_t i=0; i<nCount; ++i )
+ {
+ OpCode eOp = OpCode(i);
+ if ( xMap->getSymbol(eOp).Len() )
+ {
+ fprintf( stdout, "%s: ", aEnvVarName);
+ ByteString aStr( xMap->getSymbol(eOp), RTL_TEXTENCODING_UTF8);
+ aStr += "(";
+ formula::FormulaByteToken aToken( eOp);
+ BYTE nParams = GetMinimumParameters( eOp);
+ // preset parameter count according to opcode value, with some
+ // special handling
+ if ( eOp < SC_OPCODE_STOP_DIV )
+ {
+ switch ( eOp )
+ {
+ case ocIf:
+ aToken.SetByte(3);
+ break;
+ case ocChose:
+ aToken.SetByte(2);
+ break;
+ case ocPercentSign:
+ aToken.SetByte(1);
+ break;
+ default:;
+ }
+ }
+ else if ( eOp < SC_OPCODE_STOP_ERRORS )
+ aToken.SetByte(0);
+ else if ( eOp < SC_OPCODE_STOP_BIN_OP )
+ {
+ switch ( eOp )
+ {
+ case ocAnd:
+ case ocOr:
+ aToken.SetByte(1); // (r1)AND(r2) --> AND( r1, ...)
+ break;
+ default:
+ aToken.SetByte(2);
+ }
+ }
+ else if ( eOp < SC_OPCODE_STOP_UN_OP )
+ aToken.SetByte(1);
+ else if ( eOp < SC_OPCODE_STOP_NO_PAR )
+ aToken.SetByte(0);
+ else if ( eOp < SC_OPCODE_STOP_1_PAR )
+ aToken.SetByte(1);
+ else
+ aToken.SetByte( nParams);
+ // compare (this is a mere test for opcode order Div, BinOp, UnOp,
+ // NoPar, 1Par, ...) and override parameter count with
+ // classification
+ if ( nParams != aToken.GetByte() )
+ fprintf( stdout, "(parameter count differs, token Byte: %d classification: %d) ",
+ aToken.GetByte(), nParams);
+ aToken.SetByte( nParams);
+ if ( nParams != aToken.GetParamCount() )
+ fprintf( stdout, "(parameter count differs, token ParamCount: %d classification: %d) ",
+ aToken.GetParamCount(), nParams);
+ for ( USHORT j=0; j < nParams; ++j )
+ {
+ if ( j > 0 )
+ aStr += ",";
+ Type eType = GetParameterType( &aToken, j);
+ switch ( eType )
+ {
+ case Value :
+ aStr += " Value";
+ break;
+ case Reference :
+ aStr += " Reference";
+ break;
+ case Array :
+ aStr += " Array";
+ break;
+ case ForceArray :
+ aStr += " ForceArray";
+ break;
+ case ReferenceOrForceArray :
+ aStr += " ReferenceOrForceArray";
+ break;
+ case Bounds :
+ aStr += " (Bounds, classification error?)";
+ break;
+ default:
+ aStr += " (???, classification error?)";
+ }
+ }
+ if ( HasRepeatParameters( eOp) )
+ aStr += ", ...";
+ if ( nParams )
+ aStr += " ";
+ aStr += ")";
+ switch ( eOp )
+ {
+ case ocZGZ:
+ aStr += " // RRI in English resource, but ZGZ in English-only section";
+ break;
+ case ocMultiArea:
+ aStr += " // e.g. combined first parameter of INDEX() function, not a real function";
+ break;
+ case ocBackSolver:
+ aStr += " // goal seek via menu, not a real function";
+ break;
+ case ocTableOp:
+ aStr += " // MULTIPLE.OPERATIONS in English resource, but TABLE in English-only section";
+ break;
+ case ocNoName:
+ aStr += " // error function, not a real function";
+ break;
+ default:;
+ }
+ fprintf( stdout, "%s\n", aStr.GetBuffer());
+ }
+ }
+ fflush( stdout);
+}
+
+#endif // OSL_DEBUG_LEVEL
+
diff --git a/sc/source/core/tool/printopt.cxx b/sc/source/core/tool/printopt.cxx
new file mode 100644
index 000000000000..c701c558310b
--- /dev/null
+++ b/sc/source/core/tool/printopt.cxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "printopt.hxx"
+#include "miscuno.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScTpPrintItem, SfxPoolItem);
+
+// -----------------------------------------------------------------------
+
+ScPrintOptions::ScPrintOptions()
+{
+ SetDefaults();
+}
+
+ScPrintOptions::ScPrintOptions( const ScPrintOptions& rCpy ) :
+ bSkipEmpty( rCpy.bSkipEmpty ),
+ bAllSheets( rCpy.bAllSheets )
+{
+}
+
+ScPrintOptions::~ScPrintOptions()
+{
+}
+
+void ScPrintOptions::SetDefaults()
+{
+ bSkipEmpty = TRUE;
+ bAllSheets = FALSE;
+}
+
+const ScPrintOptions& ScPrintOptions::operator=( const ScPrintOptions& rCpy )
+{
+ bSkipEmpty = rCpy.bSkipEmpty;
+ bAllSheets = rCpy.bAllSheets;
+ return *this;
+}
+
+int ScPrintOptions::operator==( const ScPrintOptions& rOpt ) const
+{
+ return bSkipEmpty == rOpt.bSkipEmpty
+ && bAllSheets == rOpt.bAllSheets;
+}
+
+int ScPrintOptions::operator!=( const ScPrintOptions& rOpt ) const
+{
+ return !(operator==(rOpt));
+}
+
+// -----------------------------------------------------------------------
+
+//UNUSED2008-05 ScTpPrintItem::ScTpPrintItem( USHORT nWhichP ) : SfxPoolItem( nWhichP )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScTpPrintItem::ScTpPrintItem( USHORT nWhichP, const ScPrintOptions& rOpt ) :
+ SfxPoolItem ( nWhichP ),
+ theOptions ( rOpt )
+{
+}
+
+ScTpPrintItem::ScTpPrintItem( const ScTpPrintItem& rItem ) :
+ SfxPoolItem ( rItem ),
+ theOptions ( rItem.theOptions )
+{
+}
+
+ScTpPrintItem::~ScTpPrintItem()
+{
+}
+
+String ScTpPrintItem::GetValueText() const
+{
+ return String::CreateFromAscii( "ScTpPrintItem" );
+}
+
+int ScTpPrintItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScTpPrintItem& rPItem = (const ScTpPrintItem&)rItem;
+ return ( theOptions == rPItem.theOptions );
+}
+
+SfxPoolItem* ScTpPrintItem::Clone( SfxItemPool * ) const
+{
+ return new ScTpPrintItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+#define CFGPATH_PRINT "Office.Calc/Print"
+
+#define SCPRINTOPT_EMPTYPAGES 0
+#define SCPRINTOPT_ALLSHEETS 1
+#define SCPRINTOPT_COUNT 2
+
+Sequence<OUString> ScPrintCfg::GetPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Page/EmptyPages", // SCPRINTOPT_EMPTYPAGES
+ "Other/AllSheets" // SCPRINTOPT_ALLSHEETS
+ };
+ Sequence<OUString> aNames(SCPRINTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCPRINTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+ScPrintCfg::ScPrintCfg() :
+ ConfigItem( OUString::createFromAscii( CFGPATH_PRINT ) )
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues = GetProperties(aNames);
+// EnableNotification(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCPRINTOPT_EMPTYPAGES:
+ // reversed
+ SetSkipEmpty( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCPRINTOPT_ALLSHEETS:
+ SetAllSheets( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void ScPrintCfg::Commit()
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCPRINTOPT_EMPTYPAGES:
+ // reversed
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], !GetSkipEmpty() );
+ break;
+ case SCPRINTOPT_ALLSHEETS:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetAllSheets() );
+ break;
+ }
+ }
+ PutProperties(aNames, aValues);
+}
+
+void ScPrintCfg::SetOptions( const ScPrintOptions& rNew )
+{
+ *(ScPrintOptions*)this = rNew;
+ SetModified();
+}
+
+void ScPrintCfg::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& ) {}
+
diff --git a/sc/source/core/tool/prnsave.cxx b/sc/source/core/tool/prnsave.cxx
new file mode 100644
index 000000000000..b432f585e854
--- /dev/null
+++ b/sc/source/core/tool/prnsave.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+
+#include "prnsave.hxx"
+#include "global.hxx"
+#include "address.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+//------------------------------------------------------------------
+
+//
+// Daten pro Tabelle
+//
+
+ScPrintSaverTab::ScPrintSaverTab() :
+ mpRepeatCol(NULL),
+ mpRepeatRow(NULL),
+ mbEntireSheet(FALSE)
+{
+}
+
+ScPrintSaverTab::~ScPrintSaverTab()
+{
+ delete mpRepeatCol;
+ delete mpRepeatRow;
+}
+
+void ScPrintSaverTab::SetAreas( const ScRangeVec& rRanges, BOOL bEntireSheet )
+{
+ maPrintRanges = rRanges;
+ mbEntireSheet = bEntireSheet;
+}
+
+void ScPrintSaverTab::SetRepeat( const ScRange* pCol, const ScRange* pRow )
+{
+ delete mpRepeatCol;
+ mpRepeatCol = pCol ? new ScRange(*pCol) : NULL;
+ delete mpRepeatRow;
+ mpRepeatRow = pRow ? new ScRange(*pRow) : NULL;
+}
+
+inline BOOL PtrEqual( const ScRange* p1, const ScRange* p2 )
+{
+ return ( !p1 && !p2 ) || ( p1 && p2 && *p1 == *p2 );
+}
+
+BOOL ScPrintSaverTab::operator==( const ScPrintSaverTab& rCmp ) const
+{
+ return
+ PtrEqual( mpRepeatCol, rCmp.mpRepeatCol ) &&
+ PtrEqual( mpRepeatRow, rCmp.mpRepeatRow ) &&
+ (mbEntireSheet == rCmp.mbEntireSheet) &&
+ (maPrintRanges == rCmp.maPrintRanges);
+}
+
+//
+// Daten fuer das ganze Dokument
+//
+
+ScPrintRangeSaver::ScPrintRangeSaver( SCTAB nCount ) :
+ nTabCount( nCount )
+{
+ if (nCount > 0)
+ pData = new ScPrintSaverTab[nCount];
+ else
+ pData = NULL;
+}
+
+ScPrintRangeSaver::~ScPrintRangeSaver()
+{
+ delete[] pData;
+}
+
+ScPrintSaverTab& ScPrintRangeSaver::GetTabData(SCTAB nTab)
+{
+ DBG_ASSERT(nTab<nTabCount,"ScPrintRangeSaver Tab zu gross");
+ return pData[nTab];
+}
+
+const ScPrintSaverTab& ScPrintRangeSaver::GetTabData(SCTAB nTab) const
+{
+ DBG_ASSERT(nTab<nTabCount,"ScPrintRangeSaver Tab zu gross");
+ return pData[nTab];
+}
+
+BOOL ScPrintRangeSaver::operator==( const ScPrintRangeSaver& rCmp ) const
+{
+ BOOL bEqual = ( nTabCount == rCmp.nTabCount );
+ if (bEqual)
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (!(pData[i]==rCmp.pData[i]))
+ {
+ bEqual = FALSE;
+ break;
+ }
+ return bEqual;
+}
+
+
+
+
diff --git a/sc/source/core/tool/progress.cxx b/sc/source/core/tool/progress.cxx
new file mode 100644
index 000000000000..a2fa45764bcc
--- /dev/null
+++ b/sc/source/core/tool/progress.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/progress.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/eitem.hxx>
+#include <svl/itemset.hxx>
+
+#define SC_PROGRESS_CXX
+#include "progress.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+
+
+
+static ScProgress theDummyInterpretProgress;
+SfxProgress* ScProgress::pGlobalProgress = NULL;
+ULONG ScProgress::nGlobalRange = 0;
+ULONG ScProgress::nGlobalPercent = 0;
+BOOL ScProgress::bGlobalNoUserBreak = TRUE;
+ScProgress* ScProgress::pInterpretProgress = &theDummyInterpretProgress;
+ScProgress* ScProgress::pOldInterpretProgress = NULL;
+ULONG ScProgress::nInterpretProgress = 0;
+BOOL ScProgress::bAllowInterpretProgress = TRUE;
+ScDocument* ScProgress::pInterpretDoc;
+BOOL ScProgress::bIdleWasDisabled = FALSE;
+
+
+BOOL lcl_IsHiddenDocument( SfxObjectShell* pObjSh )
+{
+ if (pObjSh)
+ {
+ SfxMedium* pMed = pObjSh->GetMedium();
+ if (pMed)
+ {
+ SfxItemSet* pSet = pMed->GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_HIDDEN, TRUE, &pItem ) &&
+ ((const SfxBoolItem*)pItem)->GetValue() )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+ScProgress::ScProgress( SfxObjectShell* pObjSh, const String& rText,
+ ULONG nRange, BOOL bAllDocs, BOOL bWait )
+{
+
+ if ( pGlobalProgress || SfxProgress::GetActiveProgress( NULL ) )
+ {
+ if ( lcl_IsHiddenDocument(pObjSh) )
+ {
+ // loading a hidden document while a progress is active is possible - no error
+ pProgress = NULL;
+ }
+ else
+ {
+ DBG_ERROR( "ScProgress: there can be only one!" );
+ pProgress = NULL;
+ }
+ }
+ else if ( SFX_APP()->IsDowning() )
+ {
+ // kommt vor z.B. beim Speichern des Clipboard-Inhalts als OLE beim Beenden
+ // Dann wuerde ein SfxProgress wild im Speicher rummuellen
+ //! Soll das so sein ???
+
+ pProgress = NULL;
+ }
+ else if ( pObjSh && ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ||
+ pObjSh->GetProgress() ) )
+ {
+ // #62808# no own progress for embedded objects,
+ // #73633# no second progress if the document already has one
+
+ pProgress = NULL;
+ }
+ else
+ {
+ pProgress = new SfxProgress( pObjSh, rText, nRange, bAllDocs, bWait );
+ pGlobalProgress = pProgress;
+ nGlobalRange = nRange;
+ nGlobalPercent = 0;
+ bGlobalNoUserBreak = TRUE;
+ }
+}
+
+
+ScProgress::ScProgress() :
+ pProgress( NULL )
+{ // DummyInterpret
+}
+
+
+ScProgress::~ScProgress()
+{
+ if ( pProgress )
+ {
+ delete pProgress;
+ pGlobalProgress = NULL;
+ nGlobalRange = 0;
+ nGlobalPercent = 0;
+ bGlobalNoUserBreak = TRUE;
+ }
+}
+
+// static
+
+void ScProgress::CreateInterpretProgress( ScDocument* pDoc, BOOL bWait )
+{
+ if ( bAllowInterpretProgress )
+ {
+ if ( nInterpretProgress )
+ nInterpretProgress++;
+ else if ( pDoc->GetAutoCalc() )
+ {
+ nInterpretProgress = 1;
+ bIdleWasDisabled = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( TRUE );
+ // Interpreter may be called in many circumstances, also if another
+ // progress bar is active, for example while adapting row heights.
+ // Keep the dummy interpret progress.
+ if ( !pGlobalProgress )
+ pInterpretProgress = new ScProgress( pDoc->GetDocumentShell(),
+ ScGlobal::GetRscString( STR_PROGRESS_CALCULATING ),
+ pDoc->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE, FALSE, bWait );
+ pInterpretDoc = pDoc;
+ }
+ }
+}
+
+
+// static
+
+void ScProgress::DeleteInterpretProgress()
+{
+ if ( bAllowInterpretProgress && nInterpretProgress )
+ {
+ /* Do not decrement 'nInterpretProgress', before 'pInterpretProgress'
+ is deleted. In rare cases, deletion of 'pInterpretProgress' causes
+ a refresh of the sheet window which may call CreateInterpretProgress
+ and DeleteInterpretProgress again (from Output::DrawStrings),
+ resulting in double deletion of 'pInterpretProgress'. */
+// if ( --nInterpretProgress == 0 )
+ if ( nInterpretProgress == 1 )
+ {
+ if ( pInterpretProgress != &theDummyInterpretProgress )
+ {
+ // move pointer to local temporary to avoid double deletion
+ ScProgress* pTmpProgress = pInterpretProgress;
+ pInterpretProgress = &theDummyInterpretProgress;
+ delete pTmpProgress;
+ }
+ if ( pInterpretDoc )
+ pInterpretDoc->DisableIdle( bIdleWasDisabled );
+ }
+ --nInterpretProgress;
+ }
+}
+
+
+
diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx
new file mode 100644
index 000000000000..5b3b92f78ee4
--- /dev/null
+++ b/sc/source/core/tool/queryparam.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * 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: interpr4.cxx,v $
+ * $Revision: 1.57.92.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "queryparam.hxx"
+
+using ::std::vector;
+
+// ============================================================================
+
+ScQueryParamBase::ScQueryParamBase()
+{
+ Resize( MAXQUERY );
+ for (USHORT i=0; i<MAXQUERY; i++)
+ maEntries[i].Clear();
+}
+
+ScQueryParamBase::ScQueryParamBase(const ScQueryParamBase& r) :
+ bHasHeader(r.bHasHeader), bByRow(r.bByRow), bInplace(r.bInplace), bCaseSens(r.bCaseSens),
+ bRegExp(r.bRegExp), bDuplicate(r.bDuplicate), bMixedComparison(r.bMixedComparison),
+ maEntries(r.maEntries)
+{
+}
+
+ScQueryParamBase::~ScQueryParamBase()
+{
+}
+
+SCSIZE ScQueryParamBase::GetEntryCount() const
+{
+ return maEntries.size();
+}
+
+ScQueryEntry& ScQueryParamBase::GetEntry(SCSIZE n) const
+{
+ return maEntries[n];
+}
+
+void ScQueryParamBase::Resize(SCSIZE nNew)
+{
+ if ( nNew < MAXQUERY )
+ nNew = MAXQUERY; // nie weniger als MAXQUERY
+
+ vector<ScQueryEntry> aNewEntries(nNew);
+ SCSIZE nCopy = ::std::min(maEntries.size(), nNew);
+ for (SCSIZE i=0; i<nCopy; i++)
+ aNewEntries[i] = maEntries[i];
+
+ maEntries.swap(aNewEntries);
+}
+
+void ScQueryParamBase::DeleteQuery( SCSIZE nPos )
+{
+ if (nPos >= maEntries.size())
+ return;
+
+ size_t n = maEntries.size();
+ vector<ScQueryEntry> aNewEntries;
+ aNewEntries.reserve(n);
+ for (size_t i = 0; i < n; ++i)
+ if (i != nPos)
+ aNewEntries.push_back(maEntries[i]);
+
+ // Don't forget to append an empty entry to make up for the removed one.
+ // The size of the entries is not supposed to change.
+ aNewEntries.push_back(ScQueryEntry());
+
+ maEntries.swap(aNewEntries);
+}
+
+void ScQueryParamBase::FillInExcelSyntax(String& aCellStr, SCSIZE nIndex)
+{
+ if (aCellStr.Len() > 0)
+ {
+ if ( nIndex >= maEntries.size() )
+ Resize( nIndex+1 );
+
+ ScQueryEntry& rEntry = GetEntry(nIndex);
+
+ rEntry.bDoQuery = TRUE;
+ // Operatoren herausfiltern
+ if (aCellStr.GetChar(0) == '<')
+ {
+ if (aCellStr.GetChar(1) == '>')
+ {
+ *rEntry.pStr = aCellStr.Copy(2);
+ rEntry.eOp = SC_NOT_EQUAL;
+ }
+ else if (aCellStr.GetChar(1) == '=')
+ {
+ *rEntry.pStr = aCellStr.Copy(2);
+ rEntry.eOp = SC_LESS_EQUAL;
+ }
+ else
+ {
+ *rEntry.pStr = aCellStr.Copy(1);
+ rEntry.eOp = SC_LESS;
+ }
+ }
+ else if (aCellStr.GetChar(0) == '>')
+ {
+ if (aCellStr.GetChar(1) == '=')
+ {
+ *rEntry.pStr = aCellStr.Copy(2);
+ rEntry.eOp = SC_GREATER_EQUAL;
+ }
+ else
+ {
+ *rEntry.pStr = aCellStr.Copy(1);
+ rEntry.eOp = SC_GREATER;
+ }
+ }
+ else
+ {
+ if (aCellStr.GetChar(0) == '=')
+ *rEntry.pStr = aCellStr.Copy(1);
+ else
+ *rEntry.pStr = aCellStr;
+ rEntry.eOp = SC_EQUAL;
+ }
+ }
+}
+
+// ============================================================================
+
+ScQueryParamTable::ScQueryParamTable()
+{
+}
+
+ScQueryParamTable::ScQueryParamTable(const ScQueryParamTable& r) :
+ nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nTab(r.nTab)
+{
+}
+
+ScQueryParamTable::~ScQueryParamTable()
+{
+}
+
+// ============================================================================
+
+ScQueryParam::ScQueryParam() :
+ ScQueryParamBase(),
+ ScQueryParamTable(),
+ bDestPers(true),
+ nDestTab(0),
+ nDestCol(0),
+ nDestRow(0)
+{
+ Clear();
+}
+
+//------------------------------------------------------------------------
+
+ScQueryParam::ScQueryParam( const ScQueryParam& r ) :
+ ScQueryParamBase(r),
+ ScQueryParamTable(r),
+ bDestPers(r.bDestPers), nDestTab(r.nDestTab), nDestCol(r.nDestCol), nDestRow(r.nDestRow)
+{
+}
+
+ScQueryParam::ScQueryParam( const ScDBQueryParamInternal& r ) :
+ ScQueryParamBase(r),
+ ScQueryParamTable(r),
+ bDestPers(true),
+ nDestTab(0),
+ nDestCol(0),
+ nDestRow(0)
+{
+}
+
+
+//------------------------------------------------------------------------
+
+ScQueryParam::~ScQueryParam()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScQueryParam::Clear()
+{
+ nCol1=nCol2 = 0;
+ nRow1=nRow2 = 0;
+ nTab = SCTAB_MAX;
+ bHasHeader = bCaseSens = bRegExp = bMixedComparison = FALSE;
+ bInplace = bByRow = bDuplicate = TRUE;
+
+ Resize( MAXQUERY );
+ for (USHORT i=0; i<MAXQUERY; i++)
+ maEntries[i].Clear();
+
+ ClearDestParams();
+}
+
+void ScQueryParam::ClearDestParams()
+{
+ bDestPers = true;
+ nDestTab = 0;
+ nDestCol = 0;
+ nDestRow = 0;
+}
+
+//------------------------------------------------------------------------
+
+ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r )
+{
+ nCol1 = r.nCol1;
+ nRow1 = r.nRow1;
+ nCol2 = r.nCol2;
+ nRow2 = r.nRow2;
+ nTab = r.nTab;
+ nDestTab = r.nDestTab;
+ nDestCol = r.nDestCol;
+ nDestRow = r.nDestRow;
+ bHasHeader = r.bHasHeader;
+ bInplace = r.bInplace;
+ bCaseSens = r.bCaseSens;
+ bRegExp = r.bRegExp;
+ bMixedComparison = r.bMixedComparison;
+ bDuplicate = r.bDuplicate;
+ bByRow = r.bByRow;
+ bDestPers = r.bDestPers;
+
+ maEntries = r.maEntries;
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScQueryParam::operator==( const ScQueryParam& rOther ) const
+{
+ BOOL bEqual = FALSE;
+
+ // Anzahl der Queries gleich?
+ SCSIZE nUsed = 0;
+ SCSIZE nOtherUsed = 0;
+ SCSIZE nEntryCount = GetEntryCount();
+ SCSIZE nOtherEntryCount = rOther.GetEntryCount();
+
+ while ( nUsed<nEntryCount && maEntries[nUsed].bDoQuery ) ++nUsed;
+ while ( nOtherUsed<nOtherEntryCount && rOther.maEntries[nOtherUsed].bDoQuery )
+ ++nOtherUsed;
+
+ if ( (nUsed == nOtherUsed)
+ && (nCol1 == rOther.nCol1)
+ && (nRow1 == rOther.nRow1)
+ && (nCol2 == rOther.nCol2)
+ && (nRow2 == rOther.nRow2)
+ && (nTab == rOther.nTab)
+ && (bHasHeader == rOther.bHasHeader)
+ && (bByRow == rOther.bByRow)
+ && (bInplace == rOther.bInplace)
+ && (bCaseSens == rOther.bCaseSens)
+ && (bRegExp == rOther.bRegExp)
+ && (bMixedComparison == rOther.bMixedComparison)
+ && (bDuplicate == rOther.bDuplicate)
+ && (bDestPers == rOther.bDestPers)
+ && (nDestTab == rOther.nDestTab)
+ && (nDestCol == rOther.nDestCol)
+ && (nDestRow == rOther.nDestRow) )
+ {
+ bEqual = TRUE;
+ for ( SCSIZE i=0; i<nUsed && bEqual; i++ )
+ bEqual = maEntries[i] == rOther.maEntries[i];
+ }
+ return bEqual;
+}
+
+//------------------------------------------------------------------------
+
+void ScQueryParam::MoveToDest()
+{
+ if (!bInplace)
+ {
+ SCsCOL nDifX = ((SCsCOL) nDestCol) - ((SCsCOL) nCol1);
+ SCsROW nDifY = ((SCsROW) nDestRow) - ((SCsROW) nRow1);
+ SCsTAB nDifZ = ((SCsTAB) nDestTab) - ((SCsTAB) nTab);
+
+ nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nDifX );
+ nRow1 = sal::static_int_cast<SCROW>( nRow1 + nDifY );
+ nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX );
+ nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY );
+ nTab = sal::static_int_cast<SCTAB>( nTab + nDifZ );
+ size_t n = maEntries.size();
+ for (size_t i=0; i<n; i++)
+ maEntries[i].nField += nDifX;
+
+ bInplace = TRUE;
+ }
+ else
+ {
+ DBG_ERROR("MoveToDest, bInplace == TRUE");
+ }
+}
+
+// ============================================================================
+
+ScDBQueryParamBase::ScDBQueryParamBase(DataType eType) :
+ ScQueryParamBase(),
+ mnField(-1),
+ mbSkipString(true),
+ meType(eType)
+{
+}
+
+ScDBQueryParamBase::~ScDBQueryParamBase()
+{
+}
+
+ScDBQueryParamBase::DataType ScDBQueryParamBase::GetType() const
+{
+ return meType;
+}
+
+// ============================================================================
+
+ScDBQueryParamInternal::ScDBQueryParamInternal() :
+ ScDBQueryParamBase(ScDBQueryParamBase::INTERNAL),
+ ScQueryParamTable()
+{
+}
+
+ScDBQueryParamInternal::~ScDBQueryParamInternal()
+{
+}
+
+// ============================================================================
+
+ScDBQueryParamMatrix::ScDBQueryParamMatrix() :
+ ScDBQueryParamBase(ScDBQueryParamBase::MATRIX)
+{
+}
+
+ScDBQueryParamMatrix::~ScDBQueryParamMatrix()
+{
+}
+
diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx
new file mode 100644
index 000000000000..1ab978866c67
--- /dev/null
+++ b/sc/source/core/tool/rangelst.cxx
@@ -0,0 +1,703 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+//------------------------------------------------------------------------
+
+#define SC_RANGELST_CXX //fuer ICC
+
+#include <tools/debug.hxx>
+#include <stdlib.h> // qsort
+#include <unotools/collatorwrapper.hxx>
+
+#include "rangelst.hxx"
+#include "document.hxx"
+#include "refupdat.hxx"
+#include "rechead.hxx"
+#include "compiler.hxx"
+
+// === ScRangeList ====================================================
+
+ScRangeList::~ScRangeList()
+{
+ for ( ScRangePtr pR = First(); pR; pR = Next() )
+ delete pR;
+}
+
+void ScRangeList::RemoveAll()
+{
+ for ( ScRangePtr pR = First(); pR; pR = Next() )
+ delete pR;
+ Clear();
+}
+
+USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask,
+ formula::FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cDelimiter )
+{
+ if ( rStr.Len() )
+ {
+ if (!cDelimiter)
+ cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+
+ nMask |= SCA_VALID; // falls das jemand vergessen sollte
+ USHORT nResult = (USHORT)~0; // alle Bits setzen
+ ScRange aRange;
+ String aOne;
+ SCTAB nTab = 0;
+ if ( pDoc )
+ {
+ //! erste markierte Tabelle gibts nicht mehr am Dokument
+ //! -> uebergeben? oder spaeter an den Ranges setzen
+ }
+ else
+ nTab = 0;
+ USHORT nTCount = rStr.GetTokenCount( cDelimiter );
+ for ( USHORT i=0; i<nTCount; i++ )
+ {
+ aOne = rStr.GetToken( i, cDelimiter );
+ // FIXME : broken for Lotus
+ if ( aOne.Search( ':' ) == STRING_NOTFOUND )
+ { // Range muss es sein
+ String aStrTmp( aOne );
+ aOne += ':';
+ aOne += aStrTmp;
+ }
+ aRange.aStart.SetTab( nTab ); // Default Tab wenn nicht angegeben
+ USHORT nRes = aRange.Parse( aOne, pDoc, eConv );
+ if ( (nRes & nMask) == nMask )
+ Append( aRange );
+ nResult &= nRes; // alle gemeinsamen Bits bleiben erhalten
+ }
+ return nResult; // SCA_VALID gesetzt wenn alle ok
+ }
+ else
+ return 0;
+}
+
+
+void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc,
+ formula::FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cDelimiter ) const
+{
+ rStr.Erase();
+
+ if (!cDelimiter)
+ cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+
+ ULONG nCnt = Count();
+ for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ )
+ {
+ String aStr;
+ GetObject( nIdx )->Format( aStr, nFlags, pDoc, eConv );
+ if ( nIdx )
+ rStr += cDelimiter;
+ rStr += aStr;
+ }
+}
+
+
+void ScRangeList::Join( const ScRange& r, BOOL bIsInList )
+{
+ if ( !Count() )
+ {
+ Append( r );
+ return ;
+ }
+ SCCOL nCol1 = r.aStart.Col();
+ SCROW nRow1 = r.aStart.Row();
+ SCTAB nTab1 = r.aStart.Tab();
+ SCCOL nCol2 = r.aEnd.Col();
+ SCROW nRow2 = r.aEnd.Row();
+ SCTAB nTab2 = r.aEnd.Tab();
+ ScRangePtr pOver = (ScRangePtr) &r; // fies aber wahr wenn bInList
+ ULONG nOldPos = 0;
+ if ( bIsInList )
+ { // merken um ggbf. zu loeschen bzw. wiederherzustellen
+ nOldPos = GetPos( pOver );
+ }
+ BOOL bJoinedInput = FALSE;
+ for ( ScRangePtr p = First(); p && pOver; p = Next() )
+ {
+ if ( p == pOver )
+ continue; // derselbe, weiter mit dem naechsten
+ BOOL bJoined = FALSE;
+ if ( p->In( r ) )
+ { // Range r in Range p enthalten oder identisch
+ if ( bIsInList )
+ bJoined = TRUE; // weg mit Range r
+ else
+ { // das war's dann
+ bJoinedInput = TRUE; // nicht anhaengen
+ break; // for
+ }
+ }
+ else if ( r.In( *p ) )
+ { // Range p in Range r enthalten, r zum neuen Range machen
+ *p = r;
+ bJoined = TRUE;
+ }
+ if ( !bJoined && p->aStart.Tab() == nTab1 && p->aEnd.Tab() == nTab2 )
+ { // 2D
+ if ( p->aStart.Col() == nCol1 && p->aEnd.Col() == nCol2 )
+ {
+ if ( p->aStart.Row() == nRow2+1 )
+ { // oben
+ p->aStart.SetRow( nRow1 );
+ bJoined = TRUE;
+ }
+ else if ( p->aEnd.Row() == nRow1-1 )
+ { // unten
+ p->aEnd.SetRow( nRow2 );
+ bJoined = TRUE;
+ }
+ }
+ else if ( p->aStart.Row() == nRow1 && p->aEnd.Row() == nRow2 )
+ {
+ if ( p->aStart.Col() == nCol2+1 )
+ { // links
+ p->aStart.SetCol( nCol1 );
+ bJoined = TRUE;
+ }
+ else if ( p->aEnd.Col() == nCol1-1 )
+ { // rechts
+ p->aEnd.SetCol( nCol2 );
+ bJoined = TRUE;
+ }
+ }
+ }
+ if ( bJoined )
+ {
+ if ( bIsInList )
+ { // innerhalb der Liste Range loeschen
+ Remove( nOldPos );
+ delete pOver;
+ pOver = NULL;
+ if ( nOldPos )
+ nOldPos--; // Seek richtig aufsetzen
+ }
+ bJoinedInput = TRUE;
+ Join( *p, TRUE ); // rekursiv!
+ }
+ }
+ if ( bIsInList )
+ Seek( nOldPos );
+ else if ( !bJoinedInput )
+ Append( r );
+}
+
+
+BOOL ScRangeList::operator==( const ScRangeList& r ) const
+{
+ if ( this == &r )
+ return TRUE; // identische Referenz
+ if ( Count() != r.Count() )
+ return FALSE;
+ ULONG nCnt = Count();
+ for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ )
+ {
+ if ( *GetObject( nIdx ) != *r.GetObject( nIdx ) )
+ return FALSE; // auch andere Reihenfolge ist ungleich
+ }
+ return TRUE;
+}
+
+BOOL ScRangeList::operator!=( const ScRangeList& r ) const
+{
+ return !operator==( r );
+}
+
+BOOL ScRangeList::UpdateReference( UpdateRefMode eUpdateRefMode,
+ ScDocument* pDoc, const ScRange& rWhere,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ BOOL bChanged = FALSE;
+ if ( Count() )
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ for ( ScRange* pR = First(); pR; pR = Next() )
+ {
+ SCCOL theCol1;
+ SCROW theRow1;
+ SCTAB theTab1;
+ SCCOL theCol2;
+ SCROW theRow2;
+ SCTAB theTab2;
+ pR->GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
+ nDx, nDy, nDz,
+ theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 )
+ != UR_NOTHING )
+ {
+ bChanged = TRUE;
+ pR->aStart.Set( theCol1, theRow1, theTab1 );
+ pR->aEnd.Set( theCol2, theRow2, theTab2 );
+ }
+ }
+ }
+ return bChanged;
+}
+
+
+ScRange* ScRangeList::Find( const ScAddress& rAdr ) const
+{
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ {
+ ScRange* pR = GetObject( j );
+ if ( pR->In( rAdr ) )
+ return pR;
+ }
+ return NULL;
+}
+
+
+ScRangeList::ScRangeList( const ScRangeList& rList ) :
+ ScRangeListBase(),
+ SvRefBase()
+{
+ ULONG nListCount = rList.Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ Append( *rList.GetObject( j ) );
+}
+
+
+ScRangeList& ScRangeList::operator=(const ScRangeList& rList)
+{
+ RemoveAll();
+
+ ULONG nListCount = rList.Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ Append( *rList.GetObject( j ) );
+
+ return *this;
+}
+
+
+BOOL ScRangeList::Intersects( const ScRange& rRange ) const
+{
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ if ( GetObject(j)->Intersects( rRange ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL ScRangeList::In( const ScRange& rRange ) const
+{
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ if ( GetObject(j)->In( rRange ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+
+ULONG ScRangeList::GetCellCount() const
+{
+ ULONG nCellCount = 0;
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ {
+ ScRange* pR = GetObject( j );
+ nCellCount += ULONG(pR->aEnd.Col() - pR->aStart.Col() + 1)
+ * ULONG(pR->aEnd.Row() - pR->aStart.Row() + 1)
+ * ULONG(pR->aEnd.Tab() - pR->aStart.Tab() + 1);
+ }
+ return nCellCount;
+}
+
+
+// === ScRangePairList ====================================================
+
+ScRangePairList::~ScRangePairList()
+{
+ for ( ScRangePair* pR = First(); pR; pR = Next() )
+ delete pR;
+}
+
+
+void ScRangePairList::Join( const ScRangePair& r, BOOL bIsInList )
+{
+ if ( !Count() )
+ {
+ Append( r );
+ return ;
+ }
+ const ScRange& r1 = r.GetRange(0);
+ const ScRange& r2 = r.GetRange(1);
+ SCCOL nCol1 = r1.aStart.Col();
+ SCROW nRow1 = r1.aStart.Row();
+ SCTAB nTab1 = r1.aStart.Tab();
+ SCCOL nCol2 = r1.aEnd.Col();
+ SCROW nRow2 = r1.aEnd.Row();
+ SCTAB nTab2 = r1.aEnd.Tab();
+ ScRangePair* pOver = (ScRangePair*) &r; // fies aber wahr wenn bInList
+ ULONG nOldPos = 0;
+ if ( bIsInList )
+ { // merken um ggbf. zu loeschen bzw. wiederherzustellen
+ nOldPos = GetPos( pOver );
+ }
+ BOOL bJoinedInput = FALSE;
+ for ( ScRangePair* p = First(); p && pOver; p = Next() )
+ {
+ if ( p == pOver )
+ continue; // derselbe, weiter mit dem naechsten
+ BOOL bJoined = FALSE;
+ ScRange& rp1 = p->GetRange(0);
+ ScRange& rp2 = p->GetRange(1);
+ if ( rp2 == r2 )
+ { // nur wenn Range2 gleich ist
+ if ( rp1.In( r1 ) )
+ { // RangePair r in RangePair p enthalten oder identisch
+ if ( bIsInList )
+ bJoined = TRUE; // weg mit RangePair r
+ else
+ { // das war's dann
+ bJoinedInput = TRUE; // nicht anhaengen
+ break; // for
+ }
+ }
+ else if ( r1.In( rp1 ) )
+ { // RangePair p in RangePair r enthalten, r zum neuen RangePair machen
+ *p = r;
+ bJoined = TRUE;
+ }
+ }
+ if ( !bJoined && rp1.aStart.Tab() == nTab1 && rp1.aEnd.Tab() == nTab2
+ && rp2.aStart.Tab() == r2.aStart.Tab()
+ && rp2.aEnd.Tab() == r2.aEnd.Tab() )
+ { // 2D, Range2 muss genauso nebeneinander liegen wie Range1
+ if ( rp1.aStart.Col() == nCol1 && rp1.aEnd.Col() == nCol2
+ && rp2.aStart.Col() == r2.aStart.Col()
+ && rp2.aEnd.Col() == r2.aEnd.Col() )
+ {
+ if ( rp1.aStart.Row() == nRow2+1
+ && rp2.aStart.Row() == r2.aEnd.Row()+1 )
+ { // oben
+ rp1.aStart.SetRow( nRow1 );
+ rp2.aStart.SetRow( r2.aStart.Row() );
+ bJoined = TRUE;
+ }
+ else if ( rp1.aEnd.Row() == nRow1-1
+ && rp2.aEnd.Row() == r2.aStart.Row()-1 )
+ { // unten
+ rp1.aEnd.SetRow( nRow2 );
+ rp2.aEnd.SetRow( r2.aEnd.Row() );
+ bJoined = TRUE;
+ }
+ }
+ else if ( rp1.aStart.Row() == nRow1 && rp1.aEnd.Row() == nRow2
+ && rp2.aStart.Row() == r2.aStart.Row()
+ && rp2.aEnd.Row() == r2.aEnd.Row() )
+ {
+ if ( rp1.aStart.Col() == nCol2+1
+ && rp2.aStart.Col() == r2.aEnd.Col()+1 )
+ { // links
+ rp1.aStart.SetCol( nCol1 );
+ rp2.aStart.SetCol( r2.aStart.Col() );
+ bJoined = TRUE;
+ }
+ else if ( rp1.aEnd.Col() == nCol1-1
+ && rp2.aEnd.Col() == r2.aEnd.Col()-1 )
+ { // rechts
+ rp1.aEnd.SetCol( nCol2 );
+ rp2.aEnd.SetCol( r2.aEnd.Col() );
+ bJoined = TRUE;
+ }
+ }
+ }
+ if ( bJoined )
+ {
+ if ( bIsInList )
+ { // innerhalb der Liste RangePair loeschen
+ Remove( nOldPos );
+ delete pOver;
+ pOver = NULL;
+ if ( nOldPos )
+ nOldPos--; // Seek richtig aufsetzen
+ }
+ bJoinedInput = TRUE;
+ Join( *p, TRUE ); // rekursiv!
+ }
+ }
+ if ( bIsInList )
+ Seek( nOldPos );
+ else if ( !bJoinedInput )
+ Append( r );
+}
+
+
+BOOL ScRangePairList::operator==( const ScRangePairList& r ) const
+{
+ if ( this == &r )
+ return TRUE; // identische Referenz
+ if ( Count() != r.Count() )
+ return FALSE;
+ ULONG nCnt = Count();
+ for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ )
+ {
+ if ( *GetObject( nIdx ) != *r.GetObject( nIdx ) )
+ return FALSE; // auch andere Reihenfolge ist ungleich
+ }
+ return TRUE;
+}
+
+
+BOOL ScRangePairList::UpdateReference( UpdateRefMode eUpdateRefMode,
+ ScDocument* pDoc, const ScRange& rWhere,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ BOOL bChanged = FALSE;
+ if ( Count() )
+ {
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ for ( ScRangePair* pR = First(); pR; pR = Next() )
+ {
+ for ( USHORT j=0; j<2; j++ )
+ {
+ ScRange& rRange = pR->GetRange(j);
+ SCCOL theCol1;
+ SCROW theRow1;
+ SCTAB theTab1;
+ SCCOL theCol2;
+ SCROW theRow2;
+ SCTAB theTab2;
+ rRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
+ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
+ nDx, nDy, nDz,
+ theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 )
+ != UR_NOTHING )
+ {
+ bChanged = TRUE;
+ rRange.aStart.Set( theCol1, theRow1, theTab1 );
+ rRange.aEnd.Set( theCol2, theRow2, theTab2 );
+ }
+ }
+ }
+ }
+ return bChanged;
+}
+
+
+void ScRangePairList::DeleteOnTab( SCTAB nTab )
+{
+ // Delete entries that have the labels (first range) on nTab
+
+ ULONG nListCount = Count();
+ ULONG nPos = 0;
+ while ( nPos < nListCount )
+ {
+ ScRangePair* pR = GetObject( nPos );
+ ScRange aRange = pR->GetRange(0);
+ if ( aRange.aStart.Tab() == nTab && aRange.aEnd.Tab() == nTab )
+ {
+ Remove( nPos );
+ delete pR;
+ nListCount = Count();
+ }
+ else
+ ++nPos;
+ }
+}
+
+
+ScRangePair* ScRangePairList::Find( const ScAddress& rAdr ) const
+{
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ {
+ ScRangePair* pR = GetObject( j );
+ if ( pR->GetRange(0).In( rAdr ) )
+ return pR;
+ }
+ return NULL;
+}
+
+
+ScRangePair* ScRangePairList::Find( const ScRange& rRange ) const
+{
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ {
+ ScRangePair* pR = GetObject( j );
+ if ( pR->GetRange(0) == rRange )
+ return pR;
+ }
+ return NULL;
+}
+
+
+ScRangePairList* ScRangePairList::Clone() const
+{
+ ScRangePairList* pNew = new ScRangePairList;
+ ULONG nListCount = Count();
+ for ( ULONG j = 0; j < nListCount; j++ )
+ {
+ pNew->Append( *GetObject( j ) );
+ }
+ return pNew;
+}
+
+
+struct ScRangePairNameSort
+{
+ ScRangePair* pPair;
+ ScDocument* pDoc;
+};
+
+
+extern "C" int
+#ifdef WNT
+__cdecl
+#endif
+ScRangePairList_QsortNameCompare( const void* p1, const void* p2 )
+{
+ const ScRangePairNameSort* ps1 = (const ScRangePairNameSort*)p1;
+ const ScRangePairNameSort* ps2 = (const ScRangePairNameSort*)p2;
+ const ScAddress& rStartPos1 = ps1->pPair->GetRange(0).aStart;
+ const ScAddress& rStartPos2 = ps2->pPair->GetRange(0).aStart;
+ String aStr1, aStr2;
+ sal_Int32 nComp;
+ if ( rStartPos1.Tab() == rStartPos2.Tab() )
+ nComp = COMPARE_EQUAL;
+ else
+ {
+ ps1->pDoc->GetName( rStartPos1.Tab(), aStr1 );
+ ps2->pDoc->GetName( rStartPos2.Tab(), aStr2 );
+ nComp = ScGlobal::GetCollator()->compareString( aStr1, aStr2 );
+ }
+ switch ( nComp )
+ {
+ case COMPARE_LESS:
+ return -1;
+ //break;
+ case COMPARE_GREATER:
+ return 1;
+ //break;
+ default:
+ // gleiche Tabs
+ if ( rStartPos1.Col() < rStartPos2.Col() )
+ return -1;
+ if ( rStartPos1.Col() > rStartPos2.Col() )
+ return 1;
+ // gleiche Cols
+ if ( rStartPos1.Row() < rStartPos2.Row() )
+ return -1;
+ if ( rStartPos1.Row() > rStartPos2.Row() )
+ return 1;
+ // erste Ecke gleich, zweite Ecke
+ {
+ const ScAddress& rEndPos1 = ps1->pPair->GetRange(0).aEnd;
+ const ScAddress& rEndPos2 = ps2->pPair->GetRange(0).aEnd;
+ if ( rEndPos1.Tab() == rEndPos2.Tab() )
+ nComp = COMPARE_EQUAL;
+ else
+ {
+ ps1->pDoc->GetName( rEndPos1.Tab(), aStr1 );
+ ps2->pDoc->GetName( rEndPos2.Tab(), aStr2 );
+ nComp = ScGlobal::GetCollator()->compareString( aStr1, aStr2 );
+ }
+ switch ( nComp )
+ {
+ case COMPARE_LESS:
+ return -1;
+ //break;
+ case COMPARE_GREATER:
+ return 1;
+ //break;
+ default:
+ // gleiche Tabs
+ if ( rEndPos1.Col() < rEndPos2.Col() )
+ return -1;
+ if ( rEndPos1.Col() > rEndPos2.Col() )
+ return 1;
+ // gleiche Cols
+ if ( rEndPos1.Row() < rEndPos2.Row() )
+ return -1;
+ if ( rEndPos1.Row() > rEndPos2.Row() )
+ return 1;
+ return 0;
+ }
+ }
+ return 0;
+ }
+ return 0; // just in case
+}
+
+
+ScRangePair** ScRangePairList::CreateNameSortedArray( ULONG& nListCount,
+ ScDocument* pDoc ) const
+{
+ nListCount = Count();
+ DBG_ASSERT( nListCount * sizeof(ScRangePairNameSort) <= (size_t)~0x1F,
+ "ScRangePairList::CreateNameSortedArray nListCount * sizeof(ScRangePairNameSort) > (size_t)~0x1F" );
+ ScRangePairNameSort* pSortArray = (ScRangePairNameSort*)
+ new BYTE [ nListCount * sizeof(ScRangePairNameSort) ];
+ ULONG j;
+ for ( j=0; j < nListCount; j++ )
+ {
+ pSortArray[j].pPair = GetObject( j );
+ pSortArray[j].pDoc = pDoc;
+ }
+#if !(defined(ICC ) && defined(OS2))
+ qsort( (void*)pSortArray, nListCount, sizeof(ScRangePairNameSort), &ScRangePairList_QsortNameCompare );
+#else
+ qsort( (void*)pSortArray, nListCount, sizeof(ScRangePairNameSort), ICCQsortRPairCompare );
+#endif
+ // ScRangePair Pointer aufruecken
+ ScRangePair** ppSortArray = (ScRangePair**)pSortArray;
+ for ( j=0; j < nListCount; j++ )
+ {
+ ppSortArray[j] = pSortArray[j].pPair;
+ }
+ return ppSortArray;
+}
+
+
+
+
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
new file mode 100644
index 000000000000..e81f1f3bd94d
--- /dev/null
+++ b/sc/source/core/tool/rangenam.cxx
@@ -0,0 +1,824 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+#include <string.h>
+#include <memory>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "rangenam.hxx"
+#include "global.hxx"
+#include "compiler.hxx"
+#include "rangeutl.hxx"
+#include "rechead.hxx"
+#include "refupdat.hxx"
+#include "document.hxx"
+
+using namespace formula;
+
+//========================================================================
+// ScRangeData
+//========================================================================
+
+// Interner ctor fuer das Suchen nach einem Index
+
+ScRangeData::ScRangeData( USHORT n )
+ : pCode( NULL ), nIndex( n ), bModified( FALSE ), mnMaxRow(-1), mnMaxCol(-1)
+{}
+
+ScRangeData::ScRangeData( ScDocument* pDok,
+ const String& rName,
+ const String& rSymbol,
+ const ScAddress& rAddress,
+ RangeType nType,
+ const FormulaGrammar::Grammar eGrammar ) :
+ aName ( rName ),
+ aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
+ pCode ( NULL ),
+ aPos ( rAddress ),
+ eType ( nType ),
+ pDoc ( pDok ),
+ nIndex ( 0 ),
+ bModified ( FALSE ),
+ mnMaxRow (-1),
+ mnMaxCol (-1)
+{
+ if (rSymbol.Len() > 0)
+ {
+ ScCompiler aComp( pDoc, aPos );
+ aComp.SetGrammar(eGrammar);
+ pCode = aComp.CompileString( rSymbol );
+ if( !pCode->GetCodeError() )
+ {
+ pCode->Reset();
+ FormulaToken* p = pCode->GetNextReference();
+ if( p )// genau eine Referenz als erstes
+ {
+ if( p->GetType() == svSingleRef )
+ eType = eType | RT_ABSPOS;
+ else
+ eType = eType | RT_ABSAREA;
+ }
+ // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
+ // Dies ist fuer die manuelle Eingabe
+ aComp.CompileTokenArray();
+ pCode->DelRPN();
+ }
+ }
+ else
+ {
+ // #i63513#/#i65690# don't leave pCode as NULL.
+ // Copy ctor default-constructs pCode if it was NULL, so it's initialized here, too,
+ // to ensure same behavior if unnecessary copying is left out.
+
+ pCode = new ScTokenArray();
+ }
+}
+
+ScRangeData::ScRangeData( ScDocument* pDok,
+ const String& rName,
+ const ScTokenArray& rArr,
+ const ScAddress& rAddress,
+ RangeType nType ) :
+ aName ( rName ),
+ aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
+ pCode ( new ScTokenArray( rArr ) ),
+ aPos ( rAddress ),
+ eType ( nType ),
+ pDoc ( pDok ),
+ nIndex ( 0 ),
+ bModified ( FALSE ),
+ mnMaxRow (-1),
+ mnMaxCol (-1)
+{
+ if( !pCode->GetCodeError() )
+ {
+ pCode->Reset();
+ FormulaToken* p = pCode->GetNextReference();
+ if( p )// genau eine Referenz als erstes
+ {
+ if( p->GetType() == svSingleRef )
+ eType = eType | RT_ABSPOS;
+ else
+ eType = eType | RT_ABSAREA;
+ }
+ // Die Importfilter haben diesen Test nicht,
+ // da die benannten Bereiche z.T. noch unvollstaendig sind.
+// if( !pCode->GetCodeLen() )
+// {
+// // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
+// ScCompiler aComp( pDok, aPos, *pCode );
+// aComp.CompileTokenArray();
+// pCode->DelRPN();
+// }
+ }
+}
+
+ScRangeData::ScRangeData( ScDocument* pDok,
+ const String& rName,
+ const ScAddress& rTarget ) :
+ aName ( rName ),
+ aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
+ pCode ( new ScTokenArray() ),
+ aPos ( rTarget ),
+ eType ( RT_NAME ),
+ pDoc ( pDok ),
+ nIndex ( 0 ),
+ bModified ( FALSE ),
+ mnMaxRow (-1),
+ mnMaxCol (-1)
+{
+ ScSingleRefData aRefData;
+ aRefData.InitAddress( rTarget );
+ aRefData.SetFlag3D( TRUE );
+ pCode->AddSingleReference( aRefData );
+ ScCompiler aComp( pDoc, aPos, *pCode );
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.CompileTokenArray();
+ if ( !pCode->GetCodeError() )
+ eType |= RT_ABSPOS;
+}
+
+ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
+ ScDataObject(),
+ aName (rScRangeData.aName),
+ aUpperName (rScRangeData.aUpperName),
+ pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()), // echte Kopie erzeugen (nicht copy-ctor)
+ aPos (rScRangeData.aPos),
+ eType (rScRangeData.eType),
+ pDoc (rScRangeData.pDoc),
+ nIndex (rScRangeData.nIndex),
+ bModified (rScRangeData.bModified),
+ mnMaxRow (rScRangeData.mnMaxRow),
+ mnMaxCol (rScRangeData.mnMaxCol)
+{}
+
+ScRangeData::~ScRangeData()
+{
+ delete pCode;
+}
+
+ScDataObject* ScRangeData::Clone() const
+{
+ return new ScRangeData(*this);
+}
+
+void ScRangeData::GuessPosition()
+{
+ // setzt eine Position, mit der alle relative Referenzen bei CalcAbsIfRel
+ // ohne Fehler verabsolutiert werden koennen
+
+ DBG_ASSERT(aPos == ScAddress(), "die Position geht jetzt verloren");
+
+ SCsCOL nMinCol = 0;
+ SCsROW nMinRow = 0;
+ SCsTAB nMinTab = 0;
+
+ ScToken* t;
+ pCode->Reset();
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsColRel() && rRef1.nRelCol < nMinCol )
+ nMinCol = rRef1.nRelCol;
+ if ( rRef1.IsRowRel() && rRef1.nRelRow < nMinRow )
+ nMinRow = rRef1.nRelRow;
+ if ( rRef1.IsTabRel() && rRef1.nRelTab < nMinTab )
+ nMinTab = rRef1.nRelTab;
+
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsColRel() && rRef2.nRelCol < nMinCol )
+ nMinCol = rRef2.nRelCol;
+ if ( rRef2.IsRowRel() && rRef2.nRelRow < nMinRow )
+ nMinRow = rRef2.nRelRow;
+ if ( rRef2.IsTabRel() && rRef2.nRelTab < nMinTab )
+ nMinTab = rRef2.nRelTab;
+ }
+ }
+
+ aPos = ScAddress( (SCCOL)(-nMinCol), (SCROW)(-nMinRow), (SCTAB)(-nMinTab) );
+
+ //! Test
+// DBG_ERROR(String("Pos ")+String((SCCOL)(-nMinCol))+String("/")+
+// String((SCROW)(-nMinRow))+String("/")+String((SCTAB)(-nMinTab)));
+}
+
+void ScRangeData::GetSymbol( String& rSymbol, const FormulaGrammar::Grammar eGrammar ) const
+{
+ ScCompiler aComp(pDoc, aPos, *pCode);
+ aComp.SetGrammar(eGrammar);
+ aComp.CreateStringFromTokenArray( rSymbol );
+}
+
+void ScRangeData::UpdateSymbol( rtl::OUStringBuffer& rBuffer, const ScAddress& rPos,
+ const FormulaGrammar::Grammar eGrammar )
+{
+ ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
+ ScCompiler aComp( pDoc, rPos, *pTemp.get());
+ aComp.SetGrammar(eGrammar);
+ aComp.MoveRelWrap(GetMaxCol(), GetMaxRow());
+ aComp.CreateStringFromTokenArray( rBuffer );
+}
+
+void ScRangeData::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& r,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ BOOL bChanged = FALSE;
+
+ pCode->Reset();
+ if( pCode->GetNextReference() )
+ {
+ BOOL bSharedFormula = ((eType & RT_SHARED) == RT_SHARED);
+ ScCompiler aComp( pDoc, aPos, *pCode );
+ aComp.SetGrammar(pDoc->GetGrammar());
+ const BOOL bRelRef = aComp.UpdateNameReference( eUpdateRefMode, r,
+ nDx, nDy, nDz,
+ bChanged, bSharedFormula);
+ if (bSharedFormula)
+ {
+ if (bRelRef)
+ eType = eType | RT_SHAREDMOD;
+ else
+ eType = eType & ~RT_SHAREDMOD;
+ }
+ }
+
+ bModified = bChanged;
+}
+
+
+void ScRangeData::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
+{
+ BOOL bChanged = FALSE;
+
+ ScToken* t;
+ pCode->Reset();
+
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ if( t->GetType() != svIndex )
+ {
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
+ (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
+ ( t->GetType() == svSingleRef ||
+ (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
+ (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
+ {
+ if ( ScRefUpdate::UpdateTranspose( pDoc, rSource, rDest, rRef ) != UR_NOTHING )
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ bModified = bChanged;
+}
+
+void ScRangeData::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
+{
+ BOOL bChanged = FALSE;
+
+ ScToken* t;
+ pCode->Reset();
+
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ if( t->GetType() != svIndex )
+ {
+ SingleDoubleRefModifier aMod( *t );
+ ScComplexRefData& rRef = aMod.Ref();
+ if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
+ (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
+ ( t->GetType() == svSingleRef ||
+ (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
+ (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
+ {
+ if ( ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY, rRef ) != UR_NOTHING )
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ bModified = bChanged; // muss direkt hinterher ausgewertet werden
+}
+
+BOOL ScRangeData::operator== (const ScRangeData& rData) const // fuer Undo
+{
+ if ( nIndex != rData.nIndex ||
+ aName != rData.aName ||
+ aPos != rData.aPos ||
+ eType != rData.eType ) return FALSE;
+
+ USHORT nLen = pCode->GetLen();
+ if ( nLen != rData.pCode->GetLen() ) return FALSE;
+
+ FormulaToken** ppThis = pCode->GetArray();
+ FormulaToken** ppOther = rData.pCode->GetArray();
+
+ for ( USHORT i=0; i<nLen; i++ )
+ if ( ppThis[i] != ppOther[i] && !(*ppThis[i] == *ppOther[i]) )
+ return FALSE;
+
+ return TRUE;
+}
+
+//UNUSED2009-05 BOOL ScRangeData::IsRangeAtCursor( const ScAddress& rPos, BOOL bStartOnly ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 BOOL bRet = FALSE;
+//UNUSED2009-05 ScRange aRange;
+//UNUSED2009-05 if ( IsReference(aRange) )
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( bStartOnly )
+//UNUSED2009-05 bRet = ( rPos == aRange.aStart );
+//UNUSED2009-05 else
+//UNUSED2009-05 bRet = ( aRange.In( rPos ) );
+//UNUSED2009-05 }
+//UNUSED2009-05 return bRet;
+//UNUSED2009-05 }
+
+BOOL ScRangeData::IsRangeAtBlock( const ScRange& rBlock ) const
+{
+ BOOL bRet = FALSE;
+ ScRange aRange;
+ if ( IsReference(aRange) )
+ bRet = ( rBlock == aRange );
+ return bRet;
+}
+
+BOOL ScRangeData::IsReference( ScRange& rRange ) const
+{
+ if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS )) && pCode )
+ return pCode->IsReference( rRange );
+
+ return FALSE;
+}
+
+BOOL ScRangeData::IsReference( ScRange& rRange, const ScAddress& rPos ) const
+{
+ if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
+ {
+ ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
+ ScCompiler aComp( pDoc, rPos, *pTemp);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.MoveRelWrap(MAXCOL, MAXROW);
+ return pTemp->IsReference( rRange );
+ }
+
+ return FALSE;
+}
+
+BOOL ScRangeData::IsValidReference( ScRange& rRange ) const
+{
+ if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
+ return pCode->IsValidReference( rRange );
+
+ return FALSE;
+}
+
+void ScRangeData::UpdateTabRef(SCTAB nOldTable, USHORT nFlag, SCTAB nNewTable)
+{
+ pCode->Reset();
+ if( pCode->GetNextReference() )
+ {
+ ScRangeData* pRangeData = NULL; // must not be dereferenced
+ BOOL bChanged;
+ ScCompiler aComp( pDoc, aPos, *pCode);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ switch (nFlag)
+ {
+ case 1: // einfache InsertTab (doc.cxx)
+ pRangeData = aComp.UpdateInsertTab(nOldTable, TRUE ); // und CopyTab (doc2.cxx)
+ break;
+ case 2: // einfaches delete (doc.cxx)
+ pRangeData = aComp.UpdateDeleteTab(nOldTable, FALSE, TRUE, bChanged);
+ break;
+ case 3: // move (doc2.cxx)
+ {
+ pRangeData = aComp.UpdateMoveTab(nOldTable, nNewTable, TRUE );
+ }
+ break;
+ default:
+ {
+ DBG_ERROR("ScRangeName::UpdateTabRef: Unknown Flag");
+ }
+ break;
+ }
+ if (eType&RT_SHARED)
+ {
+ if (pRangeData)
+ eType = eType | RT_SHAREDMOD;
+ else
+ eType = eType & ~RT_SHAREDMOD;
+ }
+ }
+}
+
+
+void ScRangeData::MakeValidName( String& rName ) // static
+{
+ //ScCompiler::InitSymbolsNative();
+
+ // strip leading invalid characters
+ xub_StrLen nPos = 0;
+ xub_StrLen nLen = rName.Len();
+ while ( nPos < nLen && !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME) )
+ ++nPos;
+ if ( nPos>0 )
+ rName.Erase(0,nPos);
+
+ // if the first character is an invalid start character, precede with '_'
+ if ( rName.Len() && !ScCompiler::IsCharFlagAllConventions( rName, 0, SC_COMPILER_C_CHAR_NAME ) )
+ rName.Insert('_',0);
+
+ // replace invalid with '_'
+ nLen = rName.Len();
+ for (nPos=0; nPos<nLen; nPos++)
+ {
+ if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME) )
+ rName.SetChar( nPos, '_' );
+ }
+
+ // Ensure that the proposed name is not a reference under any convention,
+ // same as in IsNameValid()
+ ScAddress aAddr;
+ ScRange aRange;
+ for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
+ {
+ ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
+ // Don't check Parse on VALID, any partial only VALID may result in
+ // #REF! during compile later!
+ while (aRange.Parse( rName, NULL, details) || aAddr.Parse( rName, NULL, details))
+ {
+ //! Range Parse is partially valid also with invalid sheet name,
+ //! Address Parse dito, during compile name would generate a #REF!
+ if ( rName.SearchAndReplace( '.', '_' ) == STRING_NOTFOUND )
+ rName.Insert('_',0);
+ }
+ }
+}
+
+BOOL ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
+{
+ /* XXX If changed, sc/source/filter/ftools/ftools.cxx
+ * ScfTools::ConvertToScDefinedName needs to be changed too. */
+ xub_StrLen nPos = 0;
+ xub_StrLen nLen = rName.Len();
+ if ( !nLen || !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_CHAR_NAME ) )
+ return FALSE;
+ while ( nPos < nLen )
+ {
+ if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_NAME ) )
+ return FALSE;
+ }
+ ScAddress aAddr;
+ ScRange aRange;
+ for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
+ {
+ ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
+ // Don't check Parse on VALID, any partial only VALID may result in
+ // #REF! during compile later!
+ if (aRange.Parse( rName, pDoc, details) || aAddr.Parse( rName, pDoc, details))
+ return FALSE;
+ }
+ 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()
+{
+ return pCode ? pCode->GetCodeError() : 0;
+}
+
+BOOL ScRangeData::HasReferences() const
+{
+ pCode->Reset();
+ return BOOL( pCode->GetNextReference() != NULL );
+}
+
+// bei TransferTab von einem in ein anderes Dokument anpassen,
+// um Referenzen auf die eigene Tabelle mitzubekommen
+
+void ScRangeData::TransferTabRef( SCTAB nOldTab, SCTAB nNewTab )
+{
+ long nTabDiff = (long)nNewTab - nOldTab;
+ long nPosDiff = (long)nNewTab - aPos.Tab();
+ aPos.SetTab( nNewTab );
+ ScToken* t;
+ pCode->Reset();
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsTabRel() )
+ rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nPosDiff );
+ else
+ rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nTabDiff );
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsTabRel() )
+ rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nPosDiff );
+ else
+ rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nTabDiff );
+ }
+ }
+}
+
+void ScRangeData::ReplaceRangeNamesInUse( const IndexMap& rMap )
+{
+ bool bCompile = false;
+ for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
+ {
+ if ( p->GetOpCode() == ocName )
+ {
+ const sal_uInt16 nOldIndex = p->GetIndex();
+ IndexMap::const_iterator itr = rMap.find(nOldIndex);
+ const sal_uInt16 nNewIndex = itr == rMap.end() ? nOldIndex : itr->second;
+ if ( nOldIndex != nNewIndex )
+ {
+ p->SetIndex( nNewIndex );
+ bCompile = true;
+ }
+ }
+ }
+ if ( bCompile )
+ {
+ ScCompiler aComp( pDoc, aPos, *pCode);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.CompileTokenArray();
+ }
+}
+
+
+void ScRangeData::ValidateTabRefs()
+{
+ // try to make sure all relative references and the reference position
+ // are within existing tables, so they can be represented as text
+ // (if the range of used tables is more than the existing tables,
+ // the result may still contain invalid tables, because the relative
+ // references aren't changed so formulas stay the same)
+
+ // find range of used tables
+
+ SCTAB nMinTab = aPos.Tab();
+ SCTAB nMaxTab = nMinTab;
+ ScToken* t;
+ pCode->Reset();
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
+ {
+ if ( rRef1.nTab < nMinTab )
+ nMinTab = rRef1.nTab;
+ if ( rRef1.nTab > nMaxTab )
+ nMaxTab = rRef1.nTab;
+ }
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
+ {
+ if ( rRef2.nTab < nMinTab )
+ nMinTab = rRef2.nTab;
+ if ( rRef2.nTab > nMaxTab )
+ nMaxTab = rRef2.nTab;
+ }
+ }
+ }
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nMaxTab >= nTabCount && nMinTab > 0 )
+ {
+ // move position and relative tab refs
+ // The formulas that use the name are not changed by this
+
+ SCTAB nMove = nMinTab;
+ aPos.SetTab( aPos.Tab() - nMove );
+
+ pCode->Reset();
+ while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
+ {
+ ScSingleRefData& rRef1 = t->GetSingleRef();
+ if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
+ rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab - nMove );
+ if ( t->GetType() == svDoubleRef )
+ {
+ ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
+ if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
+ rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab - nMove );
+ }
+ }
+ }
+}
+
+
+extern "C" int
+#ifdef WNT
+__cdecl
+#endif
+ScRangeData_QsortNameCompare( const void* p1, const void* p2 )
+{
+ return (int) ScGlobal::GetCollator()->compareString(
+ (*(const ScRangeData**)p1)->GetName(),
+ (*(const ScRangeData**)p2)->GetName() );
+}
+
+
+//========================================================================
+// ScRangeName
+//========================================================================
+
+ScRangeName::ScRangeName(const ScRangeName& rScRangeName, ScDocument* pDocument) :
+ ScSortedCollection ( rScRangeName ),
+ pDoc ( pDocument ),
+ nSharedMaxIndex (rScRangeName.nSharedMaxIndex)
+{
+ for (USHORT i = 0; i < nCount; i++)
+ {
+ ((ScRangeData*)At(i))->SetDocument(pDocument);
+ ((ScRangeData*)At(i))->SetIndex(((ScRangeData*)rScRangeName.At(i))->GetIndex());
+ }
+}
+
+short ScRangeName::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ USHORT i1 = ((ScRangeData*)pKey1)->GetIndex();
+ USHORT i2 = ((ScRangeData*)pKey2)->GetIndex();
+ return (short) i1 - (short) i2;
+}
+
+BOOL ScRangeName::SearchNameUpper( const String& rUpperName, USHORT& rIndex ) const
+{
+ // SearchNameUpper must be called with an upper-case search string
+
+ USHORT i = 0;
+ while (i < nCount)
+ {
+ if ( ((*this)[i])->GetUpperName() == rUpperName )
+ {
+ rIndex = i;
+ return TRUE;
+ }
+ i++;
+ }
+ return FALSE;
+}
+
+BOOL ScRangeName::SearchName( const String& rName, USHORT& rIndex ) const
+{
+ if ( nCount > 0 )
+ return SearchNameUpper( ScGlobal::pCharClass->upper( rName ), rIndex );
+ else
+ return FALSE;
+}
+
+void ScRangeName::UpdateReference( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
+{
+ for (USHORT i=0; i<nCount; i++)
+ ((ScRangeData*)pItems[i])->UpdateReference(eUpdateRefMode, rRange,
+ nDx, nDy, nDz);
+}
+
+void ScRangeName::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
+{
+ for (USHORT i=0; i<nCount; i++)
+ ((ScRangeData*)pItems[i])->UpdateTranspose( rSource, rDest );
+}
+
+void ScRangeName::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
+{
+ for (USHORT i=0; i<nCount; i++)
+ ((ScRangeData*)pItems[i])->UpdateGrow( rArea, nGrowX, nGrowY );
+}
+
+BOOL ScRangeName::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return *(ScRangeData*)pKey1 == *(ScRangeData*)pKey2;
+}
+
+BOOL ScRangeName::Insert(ScDataObject* pScDataObject)
+{
+ if (!((ScRangeData*)pScDataObject)->GetIndex()) // schon gesetzt?
+ {
+ ((ScRangeData*)pScDataObject)->SetIndex( GetEntryIndex() );
+ }
+
+ return ScSortedCollection::Insert(pScDataObject);
+}
+
+// Suche nach einem freien Index
+
+USHORT ScRangeName::GetEntryIndex()
+{
+ USHORT nLast = 0;
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ USHORT nIdx = ((ScRangeData*)pItems[i])->GetIndex();
+ if( nIdx > nLast )
+ {
+ nLast = nIdx;
+ }
+ }
+ return nLast + 1;
+}
+
+ScRangeData* ScRangeName::FindIndex( USHORT nIndex )
+{
+ ScRangeData aDataObj( nIndex );
+ USHORT n;
+ if( Search( &aDataObj, n ) )
+ return (*this)[ n ];
+ else
+ return NULL;
+}
+
+//UNUSED2009-05 ScRangeData* ScRangeName::GetRangeAtCursor( const ScAddress& rPos, BOOL bStartOnly ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( pItems )
+//UNUSED2009-05 {
+//UNUSED2009-05 for ( USHORT i = 0; i < nCount; i++ )
+//UNUSED2009-05 if ( ((ScRangeData*)pItems[i])->IsRangeAtCursor( rPos, bStartOnly ) )
+//UNUSED2009-05 return (ScRangeData*)pItems[i];
+//UNUSED2009-05 }
+//UNUSED2009-05 return NULL;
+//UNUSED2009-05 }
+
+ScRangeData* ScRangeName::GetRangeAtBlock( const ScRange& rBlock ) const
+{
+ if ( pItems )
+ {
+ for ( USHORT i = 0; i < nCount; i++ )
+ if ( ((ScRangeData*)pItems[i])->IsRangeAtBlock( rBlock ) )
+ return (ScRangeData*)pItems[i];
+ }
+ return NULL;
+}
+
+void ScRangeName::UpdateTabRef(SCTAB nOldTable, USHORT nFlag, SCTAB nNewTable)
+{
+ for (USHORT i=0; i<nCount; i++)
+ ((ScRangeData*)pItems[i])->UpdateTabRef(nOldTable, nFlag, nNewTable);
+}
+
+
+
+
diff --git a/sc/source/core/tool/rangeseq.cxx b/sc/source/core/tool/rangeseq.cxx
new file mode 100644
index 000000000000..5584fb1c37e2
--- /dev/null
+++ b/sc/source/core/tool/rangeseq.cxx
@@ -0,0 +1,476 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svl/zforlist.hxx>
+#include <rtl/math.hxx>
+#include <tools/debug.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "rangeseq.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include "cell.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+long lcl_DoubleToLong( double fVal )
+{
+ double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) :
+ ::rtl::math::approxCeil( fVal );
+ if ( fInt >= LONG_MIN && fInt <= LONG_MAX )
+ return (long)fInt;
+ else
+ return 0; // out of range
+}
+
+BOOL ScRangeToSequence::FillLongArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col();
+ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row();
+
+ uno::Sequence< uno::Sequence<INT32> > aRowSeq( nRowCount );
+ uno::Sequence<INT32>* pRowAry = aRowSeq.getArray();
+ for (long nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<INT32> aColSeq( nColCount );
+ INT32* pColAry = aColSeq.getArray();
+ for (long nCol = 0; nCol < nColCount; nCol++)
+ pColAry[nCol] = lcl_DoubleToLong( pDoc->GetValue(
+ ScAddress( (SCCOL)(nStartCol+nCol), (SCROW)(nStartRow+nRow), nTab ) ) );
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE; //! check for errors
+}
+
+
+BOOL ScRangeToSequence::FillLongArray( uno::Any& rAny, const ScMatrix* pMatrix )
+{
+ if (!pMatrix)
+ return FALSE;
+
+ SCSIZE nColCount;
+ SCSIZE nRowCount;
+ pMatrix->GetDimensions( nColCount, nRowCount );
+
+ uno::Sequence< uno::Sequence<INT32> > aRowSeq( static_cast<sal_Int32>(nRowCount) );
+ uno::Sequence<INT32>* pRowAry = aRowSeq.getArray();
+ for (SCSIZE nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<INT32> aColSeq( static_cast<sal_Int32>(nColCount) );
+ INT32* pColAry = aColSeq.getArray();
+ for (SCSIZE nCol = 0; nCol < nColCount; nCol++)
+ if ( pMatrix->IsString( nCol, nRow ) )
+ pColAry[nCol] = 0;
+ else
+ pColAry[nCol] = lcl_DoubleToLong( pMatrix->GetDouble( nCol, nRow ) );
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeToSequence::FillDoubleArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col();
+ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row();
+
+ uno::Sequence< uno::Sequence<double> > aRowSeq( nRowCount );
+ uno::Sequence<double>* pRowAry = aRowSeq.getArray();
+ for (long nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<double> aColSeq( nColCount );
+ double* pColAry = aColSeq.getArray();
+ for (long nCol = 0; nCol < nColCount; nCol++)
+ pColAry[nCol] = pDoc->GetValue(
+ ScAddress( (SCCOL)(nStartCol+nCol), (SCROW)(nStartRow+nRow), nTab ) );
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE; //! check for errors
+}
+
+
+BOOL ScRangeToSequence::FillDoubleArray( uno::Any& rAny, const ScMatrix* pMatrix )
+{
+ if (!pMatrix)
+ return FALSE;
+
+ SCSIZE nColCount;
+ SCSIZE nRowCount;
+ pMatrix->GetDimensions( nColCount, nRowCount );
+
+ uno::Sequence< uno::Sequence<double> > aRowSeq( static_cast<sal_Int32>(nRowCount) );
+ uno::Sequence<double>* pRowAry = aRowSeq.getArray();
+ for (SCSIZE nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<double> aColSeq( static_cast<sal_Int32>(nColCount) );
+ double* pColAry = aColSeq.getArray();
+ for (SCSIZE nCol = 0; nCol < nColCount; nCol++)
+ if ( pMatrix->IsString( nCol, nRow ) )
+ pColAry[nCol] = 0.0;
+ else
+ pColAry[nCol] = pMatrix->GetDouble( nCol, nRow );
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeToSequence::FillStringArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col();
+ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row();
+
+ String aDocStr;
+
+ uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( nRowCount );
+ uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray();
+ for (long nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<rtl::OUString> aColSeq( nColCount );
+ rtl::OUString* pColAry = aColSeq.getArray();
+ for (long nCol = 0; nCol < nColCount; nCol++)
+ {
+ pDoc->GetString( (SCCOL)(nStartCol+nCol), (SCROW)(nStartRow+nRow), nTab, aDocStr );
+ pColAry[nCol] = rtl::OUString( aDocStr );
+ }
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE; //! check for errors
+}
+
+
+BOOL ScRangeToSequence::FillStringArray( uno::Any& rAny, const ScMatrix* pMatrix,
+ SvNumberFormatter* pFormatter )
+{
+ if (!pMatrix)
+ return FALSE;
+
+ SCSIZE nColCount;
+ SCSIZE nRowCount;
+ pMatrix->GetDimensions( nColCount, nRowCount );
+
+ uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( static_cast<sal_Int32>(nRowCount) );
+ uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray();
+ for (SCSIZE nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<rtl::OUString> aColSeq( static_cast<sal_Int32>(nColCount) );
+ rtl::OUString* pColAry = aColSeq.getArray();
+ for (SCSIZE nCol = 0; nCol < nColCount; nCol++)
+ {
+ String aStr;
+ if ( pMatrix->IsString( nCol, nRow ) )
+ {
+ if ( !pMatrix->IsEmpty( nCol, nRow ) )
+ aStr = pMatrix->GetString( nCol, nRow );
+ }
+ else if ( pFormatter )
+ {
+ double fVal = pMatrix->GetDouble( nCol, nRow );
+ Color* pColor;
+ pFormatter->GetOutputString( fVal, 0, aStr, &pColor );
+ }
+ pColAry[nCol] = rtl::OUString( aStr );
+ }
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+double lcl_GetValueFromCell( ScBaseCell& rCell )
+{
+ //! ScBaseCell member function?
+
+ CellType eType = rCell.GetCellType();
+ if ( eType == CELLTYPE_VALUE )
+ return ((ScValueCell&)rCell).GetValue();
+ else if ( eType == CELLTYPE_FORMULA )
+ return ((ScFormulaCell&)rCell).GetValue(); // called only if result is value
+
+ DBG_ERROR( "GetValueFromCell: wrong type" );
+ return 0;
+}
+
+BOOL ScRangeToSequence::FillMixedArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange,
+ BOOL bAllowNV )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col();
+ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row();
+
+ String aDocStr;
+ BOOL bHasErrors = FALSE;
+
+ uno::Sequence< uno::Sequence<uno::Any> > aRowSeq( nRowCount );
+ uno::Sequence<uno::Any>* pRowAry = aRowSeq.getArray();
+ for (long nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<uno::Any> aColSeq( nColCount );
+ uno::Any* pColAry = aColSeq.getArray();
+ for (long nCol = 0; nCol < nColCount; nCol++)
+ {
+ uno::Any& rElement = pColAry[nCol];
+
+ ScAddress aPos( (SCCOL)(nStartCol+nCol), (SCROW)(nStartRow+nRow), nTab );
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+ if ( pCell )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA &&
+ ((ScFormulaCell*)pCell)->GetErrCode() != 0 )
+ {
+ // if NV is allowed, leave empty for errors
+ bHasErrors = TRUE;
+ }
+ else if ( pCell->HasValueData() )
+ rElement <<= (double) lcl_GetValueFromCell( *pCell );
+ else
+ rElement <<= rtl::OUString( pCell->GetStringData() );
+ }
+ else
+ rElement <<= rtl::OUString(); // empty: empty string
+ }
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return bAllowNV || !bHasErrors;
+}
+
+
+BOOL ScRangeToSequence::FillMixedArray( uno::Any& rAny, const ScMatrix* pMatrix, bool bDataTypes )
+{
+ if (!pMatrix)
+ return FALSE;
+
+ SCSIZE nColCount;
+ SCSIZE nRowCount;
+ pMatrix->GetDimensions( nColCount, nRowCount );
+
+ uno::Sequence< uno::Sequence<uno::Any> > aRowSeq( static_cast<sal_Int32>(nRowCount) );
+ uno::Sequence<uno::Any>* pRowAry = aRowSeq.getArray();
+ for (SCSIZE nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<uno::Any> aColSeq( static_cast<sal_Int32>(nColCount) );
+ uno::Any* pColAry = aColSeq.getArray();
+ for (SCSIZE nCol = 0; nCol < nColCount; nCol++)
+ {
+ if ( pMatrix->IsString( nCol, nRow ) )
+ {
+ String aStr;
+ if ( !pMatrix->IsEmpty( nCol, nRow ) )
+ aStr = pMatrix->GetString( nCol, nRow );
+ pColAry[nCol] <<= rtl::OUString( aStr );
+ }
+ else
+ {
+ double fVal = pMatrix->GetDouble( nCol, nRow );
+ if (bDataTypes && pMatrix->IsBoolean( nCol, nRow ))
+ pColAry[nCol] <<= (fVal ? true : false);
+ else
+ pColAry[nCol] <<= fVal;
+ }
+ }
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ rAny <<= aRowSeq;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+// static
+bool ScApiTypeConversion::ConvertAnyToDouble( double & o_fVal,
+ com::sun::star::uno::TypeClass & o_eClass,
+ const com::sun::star::uno::Any & rAny )
+{
+ bool bRet = false;
+ o_eClass = rAny.getValueTypeClass();
+ switch (o_eClass)
+ {
+ //! extract integer values
+ case uno::TypeClass_ENUM:
+ case uno::TypeClass_BOOLEAN:
+ case uno::TypeClass_CHAR:
+ case uno::TypeClass_BYTE:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_UNSIGNED_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_UNSIGNED_LONG:
+ case uno::TypeClass_FLOAT:
+ case uno::TypeClass_DOUBLE:
+ rAny >>= o_fVal;
+ bRet = true;
+ break;
+ default:
+ ; // nothing, avoid warning
+ }
+ if (!bRet)
+ o_fVal = 0.0;
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+// static
+ScMatrixRef ScSequenceToMatrix::CreateMixedMatrix( const com::sun::star::uno::Any & rAny )
+{
+ ScMatrixRef xMatrix;
+ uno::Sequence< uno::Sequence< uno::Any > > aSequence;
+ if ( rAny >>= aSequence )
+ {
+ sal_Int32 nRowCount = aSequence.getLength();
+ const uno::Sequence<uno::Any>* pRowArr = aSequence.getConstArray();
+ sal_Int32 nMaxColCount = 0;
+ sal_Int32 nCol, nRow;
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ sal_Int32 nTmp = pRowArr[nRow].getLength();
+ if ( nTmp > nMaxColCount )
+ nMaxColCount = nTmp;
+ }
+ if ( nMaxColCount && nRowCount )
+ {
+ rtl::OUString aUStr;
+ xMatrix = new ScMatrix(
+ static_cast<SCSIZE>(nMaxColCount),
+ static_cast<SCSIZE>(nRowCount) );
+ ScMatrix* pMatrix = xMatrix;
+ SCSIZE nCols, nRows;
+ pMatrix->GetDimensions( nCols, nRows);
+ if (nCols != static_cast<SCSIZE>(nMaxColCount) || nRows != static_cast<SCSIZE>(nRowCount))
+ {
+ DBG_ERRORFILE( "ScSequenceToMatrix::CreateMixedMatrix: matrix exceeded max size, returning NULL matrix");
+ return NULL;
+ }
+ for (nRow=0; nRow<nRowCount; nRow++)
+ {
+ sal_Int32 nColCount = pRowArr[nRow].getLength();
+ const uno::Any* pColArr = pRowArr[nRow].getConstArray();
+ for (nCol=0; nCol<nColCount; nCol++)
+ {
+ double fVal;
+ uno::TypeClass eClass;
+ if (ScApiTypeConversion::ConvertAnyToDouble( fVal, eClass, pColArr[nCol]))
+ {
+ if (eClass == uno::TypeClass_BOOLEAN)
+ pMatrix->PutBoolean( (fVal ? true : false),
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ else
+ pMatrix->PutDouble( fVal,
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ }
+ else
+ {
+ // Try string, else use empty as last resort.
+
+ //Reflection* pRefl = pColArr[nCol].getReflection();
+ //if ( pRefl->equals( *OUString_getReflection() ) )
+ if ( pColArr[nCol] >>= aUStr )
+ pMatrix->PutString( String( aUStr ),
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ else
+ pMatrix->PutEmpty(
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ }
+ }
+ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+ {
+ pMatrix->PutEmpty(
+ static_cast<SCSIZE>(nCol),
+ static_cast<SCSIZE>(nRow) );
+ }
+ }
+ }
+ }
+ return xMatrix;
+}
+
+
+//------------------------------------------------------------------------
+
+BOOL ScByteSequenceToString::GetString( String& rString, const uno::Any& rAny,
+ sal_uInt16 nEncoding )
+{
+ uno::Sequence<sal_Int8> aSeq;
+ if ( rAny >>= aSeq )
+ {
+ rString = String( (const sal_Char*)aSeq.getConstArray(),
+ (xub_StrLen)aSeq.getLength(), nEncoding );
+ rString.EraseTrailingChars( (sal_Unicode) 0 );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
diff --git a/sc/source/core/tool/rangeutl.cxx b/sc/source/core/tool/rangeutl.cxx
new file mode 100644
index 000000000000..9f6526a54cf6
--- /dev/null
+++ b/sc/source/core/tool/rangeutl.cxx
@@ -0,0 +1,1054 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/debug.hxx>
+
+#include "rangeutl.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "convuno.hxx"
+#include "externalrefmgr.hxx"
+#include "compiler.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::formula::FormulaGrammar;
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeUtil::MakeArea( const String& rAreaStr,
+ ScArea& rArea,
+ ScDocument* pDoc,
+ SCTAB nTab,
+ ScAddress::Details const & rDetails ) const
+{
+ // Eingabe in rAreaStr: "$Tabelle1.$A1:$D17"
+
+ // BROKEN BROKEN BROKEN
+ // but it is only used in the consolidate dialog. Ignore for now.
+
+ BOOL nSuccess = FALSE;
+ USHORT nPointPos = rAreaStr.Search('.');
+ USHORT nColonPos = rAreaStr.Search(':');
+ String aStrArea( rAreaStr );
+ ScRefAddress startPos;
+ ScRefAddress endPos;
+
+ if ( nColonPos == STRING_NOTFOUND )
+ if ( nPointPos != STRING_NOTFOUND )
+ {
+ aStrArea += ':';
+ aStrArea += rAreaStr.Copy( nPointPos+1 ); // '.' nicht mitkopieren
+ }
+
+ nSuccess = ConvertDoubleRef( pDoc, aStrArea, nTab, startPos, endPos, rDetails );
+
+ if ( nSuccess )
+ rArea = ScArea( startPos.Tab(),
+ startPos.Col(), startPos.Row(),
+ endPos.Col(), endPos.Row() );
+
+ return nSuccess;
+}
+
+//------------------------------------------------------------------------
+
+void ScRangeUtil::CutPosString( const String& theAreaStr,
+ String& thePosStr ) const
+{
+ String aPosStr;
+ // BROKEN BROKEN BROKEN
+ // but it is only used in the consolidate dialog. Ignore for now.
+
+ USHORT nColonPos = theAreaStr.Search(':');
+
+ if ( nColonPos != STRING_NOTFOUND )
+ aPosStr = theAreaStr.Copy( 0, nColonPos ); // ':' nicht mitkopieren
+ else
+ aPosStr = theAreaStr;
+
+ thePosStr = aPosStr;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeUtil::IsAbsTabArea( const String& rAreaStr,
+ ScDocument* pDoc,
+ ScArea*** pppAreas,
+ USHORT* pAreaCount,
+ BOOL /* bAcceptCellRef */,
+ ScAddress::Details const & rDetails ) const
+{
+ DBG_ASSERT( pDoc, "Kein Dokument uebergeben!" );
+ if ( !pDoc )
+ return FALSE;
+
+ // BROKEN BROKEN BROKEN
+ // but it is only used in the consolidate dialog. Ignore for now.
+
+ /*
+ * Erwartet wird ein String der Form
+ * "$Tabelle1.$A$1:$Tabelle3.$D$17"
+ * Wenn bAcceptCellRef == TRUE ist, wird auch ein String der Form
+ * "$Tabelle1.$A$1"
+ * akzeptiert.
+ *
+ * als Ergebnis wird ein ScArea-Array angelegt,
+ * welches ueber ppAreas bekannt gegeben wird und auch
+ * wieder geloescht werden muss!
+ */
+
+ BOOL bStrOk = FALSE;
+ String aTempAreaStr(rAreaStr);
+ String aStartPosStr;
+ String aEndPosStr;
+
+ if ( STRING_NOTFOUND == aTempAreaStr.Search(':') )
+ {
+ aTempAreaStr.Append(':');
+ aTempAreaStr.Append(rAreaStr);
+ }
+
+ USHORT nColonPos = aTempAreaStr.Search(':');
+
+ if ( STRING_NOTFOUND != nColonPos
+ && STRING_NOTFOUND != aTempAreaStr.Search('.') )
+ {
+ ScRefAddress aStartPos;
+ ScRefAddress aEndPos;
+
+ aStartPosStr = aTempAreaStr.Copy( 0, nColonPos );
+ aEndPosStr = aTempAreaStr.Copy( nColonPos+1, STRING_LEN );
+
+ if ( ConvertSingleRef( pDoc, aStartPosStr, 0, aStartPos, rDetails ) )
+ {
+ if ( ConvertSingleRef( pDoc, aEndPosStr, aStartPos.Tab(), aEndPos, rDetails ) )
+ {
+ aStartPos.SetRelCol( FALSE );
+ aStartPos.SetRelRow( FALSE );
+ aStartPos.SetRelTab( FALSE );
+ aEndPos.SetRelCol( FALSE );
+ aEndPos.SetRelRow( FALSE );
+ aEndPos.SetRelTab( FALSE );
+
+ bStrOk = TRUE;
+
+ if ( pppAreas && pAreaCount ) // Array zurueckgegeben?
+ {
+ SCTAB nStartTab = aStartPos.Tab();
+ SCTAB nEndTab = aEndPos.Tab();
+ USHORT nTabCount = static_cast<USHORT>(nEndTab-nStartTab+1);
+ ScArea** theAreas = new ScArea*[nTabCount];
+ SCTAB nTab = 0;
+ USHORT i = 0;
+ ScArea theArea( 0, aStartPos.Col(), aStartPos.Row(),
+ aEndPos.Col(), aEndPos.Row() );
+
+ nTab = nStartTab;
+ for ( i=0; i<nTabCount; i++ )
+ {
+ theAreas[i] = new ScArea( theArea );
+ theAreas[i]->nTab = nTab;
+ nTab++;
+ }
+ *pppAreas = theAreas;
+ *pAreaCount = nTabCount;
+ }
+ }
+ }
+ }
+
+ return bStrOk;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeUtil::IsAbsArea( const String& rAreaStr,
+ ScDocument* pDoc,
+ SCTAB nTab,
+ String* pCompleteStr,
+ ScRefAddress* pStartPos,
+ ScRefAddress* pEndPos,
+ ScAddress::Details const & rDetails ) const
+{
+ BOOL bIsAbsArea = FALSE;
+ ScRefAddress startPos;
+ ScRefAddress endPos;
+
+ bIsAbsArea = ConvertDoubleRef( pDoc, rAreaStr, nTab, startPos, endPos, rDetails );
+
+ if ( bIsAbsArea )
+ {
+ startPos.SetRelCol( FALSE );
+ startPos.SetRelRow( FALSE );
+ startPos.SetRelTab( FALSE );
+ endPos .SetRelCol( FALSE );
+ endPos .SetRelRow( FALSE );
+ endPos .SetRelTab( FALSE );
+
+ if ( pCompleteStr )
+ {
+ *pCompleteStr = startPos.GetRefString( pDoc, MAXTAB+1, rDetails );
+ *pCompleteStr += ':';
+ *pCompleteStr += endPos .GetRefString( pDoc, nTab, rDetails );
+ }
+
+ if ( pStartPos && pEndPos )
+ {
+ *pStartPos = startPos;
+ *pEndPos = endPos;
+ }
+ }
+
+ return bIsAbsArea;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeUtil::IsAbsPos( const String& rPosStr,
+ ScDocument* pDoc,
+ SCTAB nTab,
+ String* pCompleteStr,
+ ScRefAddress* pPosTripel,
+ ScAddress::Details const & rDetails ) const
+{
+ BOOL bIsAbsPos = FALSE;
+ ScRefAddress thePos;
+
+ bIsAbsPos = ConvertSingleRef( pDoc, rPosStr, nTab, thePos, rDetails );
+ thePos.SetRelCol( FALSE );
+ thePos.SetRelRow( FALSE );
+ thePos.SetRelTab( FALSE );
+
+ if ( bIsAbsPos )
+ {
+ if ( pPosTripel )
+ *pPosTripel = thePos;
+ if ( pCompleteStr )
+ *pCompleteStr = thePos.GetRefString( pDoc, MAXTAB+1, rDetails );
+ }
+
+ return bIsAbsPos;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScRangeUtil::MakeRangeFromName (
+ const String& rName,
+ ScDocument* pDoc,
+ SCTAB nCurTab,
+ ScRange& rRange,
+ RutlNameScope eScope,
+ ScAddress::Details const & rDetails ) const
+{
+ BOOL bResult=FALSE;
+ ScRangeUtil aRangeUtil;
+ SCTAB nTab = 0;
+ SCCOL nColStart = 0;
+ SCCOL nColEnd = 0;
+ SCROW nRowStart = 0;
+ SCROW nRowEnd = 0;
+
+ if( eScope==RUTL_NAMES )
+ {
+ ScRangeName& rRangeNames = *(pDoc->GetRangeName());
+ USHORT nAt = 0;
+
+ if ( rRangeNames.SearchName( rName, nAt ) )
+ {
+ ScRangeData* pData = rRangeNames[nAt];
+ String aStrArea;
+ ScRefAddress aStartPos;
+ ScRefAddress aEndPos;
+
+ pData->GetSymbol( aStrArea );
+
+ if ( IsAbsArea( aStrArea, pDoc, nCurTab,
+ NULL, &aStartPos, &aEndPos, rDetails ) )
+ {
+ nTab = aStartPos.Tab();
+ nColStart = aStartPos.Col();
+ nRowStart = aStartPos.Row();
+ nColEnd = aEndPos.Col();
+ nRowEnd = aEndPos.Row();
+ bResult = TRUE;
+ }
+ else
+ {
+ CutPosString( aStrArea, aStrArea );
+
+ if ( IsAbsPos( aStrArea, pDoc, nCurTab,
+ NULL, &aStartPos, rDetails ) )
+ {
+ nTab = aStartPos.Tab();
+ nColStart = nColEnd = aStartPos.Col();
+ nRowStart = nRowEnd = aStartPos.Row();
+ bResult = TRUE;
+ }
+ }
+ }
+ }
+ else if( eScope==RUTL_DBASE )
+ {
+ ScDBCollection& rDbNames = *(pDoc->GetDBCollection());
+ USHORT nAt = 0;
+
+ if ( rDbNames.SearchName( rName, nAt ) )
+ {
+ ScDBData* pData = rDbNames[nAt];
+
+ pData->GetArea( nTab, nColStart, nRowStart,
+ nColEnd, nRowEnd );
+ bResult = TRUE;
+ }
+ }
+ else
+ {
+ DBG_ERROR( "ScRangeUtil::MakeRangeFromName" );
+ }
+
+ if( bResult )
+ {
+ rRange = ScRange( nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab );
+ }
+
+ return bResult;
+}
+
+//========================================================================
+
+void ScRangeStringConverter::AssignString(
+ OUString& rString,
+ const OUString& rNewStr,
+ sal_Bool bAppendStr,
+ sal_Unicode cSeperator)
+{
+ if( bAppendStr )
+ {
+ if( rNewStr.getLength() )
+ {
+ if( rString.getLength() )
+ rString += rtl::OUString(cSeperator);
+ rString += rNewStr;
+ }
+ }
+ else
+ rString = rNewStr;
+}
+
+sal_Int32 ScRangeStringConverter::IndexOf(
+ const OUString& rString,
+ sal_Unicode cSearchChar,
+ sal_Int32 nOffset,
+ sal_Unicode cQuote )
+{
+ sal_Int32 nLength = rString.getLength();
+ sal_Int32 nIndex = nOffset;
+ sal_Bool bQuoted = sal_False;
+ sal_Bool bExitLoop = sal_False;
+
+ while( !bExitLoop && (nIndex < nLength) )
+ {
+ sal_Unicode cCode = rString[ nIndex ];
+ bExitLoop = (cCode == cSearchChar) && !bQuoted;
+ bQuoted = (bQuoted != (cCode == cQuote));
+ if( !bExitLoop )
+ nIndex++;
+ }
+ return (nIndex < nLength) ? nIndex : -1;
+}
+
+sal_Int32 ScRangeStringConverter::IndexOfDifferent(
+ const OUString& rString,
+ sal_Unicode cSearchChar,
+ sal_Int32 nOffset )
+{
+ sal_Int32 nLength = rString.getLength();
+ sal_Int32 nIndex = nOffset;
+ sal_Bool bExitLoop = sal_False;
+
+ while( !bExitLoop && (nIndex < nLength) )
+ {
+ bExitLoop = (rString[ nIndex ] != cSearchChar);
+ if( !bExitLoop )
+ nIndex++;
+ }
+ return (nIndex < nLength) ? nIndex : -1;
+}
+
+void ScRangeStringConverter::GetTokenByOffset(
+ OUString& rToken,
+ const OUString& rString,
+ sal_Int32& nOffset,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote)
+{
+ sal_Int32 nLength = rString.getLength();
+ if( nOffset >= nLength )
+ {
+ rToken = OUString();
+ nOffset = -1;
+ }
+ else
+ {
+ sal_Int32 nTokenEnd = IndexOf( rString, cSeperator, nOffset, cQuote );
+ if( nTokenEnd < 0 )
+ nTokenEnd = nLength;
+ rToken = rString.copy( nOffset, nTokenEnd - nOffset );
+
+ sal_Int32 nNextBegin = IndexOfDifferent( rString, cSeperator, nTokenEnd );
+ nOffset = (nNextBegin < 0) ? nLength : nNextBegin;
+ }
+}
+
+void ScRangeStringConverter::AppendTableName(OUStringBuffer& rBuf, const OUString& rTabName, sal_Unicode /* cQuote */)
+{
+ // quote character is always "'"
+ String aQuotedTab(rTabName);
+ ScCompiler::CheckTabQuotes(aQuotedTab, ::formula::FormulaGrammar::CONV_OOO);
+ rBuf.append(aQuotedTab);
+}
+
+sal_Int32 ScRangeStringConverter::GetTokenCount( const OUString& rString, sal_Unicode cSeperator, sal_Unicode cQuote )
+{
+ OUString sToken;
+ sal_Int32 nCount = 0;
+ sal_Int32 nOffset = 0;
+ while( nOffset >= 0 )
+ {
+ GetTokenByOffset( sToken, rString, nOffset, cQuote, cSeperator );
+ if( nOffset >= 0 )
+ nCount++;
+ }
+ return nCount;
+}
+
+//___________________________________________________________________
+
+sal_Bool ScRangeStringConverter::GetAddressFromString(
+ ScAddress& rAddress,
+ const OUString& rAddressStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Int32& nOffset,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ OUString sToken;
+ GetTokenByOffset( sToken, rAddressStr, nOffset, cSeperator, cQuote );
+ if( nOffset >= 0 )
+ {
+ if ((rAddress.Parse( sToken, const_cast<ScDocument*>(pDocument), eConv ) & SCA_VALID) == SCA_VALID)
+ return true;
+ }
+ return sal_False;
+}
+
+sal_Bool ScRangeStringConverter::GetRangeFromString(
+ ScRange& rRange,
+ const OUString& rRangeStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Int32& nOffset,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ OUString sToken;
+ sal_Bool bResult(sal_False);
+ GetTokenByOffset( sToken, rRangeStr, nOffset, cSeperator, cQuote );
+ if( nOffset >= 0 )
+ {
+ sal_Int32 nIndex = IndexOf( sToken, ':', 0, cQuote );
+ String aUIString(sToken);
+
+ if( nIndex < 0 )
+ {
+ if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
+ aUIString.Erase( 0, 1 );
+ bResult = ((rRange.aStart.Parse( aUIString, const_cast<ScDocument*> (pDocument), eConv) & SCA_VALID) == SCA_VALID);
+ rRange.aEnd = rRange.aStart;
+ }
+ else
+ {
+ if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
+ {
+ aUIString.Erase( 0, 1 );
+ --nIndex;
+ }
+
+ if ( nIndex < aUIString.Len() - 1 &&
+ aUIString.GetChar((xub_StrLen)nIndex + 1) == (sal_Unicode) '.' )
+ aUIString.Erase( (xub_StrLen)nIndex + 1, 1 );
+
+ bResult = ((rRange.Parse(aUIString, const_cast<ScDocument*> (pDocument), eConv) & SCA_VALID) == SCA_VALID);
+
+ // #i77703# chart ranges in the file format contain both sheet names, even for an external reference sheet.
+ // This isn't parsed by ScRange, so try to parse the two Addresses then.
+ if (!bResult)
+ {
+ bResult = ((rRange.aStart.Parse( aUIString.Copy(0, (xub_StrLen)nIndex), const_cast<ScDocument*>(pDocument),
+ eConv) & SCA_VALID) == SCA_VALID) &&
+ ((rRange.aEnd.Parse( aUIString.Copy((xub_StrLen)nIndex+1), const_cast<ScDocument*>(pDocument),
+ eConv) & SCA_VALID) == SCA_VALID);
+ }
+ }
+ }
+ return bResult;
+}
+
+sal_Bool ScRangeStringConverter::GetRangeListFromString(
+ ScRangeList& rRangeList,
+ const OUString& rRangeListStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ sal_Bool bRet = sal_True;
+ DBG_ASSERT( rRangeListStr.getLength(), "ScXMLConverter::GetRangeListFromString - empty string!" );
+ sal_Int32 nOffset = 0;
+ while( nOffset >= 0 )
+ {
+ ScRange* pRange = new ScRange;
+ if( GetRangeFromString( *pRange, rRangeListStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
+ rRangeList.Insert( pRange, LIST_APPEND );
+ else if (nOffset > -1)
+ bRet = sal_False;
+ }
+ return bRet;
+}
+
+
+//___________________________________________________________________
+
+sal_Bool ScRangeStringConverter::GetAreaFromString(
+ ScArea& rArea,
+ const OUString& rRangeStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Int32& nOffset,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ ScRange aScRange;
+ sal_Bool bResult(sal_False);
+ if( GetRangeFromString( aScRange, rRangeStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
+ {
+ rArea.nTab = aScRange.aStart.Tab();
+ rArea.nColStart = aScRange.aStart.Col();
+ rArea.nRowStart = aScRange.aStart.Row();
+ rArea.nColEnd = aScRange.aEnd.Col();
+ rArea.nRowEnd = aScRange.aEnd.Row();
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+
+//___________________________________________________________________
+
+sal_Bool ScRangeStringConverter::GetAddressFromString(
+ table::CellAddress& rAddress,
+ const OUString& rAddressStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Int32& nOffset,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ ScAddress aScAddress;
+ sal_Bool bResult(sal_False);
+ if( GetAddressFromString( aScAddress, rAddressStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
+ {
+ ScUnoConversion::FillApiAddress( rAddress, aScAddress );
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+sal_Bool ScRangeStringConverter::GetRangeFromString(
+ table::CellRangeAddress& rRange,
+ const OUString& rRangeStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Int32& nOffset,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ ScRange aScRange;
+ sal_Bool bResult(sal_False);
+ if( GetRangeFromString( aScRange, rRangeStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
+ {
+ ScUnoConversion::FillApiRange( rRange, aScRange );
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+sal_Bool ScRangeStringConverter::GetRangeListFromString(
+ uno::Sequence< table::CellRangeAddress >& rRangeSeq,
+ const OUString& rRangeListStr,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Unicode cQuote )
+{
+ sal_Bool bRet = sal_True;
+ DBG_ASSERT( rRangeListStr.getLength(), "ScXMLConverter::GetRangeListFromString - empty string!" );
+ table::CellRangeAddress aRange;
+ sal_Int32 nOffset = 0;
+ while( nOffset >= 0 )
+ {
+ if( GetRangeFromString( aRange, rRangeListStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
+ {
+ rRangeSeq.realloc( rRangeSeq.getLength() + 1 );
+ rRangeSeq[ rRangeSeq.getLength() - 1 ] = aRange;
+ }
+ else
+ bRet = sal_False;
+ }
+ return bRet;
+}
+
+
+//___________________________________________________________________
+
+void ScRangeStringConverter::GetStringFromAddress(
+ OUString& rString,
+ const ScAddress& rAddress,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Bool bAppendStr,
+ sal_uInt16 nFormatFlags )
+{
+ if (pDocument && pDocument->HasTable(rAddress.Tab()))
+ {
+ String sAddress;
+ rAddress.Format( sAddress, nFormatFlags, (ScDocument*) pDocument, eConv );
+ AssignString( rString, sAddress, bAppendStr, cSeperator );
+ }
+}
+
+void ScRangeStringConverter::GetStringFromRange(
+ OUString& rString,
+ const ScRange& rRange,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Bool bAppendStr,
+ sal_uInt16 nFormatFlags )
+{
+ if (pDocument && pDocument->HasTable(rRange.aStart.Tab()))
+ {
+ ScAddress aStartAddress( rRange.aStart );
+ ScAddress aEndAddress( rRange.aEnd );
+ String sStartAddress;
+ String sEndAddress;
+ aStartAddress.Format( sStartAddress, nFormatFlags, (ScDocument*) pDocument, eConv );
+ aEndAddress.Format( sEndAddress, nFormatFlags, (ScDocument*) pDocument, eConv );
+ OUString sOUStartAddress( sStartAddress );
+ sOUStartAddress += OUString(':');
+ sOUStartAddress += OUString( sEndAddress );
+ AssignString( rString, sOUStartAddress, bAppendStr, cSeperator );
+ }
+}
+
+void ScRangeStringConverter::GetStringFromRangeList(
+ OUString& rString,
+ const ScRangeList* pRangeList,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_uInt16 nFormatFlags )
+{
+ OUString sRangeListStr;
+ if( pRangeList )
+ {
+ sal_Int32 nCount = pRangeList->Count();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ const ScRange* pRange = pRangeList->GetObject( nIndex );
+ if( pRange )
+ GetStringFromRange( sRangeListStr, *pRange, pDocument, eConv, cSeperator, sal_True, nFormatFlags );
+ }
+ }
+ rString = sRangeListStr;
+}
+
+
+//___________________________________________________________________
+
+void ScRangeStringConverter::GetStringFromArea(
+ OUString& rString,
+ const ScArea& rArea,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Bool bAppendStr,
+ sal_uInt16 nFormatFlags )
+{
+ ScRange aRange( rArea.nColStart, rArea.nRowStart, rArea.nTab, rArea.nColEnd, rArea.nRowEnd, rArea.nTab );
+ GetStringFromRange( rString, aRange, pDocument, eConv, cSeperator, bAppendStr, nFormatFlags );
+}
+
+
+//___________________________________________________________________
+
+void ScRangeStringConverter::GetStringFromAddress(
+ OUString& rString,
+ const table::CellAddress& rAddress,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Bool bAppendStr,
+ sal_uInt16 nFormatFlags )
+{
+ ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet );
+ GetStringFromAddress( rString, aScAddress, pDocument, eConv, cSeperator, bAppendStr, nFormatFlags );
+}
+
+void ScRangeStringConverter::GetStringFromRange(
+ OUString& rString,
+ const table::CellRangeAddress& rRange,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_Bool bAppendStr,
+ sal_uInt16 nFormatFlags )
+{
+ ScRange aScRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), rRange.Sheet,
+ static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), rRange.Sheet );
+ GetStringFromRange( rString, aScRange, pDocument, eConv, cSeperator, bAppendStr, nFormatFlags );
+}
+
+void ScRangeStringConverter::GetStringFromRangeList(
+ OUString& rString,
+ const uno::Sequence< table::CellRangeAddress >& rRangeSeq,
+ const ScDocument* pDocument,
+ FormulaGrammar::AddressConvention eConv,
+ sal_Unicode cSeperator,
+ sal_uInt16 nFormatFlags )
+{
+ OUString sRangeListStr;
+ sal_Int32 nCount = rRangeSeq.getLength();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ const table::CellRangeAddress& rRange = rRangeSeq[ nIndex ];
+ GetStringFromRange( sRangeListStr, rRange, pDocument, eConv, cSeperator, sal_True, nFormatFlags );
+ }
+ rString = sRangeListStr;
+}
+
+static void lcl_appendCellAddress(
+ rtl::OUStringBuffer& rBuf, ScDocument* pDoc, const ScAddress& rCell,
+ const ScAddress::ExternalInfo& rExtInfo)
+{
+ if (rExtInfo.mbExternal)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const String* pFilePath = pRefMgr->getExternalFileName(rExtInfo.mnFileId, true);
+ if (!pFilePath)
+ return;
+
+ sal_Unicode cQuote = '\'';
+ rBuf.append(cQuote);
+ rBuf.append(*pFilePath);
+ rBuf.append(cQuote);
+ rBuf.append(sal_Unicode('#'));
+ rBuf.append(sal_Unicode('$'));
+ ScRangeStringConverter::AppendTableName(rBuf, rExtInfo.maTabName);
+ rBuf.append(sal_Unicode('.'));
+
+ String aAddr;
+ rCell.Format(aAddr, SCA_ABS, NULL, ::formula::FormulaGrammar::CONV_OOO);
+ rBuf.append(aAddr);
+ }
+ else
+ {
+ String aAddr;
+ rCell.Format(aAddr, SCA_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
+ rBuf.append(aAddr);
+ }
+}
+
+static void lcl_appendCellRangeAddress(
+ rtl::OUStringBuffer& rBuf, ScDocument* pDoc, const ScAddress& rCell1, const ScAddress& rCell2,
+ const ScAddress::ExternalInfo& rExtInfo1, const ScAddress::ExternalInfo& rExtInfo2)
+{
+ if (rExtInfo1.mbExternal)
+ {
+ DBG_ASSERT(rExtInfo2.mbExternal, "2nd address is not external!?");
+ DBG_ASSERT(rExtInfo1.mnFileId == rExtInfo2.mnFileId, "File IDs do not match between 1st and 2nd addresses.");
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ const String* pFilePath = pRefMgr->getExternalFileName(rExtInfo1.mnFileId, true);
+ if (!pFilePath)
+ return;
+
+ sal_Unicode cQuote = '\'';
+ rBuf.append(cQuote);
+ rBuf.append(*pFilePath);
+ rBuf.append(cQuote);
+ rBuf.append(sal_Unicode('#'));
+ rBuf.append(sal_Unicode('$'));
+ ScRangeStringConverter::AppendTableName(rBuf, rExtInfo1.maTabName);
+ rBuf.append(sal_Unicode('.'));
+
+ String aAddr;
+ rCell1.Format(aAddr, SCA_ABS, NULL, ::formula::FormulaGrammar::CONV_OOO);
+ rBuf.append(aAddr);
+
+ rBuf.appendAscii(":");
+
+ if (rExtInfo1.maTabName != rExtInfo2.maTabName)
+ {
+ rBuf.append(sal_Unicode('$'));
+ ScRangeStringConverter::AppendTableName(rBuf, rExtInfo2.maTabName);
+ rBuf.append(sal_Unicode('.'));
+ }
+
+ rCell2.Format(aAddr, SCA_ABS, NULL, ::formula::FormulaGrammar::CONV_OOO);
+ rBuf.append(aAddr);
+ }
+ else
+ {
+ ScRange aRange;
+ aRange.aStart = rCell1;
+ aRange.aEnd = rCell2;
+ String aAddr;
+ aRange.Format(aAddr, SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
+ rBuf.append(aAddr);
+ }
+}
+
+void ScRangeStringConverter::GetStringFromXMLRangeString( OUString& rString, const OUString& rXMLRange, ScDocument* pDoc )
+{
+ const sal_Unicode cSep = ' ';
+ const sal_Unicode cQuote = '\'';
+
+ OUStringBuffer aRetStr;
+ sal_Int32 nOffset = 0;
+ bool bFirst = true;
+
+ while (nOffset >= 0)
+ {
+ OUString aToken;
+ GetTokenByOffset(aToken, rXMLRange, nOffset, cSep, cQuote);
+ if (nOffset < 0)
+ break;
+
+ sal_Int32 nSepPos = IndexOf(aToken, ':', 0, cQuote);
+ if (nSepPos >= 0)
+ {
+ // Cell range
+ OUString aBeginCell = aToken.copy(0, nSepPos);
+ OUString aEndCell = aToken.copy(nSepPos+1);
+
+ if (!aBeginCell.getLength() || !aEndCell.getLength())
+ // both cell addresses must exist for this to work.
+ continue;
+
+ sal_Int32 nEndCellDotPos = aEndCell.indexOf('.');
+ if (nEndCellDotPos <= 0)
+ {
+ // initialize buffer with table name...
+ sal_Int32 nDotPos = IndexOf(aBeginCell, sal_Unicode('.'), 0, cQuote);
+ OUStringBuffer aBuf = aBeginCell.copy(0, nDotPos);
+
+ if (nEndCellDotPos == 0)
+ {
+ // workaround for old syntax (probably pre-chart2 age?)
+ // e.g. Sheet1.A1:.B2
+ aBuf.append(aEndCell);
+ }
+ else if (nEndCellDotPos < 0)
+ {
+ // sheet name in the end cell is omitted (e.g. Sheet2.A1:B2).
+ aBuf.append(sal_Unicode('.'));
+ aBuf.append(aEndCell);
+ }
+ aEndCell = aBuf.makeStringAndClear();
+ }
+
+ ScAddress::ExternalInfo aExtInfo1, aExtInfo2;
+ ScAddress aCell1, aCell2;
+ rtl::OUString aBuf;
+ USHORT nRet = aCell1.Parse(aBeginCell, pDoc, FormulaGrammar::CONV_OOO, &aExtInfo1);
+ if ((nRet & SCA_VALID) != SCA_VALID)
+ // first cell is invalid.
+ continue;
+
+ nRet = aCell2.Parse(aEndCell, pDoc, FormulaGrammar::CONV_OOO, &aExtInfo2);
+ if ((nRet & SCA_VALID) != SCA_VALID)
+ // second cell is invalid.
+ continue;
+
+ if (aExtInfo1.mnFileId != aExtInfo2.mnFileId || aExtInfo1.mbExternal != aExtInfo2.mbExternal)
+ // external info inconsistency.
+ continue;
+
+ // All looks good!
+
+ if (bFirst)
+ bFirst = false;
+ else
+ aRetStr.appendAscii(";");
+
+ lcl_appendCellRangeAddress(aRetStr, pDoc, aCell1, aCell2, aExtInfo1, aExtInfo2);
+ }
+ else
+ {
+ // Chart always saves ranges using CONV_OOO convention.
+ ScAddress::ExternalInfo aExtInfo;
+ ScAddress aCell;
+ USHORT nRet = aCell.Parse(aToken, pDoc, ::formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ if ((nRet & SCA_VALID) != SCA_VALID)
+ continue;
+
+ // Looks good!
+
+ if (bFirst)
+ bFirst = false;
+ else
+ aRetStr.appendAscii(";");
+
+ lcl_appendCellAddress(aRetStr, pDoc, aCell, aExtInfo);
+ }
+ }
+
+ rString = aRetStr.makeStringAndClear();
+}
+
+//========================================================================
+
+ScArea::ScArea( SCTAB tab,
+ SCCOL colStart, SCROW rowStart,
+ SCCOL colEnd, SCROW rowEnd ) :
+ nTab ( tab ),
+ nColStart( colStart ), nRowStart( rowStart ),
+ nColEnd ( colEnd ), nRowEnd ( rowEnd )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScArea::ScArea( const ScArea& r ) :
+ nTab ( r.nTab ),
+ nColStart( r.nColStart ), nRowStart( r.nRowStart ),
+ nColEnd ( r.nColEnd ), nRowEnd ( r.nRowEnd )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScArea& ScArea::operator=( const ScArea& r )
+{
+ nTab = r.nTab;
+ nColStart = r.nColStart;
+ nRowStart = r.nRowStart;
+ nColEnd = r.nColEnd;
+ nRowEnd = r.nRowEnd;
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScArea::operator==( const ScArea& r ) const
+{
+ return ( (nTab == r.nTab)
+ && (nColStart == r.nColStart)
+ && (nRowStart == r.nRowStart)
+ && (nColEnd == r.nColEnd)
+ && (nRowEnd == r.nRowEnd) );
+}
+
+//------------------------------------------------------------------------
+
+ScAreaNameIterator::ScAreaNameIterator( ScDocument* pDoc ) :
+ aStrNoName( ScGlobal::GetRscString(STR_DB_NONAME) )
+{
+ pRangeName = pDoc->GetRangeName();
+ pDBCollection = pDoc->GetDBCollection();
+ nPos = 0;
+ bFirstPass = TRUE;
+}
+
+BOOL ScAreaNameIterator::Next( String& rName, ScRange& rRange )
+{
+ for (;;)
+ {
+ if ( bFirstPass ) // erst Bereichsnamen
+ {
+ if ( pRangeName && nPos < pRangeName->GetCount() )
+ {
+ ScRangeData* pData = (*pRangeName)[nPos++];
+ if ( pData && pData->IsValidReference(rRange) )
+ {
+ rName = pData->GetName();
+ return TRUE; // gefunden
+ }
+ }
+ else
+ {
+ bFirstPass = FALSE;
+ nPos = 0;
+ }
+ }
+ if ( !bFirstPass ) // dann DB-Bereiche
+ {
+ if ( pDBCollection && nPos < pDBCollection->GetCount() )
+ {
+ ScDBData* pData = (*pDBCollection)[nPos++];
+ if (pData && pData->GetName() != aStrNoName)
+ {
+ pData->GetArea( rRange );
+ rName = pData->GetName();
+ return TRUE; // gefunden
+ }
+ }
+ else
+ return FALSE; // gibt nichts mehr
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/core/tool/rechead.cxx b/sc/source/core/tool/rechead.cxx
new file mode 100644
index 000000000000..6da946463697
--- /dev/null
+++ b/sc/source/core/tool/rechead.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "rechead.hxx"
+#include "scerrors.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// =======================================================================
+
+ScMultipleReadHeader::ScMultipleReadHeader(SvStream& rNewStream) :
+ rStream( rNewStream )
+{
+ sal_uInt32 nDataSize;
+ rStream >> nDataSize;
+ ULONG nDataPos = rStream.Tell();
+ nTotalEnd = nDataPos + nDataSize;
+ nEntryEnd = nTotalEnd;
+
+ rStream.SeekRel(nDataSize);
+ USHORT nID;
+ rStream >> nID;
+ if (nID != SCID_SIZES)
+ {
+ DBG_ERROR("SCID_SIZES nicht gefunden");
+ if ( rStream.GetError() == SVSTREAM_OK )
+ rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ // alles auf 0, damit BytesLeft() wenigstens abbricht
+ pBuf = NULL; pMemStream = NULL;
+ nEntryEnd = nDataPos;
+ }
+ else
+ {
+ sal_uInt32 nSizeTableLen;
+ rStream >> nSizeTableLen;
+ pBuf = new BYTE[nSizeTableLen];
+ rStream.Read( pBuf, nSizeTableLen );
+ pMemStream = new SvMemoryStream( (char*)pBuf, nSizeTableLen, STREAM_READ );
+ }
+
+ nEndPos = rStream.Tell();
+ rStream.Seek( nDataPos );
+}
+
+ScMultipleReadHeader::~ScMultipleReadHeader()
+{
+ if ( pMemStream && pMemStream->Tell() != pMemStream->GetEndOfData() )
+ {
+ DBG_ERRORFILE( "Sizes nicht vollstaendig gelesen" );
+ if ( rStream.GetError() == SVSTREAM_OK )
+ rStream.SetError( SCWARN_IMPORT_INFOLOST );
+ }
+ delete pMemStream;
+ delete[] pBuf;
+
+ rStream.Seek(nEndPos);
+}
+
+void ScMultipleReadHeader::EndEntry()
+{
+ ULONG nPos = rStream.Tell();
+ DBG_ASSERT( nPos <= nEntryEnd, "zuviel gelesen" );
+ if ( nPos != nEntryEnd )
+ {
+ if ( rStream.GetError() == SVSTREAM_OK )
+ rStream.SetError( SCWARN_IMPORT_INFOLOST );
+ rStream.Seek( nEntryEnd ); // Rest ueberspringen
+ }
+
+ nEntryEnd = nTotalEnd; // den ganzen Rest, wenn kein StartEntry kommt
+}
+
+void ScMultipleReadHeader::StartEntry()
+{
+ ULONG nPos = rStream.Tell();
+ sal_uInt32 nEntrySize;
+ (*pMemStream) >> nEntrySize;
+
+ nEntryEnd = nPos + nEntrySize;
+ DBG_ASSERT( nEntryEnd <= nTotalEnd, "zuviele Eintraege gelesen" );
+}
+
+ULONG ScMultipleReadHeader::BytesLeft() const
+{
+ ULONG nReadEnd = rStream.Tell();
+ if (nReadEnd <= nEntryEnd)
+ return nEntryEnd-nReadEnd;
+
+ DBG_ERROR("Fehler bei ScMultipleReadHeader::BytesLeft");
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+ScMultipleWriteHeader::ScMultipleWriteHeader(SvStream& rNewStream, sal_uInt32 nDefault) :
+ rStream( rNewStream ),
+ aMemStream( 4096, 4096 )
+{
+ nDataSize = nDefault;
+ rStream << nDataSize;
+
+ nDataPos = rStream.Tell();
+ nEntryStart = nDataPos;
+}
+
+ScMultipleWriteHeader::~ScMultipleWriteHeader()
+{
+ ULONG nDataEnd = rStream.Tell();
+
+ rStream << (USHORT) SCID_SIZES;
+ rStream << static_cast<sal_uInt32>(aMemStream.Tell());
+ rStream.Write( aMemStream.GetData(), aMemStream.Tell() );
+
+ if ( nDataEnd - nDataPos != nDataSize ) // Default getroffen?
+ {
+ nDataSize = nDataEnd - nDataPos;
+ ULONG nPos = rStream.Tell();
+ rStream.Seek(nDataPos-sizeof(sal_uInt32));
+ rStream << nDataSize; // Groesse am Anfang eintragen
+ rStream.Seek(nPos);
+ }
+}
+
+void ScMultipleWriteHeader::EndEntry()
+{
+ ULONG nPos = rStream.Tell();
+ aMemStream << static_cast<sal_uInt32>(nPos - nEntryStart);
+}
+
+void ScMultipleWriteHeader::StartEntry()
+{
+ ULONG nPos = rStream.Tell();
+ nEntryStart = nPos;
+}
+
+
+
+
+
diff --git a/sc/source/core/tool/refdata.cxx b/sc/source/core/tool/refdata.cxx
new file mode 100644
index 000000000000..47774d348044
--- /dev/null
+++ b/sc/source/core/tool/refdata.cxx
@@ -0,0 +1,372 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "refdata.hxx"
+
+
+void ScSingleRefData::CalcRelFromAbs( const ScAddress& rPos )
+{
+ nRelCol = nCol - rPos.Col();
+ nRelRow = nRow - rPos.Row();
+ nRelTab = nTab - rPos.Tab();
+}
+
+
+void ScSingleRefData::SmartRelAbs( const ScAddress& rPos )
+{
+ if ( Flags.bColRel )
+ nCol = nRelCol + rPos.Col();
+ else
+ nRelCol = nCol - rPos.Col();
+
+ if ( Flags.bRowRel )
+ nRow = nRelRow + rPos.Row();
+ else
+ nRelRow = nRow - rPos.Row();
+
+ if ( Flags.bTabRel )
+ nTab = nRelTab + rPos.Tab();
+ else
+ nRelTab = nTab - rPos.Tab();
+}
+
+
+void ScSingleRefData::CalcAbsIfRel( const ScAddress& rPos )
+{
+ if ( Flags.bColRel )
+ {
+ nCol = nRelCol + rPos.Col();
+ if ( !VALIDCOL( nCol ) )
+ Flags.bColDeleted = TRUE;
+ }
+ if ( Flags.bRowRel )
+ {
+ nRow = nRelRow + rPos.Row();
+ if ( !VALIDROW( nRow ) )
+ Flags.bRowDeleted = TRUE;
+ }
+ if ( Flags.bTabRel )
+ {
+ nTab = nRelTab + rPos.Tab();
+ if ( !VALIDTAB( nTab ) )
+ Flags.bTabDeleted = TRUE;
+ }
+}
+
+//UNUSED2008-05 void ScSingleRefData::OldBoolsToNewFlags( const OldSingleRefBools& rBools )
+//UNUSED2008-05 {
+//UNUSED2008-05 switch ( rBools.bRelCol )
+//UNUSED2008-05 {
+//UNUSED2008-05 case SR_DELETED :
+//UNUSED2008-05 Flags.bColRel = TRUE; // der war verlorengegangen
+//UNUSED2008-05 Flags.bColDeleted = TRUE;
+//UNUSED2008-05 break;
+//UNUSED2008-05 case SR_ABSOLUTE :
+//UNUSED2008-05 Flags.bColRel = FALSE;
+//UNUSED2008-05 Flags.bColDeleted = FALSE;
+//UNUSED2008-05 break;
+//UNUSED2008-05 case SR_RELABS :
+//UNUSED2008-05 case SR_RELATIVE :
+//UNUSED2008-05 default:
+//UNUSED2008-05 Flags.bColRel = TRUE;
+//UNUSED2008-05 Flags.bColDeleted = FALSE;
+//UNUSED2008-05 }
+//UNUSED2008-05 switch ( rBools.bRelRow )
+//UNUSED2008-05 {
+//UNUSED2008-05 case SR_DELETED :
+//UNUSED2008-05 Flags.bRowRel = TRUE; // der war verlorengegangen
+//UNUSED2008-05 Flags.bRowDeleted = TRUE;
+//UNUSED2008-05 break;
+//UNUSED2008-05 case SR_ABSOLUTE :
+//UNUSED2008-05 Flags.bRowRel = FALSE;
+//UNUSED2008-05 Flags.bRowDeleted = FALSE;
+//UNUSED2008-05 break;
+//UNUSED2008-05 case SR_RELABS :
+//UNUSED2008-05 case SR_RELATIVE :
+//UNUSED2008-05 default:
+//UNUSED2008-05 Flags.bRowRel = TRUE;
+//UNUSED2008-05 Flags.bRowDeleted = FALSE;
+//UNUSED2008-05 }
+//UNUSED2008-05 switch ( rBools.bRelTab )
+//UNUSED2008-05 {
+//UNUSED2008-05 case SR_DELETED :
+//UNUSED2008-05 Flags.bTabRel = TRUE; // der war verlorengegangen
+//UNUSED2008-05 Flags.bTabDeleted = TRUE;
+//UNUSED2008-05 break;
+//UNUSED2008-05 case SR_ABSOLUTE :
+//UNUSED2008-05 Flags.bTabRel = FALSE;
+//UNUSED2008-05 Flags.bTabDeleted = FALSE;
+//UNUSED2008-05 break;
+//UNUSED2008-05 case SR_RELABS :
+//UNUSED2008-05 case SR_RELATIVE :
+//UNUSED2008-05 default:
+//UNUSED2008-05 Flags.bTabRel = TRUE;
+//UNUSED2008-05 Flags.bTabDeleted = FALSE;
+//UNUSED2008-05 }
+//UNUSED2008-05 Flags.bFlag3D = (rBools.bOldFlag3D & SRF_3D ? TRUE : FALSE);
+//UNUSED2008-05 Flags.bRelName = (rBools.bOldFlag3D & SRF_RELNAME ? TRUE : FALSE);
+//UNUSED2008-05 if ( !Flags.bFlag3D )
+//UNUSED2008-05 Flags.bTabRel = TRUE; // ist bei einigen aelteren Dokumenten nicht gesetzt
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05
+//UNUSED2008-05 /*
+//UNUSED2008-05 bis Release 3.1 sah Store so aus
+//UNUSED2008-05
+//UNUSED2008-05 BYTE n = ( ( r.bOldFlag3D & 0x03 ) << 6 ) // RelName, 3D
+//UNUSED2008-05 | ( ( r.bRelTab & 0x03 ) << 4 ) // Relative, RelAbs
+//UNUSED2008-05 | ( ( r.bRelRow & 0x03 ) << 2 )
+//UNUSED2008-05 | ( r.bRelCol & 0x03 );
+//UNUSED2008-05
+//UNUSED2008-05 bis Release 3.1 sah Load so aus
+//UNUSED2008-05
+//UNUSED2008-05 r.bRelCol = ( n & 0x03 );
+//UNUSED2008-05 r.bRelRow = ( ( n >> 2 ) & 0x03 );
+//UNUSED2008-05 r.bRelTab = ( ( n >> 4 ) & 0x03 );
+//UNUSED2008-05 r.bOldFlag3D = ( ( n >> 6 ) & 0x03 );
+//UNUSED2008-05
+//UNUSED2008-05 bRelCol == SR_DELETED war identisch mit bRelCol == (SR_RELATIVE | SR_RELABS)
+//UNUSED2008-05 leider..
+//UNUSED2008-05 3.1 liest Zukunft: Deleted wird nicht unbedingt erkannt, nur wenn auch Relativ.
+//UNUSED2008-05 Aber immer noch nCol > MAXCOL und gut sollte sein..
+//UNUSED2008-05 */
+//UNUSED2008-05
+//UNUSED2008-05 BYTE ScSingleRefData::CreateStoreByteFromFlags() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return (BYTE)(
+//UNUSED2008-05 ( (Flags.bRelName & 0x01) << 7 )
+//UNUSED2008-05 | ( (Flags.bFlag3D & 0x01) << 6 )
+//UNUSED2008-05 | ( (Flags.bTabDeleted & 0x01) << 5 )
+//UNUSED2008-05 | ( (Flags.bTabRel & 0x01) << 4 )
+//UNUSED2008-05 | ( (Flags.bRowDeleted & 0x01) << 3 )
+//UNUSED2008-05 | ( (Flags.bRowRel & 0x01) << 2 )
+//UNUSED2008-05 | ( (Flags.bColDeleted & 0x01) << 1 )
+//UNUSED2008-05 | (Flags.bColRel & 0x01)
+//UNUSED2008-05 );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05
+//UNUSED2008-05 void ScSingleRefData::CreateFlagsFromLoadByte( BYTE n )
+//UNUSED2008-05 {
+//UNUSED2008-05 Flags.bColRel = (n & 0x01 );
+//UNUSED2008-05 Flags.bColDeleted = ( (n >> 1) & 0x01 );
+//UNUSED2008-05 Flags.bRowRel = ( (n >> 2) & 0x01 );
+//UNUSED2008-05 Flags.bRowDeleted = ( (n >> 3) & 0x01 );
+//UNUSED2008-05 Flags.bTabRel = ( (n >> 4) & 0x01 );
+//UNUSED2008-05 Flags.bTabDeleted = ( (n >> 5) & 0x01 );
+//UNUSED2008-05 Flags.bFlag3D = ( (n >> 6) & 0x01 );
+//UNUSED2008-05 Flags.bRelName = ( (n >> 7) & 0x01 );
+//UNUSED2008-05 }
+
+
+BOOL ScSingleRefData::operator==( const ScSingleRefData& r ) const
+{
+ return bFlags == r.bFlags &&
+ (Flags.bColRel ? nRelCol == r.nRelCol : nCol == r.nCol) &&
+ (Flags.bRowRel ? nRelRow == r.nRelRow : nRow == r.nRow) &&
+ (Flags.bTabRel ? nRelTab == r.nRelTab : nTab == r.nTab);
+}
+
+bool ScSingleRefData::operator!=( const ScSingleRefData& r ) const
+{
+ return !operator==(r);
+}
+
+static void lcl_putInOrder( ScSingleRefData & rRef1, ScSingleRefData & rRef2 )
+{
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ SCTAB nTab1, nTab2;
+ BOOL bTmp;
+ BYTE nRelState1, nRelState2;
+ if ( rRef1.Flags.bRelName )
+ nRelState1 =
+ ((rRef1.Flags.bTabRel & 0x01) << 2)
+ | ((rRef1.Flags.bRowRel & 0x01) << 1)
+ | ((rRef1.Flags.bColRel & 0x01));
+ else
+ nRelState1 = 0;
+ if ( rRef2.Flags.bRelName )
+ nRelState2 =
+ ((rRef2.Flags.bTabRel & 0x01) << 2)
+ | ((rRef2.Flags.bRowRel & 0x01) << 1)
+ | ((rRef2.Flags.bColRel & 0x01));
+ else
+ nRelState2 = 0;
+ if ( (nCol1 = rRef1.nCol) > (nCol2 = rRef2.nCol) )
+ {
+ rRef1.nCol = nCol2;
+ rRef2.nCol = nCol1;
+ nCol1 = rRef1.nRelCol;
+ rRef1.nRelCol = rRef2.nRelCol;
+ rRef2.nRelCol = nCol1;
+ if ( rRef1.Flags.bRelName && rRef1.Flags.bColRel )
+ nRelState2 |= 1;
+ else
+ nRelState2 &= ~1;
+ if ( rRef2.Flags.bRelName && rRef2.Flags.bColRel )
+ nRelState1 |= 1;
+ else
+ nRelState1 &= ~1;
+ bTmp = rRef1.Flags.bColRel;
+ rRef1.Flags.bColRel = rRef2.Flags.bColRel;
+ rRef2.Flags.bColRel = bTmp;
+ bTmp = rRef1.Flags.bColDeleted;
+ rRef1.Flags.bColDeleted = rRef2.Flags.bColDeleted;
+ rRef2.Flags.bColDeleted = bTmp;
+ }
+ if ( (nRow1 = rRef1.nRow) > (nRow2 = rRef2.nRow) )
+ {
+ rRef1.nRow = nRow2;
+ rRef2.nRow = nRow1;
+ nRow1 = rRef1.nRelRow;
+ rRef1.nRelRow = rRef2.nRelRow;
+ rRef2.nRelRow = nRow1;
+ if ( rRef1.Flags.bRelName && rRef1.Flags.bRowRel )
+ nRelState2 |= 2;
+ else
+ nRelState2 &= ~2;
+ if ( rRef2.Flags.bRelName && rRef2.Flags.bRowRel )
+ nRelState1 |= 2;
+ else
+ nRelState1 &= ~2;
+ bTmp = rRef1.Flags.bRowRel;
+ rRef1.Flags.bRowRel = rRef2.Flags.bRowRel;
+ rRef2.Flags.bRowRel = bTmp;
+ bTmp = rRef1.Flags.bRowDeleted;
+ rRef1.Flags.bRowDeleted = rRef2.Flags.bRowDeleted;
+ rRef2.Flags.bRowDeleted = bTmp;
+ }
+ if ( (nTab1 = rRef1.nTab) > (nTab2 = rRef2.nTab) )
+ {
+ rRef1.nTab = nTab2;
+ rRef2.nTab = nTab1;
+ nTab1 = rRef1.nRelTab;
+ rRef1.nRelTab = rRef2.nRelTab;
+ rRef2.nRelTab = nTab1;
+ if ( rRef1.Flags.bRelName && rRef1.Flags.bTabRel )
+ nRelState2 |= 4;
+ else
+ nRelState2 &= ~4;
+ if ( rRef2.Flags.bRelName && rRef2.Flags.bTabRel )
+ nRelState1 |= 4;
+ else
+ nRelState1 &= ~4;
+ bTmp = rRef1.Flags.bTabRel;
+ rRef1.Flags.bTabRel = rRef2.Flags.bTabRel;
+ rRef2.Flags.bTabRel = bTmp;
+ bTmp = rRef1.Flags.bTabDeleted;
+ rRef1.Flags.bTabDeleted = rRef2.Flags.bTabDeleted;
+ rRef2.Flags.bTabDeleted = bTmp;
+ }
+ rRef1.Flags.bRelName = ( nRelState1 ? TRUE : FALSE );
+ rRef2.Flags.bRelName = ( nRelState2 ? TRUE : FALSE );
+}
+
+
+void ScComplexRefData::PutInOrder()
+{
+ lcl_putInOrder( Ref1, Ref2);
+}
+
+
+static void lcl_adjustInOrder( ScSingleRefData & rRef1, ScSingleRefData & rRef2, bool bFirstLeader )
+{
+ // a1:a2:a3, bFirstLeader: rRef1==a1==r1, rRef2==a3==r2
+ // else: rRef1==a3==r2, rRef2==a2==r1
+ ScSingleRefData& r1 = (bFirstLeader ? rRef1 : rRef2);
+ ScSingleRefData& r2 = (bFirstLeader ? rRef2 : rRef1);
+ if (r1.Flags.bFlag3D && !r2.Flags.bFlag3D)
+ {
+ // [$]Sheet1.A5:A6 on Sheet2 do still refer only Sheet1.
+ r2.nTab = r1.nTab;
+ r2.nRelTab = r1.nRelTab;
+ r2.Flags.bTabRel = r1.Flags.bTabRel;
+ }
+ lcl_putInOrder( rRef1, rRef2);
+}
+
+
+ScComplexRefData& ScComplexRefData::Extend( const ScSingleRefData & rRef, const ScAddress & rPos )
+{
+ CalcAbsIfRel( rPos);
+ ScSingleRefData aRef = rRef;
+ aRef.CalcAbsIfRel( rPos);
+ bool bInherit3D = Ref1.IsFlag3D() && !Ref2.IsFlag3D();
+ bool bInherit3Dtemp = bInherit3D && !rRef.IsFlag3D();
+ if (aRef.nCol < Ref1.nCol || aRef.nRow < Ref1.nRow || aRef.nTab < Ref1.nTab)
+ {
+ lcl_adjustInOrder( Ref1, aRef, true);
+ aRef = rRef;
+ aRef.CalcAbsIfRel( rPos);
+ }
+ if (aRef.nCol > Ref2.nCol || aRef.nRow > Ref2.nRow || aRef.nTab > Ref2.nTab)
+ {
+ if (bInherit3D)
+ Ref2.SetFlag3D( true);
+ lcl_adjustInOrder( aRef, Ref2, false);
+ if (bInherit3Dtemp)
+ Ref2.SetFlag3D( false);
+ aRef = rRef;
+ aRef.CalcAbsIfRel( rPos);
+ }
+ // In Ref2 use absolute/relative addressing from non-extended parts if
+ // equal and therefor not adjusted.
+ // A$5:A5 => A$5:A$5:A5 => A$5:A5, and not A$5:A$5
+ // A$6:$A5 => A$6:A$6:$A5 => A5:$A$6
+ if (Ref2.nCol == aRef.nCol)
+ Ref2.SetColRel( aRef.IsColRel());
+ if (Ref2.nRow == aRef.nRow)
+ Ref2.SetRowRel( aRef.IsRowRel());
+ // $Sheet1.$A$5:$A$6 => $Sheet1.$A$5:$A$5:$A$6 => $Sheet1.$A$5:$A$6, and
+ // not $Sheet1.$A$5:Sheet1.$A$6 (with invisible second 3D, but relative).
+ if (Ref2.nTab == aRef.nTab)
+ Ref2.SetTabRel( bInherit3Dtemp ? Ref1.IsTabRel() : aRef.IsTabRel());
+ Ref2.CalcRelFromAbs( rPos);
+ // Force 3D if necessary. References to other sheets always.
+ if (Ref1.nTab != rPos.Tab())
+ Ref1.SetFlag3D( true);
+ // In the second part only if different sheet thus not inherited.
+ if (Ref2.nTab != Ref1.nTab)
+ Ref2.SetFlag3D( true);
+ // Merge Flag3D to Ref2 in case there was nothing to inherit and/or range
+ // wasn't extended as in A5:A5:Sheet1.A5 if on Sheet1.
+ if (rRef.IsFlag3D())
+ Ref2.SetFlag3D( true);
+ return *this;
+}
+
+
+ScComplexRefData& ScComplexRefData::Extend( const ScComplexRefData & rRef, const ScAddress & rPos )
+{
+ return Extend( rRef.Ref1, rPos).Extend( rRef.Ref2, rPos);
+}
diff --git a/sc/source/core/tool/reffind.cxx b/sc/source/core/tool/reffind.cxx
new file mode 100644
index 000000000000..cdb5962b2b9c
--- /dev/null
+++ b/sc/source/core/tool/reffind.cxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <string.h>
+
+#include "reffind.hxx"
+#include "global.hxx"
+#include "compiler.hxx"
+#include "document.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// incl. Doppelpunkt -> Doppelte Referenzen werden einzeln behandelt
+const sal_Unicode __FAR_DATA ScRefFinder::pDelimiters[] = {
+ '=','(',')',';','+','-','*','/','^','&',' ','{','}','<','>',':', 0
+};
+
+// =======================================================================
+
+inline BOOL IsText( sal_Unicode c )
+{
+ return !ScGlobal::UnicodeStrChr( ScRefFinder::pDelimiters, c );
+}
+
+inline BOOL IsText( BOOL& bQuote, sal_Unicode c )
+{
+ if ( c == '\'' )
+ {
+ bQuote = !bQuote;
+ return TRUE;
+ }
+ if ( bQuote )
+ return TRUE;
+ return IsText( c );
+}
+
+ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument,
+ formula::FormulaGrammar::AddressConvention eConvP) :
+ aFormula( rFormula ),
+ eConv( eConvP ),
+ pDoc( pDocument )
+{
+ nSelStart = nSelEnd = nFound = 0;
+}
+
+ScRefFinder::~ScRefFinder()
+{
+}
+
+USHORT lcl_NextFlags( USHORT nOld )
+{
+ USHORT nNew = nOld & 7; // die drei Abs-Flags
+ nNew = ( nNew - 1 ) & 7; // weiterzaehlen
+
+ if (!(nOld & SCA_TAB_3D))
+ nNew &= ~SCA_TAB_ABSOLUTE; // nicht 3D -> nie absolut!
+
+ return ( nOld & 0xfff8 ) | nNew;
+}
+
+void ScRefFinder::ToggleRel( xub_StrLen nStartPos, xub_StrLen nEndPos )
+{
+ xub_StrLen nLen = aFormula.Len();
+ if (!nLen)
+ return;
+ const sal_Unicode* pSource = aFormula.GetBuffer(); // fuer schnellen Zugriff
+
+ // Selektion erweitern, und statt Selektion Start- und Endindex
+
+ if ( nEndPos < nStartPos )
+ {
+ xub_StrLen nTemp = nStartPos; nStartPos = nEndPos; nEndPos = nTemp;
+ }
+ while (nStartPos > 0 && IsText(pSource[nStartPos - 1]) )
+ --nStartPos;
+ if (nEndPos)
+ --nEndPos;
+ while (nEndPos+1 < nLen && IsText(pSource[nEndPos + 1]) )
+ ++nEndPos;
+
+ String aResult;
+ String aExpr;
+ String aSep;
+ ScAddress aAddr;
+ nFound = 0;
+
+ xub_StrLen nLoopStart = nStartPos;
+ while ( nLoopStart <= nEndPos )
+ {
+ // Formel zerlegen
+
+ xub_StrLen nEStart = nLoopStart;
+ while ( nEStart <= nEndPos && !IsText(pSource[nEStart]) )
+ ++nEStart;
+
+ BOOL bQuote = FALSE;
+ xub_StrLen nEEnd = nEStart;
+ while ( nEEnd <= nEndPos && IsText(bQuote,pSource[nEEnd]) )
+ ++nEEnd;
+
+ aSep = aFormula.Copy( nLoopStart, nEStart-nLoopStart );
+ aExpr = aFormula.Copy( nEStart, nEEnd-nEStart );
+
+ // Test, ob aExpr eine Referenz ist
+
+ USHORT nResult = aAddr.Parse( aExpr, pDoc, pDoc->GetAddressConvention() );
+ if ( nResult & SCA_VALID )
+ {
+ USHORT nFlags = lcl_NextFlags( nResult );
+ aAddr.Format( aExpr, nFlags, pDoc, pDoc->GetAddressConvention() );
+
+ xub_StrLen nAbsStart = nStartPos+aResult.Len()+aSep.Len();
+
+ if (!nFound) // erste Referenz ?
+ nSelStart = nAbsStart;
+ nSelEnd = nAbsStart+aExpr.Len(); // Selektion, keine Indizes
+ ++nFound;
+ }
+
+ // zusammenbauen
+
+ aResult += aSep;
+ aResult += aExpr;
+
+ nLoopStart = nEEnd;
+ }
+
+ String aTotal = aFormula.Copy( 0, nStartPos );
+ aTotal += aResult;
+ aTotal += aFormula.Copy( nEndPos+1 );
+
+ aFormula = aTotal;
+}
+
+
+
+
diff --git a/sc/source/core/tool/refreshtimer.cxx b/sc/source/core/tool/refreshtimer.cxx
new file mode 100644
index 000000000000..5520aac6d6eb
--- /dev/null
+++ b/sc/source/core/tool/refreshtimer.cxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "refreshtimer.hxx"
+
+
+ScRefreshTimerProtector::ScRefreshTimerProtector( ScRefreshTimerControl * const * pp )
+ :
+ ppControl( pp )
+{
+ if ( ppControl && *ppControl )
+ {
+ (*ppControl)->SetAllowRefresh( FALSE );
+ // wait for any running refresh in another thread to finnish
+ ::vos::OGuard aGuard( (*ppControl)->GetMutex() );
+ }
+}
+
+
+ScRefreshTimer::~ScRefreshTimer()
+{
+ if ( IsActive() )
+ Stop();
+ RemoveFromControl();
+}
+
+
+void ScRefreshTimer::SetRefreshDelay( ULONG nSeconds )
+{
+ BOOL bActive = IsActive();
+ if ( bActive && !nSeconds )
+ Stop();
+ SetTimeout( nSeconds * 1000 );
+ if ( !bActive && nSeconds )
+ Start();
+}
+
+
+void ScRefreshTimer::Timeout()
+{
+ if ( ppControl && *ppControl && (*ppControl)->IsRefreshAllowed() )
+ {
+ // now we COULD make the call in another thread ...
+ ::vos::OGuard aGuard( (*ppControl)->GetMutex() );
+ maTimeoutHdl.Call( this );
+ // restart from now on, don't execute immediately again if timed out
+ // a second time during refresh
+ if ( IsActive() )
+ Start();
+ }
+}
+
diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx
new file mode 100644
index 000000000000..f4976a914c39
--- /dev/null
+++ b/sc/source/core/tool/reftokenhelper.cxx
@@ -0,0 +1,479 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "reftokenhelper.hxx"
+#include "document.hxx"
+#include "rangeutl.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+
+#include "rtl/ustring.hxx"
+#include "formula/grammar.hxx"
+#include "formula/token.hxx"
+
+using namespace formula;
+
+using ::std::vector;
+using ::std::auto_ptr;
+using ::rtl::OUString;
+
+void ScRefTokenHelper::compileRangeRepresentation(
+ vector<ScSharedTokenRef>& rRefTokens, const OUString& rRangeStr, ScDocument* pDoc, FormulaGrammar::Grammar eGrammar)
+{
+ const sal_Unicode cSep = GetScCompilerNativeSymbol(ocSep).GetChar(0);
+ const sal_Unicode cQuote = '\'';
+
+ // #i107275# ignore parentheses
+ OUString aRangeStr = rRangeStr;
+ while( (aRangeStr.getLength() >= 2) && (aRangeStr[ 0 ] == '(') && (aRangeStr[ aRangeStr.getLength() - 1 ] == ')') )
+ aRangeStr = aRangeStr.copy( 1, aRangeStr.getLength() - 2 );
+
+ bool bFailure = false;
+ sal_Int32 nOffset = 0;
+ while (nOffset >= 0 && !bFailure)
+ {
+ OUString aToken;
+ ScRangeStringConverter::GetTokenByOffset(aToken, aRangeStr, nOffset, cSep, cQuote);
+ if (nOffset < 0)
+ break;
+
+ ScCompiler aCompiler(pDoc, ScAddress(0,0,0));
+ aCompiler.SetGrammar(eGrammar);
+ auto_ptr<ScTokenArray> pArray(aCompiler.CompileString(aToken));
+
+ // 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())));
+ }
+ }
+
+#if 0
+ switch (p->GetType())
+ {
+ case svSingleRef:
+ fprintf(stdout, "ScChart2DataProvider::compileRangeRepresentation: single ref\n");
+ break;
+ case svDoubleRef:
+ fprintf(stdout, "ScChart2DataProvider::compileRangeRepresentation: double ref\n");
+ break;
+ case svExternalSingleRef:
+ fprintf(stdout, "ScChart2DataProvider::compileRangeRepresentation: external single ref\n");
+ break;
+ case svExternalDoubleRef:
+ fprintf(stdout, "ScChart2DataProvider::compileRangeRepresentation: external double ref\n");
+ break;
+ default:
+ ;
+ }
+#endif
+
+ }
+ if (bFailure)
+ rRefTokens.clear();
+}
+
+bool ScRefTokenHelper::getRangeFromToken(ScRange& rRange, const ScSharedTokenRef& pToken, bool bExternal)
+{
+ StackVar eType = pToken->GetType();
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ case svExternalSingleRef:
+ {
+ if ((eType == svExternalSingleRef && !bExternal) ||
+ (eType == svSingleRef && bExternal))
+ return false;
+
+ const ScSingleRefData& rRefData = pToken->GetSingleRef();
+ rRange.aStart.SetCol(rRefData.nCol);
+ rRange.aStart.SetRow(rRefData.nRow);
+ rRange.aStart.SetTab(rRefData.nTab);
+ rRange.aEnd = rRange.aStart;
+ return true;
+ }
+ case svDoubleRef:
+ case svExternalDoubleRef:
+ {
+ if ((eType == svExternalDoubleRef && !bExternal) ||
+ (eType == svDoubleRef && bExternal))
+ return false;
+
+ const ScComplexRefData& rRefData = pToken->GetDoubleRef();
+ rRange.aStart.SetCol(rRefData.Ref1.nCol);
+ rRange.aStart.SetRow(rRefData.Ref1.nRow);
+ rRange.aStart.SetTab(rRefData.Ref1.nTab);
+ rRange.aEnd.SetCol(rRefData.Ref2.nCol);
+ rRange.aEnd.SetRow(rRefData.Ref2.nRow);
+ rRange.aEnd.SetTab(rRefData.Ref2.nTab);
+ return true;
+ }
+ default:
+ ; // do nothing
+ }
+ return false;
+}
+
+void ScRefTokenHelper::getRangeListFromTokens(ScRangeList& rRangeList, const vector<ScSharedTokenRef>& rTokens)
+{
+ vector<ScSharedTokenRef>::const_iterator itr = rTokens.begin(), itrEnd = rTokens.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScRange aRange;
+ getRangeFromToken(aRange, *itr);
+ rRangeList.Append(aRange);
+ }
+}
+
+void ScRefTokenHelper::getTokenFromRange(ScSharedTokenRef& pToken, const ScRange& rRange)
+{
+ ScComplexRefData aData;
+ aData.InitFlags();
+ aData.Ref1.nCol = rRange.aStart.Col();
+ aData.Ref1.nRow = rRange.aStart.Row();
+ aData.Ref1.nTab = rRange.aStart.Tab();
+ aData.Ref1.SetColRel(false);
+ aData.Ref1.SetRowRel(false);
+ aData.Ref1.SetTabRel(false);
+ aData.Ref1.SetFlag3D(true);
+
+ aData.Ref2.nCol = rRange.aEnd.Col();
+ aData.Ref2.nRow = rRange.aEnd.Row();
+ aData.Ref2.nTab = rRange.aEnd.Tab();
+ aData.Ref2.SetColRel(false);
+ aData.Ref2.SetRowRel(false);
+ aData.Ref2.SetTabRel(false);
+ // Display sheet name on 2nd reference only when the 1st and 2nd refs are on
+ // different sheets.
+ aData.Ref2.SetFlag3D(aData.Ref1.nTab != aData.Ref2.nTab);
+
+ pToken.reset(new ScDoubleRefToken(aData));
+}
+
+void ScRefTokenHelper::getTokensFromRangeList(vector<ScSharedTokenRef>& pTokens, const ScRangeList& rRanges)
+{
+ vector<ScSharedTokenRef> aTokens;
+ sal_uInt32 nCount = rRanges.Count();
+ aTokens.reserve(nCount);
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ ScRange* pRange = static_cast<ScRange*>(rRanges.GetObject(i));
+ if (!pRange)
+ // failed.
+ return;
+
+ ScSharedTokenRef pToken;
+ ScRefTokenHelper::getTokenFromRange(pToken,* pRange);
+ aTokens.push_back(pToken);
+ }
+ pTokens.swap(aTokens);
+}
+
+bool ScRefTokenHelper::isRef(const ScSharedTokenRef& pToken)
+{
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ case svDoubleRef:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ return true;
+ default:
+ ;
+ }
+ return false;
+}
+
+bool ScRefTokenHelper::isExternalRef(const ScSharedTokenRef& pToken)
+{
+ switch (pToken->GetType())
+ {
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ return true;
+ default:
+ ;
+ }
+ return false;
+}
+
+bool ScRefTokenHelper::intersects(const vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& pToken)
+{
+ if (!isRef(pToken))
+ return false;
+
+ bool bExternal = isExternalRef(pToken);
+ sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
+
+ ScRange aRange;
+ getRangeFromToken(aRange, pToken, bExternal);
+
+ vector<ScSharedTokenRef>::const_iterator itr = rTokens.begin(), itrEnd = rTokens.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ const ScSharedTokenRef& p = *itr;
+ if (!isRef(p))
+ continue;
+
+ if (bExternal != isExternalRef(p))
+ continue;
+
+ ScRange aRange2;
+ getRangeFromToken(aRange2, p, bExternal);
+
+ if (bExternal && nFileId != p->GetIndex())
+ // different external file
+ continue;
+
+ if (aRange.Intersects(aRange2))
+ return true;
+ }
+ return false;
+}
+
+namespace {
+
+class JoinRefTokenRanges
+{
+public:
+ /**
+ * Insert a new reference token into the existing list of reference tokens,
+ * but in that process, try to join as many adjacent ranges as possible.
+ *
+ * @param rTokens existing list of reference tokens
+ * @param rToken new token
+ */
+ void operator() (vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& pToken)
+ {
+ join(rTokens, pToken);
+ }
+
+private:
+
+ /**
+ * Check two 1-dimensional ranges to see if they overlap each other.
+ *
+ * @param nMin1 min value of range 1
+ * @param nMax1 max value of range 1
+ * @param nMin2 min value of range 2
+ * @param nMax2 max value of range 2
+ * @param rNewMin min value of new range in case they overlap
+ * @param rNewMax max value of new range in case they overlap
+ */
+ template<typename T>
+ static bool overlaps(T nMin1, T nMax1, T nMin2, T nMax2, T& rNewMin, T& rNewMax)
+ {
+ bool bDisjoint1 = (nMin1 > nMax2) && (nMin1 - nMax2 > 1);
+ bool bDisjoint2 = (nMin2 > nMax1) && (nMin2 - nMax1 > 1);
+ if (bDisjoint1 || bDisjoint2)
+ // These two ranges cannot be joined. Move on.
+ return false;
+
+ T nMin = nMin1 < nMin2 ? nMin1 : nMin2;
+ T nMax = nMax1 > nMax2 ? nMax1 : nMax2;
+
+ rNewMin = nMin;
+ rNewMax = nMax;
+
+ return true;
+ }
+
+ bool isContained(const ScComplexRefData& aOldData, const ScComplexRefData& aData) const
+ {
+ // Check for containment.
+ bool bRowsContained = (aOldData.Ref1.nRow <= aData.Ref1.nRow) && (aData.Ref2.nRow <= aOldData.Ref2.nRow);
+ bool bColsContained = (aOldData.Ref1.nCol <= aData.Ref1.nCol) && (aData.Ref2.nCol <= aOldData.Ref2.nCol);
+ return (bRowsContained && bColsContained);
+ }
+
+ void join(vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& pToken)
+ {
+ // Normalize the token to a double reference.
+ ScComplexRefData aData;
+ if (!ScRefTokenHelper::getDoubleRefDataFromToken(aData, pToken))
+ return;
+
+ // Get the information of the new token.
+ bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
+ sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
+ String aTabName = bExternal ? pToken->GetString() : String();
+
+ bool bJoined = false;
+ vector<ScSharedTokenRef>::iterator itr = rTokens.begin(), itrEnd = rTokens.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScSharedTokenRef& pOldToken = *itr;
+
+ if (!ScRefTokenHelper::isRef(pOldToken))
+ // A non-ref token should not have been added here in the first
+ // place!
+ continue;
+
+ if (bExternal != ScRefTokenHelper::isExternalRef(pOldToken))
+ // External and internal refs don't mix.
+ continue;
+
+ if (bExternal)
+ {
+ if (nFileId != pOldToken->GetIndex())
+ // Different external files.
+ continue;
+
+ if (aTabName != pOldToken->GetString())
+ // Different table names.
+ continue;
+ }
+
+ ScComplexRefData aOldData;
+ if (!ScRefTokenHelper::getDoubleRefDataFromToken(aOldData, pOldToken))
+ continue;
+
+ if (aData.Ref1.nTab != aOldData.Ref1.nTab || aData.Ref2.nTab != aOldData.Ref2.nTab)
+ // Sheet ranges differ.
+ continue;
+
+ if (isContained(aOldData, aData))
+ // This new range is part of an existing range. Skip it.
+ return;
+
+ bool bSameRows = (aData.Ref1.nRow == aOldData.Ref1.nRow) && (aData.Ref2.nRow == aOldData.Ref2.nRow);
+ bool bSameCols = (aData.Ref1.nCol == aOldData.Ref1.nCol) && (aData.Ref2.nCol == aOldData.Ref2.nCol);
+ ScComplexRefData aNewData = aOldData;
+ bool bJoinRanges = false;
+ if (bSameRows)
+ {
+ bJoinRanges = overlaps(
+ aData.Ref1.nCol, aData.Ref2.nCol, aOldData.Ref1.nCol, aOldData.Ref2.nCol,
+ aNewData.Ref1.nCol, aNewData.Ref2.nCol);
+ }
+ else if (bSameCols)
+ {
+ bJoinRanges = overlaps(
+ aData.Ref1.nRow, aData.Ref2.nRow, aOldData.Ref1.nRow, aOldData.Ref2.nRow,
+ aNewData.Ref1.nRow, aNewData.Ref2.nRow);
+ }
+
+ if (bJoinRanges)
+ {
+ if (bExternal)
+ pOldToken.reset(new ScExternalDoubleRefToken(nFileId, aTabName, aNewData));
+ else
+ pOldToken.reset(new ScDoubleRefToken(aNewData));
+
+ bJoined = true;
+ break;
+ }
+ }
+
+ if (bJoined)
+ {
+ if (rTokens.size() == 1)
+ // There is only one left. No need to do more joining.
+ return;
+
+ // Pop the last token from the list, and keep joining recursively.
+ ScSharedTokenRef p = rTokens.back();
+ rTokens.pop_back();
+ join(rTokens, p);
+ }
+ else
+ rTokens.push_back(pToken);
+ }
+};
+
+}
+
+void ScRefTokenHelper::join(vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& pToken)
+{
+ JoinRefTokenRanges join;
+ join(rTokens, pToken);
+}
+
+bool ScRefTokenHelper::getDoubleRefDataFromToken(ScComplexRefData& rData, const ScSharedTokenRef& pToken)
+{
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ case svExternalSingleRef:
+ {
+ const ScSingleRefData& r = pToken->GetSingleRef();
+ rData.Ref1 = r;
+ rData.Ref1.SetFlag3D(true);
+ rData.Ref2 = r;
+ rData.Ref2.SetFlag3D(false); // Don't display sheet name on second reference.
+ }
+ break;
+ case svDoubleRef:
+ case svExternalDoubleRef:
+ rData = pToken->GetDoubleRef();
+ break;
+ default:
+ // Not a reference token. Bail out.
+ return false;
+ }
+ return true;
+}
diff --git a/sc/source/core/tool/refupdat.cxx b/sc/source/core/tool/refupdat.cxx
new file mode 100644
index 000000000000..ad11190be75d
--- /dev/null
+++ b/sc/source/core/tool/refupdat.cxx
@@ -0,0 +1,939 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "refupdat.hxx"
+#include "document.hxx"
+#include "compiler.hxx"
+#include "bigrange.hxx"
+#include "chgtrack.hxx"
+
+//------------------------------------------------------------------------
+
+template< typename R, typename S, typename U >
+BOOL lcl_MoveStart( R& rRef, U nStart, S nDelta, U nMask )
+{
+ BOOL bCut = FALSE;
+ if ( rRef >= nStart )
+ rRef = sal::static_int_cast<R>( rRef + nDelta );
+ else if ( nDelta < 0 && rRef >= nStart + nDelta )
+ rRef = nStart + nDelta; //! begrenzen ???
+ if ( rRef < 0 )
+ {
+ rRef = 0;
+ bCut = TRUE;
+ }
+ else if ( rRef > nMask )
+ {
+ rRef = nMask;
+ bCut = TRUE;
+ }
+ return bCut;
+}
+
+template< typename R, typename S, typename U >
+BOOL lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask )
+{
+ BOOL bCut = FALSE;
+ if ( rRef >= nStart )
+ rRef = sal::static_int_cast<R>( rRef + nDelta );
+ else if ( nDelta < 0 && rRef >= nStart + nDelta )
+ rRef = nStart + nDelta - 1; //! begrenzen ???
+ if ( rRef < 0 )
+ {
+ rRef = 0;
+ bCut = TRUE;
+ }
+ else if ( rRef > nMask )
+ {
+ rRef = nMask;
+ bCut = TRUE;
+ }
+ return bCut;
+}
+
+template< typename R, typename S, typename U >
+BOOL lcl_MoveReorder( R& rRef, U nStart, U nEnd, S nDelta )
+{
+ if ( rRef >= nStart && rRef <= nEnd )
+ {
+ rRef = sal::static_int_cast<R>( rRef + nDelta );
+ return TRUE;
+ }
+
+ if ( nDelta > 0 ) // nach hinten schieben
+ {
+ if ( rRef >= nStart && rRef <= nEnd + nDelta )
+ {
+ if ( rRef <= nEnd )
+ rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range
+ else
+ rRef -= nEnd - nStart + 1; // nachruecken
+ return TRUE;
+ }
+ }
+ else // nach vorne schieben
+ {
+ if ( rRef >= nStart + nDelta && rRef <= nEnd )
+ {
+ if ( rRef >= nStart )
+ rRef = sal::static_int_cast<R>( rRef + nDelta ); // in the moved range
+ else
+ rRef += nEnd - nStart + 1; // nachruecken
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+template< typename R, typename S, typename U >
+BOOL lcl_MoveItCut( R& rRef, S nDelta, U nMask )
+{
+ BOOL bCut = FALSE;
+ rRef = sal::static_int_cast<R>( rRef + nDelta );
+ if ( rRef < 0 )
+ {
+ rRef = 0;
+ bCut = TRUE;
+ }
+ else if ( rRef > nMask )
+ {
+ rRef = nMask;
+ bCut = TRUE;
+ }
+ return bCut;
+}
+
+template< typename R, typename S, typename U >
+void lcl_MoveItWrap( R& rRef, S nDelta, U nMask )
+{
+ rRef = sal::static_int_cast<R>( rRef + nDelta );
+ if ( rRef < 0 )
+ rRef += nMask+1;
+ else if ( rRef > nMask )
+ rRef -= nMask+1;
+}
+
+template< typename R, typename S, typename U >
+BOOL lcl_MoveRefPart( R& rRef1Val, BOOL& rRef1Del, BOOL bDo1,
+ R& rRef2Val, BOOL& rRef2Del, BOOL bDo2,
+ U nStart, U nEnd, S nDelta, U nMask )
+{
+ if ( nDelta )
+ {
+ BOOL bDel, bCut1, bCut2;
+ bDel = bCut1 = bCut2 = FALSE;
+ S n;
+ if (bDo1 && bDo2)
+ {
+ if ( nDelta < 0 )
+ {
+ n = nStart + nDelta;
+ if ( n <= rRef1Val && rRef1Val < nStart
+ && n <= rRef2Val && rRef2Val < nStart )
+ bDel = TRUE;
+ }
+ else
+ {
+ n = nEnd + nDelta;
+ if ( nEnd < rRef1Val && rRef1Val <= n
+ && nEnd < rRef2Val && rRef2Val <= n )
+ bDel = TRUE;
+ }
+ }
+ if ( bDel )
+ { // move deleted along
+ rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta );
+ rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta );
+ }
+ else
+ {
+ if (bDo1)
+ {
+ if ( rRef1Del )
+ rRef1Val = sal::static_int_cast<R>( rRef1Val + nDelta );
+ else
+ bCut1 = lcl_MoveStart( rRef1Val, nStart, nDelta, nMask );
+ }
+ if (bDo2)
+ {
+ if ( rRef2Del )
+ rRef2Val = sal::static_int_cast<R>( rRef2Val + nDelta );
+ else
+ bCut2 = lcl_MoveEnd( rRef2Val, nStart, nDelta, nMask );
+ }
+ }
+ if ( bDel || (bCut1 && bCut2) )
+ rRef1Del = rRef2Del = TRUE;
+ return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del;
+ }
+ else
+ return FALSE;
+}
+
+template< typename R, typename S, typename U >
+BOOL IsExpand( R n1, R n2, U nStart, S nD )
+{ //! vor normalem Move...
+ return
+ nD > 0 // Insert
+ && n1 < n2 // mindestens zwei Cols/Rows/Tabs in Ref
+ && (
+ (nStart <= n1 && n1 < nStart + nD) // n1 innerhalb des Insert
+ || (n2 + 1 == nStart) // n2 direkt vor Insert
+ ); // n1 < nStart <= n2 wird sowieso expanded!
+}
+
+
+template< typename R, typename S, typename U >
+void Expand( R& n1, R& n2, U nStart, S nD )
+{ //! nach normalem Move..., nur wenn IsExpand vorher TRUE war!
+ //! erst das Ende
+ if ( n2 + 1 == nStart )
+ { // am Ende
+ n2 = sal::static_int_cast<R>( n2 + nD );
+ return;
+ }
+ // am Anfang
+ n1 = sal::static_int_cast<R>( n1 - nD );
+}
+
+
+BOOL lcl_IsWrapBig( INT32 nRef, INT32 nDelta )
+{
+ if ( nRef > 0 && nDelta > 0 )
+ return nRef + nDelta <= 0;
+ else if ( nRef < 0 && nDelta < 0 )
+ return nRef + nDelta >= 0;
+ return FALSE;
+}
+
+
+BOOL lcl_MoveBig( INT32& rRef, INT32 nStart, INT32 nDelta )
+{
+ BOOL bCut = FALSE;
+ if ( rRef >= nStart )
+ {
+ if ( nDelta > 0 )
+ bCut = lcl_IsWrapBig( rRef, nDelta );
+ if ( bCut )
+ rRef = nInt32Max;
+ else
+ rRef += nDelta;
+ }
+ return bCut;
+}
+
+BOOL lcl_MoveItCutBig( INT32& rRef, INT32 nDelta )
+{
+ BOOL bCut = lcl_IsWrapBig( rRef, nDelta );
+ rRef += nDelta;
+ return bCut;
+}
+
+
+ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1,
+ SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 )
+{
+ ScRefUpdateRes eRet = UR_NOTHING;
+
+ SCCOL oldCol1 = theCol1;
+ SCROW oldRow1 = theRow1;
+ SCTAB oldTab1 = theTab1;
+ SCCOL oldCol2 = theCol2;
+ SCROW oldRow2 = theRow2;
+ SCTAB oldTab2 = theTab2;
+
+ BOOL bCut1, bCut2;
+
+ if (eUpdateRefMode == URM_INSDEL)
+ {
+ BOOL bExpand = pDoc->IsExpandRefs();
+ if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
+ (theTab1 >= nTab1) && (theTab2 <= nTab2) )
+ {
+ BOOL bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx ));
+ bCut1 = lcl_MoveStart( theCol1, nCol1, nDx, MAXCOL );
+ bCut2 = lcl_MoveEnd( theCol2, nCol1, nDx, MAXCOL );
+ if ( theCol2 < theCol1 )
+ {
+ eRet = UR_INVALID;
+ theCol2 = theCol1;
+ }
+ else if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ if ( bExp )
+ {
+ Expand( theCol1, theCol2, nCol1, nDx );
+ eRet = UR_UPDATED;
+ }
+ }
+ if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
+ (theTab1 >= nTab1) && (theTab2 <= nTab2) )
+ {
+ BOOL bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy ));
+ bCut1 = lcl_MoveStart( theRow1, nRow1, nDy, MAXROW );
+ bCut2 = lcl_MoveEnd( theRow2, nRow1, nDy, MAXROW );
+ if ( theRow2 < theRow1 )
+ {
+ eRet = UR_INVALID;
+ theRow2 = theRow1;
+ }
+ else if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ if ( bExp )
+ {
+ Expand( theRow1, theRow2, nRow1, nDy );
+ eRet = UR_UPDATED;
+ }
+ }
+ if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
+ (theRow1 >= nRow1) && (theRow2 <= nRow2) )
+ {
+ SCsTAB nMaxTab = pDoc->GetTableCount() - 1;
+ nMaxTab = sal::static_int_cast<SCsTAB>(nMaxTab + nDz); // adjust to new count
+ BOOL bExp = (bExpand && IsExpand( theTab1, theTab2, nTab1, nDz ));
+ bCut1 = lcl_MoveStart( theTab1, nTab1, nDz, static_cast<SCTAB>(nMaxTab) );
+ bCut2 = lcl_MoveEnd( theTab2, nTab1, nDz, static_cast<SCTAB>(nMaxTab) );
+ if ( theTab2 < theTab1 )
+ {
+ eRet = UR_INVALID;
+ theTab2 = theTab1;
+ }
+ else if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ if ( bExp )
+ {
+ Expand( theTab1, theTab2, nTab1, nDz );
+ eRet = UR_UPDATED;
+ }
+ }
+ }
+ else if (eUpdateRefMode == URM_MOVE)
+ {
+ if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) &&
+ (theCol2 <= nCol2-nDx) && (theRow2 <= nRow2-nDy) && (theTab2 <= nTab2-nDz))
+ {
+ if ( nDx )
+ {
+ bCut1 = lcl_MoveItCut( theCol1, nDx, MAXCOL );
+ bCut2 = lcl_MoveItCut( theCol2, nDx, MAXCOL );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ }
+ if ( nDy )
+ {
+ bCut1 = lcl_MoveItCut( theRow1, nDy, MAXROW );
+ bCut2 = lcl_MoveItCut( theRow2, nDy, MAXROW );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ }
+ if ( nDz )
+ {
+ SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
+ bCut1 = lcl_MoveItCut( theTab1, nDz, static_cast<SCTAB>(nMaxTab) );
+ bCut2 = lcl_MoveItCut( theTab2, nDz, static_cast<SCTAB>(nMaxTab) );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ }
+ }
+ }
+ else if (eUpdateRefMode == URM_REORDER)
+ {
+ // bisher nur fuer nDz (MoveTab)
+ DBG_ASSERT ( !nDx && !nDy, "URM_REORDER fuer x und y noch nicht implementiert" );
+
+ if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
+ (theRow1 >= nRow1) && (theRow2 <= nRow2) )
+ {
+ bCut1 = lcl_MoveReorder( theTab1, nTab1, nTab2, nDz );
+ bCut2 = lcl_MoveReorder( theTab2, nTab1, nTab2, nDz );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ }
+ }
+
+ if ( eRet == UR_NOTHING )
+ {
+ if (oldCol1 != theCol1
+ || oldRow1 != theRow1
+ || oldTab1 != theTab1
+ || oldCol2 != theCol2
+ || oldRow2 != theRow2
+ || oldTab2 != theTab2
+ )
+ eRet = UR_UPDATED;
+ }
+ return eRet;
+}
+
+
+// simples UpdateReference fuer ScBigRange (ScChangeAction/ScChangeTrack)
+// Referenzen koennen auch ausserhalb des Dokuments liegen!
+// Ganze Spalten/Zeilen (nInt32Min..nInt32Max) bleiben immer solche!
+ScRefUpdateRes ScRefUpdate::Update( UpdateRefMode eUpdateRefMode,
+ const ScBigRange& rWhere, INT32 nDx, INT32 nDy, INT32 nDz,
+ ScBigRange& rWhat )
+{
+ ScRefUpdateRes eRet = UR_NOTHING;
+ const ScBigRange aOldRange( rWhat );
+
+ INT32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2;
+ INT32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2;
+ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
+
+ BOOL bCut1, bCut2;
+
+ if (eUpdateRefMode == URM_INSDEL)
+ {
+ if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
+ (theTab1 >= nTab1) && (theTab2 <= nTab2) &&
+ !(theCol1 == nInt32Min && theCol2 == nInt32Max) )
+ {
+ bCut1 = lcl_MoveBig( theCol1, nCol1, nDx );
+ bCut2 = lcl_MoveBig( theCol2, nCol1, nDx );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ rWhat.aStart.SetCol( theCol1 );
+ rWhat.aEnd.SetCol( theCol2 );
+ }
+ if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
+ (theTab1 >= nTab1) && (theTab2 <= nTab2) &&
+ !(theRow1 == nInt32Min && theRow2 == nInt32Max) )
+ {
+ bCut1 = lcl_MoveBig( theRow1, nRow1, nDy );
+ bCut2 = lcl_MoveBig( theRow2, nRow1, nDy );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ rWhat.aStart.SetRow( theRow1 );
+ rWhat.aEnd.SetRow( theRow2 );
+ }
+ if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) &&
+ (theRow1 >= nRow1) && (theRow2 <= nRow2) &&
+ !(theTab1 == nInt32Min && theTab2 == nInt32Max) )
+ {
+ bCut1 = lcl_MoveBig( theTab1, nTab1, nDz );
+ bCut2 = lcl_MoveBig( theTab2, nTab1, nDz );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ rWhat.aStart.SetTab( theTab1 );
+ rWhat.aEnd.SetTab( theTab2 );
+ }
+ }
+ else if (eUpdateRefMode == URM_MOVE)
+ {
+ if ( rWhere.In( rWhat ) )
+ {
+ if ( nDx && !(theCol1 == nInt32Min && theCol2 == nInt32Max) )
+ {
+ bCut1 = lcl_MoveItCutBig( theCol1, nDx );
+ bCut2 = lcl_MoveItCutBig( theCol2, nDx );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ rWhat.aStart.SetCol( theCol1 );
+ rWhat.aEnd.SetCol( theCol2 );
+ }
+ if ( nDy && !(theRow1 == nInt32Min && theRow2 == nInt32Max) )
+ {
+ bCut1 = lcl_MoveItCutBig( theRow1, nDy );
+ bCut2 = lcl_MoveItCutBig( theRow2, nDy );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ rWhat.aStart.SetRow( theRow1 );
+ rWhat.aEnd.SetRow( theRow2 );
+ }
+ if ( nDz && !(theTab1 == nInt32Min && theTab2 == nInt32Max) )
+ {
+ bCut1 = lcl_MoveItCutBig( theTab1, nDz );
+ bCut2 = lcl_MoveItCutBig( theTab2, nDz );
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ rWhat.aStart.SetTab( theTab1 );
+ rWhat.aEnd.SetTab( theTab2 );
+ }
+ }
+ }
+
+ if ( eRet == UR_NOTHING && rWhat != aOldRange )
+ eRet = UR_UPDATED;
+
+ return eRet;
+}
+
+
+ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eMode,
+ const ScAddress& rPos, const ScRange& r,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScComplexRefData& rRef, WhatType eWhat )
+{
+ ScRefUpdateRes eRet = UR_NOTHING;
+
+ SCCOL nCol1 = r.aStart.Col();
+ SCROW nRow1 = r.aStart.Row();
+ SCTAB nTab1 = r.aStart.Tab();
+ SCCOL nCol2 = r.aEnd.Col();
+ SCROW nRow2 = r.aEnd.Row();
+ SCTAB nTab2 = r.aEnd.Tab();
+
+ if( eMode == URM_INSDEL )
+ {
+ BOOL bExpand = pDoc->IsExpandRefs();
+
+ const ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ BOOL bInDeleteUndo =
+ ( pChangeTrack ? pChangeTrack->IsInDeleteUndo() : FALSE );
+
+ SCCOL oldCol1 = rRef.Ref1.nCol;
+ SCROW oldRow1 = rRef.Ref1.nRow;
+ SCTAB oldTab1 = rRef.Ref1.nTab;
+ SCCOL oldCol2 = rRef.Ref2.nCol;
+ SCROW oldRow2 = rRef.Ref2.nRow;
+ SCTAB oldTab2 = rRef.Ref2.nTab;
+
+ BOOL bRef1ColDel = rRef.Ref1.IsColDeleted();
+ BOOL bRef2ColDel = rRef.Ref2.IsColDeleted();
+ BOOL bRef1RowDel = rRef.Ref1.IsRowDeleted();
+ BOOL bRef2RowDel = rRef.Ref2.IsRowDeleted();
+ BOOL bRef1TabDel = rRef.Ref1.IsTabDeleted();
+ BOOL bRef2TabDel = rRef.Ref2.IsTabDeleted();
+
+ if( nDx &&
+ ((rRef.Ref1.nRow >= nRow1
+ && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel))
+ &&
+ ((rRef.Ref1.nTab >= nTab1
+ && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel))
+ )
+ {
+ BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nCol,
+ rRef.Ref2.nCol, nCol1, nDx ));
+ BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat ==
+ ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsColRel()));
+ BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat ==
+ ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsColRel()));
+ if ( lcl_MoveRefPart( rRef.Ref1.nCol, bRef1ColDel, bDo1,
+ rRef.Ref2.nCol, bRef2ColDel, bDo2,
+ nCol1, nCol2, nDx, MAXCOL ) )
+ {
+ eRet = UR_UPDATED;
+ if ( bInDeleteUndo && (bRef1ColDel || bRef2ColDel) )
+ {
+ if ( bRef1ColDel && nCol1 <= rRef.Ref1.nCol &&
+ rRef.Ref1.nCol <= nCol1 + nDx )
+ rRef.Ref1.SetColDeleted( FALSE );
+ if ( bRef2ColDel && nCol1 <= rRef.Ref2.nCol &&
+ rRef.Ref2.nCol <= nCol1 + nDx )
+ rRef.Ref2.SetColDeleted( FALSE );
+ }
+ else
+ {
+ if ( bRef1ColDel )
+ rRef.Ref1.SetColDeleted( TRUE );
+ if ( bRef2ColDel )
+ rRef.Ref2.SetColDeleted( TRUE );
+ }
+ }
+ if ( bExp )
+ {
+ Expand( rRef.Ref1.nCol, rRef.Ref2.nCol, nCol1, nDx );
+ eRet = UR_UPDATED;
+ }
+ }
+ if( nDy &&
+ ((rRef.Ref1.nCol >= nCol1
+ && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel))
+ &&
+ ((rRef.Ref1.nTab >= nTab1
+ && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel))
+ )
+ {
+ BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nRow,
+ rRef.Ref2.nRow, nRow1, nDy ));
+ BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat ==
+ ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsRowRel()));
+ BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat ==
+ ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsRowRel()));
+ if ( lcl_MoveRefPart( rRef.Ref1.nRow, bRef1RowDel, bDo1,
+ rRef.Ref2.nRow, bRef2RowDel, bDo2,
+ nRow1, nRow2, nDy, MAXROW ) )
+ {
+ eRet = UR_UPDATED;
+ if ( bInDeleteUndo && (bRef1RowDel || bRef2RowDel) )
+ {
+ if ( bRef1RowDel && nRow1 <= rRef.Ref1.nRow &&
+ rRef.Ref1.nRow <= nRow1 + nDy )
+ rRef.Ref1.SetRowDeleted( FALSE );
+ if ( bRef2RowDel && nRow1 <= rRef.Ref2.nRow &&
+ rRef.Ref2.nRow <= nRow1 + nDy )
+ rRef.Ref2.SetRowDeleted( FALSE );
+ }
+ else
+ {
+ if ( bRef1RowDel )
+ rRef.Ref1.SetRowDeleted( TRUE );
+ if ( bRef2RowDel )
+ rRef.Ref2.SetRowDeleted( TRUE );
+ }
+ }
+ if ( bExp )
+ {
+ Expand( rRef.Ref1.nRow, rRef.Ref2.nRow, nRow1, nDy );
+ eRet = UR_UPDATED;
+ }
+ }
+ if( nDz &&
+ ((rRef.Ref1.nCol >= nCol1
+ && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel))
+ &&
+ ((rRef.Ref1.nRow >= nRow1
+ && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel))
+ )
+ {
+ BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nTab,
+ rRef.Ref2.nTab, nTab1, nDz ));
+ SCTAB nMaxTab = pDoc->GetTableCount() - 1;
+ BOOL bDo1 = (eWhat == ScRefUpdate::ALL || (eWhat ==
+ ScRefUpdate::ABSOLUTE && !rRef.Ref1.IsTabRel()));
+ BOOL bDo2 = (eWhat == ScRefUpdate::ALL || (eWhat ==
+ ScRefUpdate::ABSOLUTE && !rRef.Ref2.IsTabRel()));
+ if ( lcl_MoveRefPart( rRef.Ref1.nTab, bRef1TabDel, bDo1,
+ rRef.Ref2.nTab, bRef2TabDel, bDo2,
+ nTab1, nTab2, nDz, nMaxTab ) )
+ {
+ eRet = UR_UPDATED;
+ if ( bInDeleteUndo && (bRef1TabDel || bRef2TabDel) )
+ {
+ if ( bRef1TabDel && nTab1 <= rRef.Ref1.nTab &&
+ rRef.Ref1.nTab <= nTab1 + nDz )
+ rRef.Ref1.SetTabDeleted( FALSE );
+ if ( bRef2TabDel && nTab1 <= rRef.Ref2.nTab &&
+ rRef.Ref2.nTab <= nTab1 + nDz )
+ rRef.Ref2.SetTabDeleted( FALSE );
+ }
+ else
+ {
+ if ( bRef1TabDel )
+ rRef.Ref1.SetTabDeleted( TRUE );
+ if ( bRef2TabDel )
+ rRef.Ref2.SetTabDeleted( TRUE );
+ }
+ }
+ if ( bExp )
+ {
+ Expand( rRef.Ref1.nTab, rRef.Ref2.nTab, nTab1, nDz );
+ eRet = UR_UPDATED;
+ }
+ }
+ if ( eRet == UR_NOTHING )
+ {
+ if (oldCol1 != rRef.Ref1.nCol
+ || oldRow1 != rRef.Ref1.nRow
+ || oldTab1 != rRef.Ref1.nTab
+ || oldCol2 != rRef.Ref2.nCol
+ || oldRow2 != rRef.Ref2.nRow
+ || oldTab2 != rRef.Ref2.nTab
+ )
+ eRet = UR_UPDATED;
+ }
+ if (eWhat != ScRefUpdate::ABSOLUTE)
+ rRef.CalcRelFromAbs( rPos );
+ }
+ else
+ {
+ if( eMode == URM_MOVE )
+ {
+ if ( rRef.Ref1.nCol >= nCol1-nDx
+ && rRef.Ref1.nRow >= nRow1-nDy
+ && rRef.Ref1.nTab >= nTab1-nDz
+ && rRef.Ref2.nCol <= nCol2-nDx
+ && rRef.Ref2.nRow <= nRow2-nDy
+ && rRef.Ref2.nTab <= nTab2-nDz )
+ {
+ eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, TRUE ); // immer verschieben
+ }
+ else if ( nDz && r.In( rPos ) )
+ {
+ rRef.Ref1.SetFlag3D( TRUE );
+ rRef.Ref2.SetFlag3D( TRUE );
+ eRet = UR_UPDATED;
+ if (eWhat != ScRefUpdate::ABSOLUTE)
+ rRef.CalcRelFromAbs( rPos );
+ }
+ else if (eWhat != ScRefUpdate::ABSOLUTE)
+ rRef.CalcRelFromAbs( rPos );
+ }
+ else if( eMode == URM_COPY && r.In( rPos ) )
+ eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, FALSE ); // nur relative
+ // sollte nicht mehr verwendet werden muessen
+ else if (eWhat != ScRefUpdate::ABSOLUTE)
+ rRef.CalcRelFromAbs( rPos );
+ }
+ return eRet;
+}
+
+
+ScRefUpdateRes ScRefUpdate::Move( ScDocument* pDoc, const ScAddress& rPos,
+ SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+ ScComplexRefData& rRef, BOOL bWrap, BOOL bAbsolute )
+{
+ ScRefUpdateRes eRet = UR_NOTHING;
+
+ SCCOL oldCol1 = rRef.Ref1.nCol;
+ SCROW oldRow1 = rRef.Ref1.nRow;
+ SCTAB oldTab1 = rRef.Ref1.nTab;
+ SCCOL oldCol2 = rRef.Ref2.nCol;
+ SCROW oldRow2 = rRef.Ref2.nRow;
+ SCTAB oldTab2 = rRef.Ref2.nTab;
+
+ BOOL bCut1, bCut2;
+ if ( nDx )
+ {
+ bCut1 = bCut2 = FALSE;
+ if( bAbsolute || rRef.Ref1.IsColRel() )
+ {
+ if( bWrap )
+ lcl_MoveItWrap( rRef.Ref1.nCol, nDx, MAXCOL );
+ else
+ bCut1 = lcl_MoveItCut( rRef.Ref1.nCol, nDx, MAXCOL );
+ }
+ if( bAbsolute || rRef.Ref2.IsColRel() )
+ {
+ if( bWrap )
+ lcl_MoveItWrap( rRef.Ref2.nCol, nDx, MAXCOL );
+ else
+ bCut2 = lcl_MoveItCut( rRef.Ref2.nCol, nDx, MAXCOL );
+ }
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ if ( bCut1 && bCut2 )
+ {
+ rRef.Ref1.SetColDeleted( TRUE );
+ rRef.Ref2.SetColDeleted( TRUE );
+ }
+ }
+ if ( nDy )
+ {
+ bCut1 = bCut2 = FALSE;
+ if( bAbsolute || rRef.Ref1.IsRowRel() )
+ {
+ if( bWrap )
+ lcl_MoveItWrap( rRef.Ref1.nRow, nDy, MAXROW );
+ else
+ bCut1 = lcl_MoveItCut( rRef.Ref1.nRow, nDy, MAXROW );
+ }
+ if( bAbsolute || rRef.Ref2.IsRowRel() )
+ {
+ if( bWrap )
+ lcl_MoveItWrap( rRef.Ref2.nRow, nDy, MAXROW );
+ else
+ bCut2 = lcl_MoveItCut( rRef.Ref2.nRow, nDy, MAXROW );
+ }
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ if ( bCut1 && bCut2 )
+ {
+ rRef.Ref1.SetRowDeleted( TRUE );
+ rRef.Ref2.SetRowDeleted( TRUE );
+ }
+ }
+ if ( nDz )
+ {
+ bCut1 = bCut2 = FALSE;
+ SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
+ if( bAbsolute || rRef.Ref1.IsTabRel() )
+ {
+ if( bWrap )
+ lcl_MoveItWrap( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
+ else
+ bCut1 = lcl_MoveItCut( rRef.Ref1.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
+ rRef.Ref1.SetFlag3D( rPos.Tab() != rRef.Ref1.nTab );
+ }
+ if( bAbsolute || rRef.Ref2.IsTabRel() )
+ {
+ if( bWrap )
+ lcl_MoveItWrap( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
+ else
+ bCut2 = lcl_MoveItCut( rRef.Ref2.nTab, nDz, static_cast<SCTAB>(nMaxTab) );
+ rRef.Ref2.SetFlag3D( rPos.Tab() != rRef.Ref2.nTab );
+ }
+ if ( bCut1 || bCut2 )
+ eRet = UR_UPDATED;
+ if ( bCut1 && bCut2 )
+ {
+ rRef.Ref1.SetTabDeleted( TRUE );
+ rRef.Ref2.SetTabDeleted( TRUE );
+ }
+ }
+
+ if ( eRet == UR_NOTHING )
+ {
+ if (oldCol1 != rRef.Ref1.nCol
+ || oldRow1 != rRef.Ref1.nRow
+ || oldTab1 != rRef.Ref1.nTab
+ || oldCol2 != rRef.Ref2.nCol
+ || oldRow2 != rRef.Ref2.nRow
+ || oldTab2 != rRef.Ref2.nTab
+ )
+ eRet = UR_UPDATED;
+ }
+ if ( bWrap && eRet != UR_NOTHING )
+ rRef.PutInOrder();
+ rRef.CalcRelFromAbs( rPos );
+ return eRet;
+}
+
+void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos,
+ 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), nMaxCol );
+ }
+ if( rRef.Ref2.IsColRel() )
+ {
+ rRef.Ref2.nCol = rRef.Ref2.nRelCol + rPos.Col();
+ 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), nMaxRow );
+ }
+ if( rRef.Ref2.IsRowRel() )
+ {
+ rRef.Ref2.nRow = rRef.Ref2.nRelRow + rPos.Row();
+ lcl_MoveItWrap( rRef.Ref2.nRow, static_cast<SCsROW>(0), nMaxRow );
+ }
+ SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
+ if( rRef.Ref1.IsTabRel() )
+ {
+ rRef.Ref1.nTab = rRef.Ref1.nRelTab + rPos.Tab();
+ lcl_MoveItWrap( rRef.Ref1.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) );
+ }
+ if( rRef.Ref2.IsTabRel() )
+ {
+ rRef.Ref2.nTab = rRef.Ref2.nRelTab + rPos.Tab();
+ lcl_MoveItWrap( rRef.Ref2.nTab, static_cast<SCsTAB>(0), static_cast<SCTAB>(nMaxTab) );
+ }
+ rRef.PutInOrder();
+ rRef.CalcRelFromAbs( rPos );
+}
+
+//------------------------------------------------------------------
+
+void ScRefUpdate::DoTranspose( SCsCOL& rCol, SCsROW& rRow, SCsTAB& rTab,
+ ScDocument* pDoc, const ScRange& rSource, const ScAddress& rDest )
+{
+ SCsTAB nDz = ((SCsTAB)rDest.Tab())-(SCsTAB)rSource.aStart.Tab();
+ if (nDz)
+ {
+ SCsTAB nNewTab = rTab+nDz;
+ SCsTAB nCount = pDoc->GetTableCount();
+ while (nNewTab<0) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab + nCount );
+ while (nNewTab>=nCount) nNewTab = sal::static_int_cast<SCsTAB>( nNewTab - nCount );
+ rTab = nNewTab;
+ }
+ DBG_ASSERT( rCol>=rSource.aStart.Col() && rRow>=rSource.aStart.Row(),
+ "UpdateTranspose: Pos. falsch" );
+
+ SCsCOL nRelX = rCol - (SCsCOL)rSource.aStart.Col();
+ SCsROW nRelY = rRow - (SCsROW)rSource.aStart.Row();
+
+ rCol = static_cast<SCsCOL>(static_cast<SCsCOLROW>(rDest.Col()) +
+ static_cast<SCsCOLROW>(nRelY));
+ rRow = static_cast<SCsROW>(static_cast<SCsCOLROW>(rDest.Row()) +
+ static_cast<SCsCOLROW>(nRelX));
+}
+
+
+ScRefUpdateRes ScRefUpdate::UpdateTranspose( ScDocument* pDoc,
+ const ScRange& rSource, const ScAddress& rDest,
+ ScComplexRefData& rRef )
+{
+ ScRefUpdateRes eRet = UR_NOTHING;
+ if ( rRef.Ref1.nCol >= rSource.aStart.Col() && rRef.Ref2.nCol <= rSource.aEnd.Col() &&
+ rRef.Ref1.nRow >= rSource.aStart.Row() && rRef.Ref2.nRow <= rSource.aEnd.Row() &&
+ rRef.Ref1.nTab >= rSource.aStart.Tab() && rRef.Ref2.nTab <= rSource.aEnd.Tab() )
+ {
+ DoTranspose( rRef.Ref1.nCol, rRef.Ref1.nRow, rRef.Ref1.nTab, pDoc, rSource, rDest );
+ DoTranspose( rRef.Ref2.nCol, rRef.Ref2.nRow, rRef.Ref2.nTab, pDoc, rSource, rDest );
+ eRet = UR_UPDATED;
+ }
+ return eRet;
+}
+
+//------------------------------------------------------------------
+
+// UpdateGrow - erweitert Referenzen, die genau auf den Bereich zeigen
+// kommt ohne Dokument aus
+
+
+ScRefUpdateRes ScRefUpdate::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY,
+ ScComplexRefData& rRef )
+{
+ ScRefUpdateRes eRet = UR_NOTHING;
+
+ // in Y-Richtung darf die Ref auch eine Zeile weiter unten anfangen,
+ // falls ein Bereich Spaltenkoepfe enthaelt
+
+ BOOL bUpdateX = ( nGrowX &&
+ rRef.Ref1.nCol == rArea.aStart.Col() && rRef.Ref2.nCol == rArea.aEnd.Col() &&
+ rRef.Ref1.nRow >= rArea.aStart.Row() && rRef.Ref2.nRow <= rArea.aEnd.Row() &&
+ rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() );
+ BOOL bUpdateY = ( nGrowY &&
+ rRef.Ref1.nCol >= rArea.aStart.Col() && rRef.Ref2.nCol <= rArea.aEnd.Col() &&
+ ( rRef.Ref1.nRow == rArea.aStart.Row() || rRef.Ref1.nRow == rArea.aStart.Row()+1 ) &&
+ rRef.Ref2.nRow == rArea.aEnd.Row() &&
+ rRef.Ref1.nTab >= rArea.aStart.Tab() && rRef.Ref2.nTab <= rArea.aEnd.Tab() );
+
+ if ( bUpdateX )
+ {
+ rRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( rRef.Ref2.nCol + nGrowX );
+ eRet = UR_UPDATED;
+ }
+ if ( bUpdateY )
+ {
+ rRef.Ref2.nRow = sal::static_int_cast<SCsROW>( rRef.Ref2.nRow + nGrowY );
+ eRet = UR_UPDATED;
+ }
+
+ return eRet;
+}
+
+
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
new file mode 100644
index 000000000000..2ecc20f53405
--- /dev/null
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -0,0 +1,859 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <tools/debug.hxx>
+
+#include "scmatrix.hxx"
+#include "global.hxx"
+#include "address.hxx"
+#include "formula/errorcodes.hxx"
+#include "interpre.hxx"
+#include <svl/zforlist.hxx>
+#include <tools/stream.hxx>
+#include <rtl/math.hxx>
+
+#include <math.h>
+
+//------------------------------------------------------------------------
+
+void ScMatrix::CreateMatrix(SCSIZE nC, SCSIZE nR) // nur fuer ctor
+{
+ pErrorInterpreter = NULL;
+ nColCount = nC;
+ nRowCount = nR;
+ SCSIZE nCount = nColCount * nRowCount;
+ if ( !nCount || nCount > GetElementsMax() )
+ {
+ DBG_ERRORFILE("ScMatrix::CreateMatrix: dimension error");
+ nColCount = nRowCount = 1;
+ pMat = new ScMatrixValue[1];
+ pMat[0].fVal = CreateDoubleError( errStackOverflow);
+ }
+ else
+ pMat = new ScMatrixValue[nCount];
+ mnValType = NULL;
+ mnNonValue = 0;
+}
+
+void ScMatrix::Clear()
+{
+ DeleteIsString();
+ delete [] pMat;
+}
+
+ScMatrix::~ScMatrix()
+{
+ Clear();
+}
+
+ScMatrix* ScMatrix::Clone() const
+{
+ ScMatrix* pScMat = new ScMatrix( nColCount, nRowCount);
+ MatCopy(*pScMat);
+ pScMat->SetErrorInterpreter( pErrorInterpreter); // TODO: really?
+ return pScMat;
+}
+
+ScMatrix* ScMatrix::CloneIfConst()
+{
+ return (mbCloneIfConst || IsEternalRef()) ? Clone() : this;
+}
+
+void ScMatrix::Resize( SCSIZE nC, SCSIZE nR)
+{
+ Clear();
+ CreateMatrix(nC, nR);
+}
+
+ScMatrix* ScMatrix::CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const
+{
+ ScMatrix* pScMat = new ScMatrix( nNewCols, nNewRows);
+ MatCopy(*pScMat);
+ pScMat->SetErrorInterpreter( pErrorInterpreter);
+ return pScMat;
+}
+
+void ScMatrix::SetErrorAtInterpreter( USHORT nError ) const
+{
+ if ( pErrorInterpreter )
+ pErrorInterpreter->SetError( nError);
+}
+
+//
+// File format: USHORT columns, USHORT rows, (columns*rows) entries:
+// BYTE type ( CELLTYPE_NONE, CELLTYPE_VALUE, CELLTYPE_STRING ); nothing, double or String
+//
+
+ScMatrix::ScMatrix(SvStream& /* rStream */)
+ : pErrorInterpreter( NULL)
+ , nRefCnt(0)
+{
+#if SC_ROWLIMIT_STREAM_ACCESS
+#error address types changed!
+ USHORT nC;
+ USHORT nR;
+
+ rStream >> nC;
+ rStream >> nR;
+
+ CreateMatrix(nC, nR);
+ DBG_ASSERT( pMat, "pMat == NULL" );
+
+ String aMatStr;
+ double fVal;
+ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
+ SCSIZE nCount = nColCount * nRowCount;
+ SCSIZE nReadCount = (SCSIZE) nC * nR;
+ for (SCSIZE i=0; i<nReadCount; i++)
+ {
+ BYTE nType;
+ rStream >> nType;
+ if ( nType == CELLTYPE_VALUE )
+ {
+ if ( i < nCount )
+ rStream >> pMat[i].fVal;
+ else
+ rStream >> fVal;
+ }
+ else
+ {
+ // For unknown types read and forget string (upwards compatibility)
+
+ if ( nType != CELLTYPE_NONE )
+ rStream.ReadByteString( aMatStr, eCharSet );
+
+ if ( i < nCount )
+ {
+ if (!mnValType)
+ ResetIsString(); // init string flags
+ mnValType[i] = ( nType == CELLTYPE_NONE ? SC_MATVAL_EMPTY : SC_MATVAL_STRING );
+ mnNonValue++;
+
+ if ( nType == CELLTYPE_STRING )
+ pMat[i].pS = new String(aMatStr);
+ else
+ pMat[i].pS = NULL;
+ }
+ }
+ }
+#else
+ CreateMatrix(0,0);
+#endif // SC_ROWLIMIT_STREAM_ACCESS
+}
+
+void ScMatrix::Store(SvStream& /* rStream */) const
+{
+#if SC_ROWLIMIT_STREAM_ACCESS
+#error address types changed!
+ SCSIZE nCount = nColCount * nRowCount;
+ // Don't store matrix with more than USHORT max elements, old versions
+ // might get confused in loops for(USHORT i=0; i<nC*nR; i++)
+ if ( !pMat || nCount > ((USHORT)(~0)) )
+ {
+ DBG_ASSERT( pMat, "ScMatrix::Store: pMat == NULL" );
+ // We can't store a 0 dimension because old versions rely on some
+ // matrix being present, e.g. DDE link results, and old versions didn't
+ // create a matrix if dimension was 0. Store an error result.
+ rStream << (USHORT) 1;
+ rStream << (USHORT) 1;
+ rStream << (BYTE) CELLTYPE_VALUE;
+ double fVal;
+ ::rtl::math::setNan( &fVal );
+ rStream << fVal;
+ return;
+ }
+
+ rStream << (USHORT) nColCount;
+#if SC_ROWLIMIT_MORE_THAN_32K
+ #error row32k
+#endif
+ rStream << (USHORT) nRowCount;
+
+ String aMatStr;
+ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ BYTE nType = CELLTYPE_VALUE;
+ if ( mnValType && IsNonValueType( mnValType[i]))
+ {
+ if ( pMat[i].pS )
+ aMatStr = *pMat[i].pS;
+ else
+ aMatStr.Erase();
+
+ if ( mnValType[i] == SC_MATVAL_STRING )
+ nType = CELLTYPE_STRING;
+ else
+ nType = CELLTYPE_NONE;
+ }
+ rStream << nType;
+ if ( nType == CELLTYPE_VALUE )
+ rStream << pMat[i].fVal;
+ else if ( nType == CELLTYPE_STRING )
+ rStream.WriteByteString( aMatStr, eCharSet );
+ }
+#endif // SC_ROWLIMIT_STREAM_ACCESS
+}
+
+void ScMatrix::ResetIsString()
+{
+ SCSIZE nCount = nColCount * nRowCount;
+ if (mnValType)
+ {
+ for (SCSIZE i = 0; i < nCount; i++)
+ {
+ if ( IsNonValueType( mnValType[i]))
+ delete pMat[i].pS;
+ }
+ }
+ else
+ mnValType = new BYTE[nCount];
+ memset( mnValType, 0, nCount * sizeof( BYTE ) );
+ mnNonValue = 0;
+}
+
+void ScMatrix::DeleteIsString()
+{
+ if ( mnValType )
+ {
+ SCSIZE nCount = nColCount * nRowCount;
+ for ( SCSIZE i = 0; i < nCount; i++ )
+ {
+ if (IsNonValueType( mnValType[i]))
+ delete pMat[i].pS;
+ }
+ delete [] mnValType;
+ mnValType = NULL;
+ mnNonValue = 0;
+ }
+}
+
+void ScMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ PutDouble( fVal, CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::PutDouble: dimension error");
+ }
+}
+
+void ScMatrix::PutString(const String& rStr, SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ PutString( rStr, CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::PutString: dimension error");
+ }
+}
+
+void ScMatrix::PutString(const String& rStr, SCSIZE nIndex)
+{
+ if (mnValType == NULL)
+ ResetIsString();
+ if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS )
+ *(pMat[nIndex].pS) = rStr;
+ else
+ {
+ pMat[nIndex].pS = new String(rStr);
+ mnNonValue++;
+ }
+ mnValType[nIndex] = SC_MATVAL_STRING;
+}
+
+void ScMatrix::PutStringEntry( const String* pStr, BYTE bFlag, SCSIZE nIndex )
+{
+ DBG_ASSERT( bFlag, "ScMatrix::PutStringEntry: bFlag == 0" );
+ if (mnValType == NULL)
+ ResetIsString();
+ // Make sure all bytes of the union are initialized to be able to access
+ // the value with if (IsValueOrEmpty()) GetDouble(). Backup pS first.
+ String* pS = pMat[nIndex].pS;
+ pMat[nIndex].fVal = 0.0;
+ // An EMPTY or EMPTYPATH entry must not have a string pointer therefor.
+ DBG_ASSERT( (((bFlag & SC_MATVAL_EMPTY) == SC_MATVAL_EMPTY) && !pStr) || TRUE,
+ "ScMatrix::PutStringEntry: pStr passed through EMPTY entry");
+ if ( IsNonValueType( mnValType[nIndex]) && pS )
+ {
+ if ((bFlag & SC_MATVAL_EMPTY) == SC_MATVAL_EMPTY)
+ delete pS, pS = NULL;
+ if ( pStr )
+ *pS = *pStr;
+ else if (pS)
+ pS->Erase();
+ pMat[nIndex].pS = pS;
+ }
+ else
+ {
+ pMat[nIndex].pS = (pStr ? new String(*pStr) : NULL);
+ mnNonValue++;
+ }
+ mnValType[nIndex] = bFlag;
+}
+
+void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ PutEmpty( CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::PutEmpty: dimension error");
+ }
+}
+
+void ScMatrix::PutEmpty(SCSIZE nIndex)
+{
+ if (mnValType == NULL)
+ ResetIsString();
+ if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS )
+ {
+ delete pMat[nIndex].pS;
+ }
+ else
+ {
+ mnNonValue++;
+ }
+ mnValType[nIndex] = SC_MATVAL_EMPTY;
+ pMat[nIndex].pS = NULL;
+ pMat[nIndex].fVal = 0.0;
+}
+
+void ScMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ PutEmptyPath( CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::PutEmptyPath: dimension error");
+ }
+}
+
+void ScMatrix::PutEmptyPath(SCSIZE nIndex)
+{
+ if (mnValType == NULL)
+ ResetIsString();
+ if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS )
+ {
+ delete pMat[nIndex].pS;
+ }
+ else
+ {
+ mnNonValue++;
+ }
+ mnValType[nIndex] = SC_MATVAL_EMPTYPATH;
+ pMat[nIndex].pS = NULL;
+ pMat[nIndex].fVal = 0.0;
+}
+
+void ScMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ PutBoolean( bVal, CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::PutBoolean: dimension error");
+ }
+}
+
+void ScMatrix::PutBoolean( bool bVal, SCSIZE nIndex)
+{
+ if (mnValType == NULL)
+ ResetIsString();
+ if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS )
+ {
+ delete pMat[nIndex].pS;
+ mnNonValue--;
+ }
+
+ mnValType[nIndex] = SC_MATVAL_BOOLEAN;
+ pMat[nIndex].pS = NULL;
+ pMat[nIndex].fVal = bVal ? 1. : 0.;
+}
+
+USHORT ScMatrix::GetError( SCSIZE nC, SCSIZE nR) const
+{
+ if (ValidColRowOrReplicated( nC, nR ))
+ return GetError( CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::GetError: dimension error");
+ return errNoValue;
+ }
+}
+
+double ScMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const
+{
+ if (ValidColRowOrReplicated( nC, nR ))
+ return GetDouble( CalcOffset( nC, nR) );
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::GetDouble: dimension error");
+ return CreateDoubleError( errNoValue);
+ }
+}
+
+const String& ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const
+{
+ if (ValidColRowOrReplicated( nC, nR ))
+ {
+ SCSIZE nIndex = CalcOffset( nC, nR);
+ if ( IsString( nIndex ) )
+ return GetString( nIndex );
+ else
+ {
+ SetErrorAtInterpreter( GetError( nIndex));
+ DBG_ERRORFILE("ScMatrix::GetString: access error, no string");
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::GetString: dimension error");
+ }
+ return ScGlobal::GetEmptyString();
+}
+
+
+String ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nIndex) const
+{
+ if (IsString( nIndex))
+ {
+ if (IsEmptyPath( nIndex))
+ { // result of empty FALSE jump path
+ ULONG nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_LOGICAL,
+ ScGlobal::eLnge);
+ String aStr;
+ Color* pColor = NULL;
+ rFormatter.GetOutputString( 0.0, nKey, aStr, &pColor);
+ return aStr;
+ }
+ return GetString( nIndex );
+ }
+
+ USHORT nError = GetError( nIndex);
+ if (nError)
+ {
+ SetErrorAtInterpreter( nError);
+ return ScGlobal::GetErrorString( nError);
+ }
+
+ double fVal= GetDouble( nIndex);
+ ULONG nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge);
+ String aStr;
+ rFormatter.GetInputLineString( fVal, nKey, aStr);
+ return aStr;
+}
+
+
+String ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const
+{
+ if (ValidColRowOrReplicated( nC, nR ))
+ {
+ SCSIZE nIndex = CalcOffset( nC, nR);
+ return GetString( rFormatter, nIndex);
+ }
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::GetString: dimension error");
+ }
+ return String();
+}
+
+
+const ScMatrixValue* ScMatrix::Get(SCSIZE nC, SCSIZE nR, ScMatValType& nType) const
+{
+ if (ValidColRowOrReplicated( nC, nR ))
+ {
+ SCSIZE nIndex = CalcOffset( nC, nR);
+ if (mnValType)
+ nType = mnValType[nIndex];
+ else
+ nType = SC_MATVAL_VALUE;
+ return &pMat[nIndex];
+ }
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::Get: dimension error");
+ }
+ nType = SC_MATVAL_EMPTY;
+ return NULL;
+}
+
+void ScMatrix::MatCopy(ScMatrix& mRes) const
+{
+ if (nColCount > mRes.nColCount || nRowCount > mRes.nRowCount)
+ {
+ DBG_ERRORFILE("ScMatrix::MatCopy: dimension error");
+ }
+ else if ( nColCount == mRes.nColCount && nRowCount == mRes.nRowCount )
+ {
+ if (mnValType)
+ {
+ ScMatValType nType;
+ mRes.ResetIsString();
+ for (SCSIZE i = 0; i < nColCount; i++)
+ {
+ SCSIZE nStart = i * nRowCount;
+ for (SCSIZE j = 0; j < nRowCount; j++)
+ {
+ if (IsNonValueType( (nType = mnValType[nStart+j])))
+ mRes.PutStringEntry( pMat[nStart+j].pS, nType, nStart+j );
+ else
+ {
+ mRes.pMat[nStart+j].fVal = pMat[nStart+j].fVal;
+ mRes.mnValType[nStart+j] = nType;
+ }
+ }
+ }
+ }
+ else
+ {
+ mRes.DeleteIsString();
+ SCSIZE nCount = nColCount * nRowCount;
+ for (SCSIZE i = 0; i < nCount; i++)
+ mRes.pMat[i].fVal = pMat[i].fVal;
+ }
+ }
+ else
+ {
+ // Copy this matrix to upper left rectangle of result matrix.
+ if (mnValType)
+ {
+ ScMatValType nType;
+ mRes.ResetIsString();
+ for (SCSIZE i = 0; i < nColCount; i++)
+ {
+ SCSIZE nStart = i * nRowCount;
+ SCSIZE nResStart = i * mRes.nRowCount;
+ for (SCSIZE j = 0; j < nRowCount; j++)
+ {
+ if (IsNonValueType( (nType = mnValType[nStart+j])))
+ mRes.PutStringEntry( pMat[nStart+j].pS, nType, nResStart+j );
+ else
+ {
+ mRes.pMat[nResStart+j].fVal = pMat[nStart+j].fVal;
+ mRes.mnValType[nResStart+j] = nType;
+ }
+ }
+ }
+ }
+ else
+ {
+ mRes.DeleteIsString();
+ for (SCSIZE i = 0; i < nColCount; i++)
+ {
+ SCSIZE nStart = i * nRowCount;
+ SCSIZE nResStart = i * mRes.nRowCount;
+ for (SCSIZE j = 0; j < nRowCount; j++)
+ mRes.pMat[nResStart+j].fVal = pMat[nStart+j].fVal;
+ }
+ }
+ }
+}
+
+void ScMatrix::MatTrans(ScMatrix& mRes) const
+{
+ if (nColCount != mRes.nRowCount || nRowCount != mRes.nColCount)
+ {
+ DBG_ERRORFILE("ScMatrix::MatTrans: dimension error");
+ }
+ else
+ {
+ if (mnValType)
+ {
+ ScMatValType nType;
+ mRes.ResetIsString();
+ for ( SCSIZE i = 0; i < nColCount; i++ )
+ {
+ SCSIZE nStart = i * nRowCount;
+ for ( SCSIZE j = 0; j < nRowCount; j++ )
+ {
+ if (IsNonValueType( (nType = mnValType[nStart+j])))
+ mRes.PutStringEntry( pMat[nStart+j].pS, nType, j*mRes.nRowCount+i );
+ else
+ {
+ mRes.pMat[j*mRes.nRowCount+i].fVal = pMat[nStart+j].fVal;
+ mRes.mnValType[j*mRes.nRowCount+i] = nType;
+ }
+ }
+ }
+ }
+ else
+ {
+ mRes.DeleteIsString();
+ for ( SCSIZE i = 0; i < nColCount; i++ )
+ {
+ SCSIZE nStart = i * nRowCount;
+ for ( SCSIZE j = 0; j < nRowCount; j++ )
+ {
+ mRes.pMat[j*mRes.nRowCount+i].fVal = pMat[nStart+j].fVal;
+ }
+ }
+ }
+ }
+}
+
+//UNUSED2009-05 void ScMatrix::MatCopyUpperLeft(ScMatrix& mRes) const
+//UNUSED2009-05 {
+//UNUSED2009-05 if (nColCount < mRes.nColCount || nRowCount < mRes.nRowCount)
+//UNUSED2009-05 {
+//UNUSED2009-05 DBG_ERRORFILE("ScMatrix::MatCopyUpperLeft: dimension error");
+//UNUSED2009-05 }
+//UNUSED2009-05 else
+//UNUSED2009-05 {
+//UNUSED2009-05 if (mnValType)
+//UNUSED2009-05 {
+//UNUSED2009-05 ScMatValType nType;
+//UNUSED2009-05 mRes.ResetIsString();
+//UNUSED2009-05 for ( SCSIZE i = 0; i < mRes.nColCount; i++ )
+//UNUSED2009-05 {
+//UNUSED2009-05 SCSIZE nStart = i * nRowCount;
+//UNUSED2009-05 for ( SCSIZE j = 0; j < mRes.nRowCount; j++ )
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( IsNonValueType( (nType = mnValType[nStart+j]) ))
+//UNUSED2009-05 mRes.PutStringEntry( pMat[nStart+j].pS, nType,
+//UNUSED2009-05 i*mRes.nRowCount+j );
+//UNUSED2009-05 else
+//UNUSED2009-05 {
+//UNUSED2009-05 mRes.pMat[i*mRes.nRowCount+j].fVal = pMat[nStart+j].fVal;
+//UNUSED2009-05 mRes.mnValType[i*mRes.nRowCount+j] = nType;
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 else
+//UNUSED2009-05 {
+//UNUSED2009-05 mRes.DeleteIsString();
+//UNUSED2009-05 for ( SCSIZE i = 0; i < mRes.nColCount; i++ )
+//UNUSED2009-05 {
+//UNUSED2009-05 SCSIZE nStart = i * nRowCount;
+//UNUSED2009-05 for ( SCSIZE j = 0; j < mRes.nRowCount; j++ )
+//UNUSED2009-05 {
+//UNUSED2009-05 mRes.pMat[i*mRes.nRowCount+j].fVal = pMat[nStart+j].fVal;
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+
+void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 )
+{
+ if (ValidColRow( nC1, nR1) && ValidColRow( nC2, nR2))
+ {
+ if ( nC1 == 0 && nR1 == 0 && nC2 == nColCount-1 && nR2 == nRowCount-1 )
+ {
+ SCSIZE nEnd = nColCount * nRowCount;
+ for ( SCSIZE j=0; j<nEnd; j++ )
+ pMat[j].fVal = fVal;
+ }
+ else
+ {
+ for ( SCSIZE i=nC1; i<=nC2; i++ )
+ {
+ SCSIZE nOff1 = i * nRowCount + nR1;
+ SCSIZE nOff2 = nOff1 + nR2 - nR1;
+ for ( SCSIZE j=nOff1; j<=nOff2; j++ )
+ pMat[j].fVal = fVal;
+ }
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("ScMatrix::FillDouble: dimension error");
+ }
+}
+
+void ScMatrix::CompareEqual()
+{
+ SCSIZE n = nColCount * nRowCount;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( IsValueType( mnValType[j]) ) // else: #WERT!
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal == 0.0);
+ }
+ else
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal == 0.0);
+ }
+}
+
+void ScMatrix::CompareNotEqual()
+{
+ SCSIZE n = nColCount * nRowCount;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( IsValueType( mnValType[j]) ) // else: #WERT!
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal != 0.0);
+ }
+ else
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal != 0.0);
+ }
+}
+
+void ScMatrix::CompareLess()
+{
+ SCSIZE n = nColCount * nRowCount;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( IsValueType( mnValType[j]) ) // else: #WERT!
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal < 0.0);
+ }
+ else
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal < 0.0);
+ }
+}
+
+void ScMatrix::CompareGreater()
+{
+ SCSIZE n = nColCount * nRowCount;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( IsValueType( mnValType[j]) ) // else: #WERT!
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal > 0.0);
+ }
+ else
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal > 0.0);
+ }
+}
+
+void ScMatrix::CompareLessEqual()
+{
+ SCSIZE n = nColCount * nRowCount;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( IsValueType( mnValType[j]) ) // else: #WERT!
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal <= 0.0);
+ }
+ else
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal <= 0.0);
+ }
+}
+
+void ScMatrix::CompareGreaterEqual()
+{
+ SCSIZE n = nColCount * nRowCount;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( IsValueType( mnValType[j]) ) // else: #WERT!
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal >= 0.0);
+ }
+ else
+ {
+ for ( SCSIZE j=0; j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError
+ pMat[j].fVal = (pMat[j].fVal >= 0.0);
+ }
+}
+
+double ScMatrix::And()
+{
+ SCSIZE n = nColCount * nRowCount;
+ bool bAnd = true;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; bAnd && j<n; j++ )
+ {
+ if ( !IsValueType( mnValType[j]) )
+ { // assuming a CompareMat this is an error
+ return CreateDoubleError( errIllegalArgument );
+ }
+ else if ( ::rtl::math::isFinite( pMat[j].fVal))
+ bAnd = (pMat[j].fVal != 0.0);
+ else
+ return pMat[j].fVal; // DoubleError
+ }
+ }
+ else
+ {
+ for ( SCSIZE j=0; bAnd && j<n; j++ )
+ {
+ if ( ::rtl::math::isFinite( pMat[j].fVal))
+ bAnd = (pMat[j].fVal != 0.0);
+ else
+ return pMat[j].fVal; // DoubleError
+ }
+ }
+ return bAnd;
+}
+
+double ScMatrix::Or()
+{
+ SCSIZE n = nColCount * nRowCount;
+ bool bOr = false;
+ if ( mnValType )
+ {
+ for ( SCSIZE j=0; !bOr && j<n; j++ )
+ if ( !IsValueType( mnValType[j]) )
+ { // assuming a CompareMat this is an error
+ return CreateDoubleError( errIllegalArgument );
+ }
+ else if ( ::rtl::math::isFinite( pMat[j].fVal))
+ bOr = (pMat[j].fVal != 0.0);
+ else
+ return pMat[j].fVal; // DoubleError
+ }
+ else
+ {
+ for ( SCSIZE j=0; !bOr && j<n; j++ )
+ if ( ::rtl::math::isFinite( pMat[j].fVal))
+ bOr = (pMat[j].fVal != 0.0);
+ else
+ return pMat[j].fVal; // DoubleError
+ }
+ return bOr;
+}
+
diff --git a/sc/source/core/tool/stringutil.cxx b/sc/source/core/tool/stringutil.cxx
new file mode 100644
index 000000000000..28a4bc6755c2
--- /dev/null
+++ b/sc/source/core/tool/stringutil.cxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * 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: table.hxx,v $
+ * $Revision: 1.35 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+#include "stringutil.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/math.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+bool ScStringUtil::parseSimpleNumber(
+ const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal)
+{
+ if (gsep == 0x00A0)
+ // unicode space to ascii space
+ gsep = 0x0020;
+
+ OUStringBuffer aBuf;
+ sal_Int32 n = rStr.getLength();
+ const sal_Unicode* p = rStr.getStr();
+ sal_Int32 nPosDSep = -1, nPosGSep = -1;
+ sal_uInt32 nDigitCount = 0;
+
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (c == 0x00A0)
+ // unicode space to ascii space
+ c = 0x0020;
+
+ if (sal_Unicode('0') <= c && c <= sal_Unicode('9'))
+ {
+ // this is a digit.
+ aBuf.append(c);
+ ++nDigitCount;
+ }
+ else if (c == dsep)
+ {
+ // this is a decimal separator.
+
+ if (nPosDSep >= 0)
+ // a second decimal separator -> not a valid number.
+ return false;
+
+ if (nPosGSep >= 0 && i - nPosGSep != 4)
+ // the number has a group separator and the decimal sep is not
+ // positioned correctly.
+ return false;
+
+ nPosDSep = i;
+ nPosGSep = -1;
+ aBuf.append(c);
+ nDigitCount = 0;
+ }
+ else if (c == gsep)
+ {
+ // this is a group (thousand) separator.
+
+ if (i == 0)
+ // not allowed as the first character.
+ return false;
+
+ if (nPosDSep >= 0)
+ // not allowed after the decimal separator.
+ return false;
+
+ if (nPosGSep >= 0 && nDigitCount != 3)
+ // must be exactly 3 digits since the last group separator.
+ return false;
+
+ nPosGSep = i;
+ nDigitCount = 0;
+ }
+ else if (c == sal_Unicode('-') || c == sal_Unicode('+'))
+ {
+ // A sign must be the first character if it's given.
+ if (i == 0)
+ aBuf.append(c);
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+
+ // finished parsing the number.
+
+ if (nPosGSep >= 0 && nDigitCount != 3)
+ // must be exactly 3 digits since the last group separator.
+ return false;
+
+ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
+ sal_Int32 nParseEnd = 0;
+ rVal = ::rtl::math::stringToDouble(aBuf.makeStringAndClear(), dsep, gsep, &eStatus, &nParseEnd);
+ if (eStatus != rtl_math_ConversionStatus_Ok)
+ return false;
+
+ return true;
+}
diff --git a/sc/source/core/tool/subtotal.cxx b/sc/source/core/tool/subtotal.cxx
new file mode 100644
index 000000000000..077b5a9d9751
--- /dev/null
+++ b/sc/source/core/tool/subtotal.cxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// INCLUDE ---------------------------------------------------------------
+
+
+
+#include "subtotal.hxx"
+#include "interpre.hxx"
+
+// -----------------------------------------------------------------------
+
+BOOL SubTotal::SafePlus(double& fVal1, double fVal2)
+{
+ BOOL bOk = TRUE;
+ SAL_MATH_FPEXCEPTIONS_OFF();
+ fVal1 += fVal2;
+ if (!::rtl::math::isFinite(fVal1))
+ {
+ bOk = FALSE;
+ if (fVal2 > 0.0)
+ fVal1 = DBL_MAX;
+ else
+ fVal1 = -DBL_MAX;
+ }
+ return bOk;
+}
+
+
+BOOL SubTotal::SafeMult(double& fVal1, double fVal2)
+{
+ BOOL bOk = TRUE;
+ SAL_MATH_FPEXCEPTIONS_OFF();
+ fVal1 *= fVal2;
+ if (!::rtl::math::isFinite(fVal1))
+ {
+ bOk = FALSE;
+ fVal1 = DBL_MAX;
+ }
+ return bOk;
+}
+
+
+BOOL SubTotal::SafeDiv(double& fVal1, double fVal2)
+{
+ BOOL bOk = TRUE;
+ SAL_MATH_FPEXCEPTIONS_OFF();
+ fVal1 /= fVal2;
+ if (!::rtl::math::isFinite(fVal1))
+ {
+ bOk = FALSE;
+ fVal1 = DBL_MAX;
+ }
+ return bOk;
+}
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
new file mode 100644
index 000000000000..81862c49fd21
--- /dev/null
+++ b/sc/source/core/tool/token.cxx
@@ -0,0 +1,1836 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+
+#if STLPORT_VERSION<321
+#include <stddef.h>
+#else
+#include <cstddef>
+#endif
+#include <cstdio>
+
+#include <string.h>
+#include <tools/mempool.hxx>
+#include <tools/debug.hxx>
+
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "compiler.hxx"
+#include <formula/compiler.hrc>
+#include "rechead.hxx"
+#include "parclass.hxx"
+#include "jumpmatrix.hxx"
+#include "rangeseq.hxx"
+#include "externalrefmgr.hxx"
+#include "document.hxx"
+
+using ::std::vector;
+
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+
+using namespace formula;
+using namespace com::sun::star;
+
+namespace
+{
+ void lcl_SingleRefToCalc( ScSingleRefData& rRef, const sheet::SingleReference& rAPI )
+ {
+ rRef.InitFlags();
+
+ rRef.nCol = static_cast<SCsCOL>(rAPI.Column);
+ rRef.nRow = static_cast<SCsROW>(rAPI.Row);
+ rRef.nTab = static_cast<SCsTAB>(rAPI.Sheet);
+ rRef.nRelCol = static_cast<SCsCOL>(rAPI.RelativeColumn);
+ rRef.nRelRow = static_cast<SCsROW>(rAPI.RelativeRow);
+ rRef.nRelTab = static_cast<SCsTAB>(rAPI.RelativeSheet);
+
+ rRef.SetColRel( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
+ rRef.SetRowRel( ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE ) != 0 );
+ rRef.SetTabRel( ( rAPI.Flags & sheet::ReferenceFlags::SHEET_RELATIVE ) != 0 );
+ rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED ) != 0 );
+ rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED ) != 0 );
+ rRef.SetTabDeleted( ( rAPI.Flags & sheet::ReferenceFlags::SHEET_DELETED ) != 0 );
+ rRef.SetFlag3D( ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D ) != 0 );
+ rRef.SetRelName( ( rAPI.Flags & sheet::ReferenceFlags::RELATIVE_NAME ) != 0 );
+ }
+
+ void lcl_ExternalRefToCalc( ScSingleRefData& rRef, const sheet::SingleReference& rAPI )
+ {
+ rRef.InitFlags();
+
+ rRef.nCol = static_cast<SCsCOL>(rAPI.Column);
+ rRef.nRow = static_cast<SCsROW>(rAPI.Row);
+ rRef.nTab = 0;
+ rRef.nRelCol = static_cast<SCsCOL>(rAPI.RelativeColumn);
+ rRef.nRelRow = static_cast<SCsROW>(rAPI.RelativeRow);
+ rRef.nRelTab = 0;
+
+ rRef.SetColRel( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
+ rRef.SetRowRel( ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE ) != 0 );
+ rRef.SetTabRel( false ); // sheet index must be absolute for external refs
+ rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED ) != 0 );
+ rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED ) != 0 );
+ rRef.SetTabDeleted( false ); // sheet must not be deleted for external refs
+ rRef.SetFlag3D( ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D ) != 0 );
+ rRef.SetRelName( false );
+ }
+//
+} // namespace
+//
+// ImpTokenIterator wird je Interpreter angelegt, mehrfache auch durch
+// SubCode via FormulaTokenIterator Push/Pop moeglich
+IMPL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator, 32, 16 )
+
+// Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2)
+
+// Since RawTokens are temporary for the compiler, don't align on 4k and waste memory.
+// ScRawToken size is FixMembers + MAXSTRLEN + ~4 ~= 1036
+IMPL_FIXEDMEMPOOL_NEWDEL( ScRawToken, 8, 4 )
+// Some ScDoubleRawToken, FixMembers + sizeof(double) ~= 16
+const USHORT nMemPoolDoubleRawToken = 0x0400 / sizeof(ScDoubleRawToken);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken, nMemPoolDoubleRawToken, nMemPoolDoubleRawToken )
+
+// Need a whole bunch of ScSingleRefToken
+const USHORT nMemPoolSingleRefToken = (0x4000 - 64) / sizeof(ScSingleRefToken);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken, nMemPoolSingleRefToken, nMemPoolSingleRefToken )
+// Need quite a lot of ScDoubleRefToken
+const USHORT nMemPoolDoubleRefToken = (0x2000 - 64) / sizeof(ScDoubleRefToken);
+IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken, nMemPoolDoubleRefToken, nMemPoolDoubleRefToken )
+
+// --- helpers --------------------------------------------------------------
+
+inline BOOL lcl_IsReference( OpCode eOp, StackVar eType )
+{
+ return
+ (eOp == ocPush && (eType == svSingleRef || eType == svDoubleRef))
+ || (eOp == ocColRowNameAuto && eType == svDoubleRef)
+ || (eOp == ocColRowName && eType == svSingleRef)
+ || (eOp == ocMatRef && eType == svSingleRef)
+ ;
+}
+
+
+// --- class ScRawToken -----------------------------------------------------
+
+xub_StrLen ScRawToken::GetStrLen( const sal_Unicode* pStr )
+{
+ if ( !pStr )
+ return 0;
+ register const sal_Unicode* p = pStr;
+ while ( *p )
+ p++;
+ return sal::static_int_cast<xub_StrLen>( p - pStr );
+}
+
+
+void ScRawToken::SetOpCode( OpCode e )
+{
+ eOp = e;
+ switch (eOp)
+ {
+ case ocIf:
+ eType = svJump;
+ nJump[ 0 ] = 3; // If, Else, Behind
+ break;
+ case ocChose:
+ eType = svJump;
+ nJump[ 0 ] = MAXJUMPCOUNT+1;
+ break;
+ case ocMissing:
+ eType = svMissing;
+ break;
+ case ocSep:
+ case ocOpen:
+ case ocClose:
+ case ocArrayRowSep:
+ case ocArrayColSep:
+ case ocArrayOpen:
+ case ocArrayClose:
+ eType = svSep;
+ break;
+ default:
+ eType = svByte;
+ sbyte.cByte = 0;
+ sbyte.bHasForceArray = ScParameterClassification::HasForceArray( eOp);
+ }
+ nRefCnt = 0;
+}
+
+void ScRawToken::SetString( const sal_Unicode* pStr )
+{
+ eOp = ocPush;
+ eType = svString;
+ if ( pStr )
+ {
+ xub_StrLen nLen = GetStrLen( pStr ) + 1;
+ if( nLen > MAXSTRLEN )
+ nLen = MAXSTRLEN;
+ memcpy( cStr, pStr, GetStrLenBytes( nLen ) );
+ cStr[ nLen-1 ] = 0;
+ }
+ else
+ cStr[0] = 0;
+ nRefCnt = 0;
+}
+
+void ScRawToken::SetSingleReference( const ScSingleRefData& rRef )
+{
+ eOp = ocPush;
+ eType = svSingleRef;
+ aRef.Ref1 =
+ aRef.Ref2 = rRef;
+ nRefCnt = 0;
+}
+
+void ScRawToken::SetDoubleReference( const ScComplexRefData& rRef )
+{
+ eOp = ocPush;
+ eType = svDoubleRef;
+ aRef = rRef;
+ nRefCnt = 0;
+}
+
+void ScRawToken::SetDouble(double rVal)
+{
+ eOp = ocPush;
+ eType = svDouble;
+ nValue = rVal;
+ nRefCnt = 0;
+}
+
+void ScRawToken::SetName( USHORT n )
+{
+ eOp = ocName;
+ eType = svIndex;
+ nIndex = n;
+ nRefCnt = 0;
+}
+
+void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ eOp = ocExternalRef;
+ eType = svExternalSingleRef;
+ nRefCnt = 0;
+
+ extref.nFileId = nFileId;
+ extref.aRef.Ref1 =
+ extref.aRef.Ref2 = rRef;
+
+ xub_StrLen n = rTabName.Len();
+ memcpy(extref.cTabName, rTabName.GetBuffer(), n*sizeof(sal_Unicode));
+ extref.cTabName[n] = 0;
+}
+
+void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
+{
+ eOp = ocExternalRef;
+ eType = svExternalDoubleRef;
+ nRefCnt = 0;
+
+ extref.nFileId = nFileId;
+ extref.aRef = rRef;
+
+ xub_StrLen n = rTabName.Len();
+ memcpy(extref.cTabName, rTabName.GetBuffer(), n*sizeof(sal_Unicode));
+ extref.cTabName[n] = 0;
+}
+
+void ScRawToken::SetExternalName( sal_uInt16 nFileId, const String& rName )
+{
+ eOp = ocExternalRef;
+ eType = svExternalName;
+ nRefCnt = 0;
+
+ extname.nFileId = nFileId;
+
+ xub_StrLen n = rName.Len();
+ memcpy(extname.cName, rName.GetBuffer(), n*sizeof(sal_Unicode));
+ extname.cName[n] = 0;
+}
+
+//UNUSED2008-05 void ScRawToken::SetInt(int rVal)
+//UNUSED2008-05 {
+//UNUSED2008-05 eOp = ocPush;
+//UNUSED2008-05 eType = svDouble;
+//UNUSED2008-05 nValue = (double)rVal;
+//UNUSED2008-05 nRefCnt = 0;
+//UNUSED2008-05
+//UNUSED2008-05 }
+//UNUSED2008-05 void ScRawToken::SetMatrix( ScMatrix* p )
+//UNUSED2008-05 {
+//UNUSED2008-05 eOp = ocPush;
+//UNUSED2008-05 eType = svMatrix;
+//UNUSED2008-05 pMat = p;
+//UNUSED2008-05 nRefCnt = 0;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 ScComplexRefData& ScRawToken::GetReference()
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ASSERT( lcl_IsReference( eOp, GetType() ), "GetReference: no Ref" );
+//UNUSED2008-05 return aRef;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScRawToken::SetReference( ScComplexRefData& rRef )
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ASSERT( lcl_IsReference( eOp, GetType() ), "SetReference: no Ref" );
+//UNUSED2008-05 aRef = rRef;
+//UNUSED2008-05 if( GetType() == svSingleRef )
+//UNUSED2008-05 aRef.Ref2 = aRef.Ref1;
+//UNUSED2008-05 }
+
+void ScRawToken::SetExternal( const sal_Unicode* pStr )
+{
+ eOp = ocExternal;
+ eType = svExternal;
+ xub_StrLen nLen = GetStrLen( pStr ) + 1;
+ if( nLen >= MAXSTRLEN )
+ nLen = MAXSTRLEN-1;
+ // Platz fuer Byte-Parameter lassen!
+ memcpy( cStr+1, pStr, GetStrLenBytes( nLen ) );
+ cStr[ nLen+1 ] = 0;
+ nRefCnt = 0;
+}
+
+USHORT lcl_ScRawTokenOffset()
+{
+ // offset of sbyte in ScRawToken
+ // offsetof(ScRawToken, sbyte) gives a warning with gcc, because ScRawToken is no POD
+
+ ScRawToken aToken;
+ return static_cast<USHORT>( reinterpret_cast<char*>(&aToken.sbyte) - reinterpret_cast<char*>(&aToken) );
+}
+
+ScRawToken* ScRawToken::Clone() const
+{
+ ScRawToken* p;
+ if ( eType == svDouble )
+ {
+ p = (ScRawToken*) new ScDoubleRawToken;
+ p->eOp = eOp;
+ p->eType = eType;
+ p->nValue = nValue;
+ }
+ else
+ {
+ static USHORT nOffset = lcl_ScRawTokenOffset(); // offset of sbyte
+ USHORT n = nOffset;
+
+ if (eOp == ocExternalRef)
+ {
+ switch (eType)
+ {
+ case svExternalSingleRef:
+ case svExternalDoubleRef: n += sizeof(extref); break;
+ case svExternalName: n += sizeof(extname); break;
+ default:
+ {
+ DBG_ERROR1( "unknown ScRawToken::Clone() external type %d", int(eType));
+ }
+ }
+ }
+ else
+ {
+ switch( eType )
+ {
+ case svSep: break;
+ case svByte: n += sizeof(ScRawToken::sbyte); break;
+ case svDouble: n += sizeof(double); break;
+ case svString: n = sal::static_int_cast<USHORT>( n + GetStrLenBytes( cStr ) + GetStrLenBytes( 1 ) ); break;
+ case svSingleRef:
+ case svDoubleRef: n += sizeof(aRef); break;
+ case svMatrix: n += sizeof(ScMatrix*); break;
+ case svIndex: n += sizeof(USHORT); break;
+ case svJump: n += nJump[ 0 ] * 2 + 2; break;
+ case svExternal: n = sal::static_int_cast<USHORT>( n + GetStrLenBytes( cStr+1 ) + GetStrLenBytes( 2 ) ); break;
+ default:
+ {
+ DBG_ERROR1( "unknown ScRawToken::Clone() type %d", int(eType));
+ }
+ }
+ }
+ p = (ScRawToken*) new BYTE[ n ];
+ memcpy( p, this, n * sizeof(BYTE) );
+ }
+ p->nRefCnt = 0;
+ p->bRaw = FALSE;
+ return p;
+}
+
+
+FormulaToken* ScRawToken::CreateToken() const
+{
+#ifdef DBG_UTIL
+#define IF_NOT_OPCODE_ERROR(o,c) if (eOp!=o) DBG_ERROR1( #c "::ctor: OpCode %d lost, converted to " #o "; maybe inherit from FormulaToken instead!", int(eOp))
+#else
+#define IF_NOT_OPCODE_ERROR(o,c)
+#endif
+ switch ( GetType() )
+ {
+ case svByte :
+ return new FormulaByteToken( eOp, sbyte.cByte, sbyte.bHasForceArray );
+ case svDouble :
+ IF_NOT_OPCODE_ERROR( ocPush, FormulaDoubleToken);
+ return new FormulaDoubleToken( nValue );
+ case svString :
+ if (eOp == ocPush)
+ return new FormulaStringToken( String( cStr ) );
+ else
+ return new FormulaStringOpToken( eOp, String( cStr ) );
+ case svSingleRef :
+ if (eOp == ocPush)
+ return new ScSingleRefToken( aRef.Ref1 );
+ else
+ return new ScSingleRefToken( aRef.Ref1, eOp );
+ case svDoubleRef :
+ if (eOp == ocPush)
+ return new ScDoubleRefToken( aRef );
+ else
+ return new ScDoubleRefToken( aRef, eOp );
+ case svMatrix :
+ IF_NOT_OPCODE_ERROR( ocPush, ScMatrixToken);
+ return new ScMatrixToken( pMat );
+ case svIndex :
+ return new FormulaIndexToken( eOp, nIndex );
+ case svExternalSingleRef:
+ {
+ String aTabName(extref.cTabName);
+ return new ScExternalSingleRefToken(extref.nFileId, aTabName, extref.aRef.Ref1);
+ }
+ case svExternalDoubleRef:
+ {
+ String aTabName(extref.cTabName);
+ return new ScExternalDoubleRefToken(extref.nFileId, aTabName, extref.aRef);
+ }
+ case svExternalName:
+ {
+ String aName(extname.cName);
+ return new ScExternalNameToken( extname.nFileId, aName );
+ }
+ case svJump :
+ return new FormulaJumpToken( eOp, (short*) nJump );
+ case svExternal :
+ return new FormulaExternalToken( eOp, sbyte.cByte, String( cStr+1 ) );
+ case svFAP :
+ return new FormulaFAPToken( eOp, sbyte.cByte, NULL );
+ case svMissing :
+ IF_NOT_OPCODE_ERROR( ocMissing, FormulaMissingToken);
+ return new FormulaMissingToken;
+ case svSep :
+ return new FormulaToken( svSep,eOp );
+ case svUnknown :
+ return new FormulaUnknownToken( eOp );
+ default:
+ {
+ DBG_ERROR1( "unknown ScRawToken::CreateToken() type %d", int(GetType()));
+ return new FormulaUnknownToken( ocBad );
+ }
+ }
+#undef IF_NOT_OPCODE_ERROR
+}
+
+
+void ScRawToken::Delete()
+{
+ if ( bRaw )
+ delete this; // FixedMemPool ScRawToken
+ else
+ { // created per Clone
+ switch ( eType )
+ {
+ case svDouble :
+ delete (ScDoubleRawToken*) this; // FixedMemPool ScDoubleRawToken
+ break;
+ default:
+ delete [] (BYTE*) this;
+ }
+ }
+}
+
+
+// --- class ScToken --------------------------------------------------------
+
+ScSingleRefData lcl_ScToken_InitSingleRef()
+{
+ ScSingleRefData aRef;
+ aRef.InitAddress( ScAddress() );
+ return aRef;
+}
+
+ScComplexRefData lcl_ScToken_InitDoubleRef()
+{
+ ScComplexRefData aRef;
+ aRef.Ref1 = lcl_ScToken_InitSingleRef();
+ aRef.Ref2 = aRef.Ref1;
+ return aRef;
+}
+
+ScToken::~ScToken()
+{
+}
+
+// TextEqual: if same formula entered (for optimization in sort)
+BOOL ScToken::TextEqual( const FormulaToken& _rToken ) const
+{
+ if ( eType == svSingleRef || eType == svDoubleRef )
+ {
+ // in relative Refs only compare relative parts
+
+ if ( eType != _rToken.GetType() || GetOpCode() != _rToken.GetOpCode() )
+ return FALSE;
+
+ const ScToken& rToken = static_cast<const ScToken&>(_rToken);
+ ScComplexRefData aTemp1;
+ if ( eType == svSingleRef )
+ {
+ aTemp1.Ref1 = GetSingleRef();
+ aTemp1.Ref2 = aTemp1.Ref1;
+ }
+ else
+ aTemp1 = GetDoubleRef();
+
+ ScComplexRefData aTemp2;
+ if ( rToken.eType == svSingleRef )
+ {
+ aTemp2.Ref1 = rToken.GetSingleRef();
+ aTemp2.Ref2 = aTemp2.Ref1;
+ }
+ else
+ aTemp2 = rToken.GetDoubleRef();
+
+ ScAddress aPos;
+ aTemp1.SmartRelAbs(aPos);
+ aTemp2.SmartRelAbs(aPos);
+
+ // memcmp doesn't work because of the alignment byte after bFlags.
+ // After SmartRelAbs only absolute parts have to be compared.
+ return aTemp1.Ref1.nCol == aTemp2.Ref1.nCol &&
+ aTemp1.Ref1.nRow == aTemp2.Ref1.nRow &&
+ aTemp1.Ref1.nTab == aTemp2.Ref1.nTab &&
+ aTemp1.Ref1.bFlags == aTemp2.Ref1.bFlags &&
+ aTemp1.Ref2.nCol == aTemp2.Ref2.nCol &&
+ aTemp1.Ref2.nRow == aTemp2.Ref2.nRow &&
+ aTemp1.Ref2.nTab == aTemp2.Ref2.nTab &&
+ aTemp1.Ref2.bFlags == aTemp2.Ref2.bFlags;
+ }
+ else
+ return *this == _rToken; // else normal operator==
+}
+
+
+BOOL ScToken::Is3DRef() const
+{
+ switch ( eType )
+ {
+ case svDoubleRef :
+ if ( GetSingleRef2().IsFlag3D() )
+ return TRUE;
+ //! fallthru
+ case svSingleRef :
+ if ( GetSingleRef().IsFlag3D() )
+ return TRUE;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return FALSE;
+}
+
+// static
+FormulaTokenRef ScToken::ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2,
+ const ScAddress & rPos, bool bReuseDoubleRef )
+{
+
+ StackVar sv1, sv2;
+ // Doing a RangeOp with RefList is probably utter nonsense, but Xcl
+ // supports it, so do we.
+ if (((sv1 = rTok1.GetType()) != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList &&
+ sv1 != svExternalSingleRef && sv1 != svExternalDoubleRef ) ||
+ ((sv2 = rTok2.GetType()) != svSingleRef && sv2 != svDoubleRef && sv2 != svRefList))
+ return NULL;
+
+ ScToken *p1 = static_cast<ScToken*>(&rTok1);
+ ScToken *p2 = static_cast<ScToken*>(&rTok2);
+
+ ScTokenRef xRes;
+ bool bExternal = (sv1 == svExternalSingleRef);
+ if ((sv1 == svSingleRef || bExternal) && sv2 == svSingleRef)
+ {
+ // Range references like Sheet1.A1:A2 are generalized and built by
+ // first creating a DoubleRef from the first SingleRef, effectively
+ // generating Sheet1.A1:A1, and then extending that with A2 as if
+ // Sheet1.A1:A1:A2 was encountered, so the mechanisms to adjust the
+ // references apply as well.
+
+ /* Given the current structure of external references an external
+ * reference can only be extended if the second reference does not
+ * point to a different sheet. 'file'#Sheet1.A1:A2 is ok,
+ * 'file'#Sheet1.A1:Sheet2.A2 is not. Since we can't determine from a
+ * svSingleRef whether the sheet would be different from the one given
+ * in the external reference, we have to bail out if there is any sheet
+ * specified. NOTE: Xcl does handle external 3D references as in
+ * '[file]Sheet1:Sheet2'!A1:A2
+ *
+ * FIXME: For OOo syntax be smart and remember an external singleref
+ * encountered and if followed by ocRange and singleref, create an
+ * external singleref for the second singleref. Both could then be
+ * merged here. For Xcl syntax already parse an external range
+ * reference entirely, cumbersome. */
+
+ const ScSingleRefData& rRef2 = p2->GetSingleRef();
+ if (bExternal && rRef2.IsFlag3D())
+ return NULL;
+
+ ScComplexRefData aRef;
+ aRef.Ref1 = aRef.Ref2 = p1->GetSingleRef();
+ aRef.Ref2.SetFlag3D( false);
+ aRef.Extend( rRef2, rPos);
+ if (bExternal)
+ xRes = new ScExternalDoubleRefToken( p1->GetIndex(), p1->GetString(), aRef);
+ else
+ xRes = new ScDoubleRefToken( aRef);
+ }
+ else
+ {
+ bExternal |= (sv1 == svExternalDoubleRef);
+ const ScRefList* pRefList = NULL;
+ if (sv1 == svDoubleRef)
+ {
+ xRes = (bReuseDoubleRef && p1->GetRef() == 1 ? p1 : static_cast<ScToken*>(p1->Clone()));
+ sv1 = svUnknown; // mark as handled
+ }
+ else if (sv2 == svDoubleRef)
+ {
+ xRes = (bReuseDoubleRef && p2->GetRef() == 1 ? p2 : static_cast<ScToken*>(p2->Clone()));
+ sv2 = svUnknown; // mark as handled
+ }
+ else if (sv1 == svRefList)
+ pRefList = p1->GetRefList();
+ else if (sv2 == svRefList)
+ pRefList = p2->GetRefList();
+ if (pRefList)
+ {
+ if (!pRefList->size())
+ return NULL;
+ if (bExternal)
+ return NULL; // external reference list not possible
+ xRes = new ScDoubleRefToken( (*pRefList)[0] );
+ }
+ if (!xRes)
+ return NULL; // shouldn't happen..
+ StackVar sv[2] = { sv1, sv2 };
+ ScToken* pt[2] = { p1, p2 };
+ ScComplexRefData& rRef = xRes->GetDoubleRef();
+ for (size_t i=0; i<2; ++i)
+ {
+ switch (sv[i])
+ {
+ case svSingleRef:
+ rRef.Extend( pt[i]->GetSingleRef(), rPos);
+ break;
+ case svDoubleRef:
+ rRef.Extend( pt[i]->GetDoubleRef(), rPos);
+ break;
+ case svRefList:
+ {
+ const ScRefList* p = pt[i]->GetRefList();
+ if (!p->size())
+ return NULL;
+ ScRefList::const_iterator it( p->begin());
+ ScRefList::const_iterator end( p->end());
+ for ( ; it != end; ++it)
+ {
+ rRef.Extend( *it, rPos);
+ }
+ }
+ break;
+ case svExternalSingleRef:
+ if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
+ return NULL; // no other sheets with external refs
+ else
+ rRef.Extend( pt[i]->GetSingleRef(), rPos);
+ break;
+ case svExternalDoubleRef:
+ if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
+ return NULL; // no other sheets with external refs
+ else
+ rRef.Extend( pt[i]->GetDoubleRef(), rPos);
+ break;
+ default:
+ ; // nothing, prevent compiler warning
+ }
+ }
+ }
+ return FormulaTokenRef(xRes.get());
+}
+
+const ScSingleRefData& ScToken::GetSingleRef() const
+{
+ DBG_ERRORFILE( "ScToken::GetSingleRef: virtual dummy called" );
+ static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
+ return aDummySingleRef;
+}
+
+ScSingleRefData& ScToken::GetSingleRef()
+{
+ DBG_ERRORFILE( "ScToken::GetSingleRef: virtual dummy called" );
+ static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
+ return aDummySingleRef;
+}
+
+const ScComplexRefData& ScToken::GetDoubleRef() const
+{
+ DBG_ERRORFILE( "ScToken::GetDoubleRef: virtual dummy called" );
+ static ScComplexRefData aDummyDoubleRef = lcl_ScToken_InitDoubleRef();
+ return aDummyDoubleRef;
+}
+
+ScComplexRefData& ScToken::GetDoubleRef()
+{
+ DBG_ERRORFILE( "ScToken::GetDoubleRef: virtual dummy called" );
+ static ScComplexRefData aDummyDoubleRef = lcl_ScToken_InitDoubleRef();
+ return aDummyDoubleRef;
+}
+
+const ScSingleRefData& ScToken::GetSingleRef2() const
+{
+ DBG_ERRORFILE( "ScToken::GetSingleRef2: virtual dummy called" );
+ static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
+ return aDummySingleRef;
+}
+
+ScSingleRefData& ScToken::GetSingleRef2()
+{
+ DBG_ERRORFILE( "ScToken::GetSingleRef2: virtual dummy called" );
+ static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
+ return aDummySingleRef;
+}
+
+void ScToken::CalcAbsIfRel( const ScAddress& /* rPos */ )
+{
+ DBG_ERRORFILE( "ScToken::CalcAbsIfRel: virtual dummy called" );
+}
+
+void ScToken::CalcRelFromAbs( const ScAddress& /* rPos */ )
+{
+ DBG_ERRORFILE( "ScToken::CalcRelFromAbs: virtual dummy called" );
+}
+
+const ScMatrix* ScToken::GetMatrix() const
+{
+ DBG_ERRORFILE( "ScToken::GetMatrix: virtual dummy called" );
+ return NULL;
+}
+
+ScMatrix* ScToken::GetMatrix()
+{
+ DBG_ERRORFILE( "ScToken::GetMatrix: virtual dummy called" );
+ return NULL;
+}
+
+
+ScJumpMatrix* ScToken::GetJumpMatrix() const
+{
+ DBG_ERRORFILE( "ScToken::GetJumpMatrix: virtual dummy called" );
+ return NULL;
+}
+const ScRefList* ScToken::GetRefList() const
+{
+ DBG_ERRORFILE( "ScToken::GetRefList: virtual dummy called" );
+ return NULL;
+}
+
+ScRefList* ScToken::GetRefList()
+{
+ DBG_ERRORFILE( "ScToken::GetRefList: virtual dummy called" );
+ return NULL;
+}
+// ==========================================================================
+// real implementations of virtual functions
+// --------------------------------------------------------------------------
+
+
+
+
+const ScSingleRefData& ScSingleRefToken::GetSingleRef() const { return aSingleRef; }
+ScSingleRefData& ScSingleRefToken::GetSingleRef() { return aSingleRef; }
+void ScSingleRefToken::CalcAbsIfRel( const ScAddress& rPos )
+ { aSingleRef.CalcAbsIfRel( rPos ); }
+void ScSingleRefToken::CalcRelFromAbs( const ScAddress& rPos )
+ { aSingleRef.CalcRelFromAbs( rPos ); }
+BOOL ScSingleRefToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) && aSingleRef == static_cast<const ScToken&>(r).GetSingleRef();
+}
+
+
+const ScSingleRefData& ScDoubleRefToken::GetSingleRef() const { return aDoubleRef.Ref1; }
+ScSingleRefData& ScDoubleRefToken::GetSingleRef() { return aDoubleRef.Ref1; }
+const ScComplexRefData& ScDoubleRefToken::GetDoubleRef() const { return aDoubleRef; }
+ScComplexRefData& ScDoubleRefToken::GetDoubleRef() { return aDoubleRef; }
+const ScSingleRefData& ScDoubleRefToken::GetSingleRef2() const { return aDoubleRef.Ref2; }
+ScSingleRefData& ScDoubleRefToken::GetSingleRef2() { return aDoubleRef.Ref2; }
+void ScDoubleRefToken::CalcAbsIfRel( const ScAddress& rPos )
+ { aDoubleRef.CalcAbsIfRel( rPos ); }
+void ScDoubleRefToken::CalcRelFromAbs( const ScAddress& rPos )
+ { aDoubleRef.CalcRelFromAbs( rPos ); }
+BOOL ScDoubleRefToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) && aDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef();
+}
+
+
+const ScRefList* ScRefListToken::GetRefList() const { return &aRefList; }
+ ScRefList* ScRefListToken::GetRefList() { return &aRefList; }
+void ScRefListToken::CalcAbsIfRel( const ScAddress& rPos )
+{
+ for (ScRefList::iterator it( aRefList.begin()); it != aRefList.end(); ++it)
+ (*it).CalcAbsIfRel( rPos);
+}
+void ScRefListToken::CalcRelFromAbs( const ScAddress& rPos )
+{
+ for (ScRefList::iterator it( aRefList.begin()); it != aRefList.end(); ++it)
+ (*it).CalcRelFromAbs( rPos);
+}
+BOOL ScRefListToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) && &aRefList == static_cast<const ScToken&>(r).GetRefList();
+}
+
+
+const ScMatrix* ScMatrixToken::GetMatrix() const { return pMatrix; }
+ScMatrix* ScMatrixToken::GetMatrix() { return pMatrix; }
+BOOL ScMatrixToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) && pMatrix == static_cast<const ScToken&>(r).GetMatrix();
+}
+
+// ============================================================================
+
+ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r ) :
+ ScToken( svExternalSingleRef, ocExternalRef),
+ mnFileId(nFileId),
+ maTabName(rTabName),
+ maSingleRef(r)
+{
+}
+
+ScExternalSingleRefToken::ScExternalSingleRefToken( const ScExternalSingleRefToken& r ) :
+ ScToken(r),
+ mnFileId(r.mnFileId),
+ maTabName(r.maTabName),
+ maSingleRef(r.maSingleRef)
+{
+}
+
+ScExternalSingleRefToken::~ScExternalSingleRefToken()
+{
+}
+
+USHORT ScExternalSingleRefToken::GetIndex() const
+{
+ return mnFileId;
+}
+
+const String& ScExternalSingleRefToken::GetString() const
+{
+ return maTabName;
+}
+
+const ScSingleRefData& ScExternalSingleRefToken::GetSingleRef() const
+{
+ return maSingleRef;
+}
+
+ScSingleRefData& ScExternalSingleRefToken::GetSingleRef()
+{
+ return maSingleRef;
+}
+
+void ScExternalSingleRefToken::CalcAbsIfRel( const ScAddress& rPos )
+{
+ maSingleRef.CalcAbsIfRel( rPos );
+}
+
+void ScExternalSingleRefToken::CalcRelFromAbs( const ScAddress& rPos )
+{
+ maSingleRef.CalcRelFromAbs( rPos );
+}
+
+BOOL ScExternalSingleRefToken::operator ==( const FormulaToken& r ) const
+{
+ if (!FormulaToken::operator==(r))
+ return false;
+
+ if (mnFileId != r.GetIndex())
+ return false;
+
+ if (maTabName != r.GetString())
+ return false;
+
+ return maSingleRef == static_cast<const ScToken&>(r).GetSingleRef();
+}
+
+// ============================================================================
+
+ScExternalDoubleRefToken::ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r ) :
+ ScToken( svExternalDoubleRef, ocExternalRef),
+ mnFileId(nFileId),
+ maTabName(rTabName),
+ maDoubleRef(r)
+{
+}
+
+ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r ) :
+ ScToken(r),
+ mnFileId(r.mnFileId),
+ maTabName(r.maTabName),
+ maDoubleRef(r.maDoubleRef)
+{
+}
+
+ScExternalDoubleRefToken::~ScExternalDoubleRefToken()
+{
+}
+
+USHORT ScExternalDoubleRefToken::GetIndex() const
+{
+ return mnFileId;
+}
+
+const String& ScExternalDoubleRefToken::GetString() const
+{
+ return maTabName;
+}
+
+const ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef() const
+{
+ return maDoubleRef.Ref1;
+}
+
+ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef()
+{
+ return maDoubleRef.Ref1;
+}
+
+const ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef2() const
+{
+ return maDoubleRef.Ref2;
+}
+
+ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef2()
+{
+ return maDoubleRef.Ref2;
+}
+
+const ScComplexRefData& ScExternalDoubleRefToken::GetDoubleRef() const
+{
+ return maDoubleRef;
+}
+
+ScComplexRefData& ScExternalDoubleRefToken::GetDoubleRef()
+{
+ return maDoubleRef;
+}
+
+void ScExternalDoubleRefToken::CalcAbsIfRel( const ScAddress& rPos )
+{
+ maDoubleRef.CalcAbsIfRel( rPos );
+}
+
+void ScExternalDoubleRefToken::CalcRelFromAbs( const ScAddress& rPos )
+{
+ maDoubleRef.CalcRelFromAbs( rPos );
+}
+
+BOOL ScExternalDoubleRefToken::operator ==( const FormulaToken& r ) const
+{
+ if (!ScToken::operator==(r))
+ return false;
+
+ if (mnFileId != r.GetIndex())
+ return false;
+
+ if (maTabName != r.GetString())
+ return false;
+
+ return maDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef();
+}
+
+// ============================================================================
+
+ScExternalNameToken::ScExternalNameToken( sal_uInt16 nFileId, const String& rName ) :
+ ScToken( svExternalName, ocExternalRef),
+ mnFileId(nFileId),
+ maName(rName)
+{
+}
+
+ScExternalNameToken::ScExternalNameToken( const ScExternalNameToken& r ) :
+ ScToken(r),
+ mnFileId(r.mnFileId),
+ maName(r.maName)
+{
+}
+
+ScExternalNameToken::~ScExternalNameToken() {}
+
+USHORT ScExternalNameToken::GetIndex() const
+{
+ return mnFileId;
+}
+
+const String& ScExternalNameToken::GetString() const
+{
+ return maName;
+}
+
+BOOL ScExternalNameToken::operator==( const FormulaToken& r ) const
+{
+ if ( !FormulaToken::operator==(r) )
+ return false;
+
+ if (mnFileId != r.GetIndex())
+ return false;
+
+ xub_StrLen nLen = maName.Len();
+ const String& rName = r.GetString();
+ if (nLen != rName.Len())
+ return false;
+
+ const sal_Unicode* p1 = maName.GetBuffer();
+ const sal_Unicode* p2 = rName.GetBuffer();
+ for (xub_StrLen j = 0; j < nLen; ++j)
+ {
+ if (p1[j] != p2[j])
+ return false;
+ }
+ return true;
+}
+
+// ============================================================================
+
+ScJumpMatrix* ScJumpMatrixToken::GetJumpMatrix() const { return pJumpMatrix; }
+BOOL ScJumpMatrixToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) && pJumpMatrix == static_cast<const ScToken&>(r).GetJumpMatrix();
+}
+ScJumpMatrixToken::~ScJumpMatrixToken()
+{
+ delete pJumpMatrix;
+}
+
+double ScEmptyCellToken::GetDouble() const { return 0.0; }
+const String & ScEmptyCellToken::GetString() const
+{
+ static String aDummyString;
+ return aDummyString;
+}
+BOOL ScEmptyCellToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) &&
+ bInherited == static_cast< const ScEmptyCellToken & >(r).IsInherited() &&
+ bDisplayedAsString == static_cast< const ScEmptyCellToken & >(r).IsDisplayedAsString();
+}
+
+
+double ScMatrixCellResultToken::GetDouble() const { return xUpperLeft->GetDouble(); }
+const String & ScMatrixCellResultToken::GetString() const { return xUpperLeft->GetString(); }
+const ScMatrix* ScMatrixCellResultToken::GetMatrix() const { return xMatrix; }
+// Non-const GetMatrix() is private and unused but must be implemented to
+// satisfy vtable linkage.
+ScMatrix* ScMatrixCellResultToken::GetMatrix()
+{
+ return const_cast<ScMatrix*>(xMatrix.operator->());
+}
+BOOL ScMatrixCellResultToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) &&
+ xUpperLeft == static_cast<const ScMatrixCellResultToken &>(r).xUpperLeft &&
+ xMatrix == static_cast<const ScMatrixCellResultToken &>(r).xMatrix;
+}
+
+
+BOOL ScMatrixFormulaCellToken::operator==( const FormulaToken& r ) const
+{
+ const ScMatrixFormulaCellToken* p = dynamic_cast<const ScMatrixFormulaCellToken*>(&r);
+ return p && ScMatrixCellResultToken::operator==( r ) &&
+ nCols == p->nCols && nRows == p->nRows;
+}
+void ScMatrixFormulaCellToken::Assign( const formula::FormulaToken& r )
+{
+ if (this == &r)
+ return;
+ const ScMatrixCellResultToken* p = dynamic_cast<const ScMatrixCellResultToken*>(&r);
+ if (p)
+ ScMatrixCellResultToken::Assign( *p);
+ else
+ {
+ DBG_ASSERT( r.GetType() != svMatrix, "ScMatrixFormulaCellToken::operator=: assigning ScMatrixToken to ScMatrixFormulaCellToken is not proper, use ScMatrixCellResultToken instead");
+ if (r.GetType() == svMatrix)
+ {
+ xUpperLeft = NULL;
+ xMatrix = static_cast<const ScToken&>(r).GetMatrix();
+ }
+ else
+ {
+ xUpperLeft = &r;
+ xMatrix = NULL;
+ }
+ }
+}
+void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f )
+{
+ switch (GetUpperLeftType())
+ {
+ case svDouble:
+ const_cast<FormulaToken*>(xUpperLeft.get())->GetDoubleAsReference() = f;
+ break;
+ case svUnknown:
+ if (!xUpperLeft)
+ {
+ xUpperLeft = new FormulaDoubleToken( f);
+ break;
+ }
+ // fall thru
+ default:
+ {
+ DBG_ERRORFILE("ScMatrixFormulaCellToken::SetUpperLeftDouble: not modifying unhandled token type");
+ }
+ }
+}
+
+
+double ScHybridCellToken::GetDouble() const { return fDouble; }
+const String & ScHybridCellToken::GetString() const { return aString; }
+BOOL ScHybridCellToken::operator==( const FormulaToken& r ) const
+{
+ return FormulaToken::operator==( r ) &&
+ fDouble == r.GetDouble() && aString == r.GetString() &&
+ aFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+
+bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken,formula::ExternalReferenceHelper* _pRef)
+{
+ bool bError = FormulaTokenArray::AddFormulaToken(_aToken,_pRef);
+ if ( bError )
+ {
+ bError = false;
+ const OpCode eOpCode = static_cast<OpCode>(_aToken.OpCode); //! assuming equal values for the moment
+
+ const uno::TypeClass eClass = _aToken.Data.getValueTypeClass();
+ switch ( eClass )
+ {
+ case uno::TypeClass_STRUCT:
+ {
+ uno::Type aType = _aToken.Data.getValueType();
+ if ( aType.equals( cppu::UnoType<sheet::SingleReference>::get() ) )
+ {
+ ScSingleRefData aSingleRef;
+ sheet::SingleReference aApiRef;
+ _aToken.Data >>= aApiRef;
+ lcl_SingleRefToCalc( aSingleRef, aApiRef );
+ if ( eOpCode == ocPush )
+ AddSingleReference( aSingleRef );
+ else if ( eOpCode == ocColRowName )
+ AddColRowName( aSingleRef );
+ else
+ bError = true;
+ }
+ else if ( aType.equals( cppu::UnoType<sheet::ComplexReference>::get() ) )
+ {
+ ScComplexRefData aComplRef;
+ sheet::ComplexReference aApiRef;
+ _aToken.Data >>= aApiRef;
+ lcl_SingleRefToCalc( aComplRef.Ref1, aApiRef.Reference1 );
+ lcl_SingleRefToCalc( aComplRef.Ref2, aApiRef.Reference2 );
+
+ if ( eOpCode == ocPush )
+ AddDoubleReference( aComplRef );
+ else
+ bError = true;
+ }
+ else if ( aType.equals( cppu::UnoType<sheet::ExternalReference>::get() ) )
+ {
+ sheet::ExternalReference aApiExtRef;
+ if( (eOpCode == ocPush) && (_aToken.Data >>= aApiExtRef) && (0 <= aApiExtRef.Index) && (aApiExtRef.Index <= SAL_MAX_UINT16) )
+ {
+ sal_uInt16 nFileId = static_cast< sal_uInt16 >( aApiExtRef.Index );
+ sheet::SingleReference aApiSRef;
+ sheet::ComplexReference aApiCRef;
+ ::rtl::OUString aName;
+ if( aApiExtRef.Reference >>= aApiSRef )
+ {
+ // try to resolve cache index to sheet name
+ size_t nCacheId = static_cast< size_t >( aApiSRef.Sheet );
+ String aTabName = _pRef->getCacheTableName( nFileId, nCacheId );
+ if( aTabName.Len() > 0 )
+ {
+ ScSingleRefData aSingleRef;
+ // convert column/row settings, set sheet index to absolute
+ lcl_ExternalRefToCalc( aSingleRef, aApiSRef );
+ AddExternalSingleReference( nFileId, aTabName, aSingleRef );
+ }
+ else
+ bError = true;
+ }
+ else if( aApiExtRef.Reference >>= aApiCRef )
+ {
+ // try to resolve cache index to sheet name.
+ size_t nCacheId = static_cast< size_t >( aApiCRef.Reference1.Sheet );
+ String aTabName = _pRef->getCacheTableName( nFileId, nCacheId );
+ if( aTabName.Len() > 0 )
+ {
+ ScComplexRefData aComplRef;
+ // convert column/row settings, set sheet index to absolute
+ lcl_ExternalRefToCalc( aComplRef.Ref1, aApiCRef.Reference1 );
+ lcl_ExternalRefToCalc( aComplRef.Ref2, aApiCRef.Reference2 );
+ // NOTE: This assumes that cached sheets are in consecutive order!
+ aComplRef.Ref2.nTab = aComplRef.Ref1.nTab + static_cast<SCsTAB>(aApiCRef.Reference2.Sheet - aApiCRef.Reference1.Sheet);
+ AddExternalDoubleReference( nFileId, aTabName, aComplRef );
+ }
+ else
+ bError = true;
+ }
+ else if( aApiExtRef.Reference >>= aName )
+ {
+ if( aName.getLength() > 0 )
+ AddExternalName( nFileId, aName );
+ else
+ bError = true;
+ }
+ else
+ bError = true;
+ }
+ else
+ bError = true;
+ }
+ else
+ bError = true; // unknown struct
+ }
+ break;
+ case uno::TypeClass_SEQUENCE:
+ {
+ if ( eOpCode != ocPush )
+ bError = true; // not an inline array
+ else if (!_aToken.Data.getValueType().equals( getCppuType(
+ (uno::Sequence< uno::Sequence< uno::Any > > *)0)))
+ bError = true; // unexpected sequence type
+ else
+ {
+ ScMatrixRef xMat = ScSequenceToMatrix::CreateMixedMatrix( _aToken.Data);
+ if (xMat)
+ AddMatrix( xMat);
+ else
+ bError = true;
+ }
+ }
+ break;
+ default:
+ bError = true;
+ }
+ }
+ return bError;
+}
+BOOL ScTokenArray::ImplGetReference( ScRange& rRange, BOOL bValidOnly ) const
+{
+ BOOL bIs = FALSE;
+ if ( pCode && nLen == 1 )
+ {
+ const FormulaToken* pToken = pCode[0];
+ if ( pToken )
+ {
+ if ( pToken->GetType() == svSingleRef )
+ {
+ const ScSingleRefData& rRef = ((const ScSingleRefToken*)pToken)->GetSingleRef();
+ rRange.aStart = rRange.aEnd = ScAddress( rRef.nCol, rRef.nRow, rRef.nTab );
+ bIs = !bValidOnly || !rRef.IsDeleted();
+ }
+ else if ( pToken->GetType() == svDoubleRef )
+ {
+ const ScComplexRefData& rCompl = ((const ScDoubleRefToken*)pToken)->GetDoubleRef();
+ const ScSingleRefData& rRef1 = rCompl.Ref1;
+ const ScSingleRefData& rRef2 = rCompl.Ref2;
+ rRange.aStart = ScAddress( rRef1.nCol, rRef1.nRow, rRef1.nTab );
+ rRange.aEnd = ScAddress( rRef2.nCol, rRef2.nRow, rRef2.nTab );
+ bIs = !bValidOnly || (!rRef1.IsDeleted() && !rRef2.IsDeleted());
+ }
+ }
+ }
+ return bIs;
+}
+
+BOOL ScTokenArray::IsReference( ScRange& rRange ) const
+{
+ return ImplGetReference( rRange, FALSE );
+}
+
+BOOL ScTokenArray::IsValidReference( ScRange& rRange ) const
+{
+ return ImplGetReference( rRange, TRUE );
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+ScTokenArray::ScTokenArray()
+{
+}
+
+ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) : FormulaTokenArray(rArr)
+{
+}
+
+ScTokenArray::~ScTokenArray()
+{
+}
+
+
+
+ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr )
+{
+ Clear();
+ Assign( rArr );
+ return *this;
+}
+
+ScTokenArray* ScTokenArray::Clone() const
+{
+ ScTokenArray* p = new ScTokenArray();
+ p->nLen = nLen;
+ p->nRPN = nRPN;
+ p->nRefs = nRefs;
+ p->nMode = nMode;
+ p->nError = nError;
+ p->bHyperLink = bHyperLink;
+ FormulaToken** pp;
+ if( nLen )
+ {
+ pp = p->pCode = new FormulaToken*[ nLen ];
+ memcpy( pp, pCode, nLen * sizeof( ScToken* ) );
+ for( USHORT i = 0; i < nLen; i++, pp++ )
+ {
+ *pp = (*pp)->Clone();
+ (*pp)->IncRef();
+ }
+ }
+ if( nRPN )
+ {
+ pp = p->pRPN = new FormulaToken*[ nRPN ];
+ memcpy( pp, pRPN, nRPN * sizeof( ScToken* ) );
+ for( USHORT i = 0; i < nRPN; i++, pp++ )
+ {
+ FormulaToken* t = *pp;
+ if( t->GetRef() > 1 )
+ {
+ FormulaToken** p2 = pCode;
+ USHORT nIdx = 0xFFFF;
+ for( USHORT j = 0; j < nLen; j++, p2++ )
+ {
+ if( *p2 == t )
+ {
+ nIdx = j; break;
+ }
+ }
+ if( nIdx == 0xFFFF )
+ *pp = t->Clone();
+ else
+ *pp = p->pCode[ nIdx ];
+ }
+ else
+ *pp = t->Clone();
+ (*pp)->IncRef();
+ }
+ }
+ return p;
+}
+
+FormulaToken* ScTokenArray::AddRawToken( const ScRawToken& r )
+{
+ return Add( r.CreateToken() );
+}
+
+// Utility function to ensure that there is strict alternation of values and
+// seperators.
+static bool
+checkArraySep( bool & bPrevWasSep, bool bNewVal )
+{
+ bool bResult = (bPrevWasSep == bNewVal);
+ bPrevWasSep = bNewVal;
+ return bResult;
+}
+
+FormulaToken* ScTokenArray::MergeArray( )
+{
+ int nCol = -1, nRow = 0;
+ int i, nPrevRowSep = -1, nStart = 0;
+ bool bPrevWasSep = false; // top of stack is ocArrayClose
+ FormulaToken* t;
+ bool bNumeric = false; // numeric value encountered in current element
+
+ // (1) Iterate from the end to the start to find matrix dims
+ // and do basic validation.
+ for ( i = nLen ; i-- > nStart ; )
+ {
+ t = pCode[i];
+ switch ( t->GetOpCode() )
+ {
+ case ocPush :
+ if( checkArraySep( bPrevWasSep, false ) )
+ {
+ return NULL;
+ }
+
+ // no references or nested arrays
+ if ( t->GetType() != svDouble && t->GetType() != svString )
+ {
+ return NULL;
+ }
+ bNumeric = (t->GetType() == svDouble);
+ break;
+
+ case ocMissing :
+ case ocTrue :
+ case ocFalse :
+ if( checkArraySep( bPrevWasSep, false ) )
+ {
+ return NULL;
+ }
+ bNumeric = false;
+ break;
+
+ case ocArrayColSep :
+ case ocSep :
+ if( checkArraySep( bPrevWasSep, true ) )
+ {
+ return NULL;
+ }
+ bNumeric = false;
+ break;
+
+ case ocArrayClose :
+ // not possible with the , but check just in case
+ // something changes in the future
+ if( i != (nLen-1))
+ {
+ return NULL;
+ }
+
+ if( checkArraySep( bPrevWasSep, true ) )
+ {
+ return NULL;
+ }
+
+ nPrevRowSep = i;
+ bNumeric = false;
+ break;
+
+ case ocArrayOpen :
+ nStart = i; // stop iteration
+ // fall through to ArrayRowSep
+
+ case ocArrayRowSep :
+ if( checkArraySep( bPrevWasSep, true ) )
+ {
+ return NULL;
+ }
+
+ if( nPrevRowSep < 0 || // missing ocArrayClose
+ ((nPrevRowSep - i) % 2) == 1) // no complex elements
+ {
+ return NULL;
+ }
+
+ if( nCol < 0 )
+ {
+ nCol = (nPrevRowSep - i) / 2;
+ }
+ else if( (nPrevRowSep - i)/2 != nCol) // irregular array
+ {
+ return NULL;
+ }
+
+ nPrevRowSep = i;
+ nRow++;
+ bNumeric = false;
+ break;
+
+ case ocNegSub :
+ case ocAdd :
+ // negation or unary plus must precede numeric value
+ if( !bNumeric )
+ {
+ return NULL;
+ }
+ --nPrevRowSep; // shorten this row by 1
+ bNumeric = false; // one level only, no --42
+ break;
+
+ case ocSpaces :
+ // ignore spaces
+ --nPrevRowSep; // shorten this row by 1
+ break;
+
+ default :
+ // no functions or operators
+ return NULL;
+ }
+ }
+ if( nCol <= 0 || nRow <= 0 )
+ return NULL;
+
+ // fprintf (stderr, "Array (cols = %d, rows = %d)\n", nCol, nRow );
+
+ int nSign = 1;
+ ScMatrix* pArray = new ScMatrix( nCol, nRow );
+ for ( i = nStart, nCol = 0, nRow = 0 ; i < nLen ; i++ )
+ {
+ t = pCode[i];
+
+ switch ( t->GetOpCode() )
+ {
+ case ocPush :
+ if ( t->GetType() == svDouble )
+ {
+ pArray->PutDouble( t->GetDouble() * nSign, nCol, nRow );
+ nSign = 1;
+ }
+ else if ( t->GetType() == svString )
+ {
+ pArray->PutString( t->GetString(), nCol, nRow );
+ }
+ break;
+
+ case ocMissing :
+ pArray->PutEmpty( nCol, nRow );
+ break;
+
+ case ocTrue :
+ pArray->PutBoolean( true, nCol, nRow );
+ break;
+
+ case ocFalse :
+ pArray->PutBoolean( false, nCol, nRow );
+ break;
+
+ case ocArrayColSep :
+ case ocSep :
+ nCol++;
+ break;
+
+ case ocArrayRowSep :
+ nRow++; nCol = 0;
+ break;
+
+ case ocNegSub :
+ nSign = -nSign;
+ break;
+
+ default :
+ break;
+ }
+ pCode[i] = NULL;
+ t->DecRef();
+ }
+ nLen = USHORT( nStart );
+ return AddMatrix( pArray );
+}
+
+
+FormulaToken* ScTokenArray::MergeRangeReference( const ScAddress & rPos )
+{
+ if (!pCode || !nLen)
+ return NULL;
+ USHORT nIdx = nLen;
+ FormulaToken *p1, *p2, *p3; // ref, ocRange, ref
+ // The actual types are checked in ExtendRangeReference().
+ if (((p3 = PeekPrev(nIdx)) != 0) &&
+ (((p2 = PeekPrev(nIdx)) != 0) && p2->GetOpCode() == ocRange) &&
+ ((p1 = PeekPrev(nIdx)) != 0))
+ {
+ FormulaTokenRef p = ScToken::ExtendRangeReference( *p1, *p3, rPos, true);
+ if (p)
+ {
+ p->IncRef();
+ p1->DecRef();
+ p2->DecRef();
+ p3->DecRef();
+ nLen -= 2;
+ pCode[ nLen-1 ] = p;
+ nRefs--;
+ }
+ }
+ return pCode[ nLen-1 ];
+}
+
+FormulaToken* ScTokenArray::AddOpCode( OpCode e )
+{
+ ScRawToken t;
+ t.SetOpCode( e );
+ return AddRawToken( t );
+}
+
+FormulaToken* ScTokenArray::AddSingleReference( const ScSingleRefData& rRef )
+{
+ return Add( new ScSingleRefToken( rRef ) );
+}
+
+FormulaToken* ScTokenArray::AddMatrixSingleReference( const ScSingleRefData& rRef )
+{
+ return Add( new ScSingleRefToken( rRef, ocMatRef ) );
+}
+
+FormulaToken* ScTokenArray::AddDoubleReference( const ScComplexRefData& rRef )
+{
+ return Add( new ScDoubleRefToken( rRef ) );
+}
+
+FormulaToken* ScTokenArray::AddMatrix( ScMatrix* p )
+{
+ return Add( new ScMatrixToken( p ) );
+}
+
+FormulaToken* ScTokenArray::AddExternalName( sal_uInt16 nFileId, const String& rName )
+{
+ return Add( new ScExternalNameToken(nFileId, rName) );
+}
+
+FormulaToken* ScTokenArray::AddExternalSingleReference( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ return Add( new ScExternalSingleRefToken(nFileId, rTabName, rRef) );
+}
+
+FormulaToken* ScTokenArray::AddExternalDoubleReference( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
+{
+ return Add( new ScExternalDoubleRefToken(nFileId, rTabName, rRef) );
+}
+
+FormulaToken* ScTokenArray::AddColRowName( const ScSingleRefData& rRef )
+{
+ return Add( new ScSingleRefToken( rRef, ocColRowName ) );
+}
+
+BOOL ScTokenArray::GetAdjacentExtendOfOuterFuncRefs( SCCOLROW& nExtend,
+ const ScAddress& rPos, ScDirection eDir )
+{
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+ switch ( eDir )
+ {
+ case DIR_BOTTOM :
+ if ( rPos.Row() < MAXROW )
+ nRow = (nExtend = rPos.Row()) + 1;
+ else
+ return FALSE;
+ break;
+ case DIR_RIGHT :
+ if ( rPos.Col() < MAXCOL )
+ nCol = static_cast<SCCOL>(nExtend = rPos.Col()) + 1;
+ else
+ return FALSE;
+ break;
+ case DIR_TOP :
+ if ( rPos.Row() > 0 )
+ nRow = (nExtend = rPos.Row()) - 1;
+ else
+ return FALSE;
+ break;
+ case DIR_LEFT :
+ if ( rPos.Col() > 0 )
+ nCol = static_cast<SCCOL>(nExtend = rPos.Col()) - 1;
+ else
+ return FALSE;
+ break;
+ default:
+ DBG_ERRORFILE( "unknown Direction" );
+ return FALSE;
+ }
+ if ( pRPN && nRPN )
+ {
+ FormulaToken* t = pRPN[nRPN-1];
+ if ( t->GetType() == svByte )
+ {
+ BYTE nParamCount = t->GetByte();
+ if ( nParamCount && nRPN > nParamCount )
+ {
+ BOOL bRet = FALSE;
+ USHORT nParam = nRPN - nParamCount - 1;
+ for ( ; nParam < nRPN-1; nParam++ )
+ {
+ FormulaToken* p = pRPN[nParam];
+ switch ( p->GetType() )
+ {
+ case svSingleRef :
+ {
+ ScSingleRefData& rRef = static_cast<ScToken*>(p)->GetSingleRef();
+ rRef.CalcAbsIfRel( rPos );
+ switch ( eDir )
+ {
+ case DIR_BOTTOM :
+ if ( rRef.nRow == nRow
+ && rRef.nRow > nExtend )
+ {
+ nExtend = rRef.nRow;
+ bRet = TRUE;
+ }
+ break;
+ case DIR_RIGHT :
+ if ( rRef.nCol == nCol
+ && static_cast<SCCOLROW>(rRef.nCol)
+ > nExtend )
+ {
+ nExtend = rRef.nCol;
+ bRet = TRUE;
+ }
+ break;
+ case DIR_TOP :
+ if ( rRef.nRow == nRow
+ && rRef.nRow < nExtend )
+ {
+ nExtend = rRef.nRow;
+ bRet = TRUE;
+ }
+ break;
+ case DIR_LEFT :
+ if ( rRef.nCol == nCol
+ && static_cast<SCCOLROW>(rRef.nCol)
+ < nExtend )
+ {
+ nExtend = rRef.nCol;
+ bRet = TRUE;
+ }
+ break;
+ }
+ }
+ break;
+ case svDoubleRef :
+ {
+ ScComplexRefData& rRef = static_cast<ScToken*>(p)->GetDoubleRef();
+ rRef.CalcAbsIfRel( rPos );
+ switch ( eDir )
+ {
+ case DIR_BOTTOM :
+ if ( rRef.Ref1.nRow == nRow
+ && rRef.Ref2.nRow > nExtend )
+ {
+ nExtend = rRef.Ref2.nRow;
+ bRet = TRUE;
+ }
+ break;
+ case DIR_RIGHT :
+ if ( rRef.Ref1.nCol == nCol &&
+ static_cast<SCCOLROW>(rRef.Ref2.nCol)
+ > nExtend )
+ {
+ nExtend = rRef.Ref2.nCol;
+ bRet = TRUE;
+ }
+ break;
+ case DIR_TOP :
+ if ( rRef.Ref2.nRow == nRow
+ && rRef.Ref1.nRow < nExtend )
+ {
+ nExtend = rRef.Ref1.nRow;
+ bRet = TRUE;
+ }
+ break;
+ case DIR_LEFT :
+ if ( rRef.Ref2.nCol == nCol &&
+ static_cast<SCCOLROW>(rRef.Ref1.nCol)
+ < nExtend )
+ {
+ nExtend = rRef.Ref1.nCol;
+ bRet = TRUE;
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ } // switch
+ } // for
+ return bRet;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
+ const ScAddress& rNewPos )
+{
+ for ( USHORT j=0; j<nLen; ++j )
+ {
+ switch ( pCode[j]->GetType() )
+ {
+ case svDoubleRef :
+ {
+ ScSingleRefData& rRef2 = static_cast<ScToken*>(pCode[j])->GetSingleRef2();
+ // Also adjust if the reference is of the form Sheet1.A2:A3
+ if ( rRef2.IsFlag3D() || static_cast<ScToken*>(pCode[j])->GetSingleRef().IsFlag3D() )
+ {
+ rRef2.CalcAbsIfRel( rOldPos );
+ rRef2.CalcRelFromAbs( rNewPos );
+ }
+ }
+ //! fallthru
+ case svSingleRef :
+ {
+ ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef();
+ if ( rRef1.IsFlag3D() )
+ {
+ rRef1.CalcAbsIfRel( rOldPos );
+ rRef1.CalcRelFromAbs( rNewPos );
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+
diff --git a/sc/source/core/tool/unitconv.cxx b/sc/source/core/tool/unitconv.cxx
new file mode 100644
index 000000000000..21f80cb1c628
--- /dev/null
+++ b/sc/source/core/tool/unitconv.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "unitconv.hxx"
+#include "global.hxx"
+#include "viewopti.hxx" //! move ScLinkConfigItem to separate header!
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+// --------------------------------------------------------------------
+
+const sal_Unicode cDelim = 0x01; // Delimiter zwischen From und To
+
+
+// --- ScUnitConverterData --------------------------------------------
+
+ScUnitConverterData::ScUnitConverterData( const String& rFromUnit,
+ const String& rToUnit, double fVal )
+ :
+ StrData( rFromUnit ),
+ fValue( fVal )
+{
+ String aTmp;
+ ScUnitConverterData::BuildIndexString( aTmp, rFromUnit, rToUnit );
+ SetString( aTmp );
+}
+
+
+ScUnitConverterData::ScUnitConverterData( const ScUnitConverterData& r )
+ :
+ StrData( r ),
+ fValue( r.fValue )
+{
+}
+
+
+ScDataObject* ScUnitConverterData::Clone() const
+{
+ return new ScUnitConverterData( *this );
+}
+
+
+// static
+void ScUnitConverterData::BuildIndexString( String& rStr,
+ const String& rFromUnit, const String& rToUnit )
+{
+#if 1
+// case sensitive
+ rStr = rFromUnit;
+ rStr += cDelim;
+ rStr += rToUnit;
+#else
+// not case sensitive
+ rStr = rFromUnit;
+ String aTo( rToUnit );
+ ScGlobal::pCharClass->toUpper( rStr );
+ ScGlobal::pCharClass->toUpper( aTo );
+ rStr += cDelim;
+ rStr += aTo;
+#endif
+}
+
+
+// --- ScUnitConverter ------------------------------------------------
+
+#define CFGPATH_UNIT "Office.Calc/UnitConversion"
+#define CFGSTR_UNIT_FROM "FromUnit"
+#define CFGSTR_UNIT_TO "ToUnit"
+#define CFGSTR_UNIT_FACTOR "Factor"
+
+ScUnitConverter::ScUnitConverter( USHORT nInit, USHORT nDeltaP ) :
+ ScStrCollection( nInit, nDeltaP, FALSE )
+{
+ // read from configuration - "convert.ini" is no longer used
+ //! config item as member to allow change of values
+
+ ScLinkConfigItem aConfigItem( OUString::createFromAscii( CFGPATH_UNIT ) );
+
+ // empty node name -> use the config item's path itself
+ OUString aEmptyString;
+ Sequence<OUString> aNodeNames = aConfigItem.GetNodeNames( aEmptyString );
+
+ long nNodeCount = aNodeNames.getLength();
+ if ( nNodeCount )
+ {
+ const OUString* pNodeArray = aNodeNames.getConstArray();
+ Sequence<OUString> aValNames( nNodeCount * 3 );
+ OUString* pValNameArray = aValNames.getArray();
+ const OUString sSlash('/');
+
+ long nIndex = 0;
+ for (long i=0; i<nNodeCount; i++)
+ {
+ OUString sPrefix = pNodeArray[i];
+ sPrefix += sSlash;
+
+ pValNameArray[nIndex] = sPrefix;
+ pValNameArray[nIndex++] += OUString::createFromAscii( CFGSTR_UNIT_FROM );
+ pValNameArray[nIndex] = sPrefix;
+ pValNameArray[nIndex++] += OUString::createFromAscii( CFGSTR_UNIT_TO );
+ pValNameArray[nIndex] = sPrefix;
+ pValNameArray[nIndex++] += OUString::createFromAscii( CFGSTR_UNIT_FACTOR );
+ }
+
+ Sequence<Any> aProperties = aConfigItem.GetProperties(aValNames);
+
+ if (aProperties.getLength() == aValNames.getLength())
+ {
+ const Any* pProperties = aProperties.getConstArray();
+
+ OUString sFromUnit;
+ OUString sToUnit;
+ double fFactor = 0;
+
+ nIndex = 0;
+ for (long i=0; i<nNodeCount; i++)
+ {
+ pProperties[nIndex++] >>= sFromUnit;
+ pProperties[nIndex++] >>= sToUnit;
+ pProperties[nIndex++] >>= fFactor;
+
+ ScUnitConverterData* pNew = new ScUnitConverterData( sFromUnit, sToUnit, fFactor );
+ if ( !Insert( pNew ) )
+ delete pNew;
+ }
+ }
+ }
+}
+
+BOOL ScUnitConverter::GetValue( double& fValue, const String& rFromUnit,
+ const String& rToUnit ) const
+{
+ ScUnitConverterData aSearch( rFromUnit, rToUnit );
+ USHORT nIndex;
+ if ( Search( &aSearch, nIndex ) )
+ {
+ fValue = ((const ScUnitConverterData*)(At( nIndex )))->GetValue();
+ return TRUE;
+ }
+ fValue = 1.0;
+ return FALSE;
+}
+
+
diff --git a/sc/source/core/tool/userlist.cxx b/sc/source/core/tool/userlist.cxx
new file mode 100644
index 000000000000..08609eeff940
--- /dev/null
+++ b/sc/source/core/tool/userlist.cxx
@@ -0,0 +1,297 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <unotools/charclass.hxx>
+#include <string.h>
+
+#include "global.hxx"
+#include "userlist.hxx"
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/calendarwrapper.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//------------------------------------------------------------------------
+
+void ScUserListData::InitTokens()
+{
+ sal_Unicode cSep = ScGlobal::cListDelimiter;
+ nTokenCount = (USHORT) aStr.GetTokenCount(cSep);
+ if (nTokenCount)
+ {
+ pSubStrings = new String[nTokenCount];
+ pUpperSub = new String[nTokenCount];
+ for (USHORT i=0; i<nTokenCount; i++)
+ {
+ pUpperSub[i] = pSubStrings[i] = aStr.GetToken((xub_StrLen)i,cSep);
+ ScGlobal::pCharClass->toUpper(pUpperSub[i]);
+ }
+ }
+ else
+ pSubStrings = pUpperSub = NULL;
+}
+
+ScUserListData::ScUserListData(const String& rStr) :
+ aStr(rStr)
+{
+ InitTokens();
+}
+
+ScUserListData::ScUserListData(const ScUserListData& rData) :
+ ScDataObject(),
+ aStr(rData.aStr)
+{
+ InitTokens();
+}
+
+__EXPORT ScUserListData::~ScUserListData()
+{
+ delete[] pSubStrings;
+ delete[] pUpperSub;
+}
+
+void ScUserListData::SetString( const String& rStr )
+{
+ delete[] pSubStrings;
+ delete[] pUpperSub;
+
+ aStr = rStr;
+ InitTokens();
+}
+
+USHORT ScUserListData::GetSubCount() const
+{
+ return nTokenCount;
+}
+
+BOOL ScUserListData::GetSubIndex(const String& rSubStr, USHORT& rIndex) const
+{
+ USHORT i;
+ for (i=0; i<nTokenCount; i++)
+ if (rSubStr == pSubStrings[i])
+ {
+ rIndex = i;
+ return TRUE;
+ }
+
+ String aUpStr = rSubStr;
+ ScGlobal::pCharClass->toUpper(aUpStr);
+ for (i=0; i<nTokenCount; i++)
+ if (aUpStr == pUpperSub[i])
+ {
+ rIndex = i;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+String ScUserListData::GetSubStr(USHORT nIndex) const
+{
+ if (nIndex < nTokenCount)
+ return pSubStrings[nIndex];
+ else
+ return EMPTY_STRING;
+}
+
+StringCompare ScUserListData::Compare(const String& rSubStr1, const String& rSubStr2) const
+{
+ USHORT nIndex1;
+ USHORT nIndex2;
+ BOOL bFound1 = GetSubIndex(rSubStr1, nIndex1);
+ BOOL bFound2 = GetSubIndex(rSubStr2, nIndex2);
+ if (bFound1)
+ {
+ if (bFound2)
+ {
+ if (nIndex1 < nIndex2)
+ return COMPARE_LESS;
+ else if (nIndex1 > nIndex2)
+ return COMPARE_GREATER;
+ else
+ return COMPARE_EQUAL;
+ }
+ else
+ return COMPARE_LESS;
+ }
+ else if (bFound2)
+ return COMPARE_GREATER;
+ else
+ return (StringCompare) ScGlobal::GetCaseTransliteration()->compareString( rSubStr1, rSubStr2 );
+}
+
+StringCompare ScUserListData::ICompare(const String& rSubStr1, const String& rSubStr2) const
+{
+ USHORT nIndex1;
+ USHORT nIndex2;
+ BOOL bFound1 = GetSubIndex(rSubStr1, nIndex1);
+ BOOL bFound2 = GetSubIndex(rSubStr2, nIndex2);
+ if (bFound1)
+ {
+ if (bFound2)
+ {
+ if (nIndex1 < nIndex2)
+ return COMPARE_LESS;
+ else if (nIndex1 > nIndex2)
+ return COMPARE_GREATER;
+ else
+ return COMPARE_EQUAL;
+ }
+ else
+ return COMPARE_LESS;
+ }
+ else if (bFound2)
+ return COMPARE_GREATER;
+ else
+ return (StringCompare) ScGlobal::GetpTransliteration()->compareString( rSubStr1, rSubStr2 );
+}
+
+ScUserList::ScUserList(USHORT nLim, USHORT nDel) :
+ ScCollection ( nLim, nDel )
+{
+ using namespace ::com::sun::star;
+
+ sal_Unicode cDelimiter = ScGlobal::cListDelimiter;
+ uno::Sequence< i18n::CalendarItem > xCal;
+
+ uno::Sequence< i18n::Calendar > xCalendars(
+ ScGlobal::pLocaleData->getAllCalendars() );
+
+ for ( sal_Int32 j = 0; j < xCalendars.getLength(); ++j )
+ {
+ xCal = xCalendars[j].Days;
+ if ( xCal.getLength() )
+ {
+ String sDayShort, sDayLong;
+ sal_Int32 i;
+ sal_Int32 nLen = xCal.getLength();
+ rtl::OUString sStart = xCalendars[j].StartOfWeek;
+ sal_Int16 nStart = sal::static_int_cast<sal_Int16>(nLen);
+ while (nStart > 0)
+ {
+ if (xCal[--nStart].ID == sStart)
+ break;
+ }
+ sal_Int16 nLast = sal::static_int_cast<sal_Int16>( (nStart + nLen - 1) % nLen );
+ for (i = nStart; i != nLast; i = (i+1) % nLen)
+ {
+ sDayShort += String( xCal[i].AbbrevName );
+ sDayShort += cDelimiter;
+ sDayLong += String( xCal[i].FullName );
+ sDayLong += cDelimiter;
+ }
+ sDayShort += String( xCal[i].AbbrevName );
+ sDayLong += String( xCal[i].FullName );
+
+ if ( !HasEntry( sDayShort ) )
+ Insert( new ScUserListData( sDayShort ));
+ if ( !HasEntry( sDayLong ) )
+ Insert( new ScUserListData( sDayLong ));
+ }
+
+ xCal = xCalendars[j].Months;
+ if ( xCal.getLength() )
+ {
+ String sMonthShort, sMonthLong;
+ sal_Int32 i;
+ sal_Int32 nLen = xCal.getLength() - 1;
+ for (i = 0; i < nLen; i++)
+ {
+ sMonthShort += String( xCal[i].AbbrevName );
+ sMonthShort += cDelimiter;
+ sMonthLong += String( xCal[i].FullName );
+ sMonthLong += cDelimiter;
+ }
+ sMonthShort += String( xCal[i].AbbrevName );
+ sMonthLong += String( xCal[i].FullName );
+
+ if ( !HasEntry( sMonthShort ) )
+ Insert( new ScUserListData( sMonthShort ));
+ if ( !HasEntry( sMonthLong ) )
+ Insert( new ScUserListData( sMonthLong ));
+ }
+ }
+}
+
+ScDataObject* ScUserList::Clone() const
+{
+ return ( new ScUserList( *this ) );
+}
+
+ScUserListData* ScUserList::GetData(const String& rSubStr) const
+{
+ USHORT nIndex;
+ USHORT i = 0;
+ for (i=0; i < nCount; i++)
+ if (((ScUserListData*)pItems[i])->GetSubIndex(rSubStr, nIndex))
+ return (ScUserListData*)pItems[i];
+ return NULL;
+}
+
+BOOL ScUserList::operator==( const ScUserList& r ) const
+{
+ BOOL bEqual = (nCount == r.nCount);
+
+ if ( bEqual )
+ {
+ ScUserListData* pMyData = NULL;
+ ScUserListData* pOtherData = NULL;
+
+ for ( USHORT i=0; i<nCount && bEqual; i++)
+ {
+ pMyData = (ScUserListData*)At(i);
+ pOtherData = (ScUserListData*)r.At(i);
+
+ bEqual =( (pMyData->nTokenCount == pOtherData->nTokenCount)
+ && (pMyData->aStr == pOtherData->aStr) );
+ }
+ }
+
+ return bEqual;
+}
+
+
+BOOL ScUserList::HasEntry( const String& rStr ) const
+{
+ for ( USHORT i=0; i<nCount; i++)
+ {
+ const ScUserListData* pMyData = (ScUserListData*) At(i);
+ if ( pMyData->aStr == rStr )
+ return TRUE;
+ }
+ return FALSE;
+}
+
diff --git a/sc/source/core/tool/viewopti.cxx b/sc/source/core/tool/viewopti.cxx
new file mode 100644
index 000000000000..7dc36bc1b548
--- /dev/null
+++ b/sc/source/core/tool/viewopti.cxx
@@ -0,0 +1,754 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "cfgids.hxx"
+#include "viewopti.hxx"
+#include "rechead.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "miscuno.hxx"
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+//------------------------------------------------------------------
+
+TYPEINIT1(ScTpViewItem, SfxPoolItem);
+
+#define SC_VERSION ((USHORT)302)
+
+
+//========================================================================
+// class ScGridOptions
+//========================================================================
+
+
+void ScGridOptions::SetDefaults()
+{
+ *this = ScGridOptions();
+
+ // Raster-Defaults sind jetzt zwischen den Apps unterschiedlich
+ // darum hier selber eintragen (alles in 1/100mm)
+
+ if ( ScOptionsUtil::IsMetricSystem() )
+ {
+ nFldDrawX = 1000; // 1cm
+ nFldDrawY = 1000;
+ nFldSnapX = 1000;
+ nFldSnapY = 1000;
+ }
+ else
+ {
+ nFldDrawX = 1270; // 0,5"
+ nFldDrawY = 1270;
+ nFldSnapX = 1270;
+ nFldSnapY = 1270;
+ }
+ nFldDivisionX = 1;
+ nFldDivisionY = 1;
+}
+
+//------------------------------------------------------------------------
+
+const ScGridOptions& ScGridOptions::operator=( const ScGridOptions& rCpy )
+{
+ nFldDrawX = rCpy.nFldDrawX; // UINT32
+ nFldDrawX = rCpy.nFldDrawX;
+ nFldDivisionX = rCpy.nFldDivisionX;
+ nFldDrawY = rCpy.nFldDrawY;
+ nFldDivisionY = rCpy.nFldDivisionY;
+ nFldSnapX = rCpy.nFldSnapX;
+ nFldSnapY = rCpy.nFldSnapY;
+ bUseGridsnap = rCpy.bUseGridsnap; // BitBool
+ bSynchronize = rCpy.bSynchronize;
+ bGridVisible = rCpy.bGridVisible;
+ bEqualGrid = rCpy.bEqualGrid;
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+int ScGridOptions::operator==( const ScGridOptions& rCpy ) const
+{
+ return ( nFldDrawX == rCpy.nFldDrawX
+ && nFldDrawX == rCpy.nFldDrawX
+ && nFldDivisionX == rCpy.nFldDivisionX
+ && nFldDrawY == rCpy.nFldDrawY
+ && nFldDivisionY == rCpy.nFldDivisionY
+ && nFldSnapX == rCpy.nFldSnapX
+ && nFldSnapY == rCpy.nFldSnapY
+ && bUseGridsnap == rCpy.bUseGridsnap
+ && bSynchronize == rCpy.bSynchronize
+ && bGridVisible == rCpy.bGridVisible
+ && bEqualGrid == rCpy.bEqualGrid );
+}
+
+
+//========================================================================
+// class ScViewOptions
+//========================================================================
+
+ScViewOptions::ScViewOptions()
+{
+ SetDefaults();
+}
+
+//------------------------------------------------------------------------
+
+ScViewOptions::ScViewOptions( const ScViewOptions& rCpy )
+{
+ *this = rCpy;
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScViewOptions::~ScViewOptions()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScViewOptions::SetDefaults()
+{
+ aOptArr[ VOPT_FORMULAS ] =
+ aOptArr[ VOPT_SYNTAX ] =
+ aOptArr[ VOPT_HELPLINES ] =
+ aOptArr[ VOPT_BIGHANDLES ] = FALSE;
+ aOptArr[ VOPT_NOTES ] =
+ aOptArr[ VOPT_NULLVALS ] =
+ aOptArr[ VOPT_VSCROLL ] =
+ aOptArr[ VOPT_HSCROLL ] =
+ aOptArr[ VOPT_TABCONTROLS ] =
+ aOptArr[ VOPT_OUTLINER ] =
+ aOptArr[ VOPT_HEADER ] =
+ aOptArr[ VOPT_GRID ] =
+ aOptArr[ VOPT_ANCHOR ] =
+ aOptArr[ VOPT_PAGEBREAKS ] =
+ aOptArr[ VOPT_SOLIDHANDLES] =
+ aOptArr[ VOPT_CLIPMARKS ] = TRUE;
+
+ aModeArr[VOBJ_TYPE_OLE ] =
+ aModeArr[VOBJ_TYPE_CHART] =
+ aModeArr[VOBJ_TYPE_DRAW ] = VOBJ_MODE_SHOW;
+
+ aGridCol = Color( SC_STD_GRIDCOLOR );
+ aGridColName = ScGlobal::GetRscString( STR_GRIDCOLOR );
+
+ aGridOpt.SetDefaults();
+}
+
+//------------------------------------------------------------------------
+
+Color ScViewOptions::GetGridColor( String* pStrName ) const
+{
+ if ( pStrName )
+ *pStrName = aGridColName;
+
+ return aGridCol;
+}
+
+//------------------------------------------------------------------------
+
+const ScViewOptions& ScViewOptions::operator=( const ScViewOptions& rCpy )
+{
+ USHORT i;
+
+ for ( i=0; i<MAX_OPT; i++ ) aOptArr [i] = rCpy.aOptArr[i];
+ for ( i=0; i<MAX_TYPE; i++ ) aModeArr[i] = rCpy.aModeArr[i];
+
+ aGridCol = rCpy.aGridCol;
+ aGridColName = rCpy.aGridColName;
+ aGridOpt = rCpy.aGridOpt;
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+
+int ScViewOptions::operator==( const ScViewOptions& rOpt ) const
+{
+ BOOL bEqual = TRUE;
+ USHORT i;
+
+ for ( i=0; i<MAX_OPT && bEqual; i++ ) bEqual = (aOptArr [i] == rOpt.aOptArr[i]);
+ for ( i=0; i<MAX_TYPE && bEqual; i++ ) bEqual = (aModeArr[i] == rOpt.aModeArr[i]);
+
+ bEqual = bEqual && (aGridCol == rOpt.aGridCol);
+ bEqual = bEqual && (aGridColName == rOpt.aGridColName);
+ bEqual = bEqual && (aGridOpt == rOpt.aGridOpt);
+
+ return bEqual;
+}
+
+//------------------------------------------------------------------------
+
+SvxGridItem* ScViewOptions::CreateGridItem( USHORT nId /* = SID_ATTR_GRID_OPTIONS */ ) const
+{
+ SvxGridItem* pItem = new SvxGridItem( nId );
+
+ pItem->SetFldDrawX ( aGridOpt.GetFldDrawX() );
+ pItem->SetFldDivisionX ( aGridOpt.GetFldDivisionX() );
+ pItem->SetFldDrawY ( aGridOpt.GetFldDrawY() );
+ pItem->SetFldDivisionY ( aGridOpt.GetFldDivisionY() );
+ pItem->SetFldSnapX ( aGridOpt.GetFldSnapX() );
+ pItem->SetFldSnapY ( aGridOpt.GetFldSnapY() );
+ pItem->SetUseGridSnap ( aGridOpt.GetUseGridSnap() );
+ pItem->SetSynchronize ( aGridOpt.GetSynchronize() );
+ pItem->SetGridVisible ( aGridOpt.GetGridVisible() );
+ pItem->SetEqualGrid ( aGridOpt.GetEqualGrid() );
+
+ return pItem;
+}
+
+//========================================================================
+// ScTpViewItem - Daten fuer die ViewOptions-TabPage
+//========================================================================
+
+//UNUSED2008-05 ScTpViewItem::ScTpViewItem( USHORT nWhichP ) : SfxPoolItem( nWhichP )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------------
+
+ScTpViewItem::ScTpViewItem( USHORT nWhichP, const ScViewOptions& rOpt )
+ : SfxPoolItem ( nWhichP ),
+ theOptions ( rOpt )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScTpViewItem::ScTpViewItem( const ScTpViewItem& rItem )
+ : SfxPoolItem ( rItem ),
+ theOptions ( rItem.theOptions )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScTpViewItem::~ScTpViewItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScTpViewItem::GetValueText() const
+{
+ return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("ScTpViewItem") );
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScTpViewItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScTpViewItem& rPItem = (const ScTpViewItem&)rItem;
+
+ return ( theOptions == rPItem.theOptions );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScTpViewItem::Clone( SfxItemPool * ) const
+{
+ return new ScTpViewItem( *this );
+}
+
+//==================================================================
+// Config Item containing view options
+//==================================================================
+
+#define CFGPATH_LAYOUT "Office.Calc/Layout"
+
+#define SCLAYOUTOPT_GRIDLINES 0
+#define SCLAYOUTOPT_GRIDCOLOR 1
+#define SCLAYOUTOPT_PAGEBREAK 2
+#define SCLAYOUTOPT_GUIDE 3
+#define SCLAYOUTOPT_SIMPLECONT 4
+#define SCLAYOUTOPT_LARGECONT 5
+#define SCLAYOUTOPT_COLROWHDR 6
+#define SCLAYOUTOPT_HORISCROLL 7
+#define SCLAYOUTOPT_VERTSCROLL 8
+#define SCLAYOUTOPT_SHEETTAB 9
+#define SCLAYOUTOPT_OUTLINE 10
+#define SCLAYOUTOPT_COUNT 11
+
+#define CFGPATH_DISPLAY "Office.Calc/Content/Display"
+
+#define SCDISPLAYOPT_FORMULA 0
+#define SCDISPLAYOPT_ZEROVALUE 1
+#define SCDISPLAYOPT_NOTETAG 2
+#define SCDISPLAYOPT_VALUEHI 3
+#define SCDISPLAYOPT_ANCHOR 4
+#define SCDISPLAYOPT_TEXTOVER 5
+#define SCDISPLAYOPT_OBJECTGRA 6
+#define SCDISPLAYOPT_CHART 7
+#define SCDISPLAYOPT_DRAWING 8
+#define SCDISPLAYOPT_COUNT 9
+
+#define CFGPATH_GRID "Office.Calc/Grid"
+
+#define SCGRIDOPT_RESOLU_X 0
+#define SCGRIDOPT_RESOLU_Y 1
+#define SCGRIDOPT_SUBDIV_X 2
+#define SCGRIDOPT_SUBDIV_Y 3
+#define SCGRIDOPT_OPTION_X 4
+#define SCGRIDOPT_OPTION_Y 5
+#define SCGRIDOPT_SNAPTOGRID 6
+#define SCGRIDOPT_SYNCHRON 7
+#define SCGRIDOPT_VISIBLE 8
+#define SCGRIDOPT_SIZETOGRID 9
+#define SCGRIDOPT_COUNT 10
+
+
+Sequence<OUString> ScViewCfg::GetLayoutPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Line/GridLine", // SCLAYOUTOPT_GRIDLINES
+ "Line/GridLineColor", // SCLAYOUTOPT_GRIDCOLOR
+ "Line/PageBreak", // SCLAYOUTOPT_PAGEBREAK
+ "Line/Guide", // SCLAYOUTOPT_GUIDE
+ "Line/SimpleControlPoint", // SCLAYOUTOPT_SIMPLECONT
+ "Line/LargeControlPoint", // SCLAYOUTOPT_LARGECONT
+ "Window/ColumnRowHeader", // SCLAYOUTOPT_COLROWHDR
+ "Window/HorizontalScroll", // SCLAYOUTOPT_HORISCROLL
+ "Window/VerticalScroll", // SCLAYOUTOPT_VERTSCROLL
+ "Window/SheetTab", // SCLAYOUTOPT_SHEETTAB
+ "Window/OutlineSymbol" // SCLAYOUTOPT_OUTLINE
+ };
+ Sequence<OUString> aNames(SCLAYOUTOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCLAYOUTOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScViewCfg::GetDisplayPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Formula", // SCDISPLAYOPT_FORMULA
+ "ZeroValue", // SCDISPLAYOPT_ZEROVALUE
+ "NoteTag", // SCDISPLAYOPT_NOTETAG
+ "ValueHighlighting", // SCDISPLAYOPT_VALUEHI
+ "Anchor", // SCDISPLAYOPT_ANCHOR
+ "TextOverflow", // SCDISPLAYOPT_TEXTOVER
+ "ObjectGraphic", // SCDISPLAYOPT_OBJECTGRA
+ "Chart", // SCDISPLAYOPT_CHART
+ "DrawingObject" // SCDISPLAYOPT_DRAWING
+ };
+ Sequence<OUString> aNames(SCDISPLAYOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCDISPLAYOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ return aNames;
+}
+
+Sequence<OUString> ScViewCfg::GetGridPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Resolution/XAxis/NonMetric", // SCGRIDOPT_RESOLU_X
+ "Resolution/YAxis/NonMetric", // SCGRIDOPT_RESOLU_Y
+ "Subdivision/XAxis", // SCGRIDOPT_SUBDIV_X
+ "Subdivision/YAxis", // SCGRIDOPT_SUBDIV_Y
+ "Option/XAxis/NonMetric", // SCGRIDOPT_OPTION_X
+ "Option/YAxis/NonMetric", // SCGRIDOPT_OPTION_Y
+ "Option/SnapToGrid", // SCGRIDOPT_SNAPTOGRID
+ "Option/Synchronize", // SCGRIDOPT_SYNCHRON
+ "Option/VisibleGrid", // SCGRIDOPT_VISIBLE
+ "Option/SizeToGrid" // SCGRIDOPT_SIZETOGRID
+ };
+ Sequence<OUString> aNames(SCGRIDOPT_COUNT);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < SCGRIDOPT_COUNT; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+
+ // adjust for metric system
+ if (ScOptionsUtil::IsMetricSystem())
+ {
+ pNames[SCGRIDOPT_RESOLU_X] = OUString::createFromAscii( "Resolution/XAxis/Metric" );
+ pNames[SCGRIDOPT_RESOLU_Y] = OUString::createFromAscii( "Resolution/YAxis/Metric" );
+ pNames[SCGRIDOPT_OPTION_X] = OUString::createFromAscii( "Option/XAxis/Metric" );
+ pNames[SCGRIDOPT_OPTION_Y] = OUString::createFromAscii( "Option/YAxis/Metric" );
+ }
+
+ return aNames;
+}
+
+
+ScViewCfg::ScViewCfg() :
+ aLayoutItem( OUString::createFromAscii( CFGPATH_LAYOUT ) ),
+ aDisplayItem( OUString::createFromAscii( CFGPATH_DISPLAY ) ),
+ aGridItem( OUString::createFromAscii( CFGPATH_GRID ) )
+{
+ sal_Int32 nIntVal = 0;
+
+ Sequence<OUString> aNames = GetLayoutPropertyNames();
+ Sequence<Any> aValues = aLayoutItem.GetProperties(aNames);
+ aLayoutItem.EnableNotification(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCLAYOUTOPT_GRIDCOLOR:
+ if ( pValues[nProp] >>= nIntVal )
+ SetGridColor( Color(nIntVal), EMPTY_STRING );
+ break;
+ case SCLAYOUTOPT_GRIDLINES:
+ SetOption( VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_PAGEBREAK:
+ SetOption( VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_GUIDE:
+ SetOption( VOPT_HELPLINES, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_SIMPLECONT:
+ // content is reversed
+ SetOption( VOPT_SOLIDHANDLES, !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_LARGECONT:
+ SetOption( VOPT_BIGHANDLES, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_COLROWHDR:
+ SetOption( VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_HORISCROLL:
+ SetOption( VOPT_HSCROLL, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_VERTSCROLL:
+ SetOption( VOPT_VSCROLL, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_SHEETTAB:
+ SetOption( VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCLAYOUTOPT_OUTLINE:
+ SetOption( VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+ aLayoutItem.SetCommitLink( LINK( this, ScViewCfg, LayoutCommitHdl ) );
+
+ aNames = GetDisplayPropertyNames();
+ aValues = aDisplayItem.GetProperties(aNames);
+ aDisplayItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCDISPLAYOPT_FORMULA:
+ SetOption( VOPT_FORMULAS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCDISPLAYOPT_ZEROVALUE:
+ SetOption( VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCDISPLAYOPT_NOTETAG:
+ SetOption( VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCDISPLAYOPT_VALUEHI:
+ SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCDISPLAYOPT_ANCHOR:
+ SetOption( VOPT_ANCHOR, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCDISPLAYOPT_TEXTOVER:
+ SetOption( VOPT_CLIPMARKS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCDISPLAYOPT_OBJECTGRA:
+ if ( pValues[nProp] >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if((sal_Int32)VOBJ_MODE_HIDE < nIntVal) nIntVal = (sal_Int32)VOBJ_MODE_SHOW;
+
+ SetObjMode( VOBJ_TYPE_OLE, (ScVObjMode)nIntVal);
+ }
+ break;
+ case SCDISPLAYOPT_CHART:
+ if ( pValues[nProp] >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if((sal_Int32)VOBJ_MODE_HIDE < nIntVal) nIntVal = (sal_Int32)VOBJ_MODE_SHOW;
+
+ SetObjMode( VOBJ_TYPE_CHART, (ScVObjMode)nIntVal);
+ }
+ break;
+ case SCDISPLAYOPT_DRAWING:
+ if ( pValues[nProp] >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if((sal_Int32)VOBJ_MODE_HIDE < nIntVal) nIntVal = (sal_Int32)VOBJ_MODE_SHOW;
+
+ SetObjMode( VOBJ_TYPE_DRAW, (ScVObjMode)nIntVal);
+ }
+ break;
+ }
+ }
+ }
+ }
+ aDisplayItem.SetCommitLink( LINK( this, ScViewCfg, DisplayCommitHdl ) );
+
+ ScGridOptions aGrid = GetGridOptions(); //! initialization necessary?
+ aNames = GetGridPropertyNames();
+ aValues = aGridItem.GetProperties(aNames);
+ aGridItem.EnableNotification(aNames);
+ pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing");
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case SCGRIDOPT_RESOLU_X:
+ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDrawX( nIntVal );
+ break;
+ case SCGRIDOPT_RESOLU_Y:
+ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDrawY( nIntVal );
+ break;
+ case SCGRIDOPT_SUBDIV_X:
+ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDivisionX( nIntVal );
+ break;
+ case SCGRIDOPT_SUBDIV_Y:
+ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDivisionY( nIntVal );
+ break;
+ case SCGRIDOPT_OPTION_X:
+ if (pValues[nProp] >>= nIntVal) aGrid.SetFldSnapX( nIntVal );
+ break;
+ case SCGRIDOPT_OPTION_Y:
+ if (pValues[nProp] >>= nIntVal) aGrid.SetFldSnapY( nIntVal );
+ break;
+ case SCGRIDOPT_SNAPTOGRID:
+ aGrid.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCGRIDOPT_SYNCHRON:
+ aGrid.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCGRIDOPT_VISIBLE:
+ aGrid.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ case SCGRIDOPT_SIZETOGRID:
+ aGrid.SetEqualGrid( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+ break;
+ }
+ }
+ }
+ }
+ SetGridOptions( aGrid );
+ aGridItem.SetCommitLink( LINK( this, ScViewCfg, GridCommitHdl ) );
+}
+
+IMPL_LINK( ScViewCfg, LayoutCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetLayoutPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCLAYOUTOPT_GRIDCOLOR:
+ pValues[nProp] <<= (sal_Int32) GetGridColor().GetColor();
+ break;
+ case SCLAYOUTOPT_GRIDLINES:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_GRID ) );
+ break;
+ case SCLAYOUTOPT_PAGEBREAK:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_PAGEBREAKS ) );
+ break;
+ case SCLAYOUTOPT_GUIDE:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_HELPLINES ) );
+ break;
+ case SCLAYOUTOPT_SIMPLECONT:
+ // content is reversed
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], !GetOption( VOPT_SOLIDHANDLES ) );
+ break;
+ case SCLAYOUTOPT_LARGECONT:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_BIGHANDLES ) );
+ break;
+ case SCLAYOUTOPT_COLROWHDR:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_HEADER ) );
+ break;
+ case SCLAYOUTOPT_HORISCROLL:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_HSCROLL ) );
+ break;
+ case SCLAYOUTOPT_VERTSCROLL:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_VSCROLL ) );
+ break;
+ case SCLAYOUTOPT_SHEETTAB:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_TABCONTROLS ) );
+ break;
+ case SCLAYOUTOPT_OUTLINE:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_OUTLINER ) );
+ break;
+ }
+ }
+ aLayoutItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScViewCfg, DisplayCommitHdl, void *, EMPTYARG )
+{
+ Sequence<OUString> aNames = GetDisplayPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCDISPLAYOPT_FORMULA:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_FORMULAS ) );
+ break;
+ case SCDISPLAYOPT_ZEROVALUE:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_NULLVALS ) );
+ break;
+ case SCDISPLAYOPT_NOTETAG:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_NOTES ) );
+ break;
+ case SCDISPLAYOPT_VALUEHI:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_SYNTAX ) );
+ break;
+ case SCDISPLAYOPT_ANCHOR:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_ANCHOR ) );
+ break;
+ case SCDISPLAYOPT_TEXTOVER:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetOption( VOPT_CLIPMARKS ) );
+ break;
+ case SCDISPLAYOPT_OBJECTGRA:
+ pValues[nProp] <<= (sal_Int32) GetObjMode( VOBJ_TYPE_OLE );
+ break;
+ case SCDISPLAYOPT_CHART:
+ pValues[nProp] <<= (sal_Int32) GetObjMode( VOBJ_TYPE_CHART );
+ break;
+ case SCDISPLAYOPT_DRAWING:
+ pValues[nProp] <<= (sal_Int32) GetObjMode( VOBJ_TYPE_DRAW );
+ break;
+ }
+ }
+ aDisplayItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+IMPL_LINK( ScViewCfg, GridCommitHdl, void *, EMPTYARG )
+{
+ const ScGridOptions& rGrid = GetGridOptions();
+
+ Sequence<OUString> aNames = GetGridPropertyNames();
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case SCGRIDOPT_RESOLU_X:
+ pValues[nProp] <<= (sal_Int32) rGrid.GetFldDrawX();
+ break;
+ case SCGRIDOPT_RESOLU_Y:
+ pValues[nProp] <<= (sal_Int32) rGrid.GetFldDrawY();
+ break;
+ case SCGRIDOPT_SUBDIV_X:
+ pValues[nProp] <<= (sal_Int32) rGrid.GetFldDivisionX();
+ break;
+ case SCGRIDOPT_SUBDIV_Y:
+ pValues[nProp] <<= (sal_Int32) rGrid.GetFldDivisionY();
+ break;
+ case SCGRIDOPT_OPTION_X:
+ pValues[nProp] <<= (sal_Int32) rGrid.GetFldSnapX();
+ break;
+ case SCGRIDOPT_OPTION_Y:
+ pValues[nProp] <<= (sal_Int32) rGrid.GetFldSnapY();
+ break;
+ case SCGRIDOPT_SNAPTOGRID:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], rGrid.GetUseGridSnap() );
+ break;
+ case SCGRIDOPT_SYNCHRON:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], rGrid.GetSynchronize() );
+ break;
+ case SCGRIDOPT_VISIBLE:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], rGrid.GetGridVisible() );
+ break;
+ case SCGRIDOPT_SIZETOGRID:
+ ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], rGrid.GetEqualGrid() );
+ break;
+ }
+ }
+ aGridItem.PutProperties(aNames, aValues);
+
+ return 0;
+}
+
+void ScViewCfg::SetOptions( const ScViewOptions& rNew )
+{
+ *(ScViewOptions*)this = rNew;
+ aLayoutItem.SetModified();
+ aDisplayItem.SetModified();
+ aGridItem.SetModified();
+}
+
+
diff --git a/sc/source/core/tool/zforauto.cxx b/sc/source/core/tool/zforauto.cxx
new file mode 100644
index 000000000000..b505e5a5051c
--- /dev/null
+++ b/sc/source/core/tool/zforauto.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+
+#include "zforauto.hxx"
+#include "global.hxx"
+
+static const sal_Char __FAR_DATA pStandardName[] = "Standard";
+
+//------------------------------------------------------------------------
+
+ScNumFormatAbbrev::ScNumFormatAbbrev() :
+ sFormatstring ( RTL_CONSTASCII_USTRINGPARAM( pStandardName ) ),
+ eLnge (LANGUAGE_SYSTEM),
+ eSysLnge (LANGUAGE_GERMAN) // sonst passt "Standard" nicht
+{
+}
+
+ScNumFormatAbbrev::ScNumFormatAbbrev(const ScNumFormatAbbrev& aFormat) :
+ sFormatstring (aFormat.sFormatstring),
+ eLnge (aFormat.eLnge),
+ eSysLnge (aFormat.eSysLnge)
+{
+}
+
+ScNumFormatAbbrev::ScNumFormatAbbrev(ULONG nFormat,
+ SvNumberFormatter& rFormatter)
+{
+ PutFormatIndex(nFormat, rFormatter);
+}
+
+void ScNumFormatAbbrev::Load( SvStream& rStream, CharSet eByteStrSet )
+{
+ USHORT nSysLang, nLang;
+ rStream.ReadByteString( sFormatstring, eByteStrSet );
+ rStream >> nSysLang >> nLang;
+ eLnge = (LanguageType) nLang;
+ eSysLnge = (LanguageType) nSysLang;
+ if ( eSysLnge == LANGUAGE_SYSTEM ) // old versions did write it
+ eSysLnge = Application::GetSettings().GetLanguage();
+}
+
+void ScNumFormatAbbrev::Save( SvStream& rStream, CharSet eByteStrSet ) const
+{
+ rStream.WriteByteString( sFormatstring, eByteStrSet );
+ rStream << (USHORT) eSysLnge << (USHORT) eLnge;
+}
+
+void ScNumFormatAbbrev::PutFormatIndex(ULONG nFormat,
+ SvNumberFormatter& rFormatter)
+{
+ const SvNumberformat* pFormat = rFormatter.GetEntry(nFormat);
+ if (pFormat)
+ {
+ eSysLnge = Application::GetSettings().GetLanguage();
+ eLnge = pFormat->GetLanguage();
+ sFormatstring = ((SvNumberformat*)pFormat)->GetFormatstring();
+ }
+ else
+ {
+ DBG_ERROR("SCNumFormatAbbrev:: unbekanntes Zahlformat");
+ eLnge = LANGUAGE_SYSTEM;
+ eSysLnge = LANGUAGE_GERMAN; // sonst passt "Standard" nicht
+ sFormatstring.AssignAscii( RTL_CONSTASCII_STRINGPARAM( pStandardName ) );
+ }
+}
+
+ULONG ScNumFormatAbbrev::GetFormatIndex( SvNumberFormatter& rFormatter)
+{
+ short nType;
+ BOOL bNewInserted;
+ xub_StrLen nCheckPos;
+ return rFormatter.GetIndexPuttingAndConverting( sFormatstring, eLnge,
+ eSysLnge, nType, bNewInserted, nCheckPos);
+}
diff --git a/sc/source/filter/dif/difexp.cxx b/sc/source/filter/dif/difexp.cxx
new file mode 100644
index 000000000000..69421879983e
--- /dev/null
+++ b/sc/source/filter/dif/difexp.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <rtl/math.hxx>
+
+#include <stdio.h>
+
+#include "dif.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "progress.hxx"
+#include <rtl/tencinfo.h>
+#include "ftools.hxx"
+
+FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc,
+ const ScAddress& rOutPos, const CharSet eNach, UINT32 nDifOption )
+{
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow );
+ ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() );
+ ScAddress aStart( rOutPos );
+
+ aStart.PutInOrder( aEnd );
+
+ return ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach, nDifOption );
+}
+
+
+FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc,
+ const ScRange&rRange, const CharSet eCharSet, UINT32 nDifOption )
+{
+ DBG_ASSERT( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range unsortiert!" );
+ DBG_ASSERTWARNING( rRange.aStart.Tab() == rRange.aEnd.Tab(),
+ "ScExportDif(): nur eine Tabelle bidde!" );
+
+ const CharSet eStreamCharSet = rOut.GetStreamCharSet();
+ if ( eStreamCharSet != eCharSet )
+ rOut.SetStreamCharSet( eCharSet );
+
+ sal_Unicode cStrDelim('"');
+ ByteString aStrDelimEncoded; // only used if not Unicode
+ UniString aStrDelimDecoded; // only used if context encoding
+ BOOL bContextOrNotAsciiEncoding;
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ {
+ rOut.StartWritingUnicodeText();
+ bContextOrNotAsciiEncoding = FALSE;
+ }
+ else
+ {
+ aStrDelimEncoded = ByteString( cStrDelim, eCharSet );
+ rtl_TextEncodingInfo aInfo;
+ aInfo.StructSize = sizeof(aInfo);
+ if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
+ {
+ bContextOrNotAsciiEncoding =
+ (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
+ ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
+ if ( bContextOrNotAsciiEncoding )
+ aStrDelimDecoded = String( aStrDelimEncoded, eCharSet );
+ }
+ else
+ bContextOrNotAsciiEncoding = FALSE;
+ }
+
+ const sal_Char* p2DoubleQuotes_LF = "\"\"\n";
+ const sal_Char* pSpecDataType_LF = "-1,0\n";
+ const sal_Char* pEmptyData = "1,0\n\"\"\n";
+ const sal_Char* pStringData = "1,0\n";
+ const sal_Char* pNumData = "0,";
+ const sal_Char* pNumDataERROR = "0,0\nERROR\n";
+
+ FltError eRet = eERR_OK;
+ String aOS;
+ String aString;
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCCOL nNumCols = nEndCol - rRange.aStart.Col() + 1;
+ SCROW nNumRows = nEndRow - rRange.aStart.Row() + 1;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ double fVal;
+
+ const BOOL bPlain = ( nDifOption == SC_DIFOPT_PLAIN );
+
+ ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), nNumRows );
+
+ aPrgrsBar.SetState( 0 );
+
+ // TABLE
+ DBG_ASSERT( pDoc->HasTable( nTab ), "*ScExportDif(): Tabelle nicht vorhanden!" );
+
+ aOS = pKeyTABLE;
+ aOS.AppendAscii( "\n0,1\n\"" );
+
+ pDoc->GetName( nTab, aString );
+ aOS += aString;
+ aOS.AppendAscii( "\"\n" );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // VECTORS
+ aOS = pKeyVECTORS;
+ aOS.AppendAscii( "\n0," );
+ aOS += String::CreateFromInt32( nNumCols );
+ aOS += sal_Unicode('\n');
+ aOS.AppendAscii( p2DoubleQuotes_LF );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // TUPLES
+ aOS = pKeyTUPLES;
+ aOS.AppendAscii( "\n0," );
+ aOS += String::CreateFromInt32( nNumRows );
+ aOS += sal_Unicode('\n');
+ aOS.AppendAscii( p2DoubleQuotes_LF );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // DATA
+ aOS = pKeyDATA;
+ aOS.AppendAscii( "\n0,0\n" );
+ aOS.AppendAscii( p2DoubleQuotes_LF );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ SCCOL nColCnt;
+ SCROW nRowCnt;
+ ScBaseCell* pAkt;
+
+ for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ )
+ {
+ aOS.AssignAscii( pSpecDataType_LF );
+ aOS += pKeyBOT;
+ aOS += sal_Unicode('\n');
+ rOut.WriteUnicodeOrByteText( aOS );
+ for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ )
+ {
+ bool bWriteStringData = false;
+ pDoc->GetCell( nColCnt, nRowCnt, nTab, pAkt );
+ if( pAkt )
+ {
+ switch( pAkt->GetCellType() )
+ {
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ aOS.AssignAscii( pEmptyData );
+ break;
+ case CELLTYPE_VALUE:
+ aOS.AssignAscii( pNumData );
+ if( bPlain )
+ {
+ fVal = ( ( ScValueCell * ) pAkt )->GetValue();
+ aOS += String( ::rtl::math::doubleToUString(
+ fVal, rtl_math_StringFormat_G, 14, '.',
+ TRUE));
+ }
+ else
+ {
+ pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
+ aOS += aString;
+ }
+ aOS.AppendAscii( "\nV\n" );
+ break;
+ case CELLTYPE_EDIT:
+ ( ( ScEditCell* ) pAkt )->GetString( aString );
+ bWriteStringData = true;
+ break;
+ case CELLTYPE_STRING:
+ ( ( ScStringCell* ) pAkt )->GetString( aString );
+ bWriteStringData = true;
+ break;
+ case CELLTYPE_FORMULA:
+ if ( ((ScFormulaCell*)pAkt)->GetErrCode() )
+ aOS.AssignAscii( pNumDataERROR );
+ else if( pAkt->HasValueData() )
+ {
+ aOS.AssignAscii( pNumData );
+ if( bPlain )
+ {
+ fVal = ( ( ScFormulaCell * ) pAkt )->GetValue();
+ aOS += String( ::rtl::math::doubleToUString(
+ fVal, rtl_math_StringFormat_G, 14,
+ '.', TRUE));
+ }
+ else
+ {
+ pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
+ aOS += aString;
+ }
+ aOS.AppendAscii( "\nV\n" );
+ }
+ else if( pAkt->HasStringData() )
+ {
+ ( ( ScFormulaCell * ) pAkt )->GetString( aString );
+ bWriteStringData = true;
+ }
+ else
+ aOS.AssignAscii( pNumDataERROR );
+
+ break;
+ default:;
+ }
+ }
+ else
+ aOS.AssignAscii( pEmptyData );
+
+ if ( !bWriteStringData )
+ rOut.WriteUnicodeOrByteText( aOS );
+ else
+ {
+ // for an explanation why this complicated, see
+ // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave()
+ // In fact we should create a common method if this would be
+ // needed just one more time..
+ aOS.AssignAscii( pStringData );
+ rOut.WriteUnicodeOrByteText( aOS, eCharSet );
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ {
+ xub_StrLen nPos = aString.Search( cStrDelim );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aString.Insert( cStrDelim, nPos );
+ nPos = aString.Search( cStrDelim, nPos+2 );
+ }
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ rOut.WriteUnicodeText( aString );
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ }
+ else if ( bContextOrNotAsciiEncoding )
+ {
+ // to byte encoding
+ ByteString aStrEnc( aString, eCharSet );
+ // back to Unicode
+ UniString aStrDec( aStrEnc, eCharSet );
+ // search on re-decoded string
+ xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aStrDec.Insert( aStrDelimDecoded, nPos );
+ nPos = aStrDec.Search( aStrDelimDecoded,
+ nPos+1+aStrDelimDecoded.Len() );
+ }
+ // write byte re-encoded
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ rOut.WriteUnicodeOrByteText( aStrDec, eCharSet );
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ }
+ else
+ {
+ ByteString aStrEnc( aString, eCharSet );
+ // search on encoded string
+ xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aStrEnc.Insert( aStrDelimEncoded, nPos );
+ nPos = aStrEnc.Search( aStrDelimEncoded,
+ nPos+1+aStrDelimEncoded.Len() );
+ }
+ // write byte encoded
+ rOut.Write( aStrDelimEncoded.GetBuffer(),
+ aStrDelimEncoded.Len() );
+ rOut.Write( aStrEnc.GetBuffer(), aStrEnc.Len() );
+ rOut.Write( aStrDelimEncoded.GetBuffer(),
+ aStrDelimEncoded.Len() );
+ }
+ rOut.WriteUniOrByteChar( '\n', eCharSet );
+ }
+ }
+ aPrgrsBar.SetState( nRowCnt );
+ }
+
+ aOS.AssignAscii( pSpecDataType_LF );
+ aOS += pKeyEOD;
+ aOS += sal_Unicode('\n');
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // restore original value
+ rOut.SetStreamCharSet( eStreamCharSet );
+
+ return eRet;
+}
+
+
+
+
diff --git a/sc/source/filter/dif/difimp.cxx b/sc/source/filter/dif/difimp.cxx
new file mode 100644
index 000000000000..2088cc84a791
--- /dev/null
+++ b/sc/source/filter/dif/difimp.cxx
@@ -0,0 +1,1008 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/zforlist.hxx>
+
+#include "dif.hxx"
+#include "filter.hxx"
+#include "fprogressbar.hxx"
+#include "scerrors.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "ftools.hxx"
+
+#include <math.h>
+
+const sal_Unicode pKeyTABLE[] = { 'T', 'A', 'B', 'L', 'E', 0 };
+const sal_Unicode pKeyVECTORS[] = { 'V', 'E', 'C', 'T', 'O', 'R', 'S', 0 };
+const sal_Unicode pKeyTUPLES[] = { 'T', 'U', 'P', 'L', 'E', 'S', 0 };
+const sal_Unicode pKeyDATA[] = { 'D', 'A', 'T', 'A', 0 };
+const sal_Unicode pKeyBOT[] = { 'B', 'O', 'T', 0 };
+const sal_Unicode pKeyEOD[] = { 'E', 'O', 'D', 0 };
+const sal_Unicode pKeyERROR[] = { 'E', 'R', 'R', 'O', 'R', 0 };
+const sal_Unicode pKeyTRUE[] = { 'T', 'R', 'U', 'E', 0 };
+const sal_Unicode pKeyFALSE[] = { 'F', 'A', 'L', 'S', 'E', 0 };
+const sal_Unicode pKeyNA[] = { 'N', 'A', 0 };
+const sal_Unicode pKeyV[] = { 'V', 0 };
+const sal_Unicode pKey1_0[] = { '1', ',', '0', 0 };
+
+
+FltError ScFormatFilterPluginImpl::ScImportDif( SvStream& rIn, ScDocument* pDoc, const ScAddress& rInsPos,
+ const CharSet eVon, UINT32 nDifOption )
+{
+ DifParser aDifParser( rIn, nDifOption, *pDoc, eVon );
+
+ const BOOL bPlain = aDifParser.IsPlain();
+
+ SCTAB nBaseTab = rInsPos.Tab();
+
+ TOPIC eTopic = T_UNKNOWN;
+ BOOL bSyntErrWarn = FALSE;
+ BOOL bOverflowWarn = FALSE;
+
+ String& rData = aDifParser.aData;
+ BOOL bData = FALSE;
+
+ SCCOL nNumCols = 0;
+ SCROW nNumRows = 0;
+
+ rIn.Seek( 0 );
+
+ ScfStreamProgressBar aPrgrsBar( rIn, pDoc->GetDocumentShell() );
+
+ while( eTopic != T_DATA && eTopic != T_END )
+ {
+ eTopic = aDifParser.GetNextTopic();
+
+ aPrgrsBar.Progress();
+
+ bData = rData.Len() > 0;
+
+ switch( eTopic )
+ {
+ case T_TABLE:
+ {
+ if( aDifParser.nVector != 0 || aDifParser.nVal != 1 )
+ bSyntErrWarn = TRUE;
+ if( bData )
+ pDoc->RenameTab( nBaseTab, rData );
+ }
+ break;
+ case T_VECTORS:
+ {
+ if( aDifParser.nVector != 0 )
+ bSyntErrWarn = TRUE;
+ if( aDifParser.nVal > MAXCOL + 1 )
+ nNumCols = SCCOL_MAX;
+ else
+ nNumCols = static_cast<SCCOL>(aDifParser.nVal);
+ }
+ break;
+ case T_TUPLES:
+ {
+ if( aDifParser.nVector != 0 )
+ bSyntErrWarn = TRUE;
+ if( aDifParser.nVal > MAXROW + 1 )
+ nNumRows = SCROW_MAX;
+ else
+ nNumRows = static_cast<SCROW>(aDifParser.nVal);
+ }
+ break;
+ case T_DATA:
+ {
+ if( aDifParser.nVector != 0 || aDifParser.nVal != 0 )
+ bSyntErrWarn = TRUE;
+ }
+ break;
+ case T_LABEL:
+ case T_COMMENT:
+ case T_SIZE:
+ case T_PERIODICITY:
+ case T_MAJORSTART:
+ case T_MINORSTART:
+ case T_TRUELENGTH:
+ case T_UINITS:
+ case T_DISPLAYUNITS:
+ case T_END:
+ case T_UNKNOWN:
+ break;
+ default:
+ DBG_ERRORFILE( "ScImportDif - missing enum" );
+ }
+
+ }
+
+
+ if( eTopic == T_DATA )
+ { // Ab hier kommen die Daten
+ SCCOL nBaseCol = rInsPos.Col();
+
+ SCCOL nColCnt = SCCOL_MAX;
+ SCROW nRowCnt = rInsPos.Row();
+ DifAttrCache aAttrCache( bPlain );
+
+ DATASET eAkt = D_UNKNOWN;
+
+ while( eAkt != D_EOD )
+ {
+ eAkt = aDifParser.GetNextDataset();
+
+ aPrgrsBar.Progress();
+
+ switch( eAkt )
+ {
+ case D_BOT:
+ if( nColCnt < SCCOL_MAX )
+ nRowCnt++;
+ nColCnt = nBaseCol;
+ break;
+ case D_EOD:
+ break;
+ case D_NUMERIC: // Numbercell
+ if( nColCnt == SCCOL_MAX )
+ nColCnt = nBaseCol;
+
+ if( ValidCol(nColCnt) && ValidRow(nRowCnt) )
+ {
+ ScBaseCell* pCell;
+ if( DifParser::IsV( rData.GetBuffer() ) )
+ {
+ pCell = new ScValueCell( aDifParser.fVal );
+ if( !bPlain )
+ aAttrCache.SetNumFormat( nColCnt, nRowCnt,
+ aDifParser.nNumFormat );
+ }
+ else if( rData == pKeyTRUE || rData == pKeyFALSE )
+ {
+ pCell = new ScValueCell( aDifParser.fVal );
+ if( bPlain )
+ aAttrCache.SetLogical( nColCnt, nRowCnt );
+ else
+ aAttrCache.SetNumFormat( nColCnt, nRowCnt,
+ aDifParser.nNumFormat );
+ }
+ else if( rData == pKeyNA || rData == pKeyERROR )
+ pCell = new ScStringCell( rData );
+ else
+ {
+ String aTmp( RTL_CONSTASCII_USTRINGPARAM( "#IND: " ));
+ aTmp += rData;
+ aTmp += sal_Unicode('?');
+ pCell = new ScStringCell( aTmp );
+ }
+
+ pDoc->PutCell( nColCnt, nRowCnt, nBaseTab, pCell, ( BOOL ) TRUE );
+ }
+ else
+ bOverflowWarn = TRUE;
+
+ nColCnt++;
+ break;
+ case D_STRING: // Textcell
+ if( nColCnt == SCCOL_MAX )
+ nColCnt = nBaseCol;
+
+ if( ValidCol(nColCnt) && ValidRow(nRowCnt) )
+ {
+ if( rData.Len() > 0 )
+ {
+ pDoc->PutCell( nColCnt, nRowCnt, nBaseTab,
+ ScBaseCell::CreateTextCell( rData, pDoc ), ( BOOL ) TRUE );
+ }
+ }
+ else
+ bOverflowWarn = TRUE;
+
+ nColCnt++;
+ break;
+ case D_UNKNOWN:
+ break;
+ case D_SYNT_ERROR:
+ break;
+ default:
+ DBG_ERROR( "ScImportDif - missing enum" );
+ }
+ }
+
+ aAttrCache.Apply( *pDoc, nBaseTab );
+ }
+ else
+ return eERR_FORMAT;
+
+ if( bSyntErrWarn )
+ //###############################################
+ // ACHTUNG: Hier fehlt noch die richtige Warnung!
+ return eERR_RNGOVRFLW;
+ //###############################################
+ else if( bOverflowWarn )
+ return eERR_RNGOVRFLW;
+ else
+ return eERR_OK;
+}
+
+
+DifParser::DifParser( SvStream& rNewIn, const UINT32 nOption, ScDocument& rDoc, CharSet e ) :
+ rIn( rNewIn )
+{
+ eCharSet = e;
+ if ( rIn.GetStreamCharSet() != eCharSet )
+ {
+ DBG_ERRORFILE( "CharSet passed overrides and modifies StreamCharSet" );
+ rIn.SetStreamCharSet( eCharSet );
+ }
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ rIn.StartReadingUnicodeText();
+
+ bPlain = ( nOption == SC_DIFOPT_PLAIN );
+
+ if( bPlain )
+ pNumFormatter = NULL;
+ else
+ pNumFormatter = rDoc.GetFormatTable();
+}
+
+
+TOPIC DifParser::GetNextTopic( void )
+{
+ enum STATE { S_VectorVal, S_Data, S_END, S_START, S_UNKNOWN, S_ERROR_L2 };
+
+ static const sal_Unicode pKeyLABEL[] = { 'L', 'A', 'B', 'E', 'L', 0 };
+ static const sal_Unicode pKeyCOMMENT[] = { 'C', 'O', 'M', 'M', 'E', 'N', 'T', 0 };
+ static const sal_Unicode pKeySIZE[] = { 'S', 'I', 'Z', 'E', 0 };
+ static const sal_Unicode pKeyPERIODICITY[] = { 'P', 'E', 'R', 'I', 'O', 'D', 'I', 'C', 'I', 'T', 'Y', 0 };
+ static const sal_Unicode pKeyMAJORSTART[] = { 'M', 'A', 'J', 'O', 'R', 'S', 'T', 'A', 'R', 'T', 0 };
+ static const sal_Unicode pKeyMINORSTART[] = { 'M', 'I', 'N', 'O', 'R', 'S', 'T', 'A', 'R', 'T', 0 };
+ static const sal_Unicode pKeyTRUELENGTH[] = { 'T', 'R', 'U', 'E', 'L', 'E', 'N', 'G', 'T', 'H', 0 };
+ static const sal_Unicode pKeyUINITS[] = { 'U', 'I', 'N', 'I', 'T', 'S', 0 };
+ static const sal_Unicode pKeyDISPLAYUNITS[] = { 'D', 'I', 'S', 'P', 'L', 'A', 'Y', 'U', 'N', 'I', 'T', 'S', 0 };
+ static const sal_Unicode pKeyUNKNOWN[] = { 0 };
+
+ static const sal_Unicode* ppKeys[] =
+ {
+ pKeyTABLE, // 0
+ pKeyVECTORS,
+ pKeyTUPLES,
+ pKeyDATA,
+ pKeyLABEL,
+ pKeyCOMMENT, // 5
+ pKeySIZE,
+ pKeyPERIODICITY,
+ pKeyMAJORSTART,
+ pKeyMINORSTART,
+ pKeyTRUELENGTH, // 10
+ pKeyUINITS,
+ pKeyDISPLAYUNITS,
+ pKeyUNKNOWN // 13
+ };
+
+ static const TOPIC pTopics[] =
+ {
+ T_TABLE, // 0
+ T_VECTORS,
+ T_TUPLES,
+ T_DATA,
+ T_LABEL,
+ T_COMMENT, // 5
+ T_SIZE,
+ T_PERIODICITY,
+ T_MAJORSTART,
+ T_MINORSTART,
+ T_TRUELENGTH, // 10
+ T_UINITS,
+ T_DISPLAYUNITS,
+ T_UNKNOWN // 13
+ };
+
+ STATE eS = S_START;
+ String aLine;
+
+ nVector = 0;
+ nVal = 0;
+ TOPIC eRet = T_UNKNOWN;
+
+ while( eS != S_END )
+ {
+ if( !ReadNextLine( aLine ) )
+ {
+ eS = S_END;
+ eRet = T_END;
+ }
+
+ switch( eS )
+ {
+ case S_START:
+ {
+ const sal_Unicode* pRef;
+ UINT16 nCnt = 0;
+ BOOL bSearch = TRUE;
+
+ pRef = ppKeys[ nCnt ];
+
+ while( bSearch )
+ {
+ if( aLine == pRef )
+ {
+ eRet = pTopics[ nCnt ];
+ bSearch = FALSE;
+ }
+ else
+ {
+ nCnt++;
+ pRef = ppKeys[ nCnt ];
+ if( !*pRef )
+ bSearch = FALSE;
+ }
+ }
+
+ if( *pRef )
+ eS = S_VectorVal;
+ else
+ eS = S_UNKNOWN;
+ }
+ break;
+ case S_VectorVal:
+ {
+ const sal_Unicode* pCur = aLine.GetBuffer();
+
+ pCur = ScanIntVal( pCur, nVector );
+
+ if( pCur && *pCur == ',' )
+ {
+ pCur++;
+ ScanIntVal( pCur, nVal );
+ eS = S_Data;
+ }
+ else
+ eS = S_ERROR_L2;
+ }
+ break;
+ case S_Data:
+ DBG_ASSERT( aLine.Len() >= 2,
+ "+GetNextTopic(): <String> ist zu kurz!" );
+ if( aLine.Len() > 2 )
+ aData = aLine.Copy( 1, aLine.Len() - 2 );
+ else
+ aData.Erase();
+ eS = S_END;
+ break;
+ case S_END:
+ DBG_ERRORFILE( "DifParser::GetNextTopic - unexpected state" );
+ break;
+ case S_UNKNOWN:
+ // 2 Zeilen ueberlesen
+ ReadNextLine( aLine );
+ case S_ERROR_L2: // Fehler in Line 2 aufgetreten
+ // eine Zeile ueberlesen
+ ReadNextLine( aLine );
+ eS = S_END;
+ break;
+ default:
+ DBG_ERRORFILE( "DifParser::GetNextTopic - missing enum" );
+ }
+ }
+
+ return eRet;
+}
+
+
+static void lcl_DeEscapeQuotesDif( String& rString )
+{
+ // Special handling for DIF import: Escaped (duplicated) quotes are resolved.
+ // Single quote characters are left in place because older versions didn't
+ // escape quotes in strings (and Excel doesn't when using the clipboard).
+ // The quotes around the string are removed before this function is called.
+
+ static const sal_Unicode aDQ[] = { '"', '"', 0 };
+ xub_StrLen nPos = 0;
+ while ( (nPos = rString.Search( aDQ, nPos )) != STRING_NOTFOUND )
+ {
+ rString.Erase( nPos, 1 );
+ ++nPos;
+ }
+}
+
+// Determine if passed in string is numeric data and set fVal/nNumFormat if so
+DATASET DifParser::GetNumberDataset( const sal_Unicode* pPossibleNumericData )
+{
+ DATASET eRet = D_SYNT_ERROR;
+ if( bPlain )
+ {
+ if( ScanFloatVal( pPossibleNumericData ) )
+ eRet = D_NUMERIC;
+ else
+ eRet = D_SYNT_ERROR;
+ }
+ else
+ { // ...und zur Strafe mit'm Numberformatter...
+ DBG_ASSERT( pNumFormatter, "-DifParser::GetNextDataset(): No Formatter, more fun!" );
+ String aTestVal( pPossibleNumericData );
+ sal_uInt32 nFormat = 0;
+ double fTmpVal;
+ if( pNumFormatter->IsNumberFormat( aTestVal, nFormat, fTmpVal ) )
+ {
+ fVal = fTmpVal;
+ nNumFormat = nFormat;
+ eRet = D_NUMERIC;
+ }
+ else
+ eRet = D_SYNT_ERROR;
+ }
+ return eRet;
+}
+
+bool DifParser::ReadNextLine( String& rStr )
+{
+ if( aLookAheadLine.Len() == 0 )
+ {
+ return rIn.ReadUniOrByteStringLine( rStr );
+ }
+ else
+ {
+ rStr = aLookAheadLine;
+ aLookAheadLine.Erase();
+ return true;
+ }
+}
+
+// Look ahead in the stream to determine if the next line is the first line of
+// a valid data record structure
+bool DifParser::LookAhead()
+{
+ const sal_Unicode* pAktBuffer;
+ bool bValidStructure = false;
+
+ DBG_ASSERT( aLookAheadLine.Len() == 0, "*DifParser::LookAhead(): LookAhead called twice in a row" );
+ rIn.ReadUniOrByteStringLine( aLookAheadLine );
+
+ pAktBuffer = aLookAheadLine.GetBuffer();
+
+ switch( *pAktBuffer )
+ {
+ case '-': // Special Datatype
+ pAktBuffer++;
+
+ if( Is1_0( pAktBuffer ) )
+ {
+ bValidStructure = true;
+ }
+ break;
+ case '0': // Numeric Data
+ pAktBuffer++;
+ if( *pAktBuffer == ',' )
+ {
+ pAktBuffer++;
+ bValidStructure = ( GetNumberDataset(pAktBuffer) != D_SYNT_ERROR );
+ }
+ break;
+ case '1': // String Data
+ if( Is1_0( aLookAheadLine.GetBuffer() ) )
+ {
+ bValidStructure = true;
+ }
+ break;
+ }
+ return bValidStructure;
+}
+
+DATASET DifParser::GetNextDataset( void )
+{
+ DATASET eRet = D_UNKNOWN;
+ String aLine;
+ const sal_Unicode* pAktBuffer;
+
+ ReadNextLine( aLine );
+
+ pAktBuffer = aLine.GetBuffer();
+
+ switch( *pAktBuffer )
+ {
+ case '-': // Special Datatype
+ pAktBuffer++;
+
+ if( Is1_0( pAktBuffer ) )
+ {
+ ReadNextLine( aLine );
+ if( IsBOT( aLine.GetBuffer() ) )
+ eRet = D_BOT;
+ else if( IsEOD( aLine.GetBuffer() ) )
+ eRet = D_EOD;
+ }
+ break;
+ case '0': // Numeric Data
+ pAktBuffer++; // Wert in fVal, 2. Zeile in aData
+ if( *pAktBuffer == ',' )
+ {
+ pAktBuffer++;
+ eRet = GetNumberDataset(pAktBuffer);
+ ReadNextLine( aData );
+ if ( eRet == D_SYNT_ERROR )
+ { // for broken records write "#ERR: data" to cell
+ String aTmp( RTL_CONSTASCII_USTRINGPARAM( "#ERR: " ));
+ aTmp += pAktBuffer;
+ aTmp.AppendAscii( " (" );
+ aTmp += aData;
+ aTmp += sal_Unicode(')');
+ aData = aTmp;
+ eRet = D_STRING;
+ }
+ }
+ break;
+ case '1': // String Data
+ if( Is1_0( aLine.GetBuffer() ) )
+ {
+ ReadNextLine( aLine );
+ xub_StrLen nLineLength = aLine.Len();
+ const sal_Unicode* pLine = aLine.GetBuffer();
+
+ if( nLineLength >= 1 && *pLine == '"' )
+ {
+ // Quotes are not always escaped (duplicated), see lcl_DeEscapeQuotesDif
+ // A look ahead into the next line is needed in order to deal with
+ // multiline strings containing quotes
+ if( LookAhead() )
+ {
+ // Single line string
+ if( nLineLength >= 2 && pLine[nLineLength - 1] == '"' )
+ {
+ aData = aLine.Copy( 1, nLineLength - 2 );
+ lcl_DeEscapeQuotesDif( aData );
+ eRet = D_STRING;
+ }
+ }
+ else
+ {
+ // Multiline string
+ aData = aLine.Copy( 1 );
+ bool bContinue = true;
+ while ( bContinue )
+ {
+ aData.Append( '\n' );
+ bContinue = !rIn.IsEof() && ReadNextLine( aLine );
+ if( bContinue )
+ {
+ nLineLength = aLine.Len();
+ if( nLineLength >= 1 )
+ {
+ pLine = aLine.GetBuffer();
+ bContinue = !LookAhead();
+ if( bContinue )
+ {
+ aData.Append( aLine );
+ }
+ else if( pLine[nLineLength - 1] == '"' )
+ {
+ aData.Append( pLine, nLineLength - 1 );
+ lcl_DeEscapeQuotesDif( aData );
+ eRet = D_STRING;
+ }
+ }
+ }
+ };
+ }
+ }
+ }
+ break;
+ }
+
+ if( eRet == D_UNKNOWN )
+ ReadNextLine( aLine );
+
+ if( rIn.IsEof() )
+ eRet = D_EOD;
+
+ return eRet;
+}
+
+
+const sal_Unicode* DifParser::ScanIntVal( const sal_Unicode* pStart, UINT32& rRet )
+{
+ // eat leading whitespace, not specified, but seen in the wild
+ while (*pStart == ' ' || *pStart == '\t')
+ ++pStart;
+
+ sal_Unicode cAkt = *pStart;
+
+ if( IsNumber( cAkt ) )
+ rRet = ( UINT32 ) ( cAkt - '0' );
+ else
+ return NULL;
+
+ pStart++;
+ cAkt = *pStart;
+
+ while( IsNumber( cAkt ) && rRet < ( 0xFFFFFFFF / 10 ) )
+ {
+ rRet *= 10;
+ rRet += ( UINT32 ) ( cAkt - '0' );
+
+ pStart++;
+ cAkt = *pStart;
+ }
+
+ return pStart;
+}
+
+
+BOOL DifParser::ScanFloatVal( const sal_Unicode* pStart )
+ {
+ double fNewVal = 0.0;
+ BOOL bNeg = FALSE;
+ double fFracPos = 1.0;
+ INT32 nExp = 0;
+ BOOL bExpNeg = FALSE;
+ BOOL bExpOverflow = FALSE;
+ static const UINT16 nExpLimit = 4096; // ACHTUNG: muss genauer ermittelt werden!
+
+ sal_Unicode cAkt;
+ BOOL bRet = FALSE;
+
+ enum STATE { S_FIRST, S_PRE, S_POST, S_EXP_FIRST, S_EXP, S_END, S_FINDEND };
+
+ STATE eS = S_FIRST;
+
+ fNewVal = 0.0;
+
+ while( eS != S_END )
+ {
+ cAkt = *pStart;
+ switch( eS )
+ {
+ case S_FIRST:
+ if( IsNumber( cAkt ) )
+ {
+ fNewVal *= 10;
+ fNewVal += cAkt - '0';
+ eS = S_PRE;
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case ' ':
+ case '\t':
+ case '+':
+ break;
+ case '-':
+ bNeg = !bNeg;
+ break;
+ case '.':
+ case ',': //!
+ eS = S_POST;
+ fFracPos = 0.1;
+ break;
+ default:
+ eS = S_END;
+ }
+ }
+ break;
+ case S_PRE:
+ if( IsNumber( cAkt ) )
+ {
+ fNewVal *= 10;
+ fNewVal += cAkt - '0';
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case '.':
+ case ',': //!
+ eS = S_POST;
+ fFracPos = 0.1;
+ break;
+ case 'e':
+ case 'E':
+ eS = S_EXP;
+ break;
+ case 0x00: // IsNumberEnding( cAkt )
+ bRet = TRUE; // no
+ default: // break!
+ eS = S_END;
+ }
+ }
+ break;
+ case S_POST:
+ if( IsNumber( cAkt ) )
+ {
+ fNewVal += fFracPos * ( cAkt - '0' );
+ fFracPos /= 10.0;
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case 'e':
+ case 'E':
+ eS = S_EXP_FIRST;
+ break;
+ case 0x00: // IsNumberEnding( cAkt )
+ bRet = TRUE; // no
+ default: // break!
+ eS = S_END;
+ }
+ }
+ break;
+ case S_EXP_FIRST:
+ if( IsNumber( cAkt ) )
+ {
+ if( nExp < nExpLimit )
+ {
+ nExp *= 10;
+ nExp += ( UINT16 ) ( cAkt - '0' );
+ }
+ eS = S_EXP;
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case '+':
+ break;
+ case '-':
+ bExpNeg = !bExpNeg;
+ break;
+ default:
+ eS = S_END;
+ }
+ }
+ break;
+ case S_EXP:
+ if( IsNumber( cAkt ) )
+ {
+ if( nExp < ( 0xFFFF / 10 ) )
+ {
+ nExp *= 10;
+ nExp += ( UINT16 ) ( cAkt - '0' );
+ }
+ else
+ {
+ bExpOverflow = TRUE;
+ eS = S_FINDEND;
+ }
+ }
+ else
+ {
+ bRet = IsNumberEnding( cAkt );
+ eS = S_END;
+ }
+ break;
+ case S_FINDEND:
+ if( IsNumberEnding( cAkt ) )
+ {
+ bRet = TRUE; // damit sinnvoll weitergeparst werden kann
+ eS = S_END;
+ }
+ break;
+ case S_END:
+ DBG_ERRORFILE( "DifParser::ScanFloatVal - unexpected state" );
+ break;
+ default:
+ DBG_ERRORFILE( "DifParser::ScanFloatVal - missing enum" );
+ }
+ pStart++;
+ }
+
+ if( bRet )
+ {
+ if( bExpOverflow )
+ return sal_False; // ACHTUNG: hier muss noch differenziert werden
+
+ if( bNeg )
+ fNewVal *= 1.0;
+
+ if( bExpNeg )
+ nExp *= -1;
+
+ if( nExp != 0 )
+ fNewVal *= pow( 10.0, ( double ) nExp );
+ fVal = fNewVal;
+ }
+
+ return bRet;
+}
+
+
+DifColumn::~DifColumn( void )
+{
+ ENTRY* pEntry = ( ENTRY* ) List::First();
+
+ while( pEntry )
+ {
+ delete pEntry;
+ pEntry = ( ENTRY* ) List::Next();
+ }
+}
+
+
+void DifColumn::SetLogical( SCROW nRow )
+{
+ DBG_ASSERT( ValidRow(nRow), "*DifColumn::SetLogical(): Row zu gross!" );
+
+ if( pAkt )
+ {
+ DBG_ASSERT( nRow > 0, "*DifColumn::SetLogical(): weitere koennen nicht 0 sein!" );
+ nRow--;
+ if( pAkt->nEnd == nRow )
+ pAkt->nEnd++;
+ else
+ pAkt = NULL;
+ }
+ else
+ {
+ pAkt = new ENTRY;
+ pAkt->nStart = pAkt->nEnd = nRow;
+ List::Insert( pAkt, LIST_APPEND );
+ }
+}
+
+
+void DifColumn::SetNumFormat( SCROW nRow, const UINT32 nNumFormat )
+{
+ DBG_ASSERT( ValidRow(nRow), "*DifColumn::SetNumFormat(): Row zu gross!" );
+
+ if( nNumFormat > 0 )
+ {
+ if( pAkt )
+ {
+ DBG_ASSERT( nRow > 0,
+ "*DifColumn::SetNumFormat(): weitere koennen nicht 0 sein!" );
+ DBG_ASSERT( nRow > pAkt->nEnd,
+ "*DifColumn::SetNumFormat(): Noch 'mal von vorne?" );
+
+ if( pAkt->nNumFormat == nNumFormat && pAkt->nEnd == nRow - 1 )
+ pAkt->nEnd = nRow;
+ else
+ NewEntry( nRow, nNumFormat );
+ }
+ else
+ NewEntry( nRow, nNumFormat );
+ }
+ else
+ pAkt = NULL;
+}
+
+
+void DifColumn::NewEntry( const SCROW nPos, const UINT32 nNumFormat )
+{
+ pAkt = new ENTRY;
+ pAkt->nStart = pAkt->nEnd = nPos;
+ pAkt->nNumFormat = nNumFormat;
+ List::Insert( pAkt, LIST_APPEND );
+}
+
+
+void DifColumn::Apply( ScDocument& rDoc, const SCCOL nCol, const SCTAB nTab, const ScPatternAttr& rPattAttr )
+{
+ ENTRY* pEntry = ( ENTRY* ) List::First();
+
+ while( pEntry )
+ {
+ rDoc.ApplyPatternAreaTab( nCol, pEntry->nStart, nCol, pEntry->nEnd,
+ nTab, rPattAttr );
+ pEntry = ( ENTRY* ) List::Next();
+ }
+}
+
+
+void DifColumn::Apply( ScDocument& rDoc, const SCCOL nCol, const SCTAB nTab )
+{
+ ScPatternAttr aAttr( rDoc.GetPool() );
+ SfxItemSet& rItemSet = aAttr.GetItemSet();
+
+ ENTRY* pEntry = ( ENTRY* ) List::First();
+
+ while( pEntry )
+ {
+ DBG_ASSERT( pEntry->nNumFormat > 0,
+ "+DifColumn::Apply(): Numberformat darf hier nicht 0 sein!" );
+ rItemSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, pEntry->nNumFormat ) );
+
+ rDoc.ApplyPatternAreaTab( nCol, pEntry->nStart, nCol, pEntry->nEnd, nTab, aAttr );
+
+ rItemSet.ClearItem();
+
+ pEntry = ( ENTRY* ) List::Next();
+ }
+}
+
+
+DifAttrCache::DifAttrCache( const BOOL bNewPlain )
+{
+ bPlain = bNewPlain;
+ ppCols = new DifColumn *[ MAXCOL + 1 ];
+ for( SCCOL nCnt = 0 ; nCnt <= MAXCOL ; nCnt++ )
+ ppCols[ nCnt ] = NULL;
+}
+
+
+DifAttrCache::~DifAttrCache()
+{
+ for( SCCOL nCnt = 0 ; nCnt <= MAXCOL ; nCnt++ )
+ {
+ if( ppCols[ nCnt ] )
+ delete ppCols[ nCnt ];
+ }
+}
+
+
+void DifAttrCache::SetNumFormat( const SCCOL nCol, const SCROW nRow, const UINT32 nNumFormat )
+{
+ DBG_ASSERT( ValidCol(nCol), "-DifAttrCache::SetNumFormat(): Col zu gross!" );
+ DBG_ASSERT( !bPlain, "*DifAttrCache::SetNumFormat(): sollte nicht Plain sein!" );
+
+ if( !ppCols[ nCol ] )
+ ppCols[ nCol ] = new DifColumn;
+
+ ppCols[ nCol ]->SetNumFormat( nRow, nNumFormat );
+}
+
+
+void DifAttrCache::Apply( ScDocument& rDoc, SCTAB nTab )
+{
+ if( bPlain )
+ {
+ ScPatternAttr* pPatt = NULL;
+
+ for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
+ {
+ if( ppCols[ nCol ] )
+ {
+ if( !pPatt )
+ {
+ pPatt = new ScPatternAttr( rDoc.GetPool() );
+ pPatt->GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT,
+ rDoc.GetFormatTable()->GetStandardFormat( NUMBERFORMAT_LOGICAL ) ) );
+ }
+
+ ppCols[ nCol ]->Apply( rDoc, nCol, nTab, *pPatt );
+ }
+ }
+
+ if( pPatt )
+ delete pPatt;
+ }
+ else
+ {
+ for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
+ {
+ if( ppCols[ nCol ] )
+ ppCols[ nCol ]->Apply( rDoc, nCol, nTab );
+ }
+ }
+}
+
+
+
diff --git a/sc/source/filter/dif/makefile.mk b/sc/source/filter/dif/makefile.mk
new file mode 100644
index 000000000000..c24de4cb4164
--- /dev/null
+++ b/sc/source/filter/dif/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=dif
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/difimp.obj \
+ $(SLO)$/difexp.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx
new file mode 100644
index 000000000000..01587c036dea
--- /dev/null
+++ b/sc/source/filter/excel/colrowst.cxx
@@ -0,0 +1,318 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "colrowst.hxx"
+
+#include <string.h>
+
+#include "document.hxx"
+#include "root.hxx"
+#include "ftools.hxx"
+#include "xltable.hxx"
+#include "xistream.hxx"
+#include "xistyle.hxx"
+#include "queryparam.hxx"
+
+// for filter manager
+#include "excimp8.hxx"
+
+// ============================================================================
+
+const sal_uInt8 EXC_COLROW_USED = 0x01;
+const sal_uInt8 EXC_COLROW_DEFAULT = 0x02;
+const sal_uInt8 EXC_COLROW_HIDDEN = 0x04;
+const sal_uInt8 EXC_COLROW_MAN = 0x08;
+
+// ============================================================================
+
+XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maWidths( MAXCOLCOUNT, 0 ),
+ maColFlags( MAXCOLCOUNT, 0 ),
+ maHeights( MAXROWCOUNT, 0 ),
+ maRowFlags( MAXROWCOUNT, 0 ),
+ mnLastScRow( -1 ),
+ mnDefWidth( STD_COL_WIDTH ),
+ mnDefHeight( static_cast< sal_uInt16 >( STD_ROW_HEIGHT ) ),
+ mnDefRowFlags( EXC_DEFROW_DEFAULTFLAGS ),
+ mbHasStdWidthRec( false ),
+ mbHasDefHeight( false ),
+ mbDirty( true )
+{
+}
+
+XclImpColRowSettings::~XclImpColRowSettings()
+{
+}
+
+void XclImpColRowSettings::SetDefWidth( sal_uInt16 nDefWidth, bool bStdWidthRec )
+{
+ if( bStdWidthRec )
+ {
+ // STANDARDWIDTH record overrides DEFCOLWIDTH record
+ mnDefWidth = nDefWidth;
+ mbHasStdWidthRec = true;
+ }
+ else if( !mbHasStdWidthRec )
+ {
+ // use DEFCOLWIDTH record only, if no STANDARDWIDTH record exists
+ mnDefWidth = nDefWidth;
+ }
+}
+
+void XclImpColRowSettings::SetWidthRange( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nWidth )
+{
+ DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetColWidthRange - invalid column range" );
+ nScCol2 = ::std::min( nScCol2, MAXCOL );
+ if (nScCol2 == 256)
+ // In BIFF8, the column range is 0-255, and the use of 256 probably
+ // means the range should extend to the max column if the loading app
+ // support columns beyond 255.
+ nScCol2 = MAXCOL;
+
+ nScCol1 = ::std::min( nScCol1, nScCol2 );
+ ::std::fill( maWidths.begin() + nScCol1, maWidths.begin() + nScCol2 + 1, nWidth );
+ for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
+ ::set_flag( *aIt, EXC_COLROW_USED );
+}
+
+void XclImpColRowSettings::HideCol( SCCOL nScCol )
+{
+ if( ValidCol( nScCol ) )
+ ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
+}
+
+void XclImpColRowSettings::HideColRange( SCCOL nScCol1, SCCOL nScCol2 )
+{
+ DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::HideColRange - invalid column range" );
+ nScCol2 = ::std::min( nScCol2, MAXCOL );
+ nScCol1 = ::std::min( nScCol1, nScCol2 );
+ for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
+ ::set_flag( *aIt, EXC_COLROW_HIDDEN );
+}
+
+void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlags )
+{
+ mnDefHeight = nDefHeight;
+ mnDefRowFlags = nFlags;
+ if( mnDefHeight == 0 )
+ {
+ mnDefHeight = static_cast< sal_uInt16 >( STD_ROW_HEIGHT );
+ ::set_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN );
+ }
+ mbHasDefHeight = true;
+}
+
+void XclImpColRowSettings::SetHeight( SCROW nScRow, sal_uInt16 nHeight )
+{
+ if( ValidRow( nScRow ) )
+ {
+ sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
+ bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
+ maHeights[ nScRow ] = nRawHeight;
+ sal_uInt8& rnFlags = maRowFlags[ nScRow ];
+ ::set_flag( rnFlags, EXC_COLROW_USED );
+ if( !bDefHeight && (nRawHeight == 0) )
+ ::set_flag( rnFlags, EXC_COLROW_HIDDEN );
+ ::set_flag( rnFlags, EXC_COLROW_DEFAULT, bDefHeight );
+ if( nScRow > mnLastScRow )
+ mnLastScRow = nScRow;
+ }
+}
+
+void XclImpColRowSettings::SetRowSettings( SCROW nScRow, sal_uInt16 nHeight, sal_uInt16 nFlags )
+{
+ if( ValidRow( nScRow ) )
+ {
+ SetHeight( nScRow, nHeight );
+ sal_uInt8& rnFlags = maRowFlags[ nScRow ];
+ if( ::get_flag( nFlags, EXC_ROW_UNSYNCED ) )
+ ::set_flag( rnFlags, EXC_COLROW_MAN );
+ if( ::get_flag( nFlags, EXC_ROW_HIDDEN ) )
+ ::set_flag( rnFlags, EXC_COLROW_HIDDEN );
+ }
+}
+
+void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow )
+{
+ if( ValidRow( nScRow ) )
+ ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_MAN );
+}
+
+void XclImpColRowSettings::SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex )
+{
+ /* #109555# assign the default column formatting here to ensure that
+ explicit cell formatting is not overwritten. */
+ DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetDefaultXF - invalid column index" );
+ nScCol2 = ::std::min( nScCol2, MAXCOL );
+ nScCol1 = ::std::min( nScCol1, nScCol2 );
+ XclImpXFRangeBuffer& rXFRangeBuffer = GetXFRangeBuffer();
+ for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
+ rXFRangeBuffer.SetColumnDefXF( nScCol, nXFIndex );
+}
+
+void XclImpColRowSettings::Convert( SCTAB nScTab )
+{
+ if( !mbDirty )
+ return;
+
+ ScDocument& rDoc = GetDoc();
+ rDoc.IncSizeRecalcLevel( nScTab );
+
+ // column widths ----------------------------------------------------------
+
+ for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
+ {
+ sal_uInt16 nWidth = ::get_flag( maColFlags[ nScCol ], EXC_COLROW_USED ) ? maWidths[ nScCol ] : mnDefWidth;
+ /* Hidden columns: remember hidden state, but do not set hidden state
+ in document here. Needed for #i11776#, no HIDDEN flags in the
+ document, until filters and outlines are inserted. */
+ if( nWidth == 0 )
+ {
+ ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
+ nWidth = mnDefWidth;
+ }
+ rDoc.SetColWidth( nScCol, nScTab, nWidth );
+ }
+
+ // row heights ------------------------------------------------------------
+
+ // #i54252# set default row height
+ rDoc.SetRowHeightOnly( 0, MAXROW, nScTab, mnDefHeight );
+ if( ::get_flag( mnDefRowFlags, EXC_DEFROW_UNSYNCED ) )
+ // first access to row flags, do not ask for old flags
+ rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE );
+ bool bDefHideRow = ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN );
+
+ SCROW nFirstScRow = -1;
+ sal_uInt16 nLastHeight = 0;
+ for( SCROW nScRow = 0; nScRow <= mnLastScRow ; ++nScRow )
+ {
+ // get height and hidden state from cached data
+ sal_uInt8 nFlags = maRowFlags[ nScRow ];
+ sal_uInt16 nHeight = 0;
+ bool bHideRow = false;
+ if( ::get_flag( nFlags, EXC_COLROW_USED ) )
+ {
+ if( ::get_flag( nFlags, EXC_COLROW_DEFAULT ) )
+ {
+ nHeight = mnDefHeight;
+ bHideRow = bDefHideRow;
+ }
+ else
+ {
+ nHeight = maHeights[ nScRow ];
+ if( nHeight == 0 )
+ {
+ nHeight = mnDefHeight;
+ bHideRow = true;
+ }
+ }
+
+ if( ::get_flag( nFlags, EXC_COLROW_MAN ) )
+ rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_MANUALSIZE );
+ }
+ else
+ {
+ nHeight = mnDefHeight;
+ bHideRow = bDefHideRow;
+ }
+
+ /* Hidden rows: remember hidden state, but do not set hidden state in
+ document here. Needed for #i11776#, no HIDDEN flags in the document,
+ until filters and outlines are inserted. */
+ if( bHideRow )
+ ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN );
+
+ // set height range
+ if( (nLastHeight != nHeight) || (nScRow == 0) )
+ {
+ DBG_ASSERT( (nScRow == 0) || (nFirstScRow >= 0), "XclImpColRowSettings::Convert - algorithm error" );
+ if( nScRow > 0 )
+ rDoc.SetRowHeightOnly( nFirstScRow, nScRow - 1, nScTab, nLastHeight );
+
+ nFirstScRow = nScRow;
+ nLastHeight = nHeight;
+ }
+ }
+
+ // set row height of last portion
+ if( mnLastScRow >= 0 )
+ rDoc.SetRowHeightOnly( nFirstScRow, mnLastScRow, nScTab, nLastHeight );
+
+ // ------------------------------------------------------------------------
+
+ mbDirty = false;
+ rDoc.DecSizeRecalcLevel( nScTab );
+}
+
+void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
+{
+ ScDocument& rDoc = GetDoc();
+
+ // hide the columns
+ for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
+ if( ::get_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN ) )
+ rDoc.ShowCol( nScCol, nScTab, FALSE );
+
+ // #i38093# rows hidden by filter need extra flag
+ SCROW nFirstFilterScRow = SCROW_MAX;
+ SCROW nLastFilterScRow = SCROW_MAX;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ const XclImpAutoFilterData* pFilter = GetFilterManager().GetByTab( nScTab );
+ // #i70026# use IsFiltered() to set the CR_FILTERED flag for active filters only
+ if( pFilter && pFilter->IsActive() && pFilter->IsFiltered() )
+ {
+ nFirstFilterScRow = pFilter->StartRow();
+ nLastFilterScRow = pFilter->EndRow();
+ }
+ }
+
+ // hide the rows
+ for( SCROW nScRow = 0; nScRow <= mnLastScRow; ++nScRow )
+ {
+ if( ::get_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN ) )
+ {
+ // hide the row
+ rDoc.ShowRow( nScRow, nScTab, FALSE );
+ // #i38093# rows hidden by filter need extra flag
+ if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) )
+ rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true);
+ }
+ }
+
+ // #i47438# if default row format is hidden, hide remaining rows
+ if( ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN ) && (mnLastScRow < MAXROW) )
+ rDoc.ShowRows( mnLastScRow + 1, MAXROW, nScTab, FALSE );
+}
+
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
new file mode 100644
index 000000000000..458629979172
--- /dev/null
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -0,0 +1,832 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zformat.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustring.hxx>
+
+#include "cell.hxx"
+#include "dociter.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "progress.hxx"
+#include "conditio.hxx"
+#include "dpobject.hxx"
+#include "attrib.hxx"
+#include "scextopt.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "olinetab.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "patattr.hxx"
+#include "docoptio.hxx"
+#include "tabprotection.hxx"
+
+#include "excdoc.hxx"
+#include "namebuff.hxx"
+
+#include "xcl97rec.hxx"
+#include "xcl97esc.hxx"
+#include "xetable.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xepage.hxx"
+#include "xeview.hxx"
+#include "xecontent.hxx"
+#include "xeescher.hxx"
+#include "xepivot.hxx"
+#include "XclExpChangeTrack.hxx"
+
+#include <math.h>
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+
+static String lcl_GetVbaTabName( SCTAB n )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM( "__VBA__" ) );
+ aRet += String::CreateFromInt32( static_cast<sal_uInt16>(n) );
+ return aRet;
+}
+
+
+static void lcl_AddBookviews( XclExpRecordList<>& aRecList, ExcTable& self )
+{
+ aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews ) );
+ aRecList.AppendNewRecord( new XclExpWindow1( self.GetRoot() ) );
+ aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews ) );
+}
+
+static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
+{
+ ScDocument& rDoc = self.GetDoc();
+
+ aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
+ // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
+ // concurrentCalc, concurrentManualCount,
+ // forceFullCalc, fullCalcOnLoad, fullPrecision
+ aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
+ aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
+ aRecList.AppendNewRecord( new XclIteration( rDoc ) );
+ aRecList.AppendNewRecord( new XclDelta( rDoc ) );
+ aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
+ aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
+}
+
+#if 0
+// removed during rebase, because scsheetprotection02 is not yet up-stream :-(
+static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, ExcTable& self )
+{
+ aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection ) );
+ const ScDocProtection* pProtect = self.GetDoc().GetDocProtection();
+ if (pProtect && pProtect->isProtected())
+ {
+ aRecList.AppendNewRecord( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
+ aRecList.AppendNewRecord( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
+ aRecList.AppendNewRecord( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
+ }
+
+ if( self.GetBiff() == EXC_BIFF8 )
+ {
+ aRecList.AppendNewRecord( new XclExpProt4Rev );
+ aRecList.AppendNewRecord( new XclExpProt4RevPass );
+ }
+ aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
+}
+#endif
+
+static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, const XclExpRoot& rRoot, SCTAB nScTab )
+{
+ // Scenarios
+ aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) );
+ // filter
+ aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) );
+}
+
+
+ExcTable::ExcTable( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnScTab( SCTAB_GLOBAL ),
+ nExcTab( EXC_NOTAB ),
+ pTabNames( new NameBuffer( 0, 16 ) )
+{
+}
+
+
+ExcTable::ExcTable( const XclExpRoot& rRoot, SCTAB nScTab ) :
+ XclExpRoot( rRoot ),
+ mnScTab( nScTab ),
+ nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
+ pTabNames( new NameBuffer( 0, 16 ) )
+{
+}
+
+
+ExcTable::~ExcTable()
+{
+ delete pTabNames;
+}
+
+
+void ExcTable::Add( XclExpRecordBase* pRec )
+{
+ DBG_ASSERT( pRec, "-ExcTable::Add(): pRec ist NULL!" );
+ aRecList.AppendNewRecord( pRec );
+}
+
+
+void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
+{
+ InitializeGlobals();
+
+ RootData& rR = GetOldRoot();
+ ScDocument& rDoc = GetDoc();
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+
+ if ( GetBiff() <= EXC_BIFF5 )
+ Add( new ExcBofW );
+ else
+ Add( new ExcBofW8 );
+
+ SCTAB nC;
+ String aTmpString;
+ SCTAB nScTabCount = rTabInfo.GetScTabCount();
+ UINT16 nExcTabCount = rTabInfo.GetXclTabCount();
+ UINT16 nCodenames = static_cast< UINT16 >( GetExtDocOptions().GetCodeNameCount() );
+
+ SfxObjectShell* pShell = GetDocShell();
+ sal_uInt16 nWriteProtHash = pShell ? pShell->GetModifyPasswordHash() : 0;
+ bool bRecommendReadOnly = pShell && pShell->IsLoadReadonly();
+
+ if( (nWriteProtHash > 0) || bRecommendReadOnly )
+ Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) );
+
+ // TODO: correct codepage for BIFF5?
+ sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE );
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR ) );
+ Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
+ Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR ) );
+ Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND ) );
+ Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) );
+ Add( new ExcDummy_00 );
+ }
+ else
+ {
+ if( IsDocumentEncrypted() )
+ Add( new XclExpFilePass( GetRoot() ) );
+ Add( new XclExpInterfaceHdr( nCodePage ) );
+ Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
+ Add( new XclExpInterfaceEnd );
+ Add( new XclExpWriteAccess );
+ }
+
+ Add( new XclExpFileSharing( GetRoot(), nWriteProtHash, bRecommendReadOnly ) );
+ Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) );
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ Add( new XclExpBoolRecord( EXC_ID_DSF, false ) );
+ Add( new XclExpEmptyRecord( EXC_ID_XL9FILE ) );
+ rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) );
+ Add( rR.pTabId );
+ if( HasVbaStorage() )
+ {
+ Add( new XclObproj );
+ const String& rCodeName = GetExtDocOptions().GetDocSettings().maGlobCodeName;
+ if( rCodeName.Len() )
+ Add( new XclCodename( rCodeName ) );
+ }
+ }
+
+ Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT, 14 ) );
+
+ // erst Namen- und Tabellen-Eintraege aufbauen
+ String aName;
+
+ for( nC = 0 ; nC < nScTabCount ; nC++ )
+ if( rTabInfo.IsExportTab( nC ) )
+ {
+ rDoc.GetName( nC, aTmpString );
+ *pTabNames << aTmpString;
+ }
+
+ if ( GetBiff() <= EXC_BIFF5 )
+ {
+ // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
+ }
+
+ // document protection options
+ 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 XclExpProt4Rev );
+ Add( new XclExpProt4RevPass );
+ }
+
+ // document protection options
+ if( GetOutput() == EXC_OUTPUT_BINARY )
+ {
+ //lcl_AddWorkbookProtection( aRecList, *this );
+ lcl_AddBookviews( aRecList, *this );
+ }
+
+ 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 );
+ Add( new Exc1904( rDoc ) );
+ Add( new ExcDummy_041 );
+ }
+ else
+ {
+ // BIFF8
+ Add( new Exc1904( rDoc ) );
+ Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
+ Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
+ Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
+ // OOXTODO: The following /workbook/workbookPr attributes are mapped
+ // to various BIFF records that are not currently supported:
+ //
+ // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
+ // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
+ // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
+ // XML_codeName: "Calc"
+ // XML_defaultThemeVersion: ???
+ // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
+ // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
+ // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
+ // XML_publishItems: NAMEPUBLISH 893h: fPublished
+ // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
+ // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
+ // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
+ // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
+ // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
+ }
+ Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
+
+ // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
+ }
+ else
+ {
+ aRecList.AppendRecord( CreateRecord( EXC_ID_FONTLIST ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_FORMATLIST ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_XFLIST ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_PALETTE ) );
+ }
+
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ // Bundlesheet
+ for( nC = 0 ; nC < nScTabCount ; nC++ )
+ if( rTabInfo.IsExportTab( nC ) )
+ {
+ ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet( rR, nC ) );
+ aRecList.AppendRecord( xBoundsheet );
+ rBoundsheetList.AppendRecord( xBoundsheet );
+ }
+ }
+ else
+ {
+ // Pivot Cache
+ GetPivotTableManager().CreatePivotTables();
+ aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
+
+ // Change tracking
+ if( rDoc.GetChangeTrack() )
+ {
+ rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
+ Add( rR.pUserBViewList );
+ }
+
+ // Natural Language Formulas Flag
+ aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
+
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ //lcl_AddWorkbookProtection( aRecList, *this );
+ lcl_AddBookviews( aRecList, *this );
+ }
+
+ // Bundlesheet
+ aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets ) );
+ for( nC = 0 ; nC < nScTabCount ; nC++ )
+ if( rTabInfo.IsExportTab( nC ) )
+ {
+ ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
+ aRecList.AppendRecord( xBoundsheet );
+ rBoundsheetList.AppendRecord( xBoundsheet );
+ }
+ aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets ) );
+
+ for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
+ {
+ aTmpString = lcl_GetVbaTabName( nAdd );
+ ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
+ aRecList.AppendRecord( xBoundsheet );
+ rBoundsheetList.AppendRecord( xBoundsheet );
+ }
+
+ // COUNTRY - in BIFF8 in workbook globals
+ Add( new XclExpCountry( GetRoot() ) );
+ // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
+
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ lcl_AddCalcPr( aRecList, *this );
+
+ Add( new XclExpRecalcId );
+
+ // MSODRAWINGGROUP per-document data
+ aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
+ // Shared string table: SST, EXTSST
+ aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
+
+ Add( new XclExpBookExt );
+ }
+
+ Add( new ExcEof );
+}
+
+
+void ExcTable::FillAsTable( SCTAB nCodeNameIdx )
+{
+ InitializeTable( mnScTab );
+
+ RootData& rR = GetOldRoot();
+ XclBiff eBiff = GetBiff();
+ ScDocument& rDoc = GetDoc();
+
+ DBG_ASSERT( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
+ DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
+
+ // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
+ if( eBiff == EXC_BIFF8 )
+ GetObjectManager().StartSheet();
+
+ // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
+ mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
+
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ FillAsXmlTable( nCodeNameIdx );
+ return;
+ }
+
+
+ // WSBOOL needs data from page settings, create it here, add it later
+ ScfRef< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
+ bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
+
+ if( eBiff <= EXC_BIFF5 )
+ {
+ Add( new ExcBof );
+ Add( new ExcDummy_02a );
+ }
+ else
+ {
+ Add( new ExcBof8 );
+ lcl_AddCalcPr( aRecList, *this );
+ }
+
+ // GUTS (count & size of outline icons)
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
+ // DEFROWHEIGHT, created by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
+
+ // COUNTRY - in BIFF5/7 in every worksheet
+ if( eBiff <= EXC_BIFF5 )
+ Add( new XclExpCountry( GetRoot() ) );
+
+ Add( new XclExpWsbool( bFitToPages ) );
+
+ // page settings (SETUP and various other records)
+ aRecList.AppendRecord( xPageSett );
+
+ const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
+ if (pTabProtect && pTabProtect->isProtected())
+ {
+ Add( new XclExpProtection(true) );
+ Add( new XclExpBoolRecord(0x00DD, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
+ Add( new XclExpBoolRecord(0x0063, pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS)) );
+#if ENABLE_SHEET_PROTECTION
+ Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
+#endif
+ }
+
+ // local link table: EXTERNCOUNT, EXTERNSHEET
+ if( eBiff <= EXC_BIFF5 )
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+
+ if ( eBiff == EXC_BIFF8 )
+ lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
+
+ // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
+ aRecList.AppendRecord( mxCellTable );
+
+ // MERGEDCELLS record, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
+ // label ranges
+ if( eBiff == EXC_BIFF8 )
+ Add( new XclExpLabelranges( GetRoot() ) );
+ // data validation (DVAL and list of DV records), generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
+
+ if( eBiff == EXC_BIFF8 )
+ {
+ // all MSODRAWING and OBJ stuff of this sheet goes here
+ aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
+ // pivot tables
+ aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
+ }
+
+ // list of NOTE records, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_NOTE ) );
+
+ // sheet view settings: WINDOW2, SCL, PANE, SELECTION
+ aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
+
+ if( eBiff == EXC_BIFF8 )
+ {
+ // sheet protection options
+ Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
+
+ // web queries
+ Add( new XclExpWebQueryBuffer( GetRoot() ) );
+
+ // conditional formats
+ Add( new XclExpCondFormatBuffer( GetRoot() ) );
+
+ if( HasVbaStorage() )
+ if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
+ Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
+ }
+
+ // list of HLINK records, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_HLINK ) );
+
+ // change tracking
+ if( rR.pUserBViewList )
+ {
+ for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
+ {
+ Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
+ Add( new XclExpUsersViewEnd );
+ }
+ }
+
+ // EOF
+ Add( new ExcEof );
+}
+
+void ExcTable::FillAsXmlTable( SCTAB nCodeNameIdx )
+{
+ RootData& rR = GetOldRoot();
+
+ // WSBOOL needs data from page settings, create it here, add it later
+ ScfRef< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
+ bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
+
+ Add( new ExcBof8 );
+
+ Add( new XclExpWsbool( bFitToPages, mnScTab, &GetFilterManager() ) );
+
+ // GUTS (count & size of outline icons)
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
+ // DEFROWHEIGHT, created by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
+
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID3_DIMENSIONS ) );
+
+ // sheet view settings: WINDOW2, SCL, PANE, SELECTION
+ aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
+
+ // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
+ aRecList.AppendRecord( mxCellTable );
+
+ // label ranges
+ Add( new XclExpLabelranges( GetRoot() ) );
+
+ // DFF not needed in MSOOXML export
+// GetObjectManager().AddSdrPage();
+// //! close Escher group shape and ESCHER_DgContainer
+// //! opened by XclExpObjList ctor MSODRAWING
+// rR.pObjRecs->EndSheet();
+// // all MSODRAWING and OBJ stuff of this sheet goes here
+// Add( rR.pObjRecs );
+
+ // pivot tables
+ aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
+
+ // list of NOTE records, generated by the cell table
+ XclExpRecordRef xNotes = mxCellTable->CreateRecord( EXC_ID_NOTE );
+ XclExpRecordList< XclExpNote >* xNoteList = dynamic_cast< XclExpRecordList< XclExpNote >* >( xNotes.get() );
+ if( xNoteList != NULL )
+ aRecList.AppendNewRecord( new XclExpComments( mnScTab, *xNoteList ) );
+
+ // web queries
+ Add( new XclExpWebQueryBuffer( GetRoot() ) );
+
+ lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
+
+ // MERGEDCELLS record, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
+
+ // conditional formats
+ Add( new XclExpCondFormatBuffer( GetRoot() ) );
+
+ if( HasVbaStorage() )
+ if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
+ Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
+
+ // data validation (DVAL and list of DV records), generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
+
+ // list of HLINK records, generated by the cell table
+ XclExpRecordRef xHyperlinks = mxCellTable->CreateRecord( EXC_ID_HLINK );
+ XclExpHyperlinkList* xHyperlinkList = dynamic_cast<XclExpHyperlinkList*>(xHyperlinks.get());
+ if( xHyperlinkList != NULL && !xHyperlinkList->IsEmpty() )
+ {
+ aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks ) );
+ aRecList.AppendRecord( xHyperlinks );
+ aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks ) );
+ }
+
+ aRecList.AppendRecord( xPageSett );
+
+ // change tracking
+ if( rR.pUserBViewList )
+ {
+ for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
+ {
+ Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
+ Add( new XclExpUsersViewEnd );
+ }
+ }
+
+ // EOF
+ Add( new ExcEof );
+}
+
+
+void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx )
+{
+ InitializeTable( mnScTab );
+
+ if( HasVbaStorage() && (nCodeNameIdx < GetExtDocOptions().GetCodeNameCount()) )
+ {
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ Add( new ExcBof );
+ }
+ else
+ {
+ Add( new ExcBof8 );
+ Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
+ }
+ // sheet view settings: WINDOW2, SCL, PANE, SELECTION
+ aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
+ Add( new ExcEof );
+ }
+}
+
+
+void ExcTable::Write( XclExpStream& rStrm )
+{
+ SetCurrScTab( mnScTab );
+ if( mxCellTable.get() )
+ mxCellTable->Finalize();
+ aRecList.Save( rStrm );
+}
+
+
+void ExcTable::WriteXml( XclExpXmlStream& rStrm )
+{
+ if (GetTabInfo().IsExportTab( mnScTab ) )
+ {
+ // worksheet export
+ String sSheetName = XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab+1 );
+
+ sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetStreamForPath( sSheetName );
+
+ rStrm.PushStream( pWorksheet );
+
+ pWorksheet->startElement( XML_worksheet,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSEND );
+ }
+
+ SetCurrScTab( mnScTab );
+ if( mxCellTable.get() )
+ mxCellTable->Finalize();
+ aRecList.SaveXml( rStrm );
+
+ if (GetTabInfo().IsExportTab( mnScTab ) )
+ {
+ rStrm.GetCurrentStream()->endElement( XML_worksheet );
+ rStrm.PopStream();
+ }
+}
+
+
+ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ aHeader( rRoot ),
+ pExpChangeTrack( NULL )
+{
+}
+
+
+ExcDocument::~ExcDocument()
+{
+ maTableList.RemoveAllRecords(); //! for the following assertion
+ delete pExpChangeTrack;
+}
+
+
+void ExcDocument::ReadDoc( void )
+{
+ InitializeConvert();
+
+ aHeader.FillAsHeader( maBoundsheetList );
+
+ SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
+ SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
+
+ for( ; nScTab < nScTabCount; ++nScTab )
+ {
+ if( GetTabInfo().IsExportTab( nScTab ) )
+ {
+ ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
+ maTableList.AppendRecord( xTab );
+ xTab->FillAsTable( nCodeNameIdx );
+ ++nCodeNameIdx;
+ }
+ }
+ for( ; nCodeNameIdx < nCodeNameCount; ++nScTab, ++nCodeNameIdx )
+ {
+ ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
+ maTableList.AppendRecord( xTab );
+ xTab->FillAsEmptyTable( nCodeNameIdx );
+ }
+
+ if ( GetBiff() == EXC_BIFF8 )
+ {
+ // complete temporary Escher stream
+ GetObjectManager().EndDocument();
+
+ // change tracking
+ if ( GetDoc().GetChangeTrack() )
+ pExpChangeTrack = new XclExpChangeTrack( GetRoot() );
+ }
+}
+
+
+void ExcDocument::Write( SvStream& rSvStrm )
+{
+ if( !maTableList.IsEmpty() )
+ {
+ InitializeSave();
+
+ XclExpStream aXclStrm( rSvStrm, GetRoot() );
+
+ aHeader.Write( aXclStrm );
+
+ DBG_ASSERT( maTableList.GetSize() == maBoundsheetList.GetSize(),
+ "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
+
+ for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
+ {
+ // set current stream position in BOUNDSHEET record
+ ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
+ if( xBoundsheet.get() )
+ xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
+ // write the table
+ maTableList.GetRecord( nTab )->Write( aXclStrm );
+ }
+
+ // write the table stream positions into the BOUNDSHEET records
+ for( size_t nBSheet = 0, nBSheetCount = maBoundsheetList.GetSize(); nBSheet < nBSheetCount; ++nBSheet )
+ maBoundsheetList.GetRecord( nBSheet )->UpdateStreamPos( aXclStrm );
+ }
+ if( pExpChangeTrack )
+ pExpChangeTrack->Write();
+}
+
+void ExcDocument::WriteXml( SvStream& rStrm )
+{
+ if( !maTableList.IsEmpty() )
+ {
+ InitializeSave();
+
+ XclExpXmlStream aStrm( ::comphelper::getProcessServiceFactory(), rStrm, GetRoot() );
+
+ sax_fastparser::FSHelperPtr& rWorkbook = aStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_workbook,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSEND );
+ rWorkbook->singleElement( XML_fileVersion,
+ XML_appName, "Calc",
+ // OOXTODO: XML_codeName
+ // OOXTODO: XML_lastEdited
+ // OOXTODO: XML_lowestEdited
+ // OOXTODO: XML_rupBuild
+ FSEND );
+
+ aHeader.WriteXml( aStrm );
+
+ for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
+ {
+ // set current stream position in BOUNDSHEET record
+#if 0
+ ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
+ if( xBoundsheet.get() )
+ xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
+#endif
+ // write the table
+ maTableList.GetRecord( nTab )->WriteXml( aStrm );
+ }
+
+ rWorkbook->endElement( XML_workbook );
+ rWorkbook.reset();
+ aStrm.commitStorage();
+ }
+#if 0
+ if( pExpChangeTrack )
+ pExpChangeTrack->WriteXml();
+#endif
+}
+
diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx
new file mode 100644
index 000000000000..3a43a23cd624
--- /dev/null
+++ b/sc/source/filter/excel/excel.cxx
@@ -0,0 +1,304 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include <sot/storage.hxx>
+#include <sot/exchange.hxx>
+#include <tools/globname.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include "scitems.hxx"
+#include <svl/stritem.hxx>
+#include "filter.hxx"
+#include "document.hxx"
+#include "xistream.hxx"
+
+#include "scerrors.hxx"
+#include "root.hxx"
+#include "imp_op.hxx"
+#include "excimp8.hxx"
+#include "exp_op.hxx"
+
+
+FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat )
+{
+ // check the passed Calc document
+ DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
+ if( !pDocument ) return eERR_INTERN; // should not happen
+
+ /* Import all BIFF versions regardless on eFormat, needed for import of
+ external cells (file type detection returns Excel4.0). */
+ if( (eFormat != EIF_AUTO) && (eFormat != EIF_BIFF_LE4) && (eFormat != EIF_BIFF5) && (eFormat != EIF_BIFF8) )
+ {
+ DBG_ERRORFILE( "::ScImportExcel - wrong file format specification" );
+ return eERR_FORMAT;
+ }
+
+ // check the input stream from medium
+ SvStream* pMedStrm = rMedium.GetInStream();
+ DBG_ASSERT( pMedStrm, "::ScImportExcel - medium without input stream" );
+ if( !pMedStrm ) return eERR_OPEN; // should not happen
+
+#if OSL_DEBUG_LEVEL > 0
+ using namespace ::com::sun::star;
+ using namespace ::comphelper;
+
+ /* Environment variable "OOO_OOXBIFFFILTER":
+ - "1" = use new OOX filter for import;
+ - undef/other = use old sc filter for import (OOX only as file dumper). */
+ const sal_Char* pcFileName = ::getenv( "OOO_OOXBIFFFILTER" );
+ bool bUseOoxFilter = pcFileName && (*pcFileName == '1') && (*(pcFileName + 1) == 0);
+ if( SfxObjectShell* pDocShell = pDocument->GetDocumentShell() ) try
+ {
+ uno::Reference< lang::XComponent > xComponent( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+
+ uno::Sequence< beans::NamedValue > aArgSeq( 1 );
+ aArgSeq[ 0 ].Name = CREATE_OUSTRING( "UseBiffFilter" );
+ aArgSeq[ 0 ].Value <<= bUseOoxFilter;
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= getProcessServiceFactory();
+ aArgs[ 1 ] <<= aArgSeq;
+ uno::Reference< document::XImporter > xImporter( ScfApiHelper::CreateInstanceWithArgs(
+ CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelBiffFilter" ), aArgs ), uno::UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComponent );
+
+ MediaDescriptor aMediaDesc;
+ SfxItemSet* pItemSet = rMedium.GetItemSet();
+ if( pItemSet )
+ {
+ if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) )
+ aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pItem->GetValue() );
+ if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_PASSWORD ) ) )
+ aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pItem->GetValue() );
+ }
+ aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium.GetInputStream();
+ aMediaDesc[ MediaDescriptor::PROP_INTERACTIONHANDLER() ] <<= rMedium.GetInteractionHandler();
+
+ // call the filter
+ uno::Reference< document::XFilter > xFilter( xImporter, uno::UNO_QUERY_THROW );
+ bool bResult = xFilter->filter( aMediaDesc.getAsConstPropertyValueList() );
+
+ // if filter returns false, document is invalid, or dumper has disabled import -> exit here
+ if( !bResult )
+ return ERRCODE_ABORT;
+
+ // if OOX filter has been used, exit with OK code
+ if( bUseOoxFilter )
+ return eERR_OK;
+ }
+ catch( uno::Exception& )
+ {
+ if( bUseOoxFilter )
+ return ERRCODE_ABORT;
+ // else ignore exception and import the document with this filter
+ }
+#endif
+
+ SvStream* pBookStrm = 0; // The "Book"/"Workbook" stream containing main data.
+ XclBiff eBiff = EXC_BIFF_UNKNOWN; // The BIFF version of the main stream.
+
+ // try to open an OLE storage
+ SotStorageRef xRootStrg;
+ SotStorageStreamRef xStrgStrm;
+ if( SotStorage::IsStorageFile( pMedStrm ) )
+ {
+ xRootStrg = new SotStorage( pMedStrm, FALSE );
+ if( xRootStrg->GetError() )
+ xRootStrg = 0;
+ }
+
+ // try to open "Book" or "Workbook" stream in OLE storage
+ if( xRootStrg.Is() )
+ {
+ // try to open the "Book" stream
+ SotStorageStreamRef xBookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK );
+ XclBiff eBookBiff = xBookStrm.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm ) : EXC_BIFF_UNKNOWN;
+
+ // try to open the "Workbook" stream
+ SotStorageStreamRef xWorkbookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_WORKBOOK );
+ XclBiff eWorkbookBiff = xWorkbookStrm.Is() ? XclImpStream::DetectBiffVersion( *xWorkbookStrm ) : EXC_BIFF_UNKNOWN;
+
+ // decide which stream to use
+ if( (eWorkbookBiff != EXC_BIFF_UNKNOWN) && ((eBookBiff == EXC_BIFF_UNKNOWN) || (eWorkbookBiff > eBookBiff)) )
+ {
+ /* Only "Workbook" stream exists; or both streams exist,
+ and "Workbook" has higher BIFF version than "Book" stream. */
+ xStrgStrm = xWorkbookStrm;
+ eBiff = eWorkbookBiff;
+ }
+ else if( eBookBiff != EXC_BIFF_UNKNOWN )
+ {
+ /* Only "Book" stream exists; or both streams exist,
+ and "Book" has higher BIFF version than "Workbook" stream. */
+ xStrgStrm = xBookStrm;
+ eBiff = eBookBiff;
+ }
+
+ pBookStrm = xStrgStrm;
+ }
+
+ // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
+ if( !pBookStrm )
+ {
+ eBiff = XclImpStream::DetectBiffVersion( *pMedStrm );
+ if( eBiff != EXC_BIFF_UNKNOWN )
+ pBookStrm = pMedStrm;
+ }
+
+ // try to import the file
+ FltError eRet = eERR_UNKN_BIFF;
+ if( pBookStrm )
+ {
+ pBookStrm->SetBufferSize( 0x8000 ); // still needed?
+
+ XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
+ ::std::auto_ptr< ImportExcel > xFilter;
+ switch( eBiff )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
+ break;
+ case EXC_BIFF8:
+ xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
+ }
+
+ return eRet;
+}
+
+
+static FltError lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
+ SvStream* pMedStrm, BOOL bBiff8, CharSet eNach )
+{
+ // try to open an OLE storage
+ SotStorageRef xRootStrg = new SotStorage( pMedStrm, FALSE );
+ if( xRootStrg->GetError() ) return eERR_OPEN;
+
+ // create BIFF dependent strings
+ String aStrmName, aClipName, aClassName;
+ if( bBiff8 )
+ {
+ aStrmName = EXC_STREAM_WORKBOOK;
+ aClipName = CREATE_STRING( "Biff8" );
+ aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
+ }
+ else
+ {
+ aStrmName = EXC_STREAM_BOOK;
+ aClipName = CREATE_STRING( "Biff5" );
+ aClassName = CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
+ }
+
+ // open the "Book"/"Workbook" stream
+ SotStorageStreamRef xStrgStrm = ScfTools::OpenStorageStreamWrite( xRootStrg, aStrmName );
+ if( !xStrgStrm.Is() || xStrgStrm->GetError() ) return eERR_OPEN;
+
+ xStrgStrm->SetBufferSize( 0x8000 ); // still needed?
+
+ FltError eRet = eERR_UNKN_BIFF;
+ XclExpRootData aExpData( bBiff8 ? EXC_BIFF8 : EXC_BIFF5, rMedium, xRootStrg, *pDocument, eNach );
+ if ( bBiff8 )
+ {
+ ExportBiff8 aFilter( aExpData, *xStrgStrm );
+ eRet = aFilter.Write();
+ }
+ else
+ {
+ ExportBiff5 aFilter( aExpData, *xStrgStrm );
+ eRet = aFilter.Write();
+ }
+
+ if( eRet == eERR_RNGOVRFLW )
+ eRet = SCWARN_EXPORT_MAXROW;
+
+ SvGlobalName aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
+ sal_uInt32 nClip = SotExchange::RegisterFormatName( aClipName );
+ xRootStrg->SetClass( aGlobName, nClip, aClassName );
+
+ xStrgStrm->Commit();
+ xRootStrg->Commit();
+
+ return eRet;
+}
+
+static FltError lcl_ExportExcel2007Xml( SfxMedium& rMedium, ScDocument *pDocument,
+ SvStream* pMedStrm, CharSet eNach )
+{
+ SotStorageRef xRootStrg = (SotStorage*) 0;
+
+ XclExpRootData aExpData( EXC_BIFF8, rMedium, xRootStrg, *pDocument, eNach );
+ aExpData.meOutput = EXC_OUTPUT_XML_2007;
+
+ ExportXml2007 aFilter( aExpData, *pMedStrm );
+
+ FltError eRet = aFilter.Write();
+
+ return eRet;
+}
+
+FltError ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
+ ExportFormatExcel eFormat, CharSet eNach )
+{
+ if( eFormat != ExpBiff5 && eFormat != ExpBiff8 && eFormat != Exp2007Xml )
+ return eERR_NI;
+
+ // check the passed Calc document
+ DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
+ if( !pDocument ) return eERR_INTERN; // should not happen
+
+ // check the output stream from medium
+ SvStream* pMedStrm = rMedium.GetOutStream();
+ DBG_ASSERT( pMedStrm, "::ScExportExcel5 - medium without output stream" );
+ if( !pMedStrm ) return eERR_OPEN; // should not happen
+
+ FltError eRet = eERR_UNKN_BIFF;
+ if( eFormat == ExpBiff5 || eFormat == ExpBiff8 )
+ eRet = lcl_ExportExcelBiff( rMedium, pDocument, pMedStrm, eFormat == ExpBiff8, eNach );
+ else if( eFormat == Exp2007Xml )
+ eRet = lcl_ExportExcel2007Xml( rMedium, pDocument, pMedStrm, eNach );
+
+ return eRet;
+}
+
+
+
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
new file mode 100644
index 000000000000..0652363e8822
--- /dev/null
+++ b/sc/source/filter/excel/excform.cxx
@@ -0,0 +1,2013 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "excform.hxx"
+#include <osl/endian.h>
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "global.hxx"
+#include "formula/errorcodes.hxx"
+
+#include "imp_op.hxx"
+#include "root.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+
+using ::std::vector;
+
+const UINT16 ExcelToSc::nRowMask = 0x3FFF;
+const UINT16 ExcelToSc::nLastInd = 399;
+
+
+
+
+void ImportExcel::Formula25()
+{
+ XclAddress aXclPos;
+ UINT16 nXF = 0, nFormLen;
+ double fCurVal;
+ BYTE nAttr0, nFlag0;
+ BOOL bShrFmla;
+
+ aIn >> aXclPos;
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// BIFF2
+ BYTE nDummy;
+
+ aIn.Ignore( 3 );
+
+ aIn >> fCurVal;
+ aIn.Ignore( 1 );
+ aIn >> nDummy;
+ nFormLen = nDummy;
+ bShrFmla = FALSE;
+ nAttr0 = 0x01; // Always calculate
+ }
+ else
+ {// BIFF5
+ aIn >> nXF >> fCurVal >> nFlag0;
+ aIn.Ignore( 5 );
+
+ aIn >> nFormLen;
+
+ bShrFmla = nFlag0 & 0x08; // shared or not shared
+ }
+
+ nLastXF = nXF;
+
+ Formula( aXclPos, nXF, nFormLen, fCurVal, bShrFmla );
+}
+
+
+void ImportExcel::Formula3()
+{
+ Formula4();
+}
+
+
+void ImportExcel::Formula4()
+{
+ XclAddress aXclPos;
+ UINT16 nXF, nFormLen;
+ double fCurVal;
+ BYTE nFlag0;
+
+ aIn >> aXclPos >> nXF >> fCurVal >> nFlag0;
+ aIn.Ignore( 1 );
+ aIn >> nFormLen;
+
+ nLastXF = nXF;
+
+ Formula( aXclPos, nXF, nFormLen, fCurVal, FALSE );
+}
+
+
+void ImportExcel::Formula( const XclAddress& rXclPos,
+ UINT16 nXF, UINT16 nFormLen, double& rCurVal, BOOL bShrFmla )
+{
+ ConvErr eErr = ConvOK;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis = 0;
+ BOOL bConvert;
+
+ pFormConv->Reset( aScPos );
+
+ if( bShrFmla )
+ bConvert = !pFormConv->GetShrFmla( pErgebnis, maStrm, nFormLen );
+ else
+ bConvert = TRUE;
+
+ if( bConvert )
+ eErr = pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ ScFormulaCell* pZelle = NULL;
+
+ if( pErgebnis )
+ {
+ pZelle = new ScFormulaCell( pD, aScPos, pErgebnis );
+ pD->PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pZelle, (BOOL)TRUE );
+ }
+ else
+ {
+ CellType eCellType;
+ ScBaseCell* pBaseCell;
+ pD->GetCellType( aScPos.Col(), aScPos.Row(), aScPos.Tab(), eCellType );
+ if( eCellType == CELLTYPE_FORMULA )
+ {
+ pD->GetCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pBaseCell );
+ pZelle = ( ScFormulaCell* ) pBaseCell;
+ if( pZelle )
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+ }
+ }
+
+ if( pZelle )
+ {
+ if( eErr != ConvOK )
+ ExcelToSc::SetError( *pZelle, eErr );
+#if 0
+ else
+ ExcelToSc::SetCurVal( *pZelle, rCurVal );
+#else
+ (void)rCurVal;
+#endif
+ }
+
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ }
+}
+
+
+
+
+ExcelToSc::ExcelToSc( const XclImpRoot& rRoot ) :
+ ExcelConverterBase( 512 ),
+ XclImpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() )
+{
+}
+
+ExcelToSc::~ExcelToSc()
+{
+}
+
+void ExcelToSc::GetDummy( const ScTokenArray*& pErgebnis )
+{
+ aPool.Store( CREATE_STRING( "Dummy()" ) );
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+}
+
+
+// if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
+// otherwise it will seek to the first byte after the additional content (eg
+// inline arrays) following <nFormulaLen>
+ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
+{
+ RootData& rR = GetOldRoot();
+ BYTE nOp, nLen, nByte;
+ UINT16 nUINT16;
+ INT16 nINT16;
+ double fDouble;
+ String aString;
+ BOOL bError = FALSE;
+ BOOL bArrayFormula = FALSE;
+ TokenId nMerk0;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ ExtensionTypeVec aExtensions;
+
+ bExternName = FALSE;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ {
+ aPool.Store( CREATE_STRING( "-/-" ) );
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ return ConvOK;
+ }
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ nUINT16 = 3;
+
+ if( meBiff != EXC_BIFF2 )
+ nUINT16++;
+
+ aIn.Ignore( nUINT16 );
+
+ bArrayFormula = TRUE;
+ break;
+ case 0x03: // Addition [312 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocAdd << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x04: // Subtraction [313 264]
+ // SECOMD-TOP minus TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocSub << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x05: // Multiplication [313 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocMul << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x06: // Division [313 264]
+ // divide TOP by SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocDiv << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x07: // Exponetiation [313 265]
+ // raise SECOND-TOP to power of TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocPow << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x08: // Concatenation [313 265]
+ // append TOP to SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocAmpersand << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x09: // Less Than [313 265]
+ // SECOND-TOP < TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLess << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0A: // Less Than or Equal [313 265]
+ // SECOND-TOP <= TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLessEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0B: // Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0C: // Greater Than or Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreaterEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0D: // Greater Than [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreater << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0E: // Not Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocNotEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0F: // Intersection [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocIntersect << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x10: // Union [314 265]
+ // ocSep behelfsweise statt 'ocUnion'
+ aStack >> nMerk0;
+//#100928# aPool << ocOpen << aStack << ocSep << nMerk0 << ocClose;
+ aPool << aStack << ocSep << nMerk0;
+ // doesn't fit exactly, but is more Excel-like
+ aPool >> aStack;
+ break;
+ case 0x11: // Range [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocRange << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x12: // Unary Plus [312 264]
+ aPool << ocAdd << aStack;
+ aPool >> aStack;
+ break;
+ case 0x13: // Unary Minus [312 264]
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+ case 0x14: // Percent Sign [312 264]
+ aPool << aStack << ocPercentSign;
+ aPool >> aStack;
+ break;
+ case 0x15: // Parenthesis [326 278]
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x16: // Missing Argument [314 266]
+ aPool << ocMissing;
+ aPool >> aStack;
+ GetTracer().TraceFormulaMissingArg();
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen;
+ aString = aIn.ReadRawByteString( nLen );
+
+ aStack << aPool.Store( aString );
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ aIn >> nOpt;
+
+ if( meBiff == EXC_BIFF2 )
+ {
+ nData = aIn.ReaduInt8();
+ nFakt = 1;
+ }
+ else
+ {
+ aIn >> nData;
+ nFakt = 2;
+ }
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ else if( nOpt & 0x10 ) // AttrSum
+ DoMulArgs( ocSum, 1 );
+ }
+ break;
+ case 0x1A: // External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 7 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 10 ); break;
+ case EXC_BIFF5:
+ DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
+ default:
+ DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1B: // End External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 3 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 4 ); break;
+ case EXC_BIFF5:
+ DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
+ default:
+ DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ {
+ aIn >> nByte;
+#if 0 // erAck
+ aPool.StoreError( XclTools::GetScErrorCode( nByte ) );
+#else
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+#endif
+ aPool >> aStack;
+ }
+ break;
+ case 0x1D: // Boolean [315 266]
+ aIn >> nByte;
+ if( nByte == 0 )
+ aPool << ocFalse << ocOpen << ocClose;
+ else
+ aPool << ocTrue << ocOpen << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn >> nUINT16;
+ aStack << aPool.Store( ( double ) nUINT16 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn >> fDouble;
+ aStack << aPool.Store( fDouble );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn >> nByte >> nUINT16;
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 );
+ if( bAllowArrays )
+ {
+ aStack << aPool.StoreMatrix();
+ aExtensions.push_back( EXTENSION_ARRAY );
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ {
+ sal_uInt16 nXclFunc;
+ if( meBiff <= EXC_BIFF3 )
+ nXclFunc = aIn.ReaduInt8();
+ else
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount, pFuncInfo->mnMinParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ {
+ sal_uInt16 nXclFunc;
+ sal_uInt8 nParamCount;
+ aIn >> nParamCount;
+ nParamCount &= 0x7F;
+ if( meBiff <= EXC_BIFF3 )
+ nXclFunc = aIn.ReaduInt8();
+ else
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ {
+ aIn >> nUINT16;
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 5 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 8 ); break;
+ case EXC_BIFF5: aIn.Ignore( 12 ); break;
+ default:
+ DBG_ERROR(
+ "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ const XclImpName* pName = GetNameManager().GetName( nUINT16 );
+ if(pName && !pName->GetScRangeData())
+ aStack << aPool.Store( ocMacro, pName->GetXclName() );
+ else
+ aStack << aPool.Store( nUINT16 );
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ aIn >> nUINT16 >> nByte;
+ aSRD.nCol = static_cast<SCsCOL>(nByte);
+ aSRD.nRow = nUINT16 & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( TRUE );
+ aSRD.SetRowDeleted( TRUE );
+ }
+
+ aStack << aPool.Store( aSRD );
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ {
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+ ScSingleRefData& rSRef1 = aCRD.Ref1;
+ ScSingleRefData& rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( TRUE );
+ rSRef2.SetTabRel( TRUE );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ // no information which part is deleted, set all
+ rSRef1.SetColDeleted( TRUE );
+ rSRef1.SetRowDeleted( TRUE );
+ rSRef2.SetColDeleted( TRUE );
+ rSRef2.SetRowDeleted( TRUE );
+ }
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ aExtensions.push_back( EXTENSION_MEMAREA );
+ // fall through
+
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 4 : 6 );
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( TRUE );
+ aCRD.Ref2.SetTabRel( TRUE );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 1 : 2 );
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aString.AssignAscii( "COMM_EQU_FUNC" );
+ aIn >> nByte;
+ aString += String::CreateFromInt32( nByte );
+ aIn >> nByte;
+ aStack << aPool.Store( aString );
+ DoMulArgs( ocPush, nByte + 1 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ aIn >> nINT16;
+ aIn.Ignore( 8 );
+ aIn >> nUINT16;
+ if( nINT16 >= 0 )
+ {
+ const ExtName* pExtName = rR.pExtNameBuff->GetNameByIndex( nINT16, nUINT16 );
+ if( pExtName && pExtName->IsDDE() &&
+ rR.pExtSheetBuff->IsLink( ( UINT16 ) nINT16 ) )
+ {
+ String aAppl, aExtDoc;
+ TokenId nPar1, nPar2;
+
+ rR.pExtSheetBuff->GetLink( ( UINT16 ) nINT16 , aAppl, aExtDoc );
+ nPar1 = aPool.Store( aAppl );
+ nPar2 = aPool.Store( aExtDoc );
+ nMerk0 = aPool.Store( pExtName->aName );
+ aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
+ << nMerk0 << ocClose;
+
+ GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT );
+ }
+ else
+ aPool << ocBad;
+
+ aPool >> aStack;
+ }
+ else
+ aStack << aPool.Store( nUINT16 );
+ aIn.Ignore( 12 );
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ {
+ UINT16 nTabFirst, nTabLast, nRow;
+ INT16 nExtSheet;
+ BYTE nCol;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
+
+ if( nExtSheet >= 0 )
+ { // von extern
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer SingleRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ { // in aktuellem Workbook
+ aSRD.nTab = static_cast<SCTAB>(nTabFirst);
+ aSRD.SetFlag3D( TRUE );
+ aSRD.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( TRUE );
+ aSRD.SetRowDeleted( TRUE );
+ }
+ if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
+ aSRD.SetTabDeleted( TRUE );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
+ aCRD.Ref2.SetTabDeleted( !ValidTab(static_cast<SCTAB>(nTabLast)) );
+ aStack << aPool.Store( aCRD );
+ }
+ else
+ aStack << aPool.Store( aSRD );
+ }
+ }
+
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ {
+ UINT16 nTabFirst, nTabLast, nRowFirst, nRowLast;
+ INT16 nExtSheet;
+ BYTE nColFirst, nColLast;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
+ >> nColFirst >> nColLast;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer CompleteRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ // erster Teil des Bereichs
+ ScSingleRefData& rR1 = aCRD.Ref1;
+ ScSingleRefData& rR2 = aCRD.Ref2;
+
+ rR1.nTab = static_cast<SCTAB>(nTabFirst);
+ rR2.nTab = static_cast<SCTAB>(nTabLast);
+ rR1.SetFlag3D( TRUE );
+ rR1.SetTabRel( FALSE );
+ rR2.SetFlag3D( nTabFirst != nTabLast );
+ rR2.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ // no information which part is deleted, set all
+ rR1.SetColDeleted( TRUE );
+ rR1.SetRowDeleted( TRUE );
+ rR2.SetColDeleted( TRUE );
+ rR2.SetRowDeleted( TRUE );
+ }
+ if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
+ rR1.SetTabDeleted( TRUE );
+ if ( !ValidTab(static_cast<SCTAB>(nTabLast)) )
+ rR2.SetTabDeleted( TRUE );
+
+ aStack << aPool.Store( aCRD );
+ }//ENDE in aktuellem Workbook
+ }
+ break;
+ default: bError = TRUE;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( aIn.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else if( bExternName )
+ {
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrExternal;
+ }
+ else if( bArrayFormula )
+ {
+ pErgebnis = NULL;
+ eRet = ConvOK;
+ }
+ else
+ {
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ aIn.Seek( nEndPos );
+
+ if( eRet == ConvOK )
+ ReadExtensions( aExtensions, aIn );
+
+ return eRet;
+}
+
+
+// stream seeks to first byte after <nFormulaLen>
+ConvErr ExcelToSc::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen, const FORMULA_TYPE eFT )
+{
+ RootData& rR = GetOldRoot();
+ BYTE nOp, nLen;
+ sal_Size nIgnore;
+ UINT16 nUINT16;
+ UINT8 nByte;
+ BOOL bError = FALSE;
+ BOOL bArrayFormula = FALSE;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ aCRD.Ref1.nTab = aCRD.Ref2.nTab = aEingPos.Tab();
+
+ bExternName = FALSE;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ return ConvOK;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+ nIgnore = 0;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
+ bArrayFormula = TRUE;
+ break;
+ case 0x02: // Data Table [325 277]
+ nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
+ break;
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen;
+ nIgnore = nLen;
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ aIn >> nOpt;
+
+ if( meBiff == EXC_BIFF2 )
+ {
+ nData = aIn.ReaduInt8();
+ nFakt = 1;
+ }
+ else
+ {
+ aIn >> nData;
+ nFakt = 2;
+ }
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ }
+ break;
+ case 0x1A: // External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 7; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 10; break;
+ case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
+ default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1B: // End External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 3; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 4; break;
+ case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
+ default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nIgnore = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ nIgnore = 2;
+ break;
+ case 0x1F: // Number [315 266]
+ nIgnore = 8;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nIgnore = (meBiff == EXC_BIFF2) ? 6 : 7;
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ nIgnore = (meBiff <= EXC_BIFF3) ? 1 : 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ nIgnore = (meBiff <= EXC_BIFF3) ? 2 : 3;
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 7; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 10; break;
+ case EXC_BIFF5: nIgnore = 14; break;
+ default: DBG_ERROR( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ aIn >> nUINT16 >> nByte;
+ aSRD.nCol = static_cast<SCsCOL>(nByte);
+ aSRD.nRow = nUINT16 & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
+
+ rRangeList.Append( aSRD );
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ {
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( TRUE );
+ rSRef2.SetTabRel( TRUE );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ nIgnore = (meBiff == EXC_BIFF2) ? 4 : 6;
+ break;
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nIgnore = 3;
+ break;
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nIgnore = 6;
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
+
+ rRangeList.Append( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( TRUE );
+ aCRD.Ref2.SetTabRel( TRUE );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ nIgnore = (meBiff == EXC_BIFF2) ? 1 : 2;
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nIgnore = 2;
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nIgnore = 24;
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ {
+ UINT16 nTabFirst, nTabLast, nRow;
+ INT16 nExtSheet;
+ BYTE nCol;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer SingleRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ BOOL b3D = ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName;
+ aSRD.nTab = static_cast<SCTAB>(nTabFirst);
+ aSRD.SetFlag3D( b3D );
+ aSRD.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aSRD;
+ aCRD.Ref2.nCol = aSRD.nCol;
+ aCRD.Ref2.nRow = aSRD.nRow;
+ aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
+ b3D = ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() );
+ aCRD.Ref2.SetFlag3D( b3D );
+ aCRD.Ref2.SetTabRel( FALSE );
+ rRangeList.Append( aCRD );
+ }
+ else
+ rRangeList.Append( aSRD );
+ }
+ }
+
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ {
+ UINT16 nTabFirst, nTabLast, nRowFirst, nRowLast;
+ INT16 nExtSheet;
+ BYTE nColFirst, nColLast;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
+ >> nColFirst >> nColLast;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer CompleteRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ // erster Teil des Bereichs
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+ rR1.nTab = static_cast<SCTAB>(nTabFirst);
+ rR2.nTab = static_cast<SCTAB>(nTabLast);
+ rR1.SetFlag3D( ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName );
+ rR1.SetTabRel( FALSE );
+ rR2.SetFlag3D( ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() ) || bRangeName );
+ rR2.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }//ENDE in aktuellem Workbook
+ }
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ nIgnore = 17;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nIgnore = 20;
+ break;
+ default: bError = TRUE;
+ }
+ bError |= !aIn.IsValid();
+
+ aIn.Ignore( nIgnore );
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ eRet = ConvErrNi;
+ else if( aIn.GetRecPos() != nEndPos )
+ eRet = ConvErrCount;
+ else if( bExternName )
+ eRet = ConvErrExternal;
+ else if( bArrayFormula )
+ eRet = ConvOK;
+ else
+ eRet = ConvOK;
+
+ aIn.Seek( nEndPos );
+ return eRet;
+}
+
+ConvErr ExcelToSc::ConvertExternName( const ScTokenArray*& /*rpArray*/, XclImpStream& /*rStrm*/, sal_Size /*nFormulaLen*/,
+ const String& /*rUrl*/, const vector<String>& /*rTabNames*/ )
+{
+ // not implemented ...
+ return ConvErrNi;
+}
+
+BOOL ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF5 );
+ if( GetBiff() != EXC_BIFF5 )
+ return FALSE;
+
+ sal_uInt8 nOp;
+ sal_uInt16 nRow1, nRow2;
+ sal_uInt8 nCol1, nCol2;
+ SCTAB nTab1, nTab2;
+ sal_uInt16 nTabFirst, nTabLast;
+ sal_Int16 nRefIdx;
+
+ sal_Size nSeek;
+ sal_Size nEndPos = rStrm.GetRecPos() + nLen;
+
+ while( rStrm.IsValid() && (rStrm.GetRecPos() < nEndPos) )
+ {
+ rStrm >> nOp;
+ nSeek = 0;
+
+ switch( nOp )
+ {
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ rStrm >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ // Area Reference Within a Shared Formula[ 274]
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nTabFirst >> nTabLast >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+
+ goto _3d_common;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nTabFirst >> nTabLast >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ _3d_common:
+ nTab1 = static_cast< SCTAB >( nTabFirst );
+ nTab2 = static_cast< SCTAB >( nTabLast );
+
+ // #122885# skip references to deleted sheets
+ if( (nRefIdx >= 0) || !ValidTab( nTab1 ) || (nTab1 != nTab2) )
+ break;
+
+ goto _common;
+ _common:
+ // do not check abs/rel flags, linked controls have set them!
+// if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
+ {
+ ScRange aScRange;
+ nRow1 &= 0x3FFF;
+ nRow2 &= 0x3FFF;
+ if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
+ rRangeList.Append( aScRange );
+ }
+ break;
+
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nSeek = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nSeek = 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nSeek = 3;
+ break;
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ nSeek = 4;
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nSeek = 6;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nSeek = 7;
+ break;
+ case 0x1F: // Number [315 266]
+ nSeek = 8;
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ nSeek = 14;
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ nSeek = 17;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nSeek = 20;
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nSeek = 24;
+ break;
+ case 0x17: // String Constant [314 266]
+ nSeek = rStrm.ReaduInt8();
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ BYTE nOpt;
+ UINT16 nData;
+ rStrm >> nOpt >> nData;
+ if( nOpt & 0x04 )
+ nSeek = nData * 2 + 2;
+ }
+ break;
+ }
+
+ rStrm.Ignore( nSeek );
+ }
+ rStrm.Seek( nEndPos );
+
+ return rRangeList.Count() != 0;
+}
+
+void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz, sal_uInt8 nMinParamCount )
+{
+ TokenId eParam[ 256 ];
+ INT32 nLauf;
+
+ if( eId == ocCeil || eId == ocFloor )
+ {
+ aStack << aPool.Store( 1.0 ); // default, da in Excel nicht vorhanden
+ nAnz++;
+ }
+
+ for( nLauf = 0; aStack.HasMoreTokens() && (nLauf < nAnz); nLauf++ )
+ aStack >> eParam[ nLauf ];
+ // #i70925# reduce parameter count, if no more tokens available on token stack
+ if( nLauf < nAnz )
+ nAnz = static_cast< sal_uInt8 >( nLauf );
+
+ if( nAnz > 0 && eId == ocExternal )
+ {
+ TokenId n = eParam[ nAnz - 1 ];
+//##### GRUETZE FUER BASIC-FUNCS RICHTEN!
+ if( const String* pExt = aPool.GetExternal( n ) )
+ {
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclMacroName( *pExt ) )
+ aPool << pFuncInfo->meOpCode;
+ else
+ aPool << n;
+ nAnz--;
+ }
+ else
+ aPool << eId;
+ }
+ else
+ aPool << eId;
+
+ aPool << ocOpen;
+
+ if( nAnz > 0 )
+ {
+ // attention: 0 = last parameter, nAnz-1 = first parameter
+ INT16 nNull = -1; // skip this parameter
+ INT16 nSkipEnd = -1; // skip all parameters <= nSkipEnd
+
+ INT16 nLast = nAnz - 1;
+
+ // Funktionen, bei denen Parameter wegfallen muessen
+ if( eId == ocPercentrank && nAnz == 3 )
+ nSkipEnd = 0; // letzten Parameter bei Bedarf weglassen
+
+ // Joost-Spezialfaelle
+ else if( eId == ocIf )
+ {
+ UINT16 nNullParam = 0;
+ for( nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ {
+ if( aPool.IsSingleOp( eParam[ nLauf ], ocMissing ) )
+ {
+ if( !nNullParam )
+ nNullParam = (UINT16) aPool.Store( ( double ) 0.0 );
+ eParam[ nLauf ] = nNullParam;
+ }
+ }
+ }
+
+ // FIXME: ideally we'd want to import all missing args, but this
+ // conflicts with lots of fn's understanding of nParams - we need
+ // a function table, and pre-call argument normalisation 1st.
+ INT16 nLastRemovable = nLast - nMinParamCount;
+
+ // #84453# skip missing parameters at end of parameter list
+ while( nSkipEnd < nLastRemovable &&
+ aPool.IsSingleOp( eParam[ nSkipEnd + 1 ], ocMissing ) )
+ nSkipEnd++;
+
+// fprintf (stderr, "Fn %d nSkipEnd %d nLast %d nMinParamCnt %d %d\n",
+// eId, nSkipEnd, nLast, nMinParamCount, nLastRemovable);
+
+ // [Parameter{;Parameter}]
+ if( nLast > nSkipEnd )
+ {
+ aPool << eParam[ nLast ];
+ for( nLauf = nLast - 1 ; nLauf > nSkipEnd ; nLauf-- )
+ {
+ if( nLauf != nNull )
+ aPool << ocSep << eParam[ nLauf ];
+ }
+ }
+ }
+ aPool << ocClose;
+
+ aPool >> aStack;
+}
+
+
+void ExcelToSc::ExcRelToScRel( UINT16 nRow, UINT8 nCol, ScSingleRefData &rSRD, const BOOL bName )
+{
+ if( bName )
+ {
+ // C O L
+ if( nRow & 0x4000 )
+ {// rel Col
+ rSRD.SetColRel( TRUE );
+ rSRD.nRelCol = static_cast<SCsCOL>(static_cast<INT8>(nCol));
+ }
+ else
+ {// abs Col
+ rSRD.SetColRel( FALSE );
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+ }
+
+ // R O W
+ if( nRow & 0x8000 )
+ {// rel Row
+ rSRD.SetRowRel( TRUE );
+ if( nRow & 0x2000 ) // Bit 13 gesetzt?
+ // -> Row negativ
+ rSRD.nRelRow = static_cast<SCsROW>(static_cast<INT16>(nRow | 0xC000));
+ else
+ // -> Row positiv
+ rSRD.nRelRow = static_cast<SCsROW>(nRow & nRowMask);
+ }
+ else
+ {// abs Row
+ rSRD.SetRowRel( FALSE );
+ rSRD.nRow = static_cast<SCROW>(nRow & nRowMask);
+ }
+
+ // T A B
+ // #67965# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab();
+ }
+ else
+ {
+ // C O L
+ rSRD.SetColRel( ( nRow & 0x4000 ) > 0 );
+ rSRD.nCol = static_cast<SCsCOL>(nCol);
+
+ // R O W
+ rSRD.SetRowRel( ( nRow & 0x8000 ) > 0 );
+ rSRD.nRow = static_cast<SCsROW>(nRow & nRowMask);
+
+ if ( rSRD.IsColRel() )
+ rSRD.nRelCol = rSRD.nCol - aEingPos.Col();
+ if ( rSRD.IsRowRel() )
+ rSRD.nRelRow = rSRD.nRow - aEingPos.Row();
+
+ // T A B
+ // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
+ }
+}
+
+
+const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
+{
+ UINT16 nError;
+ aPool.Reset();
+ aStack.Reset();
+
+ DefTokenId eOc;
+
+ switch( eType )
+ {
+ case xlErrNull: eOc = ocStop; nError = errNoCode; break;
+ case xlErrDiv0: eOc = ocStop; nError = errDivisionByZero; break;
+ case xlErrValue: eOc = ocStop; nError = errNoValue; break;
+ case xlErrRef: eOc = ocStop; nError = errNoRef; break;
+ case xlErrName: eOc = ocStop; nError = errNoName; break;
+ case xlErrNum: eOc = ocStop; nError = errIllegalFPOperation; break;
+ case xlErrNA: eOc = ocNotAvail; nError = NOTAVAILABLE; break;
+ case xlErrTrue: eOc = ocTrue; nError = 0; break;
+ case xlErrFalse: eOc = ocFalse; nError = 0; break;
+ case xlErrUnknown: eOc = ocStop; nError = errUnknownState; break;
+ default:
+ DBG_ERROR( "ExcelToSc::GetBoolErr - wrong enum!" );
+ eOc = ocNoName;
+ nError = errUnknownState;
+ }
+
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+
+ aPool >> aStack;
+
+ const ScTokenArray* pErgebnis = aPool[ aStack.Get() ];
+ if( nError )
+ ( ( ScTokenArray* ) pErgebnis )->SetCodeError( nError );
+
+ ( ( ScTokenArray* ) pErgebnis )->SetRecalcModeNormal();
+
+ return pErgebnis;
+}
+
+
+// if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
+// else stream pointer stays unchanged
+BOOL ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen )
+{
+ BYTE nOp;
+ BOOL bRet = TRUE;
+
+ if( nFormulaLen == 0 )
+ bRet = FALSE;
+ else
+ {
+ aIn.PushPosition();
+
+ aIn >> nOp;
+
+ if( nOp == 0x01 ) // Shared Formula [ 277]
+ {
+ UINT16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aStack << aPool.Store( GetOldRoot().pShrfmlaBuff->Find(
+ ScAddress( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab() ) ) );
+
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ aIn.PopPosition();
+ }
+
+ if( bRet )
+ {
+ aIn.Ignore( nFormulaLen );
+ rpErgebnis = aPool[ aStack.Get() ];
+ }
+ else
+ rpErgebnis = NULL;
+
+ return bRet;
+}
+
+
+#if 0
+BOOL ExcelToSc::SetCurVal( ScFormulaCell &rCell, double &rfCurVal )
+{
+ UINT16 nInd;
+ BYTE nType;
+ BYTE nVal;
+ BOOL bString = FALSE;
+
+#ifdef OSL_BIGENDIAN
+ // Code fuer alle anstaendigen Prozessoren
+ nType = *( ( ( BYTE * ) &rfCurVal ) + 7 );
+ nVal = *( ( ( BYTE * ) &rfCurVal ) + 5 );
+ nInd = *( ( UINT16 * ) &rfCurVal );
+#else
+ // fuer Schund-Prozessoren
+ nType = *( ( BYTE * ) &rfCurVal );
+ nVal = *( ( ( BYTE * ) &rfCurVal ) + 2 );
+ nInd = *( ( ( UINT16 * ) &rfCurVal ) + 3 );
+#endif
+
+ if( ( UINT16 ) ~nInd )
+ // Wert ist Float
+ rCell.SetHybridDouble( rfCurVal );
+ else
+ {
+ switch( nType )
+ {
+ case 0: // String
+ bString = TRUE;
+ break;
+ case 1: // Bool
+ if( nVal )
+ rfCurVal = 1.0;
+ else
+ rfCurVal = 0.0;
+ rCell.SetHybridDouble( rfCurVal );
+ break;
+ case 2: // Error
+ rCell.SetErrCode( XclTools::GetScErrorCode( nVal ) );
+ break;
+ }
+ }
+
+ return bString;
+}
+#endif
+
+
+void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr )
+{
+ UINT16 nInd;
+
+ switch( eErr )
+ {
+ case ConvErrNi: nInd = errUnknownToken; break;
+ case ConvErrNoMem: nInd = errCodeOverflow; break;
+ case ConvErrExternal: nInd = errNoName; break;
+ case ConvErrCount: nInd = errCodeOverflow; break;
+ default: nInd = errNoCode; // hier fiel mir nichts
+ // Besseres ein...
+ }
+
+ rCell.SetErrCode( nInd );
+}
+
+
+void ExcelToSc::SetComplCol( ScComplexRefData &rCRD )
+{
+ ScSingleRefData &rSRD = rCRD.Ref2;
+ if( rSRD.IsColRel() )
+ rSRD.nRelCol = MAXCOL - aEingPos.Col();
+ else
+ rSRD.nCol = MAXCOL;
+}
+
+
+void ExcelToSc::SetComplRow( ScComplexRefData &rCRD )
+{
+ ScSingleRefData &rSRD = rCRD.Ref2;
+ if( rSRD.IsRowRel() )
+ rSRD.nRelRow = MAXROW - aEingPos.Row();
+ else
+ rSRD.nRow = MAXROW;
+}
+
+void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn )
+{
+ // printf( "inline array;\n" );
+
+ BYTE nByte;
+ UINT16 nUINT16;
+ double fDouble;
+ String aString;
+ ScMatrix* pMatrix;
+
+ aIn >> nByte >> nUINT16;
+
+ SCSIZE nC, nCols;
+ SCSIZE nR, nRows;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ nCols = nByte + 1;
+ nRows = nUINT16 + 1;
+ }
+ else
+ {
+ nCols = nByte ? nByte : 256;
+ nRows = nUINT16;
+ }
+
+ pMatrix = aPool.GetMatrix( n );
+
+ if( NULL != pMatrix )
+ {
+ pMatrix->Resize(nCols, nRows);
+ pMatrix->GetDimensions( nC, nR);
+ if( nC != nCols || nR != nRows )
+ {
+ DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - matrix size mismatch" );
+ pMatrix = NULL;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - missing matrix" );
+ }
+
+ for( nR = 0 ; nR < nRows; nR++ )
+ {
+ for( nC = 0 ; nC < nCols; nC++ )
+ {
+ aIn >> nByte;
+ switch( nByte )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ aIn.Ignore( 8 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutEmpty( nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_DOUBLE:
+ aIn >> fDouble;
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutDouble( fDouble, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_STRING:
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ aIn >> nUINT16;
+ aString = aIn.ReadUniString( nUINT16 );
+ }
+ else
+ {
+ aIn >> nByte;
+ aString = aIn.ReadRawByteString( nByte );
+ }
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutString( aString, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_BOOL:
+ aIn >> nByte;
+ aIn.Ignore( 7 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutBoolean( nByte != 0, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_ERROR:
+ aIn >> nByte;
+ aIn.Ignore( 7 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutError( XclTools::GetScErrorCode( nByte ), nC, nR );
+ }
+ break;
+ }
+ }
+ }
+}
+
+void ExcelToSc::ReadExtensionNlr( XclImpStream& aIn )
+{
+ // printf( "natural lang fmla;\n" );
+
+ sal_uInt32 nFlags;
+ aIn >> nFlags;
+
+ sal_uInt32 nCount = nFlags & EXC_TOK_NLR_ADDMASK;
+ aIn.Ignore( nCount * 4 ); // Drop the cell positions
+}
+
+void ExcelToSc::ReadExtensionMemArea( XclImpStream& aIn )
+{
+ // printf( "mem area;\n" );
+
+ sal_uInt16 nCount;
+ aIn >> nCount;
+
+ aIn.Ignore( nCount * ((GetBiff() == EXC_BIFF8) ? 8 : 6) ); // drop the ranges
+}
+
+void ExcelToSc::ReadExtensions( const ExtensionTypeVec& rExtensions,
+ XclImpStream& aIn )
+{
+ unsigned int nArray = 0;
+
+ for( unsigned int i = 0 ; i < rExtensions.size() ; i++ )
+ {
+ ExtensionType eType = rExtensions[i];
+
+ switch( eType )
+ {
+ case EXTENSION_ARRAY:
+ ReadExtensionArray( nArray++, aIn );
+ break;
+
+ case EXTENSION_NLR:
+ ReadExtensionNlr( aIn );
+ break;
+
+ case EXTENSION_MEMAREA:
+ ReadExtensionMemArea( aIn );
+ break;
+ }
+ }
+}
+
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
new file mode 100644
index 000000000000..148b1542913a
--- /dev/null
+++ b/sc/source/filter/excel/excform8.cxx
@@ -0,0 +1,1596 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "excform.hxx"
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+
+#include "externalrefmgr.hxx"
+
+#include <vector>
+
+using ::std::vector;
+
+ExcelToSc8::ExternalTabInfo::ExternalTabInfo() :
+ mnFileId(0), mbExternal(false)
+{
+}
+
+// ============================================================================
+
+ExcelToSc8::ExcelToSc8( const XclImpRoot& rRoot ) :
+ ExcelToSc( rRoot ),
+ rLinkMan( rRoot.GetLinkManager() )
+{
+}
+
+
+ExcelToSc8::~ExcelToSc8()
+{
+}
+
+bool ExcelToSc8::GetExternalFileIdFromXti( UINT16 nIxti, sal_uInt16& rFileId ) const
+{
+ const String* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
+ if (!pFileUrl || pFileUrl->Len() == 0 || !GetDocShell())
+ return false;
+
+ String aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ rFileId = pRefMgr->getExternalFileId(aFileUrl);
+
+ return true;
+}
+
+bool ExcelToSc8::Read3DTabReference( UINT16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo )
+{
+ rFirstTab = rLastTab = 0;
+ rExtInfo.mbExternal = !rLinkMan.IsSelfRef(nIxti);
+ bool bSuccess = rLinkMan.GetScTabRange(rFirstTab, rLastTab, nIxti);
+ if (!bSuccess)
+ return false;
+
+ if (!rExtInfo.mbExternal)
+ // This is internal reference. Stop here.
+ return true;
+
+ rExtInfo.maTabName = rLinkMan.GetSupbookTabName(nIxti, rFirstTab);
+ return GetExternalFileIdFromXti(nIxti, rExtInfo.mnFileId);
+}
+
+
+// if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
+// otherwise it will seek to the first byte past additional content after <nFormulaLen>
+ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
+{
+ BYTE nOp, nLen, nByte;
+ UINT16 nUINT16;
+ double fDouble;
+ String aString;
+ BOOL bError = FALSE;
+ BOOL bArrayFormula = FALSE;
+ TokenId nMerk0;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ ExtensionTypeVec aExtensions;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ {
+ aPool.Store( CREATE_STRING( "-/-" ) );
+ aPool >> aStack;
+ rpTokArray = aPool[ aStack.Get() ];
+ return ConvOK;
+ }
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ aIn.Ignore( 4 );
+
+ bArrayFormula = TRUE;
+ break;
+ case 0x03: // Addition [312 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocAdd << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x04: // Subtraction [313 264]
+ // SECOMD-TOP minus TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocSub << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x05: // Multiplication [313 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocMul << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x06: // Division [313 264]
+ // divide TOP by SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocDiv << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x07: // Exponetiation [313 265]
+ // raise SECOND-TOP to power of TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocPow << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x08: // Concatenation [313 265]
+ // append TOP to SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocAmpersand << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x09: // Less Than [313 265]
+ // SECOND-TOP < TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLess << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0A: // Less Than or Equal [313 265]
+ // SECOND-TOP <= TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLessEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0B: // Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0C: // Greater Than or Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreaterEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0D: // Greater Than [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreater << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0E: // Not Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocNotEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0F: // Intersection [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocIntersect << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x10: // Union [314 265]
+ // ocSep behelfsweise statt 'ocUnion'
+ aStack >> nMerk0;
+//#100928# aPool << ocOpen << aStack << ocSep << nMerk0 << ocClose;
+ aPool << aStack << ocSep << nMerk0;
+ // doesn't fit exactly, but is more Excel-like
+ aPool >> aStack;
+ break;
+ case 0x11: // Range [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocRange << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x12: // Unary Plus [312 264]
+ aPool << ocAdd << aStack;
+ aPool >> aStack;
+ break;
+ case 0x13: // Unary Minus [312 264]
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+ case 0x14: // Percent Sign [312 264]
+ aPool << aStack << ocPercentSign;
+ aPool >> aStack;
+ break;
+ case 0x15: // Parenthesis [326 278]
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x16: // Missing Argument [314 266]
+ aPool << ocMissing;
+ aPool >> aStack;
+ GetTracer().TraceFormulaMissingArg();
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen; // und?
+ aString = aIn.ReadUniString( nLen ); // reads Grbit even if nLen==0
+
+ aStack << aPool.Store( aString );
+ break;
+ case 0x18: // natural language formula
+ {
+ UINT8 nEptg;
+ UINT16 nCol, nRow;
+ aIn >> nEptg;
+ switch( nEptg )
+ { // name size ext type
+ case 0x01: // Lel 4 - err
+ aIn.Ignore( 4 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case 0x02: // Rw 4 - ref
+ case 0x03: // Col 4 - ref
+ case 0x06: // RwV 4 - val
+ case 0x07: // ColV 4 - val
+ aIn >> nRow >> nCol;
+
+ aSRD.InitAddress( ScAddress( static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab() ) );
+
+ if( nEptg == 0x02 || nEptg == 0x06 )
+ aSRD.SetRowRel( TRUE );
+ else
+ aSRD.SetColRel( TRUE );
+
+ aSRD.CalcRelFromAbs( aEingPos );
+
+ aStack << aPool.StoreNlf( aSRD );
+ break;
+ case 0x0A: // Radical 13 - ref
+ aIn >> nRow >> nCol;
+ aIn.Ignore( 9 );
+
+ aSRD.InitAddress( ScAddress( static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab() ) );
+
+ aSRD.SetColRel( TRUE );
+
+ aSRD.CalcRelFromAbs( aEingPos );
+
+ aStack << aPool.StoreNlf( aSRD );
+ break;
+ case 0x0B: // RadicalS 13 x ref
+ aIn.Ignore( 13 );
+ aExtensions.push_back( EXTENSION_NLR );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case 0x0C: // RwS 4 x ref
+ case 0x0D: // ColS 4 x ref
+ case 0x0E: // RwSV 4 x val
+ case 0x0F: // ColSV 4 x val
+ aIn.Ignore( 4 );
+ aExtensions.push_back( EXTENSION_NLR );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case 0x10: // RadicalLel 4 - err
+ case 0x1D: // SxName 4 - val
+ aIn.Ignore( 4 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ default:
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ }
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ aIn >> nOpt >> nData;
+ nFakt = 2;
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ else if( nOpt & 0x10 ) // AttrSum
+ DoMulArgs( ocSum, 1 );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ {
+ aIn >> nByte;
+#if 0 // erAck
+ aPool.StoreError( XclTools::GetScErrorCode( nByte ) );
+#else
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+#endif
+ aPool >> aStack;
+ }
+ break;
+ case 0x1D: // Boolean [315 266]
+ aIn >> nByte;
+ if( nByte == 0 )
+ aPool << ocFalse << ocOpen << ocClose;
+ else
+ aPool << ocTrue << ocOpen << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn >> nUINT16;
+ aStack << aPool.Store( ( double ) nUINT16 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn >> fDouble;
+ aStack << aPool.Store( fDouble );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn >> nByte >> nUINT16;
+ aIn.Ignore( 4 );
+ if( bAllowArrays )
+ {
+ aStack << aPool.StoreMatrix();
+ aExtensions.push_back( EXTENSION_ARRAY );
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ {
+ sal_uInt16 nXclFunc;
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ {
+ sal_uInt16 nXclFunc;
+ sal_uInt8 nParamCount;
+ aIn >> nParamCount >> nXclFunc;
+ nParamCount &= 0x7F;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ aIn >> nUINT16;
+ {
+ aIn.Ignore( 2 );
+ //Determine if this is a user-defined Macro name.
+ const XclImpName* pName = GetNameManager().GetName( nUINT16 );
+ if(pName && !pName->GetScRangeData())
+ aStack << aPool.Store( ocMacro, pName->GetXclName() );
+ else
+ aStack << aPool.Store( nUINT16 );
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ {
+ UINT16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nCol = static_cast<SCCOL>(nCol);
+ aSRD.nRow = nRow & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( TRUE );
+ aSRD.SetRowDeleted( TRUE );
+ }
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ {
+ UINT16 nRowFirst, nRowLast;
+ UINT16 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( TRUE );
+ rSRef2.SetTabRel( TRUE );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ // no information which part is deleted, set all
+ rSRef1.SetColDeleted( TRUE );
+ rSRef1.SetRowDeleted( TRUE );
+ rSRef2.SetColDeleted( TRUE );
+ rSRef2.SetRowDeleted( TRUE );
+ }
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ aExtensions.push_back( EXTENSION_MEMAREA );
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+ break;
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ UINT16 nRow, nCol;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ UINT16 nRowFirst, nRowLast;
+ UINT16 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( TRUE );
+ aCRD.Ref2.SetTabRel( TRUE );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aString.AssignAscii( "COMM_EQU_FUNC" );
+ aIn >> nByte;
+ aString += String::CreateFromInt32( nByte );
+ aIn >> nByte;
+ aStack << aPool.Store( aString );
+ DoMulArgs( ocPush, nByte + 1 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ {
+ sal_uInt16 nXtiIndex, nNameIdx;
+ aIn >> nXtiIndex >> nNameIdx;
+ aIn.Ignore( 2 );
+
+ if( rLinkMan.IsSelfRef( nXtiIndex ) )
+ {
+ // internal defined name with explicit sheet, i.e.: =Sheet1!AnyName
+ const XclImpName* pName = GetNameManager().GetName( nNameIdx );
+ if( pName && !pName->GetScRangeData() )
+ aStack << aPool.Store( ocMacro, pName->GetXclName() );
+ else
+ aStack << aPool.Store( nNameIdx );
+ }
+ else if( const XclImpExtName* pExtName = rLinkMan.GetExternName( nXtiIndex, nNameIdx ) )
+ {
+ switch( pExtName->GetType() )
+ {
+ case xlExtName:
+ {
+ /* FIXME: enable this code for #i4385# once
+ * external name reference can be stored in ODF,
+ * which remains to be done for #i3740#. Until then
+ * create a #NAME? token. */
+#if 0
+ sal_uInt16 nFileId;
+ if (!GetExternalFileIdFromXti(nXtiIndex, nFileId) || !pExtName->HasFormulaTokens())
+ {
+ aStack << aPool.Store(ocNoName, pExtName->GetName());
+ break;
+ }
+
+ aStack << aPool.StoreExtName(nFileId, pExtName->GetName());
+ pExtName->CreateExtNameData(GetDoc(), nFileId);
+#else
+ aStack << aPool.Store( ocNoName, pExtName->GetName() );
+#endif
+ }
+ break;
+
+ case xlExtAddIn:
+ {
+ aStack << aPool.Store( ocExternal, pExtName->GetName() );
+ }
+ break;
+
+ case xlExtDDE:
+ {
+ String aApplic, aTopic;
+ if( rLinkMan.GetLinkData( aApplic, aTopic, nXtiIndex ) )
+ {
+ TokenId nPar1 = aPool.Store( aApplic );
+ TokenId nPar2 = aPool.Store( aTopic );
+ nMerk0 = aPool.Store( pExtName->GetName() );
+ aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
+ << nMerk0 << ocClose;
+ aPool >> aStack;
+ pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
+ }
+ }
+ break;
+
+ case xlExtEuroConvert:
+ {
+ aStack << aPool.Store( ocEuroConvert, String() );
+ }
+ break;
+
+ default: // OLE link
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ }
+ }
+ else
+ {
+ //aStack << ocNoName;
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ }
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ {
+ UINT16 nIxti, nRw, nGrbitCol;
+ SCTAB nTabFirst, nTabLast;
+
+ aIn >> nIxti >> nRw >> nGrbitCol;
+
+ ExternalTabInfo aExtInfo;
+ if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ }
+
+ aSRD.nTab = nTabFirst;
+ aSRD.SetFlag3D( TRUE );
+ aSRD.SetTabRel( FALSE );
+
+ ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( TRUE );
+ aSRD.SetRowDeleted( TRUE );
+ }
+
+ if (aExtInfo.mbExternal)
+ {
+ // nTabFirst and nTabLast are the indices of the refernced
+ // sheets in the SUPBOOK record, hence do not represent
+ // the actual indices of the original sheets since the
+ // SUPBOOK record only stores referenced sheets and skips
+ // the ones that are not referenced.
+
+ if (nTabLast != nTabFirst)
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = nTabLast;
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
+ }
+ else
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
+ }
+ else
+ {
+ if ( !ValidTab(nTabFirst))
+ aSRD.SetTabDeleted( TRUE );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = nTabLast;
+ aCRD.Ref2.SetTabDeleted( !ValidTab(nTabLast) );
+ aStack << aPool.Store( aCRD );
+ }
+ else
+ aStack << aPool.Store( aSRD );
+ }
+ }
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ {
+ UINT16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
+ SCTAB nTabFirst, nTabLast;
+ aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
+
+ ExternalTabInfo aExtInfo;
+ if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ }
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+
+ rR1.nTab = nTabFirst;
+ rR2.nTab = nTabLast;
+ rR1.SetFlag3D( TRUE );
+ rR1.SetTabRel( FALSE );
+ rR2.SetFlag3D( nTabFirst != nTabLast );
+ rR2.SetTabRel( FALSE );
+
+ ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRw1, nRw2 ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ // no information which part is deleted, set all
+ rR1.SetColDeleted( TRUE );
+ rR1.SetRowDeleted( TRUE );
+ rR2.SetColDeleted( TRUE );
+ rR2.SetRowDeleted( TRUE );
+ }
+
+ if (aExtInfo.mbExternal)
+ {
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
+ }
+ else
+ {
+ if ( !ValidTab(nTabFirst) )
+ rR1.SetTabDeleted( TRUE );
+ if ( !ValidTab(nTabLast) )
+ rR2.SetTabDeleted( TRUE );
+
+ aStack << aPool.Store( aCRD );
+ }
+ }
+ break;
+ default: bError = TRUE;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpTokArray = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( aIn.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpTokArray = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else if( bArrayFormula )
+ {
+ rpTokArray = NULL;
+ eRet = ConvOK;
+ }
+ else
+ {
+ rpTokArray = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ aIn.Seek( nEndPos );
+
+ if( eRet == ConvOK)
+ ReadExtensions( aExtensions, aIn );
+
+ return eRet;
+}
+
+
+// stream seeks to first byte after <nFormulaLen>
+ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen, const FORMULA_TYPE eFT )
+{
+ BYTE nOp, nLen;//, nByte;
+ BOOL bError = FALSE;
+ BOOL bArrayFormula = FALSE;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+
+ bExternName = FALSE;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ return ConvOK;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ aIn.Ignore( 4 );
+
+ bArrayFormula = TRUE;
+ break;
+ case 0x02: // Data Table [325 277]
+ aIn.Ignore( 4 );
+ break;
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen; // und?
+
+ aIn.IgnoreUniString( nLen ); // reads Grbit even if nLen==0
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ aIn >> nOpt >> nData;
+ nFakt = 2;
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ aIn.Ignore( 1 );
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn.Ignore( 2 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn.Ignore( 8 );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn.Ignore( 7 );
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ aIn.Ignore( 2 );
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ aIn.Ignore( 3 );
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ aIn.Ignore( 4 );
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ {
+ UINT16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nCol = static_cast<SCCOL>(nCol);
+ aSRD.nRow = nRow & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
+
+ rRangeList.Append( aSRD );
+ }
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ {
+ UINT16 nRowFirst, nRowLast;
+ UINT16 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( TRUE );
+ rSRef2.SetTabRel( TRUE );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+ break;
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ aIn.Ignore( 3 );
+ break;
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ aIn.Ignore( 6 );
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ UINT16 nRow, nCol;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
+
+ rRangeList.Append( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ UINT16 nRowFirst, nRowLast;
+ UINT16 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( TRUE );
+ aCRD.Ref2.SetTabRel( TRUE );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ break;
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aIn.Ignore( 2 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ aIn.Ignore( 24 );
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ {
+ UINT16 nIxti, nRw, nGrbitCol;
+
+ aIn >> nIxti >> nRw >> nGrbitCol;
+
+ SCTAB nFirstScTab, nLastScTab;
+ if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
+ {
+ aSRD.nTab = nFirstScTab;
+ aSRD.SetFlag3D( TRUE );
+ aSRD.SetTabRel( FALSE );
+
+ ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
+
+ if( nFirstScTab != nLastScTab )
+ {
+ aCRD.Ref1 = aSRD;
+ aCRD.Ref2.nCol = aSRD.nCol;
+ aCRD.Ref2.nRow = aSRD.nRow;
+ aCRD.Ref2.nTab = nLastScTab;
+ rRangeList.Append( aCRD );
+ }
+ else
+ rRangeList.Append( aSRD );
+ }
+ }
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ {
+ UINT16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
+
+ aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
+
+ SCTAB nFirstScTab, nLastScTab;
+ if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
+ {
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+ rR1.nTab = nFirstScTab;
+ rR2.nTab = nLastScTab;
+ rR1.SetFlag3D( TRUE );
+ rR1.SetTabRel( FALSE );
+ rR2.SetFlag3D( nFirstScTab != nLastScTab );
+ rR2.SetTabRel( FALSE );
+
+ ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRw1, nRw2 ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ }
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ aIn.Ignore( 6 );
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ aIn.Ignore( 10 );
+ break;
+ default:
+ bError = TRUE;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ eRet = ConvErrNi;
+ else if( aIn.GetRecPos() != nEndPos )
+ eRet = ConvErrCount;
+ else if( bExternName )
+ eRet = ConvErrExternal;
+ else
+ eRet = ConvOK;
+
+ aIn.Seek( nEndPos );
+ return eRet;
+}
+
+ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const String& rUrl, const vector<String>& rTabNames )
+{
+ if( !GetDocShell() )
+ return ConvErrNi;
+
+ String aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
+
+ sal_uInt8 nOp, nByte;
+ bool bError = false;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+
+ if (eStatus != ConvOK)
+ {
+ rStrm.Ignore(nFormulaLen);
+ return eStatus;
+ }
+
+ if (nFormulaLen == 0)
+ {
+ aPool.Store(CREATE_STRING("-/-"));
+ aPool >> aStack;
+ rpArray = aPool[aStack.Get()];
+ return ConvOK;
+ }
+
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFileUrl);
+ sal_uInt16 nTabCount = static_cast< sal_uInt16 >( rTabNames.size() );
+
+ sal_Size nEndPos = rStrm.GetRecPos() + nFormulaLen;
+
+ while( (rStrm.GetRecPos() < nEndPos) && !bError )
+ {
+ rStrm >> nOp;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp )
+ {
+ case 0x1C: // Error Value
+ {
+ rStrm >> nByte;
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+ aPool >> aStack;
+ }
+ break;
+ case 0x3A:
+ {
+ // cell reference in external range name
+ sal_uInt16 nExtTab1, nExtTab2, nRow, nGrbitCol;
+ rStrm >> nExtTab1 >> nExtTab2 >> nRow >> nGrbitCol;
+ if (nExtTab1 >= nTabCount || nExtTab2 >= nTabCount)
+ {
+ bError = true;
+ break;
+ }
+
+ aSRD.nTab = nExtTab1;
+ aSRD.SetFlag3D(true);
+ aSRD.SetTabRel(false);
+ ExcRelToScRel8(nRow, nGrbitCol, aSRD, true);
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ String aTabName = rTabNames[nExtTab1];
+
+ if (nExtTab1 == nExtTab2)
+ {
+ // single cell reference
+ aStack << aPool.StoreExtRef(nFileId, aTabName, aSRD);
+ }
+ else
+ {
+ // area reference
+ aCRD.Ref2.nTab = nExtTab2;
+ aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
+ }
+ }
+ break;
+ case 0x3B:
+ {
+ // area reference
+ sal_uInt16 nExtTab1, nExtTab2, nRow1, nRow2, nGrbitCol1, nGrbitCol2;
+ rStrm >> nExtTab1 >> nExtTab2 >> nRow1 >> nRow2 >> nGrbitCol1 >> nGrbitCol2;
+ ScSingleRefData& rR1 = aCRD.Ref1;
+ ScSingleRefData& rR2 = aCRD.Ref2;
+
+ rR1.nTab = nExtTab1;
+ rR1.SetFlag3D(true);
+ rR1.SetTabRel(false);
+ ExcRelToScRel8(nRow1, nGrbitCol1, rR1, true);
+
+ rR2.nTab = nExtTab2;
+ rR2.SetFlag3D(true);
+ rR2.SetTabRel(false);
+ ExcRelToScRel8(nRow2, nGrbitCol2, rR2, true);
+
+ String aTabName = rTabNames[nExtTab1];
+ aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
+ }
+ break;
+ default:
+ bError = true;
+ }
+ bError |= !rStrm.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpArray = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( rStrm.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpArray = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else
+ {
+ rpArray = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ rStrm.Seek(nEndPos);
+ return eRet;
+}
+
+void ExcelToSc8::ExcRelToScRel8( UINT16 nRow, UINT16 nC, ScSingleRefData &rSRD, const BOOL bName )
+{
+ const BOOL bColRel = ( nC & 0x4000 ) != 0;
+ const BOOL bRowRel = ( nC & 0x8000 ) != 0;
+ const UINT8 nCol = static_cast<UINT8>(nC);
+
+ rSRD.SetColRel( bColRel );
+ rSRD.SetRowRel( bRowRel );
+
+ if( bName )
+ {
+ // C O L
+ if( bColRel )
+ // rel Col
+ rSRD.nRelCol = static_cast<SCsCOL>(static_cast<INT8>(nC));
+ else
+ // abs Col
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+
+ // R O W
+ if( bRowRel )
+ // rel Row
+ rSRD.nRelRow = static_cast<SCsROW>(static_cast<INT16>(nRow));
+ else
+ // abs Row
+ rSRD.nRow = Min( static_cast<SCROW>(nRow), MAXROW);
+
+ // T A B
+ // #67965# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab();
+ }
+ else
+ {
+ // C O L
+ if ( bColRel )
+ rSRD.nRelCol = static_cast<SCsCOL>(nCol) - aEingPos.Col();
+ else
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+
+ // R O W
+ if ( bRowRel )
+ rSRD.nRelRow = static_cast<SCsROW>(nRow) - aEingPos.Row();
+ else
+ rSRD.nRow = static_cast<SCROW>(nRow);
+
+ // T A B
+ // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
+ }
+}
+
+
+// stream seeks to first byte after <nLen>
+BOOL ExcelToSc8::GetAbsRefs( ScRangeList& r, XclImpStream& aIn, sal_Size nLen )
+{
+ UINT8 nOp;
+ UINT16 nRow1, nRow2, nCol1, nCol2;
+ SCTAB nTab1, nTab2;
+ UINT16 nIxti;
+
+ sal_Size nSeek;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nLen;
+
+ while( aIn.IsValid() && (aIn.GetRecPos() < nEndPos) )
+ {
+ aIn >> nOp;
+ nSeek = 0;
+
+ switch( nOp )
+ {
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ aIn >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ // Area Reference Within a Shared Formula[ 274]
+ aIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ aIn >> nIxti >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+
+ goto _3d_common;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ aIn >> nIxti >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ _3d_common:
+ // #122885# skip references to deleted sheets
+ if( !rLinkMan.GetScTabRange( nTab1, nTab2, nIxti ) || !ValidTab( nTab1 ) || !ValidTab( nTab2 ) )
+ break;
+
+ goto _common;
+ _common:
+ // do not check abs/rel flags, linked controls have set them!
+// if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
+ {
+ ScRange aScRange;
+ nCol1 &= 0x3FFF;
+ nCol2 &= 0x3FFF;
+ if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
+ r.Append( aScRange );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nSeek = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nSeek = 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ nSeek = 3;
+ break;
+ case 0x01: // Array Formula [325 ]
+ case 0x02: // Data Table [325 277]
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nSeek = 4;
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nSeek = 6;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nSeek = 7;
+ break;
+ case 0x1F: // Number [315 266]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nSeek = 8;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nSeek = 10;
+ break;
+ case 0x17: // String Constant [314 266]
+ {
+ UINT8 nStrLen;
+ aIn >> nStrLen;
+ aIn.IgnoreUniString( nStrLen ); // reads Grbit even if nLen==0
+ nSeek = 0;
+ }
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData;
+ UINT8 nOpt;
+ aIn >> nOpt >> nData;
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ nSeek = nData * 2;
+ }
+ }
+ break;
+ }
+
+ aIn.Ignore( nSeek );
+ }
+ aIn.Seek( nEndPos );
+
+ return r.Count() != 0;
+}
+
+
+
+
+
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
new file mode 100644
index 000000000000..d75a0e669603
--- /dev/null
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -0,0 +1,727 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "excimp8.hxx"
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+#include <scitems.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/fltrcfg.hxx>
+
+#include <svtools/wmf.hxx>
+
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/xflclit.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+#include <basic/basmgr.hxx>
+
+#include <vcl/graph.hxx>
+#include <vcl/bmpacc.hxx>
+#include <sot/exchange.hxx>
+
+#include <sfx2/docinf.hxx>
+
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/charclass.hxx>
+#include <drwlayer.hxx>
+
+#include <boost/scoped_array.hpp>
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "conditio.hxx"
+#include "dbcolect.hxx"
+#include "editutil.hxx"
+#include "markdata.hxx"
+#include "rangenam.hxx"
+#include "docoptio.hxx"
+#include "globstr.hrc"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xipage.hxx"
+#include "xicontent.hxx"
+#include "xilink.hxx"
+#include "xiescher.hxx"
+#include "xipivot.hxx"
+
+#include "excform.hxx"
+#include "scextopt.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "detfunc.hxx"
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <cppuhelper/component_context.hxx>
+#include <sfx2/app.hxx>
+
+using namespace com::sun::star;
+using ::rtl::OUString;
+
+
+ImportExcel8::ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ) :
+ ImportExcel( rImpData, rStrm )
+{
+ // replace BIFF2-BIFF5 formula importer with BIFF8 formula importer
+ delete pFormConv;
+ pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc8( GetRoot() );
+}
+
+
+ImportExcel8::~ImportExcel8()
+{
+}
+
+
+void ImportExcel8::Calccount( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetIterCount( aIn.ReaduInt16() );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Precision( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetCalcAsShown( aIn.ReaduInt16() == 0 );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Delta( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetIterEps( aIn.ReadDouble() );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Iteration( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetIter( aIn.ReaduInt16() == 1 );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Boundsheet( void )
+{
+ UINT8 nLen;
+ UINT16 nGrbit;
+
+ aIn.DisableDecryption();
+ maSheetOffsets.push_back( aIn.ReaduInt32() );
+ aIn.EnableDecryption();
+ aIn >> nGrbit >> nLen;
+
+ String aName( aIn.ReadUniString( nLen ) );
+ GetTabInfo().AppendXclTabName( aName, nBdshtTab );
+
+ SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
+ if( nScTab > 0 )
+ {
+ DBG_ASSERT( !pD->HasTable( nScTab ), "ImportExcel8::Boundsheet - sheet exists already" );
+ pD->MakeTable( nScTab );
+ }
+
+ if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
+ pD->SetVisible( nScTab, FALSE );
+
+ if( !pD->RenameTab( nScTab, aName ) )
+ {
+ pD->CreateValidTabName( aName );
+ pD->RenameTab( nScTab, aName );
+ }
+
+ nBdshtTab++;
+}
+
+
+void ImportExcel8::Scenman( void )
+{
+ UINT16 nLastDispl;
+
+ aIn.Ignore( 4 );
+ aIn >> nLastDispl;
+
+ aScenList.SetLast( nLastDispl );
+}
+
+
+void ImportExcel8::Scenario( void )
+{
+ aScenList.Append( new ExcScenario( aIn, *pExcRoot ) );
+}
+
+
+void ImportExcel8::Labelsst( void )
+{
+ XclAddress aXclPos;
+ UINT16 nXF;
+ UINT32 nSst;
+
+ aIn >> aXclPos >> nXF >> nSst;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ if( ScBaseCell* pCell = GetSst().CreateCell( nSst, nXF ) )
+ GetDoc().PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pCell );
+ }
+}
+
+
+void ImportExcel8::SheetProtection( void )
+{
+ GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
+}
+
+void ImportExcel8::ReadBasic( void )
+{
+ SfxObjectShell* pShell = GetDocShell();
+ SotStorageRef xRootStrg = GetRootStorage();
+ SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get();
+ if( pShell && xRootStrg.Is() && pFilterOpt )
+ {
+ bool bLoadCode = pFilterOpt->IsLoadExcelBasicCode();
+ bool bLoadExecutable = pFilterOpt->IsLoadExcelBasicExecutable();
+ bool bLoadStrg = pFilterOpt->IsLoadExcelBasicStorage();
+ if( bLoadCode || bLoadStrg )
+ {
+ SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg );
+ bool bAsComment = !bLoadExecutable;
+ aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, bAsComment );
+ }
+ }
+}
+
+
+void ImportExcel8::EndSheet( void )
+{
+ GetCondFormatManager().Apply();
+ ImportExcel::EndSheet();
+}
+
+
+void ImportExcel8::PostDocLoad( void )
+{
+ // reading basic has been delayed until sheet objects (codenames etc.) are read
+ if( HasBasic() )
+ ReadBasic();
+ // #i11776# filtered ranges before outlines and hidden rows
+ if( pExcRoot->pAutoFilterBuffer )
+ pExcRoot->pAutoFilterBuffer->Apply();
+
+ GetWebQueryBuffer().Apply(); //! test if extant
+ GetSheetProtectBuffer().Apply();
+ GetDocProtectBuffer().Apply();
+
+ ImportExcel::PostDocLoad();
+
+ // Scenarien bemachen! ACHTUNG: Hier wird Tabellen-Anzahl im Dokument erhoeht!!
+ if( !pD->IsClipboard() && aScenList.Count() )
+ {
+ pD->UpdateChartListenerCollection(); // references in charts must be updated
+
+ aScenList.Apply( GetRoot() );
+ }
+
+ // read doc info (no docshell while pasting from clipboard)
+ LoadDocumentProperties();
+
+ // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available
+ // when formula cells are calculated, for the GETPIVOTDATA function.
+}
+
+void ImportExcel8::LoadDocumentProperties()
+{
+ // no docshell while pasting from clipboard
+ if( SfxObjectShell* pShell = GetDocShell() )
+ {
+ // BIFF5+ without storage is possible
+ SotStorageRef xRootStrg = GetRootStorage();
+ if( xRootStrg.Is() ) try
+ {
+ uno::Reference< document::XDocumentPropertiesSupplier > xDPS( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< document::XDocumentProperties > xDocProps( xDPS->getDocumentProperties(), uno::UNO_SET_THROW );
+ sfx2::LoadOlePropertySet( xDocProps, xRootStrg );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+}
+
+//___________________________________________________________________
+// autofilter
+
+void ImportExcel8::FilterMode( void )
+{
+ // The FilterMode record exists: if either the AutoFilter
+ // record exists or an Advanced Filter is saved and stored
+ // in the sheet. Thus if the FilterMode records only exists
+ // then the latter is true..
+ if( !pExcRoot->pAutoFilterBuffer ) return;
+
+ pExcRoot->pAutoFilterBuffer->IncrementActiveAF();
+
+ XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
+ if( pData )
+ pData->SetAutoOrAdvanced();
+}
+
+void ImportExcel8::AutoFilterInfo( void )
+{
+ if( !pExcRoot->pAutoFilterBuffer ) return;
+
+ XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
+ if( pData )
+ {
+ pData->SetAdvancedRange( NULL );
+ pData->Activate();
+ }
+}
+
+void ImportExcel8::AutoFilter( void )
+{
+ if( !pExcRoot->pAutoFilterBuffer ) return;
+
+ XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
+ if( pData )
+ pData->ReadAutoFilter( aIn );
+}
+
+
+
+XclImpAutoFilterData::XclImpAutoFilterData( RootData* pRoot, const ScRange& rRange, const String& rName ) :
+ ExcRoot( pRoot ),
+ pCurrDBData(NULL),
+ nFirstEmpty( 0 ),
+ bActive( FALSE ),
+ bHasConflict( FALSE ),
+ bCriteria( FALSE ),
+ bAutoOrAdvanced(FALSE),
+ aFilterName(rName)
+{
+ aParam.nCol1 = rRange.aStart.Col();
+ aParam.nRow1 = rRange.aStart.Row();
+ aParam.nTab = rRange.aStart.Tab();
+ aParam.nCol2 = rRange.aEnd.Col();
+ aParam.nRow2 = rRange.aEnd.Row();
+
+ aParam.bInplace = TRUE;
+
+}
+
+void XclImpAutoFilterData::CreateFromDouble( String& rStr, double fVal )
+{
+ rStr += String( ::rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), TRUE));
+}
+
+void XclImpAutoFilterData::SetCellAttribs()
+{
+ ScDocument& rDoc = pExcRoot->pIR->GetDoc();
+ for ( SCCOL nCol = StartCol(); nCol <= EndCol(); nCol++ )
+ {
+ INT16 nFlag = ((ScMergeFlagAttr*) rDoc.GetAttr( nCol, StartRow(), Tab(), ATTR_MERGE_FLAG ))->GetValue();
+ rDoc.ApplyAttr( nCol, StartRow(), Tab(), ScMergeFlagAttr( nFlag | SC_MF_AUTO) );
+ }
+}
+
+void XclImpAutoFilterData::InsertQueryParam()
+{
+ if( pCurrDBData && !bHasConflict )
+ {
+ ScRange aAdvRange;
+ BOOL bHasAdv = pCurrDBData->GetAdvancedQuerySource( aAdvRange );
+ if( bHasAdv )
+ pExcRoot->pIR->GetDoc().CreateQueryParam( aAdvRange.aStart.Col(),
+ aAdvRange.aStart.Row(), aAdvRange.aEnd.Col(), aAdvRange.aEnd.Row(),
+ aAdvRange.aStart.Tab(), aParam );
+
+ pCurrDBData->SetQueryParam( aParam );
+ if( bHasAdv )
+ pCurrDBData->SetAdvancedQuerySource( &aAdvRange );
+ else
+ {
+ pCurrDBData->SetAutoFilter( TRUE );
+ SetCellAttribs();
+ }
+ }
+}
+
+static void ExcelQueryToOooQuery( ScQueryEntry& rEntry )
+{
+ if( ( rEntry.eOp != SC_EQUAL && rEntry.eOp != SC_NOT_EQUAL ) || rEntry.pStr == NULL )
+ return;
+ else
+ {
+ xub_StrLen nLen = rEntry.pStr->Len();
+ sal_Unicode nStart = rEntry.pStr->GetChar( 0 );
+ sal_Unicode nEnd = rEntry.pStr->GetChar( nLen-1 );
+ if( nLen >2 && nStart == '*' && nEnd == '*' )
+ {
+ rEntry.pStr->Erase( nLen-1, 1 );
+ rEntry.pStr->Erase( 0, 1 );
+ rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_CONTAINS : SC_DOES_NOT_CONTAIN;
+ }
+ else if( nLen > 1 && nStart == '*' && nEnd != '*' )
+ {
+ rEntry.pStr->Erase( 0, 1 );
+ rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_ENDS_WITH : SC_DOES_NOT_END_WITH;
+ }
+ else if( nLen > 1 && nStart != '*' && nEnd == '*' )
+ {
+ rEntry.pStr->Erase( nLen-1, 1 );
+ rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_BEGINS_WITH : SC_DOES_NOT_BEGIN_WITH;
+ }
+ else if( nLen == 2 && nStart == '*' && nEnd == '*' )
+ {
+ rEntry.pStr->Erase( 0, 1 );
+ }
+ }
+}
+
+void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
+{
+ UINT16 nCol, nFlags;
+ rStrm >> nCol >> nFlags;
+
+ ScQueryConnect eConn = ::get_flagvalue( nFlags, EXC_AFFLAG_ANDORMASK, SC_OR, SC_AND );
+ BOOL bTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10 );
+ BOOL bTopOfTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10TOP );
+ BOOL bPercent = ::get_flag( nFlags, EXC_AFFLAG_TOP10PERC );
+ UINT16 nCntOfTop10 = nFlags >> 7;
+ SCSIZE nCount = aParam.GetEntryCount();
+
+ if( bTop10 )
+ {
+ if( nFirstEmpty < nCount )
+ {
+ ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+ aEntry.bDoQuery = TRUE;
+ aEntry.bQueryByString = TRUE;
+ aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
+ aEntry.eOp = bTopOfTop10 ?
+ (bPercent ? SC_TOPPERC : SC_TOPVAL) : (bPercent ? SC_BOTPERC : SC_BOTVAL);
+ aEntry.eConnect = SC_AND;
+ aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nCntOfTop10 ) );
+
+ rStrm.Ignore( 20 );
+ nFirstEmpty++;
+ }
+ }
+ else
+ {
+ UINT8 nE, nType, nOper, nBoolErr, nVal;
+ INT32 nRK;
+ double fVal;
+ BOOL bIgnore;
+
+ UINT8 nStrLen[ 2 ] = { 0, 0 };
+ ScQueryEntry *pQueryEntries[ 2 ] = { NULL, NULL };
+
+ for( nE = 0; nE < 2; nE++ )
+ {
+ if( nFirstEmpty < nCount )
+ {
+ ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+ pQueryEntries[ nE ] = &aEntry;
+ bIgnore = FALSE;
+
+ rStrm >> nType >> nOper;
+ switch( nOper )
+ {
+ case EXC_AFOPER_LESS:
+ aEntry.eOp = SC_LESS;
+ break;
+ case EXC_AFOPER_EQUAL:
+ aEntry.eOp = SC_EQUAL;
+ break;
+ case EXC_AFOPER_LESSEQUAL:
+ aEntry.eOp = SC_LESS_EQUAL;
+ break;
+ case EXC_AFOPER_GREATER:
+ aEntry.eOp = SC_GREATER;
+ break;
+ case EXC_AFOPER_NOTEQUAL:
+ aEntry.eOp = SC_NOT_EQUAL;
+ break;
+ case EXC_AFOPER_GREATEREQUAL:
+ aEntry.eOp = SC_GREATER_EQUAL;
+ break;
+ default:
+ aEntry.eOp = SC_EQUAL;
+ }
+
+ switch( nType )
+ {
+ case EXC_AFTYPE_RK:
+ rStrm >> nRK;
+ rStrm.Ignore( 4 );
+ CreateFromDouble( *aEntry.pStr, XclTools::GetDoubleFromRK( nRK ) );
+ break;
+ case EXC_AFTYPE_DOUBLE:
+ rStrm >> fVal;
+ CreateFromDouble( *aEntry.pStr, fVal );
+ break;
+ case EXC_AFTYPE_STRING:
+ rStrm.Ignore( 4 );
+ rStrm >> nStrLen[ nE ];
+ rStrm.Ignore( 3 );
+ aEntry.pStr->Erase();
+ break;
+ case EXC_AFTYPE_BOOLERR:
+ rStrm >> nBoolErr >> nVal;
+ rStrm.Ignore( 6 );
+ aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nVal ) );
+ bIgnore = (BOOL) nBoolErr;
+ break;
+ case EXC_AFTYPE_EMPTY:
+ aEntry.bQueryByString = FALSE;
+ aEntry.nVal = SC_EMPTYFIELDS;
+ aEntry.eOp = SC_EQUAL;
+ break;
+ case EXC_AFTYPE_NOTEMPTY:
+ aEntry.bQueryByString = FALSE;
+ aEntry.nVal = SC_NONEMPTYFIELDS;
+ aEntry.eOp = SC_EQUAL;
+ break;
+ default:
+ rStrm.Ignore( 8 );
+ bIgnore = TRUE;
+ }
+
+ /* #i39464# conflict, if two conditions of one column are 'OR'ed,
+ and they follow conditions of other columns.
+ Example: Let A1 be a condition of column A, and B1 and B2
+ conditions of column B, connected with OR. Excel performs
+ 'A1 AND (B1 OR B2)' in this case, but Calc would do
+ '(A1 AND B1) OR B2' instead. */
+ if( (nFirstEmpty > 1) && nE && (eConn == SC_OR) && !bIgnore )
+ bHasConflict = TRUE;
+ if( !bHasConflict && !bIgnore )
+ {
+ aEntry.bDoQuery = TRUE;
+ aEntry.bQueryByString = TRUE;
+ aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
+ aEntry.eConnect = nE ? eConn : SC_AND;
+ nFirstEmpty++;
+ }
+ }
+ else
+ rStrm.Ignore( 10 );
+ }
+
+ for( nE = 0; nE < 2; nE++ )
+ if( nStrLen[ nE ] && pQueryEntries[ nE ] )
+ {
+ pQueryEntries[ nE ]->pStr->Assign ( rStrm.ReadUniString( nStrLen[ nE ] ) );
+ ExcelQueryToOooQuery( *pQueryEntries[ nE ] );
+ }
+
+ }
+}
+
+void XclImpAutoFilterData::SetAdvancedRange( const ScRange* pRange )
+{
+ if (pRange)
+ {
+ aCriteriaRange = *pRange;
+ bCriteria = TRUE;
+ }
+ else
+ bCriteria = FALSE;
+}
+
+void XclImpAutoFilterData::SetExtractPos( const ScAddress& rAddr )
+{
+ aParam.nDestCol = rAddr.Col();
+ aParam.nDestRow = rAddr.Row();
+ aParam.nDestTab = rAddr.Tab();
+ aParam.bInplace = FALSE;
+ aParam.bDestPers = TRUE;
+}
+
+void XclImpAutoFilterData::Apply( const BOOL bUseUnNamed )
+{
+ CreateScDBData(bUseUnNamed);
+
+ if( bActive )
+ {
+ InsertQueryParam();
+
+ // #i38093# rows hidden by filter need extra flag, but CR_FILTERED is not set here yet
+// SCROW nRow1 = StartRow();
+// SCROW nRow2 = EndRow();
+// size_t nRows = nRow2 - nRow1 + 1;
+// boost::scoped_array<BYTE> pFlags( new BYTE[nRows]);
+// pExcRoot->pDoc->GetRowFlagsArray( Tab()).FillDataArray( nRow1, nRow2,
+// pFlags.get());
+// for (size_t j=0; j<nRows; ++j)
+// {
+// if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
+// pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
+// pFlags[j] | CR_FILTERED );
+// }
+ }
+}
+
+void XclImpAutoFilterData::CreateScDBData( const BOOL bUseUnNamed )
+{
+
+ // Create the ScDBData() object if the AutoFilter is activated
+ // or if we need to create the Advanced Filter.
+ if( bActive || bCriteria)
+ {
+ ScDBCollection& rColl = pExcRoot->pIR->GetDatabaseRanges();
+ pCurrDBData = rColl.GetDBAtArea( Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
+ if( !pCurrDBData )
+ {
+ AmendAFName(bUseUnNamed);
+
+ pCurrDBData = new ScDBData( aFilterName, Tab(), StartCol(), StartRow(), EndCol(), EndRow() );
+
+ if( pCurrDBData )
+ {
+ if(bCriteria)
+ {
+ EnableRemoveFilter();
+
+ pCurrDBData->SetQueryParam( aParam );
+ pCurrDBData->SetAdvancedQuerySource(&aCriteriaRange);
+ }
+ else
+ pCurrDBData->SetAdvancedQuerySource(NULL);
+ rColl.Insert( pCurrDBData );
+ }
+ }
+ }
+
+}
+
+void XclImpAutoFilterData::EnableRemoveFilter()
+{
+ // only if this is a saved Advanced filter
+ if( !bActive && bAutoOrAdvanced )
+ {
+ ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+ aEntry.bDoQuery = TRUE;
+ ++nFirstEmpty;
+ }
+
+ // TBD: force the automatic activation of the
+ // "Remove Filter" by setting a virtual mouse click
+ // inside the advanced range
+}
+
+void XclImpAutoFilterData::AmendAFName(const BOOL bUseUnNamed)
+{
+ // If-and-only-if we have one AF filter then
+ // use the Calc "unnamed" range name. Calc
+ // only supports one in total while Excel
+ // supports one per sheet.
+ if( bUseUnNamed && bAutoOrAdvanced )
+ aFilterName = ScGlobal::GetRscString(STR_DB_NONAME);
+}
+
+XclImpAutoFilterBuffer::XclImpAutoFilterBuffer() :
+ nAFActiveCount( 0 )
+{
+}
+
+XclImpAutoFilterBuffer::~XclImpAutoFilterBuffer()
+{
+ for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
+ delete pData;
+}
+
+void XclImpAutoFilterBuffer::Insert( RootData* pRoot, const ScRange& rRange,
+ const String& rName )
+{
+ if( !GetByTab( rRange.aStart.Tab() ) )
+ Append( new XclImpAutoFilterData( pRoot, rRange, rName ) );
+}
+
+void XclImpAutoFilterBuffer::AddAdvancedRange( const ScRange& rRange )
+{
+ XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
+ if( pData )
+ pData->SetAdvancedRange( &rRange );
+}
+
+void XclImpAutoFilterBuffer::AddExtractPos( const ScRange& rRange )
+{
+ XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
+ if( pData )
+ pData->SetExtractPos( rRange.aStart );
+}
+
+void XclImpAutoFilterBuffer::Apply()
+{
+ for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
+ pData->Apply(UseUnNamed());
+}
+
+XclImpAutoFilterData* XclImpAutoFilterBuffer::GetByTab( SCTAB nTab )
+{
+ for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
+ if( pData->Tab() == nTab )
+ return pData;
+ return NULL;
+}
+
diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
new file mode 100644
index 000000000000..9a66325db419
--- /dev/null
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -0,0 +1,1051 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "excrecds.hxx"
+
+#include <map>
+#include <filter/msfilter/countryid.hxx>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/objsh.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+
+#include <editeng/flditem.hxx>
+#include <editeng/flstitem.hxx>
+
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <svtools/ctrltool.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+
+#include <string.h>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "progress.hxx"
+#include "dociter.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "editutil.hxx"
+#include "formula/errorcodes.hxx"
+
+#include "excdoc.hxx"
+#include "xeescher.hxx"
+#include "xeformula.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xecontent.hxx"
+
+#include "xcl97rec.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::com::sun::star::uno::Sequence;
+
+
+using ::rtl::OString;
+
+//--------------------------------------------------------- class ExcDummy_00 -
+const BYTE ExcDummy_00::pMyData[] = {
+ 0x5c, 0x00, 0x20, 0x00, 0x04, 'C', 'a', 'l', 'c', // WRITEACCESS
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+const sal_Size ExcDummy_00::nMyLen = sizeof( ExcDummy_00::pMyData );
+
+//-------------------------------------------------------- class ExcDummy_04x -
+const BYTE ExcDummy_040::pMyData[] = {
+ 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, // BACKUP
+ 0x8d, 0x00, 0x02, 0x00, 0x00, 0x00, // HIDEOBJ
+};
+const sal_Size ExcDummy_040::nMyLen = sizeof( ExcDummy_040::pMyData );
+
+const BYTE ExcDummy_041::pMyData[] = {
+ 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, // PRECISION
+ 0xda, 0x00, 0x02, 0x00, 0x00, 0x00 // BOOKBOOL
+};
+const sal_Size ExcDummy_041::nMyLen = sizeof( ExcDummy_041::pMyData );
+
+//-------------------------------------------------------- class ExcDummy_02a -
+const BYTE ExcDummy_02a::pMyData[] = {
+ 0x0d, 0x00, 0x02, 0x00, 0x01, 0x00, // CALCMODE
+ 0x0c, 0x00, 0x02, 0x00, 0x64, 0x00, // CALCCOUNT
+ 0x0f, 0x00, 0x02, 0x00, 0x01, 0x00, // REFMODE
+ 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, // ITERATION
+ 0x10, 0x00, 0x08, 0x00, 0xfc, 0xa9, 0xf1, 0xd2, 0x4d, // DELTA
+ 0x62, 0x50, 0x3f,
+ 0x5f, 0x00, 0x02, 0x00, 0x01, 0x00 // SAVERECALC
+};
+const sal_Size ExcDummy_02a::nMyLen = sizeof( ExcDummy_02a::pMyData );
+
+//----------------------------------------------------------- class ExcRecord -
+
+void ExcRecord::Save( XclExpStream& rStrm )
+{
+ SetRecHeader( GetNum(), GetLen() );
+ XclExpRecord::Save( rStrm );
+}
+
+void ExcRecord::SaveCont( XclExpStream& /*rStrm*/ )
+{
+}
+
+void ExcRecord::WriteBody( XclExpStream& rStrm )
+{
+ SaveCont( rStrm );
+}
+
+
+//--------------------------------------------------------- class ExcEmptyRec -
+
+void ExcEmptyRec::Save( XclExpStream& /*rStrm*/ )
+{
+}
+
+
+UINT16 ExcEmptyRec::GetNum() const
+{
+ return 0;
+}
+
+
+sal_Size ExcEmptyRec::GetLen() const
+{
+ return 0;
+}
+
+
+
+//------------------------------------------------------- class ExcRecordList -
+
+ExcRecordList::~ExcRecordList()
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ delete pRec;
+}
+
+
+void ExcRecordList::Save( XclExpStream& rStrm )
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ pRec->Save( rStrm );
+}
+
+
+
+//--------------------------------------------------------- class ExcDummyRec -
+
+void ExcDummyRec::Save( XclExpStream& rStrm )
+{
+ rStrm.Write( GetData(), GetLen() ); // raw write mode
+}
+
+
+UINT16 ExcDummyRec::GetNum( void ) const
+{
+ return 0x0000;
+}
+
+
+
+//------------------------------------------------------- class ExcBoolRecord -
+
+void ExcBoolRecord::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (UINT16)(bVal ? 0x0001 : 0x0000);
+}
+
+
+sal_Size ExcBoolRecord::GetLen( void ) const
+{
+ return 2;
+}
+
+
+
+
+//--------------------------------------------------------- class ExcBof_Base -
+
+ExcBof_Base::ExcBof_Base() :
+ nRupBuild( 0x096C ), // copied from Excel
+ nRupYear( 0x07C9 ) // copied from Excel
+{
+}
+
+
+
+//-------------------------------------------------------------- class ExcBof -
+
+ExcBof::ExcBof( void )
+{
+ nDocType = 0x0010;
+ nVers = 0x0500;
+}
+
+
+void ExcBof::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nVers << nDocType << nRupBuild << nRupYear;
+}
+
+
+UINT16 ExcBof::GetNum( void ) const
+{
+ return 0x0809;
+}
+
+
+sal_Size ExcBof::GetLen( void ) const
+{
+ return 8;
+}
+
+
+
+//------------------------------------------------------------- class ExcBofW -
+
+ExcBofW::ExcBofW( void )
+{
+ nDocType = 0x0005;
+ nVers = 0x0500;
+}
+
+
+void ExcBofW::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nVers << nDocType << nRupBuild << nRupYear;
+}
+
+
+
+UINT16 ExcBofW::GetNum( void ) const
+{
+ return 0x0809;
+}
+
+
+
+sal_Size ExcBofW::GetLen( void ) const
+{
+ return 8;
+}
+
+
+
+//-------------------------------------------------------------- class ExcEof -
+
+UINT16 ExcEof::GetNum( void ) const
+{
+ return 0x000A;
+}
+
+
+sal_Size ExcEof::GetLen( void ) const
+{
+ return 0;
+}
+
+
+
+//--------------------------------------------------------- class ExcDummy_00 -
+
+sal_Size ExcDummy_00::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy_00::GetData( void ) const
+{
+ return pMyData;
+}
+
+
+
+//-------------------------------------------------------- class ExcDummy_04x -
+
+sal_Size ExcDummy_040::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy_040::GetData( void ) const
+{
+ return pMyData;
+}
+
+
+
+
+sal_Size ExcDummy_041::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy_041::GetData( void ) const
+{
+ return pMyData;
+}
+
+
+
+//------------------------------------------------------------- class Exc1904 -
+
+Exc1904::Exc1904( ScDocument& rDoc )
+{
+ Date* pDate = rDoc.GetFormatTable()->GetNullDate();
+ bVal = pDate ? (*pDate == Date( 1, 1, 1904 )) : FALSE;
+}
+
+
+UINT16 Exc1904::GetNum( void ) const
+{
+ return 0x0022;
+}
+
+
+void Exc1904::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_date1904, XclXmlUtils::ToPsz( bVal ),
+ FSEND );
+}
+
+
+
+//------------------------------------------------------ class ExcBundlesheet -
+
+ExcBundlesheetBase::ExcBundlesheetBase( RootData& rRootData, SCTAB nTabNum ) :
+ nStrPos( STREAM_SEEK_TO_END ),
+ nOwnPos( STREAM_SEEK_TO_END ),
+ nGrbit( rRootData.pER->GetTabInfo().IsVisibleTab( nTabNum ) ? 0x0000 : 0x0001 ),
+ nTab( nTabNum )
+{
+}
+
+
+ExcBundlesheetBase::ExcBundlesheetBase() :
+ nStrPos( STREAM_SEEK_TO_END ),
+ nOwnPos( STREAM_SEEK_TO_END ),
+ nGrbit( 0x0000 ),
+ nTab( SCTAB_GLOBAL )
+{
+}
+
+
+void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
+{
+ rStrm.SetSvStreamPos( nOwnPos );
+ rStrm.DisableEncryption();
+ rStrm << static_cast<sal_uInt32>(nStrPos);
+ rStrm.EnableEncryption();
+}
+
+
+UINT16 ExcBundlesheetBase::GetNum( void ) const
+{
+ return 0x0085;
+}
+
+
+
+
+ExcBundlesheet::ExcBundlesheet( RootData& rRootData, SCTAB _nTab ) :
+ ExcBundlesheetBase( rRootData, _nTab )
+{
+ String sTabName = rRootData.pER->GetTabInfo().GetScTabName( _nTab );
+ DBG_ASSERT( sTabName.Len() < 256, "ExcBundlesheet::ExcBundlesheet - table name too long" );
+ aName = ByteString( sTabName, rRootData.pER->GetTextEncoding() );
+}
+
+
+void ExcBundlesheet::SaveCont( XclExpStream& rStrm )
+{
+ nOwnPos = rStrm.GetSvStreamPos();
+ rStrm << (UINT32) 0x00000000 // dummy (stream position of the sheet)
+ << nGrbit;
+ rStrm.WriteByteString( aName ); // 8 bit length, max 255 chars
+}
+
+
+sal_Size ExcBundlesheet::GetLen() const
+{
+ return 7 + Min( aName.Len(), (xub_StrLen) 255 );
+}
+
+
+//--------------------------------------------------------- class ExcDummy_02 -
+
+sal_Size ExcDummy_02a::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+const BYTE* ExcDummy_02a::GetData( void ) const
+{
+ return pMyData;
+}
+//--------------------------------------------------------- class ExcDummy_02 -
+
+XclExpCountry::XclExpCountry( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_COUNTRY, 4 )
+{
+ /* #i31530# set document country as UI country too -
+ needed for correct behaviour of number formats. */
+ mnUICountry = mnDocCountry = static_cast< sal_uInt16 >(
+ ::msfilter::ConvertLanguageToCountry( rRoot.GetDocLanguage() ) );
+}
+
+void XclExpCountry::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnUICountry << mnDocCountry;
+}
+
+// XclExpWsbool ===============================================================
+
+XclExpWsbool::XclExpWsbool( bool bFitToPages, SCTAB nScTab, XclExpFilterManager* pManager )
+ : XclExpUInt16Record( EXC_ID_WSBOOL, EXC_WSBOOL_DEFAULTFLAGS )
+ , mnScTab( nScTab )
+ , mpManager( pManager )
+{
+ if( bFitToPages )
+ SetValue( GetValue() | EXC_WSBOOL_FITTOPAGE );
+}
+
+void XclExpWsbool::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_sheetPr,
+ // OOXTODO: XML_syncHorizontal,
+ // OOXTODO: XML_syncVertical,
+ // OOXTODO: XML_syncRef,
+ // OOXTODO: XML_transitionEvaluation,
+ // OOXTODO: XML_transitionEntry,
+ // OOXTODO: XML_published,
+ // OOXTODO: XML_codeName,
+ XML_filterMode, mpManager ? XclXmlUtils::ToPsz( mpManager->HasFilterMode( mnScTab ) ) : NULL,
+ // OOXTODO: XML_enableFormatConditionsCalculation,
+ FSEND );
+ // OOXTODO: elements XML_tabColor, XML_outlinePr
+ rWorksheet->singleElement( XML_pageSetUpPr,
+ // OOXTODO: XML_autoPageBreaks,
+ XML_fitToPage, XclXmlUtils::ToPsz( GetValue() & EXC_WSBOOL_FITTOPAGE ),
+ FSEND );
+ rWorksheet->endElement( XML_sheetPr );
+}
+
+
+// XclExpWindowProtection ===============================================================
+
+XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
+ XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
+{
+}
+
+void XclExpWindowProtection::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_lockWindows, XclXmlUtils::ToPsz( GetBool() ),
+ FSEND );
+}
+
+// XclExpDocProtection ===============================================================
+
+XclExpProtection::XclExpProtection(bool bValue) :
+ XclExpBoolRecord(EXC_ID_PROTECT, bValue)
+{
+}
+
+// ============================================================================
+
+XclExpPassHash::XclExpPassHash(const Sequence<sal_Int8>& aHash) :
+ XclExpRecord(EXC_ID_PASSWORD, 2),
+ mnHash(0x0000)
+{
+ if (aHash.getLength() >= 2)
+ {
+ mnHash = ((aHash[0] << 8) & 0xFFFF);
+ mnHash |= (aHash[1] & 0xFF);
+ }
+}
+
+XclExpPassHash::~XclExpPassHash()
+{
+}
+
+void XclExpPassHash::WriteBody(XclExpStream& rStrm)
+{
+ rStrm << mnHash;
+}
+
+// ============================================================================
+
+XclExpFiltermode::XclExpFiltermode() :
+ XclExpEmptyRecord( EXC_ID_FILTERMODE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpAutofilterinfo::XclExpAutofilterinfo( const ScAddress& rStartPos, SCCOL nScCol ) :
+ XclExpUInt16Record( EXC_ID_AUTOFILTERINFO, static_cast< sal_uInt16 >( nScCol ) ),
+ maStartPos( rStartPos )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ExcFilterCondition::ExcFilterCondition() :
+ nType( EXC_AFTYPE_NOTUSED ),
+ nOper( EXC_AFOPER_EQUAL ),
+ fVal( 0.0 ),
+ pText( NULL )
+{
+}
+
+ExcFilterCondition::~ExcFilterCondition()
+{
+ if( pText )
+ delete pText;
+}
+
+sal_Size ExcFilterCondition::GetTextBytes() const
+{
+ return pText ? (1 + pText->GetBufferSize()) : 0;
+}
+
+void ExcFilterCondition::SetCondition( UINT8 nTp, UINT8 nOp, double fV, String* pT )
+{
+ nType = nTp;
+ nOper = nOp;
+ fVal = fV;
+
+ delete pText;
+ pText = pT ? new XclExpString( *pT, EXC_STR_8BITLENGTH ) : NULL;
+}
+
+void ExcFilterCondition::Save( XclExpStream& rStrm )
+{
+ rStrm << nType << nOper;
+ switch( nType )
+ {
+ case EXC_AFTYPE_DOUBLE:
+ rStrm << fVal;
+ break;
+ case EXC_AFTYPE_STRING:
+ DBG_ASSERT( pText, "ExcFilterCondition::Save() -- pText is NULL!" );
+ rStrm << (UINT32)0 << (UINT8) pText->Len() << (UINT16)0 << (UINT8)0;
+ break;
+ case EXC_AFTYPE_BOOLERR:
+ rStrm << (UINT8)0 << (UINT8)((fVal != 0) ? 1 : 0) << (UINT32)0 << (UINT16)0;
+ break;
+ default:
+ rStrm << (UINT32)0 << (UINT32)0;
+ }
+}
+
+static const char* lcl_GetOperator( UINT8 nOper )
+{
+ switch( nOper )
+ {
+ case EXC_AFOPER_EQUAL: return "equal";
+ case EXC_AFOPER_GREATER: return "greaterThan";
+ case EXC_AFOPER_GREATEREQUAL: return "greaterThanOrEqual";
+ case EXC_AFOPER_LESS: return "lessThan";
+ case EXC_AFOPER_LESSEQUAL: return "lessThanOrEqual";
+ case EXC_AFOPER_NOTEQUAL: return "notEqual";
+ case EXC_AFOPER_NONE:
+ default: return "**none**";
+ }
+}
+
+static OString lcl_GetValue( UINT8 nType, double fVal, XclExpString* pStr )
+{
+ switch( nType )
+ {
+ case EXC_AFTYPE_STRING: return XclXmlUtils::ToOString( *pStr );
+ case EXC_AFTYPE_DOUBLE: return OString::valueOf( fVal );
+ case EXC_AFTYPE_BOOLERR: return OString::valueOf( (sal_Int32) ( fVal != 0 ? 1 : 0 ) );
+ default: return OString();
+ }
+}
+
+void ExcFilterCondition::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( IsEmpty() )
+ return;
+
+ rStrm.GetCurrentStream()->singleElement( XML_customFilter,
+ XML_operator, lcl_GetOperator( nOper ),
+ XML_val, lcl_GetValue( nType, fVal, pText ).getStr(),
+ FSEND );
+}
+
+void ExcFilterCondition::SaveText( XclExpStream& rStrm )
+{
+ if( nType == EXC_AFTYPE_STRING )
+ {
+ DBG_ASSERT( pText, "ExcFilterCondition::SaveText() -- pText is NULL!" );
+ pText->WriteFlagField( rStrm );
+ pText->WriteBuffer( rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, UINT16 nC ) :
+ XclExpRecord( EXC_ID_AUTOFILTER, 24 ),
+ XclExpRoot( rRoot ),
+ nCol( nC ),
+ nFlags( 0 )
+{
+}
+
+BOOL XclExpAutofilter::AddCondition( ScQueryConnect eConn, UINT8 nType, UINT8 nOp,
+ double fVal, String* pText, BOOL bSimple )
+{
+ if( !aCond[ 1 ].IsEmpty() )
+ return FALSE;
+
+ UINT16 nInd = aCond[ 0 ].IsEmpty() ? 0 : 1;
+
+ if( nInd == 1 )
+ nFlags |= (eConn == SC_OR) ? EXC_AFFLAG_OR : EXC_AFFLAG_AND;
+ if( bSimple )
+ nFlags |= (nInd == 0) ? EXC_AFFLAG_SIMPLE1 : EXC_AFFLAG_SIMPLE2;
+
+ aCond[ nInd ].SetCondition( nType, nOp, fVal, pText );
+
+ AddRecSize( aCond[ nInd ].GetTextBytes() );
+
+ return TRUE;
+}
+
+BOOL XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
+{
+ BOOL bConflict = FALSE;
+ String sText;
+
+ if( rEntry.pStr )
+ {
+ sText.Assign( *rEntry.pStr );
+ switch( rEntry.eOp )
+ {
+ case SC_CONTAINS:
+ case SC_DOES_NOT_CONTAIN:
+ {
+ sText.InsertAscii( "*" , 0 );
+ sText.AppendAscii( "*" );
+ }
+ break;
+ case SC_BEGINS_WITH:
+ case SC_DOES_NOT_BEGIN_WITH:
+ sText.AppendAscii( "*" );
+ break;
+ case SC_ENDS_WITH:
+ case SC_DOES_NOT_END_WITH:
+ sText.InsertAscii( "*" , 0 );
+ break;
+ default:
+ {
+ //nothing
+ }
+ }
+ }
+
+ BOOL bLen = sText.Len() > 0;
+
+ // empty/nonempty fields
+ if( !bLen && (rEntry.nVal == SC_EMPTYFIELDS) )
+ bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, NULL, TRUE );
+ else if( !bLen && (rEntry.nVal == SC_NONEMPTYFIELDS) )
+ bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, NULL, TRUE );
+ // other conditions
+ else
+ {
+ double fVal = 0.0;
+ sal_uInt32 nIndex = 0;
+ BOOL bIsNum = bLen ? GetFormatter().IsNumberFormat( sText, nIndex, fVal ) : TRUE;
+ String* pText = bIsNum ? NULL : &sText;
+
+ // top10 flags
+ UINT16 nNewFlags = 0x0000;
+ switch( rEntry.eOp )
+ {
+ case SC_TOPVAL:
+ nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP);
+ break;
+ case SC_BOTVAL:
+ nNewFlags = EXC_AFFLAG_TOP10;
+ break;
+ case SC_TOPPERC:
+ nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP | EXC_AFFLAG_TOP10PERC);
+ break;
+ case SC_BOTPERC:
+ nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10PERC);
+ break;
+ default:;
+ }
+ BOOL bNewTop10 = ::get_flag( nNewFlags, EXC_AFFLAG_TOP10 );
+
+ bConflict = HasTop10() && bNewTop10;
+ if( !bConflict )
+ {
+ if( bNewTop10 )
+ {
+ if( fVal < 0 ) fVal = 0;
+ if( fVal >= 501 ) fVal = 500;
+ nFlags |= (nNewFlags | (UINT16)(fVal) << 7);
+ }
+ // normal condition
+ else
+ {
+ UINT8 nType = bIsNum ? EXC_AFTYPE_DOUBLE : EXC_AFTYPE_STRING;
+ UINT8 nOper = EXC_AFOPER_NONE;
+
+ switch( rEntry.eOp )
+ {
+ case SC_EQUAL: nOper = EXC_AFOPER_EQUAL; break;
+ case SC_LESS: nOper = EXC_AFOPER_LESS; break;
+ case SC_GREATER: nOper = EXC_AFOPER_GREATER; break;
+ case SC_LESS_EQUAL: nOper = EXC_AFOPER_LESSEQUAL; break;
+ case SC_GREATER_EQUAL: nOper = EXC_AFOPER_GREATEREQUAL; break;
+ case SC_NOT_EQUAL: nOper = EXC_AFOPER_NOTEQUAL; break;
+ case SC_CONTAINS:
+ case SC_BEGINS_WITH:
+ case SC_ENDS_WITH:
+ nOper = EXC_AFOPER_EQUAL; break;
+ case SC_DOES_NOT_CONTAIN:
+ case SC_DOES_NOT_BEGIN_WITH:
+ case SC_DOES_NOT_END_WITH:
+ nOper = EXC_AFOPER_NOTEQUAL; break;
+ default:;
+ }
+ bConflict = !AddCondition( rEntry.eConnect, nType, nOper, fVal, pText );
+ }
+ }
+ }
+ return bConflict;
+}
+
+void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << nCol << nFlags;
+ aCond[ 0 ].Save( rStrm );
+ aCond[ 1 ].Save( rStrm );
+ aCond[ 0 ].SaveText( rStrm );
+ aCond[ 1 ].SaveText( rStrm );
+}
+
+void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !HasCondition() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+
+ rWorksheet->startElement( XML_filterColumn,
+ XML_colId, OString::valueOf( (sal_Int32) nCol ).getStr(),
+ // OOXTODO: XML_hiddenButton, AutoFilter12 fHideArrow?
+ // OOXTODO: XML_showButton,
+ FSEND );
+
+ if( HasTop10() )
+ {
+ rWorksheet->singleElement( XML_top10,
+ XML_top, XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10TOP ) ),
+ XML_percent, XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10PERC ) ),
+ XML_val, OString::valueOf( (sal_Int32) (nFlags >> 7 ) ).getStr(),
+ // OOXTODO: XML_filterVal,
+ FSEND );
+ }
+
+ rWorksheet->startElement( XML_customFilters,
+ XML_and, XclXmlUtils::ToPsz( (nFlags & EXC_AFFLAG_ANDORMASK) == EXC_AFFLAG_AND ),
+ FSEND );
+ aCond[ 0 ].SaveXml( rStrm );
+ aCond[ 1 ].SaveXml( rStrm );
+ rWorksheet->endElement( XML_customFilters );
+ // OOXTODO: XLM_colorFilter, XML_dynamicFilter,
+ // XML_extLst, XML_filters, XML_iconFilter, XML_top10
+ rWorksheet->endElement( XML_filterColumn );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab ) :
+ XclExpRoot( rRoot ),
+ pFilterMode( NULL ),
+ pFilterInfo( NULL )
+{
+ ScDBCollection& rDBColl = GetDatabaseRanges();
+ XclExpNameManager& rNameMgr = GetNameManager();
+
+ // search for first DB-range with filter
+ UINT16 nIndex = 0;
+ BOOL bFound = FALSE;
+ BOOL bAdvanced = FALSE;
+ ScDBData* pData = NULL;
+ ScRange aAdvRange;
+ while( (nIndex < rDBColl.GetCount()) && !bFound )
+ {
+ pData = rDBColl[ nIndex ];
+ if( pData )
+ {
+ ScRange aRange;
+ pData->GetArea( aRange );
+ bAdvanced = pData->GetAdvancedQuerySource( aAdvRange );
+ bFound = (aRange.aStart.Tab() == nTab) &&
+ (pData->HasQueryParam() || pData->HasAutoFilter() || bAdvanced);
+ }
+ if( !bFound )
+ nIndex++;
+ }
+
+ if( pData && bFound )
+ {
+ ScQueryParam aParam;
+ pData->GetQueryParam( aParam );
+
+ ScRange aRange( aParam.nCol1, aParam.nRow1, aParam.nTab,
+ aParam.nCol2, aParam.nRow2, aParam.nTab );
+ SCCOL nColCnt = aParam.nCol2 - aParam.nCol1 + 1;
+
+ maRef = aRange;
+
+ // #i2394# #100489# built-in defined names must be sorted by containing sheet name
+ rNameMgr.InsertBuiltInName( EXC_BUILTIN_FILTERDATABASE, aRange );
+
+ // advanced filter
+ if( bAdvanced )
+ {
+ // filter criteria, excel allows only same table
+ if( aAdvRange.aStart.Tab() == nTab )
+ rNameMgr.InsertBuiltInName( EXC_BUILTIN_CRITERIA, aAdvRange );
+
+ // filter destination range, excel allows only same table
+ if( !aParam.bInplace )
+ {
+ ScRange aDestRange( aParam.nDestCol, aParam.nDestRow, aParam.nDestTab );
+ aDestRange.aEnd.IncCol( nColCnt - 1 );
+ if( aDestRange.aStart.Tab() == nTab )
+ rNameMgr.InsertBuiltInName( EXC_BUILTIN_EXTRACT, aDestRange );
+ }
+
+ pFilterMode = new XclExpFiltermode;
+ }
+ // AutoFilter
+ else
+ {
+ BOOL bConflict = FALSE;
+ BOOL bContLoop = TRUE;
+ BOOL bHasOr = FALSE;
+ SCCOLROW nFirstField = aParam.GetEntry( 0 ).nField;
+
+ // create AUTOFILTER records for filtered columns
+ for( SCSIZE nEntry = 0; !bConflict && bContLoop && (nEntry < aParam.GetEntryCount()); nEntry++ )
+ {
+ const ScQueryEntry& rEntry = aParam.GetEntry( nEntry );
+
+ bContLoop = rEntry.bDoQuery;
+ if( bContLoop )
+ {
+ XclExpAutofilter* pFilter = GetByCol( static_cast<SCCOL>(rEntry.nField) - aRange.aStart.Col() );
+
+ if( nEntry > 0 )
+ bHasOr |= (rEntry.eConnect == SC_OR);
+
+ bConflict = (nEntry > 1) && bHasOr;
+ if( !bConflict )
+ bConflict = (nEntry == 1) && (rEntry.eConnect == SC_OR) &&
+ (nFirstField != rEntry.nField);
+ if( !bConflict )
+ bConflict = pFilter->AddEntry( rEntry );
+ }
+ }
+
+ // additional tests for conflicts
+ for( size_t nPos = 0, nSize = maFilterList.GetSize(); !bConflict && (nPos < nSize); ++nPos )
+ {
+ XclExpAutofilterRef xFilter = maFilterList.GetRecord( nPos );
+ bConflict = xFilter->HasCondition() && xFilter->HasTop10();
+ }
+
+ if( bConflict )
+ maFilterList.RemoveAllRecords();
+
+ if( !maFilterList.IsEmpty() )
+ pFilterMode = new XclExpFiltermode;
+ pFilterInfo = new XclExpAutofilterinfo( aRange.aStart, nColCnt );
+ }
+ }
+}
+
+ExcAutoFilterRecs::~ExcAutoFilterRecs()
+{
+ delete pFilterMode;
+ delete pFilterInfo;
+}
+
+XclExpAutofilter* ExcAutoFilterRecs::GetByCol( SCCOL nCol )
+{
+ XclExpAutofilterRef xFilter;
+ for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
+ {
+ xFilter = maFilterList.GetRecord( nPos );
+ if( xFilter->GetCol() == static_cast<sal_uInt16>(nCol) )
+ return xFilter.get();
+ }
+ xFilter.reset( new XclExpAutofilter( GetRoot(), static_cast<sal_uInt16>(nCol) ) );
+ maFilterList.AppendRecord( xFilter );
+ return xFilter.get();
+}
+
+BOOL ExcAutoFilterRecs::IsFiltered( SCCOL nCol )
+{
+ for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
+ if( maFilterList.GetRecord( nPos )->GetCol() == static_cast<sal_uInt16>(nCol) )
+ return TRUE;
+ return FALSE;
+}
+
+void ExcAutoFilterRecs::AddObjRecs()
+{
+ if( pFilterInfo )
+ {
+ ScAddress aAddr( pFilterInfo->GetStartPos() );
+ for( SCCOL nObj = 0, nCount = pFilterInfo->GetColCount(); nObj < nCount; nObj++ )
+ {
+ XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) );
+ GetObjectManager().AddObj( pObjRec );
+ aAddr.IncCol( 1 );
+ }
+ }
+}
+
+void ExcAutoFilterRecs::Save( XclExpStream& rStrm )
+{
+ if( pFilterMode )
+ pFilterMode->Save( rStrm );
+ if( pFilterInfo )
+ pFilterInfo->Save( rStrm );
+ maFilterList.Save( rStrm );
+}
+
+void ExcAutoFilterRecs::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maFilterList.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_autoFilter,
+ XML_ref, XclXmlUtils::ToOString( maRef ).getStr(),
+ FSEND );
+ // OOXTODO: XML_extLst, XML_sortState
+ maFilterList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_autoFilter );
+}
+
+bool ExcAutoFilterRecs::HasFilterMode() const
+{
+ return pFilterMode != NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpFilterManager::XclExpFilterManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpFilterManager::InitTabFilter( SCTAB nScTab )
+{
+ maFilterMap[ nScTab ].reset( new ExcAutoFilterRecs( GetRoot(), nScTab ) );
+}
+
+XclExpRecordRef XclExpFilterManager::CreateRecord( SCTAB nScTab )
+{
+ XclExpTabFilterRef xRec;
+ XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
+ if( aIt != maFilterMap.end() )
+ {
+ xRec = aIt->second;
+ xRec->AddObjRecs();
+ }
+ return xRec;
+}
+
+bool XclExpFilterManager::HasFilterMode( SCTAB nScTab )
+{
+ XclExpTabFilterRef xRec;
+ XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
+ if( aIt != maFilterMap.end() )
+ {
+ return aIt->second->HasFilterMode();
+ }
+ return false;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/exctools.cxx b/sc/source/filter/excel/exctools.cxx
new file mode 100644
index 000000000000..e6453c2f11e2
--- /dev/null
+++ b/sc/source/filter/excel/exctools.cxx
@@ -0,0 +1,434 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+
+#include "document.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
+#include "scextopt.hxx"
+#include "progress.hxx"
+#include "rangenam.hxx"
+#include "editutil.hxx"
+
+#include "excrecds.hxx"
+#include "root.hxx"
+#include "imp_op.hxx"
+#include "excimp8.hxx"
+#include "otlnbuff.hxx"
+#include "xcl97rec.hxx"
+#include "formel.hxx"
+#include "xilink.hxx"
+#include "xecontent.hxx"
+
+// - ALLGEMEINE ----------------------------------------------------------
+
+RootData::RootData( void )
+{
+ eDateiTyp = BiffX;
+ pExtSheetBuff = NULL;
+ pShrfmlaBuff = NULL;
+ pExtNameBuff = NULL;
+ pFmlaConverter = NULL;
+
+ pAutoFilterBuffer = NULL;
+ pPrintRanges = new _ScRangeListTabs;
+ pPrintTitles = new _ScRangeListTabs;
+
+ pTabId = NULL;
+ pUserBViewList = NULL;
+
+ pIR = NULL;
+ pER = NULL;
+}
+
+RootData::~RootData()
+{
+ delete pExtSheetBuff;
+ delete pShrfmlaBuff;
+ delete pExtNameBuff;
+ delete pAutoFilterBuffer;
+ delete pPrintRanges;
+ delete pPrintTitles;
+}
+
+
+
+
+XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize )
+{
+ DBG_ASSERT( nNewSize > 0, "-OutlineBuffer::Ctor: nNewSize == 0!" );
+
+ nSize = nNewSize + 1;
+ pLevel = new BYTE[ nSize ];
+ pOuted = new BOOL[ nSize ];
+ pHidden = new BOOL[ nSize ];
+ pOutlineArray = NULL;
+
+ Reset();
+}
+
+
+XclImpOutlineBuffer::~XclImpOutlineBuffer()
+{
+ delete[] pLevel;
+ delete[] pOuted;
+ delete[] pHidden;
+}
+
+
+void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, BYTE nVal, BOOL bOuted, BOOL bHidden )
+{
+ if( nIndex < nSize )
+ {
+ pLevel[ nIndex ] = nVal;
+ pOuted[ nIndex ] = bOuted;
+ pHidden[ nIndex ] = bHidden;
+
+ if( nIndex > nLast )
+ nLast = nIndex;
+ if( nVal > nMaxLevel )
+ nMaxLevel = nVal;
+ }
+}
+
+
+void XclImpOutlineBuffer::SetOutlineArray( ScOutlineArray* pOArray )
+{
+ pOutlineArray = pOArray;
+}
+
+
+// transtorm xcl-outline into SC-outline
+void XclImpOutlineBuffer::MakeScOutline( void )
+{
+ if( !pOutlineArray || !HasOutline() )
+ return;
+
+ const UINT16 nNumLev = 8;
+ BOOL bPreOutedLevel = FALSE;
+ BYTE nCurrLevel = 0;
+ BOOL bMakeHidden[ nNumLev ];
+ BOOL bMakeVisible[ nNumLev + 1 ];
+
+ sal_uInt16 nLevel;
+ for( nLevel = 0; nLevel < nNumLev; ++nLevel )
+ bMakeHidden[ nLevel ] = FALSE;
+ for( nLevel = 0; nLevel <= nNumLev; ++nLevel )
+ bMakeVisible[ nLevel ] = TRUE;
+ if( nLast < (nSize - 1) )
+ nLast++;
+
+ // search for hidden attributes at end of level, move them to begin
+ if( bButtonNormal )
+ {
+ for( BYTE nWorkLevel = 1; nWorkLevel <= nMaxLevel; nWorkLevel++ )
+ {
+ UINT16 nStartPos = 0;
+ BYTE nCurrLevel2 = 0;
+ BYTE nPrevLevel = 0;
+
+ for( SCSIZE nC = 0 ; nC <= nLast ; nC++ )
+ {
+ nPrevLevel = nCurrLevel2;
+ nCurrLevel2 = pLevel[ nC ];
+ if( (nPrevLevel < nWorkLevel) && (nCurrLevel2 >= nWorkLevel) )
+ nStartPos = static_cast< sal_uInt16 >( nC );
+ else if( (nPrevLevel >= nWorkLevel) && (nCurrLevel2 < nWorkLevel) )
+ {
+ if( pOuted[ nC ] && pHidden[ nStartPos ] )
+ {
+ if( nStartPos )
+ pOuted[ nStartPos - 1 ] = TRUE;
+ else
+ bPreOutedLevel = TRUE;
+ pOuted[ nC ] = FALSE;
+ }
+ }
+ }
+ }
+ }
+ else
+ bPreOutedLevel = pHidden[ 0 ];
+
+ // generate SC outlines
+ UINT16 nPrevC;
+ UINT16 nStart[ nNumLev ];
+ BOOL bDummy;
+ BOOL bPrevOuted = bPreOutedLevel;
+ BOOL bCurrHidden = FALSE;
+ BOOL bPrevHidden = FALSE;
+
+ for( SCSIZE nC = 0; nC <= nLast; nC++ )
+ {
+ BYTE nWorkLevel = pLevel[ nC ];
+
+ nPrevC = static_cast< sal_uInt16 >( nC ? nC - 1 : 0 );
+ bPrevHidden = bCurrHidden;
+ bCurrHidden = pHidden[ nC ];
+
+ // open new levels
+ while( nWorkLevel > nCurrLevel )
+ {
+ nCurrLevel++;
+ bMakeHidden[ nCurrLevel ] = bPrevOuted;
+ bMakeVisible[ nCurrLevel + 1 ] =
+ bMakeVisible[ nCurrLevel ] && !bMakeHidden[ nCurrLevel ];
+ nStart[ nCurrLevel ] = static_cast< sal_uInt16 >( nC );
+ }
+ // close levels
+ while( nWorkLevel < nCurrLevel )
+ {
+ BOOL bLastLevel = (nWorkLevel == (nCurrLevel - 1));
+ BOOL bRealHidden = (bMakeHidden[ nCurrLevel ] && bPrevHidden );
+ BOOL bRealVisible = (bMakeVisible[ nCurrLevel ] ||
+ (!bCurrHidden && bLastLevel));
+
+ pOutlineArray->Insert( nStart[ nCurrLevel ], nPrevC , bDummy,
+ bRealHidden, bRealVisible );
+ nCurrLevel--;
+ }
+
+ bPrevOuted = pOuted[ nC ];
+ }
+}
+
+
+void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, BYTE nVal,
+ BOOL bOuted, BOOL bHidden )
+{
+ DBG_ASSERT( nF <= nL, "+OutlineBuffer::SetLevelRange(): Last < First!" );
+
+ if( nL < nSize )
+ {
+ if( nL > nLast )
+ nLast = nL;
+
+ BYTE* pLevelCount;
+ BYTE* pLast;
+ BOOL* pOutedCount;
+ BOOL* pHiddenCount;
+
+ pLevelCount = &pLevel[ nF ];
+ pLast = &pLevel[ nL ];
+ pOutedCount = &pOuted[ nF ];
+ pHiddenCount = &pHidden[ nF ];
+
+ while( pLevelCount <= pLast )
+ {
+ *( pLevelCount++ ) = nVal;
+ *( pOutedCount++ ) = bOuted;
+ *( pHiddenCount++ ) = bHidden;
+ }
+
+ if( nVal > nMaxLevel )
+ nMaxLevel = nVal;
+ }
+}
+
+
+void XclImpOutlineBuffer::Reset( void )
+{
+ for( SCSIZE nC = 0 ; nC < nSize ; nC++ )
+ {
+ pLevel[ nC ] = 0;
+ pOuted[ nC ] = pHidden[ nC ] = FALSE;
+ }
+ nLast = 0;
+ nMaxLevel = 0;
+}
+
+
+//___________________________________________________________________
+
+
+ExcScenarioCell::ExcScenarioCell( const UINT16 nC, const UINT16 nR ) : nCol( nC ), nRow( nR )
+{
+}
+
+
+void ExcScenarioCell::SetValue( const String& r )
+{
+ aValue = r;
+}
+
+
+
+
+#define EXCSCAPPEND(EXCSCCELL) (List::Insert(EXCSCCELL,LIST_APPEND))
+#define EXCSCFIRST() ((ExcScenarioCell*)List::First())
+#define EXCSCNEXT() ((ExcScenarioCell*)List::Next())
+
+
+ExcScenario::ExcScenario( XclImpStream& rIn, const RootData& rR ) : nTab( rR.pIR->GetCurrScTab() )
+{
+ UINT16 nCref;
+ UINT8 nName, nComment;
+
+ rIn >> nCref;
+ rIn >> nProtected;
+ rIn.Ignore( 1 ); // Hide
+ rIn >> nName >> nComment;
+ rIn.Ignore( 1 ); // statt nUser!
+
+ if( nName )
+ pName = new String( rIn.ReadUniString( nName ) );
+ else
+ {
+ pName = new String( RTL_CONSTASCII_USTRINGPARAM( "Scenery" ) );
+ rIn.Ignore( 1 );
+ }
+
+ pUserName = new String( rIn.ReadUniString() );
+
+ if( nComment )
+ pComment = new String( rIn.ReadUniString() );
+ else
+ pComment = new String;
+
+ UINT16 n = nCref;
+ UINT16 nC, nR;
+ while( n )
+ {
+ rIn >> nR >> nC;
+
+ EXCSCAPPEND( new ExcScenarioCell( nC, nR ) );
+
+ n--;
+ }
+
+ n = nCref;
+ ExcScenarioCell* p = EXCSCFIRST();
+ while( p )
+ {
+ p->SetValue( rIn.ReadUniString() );
+
+ p = EXCSCNEXT();
+ }
+}
+
+
+ExcScenario::~ExcScenario()
+{
+ ExcScenarioCell* p = EXCSCFIRST();
+
+ while( p )
+ {
+ delete p;
+ p = EXCSCNEXT();
+ }
+
+ if( pName )
+ delete pName;
+ if( pComment )
+ delete pComment;
+ if( pUserName )
+ delete pUserName;
+}
+
+
+void ExcScenario::Apply( const XclImpRoot& rRoot, const BOOL bLast )
+{
+ ScDocument& r = rRoot.GetDoc();
+ ExcScenarioCell* p = EXCSCFIRST();
+ String aSzenName( *pName );
+ UINT16 nNewTab = nTab + 1;
+
+ if( !r.InsertTab( nNewTab, aSzenName ) )
+ return;
+
+ r.SetScenario( nNewTab, TRUE );
+ // #112621# do not show scenario frames
+ r.SetScenarioData( nNewTab, *pComment, COL_LIGHTGRAY, /*SC_SCENARIO_SHOWFRAME|*/SC_SCENARIO_COPYALL|(nProtected ? SC_SCENARIO_PROTECT : 0) );
+
+ while( p )
+ {
+ UINT16 nCol = p->nCol;
+ UINT16 nRow = p->nRow;
+ String aVal = p->GetValue();
+
+ r.ApplyFlagsTab( nCol, nRow, nCol, nRow, nNewTab, SC_MF_SCENARIO );
+
+ r.SetString( nCol, nRow, nNewTab, aVal );
+
+ p = EXCSCNEXT();
+ }
+
+ if( bLast )
+ r.SetActiveScenario( nNewTab, TRUE );
+
+ // #111896# modify what the Active tab is set to if the new
+ // scenario tab occurs before the active tab.
+ ScExtDocSettings& rDocSett = rRoot.GetExtDocOptions().GetDocSettings();
+ if( (static_cast< SCCOL >( nTab ) < rDocSett.mnDisplTab) && (rDocSett.mnDisplTab < MAXTAB) )
+ ++rDocSett.mnDisplTab;
+ rRoot.GetTabInfo().InsertScTab( nNewTab );
+}
+
+
+
+
+ExcScenarioList::~ExcScenarioList()
+{
+ ExcScenario* p = _First();
+
+ while( p )
+ {
+ delete p;
+ p = _Next();
+ }
+}
+
+
+void ExcScenarioList::Apply( const XclImpRoot& rRoot )
+{
+ ExcScenario* p = _Last();
+ UINT16 n = ( UINT16 ) Count();
+
+ while( p )
+ {
+ n--;
+ p->Apply( rRoot, ( BOOL ) ( n == nLastScenario ) );
+ p = _Prev();
+ }
+}
+
+
diff --git a/sc/source/filter/excel/expop2.cxx b/sc/source/filter/excel/expop2.cxx
new file mode 100644
index 000000000000..dbe70ae6a0ee
--- /dev/null
+++ b/sc/source/filter/excel/expop2.cxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <unotools/fltrcfg.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/docinf.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+
+#include "scerrors.hxx"
+#include "scextopt.hxx"
+
+#include "root.hxx"
+#include "excdoc.hxx"
+#include "exp_op.hxx"
+
+#include "xcl97esc.hxx"
+
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "filtopt.hxx"
+#include "xltools.hxx"
+#include "xelink.hxx"
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+
+ExportBiff5::ExportBiff5( XclExpRootData& rExpData, SvStream& rStrm ):
+ ExportTyp( rStrm, &rExpData.mrDoc, rExpData.meTextEnc ),
+ XclExpRoot( rExpData )
+{
+ // nur Teil der Root-Daten gebraucht
+ pExcRoot = &GetOldRoot();
+ pExcRoot->pER = this; // ExcRoot -> XclExpRoot
+ pExcRoot->eDateiTyp = Biff5;
+ pExcDoc = new ExcDocument( *this );
+}
+
+
+ExportBiff5::~ExportBiff5()
+{
+ delete pExcDoc;
+}
+
+
+FltError ExportBiff5::Write()
+{
+ SfxObjectShell* pDocShell = GetDocShell();
+ DBG_ASSERT( pDocShell, "ExportBiff5::Write - no document shell" );
+
+ SotStorageRef xRootStrg = GetRootStorage();
+ DBG_ASSERT( xRootStrg.Is(), "ExportBiff5::Write - no root storage" );
+
+ bool bWriteBasicCode = false;
+ bool bWriteBasicStrg = false;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
+ {
+ bWriteBasicCode = pFilterOpt->IsLoadExcelBasicCode();
+ bWriteBasicStrg = pFilterOpt->IsLoadExcelBasicStorage();
+ }
+ }
+
+ if( pDocShell && xRootStrg.Is() && bWriteBasicStrg )
+ {
+ SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
+ ULONG nErr = aBasicImport.SaveOrDelMSVBAStorage( TRUE, EXC_STORAGE_VBA_PROJECT );
+ if( nErr != ERRCODE_NONE )
+ pDocShell->SetError( nErr, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ pExcDoc->ReadDoc(); // ScDoc -> ExcDoc
+ pExcDoc->Write( aOut ); // wechstreamen
+
+ if( pDocShell && xRootStrg.Is() )
+ {
+ // #i88642# update doc info (revision etc)
+ pDocShell->UpdateDocInfoForSave();
+
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ if ( SvtFilterOptions::Get()->IsEnableCalcPreview() )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ pDocShell->GetPreviewMetaFile (sal_False);
+ uno::Sequence<sal_uInt8> metaFile(
+ sfx2::convertMetaFile(pMetaFile.get()));
+ sfx2::SaveOlePropertySet(xDocProps, xRootStrg, &metaFile);
+ }
+ else
+ sfx2::SaveOlePropertySet(xDocProps, xRootStrg );
+ }
+
+ //! TODO: separate warnings for columns and sheets
+ const XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsColTruncated() || rAddrConv.IsRowTruncated() || rAddrConv.IsTabTruncated() )
+ return SCWARN_EXPORT_MAXROW;
+
+ return eERR_OK;
+}
+
+
+
+ExportBiff8::ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm ) :
+ ExportBiff5( rExpData, rStrm )
+{
+ pExcRoot->eDateiTyp = Biff8;
+}
+
+
+ExportBiff8::~ExportBiff8()
+{
+}
+
+
+ExportXml2007::ExportXml2007( XclExpRootData& rExpData, SvStream& rStrm )
+ : ExportTyp( rStrm, &rExpData.mrDoc, rExpData.meTextEnc )
+ , XclExpRoot( rExpData )
+{
+ pExcRoot = &GetOldRoot();
+ pExcRoot->pER = this;
+ pExcRoot->eDateiTyp = Biff8;
+ pExcDoc = new ExcDocument( *this );
+}
+
+
+ExportXml2007::~ExportXml2007()
+{
+ delete pExcDoc;
+}
+
+
+FltError ExportXml2007::Write()
+{
+ SfxObjectShell* pDocShell = GetDocShell();
+ DBG_ASSERT( pDocShell, "ExportXml2007::Write - no document shell" );
+
+ SotStorageRef xRootStrg = GetRootStorage();
+ DBG_ASSERT( xRootStrg.Is(), "ExportXml2007::Write - no root storage" );
+
+ bool bWriteBasicCode = false;
+ bool bWriteBasicStrg = false;
+
+ if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
+ {
+ bWriteBasicCode = pFilterOpt->IsLoadExcelBasicCode();
+ bWriteBasicStrg = pFilterOpt->IsLoadExcelBasicStorage();
+ }
+
+ if( pDocShell && xRootStrg.Is() && bWriteBasicStrg )
+ {
+ SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
+ ULONG nErr = aBasicImport.SaveOrDelMSVBAStorage( TRUE, EXC_STORAGE_VBA_PROJECT );
+ if( nErr != ERRCODE_NONE )
+ pDocShell->SetError( nErr, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ pExcDoc->ReadDoc(); // ScDoc -> ExcDoc
+ pExcDoc->WriteXml( aOut ); // wechstreamen
+
+ if( pDocShell && xRootStrg.Is() )
+ {
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ pDocShell->GetPreviewMetaFile (sal_False);
+ uno::Sequence<sal_uInt8> metaFile(
+ sfx2::convertMetaFile(pMetaFile.get()));
+ sfx2::SaveOlePropertySet(xDocProps, xRootStrg, &metaFile);
+ }
+
+ //! TODO: separate warnings for columns and sheets
+ const XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsColTruncated() || rAddrConv.IsRowTruncated() || rAddrConv.IsTabTruncated() )
+ return SCWARN_EXPORT_MAXROW;
+
+ return eERR_OK;
+}
+
+
diff --git a/sc/source/filter/excel/fontbuff.cxx b/sc/source/filter/excel/fontbuff.cxx
new file mode 100644
index 000000000000..dca6723181ae
--- /dev/null
+++ b/sc/source/filter/excel/fontbuff.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "lotfntbf.hxx"
+
+#include "scitems.hxx"
+#include <editeng/cntritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <sfx2/printer.hxx>
+
+#include "attrib.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "ftools.hxx"
+
+const UINT16 LotusFontBuffer::nSize = 8;
+
+void LotusFontBuffer::Fill( const UINT8 nIndex, SfxItemSet& rItemSet )
+{
+ UINT8 nIntIndex = nIndex & 0x07;
+
+ ENTRY* pAkt = pData + nIntIndex;
+
+ if( pAkt->pFont )
+ rItemSet.Put( *pAkt->pFont );
+
+ if( pAkt->pHeight )
+ rItemSet.Put( *pAkt->pHeight );
+
+ if( pAkt->pColor )
+ rItemSet.Put( *pAkt->pColor );
+
+ if( nIndex & 0x08 )
+ {
+ SvxWeightItem aWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT );
+ rItemSet.Put( aWeightItem );
+ }
+
+ if( nIndex & 0x10 )
+ {
+ SvxPostureItem aAttr( ITALIC_NORMAL, ATTR_FONT_POSTURE );
+ rItemSet.Put( aAttr );
+ }
+
+ FontUnderline eUnderline;
+ switch( nIndex & 0x60 ) // Bit 5+6
+ {
+ case 0x60:
+ case 0x20: eUnderline = UNDERLINE_SINGLE; break;
+ case 0x40: eUnderline = UNDERLINE_DOUBLE; break;
+ default: eUnderline = UNDERLINE_NONE;
+ }
+ if( eUnderline != UNDERLINE_NONE )
+ {
+ SvxUnderlineItem aUndItem( eUnderline, ATTR_FONT_UNDERLINE );
+ rItemSet.Put( aUndItem );
+ }
+}
+
+
+void LotusFontBuffer::SetName( const UINT16 nIndex, const String& rName )
+{
+ DBG_ASSERT( nIndex < nSize, "*LotusFontBuffer::SetName(): Array zu klein!" );
+ if( nIndex < nSize )
+ {
+ register ENTRY* pEntry = pData + nIndex;
+ pEntry->TmpName( rName );
+
+ if( pEntry->nType >= 0 )
+ MakeFont( pEntry );
+ }
+}
+
+
+void LotusFontBuffer::SetHeight( const UINT16 nIndex, const UINT16 nHeight )
+{
+ DBG_ASSERT( nIndex < nSize, "*LotusFontBuffer::SetHeight(): Array zu klein!" );
+ if( nIndex < nSize )
+ pData[ nIndex ].Height( *( new SvxFontHeightItem( ( ULONG ) nHeight * 20, 100, ATTR_FONT_HEIGHT ) ) );
+}
+
+
+void LotusFontBuffer::SetType( const UINT16 nIndex, const UINT16 nType )
+{
+ DBG_ASSERT( nIndex < nSize, "*LotusFontBuffer::SetType(): Array zu klein!" );
+ if( nIndex < nSize )
+ {
+ register ENTRY* pEntry = pData + nIndex;
+ pEntry->Type( nType );
+
+ if( pEntry->pTmpName )
+ MakeFont( pEntry );
+ }
+}
+
+
+void LotusFontBuffer::MakeFont( ENTRY* pEntry )
+{
+ FontFamily eFamily = FAMILY_DONTKNOW;
+ FontPitch ePitch = PITCH_DONTKNOW;
+ CharSet eCharSet = RTL_TEXTENCODING_DONTKNOW;
+
+ switch( pEntry->nType )
+ {
+ case 0x00: // Helvetica
+ eFamily = FAMILY_SWISS;
+ ePitch = PITCH_VARIABLE;
+ break;
+ case 0x01: // Times Roman
+ eFamily = FAMILY_ROMAN;
+ ePitch = PITCH_VARIABLE;
+ break;
+ case 0x02: // Courier
+ ePitch = PITCH_FIXED;
+ break;
+ case 0x03: // Symbol
+ eCharSet = RTL_TEXTENCODING_SYMBOL;
+ break;
+ }
+
+ pEntry->pFont = new SvxFontItem( eFamily, *pEntry->pTmpName, EMPTY_STRING, ePitch, eCharSet, ATTR_FONT );
+
+ delete pEntry->pTmpName;
+ pEntry->pTmpName = NULL;
+}
+
+
+
diff --git a/sc/source/filter/excel/frmbase.cxx b/sc/source/filter/excel/frmbase.cxx
new file mode 100644
index 000000000000..78883b4a5c76
--- /dev/null
+++ b/sc/source/filter/excel/frmbase.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "formel.hxx"
+
+
+
+
+_ScRangeList::~_ScRangeList()
+{
+ ScRange* p = ( ScRange* ) First();
+
+ while( p )
+ {
+ delete p;
+ p = ( ScRange* ) Next();
+ }
+}
+
+
+
+
+_ScRangeListTabs::_ScRangeListTabs( void )
+{
+ ppTabLists = new _ScRangeList*[ MAXTAB + 1 ];
+
+ for( UINT16 n = 0 ; n <= MAXTAB ; n++ )
+ ppTabLists[ n ] = NULL;
+
+ bHasRanges = FALSE;
+ pAct = NULL;
+ nAct = 0;
+}
+
+
+_ScRangeListTabs::~_ScRangeListTabs()
+{
+ if( bHasRanges )
+ {
+ for( UINT16 n = 0 ; n <= MAXTAB ; n++ )
+ {
+ if( ppTabLists[ n ] )
+ delete ppTabLists[ n ];
+ }
+ }
+
+ delete[] ppTabLists;
+}
+
+
+void _ScRangeListTabs::Append( ScSingleRefData a, const BOOL b )
+{
+ if( b )
+ {
+ if( a.nTab > MAXTAB )
+ a.nTab = MAXTAB;
+
+ if( a.nCol > MAXCOL )
+ a.nCol = MAXCOL;
+
+ if( a.nRow > MAXROW )
+ a.nRow = MAXROW;
+ }
+ else
+ {
+ DBG_ASSERT( ValidTab(a.nTab), "-_ScRangeListTabs::Append(): Luegen haben kurze Abstuerze!" );
+ }
+
+ bHasRanges = TRUE;
+
+ if( a.nTab >= 0 )
+ {
+ _ScRangeList* p = ppTabLists[ a.nTab ];
+
+ if( !p )
+ p = ppTabLists[ a.nTab ] = new _ScRangeList;
+
+ p->Append( a );
+ }
+}
+
+
+void _ScRangeListTabs::Append( ScComplexRefData a, const BOOL b )
+{
+ if( b )
+ {
+ // #96263# ignore 3D ranges
+ if( a.Ref1.nTab != a.Ref2.nTab )
+ return;
+
+ SCsTAB& rTab = a.Ref1.nTab;
+ if( rTab > MAXTAB )
+ rTab = MAXTAB;
+ else if( rTab < 0 )
+ rTab = 0;
+
+ SCsCOL& rCol1 = a.Ref1.nCol;
+ if( rCol1 > MAXCOL )
+ rCol1 = MAXCOL;
+ else if( rCol1 < 0 )
+ rCol1 = 0;
+
+ SCsROW& rRow1 = a.Ref1.nRow;
+ if( rRow1 > MAXROW )
+ rRow1 = MAXROW;
+ else if( rRow1 < 0 )
+ rRow1 = 0;
+
+ SCsCOL& rCol2 = a.Ref2.nCol;
+ if( rCol2 > MAXCOL )
+ rCol2 = MAXCOL;
+ else if( rCol2 < 0 )
+ rCol2 = 0;
+
+ SCsROW& rRow2 = a.Ref2.nRow;
+ if( rRow2 > MAXROW )
+ rRow2 = MAXROW;
+ else if( rRow2 < 0 )
+ rRow2 = 0;
+ }
+ else
+ {
+ DBG_ASSERT( ValidTab(a.Ref1.nTab),
+ "-_ScRangeListTabs::Append(): Luegen haben kurze Abstuerze!" );
+ DBG_ASSERT( a.Ref1.nTab == a.Ref2.nTab,
+ "+_ScRangeListTabs::Append(): 3D-Ranges werden in SC nicht unterstuetzt!" );
+ }
+
+ bHasRanges = TRUE;
+
+ if( a.Ref1.nTab >= 0 )
+ {
+ _ScRangeList* p = ppTabLists[ a.Ref1.nTab ];
+
+ if( !p )
+ p = ppTabLists[ a.Ref1.nTab ] = new _ScRangeList;
+
+ p->Append( a );
+ }
+}
+
+
+const ScRange* _ScRangeListTabs::First( const UINT16 n )
+{
+ DBG_ASSERT( ValidTab(n), "-_ScRangeListTabs::First(): Und tschuessssssss!" );
+
+ if( ppTabLists[ n ] )
+ {
+ pAct = ppTabLists[ n ];
+ nAct = n;
+ return pAct->First();
+ }
+ else
+ {
+ pAct = NULL;
+ nAct = 0;
+ return NULL;
+ }
+}
+
+
+const ScRange* _ScRangeListTabs::Next( void )
+{
+ if( pAct )
+ return pAct->Next();
+ else
+ return NULL;
+}
+
+
+
+
+ConverterBase::ConverterBase( UINT16 nNewBuffer ) :
+ aEingPos( 0, 0, 0 ),
+ eStatus( ConvOK ),
+ nBufferSize( nNewBuffer )
+{
+ DBG_ASSERT( nNewBuffer > 0, "ConverterBase::ConverterBase - nNewBuffer == 0!" );
+ pBuffer = new sal_Char[ nNewBuffer ];
+}
+
+ConverterBase::~ConverterBase()
+{
+ delete[] pBuffer;
+}
+
+void ConverterBase::Reset()
+{
+ eStatus = ConvOK;
+ aPool.Reset();
+ aStack.Reset();
+}
+
+
+
+
+ExcelConverterBase::ExcelConverterBase( UINT16 nNewBuffer ) :
+ ConverterBase( nNewBuffer )
+{
+}
+
+ExcelConverterBase::~ExcelConverterBase()
+{
+}
+
+void ExcelConverterBase::Reset( const ScAddress& rEingPos )
+{
+ ConverterBase::Reset();
+ aEingPos = rEingPos;
+}
+
+void ExcelConverterBase::Reset()
+{
+ ConverterBase::Reset();
+ aEingPos.Set( 0, 0, 0 );
+}
+
+
+
+
+LotusConverterBase::LotusConverterBase( SvStream &rStr, UINT16 nNewBuffer ) :
+ ConverterBase( nNewBuffer ),
+ aIn( rStr ),
+ nBytesLeft( 0 )
+{
+}
+
+LotusConverterBase::~LotusConverterBase()
+{
+}
+
+//UNUSED2008-05 void LotusConverterBase::Reset( INT32 nLen, const ScAddress& rEingPos )
+//UNUSED2008-05 {
+//UNUSED2008-05 ConverterBase::Reset();
+//UNUSED2008-05 nBytesLeft = nLen;
+//UNUSED2008-05 aEingPos = rEingPos;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void LotusConverterBase::Reset( INT32 nLen )
+//UNUSED2008-05 {
+//UNUSED2008-05 ConverterBase::Reset();
+//UNUSED2008-05 nBytesLeft = nLen;
+//UNUSED2008-05 aEingPos.Set( 0, 0, 0 );
+//UNUSED2008-05 }
+
+void LotusConverterBase::Reset( const ScAddress& rEingPos )
+{
+ ConverterBase::Reset();
+ nBytesLeft = 0;
+ aEingPos = rEingPos;
+}
+
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
new file mode 100644
index 000000000000..209d24ac043d
--- /dev/null
+++ b/sc/source/filter/excel/impop.cxx
@@ -0,0 +1,1334 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "imp_op.hxx"
+
+#include <filter/msfilter/countryid.hxx>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/colritem.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/zforlist.hxx>
+
+#include <sfx2/objsh.hxx>
+#include "docuno.hxx"
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "compiler.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "markdata.hxx"
+#include "olinetab.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "compiler.hxx"
+#include "viewopti.hxx"
+#include "docoptio.hxx"
+#include "scextopt.hxx"
+#include "editutil.hxx"
+#include "filtopt.hxx"
+#include "scerrors.hxx"
+#include "unonames.hxx"
+#include "paramisc.hxx"
+#include "postit.hxx"
+
+#include "fapihelper.hxx"
+#include "xltools.hxx"
+#include "xltable.hxx"
+#include "xlview.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+#include "xilink.hxx"
+#include "xiescher.hxx"
+#include "xicontent.hxx"
+
+#include "excimp8.hxx"
+#include "excform.hxx"
+
+#if defined( WNT ) || defined( WIN )
+#include <math.h>
+#else
+#include <stdlib.h>
+#endif
+
+using namespace ::com::sun::star;
+
+
+const double ImportExcel::fExcToTwips =
+ ( double ) TWIPS_PER_CHAR / 256.0;
+
+
+ImportTyp::ImportTyp( ScDocument* pDoc, CharSet eQ )
+{
+ eQuellChar = eQ;
+ pD = pDoc;
+}
+
+
+ImportTyp::~ImportTyp()
+{
+}
+
+
+FltError ImportTyp::Read()
+{
+ return eERR_INTERN;
+}
+
+
+ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
+ ImportTyp( &rImpData.mrDoc, rImpData.meTextEnc ),
+ XclImpRoot( rImpData ),
+ maStrm( rStrm, GetRoot() ),
+ aIn( maStrm ),
+ maScOleSize( ScAddress::INITIALIZE_INVALID )
+{
+ mnLastRefIdx = 0;
+ nBdshtTab = 0;
+ nIxfeIndex = 0; // zur Sicherheit auf 0
+
+ // Root-Daten fuellen - nach new's ohne Root als Parameter
+ pExcRoot = &GetOldRoot();
+ pExcRoot->pIR = this; // ExcRoot -> XclImpRoot
+ pExcRoot->eDateiTyp = BiffX;
+ pExcRoot->pExtSheetBuff = new ExtSheetBuffer( pExcRoot ); //&aExtSheetBuff;
+ pExcRoot->pShrfmlaBuff = new ShrfmlaBuffer( pExcRoot ); //&aShrfrmlaBuff;
+ pExcRoot->pExtNameBuff = new ExtNameBuff ( *this );
+
+ pExtNameBuff = new NameBuffer( pExcRoot ); //#94039# prevent empty rootdata
+ pExtNameBuff->SetBase( 1 );
+
+ pOutlineListBuffer = new XclImpOutlineListBuffer( );
+
+ // ab Biff8
+ pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc( GetRoot() );
+
+ bTabTruncated = FALSE;
+
+ // Excel-Dokument per Default auf 31.12.1899, entspricht Excel-Einstellungen mit 1.1.1900
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetDate( 30, 12, 1899 );
+ pD->SetDocOptions( aOpt );
+ pD->GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
+
+ ScDocOptions aDocOpt( pD->GetDocOptions() );
+ aDocOpt.SetIgnoreCase( TRUE ); // always in Excel
+ aDocOpt.SetFormulaRegexEnabled( FALSE ); // regular expressions? what's that?
+ aDocOpt.SetLookUpColRowNames( FALSE ); // default: no natural language refs
+ pD->SetDocOptions( aDocOpt );
+}
+
+
+ImportExcel::~ImportExcel( void )
+{
+ GetDoc().SetSrcCharSet( GetTextEncoding() );
+
+ delete pExtNameBuff;
+
+ delete pOutlineListBuffer;
+
+ delete pFormConv;
+}
+
+
+void ImportExcel::ReadFileSharing()
+{
+ sal_uInt16 nRecommendReadOnly, nPasswordHash;
+ maStrm >> nRecommendReadOnly >> nPasswordHash;
+
+ if( (nRecommendReadOnly != 0) || (nPasswordHash != 0) )
+ {
+ if( SfxItemSet* pItemSet = GetMedium().GetItemSet() )
+ pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, TRUE ) );
+
+ if( SfxObjectShell* pShell = GetDocShell() )
+ {
+ if( nRecommendReadOnly != 0 )
+ pShell->SetLoadReadonly( sal_True );
+ if( nPasswordHash != 0 )
+ pShell->SetModifyPasswordHash( nPasswordHash );
+ }
+ }
+}
+
+sal_uInt16 ImportExcel::ReadXFIndex( bool bBiff2 )
+{
+ sal_uInt16 nXFIdx = 0;
+ if( bBiff2 )
+ {
+ sal_uInt8 nXFIdx2;
+ maStrm >> nXFIdx2;
+ maStrm.Ignore( 2 );
+ nXFIdx = nXFIdx2 & 0x3F;
+ if( nXFIdx == 63 )
+ nXFIdx = nIxfeIndex;
+ }
+ else
+ aIn >> nXFIdx;
+ return nXFIdx;
+}
+
+void ImportExcel::ReadDimensions()
+{
+ XclRange aXclUsedArea( ScAddress::UNINITIALIZED );
+ if( (maStrm.GetRecId() == EXC_ID2_DIMENSIONS) || (GetBiff() <= EXC_BIFF5) )
+ {
+ maStrm >> aXclUsedArea;
+ if( (aXclUsedArea.GetColCount() > 1) && (aXclUsedArea.GetRowCount() > 1) )
+ {
+ // Excel stores first unused row/column index
+ --aXclUsedArea.maLast.mnCol;
+ --aXclUsedArea.maLast.mnRow;
+ // create the Calc range
+ SCTAB nScTab = GetCurrScTab();
+ ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
+ GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
+ // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
+ }
+ }
+ else
+ {
+ sal_uInt32 nXclRow1, nXclRow2;
+ maStrm >> nXclRow1 >> nXclRow2 >> aXclUsedArea.maFirst.mnCol >> aXclUsedArea.maLast.mnCol;
+ if( (nXclRow1 < nXclRow2) && (aXclUsedArea.GetColCount() > 1) &&
+ (nXclRow1 <= static_cast< sal_uInt32 >( GetScMaxPos().Row() )) )
+ {
+ // Excel stores first unused row/column index
+ --nXclRow2;
+ --aXclUsedArea.maLast.mnCol;
+ // convert row indexes to 16-bit values
+ aXclUsedArea.maFirst.mnRow = static_cast< sal_uInt16 >( nXclRow1 );
+ aXclUsedArea.maLast.mnRow = limit_cast< sal_uInt16 >( nXclRow2, aXclUsedArea.maFirst.mnRow, SAL_MAX_UINT16 );
+ // create the Calc range
+ SCTAB nScTab = GetCurrScTab();
+ ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
+ GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
+ // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
+ }
+ }
+}
+
+void ImportExcel::ReadBlank()
+{
+ XclAddress aXclPos;
+ aIn >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_BLANK );
+
+ GetXFRangeBuffer().SetBlankXF( aScPos, nXFIdx );
+ }
+}
+
+void ImportExcel::ReadInteger()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( true );
+ sal_uInt16 nValue;
+ maStrm >> nValue;
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ GetDoc().PutCell( aScPos, new ScValueCell( nValue ) );
+ }
+}
+
+void ImportExcel::ReadNumber()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_NUMBER );
+ double fValue;
+ maStrm >> fValue;
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ GetDoc().PutCell( aScPos, new ScValueCell( fValue ) );
+ }
+}
+
+void ImportExcel::ReadLabel()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ /* Record ID BIFF XF type String type
+ 0x0004 2-7 3 byte 8-bit length, byte string
+ 0x0004 8 3 byte 16-bit length, unicode string
+ 0x0204 2-7 2 byte 16-bit length, byte string
+ 0x0204 8 2 byte 16-bit length, unicode string */
+ bool bBiff2 = maStrm.GetRecId() == EXC_ID2_LABEL;
+ sal_uInt16 nXFIdx = ReadXFIndex( bBiff2 );
+ XclStrFlags nFlags = (bBiff2 && (GetBiff() <= EXC_BIFF5)) ? EXC_STR_8BITLENGTH : EXC_STR_DEFAULT;
+ XclImpString aString;
+
+ // #i63105# use text encoding from FONT record
+ rtl_TextEncoding eOldTextEnc = GetTextEncoding();
+ if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
+ SetTextEncoding( pFont->GetFontEncoding() );
+ aString.Read( maStrm, nFlags );
+ SetTextEncoding( eOldTextEnc );
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ if( ScBaseCell* pCell = XclImpStringHelper::CreateCell( GetRoot(), aString, nXFIdx ) )
+ GetDoc().PutCell( aScPos, pCell );
+ }
+}
+
+void ImportExcel::ReadBoolErr()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_BOOLERR );
+ sal_uInt8 nValue, nType;
+ maStrm >> nValue >> nType;
+
+ if( nType == EXC_BOOLERR_BOOL )
+ GetXFRangeBuffer().SetBoolXF( aScPos, nXFIdx );
+ else
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+
+ double fValue;
+ const ScTokenArray* pScTokArr = ErrorToFormula( nType, nValue, fValue );
+ ScFormulaCell* pCell = new ScFormulaCell( pD, aScPos, pScTokArr );
+ pCell->SetHybridDouble( fValue );
+ GetDoc().PutCell( aScPos, pCell );
+ }
+}
+
+void ImportExcel::ReadRk()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( false );
+ sal_Int32 nRk;
+ maStrm >> nRk;
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ GetDoc().PutCell( aScPos, new ScValueCell( XclTools::GetDoubleFromRK( nRk ) ) );
+ }
+}
+
+
+void ImportExcel::Window1()
+{
+ GetDocViewSettings().ReadWindow1( maStrm );
+}
+
+
+
+
+void ImportExcel::Row25( void )
+{
+ UINT16 nRow, nRowHeight;
+
+ aIn >> nRow;
+ aIn.Ignore( 4 ); // Mic und Mac ueberspringen
+
+ if( ValidRow( nRow ) )
+ {
+ aIn >> nRowHeight; // direkt in Twips angegeben
+ aIn.Ignore( 2 );
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// -------------------- BIFF2
+ pColRowBuff->SetHeight( nRow, nRowHeight );
+ }
+ else
+ {// -------------------- BIFF5
+ UINT16 nGrbit;
+
+ aIn.Ignore( 2 ); // reserved
+ aIn >> nGrbit;
+
+ sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+ pRowOutlineBuff->SetLevel( nRow, nLevel,
+ ::get_flag( nGrbit, EXC_ROW_COLLAPSED ), ::get_flag( nGrbit, EXC_ROW_HIDDEN ) );
+
+ pColRowBuff->SetRowSettings( nRow, nRowHeight, nGrbit );
+ }
+ }
+}
+
+
+void ImportExcel::Bof2( void )
+{
+ sal_uInt16 nSubType;
+ maStrm.DisableDecryption();
+ maStrm.Ignore( 2 );
+ maStrm >> nSubType;
+
+ if( nSubType == 0x0020 ) // Chart
+ pExcRoot->eDateiTyp = Biff2C;
+ else if( nSubType == 0x0040 ) // Macro
+ pExcRoot->eDateiTyp = Biff2M;
+ else // #i51490# Excel interprets invalid indexes as worksheet
+ pExcRoot->eDateiTyp = Biff2;
+}
+
+
+void ImportExcel::Eof( void )
+{
+ // POST: darf nur nach einer GUELTIGEN Tabelle gerufen werden!
+ EndSheet();
+ IncCurrScTab();
+}
+
+
+void ImportExcel::SheetPassword( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
+}
+
+
+void ImportExcel::Externsheet( void )
+{
+ String aUrl, aTabName;
+ bool bSameWorkBook;
+ String aEncodedUrl( aIn.ReadByteString( false ) );
+ XclImpUrlHelper::DecodeUrl( aUrl, aTabName, bSameWorkBook, *pExcRoot->pIR, aEncodedUrl );
+ mnLastRefIdx = pExcRoot->pExtSheetBuff->Add( aUrl, aTabName, bSameWorkBook );
+}
+
+
+void ImportExcel:: WinProtection( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
+}
+
+
+void ImportExcel::Columndefault( void )
+{// Default Cell Attributes
+ UINT16 nColMic, nColMac;
+ BYTE nOpt0;
+
+ aIn >> nColMic >> nColMac;
+
+ DBG_ASSERT( aIn.GetRecLeft() == (sal_Size)(nColMac - nColMic) * 3 + 2,
+ "ImportExcel::Columndefault - wrong record size" );
+
+ nColMac--;
+
+ if( nColMac > MAXCOL )
+ nColMac = static_cast<UINT16>(MAXCOL);
+
+ for( UINT16 nCol = nColMic ; nCol <= nColMac ; nCol++ )
+ {
+ aIn >> nOpt0;
+ aIn.Ignore( 2 ); // nur 0. Attribut-Byte benutzt
+
+ if( nOpt0 & 0x80 ) // Col hidden?
+ pColRowBuff->HideCol( nCol );
+ }
+}
+
+
+void ImportExcel::Array25( void )
+{
+ UINT16 nFirstRow, nLastRow, nFormLen;
+ BYTE nFirstCol, nLastCol;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol;
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// BIFF2
+ aIn.Ignore( 1 );
+ nFormLen = aIn.ReaduInt8();
+ }
+ else
+ {// BIFF5
+ aIn.Ignore( 6 );
+ aIn >> nFormLen;
+ }
+
+ if( ValidColRow( nLastCol, nLastRow ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis;
+
+ pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
+ pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ DBG_ASSERT( pErgebnis, "*ImportExcel::Array25(): ScTokenArray ist NULL!" );
+
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( GetCurrScTab() );
+ pD->InsertMatrixFormula( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nLastRow), aMarkData, EMPTY_STRING,
+ pErgebnis );
+ }
+}
+
+
+void ImportExcel::Rec1904( void )
+{
+ UINT16 n1904;
+
+ aIn >> n1904;
+
+ if( n1904 )
+ {// 1904 date system
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetDate( 1, 1, 1904 );
+ pD->SetDocOptions( aOpt );
+ pD->GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
+ }
+}
+
+
+void ImportExcel::Externname25( void )
+{
+ UINT32 nRes;
+ UINT16 nOpt;
+
+ aIn >> nOpt >> nRes;
+
+ String aName( aIn.ReadByteString( FALSE ) );
+
+ if( ( nOpt & 0x0001 ) || ( ( nOpt & 0xFFFE ) == 0x0000 ) )
+ {// external name
+ ScfTools::ConvertToScDefinedName( aName );
+ pExcRoot->pExtNameBuff->AddName( aName, mnLastRefIdx );
+ }
+ else if( nOpt & 0x0010 )
+ {// ole link
+ pExcRoot->pExtNameBuff->AddOLE( aName, mnLastRefIdx, nRes ); // nRes is storage ID
+ }
+ else
+ {// dde link
+ pExcRoot->pExtNameBuff->AddDDE( aName, mnLastRefIdx );
+ }
+}
+
+
+void ImportExcel::Colwidth( void )
+{// Column Width
+ BYTE nColFirst, nColLast;
+ UINT16 nColWidth;
+
+ aIn >> nColFirst >> nColLast >> nColWidth;
+
+//! TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
+// if( nColLast > MAXCOL )
+// nColLast = static_cast<UINT16>(MAXCOL);
+
+ USHORT nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
+ pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
+}
+
+
+void ImportExcel::Defrowheight2( void )
+{
+ sal_uInt16 nDefHeight;
+ maStrm >> nDefHeight;
+ nDefHeight &= 0x7FFF;
+ pColRowBuff->SetDefHeight( nDefHeight, EXC_DEFROW_UNSYNCED );
+}
+
+
+void ImportExcel::SheetProtect( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
+}
+
+void ImportExcel::DocProtect( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn );
+}
+
+void ImportExcel::DocPasssword( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn );
+}
+
+void ImportExcel::Codepage( void )
+{
+ SetCodePage( maStrm.ReaduInt16() );
+}
+
+
+void ImportExcel::Ixfe( void )
+{
+ aIn >> nIxfeIndex;
+}
+
+
+void ImportExcel::DefColWidth( void )
+{
+ // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
+ double fDefWidth = 256.0 * maStrm.ReaduInt16();
+
+ // #i3006# additional space for default width - Excel adds space depending on font size
+ long nFontHt = GetFontBuffer().GetAppFontData().mnHeight;
+ fDefWidth += XclTools::GetXclDefColWidthCorrection( nFontHt );
+
+ USHORT nScWidth = XclTools::GetScColumnWidth( limit_cast< sal_uInt16 >( fDefWidth ), GetCharWidth() );
+ pColRowBuff->SetDefWidth( nScWidth );
+}
+
+
+void ImportExcel::Builtinfmtcnt( void )
+{
+}
+
+
+void ImportExcel::Colinfo( void )
+{// Column Formatting Information
+ UINT16 nColFirst, nColLast, nColWidth, nXF;
+ UINT16 nOpt;
+
+ aIn >> nColFirst >> nColLast >> nColWidth >> nXF >> nOpt;
+
+ if( nColFirst > MAXCOL )
+ return;
+
+ if( nColLast > MAXCOL )
+ nColLast = static_cast<UINT16>(MAXCOL);
+
+ bool bHidden = ::get_flag( nOpt, EXC_COLINFO_HIDDEN );
+ bool bCollapsed = ::get_flag( nOpt, EXC_COLINFO_COLLAPSED );
+ sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nOpt, 8, 3 );
+ pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed, bHidden );
+
+ if( bHidden )
+ pColRowBuff->HideColRange( nColFirst, nColLast );
+
+ USHORT nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
+ pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
+ pColRowBuff->SetDefaultXF( nColFirst, nColLast, nXF );
+}
+
+
+void ImportExcel::Wsbool( void )
+{
+ UINT16 nFlags;
+ aIn >> nFlags;
+
+ pRowOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_ROWBELOW ) );
+ pColOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_COLBELOW ) );
+
+ GetPageSettings().SetFitToPages( ::get_flag( nFlags, EXC_WSBOOL_FITTOPAGE ) );
+}
+
+
+void ImportExcel::Boundsheet( void )
+{
+ UINT16 nGrbit = 0;
+
+ if( GetBiff() == EXC_BIFF5 )
+ {
+ aIn.DisableDecryption();
+ maSheetOffsets.push_back( aIn.ReaduInt32() );
+ aIn.EnableDecryption();
+ aIn >> nGrbit;
+ }
+
+ String aName( aIn.ReadByteString( FALSE ) );
+
+ SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
+ if( nScTab > 0 )
+ {
+ DBG_ASSERT( !pD->HasTable( nScTab ), "ImportExcel::Boundsheet - sheet exists already" );
+ pD->MakeTable( nScTab );
+ }
+
+ if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
+ pD->SetVisible( nScTab, FALSE );
+
+ if( !pD->RenameTab( nScTab, aName ) )
+ {
+ pD->CreateValidTabName( aName );
+ pD->RenameTab( nScTab, aName );
+ }
+
+ nBdshtTab++;
+}
+
+
+void ImportExcel::Country( void )
+{
+ sal_uInt16 nUICountry, nDocCountry;
+ maStrm >> nUICountry >> nDocCountry;
+
+ // Store system language in XclRoot
+ LanguageType eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nDocCountry ) );
+ if( eLanguage != LANGUAGE_DONTKNOW )
+ SetDocLanguage( eLanguage );
+
+ // Set Excel UI language in add-in name translator
+ eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nUICountry ) );
+ if( eLanguage != LANGUAGE_DONTKNOW )
+ SetUILanguage( eLanguage );
+}
+
+
+void ImportExcel::ReadUsesElfs()
+{
+ if( maStrm.ReaduInt16() != 0 )
+ {
+ ScDocOptions aDocOpt = GetDoc().GetDocOptions();
+ aDocOpt.SetLookUpColRowNames( TRUE );
+ GetDoc().SetDocOptions( aDocOpt );
+ }
+}
+
+
+void ImportExcel::Hideobj( void )
+{
+ UINT16 nHide;
+ ScVObjMode eOle, eChart, eDraw;
+
+ aIn >> nHide;
+
+ ScViewOptions aOpts( pD->GetViewOptions() );
+
+ switch( nHide )
+ {
+ case 1: // Placeholders
+ eOle = VOBJ_MODE_SHOW; // in Excel 97 werden nur Charts als Platzhalter angezeigt
+ eChart = VOBJ_MODE_SHOW; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
+ eDraw = VOBJ_MODE_SHOW;
+ break;
+ case 2: // Hide all
+ eOle = VOBJ_MODE_HIDE;
+ eChart = VOBJ_MODE_HIDE;
+ eDraw = VOBJ_MODE_HIDE;
+ break;
+ default: // Show all
+ eOle = VOBJ_MODE_SHOW;
+ eChart = VOBJ_MODE_SHOW;
+ eDraw = VOBJ_MODE_SHOW;
+ break;
+ }
+
+ aOpts.SetObjMode( VOBJ_TYPE_OLE, eOle );
+ aOpts.SetObjMode( VOBJ_TYPE_CHART, eChart );
+ aOpts.SetObjMode( VOBJ_TYPE_DRAW, eDraw );
+
+ pD->SetViewOptions( aOpts );
+}
+
+
+void ImportExcel::Bundleheader( void )
+{
+}
+
+
+void ImportExcel::Standardwidth( void )
+{
+ USHORT nScWidth = XclTools::GetScColumnWidth( maStrm.ReaduInt16(), GetCharWidth() );
+ pColRowBuff->SetDefWidth( nScWidth, TRUE );
+}
+
+
+void ImportExcel::Shrfmla( void )
+{
+ UINT16 nFirstRow, nLastRow, nLenExpr;
+ BYTE nFirstCol, nLastCol;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol;
+ aIn.Ignore( 2 );
+ aIn >> nLenExpr;
+
+ // jetzt steht Lesemarke an der Formel
+
+ const ScTokenArray* pErgebnis;
+
+ pFormConv->Reset();
+ pFormConv->Convert( pErgebnis, maStrm, nLenExpr, true, FT_SharedFormula );
+
+
+ DBG_ASSERT( pErgebnis, "+ImportExcel::Shrfmla(): ScTokenArray ist NULL!" );
+
+ pExcRoot->pShrfmlaBuff->Store( ScRange( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), GetCurrScTab(),
+ static_cast<SCCOL>(nLastCol), static_cast<SCROW>(nLastRow),
+ GetCurrScTab()), *pErgebnis );
+}
+
+
+void ImportExcel::Mulrk( void )
+{
+ XclAddress aXclPos;
+ UINT16 nXF;
+ INT32 nRkNum;
+
+ aIn >> aXclPos;
+
+ for( XclAddress aCurrXclPos( aXclPos ); (aXclPos.mnCol <= aCurrXclPos.mnCol) && (aIn.GetRecLeft() > 2); ++aCurrXclPos.mnCol )
+ {
+ aIn >> nXF >> nRkNum;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
+ {
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ GetDoc().PutCell( aScPos, new ScValueCell( XclTools::GetDoubleFromRK( nRkNum ) ) );
+ }
+ }
+}
+
+
+void ImportExcel::Mulblank( void )
+{
+ XclAddress aXclPos;
+ UINT16 nXF;
+
+ aIn >> aXclPos;
+
+ for( XclAddress aCurrXclPos( aXclPos ); (aXclPos.mnCol <= aCurrXclPos.mnCol) && (aIn.GetRecLeft() > 2); ++aCurrXclPos.mnCol )
+ {
+ aIn >> nXF;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
+ GetXFRangeBuffer().SetBlankXF( aScPos, nXF );
+ }
+}
+
+
+void ImportExcel::Rstring( void )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXFIdx;
+ aIn >> aXclPos >> nXFIdx;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ // unformatted Unicode string with separate formatting information
+ XclImpString aString;
+
+ // #i63105# use text encoding from FONT record
+ rtl_TextEncoding eOldTextEnc = GetTextEncoding();
+ if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
+ SetTextEncoding( pFont->GetFontEncoding() );
+ aString.Read( maStrm );
+ SetTextEncoding( eOldTextEnc );
+
+ // character formatting runs
+ if( !aString.IsRich() )
+ aString.ReadFormats( maStrm );
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ if( ScBaseCell* pCell = XclImpStringHelper::CreateCell( *this, aString, nXFIdx ) )
+ GetDoc().PutCell( aScPos, pCell );
+ }
+}
+
+
+void ImportExcel::Cellmerging()
+{
+ XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ SCTAB nScTab = GetCurrScTab();
+
+ sal_uInt16 nCount;
+ maStrm >> nCount;
+ for( sal_uInt16 nIdx = 0; (nIdx < nCount) && (maStrm.GetRecLeft() >= 8); ++nIdx )
+ {
+ XclRange aXclRange;
+ maStrm >> aXclRange; // 16-bit rows and columns
+ ScRange aScRange( ScAddress::UNINITIALIZED );
+ if( rAddrConv.ConvertRange( aScRange, aXclRange, nScTab, nScTab, true ) )
+ GetXFRangeBuffer().SetMerge( aScRange.aStart.Col(), aScRange.aStart.Row(), aScRange.aEnd.Col(), aScRange.aEnd.Row() );
+ }
+}
+
+
+void ImportExcel::Olesize( void )
+{
+ XclRange aXclOleSize( ScAddress::UNINITIALIZED );
+ maStrm.Ignore( 2 );
+ aXclOleSize.Read( maStrm, false );
+
+ SCTAB nScTab = GetCurrScTab();
+ GetAddressConverter().ConvertRange( maScOleSize, aXclOleSize, nScTab, nScTab, false );
+}
+
+
+void ImportExcel::Row34( void )
+{
+ UINT16 nRow, nRowHeight, nGrbit, nXF;
+
+ aIn >> nRow;
+ aIn.Ignore( 4 ); // Mic und Mac ueberspringen
+
+ SCROW nScRow = static_cast< SCROW >( nRow );
+
+ if( ValidRow( nScRow ) )
+ {
+ aIn >> nRowHeight; // direkt in Twips angegeben
+ aIn.Ignore( 4 );
+
+ aIn >> nGrbit >> nXF;
+
+ sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+ pRowOutlineBuff->SetLevel( nScRow, nLevel,
+ ::get_flag( nGrbit, EXC_ROW_COLLAPSED ), ::get_flag( nGrbit, EXC_ROW_HIDDEN ) );
+
+ pColRowBuff->SetRowSettings( nScRow, nRowHeight, nGrbit );
+
+ if( nGrbit & EXC_ROW_USEDEFXF )
+ GetXFRangeBuffer().SetRowDefXF( nScRow, nXF & EXC_ROW_XFMASK );
+ }
+}
+
+
+void ImportExcel::Bof3( void )
+{
+ sal_uInt16 nSubType;
+ maStrm.DisableDecryption();
+ maStrm.Ignore( 2 );
+ maStrm >> nSubType;
+
+ DBG_ASSERT( nSubType != 0x0100, "*ImportExcel::Bof3(): Biff3 als Workbook?!" );
+ if( nSubType == 0x0100 ) // Book
+ pExcRoot->eDateiTyp = Biff3W;
+ else if( nSubType == 0x0020 ) // Chart
+ pExcRoot->eDateiTyp = Biff3C;
+ else if( nSubType == 0x0040 ) // Macro
+ pExcRoot->eDateiTyp = Biff3M;
+ else // #i51490# Excel interprets invalid indexes as worksheet
+ pExcRoot->eDateiTyp = Biff3;
+}
+
+
+void ImportExcel::Array34( void )
+{
+ UINT16 nFirstRow, nLastRow, nFormLen;
+ BYTE nFirstCol, nLastCol;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol;
+ aIn.Ignore( (GetBiff() >= EXC_BIFF5) ? 6 : 2 );
+ aIn >> nFormLen;
+
+ if( ValidColRow( nLastCol, nLastRow ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis;
+
+ pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
+ pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ DBG_ASSERT( pErgebnis, "+ImportExcel::Array34(): ScTokenArray ist NULL!" );
+
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( GetCurrScTab() );
+ pD->InsertMatrixFormula( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nLastRow), aMarkData, EMPTY_STRING,
+ pErgebnis);
+ }
+}
+
+
+void ImportExcel::Externname34( void )
+{
+}
+
+
+void ImportExcel::Defrowheight345( void )
+{
+ sal_uInt16 nFlags, nDefHeight;
+ maStrm >> nFlags >> nDefHeight;
+ pColRowBuff->SetDefHeight( nDefHeight, nFlags );
+}
+
+
+void ImportExcel::TableOp( void )
+{
+ UINT16 nFirstRow, nLastRow;
+ UINT8 nFirstCol, nLastCol;
+ UINT16 nGrbit;
+ UINT16 nInpRow, nInpCol, nInpRow2, nInpCol2;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol >> nGrbit
+ >> nInpRow >> nInpCol >> nInpRow2 >> nInpCol2;
+
+ if( ValidColRow( nLastCol, nLastRow ) )
+ {
+ if( nFirstCol && nFirstRow )
+ {
+ ScTabOpParam aTabOpParam;
+ aTabOpParam.nMode = (nGrbit & EXC_TABLEOP_BOTH) ? 2 : ((nGrbit & EXC_TABLEOP_ROW) ? 1 : 0 );
+ USHORT nCol = nFirstCol - 1;
+ USHORT nRow = nFirstRow - 1;
+ SCTAB nTab = GetCurrScTab();
+ switch( aTabOpParam.nMode )
+ {
+ case 0: // COL
+ aTabOpParam.aRefFormulaCell.Set(
+ static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow - 1), nTab, FALSE,
+ FALSE, FALSE );
+ aTabOpParam.aRefFormulaEnd.Set(
+ static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nFirstRow - 1), nTab, FALSE,
+ FALSE, FALSE );
+ aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol),
+ static_cast<SCROW>(nInpRow), nTab, FALSE, FALSE,
+ FALSE );
+ nRow++;
+ break;
+ case 1: // ROW
+ aTabOpParam.aRefFormulaCell.Set(
+ static_cast<SCCOL>(nFirstCol - 1),
+ static_cast<SCROW>(nFirstRow), nTab, FALSE, FALSE,
+ FALSE );
+ aTabOpParam.aRefFormulaEnd.Set(
+ static_cast<SCCOL>(nFirstCol - 1),
+ static_cast<SCROW>(nLastRow), nTab, FALSE, FALSE,
+ FALSE );
+ aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
+ static_cast<SCROW>(nInpRow), nTab, FALSE, FALSE,
+ FALSE );
+ nCol++;
+ break;
+ case 2: // TWO-INPUT
+ aTabOpParam.aRefFormulaCell.Set(
+ static_cast<SCCOL>(nFirstCol - 1),
+ static_cast<SCROW>(nFirstRow - 1), nTab, FALSE,
+ FALSE, FALSE );
+ aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
+ static_cast<SCROW>(nInpRow), nTab, FALSE, FALSE,
+ FALSE );
+ aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol2),
+ static_cast<SCROW>(nInpRow2), nTab, FALSE, FALSE,
+ FALSE );
+ break;
+ }
+
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( nTab );
+ pD->InsertTableOp( aTabOpParam, static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow), static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nLastRow), aMarkData );
+ }
+ }
+ else
+ {
+ bTabTruncated = TRUE;
+ GetTracer().TraceInvalidRow(GetCurrScTab(), nLastRow, MAXROW);
+ }
+}
+
+
+void ImportExcel::Bof4( void )
+{
+ sal_uInt16 nSubType;
+ maStrm.DisableDecryption();
+ maStrm.Ignore( 2 );
+ maStrm >> nSubType;
+
+ if( nSubType == 0x0100 ) // Book
+ pExcRoot->eDateiTyp = Biff4W;
+ else if( nSubType == 0x0020 ) // Chart
+ pExcRoot->eDateiTyp = Biff4C;
+ else if( nSubType == 0x0040 ) // Macro
+ pExcRoot->eDateiTyp = Biff4M;
+ else // #i51490# Excel interprets invalid indexes as worksheet
+ pExcRoot->eDateiTyp = Biff4;
+}
+
+
+void ImportExcel::Bof5( void )
+{
+ //POST: eDateiTyp = Typ der zu lesenden Datei
+ UINT16 nSubType, nVers;
+ BiffTyp eDatei;
+
+ maStrm.DisableDecryption();
+ maStrm >> nVers >> nSubType;
+
+ switch( nSubType )
+ {
+ case 0x0005: eDatei = Biff5W; break; // workbook globals
+ case 0x0006: eDatei = Biff5V; break; // VB module
+ case 0x0010: eDatei = Biff5; break; // worksheet
+ case 0x0020: eDatei = Biff5C; break; // chart
+ case 0x0040: eDatei = Biff5M4; break; // macro sheet
+ default:
+ pExcRoot->eDateiTyp = BiffX;
+ return;
+ }
+
+ if( nVers == 0x0600 && (GetBiff() == EXC_BIFF8) )
+ eDatei = ( BiffTyp ) ( eDatei - Biff5 + Biff8 );
+
+ pExcRoot->eDateiTyp = eDatei;
+}
+
+void ImportExcel::EndSheet( void )
+{
+ pExcRoot->pExtSheetBuff->Reset();
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ pExcRoot->pExtNameBuff->Reset();
+ mnLastRefIdx = 0;
+ }
+
+ FinalizeTable();
+}
+
+
+void ImportExcel::NeueTabelle( void )
+{
+ SCTAB nTab = GetCurrScTab();
+ if( nTab > 0 && !pD->HasTable( nTab ) )
+ pD->MakeTable( nTab );
+
+ pExcRoot->pShrfmlaBuff->Clear();
+
+ InitializeTable( nTab );
+
+ pOutlineListBuffer->Append( new XclImpOutlineDataBuffer( GetRoot(), nTab ) );
+
+ pExcRoot->pColRowBuff = pColRowBuff = pOutlineListBuffer->Last()->GetColRowBuff();
+ pColOutlineBuff = pOutlineListBuffer->Last()->GetColOutline();
+ pRowOutlineBuff = pOutlineListBuffer->Last()->GetRowOutline();
+}
+
+
+const ScTokenArray* ImportExcel::ErrorToFormula( BYTE bErrOrVal, BYTE nError, double& rVal )
+{
+ return pFormConv->GetBoolErr( XclTools::ErrorToEnum( rVal, bErrOrVal, nError ) );
+}
+
+
+void ImportExcel::AdjustRowHeight()
+{
+ /* #93255# Speed up chart import: import all sheets without charts, then
+ update row heights (here), last load all charts -> do not any longer
+ update inside of ScDocShell::ConvertFrom() (causes update of existing
+ charts during each and every change of row height). */
+ if( ScModelObj* pDocObj = GetDocModelObj() )
+ pDocObj->UpdateAllRowHeights();
+}
+
+
+void ImportExcel::PostDocLoad( void )
+{
+ /* Set automatic page numbering in Default page style (default is "page number = 1").
+ Otherwise hidden tables (i.e. for scenarios) which have Default page style will
+ break automatic page numbering. */
+ if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PAGE ) )
+ pStyleSheet->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 0 ) );
+
+ // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
+ for( XclImpOutlineDataBuffer* pBuffer = pOutlineListBuffer->First(); pBuffer; pBuffer = pOutlineListBuffer->Next() )
+ pBuffer->Convert();
+
+ // document view settings (before visible OLE area)
+ GetDocViewSettings().Finalize();
+
+ // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
+ GetObjectManager().ConvertObjects();
+
+ // visible area (used if this document is an embedded OLE object)
+ if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ // visible area if embedded
+ const ScExtDocSettings& rDocSett = GetExtDocOptions().GetDocSettings();
+ SCTAB nDisplScTab = rDocSett.mnDisplTab;
+
+ /* #i44077# If a new OLE object is inserted from file, there is no
+ OLESIZE record in the Excel file. Calculate used area from file
+ contents (used cells and drawing objects). */
+ if( !maScOleSize.IsValid() )
+ {
+ // used area of displayed sheet (cell contents)
+ if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nDisplScTab ) )
+ maScOleSize = pTabSett->maUsedArea;
+ // add all valid drawing objects
+ ScRange aScObjArea = GetObjectManager().GetUsedArea( nDisplScTab );
+ if( aScObjArea.IsValid() )
+ maScOleSize.ExtendTo( aScObjArea );
+ }
+
+ // valid size found - set it at the document
+ if( maScOleSize.IsValid() )
+ {
+ pDocShell->SetVisArea( GetDoc().GetMMRect(
+ maScOleSize.aStart.Col(), maScOleSize.aStart.Row(),
+ maScOleSize.aEnd.Col(), maScOleSize.aEnd.Row(), nDisplScTab ) );
+ GetDoc().SetVisibleTab( nDisplScTab );
+ }
+ }
+
+ // #111099# open forms in alive mode (has no effect, if no controls in document)
+ if( ScModelObj* pDocObj = GetDocModelObj() )
+ pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), uno::Any( false ) );
+
+ // enables extended options to be set to the view after import
+ GetExtDocOptions().SetChanged( true );
+
+ // root data owns the extended document options -> create a new object
+ GetDoc().SetExtDocOptions( new ScExtDocOptions( GetExtDocOptions() ) );
+
+ const SCTAB nLast = pD->GetTableCount();
+ const ScRange* p;
+
+ if( pExcRoot->pPrintRanges->HasRanges() )
+ {
+ for( SCTAB n = 0 ; n < nLast ; n++ )
+ {
+ p = pExcRoot->pPrintRanges->First( static_cast<UINT16>(n) );
+ if( p )
+ {
+ DBG_ASSERT( pExcRoot->pPrintRanges->GetActList(),
+ "-ImportExcel::PostDocLoad(): Imaginaere Tabelle gefunden!" );
+
+ pD->ClearPrintRanges( n );
+ while( p )
+ {
+ pD->AddPrintRange( n, *p );
+ p = pExcRoot->pPrintRanges->Next();
+ }
+ }
+ else
+ {
+ // #i4063# no print ranges -> print entire sheet
+ pD->SetPrintEntireSheet( n );
+ }
+ }
+ GetTracer().TracePrintRange();
+ }
+
+ if( pExcRoot->pPrintTitles->HasRanges() )
+ {
+ for( SCTAB n = 0 ; n < nLast ; n++ )
+ {
+ p = pExcRoot->pPrintTitles->First( static_cast<UINT16>(n) );
+ if( p )
+ {
+ DBG_ASSERT( pExcRoot->pPrintTitles->GetActList(),
+ "-ImportExcel::PostDocLoad(): Imaginaere Tabelle gefunden!" );
+
+ BOOL bRowVirgin = TRUE;
+ BOOL bColVirgin = TRUE;
+
+ while( p )
+ {
+ if( p->aStart.Col() == 0 && p->aEnd.Col() == MAXCOL && bRowVirgin )
+ {
+ pD->SetRepeatRowRange( n, p );
+ bRowVirgin = FALSE;
+ }
+
+ if( p->aStart.Row() == 0 && p->aEnd.Row() == MAXROW && bColVirgin )
+ {
+ pD->SetRepeatColRange( n, p );
+ bColVirgin = FALSE;
+ }
+
+ p = pExcRoot->pPrintTitles->Next();
+ }
+ }
+ }
+ }
+}
+
+XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot& rRoot, SCTAB nScTab ) :
+ XclImpRoot( rRoot ),
+ mxColOutlineBuff( new XclImpOutlineBuffer( MAXCOLCOUNT ) ),
+ mxRowOutlineBuff( new XclImpOutlineBuffer( MAXROWCOUNT ) ),
+ mxColRowBuff( new XclImpColRowSettings( rRoot ) ),
+ mnScTab( nScTab )
+{
+}
+
+XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
+{
+}
+
+void XclImpOutlineDataBuffer::Convert()
+{
+ mxColOutlineBuff->SetOutlineArray( GetDoc().GetOutlineTable( mnScTab, TRUE )->GetColArray() );
+ mxColOutlineBuff->MakeScOutline();
+
+ mxRowOutlineBuff->SetOutlineArray( GetDoc().GetOutlineTable( mnScTab, TRUE )->GetRowArray() );
+ mxRowOutlineBuff->MakeScOutline();
+
+ mxColRowBuff->ConvertHiddenFlags( mnScTab );
+}
diff --git a/sc/source/filter/excel/makefile.mk b/sc/source/filter/excel/makefile.mk
new file mode 100644
index 000000000000..04ba76d4a68a
--- /dev/null
+++ b/sc/source/filter/excel/makefile.mk
@@ -0,0 +1,160 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=excel
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/colrowst.obj \
+ $(SLO)$/excdoc.obj \
+ $(SLO)$/excel.obj \
+ $(SLO)$/excform.obj \
+ $(SLO)$/excform8.obj \
+ $(SLO)$/excimp8.obj \
+ $(SLO)$/excrecds.obj \
+ $(SLO)$/exctools.obj \
+ $(SLO)$/expop2.obj \
+ $(SLO)$/fontbuff.obj \
+ $(SLO)$/frmbase.obj \
+ $(SLO)$/impop.obj \
+ $(SLO)$/namebuff.obj \
+ $(SLO)$/read.obj \
+ $(SLO)$/tokstack.obj \
+ $(SLO)$/xechart.obj \
+ $(SLO)$/xecontent.obj \
+ $(SLO)$/xeescher.obj \
+ $(SLO)$/xeformula.obj \
+ $(SLO)$/xehelper.obj \
+ $(SLO)$/xelink.obj \
+ $(SLO)$/xename.obj \
+ $(SLO)$/xepage.obj \
+ $(SLO)$/xepivot.obj \
+ $(SLO)$/xerecord.obj \
+ $(SLO)$/xeroot.obj \
+ $(SLO)$/xestream.obj \
+ $(SLO)$/xestring.obj \
+ $(SLO)$/xestyle.obj \
+ $(SLO)$/xetable.obj \
+ $(SLO)$/xeview.obj \
+ $(SLO)$/xichart.obj \
+ $(SLO)$/xicontent.obj \
+ $(SLO)$/xiescher.obj \
+ $(SLO)$/xiformula.obj \
+ $(SLO)$/xihelper.obj \
+ $(SLO)$/xilink.obj \
+ $(SLO)$/xiname.obj \
+ $(SLO)$/xipage.obj \
+ $(SLO)$/xipivot.obj \
+ $(SLO)$/xiroot.obj \
+ $(SLO)$/xistream.obj \
+ $(SLO)$/xistring.obj \
+ $(SLO)$/xistyle.obj \
+ $(SLO)$/xiview.obj \
+ $(SLO)$/xladdress.obj \
+ $(SLO)$/xlchart.obj \
+ $(SLO)$/xlescher.obj \
+ $(SLO)$/xlformula.obj \
+ $(SLO)$/xlpage.obj \
+ $(SLO)$/xlpivot.obj \
+ $(SLO)$/xlroot.obj \
+ $(SLO)$/xlstyle.obj \
+ $(SLO)$/xltools.obj \
+ $(SLO)$/xltracer.obj \
+ $(SLO)$/xlview.obj
+
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
+NOOPTFILES = \
+ $(SLO)$/xiescher.obj
+.ENDIF
+
+EXCEPTIONSFILES = \
+ $(SLO)$/excdoc.obj \
+ $(SLO)$/excel.obj \
+ $(SLO)$/excform.obj \
+ $(SLO)$/excform8.obj \
+ $(SLO)$/excimp8.obj \
+ $(SLO)$/excrecds.obj \
+ $(SLO)$/expop2.obj \
+ $(SLO)$/impop.obj \
+ $(SLO)$/namebuff.obj \
+ $(SLO)$/tokstack.obj \
+ $(SLO)$/xecontent.obj \
+ $(SLO)$/xeescher.obj \
+ $(SLO)$/xeformula.obj \
+ $(SLO)$/xehelper.obj \
+ $(SLO)$/xelink.obj \
+ $(SLO)$/xename.obj \
+ $(SLO)$/xepage.obj \
+ $(SLO)$/xepivot.obj \
+ $(SLO)$/xechart.obj \
+ $(SLO)$/xestream.obj \
+ $(SLO)$/xestring.obj \
+ $(SLO)$/xestyle.obj \
+ $(SLO)$/xetable.obj \
+ $(SLO)$/xeview.obj \
+ $(SLO)$/xichart.obj \
+ $(SLO)$/xicontent.obj \
+ $(SLO)$/xiescher.obj \
+ $(SLO)$/xihelper.obj \
+ $(SLO)$/xilink.obj \
+ $(SLO)$/xipage.obj \
+ $(SLO)$/xipivot.obj \
+ $(SLO)$/xistream.obj \
+ $(SLO)$/xistring.obj \
+ $(SLO)$/xistyle.obj \
+ $(SLO)$/xladdress.obj \
+ $(SLO)$/xiescher.obj \
+ $(SLO)$/xlchart.obj \
+ $(SLO)$/xlformula.obj \
+ $(SLO)$/xlpivot.obj \
+ $(SLO)$/xlroot.obj \
+ $(SLO)$/xlstyle.obj \
+ $(SLO)$/xltools.obj \
+ $(SLO)$/xlview.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
new file mode 100644
index 000000000000..7db7d17ed307
--- /dev/null
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "namebuff.hxx"
+
+#include <tools/urlobj.hxx>
+#include <string.h>
+
+#include "rangenam.hxx"
+#include "document.hxx"
+#include "compiler.hxx"
+#include "scextopt.hxx"
+
+#include "root.hxx"
+#include "tokstack.hxx"
+#include "xltools.hxx"
+#include "xiroot.hxx"
+
+
+UINT32 StringHashEntry::MakeHashCode( const String& r )
+{
+ register UINT32 n = 0;
+ const sal_Unicode* pAkt = r.GetBuffer();
+ register sal_Unicode cAkt = *pAkt;
+
+ while( cAkt )
+ {
+ n *= 70;
+ n += ( UINT32 ) cAkt;
+ pAkt++;
+ cAkt = *pAkt;
+ }
+
+ return n;
+}
+
+
+
+
+NameBuffer::~NameBuffer()
+{
+ register StringHashEntry* pDel = ( StringHashEntry* ) List::First();
+ while( pDel )
+ {
+ delete pDel;
+ pDel = ( StringHashEntry* ) List::Next();
+ }
+}
+
+
+//void NameBuffer::operator <<( const SpString &rNewString )
+void NameBuffer::operator <<( const String &rNewString )
+{
+ DBG_ASSERT( Count() + nBase < 0xFFFF,
+ "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
+
+ List::Insert( new StringHashEntry( rNewString ), LIST_APPEND );
+}
+
+
+#ifdef DBG_UTIL
+UINT16 nShrCnt;
+#endif
+
+
+size_t ShrfmlaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
+{
+ // Use something simple, it is just a hash.
+ return static_cast< UINT16 >( addr.Row() ) | (static_cast< UINT8 >( addr.Col() ) << 16);
+}
+
+const size_t nBase = 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
+ShrfmlaBuffer::ShrfmlaBuffer( RootData* pRD ) :
+ ExcRoot( pRD ),
+ mnCurrIdx (nBase)
+{
+#ifdef DBG_UTIL
+ nShrCnt = 0;
+#endif
+}
+
+ShrfmlaBuffer::~ShrfmlaBuffer()
+{
+}
+
+void ShrfmlaBuffer::Clear()
+{
+ index_hash.clear();
+ // do not clear index_list, index calculation depends on complete list size...
+ // do not change mnCurrIdx
+}
+
+void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
+{
+ String aName( CreateName( rRange.aStart ) );
+
+ DBG_ASSERT( mnCurrIdx <= 0xFFFF, "*ShrfmlaBuffer::Store(): Gleich wird mir schlecht...!" );
+
+ ScRangeData* pData = new ScRangeData( pExcRoot->pIR->GetDocPtr(), aName, rToken, rRange.aStart, RT_SHARED );
+ const ScAddress& rMaxPos = pExcRoot->pIR->GetMaxPos();
+ pData->SetMaxCol(rMaxPos.Col());
+ pData->SetMaxRow(rMaxPos.Row());
+ pData->SetIndex( static_cast< USHORT >( mnCurrIdx ) );
+ pExcRoot->pIR->GetNamedRanges().Insert( pData );
+ index_hash[rRange.aStart] = static_cast< USHORT >( mnCurrIdx );
+ index_list.push_front (rRange);
+ ++mnCurrIdx;
+}
+
+
+USHORT ShrfmlaBuffer::Find( const ScAddress & aAddr ) const
+{
+ ShrfmlaHash::const_iterator hash = index_hash.find (aAddr);
+ if (hash != index_hash.end())
+ return hash->second;
+
+ // It was not hashed on the top left corner ? do a brute force search
+ unsigned int ind = nBase;
+ for (ShrfmlaList::const_iterator ptr = index_list.end(); ptr != index_list.begin() ; ind++)
+ if ((--ptr)->In (aAddr))
+ return static_cast< USHORT >( ind );
+ return static_cast< USHORT >( mnCurrIdx );
+}
+
+
+#define SHRFMLA_BASENAME "SHARED_FORMULA_"
+
+String ShrfmlaBuffer::CreateName( const ScRange& r )
+{
+ String aName( RTL_CONSTASCII_USTRINGPARAM( SHRFMLA_BASENAME ) );
+ aName += String::CreateFromInt32( r.aStart.Col() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aStart.Row() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aEnd.Col() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aEnd.Row() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aStart.Tab() );
+
+ return aName;
+}
+
+
+ExtSheetBuffer::~ExtSheetBuffer()
+{
+ Cont *pAkt = ( Cont * ) List::First();
+ while( pAkt )
+ {
+ delete pAkt;
+ pAkt = ( Cont * ) List::Next();
+ }
+}
+
+
+sal_Int16 ExtSheetBuffer::Add( const String& rFPAN, const String& rTN, const BOOL bSWB )
+{
+ List::Insert( new Cont( rFPAN, rTN, bSWB ), LIST_APPEND );
+ // return 1-based index of EXTERNSHEET
+ return static_cast< sal_Int16 >( List::Count() );
+}
+
+
+BOOL ExtSheetBuffer::GetScTabIndex( UINT16 nExcIndex, UINT16& rScIndex )
+{
+ DBG_ASSERT( nExcIndex,
+ "*ExtSheetBuffer::GetScTabIndex(): Sheet-Index == 0!" );
+
+ nExcIndex--;
+ Cont* pCur = ( Cont * ) List::GetObject( nExcIndex );
+ UINT16& rTabNum = pCur->nTabNum;
+
+ if( pCur )
+ {
+ if( rTabNum < 0xFFFD )
+ {
+ rScIndex = rTabNum;
+ return TRUE;
+ }
+
+ if( rTabNum == 0xFFFF )
+ {// neue Tabelle erzeugen
+ SCTAB nNewTabNum;
+ if( pCur->bSWB )
+ {// Tabelle ist im selben Workbook!
+ if( pExcRoot->pIR->GetDoc().GetTable( pCur->aTab, nNewTabNum ) )
+ {
+ rScIndex = rTabNum = static_cast<UINT16>(nNewTabNum);
+ return TRUE;
+ }
+ else
+ rTabNum = 0xFFFD;
+ }
+ else if( pExcRoot->pIR->GetDocShell() )
+ {// Tabelle ist 'echt' extern
+ if( pExcRoot->pIR->GetExtDocOptions().GetDocSettings().mnLinkCnt == 0 )
+ {
+ String aURL( ScGlobal::GetAbsDocName( pCur->aFile,
+ pExcRoot->pIR->GetDocShell() ) );
+ String aTabName( ScGlobal::GetDocTabName( aURL, pCur->aTab ) );
+ if( pExcRoot->pIR->GetDoc().LinkExternalTab( nNewTabNum, aTabName, aURL, pCur->aTab ) )
+ {
+ rScIndex = rTabNum = static_cast<UINT16>(nNewTabNum);
+ return TRUE;
+ }
+ else
+ rTabNum = 0xFFFE; // Tabelle einmal nicht angelegt -> wird
+ // wohl auch nicht mehr gehen...
+ }
+ else
+ rTabNum = 0xFFFE;
+
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOL ExtSheetBuffer::IsLink( const UINT16 nExcIndex ) const
+{
+ DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::IsLink(): Index muss >0 sein!" );
+ Cont* pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
+
+ if( pRet )
+ return pRet->bLink;
+ else
+ return FALSE;
+}
+
+
+BOOL ExtSheetBuffer::GetLink( const UINT16 nExcIndex, String& rAppl, String& rDoc ) const
+{
+ DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::GetLink(): Index muss >0 sein!" );
+ Cont* pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
+
+ if( pRet )
+ {
+ rAppl = pRet->aFile;
+ rDoc = pRet->aTab;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+void ExtSheetBuffer::Reset( void )
+{
+ Cont *pAkt = ( Cont * ) List::First();
+ while( pAkt )
+ {
+ delete pAkt;
+ pAkt = ( Cont * ) List::Next();
+ }
+
+ List::Clear();
+}
+
+
+
+
+BOOL ExtName::IsDDE( void ) const
+{
+ return ( nFlags & 0x0001 ) != 0;
+}
+
+
+BOOL ExtName::IsOLE( void ) const
+{
+ return ( nFlags & 0x0002 ) != 0;
+}
+
+
+ExtNameBuff::ExtNameBuff( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+
+void ExtNameBuff::AddDDE( const String& rName, sal_Int16 nRefIdx )
+{
+ ExtName aNew( rName, 0x0001 );
+ maExtNames[ nRefIdx ].push_back( aNew );
+}
+
+
+void ExtNameBuff::AddOLE( const String& rName, sal_Int16 nRefIdx, UINT32 nStorageId )
+{
+ ExtName aNew( rName, 0x0002 );
+ aNew.nStorageId = nStorageId;
+ maExtNames[ nRefIdx ].push_back( aNew );
+}
+
+
+void ExtNameBuff::AddName( const String& rName, sal_Int16 nRefIdx )
+{
+ ExtName aNew( GetScAddInName( rName ), 0x0004 );
+ maExtNames[ nRefIdx ].push_back( aNew );
+}
+
+
+const ExtName* ExtNameBuff::GetNameByIndex( sal_Int16 nRefIdx, sal_uInt16 nNameIdx ) const
+{
+ DBG_ASSERT( nNameIdx > 0, "ExtNameBuff::GetNameByIndex() - invalid name index" );
+ ExtNameMap::const_iterator aIt = maExtNames.find( nRefIdx );
+ return ((aIt != maExtNames.end()) && (0 < nNameIdx) && (nNameIdx <= aIt->second.size())) ? &aIt->second[ nNameIdx - 1 ] : 0;
+}
+
+
+void ExtNameBuff::Reset( void )
+{
+ maExtNames.clear();
+}
+
+
diff --git a/sc/source/filter/excel/ooxml-export-TODO.txt b/sc/source/filter/excel/ooxml-export-TODO.txt
new file mode 100644
index 000000000000..5b04efb97007
--- /dev/null
+++ b/sc/source/filter/excel/ooxml-export-TODO.txt
@@ -0,0 +1,148 @@
+TODO/Unimplemented Calc OOXML Export Features:
+=============================================
+
+Partially implemented features are not mentioned here; grep for OOXTODO within
+sc/source/filter/*.
+
+In updated OfficeFileFormatsProtocols.zip [MS-XLS].pdf,
+Section §2.3.1 (p.154) provides the record name :: record number mapping, and
+Section §2.3.2 (p.165) provides the record number :: record name mapping.
+
+Elements:
+ - Workbook (§3.2):
+ - customWorkbookViews (§3.2.3)
+ - ext (§3.2.7)
+ - externalReference (§3.2.8)
+ - externalReferences (§3.2.9)
+ - extLst (§3.2.10)
+ - fileRecoveryPr (§3.2.11) [ CRASHRECERR? 865h ]
+ - fileSharing (§3.2.12) [ FILESHARING 5Bh ]
+ - functionGroup (§3.2.14) [ FNGRP12 898h; FNGROUPNAME 9Ah ]
+ - functionGroups (§3.2.15) [ FNGROUPCOUNT: 9Ch ]
+ - oleSize (§3.2.16) [ OLESIZE DEh ]
+ - smartTagPr (§3.2.21) [ BOOKEXT 863h ]
+ - smartTagType (§3.2.22) [ unknown record ]
+ - smartTagTypes (§3.2.23) [ unknown record ]
+ - webPublishing (§3.2.24) [ WOPT 80Bh ]
+ - webPublishObject (§3.2.25) [ WEBPUB 801h ]
+ - webPublishObjects (§3.2.26) [ unsupported ]
+ - Worksheets (§3.3.1):
+ - autoFilter (§3.3.1.1) [ AutoFilter 9Eh ]
+ - cellSmartTag (§3.3.1.4) [ FEAT 868h ]
+ - cellSmartTagPr (§3.3.1.5) [ FEAT? 868h ]
+ - cellSmartTags (§3.3.1.6) [ FEAT 868h ]
+ - cellWatch (§3.3.1.7) [ CELLWATCH 86Ch ]
+ - cellWatches (§3.3.1.8) [ CELLWATCH 86Ch ]
+ - cfRule (§3.3.1.9) [ CF 1B1h ]
+ - cfvo (§3.3.1.10) [ CF12 87Ah ]
+ - chartsheet (§3.3.1.11) [ CHARTFRTINFO 850h, FRTWRAPPER 851h...]
+ - color (§3.3.1.14) [ DXF 88Dh xfpropBorder?
+ XFEXT 87Dh xclrType? ]
+ - colorScale (§3.3.1.15) [ DXF 88Dh? ]
+ - control (§3.3.1.18) [ ??? ]
+ - controls (§3.3.1.19) [ ??? ]
+ - customPr (§3.3.1.20) [ ??? ]
+ - customProperties (§3.3.1.21) [ ??? ]
+ - customSheetView (§3.3.1.22) [ ???; for charts; see chartsheet? ]
+ - customSheetView (§3.3.1.23) [ ??? ]
+ - customSheetViews (§3.3.1.24) [ ???; for charts; see chartsheet? ]
+ - customSheetViews (§3.3.1.25) [ ??? ]
+ - dataBar (§3.3.1.26) [ CF12 87Ah ct=Databar ]
+ - dataConsolidate (§3.3.1.27) [ DCON 50h ]
+ - dataRef (§3.3.1.28) [ DCONBIN 1B5h ]
+ - dataRefs (§3.3.1.29) [ ??? ]
+ - dialogsheet (§3.3.1.32) [ ??? ]
+ - drawing (§3.3.1.34) [ ??? ]
+ - evenFooter (§3.3.1.35) [ HeaderFooter 89Ch ]
+ - evenHeader (§3.3.1.36) [ HeaderFooter 89Ch ]
+ - firstFooter (§3.3.1.38) [ HeaderFooter 89Ch ]
+ - firstHeader (§3.3.1.39) [ HeaderFooter 89Ch ]
+ - formula (§3.3.1.40) [ CF 1B1h ]
+ - iconSet (§3.3.1.46) [ CF12 87Ah ct=CFMultistate ]
+ - ignoredError (§3.3.1.47) [ Feat/FeatForumulaErr2/FFErrorCheck 868h ]
+ - ignoredErrors (§3.3.1.48) [ Feat 868h ]
+ - legacyDrawing (§3.3.1.51) [ MsoDrawing ECh ]
+ - legacyDrawingHF (§3.3.1.52) [ ??? ]
+ - oleObject (§3.3.1.57) [ ??? ]
+ - oleObjects (§3.3.1.58) [ ??? ]
+ - outlinePr (§3.3.1.59) [ ??? ]
+ - pageSetup (§3.3.1.62) [ ???; for charts; see chartsheet? ]
+ - picture (§3.3.1.65) [ BkHim E9h; see XclExpBitmap ]
+ - pivotArea (§3.3.1.66) [ ??? ]
+ - pivotSelection (§3.3.1.67) [ ??? ]
+ - protectedRange (§3.3.1.69) [ ??? ]
+ - protectedRanges (§3.3.1.70) [ ??? ]
+ - sheetCalcPr (§3.3.1.76) [ REFRESHALL?? ]
+ - sheetFormatPr (§3.3.1.78) [ lots of records? ]
+ @defaultColWidth: DefColWidth
+ @defaultRowHeight: DEFROWHEIGHT
+ @baseColWidth: ColInfo/coldx?
+ @customHeight: ColInfo/fUserSet?
+ @zeroHeight: ColInfo/fHidden?
+ @thickTop: ?
+ @thickBottom: ?
+ @outlineLevelRow: ?
+ @outlineLevelCol: ColInfo/iOutLevel?
+ - sheetPr (§3.3.1.80) [ ??? ; for charts ]
+ - sheetView (§3.3.1.84) [ ??? ; for charts ]
+ - sheetViews (§3.3.1.86) [ ??? ; for charts ]
+ - smartTags (§3.3.1.87) [ FEAT 868h; isf=ISFFACTOID ]
+ - sortCondition (§3.3.1.88) [ SortData 895h? ]
+ - sortState (§3.3.1.89) [ Sort 90h ]
+ - tabColor (§3.3.1.90) [ SheetExt 862h ]
+ - tablePart (§3.3.1.91) [ ??? ]
+ - tableParts (§3.3.1.92) [ ??? ]
+ - webPublishItem (§3.3.1.94) [ WebPub 801h ]
+ - webPublishItems (§3.3.1.95)
+ - AutoFilter Settings (§3.3.2):
+ - colorFilter (§3.3.2.1) [ AutoFilter12 87Eh,
+ DXFN12NoCB struct ]
+ - dateGroupItem (§3.3.2.4) [ AutoFilter12 87Eh,
+ AF12DateInfo struct ]
+ - dynamicFilter (§3.3.2.5) [ AutoFilter12 87Eh, cft field ]
+ - filter (§3.3.2.6) [ AutoFilter12 87Eh, rgCriteria? ]
+ - filters (§3.3.2.9) [ AutoFilter12 87Eh, rgCriteria? ]
+ - iconFilter (§3.3.2.9) [ AutoFilter12 87Eh,
+ AF12CellIcon struct ]
+ - Shared String Table (§3.4):
+ - phoneticPr (§3.4.3)
+ - rPh (§3.4.6)
+ - Tables (§3.5.1):
+ - calculatedColumnFormula (§3.5.1.1)
+ [ ??? ]
+ - table (§3.5.1.2) [ ??? ]
+ - tableColumn (§3.5.1.3) [ ??? ]
+ - tableColumns (§3.5.1.4) [ ??? ]
+ - tableStyleInfo (§3.5.1.5) [ ??? ]
+ - totalRowFormula (§3.5.1.6) [ ??? ]
+ - xmlColumnPr (§3.5.1.7) [ ??? ]
+ - Single Cell Tables (§3.5.2):
+ - singleXmlCell (§3.5.2.1) [ ??? ]
+ - singleXmlCells (§3.5.2.2) [ ??? ]
+ - xmlCellPr (§3.5.2.3) [ ??? ]
+ - xmlPr (§3.5.2.4) [ ??? ]
+ - Calculation Chain (§3.6):
+ - c (§3.6.1) [ ??? ]
+ - calcChain (§3.6.2) [ ??? ]
+ - Comments (§3.7):
+ - Note: Excel *requires* that there be a drawing object associated
+ with the comment before it will show it. If you _just_ generate the
+ <comments/> XML part and create a <Relationship/> for it, Excell
+ will NOT display the comment.
+ - As drawing is not currently implemented, comments support is
+ incomplete.
+ - TODO: text formatting. Currently we only write unformatted text
+ into comments?.xml, as I'm not sure how formatted text is handled.
+ - Styles (§3.8):
+ - dxf (§3.8.14): [ DXF 88Dh; unsupported ]
+ - dxfs (§3.8.15): [ DXF 88Dh ]
+ - gradientFill (§3.8.23): [ ??? ]
+ - horizontal (§3.8.24): [ DXF 88Dh fNewBorder, xfprops ]
+ - mruColors (§3.8.28): [ ??? ]
+ - scheme (§3.8.36): [ ??? ]
+ - stop (§3.8.38): [ ??? ]
+ - tableStyle (§3.8.40): [ TableStyle 88Fh; unsupported ]
+ - tableStyleElement (§3.8.41): [ TableStyleElement 890h; unsupported ]
+ - tableStyles (§3.8.42): [ TableStyles 88Eh; unsupported ]
+ - vertical (§3.8.44): [ DXF 88Dh fNewBorder, xfprops ]
+
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
new file mode 100644
index 000000000000..cfe5aedb867e
--- /dev/null
+++ b/sc/source/filter/excel/read.cxx
@@ -0,0 +1,1243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "document.hxx"
+#include "scerrors.hxx"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xltable.hxx"
+#include "xihelper.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+#include "xicontent.hxx"
+#include "xiescher.hxx"
+#include "xipivot.hxx"
+#include "XclImpChangeTrack.hxx"
+
+#include "root.hxx"
+#include "imp_op.hxx"
+#include "excimp8.hxx"
+
+FltError ImportExcel::Read( void )
+{
+ XclImpPageSettings& rPageSett = GetPageSettings();
+ XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
+ XclImpPalette& rPal = GetPalette();
+ XclImpFontBuffer& rFontBfr = GetFontBuffer();
+ XclImpNumFmtBuffer& rNumFmtBfr = GetNumFmtBuffer();
+ XclImpXFBuffer& rXFBfr = GetXFBuffer();
+ XclImpNameManager& rNameMgr = GetNameManager();
+ XclImpObjectManager& rObjMgr = GetObjectManager();
+ (void)rObjMgr;
+ // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
+
+ enum Zustand {
+ Z_BiffNull, // Nicht in gueltigem Biff-Format
+ Z_Biff2, // Biff2: nur eine Tabelle
+
+ Z_Biff3, // Biff3: nur eine Tabelle
+
+ Z_Biff4, // Biff4: nur eine Tabelle
+ Z_Biff4W, // Biff4 Workbook: Globals
+ Z_Biff4T, // Biff4 Workbook: eine Tabelle selbst
+ Z_Biff4E, // Biff4 Workbook: zwischen den Tabellen
+
+ Z_Biff5WPre,// Biff5: Prefetch Workbook
+ Z_Biff5W, // Biff5: Globals
+ Z_Biff5TPre,// Biff5: Prefetch fuer Shrfmla/Array Formula
+ Z_Biff5T, // Biff5: eine Tabelle selbst
+ Z_Biff5E, // Biff5: zwischen den Tabellen
+ Z_Biffn0, // Alle Biffs: Tabelle bis naechstesss EOF ueberlesen
+ Z_Ende };
+
+ Zustand eAkt = Z_BiffNull, ePrev = Z_BiffNull;
+
+ FltError eLastErr = eERR_OK;
+ UINT16 nOpcode;
+ UINT16 nBofLevel = 0;
+ BOOL bBiff4Workbook = FALSE;
+
+ DBG_ASSERT( &aIn != NULL, "-ImportExcel::Read(): Kein Stream - wie dass?!" );
+
+ ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
+ aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
+
+ /* #i104057# Need to track a base position for progress bar calculation,
+ because sheet substreams may not be in order of sheets. */
+ sal_Size nProgressBasePos = 0;
+ sal_Size nProgressBaseSize = 0;
+
+ while( eAkt != Z_Ende )
+ {
+ if( eAkt == Z_Biff5E )
+ {
+ sal_uInt16 nScTab = GetCurrScTab();
+ if( nScTab < maSheetOffsets.size() )
+ {
+ nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
+ nProgressBasePos = maSheetOffsets[ nScTab ];
+ aIn.StartNextRecord( nProgressBasePos );
+ }
+ else
+ eAkt = Z_Ende;
+ }
+ else
+ aIn.StartNextRecord();
+
+ nOpcode = aIn.GetRecId();
+
+ if( !aIn.IsValid() )
+ {
+ // #124240# finalize table if EOF is missing
+ switch( eAkt )
+ {
+ case Z_Biff2:
+ case Z_Biff3:
+ case Z_Biff4:
+ case Z_Biff4T:
+ case Z_Biff5TPre:
+ case Z_Biff5T:
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ break;
+ default:;
+ };
+ eAkt = Z_Ende;
+ break;
+ }
+
+ if( eAkt == Z_Ende )
+ break;
+
+ if( eAkt != Z_Biff5TPre && eAkt != Z_Biff5WPre )
+ pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
+
+ switch( eAkt )
+ {
+ // ----------------------------------------------------------------
+ case Z_BiffNull: // ------------------------------- Z_BiffNull -
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF:
+ {
+ // #i23425# don't rely on the record ID, but on the detected BIFF version
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ Bof2();
+ if( pExcRoot->eDateiTyp == Biff2 )
+ {
+ eAkt = Z_Biff2;
+ NeueTabelle();
+ }
+ break;
+ case EXC_BIFF3:
+ Bof3();
+ if( pExcRoot->eDateiTyp == Biff3 )
+ {
+ eAkt = Z_Biff3;
+ NeueTabelle();
+ }
+ break;
+ case EXC_BIFF4:
+ Bof4();
+ if( pExcRoot->eDateiTyp == Biff4 )
+ {
+ eAkt = Z_Biff4;
+ NeueTabelle();
+ }
+ else if( pExcRoot->eDateiTyp == Biff4W )
+ {
+ eAkt = Z_Biff4W;
+ bBiff4Workbook = TRUE;
+ }
+ break;
+ case EXC_BIFF5:
+ Bof5();
+ if( pExcRoot->eDateiTyp == Biff5W )
+ {
+ eAkt = Z_Biff5WPre;
+
+ nBdshtTab = 0;
+
+ aIn.StoreGlobalPosition(); // und Position merken
+ }
+ else if( pExcRoot->eDateiTyp == Biff5 )
+ {
+ // #i62752# possible to have BIFF5 sheet without globals
+ NeueTabelle();
+ eAkt = Z_Biff5TPre; // Shrfmla Prefetch, Row-Prefetch
+ nBofLevel = 0;
+ aIn.StoreGlobalPosition(); // und Position merken
+ }
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ }
+ break;
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff2: // ---------------------------------- Z_Biff2 -
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x06: Formula25(); break; // FORMULA [ 2 5]
+ case 0x08: Row25(); break; // ROW [ 2 5]
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ eAkt = Z_Ende;
+ break;
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x18: rNameMgr.ReadName( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x20: Columndefault(); break; // COLUMNDEFAULT[ 2 ]
+ case 0x21: Array25(); break; // ARRAY [ 2 5]
+ case 0x23: Externname25(); break; // EXTERNNAME [ 2 5]
+ case 0x24: Colwidth(); break; // COLWIDTH [ 2 ]
+ case 0x25: Defrowheight2(); break; // DEFAULTROWHEI[ 2 ]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID2_FONT: rFontBfr.ReadFont( maStrm ); break;
+ case EXC_ID_EFONT: rFontBfr.ReadEfont( maStrm ); break;
+ case 0x3E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x43: rXFBfr.ReadXF( maStrm ); break;
+ case 0x44: Ixfe(); break; // IXFE [ 2 ]
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff3: // ---------------------------------- Z_Biff3 -
+ {
+ switch( nOpcode )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ eAkt = Z_Ende;
+ break;
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x22: Rec1904(); break; // 1904 [ 2345]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x0206: Formula3(); break; // FORMULA [ 3 ]
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x0243: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4: // ---------------------------------- Z_Biff4 -
+ {
+ switch( nOpcode )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ eAkt = Z_Ende;
+ break;
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x22: Rec1904(); break; // 1904 [ 2345]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0xA1: rPageSett.ReadSetup( maStrm ); break;
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x0406: Formula4(); break; // FORMULA [ 4 ]
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x0443: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4W: // --------------------------------- Z_Biff4W -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Ende;
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5]
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x8F: Bundleheader(); break; // BUNDLEHEADER [ 4 ]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x0409: // BOF [ 4 ]
+ Bof4();
+ if( pExcRoot->eDateiTyp == Biff4 )
+ {
+ eAkt = Z_Biff4T;
+ NeueTabelle();
+ }
+ else
+ eAkt = Z_Ende;
+ break;
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x0443: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4T: // --------------------------------- Z_Biff4T -
+ {
+ switch( nOpcode )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0A: // EOF [ 2345]
+ Eof();
+ eAkt = Z_Biff4E;
+ break;
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x8F: Bundleheader(); break; // BUNDLEHEADER [ 4 ]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0xA1: rPageSett.ReadSetup( maStrm ); break;
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0221: Array34(); break;
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x0406: Formula4(); break;
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x0443: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4E: // --------------------------------- Z_Biff4E -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Ende;
+ break;
+ case 0x8F: break; // BUNDLEHEADER [ 4 ]
+ case 0x0409: // BOF [ 4 ]
+ Bof4();
+ NeueTabelle();
+ if( pExcRoot->eDateiTyp == Biff4 )
+ {
+ eAkt = Z_Biff4T;
+ }
+ else
+ {
+ ePrev = eAkt;
+ eAkt = Z_Biffn0;
+ }
+ break;
+ }
+
+ }
+ break;
+ case Z_Biff5WPre: // ------------------------------ Z_Biff5WPre -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Biff5W;
+ aIn.SeekGlobalPosition(); // und zurueck an alte Position
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5]
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x3D: Window1(); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x85: Boundsheet(); break; // BOUNDSHEET [ 5]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ // PALETTE follows XFs, but already needed while reading the XFs
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ }
+ }
+ break;
+ case Z_Biff5W: // --------------------------------- Z_Biff5W -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ rXFBfr.CreateUserStyles();
+ eAkt = Z_Biff5E;
+ break;
+ case 0x18: rNameMgr.ReadName( maStrm ); break;
+ case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x22: Rec1904(); break; // 1904 [ 2345]
+ case 0x31: rFontBfr.ReadFont( maStrm ); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x8D: Hideobj(); break; // HIDEOBJ [ 345]
+ case 0xDE: Olesize(); break;
+ case 0xE0: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff5TPre: // ------------------------------- Z_Biff5Pre -
+ {
+ if( nOpcode == 0x0809 )
+ nBofLevel++;
+ else if( (nOpcode == 0x000A) && nBofLevel )
+ nBofLevel--;
+ else if( !nBofLevel ) // don't read chart records
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case 0x08: Row25(); break; // ROW [ 2 5]
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Biff5T;
+ aIn.SeekGlobalPosition(); // und zurueck an alte Position
+ break;
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x21: Array25(); break; // ARRAY [ 2 5]
+ case 0x23: Externname25(); break; // EXTERNNAME [ 2 5]
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x81: Wsbool(); break; // WSBOOL [ 2345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5]
+ }
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff5T: // --------------------------------- Z_Biff5T -
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0006:
+ case 0x0206:
+ case 0x0406: Formula25(); break;
+ case 0x0A: Eof(); eAkt = Z_Biff5E; break;
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x23: Externname25(); break; // EXTERNNAME [ 2 5]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x83:
+ case 0x84: rPageSett.ReadCenter( maStrm ); break;
+ case 0xA0: rTabViewSett.ReadScl( maStrm ); break;
+ case 0xA1: rPageSett.ReadSetup( maStrm ); break;
+ case 0xBD: Mulrk(); break; // MULRK [ 5]
+ case 0xBE: Mulblank(); break; // MULBLANK [ 5]
+ case 0xD6: Rstring(); break; // RSTRING [ 5]
+ case 0x00E5: Cellmerging(); break; // #i62300#
+ case 0x0236: TableOp(); break; // TABLE [ 5]
+ case 0x0809: // BOF [ 5]
+ XclTools::SkipSubStream( maStrm );
+ break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff5E: // --------------------------------- Z_Biff5E -
+ {
+ switch( nOpcode )
+ {
+ case 0x0809: // BOF [ 5]
+ Bof5();
+ NeueTabelle();
+ switch( pExcRoot->eDateiTyp )
+ {
+ case Biff5:
+ case Biff5M4:
+ eAkt = Z_Biff5TPre; // Shrfmla Prefetch, Row-Prefetch
+ nBofLevel = 0;
+ aIn.StoreGlobalPosition(); // und Position merken
+ break;
+ case Biff5C: // chart sheet
+ GetCurrSheetDrawing().ReadTabChart( maStrm );
+ Eof();
+ GetTracer().TraceChartOnlySheet();
+ break;
+ case Biff5V:
+ default:
+ pD->SetVisible( GetCurrScTab(), FALSE );
+ ePrev = eAkt;
+ eAkt = Z_Biffn0;
+ }
+ DBG_ASSERT( pExcRoot->eDateiTyp != Biff5W,
+ "+ImportExcel::Read(): Doppel-Whopper-Workbook!" );
+
+ break;
+ }
+
+ }
+ break;
+ case Z_Biffn0: // --------------------------------- Z_Biffn0 -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = ePrev;
+ IncCurrScTab();
+ break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Ende: // ----------------------------------- Z_Ende -
+ DBG_ERROR( "*ImportExcel::Read(): Not possible state!" );
+ break;
+ default: DBG_ERROR( "-ImportExcel::Read(): Zustand vergessen!" );
+ }
+ }
+
+ if( eLastErr == eERR_OK )
+ {
+ pProgress.reset();
+
+ AdjustRowHeight();
+ PostDocLoad();
+
+ pD->CalcAfterLoad();
+
+ const XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsTabTruncated() )
+ eLastErr = SCWARN_IMPORT_SHEET_OVERFLOW;
+ else if( bTabTruncated || rAddrConv.IsRowTruncated() )
+ eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
+ else if( rAddrConv.IsColTruncated() )
+ eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
+ }
+
+ return eLastErr;
+}
+
+
+//___________________________________________________________________
+
+FltError ImportExcel8::Read( void )
+{
+#if EXC_INCL_DUMPER
+ {
+ Biff8RecDumper aDumper( GetRoot(), TRUE );
+ if( aDumper.Dump( aIn ) )
+ return ERRCODE_ABORT;
+ }
+#endif
+ // read the entire BIFF8 stream
+ // don't look too close - this stuff seriously needs to be reworked
+
+ XclImpPageSettings& rPageSett = GetPageSettings();
+ XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
+ XclImpPalette& rPal = GetPalette();
+ XclImpFontBuffer& rFontBfr = GetFontBuffer();
+ XclImpNumFmtBuffer& rNumFmtBfr = GetNumFmtBuffer();
+ XclImpXFBuffer& rXFBfr = GetXFBuffer();
+ XclImpSst& rSst = GetSst();
+ XclImpTabInfo& rTabInfo = GetTabInfo();
+ XclImpNameManager& rNameMgr = GetNameManager();
+ XclImpLinkManager& rLinkMgr = GetLinkManager();
+ XclImpObjectManager& rObjMgr = GetObjectManager();
+ // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
+ XclImpCondFormatManager& rCondFmtMgr = GetCondFormatManager();
+ XclImpPivotTableManager& rPTableMgr = GetPivotTableManager();
+ XclImpWebQueryBuffer& rWQBfr = GetWebQueryBuffer();
+
+ bool bInUserView = false; // true = In USERSVIEW(BEGIN|END) record block.
+
+ enum XclImpReadState
+ {
+ EXC_STATE_BEFORE_GLOBALS, /// Before workbook globals (wait for initial BOF).
+ EXC_STATE_GLOBALS_PRE, /// Prefetch for workbook globals.
+ EXC_STATE_GLOBALS, /// Workbook globals.
+ EXC_STATE_BEFORE_SHEET, /// Before worksheet (wait for new worksheet BOF).
+ EXC_STATE_SHEET_PRE, /// Prefetch for worksheet.
+ EXC_STATE_SHEET, /// Worksheet.
+ EXC_STATE_END /// Stop reading.
+ };
+
+ XclImpReadState eAkt = EXC_STATE_BEFORE_GLOBALS;
+
+ FltError eLastErr = eERR_OK;
+
+ ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
+ aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
+
+ /* #i104057# Need to track a base position for progress bar calculation,
+ because sheet substreams may not be in order of sheets. */
+ sal_Size nProgressBasePos = 0;
+ sal_Size nProgressBaseSize = 0;
+
+ while( eAkt != EXC_STATE_END )
+ {
+ if( eAkt == EXC_STATE_BEFORE_SHEET )
+ {
+ sal_uInt16 nScTab = GetCurrScTab();
+ if( nScTab < maSheetOffsets.size() )
+ {
+ nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
+ nProgressBasePos = maSheetOffsets[ nScTab ];
+ aIn.StartNextRecord( nProgressBasePos );
+ }
+ else
+ eAkt = EXC_STATE_END;
+ }
+ else
+ aIn.StartNextRecord();
+
+ if( !aIn.IsValid() )
+ {
+ // #124240# #i63591# finalize table if EOF is missing
+ switch( eAkt )
+ {
+ case EXC_STATE_SHEET_PRE:
+ eAkt = EXC_STATE_SHEET;
+ aIn.SeekGlobalPosition();
+ continue; // next iteration in while loop
+// break; // unxsols warning: statement unreachable
+ case EXC_STATE_SHEET:
+ Eof();
+ eAkt = EXC_STATE_END;
+ break;
+ default:
+ eAkt = EXC_STATE_END;
+ }
+ }
+
+ if( eAkt == EXC_STATE_END )
+ break;
+
+ if( eAkt != EXC_STATE_SHEET_PRE && eAkt != EXC_STATE_GLOBALS_PRE )
+ pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
+
+ sal_uInt16 nRecId = aIn.GetRecId();
+
+ /* #i39464# Ignore records between USERSVIEWBEGIN and USERSVIEWEND
+ completely (user specific view settings). Otherwise view settings
+ and filters are loaded multiple times, which at least causes
+ problems in auto-filters. */
+ switch( nRecId )
+ {
+ case EXC_ID_USERSVIEWBEGIN:
+ DBG_ASSERT( !bInUserView, "ImportExcel8::Read - nested user view settings" );
+ bInUserView = true;
+ break;
+ case EXC_ID_USERSVIEWEND:
+ DBG_ASSERT( bInUserView, "ImportExcel8::Read - not in user view settings" );
+ bInUserView = false;
+ break;
+ }
+
+ if( !bInUserView ) switch( eAkt )
+ {
+ // ----------------------------------------------------------------
+ // before workbook globals: wait for initial workbook globals BOF
+ case EXC_STATE_BEFORE_GLOBALS:
+ {
+ if( nRecId == EXC_ID5_BOF )
+ {
+ DBG_ASSERT( GetBiff() == EXC_BIFF8, "ImportExcel8::Read - wrong BIFF version" );
+ Bof5();
+ if( pExcRoot->eDateiTyp == Biff8W )
+ {
+ eAkt = EXC_STATE_GLOBALS_PRE;
+ maStrm.StoreGlobalPosition();
+ nBdshtTab = 0;
+ }
+ else if( pExcRoot->eDateiTyp == Biff8 )
+ {
+ // #i62752# possible to have BIFF8 sheet without globals
+ NeueTabelle();
+ eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
+ aIn.StoreGlobalPosition();
+ }
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // prefetch for workbook globals
+ case EXC_STATE_GLOBALS_PRE:
+ {
+ switch( nRecId )
+ {
+ case EXC_ID_EOF:
+ case EXC_ID_EXTSST:
+ /* #i56376# evil hack: if EOF for globals is missing,
+ simulate it. This hack works only for the bugdoc
+ given in the issue, where the sheet substreams
+ start directly after the EXTSST record. A future
+ implementation should be more robust against
+ missing EOFs. */
+ if( (nRecId == EXC_ID_EOF) ||
+ ((nRecId == EXC_ID_EXTSST) && (maStrm.GetNextRecId() == EXC_ID5_BOF)) )
+ {
+ eAkt = EXC_STATE_GLOBALS;
+ aIn.SeekGlobalPosition();
+ }
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5678]
+ case 0x13: DocPasssword(); break;
+ case 0x19: WinProtection(); break;
+ case 0x2F: // FILEPASS [ 2345 ]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = EXC_STATE_END;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x3D: Window1(); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345 ]
+ case 0x85: Boundsheet(); break; // BOUNDSHEET [ 5 ]
+ case 0x8C: Country(); break; // COUNTRY [ 345 ]
+
+ // PALETTE follows XFs, but already needed while reading the XFs
+ case EXC_ID_PALETTE: rPal.ReadPalette( maStrm ); break;
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // workbook globals
+ case EXC_STATE_GLOBALS:
+ {
+ switch( nRecId )
+ {
+ case EXC_ID_EOF:
+ case EXC_ID_EXTSST:
+ /* #i56376# evil hack: if EOF for globals is missing,
+ simulate it. This hack works only for the bugdoc
+ given in the issue, where the sheet substreams
+ start directly after the EXTSST record. A future
+ implementation should be more robust against
+ missing EOFs. */
+ if( (nRecId == EXC_ID_EOF) ||
+ ((nRecId == EXC_ID_EXTSST) && (maStrm.GetNextRecId() == EXC_ID5_BOF)) )
+ {
+ rNumFmtBfr.CreateScFormats();
+ rXFBfr.CreateUserStyles();
+ rPTableMgr.ReadPivotCaches( maStrm );
+ eAkt = EXC_STATE_BEFORE_SHEET;
+ }
+ break;
+ case 0x0E: Precision(); break; // PRECISION
+ case 0x22: Rec1904(); break; // 1904 [ 2345 ]
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x8D: Hideobj(); break; // HIDEOBJ [ 345 ]
+ case 0xD3: SetHasBasic(); break;
+ case 0xDE: Olesize(); break;
+
+ case EXC_ID_CODENAME: ReadCodeName( aIn, true ); break;
+ case EXC_ID_USESELFS: ReadUsesElfs(); break;
+
+ case EXC_ID2_FONT: rFontBfr.ReadFont( maStrm ); break;
+ case EXC_ID4_FORMAT: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case EXC_ID5_XF: rXFBfr.ReadXF( maStrm ); break;
+ case EXC_ID_STYLE: rXFBfr.ReadStyle( maStrm ); break;
+
+ case EXC_ID_SST: rSst.ReadSst( maStrm ); break;
+ case EXC_ID_TABID: rTabInfo.ReadTabid( maStrm ); break;
+ case EXC_ID_NAME: rNameMgr.ReadName( maStrm ); break;
+
+ case EXC_ID_EXTERNSHEET: rLinkMgr.ReadExternsheet( maStrm ); break;
+ case EXC_ID_SUPBOOK: rLinkMgr.ReadSupbook( maStrm ); break;
+ case EXC_ID_XCT: rLinkMgr.ReadXct( maStrm ); break;
+ case EXC_ID_CRN: rLinkMgr.ReadCrn( maStrm ); break;
+ case EXC_ID_EXTERNNAME: rLinkMgr.ReadExternname( maStrm, pFormConv ); break;
+
+ case EXC_ID_MSODRAWINGGROUP:rObjMgr.ReadMsoDrawingGroup( maStrm ); break;
+
+ case EXC_ID_SXIDSTM: rPTableMgr.ReadSxidstm( maStrm ); break;
+ case EXC_ID_SXVS: rPTableMgr.ReadSxvs( maStrm ); break;
+ case EXC_ID_DCONREF: rPTableMgr.ReadDconref( maStrm ); break;
+ }
+
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // before worksheet: wait for new worksheet BOF
+ case EXC_STATE_BEFORE_SHEET:
+ {
+ if( nRecId == EXC_ID5_BOF )
+ {
+ // #94191# import only 256 sheets
+ if( GetCurrScTab() > GetScMaxPos().Tab() )
+ {
+ XclTools::SkipSubStream( maStrm );
+ // #i29930# show warning box
+ GetAddressConverter().CheckScTab( GetCurrScTab(), true );
+ eAkt = EXC_STATE_END;
+ }
+ else
+ {
+ Bof5();
+ NeueTabelle();
+ switch( pExcRoot->eDateiTyp )
+ {
+ case Biff8: // worksheet
+ case Biff8M4: // macro sheet
+ eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
+ aIn.StoreGlobalPosition();
+ break;
+ case Biff8C: // chart sheet
+ GetCurrSheetDrawing().ReadTabChart( maStrm );
+ Eof();
+ GetTracer().TraceChartOnlySheet();
+ break;
+ case Biff8W: // workbook
+ DBG_ERRORFILE( "ImportExcel8::Read - double workbook globals" );
+ // run through
+ case Biff8V: // VB module
+ default:
+ // TODO: do not create a sheet in the Calc document
+ pD->SetVisible( GetCurrScTab(), FALSE );
+ XclTools::SkipSubStream( maStrm );
+ IncCurrScTab();
+ }
+ }
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // prefetch for worksheet
+ case EXC_STATE_SHEET_PRE:
+ {
+ switch( nRecId )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case EXC_ID_SCL: rTabViewSett.ReadScl( maStrm ); break;
+ case EXC_ID_PANE: rTabViewSett.ReadPane( maStrm ); break;
+ case EXC_ID_SELECTION: rTabViewSett.ReadSelection( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+
+ case EXC_ID_CODENAME: ReadCodeName( aIn, false ); break;
+
+ case 0x0A: // EOF [ 2345 ]
+ eAkt = EXC_STATE_SHEET;
+ aIn.SeekGlobalPosition(); // und zurueck an alte Position
+ break;
+ case 0x12: SheetProtect(); break;
+ case 0x13: SheetPassword(); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345 ]
+ case 0x55: DefColWidth(); break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345 ]
+ case 0x81: Wsbool(); break; // WSBOOL [ 2345 ]
+ case 0x8C: Country(); break; // COUNTRY [ 345 ]
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45 ]
+ case 0x9B: FilterMode(); break; // FILTERMODE
+ case 0x9D: AutoFilterInfo(); break;// AUTOFILTERINFO
+ case 0x9E: AutoFilter(); break; // AUTOFILTER
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0021:
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
+ case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
+ case 0x0867: SheetProtection(); break; // SHEETPROTECTION
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // worksheet
+ case EXC_STATE_SHEET:
+ {
+ switch( nRecId )
+ {
+ // skip unknown substreams
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID_EOF: Eof(); eAkt = EXC_STATE_BEFORE_SHEET; break;
+
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0006:
+ case 0x0206:
+ case 0x0406: Formula25(); break; // FORMULA [ 2 5 ]
+ case 0x000C: Calccount(); break; // CALCCOUNT
+ case 0x0010: Delta(); break; // DELTA
+ case 0x0011: Iteration(); break; // ITERATION
+ case 0x007E:
+ case 0x00AE: Scenman(); break; // SCENMAN
+ case 0x00AF: Scenario(); break; // SCENARIO
+ case 0x00BD: Mulrk(); break; // MULRK [ 5 ]
+ case 0x00BE: Mulblank(); break; // MULBLANK [ 5 ]
+ case 0x00D6: Rstring(); break; // RSTRING [ 5 ]
+ case 0x00E5: Cellmerging(); break; // CELLMERGING
+ case 0x00FD: Labelsst(); break; // LABELSST [ 8 ]
+ case 0x0236: TableOp(); break; // TABLE
+
+ case EXC_ID_HORPAGEBREAKS:
+ case EXC_ID_VERPAGEBREAKS: rPageSett.ReadPageBreaks( maStrm ); break;
+ case EXC_ID_HEADER:
+ case EXC_ID_FOOTER: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case EXC_ID_LEFTMARGIN:
+ case EXC_ID_RIGHTMARGIN:
+ case EXC_ID_TOPMARGIN:
+ case EXC_ID_BOTTOMMARGIN: rPageSett.ReadMargin( maStrm ); break;
+ case EXC_ID_PRINTHEADERS: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case EXC_ID_HCENTER:
+ case EXC_ID_VCENTER: rPageSett.ReadCenter( maStrm ); break;
+ case EXC_ID_SETUP: rPageSett.ReadSetup( maStrm ); break;
+ case EXC_ID8_IMGDATA: rPageSett.ReadImgData( maStrm ); break;
+
+ case EXC_ID_MSODRAWING: GetCurrSheetDrawing().ReadMsoDrawing( maStrm ); break;
+ // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
+ case EXC_ID_OBJ: GetCurrSheetDrawing().ReadObj( maStrm ); break;
+ case EXC_ID_NOTE: GetCurrSheetDrawing().ReadNote( maStrm ); break;
+
+ case EXC_ID_HLINK: XclImpHyperlink::ReadHlink( maStrm ); break;
+ case EXC_ID_LABELRANGES: XclImpLabelranges::ReadLabelranges( maStrm ); break;
+
+ case EXC_ID_CONDFMT: rCondFmtMgr.ReadCondfmt( maStrm ); break;
+ case EXC_ID_CF: rCondFmtMgr.ReadCF( maStrm ); break;
+
+ case EXC_ID_DVAL: XclImpValidation::ReadDval( maStrm ); break;
+ case EXC_ID_DV: XclImpValidation::ReadDV( maStrm ); break;
+
+ case EXC_ID_QSI: rWQBfr.ReadQsi( maStrm ); break;
+ case EXC_ID_WQSTRING: rWQBfr.ReadWqstring( maStrm ); break;
+ case EXC_ID_PQRY: rWQBfr.ReadParamqry( maStrm ); break;
+ case EXC_ID_WQSETT: rWQBfr.ReadWqsettings( maStrm ); break;
+ case EXC_ID_WQTABLES: rWQBfr.ReadWqtables( maStrm ); break;
+
+ case EXC_ID_SXVIEW: rPTableMgr.ReadSxview( maStrm ); break;
+ case EXC_ID_SXVD: rPTableMgr.ReadSxvd( maStrm ); break;
+ case EXC_ID_SXVI: rPTableMgr.ReadSxvi( maStrm ); break;
+ case EXC_ID_SXIVD: rPTableMgr.ReadSxivd( maStrm ); break;
+ case EXC_ID_SXPI: rPTableMgr.ReadSxpi( maStrm ); break;
+ case EXC_ID_SXDI: rPTableMgr.ReadSxdi( maStrm ); break;
+ case EXC_ID_SXVDEX: rPTableMgr.ReadSxvdex( maStrm ); break;
+ case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break;
+ case EXC_ID_SHEETEXT: rTabViewSett.ReadTabBgColor( maStrm, rPal ); break;
+ case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break;
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ default:;
+ }
+ }
+
+ if( eLastErr == eERR_OK )
+ {
+ // #i45843# Convert pivot tables before calculation, so they are available
+ // for the GETPIVOTDATA function.
+ if( GetBiff() == EXC_BIFF8 )
+ GetPivotTableManager().ConvertPivotTables();
+
+ pProgress.reset();
+
+ if (pD->IsAdjustHeightEnabled())
+ AdjustRowHeight();
+
+ PostDocLoad();
+
+ pD->CalcAfterLoad();
+
+ // import change tracking data
+ XclImpChangeTrack aImpChTr( GetRoot(), maStrm );
+ aImpChTr.Apply();
+
+ const XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsTabTruncated() )
+ eLastErr = SCWARN_IMPORT_SHEET_OVERFLOW;
+ else if( bTabTruncated || rAddrConv.IsRowTruncated() )
+ eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
+ else if( rAddrConv.IsColTruncated() )
+ eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
+
+ if( GetBiff() == EXC_BIFF8 )
+ GetPivotTableManager().MaybeRefreshPivotTables();
+ }
+
+ return eLastErr;
+}
+
+//___________________________________________________________________
+
diff --git a/sc/source/filter/excel/tokstack.cxx b/sc/source/filter/excel/tokstack.cxx
new file mode 100644
index 000000000000..b61a844d02a5
--- /dev/null
+++ b/sc/source/filter/excel/tokstack.cxx
@@ -0,0 +1,888 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#ifndef PCH
+#include <string.h>
+#endif
+
+#include "compiler.hxx"
+#include "tokstack.hxx"
+#include "global.hxx"
+#include "scmatrix.hxx"
+
+#include <stdio.h> // printf
+
+const UINT16 TokenPool::nScTokenOff = 8192;
+
+
+TokenStack::TokenStack( UINT16 nNewSize )
+{
+ pStack = new TokenId[ nNewSize ];
+
+ Reset();
+ nSize = nNewSize;
+}
+
+
+TokenStack::~TokenStack()
+{
+ delete[] pStack;
+}
+
+
+
+
+//------------------------------------------------------------------------
+
+// !ACHTUNG!: nach Aussen hin beginnt die Nummerierung mit 1!
+// !ACHTUNG!: SC-Token werden mit einem Offset nScTokenOff abgelegt
+// -> Unterscheidung von anderen Token
+
+
+TokenPool::TokenPool( void )
+{
+ UINT16 nLauf = nScTokenOff;
+
+ // Sammelstelle fuer Id-Folgen
+ nP_Id = 256;
+ pP_Id = new UINT16[ nP_Id ];
+
+ // Sammelstelle fuer Ids
+ nElement = 32;
+ pElement = new UINT16[ nElement ];
+ pType = new E_TYPE[ nElement ];
+ pSize = new UINT16[ nElement ];
+ nP_IdLast = 0;
+
+ // Sammelstelle fuer Strings
+ nP_Str = 4;
+ ppP_Str = new String *[ nP_Str ];
+ for( nLauf = 0 ; nLauf < nP_Str ; nLauf++ )
+ ppP_Str[ nLauf ] = NULL;
+
+ // Sammelstelle fuer double
+ nP_Dbl = 8;
+ pP_Dbl = new double[ nP_Dbl ];
+
+ // Sammelstelle fuer error codes
+ nP_Err = 8;
+ pP_Err = new USHORT[ nP_Err ];
+
+ // Sammelstellen fuer Referenzen
+ nP_RefTr = 32;
+ ppP_RefTr = new ScSingleRefData *[ nP_RefTr ];
+ for( nLauf = 0 ; nLauf < nP_RefTr ; nLauf++ )
+ ppP_RefTr[ nLauf ] = NULL;
+
+ nP_Ext = 32;
+ ppP_Ext = new EXTCONT*[ nP_Ext ];
+ memset( ppP_Ext, 0, sizeof( EXTCONT* ) * nP_Ext );
+
+ nP_Nlf = 16;
+ ppP_Nlf = new NLFCONT*[ nP_Nlf ];
+ memset( ppP_Nlf, 0, sizeof( NLFCONT* ) * nP_Nlf );
+
+ nP_Matrix = 16;
+ ppP_Matrix = new ScMatrix*[ nP_Matrix ];
+ memset( ppP_Matrix, 0, sizeof( ScMatrix* ) * nP_Matrix );
+
+ pScToken = new ScTokenArray;
+
+ Reset();
+}
+
+
+TokenPool::~TokenPool()
+{
+ UINT16 n;
+
+ delete[] pP_Id;
+ delete[] pElement;
+ delete[] pType;
+ delete[] pSize;
+ delete[] pP_Dbl;
+ delete[] pP_Err;
+
+ for( n = 0 ; n < nP_RefTr ; n++/*, pAktTr++*/ )
+ {
+ if( ppP_RefTr[ n ] )
+ delete ppP_RefTr[ n ];
+ }
+ delete[] ppP_RefTr;
+
+ for( n = 0 ; n < nP_Str ; n++/*, pAktStr++*/ )
+ {
+ if( ppP_Str[ n ] )
+ delete ppP_Str[ n ];
+ }
+ delete[] ppP_Str;
+
+ for( n = 0 ; n < nP_Ext ; n++ )
+ {
+ if( ppP_Ext[ n ] )
+ delete ppP_Ext[ n ];
+ }
+ delete[] ppP_Ext;
+
+ for( n = 0 ; n < nP_Nlf ; n++ )
+ {
+ if( ppP_Nlf[ n ] )
+ delete ppP_Nlf[ n ];
+ }
+ delete[] ppP_Nlf;
+
+ for( n = 0 ; n < nP_Matrix ; n++ )
+ {
+ if( ppP_Matrix[ n ] )
+ ppP_Matrix[ n ]->DecRef( );
+ }
+ delete[] ppP_Matrix;
+
+ delete pScToken;
+}
+
+
+void TokenPool::GrowString( void )
+{
+ UINT16 nP_StrNew = nP_Str * 2;
+ UINT16 nL;
+
+ String** ppP_StrNew = new String *[ nP_StrNew ];
+
+ for( nL = 0 ; nL < nP_Str ; nL++ )
+ ppP_StrNew[ nL ] = ppP_Str[ nL ];
+ for( nL = nP_Str ; nL < nP_StrNew ; nL++ )
+ ppP_StrNew[ nL ] = NULL;
+
+ nP_Str = nP_StrNew;
+
+ delete[] ppP_Str;
+ ppP_Str = ppP_StrNew;
+}
+
+
+void TokenPool::GrowDouble( void )
+{
+ UINT16 nP_DblNew = nP_Dbl * 2;
+
+ double* pP_DblNew = new double[ nP_DblNew ];
+
+ for( UINT16 nL = 0 ; nL < nP_Dbl ; nL++ )
+ pP_DblNew[ nL ] = pP_Dbl[ nL ];
+
+ nP_Dbl = nP_DblNew;
+
+ delete[] pP_Dbl;
+ pP_Dbl = pP_DblNew;
+}
+
+
+//UNUSED2009-05 void TokenPool::GrowError( void )
+//UNUSED2009-05 {
+//UNUSED2009-05 UINT16 nP_ErrNew = nP_Err * 2;
+//UNUSED2009-05
+//UNUSED2009-05 USHORT* pP_ErrNew = new USHORT[ nP_ErrNew ];
+//UNUSED2009-05
+//UNUSED2009-05 for( UINT16 nL = 0 ; nL < nP_Err ; nL++ )
+//UNUSED2009-05 pP_ErrNew[ nL ] = pP_Err[ nL ];
+//UNUSED2009-05
+//UNUSED2009-05 nP_Err = nP_ErrNew;
+//UNUSED2009-05
+//UNUSED2009-05 delete[] pP_Err;
+//UNUSED2009-05 pP_Err = pP_ErrNew;
+//UNUSED2009-05 }
+
+
+void TokenPool::GrowTripel( void )
+{
+ UINT16 nP_RefTrNew = nP_RefTr * 2;
+ UINT16 nL;
+
+ ScSingleRefData** ppP_RefTrNew = new ScSingleRefData *[ nP_RefTrNew ];
+
+ for( nL = 0 ; nL < nP_RefTr ; nL++ )
+ ppP_RefTrNew[ nL ] = ppP_RefTr[ nL ];
+ for( nL = nP_RefTr ; nL < nP_RefTrNew ; nL++ )
+ ppP_RefTrNew[ nL ] = NULL;
+
+ nP_RefTr = nP_RefTrNew;
+
+ delete[] ppP_RefTr;
+ ppP_RefTr = ppP_RefTrNew;
+}
+
+
+void TokenPool::GrowId( void )
+{
+ UINT16 nP_IdNew = nP_Id * 2;
+
+ UINT16* pP_IdNew = new UINT16[ nP_IdNew ];
+
+ for( UINT16 nL = 0 ; nL < nP_Id ; nL++ )
+ pP_IdNew[ nL ] = pP_Id[ nL ];
+
+ nP_Id = nP_IdNew;
+
+ delete[] pP_Id;
+ pP_Id = pP_IdNew;
+}
+
+
+void TokenPool::GrowElement( void )
+{
+ UINT16 nElementNew = nElement * 2;
+
+ UINT16* pElementNew = new UINT16[ nElementNew ];
+ E_TYPE* pTypeNew = new E_TYPE[ nElementNew ];
+ UINT16* pSizeNew = new UINT16[ nElementNew ];
+
+ for( UINT16 nL = 0 ; nL < nElement ; nL++ )
+ {
+ pElementNew[ nL ] = pElement[ nL ];
+ pTypeNew[ nL ] = pType[ nL ];
+ pSizeNew[ nL ] = pSize[ nL ];
+ }
+
+ nElement = nElementNew;
+
+ delete[] pElement;
+ delete[] pType;
+ delete[] pSize;
+ pElement = pElementNew;
+ pType = pTypeNew;
+ pSize = pSizeNew;
+}
+
+
+void TokenPool::GrowExt( void )
+{
+ UINT16 nNewSize = nP_Ext * 2;
+
+ EXTCONT** ppNew = new EXTCONT*[ nNewSize ];
+
+ memset( ppNew, 0, sizeof( EXTCONT* ) * nNewSize );
+ memcpy( ppNew, ppP_Ext, sizeof( EXTCONT* ) * nP_Ext );
+
+ delete[] ppP_Ext;
+ ppP_Ext = ppNew;
+ nP_Ext = nNewSize;
+}
+
+
+void TokenPool::GrowNlf( void )
+{
+ UINT16 nNewSize = nP_Nlf * 2;
+
+ NLFCONT** ppNew = new NLFCONT*[ nNewSize ];
+
+ memset( ppNew, 0, sizeof( NLFCONT* ) * nNewSize );
+ memcpy( ppNew, ppP_Nlf, sizeof( NLFCONT* ) * nP_Nlf );
+
+ delete[] ppP_Nlf;
+ ppP_Nlf = ppNew;
+ nP_Nlf = nNewSize;
+}
+
+
+void TokenPool::GrowMatrix( void )
+{
+ UINT16 nNewSize = nP_Matrix * 2;
+
+ ScMatrix** ppNew = new ScMatrix*[ nNewSize ];
+
+ memset( ppNew, 0, sizeof( ScMatrix* ) * nNewSize );
+ memcpy( ppNew, ppP_Matrix, sizeof( ScMatrix* ) * nP_Matrix );
+
+ delete[] ppP_Matrix;
+ ppP_Matrix = ppNew;
+ nP_Matrix = nNewSize;
+}
+
+void TokenPool::GetElement( const UINT16 nId )
+{
+ DBG_ASSERT( nId < nElementAkt, "*TokenPool::GetElement(): Id zu gross!?" );
+
+ if( pType[ nId ] == T_Id )
+ GetElementRek( nId );
+ else
+ {
+ switch( pType[ nId ] )
+ {
+#ifdef DBG_UTIL
+ case T_Id:
+ DBG_ERROR( "-TokenPool::GetElement(): hier hast Du nichts zu suchen!" );
+ break;
+#endif
+ case T_Str:
+ pScToken->AddString( ppP_Str[ pElement[ nId ] ]->GetBuffer() );
+ break;
+ case T_D:
+ pScToken->AddDouble( pP_Dbl[ pElement[ nId ] ] );
+ break;
+ case T_Err:
+#if 0 // erAck
+ pScToken->AddError( pP_Err[ pElement[ nId ] ] );
+#endif
+ break;
+ case T_RefC:
+ pScToken->AddSingleReference( *ppP_RefTr[ pElement[ (UINT16) nId ] ] );
+ break;
+ case T_RefA:
+ {
+ ScComplexRefData aScComplexRefData;
+ aScComplexRefData.Ref1 = *ppP_RefTr[ pElement[ nId ] ];
+ aScComplexRefData.Ref2 = *ppP_RefTr[ pElement[ nId ] + 1 ];
+ pScToken->AddDoubleReference( aScComplexRefData );
+ }
+ break;
+ case T_RN:
+ pScToken->AddName( pElement[ nId ] );
+ break;
+ case T_Ext:
+ {
+ UINT16 n = pElement[ nId ];
+ EXTCONT* p = ( n < nP_Ext )? ppP_Ext[ n ] : NULL;
+
+ if( p )
+ {
+ if( p->eId == ocEuroConvert )
+ pScToken->AddOpCode( p->eId );
+ else
+ pScToken->AddExternal( p->aText, p->eId );
+ }
+ }
+ break;
+ case T_Nlf:
+ {
+ UINT16 n = pElement[ nId ];
+ NLFCONT* p = ( n < nP_Nlf )? ppP_Nlf[ n ] : NULL;
+
+ if( p )
+ pScToken->AddColRowName( p->aRef );
+ }
+ break;
+ case T_Matrix:
+ {
+ UINT16 n = pElement[ nId ];
+ ScMatrix* p = ( n < nP_Matrix )? ppP_Matrix[ n ] : NULL;
+
+ if( p )
+ pScToken->AddMatrix( p );
+ }
+ break;
+ case T_ExtName:
+ {
+ UINT16 n = pElement[nId];
+ if (n < maExtNames.size())
+ {
+ const ExtName& r = maExtNames[n];
+ pScToken->AddExternalName(r.mnFileId, r.maName);
+ }
+ }
+ case T_ExtRefC:
+ {
+ UINT16 n = pElement[nId];
+ if (n < maExtCellRefs.size())
+ {
+ const ExtCellRef& r = maExtCellRefs[n];
+ pScToken->AddExternalSingleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ case T_ExtRefA:
+ {
+ UINT16 n = pElement[nId];
+ if (n < maExtAreaRefs.size())
+ {
+ const ExtAreaRef& r = maExtAreaRefs[n];
+ pScToken->AddExternalDoubleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ break;
+ default:
+ DBG_ERROR("-TokenPool::GetElement(): Zustand undefiniert!?");
+ }
+ }
+}
+
+
+void TokenPool::GetElementRek( const UINT16 nId )
+{
+#ifdef DBG_UTIL
+ nRek++;
+ DBG_ASSERT( nRek <= nP_Id, "*TokenPool::GetElement(): Rekursion loopt!?" );
+#endif
+
+ DBG_ASSERT( nId < nElementAkt, "*TokenPool::GetElementRek(): Id zu gross!?" );
+
+ DBG_ASSERT( pType[ nId ] == T_Id, "-TokenPool::GetElementRek(): nId nicht Id-Folge!" );
+
+
+ UINT16 nAnz = pSize[ nId ];
+ UINT16* pAkt = &pP_Id[ pElement[ nId ] ];
+ for( ; nAnz > 0 ; nAnz--, pAkt++ )
+ {
+ if( *pAkt < nScTokenOff )
+ {// Rekursion oder nicht?
+ switch( pType[ *pAkt ] )
+ {
+ case T_Id:
+ GetElementRek( *pAkt );
+ break;
+ case T_Str:
+ pScToken->AddString( ppP_Str[ pElement[ *pAkt ] ]->GetBuffer() );
+ break;
+ case T_D:
+ pScToken->AddDouble( pP_Dbl[ pElement[ *pAkt ] ] );
+ break;
+ case T_Err:
+#if 0 // erAck
+ pScToken->AddError( pP_Err[ pElement[ *pAkt ] ] );
+#endif
+ break;
+ case T_RefC:
+ pScToken->AddSingleReference( *ppP_RefTr[ pElement[ *pAkt ] ] );
+ break;
+ case T_RefA:
+ {
+ ScComplexRefData aScComplexRefData;
+ aScComplexRefData.Ref1 = *ppP_RefTr[ pElement[ *pAkt ] ];
+ aScComplexRefData.Ref2 = *ppP_RefTr[ pElement[ *pAkt ] + 1 ];
+ pScToken->AddDoubleReference( aScComplexRefData );
+ }
+ break;
+ case T_RN:
+ pScToken->AddName( pElement[ *pAkt ] );
+ break;
+ case T_Ext:
+ {
+ UINT16 n = pElement[ *pAkt ];
+ EXTCONT* p = ( n < nP_Ext )? ppP_Ext[ n ] : NULL;
+
+ if( p )
+ pScToken->AddExternal( p->aText, p->eId );
+ }
+ break;
+ case T_Nlf:
+ {
+ UINT16 n = pElement[ *pAkt ];
+ NLFCONT* p = ( n < nP_Nlf )? ppP_Nlf[ n ] : NULL;
+
+ if( p )
+ pScToken->AddColRowName( p->aRef );
+ }
+ break;
+ case T_Matrix:
+ {
+ UINT16 n = pElement[ *pAkt ];
+ ScMatrix* p = ( n < nP_Matrix )? ppP_Matrix[ n ] : NULL;
+
+ if( p )
+ pScToken->AddMatrix( p );
+ }
+ break;
+ case T_ExtName:
+ {
+ UINT16 n = pElement[*pAkt];
+ if (n < maExtNames.size())
+ {
+ const ExtName& r = maExtNames[n];
+ pScToken->AddExternalName(r.mnFileId, r.maName);
+ }
+ }
+ case T_ExtRefC:
+ {
+ UINT16 n = pElement[*pAkt];
+ if (n < maExtCellRefs.size())
+ {
+ const ExtCellRef& r = maExtCellRefs[n];
+ pScToken->AddExternalSingleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ case T_ExtRefA:
+ {
+ UINT16 n = pElement[*pAkt];
+ if (n < maExtAreaRefs.size())
+ {
+ const ExtAreaRef& r = maExtAreaRefs[n];
+ pScToken->AddExternalDoubleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ break;
+ default:
+ DBG_ERROR("-TokenPool::GetElementRek(): Zustand undefiniert!?");
+ }
+ }
+ else // elementarer SC_Token
+ pScToken->AddOpCode( ( DefTokenId ) ( *pAkt - nScTokenOff ) );
+ }
+
+
+#ifdef DBG_UTIL
+ nRek--;
+#endif
+}
+
+
+void TokenPool::operator >>( TokenId& rId )
+{
+ rId = ( TokenId ) ( nElementAkt + 1 );
+
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[ nElementAkt ] = nP_IdLast; // Start der Token-Folge
+ pType[ nElementAkt ] = T_Id; // Typinfo eintragen
+ pSize[ nElementAkt ] = nP_IdAkt - nP_IdLast;
+ // von nP_IdLast bis nP_IdAkt-1 geschrieben -> Laenge der Folge
+
+ nElementAkt++; // Startwerte fuer naechste Folge
+ nP_IdLast = nP_IdAkt;
+}
+
+
+const TokenId TokenPool::Store( const double& rDouble )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_DblAkt >= nP_Dbl )
+ GrowDouble();
+
+ pElement[ nElementAkt ] = nP_DblAkt; // Index in Double-Array
+ pType[ nElementAkt ] = T_D; // Typinfo Double eintragen
+
+ pP_Dbl[ nP_DblAkt ] = rDouble;
+
+ pSize[ nElementAkt ] = 1; // eigentlich Banane
+
+ nElementAkt++;
+ nP_DblAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const UINT16 nIndex )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[ nElementAkt ] = nIndex; // Daten direkt im Index!
+ pType[ nElementAkt ] = T_RN; // Typinfo Range Name eintragen
+
+ nElementAkt++;
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const String& rString )
+{
+ // weitgehend nach Store( const sal_Char* ) kopiert, zur Vermeidung
+ // eines temporaeren Strings in "
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_StrAkt >= nP_Str )
+ GrowString();
+
+ pElement[ nElementAkt ] = nP_StrAkt; // Index in String-Array
+ pType[ nElementAkt ] = T_Str; // Typinfo String eintragen
+
+ // String anlegen
+ if( !ppP_Str[ nP_StrAkt ] )
+ //...aber nur, wenn noch nicht vorhanden
+ ppP_Str[ nP_StrAkt ] = new String( rString );
+ else
+ //...ansonsten nur kopieren
+ *ppP_Str[ nP_StrAkt ] = rString;
+
+ DBG_ASSERT( sizeof( xub_StrLen ) <= 2, "*TokenPool::Store(): StrLen doesn't match!" );
+
+ pSize[ nElementAkt ] = ( UINT16 ) ppP_Str[ nP_StrAkt ]->Len();
+
+ nElementAkt++;
+ nP_StrAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const ScSingleRefData& rTr )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_RefTrAkt >= nP_RefTr )
+ GrowTripel();
+
+ pElement[ nElementAkt ] = nP_RefTrAkt;
+ pType[ nElementAkt ] = T_RefC; // Typinfo Cell-Reff eintragen
+
+ if( !ppP_RefTr[ nP_RefTrAkt ] )
+ ppP_RefTr[ nP_RefTrAkt ] = new ScSingleRefData( rTr );
+ else
+ *ppP_RefTr[ nP_RefTrAkt ] = rTr;
+
+ nElementAkt++;
+ nP_RefTrAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const ScComplexRefData& rTr )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_RefTrAkt + 1 >= nP_RefTr )
+ GrowTripel();
+
+ pElement[ nElementAkt ] = nP_RefTrAkt;
+ pType[ nElementAkt ] = T_RefA; // Typinfo Area-Reff eintragen
+
+ if( !ppP_RefTr[ nP_RefTrAkt ] )
+ ppP_RefTr[ nP_RefTrAkt ] = new ScSingleRefData( rTr.Ref1 );
+ else
+ *ppP_RefTr[ nP_RefTrAkt ] = rTr.Ref1;
+ nP_RefTrAkt++;
+
+ if( !ppP_RefTr[ nP_RefTrAkt ] )
+ ppP_RefTr[ nP_RefTrAkt ] = new ScSingleRefData( rTr.Ref2 );
+ else
+ *ppP_RefTr[ nP_RefTrAkt ] = rTr.Ref2;
+ nP_RefTrAkt++;
+
+ nElementAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const DefTokenId e, const String& r )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_ExtAkt >= nP_Ext )
+ GrowExt();
+
+ pElement[ nElementAkt ] = nP_ExtAkt;
+ pType[ nElementAkt ] = T_Ext; // Typinfo String eintragen
+
+ if( ppP_Ext[ nP_ExtAkt ] )
+ {
+ ppP_Ext[ nP_ExtAkt ]->eId = e;
+ ppP_Ext[ nP_ExtAkt ]->aText = r;
+ }
+ else
+ ppP_Ext[ nP_ExtAkt ] = new EXTCONT( e, r );
+
+ nElementAkt++;
+ nP_ExtAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::StoreNlf( const ScSingleRefData& rTr )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_NlfAkt >= nP_Nlf )
+ GrowNlf();
+
+ pElement[ nElementAkt ] = nP_NlfAkt;
+ pType[ nElementAkt ] = T_Nlf;
+
+ if( ppP_Nlf[ nP_NlfAkt ] )
+ {
+ ppP_Nlf[ nP_NlfAkt ]->aRef = rTr;
+ }
+ else
+ ppP_Nlf[ nP_NlfAkt ] = new NLFCONT( rTr );
+
+ nElementAkt++;
+ nP_NlfAkt++;
+
+ return ( const TokenId ) nElementAkt;
+}
+
+const TokenId TokenPool::StoreMatrix()
+{
+ ScMatrix* pM;
+
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_MatrixAkt >= nP_Matrix )
+ GrowMatrix();
+
+ pElement[ nElementAkt ] = nP_MatrixAkt;
+ pType[ nElementAkt ] = T_Matrix;
+
+ pM = new ScMatrix( 0, 0 );
+ pM->IncRef( );
+ ppP_Matrix[ nP_MatrixAkt ] = pM;
+
+ nElementAkt++;
+ nP_MatrixAkt++;
+
+ return ( const TokenId ) nElementAkt;
+}
+
+const TokenId TokenPool::StoreExtName( sal_uInt16 nFileId, const String& rName )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<UINT16>(maExtNames.size());
+ pType[nElementAkt] = T_ExtName;
+
+ maExtNames.push_back(ExtName());
+ ExtName& r = maExtNames.back();
+ r.mnFileId = nFileId;
+ r.maName = rName;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+const TokenId TokenPool::StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<UINT16>(maExtCellRefs.size());
+ pType[nElementAkt] = T_ExtRefC;
+
+ maExtCellRefs.push_back(ExtCellRef());
+ ExtCellRef& r = maExtCellRefs.back();
+ r.mnFileId = nFileId;
+ r.maTabName = rTabName;
+ r.maRef = rRef;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+const TokenId TokenPool::StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<UINT16>(maExtAreaRefs.size());
+ pType[nElementAkt] = T_ExtRefA;
+
+ maExtAreaRefs.push_back(ExtAreaRef());
+ ExtAreaRef& r = maExtAreaRefs.back();
+ r.mnFileId = nFileId;
+ r.maTabName = rTabName;
+ r.maRef = rRef;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+void TokenPool::Reset( void )
+{
+ nP_IdAkt = nP_IdLast = nElementAkt = nP_StrAkt = nP_DblAkt = nP_ErrAkt = nP_RefTrAkt = nP_ExtAkt = nP_NlfAkt = nP_MatrixAkt = 0;
+ maExtNames.clear();
+ maExtCellRefs.clear();
+ maExtAreaRefs.clear();
+}
+
+
+BOOL TokenPool::IsSingleOp( const TokenId& rId, const DefTokenId eId ) const
+{
+ UINT16 nId = (UINT16) rId;
+ if( nId && nId <= nElementAkt )
+ {// existent?
+ nId--;
+ if( T_Id == pType[ nId ] )
+ {// Tokenfolge?
+ if( pSize[ nId ] == 1 )
+ {// GENAU 1 Token
+ UINT16 nSecId = pP_Id[ pElement[ nId ] ];
+ if( nSecId >= nScTokenOff )
+ {// Default-Token?
+ return ( DefTokenId ) ( nSecId - nScTokenOff ) == eId; // Gesuchter?
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+const String* TokenPool::GetExternal( const TokenId& rId ) const
+{
+ const String* p = NULL;
+ UINT16 n = (UINT16) rId;
+ if( n && n <= nElementAkt )
+ {
+ n--;
+ if( (pType[ n ] == T_Ext) && ppP_Ext[ pElement[ n ] ] )
+ p = &ppP_Ext[ pElement[ n ] ]->aText;
+ }
+
+ return p;
+}
+
+
+//UNUSED2008-05 const String* TokenPool::GetString( const TokenId& r ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 const String* p = NULL;
+//UNUSED2008-05 UINT16 n = (UINT16) r;
+//UNUSED2008-05 if( n && n <= nElementAkt )
+//UNUSED2008-05 {
+//UNUSED2008-05 n--;
+//UNUSED2008-05 if( pType[ n ] == T_Str )
+//UNUSED2008-05 p = ppP_Str[ pElement[ n ] ];
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return p;
+//UNUSED2008-05 }
+
+ScMatrix* TokenPool::GetMatrix( unsigned int n ) const
+{
+ if( n < nP_MatrixAkt )
+ return ppP_Matrix[ n ];
+ else
+ printf ("GETMATRIX %d >= %d\n", n, nP_MatrixAkt);
+ return NULL;
+}
+
diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx
new file mode 100644
index 000000000000..b6b136da4b1e
--- /dev/null
+++ b/sc/source/filter/excel/xechart.cxx
@@ -0,0 +1,3303 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xechart.hxx"
+
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
+#include <com/sun/star/chart/ChartAxisPosition.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XDiagramPositioning.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/XColorScheme.hpp>
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/CurveStyle.hpp>
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/LegendExpansion.hpp>
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <com/sun/star/chart2/TickmarkStyle.hpp>
+
+#include <vcl/outdev.hxx>
+#include <filter/msfilter/escherex.hxx>
+
+#include "document.hxx"
+#include "rangelst.hxx"
+#include "rangeutl.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+#include "token.hxx"
+#include "xeescher.hxx"
+#include "xeformula.hxx"
+#include "xehelper.hxx"
+#include "xepage.hxx"
+#include "xestyle.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::i18n::XBreakIterator;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XShapes;
+
+using ::com::sun::star::chart2::IncrementData;
+using ::com::sun::star::chart2::RelativePosition;
+using ::com::sun::star::chart2::ScaleData;
+using ::com::sun::star::chart2::SubIncrement;
+using ::com::sun::star::chart2::XAxis;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::chart2::XChartTypeContainer;
+using ::com::sun::star::chart2::XColorScheme;
+using ::com::sun::star::chart2::XCoordinateSystem;
+using ::com::sun::star::chart2::XCoordinateSystemContainer;
+using ::com::sun::star::chart2::XChartType;
+using ::com::sun::star::chart2::XDataSeries;
+using ::com::sun::star::chart2::XDataSeriesContainer;
+using ::com::sun::star::chart2::XDiagram;
+using ::com::sun::star::chart2::XFormattedString;
+using ::com::sun::star::chart2::XLegend;
+using ::com::sun::star::chart2::XRegressionCurve;
+using ::com::sun::star::chart2::XRegressionCurveContainer;
+using ::com::sun::star::chart2::XScaling;
+using ::com::sun::star::chart2::XTitle;
+using ::com::sun::star::chart2::XTitled;
+
+using ::com::sun::star::chart2::data::XDataSequence;
+using ::com::sun::star::chart2::data::XDataSource;
+using ::com::sun::star::chart2::data::XLabeledDataSequence;
+
+using ::formula::FormulaGrammar;
+using ::formula::FormulaToken;
+
+namespace cssc = ::com::sun::star::chart;
+namespace cssc2 = ::com::sun::star::chart2;
+
+// Helpers ====================================================================
+
+namespace {
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclChRectangle& rRect )
+{
+ return rStrm << rRect.mnX << rRect.mnY << rRect.mnWidth << rRect.mnHeight;
+}
+
+inline void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec )
+{
+ if( xRec.is() )
+ xRec->Save( rStrm );
+}
+
+/** Saves the passed record (group) together with a leading value record. */
+template< typename Type >
+void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec, sal_uInt16 nRecId, Type nValue )
+{
+ if( xRec.is() )
+ {
+ XclExpValueRecord< Type >( nRecId, nValue ).Save( rStrm );
+ xRec->Save( rStrm );
+ }
+}
+
+void lclWriteChFrBlockRecord( XclExpStream& rStrm, const XclChFrBlock& rFrBlock, bool bBegin )
+{
+ sal_uInt16 nRecId = bBegin ? EXC_ID_CHFRBLOCKBEGIN : EXC_ID_CHFRBLOCKEND;
+ rStrm.StartRecord( nRecId, 12 );
+ rStrm << nRecId << EXC_FUTUREREC_EMPTYFLAGS << rFrBlock.mnType << rFrBlock.mnContext << rFrBlock.mnValue1 << rFrBlock.mnValue2;
+ rStrm.EndRecord();
+}
+
+template< typename Type >
+inline bool lclIsAutoAnyOrGetValue( Type& rValue, const Any& rAny )
+{
+ return !rAny.hasValue() || !(rAny >>= rValue);
+}
+
+bool lclIsAutoAnyOrGetScaledValue( double& rfValue, const Any& rAny, bool bLogScale )
+{
+ bool bIsAuto = lclIsAutoAnyOrGetValue( rfValue, rAny );
+ if( !bIsAuto && bLogScale )
+ rfValue = log( rfValue ) / log( 10.0 );
+ return bIsAuto;
+}
+
+} // namespace
+
+// Common =====================================================================
+
+/** Stores global data needed in various classes of the Chart export filter. */
+struct XclExpChRootData : public XclChRootData
+{
+ typedef ::std::vector< XclChFrBlock > XclChFrBlockVector;
+
+ XclExpChChart& mrChartData; /// The chart data object.
+ XclChFrBlockVector maWrittenFrBlocks; /// Stack of future record levels already written out.
+ XclChFrBlockVector maUnwrittenFrBlocks; /// Stack of future record levels not yet written out.
+
+ inline explicit XclExpChRootData( XclExpChChart& rChartData ) : mrChartData( rChartData ) {}
+
+ /** Registers a new future record level. */
+ void RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
+ /** Initializes the current future record level (writes all unwritten CHFRBLOCKBEGIN records). */
+ void InitializeFutureRecBlock( XclExpStream& rStrm );
+ /** Finalizes the current future record level (writes CHFRBLOCKEND record if needed). */
+ void FinalizeFutureRecBlock( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+void XclExpChRootData::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
+{
+ maUnwrittenFrBlocks.push_back( rFrBlock );
+}
+
+void XclExpChRootData::InitializeFutureRecBlock( XclExpStream& rStrm )
+{
+ // first call from a future record writes all missing CHFRBLOCKBEGIN records
+ if( !maUnwrittenFrBlocks.empty() )
+ {
+ // write the leading CHFRINFO record
+ if( maWrittenFrBlocks.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_CHFRINFO, 20 );
+ rStrm << EXC_ID_CHFRINFO << EXC_FUTUREREC_EMPTYFLAGS << EXC_CHFRINFO_EXCELXP2003 << EXC_CHFRINFO_EXCELXP2003 << sal_uInt16( 3 );
+ rStrm << sal_uInt16( 0x0850 ) << sal_uInt16( 0x085A ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x086A ) << sal_uInt16( 0x086B );
+ rStrm.EndRecord();
+ }
+ // write all unwritten CHFRBLOCKBEGIN records
+ for( XclChFrBlockVector::const_iterator aIt = maUnwrittenFrBlocks.begin(), aEnd = maUnwrittenFrBlocks.end(); aIt != aEnd; ++aIt )
+ {
+ DBG_ASSERT( aIt->mnType != EXC_CHFRBLOCK_TYPE_UNKNOWN, "XclExpChRootData::InitializeFutureRecBlock - unknown future record block type" );
+ lclWriteChFrBlockRecord( rStrm, *aIt, true );
+ }
+ // move all record infos to vector of written blocks
+ maWrittenFrBlocks.insert( maWrittenFrBlocks.end(), maUnwrittenFrBlocks.begin(), maUnwrittenFrBlocks.end() );
+ maUnwrittenFrBlocks.clear();
+ }
+}
+
+void XclExpChRootData::FinalizeFutureRecBlock( XclExpStream& rStrm )
+{
+ DBG_ASSERT( !maUnwrittenFrBlocks.empty() || !maWrittenFrBlocks.empty(), "XclExpChRootData::FinalizeFutureRecBlock - no future record level found" );
+ if( !maUnwrittenFrBlocks.empty() )
+ {
+ // no future record has been written, just forget the topmost level
+ maUnwrittenFrBlocks.pop_back();
+ }
+ else if( !maWrittenFrBlocks.empty() )
+ {
+ // write the CHFRBLOCKEND record for the topmost block and delete it
+ lclWriteChFrBlockRecord( rStrm, maWrittenFrBlocks.back(), false );
+ maWrittenFrBlocks.pop_back();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ) :
+ XclExpRoot( rRoot ),
+ mxChData( new XclExpChRootData( rChartData ) )
+{
+}
+
+XclExpChRoot::~XclExpChRoot()
+{
+}
+
+Reference< XChartDocument > XclExpChRoot::GetChartDocument() const
+{
+ return mxChData->mxChartDoc;
+}
+
+XclExpChChart& XclExpChRoot::GetChartData() const
+{
+ return mxChData->mrChartData;
+}
+
+const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
+}
+
+const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( const OUString& rServiceName ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfoFromService( rServiceName );
+}
+
+const XclChFormatInfo& XclExpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
+{
+ return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
+}
+
+void XclExpChRoot::InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const
+{
+ mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
+}
+
+void XclExpChRoot::FinishConversion() const
+{
+ mxChData->FinishConversion();
+}
+
+bool XclExpChRoot::IsSystemColor( const Color& rColor, sal_uInt16 nSysColorIdx ) const
+{
+ XclExpPalette& rPal = GetPalette();
+ return rPal.IsSystemColor( nSysColorIdx ) && (rColor == rPal.GetDefColor( nSysColorIdx ));
+}
+
+void XclExpChRoot::SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const
+{
+ DBG_ASSERT( GetPalette().IsSystemColor( nSysColorIdx ), "XclExpChRoot::SetSystemColor - invalid color index" );
+ rColor = GetPalette().GetDefColor( nSysColorIdx );
+ rnColorId = XclExpPalette::GetColorIdFromIndex( nSysColorIdx );
+}
+
+sal_Int32 XclExpChRoot::CalcChartXFromHmm( sal_Int32 nPosX ) const
+{
+ return ::limit_cast< sal_Int32, double >( (nPosX - mxChData->mnBorderGapX) / mxChData->mfUnitSizeX, 0, EXC_CHART_TOTALUNITS );
+}
+
+sal_Int32 XclExpChRoot::CalcChartYFromHmm( sal_Int32 nPosY ) const
+{
+ return ::limit_cast< sal_Int32, double >( (nPosY - mxChData->mnBorderGapY) / mxChData->mfUnitSizeY, 0, EXC_CHART_TOTALUNITS );
+}
+
+XclChRectangle XclExpChRoot::CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const
+{
+ XclChRectangle aRect;
+ aRect.mnX = CalcChartXFromHmm( rRect.X );
+ aRect.mnY = CalcChartYFromHmm( rRect.Y );
+ aRect.mnWidth = CalcChartXFromHmm( rRect.Width );
+ aRect.mnHeight = CalcChartYFromHmm( rRect.Height );
+ return aRect;
+}
+
+sal_Int32 XclExpChRoot::CalcChartXFromRelative( double fPosX ) const
+{
+ return CalcChartXFromHmm( static_cast< sal_Int32 >( fPosX * mxChData->maChartRect.GetWidth() + 0.5 ) );
+}
+
+sal_Int32 XclExpChRoot::CalcChartYFromRelative( double fPosY ) const
+{
+ return CalcChartYFromHmm( static_cast< sal_Int32 >( fPosY * mxChData->maChartRect.GetHeight() + 0.5 ) );
+}
+
+void XclExpChRoot::ConvertLineFormat( XclChLineFormat& rLineFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().ReadLineProperties(
+ rLineFmt, *mxChData->mxLineDashTable, rPropSet, ePropMode );
+}
+
+bool XclExpChRoot::ConvertAreaFormat( XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
+{
+ return GetChartPropSetHelper().ReadAreaProperties( rAreaFmt, rPropSet, ePropMode );
+}
+
+void XclExpChRoot::ConvertEscherFormat(
+ XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().ReadEscherProperties( rEscherFmt, rPicFmt,
+ *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rPropSet, ePropMode );
+}
+
+sal_uInt16 XclExpChRoot::ConvertFont( const ScfPropertySet& rPropSet, sal_Int16 nScript ) const
+{
+ XclFontData aFontData;
+ GetFontPropSetHelper().ReadFontProperties( aFontData, rPropSet, EXC_FONTPROPSET_CHART, nScript );
+ return GetFontBuffer().Insert( aFontData, EXC_COLOR_CHARTTEXT );
+}
+
+sal_uInt16 XclExpChRoot::ConvertPieRotation( const ScfPropertySet& rPropSet )
+{
+ sal_Int32 nApiRot = 0;
+ rPropSet.GetProperty( nApiRot, EXC_CHPROP_STARTINGANGLE );
+ return static_cast< sal_uInt16 >( (450 - (nApiRot % 360)) % 360 );
+}
+
+void XclExpChRoot::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
+{
+ mxChData->RegisterFutureRecBlock( rFrBlock );
+}
+
+void XclExpChRoot::InitializeFutureRecBlock( XclExpStream& rStrm )
+{
+ mxChData->InitializeFutureRecBlock( rStrm );
+}
+
+void XclExpChRoot::FinalizeFutureRecBlock( XclExpStream& rStrm )
+{
+ mxChData->FinalizeFutureRecBlock( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChGroupBase::XclExpChGroupBase( const XclExpChRoot& rRoot,
+ sal_uInt16 nFrType, sal_uInt16 nRecId, sal_Size nRecSize ) :
+ XclExpRecord( nRecId, nRecSize ),
+ XclExpChRoot( rRoot ),
+ maFrBlock( nFrType )
+{
+}
+
+XclExpChGroupBase::~XclExpChGroupBase()
+{
+}
+
+void XclExpChGroupBase::Save( XclExpStream& rStrm )
+{
+ // header record
+ XclExpRecord::Save( rStrm );
+ // group records
+ if( HasSubRecords() )
+ {
+ // register the future record context corresponding to this record group
+ RegisterFutureRecBlock( maFrBlock );
+ // CHBEGIN record
+ XclExpEmptyRecord( EXC_ID_CHBEGIN ).Save( rStrm );
+ // embedded records
+ WriteSubRecords( rStrm );
+ // finalize the future records, must be done before the closing CHEND
+ FinalizeFutureRecBlock( rStrm );
+ // CHEND record
+ XclExpEmptyRecord( EXC_ID_CHEND ).Save( rStrm );
+ }
+}
+
+bool XclExpChGroupBase::HasSubRecords() const
+{
+ return true;
+}
+
+void XclExpChGroupBase::SetFutureRecordContext( sal_uInt16 nFrContext, sal_uInt16 nFrValue1, sal_uInt16 nFrValue2 )
+{
+ maFrBlock.mnContext = nFrContext;
+ maFrBlock.mnValue1 = nFrValue1;
+ maFrBlock.mnValue2 = nFrValue2;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFutureRecordBase::XclExpChFutureRecordBase( const XclExpChRoot& rRoot,
+ XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize ) :
+ XclExpFutureRecord( eRecType, nRecId, nRecSize ),
+ XclExpChRoot( rRoot )
+{
+}
+
+void XclExpChFutureRecordBase::Save( XclExpStream& rStrm )
+{
+ InitializeFutureRecBlock( rStrm );
+ XclExpFutureRecord::Save( rStrm );
+}
+
+// Frame formatting ===========================================================
+
+XclExpChFramePos::XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ) :
+ XclExpRecord( EXC_ID_CHFRAMEPOS, 20 )
+{
+ maData.mnTLMode = nTLMode;
+ maData.mnBRMode = nBRMode;
+}
+
+void XclExpChFramePos::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnTLMode << maData.mnBRMode << maData.maRect;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChLineFormat::XclExpChLineFormat( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHLINEFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 10 ),
+ mnColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+void XclExpChLineFormat::SetDefault( XclChFrameType eDefFrameType )
+{
+ switch( eDefFrameType )
+ {
+ case EXC_CHFRAMETYPE_AUTO:
+ SetAuto( true );
+ break;
+ case EXC_CHFRAMETYPE_INVISIBLE:
+ SetAuto( false );
+ maData.mnPattern = EXC_CHLINEFORMAT_NONE;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpChLineFormat::SetDefault - unknown frame type" );
+ }
+}
+
+void XclExpChLineFormat::Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ rRoot.ConvertLineFormat( maData, rPropSet, rFmtInfo.mePropMode );
+ if( HasLine() )
+ {
+ // detect system color, set color identifier (TODO: detect automatic series line)
+ if( (eObjType != EXC_CHOBJTYPE_LINEARSERIES) && rRoot.IsSystemColor( maData.maColor, rFmtInfo.mnAutoLineColorIdx ) )
+ {
+ // store color index from automatic format data
+ mnColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoLineColorIdx );
+ // try to set automatic mode
+ bool bAuto = (maData.mnPattern == EXC_CHLINEFORMAT_SOLID) && (maData.mnWeight == rFmtInfo.mnAutoLineWeight);
+ ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO, bAuto );
+ }
+ else
+ {
+ // user defined color - register in palette
+ mnColorId = rRoot.GetPalette().InsertColor( maData.maColor, EXC_COLOR_CHARTLINE );
+ }
+ }
+ else
+ {
+ // no line - set default system color
+ rRoot.SetSystemColor( maData.maColor, mnColorId, EXC_COLOR_CHWINDOWTEXT );
+ }
+}
+
+bool XclExpChLineFormat::IsDefault( XclChFrameType eDefFrameType ) const
+{
+ return
+ ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasLine()) ||
+ ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
+}
+
+void XclExpChLineFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maColor << maData.mnPattern << maData.mnWeight << maData.mnFlags;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ rStrm << rStrm.GetRoot().GetPalette().GetColorIndex( mnColorId );
+}
+
+namespace {
+
+/** Creates a CHLINEFORMAT record from the passed property set. */
+XclExpChLineFormatRef lclCreateLineFormat( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( rRoot ) );
+ xLineFmt->Convert( rRoot, rPropSet, eObjType );
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ if( rFmtInfo.mbDeleteDefFrame && xLineFmt->IsDefault( rFmtInfo.meDefFrameType ) )
+ xLineFmt.reset();
+ return xLineFmt;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpChAreaFormat::XclExpChAreaFormat( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHAREAFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 16 : 12 ),
+ mnPattColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
+ mnBackColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+bool XclExpChAreaFormat::Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ bool bComplexFill = rRoot.ConvertAreaFormat( maData, rPropSet, rFmtInfo.mePropMode );
+ if( HasArea() )
+ {
+ bool bSolid = maData.mnPattern == EXC_PATT_SOLID;
+ // detect system color, set color identifier (TODO: detect automatic series area)
+ if( (eObjType != EXC_CHOBJTYPE_FILLEDSERIES) && rRoot.IsSystemColor( maData.maPattColor, rFmtInfo.mnAutoPattColorIdx ) )
+ {
+ // store color index from automatic format data
+ mnPattColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoPattColorIdx );
+ // set automatic mode
+ ::set_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO, bSolid );
+ }
+ else
+ {
+ // user defined color - register color in palette
+ mnPattColorId = rRoot.GetPalette().InsertColor( maData.maPattColor, EXC_COLOR_CHARTAREA );
+ }
+ // background color (default system color for solid fills)
+ if( bSolid )
+ rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
+ else
+ mnBackColorId = rRoot.GetPalette().InsertColor( maData.maBackColor, EXC_COLOR_CHARTAREA );
+ }
+ else
+ {
+ // no area - set default system colors
+ rRoot.SetSystemColor( maData.maPattColor, mnPattColorId, EXC_COLOR_CHWINDOWBACK );
+ rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
+ }
+ return bComplexFill;
+}
+
+void XclExpChAreaFormat::SetDefault( XclChFrameType eDefFrameType )
+{
+ switch( eDefFrameType )
+ {
+ case EXC_CHFRAMETYPE_AUTO:
+ SetAuto( true );
+ break;
+ case EXC_CHFRAMETYPE_INVISIBLE:
+ SetAuto( false );
+ maData.mnPattern = EXC_PATT_NONE;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpChAreaFormat::SetDefault - unknown frame type" );
+ }
+}
+
+bool XclExpChAreaFormat::IsDefault( XclChFrameType eDefFrameType ) const
+{
+ return
+ ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasArea()) ||
+ ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
+}
+
+void XclExpChAreaFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maPattColor << maData.maBackColor << maData.mnPattern << maData.mnFlags;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
+ rStrm << rPal.GetColorIndex( mnPattColorId ) << rPal.GetColorIndex( mnBackColorId );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChEscherFormat::XclExpChEscherFormat( const XclExpChRoot& rRoot ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_UNKNOWN, EXC_ID_CHESCHERFORMAT ),
+ mnColor1Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
+ mnColor2Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+}
+
+void XclExpChEscherFormat::Convert( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ const XclChFormatInfo& rFmtInfo = GetFormatInfo( eObjType );
+ ConvertEscherFormat( maData, maPicFmt, rPropSet, rFmtInfo.mePropMode );
+ // register colors in palette
+ mnColor1Id = RegisterColor( ESCHER_Prop_fillColor );
+ mnColor2Id = RegisterColor( ESCHER_Prop_fillBackColor );
+}
+
+bool XclExpChEscherFormat::IsValid() const
+{
+ return maData.mxEscherSet.is();
+}
+
+void XclExpChEscherFormat::Save( XclExpStream& rStrm )
+{
+ if( maData.mxEscherSet.is() )
+ {
+ // replace RGB colors with palette indexes in the Escher container
+ const XclExpPalette& rPal = GetPalette();
+ maData.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, 0x08000000 | rPal.GetColorIndex( mnColor1Id ) );
+ maData.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x08000000 | rPal.GetColorIndex( mnColor2Id ) );
+
+ // save the record group
+ XclExpChGroupBase::Save( rStrm );
+ }
+}
+
+bool XclExpChEscherFormat::HasSubRecords() const
+{
+ // no subrecords for gradients
+ return maPicFmt.mnBmpMode != EXC_CHPICFORMAT_NONE;
+}
+
+void XclExpChEscherFormat::WriteSubRecords( XclExpStream& rStrm )
+{
+ rStrm.StartRecord( EXC_ID_CHPICFORMAT, 14 );
+ rStrm << maPicFmt.mnBmpMode << maPicFmt.mnFormat << maPicFmt.mnFlags << maPicFmt.mfScale;
+ rStrm.EndRecord();
+}
+
+sal_uInt32 XclExpChEscherFormat::RegisterColor( sal_uInt16 nPropId )
+{
+ sal_uInt32 nBGRValue;
+ if( maData.mxEscherSet.is() && maData.mxEscherSet->GetOpt( nPropId, nBGRValue ) )
+ {
+ // swap red and blue
+ Color aColor( RGB_COLORDATA(
+ COLORDATA_BLUE( nBGRValue ),
+ COLORDATA_GREEN( nBGRValue ),
+ COLORDATA_RED( nBGRValue ) ) );
+ return GetPalette().InsertColor( aColor, EXC_COLOR_CHARTAREA );
+ }
+ return XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK );
+}
+
+void XclExpChEscherFormat::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT( maData.mxEscherSet.is(), "XclExpChEscherFormat::WriteBody - missing property container" );
+ // write Escher property container via temporary memory stream
+ SvMemoryStream aMemStrm;
+ maData.mxEscherSet->Commit( aMemStrm );
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ rStrm.CopyFromStream( aMemStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFrameBase::XclExpChFrameBase()
+{
+}
+
+XclExpChFrameBase::~XclExpChFrameBase()
+{
+}
+
+void XclExpChFrameBase::ConvertFrameBase( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ // line format
+ mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
+ mxLineFmt->Convert( rRoot, rPropSet, eObjType );
+ // area format (only for frame objects)
+ if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
+ {
+ mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
+ bool bComplexFill = mxAreaFmt->Convert( rRoot, rPropSet, eObjType );
+ if( (rRoot.GetBiff() == EXC_BIFF8) && bComplexFill )
+ {
+ mxEscherFmt.reset( new XclExpChEscherFormat( rRoot ) );
+ mxEscherFmt->Convert( rPropSet, eObjType );
+ if( mxEscherFmt->IsValid() )
+ mxAreaFmt->SetAuto( false );
+ else
+ mxEscherFmt.reset();
+ }
+ }
+}
+
+void XclExpChFrameBase::SetDefaultFrameBase( const XclExpChRoot& rRoot,
+ XclChFrameType eDefFrameType, bool bIsFrame )
+{
+ // line format
+ mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
+ mxLineFmt->SetDefault( eDefFrameType );
+ // area format (only for frame objects)
+ if( bIsFrame )
+ {
+ mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
+ mxAreaFmt->SetDefault( eDefFrameType );
+ mxEscherFmt.reset();
+ }
+}
+
+bool XclExpChFrameBase::IsDefaultFrameBase( XclChFrameType eDefFrameType ) const
+{
+ return
+ (!mxLineFmt || mxLineFmt->IsDefault( eDefFrameType )) &&
+ (!mxAreaFmt || mxAreaFmt->IsDefault( eDefFrameType ));
+}
+
+void XclExpChFrameBase::WriteFrameRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxLineFmt );
+ lclSaveRecord( rStrm, mxAreaFmt );
+ lclSaveRecord( rStrm, mxEscherFmt );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFrame::XclExpChFrame( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_FRAME, EXC_ID_CHFRAME, 4 ),
+ meObjType( eObjType )
+{
+}
+
+void XclExpChFrame::Convert( const ScfPropertySet& rPropSet )
+{
+ ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
+}
+
+bool XclExpChFrame::IsDefault() const
+{
+ return IsDefaultFrameBase( GetFormatInfo( meObjType ).meDefFrameType );
+}
+
+bool XclExpChFrame::IsDeleteable() const
+{
+ return IsDefault() && GetFormatInfo( meObjType ).mbDeleteDefFrame;
+}
+
+void XclExpChFrame::Save( XclExpStream& rStrm )
+{
+ switch( meObjType )
+ {
+ // wall/floor frame without CHFRAME header record
+ case EXC_CHOBJTYPE_WALL3D:
+ case EXC_CHOBJTYPE_FLOOR3D:
+ WriteFrameRecords( rStrm );
+ break;
+ default:
+ XclExpChGroupBase::Save( rStrm );
+ }
+}
+
+void XclExpChFrame::WriteSubRecords( XclExpStream& rStrm )
+{
+ WriteFrameRecords( rStrm );
+}
+
+void XclExpChFrame::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnFormat << maData.mnFlags;
+}
+
+namespace {
+
+/** Creates a CHFRAME record from the passed property set. */
+XclExpChFrameRef lclCreateFrame( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ XclExpChFrameRef xFrame( new XclExpChFrame( rRoot, eObjType ) );
+ xFrame->Convert( rPropSet );
+ if( xFrame->IsDeleteable() )
+ xFrame.reset();
+ return xFrame;
+}
+
+} // namespace
+
+// Source links ===============================================================
+
+namespace {
+
+void lclAddDoubleRefData(
+ ScTokenArray& orArray, const FormulaToken& rToken,
+ SCsTAB nScTab1, SCsCOL nScCol1, SCsROW nScRow1,
+ SCsTAB nScTab2, SCsCOL nScCol2, SCsROW nScRow2 )
+{
+ ScComplexRefData aComplexRef;
+ aComplexRef.InitFlags();
+ aComplexRef.Ref1.SetFlag3D( true );
+ aComplexRef.Ref1.nTab = nScTab1;
+ aComplexRef.Ref1.nCol = nScCol1;
+ aComplexRef.Ref1.nRow = nScRow1;
+ aComplexRef.Ref2.nTab = nScTab2;
+ aComplexRef.Ref2.nCol = nScCol2;
+ aComplexRef.Ref2.nRow = nScRow2;
+
+ if( orArray.GetLen() > 0 )
+ orArray.AddOpCode( ocUnion );
+
+ DBG_ASSERT( (rToken.GetType() == ::formula::svDoubleRef) || (rToken.GetType() == ::formula::svExternalDoubleRef),
+ "lclAddDoubleRefData - double reference token expected");
+ if( rToken.GetType() == ::formula::svExternalDoubleRef )
+ orArray.AddExternalDoubleReference( rToken.GetIndex(), rToken.GetString(), aComplexRef );
+ else
+ orArray.AddDoubleReference( aComplexRef );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpChSourceLink::XclExpChSourceLink( const XclExpChRoot& rRoot, sal_uInt8 nDestType ) :
+ XclExpRecord( EXC_ID_CHSOURCELINK ),
+ XclExpChRoot( rRoot )
+{
+ maData.mnDestType = nDestType;
+ maData.mnLinkType = EXC_CHSRCLINK_DIRECTLY;
+}
+
+sal_uInt16 XclExpChSourceLink::ConvertDataSequence( Reference< XDataSequence > xDataSeq, bool bSplitToColumns, sal_uInt16 nDefCount )
+{
+ mxLinkFmla.reset();
+ maData.mnLinkType = EXC_CHSRCLINK_DEFAULT;
+
+ if( !xDataSeq.is() )
+ return nDefCount;
+
+ // Compile the range representation string into token array. Note that the
+ // source range text depends on the current grammar.
+ OUString aRangeRepr = xDataSeq->getSourceRangeRepresentation();
+ ScCompiler aComp( GetDocPtr(), ScAddress() );
+ aComp.SetGrammar( GetDocPtr()->GetGrammar() );
+ ScTokenArray* pArray = aComp.CompileString( aRangeRepr );
+ if( !pArray )
+ return nDefCount;
+
+ ScTokenArray aArray;
+ sal_uInt32 nValueCount = 0;
+ pArray->Reset();
+ for( const FormulaToken* pToken = pArray->First(); pToken; pToken = pArray->Next() )
+ {
+ switch( pToken->GetType() )
+ {
+ case ::formula::svSingleRef:
+ case ::formula::svExternalSingleRef:
+ // for a single ref token, just add it to the new token array as is
+ if( aArray.GetLen() > 0 )
+ aArray.AddOpCode( ocUnion );
+ aArray.AddToken( *pToken );
+ ++nValueCount;
+ break;
+
+ case ::formula::svDoubleRef:
+ case ::formula::svExternalDoubleRef:
+ {
+ // split 3-dimensional ranges into single sheets
+ const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
+ const ScSingleRefData& rRef1 = rComplexRef.Ref1;
+ const ScSingleRefData& rRef2 = rComplexRef.Ref2;
+ for( SCsTAB nScTab = rRef1.nTab; nScTab <= rRef2.nTab; ++nScTab )
+ {
+ // split 2-dimensional ranges into single columns
+ if( bSplitToColumns && (rRef1.nCol < rRef2.nCol) && (rRef1.nRow < rRef2.nRow) )
+ for( SCsCOL nScCol = rRef1.nCol; nScCol <= rRef2.nCol; ++nScCol )
+ lclAddDoubleRefData( aArray, *pToken, nScTab, nScCol, rRef1.nRow, nScTab, nScCol, rRef2.nRow );
+ else
+ lclAddDoubleRefData( aArray, *pToken, nScTab, rRef1.nCol, rRef1.nRow, nScTab, rRef2.nCol, rRef2.nRow );
+ }
+ sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
+ sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
+ sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
+ nValueCount += nCols * nRows * nTabs;
+ }
+ break;
+
+ default:;
+ }
+ }
+
+ const ScAddress aBaseCell;
+ mxLinkFmla = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aArray, &aBaseCell );
+ maData.mnLinkType = EXC_CHSRCLINK_WORKSHEET;
+ return ulimit_cast< sal_uInt16 >( nValueCount, EXC_CHDATAFORMAT_MAXPOINTCOUNT );
+}
+
+sal_uInt16 XclExpChSourceLink::ConvertStringSequence( const Sequence< Reference< XFormattedString > >& rStringSeq )
+{
+ mxString.reset();
+ sal_uInt16 nFontIdx = EXC_FONT_APP;
+ if( rStringSeq.hasElements() )
+ {
+ mxString = XclExpStringHelper::CreateString( GetRoot(), String::EmptyString(), EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
+ Reference< XBreakIterator > xBreakIt = GetDoc().GetBreakIterator();
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+ // convert all formatted string entries from the sequence
+ const Reference< XFormattedString >* pBeg = rStringSeq.getConstArray();
+ const Reference< XFormattedString >* pEnd = pBeg + rStringSeq.getLength();
+ for( const Reference< XFormattedString >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ if( pIt->is() )
+ {
+ sal_uInt16 nWstrnFontIdx = EXC_FONT_NOTFOUND;
+ sal_uInt16 nAsianFontIdx = EXC_FONT_NOTFOUND;
+ sal_uInt16 nCmplxFontIdx = EXC_FONT_NOTFOUND;
+ OUString aText = (*pIt)->getString();
+ ScfPropertySet aStrProp( *pIt );
+
+ // #i63255# get script type for leading weak characters
+ sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( GetRoot(), aText );
+
+ // process all script portions
+ sal_Int32 nPortionPos = 0;
+ sal_Int32 nTextLen = aText.getLength();
+ while( nPortionPos < nTextLen )
+ {
+ // get script type and end position of next script portion
+ sal_Int16 nScript = xBreakIt->getScriptType( aText, nPortionPos );
+ sal_Int32 nPortionEnd = xBreakIt->endOfScript( aText, nPortionPos, nScript );
+
+ // reuse previous script for following weak portions
+ if( nScript == ApiScriptType::WEAK )
+ nScript = nLastScript;
+
+ // Excel start position of this portion
+ sal_uInt16 nXclPortionStart = mxString->Len();
+ // add portion text to Excel string
+ XclExpStringHelper::AppendString( *mxString, GetRoot(), aText.copy( nPortionPos, nPortionEnd - nPortionPos ) );
+ if( nXclPortionStart < mxString->Len() )
+ {
+ // find font index variable dependent on script type
+ sal_uInt16& rnFontIdx = (nScript == ApiScriptType::COMPLEX) ? nCmplxFontIdx :
+ ((nScript == ApiScriptType::ASIAN) ? nAsianFontIdx : nWstrnFontIdx);
+
+ // insert font into buffer (if not yet done)
+ if( rnFontIdx == EXC_FONT_NOTFOUND )
+ rnFontIdx = ConvertFont( aStrProp, nScript );
+
+ // insert font index into format run vector
+ mxString->AppendFormat( nXclPortionStart, rnFontIdx );
+ }
+
+ // go to next script portion
+ nLastScript = nScript;
+ nPortionPos = nPortionEnd;
+ }
+ }
+ }
+ if( !mxString->IsEmpty() )
+ {
+ // get leading font index
+ const XclFormatRunVec& rFormats = mxString->GetFormats();
+ DBG_ASSERT( !rFormats.empty() && (rFormats.front().mnChar == 0),
+ "XclExpChSourceLink::ConvertStringSequenc - missing leading format" );
+ // remove leading format run, if entire string is equally formatted
+ if( rFormats.size() == 1 )
+ nFontIdx = mxString->RemoveLeadingFont();
+ else if( !rFormats.empty() )
+ nFontIdx = rFormats.front().mnFontIdx;
+ // add trailing format run, if string is rich-formatted
+ if( mxString->IsRich() )
+ mxString->AppendTrailingFormat( EXC_FONT_APP );
+ }
+ }
+ return nFontIdx;
+}
+
+void XclExpChSourceLink::ConvertNumFmt( const ScfPropertySet& rPropSet, bool bPercent )
+{
+ sal_Int32 nApiNumFmt = 0;
+ if( bPercent ? rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_PERCENTAGENUMFMT ) : rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
+ {
+ ::set_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
+ maData.mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
+ }
+}
+
+void XclExpChSourceLink::Save( XclExpStream& rStrm )
+{
+ // CHFORMATRUNS record
+ if( mxString.is() && mxString->IsRich() )
+ {
+ sal_Size nRecSize = (1 + mxString->GetFormatsCount()) * ((GetBiff() == EXC_BIFF8) ? 2 : 1);
+ rStrm.StartRecord( EXC_ID_CHFORMATRUNS, nRecSize );
+ mxString->WriteFormats( rStrm, true );
+ rStrm.EndRecord();
+ }
+ // CHSOURCELINK record
+ XclExpRecord::Save( rStrm );
+ // CHSTRING record
+ if( mxString.is() && !mxString->IsEmpty() )
+ {
+ rStrm.StartRecord( EXC_ID_CHSTRING, 2 + mxString->GetSize() );
+ rStrm << sal_uInt16( 0 ) << *mxString;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpChSourceLink::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnDestType
+ << maData.mnLinkType
+ << maData.mnFlags
+ << maData.mnNumFmtIdx
+ << mxLinkFmla;
+}
+
+// Text =======================================================================
+
+XclExpChFont::XclExpChFont( sal_uInt16 nFontIdx ) :
+ XclExpUInt16Record( EXC_ID_CHFONT, nFontIdx )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChObjectLink::XclExpChObjectLink( sal_uInt16 nLinkTarget, const XclChDataPointPos& rPointPos ) :
+ XclExpRecord( EXC_ID_CHOBJECTLINK, 6 )
+{
+ maData.mnTarget = nLinkTarget;
+ maData.maPointPos = rPointPos;
+}
+
+void XclExpChObjectLink::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnTarget << maData.maPointPos.mnSeriesIdx << maData.maPointPos.mnPointIdx;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFrLabelProps::XclExpChFrLabelProps( const XclExpChRoot& rRoot ) :
+ XclExpChFutureRecordBase( rRoot, EXC_FUTUREREC_UNUSEDREF, EXC_ID_CHFRLABELPROPS, 4 )
+{
+}
+
+void XclExpChFrLabelProps::Convert( const ScfPropertySet& rPropSet, bool bShowSeries,
+ bool bShowCateg, bool bShowValue, bool bShowPercent, bool bShowBubble )
+{
+ // label value flags
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWSERIES, bShowSeries );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWCATEG, bShowCateg );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWVALUE, bShowValue );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWPERCENT, bShowPercent );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWBUBBLE, bShowBubble );
+
+ // label value separator
+ rPropSet.GetStringProperty( maData.maSeparator, EXC_CHPROP_LABELSEPARATOR );
+ if( maData.maSeparator.Len() == 0 )
+ maData.maSeparator = String( sal_Unicode( ' ' ) );
+}
+
+void XclExpChFrLabelProps::WriteBody( XclExpStream& rStrm )
+{
+ XclExpString aXclSep( maData.maSeparator, EXC_STR_FORCEUNICODE | EXC_STR_SMARTFLAGS );
+ rStrm << maData.mnFlags << aXclSep;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFontBase::~XclExpChFontBase()
+{
+}
+
+void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, sal_uInt16 nFontIdx )
+{
+ if( const XclExpFont* pFont = rRoot.GetFontBuffer().GetFont( nFontIdx ) )
+ {
+ XclExpChFontRef xFont( new XclExpChFont( nFontIdx ) );
+ SetFont( xFont, pFont->GetFontData().maColor, pFont->GetFontColorId() );
+ }
+}
+
+void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet )
+{
+ ConvertFontBase( rRoot, rRoot.ConvertFont( rPropSet, rRoot.GetDefApiScript() ) );
+}
+
+void XclExpChFontBase::ConvertRotationBase(
+ const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet, bool bSupportsStacked )
+{
+ sal_uInt16 nRotation = rRoot.GetChartPropSetHelper().ReadRotationProperties( rPropSet, bSupportsStacked );
+ SetRotation( nRotation );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChText::XclExpChText( const XclExpChRoot& rRoot ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TEXT, EXC_ID_CHTEXT, (rRoot.GetBiff() == EXC_BIFF8) ? 32 : 26 ),
+ mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+void XclExpChText::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
+{
+ mxFont = xFont;
+ maData.maTextColor = rColor;
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, rColor == COL_AUTO );
+ mnTextColorId = nColorId;
+}
+
+void XclExpChText::SetRotation( sal_uInt16 nRotation )
+{
+ maData.mnRotation = nRotation;
+ ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 8, 3 );
+}
+
+void XclExpChText::ConvertTitle( Reference< XTitle > xTitle, sal_uInt16 nTarget )
+{
+ switch( nTarget )
+ {
+ case EXC_CHOBJLINK_TITLE: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_TITLE ); break;
+ case EXC_CHOBJLINK_YAXIS: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 1 ); break;
+ case EXC_CHOBJLINK_XAXIS: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 0 ); break;
+ case EXC_CHOBJLINK_ZAXIS: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 2 ); break;
+ }
+
+ mxSrcLink.reset();
+ mxObjLink.reset( new XclExpChObjectLink( nTarget, XclChDataPointPos( 0, 0 ) ) );
+
+ if( xTitle.is() )
+ {
+ // title frame formatting
+ ScfPropertySet aTitleProp( xTitle );
+ mxFrame = lclCreateFrame( GetChRoot(), aTitleProp, EXC_CHOBJTYPE_TEXT );
+
+ // string sequence
+ mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ sal_uInt16 nFontIdx = mxSrcLink->ConvertStringSequence( xTitle->getText() );
+ ConvertFontBase( GetChRoot(), nFontIdx );
+
+ // rotation
+ ConvertRotationBase( GetChRoot(), aTitleProp, true );
+
+ // manual text position - only for main title
+ mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
+ if( nTarget == EXC_CHOBJLINK_TITLE )
+ {
+ Any aRelPos;
+ if( aTitleProp.GetAnyProperty( aRelPos, EXC_CHPROP_RELATIVEPOSITION ) && aRelPos.has< RelativePosition >() ) try
+ {
+ // calculate absolute position for CHTEXT record
+ Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
+ Reference< XShape > xTitleShape( xChart1Doc->getTitle(), UNO_SET_THROW );
+ ::com::sun::star::awt::Point aPos = xTitleShape->getPosition();
+ ::com::sun::star::awt::Size aSize = xTitleShape->getSize();
+ ::com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, aSize.Width, aSize.Height );
+ maData.maRect = CalcChartRectFromHmm( aRect );
+ ::insert_value( maData.mnFlags2, EXC_CHTEXT_POS_MOVED, 0, 4 );
+ // manual title position implies manual plot area
+ GetChartData().SetManualPlotArea();
+ // calculate the default title position in chart units
+ sal_Int32 nDefPosX = ::std::max< sal_Int32 >( (EXC_CHART_TOTALUNITS - maData.maRect.mnWidth) / 2, 0 );
+ sal_Int32 nDefPosY = 85;
+ // set the position relative to the standard position
+ XclChRectangle& rFrameRect = mxFramePos->GetFramePosData().maRect;
+ rFrameRect.mnX = maData.maRect.mnX - nDefPosX;
+ rFrameRect.mnY = maData.maRect.mnY - nDefPosY;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ else
+ {
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED );
+ }
+}
+
+void XclExpChText::ConvertLegend( const ScfPropertySet& rPropSet )
+{
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOGEN );
+ ConvertFontBase( GetChRoot(), rPropSet );
+}
+
+bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet,
+ const XclChTypeInfo& rTypeInfo, const XclChDataPointPos& rPointPos )
+{
+ SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_DATALABEL, rPointPos.mnPointIdx, rPointPos.mnSeriesIdx );
+
+ cssc2::DataPointLabel aPointLabel;
+ if( !rPropSet.GetProperty( aPointLabel, EXC_CHPROP_LABEL ) )
+ return false;
+
+ // percentage only allowed in pie and donut charts
+ bool bIsPie = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE;
+ // bubble sizes only allowed in bubble charts
+ bool bIsBubble = rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES;
+ DBG_ASSERT( (GetBiff() == EXC_BIFF8) || !bIsBubble, "XclExpChText::ConvertDataLabel - bubble charts only in BIFF8" );
+
+ // raw show flags
+ bool bShowValue = !bIsBubble && aPointLabel.ShowNumber; // Chart2 uses 'ShowNumber' for bubble size
+ bool bShowPercent = bIsPie && aPointLabel.ShowNumberInPercent; // percentage only in pie/donut charts
+ bool bShowCateg = aPointLabel.ShowCategoryName;
+ bool bShowBubble = bIsBubble && aPointLabel.ShowNumber; // Chart2 uses 'ShowNumber' for bubble size
+ bool bShowAny = bShowValue || bShowPercent || bShowCateg || bShowBubble;
+
+ // create the CHFRLABELPROPS record for extended settings in BIFF8
+ if( bShowAny && (GetBiff() == EXC_BIFF8) )
+ {
+ mxLabelProps.reset( new XclExpChFrLabelProps( GetChRoot() ) );
+ mxLabelProps->Convert( rPropSet, false, bShowCateg, bShowValue, bShowPercent, bShowBubble );
+ }
+
+ // restrict to combinations allowed in CHTEXT
+ if( bShowPercent ) bShowValue = false; // percent wins over value
+ if( bShowValue ) bShowCateg = false; // value wins over category
+ if( bShowValue || bShowCateg ) bShowBubble = false; // value or category wins over bubble size
+
+ // set all flags
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bShowValue );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bShowPercent );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bShowCateg );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bShowPercent && bShowCateg );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWBUBBLE, bShowBubble );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL, bShowAny && aPointLabel.ShowLegendSymbol );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bShowAny );
+
+ if( bShowAny )
+ {
+ // font settings
+ ConvertFontBase( GetChRoot(), rPropSet );
+ ConvertRotationBase( GetChRoot(), rPropSet, false );
+ // label placement
+ sal_Int32 nPlacement = 0;
+ sal_uInt16 nLabelPos = EXC_CHTEXT_POS_AUTO;
+ if( rPropSet.GetProperty( nPlacement, EXC_CHPROP_LABELPLACEMENT ) )
+ {
+ using namespace ::com::sun::star::chart::DataLabelPlacement;
+ if( nPlacement == rTypeInfo.mnDefaultLabelPos )
+ {
+ nLabelPos = EXC_CHTEXT_POS_DEFAULT;
+ }
+ else switch( nPlacement )
+ {
+ case AVOID_OVERLAP: nLabelPos = EXC_CHTEXT_POS_AUTO; break;
+ case CENTER: nLabelPos = EXC_CHTEXT_POS_CENTER; break;
+ case TOP: nLabelPos = EXC_CHTEXT_POS_ABOVE; break;
+ case TOP_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
+ case LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
+ case BOTTOM_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
+ case BOTTOM: nLabelPos = EXC_CHTEXT_POS_BELOW; break;
+ case BOTTOM_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
+ case RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
+ case TOP_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
+ case INSIDE: nLabelPos = EXC_CHTEXT_POS_INSIDE; break;
+ case OUTSIDE: nLabelPos = EXC_CHTEXT_POS_OUTSIDE; break;
+ case NEAR_ORIGIN: nLabelPos = EXC_CHTEXT_POS_AXIS; break;
+ default: DBG_ERRORFILE( "XclExpChText::ConvertDataLabel - unknown label placement type" );
+ }
+ }
+ ::insert_value( maData.mnFlags2, nLabelPos, 0, 4 );
+ // source link (contains number format)
+ mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ if( bShowValue || bShowPercent )
+ // percentage format wins over value format
+ mxSrcLink->ConvertNumFmt( rPropSet, bShowPercent );
+ // object link
+ mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
+ }
+
+ /* Return true to indicate valid label settings:
+ - for existing labels at entire series
+ - for any settings at single data point (to be able to delete a point label) */
+ return bShowAny || (rPointPos.mnPointIdx != EXC_CHDATAFORMAT_ALLPOINTS);
+}
+
+void XclExpChText::ConvertTrendLineEquation( const ScfPropertySet& rPropSet, const XclChDataPointPos& rPointPos )
+{
+ // required flags
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
+ if( GetBiff() == EXC_BIFF8 )
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ); // must set this to make equation visible in Excel
+ // frame formatting
+ mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_TEXT );
+ // font settings
+ maData.mnHAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
+ maData.mnVAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
+ ConvertFontBase( GetChRoot(), rPropSet );
+ // source link (contains number format)
+ mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ mxSrcLink->ConvertNumFmt( rPropSet, false );
+ // object link
+ mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
+}
+
+sal_uInt16 XclExpChText::GetAttLabelFlags() const
+{
+ sal_uInt16 nFlags = 0;
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWVALUE, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE ) );
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWPERCENT, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT ) );
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEGPERC, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC ) );
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEG, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ) );
+ return nFlags;
+}
+
+void XclExpChText::WriteSubRecords( XclExpStream& rStrm )
+{
+ // CHFRAMEPOS record
+ lclSaveRecord( rStrm, mxFramePos );
+ // CHFONT record
+ lclSaveRecord( rStrm, mxFont );
+ // CHSOURCELINK group
+ lclSaveRecord( rStrm, mxSrcLink );
+ // CHFRAME group
+ lclSaveRecord( rStrm, mxFrame );
+ // CHOBJECTLINK record
+ lclSaveRecord( rStrm, mxObjLink );
+ // CHFRLABELPROPS record
+ lclSaveRecord( rStrm, mxLabelProps );
+}
+
+void XclExpChText::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnHAlign
+ << maData.mnVAlign
+ << maData.mnBackMode
+ << maData.maTextColor
+ << maData.maRect
+ << maData.mnFlags;
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ rStrm << GetPalette().GetColorIndex( mnTextColorId )
+ << maData.mnFlags2
+ << maData.mnRotation;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Creates and returns an Excel text object from the passed title. */
+XclExpChTextRef lclCreateTitle( const XclExpChRoot& rRoot, Reference< XTitled > xTitled, sal_uInt16 nTarget )
+{
+ Reference< XTitle > xTitle;
+ if( xTitled.is() )
+ xTitle = xTitled->getTitleObject();
+
+ XclExpChTextRef xText( new XclExpChText( rRoot ) );
+ xText->ConvertTitle( xTitle, nTarget );
+ /* Do not delete the CHTEXT group for the main title. A missing CHTEXT
+ will be interpreted as auto-generated title showing the series title in
+ charts that contain exactly one data series. */
+ if( (nTarget != EXC_CHOBJLINK_TITLE) && !xText->HasString() )
+ xText.reset();
+
+ return xText;
+}
+
+}
+
+// Data series ================================================================
+
+XclExpChMarkerFormat::XclExpChMarkerFormat( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHMARKERFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 20 : 12 ),
+ mnLineColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) ),
+ mnFillColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
+{
+}
+
+void XclExpChMarkerFormat::Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
+{
+ rRoot.GetChartPropSetHelper().ReadMarkerProperties( maData, rPropSet, nFormatIdx );
+ /* Set marker line/fill color to series line color.
+ TODO: remove this if OOChart supports own colors in markers. */
+ Color aLineColor;
+ if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
+ maData.maLineColor = maData.maFillColor = aLineColor;
+ // register colors in palette
+ RegisterColors( rRoot );
+}
+
+void XclExpChMarkerFormat::ConvertStockSymbol( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, bool bCloseSymbol )
+{
+ // clear the automatic flag
+ ::set_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
+ // symbol type and color
+ if( bCloseSymbol )
+ {
+ // set symbol type for the 'close' data series
+ maData.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ;
+ maData.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE;
+ // set symbol line/fill color to series line color
+ Color aLineColor;
+ if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
+ {
+ maData.maLineColor = maData.maFillColor = aLineColor;
+ RegisterColors( rRoot );
+ }
+ }
+ else
+ {
+ // set invisible symbol
+ maData.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
+ }
+}
+
+void XclExpChMarkerFormat::RegisterColors( const XclExpChRoot& rRoot )
+{
+ if( HasMarker() )
+ {
+ if( HasLineColor() )
+ mnLineColorId = rRoot.GetPalette().InsertColor( maData.maLineColor, EXC_COLOR_CHARTLINE );
+ if( HasFillColor() )
+ mnFillColorId = rRoot.GetPalette().InsertColor( maData.maFillColor, EXC_COLOR_CHARTAREA );
+ }
+}
+
+void XclExpChMarkerFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maLineColor << maData.maFillColor << maData.mnMarkerType << maData.mnFlags;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
+ rStrm << rPal.GetColorIndex( mnLineColorId ) << rPal.GetColorIndex( mnFillColorId ) << maData.mnMarkerSize;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChPieFormat::XclExpChPieFormat() :
+ XclExpUInt16Record( EXC_ID_CHPIEFORMAT, 0 )
+{
+}
+
+void XclExpChPieFormat::Convert( const ScfPropertySet& rPropSet )
+{
+ double fApiDist(0.0);
+ if( rPropSet.GetProperty( fApiDist, EXC_CHPROP_OFFSET ) )
+ SetValue( limit_cast< sal_uInt16 >( fApiDist * 100.0, 0, 100 ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCh3dDataFormat::XclExpCh3dDataFormat() :
+ XclExpRecord( EXC_ID_CH3DDATAFORMAT, 2 )
+{
+}
+
+void XclExpCh3dDataFormat::Convert( const ScfPropertySet& rPropSet )
+{
+ sal_Int32 nApiType(0);
+ if( rPropSet.GetProperty( nApiType, EXC_CHPROP_GEOMETRY3D ) )
+ {
+ using namespace ::com::sun::star::chart2::DataPointGeometry3D;
+ switch( nApiType )
+ {
+ case CUBOID:
+ maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
+ maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
+ break;
+ case PYRAMID:
+ maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
+ maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
+ break;
+ case CYLINDER:
+ maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
+ maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
+ break;
+ case CONE:
+ maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
+ maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpCh3dDataFormat::Convert - unknown 3D bar format" );
+ }
+ }
+}
+
+void XclExpCh3dDataFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnBase << maData.mnTop;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChAttachedLabel::XclExpChAttachedLabel( sal_uInt16 nFlags ) :
+ XclExpUInt16Record( EXC_ID_CHATTACHEDLABEL, nFlags )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChDataFormat::XclExpChDataFormat( const XclExpChRoot& rRoot,
+ const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DATAFORMAT, EXC_ID_CHDATAFORMAT, 8 )
+{
+ maData.maPointPos = rPointPos;
+ maData.mnFormatIdx = nFormatIdx;
+}
+
+void XclExpChDataFormat::ConvertDataSeries( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo )
+{
+ // line and area formatting
+ ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType() );
+
+ // data point symbols
+ bool bIsFrame = rTypeInfo.IsSeriesFrameFormat();
+ if( !bIsFrame )
+ {
+ mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
+ mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx );
+ }
+
+ // pie segments
+ if( rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE )
+ {
+ mxPieFmt.reset( new XclExpChPieFormat );
+ mxPieFmt->Convert( rPropSet );
+ }
+
+ // 3D bars (only allowed for entire series in BIFF8)
+ if( IsSeriesFormat() && (GetBiff() == EXC_BIFF8) && rTypeInfo.mb3dChart && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) )
+ {
+ mx3dDataFmt.reset( new XclExpCh3dDataFormat );
+ mx3dDataFmt->Convert( rPropSet );
+ }
+
+ // spline
+ if( IsSeriesFormat() && rTypeInfo.mbSpline && !bIsFrame )
+ mxSeriesFmt.reset( new XclExpUInt16Record( EXC_ID_CHSERIESFORMAT, EXC_CHSERIESFORMAT_SMOOTHED ) );
+
+ // data point labels
+ XclExpChTextRef xLabel( new XclExpChText( GetChRoot() ) );
+ if( xLabel->ConvertDataLabel( rPropSet, rTypeInfo, maData.maPointPos ) )
+ {
+ // CHTEXT groups for data labels are stored in global CHCHART group
+ GetChartData().SetDataLabel( xLabel );
+ mxAttLabel.reset( new XclExpChAttachedLabel( xLabel->GetAttLabelFlags() ) );
+ }
+}
+
+void XclExpChDataFormat::ConvertStockSeries( const ScfPropertySet& rPropSet, bool bCloseSymbol )
+{
+ // set line format to invisible
+ SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, false );
+ // set symbols to invisible or to 'close' series symbol
+ mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
+ mxMarkerFmt->ConvertStockSymbol( GetChRoot(), rPropSet, bCloseSymbol );
+}
+
+void XclExpChDataFormat::ConvertLine( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ ConvertFrameBase( GetChRoot(), rPropSet, eObjType );
+}
+
+void XclExpChDataFormat::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mx3dDataFmt );
+ WriteFrameRecords( rStrm );
+ lclSaveRecord( rStrm, mxPieFmt );
+ lclSaveRecord( rStrm, mxMarkerFmt );
+ lclSaveRecord( rStrm, mxSeriesFmt );
+ lclSaveRecord( rStrm, mxAttLabel );
+}
+
+void XclExpChDataFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maPointPos.mnPointIdx
+ << maData.maPointPos.mnSeriesIdx
+ << maData.mnFormatIdx
+ << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChSerTrendLine::XclExpChSerTrendLine( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHSERTRENDLINE, 28 ),
+ XclExpChRoot( rRoot )
+{
+}
+
+bool XclExpChSerTrendLine::Convert( Reference< XRegressionCurve > xRegCurve, sal_uInt16 nSeriesIdx )
+{
+ if( !xRegCurve.is() )
+ return false;
+
+ // trend line type
+ ScfPropertySet aCurveProp( xRegCurve );
+ OUString aService = aCurveProp.GetServiceName();
+ if( aService == SERVICE_CHART2_LINEARREGCURVE )
+ {
+ maData.mnLineType = EXC_CHSERTREND_POLYNOMIAL;
+ maData.mnOrder = 1;
+ }
+ else if( aService == SERVICE_CHART2_EXPREGCURVE )
+ maData.mnLineType = EXC_CHSERTREND_EXPONENTIAL;
+ else if( aService == SERVICE_CHART2_LOGREGCURVE )
+ maData.mnLineType = EXC_CHSERTREND_LOGARITHMIC;
+ else if( aService == SERVICE_CHART2_POTREGCURVE )
+ maData.mnLineType = EXC_CHSERTREND_POWER;
+ else
+ return false;
+
+ // line formatting
+ XclChDataPointPos aPointPos( nSeriesIdx );
+ mxDataFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, 0 ) );
+ mxDataFmt->ConvertLine( aCurveProp, EXC_CHOBJTYPE_TRENDLINE );
+
+ // #i83100# show equation and correlation coefficient
+ ScfPropertySet aEquationProp( xRegCurve->getEquationProperties() );
+ maData.mnShowEquation = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWEQUATION ) ? 1 : 0;
+ maData.mnShowRSquared = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWCORRELATION ) ? 1 : 0;
+
+ // #i83100# formatting of the equation text box
+ if( (maData.mnShowEquation != 0) || (maData.mnShowRSquared != 0) )
+ {
+ mxLabel.reset( new XclExpChText( GetChRoot() ) );
+ mxLabel->ConvertTrendLineEquation( aEquationProp, aPointPos );
+ }
+
+ // missing features
+ // #i20819# polynomial trend lines
+ // #i66819# moving average trend lines
+ // #i5085# manual trend line size
+ // #i34093# manual crossing point
+ return true;
+}
+
+void XclExpChSerTrendLine::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnLineType
+ << maData.mnOrder
+ << maData.mfIntercept
+ << maData.mnShowEquation
+ << maData.mnShowRSquared
+ << maData.mfForecastFor
+ << maData.mfForecastBack;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChSerErrorBar::XclExpChSerErrorBar( const XclExpChRoot& rRoot, sal_uInt8 nBarType ) :
+ XclExpRecord( EXC_ID_CHSERERRORBAR, 14 ),
+ XclExpChRoot( rRoot )
+{
+ maData.mnBarType = nBarType;
+}
+
+bool XclExpChSerErrorBar::Convert( XclExpChSourceLink& rValueLink, sal_uInt16& rnValueCount, const ScfPropertySet& rPropSet )
+{
+ sal_Int32 nBarStyle = 0;
+ bool bOk = rPropSet.GetProperty( nBarStyle, EXC_CHPROP_ERRORBARSTYLE );
+ if( bOk )
+ {
+ switch( nBarStyle )
+ {
+ case cssc::ErrorBarStyle::ABSOLUTE:
+ maData.mnSourceType = EXC_CHSERERR_FIXED;
+ rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
+ break;
+ case cssc::ErrorBarStyle::RELATIVE:
+ maData.mnSourceType = EXC_CHSERERR_PERCENT;
+ rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
+ break;
+ case cssc::ErrorBarStyle::STANDARD_DEVIATION:
+ maData.mnSourceType = EXC_CHSERERR_STDDEV;
+ rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_WEIGHT );
+ break;
+ case cssc::ErrorBarStyle::STANDARD_ERROR:
+ maData.mnSourceType = EXC_CHSERERR_STDERR;
+ break;
+ case cssc::ErrorBarStyle::FROM_DATA:
+ {
+ bOk = false;
+ maData.mnSourceType = EXC_CHSERERR_CUSTOM;
+ Reference< XDataSource > xDataSource( rPropSet.GetApiPropertySet(), UNO_QUERY );
+ if( xDataSource.is() )
+ {
+ // find first sequence with current role
+ OUString aRole = XclChartHelper::GetErrorBarValuesRole( maData.mnBarType );
+ Reference< XDataSequence > xValueSeq;
+
+ Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
+ const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
+ const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
+ for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xValueSeq.is() && (pIt != pEnd); ++pIt )
+ {
+ Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
+ ScfPropertySet aValueProp( xTmpValueSeq );
+ OUString aCurrRole;
+ if( aValueProp.GetProperty( aCurrRole, EXC_CHPROP_ROLE ) && (aCurrRole == aRole) )
+ xValueSeq = xTmpValueSeq;
+ }
+ if( xValueSeq.is() )
+ {
+ // #i86465# pass value count back to series
+ rnValueCount = maData.mnValueCount = rValueLink.ConvertDataSequence( xValueSeq, true );
+ bOk = maData.mnValueCount > 0;
+ }
+ }
+ }
+ break;
+ default:
+ bOk = false;
+ }
+ }
+ return bOk;
+}
+
+void XclExpChSerErrorBar::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnBarType
+ << maData.mnSourceType
+ << maData.mnLineEnd
+ << sal_uInt8( 1 ) // must be 1 to make line visible
+ << maData.mfValue
+ << maData.mnValueCount;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Returns the property set of the specified data point. */
+ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_Int32 nPointIdx )
+{
+ ScfPropertySet aPropSet;
+ try
+ {
+ aPropSet.Set( xDataSeries->getDataPointByIndex( nPointIdx ) );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "lclGetPointPropSet - no data point property set" );
+ }
+ return aPropSet;
+}
+
+} // namespace
+
+XclExpChSeries::XclExpChSeries( const XclExpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_SERIES, EXC_ID_CHSERIES, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 8 ),
+ mnGroupIdx( EXC_CHSERGROUP_NONE ),
+ mnSeriesIdx( nSeriesIdx ),
+ mnParentIdx( EXC_CHSERIES_INVALID )
+{
+ // CHSOURCELINK records are always required, even if unused
+ mxTitleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ mxValueLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_VALUES ) );
+ mxCategLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_CATEGORY ) );
+ if( GetBiff() == EXC_BIFF8 )
+ mxBubbleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_BUBBLES ) );
+}
+
+bool XclExpChSeries::ConvertDataSeries(
+ Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries,
+ const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx )
+{
+ bool bOk = false;
+ Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
+ if( xDataSource.is() )
+ {
+ Reference< XDataSequence > xYValueSeq, xTitleSeq, xXValueSeq, xBubbleSeq;
+
+ // find first sequence with role 'values-y'
+ Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
+ const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
+ const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
+ for( const Reference< XLabeledDataSequence >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
+ ScfPropertySet aValueProp( xTmpValueSeq );
+ OUString aRole;
+ if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) )
+ {
+ if( !xYValueSeq.is() && (aRole == EXC_CHPROP_ROLE_YVALUES) )
+ {
+ xYValueSeq = xTmpValueSeq;
+ if( !xTitleSeq.is() )
+ xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ }
+ else if( !xXValueSeq.is() && !rTypeInfo.mbCategoryAxis && (aRole == EXC_CHPROP_ROLE_XVALUES) )
+ {
+ xXValueSeq = xTmpValueSeq;
+ }
+ else if( !xBubbleSeq.is() && (rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES) && (aRole == EXC_CHPROP_ROLE_SIZEVALUES) )
+ {
+ xBubbleSeq = xTmpValueSeq;
+ xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ }
+ }
+ }
+
+ bOk = xYValueSeq.is();
+ if( bOk )
+ {
+ // chart type group index
+ mnGroupIdx = nGroupIdx;
+
+ // convert source links
+ maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
+ mxTitleLink->ConvertDataSequence( xTitleSeq, true );
+
+ // X values of XY charts
+ maData.mnCategCount = mxCategLink->ConvertDataSequence( xXValueSeq, false, maData.mnValueCount );
+
+ // size values of bubble charts
+ if( mxBubbleLink.is() )
+ mxBubbleLink->ConvertDataSequence( xBubbleSeq, false, maData.mnValueCount );
+
+ // series formatting
+ XclChDataPointPos aPointPos( mnSeriesIdx );
+ ScfPropertySet aSeriesProp( xDataSeries );
+ mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
+ mxSeriesFmt->ConvertDataSeries( aSeriesProp, rTypeInfo );
+
+ // trend lines
+ CreateTrendLines( xDataSeries );
+
+ // error bars
+ CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARX, EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
+ CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARY, EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
+
+ if( maData.mnValueCount > 0 )
+ {
+ const sal_Int32 nMaxPointCount = maData.mnValueCount;
+
+ /* #i91063# Create missing fill properties in pie/doughnut charts.
+ If freshly created (never saved to ODF), these charts show
+ varying point colors but do not return these points via API. */
+ if( xDiagram.is() && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE) )
+ {
+ Reference< XColorScheme > xColorScheme = xDiagram->getDefaultColorScheme();
+ if( xColorScheme.is() )
+ {
+ const OUString aFillStyleName = CREATE_OUSTRING( "FillStyle" );
+ const OUString aColorName = CREATE_OUSTRING( "Color" );
+ namespace cssd = ::com::sun::star::drawing;
+ for( sal_Int32 nPointIdx = 0; nPointIdx < nMaxPointCount; ++nPointIdx )
+ {
+ aPointPos.mnPointIdx = static_cast< sal_uInt16 >( nPointIdx );
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
+ // test that the point fill style is solid, but no color is set
+ cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
+ if( aPointProp.GetProperty( eFillStyle, aFillStyleName ) &&
+ (eFillStyle == cssd::FillStyle_SOLID) &&
+ !aPointProp.HasProperty( aColorName ) )
+ {
+ aPointProp.SetProperty( aColorName, xColorScheme->getColorByIndex( nPointIdx ) );
+ }
+ }
+ }
+ }
+
+ // data point formatting
+ Sequence< sal_Int32 > aPointIndexes;
+ if( aSeriesProp.GetProperty( aPointIndexes, EXC_CHPROP_ATTRIBDATAPOINTS ) && aPointIndexes.hasElements() )
+ {
+ const sal_Int32* pnBeg = aPointIndexes.getConstArray();
+ const sal_Int32* pnEnd = pnBeg + aPointIndexes.getLength();
+ for( const sal_Int32* pnIt = pnBeg; (pnIt != pnEnd) && (*pnIt < nMaxPointCount); ++pnIt )
+ {
+ aPointPos.mnPointIdx = static_cast< sal_uInt16 >( *pnIt );
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, *pnIt );
+ XclExpChDataFormatRef xPointFmt( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
+ xPointFmt->ConvertDataSeries( aPointProp, rTypeInfo );
+ maPointFmts.AppendRecord( xPointFmt );
+ }
+ }
+ }
+ }
+ }
+ return bOk;
+}
+
+bool XclExpChSeries::ConvertStockSeries( XDataSeriesRef xDataSeries,
+ const OUString& rValueRole, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx, bool bCloseSymbol )
+{
+ bool bOk = false;
+ Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
+ if( xDataSource.is() )
+ {
+ Reference< XDataSequence > xYValueSeq, xTitleSeq;
+
+ // find first sequence with passed role
+ Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
+ const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
+ const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
+ for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xYValueSeq.is() && (pIt != pEnd); ++pIt )
+ {
+ Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
+ ScfPropertySet aValueProp( xTmpValueSeq );
+ OUString aRole;
+ if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) && (aRole == rValueRole) )
+ {
+ xYValueSeq = xTmpValueSeq;
+ xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ }
+ }
+
+ bOk = xYValueSeq.is();
+ if( bOk )
+ {
+ // chart type group index
+ mnGroupIdx = nGroupIdx;
+ // convert source links
+ maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
+ mxTitleLink->ConvertDataSequence( xTitleSeq, true );
+ // series formatting
+ ScfPropertySet aSeriesProp( xDataSeries );
+ mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), nFormatIdx ) );
+ mxSeriesFmt->ConvertStockSeries( aSeriesProp, bCloseSymbol );
+ }
+ }
+ return bOk;
+}
+
+bool XclExpChSeries::ConvertTrendLine( const XclExpChSeries& rParent, Reference< XRegressionCurve > xRegCurve )
+{
+ InitFromParent( rParent );
+ mxTrendLine.reset( new XclExpChSerTrendLine( GetChRoot() ) );
+ bool bOk = mxTrendLine->Convert( xRegCurve, mnSeriesIdx );
+ if( bOk )
+ {
+ mxSeriesFmt = mxTrendLine->GetDataFormat();
+ GetChartData().SetDataLabel( mxTrendLine->GetDataLabel() );
+ }
+ return bOk;
+}
+
+bool XclExpChSeries::ConvertErrorBar( const XclExpChSeries& rParent, const ScfPropertySet& rPropSet, sal_uInt8 nBarId )
+{
+ InitFromParent( rParent );
+ // error bar settings
+ mxErrorBar.reset( new XclExpChSerErrorBar( GetChRoot(), nBarId ) );
+ bool bOk = mxErrorBar->Convert( *mxValueLink, maData.mnValueCount, rPropSet );
+ if( bOk )
+ {
+ // error bar formatting
+ mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), 0 ) );
+ mxSeriesFmt->ConvertLine( rPropSet, EXC_CHOBJTYPE_ERRORBAR );
+ }
+ return bOk;
+}
+
+void XclExpChSeries::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
+{
+ if( xCategSeq.is() )
+ maData.mnCategCount = mxCategLink->ConvertDataSequence( xCategSeq->getValues(), false );
+}
+
+void XclExpChSeries::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxTitleLink );
+ lclSaveRecord( rStrm, mxValueLink );
+ lclSaveRecord( rStrm, mxCategLink );
+ lclSaveRecord( rStrm, mxBubbleLink );
+ lclSaveRecord( rStrm, mxSeriesFmt );
+ maPointFmts.Save( rStrm );
+ if( mnGroupIdx != EXC_CHSERGROUP_NONE )
+ XclExpUInt16Record( EXC_ID_CHSERGROUP, mnGroupIdx ).Save( rStrm );
+ if( mnParentIdx != EXC_CHSERIES_INVALID )
+ XclExpUInt16Record( EXC_ID_CHSERPARENT, mnParentIdx ).Save( rStrm );
+ lclSaveRecord( rStrm, mxTrendLine );
+ lclSaveRecord( rStrm, mxErrorBar );
+}
+
+void XclExpChSeries::InitFromParent( const XclExpChSeries& rParent )
+{
+ // index to parent series is stored 1-based
+ mnParentIdx = rParent.mnSeriesIdx + 1;
+ /* #i86465# MSO2007 SP1 expects correct point counts in child series
+ (there was no problem in Excel2003 or Excel2007 without SP1...) */
+ maData.mnCategCount = rParent.maData.mnCategCount;
+ maData.mnValueCount = rParent.maData.mnValueCount;
+}
+
+void XclExpChSeries::CreateTrendLines( XDataSeriesRef xDataSeries )
+{
+ Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
+ if( xRegCurveCont.is() )
+ {
+ Sequence< Reference< XRegressionCurve > > aRegCurveSeq = xRegCurveCont->getRegressionCurves();
+ const Reference< XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
+ const Reference< XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
+ for( const Reference< XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries.is() && !xSeries->ConvertTrendLine( *this, *pIt ) )
+ GetChartData().RemoveLastSeries();
+ }
+ }
+}
+
+void XclExpChSeries::CreateErrorBars( const ScfPropertySet& rPropSet,
+ const OUString& rBarPropName, sal_uInt8 nPosBarId, sal_uInt8 nNegBarId )
+{
+ Reference< XPropertySet > xErrorBar;
+ if( rPropSet.GetProperty( xErrorBar, rBarPropName ) && xErrorBar.is() )
+ {
+ ScfPropertySet aErrorProp( xErrorBar );
+ CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWPOSITIVEERROR, nPosBarId );
+ CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWNEGATIVEERROR, nNegBarId );
+ }
+}
+
+void XclExpChSeries::CreateErrorBar( const ScfPropertySet& rPropSet,
+ const OUString& rShowPropName, sal_uInt8 nBarId )
+{
+ if( rPropSet.GetBoolProperty( rShowPropName ) )
+ {
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries.is() && !xSeries->ConvertErrorBar( *this, rPropSet, nBarId ) )
+ GetChartData().RemoveLastSeries();
+ }
+}
+
+void XclExpChSeries::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnCategType << maData.mnValueType << maData.mnCategCount << maData.mnValueCount;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << maData.mnBubbleType << maData.mnBubbleCount;
+}
+
+// Chart type groups ==========================================================
+
+XclExpChType::XclExpChType( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHUNKNOWN ),
+ XclExpChRoot( rRoot ),
+ maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
+{
+}
+
+void XclExpChType::Convert( Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
+ sal_Int32 nApiAxesSetIdx, bool bSwappedAxesSet, bool bHasXLabels )
+{
+ if( xChartType.is() )
+ {
+ maTypeInfo = GetChartTypeInfo( xChartType->getChartType() );
+ // special handling for some chart types
+ switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_BAR:
+ {
+ maTypeInfo = GetChartTypeInfo( bSwappedAxesSet ? EXC_CHTYPEID_HORBAR : EXC_CHTYPEID_BAR );
+ ::set_flag( maData.mnFlags, EXC_CHBAR_HORIZONTAL, bSwappedAxesSet );
+ ScfPropertySet aTypeProp( xChartType );
+ Sequence< sal_Int32 > aInt32Seq;
+ maData.mnOverlap = 0;
+ if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_OVERLAPSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
+ maData.mnOverlap = limit_cast< sal_Int16 >( -aInt32Seq[ nApiAxesSetIdx ], -100, 100 );
+ maData.mnGap = 150;
+ if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_GAPWIDTHSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
+ maData.mnGap = limit_cast< sal_uInt16 >( aInt32Seq[ nApiAxesSetIdx ], 0, 500 );
+ }
+ break;
+ case EXC_CHTYPECATEG_RADAR:
+ ::set_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS, bHasXLabels );
+ break;
+ case EXC_CHTYPECATEG_PIE:
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ bool bDonut = aTypeProp.GetBoolProperty( EXC_CHPROP_USERINGS );
+ maTypeInfo = GetChartTypeInfo( bDonut ? EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
+ maData.mnPieHole = bDonut ? 50 : 0;
+ // #i85166# starting angle of first pie slice
+ ScfPropertySet aDiaProp( xDiagram );
+ maData.mnRotation = XclExpChRoot::ConvertPieRotation( aDiaProp );
+ }
+ break;
+ case EXC_CHTYPECATEG_SCATTER:
+ if( GetBiff() == EXC_BIFF8 )
+ ::set_flag( maData.mnFlags, EXC_CHSCATTER_BUBBLES, maTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES );
+ break;
+ default:;
+ }
+ SetRecId( maTypeInfo.mnRecId );
+ }
+}
+
+void XclExpChType::SetStacked( bool bPercent )
+{
+ switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_LINE:
+ ::set_flag( maData.mnFlags, EXC_CHLINE_STACKED );
+ ::set_flag( maData.mnFlags, EXC_CHLINE_PERCENT, bPercent );
+ break;
+ case EXC_CHTYPECATEG_BAR:
+ ::set_flag( maData.mnFlags, EXC_CHBAR_STACKED );
+ ::set_flag( maData.mnFlags, EXC_CHBAR_PERCENT, bPercent );
+ maData.mnOverlap = -100;
+ break;
+ default:;
+ }
+}
+
+void XclExpChType::WriteBody( XclExpStream& rStrm )
+{
+ switch( GetRecId() )
+ {
+ case EXC_ID_CHBAR:
+ rStrm << maData.mnOverlap << maData.mnGap << maData.mnFlags;
+ break;
+
+ case EXC_ID_CHLINE:
+ case EXC_ID_CHAREA:
+ case EXC_ID_CHRADARLINE:
+ case EXC_ID_CHRADARAREA:
+ rStrm << maData.mnFlags;
+ break;
+
+ case EXC_ID_CHPIE:
+ rStrm << maData.mnRotation << maData.mnPieHole;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << maData.mnFlags;
+ break;
+
+ case EXC_ID_CHSCATTER:
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << maData.mnBubbleSize << maData.mnBubbleType << maData.mnFlags;
+ break;
+
+ default:
+ DBG_ERRORFILE( "XclExpChType::WriteBody - unknown chart type" );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChChart3d::XclExpChChart3d() :
+ XclExpRecord( EXC_ID_CHCHART3D, 14 )
+{
+}
+
+void XclExpChChart3d::Convert( const ScfPropertySet& rPropSet, bool b3dWallChart )
+{
+ sal_Int32 nRotationY = 0;
+ rPropSet.GetProperty( nRotationY, EXC_CHPROP_ROTATIONVERTICAL );
+ sal_Int32 nRotationX = 0;
+ rPropSet.GetProperty( nRotationX, EXC_CHPROP_ROTATIONHORIZONTAL );
+ sal_Int32 nPerspective = 15;
+ rPropSet.GetProperty( nPerspective, EXC_CHPROP_PERSPECTIVE );
+
+ if( b3dWallChart )
+ {
+ // Y rotation (Excel [0..359], Chart2 [-179,180])
+ if( nRotationY < 0 ) nRotationY += 360;
+ maData.mnRotation = static_cast< sal_uInt16 >( nRotationY );
+ // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
+ maData.mnElevation = limit_cast< sal_Int16 >( nRotationX, -90, 90 );
+ // perspective (Excel and Chart2 [0,100])
+ maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
+ // flags
+ maData.mnFlags = 0;
+ ::set_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D, !rPropSet.GetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES ) );
+ ::set_flag( maData.mnFlags, EXC_CHCHART3D_AUTOHEIGHT );
+ ::set_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS );
+ }
+ else
+ {
+ // Y rotation not used in pie charts, but 'first pie slice angle'
+ maData.mnRotation = XclExpChRoot::ConvertPieRotation( rPropSet );
+ // X rotation a.k.a. elevation (map Chart2 [-80,-10] to Excel [10..80])
+ maData.mnElevation = limit_cast< sal_Int16 >( (nRotationX + 270) % 180, 10, 80 );
+ // perspective (Excel and Chart2 [0,100])
+ maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
+ // flags
+ maData.mnFlags = 0;
+ }
+}
+
+void XclExpChChart3d::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnRotation
+ << maData.mnElevation
+ << maData.mnEyeDist
+ << maData.mnRelHeight
+ << maData.mnRelDepth
+ << maData.mnDepthGap
+ << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChLegend::XclExpChLegend( const XclExpChRoot& rRoot ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_LEGEND, EXC_ID_CHLEGEND, 20 )
+{
+}
+
+void XclExpChLegend::Convert( const ScfPropertySet& rPropSet )
+{
+ // frame properties
+ mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_LEGEND );
+ // text properties
+ mxText.reset( new XclExpChText( GetChRoot() ) );
+ mxText->ConvertLegend( rPropSet );
+
+ // legend position
+ Any aRelPosAny;
+ rPropSet.GetAnyProperty( aRelPosAny, EXC_CHPROP_RELATIVEPOSITION );
+ if( aRelPosAny.has< RelativePosition >() )
+ {
+ try
+ {
+ /* The 'RelativePosition' property is used as indicator of manually
+ changed legend position, but due to the different anchor modes
+ used by this property (in the RelativePosition.Anchor member)
+ it cannot be used to calculate the position easily. For this,
+ the Chart1 API will be used instead. */
+ Reference< ::com::sun::star::chart::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
+ Reference< XShape > xChart1Legend( xChart1Doc->getLegend(), UNO_SET_THROW );
+ // coordinates in CHLEGEND record written but not used by Excel
+ mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_CHARTSIZE, EXC_CHFRAMEPOS_PARENT ) );
+ XclChFramePos& rFramePos = mxFramePos->GetFramePosData();
+ rFramePos.maRect.mnX = maData.maRect.mnX = CalcChartXFromHmm( xChart1Legend->getPosition().X );
+ rFramePos.maRect.mnY = maData.maRect.mnY = CalcChartYFromHmm( xChart1Legend->getPosition().Y );
+ // manual legend position implies manual plot area
+ GetChartData().SetManualPlotArea();
+ maData.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "XclExpChLegend::Convert - cannot get legend shape" );
+ maData.mnDockMode = EXC_CHLEGEND_RIGHT;
+ }
+ }
+ else
+ {
+ cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
+ rPropSet.GetProperty( eApiPos, EXC_CHPROP_ANCHORPOSITION );
+ switch( eApiPos )
+ {
+ case cssc2::LegendPosition_LINE_START: maData.mnDockMode = EXC_CHLEGEND_LEFT; break;
+ case cssc2::LegendPosition_LINE_END: maData.mnDockMode = EXC_CHLEGEND_RIGHT; break;
+ case cssc2::LegendPosition_PAGE_START: maData.mnDockMode = EXC_CHLEGEND_TOP; break;
+ case cssc2::LegendPosition_PAGE_END: maData.mnDockMode = EXC_CHLEGEND_BOTTOM; break;
+ default:
+ OSL_ENSURE( false, "XclExpChLegend::Convert - unrecognized legend position" );
+ maData.mnDockMode = EXC_CHLEGEND_RIGHT;
+ }
+ }
+
+ // legend expansion
+ cssc2::LegendExpansion eApiExpand = cssc2::LegendExpansion_BALANCED;
+ rPropSet.GetProperty( eApiExpand, EXC_CHPROP_EXPANSION );
+ ::set_flag( maData.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc2::LegendExpansion_WIDE );
+
+ // other flags
+ ::set_flag( maData.mnFlags, EXC_CHLEGEND_AUTOSERIES );
+ const sal_uInt16 nAutoFlags = EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY;
+ ::set_flag( maData.mnFlags, nAutoFlags, maData.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
+}
+
+void XclExpChLegend::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxFramePos );
+ lclSaveRecord( rStrm, mxText );
+ lclSaveRecord( rStrm, mxFrame );
+}
+
+void XclExpChLegend::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maRect << maData.mnDockMode << maData.mnSpacing << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChDropBar::XclExpChDropBar( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DROPBAR, EXC_ID_CHDROPBAR, 2 ),
+ meObjType( eObjType ),
+ mnBarDist( 100 )
+{
+}
+
+void XclExpChDropBar::Convert( const ScfPropertySet& rPropSet )
+{
+ if( rPropSet.Is() )
+ ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
+ else
+ SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, true );
+}
+
+void XclExpChDropBar::WriteSubRecords( XclExpStream& rStrm )
+{
+ WriteFrameRecords( rStrm );
+}
+
+void XclExpChDropBar::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnBarDist;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChTypeGroup::XclExpChTypeGroup( const XclExpChRoot& rRoot, sal_uInt16 nGroupIdx ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TYPEGROUP, EXC_ID_CHTYPEGROUP, 20 ),
+ maType( rRoot ),
+ maTypeInfo( maType.GetTypeInfo() )
+{
+ maData.mnGroupIdx = nGroupIdx;
+}
+
+void XclExpChTypeGroup::ConvertType(
+ Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
+ sal_Int32 nApiAxesSetIdx, bool b3dChart, bool bSwappedAxesSet, bool bHasXLabels )
+{
+ // chart type settings
+ maType.Convert( xDiagram, xChartType, nApiAxesSetIdx, bSwappedAxesSet, bHasXLabels );
+
+ // spline - TODO: get from single series (#i66858#)
+ ScfPropertySet aTypeProp( xChartType );
+ ::com::sun::star::chart2::CurveStyle eCurveStyle;
+ bool bSpline = aTypeProp.GetProperty( eCurveStyle, EXC_CHPROP_CURVESTYLE ) &&
+ (eCurveStyle != ::com::sun::star::chart2::CurveStyle_LINES);
+
+ // extended type info
+ maTypeInfo.Set( maType.GetTypeInfo(), b3dChart, bSpline );
+
+ // 3d chart settings
+ if( maTypeInfo.mb3dChart ) // only true, if Excel chart supports 3d mode
+ {
+ mxChart3d.reset( new XclExpChChart3d );
+ ScfPropertySet aDiaProp( xDiagram );
+ mxChart3d->Convert( aDiaProp, Is3dWallChart() );
+ }
+}
+
+void XclExpChTypeGroup::ConvertSeries(
+ Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
+ sal_Int32 nGroupAxesSetIdx, bool bPercent, bool bConnectBars )
+{
+ Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
+ if( xSeriesCont.is() )
+ {
+ typedef ::std::vector< Reference< XDataSeries > > XDataSeriesVec;
+ XDataSeriesVec aSeriesVec;
+
+ // copy data series attached to the current axes set to the vector
+ Sequence< Reference< XDataSeries > > aSeriesSeq = xSeriesCont->getDataSeries();
+ const Reference< XDataSeries >* pBeg = aSeriesSeq.getConstArray();
+ const Reference< XDataSeries >* pEnd = pBeg + aSeriesSeq.getLength();
+ for( const Reference< XDataSeries >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ ScfPropertySet aSeriesProp( *pIt );
+ sal_Int32 nSeriesAxesSetIdx(0);
+ if( aSeriesProp.GetProperty( nSeriesAxesSetIdx, EXC_CHPROP_ATTAXISINDEX ) && (nSeriesAxesSetIdx == nGroupAxesSetIdx) )
+ aSeriesVec.push_back( *pIt );
+ }
+
+ // Are there any series in the current axes set?
+ if( !aSeriesVec.empty() )
+ {
+ // stacking direction (stacked/percent/deep 3d) from first series
+ ScfPropertySet aSeriesProp( aSeriesVec.front() );
+ cssc2::StackingDirection eStacking;
+ if( !aSeriesProp.GetProperty( eStacking, EXC_CHPROP_STACKINGDIR ) )
+ eStacking = cssc2::StackingDirection_NO_STACKING;
+
+ // stacked or percent chart
+ if( maTypeInfo.mbSupportsStacking && (eStacking == cssc2::StackingDirection_Y_STACKING) )
+ {
+ // percent overrides simple stacking
+ maType.SetStacked( bPercent );
+
+ // connected data points (only in stacked bar charts)
+ if( bConnectBars && (maTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) )
+ maChartLines[ EXC_CHCHARTLINE_CONNECT ].reset( new XclExpChLineFormat( GetChRoot() ) );
+ }
+ else
+ {
+ // reverse series order for some unstacked 2D chart types
+ if( maTypeInfo.mbReverseSeries && !Is3dChart() )
+ ::std::reverse( aSeriesVec.begin(), aSeriesVec.end() );
+ }
+
+ // deep 3d chart or clustered 3d chart (stacked is not clustered)
+ if( (eStacking == cssc2::StackingDirection_NO_STACKING) && Is3dWallChart() )
+ mxChart3d->SetClustered();
+
+ // varied point colors
+ ::set_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS, aSeriesProp.GetBoolProperty( EXC_CHPROP_VARYCOLORSBY ) );
+
+ // process all series
+ for( XDataSeriesVec::const_iterator aIt = aSeriesVec.begin(), aEnd = aSeriesVec.end(); aIt != aEnd; ++aIt )
+ {
+ // create Excel series object, stock charts need special processing
+ if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
+ CreateAllStockSeries( xChartType, *aIt );
+ else
+ CreateDataSeries( xDiagram, *aIt );
+ }
+ }
+ }
+}
+
+void XclExpChTypeGroup::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
+{
+ for( size_t nIdx = 0, nSize = maSeries.GetSize(); nIdx < nSize; ++nIdx )
+ maSeries.GetRecord( nIdx )->ConvertCategSequence( xCategSeq );
+}
+
+void XclExpChTypeGroup::ConvertLegend( const ScfPropertySet& rPropSet )
+{
+ if( rPropSet.GetBoolProperty( EXC_CHPROP_SHOW ) )
+ {
+ mxLegend.reset( new XclExpChLegend( GetChRoot() ) );
+ mxLegend->Convert( rPropSet );
+ }
+}
+
+void XclExpChTypeGroup::WriteSubRecords( XclExpStream& rStrm )
+{
+ maType.Save( rStrm );
+ lclSaveRecord( rStrm, mxChart3d );
+ lclSaveRecord( rStrm, mxLegend );
+ lclSaveRecord( rStrm, mxUpBar );
+ lclSaveRecord( rStrm, mxDownBar );
+ for( XclExpChLineFormatMap::iterator aLIt = maChartLines.begin(), aLEnd = maChartLines.end(); aLIt != aLEnd; ++aLIt )
+ lclSaveRecord( rStrm, aLIt->second, EXC_ID_CHCHARTLINE, aLIt->first );
+}
+
+sal_uInt16 XclExpChTypeGroup::GetFreeFormatIdx() const
+{
+ return static_cast< sal_uInt16 >( maSeries.GetSize() );
+}
+
+void XclExpChTypeGroup::CreateDataSeries(
+ Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries )
+{
+ // let chart create series object with correct series index
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries.is() )
+ {
+ if( xSeries->ConvertDataSeries( xDiagram, xDataSeries, maTypeInfo, GetGroupIdx(), GetFreeFormatIdx() ) )
+ maSeries.AppendRecord( xSeries );
+ else
+ GetChartData().RemoveLastSeries();
+ }
+}
+
+void XclExpChTypeGroup::CreateAllStockSeries(
+ Reference< XChartType > xChartType, Reference< XDataSeries > xDataSeries )
+{
+ // create existing series objects
+ bool bHasOpen = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_OPENVALUES, false );
+ bool bHasHigh = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_HIGHVALUES, false );
+ bool bHasLow = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_LOWVALUES, false );
+ bool bHasClose = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_CLOSEVALUES, !bHasOpen );
+
+ // formatting of special stock chart elements
+ ScfPropertySet aTypeProp( xChartType );
+ // hi-lo lines
+ if( bHasHigh && bHasLow && aTypeProp.GetBoolProperty( EXC_CHPROP_SHOWHIGHLOW ) )
+ {
+ ScfPropertySet aSeriesProp( xDataSeries );
+ XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( GetChRoot() ) );
+ xLineFmt->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
+ maChartLines[ EXC_CHCHARTLINE_HILO ] = xLineFmt;
+ }
+ // dropbars
+ if( bHasOpen && bHasClose )
+ {
+ // dropbar type is dependent on position in the file - always create both
+ Reference< XPropertySet > xWhitePropSet, xBlackPropSet;
+ // white dropbar format
+ aTypeProp.GetProperty( xWhitePropSet, EXC_CHPROP_WHITEDAY );
+ ScfPropertySet aWhiteProp( xWhitePropSet );
+ mxUpBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_WHITEDROPBAR ) );
+ mxUpBar->Convert( aWhiteProp );
+ // black dropbar format
+ aTypeProp.GetProperty( xBlackPropSet, EXC_CHPROP_BLACKDAY );
+ ScfPropertySet aBlackProp( xBlackPropSet );
+ mxDownBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_BLACKDROPBAR ) );
+ mxDownBar->Convert( aBlackProp );
+ }
+}
+
+bool XclExpChTypeGroup::CreateStockSeries( Reference< XDataSeries > xDataSeries,
+ const OUString& rValueRole, bool bCloseSymbol )
+{
+ bool bOk = false;
+ // let chart create series object with correct series index
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries.is() )
+ {
+ bOk = xSeries->ConvertStockSeries( xDataSeries,
+ rValueRole, GetGroupIdx(), GetFreeFormatIdx(), bCloseSymbol );
+ if( bOk )
+ maSeries.AppendRecord( xSeries );
+ else
+ GetChartData().RemoveLastSeries();
+ }
+ return bOk;
+}
+
+void XclExpChTypeGroup::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.WriteZeroBytes( 16 );
+ rStrm << maData.mnFlags << maData.mnGroupIdx;
+}
+
+// Axes =======================================================================
+
+XclExpChLabelRange::XclExpChLabelRange( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHLABELRANGE, 8 ),
+ XclExpChRoot( rRoot )
+{
+}
+
+void XclExpChLabelRange::Convert( const ScaleData& rScaleData, bool bMirrorOrient )
+{
+ // origin
+ double fOrigin = 0.0;
+ if( !lclIsAutoAnyOrGetValue( fOrigin, rScaleData.Origin ) )
+ maData.mnCross = limit_cast< sal_uInt16 >( fOrigin, 1, 31999 );
+
+ // reverse order
+ if( (rScaleData.Orientation == ::com::sun::star::chart2::AxisOrientation_REVERSE) != bMirrorOrient )
+ ::set_flag( maData.mnFlags, EXC_CHLABELRANGE_REVERSE );
+}
+
+void XclExpChLabelRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
+{
+ cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
+ rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION );
+ double fCrossingPos = 1.0;
+ rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE );
+ switch( eAxisPos )
+ {
+ case cssc::ChartAxisPosition_ZERO: maData.mnCross = 1; break;
+ case cssc::ChartAxisPosition_START: maData.mnCross = 1; break;
+ case cssc::ChartAxisPosition_END: ::set_flag( maData.mnFlags, EXC_CHLABELRANGE_MAXCROSS ); break;
+ case cssc::ChartAxisPosition_VALUE: maData.mnCross = limit_cast< sal_uInt16 >( fCrossingPos, 1, 31999 ); break;
+ default: maData.mnCross = 1;
+ }
+}
+
+void XclExpChLabelRange::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnCross << maData.mnLabelFreq << maData.mnTickFreq << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChValueRange::XclExpChValueRange( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHVALUERANGE, 42 ),
+ XclExpChRoot( rRoot )
+{
+}
+
+void XclExpChValueRange::Convert( const ScaleData& rScaleData )
+{
+ // scaling algorithm
+ bool bLogScale = ScfApiHelper::GetServiceName( rScaleData.Scaling ) == SERVICE_CHART2_LOGSCALING;
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, bLogScale );
+
+ // min/max
+ bool bAutoMin = lclIsAutoAnyOrGetScaledValue( maData.mfMin, rScaleData.Minimum, bLogScale );
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN, bAutoMin );
+ bool bAutoMax = lclIsAutoAnyOrGetScaledValue( maData.mfMax, rScaleData.Maximum, bLogScale );
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX, bAutoMax );
+
+ // origin
+ bool bAutoCross = lclIsAutoAnyOrGetScaledValue( maData.mfCross, rScaleData.Origin, bLogScale );
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, bAutoCross );
+
+ // major increment
+ const IncrementData& rIncrementData = rScaleData.IncrementData;
+ bool bAutoMajor = lclIsAutoAnyOrGetValue( maData.mfMajorStep, rIncrementData.Distance ) || (maData.mfMajorStep <= 0.0);
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR, bAutoMajor );
+ // minor increment
+ const Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
+ sal_Int32 nCount = 0;
+ bool bAutoMinor = bLogScale || bAutoMajor || (rSubIncrementSeq.getLength() < 1) ||
+ lclIsAutoAnyOrGetValue( nCount, rSubIncrementSeq[ 0 ].IntervalCount ) || (nCount < 1);
+ if( !bAutoMinor )
+ maData.mfMinorStep = maData.mfMajorStep / nCount;
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR, bAutoMinor );
+
+ // reverse order
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc2::AxisOrientation_REVERSE );
+}
+
+void XclExpChValueRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
+{
+ cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
+ double fCrossingPos = 0.0;
+ if( rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ) && rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE ) )
+ {
+ switch( eAxisPos )
+ {
+ case cssc::ChartAxisPosition_ZERO:
+ case cssc::ChartAxisPosition_START:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
+ break;
+ case cssc::ChartAxisPosition_END:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
+ break;
+ case cssc::ChartAxisPosition_VALUE:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, false );
+ maData.mfCross = ::get_flagvalue< double >( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, log( fCrossingPos ) / log( 10.0 ), fCrossingPos );
+ break;
+ default:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
+ }
+ }
+}
+
+void XclExpChValueRange::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mfMin
+ << maData.mfMax
+ << maData.mfMajorStep
+ << maData.mfMinorStep
+ << maData.mfCross
+ << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_uInt8 lclGetXclTickPos( sal_Int32 nApiTickmarks )
+{
+ using namespace ::com::sun::star::chart2::TickmarkStyle;
+ sal_uInt8 nXclTickPos = 0;
+ ::set_flag( nXclTickPos, EXC_CHTICK_INSIDE, ::get_flag( nApiTickmarks, INNER ) );
+ ::set_flag( nXclTickPos, EXC_CHTICK_OUTSIDE, ::get_flag( nApiTickmarks, OUTER ) );
+ return nXclTickPos;
+}
+
+} // namespace
+
+XclExpChTick::XclExpChTick( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHTICK, (rRoot.GetBiff() == EXC_BIFF8) ? 30 : 26 ),
+ XclExpChRoot( rRoot ),
+ mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+void XclExpChTick::Convert( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nAxisType )
+{
+ // tick mark style
+ sal_Int32 nApiTickmarks = 0;
+ if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MAJORTICKS ) )
+ maData.mnMajor = lclGetXclTickPos( nApiTickmarks );
+ if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MINORTICKS ) )
+ maData.mnMinor = lclGetXclTickPos( nApiTickmarks );
+
+ // axis labels
+ if( (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) && (nAxisType == EXC_CHAXIS_X) )
+ {
+ /* Radar charts disable their category labels via chart type, not via
+ axis, and axis labels are always 'near axis'. */
+ maData.mnLabelPos = EXC_CHTICK_NEXT;
+ }
+ else if( !rPropSet.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS ) )
+ {
+ // no labels
+ maData.mnLabelPos = EXC_CHTICK_NOLABEL;
+ }
+ else if( rTypeInfo.mb3dChart && (nAxisType == EXC_CHAXIS_Y) )
+ {
+ // Excel expects 'near axis' at Y axes in 3D charts
+ maData.mnLabelPos = EXC_CHTICK_NEXT;
+ }
+ else
+ {
+ cssc::ChartAxisLabelPosition eApiLabelPos = cssc::ChartAxisLabelPosition_NEAR_AXIS;
+ rPropSet.GetProperty( eApiLabelPos, EXC_CHPROP_LABELPOSITION );
+ switch( eApiLabelPos )
+ {
+ case cssc::ChartAxisLabelPosition_NEAR_AXIS:
+ case cssc::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE: maData.mnLabelPos = EXC_CHTICK_NEXT; break;
+ case cssc::ChartAxisLabelPosition_OUTSIDE_START: maData.mnLabelPos = EXC_CHTICK_LOW; break;
+ case cssc::ChartAxisLabelPosition_OUTSIDE_END: maData.mnLabelPos = EXC_CHTICK_HIGH; break;
+ default: maData.mnLabelPos = EXC_CHTICK_NEXT;
+ }
+ }
+}
+
+void XclExpChTick::SetFontColor( const Color& rColor, sal_uInt32 nColorId )
+{
+ maData.maTextColor = rColor;
+ ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR, rColor == COL_AUTO );
+ mnTextColorId = nColorId;
+}
+
+void XclExpChTick::SetRotation( sal_uInt16 nRotation )
+{
+ maData.mnRotation = nRotation;
+ ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOROT, false );
+ ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 2, 3 );
+}
+
+void XclExpChTick::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnMajor
+ << maData.mnMinor
+ << maData.mnLabelPos
+ << maData.mnBackMode;
+ rStrm.WriteZeroBytes( 16 );
+ rStrm << maData.maTextColor
+ << maData.mnFlags;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << GetPalette().GetColorIndex( mnTextColorId ) << maData.mnRotation;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Returns an API axis object from the passed coordinate system. */
+Reference< XAxis > lclGetApiAxis( Reference< XCoordinateSystem > xCoordSystem,
+ sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
+{
+ Reference< XAxis > xAxis;
+ if( (nApiAxisDim >= 0) && xCoordSystem.is() ) try
+ {
+ xAxis = xCoordSystem->getAxisByDimension( nApiAxisDim, nApiAxesSetIdx );
+ }
+ catch( Exception& )
+ {
+ }
+ return xAxis;
+}
+
+} // namespace
+
+XclExpChAxis::XclExpChAxis( const XclExpChRoot& rRoot, sal_uInt16 nAxisType ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXIS, EXC_ID_CHAXIS, 18 ),
+ mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
+{
+ maData.mnType = nAxisType;
+}
+
+void XclExpChAxis::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
+{
+ mxFont = xFont;
+ if( mxTick.is() )
+ mxTick->SetFontColor( rColor, nColorId );
+}
+
+void XclExpChAxis::SetRotation( sal_uInt16 nRotation )
+{
+ if( mxTick.is() )
+ mxTick->SetRotation( nRotation );
+}
+
+void XclExpChAxis::Convert( Reference< XAxis > xAxis, Reference< XAxis > xCrossingAxis, const XclChExtTypeInfo& rTypeInfo )
+{
+ ScfPropertySet aAxisProp( xAxis );
+ bool bCategoryAxis = ((GetAxisType() == EXC_CHAXIS_X) && rTypeInfo.mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z);
+
+ // axis line format -------------------------------------------------------
+
+ mxAxisLine.reset( new XclExpChLineFormat( GetChRoot() ) );
+ mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
+ // #i58688# axis enabled
+ mxAxisLine->SetShowAxis( aAxisProp.GetBoolProperty( EXC_CHPROP_SHOW ) );
+
+ // axis scaling and increment ---------------------------------------------
+
+ ScfPropertySet aCrossingProp( xCrossingAxis );
+ if( bCategoryAxis )
+ {
+ mxLabelRange.reset( new XclExpChLabelRange( GetChRoot() ) );
+ mxLabelRange->SetTicksBetweenCateg( rTypeInfo.mbTicksBetweenCateg );
+ if( xAxis.is() )
+ // #i71684# radar charts have reversed rotation direction
+ mxLabelRange->Convert( xAxis->getScaleData(), (GetAxisType() == EXC_CHAXIS_X) && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) );
+ // get position of crossing axis on this axis from passed axis object
+ if( aCrossingProp.Is() )
+ mxLabelRange->ConvertAxisPosition( aCrossingProp );
+ }
+ else
+ {
+ mxValueRange.reset( new XclExpChValueRange( GetChRoot() ) );
+ if( xAxis.is() )
+ mxValueRange->Convert( xAxis->getScaleData() );
+ // get position of crossing axis on this axis from passed axis object
+ if( aCrossingProp.Is() )
+ mxValueRange->ConvertAxisPosition( aCrossingProp );
+ }
+
+ // axis caption text ------------------------------------------------------
+
+ // axis ticks properties
+ mxTick.reset( new XclExpChTick( GetChRoot() ) );
+ mxTick->Convert( aAxisProp, rTypeInfo, GetAxisType() );
+
+ // axis label formatting and rotation
+ ConvertFontBase( GetChRoot(), aAxisProp );
+ ConvertRotationBase( GetChRoot(), aAxisProp, true );
+
+ // axis number format
+ sal_Int32 nApiNumFmt = 0;
+ if( !bCategoryAxis && aAxisProp.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
+ mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
+
+ // grid -------------------------------------------------------------------
+
+ if( xAxis.is() )
+ {
+ // main grid
+ ScfPropertySet aGridProp( xAxis->getGridProperties() );
+ if( aGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
+ mxMajorGrid = lclCreateLineFormat( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ // sub grid
+ Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
+ if( aSubGridPropSeq.hasElements() )
+ {
+ ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
+ if( aSubGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
+ mxMinorGrid = lclCreateLineFormat( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ }
+ }
+}
+
+void XclExpChAxis::ConvertWall( XDiagramRef xDiagram )
+{
+ if( xDiagram.is() ) switch( GetAxisType() )
+ {
+ case EXC_CHAXIS_X:
+ {
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxWallFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_WALL3D );
+ }
+ break;
+ case EXC_CHAXIS_Y:
+ {
+ ScfPropertySet aFloorProp( xDiagram->getFloor() );
+ mxWallFrame = lclCreateFrame( GetChRoot(), aFloorProp, EXC_CHOBJTYPE_FLOOR3D );
+ }
+ break;
+ default:
+ mxWallFrame.reset();
+ }
+}
+
+void XclExpChAxis::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxLabelRange );
+ lclSaveRecord( rStrm, mxValueRange );
+ if( mnNumFmtIdx != EXC_FORMAT_NOTFOUND )
+ XclExpUInt16Record( EXC_ID_CHFORMAT, mnNumFmtIdx ).Save( rStrm );
+ lclSaveRecord( rStrm, mxTick );
+ lclSaveRecord( rStrm, mxFont );
+ lclSaveRecord( rStrm, mxAxisLine, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_AXISLINE );
+ lclSaveRecord( rStrm, mxMajorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MAJORGRID );
+ lclSaveRecord( rStrm, mxMinorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MINORGRID );
+ lclSaveRecord( rStrm, mxWallFrame, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_WALLS );
+}
+
+void XclExpChAxis::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnType;
+ rStrm.WriteZeroBytes( 16 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChAxesSet::XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXESSET, EXC_ID_CHAXESSET, 18 )
+{
+ maData.mnAxesSetId = nAxesSetId;
+ SetFutureRecordContext( 0, nAxesSetId );
+
+ /* Need to set a reasonable size for the plot area, otherwise Excel will
+ move away embedded shapes while auto-sizing the plot area. This is just
+ a wild guess, but will be fixed with implementing manual positioning of
+ chart elements. */
+ maData.maRect.mnX = 262;
+ maData.maRect.mnY = 626;
+ maData.maRect.mnWidth = 3187;
+ maData.maRect.mnHeight = 2633;
+}
+
+sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 nFirstGroupIdx )
+{
+ /* First unused chart type group index is passed to be able to continue
+ counting of chart type groups for secondary axes set. */
+ sal_uInt16 nGroupIdx = nFirstGroupIdx;
+ Reference< XCoordinateSystemContainer > xCoordSysCont( xDiagram, UNO_QUERY );
+ if( xCoordSysCont.is() )
+ {
+ Sequence< Reference< XCoordinateSystem > > aCoordSysSeq = xCoordSysCont->getCoordinateSystems();
+ if( aCoordSysSeq.getLength() > 0 )
+ {
+ /* Process first coordinate system only. Import filter puts all
+ chart types into one coordinate system. */
+ Reference< XCoordinateSystem > xCoordSystem = aCoordSysSeq[ 0 ];
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+
+ // 3d mode
+ bool b3dChart = xCoordSystem.is() && (xCoordSystem->getDimension() == 3);
+
+ // percent charts
+ namespace ApiAxisType = ::com::sun::star::chart2::AxisType;
+ Reference< XAxis > xApiYAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_Y, nApiAxesSetIdx );
+ bool bPercent = xApiYAxis.is() && (xApiYAxis->getScaleData().AxisType == ApiAxisType::PERCENT);
+
+ // connector lines in bar charts
+ ScfPropertySet aDiaProp( xDiagram );
+ bool bConnectBars = aDiaProp.GetBoolProperty( EXC_CHPROP_CONNECTBARS );
+
+ // swapped axes sets
+ ScfPropertySet aCoordSysProp( xCoordSystem );
+ bool bSwappedAxesSet = aCoordSysProp.GetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS );
+
+ // X axis for later use
+ Reference< XAxis > xApiXAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_X, nApiAxesSetIdx );
+ // X axis labels
+ ScfPropertySet aXAxisProp( xApiXAxis );
+ bool bHasXLabels = aXAxisProp.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS );
+
+ // process chart types
+ Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
+ if( xChartTypeCont.is() )
+ {
+ Sequence< Reference< XChartType > > aChartTypeSeq = xChartTypeCont->getChartTypes();
+ const Reference< XChartType >* pBeg = aChartTypeSeq.getConstArray();
+ const Reference< XChartType >* pEnd = pBeg + aChartTypeSeq.getLength();
+ for( const Reference< XChartType >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ XclExpChTypeGroupRef xTypeGroup( new XclExpChTypeGroup( GetChRoot(), nGroupIdx ) );
+ xTypeGroup->ConvertType( xDiagram, *pIt, nApiAxesSetIdx, b3dChart, bSwappedAxesSet, bHasXLabels );
+ /* If new chart type group cannot be inserted into a combination
+ chart with existing type groups, insert all series into last
+ contained chart type group instead of creating a new group. */
+ XclExpChTypeGroupRef xLastGroup = GetLastTypeGroup();
+ if( xLastGroup.is() && !(xTypeGroup->IsCombinable2d() && xLastGroup->IsCombinable2d()) )
+ {
+ xLastGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
+ }
+ else
+ {
+ xTypeGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
+ if( xTypeGroup->IsValidGroup() )
+ {
+ maTypeGroups.AppendRecord( xTypeGroup );
+ ++nGroupIdx;
+ }
+ }
+ }
+ }
+
+ if( XclExpChTypeGroup* pGroup = GetFirstTypeGroup().get() )
+ {
+ const XclChExtTypeInfo& rTypeInfo = pGroup->GetTypeInfo();
+
+ // create axes according to chart type (no axes for pie and donut charts)
+ if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
+ {
+ ConvertAxis( mxXAxis, EXC_CHAXIS_X, mxXAxisTitle, EXC_CHOBJLINK_XAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_Y );
+ ConvertAxis( mxYAxis, EXC_CHAXIS_Y, mxYAxisTitle, EXC_CHOBJLINK_YAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_X );
+ if( pGroup->Is3dDeepChart() )
+ ConvertAxis( mxZAxis, EXC_CHAXIS_Z, mxZAxisTitle, EXC_CHOBJLINK_ZAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_NONE );
+ }
+
+ // X axis category ranges
+ if( rTypeInfo.mbCategoryAxis && xApiXAxis.is() )
+ {
+ const ScaleData aScaleData = xApiXAxis->getScaleData();
+ for( size_t nIdx = 0, nSize = maTypeGroups.GetSize(); nIdx < nSize; ++nIdx )
+ maTypeGroups.GetRecord( nIdx )->ConvertCategSequence( aScaleData.Categories );
+ }
+
+ // legend
+ if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
+ {
+ Reference< XLegend > xLegend = xDiagram->getLegend();
+ if( xLegend.is() )
+ {
+ ScfPropertySet aLegendProp( xLegend );
+ pGroup->ConvertLegend( aLegendProp );
+ }
+ }
+ }
+ }
+ }
+
+ // wall/floor/diagram frame formatting
+ if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
+ {
+ XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ if( xTypeGroup.is() && xTypeGroup->Is3dWallChart() )
+ {
+ // wall/floor formatting (3D charts)
+ if( mxXAxis.is() )
+ mxXAxis->ConvertWall( xDiagram );
+ if( mxYAxis.is() )
+ mxYAxis->ConvertWall( xDiagram );
+ }
+ else
+ {
+ // diagram background formatting
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxPlotFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_PLOTFRAME );
+ }
+ }
+
+ // inner and outer plot area position and size
+ try
+ {
+ Reference< ::com::sun::star::chart::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
+ Reference< ::com::sun::star::chart::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
+ // set manual flag in chart data
+ if( !xPositioning->isAutomaticDiagramPositioning() )
+ GetChartData().SetManualPlotArea();
+ // the CHAXESSET record contains the inner plot area
+ maData.maRect = CalcChartRectFromHmm( xPositioning->calculateDiagramPositionExcludingAxes() );
+ // the embedded CHFRAMEPOS record contains the outer plot area
+ mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
+ // for pie charts, always use inner plot area size to exclude the data labels as Excel does
+ const XclExpChTypeGroup* pFirstTypeGroup = GetFirstTypeGroup().get();
+ bool bPieChart = pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE);
+ mxFramePos->GetFramePosData().maRect = bPieChart ? maData.maRect :
+ CalcChartRectFromHmm( xPositioning->calculateDiagramPositionIncludingAxes() );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // return first unused chart type group index for next axes set
+ return nGroupIdx;
+}
+
+bool XclExpChAxesSet::Is3dChart() const
+{
+ XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ return xTypeGroup.is() && xTypeGroup->Is3dChart();
+}
+
+void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxFramePos );
+ lclSaveRecord( rStrm, mxXAxis );
+ lclSaveRecord( rStrm, mxYAxis );
+ lclSaveRecord( rStrm, mxZAxis );
+ lclSaveRecord( rStrm, mxXAxisTitle );
+ lclSaveRecord( rStrm, mxYAxisTitle );
+ lclSaveRecord( rStrm, mxZAxisTitle );
+ if( mxPlotFrame.is() )
+ {
+ XclExpEmptyRecord( EXC_ID_CHPLOTFRAME ).Save( rStrm );
+ mxPlotFrame->Save( rStrm );
+ }
+ maTypeGroups.Save( rStrm );
+}
+
+XclExpChTypeGroupRef XclExpChAxesSet::GetFirstTypeGroup() const
+{
+ return maTypeGroups.GetFirstRecord();
+}
+
+XclExpChTypeGroupRef XclExpChAxesSet::GetLastTypeGroup() const
+{
+ return maTypeGroups.GetLastRecord();
+}
+
+void XclExpChAxesSet::ConvertAxis(
+ XclExpChAxisRef& rxChAxis, sal_uInt16 nAxisType,
+ XclExpChTextRef& rxChAxisTitle, sal_uInt16 nTitleTarget,
+ Reference< XCoordinateSystem > xCoordSystem, const XclChExtTypeInfo& rTypeInfo,
+ sal_Int32 nCrossingAxisDim )
+{
+ // create and convert axis object
+ rxChAxis.reset( new XclExpChAxis( GetChRoot(), nAxisType ) );
+ sal_Int32 nApiAxisDim = rxChAxis->GetApiAxisDimension();
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+ Reference< XAxis > xAxis = lclGetApiAxis( xCoordSystem, nApiAxisDim, nApiAxesSetIdx );
+ Reference< XAxis > xCrossingAxis = lclGetApiAxis( xCoordSystem, nCrossingAxisDim, nApiAxesSetIdx );
+ rxChAxis->Convert( xAxis, xCrossingAxis, rTypeInfo );
+
+ // create and convert axis title
+ Reference< XTitled > xTitled( xAxis, UNO_QUERY );
+ rxChAxisTitle = lclCreateTitle( GetChRoot(), xTitled, nTitleTarget );
+}
+
+void XclExpChAxesSet::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnAxesSetId << maData.maRect;
+}
+
+// The chart object ===========================================================
+
+XclExpChChart::XclExpChChart( const XclExpRoot& rRoot,
+ Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) :
+ XclExpChGroupBase( XclExpChRoot( rRoot, *this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 )
+{
+ Size aPtSize = OutputDevice::LogicToLogic( rChartRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) );
+ // rectangle is stored in 16.16 fixed-point format
+ maRect.mnX = maRect.mnY = 0;
+ maRect.mnWidth = static_cast< sal_Int32 >( aPtSize.Width() << 16 );
+ maRect.mnHeight = static_cast< sal_Int32 >( aPtSize.Height() << 16 );
+
+ // global chart properties (default values)
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, false );
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANPLOTAREA );
+ maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP;
+
+ // always create both axes set objects
+ mxPrimAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
+ mxSecnAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
+
+ if( xChartDoc.is() )
+ {
+ Reference< XDiagram > xDiagram = xChartDoc->getFirstDiagram();
+
+ // global chart properties (only 'include hidden cells' attribute for now)
+ ScfPropertySet aDiagramProp( xDiagram );
+ bool bIncludeHidden = aDiagramProp.GetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS );
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, !bIncludeHidden );
+
+ // initialize API conversion (remembers xChartDoc and rChartRect internally)
+ InitConversion( xChartDoc, rChartRect );
+
+ // chart frame
+ ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
+ mxFrame = lclCreateFrame( GetChRoot(), aFrameProp, EXC_CHOBJTYPE_BACKGROUND );
+
+ // chart title
+ Reference< XTitled > xTitled( xChartDoc, UNO_QUERY );
+ mxTitle = lclCreateTitle( GetChRoot(), xTitled, EXC_CHOBJLINK_TITLE );
+
+ // diagrams (axes sets)
+ sal_uInt16 nFreeGroupIdx = mxPrimAxesSet->Convert( xDiagram, 0 );
+ if( !mxPrimAxesSet->Is3dChart() )
+ mxSecnAxesSet->Convert( xDiagram, nFreeGroupIdx );
+
+ // treatment of missing values
+ ScfPropertySet aDiaProp( xDiagram );
+ sal_Int32 nMissingValues = 0;
+ if( aDiaProp.GetProperty( nMissingValues, EXC_CHPROP_MISSINGVALUETREATMENT ) )
+ {
+ using namespace ::com::sun::star::chart::MissingValueTreatment;
+ switch( nMissingValues )
+ {
+ case LEAVE_GAP: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP; break;
+ case USE_ZERO: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_ZERO; break;
+ case CONTINUE: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_INTERPOLATE; break;
+ }
+ }
+
+ // finish API conversion
+ FinishConversion();
+ }
+}
+
+XclExpChSeriesRef XclExpChChart::CreateSeries()
+{
+ XclExpChSeriesRef xSeries;
+ sal_uInt16 nSeriesIdx = static_cast< sal_uInt16 >( maSeries.GetSize() );
+ if( nSeriesIdx <= EXC_CHSERIES_MAXSERIES )
+ {
+ xSeries.reset( new XclExpChSeries( GetChRoot(), nSeriesIdx ) );
+ maSeries.AppendRecord( xSeries );
+ }
+ return xSeries;
+}
+
+void XclExpChChart::RemoveLastSeries()
+{
+ if( !maSeries.IsEmpty() )
+ maSeries.RemoveRecord( maSeries.GetSize() - 1 );
+}
+
+void XclExpChChart::SetDataLabel( XclExpChTextRef xText )
+{
+ if( xText.is() )
+ maLabels.AppendRecord( xText );
+}
+
+void XclExpChChart::SetManualPlotArea()
+{
+ // this flag does not exist in BIFF5
+ if( GetBiff() == EXC_BIFF8 )
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
+}
+
+void XclExpChChart::WriteSubRecords( XclExpStream& rStrm )
+{
+ // background format
+ lclSaveRecord( rStrm, mxFrame );
+
+ // data series
+ maSeries.Save( rStrm );
+
+ // CHPROPERTIES record
+ rStrm.StartRecord( EXC_ID_CHPROPERTIES, 4 );
+ rStrm << maProps.mnFlags << maProps.mnEmptyMode << sal_uInt8( 0 );
+ rStrm.EndRecord();
+
+ // axes sets (always save primary axes set)
+ sal_uInt16 nUsedAxesSets = mxSecnAxesSet->IsValidAxesSet() ? 2 : 1;
+ XclExpUInt16Record( EXC_ID_CHUSEDAXESSETS, nUsedAxesSets ).Save( rStrm );
+ mxPrimAxesSet->Save( rStrm );
+ if( mxSecnAxesSet->IsValidAxesSet() )
+ mxSecnAxesSet->Save( rStrm );
+
+ // chart title and data labels
+ lclSaveRecord( rStrm, mxTitle );
+ maLabels.Save( rStrm );
+}
+
+void XclExpChChart::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maRect;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot,
+ const Reference< XModel >& rxModel, const Size& rChartSize ) :
+ XclExpRoot( rRoot )
+{
+ if( (rChartSize.Width() > 0) && (rChartSize.Height() > 0) )
+ {
+ ScfPropertySet aPropSet( rxModel );
+ Reference< XShapes > xShapes;
+ if( aPropSet.GetProperty( xShapes, EXC_CHPROP_ADDITIONALSHAPES ) && xShapes.is() && (xShapes->getCount() > 0) )
+ {
+ /* Create a new independent object manager with own DFF stream for the
+ DGCONTAINER, pass global manager as parent for shared usage of
+ global DFF data (picture container etc.). */
+ mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_TOTALUNITS, EXC_CHART_TOTALUNITS ) );
+ // initialize the drawing object list
+ mxObjMgr->StartSheet();
+ // process the draw page (convert all shapes)
+ mxObjRecs = mxObjMgr->ProcessDrawing( xShapes );
+ // finalize the DFF stream
+ mxObjMgr->EndDocument();
+ }
+ }
+}
+
+XclExpChartDrawing::~XclExpChartDrawing()
+{
+}
+
+void XclExpChartDrawing::Save( XclExpStream& rStrm )
+{
+ if( mxObjRecs.is() )
+ mxObjRecs->Save( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Rectangle& rChartRect ) :
+ XclExpSubStream( EXC_BOF_CHART ),
+ XclExpRoot( rRoot )
+{
+ AppendNewRecord( new XclExpChartPageSettings( rRoot ) );
+ AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) );
+ AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rChartRect.GetSize() ) );
+ AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) );
+
+ Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
+ AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rChartRect ) );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xecontent.cxx b/sc/source/filter/excel/xecontent.cxx
new file mode 100644
index 000000000000..7bfd57be7290
--- /dev/null
+++ b/sc/source/filter/excel/xecontent.cxx
@@ -0,0 +1,1462 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xecontent.hxx"
+
+#include <list>
+#include <algorithm>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XAreaLinks.hpp>
+#include <com/sun/star/sheet/XAreaLink.hpp>
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/itemset.hxx>
+#include <formula/grammar.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include "document.hxx"
+#include "validat.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "rangenam.hxx"
+#include "tokenarray.hxx"
+#include "stlpool.hxx"
+#include "patattr.hxx"
+#include "fapihelper.hxx"
+#include "xehelper.hxx"
+#include "xestyle.hxx"
+#include "xename.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::XAreaLinks;
+using ::com::sun::star::sheet::XAreaLink;
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// Shared string table ========================================================
+
+// 1 = SST hash table statistics prompt
+#define EXC_INCL_SST_STATISTICS 0
+
+// ----------------------------------------------------------------------------
+
+/** A single string entry in the hash table. */
+struct XclExpHashEntry
+{
+ const XclExpString* mpString; /// Pointer to the string (no ownership).
+ sal_uInt32 mnSstIndex; /// The SST index of this string.
+ inline explicit XclExpHashEntry( const XclExpString* pString = 0, sal_uInt32 nSstIndex = 0 ) :
+ mpString( pString ), mnSstIndex( nSstIndex ) {}
+};
+
+/** Function object for strict weak ordering. */
+struct XclExpHashEntrySWO
+{
+ inline bool operator()( const XclExpHashEntry& rLeft, const XclExpHashEntry& rRight ) const
+ { return *rLeft.mpString < *rRight.mpString; }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the SST export.
+ @descr Stores all passed strings in a hash table and prevents repeated
+ insertion of equal strings. */
+class XclExpSstImpl
+{
+public:
+ explicit XclExpSstImpl();
+
+ /** Inserts the passed string, if not already inserted, and returns the unique SST index. */
+ sal_uInt32 Insert( XclExpStringRef xString );
+
+ /** Writes the complete SST and EXTSST records. */
+ void Save( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef ::std::list< XclExpStringRef > XclExpStringList;
+ typedef ::std::vector< XclExpHashEntry > XclExpHashVec;
+ typedef ::std::vector< XclExpHashVec > XclExpHashTab;
+
+ XclExpStringList maStringList; /// List of unique strings (in SST ID order).
+ XclExpHashTab maHashTab; /// Hashed table that manages string pointers.
+ sal_uInt32 mnTotal; /// Total count of strings (including doubles).
+ sal_uInt32 mnSize; /// Size of the SST (count of unique strings).
+};
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt32 EXC_SST_HASHTABLE_SIZE = 2048;
+
+XclExpSstImpl::XclExpSstImpl() :
+ maHashTab( EXC_SST_HASHTABLE_SIZE ),
+ mnTotal( 0 ),
+ mnSize( 0 )
+{
+}
+
+sal_uInt32 XclExpSstImpl::Insert( XclExpStringRef xString )
+{
+ DBG_ASSERT( xString.get(), "XclExpSstImpl::Insert - empty pointer not allowed" );
+ if( !xString.get() )
+ xString.reset( new XclExpString );
+
+ ++mnTotal;
+ sal_uInt32 nSstIndex = 0;
+
+ // calculate hash value in range [0,EXC_SST_HASHTABLE_SIZE)
+ sal_uInt16 nHash = xString->GetHash();
+ (nHash ^= (nHash / EXC_SST_HASHTABLE_SIZE)) %= EXC_SST_HASHTABLE_SIZE;
+
+ XclExpHashVec& rVec = maHashTab[ nHash ];
+ XclExpHashEntry aEntry( xString.get(), mnSize );
+ XclExpHashVec::iterator aIt = ::std::lower_bound( rVec.begin(), rVec.end(), aEntry, XclExpHashEntrySWO() );
+ if( (aIt == rVec.end()) || (*aIt->mpString != *xString) )
+ {
+ nSstIndex = mnSize;
+ maStringList.push_back( xString );
+ rVec.insert( aIt, aEntry );
+ ++mnSize;
+ }
+ else
+ {
+ nSstIndex = aIt->mnSstIndex;
+ }
+
+ return nSstIndex;
+}
+
+void XclExpSstImpl::Save( XclExpStream& rStrm )
+{
+ if( maStringList.empty() )
+ return;
+
+#if (OSL_DEBUG_LEVEL > 1) && EXC_INCL_SST_STATISTICS
+ { // own scope for the statistics
+#define APPENDINT( value ) Append( ByteString::CreateFromInt32( value ) )
+ ScfUInt32Vec aVec;
+ size_t nPerBucket = mnSize / EXC_SST_HASHTABLE_SIZE + 1, nEff = 0;
+ for( XclExpHashTab::const_iterator aTIt = maHashTab.begin(), aTEnd = maHashTab.end(); aTIt != aTEnd; ++aTIt )
+ {
+ size_t nSize = aTIt->size();
+ if( nSize >= aVec.size() ) aVec.resize( nSize + 1, 0 );
+ ++aVec[ nSize ];
+ if( nSize > nPerBucket ) nEff += nSize - nPerBucket;
+ }
+ ByteString aStr( "SST HASHING STATISTICS\n\n" );
+ aStr.Append( "Total count:\t" ).APPENDINT( mnTotal ).Append( " strings\n" );
+ aStr.Append( "Reduced to:\t" ).APPENDINT( mnSize ).Append( " strings (" );
+ aStr.APPENDINT( 100 * mnSize / mnTotal ).Append( "%)\n" );
+ aStr.Append( "Effectivity:\t\t" ).APPENDINT( 100 - 100 * nEff / mnSize );
+ aStr.Append( "% (best: " ).APPENDINT( nPerBucket ).Append( " strings per bucket)\n" );
+ aStr.Append( "\t\tCount of buckets\nBucket size\ttotal\tmax\tTotal strings\n" );
+ for( size_t nIx = 0, nSize = aVec.size(), nInc = 1; nIx < nSize; nIx += nInc )
+ {
+ if( (nIx == 10) || (nIx == 100) || (nIx == 1000) ) nInc = nIx;
+ size_t nMaxIx = ::std::min( nIx + nInc, nSize ), nCount = 0, nMaxCount = 0, nStrings = 0;
+ for( size_t nSubIx = nIx; nSubIx < nMaxIx; ++nSubIx )
+ {
+ nCount += aVec[ nSubIx ];
+ if( aVec[ nSubIx ] > nMaxCount ) nMaxCount = aVec[ nSubIx ];
+ nStrings += nSubIx * aVec[ nSubIx ];
+ }
+ if( nMaxCount )
+ {
+ aStr.APPENDINT( nIx );
+ if( nMaxIx - nIx > 1 ) aStr.Append( '-' ).APPENDINT( nMaxIx - 1 );
+ aStr.Append( "\t\t" ).APPENDINT( nCount ).Append( '\t' ).APPENDINT( nMaxCount );
+ aStr.Append( '\t' ).APPENDINT( nStrings ).Append( '\n' );
+ }
+ }
+ DBG_ERRORFILE( aStr.GetBuffer() );
+#undef APPENDINT
+ }
+#endif
+
+ SvMemoryStream aExtSst( 8192 );
+
+ sal_uInt32 nBucket = mnSize;
+ while( nBucket > 0x0100 )
+ nBucket /= 2;
+
+ sal_uInt16 nPerBucket = llimit_cast< sal_uInt16 >( nBucket, 8 );
+ sal_uInt16 nBucketIndex = 0;
+
+ // *** write the SST record ***
+
+ rStrm.StartRecord( EXC_ID_SST, 8 );
+
+ rStrm << mnTotal << mnSize;
+ for( XclExpStringList::const_iterator aIt = maStringList.begin(), aEnd = maStringList.end(); aIt != aEnd; ++aIt )
+ {
+ if( !nBucketIndex )
+ {
+ // write bucket info before string to get correct record position
+ sal_uInt32 nStrmPos = static_cast< sal_uInt32 >( rStrm.GetSvStreamPos() );
+ sal_uInt16 nRecPos = rStrm.GetRawRecPos() + 4;
+ aExtSst << nStrmPos // stream position
+ << nRecPos // position from start of SST or CONTINUE
+ << sal_uInt16( 0 ); // reserved
+ }
+
+ rStrm << **aIt;
+
+ if( ++nBucketIndex == nPerBucket )
+ nBucketIndex = 0;
+ }
+
+ rStrm.EndRecord();
+
+ // *** write the EXTSST record ***
+
+ rStrm.StartRecord( EXC_ID_EXTSST, 0 );
+
+ rStrm << nPerBucket;
+ rStrm.SetSliceSize( 8 ); // size of one bucket info
+ aExtSst.Seek( STREAM_SEEK_TO_BEGIN );
+ rStrm.CopyFromStream( aExtSst );
+
+ rStrm.EndRecord();
+}
+
+void XclExpSstImpl::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maStringList.empty() )
+ return;
+
+ sax_fastparser::FSHelperPtr pSst = rStrm.CreateOutputStream(
+ OUString::createFromAscii( "xl/sharedStrings.xml" ),
+ OUString::createFromAscii( "sharedStrings.xml" ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" );
+ rStrm.PushStream( pSst );
+
+ pSst->startElement( XML_sst,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ XML_count, OString::valueOf( (sal_Int32) mnTotal ).getStr(),
+ XML_uniqueCount, OString::valueOf( (sal_Int32) mnSize ).getStr(),
+ FSEND );
+
+ for( XclExpStringList::const_iterator aIt = maStringList.begin(), aEnd = maStringList.end(); aIt != aEnd; ++aIt )
+ {
+ pSst->startElement( XML_si, FSEND );
+ (*aIt)->WriteXml( rStrm );
+ pSst->endElement( XML_si );
+ }
+
+ pSst->endElement( XML_sst );
+
+ rStrm.PopStream();
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpSst::XclExpSst() :
+ mxImpl( new XclExpSstImpl )
+{
+}
+
+XclExpSst::~XclExpSst()
+{
+}
+
+sal_uInt32 XclExpSst::Insert( XclExpStringRef xString )
+{
+ return mxImpl->Insert( xString );
+}
+
+void XclExpSst::Save( XclExpStream& rStrm )
+{
+ mxImpl->Save( rStrm );
+}
+
+void XclExpSst::SaveXml( XclExpXmlStream& rStrm )
+{
+ mxImpl->SaveXml( rStrm );
+}
+
+// Merged cells ===============================================================
+
+XclExpMergedcells::XclExpMergedcells( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpMergedcells::AppendRange( const ScRange& rRange, sal_uInt32 nBaseXFId )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ maMergedRanges.Append( rRange );
+ maBaseXFIds.push_back( nBaseXFId );
+ }
+}
+
+sal_uInt32 XclExpMergedcells::GetBaseXFId( const ScAddress& rPos ) const
+{
+ DBG_ASSERT( maBaseXFIds.size() == maMergedRanges.Count(), "XclExpMergedcells::GetBaseXFId - invalid lists" );
+ ScfUInt32Vec::const_iterator aIt = maBaseXFIds.begin();
+ ScRangeList& rNCRanges = const_cast< ScRangeList& >( maMergedRanges );
+ for( const ScRange* pScRange = rNCRanges.First(); pScRange; pScRange = rNCRanges.Next(), ++aIt )
+ if( pScRange->In( rPos ) )
+ return *aIt;
+ return EXC_XFID_NOTFOUND;
+}
+
+void XclExpMergedcells::Save( XclExpStream& rStrm )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ XclRangeList aXclRanges;
+ GetAddressConverter().ConvertRangeList( aXclRanges, maMergedRanges, true );
+ size_t nFirstRange = 0;
+ size_t nRemainingRanges = aXclRanges.size();
+ while( nRemainingRanges > 0 )
+ {
+ size_t nRangeCount = ::std::min< size_t >( nRemainingRanges, EXC_MERGEDCELLS_MAXCOUNT );
+ rStrm.StartRecord( EXC_ID_MERGEDCELLS, 2 + 8 * nRangeCount );
+ aXclRanges.WriteSubList( rStrm, nFirstRange, nRangeCount );
+ rStrm.EndRecord();
+ nFirstRange += nRangeCount;
+ nRemainingRanges -= nRangeCount;
+ }
+ }
+}
+
+void XclExpMergedcells::SaveXml( XclExpXmlStream& rStrm )
+{
+ ULONG nCount = maMergedRanges.Count();
+ if( !nCount )
+ return;
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_mergeCells,
+ XML_count, OString::valueOf( (sal_Int32) nCount ).getStr(),
+ FSEND );
+ for( ULONG i = 0; i < nCount; ++i )
+ {
+ if( const ScRange* pRange = maMergedRanges.GetObject( i ) )
+ {
+ rWorksheet->singleElement( XML_mergeCell,
+ XML_ref, XclXmlUtils::ToOString( *pRange ).getStr(),
+ FSEND );
+ }
+ }
+ rWorksheet->endElement( XML_mergeCells );
+}
+
+// Hyperlinks =================================================================
+
+XclExpHyperlink::XclExpHyperlink( const XclExpRoot& rRoot, const SvxURLField& rUrlField, const ScAddress& rScPos ) :
+ XclExpRecord( EXC_ID_HLINK ),
+ maScPos( rScPos ),
+ mxVarData( new SvMemoryStream ),
+ mnFlags( 0 )
+{
+ const String& rUrl = rUrlField.GetURL();
+ const String& rRepr = rUrlField.GetRepresentation();
+ INetURLObject aUrlObj( rUrl );
+ const INetProtocol eProtocol = aUrlObj.GetProtocol();
+ bool bWithRepr = rRepr.Len() > 0;
+ XclExpStream aXclStrm( *mxVarData, rRoot ); // using in raw write mode.
+
+ // description
+ if( bWithRepr )
+ {
+ XclExpString aDescr( rRepr, EXC_STR_FORCEUNICODE, 255 );
+ aXclStrm << sal_uInt32( aDescr.Len() + 1 ); // string length + 1 trailing zero word
+ aDescr.WriteBuffer( aXclStrm ); // NO flags
+ aXclStrm << sal_uInt16( 0 );
+
+ mnFlags |= EXC_HLINK_DESCR;
+ mxRepr.reset( new String( rRepr ) );
+ }
+
+ // file link or URL
+ if( eProtocol == INET_PROT_FILE )
+ {
+ sal_uInt16 nLevel;
+ bool bRel;
+ String aFileName( BuildFileName( nLevel, bRel, rUrl, rRoot ) );
+
+ if( !bRel )
+ mnFlags |= EXC_HLINK_ABS;
+ mnFlags |= EXC_HLINK_BODY;
+
+ ByteString aAsciiLink( aFileName, rRoot.GetTextEncoding() );
+ XclExpString aLink( aFileName, EXC_STR_FORCEUNICODE, 255 );
+ aXclStrm << XclTools::maGuidFileMoniker
+ << nLevel
+ << sal_uInt32( aAsciiLink.Len() + 1 ); // string length + 1 trailing zero byte
+ aXclStrm.Write( aAsciiLink.GetBuffer(), aAsciiLink.Len() );
+ aXclStrm << sal_uInt8( 0 )
+ << sal_uInt32( 0xDEADFFFF );
+ aXclStrm.WriteZeroBytes( 20 );
+ aXclStrm << sal_uInt32( aLink.GetBufferSize() + 6 )
+ << sal_uInt32( aLink.GetBufferSize() ) // byte count, not string length
+ << sal_uInt16( 0x0003 );
+ aLink.WriteBuffer( aXclStrm ); // NO flags
+
+ if( !mxRepr.get() )
+ mxRepr.reset( new String( aFileName ) );
+
+ msTarget = XclXmlUtils::ToOUString( aLink );
+ }
+ else if( eProtocol != INET_PROT_NOT_VALID )
+ {
+ XclExpString aUrl( aUrlObj.GetURLNoMark(), EXC_STR_FORCEUNICODE, 255 );
+ aXclStrm << XclTools::maGuidUrlMoniker
+ << sal_uInt32( aUrl.GetBufferSize() + 2 ); // byte count + 1 trailing zero word
+ aUrl.WriteBuffer( aXclStrm ); // NO flags
+ aXclStrm << sal_uInt16( 0 );
+
+ mnFlags |= EXC_HLINK_BODY | EXC_HLINK_ABS;
+ if( !mxRepr.get() )
+ mxRepr.reset( new String( rUrl ) );
+
+ msTarget = XclXmlUtils::ToOUString( aUrl );
+ }
+ else if( rUrl.GetChar( 0 ) == '#' ) // hack for #89066#
+ {
+ String aTextMark( rUrl.Copy( 1 ) );
+ aTextMark.SearchAndReplace( '.', '!' );
+ mxTextMark.reset( new XclExpString( aTextMark, EXC_STR_FORCEUNICODE, 255 ) );
+ }
+
+ // text mark
+ if( !mxTextMark.get() && aUrlObj.HasMark() )
+ mxTextMark.reset( new XclExpString( aUrlObj.GetMark(), EXC_STR_FORCEUNICODE, 255 ) );
+
+ if( mxTextMark.get() )
+ {
+ aXclStrm << sal_uInt32( mxTextMark->Len() + 1 ); // string length + 1 trailing zero word
+ mxTextMark->WriteBuffer( aXclStrm ); // NO flags
+ aXclStrm << sal_uInt16( 0 );
+
+ mnFlags |= EXC_HLINK_MARK;
+ }
+
+ SetRecSize( 32 + mxVarData->Tell() );
+}
+
+XclExpHyperlink::~XclExpHyperlink()
+{
+}
+
+String XclExpHyperlink::BuildFileName(
+ sal_uInt16& rnLevel, bool& rbRel, const String& rUrl, const XclExpRoot& rRoot ) const
+{
+ String aDosName( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ rnLevel = 0;
+ rbRel = rRoot.IsRelUrl();
+
+ if( rbRel )
+ {
+ // try to convert to relative file name
+ String aTmpName( aDosName );
+ aDosName = INetURLObject::GetRelURL( rRoot.GetBasePath(), rUrl,
+ INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET );
+
+ if( aDosName.SearchAscii( INET_FILE_SCHEME ) == 0 )
+ {
+ // not converted to rel -> back to old, return absolute flag
+ aDosName = aTmpName;
+ rbRel = false;
+ }
+ else if( aDosName.SearchAscii( "./" ) == 0 )
+ {
+ aDosName.Erase( 0, 2 );
+ }
+ else
+ {
+ while( aDosName.SearchAndReplaceAscii( "../", EMPTY_STRING ) == 0 )
+ ++rnLevel;
+ }
+ }
+ return aDosName;
+}
+
+void XclExpHyperlink::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nXclCol = static_cast< sal_uInt16 >( maScPos.Col() );
+ sal_uInt16 nXclRow = static_cast< sal_uInt16 >( maScPos.Row() );
+ mxVarData->Seek( STREAM_SEEK_TO_BEGIN );
+
+ rStrm << nXclRow << nXclRow << nXclCol << nXclCol
+ << XclTools::maGuidStdLink
+ << sal_uInt32( 2 )
+ << mnFlags;
+ rStrm.CopyFromStream( *mxVarData );
+}
+
+void XclExpHyperlink::SaveXml( XclExpXmlStream& rStrm )
+{
+ OUString sId = rStrm.addRelation( rStrm.GetCurrentStream()->getOutputStream(),
+ XclXmlUtils::ToOUString( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ),
+ msTarget,
+ XclXmlUtils::ToOUString( "External" ) );
+ rStrm.GetCurrentStream()->singleElement( XML_hyperlink,
+ XML_ref, XclXmlUtils::ToOString( maScPos ).getStr(),
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ XML_location, mxTextMark.get() != NULL
+ ? XclXmlUtils::ToOString( *mxTextMark ).getStr()
+ : NULL,
+ // OOXTODO: XML_tooltip, from record HLinkTooltip 800h wzTooltip
+ XML_display, XclXmlUtils::ToOString( *mxRepr ).getStr(),
+ FSEND );
+}
+
+// Label ranges ===============================================================
+
+XclExpLabelranges::XclExpLabelranges( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ SCTAB nScTab = GetCurrScTab();
+ // row label ranges
+ FillRangeList( maRowRanges, rRoot.GetDoc().GetRowNameRangesRef(), nScTab );
+ // row labels only over 1 column (restriction of Excel97/2000/XP)
+ for( ScRange* pScRange = maRowRanges.First(); pScRange; pScRange = maRowRanges.Next() )
+ if( pScRange->aStart.Col() != pScRange->aEnd.Col() )
+ pScRange->aEnd.SetCol( pScRange->aStart.Col() );
+ // col label ranges
+ FillRangeList( maColRanges, rRoot.GetDoc().GetColNameRangesRef(), nScTab );
+}
+
+void XclExpLabelranges::FillRangeList( ScRangeList& rScRanges,
+ ScRangePairListRef xLabelRangesRef, SCTAB nScTab )
+{
+ for( const ScRangePair* pRangePair = xLabelRangesRef->First(); pRangePair; pRangePair = xLabelRangesRef->Next() )
+ {
+ const ScRange& rScRange = pRangePair->GetRange( 0 );
+ if( rScRange.aStart.Tab() == nScTab )
+ rScRanges.Append( rScRange );
+ }
+}
+
+void XclExpLabelranges::Save( XclExpStream& rStrm )
+{
+ XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ XclRangeList aRowXclRanges, aColXclRanges;
+ rAddrConv.ConvertRangeList( aRowXclRanges, maRowRanges, false );
+ rAddrConv.ConvertRangeList( aColXclRanges, maColRanges, false );
+ if( !aRowXclRanges.empty() || !aColXclRanges.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_LABELRANGES, 4 + 8 * (aRowXclRanges.size() + aColXclRanges.size()) );
+ rStrm << aRowXclRanges << aColXclRanges;
+ rStrm.EndRecord();
+ }
+}
+
+// Conditional formatting ====================================================
+
+/** Represents a CF record that contains one condition of a conditional format. */
+class XclExpCFImpl : protected XclExpRoot
+{
+public:
+ explicit XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry );
+
+ /** Writes the body of the CF record. */
+ void WriteBody( XclExpStream& rStrm );
+
+private:
+ const ScCondFormatEntry& mrFormatEntry; /// Calc conditional format entry.
+ XclFontData maFontData; /// Font formatting attributes.
+ XclExpCellBorder maBorder; /// Border formatting attributes.
+ XclExpCellArea maArea; /// Pattern formatting attributes.
+ XclTokenArrayRef mxTokArr1; /// Formula for first condition.
+ XclTokenArrayRef mxTokArr2; /// Formula for second condition.
+ sal_uInt32 mnFontColorId; /// Font color ID.
+ sal_uInt8 mnType; /// Type of the condition (cell/formula).
+ sal_uInt8 mnOperator; /// Comparison operator for cell type.
+ bool mbFontUsed; /// true = Any font attribute used.
+ bool mbHeightUsed; /// true = Font height used.
+ bool mbWeightUsed; /// true = Font weight used.
+ bool mbColorUsed; /// true = Font color used.
+ bool mbUnderlUsed; /// true = Font underline type used.
+ bool mbItalicUsed; /// true = Font posture used.
+ bool mbStrikeUsed; /// true = Font strikeout used.
+ bool mbBorderUsed; /// true = Border attribute used.
+ bool mbPattUsed; /// true = Pattern attribute used.
+};
+
+// ----------------------------------------------------------------------------
+
+XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry ) :
+ XclExpRoot( rRoot ),
+ mrFormatEntry( rFormatEntry ),
+ mnFontColorId( 0 ),
+ mnType( EXC_CF_TYPE_CELL ),
+ mnOperator( EXC_CF_CMP_NONE ),
+ mbFontUsed( false ),
+ mbHeightUsed( false ),
+ mbWeightUsed( false ),
+ mbColorUsed( false ),
+ mbUnderlUsed( false ),
+ mbItalicUsed( false ),
+ mbStrikeUsed( false ),
+ mbBorderUsed( false ),
+ mbPattUsed( false )
+{
+ /* Get formatting attributes here, and not in WriteBody(). This is needed to
+ correctly insert all colors into the palette. */
+
+ if( SfxStyleSheetBase* pStyleSheet = GetDoc().GetStyleSheetPool()->Find( mrFormatEntry.GetStyle(), SFX_STYLE_FAMILY_PARA ) )
+ {
+ const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
+
+ // font
+ mbHeightUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_HEIGHT, true );
+ mbWeightUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_WEIGHT, true );
+ mbColorUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_COLOR, true );
+ mbUnderlUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_UNDERLINE, true );
+ mbItalicUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_POSTURE, true );
+ mbStrikeUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_CROSSEDOUT, true );
+ mbFontUsed = mbHeightUsed || mbWeightUsed || mbColorUsed || mbUnderlUsed || mbItalicUsed || mbStrikeUsed;
+ if( mbFontUsed )
+ {
+ Font aFont;
+ ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW );
+ maFontData.FillFromVclFont( aFont );
+ mnFontColorId = GetPalette().InsertColor( maFontData.maColor, EXC_COLOR_CELLTEXT );
+ }
+
+ // border
+ mbBorderUsed = ScfTools::CheckItem( rItemSet, ATTR_BORDER, true );
+ if( mbBorderUsed )
+ maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff() );
+
+ // pattern
+ mbPattUsed = ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, true );
+ if( mbPattUsed )
+ maArea.FillFromItemSet( rItemSet, GetPalette(), GetBiff() );
+ }
+
+ // *** mode and comparison operator ***
+
+ bool bFmla2 = false;
+ switch( rFormatEntry.GetOperation() )
+ {
+ case SC_COND_NONE: mnType = EXC_CF_TYPE_NONE; break;
+ case SC_COND_BETWEEN: mnOperator = EXC_CF_CMP_BETWEEN; bFmla2 = true; break;
+ case SC_COND_NOTBETWEEN: mnOperator = EXC_CF_CMP_NOT_BETWEEN; bFmla2 = true; break;
+ case SC_COND_EQUAL: mnOperator = EXC_CF_CMP_EQUAL; break;
+ case SC_COND_NOTEQUAL: mnOperator = EXC_CF_CMP_NOT_EQUAL; break;
+ case SC_COND_GREATER: mnOperator = EXC_CF_CMP_GREATER; break;
+ case SC_COND_LESS: mnOperator = EXC_CF_CMP_LESS; break;
+ case SC_COND_EQGREATER: mnOperator = EXC_CF_CMP_GREATER_EQUAL; break;
+ case SC_COND_EQLESS: mnOperator = EXC_CF_CMP_LESS_EQUAL; break;
+ case SC_COND_DIRECT: mnType = EXC_CF_TYPE_FMLA; break;
+ default: mnType = EXC_CF_TYPE_NONE;
+ DBG_ERRORFILE( "XclExpCF::WriteBody - unknown condition type" );
+ }
+
+ // *** formulas ***
+
+ XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
+
+ ::std::auto_ptr< ScTokenArray > xScTokArr( mrFormatEntry.CreateTokenArry( 0 ) );
+ mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_CONDFMT, *xScTokArr );
+
+ if( bFmla2 )
+ {
+ xScTokArr.reset( mrFormatEntry.CreateTokenArry( 1 ) );
+ mxTokArr2 = rFmlaComp.CreateFormula( EXC_FMLATYPE_CONDFMT, *xScTokArr );
+ }
+}
+
+void XclExpCFImpl::WriteBody( XclExpStream& rStrm )
+{
+ // *** mode and comparison operator ***
+
+ rStrm << mnType << mnOperator;
+
+ // *** formula sizes ***
+
+ sal_uInt16 nFmlaSize1 = mxTokArr1.get() ? mxTokArr1->GetSize() : 0;
+ sal_uInt16 nFmlaSize2 = mxTokArr2.get() ? mxTokArr2->GetSize() : 0;
+ rStrm << nFmlaSize1 << nFmlaSize2;
+
+ // *** formatting blocks ***
+
+ if( mbFontUsed || mbBorderUsed || mbPattUsed )
+ {
+ sal_uInt32 nFlags = EXC_CF_ALLDEFAULT;
+
+ ::set_flag( nFlags, EXC_CF_BLOCK_FONT, mbFontUsed );
+ ::set_flag( nFlags, EXC_CF_BLOCK_BORDER, mbBorderUsed );
+ ::set_flag( nFlags, EXC_CF_BLOCK_AREA, mbPattUsed );
+
+ // attributes used -> set flags to 0.
+ ::set_flag( nFlags, EXC_CF_BORDER_ALL, !mbBorderUsed );
+ ::set_flag( nFlags, EXC_CF_AREA_ALL, !mbPattUsed );
+
+ rStrm << nFlags << sal_uInt16( 0 );
+
+ if( mbFontUsed )
+ {
+ // font height, 0xFFFFFFFF indicates unused
+ sal_uInt32 nHeight = mbHeightUsed ? maFontData.mnHeight : 0xFFFFFFFF;
+ // font style: italic and strikeout
+ sal_uInt32 nStyle = 0;
+ ::set_flag( nStyle, EXC_CF_FONT_STYLE, maFontData.mbItalic );
+ ::set_flag( nStyle, EXC_CF_FONT_STRIKEOUT, maFontData.mbStrikeout );
+ // font color, 0xFFFFFFFF indicates unused
+ sal_uInt32 nColor = mbColorUsed ? GetPalette().GetColorIndex( mnFontColorId ) : 0xFFFFFFFF;
+ // font used flags for italic, weight, and strikeout -> 0 = used, 1 = default
+ sal_uInt32 nFontFlags1 = EXC_CF_FONT_ALLDEFAULT;
+ ::set_flag( nFontFlags1, EXC_CF_FONT_STYLE, !(mbItalicUsed || mbWeightUsed) );
+ ::set_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT, !mbStrikeUsed );
+ // font used flag for underline -> 0 = used, 1 = default
+ sal_uInt32 nFontFlags3 = mbUnderlUsed ? 0 : EXC_CF_FONT_UNDERL;
+
+ rStrm.WriteZeroBytesToRecord( 64 );
+ rStrm << nHeight
+ << nStyle
+ << maFontData.mnWeight
+ << EXC_FONTESC_NONE
+ << maFontData.mnUnderline;
+ rStrm.WriteZeroBytesToRecord( 3 );
+ rStrm << nColor
+ << sal_uInt32( 0 )
+ << nFontFlags1
+ << EXC_CF_FONT_ESCAPEM // escapement never used -> set the flag
+ << nFontFlags3;
+ rStrm.WriteZeroBytesToRecord( 16 );
+ rStrm << sal_uInt16( 1 ); // must be 1
+ }
+
+ if( mbBorderUsed )
+ {
+ sal_uInt16 nLineStyle = 0;
+ sal_uInt32 nLineColor = 0;
+ maBorder.SetFinalColors( GetPalette() );
+ maBorder.FillToCF8( nLineStyle, nLineColor );
+ rStrm << nLineStyle << nLineColor << sal_uInt16( 0 );
+ }
+
+ if( mbPattUsed )
+ {
+ sal_uInt16 nPattern = 0, nColor = 0;
+ maArea.SetFinalColors( GetPalette() );
+ maArea.FillToCF8( nPattern, nColor );
+ rStrm << nPattern << nColor;
+ }
+ }
+ else
+ {
+ // no data blocks at all
+ rStrm << sal_uInt32( 0 ) << sal_uInt16( 0 );
+ }
+
+ // *** formulas ***
+
+ if( mxTokArr1.get() )
+ mxTokArr1->WriteArray( rStrm );
+ if( mxTokArr2.get() )
+ mxTokArr2->WriteArray( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCF::XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry ) :
+ XclExpRecord( EXC_ID_CF ),
+ XclExpRoot( rRoot ),
+ mxImpl( new XclExpCFImpl( rRoot, rFormatEntry ) )
+{
+}
+
+XclExpCF::~XclExpCF()
+{
+}
+
+void XclExpCF::WriteBody( XclExpStream& rStrm )
+{
+ mxImpl->WriteBody( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCondfmt::XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat& rCondFormat ) :
+ XclExpRecord( EXC_ID_CONDFMT ),
+ XclExpRoot( rRoot )
+{
+ ScRangeList aScRanges;
+ GetDoc().FindConditionalFormat( rCondFormat.GetKey(), aScRanges, GetCurrScTab() );
+ GetAddressConverter().ConvertRangeList( maXclRanges, aScRanges, true );
+ if( !maXclRanges.empty() )
+ {
+ for( USHORT nIndex = 0, nCount = rCondFormat.Count(); nIndex < nCount; ++nIndex )
+ if( const ScCondFormatEntry* pEntry = rCondFormat.GetEntry( nIndex ) )
+ maCFList.AppendNewRecord( new XclExpCF( GetRoot(), *pEntry ) );
+ aScRanges.Format( msSeqRef, SCA_VALID, NULL, formula::FormulaGrammar::CONV_XL_A1 );
+ }
+}
+
+XclExpCondfmt::~XclExpCondfmt()
+{
+}
+
+bool XclExpCondfmt::IsValid() const
+{
+ return !maCFList.IsEmpty() && !maXclRanges.empty();
+}
+
+void XclExpCondfmt::Save( XclExpStream& rStrm )
+{
+ if( IsValid() )
+ {
+ XclExpRecord::Save( rStrm );
+ maCFList.Save( rStrm );
+ }
+}
+
+void XclExpCondfmt::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT( !maCFList.IsEmpty(), "XclExpCondfmt::WriteBody - no CF records to write" );
+ DBG_ASSERT( !maXclRanges.empty(), "XclExpCondfmt::WriteBody - no cell ranges found" );
+
+ rStrm << static_cast< sal_uInt16 >( maCFList.GetSize() )
+ << sal_uInt16( 1 )
+ << maXclRanges.GetEnclosingRange()
+ << maXclRanges;
+}
+
+void XclExpCondfmt::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !IsValid() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_conditionalFormatting,
+ XML_sqref, XclXmlUtils::ToOString( msSeqRef ).getStr(),
+ // OOXTODO: XML_pivot,
+ FSEND );
+ maCFList.SaveXml( rStrm );
+ // OOXTODO: XML_extLst
+ rWorksheet->endElement( XML_conditionalFormatting );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCondFormatBuffer::XclExpCondFormatBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ if( const ScConditionalFormatList* pCondFmtList = GetDoc().GetCondFormList() )
+ {
+ if( const ScConditionalFormatPtr* ppCondFmt = pCondFmtList->GetData() )
+ {
+ const ScConditionalFormatPtr* ppCondEnd = ppCondFmt + pCondFmtList->Count();
+ for( ; ppCondFmt < ppCondEnd; ++ppCondFmt )
+ {
+ if( *ppCondFmt )
+ {
+ XclExpCondfmtList::RecordRefType xCondfmtRec( new XclExpCondfmt( GetRoot(), **ppCondFmt ) );
+ if( xCondfmtRec->IsValid() )
+ maCondfmtList.AppendRecord( xCondfmtRec );
+ }
+ }
+ }
+ }
+}
+
+void XclExpCondFormatBuffer::Save( XclExpStream& rStrm )
+{
+ maCondfmtList.Save( rStrm );
+}
+
+void XclExpCondFormatBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ maCondfmtList.SaveXml( rStrm );
+}
+
+// Validation =================================================================
+
+namespace {
+
+/** Writes a formula for the DV record. */
+void lclWriteDvFormula( XclExpStream& rStrm, const XclTokenArray* pXclTokArr )
+{
+ sal_uInt16 nFmlaSize = pXclTokArr ? pXclTokArr->GetSize() : 0;
+ rStrm << nFmlaSize << sal_uInt16( 0 );
+ if( pXclTokArr )
+ pXclTokArr->WriteArray( rStrm );
+}
+
+/** Writes a formula for the DV record, based on a single string. */
+void lclWriteDvFormula( XclExpStream& rStrm, const XclExpString& rString )
+{
+ // fake a formula with a single tStr token
+ rStrm << static_cast< sal_uInt16 >( rString.GetSize() + 1 )
+ << sal_uInt16( 0 )
+ << EXC_TOKID_STR
+ << rString;
+}
+
+const char* lcl_GetValidationType( sal_uInt32 nFlags )
+{
+ switch( nFlags & EXC_DV_MODE_MASK )
+ {
+ case EXC_DV_MODE_ANY: return "none";
+ case EXC_DV_MODE_WHOLE: return "whole";
+ case EXC_DV_MODE_DECIMAL: return "decimal";
+ case EXC_DV_MODE_LIST: return "list";
+ case EXC_DV_MODE_DATE: return "date";
+ case EXC_DV_MODE_TIME: return "time";
+ case EXC_DV_MODE_TEXTLEN: return "textLength";
+ case EXC_DV_MODE_CUSTOM: return "custom";
+ }
+ return NULL;
+}
+
+const char* lcl_GetOperatorType( sal_uInt32 nFlags )
+{
+ switch( nFlags & EXC_DV_COND_MASK )
+ {
+ case EXC_DV_COND_BETWEEN: return "between";
+ case EXC_DV_COND_NOTBETWEEN: return "notBetween";
+ case EXC_DV_COND_EQUAL: return "equal";
+ case EXC_DV_COND_NOTEQUAL: return "notEqual";
+ case EXC_DV_COND_GREATER: return "greaterThan";
+ case EXC_DV_COND_LESS: return "lessThan";
+ case EXC_DV_COND_EQGREATER: return "greaterThanOrEqual";
+ case EXC_DV_COND_EQLESS: return "lessThanOrEqual";
+ }
+ return NULL;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpDV::XclExpDV( const XclExpRoot& rRoot, ULONG nScHandle ) :
+ XclExpRecord( EXC_ID_DV ),
+ XclExpRoot( rRoot ),
+ mnFlags( 0 ),
+ mnScHandle( nScHandle )
+{
+ if( const ScValidationData* pValData = GetDoc().GetValidationEntry( mnScHandle ) )
+ {
+ // prompt box - empty string represented by single NUL character
+ String aTitle, aText;
+ bool bShowPrompt = (pValData->GetInput( aTitle, aText ) == TRUE);
+ if( aTitle.Len() )
+ maPromptTitle.Assign( aTitle );
+ else
+ maPromptTitle.Assign( '\0' );
+ if( aText.Len() )
+ maPromptText.Assign( aText );
+ else
+ maPromptText.Assign( '\0' );
+
+ // error box - empty string represented by single NUL character
+ ScValidErrorStyle eScErrorStyle;
+ bool bShowError = (pValData->GetErrMsg( aTitle, aText, eScErrorStyle ) == TRUE);
+ if( aTitle.Len() )
+ maErrorTitle.Assign( aTitle );
+ else
+ maErrorTitle.Assign( '\0' );
+ if( aText.Len() )
+ maErrorText.Assign( aText );
+ else
+ maErrorText.Assign( '\0' );
+
+ // flags
+ switch( pValData->GetDataMode() )
+ {
+ case SC_VALID_ANY: mnFlags |= EXC_DV_MODE_ANY; break;
+ case SC_VALID_WHOLE: mnFlags |= EXC_DV_MODE_WHOLE; break;
+ case SC_VALID_DECIMAL: mnFlags |= EXC_DV_MODE_DECIMAL; break;
+ case SC_VALID_LIST: mnFlags |= EXC_DV_MODE_LIST; break;
+ case SC_VALID_DATE: mnFlags |= EXC_DV_MODE_DATE; break;
+ case SC_VALID_TIME: mnFlags |= EXC_DV_MODE_TIME; break;
+ case SC_VALID_TEXTLEN: mnFlags |= EXC_DV_MODE_TEXTLEN; break;
+ case SC_VALID_CUSTOM: mnFlags |= EXC_DV_MODE_CUSTOM; break;
+ default: DBG_ERRORFILE( "XclExpDV::XclExpDV - unknown mode" );
+ }
+
+ switch( pValData->GetOperation() )
+ {
+ case SC_COND_NONE:
+ case SC_COND_EQUAL: mnFlags |= EXC_DV_COND_EQUAL; break;
+ case SC_COND_LESS: mnFlags |= EXC_DV_COND_LESS; break;
+ case SC_COND_GREATER: mnFlags |= EXC_DV_COND_GREATER; break;
+ case SC_COND_EQLESS: mnFlags |= EXC_DV_COND_EQLESS; break;
+ case SC_COND_EQGREATER: mnFlags |= EXC_DV_COND_EQGREATER; break;
+ case SC_COND_NOTEQUAL: mnFlags |= EXC_DV_COND_NOTEQUAL; break;
+ case SC_COND_BETWEEN: mnFlags |= EXC_DV_COND_BETWEEN; break;
+ case SC_COND_NOTBETWEEN: mnFlags |= EXC_DV_COND_NOTBETWEEN; break;
+ default: DBG_ERRORFILE( "XclExpDV::XclExpDV - unknown condition" );
+ }
+ switch( eScErrorStyle )
+ {
+ case SC_VALERR_STOP: mnFlags |= EXC_DV_ERROR_STOP; break;
+ case SC_VALERR_WARNING: mnFlags |= EXC_DV_ERROR_WARNING; break;
+ case SC_VALERR_INFO: mnFlags |= EXC_DV_ERROR_INFO; break;
+ case SC_VALERR_MACRO:
+ // #111781# set INFO for validity with macro call, delete title
+ mnFlags |= EXC_DV_ERROR_INFO;
+ maErrorTitle.Assign( '\0' ); // contains macro name
+ break;
+ default: DBG_ERRORFILE( "XclExpDV::XclExpDV - unknown error style" );
+ }
+ ::set_flag( mnFlags, EXC_DV_IGNOREBLANK, pValData->IsIgnoreBlank() );
+ ::set_flag( mnFlags, EXC_DV_SUPPRESSDROPDOWN, pValData->GetListType() == ValidListType::INVISIBLE );
+ ::set_flag( mnFlags, EXC_DV_SHOWPROMPT, bShowPrompt );
+ ::set_flag( mnFlags, EXC_DV_SHOWERROR, bShowError );
+
+ // formulas
+ XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
+ ::std::auto_ptr< ScTokenArray > xScTokArr;
+
+ // first formula
+ xScTokArr.reset( pValData->CreateTokenArry( 0 ) );
+ if( xScTokArr.get() )
+ {
+ if( pValData->GetDataMode() == SC_VALID_LIST )
+ {
+ String aString;
+ if( XclTokenArrayHelper::GetStringList( aString, *xScTokArr, '\n' ) )
+ {
+ OUStringBuffer sFormulaBuf;
+ sFormulaBuf.append( (sal_Unicode) '"' );
+ /* Formula is a list of string tokens -> build the Excel string.
+ Data validity is BIFF8 only (important for the XclExpString object).
+ Excel uses the NUL character as string list separator. */
+ mxString1.reset( new XclExpString( EXC_STR_8BITLENGTH ) );
+ xub_StrLen nTokenCnt = aString.GetTokenCount( '\n' );
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( aString.GetToken( 0, '\n', nStringIx ) );
+ if( nToken > 0 )
+ {
+ mxString1->Append( '\0' );
+ sFormulaBuf.append( (sal_Unicode) ',' );
+ }
+ mxString1->Append( aToken );
+ sFormulaBuf.append( XclXmlUtils::ToOUString( aToken ) );
+ }
+ ::set_flag( mnFlags, EXC_DV_STRINGLIST );
+
+ sFormulaBuf.append( (sal_Unicode) '"' );
+ msFormula1 = sFormulaBuf.makeStringAndClear();
+ }
+ else
+ {
+ /* All other formulas in validation are stored like conditional
+ formatting formulas (with tRefN/tAreaN tokens as value or
+ array class). But NOT the cell references and defined names
+ in list validation - they are stored as reference class
+ tokens... Example:
+ 1) Cell must be equal to A1 -> formula is =A1 -> writes tRefNV token
+ 2) List is taken from A1 -> formula is =A1 -> writes tRefNR token
+ Formula compiler supports this by offering two different functions
+ CreateDataValFormula() and CreateListValFormula(). */
+ mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_LISTVAL, *xScTokArr );
+ msFormula1 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
+ }
+ }
+ else
+ {
+ // no list validation -> convert the formula
+ mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_DATAVAL, *xScTokArr );
+ msFormula1 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
+ }
+ }
+
+ // second formula
+ xScTokArr.reset( pValData->CreateTokenArry( 1 ) );
+ if( xScTokArr.get() )
+ {
+ mxTokArr2 = rFmlaComp.CreateFormula( EXC_FMLATYPE_DATAVAL, *xScTokArr );
+ msFormula2 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpDV::XclExpDV - missing core data" );
+ mnScHandle = ULONG_MAX;
+ }
+}
+
+XclExpDV::~XclExpDV()
+{
+}
+
+void XclExpDV::InsertCellRange( const ScRange& rRange )
+{
+ maScRanges.Join( rRange );
+}
+
+bool XclExpDV::Finalize()
+{
+ GetAddressConverter().ConvertRangeList( maXclRanges, maScRanges, true );
+ return (mnScHandle != ULONG_MAX) && !maXclRanges.empty();
+}
+
+void XclExpDV::WriteBody( XclExpStream& rStrm )
+{
+ // flags and strings
+ rStrm << mnFlags << maPromptTitle << maErrorTitle << maPromptText << maErrorText;
+ // condition formulas
+ if( mxString1.get() )
+ lclWriteDvFormula( rStrm, *mxString1 );
+ else
+ lclWriteDvFormula( rStrm, mxTokArr1.get() );
+ lclWriteDvFormula( rStrm, mxTokArr2.get() );
+ // cell ranges
+ rStrm << maXclRanges;
+}
+
+void XclExpDV::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_dataValidation,
+ XML_allowBlank, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_IGNOREBLANK ) ),
+ XML_error, XESTRING_TO_PSZ( maErrorText ),
+ // OOXTODO: XML_errorStyle,
+ XML_errorTitle, XESTRING_TO_PSZ( maErrorTitle ),
+ // OOXTODO: XML_imeMode,
+ XML_operator, lcl_GetOperatorType( mnFlags ),
+ XML_prompt, XESTRING_TO_PSZ( maPromptText ),
+ XML_promptTitle, XESTRING_TO_PSZ( maPromptTitle ),
+ XML_showDropDown, XclXmlUtils::ToPsz( ! ::get_flag( mnFlags, EXC_DV_SUPPRESSDROPDOWN ) ),
+ XML_showErrorMessage, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SHOWERROR ) ),
+ XML_showInputMessage, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SHOWPROMPT ) ),
+ XML_sqref, XclXmlUtils::ToOString( maScRanges ).getStr(),
+ XML_type, lcl_GetValidationType( mnFlags ),
+ FSEND );
+ if( msFormula1.getLength() )
+ {
+ rWorksheet->startElement( XML_formula1, FSEND );
+ rWorksheet->writeEscaped( msFormula1 );
+ rWorksheet->endElement( XML_formula1 );
+ }
+ if( msFormula2.getLength() )
+ {
+ rWorksheet->startElement( XML_formula2, FSEND );
+ rWorksheet->writeEscaped( msFormula2 );
+ rWorksheet->endElement( XML_formula2 );
+ }
+ rWorksheet->endElement( XML_dataValidation );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDval::XclExpDval( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_DVAL, 18 ),
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpDval::~XclExpDval()
+{
+}
+
+void XclExpDval::InsertCellRange( const ScRange& rRange, ULONG nScHandle )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ XclExpDV& rDVRec = SearchOrCreateDv( nScHandle );
+ rDVRec.InsertCellRange( rRange );
+ }
+}
+
+void XclExpDval::Save( XclExpStream& rStrm )
+{
+ // check all records
+ size_t nPos = maDVList.GetSize();
+ while( nPos )
+ {
+ --nPos; // backwards to keep nPos valid
+ XclExpDVRef xDVRec = maDVList.GetRecord( nPos );
+ if( !xDVRec->Finalize() )
+ maDVList.RemoveRecord( nPos );
+ }
+
+ // write the DVAL and the DV's
+ if( !maDVList.IsEmpty() )
+ {
+ XclExpRecord::Save( rStrm );
+ maDVList.Save( rStrm );
+ }
+}
+
+void XclExpDval::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maDVList.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_dataValidations,
+ XML_count, OString::valueOf( (sal_Int32) maDVList.GetSize() ).getStr(),
+ // OOXTODO: XML_disablePrompts,
+ // OOXTODO: XML_xWindow,
+ // OOXTODO: XML_yWindow,
+ FSEND );
+ maDVList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_dataValidations );
+}
+
+XclExpDV& XclExpDval::SearchOrCreateDv( ULONG nScHandle )
+{
+ // test last found record
+ if( mxLastFoundDV.get() && (mxLastFoundDV->GetScHandle() == nScHandle) )
+ return *mxLastFoundDV;
+
+ // binary search
+ size_t nCurrPos = 0;
+ if( !maDVList.IsEmpty() )
+ {
+ size_t nFirstPos = 0;
+ size_t nLastPos = maDVList.GetSize() - 1;
+ bool bLoop = true;
+ ULONG nCurrScHandle = ::std::numeric_limits< ULONG >::max();
+ while( (nFirstPos <= nLastPos) && bLoop )
+ {
+ nCurrPos = (nFirstPos + nLastPos) / 2;
+ mxLastFoundDV = maDVList.GetRecord( nCurrPos );
+ nCurrScHandle = mxLastFoundDV->GetScHandle();
+ if( nCurrScHandle == nScHandle )
+ bLoop = false;
+ else if( nCurrScHandle < nScHandle )
+ nFirstPos = nCurrPos + 1;
+ else if( nCurrPos )
+ nLastPos = nCurrPos - 1;
+ else // special case for nLastPos = -1
+ bLoop = false;
+ }
+ if( nCurrScHandle == nScHandle )
+ return *mxLastFoundDV;
+ else if( nCurrScHandle < nScHandle )
+ ++nCurrPos;
+ }
+
+ // create new DV record
+ mxLastFoundDV.reset( new XclExpDV( *this, nScHandle ) );
+ maDVList.InsertRecord( mxLastFoundDV, nCurrPos );
+ return *mxLastFoundDV;
+}
+
+void XclExpDval::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.WriteZeroBytes( 10 );
+ rStrm << EXC_DVAL_NOOBJ << static_cast< sal_uInt32 >( maDVList.GetSize() );
+}
+
+// Web Queries ================================================================
+
+XclExpWebQuery::XclExpWebQuery(
+ const String& rRangeName,
+ const String& rUrl,
+ const String& rSource,
+ sal_Int32 nRefrSecs ) :
+ maDestRange( rRangeName ),
+ maUrl( rUrl ),
+ // refresh delay time: seconds -> minutes
+ mnRefresh( ulimit_cast< sal_Int16 >( (nRefrSecs + 59L) / 60L ) ),
+ mbEntireDoc( false )
+{
+ // comma separated list of HTML table names or indexes
+ xub_StrLen nTokenCnt = rSource.GetTokenCount( ';' );
+ String aNewTables, aAppendTable;
+ xub_StrLen nStringIx = 0;
+ bool bExitLoop = false;
+ for( xub_StrLen nToken = 0; (nToken < nTokenCnt) && !bExitLoop; ++nToken )
+ {
+ String aToken( rSource.GetToken( 0, ';', nStringIx ) );
+ mbEntireDoc = ScfTools::IsHTMLDocName( aToken );
+ bExitLoop = mbEntireDoc || ScfTools::IsHTMLTablesName( aToken );
+ if( !bExitLoop && ScfTools::GetHTMLNameFromName( aToken, aAppendTable ) )
+ ScGlobal::AddToken( aNewTables, aAppendTable, ',' );
+ }
+
+ if( !bExitLoop ) // neither HTML_all nor HTML_tables found
+ {
+ if( aNewTables.Len() )
+ mxQryTables.reset( new XclExpString( aNewTables ) );
+ else
+ mbEntireDoc = true;
+ }
+}
+
+XclExpWebQuery::~XclExpWebQuery()
+{
+}
+
+void XclExpWebQuery::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( !mbEntireDoc || !mxQryTables.get(), "XclExpWebQuery::Save - illegal mode" );
+ sal_uInt16 nFlags;
+
+ // QSI record
+ rStrm.StartRecord( EXC_ID_QSI, 10 + maDestRange.GetSize() );
+ rStrm << EXC_QSI_DEFAULTFLAGS
+ << sal_uInt16( 0x0010 )
+ << sal_uInt16( 0x0012 )
+ << sal_uInt32( 0x00000000 )
+ << maDestRange;
+ rStrm.EndRecord();
+
+ // PARAMQRY record
+ nFlags = 0;
+ ::insert_value( nFlags, EXC_PQRYTYPE_WEBQUERY, 0, 3 );
+ ::set_flag( nFlags, EXC_PQRY_WEBQUERY );
+ ::set_flag( nFlags, EXC_PQRY_TABLES, !mbEntireDoc );
+ rStrm.StartRecord( EXC_ID_PQRY, 12 );
+ rStrm << nFlags
+ << sal_uInt16( 0x0000 )
+ << sal_uInt16( 0x0001 );
+ rStrm.WriteZeroBytes( 6 );
+ rStrm.EndRecord();
+
+ // WQSTRING record
+ rStrm.StartRecord( EXC_ID_WQSTRING, maUrl.GetSize() );
+ rStrm << maUrl;
+ rStrm.EndRecord();
+
+ // unknown record 0x0802
+ rStrm.StartRecord( EXC_ID_0802, 16 + maDestRange.GetSize() );
+ rStrm << EXC_ID_0802; // repeated record id ?!?
+ rStrm.WriteZeroBytes( 6 );
+ rStrm << sal_uInt16( 0x0003 )
+ << sal_uInt32( 0x00000000 )
+ << sal_uInt16( 0x0010 )
+ << maDestRange;
+ rStrm.EndRecord();
+
+ // WEBQRYSETTINGS record
+ nFlags = mxQryTables.get() ? EXC_WQSETT_SPECTABLES : EXC_WQSETT_ALL;
+ rStrm.StartRecord( EXC_ID_WQSETT, 28 );
+ rStrm << EXC_ID_WQSETT // repeated record id ?!?
+ << sal_uInt16( 0x0000 )
+ << sal_uInt16( 0x0004 )
+ << sal_uInt16( 0x0000 )
+ << EXC_WQSETT_DEFAULTFLAGS
+ << nFlags;
+ rStrm.WriteZeroBytes( 10 );
+ rStrm << mnRefresh // refresh delay in minutes
+ << EXC_WQSETT_FORMATFULL
+ << sal_uInt16( 0x0000 );
+ rStrm.EndRecord();
+
+ // WEBQRYTABLES record
+ if( mxQryTables.get() )
+ {
+ rStrm.StartRecord( EXC_ID_WQTABLES, 4 + mxQryTables->GetSize() );
+ rStrm << EXC_ID_WQTABLES // repeated record id ?!?
+ << sal_uInt16( 0x0000 )
+ << *mxQryTables; // comma separated list of source tables
+ rStrm.EndRecord();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpWebQueryBuffer::XclExpWebQueryBuffer( const XclExpRoot& rRoot )
+{
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ SfxObjectShell* pShell = rRoot.GetDocShell();
+ if( !pShell ) return;
+ ScfPropertySet aModelProp( pShell->GetModel() );
+ if( !aModelProp.Is() ) return;
+
+ Reference< XAreaLinks > xAreaLinks;
+ aModelProp.GetProperty( xAreaLinks, CREATE_OUSTRING( SC_UNO_AREALINKS ) );
+ Reference< XIndexAccess > xLinksIA( xAreaLinks, UNO_QUERY );
+ if( !xLinksIA.is() ) return;
+
+ for( sal_Int32 nIndex = 0, nCount = xLinksIA->getCount(); nIndex < nCount; ++nIndex )
+ {
+ Reference< XAreaLink > xAreaLink( xLinksIA->getByIndex( nIndex ), UNO_QUERY );
+ if( xAreaLink.is() )
+ {
+ CellRangeAddress aDestRange( xAreaLink->getDestArea() );
+ if( static_cast< SCTAB >( aDestRange.Sheet ) == nScTab )
+ {
+ ScfPropertySet aLinkProp( xAreaLink );
+ OUString aFilter;
+ if( aLinkProp.GetProperty( aFilter, CREATE_OUSTRING( SC_UNONAME_FILTER ) ) &&
+ (aFilter == CREATE_OUSTRING( EXC_WEBQRY_FILTER )) )
+ {
+ // get properties
+ OUString /*aFilterOpt,*/ aUrl;
+ sal_Int32 nRefresh = 0;
+
+// aLinkProp.GetProperty( aFilterOpt, CREATE_OUSTRING( SC_UNONAME_FILTOPT ) );
+ aLinkProp.GetProperty( aUrl, CREATE_OUSTRING( SC_UNONAME_LINKURL ) );
+ aLinkProp.GetProperty( nRefresh, CREATE_OUSTRING( SC_UNONAME_REFDELAY ) );
+
+ String aAbsDoc( ScGlobal::GetAbsDocName( aUrl, pShell ) );
+ INetURLObject aUrlObj( aAbsDoc );
+ String aWebQueryUrl( aUrlObj.getFSysPath( INetURLObject::FSYS_DOS ) );
+ if( !aWebQueryUrl.Len() )
+ aWebQueryUrl = aAbsDoc;
+
+ // find range or create a new range
+ String aRangeName;
+ ScRange aScDestRange;
+ ScUnoConversion::FillScRange( aScDestRange, aDestRange );
+ if( const ScRangeData* pRangeData = rRoot.GetNamedRanges().GetRangeAtBlock( aScDestRange ) )
+ {
+ aRangeName = pRangeData->GetName();
+ }
+ else
+ {
+ XclExpFormulaCompiler& rFmlaComp = rRoot.GetFormulaCompiler();
+ XclExpNameManager& rNameMgr = rRoot.GetNameManager();
+
+ // create a new unique defined name containing the range
+ XclTokenArrayRef xTokArr = rFmlaComp.CreateFormula( EXC_FMLATYPE_WQUERY, aScDestRange );
+ sal_uInt16 nNameIdx = rNameMgr.InsertUniqueName( aUrlObj.getBase(), xTokArr, nScTab );
+ aRangeName = rNameMgr.GetOrigName( nNameIdx );
+ }
+
+ // create and store the web query record
+ if( aRangeName.Len() )
+ AppendNewRecord( new XclExpWebQuery(
+ aRangeName, aWebQueryUrl, xAreaLink->getSourceArea(), nRefresh ) );
+ }
+ }
+ }
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
new file mode 100644
index 000000000000..b2801df7f54a
--- /dev/null
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -0,0 +1,1284 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xeescher.hxx"
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/awt/VisualEffect.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+
+#include <set>
+#include <rtl/ustrbuf.h>
+#include <vcl/bmpacc.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include "editutil.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "postit.hxx"
+
+#include "fapihelper.hxx"
+#include "xechart.hxx"
+#include "xeformula.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xestyle.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XShapes;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::embed::XEmbeddedObject;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::form::binding::XBindableValue;
+using ::com::sun::star::form::binding::XValueBinding;
+using ::com::sun::star::form::binding::XListEntrySink;
+using ::com::sun::star::form::binding::XListEntrySource;
+using ::com::sun::star::script::ScriptEventDescriptor;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+
+// Escher client anchor =======================================================
+
+XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags ) :
+ XclExpRoot( rRoot ),
+ mnFlags( nFlags )
+{
+}
+
+void XclExpDffAnchorBase::SetFlags( const SdrObject& rSdrObj )
+{
+ ImplSetFlags( rSdrObj );
+}
+
+void XclExpDffAnchorBase::SetSdrObject( const SdrObject& rSdrObj )
+{
+ ImplSetFlags( rSdrObj );
+ ImplCalcAnchorRect( rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM );
+}
+
+void XclExpDffAnchorBase::WriteDffData( EscherEx& rEscherEx ) const
+{
+ rEscherEx.AddAtom( 18, ESCHER_ClientAnchor );
+ rEscherEx.GetStream() << mnFlags << maAnchor;
+}
+
+void XclExpDffAnchorBase::WriteData( EscherEx& rEscherEx, const Rectangle& rRect )
+{
+ // the passed rectangle is in twips
+ ImplCalcAnchorRect( rRect, MAP_TWIP );
+ WriteDffData( rEscherEx );
+}
+
+void XclExpDffAnchorBase::ImplSetFlags( const SdrObject& )
+{
+ OSL_ENSURE( false, "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
+}
+
+void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle&, MapUnit )
+{
+ OSL_ENSURE( false, "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot& rRoot ) :
+ XclExpDffAnchorBase( rRoot ),
+ mnScTab( rRoot.GetCurrScTab() )
+{
+}
+
+void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject& rSdrObj )
+{
+ // Special case "page anchor" (X==0,Y==1) -> lock pos and size.
+ const Point& rPos = rSdrObj.GetAnchorPos();
+ mnFlags = ((rPos.X() == 0) && (rPos.Y() == 1)) ? EXC_ESC_ANCHOR_LOCKED : 0;
+}
+
+void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit )
+{
+ maAnchor.SetRect( GetRoot(), mnScTab, rRect, eMapUnit );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot,
+ const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) :
+ XclExpDffAnchorBase( rRoot ),
+ maPageSize( rPageSize ),
+ mnScaleX( nScaleX ),
+ mnScaleY( nScaleY )
+{
+}
+
+void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject& /*rSdrObj*/ )
+{
+ // TODO (unsupported feature): fixed size
+}
+
+void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit )
+{
+ maAnchor.SetRect( maPageSize, mnScaleX, mnScaleY, rRect, eMapUnit, true );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) :
+ XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_SIZELOCKED )
+{
+ maAnchor.SetRect( rRoot, rRoot.GetCurrScTab(), rRect, MAP_100TH_MM );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) :
+ XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_POSLOCKED )
+{
+ GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true );
+ maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1;
+ maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1;
+ maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0;
+}
+
+// MSODRAWING* records ========================================================
+
+XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ) :
+ XclExpRecord( nRecId ),
+ mrEscherEx( rEscherEx ),
+ mnFragmentKey( rEscherEx.InitNextDffFragment() )
+{
+}
+
+void XclExpMsoDrawingBase::WriteBody( XclExpStream& rStrm )
+{
+ OSL_ENSURE( mrEscherEx.GetStreamPos() == mrEscherEx.GetDffFragmentPos( mnFragmentKey ),
+ "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
+ rStrm.CopyFromStream( mrEscherEx.GetStream(), mrEscherEx.GetDffFragmentSize( mnFragmentKey ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ) :
+ XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWINGGROUP )
+{
+ SvStream& rDffStrm = mrEscherEx.GetStream();
+
+ // write the DGGCONTAINER with some default settings
+ mrEscherEx.OpenContainer( ESCHER_DggContainer );
+
+ // TODO: stuff the OPT atom with our own document defaults?
+ static const sal_uInt8 spnDffOpt[] = {
+ 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
+ 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
+ 0x00, 0x08
+ };
+ mrEscherEx.AddAtom( sizeof( spnDffOpt ), ESCHER_OPT, 3, 3 );
+ rDffStrm.Write( spnDffOpt, sizeof( spnDffOpt ) );
+
+ // SPLITMENUCOLORS contains colors in toolbar
+ static const sal_uInt8 spnDffSplitMenuColors[] = {
+ 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
+ 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
+ };
+ mrEscherEx.AddAtom( sizeof( spnDffSplitMenuColors ), ESCHER_SplitMenuColors, 0, 4 );
+ rDffStrm.Write( spnDffSplitMenuColors, sizeof( spnDffSplitMenuColors ) );
+
+ // close the DGGCONTAINER
+ mrEscherEx.CloseContainer();
+ mrEscherEx.UpdateDffFragmentEnd();
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx& rEscherEx ) :
+ XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWING )
+{
+}
+
+// ============================================================================
+
+XclExpImgData::XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId ) :
+ maGraphic( rGraphic ),
+ mnRecId( nRecId )
+{
+}
+
+void XclExpImgData::Save( XclExpStream& rStrm )
+{
+ Bitmap aBmp = maGraphic.GetBitmap();
+ if( aBmp.GetBitCount() != 24 )
+ aBmp.Convert( BMP_CONVERSION_24BIT );
+
+ if( BitmapReadAccess* pAccess = aBmp.AcquireReadAccess() )
+ {
+ sal_Int32 nWidth = ::std::min< sal_Int32 >( pAccess->Width(), 0xFFFF );
+ sal_Int32 nHeight = ::std::min< sal_Int32 >( pAccess->Height(), 0xFFFF );
+ if( (nWidth > 0) && (nHeight > 0) )
+ {
+ sal_uInt8 nPadding = static_cast< sal_uInt8 >( nWidth & 0x03 );
+ sal_uInt32 nTmpSize = static_cast< sal_uInt32 >( (nWidth * 3 + nPadding) * nHeight + 12 );
+
+ rStrm.StartRecord( mnRecId, nTmpSize + 4 );
+
+ rStrm << EXC_IMGDATA_BMP // BMP format
+ << EXC_IMGDATA_WIN // Windows
+ << nTmpSize // size after _this_ field
+ << sal_uInt32( 12 ) // BITMAPCOREHEADER size
+ << static_cast< sal_uInt16 >( nWidth ) // width
+ << static_cast< sal_uInt16 >( nHeight ) // height
+ << sal_uInt16( 1 ) // planes
+ << sal_uInt16( 24 ); // bits per pixel
+
+ for( sal_Int32 nY = nHeight - 1; nY >= 0; --nY )
+ {
+ for( sal_Int32 nX = 0; nX < nWidth; ++nX )
+ {
+ const BitmapColor& rBmpColor = pAccess->GetPixel( nY, nX );
+ rStrm << rBmpColor.GetBlue() << rBmpColor.GetGreen() << rBmpColor.GetRed();
+ }
+ rStrm.WriteZeroBytes( nPadding );
+ }
+
+ rStrm.EndRecord();
+ }
+ aBmp.ReleaseAccess( pAccess );
+ }
+}
+
+// ============================================================================
+
+XclExpControlHelper::XclExpControlHelper( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnEntryCount( 0 )
+{
+}
+
+XclExpControlHelper::~XclExpControlHelper()
+{
+}
+
+void XclExpControlHelper::ConvertSheetLinks( Reference< XShape > xShape )
+{
+ mxCellLink.reset();
+ mxSrcRange.reset();
+ mnEntryCount = 0;
+
+ // get control model
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
+ if( !xCtrlModel.is() )
+ return;
+
+ // *** cell link *** ------------------------------------------------------
+
+ Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY );
+ if( xBindable.is() )
+ {
+ Reference< XServiceInfo > xServInfo( xBindable->getValueBinding(), UNO_QUERY );
+ if( xServInfo.is() && xServInfo->supportsService( CREATE_OUSTRING( SC_SERVICENAME_VALBIND ) ) )
+ {
+ ScfPropertySet aBindProp( xServInfo );
+ CellAddress aApiAddress;
+ if( aBindProp.GetProperty( aApiAddress, CREATE_OUSTRING( SC_UNONAME_BOUNDCELL ) ) )
+ {
+ ScAddress aCellLink;
+ ScUnoConversion::FillScAddress( aCellLink, aApiAddress );
+ if( GetTabInfo().IsExportTab( aCellLink.Tab() ) )
+ mxCellLink = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL, aCellLink );
+ }
+ }
+ }
+
+ // *** source range *** ---------------------------------------------------
+
+ Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY );
+ if( xEntrySink.is() )
+ {
+ Reference< XServiceInfo > xServInfo( xEntrySink->getListEntrySource(), UNO_QUERY );
+ if( xServInfo.is() && xServInfo->supportsService( CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ) ) )
+ {
+ ScfPropertySet aSinkProp( xServInfo );
+ CellRangeAddress aApiRange;
+ if( aSinkProp.GetProperty( aApiRange, CREATE_OUSTRING( SC_UNONAME_CELLRANGE ) ) )
+ {
+ ScRange aSrcRange;
+ ScUnoConversion::FillScRange( aSrcRange, aApiRange );
+ if( (aSrcRange.aStart.Tab() == aSrcRange.aEnd.Tab()) && GetTabInfo().IsExportTab( aSrcRange.aStart.Tab() ) )
+ mxSrcRange = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL, aSrcRange );
+ mnEntryCount = static_cast< sal_uInt16 >( aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1 );
+ }
+ }
+ }
+}
+
+void XclExpControlHelper::WriteFormula( XclExpStream& rStrm, const XclTokenArray& rTokArr ) const
+{
+ sal_uInt16 nFmlaSize = rTokArr.GetSize();
+ rStrm << nFmlaSize << sal_uInt32( 0 );
+ rTokArr.WriteArray( rStrm );
+ if( nFmlaSize & 1 ) // pad to 16-bit
+ rStrm << sal_uInt8( 0 );
+}
+
+void XclExpControlHelper::WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId, const XclTokenArray& rTokArr ) const
+{
+ rStrm.StartRecord( nSubRecId, (rTokArr.GetSize() + 5) & ~1 );
+ WriteFormula( rStrm, rTokArr );
+ rStrm.EndRecord();
+}
+
+// ----------------------------------------------------------------------------
+
+#if EXC_EXP_OCX_CTRL
+
+XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape,
+ const Rectangle* pChildAnchor, const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_PICTURE, true ),
+ XclExpControlHelper( rObjMgr.GetRoot() ),
+ maClassName( rClassName ),
+ mnStrmStart( nStrmStart ),
+ mnStrmSize( nStrmSize )
+{
+ ScfPropertySet aCtrlProp( XclControlHelper::GetControlModel( xShape ) );
+
+ // OBJ record flags
+ SetLocked( TRUE );
+ SetPrintable( aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Printable" ) ) );
+ SetAutoFill( FALSE );
+ SetAutoLine( FALSE );
+
+ // fill DFF property set
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE );
+ Rectangle aDummyRect;
+ EscherPropertyContainer aPropOpt( mrEscherEx, mrEscherEx.QueryPicStream(), aDummyRect );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
+
+ // #i51348# name of the control, may overwrite shape name
+ OUString aCtrlName;
+ if( aCtrlProp.GetProperty( aCtrlName, CREATE_OUSTRING( "Name" ) ) && (aCtrlName.getLength() > 0) )
+ aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName );
+
+ // meta file
+ //! TODO - needs check
+ Reference< XPropertySet > xShapePS( xShape, UNO_QUERY );
+ if( xShapePS.is() && aPropOpt.CreateGraphicProperties( xShapePS, CREATE_STRING( "MetaFile" ), sal_False ) )
+ {
+ sal_uInt32 nBlipId;
+ if( aPropOpt.GetOpt( ESCHER_Prop_pib, nBlipId ) )
+ aPropOpt.AddOpt( ESCHER_Prop_pictureId, nBlipId );
+ }
+
+ // write DFF property set to stream
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ // anchor
+ ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ // spreadsheet links
+ ConvertSheetLinks( xShape );
+}
+
+void XclExpOcxControlObj::WriteSubRecs( XclExpStream& rStrm )
+{
+ // OBJCF - clipboard format
+ rStrm.StartRecord( EXC_ID_OBJCF, 2 );
+ rStrm << sal_uInt16( 2 );
+ rStrm.EndRecord();
+
+ // OBJFLAGS
+ rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
+ rStrm << sal_uInt16( 0x0031 );
+ rStrm.EndRecord();
+
+ // OBJPICTFMLA
+ XclExpString aClass( maClassName );
+ sal_uInt16 nClassNameSize = static_cast< sal_uInt16 >( aClass.GetSize() );
+ sal_uInt16 nClassNamePad = nClassNameSize & 1;
+ sal_uInt16 nFirstPartSize = 12 + nClassNameSize + nClassNamePad;
+
+ const XclTokenArray* pCellLink = GetCellLinkTokArr();
+ sal_uInt16 nCellLinkSize = pCellLink ? ((pCellLink->GetSize() + 7) & 0xFFFE) : 0;
+
+ const XclTokenArray* pSrcRange = GetSourceRangeTokArr();
+ sal_uInt16 nSrcRangeSize = pSrcRange ? ((pSrcRange->GetSize() + 7) & 0xFFFE) : 0;
+
+ sal_uInt16 nPictFmlaSize = nFirstPartSize + nCellLinkSize + nSrcRangeSize + 18;
+ rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nPictFmlaSize );
+
+ rStrm << sal_uInt16( nFirstPartSize ) // size of first part
+ << sal_uInt16( 5 ) // formula size
+ << sal_uInt32( 0 ) // unknown ID
+ << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
+ << sal_uInt8( 3 ) // pad to word
+ << aClass; // "Forms.***.1"
+ rStrm.WriteZeroBytes( nClassNamePad ); // pad to word
+ rStrm << mnStrmStart // start in 'Ctls' stream
+ << mnStrmSize // size in 'Ctls' stream
+ << sal_uInt32( 0 ); // class ID size
+ // cell link
+ rStrm << nCellLinkSize;
+ if( pCellLink )
+ WriteFormula( rStrm, *pCellLink );
+ // list source range
+ rStrm << nSrcRangeSize;
+ if( pSrcRange )
+ WriteFormula( rStrm, *pSrcRange );
+
+ rStrm.EndRecord();
+}
+
+#else
+
+XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN, true ),
+ XclExpControlHelper( rObjMgr.GetRoot() ),
+ mnHeight( 0 ),
+ mnState( 0 ),
+ mnLineCount( 0 ),
+ mnSelEntry( 0 ),
+ mnScrollValue( 0 ),
+ mnScrollMin( 0 ),
+ mnScrollMax( 100 ),
+ mnScrollStep( 1 ),
+ mnScrollPage( 10 ),
+ mbFlatButton( false ),
+ mbFlatBorder( false ),
+ mbMultiSel( false ),
+ mbScrollHor( false )
+{
+ namespace FormCompType = ::com::sun::star::form::FormComponentType;
+ namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+
+ ScfPropertySet aCtrlProp( XclControlHelper::GetControlModel( xShape ) );
+ if( !xShape.is() || !aCtrlProp.Is() )
+ return;
+
+ mnHeight = xShape->getSize().Height;
+ if( mnHeight <= 0 )
+ return;
+
+ // control type
+ sal_Int16 nClassId = 0;
+ if( aCtrlProp.GetProperty( nClassId, CREATE_OUSTRING( "ClassId" ) ) )
+ {
+ switch( nClassId )
+ {
+ case FormCompType::COMMANDBUTTON: mnObjType = EXC_OBJTYPE_BUTTON; meEventType = EXC_TBX_EVENT_ACTION; break;
+ case FormCompType::RADIOBUTTON: mnObjType = EXC_OBJTYPE_OPTIONBUTTON; meEventType = EXC_TBX_EVENT_ACTION; break;
+ case FormCompType::CHECKBOX: mnObjType = EXC_OBJTYPE_CHECKBOX; meEventType = EXC_TBX_EVENT_ACTION; break;
+ case FormCompType::LISTBOX: mnObjType = EXC_OBJTYPE_LISTBOX; meEventType = EXC_TBX_EVENT_CHANGE; break;
+ case FormCompType::COMBOBOX: mnObjType = EXC_OBJTYPE_DROPDOWN; meEventType = EXC_TBX_EVENT_CHANGE; break;
+ case FormCompType::GROUPBOX: mnObjType = EXC_OBJTYPE_GROUPBOX; meEventType = EXC_TBX_EVENT_MOUSE; break;
+ case FormCompType::FIXEDTEXT: mnObjType = EXC_OBJTYPE_LABEL; meEventType = EXC_TBX_EVENT_MOUSE; break;
+ case FormCompType::SCROLLBAR: mnObjType = EXC_OBJTYPE_SCROLLBAR; meEventType = EXC_TBX_EVENT_VALUE; break;
+ case FormCompType::SPINBUTTON: mnObjType = EXC_OBJTYPE_SPIN; meEventType = EXC_TBX_EVENT_VALUE; break;
+ }
+ }
+ if( mnObjType == EXC_OBJTYPE_UNKNOWN )
+ return;
+
+ // OBJ record flags
+ SetLocked( TRUE );
+ SetPrintable( aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Printable" ) ) );
+ SetAutoFill( FALSE );
+ SetAutoLine( FALSE );
+
+ // fill DFF property set
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ EscherPropertyContainer aPropOpt;
+ bool bVisible = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "EnableVisible" ) );
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, bVisible ? 0x00080000 : 0x00080002 ); // visible flag
+
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01000100 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // Text ID
+ aPropOpt.AddOpt( ESCHER_Prop_WrapText, 0x00000001 );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x001A0008 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00100000 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
+
+ // #i51348# name of the control, may overwrite shape name
+ OUString aCtrlName;
+ if( aCtrlProp.GetProperty( aCtrlName, CREATE_OUSTRING( "Name" ) ) && (aCtrlName.getLength() > 0) )
+ aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName );
+
+ // write DFF property set to stream
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ // anchor
+ ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ // control label
+ OUString aString;
+ if( aCtrlProp.GetProperty( aString, CREATE_OUSTRING( "Label" ) ) )
+ {
+ /* Be sure to construct the MSODRAWING record containing the
+ ClientTextbox atom after the base OBJ's MSODRAWING record data is
+ completed. */
+ pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
+ mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ sal_uInt16 nXclFont = EXC_FONT_APP;
+ if( aString.getLength() > 0 )
+ {
+ XclFontData aFontData;
+ GetFontPropSetHelper().ReadFontProperties( aFontData, aCtrlProp, EXC_FONTPROPSET_CONTROL );
+ if( (aFontData.maName.Len() > 0) && (aFontData.mnHeight > 0) )
+ nXclFont = GetFontBuffer().Insert( aFontData, EXC_COLOR_CTRLTEXT );
+ }
+
+ pTxo = new XclTxo( aString, nXclFont );
+ pTxo->SetHorAlign( (mnObjType == EXC_OBJTYPE_BUTTON) ? EXC_OBJ_HOR_CENTER : EXC_OBJ_HOR_LEFT );
+ pTxo->SetVerAlign( EXC_OBJ_VER_CENTER );
+ }
+
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+
+ // other properties
+ aCtrlProp.GetProperty( mnLineCount, CREATE_OUSTRING( "LineCount" ) );
+
+ // border style
+ sal_Int16 nApiButton = AwtVisualEffect::LOOK3D;
+ sal_Int16 nApiBorder = AwtVisualEffect::LOOK3D;
+ switch( nClassId )
+ {
+ case FormCompType::LISTBOX:
+ case FormCompType::COMBOBOX:
+ aCtrlProp.GetProperty( nApiBorder, CREATE_OUSTRING( "Border" ) );
+ break;
+ case FormCompType::CHECKBOX:
+ case FormCompType::RADIOBUTTON:
+ aCtrlProp.GetProperty( nApiButton, CREATE_OUSTRING( "VisualEffect" ) );
+ nApiBorder = AwtVisualEffect::NONE;
+ break;
+ // Push button cannot be set to flat in Excel
+ case FormCompType::COMMANDBUTTON:
+ nApiBorder = AwtVisualEffect::LOOK3D;
+ break;
+ // Label does not support a border in Excel
+ case FormCompType::FIXEDTEXT:
+ nApiBorder = AwtVisualEffect::NONE;
+ break;
+ /* Scroll bar and spin button have a "Border" property, but it is
+ really used for a border, and not for own 3D/flat look (#i34712#). */
+ case FormCompType::SCROLLBAR:
+ case FormCompType::SPINBUTTON:
+ nApiButton = AwtVisualEffect::LOOK3D;
+ nApiBorder = AwtVisualEffect::NONE;
+ break;
+ // Group box does not support flat style (#i34712#)
+ case FormCompType::GROUPBOX:
+ nApiBorder = AwtVisualEffect::LOOK3D;
+ break;
+ }
+ mbFlatButton = nApiButton != AwtVisualEffect::LOOK3D;
+ mbFlatBorder = nApiBorder != AwtVisualEffect::LOOK3D;
+
+ // control state
+ sal_Int16 nApiState = 0;
+ if( aCtrlProp.GetProperty( nApiState, CREATE_OUSTRING( "State" ) ) )
+ {
+ switch( nApiState )
+ {
+ case 0: mnState = EXC_OBJ_CHECKBOX_UNCHECKED; break;
+ case 1: mnState = EXC_OBJ_CHECKBOX_CHECKED; break;
+ case 2: mnState = EXC_OBJ_CHECKBOX_TRISTATE; break;
+ }
+ }
+
+ // special control contents
+ switch( nClassId )
+ {
+ case FormCompType::LISTBOX:
+ {
+ mbMultiSel = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "MultiSelection" ) );
+ Sequence< sal_Int16 > aSelection;
+ if( aCtrlProp.GetProperty( aSelection, CREATE_OUSTRING( "SelectedItems" ) ) )
+ {
+ sal_Int32 nLen = aSelection.getLength();
+ if( nLen > 0 )
+ {
+ mnSelEntry = aSelection[ 0 ] + 1;
+ maMultiSel.resize( nLen );
+ const sal_Int16* pnBegin = aSelection.getConstArray();
+ ::std::copy( pnBegin, pnBegin + nLen, maMultiSel.begin() );
+ }
+ }
+
+ // convert listbox with dropdown button to Excel dropdown
+ if( aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Dropdown" ) ) )
+ mnObjType = EXC_OBJTYPE_DROPDOWN;
+ }
+ break;
+
+ case FormCompType::COMBOBOX:
+ {
+ Sequence< OUString > aStringList;
+ OUString aDefText;
+ if( aCtrlProp.GetProperty( aStringList, CREATE_OUSTRING( "StringItemList" ) ) &&
+ aCtrlProp.GetProperty( aDefText, CREATE_OUSTRING( "Text" ) ) &&
+ aStringList.getLength() && aDefText.getLength() )
+ {
+ const OUString* pBegin = aStringList.getConstArray();
+ const OUString* pEnd = pBegin + aStringList.getLength();
+ const OUString* pString = ::std::find( pBegin, pEnd, aDefText );
+ if( pString != pEnd )
+ mnSelEntry = static_cast< sal_Int16 >( pString - pBegin + 1 ); // 1-based
+ if( mnSelEntry > 0 )
+ maMultiSel.resize( 1, mnSelEntry - 1 );
+ }
+
+ // convert combobox without dropdown button to Excel listbox
+ if( !aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Dropdown" ) ) )
+ mnObjType = EXC_OBJTYPE_LISTBOX;
+ }
+ break;
+
+ case FormCompType::SCROLLBAR:
+ {
+ sal_Int32 nApiValue = 0;
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "ScrollValueMin" ) ) )
+ mnScrollMin = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "ScrollValueMax" ) ) )
+ mnScrollMax = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, EXC_OBJ_SCROLLBAR_MIN );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "ScrollValue" ) ) )
+ mnScrollValue = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, mnScrollMax );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "LineIncrement" ) ) )
+ mnScrollStep = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "BlockIncrement" ) ) )
+ mnScrollPage = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "Orientation" ) ) )
+ mbScrollHor = nApiValue == AwtScrollOrient::HORIZONTAL;
+ }
+ break;
+
+ case FormCompType::SPINBUTTON:
+ {
+ sal_Int32 nApiValue = 0;
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinValueMin" ) ) )
+ mnScrollMin = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinValueMax" ) ) )
+ mnScrollMax = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinValue" ) ) )
+ mnScrollValue = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, mnScrollMax );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinIncrement" ) ) )
+ mnScrollStep = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "Orientation" ) ) )
+ mbScrollHor = nApiValue == AwtScrollOrient::HORIZONTAL;
+ }
+ break;
+ }
+
+ // spreadsheet links
+ ConvertSheetLinks( xShape );
+}
+
+bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor& rEvent )
+{
+ String aMacroName = XclControlHelper::ExtractFromMacroDescriptor( rEvent, meEventType );
+ if( aMacroName.Len() )
+ {
+ sal_uInt16 nExtSheet = GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC );
+ sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( aMacroName, true, false );
+ mxMacroLink = GetFormulaCompiler().CreateNameXFormula( nExtSheet, nNameIdx );
+ return true;
+ }
+ return false;
+}
+
+void XclExpTbxControlObj::WriteSubRecs( XclExpStream& rStrm )
+{
+ switch( mnObjType )
+ {
+ // *** Push buttons, labels ***
+
+ case EXC_OBJTYPE_BUTTON:
+ case EXC_OBJTYPE_LABEL:
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ break;
+
+ // *** Check boxes, option buttons ***
+
+ case EXC_OBJTYPE_CHECKBOX:
+ case EXC_OBJTYPE_OPTIONBUTTON:
+ {
+ // ftCbls - box properties
+ sal_uInt16 nStyle = 0;
+ ::set_flag( nStyle, EXC_OBJ_CHECKBOX_FLAT, mbFlatButton );
+
+ rStrm.StartRecord( EXC_ID_OBJCBLS, 12 );
+ rStrm << mnState;
+ rStrm.WriteZeroBytes( 8 );
+ rStrm << nStyle;
+ rStrm.EndRecord();
+
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ // ftCblsFmla subrecord - cell link
+ WriteCellLinkSubRec( rStrm, EXC_ID_OBJCBLSFMLA );
+
+ // ftCblsData subrecord - box properties, again
+ rStrm.StartRecord( EXC_ID_OBJCBLS, 8 );
+ rStrm << mnState;
+ rStrm.WriteZeroBytes( 4 );
+ rStrm << nStyle;
+ rStrm.EndRecord();
+ }
+ break;
+
+ // *** List boxes, combo boxes ***
+
+ case EXC_OBJTYPE_LISTBOX:
+ case EXC_OBJTYPE_DROPDOWN:
+ {
+ sal_uInt16 nEntryCount = GetSourceEntryCount();
+
+ // ftSbs subrecord - Scroll bars
+ sal_Int32 nLineHeight = XclTools::GetHmmFromTwips( 200 ); // always 10pt
+ if( mnObjType == EXC_OBJTYPE_LISTBOX )
+ mnLineCount = static_cast< sal_uInt16 >( mnHeight / nLineHeight );
+ mnScrollValue = 0;
+ mnScrollMin = 0;
+ sal_uInt16 nInvisLines = (nEntryCount >= mnLineCount) ? (nEntryCount - mnLineCount) : 0;
+ mnScrollMax = limit_cast< sal_uInt16 >( nInvisLines, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ mnScrollStep = 1;
+ mnScrollPage = limit_cast< sal_uInt16 >( mnLineCount, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ mbScrollHor = false;
+ WriteSbs( rStrm );
+
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ // ftSbsFmla subrecord - cell link
+ WriteCellLinkSubRec( rStrm, EXC_ID_OBJSBSFMLA );
+
+ // ftLbsData - source data range and box properties
+ sal_uInt16 nStyle = 0;
+ ::insert_value( nStyle, mbMultiSel ? EXC_OBJ_LISTBOX_MULTI : EXC_OBJ_LISTBOX_SINGLE, 4, 2 );
+ ::set_flag( nStyle, EXC_OBJ_LISTBOX_FLAT, mbFlatBorder );
+
+ rStrm.StartRecord( EXC_ID_OBJLBSDATA, 0 );
+
+ if( const XclTokenArray* pSrcRange = GetSourceRangeTokArr() )
+ {
+ rStrm << static_cast< sal_uInt16 >( (pSrcRange->GetSize() + 7) & 0xFFFE );
+ WriteFormula( rStrm, *pSrcRange );
+ }
+ else
+ rStrm << sal_uInt16( 0 );
+
+ rStrm << nEntryCount << mnSelEntry << nStyle << sal_uInt16( 0 );
+ if( mnObjType == EXC_OBJTYPE_LISTBOX )
+ {
+ if( nEntryCount )
+ {
+ ScfUInt8Vec aSelEx( nEntryCount, 0 );
+ for( ScfInt16Vec::const_iterator aIt = maMultiSel.begin(), aEnd = maMultiSel.end(); aIt != aEnd; ++aIt )
+ if( *aIt < nEntryCount )
+ aSelEx[ *aIt ] = 1;
+ rStrm.Write( &aSelEx[ 0 ], aSelEx.size() );
+ }
+ }
+ else if( mnObjType == EXC_OBJTYPE_DROPDOWN )
+ {
+ rStrm << sal_uInt16( 0 ) << mnLineCount << sal_uInt16( 0 ) << sal_uInt16( 0 );
+ }
+
+ rStrm.EndRecord();
+ }
+ break;
+
+ // *** Spin buttons, scrollbars ***
+
+ case EXC_OBJTYPE_SPIN:
+ case EXC_OBJTYPE_SCROLLBAR:
+ {
+ // ftSbs subrecord - scroll bars
+ WriteSbs( rStrm );
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ // ftSbsFmla subrecord - cell link
+ WriteCellLinkSubRec( rStrm, EXC_ID_OBJSBSFMLA );
+ }
+ break;
+
+ // *** Group boxes ***
+
+ case EXC_OBJTYPE_GROUPBOX:
+ {
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+
+ // ftGboData subrecord - group box properties
+ sal_uInt16 nStyle = 0;
+ ::set_flag( nStyle, EXC_OBJ_GROUPBOX_FLAT, mbFlatBorder );
+
+ rStrm.StartRecord( EXC_ID_OBJGBODATA, 6 );
+ rStrm << sal_uInt32( 0 )
+ << nStyle;
+ rStrm.EndRecord();
+ }
+ break;
+ }
+}
+
+void XclExpTbxControlObj::WriteMacroSubRec( XclExpStream& rStrm )
+{
+ if( mxMacroLink.is() )
+ WriteFormulaSubRec( rStrm, EXC_ID_OBJMACRO, *mxMacroLink );
+}
+
+void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId )
+{
+ if( const XclTokenArray* pCellLink = GetCellLinkTokArr() )
+ WriteFormulaSubRec( rStrm, nSubRecId, *pCellLink );
+}
+
+void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm )
+{
+ sal_uInt16 nOrient = 0;
+ ::set_flag( nOrient, EXC_OBJ_SCROLLBAR_HOR, mbScrollHor );
+ sal_uInt16 nStyle = EXC_OBJ_SCROLLBAR_DEFFLAGS;
+ ::set_flag( nStyle, EXC_OBJ_SCROLLBAR_FLAT, mbFlatButton );
+
+ rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
+ rStrm << sal_uInt32( 0 ) // reserved
+ << mnScrollValue // thumb position
+ << mnScrollMin // thumb min pos
+ << mnScrollMax // thumb max pos
+ << mnScrollStep // line increment
+ << mnScrollPage // page increment
+ << nOrient // 0 = vertical, 1 = horizontal
+ << sal_uInt16( 15 ) // thumb width
+ << nStyle; // flags/style
+ rStrm.EndRecord();
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+
+XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_CHART ),
+ XclExpRoot( rObjMgr.GetRoot() )
+{
+ // create the MSODRAWING record contents for the chart object
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ EscherPropertyContainer aPropOpt;
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 );
+ aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x0800004E );
+ aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x0800004D );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 );
+ aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x0800004D );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 );
+ aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00020000 );
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 );
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ // anchor
+ SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape );
+ ImplWriteAnchor( GetRoot(), pSdrObj, pChildAnchor );
+
+ // client data (the following OBJ record)
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData );
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ // load the chart OLE object
+ if( SdrOle2Obj* pSdrOleObj = dynamic_cast< SdrOle2Obj* >( pSdrObj ) )
+ svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj->GetObjRef() );
+
+ // create the chart substream object
+ ScfPropertySet aShapeProp( xShape );
+ Reference< XModel > xModel;
+ aShapeProp.GetProperty( xModel, CREATE_OUSTRING( "Model" ) );
+ ::com::sun::star::awt::Rectangle aBoundRect;
+ aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) );
+ Rectangle aChartRect( Point( aBoundRect.X, aBoundRect.Y ), Size( aBoundRect.Width, aBoundRect.Height ) );
+ mxChart.reset( new XclExpChart( GetRoot(), xModel, aChartRect ) );
+}
+
+XclExpChartObj::~XclExpChartObj()
+{
+}
+
+void XclExpChartObj::Save( XclExpStream& rStrm )
+{
+ // content of OBJ record
+ XclObj::Save( rStrm );
+ // chart substream
+ mxChart->Save( rStrm );
+}
+
+// ============================================================================
+
+XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
+ const ScPostIt* pScNote, const String& rAddText ) :
+ XclExpRecord( EXC_ID_NOTE ),
+ maScPos( rScPos ),
+ mnObjId( EXC_OBJ_INVALID_ID ),
+ mbVisible( pScNote && pScNote->IsCaptionShown() )
+{
+ // get the main note text
+ String aNoteText;
+ if( pScNote )
+ aNoteText = pScNote->GetText();
+ // append additional text
+ ScGlobal::AddToken( aNoteText, rAddText, '\n', 2 );
+ maOrigNoteText = aNoteText;
+
+ // initialize record dependent on BIFF type
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF5:
+ maNoteText = ByteString( aNoteText, rRoot.GetTextEncoding() );
+ break;
+
+ case EXC_BIFF8:
+ {
+ // TODO: additional text
+ if( pScNote )
+ if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) )
+ if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
+ mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) );
+
+ SetRecSize( 9 + maAuthor.GetSize() );
+ }
+ break;
+
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpNote::Save( XclExpStream& rStrm )
+{
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF5:
+ {
+ // write the NOTE record directly, there may be the need to create more than one
+ const sal_Char* pcBuffer = maNoteText.GetBuffer();
+ sal_uInt16 nCharsLeft = static_cast< sal_uInt16 >( maNoteText.Len() );
+
+ while( nCharsLeft )
+ {
+ sal_uInt16 nWriteChars = ::std::min( nCharsLeft, EXC_NOTE5_MAXLEN );
+
+ rStrm.StartRecord( EXC_ID_NOTE, 6 + nWriteChars );
+ if( pcBuffer == maNoteText.GetBuffer() )
+ {
+ // first record: row, col, length of complete text
+ rStrm << static_cast< sal_uInt16 >( maScPos.Row() )
+ << static_cast< sal_uInt16 >( maScPos.Col() )
+ << nCharsLeft; // still contains full length
+ }
+ else
+ {
+ // next records: -1, 0, length of current text segment
+ rStrm << sal_uInt16( 0xFFFF )
+ << sal_uInt16( 0 )
+ << nWriteChars;
+ }
+ rStrm.Write( pcBuffer, nWriteChars );
+ rStrm.EndRecord();
+
+ pcBuffer += nWriteChars;
+ nCharsLeft = nCharsLeft - nWriteChars;
+ }
+ }
+ break;
+
+ case EXC_BIFF8:
+ if( mnObjId != EXC_OBJ_INVALID_ID )
+ XclExpRecord::Save( rStrm );
+ break;
+
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpNote::WriteBody( XclExpStream& rStrm )
+{
+ // BIFF5/BIFF7 is written separately
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
+
+ sal_uInt16 nFlags = 0;
+ ::set_flag( nFlags, EXC_NOTE_VISIBLE, mbVisible );
+
+ rStrm << static_cast< sal_uInt16 >( maScPos.Row() )
+ << static_cast< sal_uInt16 >( maScPos.Col() )
+ << nFlags
+ << mnObjId
+ << maAuthor
+ << sal_uInt8( 0 );
+}
+
+void XclExpNote::WriteXml( sal_Int32 nAuthorId, XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr rComments = rStrm.GetCurrentStream();
+
+ rComments->startElement( XML_comment,
+ XML_ref, XclXmlUtils::ToOString( maScPos ).getStr(),
+ XML_authorId, OString::valueOf( nAuthorId ).getStr(),
+ // OOXTODO: XML_guid,
+ FSEND );
+ rComments->startElement( XML_text, FSEND );
+ // OOXTODO: phoneticPr, rPh, r
+ rComments->startElement( XML_t, FSEND );
+ rComments->writeEscaped( XclXmlUtils::ToOUString( maOrigNoteText ) );
+ rComments->endElement ( XML_t );
+ rComments->endElement( XML_text );
+ rComments->endElement( XML_comment );
+}
+
+// ============================================================================
+
+XclExpComments::XclExpComments( SCTAB nTab, XclExpRecordList< XclExpNote >& rNotes )
+ : mnTab( nTab ), mrNotes( rNotes )
+{
+}
+
+struct OUStringLess : public std::binary_function<OUString, OUString, bool>
+{
+ bool operator()(const OUString& x, const OUString& y) const
+ {
+ return x.compareTo( y ) <= 0;
+ }
+};
+
+void XclExpComments::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mrNotes.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr rComments = rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "comments", mnTab + 1 ),
+ XclXmlUtils::GetStreamName( "../", "comments", mnTab + 1 ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
+ rStrm.PushStream( rComments );
+
+ rComments->startElement( XML_comments,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSEND );
+ rComments->startElement( XML_authors, FSEND );
+
+ typedef std::set< OUString, OUStringLess > Authors;
+ Authors aAuthors;
+
+ size_t nNotes = mrNotes.GetSize();
+ for( size_t i = 0; i < nNotes; ++i )
+ {
+ aAuthors.insert( XclXmlUtils::ToOUString( mrNotes.GetRecord( i )->GetAuthor() ) );
+ }
+
+ for( Authors::const_iterator b = aAuthors.begin(), e = aAuthors.end(); b != e; ++b )
+ {
+ rComments->startElement( XML_author, FSEND );
+ rComments->writeEscaped( *b );
+ rComments->endElement( XML_author );
+ }
+
+ rComments->endElement( XML_authors );
+ rComments->startElement( XML_commentList, FSEND );
+
+ for( size_t i = 0; i < nNotes; ++i )
+ {
+ XclExpNoteList::RecordRefType xNote = mrNotes.GetRecord( i );
+ Authors::const_iterator aAuthor = aAuthors.find(
+ XclXmlUtils::ToOUString( xNote->GetAuthor() ) );
+ sal_Int32 nAuthorId = distance( aAuthors.begin(), aAuthor );
+ xNote->WriteXml( nAuthorId, rStrm );
+ }
+
+ rComments->endElement( XML_commentList );
+ rComments->endElement( XML_comments );
+
+ rStrm.PopStream();
+}
+
+// object manager =============================================================
+
+XclExpObjectManager::XclExpObjectManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ InitStream( true );
+ mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm ) );
+}
+
+XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager& rParent ) :
+ XclExpRoot( rParent.GetRoot() )
+{
+ InitStream( false );
+ mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm, rParent.mxEscherEx.get() ) );
+}
+
+XclExpObjectManager::~XclExpObjectManager()
+{
+}
+
+XclExpDffAnchorBase* XclExpObjectManager::CreateDffAnchor() const
+{
+ return new XclExpDffSheetAnchor( GetRoot() );
+}
+
+ScfRef< XclExpRecordBase > XclExpObjectManager::CreateDrawingGroup()
+{
+ return ScfRef< XclExpRecordBase >( new XclExpMsoDrawingGroup( *mxEscherEx ) );
+}
+
+void XclExpObjectManager::StartSheet()
+{
+ mxObjList.reset( new XclExpObjList( GetRoot(), *mxEscherEx ) );
+}
+
+ScfRef< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( SdrPage* pSdrPage )
+{
+ if( pSdrPage )
+ mxEscherEx->AddSdrPage( *pSdrPage );
+ // #106213# the first dummy object may still be open
+ DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
+ while( mxEscherEx->GetGroupLevel() )
+ mxEscherEx->LeaveGroup();
+ mxObjList->EndSheet();
+ return mxObjList;
+}
+
+ScfRef< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( const Reference< XShapes >& rxShapes )
+{
+ if( rxShapes.is() )
+ mxEscherEx->AddUnoShapes( rxShapes );
+ // #106213# the first dummy object may still be open
+ DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
+ while( mxEscherEx->GetGroupLevel() )
+ mxEscherEx->LeaveGroup();
+ mxObjList->EndSheet();
+ return mxObjList;
+}
+
+void XclExpObjectManager::EndDocument()
+{
+ mxEscherEx->EndDocument();
+}
+
+XclExpMsoDrawing* XclExpObjectManager::GetMsodrawingPerSheet()
+{
+ return mxObjList->GetMsodrawingPerSheet();
+}
+
+bool XclExpObjectManager::HasObj() const
+{
+ return mxObjList->Count() > 0;
+}
+
+sal_uInt16 XclExpObjectManager::AddObj( XclObj* pObjRec )
+{
+ return mxObjList->Add( pObjRec );
+}
+
+XclObj* XclExpObjectManager::RemoveLastObj()
+{
+ XclObj* pLastObj = static_cast< XclObj* >( mxObjList->Last() );
+ mxObjList->Remove(); // remove current, which is the Last()
+ return pLastObj;
+}
+
+void XclExpObjectManager::InitStream( bool bTempFile )
+{
+ if( bTempFile )
+ {
+ mxTempFile.reset( new ::utl::TempFile );
+ if( mxTempFile->IsValid() )
+ {
+ mxTempFile->EnableKillingFile();
+ mxDffStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile->GetURL(), STREAM_STD_READWRITE ) );
+ }
+ }
+
+ if( !mxDffStrm.get() )
+ mxDffStrm.reset( new SvMemoryStream );
+
+ mxDffStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
+ const XclExpObjectManager& rParent, const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) :
+ XclExpObjectManager( rParent ),
+ maPageSize( rPageSize ),
+ mnScaleX( nScaleX ),
+ mnScaleY( nScaleY )
+{
+}
+
+XclExpDffAnchorBase* XclExpEmbeddedObjectManager::CreateDffAnchor() const
+{
+ return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize, mnScaleX, mnScaleY );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
new file mode 100644
index 000000000000..34e48671a3bc
--- /dev/null
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -0,0 +1,2646 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// XXX xelink.hxx MUST be included before xeformula.hxx because of the
+// redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx
+// (indirectly included via xelink.hxx) and ../inc/ftools.hxx (indirectly
+// included via xeformula.hxx) that does an undef first. Ugly.
+#include "xelink.hxx"
+#include "xeformula.hxx"
+
+#include <list>
+#include <map>
+#include <memory>
+#include "addincol.hxx"
+#include "compiler.hxx"
+#include "document.hxx"
+#include "externalrefmgr.hxx"
+#include "rangelst.hxx"
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "xehelper.hxx"
+#include "xename.hxx"
+#include "xestream.hxx"
+
+using namespace ::formula;
+
+// External reference log =====================================================
+
+XclExpRefLogEntry::XclExpRefLogEntry() :
+ mpUrl( 0 ),
+ mpFirstTab( 0 ),
+ mpLastTab( 0 ),
+ mnFirstXclTab( EXC_TAB_DELETED ),
+ mnLastXclTab( EXC_TAB_DELETED )
+{
+}
+
+// Formula compiler ===========================================================
+
+namespace {
+
+/** Wrapper structure for a processed Calc formula token with additional
+ settings (whitespaces). */
+struct XclExpScToken
+{
+ const FormulaToken* mpScToken; /// Currently processed Calc token.
+ sal_uInt8 mnSpaces; /// Number of spaces before the Calc token.
+
+ inline explicit XclExpScToken() : mpScToken( 0 ), mnSpaces( 0 ) {}
+ inline bool Is() const { return mpScToken != 0; }
+ inline StackVar GetType() const { return mpScToken ? mpScToken->GetType() : static_cast< StackVar >( svUnknown ); }
+ inline OpCode GetOpCode() const { return mpScToken ? mpScToken->GetOpCode() : static_cast< OpCode >( ocNone ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Effective token class conversion types. */
+enum XclExpClassConv
+{
+ EXC_CLASSCONV_ORG, /// Keep original class of the token.
+ EXC_CLASSCONV_VAL, /// Convert ARR tokens to VAL class (REF remains uncahnged).
+ EXC_CLASSCONV_ARR /// Convert VAL tokens to ARR class (REF remains uncahnged).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Token class conversion and position of a token in the token array. */
+struct XclExpTokenConvInfo
+{
+ sal_uInt16 mnTokPos; /// Position of the token in the token array.
+ XclFuncParamConv meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
+};
+
+/** Vector of token position and conversion for all operands of an operator,
+ or for all parameters of a function. */
+struct XclExpOperandList : public ::std::vector< XclExpTokenConvInfo >
+{
+ inline explicit XclExpOperandList() { reserve( 2 ); }
+ void AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType );
+};
+
+void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType )
+{
+ resize( size() + 1 );
+ XclExpTokenConvInfo& rConvInfo = back();
+ rConvInfo.mnTokPos = nTokPos;
+ rConvInfo.meConv = eConv;
+ rConvInfo.mbValType = bValType;
+}
+
+typedef ScfRef< XclExpOperandList > XclExpOperandListRef;
+typedef ::std::vector< XclExpOperandListRef > XclExpOperandListVector;
+
+// ----------------------------------------------------------------------------
+
+/** Encapsulates all data needed for a call to an external function (macro, add-in). */
+struct XclExpExtFuncData
+{
+ String maFuncName; /// Name of the function.
+ bool mbVBasic; /// True = Visual Basic macro call.
+ bool mbHidden; /// True = Create hidden defined name.
+
+ inline explicit XclExpExtFuncData() : mbVBasic( false ), mbHidden( false ) {}
+ void Set( const String& rFuncName, bool bVBasic, bool bHidden );
+};
+
+void XclExpExtFuncData::Set( const String& rFuncName, bool bVBasic, bool bHidden )
+{
+ maFuncName = rFuncName;
+ mbVBasic = bVBasic;
+ mbHidden = bHidden;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Encapsulates all data needed to process an entire function. */
+class XclExpFuncData
+{
+public:
+ explicit XclExpFuncData(
+ const XclExpScToken& rTokData,
+ const XclFunctionInfo& rFuncInfo,
+ const XclExpExtFuncData& rExtFuncData );
+
+ inline const FormulaToken& GetScToken() const { return *mrTokData.mpScToken; }
+ inline OpCode GetOpCode() const { return mrFuncInfo.meOpCode; }
+ inline sal_uInt16 GetXclFuncIdx() const { return mrFuncInfo.mnXclFunc; }
+ inline bool IsVolatile() const { return mrFuncInfo.IsVolatile(); }
+ inline bool IsFixedParamCount() const { return mrFuncInfo.IsFixedParamCount(); }
+ inline bool IsMacroFunc() const { return mrFuncInfo.IsMacroFunc(); }
+ inline sal_uInt8 GetSpaces() const { return mrTokData.mnSpaces; }
+ inline const XclExpExtFuncData& GetExtFuncData() const { return maExtFuncData; }
+ inline sal_uInt8 GetReturnClass() const { return mrFuncInfo.mnRetClass; }
+
+ const XclFuncParamInfo& GetParamInfo() const;
+ bool IsCalcOnlyParam() const;
+ bool IsExcelOnlyParam() const;
+ void IncParamInfoIdx();
+
+ inline sal_uInt8 GetMinParamCount() const { return mrFuncInfo.mnMinParamCount; }
+ inline sal_uInt8 GetMaxParamCount() const { return mrFuncInfo.mnMaxParamCount; }
+ inline sal_uInt8 GetParamCount() const { return static_cast< sal_uInt8 >( mxOperands->size() ); }
+ void FinishParam( sal_uInt16 nTokPos );
+ inline XclExpOperandListRef GetOperandList() const { return mxOperands; }
+
+ inline ScfUInt16Vec& GetAttrPosVec() { return maAttrPosVec; }
+ inline void AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
+
+private:
+ ScfUInt16Vec maAttrPosVec; /// Token array positions of tAttr tokens.
+ const XclExpScToken& mrTokData; /// Data about processed function name token.
+ const XclFunctionInfo& mrFuncInfo; /// Constant data about processed function.
+ XclExpExtFuncData maExtFuncData; /// Data for external functions (macro, add-in).
+ XclExpOperandListRef mxOperands; /// Class conversion and position of all parameters.
+ const XclFuncParamInfo* mpParamInfo; /// Information for current parameter.
+};
+
+XclExpFuncData::XclExpFuncData( const XclExpScToken& rTokData,
+ const XclFunctionInfo& rFuncInfo, const XclExpExtFuncData& rExtFuncData ) :
+ mrTokData( rTokData ),
+ mrFuncInfo( rFuncInfo ),
+ maExtFuncData( rExtFuncData ),
+ mxOperands( new XclExpOperandList ),
+ mpParamInfo( rFuncInfo.mpParamInfos )
+{
+ DBG_ASSERT( mrTokData.mpScToken, "XclExpFuncData::XclExpFuncData - missing core token" );
+ // set name of an add-in function
+ if( (maExtFuncData.maFuncName.Len() == 0) && dynamic_cast< const FormulaExternalToken* >( mrTokData.mpScToken ) )
+ maExtFuncData.Set( GetScToken().GetExternal(), true, false );
+}
+
+const XclFuncParamInfo& XclExpFuncData::GetParamInfo() const
+{
+ static const XclFuncParamInfo saInvalidInfo = { EXC_PARAM_NONE, EXC_PARAMCONV_ORG, false };
+ return mpParamInfo ? *mpParamInfo : saInvalidInfo;
+}
+
+bool XclExpFuncData::IsCalcOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_CALCONLY);
+}
+
+bool XclExpFuncData::IsExcelOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_EXCELONLY);
+}
+
+void XclExpFuncData::IncParamInfoIdx()
+{
+ if( mpParamInfo )
+ {
+ // move pointer to next entry, if something explicit follows
+ if( (static_cast<size_t>(mpParamInfo - mrFuncInfo.mpParamInfos + 1) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
+ ++mpParamInfo;
+ // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
+ else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
+ mpParamInfo = 0;
+ // otherwise: repeat last parameter class
+ }
+}
+
+void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
+{
+ // write token class conversion info for this parameter
+ const XclFuncParamInfo& rParamInfo = GetParamInfo();
+ mxOperands->AppendOperand( nTokPos, rParamInfo.meConv, rParamInfo.mbValType );
+ // move to next parameter info structure
+ IncParamInfoIdx();
+}
+
+// compiler configuration -----------------------------------------------------
+
+/** Type of token class handling. */
+enum XclExpFmlaClassType
+{
+ EXC_CLASSTYPE_CELL, /// Cell formula, shared formula.
+ EXC_CLASSTYPE_ARRAY, /// Array formula, conditional formatting, data validation.
+ EXC_CLASSTYPE_NAME /// Defined name, range list.
+};
+
+/** Configuration data of the formula compiler. */
+struct XclExpCompConfig
+{
+ XclFormulaType meType; /// Type of the formula to be created.
+ XclExpFmlaClassType meClassType; /// Token class handling type.
+ bool mbLocalLinkMgr; /// True = local (per-sheet) link manager, false = global.
+ bool mbFromCell; /// True = Any kind of cell formula (cell, array, shared).
+ bool mb3DRefOnly; /// True = Only 3D references allowed (e.g. names).
+ bool mbAllowArrays; /// True = Allow inline arrays.
+};
+
+/** The table containing configuration data for all formula types. */
+static const XclExpCompConfig spConfigTable[] =
+{
+ // formula type token class type lclLM inCell 3dOnly allowArray
+ { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, true, true, false, true },
+ { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, true, true, false, true },
+ { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, true, true, false, true },
+ { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, true, false, false, false },
+ { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, true, false, false, false },
+ { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, false, false, true, true },
+ { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, true, false, true, true },
+ { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, true, false, false, false },
+ { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, true, false, true, false },
+ { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, true, false, false, false }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Working data of the formula compiler. Used to push onto a stack for recursive calls. */
+struct XclExpCompData
+{
+ typedef ScfRef< ScTokenArray > ScTokenArrayRef;
+
+ const XclExpCompConfig& mrCfg; /// Configuration for current formula type.
+ ScTokenArrayRef mxOwnScTokArr; /// Own clone of a Calc token array.
+ XclTokenArrayIterator maTokArrIt; /// Iterator in Calc token array.
+ XclExpLinkManager* mpLinkMgr; /// Link manager for current context (local/global).
+ XclExpRefLog* mpRefLog; /// Log for external references.
+ const ScAddress* mpScBasePos; /// Current cell position of the formula.
+
+ ScfUInt8Vec maTokVec; /// Byte vector containing token data.
+ ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
+ XclExpOperandListVector maOpListVec; /// Formula structure, maps operators to their operands.
+ ScfUInt16Vec maOpPosStack; /// Stack with positions of operand tokens waiting for an operator.
+ bool mbStopAtSep; /// True = Stop subexpression creation at an ocSep token.
+ bool mbVolatile; /// True = Formula contains volatile function.
+ bool mbOk; /// Current state of the compiler.
+
+ explicit XclExpCompData( const XclExpCompConfig* pCfg );
+};
+
+XclExpCompData::XclExpCompData( const XclExpCompConfig* pCfg ) :
+ mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
+ mpLinkMgr( 0 ),
+ mpRefLog( 0 ),
+ mpScBasePos( 0 ),
+ mbStopAtSep( false ),
+ mbVolatile( false ),
+ mbOk( pCfg != 0 )
+{
+ DBG_ASSERT( pCfg, "XclExpFmlaCompImpl::Init - unknown formula type" );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+/** Implementation class of the export formula compiler. */
+class XclExpFmlaCompImpl : protected XclExpRoot, protected XclTokenArrayHelper
+{
+public:
+ explicit XclExpFmlaCompImpl( const XclExpRoot& rRoot );
+
+ /** Creates an Excel token array from the passed Calc token array. */
+ XclTokenArrayRef CreateFormula(
+ XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos = 0, XclExpRefLog* pRefLog = 0 );
+ /** Creates a single error token containing the passed error code. */
+ XclTokenArrayRef CreateErrorFormula( sal_uInt8 nErrCode );
+ /** Creates a single token for a special cell reference. */
+ XclTokenArrayRef CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos );
+ /** Creates a single tNameXR token for a reference to an external name. */
+ XclTokenArrayRef CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName );
+
+ /** Returns true, if the passed formula type allows 3D references only. */
+ bool Is3DRefOnly( XclFormulaType eType ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ const XclExpCompConfig* GetConfigForType( XclFormulaType eType ) const;
+ inline sal_uInt16 GetSize() const { return static_cast< sal_uInt16 >( mxData->maTokVec.size() ); }
+
+ void Init( XclFormulaType eType );
+ void Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos, XclExpRefLog* pRefLog );
+
+ void RecalcTokenClasses();
+ void RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass );
+
+ void FinalizeFormula();
+ XclTokenArrayRef CreateTokenArray();
+
+ // compiler ---------------------------------------------------------------
+ // XclExpScToken: pass-by-value and return-by-value is intended
+
+ const FormulaToken* GetNextRawToken();
+ const FormulaToken* PeekNextRawToken( bool bSkipSpaces ) const;
+
+ bool GetNextToken( XclExpScToken& rTokData );
+ XclExpScToken GetNextToken();
+
+ XclExpScToken Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep );
+ XclExpScToken SkipExpression( XclExpScToken aTokData, bool bStopAtSep );
+
+ XclExpScToken OrTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken AndTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken CompareTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken ConcatTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken AddSubTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken MulDivTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken PowTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken ListTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp );
+ XclExpScToken RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp );
+ XclExpScToken Factor( XclExpScToken aTokData );
+
+ // formula structure ------------------------------------------------------
+
+ void ProcessDouble( const XclExpScToken& rTokData );
+ void ProcessString( const XclExpScToken& rTokData );
+ void ProcessError( const XclExpScToken& rTokData );
+ void ProcessMissing( const XclExpScToken& rTokData );
+ void ProcessBad( const XclExpScToken& rTokData );
+ void ProcessParentheses( const XclExpScToken& rTokData );
+ void ProcessBoolean( const XclExpScToken& rTokData );
+ void ProcessDdeLink( const XclExpScToken& rTokData );
+ void ProcessExternal( const XclExpScToken& rTokData );
+ void ProcessMatrix( const XclExpScToken& rTokData );
+
+ void ProcessFunction( const XclExpScToken& rTokData );
+ void PrepareFunction( XclExpFuncData& rFuncData );
+ void FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces );
+ void FinishIfFunction( XclExpFuncData& rFuncData );
+ void FinishChooseFunction( XclExpFuncData& rFuncData );
+
+ XclExpScToken ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
+ void PrepareParam( XclExpFuncData& rFuncData );
+ void FinishParam( XclExpFuncData& rFuncData );
+ void AppendDefaultParam( XclExpFuncData& rFuncData );
+ void AppendTrailingParam( XclExpFuncData& rFuncData );
+
+ // reference handling -----------------------------------------------------
+
+ SCTAB GetScTab( const ScSingleRefData& rRefData ) const;
+ bool IsRef2D( const ScSingleRefData& rRefData ) const;
+ bool IsRef2D( const ScComplexRefData& rRefData ) const;
+
+ void ConvertRefData( ScSingleRefData& rRefData, XclAddress& rXclPos,
+ bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const;
+ void ConvertRefData( ScComplexRefData& rRefData, XclRange& rXclRange,
+ bool bNatLangRef ) const;
+
+ XclExpRefLogEntry* GetNewRefLogEntry();
+ void ProcessCellRef( const XclExpScToken& rTokData );
+ void ProcessRangeRef( const XclExpScToken& rTokData );
+ void ProcessExternalCellRef( const XclExpScToken& rTokData );
+ void ProcessExternalRangeRef( const XclExpScToken& rTokData );
+ void ProcessDefinedName( const XclExpScToken& rTokData );
+ void ProcessExternalName( const XclExpScToken& rTokData );
+ void ProcessDatabaseArea( const XclExpScToken& rTokData );
+
+ // token vector -----------------------------------------------------------
+
+ void PushOperandPos( sal_uInt16 nTokPos );
+ void PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands );
+ sal_uInt16 PopOperandPos();
+
+ void Append( sal_uInt8 nData );
+ void Append( sal_uInt8 nData, size_t nCount );
+ void Append( sal_uInt16 nData );
+ void Append( sal_uInt32 nData );
+ void Append( double fData );
+ void Append( const String& rString );
+
+ void AppendAddress( const XclAddress& rXclPos );
+ void AppendRange( const XclRange& rXclRange );
+
+ void AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount );
+
+ void AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
+ void AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces = 0 );
+ void AppendNumToken( double fValue, sal_uInt8 nSpaces = 0 );
+ void AppendBoolToken( bool bValue, sal_uInt8 nSpaces = 0 );
+ void AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces = 0 );
+ void AppendMissingToken( sal_uInt8 nSpaces = 0 );
+ void AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces = 0 );
+ void AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces = 0 );
+ void AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces = 0 );
+ void AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+ void AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+ void AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+
+ void AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces = 0 );
+ void AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
+ void AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces = 0 );
+ void AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount );
+ void AppendFuncToken( const XclExpFuncData& rFuncData );
+
+ void AppendParenToken( sal_uInt8 nOpenSpaces = 0, sal_uInt8 nCloseSpaces = 0 );
+ void AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType );
+
+ void InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
+ void Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
+
+ void UpdateAttrGoto( sal_uInt16 nAttrPos );
+
+ bool IsSpaceToken( sal_uInt16 nPos ) const;
+ void RemoveTrailingParen();
+
+ void AppendExt( sal_uInt8 nData );
+ void AppendExt( sal_uInt8 nData, size_t nCount );
+ void AppendExt( sal_uInt16 nData );
+ void AppendExt( sal_uInt32 nData );
+ void AppendExt( double fData );
+ void AppendExt( const String& rString );
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap;
+ typedef ScfRef< XclExpCompData > XclExpCompDataRef;
+ typedef ::std::vector< XclExpCompDataRef > XclExpCompDataVector;
+
+ XclExpCompConfigMap maCfgMap; /// Compiler configuration map for all formula types.
+ XclFunctionProvider maFuncProv; /// Excel function data provider.
+ XclExpCompDataRef mxData; /// Working data for current formula.
+ XclExpCompDataVector maDataStack; /// Stack for working data, when compiler is called recursively.
+ const XclBiff meBiff; /// Cached BIFF version to save GetBiff() calls.
+ const SCsCOL mnMaxAbsCol; /// Maximum column index.
+ const SCsROW mnMaxAbsRow; /// Maximum row index.
+ const SCsCOL mnMaxScCol; /// Maximum column index in Calc itself.
+ const SCsROW mnMaxScRow; /// Maximum row index in Calc itself.
+ const sal_uInt16 mnMaxColMask; /// Mask to delete invalid bits in column fields.
+ const sal_uInt16 mnMaxRowMask; /// Mask to delete invalid bits in row fields.
+};
+
+// ----------------------------------------------------------------------------
+
+XclExpFmlaCompImpl::XclExpFmlaCompImpl( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() ),
+ mnMaxAbsCol( static_cast< SCsCOL >( rRoot.GetXclMaxPos().Col() ) ),
+ mnMaxAbsRow( static_cast< SCsROW >( rRoot.GetXclMaxPos().Row() ) ),
+ mnMaxScCol( static_cast< SCsCOL >( rRoot.GetScMaxPos().Col() ) ),
+ mnMaxScRow( static_cast< SCsROW >( rRoot.GetScMaxPos().Row() ) ),
+ mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Col() ) ),
+ mnMaxRowMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Row() ) )
+{
+ // build the configuration map
+ for( const XclExpCompConfig* pEntry = spConfigTable; pEntry != STATIC_TABLE_END( spConfigTable ); ++pEntry )
+ maCfgMap[ pEntry->meType ] = *pEntry;
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateFormula( XclFormulaType eType,
+ const ScTokenArray& rScTokArr, const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
+{
+ // initialize the compiler
+ Init( eType, rScTokArr, pScBasePos, pRefLog );
+
+ // start compilation, if initialization didn't fail
+ if( mxData->mbOk )
+ {
+ XclExpScToken aTokData( GetNextToken() );
+ USHORT nScError = rScTokArr.GetCodeError();
+ if( (nScError != 0) && (!aTokData.Is() || (aTokData.GetOpCode() == ocStop)) )
+ {
+ // #i50253# convert simple ocStop token to error code formula (e.g. =#VALUE!)
+ AppendErrorToken( XclTools::GetXclErrorCode( nScError ), aTokData.mnSpaces );
+ }
+ else if( aTokData.Is() )
+ {
+ aTokData = Expression( aTokData, false, false );
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpFmlaCompImpl::CreateFormula - empty token array" );
+ mxData->mbOk = false;
+ }
+
+ if( mxData->mbOk )
+ {
+ // #i44907# auto-generated SUBTOTAL formula cells have trailing ocStop token
+ mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() == ocStop);
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
+ }
+ }
+
+ // finalize (add tAttrVolatile token, calculate all token classes)
+ RecalcTokenClasses();
+ FinalizeFormula();
+
+ // leave recursive call, create and return the final token array
+ return CreateTokenArray();
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateErrorFormula( sal_uInt8 nErrCode )
+{
+ Init( EXC_FMLATYPE_NAME );
+ AppendErrorToken( nErrCode );
+ return CreateTokenArray();
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos )
+{
+ Init( EXC_FMLATYPE_NAME );
+ AppendOperandTokenId( nTokenId );
+ Append( rXclPos.mnRow );
+ Append( rXclPos.mnCol ); // do not use AppendAddress(), we always need 16-bit column here
+ return CreateTokenArray();
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName )
+{
+ Init( EXC_FMLATYPE_NAME );
+ AppendNameXToken( nExtSheet, nExtName );
+ return CreateTokenArray();
+}
+
+bool XclExpFmlaCompImpl::Is3DRefOnly( XclFormulaType eType ) const
+{
+ const XclExpCompConfig* pCfg = GetConfigForType( eType );
+ return pCfg && pCfg->mb3DRefOnly;
+}
+
+// private --------------------------------------------------------------------
+
+const XclExpCompConfig* XclExpFmlaCompImpl::GetConfigForType( XclFormulaType eType ) const
+{
+ XclExpCompConfigMap::const_iterator aIt = maCfgMap.find( eType );
+ DBG_ASSERT( aIt != maCfgMap.end(), "XclExpFmlaCompImpl::GetConfigForType - unknown formula type" );
+ return (aIt == maCfgMap.end()) ? 0 : &aIt->second;
+}
+
+void XclExpFmlaCompImpl::Init( XclFormulaType eType )
+{
+ // compiler invoked recursively? - store old working data
+ if( mxData.get() )
+ maDataStack.push_back( mxData );
+ // new compiler working data structure
+ mxData.reset( new XclExpCompData( GetConfigForType( eType ) ) );
+}
+
+void XclExpFmlaCompImpl::Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
+{
+ // common initialization
+ Init( eType );
+
+ // special initialization
+ if( mxData->mbOk ) switch( mxData->mrCfg.meType )
+ {
+ case EXC_FMLATYPE_CELL:
+ case EXC_FMLATYPE_MATRIX:
+ case EXC_FMLATYPE_CHART:
+ mxData->mbOk = pScBasePos != 0;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
+ mxData->mpScBasePos = pScBasePos;
+ break;
+ case EXC_FMLATYPE_SHARED:
+ mxData->mbOk = pScBasePos != 0;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
+ // clone the passed token array, convert references relative to current cell position
+ mxData->mxOwnScTokArr.reset( rScTokArr.Clone() );
+ ScCompiler::MoveRelWrap( *mxData->mxOwnScTokArr, GetDocPtr(), *pScBasePos, MAXCOL, MAXROW );
+ // don't remember pScBasePos in mxData->mpScBasePos, shared formulas use real relative refs
+ break;
+ default:;
+ }
+
+ if( mxData->mbOk )
+ {
+ // link manager to be used
+ mxData->mpLinkMgr = mxData->mrCfg.mbLocalLinkMgr ? &GetLocalLinkManager() : &GetGlobalLinkManager();
+
+ // token array iterator (use cloned token array if present)
+ mxData->maTokArrIt.Init( mxData->mxOwnScTokArr.is() ? *mxData->mxOwnScTokArr : rScTokArr, false );
+ mxData->mpRefLog = pRefLog;
+ }
+}
+
+void XclExpFmlaCompImpl::RecalcTokenClasses()
+{
+ if( mxData->mbOk )
+ {
+ mxData->mbOk = mxData->maOpPosStack.size() == 1;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
+ if( mxData->mbOk )
+ {
+ /* Cell and array formulas start with VAL conversion and VALTYPE
+ parameter type, defined names start with ARR conversion and
+ REFTYPE parameter type for the root token. */
+ XclExpOperandList aOperands;
+ bool bNameFmla = mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
+ XclFuncParamConv eParamConv = bNameFmla ? EXC_PARAMCONV_ARR : EXC_PARAMCONV_VAL;
+ XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
+ XclExpTokenConvInfo aConvInfo = { PopOperandPos(), eParamConv, !bNameFmla };
+ RecalcTokenClass( aConvInfo, eParamConv, eClassConv, bNameFmla );
+ }
+
+ // clear operand vectors (calls to the expensive InsertZeros() may follow)
+ mxData->maOpListVec.clear();
+ mxData->maOpPosStack.clear();
+ }
+}
+
+void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo,
+ XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass )
+{
+ DBG_ASSERT( rConvInfo.mnTokPos < GetSize(), "XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
+ sal_uInt8& rnTokenId = mxData->maTokVec[ rConvInfo.mnTokPos ];
+ sal_uInt8 nTokClass = GetTokenClass( rnTokenId );
+
+ // REF tokens in VALTYPE parameters behave like VAL tokens
+ if( rConvInfo.mbValType && (nTokClass == EXC_TOKCLASS_REF) )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
+
+ // replace RPO conversion of operator with parent conversion
+ XclFuncParamConv eConv = (rConvInfo.meConv == EXC_PARAMCONV_RPO) ? ePrevConv : rConvInfo.meConv;
+
+ // find the effective token class conversion to be performed for this token
+ XclExpClassConv eClassConv = EXC_CLASSCONV_ORG;
+ switch( eConv )
+ {
+ case EXC_PARAMCONV_ORG:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_VAL:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_VAL;
+ break;
+ case EXC_PARAMCONV_ARR:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_ARR;
+ break;
+ case EXC_PARAMCONV_RPT:
+ switch( ePrevConv )
+ {
+ case EXC_PARAMCONV_ORG:
+ case EXC_PARAMCONV_VAL:
+ case EXC_PARAMCONV_ARR:
+ /* If parent token has REF class (REF token in REFTYPE
+ function parameter), then RPT does not repeat the
+ previous explicit ORG or ARR conversion, but always
+ falls back to VAL conversion. */
+ eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
+ break;
+ case EXC_PARAMCONV_RPT:
+ // nested RPT repeats the previous effective conversion
+ eClassConv = ePrevClassConv;
+ break;
+ case EXC_PARAMCONV_RPX:
+ /* If parent token has REF class (REF token in REFTYPE
+ function parameter), then RPX repeats the previous
+ effective conversion (wich will be either ORG or ARR,
+ but never VAL), otherwise falls back to ORG conversion. */
+ eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_RPO: // does not occur
+ break;
+ }
+ break;
+ case EXC_PARAMCONV_RPX:
+ /* If current token still has REF class, set previous effective
+ conversion as current conversion. This will not have an effect
+ on the REF token but is needed for RPT parameters of this
+ function that want to repeat this conversion type. If current
+ token is VAL or ARR class, the previous ARR conversion will be
+ repeated on the token, but VAL conversion will not. */
+ eClassConv = ((nTokClass == EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
+ ePrevClassConv : EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_RPO: // does not occur (see above)
+ break;
+ }
+
+ // do the token class conversion
+ switch( eClassConv )
+ {
+ case EXC_CLASSCONV_ORG:
+ /* Cell formulas: leave the current token class. Cell formulas
+ are the only type of formulas where all tokens can keep
+ their original token class.
+ Array and defined name formulas: convert VAL to ARR. */
+ if( (mxData->mrCfg.meClassType != EXC_CLASSTYPE_CELL) && (nTokClass == EXC_TOKCLASS_VAL) )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
+ break;
+ case EXC_CLASSCONV_VAL:
+ // convert ARR to VAL
+ if( nTokClass == EXC_TOKCLASS_ARR )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
+ break;
+ case EXC_CLASSCONV_ARR:
+ // convert VAL to ARR
+ if( nTokClass == EXC_TOKCLASS_VAL )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
+ break;
+ }
+
+ // do conversion for nested operands, if token is an operator or function
+ if( rConvInfo.mnTokPos < mxData->maOpListVec.size() )
+ if( const XclExpOperandList* pOperands = mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
+ for( XclExpOperandList::const_iterator aIt = pOperands->begin(), aEnd = pOperands->end(); aIt != aEnd; ++aIt )
+ RecalcTokenClass( *aIt, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF );
+}
+
+void XclExpFmlaCompImpl::FinalizeFormula()
+{
+ if( mxData->mbOk )
+ {
+ // Volatile? Add a tAttrVolatile token at the beginning of the token array.
+ if( mxData->mbVolatile )
+ {
+ // tAttrSpace token can be extended with volatile flag
+ if( !IsSpaceToken( 0 ) )
+ {
+ InsertZeros( 0, 4 );
+ mxData->maTokVec[ 0 ] = EXC_TOKID_ATTR;
+ }
+ mxData->maTokVec[ 1 ] |= EXC_TOK_ATTR_VOLATILE;
+ }
+
+ // Token array too long? -> error
+ mxData->mbOk = mxData->maTokVec.size() <= EXC_TOKARR_MAXLEN;
+ }
+
+ if( !mxData->mbOk )
+ {
+ // Any unrecoverable error? -> Create a =#NA formula.
+ mxData->maTokVec.clear();
+ mxData->maExtDataVec.clear();
+ mxData->mbVolatile = false;
+ AppendErrorToken( EXC_ERR_NA );
+ }
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray()
+{
+ // create the Excel token array from working data before resetting mxData
+ DBG_ASSERT( mxData->mrCfg.mbAllowArrays || mxData->maExtDataVec.empty(), "XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
+ if( !mxData->mrCfg.mbAllowArrays )
+ mxData->maExtDataVec.clear();
+ XclTokenArrayRef xTokArr( new XclTokenArray( mxData->maTokVec, mxData->maExtDataVec, mxData->mbVolatile ) );
+ mxData.reset();
+
+ // compiler invoked recursively? - restore old working data
+ if( !maDataStack.empty() )
+ {
+ mxData = maDataStack.back();
+ maDataStack.pop_back();
+ }
+
+ return xTokArr;
+}
+
+// compiler -------------------------------------------------------------------
+
+const FormulaToken* XclExpFmlaCompImpl::GetNextRawToken()
+{
+ const FormulaToken* pScToken = mxData->maTokArrIt.Get();
+ ++mxData->maTokArrIt;
+ return pScToken;
+}
+
+const FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken( bool bSkipSpaces ) const
+{
+ /* Returns pointer to next raw token in the token array. The token array
+ iterator already points to the next token (A call to GetNextToken()
+ always increases the iterator), so this function just returns the token
+ the iterator points to. To skip space tokens, a copy of the iterator is
+ created and set to the passed skip-spaces mode. If spaces have to be
+ skipped, and the iterator currently points to a space token, the
+ constructor will move it to the next non-space token. */
+ XclTokenArrayIterator aTempIt( mxData->maTokArrIt, bSkipSpaces );
+ return aTempIt.Get();
+}
+
+bool XclExpFmlaCompImpl::GetNextToken( XclExpScToken& rTokData )
+{
+ rTokData.mpScToken = GetNextRawToken();
+ rTokData.mnSpaces = (rTokData.GetOpCode() == ocSpaces) ? rTokData.mpScToken->GetByte() : 0;
+ while( rTokData.GetOpCode() == ocSpaces )
+ rTokData.mpScToken = GetNextRawToken();
+ return rTokData.Is();
+}
+
+XclExpScToken XclExpFmlaCompImpl::GetNextToken()
+{
+ XclExpScToken aTokData;
+ GetNextToken( aTokData );
+ return aTokData;
+}
+
+namespace {
+
+/** Returns the Excel token ID of a comparison operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetCompareTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocLess: return EXC_TOKID_LT;
+ case ocLessEqual: return EXC_TOKID_LE;
+ case ocEqual: return EXC_TOKID_EQ;
+ case ocGreaterEqual: return EXC_TOKID_GE;
+ case ocGreater: return EXC_TOKID_GT;
+ case ocNotEqual: return EXC_TOKID_NE;
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a string concatenation operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetConcatTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocAmpersand) ? EXC_TOKID_CONCAT : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of an addition/subtraction operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetAddSubTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocAdd: return EXC_TOKID_ADD;
+ case ocSub: return EXC_TOKID_SUB;
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a multiplication/division operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetMulDivTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocMul: return EXC_TOKID_MUL;
+ case ocDiv: return EXC_TOKID_DIV;
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a power operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetPowTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocPow) ? EXC_TOKID_POWER : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a trailing unary operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetUnaryPostTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocPercentSign) ? EXC_TOKID_PERCENT : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a leading unary operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetUnaryPreTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocAdd: return EXC_TOKID_UPLUS; // +(1)
+ case ocNeg: return EXC_TOKID_UMINUS; // NEG(1)
+ case ocNegSub: return EXC_TOKID_UMINUS; // -(1)
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a reference list operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetListTokenId( OpCode eOpCode, bool bStopAtSep )
+{
+ return ((eOpCode == ocUnion) || (!bStopAtSep && (eOpCode == ocSep))) ? EXC_TOKID_LIST : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a reference intersection operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetIntersectTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocIntersect) ? EXC_TOKID_ISECT : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a reference range operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetRangeTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocRange) ? EXC_TOKID_RANGE : EXC_TOKID_NONE;
+}
+
+} // namespace
+
+XclExpScToken XclExpFmlaCompImpl::Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep )
+{
+ if( mxData->mbOk && aTokData.Is() )
+ {
+ // remember old stop-at-ocSep mode, restored below
+ bool bOldStopAtSep = mxData->mbStopAtSep;
+ mxData->mbStopAtSep = bStopAtSep;
+ // start compilation of the subexpression
+ aTokData = OrTerm( aTokData, bInParentheses );
+ // restore old stop-at-ocSep mode
+ mxData->mbStopAtSep = bOldStopAtSep;
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::SkipExpression( XclExpScToken aTokData, bool bStopAtSep )
+{
+ while( mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() != ocClose) && (!bStopAtSep || (aTokData.GetOpCode() != ocSep)) )
+ {
+ if( aTokData.GetOpCode() == ocOpen )
+ {
+ aTokData = SkipExpression( GetNextToken(), false );
+ if( mxData->mbOk ) mxData->mbOk = aTokData.GetOpCode() == ocClose;
+ }
+ aTokData = GetNextToken();
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::OrTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = AndTerm( aTokData, bInParentheses );
+ sal_uInt8 nParamCount = 1;
+ while( mxData->mbOk && (aTokData.GetOpCode() == ocOr) )
+ {
+ RemoveTrailingParen();
+ aTokData = AndTerm( GetNextToken(), bInParentheses );
+ RemoveTrailingParen();
+ ++nParamCount;
+ if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
+ }
+ if( mxData->mbOk && (nParamCount > 1) )
+ AppendLogicalOperatorToken( EXC_FUNCID_OR, nParamCount );
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::AndTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = CompareTerm( aTokData, bInParentheses );
+ sal_uInt8 nParamCount = 1;
+ while( mxData->mbOk && (aTokData.GetOpCode() == ocAnd) )
+ {
+ RemoveTrailingParen();
+ aTokData = CompareTerm( GetNextToken(), bInParentheses );
+ RemoveTrailingParen();
+ ++nParamCount;
+ if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
+ }
+ if( mxData->mbOk && (nParamCount > 1) )
+ AppendLogicalOperatorToken( EXC_FUNCID_AND, nParamCount );
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::CompareTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = ConcatTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = ConcatTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::ConcatTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = AddSubTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = AddSubTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::AddSubTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = MulDivTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = MulDivTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::MulDivTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = PowTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = PowTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::PowTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = UnaryPostTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = UnaryPostTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = UnaryPreTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ AppendUnaryOperatorToken( nOpTokenId, aTokData.mnSpaces );
+ GetNextToken( aTokData );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ sal_uInt8 nOpTokenId = mxData->mbOk ? lclGetUnaryPreTokenId( aTokData.GetOpCode() ) : EXC_TOKID_NONE;
+ if( nOpTokenId != EXC_TOKID_NONE )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = UnaryPreTerm( GetNextToken(), bInParentheses );
+ AppendUnaryOperatorToken( nOpTokenId, nSpaces );
+ }
+ else
+ {
+ aTokData = ListTerm( aTokData, bInParentheses );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::ListTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ sal_uInt16 nSubExprPos = GetSize();
+ bool bHasAnyRefOp = false;
+ bool bHasListOp = false;
+ aTokData = IntersectTerm( aTokData, bHasAnyRefOp );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(), mxData->mbStopAtSep )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = IntersectTerm( GetNextToken(), bHasAnyRefOp );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
+ bHasAnyRefOp = bHasListOp = true;
+ }
+ if( bHasAnyRefOp )
+ {
+ // add a tMemFunc token enclosing the entire reference subexpression
+ sal_uInt16 nSubExprSize = GetSize() - nSubExprPos;
+ InsertZeros( nSubExprPos, 3 );
+ mxData->maTokVec[ nSubExprPos ] = GetTokenId( EXC_TOKID_MEMFUNC, EXC_TOKCLASS_REF );
+ Overwrite( nSubExprPos + 1, nSubExprSize );
+ // update the operand/operator stack (set the list expression as operand of the tMemFunc)
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_VAL, false );
+ PushOperatorPos( nSubExprPos, xOperands );
+ }
+ // #i86439# enclose list operator into parentheses, e.g. Calc's =AREAS(A1~A2) to Excel's =AREAS((A1;A2))
+ if( bHasListOp && !bInParentheses )
+ AppendParenToken();
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp )
+{
+ aTokData = RangeTerm( aTokData, rbHasRefOp );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = RangeTerm( GetNextToken(), rbHasRefOp );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
+ rbHasRefOp = true;
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp )
+{
+ aTokData = Factor( aTokData );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = Factor( GetNextToken() );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
+ rbHasRefOp = true;
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::Factor( XclExpScToken aTokData )
+{
+ if( !mxData->mbOk || !aTokData.Is() ) return XclExpScToken();
+
+ switch( aTokData.GetType() )
+ {
+ case svUnknown: mxData->mbOk = false; break;
+ case svDouble: ProcessDouble( aTokData ); break;
+ case svString: ProcessString( aTokData ); break;
+#if 0 // erAck
+ case svError: ProcessError( aTokData ); break;
+#endif
+ case svSingleRef: ProcessCellRef( aTokData ); break;
+ case svDoubleRef: ProcessRangeRef( aTokData ); break;
+ case svExternalSingleRef: ProcessExternalCellRef( aTokData ); break;
+ case svExternalDoubleRef: ProcessExternalRangeRef( aTokData ); break;
+ case svExternalName: ProcessExternalName( aTokData ); break;
+ case svMatrix: ProcessMatrix( aTokData ); break;
+ case svExternal: ProcessExternal( aTokData ); break;
+
+ default: switch( aTokData.GetOpCode() )
+ {
+ case ocNone: /* do nothing */ break;
+ case ocMissing: ProcessMissing( aTokData ); break;
+ case ocBad: ProcessBad( aTokData ); break;
+ case ocOpen: ProcessParentheses( aTokData ); break;
+ case ocName: ProcessDefinedName( aTokData ); break;
+ case ocDBArea: ProcessDatabaseArea( aTokData ); break;
+ case ocFalse:
+ case ocTrue: ProcessBoolean( aTokData ); break;
+ case ocDde: ProcessDdeLink( aTokData ); break;
+ default: ProcessFunction( aTokData );
+ }
+ }
+
+ return GetNextToken();
+}
+
+// formula structure ----------------------------------------------------------
+
+void XclExpFmlaCompImpl::ProcessDouble( const XclExpScToken& rTokData )
+{
+ double fValue = rTokData.mpScToken->GetDouble();
+ double fInt;
+ double fFrac = modf( fValue, &fInt );
+ if( (fFrac == 0.0) && (0.0 <= fInt) && (fInt <= 65535.0) )
+ AppendIntToken( static_cast< sal_uInt16 >( fInt ), rTokData.mnSpaces );
+ else
+ AppendNumToken( fValue, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessString( const XclExpScToken& rTokData )
+{
+ AppendOperandTokenId( EXC_TOKID_STR, rTokData.mnSpaces );
+ Append( rTokData.mpScToken->GetString() );
+}
+
+void XclExpFmlaCompImpl::ProcessError( const XclExpScToken& rTokData )
+{
+#if 0 // erAck
+ AppendErrorToken( XclTools::GetXclErrorCode( rTokData.mpScToken->GetError() ), rTokData.mnSpaces );
+#else
+ (void)rTokData; // compiler warning
+#endif
+}
+
+void XclExpFmlaCompImpl::ProcessMissing( const XclExpScToken& rTokData )
+{
+ AppendMissingToken( rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessBad( const XclExpScToken& rTokData )
+{
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessParentheses( const XclExpScToken& rTokData )
+{
+ XclExpScToken aTokData = Expression( GetNextToken(), true, false );
+ mxData->mbOk = aTokData.GetOpCode() == ocClose;
+ AppendParenToken( rTokData.mnSpaces, aTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessBoolean( const XclExpScToken& rTokData )
+{
+ mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
+ if( mxData->mbOk )
+ AppendBoolToken( rTokData.GetOpCode() == ocTrue, rTokData.mnSpaces );
+}
+
+namespace {
+
+inline bool lclGetTokenString( String& rString, const XclExpScToken& rTokData )
+{
+ bool bIsStr = (rTokData.GetType() == svString) && (rTokData.GetOpCode() == ocPush);
+ if( bIsStr )
+ rString = rTokData.mpScToken->GetString();
+ return bIsStr;
+}
+
+} // namespace
+
+void XclExpFmlaCompImpl::ProcessDdeLink( const XclExpScToken& rTokData )
+{
+ String aApplic, aTopic, aItem;
+
+ mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aApplic, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aTopic, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aItem, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
+ if( mxData->mbOk ) mxData->mbOk = aApplic.Len() && aTopic.Len() && aItem.Len();
+ if( mxData->mbOk )
+ {
+ sal_uInt16 nExtSheet, nExtName;
+ if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
+ AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
+ else
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternal( const XclExpScToken& rTokData )
+{
+ /* #i47228# Excel import generates svExternal/ocMacro tokens for invalid
+ names and for external/invalid function calls. This function looks for
+ the next token in the token array. If it is an opening parenthesis, the
+ token is processed as external function call, otherwise as undefined name. */
+ const FormulaToken* pNextScToken = PeekNextRawToken( true );
+ if( !pNextScToken || (pNextScToken->GetOpCode() != ocOpen) )
+ AppendMissingNameToken( rTokData.mpScToken->GetExternal(), rTokData.mnSpaces );
+ else
+ ProcessFunction( rTokData );
+}
+
+void XclExpFmlaCompImpl::ProcessMatrix( const XclExpScToken& rTokData )
+{
+ const ScMatrix* pMatrix = static_cast< const ScToken* >( rTokData.mpScToken )->GetMatrix();
+ if( pMatrix && mxData->mrCfg.mbAllowArrays )
+ {
+ SCSIZE nScCols, nScRows;
+ pMatrix->GetDimensions( nScCols, nScRows );
+ DBG_ASSERT( (nScCols > 0) && (nScRows > 0), "XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
+ sal_uInt16 nCols = ::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
+ sal_uInt16 nRows = ::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
+
+ // create the tArray token
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_ARRAY, EXC_TOKCLASS_ARR ), rTokData.mnSpaces );
+ Append( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
+ Append( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
+ Append( static_cast< sal_uInt32 >( 0 ) );
+
+ // create the extended data containing the array values
+ AppendExt( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
+ AppendExt( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
+ for( SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
+ {
+ for( SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
+ {
+ ScMatValType nType;
+ const ScMatrixValue* pMatVal = pMatrix->Get( nScCol, nScRow, nType );
+ DBG_ASSERT( pMatVal, "XclExpFmlaCompImpl::ProcessMatrix - missing matrix value" );
+ if( ScMatrix::IsValueType( nType ) ) // value, boolean, or error
+ {
+ if( ScMatrix::IsBooleanType( nType ) )
+ {
+ AppendExt( EXC_CACHEDVAL_BOOL );
+ AppendExt( static_cast< sal_uInt8 >( pMatVal->GetBoolean() ? 1 : 0 ) );
+ AppendExt( 0, 7 );
+ }
+ else if( USHORT nErr = pMatVal->GetError() )
+ {
+ AppendExt( EXC_CACHEDVAL_ERROR );
+ AppendExt( XclTools::GetXclErrorCode( nErr ) );
+ AppendExt( 0, 7 );
+ }
+ else
+ {
+ AppendExt( EXC_CACHEDVAL_DOUBLE );
+ AppendExt( pMatVal->fVal );
+ }
+ }
+ else // string or empty
+ {
+ const String& rStr = pMatVal->GetString();
+ if( rStr.Len() == 0 )
+ {
+ AppendExt( EXC_CACHEDVAL_EMPTY );
+ AppendExt( 0, 8 );
+ }
+ else
+ {
+ AppendExt( EXC_CACHEDVAL_STRING );
+ AppendExt( rStr );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // array in places that do not allow it (cond fmts, data validation)
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessFunction( const XclExpScToken& rTokData )
+{
+ OpCode eOpCode = rTokData.GetOpCode();
+ const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( eOpCode );
+
+ XclExpExtFuncData aExtFuncData;
+
+ // no exportable function found - try to create an external macro call
+ if( !pFuncInfo && (eOpCode >= SC_OPCODE_START_NO_PAR) )
+ {
+ const String& rFuncName = ScCompiler::GetNativeSymbol( eOpCode );
+ if( rFuncName.Len() )
+ {
+ aExtFuncData.Set( rFuncName, true, false );
+ pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( ocMacro );
+ }
+ }
+
+ mxData->mbOk = pFuncInfo != 0;
+ if( !mxData->mbOk ) return;
+
+ // functions simulated by a macro call in file format
+ if( pFuncInfo->IsMacroFunc() )
+ aExtFuncData.Set( pFuncInfo->GetMacroFuncName(), false, true );
+
+ XclExpFuncData aFuncData( rTokData, *pFuncInfo, aExtFuncData );
+ XclExpScToken aTokData;
+
+ // preparations for special functions, before function processing starts
+ PrepareFunction( aFuncData );
+
+ enum { STATE_START, STATE_OPEN, STATE_PARAM, STATE_SEP, STATE_CLOSE, STATE_END }
+ eState = STATE_START;
+ while( eState != STATE_END ) switch( eState )
+ {
+ case STATE_START:
+ mxData->mbOk = GetNextToken( aTokData ) && (aTokData.GetOpCode() == ocOpen);
+ eState = mxData->mbOk ? STATE_OPEN : STATE_END;
+ break;
+ case STATE_OPEN:
+ mxData->mbOk = GetNextToken( aTokData );
+ eState = mxData->mbOk ? ((aTokData.GetOpCode() == ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
+ break;
+ case STATE_PARAM:
+ aTokData = ProcessParam( aTokData, aFuncData );
+ switch( aTokData.GetOpCode() )
+ {
+ case ocSep: eState = STATE_SEP; break;
+ case ocClose: eState = STATE_CLOSE; break;
+ default: mxData->mbOk = false;
+ }
+ if( !mxData->mbOk ) eState = STATE_END;
+ break;
+ case STATE_SEP:
+ mxData->mbOk = (aFuncData.GetParamCount() < EXC_FUNC_MAXPARAM) && GetNextToken( aTokData );
+ eState = mxData->mbOk ? STATE_PARAM : STATE_END;
+ break;
+ case STATE_CLOSE:
+ FinishFunction( aFuncData, aTokData.mnSpaces );
+ eState = STATE_END;
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::PrepareFunction( XclExpFuncData& rFuncData )
+{
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocCot: // simulate COT(x) by (1/TAN(x))
+ case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
+ AppendIntToken( 1 );
+ break;
+ case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
+ AppendNumToken( F_PI2 );
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces )
+{
+ // append missing parameters required in Excel, may modify param count
+ AppendTrailingParam( rFuncData );
+
+ // check if parameter count fits into the limits of the function
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ if( (rFuncData.GetMinParamCount() <= nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
+ {
+ // first put the tAttrSpace tokens, they must not be included in tAttrGoto handling
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, rFuncData.GetSpaces() );
+
+ // add tAttrGoto tokens for IF or CHOOSE functions
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ case ocChose:
+ AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
+ break;
+ default:;
+ }
+
+ // put the tFunc or tFuncVar token (or another special token, e.g. tAttrSum)
+ AppendFuncToken( rFuncData );
+
+ // update volatile flag - is set if at least one used function is volatile
+ mxData->mbVolatile |= rFuncData.IsVolatile();
+
+ // update jump tokens for specific functions, add additional tokens
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ FinishIfFunction( rFuncData );
+ break;
+ case ocChose:
+ FinishChooseFunction( rFuncData );
+ break;
+
+ case ocCot: // simulate COT(x) by (1/TAN(x))
+ case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
+ AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
+ AppendParenToken();
+ break;
+ case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
+ AppendBinaryOperatorToken( EXC_TOKID_SUB, true );
+ AppendParenToken();
+ break;
+
+ default:;
+ }
+ }
+ else
+ mxData->mbOk = false;
+}
+
+void XclExpFmlaCompImpl::FinishIfFunction( XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nParamCount = rFuncData.GetParamCount();
+ DBG_ASSERT( (nParamCount == 2) || (nParamCount == 3), "XclExpFmlaCompImpl::FinishIfFunction - wrong parameter count" );
+ const ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
+ DBG_ASSERT( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishIfFunction - wrong number of tAttr tokens" );
+ // update tAttrIf token following the condition parameter
+ Overwrite( rAttrPos[ 0 ] + 2, static_cast< sal_uInt16 >( rAttrPos[ 1 ] - rAttrPos[ 0 ] ) );
+ // update the tAttrGoto tokens following true and false parameters
+ UpdateAttrGoto( rAttrPos[ 1 ] );
+ if( nParamCount == 3 )
+ UpdateAttrGoto( rAttrPos[ 2 ] );
+}
+
+void XclExpFmlaCompImpl::FinishChooseFunction( XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nParamCount = rFuncData.GetParamCount();
+ ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
+ DBG_ASSERT( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishChooseFunction - wrong number of tAttr tokens" );
+ // number of choices is parameter count minus 1
+ sal_uInt16 nChoices = nParamCount - 1;
+ // tAttrChoose token contains number of choices
+ Overwrite( rAttrPos[ 0 ] + 2, nChoices );
+ // cache position of the jump table (follows number of choices in tAttrChoose token)
+ sal_uInt16 nJumpArrPos = rAttrPos[ 0 ] + 4;
+ // size of jump table: number of choices, plus 1 for error position
+ sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
+ // insert the jump table into the tAttrChoose token
+ InsertZeros( nJumpArrPos, nJumpArrSize );
+ // update positions of tAttrGoto tokens after jump table insertion
+ sal_uInt16 nIdx;
+ for( nIdx = 1; nIdx < nParamCount; ++nIdx )
+ rAttrPos[ nIdx ] = rAttrPos[ nIdx ] + nJumpArrSize;
+ // update the tAttrGoto tokens (they contain a value one-less to real distance)
+ for( nIdx = 1; nIdx < nParamCount; ++nIdx )
+ UpdateAttrGoto( rAttrPos[ nIdx ] );
+ // update the distances in the jump table
+ Overwrite( nJumpArrPos, nJumpArrSize );
+ for( nIdx = 1; nIdx < nParamCount; ++nIdx )
+ Overwrite( nJumpArrPos + 2 * nIdx, static_cast< sal_uInt16 >( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
+}
+
+XclExpScToken XclExpFmlaCompImpl::ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData )
+{
+ if( rFuncData.IsCalcOnlyParam() )
+ {
+ // skip Calc-only parameter, stop at next ocClose or ocSep
+ aTokData = SkipExpression( aTokData, true );
+ rFuncData.IncParamInfoIdx();
+ }
+ else
+ {
+ // insert Excel-only parameters, modifies param count and class in rFuncData
+ while( rFuncData.IsExcelOnlyParam() )
+ AppendDefaultParam( rFuncData );
+
+ // process the parameter, stop at next ocClose or ocSep
+ PrepareParam( rFuncData );
+ /* #i37355# insert tMissArg token for missing parameters --
+ Excel import filter adds ocMissing token (handled in Factor()),
+ but Calc itself does not do this if a new formula is entered. */
+ switch( aTokData.GetOpCode() )
+ {
+ case ocSep:
+ case ocClose: AppendMissingToken(); break; // empty parameter
+ default: aTokData = Expression( aTokData, false, true );
+ }
+ // finalize the parameter and add special tokens, e.g. for IF or CHOOSE parameters
+ if( mxData->mbOk ) FinishParam( rFuncData );
+ }
+ return aTokData;
+}
+
+void XclExpFmlaCompImpl::PrepareParam( XclExpFuncData& rFuncData )
+{
+ // index of this parameter is equal to number of already finished parameters
+ sal_uInt8 nParamIdx = rFuncData.GetParamCount();
+
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ switch( nParamIdx )
+ {
+ // add a tAttrIf token before true-parameter (second parameter)
+ case 1: AppendJumpToken( rFuncData, EXC_TOK_ATTR_IF ); break;
+ // add a tAttrGoto token before false-parameter (third parameter)
+ case 2: AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO ); break;
+ }
+ break;
+
+ case ocChose:
+ switch( nParamIdx )
+ {
+ // do nothing for first parameter
+ case 0: break;
+ // add a tAttrChoose token before first value parameter (second parameter)
+ case 1: AppendJumpToken( rFuncData, EXC_TOK_ATTR_CHOOSE ); break;
+ // add a tAttrGoto token before other value parameters
+ default: AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
+ }
+ break;
+
+ case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
+ if( nParamIdx == 0 )
+ AppendIntToken( 1 );
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::FinishParam( XclExpFuncData& rFuncData )
+{
+ // increase parameter count, update operand stack
+ rFuncData.FinishParam( PopOperandPos() );
+
+ // append more tokens for parameters of some special functions
+ sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
+ if( nParamIdx == 0 )
+ {
+ AppendParenToken();
+ AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
+ }
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::AppendDefaultParam( XclExpFuncData& rFuncData )
+{
+ // prepare parameters of some special functions
+ PrepareParam( rFuncData );
+
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocExternal:
+ AppendAddInCallToken( rFuncData.GetExtFuncData() );
+ break;
+ case ocEuroConvert:
+ AppendEuroToolCallToken( rFuncData.GetExtFuncData() );
+ break;
+ case ocMacro:
+ AppendMacroCallToken( rFuncData.GetExtFuncData() );
+ break;
+ default:
+ {
+ DBG_ASSERT( rFuncData.IsMacroFunc(), "XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
+ if( rFuncData.IsMacroFunc() )
+ AppendMacroCallToken( rFuncData.GetExtFuncData() );
+ else
+ AppendMissingToken(); // to keep parameter count valid
+ }
+ }
+
+ // update parameter count, add special parameter tokens
+ FinishParam( rFuncData );
+}
+
+void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
+{
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ if( nParamCount == 1 )
+ {
+ // #112262# Excel needs at least two parameters in IF function
+ PrepareParam( rFuncData );
+ AppendBoolToken( true );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocRound:
+ case ocRoundUp:
+ case ocRoundDown:
+ if( nParamCount == 1 )
+ {
+ // ROUND, ROUNDUP, ROUNDDOWN functions are fixed to 2 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendIntToken( 0 );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocIndex:
+ if( nParamCount == 1 )
+ {
+ // INDEX function needs at least 2 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendMissingToken();
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocExternal:
+ case ocMacro:
+ // external or macro call without parameters needs the external name reference
+ if( nParamCount == 0 )
+ AppendDefaultParam( rFuncData );
+ break;
+
+ case ocGammaDist:
+ if( nParamCount == 3 )
+ {
+ // GAMMADIST function needs 4 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocPoissonDist:
+ if( nParamCount == 2 )
+ {
+ // POISSON function needs 3 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocNormDist:
+ if( nParamCount == 3 )
+ {
+ // NORMDIST function needs 4 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendBoolToken( true );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocLogNormDist:
+ switch( nParamCount )
+ {
+ // LOGNORMDIST function needs 3 parameters in Excel
+ case 1:
+ PrepareParam( rFuncData );
+ AppendIntToken( 0 );
+ FinishParam( rFuncData );
+ // do not break, add next default parameter
+ case 2:
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ break;
+ default:;
+ }
+
+ break;
+
+ default:;
+ }
+}
+
+// reference handling ---------------------------------------------------------
+
+namespace {
+
+inline bool lclIsRefRel2D( const ScSingleRefData& rRefData )
+{
+ return rRefData.IsColRel() || rRefData.IsRowRel();
+}
+
+inline bool lclIsRefDel2D( const ScSingleRefData& rRefData )
+{
+ return rRefData.IsColDeleted() || rRefData.IsRowDeleted();
+}
+
+inline bool lclIsRefRel2D( const ScComplexRefData& rRefData )
+{
+ return lclIsRefRel2D( rRefData.Ref1 ) || lclIsRefRel2D( rRefData.Ref2 );
+}
+
+inline bool lclIsRefDel2D( const ScComplexRefData& rRefData )
+{
+ return lclIsRefDel2D( rRefData.Ref1 ) || lclIsRefDel2D( rRefData.Ref2 );
+}
+
+} // namespace
+
+SCTAB XclExpFmlaCompImpl::GetScTab( const ScSingleRefData& rRefData ) const
+{
+ bool bInvTab = rRefData.IsTabDeleted() || (!mxData->mpScBasePos && IsInGlobals() && rRefData.IsTabRel());
+ return bInvTab ? SCTAB_INVALID : static_cast< SCTAB >( rRefData.nTab );
+}
+
+bool XclExpFmlaCompImpl::IsRef2D( const ScSingleRefData& rRefData ) const
+{
+ /* rRefData.IsFlag3D() determines if sheet name is always visible, even on
+ the own sheet. If 3D references are allowed, the passed reference does
+ not count as 2D reference. */
+ return (!mxData->mpLinkMgr || !rRefData.IsFlag3D()) && !rRefData.IsTabDeleted() &&
+ (rRefData.IsTabRel() ? (rRefData.nRelTab == 0) : (static_cast< SCTAB >( rRefData.nTab ) == GetCurrScTab()));
+}
+
+bool XclExpFmlaCompImpl::IsRef2D( const ScComplexRefData& rRefData ) const
+{
+ return IsRef2D( rRefData.Ref1 ) && IsRef2D( rRefData.Ref2 );
+}
+
+void XclExpFmlaCompImpl::ConvertRefData(
+ ScSingleRefData& rRefData, XclAddress& rXclPos,
+ bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const
+{
+ if( mxData->mpScBasePos )
+ {
+ // *** reference position exists (cell, matrix) - convert to absolute ***
+ rRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+
+ // convert column index
+ SCsCOL& rnScCol = rRefData.nCol;
+ if( bTruncMaxCol && (rnScCol == mnMaxScCol) )
+ rnScCol = mnMaxAbsCol;
+ else if( (rnScCol < 0) || (rnScCol > mnMaxAbsCol) )
+ rRefData.SetColDeleted( TRUE );
+ rXclPos.mnCol = static_cast< sal_uInt16 >( rnScCol ) & mnMaxColMask;
+
+ // convert row index
+ SCsROW& rnScRow = rRefData.nRow;
+ if( bTruncMaxRow && (rnScRow == mnMaxScRow) )
+ rnScRow = mnMaxAbsRow;
+ else if( (rnScRow < 0) || (rnScRow > mnMaxAbsRow) )
+ rRefData.SetRowDeleted( TRUE );
+ rXclPos.mnRow = static_cast< sal_uInt16 >( rnScRow ) & mnMaxRowMask;
+ }
+ else
+ {
+ // *** no reference position (shared, names, condfmt) - use relative values ***
+
+ // convert column index (2-step-cast ScsCOL->sal_Int16->sal_uInt16 to get all bits correctly)
+ sal_Int16 nXclRelCol = static_cast< sal_Int16 >( rRefData.IsColRel() ? rRefData.nRelCol : rRefData.nCol );
+ rXclPos.mnCol = static_cast< sal_uInt16 >( nXclRelCol ) & mnMaxColMask;
+
+ // convert row index (2-step-cast ScsROW->sal_Int16->sal_uInt16 to get all bits correctly)
+ sal_Int16 nXclRelRow = static_cast< sal_Int16 >( rRefData.IsRowRel() ? rRefData.nRelRow : rRefData.nRow );
+ rXclPos.mnRow = static_cast< sal_uInt16 >( nXclRelRow ) & mnMaxRowMask;
+
+ // resolve relative tab index if possible
+ if( rRefData.IsTabRel() && !IsInGlobals() && (GetCurrScTab() < GetDoc().GetTableCount()) )
+ rRefData.nTab = static_cast< SCsTAB >( GetCurrScTab() + rRefData.nRelTab );
+ }
+
+ // flags for relative column and row
+ if( bNatLangRef )
+ {
+ DBG_ASSERT( meBiff == EXC_BIFF8, "XclExpFmlaCompImpl::ConvertRefData - NLRs only for BIFF8" );
+ // Calc does not support absolute reference mode in natural language references
+ ::set_flag( rXclPos.mnCol, EXC_TOK_NLR_REL );
+ }
+ else
+ {
+ sal_uInt16& rnRelField = (meBiff <= EXC_BIFF5) ? rXclPos.mnRow : rXclPos.mnCol;
+ ::set_flag( rnRelField, EXC_TOK_REF_COLREL, rRefData.IsColRel() );
+ ::set_flag( rnRelField, EXC_TOK_REF_ROWREL, rRefData.IsRowRel() );
+ }
+}
+
+void XclExpFmlaCompImpl::ConvertRefData(
+ ScComplexRefData& rRefData, XclRange& rXclRange, bool bNatLangRef ) const
+{
+ // convert start and end of the range
+ ConvertRefData( rRefData.Ref1, rXclRange.maFirst, bNatLangRef, false, false );
+ bool bTruncMaxCol = !rRefData.Ref1.IsColDeleted() && (rRefData.Ref1.nCol == 0);
+ bool bTruncMaxRow = !rRefData.Ref1.IsRowDeleted() && (rRefData.Ref1.nRow == 0);
+ ConvertRefData( rRefData.Ref2, rXclRange.maLast, bNatLangRef, bTruncMaxCol, bTruncMaxRow );
+}
+
+XclExpRefLogEntry* XclExpFmlaCompImpl::GetNewRefLogEntry()
+{
+ if( mxData->mpRefLog )
+ {
+ mxData->mpRefLog->resize( mxData->mpRefLog->size() + 1 );
+ return &mxData->mpRefLog->back();
+ }
+ return 0;
+}
+
+void XclExpFmlaCompImpl::ProcessCellRef( const XclExpScToken& rTokData )
+{
+ // get the Excel address components, adjust internal data in aRefData
+ bool bNatLangRef = (meBiff == EXC_BIFF8) && mxData->mpScBasePos && (rTokData.GetOpCode() == ocColRowName);
+ ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclPos, bNatLangRef, false, false );
+
+ if( bNatLangRef )
+ {
+ DBG_ASSERT( aRefData.IsColRel() != aRefData.IsRowRel(),
+ "XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
+ // create tNlr token for natural language reference
+ sal_uInt8 nSubId = aRefData.IsColRel() ? EXC_TOK_NLR_COLV : EXC_TOK_NLR_ROWV;
+ AppendOperandTokenId( EXC_TOKID_NLR, rTokData.mnSpaces );
+ Append( nSubId );
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ // store external cell contents in CRN records
+ if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCell( aRefData );
+
+ // create the tRef, tRefErr, tRefN, tRef3d, or tRefErr3d token
+ if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
+ {
+ // 2D reference (not in defined names, but allowed in range lists)
+ sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_REFN :
+ (lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR : EXC_TOKID_REF);
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ AppendAddress( aXclPos );
+ }
+ else if( mxData->mpLinkMgr ) // 3D reference
+ {
+ // 1-based EXTERNSHEET index and 0-based Excel sheet index
+ sal_uInt16 nExtSheet, nXclTab;
+ mxData->mpLinkMgr->FindExtSheet( nExtSheet, nXclTab, GetScTab( aRefData ), GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nXclTab );
+ Append( nXclTab );
+ }
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ // 3D ref in cond. format, or 2D ref in name
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpScToken& rTokData )
+{
+ // get the Excel address components, adjust internal data in aRefData
+ ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclRange, false );
+
+ // store external cell contents in CRN records
+ if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCellRange( aRefData );
+
+ // create the tArea, tAreaErr, tAreaN, tArea3d, or tAreaErr3d token
+ if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
+ {
+ // 2D reference (not in name formulas, but allowed in range lists)
+ sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_AREAN :
+ (lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR : EXC_TOKID_AREA);
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ AppendRange( aXclRange );
+ }
+ else if( mxData->mpLinkMgr ) // 3D reference
+ {
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
+ mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
+ GetScTab( aRefData.Ref1 ), GetScTab( aRefData.Ref2 ), GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstXclTab );
+ Append( nLastXclTab );
+ }
+ AppendRange( aXclRange );
+ }
+ else
+ {
+ // 3D ref in cond. format, or 2D ref in name
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternalCellRef( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ // get the Excel address components, adjust internal data in aRefData
+ ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclPos, false, false, false );
+
+ // store external cell contents in CRN records
+ USHORT nFileId = rTokData.mpScToken->GetIndex();
+ const String& rTabName = rTokData.mpScToken->GetString();
+ if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCell( nFileId, rTabName, aRefData );
+
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
+ mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstSBTab );
+ Append( nLastSBTab );
+ }
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternalRangeRef( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ // get the Excel address components, adjust internal data in aRefData
+ ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclRange, false );
+
+ // store external cell contents in CRN records
+ USHORT nFileId = rTokData.mpScToken->GetIndex();
+ const String& rTabName = rTokData.mpScToken->GetString();
+ if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCellRange( nFileId, rTabName, aRefData );
+
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
+ sal_uInt16 nTabSpan = static_cast< sal_uInt16 >( aRefData.Ref2.nTab - aRefData.Ref1.nTab + 1 );
+ mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstSBTab );
+ Append( nLastSBTab );
+ }
+ AppendRange( aXclRange );
+ }
+ else
+ {
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpScToken& rTokData )
+{
+ XclExpNameManager& rNameMgr = GetNameManager();
+ sal_uInt16 nNameIdx = rNameMgr.InsertName( rTokData.mpScToken->GetIndex() );
+ if( nNameIdx != 0 )
+ {
+ // global names always with tName token, local names dependent on config
+ SCTAB nScTab = rNameMgr.GetScTab( nNameIdx );
+ if( (nScTab == SCTAB_GLOBAL) || (!mxData->mrCfg.mb3DRefOnly && (nScTab == GetCurrScTab())) )
+ {
+ AppendNameToken( nNameIdx, rTokData.mnSpaces );
+ }
+ else if( mxData->mpLinkMgr )
+ {
+ // use the same special EXTERNNAME to refer to any local name
+ sal_uInt16 nExtSheet = mxData->mpLinkMgr->FindExtSheet( EXC_EXTSH_OWNDOC );
+ AppendNameXToken( nExtSheet, nNameIdx, rTokData.mnSpaces );
+ }
+ else
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
+ // volatile names (containing volatile functions)
+ mxData->mbVolatile |= rNameMgr.IsVolatile( nNameIdx );
+ }
+ else
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessExternalName( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ ScExternalRefManager& rExtRefMgr = *GetDoc().GetExternalRefManager();
+ USHORT nFileId = rTokData.mpScToken->GetIndex();
+ const String& rName = rTokData.mpScToken->GetString();
+ ScExternalRefCache::TokenArrayRef xArray = rExtRefMgr.getRangeNameTokens( nFileId, rName );
+ if( xArray.get() )
+ {
+ // store external cell contents in CRN records
+ if( mxData->mpScBasePos )
+ {
+ for( FormulaToken* pScToken = xArray->First(); pScToken; pScToken = xArray->Next() )
+ {
+ if( pScToken->GetOpCode() == ocExternalRef )
+ {
+ switch( pScToken->GetType() )
+ {
+ case svExternalSingleRef:
+ {
+ ScSingleRefData aRefData = static_cast< ScToken* >( pScToken )->GetSingleRef();
+ aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+ mxData->mpLinkMgr->StoreCell( nFileId, pScToken->GetString(), aRefData );
+ }
+ break;
+ case svExternalDoubleRef:
+ {
+ ScComplexRefData aRefData = static_cast< ScToken* >( pScToken )->GetDoubleRef();
+ aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+ mxData->mpLinkMgr->StoreCellRange( nFileId, pScToken->GetString(), aRefData );
+ }
+ default:
+ ; // nothing, avoid compiler warning
+ }
+ }
+ }
+ }
+
+ // insert the new external name and create the tNameX token
+ sal_uInt16 nExtSheet, nExtName;
+ const String* pFile = rExtRefMgr.getExternalFileName( nFileId );
+ if( pFile && mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile, rName, xArray ) )
+ {
+ AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
+ return;
+ }
+ }
+ }
+
+ // on any error: create a #NAME? error
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessDatabaseArea( const XclExpScToken& rTokData )
+{
+ sal_uInt16 nNameIdx = GetNameManager().InsertDBRange( rTokData.mpScToken->GetIndex() );
+ AppendNameToken( nNameIdx, rTokData.mnSpaces );
+}
+
+// token vector ---------------------------------------------------------------
+
+void XclExpFmlaCompImpl::PushOperandPos( sal_uInt16 nTokPos )
+{
+ mxData->maOpPosStack.push_back( nTokPos );
+}
+
+void XclExpFmlaCompImpl::PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands )
+{
+ PushOperandPos( nTokPos );
+ DBG_ASSERT( rxOperands.get(), "XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
+ if( mxData->maOpListVec.size() <= nTokPos )
+ mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
+ mxData->maOpListVec[ nTokPos ] = rxOperands;
+}
+
+sal_uInt16 XclExpFmlaCompImpl::PopOperandPos()
+{
+ DBG_ASSERT( !mxData->mbOk || !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
+ mxData->mbOk &= !mxData->maOpPosStack.empty();
+ if( mxData->mbOk )
+ {
+ sal_uInt16 nTokPos = mxData->maOpPosStack.back();
+ mxData->maOpPosStack.pop_back();
+ return nTokPos;
+ }
+ return 0;
+}
+
+namespace {
+
+inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt16 nData )
+{
+ orVector.resize( orVector.size() + 2 );
+ ShortToSVBT16( nData, &*(orVector.end() - 2) );
+}
+
+inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt32 nData )
+{
+ orVector.resize( orVector.size() + 4 );
+ UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
+}
+
+inline void lclAppend( ScfUInt8Vec& orVector, double fData )
+{
+ orVector.resize( orVector.size() + 8 );
+ DoubleToSVBT64( fData, &*(orVector.end() - 8) );
+}
+
+inline void lclAppend( ScfUInt8Vec& orVector, const XclExpRoot& rRoot, const String& rString, XclStrFlags nStrFlags )
+{
+ XclExpStringRef xXclStr = XclExpStringHelper::CreateString( rRoot, rString, nStrFlags, EXC_TOK_STR_MAXLEN );
+ size_t nSize = orVector.size();
+ orVector.resize( nSize + xXclStr->GetSize() );
+ xXclStr->WriteToMem( &orVector[ nSize ] );
+}
+
+} // namespace
+
+void XclExpFmlaCompImpl::Append( sal_uInt8 nData )
+{
+ mxData->maTokVec.push_back( nData );
+}
+
+void XclExpFmlaCompImpl::Append( sal_uInt8 nData, size_t nCount )
+{
+ mxData->maTokVec.resize( mxData->maTokVec.size() + nCount, nData );
+}
+
+void XclExpFmlaCompImpl::Append( sal_uInt16 nData )
+{
+ lclAppend( mxData->maTokVec, nData );
+}
+
+void XclExpFmlaCompImpl::Append( sal_uInt32 nData )
+{
+ lclAppend( mxData->maTokVec, nData );
+}
+
+void XclExpFmlaCompImpl::Append( double fData )
+{
+ lclAppend( mxData->maTokVec, fData );
+}
+
+void XclExpFmlaCompImpl::Append( const String& rString )
+{
+ lclAppend( mxData->maTokVec, GetRoot(), rString, EXC_STR_8BITLENGTH );
+}
+
+void XclExpFmlaCompImpl::AppendAddress( const XclAddress& rXclPos )
+{
+ Append( rXclPos.mnRow );
+ if( meBiff <= EXC_BIFF5 )
+ Append( static_cast< sal_uInt8 >( rXclPos.mnCol ) );
+ else
+ Append( rXclPos.mnCol );
+}
+
+void XclExpFmlaCompImpl::AppendRange( const XclRange& rXclRange )
+{
+ Append( rXclRange.maFirst.mnRow );
+ Append( rXclRange.maLast.mnRow );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( static_cast< sal_uInt8 >( rXclRange.maFirst.mnCol ) );
+ Append( static_cast< sal_uInt8 >( rXclRange.maLast.mnCol ) );
+ }
+ else
+ {
+ Append( rXclRange.maFirst.mnCol );
+ Append( rXclRange.maLast.mnCol );
+ }
+}
+
+void XclExpFmlaCompImpl::AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount )
+{
+ if( nCount > 0 )
+ {
+ Append( EXC_TOKID_ATTR );
+ Append( EXC_TOK_ATTR_SPACE );
+ Append( nType );
+ Append( nCount );
+ }
+}
+
+void XclExpFmlaCompImpl::AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
+ PushOperandPos( GetSize() );
+ Append( nTokenId );
+}
+
+void XclExpFmlaCompImpl::AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_INT, nSpaces );
+ Append( nValue );
+}
+
+void XclExpFmlaCompImpl::AppendNumToken( double fValue, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_NUM, nSpaces );
+ Append( fValue );
+}
+
+void XclExpFmlaCompImpl::AppendBoolToken( bool bValue, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_BOOL, nSpaces );
+ Append( bValue ? EXC_TOK_BOOL_TRUE : EXC_TOK_BOOL_FALSE );
+}
+
+void XclExpFmlaCompImpl::AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_ERR, nSpaces );
+ Append( nErrCode );
+}
+
+void XclExpFmlaCompImpl::AppendMissingToken( sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_MISSARG, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces )
+{
+ if( nNameIdx > 0 )
+ {
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_NAME, EXC_TOKCLASS_REF ), nSpaces );
+ Append( nNameIdx );
+ Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
+ }
+ else
+ AppendErrorToken( EXC_ERR_NAME );
+}
+
+void XclExpFmlaCompImpl::AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces )
+{
+ sal_uInt16 nNameIdx = GetNameManager().InsertRawName( rName );
+ AppendNameToken( nNameIdx, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), nSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ Append( 0, 8 );
+ Append( nExtName );
+ Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
+}
+
+void XclExpFmlaCompImpl::AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
+{
+ sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rExtFuncData.maFuncName, rExtFuncData.mbVBasic, true, rExtFuncData.mbHidden );
+ AppendNameToken( nNameIdx, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
+{
+ String aXclFuncName;
+ if( mxData->mpLinkMgr && ScGlobal::GetAddInCollection()->GetExcelName( rExtFuncData.maFuncName, GetUILanguage(), aXclFuncName ) )
+ {
+ sal_uInt16 nExtSheet, nExtName;
+ if( mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
+ {
+ AppendNameXToken( nExtSheet, nExtName, nSpaces );
+ return;
+ }
+ }
+ AppendMacroCallToken( rExtFuncData, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
+{
+ sal_uInt16 nExtSheet, nExtName;
+ if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
+ AppendNameXToken( nExtSheet, nExtName, nSpaces );
+ else
+ AppendMacroCallToken( rExtFuncData, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
+ PushOperatorPos( GetSize(), rxOperands );
+ Append( nTokenId );
+}
+
+void XclExpFmlaCompImpl::AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, true );
+ AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
+ AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ for( sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx )
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPX, false );
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, EXC_TOKCLASS_VAL ), xOperands );
+ Append( nOpCount );
+ Append( nXclFuncIdx );
+}
+
+void XclExpFmlaCompImpl::AppendFuncToken( const XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ sal_uInt8 nRetClass = rFuncData.GetReturnClass();
+
+ if( (nXclFuncIdx == EXC_FUNCID_SUM) && (nParamCount == 1) )
+ {
+ // SUM with only one parameter
+ AppendOperatorTokenId( EXC_TOKID_ATTR, rFuncData.GetOperandList() );
+ Append( EXC_TOK_ATTR_SUM );
+ Append( sal_uInt16( 0 ) );
+ }
+ else if( rFuncData.IsFixedParamCount() )
+ {
+ // fixed number of parameters
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), rFuncData.GetOperandList() );
+ Append( nXclFuncIdx );
+ }
+ else
+ {
+ // variable number of parameters
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), rFuncData.GetOperandList() );
+ Append( nParamCount );
+ Append( nXclFuncIdx );
+ }
+}
+
+void XclExpFmlaCompImpl::AppendParenToken( sal_uInt8 nOpenSpaces, sal_uInt8 nCloseSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_OPEN, nOpenSpaces );
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
+ Append( EXC_TOKID_PAREN );
+}
+
+void XclExpFmlaCompImpl::AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType )
+{
+ // store the start position of the token
+ rFuncData.AppendAttrPos( GetSize() );
+ // create the tAttr token
+ Append( EXC_TOKID_ATTR );
+ Append( nAttrType );
+ Append( sal_uInt16( 0 ) ); // placeholder that will be updated later
+}
+
+void XclExpFmlaCompImpl::InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize )
+{
+ // insert zeros into the token array
+ DBG_ASSERT( nInsertPos < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Insert - invalid position" );
+ mxData->maTokVec.insert( mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
+
+ // update positions of operands waiting for an operator
+ for( ScfUInt16Vec::iterator aIt = mxData->maOpPosStack.begin(), aEnd = mxData->maOpPosStack.end(); aIt != aEnd; ++aIt )
+ if( nInsertPos <= *aIt )
+ *aIt = *aIt + nInsertSize;
+
+ // update operand lists of all operator tokens
+ if( nInsertPos < mxData->maOpListVec.size() )
+ mxData->maOpListVec.insert( mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
+ for( XclExpOperandListVector::iterator aIt = mxData->maOpListVec.begin(), aEnd = mxData->maOpListVec.end(); aIt != aEnd; ++aIt )
+ if( aIt->get() )
+ for( XclExpOperandList::iterator aIt2 = (*aIt)->begin(), aEnd2 = (*aIt)->end(); aIt2 != aEnd2; ++aIt2 )
+ if( nInsertPos <= aIt2->mnTokPos )
+ aIt2->mnTokPos = aIt2->mnTokPos + nInsertSize;
+}
+
+void XclExpFmlaCompImpl::Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset )
+{
+ DBG_ASSERT( static_cast< size_t >( nWriteToPos + 1 ) < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Overwrite - invalid position" );
+ ShortToSVBT16( nOffset, &mxData->maTokVec[ nWriteToPos ] );
+}
+
+void XclExpFmlaCompImpl::UpdateAttrGoto( sal_uInt16 nAttrPos )
+{
+ /* tAttrGoto contains distance from end of tAttr token to position behind
+ the function token (for IF or CHOOSE function), which is currently at
+ the end of the token array. Additionally this distance is decreased by
+ one, for whatever reason. So we have to subtract 4 and 1 from the
+ distance between the tAttr token start and the end of the token array. */
+ Overwrite( nAttrPos + 2, static_cast< sal_uInt16 >( GetSize() - nAttrPos - 5 ) );
+}
+
+bool XclExpFmlaCompImpl::IsSpaceToken( sal_uInt16 nPos ) const
+{
+ return
+ (static_cast< size_t >( nPos + 4 ) <= mxData->maTokVec.size()) &&
+ (mxData->maTokVec[ nPos ] == EXC_TOKID_ATTR) &&
+ (mxData->maTokVec[ nPos + 1 ] == EXC_TOK_ATTR_SPACE);
+}
+
+void XclExpFmlaCompImpl::RemoveTrailingParen()
+{
+ // remove trailing tParen token
+ if( !mxData->maTokVec.empty() && (mxData->maTokVec.back() == EXC_TOKID_PAREN) )
+ mxData->maTokVec.pop_back();
+ // remove remaining tAttrSpace tokens
+ while( (mxData->maTokVec.size() >= 4) && IsSpaceToken( GetSize() - 4 ) )
+ mxData->maTokVec.erase( mxData->maTokVec.end() - 4, mxData->maTokVec.end() );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData )
+{
+ mxData->maExtDataVec.push_back( nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData, size_t nCount )
+{
+ mxData->maExtDataVec.resize( mxData->maExtDataVec.size() + nCount, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt16 nData )
+{
+ lclAppend( mxData->maExtDataVec, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt32 nData )
+{
+ lclAppend( mxData->maExtDataVec, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( double fData )
+{
+ lclAppend( mxData->maExtDataVec, fData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( const String& rString )
+{
+ lclAppend( mxData->maExtDataVec, GetRoot(), rString, (meBiff == EXC_BIFF8) ? EXC_STR_DEFAULT : EXC_STR_8BITLENGTH );
+}
+
+// ============================================================================
+
+namespace {
+
+void lclInitOwnTab( ScSingleRefData& rRef, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
+{
+ if( b3DRefOnly )
+ {
+ // no reduction to 2D reference, if global link manager is used
+ rRef.SetFlag3D( TRUE );
+ }
+ else if( rScPos.Tab() == nCurrScTab )
+ {
+ rRef.SetTabRel( TRUE );
+ rRef.nRelTab = 0;
+ }
+}
+
+void lclPutCellToTokenArray( ScTokenArray& rScTokArr, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
+{
+ ScSingleRefData aRef;
+ aRef.InitAddress( rScPos );
+ lclInitOwnTab( aRef, rScPos, nCurrScTab, b3DRefOnly );
+ rScTokArr.AddSingleReference( aRef );
+}
+
+void lclPutRangeToTokenArray( ScTokenArray& rScTokArr, const ScRange& rScRange, SCTAB nCurrScTab, bool b3DRefOnly )
+{
+ if( rScRange.aStart == rScRange.aEnd )
+ {
+ lclPutCellToTokenArray( rScTokArr, rScRange.aStart, nCurrScTab, b3DRefOnly );
+ }
+ else
+ {
+ ScComplexRefData aRef;
+ aRef.InitRange( rScRange );
+ lclInitOwnTab( aRef.Ref1, rScRange.aStart, nCurrScTab, b3DRefOnly );
+ lclInitOwnTab( aRef.Ref2, rScRange.aEnd, nCurrScTab, b3DRefOnly );
+ rScTokArr.AddDoubleReference( aRef );
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpFormulaCompiler::XclExpFormulaCompiler( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mxImpl( new XclExpFmlaCompImpl( rRoot ) )
+{
+}
+
+XclExpFormulaCompiler::~XclExpFormulaCompiler()
+{
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula(
+ XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
+{
+ return mxImpl->CreateFormula( eType, rScTokArr, pScBasePos, pRefLog );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScAddress& rScPos )
+{
+ ScTokenArray aScTokArr;
+ lclPutCellToTokenArray( aScTokArr, rScPos, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
+ return mxImpl->CreateFormula( eType, aScTokArr );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScRange& rScRange )
+{
+ ScTokenArray aScTokArr;
+ lclPutRangeToTokenArray( aScTokArr, rScRange, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
+ return mxImpl->CreateFormula( eType, aScTokArr );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScRangeList& rScRanges )
+{
+ ULONG nCount = rScRanges.Count();
+ if( nCount == 0 )
+ return XclTokenArrayRef();
+
+ ScTokenArray aScTokArr;
+ SCTAB nCurrScTab = GetCurrScTab();
+ bool b3DRefOnly = mxImpl->Is3DRefOnly( eType );
+ for( ULONG nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ if( nIdx > 0 )
+ aScTokArr.AddOpCode( ocUnion );
+ lclPutRangeToTokenArray( aScTokArr, *rScRanges.GetObject( nIdx ), nCurrScTab, b3DRefOnly );
+ }
+ return mxImpl->CreateFormula( eType, aScTokArr );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateErrorFormula( sal_uInt8 nErrCode )
+{
+ return mxImpl->CreateErrorFormula( nErrCode );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateSpecialRefFormula(
+ sal_uInt8 nTokenId, const XclAddress& rXclPos )
+{
+ return mxImpl->CreateSpecialRefFormula( nTokenId, rXclPos );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateNameXFormula(
+ sal_uInt16 nExtSheet, sal_uInt16 nExtName )
+{
+ return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xehelper.cxx b/sc/source/filter/excel/xehelper.cxx
new file mode 100644
index 000000000000..bce037bd05c1
--- /dev/null
+++ b/sc/source/filter/excel/xehelper.cxx
@@ -0,0 +1,1144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <sfx2/objsh.hxx>
+#include <vcl/font.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/itemset.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/outlobj.hxx>
+#include "scitems.hxx"
+#include <editeng/fhgtitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/svxfont.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "cell.hxx"
+#include "editutil.hxx"
+#include "patattr.hxx"
+#include "xestyle.hxx"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xecontent.hxx"
+#include "xelink.hxx"
+#include "xehelper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::i18n::XBreakIterator;
+
+// Export progress bar ========================================================
+
+XclExpProgressBar::XclExpProgressBar( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mxProgress( new ScfProgressBar( rRoot.GetDocShell(), STR_SAVE_DOC ) ),
+ mpSubProgress( 0 ),
+ mpSubRowCreate( 0 ),
+ mpSubRowFinal( 0 ),
+ mnSegRowFinal( SCF_INV_SEGMENT ),
+ mnRowCount( 0 )
+{
+}
+
+XclExpProgressBar::~XclExpProgressBar()
+{
+}
+
+void XclExpProgressBar::Initialize()
+{
+ const ScDocument& rDoc = GetDoc();
+ const XclExpTabInfo& rTabInfo = GetTabInfo();
+ SCTAB nScTabCount = rTabInfo.GetScTabCount();
+
+ // *** segment: creation of ROW records *** -------------------------------
+
+ sal_Int32 nSegRowCreate = mxProgress->AddSegment( 2000 );
+ mpSubRowCreate = &mxProgress->GetSegmentProgressBar( nSegRowCreate );
+ maSubSegRowCreate.resize( nScTabCount, SCF_INV_SEGMENT );
+
+ for( SCTAB nScTab = 0; nScTab < nScTabCount; ++nScTab )
+ {
+ if( rTabInfo.IsExportTab( nScTab ) )
+ {
+ SCCOL nLastUsedScCol;
+ SCROW nLastUsedScRow;
+ rDoc.GetTableArea( nScTab, nLastUsedScCol, nLastUsedScRow );
+ sal_Size nSegSize = static_cast< sal_Size >( nLastUsedScRow + 1 );
+ maSubSegRowCreate[ nScTab ] = mpSubRowCreate->AddSegment( nSegSize );
+ }
+ }
+
+ // *** segment: writing all ROW records *** -------------------------------
+
+ mnSegRowFinal = mxProgress->AddSegment( 1000 );
+ // sub progress bar and segment are created later in ActivateFinalRowsSegment()
+}
+
+void XclExpProgressBar::IncRowRecordCount()
+{
+ ++mnRowCount;
+}
+
+void XclExpProgressBar::ActivateCreateRowsSegment()
+{
+ DBG_ASSERT( (0 <= GetCurrScTab()) && (GetCurrScTab() < GetTabInfo().GetScTabCount()),
+ "XclExpProgressBar::ActivateCreateRowsSegment - invalid sheet" );
+ sal_Int32 nSeg = maSubSegRowCreate[ GetCurrScTab() ];
+ DBG_ASSERT( nSeg != SCF_INV_SEGMENT, "XclExpProgressBar::ActivateCreateRowsSegment - invalid segment" );
+ if( nSeg != SCF_INV_SEGMENT )
+ {
+ mpSubProgress = mpSubRowCreate;
+ mpSubProgress->ActivateSegment( nSeg );
+ }
+ else
+ mpSubProgress = 0;
+}
+
+void XclExpProgressBar::ActivateFinalRowsSegment()
+{
+ if( !mpSubRowFinal && (mnRowCount > 0) )
+ {
+ mpSubRowFinal = &mxProgress->GetSegmentProgressBar( mnSegRowFinal );
+ mpSubRowFinal->AddSegment( mnRowCount );
+ }
+ mpSubProgress = mpSubRowFinal;
+ if( mpSubProgress )
+ mpSubProgress->Activate();
+}
+
+void XclExpProgressBar::Progress()
+{
+ if( mpSubProgress && !mpSubProgress->IsFull() )
+ mpSubProgress->Progress();
+}
+
+// Calc->Excel cell address/range conversion ==================================
+
+namespace {
+
+/** Fills the passed Excel address with the passed Calc cell coordinates without checking any limits. */
+inline void lclFillAddress( XclAddress& rXclPos, SCCOL nScCol, SCROW nScRow )
+{
+ rXclPos.mnCol = static_cast< sal_uInt16 >( nScCol );
+ rXclPos.mnRow = static_cast< sal_uInt16 >( nScRow );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpAddressConverter::XclExpAddressConverter( const XclExpRoot& rRoot ) :
+ XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetXclMaxPos() )
+{
+}
+
+// cell address ---------------------------------------------------------------
+
+bool XclExpAddressConverter::CheckAddress( const ScAddress& rScPos, bool bWarn )
+{
+ // ScAddress::operator<=() doesn't do what we want here
+ bool bValidCol = (0 <= rScPos.Col()) && (rScPos.Col() <= maMaxPos.Col());
+ bool bValidRow = (0 <= rScPos.Row()) && (rScPos.Row() <= maMaxPos.Row());
+ bool bValidTab = (0 <= rScPos.Tab()) && (rScPos.Tab() <= maMaxPos.Tab());
+
+ bool bValid = bValidCol && bValidRow && bValidTab;
+ if( !bValid && bWarn )
+ {
+ mbColTrunc |= !bValidCol;
+ mbRowTrunc |= !bValidRow;
+ mbTabTrunc |= (rScPos.Tab() > maMaxPos.Tab()); // do not warn for deleted refs
+ mrTracer.TraceInvalidAddress( rScPos, maMaxPos );
+ }
+ return bValid;
+}
+
+bool XclExpAddressConverter::ConvertAddress( XclAddress& rXclPos,
+ const ScAddress& rScPos, bool bWarn )
+{
+ bool bValid = CheckAddress( rScPos, bWarn );
+ if( bValid )
+ lclFillAddress( rXclPos, rScPos.Col(), rScPos.Row() );
+ return bValid;
+}
+
+XclAddress XclExpAddressConverter::CreateValidAddress( const ScAddress& rScPos, bool bWarn )
+{
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ if( !ConvertAddress( aXclPos, rScPos, bWarn ) )
+ lclFillAddress( aXclPos, ::std::min( rScPos.Col(), maMaxPos.Col() ), ::std::min( rScPos.Row(), maMaxPos.Row() ) );
+ return aXclPos;
+}
+
+// cell range -----------------------------------------------------------------
+
+bool XclExpAddressConverter::CheckRange( const ScRange& rScRange, bool bWarn )
+{
+ return CheckAddress( rScRange.aStart, bWarn ) && CheckAddress( rScRange.aEnd, bWarn );
+}
+
+bool XclExpAddressConverter::ValidateRange( ScRange& rScRange, bool bWarn )
+{
+ rScRange.Justify();
+
+ // check start position
+ bool bValidStart = CheckAddress( rScRange.aStart, bWarn );
+ if( bValidStart )
+ {
+ // check & correct end position
+ ScAddress& rScEnd = rScRange.aEnd;
+ if( !CheckAddress( rScEnd, bWarn ) )
+ {
+ rScEnd.SetCol( ::std::min( rScEnd.Col(), maMaxPos.Col() ) );
+ rScEnd.SetRow( ::std::min( rScEnd.Row(), maMaxPos.Row() ) );
+ rScEnd.SetTab( ::std::min( rScEnd.Tab(), maMaxPos.Tab() ) );
+ }
+ }
+
+ return bValidStart;
+}
+
+bool XclExpAddressConverter::ConvertRange( XclRange& rXclRange,
+ const ScRange& rScRange, bool bWarn )
+{
+ // check start position
+ bool bValidStart = CheckAddress( rScRange.aStart, bWarn );
+ if( bValidStart )
+ {
+ lclFillAddress( rXclRange.maFirst, rScRange.aStart.Col(), rScRange.aStart.Row() );
+
+ // check & correct end position
+ SCCOL nScCol2 = rScRange.aEnd.Col();
+ SCROW nScRow2 = rScRange.aEnd.Row();
+ if( !CheckAddress( rScRange.aEnd, bWarn ) )
+ {
+ nScCol2 = ::std::min( nScCol2, maMaxPos.Col() );
+ nScRow2 = ::std::min( nScRow2, maMaxPos.Row() );
+ }
+ lclFillAddress( rXclRange.maLast, nScCol2, nScRow2 );
+ }
+ return bValidStart;
+}
+
+//UNUSED2008-05 XclRange XclExpAddressConverter::CreateValidRange( const ScRange& rScRange, bool bWarn )
+//UNUSED2008-05 {
+//UNUSED2008-05 return XclRange(
+//UNUSED2008-05 CreateValidAddress( rScRange.aStart, bWarn ),
+//UNUSED2008-05 CreateValidAddress( rScRange.aEnd, bWarn ) );
+//UNUSED2008-05 }
+
+// cell range list ------------------------------------------------------------
+
+//UNUSED2008-05 bool XclExpAddressConverter::CheckRangeList( const ScRangeList& rScRanges, bool bWarn )
+//UNUSED2008-05 {
+//UNUSED2008-05 for( ULONG nIdx = 0, nSize = rScRanges.Count(); nIdx < nSize; ++nIdx )
+//UNUSED2008-05 if( const ScRange* pScRange = rScRanges.GetObject( nIdx ) )
+//UNUSED2008-05 if( !CheckRange( *pScRange, bWarn ) )
+//UNUSED2008-05 return false;
+//UNUSED2008-05 return true;
+//UNUSED2008-05 }
+
+void XclExpAddressConverter::ValidateRangeList( ScRangeList& rScRanges, bool bWarn )
+{
+ ULONG nIdx = rScRanges.Count();
+ while( nIdx )
+ {
+ --nIdx; // backwards to keep nIdx valid
+ ScRange* pScRange = rScRanges.GetObject( nIdx );
+ if( pScRange && !CheckRange( *pScRange, bWarn ) )
+ delete rScRanges.Remove( nIdx );
+ }
+}
+
+void XclExpAddressConverter::ConvertRangeList( XclRangeList& rXclRanges,
+ const ScRangeList& rScRanges, bool bWarn )
+{
+ rXclRanges.clear();
+ for( ULONG nPos = 0, nCount = rScRanges.Count(); nPos < nCount; ++nPos )
+ {
+ if( const ScRange* pScRange = rScRanges.GetObject( nPos ) )
+ {
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ if( ConvertRange( aXclRange, *pScRange, bWarn ) )
+ rXclRanges.push_back( aXclRange );
+ }
+ }
+}
+
+// EditEngine->String conversion ==============================================
+
+namespace {
+
+String lclGetUrlRepresentation( const SvxURLField& rUrlField )
+{
+ String aRepr( rUrlField.GetRepresentation() );
+ // no representation -> use URL
+ return aRepr.Len() ? aRepr : rUrlField.GetURL();
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpHyperlinkHelper::XclExpHyperlinkHelper( const XclExpRoot& rRoot, const ScAddress& rScPos ) :
+ XclExpRoot( rRoot ),
+ maScPos( rScPos ),
+ mbMultipleUrls( false )
+{
+}
+
+XclExpHyperlinkHelper::~XclExpHyperlinkHelper()
+{
+}
+
+String XclExpHyperlinkHelper::ProcessUrlField( const SvxURLField& rUrlField )
+{
+ String aUrlRepr;
+
+ if( GetBiff() == EXC_BIFF8 ) // no HLINK records in BIFF2-BIFF7
+ {
+ // there was/is already a HLINK record
+ mbMultipleUrls = mxLinkRec.is();
+
+ mxLinkRec.reset( new XclExpHyperlink( GetRoot(), rUrlField, maScPos ) );
+
+ if( const String* pRepr = mxLinkRec->GetRepr() )
+ aUrlRepr = *pRepr;
+
+ // add URL to note text
+ ScGlobal::AddToken( maUrlList, rUrlField.GetURL(), '\n' );
+ }
+
+ // no hyperlink representation from Excel HLINK record -> use it from text field
+ return aUrlRepr.Len() ? aUrlRepr : lclGetUrlRepresentation( rUrlField );
+}
+
+bool XclExpHyperlinkHelper::HasLinkRecord() const
+{
+ return !mbMultipleUrls && mxLinkRec.is();
+}
+
+XclExpHyperlinkHelper::XclExpHyperlinkRef XclExpHyperlinkHelper::GetLinkRecord()
+{
+ if( HasLinkRecord() )
+ return mxLinkRec;
+ return XclExpHyperlinkRef();
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Creates a new formatted string from the passed unformatted string.
+
+ Creates a Unicode string or a byte string, depending on the current BIFF
+ version contained in the passed XclExpRoot object. May create a formatted
+ string object, if the text contains different script types.
+
+ @param pCellAttr
+ Cell attributes used for font formatting.
+ @param nFlags
+ Modifiers for string export.
+ @param nMaxLen
+ The maximum number of characters to store in this string.
+ @return
+ The new string object.
+ */
+XclExpStringRef lclCreateFormattedString(
+ const XclExpRoot& rRoot, const String& rText, const ScPatternAttr* pCellAttr,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ /* Create an empty Excel string object with correctly initialized BIFF mode,
+ because this function only uses Append() functions that require this. */
+ XclExpStringRef xString = XclExpStringHelper::CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+
+ // script type handling
+ Reference< XBreakIterator > xBreakIt = rRoot.GetDoc().GetBreakIterator();
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ // #i63255# get script type for leading weak characters
+ sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( rRoot, rText );
+
+ // font buffer and cell item set
+ XclExpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
+ const SfxItemSet& rItemSet = pCellAttr ? pCellAttr->GetItemSet() : rRoot.GetDoc().GetDefPattern()->GetItemSet();
+
+ // process all script portions
+ OUString aOUText( rText );
+ sal_Int32 nPortionPos = 0;
+ sal_Int32 nTextLen = aOUText.getLength();
+ while( nPortionPos < nTextLen )
+ {
+ // get script type and end position of next script portion
+ sal_Int16 nScript = xBreakIt->getScriptType( aOUText, nPortionPos );
+ sal_Int32 nPortionEnd = xBreakIt->endOfScript( aOUText, nPortionPos, nScript );
+
+ // reuse previous script for following weak portions
+ if( nScript == ApiScriptType::WEAK )
+ nScript = nLastScript;
+
+ // construct font from current text portion
+ SvxFont aFont( XclExpFontHelper::GetFontFromItemSet( rRoot, rItemSet, nScript ) );
+
+ // Excel start position of this portion
+ sal_uInt16 nXclPortionStart = xString->Len();
+ // add portion text to Excel string
+ XclExpStringHelper::AppendString( *xString, rRoot, aOUText.copy( nPortionPos, nPortionEnd - nPortionPos ) );
+ if( nXclPortionStart < xString->Len() )
+ {
+ // insert font into buffer
+ sal_uInt16 nFontIdx = rFontBuffer.Insert( aFont, EXC_COLOR_CELLTEXT );
+ // insert font index into format run vector
+ xString->AppendFormat( nXclPortionStart, nFontIdx );
+ }
+
+ // go to next script portion
+ nLastScript = nScript;
+ nPortionPos = nPortionEnd;
+ }
+
+ return xString;
+}
+
+/** Creates a new formatted string from an edit engine text object.
+
+ Creates a Unicode string or a byte string, depending on the current BIFF
+ version contained in the passed XclExpRoot object.
+
+ @param rEE
+ The edit engine in use. The text object must already be set.
+ @param nFlags
+ Modifiers for string export.
+ @param nMaxLen
+ The maximum number of characters to store in this string.
+ @return
+ The new string object.
+ */
+XclExpStringRef lclCreateFormattedString(
+ const XclExpRoot& rRoot, EditEngine& rEE, XclExpHyperlinkHelper* pLinkHelper,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ /* Create an empty Excel string object with correctly initialized BIFF mode,
+ because this function only uses Append() functions that require this. */
+ XclExpStringRef xString = XclExpStringHelper::CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+
+ // font buffer and helper item set for edit engine -> Calc item conversion
+ XclExpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
+ SfxItemSet aItemSet( *rRoot.GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
+
+ // script type handling
+ Reference< XBreakIterator > xBreakIt = rRoot.GetDoc().GetBreakIterator();
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ // #i63255# get script type for leading weak characters
+ sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( rRoot, rEE.GetText() );
+
+ // process all paragraphs
+ sal_uInt16 nParaCount = rEE.GetParagraphCount();
+ for( sal_uInt16 nPara = 0; nPara < nParaCount; ++nPara )
+ {
+ ESelection aSel( nPara, 0 );
+ String aParaText( rEE.GetText( nPara ) );
+
+ SvUShorts aPosList;
+ rEE.GetPortions( nPara, aPosList );
+
+ // process all portions in the paragraph
+ sal_uInt16 nPosCount = aPosList.Count();
+ for( sal_uInt16 nPos = 0; nPos < nPosCount; ++nPos )
+ {
+ aSel.nEndPos = static_cast< xub_StrLen >( aPosList.GetObject( nPos ) );
+ String aXclPortionText( aParaText, aSel.nStartPos, aSel.nEndPos - aSel.nStartPos );
+
+ aItemSet.ClearItem();
+ SfxItemSet aEditSet( rEE.GetAttribs( aSel ) );
+ ScPatternAttr::GetFromEditItemSet( aItemSet, aEditSet );
+
+ // get escapement value
+ short nEsc = GETITEM( aEditSet, SvxEscapementItem, EE_CHAR_ESCAPEMENT ).GetEsc();
+
+ // process text fields
+ bool bIsHyperlink = false;
+ if( aSel.nStartPos + 1 == aSel.nEndPos )
+ {
+ // test if the character is a text field
+ const SfxPoolItem* pItem;
+ if( aEditSet.GetItemState( EE_FEATURE_FIELD, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ const SvxFieldData* pField = static_cast< const SvxFieldItem* >( pItem )->GetField();
+ if( const SvxURLField* pUrlField = PTR_CAST( SvxURLField, pField ) )
+ {
+ // convert URL field to string representation
+ aXclPortionText = pLinkHelper ?
+ pLinkHelper->ProcessUrlField( *pUrlField ) :
+ lclGetUrlRepresentation( *pUrlField );
+ bIsHyperlink = true;
+ }
+ else
+ {
+ DBG_ERRORFILE( "lclCreateFormattedString - unknown text field" );
+ aXclPortionText.Erase();
+ }
+ }
+ }
+
+ // Excel start position of this portion
+ sal_uInt16 nXclPortionStart = xString->Len();
+ // add portion text to Excel string
+ XclExpStringHelper::AppendString( *xString, rRoot, aXclPortionText );
+ if( (nXclPortionStart < xString->Len()) || (aParaText.Len() == 0) )
+ {
+ /* Construct font from current edit engine text portion. Edit engine
+ creates different portions for different script types, no need to loop. */
+ sal_Int16 nScript = xBreakIt->getScriptType( aXclPortionText, 0 );
+ if( nScript == ApiScriptType::WEAK )
+ nScript = nLastScript;
+ SvxFont aFont( XclExpFontHelper::GetFontFromItemSet( rRoot, aItemSet, nScript ) );
+ nLastScript = nScript;
+
+ // add escapement
+ aFont.SetEscapement( nEsc );
+ // modify automatic font color for hyperlinks
+ if( bIsHyperlink && (GETITEM( aItemSet, SvxColorItem, ATTR_FONT_COLOR ).GetValue().GetColor() == COL_AUTO) )
+ aFont.SetColor( Color( COL_LIGHTBLUE ) );
+
+ // insert font into buffer
+ sal_uInt16 nFontIdx = rFontBuffer.Insert( aFont, EXC_COLOR_CELLTEXT );
+ // insert font index into format run vector
+ xString->AppendFormat( nXclPortionStart, nFontIdx );
+ }
+
+ aSel.nStartPos = aSel.nEndPos;
+ }
+
+ // add trailing newline (important for correct character index calculation)
+ if( nPara + 1 < nParaCount )
+ XclExpStringHelper::AppendChar( *xString, rRoot, '\n' );
+ }
+
+ return xString;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString( new XclExpString );
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ xString->Assign( rString, nFlags, nMaxLen );
+ else
+ xString->AssignByte( rString, rRoot.GetTextEncoding(), nFlags, nMaxLen );
+ return xString;
+}
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString = CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+ AppendChar( *xString, rRoot, cChar );
+ return xString;
+}
+
+void XclExpStringHelper::AppendString( XclExpString& rXclString, const XclExpRoot& rRoot, const String& rString )
+{
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ rXclString.Append( rString );
+ else
+ rXclString.AppendByte( rString, rRoot.GetTextEncoding() );
+}
+
+void XclExpStringHelper::AppendChar( XclExpString& rXclString, const XclExpRoot& rRoot, sal_Unicode cChar )
+{
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ rXclString.Append( cChar );
+ else
+ rXclString.AppendByte( cChar, rRoot.GetTextEncoding() );
+}
+
+XclExpStringRef XclExpStringHelper::CreateCellString(
+ const XclExpRoot& rRoot, const ScStringCell& rStringCell, const ScPatternAttr* pCellAttr,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ String aCellText;
+ rStringCell.GetString( aCellText );
+ return lclCreateFormattedString( rRoot, aCellText, pCellAttr, nFlags, nMaxLen );
+}
+
+XclExpStringRef XclExpStringHelper::CreateCellString(
+ const XclExpRoot& rRoot, const ScEditCell& rEditCell, const ScPatternAttr* pCellAttr,
+ XclExpHyperlinkHelper& rLinkHelper, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString;
+ if( const EditTextObject* pEditObj = rEditCell.GetData() )
+ {
+ // formatted cell
+ ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
+ BOOL bOldUpdateMode = rEE.GetUpdateMode();
+ rEE.SetUpdateMode( TRUE );
+ // default items
+ const SfxItemSet& rItemSet = pCellAttr ? pCellAttr->GetItemSet() : rRoot.GetDoc().GetDefPattern()->GetItemSet();
+ SfxItemSet* pEEItemSet = new SfxItemSet( rEE.GetEmptyItemSet() );
+ ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
+ rEE.SetDefaults( pEEItemSet ); // edit engine takes ownership
+ // create the string
+ rEE.SetText( *pEditObj );
+ xString = lclCreateFormattedString( rRoot, rEE, &rLinkHelper, nFlags, nMaxLen );
+ rEE.SetUpdateMode( bOldUpdateMode );
+ }
+ else
+ {
+ // unformatted cell
+ String aCellText;
+ rEditCell.GetString( aCellText );
+ xString = lclCreateFormattedString( rRoot, aCellText, pCellAttr, nFlags, nMaxLen );
+ }
+ return xString;
+}
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, const SdrTextObj& rTextObj,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString;
+ if( const OutlinerParaObject* pParaObj = rTextObj.GetOutlinerParaObject() )
+ {
+ EditEngine& rEE = rRoot.GetDrawEditEngine();
+ BOOL bOldUpdateMode = rEE.GetUpdateMode();
+ rEE.SetUpdateMode( TRUE );
+ // create the string
+ rEE.SetText( pParaObj->GetTextObject() );
+ xString = lclCreateFormattedString( rRoot, rEE, 0, nFlags, nMaxLen );
+ rEE.SetUpdateMode( bOldUpdateMode );
+ // limit formats - TODO: BIFF dependent
+ if( !xString->IsEmpty() )
+ {
+ xString->LimitFormatCount( EXC_MAXRECSIZE_BIFF8 / 8 - 1 );
+ xString->AppendTrailingFormat( EXC_FONT_APP );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpStringHelper::CreateString - textbox without para object" );
+ // create BIFF dependent empty Excel string
+ xString = CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+ }
+ return xString;
+}
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, const EditTextObject& rEditObj,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString;
+ EditEngine& rEE = rRoot.GetDrawEditEngine();
+ BOOL bOldUpdateMode = rEE.GetUpdateMode();
+ rEE.SetUpdateMode( TRUE );
+ rEE.SetText( rEditObj );
+ xString = lclCreateFormattedString( rRoot, rEE, 0, nFlags, nMaxLen );
+ rEE.SetUpdateMode( bOldUpdateMode );
+ // limit formats - TODO: BIFF dependent
+ if( !xString->IsEmpty() )
+ {
+ xString->LimitFormatCount( EXC_MAXRECSIZE_BIFF8 / 8 - 1 );
+ xString->AppendTrailingFormat( EXC_FONT_APP );
+ }
+ return xString;
+}
+
+sal_Int16 XclExpStringHelper::GetLeadingScriptType( const XclExpRoot& rRoot, const String& rString )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ Reference< XBreakIterator > xBreakIt = rRoot.GetDoc().GetBreakIterator();
+ OUString aOUString( rString );
+ sal_Int32 nStrPos = 0;
+ sal_Int32 nStrLen = aOUString.getLength();
+ sal_Int16 nScript = ApiScriptType::WEAK;
+ while( (nStrPos < nStrLen) && (nScript == ApiScriptType::WEAK) )
+ {
+ nScript = xBreakIt->getScriptType( aOUString, nStrPos );
+ nStrPos = xBreakIt->endOfScript( aOUString, nStrPos, nScript );
+ }
+ return (nScript == ApiScriptType::WEAK) ? rRoot.GetDefApiScript() : nScript;
+}
+
+// Header/footer conversion ===================================================
+
+XclExpHFConverter::XclExpHFConverter( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mrEE( rRoot.GetHFEditEngine() ),
+ mnTotalHeight( 0 )
+{
+}
+
+void XclExpHFConverter::GenerateString(
+ const EditTextObject* pLeftObj,
+ const EditTextObject* pCenterObj,
+ const EditTextObject* pRightObj )
+{
+ maHFString.Erase();
+ mnTotalHeight = 0;
+ AppendPortion( pLeftObj, 'L' );
+ AppendPortion( pCenterObj, 'C' );
+ AppendPortion( pRightObj, 'R' );
+}
+
+void XclExpHFConverter::AppendPortion( const EditTextObject* pTextObj, sal_Unicode cPortionCode )
+{
+ if( !pTextObj ) return;
+
+ String aText;
+ sal_Int32 nHeight = 0;
+ SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
+
+ // edit engine
+ BOOL bOldUpdateMode = mrEE.GetUpdateMode();
+ mrEE.SetUpdateMode( TRUE );
+ mrEE.SetText( *pTextObj );
+
+ // font information
+ XclFontData aFontData, aNewData;
+ if( const XclExpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
+ {
+ aFontData = pFirstFont->GetFontData();
+ (aFontData.mnHeight += 10) /= 20; // using pt here, not twips
+ }
+ else
+ aFontData.mnHeight = 10;
+
+ const FontList* pFontList = 0;
+ if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ if( const SvxFontListItem* pInfoItem = static_cast< const SvxFontListItem* >(
+ pDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ) )
+ pFontList = pInfoItem->GetFontList();
+ }
+
+ sal_uInt16 nParaCount = mrEE.GetParagraphCount();
+ for( sal_uInt16 nPara = 0; nPara < nParaCount; ++nPara )
+ {
+ ESelection aSel( nPara, 0 );
+ String aParaText;
+ sal_Int32 nParaHeight = 0;
+ SvUShorts aPosList;
+ mrEE.GetPortions( nPara, aPosList );
+
+ sal_uInt16 nPosCount = aPosList.Count();
+ for( sal_uInt16 nPos = 0; nPos < nPosCount; ++nPos )
+ {
+ aSel.nEndPos = static_cast< xub_StrLen >( aPosList.GetObject( nPos ) );
+ if( aSel.nStartPos < aSel.nEndPos )
+ {
+
+// --- font attributes ---
+
+ Font aFont;
+ aItemSet.ClearItem();
+ SfxItemSet aEditSet( mrEE.GetAttribs( aSel ) );
+ ScPatternAttr::GetFromEditItemSet( aItemSet, aEditSet );
+ ScPatternAttr::GetFont( aFont, aItemSet, SC_AUTOCOL_RAW );
+
+ // font name and style
+ aNewData.maName = XclTools::GetXclFontName( aFont.GetName() );
+ aNewData.mnWeight = (aFont.GetWeight() > WEIGHT_NORMAL) ? EXC_FONTWGHT_BOLD : EXC_FONTWGHT_NORMAL;
+ aNewData.mbItalic = (aFont.GetItalic() != ITALIC_NONE);
+ bool bNewFont = !(aFontData.maName == aNewData.maName);
+ bool bNewStyle = (aFontData.mnWeight != aNewData.mnWeight) ||
+ (aFontData.mbItalic != aNewData.mbItalic);
+ if( bNewFont || (bNewStyle && pFontList) )
+ {
+ aParaText.AppendAscii( "&\"" ).Append( aNewData.maName );
+ if( pFontList )
+ {
+ FontInfo aFontInfo( pFontList->Get(
+ aNewData.maName,
+ (aNewData.mnWeight > EXC_FONTWGHT_NORMAL) ? WEIGHT_BOLD : WEIGHT_NORMAL,
+ aNewData.mbItalic ? ITALIC_NORMAL : ITALIC_NONE ) );
+ aNewData.maStyle = pFontList->GetStyleName( aFontInfo );
+ if( aNewData.maStyle.Len() )
+ aParaText.Append( ',' ).Append( aNewData.maStyle );
+ }
+ aParaText.Append( '"' );
+ }
+
+ // height
+ // is calculated wrong in ScPatternAttr::GetFromEditItemSet, because already in twips and not 100thmm
+ // -> get it directly from edit engine item set
+ aNewData.mnHeight = ulimit_cast< sal_uInt16 >( GETITEM( aEditSet, SvxFontHeightItem, EE_CHAR_FONTHEIGHT ).GetHeight() );
+ (aNewData.mnHeight += 10) /= 20;
+ bool bFontHtChanged = (aFontData.mnHeight != aNewData.mnHeight);
+ if( bFontHtChanged )
+ aParaText.Append( '&' ).Append( String::CreateFromInt32( aNewData.mnHeight ) );
+ // update maximum paragraph height, convert to twips
+ nParaHeight = ::std::max< sal_Int32 >( nParaHeight, aNewData.mnHeight * 20 );
+
+ // underline
+ aNewData.mnUnderline = EXC_FONTUNDERL_NONE;
+ switch( aFont.GetUnderline() )
+ {
+ case UNDERLINE_NONE: aNewData.mnUnderline = EXC_FONTUNDERL_NONE; break;
+ case UNDERLINE_SINGLE: aNewData.mnUnderline = EXC_FONTUNDERL_SINGLE; break;
+ case UNDERLINE_DOUBLE: aNewData.mnUnderline = EXC_FONTUNDERL_DOUBLE; break;
+ default: aNewData.mnUnderline = EXC_FONTUNDERL_SINGLE;
+ }
+ if( aFontData.mnUnderline != aNewData.mnUnderline )
+ {
+ sal_uInt8 nTmpUnderl = (aNewData.mnUnderline == EXC_FONTUNDERL_NONE) ?
+ aFontData.mnUnderline : aNewData.mnUnderline;
+ aParaText.AppendAscii( (nTmpUnderl == EXC_FONTUNDERL_SINGLE) ? "&U" : "&E" );
+ }
+
+ // strikeout
+ aNewData.mbStrikeout = (aFont.GetStrikeout() != STRIKEOUT_NONE);
+ if( aFontData.mbStrikeout != aNewData.mbStrikeout )
+ aParaText.AppendAscii( "&S" );
+
+ // super/sub script
+ const SvxEscapementItem& rEscapeItem = GETITEM( aEditSet, SvxEscapementItem, EE_CHAR_ESCAPEMENT );
+ aNewData.SetScEscapement( rEscapeItem.GetEsc() );
+ if( aFontData.mnEscapem != aNewData.mnEscapem )
+ {
+ switch(aNewData.mnEscapem)
+ {
+ // close the previous super/sub script.
+ case EXC_FONTESC_NONE: aParaText.AppendAscii( (aFontData.mnEscapem == EXC_FONTESC_SUPER) ? "&X" : "&Y" ); break;
+ case EXC_FONTESC_SUPER: aParaText.AppendAscii( "&X" ); break;
+ case EXC_FONTESC_SUB: aParaText.AppendAscii( "&Y" ); break;
+ default: break;
+ }
+ }
+
+ aFontData = aNewData;
+
+// --- text content or text fields ---
+
+ const SfxPoolItem* pItem;
+ if( (aSel.nStartPos + 1 == aSel.nEndPos) && // fields are single characters
+ (aEditSet.GetItemState( EE_FEATURE_FIELD, sal_False, &pItem ) == SFX_ITEM_SET) )
+ {
+ if( const SvxFieldData* pFieldData = static_cast< const SvxFieldItem* >( pItem )->GetField() )
+ {
+ if( pFieldData->ISA( SvxPageField ) )
+ aParaText.AppendAscii( "&P" );
+ else if( pFieldData->ISA( SvxPagesField ) )
+ aParaText.AppendAscii( "&N" );
+ else if( pFieldData->ISA( SvxDateField ) )
+ aParaText.AppendAscii( "&D" );
+ else if( pFieldData->ISA( SvxTimeField ) || pFieldData->ISA( SvxExtTimeField ) )
+ aParaText.AppendAscii( "&T" );
+ else if( pFieldData->ISA( SvxTableField ) )
+ aParaText.AppendAscii( "&A" );
+ else if( pFieldData->ISA( SvxFileField ) ) // title -> file name
+ aParaText.AppendAscii( "&F" );
+ else if( const SvxExtFileField* pFileField = PTR_CAST( SvxExtFileField, pFieldData ) )
+ {
+ switch( pFileField->GetFormat() )
+ {
+ case SVXFILEFORMAT_NAME_EXT:
+ case SVXFILEFORMAT_NAME:
+ aParaText.AppendAscii( "&F" );
+ break;
+ case SVXFILEFORMAT_PATH:
+ aParaText.AppendAscii( "&Z" );
+ break;
+ case SVXFILEFORMAT_FULLPATH:
+ aParaText.AppendAscii( "&Z&F" );
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpHFConverter::AppendPortion - unknown file field" );
+ }
+ }
+ }
+ }
+ else
+ {
+ String aPortionText( mrEE.GetText( aSel ) );
+ aPortionText.SearchAndReplaceAll( String( '&' ), String( RTL_CONSTASCII_USTRINGPARAM( "&&" ) ) );
+ // #i17440# space between font height and numbers in text
+ if( bFontHtChanged && aParaText.Len() && aPortionText.Len() )
+ {
+ sal_Unicode cLast = aParaText.GetChar( aParaText.Len() - 1 );
+ sal_Unicode cFirst = aPortionText.GetChar( 0 );
+ if( ('0' <= cLast) && (cLast <= '9') && ('0' <= cFirst) && (cFirst <= '9') )
+ aParaText.Append( ' ' );
+ }
+ aParaText.Append( aPortionText );
+ }
+ }
+
+ aSel.nStartPos = aSel.nEndPos;
+ }
+
+ ScGlobal::AddToken( aText, aParaText, '\n' );
+ if( nParaHeight == 0 )
+ nParaHeight = aFontData.mnHeight * 20; // points -> twips
+ nHeight += nParaHeight;
+ }
+
+ mrEE.SetUpdateMode( bOldUpdateMode );
+
+ if( aText.Len() )
+ {
+ maHFString.Append( '&' ).Append( cPortionCode ).Append( aText );
+ mnTotalHeight = ::std::max( mnTotalHeight, nHeight );
+ }
+}
+
+// URL conversion =============================================================
+
+namespace {
+
+/** Converts the file URL passed in rUrl to a URL in DOS notation (local or UNC).
+ @param rUrl (in/out-param) In: URL to convert; Out: Converted URL in DOS notation.
+ @param rBasePath Base path for relative URLs.
+ @param bSaveRelUrl Converts to a relative URL, using rBasePath.
+ @return True = Conversion successful, rUrl contains converted file URL. */
+bool lclConvertToDos( String& rUrl, const String& rBasePath, bool bSaveRelUrl )
+{
+ String aDosUrl( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ bool bRet = (aDosUrl.Len() > 0);
+ if( bRet && bSaveRelUrl )
+ {
+ // try to convert to relative path
+ String aDosBase( INetURLObject( rBasePath ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ if( aDosBase.Len() )
+ {
+ xub_StrLen nPos;
+
+ // --- 1st step: delete equal subdirectories ---
+
+ // special handling for UNC
+ xub_StrLen nStartSearch = aDosBase.EqualsAscii( "\\\\", 0, 2 ) ? 2 : 0;
+ bool bEqualBase = false;
+ bool bLoop = true;
+ while( bLoop && ((nPos = aDosBase.Search( '\\', nStartSearch )) != STRING_NOTFOUND) )
+ {
+ bLoop = (TRUE == aDosBase.Equals( aDosUrl, 0, nPos + 1 ));
+ if( bLoop )
+ {
+ aDosBase.Erase( 0, nPos + 1 );
+ aDosUrl.Erase( 0, nPos + 1 );
+ nStartSearch = 0;
+ bEqualBase = true;
+ }
+ }
+
+ // --- 2nd step: add parent directory levels ---
+
+ if( bEqualBase )
+ {
+ while( (nPos = aDosBase.Search( '\\' )) != STRING_NOTFOUND )
+ {
+ aDosBase.Erase( 0, nPos + 1 );
+ aDosUrl.InsertAscii( "..\\", 0 );
+ }
+ }
+ }
+ rUrl = aDosUrl;
+ }
+ return bRet;
+}
+
+/** Encodes special parts of the URL, i.e. directory separators and volume names.
+ @param pTableName Pointer to a table name to be encoded in this URL, or 0. */
+void lclEncodeDosUrl( XclBiff eBiff, String& rUrl, const String* pTableName = 0 )
+{
+ if( rUrl.Len() )
+ {
+ String aOldUrl( rUrl );
+ rUrl = EXC_URLSTART_ENCODED;
+
+ if( (aOldUrl.Len() > 2) && aOldUrl.EqualsAscii( "\\\\", 0, 2 ) )
+ {
+ // UNC
+ rUrl.Append( EXC_URL_DOSDRIVE ).Append( '@' );
+ aOldUrl.Erase( 0, 2 );
+ }
+ else if( (aOldUrl.Len() > 2) && aOldUrl.EqualsAscii( ":\\", 1, 2 ) )
+ {
+ // drive letter
+ rUrl.Append( EXC_URL_DOSDRIVE ).Append( aOldUrl.GetChar( 0 ) );
+ aOldUrl.Erase( 0, 3 );
+ }
+
+ // directories
+ xub_StrLen nPos;
+ while( (nPos = aOldUrl.Search( '\\' )) != STRING_NOTFOUND )
+ {
+ if( aOldUrl.EqualsAscii( "..", 0, 2 ) )
+ rUrl.Append( EXC_URL_PARENTDIR ); // parent dir
+ else
+ rUrl.Append( aOldUrl.GetBuffer(), nPos ).Append( EXC_URL_SUBDIR );
+ aOldUrl.Erase( 0, nPos + 1 );
+ }
+
+ // file name
+ if( pTableName ) // enclose file name in brackets if table name follows
+ rUrl.Append( '[' ).Append( aOldUrl ).Append( ']' );
+ else
+ rUrl.Append( aOldUrl );
+ }
+ else // empty URL -> self reference
+ {
+ switch( eBiff )
+ {
+ case EXC_BIFF5:
+ rUrl = pTableName ? EXC_URLSTART_SELFENCODED : EXC_URLSTART_SELF;
+ break;
+ case EXC_BIFF8:
+ DBG_ASSERT( pTableName, "lclEncodeDosUrl - sheet name required for BIFF8" );
+ rUrl = EXC_URLSTART_SELF;
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ }
+
+ // table name
+ if( pTableName )
+ rUrl.Append( *pTableName );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+String XclExpUrlHelper::EncodeUrl( const XclExpRoot& rRoot, const String& rAbsUrl, const String* pTableName )
+{
+ String aDosUrl( rAbsUrl );
+ if( !aDosUrl.Len() || lclConvertToDos( aDosUrl, rRoot.GetBasePath(), rRoot.IsRelUrl() ) )
+ lclEncodeDosUrl( rRoot.GetBiff(), aDosUrl, pTableName );
+ return aDosUrl;
+}
+
+String XclExpUrlHelper::EncodeDde( const String& rApplic, const String rTopic )
+{
+ String aDde( rApplic );
+ aDde.Append( EXC_DDE_DELIM ).Append( rTopic );
+ return aDde;
+}
+
+// Cached Value Lists =========================================================
+
+XclExpCachedMatrix::XclExpCachedMatrix( const ScMatrix& rMatrix )
+ : mrMatrix( rMatrix )
+{
+ mrMatrix.IncRef();
+}
+XclExpCachedMatrix::~XclExpCachedMatrix()
+{
+ mrMatrix.DecRef();
+}
+
+void XclExpCachedMatrix::GetDimensions( SCSIZE & nCols, SCSIZE & nRows ) const
+{
+ mrMatrix.GetDimensions( nCols, nRows );
+
+ DBG_ASSERT( nCols && nRows, "XclExpCachedMatrix::GetDimensions - empty matrix" );
+ DBG_ASSERT( nCols <= 256, "XclExpCachedMatrix::GetDimensions - too many columns" );
+}
+
+sal_Size XclExpCachedMatrix::GetSize() const
+{
+ SCSIZE nCols, nRows;
+
+ GetDimensions( nCols, nRows );
+
+ /* The returned size may be wrong if the matrix contains strings. The only
+ effect is that the export stream has to update a wrong record size which is
+ faster than to iterate through all cached values and calculate their sizes. */
+ return 3 + 9 * (nCols * nRows);
+}
+
+void XclExpCachedMatrix::Save( XclExpStream& rStrm ) const
+{
+ SCSIZE nCols, nRows;
+
+ GetDimensions( nCols, nRows );
+
+ if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
+ // in BIFF2-BIFF7: 256 columns represented by 0 columns
+ rStrm << static_cast< sal_uInt8 >( nCols ) << static_cast< sal_uInt16 >( nRows );
+ else
+ // in BIFF8: columns and rows decreaed by 1
+ rStrm << static_cast< sal_uInt8 >( nCols - 1 ) << static_cast< sal_uInt16 >( nRows - 1 );
+
+ for( SCSIZE nRow = 0; nRow < nRows; ++nRow )
+ {
+ for( SCSIZE nCol = 0; nCol < nCols; ++nCol )
+ {
+ ScMatValType nMatValType = SC_MATVAL_VALUE;
+ const ScMatrixValue* pMatVal = mrMatrix.Get( nCol, nRow, nMatValType );
+
+ if( !pMatVal || SC_MATVAL_EMPTY == nMatValType )
+ {
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_EMPTY;
+ rStrm.WriteZeroBytes( 8 );
+ }
+ else if( ScMatrix::IsNonValueType( nMatValType ) )
+ {
+ XclExpString aStr( pMatVal->GetString(), EXC_STR_DEFAULT );
+ rStrm.SetSliceSize( 6 );
+ rStrm << EXC_CACHEDVAL_STRING << aStr;
+ }
+ else if( SC_MATVAL_BOOLEAN == nMatValType )
+ {
+ sal_Int8 nBool = pMatVal->GetBoolean();
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_BOOL << nBool;
+ rStrm.WriteZeroBytes( 7 );
+ }
+ else if( USHORT nScError = pMatVal->GetError() )
+ {
+ sal_Int8 nError ( XclTools::GetXclErrorCode( nScError ) );
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_ERROR << nError;
+ rStrm.WriteZeroBytes( 7 );
+ }
+ else
+ {
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_DOUBLE << pMatVal->fVal;
+ }
+ }
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xelink.cxx b/sc/source/filter/excel/xelink.cxx
new file mode 100644
index 000000000000..fcf738527025
--- /dev/null
+++ b/sc/source/filter/excel/xelink.cxx
@@ -0,0 +1,2371 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xelink.hxx"
+
+#include <algorithm>
+#include <unotools/collatorwrapper.hxx>
+#include <svl/zforlist.hxx>
+#include "document.hxx"
+#include "cell.hxx"
+#include "scextopt.hxx"
+#include "externalrefmgr.hxx"
+
+#include <vector>
+#include <memory>
+
+using ::std::auto_ptr;
+using ::std::find_if;
+using ::std::vector;
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+
+// ============================================================================
+// *** Helper classes ***
+// ============================================================================
+
+// External names =============================================================
+
+/** This is a base class for any external name (i.e. add-in names or DDE links).
+ @descr Derived classes implement creation and export of the external names. */
+class XclExpExtNameBase : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** @param nFlags The flags to export. */
+ explicit XclExpExtNameBase( const XclExpRoot& rRoot,
+ const String& rName, sal_uInt16 nFlags = 0 );
+ virtual ~XclExpExtNameBase();
+
+ /** Returns the name string of the external name. */
+ inline const String& GetName() const { return maName; }
+
+private:
+ /** Writes the start of the record that is equal in all EXTERNNAME records and calls WriteAddData(). */
+ virtual void WriteBody( XclExpStream& rStrm );
+ /** Called to write additional data following the common record contents.
+ @descr Derived classes should overwrite this function to write their data. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+
+private:
+ String maName; /// Calc name (title) of the external name.
+ XclExpStringRef mxName; /// Excel name (title) of the external name.
+ sal_uInt16 mnFlags; /// Flags for record export.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an EXTERNNAME record for an add-in function name. */
+class XclExpExtNameAddIn : public XclExpExtNameBase
+{
+public:
+ explicit XclExpExtNameAddIn( const XclExpRoot& rRoot, const String& rName );
+
+private:
+ /** Writes additional record contents. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an EXTERNNAME record for a DDE link. */
+class XclExpExtNameDde : public XclExpExtNameBase
+{
+public:
+ explicit XclExpExtNameDde( const XclExpRoot& rRoot, const String& rName,
+ sal_uInt16 nFlags, const ScMatrix* pResults = 0 );
+
+private:
+ /** Writes additional record contents. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpCachedMatrix > XclExpCachedMatRef;
+ XclExpCachedMatRef mxMatrix; /// Cached results of the DDE link.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpSupbook;
+
+class XclExpExtName : public XclExpExtNameBase
+{
+public:
+ explicit XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const String& rName,
+ const ScExternalRefCache::TokenArrayRef pArray );
+
+private:
+ /** Writes additional record contents. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+
+private:
+ const XclExpSupbook& mrSupbook;
+ auto_ptr<ScTokenArray> mpArray;
+};
+
+// List of external names =====================================================
+
+/** List of all external names of a sheet. */
+class XclExpExtNameBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpExtNameBuffer( const XclExpRoot& rRoot );
+
+ /** Inserts an add-in function name
+ @return The 1-based (Excel-like) list index of the name. */
+ sal_uInt16 InsertAddIn( const String& rName );
+ /** InsertEuroTool */
+ sal_uInt16 InsertEuroTool( const String& rName );
+ /** Inserts a DDE link.
+ @return The 1-based (Excel-like) list index of the DDE link. */
+ sal_uInt16 InsertDde( const String& rApplic, const String& rTopic, const String& rItem );
+
+ sal_uInt16 InsertExtName( const XclExpSupbook& rSupbook, const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ /** Writes the EXTERNNAME record list. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpExtNameBase > XclExpExtNameList;
+ typedef XclExpExtNameList::RecordRefType XclExpExtNameRef;
+
+private:
+ /** Returns the 1-based (Excel-like) list index of the external name or 0, if not found. */
+ sal_uInt16 GetIndex( const String& rName ) const;
+ /** Appends the passed newly crested external name.
+ @return The 1-based (Excel-like) list index of the appended name. */
+ sal_uInt16 AppendNew( XclExpExtNameBase* pExtName );
+
+private:
+ XclExpExtNameList maNameList; /// The list with all EXTERNNAME records.
+};
+
+// Cached external cells ======================================================
+
+/** Stores the contents of a consecutive row of external cells (record CRN). */
+class XclExpCrn : public XclExpRecord
+{
+public:
+ explicit XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue );
+
+ /** Returns true, if the passed value could be appended to this record. */
+ bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+ void WriteBool( XclExpStream& rStrm, bool bValue );
+ void WriteDouble( XclExpStream& rStrm, double fValue );
+ void WriteString( XclExpStream& rStrm, const OUString& rValue );
+ void WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode );
+ void WriteEmpty( XclExpStream& rStrm );
+
+private:
+ typedef ::std::vector< Any > CachedValues;
+
+ CachedValues maValues; /// All cached values.
+ SCCOL mnScCol; /// Column index of the first external cell.
+ SCROW mnScRow; /// Row index of the external cells.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the record XCT which is the header record of a CRN record list.
+ */
+class XclExpXct : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpXct( const XclExpRoot& rRoot,
+ const String& rTabName, sal_uInt16 nSBTab,
+ ScExternalRefCache::TableTypeRef xCacheTable );
+
+ /** Returns the external sheet name. */
+ inline const XclExpString& GetTabName() const { return maTabName; }
+
+ /** Stores all cells in the given range in the CRN list. */
+ void StoreCellRange( const ScRange& rRange );
+
+ void StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken );
+ void StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken );
+
+ /** Writes the XCT and all CRN records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ ScExternalRefCache::TableTypeRef mxCacheTable;
+ ScMarkData maUsedCells; /// Contains addresses of all stored cells.
+ ScRange maBoundRange; /// Bounding box of maUsedCells.
+ XclExpString maTabName; /// Sheet name of the external sheet.
+ sal_uInt16 mnSBTab; /// Referred sheet index in SUPBOOK record.
+};
+
+// External documents (EXTERNSHEET/SUPBOOK), base class =======================
+
+/** Base class for records representing external sheets/documents.
+
+ In BIFF5/BIFF7, this record is the EXTERNSHEET record containing one sheet
+ of the own or an external document. In BIFF8, this record is the SUPBOOK
+ record representing the entire own or external document with all referenced
+ sheets.
+ */
+class XclExpExternSheetBase : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpExternSheetBase( const XclExpRoot& rRoot,
+ sal_uInt16 nRecId, sal_uInt32 nRecSize = 0 );
+
+protected:
+ /** Creates and returns the list of EXTERNNAME records. */
+ XclExpExtNameBuffer& GetExtNameBuffer();
+ /** Creates and returns the list of EXTERNNAME records. */
+ void WriteExtNameBuffer( XclExpStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpExtNameBuffer > XclExpExtNameBfrRef;
+ XclExpExtNameBfrRef mxExtNameBfr; /// List of EXTERNNAME records.
+};
+
+// External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
+
+/** Represents an EXTERNSHEET record containing the URL and sheet name of a sheet.
+ @descr This class is used up to BIFF7 only, writing a BIFF8 EXTERNSHEET
+ record is implemented directly in the link manager. */
+class XclExpExternSheet : public XclExpExternSheetBase
+{
+public:
+ /** Creates an EXTERNSHEET record containing a special code (i.e. own document or sheet). */
+ explicit XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode );
+ /** Creates an EXTERNSHEET record referring to an internal sheet. */
+ explicit XclExpExternSheet( const XclExpRoot& rRoot, const String& rTabName );
+
+ /** Finds or inserts an EXTERNNAME record for add-ins.
+ @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
+ sal_uInt16 InsertAddIn( const String& rName );
+
+ /** Writes the EXTERNSHEET and all EXTERNNAME, XCT and CRN records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Initializes the record data with the passed encoded URL. */
+ void Init( const String& rEncUrl );
+ /** Writes the contents of the EXTERNSHEET record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpString maTabName; /// The name of the sheet.
+};
+
+// External documents (SUPBOOK, BIFF8) ========================================
+
+/** The SUPBOOK record contains data for an external document (URL, sheet names, external values). */
+class XclExpSupbook : public XclExpExternSheetBase
+{
+public:
+ /** Creates a SUPBOOK record for internal references. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount );
+ /** Creates a SUPBOOK record for add-in functions. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot );
+ /** EUROTOOL SUPBOOK */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl, XclSupbookType );
+ /** Creates a SUPBOOK record for an external document. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl );
+ /** Creates a SUPBOOK record for a DDE link. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic );
+
+ /** Returns true, if this SUPBOOK contains the passed URL of an external document. */
+ bool IsUrlLink( const String& rUrl ) const;
+ /** Returns true, if this SUPBOOK contains the passed DDE link. */
+ bool IsDdeLink( const String& rApplic, const String& rTopic ) const;
+ /** Fills the passed reference log entry with the URL and sheet names. */
+ void FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
+ sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const;
+
+ /** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */
+ void StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab );
+
+ void StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const ::formula::FormulaToken& rToken );
+ void StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const ::formula::FormulaToken& rToken );
+
+ sal_uInt16 GetTabIndex( const String& rTabName ) const;
+ sal_uInt16 GetTabCount() const;
+
+ /** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */
+ sal_uInt16 InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable );
+ /** Finds or inserts an EXTERNNAME record for add-ins.
+ @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
+ sal_uInt16 InsertAddIn( const String& rName );
+ /** InsertEuroTool */
+ sal_uInt16 InsertEuroTool( const String& rName );
+ /** Finds or inserts an EXTERNNAME record for DDE links.
+ @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
+ sal_uInt16 InsertDde( const String& rItem );
+
+ sal_uInt16 InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ /** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Returns the sheet name inside of this SUPBOOK. */
+ const XclExpString* GetTabName( sal_uInt16 nSBTab ) const;
+
+ /** Writes the SUPBOOK record contents. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpXct > XclExpXctList;
+ typedef XclExpXctList::RecordRefType XclExpXctRef;
+
+ XclExpXctList maXctList; /// List of XCT records (which contain CRN records).
+ String maUrl; /// URL of the external document or application name for DDE.
+ String maDdeTopic; /// Topic of an DDE link.
+ XclExpString maUrlEncoded; /// Document name encoded for Excel.
+ XclSupbookType meType; /// Type of this SUPBOOK record.
+ sal_uInt16 mnXclTabCount; /// Number of internal sheets.
+};
+
+// All SUPBOOKS in a document =================================================
+
+/** This struct contains a sheet index range for 3D references.
+ @descr This reference consists of an index to a SUPBOOK record and indexes
+ to SUPBOOK sheet names. */
+struct XclExpXti
+{
+ sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
+ sal_uInt16 mnFirstSBTab; /// Index to the first sheet of the range in the SUPBOOK.
+ sal_uInt16 mnLastSBTab; /// Index to the last sheet of the range in the SUPBOOK.
+
+ inline explicit XclExpXti() : mnSupbook( 0 ), mnFirstSBTab( 0 ), mnLastSBTab( 0 ) {}
+ inline explicit XclExpXti( sal_uInt16 nSupbook, sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) :
+ mnSupbook( nSupbook ), mnFirstSBTab( nFirstSBTab ), mnLastSBTab( nLastSBTab ) {}
+
+ /** Writes this XTI structure (inside of the EXTERNSHEET record). */
+ inline void Save( XclExpStream& rStrm ) const
+ { rStrm << mnSupbook << mnFirstSBTab << mnLastSBTab; }
+};
+
+inline bool operator==( const XclExpXti& rLeft, const XclExpXti& rRight )
+{
+ return
+ (rLeft.mnSupbook == rRight.mnSupbook) &&
+ (rLeft.mnFirstSBTab == rRight.mnFirstSBTab) &&
+ (rLeft.mnLastSBTab == rRight.mnLastSBTab);
+}
+
+// ----------------------------------------------------------------------------
+
+/** Contains a list of all SUPBOOK records and index arrays of external sheets. */
+class XclExpSupbookBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpSupbookBuffer( const XclExpRoot& rRoot );
+
+ /** Finds SUPBOOK index and SUPBOOK sheet range from given Excel sheet range.
+ @return An XTI structure containing SUPBOOK and sheet indexes. */
+ XclExpXti GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
+ XclExpRefLogEntry* pRefLogEntry = 0 ) const;
+
+ /** Stores all cells in the given range in a CRN record list. */
+ void StoreCellRange( const ScRange& rRange );
+
+ void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell );
+ void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange );
+
+ /** Finds or inserts an EXTERNNAME record for an add-in function name.
+ @param rnSupbook Returns the index of the SUPBOOK record which contains the add-in function name.
+ @param rnExtName Returns the 1-based EXTERNNAME record index. */
+ bool InsertAddIn(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rName );
+ /** InsertEuroTool */
+ bool InsertEuroTool(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rName );
+ /** Finds or inserts an EXTERNNAME record for DDE links.
+ @param rnSupbook Returns the index of the SUPBOOK record which contains the DDE link.
+ @param rnExtName Returns the 1-based EXTERNNAME record index. */
+ bool InsertDde(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ bool InsertExtName(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ XclExpXti GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ XclExpRefLogEntry* pRefLogEntry = NULL );
+
+ /** Writes all SUPBOOK records with their sub records. */
+ virtual void Save( XclExpStream& rStrm );
+
+ struct XclExpSBIndex
+ {
+ sal_uInt16 mnSupbook; /// SUPBOOK index for an Excel sheet.
+ sal_uInt16 mnSBTab; /// Sheet name index in SUPBOOK for an Excel sheet.
+ inline void Set( sal_uInt16 nSupbook, sal_uInt16 nSBTab )
+ { mnSupbook = nSupbook; mnSBTab = nSBTab; }
+ };
+ typedef ::std::vector< XclExpSBIndex > XclExpSBIndexVec;
+
+private:
+ typedef XclExpRecordList< XclExpSupbook > XclExpSupbookList;
+ typedef XclExpSupbookList::RecordRefType XclExpSupbookRef;
+
+private:
+ /** Searches for the SUPBOOK record containing the passed document URL.
+ @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
+ @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
+ @return True, if the SUPBOOK record exists (out-parameters are valid). */
+ bool GetSupbookUrl( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
+ const String& rUrl ) const;
+ /** Searches for the SUPBOOK record containing the passed DDE link.
+ @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
+ @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
+ @return True, if the SUPBOOK record exists (out-parameters are valid). */
+ bool GetSupbookDde( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
+ const String& rApplic, const String& rTopic ) const;
+
+ /** Appends a new SUPBOOK to the list.
+ @return The list index of the SUPBOOK record. */
+ sal_uInt16 Append( XclExpSupbookRef xSupbook );
+
+private:
+ XclExpSupbookList maSupbookList; /// List of all SUPBOOK records.
+ XclExpSBIndexVec maSBIndexVec; /// SUPBOOK and sheet name index for each Excel sheet.
+ sal_uInt16 mnOwnDocSB; /// Index to SUPBOOK for own document.
+ sal_uInt16 mnAddInSB; /// Index to add-in SUPBOOK.
+};
+
+// Export link manager ========================================================
+
+/** Abstract base class for implementation classes of the link manager. */
+class XclExpLinkManagerImpl : protected XclExpRoot
+{
+public:
+ /** Derived classes search for an EXTSHEET structure for the given Calc sheet range. */
+ virtual void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry ) = 0;
+ /** Derived classes search for a special EXTERNSHEET index for the own document. */
+ virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) = 0;
+
+ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry ) = 0;
+
+ /** Derived classes store all cells in the given range in a CRN record list. */
+ virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 ) = 0;
+
+ virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ) = 0;
+ virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 ) = 0;
+
+ /** Derived classes find or insert an EXTERNNAME record for an add-in function name. */
+ virtual bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName ) = 0;
+ /** InsertEuroTool */
+ virtual bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName ) = 0;
+
+ /** Derived classes find or insert an EXTERNNAME record for DDE links. */
+ virtual bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem ) = 0;
+
+ virtual bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) = 0;
+
+ /** Derived classes write the entire link table to the passed stream. */
+ virtual void Save( XclExpStream& rStrm ) = 0;
+
+protected:
+ explicit XclExpLinkManagerImpl( const XclExpRoot& rRoot );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the link manager for BIFF5/BIFF7. */
+class XclExpLinkManagerImpl5 : public XclExpLinkManagerImpl
+{
+public:
+ explicit XclExpLinkManagerImpl5( const XclExpRoot& rRoot );
+
+ virtual void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry );
+ virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
+
+ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry );
+
+ virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+ virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+
+ /** InsertEuroTool */
+ virtual bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+
+ virtual bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ virtual bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpExternSheet > XclExpExtSheetList;
+ typedef XclExpExtSheetList::RecordRefType XclExpExtSheetRef;
+ typedef ::std::map< SCTAB, sal_uInt16 > XclExpIntTabMap;
+ typedef ::std::map< sal_Unicode, sal_uInt16 > XclExpCodeMap;
+
+private:
+ /** Returns the number of EXTERNSHEET records. */
+ sal_uInt16 GetExtSheetCount() const;
+
+ /** Appends an internal EXTERNSHEET record and returns the one-based index. */
+ sal_uInt16 AppendInternal( XclExpExtSheetRef xExtSheet );
+ /** Creates all EXTERNSHEET records for internal sheets on first call. */
+ void CreateInternal();
+
+ /** Returns the specified internal EXTERNSHEET record. */
+ XclExpExtSheetRef GetInternal( sal_uInt16 nExtSheet );
+ /** Returns the EXTERNSHEET index of an internal Calc sheet, or a deleted reference. */
+ XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab );
+ /** Finds or creates the EXTERNSHEET index of an internal special EXTERNSHEET. */
+ XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_Unicode cCode );
+
+private:
+ XclExpExtSheetList maExtSheetList; /// List with EXTERNSHEET records.
+ XclExpIntTabMap maIntTabMap; /// Maps internal Calc sheets to EXTERNSHEET records.
+ XclExpCodeMap maCodeMap; /// Maps special external codes to EXTERNSHEET records.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the link manager for BIFF8. */
+class XclExpLinkManagerImpl8 : public XclExpLinkManagerImpl
+{
+public:
+ explicit XclExpLinkManagerImpl8( const XclExpRoot& rRoot );
+
+ virtual void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry );
+ virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
+
+ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry );
+
+ virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+ virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+ /** InsertEuroTool */
+ virtual bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+
+ virtual bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ virtual bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Searches for or inserts a new XTI structure.
+ @return The 0-based list index of the XTI structure. */
+ sal_uInt16 InsertXti( const XclExpXti& rXti );
+
+private:
+ typedef ::std::vector< XclExpXti > XclExpXtiVec;
+
+ XclExpSupbookBuffer maSBBuffer; /// List of all SUPBOOK records.
+ XclExpXtiVec maXtiVec; /// List of XTI structures for the EXTERNSHEET record.
+};
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+// Excel sheet indexes ========================================================
+
+const sal_uInt8 EXC_TABBUF_IGNORE = 0x01; /// Sheet will be ignored completely.
+const sal_uInt8 EXC_TABBUF_EXTERN = 0x02; /// Sheet is linked externally.
+const sal_uInt8 EXC_TABBUF_SKIPMASK = 0x0F; /// Sheet will be skipped, if any flag is set.
+const sal_uInt8 EXC_TABBUF_VISIBLE = 0x10; /// Sheet is visible.
+const sal_uInt8 EXC_TABBUF_SELECTED = 0x20; /// Sheet is selected.
+const sal_uInt8 EXC_TABBUF_MIRRORED = 0x40; /// Sheet is mirrored (right-to-left).
+
+// ----------------------------------------------------------------------------
+
+XclExpTabInfo::XclExpTabInfo( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnScCnt( 0 ),
+ mnXclCnt( 0 ),
+ mnXclExtCnt( 0 ),
+ mnXclSelCnt( 0 ),
+ mnDisplXclTab( 0 ),
+ mnFirstVisXclTab( 0 )
+{
+ ScDocument& rDoc = GetDoc();
+ ScExtDocOptions& rDocOpt = GetExtDocOptions();
+
+ mnScCnt = rDoc.GetTableCount();
+
+ SCTAB nScTab;
+ SCTAB nFirstVisScTab = SCTAB_INVALID; // first visible sheet
+ SCTAB nFirstExpScTab = SCTAB_INVALID; // first exported sheet
+
+ // --- initialize the flags in the index buffer ---
+
+ maTabInfoVec.resize( mnScCnt );
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ // ignored sheets (skipped by export, with invalid Excel sheet index)
+ if( rDoc.IsScenario( nScTab ) )
+ {
+ SetFlag( nScTab, EXC_TABBUF_IGNORE );
+ }
+
+ // external sheets (skipped, but with valid Excel sheet index for ref's)
+ else if( rDoc.GetLinkMode( nScTab ) == SC_LINK_VALUE )
+ {
+ SetFlag( nScTab, EXC_TABBUF_EXTERN );
+ }
+
+ // exported sheets
+ else
+ {
+ // sheet name
+ rDoc.GetName( nScTab, maTabInfoVec[ nScTab ].maScName );
+
+ // remember first exported sheet
+ if( nFirstExpScTab == SCTAB_INVALID )
+ nFirstExpScTab = nScTab;
+ // remember first visible exported sheet
+ if( (nFirstVisScTab == SCTAB_INVALID) && rDoc.IsVisible( nScTab ) )
+ nFirstVisScTab = nScTab;
+
+ // sheet visible (only exported sheets)
+ SetFlag( nScTab, EXC_TABBUF_VISIBLE, rDoc.IsVisible( nScTab ) );
+
+ // sheet selected (only exported sheets)
+ if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nScTab ) )
+ SetFlag( nScTab, EXC_TABBUF_SELECTED, pTabSett->mbSelected );
+
+ // sheet mirrored (only exported sheets)
+ SetFlag( nScTab, EXC_TABBUF_MIRRORED, rDoc.IsLayoutRTL( nScTab ) );
+ }
+ }
+
+ // --- visible/selected sheets ---
+
+ SCTAB nDisplScTab = rDocOpt.GetDocSettings().mnDisplTab;
+
+ // #112908# find first visible exported sheet
+ if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
+ {
+ // no exportable visible sheet -> use first exportable sheet
+ nFirstVisScTab = nFirstExpScTab;
+ if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
+ {
+ // no exportable sheet at all -> use active sheet and export it
+ nFirstVisScTab = nDisplScTab;
+ SetFlag( nFirstVisScTab, EXC_TABBUF_SKIPMASK, false ); // clear skip flags
+ }
+ SetFlag( nFirstVisScTab, EXC_TABBUF_VISIBLE ); // must be visible, even if originally hidden
+ }
+
+ // find currently displayed sheet
+ if( !IsExportTab( nDisplScTab ) ) // selected sheet not exported (i.e. scenario) -> use first visible
+ nDisplScTab = nFirstVisScTab;
+ SetFlag( nDisplScTab, EXC_TABBUF_VISIBLE | EXC_TABBUF_SELECTED );
+
+ // number of selected sheets
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ if( IsSelectedTab( nScTab ) )
+ ++mnXclSelCnt;
+
+ // --- calculate resulting Excel sheet indexes ---
+
+ CalcXclIndexes();
+ mnFirstVisXclTab = GetXclTab( nFirstVisScTab );
+ mnDisplXclTab = GetXclTab( nDisplScTab );
+
+ // --- sorted vectors for index lookup ---
+
+ CalcSortedIndexes();
+}
+
+bool XclExpTabInfo::IsExportTab( SCTAB nScTab ) const
+{
+ /* Check sheet index before to avoid assertion in GetFlag(). */
+ return (nScTab < mnScCnt) && !GetFlag( nScTab, EXC_TABBUF_SKIPMASK );
+}
+
+bool XclExpTabInfo::IsExternalTab( SCTAB nScTab ) const
+{
+ /* Check sheet index before to avoid assertion (called from formula
+ compiler also for deleted references). */
+ return (nScTab < mnScCnt) && GetFlag( nScTab, EXC_TABBUF_EXTERN );
+}
+
+bool XclExpTabInfo::IsVisibleTab( SCTAB nScTab ) const
+{
+ return GetFlag( nScTab, EXC_TABBUF_VISIBLE );
+}
+
+bool XclExpTabInfo::IsSelectedTab( SCTAB nScTab ) const
+{
+ return GetFlag( nScTab, EXC_TABBUF_SELECTED );
+}
+
+bool XclExpTabInfo::IsDisplayedTab( SCTAB nScTab ) const
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
+ return GetXclTab( nScTab ) == mnDisplXclTab;
+}
+
+bool XclExpTabInfo::IsMirroredTab( SCTAB nScTab ) const
+{
+ return GetFlag( nScTab, EXC_TABBUF_MIRRORED );
+}
+
+const String& XclExpTabInfo::GetScTabName( SCTAB nScTab ) const
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
+ return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].maScName : EMPTY_STRING;
+}
+
+sal_uInt16 XclExpTabInfo::GetXclTab( SCTAB nScTab ) const
+{
+ return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].mnXclTab : EXC_TAB_DELETED;
+}
+
+SCTAB XclExpTabInfo::GetRealScTab( SCTAB nSortedScTab ) const
+{
+ DBG_ASSERT( nSortedScTab < mnScCnt, "XclExpTabInfo::GetRealScTab - sheet out of range" );
+ return (nSortedScTab < mnScCnt) ? maFromSortedVec[ nSortedScTab ] : SCTAB_INVALID;
+}
+
+//UNUSED2009-05 SCTAB XclExpTabInfo::GetSortedScTab( SCTAB nScTab ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::GetSortedScTab - sheet out of range" );
+//UNUSED2009-05 return (nScTab < mnScCnt) ? maToSortedVec[ nScTab ] : SCTAB_INVALID;
+//UNUSED2009-05 }
+
+bool XclExpTabInfo::GetFlag( SCTAB nScTab, sal_uInt8 nFlags ) const
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::GetFlag - sheet out of range" );
+ return (nScTab < mnScCnt) && ::get_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags );
+}
+
+void XclExpTabInfo::SetFlag( SCTAB nScTab, sal_uInt8 nFlags, bool bSet )
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::SetFlag - sheet out of range" );
+ if( nScTab < mnScCnt )
+ ::set_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags, bSet );
+}
+
+void XclExpTabInfo::CalcXclIndexes()
+{
+ sal_uInt16 nXclTab = 0;
+ SCTAB nScTab = 0;
+
+ // --- pass 1: process regular sheets ---
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ if( IsExportTab( nScTab ) )
+ {
+ maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
+ ++nXclTab;
+ }
+ else
+ maTabInfoVec[ nScTab ].mnXclTab = EXC_TAB_DELETED;
+ }
+ mnXclCnt = nXclTab;
+
+ // --- pass 2: process external sheets (nXclTab continues) ---
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ if( IsExternalTab( nScTab ) )
+ {
+ maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
+ ++nXclTab;
+ ++mnXclExtCnt;
+ }
+ }
+
+ // result: first occur all exported sheets, followed by all external sheets
+}
+
+typedef ::std::pair< String, SCTAB > XclExpTabName;
+typedef ::std::vector< XclExpTabName > XclExpTabNameVec;
+
+inline bool operator<( const XclExpTabName& rArg1, const XclExpTabName& rArg2 )
+{
+ // compare the sheet names only
+ return ScGlobal::GetCollator()->compareString( rArg1.first, rArg2.first ) == COMPARE_LESS;
+}
+
+void XclExpTabInfo::CalcSortedIndexes()
+{
+ ScDocument& rDoc = GetDoc();
+ XclExpTabNameVec aVec( mnScCnt );
+ SCTAB nScTab;
+
+ // fill with sheet names
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ rDoc.GetName( nScTab, aVec[ nScTab ].first );
+ aVec[ nScTab ].second = nScTab;
+ }
+ ::std::sort( aVec.begin(), aVec.end() );
+
+ // fill index vectors from sorted sheet name vector
+ maFromSortedVec.resize( mnScCnt );
+ maToSortedVec.resize( mnScCnt );
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ maFromSortedVec[ nScTab ] = aVec[ nScTab ].second;
+ maToSortedVec[ aVec[ nScTab ].second ] = nScTab;
+ }
+}
+
+// External names =============================================================
+
+XclExpExtNameBase::XclExpExtNameBase(
+ const XclExpRoot& rRoot, const String& rName, sal_uInt16 nFlags ) :
+ XclExpRecord( EXC_ID_EXTERNNAME ),
+ XclExpRoot( rRoot ),
+ maName( rName ),
+ mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
+ mnFlags( nFlags )
+{
+ DBG_ASSERT( maName.Len() <= 255, "XclExpExtNameBase::XclExpExtNameBase - string too long" );
+ SetRecSize( 6 + mxName->GetSize() );
+}
+
+XclExpExtNameBase::~XclExpExtNameBase()
+{
+}
+
+void XclExpExtNameBase::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnFlags
+ << sal_uInt32( 0 )
+ << *mxName;
+ WriteAddData( rStrm );
+}
+
+void XclExpExtNameBase::WriteAddData( XclExpStream& /*rStrm*/ )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpExtNameAddIn::XclExpExtNameAddIn( const XclExpRoot& rRoot, const String& rName ) :
+ XclExpExtNameBase( rRoot, rName )
+{
+ AddRecSize( 4 );
+}
+
+void XclExpExtNameAddIn::WriteAddData( XclExpStream& rStrm )
+{
+ // write a #REF! error formula
+ rStrm << sal_uInt16( 2 ) << EXC_TOKID_ERR << EXC_ERR_REF;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpExtNameDde::XclExpExtNameDde( const XclExpRoot& rRoot,
+ const String& rName, sal_uInt16 nFlags, const ScMatrix* pResults ) :
+ XclExpExtNameBase( rRoot, rName, nFlags )
+{
+ if( pResults )
+ {
+ mxMatrix.reset( new XclExpCachedMatrix( *pResults ) );
+ AddRecSize( mxMatrix->GetSize() );
+ }
+}
+
+void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
+{
+ if( mxMatrix.is() )
+ mxMatrix->Save( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) :
+ XclExpExtNameBase( rRoot, rName ),
+ mrSupbook(rSupbook),
+ mpArray(pArray->Clone())
+{
+}
+
+void XclExpExtName::WriteAddData( XclExpStream& rStrm )
+{
+ // Write only if it only has a single token that is either a cell or cell
+ // range address. Excel just writes '02 00 1C 17' for all the other types
+ // of external names.
+
+ using namespace ::formula;
+ do
+ {
+ if (mpArray->GetLen() != 1)
+ break;
+
+ const ScToken* p = static_cast<const ScToken*>(mpArray->First());
+ if (p->GetOpCode() != ocExternalRef)
+ break;
+
+ switch (p->GetType())
+ {
+ case svExternalSingleRef:
+ {
+ const ScSingleRefData& rRef = p->GetSingleRef();
+ if (rRef.IsTabRel())
+ break;
+
+ bool bColRel = rRef.IsColRel();
+ bool bRowRel = rRef.IsRowRel();
+ sal_uInt16 nCol = static_cast< sal_uInt16 >( bColRel ? rRef.nRelCol : rRef.nCol );
+ sal_uInt16 nRow = static_cast< sal_uInt16 >( bRowRel ? rRef.nRelRow : rRef.nRow );
+ if (bColRel) nCol |= 0x4000;
+ if (bRowRel) nCol |= 0x8000;
+
+ const String& rTabName = p->GetString();
+ sal_uInt16 nSBTab = mrSupbook.GetTabIndex(rTabName);
+
+ // size is always 9
+ rStrm << static_cast<sal_uInt16>(9);
+ // operator token (3A for cell reference)
+ rStrm << static_cast<sal_uInt8>(0x3A);
+ // cell address (Excel's address has 2 sheet IDs.)
+ rStrm << nSBTab << nSBTab << nRow << nCol;
+ return;
+ }
+ case svExternalDoubleRef:
+ {
+ const ScComplexRefData& rRef = p->GetDoubleRef();
+ const ScSingleRefData& r1 = rRef.Ref1;
+ const ScSingleRefData& r2 = rRef.Ref2;
+ if (r1.IsTabRel() || r2.IsTabRel())
+ break;
+
+ sal_uInt16 nTab1 = r1.nTab;
+ sal_uInt16 nTab2 = r2.nTab;
+ bool bCol1Rel = r1.IsColRel();
+ bool bRow1Rel = r1.IsRowRel();
+ bool bCol2Rel = r2.IsColRel();
+ bool bRow2Rel = r2.IsRowRel();
+
+ sal_uInt16 nCol1 = static_cast< sal_uInt16 >( bCol1Rel ? r1.nRelCol : r1.nCol );
+ sal_uInt16 nCol2 = static_cast< sal_uInt16 >( bCol2Rel ? r2.nRelCol : r2.nCol );
+ sal_uInt16 nRow1 = static_cast< sal_uInt16 >( bRow1Rel ? r1.nRelRow : r1.nRow );
+ sal_uInt16 nRow2 = static_cast< sal_uInt16 >( bRow2Rel ? r2.nRelRow : r2.nRow );
+ if (bCol1Rel) nCol1 |= 0x4000;
+ if (bRow1Rel) nCol1 |= 0x8000;
+ if (bCol2Rel) nCol2 |= 0x4000;
+ if (bRow2Rel) nCol2 |= 0x8000;
+
+ const String& rTabName = p->GetString();
+ sal_uInt16 nSBTab = mrSupbook.GetTabIndex(rTabName);
+
+ // size is always 13 (0x0D)
+ rStrm << static_cast<sal_uInt16>(13);
+ // operator token (3B for area reference)
+ rStrm << static_cast<sal_uInt8>(0x3B);
+ // range (area) address
+ sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1;
+ rStrm << nSBTab << nSBTab2 << nRow1 << nRow2 << nCol1 << nCol2;
+ return;
+ }
+ default:
+ ; // nothing
+ }
+ }
+ while (false);
+
+ // special value for #REF! (02 00 1C 17)
+ rStrm << static_cast<sal_uInt16>(2) << EXC_TOKID_ERR << EXC_ERR_REF;
+}
+
+// List of external names =====================================================
+
+XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertAddIn( const String& rName )
+{
+ sal_uInt16 nIndex = GetIndex( rName );
+ return nIndex ? nIndex : AppendNew( new XclExpExtNameAddIn( GetRoot(), rName ) );
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertEuroTool( const String& rName )
+{
+ sal_uInt16 nIndex = GetIndex( rName );
+ return nIndex ? nIndex : AppendNew( new XclExpExtNameBase( GetRoot(), rName ) );
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertDde(
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ sal_uInt16 nIndex = GetIndex( rItem );
+ if( nIndex == 0 )
+ {
+ USHORT nPos;
+ if( GetDoc().FindDdeLink( rApplic, rTopic, rItem, SC_DDE_IGNOREMODE, nPos ) )
+ {
+ // create the leading 'StdDocumentName' EXTERNNAME record
+ if( maNameList.IsEmpty() )
+ AppendNew( new XclExpExtNameDde(
+ GetRoot(), CREATE_STRING( "StdDocumentName" ), EXC_EXTN_EXPDDE_STDDOC ) );
+
+ // try to find DDE result array, but create EXTERNNAME record without them too
+ const ScMatrix* pScMatrix = GetDoc().GetDdeLinkResultMatrix( nPos );
+ nIndex = AppendNew( new XclExpExtNameDde( GetRoot(), rItem, EXC_EXTN_EXPDDE, pScMatrix ) );
+ }
+ }
+ return nIndex;
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ sal_uInt16 nIndex = GetIndex( rName );
+ return nIndex ? nIndex : AppendNew( new XclExpExtName( GetRoot(), rSupbook, rName, pArray ) );
+}
+
+void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
+{
+ maNameList.Save( rStrm );
+}
+
+sal_uInt16 XclExpExtNameBuffer::GetIndex( const String& rName ) const
+{
+ for( size_t nPos = 0, nSize = maNameList.GetSize(); nPos < nSize; ++nPos )
+ if( maNameList.GetRecord( nPos )->GetName() == rName )
+ return static_cast< sal_uInt16 >( nPos + 1 );
+ return 0;
+}
+
+sal_uInt16 XclExpExtNameBuffer::AppendNew( XclExpExtNameBase* pExtName )
+{
+ XclExpExtNameRef xExtName( pExtName );
+ size_t nSize = maNameList.GetSize();
+ if( nSize < 0x7FFF )
+ {
+ maNameList.AppendRecord( xExtName );
+ return static_cast< sal_uInt16 >( nSize + 1 );
+ }
+ return 0;
+}
+
+// Cached external cells ======================================================
+
+XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ) :
+ XclExpRecord( EXC_ID_CRN, 4 ),
+ mnScCol( nScCol ),
+ mnScRow( nScRow )
+{
+ maValues.push_back( rValue );
+}
+
+bool XclExpCrn::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
+{
+ if( (nScRow != mnScRow) || (nScCol != static_cast< SCCOL >( mnScCol + maValues.size() )) )
+ return false;
+ maValues.push_back( rValue );
+ return true;
+}
+
+void XclExpCrn::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt8 >( mnScCol + maValues.size() - 1 )
+ << static_cast< sal_uInt8 >( mnScCol )
+ << static_cast< sal_uInt16 >( mnScRow );
+ for( CachedValues::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->has< bool >() )
+ WriteBool( rStrm, aIt->get< bool >() );
+ else if( aIt->has< double >() )
+ WriteDouble( rStrm, aIt->get< double >() );
+ else if( aIt->has< OUString >() )
+ WriteString( rStrm, aIt->get< OUString >() );
+ else
+ WriteEmpty( rStrm );
+ }
+}
+
+void XclExpCrn::WriteBool( XclExpStream& rStrm, bool bValue )
+{
+ rStrm << EXC_CACHEDVAL_BOOL << sal_uInt8( bValue ? 1 : 0);
+ rStrm.WriteZeroBytes( 7 );
+}
+
+void XclExpCrn::WriteDouble( XclExpStream& rStrm, double fValue )
+{
+ if( ::rtl::math::isNan( fValue ) )
+ {
+ USHORT nScError = static_cast< USHORT >( reinterpret_cast< const sal_math_Double* >( &fValue )->nan_parts.fraction_lo );
+ WriteError( rStrm, XclTools::GetXclErrorCode( nScError ) );
+ }
+ else
+ {
+ rStrm << EXC_CACHEDVAL_DOUBLE << fValue;
+ }
+}
+
+void XclExpCrn::WriteString( XclExpStream& rStrm, const OUString& rValue )
+{
+ rStrm << EXC_CACHEDVAL_STRING << XclExpString( rValue );
+}
+
+void XclExpCrn::WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode )
+{
+ rStrm << EXC_CACHEDVAL_ERROR << nErrCode;
+ rStrm.WriteZeroBytes( 7 );
+}
+
+void XclExpCrn::WriteEmpty( XclExpStream& rStrm )
+{
+ rStrm << EXC_CACHEDVAL_EMPTY;
+ rStrm.WriteZeroBytes( 8 );
+}
+
+// Cached cells of a sheet ====================================================
+
+XclExpXct::XclExpXct( const XclExpRoot& rRoot, const String& rTabName,
+ sal_uInt16 nSBTab, ScExternalRefCache::TableTypeRef xCacheTable ) :
+ XclExpRoot( rRoot ),
+ mxCacheTable( xCacheTable ),
+ maBoundRange( ScAddress::INITIALIZE_INVALID ),
+ maTabName( rTabName ),
+ mnSBTab( nSBTab )
+{
+}
+
+void XclExpXct::StoreCellRange( const ScRange& rRange )
+{
+ // #i70418# restrict size of external range to prevent memory overflow
+ if( (rRange.aEnd.Col() - rRange.aStart.Col()) * (rRange.aEnd.Row() - rRange.aStart.Row()) > 1024 )
+ return;
+
+ maUsedCells.SetMultiMarkArea( rRange );
+ maBoundRange.ExtendTo( rRange );
+}
+
+void XclExpXct::StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken )
+{
+ maUsedCells.SetMultiMarkArea( ScRange( rCell ) );
+ maBoundRange.ExtendTo( ScRange( rCell ) );
+ (void)rToken;
+}
+
+void XclExpXct::StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken )
+{
+ maUsedCells.SetMultiMarkArea( rRange );
+ maBoundRange.ExtendTo( rRange );
+ (void)rToken;
+}
+
+namespace {
+
+class XclExpCrnList : public XclExpRecordList< XclExpCrn >
+{
+public:
+ /** Inserts the passed value into an existing or new CRN record.
+ @return True = value inserted successfully, false = CRN list is full. */
+ bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
+};
+
+bool XclExpCrnList::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
+{
+ RecordRefType xLastRec = GetLastRecord();
+ if( xLastRec.is() && xLastRec->InsertValue( nScCol, nScRow, rValue ) )
+ return true;
+ if( GetSize() == SAL_MAX_UINT16 )
+ return false;
+ AppendNewRecord( new XclExpCrn( nScCol, nScRow, rValue ) );
+ return true;
+}
+
+} // namespace
+
+void XclExpXct::Save( XclExpStream& rStrm )
+{
+ if( !mxCacheTable )
+ return;
+
+ /* Get the range of used rows in the cache table. This may help to
+ optimize building the CRN record list if the cache table does not
+ contain all referred cells, e.g. if big empty ranges are used in the
+ formulas. */
+ ::std::pair< SCROW, SCROW > aRowRange = mxCacheTable->getRowRange();
+ if( aRowRange.first >= aRowRange.second )
+ return;
+
+ /* Crop the bounding range of used cells in this table to Excel limits.
+ Return if there is no external cell inside these limits. */
+ if( !GetAddressConverter().ValidateRange( maBoundRange, false ) )
+ return;
+
+ /* Find the resulting row range that needs to be processed. */
+ SCROW nScRow1 = ::std::max( aRowRange.first, maBoundRange.aStart.Row() );
+ SCROW nScRow2 = ::std::min( aRowRange.second - 1, maBoundRange.aEnd.Row() );
+ if( nScRow1 > nScRow2 )
+ return;
+
+ /* Build and collect all CRN records before writing the XCT record. This
+ is needed to determine the total number of CRN records which must be
+ known when writing the XCT record (possibly encrypted, so seeking the
+ output strem back after writing the CRN records is not an option). */
+ XclExpCrnList aCrnRecs;
+ SvNumberFormatter& rFormatter = GetFormatter();
+ bool bValid = true;
+ for( SCROW nScRow = nScRow1; bValid && (nScRow <= nScRow2); ++nScRow )
+ {
+ ::std::pair< SCCOL, SCCOL > aColRange = mxCacheTable->getColRange( nScRow );
+ for( SCCOL nScCol = aColRange.first; bValid && (nScCol < aColRange.second); ++nScCol )
+ {
+ if( maUsedCells.IsCellMarked( nScCol, nScRow, TRUE ) )
+ {
+ sal_uInt32 nScNumFmt = 0;
+ ScExternalRefCache::TokenRef xToken = mxCacheTable->getCell( nScCol, nScRow, &nScNumFmt );
+ using namespace ::formula;
+ if( xToken.get() ) switch( xToken->GetType() )
+ {
+ case svDouble:
+ bValid = (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) ?
+ aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() != 0 ) ) :
+ aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() ) );
+ break;
+ case svString:
+ // do not save empty strings (empty cells) to cache
+ if( xToken->GetString().Len() > 0 )
+ bValid = aCrnRecs.InsertValue( nScCol, nScRow, Any( OUString( xToken->GetString() ) ) );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ // write the XCT record and the list of CRN records
+ rStrm.StartRecord( EXC_ID_XCT, 4 );
+ rStrm << static_cast< sal_uInt16 >( aCrnRecs.GetSize() ) << mnSBTab;
+ rStrm.EndRecord();
+ aCrnRecs.Save( rStrm );
+}
+
+// External documents (EXTERNSHEET/SUPBOOK), base class =======================
+
+XclExpExternSheetBase::XclExpExternSheetBase( const XclExpRoot& rRoot, sal_uInt16 nRecId, sal_uInt32 nRecSize ) :
+ XclExpRecord( nRecId, nRecSize ),
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpExtNameBuffer& XclExpExternSheetBase::GetExtNameBuffer()
+{
+ if( !mxExtNameBfr )
+ mxExtNameBfr.reset( new XclExpExtNameBuffer( GetRoot() ) );
+ return *mxExtNameBfr;
+}
+
+void XclExpExternSheetBase::WriteExtNameBuffer( XclExpStream& rStrm )
+{
+ if( mxExtNameBfr.is() )
+ mxExtNameBfr->Save( rStrm );
+}
+
+// External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
+
+XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
+{
+ Init( String( cCode ) );
+}
+
+XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, const String& rTabName ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
+{
+ // reference to own sheet: \03<sheetname>
+ Init( String( EXC_EXTSH_TABNAME ).Append( rTabName ) );
+}
+
+void XclExpExternSheet::Save( XclExpStream& rStrm )
+{
+ // EXTERNSHEET record
+ XclExpRecord::Save( rStrm );
+ // EXTERNNAME records
+ WriteExtNameBuffer( rStrm );
+}
+
+void XclExpExternSheet::Init( const String& rEncUrl )
+{
+ DBG_ASSERT_BIFF( GetBiff() <= EXC_BIFF5 );
+ maTabName.AssignByte( rEncUrl, GetTextEncoding(), EXC_STR_8BITLENGTH );
+ SetRecSize( maTabName.GetSize() );
+}
+
+sal_uInt16 XclExpExternSheet::InsertAddIn( const String& rName )
+{
+ return GetExtNameBuffer().InsertAddIn( rName );
+}
+
+void XclExpExternSheet::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt8 nNameSize = static_cast< sal_uInt8 >( maTabName.Len() );
+ // special case: reference to own sheet (starting with '\03') needs wrong string length
+ if( maTabName.GetChar( 0 ) == EXC_EXTSH_TABNAME )
+ --nNameSize;
+ rStrm << nNameSize;
+ maTabName.WriteBuffer( rStrm );
+}
+
+// External document (SUPBOOK, BIFF8) =========================================
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
+ meType( EXC_SBTYPE_SELF ),
+ mnXclTabCount( nXclTabCount )
+{
+}
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
+ meType( EXC_SBTYPE_ADDIN ),
+ mnXclTabCount( 1 )
+{
+}
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl, XclSupbookType ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
+ maUrl( rUrl ),
+ maUrlEncoded( rUrl ),
+ meType( EXC_SBTYPE_EUROTOOL ),
+ mnXclTabCount( 0 )
+{
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
+}
+
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
+ maUrl( rUrl ),
+ maUrlEncoded( XclExpUrlHelper::EncodeUrl( rRoot, rUrl ) ),
+ meType( EXC_SBTYPE_EXTERN ),
+ mnXclTabCount( 0 )
+{
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
+
+ // We need to create all tables up front to ensure the correct table order.
+ ScExternalRefManager* pRefMgr = rRoot.GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId( rUrl );
+ ScfStringVec aTabNames;
+ pRefMgr->getAllCachedTableNames( nFileId, aTabNames );
+ for( ScfStringVec::const_iterator aBeg = aTabNames.begin(), aIt = aBeg, aEnd = aTabNames.end(); aIt != aEnd; ++aIt )
+ InsertTabName( *aIt, pRefMgr->getCacheTable( nFileId, aIt - aBeg ) );
+}
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
+ maUrl( rApplic ),
+ maDdeTopic( rTopic ),
+ maUrlEncoded( XclExpUrlHelper::EncodeDde( rApplic, rTopic ) ),
+ meType( EXC_SBTYPE_SPECIAL ),
+ mnXclTabCount( 0 )
+{
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
+}
+
+bool XclExpSupbook::IsUrlLink( const String& rUrl ) const
+{
+ return (meType == EXC_SBTYPE_EXTERN || meType == EXC_SBTYPE_EUROTOOL) && (maUrl == rUrl);
+}
+
+bool XclExpSupbook::IsDdeLink( const String& rApplic, const String& rTopic ) const
+{
+ return (meType == EXC_SBTYPE_SPECIAL) && (maUrl == rApplic) && (maDdeTopic == rTopic);
+}
+
+void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
+ sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const
+{
+ rRefLogEntry.mpUrl = maUrlEncoded.IsEmpty() ? 0 : &maUrlEncoded;
+ rRefLogEntry.mpFirstTab = GetTabName( nFirstSBTab );
+ rRefLogEntry.mpLastTab = GetTabName( nLastSBTab );
+}
+
+void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
+{
+ if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
+ pXct->StoreCellRange( rRange );
+}
+
+void XclExpSupbook::StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const formula::FormulaToken& rToken )
+{
+ if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
+ pXct->StoreCell( rCell, rToken );
+}
+
+void XclExpSupbook::StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const formula::FormulaToken& rToken )
+{
+ // multi-table range is not allowed!
+ if( rRange.aStart.Tab() == rRange.aEnd.Tab() )
+ if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
+ pXct->StoreCellRange( rRange, rToken );
+}
+
+sal_uInt16 XclExpSupbook::GetTabIndex( const String& rTabName ) const
+{
+ XclExpString aXclName(rTabName);
+ size_t nSize = maXctList.GetSize();
+ for (size_t i = 0; i < nSize; ++i)
+ {
+ XclExpXctRef aRec = maXctList.GetRecord(i);
+ if (aXclName == aRec->GetTabName())
+ return ulimit_cast<sal_uInt16>(i);
+ }
+ return EXC_NOTAB;
+}
+
+sal_uInt16 XclExpSupbook::GetTabCount() const
+{
+ return ulimit_cast<sal_uInt16>(maXctList.GetSize());
+}
+
+sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable )
+{
+ DBG_ASSERT( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
+ sal_uInt16 nSBTab = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
+ XclExpXctRef xXct( new XclExpXct( GetRoot(), rTabName, nSBTab, xCacheTable ) );
+ AddRecSize( xXct->GetTabName().GetSize() );
+ maXctList.AppendRecord( xXct );
+ return nSBTab;
+}
+
+sal_uInt16 XclExpSupbook::InsertAddIn( const String& rName )
+{
+ return GetExtNameBuffer().InsertAddIn( rName );
+}
+
+sal_uInt16 XclExpSupbook::InsertEuroTool( const String& rName )
+{
+ return GetExtNameBuffer().InsertEuroTool( rName );
+}
+
+sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
+{
+ return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
+}
+
+sal_uInt16 XclExpSupbook::InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ return GetExtNameBuffer().InsertExtName(*this, rName, pArray);
+}
+
+void XclExpSupbook::Save( XclExpStream& rStrm )
+{
+ // SUPBOOK record
+ XclExpRecord::Save( rStrm );
+ // XCT record, CRN records
+ maXctList.Save( rStrm );
+ // EXTERNNAME records
+ WriteExtNameBuffer( rStrm );
+}
+
+const XclExpString* XclExpSupbook::GetTabName( sal_uInt16 nSBTab ) const
+{
+ XclExpXctRef xXct = maXctList.GetRecord( nSBTab );
+ return xXct.is() ? &xXct->GetTabName() : 0;
+}
+
+void XclExpSupbook::WriteBody( XclExpStream& rStrm )
+{
+ switch( meType )
+ {
+ case EXC_SBTYPE_SELF:
+ rStrm << mnXclTabCount << EXC_SUPB_SELF;
+ break;
+ case EXC_SBTYPE_EXTERN:
+ case EXC_SBTYPE_SPECIAL:
+ case EXC_SBTYPE_EUROTOOL:
+ {
+ sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
+ rStrm << nCount << maUrlEncoded;
+
+ for( size_t nPos = 0, nSize = maXctList.GetSize(); nPos < nSize; ++nPos )
+ rStrm << maXctList.GetRecord( nPos )->GetTabName();
+ }
+ break;
+ case EXC_SBTYPE_ADDIN:
+ rStrm << mnXclTabCount << EXC_SUPB_ADDIN;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpSupbook::WriteBody - unknown SUPBOOK type" );
+ }
+}
+
+// All SUPBOOKS in a document =================================================
+
+XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnOwnDocSB( SAL_MAX_UINT16 ),
+ mnAddInSB( SAL_MAX_UINT16 )
+{
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+ sal_uInt16 nXclCnt = rTabInfo.GetXclTabCount();
+ sal_uInt16 nCodeCnt = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
+ size_t nCount = nXclCnt + rTabInfo.GetXclExtTabCount();
+
+ DBG_ASSERT( nCount > 0, "XclExpSupbookBuffer::XclExpSupbookBuffer - no sheets to export" );
+ if( nCount )
+ {
+ maSBIndexVec.resize( nCount );
+
+ // self-ref SUPBOOK first of list
+ XclExpSupbookRef xSupbook( new XclExpSupbook( GetRoot(), ::std::max( nXclCnt, nCodeCnt ) ) );
+ mnOwnDocSB = Append( xSupbook );
+ for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
+ maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
+ }
+}
+
+XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
+ XclExpRefLogEntry* pRefLogEntry ) const
+{
+ XclExpXti aXti;
+ size_t nSize = maSBIndexVec.size();
+ if( (nFirstXclTab < nSize) && (nLastXclTab < nSize) )
+ {
+ // index of the SUPBOOK record
+ aXti.mnSupbook = maSBIndexVec[ nFirstXclTab ].mnSupbook;
+
+ // all sheets in the same supbook?
+ bool bSameSB = true;
+ for( sal_uInt16 nXclTab = nFirstXclTab + 1; bSameSB && (nXclTab <= nLastXclTab); ++nXclTab )
+ {
+ bSameSB = maSBIndexVec[ nXclTab ].mnSupbook == aXti.mnSupbook;
+ if( !bSameSB )
+ nLastXclTab = nXclTab - 1;
+ }
+ aXti.mnFirstSBTab = maSBIndexVec[ nFirstXclTab ].mnSBTab;
+ aXti.mnLastSBTab = maSBIndexVec[ nLastXclTab ].mnSBTab;
+
+ // fill external reference log entry (for change tracking)
+ if( pRefLogEntry )
+ {
+ pRefLogEntry->mnFirstXclTab = nFirstXclTab;
+ pRefLogEntry->mnLastXclTab = nLastXclTab;
+ XclExpSupbookRef xSupbook = maSupbookList.GetRecord( aXti.mnSupbook );
+ if( xSupbook.is() )
+ xSupbook->FillRefLogEntry( *pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab );
+ }
+ }
+ else
+ {
+ // special range, i.e. for deleted sheets or add-ins
+ aXti.mnSupbook = mnOwnDocSB;
+ aXti.mnFirstSBTab = nFirstXclTab;
+ aXti.mnLastSBTab = nLastXclTab;
+ }
+
+ return aXti;
+}
+
+void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
+{
+ sal_uInt16 nXclTab = GetTabInfo().GetXclTab( rRange.aStart.Tab() );
+ if( nXclTab < maSBIndexVec.size() )
+ {
+ const XclExpSBIndex& rSBIndex = maSBIndexVec[ nXclTab ];
+ XclExpSupbookRef xSupbook = maSupbookList.GetRecord( rSBIndex.mnSupbook );
+ DBG_ASSERT( xSupbook.is(), "XclExpSupbookBuffer::StoreCellRange - missing SUPBOOK record" );
+ if( xSupbook.is() )
+ xSupbook->StoreCellRange( rRange, rSBIndex.mnSBTab );
+ }
+}
+
+namespace {
+
+class FindSBIndexEntry
+{
+public:
+ explicit FindSBIndexEntry(sal_uInt16 nSupbookId, sal_uInt16 nTabId) :
+ mnSupbookId(nSupbookId), mnTabId(nTabId) {}
+
+ bool operator()(const XclExpSupbookBuffer::XclExpSBIndex& r) const
+ {
+ return mnSupbookId == r.mnSupbook && mnTabId == r.mnSBTab;
+ }
+
+private:
+ sal_uInt16 mnSupbookId;
+ sal_uInt16 mnTabId;
+};
+
+}
+
+void XclExpSupbookBuffer::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell )
+{
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ return;
+
+ XclExpSupbookRef xSupbook;
+ sal_uInt16 nSupbookId;
+ if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
+ {
+ xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
+ nSupbookId = Append(xSupbook);
+ }
+
+ ScExternalRefCache::TokenRef pToken = pRefMgr->getSingleRefToken(nFileId, rTabName, rCell, NULL, NULL);
+ if (!pToken.get())
+ return;
+
+ sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
+ if (nSheetId == EXC_NOTAB)
+ // specified table name not found in this SUPBOOK.
+ return;
+
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
+ if (itr == itrEnd)
+ {
+ maSBIndexVec.push_back(XclExpSBIndex());
+ XclExpSBIndex& r = maSBIndexVec.back();
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
+
+ xSupbook->StoreCell(nSheetId, rCell, *pToken);
+}
+
+void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange )
+{
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ return;
+
+ XclExpSupbookRef xSupbook;
+ sal_uInt16 nSupbookId;
+ if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
+ {
+ xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
+ nSupbookId = Append(xSupbook);
+ }
+
+ SCTAB nTabCount = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
+
+ // If this is a multi-table range, get token for each table.
+ using namespace ::formula;
+ vector<FormulaToken*> aMatrixList;
+ aMatrixList.reserve(nTabCount);
+
+ // This is a new'ed instance, so we must manage its life cycle here.
+ ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
+ if (!pArray.get())
+ return;
+
+ for (FormulaToken* p = pArray->First(); p; p = pArray->Next())
+ {
+ if (p->GetType() == svMatrix)
+ aMatrixList.push_back(p);
+ else if (p->GetOpCode() != ocSep)
+ {
+ // This is supposed to be ocSep!!!
+ return;
+ }
+ }
+
+ if (aMatrixList.size() != static_cast<size_t>(nTabCount))
+ {
+ // matrix size mis-match !
+ return;
+ }
+
+ sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
+
+ ScRange aRange(rRange);
+ aRange.aStart.SetTab(0);
+ aRange.aEnd.SetTab(0);
+ for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
+ {
+ sal_uInt16 nSheetId = nFirstSheetId + static_cast<sal_uInt16>(nTab);
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
+ if (itr == itrEnd)
+ {
+ maSBIndexVec.push_back(XclExpSBIndex());
+ XclExpSBIndex& r = maSBIndexVec.back();
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
+
+ xSupbook->StoreCellRange(nSheetId, aRange, *aMatrixList[nTab]);
+ }
+}
+
+bool XclExpSupbookBuffer::InsertAddIn(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
+{
+ XclExpSupbookRef xSupbook;
+ if( mnAddInSB == SAL_MAX_UINT16 )
+ {
+ xSupbook.reset( new XclExpSupbook( GetRoot() ) );
+ mnAddInSB = Append( xSupbook );
+ }
+ else
+ xSupbook = maSupbookList.GetRecord( mnAddInSB );
+ DBG_ASSERT( xSupbook.is(), "XclExpSupbookBuffer::InsertAddin - missing add-in supbook" );
+ rnSupbook = mnAddInSB;
+ rnExtName = xSupbook->InsertAddIn( rName );
+ return rnExtName > 0;
+}
+
+bool XclExpSupbookBuffer::InsertEuroTool(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
+{
+ XclExpSupbookRef xSupbook;
+ String aUrl( RTL_CONSTASCII_USTRINGPARAM("\001\010EUROTOOL.XLA"));
+ if( !GetSupbookUrl( xSupbook, rnSupbook, aUrl ) )
+ {
+ xSupbook.reset( new XclExpSupbook( GetRoot(), aUrl, EXC_SBTYPE_EUROTOOL ) );
+ rnSupbook = Append( xSupbook );
+ }
+ rnExtName = xSupbook->InsertEuroTool( rName );
+ return rnExtName > 0;
+}
+
+bool XclExpSupbookBuffer::InsertDde(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ XclExpSupbookRef xSupbook;
+ if( !GetSupbookDde( xSupbook, rnSupbook, rApplic, rTopic ) )
+ {
+ xSupbook.reset( new XclExpSupbook( GetRoot(), rApplic, rTopic ) );
+ rnSupbook = Append( xSupbook );
+ }
+ rnExtName = xSupbook->InsertDde( rItem );
+ return rnExtName > 0;
+}
+
+bool XclExpSupbookBuffer::InsertExtName(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ XclExpSupbookRef xSupbook;
+ if (!GetSupbookUrl(xSupbook, rnSupbook, rUrl))
+ {
+ xSupbook.reset( new XclExpSupbook(GetRoot(), rUrl) );
+ rnSupbook = Append(xSupbook);
+ }
+ rnExtName = xSupbook->InsertExtName(rName, pArray);
+ return rnExtName > 0;
+}
+
+XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ XclExpRefLogEntry* pRefLogEntry )
+{
+ XclExpXti aXti(0, EXC_NOTAB, EXC_NOTAB);
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ return aXti;
+
+ XclExpSupbookRef xSupbook;
+ sal_uInt16 nSupbookId;
+ if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
+ {
+ xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
+ nSupbookId = Append(xSupbook);
+ }
+ aXti.mnSupbook = nSupbookId;
+
+ sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
+ if (nFirstSheetId == EXC_NOTAB)
+ {
+ // first sheet not found in SUPBOOK.
+ return aXti;
+ }
+ sal_uInt16 nSheetCount = xSupbook->GetTabCount();
+ for (sal_uInt16 i = 0; i < nXclTabSpan; ++i)
+ {
+ sal_uInt16 nSheetId = nFirstSheetId + i;
+ if (nSheetId >= nSheetCount)
+ return aXti;
+
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
+ if (itr == itrEnd)
+ {
+ maSBIndexVec.push_back(XclExpSBIndex());
+ XclExpSBIndex& r = maSBIndexVec.back();
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
+ if (i == 0)
+ aXti.mnFirstSBTab = nSheetId;
+ if (i == nXclTabSpan - 1)
+ aXti.mnLastSBTab = nSheetId;
+ }
+
+ if (pRefLogEntry)
+ {
+ pRefLogEntry->mnFirstXclTab = 0;
+ pRefLogEntry->mnLastXclTab = 0;
+ if (xSupbook.is())
+ xSupbook->FillRefLogEntry(*pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab);
+ }
+
+ return aXti;
+}
+
+void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
+{
+ maSupbookList.Save( rStrm );
+}
+
+bool XclExpSupbookBuffer::GetSupbookUrl(
+ XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex, const String& rUrl ) const
+{
+ for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
+ {
+ rxSupbook = maSupbookList.GetRecord( nPos );
+ if( rxSupbook->IsUrlLink( rUrl ) )
+ {
+ rnIndex = ulimit_cast< sal_uInt16 >( nPos );
+ return true;
+ }
+ }
+ return false;
+}
+
+bool XclExpSupbookBuffer::GetSupbookDde( XclExpSupbookRef& rxSupbook,
+ sal_uInt16& rnIndex, const String& rApplic, const String& rTopic ) const
+{
+ for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
+ {
+ rxSupbook = maSupbookList.GetRecord( nPos );
+ if( rxSupbook->IsDdeLink( rApplic, rTopic ) )
+ {
+ rnIndex = ulimit_cast< sal_uInt16 >( nPos );
+ return true;
+ }
+ }
+ return false;
+}
+
+sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
+{
+ maSupbookList.AppendRecord( xSupbook );
+ return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
+}
+
+// Export link manager ========================================================
+
+XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpLinkManagerImpl5::XclExpLinkManagerImpl5( const XclExpRoot& rRoot ) :
+ XclExpLinkManagerImpl( rRoot )
+{
+}
+
+void XclExpLinkManagerImpl5::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ FindInternal( rnExtSheet, rnFirstXclTab, nFirstScTab );
+ if( (rnFirstXclTab == EXC_TAB_DELETED) || (nFirstScTab == nLastScTab) )
+ {
+ rnLastXclTab = rnFirstXclTab;
+ }
+ else
+ {
+ sal_uInt16 nDummyExtSheet;
+ FindInternal( nDummyExtSheet, rnLastXclTab, nLastScTab );
+ }
+
+ (void)pRefLogEntry; // avoid compiler warning
+ DBG_ASSERT( !pRefLogEntry, "XclExpLinkManagerImpl5::FindExtSheet - fill reflog entry not implemented" );
+}
+
+sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
+{
+ sal_uInt16 nExtSheet;
+ FindInternal( nExtSheet, cCode );
+ return nExtSheet;
+}
+
+void XclExpLinkManagerImpl5::FindExtSheet(
+ sal_uInt16 /*nFileId*/, const String& /*rTabName*/, sal_uInt16 /*nXclTabSpan*/,
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
+ XclExpRefLogEntry* /*pRefLogEntry*/ )
+{
+ // not implemented
+}
+
+void XclExpLinkManagerImpl5::StoreCellRange( const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/ )
+{
+ // not implemented
+}
+
+void XclExpLinkManagerImpl5::StoreCell( sal_uInt16 /*nFileId*/, const String& /*rTabName*/, const ScSingleRefData& /*rRef*/ )
+{
+ // not implemented
+}
+
+void XclExpLinkManagerImpl5::StoreCellRange( sal_uInt16 /*nFileId*/, const String& /*rTabName*/, const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/ )
+{
+ // not implemented
+}
+
+bool XclExpLinkManagerImpl5::InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ XclExpExtSheetRef xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_ADDIN );
+ if( xExtSheet.is() )
+ {
+ rnExtName = xExtSheet->InsertAddIn( rName );
+ return rnExtName > 0;
+ }
+ return false;
+}
+
+bool XclExpLinkManagerImpl5::InsertEuroTool(
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rName*/ )
+{
+ return false;
+}
+
+
+bool XclExpLinkManagerImpl5::InsertDde(
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/,
+ const String& /*rApplic*/, const String& /*rTopic*/, const String& /*rItem*/ )
+{
+ // not implemented
+ return false;
+}
+
+bool XclExpLinkManagerImpl5::InsertExtName(
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rUrl*/,
+ const String& /*rName*/, const ScExternalRefCache::TokenArrayRef /*pArray*/ )
+{
+ // not implemented
+ return false;
+}
+
+void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
+{
+ if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
+ {
+ // EXTERNCOUNT record
+ XclExpUInt16Record( EXC_ID_EXTERNCOUNT, nExtSheetCount ).Save( rStrm );
+ // list of EXTERNSHEET records with EXTERNNAME, XCT, CRN records
+ maExtSheetList.Save( rStrm );
+ }
+}
+
+sal_uInt16 XclExpLinkManagerImpl5::GetExtSheetCount() const
+{
+ return static_cast< sal_uInt16 >( maExtSheetList.GetSize() );
+}
+
+sal_uInt16 XclExpLinkManagerImpl5::AppendInternal( XclExpExtSheetRef xExtSheet )
+{
+ if( GetExtSheetCount() < 0x7FFF )
+ {
+ maExtSheetList.AppendRecord( xExtSheet );
+ // return negated one-based EXTERNSHEET index (i.e. 0xFFFD for 3rd record)
+ return static_cast< sal_uInt16 >( -GetExtSheetCount() );
+ }
+ return 0;
+}
+
+void XclExpLinkManagerImpl5::CreateInternal()
+{
+ if( maIntTabMap.empty() )
+ {
+ // create EXTERNSHEET records for all internal exported sheets
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+ for( SCTAB nScTab = 0, nScCnt = rTabInfo.GetScTabCount(); nScTab < nScCnt; ++nScTab )
+ {
+ if( rTabInfo.IsExportTab( nScTab ) )
+ {
+ XclExpExtSheetRef xRec;
+ if( nScTab == GetCurrScTab() )
+ xRec.reset( new XclExpExternSheet( GetRoot(), EXC_EXTSH_OWNTAB ) );
+ else
+ xRec.reset( new XclExpExternSheet( GetRoot(), rTabInfo.GetScTabName( nScTab ) ) );
+ maIntTabMap[ nScTab ] = AppendInternal( xRec );
+ }
+ }
+ }
+}
+
+XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::GetInternal( sal_uInt16 nExtSheet )
+{
+ return maExtSheetList.GetRecord( static_cast< sal_uInt16 >( -nExtSheet - 1 ) );
+}
+
+XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab )
+{
+ // create internal EXTERNSHEET records on demand
+ CreateInternal();
+
+ // try to find an EXTERNSHEET record - if not, return a "deleted sheet" reference
+ XclExpExtSheetRef xExtSheet;
+ XclExpIntTabMap::const_iterator aIt = maIntTabMap.find( nScTab );
+ if( aIt == maIntTabMap.end() )
+ {
+ xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_OWNDOC );
+ rnXclTab = EXC_TAB_DELETED;
+ }
+ else
+ {
+ rnExtSheet = aIt->second;
+ xExtSheet = GetInternal( rnExtSheet );
+ rnXclTab = GetTabInfo().GetXclTab( nScTab );
+ }
+ return xExtSheet;
+}
+
+XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
+ sal_uInt16& rnExtSheet, sal_Unicode cCode )
+{
+ XclExpExtSheetRef xExtSheet;
+ XclExpCodeMap::const_iterator aIt = maCodeMap.find( cCode );
+ if( aIt == maCodeMap.end() )
+ {
+ xExtSheet.reset( new XclExpExternSheet( GetRoot(), cCode ) );
+ rnExtSheet = maCodeMap[ cCode ] = AppendInternal( xExtSheet );
+ }
+ else
+ {
+ rnExtSheet = aIt->second;
+ xExtSheet = GetInternal( rnExtSheet );
+ }
+ return xExtSheet;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpLinkManagerImpl8::XclExpLinkManagerImpl8( const XclExpRoot& rRoot ) :
+ XclExpLinkManagerImpl( rRoot ),
+ maSBBuffer( rRoot )
+{
+}
+
+void XclExpLinkManagerImpl8::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+ rnFirstXclTab = rTabInfo.GetXclTab( nFirstScTab );
+ rnLastXclTab = rTabInfo.GetXclTab( nLastScTab );
+ rnExtSheet = InsertXti( maSBBuffer.GetXti( rnFirstXclTab, rnLastXclTab, pRefLogEntry ) );
+}
+
+sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
+{
+ (void)cCode; // avoid compiler warning
+ DBG_ASSERT( (cCode == EXC_EXTSH_OWNDOC) || (cCode == EXC_EXTSH_ADDIN),
+ "XclExpLinkManagerImpl8::FindExtSheet - unknown externsheet code" );
+ return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+}
+
+void XclExpLinkManagerImpl8::FindExtSheet(
+ sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry )
+{
+ XclExpXti aXti = maSBBuffer.GetXti(nFileId, rTabName, nXclTabSpan, pRefLogEntry);
+ rnExtSheet = InsertXti(aXti);
+ rnFirstSBTab = aXti.mnFirstSBTab;
+ rnLastSBTab = aXti.mnLastSBTab;
+}
+
+void XclExpLinkManagerImpl8::StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 )
+{
+ if( !rRef1.IsDeleted() && !rRef2.IsDeleted() && (rRef1.nTab >= 0) && (rRef2.nTab >= 0) )
+ {
+ const XclExpTabInfo& rTabInfo = GetTabInfo();
+ SCTAB nFirstScTab = static_cast< SCTAB >( rRef1.nTab );
+ SCTAB nLastScTab = static_cast< SCTAB >( rRef2.nTab );
+ ScRange aRange(
+ static_cast< SCCOL >( rRef1.nCol ), static_cast< SCROW >( rRef1.nRow ), 0,
+ static_cast< SCCOL >( rRef2.nCol ), static_cast< SCROW >( rRef2.nRow ), 0 );
+ for( SCTAB nScTab = nFirstScTab; nScTab <= nLastScTab; ++nScTab )
+ {
+ if( rTabInfo.IsExternalTab( nScTab ) )
+ {
+ aRange.aStart.SetTab( nScTab );
+ aRange.aEnd.SetTab( nScTab );
+ maSBBuffer.StoreCellRange( aRange );
+ }
+ }
+ }
+}
+
+void XclExpLinkManagerImpl8::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ ScAddress aAddr(rRef.nCol, rRef.nRow, rRef.nTab);
+ maSBBuffer.StoreCell(nFileId, rTabName, aAddr);
+}
+
+void XclExpLinkManagerImpl8::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 )
+{
+ ScRange aRange(static_cast<SCCOL>(rRef1.nCol), static_cast<SCROW>(rRef1.nRow), static_cast<SCTAB>(rRef1.nTab),
+ static_cast<SCCOL>(rRef2.nCol), static_cast<SCROW>(rRef2.nRow), static_cast<SCTAB>(rRef2.nTab));
+ maSBBuffer.StoreCellRange(nFileId, rTabName, aRange);
+}
+
+bool XclExpLinkManagerImpl8::InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertAddIn( nSupbook, rnExtName, rName ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+bool XclExpLinkManagerImpl8::InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertEuroTool( nSupbook, rnExtName, rName ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+
+bool XclExpLinkManagerImpl8::InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertDde( nSupbook, rnExtName, rApplic, rTopic, rItem ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName, const String& rUrl, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertExtName( nSupbook, rnExtName, rUrl, rName, pArray ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
+{
+ if( !maXtiVec.empty() )
+ {
+ // SUPBOOKs, XCTs, CRNs, EXTERNNAMEs
+ maSBBuffer.Save( rStrm );
+
+ // EXTERNSHEET
+ sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXtiVec.size() );
+ rStrm.StartRecord( EXC_ID_EXTERNSHEET, 2 + 6 * nCount );
+ rStrm << nCount;
+ rStrm.SetSliceSize( 6 );
+ for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
+ aIt->Save( rStrm );
+ rStrm.EndRecord();
+ }
+}
+
+sal_uInt16 XclExpLinkManagerImpl8::InsertXti( const XclExpXti& rXti )
+{
+ for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
+ if( *aIt == rXti )
+ return ulimit_cast< sal_uInt16 >( aIt - maXtiVec.begin() );
+ maXtiVec.push_back( rXti );
+ return ulimit_cast< sal_uInt16 >( maXtiVec.size() - 1 );
+}
+
+// ============================================================================
+
+XclExpLinkManager::XclExpLinkManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5:
+ mxImpl.reset( new XclExpLinkManagerImpl5( rRoot ) );
+ break;
+ case EXC_BIFF8:
+ mxImpl.reset( new XclExpLinkManagerImpl8( rRoot ) );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+XclExpLinkManager::~XclExpLinkManager()
+{
+}
+
+void XclExpLinkManager::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab,
+ SCTAB nScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ mxImpl->FindExtSheet( rnExtSheet, rnXclTab, rnXclTab, nScTab, nScTab, pRefLogEntry );
+}
+
+void XclExpLinkManager::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ mxImpl->FindExtSheet( rnExtSheet, rnFirstXclTab, rnLastXclTab, nFirstScTab, nLastScTab, pRefLogEntry );
+}
+
+sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
+{
+ return mxImpl->FindExtSheet( cCode );
+}
+
+void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry )
+{
+ mxImpl->FindExtSheet( nFileId, rTabName, nXclTabSpan, rnExtSheet, rnFirstSBTab, rnLastSBTab, pRefLogEntry );
+}
+
+void XclExpLinkManager::StoreCell( const ScSingleRefData& rRef )
+{
+ mxImpl->StoreCellRange( rRef, rRef );
+}
+
+void XclExpLinkManager::StoreCellRange( const ScComplexRefData& rRef )
+{
+ mxImpl->StoreCellRange( rRef.Ref1, rRef.Ref2 );
+}
+
+void XclExpLinkManager::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ mxImpl->StoreCell( nFileId, rTabName, rRef );
+}
+
+void XclExpLinkManager::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
+{
+ mxImpl->StoreCellRange( nFileId, rTabName, rRef.Ref1, rRef.Ref2 );
+}
+
+bool XclExpLinkManager::InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ return mxImpl->InsertAddIn( rnExtSheet, rnExtName, rName );
+}
+
+bool XclExpLinkManager::InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ return mxImpl->InsertEuroTool( rnExtSheet, rnExtName, rName );
+}
+
+bool XclExpLinkManager::InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
+}
+
+bool XclExpLinkManager::InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName, const String& rUrl,
+ const ScExternalRefCache::TokenArrayRef pArray )
+{
+ return mxImpl->InsertExtName( rnExtSheet, rnExtName, rUrl, rName, pArray );
+}
+
+void XclExpLinkManager::Save( XclExpStream& rStrm )
+{
+ mxImpl->Save( rStrm );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xename.cxx b/sc/source/filter/excel/xename.cxx
new file mode 100644
index 000000000000..af275bef7eef
--- /dev/null
+++ b/sc/source/filter/excel/xename.cxx
@@ -0,0 +1,791 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xename.hxx"
+
+#include <map>
+
+#include "globstr.hrc"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "xehelper.hxx"
+#include "xelink.hxx"
+
+// for filter manager
+#include "excrecds.hxx"
+
+#include <oox/core/tokens.hxx>
+#include <formula/grammar.hxx>
+
+using ::rtl::OString;
+
+// ============================================================================
+// *** Helper classes ***
+// ============================================================================
+
+/** Represents an internal defined name, supports writing it to a NAME record. */
+class XclExpName : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Creates a standard defined name. */
+ explicit XclExpName( const XclExpRoot& rRoot, const String& rName );
+ /** Creates a built-in defined name. */
+ explicit XclExpName( const XclExpRoot& rRoot, sal_Unicode cBuiltIn );
+
+ /** Sets a token array containing the definition of this name. */
+ void SetTokenArray( XclTokenArrayRef xTokArr );
+ /** Changes this defined name to be local on the specified Calc sheet. */
+ void SetLocalTab( SCTAB nScTab );
+ /** Hides or unhides the defined name. */
+ void SetHidden( bool bHidden = true );
+ /** Changes this name to be the call to a VB macro function or procedure.
+ @param bVBasic true = Visual Basic macro, false = Sheet macro.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ void SetMacroCall( bool bVBasic, bool bFunc );
+
+
+ /** Sets the name's symbol value
+ @param sValue the name's symbolic value */
+ void SetSymbol( String sValue );
+ /** Returns the name's symbol value */
+ inline const String& GetSymbol() const { return msSymbol; }
+
+ /** Returns the original name (title) of this defined name. */
+ inline const String& GetOrigName() const { return maOrigName; }
+ /** Returns the Excel built-in name index of this defined name.
+ @return The built-in name index or EXC_BUILTIN_UNKNOWN for user-defined names. */
+ inline sal_Unicode GetBuiltInName() const { return mcBuiltIn; }
+
+ /** Returns the token array for this defined name. */
+ inline XclTokenArrayRef GetTokenArray() const { return mxTokArr; }
+
+ /** Returns true, if this is a document-global defined name. */
+ inline bool IsGlobal() const { return mnXclTab == EXC_NAME_GLOBAL; }
+ /** Returns the Calc sheet of a local defined name. */
+ inline SCTAB GetScTab() const { return mnScTab; }
+
+ /** Returns true, if this defined name is volatile. */
+ bool IsVolatile() const;
+ /** Returns true, if this defined name is hidden. */
+ bool IsHidden() const;
+ /** Returns true, if this defined name describes a macro call.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ bool IsMacroCall( bool bVBasic, bool bFunc ) const;
+
+ /** Writes the entire NAME record to the passed stream. */
+ virtual void Save( XclExpStream& rStrm );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the NAME record to the passed stream. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ String maOrigName; /// The original user-defined name.
+ String msSymbol; /// The value of the symbol
+ XclExpStringRef mxName; /// The name as Excel string object.
+ XclTokenArrayRef mxTokArr; /// The definition of the defined name.
+ sal_Unicode mcBuiltIn; /// The built-in index for built-in names.
+ SCTAB mnScTab; /// The Calc sheet index for local names.
+ sal_uInt16 mnFlags; /// Additional flags for this defined name.
+ sal_uInt16 mnExtSheet; /// The 1-based index to a global EXTERNSHEET record.
+ sal_uInt16 mnXclTab; /// The 1-based Excel sheet index for local names.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScRangeData;
+class ScDBData;
+
+/** Implementation class of the name manager. */
+class XclExpNameManagerImpl : protected XclExpRoot
+{
+public:
+ explicit XclExpNameManagerImpl( const XclExpRoot& rRoot );
+
+ /** Creates NAME records for built-in and user defined names. */
+ void Initialize();
+
+ /** Inserts the Calc name with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertName( USHORT nScNameIdx );
+ /** Inserts the Calc database range with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertDBRange( USHORT nScDBRangeIdx );
+
+ /** Inserts a new built-in defined name. */
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ /** Inserts a new defined name. Sets another unused name, if rName already exists. */
+ sal_uInt16 InsertUniqueName( const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ /** Returns index of an existing name, or creates a name without definition. */
+ sal_uInt16 InsertRawName( const String& rName );
+ /** Searches or inserts a defined name describing a macro name.
+ @param bVBasic true = Visual Basic macro; false = Sheet macro.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ sal_uInt16 InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden );
+
+ /** Returns the NAME record at the specified position or 0 on error. */
+ const XclExpName* GetName( sal_uInt16 nNameIdx ) const;
+
+ /** Writes the entire list of NAME records.
+ @descr In BIFF7 and lower, writes the entire global link table, which
+ consists of an EXTERNCOUNT record, several EXTERNSHEET records, and
+ the list of NAME records. */
+ void Save( XclExpStream& rStrm );
+
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpName > XclExpNameList;
+ typedef XclExpNameList::RecordRefType XclExpNameRef;
+ typedef ::std::map< USHORT, sal_uInt16 > XclExpIndexMap;
+
+private:
+ /** Finds the index of a NAME record from the passed Calc index in the specified map. */
+ sal_uInt16 FindNameIdx( const XclExpIndexMap& rMap, USHORT nScIdx ) const;
+ /** Returns the index of an existing built-in NAME record with the passed definition, otherwise 0. */
+ sal_uInt16 FindBuiltInNameIdx( const String& rName,
+ const XclTokenArray& rTokArr, bool bDBRange ) const;
+ /** Returns an unused name for the passed name. */
+ String GetUnusedName( const String& rName ) const;
+
+ /** Appends a new NAME record to the record list.
+ @return The 1-based NAME record index used elsewhere in the Excel file. */
+ sal_uInt16 Append( XclExpNameRef xName );
+ /** Creates a new NAME record for the passed user-defined name.
+ @return The 1-based NAME record index used elsewhere in the Excel file. */
+ sal_uInt16 CreateName( const ScRangeData& rRangeData );
+ /** Creates a new NAME record for the passed database range.
+ @return The 1-based NAME record index used elsewhere in the Excel file. */
+ sal_uInt16 CreateName( const ScDBData& rDBData );
+
+ /** Creates NAME records for all built-in names in the document. */
+ void CreateBuiltInNames();
+ /** Creates NAME records for all user-defined names in the document. */
+ void CreateUserNames();
+ /** Creates NAME records for all database ranges in the document. */
+ void CreateDatabaseNames();
+
+private:
+ XclExpNameList maNameList; /// List of NAME records.
+ XclExpIndexMap maNameMap; /// Maps Calc defined names to Excel NAME records.
+ XclExpIndexMap maDBRangeMap; /// Maps Calc database ranges to Excel NAME records.
+ String maUnnamedDBName; /// Name of the hidden unnamed database range.
+ size_t mnFirstUserIdx; /// List index of first user-defined NAME record.
+};
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+XclExpName::XclExpName( const XclExpRoot& rRoot, const String& rName ) :
+ XclExpRecord( EXC_ID_NAME ),
+ XclExpRoot( rRoot ),
+ maOrigName( rName ),
+ mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
+ mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
+ mnScTab( SCTAB_GLOBAL ),
+ mnFlags( EXC_NAME_DEFAULT ),
+ mnExtSheet( EXC_NAME_GLOBAL ),
+ mnXclTab( EXC_NAME_GLOBAL )
+{
+}
+
+XclExpName::XclExpName( const XclExpRoot& rRoot, sal_Unicode cBuiltIn ) :
+ XclExpRecord( EXC_ID_NAME ),
+ XclExpRoot( rRoot ),
+ mcBuiltIn( cBuiltIn ),
+ mnScTab( SCTAB_GLOBAL ),
+ mnFlags( EXC_NAME_DEFAULT ),
+ mnExtSheet( EXC_NAME_GLOBAL ),
+ mnXclTab( EXC_NAME_GLOBAL )
+{
+ // filter source range is hidden in Excel
+ if( cBuiltIn == EXC_BUILTIN_FILTERDATABASE )
+ SetHidden();
+
+ // special case for BIFF5/7 filter source range - name appears as plain text without built-in flag
+ if( (GetBiff() <= EXC_BIFF5) && (cBuiltIn == EXC_BUILTIN_FILTERDATABASE) )
+ {
+ String aName( XclTools::GetXclBuiltInDefName( EXC_BUILTIN_FILTERDATABASE ) );
+ mxName = XclExpStringHelper::CreateString( rRoot, aName, EXC_STR_8BITLENGTH );
+ }
+ else
+ {
+ mxName = XclExpStringHelper::CreateString( rRoot, cBuiltIn, EXC_STR_8BITLENGTH );
+ ::set_flag( mnFlags, EXC_NAME_BUILTIN );
+ }
+}
+
+void XclExpName::SetTokenArray( XclTokenArrayRef xTokArr )
+{
+ mxTokArr = xTokArr;
+}
+
+void XclExpName::SetLocalTab( SCTAB nScTab )
+{
+ DBG_ASSERT( GetTabInfo().IsExportTab( nScTab ), "XclExpName::SetLocalTab - invalid sheet index" );
+ if( GetTabInfo().IsExportTab( nScTab ) )
+ {
+ mnScTab = nScTab;
+ GetGlobalLinkManager().FindExtSheet( mnExtSheet, mnXclTab, nScTab );
+
+ // special handling for NAME record
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5: // EXTERNSHEET index is positive in NAME record
+ mnExtSheet = ~mnExtSheet + 1;
+ break;
+ case EXC_BIFF8: // EXTERNSHEET index not used, but must be created in link table
+ mnExtSheet = 0;
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ // Excel sheet index is 1-based
+ ++mnXclTab;
+ }
+}
+
+void XclExpName::SetHidden( bool bHidden )
+{
+ ::set_flag( mnFlags, EXC_NAME_HIDDEN, bHidden );
+}
+
+void XclExpName::SetMacroCall( bool bVBasic, bool bFunc )
+{
+ ::set_flag( mnFlags, EXC_NAME_PROC );
+ ::set_flag( mnFlags, EXC_NAME_VB, bVBasic );
+ ::set_flag( mnFlags, EXC_NAME_FUNC, bFunc );
+}
+
+void XclExpName::SetSymbol( String sSymbol )
+{
+ msSymbol = sSymbol;
+}
+
+bool XclExpName::IsVolatile() const
+{
+ return mxTokArr.is() && mxTokArr->IsVolatile();
+}
+
+bool XclExpName::IsHidden() const
+{
+ return ::get_flag( mnFlags, EXC_NAME_HIDDEN );
+}
+
+bool XclExpName::IsMacroCall( bool bVBasic, bool bFunc ) const
+{
+ return
+ (::get_flag( mnFlags, EXC_NAME_VB ) == bVBasic) &&
+ (::get_flag( mnFlags, EXC_NAME_FUNC ) == bFunc);
+}
+
+void XclExpName::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mxName.is() && (mxName->Len() > 0), "XclExpName::Save - missing name" );
+ DBG_ASSERT( !(IsGlobal() && ::get_flag( mnFlags, EXC_NAME_BUILTIN )), "XclExpName::Save - global built-in name" );
+ SetRecSize( 11 + mxName->GetSize() + (mxTokArr.is() ? mxTokArr->GetSize() : 2) );
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpName::SaveXml( XclExpXmlStream& rStrm )
+{
+ // For some reason, AutoFilter creates exportable names where maOrigName==""
+ if( maOrigName.Len() == 0 )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_definedName,
+ // OOXTODO: XML_comment, "",
+ // OOXTODO: XML_customMenu, "",
+ // OOXTODO: XML_description, "",
+ XML_function, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_VB ) ),
+ // OOXTODO: XML_functionGroupId, "",
+ // OOXTODO: XML_help, "",
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_HIDDEN ) ),
+ XML_localSheetId, mnScTab == SCTAB_GLOBAL ? NULL : OString::valueOf( (sal_Int32)mnScTab ).getStr(),
+ XML_name, XclXmlUtils::ToOString( maOrigName ).getStr(),
+ // OOXTODO: XML_publishToServer, "",
+ // OOXTODO: XML_shortcutKey, "",
+ // OOXTODO: XML_statusBar, "",
+ XML_vbProcedure, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_VB ) ),
+ // OOXTODO: XML_workbookParameter, "",
+ // OOXTODO: XML_xlm, "",
+ FSEND );
+ rWorkbook->writeEscaped( XclXmlUtils::ToOUString( msSymbol ) );
+ rWorkbook->endElement( XML_definedName );
+}
+
+void XclExpName::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nFmlaSize = mxTokArr.is() ? mxTokArr->GetSize() : 0;
+
+ rStrm << mnFlags // flags
+ << sal_uInt8( 0 ); // keyboard shortcut
+ mxName->WriteLenField( rStrm ); // length of name
+ rStrm << nFmlaSize // size of token array
+ << mnExtSheet // BIFF5/7: EXTSHEET index, BIFF8: not used
+ << mnXclTab // 1-based sheet index for local names
+ << sal_uInt32( 0 ); // length of menu/descr/help/status text
+ mxName->WriteFlagField( rStrm ); // BIFF8 flag field (no-op in <=BIFF7)
+ mxName->WriteBuffer( rStrm ); // character array of the name
+ if( mxTokArr.is() )
+ mxTokArr->WriteArray( rStrm ); // token array without size
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpNameManagerImpl::XclExpNameManagerImpl( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maUnnamedDBName( ScGlobal::GetRscString( STR_DB_NONAME ) ),
+ mnFirstUserIdx( 0 )
+{
+}
+
+void XclExpNameManagerImpl::Initialize()
+{
+ CreateBuiltInNames();
+ mnFirstUserIdx = maNameList.GetSize();
+ CreateUserNames();
+ CreateDatabaseNames();
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertName( USHORT nScNameIdx )
+{
+ sal_uInt16 nNameIdx = FindNameIdx( maNameMap, nScNameIdx );
+ if( nNameIdx == 0 )
+ if( const ScRangeData* pRangeData = GetNamedRanges().FindIndex( nScNameIdx ) )
+ nNameIdx = CreateName( *pRangeData );
+ return nNameIdx;
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertDBRange( USHORT nScDBRangeIdx )
+{
+ sal_uInt16 nNameIdx = FindNameIdx( maDBRangeMap, nScDBRangeIdx );
+ if( nNameIdx == 0 )
+ if( const ScDBData* pDBData = GetDatabaseRanges().FindIndex( nScDBRangeIdx ) )
+ nNameIdx = CreateName( *pDBData );
+ return nNameIdx;
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab )
+{
+ XclExpNameRef xName( new XclExpName( GetRoot(), cBuiltIn ) );
+ xName->SetTokenArray( xTokArr );
+ xName->SetLocalTab( nScTab );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertUniqueName(
+ const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab )
+{
+ DBG_ASSERT( rName.Len(), "XclExpNameManagerImpl::InsertUniqueName - empty name" );
+ XclExpNameRef xName( new XclExpName( GetRoot(), GetUnusedName( rName ) ) );
+ xName->SetTokenArray( xTokArr );
+ xName->SetLocalTab( nScTab );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertRawName( const String& rName )
+{
+ // empty name? may occur in broken external Calc tokens
+ if( !rName.Len() )
+ return 0;
+
+ // try to find an existing NAME record, regardless of its type
+ for( size_t nListIdx = mnFirstUserIdx, nListSize = maNameList.GetSize(); nListIdx < nListSize; ++nListIdx )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nListIdx );
+ if( xName->IsGlobal() && (xName->GetOrigName() == rName) )
+ return static_cast< sal_uInt16 >( nListIdx + 1 );
+ }
+
+ // create a new NAME record
+ XclExpNameRef xName( new XclExpName( GetRoot(), rName ) );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden )
+{
+ // empty name? may occur in broken external Calc tokens
+ if( !rMacroName.Len() )
+ return 0;
+
+ // try to find an existing NAME record
+ for( size_t nListIdx = mnFirstUserIdx, nListSize = maNameList.GetSize(); nListIdx < nListSize; ++nListIdx )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nListIdx );
+ if( xName->IsMacroCall( bVBasic, bFunc ) && (xName->GetOrigName() == rMacroName) )
+ return static_cast< sal_uInt16 >( nListIdx + 1 );
+ }
+
+ // create a new NAME record
+ XclExpNameRef xName( new XclExpName( GetRoot(), rMacroName ) );
+ xName->SetMacroCall( bVBasic, bFunc );
+ xName->SetHidden( bHidden );
+
+ // for sheet macros, add a #NAME! error
+ if( !bVBasic )
+ xName->SetTokenArray( GetFormulaCompiler().CreateErrorFormula( EXC_ERR_NAME ) );
+
+ return Append( xName );
+}
+
+const XclExpName* XclExpNameManagerImpl::GetName( sal_uInt16 nNameIdx ) const
+{
+ DBG_ASSERT( maNameList.HasRecord( nNameIdx - 1 ), "XclExpNameManagerImpl::GetName - wrong record index" );
+ return maNameList.GetRecord( nNameIdx - 1 ).get();
+}
+
+void XclExpNameManagerImpl::Save( XclExpStream& rStrm )
+{
+ maNameList.Save( rStrm );
+}
+
+void XclExpNameManagerImpl::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maNameList.IsEmpty() )
+ return;
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_definedNames, FSEND );
+ maNameList.SaveXml( rStrm );
+ rWorkbook->endElement( XML_definedNames );
+}
+
+// private --------------------------------------------------------------------
+
+sal_uInt16 XclExpNameManagerImpl::FindNameIdx( const XclExpIndexMap& rMap, USHORT nScIdx ) const
+{
+ XclExpIndexMap::const_iterator aIt = rMap.find( nScIdx );
+ return (aIt == rMap.end()) ? 0 : aIt->second;
+}
+
+sal_uInt16 XclExpNameManagerImpl::FindBuiltInNameIdx(
+ const String& rName, const XclTokenArray& rTokArr, bool bDBRange ) const
+{
+ /* Get built-in index from the name. Special case: the database range
+ 'unnamed' will be mapped to Excel's built-in '_FilterDatabase' name. */
+ sal_Unicode cBuiltIn = (bDBRange && (rName == maUnnamedDBName)) ?
+ EXC_BUILTIN_FILTERDATABASE : XclTools::GetBuiltInDefNameIndex( rName );
+
+ if( cBuiltIn < EXC_BUILTIN_UNKNOWN )
+ {
+ // try to find the record in existing built-in NAME record list
+ for( size_t nPos = 0; nPos < mnFirstUserIdx; ++nPos )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nPos );
+ if( xName->GetBuiltInName() == cBuiltIn )
+ {
+ XclTokenArrayRef xTokArr = xName->GetTokenArray();
+ if( xTokArr.is() && (*xTokArr == rTokArr) )
+ return static_cast< sal_uInt16 >( nPos + 1 );
+ }
+ }
+ }
+ return 0;
+}
+
+String XclExpNameManagerImpl::GetUnusedName( const String& rName ) const
+{
+ String aNewName( rName );
+ sal_Int32 nAppIdx = 0;
+ bool bExist = true;
+ while( bExist )
+ {
+ // search the list of user-defined names
+ bExist = false;
+ for( size_t nPos = mnFirstUserIdx, nSize = maNameList.GetSize(); !bExist && (nPos < nSize); ++nPos )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nPos );
+ bExist = xName->GetOrigName() == aNewName;
+ // name exists -> create a new name "<originalname>_<counter>"
+ if( bExist )
+ aNewName.Assign( rName ).Append( '_' ).Append( String::CreateFromInt32( ++nAppIdx ) );
+ }
+ }
+ return aNewName;
+}
+
+sal_uInt16 XclExpNameManagerImpl::Append( XclExpNameRef xName )
+{
+ if( maNameList.GetSize() == 0xFFFF )
+ return 0;
+ maNameList.AppendRecord( xName );
+ return static_cast< sal_uInt16 >( maNameList.GetSize() ); // 1-based
+}
+
+sal_uInt16 XclExpNameManagerImpl::CreateName( const ScRangeData& rRangeData )
+{
+ const String& rName = rRangeData.GetName();
+
+ /* #i38821# recursive names: first insert the (empty) name object,
+ otherwise a recursive call of this function from the formula compiler
+ with the same defined name will not find it and will create it again. */
+ size_t nOldListSize = maNameList.GetSize();
+ XclExpNameRef xName( new XclExpName( GetRoot(), rName ) );
+ sal_uInt16 nNameIdx = Append( xName );
+ // store the index of the NAME record in the lookup map
+ maNameMap[ rRangeData.GetIndex() ] = nNameIdx;
+
+ /* Create the definition formula.
+ This may cause recursive creation of other defined names. */
+ if( const ScTokenArray* pScTokArr = const_cast< ScRangeData& >( rRangeData ).GetCode() )
+ {
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, *pScTokArr );
+ xName->SetTokenArray( xTokArr );
+
+ String sSymbol;
+ rRangeData.GetSymbol( sSymbol, formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
+ xName->SetSymbol( sSymbol );
+
+ /* Try to replace by existing built-in name - complete token array is
+ needed for comparison, and due to the recursion problem above this
+ cannot be done earlier. If a built-in name is found, the created NAME
+ record for this name and all following records in the list must be
+ deleted, otherwise they may contain wrong name list indexes. */
+ sal_uInt16 nBuiltInIdx = FindBuiltInNameIdx( rName, *xTokArr, false );
+ if( nBuiltInIdx != 0 )
+ {
+ // delete the new NAME records
+ while( maNameList.GetSize() > nOldListSize )
+ maNameList.RemoveRecord( maNameList.GetSize() - 1 );
+ // use index of the found built-in NAME record
+ maNameMap[ rRangeData.GetIndex() ] = nNameIdx = nBuiltInIdx;
+ }
+ }
+
+ return nNameIdx;
+}
+
+sal_uInt16 XclExpNameManagerImpl::CreateName( const ScDBData& rDBData )
+{
+ // get name and source range, and create the definition formula
+ const String& rName = rDBData.GetName();
+ ScRange aRange;
+ rDBData.GetArea( aRange );
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, aRange );
+
+ // try to use an existing built-in name
+ sal_uInt16 nNameIdx = FindBuiltInNameIdx( rName, *xTokArr, true );
+ if( nNameIdx == 0 )
+ {
+ // insert a new name into the list
+ XclExpNameRef xName( new XclExpName( GetRoot(), GetUnusedName( rName ) ) );
+ xName->SetTokenArray( xTokArr );
+ nNameIdx = Append( xName );
+ }
+
+ // store the index of the NAME record in the lookup map
+ maDBRangeMap[ rDBData.GetIndex() ] = nNameIdx;
+ return nNameIdx;
+}
+
+void XclExpNameManagerImpl::CreateBuiltInNames()
+{
+ ScDocument& rDoc = GetDoc();
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+
+ /* #i2394# #100489# built-in defined names must be sorted by the name of the
+ containing sheet. Example: SheetA!Print_Range must be stored *before*
+ SheetB!Print_Range, regardless of the position of SheetA in the document! */
+ for( SCTAB nScTabIdx = 0, nScTabCount = rTabInfo.GetScTabCount(); nScTabIdx < nScTabCount; ++nScTabIdx )
+ {
+ // find real sheet index from the nScTabIdx counter
+ SCTAB nScTab = rTabInfo.GetRealScTab( nScTabIdx );
+ // create NAME records for all built-in names of this sheet
+ if( rTabInfo.IsExportTab( nScTab ) )
+ {
+ // *** 1) print ranges *** ----------------------------------------
+
+ if( rDoc.HasPrintRange() )
+ {
+ ScRangeList aRangeList;
+ for( USHORT nIdx = 0, nCount = rDoc.GetPrintRangeCount( nScTab ); nIdx < nCount; ++nIdx )
+ {
+ ScRange aRange( *rDoc.GetPrintRange( nScTab, nIdx ) );
+ // Calc document does not care about sheet index in print ranges
+ aRange.aStart.SetTab( nScTab );
+ aRange.aEnd.SetTab( nScTab );
+ aRange.Justify();
+ aRangeList.Append( aRange );
+ }
+ // create the NAME record (do not warn if ranges are shrunken)
+ GetAddressConverter().ValidateRangeList( aRangeList, false );
+ if( aRangeList.Count() > 0 )
+ GetNameManager().InsertBuiltInName( EXC_BUILTIN_PRINTAREA, aRangeList );
+ }
+
+ // *** 2) print titles *** ----------------------------------------
+
+ ScRangeList aTitleList;
+ // repeated columns
+ if( const ScRange* pColRange = rDoc.GetRepeatColRange( nScTab ) )
+ aTitleList.Append( ScRange(
+ pColRange->aStart.Col(), 0, nScTab,
+ pColRange->aEnd.Col(), GetXclMaxPos().Row(), nScTab ) );
+ // repeated rows
+ if( const ScRange* pRowRange = rDoc.GetRepeatRowRange( nScTab ) )
+ aTitleList.Append( ScRange(
+ 0, pRowRange->aStart.Row(), nScTab,
+ GetXclMaxPos().Col(), pRowRange->aEnd.Row(), nScTab ) );
+ // create the NAME record
+ GetAddressConverter().ValidateRangeList( aTitleList, false );
+ if( aTitleList.Count() > 0 )
+ GetNameManager().InsertBuiltInName( EXC_BUILTIN_PRINTTITLES, aTitleList );
+
+ // *** 3) filter ranges *** ---------------------------------------
+
+ if( GetBiff() == EXC_BIFF8 )
+ GetFilterManager().InitTabFilter( nScTab );
+ }
+ }
+}
+
+void XclExpNameManagerImpl::CreateUserNames()
+{
+ const ScRangeName& rNamedRanges = GetNamedRanges();
+ for( USHORT nNameIdx = 0, nNameCount = rNamedRanges.GetCount(); nNameIdx < nNameCount; ++nNameIdx )
+ {
+ const ScRangeData* pRangeData = rNamedRanges[ nNameIdx ];
+ DBG_ASSERT( rNamedRanges[ nNameIdx ], "XclExpNameManagerImpl::CreateUserNames - missing defined name" );
+ // skip definitions of shared formulas
+ if( pRangeData && !pRangeData->HasType( RT_SHARED ) && !FindNameIdx( maNameMap, pRangeData->GetIndex() ) )
+ CreateName( *pRangeData );
+ }
+}
+
+void XclExpNameManagerImpl::CreateDatabaseNames()
+{
+ const ScDBCollection& rDBRanges = GetDatabaseRanges();
+ for( USHORT nDBIdx = 0, nDBCount = rDBRanges.GetCount(); nDBIdx < nDBCount; ++nDBIdx )
+ {
+ const ScDBData* pDBData = rDBRanges[ nDBIdx ];
+ DBG_ASSERT( pDBData, "XclExpNameManagerImpl::CreateDatabaseNames - missing database range" );
+ // skip hidden "unnamed" range
+ if( pDBData && (pDBData->GetName() != maUnnamedDBName) && !FindNameIdx( maDBRangeMap, pDBData->GetIndex() ) )
+ CreateName( *pDBData );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpNameManager::XclExpNameManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mxImpl( new XclExpNameManagerImpl( rRoot ) )
+{
+}
+
+XclExpNameManager::~XclExpNameManager()
+{
+}
+
+void XclExpNameManager::Initialize()
+{
+ mxImpl->Initialize();
+}
+
+sal_uInt16 XclExpNameManager::InsertName( USHORT nScNameIdx )
+{
+ return mxImpl->InsertName( nScNameIdx );
+}
+
+sal_uInt16 XclExpNameManager::InsertDBRange( USHORT nScDBRangeIdx )
+{
+ return mxImpl->InsertDBRange( nScDBRangeIdx );
+}
+
+//UNUSED2009-05 sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab )
+//UNUSED2009-05 {
+//UNUSED2009-05 return mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, nScTab );
+//UNUSED2009-05 }
+
+sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, const ScRange& rRange )
+{
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, rRange );
+ return mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, rRange.aStart.Tab() );
+}
+
+sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, const ScRangeList& rRangeList )
+{
+ sal_uInt16 nNameIdx = 0;
+ if( rRangeList.Count() )
+ {
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, rRangeList );
+ nNameIdx = mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, rRangeList.GetObject( 0 )->aStart.Tab() );
+ }
+ return nNameIdx;
+}
+
+sal_uInt16 XclExpNameManager::InsertUniqueName(
+ const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab )
+{
+ return mxImpl->InsertUniqueName( rName, xTokArr, nScTab );
+}
+
+sal_uInt16 XclExpNameManager::InsertRawName( const String& rName )
+{
+ return mxImpl->InsertRawName( rName );
+}
+
+sal_uInt16 XclExpNameManager::InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden )
+{
+ return mxImpl->InsertMacroCall( rMacroName, bVBasic, bFunc, bHidden );
+}
+
+const String& XclExpNameManager::GetOrigName( sal_uInt16 nNameIdx ) const
+{
+ const XclExpName* pName = mxImpl->GetName( nNameIdx );
+ return pName ? pName->GetOrigName() : EMPTY_STRING;
+}
+
+SCTAB XclExpNameManager::GetScTab( sal_uInt16 nNameIdx ) const
+{
+ const XclExpName* pName = mxImpl->GetName( nNameIdx );
+ return pName ? pName->GetScTab() : SCTAB_GLOBAL;
+}
+
+bool XclExpNameManager::IsVolatile( sal_uInt16 nNameIdx ) const
+{
+ const XclExpName* pName = mxImpl->GetName( nNameIdx );
+ return pName && pName->IsVolatile();
+}
+
+void XclExpNameManager::Save( XclExpStream& rStrm )
+{
+ mxImpl->Save( rStrm );
+}
+
+void XclExpNameManager::SaveXml( XclExpXmlStream& rStrm )
+{
+ mxImpl->SaveXml( rStrm );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xepage.cxx b/sc/source/filter/excel/xepage.cxx
new file mode 100644
index 000000000000..6194a04c27f6
--- /dev/null
+++ b/sc/source/filter/excel/xepage.cxx
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xepage.hxx"
+#include <svl/itemset.hxx>
+#include "scitems.hxx"
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "attrib.hxx"
+#include "xehelper.hxx"
+#include "xeescher.hxx"
+
+#include <set>
+#include <limits>
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+using ::std::set;
+using ::std::numeric_limits;
+
+// Page settings records ======================================================
+
+// Header/footer --------------------------------------------------------------
+
+XclExpHeaderFooter::XclExpHeaderFooter( sal_uInt16 nRecId, const String& rHdrString ) :
+ XclExpRecord( nRecId ),
+ maHdrString( rHdrString )
+{
+}
+
+void XclExpHeaderFooter::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ sal_Int32 nElement = GetRecId() == EXC_ID_HEADER ? XML_oddHeader : XML_oddFooter;
+ rWorksheet->startElement( nElement, FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( maHdrString ) );
+ rWorksheet->endElement( nElement );
+}
+
+void XclExpHeaderFooter::WriteBody( XclExpStream& rStrm )
+{
+ if( maHdrString.Len() )
+ {
+ XclExpString aExString;
+ if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
+ aExString.AssignByte( maHdrString, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ aExString.Assign( maHdrString, EXC_STR_DEFAULT, 255 ); // 16-bit length, but max 255 chars
+ rStrm << aExString;
+ }
+}
+
+// General page settings ------------------------------------------------------
+
+XclExpSetup::XclExpSetup( const XclPageData& rPageData ) :
+ XclExpRecord( EXC_ID_SETUP, 34 ),
+ mrData( rPageData )
+{
+}
+
+void XclExpSetup::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_pageSetup,
+ XML_paperSize, OString::valueOf( (sal_Int32) mrData.mnPaperSize ).getStr(),
+ XML_scale, OString::valueOf( (sal_Int32) mrData.mnScaling ).getStr(),
+ XML_firstPageNumber, OString::valueOf( (sal_Int32) mrData.mnStartPage ).getStr(),
+ XML_fitToWidth, OString::valueOf( (sal_Int32) mrData.mnFitToWidth ).getStr(),
+ XML_fitToHeight, OString::valueOf( (sal_Int32) mrData.mnFitToHeight ).getStr(),
+ XML_pageOrder, mrData.mbPrintInRows ? "overThenDown" : "downThenOver",
+ XML_orientation, mrData.mbPortrait ? "portrait" : "landscape", // OOXTODO: "default"?
+ XML_usePrinterDefaults, XclXmlUtils::ToPsz( !mrData.mbValid ),
+ XML_blackAndWhite, XclXmlUtils::ToPsz( mrData.mbBlackWhite ),
+ XML_draft, XclXmlUtils::ToPsz( mrData.mbDraftQuality ),
+ XML_cellComments, mrData.mbPrintNotes ? "atEnd" : "none", // OOXTODO: "asDisplayed"?
+ XML_useFirstPageNumber, XclXmlUtils::ToPsz( mrData.mbManualStart ),
+ // OOXTODO: XML_errors, // == displayed|blank|dash|NA
+ XML_horizontalDpi, OString::valueOf( (sal_Int32) mrData.mnHorPrintRes ).getStr(),
+ XML_verticalDpi, OString::valueOf( (sal_Int32) mrData.mnVerPrintRes ).getStr(),
+ XML_copies, OString::valueOf( (sal_Int32) mrData.mnCopies ).getStr(),
+ // OOXTODO: devMode settings part RelationshipId: FSNS( XML_r, XML_id ),
+ FSEND );
+}
+
+void XclExpSetup::WriteBody( XclExpStream& rStrm )
+{
+ XclBiff eBiff = rStrm.GetRoot().GetBiff();
+
+ sal_uInt16 nFlags = 0;
+ ::set_flag( nFlags, EXC_SETUP_INROWS, mrData.mbPrintInRows );
+ ::set_flag( nFlags, EXC_SETUP_PORTRAIT, mrData.mbPortrait );
+ ::set_flag( nFlags, EXC_SETUP_INVALID, !mrData.mbValid );
+ ::set_flag( nFlags, EXC_SETUP_BLACKWHITE, mrData.mbBlackWhite );
+ if( eBiff >= EXC_BIFF5 )
+ {
+ ::set_flag( nFlags, EXC_SETUP_DRAFT, mrData.mbDraftQuality );
+ /* Set the Comments/Notes to "At end of sheet" if Print Notes is true.
+ We don't currently support "as displayed on sheet". Thus this value
+ will be re-interpreted to "At end of sheet". */
+ const sal_uInt16 nNotes = EXC_SETUP_PRINTNOTES | EXC_SETUP_NOTES_END;
+ ::set_flag( nFlags, nNotes, mrData.mbPrintNotes );
+ ::set_flag( nFlags, EXC_SETUP_STARTPAGE, mrData.mbManualStart );
+ }
+
+ rStrm << mrData.mnPaperSize << mrData.mnScaling << mrData.mnStartPage
+ << mrData.mnFitToWidth << mrData.mnFitToHeight << nFlags;
+ if( eBiff >= EXC_BIFF5 )
+ {
+ rStrm << mrData.mnHorPrintRes << mrData.mnVerPrintRes
+ << mrData.mfHeaderMargin << mrData.mfFooterMargin << mrData.mnCopies;
+ }
+}
+
+// Manual page breaks ---------------------------------------------------------
+
+XclExpPageBreaks::XclExpPageBreaks( sal_uInt16 nRecId, const ScfUInt16Vec& rPageBreaks, sal_uInt16 nMaxPos ) :
+ XclExpRecord( nRecId ),
+ mrPageBreaks( rPageBreaks ),
+ mnMaxPos( nMaxPos )
+{
+}
+
+void XclExpPageBreaks::Save( XclExpStream& rStrm )
+{
+ if( !mrPageBreaks.empty() )
+ {
+ SetRecSize( 2 + ((rStrm.GetRoot().GetBiff() <= EXC_BIFF5) ? 2 : 6) * mrPageBreaks.size() );
+ XclExpRecord::Save( rStrm );
+ }
+}
+
+void XclExpPageBreaks::WriteBody( XclExpStream& rStrm )
+{
+ bool bWriteRange = (rStrm.GetRoot().GetBiff() == EXC_BIFF8);
+
+ rStrm << static_cast< sal_uInt16 >( mrPageBreaks.size() );
+ for( ScfUInt16Vec::const_iterator aIt = mrPageBreaks.begin(), aEnd = mrPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ rStrm << *aIt;
+ if( bWriteRange )
+ rStrm << sal_uInt16( 0 ) << mnMaxPos;
+ }
+}
+
+void XclExpPageBreaks::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mrPageBreaks.empty() )
+ return;
+
+ sal_Int32 nElement = GetRecId() == EXC_ID_HORPAGEBREAKS ? XML_rowBreaks : XML_colBreaks;
+ sax_fastparser::FSHelperPtr& pWorksheet = rStrm.GetCurrentStream();
+ OString sNumPageBreaks = OString::valueOf( (sal_Int32) mrPageBreaks.size() );
+ pWorksheet->startElement( nElement,
+ XML_count, sNumPageBreaks.getStr(),
+ XML_manualBreakCount, sNumPageBreaks.getStr(),
+ FSEND );
+ for( ScfUInt16Vec::const_iterator aIt = mrPageBreaks.begin(), aEnd = mrPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ pWorksheet->singleElement( XML_brk,
+ XML_id, OString::valueOf( (sal_Int32) *aIt ).getStr(),
+ XML_man, "true",
+ XML_max, OString::valueOf( (sal_Int32) mnMaxPos ).getStr(),
+ XML_min, "0",
+ // OOXTODO: XML_pt, "",
+ FSEND );
+ }
+ pWorksheet->endElement( nElement );
+}
+
+// Page settings ==============================================================
+
+XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( rDoc.GetPageStyle( nScTab ), SFX_STYLE_FAMILY_PAGE ) )
+ {
+ const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
+ maData.mbValid = true;
+
+ // *** page settings ***
+
+ maData.mbPrintInRows = !GETITEMBOOL( rItemSet, ATTR_PAGE_TOPDOWN );
+ maData.mbHorCenter = GETITEMBOOL( rItemSet, ATTR_PAGE_HORCENTER );
+ maData.mbVerCenter = GETITEMBOOL( rItemSet, ATTR_PAGE_VERCENTER );
+ maData.mbPrintHeadings = GETITEMBOOL( rItemSet, ATTR_PAGE_HEADERS );
+ maData.mbPrintGrid = GETITEMBOOL( rItemSet, ATTR_PAGE_GRID );
+ maData.mbPrintNotes = GETITEMBOOL( rItemSet, ATTR_PAGE_NOTES );
+
+ maData.mnStartPage = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_FIRSTPAGENO, sal_uInt16 );
+ maData.mbManualStart = maData.mnStartPage && (!nScTab || rDoc.NeedPageResetAfterTab( nScTab - 1 ));
+
+ const SvxLRSpaceItem& rLRItem = GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE );
+ maData.mfLeftMargin = XclTools::GetInchFromTwips( rLRItem.GetLeft() );
+ maData.mfRightMargin = XclTools::GetInchFromTwips( rLRItem.GetRight() );
+ const SvxULSpaceItem& rULItem = GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE );
+ maData.mfTopMargin = XclTools::GetInchFromTwips( rULItem.GetUpper() );
+ maData.mfBottomMargin = XclTools::GetInchFromTwips( rULItem.GetLower() );
+
+ const SvxPageItem& rPageItem = GETITEM( rItemSet, SvxPageItem, ATTR_PAGE );
+ const SvxSizeItem& rSizeItem = GETITEM( rItemSet, SvxSizeItem, ATTR_PAGE_SIZE );
+ maData.SetScPaperSize( rSizeItem.GetSize(), !rPageItem.IsLandscape() );
+
+ const ScPageScaleToItem& rScaleToItem = GETITEM( rItemSet, ScPageScaleToItem, ATTR_PAGE_SCALETO );
+ sal_uInt16 nPages = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_SCALETOPAGES, sal_uInt16 );
+ sal_uInt16 nScale = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_SCALE, sal_uInt16 );
+
+ if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETO, false ) && rScaleToItem.IsValid() )
+ {
+ maData.mnFitToWidth = rScaleToItem.GetWidth();
+ maData.mnFitToHeight = rScaleToItem.GetHeight();
+ maData.mbFitToPages = true;
+
+ }
+ else if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETOPAGES, false ) && nPages )
+ {
+ maData.mnFitToWidth = 1;
+ maData.mnFitToHeight = nPages;
+ maData.mbFitToPages = true;
+ }
+ else if( nScale )
+ {
+ maData.mnScaling = nScale;
+ maData.mbFitToPages = false;
+ }
+
+ maData.mxBrushItem.reset( new SvxBrushItem( GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND ) ) );
+
+ // *** header and footer ***
+
+ XclExpHFConverter aHFConv( GetRoot() );
+
+ // header
+ const SfxItemSet& rHdrItemSet = GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ).GetItemSet();
+ if( GETITEMBOOL( rHdrItemSet, ATTR_PAGE_ON ) )
+ {
+ const ScPageHFItem& rHFItem = GETITEM( rItemSet, ScPageHFItem, ATTR_PAGE_HEADERRIGHT );
+ aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
+ maData.maHeader = aHFConv.GetHFString();
+ // header height (Excel excludes header from top margin)
+ sal_Int32 nHdrHeight = GETITEMBOOL( rHdrItemSet, ATTR_PAGE_DYNAMIC ) ?
+ // dynamic height: calculate header height, add header <-> sheet area distance
+ (aHFConv.GetTotalHeight() + GETITEM( rHdrItemSet, SvxULSpaceItem, ATTR_ULSPACE ).GetLower()) :
+ // static height: ATTR_PAGE_SIZE already includes header <-> sheet area distance
+ static_cast< sal_Int32 >( GETITEM( rHdrItemSet, SvxSizeItem, ATTR_PAGE_SIZE ).GetSize().Height() );
+ maData.mfHeaderMargin = maData.mfTopMargin;
+ maData.mfTopMargin += XclTools::GetInchFromTwips( nHdrHeight );
+ }
+
+ // footer
+ const SfxItemSet& rFtrItemSet = GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ).GetItemSet();
+ if( GETITEMBOOL( rFtrItemSet, ATTR_PAGE_ON ) )
+ {
+ const ScPageHFItem& rHFItem = GETITEM( rItemSet, ScPageHFItem, ATTR_PAGE_FOOTERRIGHT );
+ aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
+ maData.maFooter = aHFConv.GetHFString();
+ // footer height (Excel excludes footer from bottom margin)
+ sal_Int32 nFtrHeight = GETITEMBOOL( rFtrItemSet, ATTR_PAGE_DYNAMIC ) ?
+ // dynamic height: calculate footer height, add sheet area <-> footer distance
+ (aHFConv.GetTotalHeight() + GETITEM( rFtrItemSet, SvxULSpaceItem, ATTR_ULSPACE ).GetUpper()) :
+ // static height: ATTR_PAGE_SIZE already includes sheet area <-> footer distance
+ static_cast< sal_Int32 >( GETITEM( rFtrItemSet, SvxSizeItem, ATTR_PAGE_SIZE ).GetSize().Height() );
+ maData.mfFooterMargin = maData.mfBottomMargin;
+ maData.mfBottomMargin += XclTools::GetInchFromTwips( nFtrHeight );
+ }
+ }
+
+ // *** page breaks ***
+
+ set<SCROW> aRowBreaks;
+ rDoc.GetAllRowBreaks(aRowBreaks, nScTab, false, true);
+
+ SCROW nMaxRow = numeric_limits<sal_uInt16>::max();
+ for (set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); itr != itrEnd; ++itr)
+ {
+ SCROW nRow = *itr;
+ if (nRow > nMaxRow)
+ break;
+
+ maData.maHorPageBreaks.push_back(nRow);
+ }
+
+ set<SCCOL> aColBreaks;
+ rDoc.GetAllColBreaks(aColBreaks, nScTab, false, true);
+ for (set<SCCOL>::const_iterator itr = aColBreaks.begin(), itrEnd = aColBreaks.end(); itr != itrEnd; ++itr)
+ maData.maVerPageBreaks.push_back(*itr);
+}
+
+static void lcl_WriteHeaderFooter( XclExpXmlStream& rStrm )
+{
+ // OOXTODO: we currently only emit oddHeader/oddFooter elements, and
+ // do not support the first/even/odd page distinction.
+ rStrm.WriteAttributes(
+ // OOXTODO: XML_alignWithMargins,
+ XML_differentFirst, "false", // OOXTODO
+ XML_differentOddEven, "false", // OOXTODO
+ // OOXTODO: XML_scaleWithDoc
+ FSEND );
+ rStrm.GetCurrentStream()->write( ">" );
+}
+
+void XclExpPageSettings::Save( XclExpStream& rStrm )
+{
+ XclExpBoolRecord( EXC_ID_PRINTHEADERS, maData.mbPrintHeadings ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_PRINTGRIDLINES, maData.mbPrintGrid ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_GRIDSET, true ).Save( rStrm );
+ XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks, static_cast< sal_uInt16 >( GetXclMaxPos().Col() ) ).Save( rStrm );
+ XclExpPageBreaks( EXC_ID_VERPAGEBREAKS, maData.maVerPageBreaks, static_cast< sal_uInt16 >( GetXclMaxPos().Row() ) ).Save( rStrm );
+ XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).Save( rStrm );
+ XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_LEFTMARGIN, maData.mfLeftMargin ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_RIGHTMARGIN, maData.mfRightMargin ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_TOPMARGIN, maData.mfTopMargin ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_BOTTOMMARGIN, maData.mfBottomMargin ).Save( rStrm );
+ XclExpSetup( maData ).Save( rStrm );
+
+ if( (GetBiff() == EXC_BIFF8) && maData.mxBrushItem.get() )
+ if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() )
+ XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ).Save( rStrm );
+}
+
+void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
+{
+ XclExpXmlStartSingleElementRecord( XML_printOptions ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_PRINTHEADERS, maData.mbPrintHeadings, XML_headings ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_PRINTGRIDLINES, maData.mbPrintGrid, XML_gridLines ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_GRIDSET, true, XML_gridLinesSet ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter, XML_horizontalCentered ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter, XML_verticalCentered ).SaveXml( rStrm );
+ XclExpXmlEndSingleElementRecord().SaveXml( rStrm ); // XML_printOptions
+
+ XclExpXmlStartSingleElementRecord( XML_pageMargins ).SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_LEFTMARGIN, maData.mfLeftMargin ).SetAttribute( XML_left )->SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_RIGHTMARGIN, maData.mfRightMargin ).SetAttribute( XML_right )->SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_TOPMARGIN, maData.mfTopMargin ).SetAttribute( XML_top )->SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_BOTTOMMARGIN, maData.mfBottomMargin ).SetAttribute( XML_bottom )->SaveXml( rStrm );
+ XclExpDoubleRecord( 0, maData.mfHeaderMargin).SetAttribute( XML_header )->SaveXml( rStrm );
+ XclExpDoubleRecord( 0, maData.mfFooterMargin).SetAttribute( XML_footer )->SaveXml( rStrm );
+ XclExpXmlEndSingleElementRecord().SaveXml( rStrm ); // XML_pageMargins
+
+ XclExpSetup( maData ).SaveXml( rStrm );
+
+ XclExpXmlStartElementRecord( XML_headerFooter, lcl_WriteHeaderFooter ).SaveXml( rStrm );
+ XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).SaveXml( rStrm );
+ XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).SaveXml( rStrm );
+ XclExpXmlEndElementRecord( XML_headerFooter ).SaveXml( rStrm );
+
+ XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks,
+ static_cast< sal_uInt16 >( GetXclMaxPos().Col() ) ).SaveXml( rStrm );
+ XclExpPageBreaks( EXC_ID_VERPAGEBREAKS, maData.maVerPageBreaks,
+ static_cast< sal_uInt16 >( GetXclMaxPos().Row() ) ).SaveXml( rStrm );
+
+ if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() )
+ XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ).SaveXml( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChartPageSettings::XclExpChartPageSettings( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpChartPageSettings::Save( XclExpStream& rStrm )
+{
+ XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).Save( rStrm );
+ XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter ).Save( rStrm );
+ XclExpSetup( maData ).Save( rStrm );
+ XclExpUInt16Record( EXC_ID_PRINTSIZE, EXC_PRINTSIZE_FULL ).Save( rStrm );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
new file mode 100644
index 000000000000..ddcdb3243167
--- /dev/null
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -0,0 +1,1810 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xepivot.hxx"
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+#include <algorithm>
+#include <math.h>
+
+#include <rtl/math.hxx>
+#include <tools/date.hxx>
+#include <svl/zformat.hxx>
+#include <sot/storage.hxx>
+#include "document.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dpshttab.hxx"
+#include "globstr.hrc"
+#include "fapihelper.hxx"
+#include "xestring.hxx"
+#include "xelink.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_HIDDEN;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_ROW;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_COLUMN;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_PAGE;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
+using ::com::sun::star::sheet::GeneralFunction;
+using ::com::sun::star::sheet::DataPilotFieldSortInfo;
+using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
+using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+namespace {
+
+// constants to track occurence of specific data types
+const sal_uInt16 EXC_PCITEM_DATA_STRING = 0x0001; /// String, empty, boolean, error.
+const sal_uInt16 EXC_PCITEM_DATA_DOUBLE = 0x0002; /// Double with fraction.
+const sal_uInt16 EXC_PCITEM_DATA_INTEGER = 0x0004; /// Integer, double without fraction.
+const sal_uInt16 EXC_PCITEM_DATA_DATE = 0x0008; /// Date, time, date/time.
+
+/** Maps a bitfield consisting of EXC_PCITEM_DATA_* flags above to SXFIELD data type bitfield. */
+static const sal_uInt16 spnPCItemFlags[] =
+{ // STR DBL INT DAT
+ EXC_SXFIELD_DATA_NONE, //
+ EXC_SXFIELD_DATA_STR, // x
+ EXC_SXFIELD_DATA_INT, // x
+ EXC_SXFIELD_DATA_STR_INT, // x x
+ EXC_SXFIELD_DATA_DBL, // x
+ EXC_SXFIELD_DATA_STR_DBL, // x x
+ EXC_SXFIELD_DATA_INT, // x x
+ EXC_SXFIELD_DATA_STR_INT, // x x x
+ EXC_SXFIELD_DATA_DATE, // x
+ EXC_SXFIELD_DATA_DATE_STR, // x x
+ EXC_SXFIELD_DATA_DATE_NUM, // x x
+ EXC_SXFIELD_DATA_DATE_STR, // x x x
+ EXC_SXFIELD_DATA_DATE_NUM, // x x
+ EXC_SXFIELD_DATA_DATE_STR, // x x x
+ EXC_SXFIELD_DATA_DATE_NUM, // x x x
+ EXC_SXFIELD_DATA_DATE_STR // x x x x
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpPCItem::XclExpPCItem( const String& rText ) :
+ XclExpRecord( (rText.Len() > 0) ? EXC_ID_SXSTRING : EXC_ID_SXEMPTY, 0 ),
+ mnTypeFlag( EXC_PCITEM_DATA_STRING )
+{
+ if( rText.Len() )
+ SetText( rText );
+ else
+ SetEmpty();
+}
+
+XclExpPCItem::XclExpPCItem( double fValue ) :
+ XclExpRecord( EXC_ID_SXDOUBLE, 8 )
+{
+ SetDouble( fValue );
+ mnTypeFlag = (fValue - floor( fValue ) == 0.0) ?
+ EXC_PCITEM_DATA_INTEGER : EXC_PCITEM_DATA_DOUBLE;
+}
+
+XclExpPCItem::XclExpPCItem( const DateTime& rDateTime ) :
+ XclExpRecord( EXC_ID_SXDATETIME, 8 )
+{
+ SetDateTime( rDateTime );
+ mnTypeFlag = EXC_PCITEM_DATA_DATE;
+}
+
+XclExpPCItem::XclExpPCItem( sal_Int16 nValue ) :
+ XclExpRecord( EXC_ID_SXINTEGER, 2 ),
+ mnTypeFlag( EXC_PCITEM_DATA_INTEGER )
+{
+ SetInteger( nValue );
+}
+
+XclExpPCItem::XclExpPCItem( bool bValue ) :
+ XclExpRecord( EXC_ID_SXBOOLEAN, 2 ),
+ mnTypeFlag( EXC_PCITEM_DATA_STRING )
+{
+ SetBool( bValue );
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclExpPCItem::EqualsText( const String& rText ) const
+{
+ return (rText.Len() == 0) ? IsEmpty() : (GetText() && (*GetText() == rText));
+}
+
+bool XclExpPCItem::EqualsDouble( double fValue ) const
+{
+ return GetDouble() && (*GetDouble() == fValue);
+}
+
+bool XclExpPCItem::EqualsDateTime( const DateTime& rDateTime ) const
+{
+ return GetDateTime() && (*GetDateTime() == rDateTime);
+}
+
+bool XclExpPCItem::EqualsBool( bool bValue ) const
+{
+ return GetBool() && (*GetBool() == bValue);
+}
+
+// ----------------------------------------------------------------------------
+
+void XclExpPCItem::WriteBody( XclExpStream& rStrm )
+{
+ if( const String* pText = GetText() )
+ {
+ rStrm << XclExpString( *pText );
+ }
+ else if( const double* pfValue = GetDouble() )
+ {
+ rStrm << *pfValue;
+ }
+ else if( const sal_Int16* pnValue = GetInteger() )
+ {
+ rStrm << *pnValue;
+ }
+ else if( const DateTime* pDateTime = GetDateTime() )
+ {
+ sal_uInt16 nYear = static_cast< sal_uInt16 >( pDateTime->GetYear() );
+ sal_uInt16 nMonth = static_cast< sal_uInt16 >( pDateTime->GetMonth() );
+ sal_uInt8 nDay = static_cast< sal_uInt8 >( pDateTime->GetDay() );
+ sal_uInt8 nHour = static_cast< sal_uInt8 >( pDateTime->GetHour() );
+ sal_uInt8 nMin = static_cast< sal_uInt8 >( pDateTime->GetMin() );
+ sal_uInt8 nSec = static_cast< sal_uInt8 >( pDateTime->GetSec() );
+ if( nYear < 1900 ) { nYear = 1900; nMonth = 1; nDay = 0; }
+ rStrm << nYear << nMonth << nDay << nHour << nMin << nSec;
+ }
+ else if( const bool* pbValue = GetBool() )
+ {
+ rStrm << static_cast< sal_uInt16 >( *pbValue ? 1 : 0 );
+ }
+ else
+ {
+ // nothing to do for SXEMPTY
+ DBG_ASSERT( IsEmpty(), "XclExpPCItem::WriteBody - no data found" );
+ }
+}
+
+// ============================================================================
+
+XclExpPCField::XclExpPCField(
+ const XclExpRoot& rRoot, const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScRange& rRange ) :
+ XclExpRecord( EXC_ID_SXFIELD ),
+ XclPCField( EXC_PCFIELD_STANDARD, nFieldIdx ),
+ XclExpRoot( rRoot ),
+ mrPCache( rPCache ),
+ mnTypeFlags( 0 )
+{
+ // general settings for the standard field, insert all items from source range
+ InitStandardField( rRange );
+
+ // add special settings for inplace numeric grouping
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ if( const ScDPDimensionSaveData* pSaveDimData = pSaveData->GetExistingDimensionData() )
+ {
+ if( const ScDPSaveNumGroupDimension* pNumGroupDim = pSaveDimData->GetNumGroupDim( GetFieldName() ) )
+ {
+ const ScDPNumGroupInfo& rNumInfo = pNumGroupDim->GetInfo();
+ const ScDPNumGroupInfo& rDateInfo = pNumGroupDim->GetDateInfo();
+ DBG_ASSERT( !rNumInfo.Enable || !rDateInfo.Enable,
+ "XclExpPCField::XclExpPCField - numeric and date grouping enabled" );
+
+ if( rNumInfo.Enable )
+ InitNumGroupField( rDPObj, rNumInfo );
+ else if( rDateInfo.Enable )
+ InitDateGroupField( rDPObj, rDateInfo, pNumGroupDim->GetDatePart() );
+ }
+ }
+ }
+
+ // final settings (flags, item numbers)
+ Finalize();
+}
+
+XclExpPCField::XclExpPCField(
+ const XclExpRoot& rRoot, const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim, const XclExpPCField& rBaseField ) :
+ XclExpRecord( EXC_ID_SXFIELD ),
+ XclPCField( EXC_PCFIELD_STDGROUP, nFieldIdx ),
+ XclExpRoot( rRoot ),
+ mrPCache( rPCache ),
+ mnTypeFlags( 0 )
+{
+ // add base field info (always using first base field, not predecessor of this field) ***
+ DBG_ASSERT( rBaseField.GetFieldName() == rGroupDim.GetSourceDimName(),
+ "XclExpPCField::FillFromGroup - wrong base cache field" );
+ maFieldInfo.maName = rGroupDim.GetGroupDimName();
+ maFieldInfo.mnGroupBase = rBaseField.GetFieldIndex();
+
+ // add standard group info or date group info
+ const ScDPNumGroupInfo& rDateInfo = rGroupDim.GetDateInfo();
+ if( rDateInfo.Enable && (rGroupDim.GetDatePart() != 0) )
+ InitDateGroupField( rDPObj, rDateInfo, rGroupDim.GetDatePart() );
+ else
+ InitStdGroupField( rBaseField, rGroupDim );
+
+ // final settings (flags, item numbers)
+ Finalize();
+}
+
+XclExpPCField::~XclExpPCField()
+{
+}
+
+void XclExpPCField::SetGroupChildField( const XclExpPCField& rChildField )
+{
+ DBG_ASSERT( !::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD ),
+ "XclExpPCField::SetGroupChildIndex - field already has a grouping child field" );
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
+ maFieldInfo.mnGroupChild = rChildField.GetFieldIndex();
+}
+
+sal_uInt16 XclExpPCField::GetItemCount() const
+{
+ return static_cast< sal_uInt16 >( GetVisItemList().GetSize() );
+}
+
+const XclExpPCItem* XclExpPCField::GetItem( sal_uInt16 nItemIdx ) const
+{
+ return GetVisItemList().GetRecord( nItemIdx ).get();
+}
+
+sal_uInt16 XclExpPCField::GetItemIndex( const String& rItemName ) const
+{
+ const XclExpPCItemList& rItemList = GetVisItemList();
+ for( size_t nPos = 0, nSize = rItemList.GetSize(); nPos < nSize; ++nPos )
+ if( rItemList.GetRecord( nPos )->ConvertToText() == rItemName )
+ return static_cast< sal_uInt16 >( nPos );
+ return EXC_PC_NOITEM;
+}
+
+sal_Size XclExpPCField::GetIndexSize() const
+{
+ return Has16BitIndexes() ? 2 : 1;
+}
+
+void XclExpPCField::WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const
+{
+ // only standard fields write item indexes
+ if( nSrcRow < maIndexVec.size() )
+ {
+ sal_uInt16 nIndex = maIndexVec[ nSrcRow ];
+ if( Has16BitIndexes() )
+ rStrm << nIndex;
+ else
+ rStrm << static_cast< sal_uInt8 >( nIndex );
+ }
+}
+
+void XclExpPCField::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( IsSupportedField(), "XclExpPCField::Save - unknown field type" );
+ // SXFIELD
+ XclExpRecord::Save( rStrm );
+ // SXFDBTYPE
+ XclExpUInt16Record( EXC_ID_SXFDBTYPE, EXC_SXFDBTYPE_DEFAULT ).Save( rStrm );
+ // list of grouping items
+ maGroupItemList.Save( rStrm );
+ // SXGROUPINFO
+ WriteSxgroupinfo( rStrm );
+ // SXNUMGROUP and additional grouping items (grouping limit settings)
+ WriteSxnumgroup( rStrm );
+ // list of original items
+ maOrigItemList.Save( rStrm );
+}
+
+// private --------------------------------------------------------------------
+
+const XclExpPCField::XclExpPCItemList& XclExpPCField::GetVisItemList() const
+{
+ DBG_ASSERT( IsStandardField() == maGroupItemList.IsEmpty(),
+ "XclExpPCField::GetVisItemList - unexpected additional items in standard field" );
+ return IsStandardField() ? maOrigItemList : maGroupItemList;
+}
+
+void XclExpPCField::InitStandardField( const ScRange& rRange )
+{
+ DBG_ASSERT( IsStandardField(), "XclExpPCField::InitStandardField - only for standard fields" );
+ DBG_ASSERT( rRange.aStart.Col() == rRange.aEnd.Col(), "XclExpPCField::InitStandardField - cell range with multiple columns" );
+
+ ScDocument& rDoc = GetDoc();
+ SvNumberFormatter& rFormatter = GetFormatter();
+
+ // field name is in top cell of the range
+ ScAddress aPos( rRange.aStart );
+ rDoc.GetString( aPos.Col(), aPos.Row(), aPos.Tab(), maFieldInfo.maName );
+ // #i76047# maximum field name length in pivot cache is 255
+ maFieldInfo.maName.Erase( ::std::min( maFieldInfo.maName.Len(), EXC_PC_MAXSTRLEN ) );
+
+ // loop over all cells, create pivot cache items
+ for( aPos.IncRow(); (aPos.Row() <= rRange.aEnd.Row()) && (maOrigItemList.GetSize() < EXC_PC_MAXITEMCOUNT); aPos.IncRow() )
+ {
+ if( rDoc.HasValueData( aPos.Col(), aPos.Row(), aPos.Tab() ) )
+ {
+ double fValue = rDoc.GetValue( aPos );
+ short nFmtType = rFormatter.GetType( rDoc.GetNumberFormat( aPos ) );
+ if( nFmtType == NUMBERFORMAT_LOGICAL )
+ InsertOrigBoolItem( fValue != 0 );
+ else if( nFmtType & NUMBERFORMAT_DATETIME )
+ InsertOrigDateTimeItem( GetDateTimeFromDouble( ::std::max( fValue, 0.0 ) ) );
+ else
+ InsertOrigDoubleItem( fValue );
+ }
+ else
+ {
+ String aText;
+ rDoc.GetString( aPos.Col(), aPos.Row(), aPos.Tab(), aText );
+ InsertOrigTextItem( aText );
+ }
+ }
+}
+
+void XclExpPCField::InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim )
+{
+ DBG_ASSERT( IsGroupField(), "XclExpPCField::InitStdGroupField - only for standard grouping fields" );
+
+ maFieldInfo.mnBaseItems = rBaseField.GetItemCount();
+ maGroupOrder.resize( maFieldInfo.mnBaseItems, EXC_PC_NOITEM );
+
+ // loop over all groups of this field
+ for( long nGroupIdx = 0, nGroupCount = rGroupDim.GetGroupCount(); nGroupIdx < nGroupCount; ++nGroupIdx )
+ {
+ if( const ScDPSaveGroupItem* pGroupItem = rGroupDim.GetGroupByIndex( nGroupIdx ) )
+ {
+ // the index of the new item containing the grouping name
+ sal_uInt16 nGroupItemIdx = EXC_PC_NOITEM;
+ // loop over all elements of one group
+ for( size_t nElemIdx = 0, nElemCount = pGroupItem->GetElementCount(); nElemIdx < nElemCount; ++nElemIdx )
+ {
+ if( const String* pElemName = pGroupItem->GetElementByIndex( nElemIdx ) )
+ {
+ // try to find the item that is part of the group in the base field
+ sal_uInt16 nBaseItemIdx = rBaseField.GetItemIndex( *pElemName );
+ if( nBaseItemIdx < maFieldInfo.mnBaseItems )
+ {
+ // add group name item only if there are any valid base items
+ if( nGroupItemIdx == EXC_PC_NOITEM )
+ nGroupItemIdx = InsertGroupItem( new XclExpPCItem( pGroupItem->GetGroupName() ) );
+ maGroupOrder[ nBaseItemIdx ] = nGroupItemIdx;
+ }
+ }
+ }
+ }
+ }
+
+ // add items and base item indexes of all ungrouped elements
+ for( sal_uInt16 nBaseItemIdx = 0; nBaseItemIdx < maFieldInfo.mnBaseItems; ++nBaseItemIdx )
+ // items that are not part of a group still have the EXC_PC_NOITEM entry
+ if( maGroupOrder[ nBaseItemIdx ] == EXC_PC_NOITEM )
+ // try to find the base item
+ if( const XclExpPCItem* pBaseItem = rBaseField.GetItem( nBaseItemIdx ) )
+ // create a clone of the base item, insert its index into item order list
+ maGroupOrder[ nBaseItemIdx ] = InsertGroupItem( new XclExpPCItem( *pBaseItem ) );
+}
+
+void XclExpPCField::InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo )
+{
+ DBG_ASSERT( IsStandardField(), "XclExpPCField::InitNumGroupField - only for standard fields" );
+ DBG_ASSERT( rNumInfo.Enable, "XclExpPCField::InitNumGroupField - numeric grouping not enabled" );
+
+ // new field type, date type, limit settings (min/max/step/auto)
+ if( rNumInfo.DateValues )
+ {
+ // special case: group by days with step count
+ meFieldType = EXC_PCFIELD_DATEGROUP;
+ maNumGroupInfo.SetScDateType( com::sun::star::sheet::DataPilotFieldGroupBy::DAYS );
+ SetDateGroupLimit( rNumInfo, true );
+ }
+ else
+ {
+ meFieldType = EXC_PCFIELD_NUMGROUP;
+ maNumGroupInfo.SetNumType();
+ SetNumGroupLimit( rNumInfo );
+ }
+
+ // generate visible items
+ InsertNumDateGroupItems( rDPObj, rNumInfo );
+}
+
+void XclExpPCField::InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart )
+{
+ DBG_ASSERT( IsStandardField() || IsStdGroupField(), "XclExpPCField::InitDateGroupField - only for standard fields" );
+ DBG_ASSERT( rDateInfo.Enable, "XclExpPCField::InitDateGroupField - date grouping not enabled" );
+
+ // new field type
+ meFieldType = IsStandardField() ? EXC_PCFIELD_DATEGROUP : EXC_PCFIELD_DATECHILD;
+
+ // date type, limit settings (min/max/step/auto)
+ maNumGroupInfo.SetScDateType( nDatePart );
+ SetDateGroupLimit( rDateInfo, false );
+
+ // generate visible items
+ InsertNumDateGroupItems( rDPObj, rDateInfo, nDatePart );
+}
+
+void XclExpPCField::InsertItemArrayIndex( size_t nListPos )
+{
+ DBG_ASSERT( IsStandardField(), "XclExpPCField::InsertItemArrayIndex - only for standard fields" );
+ maIndexVec.push_back( static_cast< sal_uInt16 >( nListPos ) );
+}
+
+void XclExpPCField::InsertOrigItem( XclExpPCItem* pNewItem )
+{
+ size_t nItemIdx = maOrigItemList.GetSize();
+ maOrigItemList.AppendNewRecord( pNewItem );
+ InsertItemArrayIndex( nItemIdx );
+ mnTypeFlags |= pNewItem->GetTypeFlag();
+}
+
+void XclExpPCField::InsertOrigTextItem( const String& rText )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ // #i76047# maximum item text length in pivot cache is 255
+ String aShortText( rText, 0, ::std::min( rText.Len(), EXC_PC_MAXSTRLEN ) );
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsText( aShortText )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( aShortText ) );
+}
+
+void XclExpPCField::InsertOrigDoubleItem( double fValue )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsDouble( fValue )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( fValue ) );
+}
+
+void XclExpPCField::InsertOrigDateTimeItem( const DateTime& rDateTime )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsDateTime( rDateTime )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( rDateTime ) );
+}
+
+void XclExpPCField::InsertOrigBoolItem( bool bValue )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsBool( bValue )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( bValue ) );
+}
+
+sal_uInt16 XclExpPCField::InsertGroupItem( XclExpPCItem* pNewItem )
+{
+ maGroupItemList.AppendNewRecord( pNewItem );
+ return static_cast< sal_uInt16 >( maGroupItemList.GetSize() - 1 );
+}
+
+void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart )
+{
+ DBG_ASSERT( rDPObj.GetSheetDesc(), "XclExpPCField::InsertNumDateGroupItems - cannot generate element list" );
+ if( const ScSheetSourceDesc* pSrcDesc = rDPObj.GetSheetDesc() )
+ {
+ // get the string collection with original source elements
+ ScSheetDPData aDPData( GetDocPtr(), *pSrcDesc );
+ // Wang Xu Ming - DataPilot migration
+ // 2009-05-08
+ const std::vector< SCROW > aOrignial = aDPData.GetColumnEntries( static_cast< long >( GetBaseFieldIndex() ) );
+ // get the string collection with generated grouping elements
+ ScDPNumGroupDimension aTmpDim( rNumInfo );
+ if( nDatePart != 0 )
+ aTmpDim.MakeDateHelper( rNumInfo, nDatePart );
+ const std::vector< SCROW > aMemberIds = aTmpDim.GetNumEntries( static_cast< SCCOL >( GetBaseFieldIndex() ), aDPData.GetCacheTable().GetCache(), aOrignial );
+ for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ )
+ {
+ const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] );
+ if ( pData )
+ InsertGroupItem( new XclExpPCItem( pData->GetString() ) );
+ }
+// End Comments
+ }
+}
+
+void XclExpPCField::SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo )
+{
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN, rNumInfo.AutoStart );
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX, rNumInfo.AutoEnd );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( rNumInfo.Start ) );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( rNumInfo.End ) );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( rNumInfo.Step ) );
+}
+
+void XclExpPCField::SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep )
+{
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN, rDateInfo.AutoStart );
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX, rDateInfo.AutoEnd );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( GetDateTimeFromDouble( rDateInfo.Start ) ) );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( GetDateTimeFromDouble( rDateInfo.End ) ) );
+ sal_Int16 nStep = bUseStep ? limit_cast< sal_Int16 >( rDateInfo.Step, 1, SAL_MAX_INT16 ) : 1;
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( nStep ) );
+}
+
+void XclExpPCField::Finalize()
+{
+ // flags
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASITEMS, !GetVisItemList().IsEmpty() );
+ // Excel writes long indexes even for 0x0100 items (indexes from 0x00 to 0xFF)
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT, maOrigItemList.GetSize() >= 0x0100 );
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_NUMGROUP, IsNumGroupField() || IsDateGroupField() );
+ /* mnTypeFlags is updated in all Insert***Item() functions. Now the flags
+ for the current combination of item types is added to the flags. */
+ ::set_flag( maFieldInfo.mnFlags, spnPCItemFlags[ mnTypeFlags ] );
+
+ // item count fields
+ maFieldInfo.mnVisItems = static_cast< sal_uInt16 >( GetVisItemList().GetSize() );
+ maFieldInfo.mnGroupItems = static_cast< sal_uInt16 >( maGroupItemList.GetSize() );
+ // maFieldInfo.mnBaseItems set in InitStdGroupField()
+ maFieldInfo.mnOrigItems = static_cast< sal_uInt16 >( maOrigItemList.GetSize() );
+}
+
+void XclExpPCField::WriteSxnumgroup( XclExpStream& rStrm )
+{
+ if( IsNumGroupField() || IsDateGroupField() )
+ {
+ // SXNUMGROUP record
+ rStrm.StartRecord( EXC_ID_SXNUMGROUP, 2 );
+ rStrm << maNumGroupInfo;
+ rStrm.EndRecord();
+
+ // limits (min/max/step) for numeric grouping
+ DBG_ASSERT( maNumGroupLimits.GetSize() == 3,
+ "XclExpPCField::WriteSxnumgroup - missing numeric grouping limits" );
+ maNumGroupLimits.Save( rStrm );
+ }
+}
+
+void XclExpPCField::WriteSxgroupinfo( XclExpStream& rStrm )
+{
+ DBG_ASSERT( IsStdGroupField() != maGroupOrder.empty(),
+ "XclExpPCField::WriteSxgroupinfo - missing grouping info" );
+ if( IsStdGroupField() && !maGroupOrder.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_SXGROUPINFO, 2 * maGroupOrder.size() );
+ for( ScfUInt16Vec::const_iterator aIt = maGroupOrder.begin(), aEnd = maGroupOrder.end(); aIt != aEnd; ++aIt )
+ rStrm << *aIt;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPCField::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maFieldInfo;
+}
+
+// ============================================================================
+
+XclExpPivotCache::XclExpPivotCache( const XclExpRoot& rRoot, const ScDPObject& rDPObj, sal_uInt16 nListIdx ) :
+ XclExpRoot( rRoot ),
+ mnListIdx( nListIdx ),
+ mbValid( false )
+{
+ // source from sheet only
+ if( const ScSheetSourceDesc* pSrcDesc = rDPObj.GetSheetDesc() )
+ {
+ /* maOrigSrcRange: Range received from the DataPilot object.
+ maExpSrcRange: Range written to the DCONREF record.
+ maDocSrcRange: Range used to get source data from Calc document.
+ This range may be shorter than maExpSrcRange to improve export
+ performance (#i22541#). */
+ maOrigSrcRange = maExpSrcRange = maDocSrcRange = pSrcDesc->aSourceRange;
+
+ // internal sheet data only
+ SCTAB nScTab = maExpSrcRange.aStart.Tab();
+ if( (nScTab == maExpSrcRange.aEnd.Tab()) && GetTabInfo().IsExportTab( nScTab ) )
+ {
+ // ValidateRange() restricts source range to valid Excel limits
+ if( GetAddressConverter().ValidateRange( maExpSrcRange, true ) )
+ {
+ // #i22541# skip empty cell areas (performance)
+ SCCOL nDocCol1, nDocCol2;
+ SCROW nDocRow1, nDocRow2;
+ GetDoc().GetDataStart( nScTab, nDocCol1, nDocRow1 );
+ GetDoc().GetPrintArea( nScTab, nDocCol2, nDocRow2, false );
+ SCCOL nSrcCol1 = maExpSrcRange.aStart.Col();
+ SCROW nSrcRow1 = maExpSrcRange.aStart.Row();
+ SCCOL nSrcCol2 = maExpSrcRange.aEnd.Col();
+ SCROW nSrcRow2 = maExpSrcRange.aEnd.Row();
+
+ // #i22541# do not store index list for too big ranges
+ if( 2 * (nDocRow2 - nDocRow1) < (nSrcRow2 - nSrcRow1) )
+ ::set_flag( maPCInfo.mnFlags, EXC_SXDB_SAVEDATA, false );
+
+ // #160184# Excel must refresh tables to make drilldown working
+ ::set_flag( maPCInfo.mnFlags, EXC_SXDB_REFRESH_LOAD );
+
+ // adjust row indexes, keep one row of empty area to surely have the empty cache item
+ if( nSrcRow1 < nDocRow1 )
+ nSrcRow1 = nDocRow1 - 1;
+ if( nSrcRow2 > nDocRow2 )
+ nSrcRow2 = nDocRow2 + 1;
+
+ maDocSrcRange.aStart.SetCol( ::std::max( nDocCol1, nSrcCol1 ) );
+ maDocSrcRange.aStart.SetRow( nSrcRow1 );
+ maDocSrcRange.aEnd.SetCol( ::std::min( nDocCol2, nSrcCol2 ) );
+ maDocSrcRange.aEnd.SetRow( nSrcRow2 );
+
+ GetDoc().GetName( nScTab, maTabName );
+ maPCInfo.mnSrcRecs = static_cast< sal_uInt32 >( maExpSrcRange.aEnd.Row() - maExpSrcRange.aStart.Row() );
+ maPCInfo.mnStrmId = nListIdx + 1;
+ maPCInfo.mnSrcType = EXC_SXDB_SRC_SHEET;
+
+ AddFields( rDPObj );
+
+ mbValid = true;
+ }
+ }
+ }
+}
+
+bool XclExpPivotCache::HasItemIndexList() const
+{
+ return ::get_flag( maPCInfo.mnFlags, EXC_SXDB_SAVEDATA );
+}
+
+sal_uInt16 XclExpPivotCache::GetFieldCount() const
+{
+ return static_cast< sal_uInt16 >( maFieldList.GetSize() );
+}
+
+const XclExpPCField* XclExpPivotCache::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return maFieldList.GetRecord( nFieldIdx ).get();
+}
+
+//UNUSED2009-05 const XclExpPCField* XclExpPivotCache::GetField( const String& rFieldName ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 return const_cast< XclExpPivotCache* >( this )->GetFieldAcc( rFieldName );
+//UNUSED2009-05 }
+
+bool XclExpPivotCache::HasAddFields() const
+{
+ // pivot cache can be shared, if there are no additional cache fields
+ return maPCInfo.mnStdFields < maPCInfo.mnTotalFields;
+}
+
+bool XclExpPivotCache::HasEqualDataSource( const ScDPObject& rDPObj ) const
+{
+ /* For now, only sheet sources are supported, therefore it is enough to
+ compare the ScSheetSourceDesc. Later, there should be done more complicated
+ comparisons regarding the source type of rDPObj and this cache. */
+ if( const ScSheetSourceDesc* pSrcDesc = rDPObj.GetSheetDesc() )
+ return pSrcDesc->aSourceRange == maOrigSrcRange;
+ return false;
+}
+
+void XclExpPivotCache::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mbValid, "XclExpPivotCache::Save - invalid pivot cache" );
+ // SXIDSTM
+ XclExpUInt16Record( EXC_ID_SXIDSTM, maPCInfo.mnStrmId ).Save( rStrm );
+ // SXVS
+ XclExpUInt16Record( EXC_ID_SXVS, EXC_SXVS_SHEET ).Save( rStrm );
+ // DCONREF
+ WriteDconref( rStrm );
+ // create the pivot cache storage stream
+ WriteCacheStream();
+}
+
+void XclExpPivotCache::SaveXml( XclExpXmlStream& rStrm )
+{
+ DBG_ASSERT( mbValid, "XclExpPivotCache::Save - invalid pivot cache" );
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ OUString sId = OUStringBuffer()
+ .appendAscii("rId")
+ .append( rStrm.GetUniqueIdOUString() )
+ .makeStringAndClear();
+ rWorkbook->startElement( XML_pivotCache,
+ XML_cacheId, OString::valueOf( (sal_Int32)maPCInfo.mnStrmId ).getStr(),
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+ // SXIDSTM
+ XclExpUInt16Record( EXC_ID_SXIDSTM, maPCInfo.mnStrmId ).SaveXml( rStrm );
+ // SXVS
+ XclExpUInt16Record( EXC_ID_SXVS, EXC_SXVS_SHEET ).SaveXml( rStrm );
+ // DCONREF
+ // OOXTODO: WriteDconref( rStrm );
+ // create the pivot cache storage stream
+ // OOXTODO: WriteCacheStream();
+ rWorkbook->endElement( XML_pivotCache );
+}
+
+// private --------------------------------------------------------------------
+
+XclExpPCField* XclExpPivotCache::GetFieldAcc( sal_uInt16 nFieldIdx )
+{
+ return maFieldList.GetRecord( nFieldIdx ).get();
+}
+
+XclExpPCField* XclExpPivotCache::GetFieldAcc( const String& rFieldName )
+{
+ XclExpPCField* pField = 0;
+ for( size_t nPos = 0, nSize = maFieldList.GetSize(); !pField && (nPos < nSize); ++nPos )
+ if( maFieldList.GetRecord( nPos )->GetFieldName() == rFieldName )
+ pField = maFieldList.GetRecord( nPos ).get();
+ return pField;
+}
+
+void XclExpPivotCache::AddFields( const ScDPObject& rDPObj )
+{
+ AddStdFields( rDPObj );
+ maPCInfo.mnStdFields = GetFieldCount();
+ AddGroupFields( rDPObj );
+ AddCalcFields( rDPObj );
+ maPCInfo.mnTotalFields = GetFieldCount();
+};
+
+void XclExpPivotCache::AddStdFields( const ScDPObject& rDPObj )
+{
+ // if item index list is not written, used shortened source range (maDocSrcRange) for performance
+ const ScRange& rRange = HasItemIndexList() ? maExpSrcRange : maDocSrcRange;
+ // create a standard pivot cache field for each source column
+ for( SCCOL nScCol = rRange.aStart.Col(), nEndScCol = rRange.aEnd.Col(); nScCol <= nEndScCol; ++nScCol )
+ {
+ ScRange aColRange( rRange );
+ aColRange.aStart.SetCol( nScCol );
+ aColRange.aEnd.SetCol( nScCol );
+ maFieldList.AppendNewRecord( new XclExpPCField(
+ GetRoot(), *this, GetFieldCount(), rDPObj, aColRange ) );
+ }
+}
+
+void XclExpPivotCache::AddGroupFields( const ScDPObject& rDPObj )
+{
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ if( const ScDPDimensionSaveData* pSaveDimData = pSaveData->GetExistingDimensionData() )
+ {
+ // loop over all existing standard fields to find their group fields
+ for( sal_uInt16 nFieldIdx = 0; nFieldIdx < maPCInfo.mnStdFields; ++nFieldIdx )
+ {
+ if( XclExpPCField* pCurrStdField = GetFieldAcc( nFieldIdx ) )
+ {
+ const ScDPSaveGroupDimension* pGroupDim = pSaveDimData->GetGroupDimForBase( pCurrStdField->GetFieldName() );
+ XclExpPCField* pLastGroupField = pCurrStdField;
+ while( pGroupDim )
+ {
+ // insert the new grouping field
+ XclExpPCFieldRef xNewGroupField( new XclExpPCField(
+ GetRoot(), *this, GetFieldCount(), rDPObj, *pGroupDim, *pCurrStdField ) );
+ maFieldList.AppendRecord( xNewGroupField );
+
+ // register new grouping field at current grouping field, building a chain
+ pLastGroupField->SetGroupChildField( *xNewGroupField );
+
+ // next grouping dimension
+ pGroupDim = pSaveDimData->GetGroupDimForBase( pGroupDim->GetGroupDimName() );
+ pLastGroupField = xNewGroupField.get();
+ }
+ }
+ }
+ }
+ }
+}
+
+void XclExpPivotCache::AddCalcFields( const ScDPObject& /*rDPObj*/ )
+{
+ // not supported
+}
+
+void XclExpPivotCache::WriteDconref( XclExpStream& rStrm ) const
+{
+ XclExpString aRef( XclExpUrlHelper::EncodeUrl( GetRoot(), EMPTY_STRING, &maTabName ) );
+ rStrm.StartRecord( EXC_ID_DCONREF, 7 + aRef.GetSize() );
+ rStrm << static_cast< sal_uInt16 >( maExpSrcRange.aStart.Row() )
+ << static_cast< sal_uInt16 >( maExpSrcRange.aEnd.Row() )
+ << static_cast< sal_uInt8 >( maExpSrcRange.aStart.Col() )
+ << static_cast< sal_uInt8 >( maExpSrcRange.aEnd.Col() )
+ << aRef
+ << sal_uInt8( 0 );
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteCacheStream()
+{
+ SotStorageRef xSvStrg = OpenStorage( EXC_STORAGE_PTCACHE );
+ SotStorageStreamRef xSvStrm = OpenStream( xSvStrg, ScfTools::GetHexStr( maPCInfo.mnStrmId ) );
+ if( xSvStrm.Is() )
+ {
+ XclExpStream aStrm( *xSvStrm, GetRoot() );
+ // SXDB
+ WriteSxdb( aStrm );
+ // SXDBEX
+ WriteSxdbex( aStrm );
+ // field list (SXFIELD and items)
+ maFieldList.Save( aStrm );
+ // index table (list of SXINDEXLIST)
+ WriteSxindexlistList( aStrm );
+ // EOF
+ XclExpEmptyRecord( EXC_ID_EOF ).Save( aStrm );
+ }
+}
+
+void XclExpPivotCache::WriteSxdb( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXDB, 21 );
+ rStrm << maPCInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteSxdbex( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXDBEX, 12 );
+ rStrm << EXC_SXDBEX_CREATION_DATE
+ << sal_uInt32( 0 ); // number of SXFORMULA records
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteSxindexlistList( XclExpStream& rStrm ) const
+{
+ if( HasItemIndexList() )
+ {
+ sal_Size nRecSize = 0;
+ size_t nPos, nSize = maFieldList.GetSize();
+ for( nPos = 0; nPos < nSize; ++nPos )
+ nRecSize += maFieldList.GetRecord( nPos )->GetIndexSize();
+
+ for( sal_uInt32 nSrcRow = 0; nSrcRow < maPCInfo.mnSrcRecs; ++nSrcRow )
+ {
+ rStrm.StartRecord( EXC_ID_SXINDEXLIST, nRecSize );
+ for( nPos = 0; nPos < nSize; ++nPos )
+ maFieldList.GetRecord( nPos )->WriteIndex( rStrm, nSrcRow );
+ rStrm.EndRecord();
+ }
+ }
+}
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+namespace {
+
+// ----------------------------------------------------------------------------
+
+/** Returns a display string for a data field containing the field name and aggregation function. */
+String lclGetDataFieldCaption( const String& rFieldName, GeneralFunction eFunc )
+{
+ String aCaption;
+
+ USHORT nResIdx = 0;
+ using namespace ::com::sun::star::sheet;
+ switch( eFunc )
+ {
+ case GeneralFunction_SUM: nResIdx = STR_FUN_TEXT_SUM; break;
+ case GeneralFunction_COUNT: nResIdx = STR_FUN_TEXT_COUNT; break;
+ case GeneralFunction_AVERAGE: nResIdx = STR_FUN_TEXT_AVG; break;
+ case GeneralFunction_MAX: nResIdx = STR_FUN_TEXT_MAX; break;
+ case GeneralFunction_MIN: nResIdx = STR_FUN_TEXT_MIN; break;
+ case GeneralFunction_PRODUCT: nResIdx = STR_FUN_TEXT_PRODUCT; break;
+ case GeneralFunction_COUNTNUMS: nResIdx = STR_FUN_TEXT_COUNT; break;
+ case GeneralFunction_STDEV: nResIdx = STR_FUN_TEXT_STDDEV; break;
+ case GeneralFunction_STDEVP: nResIdx = STR_FUN_TEXT_STDDEV; break;
+ case GeneralFunction_VAR: nResIdx = STR_FUN_TEXT_VAR; break;
+ case GeneralFunction_VARP: nResIdx = STR_FUN_TEXT_VAR; break;
+ default:;
+ }
+ if( nResIdx )
+ aCaption.Assign( ScGlobal::GetRscString( nResIdx ) ).AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) );
+ aCaption.Append( rFieldName );
+ return aCaption;
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// ============================================================================
+
+XclExpPTItem::XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx ) :
+ XclExpRecord( EXC_ID_SXVI, 8 ),
+ mpCacheItem( rCacheField.GetItem( nCacheIdx ) )
+{
+ maItemInfo.mnType = EXC_SXVI_TYPE_DATA;
+ maItemInfo.mnCacheIdx = nCacheIdx;
+ maItemInfo.maVisName.mbUseCache = mpCacheItem != 0;
+}
+
+XclExpPTItem::XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx, bool bUseCache ) :
+ XclExpRecord( EXC_ID_SXVI, 8 ),
+ mpCacheItem( 0 )
+{
+ maItemInfo.mnType = nItemType;
+ maItemInfo.mnCacheIdx = nCacheIdx;
+ maItemInfo.maVisName.mbUseCache = bUseCache;
+}
+
+const String& XclExpPTItem::GetItemName() const
+{
+ return mpCacheItem ? mpCacheItem->ConvertToText() : EMPTY_STRING;
+}
+
+void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem )
+{
+ ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() );
+ ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() );
+
+ // visible name
+ const OUString* pVisName = rSaveMem.GetLayoutName();
+ if (pVisName && !pVisName->equals(GetItemName()))
+ maItemInfo.SetVisName(*pVisName);
+}
+
+void XclExpPTItem::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maItemInfo;
+}
+
+// ============================================================================
+
+XclExpPTField::XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx ) :
+ mrPTable( rPTable ),
+ mpCacheField( rPTable.GetCacheField( nCacheIdx ) )
+{
+ maFieldInfo.mnCacheIdx = nCacheIdx;
+
+ // create field items
+ if( mpCacheField )
+ for( sal_uInt16 nItemIdx = 0, nItemCount = mpCacheField->GetItemCount(); nItemIdx < nItemCount; ++nItemIdx )
+ maItemList.AppendNewRecord( new XclExpPTItem( *mpCacheField, nItemIdx ) );
+ maFieldInfo.mnItemCount = static_cast< sal_uInt16 >( maItemList.GetSize() );
+}
+
+// data access ----------------------------------------------------------------
+
+const String& XclExpPTField::GetFieldName() const
+{
+ return mpCacheField ? mpCacheField->GetFieldName() : EMPTY_STRING;
+}
+
+sal_uInt16 XclExpPTField::GetFieldIndex() const
+{
+ // field index always equal to cache index
+ return maFieldInfo.mnCacheIdx;
+}
+
+sal_uInt16 XclExpPTField::GetLastDataInfoIndex() const
+{
+ DBG_ASSERT( !maDataInfoVec.empty(), "XclExpPTField::GetLastDataInfoIndex - no data info found" );
+ // will return 0xFFFF for empty vector -> ok
+ return static_cast< sal_uInt16 >( maDataInfoVec.size() - 1 );
+}
+
+//UNUSED2009-05 const XclExpPTItem* XclExpPTField::GetItem( const String& rName ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 return const_cast< XclExpPTField* >( this )->GetItemAcc( rName );
+//UNUSED2009-05 }
+
+sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefaultIdx ) const
+{
+ for( size_t nPos = 0, nSize = maItemList.GetSize(); nPos < nSize; ++nPos )
+ if( maItemList.GetRecord( nPos )->GetItemName() == rName )
+ return static_cast< sal_uInt16 >( nPos );
+ return nDefaultIdx;
+}
+
+// fill data --------------------------------------------------------------
+
+/**
+ * Calc's subtotal names are escaped with backslashes ('\'), while Excel's
+ * are not escaped at all.
+ */
+static OUString lcl_convertCalcSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ bool bEscaped = false;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ aBuf.append(c);
+ bEscaped = false;
+ }
+ return aBuf.makeStringAndClear();
+}
+
+void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ // orientation
+ DataPilotFieldOrientation eOrient = static_cast< DataPilotFieldOrientation >( rSaveDim.GetOrientation() );
+ DBG_ASSERT( eOrient != DataPilotFieldOrientation_DATA, "XclExpPTField::SetPropertiesFromDim - called for data field" );
+ maFieldInfo.AddApiOrient( eOrient );
+
+ // show empty items
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() );
+
+ // visible name
+ const OUString* pLayoutName = rSaveDim.GetLayoutName();
+ if (pLayoutName && !pLayoutName->equals(GetFieldName()))
+ maFieldInfo.SetVisName(*pLayoutName);
+
+ const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName();
+ if (pSubtotalName)
+ {
+ OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName);
+ maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName));
+ }
+
+ // subtotals
+ XclPTSubtotalVec aSubtotals;
+ aSubtotals.reserve( static_cast< size_t >( rSaveDim.GetSubTotalsCount() ) );
+ for( long nSubtIdx = 0, nSubtCount = rSaveDim.GetSubTotalsCount(); nSubtIdx < nSubtCount; ++nSubtIdx )
+ aSubtotals.push_back( rSaveDim.GetSubTotalFunc( nSubtIdx ) );
+ maFieldInfo.SetSubtotals( aSubtotals );
+
+ // sorting
+ if( const DataPilotFieldSortInfo* pSortInfo = rSaveDim.GetSortInfo() )
+ {
+ maFieldExtInfo.SetApiSortMode( pSortInfo->Mode );
+ if( pSortInfo->Mode == ::com::sun::star::sheet::DataPilotFieldSortMode::DATA )
+ maFieldExtInfo.mnSortField = mrPTable.GetDataFieldIndex( pSortInfo->Field, EXC_SXVDEX_SORT_OWN );
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SORT_ASC, pSortInfo->IsAscending );
+ }
+
+ // auto show
+ if( const DataPilotFieldAutoShowInfo* pShowInfo = rSaveDim.GetAutoShowInfo() )
+ {
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_AUTOSHOW, pShowInfo->IsEnabled );
+ maFieldExtInfo.SetApiAutoShowMode( pShowInfo->ShowItemsMode );
+ maFieldExtInfo.SetApiAutoShowCount( pShowInfo->ItemCount );
+ maFieldExtInfo.mnShowField = mrPTable.GetDataFieldIndex( pShowInfo->DataField, EXC_SXVDEX_SHOW_NONE );
+ }
+
+ // layout
+ if( const DataPilotFieldLayoutInfo* pLayoutInfo = rSaveDim.GetLayoutInfo() )
+ {
+ maFieldExtInfo.SetApiLayoutMode( pLayoutInfo->LayoutMode );
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_LAYOUT_BLANK, pLayoutInfo->AddEmptyLines );
+ }
+
+ // special page field properties
+ if( eOrient == DataPilotFieldOrientation_PAGE )
+ {
+ maPageInfo.mnField = GetFieldIndex();
+
+ // selected item
+ if( rSaveDim.HasCurrentPage() )
+ maPageInfo.mnSelItem = GetItemIndex( rSaveDim.GetCurrentPage(), EXC_SXPI_ALLITEMS );
+ else
+ maPageInfo.mnSelItem = EXC_SXPI_ALLITEMS;
+ }
+
+ // item properties
+ const ScDPSaveDimension::MemberList &rMembers = rSaveDim.GetMembers();
+ for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
+ if( XclExpPTItem* pItem = GetItemAcc( (*i)->GetName() ) )
+ pItem->SetPropertiesFromMember( **i );
+}
+
+void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ maDataInfoVec.push_back( XclPTDataFieldInfo() );
+ XclPTDataFieldInfo& rDataInfo = maDataInfoVec.back();
+ rDataInfo.mnField = GetFieldIndex();
+
+ // orientation
+ maFieldInfo.AddApiOrient( DataPilotFieldOrientation_DATA );
+
+ // aggregation function
+ GeneralFunction eFunc = static_cast< GeneralFunction >( rSaveDim.GetFunction() );
+ rDataInfo.SetApiAggFunc( eFunc );
+
+ // visible name
+ const rtl::OUString* pVisName = rSaveDim.GetLayoutName();
+ if (pVisName)
+ rDataInfo.SetVisName(*pVisName);
+ else
+ rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
+
+ // result field reference
+ if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() )
+ {
+ rDataInfo.SetApiRefType( pFieldRef->ReferenceType );
+ rDataInfo.SetApiRefItemType( pFieldRef->ReferenceItemType );
+ if( const XclExpPTField* pRefField = mrPTable.GetField( pFieldRef->ReferenceField ) )
+ {
+ rDataInfo.mnRefField = pRefField->GetFieldIndex();
+ if( pFieldRef->ReferenceItemType == ::com::sun::star::sheet::DataPilotFieldReferenceItemType::NAMED )
+ rDataInfo.mnRefItem = pRefField->GetItemIndex( pFieldRef->ReferenceItemName, 0 );
+ }
+ }
+}
+
+void XclExpPTField::AppendSubtotalItems()
+{
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) AppendSubtotalItem( EXC_SXVI_TYPE_DEFAULT );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_SUM ) AppendSubtotalItem( EXC_SXVI_TYPE_SUM );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_COUNT ) AppendSubtotalItem( EXC_SXVI_TYPE_COUNT );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) AppendSubtotalItem( EXC_SXVI_TYPE_AVERAGE );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_MAX ) AppendSubtotalItem( EXC_SXVI_TYPE_MAX );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_MIN ) AppendSubtotalItem( EXC_SXVI_TYPE_MIN );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_PROD ) AppendSubtotalItem( EXC_SXVI_TYPE_PROD );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) AppendSubtotalItem( EXC_SXVI_TYPE_COUNTNUM );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_STDDEV ) AppendSubtotalItem( EXC_SXVI_TYPE_STDDEV );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) AppendSubtotalItem( EXC_SXVI_TYPE_STDDEVP );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_VAR ) AppendSubtotalItem( EXC_SXVI_TYPE_VAR );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_VARP ) AppendSubtotalItem( EXC_SXVI_TYPE_VARP );
+}
+
+// records --------------------------------------------------------------------
+
+void XclExpPTField::WriteSxpiEntry( XclExpStream& rStrm ) const
+{
+ rStrm << maPageInfo;
+}
+
+void XclExpPTField::WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const
+{
+ DBG_ASSERT( nDataInfoIdx < maDataInfoVec.size(), "XclExpPTField::WriteSxdi - data field not found" );
+ if( nDataInfoIdx < maDataInfoVec.size() )
+ {
+ rStrm.StartRecord( EXC_ID_SXDI, 12 );
+ rStrm << maDataInfoVec[ nDataInfoIdx ];
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPTField::Save( XclExpStream& rStrm )
+{
+ // SXVD
+ WriteSxvd( rStrm );
+ // list of SXVI records
+ maItemList.Save( rStrm );
+ // SXVDEX
+ WriteSxvdex( rStrm );
+}
+
+// private --------------------------------------------------------------------
+
+XclExpPTItem* XclExpPTField::GetItemAcc( const String& rName )
+{
+ XclExpPTItem* pItem = 0;
+ for( size_t nPos = 0, nSize = maItemList.GetSize(); !pItem && (nPos < nSize); ++nPos )
+ if( maItemList.GetRecord( nPos )->GetItemName() == rName )
+ pItem = maItemList.GetRecord( nPos ).get();
+ return pItem;
+}
+
+void XclExpPTField::AppendSubtotalItem( sal_uInt16 nItemType )
+{
+ maItemList.AppendNewRecord( new XclExpPTItem( nItemType, EXC_SXVI_DEFAULT_CACHE, true ) );
+ ++maFieldInfo.mnItemCount;
+}
+
+void XclExpPTField::WriteSxvd( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXVD, 10 );
+ rStrm << maFieldInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPTField::WriteSxvdex( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXVDEX, 20 );
+ rStrm << maFieldExtInfo;
+ rStrm.EndRecord();
+}
+
+// ============================================================================
+
+XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& rDPObj, const XclExpPivotCache& rPCache ) :
+ XclExpRoot( rRoot ),
+ mrPCache( rPCache ),
+ maDataOrientField( *this, EXC_SXIVD_DATA ),
+ mnOutScTab( 0 ),
+ mbValid( false ),
+ mbFilterBtn( false )
+{
+ const ScRange& rOutScRange = rDPObj.GetOutRange();
+ if( GetAddressConverter().ConvertRange( maPTInfo.maOutXclRange, rOutScRange, true ) )
+ {
+ // DataPilot properties -----------------------------------------------
+
+ // pivot table properties from DP object
+ mnOutScTab = rOutScRange.aStart.Tab();
+ maPTInfo.maTableName = rDPObj.GetName();
+ maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex();
+
+ maPTViewEx9Info.Init( rDPObj );
+
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ // additional properties from ScDPSaveData
+ SetPropertiesFromDP( *pSaveData );
+
+ // loop over all dimensions ---------------------------------------
+
+ /* 1) Default-construct all pivot table fields for all pivot cache fields. */
+ for( sal_uInt16 nFieldIdx = 0, nFieldCount = mrPCache.GetFieldCount(); nFieldIdx < nFieldCount; ++nFieldIdx )
+ maFieldList.AppendNewRecord( new XclExpPTField( *this, nFieldIdx ) );
+
+ const List& rDimList = pSaveData->GetDimensions();
+ ULONG nDimIdx, nDimCount = rDimList.Count();
+
+ /* 2) First process all data dimensions, they are needed for extended
+ settings of row/column/page fields (sorting/auto show). */
+ for( nDimIdx = 0; nDimIdx < nDimCount; ++nDimIdx )
+ if( const ScDPSaveDimension* pSaveDim = static_cast< const ScDPSaveDimension* >( rDimList.GetObject( nDimIdx ) ) )
+ if( pSaveDim->GetOrientation() == DataPilotFieldOrientation_DATA )
+ SetDataFieldPropertiesFromDim( *pSaveDim );
+
+ /* 3) Row/column/page/hidden fields. */
+ for( nDimIdx = 0; nDimIdx < nDimCount; ++nDimIdx )
+ if( const ScDPSaveDimension* pSaveDim = static_cast< const ScDPSaveDimension* >( rDimList.GetObject( nDimIdx ) ) )
+ if( pSaveDim->GetOrientation() != DataPilotFieldOrientation_DATA )
+ SetFieldPropertiesFromDim( *pSaveDim );
+
+ // Finalize -------------------------------------------------------
+
+ Finalize();
+ mbValid = true;
+ }
+ }
+}
+
+const XclExpPCField* XclExpPivotTable::GetCacheField( sal_uInt16 nCacheIdx ) const
+{
+ return mrPCache.GetField( nCacheIdx );
+}
+
+const XclExpPTField* XclExpPivotTable::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return (nFieldIdx == EXC_SXIVD_DATA) ? &maDataOrientField : maFieldList.GetRecord( nFieldIdx ).get();
+}
+
+const XclExpPTField* XclExpPivotTable::GetField( const String& rName ) const
+{
+ return const_cast< XclExpPivotTable* >( this )->GetFieldAcc( rName );
+}
+
+sal_uInt16 XclExpPivotTable::GetDataFieldIndex( const String& rName, sal_uInt16 nDefaultIdx ) const
+{
+ for( XclPTDataFieldPosVec::const_iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
+ if( const XclExpPTField* pField = GetField( aIt->first ) )
+ if( pField->GetFieldName() == rName )
+ return static_cast< sal_uInt16 >( aIt - maDataFields.begin() );
+ return nDefaultIdx;
+}
+
+void XclExpPivotTable::Save( XclExpStream& rStrm )
+{
+ if( mbValid )
+ {
+ // SXVIEW
+ WriteSxview( rStrm );
+ // pivot table fields (SXVD, SXVDEX, and item records)
+ maFieldList.Save( rStrm );
+ // SXIVD records for row and column fields
+ WriteSxivd( rStrm, maRowFields );
+ WriteSxivd( rStrm, maColFields );
+ // SXPI
+ WriteSxpi( rStrm );
+ // list of SXDI records containing data field info
+ WriteSxdiList( rStrm );
+ // SXLI records
+ WriteSxli( rStrm, maPTInfo.mnDataRows, maPTInfo.mnRowFields );
+ WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields );
+ // SXEX
+ WriteSxex( rStrm );
+ // QSISXTAG
+ WriteQsiSxTag( rStrm );
+ // SXVIEWEX9
+ WriteSxViewEx9( rStrm );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+XclExpPTField* XclExpPivotTable::GetFieldAcc( const String& rName )
+{
+ XclExpPTField* pField = 0;
+ for( size_t nPos = 0, nSize = maFieldList.GetSize(); !pField && (nPos < nSize); ++nPos )
+ if( maFieldList.GetRecord( nPos )->GetFieldName() == rName )
+ pField = maFieldList.GetRecord( nPos ).get();
+ return pField;
+}
+
+XclExpPTField* XclExpPivotTable::GetFieldAcc( const ScDPSaveDimension& rSaveDim )
+{
+ // data field orientation field?
+ if( rSaveDim.IsDataLayout() )
+ return &maDataOrientField;
+
+ // a real dimension
+ String aFieldName( rSaveDim.GetName() );
+ return aFieldName.Len() ? GetFieldAcc( aFieldName ) : 0;
+}
+
+// fill data --------------------------------------------------------------
+
+void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData )
+{
+ ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_ROWGRAND, rSaveData.GetRowGrand() );
+ ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() );
+ ::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() );
+ mbFilterBtn = rSaveData.GetFilterButton();
+ const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension();
+ if (!pDim)
+ return;
+
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maPTInfo.maDataName = *pLayoutName;
+ else
+ maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA);
+}
+
+void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ if( XclExpPTField* pField = GetFieldAcc( rSaveDim ) )
+ {
+ // field properties
+ pField->SetPropertiesFromDim( rSaveDim );
+
+ // update the corresponding field position list
+ DataPilotFieldOrientation eOrient = static_cast< DataPilotFieldOrientation >( rSaveDim.GetOrientation() );
+ sal_uInt16 nFieldIdx = pField->GetFieldIndex();
+ bool bDataLayout = nFieldIdx == EXC_SXIVD_DATA;
+ bool bMultiData = maDataFields.size() > 1;
+
+ if( !bDataLayout || bMultiData ) switch( eOrient )
+ {
+ case DataPilotFieldOrientation_ROW:
+ maRowFields.push_back( nFieldIdx );
+ if( bDataLayout )
+ maPTInfo.mnDataAxis = EXC_SXVD_AXIS_ROW;
+ break;
+ case DataPilotFieldOrientation_COLUMN:
+ maColFields.push_back( nFieldIdx );
+ if( bDataLayout )
+ maPTInfo.mnDataAxis = EXC_SXVD_AXIS_COL;
+ break;
+ case DataPilotFieldOrientation_PAGE:
+ maPageFields.push_back( nFieldIdx );
+ DBG_ASSERT( !bDataLayout, "XclExpPivotTable::SetFieldPropertiesFromDim - wrong orientation for data fields" );
+ break;
+ case DataPilotFieldOrientation_DATA:
+ DBG_ERRORFILE( "XclExpPivotTable::SetFieldPropertiesFromDim - called for data field" );
+ break;
+ default:;
+ }
+ }
+}
+
+void XclExpPivotTable::SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ if( XclExpPTField* pField = GetFieldAcc( rSaveDim ) )
+ {
+ // field properties
+ pField->SetDataPropertiesFromDim( rSaveDim );
+ // update the data field position list
+ maDataFields.push_back( XclPTDataFieldPos( pField->GetFieldIndex(), pField->GetLastDataInfoIndex() ) );
+ }
+}
+
+void XclExpPivotTable::Finalize()
+{
+ // field numbers
+ maPTInfo.mnFields = static_cast< sal_uInt16 >( maFieldList.GetSize() );
+ maPTInfo.mnRowFields = static_cast< sal_uInt16 >( maRowFields.size() );
+ maPTInfo.mnColFields = static_cast< sal_uInt16 >( maColFields.size() );
+ maPTInfo.mnPageFields = static_cast< sal_uInt16 >( maPageFields.size() );
+ maPTInfo.mnDataFields = static_cast< sal_uInt16 >( maDataFields.size() );
+
+ maPTExtInfo.mnPagePerRow = maPTInfo.mnPageFields;
+ maPTExtInfo.mnPagePerCol = (maPTInfo.mnPageFields > 0) ? 1 : 0;
+
+ // subtotal items
+ for( size_t nPos = 0, nSize = maFieldList.GetSize(); nPos < nSize; ++nPos )
+ maFieldList.GetRecord( nPos )->AppendSubtotalItems();
+
+ // find data field orientation field
+ maPTInfo.mnDataPos = EXC_SXVIEW_DATALAST;
+ const ScfUInt16Vec* pFieldVec = 0;
+ switch( maPTInfo.mnDataAxis )
+ {
+ case EXC_SXVD_AXIS_ROW: pFieldVec = &maRowFields; break;
+ case EXC_SXVD_AXIS_COL: pFieldVec = &maColFields; break;
+ }
+
+ if( pFieldVec && !pFieldVec->empty() && (pFieldVec->back() != EXC_SXIVD_DATA) )
+ {
+ ScfUInt16Vec::const_iterator aIt = ::std::find( pFieldVec->begin(), pFieldVec->end(), EXC_SXIVD_DATA );
+ if( aIt != pFieldVec->end() )
+ maPTInfo.mnDataPos = static_cast< sal_uInt16 >( aIt - pFieldVec->begin() );
+ }
+
+ // single data field is always row oriented
+ if( maPTInfo.mnDataAxis == EXC_SXVD_AXIS_NONE )
+ maPTInfo.mnDataAxis = EXC_SXVD_AXIS_ROW;
+
+ // update output range (initialized in ctor)
+ sal_uInt16& rnXclCol1 = maPTInfo.maOutXclRange.maFirst.mnCol;
+ sal_uInt16& rnXclRow1 = maPTInfo.maOutXclRange.maFirst.mnRow;
+ sal_uInt16& rnXclCol2 = maPTInfo.maOutXclRange.maLast.mnCol;
+ sal_uInt16& rnXclRow2 = maPTInfo.maOutXclRange.maLast.mnRow;
+ // exclude page fields from output range
+ rnXclRow1 = rnXclRow1 + maPTInfo.mnPageFields;
+ // exclude filter button from output range
+ if( mbFilterBtn )
+ ++rnXclRow1;
+ // exclude empty row between (filter button and/or page fields) and table
+ if( mbFilterBtn || maPTInfo.mnPageFields )
+ ++rnXclRow1;
+
+ // data area
+ sal_uInt16& rnDataXclCol = maPTInfo.maDataXclPos.mnCol;
+ sal_uInt16& rnDataXclRow = maPTInfo.maDataXclPos.mnRow;
+ rnDataXclCol = rnXclCol1 + maPTInfo.mnRowFields;
+ rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1;
+ if( maDataFields.empty() )
+ ++rnDataXclRow;
+
+ bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0);
+ if (bExtraHeaderRow)
+ // Insert an extra row only when there is no column field.
+ ++rnDataXclRow;
+
+ rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol );
+ rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow );
+ maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1;
+ maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1;
+
+ // first heading
+ maPTInfo.mnFirstHeadRow = rnXclRow1;
+ if (bExtraHeaderRow)
+ maPTInfo.mnFirstHeadRow += 2;
+}
+
+// records ----------------------------------------------------------------
+
+void XclExpPivotTable::WriteSxview( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXVIEW, 46 + maPTInfo.maTableName.Len() + maPTInfo.maDataName.Len() );
+ rStrm << maPTInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ) const
+{
+ if( !rFields.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_SXIVD, rFields.size() * 2 );
+ for( ScfUInt16Vec::const_iterator aIt = rFields.begin(), aEnd = rFields.end(); aIt != aEnd; ++aIt )
+ rStrm << *aIt;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPivotTable::WriteSxpi( XclExpStream& rStrm ) const
+{
+ if( !maPageFields.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_SXPI, maPageFields.size() * 6 );
+ rStrm.SetSliceSize( 6 );
+ for( ScfUInt16Vec::const_iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
+ {
+ XclExpPTFieldRef xField = maFieldList.GetRecord( *aIt );
+ if( xField.is() )
+ xField->WriteSxpiEntry( rStrm );
+ }
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPivotTable::WriteSxdiList( XclExpStream& rStrm ) const
+{
+ for( XclPTDataFieldPosVec::const_iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
+ {
+ XclExpPTFieldRef xField = maFieldList.GetRecord( aIt->first );
+ if( xField.is() )
+ xField->WriteSxdi( rStrm, aIt->second );
+ }
+}
+
+void XclExpPivotTable::WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const
+{
+ if( nLineCount > 0 )
+ {
+ sal_uInt16 nLineSize = 8 + 2 * nIndexCount;
+ rStrm.StartRecord( EXC_ID_SXLI, nLineSize * nLineCount );
+
+ /* #158444# Excel expects the records to be filled completely, do not
+ set a segment size... */
+// rStrm.SetSliceSize( nLineSize );
+
+ for( sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
+ {
+ // #106598# Excel XP needs a partly initialized SXLI record
+ rStrm << sal_uInt16( 0 ) // number of equal index entries
+ << EXC_SXVI_TYPE_DATA
+ << nIndexCount
+ << EXC_SXLI_DEFAULTFLAGS;
+ rStrm.WriteZeroBytes( 2 * nIndexCount );
+ }
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXEX, 24 );
+ rStrm << maPTExtInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( 0x0802, 32 );
+
+ sal_uInt16 nRecordType = 0x0802;
+ sal_uInt16 nDummyFlags = 0x0000;
+ sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table
+
+ rStrm << nRecordType << nDummyFlags << nTableType;
+
+ // General flags
+ bool bEnableRefresh = true;
+ bool bPCacheInvalid = false;
+ bool bOlapPTReport = false;
+
+ sal_uInt16 nFlags = 0x0000;
+ if (bEnableRefresh) nFlags |= 0x0001;
+ if (bPCacheInvalid) nFlags |= 0x0002;
+ if (bOlapPTReport) nFlags |= 0x0004;
+ rStrm << nFlags;
+
+ // Feature-specific options. The value differs depending on the table
+ // type, but we assume the table type is always pivot table.
+ sal_uInt32 nOptions = 0x00000000;
+ bool bNoStencil = false;
+ bool bHideTotal = false;
+ bool bEmptyRows = false;
+ bool bEmptyCols = false;
+ if (bNoStencil) nOptions |= 0x00000001;
+ if (bHideTotal) nOptions |= 0x00000002;
+ if (bEmptyRows) nOptions |= 0x00000008;
+ if (bEmptyCols) nOptions |= 0x00000010;
+ rStrm << nOptions;
+
+ enum ExcelVersion
+ {
+ Excel2000 = 0,
+ ExcelXP = 1,
+ Excel2003 = 2,
+ Excel2007 = 3
+ };
+ ExcelVersion eXclVer = Excel2000;
+ sal_uInt8 nOffsetBytes = 16;
+ rStrm << static_cast<sal_uInt8>(eXclVer) // version table last refreshed
+ << static_cast<sal_uInt8>(eXclVer) // minimum version to refresh
+ << nOffsetBytes
+ << static_cast<sal_uInt8>(eXclVer); // first version created
+
+ rStrm << XclExpString(maPTInfo.maTableName);
+ rStrm << static_cast<sal_uInt16>(0x0001); // no idea what this is for.
+
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const
+{
+ // Until we sync the autoformat ids only export if using grid header layout
+ // That could only have been set via xls import so far.
+ if ( 0 == maPTViewEx9Info.mnGridLayout )
+ {
+ rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 );
+ rStrm << maPTViewEx9Info;
+ rStrm.EndRecord();
+ }
+}
+
+// ============================================================================
+
+namespace {
+
+const SCTAB EXC_PTMGR_PIVOTCACHES = SCTAB_MAX;
+
+/** Record wrapper class to write the pivot caches or pivot tables. */
+class XclExpPivotRecWrapper : public XclExpRecordBase
+{
+public:
+ explicit XclExpPivotRecWrapper( XclExpPivotTableManager& rPTMgr, SCTAB nScTab );
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ XclExpPivotTableManager& mrPTMgr;
+ SCTAB mnScTab;
+};
+
+XclExpPivotRecWrapper::XclExpPivotRecWrapper( XclExpPivotTableManager& rPTMgr, SCTAB nScTab ) :
+ mrPTMgr( rPTMgr ),
+ mnScTab( nScTab )
+{
+}
+
+void XclExpPivotRecWrapper::Save( XclExpStream& rStrm )
+{
+ if( mnScTab == EXC_PTMGR_PIVOTCACHES )
+ mrPTMgr.WritePivotCaches( rStrm );
+ else
+ mrPTMgr.WritePivotTables( rStrm, mnScTab );
+}
+
+void XclExpPivotRecWrapper::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnScTab == EXC_PTMGR_PIVOTCACHES )
+ mrPTMgr.WritePivotCachesXml( rStrm );
+ else
+ mrPTMgr.WritePivotTablesXml( rStrm, mnScTab );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpPivotTableManager::XclExpPivotTableManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mbShareCaches( true )
+{
+}
+
+void XclExpPivotTableManager::CreatePivotTables()
+{
+ if( ScDPCollection* pDPColl = GetDoc().GetDPCollection() )
+ for( USHORT nDPObj = 0, nCount = pDPColl->GetCount(); nDPObj < nCount; ++nDPObj )
+ if( ScDPObject* pDPObj = (*pDPColl)[ nDPObj ] )
+ if( const XclExpPivotCache* pPCache = CreatePivotCache( *pDPObj ) )
+ maPTableList.AppendNewRecord( new XclExpPivotTable( GetRoot(), *pDPObj, *pPCache ) );
+}
+
+XclExpRecordRef XclExpPivotTableManager::CreatePivotCachesRecord()
+{
+ return XclExpRecordRef( new XclExpPivotRecWrapper( *this, EXC_PTMGR_PIVOTCACHES ) );
+}
+
+XclExpRecordRef XclExpPivotTableManager::CreatePivotTablesRecord( SCTAB nScTab )
+{
+ return XclExpRecordRef( new XclExpPivotRecWrapper( *this, nScTab ) );
+}
+
+void XclExpPivotTableManager::WritePivotCaches( XclExpStream& rStrm )
+{
+ maPCacheList.Save( rStrm );
+}
+
+void XclExpPivotTableManager::WritePivotCachesXml( XclExpXmlStream& rStrm )
+{
+ if( maPCacheList.IsEmpty() )
+ return;
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_pivotCaches, FSEND );
+ maPCacheList.SaveXml( rStrm );
+ rWorkbook->endElement( XML_pivotCaches );
+}
+
+void XclExpPivotTableManager::WritePivotTables( XclExpStream& rStrm, SCTAB nScTab )
+{
+ for( size_t nPos = 0, nSize = maPTableList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpPivotTableRef xPTable = maPTableList.GetRecord( nPos );
+ if( xPTable->GetScTab() == nScTab )
+ xPTable->Save( rStrm );
+ }
+}
+
+void XclExpPivotTableManager::WritePivotTablesXml( XclExpXmlStream& rStrm, SCTAB nScTab )
+{
+ for( size_t nPos = 0, nSize = maPTableList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpPivotTableRef xPTable = maPTableList.GetRecord( nPos );
+ if( xPTable->GetScTab() == nScTab )
+ xPTable->SaveXml( rStrm );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+const XclExpPivotCache* XclExpPivotTableManager::CreatePivotCache( const ScDPObject& rDPObj )
+{
+ // try to find a pivot cache with the same data source
+ /* #i25110# In Excel, the pivot cache contains additional fields
+ (i.e. grouping info, calculated fields). If the passed DataPilot object
+ or the found cache contains this data, do not share the cache with
+ multiple pivot tables. */
+ if( mbShareCaches )
+ {
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ const ScDPDimensionSaveData* pDimSaveData = pSaveData->GetExistingDimensionData();
+ // no dimension save data at all or save data does not contain grouping info
+ if( !pDimSaveData || !pDimSaveData->HasGroupDimensions() )
+ {
+ // check all existing pivot caches
+ for( size_t nPos = 0, nSize = maPCacheList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpPivotCacheRef xPCache = maPCacheList.GetRecord( nPos );
+ // pivot cache does not have grouping info and source data is equal
+ if( !xPCache->HasAddFields() && xPCache->HasEqualDataSource( rDPObj ) )
+ return xPCache.get();
+ }
+ }
+ }
+ }
+
+ // create a new pivot cache
+ sal_uInt16 nNewCacheIdx = static_cast< sal_uInt16 >( maPCacheList.GetSize() );
+ XclExpPivotCacheRef xNewPCache( new XclExpPivotCache( GetRoot(), rDPObj, nNewCacheIdx ) );
+ if( xNewPCache->IsValid() )
+ {
+ maPCacheList.AppendRecord( xNewPCache );
+ return xNewPCache.get();
+ }
+
+ return 0;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xerecord.cxx b/sc/source/filter/excel/xerecord.cxx
new file mode 100644
index 000000000000..fed58411aa5c
--- /dev/null
+++ b/sc/source/filter/excel/xerecord.cxx
@@ -0,0 +1,302 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xerecord.hxx"
+#include "xeroot.hxx"
+
+#include <oox/core/tokens.hxx>
+
+// Base classes to export Excel records =======================================
+
+XclExpRecordBase::~XclExpRecordBase()
+{
+}
+
+void XclExpRecordBase::Save( XclExpStream& /*rStrm*/ )
+{
+}
+
+void XclExpRecordBase::SaveXml( XclExpXmlStream& /*rStrm*/ )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDelegatingRecord::XclExpDelegatingRecord( XclExpRecordBase* pRecord ) :
+ mpRecord( pRecord )
+{
+}
+
+XclExpDelegatingRecord::~XclExpDelegatingRecord()
+{
+ // Do Nothing; we use Delegating Record for other objects we "know" will
+ // survive...
+}
+
+void XclExpDelegatingRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mpRecord )
+ mpRecord->SaveXml( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlElementRecord::XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
+ : mnElement( nElement ), mpAttributes( pAttributes )
+{
+}
+
+XclExpXmlElementRecord::~XclExpXmlElementRecord()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlStartElementRecord::XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
+ : XclExpXmlElementRecord( nElement, pAttributes )
+{
+}
+
+XclExpXmlStartElementRecord::~XclExpXmlStartElementRecord()
+{
+}
+
+void XclExpXmlStartElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
+ if( ! mpAttributes )
+ {
+ rStream->startElement( mnElement, FSEND );
+ }
+ else
+ {
+ rStream->write( "<" )->writeId( mnElement );
+ (*mpAttributes)( rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlEndElementRecord::XclExpXmlEndElementRecord( sal_Int32 nElement )
+ : XclExpXmlElementRecord( nElement )
+{
+}
+
+XclExpXmlEndElementRecord::~XclExpXmlEndElementRecord()
+{
+}
+
+void XclExpXmlEndElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->endElement( mnElement );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlStartSingleElementRecord::XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
+ : XclExpXmlElementRecord( nElement, pAttributes )
+{
+}
+
+XclExpXmlStartSingleElementRecord::~XclExpXmlStartSingleElementRecord()
+{
+}
+
+void XclExpXmlStartSingleElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
+ rStream->write( "<" )->writeId( mnElement );
+ if( mpAttributes )
+ (*mpAttributes)( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlEndSingleElementRecord::XclExpXmlEndSingleElementRecord()
+{
+}
+
+XclExpXmlEndSingleElementRecord::~XclExpXmlEndSingleElementRecord()
+{
+}
+
+void XclExpXmlEndSingleElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->write( "/>" );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRecord::XclExpRecord( sal_uInt16 nRecId, sal_Size nRecSize ) :
+ mnRecSize( nRecSize ),
+ mnRecId( nRecId )
+{
+}
+
+XclExpRecord::~XclExpRecord()
+{
+}
+
+void XclExpRecord::SetRecHeader( sal_uInt16 nRecId, sal_Size nRecSize )
+{
+ SetRecId( nRecId );
+ SetRecSize( nRecSize );
+}
+
+void XclExpRecord::WriteBody( XclExpStream& /*rStrm*/ )
+{
+}
+
+void XclExpRecord::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mnRecId != EXC_ID_UNKNOWN, "XclExpRecord::Save - record ID uninitialized" );
+ rStrm.StartRecord( mnRecId, mnRecSize );
+ WriteBody( rStrm );
+ rStrm.EndRecord();
+}
+
+// ----------------------------------------------------------------------------
+
+template<>
+void XclExpValueRecord<double>::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnAttribute == -1 )
+ return;
+ rStrm.WriteAttributes(
+ mnAttribute, rtl::OString::valueOf( maValue ).getStr(),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclExpBoolRecord::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt16 >( mbValue ? 1 : 0 );
+}
+
+void XclExpBoolRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnAttribute == -1 )
+ return;
+
+ rStrm.WriteAttributes(
+ // HACK: HIDEOBJ (excdoc.cxx) should be its own object to handle XML_showObjects
+ mnAttribute, mnAttribute == XML_showObjects ? "all" : XclXmlUtils::ToPsz( mbValue ),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDummyRecord::XclExpDummyRecord( sal_uInt16 nRecId, const void* pRecData, sal_Size nRecSize ) :
+ XclExpRecord( nRecId )
+{
+ SetData( pRecData, nRecSize );
+}
+
+void XclExpDummyRecord::SetData( const void* pRecData, sal_Size nRecSize )
+{
+ mpData = pRecData;
+ SetRecSize( pRecData ? nRecSize : 0 );
+}
+
+void XclExpDummyRecord::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.Write( mpData, GetRecSize() );
+}
+
+// Future records =============================================================
+
+XclExpFutureRecord::XclExpFutureRecord( XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize ) :
+ XclExpRecord( nRecId, nRecSize ),
+ meRecType( eRecType )
+{
+}
+
+void XclExpFutureRecord::Save( XclExpStream& rStrm )
+{
+ rStrm.StartRecord( GetRecId(), GetRecSize() + ((meRecType == EXC_FUTUREREC_UNUSEDREF) ? 12 : 4) );
+ rStrm << GetRecId() << sal_uInt16( 0 );
+ if( meRecType == EXC_FUTUREREC_UNUSEDREF )
+ rStrm.WriteZeroBytes( 8 );
+ WriteBody( rStrm );
+ rStrm.EndRecord();
+}
+
+// ============================================================================
+
+XclExpSubStream::XclExpSubStream( sal_uInt16 nSubStrmType ) :
+ mnSubStrmType( nSubStrmType )
+{
+}
+
+void XclExpSubStream::Save( XclExpStream& rStrm )
+{
+ // BOF record
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF2:
+ rStrm.StartRecord( EXC_ID2_BOF, 4 );
+ rStrm << sal_uInt16( 7 ) << mnSubStrmType;
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF3:
+ rStrm.StartRecord( EXC_ID3_BOF, 6 );
+ rStrm << sal_uInt16( 0 ) << mnSubStrmType << sal_uInt16( 2104 );
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF4:
+ rStrm.StartRecord( EXC_ID4_BOF, 6 );
+ rStrm << sal_uInt16( 0 ) << mnSubStrmType << sal_uInt16( 1705 );
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF5:
+ rStrm.StartRecord( EXC_ID5_BOF, 8 );
+ rStrm << EXC_BOF_BIFF5 << mnSubStrmType << sal_uInt16( 4915 ) << sal_uInt16( 1994 );
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF8:
+ rStrm.StartRecord( EXC_ID5_BOF, 16 );
+ rStrm << EXC_BOF_BIFF8 << mnSubStrmType << sal_uInt16( 3612 ) << sal_uInt16( 1996 );
+ rStrm << sal_uInt32( 1 ) << sal_uInt32( 6 );
+ rStrm.EndRecord();
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+
+ // substream records
+ XclExpRecordList<>::Save( rStrm );
+
+ // EOF record
+ rStrm.StartRecord( EXC_ID_EOF, 0 );
+ rStrm.EndRecord();
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx
new file mode 100644
index 000000000000..50e07ae1f2ed
--- /dev/null
+++ b/sc/source/filter/excel/xeroot.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <unotools/saveopt.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include "xecontent.hxx"
+#include "xltracer.hxx"
+#include "xeescher.hxx"
+#include "xeformula.hxx"
+#include "xehelper.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xepivot.hxx"
+#include "xestyle.hxx"
+#include "xeroot.hxx"
+
+#include "excrecds.hxx" // for filter manager
+#include "tabprotection.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+
+// Global data ================================================================
+
+XclExpRootData::XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
+ XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, true )
+{
+ SvtSaveOptions aSaveOpt;
+ mbRelUrl = mrMedium.IsRemote() ? aSaveOpt.IsSaveRelINet() : aSaveOpt.IsSaveRelFSys();
+}
+
+XclExpRootData::~XclExpRootData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRoot::XclExpRoot( XclExpRootData& rExpRootData ) :
+ XclRoot( rExpRootData ),
+ mrExpData( rExpRootData )
+{
+}
+
+XclExpTabInfo& XclExpRoot::GetTabInfo() const
+{
+ DBG_ASSERT( mrExpData.mxTabInfo.is(), "XclExpRoot::GetTabInfo - missing object (wrong BIFF?)" );
+ return *mrExpData.mxTabInfo;
+}
+
+XclExpAddressConverter& XclExpRoot::GetAddressConverter() const
+{
+ DBG_ASSERT( mrExpData.mxAddrConv.is(), "XclExpRoot::GetAddressConverter - missing object (wrong BIFF?)" );
+ return *mrExpData.mxAddrConv;
+}
+
+XclExpFormulaCompiler& XclExpRoot::GetFormulaCompiler() const
+{
+ DBG_ASSERT( mrExpData.mxFmlaComp.is(), "XclExpRoot::GetFormulaCompiler - missing object (wrong BIFF?)" );
+ return *mrExpData.mxFmlaComp;
+}
+
+XclExpProgressBar& XclExpRoot::GetProgressBar() const
+{
+ DBG_ASSERT( mrExpData.mxProgress.is(), "XclExpRoot::GetProgressBar - missing object (wrong BIFF?)" );
+ return *mrExpData.mxProgress;
+}
+
+XclExpSst& XclExpRoot::GetSst() const
+{
+ DBG_ASSERT( mrExpData.mxSst.is(), "XclExpRoot::GetSst - missing object (wrong BIFF?)" );
+ return *mrExpData.mxSst;
+}
+
+XclExpPalette& XclExpRoot::GetPalette() const
+{
+ DBG_ASSERT( mrExpData.mxPalette.is(), "XclExpRoot::GetPalette - missing object (wrong BIFF?)" );
+ return *mrExpData.mxPalette;
+}
+
+XclExpFontBuffer& XclExpRoot::GetFontBuffer() const
+{
+ DBG_ASSERT( mrExpData.mxFontBfr.is(), "XclExpRoot::GetFontBuffer - missing object (wrong BIFF?)" );
+ return *mrExpData.mxFontBfr;
+}
+
+XclExpNumFmtBuffer& XclExpRoot::GetNumFmtBuffer() const
+{
+ DBG_ASSERT( mrExpData.mxNumFmtBfr.is(), "XclExpRoot::GetNumFmtBuffer - missing object (wrong BIFF?)" );
+ return *mrExpData.mxNumFmtBfr;
+}
+
+XclExpXFBuffer& XclExpRoot::GetXFBuffer() const
+{
+ DBG_ASSERT( mrExpData.mxXFBfr.is(), "XclExpRoot::GetXFBuffer - missing object (wrong BIFF?)" );
+ return *mrExpData.mxXFBfr;
+}
+
+XclExpLinkManager& XclExpRoot::GetGlobalLinkManager() const
+{
+ DBG_ASSERT( mrExpData.mxGlobLinkMgr.is(), "XclExpRoot::GetGlobalLinkManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxGlobLinkMgr;
+}
+
+XclExpLinkManager& XclExpRoot::GetLocalLinkManager() const
+{
+ DBG_ASSERT( GetLocalLinkMgrRef().is(), "XclExpRoot::GetLocalLinkManager - missing object (wrong BIFF?)" );
+ return *GetLocalLinkMgrRef();
+}
+
+XclExpNameManager& XclExpRoot::GetNameManager() const
+{
+ DBG_ASSERT( mrExpData.mxNameMgr.is(), "XclExpRoot::GetNameManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxNameMgr;
+}
+
+XclExpObjectManager& XclExpRoot::GetObjectManager() const
+{
+ DBG_ASSERT( mrExpData.mxObjMgr.is(), "XclExpRoot::GetObjectManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxObjMgr;
+}
+
+XclExpFilterManager& XclExpRoot::GetFilterManager() const
+{
+ DBG_ASSERT( mrExpData.mxFilterMgr.is(), "XclExpRoot::GetFilterManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxFilterMgr;
+}
+
+XclExpPivotTableManager& XclExpRoot::GetPivotTableManager() const
+{
+ DBG_ASSERT( mrExpData.mxPTableMgr.is(), "XclExpRoot::GetPivotTableManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxPTableMgr;
+}
+
+void XclExpRoot::InitializeConvert()
+{
+ mrExpData.mxTabInfo.reset( new XclExpTabInfo( GetRoot() ) );
+ mrExpData.mxAddrConv.reset( new XclExpAddressConverter( GetRoot() ) );
+ mrExpData.mxFmlaComp.reset( new XclExpFormulaCompiler( GetRoot() ) );
+ mrExpData.mxProgress.reset( new XclExpProgressBar( GetRoot() ) );
+
+ GetProgressBar().Initialize();
+}
+
+void XclExpRoot::InitializeGlobals()
+{
+ SetCurrScTab( SCTAB_GLOBAL );
+
+ if( GetBiff() >= EXC_BIFF5 )
+ {
+ mrExpData.mxPalette.reset( new XclExpPalette( GetRoot() ) );
+ mrExpData.mxFontBfr.reset( new XclExpFontBuffer( GetRoot() ) );
+ mrExpData.mxNumFmtBfr.reset( new XclExpNumFmtBuffer( GetRoot() ) );
+ mrExpData.mxXFBfr.reset( new XclExpXFBuffer( GetRoot() ) );
+ mrExpData.mxGlobLinkMgr.reset( new XclExpLinkManager( GetRoot() ) );
+ mrExpData.mxNameMgr.reset( new XclExpNameManager( GetRoot() ) );
+ }
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ mrExpData.mxSst.reset( new XclExpSst );
+ mrExpData.mxObjMgr.reset( new XclExpObjectManager( GetRoot() ) );
+ mrExpData.mxFilterMgr.reset( new XclExpFilterManager( GetRoot() ) );
+ mrExpData.mxPTableMgr.reset( new XclExpPivotTableManager( GetRoot() ) );
+ // BIFF8: only one link manager for all sheets
+ mrExpData.mxLocLinkMgr = mrExpData.mxGlobLinkMgr;
+ }
+
+ GetXFBuffer().Initialize();
+ GetNameManager().Initialize();
+}
+
+void XclExpRoot::InitializeTable( SCTAB nScTab )
+{
+ SetCurrScTab( nScTab );
+ if( GetBiff() == EXC_BIFF5 )
+ {
+ // local link manager per sheet
+ mrExpData.mxLocLinkMgr.reset( new XclExpLinkManager( GetRoot() ) );
+ }
+}
+
+void XclExpRoot::InitializeSave()
+{
+ GetPalette().Finalize();
+ GetXFBuffer().Finalize();
+}
+
+XclExpRecordRef XclExpRoot::CreateRecord( sal_uInt16 nRecId ) const
+{
+ XclExpRecordRef xRec;
+ switch( nRecId )
+ {
+ case EXC_ID_PALETTE: xRec = mrExpData.mxPalette; break;
+ case EXC_ID_FONTLIST: xRec = mrExpData.mxFontBfr; break;
+ case EXC_ID_FORMATLIST: xRec = mrExpData.mxNumFmtBfr; break;
+ case EXC_ID_XFLIST: xRec = mrExpData.mxXFBfr; break;
+ case EXC_ID_SST: xRec = mrExpData.mxSst; break;
+ case EXC_ID_EXTERNSHEET: xRec = GetLocalLinkMgrRef(); break;
+ case EXC_ID_NAME: xRec = mrExpData.mxNameMgr; break;
+ }
+ DBG_ASSERT( xRec.is(), "XclExpRoot::CreateRecord - unknown record ID or missing object" );
+ return xRec;
+}
+
+bool XclExpRoot::IsDocumentEncrypted() const
+{
+ // We need to encrypt the content when the document structure is protected.
+ const ScDocProtection* pDocProt = GetDoc().GetDocProtection();
+ if (pDocProt && pDocProt->isProtected() && pDocProt->isOptionEnabled(ScDocProtection::STRUCTURE))
+ return true;
+
+ if (GetPassword().Len() > 0)
+ // Password is entered directly into the save dialog.
+ return true;
+
+ return false;
+}
+
+String XclExpRoot::GetPassword() const
+{
+ if( SfxItemSet* pItemSet = GetMedium().GetItemSet() )
+ {
+ const SfxPoolItem* pItem = 0;
+ if( pItemSet->GetItemState( SID_PASSWORD, TRUE, &pItem ) == SFX_ITEM_SET )
+ if( const SfxStringItem* pStrItem = dynamic_cast< const SfxStringItem* >( pItem ) )
+ return pStrItem->GetValue();
+ }
+ return String::EmptyString();
+}
+
+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
new file mode 100644
index 000000000000..f828079c8735
--- /dev/null
+++ b/sc/source/filter/excel/xestream.cxx
@@ -0,0 +1,1034 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <utility>
+
+#include <rtl/ustring.hxx>
+#include <sax/fshelper.hxx>
+#include <unotools/streamwrap.hxx>
+
+#include "precompiled_sc.hxx"
+#include "docuno.hxx"
+#include "xestream.hxx"
+#include "xladdress.hxx"
+#include "xlstring.hxx"
+#include "xeroot.hxx"
+#include "xestyle.hxx"
+#include "rangelst.hxx"
+#include "compiler.hxx"
+
+#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;
+using ::com::sun::star::lang::XComponent;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+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 ) :
+ mrStrm( rOutStrm ),
+ mrRoot( rRoot ),
+ mnMaxRecSize( nMaxRecSize ),
+ mnCurrMaxSize( 0 ),
+ mnMaxSliceSize( 0 ),
+ mnHeaderSize( 0 ),
+ mnCurrSize( 0 ),
+ mnSliceSize( 0 ),
+ mnPredictSize( 0 ),
+ mnLastSizePos( 0 ),
+ mbInRec( false )
+{
+ if( mnMaxRecSize == 0 )
+ mnMaxRecSize = (mrRoot.GetBiff() <= EXC_BIFF5) ? EXC_MAXRECSIZE_BIFF5 : EXC_MAXRECSIZE_BIFF8;
+ mnMaxContSize = mnMaxRecSize;
+}
+
+XclExpStream::~XclExpStream()
+{
+ mrStrm.Flush();
+}
+
+void XclExpStream::StartRecord( sal_uInt16 nRecId, sal_Size nRecSize )
+{
+ DBG_ASSERT( !mbInRec, "XclExpStream::StartRecord - another record still open" );
+ DisableEncryption();
+ mnMaxContSize = mnCurrMaxSize = mnMaxRecSize;
+ mnPredictSize = nRecSize;
+ mbInRec = true;
+ InitRecord( nRecId );
+ SetSliceSize( 0 );
+ EnableEncryption();
+}
+
+void XclExpStream::EndRecord()
+{
+ DBG_ASSERT( mbInRec, "XclExpStream::EndRecord - no record open" );
+ DisableEncryption();
+ UpdateRecSize();
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ mbInRec = false;
+}
+
+void XclExpStream::SetSliceSize( sal_uInt16 nSize )
+{
+ mnMaxSliceSize = nSize;
+ mnSliceSize = 0;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
+{
+ PrepareWrite( 1 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
+{
+ PrepareWrite( 1 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
+{
+ PrepareWrite( 2 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
+{
+ PrepareWrite( 2 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( float fValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, fValue);
+ else
+ mrStrm << fValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( double fValue )
+{
+ PrepareWrite( 8 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, fValue);
+ else
+ mrStrm << fValue;
+ return *this;
+}
+
+sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
+{
+ sal_Size nRet = 0;
+ if( pData && (nBytes > 0) )
+ {
+ if( mbInRec )
+ {
+ const sal_uInt8* pBuffer = reinterpret_cast< const sal_uInt8* >( pData );
+ sal_Size nBytesLeft = nBytes;
+ bool bValid = true;
+
+ while( bValid && (nBytesLeft > 0) )
+ {
+ sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
+ sal_Size nWriteRet = nWriteLen;
+ if (mbUseEncrypter && HasValidEncrypter())
+ {
+ DBG_ASSERT(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
+ vector<sal_uInt8> aBytes(nWriteLen);
+ memcpy(&aBytes[0], pBuffer, nWriteLen);
+ mxEncrypter->EncryptBytes(mrStrm, aBytes);
+ // TODO: How do I check if all the bytes have been successfully written ?
+ }
+ else
+ {
+ nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
+ bValid = (nWriteLen == nWriteRet);
+ DBG_ASSERT( bValid, "XclExpStream::Write - stream write error" );
+ }
+ pBuffer += nWriteRet;
+ nRet += nWriteRet;
+ nBytesLeft -= nWriteRet;
+ UpdateSizeVars( nWriteRet );
+ }
+ }
+ else
+ nRet = mrStrm.Write( pData, nBytes );
+ }
+ return nRet;
+}
+
+void XclExpStream::WriteZeroBytes( sal_Size nBytes )
+{
+ if( mbInRec )
+ {
+ sal_Size nBytesLeft = nBytes;
+ while( nBytesLeft > 0 )
+ {
+ sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
+ WriteRawZeroBytes( nWriteLen );
+ nBytesLeft -= nWriteLen;
+ UpdateSizeVars( nWriteLen );
+ }
+ }
+ else
+ WriteRawZeroBytes( nBytes );
+}
+
+void XclExpStream::WriteZeroBytesToRecord( sal_Size nBytes )
+{
+ if (!mbInRec)
+ // not in record.
+ return;
+
+ sal_uInt8 nZero = 0;
+ for (sal_Size i = 0; i < nBytes; ++i)
+ *this << nZero;
+}
+
+sal_Size XclExpStream::CopyFromStream( SvStream& rInStrm, sal_Size nBytes )
+{
+ sal_Size nStrmPos = rInStrm.Tell();
+ rInStrm.Seek( STREAM_SEEK_TO_END );
+ sal_Size nStrmSize = rInStrm.Tell();
+ rInStrm.Seek( nStrmPos );
+
+ sal_Size nBytesLeft = ::std::min( nBytes, nStrmSize - nStrmPos );
+ sal_Size nRet = 0;
+ if( nBytesLeft > 0 )
+ {
+ const sal_Size nMaxBuffer = 4096;
+ sal_uInt8* pBuffer = new sal_uInt8[ ::std::min( nBytesLeft, nMaxBuffer ) ];
+ bool bValid = true;
+
+ while( bValid && (nBytesLeft > 0) )
+ {
+ sal_Size nWriteLen = ::std::min( nBytesLeft, nMaxBuffer );
+ rInStrm.Read( pBuffer, nWriteLen );
+ sal_Size nWriteRet = Write( pBuffer, nWriteLen );
+ bValid = (nWriteLen == nWriteRet);
+ nRet += nWriteRet;
+ nBytesLeft -= nWriteRet;
+ }
+ delete[] pBuffer;
+ }
+ return nRet;
+}
+
+//UNUSED2008-05 void XclExpStream::WriteUnicodeBuffer( const sal_uInt16* pBuffer, sal_Size nChars, sal_uInt8 nFlags )
+//UNUSED2008-05 {
+//UNUSED2008-05 SetSliceSize( 0 );
+//UNUSED2008-05 if( pBuffer && (nChars > 0) )
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_uInt16 nCharLen = (nFlags & EXC_STRF_16BIT) ? 2 : 1;
+//UNUSED2008-05 for( sal_Size nIndex = 0; nIndex < nChars; ++nIndex )
+//UNUSED2008-05 {
+//UNUSED2008-05 if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
+//UNUSED2008-05 {
+//UNUSED2008-05 StartContinue();
+//UNUSED2008-05 // repeat only 16bit flag
+//UNUSED2008-05 operator<<( static_cast< sal_uInt8 >( nFlags & EXC_STRF_16BIT ) );
+//UNUSED2008-05 }
+//UNUSED2008-05 if( nCharLen == 2 )
+//UNUSED2008-05 operator<<( pBuffer[ nIndex ] );
+//UNUSED2008-05 else
+//UNUSED2008-05 operator<<( static_cast< sal_uInt8 >( pBuffer[ nIndex ] ) );
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+void XclExpStream::WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags )
+{
+ SetSliceSize( 0 );
+ nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
+ sal_uInt16 nCharLen = nFlags ? 2 : 1;
+
+ ScfUInt16Vec::const_iterator aEnd = rBuffer.end();
+ for( ScfUInt16Vec::const_iterator aIter = rBuffer.begin(); aIter != aEnd; ++aIter )
+ {
+ if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
+ {
+ StartContinue();
+ operator<<( nFlags );
+ }
+ if( nCharLen == 2 )
+ operator<<( *aIter );
+ else
+ operator<<( static_cast< sal_uInt8 >( *aIter ) );
+ }
+}
+
+//UNUSED2008-05 void XclExpStream::WriteByteStringBuffer( const ByteString& rString, sal_uInt16 nMaxLen )
+//UNUSED2008-05 {
+//UNUSED2008-05 SetSliceSize( 0 );
+//UNUSED2008-05 Write( rString.GetBuffer(), ::std::min< sal_Size >( rString.Len(), nMaxLen ) );
+//UNUSED2008-05 }
+
+// ER: #71367# Xcl has an obscure sense of whether starting a new record or not,
+// and crashes if it encounters the string header at the very end of a record.
+// Thus we add 1 to give some room, seems like they do it that way but with another count (10?)
+void XclExpStream::WriteByteString( const ByteString& rString, sal_uInt16 nMaxLen, bool b16BitCount )
+{
+ SetSliceSize( 0 );
+ sal_Size nLen = ::std::min< sal_Size >( rString.Len(), nMaxLen );
+ if( !b16BitCount )
+ nLen = ::std::min< sal_Size >( nLen, 0xFF );
+
+ sal_uInt16 nLeft = PrepareWrite();
+ sal_uInt16 nLenFieldSize = b16BitCount ? 2 : 1;
+ if( mbInRec && (nLeft <= nLenFieldSize) )
+ StartContinue();
+
+ if( b16BitCount )
+ operator<<( static_cast< sal_uInt16 >( nLen ) );
+ else
+ operator<<( static_cast< sal_uInt8 >( nLen ) );
+ Write( rString.GetBuffer(), nLen );
+}
+
+void XclExpStream::WriteCharBuffer( const ScfUInt8Vec& rBuffer )
+{
+ SetSliceSize( 0 );
+ Write( &rBuffer[ 0 ], rBuffer.size() );
+}
+
+void XclExpStream::SetEncrypter( XclExpEncrypterRef xEncrypter )
+{
+ mxEncrypter = xEncrypter;
+}
+
+bool XclExpStream::HasValidEncrypter() const
+{
+ return mxEncrypter.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" );
+ return mbInRec ? 0 : mrStrm.Seek( nPos );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpStream::InitRecord( sal_uInt16 nRecId )
+{
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ mrStrm << nRecId;
+
+ mnLastSizePos = mrStrm.Tell();
+ mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( mnPredictSize, mnCurrMaxSize ) );
+ mrStrm << mnHeaderSize;
+ mnCurrSize = mnSliceSize = 0;
+}
+
+void XclExpStream::UpdateRecSize()
+{
+ if( mnCurrSize != mnHeaderSize )
+ {
+ mrStrm.Seek( mnLastSizePos );
+ mrStrm << mnCurrSize;
+ }
+}
+
+void XclExpStream::UpdateSizeVars( sal_Size nSize )
+{
+ DBG_ASSERT( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
+ mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
+
+ if( mnMaxSliceSize > 0 )
+ {
+ DBG_ASSERT( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
+ mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
+ if( mnSliceSize >= mnMaxSliceSize )
+ mnSliceSize = 0;
+ }
+}
+
+void XclExpStream::StartContinue()
+{
+ UpdateRecSize();
+ mnCurrMaxSize = mnMaxContSize;
+ mnPredictSize -= mnCurrSize;
+ InitRecord( EXC_ID_CONT );
+}
+
+void XclExpStream::PrepareWrite( sal_uInt16 nSize )
+{
+ if( mbInRec )
+ {
+ if( (mnCurrSize + nSize > mnCurrMaxSize) ||
+ ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
+ StartContinue();
+ UpdateSizeVars( nSize );
+ }
+}
+
+sal_uInt16 XclExpStream::PrepareWrite()
+{
+ sal_uInt16 nRet = 0;
+ if( mbInRec )
+ {
+ if( (mnCurrSize >= mnCurrMaxSize) ||
+ ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
+ StartContinue();
+ UpdateSizeVars( 0 );
+
+ nRet = (mnMaxSliceSize > 0) ? (mnMaxSliceSize - mnSliceSize) : (mnCurrMaxSize - mnCurrSize);
+ }
+ return nRet;
+}
+
+void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
+{
+ const sal_uInt32 nData = 0;
+ sal_Size nBytesLeft = nBytes;
+ while( nBytesLeft >= sizeof( nData ) )
+ {
+ mrStrm << nData;
+ nBytesLeft -= sizeof( nData );
+ }
+ if( nBytesLeft )
+ mrStrm.Write( &nData, nBytesLeft );
+}
+
+// ============================================================================
+
+XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot, 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 = rRoot.GetDefaultPassword();
+ 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.
+ ::msfilter::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;
+ if( sStreamDir )
+ sBuf.appendAscii( sStreamDir );
+ sBuf.appendAscii( sStream );
+ if( nId )
+ sBuf.append( nId );
+ sBuf.appendAscii( ".xml" );
+ return sBuf.makeStringAndClear();
+}
+
+rtl::OString XclXmlUtils::ToOString( const Color& rColor )
+{
+ char buf[9];
+ sprintf( buf, "%.2X%.2X%.2X%.2X", rColor.GetTransparency(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
+ buf[8] = '\0';
+ return OString( buf );
+}
+
+rtl::OString XclXmlUtils::ToOString( const ::rtl::OUString& s )
+{
+ return OUStringToOString( s, RTL_TEXTENCODING_UTF8 );
+}
+
+rtl::OString XclXmlUtils::ToOString( const String& s )
+{
+ return rtl::OString( s.GetBuffer(), s.Len(), RTL_TEXTENCODING_UTF8 );
+}
+
+rtl::OString XclXmlUtils::ToOString( const ScAddress& rAddress )
+{
+ String sAddress;
+ rAddress.Format( sAddress, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) );
+ return ToOString( sAddress );
+}
+
+rtl::OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer )
+{
+ const sal_uInt16* pBuffer = &rBuffer [0];
+ return ::rtl::OString( pBuffer, rBuffer.size(), RTL_TEXTENCODING_UTF8 );
+}
+
+rtl::OString XclXmlUtils::ToOString( const ScRange& rRange )
+{
+ String sRange;
+ rRange.Format( sRange, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) );
+ return ToOString( sRange );
+}
+
+rtl::OString XclXmlUtils::ToOString( const ScRangeList& rRangeList )
+{
+ String s;
+ rRangeList.Format( s, SCA_VALID, NULL, FormulaGrammar::CONV_XL_A1, ' ' );
+ return ToOString( s );
+}
+
+static ScAddress lcl_ToAddress( const XclAddress& rAddress )
+{
+ ScAddress aAddress;
+
+ // For some reason, ScRange::Format() returns omits row numbers if
+ // the row is >= MAXROW or the column is >= MAXCOL, and Excel doesn't
+ // like "A:IV" (i.e. no row numbers). Prevent this.
+ aAddress.SetRow( std::min<sal_Int32>( rAddress.mnRow, MAXROW-1 ) );
+ aAddress.SetCol( static_cast<sal_Int16>(std::min<sal_Int32>( rAddress.mnCol, MAXCOL-1 )) );
+
+ return aAddress;
+}
+
+rtl::OString XclXmlUtils::ToOString( const XclAddress& rAddress )
+{
+ return ToOString( lcl_ToAddress( rAddress ) );
+}
+
+rtl::OString XclXmlUtils::ToOString( const XclExpString& s )
+{
+ DBG_ASSERT( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
+ return ToOString( s.GetUnicodeBuffer() );
+}
+
+static ScRange lcl_ToRange( const XclRange& rRange )
+{
+ ScRange aRange;
+
+ aRange.aStart = lcl_ToAddress( rRange.maFirst );
+ aRange.aEnd = lcl_ToAddress( rRange.maLast );
+
+ return aRange;
+}
+
+rtl::OString XclXmlUtils::ToOString( const XclRangeList& rRanges )
+{
+ ScRangeList aRanges;
+ for( XclRangeList::const_iterator i = rRanges.begin(), end = rRanges.end();
+ i != end; ++i )
+ {
+ aRanges.Append( lcl_ToRange( *i ) );
+ }
+ return ToOString( aRanges );
+}
+
+OUString XclXmlUtils::ToOUString( const char* s )
+{
+ return OUString( s, (sal_Int32) strlen( s ), RTL_TEXTENCODING_ASCII_US );
+}
+
+OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sal_Int32 nLength )
+{
+ if( nLength == -1 )
+ nLength = rBuf.size();
+
+ return OUString( &rBuf[nStart], nLength );
+}
+
+OUString XclXmlUtils::ToOUString( const String& s )
+{
+ return OUString( s.GetBuffer(), s.Len() );
+}
+
+rtl::OUString XclXmlUtils::ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray )
+{
+ ScCompiler aCompiler( &rDocument, rAddress, *pTokenArray);
+ aCompiler.SetGrammar(FormulaGrammar::GRAM_NATIVE_XL_A1);
+ String s;
+ aCompiler.CreateStringFromTokenArray( s );
+ return ToOUString( s );
+}
+
+OUString XclXmlUtils::ToOUString( const XclExpString& s )
+{
+ DBG_ASSERT( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
+ return ToOUString( s.GetUnicodeBuffer() );
+}
+
+const char* XclXmlUtils::ToPsz( bool b )
+{
+ return b ? "true" : "false";
+}
+
+// ============================================================================
+
+XclExpXmlStream::XclExpXmlStream( const Reference< XMultiServiceFactory >& rSMgr, SvStream& rStrm, const XclExpRoot& rRoot )
+ : XmlFilterBase( rSMgr )
+ , mrRoot( rRoot )
+{
+ Sequence< PropertyValue > aArgs( 1 );
+ const OUString sStream( RTL_CONSTASCII_USTRINGPARAM( "StreamForOutput" ) );
+ aArgs[0].Name = sStream;
+ aArgs[0].Value <<= Reference< XStream > ( new OStreamWrapper( rStrm ) );
+
+ XServiceInfo* pInfo = rRoot.GetDocModelObj();
+ Reference< XComponent > aComponent( pInfo, UNO_QUERY );
+ setSourceDocument( aComponent );
+ filter( aArgs );
+
+ PushStream( CreateOutputStream(
+ OUString::createFromAscii( "xl/workbook.xml" ),
+ OUString::createFromAscii( "xl/workbook.xml" ),
+ Reference< XOutputStream >(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) );
+}
+
+XclExpXmlStream::~XclExpXmlStream()
+{
+}
+
+sax_fastparser::FSHelperPtr& XclExpXmlStream::GetCurrentStream()
+{
+ DBG_ASSERT( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
+ return maStreams.top();
+}
+
+void XclExpXmlStream::PushStream( sax_fastparser::FSHelperPtr aStream )
+{
+ maStreams.push( aStream );
+}
+
+void XclExpXmlStream::PopStream()
+{
+ DBG_ASSERT( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
+ maStreams.pop();
+}
+
+OUString XclExpXmlStream::GetIdForPath( const OUString& sPath )
+{
+ if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
+ return OUString();
+ return maOpenedStreamMap[ sPath ].first;
+}
+
+sax_fastparser::FSHelperPtr XclExpXmlStream::GetStreamForPath( const OUString& sPath )
+{
+ if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
+ return sax_fastparser::FSHelperPtr();
+ return maOpenedStreamMap[ sPath ].second;
+}
+
+sax_fastparser::FSHelperPtr& XclExpXmlStream::WriteAttributes( sal_Int32 nAttribute, ... )
+{
+ sax_fastparser::FSHelperPtr& rStream = GetCurrentStream();
+
+ va_list args;
+ va_start( args, nAttribute );
+ do {
+ const char* pValue = va_arg( args, const char* );
+ if( pValue )
+ {
+ rStream->write( " " )
+ ->writeId( nAttribute )
+ ->write( "=\"" )
+ ->writeEscaped( pValue )
+ ->write( "\"" );
+ }
+
+ nAttribute = va_arg( args, sal_Int32 );
+ if( nAttribute == FSEND )
+ break;
+ } while( true );
+ va_end( args );
+
+ return rStream;
+}
+
+static void lcl_WriteValue( sax_fastparser::FSHelperPtr& rStream, sal_Int32 nElement, const char* pValue )
+{
+ if( !pValue )
+ return;
+ rStream->singleElement( nElement,
+ XML_val, pValue,
+ FSEND );
+}
+
+static const char* lcl_GetUnderlineStyle( FontUnderline eUnderline, bool& bHaveUnderline )
+{
+ bHaveUnderline = true;
+ switch( eUnderline )
+ {
+ // OOXTODO: doubleAccounting, singleAccounting
+ // OOXTODO: what should be done with the other FontUnderline values?
+ case UNDERLINE_SINGLE: return "single";
+ case UNDERLINE_DOUBLE: return "double";
+ case UNDERLINE_NONE:
+ default: bHaveUnderline = false; return "none";
+ }
+}
+
+static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
+{
+ bHaveAlignment = true;
+ switch( eEscapement )
+ {
+ case SVX_ESCAPEMENT_SUPERSCRIPT: return "superscript";
+ case SVX_ESCAPEMENT_SUBSCRIPT: return "subscript";
+ case SVX_ESCAPEMENT_OFF:
+ default: bHaveAlignment = false; return "baseline";
+ }
+}
+
+sax_fastparser::FSHelperPtr& XclExpXmlStream::WriteFontData( const XclFontData& rFontData, sal_Int32 nFontId )
+{
+ bool bHaveUnderline, bHaveVertAlign;
+ const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
+ const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
+
+ sax_fastparser::FSHelperPtr& rStream = GetCurrentStream();
+
+ lcl_WriteValue( rStream, nFontId, XclXmlUtils::ToOString( rFontData.maName ).getStr() );
+ lcl_WriteValue( rStream, XML_charset, rFontData.mnCharSet != 0 ? OString::valueOf( (sal_Int32) rFontData.mnCharSet ).getStr() : NULL );
+ lcl_WriteValue( rStream, XML_family, OString::valueOf( (sal_Int32) rFontData.mnFamily ).getStr() );
+ lcl_WriteValue( rStream, XML_b, rFontData.mnWeight > 400 ? XclXmlUtils::ToPsz( rFontData.mnWeight > 400 ) : NULL );
+ lcl_WriteValue( rStream, XML_i, rFontData.mbItalic ? XclXmlUtils::ToPsz( rFontData.mbItalic ) : NULL );
+ lcl_WriteValue( rStream, XML_strike, rFontData.mbStrikeout ? XclXmlUtils::ToPsz( rFontData.mbStrikeout ) : NULL );
+ lcl_WriteValue( rStream, XML_outline, rFontData.mbOutline ? XclXmlUtils::ToPsz( rFontData.mbOutline ) : NULL );
+ lcl_WriteValue( rStream, XML_shadow, rFontData.mbShadow ? XclXmlUtils::ToPsz( rFontData.mbShadow ) : NULL );
+ // OOXTODO: lcl_WriteValue( rStream, XML_condense, ); // mac compatibility setting
+ // OOXTODO: lcl_WriteValue( rStream, XML_extend, ); // compatibility setting
+ if( rFontData.maColor != Color( 0xFF, 0xFF, 0xFF, 0xFF ) )
+ rStream->singleElement( XML_color,
+ // OOXTODO: XML_auto, bool
+ // OOXTODO: XML_indexed, uint
+ XML_rgb, XclXmlUtils::ToOString( rFontData.maColor ).getStr(),
+ // OOXTODO: XML_theme, index into <clrScheme/>
+ // OOXTODO: XML_tint, double
+ FSEND );
+ lcl_WriteValue( rStream, XML_sz, OString::valueOf( (double) (rFontData.mnHeight / 20.0) ) ); // Twips->Pt
+ lcl_WriteValue( rStream, XML_u, bHaveUnderline ? pUnderline : NULL );
+ lcl_WriteValue( rStream, XML_vertAlign, bHaveVertAlign ? pVertAlign : NULL );
+
+ return rStream;
+}
+
+sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
+ const OUString& sFullStream,
+ const OUString& sRelativeStream,
+ const Reference< XOutputStream >& xParentRelation,
+ const char* sContentType,
+ const char* sRelationshipType,
+ ::rtl::OUString* pRelationshipId )
+{
+ OUString sRelationshipId;
+ if (xParentRelation.is())
+ sRelationshipId = addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
+ else
+ sRelationshipId = addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
+
+ if( pRelationshipId )
+ *pRelationshipId = sRelationshipId;
+
+ sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
+
+ maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
+
+ return p;
+}
+
+bool XclExpXmlStream::importDocument() throw()
+{
+ return false;
+}
+
+oox::vml::Drawing* XclExpXmlStream::getVmlDrawing()
+{
+ return 0;
+}
+
+const oox::drawingml::Theme* XclExpXmlStream::getCurrentTheme() const
+{
+ return 0;
+}
+
+const oox::drawingml::table::TableStyleListPtr XclExpXmlStream::getTableStyles()
+{
+ return oox::drawingml::table::TableStyleListPtr();
+}
+
+oox::drawingml::chart::ChartConverter& XclExpXmlStream::getChartConverter()
+{
+ // DO NOT CALL
+ return * (oox::drawingml::chart::ChartConverter*) NULL;
+}
+
+bool XclExpXmlStream::exportDocument() throw()
+{
+ return false;
+}
+
+::rtl::OUString XclExpXmlStream::implGetImplementationName() const
+{
+ return CREATE_OUSTRING( "TODO" );
+}
+
+void XclExpXmlStream::Trace( const char* format, ...)
+{
+ va_list ap;
+ va_start( ap, format );
+ vfprintf( stderr, format, ap );
+ va_end( ap );
+}
+
diff --git a/sc/source/filter/excel/xestring.cxx b/sc/source/filter/excel/xestring.cxx
new file mode 100644
index 000000000000..cd0b083aa208
--- /dev/null
+++ b/sc/source/filter/excel/xestring.cxx
@@ -0,0 +1,656 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <algorithm>
+#include <stdio.h>
+#include "xestream.hxx"
+#include "xlstyle.hxx"
+#include "xestyle.hxx"
+#include "xestring.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+// compare vectors
+
+/** Compares two vectors.
+ @return A negative value, if rLeft<rRight; or a positive value, if rLeft>rRight;
+ or 0, if rLeft==rRight. */
+template< typename Type >
+int lclCompareVectors( const ::std::vector< Type >& rLeft, const ::std::vector< Type >& rRight )
+{
+ int nResult = 0;
+
+ // 1st: compare all elements of the vectors
+ typedef typename ::std::vector< Type >::const_iterator CIT;
+ CIT aEndL = rLeft.end(), aEndR = rRight.end();
+ for( CIT aItL = rLeft.begin(), aItR = rRight.begin(); !nResult && (aItL != aEndL) && (aItR != aEndR); ++aItL, ++aItR )
+ nResult = static_cast< int >( *aItL ) - static_cast< int >( *aItR );
+
+ // 2nd: no differences found so far -> compare the vector sizes. Shorter vector is less
+ if( !nResult )
+ nResult = static_cast< int >( rLeft.size() ) - static_cast< int >( rRight.size() );
+
+ return nResult;
+}
+
+// hashing helpers
+
+/** Base class for value hashers.
+ @descr These function objects are used to hash any value to a sal_uInt32 value. */
+template< typename Type >
+struct XclHasher : public ::std::unary_function< Type, sal_uInt32 > {};
+
+template< typename Type >
+struct XclDirectHasher : public XclHasher< Type >
+{
+ inline sal_uInt32 operator()( Type nVal ) const { return nVal; }
+};
+
+struct XclFormatRunHasher : public XclHasher< const XclFormatRun& >
+{
+ inline sal_uInt32 operator()( const XclFormatRun& rRun ) const
+ { return (rRun.mnChar << 8) ^ rRun.mnFontIdx; }
+};
+
+/** Calculates a hash value from a vector.
+ @descr Uses the passed hasher function object to calculate hash values from
+ all vector elements. */
+template< typename Type, typename ValueHasher >
+sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec, const ValueHasher& rHasher )
+{
+ sal_uInt32 nHash = rVec.size();
+ typedef typename ::std::vector< Type >::const_iterator CIT;
+ for( CIT aIt = rVec.begin(), aEnd = rVec.end(); aIt != aEnd; ++aIt )
+ (nHash *= 31) += rHasher( *aIt );
+ return static_cast< sal_uInt16 >( nHash ^ (nHash >> 16) );
+}
+
+/** Calculates a hash value from a vector. Uses XclDirectHasher to hash the vector elements. */
+template< typename Type >
+inline sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec )
+{
+ return lclHashVector( rVec, XclDirectHasher< Type >() );
+}
+
+} // namespace
+
+// constructors ---------------------------------------------------------------
+
+XclExpString::XclExpString( XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Init( 0, nFlags, nMaxLen, true );
+}
+
+XclExpString::XclExpString( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Assign( rString, nFlags, nMaxLen );
+}
+
+XclExpString::XclExpString( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Assign( rString, nFlags, nMaxLen );
+}
+
+//UNUSED2008-05 XclExpString::XclExpString(
+//UNUSED2008-05 const String& rString, const XclFormatRunVec& rFormats,
+//UNUSED2008-05 XclStrFlags nFlags, sal_uInt16 nMaxLen )
+//UNUSED2008-05 {
+//UNUSED2008-05 Assign( rString, rFormats, nFlags, nMaxLen );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 XclExpString::XclExpString(
+//UNUSED2008-05 const OUString& rString, const XclFormatRunVec& rFormats,
+//UNUSED2008-05 XclStrFlags nFlags, sal_uInt16 nMaxLen )
+//UNUSED2008-05 {
+//UNUSED2008-05 Assign( rString, rFormats, nFlags, nMaxLen );
+//UNUSED2008-05 }
+
+// assign ---------------------------------------------------------------------
+
+void XclExpString::Assign( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Build( rString.GetBuffer(), rString.Len(), nFlags, nMaxLen );
+}
+
+void XclExpString::Assign(
+ const String& rString, const XclFormatRunVec& rFormats,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Assign( rString, nFlags, nMaxLen );
+ SetFormats( rFormats );
+}
+
+void XclExpString::Assign( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Build( rString.getStr(), rString.getLength(), nFlags, nMaxLen );
+}
+
+void XclExpString::Assign(
+ const OUString& rString, const XclFormatRunVec& rFormats,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Assign( rString, nFlags, nMaxLen );
+ SetFormats( rFormats );
+}
+
+void XclExpString::Assign( sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Build( &cChar, 1, nFlags, nMaxLen );
+}
+
+void XclExpString::AssignByte(
+ const String& rString, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ ByteString aByteStr( rString, eTextEnc ); // length may differ from length of rString
+ Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
+}
+
+//UNUSED2008-05 void XclExpString::AssignByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+//UNUSED2008-05 {
+//UNUSED2008-05 if( !cChar )
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_Char cByteChar = 0;
+//UNUSED2008-05 Build( &cByteChar, 1, nFlags, nMaxLen );
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 ByteString aByteStr( &cChar, 1, eTextEnc ); // length may be >1
+//UNUSED2008-05 Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+// append ---------------------------------------------------------------------
+
+void XclExpString::Append( const String& rString )
+{
+ BuildAppend( rString.GetBuffer(), rString.Len() );
+}
+
+//UNUSED2008-05 void XclExpString::Append( const ::rtl::OUString& rString )
+//UNUSED2008-05 {
+//UNUSED2008-05 BuildAppend( rString.getStr(), rString.getLength() );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void XclExpString::Append( sal_Unicode cChar )
+//UNUSED2008-05 {
+//UNUSED2008-05 BuildAppend( &cChar, 1 );
+//UNUSED2008-05 }
+
+void XclExpString::AppendByte( const String& rString, rtl_TextEncoding eTextEnc )
+{
+ if( rString.Len() > 0 )
+ {
+ ByteString aByteStr( rString, eTextEnc ); // length may differ from length of rString
+ BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
+ }
+}
+
+void XclExpString::AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc )
+{
+ if( !cChar )
+ {
+ sal_Char cByteChar = 0;
+ BuildAppend( &cByteChar, 1 );
+ }
+ else
+ {
+ ByteString aByteStr( &cChar, 1, eTextEnc ); // length may be >1
+ BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
+ }
+}
+
+// formatting runs ------------------------------------------------------------
+
+void XclExpString::SetFormats( const XclFormatRunVec& rFormats )
+{
+ maFormats = rFormats;
+#ifdef DBG_UTIL
+ if( IsRich() )
+ {
+ XclFormatRunVec::const_iterator aCurr = maFormats.begin();
+ XclFormatRunVec::const_iterator aPrev = aCurr;
+ XclFormatRunVec::const_iterator aEnd = maFormats.end();
+ for( ++aCurr; aCurr != aEnd; ++aCurr, ++aPrev )
+ DBG_ASSERT( aPrev->mnChar < aCurr->mnChar, "XclExpString::SetFormats - invalid char order" );
+ DBG_ASSERT( aPrev->mnChar <= mnLen, "XclExpString::SetFormats - invalid char index" );
+ }
+#endif
+ LimitFormatCount( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
+}
+
+void XclExpString::AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate )
+{
+ DBG_ASSERT( maFormats.empty() || (maFormats.back().mnChar < nChar), "XclExpString::AppendFormat - invalid char index" );
+ size_t nMaxSize = static_cast< size_t >( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
+ if( maFormats.empty() || ((maFormats.size() < nMaxSize) && (!bDropDuplicate || (maFormats.back().mnFontIdx != nFontIdx))) )
+ maFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
+}
+
+void XclExpString::AppendTrailingFormat( sal_uInt16 nFontIdx )
+{
+ AppendFormat( mnLen, nFontIdx, false );
+}
+
+void XclExpString::LimitFormatCount( sal_uInt16 nMaxCount )
+{
+ if( maFormats.size() > nMaxCount )
+ maFormats.erase( maFormats.begin() + nMaxCount, maFormats.end() );
+}
+
+sal_uInt16 XclExpString::RemoveLeadingFont()
+{
+ sal_uInt16 nFontIdx = EXC_FONT_NOTFOUND;
+ if( !maFormats.empty() && (maFormats.front().mnChar == 0) )
+ {
+ nFontIdx = maFormats.front().mnFontIdx;
+ maFormats.erase( maFormats.begin() );
+ }
+ return nFontIdx;
+}
+
+bool XclExpString::IsEqual( const XclExpString& rCmp ) const
+{
+ return
+ (mnLen == rCmp.mnLen) &&
+ (mbIsBiff8 == rCmp.mbIsBiff8) &&
+ (mbIsUnicode == rCmp.mbIsUnicode) &&
+ (mbWrapped == rCmp.mbWrapped) &&
+ (
+ ( mbIsBiff8 && (maUniBuffer == rCmp.maUniBuffer)) ||
+ (!mbIsBiff8 && (maCharBuffer == rCmp.maCharBuffer))
+ ) &&
+ (maFormats == rCmp.maFormats);
+}
+
+bool XclExpString::IsLessThan( const XclExpString& rCmp ) const
+{
+ int nResult = mbIsBiff8 ?
+ lclCompareVectors( maUniBuffer, rCmp.maUniBuffer ) :
+ lclCompareVectors( maCharBuffer, rCmp.maCharBuffer );
+ return (nResult != 0) ? (nResult < 0) : (maFormats < rCmp.maFormats);
+}
+
+// get data -------------------------------------------------------------------
+
+sal_uInt16 XclExpString::GetFormatsCount() const
+{
+ return static_cast< sal_uInt16 >( maFormats.size() );
+}
+
+sal_uInt8 XclExpString::GetFlagField() const
+{
+ return (mbIsUnicode ? EXC_STRF_16BIT : 0) | (IsWriteFormats() ? EXC_STRF_RICH : 0);
+}
+
+sal_uInt16 XclExpString::GetHeaderSize() const
+{
+ return
+ (mb8BitLen ? 1 : 2) + // length field
+ (IsWriteFlags() ? 1 : 0) + // flag field
+ (IsWriteFormats() ? 2 : 0); // richtext formattting count
+}
+
+sal_Size XclExpString::GetBufferSize() const
+{
+ return mnLen * (mbIsUnicode ? 2 : 1);
+}
+
+sal_Size XclExpString::GetSize() const
+{
+ return
+ GetHeaderSize() + // header
+ GetBufferSize() + // character buffer
+ (IsWriteFormats() ? (4 * GetFormatsCount()) : 0); // richtext formattting
+}
+
+sal_uInt16 XclExpString::GetChar( sal_uInt16 nCharIdx ) const
+{
+ DBG_ASSERT( nCharIdx < Len(), "XclExpString::GetChar - invalid character index" );
+ return static_cast< sal_uInt16 >( mbIsBiff8 ? maUniBuffer[ nCharIdx ] : maCharBuffer[ nCharIdx ] );
+}
+
+sal_uInt16 XclExpString::GetHash() const
+{
+ return
+ (mbIsBiff8 ? lclHashVector( maUniBuffer ) : lclHashVector( maCharBuffer )) ^
+ lclHashVector( maFormats, XclFormatRunHasher() );
+}
+
+// streaming ------------------------------------------------------------------
+
+void XclExpString::WriteLenField( XclExpStream& rStrm ) const
+{
+ if( mb8BitLen )
+ rStrm << static_cast< sal_uInt8 >( mnLen );
+ else
+ rStrm << mnLen;
+}
+
+void XclExpString::WriteFlagField( XclExpStream& rStrm ) const
+{
+ if( mbIsBiff8 )
+ {
+ PrepareWrite( rStrm, 1 );
+ rStrm << GetFlagField();
+ rStrm.SetSliceSize( 0 );
+ }
+}
+
+void XclExpString::WriteHeader( XclExpStream& rStrm ) const
+{
+ DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeader - string too long" );
+ PrepareWrite( rStrm, GetHeaderSize() );
+ // length
+ WriteLenField( rStrm );
+ // flag field
+ if( IsWriteFlags() )
+ rStrm << GetFlagField();
+ // format run count
+ if( IsWriteFormats() )
+ rStrm << GetFormatsCount();
+ rStrm.SetSliceSize( 0 );
+}
+
+void XclExpString::WriteBuffer( XclExpStream& rStrm ) const
+{
+ if( mbIsBiff8 )
+ rStrm.WriteUnicodeBuffer( maUniBuffer, GetFlagField() );
+ else
+ rStrm.WriteCharBuffer( maCharBuffer );
+}
+
+void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
+{
+ if( IsRich() )
+ {
+ XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
+ if( mbIsBiff8 )
+ {
+ if( bWriteSize )
+ rStrm << GetFormatsCount();
+ rStrm.SetSliceSize( 4 );
+ for( ; aIt != aEnd; ++aIt )
+ rStrm << aIt->mnChar << aIt->mnFontIdx;
+ }
+ else
+ {
+ if( bWriteSize )
+ rStrm << static_cast< sal_uInt8 >( GetFormatsCount() );
+ rStrm.SetSliceSize( 2 );
+ for( ; aIt != aEnd; ++aIt )
+ rStrm << static_cast< sal_uInt8 >( aIt->mnChar ) << static_cast< sal_uInt8 >( aIt->mnFontIdx );
+ }
+ rStrm.SetSliceSize( 0 );
+ }
+}
+
+void XclExpString::Write( XclExpStream& rStrm ) const
+{
+ if (!mbSkipHeader)
+ WriteHeader( rStrm );
+ WriteBuffer( rStrm );
+ if( IsWriteFormats() ) // only in BIFF8 included in string
+ WriteFormats( rStrm );
+}
+
+void XclExpString::WriteHeaderToMem( sal_uInt8* pnMem ) const
+{
+ DBG_ASSERT( pnMem, "XclExpString::WriteHeaderToMem - no memory to write to" );
+ DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeaderToMem - string too long" );
+ DBG_ASSERT( !IsWriteFormats(), "XclExpString::WriteHeaderToMem - formatted strings not supported" );
+ // length
+ if( mb8BitLen )
+ {
+ *pnMem = static_cast< sal_uInt8 >( mnLen );
+ ++pnMem;
+ }
+ else
+ {
+ ShortToSVBT16( mnLen, pnMem );
+ pnMem += 2;
+ }
+ // flag field
+ if( IsWriteFlags() )
+ *pnMem = GetFlagField();
+}
+
+void XclExpString::WriteBufferToMem( sal_uInt8* pnMem ) const
+{
+ DBG_ASSERT( pnMem, "XclExpString::WriteBufferToMem - no memory to write to" );
+ if( !IsEmpty() )
+ {
+ if( mbIsBiff8 )
+ {
+ for( ScfUInt16Vec::const_iterator aIt = maUniBuffer.begin(), aEnd = maUniBuffer.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt16 nChar = *aIt;
+ *pnMem = static_cast< sal_uInt8 >( nChar );
+ ++pnMem;
+ if( mbIsUnicode )
+ {
+ *pnMem = static_cast< sal_uInt8 >( nChar >> 8 );
+ ++pnMem;
+ }
+ }
+ }
+ else
+ memcpy( pnMem, &maCharBuffer[ 0 ], mnLen );
+ }
+}
+
+void XclExpString::WriteToMem( sal_uInt8* pnMem ) const
+{
+ WriteHeaderToMem( pnMem );
+ WriteBufferToMem( pnMem + GetHeaderSize() );
+}
+
+static sal_uInt16 lcl_WriteRun( XclExpXmlStream& rStrm, const ScfUInt16Vec& rBuffer, sal_uInt16 nStart, sal_Int32 nLength, const XclExpFont* pFont )
+{
+ if( nLength == 0 )
+ return nStart;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+
+ rWorksheet->startElement( XML_r, FSEND );
+ if( pFont )
+ {
+ const XclFontData& rFontData = pFont->GetFontData();
+ rWorksheet->startElement( XML_rPr, FSEND );
+ rStrm.WriteFontData( rFontData, XML_rFont );
+ rWorksheet->endElement( XML_rPr );
+ }
+ rWorksheet->startElement( XML_t,
+ FSNS( XML_xml, XML_space ), "preserve",
+ FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( rBuffer, nStart, nLength ) );
+ rWorksheet->endElement( XML_t );
+ rWorksheet->endElement( XML_r );
+ return static_cast<sal_uInt16>(nStart + nLength);
+}
+
+void XclExpString::WriteXml( XclExpXmlStream& rStrm ) const
+{
+ sax_fastparser::FSHelperPtr rWorksheet = rStrm.GetCurrentStream();
+
+ if( !IsWriteFormats() )
+ {
+ rWorksheet->startElement( XML_t, FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *this ) );
+ rWorksheet->endElement( XML_t );
+ }
+ else
+ {
+ XclExpFontBuffer& rFonts = rStrm.GetRoot().GetFontBuffer();
+ XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
+
+ sal_uInt16 nStart = 0;
+ const XclExpFont* pFont = NULL;
+ for ( ; aIt != aEnd; ++aIt )
+ {
+ nStart = lcl_WriteRun( rStrm, GetUnicodeBuffer(),
+ nStart, aIt->mnChar-nStart, pFont );
+ pFont = rFonts.GetFont( aIt->mnFontIdx );
+ }
+ lcl_WriteRun( rStrm, GetUnicodeBuffer(),
+ nStart, GetUnicodeBuffer().size() - nStart, pFont );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclExpString::IsWriteFlags() const
+{
+ return mbIsBiff8 && (!IsEmpty() || !mbSmartFlags);
+}
+
+bool XclExpString::IsWriteFormats() const
+{
+ return mbIsBiff8 && !mbSkipFormats && IsRich();
+}
+
+void XclExpString::SetStrLen( sal_Int32 nNewLen )
+{
+ sal_uInt16 nAllowedLen = (mb8BitLen && (mnMaxLen > 255)) ? 255 : mnMaxLen;
+ mnLen = limit_cast< sal_uInt16 >( nNewLen, 0, nAllowedLen );
+}
+
+void XclExpString::CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
+{
+ DBG_ASSERT( maUniBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
+ "XclExpString::CharsToBuffer - char buffer invalid" );
+ ScfUInt16Vec::iterator aBeg = maUniBuffer.begin() + nBegin;
+ ScfUInt16Vec::iterator aEnd = aBeg + nLen;
+ const sal_Unicode* pcSrcChar = pcSource;
+ for( ScfUInt16Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
+ {
+ *aIt = static_cast< sal_uInt16 >( *pcSrcChar );
+ if( *aIt & 0xFF00 )
+ mbIsUnicode = true;
+ }
+ if( !mbWrapped )
+ mbWrapped = ::std::find( aBeg, aEnd, EXC_LF ) != aEnd;
+}
+
+void XclExpString::CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
+{
+ DBG_ASSERT( maCharBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
+ "XclExpString::CharsToBuffer - char buffer invalid" );
+ ScfUInt8Vec::iterator aBeg = maCharBuffer.begin() + nBegin;
+ ScfUInt8Vec::iterator aEnd = aBeg + nLen;
+ const sal_Char* pcSrcChar = pcSource;
+ for( ScfUInt8Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
+ *aIt = static_cast< sal_uInt8 >( *pcSrcChar );
+ mbIsUnicode = false;
+ if( !mbWrapped )
+ mbWrapped = ::std::find( aBeg, aEnd, EXC_LF_C ) != aEnd;
+}
+
+void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 )
+{
+ mbIsBiff8 = bBiff8;
+ mbIsUnicode = bBiff8 && ::get_flag( nFlags, EXC_STR_FORCEUNICODE );
+ mb8BitLen = ::get_flag( nFlags, EXC_STR_8BITLENGTH );
+ mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
+ mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
+ mbWrapped = false;
+ mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
+ mnMaxLen = nMaxLen;
+ SetStrLen( nCurrLen );
+
+ maFormats.clear();
+ if( mbIsBiff8 )
+ {
+ maCharBuffer.clear();
+ maUniBuffer.resize( mnLen );
+ }
+ else
+ {
+ maUniBuffer.clear();
+ maCharBuffer.resize( mnLen );
+ }
+}
+
+void XclExpString::Build( const sal_Unicode* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Init( nCurrLen, nFlags, nMaxLen, true );
+ CharsToBuffer( pcSource, 0, mnLen );
+}
+
+void XclExpString::Build( const sal_Char* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Init( nCurrLen, nFlags, nMaxLen, false );
+ CharsToBuffer( pcSource, 0, mnLen );
+}
+
+void XclExpString::InitAppend( sal_Int32 nAddLen )
+{
+ SetStrLen( static_cast< sal_Int32 >( mnLen ) + nAddLen );
+ if( mbIsBiff8 )
+ maUniBuffer.resize( mnLen );
+ else
+ maCharBuffer.resize( mnLen );
+}
+
+void XclExpString::BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen )
+{
+ DBG_ASSERT( mbIsBiff8, "XclExpString::BuildAppend - must not be called at byte strings" );
+ if( mbIsBiff8 )
+ {
+ sal_uInt16 nOldLen = mnLen;
+ InitAppend( nAddLen );
+ CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
+ }
+}
+
+void XclExpString::BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen )
+{
+ DBG_ASSERT( !mbIsBiff8, "XclExpString::BuildAppend - must not be called at unicode strings" );
+ if( !mbIsBiff8 )
+ {
+ sal_uInt16 nOldLen = mnLen;
+ InitAppend( nAddLen );
+ CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
+ }
+}
+
+void XclExpString::PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const
+{
+ rStrm.SetSliceSize( nBytes + (mbIsUnicode ? 2 : 1) );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx
new file mode 100644
index 000000000000..ccebe9a4280f
--- /dev/null
+++ b/sc/source/filter/excel/xestyle.cxx
@@ -0,0 +1,2903 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xestyle.hxx"
+
+#include <algorithm>
+#include <iterator>
+#include <set>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <vcl/font.hxx>
+#include <svl/zformat.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/printer.hxx>
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/escpitem.hxx>
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
+#include "xestring.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+
+// PALETTE record - color information =========================================
+
+namespace {
+
+sal_uInt32 lclGetWeighting( XclExpColorType eType )
+{
+ switch( eType )
+ {
+ case EXC_COLOR_CHARTLINE: return 1;
+ case EXC_COLOR_CELLBORDER:
+ case EXC_COLOR_CHARTAREA: return 2;
+ case EXC_COLOR_CELLTEXT:
+ case EXC_COLOR_CHARTTEXT:
+ case EXC_COLOR_CTRLTEXT: return 10;
+ case EXC_COLOR_TABBG:
+ case EXC_COLOR_CELLAREA: return 20;
+ case EXC_COLOR_GRID: return 50;
+ default: DBG_ERRORFILE( "lclGetWeighting - unknown color type" );
+ }
+ return 1;
+}
+
+sal_Int32 lclGetColorDistance( const Color& rColor1, const Color& rColor2 )
+{
+ sal_Int32 nDist = rColor1.GetRed() - rColor2.GetRed();
+ nDist *= nDist * 77;
+ sal_Int32 nDummy = rColor1.GetGreen() - rColor2.GetGreen();
+ nDist += nDummy * nDummy * 151;
+ nDummy = rColor1.GetBlue() - rColor2.GetBlue();
+ nDist += nDummy * nDummy * 28;
+ return nDist;
+}
+
+sal_uInt8 lclGetMergedColorComp( sal_uInt8 nComp1, sal_uInt32 nWeight1, sal_uInt8 nComp2, sal_uInt32 nWeight2 )
+{
+ sal_uInt8 nComp1Dist = ::std::min< sal_uInt8 >( nComp1, 0xFF - nComp1 );
+ sal_uInt8 nComp2Dist = ::std::min< sal_uInt8 >( nComp2, 0xFF - nComp2 );
+ if( nComp1Dist != nComp2Dist )
+ {
+ /* #i36945# One of the passed RGB components is nearer at the limits (0x00 or 0xFF).
+ Increase its weighting to prevent fading of the colors during reduction. */
+ const sal_uInt8& rnCompNearer = (nComp1Dist < nComp2Dist) ? nComp1 : nComp2;
+ sal_uInt32& rnWeight = (nComp1Dist < nComp2Dist) ? nWeight1 : nWeight2;
+ rnWeight *= ((rnCompNearer - 0x80L) * (rnCompNearer - 0x7FL) / 0x1000L + 1);
+ }
+ sal_uInt32 nWSum = nWeight1 + nWeight2;
+ return static_cast< sal_uInt8 >( (nComp1 * nWeight1 + nComp2 * nWeight2 + nWSum / 2) / nWSum );
+}
+
+void lclSetMixedColor( Color& rDest, const Color& rSrc1, const Color& rSrc2 )
+{
+ rDest.SetRed( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetRed() ) + rSrc2.GetRed()) / 2 ) );
+ rDest.SetGreen( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetGreen() ) + rSrc2.GetGreen()) / 2 ) );
+ rDest.SetBlue( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetBlue() ) + rSrc2.GetBlue()) / 2 ) );
+}
+
+} // namespace
+
+// additional classes for color reduction -------------------------------------
+
+namespace {
+
+/** Represents an entry in a color list.
+
+ The color stores a weighting value, which increases the more the color is
+ used in the document. Heavy-weighted colors will change less than others on
+ color reduction.
+ */
+class XclListColor
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclListColor )
+
+private:
+ Color maColor; /// The color value of this palette entry.
+ sal_uInt32 mnColorId; /// Unique color ID for color reduction.
+ sal_uInt32 mnWeight; /// Weighting for color reduction.
+ bool mbBaseColor; /// true = Handle as base color, (don't remove/merge).
+
+public:
+ explicit XclListColor( const Color& rColor, sal_uInt32 nColorId );
+
+ /** Returns the RGB color value of the color. */
+ inline const Color& GetColor() const { return maColor; }
+ /** Returns the unique ID of the color. */
+ inline sal_uInt32 GetColorId() const { return mnColorId; }
+ /** Returns the current weighting of the color. */
+ inline sal_uInt32 GetWeighting() const { return mnWeight; }
+ /** Returns true, if this color is a base color, i.e. it will not be removed or merged. */
+ inline bool IsBaseColor() const { return mbBaseColor; }
+
+ /** Adds the passed weighting to this color. */
+ inline void AddWeighting( sal_uInt32 nWeight ) { mnWeight += nWeight; }
+ /** Merges this color with rColor, regarding weighting settings. */
+ void Merge( const XclListColor& rColor );
+};
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclListColor, 100, 100 )
+
+XclListColor::XclListColor( const Color& rColor, sal_uInt32 nColorId ) :
+ maColor( rColor ),
+ mnColorId( nColorId ),
+ mnWeight( 0 )
+{
+ mbBaseColor =
+ ((rColor.GetRed() == 0x00) || (rColor.GetRed() == 0xFF)) &&
+ ((rColor.GetGreen() == 0x00) || (rColor.GetGreen() == 0xFF)) &&
+ ((rColor.GetBlue() == 0x00) || (rColor.GetBlue() == 0xFF));
+}
+
+void XclListColor::Merge( const XclListColor& rColor )
+{
+ sal_uInt32 nWeight2 = rColor.GetWeighting();
+ // do not change RGB value of base colors
+ if( !mbBaseColor )
+ {
+ maColor.SetRed( lclGetMergedColorComp( maColor.GetRed(), mnWeight, rColor.maColor.GetRed(), nWeight2 ) );
+ maColor.SetGreen( lclGetMergedColorComp( maColor.GetGreen(), mnWeight, rColor.maColor.GetGreen(), nWeight2 ) );
+ maColor.SetBlue( lclGetMergedColorComp( maColor.GetBlue(), mnWeight, rColor.maColor.GetBlue(), nWeight2 ) );
+ }
+ AddWeighting( nWeight2 );
+}
+
+// ----------------------------------------------------------------------------
+
+/** Data for each inserted original color, represented by a color ID. */
+struct XclColorIdData
+{
+ Color maColor; /// The original inserted color.
+ sal_uInt32 mnIndex; /// Maps current color ID to color list or export color vector.
+ /** Sets the contents of this struct. */
+ inline void Set( const Color& rColor, sal_uInt32 nIndex ) { maColor = rColor; mnIndex = nIndex; }
+};
+
+/** A color that will be written to the Excel file. */
+struct XclPaletteColor
+{
+ Color maColor; /// Resulting color to export.
+ bool mbUsed; /// true = Entry is used in the document.
+
+ inline explicit XclPaletteColor( const Color& rColor ) : maColor( rColor ), mbUsed( false ) {}
+ inline void SetColor( const Color& rColor ) { maColor = rColor; mbUsed = true; }
+};
+
+/** Maps a color list index to a palette index.
+ @descr Used to remap the color ID data vector from list indexes to palette indexes. */
+struct XclRemap
+{
+ sal_uInt32 mnPalIndex; /// Index to palette.
+ bool mbProcessed; /// true = List color already processed.
+
+ inline explicit XclRemap() : mnPalIndex( 0 ), mbProcessed( false ) {}
+ inline void SetIndex( sal_uInt32 nPalIndex )
+ { mnPalIndex = nPalIndex; mbProcessed = true; }
+};
+
+/** Stores the nearest palette color index of a list color. */
+struct XclNearest
+{
+ sal_uInt32 mnPalIndex; /// Index to nearest palette color.
+ sal_Int32 mnDist; /// Distance to palette color.
+
+ inline explicit XclNearest() : mnPalIndex( 0 ), mnDist( 0 ) {}
+};
+
+typedef ::std::vector< XclRemap > XclRemapVec;
+typedef ::std::vector< XclNearest > XclNearestVec;
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+class XclExpPaletteImpl
+{
+public:
+ explicit XclExpPaletteImpl( const XclDefaultPalette& rDefPal );
+
+ /** Inserts the color into the list and updates weighting.
+ @param nAutoDefault The Excel palette index for automatic color.
+ @return A unique ID for this color. */
+ sal_uInt32 InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
+ /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
+ static sal_uInt32 GetColorIdFromIndex( sal_uInt16 nIndex );
+
+ /** Reduces the color list to the maximum count of the current BIFF version. */
+ void Finalize();
+
+ /** Returns the Excel palette index of the color with passed color ID. */
+ sal_uInt16 GetColorIndex( sal_uInt32 nColorId ) const;
+
+ /** Returns a foreground and background color for the two passed color IDs.
+ @descr If rnXclPattern contains a solid pattern, this function tries to find
+ the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
+ This will result in a better approximation to the passed foreground color. */
+ void GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
+
+ /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ ColorData GetColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the color for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ inline Color GetColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetColorData( nXclIndex ) ); }
+
+ /** Returns true, if all colors of the palette are equal to default palette colors. */
+ bool IsDefaultPalette() const;
+ /** Writes the color list (contents of the palette record) to the passed stream. */
+ void WriteBody( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Returns the Excel index of a 0-based color index. */
+ inline sal_uInt16 GetXclIndex( sal_uInt32 nIndex ) const
+ { return static_cast< sal_uInt16 >( nIndex + EXC_COLOR_USEROFFSET ); }
+
+ /** Returns the original inserted color represented by the color ID nColorId. */
+ const Color& GetOriginalColor( sal_uInt32 nColorId ) const;
+
+ /** Searches for rColor, returns the ordered insertion index for rColor in rnIndex. */
+ XclListColor* SearchListEntry( const Color& rColor, sal_uInt32& rnIndex );
+ /** Creates and inserts a new color list entry at the specified list position. */
+ XclListColor* CreateListEntry( const Color& rColor, sal_uInt32 nIndex );
+
+ /** Raw and fast reduction of the palette. */
+ void RawReducePalette( sal_uInt32 nPass );
+ /** Reduction of one color using advanced color merging based on color weighting. */
+ void ReduceLeastUsedColor();
+
+ /** Finds the least used color and returns its current list index. */
+ sal_uInt32 GetLeastUsedListColor() const;
+ /** Returns the list index of the color nearest to rColor.
+ @param nIgnore List index of a color which will be ignored.
+ @return The list index of the found color. */
+ sal_uInt32 GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const;
+ /** Returns the list index of the color nearest to the color with list index nIndex. */
+ sal_uInt32 GetNearestListColor( sal_uInt32 nIndex ) const;
+
+ /** Returns in rnIndex the palette index of the color nearest to rColor.
+ @param bDefaultOnly true = Searches for default colors only (colors never replaced).
+ @return The distance from passed color to found color. */
+ sal_Int32 GetNearestPaletteColor(
+ sal_uInt32& rnIndex,
+ const Color& rColor, bool bDefaultOnly ) const;
+ /** Returns in rnFirst and rnSecond the palette indexes of the two colors nearest to rColor.
+ @return The minimum distance from passed color to found colors. */
+ sal_Int32 GetNearPaletteColors(
+ sal_uInt32& rnFirst, sal_uInt32& rnSecond,
+ const Color& rColor ) const;
+
+private:
+ typedef ScfDelList< XclListColor > XclListColorList;
+ typedef ScfRef< XclListColorList > XclListColorListRef;
+ typedef ::std::vector< XclColorIdData > XclColorIdDataVec;
+ typedef ::std::vector< XclPaletteColor > XclPaletteColorVec;
+
+ const XclDefaultPalette& mrDefPal; /// The default palette for the current BIFF version.
+ XclListColorListRef mxColorList; /// Working color list.
+ XclColorIdDataVec maColorIdDataVec; /// Data of all CIDs.
+ XclPaletteColorVec maPalette; /// Contains resulting colors to export.
+ sal_uInt32 mnLastIdx; /// Last insertion index for search opt.
+};
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt32 EXC_PAL_INDEXBASE = 0xFFFF0000;
+const sal_uInt32 EXC_PAL_MAXRAWSIZE = 1024;
+
+XclExpPaletteImpl::XclExpPaletteImpl( const XclDefaultPalette& rDefPal ) :
+ mrDefPal( rDefPal ),
+ mxColorList( new XclListColorList ),
+ mnLastIdx( 0 )
+{
+ // initialize maPalette with default colors
+ sal_uInt16 nCount = static_cast< sal_uInt16 >( mrDefPal.GetColorCount() );
+ maPalette.reserve( nCount );
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ maPalette.push_back( XclPaletteColor( mrDefPal.GetDefColor( GetXclIndex( nIdx ) ) ) );
+
+ InsertColor( Color( COL_BLACK ), EXC_COLOR_CELLTEXT );
+}
+
+sal_uInt32 XclExpPaletteImpl::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
+{
+ if( rColor.GetColor() == COL_AUTO )
+ return GetColorIdFromIndex( nAutoDefault );
+
+ sal_uInt32 nFoundIdx = 0;
+ XclListColor* pEntry = SearchListEntry( rColor, nFoundIdx );
+ if( !pEntry || (pEntry->GetColor() != rColor) )
+ pEntry = CreateListEntry( rColor, nFoundIdx );
+ pEntry->AddWeighting( lclGetWeighting( eType ) );
+
+ return pEntry->GetColorId();
+}
+
+sal_uInt32 XclExpPaletteImpl::GetColorIdFromIndex( sal_uInt16 nIndex )
+{
+ return EXC_PAL_INDEXBASE | nIndex;
+}
+
+void XclExpPaletteImpl::Finalize()
+{
+// --- build initial color ID data vector (maColorIdDataVec) ---
+
+ sal_uInt32 nCount = mxColorList->Count();
+ maColorIdDataVec.resize( nCount );
+ for( sal_uInt32 nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ XclListColor* pListColor = mxColorList->GetObject( nIdx );
+ maColorIdDataVec[ pListColor->GetColorId() ].Set( pListColor->GetColor(), nIdx );
+ }
+
+// --- loop as long as current color count does not fit into palette of current BIFF ---
+
+ // phase 1: raw reduction (performance reasons, #i36945#)
+ sal_uInt32 nPass = 0;
+ while( mxColorList->Count() > EXC_PAL_MAXRAWSIZE )
+ RawReducePalette( nPass++ );
+
+ // phase 2: precise reduction using advanced color merging based on color weighting
+ while( mxColorList->Count() > mrDefPal.GetColorCount() )
+ ReduceLeastUsedColor();
+
+// --- #104865# use default palette and replace colors with nearest used colors ---
+
+ nCount = mxColorList->Count();
+ XclRemapVec aRemapVec( nCount );
+ XclNearestVec aNearestVec( nCount );
+
+ // in each run: search the best fitting color and replace a default color with it
+ for( sal_uInt32 nRun = 0; nRun < nCount; ++nRun )
+ {
+ sal_uInt32 nIndex;
+ // find nearest unused default color for each unprocessed list color
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ aNearestVec[ nIndex ].mnDist = aRemapVec[ nIndex ].mbProcessed ? SAL_MAX_INT32 :
+ GetNearestPaletteColor( aNearestVec[ nIndex ].mnPalIndex, mxColorList->GetObject( nIndex )->GetColor(), true );
+ // find the list color which is nearest to a default color
+ sal_uInt32 nFound = 0;
+ for( nIndex = 1; nIndex < nCount; ++nIndex )
+ if( aNearestVec[ nIndex ].mnDist < aNearestVec[ nFound ].mnDist )
+ nFound = nIndex;
+ // replace default color with list color
+ sal_uInt32 nNearest = aNearestVec[ nFound ].mnPalIndex;
+ DBG_ASSERT( mxColorList->GetObject( nFound ), "XclExpPaletteImpl::Finalize - missing a color" );
+ DBG_ASSERT( nNearest < maPalette.size(), "XclExpPaletteImpl::Finalize - algorithm error" );
+ maPalette[ nNearest ].SetColor( mxColorList->GetObject( nFound )->GetColor() );
+ aRemapVec[ nFound ].SetIndex( nNearest );
+ }
+
+ // remap color ID data map (maColorIdDataVec) from list indexes to palette indexes
+ for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
+ aIt->mnIndex = aRemapVec[ aIt->mnIndex ].mnPalIndex;
+}
+
+sal_uInt16 XclExpPaletteImpl::GetColorIndex( sal_uInt32 nColorId ) const
+{
+ sal_uInt16 nRet = 0;
+ if( nColorId >= EXC_PAL_INDEXBASE )
+ nRet = static_cast< sal_uInt16 >( nColorId & ~EXC_PAL_INDEXBASE );
+ else if( nColorId < maColorIdDataVec.size() )
+ nRet = GetXclIndex( maColorIdDataVec[ nColorId ].mnIndex );
+ return nRet;
+}
+
+void XclExpPaletteImpl::GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
+{
+ rnXclForeIx = GetColorIndex( nForeColorId );
+ rnXclBackIx = GetColorIndex( nBackColorId );
+ if( (rnXclPattern != EXC_PATT_SOLID) || (nForeColorId >= maColorIdDataVec.size()) )
+ return;
+
+ // now we have solid pattern, and a defined foreground (background doesn't care for solid pattern)
+
+ sal_uInt32 nIndex1, nIndex2;
+ Color aForeColor( GetOriginalColor( nForeColorId ) );
+ sal_Int32 nFirstDist = GetNearPaletteColors( nIndex1, nIndex2, aForeColor );
+ if( (nIndex1 >= maPalette.size()) || (nIndex2 >= maPalette.size()) )
+ return;
+
+ Color aColorArr[ 5 ];
+ aColorArr[ 0 ] = maPalette[ nIndex1 ].maColor;
+ aColorArr[ 4 ] = maPalette[ nIndex2 ].maColor;
+ lclSetMixedColor( aColorArr[ 2 ], aColorArr[ 0 ], aColorArr[ 4 ] );
+ lclSetMixedColor( aColorArr[ 1 ], aColorArr[ 0 ], aColorArr[ 2 ] );
+ lclSetMixedColor( aColorArr[ 3 ], aColorArr[ 2 ], aColorArr[ 4 ] );
+
+ sal_Int32 nMinDist = nFirstDist;
+ sal_uInt32 nMinIndex = 0;
+ for( sal_uInt32 nCnt = 1; nCnt < 4; ++nCnt )
+ {
+ sal_Int32 nDist = lclGetColorDistance( aForeColor, aColorArr[ nCnt ] );
+ if( nDist < nMinDist )
+ {
+ nMinDist = nDist;
+ nMinIndex = nCnt;
+ }
+ }
+ rnXclForeIx = GetXclIndex( nIndex1 );
+ rnXclBackIx = GetXclIndex( nIndex2 );
+ if( nMinDist < nFirstDist )
+ {
+ switch( nMinIndex )
+ {
+ case 1: rnXclPattern = EXC_PATT_75_PERC; break;
+ case 2: rnXclPattern = EXC_PATT_50_PERC; break;
+ case 3: rnXclPattern = EXC_PATT_25_PERC; break;
+ }
+ }
+}
+
+ColorData XclExpPaletteImpl::GetColorData( sal_uInt16 nXclIndex ) const
+{
+ if( nXclIndex >= EXC_COLOR_USEROFFSET )
+ {
+ sal_uInt32 nIdx = nXclIndex - EXC_COLOR_USEROFFSET;
+ if( nIdx < maPalette.size() )
+ return maPalette[ nIdx ].maColor.GetColor();
+ }
+ return mrDefPal.GetDefColorData( nXclIndex );
+}
+
+bool XclExpPaletteImpl::IsDefaultPalette() const
+{
+ bool bDefault = true;
+ for( sal_uInt32 nIdx = 0, nSize = static_cast< sal_uInt32 >( maPalette.size() ); bDefault && (nIdx < nSize); ++nIdx )
+ bDefault = maPalette[ nIdx ].maColor == mrDefPal.GetDefColor( GetXclIndex( nIdx ) );
+ return bDefault;
+}
+
+void XclExpPaletteImpl::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt16 >( maPalette.size() );
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
+ rStrm << aIt->maColor;
+}
+
+void XclExpPaletteImpl::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !maPalette.size() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_colors, FSEND );
+ rStyleSheet->startElement( XML_indexedColors, FSEND );
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
+ rStyleSheet->singleElement( XML_rgbColor,
+ XML_rgb, XclXmlUtils::ToOString( aIt->maColor ).getStr(),
+ FSEND );
+ rStyleSheet->endElement( XML_indexedColors );
+ rStyleSheet->endElement( XML_colors );
+}
+
+const Color& XclExpPaletteImpl::GetOriginalColor( sal_uInt32 nColorId ) const
+{
+ if( nColorId < maColorIdDataVec.size() )
+ return maColorIdDataVec[ nColorId ].maColor;
+ return maPalette[ 0 ].maColor;
+}
+
+XclListColor* XclExpPaletteImpl::SearchListEntry( const Color& rColor, sal_uInt32& rnIndex )
+{
+ rnIndex = mnLastIdx;
+ XclListColor* pEntry = mxColorList->GetObject( rnIndex );
+
+ // search optimization for equal-colored objects occuring repeatedly
+ if( pEntry && (pEntry->GetColor() == rColor) )
+ return pEntry;
+
+ // binary search for color
+ sal_uInt32 nBegIdx = 0;
+ sal_uInt32 nEndIdx = mxColorList->Count();
+ bool bFound = false;
+ while( !bFound && (nBegIdx < nEndIdx) )
+ {
+ rnIndex = (nBegIdx + nEndIdx) / 2;
+ pEntry = mxColorList->GetObject( rnIndex );
+ bFound = pEntry->GetColor() == rColor;
+ if( !bFound )
+ {
+ if( pEntry->GetColor().GetColor() < rColor.GetColor() )
+ nBegIdx = rnIndex + 1;
+ else
+ nEndIdx = rnIndex;
+ }
+ }
+ // not found - use end of range as new insertion position
+ if( !bFound )
+ pEntry = mxColorList->GetObject( rnIndex = nEndIdx );
+
+ mnLastIdx = rnIndex;
+ return pEntry;
+}
+
+XclListColor* XclExpPaletteImpl::CreateListEntry( const Color& rColor, sal_uInt32 nIndex )
+{
+ XclListColor* pEntry = new XclListColor( rColor, mxColorList->Count() );
+ mxColorList->Insert( pEntry, nIndex );
+ return pEntry;
+}
+
+void XclExpPaletteImpl::RawReducePalette( sal_uInt32 nPass )
+{
+ /* Fast palette reduction - in each call of this function one RGB component
+ of each color is reduced to a lower number of distinct values.
+ Pass 0: Blue is reduced to 128 distinct values.
+ Pass 1: Red is reduced to 128 distinct values.
+ Pass 2: Green is reduced to 128 distinct values.
+ Pass 3: Blue is reduced to 64 distinct values.
+ Pass 4: Red is reduced to 64 distinct values.
+ Pass 5: Green is reduced to 64 distinct values.
+ And so on...
+ */
+
+ XclListColorListRef xOldList = mxColorList;
+ mxColorList.reset( new XclListColorList );
+
+ // maps old list indexes to new list indexes, used to update maColorIdDataVec
+ ScfUInt32Vec aListIndexMap;
+ aListIndexMap.reserve( xOldList->Count() );
+
+ // preparations
+ sal_uInt8 nR, nG, nB;
+ sal_uInt8& rnComp = ((nPass % 3 == 0) ? nB : ((nPass % 3 == 1) ? nR : nG));
+ nPass /= 3;
+ DBG_ASSERT( nPass < 7, "XclExpPaletteImpl::RawReducePalette - reduction not terminated" );
+
+ static const sal_uInt8 spnFactor2[] = { 0x81, 0x82, 0x84, 0x88, 0x92, 0xAA, 0xFF };
+ sal_uInt8 nFactor1 = static_cast< sal_uInt8 >( 0x02 << nPass );
+ sal_uInt8 nFactor2 = spnFactor2[ nPass ];
+ sal_uInt8 nFactor3 = static_cast< sal_uInt8 >( 0x40 >> nPass );
+
+ // process each color in the old color list
+ for( sal_uInt32 nIdx = 0, nCount = xOldList->Count(); nIdx < nCount; ++nIdx )
+ {
+ // get the old list entry
+ const XclListColor* pOldEntry = xOldList->GetObject( nIdx );
+ nR = pOldEntry->GetColor().GetRed();
+ nG = pOldEntry->GetColor().GetGreen();
+ nB = pOldEntry->GetColor().GetBlue();
+
+ /* Calculate the new RGB component (rnComp points to one of nR, nG, nB).
+ Using integer arithmetic with its rounding errors, the results of
+ this calculation are always exactly in the range 0x00 to 0xFF
+ (simply cutting the lower bits would darken the colors slightly). */
+ sal_uInt32 nNewComp = rnComp;
+ nNewComp /= nFactor1;
+ nNewComp *= nFactor2;
+ nNewComp /= nFactor3;
+ rnComp = static_cast< sal_uInt8 >( nNewComp );
+ Color aNewColor( nR, nG, nB );
+
+ // find or insert the new color
+ sal_uInt32 nFoundIdx = 0;
+ XclListColor* pNewEntry = SearchListEntry( aNewColor, nFoundIdx );
+ if( !pNewEntry || (pNewEntry->GetColor() != aNewColor) )
+ pNewEntry = CreateListEntry( aNewColor, nFoundIdx );
+ pNewEntry->AddWeighting( pOldEntry->GetWeighting() );
+ aListIndexMap.push_back( nFoundIdx );
+ }
+
+ // update color ID data map (maps color IDs to color list indexes), replace old by new list indexes
+ for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
+ aIt->mnIndex = aListIndexMap[ aIt->mnIndex ];
+}
+
+void XclExpPaletteImpl::ReduceLeastUsedColor()
+{
+ // find a list color to remove
+ sal_uInt32 nRemove = GetLeastUsedListColor();
+ // find its nearest neighbor
+ sal_uInt32 nKeep = GetNearestListColor( nRemove );
+
+ // merge both colors to one color, remove one color from list
+ XclListColor* pKeepEntry = mxColorList->GetObject( nKeep );
+ XclListColor* pRemoveEntry = mxColorList->GetObject( nRemove );
+ if( pKeepEntry && pRemoveEntry )
+ {
+ // merge both colors (if pKeepEntry is a base color, it will not change)
+ pKeepEntry->Merge( *pRemoveEntry );
+ // remove the less used color, adjust nKeep index if kept color follows removed color
+ mxColorList->Delete( nRemove );
+ if( nKeep > nRemove ) --nKeep;
+
+ // recalculate color ID data map (maps color IDs to color list indexes)
+ for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mnIndex > nRemove )
+ --aIt->mnIndex;
+ else if( aIt->mnIndex == nRemove )
+ aIt->mnIndex = nKeep;
+ }
+ }
+}
+
+sal_uInt32 XclExpPaletteImpl::GetLeastUsedListColor() const
+{
+ sal_uInt32 nFound = 0;
+ sal_uInt32 nMinW = SAL_MAX_UINT32;
+
+ for( sal_uInt32 nIdx = 0, nCount = mxColorList->Count(); nIdx < nCount; ++nIdx )
+ {
+ XclListColor* pEntry = mxColorList->GetObject( nIdx );
+ // ignore the base colors
+ if( !pEntry->IsBaseColor() && (pEntry->GetWeighting() < nMinW) )
+ {
+ nFound = nIdx;
+ nMinW = pEntry->GetWeighting();
+ }
+ }
+ return nFound;
+}
+
+sal_uInt32 XclExpPaletteImpl::GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const
+{
+ sal_uInt32 nFound = 0;
+ sal_Int32 nMinD = SAL_MAX_INT32;
+
+ for( sal_uInt32 nIdx = 0, nCount = mxColorList->Count(); nIdx < nCount; ++nIdx )
+ {
+ if( nIdx != nIgnore )
+ {
+ if( XclListColor* pEntry = mxColorList->GetObject( nIdx ) )
+ {
+ sal_Int32 nDist = lclGetColorDistance( rColor, pEntry->GetColor() );
+ if( nDist < nMinD )
+ {
+ nFound = nIdx;
+ nMinD = nDist;
+ }
+ }
+ }
+ }
+ return nFound;
+}
+
+sal_uInt32 XclExpPaletteImpl::GetNearestListColor( sal_uInt32 nIndex ) const
+{
+ XclListColor* pEntry = mxColorList->GetObject( nIndex );
+ return pEntry ? GetNearestListColor( pEntry->GetColor(), nIndex ) : 0;
+}
+
+sal_Int32 XclExpPaletteImpl::GetNearestPaletteColor(
+ sal_uInt32& rnIndex, const Color& rColor, bool bDefaultOnly ) const
+{
+ rnIndex = 0;
+ sal_Int32 nDist = SAL_MAX_INT32;
+
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
+ aIt != aEnd; ++aIt )
+ {
+ if( !bDefaultOnly || !aIt->mbUsed )
+ {
+ sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
+ if( nCurrDist < nDist )
+ {
+ rnIndex = aIt - maPalette.begin();
+ nDist = nCurrDist;
+ }
+ }
+ }
+ return nDist;
+}
+
+sal_Int32 XclExpPaletteImpl::GetNearPaletteColors(
+ sal_uInt32& rnFirst, sal_uInt32& rnSecond, const Color& rColor ) const
+{
+ rnFirst = rnSecond = 0;
+ sal_Int32 nDist1 = SAL_MAX_INT32;
+ sal_Int32 nDist2 = SAL_MAX_INT32;
+
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
+ aIt != aEnd; ++aIt )
+ {
+ sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
+ if( nCurrDist < nDist1 )
+ {
+ rnSecond = rnFirst;
+ nDist2 = nDist1;
+ rnFirst = aIt - maPalette.begin();
+ nDist1 = nCurrDist;
+ }
+ else if( nCurrDist < nDist2 )
+ {
+ rnSecond = aIt - maPalette.begin();
+ nDist2 = nCurrDist;
+ }
+ }
+ return nDist1;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpPalette::XclExpPalette( const XclExpRoot& rRoot ) :
+ XclDefaultPalette( rRoot ),
+ XclExpRecord( EXC_ID_PALETTE )
+{
+ mxImpl.reset( new XclExpPaletteImpl( *this ) );
+ SetRecSize( GetColorCount() * 4 + 2 );
+}
+
+XclExpPalette::~XclExpPalette()
+{
+}
+
+sal_uInt32 XclExpPalette::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
+{
+ return mxImpl->InsertColor( rColor, eType, nAutoDefault );
+}
+
+sal_uInt32 XclExpPalette::GetColorIdFromIndex( sal_uInt16 nIndex )
+{
+ return XclExpPaletteImpl::GetColorIdFromIndex( nIndex );
+}
+
+void XclExpPalette::Finalize()
+{
+ mxImpl->Finalize();
+}
+
+sal_uInt16 XclExpPalette::GetColorIndex( sal_uInt32 nColorId ) const
+{
+ return mxImpl->GetColorIndex( nColorId );
+}
+
+void XclExpPalette::GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
+{
+ return mxImpl->GetMixedColors( rnXclForeIx, rnXclBackIx, rnXclPattern, nForeColorId, nBackColorId );
+}
+
+ColorData XclExpPalette::GetColorData( sal_uInt16 nXclIndex ) const
+{
+ return mxImpl->GetColorData( nXclIndex );
+}
+
+void XclExpPalette::Save( XclExpStream& rStrm )
+{
+ if( !mxImpl->IsDefaultPalette() )
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpPalette::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !mxImpl->IsDefaultPalette() )
+ mxImpl->SaveXml( rStrm );
+}
+
+void XclExpPalette::WriteBody( XclExpStream& rStrm )
+{
+ mxImpl->WriteBody( rStrm );
+}
+
+// FONT record - font information =============================================
+
+namespace {
+
+typedef ::std::pair< USHORT, sal_Int16 > WhichAndScript;
+
+sal_Int16 lclCheckFontItems( const SfxItemSet& rItemSet,
+ const WhichAndScript& rWAS1, const WhichAndScript& rWAS2, const WhichAndScript& rWAS3 )
+{
+ if( ScfTools::CheckItem( rItemSet, rWAS1.first, false ) ) return rWAS1.second;
+ if( ScfTools::CheckItem( rItemSet, rWAS2.first, false ) ) return rWAS2.second;
+ if( ScfTools::CheckItem( rItemSet, rWAS3.first, false ) ) return rWAS3.second;
+ return 0;
+};
+
+} // namespace
+
+/*static*/ sal_Int16 XclExpFontHelper::GetFirstUsedScript( const XclExpRoot& rRoot, const SfxItemSet& rItemSet )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+ /* #i17050# #i107170# We need to determine which font items are set in the
+ item set, and which script type we should prefer according to the
+ current language settings. */
+
+ static const WhichAndScript WAS_LATIN( ATTR_FONT, ::com::sun::star::i18n::ScriptType::LATIN );
+ static const WhichAndScript WAS_ASIAN( ATTR_CJK_FONT, ::com::sun::star::i18n::ScriptType::ASIAN );
+ static const WhichAndScript WAS_CMPLX( ATTR_CTL_FONT, ::com::sun::star::i18n::ScriptType::COMPLEX );
+
+ /* #114008# do not let a font from a parent style override an explicit
+ cell font. */
+
+ sal_Int16 nDefScript = rRoot.GetDefApiScript();
+ sal_Int16 nScript = 0;
+ const SfxItemSet* pCurrSet = &rItemSet;
+
+ while( (nScript == 0) && pCurrSet )
+ {
+ switch( nDefScript )
+ {
+ case ApiScriptType::LATIN:
+ nScript = lclCheckFontItems( *pCurrSet, WAS_LATIN, WAS_CMPLX, WAS_ASIAN );
+ break;
+ case ApiScriptType::ASIAN:
+ nScript = lclCheckFontItems( *pCurrSet, WAS_ASIAN, WAS_CMPLX, WAS_LATIN );
+ break;
+ case ApiScriptType::COMPLEX:
+ nScript = lclCheckFontItems( *pCurrSet, WAS_CMPLX, WAS_ASIAN, WAS_LATIN );
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpFontHelper::GetFirstUsedScript - unknown script type" );
+ nScript = ApiScriptType::LATIN;
+ };
+ pCurrSet = pCurrSet->GetParent();
+ }
+
+ return nScript;
+}
+
+/*static*/ Font XclExpFontHelper::GetFontFromItemSet( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+ // if WEAK is passed, guess script type from existing items in the item set
+ if( nScript == ApiScriptType::WEAK )
+ nScript = GetFirstUsedScript( rRoot, rItemSet );
+
+ // convert to core script type constants
+ BYTE nScScript = SCRIPTTYPE_LATIN;
+ switch( nScript )
+ {
+ case ApiScriptType::LATIN: nScScript = SCRIPTTYPE_LATIN; break;
+ case ApiScriptType::ASIAN: nScScript = SCRIPTTYPE_ASIAN; break;
+ case ApiScriptType::COMPLEX: nScScript = SCRIPTTYPE_COMPLEX; break;
+ default: DBG_ERRORFILE( "XclExpFontHelper::GetFontFromItemSet - unknown script type" );
+ }
+
+ // fill the font object
+ Font aFont;
+ ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW, 0, 0, 0, nScScript );
+ return aFont;
+}
+
+/*static*/ bool XclExpFontHelper::CheckItems( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript, bool bDeep )
+{
+ static const USHORT pnCommonIds[] = {
+ ATTR_FONT_UNDERLINE, ATTR_FONT_CROSSEDOUT, ATTR_FONT_CONTOUR,
+ ATTR_FONT_SHADOWED, ATTR_FONT_COLOR, ATTR_FONT_LANGUAGE, 0 };
+ static const USHORT pnLatinIds[] = {
+ ATTR_FONT, ATTR_FONT_HEIGHT, ATTR_FONT_WEIGHT, ATTR_FONT_POSTURE, 0 };
+ static const USHORT pnAsianIds[] = {
+ ATTR_CJK_FONT, ATTR_CJK_FONT_HEIGHT, ATTR_CJK_FONT_WEIGHT, ATTR_CJK_FONT_POSTURE, 0 };
+ static const USHORT pnComplexIds[] = {
+ ATTR_CTL_FONT, ATTR_CTL_FONT_HEIGHT, ATTR_CTL_FONT_WEIGHT, ATTR_CTL_FONT_POSTURE, 0 };
+
+ bool bUsed = ScfTools::CheckItems( rItemSet, pnCommonIds, bDeep );
+ if( !bUsed )
+ {
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ // if WEAK is passed, guess script type from existing items in the item set
+ if( nScript == ApiScriptType::WEAK )
+ nScript = GetFirstUsedScript( rRoot, rItemSet );
+ // check the correct items
+ switch( nScript )
+ {
+ case ApiScriptType::LATIN: bUsed = ScfTools::CheckItems( rItemSet, pnLatinIds, bDeep ); break;
+ case ApiScriptType::ASIAN: bUsed = ScfTools::CheckItems( rItemSet, pnAsianIds, bDeep ); break;
+ case ApiScriptType::COMPLEX: bUsed = ScfTools::CheckItems( rItemSet, pnComplexIds, bDeep ); break;
+ default: DBG_ERRORFILE( "XclExpFontHelper::CheckItems - unknown script type" );
+ }
+ }
+ return bUsed;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_uInt32 lclCalcHash( const XclFontData& rFontData )
+{
+ sal_uInt32 nHash = rFontData.maName.Len();
+ nHash += rFontData.maColor.GetColor() * 2;
+ nHash += rFontData.mnWeight * 3;
+ nHash += rFontData.mnCharSet * 5;
+ nHash += rFontData.mnFamily * 7;
+ nHash += rFontData.mnHeight * 11;
+ nHash += rFontData.mnUnderline * 13;
+ nHash += rFontData.mnEscapem * 17;
+ if( rFontData.mbItalic ) nHash += 19;
+ if( rFontData.mbStrikeout ) nHash += 23;
+ if( rFontData.mbOutline ) nHash += 29;
+ if( rFontData.mbShadow ) nHash += 31;
+ return nHash;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpFont::XclExpFont( const XclExpRoot& rRoot,
+ const XclFontData& rFontData, XclExpColorType eColorType ) :
+ XclExpRecord( EXC_ID2_FONT, 14 ),
+ XclExpRoot( rRoot ),
+ maData( rFontData )
+{
+ // insert font color into palette
+ mnColorId = rRoot.GetPalette().InsertColor( rFontData.maColor, eColorType, EXC_COLOR_FONTAUTO );
+ // hash value for faster comparison
+ mnHash = lclCalcHash( maData );
+ // record size
+ sal_Size nStrLen = maData.maName.Len();
+ SetRecSize( ((GetBiff() == EXC_BIFF8) ? (nStrLen * 2 + 1) : nStrLen) + 15 );
+}
+
+bool XclExpFont::Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const
+{
+ return (mnHash == nHash) && (maData == rFontData);
+}
+
+void XclExpFont::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_font, FSEND );
+ rStrm.WriteFontData( maData, XML_name );
+ // OOXTODO: XML_scheme; //scheme/@val values: "major", "minor", "none"
+ rStyleSheet->endElement( XML_font );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpFont::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nAttr = EXC_FONTATTR_NONE;
+ ::set_flag( nAttr, EXC_FONTATTR_ITALIC, maData.mbItalic );
+ ::set_flag( nAttr, EXC_FONTATTR_STRIKEOUT, maData.mbStrikeout );
+ ::set_flag( nAttr, EXC_FONTATTR_OUTLINE, maData.mbOutline );
+ ::set_flag( nAttr, EXC_FONTATTR_SHADOW, maData.mbShadow );
+
+ DBG_ASSERT( maData.maName.Len() < 256, "XclExpFont::WriteBody - font name too long" );
+ XclExpString aFontName;
+ if( GetBiff() <= EXC_BIFF5 )
+ aFontName.AssignByte( maData.maName, GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ aFontName.Assign( maData.maName, EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH );
+
+ rStrm << maData.mnHeight
+ << nAttr
+ << GetPalette().GetColorIndex( mnColorId )
+ << maData.mnWeight
+ << maData.mnEscapem
+ << maData.mnUnderline
+ << maData.mnFamily
+ << maData.mnCharSet
+ << sal_uInt8( 0 )
+ << aFontName;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpBlindFont::XclExpBlindFont( const XclExpRoot& rRoot ) :
+ XclExpFont( rRoot, XclFontData(), EXC_COLOR_CELLTEXT )
+{
+}
+
+bool XclExpBlindFont::Equals( const XclFontData& /*rFontData*/, sal_uInt32 /*nHash*/ ) const
+{
+ return false;
+}
+
+void XclExpBlindFont::Save( XclExpStream& /*rStrm*/ )
+{
+ // do nothing
+}
+
+// ============================================================================
+
+XclExpFontBuffer::XclExpFontBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnXclMaxSize( 0 )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF4: mnXclMaxSize = EXC_FONT_MAXCOUNT4; break;
+ case EXC_BIFF5: mnXclMaxSize = EXC_FONT_MAXCOUNT5; break;
+ case EXC_BIFF8: mnXclMaxSize = EXC_FONT_MAXCOUNT8; break;
+ default: DBG_ERROR_BIFF();
+ }
+ InitDefaultFonts();
+}
+
+const XclExpFont* XclExpFontBuffer::GetFont( sal_uInt16 nXclFont ) const
+{
+ return maFontList.GetRecord( nXclFont ).get();
+}
+
+const XclFontData& XclExpFontBuffer::GetAppFontData() const
+{
+ return maFontList.GetRecord( EXC_FONT_APP )->GetFontData(); // exists always
+}
+
+sal_uInt16 XclExpFontBuffer::Insert(
+ const XclFontData& rFontData, XclExpColorType eColorType, bool bAppFont )
+{
+ if( bAppFont )
+ {
+ XclExpFontRef xFont( new XclExpFont( GetRoot(), rFontData, eColorType ) );
+ maFontList.ReplaceRecord( xFont, EXC_FONT_APP );
+ // #108487# set width of '0' character for column width export
+ SetCharWidth( xFont->GetFontData() );
+ return EXC_FONT_APP;
+ }
+
+ size_t nPos = Find( rFontData );
+ if( nPos == EXC_FONTLIST_NOTFOUND )
+ {
+ // not found in buffer - create new font
+ size_t nSize = maFontList.GetSize();
+ if( nSize < mnXclMaxSize )
+ {
+ // possible to insert
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), rFontData, eColorType ) );
+ nPos = nSize; // old size is last position now
+ }
+ else
+ {
+ // buffer is full - ignore new font, use default font
+ nPos = EXC_FONT_APP;
+ }
+ }
+ return static_cast< sal_uInt16 >( nPos );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert(
+ const Font& rFont, XclExpColorType eColorType, bool bAppFont )
+{
+ return Insert( XclFontData( rFont ), eColorType, bAppFont );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert(
+ const SvxFont& rFont, XclExpColorType eColorType, bool bAppFont )
+{
+ return Insert( XclFontData( rFont ), eColorType, bAppFont );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert( const SfxItemSet& rItemSet,
+ sal_Int16 nScript, XclExpColorType eColorType, bool bAppFont )
+{
+ // #i17050# #114008# #115495# script type now provided by caller
+ Font aFont = XclExpFontHelper::GetFontFromItemSet( GetRoot(), rItemSet, nScript );
+ return Insert( aFont, eColorType, bAppFont );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert( const ScPatternAttr& rPattern,
+ sal_Int16 nScript, XclExpColorType eColorType, bool bAppFont )
+{
+ return Insert( rPattern.GetItemSet(), nScript, eColorType, bAppFont );
+}
+
+void XclExpFontBuffer::Save( XclExpStream& rStrm )
+{
+ maFontList.Save( rStrm );
+}
+
+void XclExpFontBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maFontList.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_fonts,
+ XML_count, OString::valueOf( (sal_Int32) maFontList.GetSize() ).getStr(),
+ FSEND );
+
+ maFontList.SaveXml( rStrm );
+
+ rStyleSheet->endElement( XML_fonts );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpFontBuffer::InitDefaultFonts()
+{
+ XclFontData aFontData;
+ aFontData.maName.AssignAscii( "Arial" );
+ aFontData.SetScFamily( FAMILY_DONTKNOW );
+ aFontData.SetFontEncoding( ScfTools::GetSystemTextEncoding() );
+ aFontData.SetScHeight( 200 ); // 200 twips = 10 pt
+ aFontData.SetScWeight( WEIGHT_NORMAL );
+
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5:
+ {
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ aFontData.SetScWeight( WEIGHT_BOLD );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ aFontData.SetScWeight( WEIGHT_NORMAL );
+ aFontData.SetScPosture( ITALIC_NORMAL );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ aFontData.SetScWeight( WEIGHT_BOLD );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ // the blind font with index 4
+ maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
+ // already add the first user defined font (Excel does it too)
+ aFontData.SetScWeight( WEIGHT_NORMAL );
+ aFontData.SetScPosture( ITALIC_NONE );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ }
+ break;
+ case EXC_BIFF8:
+ {
+ XclExpFontRef xFont( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ maFontList.AppendRecord( xFont );
+ maFontList.AppendRecord( xFont );
+ maFontList.AppendRecord( xFont );
+ maFontList.AppendRecord( xFont );
+ if( GetOutput() == EXC_OUTPUT_BINARY )
+ // the blind font with index 4
+ maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
+ }
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+size_t XclExpFontBuffer::Find( const XclFontData& rFontData )
+{
+ sal_uInt32 nHash = lclCalcHash( rFontData );
+ for( size_t nPos = 0, nSize = maFontList.GetSize(); nPos < nSize; ++nPos )
+ if( maFontList.GetRecord( nPos )->Equals( rFontData, nHash ) )
+ return nPos;
+ return EXC_FONTLIST_NOTFOUND;
+}
+
+// FORMAT record - number formats =============================================
+
+/** Predicate for search algorithm. */
+struct XclExpNumFmtPred
+{
+ ULONG mnScNumFmt;
+ inline explicit XclExpNumFmtPred( ULONG nScNumFmt ) : mnScNumFmt( nScNumFmt ) {}
+ inline bool operator()( const XclExpNumFmt& rFormat ) const
+ { return rFormat.mnScNumFmt == mnScNumFmt; }
+};
+
+// ----------------------------------------------------------------------------
+
+XclExpNumFmtBuffer::XclExpNumFmtBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ /* Compiler needs a hint, this doesn't work: new NfKeywordTable;
+ cannot convert from 'class String *' to 'class String (*)[54]'
+ The effective result here is class String (*)[54*1] */
+ mxFormatter( new SvNumberFormatter( rRoot.GetDoc().GetServiceManager(), LANGUAGE_ENGLISH_US ) ),
+ mpKeywordTable( new NfKeywordTable[ 1 ] ),
+ mnStdFmt( GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5: mnXclOffset = EXC_FORMAT_OFFSET5; break;
+ case EXC_BIFF8: mnXclOffset = EXC_FORMAT_OFFSET8; break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ mxFormatter->FillKeywordTable( *mpKeywordTable, LANGUAGE_ENGLISH_US );
+ // remap codes unknown to Excel
+ (*mpKeywordTable)[ NF_KEY_NN ] = String( RTL_CONSTASCII_USTRINGPARAM( "DDD" ) );
+ (*mpKeywordTable)[ NF_KEY_NNN ] = String( RTL_CONSTASCII_USTRINGPARAM( "DDDD" ) );
+ // NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
+ (*mpKeywordTable)[ NF_KEY_NNNN ] = String( RTL_CONSTASCII_USTRINGPARAM( "DDDD" ) );
+ // Export the Thai T NatNum modifier.
+ (*mpKeywordTable)[ NF_KEY_THAI_T ] = String( RTL_CONSTASCII_USTRINGPARAM( "T" ) );
+}
+
+XclExpNumFmtBuffer::~XclExpNumFmtBuffer()
+{
+ delete[] mpKeywordTable;
+}
+
+sal_uInt16 XclExpNumFmtBuffer::Insert( ULONG nScNumFmt )
+{
+ XclExpNumFmtVec::const_iterator aIt =
+ ::std::find_if( maFormatMap.begin(), maFormatMap.end(), XclExpNumFmtPred( nScNumFmt ) );
+ if( aIt != maFormatMap.end() )
+ return aIt->mnXclNumFmt;
+
+ size_t nSize = maFormatMap.size();
+ if( nSize < static_cast< size_t >( 0xFFFF - mnXclOffset ) )
+ {
+ sal_uInt16 nXclNumFmt = static_cast< sal_uInt16 >( nSize + mnXclOffset );
+ maFormatMap.push_back( XclExpNumFmt( nScNumFmt, nXclNumFmt ) );
+ return nXclNumFmt;
+ }
+
+ return 0;
+}
+
+void XclExpNumFmtBuffer::Save( XclExpStream& rStrm )
+{
+ for( XclExpNumFmtVec::const_iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
+ WriteFormatRecord( rStrm, *aIt );
+}
+
+void XclExpNumFmtBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !maFormatMap.size() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_numFmts,
+ XML_count, OString::valueOf( (sal_Int32) maFormatMap.size() ).getStr(),
+ FSEND );
+ for( XclExpNumFmtVec::const_iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
+ {
+ rStyleSheet->singleElement( XML_numFmt,
+ XML_numFmtId, OString::valueOf( sal_Int32(aIt->mnXclNumFmt) ).getStr(),
+ XML_formatCode, XclXmlUtils::ToOString( GetFormatCode( *aIt ) ).getStr(),
+ FSEND );
+ }
+ rStyleSheet->endElement( XML_numFmts );
+}
+
+void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const String& rFormatStr )
+{
+ XclExpString aExpStr;
+ if( GetBiff() <= EXC_BIFF5 )
+ aExpStr.AssignByte( rFormatStr, GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ aExpStr.Assign( rFormatStr );
+
+ rStrm.StartRecord( EXC_ID4_FORMAT, 2 + aExpStr.GetSize() );
+ rStrm << nXclNumFmt << aExpStr;
+ rStrm.EndRecord();
+}
+
+void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat )
+{
+ WriteFormatRecord( rStrm, rFormat.mnXclNumFmt, GetFormatCode( rFormat ) );
+}
+
+String XclExpNumFmtBuffer::GetFormatCode( const XclExpNumFmt& rFormat )
+{
+ String aFormatStr;
+
+ if( const SvNumberformat* pEntry = GetFormatter().GetEntry( rFormat.mnScNumFmt ) )
+ {
+ if( pEntry->GetType() == NUMBERFORMAT_LOGICAL )
+ {
+ // build Boolean number format
+ Color* pColor = 0;
+ String aTemp;
+ const_cast< SvNumberformat* >( pEntry )->GetOutputString( 1.0, aTemp, &pColor );
+ aFormatStr.Append( '"' ).Append( aTemp ).AppendAscii( "\";\"" ).Append( aTemp ).AppendAscii( "\";\"" );
+ const_cast< SvNumberformat* >( pEntry )->GetOutputString( 0.0, aTemp, &pColor );
+ aFormatStr.Append( aTemp ).Append( '"' );
+ }
+ else
+ {
+ LanguageType eLang = pEntry->GetLanguage();
+ if( eLang != LANGUAGE_ENGLISH_US )
+ {
+ xub_StrLen nCheckPos;
+ short nType = NUMBERFORMAT_DEFINED;
+ sal_uInt32 nKey;
+ String aTemp( pEntry->GetFormatstring() );
+ mxFormatter->PutandConvertEntry( aTemp, nCheckPos, nType, nKey, eLang, LANGUAGE_ENGLISH_US );
+ DBG_ASSERT( nCheckPos == 0, "XclExpNumFmtBuffer::WriteFormatRecord - format code not convertible" );
+ pEntry = mxFormatter->GetEntry( nKey );
+ }
+
+ aFormatStr = pEntry->GetMappedFormatstring( *mpKeywordTable, *mxFormatter->GetLocaleData() );
+ if( aFormatStr.EqualsAscii( "Standard" ) )
+ aFormatStr.AssignAscii( "General" );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpNumFmtBuffer::WriteFormatRecord - format not found" );
+ aFormatStr.AssignAscii( "General" );
+ }
+
+ return aFormatStr;
+}
+
+// XF, STYLE record - Cell formatting =========================================
+
+bool XclExpCellProt::FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle )
+{
+ const ScProtectionAttr& rProtItem = GETITEM( rItemSet, ScProtectionAttr, ATTR_PROTECTION );
+ mbLocked = rProtItem.GetProtection();
+ mbHidden = rProtItem.GetHideFormula() || rProtItem.GetHideCell();
+ return ScfTools::CheckItem( rItemSet, ATTR_PROTECTION, bStyle );
+}
+
+#if 0
+void XclExpCellProt::FillToXF2( sal_uInt8& rnNumFmt ) const
+{
+ ::set_flag( rnNumFmt, EXC_XF2_LOCKED, mbLocked );
+ ::set_flag( rnNumFmt, EXC_XF2_HIDDEN, mbHidden );
+}
+#endif
+
+void XclExpCellProt::FillToXF3( sal_uInt16& rnProt ) const
+{
+ ::set_flag( rnProt, EXC_XF_LOCKED, mbLocked );
+ ::set_flag( rnProt, EXC_XF_HIDDEN, mbHidden );
+}
+
+void XclExpCellProt::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ rStrm.GetCurrentStream()->singleElement( XML_protection,
+ XML_locked, XclXmlUtils::ToPsz( mbLocked ),
+ XML_hidden, XclXmlUtils::ToPsz( mbHidden ),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclExpCellAlign::FillFromItemSet(
+ const SfxItemSet& rItemSet, bool bForceLineBreak, XclBiff eBiff, bool bStyle )
+{
+ bool bUsed = false;
+
+ switch( eBiff )
+ {
+ // ALL 'case's - run through!
+
+ case EXC_BIFF8: // attributes new in BIFF8
+ {
+ // text indent
+ long nTmpIndent = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_INDENT, sal_Int32 );
+ (nTmpIndent += 100) /= 200; // 1 Excel unit == 10 pt == 200 twips
+ mnIndent = limit_cast< sal_uInt8 >( nTmpIndent, 0, 15 );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_INDENT, bStyle );
+
+ // shrink to fit
+ mbShrink = GETITEMVALUE( rItemSet, SfxBoolItem, ATTR_SHRINKTOFIT, BOOL );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_SHRINKTOFIT, bStyle );
+
+ // CTL text direction
+ SetScFrameDir( GETITEMVALUE( rItemSet, SvxFrameDirectionItem, ATTR_WRITINGDIR, SvxFrameDirection ) );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_WRITINGDIR, bStyle );
+ }
+
+ case EXC_BIFF5: // attributes new in BIFF5
+ case EXC_BIFF4: // attributes new in BIFF4
+ {
+ // vertical alignment
+ SetScVerAlign( GETITEMVALUE( rItemSet, SvxVerJustifyItem, ATTR_VER_JUSTIFY, SvxCellVerJustify ) );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_VER_JUSTIFY, bStyle );
+
+ // stacked/rotation
+ bool bStacked = GETITEMVALUE( rItemSet, SfxBoolItem, ATTR_STACKED, BOOL );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_STACKED, bStyle );
+ if( bStacked )
+ {
+ mnRotation = EXC_ROT_STACKED;
+ }
+ else
+ {
+ // rotation
+ sal_Int32 nScRot = GETITEMVALUE( rItemSet, SfxInt32Item, ATTR_ROTATE_VALUE, sal_Int32 );
+ mnRotation = XclTools::GetXclRotation( nScRot );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_ROTATE_VALUE, bStyle );
+ }
+ mnOrient = XclTools::GetXclOrientFromRot( mnRotation );
+ }
+
+ case EXC_BIFF3: // attributes new in BIFF3
+ {
+ // text wrap
+ mbLineBreak = bForceLineBreak || GETITEMBOOL( rItemSet, ATTR_LINEBREAK );
+ bUsed |= bForceLineBreak || ScfTools::CheckItem( rItemSet, ATTR_LINEBREAK, bStyle );
+ }
+
+ case EXC_BIFF2: // attributes new in BIFF2
+ {
+ // horizontal alignment
+ SetScHorAlign( GETITEMVALUE( rItemSet, SvxHorJustifyItem, ATTR_HOR_JUSTIFY, SvxCellHorJustify ) );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_HOR_JUSTIFY, bStyle );
+ }
+
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ return bUsed;
+}
+
+#if 0
+void XclExpCellAlign::FillToXF2( sal_uInt8& rnFlags ) const
+{
+ ::insert_value( rnFlags, mnHorAlign, 0, 3 );
+}
+
+void XclExpCellAlign::FillToXF3( sal_uInt16& rnAlign ) const
+{
+ ::insert_value( rnAlign, mnHorAlign, 0, 3 );
+ ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
+}
+
+void XclExpCellAlign::FillToXF4( sal_uInt16& rnAlign ) const
+{
+ FillToXF3( rnAlign );
+ ::insert_value( rnAlign, mnVerAlign, 4, 2 );
+ ::insert_value( rnAlign, mnOrient, 6, 2 );
+}
+#endif
+
+void XclExpCellAlign::FillToXF5( sal_uInt16& rnAlign ) const
+{
+ ::insert_value( rnAlign, mnHorAlign, 0, 3 );
+ ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
+ ::insert_value( rnAlign, mnVerAlign, 4, 3 );
+ ::insert_value( rnAlign, mnOrient, 8, 2 );
+}
+
+void XclExpCellAlign::FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const
+{
+ ::insert_value( rnAlign, mnHorAlign, 0, 3 );
+ ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
+ ::insert_value( rnAlign, mnVerAlign, 4, 3 );
+ ::insert_value( rnAlign, mnRotation, 8, 8 );
+ ::insert_value( rnMiscAttrib, mnIndent, 0, 4 );
+ ::set_flag( rnMiscAttrib, EXC_XF8_SHRINK, mbShrink );
+ ::insert_value( rnMiscAttrib, mnTextDir, 6, 2 );
+}
+
+static const char* ToHorizontalAlignment( sal_uInt8 nHorAlign )
+{
+ switch( nHorAlign )
+ {
+ case EXC_XF_HOR_GENERAL: return "general";
+ case EXC_XF_HOR_LEFT: return "left";
+ case EXC_XF_HOR_CENTER: return "center";
+ case EXC_XF_HOR_RIGHT: return "right";
+ case EXC_XF_HOR_FILL: return "fill";
+ case EXC_XF_HOR_JUSTIFY: return "justify";
+ case EXC_XF_HOR_CENTER_AS: return "centerContinuous";
+ case EXC_XF_HOR_DISTRIB: return "distributed";
+ }
+ return "*unknown*";
+}
+
+static const char* ToVerticalAlignment( sal_uInt8 nVerAlign )
+{
+ switch( nVerAlign )
+ {
+ case EXC_XF_VER_TOP: return "top";
+ case EXC_XF_VER_CENTER: return "center";
+ case EXC_XF_VER_BOTTOM: return "bottom";
+ case EXC_XF_VER_JUSTIFY: return "justify";
+ case EXC_XF_VER_DISTRIB: return "distributed";
+ }
+ return "*unknown*";
+}
+
+void XclExpCellAlign::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ rStrm.GetCurrentStream()->singleElement( XML_alignment,
+ XML_horizontal, ToHorizontalAlignment( mnHorAlign ),
+ XML_vertical, ToVerticalAlignment( mnVerAlign ),
+ XML_textRotation, OString::valueOf( (sal_Int32) mnRotation ).getStr(),
+ XML_wrapText, XclXmlUtils::ToPsz( mbLineBreak ),
+ XML_indent, OString::valueOf( (sal_Int32) mnIndent ).getStr(),
+ // OOXTODO: XML_relativeIndent, mnIndent?
+ // OOXTODO: XML_justifyLastLine,
+ XML_shrinkToFit, XclXmlUtils::ToPsz( mbShrink ),
+ // OOXTODO: XML_readingOrder,
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+void lclGetBorderLine(
+ sal_uInt8& rnXclLine, sal_uInt32& rnColorId,
+ const SvxBorderLine* pLine, XclExpPalette& rPalette, XclBiff eBiff )
+{
+ rnXclLine = EXC_LINE_NONE;
+ if( pLine )
+ {
+ sal_uInt16 nOuterWidth = pLine->GetOutWidth();
+ sal_uInt16 nDistance = pLine->GetDistance();
+ if( nDistance > 0 )
+ rnXclLine = EXC_LINE_DOUBLE;
+ else if( nOuterWidth > DEF_LINE_WIDTH_2 )
+ rnXclLine = EXC_LINE_THICK;
+ else if( nOuterWidth > DEF_LINE_WIDTH_1 )
+ rnXclLine = EXC_LINE_MEDIUM;
+ else if( nOuterWidth > DEF_LINE_WIDTH_0 )
+ rnXclLine = EXC_LINE_THIN;
+ else if( nOuterWidth > 0 )
+ rnXclLine = EXC_LINE_HAIR;
+ else
+ rnXclLine = EXC_LINE_NONE;
+ }
+ if( (eBiff == EXC_BIFF2) && (rnXclLine != EXC_LINE_NONE) )
+ rnXclLine = EXC_LINE_THIN;
+
+ rnColorId = (pLine && (rnXclLine != EXC_LINE_NONE)) ?
+ rPalette.InsertColor( pLine->GetColor(), EXC_COLOR_CELLBORDER ) :
+ XclExpPalette::GetColorIdFromIndex( 0 );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpCellBorder::XclExpCellBorder() :
+ mnLeftColorId( XclExpPalette::GetColorIdFromIndex( mnLeftColor ) ),
+ mnRightColorId( XclExpPalette::GetColorIdFromIndex( mnRightColor ) ),
+ mnTopColorId( XclExpPalette::GetColorIdFromIndex( mnTopColor ) ),
+ mnBottomColorId( XclExpPalette::GetColorIdFromIndex( mnBottomColor ) ),
+ mnDiagColorId( XclExpPalette::GetColorIdFromIndex( mnDiagColor ) )
+{
+}
+
+bool XclExpCellBorder::FillFromItemSet(
+ const SfxItemSet& rItemSet, XclExpPalette& rPalette, XclBiff eBiff, bool bStyle )
+{
+ bool bUsed = false;
+
+ switch( eBiff )
+ {
+ // ALL 'case's - run through!
+
+ case EXC_BIFF8: // attributes new in BIFF8
+ {
+ const SvxLineItem& rTLBRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_TLBR );
+ sal_uInt8 nTLBRLine;
+ sal_uInt32 nTLBRColorId;
+ lclGetBorderLine( nTLBRLine, nTLBRColorId, rTLBRItem.GetLine(), rPalette, eBiff );
+ mbDiagTLtoBR = (nTLBRLine != EXC_LINE_NONE);
+
+ const SvxLineItem& rBLTRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_BLTR );
+ sal_uInt8 nBLTRLine;
+ sal_uInt32 nBLTRColorId;
+ lclGetBorderLine( nBLTRLine, nBLTRColorId, rBLTRItem.GetLine(), rPalette, eBiff );
+ mbDiagBLtoTR = (nBLTRLine != EXC_LINE_NONE);
+
+ if( ::ScHasPriority( rTLBRItem.GetLine(), rBLTRItem.GetLine() ) )
+ {
+ mnDiagLine = nTLBRLine;
+ mnDiagColorId = nTLBRColorId;
+ }
+ else
+ {
+ mnDiagLine = nBLTRLine;
+ mnDiagColorId = nBLTRColorId;
+ }
+
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER_TLBR, bStyle ) ||
+ ScfTools::CheckItem( rItemSet, ATTR_BORDER_BLTR, bStyle );
+ }
+
+ case EXC_BIFF5:
+ case EXC_BIFF4:
+ case EXC_BIFF3:
+ case EXC_BIFF2:
+ {
+ const SvxBoxItem& rBoxItem = GETITEM( rItemSet, SvxBoxItem, ATTR_BORDER );
+ lclGetBorderLine( mnLeftLine, mnLeftColorId, rBoxItem.GetLeft(), rPalette, eBiff );
+ lclGetBorderLine( mnRightLine, mnRightColorId, rBoxItem.GetRight(), rPalette, eBiff );
+ lclGetBorderLine( mnTopLine, mnTopColorId, rBoxItem.GetTop(), rPalette, eBiff );
+ lclGetBorderLine( mnBottomLine, mnBottomColorId, rBoxItem.GetBottom(), rPalette, eBiff );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER, bStyle );
+ }
+
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ return bUsed;
+}
+
+void XclExpCellBorder::SetFinalColors( const XclExpPalette& rPalette )
+{
+ mnLeftColor = rPalette.GetColorIndex( mnLeftColorId );
+ mnRightColor = rPalette.GetColorIndex( mnRightColorId );
+ mnTopColor = rPalette.GetColorIndex( mnTopColorId );
+ mnBottomColor = rPalette.GetColorIndex( mnBottomColorId );
+ mnDiagColor = rPalette.GetColorIndex( mnDiagColorId );
+}
+
+#if 0
+void XclExpCellBorder::FillToXF2( sal_uInt8& rnFlags ) const
+{
+ ::set_flag( rnFlags, EXC_XF2_LEFTLINE, mnLeftLine != EXC_LINE_NONE );
+ ::set_flag( rnFlags, EXC_XF2_RIGHTLINE, mnRightLine != EXC_LINE_NONE );
+ ::set_flag( rnFlags, EXC_XF2_TOPLINE, mnTopLine != EXC_LINE_NONE );
+ ::set_flag( rnFlags, EXC_XF2_BOTTOMLINE, mnBottomLine != EXC_LINE_NONE );
+}
+
+void XclExpCellBorder::FillToXF3( sal_uInt32& rnBorder ) const
+{
+ ::insert_value( rnBorder, mnTopLine, 0, 3 );
+ ::insert_value( rnBorder, mnLeftLine, 8, 3 );
+ ::insert_value( rnBorder, mnBottomLine, 16, 3 );
+ ::insert_value( rnBorder, mnRightLine, 24, 3 );
+ ::insert_value( rnBorder, mnTopColor, 3, 5 );
+ ::insert_value( rnBorder, mnLeftColor, 11, 5 );
+ ::insert_value( rnBorder, mnBottomColor, 19, 5 );
+ ::insert_value( rnBorder, mnRightColor, 27, 5 );
+}
+#endif
+
+void XclExpCellBorder::FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const
+{
+ ::insert_value( rnBorder, mnTopLine, 0, 3 );
+ ::insert_value( rnBorder, mnLeftLine, 3, 3 );
+ ::insert_value( rnArea, mnBottomLine, 22, 3 );
+ ::insert_value( rnBorder, mnRightLine, 6, 3 );
+ ::insert_value( rnBorder, mnTopColor, 9, 7 );
+ ::insert_value( rnBorder, mnLeftColor, 16, 7 );
+ ::insert_value( rnArea, mnBottomColor, 25, 7 );
+ ::insert_value( rnBorder, mnRightColor, 23, 7 );
+}
+
+void XclExpCellBorder::FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const
+{
+ ::insert_value( rnBorder1, mnLeftLine, 0, 4 );
+ ::insert_value( rnBorder1, mnRightLine, 4, 4 );
+ ::insert_value( rnBorder1, mnTopLine, 8, 4 );
+ ::insert_value( rnBorder1, mnBottomLine, 12, 4 );
+ ::insert_value( rnBorder1, mnLeftColor, 16, 7 );
+ ::insert_value( rnBorder1, mnRightColor, 23, 7 );
+ ::insert_value( rnBorder2, mnTopColor, 0, 7 );
+ ::insert_value( rnBorder2, mnBottomColor, 7, 7 );
+ ::insert_value( rnBorder2, mnDiagColor, 14, 7 );
+ ::insert_value( rnBorder2, mnDiagLine, 21, 4 );
+ ::set_flag( rnBorder1, EXC_XF_DIAGONAL_TL_TO_BR, mbDiagTLtoBR );
+ ::set_flag( rnBorder1, EXC_XF_DIAGONAL_BL_TO_TR, mbDiagBLtoTR );
+}
+
+void XclExpCellBorder::FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const
+{
+ ::insert_value( rnLine, mnLeftLine, 0, 4 );
+ ::insert_value( rnLine, mnRightLine, 4, 4 );
+ ::insert_value( rnLine, mnTopLine, 8, 4 );
+ ::insert_value( rnLine, mnBottomLine, 12, 4 );
+ ::insert_value( rnColor, mnLeftColor, 0, 7 );
+ ::insert_value( rnColor, mnRightColor, 7, 7 );
+ ::insert_value( rnColor, mnTopColor, 16, 7 );
+ ::insert_value( rnColor, mnBottomColor, 23, 7 );
+}
+
+static const char* ToLineStyle( sal_uInt8 nLineStyle )
+{
+ switch( nLineStyle )
+ {
+ case EXC_LINE_NONE: return "none";
+ case EXC_LINE_THIN: return "thin";
+ case EXC_LINE_MEDIUM: return "medium";
+ case EXC_LINE_THICK: return "thick";
+ case EXC_LINE_DOUBLE: return "double";
+ case EXC_LINE_HAIR: return "hair";
+ }
+ return "*unknown*";
+}
+
+static void lcl_WriteBorder( XclExpXmlStream& rStrm, sal_Int32 nElement, sal_uInt8 nLineStyle, const Color& rColor )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ if( nLineStyle == EXC_LINE_NONE )
+ rStyleSheet->singleElement( nElement, FSEND );
+ else if( rColor == Color( 0, 0, 0, 0 ) )
+ rStyleSheet->singleElement( nElement,
+ XML_style, ToLineStyle( nLineStyle ),
+ FSEND );
+ else
+ {
+ rStyleSheet->startElement( nElement,
+ XML_style, ToLineStyle( nLineStyle ),
+ FSEND );
+ rStyleSheet->singleElement( XML_color,
+ XML_rgb, XclXmlUtils::ToOString( rColor ).getStr(),
+ FSEND );
+ rStyleSheet->endElement( nElement );
+ }
+}
+
+void XclExpCellBorder::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+
+ XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
+
+ rStyleSheet->startElement( XML_border,
+ XML_diagonalUp, XclXmlUtils::ToPsz( mbDiagBLtoTR ),
+ XML_diagonalDown, XclXmlUtils::ToPsz( mbDiagTLtoBR ),
+ // OOXTODO: XML_outline,
+ FSEND );
+ lcl_WriteBorder( rStrm, XML_left, mnLeftLine, rPalette.GetColor( mnLeftColor ) );
+ lcl_WriteBorder( rStrm, XML_right, mnRightLine, rPalette.GetColor( mnRightColor ) );
+ lcl_WriteBorder( rStrm, XML_top, mnTopLine, rPalette.GetColor( mnTopColor ) );
+ lcl_WriteBorder( rStrm, XML_bottom, mnBottomLine, rPalette.GetColor( mnBottomColor ) );
+ lcl_WriteBorder( rStrm, XML_diagonal, mnDiagLine, rPalette.GetColor( mnDiagColor ) );
+ // OOXTODO: XML_vertical, XML_horizontal
+ rStyleSheet->endElement( XML_border );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCellArea::XclExpCellArea() :
+ mnForeColorId( XclExpPalette::GetColorIdFromIndex( mnForeColor ) ),
+ mnBackColorId( XclExpPalette::GetColorIdFromIndex( mnBackColor ) )
+{
+}
+
+bool XclExpCellArea::FillFromItemSet( const SfxItemSet& rItemSet, XclExpPalette& rPalette, bool bStyle )
+{
+ const SvxBrushItem& rBrushItem = GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND );
+ if( rBrushItem.GetColor().GetTransparency() )
+ {
+ mnPattern = EXC_PATT_NONE;
+ mnForeColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
+ mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWBACK );
+ }
+ else
+ {
+ mnPattern = EXC_PATT_SOLID;
+ mnForeColorId = rPalette.InsertColor( rBrushItem.GetColor(), EXC_COLOR_CELLAREA );
+ mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
+ }
+ return ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, bStyle );
+}
+
+void XclExpCellArea::SetFinalColors( const XclExpPalette& rPalette )
+{
+ rPalette.GetMixedColors( mnForeColor, mnBackColor, mnPattern, mnForeColorId, mnBackColorId );
+}
+
+#if 0
+void XclExpCellArea::FillToXF2( sal_uInt8& rnFlags ) const
+{
+ ::set_flag( rnFlags, EXC_XF2_BACKGROUND, mnPattern != EXC_PATT_NONE );
+}
+
+void XclExpCellArea::FillToXF3( sal_uInt16& rnArea ) const
+{
+ ::insert_value( rnArea, mnPattern, 0, 6 );
+ ::insert_value( rnArea, mnForeColor, 6, 5 );
+ ::insert_value( rnArea, mnBackColor, 11, 5 );
+}
+#endif
+
+void XclExpCellArea::FillToXF5( sal_uInt32& rnArea ) const
+{
+ ::insert_value( rnArea, mnPattern, 16, 6 );
+ ::insert_value( rnArea, mnForeColor, 0, 7 );
+ ::insert_value( rnArea, mnBackColor, 7, 7 );
+}
+
+void XclExpCellArea::FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const
+{
+ ::insert_value( rnBorder2, mnPattern, 26, 6 );
+ ::insert_value( rnArea, mnForeColor, 0, 7 );
+ ::insert_value( rnArea, mnBackColor, 7, 7 );
+}
+
+void XclExpCellArea::FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const
+{
+ XclCellArea aTmp( *this );
+ if( !aTmp.IsTransparent() && (aTmp.mnBackColor == EXC_COLOR_WINDOWTEXT) )
+ aTmp.mnBackColor = 0;
+ if( aTmp.mnPattern == EXC_PATT_SOLID )
+ ::std::swap( aTmp.mnForeColor, aTmp.mnBackColor );
+ ::insert_value( rnColor, aTmp.mnForeColor, 0, 7 );
+ ::insert_value( rnColor, aTmp.mnBackColor, 7, 7 );
+ ::insert_value( rnPattern, aTmp.mnPattern, 10, 6 );
+}
+
+static const char* ToPatternType( sal_uInt8 nPattern )
+{
+ switch( nPattern )
+ {
+ case EXC_PATT_NONE: return "none";
+ case EXC_PATT_SOLID: return "solid";
+ case EXC_PATT_50_PERC: return "mediumGray";
+ case EXC_PATT_75_PERC: return "darkGray";
+ case EXC_PATT_25_PERC: return "lightGray";
+ case EXC_PATT_12_5_PERC: return "gray125";
+ case EXC_PATT_6_25_PERC: return "gray0625";
+ }
+ return "*unknown*";
+}
+
+void XclExpCellArea::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_fill,
+ FSEND );
+
+ // OOXTODO: XML_gradientFill
+
+ XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
+
+ if( mnPattern == EXC_PATT_NONE || ( mnForeColor == 0 && mnBackColor == 0 ) )
+ rStyleSheet->singleElement( XML_patternFill,
+ XML_patternType, ToPatternType( mnPattern ),
+ FSEND );
+ else
+ {
+ rStyleSheet->startElement( XML_patternFill,
+ XML_patternType, ToPatternType( mnPattern ),
+ FSEND );
+ rStyleSheet->singleElement( XML_fgColor,
+ XML_rgb, XclXmlUtils::ToOString( rPalette.GetColor( mnForeColor ) ).getStr(),
+ FSEND );
+ rStyleSheet->singleElement( XML_bgColor,
+ XML_rgb, XclXmlUtils::ToOString( rPalette.GetColor( mnBackColor ) ).getStr(),
+ FSEND );
+ rStyleSheet->endElement( XML_patternFill );
+ }
+
+ rStyleSheet->endElement( XML_fill );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXFId::XclExpXFId() :
+ mnXFId( XclExpXFBuffer::GetDefCellXFId() ),
+ mnXFIndex( EXC_XF_DEFAULTCELL )
+{
+}
+
+XclExpXFId::XclExpXFId( sal_uInt32 nXFId ) :
+ mnXFId( nXFId ),
+ mnXFIndex( EXC_XF_DEFAULTCELL )
+{
+}
+
+void XclExpXFId::ConvertXFIndex( const XclExpRoot& rRoot )
+{
+ mnXFIndex = rRoot.GetXFBuffer().GetXFIndex( mnXFId );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXF::XclExpXF(
+ const XclExpRoot& rRoot, const ScPatternAttr& rPattern, sal_Int16 nScript,
+ ULONG nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) :
+ XclXFBase( true ),
+ XclExpRoot( rRoot )
+{
+ mnParentXFId = GetXFBuffer().InsertStyle( rPattern.GetStyleSheet() );
+ Init( rPattern.GetItemSet(), nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak, false );
+}
+
+XclExpXF::XclExpXF( const XclExpRoot& rRoot, const SfxStyleSheetBase& rStyleSheet ) :
+ XclXFBase( false ),
+ XclExpRoot( rRoot ),
+ mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
+{
+ bool bDefStyle = (rStyleSheet.GetName() == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ));
+ sal_Int16 nScript = bDefStyle ? GetDefApiScript() : ::com::sun::star::i18n::ScriptType::WEAK;
+ Init( const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet(), nScript,
+ NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false, bDefStyle );
+}
+
+XclExpXF::XclExpXF( const XclExpRoot& rRoot, bool bCellXF ) :
+ XclXFBase( bCellXF ),
+ XclExpRoot( rRoot ),
+ mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
+{
+ InitDefault();
+}
+
+bool XclExpXF::Equals( const ScPatternAttr& rPattern,
+ ULONG nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
+{
+ return IsCellXF() && (mpItemSet == &rPattern.GetItemSet()) &&
+ (!bForceLineBreak || maAlignment.mbLineBreak) &&
+ ((nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) || (mnScNumFmt == nForceScNumFmt)) &&
+ ((nForceXclFont == EXC_FONT_NOTFOUND) || (mnXclFont == nForceXclFont));
+}
+
+bool XclExpXF::Equals( const SfxStyleSheetBase& rStyleSheet ) const
+{
+ return IsStyleXF() && (mpItemSet == &const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet());
+}
+
+void XclExpXF::SetFinalColors()
+{
+ maBorder.SetFinalColors( GetPalette() );
+ maArea.SetFinalColors( GetPalette() );
+}
+
+bool XclExpXF::Equals( const XclExpXF& rCmpXF ) const
+{
+ return XclXFBase::Equals( rCmpXF ) &&
+ (maProtection == rCmpXF.maProtection) && (maAlignment == rCmpXF.maAlignment) &&
+ (maBorder == rCmpXF.maBorder) && (maArea == rCmpXF.maArea) &&
+ (mnXclFont == rCmpXF.mnXclFont) && (mnXclNumFmt == rCmpXF.mnXclNumFmt) &&
+ (mnParentXFId == rCmpXF.mnParentXFId);
+}
+
+void XclExpXF::InitDefault()
+{
+ SetRecHeader( EXC_ID5_XF, (GetBiff() == EXC_BIFF8) ? 20 : 16 );
+ mpItemSet = 0;
+ mnScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
+ mnXclFont = mnXclNumFmt = 0;
+}
+
+void XclExpXF::Init( const SfxItemSet& rItemSet, sal_Int16 nScript,
+ ULONG nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak, bool bDefStyle )
+{
+ InitDefault();
+ mpItemSet = &rItemSet;
+
+ // cell protection
+ mbProtUsed = maProtection.FillFromItemSet( rItemSet, IsStyleXF() );
+
+ // font
+ if( nForceXclFont == EXC_FONT_NOTFOUND )
+ {
+ mnXclFont = GetFontBuffer().Insert( rItemSet, nScript, EXC_COLOR_CELLTEXT, bDefStyle );
+ mbFontUsed = XclExpFontHelper::CheckItems( GetRoot(), rItemSet, nScript, IsStyleXF() );
+ }
+ else
+ {
+ mnXclFont = nForceXclFont;
+ mbFontUsed = true;
+ }
+
+ // number format
+ mnScNumFmt = (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) ?
+ GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALUE_FORMAT, ULONG ) : nForceScNumFmt;
+ mnXclNumFmt = GetNumFmtBuffer().Insert( mnScNumFmt );
+ mbFmtUsed = ScfTools::CheckItem( rItemSet, ATTR_VALUE_FORMAT, IsStyleXF() );
+
+ // alignment
+ mbAlignUsed = maAlignment.FillFromItemSet( rItemSet, bForceLineBreak, GetBiff(), IsStyleXF() );
+
+ // cell border
+ mbBorderUsed = maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff(), IsStyleXF() );
+
+ // background area
+ mbAreaUsed = maArea.FillFromItemSet( rItemSet, GetPalette(), IsStyleXF() );
+
+ // set all b***Used flags to true in "Default"/"Normal" style
+ if( bDefStyle )
+ SetAllUsedFlags( true );
+}
+
+sal_uInt8 XclExpXF::GetUsedFlags() const
+{
+ sal_uInt8 nUsedFlags = 0;
+ /* In cell XFs a set bit means a used attribute, in style XFs a cleared bit.
+ "mbCellXF == mb***Used" evaluates to correct value in cell and style XFs. */
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_PROT, mbCellXF == mbProtUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_FONT, mbCellXF == mbFontUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_VALFMT, mbCellXF == mbFmtUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_ALIGN, mbCellXF == mbAlignUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_BORDER, mbCellXF == mbBorderUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_AREA, mbCellXF == mbAreaUsed );
+ return nUsedFlags;
+}
+
+void XclExpXF::WriteBody5( XclExpStream& rStrm )
+{
+ sal_uInt16 nTypeProt = 0, nAlign = 0;
+ sal_uInt32 nArea = 0, nBorder = 0;
+
+ ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
+ ::insert_value( nTypeProt, mnParent, 4, 12 );
+ ::insert_value( nAlign, GetUsedFlags(), 10, 6 );
+
+ maProtection.FillToXF3( nTypeProt );
+ maAlignment.FillToXF5( nAlign );
+ maBorder.FillToXF5( nBorder, nArea );
+ maArea.FillToXF5( nArea );
+
+ rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nArea << nBorder;
+}
+
+void XclExpXF::WriteBody8( XclExpStream& rStrm )
+{
+ sal_uInt16 nTypeProt = 0, nAlign = 0, nMiscAttrib = 0, nArea = 0;
+ sal_uInt32 nBorder1 = 0, nBorder2 = 0;
+
+ ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
+ ::insert_value( nTypeProt, mnParent, 4, 12 );
+ ::insert_value( nMiscAttrib, GetUsedFlags(), 10, 6 );
+
+ maProtection.FillToXF3( nTypeProt );
+ maAlignment.FillToXF8( nAlign, nMiscAttrib );
+ maBorder.FillToXF8( nBorder1, nBorder2 );
+ maArea.FillToXF8( nBorder2, nArea );
+
+ rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nMiscAttrib << nBorder1 << nBorder2 << nArea;
+}
+
+void XclExpXF::WriteBody( XclExpStream& rStrm )
+{
+ XclExpXFId aParentId( mnParentXFId );
+ aParentId.ConvertXFIndex( GetRoot() );
+ mnParent = aParentId.mnXFIndex;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5: WriteBody5( rStrm ); break;
+ case EXC_BIFF8: WriteBody8( rStrm ); break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpXF::SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId )
+{
+ mnBorderId = nBorderId;
+ mnFillId = nFillId;
+}
+
+void XclExpXF::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+
+ sal_Int32 nXfId = 0;
+ if( IsCellXF() )
+ {
+ sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( mnParentXFId );
+ nXfId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( nXFIndex );
+ }
+
+ rStyleSheet->startElement( XML_xf,
+ XML_numFmtId, OString::valueOf( (sal_Int32) mnXclNumFmt ).getStr(),
+ XML_fontId, OString::valueOf( (sal_Int32) mnXclFont ).getStr(),
+ XML_fillId, OString::valueOf( (sal_Int32) mnFillId ).getStr(),
+ XML_borderId, OString::valueOf( (sal_Int32) mnBorderId ).getStr(),
+ XML_xfId, IsStyleXF() ? NULL : OString::valueOf( nXfId ).getStr(),
+ // OOXTODO: XML_quotePrefix,
+ // OOXTODO: XML_pivotButton,
+ // OOXTODO: XML_applyNumberFormat, ;
+ XML_applyFont, XclXmlUtils::ToPsz( mbFontUsed ),
+ // OOXTODO: XML_applyFill,
+ XML_applyBorder, XclXmlUtils::ToPsz( mbBorderUsed ),
+ XML_applyAlignment, XclXmlUtils::ToPsz( mbAlignUsed ),
+ XML_applyProtection, XclXmlUtils::ToPsz( mbProtUsed ),
+ FSEND );
+ if( mbAlignUsed )
+ maAlignment.SaveXml( rStrm );
+ if( mbProtUsed )
+ maProtection.SaveXml( rStrm );
+ // OOXTODO: XML_extLst
+ rStyleSheet->endElement( XML_xf );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDefaultXF::XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF ) :
+ XclExpXF( rRoot, bCellXF )
+{
+}
+
+//UNUSED2008-05 void XclExpDefaultXF::SetParent( sal_uInt32 nParentXFId )
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ASSERT( IsCellXF(), "XclExpDefaultXF::SetParent - not allowed in style XFs" );
+//UNUSED2008-05 if( IsCellXF() )
+//UNUSED2008-05 mnParentXFId = nParentXFId;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void XclExpDefaultXF::SetUsedFlags(
+//UNUSED2008-05 bool bProtUsed, bool bFontUsed, bool bFmtUsed,
+//UNUSED2008-05 bool bAlignUsed, bool bBorderUsed, bool bAreaUsed )
+//UNUSED2008-05 {
+//UNUSED2008-05 mbProtUsed = bProtUsed;
+//UNUSED2008-05 mbFontUsed = bFontUsed;
+//UNUSED2008-05 mbFmtUsed = bFmtUsed;
+//UNUSED2008-05 mbAlignUsed = bAlignUsed;
+//UNUSED2008-05 mbBorderUsed = bBorderUsed;
+//UNUSED2008-05 mbAreaUsed = bAreaUsed;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void XclExpDefaultXF::SetProtection( const XclExpCellProt& rProtection )
+//UNUSED2008-05 {
+//UNUSED2008-05 maProtection = rProtection;
+//UNUSED2008-05 mbProtUsed = true;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void XclExpDefaultXF::SetAlignment( const XclExpCellAlign& rAlignment )
+//UNUSED2008-05 {
+//UNUSED2008-05 maAlignment = rAlignment;
+//UNUSED2008-05 mbAlignUsed = true;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void XclExpDefaultXF::SetBorder( const XclExpCellBorder& rBorder )
+//UNUSED2008-05 {
+//UNUSED2008-05 maBorder = rBorder;
+//UNUSED2008-05 mbBorderUsed = true;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void XclExpDefaultXF::SetArea( const XclExpCellArea& rArea )
+//UNUSED2008-05 {
+//UNUSED2008-05 maArea = rArea;
+//UNUSED2008-05 mbAreaUsed = true;
+//UNUSED2008-05 }
+
+void XclExpDefaultXF::SetFont( sal_uInt16 nXclFont )
+{
+ mnXclFont = nXclFont;
+ mbFontUsed = true;
+}
+
+void XclExpDefaultXF::SetNumFmt( sal_uInt16 nXclNumFmt )
+{
+ mnXclNumFmt = nXclNumFmt;
+ mbFmtUsed = true;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpStyle::XclExpStyle( sal_uInt32 nXFId, const String& rStyleName ) :
+ XclExpRecord( EXC_ID_STYLE, 4 ),
+ maName( rStyleName ),
+ maXFId( nXFId ),
+ mnStyleId( EXC_STYLE_USERDEF ),
+ mnLevel( EXC_STYLE_NOLEVEL )
+{
+ DBG_ASSERT( maName.Len(), "XclExpStyle::XclExpStyle - empty style name" );
+#ifdef DBG_UTIL
+ sal_uInt8 nStyleId, nLevel; // do not use members for debug tests
+ DBG_ASSERT( !XclTools::GetBuiltInStyleId( nStyleId, nLevel, maName ),
+ "XclExpStyle::XclExpStyle - this is a built-in style" );
+#endif
+}
+
+XclExpStyle::XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel ) :
+ XclExpRecord( EXC_ID_STYLE, 4 ),
+ maXFId( nXFId ),
+ mnStyleId( nStyleId ),
+ mnLevel( nLevel )
+{
+}
+
+void XclExpStyle::WriteBody( XclExpStream& rStrm )
+{
+ maXFId.ConvertXFIndex( rStrm.GetRoot() );
+ ::set_flag( maXFId.mnXFIndex, EXC_STYLE_BUILTIN, IsBuiltIn() );
+ rStrm << maXFId.mnXFIndex;
+
+ if( IsBuiltIn() )
+ {
+ rStrm << mnStyleId << mnLevel;
+ }
+ else
+ {
+ XclExpString aNameEx;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ aNameEx.Assign( maName );
+ else
+ aNameEx.AssignByte( maName, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
+ rStrm << aNameEx;
+ }
+}
+
+static const char* lcl_StyleNameFromId( sal_Int32 nStyleId )
+{
+ switch( nStyleId )
+ {
+ case 0: return "Normal";
+ case 3: return "Comma";
+ case 4: return "Currency";
+ case 5: return "Percent";
+ case 6: return "Comma [0]";
+ case 7: return "Currency [0]";
+ }
+ return "*unknown*";
+}
+
+void XclExpStyle::SaveXml( XclExpXmlStream& rStrm )
+{
+ OString sName;
+ if( IsBuiltIn() )
+ {
+ sName = OString( lcl_StyleNameFromId( mnStyleId ) );
+ }
+ else
+ sName = XclXmlUtils::ToOString( maName );
+ sal_Int32 nXFId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( maXFId.mnXFId );
+ rStrm.GetCurrentStream()->singleElement( XML_cellStyle,
+ XML_name, sName.getStr(),
+ XML_xfId, OString::valueOf( nXFId ).getStr(),
+ XML_builtinId, OString::valueOf( (sal_Int32) mnStyleId ).getStr(),
+ // OOXTODO: XML_iLevel,
+ // OOXTODO: XML_hidden,
+ XML_customBuiltin, XclXmlUtils::ToPsz( ! IsBuiltIn() ),
+ FSEND );
+ // OOXTODO: XML_extLst
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+const sal_uInt32 EXC_XFLIST_INDEXBASE = 0xFFFE0000;
+/** Maximum count of XF records to store in the XF list (performance). */
+const sal_uInt32 EXC_XFLIST_HARDLIMIT = 256 * 1024;
+
+bool lclIsBuiltInStyle( const String& rStyleName )
+{
+ return
+ XclTools::IsBuiltInStyleName( rStyleName ) ||
+ XclTools::IsCondFormatStyleName( rStyleName );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpXFBuffer::XclExpBuiltInInfo::XclExpBuiltInInfo() :
+ mnStyleId( EXC_STYLE_USERDEF ),
+ mnLevel( EXC_STYLE_NOLEVEL ),
+ mbPredefined( true ),
+ mbHasStyleRec( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+/** Predicate for search algorithm. */
+struct XclExpBorderPred
+{
+ const XclExpCellBorder&
+ mrBorder;
+ inline explicit XclExpBorderPred( const XclExpCellBorder& rBorder ) : mrBorder( rBorder ) {}
+ bool operator()( const XclExpCellBorder& rBorder ) const;
+};
+
+bool XclExpBorderPred::operator()( const XclExpCellBorder& rBorder ) const
+{
+ return
+ mrBorder.mnLeftColor == rBorder.mnLeftColor &&
+ mrBorder.mnRightColor == rBorder.mnRightColor &&
+ mrBorder.mnTopColor == rBorder.mnTopColor &&
+ mrBorder.mnBottomColor == rBorder.mnBottomColor &&
+ mrBorder.mnDiagColor == rBorder.mnDiagColor &&
+ mrBorder.mnLeftLine == rBorder.mnLeftLine &&
+ mrBorder.mnRightLine == rBorder.mnRightLine &&
+ mrBorder.mnTopLine == rBorder.mnTopLine &&
+ mrBorder.mnBottomLine == rBorder.mnBottomLine &&
+ mrBorder.mnDiagLine == rBorder.mnDiagLine &&
+ mrBorder.mbDiagTLtoBR == rBorder.mbDiagTLtoBR &&
+ mrBorder.mbDiagBLtoTR == rBorder.mbDiagBLtoTR &&
+ mrBorder.mnLeftColorId == rBorder.mnLeftColorId &&
+ mrBorder.mnRightColorId == rBorder.mnRightColorId &&
+ mrBorder.mnTopColorId == rBorder.mnTopColorId &&
+ mrBorder.mnBottomColorId == rBorder.mnBottomColorId &&
+ mrBorder.mnDiagColorId == rBorder.mnDiagColorId;
+}
+
+struct XclExpFillPred
+{
+ const XclExpCellArea&
+ mrFill;
+ inline explicit XclExpFillPred( const XclExpCellArea& rFill ) : mrFill( rFill ) {}
+ bool operator()( const XclExpCellArea& rFill ) const;
+};
+
+bool XclExpFillPred::operator()( const XclExpCellArea& rFill ) const
+{
+ return
+ mrFill.mnForeColor == rFill.mnForeColor &&
+ mrFill.mnBackColor == rFill.mnBackColor &&
+ mrFill.mnPattern == rFill.mnPattern &&
+ mrFill.mnForeColorId == rFill.mnForeColorId &&
+ mrFill.mnBackColorId == rFill.mnBackColorId;
+}
+
+XclExpXFBuffer::XclExpXFBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpXFBuffer::Initialize()
+{
+ InsertDefaultRecords();
+ InsertUserStyles();
+}
+
+sal_uInt32 XclExpXFBuffer::Insert( const ScPatternAttr* pPattern, sal_Int16 nScript )
+{
+ return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false );
+}
+
+sal_uInt32 XclExpXFBuffer::InsertWithFont( const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uInt16 nForceXclFont, bool bForceLineBreak )
+{
+ return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, nForceXclFont, bForceLineBreak );
+}
+
+sal_uInt32 XclExpXFBuffer::InsertWithNumFmt( const ScPatternAttr* pPattern, sal_Int16 nScript, ULONG nForceScNumFmt, bool bForceLineBreak )
+{
+ return InsertCellXF( pPattern, nScript, nForceScNumFmt, EXC_FONT_NOTFOUND, bForceLineBreak );
+}
+
+sal_uInt32 XclExpXFBuffer::InsertStyle( const SfxStyleSheetBase* pStyleSheet )
+{
+ return pStyleSheet ? InsertStyleXF( *pStyleSheet ) : GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
+}
+
+sal_uInt32 XclExpXFBuffer::GetXFIdFromIndex( sal_uInt16 nXFIndex )
+{
+ return EXC_XFLIST_INDEXBASE | nXFIndex;
+}
+
+sal_uInt32 XclExpXFBuffer::GetDefCellXFId()
+{
+ return GetXFIdFromIndex( EXC_XF_DEFAULTCELL );
+}
+
+const XclExpXF* XclExpXFBuffer::GetXFById( sal_uInt32 nXFId ) const
+{
+ return maXFList.GetRecord( nXFId ).get();
+}
+
+void XclExpXFBuffer::Finalize()
+{
+ for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
+ maXFList.GetRecord( nPos )->SetFinalColors();
+
+ sal_uInt32 nTotalCount = static_cast< sal_uInt32 >( maXFList.GetSize() );
+ sal_uInt32 nId;
+ maXFIndexVec.resize( nTotalCount, EXC_XF_DEFAULTCELL );
+ maStyleIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
+ maCellIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
+
+ XclExpBuiltInMap::const_iterator aBuiltInEnd = maBuiltInMap.end();
+ /* nMaxBuiltInXFId used to decide faster whether an XF record is
+ user-defined. If the current XF ID is greater than this value,
+ maBuiltInMap doesn't need to be searched. */
+ sal_uInt32 nMaxBuiltInXFId = maBuiltInMap.empty() ? 0 : maBuiltInMap.rbegin()->first;
+
+ // *** map all built-in XF records (cell and style) *** -------------------
+
+ // do not change XF order -> std::map<> iterates elements in ascending order
+ for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(); aIt != aBuiltInEnd; ++aIt )
+ AppendXFIndex( aIt->first );
+
+ // *** insert all user-defined style XF records, without reduce *** -------
+
+ sal_uInt32 nStyleXFCount = 0; // counts up to EXC_XF_MAXSTYLECOUNT limit
+
+ for( nId = 0; nId < nTotalCount; ++nId )
+ {
+ XclExpXFRef xXF = maXFList.GetRecord( nId );
+ if( xXF->IsStyleXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
+ {
+ if( nStyleXFCount < EXC_XF_MAXSTYLECOUNT )
+ {
+ // maximum count of styles not reached
+ AppendXFIndex( nId );
+ ++nStyleXFCount;
+ }
+ else
+ {
+ /* Maximum count of styles reached - do not append more
+ pointers to XFs; use default style XF instead; do not break
+ the loop to initialize all maXFIndexVec elements. */
+ maXFIndexVec[ nId ] = EXC_XF_DEFAULTSTYLE;
+ }
+ }
+ }
+
+ // *** insert all cell XF records *** -------------------------------------
+
+ // start position to search for equal inserted XF records
+ size_t nSearchStart = maSortedXFList.GetSize();
+
+ // break the loop if XF limit reached - maXFIndexVec is already initialized with default index
+ XclExpXFRef xDefCellXF = maXFList.GetRecord( EXC_XF_DEFAULTCELL );
+ for( nId = 0; (nId < nTotalCount) && (maSortedXFList.GetSize() < EXC_XF_MAXCOUNT); ++nId )
+ {
+ XclExpXFRef xXF = maXFList.GetRecord( nId );
+ if( xXF->IsCellXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
+ {
+ // try to find an XF record equal to *xXF, which is already inserted
+ sal_uInt16 nFoundIndex = EXC_XF_NOTFOUND;
+
+ // first try if it is equal to the default cell XF
+ if( xDefCellXF->Equals( *xXF ) )
+ {
+ nFoundIndex = EXC_XF_DEFAULTCELL;
+ }
+ else for( size_t nSearchPos = nSearchStart, nSearchEnd = maSortedXFList.GetSize();
+ (nSearchPos < nSearchEnd) && (nFoundIndex == EXC_XF_NOTFOUND); ++nSearchPos )
+ {
+ if( maSortedXFList.GetRecord( nSearchPos )->Equals( *xXF ) )
+ nFoundIndex = static_cast< sal_uInt16 >( nSearchPos );
+ }
+
+ if( nFoundIndex != EXC_XF_NOTFOUND )
+ // equal XF already in the list, use its resulting XF index
+ maXFIndexVec[ nId ] = nFoundIndex;
+ else
+ AppendXFIndex( nId );
+ }
+ }
+
+ sal_uInt16 nXmlStyleIndex = 0;
+ sal_uInt16 nXmlCellIndex = 0;
+
+ size_t nXFCount = maSortedXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
+ if( xXF->IsStyleXF() )
+ maStyleIndexes[ i ] = nXmlStyleIndex++;
+ else
+ maCellIndexes[ i ] = nXmlCellIndex++;
+ }
+}
+
+sal_uInt16 XclExpXFBuffer::GetXFIndex( sal_uInt32 nXFId ) const
+{
+ sal_uInt16 nXFIndex = EXC_XF_DEFAULTSTYLE;
+ if( nXFId >= EXC_XFLIST_INDEXBASE )
+ nXFIndex = static_cast< sal_uInt16 >( nXFId & ~EXC_XFLIST_INDEXBASE );
+ else if( nXFId < maXFIndexVec.size() )
+ nXFIndex = maXFIndexVec[ nXFId ];
+ return nXFIndex;
+}
+
+sal_Int32 XclExpXFBuffer::GetXmlStyleIndex( sal_uInt32 nXFIndex ) const
+{
+ DBG_ASSERT( nXFIndex < maStyleIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
+ if( nXFIndex > maStyleIndexes.size() )
+ return 0; // should be caught/debugged via above assert; return "valid" index.
+ return maStyleIndexes[ nXFIndex ];
+}
+
+sal_Int32 XclExpXFBuffer::GetXmlCellIndex( sal_uInt32 nXFIndex ) const
+{
+ DBG_ASSERT( nXFIndex < maCellIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
+ if( nXFIndex > maCellIndexes.size() )
+ return 0; // should be caught/debugged via above assert; return "valid" index.
+ return maCellIndexes[ nXFIndex ];
+}
+
+void XclExpXFBuffer::Save( XclExpStream& rStrm )
+{
+ // save all XF records contained in the maSortedXFList vector (sorted by XF index)
+ maSortedXFList.Save( rStrm );
+ // save all STYLE records
+ maStyleList.Save( rStrm );
+}
+
+static void lcl_GetCellCounts( const XclExpRecordList< XclExpXF >& rXFList, sal_Int32& rCells, sal_Int32& rStyles )
+{
+ rCells = 0;
+ rStyles = 0;
+ size_t nXFCount = rXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpRecordList< XclExpXF >::RecordRefType xXF = rXFList.GetRecord( i );
+ if( xXF->IsCellXF() )
+ ++rCells;
+ else if( xXF->IsStyleXF() )
+ ++rStyles;
+ }
+}
+
+void XclExpXFBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+
+ rStyleSheet->startElement( XML_fills,
+ XML_count, OString::valueOf( (sal_Int32) maFills.size() ).getStr(),
+ FSEND );
+ for( XclExpFillList::iterator aIt = maFills.begin(), aEnd = maFills.end();
+ aIt != aEnd; ++aIt )
+ {
+ aIt->SaveXml( rStrm );
+ }
+ rStyleSheet->endElement( XML_fills );
+
+ rStyleSheet->startElement( XML_borders,
+ XML_count, OString::valueOf( (sal_Int32) maBorders.size() ).getStr(),
+ FSEND );
+ for( XclExpBorderList::iterator aIt = maBorders.begin(), aEnd = maBorders.end();
+ aIt != aEnd; ++aIt )
+ {
+ aIt->SaveXml( rStrm );
+ }
+ rStyleSheet->endElement( XML_borders );
+
+ // save all XF records contained in the maSortedXFList vector (sorted by XF index)
+ sal_Int32 nCells, nStyles;
+ lcl_GetCellCounts( maSortedXFList, nCells, nStyles );
+
+ if( nStyles > 0 )
+ {
+ rStyleSheet->startElement( XML_cellStyleXfs,
+ XML_count, OString::valueOf( nStyles ).getStr(),
+ FSEND );
+ size_t nXFCount = maSortedXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
+ if( ! xXF->IsStyleXF() )
+ continue;
+ SaveXFXml( rStrm, *xXF );
+ }
+ rStyleSheet->endElement( XML_cellStyleXfs );
+ }
+
+ if( nCells > 0 )
+ {
+ rStyleSheet->startElement( XML_cellXfs,
+ XML_count, OString::valueOf( nCells ).getStr(),
+ FSEND );
+ size_t nXFCount = maSortedXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
+ if( ! xXF->IsCellXF() )
+ continue;
+ SaveXFXml( rStrm, *xXF );
+ }
+ rStyleSheet->endElement( XML_cellXfs );
+ }
+
+ // save all STYLE records
+ rStyleSheet->startElement( XML_cellStyles,
+ XML_count, OString::valueOf( (sal_Int32) maStyleList.GetSize() ).getStr(),
+ FSEND );
+ maStyleList.SaveXml( rStrm );
+ rStyleSheet->endElement( XML_cellStyles );
+}
+
+void XclExpXFBuffer::SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF )
+{
+ XclExpBorderList::iterator aBorderPos =
+ std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) );
+ DBG_ASSERT( aBorderPos != maBorders.end(), "XclExpXFBuffer::SaveXml - Invalid @borderId!" );
+ XclExpFillList::iterator aFillPos =
+ std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) );
+ DBG_ASSERT( aFillPos != maFills.end(), "XclExpXFBuffer::SaveXml - Invalid @fillId!" );
+
+ sal_Int32 nBorderId = 0, nFillId = 0;
+ if( aBorderPos != maBorders.end() )
+ nBorderId = std::distance( maBorders.begin(), aBorderPos );
+ if( aFillPos != maFills.end() )
+ nFillId = std::distance( maFills.begin(), aFillPos );
+
+ rXF.SetXmlIds( nBorderId, nFillId );
+ rXF.SaveXml( rStrm );
+}
+
+sal_uInt32 XclExpXFBuffer::FindXF( const ScPatternAttr& rPattern,
+ ULONG nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
+{
+ for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
+ if( maXFList.GetRecord( nPos )->Equals( rPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak ) )
+ return static_cast< sal_uInt32 >( nPos );
+ return EXC_XFID_NOTFOUND;
+}
+
+sal_uInt32 XclExpXFBuffer::FindXF( const SfxStyleSheetBase& rStyleSheet ) const
+{
+ for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
+ if( maXFList.GetRecord( nPos )->Equals( rStyleSheet ) )
+ return static_cast< sal_uInt32 >( nPos );
+ return EXC_XFID_NOTFOUND;
+}
+
+sal_uInt32 XclExpXFBuffer::FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel ) const
+{
+ for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(), aEnd = maBuiltInMap.end(); aIt != aEnd; ++aIt )
+ if( (aIt->second.mnStyleId == nStyleId) && (aIt->second.mnLevel == nLevel) )
+ return aIt->first;
+ return EXC_XFID_NOTFOUND;
+}
+
+sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
+ ULONG nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak )
+{
+ const ScPatternAttr* pDefPattern = GetDoc().GetDefPattern();
+ if( !pPattern )
+ pPattern = pDefPattern;
+
+ // special handling for default cell formatting
+ if( (pPattern == pDefPattern) && !bForceLineBreak &&
+ (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) &&
+ (nForceXclFont == EXC_FONT_NOTFOUND) )
+ {
+ // Is it the first try to insert the default cell format?
+ bool& rbPredefined = maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined;
+ if( rbPredefined )
+ {
+ // replace default cell pattern
+ XclExpXFRef xNewXF( new XclExpXF( GetRoot(), *pPattern, nScript ) );
+ maXFList.ReplaceRecord( xNewXF, EXC_XF_DEFAULTCELL );
+ rbPredefined = false;
+ }
+ return GetDefCellXFId();
+ }
+
+ sal_uInt32 nXFId = FindXF( *pPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak );
+ if( nXFId == EXC_XFID_NOTFOUND )
+ {
+ // not found - insert new cell XF
+ if( maXFList.GetSize() < EXC_XFLIST_HARDLIMIT )
+ {
+ maXFList.AppendNewRecord( new XclExpXF(
+ GetRoot(), *pPattern, nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak ) );
+ // do not set nXFId before the AppendNewRecord() call - it may insert 2 XFs (style+cell)
+ nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() - 1 );
+ }
+ else
+ {
+ // list full - fall back to default cell XF
+ nXFId = GetDefCellXFId();
+ }
+ }
+ return nXFId;
+}
+
+sal_uInt32 XclExpXFBuffer::InsertStyleXF( const SfxStyleSheetBase& rStyleSheet )
+{
+ // *** try, if it is a built-in style - create new XF or replace existing predefined XF ***
+
+ sal_uInt8 nStyleId, nLevel;
+ if( XclTools::GetBuiltInStyleId( nStyleId, nLevel, rStyleSheet.GetName() ) )
+ {
+ // try to find the built-in XF record (if already created in InsertDefaultRecords())
+ sal_uInt32 nXFId = FindBuiltInXF( nStyleId, nLevel );
+ if( nXFId == EXC_XFID_NOTFOUND )
+ {
+ // built-in style XF not yet created - do it now
+ XclExpXFRef xXF( new XclExpXF( GetRoot(), rStyleSheet ) );
+ nXFId = AppendBuiltInXFWithStyle( xXF, nStyleId, nLevel );
+ // this new XF record is not predefined
+ maBuiltInMap[ nXFId ].mbPredefined = false;
+ }
+ else
+ {
+ DBG_ASSERT( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::InsertStyleXF - built-in XF not found" );
+ // XF record still predefined? -> Replace with real XF
+ bool& rbPredefined = maBuiltInMap[ nXFId ].mbPredefined;
+ if( rbPredefined )
+ {
+ // replace predefined built-in style (ReplaceRecord() deletes old record)
+ maXFList.ReplaceRecord( XclExpXFRef( new XclExpXF( GetRoot(), rStyleSheet ) ), nXFId );
+ rbPredefined = false;
+ }
+ }
+
+ // STYLE already inserted? (may be not, i.e. for RowLevel/ColLevel or Hyperlink styles)
+ bool& rbHasStyleRec = maBuiltInMap[ nXFId ].mbHasStyleRec;
+ if( !rbHasStyleRec )
+ {
+ maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
+ rbHasStyleRec = true;
+ }
+
+ return nXFId;
+ }
+
+ // *** try to find the XF record of a user-defined style ***
+
+ sal_uInt32 nXFId = FindXF( rStyleSheet );
+ if( nXFId == EXC_XFID_NOTFOUND )
+ {
+ // not found - insert new style XF and STYLE
+ nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
+ if( nXFId < EXC_XFLIST_HARDLIMIT )
+ {
+ maXFList.AppendNewRecord( new XclExpXF( GetRoot(), rStyleSheet ) );
+ // create the STYLE record
+ if( rStyleSheet.GetName().Len() )
+ maStyleList.AppendNewRecord( new XclExpStyle( nXFId, rStyleSheet.GetName() ) );
+ }
+ else
+ // list full - fall back to default style XF
+ nXFId = GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
+ }
+ return nXFId;
+}
+
+void XclExpXFBuffer::InsertUserStyles()
+{
+ SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
+ for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
+ if( pStyleSheet->IsUserDefined() && !lclIsBuiltInStyle( pStyleSheet->GetName() ) )
+ InsertStyleXF( *pStyleSheet );
+}
+
+sal_uInt32 XclExpXFBuffer::AppendBuiltInXF( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
+{
+ sal_uInt32 nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
+ maXFList.AppendRecord( xXF );
+ XclExpBuiltInInfo& rInfo = maBuiltInMap[ nXFId ];
+ rInfo.mnStyleId = nStyleId;
+ rInfo.mnLevel = nLevel;
+ rInfo.mbPredefined = true;
+ return nXFId;
+}
+
+sal_uInt32 XclExpXFBuffer::AppendBuiltInXFWithStyle( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
+{
+ sal_uInt32 nXFId = AppendBuiltInXF( xXF, nStyleId, nLevel );
+ maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
+ maBuiltInMap[ nXFId ].mbHasStyleRec = true; // mark existing STYLE record
+ return nXFId;
+}
+
+static XclExpCellArea lcl_GetPatternFill_None()
+{
+ XclExpCellArea aFill;
+ aFill.mnPattern = EXC_PATT_NONE;
+ return aFill;
+}
+
+static XclExpCellArea lcl_GetPatternFill_Gray125()
+{
+ XclExpCellArea aFill;
+ aFill.mnPattern = EXC_PATT_12_5_PERC;
+ aFill.mnForeColor = 0;
+ aFill.mnBackColor = 0;
+ return aFill;
+}
+
+void XclExpXFBuffer::InsertDefaultRecords()
+{
+ maFills.push_back( lcl_GetPatternFill_None() );
+ maFills.push_back( lcl_GetPatternFill_Gray125() );
+
+ // index 0: default style
+ if( SfxStyleSheetBase* pDefStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) )
+ {
+ XclExpXFRef xDefStyle( new XclExpXF( GetRoot(), *pDefStyleSheet ) );
+ sal_uInt32 nXFId = AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
+ // mark this XF as not predefined, prevents overwriting
+ maBuiltInMap[ nXFId ].mbPredefined = false;
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpXFBuffer::InsertDefaultRecords - default style not found" );
+ XclExpXFRef xDefStyle( new XclExpDefaultXF( GetRoot(), false ) );
+ xDefStyle->SetAllUsedFlags( true );
+ AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
+ }
+
+ // index 1-14: RowLevel and ColLevel styles (without STYLE records)
+ XclExpDefaultXF aLevelStyle( GetRoot(), false );
+ // RowLevel_1, ColLevel_1
+ aLevelStyle.SetFont( 1 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 0 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 0 );
+ // RowLevel_2, ColLevel_2
+ aLevelStyle.SetFont( 2 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 1 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 1 );
+ // RowLevel_3, ColLevel_3 ... RowLevel_7, ColLevel_7
+ aLevelStyle.SetFont( 0 );
+ for( sal_uInt8 nLevel = 2; nLevel < EXC_STYLE_LEVELCOUNT; ++nLevel )
+ {
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, nLevel );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, nLevel );
+ }
+
+ // index 15: default hard cell format, placeholder to be able to add more built-in styles
+ maXFList.AppendNewRecord( new XclExpDefaultXF( GetRoot(), true ) );
+ maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined = true;
+
+ // index 16-20: other built-in styles
+ XclExpDefaultXF aFormatStyle( GetRoot(), false );
+ aFormatStyle.SetFont( 1 );
+ aFormatStyle.SetNumFmt( 43 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA );
+ aFormatStyle.SetNumFmt( 41 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA_0 );
+ aFormatStyle.SetNumFmt( 44 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY );
+ aFormatStyle.SetNumFmt( 42 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY_0 );
+ aFormatStyle.SetNumFmt( 9 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_PERCENT );
+
+ // other built-in style XF records (i.e. Hyperlink styles) are created on demand
+
+ /* Insert the real default hard cell format -> 0 is document default pattern.
+ Do it here (and not already above) to really have all built-in styles. */
+ Insert( 0, GetDefApiScript() );
+}
+
+void XclExpXFBuffer::AppendXFIndex( sal_uInt32 nXFId )
+{
+ DBG_ASSERT( nXFId < maXFIndexVec.size(), "XclExpXFBuffer::AppendXFIndex - XF ID out of range" );
+ maXFIndexVec[ nXFId ] = static_cast< sal_uInt16 >( maSortedXFList.GetSize() );
+ XclExpXFRef xXF = maXFList.GetRecord( nXFId );
+ AddBorderAndFill( *xXF );
+ maSortedXFList.AppendRecord( xXF );
+ DBG_ASSERT( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::AppendXFIndex - XF not found" );
+}
+
+void XclExpXFBuffer::AddBorderAndFill( const XclExpXF& rXF )
+{
+ if( std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) ) == maBorders.end() )
+ {
+ maBorders.push_back( rXF.GetBorderData() );
+ }
+
+ if( std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) ) == maFills.end() )
+ {
+ maFills.push_back( rXF.GetAreaData() );
+ }
+}
+
+// ============================================================================
+
+XclExpXmlStyleSheet::XclExpXmlStyleSheet( const XclExpRoot& rRoot )
+ : XclExpRoot( rRoot )
+{
+}
+
+void XclExpXmlStyleSheet::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr aStyleSheet = rStrm.CreateOutputStream(
+ OUString::createFromAscii( "xl/styles.xml" ),
+ OUString::createFromAscii( "styles.xml" ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" );
+ rStrm.PushStream( aStyleSheet );
+
+ aStyleSheet->startElement( XML_styleSheet,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSEND );
+
+ CreateRecord( EXC_ID_FORMATLIST )->SaveXml( rStrm );
+ CreateRecord( EXC_ID_FONTLIST )->SaveXml( rStrm );
+ CreateRecord( EXC_ID_XFLIST )->SaveXml( rStrm );
+ CreateRecord( EXC_ID_PALETTE )->SaveXml( rStrm );
+
+ aStyleSheet->endElement( XML_styleSheet );
+
+ rStrm.PopStream();
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
new file mode 100644
index 000000000000..b5ca318a91b4
--- /dev/null
+++ b/sc/source/filter/excel/xetable.cxx
@@ -0,0 +1,2579 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xetable.hxx"
+
+#include <map>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include "scitems.hxx"
+#include <svl/intitem.hxx>
+#include "document.hxx"
+#include "dociter.hxx"
+#include "olinetab.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "xehelper.hxx"
+#include "xecontent.hxx"
+#include "xeescher.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+// ============================================================================
+// Helper records for cell records
+// ============================================================================
+
+XclExpStringRec::XclExpStringRec( const XclExpRoot& rRoot, const String& rResult ) :
+ XclExpRecord( EXC_ID3_STRING ),
+ mxResult( XclExpStringHelper::CreateString( rRoot, rResult ) )
+{
+ DBG_ASSERT( (rRoot.GetBiff() <= EXC_BIFF5) || (mxResult->Len() > 0),
+ "XclExpStringRec::XclExpStringRec - empty result not allowed in BIFF8+" );
+ SetRecSize( mxResult->GetSize() );
+}
+
+void XclExpStringRec::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << *mxResult;
+}
+
+// Additional records for special formula ranges ==============================
+
+XclExpRangeFmlaBase::XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScAddress& rScPos ) :
+ XclExpRecord( nRecId, nRecSize ),
+ maXclRange( ScAddress::UNINITIALIZED ),
+ maBaseXclPos( ScAddress::UNINITIALIZED )
+{
+ maBaseXclPos.Set( static_cast< sal_uInt16 >( rScPos.Col() ), static_cast< sal_uInt16 >( rScPos.Row() ) );
+ maXclRange.maFirst = maXclRange.maLast = maBaseXclPos;
+}
+
+XclExpRangeFmlaBase::XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScRange& rScRange ) :
+ XclExpRecord( nRecId, nRecSize ),
+ maXclRange( ScAddress::UNINITIALIZED ),
+ maBaseXclPos( ScAddress::UNINITIALIZED )
+{
+ maXclRange.Set(
+ static_cast< sal_uInt16 >( rScRange.aStart.Col() ),
+ static_cast< sal_uInt16 >( rScRange.aStart.Row() ),
+ static_cast< sal_uInt16 >( rScRange.aEnd.Col() ),
+ static_cast< sal_uInt16 >( rScRange.aEnd.Row() ) );
+ maBaseXclPos = maXclRange.maFirst;
+}
+
+bool XclExpRangeFmlaBase::IsBasePos( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const
+{
+ return (maBaseXclPos.mnCol == nXclCol) && (maBaseXclPos.mnRow == nXclRow);
+}
+
+void XclExpRangeFmlaBase::Extend( const ScAddress& rScPos )
+{
+ sal_uInt16 nXclCol = static_cast< sal_uInt16 >( rScPos.Col() );
+ sal_uInt16 nXclRow = static_cast< sal_uInt16 >( rScPos.Row() );
+ maXclRange.maFirst.mnCol = ::std::min( maXclRange.maFirst.mnCol, nXclCol );
+ maXclRange.maFirst.mnRow = ::std::min( maXclRange.maFirst.mnRow, nXclRow );
+ maXclRange.maLast.mnCol = ::std::max( maXclRange.maLast.mnCol, nXclCol );
+ maXclRange.maLast.mnRow = ::std::max( maXclRange.maLast.mnRow, nXclRow );
+}
+
+void XclExpRangeFmlaBase::WriteRangeAddress( XclExpStream& rStrm ) const
+{
+ maXclRange.Write( rStrm, false );
+}
+
+// Array formulas =============================================================
+
+XclExpArray::XclExpArray( XclTokenArrayRef xTokArr, const ScRange& rScRange ) :
+ XclExpRangeFmlaBase( EXC_ID3_ARRAY, 14 + xTokArr->GetSize(), rScRange ),
+ mxTokArr( xTokArr )
+{
+}
+
+XclTokenArrayRef XclExpArray::CreateCellTokenArray( const XclExpRoot& rRoot ) const
+{
+ return rRoot.GetFormulaCompiler().CreateSpecialRefFormula( EXC_TOKID_EXP, maBaseXclPos );
+}
+
+bool XclExpArray::IsVolatile() const
+{
+ return mxTokArr->IsVolatile();
+}
+
+void XclExpArray::WriteBody( XclExpStream& rStrm )
+{
+ WriteRangeAddress( rStrm );
+ sal_uInt16 nFlags = EXC_ARRAY_DEFAULTFLAGS;
+ ::set_flag( nFlags, EXC_ARRAY_RECALC_ALWAYS, IsVolatile() );
+ rStrm << nFlags << sal_uInt32( 0 ) << *mxTokArr;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpArrayBuffer::XclExpArrayBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpArrayRef XclExpArrayBuffer::CreateArray( const ScTokenArray& rScTokArr, const ScRange& rScRange )
+{
+ const ScAddress& rScPos = rScRange.aStart;
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_MATRIX, rScTokArr, &rScPos );
+
+ DBG_ASSERT( maRecMap.find( rScPos ) == maRecMap.end(), "XclExpArrayBuffer::CreateArray - array exists already" );
+ XclExpArrayRef& rxRec = maRecMap[ rScPos ];
+ rxRec.reset( new XclExpArray( xTokArr, rScRange ) );
+ return rxRec;
+}
+
+XclExpArrayRef XclExpArrayBuffer::FindArray( const ScTokenArray& rScTokArr ) const
+{
+ XclExpArrayRef xRec;
+ // try to extract a matrix reference token
+ if( rScTokArr.GetLen() == 1 )
+ {
+ const formula::FormulaToken* pToken = rScTokArr.GetArray()[ 0 ];
+ if( pToken && (pToken->GetOpCode() == ocMatRef) )
+ {
+ const ScSingleRefData& rRef = static_cast<const ScToken*>(pToken)->GetSingleRef();
+ ScAddress aBasePos( rRef.nCol, rRef.nRow, GetCurrScTab() );
+ XclExpArrayMap::const_iterator aIt = maRecMap.find( aBasePos );
+ if( aIt != maRecMap.end() )
+ xRec = aIt->second;
+ }
+ }
+ return xRec;
+}
+
+// Shared formulas ============================================================
+
+XclExpShrfmla::XclExpShrfmla( XclTokenArrayRef xTokArr, const ScAddress& rScPos ) :
+ XclExpRangeFmlaBase( EXC_ID_SHRFMLA, 10 + xTokArr->GetSize(), rScPos ),
+ mxTokArr( xTokArr ),
+ mnUsedCount( 1 )
+{
+}
+
+void XclExpShrfmla::ExtendRange( const ScAddress& rScPos )
+{
+ Extend( rScPos );
+ ++mnUsedCount;
+}
+
+XclTokenArrayRef XclExpShrfmla::CreateCellTokenArray( const XclExpRoot& rRoot ) const
+{
+ return rRoot.GetFormulaCompiler().CreateSpecialRefFormula( EXC_TOKID_EXP, maBaseXclPos );
+}
+
+bool XclExpShrfmla::IsVolatile() const
+{
+ return mxTokArr->IsVolatile();
+}
+
+void XclExpShrfmla::WriteBody( XclExpStream& rStrm )
+{
+ WriteRangeAddress( rStrm );
+ rStrm << sal_uInt8( 0 ) << mnUsedCount << *mxTokArr;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpShrfmlaBuffer::XclExpShrfmlaBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpShrfmlaRef XclExpShrfmlaBuffer::CreateOrExtendShrfmla(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos )
+{
+ XclExpShrfmlaRef xRec;
+ if( const ScTokenArray* pShrdScTokArr = XclTokenArrayHelper::GetSharedFormula( GetRoot(), rScTokArr ) )
+ {
+ XclExpShrfmlaMap::iterator aIt = maRecMap.find( pShrdScTokArr );
+ if( aIt == maRecMap.end() )
+ {
+ // create a new record
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_SHARED, *pShrdScTokArr, &rScPos );
+ xRec.reset( new XclExpShrfmla( xTokArr, rScPos ) );
+ maRecMap[ pShrdScTokArr ] = xRec;
+ }
+ else
+ {
+ // extend existing record
+ DBG_ASSERT( aIt->second, "XclExpShrfmlaBuffer::CreateOrExtendShrfmla - missing record" );
+ xRec = aIt->second;
+ xRec->ExtendRange( rScPos );
+ }
+ }
+ return xRec;
+}
+
+// Multiple operations ========================================================
+
+XclExpTableop::XclExpTableop( const ScAddress& rScPos,
+ const XclMultipleOpRefs& rRefs, sal_uInt8 nScMode ) :
+ XclExpRangeFmlaBase( EXC_ID3_TABLEOP, 16, rScPos ),
+ mnLastAppXclCol( static_cast< sal_uInt16 >( rScPos.Col() ) ),
+ mnColInpXclCol( static_cast< sal_uInt16 >( rRefs.maColFirstScPos.Col() ) ),
+ mnColInpXclRow( static_cast< sal_uInt16 >( rRefs.maColFirstScPos.Row() ) ),
+ mnRowInpXclCol( static_cast< sal_uInt16 >( rRefs.maRowFirstScPos.Col() ) ),
+ mnRowInpXclRow( static_cast< sal_uInt16 >( rRefs.maRowFirstScPos.Row() ) ),
+ mnScMode( nScMode ),
+ mbValid( false )
+{
+}
+
+bool XclExpTableop::TryExtend( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs )
+{
+ sal_uInt16 nXclCol = static_cast< sal_uInt16 >( rScPos.Col() );
+ sal_uInt16 nXclRow = static_cast< sal_uInt16 >( rScPos.Row() );
+
+ bool bOk = IsAppendable( nXclCol, nXclRow );
+ if( bOk )
+ {
+ SCCOL nFirstScCol = static_cast< SCCOL >( maXclRange.maFirst.mnCol );
+ SCROW nFirstScRow = static_cast< SCROW >( maXclRange.maFirst.mnRow );
+ SCCOL nColInpScCol = static_cast< SCCOL >( mnColInpXclCol );
+ SCROW nColInpScRow = static_cast< SCROW >( mnColInpXclRow );
+ SCCOL nRowInpScCol = static_cast< SCCOL >( mnRowInpXclCol );
+ SCROW nRowInpScRow = static_cast< SCROW >( mnRowInpXclRow );
+
+ bOk = ((mnScMode == 2) == rRefs.mbDblRefMode) &&
+ (rScPos.Tab() == rRefs.maFmlaScPos.Tab()) &&
+ (nColInpScCol == rRefs.maColFirstScPos.Col()) &&
+ (nColInpScRow == rRefs.maColFirstScPos.Row()) &&
+ (rScPos.Tab() == rRefs.maColFirstScPos.Tab()) &&
+ (rScPos.Tab() == rRefs.maColRelScPos.Tab());
+
+ if( bOk ) switch( mnScMode )
+ {
+ case 0:
+ bOk = (rScPos.Col() == rRefs.maFmlaScPos.Col()) &&
+ (nFirstScRow == rRefs.maFmlaScPos.Row() + 1) &&
+ (nFirstScCol == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row());
+ break;
+ case 1:
+ bOk = (nFirstScCol == rRefs.maFmlaScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row()) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col()) &&
+ (nFirstScRow == rRefs.maColRelScPos.Row() + 1);
+ break;
+ case 2:
+ bOk = (nFirstScCol == rRefs.maFmlaScPos.Col() + 1) &&
+ (nFirstScRow == rRefs.maFmlaScPos.Row() + 1) &&
+ (nFirstScCol == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row()) &&
+ (nRowInpScCol == rRefs.maRowFirstScPos.Col()) &&
+ (nRowInpScRow == rRefs.maRowFirstScPos.Row()) &&
+ (rScPos.Tab() == rRefs.maRowFirstScPos.Tab()) &&
+ (rScPos.Col() == rRefs.maRowRelScPos.Col()) &&
+ (nFirstScRow == rRefs.maRowRelScPos.Row() + 1) &&
+ (rScPos.Tab() == rRefs.maRowRelScPos.Tab());
+ break;
+ default:
+ bOk = false;
+ }
+
+ if( bOk )
+ {
+ // extend the cell range
+ DBG_ASSERT( IsAppendable( nXclCol, nXclRow ), "XclExpTableop::TryExtend - wrong cell address" );
+ Extend( rScPos );
+ mnLastAppXclCol = nXclCol;
+ }
+ }
+
+ return bOk;
+}
+
+void XclExpTableop::Finalize()
+{
+ // is the range complete? (last appended cell is in last column)
+ mbValid = maXclRange.maLast.mnCol == mnLastAppXclCol;
+ // if last row is incomplete, try to shorten the used range
+ if( !mbValid && (maXclRange.maFirst.mnRow < maXclRange.maLast.mnRow) )
+ {
+ --maXclRange.maLast.mnRow;
+ mbValid = true;
+ }
+
+ // check if referred cells are outside of own range
+ if( mbValid ) switch( mnScMode )
+ {
+ case 0:
+ mbValid = (mnColInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnColInpXclRow < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow);
+ break;
+ case 1:
+ mbValid = (mnColInpXclCol < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnColInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow);
+ break;
+ case 2:
+ mbValid = ((mnColInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnColInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow)) &&
+ ((mnRowInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnRowInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnRowInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnRowInpXclRow > maXclRange.maLast.mnRow));
+ break;
+ }
+}
+
+XclTokenArrayRef XclExpTableop::CreateCellTokenArray( const XclExpRoot& rRoot ) const
+{
+ XclExpFormulaCompiler& rFmlaComp = rRoot.GetFormulaCompiler();
+ return mbValid ?
+ rFmlaComp.CreateSpecialRefFormula( EXC_TOKID_TBL, maBaseXclPos ) :
+ rFmlaComp.CreateErrorFormula( EXC_ERR_NA );
+}
+
+bool XclExpTableop::IsVolatile() const
+{
+ return true;
+}
+
+void XclExpTableop::Save( XclExpStream& rStrm )
+{
+ if( mbValid )
+ XclExpRangeFmlaBase::Save( rStrm );
+}
+
+bool XclExpTableop::IsAppendable( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const
+{
+ return ((nXclCol == mnLastAppXclCol + 1) && (nXclRow == maXclRange.maFirst.mnRow)) ||
+ ((nXclCol == mnLastAppXclCol + 1) && (nXclCol <= maXclRange.maLast.mnCol) && (nXclRow == maXclRange.maLast.mnRow)) ||
+ ((mnLastAppXclCol == maXclRange.maLast.mnCol) && (nXclCol == maXclRange.maFirst.mnCol) && (nXclRow == maXclRange.maLast.mnRow + 1));
+}
+
+void XclExpTableop::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nFlags = EXC_TABLEOP_DEFAULTFLAGS;
+ ::set_flag( nFlags, EXC_TABLEOP_RECALC_ALWAYS, IsVolatile() );
+ switch( mnScMode )
+ {
+ case 1: ::set_flag( nFlags, EXC_TABLEOP_ROW ); break;
+ case 2: ::set_flag( nFlags, EXC_TABLEOP_BOTH ); break;
+ }
+
+ WriteRangeAddress( rStrm );
+ rStrm << nFlags;
+ if( mnScMode == 2 )
+ rStrm << mnRowInpXclRow << mnRowInpXclCol << mnColInpXclRow << mnColInpXclCol;
+ else
+ rStrm << mnColInpXclRow << mnColInpXclCol << sal_uInt32( 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpTableopBuffer::XclExpTableopBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpTableopRef XclExpTableopBuffer::CreateOrExtendTableop(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos )
+{
+ XclExpTableopRef xRec;
+
+ // try to extract cell references of a multiple operations formula
+ XclMultipleOpRefs aRefs;
+ if( XclTokenArrayHelper::GetMultipleOpRefs( aRefs, rScTokArr ) )
+ {
+ // try to find an existing TABLEOP record for this cell position
+ for( size_t nPos = 0, nSize = maTableopList.GetSize(); !xRec && (nPos < nSize); ++nPos )
+ {
+ XclExpTableopRef xTempRec = maTableopList.GetRecord( nPos );
+ if( xTempRec->TryExtend( rScPos, aRefs ) )
+ xRec = xTempRec;
+ }
+
+ // no record found, or found record not extensible
+ if( !xRec )
+ xRec = TryCreate( rScPos, aRefs );
+ }
+
+ return xRec;
+}
+
+void XclExpTableopBuffer::Finalize()
+{
+ for( size_t nPos = 0, nSize = maTableopList.GetSize(); nPos < nSize; ++nPos )
+ maTableopList.GetRecord( nPos )->Finalize();
+}
+
+XclExpTableopRef XclExpTableopBuffer::TryCreate( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs )
+{
+ sal_uInt8 nScMode = 0;
+ bool bOk = (rScPos.Tab() == rRefs.maFmlaScPos.Tab()) &&
+ (rScPos.Tab() == rRefs.maColFirstScPos.Tab()) &&
+ (rScPos.Tab() == rRefs.maColRelScPos.Tab());
+
+ if( bOk )
+ {
+ if( rRefs.mbDblRefMode )
+ {
+ nScMode = 2;
+ bOk = (rScPos.Col() == rRefs.maFmlaScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row() + 1) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row()) &&
+ (rScPos.Tab() == rRefs.maRowFirstScPos.Tab()) &&
+ (rScPos.Col() == rRefs.maRowRelScPos.Col()) &&
+ (rScPos.Row() == rRefs.maRowRelScPos.Row() + 1) &&
+ (rScPos.Tab() == rRefs.maRowRelScPos.Tab());
+ }
+ else if( (rScPos.Col() == rRefs.maFmlaScPos.Col()) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row() + 1) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row()) )
+ {
+ nScMode = 0;
+ }
+ else if( (rScPos.Col() == rRefs.maFmlaScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row()) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col()) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row() + 1) )
+ {
+ nScMode = 1;
+ }
+ else
+ {
+ bOk = false;
+ }
+ }
+
+ XclExpTableopRef xRec;
+ if( bOk )
+ {
+ xRec.reset( new XclExpTableop( rScPos, rRefs, nScMode ) );
+ maTableopList.AppendRecord( xRec );
+ }
+
+ return xRec;
+}
+
+// ============================================================================
+// Cell records
+// ============================================================================
+
+XclExpCellBase::XclExpCellBase(
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos ) :
+ XclExpRecord( nRecId, nContSize + 4 ),
+ maXclPos( rXclPos )
+{
+}
+
+bool XclExpCellBase::IsMultiLineText() const
+{
+ return false;
+}
+
+bool XclExpCellBase::TryMerge( const XclExpCellBase& /*rCell*/ )
+{
+ return false;
+}
+
+void XclExpCellBase::GetBlankXFIndexes( ScfUInt16Vec& /*rXFIndexes*/ ) const
+{
+ // default: do nothing
+}
+
+void XclExpCellBase::RemoveUnusedBlankCells( const ScfUInt16Vec& /*rXFIndexes*/ )
+{
+ // default: do nothing
+}
+
+// Single cell records ========================================================
+
+XclExpSingleCellBase::XclExpSingleCellBase(
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos, sal_uInt32 nXFId ) :
+ XclExpCellBase( nRecId, 2, rXclPos ),
+ maXFId( nXFId ),
+ mnContSize( nContSize )
+{
+}
+
+XclExpSingleCellBase::XclExpSingleCellBase( const XclExpRoot& rRoot,
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uInt32 nForcedXFId ) :
+ XclExpCellBase( nRecId, 2, rXclPos ),
+ maXFId( nForcedXFId ),
+ mnContSize( nContSize )
+{
+ if( GetXFId() == EXC_XFID_NOTFOUND )
+ SetXFId( rRoot.GetXFBuffer().Insert( pPattern, nScript ) );
+}
+
+sal_uInt16 XclExpSingleCellBase::GetLastXclCol() const
+{
+ return GetXclCol();
+}
+
+sal_uInt32 XclExpSingleCellBase::GetFirstXFId() const
+{
+ return GetXFId();
+}
+
+bool XclExpSingleCellBase::IsEmpty() const
+{
+ return false;
+}
+
+void XclExpSingleCellBase::ConvertXFIndexes( const XclExpRoot& rRoot )
+{
+ maXFId.ConvertXFIndex( rRoot );
+}
+
+void XclExpSingleCellBase::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
+ AddRecSize( mnContSize );
+ XclExpCellBase::Save( rStrm );
+}
+
+void XclExpSingleCellBase::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << GetXclRow() << GetXclCol() << maXFId.mnXFIndex;
+ WriteContents( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpNumberCell, 256, 256 )
+
+XclExpNumberCell::XclExpNumberCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, double fValue ) :
+ // #i41210# always use latin script for number cells - may look wrong for special number formats...
+ XclExpSingleCellBase( rRoot, EXC_ID3_NUMBER, 8, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
+ mfValue( fValue )
+{
+}
+
+static OString lcl_GetStyleId( XclExpXmlStream& rStrm, sal_uInt32 nXFIndex )
+{
+ return OString::valueOf( rStrm.GetRoot().GetXFBuffer()
+ .GetXmlCellIndex( nXFIndex ) );
+}
+
+static OString lcl_GetStyleId( XclExpXmlStream& rStrm, const XclExpCellBase& rCell )
+{
+ sal_uInt32 nXFId = rCell.GetFirstXFId();
+ sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( nXFId );
+ return lcl_GetStyleId( rStrm, nXFIndex );
+}
+
+void XclExpNumberCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, "n",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( mfValue );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpNumberCell::WriteContents( XclExpStream& rStrm )
+{
+ rStrm << mfValue;
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpBooleanCell, 256, 256 )
+
+XclExpBooleanCell::XclExpBooleanCell(
+ const XclExpRoot rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, bool bValue ) :
+ // #i41210# always use latin script for boolean cells
+ XclExpSingleCellBase( rRoot, EXC_ID3_BOOLERR, 2, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
+ mbValue( bValue )
+{
+}
+
+void XclExpBooleanCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, "b",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( mbValue ? "1" : "0" );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpBooleanCell::WriteContents( XclExpStream& rStrm )
+{
+ rStrm << sal_uInt16( mbValue ? 1 : 0 ) << EXC_BOOLERR_BOOL;
+}
+
+// ----------------------------------------------------------------------------
+
+//UNUSED2009-05 IMPL_FIXEDMEMPOOL_NEWDEL( XclExpErrorCell, 256, 256 )
+//UNUSED2009-05
+//UNUSED2009-05 XclExpErrorCell::XclExpErrorCell(
+//UNUSED2009-05 const XclExpRoot rRoot, const XclAddress& rXclPos,
+//UNUSED2009-05 const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, sal_uInt8 nErrCode ) :
+//UNUSED2009-05 // #i41210# always use latin script for error cells
+//UNUSED2009-05 XclExpSingleCellBase( rRoot, EXC_ID3_BOOLERR, 2, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
+//UNUSED2009-05 mnErrCode( nErrCode )
+//UNUSED2009-05 {
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 void XclExpErrorCell::SaveXml( XclExpXmlStream& rStrm )
+//UNUSED2009-05 {
+//UNUSED2009-05 sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+//UNUSED2009-05 rWorksheet->startElement( XML_c,
+//UNUSED2009-05 XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+//UNUSED2009-05 XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+//UNUSED2009-05 XML_t, "e",
+//UNUSED2009-05 // OOXTODO: XML_cm, XML_vm, XML_ph
+//UNUSED2009-05 FSEND );
+//UNUSED2009-05 rWorksheet->startElement( XML_v, FSEND );
+//UNUSED2009-05 rWorksheet->write( (sal_Int32) mnErrCode );
+//UNUSED2009-05 rWorksheet->endElement( XML_v );
+//UNUSED2009-05 rWorksheet->endElement( XML_c );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 void XclExpErrorCell::WriteContents( XclExpStream& rStrm )
+//UNUSED2009-05 {
+//UNUSED2009-05 rStrm << mnErrCode << EXC_BOOLERR_ERROR;
+//UNUSED2009-05 }
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpLabelCell, 256, 256 )
+
+XclExpLabelCell::XclExpLabelCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, const ScStringCell& rCell ) :
+ XclExpSingleCellBase( EXC_ID3_LABEL, 0, rXclPos, nForcedXFId )
+{
+ sal_uInt16 nMaxLen = (rRoot.GetBiff() == EXC_BIFF8) ? EXC_STR_MAXLEN : EXC_LABEL_MAXLEN;
+ XclExpStringRef xText = XclExpStringHelper::CreateCellString( rRoot, rCell, pPattern, EXC_STR_DEFAULT, nMaxLen );
+ Init( rRoot, pPattern, xText );
+}
+
+XclExpLabelCell::XclExpLabelCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScEditCell& rCell, XclExpHyperlinkHelper& rLinkHelper ) :
+ XclExpSingleCellBase( EXC_ID3_LABEL, 0, rXclPos, nForcedXFId )
+{
+ sal_uInt16 nMaxLen = (rRoot.GetBiff() == EXC_BIFF8) ? EXC_STR_MAXLEN : EXC_LABEL_MAXLEN;
+ XclExpStringRef xText = XclExpStringHelper::CreateCellString( rRoot, rCell, pPattern, rLinkHelper, EXC_STR_DEFAULT, nMaxLen );
+ Init( rRoot, pPattern, xText );
+}
+
+bool XclExpLabelCell::IsMultiLineText() const
+{
+ return mbLineBreak || mxText->IsWrapped();
+}
+
+void XclExpLabelCell::Init( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, XclExpStringRef xText )
+{
+ DBG_ASSERT( xText.is() && xText->Len(), "XclExpLabelCell::XclExpLabelCell - empty string passed" );
+ mxText = xText;
+ mnSstIndex = 0;
+
+ // create the cell format
+ sal_uInt16 nXclFont = mxText->RemoveLeadingFont();
+ if( GetXFId() == EXC_XFID_NOTFOUND )
+ {
+ DBG_ASSERT( nXclFont != EXC_FONT_NOTFOUND, "XclExpLabelCell::Init - leading font not found" );
+ bool bForceLineBreak = mxText->IsWrapped();
+ SetXFId( rRoot.GetXFBuffer().InsertWithFont( pPattern, ApiScriptType::WEAK, nXclFont, bForceLineBreak ) );
+ }
+
+ // get auto-wrap attribute from cell format
+ const XclExpXF* pXF = rRoot.GetXFBuffer().GetXFById( GetXFId() );
+ mbLineBreak = pXF && pXF->GetAlignmentData().mbLineBreak;
+
+ // initialize the record contents
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF5:
+ // BIFF5-BIFF7: create a LABEL or RSTRING record
+ DBG_ASSERT( mxText->Len() <= EXC_LABEL_MAXLEN, "XclExpLabelCell::XclExpLabelCell - string too long" );
+ SetContSize( mxText->GetSize() );
+ // formatted string is exported in an RSTRING record
+ if( mxText->IsRich() )
+ {
+ DBG_ASSERT( mxText->GetFormatsCount() <= EXC_LABEL_MAXLEN, "XclExpLabelCell::WriteContents - too many formats" );
+ mxText->LimitFormatCount( EXC_LABEL_MAXLEN );
+ SetRecId( EXC_ID_RSTRING );
+ SetContSize( GetContSize() + 1 + 2 * mxText->GetFormatsCount() );
+ }
+ break;
+ case EXC_BIFF8:
+ // BIFF8+: create a LABELSST record
+ mnSstIndex = rRoot.GetSst().Insert( xText );
+ SetRecId( EXC_ID_LABELSST );
+ SetContSize( 4 );
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpLabelCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, "s",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( (sal_Int32) mnSstIndex );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpLabelCell::WriteContents( XclExpStream& rStrm )
+{
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF5:
+ rStrm << *mxText;
+ if( mxText->IsRich() )
+ {
+ rStrm << static_cast< sal_uInt8 >( mxText->GetFormatsCount() );
+ mxText->WriteFormats( rStrm );
+ }
+ break;
+ case EXC_BIFF8:
+ rStrm << mnSstIndex;
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpFormulaCell, 256, 256 )
+
+XclExpFormulaCell::XclExpFormulaCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScFormulaCell& rScFmlaCell,
+ XclExpArrayBuffer& rArrayBfr,
+ XclExpShrfmlaBuffer& rShrfmlaBfr,
+ XclExpTableopBuffer& rTableopBfr ) :
+ XclExpSingleCellBase( EXC_ID2_FORMULA, 0, rXclPos, nForcedXFId ),
+ mrScFmlaCell( const_cast< ScFormulaCell& >( rScFmlaCell ) )
+{
+ // *** Find result number format overwriting cell number format *** -------
+
+ if( GetXFId() == EXC_XFID_NOTFOUND )
+ {
+ SvNumberFormatter& rFormatter = rRoot.GetFormatter();
+ XclExpNumFmtBuffer& rNumFmtBfr = rRoot.GetNumFmtBuffer();
+
+ // current cell number format
+ ULONG nScNumFmt = pPattern ?
+ GETITEMVALUE( pPattern->GetItemSet(), SfxUInt32Item, ATTR_VALUE_FORMAT, ULONG ) :
+ rNumFmtBfr.GetStandardFormat();
+
+ // alternative number format passed to XF buffer
+ ULONG nAltScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
+ /* #73420# Xcl doesn't know Boolean number formats, we write
+ "TRUE";"FALSE" (language dependent). Don't do it for automatic
+ formula formats, because Excel gets them right. */
+ /* #i8640# Don't set text format, if we have string results. */
+ short nFormatType = mrScFmlaCell.GetFormatType();
+ if( ((nScNumFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0) &&
+ (nFormatType != NUMBERFORMAT_LOGICAL) &&
+ (nFormatType != NUMBERFORMAT_TEXT) )
+ nAltScNumFmt = mrScFmlaCell.GetStandardFormat( rFormatter, nScNumFmt );
+ /* #73420# If cell number format is Boolean and automatic formula
+ format is Boolean don't write that ugly special format. */
+ else if( (nFormatType == NUMBERFORMAT_LOGICAL) &&
+ (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) )
+ nAltScNumFmt = rNumFmtBfr.GetStandardFormat();
+
+ // #i41420# find script type according to result type (always latin for numeric results)
+ sal_Int16 nScript = ApiScriptType::LATIN;
+ bool bForceLineBreak = false;
+ if( nFormatType == NUMBERFORMAT_TEXT )
+ {
+ String aResult;
+ mrScFmlaCell.GetString( aResult );
+ bForceLineBreak = mrScFmlaCell.IsMultilineResult();
+ nScript = XclExpStringHelper::GetLeadingScriptType( rRoot, aResult );
+ }
+ SetXFId( rRoot.GetXFBuffer().InsertWithNumFmt( pPattern, nScript, nAltScNumFmt, bForceLineBreak ) );
+ }
+
+ // *** Convert the formula token array *** --------------------------------
+
+ ScAddress aScPos( static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), rRoot.GetCurrScTab() );
+ const ScTokenArray& rScTokArr = *mrScFmlaCell.GetCode();
+
+ // first try to create multiple operations
+ mxAddRec = rTableopBfr.CreateOrExtendTableop( rScTokArr, aScPos );
+
+ // no multiple operation found - try to create matrix formula
+ if( !mxAddRec ) switch( static_cast< ScMatrixMode >( mrScFmlaCell.GetMatrixFlag() ) )
+ {
+ case MM_FORMULA:
+ {
+ // origin of the matrix - find the used matrix range
+ SCCOL nMatWidth;
+ SCROW nMatHeight;
+ mrScFmlaCell.GetMatColsRows( nMatWidth, nMatHeight );
+ DBG_ASSERT( nMatWidth && nMatHeight, "XclExpFormulaCell::XclExpFormulaCell - empty matrix" );
+ ScRange aMatScRange( aScPos );
+ ScAddress& rMatEnd = aMatScRange.aEnd;
+ rMatEnd.IncCol( static_cast< SCsCOL >( nMatWidth - 1 ) );
+ rMatEnd.IncRow( static_cast< SCsROW >( nMatHeight - 1 ) );
+ // reduce to valid range (range keeps valid, because start position IS valid)
+ rRoot.GetAddressConverter().ValidateRange( aMatScRange, true );
+ // create the ARRAY record
+ mxAddRec = rArrayBfr.CreateArray( rScTokArr, aMatScRange );
+ }
+ break;
+ case MM_REFERENCE:
+ {
+ // other formula cell covered by a matrix - find the ARRAY record
+ mxAddRec = rArrayBfr.FindArray( rScTokArr );
+ // should always be found, if Calc document is not broken
+ DBG_ASSERT( mxAddRec.is(), "XclExpFormulaCell::XclExpFormulaCell - no matrix found" );
+ }
+ break;
+ default:;
+ }
+
+ // no matrix found - try to create shared formula
+ if( !mxAddRec )
+ mxAddRec = rShrfmlaBfr.CreateOrExtendShrfmla( rScTokArr, aScPos );
+
+ // no shared formula found - create a simple cell formula
+ if( !mxAddRec )
+ mxTokArr = rRoot.GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CELL, rScTokArr, &aScPos );
+}
+
+void XclExpFormulaCell::Save( XclExpStream& rStrm )
+{
+ // create token array for FORMULA cells with additional record
+ if( mxAddRec.is() )
+ mxTokArr = mxAddRec->CreateCellTokenArray( rStrm.GetRoot() );
+
+ // FORMULA record itself
+ DBG_ASSERT( mxTokArr.is(), "XclExpFormulaCell::Save - missing token array" );
+ if( !mxTokArr )
+ mxTokArr = rStrm.GetRoot().GetFormulaCompiler().CreateErrorFormula( EXC_ERR_NA );
+ SetContSize( 16 + mxTokArr->GetSize() );
+ XclExpSingleCellBase::Save( rStrm );
+
+ // additional record (ARRAY, SHRFMLA, or TABLEOP), only for first FORMULA record
+ if( mxAddRec.is() && mxAddRec->IsBasePos( GetXclCol(), GetXclRow() ) )
+ mxAddRec->Save( rStrm );
+
+ // STRING record for string result
+ if( mxStringRec.is() )
+ mxStringRec->Save( rStrm );
+}
+
+static const char* lcl_GetErrorString( USHORT nScErrCode )
+{
+ sal_uInt8 nXclErrCode = XclTools::GetXclErrorCode( nScErrCode );
+ switch( nXclErrCode )
+ {
+ case EXC_ERR_NULL: return "#NULL!";
+ case EXC_ERR_DIV0: return "#DIV/0!";
+ case EXC_ERR_VALUE: return "#VALUE!";
+ case EXC_ERR_REF: return "#REF!";
+ case EXC_ERR_NAME: return "#NAME?";
+ case EXC_ERR_NUM: return "#NUM!";
+ case EXC_ERR_NA:
+ default: return "#N/A";
+ }
+}
+
+static void lcl_GetFormulaInfo( ScFormulaCell& rCell, const char** pType, OUString& rValue)
+{
+ switch( rCell.GetFormatType() )
+ {
+ case NUMBERFORMAT_NUMBER:
+ {
+ // either value or error code
+ USHORT nScErrCode = rCell.GetErrCode();
+ if( nScErrCode )
+ {
+ *pType = "e";
+ rValue = XclXmlUtils::ToOUString( lcl_GetErrorString( nScErrCode ) );
+ }
+ else
+ {
+ *pType = "n";
+ rValue = OUString::valueOf( rCell.GetValue() );
+ }
+ }
+ break;
+
+ case NUMBERFORMAT_TEXT:
+ {
+ *pType = "str";
+ String aResult;
+ rCell.GetString( aResult );
+ rValue = XclXmlUtils::ToOUString( aResult );
+ }
+ break;
+
+ case NUMBERFORMAT_LOGICAL:
+ {
+ *pType = "b";
+ rValue = XclXmlUtils::ToOUString( rCell.GetValue() == 0.0 ? "0" : "1" );
+ }
+ break;
+
+ default:
+ {
+ *pType = "inlineStr";
+ String aResult;
+ rCell.GetString( aResult );
+ rValue = XclXmlUtils::ToOUString( aResult );
+ }
+ break;
+ }
+}
+
+void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ const char* sType = NULL;
+ OUString sValue;
+
+ lcl_GetFormulaInfo( mrScFmlaCell, &sType, sValue );
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, sType,
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+
+ rWorksheet->startElement( XML_f,
+ // OOXTODO: XML_t, ST_CellFormulaType
+ XML_aca, XclXmlUtils::ToPsz( mxTokArr->IsVolatile() || (mxAddRec.is() && mxAddRec->IsVolatile()) ),
+ // OOXTODO: XML_ref, ST_Ref
+ // OOXTODO: XML_dt2D, bool
+ // OOXTODO: XML_dtr, bool
+ // OOXTODO: XML_del1, bool
+ // OOXTODO: XML_del2, bool
+ // OOXTODO: XML_r1, ST_CellRef
+ // OOXTODO: XML_r2, ST_CellRef
+ // OOXTODO: XML_ca, bool
+ // OOXTODO: XML_si, uint
+ // OOXTODO: XML_bx bool
+ FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *mrScFmlaCell.GetDocument(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode() ) );
+ rWorksheet->endElement( XML_f );
+ if( strcmp( sType, "inlineStr" ) == 0 )
+ {
+ rWorksheet->startElement( XML_is, FSEND );
+ rWorksheet->startElement( XML_t, FSEND );
+ rWorksheet->writeEscaped( sValue );
+ rWorksheet->endElement( XML_t );
+ rWorksheet->endElement( XML_is );
+ }
+ else
+ {
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->writeEscaped( sValue );
+ rWorksheet->endElement( XML_v );
+ }
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpFormulaCell::WriteContents( XclExpStream& rStrm )
+{
+ // result of the formula
+ switch( mrScFmlaCell.GetFormatType() )
+ {
+ case NUMBERFORMAT_NUMBER:
+ {
+ // either value or error code
+ USHORT nScErrCode = mrScFmlaCell.GetErrCode();
+ if( nScErrCode )
+ rStrm << EXC_FORMULA_RES_ERROR << sal_uInt8( 0 )
+ << XclTools::GetXclErrorCode( nScErrCode )
+ << sal_uInt8( 0 ) << sal_uInt16( 0 )
+ << sal_uInt16( 0xFFFF );
+ else
+ rStrm << mrScFmlaCell.GetValue();
+ }
+ break;
+
+ case NUMBERFORMAT_TEXT:
+ {
+ String aResult;
+ mrScFmlaCell.GetString( aResult );
+ if( aResult.Len() || (rStrm.GetRoot().GetBiff() <= EXC_BIFF5) )
+ {
+ rStrm << EXC_FORMULA_RES_STRING;
+ mxStringRec.reset( new XclExpStringRec( rStrm.GetRoot(), aResult ) );
+ }
+ else
+ rStrm << EXC_FORMULA_RES_EMPTY; // BIFF8 only
+ rStrm << sal_uInt8( 0 ) << sal_uInt32( 0 ) << sal_uInt16( 0xFFFF );
+ }
+ break;
+
+ case NUMBERFORMAT_LOGICAL:
+ {
+ sal_uInt8 nXclValue = (mrScFmlaCell.GetValue() == 0.0) ? 0 : 1;
+ rStrm << EXC_FORMULA_RES_BOOL << sal_uInt8( 0 )
+ << nXclValue << sal_uInt8( 0 ) << sal_uInt16( 0 )
+ << sal_uInt16( 0xFFFF );
+ }
+ break;
+
+ default:
+ rStrm << mrScFmlaCell.GetValue();
+ }
+
+ // flags and formula token array
+ sal_uInt16 nFlags = EXC_FORMULA_DEFAULTFLAGS;
+ ::set_flag( nFlags, EXC_FORMULA_RECALC_ALWAYS, mxTokArr->IsVolatile() || (mxAddRec.is() && mxAddRec->IsVolatile()) );
+ ::set_flag( nFlags, EXC_FORMULA_SHARED, mxAddRec.is() && (mxAddRec->GetRecId() == EXC_ID_SHRFMLA) );
+ rStrm << nFlags << sal_uInt32( 0 ) << *mxTokArr;
+}
+
+// Multiple cell records ======================================================
+
+XclExpMultiCellBase::XclExpMultiCellBase(
+ sal_uInt16 nRecId, sal_uInt16 nMulRecId, sal_Size nContSize, const XclAddress& rXclPos ) :
+ XclExpCellBase( nRecId, 0, rXclPos ),
+ mnMulRecId( nMulRecId ),
+ mnContSize( nContSize )
+{
+}
+
+sal_uInt16 XclExpMultiCellBase::GetLastXclCol() const
+{
+ return GetXclCol() + GetCellCount() - 1;
+}
+
+sal_uInt32 XclExpMultiCellBase::GetFirstXFId() const
+{
+ return maXFIds.empty() ? XclExpXFBuffer::GetDefCellXFId() : maXFIds.front().mnXFId;
+}
+
+bool XclExpMultiCellBase::IsEmpty() const
+{
+ return maXFIds.empty();
+}
+
+void XclExpMultiCellBase::ConvertXFIndexes( const XclExpRoot& rRoot )
+{
+ for( XclExpMultiXFIdDeq::iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
+ aIt->ConvertXFIndex( rRoot );
+}
+
+void XclExpMultiCellBase::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
+
+ XclExpMultiXFIdDeq::const_iterator aEnd = maXFIds.end();
+ XclExpMultiXFIdDeq::const_iterator aRangeBeg = maXFIds.begin();
+ XclExpMultiXFIdDeq::const_iterator aRangeEnd = aRangeBeg;
+ sal_uInt16 nBegXclCol = GetXclCol();
+ sal_uInt16 nEndXclCol = nBegXclCol;
+
+ while( aRangeEnd != aEnd )
+ {
+ // find begin of next used XF range
+ aRangeBeg = aRangeEnd;
+ nBegXclCol = nEndXclCol;
+ while( (aRangeBeg != aEnd) && (aRangeBeg->mnXFIndex == EXC_XF_NOTFOUND) )
+ {
+ nBegXclCol = nBegXclCol + aRangeBeg->mnCount;
+ ++aRangeBeg;
+ }
+ // find end of next used XF range
+ aRangeEnd = aRangeBeg;
+ nEndXclCol = nBegXclCol;
+ while( (aRangeEnd != aEnd) && (aRangeEnd->mnXFIndex != EXC_XF_NOTFOUND) )
+ {
+ nEndXclCol = nEndXclCol + aRangeEnd->mnCount;
+ ++aRangeEnd;
+ }
+
+ // export this range as a record
+ if( aRangeBeg != aRangeEnd )
+ {
+ sal_uInt16 nCount = nEndXclCol - nBegXclCol;
+ bool bIsMulti = nCount > 1;
+ sal_Size nTotalSize = GetRecSize() + (2 + mnContSize) * nCount;
+ if( bIsMulti ) nTotalSize += 2;
+
+ rStrm.StartRecord( bIsMulti ? mnMulRecId : GetRecId(), nTotalSize );
+ rStrm << GetXclRow() << nBegXclCol;
+
+ sal_uInt16 nRelCol = nBegXclCol - GetXclCol();
+ for( XclExpMultiXFIdDeq::const_iterator aIt = aRangeBeg; aIt != aRangeEnd; ++aIt )
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < aIt->mnCount; ++nIdx )
+ {
+ rStrm << aIt->mnXFIndex;
+ WriteContents( rStrm, nRelCol );
+ ++nRelCol;
+ }
+ }
+ if( bIsMulti )
+ rStrm << static_cast< sal_uInt16 >( nEndXclCol - 1 );
+ rStrm.EndRecord();
+ }
+ }
+}
+
+void XclExpMultiCellBase::SaveXml( XclExpXmlStream& rStrm )
+{
+ XclExpMultiXFIdDeq::const_iterator aEnd = maXFIds.end();
+ XclExpMultiXFIdDeq::const_iterator aRangeBeg = maXFIds.begin();
+ XclExpMultiXFIdDeq::const_iterator aRangeEnd = aRangeBeg;
+ sal_uInt16 nBegXclCol = GetXclCol();
+ sal_uInt16 nEndXclCol = nBegXclCol;
+
+ while( aRangeEnd != aEnd )
+ {
+ // find begin of next used XF range
+ aRangeBeg = aRangeEnd;
+ nBegXclCol = nEndXclCol;
+ while( (aRangeBeg != aEnd) && (aRangeBeg->mnXFIndex == EXC_XF_NOTFOUND) )
+ {
+ nBegXclCol = nBegXclCol + aRangeBeg->mnCount;
+ ++aRangeBeg;
+ }
+ // find end of next used XF range
+ aRangeEnd = aRangeBeg;
+ nEndXclCol = nBegXclCol;
+ while( (aRangeEnd != aEnd) && (aRangeEnd->mnXFIndex != EXC_XF_NOTFOUND) )
+ {
+ nEndXclCol = nEndXclCol + aRangeEnd->mnCount;
+ ++aRangeEnd;
+ }
+
+ // export this range as a record
+ if( aRangeBeg != aRangeEnd )
+ {
+ sal_uInt16 nRelColIdx = nBegXclCol - GetXclCol();
+ sal_Int32 nRelCol = 0;
+ for( XclExpMultiXFIdDeq::const_iterator aIt = aRangeBeg; aIt != aRangeEnd; ++aIt )
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < aIt->mnCount; ++nIdx )
+ {
+ WriteXmlContents(
+ rStrm,
+ XclAddress( static_cast<sal_uInt16>(nBegXclCol + nRelCol), GetXclRow() ),
+ aIt->mnXFIndex,
+ nRelColIdx );
+ ++nRelCol;
+ ++nRelColIdx;
+ }
+ }
+ }
+ }
+}
+
+sal_uInt16 XclExpMultiCellBase::GetCellCount() const
+{
+ sal_uInt16 nCount = 0;
+ for( XclExpMultiXFIdDeq::const_iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
+ nCount = nCount + aIt->mnCount;
+ return nCount;
+}
+
+void XclExpMultiCellBase::AppendXFId( const XclExpMultiXFId& rXFId )
+{
+ if( maXFIds.empty() || (maXFIds.back().mnXFId != rXFId.mnXFId) )
+ maXFIds.push_back( rXFId );
+ else
+ maXFIds.back().mnCount = maXFIds.back().mnCount + rXFId.mnCount;
+}
+
+void XclExpMultiCellBase::AppendXFId( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, sal_uInt16 nScript, sal_uInt32 nForcedXFId, sal_uInt16 nCount )
+{
+ sal_uInt32 nXFId = (nForcedXFId == EXC_XFID_NOTFOUND) ?
+ rRoot.GetXFBuffer().Insert( pPattern, nScript ) : nForcedXFId;
+ AppendXFId( XclExpMultiXFId( nXFId, nCount ) );
+}
+
+bool XclExpMultiCellBase::TryMergeXFIds( const XclExpMultiCellBase& rCell )
+{
+ if( GetLastXclCol() + 1 == rCell.GetXclCol() )
+ {
+ maXFIds.insert( maXFIds.end(), rCell.maXFIds.begin(), rCell.maXFIds.end() );
+ return true;
+ }
+ return false;
+}
+
+void XclExpMultiCellBase::GetXFIndexes( ScfUInt16Vec& rXFIndexes ) const
+{
+ DBG_ASSERT( GetLastXclCol() < rXFIndexes.size(), "XclExpMultiCellBase::GetXFIndexes - vector too small" );
+ ScfUInt16Vec::iterator aDestIt = rXFIndexes.begin() + GetXclCol();
+ for( XclExpMultiXFIdDeq::const_iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
+ {
+ ::std::fill( aDestIt, aDestIt + aIt->mnCount, aIt->mnXFIndex );
+ aDestIt += aIt->mnCount;
+ }
+}
+
+void XclExpMultiCellBase::RemoveUnusedXFIndexes( const ScfUInt16Vec& rXFIndexes )
+{
+ // save last column before calling maXFIds.clear()
+ sal_uInt16 nLastXclCol = GetLastXclCol();
+ DBG_ASSERT( nLastXclCol < rXFIndexes.size(), "XclExpMultiCellBase::RemoveUnusedXFIndexes - XF index vector too small" );
+
+ // build new XF index vector, containing passed XF indexes
+ maXFIds.clear();
+ XclExpMultiXFId aXFId( 0 );
+ for( ScfUInt16Vec::const_iterator aIt = rXFIndexes.begin() + GetXclCol(), aEnd = rXFIndexes.begin() + nLastXclCol + 1; aIt != aEnd; ++aIt )
+ {
+ // AppendXFId() tests XclExpXFIndex::mnXFId, set it too
+ aXFId.mnXFId = aXFId.mnXFIndex = *aIt;
+ AppendXFId( aXFId );
+ }
+
+ // remove leading and trailing unused XF indexes
+ if( !maXFIds.empty() && (maXFIds.front().mnXFIndex == EXC_XF_NOTFOUND) )
+ {
+ SetXclCol( GetXclCol() + maXFIds.front().mnCount );
+ maXFIds.pop_front();
+ }
+ if( !maXFIds.empty() && (maXFIds.back().mnXFIndex == EXC_XF_NOTFOUND) )
+ maXFIds.pop_back();
+
+ // The Save() function will skip all XF indexes equal to EXC_XF_NOTFOUND.
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpBlankCell, 256, 256 )
+
+XclExpBlankCell::XclExpBlankCell( const XclAddress& rXclPos, const XclExpMultiXFId& rXFId ) :
+ XclExpMultiCellBase( EXC_ID3_BLANK, EXC_ID_MULBLANK, 0, rXclPos )
+{
+ DBG_ASSERT( rXFId.mnCount > 0, "XclExpBlankCell::XclExpBlankCell - invalid count" );
+ AppendXFId( rXFId );
+}
+
+XclExpBlankCell::XclExpBlankCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos, sal_uInt16 nLastXclCol,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId ) :
+ XclExpMultiCellBase( EXC_ID3_BLANK, EXC_ID_MULBLANK, 0, rXclPos )
+{
+ DBG_ASSERT( rXclPos.mnCol <= nLastXclCol, "XclExpBlankCell::XclExpBlankCell - invalid column range" );
+ // #i46627# use default script type instead of ApiScriptType::WEAK
+ AppendXFId( rRoot, pPattern, rRoot.GetDefApiScript(), nForcedXFId, nLastXclCol - rXclPos.mnCol + 1 );
+}
+
+bool XclExpBlankCell::TryMerge( const XclExpCellBase& rCell )
+{
+ const XclExpBlankCell* pBlankCell = dynamic_cast< const XclExpBlankCell* >( &rCell );
+ return pBlankCell && TryMergeXFIds( *pBlankCell );
+}
+
+void XclExpBlankCell::GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const
+{
+ GetXFIndexes( rXFIndexes );
+}
+
+void XclExpBlankCell::RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes )
+{
+ RemoveUnusedXFIndexes( rXFIndexes );
+}
+
+void XclExpBlankCell::WriteContents( XclExpStream& /*rStrm*/, sal_uInt16 /*nRelCol*/ )
+{
+}
+
+void XclExpBlankCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 /* nRelCol */ )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->singleElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( rAddress ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, nXFId ).getStr(),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpRkCell, 256, 256 )
+
+XclExpRkCell::XclExpRkCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, sal_Int32 nRkValue ) :
+ XclExpMultiCellBase( EXC_ID_RK, EXC_ID_MULRK, 4, rXclPos )
+{
+ // #i41210# always use latin script for number cells - may look wrong for special number formats...
+ AppendXFId( rRoot, pPattern, ApiScriptType::LATIN, nForcedXFId );
+ maRkValues.push_back( nRkValue );
+}
+
+bool XclExpRkCell::TryMerge( const XclExpCellBase& rCell )
+{
+ const XclExpRkCell* pRkCell = dynamic_cast< const XclExpRkCell* >( &rCell );
+ if( pRkCell && TryMergeXFIds( *pRkCell ) )
+ {
+ maRkValues.insert( maRkValues.end(), pRkCell->maRkValues.begin(), pRkCell->maRkValues.end() );
+ return true;
+ }
+ return false;
+}
+
+void XclExpRkCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( rAddress ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, nXFId ).getStr(),
+ XML_t, "n",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( XclTools::GetDoubleFromRK( maRkValues[ nRelCol ] ) );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpRkCell::WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol )
+{
+ DBG_ASSERT( nRelCol < maRkValues.size(), "XclExpRkCell::WriteContents - overflow error" );
+ rStrm << maRkValues[ nRelCol ];
+}
+
+// ============================================================================
+// Rows and Columns
+// ============================================================================
+
+XclExpOutlineBuffer::XclExpOutlineBuffer( const XclExpRoot& rRoot, bool bRows ) :
+ mpScOLArray( 0 ),
+ maLevelInfos( SC_OL_MAXDEPTH ),
+ mnCurrLevel( 0 ),
+ mbCurrCollapse( false )
+{
+ if( const ScOutlineTable* pOutlineTable = rRoot.GetDoc().GetOutlineTable( rRoot.GetCurrScTab() ) )
+ mpScOLArray = bRows ? pOutlineTable->GetRowArray() : pOutlineTable->GetColArray();
+
+ if( mpScOLArray )
+ for( USHORT nLevel = 0; nLevel < SC_OL_MAXDEPTH; ++nLevel )
+ if( ScOutlineEntry* pEntry = mpScOLArray->GetEntryByPos( nLevel, 0 ) )
+ maLevelInfos[ nLevel ].mnScEndPos = pEntry->GetEnd();
+}
+
+void XclExpOutlineBuffer::UpdateColRow( SCCOLROW nScPos )
+{
+ if( mpScOLArray )
+ {
+ // find open level index for passed position
+ USHORT nNewOpenScLevel = 0; // new open level (0-based Calc index)
+ sal_uInt8 nNewLevel = 0; // new open level (1-based Excel index)
+
+ if( mpScOLArray->FindTouchedLevel( nScPos, nScPos, nNewOpenScLevel ) )
+ nNewLevel = static_cast< sal_uInt8 >( nNewOpenScLevel + 1 );
+ // else nNewLevel keeps 0 to show that there are no groups
+
+ mbCurrCollapse = false;
+ if( nNewLevel >= mnCurrLevel )
+ {
+ // new level(s) opened, or no level closed - update all level infos
+ for( USHORT nScLevel = 0; nScLevel <= nNewOpenScLevel; ++nScLevel )
+ {
+ /* In each level: check if a new group is started (there may be
+ neighbored groups without gap - therefore check ALL levels). */
+ if( maLevelInfos[ nScLevel ].mnScEndPos < nScPos )
+ {
+ if( ScOutlineEntry* pEntry = mpScOLArray->GetEntryByPos( nScLevel, nScPos ) )
+ {
+ maLevelInfos[ nScLevel ].mnScEndPos = pEntry->GetEnd();
+ maLevelInfos[ nScLevel ].mbHidden = pEntry->IsHidden();
+ }
+ }
+ }
+ }
+ else
+ {
+ // level(s) closed - check if any of the closed levels are collapsed
+ // Calc uses 0-based level indexes
+ USHORT nOldOpenScLevel = mnCurrLevel - 1;
+ for( USHORT nScLevel = nNewOpenScLevel + 1; !mbCurrCollapse && (nScLevel <= nOldOpenScLevel); ++nScLevel )
+ mbCurrCollapse = maLevelInfos[ nScLevel ].mbHidden;
+ }
+
+ // cache new opened level
+ mnCurrLevel = nNewLevel;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpGuts::XclExpGuts( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_GUTS, 8 ),
+ mnColLevels( 0 ),
+ mnColWidth( 0 ),
+ mnRowLevels( 0 ),
+ mnRowWidth( 0 )
+{
+ if( const ScOutlineTable* pOutlineTable = rRoot.GetDoc().GetOutlineTable( rRoot.GetCurrScTab() ) )
+ {
+ // column outline groups
+ if( const ScOutlineArray* pColArray = pOutlineTable->GetColArray() )
+ mnColLevels = ulimit_cast< sal_uInt16 >( pColArray->GetDepth(), EXC_OUTLINE_MAX );
+ if( mnColLevels )
+ {
+ ++mnColLevels;
+ mnColWidth = 12 * mnColLevels + 5;
+ }
+
+ // row outline groups
+ if( const ScOutlineArray* pRowArray = pOutlineTable->GetRowArray() )
+ mnRowLevels = ulimit_cast< sal_uInt16 >( pRowArray->GetDepth(), EXC_OUTLINE_MAX );
+ if( mnRowLevels )
+ {
+ ++mnRowLevels;
+ mnRowWidth = 12 * mnRowLevels + 5;
+ }
+ }
+}
+
+void XclExpGuts::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnRowWidth << mnColWidth << mnRowLevels << mnColLevels;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDimensions::XclExpDimensions( const XclExpRoot& rRoot ) :
+ mnFirstUsedXclRow( 0 ),
+ mnFirstFreeXclRow( 0 ),
+ mnFirstUsedXclCol( 0 ),
+ mnFirstFreeXclCol( 0 )
+{
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF2: SetRecHeader( EXC_ID2_DIMENSIONS, 8 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5: SetRecHeader( EXC_ID3_DIMENSIONS, 10 ); break;
+ case EXC_BIFF8: SetRecHeader( EXC_ID3_DIMENSIONS, 14 ); break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpDimensions::SetDimensions(
+ sal_uInt16 nFirstUsedXclCol, sal_uInt32 nFirstUsedXclRow,
+ sal_uInt16 nFirstFreeXclCol, sal_uInt32 nFirstFreeXclRow )
+{
+ mnFirstUsedXclRow = nFirstUsedXclRow;
+ mnFirstFreeXclRow = nFirstFreeXclRow;
+ mnFirstUsedXclCol = nFirstUsedXclCol;
+ mnFirstFreeXclCol = nFirstFreeXclCol;
+}
+
+void XclExpDimensions::SaveXml( XclExpXmlStream& rStrm )
+{
+ ScRange aRange;
+ aRange.aStart.SetRow( (SCROW) mnFirstUsedXclRow );
+ aRange.aStart.SetCol( (SCCOL) mnFirstUsedXclCol );
+
+ if( mnFirstFreeXclRow != mnFirstUsedXclRow && mnFirstFreeXclCol != mnFirstUsedXclCol )
+ {
+ aRange.aEnd.SetRow( (SCROW) (mnFirstFreeXclRow-1) );
+ aRange.aEnd.SetCol( (SCCOL) (mnFirstFreeXclCol-1) );
+ }
+
+ rStrm.GetCurrentStream()->singleElement( XML_dimension,
+ XML_ref, XclXmlUtils::ToOString( aRange ).getStr(),
+ FSEND );
+}
+
+void XclExpDimensions::WriteBody( XclExpStream& rStrm )
+{
+ XclBiff eBiff = rStrm.GetRoot().GetBiff();
+ if( eBiff == EXC_BIFF8 )
+ rStrm << mnFirstUsedXclRow << mnFirstFreeXclRow;
+ else
+ rStrm << static_cast< sal_uInt16 >( mnFirstUsedXclRow ) << static_cast< sal_uInt16 >( mnFirstFreeXclRow );
+ rStrm << mnFirstUsedXclCol << mnFirstFreeXclCol;
+ if( eBiff >= EXC_BIFF3 )
+ rStrm << sal_uInt16( 0 );
+}
+
+// ============================================================================
+
+namespace {
+
+double lclGetCorrectedColWidth( const XclExpRoot& rRoot, sal_uInt16 nXclColWidth )
+{
+ long nFontHt = rRoot.GetFontBuffer().GetAppFontData().mnHeight;
+ return nXclColWidth - XclTools::GetXclDefColWidthCorrection( nFontHt );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpDefcolwidth::XclExpDefcolwidth( const XclExpRoot& rRoot ) :
+ XclExpUInt16Record( EXC_ID_DEFCOLWIDTH, EXC_DEFCOLWIDTH_DEF ),
+ XclExpRoot( rRoot )
+{
+}
+
+bool XclExpDefcolwidth::IsDefWidth( sal_uInt16 nXclColWidth ) const
+{
+ double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth );
+ // exactly matched, if difference is less than 1/16 of a character to the left or to the right
+ return Abs( static_cast< long >( GetValue() * 256.0 - fNewColWidth + 0.5 ) ) < 16;
+}
+
+void XclExpDefcolwidth::SetDefWidth( sal_uInt16 nXclColWidth )
+{
+ double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth );
+ SetValue( limit_cast< sal_uInt16 >( fNewColWidth / 256.0 + 0.5 ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot,
+ SCCOL nScCol, SCROW nLastScRow, XclExpColOutlineBuffer& rOutlineBfr ) :
+ XclExpRecord( EXC_ID_COLINFO, 12 ),
+ XclExpRoot( rRoot ),
+ mnWidth( 0 ),
+ mnFlags( 0 ),
+ mnFirstXclCol( static_cast< sal_uInt16 >( nScCol ) ),
+ mnLastXclCol( static_cast< sal_uInt16 >( nScCol ) )
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ // column default format
+ maXFId.mnXFId = GetXFBuffer().Insert(
+ rDoc.GetMostUsedPattern( nScCol, 0, nLastScRow, nScTab ), GetDefApiScript() );
+
+ // column width
+ USHORT nScWidth = rDoc.GetColWidth( nScCol, nScTab );
+ mnWidth = XclTools::GetXclColumnWidth( nScWidth, GetCharWidth() );
+
+ // column flags
+ ::set_flag( mnFlags, EXC_COLINFO_HIDDEN, rDoc.ColHidden(nScCol, nScTab) );
+
+ // outline data
+ rOutlineBfr.Update( nScCol );
+ ::set_flag( mnFlags, EXC_COLINFO_COLLAPSED, rOutlineBfr.IsCollapsed() );
+ ::insert_value( mnFlags, rOutlineBfr.GetLevel(), 8, 3 );
+}
+
+sal_uInt16 XclExpColinfo::ConvertXFIndexes()
+{
+ maXFId.ConvertXFIndex( GetRoot() );
+ return maXFId.mnXFIndex;
+}
+
+bool XclExpColinfo::IsDefault( const XclExpDefcolwidth& rDefColWidth ) const
+{
+ return (maXFId.mnXFIndex == EXC_XF_DEFAULTCELL) && (mnFlags == 0) && rDefColWidth.IsDefWidth( mnWidth );
+}
+
+bool XclExpColinfo::TryMerge( const XclExpColinfo& rColInfo )
+{
+ if( (maXFId.mnXFIndex == rColInfo.maXFId.mnXFIndex) &&
+ (mnWidth == rColInfo.mnWidth) &&
+ (mnFlags == rColInfo.mnFlags) &&
+ (mnLastXclCol + 1 == rColInfo.mnFirstXclCol) )
+ {
+ mnLastXclCol = rColInfo.mnLastXclCol;
+ return true;
+ }
+ return false;
+}
+
+void XclExpColinfo::WriteBody( XclExpStream& rStrm )
+{
+ // if last column is equal to last possible column, Excel adds one more
+ sal_uInt16 nLastXclCol = mnLastXclCol;
+ if( nLastXclCol == static_cast< sal_uInt16 >( rStrm.GetRoot().GetMaxPos().Col() ) )
+ ++nLastXclCol;
+
+ rStrm << mnFirstXclCol
+ << nLastXclCol
+ << mnWidth
+ << maXFId.mnXFIndex
+ << mnFlags
+ << sal_uInt16( 0 );
+}
+
+void XclExpColinfo::SaveXml( XclExpXmlStream& rStrm )
+{
+ // if last column is equal to last possible column, Excel adds one more
+ sal_uInt16 nLastXclCol = mnLastXclCol;
+ if( nLastXclCol == static_cast< sal_uInt16 >( rStrm.GetRoot().GetMaxPos().Col() ) )
+ ++nLastXclCol;
+
+ rStrm.GetCurrentStream()->singleElement( XML_col,
+ // OOXTODO: XML_bestFit,
+ XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_COLLAPSED ) ),
+ // OOXTODO: XML_customWidth,
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_HIDDEN ) ),
+ XML_max, OString::valueOf( (sal_Int32) (nLastXclCol+1) ).getStr(),
+ XML_min, OString::valueOf( (sal_Int32) (mnFirstXclCol+1) ).getStr(),
+ // OOXTODO: XML_outlineLevel,
+ // OOXTODO: XML_phonetic,
+ XML_style, lcl_GetStyleId( rStrm, maXFId.mnXFIndex ).getStr(),
+ XML_width, OString::valueOf( (double) (mnWidth / 255.0) ).getStr(),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpColinfoBuffer::XclExpColinfoBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maDefcolwidth( rRoot ),
+ maOutlineBfr( rRoot )
+{
+}
+
+void XclExpColinfoBuffer::Initialize( SCROW nLastScRow )
+{
+
+ for( sal_uInt16 nScCol = 0, nLastScCol = GetMaxPos().Col(); nScCol <= nLastScCol; ++nScCol )
+ maColInfos.AppendNewRecord( new XclExpColinfo( GetRoot(), nScCol, nLastScRow, maOutlineBfr ) );
+}
+
+void XclExpColinfoBuffer::Finalize( ScfUInt16Vec& rXFIndexes )
+{
+ rXFIndexes.clear();
+ rXFIndexes.reserve( maColInfos.GetSize() );
+
+ size_t nPos, nSize;
+
+ // do not cache the record list size, it may change in the loop
+ for( nPos = 0; nPos < maColInfos.GetSize(); ++nPos )
+ {
+ XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
+ xRec->ConvertXFIndexes();
+
+ // try to merge with previous record
+ if( nPos > 0 )
+ {
+ XclExpColinfoRef xPrevRec = maColInfos.GetRecord( nPos - 1 );
+ if( xPrevRec->TryMerge( *xRec ) )
+ // adjust nPos to get the next COLINFO record at the same position
+ maColInfos.RemoveRecord( nPos-- );
+ }
+ }
+
+ // put XF indexes into passed vector, collect use count of all different widths
+ typedef ::std::map< sal_uInt16, sal_uInt16 > XclExpWidthMap;
+ XclExpWidthMap aWidthMap;
+ sal_uInt16 nMaxColCount = 0;
+ sal_uInt16 nMaxUsedWidth = 0;
+ for( nPos = 0, nSize = maColInfos.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
+ sal_uInt16 nColCount = xRec->GetColCount();
+
+ // add XF index to passed vector
+ rXFIndexes.resize( rXFIndexes.size() + nColCount, xRec->GetXFIndex() );
+
+ // collect use count of column width
+ sal_uInt16 nWidth = xRec->GetColWidth();
+ sal_uInt16& rnMapCount = aWidthMap[ nWidth ];
+ rnMapCount = rnMapCount + nColCount;
+ if( rnMapCount > nMaxColCount )
+ {
+ nMaxColCount = rnMapCount;
+ nMaxUsedWidth = nWidth;
+ }
+ }
+ maDefcolwidth.SetDefWidth( nMaxUsedWidth );
+
+ // remove all default COLINFO records
+ nPos = 0;
+ while( nPos < maColInfos.GetSize() )
+ {
+ XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
+ if( xRec->IsDefault( maDefcolwidth ) )
+ maColInfos.RemoveRecord( nPos );
+ else
+ ++nPos;
+ }
+}
+
+void XclExpColinfoBuffer::Save( XclExpStream& rStrm )
+{
+ // DEFCOLWIDTH
+ maDefcolwidth.Save( rStrm );
+ // COLINFO records
+ maColInfos.Save( rStrm );
+}
+
+void XclExpColinfoBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maColInfos.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_cols,
+ FSEND );
+ maColInfos.SaveXml( rStrm );
+ rWorksheet->endElement( XML_cols );
+}
+
+// ============================================================================
+
+XclExpDefaultRowData::XclExpDefaultRowData() :
+ mnFlags( EXC_DEFROW_DEFAULTFLAGS ),
+ mnHeight( EXC_DEFROW_DEFAULTHEIGHT )
+{
+}
+
+XclExpDefaultRowData::XclExpDefaultRowData( const XclExpRow& rRow ) :
+ mnFlags( EXC_DEFROW_DEFAULTFLAGS ),
+ mnHeight( rRow.GetHeight() )
+{
+ ::set_flag( mnFlags, EXC_DEFROW_HIDDEN, rRow.IsHidden() );
+ ::set_flag( mnFlags, EXC_DEFROW_UNSYNCED, rRow.IsUnsynced() );
+}
+
+bool operator<( const XclExpDefaultRowData& rLeft, const XclExpDefaultRowData& rRight )
+{
+ return (rLeft.mnHeight < rRight.mnHeight) ||
+ ((rLeft.mnHeight == rRight.mnHeight) && (rLeft.mnFlags < rRight.mnFlags));
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDefrowheight::XclExpDefrowheight() :
+ XclExpRecord( EXC_ID3_DEFROWHEIGHT, 4 )
+{
+}
+
+void XclExpDefrowheight::SetDefaultData( const XclExpDefaultRowData& rDefData )
+{
+ maDefData = rDefData;
+}
+
+void XclExpDefrowheight::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
+ rStrm << maDefData.mnFlags << maDefData.mnHeight;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRow::XclExpRow( const XclExpRoot& rRoot, sal_uInt16 nXclRow,
+ XclExpRowOutlineBuffer& rOutlineBfr, bool bAlwaysEmpty ) :
+ XclExpRecord( EXC_ID3_ROW, 16 ),
+ XclExpRoot( rRoot ),
+ mnXclRow( nXclRow ),
+ mnHeight( 0 ),
+ mnFlags( EXC_ROW_DEFAULTFLAGS ),
+ mnXFIndex( EXC_XF_DEFAULTCELL ),
+ mnOutlineLevel( 0 ),
+ mbAlwaysEmpty( bAlwaysEmpty ),
+ mbEnabled( true )
+{
+ SCTAB nScTab = GetCurrScTab();
+ SCROW nScRow = static_cast< SCROW >( mnXclRow );
+
+ // *** Row flags *** ------------------------------------------------------
+
+ BYTE nRowFlags = GetDoc().GetRowFlags( nScRow, nScTab );
+ bool bUserHeight = ::get_flag< BYTE >( nRowFlags, CR_MANUALSIZE );
+ bool bHidden = GetDoc().RowHidden(nScRow, nScTab);
+ ::set_flag( mnFlags, EXC_ROW_UNSYNCED, bUserHeight );
+ ::set_flag( mnFlags, EXC_ROW_HIDDEN, bHidden );
+
+ // *** Row height *** -----------------------------------------------------
+
+ if (bUserHeight)
+ mnHeight = GetDoc().GetRowHeight(nScRow, nScTab, false);
+ else
+ mnHeight = EXC_ROW_DEFAULTHEIGHT;
+
+ // #76250# not usable in Applix
+// ::set_flag( mnHeight, EXC_ROW_FLAGDEFHEIGHT, !bUserHeight );
+
+ // *** Outline data *** ---------------------------------------------------
+
+ rOutlineBfr.Update( nScRow );
+ ::set_flag( mnFlags, EXC_ROW_COLLAPSED, rOutlineBfr.IsCollapsed() );
+ ::insert_value( mnFlags, rOutlineBfr.GetLevel(), 0, 3 );
+ mnOutlineLevel = rOutlineBfr.GetLevel();
+
+ // *** Progress bar *** ---------------------------------------------------
+
+ XclExpProgressBar& rProgress = GetProgressBar();
+ rProgress.IncRowRecordCount();
+ rProgress.Progress();
+}
+
+void XclExpRow::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
+{
+ DBG_ASSERT( !mbAlwaysEmpty, "XclExpRow::AppendCell - row is marked to be always empty" );
+ // try to merge with last existing cell
+ InsertCell( xCell, maCellList.GetSize(), bIsMergedBase );
+}
+
+void XclExpRow::Finalize( const ScfUInt16Vec& rColXFIndexes )
+{
+ size_t nPos, nSize;
+
+ // *** Convert XF identifiers *** -----------------------------------------
+
+ // additionally collect the blank XF indexes
+ size_t nColCount = GetMaxPos().Col() + 1;
+ DBG_ASSERT( rColXFIndexes.size() == nColCount, "XclExpRow::Finalize - wrong column XF index count" );
+
+ ScfUInt16Vec aXFIndexes( nColCount, EXC_XF_NOTFOUND );
+ for( nPos = 0, nSize = maCellList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpCellRef xCell = maCellList.GetRecord( nPos );
+ xCell->ConvertXFIndexes( GetRoot() );
+ xCell->GetBlankXFIndexes( aXFIndexes );
+ }
+
+ // *** Fill gaps with BLANK/MULBLANK cell records *** ---------------------
+
+ /* This is needed because nonexistant cells in Calc are not formatted at all,
+ but in Excel they would have the column default format. Blank cells that
+ are equal to the respective column default are removed later in this function. */
+ if( !mbAlwaysEmpty )
+ {
+ // XF identifier representing default cell XF
+ XclExpMultiXFId aXFId( XclExpXFBuffer::GetDefCellXFId() );
+ aXFId.ConvertXFIndex( GetRoot() );
+
+ nPos = 0;
+ while( nPos <= maCellList.GetSize() ) // don't cache list size, may change in the loop
+ {
+ // get column index that follows previous cell
+ sal_uInt16 nFirstFreeXclCol = (nPos > 0) ? (maCellList.GetRecord( nPos - 1 )->GetLastXclCol() + 1) : 0;
+ // get own column index
+ sal_uInt16 nNextUsedXclCol = (nPos < maCellList.GetSize()) ? maCellList.GetRecord( nPos )->GetXclCol() : (GetMaxPos().Col() + 1);
+
+ // is there a gap?
+ if( nFirstFreeXclCol < nNextUsedXclCol )
+ {
+ aXFId.mnCount = nNextUsedXclCol - nFirstFreeXclCol;
+ XclExpCellRef xNewCell( new XclExpBlankCell( XclAddress( nFirstFreeXclCol, mnXclRow ), aXFId ) );
+ // insert the cell, InsertCell() may merge it with existing BLANK records
+ InsertCell( xNewCell, nPos, false );
+ // insert default XF indexes into aXFIndexes
+ ::std::fill( aXFIndexes.begin() + nFirstFreeXclCol,
+ aXFIndexes.begin() + nNextUsedXclCol, aXFId.mnXFIndex );
+ // don't step forward with nPos, InsertCell() may remove records
+ }
+ else
+ ++nPos;
+ }
+ }
+
+ // *** Find default row format *** ----------------------------------------
+
+ ScfUInt16Vec::iterator aCellBeg = aXFIndexes.begin(), aCellEnd = aXFIndexes.end(), aCellIt;
+ ScfUInt16Vec::const_iterator aColBeg = rColXFIndexes.begin(), aColIt;
+
+ // find most used XF index in the row
+ typedef ::std::map< sal_uInt16, size_t > XclExpXFIndexMap;
+ XclExpXFIndexMap aIndexMap;
+ sal_uInt16 nRowXFIndex = EXC_XF_DEFAULTCELL;
+ size_t nMaxXFCount = 0;
+ for( aCellIt = aCellBeg; aCellIt != aCellEnd; ++aCellIt )
+ {
+ if( *aCellIt != EXC_XF_NOTFOUND )
+ {
+ size_t& rnCount = aIndexMap[ *aCellIt ];
+ ++rnCount;
+ if( rnCount > nMaxXFCount )
+ {
+ nRowXFIndex = *aCellIt;
+ nMaxXFCount = rnCount;
+ }
+ }
+ }
+
+ // decide whether to use the row default XF index or column default XF indexes
+ bool bUseColDefXFs = nRowXFIndex == EXC_XF_DEFAULTCELL;
+ if( !bUseColDefXFs )
+ {
+ // count needed XF indexes for blank cells with and without row default XF index
+ size_t nXFCountWithRowDefXF = 0;
+ size_t nXFCountWithoutRowDefXF = 0;
+ for( aCellIt = aCellBeg, aColIt = aColBeg; aCellIt != aCellEnd; ++aCellIt, ++aColIt )
+ {
+ sal_uInt16 nXFIndex = *aCellIt;
+ if( nXFIndex != EXC_XF_NOTFOUND )
+ {
+ if( nXFIndex != nRowXFIndex )
+ ++nXFCountWithRowDefXF; // with row default XF index
+ if( nXFIndex != *aColIt )
+ ++nXFCountWithoutRowDefXF; // without row default XF index
+ }
+ }
+
+ // use column XF indexes if this would cause less or equal number of BLANK records
+ bUseColDefXFs = nXFCountWithoutRowDefXF <= nXFCountWithRowDefXF;
+ }
+
+ // *** Remove unused BLANK cell records *** -------------------------------
+
+ if( bUseColDefXFs )
+ {
+ // use column default XF indexes
+ // #i194#: remove cell XF indexes equal to column default XF indexes
+ for( aCellIt = aCellBeg, aColIt = aColBeg; aCellIt != aCellEnd; ++aCellIt, ++aColIt )
+ if( *aCellIt == *aColIt )
+ *aCellIt = EXC_XF_NOTFOUND;
+ }
+ else
+ {
+ // use row default XF index
+ mnXFIndex = nRowXFIndex;
+ ::set_flag( mnFlags, EXC_ROW_USEDEFXF );
+ // #98133#, #i194#, #i27407#: remove cell XF indexes equal to row default XF index
+ for( aCellIt = aCellBeg; aCellIt != aCellEnd; ++aCellIt )
+ if( *aCellIt == nRowXFIndex )
+ *aCellIt = EXC_XF_NOTFOUND;
+ }
+
+ // remove unused parts of BLANK/MULBLANK cell records
+ nPos = 0;
+ while( nPos < maCellList.GetSize() ) // do not cache list size, may change in the loop
+ {
+ XclExpCellRef xCell = maCellList.GetRecord( nPos );
+ xCell->RemoveUnusedBlankCells( aXFIndexes );
+ if( xCell->IsEmpty() )
+ maCellList.RemoveRecord( nPos );
+ else
+ ++nPos;
+ }
+
+ // progress bar includes disabled rows
+ GetProgressBar().Progress();
+}
+
+sal_uInt16 XclExpRow::GetFirstUsedXclCol() const
+{
+ return maCellList.IsEmpty() ? 0 : maCellList.GetFirstRecord()->GetXclCol();
+}
+
+sal_uInt16 XclExpRow::GetFirstFreeXclCol() const
+{
+ return maCellList.IsEmpty() ? 0 : (maCellList.GetLastRecord()->GetLastXclCol() + 1);
+}
+
+bool XclExpRow::IsDefaultable() const
+{
+ const sal_uInt16 nAllowedFlags = EXC_ROW_DEFAULTFLAGS | EXC_ROW_HIDDEN | EXC_ROW_UNSYNCED;
+ return !::get_flag( mnFlags, static_cast< sal_uInt16 >( ~nAllowedFlags ) ) && IsEmpty();
+}
+
+void XclExpRow::DisableIfDefault( const XclExpDefaultRowData& rDefRowData )
+{
+ mbEnabled = !IsDefaultable() ||
+ (mnHeight != rDefRowData.mnHeight) ||
+ (IsHidden() != rDefRowData.IsHidden()) ||
+ (IsUnsynced() != rDefRowData.IsUnsynced());
+}
+
+void XclExpRow::WriteCellList( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mbEnabled || maCellList.IsEmpty(), "XclExpRow::WriteCellList - cells in disabled row" );
+ maCellList.Save( rStrm );
+}
+
+void XclExpRow::Save( XclExpStream& rStrm )
+{
+ if( mbEnabled )
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpRow::InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase )
+{
+ DBG_ASSERT( xCell.is(), "XclExpRow::InsertCell - missing cell" );
+
+ /* #109751# If we have a multi-line text in a merged cell, and the resulting
+ row height has not been confirmed, we need to force the EXC_ROW_UNSYNCED
+ flag to be true to ensure Excel works correctly. */
+ if( bIsMergedBase && xCell->IsMultiLineText() )
+ ::set_flag( mnFlags, EXC_ROW_UNSYNCED );
+
+ // try to merge with previous cell, insert the new cell if not successful
+ XclExpCellRef xPrevCell = maCellList.GetRecord( nPos - 1 );
+ if( xPrevCell.is() && xPrevCell->TryMerge( *xCell ) )
+ xCell = xPrevCell;
+ else
+ maCellList.InsertRecord( xCell, nPos++ );
+ // nPos points now to following cell
+
+ // try to merge with following cell, remove it if successful
+ XclExpCellRef xNextCell = maCellList.GetRecord( nPos );
+ if( xNextCell.is() && xCell->TryMerge( *xNextCell ) )
+ maCellList.RemoveRecord( nPos );
+}
+
+void XclExpRow::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnXclRow
+ << GetFirstUsedXclCol()
+ << GetFirstFreeXclCol()
+ << mnHeight
+ << sal_uInt32( 0 )
+ << mnFlags
+ << mnXFIndex;
+}
+
+void XclExpRow::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !mbEnabled )
+ return;
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ bool haveFormat = ::get_flag( mnFlags, EXC_ROW_USEDEFXF );
+ rWorksheet->startElement( XML_row,
+ XML_r, OString::valueOf( (sal_Int32) (mnXclRow+1) ).getStr(),
+ // OOXTODO: XML_spans, optional
+ XML_s, haveFormat ? lcl_GetStyleId( rStrm, mnXFIndex ).getStr() : NULL,
+ XML_customFormat, XclXmlUtils::ToPsz( haveFormat ),
+ XML_ht, OString::valueOf( (double) mnHeight / 20.0 ).getStr(),
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_HIDDEN ) ),
+ XML_customHeight, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_UNSYNCED ) ),
+ XML_outlineLevel, OString::valueOf( (sal_Int32) mnOutlineLevel ).getStr(),
+ XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_COLLAPSED ) ),
+ // OOXTODO: XML_thickTop, bool
+ // OOXTODO: XML_thickBot, bool
+ // OOXTODO: XML_ph, bool
+ FSEND );
+ // OOXTODO: XML_extLst
+ maCellList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_row );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRowBuffer::XclExpRowBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maOutlineBfr( rRoot ),
+ maDimensions( rRoot ),
+ mpLastUsedRow( 0 ),
+ mnLastUsedXclRow( 0 )
+{
+}
+
+void XclExpRowBuffer::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
+{
+ DBG_ASSERT( xCell.is(), "XclExpRowBuffer::AppendCell - missing cell" );
+ GetOrCreateRow( xCell->GetXclRow(), false ).AppendCell( xCell, bIsMergedBase );
+}
+
+void XclExpRowBuffer::CreateRows( SCROW nFirstFreeScRow )
+{
+ if( nFirstFreeScRow > 0 )
+ GetOrCreateRow( static_cast< sal_uInt16 >( nFirstFreeScRow - 1 ), true );
+}
+
+void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes )
+{
+ size_t nPos, nSize;
+
+ // *** Finalize all rows *** ----------------------------------------------
+
+ GetProgressBar().ActivateFinalRowsSegment();
+
+ // unused blank cell records will be removed
+ for( nPos = 0, nSize = maRowList.GetSize(); nPos < nSize; ++nPos )
+ maRowList.GetRecord( nPos )->Finalize( rColXFIndexes );
+
+ // *** Default row format *** ---------------------------------------------
+
+ typedef ::std::map< XclExpDefaultRowData, size_t > XclExpDefRowDataMap;
+ XclExpDefRowDataMap aDefRowMap;
+
+ // find default row format for rows beyond used area
+ sal_uInt32 nDefaultXclRow = maRowList.IsEmpty() ? 0 : (maRowList.GetLastRecord()->GetXclRow() + 1);
+ XclExpDefaultRowData aMaxDefData;
+ size_t nMaxDefCount = 0;
+ /* #i30411# Files saved with SO7/OOo1.x with nonstandard default column
+ formatting cause big Excel files, because all rows from row 1 to row
+ 32000 are exported. Now, if the used area goes exactly to row 32000,
+ ignore all rows >32000.
+ #i59220# Tolerance of +-128 rows for inserted/removed rows. */
+ if( (nDefaultXclRow < 31872) || (nDefaultXclRow > 32128) )
+ {
+ sal_uInt16 nLastXclRow = static_cast< sal_uInt16 >( GetMaxPos().Row() );
+ if( nDefaultXclRow <= nLastXclRow )
+ {
+ // create a dummy ROW record and fill aMaxDefData
+ XclExpRowOutlineBuffer aOutlineBfr( GetRoot() );
+ XclExpRow aRow( GetRoot(), nLastXclRow, aOutlineBfr, true );
+ aMaxDefData = XclExpDefaultRowData( aRow );
+ aDefRowMap[ aMaxDefData ] = nMaxDefCount =
+ static_cast< size_t >( nLastXclRow - nDefaultXclRow + 1 );
+ }
+ }
+
+ // only look for default format in existing rows, if there are more than unused
+ nSize = maRowList.GetSize();
+ if( nMaxDefCount < nSize )
+ {
+ for( nPos = 0; nPos < nSize; ++nPos )
+ {
+ XclExpRowRef xRow = maRowList.GetRecord( nPos );
+ /* Collect formats of unused rows (rows without cells), which are able
+ to be defaulted (i.e. no explicit format or outline level). */
+ if( xRow->IsDefaultable() )
+ {
+ XclExpDefaultRowData aDefData( *xRow );
+ size_t& rnDefCount = aDefRowMap[ aDefData ];
+ ++rnDefCount;
+ if( rnDefCount > nMaxDefCount )
+ {
+ nMaxDefCount = rnDefCount;
+ aMaxDefData = aDefData;
+ }
+ }
+ }
+ }
+
+ // return the default row format to caller
+ rDefRowData = aMaxDefData;
+
+ // *** Disable unused ROW records, find used area *** ---------------------
+
+ sal_uInt16 nFirstUsedXclCol = SAL_MAX_UINT16;
+ sal_uInt16 nFirstFreeXclCol = 0;
+ sal_uInt32 nFirstUsedXclRow = SAL_MAX_UINT32;
+ sal_uInt32 nFirstFreeXclRow = 0;
+
+ for( nPos = 0, nSize = maRowList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpRowRef xRow = maRowList.GetRecord( nPos );
+
+ // disable unused rows
+ xRow->DisableIfDefault( aMaxDefData );
+
+ // find used column range
+ if( !xRow->IsEmpty() ) // empty rows return (0...0) as used range
+ {
+ nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, xRow->GetFirstUsedXclCol() );
+ nFirstFreeXclCol = ::std::max( nFirstFreeXclCol, xRow->GetFirstFreeXclCol() );
+ }
+
+ // find used row range
+ if( xRow->IsEnabled() )
+ {
+ sal_uInt16 nXclRow = xRow->GetXclRow();
+ nFirstUsedXclRow = ::std::min< sal_uInt32 >( nFirstUsedXclRow, nXclRow );
+ nFirstFreeXclRow = ::std::max< sal_uInt32 >( nFirstFreeXclRow, nXclRow + 1 );
+ }
+ }
+
+ // adjust start position, if there are no or only empty/disabled ROW records
+ nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, nFirstFreeXclCol );
+ nFirstUsedXclRow = ::std::min( nFirstUsedXclRow, nFirstFreeXclRow );
+
+ // initialize the DIMENSIONS record
+ maDimensions.SetDimensions(
+ nFirstUsedXclCol, nFirstUsedXclRow, nFirstFreeXclCol, nFirstFreeXclRow );
+}
+
+void XclExpRowBuffer::Save( XclExpStream& rStrm )
+{
+ // DIMENSIONS record
+ maDimensions.Save( rStrm );
+
+ // save in blocks of 32 rows, each block contains first all ROWs, then all cells
+ size_t nSize = maRowList.GetSize();
+ size_t nBlockStart = 0;
+ sal_uInt16 nStartXclRow = (nSize == 0) ? 0 : maRowList.GetRecord( 0 )->GetXclRow();
+
+ while( nBlockStart < nSize )
+ {
+ // find end of row block
+ size_t nBlockEnd = nBlockStart + 1;
+ while( (nBlockEnd < nSize) && (maRowList.GetRecord( nBlockEnd )->GetXclRow() - nStartXclRow < EXC_ROW_ROWBLOCKSIZE) )
+ ++nBlockEnd;
+
+ // write the ROW records
+ size_t nPos;
+ for( nPos = nBlockStart; nPos < nBlockEnd; ++nPos )
+ maRowList.GetRecord( nPos )->Save( rStrm );
+
+ // write the cell records
+ for( nPos = nBlockStart; nPos < nBlockEnd; ++nPos )
+ maRowList.GetRecord( nPos )->WriteCellList( rStrm );
+
+ nBlockStart = nBlockEnd;
+ nStartXclRow += EXC_ROW_ROWBLOCKSIZE;
+ }
+}
+
+void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ sal_Int32 nNonEmpty = 0;
+
+ size_t nRows = maRowList.GetSize();
+ for( size_t i = 0; i < nRows; ++i)
+ if( maRowList.GetRecord( i )->IsEnabled() )
+ ++nNonEmpty;
+
+ if( nNonEmpty == 0 )
+ {
+ rStrm.GetCurrentStream()->singleElement( XML_sheetData, FSEND );
+ }
+ else
+ {
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_sheetData, FSEND );
+ maRowList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_sheetData );
+ }
+}
+
+XclExpDimensions* XclExpRowBuffer::GetDimensions()
+{
+ return &maDimensions;
+}
+
+XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt16 nXclRow, bool bRowAlwaysEmpty )
+{
+ if( !mpLastUsedRow || (mnLastUsedXclRow != nXclRow) )
+ {
+ // fill up missing ROW records
+ // do not use sal_uInt16 for nFirstFreeXclRow, would cause loop in full sheets
+ for( size_t nFirstFreeXclRow = maRowList.GetSize(); nFirstFreeXclRow <= nXclRow; ++nFirstFreeXclRow )
+ maRowList.AppendNewRecord( new XclExpRow(
+ GetRoot(), static_cast< sal_uInt16 >( nFirstFreeXclRow ), maOutlineBfr, bRowAlwaysEmpty ) );
+
+ mpLastUsedRow = maRowList.GetRecord( nXclRow ).get();
+ mnLastUsedXclRow = nXclRow;
+ }
+ return *mpLastUsedRow;
+}
+
+// ============================================================================
+// Cell Table
+// ============================================================================
+
+XclExpCellTable::XclExpCellTable( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maColInfoBfr( rRoot ),
+ maRowBfr( rRoot ),
+ maArrayBfr( rRoot ),
+ maShrfmlaBfr( rRoot ),
+ maTableopBfr( rRoot ),
+ mxDefrowheight( new XclExpDefrowheight ),
+ mxGuts( new XclExpGuts( rRoot ) ),
+ mxNoteList( new XclExpNoteList ),
+ mxMergedcells( new XclExpMergedcells( rRoot ) ),
+ mxHyperlinkList( new XclExpHyperlinkList ),
+ mxDval( new XclExpDval( rRoot ) )
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+ SvNumberFormatter& rFormatter = GetFormatter();
+
+ // maximum sheet limits
+ SCCOL nMaxScCol = GetMaxPos().Col();
+ SCROW nMaxScRow = GetMaxPos().Row();
+
+ // find used area (non-empty cells)
+ SCCOL nLastUsedScCol;
+ SCROW nLastUsedScRow;
+ rDoc.GetTableArea( nScTab, nLastUsedScCol, nLastUsedScRow );
+
+ ScRange aUsedRange( 0, 0, nScTab, nLastUsedScCol, nLastUsedScRow, nScTab );
+ GetAddressConverter().ValidateRange( aUsedRange, true );
+ nLastUsedScCol = aUsedRange.aEnd.Col();
+ nLastUsedScRow = aUsedRange.aEnd.Row();
+
+ // first row without any set attributes (height/hidden/...)
+ SCROW nFirstUnflaggedScRow = rDoc.GetLastFlaggedRow( nScTab ) + 1;
+
+ // find range of outlines
+ SCROW nFirstUngroupedScRow = 0;
+ if( const ScOutlineTable* pOutlineTable = rDoc.GetOutlineTable( nScTab ) )
+ {
+ SCCOLROW nScStartPos, nScEndPos;
+ if( const ScOutlineArray* pRowArray = pOutlineTable->GetRowArray() )
+ {
+ pRowArray->GetRange( nScStartPos, nScEndPos );
+ // +1 because open/close button is in next row in Excel, +1 for "end->first unused"
+ nFirstUngroupedScRow = static_cast< SCROW >( nScEndPos + 2 );
+ }
+ }
+
+ // column settings
+ /* #i30411# Files saved with SO7/OOo1.x with nonstandard default column
+ formatting cause big Excel files, because all rows from row 1 to row
+ 32000 are exported. Now, if the used area goes exactly to row 32000,
+ use this row as default and ignore all rows >32000.
+ #i59220# Tolerance of +-128 rows for inserted/removed rows. */
+ if( (31871 <= nLastUsedScRow) && (nLastUsedScRow <= 32127) && (nFirstUnflaggedScRow < nLastUsedScRow) && (nFirstUngroupedScRow <= nLastUsedScRow) )
+ nMaxScRow = nLastUsedScRow;
+ maColInfoBfr.Initialize( nMaxScRow );
+
+ // range for cell iterator
+ SCCOL nLastIterScCol = nMaxScCol;
+ SCROW nLastIterScRow = ulimit_cast< SCROW >( nLastUsedScRow + 128, nMaxScRow );
+ ScUsedAreaIterator aIt( &rDoc, nScTab, 0, 0, nLastIterScCol, nLastIterScRow );
+
+ // activate the correct segment and sub segment at the progress bar
+ GetProgressBar().ActivateCreateRowsSegment();
+
+ for( bool bIt = aIt.GetNext(); bIt; bIt = aIt.GetNext() )
+ {
+ SCCOL nScCol = aIt.GetStartCol();
+ SCROW nScRow = aIt.GetRow();
+ SCCOL nLastScCol = aIt.GetEndCol();
+ ScAddress aScPos( nScCol, nScRow, nScTab );
+
+ XclAddress aXclPos( static_cast< sal_uInt16 >( nScCol ), static_cast< sal_uInt16 >( nScRow ) );
+ sal_uInt16 nLastXclCol = static_cast< sal_uInt16 >( nLastScCol );
+
+ const ScBaseCell* pScCell = aIt.GetCell();
+ XclExpCellRef xCell;
+
+ const ScPatternAttr* pPattern = aIt.GetPattern();
+
+ // handle overlapped merged cells before creating the cell record
+ sal_uInt32 nMergeBaseXFId = EXC_XFID_NOTFOUND;
+ bool bIsMergedBase = false;
+ if( pPattern )
+ {
+ const SfxItemSet& rItemSet = pPattern->GetItemSet();
+ // base cell in a merged range
+ const ScMergeAttr& rMergeItem = GETITEM( rItemSet, ScMergeAttr, ATTR_MERGE );
+ bIsMergedBase = rMergeItem.IsMerged();
+ /* overlapped cell in a merged range; in Excel all merged cells
+ must contain same XF index, for correct border */
+ const ScMergeFlagAttr& rMergeFlagItem = GETITEM( rItemSet, ScMergeFlagAttr, ATTR_MERGE_FLAG );
+ if( rMergeFlagItem.IsOverlapped() )
+ nMergeBaseXFId = mxMergedcells->GetBaseXFId( aScPos );
+ }
+
+ String aAddNoteText; // additional text to be appended to a note
+
+ CellType eCellType = pScCell ? pScCell->GetCellType() : CELLTYPE_NONE;
+ switch( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ {
+ double fValue = static_cast< const ScValueCell* >( pScCell )->GetValue();
+
+ // try to create a Boolean cell
+ if( pPattern && ((fValue == 0.0) || (fValue == 1.0)) )
+ {
+ ULONG nScNumFmt = GETITEMVALUE( pPattern->GetItemSet(), SfxUInt32Item, ATTR_VALUE_FORMAT, ULONG );
+ if( rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL )
+ xCell.reset( new XclExpBooleanCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, fValue != 0.0 ) );
+ }
+
+ // try to create an RK value (compressed floating-point number)
+ sal_Int32 nRkValue;
+ if( !xCell && XclTools::GetRKFromDouble( nRkValue, fValue ) )
+ xCell.reset( new XclExpRkCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, nRkValue ) );
+
+ // else: simple floating-point number cell
+ if( !xCell )
+ xCell.reset( new XclExpNumberCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, fValue ) );
+ }
+ break;
+
+ case CELLTYPE_STRING:
+ {
+ const ScStringCell& rScStrCell = *static_cast< const ScStringCell* >( pScCell );
+ xCell.reset( new XclExpLabelCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, rScStrCell ) );
+ }
+ break;
+
+ case CELLTYPE_EDIT:
+ {
+ const ScEditCell& rScEditCell = *static_cast< const ScEditCell* >( pScCell );
+ XclExpHyperlinkHelper aLinkHelper( GetRoot(), aScPos );
+ xCell.reset( new XclExpLabelCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, rScEditCell, aLinkHelper ) );
+
+ // add a single created HLINK record to the record list
+ if( aLinkHelper.HasLinkRecord() )
+ mxHyperlinkList->AppendRecord( aLinkHelper.GetLinkRecord() );
+ // add list of multiple URLs to the additional cell note text
+ if( aLinkHelper.HasMultipleUrls() )
+ ScGlobal::AddToken( aAddNoteText, aLinkHelper.GetUrlList(), '\n', 2 );
+ }
+ break;
+
+ case CELLTYPE_FORMULA:
+ {
+ const ScFormulaCell& rScFmlaCell = *static_cast< const ScFormulaCell* >( pScCell );
+ xCell.reset( new XclExpFormulaCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId,
+ rScFmlaCell, maArrayBfr, maShrfmlaBfr, maTableopBfr ) );
+ }
+ break;
+
+ default:
+ DBG_ERRORFILE( "XclExpCellTable::XclExpCellTable - unknown cell type" );
+ // run-through!
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ {
+ xCell.reset( new XclExpBlankCell(
+ GetRoot(), aXclPos, nLastXclCol, pPattern, nMergeBaseXFId ) );
+ }
+ break;
+ }
+
+ // insert the cell into the current row
+ if( xCell.is() )
+ maRowBfr.AppendCell( xCell, bIsMergedBase );
+
+ // notes
+ const ScPostIt* pScNote = pScCell ? pScCell->GetNote() : 0;
+ if( pScNote || (aAddNoteText.Len() > 0) )
+ mxNoteList->AppendNewRecord( new XclExpNote( GetRoot(), aScPos, pScNote, aAddNoteText ) );
+
+ // other sheet contents
+ if( pPattern )
+ {
+ const SfxItemSet& rItemSet = pPattern->GetItemSet();
+
+ // base cell in a merged range
+ if( bIsMergedBase )
+ {
+ const ScMergeAttr& rMergeItem = GETITEM( rItemSet, ScMergeAttr, ATTR_MERGE );
+ ScRange aScRange( aScPos );
+ aScRange.aEnd.IncCol( rMergeItem.GetColMerge() - 1 );
+ aScRange.aEnd.IncRow( rMergeItem.GetRowMerge() - 1 );
+ sal_uInt32 nXFId = xCell.is() ? xCell->GetFirstXFId() : EXC_XFID_NOTFOUND;
+ // #120156# blank cells merged vertically may occur repeatedly
+ DBG_ASSERT( (aScRange.aStart.Col() == aScRange.aEnd.Col()) || (nScCol == nLastScCol),
+ "XclExpCellTable::XclExpCellTable - invalid repeated blank merged cell" );
+ for( SCCOL nIndex = nScCol; nIndex <= nLastScCol; ++nIndex )
+ {
+ mxMergedcells->AppendRange( aScRange, nXFId );
+ aScRange.aStart.IncCol();
+ aScRange.aEnd.IncCol();
+ }
+ }
+
+ // data validation
+ if( ScfTools::CheckItem( rItemSet, ATTR_VALIDDATA, false ) )
+ {
+ ULONG nScHandle = GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALIDDATA, ULONG );
+ ScRange aScRange( aScPos );
+ aScRange.aEnd.SetCol( nLastScCol );
+ mxDval->InsertCellRange( aScRange, nScHandle );
+ }
+ }
+ }
+
+ // create missing row settings for rows anyhow flagged or with outlines
+ maRowBfr.CreateRows( ::std::max( nFirstUnflaggedScRow, nFirstUngroupedScRow ) );
+}
+
+void XclExpCellTable::Finalize()
+{
+ // Finalize multiple operations.
+ maTableopBfr.Finalize();
+
+ /* Finalize column buffer. This calculates column default XF indexes from
+ the XF identifiers and fills a vector with these XF indexes. */
+ ScfUInt16Vec aColXFIndexes;
+ maColInfoBfr.Finalize( aColXFIndexes );
+
+ /* Finalize row buffer. This calculates all cell XF indexes from the XF
+ identifiers. Then the XF index vector aColXFIndexes (filled above) is
+ used to calculate the row default formats. With this, all unneeded blank
+ cell records (equal to row default or column default) will be removed.
+ The function returns the (most used) default row format in aDefRowData. */
+ XclExpDefaultRowData aDefRowData;
+ maRowBfr.Finalize( aDefRowData, aColXFIndexes );
+
+ // Initialize the DEFROWHEIGHT record.
+ mxDefrowheight->SetDefaultData( aDefRowData );
+}
+
+XclExpRecordRef XclExpCellTable::CreateRecord( sal_uInt16 nRecId ) const
+{
+ XclExpRecordRef xRec;
+ switch( nRecId )
+ {
+ case EXC_ID3_DIMENSIONS: xRec.reset( new XclExpDelegatingRecord( const_cast<XclExpRowBuffer*>(&maRowBfr)->GetDimensions() ) ); break;
+ case EXC_ID2_DEFROWHEIGHT: xRec = mxDefrowheight; break;
+ case EXC_ID_GUTS: xRec = mxGuts; break;
+ case EXC_ID_NOTE: xRec = mxNoteList; break;
+ case EXC_ID_MERGEDCELLS: xRec = mxMergedcells; break;
+ case EXC_ID_HLINK: xRec = mxHyperlinkList; break;
+ case EXC_ID_DVAL: xRec = mxDval; break;
+ default: DBG_ERRORFILE( "XclExpCellTable::CreateRecord - unknown record id" );
+ }
+ return xRec;
+}
+
+void XclExpCellTable::Save( XclExpStream& rStrm )
+{
+ // DEFCOLWIDTH and COLINFOs
+ maColInfoBfr.Save( rStrm );
+ // ROWs and cell records
+ maRowBfr.Save( rStrm );
+}
+
+void XclExpCellTable::SaveXml( XclExpXmlStream& rStrm )
+{
+ maColInfoBfr.SaveXml( rStrm );
+ maRowBfr.SaveXml( rStrm );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xeview.cxx b/sc/source/filter/excel/xeview.cxx
new file mode 100644
index 000000000000..035afd0a5830
--- /dev/null
+++ b/sc/source/filter/excel/xeview.cxx
@@ -0,0 +1,538 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xeview.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "viewopti.hxx"
+#include "xelink.hxx"
+#include "xestyle.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+
+// Workbook view settings records =============================================
+
+XclExpWindow1::XclExpWindow1( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_WINDOW1, 18 ),
+ mnFlags( 0 ),
+ mnTabBarSize( 600 )
+{
+ const ScViewOptions& rViewOpt = rRoot.GetDoc().GetViewOptions();
+ ::set_flag( mnFlags, EXC_WIN1_HOR_SCROLLBAR, rViewOpt.GetOption( VOPT_HSCROLL ) );
+ ::set_flag( mnFlags, EXC_WIN1_VER_SCROLLBAR, rViewOpt.GetOption( VOPT_VSCROLL ) );
+ ::set_flag( mnFlags, EXC_WIN1_TABBAR, rViewOpt.GetOption( VOPT_TABCONTROLS ) );
+
+ double fTabBarWidth = rRoot.GetExtDocOptions().GetDocSettings().mfTabBarWidth;
+ if( (0.0 <= fTabBarWidth) && (fTabBarWidth <= 1.0) )
+ mnTabBarSize = static_cast< sal_uInt16 >( fTabBarWidth * 1000.0 + 0.5 );
+}
+
+void XclExpWindow1::SaveXml( XclExpXmlStream& rStrm )
+{
+ const XclExpTabInfo& rTabInfo = rStrm.GetRoot().GetTabInfo();
+
+ rStrm.GetCurrentStream()->singleElement( XML_workbookView,
+ // OOXTODO: XML_visibility, // ST_visibilty
+ // OOXTODO: XML_minimized, // bool
+ XML_showHorizontalScroll, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_WIN1_HOR_SCROLLBAR ) ),
+ XML_showVerticalScroll, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_WIN1_VER_SCROLLBAR ) ),
+ XML_showSheetTabs, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_WIN1_TABBAR ) ),
+ XML_xWindow, "0",
+ XML_yWindow, "0",
+ XML_windowWidth, OString::valueOf( (sal_Int32)0x4000 ).getStr(),
+ XML_windowHeight, OString::valueOf( (sal_Int32)0x2000 ).getStr(),
+ XML_tabRatio, OString::valueOf( (sal_Int32)mnTabBarSize ).getStr(),
+ XML_firstSheet, OString::valueOf( (sal_Int32)rTabInfo.GetFirstVisXclTab() ).getStr(),
+ XML_activeTab, OString::valueOf( (sal_Int32)rTabInfo.GetDisplayedXclTab() ).getStr(),
+ // OOXTODO: XML_autoFilterDateGrouping, // bool; AUTOFILTER12? 87Eh
+ FSEND );
+}
+
+void XclExpWindow1::WriteBody( XclExpStream& rStrm )
+{
+ const XclExpTabInfo& rTabInfo = rStrm.GetRoot().GetTabInfo();
+
+ rStrm << sal_uInt16( 0 ) // X position of the window
+ << sal_uInt16( 0 ) // Y position of the window
+ << sal_uInt16( 0x4000 ) // width of the window
+ << sal_uInt16( 0x2000 ) // height of the window
+ << mnFlags
+ << rTabInfo.GetDisplayedXclTab()
+ << rTabInfo.GetFirstVisXclTab()
+ << rTabInfo.GetXclSelectedCount()
+ << mnTabBarSize;
+}
+
+// Sheet view settings records ================================================
+
+XclExpWindow2::XclExpWindow2( const XclExpRoot& rRoot,
+ const XclTabViewData& rData, sal_uInt32 nGridColorId ) :
+ XclExpRecord( EXC_ID_WINDOW2, (rRoot.GetBiff() == EXC_BIFF8) ? 18 : 10 ),
+ maGridColor( rData.maGridColor ),
+ mnGridColorId( nGridColorId ),
+ mnFlags( 0 ),
+ maFirstXclPos( rData.maFirstXclPos ),
+ mnNormalZoom( rData.mnNormalZoom ),
+ mnPageZoom( rData.mnPageZoom )
+{
+ ::set_flag( mnFlags, EXC_WIN2_SHOWFORMULAS, rData.mbShowFormulas );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWGRID, rData.mbShowGrid );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWHEADINGS, rData.mbShowHeadings );
+ ::set_flag( mnFlags, EXC_WIN2_FROZEN, rData.mbFrozenPanes );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWZEROS, rData.mbShowZeros );
+ ::set_flag( mnFlags, EXC_WIN2_DEFGRIDCOLOR, rData.mbDefGridColor );
+ ::set_flag( mnFlags, EXC_WIN2_MIRRORED, rData.mbMirrored );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWOUTLINE, rData.mbShowOutline );
+ ::set_flag( mnFlags, EXC_WIN2_FROZENNOSPLIT, rData.mbFrozenPanes );
+ ::set_flag( mnFlags, EXC_WIN2_SELECTED, rData.mbSelected );
+ ::set_flag( mnFlags, EXC_WIN2_DISPLAYED, rData.mbDisplayed );
+ ::set_flag( mnFlags, EXC_WIN2_PAGEBREAKMODE, rData.mbPageMode );
+}
+
+void XclExpWindow2::WriteBody( XclExpStream& rStrm )
+{
+ const XclExpRoot& rRoot = rStrm.GetRoot();
+
+ rStrm << mnFlags
+ << maFirstXclPos;
+
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ rStrm << maGridColor;
+ break;
+ case EXC_BIFF8:
+ rStrm << rRoot.GetPalette().GetColorIndex( mnGridColorId )
+ << sal_uInt16( 0 )
+ << mnPageZoom
+ << mnNormalZoom
+ << sal_uInt32( 0 );
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpScl::XclExpScl( sal_uInt16 nZoom ) :
+ XclExpRecord( EXC_ID_SCL, 4 ),
+ mnNum( nZoom ),
+ mnDenom( 100 )
+{
+ Shorten( 2 );
+ Shorten( 5 );
+}
+
+void XclExpScl::Shorten( sal_uInt16 nFactor )
+{
+ while( (mnNum % nFactor == 0) && (mnDenom % nFactor == 0) )
+ {
+ mnNum = mnNum / nFactor;
+ mnDenom = mnDenom / nFactor;
+ }
+}
+
+void XclExpScl::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF4 );
+ rStrm << mnNum << mnDenom;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpPane::XclExpPane( const XclTabViewData& rData ) :
+ XclExpRecord( EXC_ID_PANE, 10 ),
+ mnSplitX( rData.mnSplitX ),
+ mnSplitY( rData.mnSplitY ),
+ maSecondXclPos( rData.maSecondXclPos ),
+ mnActivePane( rData.mnActivePane )
+{
+ DBG_ASSERT( rData.IsSplit(), "XclExpPane::XclExpPane - no PANE record for unsplit view" );
+}
+
+static const char* lcl_GetActivePane( sal_uInt8 nActivePane )
+{
+ switch( nActivePane )
+ {
+ case EXC_PANE_TOPLEFT: return "topLeft"; //break;
+ case EXC_PANE_TOPRIGHT: return "topRight"; //break;
+ case EXC_PANE_BOTTOMLEFT: return "bottomLeft"; //break;
+ case EXC_PANE_BOTTOMRIGHT: return "bottomRight"; //break;
+ }
+ return "**error: lcl_GetActivePane";
+}
+
+void XclExpPane::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_pane,
+ XML_xSplit, OString::valueOf( (sal_Int32)mnSplitX ).getStr(),
+ XML_ySplit, OString::valueOf( (sal_Int32)mnSplitY ).getStr(),
+ XML_topLeftCell, XclXmlUtils::ToOString( maSecondXclPos ).getStr(),
+ XML_activePane, lcl_GetActivePane( mnActivePane ),
+ // OOXTODO: XML_state,
+ FSEND );
+}
+
+void XclExpPane::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnSplitX
+ << mnSplitY
+ << maSecondXclPos
+ << mnActivePane;
+ if( rStrm.GetRoot().GetBiff() >= EXC_BIFF5 )
+ rStrm << sal_uInt8( 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpSelection::XclExpSelection( const XclTabViewData& rData, sal_uInt8 nPane ) :
+ XclExpRecord( EXC_ID_SELECTION, 15 ),
+ mnPane( nPane )
+{
+ if( const XclSelectionData* pSelData = rData.GetSelectionData( nPane ) )
+ maSelData = *pSelData;
+
+ // find the cursor position in the selection list (or add it)
+ XclRangeList& rXclSel = maSelData.maXclSelection;
+ bool bFound = false;
+ for( XclRangeList::const_iterator aIt = rXclSel.begin(), aEnd = rXclSel.end(); !bFound && (aIt != aEnd); ++aIt )
+ if( (bFound = aIt->Contains( maSelData.maXclCursor )) == true )
+ maSelData.mnCursorIdx = static_cast< sal_uInt16 >( aIt - rXclSel.begin() );
+ /* Cursor cell not found in list? (e.g. inactive pane, or removed in
+ ConvertRangeList(), because Calc cursor on invalid pos)
+ -> insert the valid Excel cursor. */
+ if( !bFound )
+ {
+ maSelData.mnCursorIdx = static_cast< sal_uInt16 >( rXclSel.size() );
+ rXclSel.push_back( XclRange( maSelData.maXclCursor ) );
+ }
+}
+
+void XclExpSelection::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_selection,
+ XML_pane, lcl_GetActivePane( mnPane ),
+ XML_activeCell, XclXmlUtils::ToOString( maSelData.maXclCursor ).getStr(),
+ XML_activeCellId, OString::valueOf( (sal_Int32) maSelData.mnCursorIdx ).getStr(),
+ XML_sqref, XclXmlUtils::ToOString( maSelData.maXclSelection ).getStr(),
+ FSEND );
+}
+
+void XclExpSelection::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnPane // pane for this selection
+ << maSelData.maXclCursor // cell cursor
+ << maSelData.mnCursorIdx; // index to range containing cursor
+ maSelData.maXclSelection.Write( rStrm, false );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpTabBgColor::XclExpTabBgColor( const XclTabViewData& rTabViewData ) :
+ XclExpRecord( EXC_ID_SHEETEXT, 18 ),
+ mrTabViewData( rTabViewData )
+{
+}
+//TODO Fix savexml...
+/*void XclExpTabBgColor::SaveXml( XclExpXmlStream& rStrm )
+{
+}*/
+
+void XclExpTabBgColor::WriteBody( XclExpStream& rStrm )
+{
+ if ( mrTabViewData.IsDefaultTabBgColor() )
+ return;
+ sal_uInt16 rt = 0x0862; //rt
+ sal_uInt16 grbitFrt = 0x0000; //grbit must be set to 0
+ sal_uInt32 unused = 0x00000000; //Use twice...
+ sal_uInt32 cb = 0x00000014; // Record Size, may be larger in future...
+ sal_uInt16 reserved = 0x0000; //trailing bits are 0
+ sal_uInt16 TabBgColorIndex;
+ XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
+ TabBgColorIndex = rPal.GetColorIndex(mrTabViewData.mnTabBgColorId);
+ if (TabBgColorIndex < 8 || TabBgColorIndex > 63 ) // only numbers 8 - 63 are valid numbers
+ TabBgColorIndex = 127; //Excel specs: 127 makes excel ignore tab color information.
+ rStrm << rt << grbitFrt << unused << unused << cb << TabBgColorIndex << reserved;
+}
+
+// Sheet view settings ========================================================
+
+namespace {
+
+/** Converts a Calc zoom factor into an Excel zoom factor. Returns 0 for a default zoom value. */
+sal_uInt16 lclGetXclZoom( long nScZoom, sal_uInt16 nDefXclZoom )
+{
+ sal_uInt16 nXclZoom = limit_cast< sal_uInt16 >( nScZoom, EXC_ZOOM_MIN, EXC_ZOOM_MAX );
+ return (nXclZoom == nDefXclZoom) ? 0 : nXclZoom;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpTabViewSettings::XclExpTabViewSettings( const XclExpRoot& rRoot, SCTAB nScTab ) :
+ XclExpRoot( rRoot ),
+ mnGridColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT ) )
+{
+ // *** sheet flags ***
+
+ const XclExpTabInfo& rTabInfo = GetTabInfo();
+ maData.mbSelected = rTabInfo.IsSelectedTab( nScTab );
+ maData.mbDisplayed = rTabInfo.IsDisplayedTab( nScTab );
+ maData.mbMirrored = rTabInfo.IsMirroredTab( nScTab );
+
+ const ScViewOptions& rViewOpt = GetDoc().GetViewOptions();
+ maData.mbShowFormulas = rViewOpt.GetOption( VOPT_FORMULAS );
+ maData.mbShowGrid = rViewOpt.GetOption( VOPT_GRID );
+ maData.mbShowHeadings = rViewOpt.GetOption( VOPT_HEADER );
+ maData.mbShowZeros = rViewOpt.GetOption( VOPT_NULLVALS );
+ maData.mbShowOutline = rViewOpt.GetOption( VOPT_OUTLINER );
+
+ // *** sheet options: cursor, selection, splits, grid color, zoom ***
+
+ if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nScTab ) )
+ {
+ const ScExtTabSettings& rTabSett = *pTabSett;
+ XclExpAddressConverter& rAddrConv = GetAddressConverter();
+
+ // first visible cell in top-left pane
+ if( (rTabSett.maFirstVis.Col() >= 0) && (rTabSett.maFirstVis.Row() >= 0) )
+ maData.maFirstXclPos = rAddrConv.CreateValidAddress( rTabSett.maFirstVis, false );
+
+ // first visible cell in additional pane(s)
+ if( (rTabSett.maSecondVis.Col() >= 0) && (rTabSett.maSecondVis.Row() >= 0) )
+ maData.maSecondXclPos = rAddrConv.CreateValidAddress( rTabSett.maSecondVis, false );
+
+ // active pane
+ switch( rTabSett.meActivePane )
+ {
+ case SCEXT_PANE_TOPLEFT: maData.mnActivePane = EXC_PANE_TOPLEFT; break;
+ case SCEXT_PANE_TOPRIGHT: maData.mnActivePane = EXC_PANE_TOPRIGHT; break;
+ case SCEXT_PANE_BOTTOMLEFT: maData.mnActivePane = EXC_PANE_BOTTOMLEFT; break;
+ case SCEXT_PANE_BOTTOMRIGHT: maData.mnActivePane = EXC_PANE_BOTTOMRIGHT; break;
+ }
+
+ // freeze/split position
+ maData.mbFrozenPanes = rTabSett.mbFrozenPanes;
+ if( maData.mbFrozenPanes )
+ {
+ /* Frozen panes: handle split position as row/column positions.
+ #i35812# Excel uses number of visible rows/columns, Calc uses position of freeze. */
+ SCCOL nFreezeScCol = rTabSett.maFreezePos.Col();
+ if( (0 < nFreezeScCol) && (nFreezeScCol <= GetXclMaxPos().Col()) )
+ maData.mnSplitX = static_cast< sal_uInt16 >( nFreezeScCol ) - maData.maFirstXclPos.mnCol;
+ SCROW nFreezeScRow = rTabSett.maFreezePos.Row();
+ if( (0 < nFreezeScRow) && (nFreezeScRow <= GetXclMaxPos().Row()) )
+ maData.mnSplitY = static_cast< sal_uInt16 >( nFreezeScRow ) - maData.maFirstXclPos.mnRow;
+ // if both splits are left out (address overflow), remove the frozen flag
+ maData.mbFrozenPanes = maData.IsSplit();
+
+ // #i20671# frozen panes: mostright/mostbottom pane is active regardless of cursor position
+ if( maData.HasPane( EXC_PANE_BOTTOMRIGHT ) )
+ maData.mnActivePane = EXC_PANE_BOTTOMRIGHT;
+ else if( maData.HasPane( EXC_PANE_TOPRIGHT ) )
+ maData.mnActivePane = EXC_PANE_TOPRIGHT;
+ else if( maData.HasPane( EXC_PANE_BOTTOMLEFT ) )
+ maData.mnActivePane = EXC_PANE_BOTTOMLEFT;
+ }
+ else
+ {
+ // split window: position is in twips
+ maData.mnSplitX = ulimit_cast< sal_uInt16 >( rTabSett.maSplitPos.X() );
+ maData.mnSplitY = ulimit_cast< sal_uInt16 >( rTabSett.maSplitPos.Y() );
+ }
+
+ // selection
+ CreateSelectionData( EXC_PANE_TOPLEFT, rTabSett.maCursor, rTabSett.maSelection );
+ CreateSelectionData( EXC_PANE_TOPRIGHT, rTabSett.maCursor, rTabSett.maSelection );
+ CreateSelectionData( EXC_PANE_BOTTOMLEFT, rTabSett.maCursor, rTabSett.maSelection );
+ CreateSelectionData( EXC_PANE_BOTTOMRIGHT, rTabSett.maCursor, rTabSett.maSelection );
+
+ // grid color
+ const Color& rGridColor = rTabSett.maGridColor;
+ maData.mbDefGridColor = rGridColor.GetColor() == COL_AUTO;
+ if( !maData.mbDefGridColor )
+ {
+ if( GetBiff() == EXC_BIFF8 )
+ mnGridColorId = GetPalette().InsertColor( rGridColor, EXC_COLOR_GRID );
+ else
+ maData.maGridColor = rGridColor;
+ }
+
+ // view mode and zoom
+ maData.mbPageMode = (GetBiff() == EXC_BIFF8) && rTabSett.mbPageMode;
+ maData.mnNormalZoom = lclGetXclZoom( rTabSett.mnNormalZoom, EXC_WIN2_NORMALZOOM_DEF );
+ maData.mnPageZoom = lclGetXclZoom( rTabSett.mnPageZoom, EXC_WIN2_PAGEZOOM_DEF );
+ maData.mnCurrentZoom = maData.mbPageMode ? maData.mnPageZoom : maData.mnNormalZoom;
+ }
+
+ // Tab Bg Color
+ if ( GetBiff() == EXC_BIFF8 && !GetDoc().IsDefaultTabBgColor(nScTab) )
+ {
+ XclExpPalette& rPal = GetPalette();
+ maData.maTabBgColor = GetDoc().GetTabBgColor(nScTab);
+ maData.mnTabBgColorId = rPal.InsertColor(maData.maTabBgColor, EXC_COLOR_TABBG, EXC_COLOR_NOTABBG );
+ }
+}
+
+void XclExpTabViewSettings::Save( XclExpStream& rStrm )
+{
+ WriteWindow2( rStrm );
+ WriteScl( rStrm );
+ WritePane( rStrm );
+ WriteSelection( rStrm, EXC_PANE_TOPLEFT );
+ WriteSelection( rStrm, EXC_PANE_TOPRIGHT );
+ WriteSelection( rStrm, EXC_PANE_BOTTOMLEFT );
+ WriteSelection( rStrm, EXC_PANE_BOTTOMRIGHT );
+ WriteTabBgColor( rStrm );
+}
+
+static void lcl_WriteSelection( XclExpXmlStream& rStrm, const XclTabViewData& rData, sal_uInt8 nPane )
+{
+ if( rData.HasPane( nPane ) )
+ XclExpSelection( rData, nPane ).SaveXml( rStrm );
+}
+
+OString lcl_GetZoom( sal_uInt16 nZoom )
+{
+ if( nZoom )
+ return OString::valueOf( (sal_Int32)nZoom );
+ return OString( "100" );
+}
+
+void XclExpTabViewSettings::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_sheetViews, FSEND );
+ rWorksheet->startElement( XML_sheetView,
+ XML_windowProtection, XclXmlUtils::ToPsz( maData.mbFrozenPanes ),
+ XML_showFormulas, XclXmlUtils::ToPsz( maData.mbShowFormulas ),
+ XML_showGridLines, XclXmlUtils::ToPsz( maData.mbShowGrid ),
+ XML_showRowColHeaders, XclXmlUtils::ToPsz( maData.mbShowHeadings ),
+ XML_showZeros, XclXmlUtils::ToPsz( maData.mbShowZeros ),
+ XML_rightToLeft, XclXmlUtils::ToPsz( maData.mbMirrored ),
+ XML_tabSelected, XclXmlUtils::ToPsz( maData.mbSelected ),
+ // OOXTODO: XML_showRuler,
+ XML_showOutlineSymbols, XclXmlUtils::ToPsz( maData.mbShowOutline ),
+ XML_defaultGridColor, mnGridColorId == XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT ) ? "true" : "false",
+ // OOXTODO: XML_showWhiteSpace,
+ XML_view, maData.mbPageMode ? "pageBreakPreview" : "normal", // OOXTODO: pageLayout
+ XML_topLeftCell, XclXmlUtils::ToOString( maData.maFirstXclPos ).getStr(),
+ XML_colorId, OString::valueOf( (sal_Int32) rStrm.GetRoot().GetPalette().GetColorIndex( mnGridColorId ) ).getStr(),
+ XML_zoomScale, lcl_GetZoom( maData.mnCurrentZoom ).getStr(),
+ XML_zoomScaleNormal, lcl_GetZoom( maData.mnNormalZoom ).getStr(),
+ // OOXTODO: XML_zoomScaleSheetLayoutView,
+ XML_zoomScalePageLayoutView, lcl_GetZoom( maData.mnPageZoom ).getStr(),
+ XML_workbookViewId, "0", // OOXTODO? 0-based index of document(xl/workbook.xml)/workbook/bookviews/workbookView
+ // should always be 0, as we only generate 1 such element.
+ FSEND );
+ if( maData.IsSplit() )
+ {
+ XclExpPane aPane( maData );
+ aPane.SaveXml( rStrm );
+ }
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_TOPLEFT );
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_TOPRIGHT );
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_BOTTOMLEFT );
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_BOTTOMRIGHT );
+ rWorksheet->endElement( XML_sheetView );
+ // OOXTODO: XML_extLst
+ rWorksheet->endElement( XML_sheetViews );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpTabViewSettings::CreateSelectionData( sal_uInt8 nPane,
+ const ScAddress& rCursor, const ScRangeList& rSelection )
+{
+ if( maData.HasPane( nPane ) )
+ {
+ XclSelectionData& rSelData = maData.CreateSelectionData( nPane );
+
+ // first step: use top-left visible cell as cursor
+ rSelData.maXclCursor.mnCol = ((nPane == EXC_PANE_TOPLEFT) || (nPane == EXC_PANE_BOTTOMLEFT)) ?
+ maData.maFirstXclPos.mnCol : maData.maSecondXclPos.mnCol;
+ rSelData.maXclCursor.mnRow = ((nPane == EXC_PANE_TOPLEFT) || (nPane == EXC_PANE_TOPRIGHT)) ?
+ maData.maFirstXclPos.mnRow : maData.maSecondXclPos.mnRow;
+
+ // second step, active pane: create actual selection data with current cursor position
+ if( nPane == maData.mnActivePane )
+ {
+ XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ // cursor position (keep top-left pane position from above, if rCursor is invalid)
+ if( (rCursor.Col() >= 0) && (rCursor.Row() >= 0) )
+ rSelData.maXclCursor = rAddrConv.CreateValidAddress( rCursor, false );
+ // selection
+ rAddrConv.ConvertRangeList( rSelData.maXclSelection, rSelection, false );
+ }
+ }
+}
+
+void XclExpTabViewSettings::WriteWindow2( XclExpStream& rStrm ) const
+{
+// #i43553# GCC 3.3 parse error
+// XclExpWindow2( GetRoot(), maData, mnGridColorId ).Save( rStrm );
+ XclExpWindow2 aWindow2( GetRoot(), maData, mnGridColorId );
+ aWindow2.Save( rStrm );
+}
+
+void XclExpTabViewSettings::WriteScl( XclExpStream& rStrm ) const
+{
+ if( maData.mnCurrentZoom != 0 )
+ XclExpScl( maData.mnCurrentZoom ).Save( rStrm );
+}
+
+void XclExpTabViewSettings::WritePane( XclExpStream& rStrm ) const
+{
+ if( maData.IsSplit() )
+// #i43553# GCC 3.3 parse error
+// XclExpPane( GetRoot(), maData ).Save( rStrm );
+ {
+ XclExpPane aPane( maData );
+ aPane.Save( rStrm );
+ }
+}
+
+void XclExpTabViewSettings::WriteSelection( XclExpStream& rStrm, sal_uInt8 nPane ) const
+{
+ if( maData.HasPane( nPane ) )
+ XclExpSelection( maData, nPane ).Save( rStrm );
+}
+
+void XclExpTabViewSettings::WriteTabBgColor( XclExpStream& rStrm ) const
+{
+ if ( !maData.IsDefaultTabBgColor() )
+ XclExpTabBgColor( maData ).Save( rStrm );
+}
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx
new file mode 100755
index 000000000000..7cbd74a836d2
--- /dev/null
+++ b/sc/source/filter/excel/xichart.cxx
@@ -0,0 +1,4147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xichart.hxx"
+
+#include <algorithm>
+#include <memory>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
+#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
+#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
+#include <com/sun/star/chart/ChartAxisPosition.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XDiagramPositioning.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/CurveStyle.hpp>
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/LegendExpansion.hpp>
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <com/sun/star/chart2/TickmarkStyle.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+
+#include <sfx2/objsh.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/unoapi.hxx>
+
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "rangeutl.hxx"
+#include "tokenarray.hxx"
+#include "token.hxx"
+#include "compiler.hxx"
+#include "reftokenhelper.hxx"
+#include "chartlis.hxx"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xiformula.hxx"
+#include "xistyle.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::util::XNumberFormatsSupplier;
+using ::com::sun::star::drawing::XDrawPage;
+using ::com::sun::star::drawing::XDrawPageSupplier;
+using ::com::sun::star::drawing::XShape;
+
+using ::com::sun::star::chart2::IncrementData;
+using ::com::sun::star::chart2::RelativePosition;
+using ::com::sun::star::chart2::ScaleData;
+using ::com::sun::star::chart2::SubIncrement;
+using ::com::sun::star::chart2::XAxis;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::chart2::XChartType;
+using ::com::sun::star::chart2::XChartTypeContainer;
+using ::com::sun::star::chart2::XCoordinateSystem;
+using ::com::sun::star::chart2::XCoordinateSystemContainer;
+using ::com::sun::star::chart2::XDataSeries;
+using ::com::sun::star::chart2::XDataSeriesContainer;
+using ::com::sun::star::chart2::XDiagram;
+using ::com::sun::star::chart2::XFormattedString;
+using ::com::sun::star::chart2::XLegend;
+using ::com::sun::star::chart2::XRegressionCurve;
+using ::com::sun::star::chart2::XRegressionCurveContainer;
+using ::com::sun::star::chart2::XScaling;
+using ::com::sun::star::chart2::XTitle;
+using ::com::sun::star::chart2::XTitled;
+
+using ::com::sun::star::chart2::data::XDataProvider;
+using ::com::sun::star::chart2::data::XDataReceiver;
+using ::com::sun::star::chart2::data::XDataSequence;
+using ::com::sun::star::chart2::data::XDataSink;
+using ::com::sun::star::chart2::data::XLabeledDataSequence;
+
+using ::formula::FormulaToken;
+using ::formula::StackVar;
+
+namespace cssc = ::com::sun::star::chart;
+namespace cssc2 = ::com::sun::star::chart2;
+
+// Helpers ====================================================================
+
+namespace {
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclChRectangle& rRect )
+{
+ return rStrm >> rRect.mnX >> rRect.mnY >> rRect.mnWidth >> rRect.mnHeight;
+}
+
+template< typename Type >
+void lclSetValueOrClearAny( Any& rAny, const Type& rValue, bool bClear )
+{
+ if( bClear )
+ rAny.clear();
+ else
+ rAny <<= rValue;
+}
+
+void lclSetExpValueOrClearAny( Any& rAny, double fValue, bool bLogScale, bool bClear )
+{
+ if( !bClear && bLogScale )
+ fValue = pow( 10.0, fValue );
+ lclSetValueOrClearAny( rAny, fValue, bClear );
+}
+
+} // namespace
+
+// Common =====================================================================
+
+/** Stores global data needed in various classes of the Chart import filter. */
+struct XclImpChRootData : public XclChRootData
+{
+ XclImpChChart& mrChartData; /// The chart data object.
+
+ inline explicit XclImpChRootData( XclImpChChart& rChartData ) : mrChartData( rChartData ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ) :
+ XclImpRoot( rRoot ),
+ mxChData( new XclImpChRootData( rChartData ) )
+{
+}
+
+XclImpChRoot::~XclImpChRoot()
+{
+}
+
+XclImpChChart& XclImpChRoot::GetChartData() const
+{
+ return mxChData->mrChartData;
+}
+
+const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
+}
+
+const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfoFromRecId( nRecId );
+}
+
+const XclChFormatInfo& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
+{
+ return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
+}
+
+Color XclImpChRoot::GetFontAutoColor() const
+{
+ return GetPalette().GetColor( EXC_COLOR_CHWINDOWTEXT );
+}
+
+Color XclImpChRoot::GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const
+{
+ return GetPalette().GetColor( XclChartHelper::GetSeriesLineAutoColorIdx( nFormatIdx ) );
+}
+
+Color XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const
+{
+ const XclImpPalette& rPal = GetPalette();
+ Color aColor = rPal.GetColor( XclChartHelper::GetSeriesFillAutoColorIdx( nFormatIdx ) );
+ sal_uInt8 nTrans = XclChartHelper::GetSeriesFillAutoTransp( nFormatIdx );
+ return ScfTools::GetMixedColor( aColor, rPal.GetColor( EXC_COLOR_CHWINDOWBACK ), nTrans );
+}
+
+void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) const
+{
+ // create formatting object tables
+ mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
+
+ // lock the model to suppress any internal updates
+ Reference< XModel > xModel( xChartDoc, UNO_QUERY );
+ if( xModel.is() )
+ xModel->lockControllers();
+
+ SfxObjectShell* pDocShell = GetDocShell();
+ Reference< XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
+ if( pDocShell && xDataRec.is() )
+ {
+ // create and register a data provider
+ Reference< XDataProvider > xDataProv(
+ ScfApiHelper::CreateInstance( pDocShell, SERVICE_CHART2_DATAPROVIDER ), UNO_QUERY );
+ if( xDataProv.is() )
+ xDataRec->attachDataProvider( xDataProv );
+ // attach the number formatter
+ Reference< XNumberFormatsSupplier > xNumFmtSupp( pDocShell->GetModel(), UNO_QUERY );
+ if( xNumFmtSupp.is() )
+ xDataRec->attachNumberFormatsSupplier( xNumFmtSupp );
+ }
+}
+
+void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const
+{
+ rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
+ // unlock the model
+ Reference< XModel > xModel( mxChData->mxChartDoc, UNO_QUERY );
+ if( xModel.is() )
+ xModel->unlockControllers();
+ rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
+
+ mxChData->FinishConversion();
+}
+
+Reference< XDataProvider > XclImpChRoot::GetDataProvider() const
+{
+ return mxChData->mxChartDoc->getDataProvider();
+}
+
+Reference< XShape > XclImpChRoot::GetTitleShape( const XclChTextKey& rTitleKey ) const
+{
+ return mxChData->GetTitleShape( rTitleKey );
+}
+
+sal_Int32 XclImpChRoot::CalcHmmFromChartX( sal_Int32 nPosX ) const
+{
+ return static_cast< sal_Int32 >( mxChData->mfUnitSizeX * nPosX + mxChData->mnBorderGapX + 0.5 );
+}
+
+sal_Int32 XclImpChRoot::CalcHmmFromChartY( sal_Int32 nPosY ) const
+{
+ return static_cast< sal_Int32 >( mxChData->mfUnitSizeY * nPosY + mxChData->mnBorderGapY + 0.5 );
+}
+
+::com::sun::star::awt::Rectangle XclImpChRoot::CalcHmmFromChartRect( const XclChRectangle& rRect ) const
+{
+ return ::com::sun::star::awt::Rectangle(
+ CalcHmmFromChartX( rRect.mnX ),
+ CalcHmmFromChartY( rRect.mnY ),
+ CalcHmmFromChartX( rRect.mnWidth ),
+ CalcHmmFromChartY( rRect.mnHeight ) );
+}
+
+double XclImpChRoot::CalcRelativeFromChartX( sal_Int32 nPosX ) const
+{
+ return static_cast< double >( CalcHmmFromChartX( nPosX ) ) / mxChData->maChartRect.GetWidth();
+}
+
+double XclImpChRoot::CalcRelativeFromChartY( sal_Int32 nPosY ) const
+{
+ return static_cast< double >( CalcHmmFromChartY( nPosY ) ) / mxChData->maChartRect.GetHeight();
+}
+
+void XclImpChRoot::ConvertLineFormat( ScfPropertySet& rPropSet,
+ const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().WriteLineProperties(
+ rPropSet, *mxChData->mxLineDashTable, rLineFmt, ePropMode );
+}
+
+void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().WriteAreaProperties( rPropSet, rAreaFmt, ePropMode );
+}
+
+void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet,
+ const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().WriteEscherProperties( rPropSet,
+ *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable,
+ rEscherFmt, rPicFmt, ePropMode );
+}
+
+void XclImpChRoot::ConvertFont( ScfPropertySet& rPropSet,
+ sal_uInt16 nFontIdx, const Color* pFontColor ) const
+{
+ GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CHART, nFontIdx, pFontColor );
+}
+
+void XclImpChRoot::ConvertPieRotation( ScfPropertySet& rPropSet, sal_uInt16 nAngle )
+{
+ sal_Int32 nApiRot = (450 - (nAngle % 360)) % 360;
+ rPropSet.SetProperty( EXC_CHPROP_STARTINGANGLE, nApiRot );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChGroupBase::~XclImpChGroupBase()
+{
+}
+
+void XclImpChGroupBase::ReadRecordGroup( XclImpStream& rStrm )
+{
+ // read contents of the header record
+ ReadHeaderRecord( rStrm );
+
+ // only read sub records, if the next record is a CHBEGIN
+ if( rStrm.GetNextRecId() == EXC_ID_CHBEGIN )
+ {
+ // read the CHBEGIN record, may be used for special initial processing
+ rStrm.StartNextRecord();
+ ReadSubRecord( rStrm );
+
+ // read the nested records
+ bool bLoop = true;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bLoop = nRecId != EXC_ID_CHEND;
+ // skip unsupported nested blocks
+ if( nRecId == EXC_ID_CHBEGIN )
+ SkipBlock( rStrm );
+ else
+ ReadSubRecord( rStrm );
+ }
+ }
+ /* Returns with current CHEND record or unchanged stream, if no record
+ group present. In every case another call to StartNextRecord() will go
+ to next record of interest. */
+}
+
+void XclImpChGroupBase::SkipBlock( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecId() == EXC_ID_CHBEGIN, "XclImpChGroupBase::SkipBlock - no CHBEGIN record" );
+ // do nothing if current record is not CHBEGIN
+ bool bLoop = rStrm.GetRecId() == EXC_ID_CHBEGIN;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bLoop = nRecId != EXC_ID_CHEND;
+ // skip nested record groups
+ if( nRecId == EXC_ID_CHBEGIN )
+ SkipBlock( rStrm );
+ }
+}
+
+// Frame formatting ===========================================================
+
+void XclImpChFramePos::ReadChFramePos( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnTLMode >> maData.mnBRMode;
+ /* According to the spec, the upper 16 bits of all members in the
+ rectangle are unused and may contain garbage. */
+ maData.maRect.mnX = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+ maData.maRect.mnY = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+ maData.maRect.mnWidth = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+ maData.maRect.mnHeight = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpChLineFormat::ReadChLineFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.maColor >> maData.mnPattern >> maData.mnWeight >> maData.mnFlags;
+
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ // #116397# BIFF8: index into palette used instead of RGB data
+ maData.maColor = rRoot.GetPalette().GetColor( rStrm.ReaduInt16() );
+}
+
+void XclImpChLineFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ if( IsAuto() )
+ {
+ XclChLineFormat aLineFmt;
+ aLineFmt.maColor = (eObjType == EXC_CHOBJTYPE_LINEARSERIES) ?
+ rRoot.GetSeriesLineAutoColor( nFormatIdx ) :
+ rRoot.GetPalette().GetColor( rFmtInfo.mnAutoLineColorIdx );
+ aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ aLineFmt.mnWeight = rFmtInfo.mnAutoLineWeight;
+ rRoot.ConvertLineFormat( rPropSet, aLineFmt, rFmtInfo.mePropMode );
+ }
+ else
+ {
+ rRoot.ConvertLineFormat( rPropSet, maData, rFmtInfo.mePropMode );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpChAreaFormat::ReadChAreaFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.maPattColor >> maData.maBackColor >> maData.mnPattern >> maData.mnFlags;
+
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ {
+ // #116397# BIFF8: index into palette used instead of RGB data
+ const XclImpPalette& rPal = rRoot.GetPalette();
+ maData.maPattColor = rPal.GetColor( rStrm.ReaduInt16() );
+ maData.maBackColor = rPal.GetColor( rStrm.ReaduInt16());
+ }
+}
+
+void XclImpChAreaFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ if( IsAuto() )
+ {
+ XclChAreaFormat aAreaFmt;
+ aAreaFmt.maPattColor = (eObjType == EXC_CHOBJTYPE_FILLEDSERIES) ?
+ rRoot.GetSeriesFillAutoColor( nFormatIdx ) :
+ rRoot.GetPalette().GetColor( rFmtInfo.mnAutoPattColorIdx );
+ aAreaFmt.mnPattern = EXC_PATT_SOLID;
+ rRoot.ConvertAreaFormat( rPropSet, aAreaFmt, rFmtInfo.mePropMode );
+ }
+ else
+ {
+ rRoot.ConvertAreaFormat( rPropSet, maData, rFmtInfo.mePropMode );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot& rRoot )
+{
+ maData.mxItemSet.reset(
+ new SfxItemSet( rRoot.GetDoc().GetDrawLayer()->GetItemPool() ) );
+}
+
+void XclImpChEscherFormat::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ // read from stream - CHESCHERFORMAT uses own ID for record continuation
+ XclImpDffPropSet aPropSet( rStrm.GetRoot() );
+ rStrm.ResetRecord( true, rStrm.GetRecId() );
+ rStrm >> aPropSet;
+ // get the data
+ aPropSet.FillToItemSet( *maData.mxItemSet );
+ // get bitmap mode from DFF item set
+ sal_uInt32 nType = aPropSet.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
+ maPicFmt.mnBmpMode = (nType == mso_fillPicture) ? EXC_CHPICFORMAT_STRETCH : EXC_CHPICFORMAT_STACK;
+}
+
+void XclImpChEscherFormat::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHPICFORMAT:
+ rStrm >> maPicFmt.mnBmpMode >> maPicFmt.mnFormat >> maPicFmt.mnFlags >> maPicFmt.mfScale;
+ break;
+ }
+}
+
+void XclImpChEscherFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType ) const
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ rRoot.ConvertEscherFormat( rPropSet, maData, maPicFmt, rFmtInfo.mePropMode );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChFrameBase::XclImpChFrameBase( const XclChFormatInfo& rFmtInfo )
+{
+ if( rFmtInfo.mbCreateDefFrame ) switch( rFmtInfo.meDefFrameType )
+ {
+ case EXC_CHFRAMETYPE_AUTO:
+ mxLineFmt.reset( new XclImpChLineFormat );
+ if( rFmtInfo.mbIsFrame )
+ mxAreaFmt.reset( new XclImpChAreaFormat );
+ break;
+ case EXC_CHFRAMETYPE_INVISIBLE:
+ {
+ XclChLineFormat aLineFmt;
+ ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
+ aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
+ mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
+ if( rFmtInfo.mbIsFrame )
+ {
+ XclChAreaFormat aAreaFmt;
+ ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
+ aAreaFmt.mnPattern = EXC_PATT_NONE;
+ mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpChFrameBase::XclImpChFrameBase - unknown frame type" );
+ }
+}
+
+void XclImpChFrameBase::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHLINEFORMAT:
+ mxLineFmt.reset( new XclImpChLineFormat );
+ mxLineFmt->ReadChLineFormat( rStrm );
+ break;
+ case EXC_ID_CHAREAFORMAT:
+ mxAreaFmt.reset( new XclImpChAreaFormat );
+ mxAreaFmt->ReadChAreaFormat( rStrm );
+ break;
+ case EXC_ID_CHESCHERFORMAT:
+ mxEscherFmt.reset( new XclImpChEscherFormat( rStrm.GetRoot() ) );
+ mxEscherFmt->ReadRecordGroup( rStrm );
+ break;
+ }
+}
+
+void XclImpChFrameBase::ConvertLineBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ if( mxLineFmt.is() )
+ mxLineFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
+}
+
+void XclImpChFrameBase::ConvertAreaBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
+ {
+ // CHESCHERFORMAT overrides CHAREAFORMAT (even if it is auto)
+ if( mxEscherFmt.is() )
+ mxEscherFmt->Convert( rRoot, rPropSet, eObjType );
+ else if( mxAreaFmt.is() )
+ mxAreaFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
+ }
+}
+
+void XclImpChFrameBase::ConvertFrameBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ ConvertLineBase( rRoot, rPropSet, eObjType, nFormatIdx );
+ ConvertAreaBase( rRoot, rPropSet, eObjType, nFormatIdx );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChFrame::XclImpChFrame( const XclImpChRoot& rRoot, XclChObjectType eObjType ) :
+ XclImpChFrameBase( rRoot.GetFormatInfo( eObjType ) ),
+ XclImpChRoot( rRoot ),
+ meObjType( eObjType )
+{
+}
+
+void XclImpChFrame::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnFormat >> maData.mnFlags;
+}
+
+void XclImpChFrame::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
+{
+ const XclImpPalette& rPal = GetPalette();
+
+ if( rLineData.IsVisible() && (!mxLineFmt || !mxLineFmt->HasLine()) )
+ {
+ // line formatting
+ XclChLineFormat aLineFmt;
+ aLineFmt.maColor = rPal.GetColor( rLineData.mnColorIdx );
+ switch( rLineData.mnStyle )
+ {
+ case EXC_OBJ_LINE_SOLID: aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID; break;
+ case EXC_OBJ_LINE_DASH: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASH; break;
+ case EXC_OBJ_LINE_DOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DOT; break;
+ case EXC_OBJ_LINE_DASHDOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOT; break;
+ case EXC_OBJ_LINE_DASHDOTDOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOTDOT; break;
+ case EXC_OBJ_LINE_MEDTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS; break;
+ case EXC_OBJ_LINE_DARKTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS; break;
+ case EXC_OBJ_LINE_LIGHTTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS; break;
+ case EXC_OBJ_LINE_NONE: aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE; break;
+ default: aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ }
+ switch( rLineData.mnWidth )
+ {
+ case EXC_OBJ_LINE_HAIR: aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR; break;
+ case EXC_OBJ_LINE_THIN: aLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE; break;
+ case EXC_OBJ_LINE_MEDIUM: aLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE; break;
+ case EXC_OBJ_LINE_THICK: aLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE; break;
+ default: aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
+ }
+ ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, rLineData.IsAuto() );
+ mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
+ }
+
+ if( rFillData.IsFilled() && (!mxAreaFmt || !mxAreaFmt->HasArea()) && !mxEscherFmt )
+ {
+ // area formatting
+ XclChAreaFormat aAreaFmt;
+ aAreaFmt.maPattColor = rPal.GetColor( rFillData.mnPattColorIdx );
+ aAreaFmt.maBackColor = rPal.GetColor( rFillData.mnBackColorIdx );
+ aAreaFmt.mnPattern = rFillData.mnPattern;
+ ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, rFillData.IsAuto() );
+ mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
+ }
+}
+
+void XclImpChFrame::Convert( ScfPropertySet& rPropSet ) const
+{
+ ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
+}
+
+// Source links ===============================================================
+
+namespace {
+
+/** Creates a labeled data sequence object, adds link for series title if present. */
+Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
+ XclImpChSourceLinkRef xValueLink, const OUString& rValueRole,
+ const XclImpChSourceLink* pTitleLink = 0 )
+{
+ // create data sequence for values and title
+ Reference< XDataSequence > xValueSeq;
+ if( xValueLink.is() )
+ xValueSeq = xValueLink->CreateDataSequence( rValueRole );
+ Reference< XDataSequence > xTitleSeq;
+ if( pTitleLink )
+ xTitleSeq = pTitleLink->CreateDataSequence( EXC_CHPROP_ROLE_LABEL );
+
+ // create the labeled data sequence, if values or title are present
+ Reference< XLabeledDataSequence > xLabeledSeq;
+ if( xValueSeq.is() || xTitleSeq.is() )
+ xLabeledSeq.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_LABELEDDATASEQ ), UNO_QUERY );
+ if( xLabeledSeq.is() )
+ {
+ if( xValueSeq.is() )
+ xLabeledSeq->setValues( xValueSeq );
+ if( xTitleSeq.is() )
+ xLabeledSeq->setLabel( xTitleSeq );
+ }
+ return xLabeledSeq;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclImpChSourceLink::XclImpChSourceLink( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+XclImpChSourceLink::~XclImpChSourceLink()
+{
+}
+
+void XclImpChSourceLink::ReadChSourceLink( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnDestType
+ >> maData.mnLinkType
+ >> maData.mnFlags
+ >> maData.mnNumFmtIdx;
+
+ mxTokenArray.reset();
+ if( GetLinkType() == EXC_CHSRCLINK_WORKSHEET )
+ {
+ // read token array
+ XclTokenArray aXclTokArr;
+ rStrm >> aXclTokArr;
+
+ // convert BIFF formula tokens to Calc token array
+ if( const ScTokenArray* pTokens = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aXclTokArr ) )
+ mxTokenArray.reset( pTokens->Clone() );
+ }
+
+ // try to read a following CHSTRING record
+ if( (rStrm.GetNextRecId() == EXC_ID_CHSTRING) && rStrm.StartNextRecord() )
+ {
+ mxString.reset( new XclImpString );
+ rStrm.Ignore( 2 );
+ mxString->Read( rStrm, EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
+ }
+}
+
+void XclImpChSourceLink::SetString( const String& rString )
+{
+ if( !mxString )
+ mxString.reset( new XclImpString );
+ mxString->SetText( rString );
+}
+
+void XclImpChSourceLink::SetTextFormats( const XclFormatRunVec& rFormats )
+{
+ if( mxString.is() )
+ mxString->SetFormats( rFormats );
+}
+
+sal_uInt16 XclImpChSourceLink::GetCellCount() const
+{
+ sal_uInt32 nCellCount = 0;
+ if( mxTokenArray.is() )
+ {
+ mxTokenArray->Reset();
+ for( const FormulaToken* pToken = mxTokenArray->First(); pToken; pToken = mxTokenArray->Next() )
+ {
+ switch( pToken->GetType() )
+ {
+ case ::formula::svSingleRef:
+ case ::formula::svExternalSingleRef:
+ // single cell
+ ++nCellCount;
+ break;
+ case ::formula::svDoubleRef:
+ case ::formula::svExternalDoubleRef:
+ {
+ // cell range
+ const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
+ const ScSingleRefData& rRef1 = rComplexRef.Ref1;
+ const ScSingleRefData& rRef2 = rComplexRef.Ref2;
+ sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
+ sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
+ sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
+ nCellCount += nCols * nRows * nTabs;
+ }
+ break;
+ default: ;
+ }
+ }
+ }
+ return limit_cast< sal_uInt16 >( nCellCount );
+}
+
+void XclImpChSourceLink::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
+{
+ bool bLinkToSource = ::get_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
+ sal_uInt32 nScNumFmt = bLinkToSource ? GetNumFmtBuffer().GetScFormat( maData.mnNumFmtIdx ) : NUMBERFORMAT_ENTRY_NOT_FOUND;
+ OUString aPropName = bPercent ? EXC_CHPROP_PERCENTAGENUMFMT : EXC_CHPROP_NUMBERFORMAT;
+ if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
+ rPropSet.SetProperty( aPropName, static_cast< sal_Int32 >( nScNumFmt ) );
+ else
+ // restore 'link to source' at data point (series may contain manual number format)
+ rPropSet.SetAnyProperty( aPropName, Any() );
+}
+
+Reference< XDataSequence > XclImpChSourceLink::CreateDataSequence( const OUString& rRole ) const
+{
+ Reference< XDataSequence > xDataSeq;
+ Reference< XDataProvider > xDataProv = GetDataProvider();
+ if( xDataProv.is() && mxTokenArray.is() )
+ {
+ ScCompiler aComp( GetDocPtr(), ScAddress(), *mxTokenArray );
+ aComp.SetGrammar( ::formula::FormulaGrammar::GRAM_ENGLISH );
+ OUStringBuffer aRangeRep;
+ aComp.CreateStringFromTokenArray( aRangeRep );
+ try
+ {
+ xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aRangeRep.makeStringAndClear() );
+ // set sequence role
+ ScfPropertySet aSeqProp( xDataSeq );
+ aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
+ }
+ catch( Exception& )
+ {
+// DBG_ERRORFILE( "XclImpChSourceLink::CreateDataSequence - cannot create data sequence" );
+ }
+ }
+ return xDataSeq;
+}
+
+Sequence< Reference< XFormattedString > > XclImpChSourceLink::CreateStringSequence(
+ const XclImpChRoot& rRoot, sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const
+{
+ ::std::vector< Reference< XFormattedString > > aStringVec;
+ if( mxString.is() )
+ {
+ for( XclImpStringIterator aIt( *mxString ); aIt.Is(); ++aIt )
+ {
+ Reference< XFormattedString > xFmtStr(
+ ScfApiHelper::CreateInstance( SERVICE_CHART2_FORMATTEDSTRING ), UNO_QUERY );
+ if( xFmtStr.is() )
+ {
+ // set text data
+ xFmtStr->setString( aIt.GetPortionText() );
+
+ // set font formatting and font color
+ ScfPropertySet aStringProp( xFmtStr );
+ sal_uInt16 nFontIdx = aIt.GetPortionFont();
+ if( (nFontIdx == EXC_FONT_NOTFOUND) && (aIt.GetPortionIndex() == 0) )
+ // leading unformatted portion - use passed font settings
+ rRoot.ConvertFont( aStringProp, nLeadFontIdx, &rLeadFontColor );
+ else
+ rRoot.ConvertFont( aStringProp, nFontIdx );
+
+ // add string to vector of strings
+ aStringVec.push_back( xFmtStr );
+ }
+ }
+ }
+ return ScfApiHelper::VectorToSequence( aStringVec );
+}
+
+void XclImpChSourceLink::FillSourceLink( ::std::vector< ScSharedTokenRef >& rTokens ) const
+{
+ if( !mxTokenArray.is() )
+ // no links to fill.
+ return;
+
+ mxTokenArray->Reset();
+ for (FormulaToken* p = mxTokenArray->First(); p; p = mxTokenArray->Next())
+ {
+ ScSharedTokenRef pToken(static_cast<ScToken*>(p->Clone()));
+ if (ScRefTokenHelper::isRef(pToken))
+ // This is a reference token. Store it.
+ ScRefTokenHelper::join(rTokens, pToken);
+ }
+}
+
+// Text =======================================================================
+
+XclImpChFontBase::~XclImpChFontBase()
+{
+}
+
+void XclImpChFontBase::ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
+{
+ Color aFontColor = GetFontColor();
+ rRoot.ConvertFont( rPropSet, GetFontIndex(), &aFontColor );
+}
+
+void XclImpChFontBase::ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const
+{
+ rRoot.GetChartPropSetHelper().WriteRotationProperties( rPropSet, GetRotation(), bSupportsStacked );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChFont::XclImpChFont() :
+ mnFontIdx( EXC_FONT_NOTFOUND )
+{
+}
+
+void XclImpChFont::ReadChFont( XclImpStream& rStrm )
+{
+ rStrm >> mnFontIdx;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChText::XclImpChText( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChText::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnHAlign
+ >> maData.mnVAlign
+ >> maData.mnBackMode
+ >> maData.maTextColor
+ >> maData.maRect
+ >> maData.mnFlags;
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ // #116397# BIFF8: index into palette used instead of RGB data
+ maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
+ // placement and rotation
+ rStrm >> maData.mnFlags2 >> maData.mnRotation;
+ }
+ else
+ {
+ // BIFF2-BIFF7: get rotation from text orientation
+ sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 8, 3 );
+ maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
+ }
+}
+
+void XclImpChText::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAMEPOS:
+ mxFramePos.reset( new XclImpChFramePos );
+ mxFramePos->ReadChFramePos( rStrm );
+ break;
+ case EXC_ID_CHFONT:
+ mxFont.reset( new XclImpChFont );
+ mxFont->ReadChFont( rStrm );
+ break;
+ case EXC_ID_CHFORMATRUNS:
+ if( GetBiff() == EXC_BIFF8 )
+ XclImpString::ReadFormats( rStrm, maFormats );
+ break;
+ case EXC_ID_CHSOURCELINK:
+ mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
+ mxSrcLink->ReadChSourceLink( rStrm );
+ break;
+ case EXC_ID_CHFRAME:
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_TEXT ) );
+ mxFrame->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHOBJECTLINK:
+ rStrm >> maObjLink.mnTarget >> maObjLink.maPointPos.mnSeriesIdx >> maObjLink.maPointPos.mnPointIdx;
+ break;
+ case EXC_ID_CHFRLABELPROPS:
+ ReadChFrLabelProps( rStrm );
+ break;
+ case EXC_ID_CHEND:
+ if( mxSrcLink.is() && !maFormats.empty() )
+ mxSrcLink->SetTextFormats( maFormats );
+ break;
+ }
+}
+
+sal_uInt16 XclImpChText::GetFontIndex() const
+{
+ return mxFont.is() ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
+}
+
+Color XclImpChText::GetFontColor() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
+}
+
+sal_uInt16 XclImpChText::GetRotation() const
+{
+ return maData.mnRotation;
+}
+
+void XclImpChText::SetString( const String& rString )
+{
+ if( !mxSrcLink )
+ mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
+ mxSrcLink->SetString( rString );
+}
+
+void XclImpChText::UpdateText( const XclImpChText* pParentText )
+{
+ if( pParentText )
+ {
+ // update missing members
+ if( !mxFrame )
+ mxFrame = pParentText->mxFrame;
+ if( !mxFont )
+ {
+ mxFont = pParentText->mxFont;
+ // text color is taken from CHTEXT record, not from font in CHFONT
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, ::get_flag( pParentText->maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) );
+ maData.maTextColor = pParentText->maData.maTextColor;
+ }
+ }
+}
+
+void XclImpChText::UpdateDataLabel( bool bCateg, bool bValue, bool bPercent )
+{
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bCateg );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bValue );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bPercent );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bCateg && bPercent );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bCateg && !bValue && !bPercent );
+}
+
+void XclImpChText::ConvertFont( ScfPropertySet& rPropSet ) const
+{
+ ConvertFontBase( GetChRoot(), rPropSet );
+}
+
+void XclImpChText::ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const
+{
+ ConvertRotationBase( GetChRoot(), rPropSet, bSupportsStacked );
+}
+
+void XclImpChText::ConvertFrame( ScfPropertySet& rPropSet ) const
+{
+ if( mxFrame.is() )
+ mxFrame->Convert( rPropSet );
+}
+
+void XclImpChText::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
+{
+ if( mxSrcLink.is() )
+ mxSrcLink->ConvertNumFmt( rPropSet, bPercent );
+}
+
+void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const
+{
+ // existing CHFRLABELPROPS record wins over flags from CHTEXT
+ sal_uInt16 nShowFlags = mxLabelProps.is() ? mxLabelProps->mnFlags : maData.mnFlags;
+ sal_uInt16 SHOWANYCATEG = mxLabelProps.is() ? EXC_CHFRLABELPROPS_SHOWCATEG : (EXC_CHTEXT_SHOWCATEGPERC | EXC_CHTEXT_SHOWCATEG);
+ sal_uInt16 SHOWANYVALUE = mxLabelProps.is() ? EXC_CHFRLABELPROPS_SHOWVALUE : EXC_CHTEXT_SHOWVALUE;
+ sal_uInt16 SHOWANYPERCENT = mxLabelProps.is() ? EXC_CHFRLABELPROPS_SHOWPERCENT : (EXC_CHTEXT_SHOWPERCENT | EXC_CHTEXT_SHOWCATEGPERC);
+ sal_uInt16 SHOWANYBUBBLE = mxLabelProps.is() ? EXC_CHFRLABELPROPS_SHOWBUBBLE : EXC_CHTEXT_SHOWBUBBLE;
+
+ // get raw flags for label values
+ bool bShowNone = IsDeleted();
+ bool bShowCateg = !bShowNone && ::get_flag( nShowFlags, SHOWANYCATEG );
+ bool bShowPercent = !bShowNone && ::get_flag( nShowFlags, SHOWANYPERCENT );
+ bool bShowValue = !bShowNone && ::get_flag( nShowFlags, SHOWANYVALUE );
+ bool bShowBubble = !bShowNone && ::get_flag( nShowFlags, SHOWANYBUBBLE );
+
+ // adjust to Chart2 behaviour
+ if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
+ bShowValue = bShowBubble; // Chart2 bubble charts show bubble size if 'ShowValue' is set
+
+ // other flags
+ bool bShowAny = bShowValue || bShowPercent || bShowCateg;
+ bool bShowSymbol = bShowAny && ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL );
+
+ // create API struct for label values, set API label separator
+ cssc2::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
+ rPropSet.SetProperty( EXC_CHPROP_LABEL, aPointLabel );
+ String aSep = mxLabelProps.is() ? mxLabelProps->maSeparator : String( sal_Unicode( '\n' ) );
+ if( aSep.Len() == 0 )
+ aSep = CREATE_STRING( "; " );
+ rPropSet.SetStringProperty( EXC_CHPROP_LABELSEPARATOR, aSep );
+
+ // text properties of attached label
+ if( bShowAny )
+ {
+ ConvertFont( rPropSet );
+ ConvertRotation( rPropSet, false );
+ // label placement
+ using namespace cssc::DataLabelPlacement;
+ sal_Int32 nPlacement = rTypeInfo.mnDefaultLabelPos;
+ switch( ::extract_value< sal_uInt16 >( maData.mnFlags2, 0, 4 ) )
+ {
+ case EXC_CHTEXT_POS_DEFAULT: nPlacement = rTypeInfo.mnDefaultLabelPos; break;
+ case EXC_CHTEXT_POS_OUTSIDE: nPlacement = OUTSIDE; break;
+ case EXC_CHTEXT_POS_INSIDE: nPlacement = INSIDE; break;
+ case EXC_CHTEXT_POS_CENTER: nPlacement = CENTER; break;
+ case EXC_CHTEXT_POS_AXIS: nPlacement = NEAR_ORIGIN; break;
+ case EXC_CHTEXT_POS_ABOVE: nPlacement = TOP; break;
+ case EXC_CHTEXT_POS_BELOW: nPlacement = BOTTOM; break;
+ case EXC_CHTEXT_POS_LEFT: nPlacement = LEFT; break;
+ case EXC_CHTEXT_POS_RIGHT: nPlacement = RIGHT; break;
+ case EXC_CHTEXT_POS_AUTO: nPlacement = AVOID_OVERLAP; break;
+ }
+ rPropSet.SetProperty( EXC_CHPROP_LABELPLACEMENT, nPlacement );
+ // label number format (percentage format wins over value format)
+ if( bShowPercent || bShowValue )
+ ConvertNumFmt( rPropSet, bShowPercent );
+ }
+}
+
+Reference< XTitle > XclImpChText::CreateTitle() const
+{
+ Reference< XTitle > xTitle;
+ if( mxSrcLink.is() && mxSrcLink->HasString() )
+ {
+ // create the formatted strings
+ Sequence< Reference< XFormattedString > > aStringSeq(
+ mxSrcLink->CreateStringSequence( GetChRoot(), GetFontIndex(), GetFontColor() ) );
+ if( aStringSeq.hasElements() )
+ {
+ // create the title object
+ xTitle.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_TITLE ), UNO_QUERY );
+ if( xTitle.is() )
+ {
+ // set the formatted strings
+ xTitle->setText( aStringSeq );
+ // more title formatting properties
+ ScfPropertySet aTitleProp( xTitle );
+ ConvertFrame( aTitleProp );
+ ConvertRotation( aTitleProp, true );
+ }
+ }
+ }
+ return xTitle;
+}
+
+void XclImpChText::ConvertTitlePosition( const XclChTextKey& rTitleKey ) const
+{
+ if( !mxFramePos ) return;
+
+ const XclChFramePos& rPosData = mxFramePos->GetFramePosData();
+ OSL_ENSURE( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rPosData.mnBRMode == EXC_CHFRAMEPOS_PARENT),
+ "XclImpChText::ConvertTitlePosition - unexpected frame position mode" );
+
+ /* Check if title is moved manually. To get the actual position of the
+ title, we do some kind of hack and use the values from the CHTEXT
+ record, effectively ignoring the contents of the CHFRAMEPOS record
+ which contains the position relative to the default title position
+ (according to the spec, the CHFRAMEPOS supersedes the CHTEXT record).
+ Especially when it comes to axis titles, things would become very
+ complicated here, because the relative title position is stored in a
+ measurement unit that is dependent on the size of the inner plot area,
+ the interpretation of the X and Y coordinate is dependent on the
+ direction of the axis, and in 3D charts, and the title default
+ positions are dependent on the 3D view settings (rotation, elevation,
+ and perspective). Thus, it is easier to assume that the creator has
+ written out the correct absolute position and size of the title in the
+ CHTEXT record. This is assured by checking that the shape size stored
+ in the CHTEXT record is non-zero. */
+ if( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) &&
+ ((rPosData.maRect.mnX != 0) || (rPosData.maRect.mnY != 0)) &&
+ (maData.maRect.mnWidth > 0) && (maData.maRect.mnHeight > 0) ) try
+ {
+ Reference< XShape > xTitleShape( GetTitleShape( rTitleKey ), UNO_SET_THROW );
+ // the call to XShape.getSize() may recalc the chart view
+ ::com::sun::star::awt::Size aTitleSize = xTitleShape->getSize();
+ // rotated titles need special handling...
+ sal_Int32 nScRot = XclTools::GetScRotation( GetRotation(), 0 );
+ double fRad = nScRot * F_PI18000;
+ double fSin = fabs( sin( fRad ) );
+ double fCos = fabs( cos( fRad ) );
+ ::com::sun::star::awt::Size aBoundSize(
+ static_cast< sal_Int32 >( fCos * aTitleSize.Width + fSin * aTitleSize.Height + 0.5 ),
+ static_cast< sal_Int32 >( fSin * aTitleSize.Width + fCos * aTitleSize.Height + 0.5 ) );
+ // calculate the title position from the values in the CHTEXT record
+ ::com::sun::star::awt::Point aTitlePos(
+ CalcHmmFromChartX( maData.maRect.mnX ),
+ CalcHmmFromChartY( maData.maRect.mnY ) );
+ // add part of height to X direction, if title is rotated down (clockwise)
+ if( nScRot > 18000 )
+ aTitlePos.X += static_cast< sal_Int32 >( fSin * aTitleSize.Height + 0.5 );
+ // add part of width to Y direction, if title is rotated up (counterclockwise)
+ else if( nScRot > 0 )
+ aTitlePos.Y += static_cast< sal_Int32 >( fSin * aTitleSize.Width + 0.5 );
+ // set the resulting position at the title shape
+ xTitleShape->setPosition( aTitlePos );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void XclImpChText::ReadChFrLabelProps( XclImpStream& rStrm )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ mxLabelProps.reset( new XclChFrLabelProps );
+ sal_uInt16 nSepLen;
+ rStrm.Ignore( 12 );
+ rStrm >> mxLabelProps->mnFlags >> nSepLen;
+ if( nSepLen > 0 )
+ mxLabelProps->maSeparator = rStrm.ReadUniString( nSepLen );
+ }
+}
+
+namespace {
+
+void lclUpdateText( XclImpChTextRef& rxText, XclImpChTextRef xDefText )
+{
+ if( rxText.is() )
+ rxText->UpdateText( xDefText.get() );
+ else
+ rxText = xDefText;
+}
+
+void lclFinalizeTitle( XclImpChTextRef& rxTitle, XclImpChTextRef xDefText, const String& rAutoTitle )
+{
+ /* Do not update a title, if it is not visible (if rxTitle is null).
+ Existing reference indicates enabled title. */
+ if( rxTitle.is() )
+ {
+ if( !rxTitle->HasString() )
+ rxTitle->SetString( rAutoTitle );
+ if( rxTitle->HasString() )
+ rxTitle->UpdateText( xDefText.get() );
+ else
+ rxTitle.reset();
+ }
+}
+
+} // namespace
+
+// Data series ================================================================
+
+void XclImpChMarkerFormat::ReadChMarkerFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.maLineColor >> maData.maFillColor >> maData.mnMarkerType >> maData.mnFlags;
+
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ {
+ // #116397# BIFF8: index into palette used instead of RGB data
+ const XclImpPalette& rPal = rRoot.GetPalette();
+ maData.maLineColor = rPal.GetColor( rStrm.ReaduInt16() );
+ maData.maFillColor = rPal.GetColor( rStrm.ReaduInt16() );
+ // marker size
+ rStrm >> maData.mnMarkerSize;
+ }
+}
+
+void XclImpChMarkerFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const
+{
+ if( IsAuto() )
+ {
+ XclChMarkerFormat aMarkerFmt;
+ // line and fill color of the symbol are equal to series line color
+ //! TODO: Excel sets no fill color for specific symbols (e.g. cross)
+ aMarkerFmt.maLineColor = aMarkerFmt.maFillColor = rRoot.GetSeriesLineAutoColor( nFormatIdx );
+ switch( nLineWeight )
+ {
+ case EXC_CHLINEFORMAT_HAIR: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_HAIRSIZE; break;
+ case EXC_CHLINEFORMAT_SINGLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE; break;
+ case EXC_CHLINEFORMAT_DOUBLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE; break;
+ case EXC_CHLINEFORMAT_TRIPLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_TRIPLESIZE; break;
+ default: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE;
+ }
+ aMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
+ rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, aMarkerFmt );
+ }
+ else
+ {
+ rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, maData );
+ }
+}
+
+void XclImpChMarkerFormat::ConvertColor( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const
+{
+ Color aLineColor = IsAuto() ? rRoot.GetSeriesLineAutoColor( nFormatIdx ) : maData.maFillColor;
+ rPropSet.SetColorProperty( EXC_CHPROP_COLOR, aLineColor );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChPieFormat::XclImpChPieFormat() :
+ mnPieDist( 0 )
+{
+}
+
+void XclImpChPieFormat::ReadChPieFormat( XclImpStream& rStrm )
+{
+ rStrm >> mnPieDist;
+}
+
+void XclImpChPieFormat::Convert( ScfPropertySet& rPropSet ) const
+{
+ double fApiDist = ::std::min< double >( mnPieDist / 100.0, 1.0 );
+ rPropSet.SetProperty( EXC_CHPROP_OFFSET, fApiDist );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSeriesFormat::XclImpChSeriesFormat() :
+ mnFlags( 0 )
+{
+}
+
+void XclImpChSeriesFormat::ReadChSeriesFormat( XclImpStream& rStrm )
+{
+ rStrm >> mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpCh3dDataFormat::ReadCh3dDataFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnBase >> maData.mnTop;
+}
+
+void XclImpCh3dDataFormat::Convert( ScfPropertySet& rPropSet ) const
+{
+ using namespace ::com::sun::star::chart2::DataPointGeometry3D;
+ sal_Int32 nApiType = (maData.mnBase == EXC_CH3DDATAFORMAT_RECT) ?
+ ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CUBOID : PYRAMID) :
+ ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CYLINDER : CONE);
+ rPropSet.SetProperty( EXC_CHPROP_GEOMETRY3D, nApiType );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChAttachedLabel::XclImpChAttachedLabel( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot ),
+ mnFlags( 0 )
+{
+}
+
+void XclImpChAttachedLabel::ReadChAttachedLabel( XclImpStream& rStrm )
+{
+ rStrm >> mnFlags;
+}
+
+XclImpChTextRef XclImpChAttachedLabel::CreateDataLabel( XclImpChTextRef xParent ) const
+{
+ const sal_uInt16 EXC_CHATTLABEL_SHOWANYVALUE = EXC_CHATTLABEL_SHOWVALUE;
+ const sal_uInt16 EXC_CHATTLABEL_SHOWANYPERCENT = EXC_CHATTLABEL_SHOWPERCENT | EXC_CHATTLABEL_SHOWCATEGPERC;
+ const sal_uInt16 EXC_CHATTLABEL_SHOWANYCATEG = EXC_CHATTLABEL_SHOWCATEG | EXC_CHATTLABEL_SHOWCATEGPERC;
+
+ XclImpChTextRef xLabel( xParent.is() ? new XclImpChText( *xParent ) : new XclImpChText( GetChRoot() ) );
+ xLabel->UpdateDataLabel(
+ ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYCATEG ),
+ ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYVALUE ),
+ ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYPERCENT ) );
+ return xLabel;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChDataFormat::XclImpChDataFormat( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChDataFormat::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.maPointPos.mnPointIdx
+ >> maData.maPointPos.mnSeriesIdx
+ >> maData.mnFormatIdx
+ >> maData.mnFlags;
+}
+
+void XclImpChDataFormat::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHMARKERFORMAT:
+ mxMarkerFmt.reset( new XclImpChMarkerFormat );
+ mxMarkerFmt->ReadChMarkerFormat( rStrm );
+ break;
+ case EXC_ID_CHPIEFORMAT:
+ mxPieFmt.reset( new XclImpChPieFormat );
+ mxPieFmt->ReadChPieFormat( rStrm );
+ break;
+ case EXC_ID_CHSERIESFORMAT:
+ mxSeriesFmt.reset( new XclImpChSeriesFormat );
+ mxSeriesFmt->ReadChSeriesFormat( rStrm );
+ break;
+ case EXC_ID_CH3DDATAFORMAT:
+ mx3dDataFmt.reset( new XclImpCh3dDataFormat );
+ mx3dDataFmt->ReadCh3dDataFormat( rStrm );
+ break;
+ case EXC_ID_CHATTACHEDLABEL:
+ mxAttLabel.reset( new XclImpChAttachedLabel( GetChRoot() ) );
+ mxAttLabel->ReadChAttachedLabel( rStrm );
+ break;
+ default:
+ XclImpChFrameBase::ReadSubRecord( rStrm );
+ }
+}
+
+void XclImpChDataFormat::SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx )
+{
+ maData.maPointPos = rPointPos;
+ maData.mnFormatIdx = nFormatIdx;
+}
+
+void XclImpChDataFormat::UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo )
+{
+ // remove formats not used for the current chart type
+ RemoveUnusedFormats( rTypeInfo );
+}
+
+void XclImpChDataFormat::UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt )
+{
+ // update missing formats from passed chart type group format
+ if( pGroupFmt )
+ {
+ if( !mxLineFmt )
+ mxLineFmt = pGroupFmt->mxLineFmt;
+ if( !mxAreaFmt && !mxEscherFmt )
+ {
+ mxAreaFmt = pGroupFmt->mxAreaFmt;
+ mxEscherFmt = pGroupFmt->mxEscherFmt;
+ }
+ if( !mxMarkerFmt )
+ mxMarkerFmt = pGroupFmt->mxMarkerFmt;
+ if( !mxPieFmt )
+ mxPieFmt = pGroupFmt->mxPieFmt;
+ if( !mxSeriesFmt )
+ mxSeriesFmt = pGroupFmt->mxSeriesFmt;
+ if( !mx3dDataFmt )
+ mx3dDataFmt = pGroupFmt->mx3dDataFmt;
+ if( !mxAttLabel )
+ mxAttLabel = pGroupFmt->mxAttLabel;
+ }
+
+ /* Create missing but required formats. Existing line, area, and marker
+ format objects are needed to create automatic series formatting. */
+ if( !mxLineFmt )
+ mxLineFmt.reset( new XclImpChLineFormat );
+ if( !mxAreaFmt && !mxEscherFmt )
+ mxAreaFmt.reset( new XclImpChAreaFormat );
+ if( !mxMarkerFmt )
+ mxMarkerFmt.reset( new XclImpChMarkerFormat );
+
+ // remove formats not used for the current chart type
+ RemoveUnusedFormats( rTypeInfo );
+ // update data label
+ UpdateDataLabel( pGroupFmt );
+}
+
+void XclImpChDataFormat::UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt )
+{
+ // remove formats if they are automatic in this and in the passed series format
+ if( pSeriesFmt )
+ {
+ if( IsAutoLine() && pSeriesFmt->IsAutoLine() )
+ mxLineFmt.reset();
+ if( IsAutoArea() && pSeriesFmt->IsAutoArea() )
+ mxAreaFmt.reset();
+ if( IsAutoMarker() && pSeriesFmt->IsAutoMarker() )
+ mxMarkerFmt.reset();
+ mxSeriesFmt.reset();
+ }
+
+ // Excel ignores 3D bar format for single data points
+ mx3dDataFmt.reset();
+ // remove point line formats for linear chart types, TODO: implement in OOChart
+ if( !rTypeInfo.IsSeriesFrameFormat() )
+ mxLineFmt.reset();
+
+ // remove formats not used for the current chart type
+ RemoveUnusedFormats( rTypeInfo );
+ // update data label
+ UpdateDataLabel( pSeriesFmt );
+}
+
+void XclImpChDataFormat::UpdateTrendLineFormat()
+{
+ if( !mxLineFmt )
+ mxLineFmt.reset( new XclImpChLineFormat );
+ mxAreaFmt.reset();
+ mxEscherFmt.reset();
+ mxMarkerFmt.reset();
+ mxPieFmt.reset();
+ mxSeriesFmt.reset();
+ mx3dDataFmt.reset();
+ mxAttLabel.reset();
+ // update data label
+ UpdateDataLabel( 0 );
+}
+
+void XclImpChDataFormat::Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const
+{
+ // line and area format
+ ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType(), maData.mnFormatIdx );
+#if EXC_CHART2_3DBAR_HAIRLINES_ONLY
+ // #i83151# only hair lines in 3D charts with filled data points
+ if( rTypeInfo.mb3dChart && rTypeInfo.IsSeriesFrameFormat() && mxLineFmt.is() && mxLineFmt->HasLine() )
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BorderWidth" ), 0 );
+#endif
+
+ // other formatting
+ if( mxMarkerFmt.is() )
+ mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx, GetLineWeight() );
+ if( mxPieFmt.is() )
+ mxPieFmt->Convert( rPropSet );
+ if( mx3dDataFmt.is() )
+ mx3dDataFmt->Convert( rPropSet );
+ if( mxLabel.is() )
+ mxLabel->ConvertDataLabel( rPropSet, rTypeInfo );
+
+ // 3D settings
+ rPropSet.SetProperty< sal_Int16 >( EXC_CHPROP_PERCENTDIAGONAL, 0 );
+
+ /* Special case: set marker color as line color, if series line is not
+ visible. This makes the color visible in the marker area.
+ TODO: remove this if OOChart supports own colors in markers. */
+ if( !rTypeInfo.IsSeriesFrameFormat() && !HasLine() && mxMarkerFmt.is() )
+ mxMarkerFmt->ConvertColor( GetChRoot(), rPropSet, maData.mnFormatIdx );
+}
+
+void XclImpChDataFormat::ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const
+{
+ ConvertLineBase( GetChRoot(), rPropSet, eObjType );
+}
+
+void XclImpChDataFormat::ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const
+{
+ ConvertAreaBase( GetChRoot(), rPropSet, EXC_CHOBJTYPE_FILLEDSERIES, nFormatIdx );
+}
+
+void XclImpChDataFormat::RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo )
+{
+ // data point marker only in linear 2D charts
+ if( rTypeInfo.IsSeriesFrameFormat() )
+ mxMarkerFmt.reset();
+ // pie format only in pie/donut charts
+ if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
+ mxPieFmt.reset();
+ // 3D format only in 3D bar charts
+ if( !rTypeInfo.mb3dChart || (rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
+ mx3dDataFmt.reset();
+}
+
+void XclImpChDataFormat::UpdateDataLabel( const XclImpChDataFormat* pParentFmt )
+{
+ /* CHTEXT groups linked to data labels override existing CHATTACHEDLABEL
+ records. Only if there is a CHATTACHEDLABEL record without a CHTEXT
+ group, the contents of the CHATTACHEDLABEL record are used. In this
+ case a new CHTEXT group is created and filled with the settings from
+ the CHATTACHEDLABEL record. */
+ XclImpChTextRef xDefText;
+ if( pParentFmt )
+ xDefText = pParentFmt->GetDataLabel();
+ if( !xDefText )
+ xDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_DATALABEL );
+ if( mxLabel.is() )
+ mxLabel->UpdateText( xDefText.get() );
+ else if( mxAttLabel.is() )
+ mxLabel = mxAttLabel->CreateDataLabel( xDefText );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSerTrendLine::XclImpChSerTrendLine( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChSerTrendLine::ReadChSerTrendLine( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnLineType
+ >> maData.mnOrder
+ >> maData.mfIntercept
+ >> maData.mnShowEquation
+ >> maData.mnShowRSquared
+ >> maData.mfForecastFor
+ >> maData.mfForecastBack;
+}
+
+Reference< XRegressionCurve > XclImpChSerTrendLine::CreateRegressionCurve() const
+{
+ // trend line type
+ OUString aService;
+ switch( maData.mnLineType )
+ {
+ case EXC_CHSERTREND_POLYNOMIAL:
+ // TODO: only linear trend lines are supported by OOChart (#i20819#)
+ if( maData.mnOrder == 1 )
+ aService = SERVICE_CHART2_LINEARREGCURVE;
+ break;
+ case EXC_CHSERTREND_EXPONENTIAL:
+ aService = SERVICE_CHART2_EXPREGCURVE;
+ break;
+ case EXC_CHSERTREND_LOGARITHMIC:
+ aService = SERVICE_CHART2_LOGREGCURVE;
+ break;
+ case EXC_CHSERTREND_POWER:
+ aService = SERVICE_CHART2_POTREGCURVE;
+ break;
+ }
+ Reference< XRegressionCurve > xRegCurve;
+ if( aService.getLength() > 0 )
+ xRegCurve.set( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
+
+ // trend line formatting
+ if( xRegCurve.is() && mxDataFmt.is() )
+ {
+ ScfPropertySet aPropSet( xRegCurve );
+ mxDataFmt->ConvertLine( aPropSet, EXC_CHOBJTYPE_TRENDLINE );
+
+ // #i83100# show equation and correlation coefficient
+ ScfPropertySet aLabelProp( xRegCurve->getEquationProperties() );
+ aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWEQUATION, maData.mnShowEquation != 0 );
+ aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWCORRELATION, maData.mnShowRSquared != 0 );
+
+ // #i83100# formatting of the equation text box
+ if( const XclImpChText* pLabel = mxDataFmt->GetDataLabel().get() )
+ {
+ pLabel->ConvertFont( aLabelProp );
+ pLabel->ConvertFrame( aLabelProp );
+ pLabel->ConvertNumFmt( aLabelProp, false );
+ }
+ }
+
+ // missing features
+ // #i20819# polynomial trend lines
+ // #i66819# moving average trend lines
+ // #i5085# manual trend line size
+ // #i34093# manual crossing point
+
+ return xRegCurve;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSerErrorBar::XclImpChSerErrorBar( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChSerErrorBar::ReadChSerErrorBar( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnBarType >> maData.mnSourceType >> maData.mnLineEnd;
+ rStrm.Ignore( 1 );
+ rStrm >> maData.mfValue >> maData.mnValueCount;
+}
+
+void XclImpChSerErrorBar::SetSeriesData( XclImpChSourceLinkRef xValueLink, XclImpChDataFormatRef xDataFmt )
+{
+ mxValueLink = xValueLink;
+ mxDataFmt = xDataFmt;
+}
+
+Reference< XLabeledDataSequence > XclImpChSerErrorBar::CreateValueSequence() const
+{
+ return lclCreateLabeledDataSequence( mxValueLink, XclChartHelper::GetErrorBarValuesRole( maData.mnBarType ) );
+}
+
+Reference< XPropertySet > XclImpChSerErrorBar::CreateErrorBar( const XclImpChSerErrorBar* pPosBar, const XclImpChSerErrorBar* pNegBar )
+{
+ Reference< XPropertySet > xErrorBar;
+
+ if( const XclImpChSerErrorBar* pPrimaryBar = pPosBar ? pPosBar : pNegBar )
+ {
+ xErrorBar.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_ERRORBAR ), UNO_QUERY );
+ ScfPropertySet aBarProp( xErrorBar );
+
+ // plus/minus bars visible?
+ aBarProp.SetBoolProperty( EXC_CHPROP_SHOWPOSITIVEERROR, pPosBar != 0 );
+ aBarProp.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR, pNegBar != 0 );
+
+ // type of displayed error
+ switch( pPrimaryBar->maData.mnSourceType )
+ {
+ case EXC_CHSERERR_PERCENT:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::RELATIVE );
+ aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
+ aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
+ break;
+ case EXC_CHSERERR_FIXED:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::ABSOLUTE );
+ aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
+ aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
+ break;
+ case EXC_CHSERERR_STDDEV:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_DEVIATION );
+ aBarProp.SetProperty( EXC_CHPROP_WEIGHT, pPrimaryBar->maData.mfValue );
+ break;
+ case EXC_CHSERERR_STDERR:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_ERROR );
+ break;
+ case EXC_CHSERERR_CUSTOM:
+ {
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::FROM_DATA );
+ // attach data sequences to erorr bar
+ Reference< XDataSink > xDataSink( xErrorBar, UNO_QUERY );
+ if( xDataSink.is() )
+ {
+ // create vector of all value sequences
+ ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
+ // add positive values
+ if( pPosBar )
+ {
+ Reference< XLabeledDataSequence > xValueSeq = pPosBar->CreateValueSequence();
+ if( xValueSeq.is() )
+ aLabeledSeqVec.push_back( xValueSeq );
+ }
+ // add negative values
+ if( pNegBar )
+ {
+ Reference< XLabeledDataSequence > xValueSeq = pNegBar->CreateValueSequence();
+ if( xValueSeq.is() )
+ aLabeledSeqVec.push_back( xValueSeq );
+ }
+ // attach labeled data sequences to series
+ if( aLabeledSeqVec.empty() )
+ xErrorBar.clear();
+ else
+ xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
+ }
+ }
+ break;
+ default:
+ xErrorBar.clear();
+ }
+
+ // error bar formatting
+ if( pPrimaryBar->mxDataFmt.is() && xErrorBar.is() )
+ pPrimaryBar->mxDataFmt->ConvertLine( aBarProp, EXC_CHOBJTYPE_ERRORBAR );
+ }
+
+ return xErrorBar;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSeries::XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
+ XclImpChRoot( rRoot ),
+ mnGroupIdx( EXC_CHSERGROUP_NONE ),
+ mnSeriesIdx( nSeriesIdx ),
+ mnParentIdx( EXC_CHSERIES_INVALID )
+{
+}
+
+void XclImpChSeries::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnCategType >> maData.mnValueType >> maData.mnCategCount >> maData.mnValueCount;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm >> maData.mnBubbleType >> maData.mnBubbleCount;
+}
+
+void XclImpChSeries::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHSOURCELINK:
+ ReadChSourceLink( rStrm );
+ break;
+ case EXC_ID_CHDATAFORMAT:
+ ReadChDataFormat( rStrm );
+ break;
+ case EXC_ID_CHSERGROUP:
+ rStrm >> mnGroupIdx;
+ break;
+ case EXC_ID_CHSERPARENT:
+ ReadChSerParent( rStrm );
+ break;
+ case EXC_ID_CHSERTRENDLINE:
+ ReadChSerTrendLine( rStrm );
+ break;
+ case EXC_ID_CHSERERRORBAR:
+ ReadChSerErrorBar( rStrm );
+ break;
+ }
+}
+
+void XclImpChSeries::SetDataFormat( XclImpChDataFormatRef xDataFmt )
+{
+ if( xDataFmt.is() )
+ {
+ XclImpChDataFormatRef* pxDataFmt = GetDataFormatRef( xDataFmt->GetPointPos().mnPointIdx );
+ // do not overwrite existing data format
+ if( pxDataFmt && !*pxDataFmt )
+ {
+ *pxDataFmt = xDataFmt;
+ // #i51639# register series format index at chart type group
+ if( (pxDataFmt == &mxSeriesFmt) && !HasParentSeries() )
+ if( XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
+ pTypeGroup->SetUsedFormatIndex( xDataFmt->GetFormatIdx() );
+ }
+ }
+}
+
+void XclImpChSeries::SetDataLabel( XclImpChTextRef xLabel )
+{
+ if( xLabel.is() )
+ {
+ XclImpChTextRef* pxLabel = GetDataLabelRef( xLabel->GetPointPos().mnPointIdx );
+ if( pxLabel && !*pxLabel )
+ *pxLabel = xLabel;
+ }
+}
+
+void XclImpChSeries::AddChildSeries( const XclImpChSeries& rSeries )
+{
+ DBG_ASSERT( !HasParentSeries(), "XclImpChSeries::AddChildSeries - not allowed for child series" );
+
+ /* In Excel, trend lines and error bars are stored as own series. In Calc,
+ these are properties of the parent series. This function adds the
+ settings of the passed series to this series. */
+ maTrendLines.insert( maTrendLines.end(), rSeries.maTrendLines.begin(), rSeries.maTrendLines.end() );
+ maErrorBars.insert( rSeries.maErrorBars.begin(), rSeries.maErrorBars.end() );
+}
+
+void XclImpChSeries::FinalizeDataFormats()
+{
+ if( HasParentSeries() )
+ {
+ // *** series is a child series, e.g. trend line or error bar ***
+
+ // create missing series format
+ if( !mxSeriesFmt )
+ mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, 0 );
+
+ if( mxSeriesFmt.is() )
+ {
+ // #i83100# set text label format, e.g. for trend line equations
+ mxSeriesFmt->SetDataLabel( maLabels.get( EXC_CHDATAFORMAT_ALLPOINTS ) );
+ // create missing automatic formats
+ mxSeriesFmt->UpdateTrendLineFormat();
+ }
+
+ // copy series formatting to child objects
+ for( XclImpChSerTrendLineList::iterator aLIt = maTrendLines.begin(), aLEnd = maTrendLines.end(); aLIt != aLEnd; ++aLIt )
+ (*aLIt)->SetDataFormat( mxSeriesFmt );
+ for( XclImpChSerErrorBarMap::iterator aMIt = maErrorBars.begin(), aMEnd = maErrorBars.end(); aMIt != aMEnd; ++aMIt )
+ aMIt->second->SetSeriesData( mxValueLink, mxSeriesFmt );
+ }
+ else if( XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
+ {
+ // *** series is a regular data series ***
+
+ // create missing series format
+ if( !mxSeriesFmt )
+ {
+ // #i51639# use a new unused format index to create series default format
+ sal_uInt16 nFormatIdx = pTypeGroup->PopUnusedFormatIndex();
+ mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, nFormatIdx );
+ }
+
+ // set text labels to data formats
+ for( XclImpChTextMap::iterator aTIt = maLabels.begin(), aTEnd = maLabels.end(); aTIt != aTEnd; ++aTIt )
+ {
+ if( XclImpChDataFormatRef* pxDataFmt = GetDataFormatRef( aTIt->first ) )
+ {
+ if( !*pxDataFmt )
+ *pxDataFmt = CreateDataFormat( aTIt->first, EXC_CHDATAFORMAT_DEFAULT );
+ (*pxDataFmt)->SetDataLabel( aTIt->second );
+ }
+ }
+
+ // update series format (copy missing formatting from group default format)
+ if( mxSeriesFmt.is() )
+ mxSeriesFmt->UpdateSeriesFormat( pTypeGroup->GetTypeInfo(), pTypeGroup->GetGroupFormat().get() );
+
+ // update data point formats (removes unchanged automatic formatting)
+ for( XclImpChDataFormatMap::iterator aFIt = maPointFmts.begin(), aFEnd = maPointFmts.end(); aFIt != aFEnd; ++aFIt )
+ aFIt->second->UpdatePointFormat( pTypeGroup->GetTypeInfo(), mxSeriesFmt.get() );
+ }
+}
+
+namespace {
+
+/** Returns the property set of the specified data point. */
+ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_uInt16 nPointIdx )
+{
+ ScfPropertySet aPropSet;
+ try
+ {
+ aPropSet.Set( xDataSeries->getDataPointByIndex( static_cast< sal_Int32 >( nPointIdx ) ) );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "lclGetPointPropSet - no data point property set" );
+ }
+ return aPropSet;
+}
+
+} // namespace
+
+Reference< XLabeledDataSequence > XclImpChSeries::CreateValueSequence( const OUString& rValueRole ) const
+{
+ return lclCreateLabeledDataSequence( mxValueLink, rValueRole, mxTitleLink.get() );
+}
+
+Reference< XLabeledDataSequence > XclImpChSeries::CreateCategSequence( const OUString& rCategRole ) const
+{
+ return lclCreateLabeledDataSequence( mxCategLink, rCategRole );
+}
+
+Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const
+{
+ Reference< XDataSeries > xDataSeries;
+ if( const XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
+ {
+ const XclChExtTypeInfo& rTypeInfo = pTypeGroup->GetTypeInfo();
+
+ // create the data series object
+ xDataSeries.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
+
+ // attach data and title sequences to series
+ Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
+ if( xDataSink.is() )
+ {
+ // create vector of all value sequences
+ ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
+ // add Y values
+ Reference< XLabeledDataSequence > xYValueSeq =
+ CreateValueSequence( EXC_CHPROP_ROLE_YVALUES );
+ if( xYValueSeq.is() )
+ aLabeledSeqVec.push_back( xYValueSeq );
+ // add X values
+ if( !rTypeInfo.mbCategoryAxis )
+ {
+ Reference< XLabeledDataSequence > xXValueSeq =
+ CreateCategSequence( EXC_CHPROP_ROLE_XVALUES );
+ if( xXValueSeq.is() )
+ aLabeledSeqVec.push_back( xXValueSeq );
+ // add size values of bubble charts
+ if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
+ {
+ Reference< XLabeledDataSequence > xSizeValueSeq =
+ lclCreateLabeledDataSequence( mxBubbleLink, EXC_CHPROP_ROLE_SIZEVALUES, mxTitleLink.get() );
+ if( xSizeValueSeq.is() )
+ aLabeledSeqVec.push_back( xSizeValueSeq );
+ }
+ }
+ // attach labeled data sequences to series
+ if( !aLabeledSeqVec.empty() )
+ xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
+ }
+
+ // series formatting
+ ScfPropertySet aSeriesProp( xDataSeries );
+ if( mxSeriesFmt.is() )
+ mxSeriesFmt->Convert( aSeriesProp, rTypeInfo );
+
+ // trend lines
+ ConvertTrendLines( xDataSeries );
+
+ // error bars
+ Reference< XPropertySet > xErrorBarX = CreateErrorBar( EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
+ if( xErrorBarX.is() )
+ aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARX, xErrorBarX );
+ Reference< XPropertySet > xErrorBarY = CreateErrorBar( EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
+ if( xErrorBarY.is() )
+ aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARY, xErrorBarY );
+
+ // own area formatting for every data point (TODO: varying line color not supported)
+ bool bVarPointFmt = pTypeGroup->HasVarPointFormat() && rTypeInfo.IsSeriesFrameFormat();
+#if EXC_CHART2_VARYCOLORSBY_PROP
+ aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, bVarPointFmt );
+#else
+ aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
+#endif
+ // #i91271# always set area formatting for every point in pie/doughnut charts
+ if( mxSeriesFmt.is() && ((bVarPointFmt && mxSeriesFmt->IsAutoArea()) || (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE)) )
+ {
+ for( sal_uInt16 nPointIdx = 0, nPointCount = mxValueLink->GetCellCount(); nPointIdx < nPointCount; ++nPointIdx )
+ {
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
+ mxSeriesFmt->ConvertArea( aPointProp, bVarPointFmt ? nPointIdx : mnSeriesIdx );
+ }
+ }
+
+ // data point formatting
+ for( XclImpChDataFormatMap::const_iterator aIt = maPointFmts.begin(), aEnd = maPointFmts.end(); aIt != aEnd; ++aIt )
+ {
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, aIt->first );
+ aIt->second->Convert( aPointProp, rTypeInfo );
+ }
+ }
+ return xDataSeries;
+}
+
+void XclImpChSeries::FillAllSourceLinks( ::std::vector< ScSharedTokenRef >& rTokens ) const
+{
+ if( mxValueLink.is() )
+ mxValueLink->FillSourceLink( rTokens );
+ if( mxCategLink.is() )
+ mxCategLink->FillSourceLink( rTokens );
+ if( mxTitleLink.is() )
+ mxTitleLink->FillSourceLink( rTokens );
+ if( mxBubbleLink.is() )
+ mxBubbleLink->FillSourceLink( rTokens );
+}
+
+void XclImpChSeries::ReadChSourceLink( XclImpStream& rStrm )
+{
+ XclImpChSourceLinkRef xSrcLink( new XclImpChSourceLink( GetChRoot() ) );
+ xSrcLink->ReadChSourceLink( rStrm );
+ switch( xSrcLink->GetDestType() )
+ {
+ case EXC_CHSRCLINK_TITLE: mxTitleLink = xSrcLink; break;
+ case EXC_CHSRCLINK_VALUES: mxValueLink = xSrcLink; break;
+ case EXC_CHSRCLINK_CATEGORY: mxCategLink = xSrcLink; break;
+ case EXC_CHSRCLINK_BUBBLES: mxBubbleLink = xSrcLink; break;
+ }
+}
+
+void XclImpChSeries::ReadChDataFormat( XclImpStream& rStrm )
+{
+ // #i51639# chart stores all data formats and assigns them later to the series
+ GetChartData().ReadChDataFormat( rStrm );
+}
+
+void XclImpChSeries::ReadChSerParent( XclImpStream& rStrm )
+{
+ rStrm >> mnParentIdx;
+ // index to parent series is 1-based, convert it to 0-based
+ if( mnParentIdx > 0 )
+ --mnParentIdx;
+ else
+ mnParentIdx = EXC_CHSERIES_INVALID;
+}
+
+void XclImpChSeries::ReadChSerTrendLine( XclImpStream& rStrm )
+{
+ XclImpChSerTrendLineRef xTrendLine( new XclImpChSerTrendLine( GetChRoot() ) );
+ xTrendLine->ReadChSerTrendLine( rStrm );
+ maTrendLines.push_back( xTrendLine );
+}
+
+void XclImpChSeries::ReadChSerErrorBar( XclImpStream& rStrm )
+{
+ XclImpChSerErrorBarRef xErrorBar( new XclImpChSerErrorBar( GetChRoot() ) );
+ xErrorBar->ReadChSerErrorBar( rStrm );
+ maErrorBars[ xErrorBar->GetBarType() ] = xErrorBar;
+}
+
+XclImpChDataFormatRef XclImpChSeries::CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx )
+{
+ XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
+ xDataFmt->SetPointPos( XclChDataPointPos( mnSeriesIdx, nPointIdx ), nFormatIdx );
+ return xDataFmt;
+}
+
+XclImpChDataFormatRef* XclImpChSeries::GetDataFormatRef( sal_uInt16 nPointIdx )
+{
+ if( nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS )
+ return &mxSeriesFmt;
+ if( nPointIdx < EXC_CHDATAFORMAT_MAXPOINTCOUNT )
+ return &maPointFmts[ nPointIdx ];
+ return 0;
+}
+
+XclImpChTextRef* XclImpChSeries::GetDataLabelRef( sal_uInt16 nPointIdx )
+{
+ if( (nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS) || (nPointIdx < EXC_CHDATAFORMAT_MAXPOINTCOUNT) )
+ return &maLabels[ nPointIdx ];
+ return 0;
+}
+
+void XclImpChSeries::ConvertTrendLines( Reference< XDataSeries > xDataSeries ) const
+{
+ Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
+ if( xRegCurveCont.is() )
+ {
+ for( XclImpChSerTrendLineList::const_iterator aIt = maTrendLines.begin(), aEnd = maTrendLines.end(); aIt != aEnd; ++aIt )
+ {
+ try
+ {
+ Reference< XRegressionCurve > xRegCurve = (*aIt)->CreateRegressionCurve();
+ if( xRegCurve.is() )
+ xRegCurveCont->addRegressionCurve( xRegCurve );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChSeries::ConvertTrendLines - cannot add regression curve" );
+ }
+ }
+ }
+}
+
+Reference< XPropertySet > XclImpChSeries::CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const
+{
+ return XclImpChSerErrorBar::CreateErrorBar( maErrorBars.get( nPosBarId ).get(), maErrorBars.get( nNegBarId ).get() );
+}
+
+// Chart type groups ==========================================================
+
+XclImpChType::XclImpChType( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot ),
+ mnRecId( EXC_ID_CHUNKNOWN ),
+ maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
+{
+}
+
+void XclImpChType::ReadChType( XclImpStream& rStrm )
+{
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bool bKnownType = true;
+
+ switch( nRecId )
+ {
+ case EXC_ID_CHBAR:
+ rStrm >> maData.mnOverlap >> maData.mnGap >> maData.mnFlags;
+ break;
+
+ case EXC_ID_CHLINE:
+ case EXC_ID_CHAREA:
+ case EXC_ID_CHRADARLINE:
+ case EXC_ID_CHRADARAREA:
+ rStrm >> maData.mnFlags;
+ break;
+
+ case EXC_ID_CHPIE:
+ rStrm >> maData.mnRotation >> maData.mnPieHole;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm >> maData.mnFlags;
+ else
+ maData.mnFlags = 0;
+ break;
+
+ case EXC_ID_CHPIEEXT:
+ maData.mnRotation = 0;
+ maData.mnPieHole = 0;
+ maData.mnFlags = 0;
+ break;
+
+ case EXC_ID_CHSCATTER:
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm >> maData.mnBubbleSize >> maData.mnBubbleType >> maData.mnFlags;
+ else
+ maData.mnFlags = 0;
+ break;
+
+ case EXC_ID_CHSURFACE:
+ rStrm >> maData.mnFlags;
+ break;
+
+ default:
+ bKnownType = false;
+ }
+
+ if( bKnownType )
+ mnRecId = nRecId;
+}
+
+void XclImpChType::Finalize( bool bStockChart )
+{
+ switch( mnRecId )
+ {
+ case EXC_ID_CHLINE:
+ maTypeInfo = GetChartTypeInfo( bStockChart ?
+ EXC_CHTYPEID_STOCK : EXC_CHTYPEID_LINE );
+ break;
+ case EXC_ID_CHBAR:
+ maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
+ maData.mnFlags, EXC_CHBAR_HORIZONTAL,
+ EXC_CHTYPEID_HORBAR, EXC_CHTYPEID_BAR ) );
+ break;
+ case EXC_ID_CHPIE:
+ maTypeInfo = GetChartTypeInfo( (maData.mnPieHole > 0) ?
+ EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
+ break;
+ case EXC_ID_CHSCATTER:
+ maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
+ maData.mnFlags, EXC_CHSCATTER_BUBBLES,
+ EXC_CHTYPEID_BUBBLES, EXC_CHTYPEID_SCATTER ) );
+ break;
+ default:
+ maTypeInfo = GetChartTypeInfo( mnRecId );
+ }
+
+ switch( maTypeInfo.meTypeId )
+ {
+ case EXC_CHTYPEID_PIEEXT:
+ case EXC_CHTYPEID_BUBBLES:
+ case EXC_CHTYPEID_SURFACE:
+ case EXC_CHTYPEID_UNKNOWN:
+ GetTracer().TraceChartUnKnownType();
+ break;
+ default:;
+ }
+}
+
+bool XclImpChType::IsStacked() const
+{
+ bool bStacked = false;
+ if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_LINE:
+ bStacked =
+ ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
+ !::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
+ break;
+ case EXC_CHTYPECATEG_BAR:
+ bStacked =
+ ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
+ !::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
+ break;
+ default:;
+ }
+ return bStacked;
+}
+
+bool XclImpChType::IsPercent() const
+{
+ bool bPercent = false;
+ if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_LINE:
+ bPercent =
+ ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
+ ::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
+ break;
+ case EXC_CHTYPECATEG_BAR:
+ bPercent =
+ ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
+ ::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
+ break;
+ default:;
+ }
+ return bPercent;
+}
+
+bool XclImpChType::HasCategoryLabels() const
+{
+ // radar charts disable category labels in chart type, not in CHTICK of X axis
+ return (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) || ::get_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS );
+}
+
+Reference< XCoordinateSystem > XclImpChType::CreateCoordSystem( bool b3dChart ) const
+{
+ // service name
+ OUString aCoordSysService;
+ if( maTypeInfo.mbPolarCoordSystem )
+ {
+ if( b3dChart )
+ aCoordSysService = SERVICE_CHART2_POLARCOORDSYS3D;
+ else
+ aCoordSysService = SERVICE_CHART2_POLARCOORDSYS2D;
+ }
+ else
+ {
+ if( b3dChart )
+ aCoordSysService = SERVICE_CHART2_CARTESIANCOORDSYS3D;
+ else
+ aCoordSysService = SERVICE_CHART2_CARTESIANCOORDSYS2D;
+ }
+
+ // create the coordinate system object
+ Reference< XCoordinateSystem > xCoordSystem( ScfApiHelper::CreateInstance( aCoordSysService ), UNO_QUERY );
+
+ // swap X and Y axis
+ if( maTypeInfo.mbSwappedAxesSet )
+ {
+ ScfPropertySet aCoordSysProp( xCoordSystem );
+ aCoordSysProp.SetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS, true );
+ }
+
+ return xCoordSystem;
+}
+
+Reference< XChartType > XclImpChType::CreateChartType( Reference< XDiagram > xDiagram, bool b3dChart ) const
+{
+ OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
+ Reference< XChartType > xChartType( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
+
+ // additional properties
+ switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_BAR:
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ Sequence< sal_Int32 > aInt32Seq( 2 );
+ aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = -maData.mnOverlap;
+ aTypeProp.SetProperty( EXC_CHPROP_OVERLAPSEQ, aInt32Seq );
+ aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = maData.mnGap;
+ aTypeProp.SetProperty( EXC_CHPROP_GAPWIDTHSEQ, aInt32Seq );
+ }
+ break;
+ case EXC_CHTYPECATEG_PIE:
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_USERINGS, maTypeInfo.meTypeId == EXC_CHTYPEID_DONUT );
+ /* #i85166# starting angle of first pie slice. 3D pie charts use Y
+ rotation setting in view3D element. Of-pie charts do not
+ support pie rotation. */
+ if( !b3dChart && (maTypeInfo.meTypeId != EXC_CHTYPEID_PIEEXT) )
+ {
+ ScfPropertySet aDiaProp( xDiagram );
+ XclImpChRoot::ConvertPieRotation( aDiaProp, maData.mnRotation );
+ }
+ }
+ break;
+ default:;
+ }
+
+ return xChartType;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpChChart3d::ReadChChart3d( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnRotation
+ >> maData.mnElevation
+ >> maData.mnEyeDist
+ >> maData.mnRelHeight
+ >> maData.mnRelDepth
+ >> maData.mnDepthGap
+ >> maData.mnFlags;
+}
+
+void XclImpChChart3d::Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+// #i104057# do not assert this, written by broken external generators
+// DBG_ASSERT( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" );
+
+ sal_Int32 nRotationY = 0;
+ sal_Int32 nRotationX = 0;
+ sal_Int32 nPerspective = 15;
+ bool bRightAngled = false;
+ cssd::ProjectionMode eProjMode = cssd::ProjectionMode_PERSPECTIVE;
+ Color aAmbientColor, aLightColor;
+
+ if( b3dWallChart )
+ {
+ // Y rotation (Excel [0..359], Chart2 [-179,180])
+ nRotationY = maData.mnRotation % 360;
+ if( nRotationY > 180 ) nRotationY -= 360;
+ // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
+ nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, -90, 90 );
+ // perspective (Excel and Chart2 [0,100])
+ nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
+ // right-angled axes
+ bRightAngled = !::get_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D );
+ // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%)
+ bool bParallel = bRightAngled || (nPerspective == 0);
+ eProjMode = bParallel ? cssd::ProjectionMode_PARALLEL : cssd::ProjectionMode_PERSPECTIVE;
+ // ambient color (Gray 20%)
+ aAmbientColor.SetColor( RGB_COLORDATA( 204, 204, 204 ) );
+ // light color (Gray 60%)
+ aLightColor.SetColor( RGB_COLORDATA( 102, 102, 102 ) );
+ }
+ else
+ {
+ // Y rotation not used in pie charts, but 'first pie slice angle'
+ nRotationY = 0;
+ XclImpChRoot::ConvertPieRotation( rPropSet, maData.mnRotation );
+ // X rotation a.k.a. elevation (map Excel [10..80] to Chart2 [-80,-10])
+ nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, 10, 80 ) - 90;
+ // perspective (Excel and Chart2 [0,100])
+ nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
+ // no right-angled axes in pie charts, but parallel projection
+ bRightAngled = false;
+ eProjMode = cssd::ProjectionMode_PARALLEL;
+ // ambient color (Gray 30%)
+ aAmbientColor.SetColor( RGB_COLORDATA( 179, 179, 179 ) );
+ // light color (Gray 70%)
+ aLightColor.SetColor( RGB_COLORDATA( 76, 76, 76 ) );
+ }
+
+ // properties
+ rPropSet.SetProperty( EXC_CHPROP_ROTATIONVERTICAL, nRotationY );
+ rPropSet.SetProperty( EXC_CHPROP_ROTATIONHORIZONTAL, nRotationX );
+ rPropSet.SetProperty( EXC_CHPROP_PERSPECTIVE, nPerspective );
+ rPropSet.SetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES, bRightAngled );
+ rPropSet.SetProperty( EXC_CHPROP_D3DSCENEPERSPECTIVE, eProjMode );
+
+ // light settings
+ rPropSet.SetProperty( EXC_CHPROP_D3DSCENESHADEMODE, cssd::ShadeMode_FLAT );
+ rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENEAMBIENTCOLOR, aAmbientColor );
+ rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON1, false );
+ rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON2, true );
+ rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENELIGHTCOLOR2, aLightColor );
+ rPropSet.SetProperty( EXC_CHPROP_D3DSCENELIGHTDIR2, cssd::Direction3D( 0.2, 0.4, 1.0 ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChLegend::XclImpChLegend( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChLegend::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.maRect >> maData.mnDockMode >> maData.mnSpacing >> maData.mnFlags;
+
+ // trace unsupported features
+ if( GetTracer().IsEnabled() )
+ {
+ if( maData.mnDockMode == EXC_CHLEGEND_NOTDOCKED )
+ GetTracer().TraceChartLegendPosition();
+ if( ::get_flag( maData.mnFlags, EXC_CHLEGEND_DATATABLE ) )
+ GetTracer().TraceChartDataTable();
+ }
+}
+
+void XclImpChLegend::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAMEPOS:
+ mxFramePos.reset( new XclImpChFramePos );
+ mxFramePos->ReadChFramePos( rStrm );
+ break;
+ case EXC_ID_CHTEXT:
+ mxText.reset( new XclImpChText( GetChRoot() ) );
+ mxText->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHFRAME:
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
+ mxFrame->ReadRecordGroup( rStrm );
+ break;
+ }
+}
+
+void XclImpChLegend::Finalize()
+{
+ // legend default formatting differs in OOChart and Excel, missing frame means automatic
+ if( !mxFrame )
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
+ // Update text formatting. If mxText is empty, the passed default text is used.
+ lclUpdateText( mxText, GetChartData().GetDefaultText( EXC_CHTEXTTYPE_LEGEND ) );
+}
+
+Reference< XLegend > XclImpChLegend::CreateLegend() const
+{
+ Reference< XLegend > xLegend( ScfApiHelper::CreateInstance( SERVICE_CHART2_LEGEND ), UNO_QUERY );
+ if( xLegend.is() )
+ {
+ ScfPropertySet aLegendProp( xLegend );
+ aLegendProp.SetBoolProperty( EXC_CHPROP_SHOW, true );
+
+ // frame properties
+ if( mxFrame.is() )
+ mxFrame->Convert( aLegendProp );
+ // text properties
+ if( mxText.is() )
+ mxText->ConvertFont( aLegendProp );
+
+ /* Legend position and size. Default positions are used only if the
+ plot area is positioned automatically (Excel sets the plot area to
+ manual mode, if the legend is moved or resized). With manual plot
+ areas, Excel ignores the value in maData.mnDockMode completely. */
+ cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
+ cssc2::LegendExpansion eApiExpand = cssc2::LegendExpansion_BALANCED;
+ if( !GetChartData().IsManualPlotArea() ) switch( maData.mnDockMode )
+ {
+ case EXC_CHLEGEND_LEFT: eApiPos = cssc2::LegendPosition_LINE_START; eApiExpand = cssc2::LegendExpansion_HIGH; break;
+ case EXC_CHLEGEND_RIGHT: eApiPos = cssc2::LegendPosition_LINE_END; eApiExpand = cssc2::LegendExpansion_HIGH; break;
+ case EXC_CHLEGEND_TOP: eApiPos = cssc2::LegendPosition_PAGE_START; eApiExpand = cssc2::LegendExpansion_WIDE; break;
+ case EXC_CHLEGEND_BOTTOM: eApiPos = cssc2::LegendPosition_PAGE_END; eApiExpand = cssc2::LegendExpansion_WIDE; break;
+ // top-right not supported
+ case EXC_CHLEGEND_CORNER: eApiPos = cssc2::LegendPosition_LINE_END; eApiExpand = cssc2::LegendExpansion_HIGH; break;
+ }
+
+ // no automatic position: try to find the correct position and size
+ if( eApiPos == cssc2::LegendPosition_CUSTOM )
+ {
+ const XclChFramePos* pFramePos = mxFramePos.is() ? &mxFramePos->GetFramePosData() : 0;
+
+ /* Legend position. Only the settings from the CHFRAMEPOS record
+ are used by Excel, the position in the CHLEGEND record will be
+ ignored. */
+ if( pFramePos )
+ {
+ RelativePosition aRelPos;
+ aRelPos.Primary = CalcRelativeFromChartX( pFramePos->maRect.mnX );
+ aRelPos.Secondary = CalcRelativeFromChartY( pFramePos->maRect.mnY );
+ aRelPos.Anchor = ::com::sun::star::drawing::Alignment_TOP_LEFT;
+ aLegendProp.SetProperty( EXC_CHPROP_RELATIVEPOSITION, aRelPos );
+ }
+ else
+ {
+ // no manual position found, just go for the default
+ eApiPos = cssc2::LegendPosition_LINE_END;
+ }
+
+
+ /* Legend size. #i71697# It is not possible to set the legend size
+ directly in the Chart, do some magic here. */
+ if( !pFramePos || (pFramePos->mnBRMode != EXC_CHFRAMEPOS_ABSSIZE_POINTS) ||
+ (pFramePos->maRect.mnWidth == 0) || (pFramePos->maRect.mnHeight == 0) )
+ {
+ // automatic size: determine entry direction from flags
+ eApiExpand = ::get_flagvalue( maData.mnFlags, EXC_CHLEGEND_STACKED,
+ cssc2::LegendExpansion_HIGH, cssc2::LegendExpansion_WIDE );
+ }
+ else
+ {
+ // legend size is given in points, not in chart units
+ double fRatio = static_cast< double >( pFramePos->maRect.mnWidth ) / pFramePos->maRect.mnHeight;
+ if( fRatio > 1.5 )
+ eApiExpand = cssc2::LegendExpansion_WIDE;
+ else if( fRatio < 0.75 )
+ eApiExpand = cssc2::LegendExpansion_HIGH;
+ else
+ eApiExpand = cssc2::LegendExpansion_BALANCED;
+ }
+ }
+ aLegendProp.SetProperty( EXC_CHPROP_ANCHORPOSITION, eApiPos );
+ aLegendProp.SetProperty( EXC_CHPROP_EXPANSION, eApiExpand );
+ }
+ return xLegend;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChDropBar::XclImpChDropBar( sal_uInt16 nDropBar ) :
+ mnDropBar( nDropBar ),
+ mnBarDist( 0 )
+{
+}
+
+void XclImpChDropBar::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> mnBarDist;
+}
+
+void XclImpChDropBar::Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
+{
+ XclChObjectType eObjType = EXC_CHOBJTYPE_BACKGROUND;
+ switch( mnDropBar )
+ {
+ case EXC_CHDROPBAR_UP: eObjType = EXC_CHOBJTYPE_WHITEDROPBAR; break;
+ case EXC_CHDROPBAR_DOWN: eObjType = EXC_CHOBJTYPE_BLACKDROPBAR; break;
+ }
+ ConvertFrameBase( rRoot, rPropSet, eObjType );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot ),
+ maType( rRoot ),
+ maTypeInfo( maType.GetTypeInfo() )
+{
+ // Initialize unused format indexes set. At this time, all formats are unused.
+ for( sal_uInt16 nFormatIdx = 0; nFormatIdx <= EXC_CHSERIES_MAXSERIES; ++nFormatIdx )
+ maUnusedFormats.insert( maUnusedFormats.end(), nFormatIdx );
+}
+
+void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm.Ignore( 16 );
+ rStrm >> maData.mnFlags >> maData.mnGroupIdx;
+}
+
+void XclImpChTypeGroup::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHCHART3D:
+ mxChart3d.reset( new XclImpChChart3d );
+ mxChart3d->ReadChChart3d( rStrm );
+ break;
+ case EXC_ID_CHLEGEND:
+ mxLegend.reset( new XclImpChLegend( GetChRoot() ) );
+ mxLegend->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHDEFAULTTEXT:
+ GetChartData().ReadChDefaultText( rStrm );
+ break;
+ case EXC_ID_CHDROPBAR:
+ ReadChDropBar( rStrm );
+ break;
+ case EXC_ID_CHCHARTLINE:
+ ReadChChartLine( rStrm );
+ break;
+ case EXC_ID_CHDATAFORMAT:
+ ReadChDataFormat( rStrm );
+ break;
+ default:
+ maType.ReadChType( rStrm );
+ }
+}
+
+void XclImpChTypeGroup::Finalize()
+{
+ // check and set valid chart type
+ bool bStockChart =
+ (maType.GetRecId() == EXC_ID_CHLINE) && // must be a line chart
+ !mxChart3d && // must be a 2d chart
+ HasHiLoLine() && // must contain hi-lo lines
+ (maSeries.size() == static_cast<XclImpChSeriesVec::size_type>(HasDropBars() ? 4 : 3)); // correct series count
+ maType.Finalize( bStockChart );
+
+ // extended type info
+ maTypeInfo.Set( maType.GetTypeInfo(), mxChart3d.is(), false );
+
+ // reverse series order for some unstacked 2D chart types
+ if( maTypeInfo.mbReverseSeries && !Is3dChart() && !maType.IsStacked() && !maType.IsPercent() )
+ ::std::reverse( maSeries.begin(), maSeries.end() );
+
+ // update chart type group format, may depend on chart type finalized above
+ if( mxGroupFmt.is() )
+ mxGroupFmt->UpdateGroupFormat( maTypeInfo );
+}
+
+void XclImpChTypeGroup::AddSeries( XclImpChSeriesRef xSeries )
+{
+ if( xSeries.is() )
+ maSeries.push_back( xSeries );
+ // store first inserted series separately, series order may be reversed later
+ if( !mxFirstSeries )
+ mxFirstSeries = xSeries;
+}
+
+void XclImpChTypeGroup::SetUsedFormatIndex( sal_uInt16 nFormatIdx )
+{
+ maUnusedFormats.erase( nFormatIdx );
+}
+
+sal_uInt16 XclImpChTypeGroup::PopUnusedFormatIndex()
+{
+ DBG_ASSERT( !maUnusedFormats.empty(), "XclImpChTypeGroup::PopUnusedFormatIndex - no more format indexes available" );
+ sal_uInt16 nFormatIdx = maUnusedFormats.empty() ? 0 : *maUnusedFormats.begin();
+ SetUsedFormatIndex( nFormatIdx );
+ return nFormatIdx;
+}
+
+bool XclImpChTypeGroup::HasVarPointFormat() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS ) &&
+ ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_MULTI) || // multiple series allowed
+ ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_SINGLE) && // or exactly 1 series?
+ (maSeries.size() == 1)));
+}
+
+bool XclImpChTypeGroup::HasConnectorLines() const
+{
+ // existence of connector lines (only in stacked bar charts)
+ bool bAnyStacked = maType.IsStacked() || maType.IsPercent();
+ XclImpChLineFormatRef xConnLine = maChartLines.get( EXC_CHCHARTLINE_CONNECT );
+ return bAnyStacked && (maTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) && xConnLine.is() && xConnLine->HasLine();
+}
+
+const String& XclImpChTypeGroup::GetSingleSeriesTitle() const
+{
+ // no automatic title for series with trendlines or error bars
+ // pie charts always show an automatic title, even if more series exist
+ return (mxFirstSeries.is() && !mxFirstSeries->HasChildSeries() && (maTypeInfo.mbSingleSeriesVis || (maSeries.size() == 1))) ?
+ mxFirstSeries->GetTitle() : String::EmptyString();
+}
+
+void XclImpChTypeGroup::ConvertChart3d( ScfPropertySet& rPropSet ) const
+{
+ if( mxChart3d.is() )
+ mxChart3d->Convert( rPropSet, Is3dWallChart() );
+}
+
+Reference< XCoordinateSystem > XclImpChTypeGroup::CreateCoordSystem() const
+{
+ return maType.CreateCoordSystem( Is3dChart() );
+}
+
+Reference< XChartType > XclImpChTypeGroup::CreateChartType( Reference< XDiagram > xDiagram, sal_Int32 nApiAxesSetIdx ) const
+{
+ DBG_ASSERT( IsValidGroup(), "XclImpChTypeGroup::CreateChartType - type group without series" );
+
+ // create the chart type object
+ Reference< XChartType > xChartType = maType.CreateChartType( xDiagram, Is3dChart() );
+
+ // bar chart connector lines
+ if( HasConnectorLines() )
+ {
+ ScfPropertySet aDiaProp( xDiagram );
+ aDiaProp.SetBoolProperty( EXC_CHPROP_CONNECTBARS, true );
+ }
+
+ /* Stock chart needs special processing. Create one 'big' series with
+ data sequences of different roles. */
+ if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
+ CreateStockSeries( xChartType, nApiAxesSetIdx );
+ else
+ CreateDataSeries( xChartType, nApiAxesSetIdx );
+
+ return xChartType;
+}
+
+Reference< XLabeledDataSequence > XclImpChTypeGroup::CreateCategSequence() const
+{
+ Reference< XLabeledDataSequence > xLabeledSeq;
+ // create category sequence from first visible series
+ if( mxFirstSeries.is() )
+ xLabeledSeq = mxFirstSeries->CreateCategSequence( EXC_CHPROP_ROLE_CATEG );
+ return xLabeledSeq;
+}
+
+void XclImpChTypeGroup::ReadChDropBar( XclImpStream& rStrm )
+{
+ sal_uInt16 nDropBar = EXC_CHDROPBAR_NONE;
+ if( !maDropBars.has( EXC_CHDROPBAR_UP ) )
+ nDropBar = EXC_CHDROPBAR_UP;
+ else if( !maDropBars.has( EXC_CHDROPBAR_DOWN ) )
+ nDropBar = EXC_CHDROPBAR_DOWN;
+
+ if( nDropBar != EXC_CHDROPBAR_NONE )
+ {
+ XclImpChDropBarRef xDropBar( new XclImpChDropBar( nDropBar ) );
+ xDropBar->ReadRecordGroup( rStrm );
+ maDropBars[ nDropBar ] = xDropBar;
+ }
+}
+
+void XclImpChTypeGroup::ReadChChartLine( XclImpStream& rStrm )
+{
+ sal_uInt16 nLineId = rStrm.ReaduInt16();
+ if( (rStrm.GetNextRecId() == EXC_ID_CHLINEFORMAT) && rStrm.StartNextRecord() )
+ {
+ XclImpChLineFormatRef xLineFmt( new XclImpChLineFormat );
+ xLineFmt->ReadChLineFormat( rStrm );
+ maChartLines[ nLineId ] = xLineFmt;
+ }
+}
+
+void XclImpChTypeGroup::ReadChDataFormat( XclImpStream& rStrm )
+{
+ // global series and data point format
+ XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
+ xDataFmt->ReadRecordGroup( rStrm );
+ const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
+ if( (rPos.mnSeriesIdx == 0) && (rPos.mnPointIdx == 0) &&
+ (xDataFmt->GetFormatIdx() == EXC_CHDATAFORMAT_DEFAULT) )
+ mxGroupFmt = xDataFmt;
+}
+
+
+void XclImpChTypeGroup::InsertDataSeries( Reference< XChartType > xChartType,
+ Reference< XDataSeries > xSeries, sal_Int32 nApiAxesSetIdx ) const
+{
+ Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
+ if( xSeriesCont.is() && xSeries.is() )
+ {
+ // series stacking mode
+ cssc2::StackingDirection eStacking = cssc2::StackingDirection_NO_STACKING;
+ // stacked overrides deep-3d
+ if( maType.IsStacked() || maType.IsPercent() )
+ eStacking = cssc2::StackingDirection_Y_STACKING;
+ else if( Is3dDeepChart() )
+ eStacking = cssc2::StackingDirection_Z_STACKING;
+
+ // additional series properties
+ ScfPropertySet aSeriesProp( xSeries );
+ aSeriesProp.SetProperty( EXC_CHPROP_STACKINGDIR, eStacking );
+ aSeriesProp.SetProperty( EXC_CHPROP_ATTAXISINDEX, nApiAxesSetIdx );
+
+ // insert series into container
+ try
+ {
+ xSeriesCont->addDataSeries( xSeries );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChTypeGroup::InsertDataSeries - cannot add data series" );
+ }
+ }
+}
+
+void XclImpChTypeGroup::CreateDataSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
+{
+ bool bSpline = false;
+ for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
+ {
+ Reference< XDataSeries > xDataSeries = (*aIt)->CreateDataSeries();
+ InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
+ bSpline |= (*aIt)->HasSpline();
+ }
+ // spline - TODO: set at single series (#i66858#)
+ if( bSpline && !maTypeInfo.IsSeriesFrameFormat() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) )
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ aTypeProp.SetProperty( EXC_CHPROP_CURVESTYLE, ::com::sun::star::chart2::CurveStyle_CUBIC_SPLINES );
+ }
+}
+
+void XclImpChTypeGroup::CreateStockSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
+{
+ // create the data series object
+ Reference< XDataSeries > xDataSeries( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
+ Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
+ if( xDataSink.is() )
+ {
+ // create a list of data sequences from all series
+ ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
+ DBG_ASSERT( maSeries.size() >= 3, "XclImpChTypeGroup::CreateChartType - missing stock series" );
+ int nRoleIdx = (maSeries.size() == 3) ? 1 : 0;
+ for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end();
+ (nRoleIdx < 4) && (aIt != aEnd); ++nRoleIdx, ++aIt )
+ {
+ // create a data sequence with a specific role
+ OUString aRole;
+ switch( nRoleIdx )
+ {
+ case 0: aRole = EXC_CHPROP_ROLE_OPENVALUES; break;
+ case 1: aRole = EXC_CHPROP_ROLE_HIGHVALUES; break;
+ case 2: aRole = EXC_CHPROP_ROLE_LOWVALUES; break;
+ case 3: aRole = EXC_CHPROP_ROLE_CLOSEVALUES; break;
+ }
+ Reference< XLabeledDataSequence > xDataSeq = (*aIt)->CreateValueSequence( aRole );
+ if( xDataSeq.is() )
+ aLabeledSeqVec.push_back( xDataSeq );
+ }
+
+ // attach labeled data sequences to series and insert series into chart type
+ xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
+
+ // formatting of special stock chart elements
+ ScfPropertySet aTypeProp( xChartType );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_JAPANESE, HasDropBars() );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWFIRST, HasDropBars() );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWHIGHLOW, true );
+ // hi-lo line format
+ XclImpChLineFormatRef xHiLoLine = maChartLines.get( EXC_CHCHARTLINE_HILO );
+ if( xHiLoLine.is() )
+ {
+ ScfPropertySet aSeriesProp( xDataSeries );
+ xHiLoLine->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
+ }
+ // white dropbar format
+ XclImpChDropBarRef xUpBar = maDropBars.get( EXC_CHDROPBAR_UP );
+ Reference< XPropertySet > xWhitePropSet;
+ if( xUpBar.is() && aTypeProp.GetProperty( xWhitePropSet, EXC_CHPROP_WHITEDAY ) )
+ {
+ ScfPropertySet aBarProp( xWhitePropSet );
+ xUpBar->Convert( GetChRoot(), aBarProp );
+ }
+ // black dropbar format
+ XclImpChDropBarRef xDownBar = maDropBars.get( EXC_CHDROPBAR_DOWN );
+ Reference< XPropertySet > xBlackPropSet;
+ if( xDownBar.is() && aTypeProp.GetProperty( xBlackPropSet, EXC_CHPROP_BLACKDAY ) )
+ {
+ ScfPropertySet aBarProp( xBlackPropSet );
+ xDownBar->Convert( GetChRoot(), aBarProp );
+ }
+
+ // insert the series into the chart type object
+ InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
+ }
+}
+
+// Axes =======================================================================
+
+XclImpChLabelRange::XclImpChLabelRange( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChLabelRange::ReadChLabelRange( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnCross >> maData.mnLabelFreq >> maData.mnTickFreq >> maData.mnFlags;
+}
+
+void XclImpChLabelRange::Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const
+{
+ // do not overlap text unless all labels are visible
+ rPropSet.SetBoolProperty( EXC_CHPROP_TEXTOVERLAP, maData.mnLabelFreq == 1 );
+ // do not break text into several lines unless all labels are visible
+ rPropSet.SetBoolProperty( EXC_CHPROP_TEXTBREAK, maData.mnLabelFreq == 1 );
+ // do not stagger labels in two lines
+ rPropSet.SetProperty( EXC_CHPROP_ARRANGEORDER, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
+
+ // reverse order
+ bool bReverse = ::get_flag( maData.mnFlags, EXC_CHLABELRANGE_REVERSE ) != bMirrorOrient;
+ rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
+
+ //! TODO #i58731# show n-th category
+}
+
+void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const
+{
+ /* Crossing mode (max-cross flag overrides other crossing settings). Excel
+ does not move the Y axis in 3D charts, regardless of actual settings.
+ But: the Y axis has to be moved to "end", if the X axis is mirrored,
+ to keep it at the left end of the chart. */
+ bool bMaxCross = ::get_flag( maData.mnFlags, b3dChart ? EXC_CHLABELRANGE_REVERSE : EXC_CHLABELRANGE_MAXCROSS );
+ cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
+
+ // crossing position
+ double fCrossingPos = b3dChart ? 1.0 : maData.mnCross;
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChValueRange::XclImpChValueRange( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChValueRange::ReadChValueRange( XclImpStream& rStrm )
+{
+ rStrm >> maData.mfMin
+ >> maData.mfMax
+ >> maData.mfMajorStep
+ >> maData.mfMinorStep
+ >> maData.mfCross
+ >> maData.mnFlags;
+}
+
+void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) const
+{
+ // scaling algorithm
+ bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
+ OUString aScalingService = bLogScale ? SERVICE_CHART2_LOGSCALING : SERVICE_CHART2_LINEARSCALING;
+ rScaleData.Scaling.set( ScfApiHelper::CreateInstance( aScalingService ), UNO_QUERY );
+
+ // min/max
+ lclSetExpValueOrClearAny( rScaleData.Minimum, maData.mfMin, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN ) );
+ lclSetExpValueOrClearAny( rScaleData.Maximum, maData.mfMax, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX ) );
+
+ // increment
+ bool bAutoMajor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR );
+ bool bAutoMinor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR );
+ // major increment
+ IncrementData& rIncrementData = rScaleData.IncrementData;
+ lclSetValueOrClearAny( rIncrementData.Distance, maData.mfMajorStep, bAutoMajor );
+ // minor increment
+ Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
+ rSubIncrementSeq.realloc( 1 );
+ Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount;
+ if( bLogScale )
+ {
+ if( !bAutoMinor )
+ rIntervalCount <<= sal_Int32( 9 );
+ }
+ else
+ {
+ sal_Int32 nCount = 0;
+ if( !bAutoMajor && !bAutoMinor && (0.0 < maData.mfMinorStep) && (maData.mfMinorStep <= maData.mfMajorStep) )
+ {
+ double fCount = maData.mfMajorStep / maData.mfMinorStep + 0.5;
+ if( fCount < 1001.0 )
+ nCount = static_cast< sal_Int32 >( fCount );
+ }
+ lclSetValueOrClearAny( rIntervalCount, nCount, nCount == 0 );
+ }
+
+ // reverse order
+ bool bReverse = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE ) != bMirrorOrient;
+ rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
+}
+
+void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet& rPropSet ) const
+{
+ bool bMaxCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
+ bool bAutoCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
+ bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
+
+ // crossing mode (max-cross flag overrides other crossing settings)
+ cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
+
+ // crossing position
+ double fCrossingPos = bAutoCross ? 0.0 : maData.mfCross;
+ if( bLogScale ) fCrossingPos = pow( 10.0, fCrossingPos );
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_Int32 lclGetApiTickmarks( sal_uInt8 nXclTickPos )
+{
+ using namespace ::com::sun::star::chart2::TickmarkStyle;
+ sal_Int32 nApiTickmarks = NONE;
+ ::set_flag( nApiTickmarks, INNER, ::get_flag( nXclTickPos, EXC_CHTICK_INSIDE ) );
+ ::set_flag( nApiTickmarks, OUTER, ::get_flag( nXclTickPos, EXC_CHTICK_OUTSIDE ) );
+ return nApiTickmarks;
+}
+
+cssc::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos )
+{
+ using namespace ::com::sun::star::chart;
+ switch( nXclLabelPos )
+ {
+ case EXC_CHTICK_LOW: return ChartAxisLabelPosition_OUTSIDE_START;
+ case EXC_CHTICK_HIGH: return ChartAxisLabelPosition_OUTSIDE_END;
+ case EXC_CHTICK_NEXT: return ChartAxisLabelPosition_NEAR_AXIS;
+ }
+ return ChartAxisLabelPosition_NEAR_AXIS;
+}
+
+} // namespace
+
+XclImpChTick::XclImpChTick( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChTick::ReadChTick( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnMajor
+ >> maData.mnMinor
+ >> maData.mnLabelPos
+ >> maData.mnBackMode;
+ rStrm.Ignore( 16 );
+ rStrm >> maData.maTextColor
+ >> maData.mnFlags;
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ // #116397# BIFF8: index into palette used instead of RGB data
+ maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
+ // rotation
+ rStrm >> maData.mnRotation;
+ }
+ else
+ {
+ // BIFF2-BIFF7: get rotation from text orientation
+ sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 2, 3 );
+ maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
+ }
+}
+
+Color XclImpChTick::GetFontColor() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
+}
+
+sal_uInt16 XclImpChTick::GetRotation() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOROT ) ? EXC_CHART_AUTOROTATION : maData.mnRotation;
+}
+
+void XclImpChTick::Convert( ScfPropertySet& rPropSet ) const
+{
+ rPropSet.SetProperty( EXC_CHPROP_MAJORTICKS, lclGetApiTickmarks( maData.mnMajor ) );
+ rPropSet.SetProperty( EXC_CHPROP_MINORTICKS, lclGetApiTickmarks( maData.mnMinor ) );
+ rPropSet.SetProperty( EXC_CHPROP_LABELPOSITION, lclGetApiLabelPosition( maData.mnLabelPos ) );
+ rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, cssc::ChartAxisMarkPosition_AT_AXIS );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChAxis::XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType ) :
+ XclImpChRoot( rRoot ),
+ mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
+{
+ maData.mnType = nAxisType;
+}
+
+void XclImpChAxis::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnType;
+}
+
+void XclImpChAxis::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHLABELRANGE:
+ mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
+ mxLabelRange->ReadChLabelRange( rStrm );
+ break;
+ case EXC_ID_CHVALUERANGE:
+ mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
+ mxValueRange->ReadChValueRange( rStrm );
+ break;
+ case EXC_ID_CHFORMAT:
+ rStrm >> mnNumFmtIdx;
+ break;
+ case EXC_ID_CHTICK:
+ mxTick.reset( new XclImpChTick( GetChRoot() ) );
+ mxTick->ReadChTick( rStrm );
+ break;
+ case EXC_ID_CHFONT:
+ mxFont.reset( new XclImpChFont );
+ mxFont->ReadChFont( rStrm );
+ break;
+ case EXC_ID_CHAXISLINE:
+ ReadChAxisLine( rStrm );
+ break;
+ }
+}
+
+void XclImpChAxis::Finalize()
+{
+ // add default scaling, needed e.g. to adjust rotation direction of pie and radar charts
+ if( !mxLabelRange )
+ mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
+ if( !mxValueRange )
+ mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
+ // remove invisible grid lines completely
+ if( mxMajorGrid.is() && !mxMajorGrid->HasLine() )
+ mxMajorGrid.reset();
+ if( mxMinorGrid.is() && !mxMinorGrid->HasLine() )
+ mxMinorGrid.reset();
+ // default tick settings different in OOChart and Excel
+ if( !mxTick )
+ mxTick.reset( new XclImpChTick( GetChRoot() ) );
+ // #i4140# different default axis line color
+ if( !mxAxisLine )
+ {
+ XclChLineFormat aLineFmt;
+ // set "show axis" flag, default if line format record is missing
+ ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS );
+ mxAxisLine.reset( new XclImpChLineFormat( aLineFmt ) );
+ }
+ // add wall/floor frame for 3d charts
+ if( !mxWallFrame )
+ CreateWallFrame();
+}
+
+sal_uInt16 XclImpChAxis::GetFontIndex() const
+{
+ return mxFont.is() ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
+}
+
+Color XclImpChAxis::GetFontColor() const
+{
+ return mxTick.is() ? mxTick->GetFontColor() : GetFontAutoColor();
+}
+
+sal_uInt16 XclImpChAxis::GetRotation() const
+{
+ return mxTick.is() ? mxTick->GetRotation() : EXC_CHART_AUTOROTATION;
+}
+
+Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const
+{
+ // create the axis object (always)
+ Reference< XAxis > xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS ), UNO_QUERY );
+ if( xAxis.is() )
+ {
+ ScfPropertySet aAxisProp( xAxis );
+ // #i58688# axis enabled
+ aAxisProp.SetBoolProperty( EXC_CHPROP_SHOW, IsActivated() );
+
+ // axis line properties
+ if( mxAxisLine.is() )
+ mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
+ // axis ticks properties
+ if( mxTick.is() )
+ mxTick->Convert( aAxisProp );
+
+ // axis caption text --------------------------------------------------
+
+ // radar charts disable their category labels via chart type, not via axis
+ bool bHasLabels = HasLabels() &&
+ ((GetAxisType() != EXC_CHAXIS_X) || rTypeGroup.HasCategoryLabels());
+ aAxisProp.SetBoolProperty( EXC_CHPROP_DISPLAYLABELS, bHasLabels );
+ if( bHasLabels )
+ {
+ // font settings from CHFONT record or from default text
+ if( mxFont.is() )
+ ConvertFontBase( GetChRoot(), aAxisProp );
+ else if( const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISLABEL ).get() )
+ pDefText->ConvertFont( aAxisProp );
+ // label text rotation
+ ConvertRotationBase( GetChRoot(), aAxisProp, true );
+ // number format
+ sal_uInt32 nScNumFmt = GetNumFmtBuffer().GetScFormat( mnNumFmtIdx );
+ if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
+ aAxisProp.SetProperty( EXC_CHPROP_NUMBERFORMAT, static_cast< sal_Int32 >( nScNumFmt ) );
+ }
+
+ // axis scaling and increment -----------------------------------------
+
+ const XclChExtTypeInfo& rTypeInfo = rTypeGroup.GetTypeInfo();
+ ScaleData aScaleData = xAxis->getScaleData();
+ // set axis type
+ switch( GetAxisType() )
+ {
+ case EXC_CHAXIS_X:
+ if( rTypeInfo.mbCategoryAxis )
+ {
+ aScaleData.AxisType = cssc2::AxisType::CATEGORY;
+ aScaleData.Categories = rTypeGroup.CreateCategSequence();
+ }
+ else
+ aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
+ break;
+ case EXC_CHAXIS_Y:
+ aScaleData.AxisType = rTypeGroup.IsPercent() ?
+ cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
+ break;
+ case EXC_CHAXIS_Z:
+ aScaleData.AxisType = cssc2::AxisType::SERIES;
+ break;
+ }
+ // axis scaling settings, dependent on axis type
+ switch( aScaleData.AxisType )
+ {
+ case cssc2::AxisType::CATEGORY:
+ case cssc2::AxisType::SERIES:
+ // #i71684# radar charts have reversed rotation direction
+ mxLabelRange->Convert( aAxisProp, aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR );
+ break;
+ case cssc2::AxisType::REALNUMBER:
+ case cssc2::AxisType::PERCENT:
+ // #i85167# pie/donut charts have reversed rotation direction (at Y axis!)
+ mxValueRange->Convert( aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpChAxis::CreateAxis - unknown axis type" );
+ }
+
+ /* Do not set a value to the Origin member anymore (will be done via
+ new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
+ aScaleData.Origin.clear();
+
+ // write back
+ xAxis->setScaleData( aScaleData );
+
+ // grid ---------------------------------------------------------------
+
+ // main grid
+ ScfPropertySet aGridProp( xAxis->getGridProperties() );
+ aGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMajorGrid() );
+ if( mxMajorGrid.is() )
+ mxMajorGrid->Convert( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ // sub grid
+ Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
+ if( aSubGridPropSeq.hasElements() )
+ {
+ ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
+ aSubGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMinorGrid() );
+ if( mxMinorGrid.is() )
+ mxMinorGrid->Convert( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ }
+
+ // position of crossing axis ------------------------------------------
+
+ if( pCrossingAxis )
+ pCrossingAxis->ConvertAxisPosition( aAxisProp, rTypeGroup );
+ }
+ return xAxis;
+}
+
+void XclImpChAxis::ConvertWall( ScfPropertySet& rPropSet ) const
+{
+ if( mxWallFrame.is() )
+ mxWallFrame->Convert( rPropSet );
+}
+
+void XclImpChAxis::ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const
+{
+ if( ((GetAxisType() == EXC_CHAXIS_X) && rTypeGroup.GetTypeInfo().mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z) )
+ mxLabelRange->ConvertAxisPosition( rPropSet, rTypeGroup.Is3dChart() );
+ else
+ mxValueRange->ConvertAxisPosition( rPropSet );
+}
+
+void XclImpChAxis::ReadChAxisLine( XclImpStream& rStrm )
+{
+ XclImpChLineFormatRef* pxLineFmt = 0;
+ bool bWallFrame = false;
+ switch( rStrm.ReaduInt16() )
+ {
+ case EXC_CHAXISLINE_AXISLINE: pxLineFmt = &mxAxisLine; break;
+ case EXC_CHAXISLINE_MAJORGRID: pxLineFmt = &mxMajorGrid; break;
+ case EXC_CHAXISLINE_MINORGRID: pxLineFmt = &mxMinorGrid; break;
+ case EXC_CHAXISLINE_WALLS: bWallFrame = true; break;
+ }
+ if( bWallFrame )
+ CreateWallFrame();
+
+ bool bLoop = pxLineFmt || bWallFrame;
+ while( bLoop )
+ {
+ sal_uInt16 nRecId = rStrm.GetNextRecId();
+ bLoop = ((nRecId == EXC_ID_CHLINEFORMAT) ||
+ (nRecId == EXC_ID_CHAREAFORMAT) ||
+ (nRecId == EXC_ID_CHESCHERFORMAT))
+ && rStrm.StartNextRecord();
+ if( bLoop )
+ {
+ if( pxLineFmt && (nRecId == EXC_ID_CHLINEFORMAT) )
+ {
+ pxLineFmt->reset( new XclImpChLineFormat );
+ (*pxLineFmt)->ReadChLineFormat( rStrm );
+ }
+ else if( bWallFrame && mxWallFrame.is() )
+ {
+ mxWallFrame->ReadSubRecord( rStrm );
+ }
+ }
+ }
+}
+
+void XclImpChAxis::CreateWallFrame()
+{
+ switch( GetAxisType() )
+ {
+ case EXC_CHAXIS_X:
+ mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_WALL3D ) );
+ break;
+ case EXC_CHAXIS_Y:
+ mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_FLOOR3D ) );
+ break;
+ default:
+ mxWallFrame.reset();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChAxesSet::XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
+ XclImpChRoot( rRoot )
+{
+ maData.mnAxesSetId = nAxesSetId;
+}
+
+void XclImpChAxesSet::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnAxesSetId >> maData.maRect;
+}
+
+void XclImpChAxesSet::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAMEPOS:
+ mxFramePos.reset( new XclImpChFramePos );
+ mxFramePos->ReadChFramePos( rStrm );
+ break;
+ case EXC_ID_CHAXIS:
+ ReadChAxis( rStrm );
+ break;
+ case EXC_ID_CHTEXT:
+ ReadChText( rStrm );
+ break;
+ case EXC_ID_CHPLOTFRAME:
+ ReadChPlotFrame( rStrm );
+ break;
+ case EXC_ID_CHTYPEGROUP:
+ ReadChTypeGroup( rStrm );
+ break;
+ }
+}
+
+void XclImpChAxesSet::Finalize()
+{
+ if( IsValidAxesSet() )
+ {
+ // finalize chart type groups, erase empty groups without series
+ XclImpChTypeGroupMap aValidGroups;
+ for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
+ {
+ XclImpChTypeGroupRef xTypeGroup = aIt->second;
+ xTypeGroup->Finalize();
+ if( xTypeGroup->IsValidGroup() )
+ aValidGroups[ aIt->first ] = xTypeGroup;
+ }
+ maTypeGroups.swap( aValidGroups );
+ }
+
+ // invalid chart type groups are deleted now, check again with IsValidAxesSet()
+ if( IsValidAxesSet() )
+ {
+ // always create missing axis objects
+ if( !mxXAxis )
+ mxXAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_X ) );
+ if( !mxYAxis )
+ mxYAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Y ) );
+ if( !mxZAxis && GetFirstTypeGroup()->Is3dDeepChart() )
+ mxZAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Z ) );
+
+ // finalize axes
+ if( mxXAxis.is() ) mxXAxis->Finalize();
+ if( mxYAxis.is() ) mxYAxis->Finalize();
+ if( mxZAxis.is() ) mxZAxis->Finalize();
+
+ // finalize axis titles
+ XclImpChTextRef xDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE );
+ String aAutoTitle = CREATE_STRING( "Axis Title" );
+ lclFinalizeTitle( mxXAxisTitle, xDefText, aAutoTitle );
+ lclFinalizeTitle( mxYAxisTitle, xDefText, aAutoTitle );
+ lclFinalizeTitle( mxZAxisTitle, xDefText, aAutoTitle );
+
+ // #i47745# missing plot frame -> invisible border and area
+ if( !mxPlotFrame )
+ mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
+ }
+}
+
+XclImpChTypeGroupRef XclImpChAxesSet::GetFirstTypeGroup() const
+{
+ XclImpChTypeGroupRef xTypeGroup;
+ if( !maTypeGroups.empty() )
+ xTypeGroup = maTypeGroups.begin()->second;
+ return xTypeGroup;
+}
+
+XclImpChLegendRef XclImpChAxesSet::GetLegend() const
+{
+ XclImpChLegendRef xLegend;
+ for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); !xLegend && (aIt != aEnd); ++aIt )
+ xLegend = aIt->second->GetLegend();
+ return xLegend;
+}
+
+const String& XclImpChAxesSet::GetSingleSeriesTitle() const
+{
+ return (maTypeGroups.size() == 1) ? maTypeGroups.begin()->second->GetSingleSeriesTitle() : String::EmptyString();
+}
+
+void XclImpChAxesSet::Convert( Reference< XDiagram > xDiagram ) const
+{
+ if( IsValidAxesSet() && xDiagram.is() )
+ {
+ // diagram background formatting
+ if( GetAxesSetId() == EXC_CHAXESSET_PRIMARY )
+ ConvertBackground( xDiagram );
+
+ // create the coordinate system, this inserts all chart types and series
+ Reference< XCoordinateSystem > xCoordSystem = CreateCoordSystem( xDiagram );
+ if( xCoordSystem.is() )
+ {
+ // insert coordinate system, if not already done
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
+ if( aCoordSystems.getLength() == 0 )
+ xCoordSystemCont->addCoordinateSystem( xCoordSystem );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::Convert - cannot insert coordinate system" );
+ }
+
+ // create the axes with grids and axis titles and insert them into the diagram
+ ConvertAxis( mxXAxis, mxXAxisTitle, xCoordSystem, mxYAxis.get() );
+ ConvertAxis( mxYAxis, mxYAxisTitle, xCoordSystem, mxXAxis.get() );
+ ConvertAxis( mxZAxis, mxZAxisTitle, xCoordSystem, 0 );
+ }
+ }
+}
+
+void XclImpChAxesSet::ConvertTitlePositions() const
+{
+ if( mxXAxisTitle.is() )
+ mxXAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_X ) );
+ if( mxYAxisTitle.is() )
+ mxYAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Y ) );
+ if( mxZAxisTitle.is() )
+ mxZAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Z ) );
+}
+
+void XclImpChAxesSet::ReadChAxis( XclImpStream& rStrm )
+{
+ XclImpChAxisRef xAxis( new XclImpChAxis( GetChRoot() ) );
+ xAxis->ReadRecordGroup( rStrm );
+
+ switch( xAxis->GetAxisType() )
+ {
+ case EXC_CHAXIS_X: mxXAxis = xAxis; break;
+ case EXC_CHAXIS_Y: mxYAxis = xAxis; break;
+ case EXC_CHAXIS_Z: mxZAxis = xAxis; break;
+ }
+}
+
+void XclImpChAxesSet::ReadChText( XclImpStream& rStrm )
+{
+ XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
+ xText->ReadRecordGroup( rStrm );
+
+ switch( xText->GetLinkTarget() )
+ {
+ case EXC_CHOBJLINK_XAXIS: mxXAxisTitle = xText; break;
+ case EXC_CHOBJLINK_YAXIS: mxYAxisTitle = xText; break;
+ case EXC_CHOBJLINK_ZAXIS: mxZAxisTitle = xText; break;
+ }
+}
+
+void XclImpChAxesSet::ReadChPlotFrame( XclImpStream& rStrm )
+{
+ if( (rStrm.GetNextRecId() == EXC_ID_CHFRAME) && rStrm.StartNextRecord() )
+ {
+ mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
+ mxPlotFrame->ReadRecordGroup( rStrm );
+ }
+}
+
+void XclImpChAxesSet::ReadChTypeGroup( XclImpStream& rStrm )
+{
+ XclImpChTypeGroupRef xTypeGroup( new XclImpChTypeGroup( GetChRoot() ) );
+ xTypeGroup->ReadRecordGroup( rStrm );
+ maTypeGroups[ xTypeGroup->GetGroupIdx() ] = xTypeGroup;
+}
+
+Reference< XCoordinateSystem > XclImpChAxesSet::CreateCoordSystem( Reference< XDiagram > xDiagram ) const
+{
+ Reference< XCoordinateSystem > xCoordSystem;
+
+ /* Try to get existing ccordinate system. For now, all series from primary
+ and secondary axes sets are inserted into one coordinate system. Later,
+ this should be changed to use one coordinate system for each axes set. */
+ Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY );
+ if( xCoordSystemCont.is() )
+ {
+ Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
+ DBG_ASSERT( aCoordSystems.getLength() <= 1, "XclImpChAxesSet::CreateCoordSystem - too many existing coordinate systems" );
+ if( aCoordSystems.getLength() > 0 )
+ xCoordSystem = aCoordSystems[ 0 ];
+ }
+
+ // create the coordinate system according to the first chart type
+ if( !xCoordSystem.is() )
+ {
+ XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ if( xTypeGroup.is() )
+ {
+ xCoordSystem = xTypeGroup->CreateCoordSystem();
+ // convert 3d chart settings
+ ScfPropertySet aDiaProp( xDiagram );
+ xTypeGroup->ConvertChart3d( aDiaProp );
+ }
+ }
+
+ /* Create XChartType objects for all chart type groups. Each group will
+ add its series to the data provider attached to the chart document. */
+ Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
+ if( xChartTypeCont.is() )
+ {
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+ for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
+ {
+ try
+ {
+ Reference< XChartType > xChartType = aIt->second->CreateChartType( xDiagram, nApiAxesSetIdx );
+ if( xChartType.is() )
+ xChartTypeCont->addChartType( xChartType );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::CreateCoordSystem - cannot add chart type" );
+ }
+ }
+ }
+
+ return xCoordSystem;
+}
+
+void XclImpChAxesSet::ConvertAxis(
+ XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
+ Reference< XCoordinateSystem > xCoordSystem, const XclImpChAxis* pCrossingAxis ) const
+{
+ if( xChAxis.is() )
+ {
+ // create and attach the axis object
+ Reference< XAxis > xAxis = CreateAxis( *xChAxis, pCrossingAxis );
+ if( xAxis.is() )
+ {
+ // create and attach the axis title
+ if( xChAxisTitle.is() ) try
+ {
+ Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
+ Reference< XTitle > xTitle( xChAxisTitle->CreateTitle(), UNO_SET_THROW );
+ xTitled->setTitleObject( xTitle );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis title" );
+ }
+
+ // insert axis into coordinate system
+ try
+ {
+ sal_Int32 nApiAxisDim = xChAxis->GetApiAxisDimension();
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+ xCoordSystem->setAxisByDimension( nApiAxisDim, xAxis, nApiAxesSetIdx );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis" );
+ }
+ }
+ }
+}
+
+Reference< XAxis > XclImpChAxesSet::CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const
+{
+ Reference< XAxis > xAxis;
+ if( const XclImpChTypeGroup* pTypeGroup = GetFirstTypeGroup().get() )
+ xAxis = rChAxis.CreateAxis( *pTypeGroup, pCrossingAxis );
+ return xAxis;
+}
+
+void XclImpChAxesSet::ConvertBackground( Reference< XDiagram > xDiagram ) const
+{
+ XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ if( xTypeGroup.is() && xTypeGroup->Is3dWallChart() )
+ {
+ // wall/floor formatting (3D charts)
+ if( mxXAxis.is() )
+ {
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxXAxis->ConvertWall( aWallProp );
+ }
+ if( mxYAxis.is() )
+ {
+ ScfPropertySet aFloorProp( xDiagram->getFloor() );
+ mxYAxis->ConvertWall( aFloorProp );
+ }
+ }
+ else if( mxPlotFrame.is() )
+ {
+ // diagram background formatting
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxPlotFrame->Convert( aWallProp );
+ }
+}
+
+// The chart object ===========================================================
+
+XclImpChChart::XclImpChChart( const XclImpRoot& rRoot ) :
+ XclImpChRoot( rRoot, *this )
+{
+ mxPrimAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
+ mxSecnAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
+}
+
+XclImpChChart::~XclImpChChart()
+{
+}
+
+void XclImpChChart::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ // coordinates are stored as 16.16 fixed point
+ rStrm >> maRect;
+}
+
+void XclImpChChart::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAME:
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
+ mxFrame->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHSERIES:
+ ReadChSeries( rStrm );
+ break;
+ case EXC_ID_CHPROPERTIES:
+ ReadChProperties( rStrm );
+ break;
+ case EXC_ID_CHDEFAULTTEXT:
+ ReadChDefaultText( rStrm );
+ break;
+ case EXC_ID_CHAXESSET:
+ ReadChAxesSet( rStrm );
+ break;
+ case EXC_ID_CHTEXT:
+ ReadChText( rStrm );
+ break;
+ case EXC_ID_CHEND:
+ Finalize(); // finalize the entire chart object
+ break;
+ }
+}
+
+void XclImpChChart::ReadChDefaultText( XclImpStream& rStrm )
+{
+ sal_uInt16 nTextId = rStrm.ReaduInt16();
+ if( (rStrm.GetNextRecId() == EXC_ID_CHTEXT) && rStrm.StartNextRecord() )
+ {
+ XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
+ xText->ReadRecordGroup( rStrm );
+ maDefTexts[ nTextId ] = xText;
+ }
+}
+
+void XclImpChChart::ReadChDataFormat( XclImpStream& rStrm )
+{
+ XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
+ xDataFmt->ReadRecordGroup( rStrm );
+ if( xDataFmt->GetPointPos().mnSeriesIdx <= EXC_CHSERIES_MAXSERIES )
+ {
+ XclImpChDataFormatRef& rxMapFmt = maDataFmts[ xDataFmt->GetPointPos() ];
+ /* Do not overwrite existing data format group, Excel always uses the
+ first data format group occuring in any CHSERIES group. */
+ if( !rxMapFmt )
+ rxMapFmt = xDataFmt;
+ }
+}
+
+void XclImpChChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
+{
+ if( !mxFrame )
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
+ mxFrame->UpdateObjFrame( rLineData, rFillData );
+}
+
+XclImpChTypeGroupRef XclImpChChart::GetTypeGroup( sal_uInt16 nGroupIdx ) const
+{
+ XclImpChTypeGroupRef xTypeGroup = mxPrimAxesSet->GetTypeGroup( nGroupIdx );
+ if( !xTypeGroup ) xTypeGroup = mxSecnAxesSet->GetTypeGroup( nGroupIdx );
+ if( !xTypeGroup ) xTypeGroup = mxPrimAxesSet->GetFirstTypeGroup();
+ return xTypeGroup;
+}
+
+XclImpChTextRef XclImpChChart::GetDefaultText( XclChTextType eTextType ) const
+{
+ sal_uInt16 nDefTextId = EXC_CHDEFTEXT_GLOBAL;
+ bool bBiff8 = GetBiff() == EXC_BIFF8;
+ switch( eTextType )
+ {
+ case EXC_CHTEXTTYPE_TITLE: nDefTextId = EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_LEGEND: nDefTextId = EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_AXISTITLE: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_AXISLABEL: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_DATALABEL: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
+ }
+ return maDefTexts.get( nDefTextId );
+}
+
+bool XclImpChChart::IsManualPlotArea() const
+{
+ // there is no real automatic mode in BIFF5 charts
+ return (GetBiff() <= EXC_BIFF5) || ::get_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
+}
+
+void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc,
+ XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
+{
+ // initialize conversion (locks the model to suppress any internal updates)
+ InitConversion( xChartDoc, rChartRect );
+
+ // chart frame formatting
+ if( mxFrame.is() )
+ {
+ ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
+ mxFrame->Convert( aFrameProp );
+ }
+
+ // chart title
+ if( mxTitle.is() ) try
+ {
+ Reference< XTitled > xTitled( xChartDoc, UNO_QUERY_THROW );
+ Reference< XTitle > xTitle( mxTitle->CreateTitle(), UNO_SET_THROW );
+ xTitled->setTitleObject( xTitle );
+ }
+ catch( Exception& )
+ {
+ }
+
+ /* Create the diagram object and attach it to the chart document. Currently,
+ one diagram is used to carry all coordinate systems and data series. */
+ Reference< XDiagram > xDiagram = CreateDiagram();
+ xChartDoc->setFirstDiagram( xDiagram );
+
+ // coordinate systems and chart types, convert axis settings
+ mxPrimAxesSet->Convert( xDiagram );
+ mxSecnAxesSet->Convert( xDiagram );
+
+ // legend
+ if( xDiagram.is() && mxLegend.is() )
+ xDiagram->setLegend( mxLegend->CreateLegend() );
+
+ /* Following all conversions needing the old Chart1 API that involves full
+ initialization of the chart view. */
+ Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY );
+ if( xChart1Doc.is() )
+ {
+ Reference< cssc::XDiagram > xDiagram1 = xChart1Doc->getDiagram();
+
+ /* Set the 'IncludeHiddenCells' property via the old API as only this
+ ensures that the data provider and all created sequences get this
+ flag correctly. */
+ ScfPropertySet aDiaProp( xDiagram1 );
+ bool bShowVisCells = ::get_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY );
+ aDiaProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells );
+
+ // plot area position and size (there is no real automatic mode in BIFF5 charts)
+ XclImpChFramePosRef xPlotAreaPos = mxPrimAxesSet->GetPlotAreaFramePos();
+ if( IsManualPlotArea() && xPlotAreaPos.is() ) try
+ {
+ const XclChFramePos& rFramePos = xPlotAreaPos->GetFramePosData();
+ if( (rFramePos.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rFramePos.mnBRMode == EXC_CHFRAMEPOS_PARENT) )
+ {
+ Reference< cssc::XDiagramPositioning > xPositioning( xDiagram1, UNO_QUERY_THROW );
+ ::com::sun::star::awt::Rectangle aDiagramRect = CalcHmmFromChartRect( rFramePos.maRect );
+ // for pie charts, always set inner plot area size to exclude the data labels as Excel does
+ const XclImpChTypeGroup* pFirstTypeGroup = mxPrimAxesSet->GetFirstTypeGroup().get();
+ if( pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE) )
+ xPositioning->setDiagramPositionExcludingAxes( aDiagramRect );
+ else if( pFirstTypeGroup && pFirstTypeGroup->Is3dChart() )
+ xPositioning->setDiagramPositionIncludingAxesAndAxisTitles( aDiagramRect );
+ else
+ xPositioning->setDiagramPositionIncludingAxes( aDiagramRect );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // positions of all title objects
+ if( mxTitle.is() )
+ mxTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_TITLE ) );
+ mxPrimAxesSet->ConvertTitlePositions();
+ mxSecnAxesSet->ConvertTitlePositions();
+ }
+
+ // unlock the model
+ FinishConversion( rDffConv );
+
+ // start listening to this chart
+ ScDocument& rDoc = GetRoot().GetDoc();
+ if( ScChartListenerCollection* pChartCollection = rDoc.GetChartListenerCollection() )
+ {
+ ::std::auto_ptr< ::std::vector< ScSharedTokenRef > > xRefTokens( new ::std::vector< ScSharedTokenRef > );
+ for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
+ (*aIt)->FillAllSourceLinks( *xRefTokens );
+ if( !xRefTokens->empty() )
+ {
+ ::std::auto_ptr< ScChartListener > xListener( new ScChartListener( rObjName, &rDoc, xRefTokens.release() ) );
+ xListener->SetUsed( true );
+ xListener->StartListeningTo();
+ pChartCollection->Insert( xListener.release() );
+ }
+ }
+}
+
+void XclImpChChart::ReadChSeries( XclImpStream& rStrm )
+{
+ sal_uInt16 nNewSeriesIdx = static_cast< sal_uInt16 >( maSeries.size() );
+ XclImpChSeriesRef xSeries( new XclImpChSeries( GetChRoot(), nNewSeriesIdx ) );
+ xSeries->ReadRecordGroup( rStrm );
+ maSeries.push_back( xSeries );
+}
+
+void XclImpChChart::ReadChProperties( XclImpStream& rStrm )
+{
+ rStrm >> maProps.mnFlags >> maProps.mnEmptyMode;
+}
+
+void XclImpChChart::ReadChAxesSet( XclImpStream& rStrm )
+{
+ XclImpChAxesSetRef xAxesSet( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_NONE ) );
+ xAxesSet->ReadRecordGroup( rStrm );
+ switch( xAxesSet->GetAxesSetId() )
+ {
+ case EXC_CHAXESSET_PRIMARY: mxPrimAxesSet = xAxesSet; break;
+ case EXC_CHAXESSET_SECONDARY: mxSecnAxesSet = xAxesSet; break;
+ }
+}
+
+void XclImpChChart::ReadChText( XclImpStream& rStrm )
+{
+ XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
+ xText->ReadRecordGroup( rStrm );
+ switch( xText->GetLinkTarget() )
+ {
+ case EXC_CHOBJLINK_TITLE:
+ mxTitle = xText;
+ break;
+ case EXC_CHOBJLINK_DATA:
+ {
+ sal_uInt16 nSeriesIdx = xText->GetPointPos().mnSeriesIdx;
+ if( nSeriesIdx < maSeries.size() )
+ maSeries[ nSeriesIdx ]->SetDataLabel( xText );
+ }
+ break;
+ }
+}
+
+void XclImpChChart::Finalize()
+{
+ // finalize series (must be done first)
+ FinalizeSeries();
+ // #i49218# legend may be attached to primary or secondary axes set
+ mxLegend = mxPrimAxesSet->GetLegend();
+ if( !mxLegend )
+ mxLegend = mxSecnAxesSet->GetLegend();
+ if( mxLegend.is() )
+ mxLegend->Finalize();
+ // axes sets, updates chart type group default formats -> must be called before FinalizeDataFormats()
+ mxPrimAxesSet->Finalize();
+ mxSecnAxesSet->Finalize();
+ // formatting of all series
+ FinalizeDataFormats();
+ // #i47745# missing frame -> invisible border and area
+ if( !mxFrame )
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
+ // chart title
+ FinalizeTitle();
+}
+
+void XclImpChChart::FinalizeSeries()
+{
+ for( XclImpChSeriesVec::iterator aSIt = maSeries.begin(), aSEnd = maSeries.end(); aSIt != aSEnd; ++aSIt )
+ {
+ XclImpChSeriesRef xSeries = *aSIt;
+ if( xSeries->HasParentSeries() )
+ {
+ /* Process child series (trend lines and error bars). Data of
+ child series will be set at the connected parent series. */
+ if( xSeries->GetParentIdx() < maSeries.size() )
+ maSeries[ xSeries->GetParentIdx() ]->AddChildSeries( *xSeries );
+ }
+ else
+ {
+ // insert the series into the related chart type group
+ if( XclImpChTypeGroup* pTypeGroup = GetTypeGroup( xSeries->GetGroupIdx() ).get() )
+ pTypeGroup->AddSeries( xSeries );
+ }
+ }
+}
+
+void XclImpChChart::FinalizeDataFormats()
+{
+ /* #i51639# (part 1): CHDATAFORMAT groups are part of CHSERIES groups.
+ Each CHDATAFORMAT group specifies the series and data point it is
+ assigned to. This makes it possible to have a data format that is
+ related to another series, e.g. a CHDATAFORMAT group for series 2 is
+ part of a CHSERIES group that describes series 1. Therefore the chart
+ itself has collected all CHDATAFORMAT groups to be able to store data
+ format groups for series that have not been imported at that time. This
+ loop finally assigns these groups to the related series. */
+ for( XclImpChDataFormatMap::const_iterator aMIt = maDataFmts.begin(), aMEnd = maDataFmts.end(); aMIt != aMEnd; ++aMIt )
+ {
+ sal_uInt16 nSeriesIdx = aMIt->first.mnSeriesIdx;
+ if( nSeriesIdx < maSeries.size() )
+ maSeries[ nSeriesIdx ]->SetDataFormat( aMIt->second );
+ }
+
+ /* #i51639# (part 2): Finalize data formats of all series. This adds for
+ example missing CHDATAFORMAT groups for entire series that are needed
+ for automatic colors of lines and areas. */
+ for( XclImpChSeriesVec::iterator aVIt = maSeries.begin(), aVEnd = maSeries.end(); aVIt != aVEnd; ++aVIt )
+ (*aVIt)->FinalizeDataFormats();
+}
+
+void XclImpChChart::FinalizeTitle()
+{
+ // special handling for auto-generated title
+ String aAutoTitle;
+ if( !mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString()) )
+ {
+ // automatic title from first series name (if there are no series on secondary axes set)
+ if( !mxSecnAxesSet->IsValidAxesSet() )
+ aAutoTitle = mxPrimAxesSet->GetSingleSeriesTitle();
+ if( mxTitle.is() || (aAutoTitle.Len() > 0) )
+ {
+ if( !mxTitle )
+ mxTitle.reset( new XclImpChText( GetChRoot() ) );
+ if( aAutoTitle.Len() == 0 )
+ aAutoTitle = CREATE_STRING( "Chart Title" );
+ }
+ }
+
+ // will reset mxTitle, if it does not contain a string and no auto title exists
+ lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ), aAutoTitle );
+}
+
+Reference< XDiagram > XclImpChChart::CreateDiagram() const
+{
+ // create a diagram object
+ Reference< XDiagram > xDiagram( ScfApiHelper::CreateInstance( SERVICE_CHART2_DIAGRAM ), UNO_QUERY );
+
+ // convert global chart settings
+ ScfPropertySet aDiaProp( xDiagram );
+
+ // treatment of missing values
+ using namespace cssc::MissingValueTreatment;
+ sal_Int32 nMissingValues = LEAVE_GAP;
+ switch( maProps.mnEmptyMode )
+ {
+ case EXC_CHPROPS_EMPTY_SKIP: nMissingValues = LEAVE_GAP; break;
+ case EXC_CHPROPS_EMPTY_ZERO: nMissingValues = USE_ZERO; break;
+ case EXC_CHPROPS_EMPTY_INTERPOLATE: nMissingValues = CONTINUE; break;
+ }
+ aDiaProp.SetProperty( EXC_CHPROP_MISSINGVALUETREATMENT, nMissingValues );
+
+ return xDiagram;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChartDrawing::XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ) :
+ XclImpDrawing( rRoot, bOwnTab ), // sheet charts may contain OLE objects
+ mnScTab( rRoot.GetCurrScTab() ),
+ mbOwnTab( bOwnTab )
+{
+}
+
+void XclImpChartDrawing::ConvertObjects( XclImpDffConverter& rDffConv,
+ const Reference< XModel >& rxModel, const Rectangle& rChartRect )
+{
+ maChartRect = rChartRect; // needed in CalcAnchorRect() callback
+
+ SdrModel* pSdrModel = 0;
+ SdrPage* pSdrPage = 0;
+ if( mbOwnTab )
+ {
+ // chart sheet: insert all shapes into the sheet, not into the chart object
+ pSdrModel = GetDoc().GetDrawLayer();
+ pSdrPage = GetSdrPage( mnScTab );
+ }
+ else
+ {
+ // embedded chart object: insert all shapes into the chart
+ try
+ {
+ Reference< XDrawPageSupplier > xDrawPageSupp( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPage > xDrawPage( xDrawPageSupp->getDrawPage(), UNO_SET_THROW );
+ pSdrPage = ::GetSdrPageFromXDrawPage( xDrawPage );
+ pSdrModel = pSdrPage ? pSdrPage->GetModel() : 0;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ if( pSdrModel && pSdrPage )
+ ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
+}
+
+Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const
+{
+ /* In objects with DFF client anchor, the position of the shape is stored
+ in the cell address components of the client anchor. In old BIFF3-BIFF5
+ objects, the position is stored in the offset components of the anchor. */
+ Rectangle aRect(
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ),
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ) );
+ aRect.Justify();
+ // move shapes into chart area for sheet charts
+ if( mbOwnTab )
+ aRect.Move( maChartRect.Left(), maChartRect.Top() );
+ return aRect;
+}
+
+void XclImpChartDrawing::OnObjectInserted( const XclImpDrawObjBase& )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) :
+ XclImpRoot( rRoot ),
+ mbOwnTab( bOwnTab ),
+ mbIsPivotChart( false )
+{
+}
+
+XclImpChart::~XclImpChart()
+{
+}
+
+void XclImpChart::ReadChartSubStream( XclImpStream& rStrm )
+{
+ XclImpPageSettings& rPageSett = GetPageSettings();
+ XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
+
+ bool bLoop = true;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ // page settings - only for charts in entire sheet
+ if( mbOwnTab ) switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HORPAGEBREAKS:
+ case EXC_ID_VERPAGEBREAKS: rPageSett.ReadPageBreaks( rStrm ); break;
+ case EXC_ID_HEADER:
+ case EXC_ID_FOOTER: rPageSett.ReadHeaderFooter( rStrm ); break;
+ case EXC_ID_LEFTMARGIN:
+ case EXC_ID_RIGHTMARGIN:
+ case EXC_ID_TOPMARGIN:
+ case EXC_ID_BOTTOMMARGIN: rPageSett.ReadMargin( rStrm ); break;
+ case EXC_ID_PRINTHEADERS: rPageSett.ReadPrintHeaders( rStrm ); break;
+ case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( rStrm ); break;
+ case EXC_ID_HCENTER:
+ case EXC_ID_VCENTER: rPageSett.ReadCenter( rStrm ); break;
+ case EXC_ID_SETUP: rPageSett.ReadSetup( rStrm ); break;
+ case EXC_ID8_IMGDATA: rPageSett.ReadImgData( rStrm ); break;
+
+ case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( rStrm, true );break;
+ case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break;
+
+ case EXC_ID_SHEETEXT: //0x0862
+ {
+ // FIXME: do not need to pass palette, XclImpTabVieSettings is derived from root
+ XclImpPalette& rPal = GetPalette();
+ rTabViewSett.ReadTabBgColor( rStrm, rPal);
+ }
+ break;
+
+ case EXC_ID_CODENAME: ReadCodeName( rStrm, false ); break;
+ }
+
+ // common records
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_EOF: bLoop = false; break;
+
+ // #i31882# ignore embedded chart objects
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( rStrm ); break;
+
+ case EXC_ID_CHCHART: ReadChChart( rStrm ); break;
+
+ case EXC_ID8_CHPIVOTREF:
+ GetTracer().TracePivotChartExists();
+ mbIsPivotChart = true;
+ break;
+
+ // BIFF specific records
+ default: switch( GetBiff() )
+ {
+ case EXC_BIFF5: switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break;
+ }
+ break;
+ case EXC_BIFF8: switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_MSODRAWING: GetChartDrawing().ReadMsoDrawing( rStrm ); break;
+ // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
+ case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break;
+ }
+ break;
+ default:;
+ }
+ }
+ }
+}
+
+void XclImpChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
+{
+ if( !mxChartData )
+ mxChartData.reset( new XclImpChChart( GetRoot() ) );
+ mxChartData->UpdateObjFrame( rLineData, rFillData );
+}
+
+sal_Size XclImpChart::GetProgressSize() const
+{
+ return
+ (mxChartData.is() ? mxChartData->GetProgressSize() : 0) +
+ (mxChartDrawing.is() ? mxChartDrawing->GetProgressSize() : 0);
+}
+
+void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
+{
+ Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
+ if( xChartDoc.is() )
+ {
+ if( mxChartData.is() )
+ mxChartData->Convert( xChartDoc, rDffConv, rObjName, rChartRect );
+ if( mxChartDrawing.is() )
+ mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect );
+ }
+}
+
+XclImpChartDrawing& XclImpChart::GetChartDrawing()
+{
+ if( !mxChartDrawing )
+ mxChartDrawing.reset( new XclImpChartDrawing( GetRoot(), mbOwnTab ) );
+ return *mxChartDrawing;
+}
+
+void XclImpChart::ReadChChart( XclImpStream& rStrm )
+{
+ mxChartData.reset( new XclImpChChart( GetRoot() ) );
+ mxChartData->ReadRecordGroup( rStrm );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
new file mode 100644
index 000000000000..fb1eb9a3bf44
--- /dev/null
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -0,0 +1,1319 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xicontent.hxx"
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svl/itemset.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include "document.hxx"
+#include "editutil.hxx"
+#include "cell.hxx"
+#include "validat.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "rangenam.hxx"
+#include "arealink.hxx"
+#include "stlsheet.hxx"
+#include "scextopt.hxx"
+#include "xlformula.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xistyle.hxx"
+#include "xiescher.hxx"
+#include "xiname.hxx"
+
+#include "excform.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
+
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
+
+// Shared string table ========================================================
+
+XclImpSst::XclImpSst( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpSst::ReadSst( XclImpStream& rStrm )
+{
+ sal_uInt32 nStrCount;
+ rStrm.Ignore( 4 );
+ rStrm >> nStrCount;
+ maStrings.clear();
+ maStrings.reserve( static_cast< size_t >( nStrCount ) );
+ while( (nStrCount > 0) && rStrm.IsValid() )
+ {
+ XclImpString aString;
+ aString.Read( rStrm );
+ maStrings.push_back( aString );
+ --nStrCount;
+ }
+}
+
+const XclImpString* XclImpSst::GetString( sal_uInt32 nSstIndex ) const
+{
+ return (nSstIndex < maStrings.size()) ? &maStrings[ nSstIndex ] : 0;
+}
+
+ScBaseCell* XclImpSst::CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex ) const
+{
+ ScBaseCell* pCell = 0;
+ if( const XclImpString* pString = GetString( nSstIndex ) )
+ pCell = XclImpStringHelper::CreateCell( *this, *pString, nXFIndex );
+ return pCell;
+}
+
+// Hyperlinks =================================================================
+
+namespace {
+
+/** Reads character array and stores it into rString.
+ @param nChars Number of following characters (not byte count!).
+ @param b16Bit true = 16-bit characters, false = 8-bit characters. */
+void lclAppendString32( String& rString, XclImpStream& rStrm, sal_uInt32 nChars, bool b16Bit )
+{
+ sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
+ rString.Append( rStrm.ReadRawUniString( nReadChars, b16Bit ) );
+ // ignore remaining chars
+ sal_Size nIgnore = nChars - nReadChars;
+ if( b16Bit )
+ nIgnore *= 2;
+ rStrm.Ignore( nIgnore );
+}
+
+/** Reads 32-bit string length and the character array and stores it into rString.
+ @param b16Bit true = 16-bit characters, false = 8-bit characters. */
+void lclAppendString32( String& rString, XclImpStream& rStrm, bool b16Bit )
+{
+ lclAppendString32( rString, rStrm, rStrm.ReaduInt32(), b16Bit );
+}
+
+/** Reads 32-bit string length and ignores following character array.
+ @param b16Bit true = 16-bit characters, false = 8-bit characters. */
+void lclIgnoreString32( XclImpStream& rStrm, bool b16Bit )
+{
+ sal_uInt32 nChars;
+ rStrm >> nChars;
+ if( b16Bit )
+ nChars *= 2;
+ rStrm.Ignore( nChars );
+}
+
+/** Converts a path to an absolute path.
+ @param rPath The source path. The resulting path is returned here.
+ @param nLevel Number of parent directories to add in front of the path. */
+void lclGetAbsPath( String& rPath, sal_uInt16 nLevel, SfxObjectShell* pDocShell )
+{
+ String aTmpStr;
+ while( nLevel )
+ {
+ aTmpStr.AppendAscii( "../" );
+ --nLevel;
+ }
+ aTmpStr += rPath;
+
+ if( pDocShell )
+ {
+ bool bWasAbs = false;
+ rPath = pDocShell->GetMedium()->GetURLObject().smartRel2Abs( aTmpStr, bWasAbs ).GetMainURL( INetURLObject::NO_DECODE );
+ // full path as stored in SvxURLField must be encoded
+ }
+ else
+ rPath = aTmpStr;
+}
+
+/** Inserts the URL into a text cell. Does not modify value or formula cells. */
+void lclInsertUrl( const XclImpRoot& rRoot, const String& rUrl, SCCOL nScCol, SCROW nScRow, SCTAB nScTab )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ ScAddress aScPos( nScCol, nScRow, nScTab );
+ CellType eCellType = rDoc.GetCellType( aScPos );
+ switch( eCellType )
+ {
+ // #i54261# hyperlinks in string cells
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ String aDisplText;
+ rDoc.GetString( nScCol, nScRow, nScTab, aDisplText );
+ if( !aDisplText.Len() )
+ aDisplText = rUrl;
+
+ ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
+ SvxURLField aUrlField( rUrl, aDisplText, SVXURLFORMAT_APPDEFAULT );
+
+ const ScEditCell* pEditCell = (eCellType == CELLTYPE_EDIT) ? static_cast< const ScEditCell* >( rDoc.GetCell( aScPos ) ) : 0;
+ const EditTextObject* pEditObj = pEditCell ? pEditCell->GetData() : 0;
+ if( pEditObj )
+ {
+ rEE.SetText( *pEditObj );
+ rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection( 0, 0, 0xFFFF, 0 ) );
+ }
+ else
+ {
+ rEE.SetText( EMPTY_STRING );
+ rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection() );
+ if( const ScPatternAttr* pPattern = rDoc.GetPattern( aScPos.Col(), aScPos.Row(), nScTab ) )
+ {
+ SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
+ pPattern->FillEditItemSet( &aItemSet );
+ rEE.QuickSetAttribs( aItemSet, ESelection( 0, 0, 0xFFFF, 0 ) );
+ }
+ }
+ ::std::auto_ptr< EditTextObject > xTextObj( rEE.CreateTextObject() );
+
+ ScEditCell* pCell = new ScEditCell( xTextObj.get(), &rDoc, rEE.GetEditTextObjectPool() );
+ rDoc.PutCell( aScPos, pCell );
+ }
+ break;
+
+ // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#)
+#if 0
+ case CELLTYPE_VALUE:
+ {
+ // #i31050# replace number with HYPERLINK function
+ ScTokenArray aTokenArray;
+ aTokenArray.AddOpCode( ocHyperLink );
+ aTokenArray.AddOpCode( ocOpen );
+ aTokenArray.AddString( rUrl );
+ aTokenArray.AddOpCode( ocSep );
+ aTokenArray.AddDouble( rDoc.GetValue( aScPos ) );
+ aTokenArray.AddOpCode( ocClose );
+ rDoc.PutCell( aScPos, new ScFormulaCell( &rDoc, aScPos, &aTokenArray ) );
+ }
+ break;
+#endif
+
+ default:;
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+void XclImpHyperlink::ReadHlink( XclImpStream& rStrm )
+{
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ rStrm >> aXclRange;
+ // #i80006# Excel silently ignores invalid hi-byte of column index (TODO: everywhere?)
+ aXclRange.maFirst.mnCol &= 0xFF;
+ aXclRange.maLast.mnCol &= 0xFF;
+ String aString = ReadEmbeddedData( rStrm );
+ if ( aString.Len() > 0 )
+ rStrm.GetRoot().GetXFRangeBuffer().SetHyperlink( aXclRange, aString );
+}
+
+String XclImpHyperlink::ReadEmbeddedData( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ SfxObjectShell* pDocShell = rRoot.GetDocShell();
+
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ sal_uInt32 nFlags;
+ XclGuid aGuid;
+ rStrm >> aGuid;
+ rStrm.Ignore( 4 );
+ rStrm >> nFlags;
+
+ DBG_ASSERT( aGuid == XclTools::maGuidStdLink, "XclImpHyperlink::ReadEmbeddedData - unknown header GUID" );
+
+ sal_uInt16 nLevel = 0; // counter for level to climb down in path
+ ::std::auto_ptr< String > xLongName; // link / file name
+ ::std::auto_ptr< String > xShortName; // 8.3-representation of file name
+ ::std::auto_ptr< String > xTextMark; // text mark
+
+ // description (ignore)
+ if( ::get_flag( nFlags, EXC_HLINK_DESCR ) )
+ lclIgnoreString32( rStrm, true );
+ // target frame (ignore) !! DESCR/FRAME - is this the right order? (never seen them together)
+ if( ::get_flag( nFlags, EXC_HLINK_FRAME ) )
+ lclIgnoreString32( rStrm, true );
+
+ // URL fields are zero-terminated - do not let the stream replace them
+ // in the lclAppendString32() with the '?' character.
+ rStrm.SetNulSubstChar( '\0' );
+
+ // UNC path
+ if( ::get_flag( nFlags, EXC_HLINK_UNC ) )
+ {
+ xLongName.reset( new String );
+ lclAppendString32( *xLongName, rStrm, true );
+ lclGetAbsPath( *xLongName, 0, pDocShell );
+ }
+ // file link or URL
+ else if( ::get_flag( nFlags, EXC_HLINK_BODY ) )
+ {
+ rStrm >> aGuid;
+
+ if( aGuid == XclTools::maGuidFileMoniker )
+ {
+ rStrm >> nLevel;
+ xShortName.reset( new String );
+ lclAppendString32( *xShortName, rStrm, false );
+ rStrm.Ignore( 24 );
+
+ sal_uInt32 nStrLen;
+ rStrm >> nStrLen;
+ if( nStrLen )
+ {
+ rStrm >> nStrLen;
+ nStrLen /= 2; // it's byte count here...
+ rStrm.Ignore( 2 );
+ xLongName.reset( new String );
+ lclAppendString32( *xLongName, rStrm, nStrLen, true );
+ lclGetAbsPath( *xLongName, nLevel, pDocShell );
+ }
+ else
+ lclGetAbsPath( *xShortName, nLevel, pDocShell );
+ }
+ else if( aGuid == XclTools::maGuidUrlMoniker )
+ {
+ sal_uInt32 nStrLen;
+ rStrm >> nStrLen;
+ nStrLen /= 2; // it's byte count here...
+ xLongName.reset( new String );
+ lclAppendString32( *xLongName, rStrm, nStrLen, true );
+ if( !::get_flag( nFlags, EXC_HLINK_ABS ) )
+ lclGetAbsPath( *xLongName, 0, pDocShell );
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclImpHyperlink::ReadEmbeddedData - unknown content GUID" );
+ }
+ }
+
+ // text mark
+ if( ::get_flag( nFlags, EXC_HLINK_MARK ) )
+ {
+ xTextMark.reset( new String );
+ lclAppendString32( *xTextMark, rStrm, true );
+ }
+
+ rStrm.SetNulSubstChar(); // back to default
+
+ DBG_ASSERT( rStrm.GetRecLeft() == 0, "XclImpHyperlink::ReadEmbeddedData - record size mismatch" );
+
+ if( !xLongName.get() && xShortName.get() )
+ xLongName = xShortName;
+ else if( !xLongName.get() && xTextMark.get() )
+ xLongName.reset( new String );
+
+ if( xLongName.get() )
+ {
+ if( xTextMark.get() )
+ {
+ if( xLongName->Len() == 0 )
+ xTextMark->SearchAndReplaceAll( '!', '.' );
+ xLongName->Append( '#' );
+ xLongName->Append( *xTextMark );
+ }
+ return *xLongName;
+ }
+ return String::EmptyString();
+}
+
+void XclImpHyperlink::ConvertToValidTabName(String& rUrl)
+{
+ xub_StrLen n = rUrl.Len();
+ if (n < 4)
+ // Needs at least 4 characters.
+ return;
+
+ sal_Unicode c = rUrl.GetChar(0);
+ if (c != sal_Unicode('#'))
+ // the 1st character must be '#'.
+ return;
+
+ String aNewUrl(sal_Unicode('#')), aTabName;
+
+ bool bInQuote = false;
+ bool bQuoteTabName = false;
+ for (xub_StrLen i = 1; i < n; ++i)
+ {
+ c = rUrl.GetChar(i);
+ if (c == sal_Unicode('\''))
+ {
+ if (bInQuote && i+1 < n && rUrl.GetChar(i+1) == sal_Unicode('\''))
+ {
+ // Two consecutive single quotes ('') signify a single literal
+ // quite. When this occurs, the whole table name needs to be
+ // quoted.
+ bQuoteTabName = true;
+ aTabName.Append(c);
+ aTabName.Append(c);
+ ++i;
+ continue;
+ }
+
+ bInQuote = !bInQuote;
+ if (!bInQuote && aTabName.Len() > 0)
+ {
+ if (bQuoteTabName)
+ aNewUrl.Append(sal_Unicode('\''));
+ aNewUrl.Append(aTabName);
+ if (bQuoteTabName)
+ aNewUrl.Append(sal_Unicode('\''));
+ }
+ }
+ else if (bInQuote)
+ aTabName.Append(c);
+ else
+ aNewUrl.Append(c);
+ }
+
+ if (bInQuote)
+ // It should be outside the quotes!
+ return;
+
+ // All is good. Pass the new URL.
+ rUrl = aNewUrl;
+}
+
+void XclImpHyperlink::InsertUrl( const XclImpRoot& rRoot, const XclRange& rXclRange, const String& rUrl )
+{
+ String aUrl(rUrl);
+ ConvertToValidTabName(aUrl);
+
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ ScRange aScRange( ScAddress::UNINITIALIZED );
+ if( rRoot.GetAddressConverter().ConvertRange( aScRange, rXclRange, nScTab, nScTab, true ) )
+ {
+ SCCOL nScCol1, nScCol2;
+ SCROW nScRow1, nScRow2;
+ aScRange.GetVars( nScCol1, nScRow1, nScTab, nScCol2, nScRow2, nScTab );
+ for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
+ for( SCROW nScRow = nScRow1; nScRow <= nScRow2; ++nScRow )
+ lclInsertUrl( rRoot, aUrl, nScCol, nScRow, nScTab );
+ }
+}
+
+// Label ranges ===============================================================
+
+void XclImpLabelranges::ReadLabelranges( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ ScDocument& rDoc = rRoot.GetDoc();
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ XclImpAddressConverter& rAddrConv = rRoot.GetAddressConverter();
+ ScRangePairListRef xLabelRangesRef;
+ const ScRange* pScRange = 0;
+
+ XclRangeList aRowXclRanges, aColXclRanges;
+ rStrm >> aRowXclRanges >> aColXclRanges;
+
+ // row label ranges
+ ScRangeList aRowScRanges;
+ rAddrConv.ConvertRangeList( aRowScRanges, aRowXclRanges, nScTab, false );
+ xLabelRangesRef = rDoc.GetRowNameRangesRef();
+ for( pScRange = aRowScRanges.First(); pScRange; pScRange = aRowScRanges.Next() )
+ {
+ ScRange aDataRange( *pScRange );
+ if( aDataRange.aEnd.Col() < MAXCOL )
+ {
+ aDataRange.aStart.SetCol( aDataRange.aEnd.Col() + 1 );
+ aDataRange.aEnd.SetCol( MAXCOL );
+ }
+ else if( aDataRange.aStart.Col() > 0 )
+ {
+ aDataRange.aEnd.SetCol( aDataRange.aStart.Col() - 1 );
+ aDataRange.aStart.SetCol( 0 );
+ }
+ xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
+ }
+
+ // column label ranges
+ ScRangeList aColScRanges;
+ rAddrConv.ConvertRangeList( aColScRanges, aColXclRanges, nScTab, false );
+ xLabelRangesRef = rDoc.GetColNameRangesRef();
+ for( pScRange = aColScRanges.First(); pScRange; pScRange = aColScRanges.Next() )
+ {
+ ScRange aDataRange( *pScRange );
+ if( aDataRange.aEnd.Row() < MAXROW )
+ {
+ aDataRange.aStart.SetRow( aDataRange.aEnd.Row() + 1 );
+ aDataRange.aEnd.SetRow( MAXROW );
+ }
+ else if( aDataRange.aStart.Row() > 0 )
+ {
+ aDataRange.aEnd.SetRow( aDataRange.aStart.Row() - 1 );
+ aDataRange.aStart.SetRow( 0 );
+ }
+ xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
+ }
+}
+
+// Conditional formatting =====================================================
+
+XclImpCondFormat::XclImpCondFormat( const XclImpRoot& rRoot, sal_uInt32 nFormatIndex ) :
+ XclImpRoot( rRoot ),
+ mnFormatIndex( nFormatIndex ),
+ mnCondCount( 0 ),
+ mnCondIndex( 0 )
+{
+}
+
+XclImpCondFormat::~XclImpCondFormat()
+{
+}
+
+void XclImpCondFormat::ReadCondfmt( XclImpStream& rStrm )
+{
+ DBG_ASSERT( !mnCondCount, "XclImpCondFormat::ReadCondfmt - already initialized" );
+ XclRangeList aXclRanges;
+ rStrm >> mnCondCount;
+ rStrm.Ignore( 10 );
+ rStrm >> aXclRanges;
+ GetAddressConverter().ConvertRangeList( maRanges, aXclRanges, GetCurrScTab(), true );
+}
+
+void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
+{
+ if( mnCondIndex >= mnCondCount )
+ {
+ DBG_ERRORFILE( "XclImpCondFormat::ReadCF - CF without leading CONDFMT" );
+ return;
+ }
+
+ // entire conditional format outside of valid range?
+ if( !maRanges.Count() )
+ return;
+
+ sal_uInt8 nType, nOperator;
+ sal_uInt16 nFmlaSize1, nFmlaSize2;
+ sal_uInt32 nFlags;
+
+ rStrm >> nType >> nOperator >> nFmlaSize1 >> nFmlaSize2 >> nFlags;
+ rStrm.Ignore( 2 );
+
+ // *** mode and comparison operator ***
+
+ ScConditionMode eMode = SC_COND_NONE;
+ switch( nType )
+ {
+ case EXC_CF_TYPE_CELL:
+ {
+ switch( nOperator )
+ {
+ case EXC_CF_CMP_BETWEEN: eMode = SC_COND_BETWEEN; break;
+ case EXC_CF_CMP_NOT_BETWEEN: eMode = SC_COND_NOTBETWEEN; break;
+ case EXC_CF_CMP_EQUAL: eMode = SC_COND_EQUAL; break;
+ case EXC_CF_CMP_NOT_EQUAL: eMode = SC_COND_NOTEQUAL; break;
+ case EXC_CF_CMP_GREATER: eMode = SC_COND_GREATER; break;
+ case EXC_CF_CMP_LESS: eMode = SC_COND_LESS; break;
+ case EXC_CF_CMP_GREATER_EQUAL: eMode = SC_COND_EQGREATER; break;
+ case EXC_CF_CMP_LESS_EQUAL: eMode = SC_COND_EQLESS; break;
+ default:
+ DBG_ERROR1( "XclImpCondFormat::ReadCF - unknown CF comparison 0x%02hX", nOperator );
+ }
+ }
+ break;
+
+ case EXC_CF_TYPE_FMLA:
+ eMode = SC_COND_DIRECT;
+ break;
+
+ default:
+ DBG_ERROR1( "XclImpCondFormat::ReadCF - unknown CF mode 0x%02hX", nType );
+ return;
+ }
+
+ // *** create style sheet ***
+
+ String aStyleName( XclTools::GetCondFormatStyleName( GetCurrScTab(), mnFormatIndex, mnCondIndex ) );
+ SfxItemSet& rStyleItemSet = ScfTools::MakeCellStyleSheet( GetStyleSheetPool(), aStyleName, true ).GetItemSet();
+
+ const XclImpPalette& rPalette = GetPalette();
+
+ // *** font block ***
+
+ if( ::get_flag( nFlags, EXC_CF_BLOCK_FONT ) )
+ {
+ XclImpFont aFont( GetRoot() );
+ aFont.ReadCFFontBlock( rStrm );
+ aFont.FillToItemSet( rStyleItemSet, EXC_FONTITEM_CELL );
+ }
+
+ // *** border block ***
+
+ if( ::get_flag( nFlags, EXC_CF_BLOCK_BORDER ) )
+ {
+ sal_uInt16 nLineStyle;
+ sal_uInt32 nLineColor;
+ rStrm >> nLineStyle >> nLineColor;
+ rStrm.Ignore( 2 );
+
+ XclImpCellBorder aBorder;
+ aBorder.FillFromCF8( nLineStyle, nLineColor, nFlags );
+ aBorder.FillToItemSet( rStyleItemSet, rPalette );
+ }
+
+ // *** pattern block ***
+
+ if( ::get_flag( nFlags, EXC_CF_BLOCK_AREA ) )
+ {
+ sal_uInt16 nPattern, nColor;
+ rStrm >> nPattern >> nColor;
+
+ XclImpCellArea aArea;
+ aArea.FillFromCF8( nPattern, nColor, nFlags );
+ aArea.FillToItemSet( rStyleItemSet, rPalette );
+ }
+
+ // *** formulas ***
+
+ const ScAddress& rPos = maRanges.GetObject( 0 )->aStart; // assured above that maRanges is not empty
+ ExcelToSc& rFmlaConv = GetOldFmlaConverter();
+
+ ::std::auto_ptr< ScTokenArray > xTokArr1;
+ if( nFmlaSize1 > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset( rPos );
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ xTokArr1.reset( pTokArr->Clone() );
+ }
+
+ ::std::auto_ptr< ScTokenArray > pTokArr2;
+ if( nFmlaSize2 > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset( rPos );
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ pTokArr2.reset( pTokArr->Clone() );
+ }
+
+ // *** create the Calc conditional formatting ***
+
+ if( !mxScCondFmt.get() )
+ {
+ ULONG nKey = 0;
+ mxScCondFmt.reset( new ScConditionalFormat( nKey, GetDocPtr() ) );
+ }
+
+ ScCondFormatEntry aEntry( eMode, xTokArr1.get(), pTokArr2.get(), GetDocPtr(), rPos, aStyleName );
+ mxScCondFmt->AddEntry( aEntry );
+ ++mnCondIndex;
+}
+
+void XclImpCondFormat::Apply()
+{
+ if( mxScCondFmt.get() )
+ {
+ ScDocument& rDoc = GetDoc();
+
+ ULONG nKey = rDoc.AddCondFormat( *mxScCondFmt );
+ ScPatternAttr aPattern( rDoc.GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nKey ) );
+
+ // maRanges contains only valid cell ranges
+ for( const ScRange* pScRange = maRanges.First(); pScRange; pScRange = maRanges.Next() )
+ {
+ rDoc.ApplyPatternAreaTab(
+ pScRange->aStart.Col(), pScRange->aStart.Row(),
+ pScRange->aEnd.Col(), pScRange->aEnd.Row(),
+ pScRange->aStart.Tab(), aPattern );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCondFormatManager::XclImpCondFormatManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpCondFormatManager::ReadCondfmt( XclImpStream& rStrm )
+{
+ XclImpCondFormat* pFmt = new XclImpCondFormat( GetRoot(), maCondFmtList.Count() );
+ pFmt->ReadCondfmt( rStrm );
+ maCondFmtList.Append( pFmt );
+}
+
+void XclImpCondFormatManager::ReadCF( XclImpStream& rStrm )
+{
+ DBG_ASSERT( !maCondFmtList.Empty(), "XclImpCondFormatManager::ReadCF - CF without leading CONDFMT" );
+ if( !maCondFmtList.Empty() )
+ maCondFmtList.GetObject( maCondFmtList.Count() - 1 )->ReadCF( rStrm );
+}
+
+void XclImpCondFormatManager::Apply()
+{
+ for( XclImpCondFormat* pFmt = maCondFmtList.First(); pFmt; pFmt = maCondFmtList.Next() )
+ pFmt->Apply();
+ maCondFmtList.Clear();
+}
+
+// Data Validation ============================================================
+
+void XclImpValidation::ReadDval( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ sal_uInt32 nObjId;
+ rStrm.Ignore( 10 );
+ rStrm >> nObjId;
+ if( nObjId != EXC_DVAL_NOOBJ )
+ {
+ DBG_ASSERT( nObjId <= 0xFFFF, "XclImpValidation::ReadDval - invalid object ID" );
+ rRoot.GetCurrSheetDrawing().SetSkipObj( static_cast< sal_uInt16 >( nObjId ) );
+ }
+}
+
+void XclImpValidation::ReadDV( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ ScDocument& rDoc = rRoot.GetDoc();
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ ExcelToSc& rFmlaConv = rRoot.GetOldFmlaConverter();
+
+ // flags
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+
+ // message strings
+ /* Empty strings are single NUL characters in Excel (string length is 1).
+ -> Do not let the stream replace them with '?' characters. */
+ rStrm.SetNulSubstChar( '\0' );
+ String aPromptTitle( rStrm.ReadUniString() );
+ String aErrorTitle( rStrm.ReadUniString() );
+ String aPromptMessage( rStrm.ReadUniString() );
+ String aErrorMessage( rStrm.ReadUniString() );
+ rStrm.SetNulSubstChar(); // back to default
+
+ // formula(s)
+ if( rStrm.GetRecLeft() > 8 )
+ {
+ sal_uInt16 nLen;
+
+ // first formula
+ // string list is single tStr token with NUL separators -> replace them with LF
+ rStrm.SetNulSubstChar( '\n' );
+ ::std::auto_ptr< ScTokenArray > xTokArr1;
+ rStrm >> nLen;
+ rStrm.Ignore( 2 );
+ if( nLen > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset();
+ rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ xTokArr1.reset( pTokArr->Clone() );
+ }
+ rStrm.SetNulSubstChar(); // back to default
+
+ // second formula
+ ::std::auto_ptr< ScTokenArray > xTokArr2;
+ rStrm >> nLen;
+ rStrm.Ignore( 2 );
+ if( nLen > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset();
+ rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ xTokArr2.reset( pTokArr->Clone() );
+ }
+
+ // read all cell ranges
+ XclRangeList aXclRanges;
+ rStrm >> aXclRanges;
+
+ // convert to Calc range list
+ ScRangeList aScRanges;
+ rRoot.GetAddressConverter().ConvertRangeList( aScRanges, aXclRanges, nScTab, true );
+
+ // only continue if there are valid ranges
+ if( aScRanges.Count() )
+ {
+ bool bIsValid = true; // valid settings in flags field
+
+ ScValidationMode eValMode = SC_VALID_ANY;
+ switch( nFlags & EXC_DV_MODE_MASK )
+ {
+ case EXC_DV_MODE_ANY: eValMode = SC_VALID_ANY; break;
+ case EXC_DV_MODE_WHOLE: eValMode = SC_VALID_WHOLE; break;
+ case EXC_DV_MODE_DECIMAL: eValMode = SC_VALID_DECIMAL; break;
+ case EXC_DV_MODE_LIST: eValMode = SC_VALID_LIST; break;
+ case EXC_DV_MODE_DATE: eValMode = SC_VALID_DATE; break;
+ case EXC_DV_MODE_TIME: eValMode = SC_VALID_TIME; break;
+ case EXC_DV_MODE_TEXTLEN: eValMode = SC_VALID_TEXTLEN; break;
+ case EXC_DV_MODE_CUSTOM: eValMode = SC_VALID_CUSTOM; break;
+ default: bIsValid = false;
+ }
+ rRoot.GetTracer().TraceDVType(eValMode == SC_VALID_CUSTOM);
+
+ ScConditionMode eCondMode = SC_COND_BETWEEN;
+ switch( nFlags & EXC_DV_COND_MASK )
+ {
+ case EXC_DV_COND_BETWEEN: eCondMode = SC_COND_BETWEEN; break;
+ case EXC_DV_COND_NOTBETWEEN:eCondMode = SC_COND_NOTBETWEEN; break;
+ case EXC_DV_COND_EQUAL: eCondMode = SC_COND_EQUAL; break;
+ case EXC_DV_COND_NOTEQUAL: eCondMode = SC_COND_NOTEQUAL; break;
+ case EXC_DV_COND_GREATER: eCondMode = SC_COND_GREATER; break;
+ case EXC_DV_COND_LESS: eCondMode = SC_COND_LESS; break;
+ case EXC_DV_COND_EQGREATER: eCondMode = SC_COND_EQGREATER; break;
+ case EXC_DV_COND_EQLESS: eCondMode = SC_COND_EQLESS; break;
+ default: bIsValid = false;
+ }
+
+ if( bIsValid )
+ {
+ // first range for base address for relative references
+ const ScRange& rScRange = *aScRanges.GetObject( 0 ); // aScRanges is not empty
+
+ // process string list of a list validity (convert to list of string tokens)
+ if( xTokArr1.get() && (eValMode == SC_VALID_LIST) && ::get_flag( nFlags, EXC_DV_STRINGLIST ) )
+ XclTokenArrayHelper::ConvertStringToList( *xTokArr1, '\n', true );
+
+ ScValidationData aValidData( eValMode, eCondMode, xTokArr1.get(), xTokArr2.get(), &rDoc, rScRange.aStart );
+
+ aValidData.SetIgnoreBlank( ::get_flag( nFlags, EXC_DV_IGNOREBLANK ) );
+ aValidData.SetListType( ::get_flagvalue( nFlags, EXC_DV_SUPPRESSDROPDOWN, ValidListType::INVISIBLE, ValidListType::UNSORTED ) );
+
+ // *** prompt box ***
+ if( aPromptTitle.Len() || aPromptMessage.Len() )
+ {
+ // set any text stored in the record
+ aValidData.SetInput( aPromptTitle, aPromptMessage );
+ if( !::get_flag( nFlags, EXC_DV_SHOWPROMPT ) )
+ aValidData.ResetInput();
+ }
+
+ // *** error box ***
+ ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
+ switch( nFlags & EXC_DV_ERROR_MASK )
+ {
+ case EXC_DV_ERROR_WARNING: eErrStyle = SC_VALERR_WARNING; break;
+ case EXC_DV_ERROR_INFO: eErrStyle = SC_VALERR_INFO; break;
+ }
+ // set texts and error style
+ aValidData.SetError( aErrorTitle, aErrorMessage, eErrStyle );
+ if( !::get_flag( nFlags, EXC_DV_SHOWERROR ) )
+ aValidData.ResetError();
+
+ // set the handle ID
+ ULONG nHandle = rDoc.AddValidationEntry( aValidData );
+ ScPatternAttr aPattern( rDoc.GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nHandle ) );
+
+ // apply all ranges
+ for( const ScRange* pScRange = aScRanges.First(); pScRange; pScRange = aScRanges.Next() )
+ rDoc.ApplyPatternAreaTab( pScRange->aStart.Col(), pScRange->aStart.Row(),
+ pScRange->aEnd.Col(), pScRange->aEnd.Row(), nScTab, aPattern );
+ }
+ }
+ }
+}
+
+// Web queries ================================================================
+
+XclImpWebQuery::XclImpWebQuery( const ScRange& rDestRange ) :
+ maDestRange( rDestRange ),
+ meMode( xlWQUnknown ),
+ mnRefresh( 0 )
+{
+}
+
+void XclImpWebQuery::ReadParamqry( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags = rStrm.ReaduInt16();
+ sal_uInt16 nType = ::extract_value< sal_uInt16 >( nFlags, 0, 3 );
+ if( (nType == EXC_PQRYTYPE_WEBQUERY) && ::get_flag( nFlags, EXC_PQRY_WEBQUERY ) )
+ {
+ if( ::get_flag( nFlags, EXC_PQRY_TABLES ) )
+ {
+ meMode = xlWQAllTables;
+ maTables = ScfTools::GetHTMLTablesName();
+ }
+ else
+ {
+ meMode = xlWQDocument;
+ maTables = ScfTools::GetHTMLDocName();
+ }
+ }
+}
+
+void XclImpWebQuery::ReadWqstring( XclImpStream& rStrm )
+{
+ maURL = rStrm.ReadUniString();
+}
+
+void XclImpWebQuery::ReadWqsettings( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> nFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> mnRefresh;
+
+ if( ::get_flag( nFlags, EXC_WQSETT_SPECTABLES ) && (meMode == xlWQAllTables) )
+ meMode = xlWQSpecTables;
+}
+
+void XclImpWebQuery::ReadWqtables( XclImpStream& rStrm )
+{
+ if( meMode == xlWQSpecTables )
+ {
+ rStrm.Ignore( 4 );
+ String aTables( rStrm.ReadUniString() );
+
+ const sal_Unicode cSep = ';';
+ aTables.SearchAndReplaceAll( ',', cSep );
+ String aQuotedPairs( RTL_CONSTASCII_USTRINGPARAM( "\"\"" ) );
+ xub_StrLen nTokenCnt = aTables.GetQuotedTokenCount( aQuotedPairs, cSep );
+ maTables.Erase();
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( aTables.GetQuotedToken( 0, aQuotedPairs, cSep, nStringIx ) );
+ sal_Int32 nTabNum = CharClass::isAsciiNumeric( aToken ) ? aToken.ToInt32() : 0;
+ if( nTabNum > 0 )
+ ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLIndex( static_cast< sal_uInt32 >( nTabNum ) ), cSep );
+ else
+ {
+ ScGlobal::EraseQuotes( aToken, '"', false );
+ if( aToken.Len() )
+ ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLName( aToken ), cSep );
+ }
+ }
+ }
+}
+
+void XclImpWebQuery::Apply( ScDocument& rDoc, const String& rFilterName )
+{
+ if( maURL.Len() && (meMode != xlWQUnknown) && rDoc.GetDocumentShell() )
+ {
+ ScAreaLink* pLink = new ScAreaLink( rDoc.GetDocumentShell(),
+ maURL, rFilterName, EMPTY_STRING, maTables, maDestRange, mnRefresh * 60UL );
+ rDoc.GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE,
+ maURL, &rFilterName, &maTables );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpWebQueryBuffer::XclImpWebQueryBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpWebQueryBuffer::ReadQsi( XclImpStream& rStrm )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ rStrm.Ignore( 10 );
+ String aXclName( rStrm.ReadUniString() );
+
+ // #i64794# Excel replaces spaces with underscores
+ aXclName.SearchAndReplaceAll( ' ', '_' );
+
+ // #101529# find the defined name used in Calc
+ if( const XclImpName* pName = GetNameManager().FindName( aXclName, GetCurrScTab() ) )
+ {
+ if( const ScRangeData* pRangeData = pName->GetScRangeData() )
+ {
+ ScRange aRange;
+ if( pRangeData->IsReference( aRange ) )
+ maWQList.Append( new XclImpWebQuery( aRange ) );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR_BIFF();
+ }
+}
+
+void XclImpWebQueryBuffer::ReadParamqry( XclImpStream& rStrm )
+{
+ if( XclImpWebQuery* pQuery = maWQList.Last() )
+ pQuery->ReadParamqry( rStrm );
+}
+
+void XclImpWebQueryBuffer::ReadWqstring( XclImpStream& rStrm )
+{
+ if( XclImpWebQuery* pQuery = maWQList.Last() )
+ pQuery->ReadWqstring( rStrm );
+}
+
+void XclImpWebQueryBuffer::ReadWqsettings( XclImpStream& rStrm )
+{
+ if( XclImpWebQuery* pQuery = maWQList.Last() )
+ pQuery->ReadWqsettings( rStrm );
+}
+
+void XclImpWebQueryBuffer::ReadWqtables( XclImpStream& rStrm )
+{
+ if( XclImpWebQuery* pQuery = maWQList.Last() )
+ pQuery->ReadWqtables( rStrm );
+}
+
+void XclImpWebQueryBuffer::Apply()
+{
+ ScDocument& rDoc = GetDoc();
+ String aFilterName( RTL_CONSTASCII_USTRINGPARAM( EXC_WEBQRY_FILTER ) );
+ for( XclImpWebQuery* pQuery = maWQList.First(); pQuery; pQuery = maWQList.Next() )
+ pQuery->Apply( rDoc, aFilterName );
+}
+
+// Decryption =================================================================
+
+namespace {
+
+XclImpDecrypterRef lclReadFilepass5( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+ DBG_ASSERT( rStrm.GetRecLeft() == 4, "lclReadFilepass5 - wrong record size" );
+ if( rStrm.GetRecLeft() == 4 )
+ {
+ sal_uInt16 nKey, nHash;
+ rStrm >> nKey >> nHash;
+ xDecr.reset( new XclImpBiff5Decrypter( nKey, nHash ) );
+ }
+ return xDecr;
+}
+
+XclImpDecrypterRef lclReadFilepass8_Standard( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+ DBG_ASSERT( rStrm.GetRecLeft() == 48, "lclReadFilepass8 - wrong record size" );
+ if( rStrm.GetRecLeft() == 48 )
+ {
+ sal_uInt8 pnSalt[ 16 ];
+ sal_uInt8 pnVerifier[ 16 ];
+ sal_uInt8 pnVerifierHash[ 16 ];
+ rStrm.Read( pnSalt, 16 );
+ rStrm.Read( pnVerifier, 16 );
+ rStrm.Read( pnVerifierHash, 16 );
+ xDecr.reset( new XclImpBiff8Decrypter( pnSalt, pnVerifier, pnVerifierHash ) );
+ }
+ return xDecr;
+}
+
+XclImpDecrypterRef lclReadFilepass8_Strong( XclImpStream& /*rStrm*/ )
+{
+ // not supported
+ return XclImpDecrypterRef();
+}
+
+XclImpDecrypterRef lclReadFilepass8( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+
+ sal_uInt16 nMode;
+ rStrm >> nMode;
+ switch( nMode )
+ {
+ case EXC_FILEPASS_BIFF5:
+ xDecr = lclReadFilepass5( rStrm );
+ break;
+
+ case EXC_FILEPASS_BIFF8:
+ {
+ rStrm.Ignore( 2 );
+ sal_uInt16 nSubMode;
+ rStrm >> nSubMode;
+ switch( nSubMode )
+ {
+ case EXC_FILEPASS_BIFF8_STD:
+ xDecr = lclReadFilepass8_Standard( rStrm );
+ break;
+ case EXC_FILEPASS_BIFF8_STRONG:
+ xDecr = lclReadFilepass8_Strong( rStrm );
+ break;
+ default:
+ DBG_ERRORFILE( "lclReadFilepass8 - unknown BIFF8 encryption sub mode" );
+ }
+ }
+ break;
+
+ default:
+ DBG_ERRORFILE( "lclReadFilepass8 - unknown encryption mode" );
+ }
+
+ return xDecr;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+ rStrm.DisableDecryption();
+
+ // read the FILEPASS record and create a new decrypter object
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5: xDecr = lclReadFilepass5( rStrm ); break;
+ case EXC_BIFF8: xDecr = lclReadFilepass8( rStrm ); break;
+ default: DBG_ERROR_BIFF();
+ };
+
+ // set decrypter at import stream
+ rStrm.SetDecrypter( xDecr );
+
+ // request and verify a password (decrypter implements IDocPasswordVerifier)
+ if( xDecr.is() )
+ rStrm.GetRoot().RequestPassword( *xDecr );
+
+ // return error code (success, wrong password, etc.)
+ return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
+}
+
+// Document protection ========================================================
+
+XclImpDocProtectBuffer::XclImpDocProtectBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnPassHash(0x0000),
+ mbDocProtect(false),
+ mbWinProtect(false)
+{
+}
+
+void XclImpDocProtectBuffer::ReadDocProtect( XclImpStream& rStrm )
+{
+ mbDocProtect = rStrm.ReaduInt16() ? true : false;
+}
+
+void XclImpDocProtectBuffer::ReadWinProtect( XclImpStream& rStrm )
+{
+ mbWinProtect = rStrm.ReaduInt16() ? true : false;
+}
+
+void XclImpDocProtectBuffer::ReadPasswordHash( XclImpStream& rStrm )
+{
+ rStrm.EnableDecryption();
+ mnPassHash = rStrm.ReaduInt16();
+}
+
+void XclImpDocProtectBuffer::Apply() const
+{
+ if (!mbDocProtect && !mbWinProtect)
+ // Excel requires either the structure or windows protection is set.
+ // If neither is set then the document is not protected at all.
+ return;
+
+ auto_ptr<ScDocProtection> pProtect(new ScDocProtection);
+ pProtect->setProtected(true);
+
+#if 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(12);
+
+ // feature type can be either 2 or 4. If 2, this record stores flag for
+ // enhanced protection, whereas if 4 it stores flag for smart tag.
+ sal_uInt16 nFeatureType;
+ rStrm >> nFeatureType;
+ if (nFeatureType != 2)
+ // We currently only support import of enhanced protection data.
+ return;
+
+ rStrm.Ignore(1); // always 1
+
+ // The flag size specifies the size of bytes that follows that stores
+ // feature data. If -1 it depends on the feature type imported earlier.
+ // For enhanced protection data, the size is always 4. For the most xls
+ // documents out there this value is almost always -1.
+ sal_Int32 nFlagSize;
+ rStrm >> nFlagSize;
+ if (nFlagSize != -1)
+ return;
+
+ // There are actually 4 bytes to read, but the upper 2 bytes currently
+ // don't store any bits.
+ sal_uInt16 nOptions;
+ rStrm >> nOptions;
+
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mnOptions = nOptions;
+}
+
+void XclImpSheetProtectBuffer::ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab )
+{
+ sal_uInt16 nHash;
+ rStrm >> nHash;
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mnPasswordHash = nHash;
+}
+
+void XclImpSheetProtectBuffer::Apply() const
+{
+ for (ProtectedSheetMap::const_iterator itr = maProtectedSheets.begin(), itrEnd = maProtectedSheets.end();
+ itr != itrEnd; ++itr)
+ {
+ if (!itr->second.mbProtected)
+ // This sheet is (for whatever reason) not protected.
+ continue;
+
+ auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
+ pProtect->setProtected(true);
+
+#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
new file mode 100644
index 000000000000..8d09cae60941
--- /dev/null
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -0,0 +1,4120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xiescher.hxx"
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/awt/PushButtonType.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/awt/VisualEffect.hpp>
+#include <com/sun/star/style/HorizontalAlignment.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+
+#include <rtl/logfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <svtools/wmf.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/classids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#include <svx/svdopath.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/svditer.hxx>
+#include <editeng/writingmodeitem.hxx>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/colritem.hxx>
+#include <svx/xflclit.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/xlineit.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xbtmpit.hxx>
+
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "chartarr.hxx"
+#include "detfunc.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "postit.hxx"
+#include "globstr.hrc"
+
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xiformula.hxx"
+#include "xilink.hxx"
+#include "xistyle.hxx"
+#include "xipage.hxx"
+#include "xichart.hxx"
+#include "xicontent.hxx"
+#include "namebuff.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::container::XIndexContainer;
+using ::com::sun::star::container::XNameContainer;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::embed::XEmbeddedObject;
+using ::com::sun::star::embed::XEmbedPersist;
+using ::com::sun::star::drawing::XControlShape;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::form::XForm;
+using ::com::sun::star::form::XFormComponent;
+using ::com::sun::star::form::XFormsSupplier;
+using ::com::sun::star::form::binding::XBindableValue;
+using ::com::sun::star::form::binding::XValueBinding;
+using ::com::sun::star::form::binding::XListEntrySink;
+using ::com::sun::star::form::binding::XListEntrySource;
+using ::com::sun::star::script::ScriptEventDescriptor;
+using ::com::sun::star::script::XEventAttacherManager;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+
+// ============================================================================
+
+namespace {
+
+/** Helper class which mimics the auto_ptr< SdrObject > semantics, but calls
+ SdrObject::Free instead of deleting the SdrObject directly. */
+template< typename SdrObjType >
+class TSdrObjectPtr
+{
+public:
+ inline explicit TSdrObjectPtr( SdrObjType* pObj = 0 ) : mpObj( pObj ) {}
+ inline ~TSdrObjectPtr() { free(); }
+
+ inline const SdrObjType* operator->() const { return mpObj; }
+ inline SdrObjType* operator->() { return mpObj; }
+
+ inline const SdrObjType* get() const { return mpObj; }
+ inline SdrObjType* get() { return mpObj; }
+
+ inline const SdrObjType& operator*() const { return *mpObj; }
+ inline SdrObjType& operator*() { return *mpObj; }
+
+ inline bool is() const { return mpObj != 0; }
+ inline bool operator!() const { return mpObj == 0; }
+
+ inline void reset( SdrObjType* pObj = 0 ) { free(); mpObj = pObj; }
+ inline SdrObjType* release() { SdrObjType* pObj = mpObj; mpObj = 0; return pObj; }
+
+private:
+ TSdrObjectPtr( const TSdrObjectPtr& ); // not implemented
+ TSdrObjectPtr& operator=( TSdrObjectPtr& rxObj ); // not implemented
+
+ inline void free() { SdrObject* pObj = mpObj; mpObj = 0; SdrObject::Free( pObj ); }
+
+private:
+ SdrObjType* mpObj;
+};
+
+typedef TSdrObjectPtr< SdrObject > SdrObjectPtr;
+
+} // namespace
+
+// Drawing objects ============================================================
+
+XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnObjId( EXC_OBJ_INVALID_ID ),
+ mnObjType( EXC_OBJTYPE_UNKNOWN ),
+ mnDffShapeId( 0 ),
+ mnDffFlags( 0 ),
+ mbHasAnchor( false ),
+ mbHidden( false ),
+ mbVisible( true ),
+ mbPrintable( true ),
+ mbAreaObj( false ),
+ mbAutoMargin( true ),
+ mbSimpleMacro( true ),
+ mbProcessSdr( true ),
+ mbInsertSdr( true ),
+ mbCustomDff( false )
+{
+}
+
+XclImpDrawObjBase::~XclImpDrawObjBase()
+{
+}
+
+/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 30 )
+ {
+ sal_uInt16 nObjType;
+ rStrm.Ignore( 4 );
+ rStrm >> nObjType;
+ switch( nObjType )
+ {
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
+ case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
+ case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ default:
+ DBG_ERROR1( "XclImpDrawObjBase::ReadObj3 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+
+ xDrawObj->ImplReadObj3( rStrm );
+ return xDrawObj;
+}
+
+/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 30 )
+ {
+ sal_uInt16 nObjType;
+ rStrm.Ignore( 4 );
+ rStrm >> nObjType;
+ switch( nObjType )
+ {
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
+ case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
+ case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break;
+ default:
+ DBG_ERROR1( "XclImpDrawObjBase::ReadObj4 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+
+ xDrawObj->ImplReadObj4( rStrm );
+ return xDrawObj;
+}
+
+/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 34 )
+ {
+ sal_uInt16 nObjType;
+ rStrm.Ignore( 4 );
+ rStrm >> nObjType;
+ switch( nObjType )
+ {
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
+ case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
+ case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break;
+ default:
+ DBG_ERROR1( "XclImpDrawObjBase::ReadObj5 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+
+ xDrawObj->ImplReadObj5( rStrm );
+ return xDrawObj;
+}
+
+/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 10 )
+ {
+ sal_uInt16 nSubRecId, nSubRecSize, nObjType;
+ rStrm >> nSubRecId >> nSubRecSize >> nObjType;
+ DBG_ASSERT( nSubRecId == EXC_ID_OBJCMO, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" );
+ if( (nSubRecId == EXC_ID_OBJCMO) && (nSubRecSize >= 6) )
+ {
+ switch( nObjType )
+ {
+ // in BIFF8, all simple objects support text
+ case EXC_OBJTYPE_LINE:
+ case EXC_OBJTYPE_ARC:
+ xDrawObj.reset( new XclImpTextObj( rRoot ) );
+ // lines and arcs may be 2-dimensional
+ xDrawObj->SetAreaObj( false );
+ break;
+
+ // in BIFF8, all simple objects support text
+ case EXC_OBJTYPE_RECTANGLE:
+ case EXC_OBJTYPE_OVAL:
+ case EXC_OBJTYPE_POLYGON:
+ case EXC_OBJTYPE_DRAWING:
+ case EXC_OBJTYPE_TEXT:
+ xDrawObj.reset( new XclImpTextObj( rRoot ) );
+ break;
+
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break;
+ case EXC_OBJTYPE_NOTE: xDrawObj.reset( new XclImpNoteObj( rRoot ) ); break;
+
+ default:
+ DBG_ERROR1( "XclImpDrawObjBase::ReadObj8 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+ }
+
+ xDrawObj->ImplReadObj8( rStrm );
+ return xDrawObj;
+}
+
+void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor )
+{
+ maAnchor = rAnchor;
+ mbHasAnchor = true;
+}
+
+void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin )
+{
+ mnDffShapeId = rDffObjData.nShapeId;
+ mnDffFlags = rDffObjData.nSpFlags;
+ maObjName = rObjName;
+ maHyperlink = rHyperlink;
+ mbVisible = bVisible;
+ mbAutoMargin = bAutoMargin;
+}
+
+String XclImpDrawObjBase::GetObjName() const
+{
+ /* #118053# #i51348# Always return a non-empty name. Create English
+ default names depending on the object type. This is not implemented as
+ virtual functions in derived classes, as class type and object type may
+ not match. */
+ return (maObjName.Len() > 0) ? maObjName : GetObjectManager().GetDefaultObjName( *this );
+}
+
+const XclObjAnchor* XclImpDrawObjBase::GetAnchor() const
+{
+ return mbHasAnchor ? &maAnchor : 0;
+}
+
+bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const
+{
+ // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0
+ return mbAreaObj ?
+ ((rAnchorRect.GetWidth() > 3) && (rAnchorRect.GetHeight() > 1)) :
+ ((rAnchorRect.GetWidth() > 3) || (rAnchorRect.GetHeight() > 1));
+}
+
+ScRange XclImpDrawObjBase::GetUsedArea( SCTAB nScTab ) const
+{
+ ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
+ // #i44077# object inserted -> update used area for OLE object import
+ if( mbHasAnchor && GetAddressConverter().ConvertRange( aScUsedArea, maAnchor, nScTab, nScTab, false ) )
+ {
+ // reduce range, if object ends directly on borders between two columns or rows
+ if( (maAnchor.mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) )
+ aScUsedArea.aEnd.IncCol( -1 );
+ if( (maAnchor.mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) )
+ aScUsedArea.aEnd.IncRow( -1 );
+ }
+ return aScUsedArea;
+}
+
+sal_Size XclImpDrawObjBase::GetProgressSize() const
+{
+ return DoGetProgressSize();
+}
+
+SdrObject* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const
+{
+ SdrObjectPtr xSdrObj;
+ if( bIsDff && !mbCustomDff )
+ {
+ rDffConv.Progress( GetProgressSize() );
+ }
+ else
+ {
+ xSdrObj.reset( DoCreateSdrObj( rDffConv, rAnchorRect ) );
+ if( xSdrObj.is() )
+ xSdrObj->SetModel( rDffConv.GetModel() );
+ }
+ return xSdrObj.release();
+}
+
+void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj()
+ rSdrObj.NbcSetLayer( SC_LAYER_FRONT );
+
+ // set object name (GetObjName() will always return a non-empty name)
+ rSdrObj.SetName( GetObjName() );
+
+ // #i39167# full width for all objects regardless of horizontal alignment
+ rSdrObj.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) );
+
+ // automatic text margin
+ if( mbAutoMargin )
+ {
+ sal_Int32 nMargin = rDffConv.GetDefaultTextMargin();
+ rSdrObj.SetMergedItem( SdrTextLeftDistItem( nMargin ) );
+ rSdrObj.SetMergedItem( SdrTextRightDistItem( nMargin ) );
+ rSdrObj.SetMergedItem( SdrTextUpperDistItem( nMargin ) );
+ rSdrObj.SetMergedItem( SdrTextLowerDistItem( nMargin ) );
+ }
+
+ // macro and hyperlink
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ if( mbSimpleMacro && ((maMacroName.Len() > 0) || (maHyperlink.getLength() > 0)) )
+ {
+ if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) )
+ {
+ pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) );
+ pInfo->SetHlink( maHyperlink );
+ }
+ }
+#else
+ if( mbSimpleMacro && (maMacroName.Len() > 0) )
+ if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) )
+ pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) );
+#endif
+
+ // call virtual function for object type specific processing
+ DoPreProcessSdrObj( rDffConv, rSdrObj );
+}
+
+void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // call virtual function for object type specific processing
+ DoPostProcessSdrObj( rDffConv, rSdrObj );
+}
+
+// protected ------------------------------------------------------------------
+
+void XclImpDrawObjBase::ReadName5( XclImpStream& rStrm, sal_uInt16 nNameLen )
+{
+ maObjName.Erase();
+ if( nNameLen > 0 )
+ {
+ // name length field is repeated before the name
+ maObjName = rStrm.ReadByteString( false );
+ // skip padding byte for word boundaries
+ if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
+ }
+}
+
+void XclImpDrawObjBase::ReadMacro3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ maMacroName.Erase();
+ rStrm.Ignore( nMacroSize );
+ // skip padding byte for word boundaries, not contained in nMacroSize
+ if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
+}
+
+void XclImpDrawObjBase::ReadMacro4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ maMacroName.Erase();
+ rStrm.Ignore( nMacroSize );
+}
+
+void XclImpDrawObjBase::ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ maMacroName.Erase();
+ rStrm.Ignore( nMacroSize );
+}
+
+void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm )
+{
+ maMacroName.Erase();
+ if( rStrm.GetRecLeft() > 6 )
+ {
+ // macro is stored in a tNameXR token containing a link to a defined name
+ sal_uInt16 nFmlaSize;
+ rStrm >> nFmlaSize;
+ rStrm.Ignore( 4 );
+ DBG_ASSERT( nFmlaSize == 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
+ if( nFmlaSize == 7 )
+ {
+ sal_uInt8 nTokenId;
+ sal_uInt16 nExtSheet, nExtName;
+ rStrm >> nTokenId >> nExtSheet >> nExtName;
+ DBG_ASSERT( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ),
+ "XclImpDrawObjBase::ReadMacro - tNameXR token expected" );
+ if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
+ maMacroName = GetLinkManager().GetMacroName( nExtSheet, nExtName );
+ }
+ }
+}
+
+void XclImpDrawObjBase::ConvertLineStyle( SdrObject& rSdrObj, const XclObjLineData& rLineData ) const
+{
+ if( rLineData.IsAuto() )
+ {
+ XclObjLineData aAutoData;
+ aAutoData.mnAuto = 0;
+ ConvertLineStyle( rSdrObj, aAutoData );
+ }
+ else
+ {
+ long nLineWidth = 35 * ::std::min( rLineData.mnWidth, EXC_OBJ_LINE_THICK );
+ rSdrObj.SetMergedItem( XLineWidthItem( nLineWidth ) );
+ rSdrObj.SetMergedItem( XLineColorItem( EMPTY_STRING, GetPalette().GetColor( rLineData.mnColorIdx ) ) );
+ rSdrObj.SetMergedItem( XLineJointItem( XLINEJOINT_MITER ) );
+
+ ULONG nDotLen = ::std::max< ULONG >( 70 * rLineData.mnWidth, 35 );
+ ULONG nDashLen = 3 * nDotLen;
+ ULONG nDist = 2 * nDotLen;
+
+ switch( rLineData.mnStyle )
+ {
+ default:
+ case EXC_OBJ_LINE_SOLID:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ break;
+ case EXC_OBJ_LINE_DASH:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 0, nDotLen, 1, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_DOT:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 0, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_DASHDOT:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 1, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_DASHDOTDOT:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 2, nDotLen, 1, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_MEDTRANS:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ rSdrObj.SetMergedItem( XLineTransparenceItem( 50 ) );
+ break;
+ case EXC_OBJ_LINE_DARKTRANS:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ rSdrObj.SetMergedItem( XLineTransparenceItem( 25 ) );
+ break;
+ case EXC_OBJ_LINE_LIGHTTRANS:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ rSdrObj.SetMergedItem( XLineTransparenceItem( 75 ) );
+ break;
+ case EXC_OBJ_LINE_NONE:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_NONE ) );
+ break;
+ }
+ }
+}
+
+void XclImpDrawObjBase::ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillData& rFillData ) const
+{
+ if( rFillData.IsAuto() )
+ {
+ XclObjFillData aAutoData;
+ aAutoData.mnAuto = 0;
+ ConvertFillStyle( rSdrObj, aAutoData );
+ }
+ else if( rFillData.mnPattern == EXC_PATT_NONE )
+ {
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_NONE ) );
+ }
+ else
+ {
+ Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx );
+ Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx );
+ if( (rFillData.mnPattern == EXC_PATT_SOLID) || (aPattColor == aBackColor) )
+ {
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_SOLID ) );
+ rSdrObj.SetMergedItem( XFillColorItem( EMPTY_STRING, aPattColor ) );
+ }
+ else
+ {
+ static const sal_uInt8 sppnPatterns[][ 8 ] =
+ {
+ { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
+ { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
+ { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
+ { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
+ { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
+ { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
+ { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
+ { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
+ { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
+ { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
+ { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
+ { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
+ { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
+ { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
+ { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
+ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
+ };
+ const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_TABLE_SIZE( sppnPatterns ) ) ];
+ // create 2-colored 8x8 DIB
+ SvMemoryStream aMemStrm;
+ aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
+ aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
+ aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
+ for( size_t nIdx = 0; nIdx < 8; ++nIdx )
+ aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ Bitmap aBitmap;
+ aBitmap.Read( aMemStrm, FALSE );
+ XOBitmap aXOBitmap( aBitmap );
+ aXOBitmap.Bitmap2Array();
+ aXOBitmap.SetBitmapType( XBITMAP_8X8 );
+ if( aXOBitmap.GetBackgroundColor().GetColor() == COL_BLACK )
+ ::std::swap( aPattColor, aBackColor );
+ aXOBitmap.SetPixelColor( aPattColor );
+ aXOBitmap.SetBackgroundColor( aBackColor );
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_BITMAP ) );
+ rSdrObj.SetMergedItem( XFillBitmapItem( EMPTY_STRING, aXOBitmap ) );
+ }
+ }
+}
+
+void XclImpDrawObjBase::ConvertFrameStyle( SdrObject& rSdrObj, sal_uInt16 nFrameFlags ) const
+{
+ if( ::get_flag( nFrameFlags, EXC_OBJ_FRAME_SHADOW ) )
+ {
+ rSdrObj.SetMergedItem( SdrShadowItem( TRUE ) );
+ rSdrObj.SetMergedItem( SdrShadowXDistItem( 35 ) );
+ rSdrObj.SetMergedItem( SdrShadowYDistItem( 35 ) );
+ rSdrObj.SetMergedItem( SdrShadowColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWTEXT ) ) );
+ }
+}
+
+Color XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData& rLineData ) const
+{
+ Color aColor( COL_TRANSPARENT );
+ if( rLineData.IsAuto() )
+ {
+ XclObjLineData aAutoData;
+ aAutoData.mnAuto = 0;
+ aColor = GetSolidLineColor( aAutoData );
+ }
+ else if( rLineData.mnStyle != EXC_OBJ_LINE_NONE )
+ {
+ aColor = GetPalette().GetColor( rLineData.mnColorIdx );
+ }
+ return aColor;
+}
+
+Color XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData& rFillData ) const
+{
+ Color aColor( COL_TRANSPARENT );
+ if( rFillData.IsAuto() )
+ {
+ XclObjFillData aAutoData;
+ aAutoData.mnAuto = 0;
+ aColor = GetSolidFillColor( aAutoData );
+ }
+ else if( rFillData.mnPattern != EXC_PATT_NONE )
+ {
+ Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx );
+ Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx );
+ aColor = XclTools::GetPatternColor( aPattColor, aBackColor, rFillData.mnPattern );
+ }
+ return aColor;
+}
+
+void XclImpDrawObjBase::DoReadObj3( XclImpStream&, sal_uInt16 )
+{
+}
+
+void XclImpDrawObjBase::DoReadObj4( XclImpStream&, sal_uInt16 )
+{
+}
+
+void XclImpDrawObjBase::DoReadObj5( XclImpStream&, sal_uInt16, sal_uInt16 )
+{
+}
+
+void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream&, sal_uInt16, sal_uInt16 )
+{
+}
+
+sal_Size XclImpDrawObjBase::DoGetProgressSize() const
+{
+ return 1;
+}
+
+SdrObject* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& ) const
+{
+ rDffConv.Progress( GetProgressSize() );
+ return 0;
+}
+
+void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter&, SdrObject& ) const
+{
+ // trace if object is not printable
+ if( !IsPrintable() )
+ GetTracer().TraceObjectNotPrintable();
+}
+
+void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter&, SdrObject& ) const
+{
+}
+
+void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm )
+{
+ // back to offset 4 (ignore object count field)
+ rStrm.Seek( 4 );
+
+ sal_uInt16 nObjFlags, nMacroSize;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
+ rStrm.Ignore( 2 );
+
+ mbHasAnchor = true;
+ mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
+ mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
+ DoReadObj3( rStrm, nMacroSize );
+}
+
+void XclImpDrawObjBase::ImplReadObj4( XclImpStream& rStrm )
+{
+ // back to offset 4 (ignore object count field)
+ rStrm.Seek( 4 );
+
+ sal_uInt16 nObjFlags, nMacroSize;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
+ rStrm.Ignore( 2 );
+
+ mbHasAnchor = true;
+ mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
+ mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
+ mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE );
+ DoReadObj4( rStrm, nMacroSize );
+}
+
+void XclImpDrawObjBase::ImplReadObj5( XclImpStream& rStrm )
+{
+ // back to offset 4 (ignore object count field)
+ rStrm.Seek( 4 );
+
+ sal_uInt16 nObjFlags, nMacroSize, nNameLen;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
+ rStrm.Ignore( 2 );
+ rStrm >> nNameLen;
+ rStrm.Ignore( 2 );
+
+ mbHasAnchor = true;
+ mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
+ mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
+ mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE );
+ DoReadObj5( rStrm, nNameLen, nMacroSize );
+}
+
+void XclImpDrawObjBase::ImplReadObj8( XclImpStream& rStrm )
+{
+ // back to beginning
+ rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
+
+ bool bLoop = true;
+ while( bLoop && (rStrm.GetRecLeft() >= 4) )
+ {
+ sal_uInt16 nSubRecId, nSubRecSize;
+ rStrm >> nSubRecId >> nSubRecSize;
+ rStrm.PushPosition();
+ // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
+ nSubRecSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nSubRecSize, rStrm.GetRecLeft() ) );
+
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJCMO:
+ DBG_ASSERT( rStrm.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
+ if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) )
+ {
+ sal_uInt16 nObjFlags;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags;
+ mbPrintable = ::get_flag( nObjFlags, EXC_OBJCMO_PRINTABLE );
+ }
+ break;
+ case EXC_ID_OBJMACRO:
+ ReadMacro8( rStrm );
+ break;
+ case EXC_ID_OBJEND:
+ bLoop = false;
+ break;
+ default:
+ DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+
+ rStrm.PopPosition();
+ rStrm.Ignore( nSubRecSize );
+ }
+
+ /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
+ processing (e.g. charts), even if the OBJEND subrecord is missing. */
+ DoReadObj8SubRec( rStrm, EXC_ID_OBJEND, 0 );
+
+ /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
+ IMGDATA record following the OBJ record (but they use the image data
+ stored in DFF). The IMGDATA record may be continued by several CONTINUE
+ records. But the last CONTINUE record may be in fact an MSODRAWING
+ record that contains the DFF data of the next drawing object! So we
+ have to skip just enough CONTINUE records to look at the next
+ MSODRAWING/CONTINUE record. */
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ {
+ sal_uInt32 nDataSize;
+ rStrm.Ignore( 4 );
+ rStrm >> nDataSize;
+ nDataSize -= rStrm.GetRecLeft();
+ // skip following CONTINUE records until IMGDATA ends
+ while( (nDataSize > 0) && (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord() )
+ {
+ DBG_ASSERT( nDataSize >= rStrm.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
+ nDataSize -= ::std::min< sal_uInt32 >( rStrm.GetRecLeft(), nDataSize );
+ }
+ DBG_ASSERT( nDataSize == 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
+ // next record may be MSODRAWING or CONTINUE or anything else
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef xDrawObj )
+{
+ if( !empty() )
+ if( XclImpGroupObj* pGroupObj = dynamic_cast< XclImpGroupObj* >( back().get() ) )
+ if( pGroupObj->TryInsert( xDrawObj ) )
+ return;
+ push_back( xDrawObj );
+}
+
+sal_Size XclImpDrawObjVector::GetProgressSize() const
+{
+ sal_Size nProgressSize = 0;
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ nProgressSize += (*aIt)->GetProgressSize();
+ return nProgressSize;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpPhObj::XclImpPhObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot )
+{
+ SetProcessSdrObj( false );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpGroupObj::XclImpGroupObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnFirstUngrouped( 0 )
+{
+}
+
+bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj )
+{
+ if( xDrawObj->GetObjId() == mnFirstUngrouped )
+ return false;
+ // insert into own list or into nested group
+ maChildren.InsertGrouped( xDrawObj );
+ return true;
+}
+
+void XclImpGroupObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnFirstUngrouped;
+ rStrm.Ignore( 16 );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpGroupObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnFirstUngrouped;
+ rStrm.Ignore( 16 );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpGroupObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnFirstUngrouped;
+ rStrm.Ignore( 16 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+sal_Size XclImpGroupObj::DoGetProgressSize() const
+{
+ return XclImpDrawObjBase::DoGetProgressSize() + maChildren.GetProgressSize();
+}
+
+SdrObject* XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& /*rAnchorRect*/ ) const
+{
+ TSdrObjectPtr< SdrObjGroup > xSdrObj( new SdrObjGroup );
+ // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
+ SdrObjList& rObjList = *xSdrObj->GetSubList(); // SdrObjGroup always returns existing sublist
+ for( XclImpDrawObjVector::const_iterator aIt = maChildren.begin(), aEnd = maChildren.end(); aIt != aEnd; ++aIt )
+ rDffConv.ProcessObject( rObjList, **aIt );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpLineObj::XclImpLineObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnArrows( 0 ),
+ mnStartPoint( EXC_OBJ_LINE_TL )
+{
+ SetAreaObj( false );
+}
+
+void XclImpLineObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maLineData >> mnArrows >> mnStartPoint;
+ rStrm.Ignore( 1 );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpLineObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maLineData >> mnArrows >> mnStartPoint;
+ rStrm.Ignore( 1 );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm >> maLineData >> mnArrows >> mnStartPoint;
+ rStrm.Ignore( 1 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+SdrObject* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ ::basegfx::B2DPolygon aB2DPolygon;
+ switch( mnStartPoint )
+ {
+ default:
+ case EXC_OBJ_LINE_TL:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
+ break;
+ case EXC_OBJ_LINE_TR:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
+ break;
+ case EXC_OBJ_LINE_BR:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
+ break;
+ case EXC_OBJ_LINE_BL:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
+ break;
+ }
+ SdrObjectPtr xSdrObj( new SdrPathObj( OBJ_LINE, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
+ ConvertLineStyle( *xSdrObj, maLineData );
+
+ // line ends
+ sal_uInt8 nArrowType = ::extract_value< sal_uInt8 >( mnArrows, 0, 4 );
+ bool bLineStart = false;
+ bool bLineEnd = false;
+ bool bFilled = false;
+ switch( nArrowType )
+ {
+ case EXC_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break;
+ case EXC_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break;
+ case EXC_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break;
+ case EXC_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break;
+ }
+ if( bLineStart || bLineEnd )
+ {
+ sal_uInt8 nArrowWidth = ::extract_value< sal_uInt8 >( mnArrows, 4, 4 );
+ double fArrowWidth = 3.0;
+ switch( nArrowWidth )
+ {
+ case EXC_OBJ_ARROW_NARROW: fArrowWidth = 2.0; break;
+ case EXC_OBJ_ARROW_MEDIUM: fArrowWidth = 3.0; break;
+ case EXC_OBJ_ARROW_WIDE: fArrowWidth = 5.0; break;
+ }
+
+ sal_uInt8 nArrowLength = ::extract_value< sal_uInt8 >( mnArrows, 8, 4 );
+ double fArrowLength = 3.0;
+ switch( nArrowLength )
+ {
+ case EXC_OBJ_ARROW_NARROW: fArrowLength = 2.5; break;
+ case EXC_OBJ_ARROW_MEDIUM: fArrowLength = 3.5; break;
+ case EXC_OBJ_ARROW_WIDE: fArrowLength = 6.0; break;
+ }
+
+ ::basegfx::B2DPolygon aArrowPoly;
+#define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
+ if( bFilled )
+ {
+ aArrowPoly.append( EXC_ARROW_POINT( 0, 100 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 100, 100 ) );
+ }
+ else
+ {
+ sal_uInt8 nLineWidth = ::limit_cast< sal_uInt8 >( maLineData.mnWidth, EXC_OBJ_LINE_THIN, EXC_OBJ_LINE_THICK );
+ aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth, 100 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 50, 12 * nLineWidth ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 5 * nLineWidth, 100 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth ) );
+ }
+#undef EXC_ARROW_POINT
+
+ ::basegfx::B2DPolyPolygon aArrowPolyPoly( aArrowPoly );
+ long nWidth = static_cast< long >( 125 * fArrowWidth );
+ if( bLineStart )
+ {
+ xSdrObj->SetMergedItem( XLineStartItem( EMPTY_STRING, aArrowPolyPoly ) );
+ xSdrObj->SetMergedItem( XLineStartWidthItem( nWidth ) );
+ xSdrObj->SetMergedItem( XLineStartCenterItem( FALSE ) );
+ }
+ if( bLineEnd )
+ {
+ xSdrObj->SetMergedItem( XLineEndItem( EMPTY_STRING, aArrowPolyPoly ) );
+ xSdrObj->SetMergedItem( XLineEndWidthItem( nWidth ) );
+ xSdrObj->SetMergedItem( XLineEndCenterItem( FALSE ) );
+ }
+ }
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpRectObj::XclImpRectObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnFrameFlags( 0 )
+{
+ SetAreaObj( true );
+}
+
+void XclImpRectObj::ReadFrameData( XclImpStream& rStrm )
+{
+ rStrm >> maFillData >> maLineData >> mnFrameFlags;
+}
+
+void XclImpRectObj::ConvertRectStyle( SdrObject& rSdrObj ) const
+{
+ ConvertLineStyle( rSdrObj, maLineData );
+ ConvertFillStyle( rSdrObj, maFillData );
+ ConvertFrameStyle( rSdrObj, mnFrameFlags );
+}
+
+void XclImpRectObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpRectObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+SdrObject* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj( new SdrRectObj( rAnchorRect ) );
+ ConvertRectStyle( *xSdrObj );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpOvalObj::XclImpOvalObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot )
+{
+}
+
+SdrObject* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj( new SdrCircObj( OBJ_CIRC, rAnchorRect ) );
+ ConvertRectStyle( *xSdrObj );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpArcObj::XclImpArcObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnQuadrant( EXC_OBJ_ARC_TR )
+{
+ SetAreaObj( false ); // arc may be 2-dimensional
+}
+
+void XclImpArcObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillData >> maLineData >> mnQuadrant;
+ rStrm.Ignore( 1 );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpArcObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillData >> maLineData >> mnQuadrant;
+ rStrm.Ignore( 1 );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillData >> maLineData >> mnQuadrant;
+ rStrm.Ignore( 1 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+SdrObject* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ Rectangle aNewRect = rAnchorRect;
+ long nStartAngle = 0;
+ long nEndAngle = 0;
+ switch( mnQuadrant )
+ {
+ default:
+ case EXC_OBJ_ARC_TR:
+ nStartAngle = 0;
+ nEndAngle = 9000;
+ aNewRect.Left() -= rAnchorRect.GetWidth();
+ aNewRect.Bottom() += rAnchorRect.GetHeight();
+ break;
+ case EXC_OBJ_ARC_TL:
+ nStartAngle = 9000;
+ nEndAngle = 18000;
+ aNewRect.Right() += rAnchorRect.GetWidth();
+ aNewRect.Bottom() += rAnchorRect.GetHeight();
+ break;
+ case EXC_OBJ_ARC_BL:
+ nStartAngle = 18000;
+ nEndAngle = 27000;
+ aNewRect.Right() += rAnchorRect.GetWidth();
+ aNewRect.Top() -= rAnchorRect.GetHeight();
+ break;
+ case EXC_OBJ_ARC_BR:
+ nStartAngle = 27000;
+ nEndAngle = 0;
+ aNewRect.Left() -= rAnchorRect.GetWidth();
+ aNewRect.Top() -= rAnchorRect.GetHeight();
+ break;
+ }
+ SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_SECT : OBJ_CARC;
+ SdrObjectPtr xSdrObj( new SdrCircObj( eObjKind, aNewRect, nStartAngle, nEndAngle ) );
+ ConvertFillStyle( *xSdrObj, maFillData );
+ ConvertLineStyle( *xSdrObj, maLineData );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot ),
+ mnPolyFlags( 0 ),
+ mnPointCount( 0 )
+{
+ SetAreaObj( false ); // polygon may be 2-dimensional
+}
+
+void XclImpPolygonObj::ReadCoordList( XclImpStream& rStrm )
+{
+ if( (rStrm.GetNextRecId() == EXC_ID_COORDLIST) && rStrm.StartNextRecord() )
+ {
+ DBG_ASSERT( rStrm.GetRecLeft() / 4 == mnPointCount, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
+ while( rStrm.GetRecLeft() >= 4 )
+ {
+ sal_uInt16 nX, nY;
+ rStrm >> nX >> nY;
+ maCoords.push_back( Point( nX, nY ) );
+ }
+ }
+}
+
+void XclImpPolygonObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ rStrm >> mnPolyFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> mnPointCount;
+ rStrm.Ignore( 8 );
+ ReadMacro4( rStrm, nMacroSize );
+ ReadCoordList( rStrm );
+}
+
+void XclImpPolygonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ rStrm >> mnPolyFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> mnPointCount;
+ rStrm.Ignore( 8 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ ReadCoordList( rStrm );
+}
+
+namespace {
+
+::basegfx::B2DPoint lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint )
+{
+ return ::basegfx::B2DPoint(
+ rAnchorRect.Left() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.X(), 16384.0 ) / 16384.0 * rAnchorRect.GetWidth() + 0.5 ),
+ rAnchorRect.Top() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.Y(), 16384.0 ) / 16384.0 * rAnchorRect.GetHeight() + 0.5 ) );
+}
+
+} // namespace
+
+SdrObject* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj;
+ if( maCoords.size() >= 2 )
+ {
+ // create the polygon
+ ::basegfx::B2DPolygon aB2DPolygon;
+ for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt )
+ aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, *aIt ) );
+ // close polygon if specified
+ if( ::get_flag( mnPolyFlags, EXC_OBJ_POLY_CLOSED ) && (maCoords.front() != maCoords.back()) )
+ aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, maCoords.front() ) );
+ // create the SdrObject
+ SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_PATHPOLY : OBJ_PATHPLIN;
+ xSdrObj.reset( new SdrPathObj( eObjKind, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
+ ConvertRectStyle( *xSdrObj );
+ }
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpObjTextData::ReadByteString( XclImpStream& rStrm )
+{
+ mxString.reset();
+ if( maData.mnTextLen > 0 )
+ {
+ mxString.reset( new XclImpString( rStrm.ReadRawByteString( maData.mnTextLen ) ) );
+ // skip padding byte for word boundaries
+ if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
+ }
+}
+
+void XclImpObjTextData::ReadFormats( XclImpStream& rStrm )
+{
+ if( mxString.is() )
+ mxString->ReadObjFormats( rStrm, maData.mnFormatSize );
+ else
+ rStrm.Ignore( maData.mnFormatSize );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTextObj::XclImpTextObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot )
+{
+}
+
+void XclImpTextObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ maTextData.maData.ReadObj3( rStrm );
+ ReadMacro3( rStrm, nMacroSize );
+ maTextData.ReadByteString( rStrm );
+ maTextData.ReadFormats( rStrm );
+}
+
+void XclImpTextObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ maTextData.maData.ReadObj3( rStrm );
+ ReadMacro4( rStrm, nMacroSize );
+ maTextData.ReadByteString( rStrm );
+ maTextData.ReadFormats( rStrm );
+}
+
+void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ maTextData.maData.ReadObj5( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ maTextData.ReadByteString( rStrm );
+ rStrm.Ignore( maTextData.maData.mnLinkSize ); // ignore text link formula
+ maTextData.ReadFormats( rStrm );
+}
+
+SdrObject* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ TSdrObjectPtr< SdrObjCustomShape > xSdrObj( new SdrObjCustomShape );
+ xSdrObj->NbcSetSnapRect( rAnchorRect );
+ OUString aRectType = CREATE_OUSTRING( "rectangle" );
+ xSdrObj->MergeDefaultAttributes( &aRectType );
+ ConvertRectStyle( *xSdrObj );
+ BOOL bAutoSize = ::get_flag( maTextData.maData.mnFlags, EXC_OBJ_TEXT_AUTOSIZE );
+ xSdrObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize ) );
+ xSdrObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize ) );
+ xSdrObj->SetMergedItem( SdrTextWordWrapItem( TRUE ) );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // set text data
+ if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) )
+ {
+ if( maTextData.mxString.is() )
+ {
+ if( maTextData.mxString->IsRich() )
+ {
+ // rich text
+ ::std::auto_ptr< EditTextObject > xEditObj(
+ XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData.mxString ) );
+ OutlinerParaObject* pOutlineObj = new OutlinerParaObject( *xEditObj );
+ pOutlineObj->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
+ // text object takes ownership of the outliner object
+ pTextObj->NbcSetOutlinerParaObject( pOutlineObj );
+ }
+ else
+ {
+ // plain text
+ pTextObj->NbcSetText( maTextData.mxString->GetText() );
+ }
+
+ /* #i96858# Do not apply any formatting if there is no text.
+ SdrObjCustomShape::SetVerticalWriting (initiated from
+ SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
+ ensures that we can erroneously write a ClientTextbox record
+ (with no content) while exporting to XLS, which can cause a
+ corrupted exported document. */
+
+ SvxAdjust eHorAlign = SVX_ADJUST_LEFT;
+ SdrTextVertAdjust eVerAlign = SDRTEXTVERTADJUST_TOP;
+
+ // orientation (this is only a fake, drawing does not support real text orientation)
+ namespace csst = ::com::sun::star::text;
+ csst::WritingMode eWriteMode = csst::WritingMode_LR_TB;
+ switch( maTextData.maData.mnOrient )
+ {
+ default:
+ case EXC_OBJ_ORIENT_NONE:
+ {
+ eWriteMode = csst::WritingMode_LR_TB;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_HOR_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ }
+ break;
+
+ case EXC_OBJ_ORIENT_90CCW:
+ {
+ if( SdrObjCustomShape* pObjCustomShape = dynamic_cast< SdrObjCustomShape* >( &rSdrObj ) )
+ {
+ double fAngle = 180.0;
+ com::sun::star::beans::PropertyValue aTextRotateAngle;
+ aTextRotateAngle.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
+ aTextRotateAngle.Value <<= fAngle;
+ SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)pObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+ aGeometryItem.SetPropertyValue( aTextRotateAngle );
+ pObjCustomShape->SetMergedItem( aGeometryItem );
+ }
+ eWriteMode = csst::WritingMode_TB_RL;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+ switch( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ {
+ eHorAlign = SVX_ADJUST_CENTER;
+ }
+ break;
+
+ default:
+ {
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ }
+ }
+ }
+ break;
+
+ case EXC_OBJ_ORIENT_STACKED: // PASSTHROUGH INTENDED
+ {
+ // sj: STACKED is not supported, maybe it can be optimized here a bit
+ }
+ case EXC_OBJ_ORIENT_90CW:
+ {
+ eWriteMode = csst::WritingMode_TB_RL;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ {
+ eHorAlign = SVX_ADJUST_CENTER;
+ }
+ break;
+
+ default:
+ {
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) );
+ rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) );
+ rSdrObj.SetMergedItem( SvxWritingModeItem( eWriteMode, SDRATTR_TEXTDIRECTION ) );
+ }
+ }
+ // base class processing
+ XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) :
+ XclImpRectObj( rRoot ),
+ mbOwnTab( bOwnTab )
+{
+ SetSimpleMacro( false );
+ SetCustomDffObj( true );
+}
+
+void XclImpChartObj::ReadChartSubStream( XclImpStream& rStrm )
+{
+ if( mbOwnTab ? (rStrm.GetRecId() == EXC_ID5_BOF) : ((rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord()) )
+ {
+ sal_uInt16 nBofType;
+ rStrm.Seek( 2 );
+ rStrm >> nBofType;
+ DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
+
+ // read chart, even if BOF record contains wrong substream identifier
+ mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) );
+ mxChart->ReadChartSubStream( rStrm );
+ if( mbOwnTab )
+ FinalizeTabChart();
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
+ }
+}
+
+void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ // read OBJ record and the following chart substream
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 18 );
+ ReadMacro3( rStrm, nMacroSize );
+#if 0
+ ReadChartSubStream( rStrm );
+#endif
+ // set frame format from OBJ record, it is used if chart itself is transparent
+ if( mxChart.is() )
+ mxChart->UpdateObjFrame( maLineData, maFillData );
+}
+
+void XclImpChartObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ // read OBJ record and the following chart substream
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 18 );
+ ReadMacro4( rStrm, nMacroSize );
+#if 0
+ ReadChartSubStream( rStrm );
+#endif
+ // set frame format from OBJ record, it is used if chart itself is transparent
+ if( mxChart.is() )
+ mxChart->UpdateObjFrame( maLineData, maFillData );
+}
+
+void XclImpChartObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ // read OBJ record and the following chart substream
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 18 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ ReadChartSubStream( rStrm );
+ // set frame format from OBJ record, it is used if chart itself is transparent
+ if( mxChart.is() )
+ mxChart->UpdateObjFrame( maLineData, maFillData );
+}
+
+void XclImpChartObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 /*nSubRecSize*/ )
+{
+ // read the following chart substream
+ if( nSubRecId == EXC_ID_OBJEND )
+ {
+ // enable CONTINUE handling for the entire chart substream
+ rStrm.ResetRecord( true );
+ ReadChartSubStream( rStrm );
+ /* #90118# disable CONTINUE handling again to be able to read
+ following CONTINUE records as MSODRAWING records. */
+ rStrm.ResetRecord( false );
+ }
+}
+
+sal_Size XclImpChartObj::DoGetProgressSize() const
+{
+ return mxChart.is() ? mxChart->GetProgressSize() : 1;
+}
+
+SdrObject* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj;
+ SfxObjectShell* pDocShell = GetDocShell();
+ if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() )
+ {
+ // create embedded chart object
+ OUString aEmbObjName;
+ Reference< XEmbeddedObject > xEmbObj = pDocShell->GetEmbeddedObjectContainer().
+ CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aEmbObjName );
+
+ /* Set the size to the embedded object, this prevents that font sizes
+ of text objects are changed in the chart when the object is
+ inserted into the draw page. */
+ sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj->getMapUnit( nAspect ) );
+ Size aSize( Window::LogicToLogic( rAnchorRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( aUnit ) ) );
+ ::com::sun::star::awt::Size aAwtSize( aSize.Width(), aSize.Height() );
+ xEmbObj->setVisualAreaSize( nAspect, aAwtSize );
+
+ // create the container OLE object
+ xSdrObj.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj, nAspect ), aEmbObjName, rAnchorRect ) );
+ }
+
+ return xSdrObj.release();
+}
+
+void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ const SdrOle2Obj* pSdrOleObj = dynamic_cast< const SdrOle2Obj* >( &rSdrObj );
+ if( mxChart.is() && pSdrOleObj )
+ {
+ Reference< XEmbeddedObject > xEmbObj = pSdrOleObj->GetObjRef();
+ if( xEmbObj.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) try
+ {
+ Reference< XEmbedPersist > xPersist( xEmbObj, UNO_QUERY_THROW );
+ Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY_THROW );
+ mxChart->Convert( xModel, rDffConv, xPersist->getEntryName(), rSdrObj.GetLogicRect() );
+ xPersist->storeOwn();
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+void XclImpChartObj::FinalizeTabChart()
+{
+ /* #i44077# Calculate and store DFF anchor for sheet charts.
+ Needed to get used area if this chart is inserted as OLE object. */
+ DBG_ASSERT( mbOwnTab, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
+
+ // set uninitialized page to landscape
+ if( !GetPageSettings().GetPageData().mbValid )
+ GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT, false );
+
+ // calculate size of the chart object
+ const XclPageData& rPageData = GetPageSettings().GetPageData();
+ Size aPaperSize = rPageData.GetScPaperSize();
+
+ long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() );
+ long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() );
+
+ // subtract page margins, give some more extra space
+ nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000);
+ nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000);
+
+ // print column/row headers?
+ if( rPageData.mbPrintHeadings )
+ {
+ nWidth -= 2000;
+ nHeight -= 1000;
+ }
+
+ // create the object anchor
+ XclObjAnchor aAnchor;
+ aAnchor.SetRect( GetRoot(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM );
+ SetAnchor( aAnchor );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpNoteObj::XclImpNoteObj( const XclImpRoot& rRoot ) :
+ XclImpTextObj( rRoot ),
+ maScPos( ScAddress::INITIALIZE_INVALID ),
+ mnNoteFlags( 0 )
+{
+ SetSimpleMacro( false );
+ // caption object will be created manually
+ SetInsertSdrObj( false );
+}
+
+void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags )
+{
+ maScPos = rScPos;
+ mnNoteFlags = nNoteFlags;
+}
+
+void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // create formatted text
+ XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+ OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
+ if( maScPos.IsValid() && pOutlinerObj )
+ {
+ // create cell note with all data from drawing object
+ ScNoteUtil::CreateNoteFromObjectData(
+ GetDoc(), maScPos,
+ rSdrObj.GetMergedItemSet().Clone(), // new object on heap expected
+ new OutlinerParaObject( *pOutlinerObj ), // new object on heap expected
+ rSdrObj.GetLogicRect(),
+ ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ),
+ false );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpControlHelper::XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode ) :
+ mrRoot( rRoot ),
+ meBindMode( eBindMode )
+{
+}
+
+XclImpControlHelper::~XclImpControlHelper()
+{
+}
+
+SdrObject* XclImpControlHelper::CreateSdrObjectFromShape(
+ const Reference< XShape >& rxShape, const Rectangle& rAnchorRect ) const
+{
+ mxShape = rxShape;
+ SdrObjectPtr xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape ) );
+ if( xSdrObj.is() )
+ {
+ xSdrObj->NbcSetSnapRect( rAnchorRect );
+ // #i30543# insert into control layer
+ xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS );
+ }
+ return xSdrObj.release();
+}
+
+void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) const
+{
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
+ if( !xCtrlModel.is() )
+ return;
+
+ ScfPropertySet aPropSet( xCtrlModel );
+
+ // #118053# #i51348# set object name at control model
+ aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
+
+ // control visible and printable?
+ aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
+ aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
+
+ // sheet links
+ if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
+ {
+ Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY );
+ if( xFactory.is() )
+ {
+ // cell link
+ if( mxCellLink.is() ) try
+ {
+ Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW );
+
+ // create argument sequence for createInstanceWithArguments()
+ CellAddress aApiAddress;
+ ScUnoConversion::FillApiAddress( aApiAddress, *mxCellLink );
+
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( SC_UNONAME_BOUNDCELL );
+ aValue.Value <<= aApiAddress;
+
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the CellValueBinding instance and set at the control model
+ OUString aServiceName;
+ switch( meBindMode )
+ {
+ case EXC_CTRL_BINDCONTENT: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_VALBIND ); break;
+ case EXC_CTRL_BINDPOSITION: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND ); break;
+ }
+ Reference< XValueBinding > xBinding(
+ xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW );
+ xBindable->setValueBinding( xBinding );
+ }
+ catch( const Exception& )
+ {
+ }
+
+ // source range
+ if( mxSrcRange.is() ) try
+ {
+ Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW );
+
+ // create argument sequence for createInstanceWithArguments()
+ CellRangeAddress aApiRange;
+ ScUnoConversion::FillApiRange( aApiRange, *mxSrcRange );
+
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( SC_UNONAME_CELLRANGE );
+ aValue.Value <<= aApiRange;
+
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the EntrySource instance and set at the control model
+ Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ), aArgs ), UNO_QUERY_THROW );
+ xEntrySink->setListEntrySource( xEntrySource );
+ }
+ catch( const Exception& )
+ {
+ }
+ }
+ }
+
+ // virtual call for type specific processing
+ DoProcessControl( aPropSet );
+}
+
+void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize )
+{
+ ScRangeList aScRanges;
+ ReadRangeList( aScRanges, rStrm, bWithBoundSize );
+ // Use first cell of first range
+ if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
+ mxCellLink.reset( new ScAddress( pScRange->aStart ) );
+}
+
+void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize )
+{
+ ScRangeList aScRanges;
+ ReadRangeList( aScRanges, rStrm, bWithBoundSize );
+ // Use first range
+ if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
+ mxSrcRange.reset( new ScRange( *pScRange ) );
+}
+
+void XclImpControlHelper::DoProcessControl( ScfPropertySet& ) const
+{
+}
+
+void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm )
+{
+ XclTokenArray aXclTokArr;
+ aXclTokArr.ReadSize( rStrm );
+ rStrm.Ignore( 4 );
+ aXclTokArr.ReadArray( rStrm );
+ mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm );
+}
+
+void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize )
+{
+ if( bWithBoundSize )
+ {
+ sal_uInt16 nSize;
+ rStrm >> nSize;
+ if( nSize > 0 )
+ {
+ rStrm.PushPosition();
+ ReadRangeList( rScRanges, rStrm );
+ rStrm.PopPosition();
+ rStrm.Ignore( nSize );
+ }
+ }
+ else
+ {
+ ReadRangeList( rScRanges, rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot& rRoot ) :
+ XclImpTextObj( rRoot ),
+ XclImpControlHelper( rRoot, EXC_CTRL_BINDPOSITION )
+{
+ SetSimpleMacro( false );
+ SetCustomDffObj( true );
+}
+
+namespace {
+
+void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId )
+{
+ if( rDffPropSet.IsProperty( nPropId ) )
+ {
+ sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId );
+ if( (nColor & 0xFF000000) == 0x08000000 )
+ rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 );
+ }
+}
+
+} // namespace
+
+void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet )
+{
+ maFillData.mnPattern = rDffPropSet.GetPropertyBool( DFF_Prop_fFilled ) ? EXC_PATT_SOLID : EXC_PATT_NONE;
+ lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor );
+ lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor );
+ ::set_flag( maFillData.mnAuto, EXC_OBJ_LINE_AUTO, false );
+
+ maLineData.mnStyle = rDffPropSet.GetPropertyBool( DFF_Prop_fLine ) ? EXC_OBJ_LINE_SOLID : EXC_OBJ_LINE_NONE;
+ lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor );
+ ::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false );
+}
+
+bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
+{
+ return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() );
+}
+
+void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const
+{
+ if( maTextData.mxString.is() )
+ {
+ const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats();
+ if( rFormatRuns.empty() )
+ GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
+ else
+ GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx );
+ }
+}
+
+void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const
+{
+ if( maTextData.mxString.is() )
+ {
+ String aLabel = maTextData.mxString->GetText();
+ if( maTextData.maData.mnShortcut > 0 )
+ {
+ xub_StrLen nPos = aLabel.Search( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) );
+ if( nPos != STRING_NOTFOUND )
+ aLabel.Insert( '~', nPos );
+ }
+ rPropSet.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel );
+ }
+ ConvertFont( rPropSet );
+}
+
+SdrObject* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const
+{
+ // do not call DoPreProcessSdrObj() from base class (to skip text processing)
+ ProcessControl( *this );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpButtonObj::XclImpButtonObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot )
+{
+}
+
+void XclImpButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+
+ /* Horizontal text alignment. For unknown reason, the property type is a
+ simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
+ sal_Int16 nHorAlign = 1;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break;
+ case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break;
+ case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break;
+ }
+ rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign );
+
+ // vertical text alignment
+ namespace csss = ::com::sun::star::style;
+ csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE;
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break;
+ case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break;
+ case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break;
+ }
+ rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign );
+
+ // always wrap text automatically
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
+
+ // default button
+ bool bDefButton = ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_DEFAULT );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton );
+
+ // button type (flags cannot be combined in OOo)
+ namespace cssa = ::com::sun::star::awt;
+ cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD;
+ if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CLOSE ) )
+ eButtonType = cssa::PushButtonType_OK;
+ else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CANCEL ) )
+ eButtonType = cssa::PushButtonType_CANCEL;
+ else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_HELP ) )
+ eButtonType = cssa::PushButtonType_HELP;
+ // property type is short, not enum
+ rPropSet.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType ) );
+}
+
+OUString XclImpButtonObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
+}
+
+XclTbxEventType XclImpButtonObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_ACTION;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnState( EXC_OBJ_CHECKBOX_UNCHECKED ),
+ mnCheckBoxFlags( 0 )
+{
+}
+
+void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 20 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
+}
+
+void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJCBLS:
+ // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
+ rStrm >> mnState;
+ rStrm.Ignore( 4 );
+ rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
+ break;
+ case EXC_ID_OBJCBLSFMLA:
+ ReadCellLinkFormula( rStrm, false );
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+
+ // state
+ bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX;
+ sal_Int16 nApiState = 0;
+ switch( mnState )
+ {
+ case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break;
+ case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break;
+ case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break;
+ }
+ if( bSupportsTristate )
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState == 2 );
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState );
+
+ // box style
+ namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
+ sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
+ rPropSet.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect );
+
+ // do not wrap text automatically
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false );
+
+ // #i40279# always centered vertically
+ namespace csss = ::com::sun::star::style;
+ rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE );
+
+ // background color
+ if( maFillData.IsFilled() )
+ {
+ sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ).GetColor() );
+ rPropSet.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor );
+ }
+}
+
+OUString XclImpCheckBoxObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
+}
+
+XclTbxEventType XclImpCheckBoxObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_ACTION;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot& rRoot ) :
+ XclImpCheckBoxObj( rRoot ),
+ mnNextInGroup( 0 ),
+ mnFirstInGroup( 1 )
+{
+}
+
+void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 32 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA;
+ rStrm >> mnCheckBoxFlags >> mnNextInGroup >> mnFirstInGroup;
+}
+
+void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJRBODATA:
+ rStrm >> mnNextInGroup >> mnFirstInGroup;
+ break;
+ default:
+ XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ XclImpCheckBoxObj::DoProcessControl( rPropSet );
+ // TODO: grouping
+}
+
+OUString XclImpOptionButtonObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
+}
+
+XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_ACTION;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot )
+{
+}
+
+void XclImpLabelObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+
+ // text alignment (always top/left aligned)
+ rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) );
+ namespace csss = ::com::sun::star::style;
+ rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP );
+
+ // always wrap text automatically
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
+}
+
+OUString XclImpLabelObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
+}
+
+XclTbxEventType XclImpLabelObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_MOUSE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnGroupBoxFlags( 0 )
+{
+}
+
+void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 26 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
+}
+
+void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJGBODATA:
+ rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+}
+
+OUString XclImpGroupBoxObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
+}
+
+XclTbxEventType XclImpGroupBoxObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_MOUSE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDialogObj::XclImpDialogObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot )
+{
+}
+
+void XclImpDialogObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+}
+
+OUString XclImpDialogObj::DoGetServiceName() const
+{
+ // dialog frame faked by a groupbox
+ return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
+}
+
+XclTbxEventType XclImpDialogObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_MOUSE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpEditObj::XclImpEditObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnContentType( EXC_OBJ_EDIT_TEXT ),
+ mnMultiLine( 0 ),
+ mnScrollBar( 0 ),
+ mnListBoxObjId( 0 )
+{
+}
+
+bool XclImpEditObj::IsNumeric() const
+{
+ return (mnContentType == EXC_OBJ_EDIT_INTEGER) || (mnContentType == EXC_OBJ_EDIT_DOUBLE);
+}
+
+void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 14 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
+}
+
+void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJEDODATA:
+ rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpEditObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ if( maTextData.mxString.is() )
+ {
+ OUString aText = maTextData.mxString->GetText();
+ if( IsNumeric() )
+ {
+ // TODO: OUString::toDouble() does not handle local decimal separator
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText.toDouble() );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar != 0 );
+ }
+ else
+ {
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine != 0 );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar != 0 );
+ }
+ }
+ ConvertFont( rPropSet );
+}
+
+OUString XclImpEditObj::DoGetServiceName() const
+{
+ return IsNumeric() ?
+ CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) :
+ CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
+}
+
+XclTbxEventType XclImpEditObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_TEXT;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnValue( 0 ),
+ mnMin( 0 ),
+ mnMax( 100 ),
+ mnStep( 1 ),
+ mnPageStep( 10 ),
+ mnOrient( 0 ),
+ mnThumbWidth( 1 ),
+ mnScrollFlags( 0 )
+{
+}
+
+void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream& rStrm )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnValue >> mnMin >> mnMax >> mnStep >> mnPageStep >> mnOrient >> mnThumbWidth >> mnScrollFlags;
+}
+
+void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJSBS:
+ ReadSbs( rStrm );
+ break;
+ case EXC_ID_OBJSBSFMLA:
+ ReadCellLinkFormula( rStrm, false );
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjScrollableBase( rRoot )
+{
+}
+
+void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+}
+
+void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
+ rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMin" ), mnMin );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMax" ), mnMax );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinIncrement" ), mnStep );
+
+ // Excel spin buttons always vertical
+ rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL );
+}
+
+OUString XclImpSpinButtonObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
+}
+
+XclTbxEventType XclImpSpinButtonObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_VALUE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjScrollableBase( rRoot )
+{
+}
+
+void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+}
+
+void XclImpScrollBarObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
+ rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMin" ), mnMin );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMax" ), mnMax );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "LineIncrement" ), mnStep );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep );
+ rPropSet.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min< sal_Int32 >( mnPageStep, 1 ) );
+
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+ sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL );
+ rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient );
+}
+
+OUString XclImpScrollBarObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
+}
+
+XclTbxEventType XclImpScrollBarObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_VALUE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot& rRoot ) :
+ XclImpTbxObjScrollableBase( rRoot ),
+ mnEntryCount( 0 ),
+ mnSelEntry( 0 ),
+ mnListFlags( 0 ),
+ mnEditObjId( 0 ),
+ mbHasDefFontIdx( false )
+{
+}
+
+void XclImpTbxObjListBase::ReadLbsData( XclImpStream& rStrm )
+{
+ ReadSourceRangeFormula( rStrm, true );
+ rStrm >> mnEntryCount >> mnSelEntry >> mnListFlags >> mnEditObjId;
+}
+
+void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet& rPropSet ) const
+{
+ // border style
+ namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
+ sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
+ rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder );
+
+ // font formatting
+ if( mbHasDefFontIdx )
+ GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, maTextData.maData.mnDefFontIdx );
+ else
+ GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjListBase( rRoot )
+{
+}
+
+void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft )
+{
+ sal_Size nRecEnd = rStrm.GetRecPos() + nRecLeft;
+ ReadLbsData( rStrm );
+ DBG_ASSERT( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd),
+ "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
+ while( rStrm.IsValid() && (rStrm.GetRecPos() < nRecEnd) )
+ maSelection.push_back( rStrm.ReaduInt8() );
+}
+
+void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ rStrm.Ignore( 18 );
+ rStrm >> maTextData.maData.mnDefFontIdx;
+ rStrm.Ignore( 4 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ ReadFullLbsData( rStrm, rStrm.GetRecLeft() );
+ mbHasDefFontIdx = true;
+}
+
+void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJLBSDATA:
+ ReadFullLbsData( rStrm, nSubRecSize );
+ break;
+ default:
+ XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpListBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // listbox formatting
+ SetBoxFormatting( rPropSet );
+
+ // selection type
+ sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 );
+ bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE;
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel );
+
+ // selection (do not set, if listbox is linked to a cell)
+ if( !HasCellLink() )
+ {
+ ScfInt16Vec aSelVec;
+
+ // multi selection: API expects sequence of list entry indexes
+ if( bMultiSel )
+ for( ScfUInt8Vec::const_iterator aBeg = maSelection.begin(), aIt = aBeg, aEnd = maSelection.end(); aIt != aEnd; ++aIt )
+ if( *aIt != 0 )
+ aSelVec.push_back( static_cast< sal_Int16 >( aIt - aBeg ) );
+ // single selection: mnSelEntry is one-based, API expects zero-based
+ else if( mnSelEntry > 0 )
+ aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) );
+
+ if( !aSelVec.empty() )
+ {
+ Sequence< sal_Int16 > aSelSeq( &aSelVec.front(), static_cast< sal_Int32 >( aSelVec.size() ) );
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
+ }
+ }
+}
+
+OUString XclImpListBoxObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+}
+
+XclTbxEventType XclImpListBoxObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_CHANGE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjListBase( rRoot ),
+ mnLeft( 0 ),
+ mnTop( 0 ),
+ mnRight( 0 ),
+ mnBottom( 0 ),
+ mnDropDownFlags( 0 ),
+ mnLineCount( 0 ),
+ mnMinWidth( 0 )
+{
+}
+
+sal_uInt16 XclImpDropDownObj::GetDropDownType() const
+{
+ return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 );
+}
+
+void XclImpDropDownObj::ReadFullLbsData( XclImpStream& rStrm )
+{
+ ReadLbsData( rStrm );
+ rStrm >> mnDropDownFlags >> mnLineCount >> mnMinWidth >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ // dropdowns of auto-filters have 'simple' style, they don't have a text area
+ if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE )
+ SetProcessSdrObj( false );
+}
+
+void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ rStrm.Ignore( 18 );
+ rStrm >> maTextData.maData.mnDefFontIdx;
+ rStrm.Ignore( 14 );
+ rStrm >> mnLeft >> mnTop >> mnRight >> mnBottom;
+ rStrm.Ignore( 4 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ ReadFullLbsData( rStrm );
+ mbHasDefFontIdx = true;
+}
+
+void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJLBSDATA:
+ ReadFullLbsData( rStrm );
+ break;
+ default:
+ XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpDropDownObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // dropdown listbox formatting
+ SetBoxFormatting( rPropSet );
+ // enable dropdown button
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true );
+ // dropdown line count
+ rPropSet.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount );
+
+ if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX )
+ {
+ // text of editable combobox
+ if( maTextData.mxString.is() )
+ rPropSet.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData.mxString->GetText() );
+ }
+ else
+ {
+ // selection (do not set, if dropdown is linked to a cell)
+ if( !HasCellLink() && (mnSelEntry > 0) )
+ {
+ Sequence< sal_Int16 > aSelSeq( 1 );
+ aSelSeq[ 0 ] = mnSelEntry - 1;
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
+ }
+ }
+}
+
+OUString XclImpDropDownObj::DoGetServiceName() const
+{
+ return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ?
+ CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) :
+ CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+}
+
+XclTbxEventType XclImpDropDownObj::DoGetEventType() const
+{
+ return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? EXC_TBX_EVENT_TEXT : EXC_TBX_EVENT_CHANGE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpPictureObj::XclImpPictureObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot ),
+ XclImpControlHelper( rRoot, EXC_CTRL_BINDCONTENT ),
+ mnStorageId( 0 ),
+ mnCtlsStrmPos( 0 ),
+ mnCtlsStrmSize( 0 ),
+ mbEmbedded( false ),
+ mbLinked( false ),
+ mbSymbol( false ),
+ mbControl( false ),
+ mbUseCtlsStrm( false )
+{
+ SetAreaObj( true );
+ SetSimpleMacro( false );
+ SetCustomDffObj( true );
+}
+
+String XclImpPictureObj::GetOleStorageName() const
+{
+ String aStrgName;
+ if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) )
+ {
+ aStrgName = mbEmbedded ? EXC_STORAGE_OLE_EMBEDDED : EXC_STORAGE_OLE_LINKED;
+ static const sal_Char spcHexChars[] = "0123456789ABCDEF";
+ for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 )
+ aStrgName.Append( sal_Unicode( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ) );
+ }
+ return aStrgName;
+}
+
+void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ sal_uInt16 nLinkSize;
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 6 );
+ rStrm >> nLinkSize;
+ rStrm.Ignore( 2 );
+ ReadFlags3( rStrm );
+ ReadMacro3( rStrm, nMacroSize );
+ ReadPictFmla( rStrm, nLinkSize );
+
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+}
+
+void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ sal_uInt16 nLinkSize;
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 6 );
+ rStrm >> nLinkSize;
+ rStrm.Ignore( 2 );
+ ReadFlags3( rStrm );
+ ReadMacro4( rStrm, nMacroSize );
+ ReadPictFmla( rStrm, nLinkSize );
+
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+}
+
+void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ sal_uInt16 nLinkSize;
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 6 );
+ rStrm >> nLinkSize;
+ rStrm.Ignore( 2 );
+ ReadFlags3( rStrm );
+ rStrm.Ignore( 4 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ ReadPictFmla( rStrm, nLinkSize );
+
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ {
+ // page background is stored as hidden picture with name "__BkgndObj"
+ if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) )
+ GetPageSettings().ReadImgData( rStrm );
+ else
+ maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+ }
+}
+
+void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJFLAGS:
+ ReadFlags8( rStrm );
+ break;
+ case EXC_ID_OBJPICTFMLA:
+ ReadPictFmla( rStrm, rStrm.ReaduInt16() );
+ break;
+ default:
+ XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+SdrObject* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ // try to create an OLE object or form control
+ SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
+
+ // no OLE - create a plain picture from IMGDATA record data
+ if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) )
+ {
+ xSdrObj.reset( new SdrGrafObj( maGraphic, rAnchorRect ) );
+ ConvertRectStyle( *xSdrObj );
+ }
+
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ if( IsOcxControl() )
+ {
+ // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature
+ ProcessControl( *this );
+ }
+ else if( mbEmbedded || mbLinked )
+ {
+ // trace missing "printable" feature
+ XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+
+ SfxObjectShell* pDocShell = GetDocShell();
+ SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj );
+ if( pOleSdrObj && pDocShell )
+ {
+ comphelper::EmbeddedObjectContainer& rEmbObjCont = pDocShell->GetEmbeddedObjectContainer();
+ Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef();
+ OUString aOldName( pOleSdrObj->GetPersistName() );
+
+ /* The object persistence should be already in the storage, but
+ the object still might not be inserted into the container. */
+ if( rEmbObjCont.HasEmbeddedObject( aOldName ) )
+ {
+ if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) )
+ // filter code is allowed to call the following method
+ rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName );
+ }
+ else
+ {
+ /* If the object is still not in container it must be inserted
+ there, the name must be generated in this case. */
+ OUString aNewName;
+ rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName );
+ if( aOldName != aNewName )
+ // #95381# SetPersistName, not SetName
+ pOleSdrObj->SetPersistName( aNewName );
+ }
+ }
+ }
+}
+
+void XclImpPictureObj::ReadFlags3( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
+}
+
+void XclImpPictureObj::ReadFlags8( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
+ mbControl = ::get_flag( nFlags, EXC_OBJ_PIC_CONTROL );
+ mbUseCtlsStrm = ::get_flag( nFlags, EXC_OBJ_PIC_CTLSSTREAM );
+ DBG_ASSERT( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
+ SetProcessSdrObj( mbControl || !mbUseCtlsStrm );
+}
+
+void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize )
+{
+ sal_Size nLinkEnd = rStrm.GetRecPos() + nLinkSize;
+ if( nLinkSize >= 6 )
+ {
+ sal_uInt16 nFmlaSize;
+ rStrm >> nFmlaSize;
+ DBG_ASSERT( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
+ // BIFF3/BIFF4 do not support storages, nothing to do here
+ if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) )
+ {
+ rStrm.Ignore( 4 );
+ sal_uInt8 nToken;
+ rStrm >> nToken;
+
+ // different processing for linked vs. embedded OLE objects
+ if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
+ {
+ mbLinked = true;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5:
+ {
+ sal_Int16 nRefIdx;
+ sal_uInt16 nNameIdx;
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nNameIdx;
+ rStrm.Ignore( 12 );
+ const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx );
+ if( pExtName && pExtName->IsOLE() )
+ mnStorageId = pExtName->nStorageId;
+ }
+ break;
+ case EXC_BIFF8:
+ {
+ sal_uInt16 nXti, nExtName;
+ rStrm >> nXti >> nExtName;
+ const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName );
+ if( pExtName && (pExtName->GetType() == xlExtOLE) )
+ mnStorageId = pExtName->GetStorageId();
+ }
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ }
+ else if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL, EXC_TOKCLASS_NONE ) )
+ {
+ mbEmbedded = true;
+ DBG_ASSERT( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
+ rStrm.Ignore( nFmlaSize - 1 ); // token ID already read
+ if( nFmlaSize & 1 )
+ rStrm.Ignore( 1 ); // padding byte
+
+ // a class name may follow inside the picture link
+ if( rStrm.GetRecPos() + 2 <= nLinkEnd )
+ {
+ sal_uInt16 nLen;
+ rStrm >> nLen;
+ if( nLen > 0 )
+ maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen );
+ }
+ }
+ // else: ignore other formulas, e.g. pictures linked to cell ranges
+ }
+ }
+
+ // seek behind picture link data
+ rStrm.Seek( nLinkEnd );
+
+ // read additional data for embedded OLE objects following the picture link
+ if( IsOcxControl() )
+ {
+ // #i26521# form controls to be ignored
+ if( maClassName.EqualsAscii( "Forms.HTML:Hidden.1" ) )
+ {
+ SetProcessSdrObj( false );
+ return;
+ }
+
+ if( rStrm.GetRecLeft() <= 8 ) return;
+
+ // position and size of control data in 'Ctls' stream
+ mnCtlsStrmPos = static_cast< sal_Size >( rStrm.ReaduInt32() );
+ mnCtlsStrmSize = static_cast< sal_Size >( rStrm.ReaduInt32() );
+
+ if( rStrm.GetRecLeft() <= 8 ) return;
+
+ // additional string (16-bit characters), e.g. for progress bar control
+ sal_uInt32 nAddStrSize;
+ rStrm >> nAddStrSize;
+ DBG_ASSERT( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" );
+ if( rStrm.GetRecLeft() >= nAddStrSize + 4 )
+ {
+ rStrm.Ignore( nAddStrSize );
+ // cell link and source range
+ ReadCellLinkFormula( rStrm, true );
+ ReadSourceRangeFormula( rStrm, true );
+ }
+ }
+ else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) )
+ {
+ rStrm >> mnStorageId;
+ }
+}
+
+// DFF stream conversion ======================================================
+
+//UNUSED2009-05 void XclImpSolverContainer::ReadSolverContainer( SvStream& rDffStrm )
+//UNUSED2009-05 {
+//UNUSED2009-05 rDffStrm >> *this;
+//UNUSED2009-05 }
+
+void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags )
+{
+ if( nDffShapeId > 0 )
+ {
+ maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags );
+ maSdrObjMap[ &rSdrObj ] = nDffShapeId;
+ }
+}
+
+void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject& rSdrObj )
+{
+ // remove info of passed object from the maps
+ XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj );
+ if( aIt != maSdrObjMap.end() )
+ {
+ maSdrInfoMap.erase( aIt->second );
+ maSdrObjMap.erase( aIt );
+ }
+
+ // remove info of all child objects of a group object
+ if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) )
+ {
+ if( SdrObjList* pSubList = pGroupObj->GetSubList() )
+ {
+ // iterate flat over the list because this function already works recursively
+ SdrObjListIter aObjIt( *pSubList, IM_FLAT );
+ for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() )
+ RemoveSdrObjectInfo( *pChildObj );
+ }
+ }
+}
+
+void XclImpSolverContainer::UpdateConnectorRules()
+{
+ for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
+ {
+ UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA );
+ UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB );
+ UpdateConnection( pRule->nShapeC, pRule->pCObj );
+ }
+}
+
+void XclImpSolverContainer::RemoveConnectorRules()
+{
+ // base class from SVX uses plain untyped tools/List
+ for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
+ delete pRule;
+ aCList.Clear();
+
+ maSdrInfoMap.clear();
+ maSdrObjMap.clear();
+}
+
+SvxMSDffConnectorRule* XclImpSolverContainer::GetFirstRule()
+{
+ return static_cast< SvxMSDffConnectorRule* >( aCList.First() );
+}
+
+SvxMSDffConnectorRule* XclImpSolverContainer::GetNextRule()
+{
+ return static_cast< SvxMSDffConnectorRule* >( aCList.Next() );
+}
+
+void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags )
+{
+ XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId );
+ if( aIt != maSdrInfoMap.end() )
+ {
+ rpSdrObj = aIt->second.mpSdrObj;
+ if( pnDffFlags )
+ *pnDffFlags = aIt->second.mnDffFlags;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
+ SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ),
+ XclImpRoot( rRoot )
+{
+ SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL );
+}
+
+XclImpSimpleDffConverter::~XclImpSimpleDffConverter()
+{
+}
+
+FASTBOOL XclImpSimpleDffConverter::GetColorFromPalette( USHORT nIndex, Color& rColor ) const
+{
+ ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) );
+
+ if( nColor == COL_AUTO )
+ return FALSE;
+
+ rColor.SetColor( nColor );
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDffConverter::XclImpDffConvData::XclImpDffConvData(
+ XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) :
+ mrDrawing( rDrawing ),
+ mrSdrModel( rSdrModel ),
+ mrSdrPage( rSdrPage ),
+ mnLastCtrlIndex( -1 ),
+ mbHasCtrlForm( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
+ XclImpSimpleDffConverter( rRoot, rDffStrm ),
+ SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ),
+ maStdFormName( CREATE_OUSTRING( "Standard" ) ),
+ mnOleImpFlags( 0 )
+{
+ if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
+ {
+ if( pFilterOpt->IsMathType2Math() )
+ mnOleImpFlags |= OLE_MATHTYPE_2_STARMATH;
+ if( pFilterOpt->IsWinWord2Writer() )
+ mnOleImpFlags |= OLE_WINWORD_2_STARWRITER;
+ if( pFilterOpt->IsPowerPoint2Impress() )
+ mnOleImpFlags |= OLE_POWERPOINT_2_STARIMPRESS;
+ }
+
+ // try to open the 'Ctls' storage stream containing OCX control properties
+ mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
+
+ // default text margin (convert EMU to drawing layer units)
+ mnDefTextMargin = EXC_OBJ_TEXT_MARGIN;
+ ScaleEmu( mnDefTextMargin );
+}
+
+XclImpDffConverter::~XclImpDffConverter()
+{
+}
+
+void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize )
+{
+ mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) );
+ mxProgress->AddSegment( nProgressSize );
+ mxProgress->Activate();
+}
+
+void XclImpDffConverter::Progress( sal_Size nDelta )
+{
+ DBG_ASSERT( mxProgress.is(), "XclImpDffConverter::Progress - invalid call, no progress bar" );
+ mxProgress->Progress( nDelta );
+}
+
+void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage )
+{
+ XclImpDffConvDataRef xConvData( new XclImpDffConvData( rDrawing, rSdrModel, rSdrPage ) );
+ maDataStack.push_back( xConvData );
+ SetModel( &xConvData->mrSdrModel, 1440 );
+}
+
+void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj )
+{
+ if( rDrawObj.IsProcessSdrObj() )
+ {
+ if( const XclObjAnchor* pAnchor = rDrawObj.GetAnchor() )
+ {
+ Rectangle aAnchorRect = GetConvData().mrDrawing.CalcAnchorRect( *pAnchor, false );
+ if( rDrawObj.IsValidSize( aAnchorRect ) )
+ {
+ // CreateSdrObject() recursively creates embedded child objects
+ SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( *this, aAnchorRect, false ) );
+ if( xSdrObj.is() )
+ rDrawObj.PreProcessSdrObject( *this, *xSdrObj );
+ // call InsertSdrObject() also, if SdrObject is missing
+ InsertSdrObject( rObjList, rDrawObj, xSdrObj.release() );
+ }
+ }
+ }
+}
+
+void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector& rDrawObjs )
+{
+ SdrPage& rSdrPage = GetConvData().mrSdrPage;
+ for( XclImpDrawObjVector::const_iterator aIt = rDrawObjs.begin(), aEnd = rDrawObjs.end(); aIt != aEnd; ++aIt )
+ ProcessObject( rSdrPage, **aIt );
+}
+
+void XclImpDffConverter::ProcessDrawing( SvStream& rDffStrm )
+{
+ rDffStrm.Seek( STREAM_SEEK_TO_END );
+ if( rDffStrm.Tell() > 0 )
+ {
+ rDffStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ DffRecordHeader aHeader;
+ rDffStrm >> aHeader;
+ DBG_ASSERT( aHeader.nRecType == DFF_msofbtDgContainer, "XclImpDffConverter::ProcessDrawing - unexpected record" );
+ if( aHeader.nRecType == DFF_msofbtDgContainer )
+ ProcessDgContainer( rDffStrm, aHeader );
+ }
+}
+
+void XclImpDffConverter::FinalizeDrawing()
+{
+ DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" );
+ maDataStack.pop_back();
+ // restore previous model at core DFF converter
+ if( !maDataStack.empty() )
+ SetModel( &maDataStack.back()->mrSdrModel, 1440 );
+}
+
+SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect )
+{
+ SdrObjectPtr xSdrObj;
+
+ OUString aServiceName = rTbxObj.GetServiceName();
+ if( SupportsOleObjects() && (aServiceName.getLength() > 0) ) try
+ {
+ // create the form control from scratch
+ Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW );
+ // set controls form, needed in virtual function InsertControl()
+ InitControlForm();
+ // try to insert the control into the form
+ ::com::sun::star::awt::Size aDummySize;
+ Reference< XShape > xShape;
+ XclImpDffConvData& rConvData = GetConvData();
+ if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) )
+ {
+ xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
+ // try to attach a macro to the control
+ ScriptEventDescriptor aDescriptor;
+ if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) )
+ {
+ Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW );
+ xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ return xSdrObj.release();
+}
+
+SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect )
+{
+ SdrObjectPtr xSdrObj;
+
+ if( SupportsOleObjects() )
+ {
+ if( rPicObj.IsOcxControl() )
+ {
+ if( mxCtlsStrm.Is() ) try
+ {
+ /* set controls form, needed in virtual function InsertControl()
+ called from ReadOCXExcelKludgeStream() */
+ InitControlForm();
+ // seek to stream position of the extra data for this control
+ mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() );
+ // read from mxCtlsStrm into xShape, insert the control model into the form
+ Reference< XShape > xShape;
+ if( GetConvData().mxCtrlForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) )
+ xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ else
+ {
+ SfxObjectShell* pDocShell = GetDocShell();
+ SotStorageRef xSrcStrg = GetRootStorage();
+ String aStrgName = rPicObj.GetOleStorageName();
+ if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) )
+ {
+ // first try to resolve graphic from DFF storage
+ Graphic aGraphic;
+ Rectangle aVisArea;
+ if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) )
+ {
+ // if not found, use graphic from object (imported from IMGDATA record)
+ aGraphic = rPicObj.GetGraphic();
+ aVisArea = rPicObj.GetVisArea();
+ }
+ if( aGraphic.GetType() != GRAPHIC_NONE )
+ {
+ ErrCode nError = ERRCODE_NONE;
+ namespace cssea = ::com::sun::star::embed::Aspects;
+ sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT;
+ xSdrObj.reset( CreateSdrOLEFromStorage(
+ aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic,
+ rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) );
+ }
+ }
+ }
+ }
+
+ return xSdrObj.release();
+}
+
+bool XclImpDffConverter::SupportsOleObjects() const
+{
+ return GetConvData().mrDrawing.SupportsOleObjects();
+}
+
+// virtual functions ----------------------------------------------------------
+
+void XclImpDffConverter::ProcessClientAnchor2( SvStream& rDffStrm,
+ DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData )
+{
+ // find the OBJ record data related to the processed shape
+ XclImpDffConvData& rConvData = GetConvData();
+ if( XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get() )
+ {
+ DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" );
+ XclObjAnchor aAnchor;
+ rHeader.SeekToContent( rDffStrm );
+ rDffStrm.SeekRel( 2 ); // flags
+ rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records
+ pDrawObj->SetAnchor( aAnchor );
+ rObjData.aChildAnchor = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true );
+ rObjData.bChildAnchor = sal_True;
+ }
+}
+
+SdrObject* XclImpDffConverter::ProcessObj( SvStream& rDffStrm, DffObjData& rDffObjData,
+ void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj )
+{
+ XclImpDffConvData& rConvData = GetConvData();
+
+ /* pOldSdrObj passes a generated SdrObject. This function owns this object
+ and can modify it. The function has either to return it back to caller
+ or to delete it by itself. */
+ SdrObjectPtr xSdrObj( pOldSdrObj );
+
+ // find the OBJ record data related to the processed shape
+ XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd );
+ const Rectangle& rAnchorRect = rDffObjData.aChildAnchor;
+
+ // #102378# Do not process the global page group shape (flag SP_FPATRIARCH)
+ bool bGlobalPageGroup = ::get_flag< sal_uInt32 >( rDffObjData.nSpFlags, SP_FPATRIARCH );
+ if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup )
+ return 0; // simply return, xSdrObj will be destroyed
+
+ /* Pass pointer to top-level object back to caller. If the processed
+ object is embedded in a group, the pointer is already set to the
+ top-level parent object. */
+ XclImpDrawObjBase** ppTopLevelObj = reinterpret_cast< XclImpDrawObjBase** >( pClientData );
+ bool bIsTopLevel = !ppTopLevelObj || !*ppTopLevelObj;
+ if( ppTopLevelObj && bIsTopLevel )
+ *ppTopLevelObj = xDrawObj.get();
+
+ // #119010# connectors don't have to be area objects
+ if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) )
+ xDrawObj->SetAreaObj( false );
+
+ /* Check for valid size for all objects. Needed to ignore lots of invisible
+ phantom objects from deleted rows or columns (for performance reasons).
+ #i30816# Include objects embedded in groups.
+ #i58780# Ignore group shapes, size is not initialized. */
+ bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() );
+ if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) )
+ return 0; // simply return, xSdrObj will be destroyed
+
+ // set shape information from DFF stream
+ String aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm );
+ String aHyperlink = ReadHlinkProperty( rDffStrm );
+ bool bVisible = !GetPropertyBool( DFF_Prop_fHidden );
+ bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin );
+ xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin );
+
+ /* Connect textbox data (string, alignment, text orientation) to object.
+ #98132# don't ask for a text-ID, DFF export doesn't set one. */
+ if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) )
+ if( const XclImpObjTextData* pTextData = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) )
+ pTextObj->SetTextData( *pTextData );
+
+ // copy line and fill formatting of TBX form controls from DFF properties
+ if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) )
+ pTbxObj->SetDffProperties( *this );
+
+ // try to create a custom SdrObject that overwrites the passed object
+ SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) );
+ if( xNewSdrObj.is() )
+ xSdrObj.reset( xNewSdrObj.release() );
+
+ // process the SdrObject
+ if( xSdrObj.is() )
+ {
+ // filled without color -> set system window color
+ if( GetPropertyBool( DFF_Prop_fFilled ) && !IsProperty( DFF_Prop_fillColor ) )
+ xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) );
+
+ // additional processing on the SdrObject
+ xDrawObj->PreProcessSdrObject( *this, *xSdrObj );
+
+ /* If the SdrObject will not be inserted into the draw page, delete it
+ here. Happens e.g. for notes: The PreProcessSdrObject() call above
+ has inserted the note into the document, and the SdrObject is not
+ needed anymore. */
+ if( !xDrawObj->IsInsertSdrObj() )
+ xSdrObj.reset();
+ }
+
+ if( xSdrObj.is() )
+ {
+ /* Store the relation between shape ID and SdrObject for connectors.
+ Must be done here (and not in InsertSdrObject() function),
+ otherwise all SdrObjects embedded in groups would be lost. */
+ rConvData.maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() );
+
+ /* If the drawing object is embedded in a group object, call
+ PostProcessSdrObject() here. For top-level objects this will be
+ done automatically in InsertSdrObject() but grouped shapes are
+ inserted into their groups somewhere in the SvxMSDffManager base
+ class without chance of notification. Unfortunately, now this is
+ called before the object is really inserted into its group object,
+ but that should not have any effect for grouped objects. */
+ if( !bIsTopLevel )
+ xDrawObj->PostProcessSdrObject( *this, *xSdrObj );
+ }
+
+ return xSdrObj.release();
+}
+
+ULONG XclImpDffConverter::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const
+{
+ return nStreamPos + 4;
+}
+
+sal_Bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp,
+ const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape,
+ BOOL /*bFloatingCtrl*/ )
+{
+ if( GetDocShell() ) try
+ {
+ XclImpDffConvData& rConvData = GetConvData();
+ Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW );
+ Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW );
+
+ // create the control shape
+ Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW );
+ Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW );
+
+ // insert the new control into the form
+ sal_Int32 nNewIndex = xFormIC->getCount();
+ xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) );
+ // on success: store new index of the control for later use (macro events)
+ rConvData.mnLastCtrlIndex = nNewIndex;
+
+ // set control model at control shape and pass back shape to caller
+ xCtrlShape->setControl( xCtrlModel );
+ if( pxShape ) *pxShape = xShape;
+ return sal_True;
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpDffConverter::InsertControl - cannot create form control" );
+ }
+
+ return sal_False;
+}
+
+// private --------------------------------------------------------------------
+
+XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData()
+{
+ DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
+ return *maDataStack.back();
+}
+
+const XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() const
+{
+ DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
+ return *maDataStack.back();
+}
+
+String XclImpDffConverter::ReadHlinkProperty( SvStream& rDffStrm ) const
+{
+ /* Reads hyperlink data from a complex DFF property. Contents of this
+ property are equal to the HLINK record, import of this record is
+ implemented in class XclImpHyperlink. This function has to create an
+ instance of the XclImpStream class to be able to reuse the
+ functionality of XclImpHyperlink. */
+ String aString;
+ sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
+ if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) )
+ {
+ // create a faked BIFF record that can be read by XclImpStream class
+ SvMemoryStream aMemStream;
+ aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize );
+
+ // copy from DFF stream to memory stream
+ ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
+ sal_uInt8* pnData = &aBuffer.front();
+ if( rDffStrm.Read( pnData, nBufferSize ) == nBufferSize )
+ {
+ aMemStream.Write( pnData, nBufferSize );
+
+ // create BIFF import stream to be able to use XclImpHyperlink class
+ XclImpStream aXclStrm( aMemStream, GetRoot() );
+ if( aXclStrm.StartNextRecord() )
+ aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm );
+ }
+ }
+ return aString;
+}
+
+void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
+{
+ sal_Size nEndPos = rDgHeader.GetRecEndFilePos();
+ while( rDffStrm.Tell() < nEndPos )
+ {
+ DffRecordHeader aHeader;
+ rDffStrm >> aHeader;
+ switch( aHeader.nRecType )
+ {
+ case DFF_msofbtSolverContainer:
+ ProcessSolverContainer( rDffStrm, aHeader );
+ break;
+ case DFF_msofbtSpgrContainer:
+ ProcessShGrContainer( rDffStrm, aHeader );
+ break;
+ default:
+ aHeader.SeekToEndOfRecord( rDffStrm );
+ }
+ }
+ // seek to end of drawing page container
+ rDgHeader.SeekToEndOfRecord( rDffStrm );
+
+ // #i12638# #i37900# connector rules
+ XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont;
+ rSolverCont.UpdateConnectorRules();
+ SolveSolver( rSolverCont );
+ rSolverCont.RemoveConnectorRules();
+}
+
+void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
+{
+ sal_Size nEndPos = rShGrHeader.GetRecEndFilePos();
+ while( rDffStrm.Tell() < nEndPos )
+ {
+ DffRecordHeader aHeader;
+ rDffStrm >> aHeader;
+ switch( aHeader.nRecType )
+ {
+ case DFF_msofbtSpgrContainer:
+ case DFF_msofbtSpContainer:
+ ProcessShContainer( rDffStrm, aHeader );
+ break;
+ default:
+ aHeader.SeekToEndOfRecord( rDffStrm );
+ }
+ }
+ // seek to end of shape group container
+ rShGrHeader.SeekToEndOfRecord( rDffStrm );
+}
+
+void XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
+{
+ // solver container wants to read the solver container header again
+ rSolverHeader.SeekToBegOfRecord( rDffStrm );
+ // read the entire solver container
+ rDffStrm >> GetConvData().maSolverCont;
+ // seek to end of solver container
+ rSolverHeader.SeekToEndOfRecord( rDffStrm );
+}
+
+void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
+{
+ rShHeader.SeekToBegOfRecord( rDffStrm );
+ Rectangle aDummy;
+ const XclImpDrawObjBase* pDrawObj = 0;
+ /* The call to ImportObj() creates and returns a new SdrObject for the
+ processed shape. We take ownership of the returned object here. If the
+ shape is a group object, all embedded objects are created recursively,
+ and the returned group object contains them all. ImportObj() calls the
+ virtual functions ProcessClientAnchor2() and ProcessObj() and writes
+ the pointer to the related draw object data (OBJ record) into pDrawObj. */
+ SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) );
+ if( pDrawObj && xSdrObj.is() )
+ InsertSdrObject( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() );
+ rShHeader.SeekToEndOfRecord( rDffStrm );
+}
+
+void XclImpDffConverter::InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj )
+{
+ XclImpDffConvData& rConvData = GetConvData();
+ /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
+ states to skip insertion), the object is automatically deleted. */
+ SdrObjectPtr xSdrObj( pSdrObj );
+ if( xSdrObj.is() && rDrawObj.IsInsertSdrObj() )
+ {
+ rObjList.NbcInsertObject( xSdrObj.release() );
+ // callback to drawing manager for e.g. tracking of used sheet area
+ rConvData.mrDrawing.OnObjectInserted( rDrawObj );
+ // callback to drawing object for post processing (use pSdrObj, xSdrObj already released)
+ rDrawObj.PostProcessSdrObject( *this, *pSdrObj );
+ }
+ /* SdrObject still here? Insertion failed, remove data from shape ID map.
+ The SdrObject will be destructed then. */
+ if( xSdrObj.is() )
+ rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj );
+}
+
+void XclImpDffConverter::InitControlForm()
+{
+ XclImpDffConvData& rConvData = GetConvData();
+ if( rConvData.mbHasCtrlForm )
+ return;
+
+ rConvData.mbHasCtrlForm = true;
+ if( SupportsOleObjects() ) try
+ {
+ Reference< XFormsSupplier > xFormsSupplier( rConvData.mrSdrPage.getUnoPage(), UNO_QUERY_THROW );
+ Reference< XNameContainer > xFormsNC( xFormsSupplier->getForms(), UNO_SET_THROW );
+ // find or create the Standard form used to insert the imported controls
+ if( xFormsNC->hasByName( maStdFormName ) )
+ {
+ xFormsNC->getByName( maStdFormName ) >>= rConvData.mxCtrlForm;
+ }
+ else if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ rConvData.mxCtrlForm.set( ScfApiHelper::CreateInstance( pDocShell, CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW );
+ xFormsNC->insertByName( maStdFormName, Any( rConvData.mxCtrlForm ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// Drawing manager ============================================================
+
+XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) :
+ XclImpRoot( rRoot ),
+ mbOleObjs( bOleObjects )
+{
+}
+
+XclImpDrawing::~XclImpDrawing()
+{
+}
+
+/*static*/ Graphic XclImpDrawing::ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ Graphic aGraphic;
+ sal_uInt16 nFormat, nEnv;
+ sal_uInt32 nDataSize;
+ rStrm >> nFormat >> nEnv >> nDataSize;
+ if( nDataSize <= rStrm.GetRecLeft() )
+ {
+ switch( nFormat )
+ {
+ case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rRoot, rStrm ); break;
+ case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rRoot, rStrm ); break;
+ default: DBG_ERRORFILE( "XclImpDrawing::ReadImgData - unknown image format" );
+ }
+ }
+ return aGraphic;
+}
+
+void XclImpDrawing::ReadObj( XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
+ records. In this case, the OBJ records are in BIFF5 format. Do a sanity
+ check here that there is no DFF data loaded before. */
+ DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
+ if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
+ {
+ case EXC_BIFF3:
+ xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm );
+ break;
+ case EXC_BIFF4:
+ xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm );
+ break;
+ case EXC_BIFF5:
+ case EXC_BIFF8:
+ xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+
+ if( xDrawObj.is() )
+ {
+ // insert into maRawObjs or into the last open group object
+ maRawObjs.InsertGrouped( xDrawObj );
+ // to be able to find objects by ID
+ maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
+ }
+}
+
+void XclImpDrawing::ReadMsoDrawing( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+ // disable internal CONTINUE handling
+ rStrm.ResetRecord( false );
+ // read leading MSODRAWING record
+ ReadDffRecord( rStrm );
+
+ // read following drawing records, but do not start following unrelated record
+ bool bLoop = true;
+ while( bLoop ) switch( rStrm.GetNextRecId() )
+ {
+ case EXC_ID_MSODRAWING:
+ case EXC_ID_MSODRAWINGSEL:
+ case EXC_ID_CONT:
+ rStrm.StartNextRecord();
+ ReadDffRecord( rStrm );
+ break;
+ case EXC_ID_OBJ:
+ rStrm.StartNextRecord();
+ ReadObj8( rStrm );
+ break;
+ case EXC_ID_TXO:
+ rStrm.StartNextRecord();
+ ReadTxo( rStrm );
+ break;
+ default:
+ bLoop = false;
+ }
+
+ // re-enable internal CONTINUE handling
+ rStrm.ResetRecord( true );
+}
+
+XclImpDrawObjRef XclImpDrawing::FindDrawObj( const DffRecordHeader& rHeader ) const
+{
+ /* maObjMap stores objects by position of the client data (OBJ record) in
+ the DFF stream, which is always behind shape start position of the
+ passed header. The function upper_bound() finds the first element in
+ the map whose key is greater than the start position of the header. Its
+ end position is used to test whether the found object is really related
+ to the shape. */
+ XclImpDrawObjRef xDrawObj;
+ XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() );
+ if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
+ xDrawObj = aIt->second;
+ return xDrawObj;
+}
+
+XclImpDrawObjRef XclImpDrawing::FindDrawObj( sal_uInt16 nObjId ) const
+{
+ XclImpDrawObjRef xDrawObj;
+ XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId );
+ if( aIt != maObjMapId.end() )
+ xDrawObj = aIt->second;
+ return xDrawObj;
+}
+
+const XclImpObjTextData* XclImpDrawing::FindTextData( const DffRecordHeader& rHeader ) const
+{
+ /* maTextMap stores textbox data by position of the client data (TXO
+ record) in the DFF stream, which is always behind shape start position
+ of the passed header. The function upper_bound() finds the first
+ element in the map whose key is greater than the start position of the
+ header. Its end position is used to test whether the found object is
+ really related to the shape. */
+ XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() );
+ if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
+ return aIt->second.get();
+ return 0;
+}
+
+void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId )
+{
+ maSkipObjs.push_back( nObjId );
+}
+
+sal_Size XclImpDrawing::GetProgressSize() const
+{
+ sal_Size nProgressSize = maRawObjs.GetProgressSize();
+ for( XclImpObjMap::const_iterator aIt = maObjMap.begin(), aEnd = maObjMap.end(); aIt != aEnd; ++aIt )
+ nProgressSize += aIt->second->GetProgressSize();
+ return nProgressSize;
+}
+
+void XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage )
+{
+ // register this drawing manager at the passed (global) DFF manager
+ rDffConv.InitializeDrawing( *this, rSdrModel, rSdrPage );
+ // process list of objects to be skipped
+ for( ScfUInt16Vec::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt )
+ if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aIt ).get() )
+ pDrawObj->SetProcessSdrObj( false );
+ // process drawing objects without DFF data
+ rDffConv.ProcessDrawing( maRawObjs );
+ // process all objects in the DFF stream
+ rDffConv.ProcessDrawing( maDffStrm );
+ // unregister this drawing manager at the passed (global) DFF manager
+ rDffConv.FinalizeDrawing();
+}
+
+// protected ------------------------------------------------------------------
+
+void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef& rxDrawObj )
+{
+ DBG_ASSERT( rxDrawObj.is(), "XclImpDrawing::AppendRawObject - unexpected empty reference" );
+ maRawObjs.push_back( rxDrawObj );
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpDrawing::ReadWmf( Graphic& rGraphic, const XclImpRoot&, XclImpStream& rStrm ) // static helper
+{
+ // extract graphic data from IMGDATA and following CONTINUE records
+ rStrm.Ignore( 8 );
+ SvMemoryStream aMemStrm;
+ rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ // import the graphic from memory stream
+ GDIMetaFile aGDIMetaFile;
+ if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile, 0 ) )
+ rGraphic = aGDIMetaFile;
+}
+
+void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper
+{
+ // extract graphic data from IMGDATA and following CONTINUE records
+ SvMemoryStream aMemStrm;
+
+ /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
+ DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
+ pixel depth = 32 bit. After that, 3 unused bytes are added before the
+ actual pixel data. This does even confuse Excel 5 and later, which
+ cannot read the image data correctly. */
+ if( rRoot.GetBiff() <= EXC_BIFF4 )
+ {
+ rStrm.PushPosition();
+ sal_uInt32 nHdrSize;
+ sal_uInt16 nWidth, nHeight, nPlanes, nDepth;
+ rStrm >> nHdrSize >> nWidth >> nHeight >> nPlanes >> nDepth;
+ if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) )
+ {
+ rStrm.Ignore( 3 );
+ aMemStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ aMemStrm << nHdrSize << nWidth << nHeight << nPlanes << nDepth;
+ rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
+ }
+ rStrm.PopPosition();
+ }
+
+ // no special handling above -> just copy the remaining record data
+ if( aMemStrm.Tell() == 0 )
+ rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
+
+ // import the graphic from memory stream
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ Bitmap aBitmap;
+ if( aBitmap.Read( aMemStrm, FALSE ) ) // read DIB without file header
+ rGraphic = aBitmap;
+}
+
+void XclImpDrawing::ReadDffRecord( XclImpStream& rStrm )
+{
+ maDffStrm.Seek( STREAM_SEEK_TO_END );
+ rStrm.CopyRecordToStream( maDffStrm );
+}
+
+void XclImpDrawing::ReadObj8( XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm );
+ // store the new object in the internal containers
+ maObjMap[ maDffStrm.Tell() ] = xDrawObj;
+ maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
+}
+
+void XclImpDrawing::ReadTxo( XclImpStream& rStrm )
+{
+ XclImpObjTextRef xTextData( new XclImpObjTextData );
+ maTextMap[ maDffStrm.Tell() ] = xTextData;
+
+ // 1) read the TXO record
+ xTextData->maData.ReadTxo8( rStrm );
+
+ // 2) first CONTINUE with string
+ xTextData->mxString.reset();
+ bool bValid = true;
+ if( xTextData->maData.mnTextLen > 0 )
+ {
+ bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
+ DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
+ if( bValid )
+ xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) );
+ }
+
+ // 3) second CONTINUE with formatting runs
+ if( xTextData->maData.mnFormatSize > 0 )
+ {
+ bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
+ DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
+ if( bValid )
+ xTextData->ReadFormats( rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ) :
+ XclImpDrawing( rRoot, true ),
+ maScUsedArea( ScAddress::INITIALIZE_INVALID )
+{
+ maScUsedArea.aStart.SetTab( nScTab );
+ maScUsedArea.aEnd.SetTab( nScTab );
+}
+
+void XclImpSheetDrawing::ReadNote( XclImpStream& rStrm )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ ReadNote3( rStrm );
+ break;
+ case EXC_BIFF8:
+ ReadNote8( rStrm );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+void XclImpSheetDrawing::ReadTabChart( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 );
+ ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) );
+ xChartObj->ReadChartSubStream( rStrm );
+ // insert the chart as raw object without connected DFF data
+ AppendRawObject( xChartObj );
+}
+
+void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter& rDffConv )
+{
+ if( SdrModel* pSdrModel = GetDoc().GetDrawLayer() )
+ if( SdrPage* pSdrPage = GetSdrPage( maScUsedArea.aStart.Tab() ) )
+ ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
+}
+
+Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const
+{
+ return rAnchor.GetRect( GetRoot(), maScUsedArea.aStart.Tab(), MAP_100TH_MM );
+}
+
+void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase& rDrawObj )
+{
+ ScRange aScObjArea = rDrawObj.GetUsedArea( maScUsedArea.aStart.Tab() );
+ if( aScObjArea.IsValid() )
+ maScUsedArea.ExtendTo( aScObjArea );
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpSheetDrawing::ReadNote3( XclImpStream& rStrm )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nTotalLen;
+ rStrm >> aXclPos >> nTotalLen;
+
+ ScAddress aScNotePos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
+ {
+ sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) );
+ String aNoteText = rStrm.ReadRawByteString( nPartLen );
+ nTotalLen = nTotalLen - nPartLen;
+ while( (nTotalLen > 0) && (rStrm.GetNextRecId() == EXC_ID_NOTE) && rStrm.StartNextRecord() )
+ {
+ rStrm >> aXclPos >> nPartLen;
+ DBG_ASSERT( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
+ if( aXclPos.mnRow == 0xFFFF )
+ {
+ DBG_ASSERT( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" );
+ aNoteText.Append( rStrm.ReadRawByteString( nPartLen ) );
+ nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen );
+ }
+ else
+ {
+ // seems to be a new note, record already started -> load the note
+ rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
+ ReadNote( rStrm );
+ nTotalLen = 0;
+ }
+ }
+ ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false );
+ }
+}
+
+void XclImpSheetDrawing::ReadNote8( XclImpStream& rStrm )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nFlags, nObjId;
+ rStrm >> aXclPos >> nFlags >> nObjId;
+
+ ScAddress aScNotePos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
+ if( nObjId != EXC_OBJ_INVALID_ID )
+ if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) )
+ pNoteObj->SetNoteData( aScNotePos, nFlags );
+}
+
+// The object manager =========================================================
+
+XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+ maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" );
+ maDefObjNames[ EXC_OBJTYPE_LINE ] = CREATE_STRING( "Line" );
+ maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = CREATE_STRING( "Rectangle" );
+ maDefObjNames[ EXC_OBJTYPE_OVAL ] = CREATE_STRING( "Oval" );
+ maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" );
+ maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" );
+ maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" );
+ maDefObjNames[ EXC_OBJTYPE_BUTTON ] = CREATE_STRING( "Button" );
+ maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" );
+ maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" );
+ maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = CREATE_STRING( "Check Box" );
+ maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = CREATE_STRING( "Option Button" );
+ maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" );
+ maDefObjNames[ EXC_OBJTYPE_LABEL ] = CREATE_STRING( "Label" );
+ maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" );
+ maDefObjNames[ EXC_OBJTYPE_SPIN ] = CREATE_STRING( "Spinner" );
+ maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = CREATE_STRING( "Scroll Bar" );
+ maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = CREATE_STRING( "List Box" );
+ maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = CREATE_STRING( "Group Box" );
+ maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = CREATE_STRING( "Drop Down" );
+ maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" );
+ maDefObjNames[ EXC_OBJTYPE_DRAWING ] = CREATE_STRING( "AutoShape" );
+}
+
+XclImpObjectManager::~XclImpObjectManager()
+{
+}
+
+void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+ // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
+ rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP );
+ maDggStrm.Seek( STREAM_SEEK_TO_END );
+ rStrm.CopyRecordToStream( maDggStrm );
+}
+
+XclImpSheetDrawing& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab )
+{
+ XclImpSheetDrawingRef& rxDrawing = maSheetDrawings[ nScTab ];
+ if( !rxDrawing )
+ rxDrawing.reset( new XclImpSheetDrawing( GetRoot(), nScTab ) );
+ return *rxDrawing;
+}
+
+void XclImpObjectManager::ConvertObjects()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
+
+ // do nothing if the document does not contain a drawing layer
+ if( !GetDoc().GetDrawLayer() )
+ return;
+
+ // get total progress bar size for all sheet drawing managers
+ sal_Size nProgressSize = 0;
+ for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt )
+ nProgressSize += aIt->second->GetProgressSize();
+ // nothing to do if progress bar is zero (no objects present)
+ if( nProgressSize == 0 )
+ return;
+
+ XclImpDffConverter aDffConv( GetRoot(), maDggStrm );
+ aDffConv.StartProgressBar( nProgressSize );
+ for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt )
+ aIt->second->ConvertObjects( aDffConv );
+
+ // #i112436# don't call ScChartListenerCollection::SetDirty here,
+ // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad.
+}
+
+String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const
+{
+ String aDefName;
+ DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() );
+ if( aIt != maDefObjNames.end() )
+ aDefName.Append( aIt->second );
+ return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId() ) );
+}
+
+ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const
+{
+ XclImpSheetDrawingMap::const_iterator aIt = maSheetDrawings.find( nScTab );
+ if( aIt != maSheetDrawings.end() )
+ return aIt->second->GetUsedArea();
+ return ScRange( ScAddress::INITIALIZE_INVALID );
+}
+
+// DFF property set helper ====================================================
+
+XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maDffConv( rRoot, maDummyStrm )
+{
+}
+
+void XclImpDffPropSet::Read( XclImpStream& rStrm )
+{
+ sal_uInt32 nPropSetSize;
+
+ rStrm.PushPosition();
+ rStrm.Ignore( 4 );
+ rStrm >> nPropSetSize;
+ rStrm.PopPosition();
+
+ mxMemStrm.reset( new SvMemoryStream );
+ rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize );
+ mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ maDffConv.ReadPropSet( *mxMemStrm, 0 );
+}
+
+sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const
+{
+ return maDffConv.GetPropertyValue( nPropId, nDefault );
+}
+
+void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const
+{
+ if( mxMemStrm.get() )
+ maDffConv.ApplyAttributes( *mxMemStrm, rItemSet );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet )
+{
+ rPropSet.Read( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xiformula.cxx b/sc/source/filter/excel/xiformula.cxx
new file mode 100644
index 000000000000..40c6ef9be374
--- /dev/null
+++ b/sc/source/filter/excel/xiformula.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sc.hxx"
+#include "xiformula.hxx"
+#include "rangelst.hxx"
+#include "xistream.hxx"
+
+#include "excform.hxx"
+
+// Formula compiler ===========================================================
+
+/** Implementation class of the export formula compiler. */
+class XclImpFmlaCompImpl : protected XclImpRoot, protected XclTokenArrayHelper
+{
+public:
+ explicit XclImpFmlaCompImpl( const XclImpRoot& rRoot );
+
+ /** Creates a range list from the passed Excel token array. */
+ void CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType eType,
+ const XclTokenArray& rXclTokArr, XclImpStream& rStrm );
+
+ const ScTokenArray* CreateFormula( XclFormulaType eType, const XclTokenArray& rXclTokArr );
+
+ // ------------------------------------------------------------------------
+private:
+ XclFunctionProvider maFuncProv; /// Excel function data provider.
+ const XclBiff meBiff; /// Cached BIFF version to save GetBiff() calls.
+};
+
+// ----------------------------------------------------------------------------
+
+XclImpFmlaCompImpl::XclImpFmlaCompImpl( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() )
+{
+}
+
+void XclImpFmlaCompImpl::CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType /*eType*/,
+ const XclTokenArray& rXclTokArr, XclImpStream& /*rStrm*/ )
+{
+ rScRanges.RemoveAll();
+
+ //! evil hack, using old formula import :-)
+ if( !rXclTokArr.Empty() )
+ {
+ SvMemoryStream aMemStrm;
+ aMemStrm << EXC_ID_EOF << rXclTokArr.GetSize();
+ aMemStrm.Write( rXclTokArr.GetData(), rXclTokArr.GetSize() );
+ XclImpStream aFmlaStrm( aMemStrm, GetRoot() );
+ aFmlaStrm.StartNextRecord();
+ GetOldFmlaConverter().GetAbsRefs( rScRanges, aFmlaStrm, aFmlaStrm.GetRecSize() );
+ }
+}
+
+const ScTokenArray* XclImpFmlaCompImpl::CreateFormula(
+ XclFormulaType /*eType*/, const XclTokenArray& rXclTokArr )
+{
+ if (rXclTokArr.Empty())
+ return NULL;
+
+ // evil hack! are we trying to phase out the old style formula converter ?
+ SvMemoryStream aMemStrm;
+ aMemStrm << EXC_ID_EOF << rXclTokArr.GetSize();
+ aMemStrm.Write( rXclTokArr.GetData(), rXclTokArr.GetSize() );
+ XclImpStream aFmlaStrm( aMemStrm, GetRoot() );
+ aFmlaStrm.StartNextRecord();
+ const ScTokenArray* pArray = NULL;
+ GetOldFmlaConverter().Reset();
+ GetOldFmlaConverter().Convert(pArray, aFmlaStrm, aFmlaStrm.GetRecSize(), true);
+ return pArray;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpFormulaCompiler::XclImpFormulaCompiler( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mxImpl( new XclImpFmlaCompImpl( rRoot ) )
+{
+}
+
+XclImpFormulaCompiler::~XclImpFormulaCompiler()
+{
+}
+
+void XclImpFormulaCompiler::CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType eType,
+ const XclTokenArray& rXclTokArr, XclImpStream& rStrm )
+{
+ mxImpl->CreateRangeList( rScRanges, eType, rXclTokArr, rStrm );
+}
+
+const ScTokenArray* XclImpFormulaCompiler::CreateFormula(
+ XclFormulaType eType, const XclTokenArray& rXclTokArr )
+{
+ return mxImpl->CreateFormula(eType, rXclTokArr);
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xihelper.cxx b/sc/source/filter/excel/xihelper.cxx
new file mode 100644
index 000000000000..ad04a1f3930c
--- /dev/null
+++ b/sc/source/filter/excel/xihelper.cxx
@@ -0,0 +1,918 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xihelper.hxx"
+#include <svl/itemset.hxx>
+#include <editeng/editobj.hxx>
+#include <tools/urlobj.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include "document.hxx"
+#include "cell.hxx"
+#include "rangelst.hxx"
+#include "editutil.hxx"
+#include "attrib.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xistyle.hxx"
+
+#include "excform.hxx"
+
+// Excel->Calc cell address/range conversion ==================================
+
+namespace {
+
+/** Fills the passed Calc address with the passed Excel cell coordinates without checking any limits. */
+inline void lclFillAddress( ScAddress& rScPos, sal_uInt16 nXclCol, sal_uInt16 nXclRow, SCTAB nScTab )
+{
+ rScPos.SetCol( static_cast< SCCOL >( nXclCol ) );
+ rScPos.SetRow( static_cast< SCROW >( nXclRow ) );
+ rScPos.SetTab( nScTab );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclImpAddressConverter::XclImpAddressConverter( const XclImpRoot& rRoot ) :
+ XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetScMaxPos() )
+{
+}
+
+// cell address ---------------------------------------------------------------
+
+bool XclImpAddressConverter::CheckAddress( const XclAddress& rXclPos, bool bWarn )
+{
+ bool bValidCol = rXclPos.mnCol <= mnMaxCol;
+ bool bValidRow = rXclPos.mnRow <= mnMaxRow;
+ bool bValid = bValidCol && bValidRow;
+ if( !bValid && bWarn )
+ {
+ mbColTrunc |= !bValidCol;
+ mbRowTrunc |= !bValidRow;
+ mrTracer.TraceInvalidAddress( ScAddress(
+ static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), 0 ), maMaxPos );
+ }
+ return bValid;
+}
+
+bool XclImpAddressConverter::ConvertAddress( ScAddress& rScPos,
+ const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
+{
+ bool bValid = CheckAddress( rXclPos, bWarn );
+ if( bValid )
+ lclFillAddress( rScPos, rXclPos.mnCol, rXclPos.mnRow, nScTab );
+ return bValid;
+}
+
+ScAddress XclImpAddressConverter::CreateValidAddress(
+ const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
+{
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( !ConvertAddress( aScPos, rXclPos, nScTab, bWarn ) )
+ {
+ aScPos.SetCol( static_cast< SCCOL >( ::std::min( rXclPos.mnCol, mnMaxCol ) ) );
+ aScPos.SetRow( static_cast< SCROW >( ::std::min( rXclPos.mnRow, mnMaxRow ) ) );
+ aScPos.SetTab( limit_cast< SCTAB >( nScTab, 0, maMaxPos.Tab() ) );
+ }
+ return aScPos;
+}
+
+// cell range -----------------------------------------------------------------
+
+bool XclImpAddressConverter::CheckRange( const XclRange& rXclRange, bool bWarn )
+{
+ return CheckAddress( rXclRange.maFirst, bWarn ) && CheckAddress( rXclRange.maLast, bWarn );
+}
+
+bool XclImpAddressConverter::ConvertRange( ScRange& rScRange,
+ const XclRange& rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn )
+{
+ // check start position
+ bool bValidStart = CheckAddress( rXclRange.maFirst, bWarn );
+ if( bValidStart )
+ {
+ lclFillAddress( rScRange.aStart, rXclRange.maFirst.mnCol, rXclRange.maFirst.mnRow, nScTab1 );
+
+ // check & correct end position
+ sal_uInt16 nXclCol2 = rXclRange.maLast.mnCol;
+ sal_uInt16 nXclRow2 = rXclRange.maLast.mnRow;
+ if( !CheckAddress( rXclRange.maLast, bWarn ) )
+ {
+ nXclCol2 = ::std::min( nXclCol2, mnMaxCol );
+ nXclRow2 = ::std::min( nXclRow2, mnMaxRow );
+ }
+ lclFillAddress( rScRange.aEnd, nXclCol2, nXclRow2, nScTab2 );
+ }
+ return bValidStart;
+}
+
+//UNUSED2009-05 ScRange XclImpAddressConverter::CreateValidRange(
+//UNUSED2009-05 const XclRange& rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn )
+//UNUSED2009-05 {
+//UNUSED2009-05 return ScRange(
+//UNUSED2009-05 CreateValidAddress( rXclRange.maFirst, nScTab1, bWarn ),
+//UNUSED2009-05 CreateValidAddress( rXclRange.maLast, nScTab2, bWarn ) );
+//UNUSED2009-05 }
+
+// cell range list ------------------------------------------------------------
+
+//UNUSED2009-05 bool XclImpAddressConverter::CheckRangeList( const XclRangeList& rXclRanges, bool bWarn )
+//UNUSED2009-05 {
+//UNUSED2009-05 for( XclRangeList::const_iterator aIt = rXclRanges.begin(), aEnd = rXclRanges.end(); aIt != aEnd; ++aIt )
+//UNUSED2009-05 if( !CheckRange( *aIt, bWarn ) )
+//UNUSED2009-05 return false;
+//UNUSED2009-05 return true;
+//UNUSED2009-05 }
+
+void XclImpAddressConverter::ConvertRangeList( ScRangeList& rScRanges,
+ const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn )
+{
+ rScRanges.RemoveAll();
+ for( XclRangeList::const_iterator aIt = rXclRanges.begin(), aEnd = rXclRanges.end(); aIt != aEnd; ++aIt )
+ {
+ ScRange aScRange( ScAddress::UNINITIALIZED );
+ if( ConvertRange( aScRange, *aIt, nScTab, nScTab, bWarn ) )
+ rScRanges.Append( aScRange );
+ }
+}
+
+// String->EditEngine conversion ==============================================
+
+namespace {
+
+EditTextObject* lclCreateTextObject( const XclImpRoot& rRoot,
+ const XclImpString& rString, XclFontItemType eType, sal_uInt16 nXFIndex )
+{
+ EditTextObject* pTextObj = 0;
+
+ const XclImpXFBuffer& rXFBuffer = rRoot.GetXFBuffer();
+ const XclImpFont* pFirstFont = rXFBuffer.GetFont( nXFIndex );
+ bool bFirstEscaped = pFirstFont && pFirstFont->HasEscapement();
+
+ if( rString.IsRich() || bFirstEscaped )
+ {
+ const XclImpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
+ const XclFormatRunVec& rFormats = rString.GetFormats();
+
+ ScEditEngineDefaulter& rEE = (eType == EXC_FONTITEM_NOTE) ?
+ static_cast< ScEditEngineDefaulter& >( rRoot.GetDoc().GetNoteEngine() ) : rRoot.GetEditEngine();
+ rEE.SetText( rString.GetText() );
+
+ SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
+ if( bFirstEscaped )
+ rFontBuffer.FillToItemSet( aItemSet, eType, rXFBuffer.GetFontIndex( nXFIndex ) );
+ ESelection aSelection;
+
+ XclFormatRun aNextRun;
+ XclFormatRunVec::const_iterator aIt = rFormats.begin();
+ XclFormatRunVec::const_iterator aEnd = rFormats.end();
+
+ if( aIt != aEnd )
+ aNextRun = *aIt++;
+ else
+ aNextRun.mnChar = 0xFFFF;
+
+ xub_StrLen nLen = rString.GetText().Len();
+ for( sal_uInt16 nChar = 0; nChar < nLen; ++nChar )
+ {
+ // reached new different formatted text portion
+ if( nChar >= aNextRun.mnChar )
+ {
+ // send items to edit engine
+ rEE.QuickSetAttribs( aItemSet, aSelection );
+
+ // start new item set
+ aItemSet.ClearItem();
+ rFontBuffer.FillToItemSet( aItemSet, eType, aNextRun.mnFontIdx );
+
+ // read new formatting information
+ if( aIt != aEnd )
+ aNextRun = *aIt++;
+ else
+ aNextRun.mnChar = 0xFFFF;
+
+ // reset selection start to current position
+ aSelection.nStartPara = aSelection.nEndPara;
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+
+ // set end of selection to current position
+ if( rString.GetText().GetChar( nChar ) == '\n' )
+ {
+ ++aSelection.nEndPara;
+ aSelection.nEndPos = 0;
+ }
+ else
+ ++aSelection.nEndPos;
+ }
+
+ // send items of last text portion to edit engine
+ rEE.QuickSetAttribs( aItemSet, aSelection );
+
+ pTextObj = rEE.CreateTextObject();
+ }
+
+ return pTextObj;
+}
+
+} // namespace
+
+EditTextObject* XclImpStringHelper::CreateTextObject(
+ const XclImpRoot& rRoot, const XclImpString& rString )
+{
+ return lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, 0 );
+}
+
+//UNUSED2009-05 EditTextObject* XclImpStringHelper::CreateNoteObject(
+//UNUSED2009-05 const XclImpRoot& rRoot, const XclImpString& rString )
+//UNUSED2009-05 {
+//UNUSED2009-05 return lclCreateTextObject( rRoot, rString, EXC_FONTITEM_NOTE, 0 );
+//UNUSED2009-05 }
+
+ScBaseCell* XclImpStringHelper::CreateCell(
+ const XclImpRoot& rRoot, const XclImpString& rString, sal_uInt16 nXFIndex )
+{
+ ScBaseCell* pCell = 0;
+
+ if( rString.GetText().Len() )
+ {
+ ::std::auto_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, nXFIndex ) );
+ ScDocument& rDoc = rRoot.GetDoc();
+
+ if( pTextObj.get() )
+ // ScEditCell creates own copy of text object
+ pCell = new ScEditCell( pTextObj.get(), &rDoc, rRoot.GetEditEngine().GetEditTextObjectPool() );
+ else
+ pCell = ScBaseCell::CreateTextCell( rString.GetText(), &rDoc );
+ }
+
+ return pCell;
+}
+
+// Header/footer conversion ===================================================
+
+XclImpHFConverter::XclImpHFPortionInfo::XclImpHFPortionInfo() :
+ mnHeight( 0 ),
+ mnMaxLineHt( 0 )
+{
+ maSel.nStartPara = maSel.nEndPara = 0;
+ maSel.nStartPos = maSel.nEndPos = 0;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpHFConverter::XclImpHFConverter( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mrEE( rRoot.GetHFEditEngine() ),
+ mxFontData( new XclFontData ),
+ meCurrObj( EXC_HF_CENTER )
+{
+}
+
+XclImpHFConverter::~XclImpHFConverter()
+{
+}
+
+void XclImpHFConverter::ParseString( const String& rHFString )
+{
+ // edit engine objects
+ mrEE.SetText( EMPTY_STRING );
+ maInfos.clear();
+ maInfos.resize( EXC_HF_PORTION_COUNT );
+ meCurrObj = EXC_HF_CENTER;
+
+ // parser temporaries
+ maCurrText.Erase();
+ String aReadFont; // current font name
+ String aReadStyle; // current font style
+ sal_uInt16 nReadHeight = 0; // current font height
+ ResetFontData();
+
+ /** State of the parser. */
+ enum XclHFParserState
+ {
+ xlPSText, /// Read text, search for functions.
+ xlPSFunc, /// Read function (token following a '&').
+ xlPSFont, /// Read font name ('&' is followed by '"', reads until next '"' or ',').
+ xlPSFontStyle, /// Read font style name (font part after ',', reads until next '"').
+ xlPSHeight /// Read font height ('&' is followed by num. digits, reads until non-digit).
+ } eState = xlPSText;
+
+ const sal_Unicode* pChar = rHFString.GetBuffer();
+ const sal_Unicode* pNull = pChar + rHFString.Len(); // pointer to teminating null char
+ while( *pChar )
+ {
+ switch( eState )
+ {
+
+// --- read text character ---
+
+ case xlPSText:
+ {
+ switch( *pChar )
+ {
+ case '&': // new command
+ InsertText();
+ eState = xlPSFunc;
+ break;
+ case '\n': // line break
+ InsertText();
+ InsertLineBreak();
+ break;
+ default:
+ maCurrText += *pChar;
+ }
+ }
+ break;
+
+// --- read control sequence ---
+
+ case xlPSFunc:
+ {
+ eState = xlPSText;
+ switch( *pChar )
+ {
+ case '&': maCurrText += '&'; break; // the '&' character
+
+ case 'L': SetNewPortion( EXC_HF_LEFT ); break; // Left portion
+ case 'C': SetNewPortion( EXC_HF_CENTER ); break; // Center portion
+ case 'R': SetNewPortion( EXC_HF_RIGHT ); break; // Right portion
+
+ case 'P': InsertField( SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD ) ); break; // page
+ case 'N': InsertField( SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD ) ); break; // page count
+ case 'D': InsertField( SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD ) ); break; // date
+ case 'T': InsertField( SvxFieldItem( SvxTimeField(), EE_FEATURE_FIELD ) ); break; // time
+ case 'A': InsertField( SvxFieldItem( SvxTableField(), EE_FEATURE_FIELD ) ); break; // table name
+
+ case 'Z': // file path
+ InsertField( SvxFieldItem( SvxExtFileField(), EE_FEATURE_FIELD ) ); // convert to full name
+ if( (pNull - pChar >= 2) && (*(pChar + 1) == '&') && (*(pChar + 2) == 'F') )
+ {
+ // &Z&F found - ignore the &F part
+ pChar += 2;
+ }
+ break;
+ case 'F': // file name
+ InsertField( SvxFieldItem( SvxExtFileField( EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT ), EE_FEATURE_FIELD ) );
+ break;
+
+ case 'U': // underline
+ SetAttribs();
+ mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_SINGLE) ?
+ EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_SINGLE;
+ break;
+ case 'E': // double underline
+ SetAttribs();
+ mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_DOUBLE) ?
+ EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_DOUBLE;
+ break;
+ case 'S': // strikeout
+ SetAttribs();
+ mxFontData->mbStrikeout = !mxFontData->mbStrikeout;
+ break;
+ case 'X': // superscript
+ SetAttribs();
+ mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUPER) ?
+ EXC_FONTESC_NONE : EXC_FONTESC_SUPER;
+ break;
+ case 'Y': // subsrcipt
+ SetAttribs();
+ mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUB) ?
+ EXC_FONTESC_NONE : EXC_FONTESC_SUB;
+ break;
+
+ case '\"': // font name
+ aReadFont.Erase();
+ aReadStyle.Erase();
+ eState = xlPSFont;
+ break;
+ default:
+ if( ('0' <= *pChar) && (*pChar <= '9') ) // font size
+ {
+ nReadHeight = *pChar - '0';
+ eState = xlPSHeight;
+ }
+ }
+ }
+ break;
+
+// --- read font name ---
+
+ case xlPSFont:
+ {
+ switch( *pChar )
+ {
+ case '\"':
+ --pChar;
+ // run through
+ case ',':
+ eState = xlPSFontStyle;
+ break;
+ default:
+ aReadFont += *pChar;
+ }
+ }
+ break;
+
+// --- read font style ---
+
+ case xlPSFontStyle:
+ {
+ switch( *pChar )
+ {
+ case '\"':
+ SetAttribs();
+ if( aReadFont.Len() )
+ mxFontData->maName = aReadFont;
+ mxFontData->maStyle = aReadStyle;
+ eState = xlPSText;
+ break;
+ default:
+ aReadStyle += *pChar;
+ }
+ }
+ break;
+
+// --- read font height ---
+
+ case xlPSHeight:
+ {
+ if( ('0' <= *pChar) && (*pChar <= '9') )
+ {
+ if( nReadHeight != 0xFFFF )
+ {
+ nReadHeight *= 10;
+ nReadHeight += (*pChar - '0');
+ if( nReadHeight > 1600 ) // max 1600pt = 32000twips
+ nReadHeight = 0xFFFF;
+ }
+ }
+ else
+ {
+ if( (nReadHeight != 0) && (nReadHeight != 0xFFFF) )
+ {
+ SetAttribs();
+ mxFontData->mnHeight = nReadHeight * 20;
+ }
+ --pChar;
+ eState = xlPSText;
+ }
+ }
+ break;
+ }
+ ++pChar;
+ }
+
+ // finalize
+ CreateCurrObject();
+ maInfos[ EXC_HF_LEFT ].mnHeight += GetMaxLineHeight( EXC_HF_LEFT );
+ maInfos[ EXC_HF_CENTER ].mnHeight += GetMaxLineHeight( EXC_HF_CENTER );
+ maInfos[ EXC_HF_RIGHT ].mnHeight += GetMaxLineHeight( EXC_HF_RIGHT );
+}
+
+void XclImpHFConverter::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const
+{
+ ScPageHFItem aHFItem( nWhichId );
+ if( maInfos[ EXC_HF_LEFT ].mxObj.get() )
+ aHFItem.SetLeftArea( *maInfos[ EXC_HF_LEFT ].mxObj );
+ if( maInfos[ EXC_HF_CENTER ].mxObj.get() )
+ aHFItem.SetCenterArea( *maInfos[ EXC_HF_CENTER ].mxObj );
+ if( maInfos[ EXC_HF_RIGHT ].mxObj.get() )
+ aHFItem.SetRightArea( *maInfos[ EXC_HF_RIGHT ].mxObj );
+ rItemSet.Put( aHFItem );
+}
+
+sal_Int32 XclImpHFConverter::GetTotalHeight() const
+{
+ return ::std::max( maInfos[ EXC_HF_LEFT ].mnHeight,
+ ::std::max( maInfos[ EXC_HF_CENTER ].mnHeight, maInfos[ EXC_HF_RIGHT ].mnHeight ) );
+}
+
+// private --------------------------------------------------------------------
+
+sal_uInt16 XclImpHFConverter::GetMaxLineHeight( XclImpHFPortion ePortion ) const
+{
+ sal_uInt16 nMaxHt = maInfos[ ePortion ].mnMaxLineHt;
+ return (nMaxHt == 0) ? mxFontData->mnHeight : nMaxHt;
+}
+
+sal_uInt16 XclImpHFConverter::GetCurrMaxLineHeight() const
+{
+ return GetMaxLineHeight( meCurrObj );
+}
+
+void XclImpHFConverter::UpdateMaxLineHeight( XclImpHFPortion ePortion )
+{
+ sal_uInt16& rnMaxHt = maInfos[ ePortion ].mnMaxLineHt;
+ rnMaxHt = ::std::max( rnMaxHt, mxFontData->mnHeight );
+}
+
+void XclImpHFConverter::UpdateCurrMaxLineHeight()
+{
+ UpdateMaxLineHeight( meCurrObj );
+}
+
+void XclImpHFConverter::SetAttribs()
+{
+ ESelection& rSel = GetCurrSel();
+ if( (rSel.nStartPara != rSel.nEndPara) || (rSel.nStartPos != rSel.nEndPos) )
+ {
+ SfxItemSet aItemSet( mrEE.GetEmptyItemSet() );
+ XclImpFont aFont( GetRoot(), *mxFontData );
+ aFont.FillToItemSet( aItemSet, EXC_FONTITEM_HF );
+ mrEE.QuickSetAttribs( aItemSet, rSel );
+ rSel.nStartPara = rSel.nEndPara;
+ rSel.nStartPos = rSel.nEndPos;
+ }
+}
+
+void XclImpHFConverter::ResetFontData()
+{
+ if( const XclImpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
+ *mxFontData = pFirstFont->GetFontData();
+ else
+ {
+ mxFontData->Clear();
+ mxFontData->mnHeight = 200;
+ }
+}
+
+void XclImpHFConverter::InsertText()
+{
+ if( maCurrText.Len() )
+ {
+ ESelection& rSel = GetCurrSel();
+ mrEE.QuickInsertText( maCurrText, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
+ rSel.nEndPos = rSel.nEndPos + maCurrText.Len();
+ maCurrText.Erase();
+ UpdateCurrMaxLineHeight();
+ }
+}
+
+void XclImpHFConverter::InsertField( const SvxFieldItem& rFieldItem )
+{
+ ESelection& rSel = GetCurrSel();
+ mrEE.QuickInsertField( rFieldItem, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
+ ++rSel.nEndPos;
+ UpdateCurrMaxLineHeight();
+}
+
+void XclImpHFConverter::InsertLineBreak()
+{
+ ESelection& rSel = GetCurrSel();
+ mrEE.QuickInsertText( String( '\n' ), ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
+ ++rSel.nEndPara;
+ rSel.nEndPos = 0;
+ GetCurrInfo().mnHeight += GetCurrMaxLineHeight();
+ GetCurrInfo().mnMaxLineHt = 0;
+}
+
+void XclImpHFConverter::CreateCurrObject()
+{
+ InsertText();
+ SetAttribs();
+ GetCurrObj().reset( mrEE.CreateTextObject() );
+}
+
+void XclImpHFConverter::SetNewPortion( XclImpHFPortion eNew )
+{
+ if( eNew != meCurrObj )
+ {
+ CreateCurrObject();
+ meCurrObj = eNew;
+ if( GetCurrObj().get() )
+ mrEE.SetText( *GetCurrObj() );
+ else
+ mrEE.SetText( EMPTY_STRING );
+ ResetFontData();
+ }
+}
+
+// URL conversion =============================================================
+
+namespace {
+
+void lclAppendUrlChar( String& rUrl, sal_Unicode cChar )
+{
+ // #126855# encode special characters
+ switch( cChar )
+ {
+ case '#': rUrl.AppendAscii( "%23" ); break;
+ case '%': rUrl.AppendAscii( "%25" ); break;
+ default: rUrl.Append( cChar );
+ }
+}
+
+} // namespace
+
+void XclImpUrlHelper::DecodeUrl(
+ String& rUrl, String& rTabName, bool& rbSameWb,
+ const XclImpRoot& rRoot, const String& rEncodedUrl )
+{
+ enum
+ {
+ xlUrlInit, /// Initial state, read string mode character.
+ xlUrlPath, /// Read URL path.
+ xlUrlFileName, /// Read file name.
+ xlUrlSheetName, /// Read sheet name.
+ xlUrlRaw /// Raw mode. No control characters will occur.
+ } eState = xlUrlInit;
+
+ bool bEncoded = true;
+ rbSameWb = false;
+
+ sal_Unicode cCurrDrive = 0;
+ String aDosBase( INetURLObject( rRoot.GetBasePath() ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ if( (aDosBase.Len() > 2) && aDosBase.EqualsAscii( ":\\", 1, 2 ) )
+ cCurrDrive = aDosBase.GetChar( 0 );
+
+ const sal_Unicode* pChar = rEncodedUrl.GetBuffer();
+ while( *pChar )
+ {
+ switch( eState )
+ {
+
+// --- first character ---
+
+ case xlUrlInit:
+ {
+ switch( *pChar )
+ {
+ case EXC_URLSTART_ENCODED:
+ eState = xlUrlPath;
+ break;
+ case EXC_URLSTART_SELF:
+ case EXC_URLSTART_SELFENCODED:
+ rbSameWb = true;
+ eState = xlUrlSheetName;
+ break;
+ case '[':
+ bEncoded = false;
+ eState = xlUrlFileName;
+ break;
+ default:
+ bEncoded = false;
+ lclAppendUrlChar( rUrl, *pChar );
+ eState = xlUrlPath;
+ }
+ }
+ break;
+
+// --- URL path ---
+
+ case xlUrlPath:
+ {
+ switch( *pChar )
+ {
+ case EXC_URL_DOSDRIVE:
+ {
+ if( *(pChar + 1) )
+ {
+ ++pChar;
+ if( *pChar == '@' )
+ rUrl.AppendAscii( "\\\\" );
+ else
+ {
+ lclAppendUrlChar( rUrl, *pChar );
+ rUrl.AppendAscii( ":\\" );
+ }
+ }
+ else
+ rUrl.AppendAscii( "<NULL-DRIVE!>" );
+ }
+ break;
+ case EXC_URL_DRIVEROOT:
+ if( cCurrDrive )
+ {
+ lclAppendUrlChar( rUrl, cCurrDrive );
+ rUrl.Append( ':' );
+ }
+ // run through
+ case EXC_URL_SUBDIR:
+ if( bEncoded )
+ rUrl.Append( '\\' );
+ else // control character in raw name -> DDE link
+ {
+ rUrl.Append( EXC_DDE_DELIM );
+ eState = xlUrlRaw;
+ }
+ break;
+ case EXC_URL_PARENTDIR:
+ rUrl.AppendAscii( "..\\" );
+ break;
+ case EXC_URL_RAW:
+ {
+ if( *(pChar + 1) )
+ {
+ xub_StrLen nLen = *++pChar;
+ for( xub_StrLen nChar = 0; (nChar < nLen) && *(pChar + 1); ++nChar )
+ lclAppendUrlChar( rUrl, *++pChar );
+// rUrl.Append( ':' );
+ }
+ }
+ break;
+ case '[':
+ eState = xlUrlFileName;
+ break;
+ default:
+ lclAppendUrlChar( rUrl, *pChar );
+ }
+ }
+ break;
+
+// --- file name ---
+
+ case xlUrlFileName:
+ {
+ switch( *pChar )
+ {
+ case ']': eState = xlUrlSheetName; break;
+ default: lclAppendUrlChar( rUrl, *pChar );
+ }
+ }
+ break;
+
+// --- sheet name ---
+
+ case xlUrlSheetName:
+ rTabName.Append( *pChar );
+ break;
+
+// --- raw read mode ---
+
+ case xlUrlRaw:
+ lclAppendUrlChar( rUrl, *pChar );
+ break;
+ }
+
+ ++pChar;
+ }
+}
+
+void XclImpUrlHelper::DecodeUrl(
+ String& rUrl, bool& rbSameWb, const XclImpRoot& rRoot, const String& rEncodedUrl )
+{
+ String aTabName;
+ DecodeUrl( rUrl, aTabName, rbSameWb, rRoot, rEncodedUrl );
+ DBG_ASSERT( !aTabName.Len(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
+}
+
+bool XclImpUrlHelper::DecodeLink( String& rApplic, String& rTopic, const String rEncUrl )
+{
+ xub_StrLen nPos = rEncUrl.Search( EXC_DDE_DELIM );
+ if( (nPos != STRING_NOTFOUND) && (0 < nPos) && (nPos + 1 < rEncUrl.Len()) )
+ {
+ rApplic = rEncUrl.Copy( 0, nPos );
+ rTopic = rEncUrl.Copy( nPos + 1 );
+ return true;
+ }
+ return false;
+}
+
+// Cached Values ==============================================================
+
+XclImpCachedValue::XclImpCachedValue( XclImpStream& rStrm ) :
+ mfValue( 0.0 ),
+ mnBoolErr( 0 )
+{
+ rStrm >> mnType;
+ switch( mnType )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ rStrm.Ignore( 8 );
+ break;
+ case EXC_CACHEDVAL_DOUBLE:
+ rStrm >> mfValue;
+ break;
+ case EXC_CACHEDVAL_STRING:
+ mxStr.reset( new String( rStrm.ReadUniString() ) );
+ break;
+ case EXC_CACHEDVAL_BOOL:
+ case EXC_CACHEDVAL_ERROR:
+ {
+ double fVal;
+ rStrm >> mnBoolErr;
+ rStrm.Ignore( 7 );
+
+ const ScTokenArray* pScTokArr = rStrm.GetRoot().GetOldFmlaConverter().GetBoolErr(
+ XclTools::ErrorToEnum( fVal, mnType == EXC_CACHEDVAL_ERROR, mnBoolErr ) );
+ if( pScTokArr )
+ mxTokArr.reset( pScTokArr->Clone() );
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpCachedValue::XclImpCachedValue - unknown data type" );
+ }
+}
+
+XclImpCachedValue::~XclImpCachedValue()
+{
+}
+
+USHORT XclImpCachedValue::GetScError() const
+{
+ return (mnType == EXC_CACHEDVAL_ERROR) ? XclTools::GetScErrorCode( mnBoolErr ) : 0;
+}
+
+// Matrix Cached Values ==============================================================
+
+XclImpCachedMatrix::XclImpCachedMatrix( XclImpStream& rStrm ) :
+ mnScCols( 0 ),
+ mnScRows( 0 )
+{
+ mnScCols = rStrm.ReaduInt8();
+ mnScRows = rStrm.ReaduInt16();
+
+ if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
+ {
+ // in BIFF2-BIFF7: 256 columns represented by 0 columns
+ if( mnScCols == 0 )
+ mnScCols = 256;
+ }
+ else
+ {
+ // in BIFF8: columns and rows decreaed by 1
+ ++mnScCols;
+ ++mnScRows;
+ }
+
+ for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
+ for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
+ maValueList.Append( new XclImpCachedValue( rStrm ) );
+}
+
+XclImpCachedMatrix::~XclImpCachedMatrix()
+{
+}
+
+ScMatrixRef XclImpCachedMatrix::CreateScMatrix() const
+{
+ ScMatrixRef xScMatrix;
+ DBG_ASSERT( mnScCols * mnScRows == maValueList.Count(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
+ if( mnScCols && mnScRows && static_cast< ULONG >( mnScCols * mnScRows ) <= maValueList.Count() )
+ {
+ xScMatrix = new ScMatrix( mnScCols, mnScRows );
+ const XclImpCachedValue* pValue = maValueList.First();
+ for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
+ {
+ for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
+ {
+ switch( pValue->GetType() )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ // Excel shows 0.0 here, not an empty cell
+ xScMatrix->PutEmpty( nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_DOUBLE:
+ xScMatrix->PutDouble( pValue->GetValue(), nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_STRING:
+ xScMatrix->PutString( pValue->GetString(), nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_BOOL:
+ xScMatrix->PutBoolean( pValue->GetBool(), nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_ERROR:
+ xScMatrix->PutError( pValue->GetScError(), nScCol, nScRow );
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpCachedMatrix::CreateScMatrix - unknown value type" );
+ xScMatrix->PutEmpty( nScCol, nScRow );
+ }
+ pValue = maValueList.Next();
+ }
+ }
+ }
+ return xScMatrix;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx
new file mode 100644
index 000000000000..dc2234570ea6
--- /dev/null
+++ b/sc/source/filter/excel/xilink.cxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xilink.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "scextopt.hxx"
+#include "tablink.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xiname.hxx"
+#include "excform.hxx"
+#include "tokenarray.hxx"
+#include "externalrefmgr.hxx"
+
+#include <vector>
+
+using ::std::vector;
+
+// ============================================================================
+// *** Helper classes ***
+// ============================================================================
+
+// Cached external cells ======================================================
+
+/** Contains the address and value of an external referenced cell. */
+class XclImpCrn : public XclImpCachedValue
+{
+public:
+ /** Reads a cached value and stores it with its cell address. */
+ explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
+
+ const XclAddress& GetAddress() const;
+
+private:
+ XclAddress maXclPos; /// Excel position of the cached cell.
+};
+
+// Sheet in an external document ==============================================
+
+/** Contains the name and sheet index of one sheet in an external document. */
+class XclImpSupbookTab
+{
+public:
+ /** Stores the sheet name and marks the sheet index as invalid.
+ The sheet index is set while creating the Calc sheet with CreateTable(). */
+ explicit XclImpSupbookTab( const String& rTabName );
+ ~XclImpSupbookTab();
+
+ inline const String& GetTabName() const { return maTabName; }
+
+ /** Reads a CRN record (external referenced cell) at the specified address. */
+ void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
+
+ void LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable);
+
+private:
+ typedef ScfDelList< XclImpCrn > XclImpCrnList;
+
+ XclImpCrnList maCrnList; /// List of CRN records (cached cell values).
+ String maTabName; /// Name of the external sheet.
+ SCTAB mnScTab; /// New sheet index in Calc document.
+};
+
+// External document (SUPBOOK) ================================================
+
+/** This class represents an external linked document (record SUPBOOK).
+ @descr Contains a list of all referenced sheets in the document. */
+class XclImpSupbook : protected XclImpRoot
+{
+public:
+ /** Reads the SUPBOOK record from stream. */
+ explicit XclImpSupbook( XclImpStream& rStrm );
+
+ /** Reads an XCT record (count of following CRNs and current sheet). */
+ void ReadXct( XclImpStream& rStrm );
+ /** Reads a CRN record (external referenced cell). */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record. */
+ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns the SUPBOOK record type. */
+ inline XclSupbookType GetType() const { return meType; }
+
+ /** Returns the URL of the external document. */
+ inline const String& GetXclUrl() const { return maXclUrl; }
+
+ /** Returns the external name specified by an index from the Excel document (one-based). */
+ const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
+ /** Tries to decode the URL to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ bool GetLinkData( String& rApplic, String& rDoc ) const;
+ /** Returns the specified macro name (1-based) or an empty string on error. */
+ const String& GetMacroName( sal_uInt16 nXclNameIdx ) const;
+
+ const String& GetTabName( sal_uInt16 nXtiTab ) const;
+
+ sal_uInt16 GetTabCount() const;
+
+ void LoadCachedValues();
+
+private:
+ typedef ScfDelList< XclImpSupbookTab > XclImpSupbookTabList;
+ typedef ScfDelList< XclImpExtName > XclImpExtNameList;
+
+ XclImpSupbookTabList maSupbTabList; /// All sheet names of the document.
+ XclImpExtNameList maExtNameList; /// All external names of the document.
+ String maXclUrl; /// URL of the external document (Excel mode).
+ String maFilterName; /// Detected filer name.
+ String maFilterOpt; /// Detected filer options.
+ XclSupbookType meType; /// Type of the supbook record.
+ sal_uInt16 mnSBTab; /// Current Excel sheet index from SUPBOOK for XCT/CRN records.
+};
+
+// Import link manager ========================================================
+
+/** Contains the SUPBOOK index and sheet indexes of an external link.
+ @descr It is possible to enter a formula like =SUM(Sheet1:Sheet3!A1),
+ therefore here occurs a sheet range. */
+struct XclImpXti
+{
+ sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
+ sal_uInt16 mnSBTabFirst; /// Index to the first sheet of the range in the SUPBOOK.
+ sal_uInt16 mnSBTabLast; /// Index to the last sheet of the range in the SUPBOOK.
+ inline explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {}
+};
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti )
+{
+ return rStrm >> rXti.mnSupbook >> rXti.mnSBTabFirst >> rXti.mnSBTabLast;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the link manager. */
+class XclImpLinkManagerImpl : protected XclImpRoot
+{
+public:
+ explicit XclImpLinkManagerImpl( const XclImpRoot& rRoot );
+
+ /** Reads the EXTERNSHEET record. */
+ void ReadExternsheet( XclImpStream& rStrm );
+ /** Reads a SUPBOOK record. */
+ void ReadSupbook( XclImpStream& rStrm );
+ /** Reads an XCT record and appends it to the current SUPBOOK. */
+ void ReadXct( XclImpStream& rStrm );
+ /** Reads a CRN record and appends it to the current SUPBOOK. */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
+ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns true, if the specified XTI entry contains an internal reference. */
+ bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
+ /** Returns the Calc sheet index range of the specified XTI entry.
+ @return true = XTI data found, returned sheet index range is valid. */
+ bool GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
+ sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified external name or 0 on error. */
+ const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
+
+ /** Returns the absolute file URL of a supporting workbook specified by
+ the index. */
+ const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
+
+ const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
+
+ /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified macro name or an empty string on error. */
+ const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
+
+private:
+ /** Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record). */
+ const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified SUPBOOK (external document). */
+ const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const;
+//UNUSED2009-05 /** Returns the SUPBOOK (external workbook) specified by its URL. */
+//UNUSED2009-05 const XclImpSupbook* GetSupbook( const String& rUrl ) const;
+
+ void LoadCachedValues();
+
+//UNUSED2009-05 /** Finds the largest range of sheet indexes in a SUPBOOK after a start sheet index.
+//UNUSED2009-05 @param rnSBTabFirst (out-param) The first sheet index of the range in SUPBOOK is returned here.
+//UNUSED2009-05 @param rnSBTabLast (out-param) The last sheet index of the range in SUPBOOK is returned here (inclusive).
+//UNUSED2009-05 @param nSupbook The list index of the SUPBOOK.
+//UNUSED2009-05 @param nSBTabStart The first allowed sheet index. Sheet ranges with an earlier start index are ignored.
+//UNUSED2009-05 @return true = the return values are valid; false = nothing found. */
+//UNUSED2009-05 bool FindNextTabRange(
+//UNUSED2009-05 sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
+//UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const;
+
+private:
+ typedef ::std::vector< XclImpXti > XclImpXtiVector;
+ typedef ScfDelList< XclImpSupbook > XclImpSupbookList;
+
+ XclImpXtiVector maXtiList; /// List of all XTI structures.
+ XclImpSupbookList maSupbookList; /// List of external documents.
+ bool mbCreated; /// true = Calc sheets already created.
+};
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+// Excel sheet indexes ========================================================
+
+// original Excel sheet names -------------------------------------------------
+
+void XclImpTabInfo::AppendXclTabName( const String& rXclTabName, SCTAB nScTab )
+{
+ maTabNames[ rXclTabName ] = nScTab;
+}
+
+void XclImpTabInfo::InsertScTab( SCTAB nScTab )
+{
+ for( XclTabNameMap::iterator aIt = maTabNames.begin(), aEnd = maTabNames.end(); aIt != aEnd; ++aIt )
+ if( aIt->second >= nScTab )
+ ++aIt->second;
+}
+
+SCTAB XclImpTabInfo::GetScTabFromXclName( const String& rXclTabName ) const
+{
+ XclTabNameMap::const_iterator aIt = maTabNames.find( rXclTabName );
+ return (aIt != maTabNames.end()) ? aIt->second : SCTAB_INVALID;
+}
+
+// record creation order - TABID record ---------------------------------------
+
+void XclImpTabInfo::ReadTabid( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ rStrm.EnableDecryption();
+ sal_Size nReadCount = rStrm.GetRecLeft() / 2;
+ DBG_ASSERT( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
+ maTabIdVec.clear();
+ maTabIdVec.reserve( nReadCount );
+ for( sal_Size nIndex = 0; rStrm.IsValid() && (nIndex < nReadCount); ++nIndex )
+ // #93471# zero index is not allowed in BIFF8, but it seems that it occurs in real life
+ maTabIdVec.push_back( rStrm.ReaduInt16() );
+ }
+}
+
+sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId ) const
+{
+ sal_uInt16 nReturn = 0;
+ for( ScfUInt16Vec::const_iterator aIt = maTabIdVec.begin(), aEnd = maTabIdVec.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt16 nValue = *aIt;
+ if( nValue == nCreatedId )
+ return nReturn;
+ if( nValue <= nMaxTabId )
+ ++nReturn;
+ }
+ return 0;
+}
+
+// External names =============================================================
+
+XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv )
+{
+ sal_uInt16 nFlags;
+ sal_uInt8 nLen;
+
+ rStrm >> nFlags >> mnStorageId >> nLen ;
+ maName = rStrm.ReadUniString( nLen );
+ if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
+ {
+ if( eSubType == EXC_SBTYPE_ADDIN )
+ {
+ meType = xlExtAddIn;
+ maName = rStrm.GetRoot().GetScAddInName( maName );
+ }
+ else if ( (eSubType == EXC_SBTYPE_EUROTOOL) &&
+ maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
+ meType = xlExtEuroConvert;
+ else
+ {
+ meType = xlExtName;
+ ScfTools::ConvertToScDefinedName( maName );
+ }
+ }
+ else
+ {
+ meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE );
+ }
+
+ if( (meType == xlExtDDE) && (rStrm.GetRecLeft() > 1) )
+ mxDdeMatrix.reset( new XclImpCachedMatrix( rStrm ) );
+
+ if (meType == xlExtName)
+ {
+ // TODO: For now, only global external names are supported. In future
+ // we should extend this to supporting per-sheet external names.
+ if (mnStorageId == 0)
+ {
+ if (pFormulaConv)
+ {
+ const ScTokenArray* pArray = NULL;
+ sal_uInt16 nFmlaLen;
+ rStrm >> nFmlaLen;
+ vector<String> aTabNames;
+ sal_uInt16 nCount = rSupbook.GetTabCount();
+ aTabNames.reserve(nCount);
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ aTabNames.push_back(rSupbook.GetTabName(i));
+
+ pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
+ if (pArray)
+ mxArray.reset(pArray->Clone());
+ }
+ }
+ }
+}
+
+XclImpExtName::~XclImpExtName()
+{
+}
+
+void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, const String& rTopic ) const
+{
+ ScMatrixRef xResults;
+ if( mxDdeMatrix.get() )
+ xResults = mxDdeMatrix->CreateScMatrix();
+ rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
+}
+
+void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const
+{
+ if (!mxArray.get())
+ return;
+
+ ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
+ pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
+}
+
+bool XclImpExtName::HasFormulaTokens() const
+{
+ return (mxArray.get() != NULL);
+}
+
+// Cached external cells ======================================================
+
+XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
+ XclImpCachedValue( rStrm ),
+ maXclPos( rXclPos )
+{
+}
+
+const XclAddress& XclImpCrn::GetAddress() const
+{
+ return maXclPos;
+}
+
+// Sheet in an external document ==============================================
+
+XclImpSupbookTab::XclImpSupbookTab( const String& rTabName ) :
+ maTabName( rTabName ),
+ mnScTab( SCTAB_INVALID )
+{
+}
+
+XclImpSupbookTab::~XclImpSupbookTab()
+{
+}
+
+void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
+{
+ maCrnList.Append( new XclImpCrn( rStrm, rXclPos ) );
+}
+
+void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)
+{
+ if (maCrnList.Empty())
+ return;
+
+ for (XclImpCrn* p = maCrnList.First(); p; p = maCrnList.Next())
+ {
+ const XclAddress& rAddr = p->GetAddress();
+ switch (p->GetType())
+ {
+ case EXC_CACHEDVAL_BOOL:
+ {
+ bool b = p->GetBool();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
+ }
+ break;
+ case EXC_CACHEDVAL_DOUBLE:
+ {
+ double f = p->GetValue();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(f));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
+ }
+ break;
+ case EXC_CACHEDVAL_ERROR:
+ {
+ double fError = XclTools::ErrorToDouble( p->GetXclError() );
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(fError));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
+ }
+ break;
+ case EXC_CACHEDVAL_STRING:
+ {
+ const String& rStr = p->GetString();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+// External document (SUPBOOK) ================================================
+
+XclImpSupbook::XclImpSupbook( XclImpStream& rStrm ) :
+ XclImpRoot( rStrm.GetRoot() ),
+ meType( EXC_SBTYPE_UNKNOWN ),
+ mnSBTab( EXC_TAB_DELETED )
+{
+ sal_uInt16 nSBTabCnt;
+ rStrm >> nSBTabCnt;
+
+ if( rStrm.GetRecLeft() == 2 )
+ {
+ switch( rStrm.ReaduInt16() )
+ {
+ case EXC_SUPB_SELF: meType = EXC_SBTYPE_SELF; break;
+ case EXC_SUPB_ADDIN: meType = EXC_SBTYPE_ADDIN; break;
+ default: DBG_ERRORFILE( "XclImpSupbook::XclImpSupbook - unknown special SUPBOOK type" );
+ }
+ return;
+ }
+
+ String aEncUrl( rStrm.ReadUniString() );
+ bool bSelf = false;
+ XclImpUrlHelper::DecodeUrl( maXclUrl, bSelf, GetRoot(), aEncUrl );
+
+ if( maXclUrl.EqualsIgnoreCaseAscii( "\010EUROTOOL.XLA" ) )
+ {
+ meType = EXC_SBTYPE_EUROTOOL;
+ maSupbTabList.Append( new XclImpSupbookTab( maXclUrl ) );
+ }
+ else if( nSBTabCnt )
+ {
+ meType = EXC_SBTYPE_EXTERN;
+ for( sal_uInt16 nSBTab = 0; nSBTab < nSBTabCnt; ++nSBTab )
+ {
+ String aTabName( rStrm.ReadUniString() );
+ maSupbTabList.Append( new XclImpSupbookTab( aTabName ) );
+ }
+ }
+ else
+ {
+ meType = EXC_SBTYPE_SPECIAL;
+ // create dummy list entry
+ maSupbTabList.Append( new XclImpSupbookTab( maXclUrl ) );
+ }
+}
+
+void XclImpSupbook::ReadXct( XclImpStream& rStrm )
+{
+ rStrm.Ignore( 2 );
+ rStrm >> mnSBTab;
+}
+
+void XclImpSupbook::ReadCrn( XclImpStream& rStrm )
+{
+ if( XclImpSupbookTab* pSBTab = maSupbTabList.GetObject( mnSBTab ) )
+ {
+ sal_uInt8 nXclColLast, nXclColFirst;
+ sal_uInt16 nXclRow;
+ rStrm >> nXclColLast >> nXclColFirst >> nXclRow;
+
+ for( sal_uInt8 nXclCol = nXclColFirst; (nXclCol <= nXclColLast) && (rStrm.GetRecLeft() > 1); ++nXclCol )
+ pSBTab->ReadCrn( rStrm, XclAddress( nXclCol, nXclRow ) );
+ }
+}
+
+void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+{
+ maExtNameList.Append( new XclImpExtName( *this, rStrm, meType, pFormulaConv ) );
+}
+
+const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
+{
+ DBG_ASSERT( nXclIndex > 0, "XclImpSupbook::GetExternName - index must be >0" );
+ return (meType == EXC_SBTYPE_SELF) ? 0 : maExtNameList.GetObject( nXclIndex - 1 );
+}
+
+bool XclImpSupbook::GetLinkData( String& rApplic, String& rTopic ) const
+{
+ return (meType == EXC_SBTYPE_SPECIAL) && XclImpUrlHelper::DecodeLink( rApplic, rTopic, maXclUrl );
+}
+
+const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
+{
+ DBG_ASSERT( nXclNameIdx > 0, "XclImpSupbook::GetMacroName - index must be >0" );
+ const XclImpName* pName = (meType == EXC_SBTYPE_SELF) ? GetNameManager().GetName( nXclNameIdx ) : 0;
+ return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_STRING;
+}
+
+const String& XclImpSupbook::GetTabName( sal_uInt16 nXtiTab ) const
+{
+ if (maSupbTabList.Empty())
+ return EMPTY_STRING;
+
+ sal_uInt16 i = 0;
+ for (XclImpSupbookTab* p = maSupbTabList.First(); p; p = maSupbTabList.Next(), ++i)
+ {
+ if (i == nXtiTab)
+ return p->GetTabName();
+ }
+
+ return EMPTY_STRING;
+}
+
+sal_uInt16 XclImpSupbook::GetTabCount() const
+{
+ return ulimit_cast<sal_uInt16>(maSupbTabList.Count());
+}
+
+void XclImpSupbook::LoadCachedValues()
+{
+ if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
+ return;
+
+ String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
+
+ ScExternalRefManager* pRefMgr = GetRoot().GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
+
+ sal_uInt16 nCount = static_cast< sal_uInt16 >( maSupbTabList.Count() );
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ XclImpSupbookTab* pTab = maSupbTabList.GetObject(i);
+ if (!pTab)
+ return;
+
+ const String& rTabName = pTab->GetTabName();
+ ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
+ pTab->LoadCachedValues(pCacheTable);
+ pCacheTable->setWholeTableCached();
+ }
+}
+
+// Import link manager ========================================================
+
+XclImpLinkManagerImpl::XclImpLinkManagerImpl( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mbCreated( false )
+{
+}
+
+void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
+{
+ sal_uInt16 nXtiCount;
+ rStrm >> nXtiCount;
+ DBG_ASSERT( static_cast< sal_Size >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" );
+ nXtiCount = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nXtiCount, rStrm.GetRecLeft() / 6 ) );
+
+ /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
+ records instead of only one as expected. Surprisingly, Excel seems to
+ insert the entries of the second record before the entries of the first
+ record. */
+ XclImpXtiVector aNewEntries( nXtiCount );
+ for( XclImpXtiVector::iterator aIt = aNewEntries.begin(), aEnd = aNewEntries.end(); rStrm.IsValid() && (aIt != aEnd); ++aIt )
+ rStrm >> *aIt;
+ maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() );
+
+ LoadCachedValues();
+}
+
+void XclImpLinkManagerImpl::ReadSupbook( XclImpStream& rStrm )
+{
+ maSupbookList.Append( new XclImpSupbook( rStrm ) );
+}
+
+void XclImpLinkManagerImpl::ReadXct( XclImpStream& rStrm )
+{
+ if( XclImpSupbook* pSupbook = maSupbookList.Last() )
+ pSupbook->ReadXct( rStrm );
+}
+
+void XclImpLinkManagerImpl::ReadCrn( XclImpStream& rStrm )
+{
+ if( XclImpSupbook* pSupbook = maSupbookList.Last() )
+ pSupbook->ReadCrn( rStrm );
+}
+
+void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+{
+ if( XclImpSupbook* pSupbook = maSupbookList.Last() )
+ pSupbook->ReadExternname( rStrm, pFormulaConv );
+}
+
+bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
+ return pSupbook && (pSupbook->GetType() == EXC_SBTYPE_SELF);
+}
+
+bool XclImpLinkManagerImpl::GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
+{
+ if( const XclImpXti* pXti = GetXti( nXtiIndex ) )
+ {
+ if (maSupbookList.GetObject(pXti->mnSupbook))
+ {
+ rnFirstScTab = pXti->mnSBTabFirst;
+ rnLastScTab = pXti->mnSBTabLast;
+ return true;
+ }
+ }
+ return false;
+}
+
+const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
+ return pSupbook ? pSupbook->GetExternName( nExtName ) : 0;
+}
+
+const String* XclImpLinkManagerImpl::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
+{
+ const XclImpSupbook* p = GetSupbook( nXtiIndex );
+ if (!p)
+ return NULL;
+ return &p->GetXclUrl();
+}
+
+const String& XclImpLinkManagerImpl::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
+{
+ const XclImpSupbook* p = GetSupbook(nXti);
+ return p ? p->GetTabName(nXtiTab) : EMPTY_STRING;
+}
+
+bool XclImpLinkManagerImpl::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
+ return pSupbook && pSupbook->GetLinkData( rApplic, rTopic );
+}
+
+const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
+ return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
+}
+
+const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
+{
+ return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0;
+}
+
+const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
+{
+ const XclImpXti* pXti = GetXti( nXtiIndex );
+ return pXti ? maSupbookList.GetObject( pXti->mnSupbook ) : 0;
+}
+
+//UNUSED2009-05 const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( const String& rUrl ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 for( const XclImpSupbook* pSupbook = maSupbookList.First(); pSupbook; pSupbook = maSupbookList.Next() )
+//UNUSED2009-05 if( pSupbook->GetXclUrl() == rUrl )
+//UNUSED2009-05 return pSupbook;
+//UNUSED2009-05 return 0;
+//UNUSED2009-05 }
+
+void XclImpLinkManagerImpl::LoadCachedValues()
+{
+ // Read all CRN records which can be accessed via XclImpSupbook, and store
+ // the cached values to the external reference manager.
+
+ sal_uInt32 nCount = maSupbookList.Count();
+ for (sal_uInt16 nSupbook = 0; nSupbook < nCount; ++nSupbook)
+ {
+ XclImpSupbook* pSupbook = maSupbookList.GetObject(nSupbook);
+ pSupbook->LoadCachedValues();
+ }
+}
+
+//UNUSED2009-05 bool XclImpLinkManagerImpl::FindNextTabRange(
+//UNUSED2009-05 sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
+//UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const
+//UNUSED2009-05 {
+//UNUSED2009-05 rnSBTabFirst = rnSBTabLast = EXC_NOTAB;
+//UNUSED2009-05 for( const XclImpXti* pXti = maXtiList.First(); pXti; pXti = maXtiList.Next() )
+//UNUSED2009-05 {
+//UNUSED2009-05 if( (nSupbook == pXti->mnSupbook) && (nSBTabStart <= pXti->mnSBTabLast) && (pXti->mnSBTabFirst < rnSBTabFirst) )
+//UNUSED2009-05 {
+//UNUSED2009-05 rnSBTabFirst = ::std::max( nSBTabStart, pXti->mnSBTabFirst );
+//UNUSED2009-05 rnSBTabLast = pXti->mnSBTabLast;
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 return rnSBTabFirst != EXC_NOTAB;
+//UNUSED2009-05 }
+
+// ============================================================================
+
+XclImpLinkManager::XclImpLinkManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mxImpl( new XclImpLinkManagerImpl( rRoot ) )
+{
+}
+
+XclImpLinkManager::~XclImpLinkManager()
+{
+}
+
+void XclImpLinkManager::ReadExternsheet( XclImpStream& rStrm )
+{
+ mxImpl->ReadExternsheet( rStrm );
+}
+
+void XclImpLinkManager::ReadSupbook( XclImpStream& rStrm )
+{
+ mxImpl->ReadSupbook( rStrm );
+}
+
+void XclImpLinkManager::ReadXct( XclImpStream& rStrm )
+{
+ mxImpl->ReadXct( rStrm );
+}
+
+void XclImpLinkManager::ReadCrn( XclImpStream& rStrm )
+{
+ mxImpl->ReadCrn( rStrm );
+}
+
+void XclImpLinkManager::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+{
+ mxImpl->ReadExternname( rStrm, pFormulaConv );
+}
+
+bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->IsSelfRef( nXtiIndex );
+}
+
+bool XclImpLinkManager::GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->GetScTabRange( rnFirstScTab, rnLastScTab, nXtiIndex );
+}
+
+const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
+{
+ return mxImpl->GetExternName( nXtiIndex, nExtName );
+}
+
+const String* XclImpLinkManager::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->GetSupbookUrl(nXtiIndex);
+}
+
+const String& XclImpLinkManager::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
+{
+ return mxImpl->GetSupbookTabName(nXti, nXtiTab);
+}
+
+bool XclImpLinkManager::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
+}
+
+const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
+{
+ return mxImpl->GetMacroName( nExtSheet, nExtName );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx
new file mode 100644
index 000000000000..3d373f6c36ba
--- /dev/null
+++ b/sc/source/filter/excel/xiname.cxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xiname.hxx"
+#include "rangenam.hxx"
+#include "xistream.hxx"
+
+// for formula compiler
+#include "excform.hxx"
+// for filter manager
+#include "excimp8.hxx"
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) :
+ XclImpRoot( rStrm.GetRoot() ),
+ mpScData( 0 ),
+ mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
+ mnScTab( SCTAB_MAX ),
+ mbFunction( false ),
+ mbVBName( false )
+{
+ ExcelToSc& rFmlaConv = GetOldFmlaConverter();
+ ScRangeName& rRangeNames = GetNamedRanges();
+
+ // 1) *** read data from stream *** ---------------------------------------
+
+ sal_uInt16 nFlags = 0, nFmlaSize = 0, nExtSheet = EXC_NAME_GLOBAL, nXclTab = EXC_NAME_GLOBAL;
+ sal_uInt8 nNameLen = 0, nShortCut;
+
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ {
+ sal_uInt8 nFlagsBiff2;
+ rStrm >> nFlagsBiff2;
+ rStrm.Ignore( 1 );
+ rStrm >> nShortCut >> nNameLen;
+ nFmlaSize = rStrm.ReaduInt8();
+ ::set_flag( nFlags, EXC_NAME_FUNC, ::get_flag( nFlagsBiff2, EXC_NAME2_FUNC ) );
+ }
+ break;
+
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ {
+ rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize;
+ }
+ break;
+
+ case EXC_BIFF5:
+ case EXC_BIFF8:
+ {
+ rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize >> nExtSheet >> nXclTab;
+ rStrm.Ignore( 4 );
+ }
+ break;
+
+ default: DBG_ERROR_BIFF();
+ }
+
+ if( GetBiff() <= EXC_BIFF5 )
+ maXclName = rStrm.ReadRawByteString( nNameLen );
+ else
+ maXclName = rStrm.ReadUniString( nNameLen );
+
+ // 2) *** convert sheet index and name *** --------------------------------
+
+ // functions and VBA
+ mbFunction = ::get_flag( nFlags, EXC_NAME_FUNC );
+ mbVBName = ::get_flag( nFlags, EXC_NAME_VB );
+
+ // get built-in name, or convert characters invalid in Calc
+ bool bBuiltIn = ::get_flag( nFlags, EXC_NAME_BUILTIN );
+
+ // special case for BIFF5 filter range - name appears as plain text without built-in flag
+ if( (GetBiff() == EXC_BIFF5) && (maXclName == XclTools::GetXclBuiltInDefName( EXC_BUILTIN_FILTERDATABASE )) )
+ {
+ bBuiltIn = true;
+ maXclName.Assign( EXC_BUILTIN_FILTERDATABASE );
+ }
+
+ // convert Excel name to Calc name
+ if( mbVBName )
+ {
+ // VB macro name
+ maScName = maXclName;
+ }
+ else if( bBuiltIn )
+ {
+ // built-in name
+ if( maXclName.Len() )
+ mcBuiltIn = maXclName.GetChar( 0 );
+ if( mcBuiltIn == '?' ) // NUL character is imported as '?'
+ mcBuiltIn = '\0';
+ maScName = XclTools::GetBuiltInDefName( mcBuiltIn );
+ }
+ else
+ {
+ // any other name
+ maScName = maXclName;
+ ScfTools::ConvertToScDefinedName( maScName );
+ }
+
+ // add index for local names
+ if( nXclTab != EXC_NAME_GLOBAL )
+ {
+ sal_uInt16 nUsedTab = (GetBiff() == EXC_BIFF8) ? nXclTab : nExtSheet;
+ // #163146# do not rename sheet-local names by default, this breaks VBA scripts
+// maScName.Append( '_' ).Append( String::CreateFromInt32( nUsedTab ) );
+ // TODO: may not work for BIFF5, handle skipped sheets (all BIFF)
+ mnScTab = static_cast< SCTAB >( nUsedTab - 1 );
+ }
+
+ // find an unused name
+ String aOrigName( maScName );
+ sal_Int32 nCounter = 0;
+ USHORT nDummy;
+ while( rRangeNames.SearchName( maScName, nDummy ) )
+ maScName.Assign( aOrigName ).Append( ' ' ).Append( String::CreateFromInt32( ++nCounter ) );
+
+ // 3) *** convert the name definition formula *** -------------------------
+
+ rFmlaConv.Reset();
+ const ScTokenArray* pTokArr = 0; // pointer to token array, owned by rFmlaConv
+ RangeType nNameType = RT_NAME;
+
+ if( ::get_flag( nFlags, EXC_NAME_BIG ) )
+ {
+ // special, unsupported name
+ rFmlaConv.GetDummy( pTokArr );
+ }
+ else if( bBuiltIn )
+ {
+ // --- print ranges or title ranges ---
+ rStrm.PushPosition();
+ switch( mcBuiltIn )
+ {
+ case EXC_BUILTIN_PRINTAREA:
+ if( rFmlaConv.Convert( GetPrintAreaBuffer(), rStrm, nFmlaSize, FT_RangeName ) == ConvOK )
+ nNameType |= RT_PRINTAREA;
+ break;
+ case EXC_BUILTIN_PRINTTITLES:
+ if( rFmlaConv.Convert( GetTitleAreaBuffer(), rStrm, nFmlaSize, FT_RangeName ) == ConvOK )
+ nNameType |= RT_COLHEADER | RT_ROWHEADER;
+ break;
+ }
+ rStrm.PopPosition();
+
+ // --- name formula ---
+ // JEG : double check this. It is clearly false for normal names
+ // but some of the builtins (sheettitle?) might be able to handle arrays
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize, false, FT_RangeName );
+
+ // --- auto or advanced filter ---
+ if( (GetBiff() == EXC_BIFF8) && pTokArr && bBuiltIn )
+ {
+ ScRange aRange;
+ if( pTokArr->IsReference( aRange ) )
+ {
+ switch( mcBuiltIn )
+ {
+ case EXC_BUILTIN_FILTERDATABASE:
+ GetFilterManager().Insert( &GetOldRoot(), aRange, maScName );
+ break;
+ case EXC_BUILTIN_CRITERIA:
+ GetFilterManager().AddAdvancedRange( aRange );
+ nNameType |= RT_CRITERIA;
+ break;
+ case EXC_BUILTIN_EXTRACT:
+ if( pTokArr->IsValidReference( aRange ) )
+ GetFilterManager().AddExtractPos( aRange );
+ break;
+ }
+ }
+ }
+ }
+ else if( nFmlaSize > 0 )
+ {
+ // regular defined name
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize, true, FT_RangeName );
+ }
+
+ // 4) *** create a defined name in the Calc document *** ------------------
+
+ // #163146# do not ignore hidden names (may be regular names created by VBA scripts)
+ if( pTokArr /*&& (bBuiltIn || !::get_flag( nFlags, EXC_NAME_HIDDEN ))*/ && !mbFunction && !mbVBName )
+ {
+ // create the Calc name data
+ ScRangeData* pData = new ScRangeData( GetDocPtr(), maScName, *pTokArr, ScAddress(), nNameType );
+ pData->GuessPosition(); // calculate base position for relative refs
+ pData->SetIndex( nXclNameIdx ); // used as unique identifier in formulas
+ rRangeNames.Insert( pData ); // takes ownership of pData
+ mpScData = pData; // cache for later use
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpNameManager::ReadName( XclImpStream& rStrm )
+{
+ ULONG nCount = maNameList.Count();
+ if( nCount < 0xFFFF )
+ maNameList.Append( new XclImpName( rStrm, static_cast< sal_uInt16 >( nCount + 1 ) ) );
+}
+
+const XclImpName* XclImpNameManager::FindName( const String& rXclName, SCTAB nScTab ) const
+{
+ const XclImpName* pGlobalName = 0; // a found global name
+ const XclImpName* pLocalName = 0; // a found local name
+ for( const XclImpName* pName = maNameList.First(); pName && !pLocalName; pName = maNameList.Next() )
+ {
+ if( pName->GetXclName() == rXclName )
+ {
+ if( pName->GetScTab() == nScTab )
+ pLocalName = pName;
+ else if( pName->IsGlobal() )
+ pGlobalName = pName;
+ }
+ }
+ return pLocalName ? pLocalName : pGlobalName;
+}
+
+const XclImpName* XclImpNameManager::GetName( sal_uInt16 nXclNameIdx ) const
+{
+ DBG_ASSERT( nXclNameIdx > 0, "XclImpNameManager::GetName - index must be >0" );
+ return maNameList.GetObject( nXclNameIdx - 1 );
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xipage.cxx b/sc/source/filter/excel/xipage.cxx
new file mode 100644
index 000000000000..38cebc2e6ca8
--- /dev/null
+++ b/sc/source/filter/excel/xipage.cxx
@@ -0,0 +1,390 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xipage.hxx"
+#include <svl/itemset.hxx>
+#include <vcl/graph.hxx>
+#include "scitems.hxx"
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include "document.hxx"
+#include "stlsheet.hxx"
+#include "attrib.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xiescher.hxx"
+
+// Page settings ==============================================================
+
+XclImpPageSettings::XclImpPageSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+ Initialize();
+}
+
+void XclImpPageSettings::Initialize()
+{
+ maData.SetDefaults();
+ mbValidPaper = false;
+}
+
+void XclImpPageSettings::ReadSetup( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF4 );
+ if( GetBiff() < EXC_BIFF4 )
+ return;
+
+ // BIFF4 - BIFF8
+ sal_uInt16 nFlags;
+ rStrm >> maData.mnPaperSize >> maData.mnScaling >> maData.mnStartPage
+ >> maData.mnFitToWidth >> maData.mnFitToHeight >> nFlags;
+
+ mbValidPaper = maData.mbValid = !::get_flag( nFlags, EXC_SETUP_INVALID );
+ maData.mbPrintInRows = ::get_flag( nFlags, EXC_SETUP_INROWS );
+ maData.mbPortrait = ::get_flag( nFlags, EXC_SETUP_PORTRAIT );
+ maData.mbBlackWhite = ::get_flag( nFlags, EXC_SETUP_BLACKWHITE );
+ maData.mbManualStart = true;
+
+ // new in BIFF5 - BIFF8
+ if( GetBiff() >= EXC_BIFF5 )
+ {
+ rStrm >> maData.mnHorPrintRes >> maData.mnVerPrintRes
+ >> maData.mfHeaderMargin >> maData.mfFooterMargin >> maData.mnCopies;
+
+ maData.mbDraftQuality = ::get_flag( nFlags, EXC_SETUP_DRAFT );
+ maData.mbPrintNotes = ::get_flag( nFlags, EXC_SETUP_PRINTNOTES );
+ maData.mbManualStart = ::get_flag( nFlags, EXC_SETUP_STARTPAGE );
+ }
+}
+
+void XclImpPageSettings::ReadMargin( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_LEFTMARGIN: rStrm >> maData.mfLeftMargin; break;
+ case EXC_ID_RIGHTMARGIN: rStrm >> maData.mfRightMargin; break;
+ case EXC_ID_TOPMARGIN: rStrm >> maData.mfTopMargin; break;
+ case EXC_ID_BOTTOMMARGIN: rStrm >> maData.mfBottomMargin; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadMargin - unknown record" );
+ }
+}
+
+void XclImpPageSettings::ReadCenter( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 ); // read it anyway
+ bool bCenter = (rStrm.ReaduInt16() != 0);
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HCENTER: maData.mbHorCenter = bCenter; break;
+ case EXC_ID_VCENTER: maData.mbVerCenter = bCenter; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadCenter - unknown record" );
+ }
+}
+
+void XclImpPageSettings::ReadHeaderFooter( XclImpStream& rStrm )
+{
+ String aString;
+ if( rStrm.GetRecLeft() )
+ aString = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
+
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HEADER: maData.maHeader = aString; break;
+ case EXC_ID_FOOTER: maData.maFooter = aString; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadHeaderFooter - unknown record" );
+ }
+}
+
+void XclImpPageSettings::ReadPageBreaks( XclImpStream& rStrm )
+{
+ ScfUInt16Vec* pVec = 0;
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HORPAGEBREAKS: pVec = &maData.maHorPageBreaks; break;
+ case EXC_ID_VERPAGEBREAKS: pVec = &maData.maVerPageBreaks; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadPageBreaks - unknown record" );
+ }
+
+ if( pVec )
+ {
+ bool bIgnore = GetBiff() == EXC_BIFF8; // ignore start/end columns or rows in BIFF8
+
+ sal_uInt16 nCount, nBreak;
+ rStrm >> nCount;
+ pVec->clear();
+ pVec->reserve( nCount );
+
+ while( nCount-- )
+ {
+ rStrm >> nBreak;
+ if( nBreak )
+ pVec->push_back( nBreak );
+ if( bIgnore )
+ rStrm.Ignore( 4 );
+ }
+ }
+}
+
+void XclImpPageSettings::ReadPrintHeaders( XclImpStream& rStrm )
+{
+ maData.mbPrintHeadings = (rStrm.ReaduInt16() != 0);
+}
+
+void XclImpPageSettings::ReadPrintGridLines( XclImpStream& rStrm )
+{
+ maData.mbPrintGrid = (rStrm.ReaduInt16() != 0);
+}
+
+void XclImpPageSettings::ReadImgData( XclImpStream& rStrm )
+{
+ Graphic aGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+ if( aGraphic.GetType() != GRAPHIC_NONE )
+ maData.mxBrushItem.reset( new SvxBrushItem( aGraphic, GPOS_TILED, ATTR_BACKGROUND ) );
+}
+
+void XclImpPageSettings::SetPaperSize( sal_uInt16 nXclPaperSize, bool bPortrait )
+{
+ maData.mnPaperSize = nXclPaperSize;
+ maData.mbPortrait = bPortrait;
+ mbValidPaper = true;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+void lclPutMarginItem( SfxItemSet& rItemSet, sal_uInt16 nRecId, double fMarginInch )
+{
+ sal_uInt16 nMarginTwips = XclTools::GetTwipsFromInch( fMarginInch );
+ switch( nRecId )
+ {
+ case EXC_ID_TOPMARGIN:
+ case EXC_ID_BOTTOMMARGIN:
+ {
+ SvxULSpaceItem aItem( GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE ) );
+ if( nRecId == EXC_ID_TOPMARGIN )
+ aItem.SetUpperValue( nMarginTwips );
+ else
+ aItem.SetLowerValue( nMarginTwips );
+ rItemSet.Put( aItem );
+ }
+ break;
+ case EXC_ID_LEFTMARGIN:
+ case EXC_ID_RIGHTMARGIN:
+ {
+ SvxLRSpaceItem aItem( GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE ) );
+ if( nRecId == EXC_ID_LEFTMARGIN )
+ aItem.SetLeftValue( nMarginTwips );
+ else
+ aItem.SetRightValue( nMarginTwips );
+ rItemSet.Put( aItem );
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpPageSettings::SetMarginItem - unknown record id" );
+ }
+}
+
+} // namespace
+
+void XclImpPageSettings::Finalize()
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ // *** create page style sheet ***
+
+ String aStyleName( RTL_CONSTASCII_USTRINGPARAM( "PageStyle_" ) );
+ String aTableName;
+ if( GetDoc().GetName( nScTab, aTableName ) )
+ aStyleName.Append( aTableName );
+ else
+ aStyleName.Append( String::CreateFromInt32( nScTab + 1 ) );
+
+ ScStyleSheet& rStyleSheet = ScfTools::MakePageStyleSheet( GetStyleSheetPool(), aStyleName, false );
+ SfxItemSet& rItemSet = rStyleSheet.GetItemSet();
+
+ // *** page settings ***
+
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_TOPDOWN, !maData.mbPrintInRows ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HORCENTER, maData.mbHorCenter ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_VERCENTER, maData.mbVerCenter ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HEADERS, maData.mbPrintHeadings ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_GRID, maData.mbPrintGrid ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_NOTES, maData.mbPrintNotes ), true );
+
+ sal_uInt16 nStartPage = maData.mbManualStart ? maData.mnStartPage : 0;
+ ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, nStartPage ), true );
+
+ if( maData.mxBrushItem.get() )
+ rItemSet.Put( *maData.mxBrushItem );
+
+ if( mbValidPaper )
+ {
+ SvxPageItem aPageItem( GETITEM( rItemSet, SvxPageItem, ATTR_PAGE ) );
+ aPageItem.SetLandscape( !maData.mbPortrait );
+ rItemSet.Put( aPageItem );
+ ScfTools::PutItem( rItemSet, SvxSizeItem( ATTR_PAGE_SIZE, maData.GetScPaperSize() ), true );
+ }
+
+ if( maData.mbFitToPages )
+ rItemSet.Put( ScPageScaleToItem( maData.mnFitToWidth, maData.mnFitToHeight ) );
+ else if( maData.mbValid )
+ rItemSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, maData.mnScaling ) );
+
+ // *** margin preparations ***
+
+ double fLeftMargin = maData.mfLeftMargin;
+ double fRightMargin = maData.mfRightMargin;
+ double fTopMargin = maData.mfTopMargin;
+ double fBottomMargin = maData.mfBottomMargin;
+ // distances between header/footer and page area
+ double fHeaderHeight = 0.0;
+ double fHeaderDist = 0.0;
+ double fFooterHeight = 0.0;
+ double fFooterDist = 0.0;
+ // in Calc, "header/footer left/right margin" is X distance between header/footer and page margin
+ double fHdrLeftMargin = maData.mfHdrLeftMargin - maData.mfLeftMargin;
+ double fHdrRightMargin = maData.mfHdrRightMargin - maData.mfRightMargin;
+ double fFtrLeftMargin = maData.mfFtrLeftMargin - maData.mfLeftMargin;
+ double fFtrRightMargin = maData.mfFtrRightMargin - maData.mfRightMargin;
+
+ // *** header and footer ***
+
+ XclImpHFConverter aHFConv( GetRoot() );
+
+ // header
+ bool bHasHeader = (maData.maHeader.Len() != 0);
+ SvxSetItem aHdrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ) );
+ SfxItemSet& rHdrItemSet = aHdrSetItem.GetItemSet();
+ rHdrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasHeader ) );
+ if( bHasHeader )
+ {
+ aHFConv.ParseString( maData.maHeader );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERLEFT );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERRIGHT );
+ // #i23296# In Calc, "top margin" is distance to header
+ fTopMargin = maData.mfHeaderMargin;
+ // Calc uses distance between header and sheet data area
+ fHeaderHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() );
+ fHeaderDist = maData.mfTopMargin - maData.mfHeaderMargin - fHeaderHeight;
+ }
+ if( fHeaderDist < 0.0 )
+ {
+ /* #i23296# Header overlays sheet data:
+ -> set fixed header height to get correct sheet data position. */
+ ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true );
+ // shrink header height
+ long nHdrHeight = XclTools::GetTwipsFromInch( fHeaderHeight + fHeaderDist );
+ ScfTools::PutItem( rHdrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nHdrHeight ) ), true );
+ lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, 0.0 );
+ }
+ else
+ {
+ // use dynamic header height
+ ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true );
+ lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, fHeaderDist );
+ }
+ lclPutMarginItem( rHdrItemSet, EXC_ID_LEFTMARGIN, fHdrLeftMargin );
+ lclPutMarginItem( rHdrItemSet, EXC_ID_RIGHTMARGIN, fHdrRightMargin );
+ rItemSet.Put( aHdrSetItem );
+
+ // footer
+ bool bHasFooter = (maData.maFooter.Len() != 0);
+ SvxSetItem aFtrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ) );
+ SfxItemSet& rFtrItemSet = aFtrSetItem.GetItemSet();
+ rFtrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasFooter ) );
+ if( bHasFooter )
+ {
+ aHFConv.ParseString( maData.maFooter );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERLEFT );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERRIGHT );
+ // #i23296# In Calc, "bottom margin" is distance to footer
+ fBottomMargin = maData.mfFooterMargin;
+ // Calc uses distance between footer and sheet data area
+ fFooterHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() );
+ fFooterDist = maData.mfBottomMargin - maData.mfFooterMargin - fFooterHeight;
+ }
+ if( fFooterDist < 0.0 )
+ {
+ /* #i23296# Footer overlays sheet data:
+ -> set fixed footer height to get correct sheet data end position. */
+ ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true );
+ // shrink footer height
+ long nFtrHeight = XclTools::GetTwipsFromInch( fFooterHeight + fFooterDist );
+ ScfTools::PutItem( rFtrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nFtrHeight ) ), true );
+ lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, 0.0 );
+ }
+ else
+ {
+ // use dynamic footer height
+ ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true );
+ lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, fFooterDist );
+ }
+ lclPutMarginItem( rFtrItemSet, EXC_ID_LEFTMARGIN, fFtrLeftMargin );
+ lclPutMarginItem( rFtrItemSet, EXC_ID_RIGHTMARGIN, fFtrRightMargin );
+ rItemSet.Put( aFtrSetItem );
+
+ // *** set final margins ***
+
+ lclPutMarginItem( rItemSet, EXC_ID_LEFTMARGIN, fLeftMargin );
+ lclPutMarginItem( rItemSet, EXC_ID_RIGHTMARGIN, fRightMargin );
+ lclPutMarginItem( rItemSet, EXC_ID_TOPMARGIN, fTopMargin );
+ lclPutMarginItem( rItemSet, EXC_ID_BOTTOMMARGIN, fBottomMargin );
+
+ // *** put style sheet into document ***
+
+ rDoc.SetPageStyle( nScTab, rStyleSheet.GetName() );
+
+ // *** page breaks ***
+
+ ScfUInt16Vec::const_iterator aIt, aEnd;
+
+ for( aIt = maData.maHorPageBreaks.begin(), aEnd = maData.maHorPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ SCROW nScRow = static_cast< SCROW >( *aIt );
+ if( nScRow <= MAXROW )
+ rDoc.SetRowBreak(nScRow, nScTab, false, true);
+ }
+
+ for( aIt = maData.maVerPageBreaks.begin(), aEnd = maData.maVerPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ SCCOL nScCol = static_cast< SCCOL >( *aIt );
+ if( nScCol <= MAXCOL )
+ rDoc.SetColBreak(nScCol, nScTab, false, true);
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
new file mode 100644
index 000000000000..29e27a698a42
--- /dev/null
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -0,0 +1,1638 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xipivot.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+
+#include <tools/datetime.hxx>
+#include <svl/zformat.hxx>
+#include <svl/intitem.hxx>
+
+#include "document.hxx"
+#include "cell.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dpobject.hxx"
+#include "dpshttab.hxx"
+#include "dpoutputgeometry.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiescher.hxx"
+
+//! TODO ExcelToSc usage
+#include "excform.hxx"
+#include "xltable.hxx"
+
+#include <vector>
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
+using ::com::sun::star::sheet::DataPilotFieldSortInfo;
+using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
+using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::std::vector;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+XclImpPCItem::XclImpPCItem( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_SXDOUBLE: ReadSxdouble( rStrm ); break;
+ case EXC_ID_SXBOOLEAN: ReadSxboolean( rStrm ); break;
+ case EXC_ID_SXERROR: ReadSxerror( rStrm ); break;
+ case EXC_ID_SXINTEGER: ReadSxinteger( rStrm ); break;
+ case EXC_ID_SXSTRING: ReadSxstring( rStrm ); break;
+ case EXC_ID_SXDATETIME: ReadSxdatetime( rStrm ); break;
+ case EXC_ID_SXEMPTY: ReadSxempty( rStrm ); break;
+ default: DBG_ERRORFILE( "XclImpPCItem::XclImpPCItem - unknown record id" );
+ }
+}
+
+namespace {
+
+void lclSetValue( const XclImpRoot& rRoot, const ScAddress& rScPos, double fValue, short nFormatType )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ rDoc.SetValue( rScPos.Col(), rScPos.Row(), rScPos.Tab(), fValue );
+ sal_uInt32 nScNumFmt = rRoot.GetFormatter().GetStandardFormat( nFormatType, rRoot.GetDocLanguage() );
+ rDoc.ApplyAttr( rScPos.Col(), rScPos.Row(), rScPos.Tab(), SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ) );
+}
+
+} // namespace
+
+void XclImpPCItem::WriteToSource( const XclImpRoot& rRoot, const ScAddress& rScPos ) const
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ if( const String* pText = GetText() )
+ rDoc.SetString( rScPos.Col(), rScPos.Row(), rScPos.Tab(), *pText );
+ else if( const double* pfValue = GetDouble() )
+ rDoc.SetValue( rScPos.Col(), rScPos.Row(), rScPos.Tab(), *pfValue );
+ else if( const sal_Int16* pnValue = GetInteger() )
+ rDoc.SetValue( rScPos.Col(), rScPos.Row(), rScPos.Tab(), *pnValue );
+ else if( const bool* pbValue = GetBool() )
+ lclSetValue( rRoot, rScPos, *pbValue ? 1.0 : 0.0, NUMBERFORMAT_LOGICAL );
+ else if( const DateTime* pDateTime = GetDateTime() )
+ {
+ // set number format date, time, or date/time, depending on the value
+ double fValue = rRoot.GetDoubleFromDateTime( *pDateTime );
+ double fInt = 0.0;
+ double fFrac = modf( fValue, &fInt );
+ short nFormatType = ((fFrac == 0.0) && (fInt != 0.0)) ? NUMBERFORMAT_DATE :
+ ((fInt == 0.0) ? NUMBERFORMAT_TIME : NUMBERFORMAT_DATETIME);
+ lclSetValue( rRoot, rScPos, fValue, nFormatType );
+ }
+ else if( const sal_uInt16* pnError = GetError() )
+ {
+ double fValue;
+ sal_uInt8 nErrCode = static_cast< sal_uInt8 >( *pnError );
+ const ScTokenArray* pScTokArr = rRoot.GetOldFmlaConverter().GetBoolErr(
+ XclTools::ErrorToEnum( fValue, EXC_BOOLERR_ERROR, nErrCode ) );
+ ScFormulaCell* pCell = new ScFormulaCell( &rDoc, rScPos, pScTokArr );
+ pCell->SetHybridDouble( fValue );
+ rDoc.PutCell( rScPos, pCell );
+ }
+}
+
+void XclImpPCItem::ReadSxdouble( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 8, "XclImpPCItem::ReadSxdouble - wrong record size" );
+ SetDouble( rStrm.ReadDouble() );
+}
+
+void XclImpPCItem::ReadSxboolean( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxboolean - wrong record size" );
+ SetBool( rStrm.ReaduInt16() != 0 );
+}
+
+void XclImpPCItem::ReadSxerror( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxerror - wrong record size" );
+ SetError( rStrm.ReaduInt16() );
+}
+
+void XclImpPCItem::ReadSxinteger( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxinteger - wrong record size" );
+ SetInteger( rStrm.ReadInt16() );
+}
+
+void XclImpPCItem::ReadSxstring( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() >= 3, "XclImpPCItem::ReadSxstring - wrong record size" );
+ SetText( rStrm.ReadUniString() );
+}
+
+void XclImpPCItem::ReadSxdatetime( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 8, "XclImpPCItem::ReadSxdatetime - wrong record size" );
+ sal_uInt16 nYear, nMonth;
+ sal_uInt8 nDay, nHour, nMin, nSec;
+ rStrm >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec;
+ SetDateTime( DateTime( Date( nDay, nMonth, nYear ), Time( nHour, nMin, nSec ) ) );
+}
+
+void XclImpPCItem::ReadSxempty( XclImpStream& rStrm )
+{
+ (void)rStrm; // avoid compiler warning
+ DBG_ASSERT( rStrm.GetRecSize() == 0, "XclImpPCItem::ReadSxempty - wrong record size" );
+ SetEmpty();
+}
+
+// ============================================================================
+
+XclImpPCField::XclImpPCField( const XclImpRoot& rRoot, XclImpPivotCache& rPCache, sal_uInt16 nFieldIdx ) :
+ XclPCField( EXC_PCFIELD_UNKNOWN, nFieldIdx ),
+ XclImpRoot( rRoot ),
+ mrPCache( rPCache ),
+ mnSourceScCol( -1 ),
+ mbNumGroupInfoRead( false )
+{
+}
+
+XclImpPCField::~XclImpPCField()
+{
+}
+
+// general field/item access --------------------------------------------------
+
+const String& XclImpPCField::GetFieldName( const ScfStringVec& rVisNames ) const
+{
+ if( IsGroupChildField() && (mnFieldIdx < rVisNames.size()) )
+ {
+ const String& rVisName = rVisNames[ mnFieldIdx ];
+ if( rVisName.Len() > 0 )
+ return rVisName;
+ }
+ return maFieldInfo.maName;
+}
+
+const XclImpPCField* XclImpPCField::GetGroupBaseField() const
+{
+ DBG_ASSERT( IsGroupChildField(), "XclImpPCField::GetGroupBaseField - this field type does not have a base field" );
+ return IsGroupChildField() ? mrPCache.GetField( maFieldInfo.mnGroupBase ) : 0;
+}
+
+sal_uInt16 XclImpPCField::GetItemCount() const
+{
+ return static_cast< sal_uInt16 >( maItems.size() );
+}
+
+const XclImpPCItem* XclImpPCField::GetItem( sal_uInt16 nItemIdx ) const
+{
+ return (nItemIdx < maItems.size()) ? maItems[ nItemIdx ].get() : 0;
+}
+
+const XclImpPCItem* XclImpPCField::GetLimitItem( sal_uInt16 nItemIdx ) const
+{
+ DBG_ASSERT( nItemIdx < 3, "XclImpPCField::GetLimitItem - invalid item index" );
+ DBG_ASSERT( nItemIdx < maNumGroupItems.size(), "XclImpPCField::GetLimitItem - no item found" );
+ return (nItemIdx < maNumGroupItems.size()) ? maNumGroupItems[ nItemIdx ].get() : 0;
+}
+
+void XclImpPCField::WriteFieldNameToSource( SCCOL nScCol, SCTAB nScTab ) const
+{
+ DBG_ASSERT( HasOrigItems(), "XclImpPCField::WriteFieldNameToSource - only for standard fields" );
+ GetDoc().SetString( nScCol, 0, nScTab, maFieldInfo.maName );
+ mnSourceScCol = nScCol;
+}
+
+void XclImpPCField::WriteOrigItemToSource( SCROW nScRow, SCTAB nScTab, sal_uInt16 nItemIdx ) const
+{
+ if( nItemIdx < maOrigItems.size() )
+ maOrigItems[ nItemIdx ]->WriteToSource( GetRoot(), ScAddress( mnSourceScCol, nScRow, nScTab ) );
+}
+
+void XclImpPCField::WriteLastOrigItemToSource( SCROW nScRow, SCTAB nScTab ) const
+{
+ if( !maOrigItems.empty() )
+ maOrigItems.back()->WriteToSource( GetRoot(), ScAddress( mnSourceScCol, nScRow, nScTab ) );
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPCField::ReadSxfield( XclImpStream& rStrm )
+{
+ rStrm >> maFieldInfo;
+
+ /* Detect the type of this field. This is done very restrictive to detect
+ any unexpected state. */
+ meFieldType = EXC_PCFIELD_UNKNOWN;
+
+ bool bItems = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASITEMS );
+ bool bPostp = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
+ bool bCalced = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_CALCED );
+ bool bChild = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
+ bool bNum = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_NUMGROUP );
+
+ sal_uInt16 nVisC = maFieldInfo.mnVisItems;
+ sal_uInt16 nGroupC = maFieldInfo.mnGroupItems;
+ sal_uInt16 nBaseC = maFieldInfo.mnBaseItems;
+ sal_uInt16 nOrigC = maFieldInfo.mnOrigItems;
+ DBG_ASSERT( nVisC > 0, "XclImpPCField::ReadSxfield - field without visible items" );
+
+ sal_uInt16 nType = maFieldInfo.mnFlags & EXC_SXFIELD_DATA_MASK;
+ bool bType =
+ (nType == EXC_SXFIELD_DATA_STR) ||
+ (nType == EXC_SXFIELD_DATA_INT) ||
+ (nType == EXC_SXFIELD_DATA_DBL) ||
+ (nType == EXC_SXFIELD_DATA_STR_INT) ||
+ (nType == EXC_SXFIELD_DATA_STR_DBL) ||
+ (nType == EXC_SXFIELD_DATA_DATE) ||
+ (nType == EXC_SXFIELD_DATA_DATE_EMP) ||
+ (nType == EXC_SXFIELD_DATA_DATE_NUM) ||
+ (nType == EXC_SXFIELD_DATA_DATE_STR);
+ bool bTypeNone =
+ (nType == EXC_SXFIELD_DATA_NONE);
+ // for now, ignore data type of calculated fields
+ DBG_ASSERT( bCalced || bType || bTypeNone, "XclImpPCField::ReadSxfield - unknown item data type" );
+
+ if( nVisC > 0 || bPostp )
+ {
+ if( bItems && !bPostp )
+ {
+ if( !bCalced )
+ {
+ // 1) standard fields and standard grouping fields
+ if( !bNum )
+ {
+ // 1a) standard field without grouping
+ if( bType && (nGroupC == 0) && (nBaseC == 0) && (nOrigC == nVisC) )
+ meFieldType = EXC_PCFIELD_STANDARD;
+
+ // 1b) standard grouping field
+ else if( bTypeNone && (nGroupC == nVisC) && (nBaseC > 0) && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_STDGROUP;
+ }
+ // 2) numerical grouping fields
+ else if( (nGroupC == nVisC) && (nBaseC == 0) )
+ {
+ // 2a) single num/date grouping field without child grouping field
+ if( !bChild && bType && (nOrigC > 0) )
+ {
+ switch( nType )
+ {
+ case EXC_SXFIELD_DATA_INT:
+ case EXC_SXFIELD_DATA_DBL: meFieldType = EXC_PCFIELD_NUMGROUP; break;
+ case EXC_SXFIELD_DATA_DATE: meFieldType = EXC_PCFIELD_DATEGROUP; break;
+ default: DBG_ERRORFILE( "XclImpPCField::ReadSxfield - numeric group with wrong data type" );
+ }
+ }
+
+ // 2b) first date grouping field with child grouping field
+ else if( bChild && (nType == EXC_SXFIELD_DATA_DATE) && (nOrigC > 0) )
+ meFieldType = EXC_PCFIELD_DATEGROUP;
+
+ // 2c) additional date grouping field
+ else if( bTypeNone && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_DATECHILD;
+ }
+ DBG_ASSERT( meFieldType != EXC_PCFIELD_UNKNOWN, "XclImpPCField::ReadSxfield - invalid standard or grouped field" );
+ }
+
+ // 3) calculated field
+ else
+ {
+ if( !bChild && !bNum && (nGroupC == 0) && (nBaseC == 0) && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_CALCED;
+ DBG_ASSERT( meFieldType == EXC_PCFIELD_CALCED, "XclImpPCField::ReadSxfield - invalid calculated field" );
+ }
+ }
+
+ else if( !bItems && bPostp )
+ {
+ // 4) standard field with postponed items
+ if( !bCalced && !bChild && !bNum && bType && (nGroupC == 0) && (nBaseC == 0) && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_STANDARD;
+ DBG_ASSERT( meFieldType == EXC_PCFIELD_STANDARD, "XclImpPCField::ReadSxfield - invalid postponed field" );
+ }
+ }
+}
+
+void XclImpPCField::ReadItem( XclImpStream& rStrm )
+{
+ DBG_ASSERT( HasInlineItems() || HasPostponedItems(), "XclImpPCField::ReadItem - field does not expect items" );
+
+ // read the item
+ XclImpPCItemRef xItem( new XclImpPCItem( rStrm ) );
+
+ // try to insert into an item list
+ if( mbNumGroupInfoRead )
+ {
+ // there are 3 items after SXNUMGROUP that contain grouping limits and step count
+ if( maNumGroupItems.size() < 3 )
+ maNumGroupItems.push_back( xItem );
+ else
+ maOrigItems.push_back( xItem );
+ }
+ else if( HasInlineItems() || HasPostponedItems() )
+ {
+ maItems.push_back( xItem );
+ // visible item is original item in standard fields
+ if( IsStandardField() )
+ maOrigItems.push_back( xItem );
+ }
+}
+
+void XclImpPCField::ReadSxnumgroup( XclImpStream& rStrm )
+{
+ DBG_ASSERT( IsNumGroupField() || IsDateGroupField(), "XclImpPCField::ReadSxnumgroup - SXNUMGROUP outside numeric grouping field" );
+ DBG_ASSERT( !mbNumGroupInfoRead, "XclImpPCField::ReadSxnumgroup - multiple SXNUMGROUP records" );
+ DBG_ASSERT( maItems.size() == maFieldInfo.mnGroupItems, "XclImpPCField::ReadSxnumgroup - SXNUMGROUP out of record order" );
+ rStrm >> maNumGroupInfo;
+ mbNumGroupInfoRead = IsNumGroupField() || IsDateGroupField();
+}
+
+void XclImpPCField::ReadSxgroupinfo( XclImpStream& rStrm )
+{
+ DBG_ASSERT( IsStdGroupField(), "XclImpPCField::ReadSxgroupinfo - SXGROUPINFO outside grouping field" );
+ DBG_ASSERT( maGroupOrder.empty(), "XclImpPCField::ReadSxgroupinfo - multiple SXGROUPINFO records" );
+ DBG_ASSERT( maItems.size() == maFieldInfo.mnGroupItems, "XclImpPCField::ReadSxgroupinfo - SXGROUPINFO out of record order" );
+ DBG_ASSERT( (rStrm.GetRecLeft() / 2) == maFieldInfo.mnBaseItems, "XclImpPCField::ReadSxgroupinfo - wrong SXGROUPINFO size" );
+ maGroupOrder.clear();
+ size_t nSize = rStrm.GetRecLeft() / 2;
+ maGroupOrder.resize( nSize, 0 );
+ for( size_t nIdx = 0; nIdx < nSize; ++nIdx )
+ rStrm >> maGroupOrder[ nIdx ];
+}
+
+// grouping -------------------------------------------------------------------
+
+void XclImpPCField::ConvertGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ if( GetFieldName( rVisNames ).Len() > 0 )
+ {
+ if( IsStdGroupField() )
+ ConvertStdGroupField( rSaveData, rVisNames );
+ else if( IsNumGroupField() )
+ ConvertNumGroupField( rSaveData, rVisNames );
+ else if( IsDateGroupField() )
+ ConvertDateGroupField( rSaveData, rVisNames );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpPCField::ConvertStdGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ if( const XclImpPCField* pBaseField = GetGroupBaseField() )
+ {
+ const String& rBaseFieldName = pBaseField->GetFieldName( rVisNames );
+ if( rBaseFieldName.Len() > 0 )
+ {
+ // *** create a ScDPSaveGroupItem for each own item, they collect base item names ***
+ typedef ::std::vector< ScDPSaveGroupItem > ScDPSaveGroupItemVec;
+ ScDPSaveGroupItemVec aGroupItems;
+ aGroupItems.reserve( maItems.size() );
+ // initialize with own item names
+ for( XclImpPCItemVec::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
+ aGroupItems.push_back( ScDPSaveGroupItem( (*aIt)->ConvertToText() ) );
+
+ // *** iterate over all base items, set their names at corresponding own items ***
+ for( sal_uInt16 nItemIdx = 0, nItemCount = static_cast< sal_uInt16 >( maGroupOrder.size() ); nItemIdx < nItemCount; ++nItemIdx )
+ if( maGroupOrder[ nItemIdx ] < aGroupItems.size() )
+ if( const XclImpPCItem* pBaseItem = pBaseField->GetItem( nItemIdx ) )
+ if( const XclImpPCItem* pGroupItem = GetItem( maGroupOrder[ nItemIdx ] ) )
+ if( *pBaseItem != *pGroupItem )
+ aGroupItems[ maGroupOrder[ nItemIdx ] ].AddElement( pBaseItem->ConvertToText() );
+
+ // *** create the ScDPSaveGroupDimension object, fill with grouping info ***
+ ScDPSaveGroupDimension aGroupDim( rBaseFieldName, GetFieldName( rVisNames ) );
+ for( ScDPSaveGroupItemVec::const_iterator aIt = aGroupItems.begin(), aEnd = aGroupItems.end(); aIt != aEnd; ++aIt )
+ if( !aIt->IsEmpty() )
+ aGroupDim.AddGroupItem( *aIt );
+ rSaveData.GetDimensionData()->AddGroupDimension( aGroupDim );
+ }
+ }
+}
+
+void XclImpPCField::ConvertNumGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ ScDPNumGroupInfo aNumInfo( GetScNumGroupInfo() );
+ ScDPSaveNumGroupDimension aNumGroupDim( GetFieldName( rVisNames ), aNumInfo );
+ rSaveData.GetDimensionData()->AddNumGroupDimension( aNumGroupDim );
+}
+
+void XclImpPCField::ConvertDateGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ ScDPNumGroupInfo aDateInfo( GetScDateGroupInfo() );
+ sal_Int32 nScDateType = maNumGroupInfo.GetScDateType();
+
+ switch( meFieldType )
+ {
+ case EXC_PCFIELD_DATEGROUP:
+ {
+ if( aDateInfo.DateValues )
+ {
+ // special case for days only with step value - create numeric grouping
+ ScDPSaveNumGroupDimension aNumGroupDim( GetFieldName( rVisNames ), aDateInfo );
+ rSaveData.GetDimensionData()->AddNumGroupDimension( aNumGroupDim );
+ }
+ else
+ {
+ ScDPSaveNumGroupDimension aNumGroupDim( GetFieldName( rVisNames ), ScDPNumGroupInfo() );
+ aNumGroupDim.SetDateInfo( aDateInfo, nScDateType );
+ rSaveData.GetDimensionData()->AddNumGroupDimension( aNumGroupDim );
+ }
+ }
+ break;
+
+ case EXC_PCFIELD_DATECHILD:
+ {
+ if( const XclImpPCField* pBaseField = GetGroupBaseField() )
+ {
+ const String& rBaseFieldName = pBaseField->GetFieldName( rVisNames );
+ if( rBaseFieldName.Len() > 0 )
+ {
+ ScDPSaveGroupDimension aGroupDim( rBaseFieldName, GetFieldName( rVisNames ) );
+ aGroupDim.SetDateInfo( aDateInfo, nScDateType );
+ rSaveData.GetDimensionData()->AddGroupDimension( aGroupDim );
+ }
+ }
+ }
+ break;
+
+ default:
+ DBG_ERRORFILE( "XclImpPCField::ConvertDateGroupField - unknown date field type" );
+ }
+}
+
+ScDPNumGroupInfo XclImpPCField::GetScNumGroupInfo() const
+{
+ ScDPNumGroupInfo aNumInfo;
+ aNumInfo.Enable = sal_True;
+ aNumInfo.DateValues = sal_False;
+ aNumInfo.AutoStart = sal_True;
+ aNumInfo.AutoEnd = sal_True;
+
+ if( const double* pfMinValue = GetNumGroupLimit( EXC_SXFIELD_INDEX_MIN ) )
+ {
+ aNumInfo.Start = *pfMinValue;
+ aNumInfo.AutoStart = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN );
+ }
+ if( const double* pfMaxValue = GetNumGroupLimit( EXC_SXFIELD_INDEX_MAX ) )
+ {
+ aNumInfo.End = *pfMaxValue;
+ aNumInfo.AutoEnd = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX );
+ }
+ if( const double* pfStepValue = GetNumGroupLimit( EXC_SXFIELD_INDEX_STEP ) )
+ aNumInfo.Step = *pfStepValue;
+
+ return aNumInfo;
+}
+
+ScDPNumGroupInfo XclImpPCField::GetScDateGroupInfo() const
+{
+ ScDPNumGroupInfo aDateInfo;
+ aDateInfo.Enable = sal_True;
+ aDateInfo.DateValues = sal_False;
+ aDateInfo.AutoStart = sal_True;
+ aDateInfo.AutoEnd = sal_True;
+
+ if( const DateTime* pMinDate = GetDateGroupLimit( EXC_SXFIELD_INDEX_MIN ) )
+ {
+ aDateInfo.Start = GetDoubleFromDateTime( *pMinDate );
+ aDateInfo.AutoStart = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN );
+ }
+ if( const DateTime* pMaxDate = GetDateGroupLimit( EXC_SXFIELD_INDEX_MAX ) )
+ {
+ aDateInfo.End = GetDoubleFromDateTime( *pMaxDate );
+ aDateInfo.AutoEnd = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX );
+ }
+ // GetDateGroupStep() returns a value for date type "day" in single date groups only
+ if( const sal_Int16* pnStepValue = GetDateGroupStep() )
+ {
+ aDateInfo.Step = *pnStepValue;
+ aDateInfo.DateValues = sal_True;
+ }
+
+ return aDateInfo;
+}
+
+const double* XclImpPCField::GetNumGroupLimit( sal_uInt16 nLimitIdx ) const
+{
+ DBG_ASSERT( IsNumGroupField(), "XclImpPCField::GetNumGroupLimit - only for numeric grouping fields" );
+ if( const XclImpPCItem* pItem = GetLimitItem( nLimitIdx ) )
+ {
+ DBG_ASSERT( pItem->GetDouble(), "XclImpPCField::GetNumGroupLimit - SXDOUBLE item expected" );
+ return pItem->GetDouble();
+ }
+ return 0;
+}
+
+const DateTime* XclImpPCField::GetDateGroupLimit( sal_uInt16 nLimitIdx ) const
+{
+ DBG_ASSERT( IsDateGroupField(), "XclImpPCField::GetDateGroupLimit - only for date grouping fields" );
+ if( const XclImpPCItem* pItem = GetLimitItem( nLimitIdx ) )
+ {
+ DBG_ASSERT( pItem->GetDateTime(), "XclImpPCField::GetDateGroupLimit - SXDATETIME item expected" );
+ return pItem->GetDateTime();
+ }
+ return 0;
+}
+
+const sal_Int16* XclImpPCField::GetDateGroupStep() const
+{
+ // only for single date grouping fields, not for grouping chains
+ if( !IsGroupBaseField() && !IsGroupChildField() )
+ {
+ // only days may have a step value, return 0 for all other date types
+ if( maNumGroupInfo.GetXclDataType() == EXC_SXNUMGROUP_TYPE_DAY )
+ {
+ if( const XclImpPCItem* pItem = GetLimitItem( EXC_SXFIELD_INDEX_STEP ) )
+ {
+ DBG_ASSERT( pItem->GetInteger(), "XclImpPCField::GetDateGroupStep - SXINTEGER item expected" );
+ if( const sal_Int16* pnStep = pItem->GetInteger() )
+ {
+ DBG_ASSERT( *pnStep > 0, "XclImpPCField::GetDateGroupStep - invalid step count" );
+ // return nothing for step count 1 - this is also a standard date group in Excel
+ return (*pnStep > 1) ? pnStep : 0;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+// ============================================================================
+
+XclImpPivotCache::XclImpPivotCache( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maSrcRange( ScAddress::INITIALIZE_INVALID ),
+ mnStrmId( 0 ),
+ mnSrcType( EXC_SXVS_UNKNOWN ),
+ mbSelfRef( false )
+{
+}
+
+XclImpPivotCache::~XclImpPivotCache()
+{
+}
+
+// data access ----------------------------------------------------------------
+
+sal_uInt16 XclImpPivotCache::GetFieldCount() const
+{
+ return static_cast< sal_uInt16 >( maFields.size() );
+}
+
+const XclImpPCField* XclImpPivotCache::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return (nFieldIdx < maFields.size()) ? maFields[ nFieldIdx ].get() : 0;
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPivotCache::ReadSxidstm( XclImpStream& rStrm )
+{
+ rStrm >> mnStrmId;
+}
+
+void XclImpPivotCache::ReadSxvs( XclImpStream& rStrm )
+{
+ rStrm >> mnSrcType;
+ GetTracer().TracePivotDataSource( mnSrcType != EXC_SXVS_SHEET );
+}
+
+void XclImpPivotCache::ReadDconref( XclImpStream& rStrm )
+{
+ /* Read DCONREF only once (by checking maTabName), there may be other
+ DCONREF records in another context. Read reference only if a leading
+ SXVS record is present (by checking mnSrcType). */
+ if( (maTabName.Len() > 0) || (mnSrcType != EXC_SXVS_SHEET) )
+ return;
+
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ aXclRange.Read( rStrm, false );
+ String aEncUrl = rStrm.ReadUniString();
+
+ XclImpUrlHelper::DecodeUrl( maUrl, maTabName, mbSelfRef, GetRoot(), aEncUrl );
+
+ /* Do not convert maTabName to Calc sheet name -> original name is used to
+ find the sheet in the document. Sheet index of source range will be
+ found later in XclImpPivotCache::ReadPivotCacheStream(), because sheet
+ may not exist yet. */
+ if( mbSelfRef )
+ GetAddressConverter().ConvertRange( maSrcRange, aXclRange, 0, 0, true );
+}
+
+void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm )
+{
+ if( (mnSrcType != EXC_SXVS_SHEET) && (mnSrcType != EXC_SXVS_EXTERN) )
+ return;
+
+ ScDocument& rDoc = GetDoc();
+ SCCOL nFieldScCol = 0; // column index of source data for next field
+ SCROW nItemScRow = 0; // row index of source data for current items
+ SCTAB nScTab = 0; // sheet index of source data
+ bool bGenerateSource = false; // true = write source data from cache to dummy table
+
+ if( mbSelfRef )
+ {
+ // try to find internal sheet containing the source data
+ nScTab = GetTabInfo().GetScTabFromXclName( maTabName );
+ if( rDoc.HasTable( nScTab ) )
+ {
+ // set sheet index to source range
+ maSrcRange.aStart.SetTab( nScTab );
+ maSrcRange.aEnd.SetTab( nScTab );
+ }
+ else
+ {
+ // create dummy sheet for deleted internal sheet
+ bGenerateSource = true;
+ }
+ }
+ else
+ {
+ // create dummy sheet for external sheet
+ bGenerateSource = true;
+ }
+
+ // create dummy sheet for source data from external or deleted sheet
+ if( bGenerateSource )
+ {
+ if( rDoc.GetTableCount() >= MAXTABCOUNT )
+ // cannot create more sheets -> exit
+ return;
+
+ nScTab = rDoc.GetTableCount();
+ rDoc.MakeTable( nScTab );
+ String aDummyName = CREATE_STRING( "DPCache" );
+ if( maTabName.Len() > 0 )
+ aDummyName.Append( '_' ).Append( maTabName );
+ rDoc.CreateValidTabName( aDummyName );
+ rDoc.RenameTab( nScTab, aDummyName );
+ // set sheet index to source range
+ maSrcRange.aStart.SetTab( nScTab );
+ maSrcRange.aEnd.SetTab( nScTab );
+ }
+
+ // open pivot cache storage stream
+ SotStorageRef xSvStrg = OpenStorage( EXC_STORAGE_PTCACHE );
+ SotStorageStreamRef xSvStrm = OpenStream( xSvStrg, ScfTools::GetHexStr( mnStrmId ) );
+ if( !xSvStrm.Is() )
+ return;
+
+ // create Excel record stream object
+ XclImpStream aPCStrm( *xSvStrm, GetRoot() );
+ aPCStrm.CopyDecrypterFrom( rStrm ); // pivot cache streams are encrypted
+
+ XclImpPCFieldRef xCurrField; // current field for new items
+ XclImpPCFieldVec aOrigFields; // all standard fields with inline original items
+ XclImpPCFieldVec aPostpFields; // all standard fields with postponed original items
+ size_t nPostpIdx = 0; // index to current field with postponed items
+ bool bLoop = true; // true = continue loop
+
+ while( bLoop && aPCStrm.StartNextRecord() )
+ {
+ switch( aPCStrm.GetRecId() )
+ {
+ case EXC_ID_EOF:
+ bLoop = false;
+ break;
+
+ case EXC_ID_SXDB:
+ aPCStrm >> maPCInfo;
+ break;
+
+ case EXC_ID_SXFIELD:
+ {
+ xCurrField.reset();
+ sal_uInt16 nNewFieldIdx = GetFieldCount();
+ if( nNewFieldIdx < EXC_PC_MAXFIELDCOUNT )
+ {
+ xCurrField.reset( new XclImpPCField( GetRoot(), *this, nNewFieldIdx ) );
+ maFields.push_back( xCurrField );
+ xCurrField->ReadSxfield( aPCStrm );
+ if( xCurrField->HasOrigItems() )
+ {
+ if( xCurrField->HasPostponedItems() )
+ aPostpFields.push_back( xCurrField );
+ else
+ aOrigFields.push_back( xCurrField );
+ // insert field name into generated source data, field remembers its column index
+ if( bGenerateSource && (nFieldScCol <= MAXCOL) )
+ xCurrField->WriteFieldNameToSource( nFieldScCol++, nScTab );
+ }
+ // do not read items into invalid/postponed fields
+ if( !xCurrField->HasInlineItems() )
+ xCurrField.reset();
+ }
+ }
+ break;
+
+ case EXC_ID_SXINDEXLIST:
+ // read index list and insert all items into generated source data
+ if( bGenerateSource && (nItemScRow <= MAXROW) && (++nItemScRow <= MAXROW) )
+ {
+ for( XclImpPCFieldVec::const_iterator aIt = aOrigFields.begin(), aEnd = aOrigFields.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt16 nItemIdx = (*aIt)->Has16BitIndexes() ? aPCStrm.ReaduInt16() : aPCStrm.ReaduInt8();
+ (*aIt)->WriteOrigItemToSource( nItemScRow, nScTab, nItemIdx );
+ }
+ }
+ xCurrField.reset();
+ break;
+
+ case EXC_ID_SXDOUBLE:
+ case EXC_ID_SXBOOLEAN:
+ case EXC_ID_SXERROR:
+ case EXC_ID_SXINTEGER:
+ case EXC_ID_SXSTRING:
+ case EXC_ID_SXDATETIME:
+ case EXC_ID_SXEMPTY:
+ if( xCurrField.is() ) // inline items
+ {
+ xCurrField->ReadItem( aPCStrm );
+ }
+ else if( !aPostpFields.empty() ) // postponed items
+ {
+ // read postponed item
+ aPostpFields[ nPostpIdx ]->ReadItem( aPCStrm );
+ // write item to source
+ if( bGenerateSource && (nItemScRow <= MAXROW) )
+ {
+ // start new row, if there are only postponed fields
+ if( aOrigFields.empty() && (nPostpIdx == 0) )
+ ++nItemScRow;
+ if( nItemScRow <= MAXROW )
+ aPostpFields[ nPostpIdx ]->WriteLastOrigItemToSource( nItemScRow, nScTab );
+ }
+ // get index of next postponed field
+ ++nPostpIdx;
+ if( nPostpIdx >= aPostpFields.size() )
+ nPostpIdx = 0;
+ }
+ break;
+
+ case EXC_ID_SXNUMGROUP:
+ if( xCurrField.is() )
+ xCurrField->ReadSxnumgroup( aPCStrm );
+ break;
+
+ case EXC_ID_SXGROUPINFO:
+ if( xCurrField.is() )
+ xCurrField->ReadSxgroupinfo( aPCStrm );
+ break;
+
+ // known but ignored records
+ case EXC_ID_SXRULE:
+ case EXC_ID_SXFILT:
+ case EXC_ID_00F5:
+ case EXC_ID_SXNAME:
+ case EXC_ID_SXPAIR:
+ case EXC_ID_SXFMLA:
+ case EXC_ID_SXFORMULA:
+ case EXC_ID_SXDBEX:
+ case EXC_ID_SXFDBTYPE:
+ break;
+
+ default:
+ DBG_ERROR1( "XclImpPivotCache::ReadPivotCacheStream - unknown record 0x%04hX", aPCStrm.GetRecId() );
+ }
+ }
+
+ DBG_ASSERT( maPCInfo.mnTotalFields == maFields.size(),
+ "XclImpPivotCache::ReadPivotCacheStream - field count mismatch" );
+
+ // set source range for external source data
+ if( bGenerateSource && (nFieldScCol > 0) )
+ {
+ maSrcRange.aStart.SetCol( 0 );
+ maSrcRange.aStart.SetRow( 0 );
+ // nFieldScCol points to first unused column
+ maSrcRange.aEnd.SetCol( nFieldScCol - 1 );
+ // nItemScRow points to last used row
+ maSrcRange.aEnd.SetRow( nItemScRow );
+ }
+}
+
+bool XclImpPivotCache::IsRefreshOnLoad() const
+{
+ return static_cast<bool>(maPCInfo.mnFlags & 0x0004);
+}
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+XclImpPTItem::XclImpPTItem( const XclImpPCField* pCacheField ) :
+ mpCacheField( pCacheField )
+{
+}
+
+const String* XclImpPTItem::GetItemName() const
+{
+ if( mpCacheField )
+ if( const XclImpPCItem* pCacheItem = mpCacheField->GetItem( maItemInfo.mnCacheIdx ) )
+ //! TODO: use XclImpPCItem::ConvertToText(), if all conversions are available
+ return pCacheItem->IsEmpty() ? &String::EmptyString() : pCacheItem->GetText();
+ return 0;
+}
+
+const String* XclImpPTItem::GetVisItemName() const
+{
+ return maItemInfo.HasVisName() ? maItemInfo.GetVisName() : GetItemName();
+}
+
+void XclImpPTItem::ReadSxvi( XclImpStream& rStrm )
+{
+ rStrm >> maItemInfo;
+}
+
+void XclImpPTItem::ConvertItem( ScDPSaveDimension& rSaveDim ) const
+{
+ if( const String* pItemName = GetItemName() )
+ {
+ ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName );
+ rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) );
+ rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) );
+ if (maItemInfo.HasVisName())
+ rMember.SetLayoutName(*maItemInfo.GetVisName());
+ }
+}
+
+// ============================================================================
+
+XclImpPTField::XclImpPTField( const XclImpPivotTable& rPTable, sal_uInt16 nCacheIdx ) :
+ mrPTable( rPTable )
+{
+ maFieldInfo.mnCacheIdx = nCacheIdx;
+}
+
+// general field/item access --------------------------------------------------
+
+const XclImpPCField* XclImpPTField::GetCacheField() const
+{
+ XclImpPivotCacheRef xPCache = mrPTable.GetPivotCache();
+ return xPCache.is() ? xPCache->GetField( maFieldInfo.mnCacheIdx ) : 0;
+}
+
+const String& XclImpPTField::GetFieldName() const
+{
+ const XclImpPCField* pField = GetCacheField();
+ return pField ? pField->GetFieldName( mrPTable.GetVisFieldNames() ) : String::EmptyString();
+}
+
+const String& XclImpPTField::GetVisFieldName() const
+{
+ const String* pVisName = maFieldInfo.GetVisName();
+ return pVisName ? *pVisName : String::EmptyString();
+}
+
+const XclImpPTItem* XclImpPTField::GetItem( sal_uInt16 nItemIdx ) const
+{
+ return (nItemIdx < maItems.size()) ? maItems[ nItemIdx ].get() : 0;
+}
+
+const String* XclImpPTField::GetItemName( sal_uInt16 nItemIdx ) const
+{
+ const XclImpPTItem* pItem = GetItem( nItemIdx );
+ return pItem ? pItem->GetItemName() : 0;
+}
+
+const String* XclImpPTField::GetVisItemName( sal_uInt16 nItemIdx ) const
+{
+ const XclImpPTItem* pItem = GetItem( nItemIdx );
+ return pItem ? pItem->GetVisItemName() : 0;
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPTField::ReadSxvd( XclImpStream& rStrm )
+{
+ rStrm >> maFieldInfo;
+}
+
+void XclImpPTField::ReadSxvdex( XclImpStream& rStrm )
+{
+ rStrm >> maFieldExtInfo;
+}
+
+void XclImpPTField::ReadSxvi( XclImpStream& rStrm )
+{
+ XclImpPTItemRef xItem( new XclImpPTItem( GetCacheField() ) );
+ maItems.push_back( xItem );
+ xItem->ReadSxvi( rStrm );
+}
+
+// row/column fields ----------------------------------------------------------
+
+void XclImpPTField::ConvertRowColField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_ROWCOL, "XclImpPTField::ConvertRowColField - no row/column field" );
+ // special data orientation field?
+ if( maFieldInfo.mnCacheIdx == EXC_SXIVD_DATA )
+ rSaveData.GetDataLayoutDimension()->SetOrientation( static_cast< USHORT >( maFieldInfo.GetApiOrient( EXC_SXVD_AXIS_ROWCOL ) ) );
+ else
+ ConvertRCPField( rSaveData );
+}
+
+// page fields ----------------------------------------------------------------
+
+void XclImpPTField::SetPageFieldInfo( const XclPTPageFieldInfo& rPageInfo )
+{
+ maPageInfo = rPageInfo;
+}
+
+void XclImpPTField::ConvertPageField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_PAGE, "XclImpPTField::ConvertPageField - no page field" );
+ if( ScDPSaveDimension* pSaveDim = ConvertRCPField( rSaveData ) )
+ pSaveDim->SetCurrentPage( GetItemName( maPageInfo.mnSelItem ) );
+}
+
+// hidden fields --------------------------------------------------------------
+
+void XclImpPTField::ConvertHiddenField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( (maFieldInfo.mnAxes & EXC_SXVD_AXIS_ROWCOLPAGE) == 0, "XclImpPTField::ConvertHiddenField - field not hidden" );
+ ConvertRCPField( rSaveData );
+}
+
+// data fields ----------------------------------------------------------------
+
+bool XclImpPTField::HasDataFieldInfo() const
+{
+ return !maDataInfoList.empty();
+}
+
+void XclImpPTField::AddDataFieldInfo( const XclPTDataFieldInfo& rDataInfo )
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_DATA, "XclImpPTField::AddDataFieldInfo - no data field" );
+ maDataInfoList.push_back( rDataInfo );
+}
+
+void XclImpPTField::ConvertDataField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_DATA, "XclImpPTField::ConvertDataField - no data field" );
+ DBG_ASSERT( !maDataInfoList.empty(), "XclImpPTField::ConvertDataField - no data field info" );
+ if( !maDataInfoList.empty() )
+ {
+ const String& rFieldName = GetFieldName();
+ if( rFieldName.Len() > 0 )
+ {
+ XclPTDataFieldInfoList::const_iterator aIt = maDataInfoList.begin(), aEnd = maDataInfoList.end();
+
+ ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName );
+ ConvertDataField( rSaveDim, *aIt );
+
+ // multiple data fields -> clone dimension
+ for( ++aIt; aIt != aEnd; ++aIt )
+ {
+ ScDPSaveDimension& rDupDim = rSaveData.DuplicateDimension( rSaveDim );
+ ConvertDataFieldInfo( rDupDim, *aIt );
+ }
+ }
+ }
+}
+
+// private --------------------------------------------------------------------
+
+/**
+ * Convert Excel-encoded subtotal name to a Calc-encoded one.
+ */
+static OUString lcl_convertExcelSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (c == sal_Unicode('\\'))
+ {
+ aBuf.append(c);
+ aBuf.append(c);
+ }
+ else
+ aBuf.append(c);
+ }
+ return aBuf.makeStringAndClear();
+}
+
+ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) const
+{
+ const String& rFieldName = GetFieldName();
+ if( rFieldName.Len() == 0 )
+ return 0;
+
+ const XclImpPCField* pCacheField = GetCacheField();
+ if( !pCacheField || !pCacheField->IsSupportedField() )
+ return 0;
+
+ ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName );
+
+ // orientation
+ rSaveDim.SetOrientation( static_cast< USHORT >( maFieldInfo.GetApiOrient( EXC_SXVD_AXIS_ROWCOLPAGE ) ) );
+
+ // general field info
+ ConvertFieldInfo( rSaveDim );
+
+ // visible name
+ if( const String* pVisName = maFieldInfo.GetVisName() )
+ if( pVisName->Len() > 0 )
+ rSaveDim.SetLayoutName( *pVisName );
+
+ // subtotal function(s)
+ XclPTSubtotalVec aSubtotalVec;
+ maFieldInfo.GetSubtotals( aSubtotalVec );
+ if( !aSubtotalVec.empty() )
+ rSaveDim.SetSubTotals( static_cast< long >( aSubtotalVec.size() ), &aSubtotalVec[ 0 ] );
+
+ // sorting
+ DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Field = mrPTable.GetDataFieldName( maFieldExtInfo.mnSortField );
+ aSortInfo.IsAscending = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SORT_ASC );
+ aSortInfo.Mode = maFieldExtInfo.GetApiSortMode();
+ rSaveDim.SetSortInfo( &aSortInfo );
+
+ // auto show
+ DataPilotFieldAutoShowInfo aShowInfo;
+ aShowInfo.IsEnabled = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_AUTOSHOW );
+ aShowInfo.ShowItemsMode = maFieldExtInfo.GetApiAutoShowMode();
+ aShowInfo.ItemCount = maFieldExtInfo.GetApiAutoShowCount();
+ aShowInfo.DataField = mrPTable.GetDataFieldName( maFieldExtInfo.mnShowField );
+ rSaveDim.SetAutoShowInfo( &aShowInfo );
+
+ // layout
+ DataPilotFieldLayoutInfo aLayoutInfo;
+ aLayoutInfo.LayoutMode = maFieldExtInfo.GetApiLayoutMode();
+ aLayoutInfo.AddEmptyLines = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_LAYOUT_BLANK );
+ rSaveDim.SetLayoutInfo( &aLayoutInfo );
+
+ // grouping info
+ pCacheField->ConvertGroupField( rSaveData, mrPTable.GetVisFieldNames() );
+
+ // custom subtotal name
+ if (maFieldExtInfo.mpFieldTotalName.get())
+ {
+ OUString aSubName = lcl_convertExcelSubtotalName(*maFieldExtInfo.mpFieldTotalName);
+ rSaveDim.SetSubtotalName(aSubName);
+ }
+
+ return &rSaveDim;
+}
+
+void XclImpPTField::ConvertFieldInfo( ScDPSaveDimension& rSaveDim ) const
+{
+ rSaveDim.SetShowEmpty( ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL ) );
+ ConvertItems( rSaveDim );
+}
+
+void XclImpPTField::ConvertDataField( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const
+{
+ // orientation
+ rSaveDim.SetOrientation( DataPilotFieldOrientation_DATA );
+ // general field info
+ ConvertFieldInfo( rSaveDim );
+ // extended data field info
+ ConvertDataFieldInfo( rSaveDim, rDataInfo );
+}
+
+void XclImpPTField::ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const
+{
+ // visible name
+ if( const String* pVisName = rDataInfo.GetVisName() )
+ if( pVisName->Len() > 0 )
+ rSaveDim.SetLayoutName( *pVisName );
+
+ // aggregation function
+ rSaveDim.SetFunction( static_cast< USHORT >( rDataInfo.GetApiAggFunc() ) );
+
+ // result field reference
+ sal_Int32 nRefType = rDataInfo.GetApiRefType();
+ if( nRefType != ::com::sun::star::sheet::DataPilotFieldReferenceType::NONE )
+ {
+ DataPilotFieldReference aFieldRef;
+ aFieldRef.ReferenceType = nRefType;
+
+ if( const XclImpPTField* pRefField = mrPTable.GetField( rDataInfo.mnRefField ) )
+ {
+ aFieldRef.ReferenceField = pRefField->GetFieldName();
+ aFieldRef.ReferenceItemType = rDataInfo.GetApiRefItemType();
+ if( aFieldRef.ReferenceItemType == ::com::sun::star::sheet::DataPilotFieldReferenceItemType::NAMED )
+ if( const String* pRefItemName = pRefField->GetItemName( rDataInfo.mnRefItem ) )
+ aFieldRef.ReferenceItemName = *pRefItemName;
+ }
+
+ rSaveDim.SetReferenceValue( &aFieldRef );
+ }
+}
+
+void XclImpPTField::ConvertItems( ScDPSaveDimension& rSaveDim ) const
+{
+ for( XclImpPTItemVec::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
+ (*aIt)->ConvertItem( rSaveDim );
+}
+
+// ============================================================================
+
+XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maDataOrientField( *this, EXC_SXIVD_DATA ),
+ mpDPObj(NULL)
+{
+}
+
+XclImpPivotTable::~XclImpPivotTable()
+{
+}
+
+// cache/field access, misc. --------------------------------------------------
+
+sal_uInt16 XclImpPivotTable::GetFieldCount() const
+{
+ return static_cast< sal_uInt16 >( maFields.size() );
+}
+
+const XclImpPTField* XclImpPivotTable::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return (nFieldIdx == EXC_SXIVD_DATA) ? &maDataOrientField :
+ ((nFieldIdx < maFields.size()) ? maFields[ nFieldIdx ].get() : 0);
+}
+
+XclImpPTField* XclImpPivotTable::GetFieldAcc( sal_uInt16 nFieldIdx )
+{
+ // do not return maDataOrientField
+ return (nFieldIdx < maFields.size()) ? maFields[ nFieldIdx ].get() : 0;
+}
+
+const String& XclImpPivotTable::GetFieldName( sal_uInt16 nFieldIdx ) const
+{
+ if( const XclImpPTField* pField = GetField( nFieldIdx ) )
+ return pField->GetFieldName();
+ return EMPTY_STRING;
+}
+
+const XclImpPTField* XclImpPivotTable::GetDataField( sal_uInt16 nDataFieldIdx ) const
+{
+ if( nDataFieldIdx < maOrigDataFields.size() )
+ return GetField( maOrigDataFields[ nDataFieldIdx ] );
+ return 0;
+}
+
+const String& XclImpPivotTable::GetDataFieldName( sal_uInt16 nDataFieldIdx ) const
+{
+ if( const XclImpPTField* pField = GetDataField( nDataFieldIdx ) )
+ return pField->GetFieldName();
+ return EMPTY_STRING;
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPivotTable::ReadSxview( XclImpStream& rStrm )
+{
+ rStrm >> maPTInfo;
+
+ GetAddressConverter().ConvertRange(
+ maOutScRange, maPTInfo.maOutXclRange, GetCurrScTab(), GetCurrScTab(), true );
+
+ mxPCache = GetPivotTableManager().GetPivotCache( maPTInfo.mnCacheIdx );
+ mxCurrField.reset();
+}
+
+void XclImpPivotTable::ReadSxvd( XclImpStream& rStrm )
+{
+ sal_uInt16 nFieldCount = GetFieldCount();
+ if( nFieldCount < EXC_PT_MAXFIELDCOUNT )
+ {
+ // cache index for the field is equal to the SXVD record index
+ mxCurrField.reset( new XclImpPTField( *this, nFieldCount ) );
+ maFields.push_back( mxCurrField );
+ mxCurrField->ReadSxvd( rStrm );
+ // add visible name of new field to list of visible names
+ maVisFieldNames.push_back( mxCurrField->GetVisFieldName() );
+ DBG_ASSERT( maFields.size() == maVisFieldNames.size(),
+ "XclImpPivotTable::ReadSxvd - wrong size of visible name array" );
+ }
+ else
+ mxCurrField.reset();
+}
+
+void XclImpPivotTable::ReadSxvi( XclImpStream& rStrm )
+{
+ if( mxCurrField.is() )
+ mxCurrField->ReadSxvi( rStrm );
+}
+
+void XclImpPivotTable::ReadSxvdex( XclImpStream& rStrm )
+{
+ if( mxCurrField.is() )
+ mxCurrField->ReadSxvdex( rStrm );
+}
+
+void XclImpPivotTable::ReadSxivd( XclImpStream& rStrm )
+{
+ mxCurrField.reset();
+
+ // find the index vector to fill (row SXIVD doesn't exist without row fields)
+ ScfUInt16Vec* pFieldVec = 0;
+ if( maRowFields.empty() && (maPTInfo.mnRowFields > 0) )
+ pFieldVec = &maRowFields;
+ else if( maColFields.empty() && (maPTInfo.mnColFields > 0) )
+ pFieldVec = &maColFields;
+
+ // fill the vector from record data
+ if( pFieldVec )
+ {
+ sal_uInt16 nSize = ulimit_cast< sal_uInt16 >( rStrm.GetRecSize() / 2, EXC_PT_MAXROWCOLCOUNT );
+ pFieldVec->reserve( nSize );
+ for( sal_uInt16 nIdx = 0; nIdx < nSize; ++nIdx )
+ {
+ sal_uInt16 nFieldIdx;
+ rStrm >> nFieldIdx;
+ pFieldVec->push_back( nFieldIdx );
+
+ // set orientation at special data orientation field
+ if( nFieldIdx == EXC_SXIVD_DATA )
+ {
+ sal_uInt16 nAxis = (pFieldVec == &maRowFields) ? EXC_SXVD_AXIS_ROW : EXC_SXVD_AXIS_COL;
+ maDataOrientField.SetAxes( nAxis );
+ }
+ }
+ }
+}
+
+void XclImpPivotTable::ReadSxpi( XclImpStream& rStrm )
+{
+ mxCurrField.reset();
+
+ sal_uInt16 nSize = ulimit_cast< sal_uInt16 >( rStrm.GetRecSize() / 6 );
+ for( sal_uInt16 nEntry = 0; nEntry < nSize; ++nEntry )
+ {
+ XclPTPageFieldInfo aPageInfo;
+ rStrm >> aPageInfo;
+ if( XclImpPTField* pField = GetFieldAcc( aPageInfo.mnField ) )
+ {
+ maPageFields.push_back( aPageInfo.mnField );
+ pField->SetPageFieldInfo( aPageInfo );
+ }
+ GetCurrSheetDrawing().SetSkipObj( aPageInfo.mnObjId );
+ }
+}
+
+void XclImpPivotTable::ReadSxdi( XclImpStream& rStrm )
+{
+ mxCurrField.reset();
+
+ XclPTDataFieldInfo aDataInfo;
+ rStrm >> aDataInfo;
+ if( XclImpPTField* pField = GetFieldAcc( aDataInfo.mnField ) )
+ {
+ maOrigDataFields.push_back( aDataInfo.mnField );
+ // DataPilot does not support double data fields -> add first appearence to index list only
+ if( !pField->HasDataFieldInfo() )
+ maFiltDataFields.push_back( aDataInfo.mnField );
+ pField->AddDataFieldInfo( aDataInfo );
+ }
+}
+
+void XclImpPivotTable::ReadSxex( XclImpStream& rStrm )
+{
+ rStrm >> maPTExtInfo;
+}
+
+void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm )
+{
+ rStrm >> maPTViewEx9Info;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpPivotTable::Convert()
+{
+ if( !mxPCache || !mxPCache->GetSourceRange().IsValid() )
+ return;
+
+ ScDPSaveData aSaveData;
+
+ // *** global settings ***
+
+ aSaveData.SetRowGrand( ::get_flag( maPTInfo.mnFlags, EXC_SXVIEW_ROWGRAND ) );
+ aSaveData.SetColumnGrand( ::get_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND ) );
+ aSaveData.SetFilterButton( FALSE );
+ aSaveData.SetDrillDown( ::get_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN ) );
+
+ // *** fields ***
+
+ ScfUInt16Vec::const_iterator aIt, aEnd;
+
+ // row fields
+ for( aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertRowColField( aSaveData );
+
+ // column fields
+ for( aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertRowColField( aSaveData );
+
+ // page fields
+ for( aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertPageField( aSaveData );
+
+ // We need to import hidden fields because hidden fields may contain
+ // special settings for subtotals (aggregation function, filters, custom
+ // name etc.) and members (hidden, custom name etc.).
+
+ // hidden fields
+ for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField )
+ if( const XclImpPTField* pField = GetField( nField ) )
+ if( (pField->GetAxes() & EXC_SXVD_AXIS_ROWCOLPAGE) == 0 )
+ pField->ConvertHiddenField( aSaveData );
+
+ // data fields
+ for( aIt = maFiltDataFields.begin(), aEnd = maFiltDataFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertDataField( aSaveData );
+
+ // *** insert into Calc document ***
+
+ // create source descriptor
+ ScSheetSourceDesc aDesc;
+ aDesc.aSourceRange = mxPCache->GetSourceRange();
+
+ // adjust output range to include the page fields
+ ScRange aOutRange( maOutScRange );
+ if( !maPageFields.empty() )
+ {
+ SCsROW nDecRows = ::std::min< SCsROW >( aOutRange.aStart.Row(), maPageFields.size() + 1 );
+ aOutRange.aStart.IncRow( -nDecRows );
+ }
+
+ // create the DataPilot
+ ScDPObject* pDPObj = new ScDPObject( GetDocPtr() );
+ pDPObj->SetName( maPTInfo.maTableName );
+ if (maPTInfo.maDataName.Len() > 0)
+ aSaveData.GetDataLayoutDimension()->SetLayoutName(maPTInfo.maDataName);
+
+ if (maPTViewEx9Info.maGrandTotalName.Len() > 0)
+ aSaveData.SetGrandTotalName(maPTViewEx9Info.maGrandTotalName);
+
+ pDPObj->SetSaveData( aSaveData );
+ pDPObj->SetSheetDesc( aDesc );
+ pDPObj->SetOutRange( aOutRange );
+ pDPObj->SetAlive( TRUE );
+ pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 );
+
+ GetDoc().GetDPCollection()->InsertNewTable(pDPObj);
+ mpDPObj = pDPObj;
+
+ ApplyMergeFlags(aOutRange, aSaveData);
+}
+
+void XclImpPivotTable::MaybeRefresh()
+{
+ if (mpDPObj && mxPCache->IsRefreshOnLoad())
+ {
+ // 'refresh table on load' flag is set. Refresh the table now. Some
+ // Excel files contain partial table output when this flag is set.
+ ScRange aOutRange = mpDPObj->GetOutRange();
+ mpDPObj->Output(aOutRange.aStart);
+ }
+}
+
+void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData)
+{
+ // Apply merge flags for varoius datapilot controls.
+
+ ScDPOutputGeometry aGeometry(rOutRange, false, ScDPOutputGeometry::XLS);
+ aGeometry.setColumnFieldCount(maPTInfo.mnColFields);
+ aGeometry.setPageFieldCount(maPTInfo.mnPageFields);
+ aGeometry.setDataFieldCount(maPTInfo.mnDataFields);
+
+ // Excel includes data layout field in the row field count. We need to
+ // subtract it.
+ bool bDataLayout = maPTInfo.mnDataFields > 1;
+ aGeometry.setRowFieldCount(maPTInfo.mnRowFields - static_cast<sal_uInt32>(bDataLayout));
+
+ ScDocument& rDoc = GetDoc();
+
+ vector<ScAddress> aPageBtns;
+ aGeometry.getPageFieldPositions(aPageBtns);
+ vector<ScAddress>::const_iterator itr = aPageBtns.begin(), itrEnd = aPageBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_uInt16 nMFlag = SC_MF_BUTTON;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), SC_MF_AUTO);
+ }
+
+ vector<ScAddress> aColBtns;
+ aGeometry.getColumnFieldPositions(aColBtns);
+ itr = aColBtns.begin();
+ itrEnd = aColBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ }
+
+ vector<ScAddress> aRowBtns;
+ aGeometry.getRowFieldPositions(aRowBtns);
+ if (aRowBtns.empty())
+ {
+ if (bDataLayout)
+ {
+ // No row fields, but the data layout button exists.
+ SCROW nRow = aGeometry.getRowFieldHeaderRow();
+ SCCOL nCol = rOutRange.aStart.Col();
+ SCTAB nTab = rOutRange.aStart.Tab();
+ rDoc.ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
+ }
+ }
+ else
+ {
+ itr = aRowBtns.begin();
+ itrEnd = aRowBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ }
+ if (bDataLayout)
+ {
+ --itr; // move back to the last row field position.
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON);
+ }
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+XclImpPivotTableManager::XclImpPivotTableManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+XclImpPivotTableManager::~XclImpPivotTableManager()
+{
+}
+
+// pivot cache records --------------------------------------------------------
+
+XclImpPivotCacheRef XclImpPivotTableManager::GetPivotCache( sal_uInt16 nCacheIdx )
+{
+ XclImpPivotCacheRef xPCache;
+ if( nCacheIdx < maPCaches.size() )
+ xPCache = maPCaches[ nCacheIdx ];
+ return xPCache;
+}
+
+void XclImpPivotTableManager::ReadSxidstm( XclImpStream& rStrm )
+{
+ XclImpPivotCacheRef xPCache( new XclImpPivotCache( GetRoot() ) );
+ maPCaches.push_back( xPCache );
+ xPCache->ReadSxidstm( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvs( XclImpStream& rStrm )
+{
+ if( !maPCaches.empty() )
+ maPCaches.back()->ReadSxvs( rStrm );
+}
+
+void XclImpPivotTableManager::ReadDconref( XclImpStream& rStrm )
+{
+ if( !maPCaches.empty() )
+ maPCaches.back()->ReadDconref( rStrm );
+}
+
+// pivot table records --------------------------------------------------------
+
+void XclImpPivotTableManager::ReadSxview( XclImpStream& rStrm )
+{
+ XclImpPivotTableRef xPTable( new XclImpPivotTable( GetRoot() ) );
+ maPTables.push_back( xPTable );
+ xPTable->ReadSxview( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvd( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxvd( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvdex( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxvdex( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxivd( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxivd( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxpi( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxpi( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxdi( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxdi( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvi( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxvi( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxex( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxex( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxViewEx9( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxViewEx9( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpPivotTableManager::ReadPivotCaches( XclImpStream& rStrm )
+{
+ for( XclImpPivotCacheVec::iterator aIt = maPCaches.begin(), aEnd = maPCaches.end(); aIt != aEnd; ++aIt )
+ (*aIt)->ReadPivotCacheStream( rStrm );
+}
+
+void XclImpPivotTableManager::ConvertPivotTables()
+{
+ for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
+ (*aIt)->Convert();
+}
+
+void XclImpPivotTableManager::MaybeRefreshPivotTables()
+{
+ for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
+ (*aIt)->MaybeRefresh();
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx
new file mode 100644
index 000000000000..5f8bcbd481e5
--- /dev/null
+++ b/sc/source/filter/excel/xiroot.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xiroot.hxx"
+#include "addincol.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xiformula.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+#include "xistyle.hxx"
+#include "xicontent.hxx"
+#include "xiescher.hxx"
+#include "xipivot.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+
+#include "root.hxx"
+#include "excimp8.hxx"
+
+// Global data ================================================================
+
+XclImpRootData::XclImpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
+ XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, false ),
+ mbHasCodePage( false ),
+ mbHasBasic( false )
+{
+}
+
+XclImpRootData::~XclImpRootData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpRoot::XclImpRoot( XclImpRootData& rImpRootData ) :
+ XclRoot( rImpRootData ),
+ mrImpData( rImpRootData )
+{
+ mrImpData.mxAddrConv.reset( new XclImpAddressConverter( GetRoot() ) );
+ mrImpData.mxFmlaComp.reset( new XclImpFormulaCompiler( GetRoot() ) );
+ mrImpData.mxPalette.reset( new XclImpPalette( GetRoot() ) );
+ mrImpData.mxFontBfr.reset( new XclImpFontBuffer( GetRoot() ) );
+ mrImpData.mxNumFmtBfr.reset( new XclImpNumFmtBuffer( GetRoot() ) );
+ mrImpData.mpXFBfr.reset( new XclImpXFBuffer( GetRoot() ) );
+ mrImpData.mxXFRangeBfr.reset( new XclImpXFRangeBuffer( GetRoot() ) );
+ mrImpData.mxTabInfo.reset( new XclImpTabInfo );
+ mrImpData.mxNameMgr.reset( new XclImpNameManager( GetRoot() ) );
+ mrImpData.mxObjMgr.reset( new XclImpObjectManager( GetRoot() ) );
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ mrImpData.mxLinkMgr.reset( new XclImpLinkManager( GetRoot() ) );
+ mrImpData.mxSst.reset( new XclImpSst( GetRoot() ) );
+ mrImpData.mxCondFmtMgr.reset( new XclImpCondFormatManager( GetRoot() ) );
+ // TODO still in old RootData (deleted by RootData)
+ GetOldRoot().pAutoFilterBuffer = new XclImpAutoFilterBuffer;
+ mrImpData.mxWebQueryBfr.reset( new XclImpWebQueryBuffer( GetRoot() ) );
+ mrImpData.mxPTableMgr.reset( new XclImpPivotTableManager( GetRoot() ) );
+ mrImpData.mxTabProtect.reset( new XclImpSheetProtectBuffer( GetRoot() ) );
+ mrImpData.mxDocProtect.reset( new XclImpDocProtectBuffer( GetRoot() ) );
+ }
+
+ mrImpData.mxPageSett.reset( new XclImpPageSettings( GetRoot() ) );
+ mrImpData.mxDocViewSett.reset( new XclImpDocViewSettings( GetRoot() ) );
+ mrImpData.mxTabViewSett.reset( new XclImpTabViewSettings( GetRoot() ) );
+}
+
+void XclImpRoot::SetCodePage( sal_uInt16 nCodePage )
+{
+ SetTextEncoding( XclTools::GetTextEncoding( nCodePage ) );
+ mrImpData.mbHasCodePage = true;
+}
+
+void XclImpRoot::SetAppFontEncoding( rtl_TextEncoding eAppFontEnc )
+{
+ if( !mrImpData.mbHasCodePage )
+ SetTextEncoding( eAppFontEnc );
+}
+
+void XclImpRoot::InitializeTable( SCTAB /*nScTab*/ )
+{
+ if( GetBiff() <= EXC_BIFF4 )
+ {
+ GetPalette().Initialize();
+ GetFontBuffer().Initialize();
+ GetNumFmtBuffer().Initialize();
+ GetXFBuffer().Initialize();
+ }
+ GetXFRangeBuffer().Initialize();
+ GetPageSettings().Initialize();
+ GetTabViewSettings().Initialize();
+}
+
+void XclImpRoot::FinalizeTable()
+{
+ GetXFRangeBuffer().Finalize();
+ GetOldRoot().pColRowBuff->Convert( GetCurrScTab() );
+ GetPageSettings().Finalize();
+ GetTabViewSettings().Finalize();
+}
+
+XclImpAddressConverter& XclImpRoot::GetAddressConverter() const
+{
+ return *mrImpData.mxAddrConv;
+}
+
+XclImpFormulaCompiler& XclImpRoot::GetFormulaCompiler() const
+{
+ return *mrImpData.mxFmlaComp;
+}
+
+ExcelToSc& XclImpRoot::GetOldFmlaConverter() const
+{
+ // TODO still in old RootData
+ return *GetOldRoot().pFmlaConverter;
+}
+
+XclImpSst& XclImpRoot::GetSst() const
+{
+ DBG_ASSERT( mrImpData.mxSst.is(), "XclImpRoot::GetSst - invalid call, wrong BIFF" );
+ return *mrImpData.mxSst;
+}
+
+XclImpPalette& XclImpRoot::GetPalette() const
+{
+ return *mrImpData.mxPalette;
+}
+
+XclImpFontBuffer& XclImpRoot::GetFontBuffer() const
+{
+ return *mrImpData.mxFontBfr;
+}
+
+XclImpNumFmtBuffer& XclImpRoot::GetNumFmtBuffer() const
+{
+ return *mrImpData.mxNumFmtBfr;
+}
+
+XclImpXFBuffer& XclImpRoot::GetXFBuffer() const
+{
+ return *mrImpData.mpXFBfr;
+}
+
+XclImpXFRangeBuffer& XclImpRoot::GetXFRangeBuffer() const
+{
+ return *mrImpData.mxXFRangeBfr;
+}
+
+_ScRangeListTabs& XclImpRoot::GetPrintAreaBuffer() const
+{
+ // TODO still in old RootData
+ return *GetOldRoot().pPrintRanges;
+}
+
+_ScRangeListTabs& XclImpRoot::GetTitleAreaBuffer() const
+{
+ // TODO still in old RootData
+ return *GetOldRoot().pPrintTitles;
+}
+
+XclImpTabInfo& XclImpRoot::GetTabInfo() const
+{
+ return *mrImpData.mxTabInfo;
+}
+
+XclImpNameManager& XclImpRoot::GetNameManager() const
+{
+ return *mrImpData.mxNameMgr;
+}
+
+XclImpLinkManager& XclImpRoot::GetLinkManager() const
+{
+ DBG_ASSERT( mrImpData.mxLinkMgr.is(), "XclImpRoot::GetLinkManager - invalid call, wrong BIFF" );
+ return *mrImpData.mxLinkMgr;
+}
+
+XclImpObjectManager& XclImpRoot::GetObjectManager() const
+{
+ return *mrImpData.mxObjMgr;
+}
+
+XclImpSheetDrawing& XclImpRoot::GetCurrSheetDrawing() const
+{
+ DBG_ASSERT( !IsInGlobals(), "XclImpRoot::GetCurrSheetDrawing - must not be called from workbook globals" );
+ return mrImpData.mxObjMgr->GetSheetDrawing( GetCurrScTab() );
+}
+
+XclImpCondFormatManager& XclImpRoot::GetCondFormatManager() const
+{
+ DBG_ASSERT( mrImpData.mxCondFmtMgr.is(), "XclImpRoot::GetCondFormatManager - invalid call, wrong BIFF" );
+ return *mrImpData.mxCondFmtMgr;
+}
+
+XclImpAutoFilterBuffer& XclImpRoot::GetFilterManager() const
+{
+ // TODO still in old RootData
+ DBG_ASSERT( GetOldRoot().pAutoFilterBuffer, "XclImpRoot::GetFilterManager - invalid call, wrong BIFF" );
+ return *GetOldRoot().pAutoFilterBuffer;
+}
+
+XclImpWebQueryBuffer& XclImpRoot::GetWebQueryBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxWebQueryBfr.is(), "XclImpRoot::GetWebQueryBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxWebQueryBfr;
+}
+
+XclImpPivotTableManager& XclImpRoot::GetPivotTableManager() const
+{
+ DBG_ASSERT( mrImpData.mxPTableMgr.is(), "XclImpRoot::GetPivotTableManager - invalid call, wrong BIFF" );
+ 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;
+}
+
+XclImpDocViewSettings& XclImpRoot::GetDocViewSettings() const
+{
+ return *mrImpData.mxDocViewSett;
+}
+
+XclImpTabViewSettings& XclImpRoot::GetTabViewSettings() const
+{
+ return *mrImpData.mxTabViewSett;
+}
+
+String XclImpRoot::GetScAddInName( const String& rXclName ) const
+{
+ String aScName;
+ if( ScGlobal::GetAddInCollection()->GetCalcName( rXclName, aScName ) )
+ return aScName;
+ return rXclName;
+}
+
+void XclImpRoot::ReadCodeName( XclImpStream& rStrm, bool bGlobals )
+{
+ if( mrImpData.mbHasBasic && (GetBiff() == EXC_BIFF8) )
+ {
+ String aName = rStrm.ReadUniString();
+ if( aName.Len() > 0 )
+ {
+ if( bGlobals )
+ {
+ GetExtDocOptions().GetDocSettings().maGlobCodeName = aName;
+ GetDoc().SetCodeName( aName );
+ }
+ else
+ {
+ GetExtDocOptions().SetCodeName( GetCurrScTab(), aName );
+ GetDoc().SetCodeName( GetCurrScTab(), aName );
+ }
+ }
+ }
+}
+
+// ============================================================================
diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
new file mode 100644
index 000000000000..98db9dcb4471
--- /dev/null
+++ b/sc/source/filter/excel/xistream.cxx
@@ -0,0 +1,1102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "xistream.hxx"
+#include "xlstring.hxx"
+#include "xiroot.hxx"
+
+#include <vector>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringToOString;
+
+// ============================================================================
+// Decryption
+// ============================================================================
+
+XclImpDecrypter::XclImpDecrypter() :
+ mnError( EXC_ENCR_ERROR_UNSUPP_CRYPT ),
+ mnOldPos( STREAM_SEEK_TO_END ),
+ mnRecSize( 0 )
+{
+}
+
+XclImpDecrypter::XclImpDecrypter( const XclImpDecrypter& rSrc ) :
+ ::comphelper::IDocPasswordVerifier(),
+ mnError( rSrc.mnError ),
+ mnOldPos( STREAM_SEEK_TO_END ),
+ mnRecSize( 0 )
+{
+}
+
+XclImpDecrypter::~XclImpDecrypter()
+{
+}
+
+XclImpDecrypterRef XclImpDecrypter::Clone() const
+{
+ XclImpDecrypterRef xNewDecr;
+ if( IsValid() )
+ xNewDecr.reset( OnClone() );
+ return xNewDecr;
+}
+
+::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const OUString& rPassword )
+{
+ bool bValid = OnVerify( rPassword );
+ mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT;
+ return bValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+void XclImpDecrypter::Update( SvStream& rStrm, sal_uInt16 nRecSize )
+{
+ if( IsValid() )
+ {
+ sal_Size nNewPos = rStrm.Tell();
+ if( (mnOldPos != nNewPos) || (mnRecSize != nRecSize) )
+ {
+ OnUpdate( mnOldPos, nNewPos, nRecSize );
+ mnOldPos = nNewPos;
+ mnRecSize = nRecSize;
+ }
+ }
+}
+
+sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes )
+{
+ sal_uInt16 nRet = 0;
+ if( pData && nBytes )
+ {
+ if( IsValid() )
+ {
+ Update( rStrm, mnRecSize );
+ nRet = OnRead( rStrm, reinterpret_cast< sal_uInt8* >( pData ), nBytes );
+ mnOldPos = rStrm.Tell();
+ }
+ else
+ nRet = static_cast< sal_uInt16 >( rStrm.Read( pData, nBytes ) );
+ }
+ return nRet;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) :
+ maPassword( 16 ),
+ mnKey( nKey ),
+ mnHash( nHash )
+{
+}
+
+XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ) :
+ XclImpDecrypter( rSrc ),
+ maPassword( rSrc.maPassword ),
+ mnKey( rSrc.mnKey ),
+ mnHash( rSrc.mnHash )
+{
+ if( IsValid() )
+ maCodec.InitKey( &maPassword.front() );
+}
+
+XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const
+{
+ return new XclImpBiff5Decrypter( *this );
+}
+
+bool XclImpBiff5Decrypter::OnVerify( const OUString& rPassword )
+{
+ /* Convert password to a byte string. TODO: this needs some finetuning
+ according to the spec... */
+ OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
+ sal_Int32 nLen = aBytePassword.getLength();
+ if( (0 < nLen) && (nLen < 16) )
+ {
+ // copy byte string to sal_uInt8 array
+ maPassword.clear();
+ maPassword.resize( 16, 0 );
+ memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) );
+
+ // init codec
+ maCodec.InitKey( &maPassword.front() );
+ return maCodec.VerifyKey( mnKey, mnHash );
+ }
+ return false;
+}
+
+void XclImpBiff5Decrypter::OnUpdate( sal_Size /*nOldStrmPos*/, sal_Size nNewStrmPos, sal_uInt16 nRecSize )
+{
+ maCodec.InitCipher();
+ maCodec.Skip( (nNewStrmPos + nRecSize) & 0x0F );
+}
+
+sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
+{
+ sal_uInt16 nRet = static_cast< sal_uInt16 >( rStrm.Read( pnData, nBytes ) );
+ maCodec.Decode( pnData, nRet );
+ return nRet;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
+ sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
+ maPassword( 16, 0 ),
+ maSalt( pnSalt, pnSalt + 16 ),
+ maVerifier( pnVerifier, pnVerifier + 16 ),
+ maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
+{
+}
+
+XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) :
+ XclImpDecrypter( rSrc ),
+ maPassword( rSrc.maPassword ),
+ maSalt( rSrc.maSalt ),
+ maVerifier( rSrc.maVerifier ),
+ maVerifierHash( rSrc.maVerifierHash )
+{
+ if( IsValid() )
+ maCodec.InitKey( &maPassword.front(), &maSalt.front() );
+}
+
+XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const
+{
+ return new XclImpBiff8Decrypter( *this );
+}
+
+bool XclImpBiff8Decrypter::OnVerify( const OUString& rPassword )
+{
+ sal_Int32 nLen = rPassword.getLength();
+ if( (0 < nLen) && (nLen < 16) )
+ {
+ // copy string to sal_uInt16 array
+ maPassword.clear();
+ maPassword.resize( 16, 0 );
+ const sal_Unicode* pcChar = rPassword.getStr();
+ const sal_Unicode* pcCharEnd = pcChar + nLen;
+ ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin();
+ for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
+ *aIt = static_cast< sal_uInt16 >( *pcChar );
+
+ // init codec
+ maCodec.InitKey( &maPassword.front(), &maSalt.front() );
+ return maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() );
+ }
+ return false;
+}
+
+void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 /*nRecSize*/ )
+{
+ if( nNewStrmPos != nOldStrmPos )
+ {
+ sal_uInt32 nOldBlock = GetBlock( nOldStrmPos );
+ sal_uInt16 nOldOffset = GetOffset( nOldStrmPos );
+
+ sal_uInt32 nNewBlock = GetBlock( nNewStrmPos );
+ sal_uInt16 nNewOffset = GetOffset( nNewStrmPos );
+
+ /* Rekey cipher, if block changed or if previous offset in same block. */
+ if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
+ {
+ maCodec.InitCipher( nNewBlock );
+ nOldOffset = 0; // reset nOldOffset for next if() statement
+ }
+
+ /* Seek to correct offset. */
+ if( nNewOffset > nOldOffset )
+ maCodec.Skip( nNewOffset - nOldOffset );
+ }
+}
+
+sal_uInt16 XclImpBiff8Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
+{
+ sal_uInt16 nRet = 0;
+
+ sal_uInt8* pnCurrData = pnData;
+ sal_uInt16 nBytesLeft = nBytes;
+ while( nBytesLeft )
+ {
+ sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - GetOffset( rStrm.Tell() );
+ sal_uInt16 nDecBytes = ::std::min< sal_uInt16 >( nBytesLeft, nBlockLeft );
+
+ // read the block from stream
+ nRet = nRet + static_cast< sal_uInt16 >( rStrm.Read( pnCurrData, nDecBytes ) );
+ // decode the block inplace
+ maCodec.Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
+ if( GetOffset( rStrm.Tell() ) == 0 )
+ maCodec.InitCipher( GetBlock( rStrm.Tell() ) );
+
+ pnCurrData += nDecBytes;
+ nBytesLeft = nBytesLeft - nDecBytes;
+ }
+
+ return nRet;
+}
+
+sal_uInt32 XclImpBiff8Decrypter::GetBlock( sal_Size nStrmPos ) const
+{
+ return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
+}
+
+sal_uInt16 XclImpBiff8Decrypter::GetOffset( sal_Size nStrmPos ) const
+{
+ return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
+}
+
+// ============================================================================
+// Stream
+// ============================================================================
+
+XclImpStreamPos::XclImpStreamPos() :
+ mnPos( STREAM_SEEK_TO_BEGIN ),
+ mnNextPos( STREAM_SEEK_TO_BEGIN ),
+ mnCurrSize( 0 ),
+ mnRawRecId( EXC_ID_UNKNOWN ),
+ mnRawRecSize( 0 ),
+ mnRawRecLeft( 0 ),
+ mbValid( false )
+{
+}
+
+void XclImpStreamPos::Set(
+ const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize,
+ sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
+ bool bValid )
+{
+ mnPos = rStrm.Tell();
+ mnNextPos = nNextPos;
+ mnCurrSize = nCurrSize;
+ mnRawRecId = nRawRecId;
+ mnRawRecSize = nRawRecSize;
+ mnRawRecLeft = nRawRecLeft;
+ mbValid = bValid;
+}
+
+void XclImpStreamPos::Get(
+ SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize,
+ sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
+ bool& rbValid ) const
+{
+ rStrm.Seek( mnPos );
+ rnNextPos = mnNextPos;
+ rnCurrSize = mnCurrSize;
+ rnRawRecId = mnRawRecId;
+ rnRawRecSize = mnRawRecSize;
+ rnRawRecLeft = mnRawRecLeft;
+ rbValid = mbValid;
+}
+
+// ============================================================================
+
+XclBiff XclImpStream::DetectBiffVersion( SvStream& rStrm )
+{
+ XclBiff eBiff = EXC_BIFF_UNKNOWN;
+
+ rStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ sal_uInt16 nBofId, nBofSize;
+ rStrm >> nBofId >> nBofSize;
+
+ if( (4 <= nBofSize) && (nBofSize <= 16) ) switch( nBofId )
+ {
+ case EXC_ID2_BOF:
+ eBiff = EXC_BIFF2;
+ break;
+ case EXC_ID3_BOF:
+ eBiff = EXC_BIFF3;
+ break;
+ case EXC_ID4_BOF:
+ eBiff = EXC_BIFF4;
+ break;
+ case EXC_ID5_BOF:
+ {
+ sal_uInt16 nVersion;
+ rStrm >> nVersion;
+ // #i23425# #i44031# #i62752# there are some *really* broken documents out there...
+ switch( nVersion & 0xFF00 )
+ {
+ case 0: eBiff = EXC_BIFF5; break; // #i44031# #i62752#
+ case EXC_BOF_BIFF2: eBiff = EXC_BIFF2; break;
+ case EXC_BOF_BIFF3: eBiff = EXC_BIFF3; break;
+ case EXC_BOF_BIFF4: eBiff = EXC_BIFF4; break;
+ case EXC_BOF_BIFF5: eBiff = EXC_BIFF5; break;
+ case EXC_BOF_BIFF8: eBiff = EXC_BIFF8; break;
+ default: DBG_ERROR1( "XclImpStream::DetectBiffVersion - unknown BIFF version: 0x%04hX", nVersion );
+ }
+ }
+ break;
+ }
+ return eBiff;
+}
+
+XclImpStream::XclImpStream( SvStream& rInStrm, const XclImpRoot& rRoot, bool bContLookup ) :
+ mrStrm( rInStrm ),
+ mrRoot( rRoot ),
+ mnGlobRecId( EXC_ID_UNKNOWN ),
+ mbGlobValidRec( false ),
+ mbHasGlobPos( false ),
+ mnNextRecPos( STREAM_SEEK_TO_BEGIN ),
+ mnCurrRecSize( 0 ),
+ mnComplRecSize( 0 ),
+ mbHasComplRec( false ),
+ mnRecId( EXC_ID_UNKNOWN ),
+ mnAltContId( EXC_ID_UNKNOWN ),
+ mnRawRecId( EXC_ID_UNKNOWN ),
+ mnRawRecSize( 0 ),
+ mnRawRecLeft( 0 ),
+ mcNulSubst( '?' ),
+ mbCont( bContLookup ),
+ mbUseDecr( false ),
+ mbValidRec( false ),
+ mbValid( false )
+{
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ mnStreamSize = mrStrm.Tell();
+ mrStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ DBG_ASSERT( mnStreamSize < STREAM_SEEK_TO_END, "XclImpStream::XclImpStream - stream error" );
+}
+
+XclImpStream::~XclImpStream()
+{
+}
+
+bool XclImpStream::StartNextRecord()
+{
+ maPosStack.clear();
+
+ /* #i4266# Counter to ignore zero records (id==len==0) (i.e. the application
+ "Crystal Report" writes zero records between other records) */
+ sal_Size nZeroRecCount = 5;
+ bool bIsZeroRec = false;
+
+ do
+ {
+ mbValidRec = ReadNextRawRecHeader();
+ bIsZeroRec = (mnRawRecId == 0) && (mnRawRecSize == 0);
+ if( bIsZeroRec ) --nZeroRecCount;
+ mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
+ }
+ while( mbValidRec && ((mbCont && IsContinueId( mnRawRecId )) || (bIsZeroRec && nZeroRecCount)) );
+
+ mbValidRec = mbValidRec && !bIsZeroRec;
+ mbValid = mbValidRec;
+ SetupRecord();
+
+ return mbValidRec;
+}
+
+bool XclImpStream::StartNextRecord( sal_Size nNextRecPos )
+{
+ mnNextRecPos = nNextRecPos;
+ return StartNextRecord();
+}
+
+void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
+{
+ if( mbValidRec )
+ {
+ maPosStack.clear();
+ RestorePosition( maFirstRec );
+ mnCurrRecSize = mnComplRecSize = mnRawRecSize;
+ mbHasComplRec = !bContLookup;
+ mbCont = bContLookup;
+ mnAltContId = nAltContId;
+ EnableDecryption();
+ }
+}
+
+void XclImpStream::SetDecrypter( XclImpDecrypterRef xDecrypter )
+{
+ mxDecrypter = xDecrypter;
+ EnableDecryption();
+ SetupDecrypter();
+}
+
+void XclImpStream::CopyDecrypterFrom( const XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xNewDecr;
+ if( rStrm.mxDecrypter.is() )
+ xNewDecr = rStrm.mxDecrypter->Clone();
+ SetDecrypter( xNewDecr );
+}
+
+bool XclImpStream::HasValidDecrypter() const
+{
+ return mxDecrypter.is() && mxDecrypter->IsValid();
+}
+
+void XclImpStream::EnableDecryption( bool bEnable )
+{
+ mbUseDecr = bEnable && HasValidDecrypter();
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpStream::PushPosition()
+{
+ maPosStack.push_back( XclImpStreamPos() );
+ StorePosition( maPosStack.back() );
+}
+
+void XclImpStream::PopPosition()
+{
+ DBG_ASSERT( !maPosStack.empty(), "XclImpStream::PopPosition - stack empty" );
+ if( !maPosStack.empty() )
+ {
+ RestorePosition( maPosStack.back() );
+ maPosStack.pop_back();
+ }
+}
+
+//UNUSED2008-05 void XclImpStream::RejectPosition()
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ASSERT( !maPosStack.empty(), "XclImpStream::RejectPosition - stack empty" );
+//UNUSED2008-05 if( !maPosStack.empty() )
+//UNUSED2008-05 maPosStack.pop_back();
+//UNUSED2008-05 }
+
+void XclImpStream::StoreGlobalPosition()
+{
+ StorePosition( maGlobPos );
+ mnGlobRecId = mnRecId;
+ mbGlobValidRec = mbValidRec;
+ mbHasGlobPos = true;
+}
+
+void XclImpStream::SeekGlobalPosition()
+{
+ DBG_ASSERT( mbHasGlobPos, "XclImpStream::SeekGlobalPosition - no position stored" );
+ if( mbHasGlobPos )
+ {
+ RestorePosition( maGlobPos );
+ mnRecId = mnGlobRecId;
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = !mbCont;
+ mbValidRec = mbGlobValidRec;
+ }
+}
+
+sal_Size XclImpStream::GetRecPos() const
+{
+ return mbValid ? (mnCurrRecSize - mnRawRecLeft) : EXC_REC_SEEK_TO_END;
+}
+
+sal_Size XclImpStream::GetRecSize()
+{
+ if( !mbHasComplRec )
+ {
+ PushPosition();
+ while( JumpToNextContinue() ) ; // JumpToNextContinue() adds up mnCurrRecSize
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = true;
+ PopPosition();
+ }
+ return mnComplRecSize;
+}
+
+sal_Size XclImpStream::GetRecLeft()
+{
+ return mbValid ? (GetRecSize() - GetRecPos()) : 0;
+}
+
+sal_uInt16 XclImpStream::GetNextRecId()
+{
+ sal_uInt16 nRecId = EXC_ID_UNKNOWN;
+ if( mbValidRec )
+ {
+ PushPosition();
+ while( JumpToNextContinue() ) ; // skip following CONTINUE records
+ if( mnNextRecPos < mnStreamSize )
+ {
+ mrStrm.Seek( mnNextRecPos );
+ mrStrm >> nRecId;
+ }
+ PopPosition();
+ }
+ return nRecId;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpStream& XclImpStream::operator>>( sal_Int8& rnValue )
+{
+ if( EnsureRawReadSize( 1 ) )
+ {
+ if( mbUseDecr )
+ mxDecrypter->Read( mrStrm, &rnValue, 1 );
+ else
+ mrStrm >> rnValue;
+ --mnRawRecLeft;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_uInt8& rnValue )
+{
+ if( EnsureRawReadSize( 1 ) )
+ {
+ if( mbUseDecr )
+ mxDecrypter->Read( mrStrm, &rnValue, 1 );
+ else
+ mrStrm >> rnValue;
+ --mnRawRecLeft;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_Int16& rnValue )
+{
+ if( EnsureRawReadSize( 2 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT16 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 2 );
+ rnValue = static_cast< sal_Int16 >( SVBT16ToShort( pnBuffer ) );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 2;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_uInt16& rnValue )
+{
+ if( EnsureRawReadSize( 2 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT16 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 2 );
+ rnValue = SVBT16ToShort( pnBuffer );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 2;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_Int32& rnValue )
+{
+ if( EnsureRawReadSize( 4 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT32 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 4 );
+ rnValue = static_cast< sal_Int32 >( SVBT32ToUInt32( pnBuffer ) );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 4;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_uInt32& rnValue )
+{
+ if( EnsureRawReadSize( 4 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT32 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 4 );
+ rnValue = SVBT32ToUInt32( pnBuffer );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 4;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( float& rfValue )
+{
+ if( EnsureRawReadSize( 4 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT32 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 4 );
+ sal_uInt32 nValue = SVBT32ToUInt32( pnBuffer );
+ memcpy( &rfValue, &nValue, 4 );
+ }
+ else
+ mrStrm >> rfValue;
+ mnRawRecLeft -= 4;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( double& rfValue )
+{
+ if( EnsureRawReadSize( 8 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT64 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 8 );
+ rfValue = SVBT64ToDouble( pnBuffer );
+ }
+ else
+ mrStrm >> rfValue;
+ mnRawRecLeft -= 8;
+ }
+ return *this;
+}
+
+sal_Int8 XclImpStream::ReadInt8()
+{
+ sal_Int8 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_uInt8 XclImpStream::ReaduInt8()
+{
+ sal_uInt8 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_Int16 XclImpStream::ReadInt16()
+{
+ sal_Int16 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_uInt16 XclImpStream::ReaduInt16()
+{
+ sal_uInt16 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_Int32 XclImpStream::ReadInt32()
+{
+ sal_Int32 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_uInt32 XclImpStream::ReaduInt32()
+{
+ sal_uInt32 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+float XclImpStream::ReadFloat()
+{
+ float fValue(0.0);
+ operator>>( fValue );
+ return fValue;
+}
+
+double XclImpStream::ReadDouble()
+{
+ double fValue(0.0);
+ operator>>( fValue );
+ return fValue;
+}
+
+sal_Size XclImpStream::Read( void* pData, sal_Size nBytes )
+{
+ sal_Size nRet = 0;
+ if( mbValid && pData && (nBytes > 0) )
+ {
+ sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( pData );
+ sal_Size nBytesLeft = nBytes;
+
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
+ sal_uInt16 nReadRet = ReadRawData( pnBuffer, nReadSize );
+ nRet += nReadRet;
+ mbValid = (nReadSize == nReadRet);
+ DBG_ASSERT( mbValid, "XclImpStream::Read - stream read error" );
+ pnBuffer += nReadRet;
+ nBytesLeft -= nReadRet;
+ if( mbValid && (nBytesLeft > 0) )
+ JumpToNextContinue();
+ DBG_ASSERT( mbValid, "XclImpStream::Read - record overread" );
+ }
+ }
+ return nRet;
+}
+
+sal_Size XclImpStream::CopyToStream( SvStream& rOutStrm, sal_Size nBytes )
+{
+ sal_Size nRet = 0;
+ if( mbValid && (nBytes > 0) )
+ {
+ const sal_Size nMaxBuffer = 4096;
+ sal_uInt8* pnBuffer = new sal_uInt8[ ::std::min( nBytes, nMaxBuffer ) ];
+ sal_Size nBytesLeft = nBytes;
+
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_Size nReadSize = ::std::min( nBytesLeft, nMaxBuffer );
+ nRet += Read( pnBuffer, nReadSize );
+ rOutStrm.Write( pnBuffer, nReadSize );
+ nBytesLeft -= nReadSize;
+ }
+
+ delete[] pnBuffer;
+ }
+ return nRet;
+}
+
+sal_Size XclImpStream::CopyRecordToStream( SvStream& rOutStrm )
+{
+ sal_Size nRet = 0;
+ if( mbValidRec )
+ {
+ PushPosition();
+ RestorePosition( maFirstRec );
+ nRet = CopyToStream( rOutStrm, GetRecSize() );
+ PopPosition();
+ }
+ return nRet;
+}
+
+void XclImpStream::Seek( sal_Size nPos )
+{
+ if( mbValidRec )
+ {
+ sal_Size nCurrPos = GetRecPos();
+ if( !mbValid || (nPos < nCurrPos) ) // from invalid state or backward
+ {
+ RestorePosition( maFirstRec );
+ Ignore( nPos );
+ }
+ else if( nPos > nCurrPos ) // forward
+ {
+ Ignore( nPos - nCurrPos );
+ }
+ }
+}
+
+void XclImpStream::Ignore( sal_Size nBytes )
+{
+ // implementation similar to Read(), but without really reading anything
+ sal_Size nBytesLeft = nBytes;
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
+ mrStrm.SeekRel( nReadSize );
+ mnRawRecLeft = mnRawRecLeft - nReadSize;
+ nBytesLeft -= nReadSize;
+ if( nBytesLeft > 0 )
+ JumpToNextContinue();
+ DBG_ASSERT( mbValid, "XclImpStream::Ignore - record overread" );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sal_Size XclImpStream::ReadUniStringExtHeader(
+ bool& rb16Bit, bool& rbRich, bool& rbFareast,
+ sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags )
+{
+ DBG_ASSERT( !::get_flag( nFlags, EXC_STRF_UNKNOWN ), "XclImpStream::ReadUniStringExt - unknown flags" );
+ rb16Bit = ::get_flag( nFlags, EXC_STRF_16BIT );
+ rbRich = ::get_flag( nFlags, EXC_STRF_RICH );
+ rbFareast = ::get_flag( nFlags, EXC_STRF_FAREAST );
+ rnFormatRuns = rbRich ? ReaduInt16() : 0;
+ rnExtInf = rbFareast ? ReaduInt32() : 0;
+ return rnExtInf + 4 * rnFormatRuns;
+}
+
+sal_Size XclImpStream::ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags )
+{
+ bool bRich, bFareast;
+ sal_uInt16 nCrun;
+ sal_uInt32 nExtInf;
+ return ReadUniStringExtHeader( rb16Bit, bRich, bFareast, nCrun, nExtInf, nFlags );
+}
+
+// ----------------------------------------------------------------------------
+
+String XclImpStream::ReadRawUniString( sal_uInt16 nChars, bool b16Bit )
+{
+ String aRet;
+ sal_uInt16 nCharsLeft = nChars;
+ sal_uInt16 nReadSize;
+
+ sal_Unicode* pcBuffer = new sal_Unicode[ nCharsLeft + 1 ];
+
+ while( IsValid() && (nCharsLeft > 0) )
+ {
+ if( b16Bit )
+ {
+ nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
+ DBG_ASSERT( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
+ "XclImpStream::ReadRawUniString - missing a byte" );
+ }
+ else
+ nReadSize = GetMaxRawReadSize( nCharsLeft );
+
+ sal_Unicode* pcUniChar = pcBuffer;
+ sal_Unicode* pcEndChar = pcBuffer + nReadSize;
+
+ if( b16Bit )
+ {
+ sal_uInt16 nReadChar;
+ for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
+ {
+ operator>>( nReadChar );
+ (*pcUniChar) = (nReadChar == EXC_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
+ }
+ }
+ else
+ {
+ sal_uInt8 nReadChar;
+ for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
+ {
+ operator>>( nReadChar );
+ (*pcUniChar) = (nReadChar == EXC_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
+ }
+ }
+
+ *pcEndChar = '\0';
+ aRet.Append( pcBuffer );
+
+ nCharsLeft = nCharsLeft - nReadSize;
+ if( nCharsLeft > 0 )
+ JumpToNextStringContinue( b16Bit );
+ }
+
+ delete[] pcBuffer;
+ return aRet;
+}
+
+String XclImpStream::ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
+{
+ bool b16Bit;
+ sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
+ String aRet( ReadRawUniString( nChars, b16Bit ) );
+ Ignore( nExtSize );
+ return aRet;
+}
+
+String XclImpStream::ReadUniString( sal_uInt16 nChars )
+{
+ return ReadUniString( nChars, ReaduInt8() );
+}
+
+String XclImpStream::ReadUniString()
+{
+ return ReadUniString( ReaduInt16() );
+}
+
+void XclImpStream::IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit )
+{
+ sal_uInt16 nCharsLeft = nChars;
+ sal_uInt16 nReadSize;
+
+ while( IsValid() && (nCharsLeft > 0) )
+ {
+ if( b16Bit )
+ {
+ nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
+ DBG_ASSERT( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
+ "XclImpStream::IgnoreRawUniString - missing a byte" );
+ Ignore( nReadSize * 2 );
+ }
+ else
+ {
+ nReadSize = GetMaxRawReadSize( nCharsLeft );
+ Ignore( nReadSize );
+ }
+
+ nCharsLeft = nCharsLeft - nReadSize;
+ if( nCharsLeft > 0 )
+ JumpToNextStringContinue( b16Bit );
+ }
+}
+
+void XclImpStream::IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
+{
+ bool b16Bit;
+ sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
+ IgnoreRawUniString( nChars, b16Bit );
+ Ignore( nExtSize );
+}
+
+void XclImpStream::IgnoreUniString( sal_uInt16 nChars )
+{
+ IgnoreUniString( nChars, ReaduInt8() );
+}
+
+void XclImpStream::IgnoreUniString()
+{
+ IgnoreUniString( ReaduInt16() );
+}
+
+// ----------------------------------------------------------------------------
+
+String XclImpStream::ReadRawByteString( sal_uInt16 nChars )
+{
+ sal_Char* pcBuffer = new sal_Char[ nChars + 1 ];
+ sal_uInt16 nCharsRead = ReadRawData( pcBuffer, nChars );
+ pcBuffer[ nCharsRead ] = '\0';
+ String aRet( pcBuffer, mrRoot.GetTextEncoding() );
+ delete[] pcBuffer;
+ return aRet;
+}
+
+String XclImpStream::ReadByteString( bool b16BitLen )
+{
+ return ReadRawByteString( ReadByteStrLen( b16BitLen ) );
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpStream::StorePosition( XclImpStreamPos& rPos )
+{
+ rPos.Set( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
+}
+
+void XclImpStream::RestorePosition( const XclImpStreamPos& rPos )
+{
+ rPos.Get( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
+ SetupDecrypter();
+}
+
+bool XclImpStream::ReadNextRawRecHeader()
+{
+ mrStrm.Seek( mnNextRecPos );
+ bool bRet = mnNextRecPos + 4 <= mnStreamSize;
+ if( bRet )
+ mrStrm >> mnRawRecId >> mnRawRecSize;
+ return bRet;
+}
+
+void XclImpStream::SetupDecrypter()
+{
+ if( mxDecrypter.is() )
+ mxDecrypter->Update( mrStrm, mnRawRecSize );
+}
+
+void XclImpStream::SetupRawRecord()
+{
+ // pre: mnRawRecSize contains current raw record size
+ // pre: mrStrm points to start of raw record data
+ mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
+ mnRawRecLeft = mnRawRecSize;
+ mnCurrRecSize += mnRawRecSize;
+ SetupDecrypter(); // decrypter works on raw record level
+}
+
+void XclImpStream::SetupRecord()
+{
+ mnRecId = mnRawRecId;
+ mnAltContId = EXC_ID_UNKNOWN;
+ mnCurrRecSize = 0;
+ mnComplRecSize = mnRawRecSize;
+ mbHasComplRec = !mbCont;
+ SetupRawRecord();
+ SetNulSubstChar();
+ EnableDecryption();
+ StorePosition( maFirstRec );
+}
+
+bool XclImpStream::IsContinueId( sal_uInt16 nRecId ) const
+{
+ return (nRecId == EXC_ID_CONT) || (nRecId == mnAltContId);
+}
+
+bool XclImpStream::JumpToNextContinue()
+{
+ mbValid = mbValid && mbCont && ReadNextRawRecHeader() && IsContinueId( mnRawRecId );
+ if( mbValid ) // do not setup a following non-CONTINUE record
+ SetupRawRecord();
+ return mbValid;
+}
+
+bool XclImpStream::JumpToNextStringContinue( bool& rb16Bit )
+{
+ DBG_ASSERT( mnRawRecLeft == 0, "XclImpStream::JumpToNextStringContinue - unexpected garbage" );
+
+ if( mbCont && (GetRecLeft() > 0) )
+ {
+ JumpToNextContinue();
+ }
+ else if( mnRecId == EXC_ID_CONT )
+ {
+ // CONTINUE handling is off, but we have started reading in a CONTINUE record
+ // -> start next CONTINUE for TXO import
+ mbValidRec = ReadNextRawRecHeader() && ((mnRawRecId != 0) || (mnRawRecSize > 0));
+ mbValid = mbValidRec && (mnRawRecId == EXC_ID_CONT);
+ // we really start a new record here - no chance to return to string origin
+ if( mbValid )
+ SetupRecord();
+ }
+ else
+ mbValid = false;
+
+ if( mbValid )
+ rb16Bit = ::get_flag( ReaduInt8(), EXC_STRF_16BIT );
+ return mbValid;
+}
+
+bool XclImpStream::EnsureRawReadSize( sal_uInt16 nBytes )
+{
+ if( mbValid && nBytes )
+ {
+ while( mbValid && !mnRawRecLeft ) JumpToNextContinue();
+ mbValid = mbValid && (nBytes <= mnRawRecLeft);
+ DBG_ASSERT( mbValid, "XclImpStream::EnsureRawReadSize - record overread" );
+ }
+ return mbValid;
+}
+
+sal_uInt16 XclImpStream::GetMaxRawReadSize( sal_Size nBytes ) const
+{
+ return static_cast< sal_uInt16 >( ::std::min< sal_Size >( nBytes, mnRawRecLeft ) );
+}
+
+sal_uInt16 XclImpStream::ReadRawData( void* pData, sal_uInt16 nBytes )
+{
+ DBG_ASSERT( (nBytes <= mnRawRecLeft), "XclImpStream::ReadRawData - record overread" );
+ sal_uInt16 nRet = 0;
+ if( mbUseDecr )
+ nRet = mxDecrypter->Read( mrStrm, pData, nBytes );
+ else
+ nRet = static_cast< sal_uInt16 >( mrStrm.Read( pData, nBytes ) );
+ mnRawRecLeft = mnRawRecLeft - nRet;
+ return nRet;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xistring.cxx b/sc/source/filter/excel/xistring.cxx
new file mode 100644
index 000000000000..cb2645bec538
--- /dev/null
+++ b/sc/source/filter/excel/xistring.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sc.hxx"
+#include "xistring.hxx"
+#include "xlstyle.hxx"
+#include "xistream.hxx"
+#include "xiroot.hxx"
+
+// Byte/Unicode strings =======================================================
+
+/** All allowed flags for import. */
+const XclStrFlags nAllowedFlags = EXC_STR_8BITLENGTH | EXC_STR_SMARTFLAGS | EXC_STR_SEPARATEFORMATS;
+
+// ----------------------------------------------------------------------------
+
+XclImpString::XclImpString()
+{
+}
+
+XclImpString::XclImpString( const String& rString ) :
+ maString( rString )
+{
+}
+
+XclImpString::~XclImpString()
+{
+}
+
+void XclImpString::Read( XclImpStream& rStrm, XclStrFlags nFlags )
+{
+ if( !::get_flag( nFlags, EXC_STR_SEPARATEFORMATS ) )
+ maFormats.clear();
+
+ DBG_ASSERT( (nFlags & ~nAllowedFlags) == 0, "XclImpString::Read - unknown flag" );
+ bool b16BitLen = !::get_flag( nFlags, EXC_STR_8BITLENGTH );
+
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ // no integrated formatting in BIFF2-BIFF7
+ maString = rStrm.ReadByteString( b16BitLen );
+ break;
+
+ case EXC_BIFF8:
+ {
+ // --- string header ---
+ sal_uInt16 nChars = b16BitLen ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
+ sal_uInt8 nFlagField = 0;
+ if( nChars || !::get_flag( nFlags, EXC_STR_SMARTFLAGS ) )
+ rStrm >> nFlagField;
+
+ bool b16Bit, bRich, bFarEast;
+ sal_uInt16 nRunCount;
+ sal_uInt32 nExtInf;
+ rStrm.ReadUniStringExtHeader( b16Bit, bRich, bFarEast, nRunCount, nExtInf, nFlagField );
+ // #122185# ignore the flags, they may be wrong
+
+ // --- character array ---
+ maString = rStrm.ReadRawUniString( nChars, b16Bit );
+
+ // --- formatting ---
+ if( nRunCount > 0 )
+ ReadFormats( rStrm, nRunCount );
+
+ // --- extended (FarEast) information ---
+ rStrm.Ignore( nExtInf );
+ }
+ break;
+
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+void XclImpString::AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx )
+{
+ // #i33341# real life -- same character index may occur several times
+ DBG_ASSERT( rFormats.empty() || (rFormats.back().mnChar <= nChar), "XclImpString::AppendFormat - wrong char order" );
+ if( rFormats.empty() || (rFormats.back().mnChar < nChar) )
+ rFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
+ else
+ rFormats.back().mnFontIdx = nFontIdx;
+}
+
+void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats )
+{
+ bool bBiff8 = rStrm.GetRoot().GetBiff() == EXC_BIFF8;
+ sal_uInt16 nRunCount = bBiff8 ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
+ ReadFormats( rStrm, rFormats, nRunCount );
+}
+
+void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount )
+{
+ rFormats.clear();
+ rFormats.reserve( nRunCount );
+ /* #i33341# real life -- same character index may occur several times
+ -> use AppendFormat() to validate formats */
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
+ {
+ sal_uInt16 nChar, nFontIdx;
+ rStrm >> nChar >> nFontIdx;
+ AppendFormat( rFormats, nChar, nFontIdx );
+ }
+ }
+ else
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
+ {
+ sal_uInt8 nChar, nFontIdx;
+ rStrm >> nChar >> nFontIdx;
+ AppendFormat( rFormats, nChar, nFontIdx );
+ }
+ }
+}
+
+void XclImpString::ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize )
+{
+ // number of formatting runs, each takes 8 bytes
+ sal_uInt16 nRunCount = nFormatSize / 8;
+ rFormats.clear();
+ rFormats.reserve( nRunCount );
+ for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
+ {
+ sal_uInt16 nChar, nFontIdx;
+ rStrm >> nChar >> nFontIdx;
+ rStrm.Ignore( 4 );
+ AppendFormat( rFormats, nChar, nFontIdx );
+ }
+}
+
+// String iterator ============================================================
+
+XclImpStringIterator::XclImpStringIterator( const XclImpString& rString ) :
+ mrText( rString.GetText() ),
+ mrFormats( rString.GetFormats() ),
+ mnPortion( 0 ),
+ mnTextBeg( 0 ),
+ mnTextEnd( 0 ),
+ mnFormatsBeg( 0 ),
+ mnFormatsEnd( 0 )
+{
+ // first portion is formatted, adjust vector index to next portion
+ if( !mrFormats.empty() && (mrFormats.front().mnChar == 0) )
+ ++mnFormatsEnd;
+ // find end position of the first portion
+ mnTextEnd = static_cast< xub_StrLen >( (mnFormatsEnd < mrFormats.size()) ?
+ mrFormats[ mnFormatsEnd ].mnChar : mrText.Len() );
+}
+
+String XclImpStringIterator::GetPortionText() const
+{
+ return String( mrText, mnTextBeg, mnTextEnd - mnTextBeg );
+}
+
+sal_uInt16 XclImpStringIterator::GetPortionFont() const
+{
+ return (mnFormatsBeg < mnFormatsEnd) ? mrFormats[ mnFormatsBeg ].mnFontIdx : EXC_FONT_NOTFOUND;
+}
+
+XclImpStringIterator& XclImpStringIterator::operator++()
+{
+ if( Is() )
+ {
+ ++mnPortion;
+ do
+ {
+ // indexes into vector of formatting runs
+ if( mnFormatsBeg < mnFormatsEnd )
+ ++mnFormatsBeg;
+ if( mnFormatsEnd < mrFormats.size() )
+ ++mnFormatsEnd;
+ // character positions of next portion
+ mnTextBeg = mnTextEnd;
+ mnTextEnd = static_cast< xub_StrLen >( (mnFormatsEnd < mrFormats.size()) ?
+ mrFormats[ mnFormatsEnd ].mnChar : mrText.Len() );
+ }
+ while( Is() && (mnTextBeg == mnTextEnd) );
+ }
+ return *this;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
new file mode 100644
index 000000000000..1559ef5530f5
--- /dev/null
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -0,0 +1,1823 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xistyle.hxx"
+#include <sfx2/printer.hxx>
+#include <sfx2/objsh.hxx>
+#include <svtools/ctrltool.hxx>
+#include <editeng/editobj.hxx>
+#include "scitems.hxx"
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flstitem.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xicontent.hxx"
+
+#include "root.hxx"
+#include "colrowst.hxx"
+
+// PALETTE record - color information =========================================
+
+XclImpPalette::XclImpPalette( const XclImpRoot& rRoot ) :
+ XclDefaultPalette( rRoot )
+{
+}
+
+void XclImpPalette::Initialize()
+{
+ maColorTable.clear();
+}
+
+ColorData XclImpPalette::GetColorData( sal_uInt16 nXclIndex ) const
+{
+ if( nXclIndex >= EXC_COLOR_USEROFFSET )
+ {
+ sal_uInt32 nIx = nXclIndex - EXC_COLOR_USEROFFSET;
+ if( nIx < maColorTable.size() )
+ return maColorTable[ nIx ];
+ }
+ return GetDefColorData( nXclIndex );
+}
+
+void XclImpPalette::ReadPalette( XclImpStream& rStrm )
+{
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ DBG_ASSERT( rStrm.GetRecLeft() == static_cast< sal_Size >( 4 * nCount ),
+ "XclImpPalette::ReadPalette - size mismatch" );
+
+ maColorTable.resize( nCount );
+ Color aColor;
+ for( sal_uInt16 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ rStrm >> aColor;
+ maColorTable[ nIndex ] = aColor.GetColor();
+ }
+}
+
+// FONT record - font information =============================================
+
+XclImpFont::XclImpFont( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mbHasCharSet( false ),
+ mbHasWstrn( true ),
+ mbHasAsian( false ),
+ mbHasCmplx( false )
+{
+ SetAllUsedFlags( false );
+}
+
+XclImpFont::XclImpFont( const XclImpRoot& rRoot, const XclFontData& rFontData ) :
+ XclImpRoot( rRoot )
+{
+ SetFontData( rFontData, false );
+}
+
+void XclImpFont::SetAllUsedFlags( bool bUsed )
+{
+ mbFontNameUsed = mbHeightUsed = mbColorUsed = mbWeightUsed = mbEscapemUsed =
+ mbUnderlUsed = mbItalicUsed = mbStrikeUsed = mbOutlineUsed = mbShadowUsed = bUsed;
+}
+
+void XclImpFont::SetFontData( const XclFontData& rFontData, bool bHasCharSet )
+{
+ maData = rFontData;
+ mbHasCharSet = bHasCharSet;
+ if( maData.maStyle.Len() )
+ {
+ if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ if( const SvxFontListItem* pInfoItem = static_cast< const SvxFontListItem* >(
+ pDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ) )
+ {
+ if( const FontList* pFontList = pInfoItem->GetFontList() )
+ {
+ FontInfo aFontInfo( pFontList->Get( maData.maName, maData.maStyle ) );
+ maData.SetScWeight( aFontInfo.GetWeight() );
+ maData.SetScPosture( aFontInfo.GetItalic() );
+ }
+ }
+ }
+ maData.maStyle.Erase();
+ }
+ GuessScriptType();
+ SetAllUsedFlags( true );
+}
+
+rtl_TextEncoding XclImpFont::GetFontEncoding() const
+{
+ // #i63105# use text encoding from FONT record
+ // #i67768# BIFF2-BIFF4 FONT records do not contain character set
+ rtl_TextEncoding eFontEnc = mbHasCharSet ? maData.GetFontEncoding() : GetTextEncoding();
+ return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? GetTextEncoding() : eFontEnc;
+}
+
+void XclImpFont::ReadFont( XclImpStream& rStrm )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ ReadFontData2( rStrm );
+ ReadFontName2( rStrm );
+ break;
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ ReadFontData2( rStrm );
+ ReadFontColor( rStrm );
+ ReadFontName2( rStrm );
+ break;
+ case EXC_BIFF5:
+ ReadFontData5( rStrm );
+ ReadFontName2( rStrm );
+ break;
+ case EXC_BIFF8:
+ ReadFontData5( rStrm );
+ ReadFontName8( rStrm );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ return;
+ }
+ GuessScriptType();
+ SetAllUsedFlags( true );
+}
+
+void XclImpFont::ReadEfont( XclImpStream& rStrm )
+{
+ ReadFontColor( rStrm );
+}
+
+void XclImpFont::ReadCFFontBlock( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+ if( GetBiff() != EXC_BIFF8 )
+ return;
+
+ sal_uInt32 nHeight, nStyle, nColor, nFontFlags1, nFontFlags2, nFontFlags3;
+ sal_uInt16 nWeight, nEscapem;
+ sal_uInt8 nUnderl;
+
+ rStrm.Ignore( 64 );
+ rStrm >> nHeight >> nStyle >> nWeight >> nEscapem >> nUnderl;
+ rStrm.Ignore( 3 );
+ rStrm >> nColor;
+ rStrm.Ignore( 4 );
+ rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3;
+ rStrm.Ignore( 18 );
+
+ if( (mbHeightUsed = (nHeight <= 0x7FFF)) == true )
+ maData.mnHeight = static_cast< sal_uInt16 >( nHeight );
+ if( (mbWeightUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE ) && (nWeight < 0x7FFF)) == true )
+ maData.mnWeight = static_cast< sal_uInt16 >( nWeight );
+ if( (mbItalicUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE )) == true )
+ maData.mbItalic = ::get_flag( nStyle, EXC_CF_FONT_STYLE );
+ if( (mbUnderlUsed = !::get_flag( nFontFlags3, EXC_CF_FONT_UNDERL ) && (nUnderl <= 0x7F)) == true )
+ maData.mnUnderline = nUnderl;
+ if( (mbColorUsed = (nColor <= 0x7FFF)) == true )
+ maData.maColor = GetPalette().GetColor( static_cast< sal_uInt16 >( nColor ) );
+ if( (mbStrikeUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT )) == true )
+ maData.mbStrikeout = ::get_flag( nStyle, EXC_CF_FONT_STRIKEOUT );
+}
+
+void XclImpFont::FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType, bool bSkipPoolDefs ) const
+{
+ // true = edit engine Which-IDs (EE_CHAR_*); false = Calc Which-IDs (ATTR_*)
+ bool bEE = eType != EXC_FONTITEM_CELL;
+
+// item = the item to put into the item set
+// sc_which = the Calc Which-ID of the item
+// ee_which = the edit engine Which-ID of the item
+#define PUTITEM( item, sc_which, ee_which ) \
+ ScfTools::PutItem( rItemSet, item, (bEE ? (ee_which) : (sc_which)), bSkipPoolDefs )
+
+// Font item
+ // #i36997# do not set default Tahoma font from notes
+ bool bDefNoteFont = (eType == EXC_FONTITEM_NOTE) && (maData.maName.EqualsIgnoreCaseAscii( "Tahoma" ));
+ if( mbFontNameUsed && !bDefNoteFont )
+ {
+ rtl_TextEncoding eFontEnc = maData.GetFontEncoding();
+ rtl_TextEncoding eTempTextEnc = (bEE && (eFontEnc == GetTextEncoding())) ?
+ ScfTools::GetSystemTextEncoding() : eFontEnc;
+
+ SvxFontItem aFontItem( maData.GetScFamily( GetTextEncoding() ), maData.maName, EMPTY_STRING,
+ PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
+ // #91658# set only for valid script types
+ if( mbHasWstrn )
+ PUTITEM( aFontItem, ATTR_FONT, EE_CHAR_FONTINFO );
+ if( mbHasAsian )
+ PUTITEM( aFontItem, ATTR_CJK_FONT, EE_CHAR_FONTINFO_CJK );
+ if( mbHasCmplx )
+ PUTITEM( aFontItem, ATTR_CTL_FONT, EE_CHAR_FONTINFO_CTL );
+ }
+
+// Font height (for all script types)
+ if( mbHeightUsed )
+ {
+ sal_Int32 nHeight = maData.mnHeight;
+ if( bEE && (eType != EXC_FONTITEM_HF) ) // do not convert header/footer height
+ nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH; // #98527# 1 in == 72 pt
+
+ SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
+ PUTITEM( aHeightItem, ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT );
+ PUTITEM( aHeightItem, ATTR_CJK_FONT_HEIGHT, EE_CHAR_FONTHEIGHT_CJK );
+ PUTITEM( aHeightItem, ATTR_CTL_FONT_HEIGHT, EE_CHAR_FONTHEIGHT_CTL );
+ }
+
+// Font color - pass AUTO_COL to item
+ if( mbColorUsed )
+ PUTITEM( SvxColorItem( maData.maColor, ATTR_FONT_COLOR ), ATTR_FONT_COLOR, EE_CHAR_COLOR );
+
+// Font weight (for all script types)
+ if( mbWeightUsed )
+ {
+ SvxWeightItem aWeightItem( maData.GetScWeight(), ATTR_FONT_WEIGHT );
+ PUTITEM( aWeightItem, ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT );
+ PUTITEM( aWeightItem, ATTR_CJK_FONT_WEIGHT, EE_CHAR_WEIGHT_CJK );
+ PUTITEM( aWeightItem, ATTR_CTL_FONT_WEIGHT, EE_CHAR_WEIGHT_CTL );
+ }
+
+// Font underline
+ if( mbUnderlUsed )
+ {
+ SvxUnderlineItem aUnderlItem( maData.GetScUnderline(), ATTR_FONT_UNDERLINE );
+ PUTITEM( aUnderlItem, ATTR_FONT_UNDERLINE, EE_CHAR_UNDERLINE );
+ }
+
+// Font posture (for all script types)
+ if( mbItalicUsed )
+ {
+ SvxPostureItem aPostItem( maData.GetScPosture(), ATTR_FONT_POSTURE );
+ PUTITEM( aPostItem, ATTR_FONT_POSTURE, EE_CHAR_ITALIC );
+ PUTITEM( aPostItem, ATTR_CJK_FONT_POSTURE, EE_CHAR_ITALIC_CJK );
+ PUTITEM( aPostItem, ATTR_CTL_FONT_POSTURE, EE_CHAR_ITALIC_CTL );
+ }
+
+// Boolean attributes crossed out, contoured, shadowed
+ if( mbStrikeUsed )
+ PUTITEM( SvxCrossedOutItem( maData.GetScStrikeout(), ATTR_FONT_CROSSEDOUT ), ATTR_FONT_CROSSEDOUT, EE_CHAR_STRIKEOUT );
+ if( mbOutlineUsed )
+ PUTITEM( SvxContourItem( maData.mbOutline, ATTR_FONT_CONTOUR ), ATTR_FONT_CONTOUR, EE_CHAR_OUTLINE );
+ if( mbShadowUsed )
+ PUTITEM( SvxShadowedItem( maData.mbShadow, ATTR_FONT_SHADOWED ), ATTR_FONT_SHADOWED, EE_CHAR_SHADOW );
+
+// Super-/subscript: only on edit engine objects
+ if( mbEscapemUsed && bEE )
+ rItemSet.Put( SvxEscapementItem( maData.GetScEscapement(), EE_CHAR_ESCAPEMENT ) );
+
+#undef PUTITEM
+}
+
+void XclImpFont::WriteFontProperties( ScfPropertySet& rPropSet,
+ XclFontPropSetType eType, const Color* pFontColor ) const
+{
+ GetFontPropSetHelper().WriteFontProperties(
+ rPropSet, eType, maData, mbHasWstrn, mbHasAsian, mbHasCmplx, pFontColor );
+}
+
+void XclImpFont::ReadFontData2( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> maData.mnHeight >> nFlags;
+
+ maData.mnWeight = ::get_flagvalue( nFlags, EXC_FONTATTR_BOLD, EXC_FONTWGHT_BOLD, EXC_FONTWGHT_NORMAL );
+ maData.mnUnderline = ::get_flagvalue( nFlags, EXC_FONTATTR_UNDERLINE, EXC_FONTUNDERL_SINGLE, EXC_FONTUNDERL_NONE );
+ maData.mbItalic = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
+ maData.mbStrikeout = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
+ maData.mbOutline = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
+ maData.mbShadow = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
+ mbHasCharSet = false;
+}
+
+void XclImpFont::ReadFontData5( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+
+ rStrm >> maData.mnHeight >> nFlags;
+ ReadFontColor( rStrm );
+ rStrm >> maData.mnWeight >> maData.mnEscapem >> maData.mnUnderline >> maData.mnFamily >> maData.mnCharSet;
+ rStrm.Ignore( 1 );
+
+ maData.mbItalic = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
+ maData.mbStrikeout = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
+ maData.mbOutline = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
+ maData.mbShadow = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
+ mbHasCharSet = true;
+}
+
+void XclImpFont::ReadFontColor( XclImpStream& rStrm )
+{
+ maData.maColor = GetPalette().GetColor( rStrm.ReaduInt16() );
+}
+
+void XclImpFont::ReadFontName2( XclImpStream& rStrm )
+{
+ maData.maName = rStrm.ReadByteString( false );
+}
+
+void XclImpFont::ReadFontName8( XclImpStream& rStrm )
+{
+ maData.maName = rStrm.ReadUniString( rStrm.ReaduInt8() );
+}
+
+void XclImpFont::GuessScriptType()
+{
+ mbHasWstrn = true;
+ mbHasAsian = mbHasCmplx = false;
+
+ // #91658# #113783# find the script types for which the font contains characters
+ if( OutputDevice* pPrinter = GetPrinter() )
+ {
+ Font aFont( maData.maName, Size( 0, 10 ) );
+ FontCharMap aCharMap;
+
+ pPrinter->SetFont( aFont );
+ if( pPrinter->GetFontCharMap( aCharMap ) )
+ {
+ // #91658# CJK fonts
+ mbHasAsian =
+ aCharMap.HasChar( 0x3041 ) || // 3040-309F: Hiragana
+ aCharMap.HasChar( 0x30A1 ) || // 30A0-30FF: Katakana
+ aCharMap.HasChar( 0x3111 ) || // 3100-312F: Bopomofo
+ aCharMap.HasChar( 0x3131 ) || // 3130-318F: Hangul Compatibility Jamo
+ aCharMap.HasChar( 0x3301 ) || // 3300-33FF: CJK Compatibility
+ aCharMap.HasChar( 0x3401 ) || // 3400-4DBF: CJK Unified Ideographs Extension A
+ aCharMap.HasChar( 0x4E01 ) || // 4E00-9FAF: CJK Unified Ideographs
+ aCharMap.HasChar( 0x7E01 ) || // 4E00-9FAF: CJK unified ideographs
+ aCharMap.HasChar( 0xA001 ) || // A001-A48F: Yi Syllables
+ aCharMap.HasChar( 0xAC01 ) || // AC00-D7AF: Hangul Syllables
+ aCharMap.HasChar( 0xCC01 ) || // AC00-D7AF: Hangul Syllables
+ aCharMap.HasChar( 0xF901 ) || // F900-FAFF: CJK Compatibility Ideographs
+ aCharMap.HasChar( 0xFF71 ); // FF00-FFEF: Halfwidth/Fullwidth Forms
+ // #113783# CTL fonts
+ mbHasCmplx =
+ aCharMap.HasChar( 0x05D1 ) || // 0590-05FF: Hebrew
+ aCharMap.HasChar( 0x0631 ) || // 0600-06FF: Arabic
+ aCharMap.HasChar( 0x0721 ) || // 0700-074F: Syriac
+ aCharMap.HasChar( 0x0911 ) || // 0900-0DFF: Indic scripts
+ aCharMap.HasChar( 0x0E01 ) || // 0E00-0E7F: Thai
+ aCharMap.HasChar( 0xFB21 ) || // FB1D-FB4F: Hebrew Presentation Forms
+ aCharMap.HasChar( 0xFB51 ) || // FB50-FDFF: Arabic Presentation Forms-A
+ aCharMap.HasChar( 0xFE71 ); // FE70-FEFF: Arabic Presentation Forms-B
+ // Western fonts
+ mbHasWstrn = (!mbHasAsian && !mbHasCmplx) || aCharMap.HasChar( 'A' );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpFontBuffer::XclImpFontBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maFont4( rRoot ),
+ maCtrlFont( rRoot )
+{
+ Initialize();
+
+ // default font for form controls without own font information
+ XclFontData aCtrlFontData;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ aCtrlFontData.maName.AssignAscii( "Helv" );
+ aCtrlFontData.mnHeight = 160;
+ aCtrlFontData.mnWeight = EXC_FONTWGHT_BOLD;
+ break;
+ case EXC_BIFF8:
+ aCtrlFontData.maName.AssignAscii( "Tahoma" );
+ aCtrlFontData.mnHeight = 160;
+ aCtrlFontData.mnWeight = EXC_FONTWGHT_NORMAL;
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ maCtrlFont.SetFontData( aCtrlFontData, false );
+}
+
+void XclImpFontBuffer::Initialize()
+{
+ maFontList.Clear();
+
+ // application font for column width calculation, later filled with first font from font list
+ XclFontData aAppFontData;
+ aAppFontData.maName.AssignAscii( "Arial" );
+ aAppFontData.mnHeight = 200;
+ aAppFontData.mnWeight = EXC_FONTWGHT_NORMAL;
+ UpdateAppFont( aAppFontData, false );
+}
+
+const XclImpFont* XclImpFontBuffer::GetFont( sal_uInt16 nFontIndex ) const
+{
+ /* Font with index 4 is not stored in an Excel file, but used e.g. by
+ BIFF5 form pushbutton objects. It is the bold default font. */
+ return (nFontIndex == 4) ? &maFont4 :
+ maFontList.GetObject( (nFontIndex < 4) ? nFontIndex : (nFontIndex - 1) );
+}
+
+void XclImpFontBuffer::ReadFont( XclImpStream& rStrm )
+{
+ XclImpFont* pFont = new XclImpFont( GetRoot() );
+ pFont->ReadFont( rStrm );
+ maFontList.Append( pFont );
+
+ if( maFontList.Count() == 1 )
+ {
+ UpdateAppFont( pFont->GetFontData(), pFont->HasCharSet() );
+ // #i71033# set text encoding from application font, if CODEPAGE is missing
+ SetAppFontEncoding( pFont->GetFontEncoding() );
+ }
+}
+
+void XclImpFontBuffer::ReadEfont( XclImpStream& rStrm )
+{
+ if( XclImpFont* pFont = maFontList.Last() )
+ pFont->ReadEfont( rStrm );
+}
+
+void XclImpFontBuffer::FillToItemSet(
+ SfxItemSet& rItemSet, XclFontItemType eType,
+ sal_uInt16 nFontIdx, bool bSkipPoolDefs ) const
+{
+ if( const XclImpFont* pFont = GetFont( nFontIdx ) )
+ pFont->FillToItemSet( rItemSet, eType, bSkipPoolDefs );
+}
+
+void XclImpFontBuffer::WriteFontProperties( ScfPropertySet& rPropSet,
+ XclFontPropSetType eType, sal_uInt16 nFontIdx, const Color* pFontColor ) const
+{
+ if( const XclImpFont* pFont = GetFont( nFontIdx ) )
+ pFont->WriteFontProperties( rPropSet, eType, pFontColor );
+}
+
+void XclImpFontBuffer::WriteDefaultCtrlFontProperties( ScfPropertySet& rPropSet ) const
+{
+ maCtrlFont.WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL );
+}
+
+void XclImpFontBuffer::UpdateAppFont( const XclFontData& rFontData, bool bHasCharSet )
+{
+ maAppFont = rFontData;
+ // #i3006# Calculate the width of '0' from first font and current printer.
+ SetCharWidth( maAppFont );
+
+ // font 4 is bold font 0
+ XclFontData aFont4Data( maAppFont );
+ aFont4Data.mnWeight = EXC_FONTWGHT_BOLD;
+ maFont4.SetFontData( aFont4Data, bHasCharSet );
+}
+
+// FORMAT record - number formats =============================================
+
+XclImpNumFmtBuffer::XclImpNumFmtBuffer( const XclImpRoot& rRoot ) :
+ XclNumFmtBuffer( rRoot ),
+ XclImpRoot( rRoot ),
+ mnNextXclIdx( 0 )
+{
+}
+
+void XclImpNumFmtBuffer::Initialize()
+{
+ maIndexMap.clear();
+ mnNextXclIdx = 0;
+ InitializeImport(); // base class
+}
+
+void XclImpNumFmtBuffer::ReadFormat( XclImpStream& rStrm )
+{
+ String aFormat;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ aFormat = rStrm.ReadByteString( false );
+ break;
+
+ case EXC_BIFF4:
+ rStrm.Ignore( 2 ); // in BIFF4 the index field exists, but is undefined
+ aFormat = rStrm.ReadByteString( false );
+ break;
+
+ case EXC_BIFF5:
+ rStrm >> mnNextXclIdx;
+ aFormat = rStrm.ReadByteString( false );
+ break;
+
+ case EXC_BIFF8:
+ rStrm >> mnNextXclIdx;
+ aFormat = rStrm.ReadUniString();
+ break;
+
+ default:
+ DBG_ERROR_BIFF();
+ return;
+ }
+
+ if( mnNextXclIdx < 0xFFFF )
+ {
+ InsertFormat( mnNextXclIdx, aFormat );
+ ++mnNextXclIdx;
+ }
+}
+
+void XclImpNumFmtBuffer::CreateScFormats()
+{
+ DBG_ASSERT( maIndexMap.empty(), "XclImpNumFmtBuffer::CreateScFormats - already created" );
+
+ SvNumberFormatter& rFormatter = GetFormatter();
+ for( XclNumFmtMap::const_iterator aIt = GetFormatMap().begin(), aEnd = GetFormatMap().end(); aIt != aEnd; ++aIt )
+ {
+ const XclNumFmt& rNumFmt = aIt->second;
+
+ // insert/convert the Excel number format
+ xub_StrLen nCheckPos;
+ short nType = NUMBERFORMAT_DEFINED;
+ sal_uInt32 nKey;
+ if( rNumFmt.maFormat.Len() )
+ {
+ String aFormat( rNumFmt.maFormat );
+ rFormatter.PutandConvertEntry( aFormat, nCheckPos,
+ nType, nKey, LANGUAGE_ENGLISH_US, rNumFmt.meLanguage );
+ }
+ else
+ nKey = rFormatter.GetFormatIndex( rNumFmt.meOffset, rNumFmt.meLanguage );
+
+ // insert the resulting format key into the Excel->Calc index map
+ maIndexMap[ aIt->first ] = nKey;
+ }
+}
+
+ULONG XclImpNumFmtBuffer::GetScFormat( sal_uInt16 nXclNumFmt ) const
+{
+ XclImpIndexMap::const_iterator aIt = maIndexMap.find( nXclNumFmt );
+ return (aIt != maIndexMap.end()) ? aIt->second : NUMBERFORMAT_ENTRY_NOT_FOUND;
+}
+
+void XclImpNumFmtBuffer::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nXclNumFmt, bool bSkipPoolDefs ) const
+{
+ ULONG nScNumFmt = GetScFormat( nXclNumFmt );
+ if( nScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ nScNumFmt = GetStdScNumFmt();
+ FillScFmtToItemSet( rItemSet, nScNumFmt, bSkipPoolDefs );
+}
+
+void XclImpNumFmtBuffer::FillScFmtToItemSet( SfxItemSet& rItemSet, ULONG nScNumFmt, bool bSkipPoolDefs ) const
+{
+ DBG_ASSERT( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND, "XclImpNumFmtBuffer::FillScFmtToItemSet - invalid number format" );
+ ScfTools::PutItem( rItemSet, SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ), bSkipPoolDefs );
+ if( rItemSet.GetItemState( ATTR_VALUE_FORMAT, FALSE ) == SFX_ITEM_SET )
+ ScGlobal::AddLanguage( rItemSet, GetFormatter() );
+}
+
+// XF, STYLE record - Cell formatting =========================================
+
+void XclImpCellProt::FillFromXF2( sal_uInt8 nNumFmt )
+{
+ mbLocked = ::get_flag( nNumFmt, EXC_XF2_LOCKED );
+ mbHidden = ::get_flag( nNumFmt, EXC_XF2_HIDDEN );
+}
+
+void XclImpCellProt::FillFromXF3( sal_uInt16 nProt )
+{
+ mbLocked = ::get_flag( nProt, EXC_XF_LOCKED );
+ mbHidden = ::get_flag( nProt, EXC_XF_HIDDEN );
+}
+
+void XclImpCellProt::FillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+ ScfTools::PutItem( rItemSet, ScProtectionAttr( mbLocked, mbHidden ), bSkipPoolDefs );
+}
+
+
+// ----------------------------------------------------------------------------
+
+void XclImpCellAlign::FillFromXF2( sal_uInt8 nFlags )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nFlags, 0, 3 );
+}
+
+void XclImpCellAlign::FillFromXF3( sal_uInt16 nAlign )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
+ mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK ); // new in BIFF3
+}
+
+void XclImpCellAlign::FillFromXF4( sal_uInt16 nAlign )
+{
+ FillFromXF3( nAlign );
+ mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 2 ); // new in BIFF4
+ mnOrient = ::extract_value< sal_uInt8 >( nAlign, 6, 2 ); // new in BIFF4
+}
+
+void XclImpCellAlign::FillFromXF5( sal_uInt16 nAlign )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
+ mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
+ mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
+ mnOrient = ::extract_value< sal_uInt8 >( nAlign, 8, 2 );
+}
+
+void XclImpCellAlign::FillFromXF8( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
+ mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
+ mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
+ mnRotation = ::extract_value< sal_uInt8 >( nAlign, 8, 8 ); // new in BIFF8
+ mnIndent = ::extract_value< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8
+ mbShrink = ::get_flag( nMiscAttrib, EXC_XF8_SHRINK ); // new in BIFF8
+ mnTextDir = ::extract_value< sal_uInt8 >( nMiscAttrib, 6, 2 ); // new in BIFF8
+}
+
+void XclImpCellAlign::FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFont, bool bSkipPoolDefs ) const
+{
+ // horizontal alignment
+ ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
+
+ // text wrap (#i74508# always if vertical alignment is justified or distributed)
+ bool bLineBreak = mbLineBreak || (mnVerAlign == EXC_XF_VER_JUSTIFY) || (mnVerAlign == EXC_XF_VER_DISTRIB);
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, bLineBreak ), bSkipPoolDefs );
+
+ // vertical alignment
+ ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
+
+ // indent
+ sal_uInt16 nScIndent = mnIndent * 200; // 1 Excel unit == 10 pt == 200 twips
+ ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, nScIndent ), bSkipPoolDefs );
+
+ // shrink to fit
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, mbShrink ), bSkipPoolDefs );
+
+ // text orientation/rotation (BIFF2-BIFF7 sets mnOrient)
+ sal_uInt8 nXclRot = (mnOrient == EXC_ORIENT_NONE) ? mnRotation : XclTools::GetXclRotFromOrient( mnOrient );
+ bool bStacked = (nXclRot == EXC_ROT_STACKED);
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, bStacked ), bSkipPoolDefs );
+ // set an angle in the range from -90 to 90 degrees
+ sal_Int32 nAngle = XclTools::GetScRotation( nXclRot, 0 );
+ ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, nAngle ), bSkipPoolDefs );
+ // #105933# set "Use asian vertical layout", if cell is stacked and font contains CKJ characters
+ bool bAsianVert = bStacked && pFont && pFont->HasAsianChars();
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_VERTICAL_ASIAN, bAsianVert ), bSkipPoolDefs );
+
+ // CTL text direction
+ ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCellBorder::XclImpCellBorder()
+{
+ SetUsedFlags( false, false );
+}
+
+void XclImpCellBorder::SetUsedFlags( bool bOuterUsed, bool bDiagUsed )
+{
+ mbLeftUsed = mbRightUsed = mbTopUsed = mbBottomUsed = bOuterUsed;
+ mbDiagUsed = bDiagUsed;
+}
+
+void XclImpCellBorder::FillFromXF2( sal_uInt8 nFlags )
+{
+ mnLeftLine = ::get_flagvalue( nFlags, EXC_XF2_LEFTLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnRightLine = ::get_flagvalue( nFlags, EXC_XF2_RIGHTLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnTopLine = ::get_flagvalue( nFlags, EXC_XF2_TOPLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnBottomLine = ::get_flagvalue( nFlags, EXC_XF2_BOTTOMLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnLeftColor = mnRightColor = mnTopColor = mnBottomColor = EXC_COLOR_BIFF2_BLACK;
+ SetUsedFlags( true, false );
+}
+
+void XclImpCellBorder::FillFromXF3( sal_uInt32 nBorder )
+{
+ mnTopLine = ::extract_value< sal_uInt8 >( nBorder, 0, 3 );
+ mnLeftLine = ::extract_value< sal_uInt8 >( nBorder, 8, 3 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nBorder, 16, 3 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nBorder, 24, 3 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nBorder, 3, 5 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nBorder, 11, 5 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nBorder, 19, 5 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nBorder, 27, 5 );
+ SetUsedFlags( true, false );
+}
+
+void XclImpCellBorder::FillFromXF5( sal_uInt32 nBorder, sal_uInt32 nArea )
+{
+ mnTopLine = ::extract_value< sal_uInt8 >( nBorder, 0, 3 );
+ mnLeftLine = ::extract_value< sal_uInt8 >( nBorder, 3, 3 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nArea, 22, 3 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nBorder, 6, 3 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nBorder, 9, 7 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nBorder, 16, 7 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nArea, 25, 7 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nBorder, 23, 7 );
+ SetUsedFlags( true, false );
+}
+
+void XclImpCellBorder::FillFromXF8( sal_uInt32 nBorder1, sal_uInt32 nBorder2 )
+{
+ mnLeftLine = ::extract_value< sal_uInt8 >( nBorder1, 0, 4 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nBorder1, 4, 4 );
+ mnTopLine = ::extract_value< sal_uInt8 >( nBorder1, 8, 4 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nBorder1, 12, 4 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nBorder1, 16, 7 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nBorder1, 23, 7 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nBorder2, 0, 7 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nBorder2, 7, 7 );
+ mbDiagTLtoBR = ::get_flag( nBorder1, EXC_XF_DIAGONAL_TL_TO_BR );
+ mbDiagBLtoTR = ::get_flag( nBorder1, EXC_XF_DIAGONAL_BL_TO_TR );
+ if( mbDiagTLtoBR || mbDiagBLtoTR )
+ {
+ mnDiagLine = ::extract_value< sal_uInt8 >( nBorder2, 21, 4 );
+ mnDiagColor = ::extract_value< sal_uInt16 >( nBorder2, 14, 7 );
+ }
+ SetUsedFlags( true, true );
+}
+
+void XclImpCellBorder::FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags )
+{
+ mnLeftLine = ::extract_value< sal_uInt8 >( nLineStyle, 0, 4 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nLineStyle, 4, 4 );
+ mnTopLine = ::extract_value< sal_uInt8 >( nLineStyle, 8, 4 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nLineStyle, 12, 4 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nLineColor, 0, 7 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nLineColor, 7, 7 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nLineColor, 16, 7 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nLineColor, 23, 7 );
+ mbLeftUsed = !::get_flag( nFlags, EXC_CF_BORDER_LEFT );
+ mbRightUsed = !::get_flag( nFlags, EXC_CF_BORDER_RIGHT );
+ mbTopUsed = !::get_flag( nFlags, EXC_CF_BORDER_TOP );
+ mbBottomUsed = !::get_flag( nFlags, EXC_CF_BORDER_BOTTOM );
+ mbDiagUsed = false;
+}
+
+bool XclImpCellBorder::HasAnyOuterBorder() const
+{
+ return
+ (mbLeftUsed && (mnLeftLine != EXC_LINE_NONE)) ||
+ (mbRightUsed && (mnRightLine != EXC_LINE_NONE)) ||
+ (mbTopUsed && (mnTopLine != EXC_LINE_NONE)) ||
+ (mbBottomUsed && (mnBottomLine != EXC_LINE_NONE));
+}
+
+namespace {
+
+/** Converts the passed line style to a SvxBorderLine, or returns false, if style is "no line". */
+bool lclConvertBorderLine( SvxBorderLine& rLine, const XclImpPalette& rPalette, sal_uInt8 nXclLine, sal_uInt16 nXclColor )
+{
+ static const sal_uInt16 ppnLineParam[][ 3 ] =
+ {
+ // outer width, inner width, distance
+ { 0, 0, 0 }, // 0 = none
+ { DEF_LINE_WIDTH_1, 0, 0 }, // 1 = thin
+ { DEF_LINE_WIDTH_2, 0, 0 }, // 2 = medium
+ { DEF_LINE_WIDTH_1, 0, 0 }, // 3 = dashed
+ { DEF_LINE_WIDTH_0, 0, 0 }, // 4 = dotted
+ { DEF_LINE_WIDTH_3, 0, 0 }, // 5 = thick
+ { DEF_LINE_WIDTH_1, DEF_LINE_WIDTH_1, DEF_LINE_WIDTH_1 }, // 6 = double
+ { DEF_LINE_WIDTH_0, 0, 0 }, // 7 = hair
+ { DEF_LINE_WIDTH_2, 0, 0 }, // 8 = med dash
+ { DEF_LINE_WIDTH_1, 0, 0 }, // 9 = thin dashdot
+ { DEF_LINE_WIDTH_2, 0, 0 }, // A = med dashdot
+ { DEF_LINE_WIDTH_1, 0, 0 }, // B = thin dashdotdot
+ { DEF_LINE_WIDTH_2, 0, 0 }, // C = med dashdotdot
+ { DEF_LINE_WIDTH_2, 0, 0 } // D = med slant dashdot
+ };
+
+ if( nXclLine == EXC_LINE_NONE )
+ return false;
+ if( nXclLine >= STATIC_TABLE_SIZE( ppnLineParam ) )
+ nXclLine = EXC_LINE_THIN;
+
+ rLine.SetColor( rPalette.GetColor( nXclColor ) );
+ rLine.SetOutWidth( ppnLineParam[ nXclLine ][ 0 ] );
+ rLine.SetInWidth( ppnLineParam[ nXclLine ][ 1 ] );
+ rLine.SetDistance( ppnLineParam[ nXclLine ][ 2 ] );
+ return true;
+}
+
+} // namespace
+
+void XclImpCellBorder::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
+{
+ if( mbLeftUsed || mbRightUsed || mbTopUsed || mbBottomUsed )
+ {
+ SvxBoxItem aBoxItem( ATTR_BORDER );
+ SvxBorderLine aLine;
+ if( mbLeftUsed && lclConvertBorderLine( aLine, rPalette, mnLeftLine, mnLeftColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
+ if( mbRightUsed && lclConvertBorderLine( aLine, rPalette, mnRightLine, mnRightColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
+ if( mbTopUsed && lclConvertBorderLine( aLine, rPalette, mnTopLine, mnTopColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
+ if( mbBottomUsed && lclConvertBorderLine( aLine, rPalette, mnBottomLine, mnBottomColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
+ ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
+ }
+ if( mbDiagUsed )
+ {
+ SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
+ SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
+ SvxBorderLine aLine;
+ if( lclConvertBorderLine( aLine, rPalette, mnDiagLine, mnDiagColor ) )
+ {
+ if( mbDiagTLtoBR )
+ aTLBRItem.SetLine( &aLine );
+ if( mbDiagBLtoTR )
+ aBLTRItem.SetLine( &aLine );
+ }
+ ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
+ ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCellArea::XclImpCellArea()
+{
+ SetUsedFlags( false );
+}
+
+void XclImpCellArea::SetUsedFlags( bool bUsed )
+{
+ mbForeUsed = mbBackUsed = mbPattUsed = bUsed;
+}
+
+void XclImpCellArea::FillFromXF2( sal_uInt8 nFlags )
+{
+ mnPattern = ::get_flagvalue( nFlags, EXC_XF2_BACKGROUND, EXC_PATT_12_5_PERC, EXC_PATT_NONE );
+ mnForeColor = EXC_COLOR_BIFF2_BLACK;
+ mnBackColor = EXC_COLOR_BIFF2_WHITE;
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromXF3( sal_uInt16 nArea )
+{
+ mnPattern = ::extract_value< sal_uInt8 >( nArea, 0, 6 );
+ mnForeColor = ::extract_value< sal_uInt16 >( nArea, 6, 5 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nArea, 11, 5 );
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromXF5( sal_uInt32 nArea )
+{
+ mnPattern = ::extract_value< sal_uInt8 >( nArea, 16, 6 );
+ mnForeColor = ::extract_value< sal_uInt16 >( nArea, 0, 7 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nArea, 7, 7 );
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromXF8( sal_uInt32 nBorder2, sal_uInt16 nArea )
+{
+ mnPattern = ::extract_value< sal_uInt8 >( nBorder2, 26, 6 );
+ mnForeColor = ::extract_value< sal_uInt16 >( nArea, 0, 7 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nArea, 7, 7 );
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromCF8( sal_uInt16 nPattern, sal_uInt16 nColor, sal_uInt32 nFlags )
+{
+ mnForeColor = ::extract_value< sal_uInt16 >( nColor, 0, 7 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nColor, 7, 7 );
+ mnPattern = ::extract_value< sal_uInt8 >( nPattern, 10, 6 );
+ mbForeUsed = !::get_flag( nFlags, EXC_CF_AREA_FGCOLOR );
+ mbBackUsed = !::get_flag( nFlags, EXC_CF_AREA_BGCOLOR );
+ mbPattUsed = !::get_flag( nFlags, EXC_CF_AREA_PATTERN );
+
+ if( mbBackUsed && (!mbPattUsed || (mnPattern == EXC_PATT_SOLID)) )
+ {
+ mnForeColor = mnBackColor;
+ mnPattern = EXC_PATT_SOLID;
+ mbForeUsed = mbPattUsed = true;
+ }
+ else if( !mbBackUsed && mbPattUsed && (mnPattern == EXC_PATT_SOLID) )
+ {
+ mbPattUsed = false;
+ }
+}
+
+void XclImpCellArea::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
+{
+ if( mbPattUsed ) // colors may be both unused in cond. formats
+ {
+ SvxBrushItem aBrushItem( ATTR_BACKGROUND );
+
+ // #108935# do not use IsTransparent() - old Calc filter writes tranparency with different color indexes
+ if( mnPattern == EXC_PATT_NONE )
+ {
+ aBrushItem.SetColor( Color( COL_TRANSPARENT ) );
+ }
+ else
+ {
+ Color aFore( rPalette.GetColor( mbForeUsed ? mnForeColor : EXC_COLOR_WINDOWTEXT ) );
+ Color aBack( rPalette.GetColor( mbBackUsed ? mnBackColor : EXC_COLOR_WINDOWBACK ) );
+ aBrushItem.SetColor( XclTools::GetPatternColor( aFore, aBack, mnPattern ) );
+ }
+
+ ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+XclImpXF::XclImpXF( const XclImpRoot& rRoot ) :
+ XclXFBase( true ), // default is cell XF
+ XclImpRoot( rRoot ),
+ mpStyleSheet( 0 ),
+ mnXclNumFmt( 0 ),
+ mnXclFont( 0 )
+{
+}
+
+XclImpXF::~XclImpXF()
+{
+}
+
+void XclImpXF::ReadXF2( XclImpStream& rStrm )
+{
+ sal_uInt8 nReadFont, nReadNumFmt, nFlags;
+ rStrm >> nReadFont;
+ rStrm.Ignore( 1 );
+ rStrm >> nReadNumFmt >> nFlags;
+
+ // XF type always cell, no parent, used flags always true
+ SetAllUsedFlags( true );
+
+ // attributes
+ maProtection.FillFromXF2( nReadNumFmt );
+ mnXclFont = nReadFont;
+ mnXclNumFmt = nReadNumFmt & EXC_XF2_VALFMT_MASK;
+ maAlignment.FillFromXF2( nFlags );
+ maBorder.FillFromXF2( nFlags );
+ maArea.FillFromXF2( nFlags );
+}
+
+void XclImpXF::ReadXF3( XclImpStream& rStrm )
+{
+ sal_uInt32 nBorder;
+ sal_uInt16 nTypeProt, nAlign, nArea;
+ sal_uInt8 nReadFont, nReadNumFmt;
+ rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE ); // new in BIFF3
+ mnParent = ::extract_value< sal_uInt16 >( nAlign, 4, 12 ); // new in BIFF3
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nTypeProt, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ mnXclFont = nReadFont;
+ mnXclNumFmt = nReadNumFmt;
+ maAlignment.FillFromXF3( nAlign );
+ maBorder.FillFromXF3( nBorder );
+ maArea.FillFromXF3( nArea ); // new in BIFF3
+}
+
+void XclImpXF::ReadXF4( XclImpStream& rStrm )
+{
+ sal_uInt32 nBorder;
+ sal_uInt16 nTypeProt, nAlign, nArea;
+ sal_uInt8 nReadFont, nReadNumFmt;
+ rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
+ mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ mnXclFont = nReadFont;
+ mnXclNumFmt = nReadNumFmt;
+ maAlignment.FillFromXF4( nAlign );
+ maBorder.FillFromXF3( nBorder );
+ maArea.FillFromXF3( nArea );
+}
+
+void XclImpXF::ReadXF5( XclImpStream& rStrm )
+{
+ sal_uInt32 nArea, nBorder;
+ sal_uInt16 nTypeProt, nAlign;
+ rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
+ mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ maAlignment.FillFromXF5( nAlign );
+ maBorder.FillFromXF5( nBorder, nArea );
+ maArea.FillFromXF5( nArea );
+}
+
+void XclImpXF::ReadXF8( XclImpStream& rStrm )
+{
+ sal_uInt32 nBorder1, nBorder2;
+ sal_uInt16 nTypeProt, nAlign, nMiscAttrib, nArea;
+ rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
+ mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nMiscAttrib, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ maAlignment.FillFromXF8( nAlign, nMiscAttrib );
+ maBorder.FillFromXF8( nBorder1, nBorder2 );
+ maArea.FillFromXF8( nBorder2, nArea );
+}
+
+void XclImpXF::ReadXF( XclImpStream& rStrm )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2: ReadXF2( rStrm ); break;
+ case EXC_BIFF3: ReadXF3( rStrm ); break;
+ case EXC_BIFF4: ReadXF4( rStrm ); break;
+ case EXC_BIFF5: ReadXF5( rStrm ); break;
+ case EXC_BIFF8: ReadXF8( rStrm ); break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs )
+{
+ if( mpPattern.get() )
+ return *mpPattern;
+
+ // create new pattern attribute set
+ mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) );
+ SfxItemSet& rItemSet = mpPattern->GetItemSet();
+ XclImpXF* pParentXF = IsCellXF() ? GetXFBuffer().GetXF( mnParent ) : 0;
+
+ // parent cell style
+ if( IsCellXF() && !mpStyleSheet )
+ {
+ mpStyleSheet = GetXFBuffer().CreateStyleSheet( mnParent );
+
+ /* Enables mb***Used flags, if the formatting attributes differ from
+ the passed XF record. In cell XFs Excel uses the cell attributes,
+ if they differ from the parent style XF.
+ #109899# ...or if the respective flag is not set in parent style XF. */
+ if( pParentXF )
+ {
+ if( !mbProtUsed )
+ mbProtUsed = !pParentXF->mbProtUsed || !(maProtection == pParentXF->maProtection);
+ if( !mbFontUsed )
+ mbFontUsed = !pParentXF->mbFontUsed || (mnXclFont != pParentXF->mnXclFont);
+ if( !mbFmtUsed )
+ mbFmtUsed = !pParentXF->mbFmtUsed || (mnXclNumFmt != pParentXF->mnXclNumFmt);
+ if( !mbAlignUsed )
+ mbAlignUsed = !pParentXF->mbAlignUsed || !(maAlignment == pParentXF->maAlignment);
+ if( !mbBorderUsed )
+ mbBorderUsed = !pParentXF->mbBorderUsed || !(maBorder == pParentXF->maBorder);
+ if( !mbAreaUsed )
+ mbAreaUsed = !pParentXF->mbAreaUsed || !(maArea == pParentXF->maArea);
+ }
+ }
+
+ // cell protection
+ if( mbProtUsed )
+ maProtection.FillToItemSet( rItemSet, bSkipPoolDefs );
+
+ // font
+ if( mbFontUsed )
+ GetFontBuffer().FillToItemSet( rItemSet, EXC_FONTITEM_CELL, mnXclFont, bSkipPoolDefs );
+
+ // value format
+ if( mbFmtUsed )
+ {
+ GetNumFmtBuffer().FillToItemSet( rItemSet, mnXclNumFmt, bSkipPoolDefs );
+ // Trace occurrences of Windows date formats
+ GetTracer().TraceDates( mnXclNumFmt );
+ }
+
+ // alignment
+ if( mbAlignUsed )
+ maAlignment.FillToItemSet( rItemSet, GetFontBuffer().GetFont( mnXclFont ), bSkipPoolDefs );
+
+ // border
+ if( mbBorderUsed )
+ {
+ maBorder.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
+ GetTracer().TraceBorderLineStyle(maBorder.mnLeftLine > EXC_LINE_HAIR ||
+ maBorder.mnRightLine > EXC_LINE_HAIR || maBorder.mnTopLine > EXC_LINE_HAIR ||
+ maBorder.mnBottomLine > EXC_LINE_HAIR );
+ }
+
+ // area
+ if( mbAreaUsed )
+ {
+ maArea.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
+ GetTracer().TraceFillPattern(maArea.mnPattern != EXC_PATT_NONE &&
+ maArea.mnPattern != EXC_PATT_SOLID);
+ }
+
+ /* #i38709# Decide which rotation reference mode to use. If any outer
+ border line of the cell is set (either explicitly or via cell style),
+ and the cell contents are rotated, set rotation reference to bottom of
+ cell. This causes the borders to be painted rotated with the text. */
+ if( mbAlignUsed || mbBorderUsed )
+ {
+ SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
+ const XclImpCellAlign* pAlign = mbAlignUsed ? &maAlignment : (pParentXF ? &pParentXF->maAlignment : 0);
+ const XclImpCellBorder* pBorder = mbBorderUsed ? &maBorder : (pParentXF ? &pParentXF->maBorder : 0);
+ if( pAlign && pBorder && (0 < pAlign->mnRotation) && (pAlign->mnRotation <= 180) && pBorder->HasAnyOuterBorder() )
+ eRotateMode = SVX_ROTATE_MODE_BOTTOM;
+ ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
+ }
+
+ return *mpPattern;
+}
+
+void XclImpXF::ApplyPattern(
+ SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2,
+ SCTAB nScTab, ULONG nForceScNumFmt )
+{
+ // force creation of cell style and hard formatting, do it here to have mpStyleSheet
+ const ScPatternAttr& rPattern = CreatePattern();
+
+ // insert into document
+ ScDocument& rDoc = GetDoc();
+ if( IsCellXF() && mpStyleSheet )
+ rDoc.ApplyStyleAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, *mpStyleSheet );
+ if( HasUsedFlags() )
+ rDoc.ApplyPatternAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, rPattern );
+
+ // #108770# apply special number format
+ if( nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
+ {
+ ScPatternAttr aPattern( GetDoc().GetPool() );
+ GetNumFmtBuffer().FillScFmtToItemSet( aPattern.GetItemSet(), nForceScNumFmt );
+ rDoc.ApplyPatternAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, aPattern );
+ }
+}
+
+void XclImpXF::SetUsedFlags( sal_uInt8 nUsedFlags )
+{
+ /* Notes about finding the mb***Used flags:
+ - In cell XFs a *set* bit means a used attribute.
+ - In style XFs a *cleared* bit means a used attribute.
+ The mb***Used members always store true, if the attribute is used.
+ The "mbCellXF == ::get_flag(...)" construct evaluates to true in
+ both mentioned cases: cell XF and set bit; or style XF and cleared bit.
+ */
+ mbProtUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_PROT ));
+ mbFontUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_FONT ));
+ mbFmtUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_VALFMT ));
+ mbAlignUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_ALIGN ));
+ mbBorderUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_BORDER ));
+ mbAreaUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_AREA ));
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpStyle::XclImpStyle( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnXfId( EXC_XF_NOTFOUND ),
+ mnBuiltinId( EXC_STYLE_USERDEF ),
+ mnLevel( EXC_STYLE_NOLEVEL ),
+ mbBuiltin( false ),
+ mbCustom( false ),
+ mbHidden( false ),
+ mpStyleSheet( 0 )
+{
+}
+
+void XclImpStyle::ReadStyle( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 );
+
+ sal_uInt16 nXFIndex;
+ rStrm >> nXFIndex;
+ mnXfId = nXFIndex & EXC_STYLE_XFMASK;
+ mbBuiltin = ::get_flag( nXFIndex, EXC_STYLE_BUILTIN );
+
+ if( mbBuiltin )
+ {
+ rStrm >> mnBuiltinId >> mnLevel;
+ }
+ else
+ {
+ maName = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
+ // #i103281# check if this is a new built-in style introduced in XL2007
+ if( (GetBiff() == EXC_BIFF8) && (rStrm.GetNextRecId() == EXC_ID_STYLEEXT) && rStrm.StartNextRecord() )
+ {
+ sal_uInt8 nExtFlags;
+ rStrm.Ignore( 12 );
+ rStrm >> nExtFlags;
+ mbBuiltin = ::get_flag( nExtFlags, EXC_STYLEEXT_BUILTIN );
+ mbCustom = ::get_flag( nExtFlags, EXC_STYLEEXT_CUSTOM );
+ mbHidden = ::get_flag( nExtFlags, EXC_STYLEEXT_HIDDEN );
+ if( mbBuiltin )
+ {
+ rStrm.Ignore( 1 ); // category
+ rStrm >> mnBuiltinId >> mnLevel;
+ }
+ }
+ }
+}
+
+ScStyleSheet* XclImpStyle::CreateStyleSheet()
+{
+ // #i1624# #i1768# ignore unnamed user styles
+ if( !mpStyleSheet && (maFinalName.Len() > 0) )
+ {
+ bool bCreatePattern = false;
+ XclImpXF* pXF = GetXFBuffer().GetXF( mnXfId );
+
+ bool bDefStyle = mbBuiltin && (mnBuiltinId == EXC_STYLE_NORMAL);
+ if( bDefStyle )
+ {
+ // set all flags to true to get all items in XclImpXF::CreatePattern()
+ if( pXF ) pXF->SetAllUsedFlags( true );
+ // use existing "Default" style sheet
+ mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find(
+ ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) );
+ DBG_ASSERT( mpStyleSheet, "XclImpStyle::CreateStyleSheet - Default style not found" );
+ bCreatePattern = true;
+ }
+ else
+ {
+ /* #i103281# do not create another style sheet of the same name,
+ if it exists already. This is needed to prevent that styles
+ pasted from clipboard get duplicated over and over. */
+ mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( maFinalName, SFX_STYLE_FAMILY_PARA ) );
+ if( !mpStyleSheet )
+ {
+ mpStyleSheet = &static_cast< ScStyleSheet& >( GetStyleSheetPool().Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) );
+ bCreatePattern = true;
+ }
+ }
+
+ // bDefStyle==true omits default pool items in CreatePattern()
+ if( bCreatePattern && mpStyleSheet && pXF )
+ mpStyleSheet->GetItemSet().Put( pXF->CreatePattern( bDefStyle ).GetItemSet() );
+ }
+ return mpStyleSheet;
+}
+
+void XclImpStyle::CreateUserStyle( const String& rFinalName )
+{
+ maFinalName = rFinalName;
+ if( !IsBuiltin() || mbCustom )
+ CreateStyleSheet();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpXFBuffer::XclImpXFBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpXFBuffer::Initialize()
+{
+ maXFList.Clear();
+ maBuiltinStyles.Clear();
+ maUserStyles.Clear();
+ maStylesByXf.clear();
+}
+
+void XclImpXFBuffer::ReadXF( XclImpStream& rStrm )
+{
+ XclImpXF* pXF = new XclImpXF( GetRoot() );
+ pXF->ReadXF( rStrm );
+ maXFList.Append( pXF );
+}
+
+void XclImpXFBuffer::ReadStyle( XclImpStream& rStrm )
+{
+ XclImpStyle* pStyle = new XclImpStyle( GetRoot() );
+ pStyle->ReadStyle( rStrm );
+ (pStyle->IsBuiltin() ? maBuiltinStyles : maUserStyles).Append( pStyle );
+ DBG_ASSERT( maStylesByXf.count( pStyle->GetXfId() ) == 0, "XclImpXFBuffer::ReadStyle - multiple styles with equal XF identifier" );
+ maStylesByXf[ pStyle->GetXfId() ] = pStyle;
+}
+
+sal_uInt16 XclImpXFBuffer::GetFontIndex( sal_uInt16 nXFIndex ) const
+{
+ const XclImpXF* pXF = GetXF( nXFIndex );
+ return pXF ? pXF->GetFontIndex() : EXC_FONT_NOTFOUND;
+}
+
+const XclImpFont* XclImpXFBuffer::GetFont( sal_uInt16 nXFIndex ) const
+{
+ return GetFontBuffer().GetFont( GetFontIndex( nXFIndex ) );
+}
+
+namespace {
+
+/** Functor for case-insensitive string comparison, usable in maps etc. */
+struct IgnoreCaseCompare
+{
+ inline bool operator()( const String& rName1, const String& rName2 ) const
+ { return rName1.CompareIgnoreCaseToAscii( rName2 ) == COMPARE_LESS; }
+};
+
+} // namespace
+
+void XclImpXFBuffer::CreateUserStyles()
+{
+ // calculate final names of all styles
+ typedef ::std::map< String, XclImpStyle*, IgnoreCaseCompare > CellStyleNameMap;
+ typedef ::std::vector< XclImpStyle* > XclImpStyleVector;
+
+ CellStyleNameMap aCellStyles;
+ XclImpStyleVector aConflictNameStyles;
+
+ /* First, reserve style names that are built-in in Calc. This causes that
+ imported cell styles get different unused names and thus do not try to
+ overwrite these built-in styles. For BIFF4 workbooks (which contain a
+ separate list of cell styles per sheet), reserve all existing styles if
+ current sheet is not the first sheet (this styles buffer will be
+ initialized again for every new sheet). This will create unique names
+ for styles in different sheets with the same name. Assuming that the
+ BIFF4W import filter is never used to import from clipboard... */
+ bool bReserveAll = (GetBiff() == EXC_BIFF4) && (GetCurrScTab() > 0);
+ SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
+ String aStandardName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
+ for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
+ if( (pStyleSheet->GetName() != aStandardName) && (bReserveAll || !pStyleSheet->IsUserDefined()) )
+ if( aCellStyles.count( pStyleSheet->GetName() ) == 0 )
+ aCellStyles[ pStyleSheet->GetName() ] = 0;
+
+ /* Calculate names of built-in styles. Store styles with reserved names
+ in the aConflictNameStyles list. */
+ for( XclImpStyle* pStyle = maBuiltinStyles.First(); pStyle; pStyle = maBuiltinStyles.Next() )
+ {
+ String aStyleName = XclTools::GetBuiltInStyleName( pStyle->GetBuiltinId(), pStyle->GetName(), pStyle->GetLevel() );
+ DBG_ASSERT( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
+ "XclImpXFBuffer::CreateUserStyles - multiple styles with equal built-in identifier" );
+ if( aCellStyles.count( aStyleName ) > 0 )
+ aConflictNameStyles.push_back( pStyle );
+ else
+ aCellStyles[ aStyleName ] = pStyle;
+ }
+
+ /* Calculate names of user defined styles. Store styles with reserved
+ names in the aConflictNameStyles list. */
+ for( XclImpStyle* pStyle = maUserStyles.First(); pStyle; pStyle = maUserStyles.Next() )
+ {
+ // #i1624# #i1768# ignore unnamed user styles
+ if( pStyle->GetName().Len() > 0 )
+ {
+ if( aCellStyles.count( pStyle->GetName() ) > 0 )
+ aConflictNameStyles.push_back( pStyle );
+ else
+ aCellStyles[ pStyle->GetName() ] = pStyle;
+ }
+ }
+
+ // find unused names for all styles with conflicting names
+ for( XclImpStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
+ {
+ XclImpStyle* pStyle = *aIt;
+ String aUnusedName;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aUnusedName.Assign( pStyle->GetName() ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) );
+ }
+ while( aCellStyles.count( aUnusedName ) > 0 );
+ aCellStyles[ aUnusedName ] = pStyle;
+ }
+
+ // set final names and create user-defined and modified built-in cell styles
+ for( CellStyleNameMap::iterator aIt = aCellStyles.begin(), aEnd = aCellStyles.end(); aIt != aEnd; ++aIt )
+ if( aIt->second )
+ aIt->second->CreateUserStyle( aIt->first );
+}
+
+ScStyleSheet* XclImpXFBuffer::CreateStyleSheet( sal_uInt16 nXFIndex )
+{
+ XclImpStyleMap::iterator aIt = maStylesByXf.find( nXFIndex );
+ return (aIt == maStylesByXf.end()) ? 0 : aIt->second->CreateStyleSheet();
+}
+
+void XclImpXFBuffer::ApplyPattern(
+ SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2,
+ SCTAB nScTab, const XclImpXFIndex& rXFIndex )
+{
+ if( XclImpXF* pXF = GetXF( rXFIndex.GetXFIndex() ) )
+ {
+ // #108770# set 'Standard' number format for all Boolean cells
+ ULONG nForceScNumFmt = rXFIndex.IsBoolCell() ? GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND;
+ pXF->ApplyPattern( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, nForceScNumFmt );
+ }
+}
+
+// Buffer for XF indexes in cells =============================================
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange, 100, 500 )
+
+bool XclImpXFRange::Expand( SCROW nScRow, const XclImpXFIndex& rXFIndex )
+{
+ if( maXFIndex != rXFIndex )
+ return false;
+
+ if( mnScRow2 + 1 == nScRow )
+ {
+ ++mnScRow2;
+ return true;
+ }
+ if( mnScRow1 > 0 && (mnScRow1 - 1 == nScRow) )
+ {
+ --mnScRow1;
+ return true;
+ }
+
+ return false;
+}
+
+bool XclImpXFRange::Expand( const XclImpXFRange& rNextRange )
+{
+ DBG_ASSERT( mnScRow2 < rNextRange.mnScRow1, "XclImpXFRange::Expand - rows out of order" );
+ if( (maXFIndex == rNextRange.maXFIndex) && (mnScRow2 + 1 == rNextRange.mnScRow1) )
+ {
+ mnScRow2 = rNextRange.mnScRow2;
+ return true;
+ }
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpXFRangeColumn::SetDefaultXF( const XclImpXFIndex& rXFIndex )
+{
+ // List should be empty when inserting the default column format.
+ // Later explicit SetXF() calls will break up this range.
+ DBG_ASSERT( maIndexList.Empty(), "XclImpXFRangeColumn::SetDefaultXF - Setting Default Column XF is not empty" );
+
+ // insert a complete row range with one insert.
+ maIndexList.Append( new XclImpXFRange( 0, MAXROW, rXFIndex ) );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpXFRangeColumn::SetXF( SCROW nScRow, const XclImpXFIndex& rXFIndex )
+{
+ XclImpXFRange* pPrevRange;
+ XclImpXFRange* pNextRange;
+ ULONG nNextIndex;
+
+ Find( pPrevRange, pNextRange, nNextIndex, nScRow );
+
+ // previous range:
+ // try to overwrite XF (if row is contained in) or try to expand range
+ if( pPrevRange )
+ {
+ if( pPrevRange->Contains( nScRow ) ) // overwrite old XF
+ {
+ if( rXFIndex == pPrevRange->maXFIndex )
+ return;
+
+ SCROW nFirstScRow = pPrevRange->mnScRow1;
+ SCROW nLastScRow = pPrevRange->mnScRow2;
+ ULONG nIndex = nNextIndex - 1;
+ XclImpXFRange* pThisRange = pPrevRange;
+ pPrevRange = nIndex ? maIndexList.GetObject( nIndex - 1 ) : 0;
+
+ if( nFirstScRow == nLastScRow ) // replace solely XF
+ {
+ pThisRange->maXFIndex = rXFIndex;
+ TryConcatPrev( nNextIndex ); // try to concat. next with this
+ TryConcatPrev( nIndex ); // try to concat. this with previous
+ }
+ else if( nFirstScRow == nScRow ) // replace first XF
+ {
+ ++(pThisRange->mnScRow1);
+ // try to concatenate with previous of this
+ if( !pPrevRange || !pPrevRange->Expand( nScRow, rXFIndex ) )
+ maIndexList.Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
+ }
+ else if( nLastScRow == nScRow ) // replace last XF
+ {
+ --(pThisRange->mnScRow2);
+ if( !pNextRange || !pNextRange->Expand( nScRow, rXFIndex ) )
+ maIndexList.Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
+ }
+ else // insert in the middle of the range
+ {
+ pThisRange->mnScRow1 = nScRow + 1;
+ // List::Insert() moves entries towards end of list, so insert twice at nIndex
+ maIndexList.Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
+ maIndexList.Insert( new XclImpXFRange( nFirstScRow, nScRow - 1, pThisRange->maXFIndex ), nIndex );
+ }
+ return;
+ }
+ else if( pPrevRange->Expand( nScRow, rXFIndex ) ) // try to expand
+ {
+ TryConcatPrev( nNextIndex ); // try to concatenate next with expanded
+ return;
+ }
+ }
+
+ // try to expand next range
+ if( pNextRange && pNextRange->Expand( nScRow, rXFIndex ) )
+ return;
+
+ // create new range
+ maIndexList.Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
+}
+
+void XclImpXFRangeColumn::Find(
+ XclImpXFRange*& rpPrevRange, XclImpXFRange*& rpNextRange,
+ ULONG& rnNextIndex, SCROW nScRow ) const
+{
+
+ // test whether list is empty
+ if( maIndexList.Empty() )
+ {
+ rpPrevRange = rpNextRange = 0;
+ rnNextIndex = 0;
+ return;
+ }
+
+ rpPrevRange = maIndexList.GetObject( 0 );
+ rpNextRange = maIndexList.GetObject( maIndexList.Count() - 1 );
+
+ // test whether row is at end of list (contained in or behind last range)
+ // rpPrevRange will contain a possible existing row
+ if( rpNextRange->mnScRow1 <= nScRow )
+ {
+ rpPrevRange = rpNextRange;
+ rpNextRange = 0;
+ rnNextIndex = maIndexList.Count();
+ return;
+ }
+
+ // test whether row is at beginning of list (really before first range)
+ if( nScRow < rpPrevRange->mnScRow1 )
+ {
+ rpNextRange = rpPrevRange;
+ rpPrevRange = 0;
+ rnNextIndex = 0;
+ return;
+ }
+
+ // loop: find range entries before and after new row
+ // break the loop if there is no more range between first and last -or-
+ // if rpPrevRange contains nScRow (rpNextRange will never contain nScRow)
+ ULONG nPrevIndex = 0;
+ ULONG nMidIndex;
+ rnNextIndex = maIndexList.Count() - 1;
+ XclImpXFRange* pMidRange;
+ while( ((rnNextIndex - nPrevIndex) > 1) && (rpPrevRange->mnScRow2 < nScRow) )
+ {
+ nMidIndex = (nPrevIndex + rnNextIndex) / 2;
+ pMidRange = maIndexList.GetObject( nMidIndex );
+ DBG_ASSERT( pMidRange, "XclImpXFRangeColumn::Find - missing XF index range" );
+ if( nScRow < pMidRange->mnScRow1 ) // row is really before pMidRange
+ {
+ rpNextRange = pMidRange;
+ rnNextIndex = nMidIndex;
+ }
+ else // row is in or after pMidRange
+ {
+ rpPrevRange = pMidRange;
+ nPrevIndex = nMidIndex;
+ }
+ }
+
+ // find next rpNextRange if rpPrevRange contains nScRow
+ if( nScRow <= rpPrevRange->mnScRow2 )
+ {
+ rnNextIndex = nPrevIndex + 1;
+ rpNextRange = maIndexList.GetObject( rnNextIndex );
+ }
+}
+
+void XclImpXFRangeColumn::TryConcatPrev( ULONG nIndex )
+{
+ if( !nIndex )
+ return;
+
+ XclImpXFRange* pPrevRange = maIndexList.GetObject( nIndex - 1 );
+ XclImpXFRange* pNextRange = maIndexList.GetObject( nIndex );
+ if( !pPrevRange || !pNextRange )
+ return;
+
+ if( pPrevRange->Expand( *pNextRange ) )
+ maIndexList.Delete( nIndex );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpXFRangeBuffer::XclImpXFRangeBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+XclImpXFRangeBuffer::~XclImpXFRangeBuffer()
+{
+}
+
+void XclImpXFRangeBuffer::Initialize()
+{
+ maColumns.clear();
+ maHyperlinks.clear();
+ maMergeList.RemoveAll();
+}
+
+void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex, XclImpXFInsertMode eMode )
+{
+ SCCOL nScCol = rScPos.Col();
+ SCROW nScRow = rScPos.Row();
+
+ // set cell XF's
+ size_t nIndex = static_cast< size_t >( nScCol );
+ if( maColumns.size() <= nIndex )
+ maColumns.resize( nIndex + 1 );
+ if( !maColumns[ nIndex ] )
+ maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
+ // #108770# remember all Boolean cells, they will get 'Standard' number format
+ maColumns[ nIndex ]->SetXF( nScRow, XclImpXFIndex( nXFIndex, eMode == xlXFModeBoolCell ) );
+
+ // set "center across selection" and "fill" attribute for all following empty cells
+ // #97130# ignore it on row default XFs
+ if( eMode != xlXFModeRow )
+ {
+ const XclImpXF* pXF = GetXFBuffer().GetXF( nXFIndex );
+ if( pXF && ((pXF->GetHorAlign() == EXC_XF_HOR_CENTER_AS) || (pXF->GetHorAlign() == EXC_XF_HOR_FILL)) )
+ {
+ // expand last merged range if this attribute is set repeatedly
+ ScRange* pRange = maMergeList.Last();
+ if( pRange && (pRange->aEnd.Row() == nScRow) && (pRange->aEnd.Col() + 1 == nScCol)
+ && (eMode == xlXFModeBlank) )
+ pRange->aEnd.IncCol();
+ else if( eMode != xlXFModeBlank ) // #108781# do not merge empty cells
+ SetMerge( nScCol, nScRow );
+ }
+ }
+}
+
+void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
+{
+ SetXF( rScPos, nXFIndex, xlXFModeCell );
+}
+
+void XclImpXFRangeBuffer::SetBlankXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
+{
+ SetXF( rScPos, nXFIndex, xlXFModeBlank );
+}
+
+void XclImpXFRangeBuffer::SetBoolXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
+{
+ SetXF( rScPos, nXFIndex, xlXFModeBoolCell );
+}
+
+void XclImpXFRangeBuffer::SetRowDefXF( SCROW nScRow, sal_uInt16 nXFIndex )
+{
+ for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
+ SetXF( ScAddress( nScCol, nScRow, 0 ), nXFIndex, xlXFModeRow );
+}
+
+void XclImpXFRangeBuffer::SetColumnDefXF( SCCOL nScCol, sal_uInt16 nXFIndex )
+{
+ // our array should not have values when creating the default column format.
+ size_t nIndex = static_cast< size_t >( nScCol );
+ if( maColumns.size() <= nIndex )
+ maColumns.resize( nIndex + 1 );
+ DBG_ASSERT( !maColumns[ nIndex ], "XclImpXFRangeBuffer::SetColumnDefXF - default column of XFs already has values" );
+ maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
+ maColumns[ nIndex ]->SetDefaultXF( XclImpXFIndex( nXFIndex ) );
+}
+
+void XclImpXFRangeBuffer::SetBorderLine( const ScRange& rRange, SCTAB nScTab, USHORT nLine )
+{
+ SCCOL nFromScCol = (nLine == BOX_LINE_RIGHT) ? rRange.aEnd.Col() : rRange.aStart.Col();
+ SCROW nFromScRow = (nLine == BOX_LINE_BOTTOM) ? rRange.aEnd.Row() : rRange.aStart.Row();
+ ScDocument& rDoc = GetDoc();
+
+ const SvxBoxItem* pFromItem = static_cast< const SvxBoxItem* >(
+ rDoc.GetAttr( nFromScCol, nFromScRow, nScTab, ATTR_BORDER ) );
+ const SvxBoxItem* pToItem = static_cast< const SvxBoxItem* >(
+ rDoc.GetAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, ATTR_BORDER ) );
+
+ SvxBoxItem aNewItem( *pToItem );
+ aNewItem.SetLine( pFromItem->GetLine( nLine ), nLine );
+ rDoc.ApplyAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, aNewItem );
+}
+
+void XclImpXFRangeBuffer::SetHyperlink( const XclRange& rXclRange, const String& rUrl )
+{
+ maHyperlinks.push_back( XclImpHyperlinkRange( rXclRange, rUrl ) );
+}
+
+void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol, SCROW nScRow )
+{
+ maMergeList.Append( ScRange( nScCol, nScRow, 0 ) );
+}
+
+void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2 )
+{
+ if( (nScCol1 < nScCol2) || (nScRow1 < nScRow2) )
+ maMergeList.Append( ScRange( nScCol1, nScRow1, 0, nScCol2, nScRow2, 0 ) );
+}
+
+void XclImpXFRangeBuffer::Finalize()
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ // apply patterns
+ XclImpXFBuffer& rXFBuffer = GetXFBuffer();
+ for( XclImpXFRangeColumnVec::const_iterator aVBeg = maColumns.begin(), aVEnd = maColumns.end(), aVIt = aVBeg; aVIt != aVEnd; ++aVIt )
+ {
+ // apply all cell styles of an existing column
+ if( aVIt->is() )
+ {
+ XclImpXFRangeColumn& rColumn = **aVIt;
+ SCCOL nScCol = static_cast< SCCOL >( aVIt - aVBeg );
+ for( XclImpXFRange* pStyle = rColumn.First(); pStyle; pStyle = rColumn.Next() )
+ rXFBuffer.ApplyPattern( nScCol, pStyle->mnScRow1, nScCol, pStyle->mnScRow2, nScTab, pStyle->maXFIndex );
+ }
+ }
+
+ // insert hyperlink cells
+ for( XclImpHyperlinkList::const_iterator aLIt = maHyperlinks.begin(), aLEnd = maHyperlinks.end(); aLIt != aLEnd; ++aLIt )
+ XclImpHyperlink::InsertUrl( GetRoot(), aLIt->first, aLIt->second );
+
+ // apply cell merging
+ for( const ScRange* pRange = maMergeList.First(); pRange; pRange = maMergeList.Next() )
+ {
+ const ScAddress& rStart = pRange->aStart;
+ const ScAddress& rEnd = pRange->aEnd;
+ bool bMultiCol = rStart.Col() != rEnd.Col();
+ bool bMultiRow = rStart.Row() != rEnd.Row();
+ // set correct right border
+ if( bMultiCol )
+ SetBorderLine( *pRange, nScTab, BOX_LINE_RIGHT );
+ // set correct lower border
+ if( bMultiRow )
+ SetBorderLine( *pRange, nScTab, BOX_LINE_BOTTOM );
+ // do merge
+ if( bMultiCol || bMultiRow )
+ rDoc.DoMerge( nScTab, rStart.Col(), rStart.Row(), rEnd.Col(), rEnd.Row() );
+ // #i93609# merged range in a single row: test if manual row height is needed
+ if( !bMultiRow )
+ {
+ bool bTextWrap = static_cast< const SfxBoolItem* >( rDoc.GetAttr( rStart.Col(), rStart.Row(), rStart.Tab(), ATTR_LINEBREAK ) )->GetValue();
+ if( !bTextWrap && (rDoc.GetCellType( rStart ) == CELLTYPE_EDIT) )
+ if( const EditTextObject* pEditObj = static_cast< const ScEditCell* >( rDoc.GetCell( rStart ) )->GetData() )
+ bTextWrap = pEditObj->GetParagraphCount() > 1;
+ if( bTextWrap )
+ GetOldRoot().pColRowBuff->SetManualRowHeight( rStart.Row() );
+ }
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xiview.cxx b/sc/source/filter/excel/xiview.cxx
new file mode 100644
index 000000000000..f75032ff461e
--- /dev/null
+++ b/sc/source/filter/excel/xiview.cxx
@@ -0,0 +1,304 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xiview.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "viewopti.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xistyle.hxx"
+
+// Document view settings =====================================================
+
+XclImpDocViewSettings::XclImpDocViewSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpDocViewSettings::ReadWindow1( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnWinX
+ >> maData.mnWinY
+ >> maData.mnWinWidth
+ >> maData.mnWinHeight
+ >> maData.mnFlags;
+ if( GetBiff() >= EXC_BIFF5 )
+ {
+ rStrm >> maData.mnDisplXclTab
+ >> maData.mnFirstVisXclTab
+ >> maData.mnXclSelectCnt
+ >> maData.mnTabBarWidth;
+ }
+}
+
+SCTAB XclImpDocViewSettings::GetDisplScTab() const
+{
+ /* Simply cast Excel index to Calc index.
+ TODO: This may fail if the document contains scenarios. */
+ sal_uInt16 nMaxXclTab = static_cast< sal_uInt16 >( GetMaxPos().Tab() );
+ return static_cast< SCTAB >( (maData.mnDisplXclTab <= nMaxXclTab) ? maData.mnDisplXclTab : 0 );
+}
+
+void XclImpDocViewSettings::Finalize()
+{
+ ScViewOptions aViewOpt( GetDoc().GetViewOptions() );
+ aViewOpt.SetOption( VOPT_HSCROLL, ::get_flag( maData.mnFlags, EXC_WIN1_HOR_SCROLLBAR ) );
+ aViewOpt.SetOption( VOPT_VSCROLL, ::get_flag( maData.mnFlags, EXC_WIN1_VER_SCROLLBAR ) );
+ aViewOpt.SetOption( VOPT_TABCONTROLS, ::get_flag( maData.mnFlags, EXC_WIN1_TABBAR ) );
+ GetDoc().SetViewOptions( aViewOpt );
+
+ // displayed sheet
+ GetExtDocOptions().GetDocSettings().mnDisplTab = GetDisplScTab();
+
+ // width of the tabbar with sheet names
+ if( maData.mnTabBarWidth <= 1000 )
+ GetExtDocOptions().GetDocSettings().mfTabBarWidth = static_cast< double >( maData.mnTabBarWidth ) / 1000.0;
+}
+
+// Sheet view settings ========================================================
+
+namespace {
+
+long lclGetScZoom( sal_uInt16 nXclZoom, sal_uInt16 nDefZoom )
+{
+ return static_cast< long >( nXclZoom ? nXclZoom : nDefZoom );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclImpTabViewSettings::XclImpTabViewSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+ Initialize();
+}
+
+void XclImpTabViewSettings::Initialize()
+{
+ maData.SetDefaults();
+}
+
+void XclImpTabViewSettings::ReadTabBgColor( XclImpStream& rStrm, XclImpPalette& rPal )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF8 );
+ if( GetBiff() < EXC_BIFF8 )
+ return;
+
+ sal_uInt8 ColorIndex;
+ Color TabBgColor;
+
+ rStrm.Ignore( 16 );
+ ColorIndex = rStrm.ReaduInt8() & EXC_SHEETEXT_TABCOLOR; //0x7F
+ if ( ColorIndex >= 8 && ColorIndex <= 63 ) //only accept valid index values
+ {
+ TabBgColor = rPal.GetColor( ColorIndex );
+ maData.maTabBgColor = TabBgColor;
+ }
+}
+
+void XclImpTabViewSettings::ReadWindow2( XclImpStream& rStrm, bool bChart )
+{
+ if( GetBiff() == EXC_BIFF2 )
+ {
+ maData.mbShowFormulas = rStrm.ReaduInt8() != 0;
+ maData.mbShowGrid = rStrm.ReaduInt8() != 0;
+ maData.mbShowHeadings = rStrm.ReaduInt8() != 0;
+ maData.mbFrozenPanes = rStrm.ReaduInt8() != 0;
+ maData.mbShowZeros = rStrm.ReaduInt8() != 0;
+ rStrm >> maData.maFirstXclPos;
+ maData.mbDefGridColor = rStrm.ReaduInt8() != 0;
+ rStrm >> maData.maGridColor;
+ }
+ else
+ {
+ sal_uInt16 nFlags;
+ rStrm >> nFlags >> maData.maFirstXclPos;
+
+ // #i59590# #158194# real life: Excel ignores some view settings in chart sheets
+ maData.mbSelected = ::get_flag( nFlags, EXC_WIN2_SELECTED );
+ maData.mbDisplayed = ::get_flag( nFlags, EXC_WIN2_DISPLAYED );
+ maData.mbMirrored = !bChart && ::get_flag( nFlags, EXC_WIN2_MIRRORED );
+ maData.mbFrozenPanes = !bChart && ::get_flag( nFlags, EXC_WIN2_FROZEN );
+ maData.mbPageMode = !bChart && ::get_flag( nFlags, EXC_WIN2_PAGEBREAKMODE );
+ maData.mbDefGridColor = bChart || ::get_flag( nFlags, EXC_WIN2_DEFGRIDCOLOR );
+ maData.mbShowFormulas = !bChart && ::get_flag( nFlags, EXC_WIN2_SHOWFORMULAS );
+ maData.mbShowGrid = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWGRID );
+ maData.mbShowHeadings = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWHEADINGS );
+ maData.mbShowZeros = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWZEROS );
+ maData.mbShowOutline = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWOUTLINE );
+
+ switch( GetBiff() )
+ {
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ rStrm >> maData.maGridColor;
+ break;
+ case EXC_BIFF8:
+ {
+ sal_uInt16 nGridColorIdx;
+ rStrm >> nGridColorIdx;
+ // zoom data not included in chart sheets
+ if( rStrm.GetRecLeft() >= 6 )
+ {
+ rStrm.Ignore( 2 );
+ rStrm >> maData.mnPageZoom >> maData.mnNormalZoom;
+ }
+
+ if( !maData.mbDefGridColor )
+ maData.maGridColor = GetPalette().GetColor( nGridColorIdx );
+ }
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+ }
+
+ // do not scroll chart sheets
+ if( bChart )
+ maData.maFirstXclPos.Set( 0, 0 );
+}
+
+void XclImpTabViewSettings::ReadScl( XclImpStream& rStrm )
+{
+ sal_uInt16 nNum, nDenom;
+ rStrm >> nNum >> nDenom;
+ DBG_ASSERT( nDenom > 0, "XclImpPageSettings::ReadScl - invalid denominator" );
+ if( nDenom > 0 )
+ maData.mnCurrentZoom = limit_cast< sal_uInt16 >( (nNum * 100) / nDenom );
+}
+
+void XclImpTabViewSettings::ReadPane( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnSplitX
+ >> maData.mnSplitY
+ >> maData.maSecondXclPos
+ >> maData.mnActivePane;
+}
+
+void XclImpTabViewSettings::ReadSelection( XclImpStream& rStrm )
+{
+ // pane of this selection
+ sal_uInt8 nPane;
+ rStrm >> nPane;
+ XclSelectionData& rSelData = maData.CreateSelectionData( nPane );
+ // cursor position and selection
+ rStrm >> rSelData.maXclCursor >> rSelData.mnCursorIdx;
+ rSelData.maXclSelection.Read( rStrm, false );
+}
+
+void XclImpTabViewSettings::Finalize()
+{
+ SCTAB nScTab = GetCurrScTab();
+ ScDocument& rDoc = GetDoc();
+ XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ ScExtTabSettings& rTabSett = GetExtDocOptions().GetOrCreateTabSettings( nScTab );
+ bool bDisplayed = GetDocViewSettings().GetDisplScTab() == nScTab;
+
+ // *** sheet options: cursor, selection, splits, zoom ***
+
+ // sheet flags
+ if( maData.mbMirrored )
+ // do not call this function with FALSE, it would mirror away all drawing objects
+ rDoc.SetLayoutRTL( nScTab, TRUE );
+ rTabSett.mbSelected = maData.mbSelected || bDisplayed;
+
+ // first visible cell in top-left pane and in additional pane(s)
+ rTabSett.maFirstVis = rAddrConv.CreateValidAddress( maData.maFirstXclPos, nScTab, false );
+ rTabSett.maSecondVis = rAddrConv.CreateValidAddress( maData.maSecondXclPos, nScTab, false );
+
+ // cursor position and selection
+ if( const XclSelectionData* pSelData = maData.GetSelectionData( maData.mnActivePane ) )
+ {
+ rTabSett.maCursor = rAddrConv.CreateValidAddress( pSelData->maXclCursor, nScTab, false );
+ rAddrConv.ConvertRangeList( rTabSett.maSelection, pSelData->maXclSelection, nScTab, false );
+ }
+
+ // active pane
+ switch( maData.mnActivePane )
+ {
+ case EXC_PANE_TOPLEFT: rTabSett.meActivePane = SCEXT_PANE_TOPLEFT; break;
+ case EXC_PANE_TOPRIGHT: rTabSett.meActivePane = SCEXT_PANE_TOPRIGHT; break;
+ case EXC_PANE_BOTTOMLEFT: rTabSett.meActivePane = SCEXT_PANE_BOTTOMLEFT; break;
+ case EXC_PANE_BOTTOMRIGHT: rTabSett.meActivePane = SCEXT_PANE_BOTTOMRIGHT; break;
+ }
+
+ // freeze/split position
+ rTabSett.mbFrozenPanes = maData.mbFrozenPanes;
+ if( maData.mbFrozenPanes )
+ {
+ /* Frozen panes: handle split position as row/column positions.
+ #i35812# Excel uses number of visible rows/columns, Calc uses position of freeze. */
+ if( (maData.mnSplitX > 0) && (maData.maFirstXclPos.mnCol + maData.mnSplitX <= GetScMaxPos().Col()) )
+ rTabSett.maFreezePos.SetCol( static_cast< SCCOL >( maData.maFirstXclPos.mnCol + maData.mnSplitX ) );
+ if( (maData.mnSplitY > 0) && (maData.maFirstXclPos.mnRow + maData.mnSplitY <= GetScMaxPos().Row()) )
+ rTabSett.maFreezePos.SetRow( static_cast< SCROW >( maData.maFirstXclPos.mnRow + maData.mnSplitY ) );
+ }
+ else
+ {
+ // split window: position is in twips
+ rTabSett.maSplitPos.X() = static_cast< long >( maData.mnSplitX );
+ rTabSett.maSplitPos.Y() = static_cast< long >( maData.mnSplitY );
+ }
+
+ // grid color
+ if( maData.mbDefGridColor )
+ rTabSett.maGridColor.SetColor( COL_AUTO );
+ else
+ rTabSett.maGridColor = maData.maGridColor;
+
+ // view mode and zoom
+ if( maData.mnCurrentZoom != 0 )
+ (maData.mbPageMode ? maData.mnPageZoom : maData.mnNormalZoom) = maData.mnCurrentZoom;
+ rTabSett.mbPageMode = maData.mbPageMode;
+ rTabSett.mnNormalZoom = lclGetScZoom( maData.mnNormalZoom, EXC_WIN2_NORMALZOOM_DEF );
+ rTabSett.mnPageZoom = lclGetScZoom( maData.mnPageZoom, EXC_WIN2_PAGEZOOM_DEF );
+
+ // *** additional handling for displayed sheet ***
+
+ if( bDisplayed )
+ {
+ // set Excel sheet settings globally at Calc document, take settings from displayed sheet
+ ScViewOptions aViewOpt( rDoc.GetViewOptions() );
+ aViewOpt.SetOption( VOPT_FORMULAS, maData.mbShowFormulas );
+ aViewOpt.SetOption( VOPT_GRID, maData.mbShowGrid );
+ aViewOpt.SetOption( VOPT_HEADER, maData.mbShowHeadings );
+ aViewOpt.SetOption( VOPT_NULLVALS, maData.mbShowZeros );
+ aViewOpt.SetOption( VOPT_OUTLINER, maData.mbShowOutline );
+ rDoc.SetViewOptions( aViewOpt );
+ }
+
+ // *** set tab bg color
+ if ( !maData.IsDefaultTabBgColor() )
+ rDoc.SetTabBgColor(nScTab, maData.maTabBgColor);
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xladdress.cxx b/sc/source/filter/excel/xladdress.cxx
new file mode 100644
index 000000000000..d0c1a925f8ab
--- /dev/null
+++ b/sc/source/filter/excel/xladdress.cxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xladdress.hxx"
+#include "xestream.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+
+// ============================================================================
+
+void XclAddress::Read( XclImpStream& rStrm, bool bCol16Bit )
+{
+ rStrm >> mnRow;
+ if( bCol16Bit )
+ rStrm >> mnCol;
+ else
+ mnCol = rStrm.ReaduInt8();
+}
+
+void XclAddress::Write( XclExpStream& rStrm, bool bCol16Bit ) const
+{
+ rStrm << mnRow;
+ if( bCol16Bit )
+ rStrm << mnCol;
+ else
+ rStrm << static_cast< sal_uInt8 >( mnCol );
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclRange::Contains( const XclAddress& rPos ) const
+{
+ return (maFirst.mnCol <= rPos.mnCol) && (rPos.mnCol <= maLast.mnCol) &&
+ (maFirst.mnRow <= rPos.mnRow) && (rPos.mnRow <= maLast.mnRow);
+}
+
+void XclRange::Read( XclImpStream& rStrm, bool bCol16Bit )
+{
+ rStrm >> maFirst.mnRow >> maLast.mnRow;
+ if( bCol16Bit )
+ rStrm >> maFirst.mnCol >> maLast.mnCol;
+ else
+ {
+ maFirst.mnCol = rStrm.ReaduInt8();
+ maLast.mnCol = rStrm.ReaduInt8();
+ }
+}
+
+void XclRange::Write( XclExpStream& rStrm, bool bCol16Bit ) const
+{
+ rStrm << maFirst.mnRow << maLast.mnRow;
+ if( bCol16Bit )
+ rStrm << maFirst.mnCol << maLast.mnCol;
+ else
+ rStrm << static_cast< sal_uInt8 >( maFirst.mnCol ) << static_cast< sal_uInt8 >( maLast.mnCol );
+}
+
+// ----------------------------------------------------------------------------
+
+XclRange XclRangeList::GetEnclosingRange() const
+{
+ XclRange aXclRange;
+ if( !empty() )
+ {
+ const_iterator aIt = begin(), aEnd = end();
+ aXclRange = *aIt;
+ for( ++aIt; aIt != aEnd; ++aIt )
+ {
+ aXclRange.maFirst.mnCol = ::std::min( aXclRange.maFirst.mnCol, aIt->maFirst.mnCol );
+ aXclRange.maFirst.mnRow = ::std::min( aXclRange.maFirst.mnRow, aIt->maFirst.mnRow );
+ aXclRange.maLast.mnCol = ::std::max( aXclRange.maLast.mnCol, aIt->maLast.mnCol );
+ aXclRange.maLast.mnRow = ::std::max( aXclRange.maLast.mnRow, aIt->maLast.mnRow );
+ }
+ }
+ return aXclRange;
+}
+
+void XclRangeList::Read( XclImpStream& rStrm, bool bCol16Bit )
+{
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ size_t nOldSize = size();
+ resize( nOldSize + nCount );
+ for( iterator aIt = begin() + nOldSize; rStrm.IsValid() && (nCount > 0); --nCount, ++aIt )
+ aIt->Read( rStrm, bCol16Bit );
+}
+
+void XclRangeList::Write( XclExpStream& rStrm, bool bCol16Bit ) const
+{
+ WriteSubList( rStrm, 0, size(), bCol16Bit );
+}
+
+void XclRangeList::WriteSubList( XclExpStream& rStrm, size_t nBegin, size_t nCount, bool bCol16Bit ) const
+{
+ DBG_ASSERT( nBegin <= size(), "XclRangeList::WriteSubList - invalid start position" );
+ size_t nEnd = ::std::min< size_t >( nBegin + nCount, size() );
+ sal_uInt16 nXclCount = ulimit_cast< sal_uInt16 >( nEnd - nBegin );
+ rStrm << nXclCount;
+ rStrm.SetSliceSize( bCol16Bit ? 8 : 6 );
+ for( const_iterator aIt = begin() + nBegin, aEnd = begin() + nEnd; aIt != aEnd; ++aIt )
+ aIt->Write( rStrm, bCol16Bit );
+}
+
+// ============================================================================
+
+XclAddressConverterBase::XclAddressConverterBase( XclTracer& rTracer, const ScAddress& rMaxPos ) :
+ mrTracer( rTracer ),
+ maMaxPos( rMaxPos ),
+ mnMaxCol( static_cast< sal_uInt16 >( rMaxPos.Col() ) ),
+ mnMaxRow( static_cast< sal_uInt16 >( rMaxPos.Row() ) ),
+ mbColTrunc( false ),
+ mbRowTrunc( false ),
+ mbTabTrunc( false )
+{
+ DBG_ASSERT( static_cast< size_t >( rMaxPos.Col() ) <= SAL_MAX_UINT16, "XclAddressConverterBase::XclAddressConverterBase - invalid max column" );
+ DBG_ASSERT( static_cast< size_t >( rMaxPos.Row() ) <= SAL_MAX_UINT16, "XclAddressConverterBase::XclAddressConverterBase - invalid max row" );
+}
+
+XclAddressConverterBase::~XclAddressConverterBase()
+{
+}
+
+bool XclAddressConverterBase::CheckScTab( SCTAB nScTab, bool bWarn )
+{
+ bool bValid = (0 <= nScTab) && (nScTab <= maMaxPos.Tab());
+ if( !bValid && bWarn )
+ {
+ mbTabTrunc |= (nScTab > maMaxPos.Tab()); // do not warn for deleted refs
+ mrTracer.TraceInvalidTab( nScTab, maMaxPos.Tab() );
+ }
+ return bValid;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx
new file mode 100755
index 000000000000..10a0657c7899
--- /dev/null
+++ b/sc/source/filter/excel/xlchart.cxx
@@ -0,0 +1,1328 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xlchart.hxx"
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/XAxisXSupplier.hpp>
+#include <com/sun/star/chart/XAxisYSupplier.hpp>
+#include <com/sun/star/chart/XAxisZSupplier.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
+#include <com/sun/star/chart2/Symbol.hpp>
+
+#include <rtl/math.hxx>
+#include <svl/itemset.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/unomid.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include <editeng/memberids.hrc>
+#include "global.hxx"
+#include "xlroot.hxx"
+#include "xlstyle.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::drawing::XShape;
+
+namespace cssc = ::com::sun::star::chart;
+
+// Common =====================================================================
+
+XclChRectangle::XclChRectangle() :
+ mnX( 0 ),
+ mnY( 0 ),
+ mnWidth( 0 ),
+ mnHeight( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) :
+ mnSeriesIdx( nSeriesIdx ),
+ mnPointIdx( nPointIdx )
+{
+}
+
+bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR )
+{
+ return (rL.mnSeriesIdx < rR.mnSeriesIdx) ||
+ ((rL.mnSeriesIdx == rR.mnSeriesIdx) && (rL.mnPointIdx < rR.mnPointIdx));
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) :
+ mnType( nType ),
+ mnContext( 0 ),
+ mnValue1( 0 ),
+ mnValue2( 0 )
+{
+}
+
+// Frame formatting ===========================================================
+
+XclChFramePos::XclChFramePos() :
+ mnTLMode( EXC_CHFRAMEPOS_PARENT ),
+ mnBRMode( EXC_CHFRAMEPOS_PARENT )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChLineFormat::XclChLineFormat() :
+ maColor( COL_BLACK ),
+ mnPattern( EXC_CHLINEFORMAT_SOLID ),
+ mnWeight( EXC_CHLINEFORMAT_SINGLE ),
+ mnFlags( EXC_CHLINEFORMAT_AUTO )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChAreaFormat::XclChAreaFormat() :
+ maPattColor( COL_WHITE ),
+ maBackColor( COL_BLACK ),
+ mnPattern( EXC_PATT_SOLID ),
+ mnFlags( EXC_CHAREAFORMAT_AUTO )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChEscherFormat::XclChEscherFormat()
+{
+}
+
+XclChEscherFormat::~XclChEscherFormat()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChPicFormat::XclChPicFormat() :
+ mnBmpMode( EXC_CHPICFORMAT_NONE ),
+ mnFormat( EXC_CHPICFORMAT_DEFAULT ),
+ mnFlags( EXC_CHPICFORMAT_DEFAULTFLAGS ),
+ mfScale( 0.5 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFrame::XclChFrame() :
+ mnFormat( EXC_CHFRAME_STANDARD ),
+ mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS )
+{
+}
+
+// Source links ===============================================================
+
+XclChSourceLink::XclChSourceLink() :
+ mnDestType( EXC_CHSRCLINK_TITLE ),
+ mnLinkType( EXC_CHSRCLINK_DEFAULT ),
+ mnFlags( 0 ),
+ mnNumFmtIdx( 0 )
+{
+}
+
+// Text =======================================================================
+
+XclChObjectLink::XclChObjectLink() :
+ mnTarget( EXC_CHOBJLINK_NONE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFrLabelProps::XclChFrLabelProps() :
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChText::XclChText() :
+ maTextColor( COL_BLACK ),
+ mnHAlign( EXC_CHTEXT_ALIGN_CENTER ),
+ mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
+ mnBackMode( EXC_CHTEXT_TRANSPARENT ),
+ mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
+ mnFlags2( EXC_CHTEXT_POS_DEFAULT ),
+ mnRotation( EXC_ROT_NONE )
+{
+}
+
+// Data series ================================================================
+
+XclChMarkerFormat::XclChMarkerFormat() :
+ maLineColor( COL_BLACK ),
+ maFillColor( COL_WHITE ),
+ mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ),
+ mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ),
+ mnFlags( EXC_CHMARKERFORMAT_AUTO )
+{
+};
+
+// ----------------------------------------------------------------------------
+
+XclCh3dDataFormat::XclCh3dDataFormat() :
+ mnBase( EXC_CH3DDATAFORMAT_RECT ),
+ mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChDataFormat::XclChDataFormat() :
+ mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChSerTrendLine::XclChSerTrendLine() :
+ mfForecastFor( 0.0 ),
+ mfForecastBack( 0.0 ),
+ mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
+ mnOrder( 1 ),
+ mnShowEquation( 0 ),
+ mnShowRSquared( 0 )
+{
+ /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
+ there is no interception point. Cannot use ::rtl::math::setNan() here
+ cause it misses the sign bit. */
+ sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept );
+ pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF;
+}
+
+// ----------------------------------------------------------------------------
+
+XclChSerErrorBar::XclChSerErrorBar() :
+ mfValue( 0.0 ),
+ mnValueCount( 1 ),
+ mnBarType( EXC_CHSERERR_NONE ),
+ mnSourceType( EXC_CHSERERR_FIXED ),
+ mnLineEnd( EXC_CHSERERR_END_TSHAPE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChSeries::XclChSeries() :
+ mnCategType( EXC_CHSERIES_NUMERIC ),
+ mnValueType( EXC_CHSERIES_NUMERIC ),
+ mnBubbleType( EXC_CHSERIES_NUMERIC ),
+ mnCategCount( 0 ),
+ mnValueCount( 0 ),
+ mnBubbleCount( 0 )
+{
+}
+
+// Chart type groups ==========================================================
+
+XclChType::XclChType() :
+ mnOverlap( 0 ),
+ mnGap( 150 ),
+ mnRotation( 0 ),
+ mnPieHole( 0 ),
+ mnBubbleSize( 100 ),
+ mnBubbleType( EXC_CHSCATTER_AREA ),
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChChart3d::XclChChart3d() :
+ mnRotation( 20 ),
+ mnElevation( 15 ),
+ mnEyeDist( 30 ),
+ mnRelHeight( 100 ),
+ mnRelDepth( 100 ),
+ mnDepthGap( 150 ),
+ mnFlags( EXC_CHCHART3D_AUTOHEIGHT )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChLegend::XclChLegend() :
+ mnDockMode( EXC_CHLEGEND_RIGHT ),
+ mnSpacing( EXC_CHLEGEND_MEDIUM ),
+ mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES |
+ EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChTypeGroup::XclChTypeGroup() :
+ mnFlags( 0 ),
+ mnGroupIdx( EXC_CHSERGROUP_NONE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChProperties::XclChProperties() :
+ mnFlags( 0 ),
+ mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
+{
+}
+
+// Axes =======================================================================
+
+XclChLabelRange::XclChLabelRange() :
+ mnCross( 1 ),
+ mnLabelFreq( 1 ),
+ mnTickFreq( 1 ),
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChValueRange::XclChValueRange() :
+ mfMin( 0.0 ),
+ mfMax( 0.0 ),
+ mfMajorStep( 0.0 ),
+ mfMinorStep( 0.0 ),
+ mfCross( 0.0 ),
+ mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX |
+ EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR | EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChTick::XclChTick() :
+ maTextColor( COL_BLACK ),
+ mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ),
+ mnMinor( 0 ),
+ mnLabelPos( EXC_CHTICK_NEXT ),
+ mnBackMode( EXC_CHTICK_TRANSPARENT ),
+ mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ),
+ mnRotation( EXC_ROT_NONE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChAxis::XclChAxis() :
+ mnType( EXC_CHAXIS_NONE )
+{
+}
+
+sal_Int32 XclChAxis::GetApiAxisDimension() const
+{
+ sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE;
+ switch( mnType )
+ {
+ case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break;
+ case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break;
+ case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break;
+ }
+ return nApiAxisDim;
+}
+
+// ----------------------------------------------------------------------------
+
+XclChAxesSet::XclChAxesSet() :
+ mnAxesSetId( EXC_CHAXESSET_PRIMARY )
+{
+}
+
+sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const
+{
+ sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE;
+ switch( mnAxesSetId )
+ {
+ case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break;
+ case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break;
+ }
+ return nApiAxesSetIdx;
+}
+
+// Static helper functions ====================================================
+
+sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt16 spnLineColors[] =
+ {
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 63
+ };
+ return spnLineColors[ nFormatIdx % STATIC_TABLE_SIZE( spnLineColors ) ];
+}
+
+sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt16 spnFillColors[] =
+ {
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23
+ };
+ return spnFillColors[ nFormatIdx % STATIC_TABLE_SIZE( spnFillColors ) ];
+}
+
+sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
+ return spnTrans[ (nFormatIdx / 56) % STATIC_TABLE_SIZE( spnTrans ) ];
+}
+
+sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt16 spnSymbols[] = {
+ EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE,
+ EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE,
+ EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV };
+ return spnSymbols[ nFormatIdx % STATIC_TABLE_SIZE( spnSymbols ) ];
+}
+
+bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType )
+{
+ static const bool spbFilled[] = {
+ false, true, true, true, false, false, false, false, true, false };
+ return (nMarkerType < STATIC_TABLE_SIZE( spbFilled )) && spbFilled[ nMarkerType ];
+}
+
+OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType )
+{
+ switch( nBarType )
+ {
+ case EXC_CHSERERR_XPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSX;
+ case EXC_CHSERERR_XMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGX;
+ case EXC_CHSERERR_YPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSY;
+ case EXC_CHSERERR_YMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGY;
+ default: DBG_ERRORFILE( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
+ }
+ return OUString();
+}
+
+// Chart formatting info provider =============================================
+
+namespace {
+
+static const XclChFormatInfo spFmtInfos[] =
+{
+ // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
+ { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
+ { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
+ { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true },
+ { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true },
+ { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true },
+ { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true },
+ { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
+ { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true },
+ { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
+ { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false },
+ { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true },
+ { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }
+};
+
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFormatInfoProvider::XclChFormatInfoProvider()
+{
+ const XclChFormatInfo* pEnd = STATIC_TABLE_END( spFmtInfos );
+ for( const XclChFormatInfo* pIt = spFmtInfos; pIt != pEnd; ++pIt )
+ maInfoMap[ pIt->meObjType ] = pIt;
+}
+
+const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const
+{
+ XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType );
+ DBG_ASSERT( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
+ return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second;
+}
+
+// Chart type info provider ===================================================
+
+namespace {
+
+// chart type service names
+const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
+const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
+const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
+const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
+const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
+const sal_Char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
+const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
+const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
+const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
+const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
+
+namespace csscd = cssc::DataLabelPlacement;
+
+static const XclChTypeInfo spTypeInfos[] =
+{
+ // chart type chart type category record id service varied point color def label pos comb2d 3d polar area2d area3d 1stvis xcateg swap stack revers betw
+ { EXC_CHTYPEID_BAR, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, true, true, false, true, true, false, true, false, true, false, true },
+ { EXC_CHTYPEID_HORBAR, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, false, true, false, true, true, false, true, true, true, false, true },
+ { EXC_CHTYPEID_LINE, EXC_CHTYPECATEG_LINE, EXC_ID_CHLINE, SERVICE_CHART2_LINE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, true, false, false, true, false, true, false, true, false, false },
+ { EXC_CHTYPEID_AREA, EXC_CHTYPECATEG_LINE, EXC_ID_CHAREA, SERVICE_CHART2_AREA, EXC_CHVARPOINT_NONE, csscd::CENTER, true, true, false, true, true, false, true, false, true, true, false },
+ { EXC_CHTYPEID_STOCK, EXC_CHTYPECATEG_LINE, EXC_ID_CHLINE, SERVICE_CHART2_CANDLE, EXC_CHVARPOINT_NONE, csscd::RIGHT, true, false, false, false, false, false, true, false, true, false, false },
+ { EXC_CHTYPEID_RADARLINE, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARLINE, SERVICE_CHART2_NET, EXC_CHVARPOINT_SINGLE, csscd::TOP, false, false, true, false, true, false, true, false, false, false, false },
+ { EXC_CHTYPEID_RADARAREA, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARAREA, SERVICE_CHART2_FILLEDNET, EXC_CHVARPOINT_NONE, csscd::TOP, false, false, true, true, true, false, true, false, false, true, false },
+ { EXC_CHTYPEID_PIE, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, true, true, false, false, false, false },
+ { EXC_CHTYPEID_DONUT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, false, true, false, false, true, false },
+ { EXC_CHTYPEID_PIEEXT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIEEXT, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, false, true, true, true, true, true, false, false, false, false },
+ { EXC_CHTYPEID_SCATTER, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_SCATTER, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, false, false, false, true, false, false, false, false, false, false },
+ { EXC_CHTYPEID_BUBBLES, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_BUBBLE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, false, false, false, true, true, false, false, false, false, false, false },
+ { EXC_CHTYPEID_SURFACE, EXC_CHTYPECATEG_SURFACE, EXC_ID_CHSURFACE, SERVICE_CHART2_SURFACE, EXC_CHVARPOINT_NONE, csscd::RIGHT, false, true, false, true, true, false, true, false, false, false, false },
+ { EXC_CHTYPEID_UNKNOWN, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, true, true, false, true, true, false, true, false, true, false, true }
+};
+
+} // namespace
+
+XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
+ XclChTypeInfo( rTypeInfo ),
+ mb3dChart( false ),
+ mbSpline( false )
+{
+}
+
+void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
+{
+ static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
+ mb3dChart = mbSupports3d && b3dChart;
+ mbSpline = bSpline;
+}
+
+// ----------------------------------------------------------------------------
+
+XclChTypeInfoProvider::XclChTypeInfoProvider()
+{
+ const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
+ for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ maInfoMap[ pIt->meTypeId ] = pIt;
+}
+
+const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const
+{
+ XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId );
+ DBG_ASSERT( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
+ return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second;
+}
+
+const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const
+{
+ const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
+ for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ if( pIt->mnRecId == nRecId )
+ return *pIt;
+ DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
+ return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
+}
+
+const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const
+{
+ const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
+ for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ if( rServiceName.equalsAscii( pIt->mpcServiceName ) )
+ return *pIt;
+ DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
+ return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
+}
+
+// Property helpers ===========================================================
+
+XclChObjectTable::XclChObjectTable( Reference< XMultiServiceFactory > xFactory,
+ const OUString& rServiceName, const OUString& rObjNameBase ) :
+ mxFactory( xFactory ),
+ maServiceName( rServiceName ),
+ maObjNameBase( rObjNameBase ),
+ mnIndex( 0 )
+{
+}
+
+Any XclChObjectTable::GetObject( const OUString& rObjName )
+{
+ // get object table
+ if( !mxContainer.is() )
+ mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
+ DBG_ASSERT( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
+
+ Any aObj;
+ if( mxContainer.is() )
+ {
+ // get object from container
+ try
+ {
+ aObj = mxContainer->getByName( rObjName );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclChObjectTable::GetObject - object not found" );
+ }
+ }
+ return aObj;
+}
+
+OUString XclChObjectTable::InsertObject( const Any& rObj )
+{
+
+ // create object table
+ if( !mxContainer.is() )
+ mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
+ DBG_ASSERT( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" );
+
+ OUString aObjName;
+ if( mxContainer.is() )
+ {
+ // create new unused identifier
+ do
+ {
+ aObjName = maObjNameBase + OUString::valueOf( ++mnIndex );
+ }
+ while( mxContainer->hasByName( aObjName ) );
+
+ // insert object
+ try
+ {
+ mxContainer->insertByName( aObjName, rObj );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclChObjectTable::InsertObject - cannot insert object" );
+ aObjName = OUString();
+ }
+ }
+ return aObjName;
+}
+
+// Property names -------------------------------------------------------------
+
+namespace {
+
+/** Property names for line style in common objects. */
+const sal_Char* const sppcLineNamesCommon[] =
+ { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
+/** Property names for line style in linear series objects. */
+const sal_Char* const sppcLineNamesLinear[] =
+ { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
+/** Property names for line style in filled series objects. */
+const sal_Char* const sppcLineNamesFilled[] =
+ { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
+
+/** Property names for solid area style in common objects. */
+const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
+/** Property names for solid area style in filled series objects. */
+const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", 0 };
+/** Property names for gradient area style in common objects. */
+const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", 0 };
+/** Property names for gradient area style in filled series objects. */
+const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", 0 };
+/** Property names for hatch area style in common objects. */
+const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
+/** Property names for hatch area style in filled series objects. */
+const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
+/** Property names for bitmap area style. */
+const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclChPropSetHelper::XclChPropSetHelper() :
+ maLineHlpCommon( sppcLineNamesCommon ),
+ maLineHlpLinear( sppcLineNamesLinear ),
+ maLineHlpFilled( sppcLineNamesFilled ),
+ maAreaHlpCommon( sppcAreaNamesCommon ),
+ maAreaHlpFilled( sppcAreaNamesFilled ),
+ maGradHlpCommon( sppcGradNamesCommon ),
+ maGradHlpFilled( sppcGradNamesFilled ),
+ maHatchHlpCommon( sppcHatchNamesCommon ),
+ maHatchHlpFilled( sppcHatchNamesFilled ),
+ maBitmapHlp( sppcBitmapNames )
+{
+}
+
+// read properties ------------------------------------------------------------
+
+void XclChPropSetHelper::ReadLineProperties(
+ XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+ // read properties from property set
+ cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
+ sal_Int32 nApiWidth = 0;
+ sal_Int16 nApiTrans = 0;
+ Any aDashNameAny;
+
+ ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
+ rLineHlp.ReadFromPropertySet( rPropSet );
+ rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny;
+
+ // clear automatic flag
+ ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
+
+ // line width
+ if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
+ else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;
+ else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;
+ else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;
+
+ // line style
+ switch( eApiStyle )
+ {
+ case cssd::LineStyle_NONE:
+ rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
+ break;
+ case cssd::LineStyle_SOLID:
+ {
+ if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;
+ else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;
+ else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;
+ else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
+ }
+ break;
+ case cssd::LineStyle_DASH:
+ {
+ rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ OUString aDashName;
+ cssd::LineDash aApiDash;
+ if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) )
+ {
+ // reorder dashes that are shorter than dots
+ if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) )
+ {
+ ::std::swap( aApiDash.Dashes, aApiDash.Dots );
+ ::std::swap( aApiDash.DashLen, aApiDash.DotLen );
+ }
+ // ignore dots that are nearly equal to dashes
+ if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 )
+ aApiDash.Dots = 0;
+
+ // convert line dash to predefined Excel dash types
+ if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) )
+ // one dash and one or more dots
+ rLineFmt.mnPattern = (aApiDash.Dots == 1) ?
+ EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT;
+ else if( aApiDash.Dashes >= 1 )
+ // one or more dashes and no dots (also: dash-dash-dot)
+ rLineFmt.mnPattern = (aApiDash.DashLen < 250) ?
+ EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH;
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
+ rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ }
+}
+
+bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+ // read properties from property set
+ cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
+ sal_Int16 nTransparency = 0;
+
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.ReadFromPropertySet( rPropSet );
+ rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency;
+
+ // clear automatic flag
+ ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
+
+ // set fill style transparent or solid (set solid for anything but transparent)
+ rAreaFmt.mnPattern = (eApiStyle == cssd::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID;
+
+ // return true to indicate complex fill (gradient, bitmap, solid transparency)
+ return (eApiStyle != cssd::FillStyle_NONE) && ((eApiStyle != cssd::FillStyle_SOLID) || (nTransparency > 0));
+}
+
+void XclChPropSetHelper::ReadEscherProperties(
+ XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
+ XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+ namespace cssa = ::com::sun::star::awt;
+
+ // read style and transparency properties from property set
+ cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
+ Color aColor;
+ sal_Int16 nTransparency = 0;
+
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.ReadFromPropertySet( rPropSet );
+ rAreaHlp >> eApiStyle >> aColor >> nTransparency;
+
+ switch( eApiStyle )
+ {
+ case cssd::FillStyle_SOLID:
+ {
+ DBG_ASSERT( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
+ if( (0 < nTransparency) && (nTransparency <= 100) )
+ {
+ // convert to Escher properties
+ sal_uInt32 nEscherColor = 0x02000000;
+ ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 );
+ ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 );
+ ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 );
+ sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 );
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C );
+ }
+ }
+ break;
+ case cssd::FillStyle_GRADIENT:
+ {
+ // extract gradient from global gradient table
+ OUString aGradientName;
+ ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
+ rGradHlp.ReadFromPropertySet( rPropSet );
+ rGradHlp >> eApiStyle >> aGradientName;
+ cssa::Gradient aGradient;
+ if( rGradientTable.GetObject( aGradientName ) >>= aGradient )
+ {
+ // convert to Escher properties
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient );
+ }
+ }
+ break;
+ case cssd::FillStyle_HATCH:
+ {
+ // extract hatch from global hatch table
+ OUString aHatchName;
+ bool bFillBackground;
+ ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
+ rHatchHlp.ReadFromPropertySet( rPropSet );
+ rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
+ cssd::Hatch aHatch;
+ if( rHatchTable.GetObject( aHatchName ) >>= aHatch )
+ {
+ // convert to Escher properties
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground );
+ rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK;
+ }
+ }
+ break;
+ case cssd::FillStyle_BITMAP:
+ {
+ // extract bitmap URL from global bitmap table
+ OUString aBitmapName;
+ cssd::BitmapMode eApiBmpMode;
+ maBitmapHlp.ReadFromPropertySet( rPropSet );
+ maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode;
+ OUString aBitmapUrl;
+ if( rBitmapTable.GetObject( aBitmapName ) >>= aBitmapUrl )
+ {
+ // convert to Escher properties
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( aBitmapUrl, eApiBmpMode );
+ rPicFmt.mnBmpMode = (eApiBmpMode == cssd::BitmapMode_REPEAT) ?
+ EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH;
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
+ }
+}
+
+void XclChPropSetHelper::ReadMarkerProperties(
+ XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
+{
+ namespace cssc = ::com::sun::star::chart2;
+ namespace cssa = ::com::sun::star::awt;
+ cssc::Symbol aApiSymbol;
+ if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) )
+ {
+ // clear automatic flag
+ ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
+
+ // symbol style
+ switch( aApiSymbol.Style )
+ {
+ case cssc::SymbolStyle_NONE:
+ rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
+ break;
+ case cssc::SymbolStyle_STANDARD:
+ switch( aApiSymbol.StandardSymbol )
+ {
+ case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square
+ case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond
+ case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down
+ case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up
+ case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // arrow right
+ case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left
+ case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie
+ case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass
+ default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
+ }
+ break;
+ default:
+ rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
+ }
+ bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
+ ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
+
+ // symbol size
+ sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
+ rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
+
+ // symbol colors
+ rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor );
+ rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor );
+ }
+}
+
+sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked )
+{
+ // chart2 handles rotation as double in the range [0,360)
+ double fAngle = 0.0;
+ rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION );
+ bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS );
+ return bStacked ? EXC_ROT_STACKED :
+ XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
+}
+
+// write properties -----------------------------------------------------------
+
+void XclChPropSetHelper::WriteLineProperties(
+ ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
+ const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+ // line width
+ sal_Int32 nApiWidth = 0; // 0 is the width of a hair line
+ switch( rLineFmt.mnWeight )
+ {
+ case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break;
+ case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break;
+ case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break;
+ }
+
+ // line style
+ cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
+ sal_Int16 nApiTrans = 0;
+ sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
+ cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
+
+ switch( rLineFmt.mnPattern )
+ {
+ case EXC_CHLINEFORMAT_SOLID:
+ eApiStyle = cssd::LineStyle_SOLID;
+ break;
+ case EXC_CHLINEFORMAT_DARKTRANS:
+ eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
+ break;
+ case EXC_CHLINEFORMAT_MEDTRANS:
+ eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
+ break;
+ case EXC_CHLINEFORMAT_LIGHTTRANS:
+ eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
+ break;
+ case EXC_CHLINEFORMAT_DASH:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
+ break;
+ case EXC_CHLINEFORMAT_DOT:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
+ break;
+ case EXC_CHLINEFORMAT_DASHDOT:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
+ break;
+ case EXC_CHLINEFORMAT_DASHDOTDOT:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
+ break;
+ }
+
+ // line color
+ sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
+
+ // try to insert the dash style and receive its name
+ Any aDashNameAny;
+ if( eApiStyle == cssd::LineStyle_DASH )
+ {
+ OUString aDashName = rDashTable.InsertObject( ::com::sun::star::uno::makeAny( aApiDash ) );
+ if( aDashName.getLength() )
+ aDashNameAny <<= aDashName;
+ }
+
+ // write the properties
+ ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
+ rLineHlp.InitializeWrite();
+ rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
+ rLineHlp.WriteToPropertySet( rPropSet );
+}
+
+void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+ cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
+ Color aColor;
+ sal_Int16 nTransparency = 0;
+
+ // fill color
+ if( rAreaFmt.mnPattern != EXC_PATT_NONE )
+ {
+ eFillStyle = cssd::FillStyle_SOLID;
+ aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
+ }
+
+ // write the properties
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.InitializeWrite();
+ rAreaHlp << eFillStyle << aColor << nTransparency;
+ rAreaHlp.WriteToPropertySet( rPropSet );
+}
+
+void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
+ XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable,
+ const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode )
+{
+ if( rEscherFmt.mxItemSet.is() )
+ {
+ if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, FALSE ) ) )
+ {
+ switch( pStyleItem->GetValue() )
+ {
+ case XFILL_SOLID:
+ // #i84812# Excel 2007 writes Escher properties for solid fill
+ if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, FALSE ) ) )
+ {
+ namespace cssd = ::com::sun::star::drawing;
+ // get solid transparence too
+ const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, FALSE ) );
+ sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.InitializeWrite();
+ rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
+ rAreaHlp.WriteToPropertySet( rPropSet );
+ }
+ break;
+ case XFILL_GRADIENT:
+ if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, FALSE ) ) )
+ {
+ Any aGradientAny;
+ if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
+ {
+ OUString aGradName = rGradientTable.InsertObject( aGradientAny );
+ if( aGradName.getLength() )
+ {
+ namespace cssd = ::com::sun::star::drawing;
+ ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
+ rGradHlp.InitializeWrite();
+ rGradHlp << cssd::FillStyle_GRADIENT << aGradName;
+ rGradHlp.WriteToPropertySet( rPropSet );
+ }
+ }
+ }
+ break;
+ case XFILL_BITMAP:
+ if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, FALSE ) ) )
+ {
+ Any aBitmapAny;
+ if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) )
+ {
+ OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
+ if( aBmpName.getLength() )
+ {
+ namespace cssd = ::com::sun::star::drawing;
+ cssd::BitmapMode eApiBmpMode = (rPicFmt.mnBmpMode == EXC_CHPICFORMAT_STRETCH) ?
+ cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT;
+ maBitmapHlp.InitializeWrite();
+ maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode;
+ maBitmapHlp.WriteToPropertySet( rPropSet );
+ }
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
+ }
+ }
+ }
+}
+
+void XclChPropSetHelper::WriteMarkerProperties(
+ ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
+{
+ namespace cssc = ::com::sun::star::chart2;
+ namespace cssa = ::com::sun::star::awt;
+
+ // symbol style
+ cssc::Symbol aApiSymbol;
+ aApiSymbol.Style = cssc::SymbolStyle_STANDARD;
+ switch( rMarkerFmt.mnMarkerType )
+ {
+ case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = cssc::SymbolStyle_NONE; break;
+ case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square
+ case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond
+ case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up
+ case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 6; break; // bow tie
+ case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 7; break; // sand glass
+ case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right
+ case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 2; break; // arrow down
+ case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 4; break; // arrow right
+ case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 5; break; // arrow left
+ }
+
+ // symbol size
+ sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
+ aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
+
+ // symbol colors
+ aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
+ aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
+ aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
+
+ // set the property
+ rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
+}
+
+void XclChPropSetHelper::WriteRotationProperties(
+ ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked )
+{
+ if( nRotation != EXC_CHART_AUTOROTATION )
+ {
+ // chart2 handles rotation as double in the range [0,360)
+ double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
+ rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle );
+ if( bSupportsStacked )
+ rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maLineHlpCommon;
+ case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
+ }
+ return maLineHlpCommon;
+}
+
+ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
+ }
+ return maAreaHlpCommon;
+}
+
+ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maGradHlpCommon;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
+ }
+ return maGradHlpCommon;
+}
+
+ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
+ }
+ return maHatchHlpCommon;
+}
+
+// ============================================================================
+
+namespace {
+
+/* The following local functions implement getting the XShape interface of all
+ supported title objects (chart and axes). This needs some effort due to the
+ design of the old Chart1 API used to access these objects. */
+
+/** A code fragment that returns a shape object from the passed shape supplier
+ using the specified interface function. Checks a boolean property first. */
+#define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
+ ScfPropertySet aPropSet( shape_supplier ); \
+ if( shape_supplier.is() && aPropSet.GetBoolProperty( CREATE_OUSTRING( #property_name ) ) ) \
+ return shape_supplier->supplier_func(); \
+ return Reference< XShape >(); \
+
+/** Implements a function returning the drawing shape of an axis title, if
+ existing, using the specified API interface and its function. */
+#define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
+Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
+{ \
+ Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
+ EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
+}
+
+/** Returns the drawing shape of the main title, if existing. */
+Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
+{
+ EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
+}
+
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
+
+#undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
+#undef EXC_IMPLEMENT_GETTITLESHAPE
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclChRootData::XclChRootData() :
+ mxTypeInfoProv( new XclChTypeInfoProvider ),
+ mxFmtInfoProv( new XclChFormatInfoProvider ),
+ mnBorderGapX( 0 ),
+ mnBorderGapY( 0 )
+{
+ // remember some title shape getter functions
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
+}
+
+XclChRootData::~XclChRootData()
+{
+}
+
+void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect )
+{
+ // remember chart document reference and chart shape position/size
+ DBG_ASSERT( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
+ mxChartDoc = rxChartDoc;
+ maChartRect = rChartRect;
+
+ // Excel excludes a border of 5 pixels in each direction from chart area
+ mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
+ mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
+
+ // size of a chart unit in 1/100 mm
+ mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
+ mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
+
+ // create object tables
+ Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
+ mxLineDashTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_DASHTABLE, CREATE_OUSTRING( "Excel line dash " ) ) );
+ mxGradientTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_GRADIENTTABLE, CREATE_OUSTRING( "Excel gradient " ) ) );
+ mxHatchTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_HATCHTABLE, CREATE_OUSTRING( "Excel hatch " ) ) );
+ mxBitmapTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_BITMAPTABLE, CREATE_OUSTRING( "Excel bitmap " ) ) );
+}
+
+void XclChRootData::FinishConversion()
+{
+ // forget formatting object tables
+ mxBitmapTable.reset();
+ mxHatchTable.reset();
+ mxGradientTable.reset();
+ mxLineDashTable.reset();
+ // forget chart document reference
+ mxChartDoc.clear();
+}
+
+Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const
+{
+ XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
+ OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
+ Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY );
+ Reference< XShape > xTitleShape;
+ if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) )
+ xTitleShape = (aIt->second)( xChart1Doc );
+ return xTitleShape;
+}
+
+// ============================================================================
diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx
new file mode 100644
index 000000000000..153a5d5ed3cc
--- /dev/null
+++ b/sc/source/filter/excel/xlescher.cxx
@@ -0,0 +1,379 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xlescher.hxx"
+
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <svx/unoapi.hxx>
+#include "document.hxx"
+#include "xestream.hxx"
+#include "xistream.hxx"
+#include "xlroot.hxx"
+#include "xltools.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XControlShape;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::script::ScriptEventDescriptor;
+
+// Structs and classes ========================================================
+
+XclObjId::XclObjId() :
+ mnScTab( SCTAB_INVALID ),
+ mnObjId( EXC_OBJ_INVALID_ID )
+{
+}
+
+XclObjId::XclObjId( SCTAB nScTab, sal_uInt16 nObjId ) :
+ mnScTab( nScTab ),
+ mnObjId( nObjId )
+{
+}
+
+bool operator==( const XclObjId& rL, const XclObjId& rR )
+{
+ return (rL.mnScTab == rR.mnScTab) && (rL.mnObjId == rR.mnObjId);
+}
+
+bool operator<( const XclObjId& rL, const XclObjId& rR )
+{
+ return (rL.mnScTab < rR.mnScTab) || ((rL.mnScTab == rR.mnScTab) && (rL.mnObjId < rR.mnObjId));
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Returns the scaling factor to calculate coordinates from twips. */
+double lclGetTwipsScale( MapUnit eMapUnit )
+{
+ /* #111027# We cannot use OutputDevice::LogicToLogic() or the XclTools
+ conversion functions to calculate drawing layer coordinates due to
+ Calc's strange definition of a point (1 inch == 72.27 points, instead
+ of 72 points). */
+ double fScale = 1.0;
+ switch( eMapUnit )
+ {
+ case MAP_TWIP: fScale = 72 / POINTS_PER_INCH; break; // Calc twips <-> real twips
+ case MAP_100TH_MM: fScale = HMM_PER_TWIPS; break; // Calc twips <-> 1/100mm
+ default: DBG_ERRORFILE( "lclGetTwipsScale - map unit not implemented" );
+ }
+ return fScale;
+}
+
+/** Calculates a drawing layer X position (in twips) from an object column position. */
+long lclGetXFromCol( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nXclCol, sal_uInt16 nOffset, double fScale )
+{
+ SCCOL nScCol = static_cast< SCCOL >( nXclCol );
+ return static_cast< long >( fScale * (rDoc.GetColOffset( nScCol, nScTab ) +
+ ::std::min( nOffset / 1024.0, 1.0 ) * rDoc.GetColWidth( nScCol, nScTab )) + 0.5 );
+}
+
+/** Calculates a drawing layer Y position (in twips) from an object row position. */
+long lclGetYFromRow( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nXclRow, sal_uInt16 nOffset, double fScale )
+{
+ SCROW nScRow = static_cast< SCROW >( nXclRow );
+ return static_cast< long >( fScale * (rDoc.GetRowOffset( nScRow, nScTab ) +
+ ::std::min( nOffset / 256.0, 1.0 ) * rDoc.GetRowHeight( nScRow, nScTab )) + 0.5 );
+}
+
+/** Calculates an object column position from a drawing layer X position (in twips). */
+void lclGetColFromX(
+ ScDocument& rDoc, SCTAB nScTab, sal_uInt16& rnXclCol,
+ sal_uInt16& rnOffset, sal_uInt16 nXclStartCol, sal_uInt16 nXclMaxCol,
+ long& rnStartW, long nX, double fScale )
+{
+ // rnStartW in conjunction with nXclStartCol is used as buffer for previously calculated width
+ long nTwipsX = static_cast< long >( nX / fScale + 0.5 );
+ long nColW = 0;
+ for( rnXclCol = nXclStartCol; rnXclCol <= nXclMaxCol; ++rnXclCol )
+ {
+ nColW = rDoc.GetColWidth( static_cast< SCCOL >( rnXclCol ), nScTab );
+ if( rnStartW + nColW > nTwipsX )
+ break;
+ rnStartW += nColW;
+ }
+ rnOffset = nColW ? static_cast< sal_uInt16 >( (nTwipsX - rnStartW) * 1024.0 / nColW + 0.5 ) : 0;
+}
+
+/** Calculates an object row position from a drawing layer Y position (in twips). */
+void lclGetRowFromY(
+ ScDocument& rDoc, SCTAB nScTab, sal_uInt16& rnXclRow,
+ sal_uInt16& rnOffset, sal_uInt16 nXclStartRow, sal_uInt16 nXclMaxRow,
+ long& rnStartH, long nY, double fScale )
+{
+ // rnStartH in conjunction with nXclStartRow is used as buffer for previously calculated height
+ long nTwipsY = static_cast< long >( nY / fScale + 0.5 );
+ long nRowH = 0;
+ bool bFound = false;
+ for( SCROW nRow = static_cast< SCROW >( nXclStartRow ); nRow <= nXclMaxRow; ++nRow )
+ {
+ nRowH = rDoc.GetRowHeight( nRow, nScTab );
+ if( rnStartH + nRowH > nTwipsY )
+ {
+ rnXclRow = static_cast< sal_uInt16 >( nRow );
+ bFound = true;
+ break;
+ }
+ rnStartH += nRowH;
+ }
+ if( !bFound )
+ rnXclRow = nXclMaxRow;
+ rnOffset = static_cast< sal_uInt16 >( nRowH ? ((nTwipsY - rnStartH) * 256.0 / nRowH + 0.5) : 0 );
+}
+
+/** Mirrors a rectangle (from LTR to RTL layout or vice versa). */
+void lclMirrorRectangle( Rectangle& rRect )
+{
+ long nLeft = rRect.Left();
+ rRect.Left() = -rRect.Right();
+ rRect.Right() = -nLeft;
+}
+
+sal_uInt16 lclGetEmbeddedScale( long nPageSize, sal_Int32 nPageScale, long nPos, double fPosScale )
+{
+ return static_cast< sal_uInt16 >( nPos * fPosScale / nPageSize * nPageScale + 0.5 );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclObjAnchor::XclObjAnchor() :
+ mnLX( 0 ),
+ mnTY( 0 ),
+ mnRX( 0 ),
+ mnBY( 0 )
+{
+}
+
+Rectangle XclObjAnchor::GetRect( const XclRoot& rRoot, SCTAB nScTab, MapUnit eMapUnit ) const
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ double fScale = lclGetTwipsScale( eMapUnit );
+ Rectangle aRect(
+ lclGetXFromCol( rDoc, nScTab, maFirst.mnCol, mnLX, fScale ),
+ lclGetYFromRow( rDoc, nScTab, maFirst.mnRow, mnTY, fScale ),
+ lclGetXFromCol( rDoc, nScTab, maLast.mnCol, mnRX + 1, fScale ),
+ lclGetYFromRow( rDoc, nScTab, maLast.mnRow, mnBY, fScale ) );
+
+ // #106948# adjust coordinates in mirrored sheets
+ if( rDoc.IsLayoutRTL( nScTab ) )
+ lclMirrorRectangle( aRect );
+ return aRect;
+}
+
+void XclObjAnchor::SetRect( const XclRoot& rRoot, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ sal_uInt16 nXclMaxCol = rRoot.GetXclMaxPos().Col();
+ sal_uInt16 nXclMaxRow = static_cast<sal_uInt16>( rRoot.GetXclMaxPos().Row());
+
+ // #106948# adjust coordinates in mirrored sheets
+ Rectangle aRect( rRect );
+ if( rDoc.IsLayoutRTL( nScTab ) )
+ lclMirrorRectangle( aRect );
+
+ double fScale = lclGetTwipsScale( eMapUnit );
+ long nDummy = 0;
+ lclGetColFromX( rDoc, nScTab, maFirst.mnCol, mnLX, 0, nXclMaxCol, nDummy, aRect.Left(), fScale );
+ lclGetColFromX( rDoc, nScTab, maLast.mnCol, mnRX, maFirst.mnCol, nXclMaxCol, nDummy, aRect.Right(), fScale );
+ nDummy = 0;
+ lclGetRowFromY( rDoc, nScTab, maFirst.mnRow, mnTY, 0, nXclMaxRow, nDummy, aRect.Top(), fScale );
+ lclGetRowFromY( rDoc, nScTab, maLast.mnRow, mnBY, maFirst.mnRow, nXclMaxRow, nDummy, aRect.Bottom(), fScale );
+}
+
+void XclObjAnchor::SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY,
+ const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor )
+{
+ double fScale = 1.0;
+ switch( eMapUnit )
+ {
+ case MAP_TWIP: fScale = HMM_PER_TWIPS; break; // Calc twips -> 1/100mm
+ case MAP_100TH_MM: fScale = 1.0; break; // Calc 1/100mm -> 1/100mm
+ default: DBG_ERRORFILE( "XclObjAnchor::SetRect - map unit not implemented" );
+ }
+
+ /* In objects with DFF client anchor, the position of the shape is stored
+ in the cell address components of the client anchor. In old BIFF3-BIFF5
+ objects, the position is stored in the offset components of the anchor. */
+ (bDffAnchor ? maFirst.mnCol : mnLX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Left(), fScale );
+ (bDffAnchor ? maFirst.mnRow : mnTY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Top(), fScale );
+ (bDffAnchor ? maLast.mnCol : mnRX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Right(), fScale );
+ (bDffAnchor ? maLast.mnRow : mnBY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Bottom(), fScale );
+
+ // for safety, clear the other members
+ if( bDffAnchor )
+ mnLX = mnTY = mnRX = mnBY = 0;
+ else
+ Set( 0, 0, 0, 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclObjLineData::XclObjLineData() :
+ mnColorIdx( EXC_OBJ_LINE_AUTOCOLOR ),
+ mnStyle( EXC_OBJ_LINE_SOLID ),
+ mnWidth( EXC_OBJ_LINE_HAIR ),
+ mnAuto( EXC_OBJ_LINE_AUTO )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjLineData& rLineData )
+{
+ return rStrm
+ >> rLineData.mnColorIdx
+ >> rLineData.mnStyle
+ >> rLineData.mnWidth
+ >> rLineData.mnAuto;
+}
+
+// ----------------------------------------------------------------------------
+
+XclObjFillData::XclObjFillData() :
+ mnBackColorIdx( EXC_OBJ_LINE_AUTOCOLOR ),
+ mnPattColorIdx( EXC_OBJ_FILL_AUTOCOLOR ),
+ mnPattern( EXC_PATT_SOLID ),
+ mnAuto( EXC_OBJ_FILL_AUTO )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjFillData& rFillData )
+{
+ return rStrm
+ >> rFillData.mnBackColorIdx
+ >> rFillData.mnPattColorIdx
+ >> rFillData.mnPattern
+ >> rFillData.mnAuto;
+}
+
+// ----------------------------------------------------------------------------
+
+XclObjTextData::XclObjTextData() :
+ mnTextLen( 0 ),
+ mnFormatSize( 0 ),
+ mnLinkSize( 0 ),
+ mnDefFontIdx( EXC_FONT_APP ),
+ mnFlags( 0 ),
+ mnOrient( EXC_OBJ_ORIENT_NONE ),
+ mnButtonFlags( 0 ),
+ mnShortcut( 0 ),
+ mnShortcutEA( 0 )
+{
+}
+
+void XclObjTextData::ReadObj3( XclImpStream& rStrm )
+{
+ rStrm >> mnTextLen;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFormatSize >> mnDefFontIdx;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFlags >> mnOrient;
+ rStrm.Ignore( 8 );
+}
+
+void XclObjTextData::ReadObj5( XclImpStream& rStrm )
+{
+ rStrm >> mnTextLen;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFormatSize >> mnDefFontIdx;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFlags >> mnOrient;
+ rStrm.Ignore( 2 );
+ rStrm >> mnLinkSize;
+ rStrm.Ignore( 2 );
+ rStrm >> mnButtonFlags >> mnShortcut >> mnShortcutEA;
+}
+
+void XclObjTextData::ReadTxo8( XclImpStream& rStrm )
+{
+ rStrm >> mnFlags >> mnOrient >> mnButtonFlags >> mnShortcut >> mnShortcutEA >> mnTextLen >> mnFormatSize;
+}
+
+// ============================================================================
+
+Reference< XControlModel > XclControlHelper::GetControlModel( Reference< XShape > xShape )
+{
+ Reference< XControlModel > xCtrlModel;
+ Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY );
+ if( xCtrlShape.is() )
+ xCtrlModel = xCtrlShape->getControl();
+ return xCtrlModel;
+}
+
+namespace {
+
+static const struct
+{
+ const sal_Char* mpcListenerType;
+ const sal_Char* mpcEventMethod;
+}
+spTbxListenerData[] =
+{
+ // Attention: MUST be in order of the XclTbxEventType enum!
+ /*EXC_TBX_EVENT_ACTION*/ { "XActionListener", "actionPerformed" },
+ /*EXC_TBX_EVENT_MOUSE*/ { "XMouseListener", "mouseReleased" },
+ /*EXC_TBX_EVENT_TEXT*/ { "XTextListener", "textChanged" },
+ /*EXC_TBX_EVENT_VALUE*/ { "XAdjustmentListener", "adjustmentValueChanged" },
+ /*EXC_TBX_EVENT_CHANGE*/ { "XChangeListener", "changed" }
+};
+
+} // namespace
+
+bool XclControlHelper::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor,
+ XclTbxEventType eEventType, const String& rXclMacroName, SfxObjectShell* pDocShell )
+{
+ if( rXclMacroName.Len() > 0 )
+ {
+ rDescriptor.ListenerType = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcListenerType );
+ rDescriptor.EventMethod = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcEventMethod );
+ rDescriptor.ScriptType = CREATE_OUSTRING( "Script" );
+ rDescriptor.ScriptCode = XclTools::GetSbMacroUrl( rXclMacroName, pDocShell );
+ return true;
+ }
+ return false;
+}
+
+String XclControlHelper::ExtractFromMacroDescriptor(
+ const ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType )
+{
+ if( (rDescriptor.ScriptCode.getLength() > 0) &&
+ rDescriptor.ScriptType.equalsIgnoreAsciiCaseAscii( "Script" ) &&
+ rDescriptor.ListenerType.equalsAscii( spTbxListenerData[ eEventType ].mpcListenerType ) &&
+ rDescriptor.EventMethod.equalsAscii( spTbxListenerData[ eEventType ].mpcEventMethod ) )
+ return XclTools::GetXclMacroName( rDescriptor.ScriptCode );
+ return String::EmptyString();
+}
+
+// ============================================================================
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
new file mode 100644
index 000000000000..d613f1279242
--- /dev/null
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -0,0 +1,786 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlformula.hxx"
+
+#include "compiler.hxx"
+#include "rangenam.hxx"
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "xestream.hxx"
+#include "xistream.hxx"
+#include "xlroot.hxx"
+
+using namespace ::formula;
+
+// Function data ==============================================================
+
+String XclFunctionInfo::GetMacroFuncName() const
+{
+ if( IsMacroFunc() )
+ return String( mpcMacroName, RTL_TEXTENCODING_UTF8 );
+ return EMPTY_STRING;
+}
+
+// abbreviations for function return token class
+const sal_uInt8 R = EXC_TOKCLASS_REF;
+const sal_uInt8 V = EXC_TOKCLASS_VAL;
+const sal_uInt8 A = EXC_TOKCLASS_ARR;
+
+// abbreviations for parameter infos
+#define RO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, false }
+#define RV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, false }
+#define RA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, false }
+#define RR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, false }
+#define RX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, false }
+#define VO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, true }
+#define VV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, true }
+#define VA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, true }
+#define VR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, true }
+#define VX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, true }
+#define RO_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_ORG, false }
+#define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true }
+#define C { EXC_PARAM_CALCONLY, EXC_PARAMCONV_ORG, false }
+
+const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF/OOBIN function identifier available.
+const sal_uInt8 MX = 30; /// Maximum parameter count.
+
+#define EXC_FUNCNAME( ascii ) "_xlfn." ascii
+#define EXC_FUNCNAME_ODF( ascii ) "_xlfnodf." ascii
+
+/** Functions new in BIFF2. */
+static const XclFunctionInfo saFuncTable_2[] =
+{
+ { ocCount, 0, 0, MX, V, { RX }, 0, 0 },
+ { ocIf, 1, 2, 3, R, { VO, RO }, 0, 0 },
+ { ocIsNA, 2, 1, 1, V, { VR }, 0, 0 },
+ { ocIsError, 3, 1, 1, V, { VR }, 0, 0 },
+ { ocSum, 4, 0, MX, V, { RX }, 0, 0 },
+ { ocAverage, 5, 1, MX, V, { RX }, 0, 0 },
+ { ocMin, 6, 1, MX, V, { RX }, 0, 0 },
+ { ocMax, 7, 1, MX, V, { RX }, 0, 0 },
+ { ocRow, 8, 0, 1, V, { RO }, 0, 0 },
+ { ocColumn, 9, 0, 1, V, { RO }, 0, 0 },
+ { ocNotAvail, 10, 0, 0, V, {}, 0, 0 },
+ { ocNPV, 11, 2, MX, V, { VR, RX }, 0, 0 },
+ { ocStDev, 12, 1, MX, V, { RX }, 0, 0 },
+ { ocCurrency, 13, 1, 2, V, { VR }, 0, 0 },
+ { ocFixed, 14, 1, 2, V, { VR, VR, C }, 0, 0 },
+ { ocSin, 15, 1, 1, V, { VR }, 0, 0 },
+ { ocCos, 16, 1, 1, V, { VR }, 0, 0 },
+ { ocTan, 17, 1, 1, V, { VR }, 0, 0 },
+ { ocCot, 17, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocArcTan, 18, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCot, 18, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocPi, 19, 0, 0, V, {}, 0, 0 },
+ { ocSqrt, 20, 1, 1, V, { VR }, 0, 0 },
+ { ocExp, 21, 1, 1, V, { VR }, 0, 0 },
+ { ocLn, 22, 1, 1, V, { VR }, 0, 0 },
+ { ocLog10, 23, 1, 1, V, { VR }, 0, 0 },
+ { ocAbs, 24, 1, 1, V, { VR }, 0, 0 },
+ { ocInt, 25, 1, 1, V, { VR }, 0, 0 },
+ { ocPlusMinus, 26, 1, 1, V, { VR }, 0, 0 },
+ { ocRound, 27, 2, 2, V, { VR }, 0, 0 },
+ { ocLookup, 28, 2, 3, V, { VR, RA }, 0, 0 },
+ { ocIndex, 29, 2, 4, R, { RA, VV }, 0, 0 },
+ { ocRept, 30, 2, 2, V, { VR }, 0, 0 },
+ { ocMid, 31, 3, 3, V, { VR }, 0, 0 },
+ { ocLen, 32, 1, 1, V, { VR }, 0, 0 },
+ { ocValue, 33, 1, 1, V, { VR }, 0, 0 },
+ { ocTrue, 34, 0, 0, V, {}, 0, 0 },
+ { ocFalse, 35, 0, 0, V, {}, 0, 0 },
+ { ocAnd, 36, 1, MX, V, { RX }, 0, 0 },
+ { ocOr, 37, 1, MX, V, { RX }, 0, 0 },
+ { ocNot, 38, 1, 1, V, { VR }, 0, 0 },
+ { ocMod, 39, 2, 2, V, { VR }, 0, 0 },
+ { ocDBCount, 40, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBSum, 41, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBAverage, 42, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBMin, 43, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBMax, 44, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBStdDev, 45, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocVar, 46, 1, MX, V, { RX }, 0, 0 },
+ { ocDBVar, 47, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocText, 48, 2, 2, V, { VR }, 0, 0 },
+ { ocRGP, 49, 1, 2, A, { RA, RA, C, C }, 0, 0 },
+ { ocTrend, 50, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
+ { ocRKP, 51, 1, 2, A, { RA, RA, C, C }, 0, 0 },
+ { ocGrowth, 52, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
+ { ocBW, 56, 3, 5, V, { VR }, 0, 0 },
+ { ocZW, 57, 3, 5, V, { VR }, 0, 0 },
+ { ocZZR, 58, 3, 5, V, { VR }, 0, 0 },
+ { ocRMZ, 59, 3, 5, V, { VR }, 0, 0 },
+ { ocZins, 60, 3, 6, V, { VR }, 0, 0 },
+ { ocMIRR, 61, 3, 3, V, { RA, VR }, 0, 0 },
+ { ocIRR, 62, 1, 2, V, { RA, VR }, 0, 0 },
+ { ocRandom, 63, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocMatch, 64, 2, 3, V, { VR, RX, RR }, 0, 0 },
+ { ocGetDate, 65, 3, 3, V, { VR }, 0, 0 },
+ { ocGetTime, 66, 3, 3, V, { VR }, 0, 0 },
+ { ocGetDay, 67, 1, 1, V, { VR }, 0, 0 },
+ { ocGetMonth, 68, 1, 1, V, { VR }, 0, 0 },
+ { ocGetYear, 69, 1, 1, V, { VR }, 0, 0 },
+ { ocGetDayOfWeek, 70, 1, 1, V, { VR, C }, 0, 0 },
+ { ocGetHour, 71, 1, 1, V, { VR }, 0, 0 },
+ { ocGetMin, 72, 1, 1, V, { VR }, 0, 0 },
+ { ocGetSec, 73, 1, 1, V, { VR }, 0, 0 },
+ { ocGetActTime, 74, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocAreas, 75, 1, 1, V, { RO }, 0, 0 },
+ { ocRows, 76, 1, 1, V, { RO }, 0, 0 },
+ { ocColumns, 77, 1, 1, V, { RO }, 0, 0 },
+ { ocOffset, 78, 3, 5, R, { RO, VR }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocSearch, 82, 2, 3, V, { VR }, 0, 0 },
+ { ocMatTrans, 83, 1, 1, A, { VO }, 0, 0 },
+ { ocType, 86, 1, 1, V, { VX }, 0, 0 },
+ { ocArcTan2, 97, 2, 2, V, { VR }, 0, 0 },
+ { ocArcSin, 98, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCos, 99, 1, 1, V, { VR }, 0, 0 },
+ { ocChose, 100, 2, MX, R, { VO, RO }, 0, 0 },
+ { ocHLookup, 101, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
+ { ocVLookup, 102, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
+ { ocIsRef, 105, 1, 1, V, { RX }, 0, 0 },
+ { ocLog, 109, 1, 2, V, { VR }, 0, 0 },
+ { ocChar, 111, 1, 1, V, { VR }, 0, 0 },
+ { ocLower, 112, 1, 1, V, { VR }, 0, 0 },
+ { ocUpper, 113, 1, 1, V, { VR }, 0, 0 },
+ { ocPropper, 114, 1, 1, V, { VR }, 0, 0 },
+ { ocLeft, 115, 1, 2, V, { VR }, 0, 0 },
+ { ocRight, 116, 1, 2, V, { VR }, 0, 0 },
+ { ocExact, 117, 2, 2, V, { VR }, 0, 0 },
+ { ocTrim, 118, 1, 1, V, { VR }, 0, 0 },
+ { ocReplace, 119, 4, 4, V, { VR }, 0, 0 },
+ { ocSubstitute, 120, 3, 4, V, { VR }, 0, 0 },
+ { ocCode, 121, 1, 1, V, { VR }, 0, 0 },
+ { ocFind, 124, 2, 3, V, { VR }, 0, 0 },
+ { ocCell, 125, 1, 2, V, { VV, RO }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocIsErr, 126, 1, 1, V, { VR }, 0, 0 },
+ { ocIsString, 127, 1, 1, V, { VR }, 0, 0 },
+ { ocIsValue, 128, 1, 1, V, { VR }, 0, 0 },
+ { ocIsEmpty, 129, 1, 1, V, { VR }, 0, 0 },
+ { ocT, 130, 1, 1, V, { RO }, 0, 0 },
+ { ocN, 131, 1, 1, V, { RO }, 0, 0 },
+ { ocGetDateValue, 140, 1, 1, V, { VR }, 0, 0 },
+ { ocGetTimeValue, 141, 1, 1, V, { VR }, 0, 0 },
+ { ocLIA, 142, 3, 3, V, { VR }, 0, 0 },
+ { ocDIA, 143, 4, 4, V, { VR }, 0, 0 },
+ { ocGDA, 144, 4, 5, V, { VR }, 0, 0 },
+ { ocIndirect, 148, 1, 2, R, { VR }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocClean, 162, 1, 1, V, { VR }, 0, 0 },
+ { ocMatDet, 163, 1, 1, V, { VA }, 0, 0 },
+ { ocMatInv, 164, 1, 1, A, { VA }, 0, 0 },
+ { ocMatMult, 165, 2, 2, A, { VA }, 0, 0 },
+ { ocZinsZ, 167, 4, 6, V, { VR }, 0, 0 },
+ { ocKapz, 168, 4, 6, V, { VR }, 0, 0 },
+ { ocCount2, 169, 0, MX, V, { RX }, 0, 0 },
+ { ocProduct, 183, 0, MX, V, { RX }, 0, 0 },
+ { ocFact, 184, 1, 1, V, { VR }, 0, 0 },
+ { ocDBProduct, 189, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocIsNonString, 190, 1, 1, V, { VR }, 0, 0 },
+ { ocStDevP, 193, 1, MX, V, { RX }, 0, 0 },
+ { ocVarP, 194, 1, MX, V, { RX }, 0, 0 },
+ { ocDBStdDevP, 195, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBVarP, 196, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocTrunc, 197, 1, 1, V, { VR, C }, 0, 0 },
+ { ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 },
+ { ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
+ { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 },
+ { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 },
+ { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
+};
+
+/** Functions new in BIFF3. */
+static const XclFunctionInfo saFuncTable_3[] =
+{
+ { ocRGP, 49, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { ocTrend, 50, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { ocRKP, 51, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { ocGrowth, 52, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { ocTrunc, 197, 1, 2, V, { VR }, 0, 0 }, // BIFF2: 1, BIFF3: 1-2
+ { ocAddress, 219, 2, 5, V, { VR }, 0, 0 },
+ { ocGetDiffDate360, 220, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocGetActDate, 221, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocVBD, 222, 5, 7, V, { VR }, 0, 0 },
+ { ocMedian, 227, 1, MX, V, { RX }, 0, 0 },
+ { ocSumProduct, 228, 1, MX, V, { VA }, 0, 0 },
+ { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 },
+ { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 },
+ { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 },
+ { ocCotHyp, 231, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocArcSinHyp, 232, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCosHyp, 233, 1, 1, V, { VR }, 0, 0 },
+ { ocArcTanHyp, 234, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCotHyp, 234, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocDBGet, 235, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocInfo, 244, 1, 1, V, { VR }, EXC_FUNCFLAG_VOLATILE, 0 }
+};
+
+/** Functions new in BIFF4. */
+static const XclFunctionInfo saFuncTable_4[] =
+{
+ { ocFixed, 14, 1, 3, V, { VR }, 0, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
+ { ocAsc, 214, 1, 1, V, { VR }, 0, 0 },
+ { ocJis, 215, 1, 1, V, { VR }, 0, 0 },
+ { ocRank, 216, 2, 3, V, { VR, RO, VR }, 0, 0 },
+ { ocGDA2, 247, 4, 5, V, { VR }, 0, 0 },
+ { ocFrequency, 252, 2, 2, A, { RA }, 0, 0 },
+ { ocErrorType, 261, 1, 1, V, { VR }, 0, 0 },
+ { ocAveDev, 269, 1, MX, V, { RX }, 0, 0 },
+ { ocBetaDist, 270, 3, 5, V, { VR }, 0, 0 },
+ { ocGammaLn, 271, 1, 1, V, { VR }, 0, 0 },
+ { ocBetaInv, 272, 3, 5, V, { VR }, 0, 0 },
+ { ocBinomDist, 273, 4, 4, V, { VR }, 0, 0 },
+ { ocChiDist, 274, 2, 2, V, { VR }, 0, 0 },
+ { ocChiInv, 275, 2, 2, V, { VR }, 0, 0 },
+ { ocKombin, 276, 2, 2, V, { VR }, 0, 0 },
+ { ocConfidence, 277, 3, 3, V, { VR }, 0, 0 },
+ { ocKritBinom, 278, 3, 3, V, { VR }, 0, 0 },
+ { ocEven, 279, 1, 1, V, { VR }, 0, 0 },
+ { ocExpDist, 280, 3, 3, V, { VR }, 0, 0 },
+ { ocFDist, 281, 3, 3, V, { VR }, 0, 0 },
+ { ocFInv, 282, 3, 3, V, { VR }, 0, 0 },
+ { ocFisher, 283, 1, 1, V, { VR }, 0, 0 },
+ { ocFisherInv, 284, 1, 1, V, { VR }, 0, 0 },
+ { ocFloor, 285, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocGammaDist, 286, 4, 4, V, { VR }, 0, 0 },
+ { ocGammaInv, 287, 3, 3, V, { VR }, 0, 0 },
+ { ocCeil, 288, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocHypGeomDist, 289, 4, 4, V, { VR }, 0, 0 },
+ { ocLogNormDist, 290, 3, 3, V, { VR }, 0, 0 },
+ { ocLogInv, 291, 3, 3, V, { VR }, 0, 0 },
+ { ocNegBinomVert, 292, 3, 3, V, { VR }, 0, 0 },
+ { ocNormDist, 293, 4, 4, V, { VR }, 0, 0 },
+ { ocStdNormDist, 294, 1, 1, V, { VR }, 0, 0 },
+ { ocNormInv, 295, 3, 3, V, { VR }, 0, 0 },
+ { ocSNormInv, 296, 1, 1, V, { VR }, 0, 0 },
+ { ocStandard, 297, 3, 3, V, { VR }, 0, 0 },
+ { ocOdd, 298, 1, 1, V, { VR }, 0, 0 },
+ { ocVariationen, 299, 2, 2, V, { VR }, 0, 0 },
+ { ocPoissonDist, 300, 3, 3, V, { VR }, 0, 0 },
+ { ocTDist, 301, 3, 3, V, { VR }, 0, 0 },
+ { ocWeibull, 302, 4, 4, V, { VR }, 0, 0 },
+ { ocSumXMY2, 303, 2, 2, V, { VA }, 0, 0 },
+ { ocSumX2MY2, 304, 2, 2, V, { VA }, 0, 0 },
+ { ocSumX2DY2, 305, 2, 2, V, { VA }, 0, 0 },
+ { ocChiTest, 306, 2, 2, V, { VA }, 0, 0 },
+ { ocCorrel, 307, 2, 2, V, { VA }, 0, 0 },
+ { ocCovar, 308, 2, 2, V, { VA }, 0, 0 },
+ { ocForecast, 309, 3, 3, V, { VR, VA }, 0, 0 },
+ { ocFTest, 310, 2, 2, V, { VA }, 0, 0 },
+ { ocIntercept, 311, 2, 2, V, { VA }, 0, 0 },
+ { ocPearson, 312, 2, 2, V, { VA }, 0, 0 },
+ { ocRSQ, 313, 2, 2, V, { VA }, 0, 0 },
+ { ocSTEYX, 314, 2, 2, V, { VA }, 0, 0 },
+ { ocSlope, 315, 2, 2, V, { VA }, 0, 0 },
+ { ocTTest, 316, 4, 4, V, { VA, VA, VR }, 0, 0 },
+ { ocProb, 317, 3, 4, V, { VA, VA, VR }, 0, 0 },
+ { ocDevSq, 318, 1, MX, V, { RX }, 0, 0 },
+ { ocGeoMean, 319, 1, MX, V, { RX }, 0, 0 },
+ { ocHarMean, 320, 1, MX, V, { RX }, 0, 0 },
+ { ocSumSQ, 321, 0, MX, V, { RX }, 0, 0 },
+ { ocKurt, 322, 1, MX, V, { RX }, 0, 0 },
+ { ocSchiefe, 323, 1, MX, V, { RX }, 0, 0 },
+ { ocZTest, 324, 2, 3, V, { RX, VR }, 0, 0 },
+ { ocLarge, 325, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocSmall, 326, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocQuartile, 327, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocPercentile, 328, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocPercentrank, 329, 2, 3, V, { RX, VR, VR_E }, 0, 0 },
+ { ocModalValue, 330, 1, MX, V, { VA }, 0, 0 },
+ { ocTrimMean, 331, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocTInv, 332, 2, 2, V, { VR }, 0, 0 }
+};
+
+/** Functions new in BIFF5/BIFF7. Unsupported functions: DATEDIF, DATESTRING, NUMBERSTRING. */
+static const XclFunctionInfo saFuncTable_5[] =
+{
+ { ocGetDayOfWeek, 70, 1, 2, V, { VR }, 0, 0 }, // BIFF2-4: 1, BIFF5: 1-2
+ { ocHLookup, 101, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { ocVLookup, 102, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { ocGetDiffDate360, 220, 2, 3, V, { VR }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3
+ { ocMacro, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocConcat, 336, 0, MX, V, { VR }, 0, 0 },
+ { ocPower, 337, 2, 2, V, { VR }, 0, 0 },
+ { ocRad, 342, 1, 1, V, { VR }, 0, 0 },
+ { ocDeg, 343, 1, 1, V, { VR }, 0, 0 },
+ { ocSubTotal, 344, 2, MX, V, { VR, RO }, 0, 0 },
+ { ocSumIf, 345, 2, 3, V, { RO, VR, RO }, 0, 0 },
+ { ocCountIf, 346, 2, 2, V, { RO, VR }, 0, 0 },
+ { ocCountEmptyCells, 347, 1, 1, V, { RO }, 0, 0 },
+ { ocISPMT, 350, 4, 4, V, { VR }, 0, 0 },
+ { ocNoName, 351, 3, 3, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATEDIF
+ { ocNoName, 352, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATESTRING
+ { ocNoName, 353, 2, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // NUMBERSTRING
+ { ocRoman, 354, 1, 2, V, { VR }, 0, 0 }
+};
+
+/** Functions new in BIFF8. Unsupported functions: PHONETIC. */
+static const XclFunctionInfo saFuncTable_8[] =
+{
+ { ocGetPivotData, 358, 2, MX, V, { RR, RR, VR }, 0, 0 },
+ { ocHyperLink, 359, 1, 2, V, { VV, VO }, 0, 0 },
+ { ocNoName, 360, 1, 1, V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC
+ { ocAverageA, 361, 1, MX, V, { RX }, 0, 0 },
+ { ocMaxA, 362, 1, MX, V, { RX }, 0, 0 },
+ { ocMinA, 363, 1, MX, V, { RX }, 0, 0 },
+ { ocStDevPA, 364, 1, MX, V, { RX }, 0, 0 },
+ { ocVarPA, 365, 1, MX, V, { RX }, 0, 0 },
+ { ocStDevA, 366, 1, MX, V, { RX }, 0, 0 },
+ { ocVarA, 367, 1, MX, V, { RX }, 0, 0 },
+ { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
+ { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
+ { ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
+};
+
+#define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \
+ { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \
+ { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }
+
+/** Functions defined by OpenFormula, but not supported by Calc (ocNoName) or by Excel (defined op-code). */
+static const XclFunctionInfo saFuncTable_Odf[] =
+{
+ EXC_FUNCENTRY_ODF( ocArabic, 1, 1, 0, "ARABIC" ),
+ EXC_FUNCENTRY_ODF( ocB, 3, 4, 0, "B" ),
+ EXC_FUNCENTRY_ODF( ocBase, 2, 3, 0, "BASE" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITAND" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITLSHIFT" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITOR" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITRSHIFT" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITXOR" ),
+ EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ),
+ EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ),
+ EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ),
+ EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ),
+ EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ),
+ EXC_FUNCENTRY_ODF( ocFDist, 3, 4, 0, "FDIST" ),
+ EXC_FUNCENTRY_ODF( ocFInv, 3, 3, 0, "FINV" ),
+ EXC_FUNCENTRY_ODF( ocFormula, 1, 1, 0, "FORMULA" ),
+ EXC_FUNCENTRY_ODF( ocGamma, 1, 1, 0, "GAMMA" ),
+ EXC_FUNCENTRY_ODF( ocGauss, 1, 1, 0, "GAUSS" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "IFNA" ),
+ EXC_FUNCENTRY_ODF( ocIsFormula, 1, 1, 0, "ISFORMULA" ),
+ EXC_FUNCENTRY_ODF( ocWeek, 1, 2, 0, "ISOWEEKNUM" ),
+ EXC_FUNCENTRY_ODF( ocMatrixUnit, 1, 1, 0, "MUNIT" ),
+ EXC_FUNCENTRY_ODF( ocNumberValue, 2, 2, 0, "NUMBERVALUE" ),
+ EXC_FUNCENTRY_ODF( ocLaufz, 3, 3, 0, "PDURATION" ),
+ EXC_FUNCENTRY_ODF( ocVariationen2, 2, 2, 0, "PERMUTATIONA" ),
+ EXC_FUNCENTRY_ODF( ocPhi, 1, 1, 0, "PHI" ),
+ EXC_FUNCENTRY_ODF( ocZGZ, 3, 3, 0, "RRI" ),
+ EXC_FUNCENTRY_ODF( ocTable, 1, 1, 0, "SHEET" ),
+ EXC_FUNCENTRY_ODF( ocTables, 0, 1, 0, "SHEETS" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "SKEWP" ),
+ EXC_FUNCENTRY_ODF( ocUnichar, 1, 1, 0, "UNICHAR" ),
+ EXC_FUNCENTRY_ODF( ocUnicode, 1, 1, 0, "UNICODE" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "XOR" )
+};
+
+#undef EXC_FUNCENTRY_ODF
+
+// ----------------------------------------------------------------------------
+
+XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot )
+{
+ void (XclFunctionProvider::*pFillFunc)( const XclFunctionInfo*, const XclFunctionInfo* ) =
+ rRoot.IsImport() ? &XclFunctionProvider::FillXclFuncMap : &XclFunctionProvider::FillScFuncMap;
+
+ /* Only read/write functions supported in the current BIFF version.
+ Function tables from later BIFF versions may overwrite single functions
+ from earlier tables. */
+ XclBiff eBiff = rRoot.GetBiff();
+ if( eBiff >= EXC_BIFF2 )
+ (this->*pFillFunc)( saFuncTable_2, STATIC_TABLE_END( saFuncTable_2 ) );
+ if( eBiff >= EXC_BIFF3 )
+ (this->*pFillFunc)( saFuncTable_3, STATIC_TABLE_END( saFuncTable_3 ) );
+ if( eBiff >= EXC_BIFF4 )
+ (this->*pFillFunc)( saFuncTable_4, STATIC_TABLE_END( saFuncTable_4 ) );
+ if( eBiff >= EXC_BIFF5 )
+ (this->*pFillFunc)( saFuncTable_5, STATIC_TABLE_END( saFuncTable_5 ) );
+ if( eBiff >= EXC_BIFF8 )
+ (this->*pFillFunc)( saFuncTable_8, STATIC_TABLE_END( saFuncTable_8 ) );
+ (this->*pFillFunc)( saFuncTable_Odf, STATIC_TABLE_END( saFuncTable_Odf ) );
+}
+
+const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const
+{
+ // only in import filter allowed
+ DBG_ASSERT( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclFunc - wrong filter" );
+ XclFuncMap::const_iterator aIt = maXclFuncMap.find( nXclFunc );
+ return (aIt == maXclFuncMap.end()) ? 0 : aIt->second;
+}
+
+const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const
+{
+ // only in import filter allowed, but do not test maXclMacroNameMap, it may be empty for old BIFF versions
+ DBG_ASSERT( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclMacroName - wrong filter" );
+ XclMacroNameMap::const_iterator aIt = maXclMacroNameMap.find( rXclMacroName );
+ return (aIt == maXclMacroNameMap.end()) ? 0 : aIt->second;
+}
+
+const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromOpCode( OpCode eOpCode ) const
+{
+ // only in export filter allowed
+ DBG_ASSERT( !maScFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromOpCode - wrong filter" );
+ ScFuncMap::const_iterator aIt = maScFuncMap.find( eOpCode );
+ return (aIt == maScFuncMap.end()) ? 0 : aIt->second;
+}
+
+void XclFunctionProvider::FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
+{
+ for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_EXPORTONLY ) )
+ {
+ maXclFuncMap[ pIt->mnXclFunc ] = pIt;
+ if( pIt->IsMacroFunc() )
+ maXclMacroNameMap[ pIt->GetMacroFuncName() ] = pIt;
+ }
+ }
+}
+
+void XclFunctionProvider::FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
+{
+ for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
+ if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_IMPORTONLY ) )
+ maScFuncMap[ pIt->meOpCode ] = pIt;
+}
+
+// Token array ================================================================
+
+XclTokenArray::XclTokenArray( bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+}
+
+XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+ maTokVec.swap( rTokVec );
+}
+
+XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+ maTokVec.swap( rTokVec );
+ maExtDataVec.swap( rExtDataVec );
+}
+
+sal_uInt16 XclTokenArray::GetSize() const
+{
+ DBG_ASSERT( maTokVec.size() <= 0xFFFF, "XclTokenArray::GetSize - array too long" );
+ return limit_cast< sal_uInt16 >( maTokVec.size() );
+}
+
+void XclTokenArray::ReadSize( XclImpStream& rStrm )
+{
+ sal_uInt16 nSize;
+ rStrm >> nSize;
+ maTokVec.resize( nSize );
+}
+
+void XclTokenArray::ReadArray( XclImpStream& rStrm )
+{
+ if( !maTokVec.empty() )
+ rStrm.Read( &maTokVec.front(), GetSize() );
+}
+
+void XclTokenArray::Read( XclImpStream& rStrm )
+{
+ ReadSize( rStrm );
+ ReadArray( rStrm );
+}
+
+void XclTokenArray::WriteSize( XclExpStream& rStrm ) const
+{
+ rStrm << GetSize();
+}
+
+void XclTokenArray::WriteArray( XclExpStream& rStrm ) const
+{
+ if( !maTokVec.empty() )
+ rStrm.Write( &maTokVec.front(), GetSize() );
+ if( !maExtDataVec.empty() )
+ rStrm.Write( &maExtDataVec.front(), maExtDataVec.size() );
+}
+
+void XclTokenArray::Write( XclExpStream& rStrm ) const
+{
+ WriteSize( rStrm );
+ WriteArray( rStrm );
+}
+
+bool XclTokenArray::operator==( const XclTokenArray& rTokArr ) const
+{
+ return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec) && (maExtDataVec == rTokArr.maExtDataVec);
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr )
+{
+ rTokArr.Read( rStrm );
+ return rStrm;
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr )
+{
+ if( !rxTokArr )
+ rxTokArr.reset( new XclTokenArray );
+ rxTokArr->Read( rStrm );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr )
+{
+ rTokArr.Write( rStrm );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr )
+{
+ if( rxTokArr.is() )
+ rxTokArr->Write( rStrm );
+ else
+ rStrm << sal_uInt16( 0 );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+XclTokenArrayIterator::XclTokenArrayIterator() :
+ mppScTokenBeg( 0 ),
+ mppScTokenEnd( 0 ),
+ mppScToken( 0 ),
+ mbSkipSpaces( false )
+{
+}
+
+XclTokenArrayIterator::XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces )
+{
+ Init( rScTokArr, bSkipSpaces );
+}
+
+XclTokenArrayIterator::XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces ) :
+ mppScTokenBeg( rTokArrIt.mppScTokenBeg ),
+ mppScTokenEnd( rTokArrIt.mppScTokenEnd ),
+ mppScToken( rTokArrIt.mppScToken ),
+ mbSkipSpaces( bSkipSpaces )
+{
+ SkipSpaces();
+}
+
+void XclTokenArrayIterator::Init()
+{
+ mppScTokenBeg = mppScTokenEnd = mppScToken = 0;
+}
+
+void XclTokenArrayIterator::Init( const ScTokenArray& rScTokArr, bool bSkipSpaces )
+{
+ USHORT nTokArrLen = rScTokArr.GetLen();
+ mppScTokenBeg = static_cast< const FormulaToken* const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
+ mppScTokenEnd = mppScTokenBeg ? (mppScTokenBeg + nTokArrLen) : 0;
+ mppScToken = (mppScTokenBeg != mppScTokenEnd) ? mppScTokenBeg : 0;
+ mbSkipSpaces = bSkipSpaces;
+ SkipSpaces();
+}
+
+XclTokenArrayIterator& XclTokenArrayIterator::operator++()
+{
+ NextRawToken();
+ SkipSpaces();
+ return *this;
+}
+
+void XclTokenArrayIterator::NextRawToken()
+{
+ if( mppScToken )
+ if( (++mppScToken == mppScTokenEnd) || !*mppScToken )
+ mppScToken = 0;
+}
+
+void XclTokenArrayIterator::SkipSpaces()
+{
+ if( mbSkipSpaces )
+ while( Is() && ((*this)->GetOpCode() == ocSpaces) )
+ NextRawToken();
+}
+
+// strings and string lists ---------------------------------------------------
+
+bool XclTokenArrayHelper::GetTokenString( String& rString, const FormulaToken& rScToken )
+{
+ bool bIsStr = (rScToken.GetType() == svString) && (rScToken.GetOpCode() == ocPush);
+ if( bIsStr ) rString = rScToken.GetString();
+ return bIsStr;
+}
+
+bool XclTokenArrayHelper::GetString( String& rString, const ScTokenArray& rScTokArr )
+{
+ XclTokenArrayIterator aIt( rScTokArr, true );
+ // something is following the string token -> error
+ return aIt.Is() && GetTokenString( rString, *aIt ) && !++aIt;
+}
+
+bool XclTokenArrayHelper::GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep )
+{
+ bool bRet = true;
+ String aString;
+ XclTokenArrayIterator aIt( rScTokArr, true );
+ enum { STATE_START, STATE_STR, STATE_SEP, STATE_END } eState = STATE_START;
+ while( eState != STATE_END ) switch( eState )
+ {
+ case STATE_START:
+ eState = aIt.Is() ? STATE_STR : STATE_END;
+ break;
+ case STATE_STR:
+ bRet = GetTokenString( aString, *aIt );
+ if( bRet ) rStringList.Append( aString );
+ eState = (bRet && (++aIt).Is()) ? STATE_SEP : STATE_END;
+ break;
+ case STATE_SEP:
+ bRet = aIt->GetOpCode() == ocSep;
+ if( bRet ) rStringList.Append( cSep );
+ eState = (bRet && (++aIt).Is()) ? STATE_STR : STATE_END;
+ break;
+ default:;
+ }
+ return bRet;
+}
+
+void XclTokenArrayHelper::ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces )
+{
+ String aString;
+ if( GetString( aString, rScTokArr ) )
+ {
+ rScTokArr.Clear();
+ xub_StrLen nTokenCnt = aString.GetTokenCount( cStringSep );
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( aString.GetToken( 0, cStringSep, nStringIx ) );
+ if( bTrimLeadingSpaces )
+ aToken.EraseLeadingChars( ' ' );
+ if( nToken > 0 )
+ rScTokArr.AddOpCode( ocSep );
+ rScTokArr.AddString( aToken );
+ }
+ }
+}
+
+// shared formulas ------------------------------------------------------------
+
+const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr )
+{
+ if( rScTokArr.GetLen() == 1 )
+ if( const FormulaToken* pScToken = rScTokArr.GetArray()[ 0 ] )
+ if( pScToken->GetOpCode() == ocName )
+ if( ScRangeData* pData = rRoot.GetNamedRanges().FindIndex( pScToken->GetIndex() ) )
+ if( pData->HasType( RT_SHARED ) )
+ return pData->GetCode();
+ return 0;
+}
+
+// multiple operations --------------------------------------------------------
+
+namespace {
+
+inline bool lclGetAddress( ScAddress& rAddress, const FormulaToken& rToken )
+{
+ OpCode eOpCode = rToken.GetOpCode();
+ bool bIsSingleRef = (eOpCode == ocPush) && (rToken.GetType() == svSingleRef);
+ if( bIsSingleRef )
+ {
+ const ScSingleRefData& rRef = static_cast<const ScToken&>(rToken).GetSingleRef();
+ rAddress.Set( rRef.nCol, rRef.nRow, rRef.nTab );
+ bIsSingleRef = !rRef.IsDeleted();
+ }
+ return bIsSingleRef;
+}
+
+} // namespace
+
+bool XclTokenArrayHelper::GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr )
+{
+ rRefs.mbDblRefMode = false;
+ enum
+ {
+ stBegin, stTableOp, stOpen, stFormula, stFormulaSep,
+ stColFirst, stColFirstSep, stColRel, stColRelSep,
+ stRowFirst, stRowFirstSep, stRowRel, stClose, stError
+ } eState = stBegin; // last read token
+ for( XclTokenArrayIterator aIt( rScTokArr, true ); aIt.Is() && (eState != stError); ++aIt )
+ {
+ OpCode eOpCode = aIt->GetOpCode();
+ bool bIsSep = eOpCode == ocSep;
+ switch( eState )
+ {
+ case stBegin:
+ eState = (eOpCode == ocTableOp) ? stTableOp : stError;
+ break;
+ case stTableOp:
+ eState = (eOpCode == ocOpen) ? stOpen : stError;
+ break;
+ case stOpen:
+ eState = lclGetAddress( rRefs.maFmlaScPos, *aIt ) ? stFormula : stError;
+ break;
+ case stFormula:
+ eState = bIsSep ? stFormulaSep : stError;
+ break;
+ case stFormulaSep:
+ eState = lclGetAddress( rRefs.maColFirstScPos, *aIt ) ? stColFirst : stError;
+ break;
+ case stColFirst:
+ eState = bIsSep ? stColFirstSep : stError;
+ break;
+ case stColFirstSep:
+ eState = lclGetAddress( rRefs.maColRelScPos, *aIt ) ? stColRel : stError;
+ break;
+ case stColRel:
+ eState = bIsSep ? stColRelSep : ((eOpCode == ocClose) ? stClose : stError);
+ break;
+ case stColRelSep:
+ eState = lclGetAddress( rRefs.maRowFirstScPos, *aIt ) ? stRowFirst : stError;
+ rRefs.mbDblRefMode = true;
+ break;
+ case stRowFirst:
+ eState = bIsSep ? stRowFirstSep : stError;
+ break;
+ case stRowFirstSep:
+ eState = lclGetAddress( rRefs.maRowRelScPos, *aIt ) ? stRowRel : stError;
+ break;
+ case stRowRel:
+ eState = (eOpCode == ocClose) ? stClose : stError;
+ break;
+ default:
+ eState = stError;
+ }
+ }
+ return eState == stClose;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xlpage.cxx b/sc/source/filter/excel/xlpage.cxx
new file mode 100644
index 000000000000..a59c6f761667
--- /dev/null
+++ b/sc/source/filter/excel/xlpage.cxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlpage.hxx"
+#include <sfx2/printer.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/paperinf.hxx>
+#include <vcl/svapp.hxx>
+#include "scitems.hxx"
+#include <editeng/brshitem.hxx>
+#include "global.hxx"
+#include "xlconst.hxx"
+
+// Paper size =================================================================
+
+struct XclPaperSize
+{
+ Paper mePaper; /// SVX paper size identifier.
+ long mnWidth; /// Paper width in twips.
+ long mnHeight; /// Paper height in twips.
+};
+
+#define IN2TWIPS( v ) ((long)((v) * EXC_TWIPS_PER_INCH + 0.5))
+#define MM2TWIPS( v ) ((long)((v) * EXC_TWIPS_PER_INCH / CM_PER_INCH / 10.0 + 0.5))
+
+static const XclPaperSize pPaperSizeTable[] =
+{
+/* 0*/ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_LETTER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter Small
+ { PAPER_TABLOID, IN2TWIPS( 11 ), IN2TWIPS( 17 ) }, // Tabloid
+ { PAPER_LEDGER, IN2TWIPS( 17 ), IN2TWIPS( 11 ) }, // Ledger
+/* 5*/ { PAPER_LEGAL, IN2TWIPS( 8.5 ), IN2TWIPS( 14 ) }, // Legal
+ { PAPER_STATEMENT, IN2TWIPS( 5.5 ), IN2TWIPS( 8.5 ) }, // Statement
+ { PAPER_EXECUTIVE, IN2TWIPS( 7.25 ), IN2TWIPS( 10.5 ) }, // Executive
+ { PAPER_A3, MM2TWIPS( 297 ), MM2TWIPS( 420 ) }, // A3
+ { PAPER_A4, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4
+/* 10*/ { PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4 Small
+ { PAPER_A5, MM2TWIPS( 148 ), MM2TWIPS( 210 ) }, // A5
+ //See: http://wiki.services.openoffice.org/wiki/DefaultPaperSize comments
+ //near DMPAPER_B4 in vcl
+ //i.e.
+ //http://msdn.microsoft.com/en-us/library/bb241398.aspx makes the claim:
+ //xlPaperB4 12 B4 (250 mm x 354 mm)
+ //xlPaperB5 13 A5 (148 mm x 210 mm)
+ //but, a paper enum called B5 is surely not actually "A5", and furthermore
+ //the XlPaperSize enumeration otherwise follows the DMPAPER values
+ //http://msdn.microsoft.com/en-us/library/ms776398(VS.85).aspx
+ //which has
+ //DMPAPER_B4 12 B4 (JIS) 250 x 354
+ //DMPAPER_B5 13 B5 (JIS) 182 x 257 mm
+ //which claim them to be the JIS sizes. Though that document then gives
+ //"B4 (JIS)" an *ISO* B4 size in the text, but
+ //http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf
+ //claims that the MS DMPAPER_B4 and DMPAPER_B5 truly are the JIS sizes
+ //which at least makes some sort of sense. (cmc)
+ { PAPER_B4_JIS, MM2TWIPS( 257 ), MM2TWIPS( 364 ) }, // B4 (JIS)
+ { PAPER_B5_JIS, MM2TWIPS( 182 ), MM2TWIPS( 257 ) }, // B5 (JIS)
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 13 ) }, // Folio
+/* 15*/ { PAPER_QUARTO, MM2TWIPS( 215 ), MM2TWIPS( 275 ) }, // Quarto
+ { PAPER_10x14, IN2TWIPS( 10 ), IN2TWIPS( 14 ) }, // 10x14
+ { PAPER_USER, IN2TWIPS( 11 ), IN2TWIPS( 17 ) }, // 11x17
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Note
+ { PAPER_ENV_9, IN2TWIPS( 3.875 ), IN2TWIPS( 8.875 ) }, // Envelope #9
+/* 20*/ { PAPER_ENV_10, IN2TWIPS( 4.125 ), IN2TWIPS( 9.5 ) }, // Envelope #10
+ { PAPER_ENV_11, IN2TWIPS( 4.5 ), IN2TWIPS( 10.375 ) }, // Envelope #11
+ { PAPER_ENV_12, IN2TWIPS( 4.75 ), IN2TWIPS( 11 ) }, // Envelope #12
+ { PAPER_ENV_14, IN2TWIPS( 5 ), IN2TWIPS( 11.5 ) }, // Envelope #14
+ { PAPER_C, IN2TWIPS( 17 ), IN2TWIPS( 22 ) }, // ANSI-C
+/* 25*/ { PAPER_D, IN2TWIPS( 22 ), IN2TWIPS( 34 ) }, // ANSI-D
+ { PAPER_E, IN2TWIPS( 34 ), IN2TWIPS( 44 ) }, // ANSI-E
+ { PAPER_ENV_DL, MM2TWIPS( 110 ), MM2TWIPS( 220 ) }, // Envelope DL
+ { PAPER_ENV_C5, MM2TWIPS( 162 ), MM2TWIPS( 229 ) }, // Envelope C5
+ { PAPER_ENV_C3, MM2TWIPS( 324 ), MM2TWIPS( 458 ) }, // Envelope C3
+/* 30*/ { PAPER_ENV_C4, MM2TWIPS( 229 ), MM2TWIPS( 324 ) }, // Envelope C4
+ { PAPER_ENV_C6, MM2TWIPS( 114 ), MM2TWIPS( 162 ) }, // Envelope C6
+ { PAPER_ENV_C65, MM2TWIPS( 114 ), MM2TWIPS( 229 ) }, // Envelope C65
+ { PAPER_B4_ISO, MM2TWIPS( 250 ), MM2TWIPS( 353 ) }, // B4 (ISO)
+ { PAPER_B5_ISO, MM2TWIPS( 176 ), MM2TWIPS( 250 ) }, // B5 (ISO)
+/* 35*/ { PAPER_B6_ISO, MM2TWIPS( 125 ), MM2TWIPS( 176 ) }, // B6 (ISO)
+ { PAPER_ENV_ITALY, MM2TWIPS( 110 ), MM2TWIPS( 230 ) }, // Envelope Italy
+ { PAPER_ENV_MONARCH, IN2TWIPS( 3.875 ), IN2TWIPS( 7.5 ) }, // Envelope Monarch
+ { PAPER_ENV_PERSONAL, IN2TWIPS( 3.625 ), IN2TWIPS( 6.5 ) }, // 6 3/4 Envelope
+ { PAPER_FANFOLD_US, IN2TWIPS( 14.875 ), IN2TWIPS( 11 ) }, // US Std Fanfold
+/* 40*/ { PAPER_FANFOLD_DE, IN2TWIPS( 8.5 ), IN2TWIPS( 12 ) }, // German Std Fanfold
+ { PAPER_FANFOLD_LEGAL_DE, IN2TWIPS( 8.5 ), IN2TWIPS( 13 ) }, // German Legal Fanfold
+ { PAPER_B4_ISO, MM2TWIPS( 250 ), MM2TWIPS( 353 ) }, // B4 (ISO)
+ { PAPER_POSTCARD_JP,MM2TWIPS( 100 ), MM2TWIPS( 148 ) }, // Japanese Postcard
+ { PAPER_9x11, IN2TWIPS( 9 ), IN2TWIPS( 11 ) }, // 9x11
+/* 45*/ { PAPER_10x11, IN2TWIPS( 10 ), IN2TWIPS( 11 ) }, // 10x11
+ { PAPER_15x11, IN2TWIPS( 15 ), IN2TWIPS( 11 ) }, // 15x11
+ { PAPER_ENV_INVITE, MM2TWIPS( 220 ), MM2TWIPS( 220 ) }, // Envelope Invite
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+/* 50*/ { PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 12 ) }, // Letter Extra
+ { PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 15 ) }, // Legal Extra
+ { PAPER_USER, IN2TWIPS( 11.69 ), IN2TWIPS( 18 ) }, // Tabloid Extra
+ { PAPER_USER, MM2TWIPS( 235 ), MM2TWIPS( 322 ) }, // A4 Extra
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter Transverse
+/* 55*/ { PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4 Transverse
+ { PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 12 ) }, // Letter Extra Transverse
+ { PAPER_A_PLUS, MM2TWIPS( 227 ), MM2TWIPS( 356 ) }, // Super A/A4
+ { PAPER_B_PLUS, MM2TWIPS( 305 ), MM2TWIPS( 487 ) }, // Super B/A3
+ { PAPER_LETTER_PLUS,IN2TWIPS( 8.5 ), IN2TWIPS( 12.69 ) }, // Letter Plus
+/* 60*/ { PAPER_A4_PLUS, MM2TWIPS( 210 ), MM2TWIPS( 330 ) }, // A4 Plus
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 210 ) }, // A5 Transverse
+ { PAPER_USER, MM2TWIPS( 182 ), MM2TWIPS( 257 ) }, // B5 (JIS) Transverse
+ { PAPER_USER, MM2TWIPS( 322 ), MM2TWIPS( 445 ) }, // A3 Extra
+ { PAPER_USER, MM2TWIPS( 174 ), MM2TWIPS( 235 ) }, // A5 Extra
+/* 65*/ { PAPER_USER, MM2TWIPS( 201 ), MM2TWIPS( 276 ) }, // B5 (ISO) Extra
+ { PAPER_A2, MM2TWIPS( 420 ), MM2TWIPS( 594 ) }, // A2
+ { PAPER_USER, MM2TWIPS( 297 ), MM2TWIPS( 420 ) }, // A3 Transverse
+ { PAPER_USER, MM2TWIPS( 322 ), MM2TWIPS( 445 ) }, // A3 Extra Transverse
+ { PAPER_DOUBLEPOSTCARD_JP, MM2TWIPS( 200 ), MM2TWIPS( 148 ) }, // Double Japanese Postcard
+/* 70*/ { PAPER_A6, MM2TWIPS( 105 ), MM2TWIPS( 148 ) }, // A6
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+/* 75*/ { PAPER_USER, IN2TWIPS( 11 ), IN2TWIPS( 8.5 ) }, // Letter Rotated
+ { PAPER_USER, MM2TWIPS( 420 ), MM2TWIPS( 297 ) }, // A3 Rotated
+ { PAPER_USER, MM2TWIPS( 297 ), MM2TWIPS( 210 ) }, // A4 Rotated
+ { PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 148 ) }, // A5 Rotated
+ { PAPER_USER, MM2TWIPS( 364 ), MM2TWIPS( 257 ) }, // B4 (JIS) Rotated
+/* 80*/ { PAPER_USER, MM2TWIPS( 257 ), MM2TWIPS( 182 ) }, // B5 (JIS) Rotated
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 100 ) }, // Japanese Postcard Rotated
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 200 ) }, // Double Japanese Postcard Rotated
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 105 ) }, // A6 Rotated
+ { PAPER_USER, 0, 0 }, // undefined
+/* 85*/ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_B6_JIS, MM2TWIPS( 128 ), MM2TWIPS( 182 ) }, // B6 (JIS)
+ { PAPER_USER, MM2TWIPS( 182 ), MM2TWIPS( 128 ) }, // B6 (JIS) Rotated
+/* 90*/ { PAPER_12x11, IN2TWIPS( 12 ), IN2TWIPS( 11 ) } // 12x11
+};
+
+#undef IN2TWIPS
+#undef MM2TWIPS
+
+// Page settings ==============================================================
+
+XclPageData::XclPageData()
+{
+ SetDefaults();
+}
+
+XclPageData::~XclPageData()
+{
+ // SvxBrushItem incomplete in header
+}
+
+void XclPageData::SetDefaults()
+{
+ maHorPageBreaks.clear();
+ maVerPageBreaks.clear();
+ mxBrushItem.reset();
+ maHeader.Erase();
+ maFooter.Erase();
+ mfLeftMargin = mfRightMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_LR );
+ mfTopMargin = mfBottomMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_TB );
+ mfHeaderMargin = mfFooterMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_HF );
+ mfHdrLeftMargin = mfHdrRightMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_HLR );
+ mfFtrLeftMargin = mfFtrRightMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_FLR );
+ mnPaperSize = EXC_PAPERSIZE_DEFAULT;
+ mnCopies = 1;
+ mnStartPage = 0;
+ mnScaling = 100;
+ mnFitToWidth = mnFitToHeight = 1;
+ mnHorPrintRes = mnVerPrintRes = 300;
+ mbValid = false;
+ mbPortrait = true;
+ mbPrintInRows = mbBlackWhite = mbDraftQuality = mbPrintNotes = mbManualStart = mbFitToPages = false;
+ mbHorCenter = mbVerCenter = mbPrintHeadings = mbPrintGrid = false;
+}
+
+Size XclPageData::GetScPaperSize() const
+{
+ const XclPaperSize* pEntry = pPaperSizeTable;
+ if( mnPaperSize < STATIC_TABLE_SIZE( pPaperSizeTable ) )
+ pEntry += mnPaperSize;
+
+ Size aSize;
+ if( pEntry->mePaper == PAPER_USER )
+ aSize = Size( pEntry->mnWidth, pEntry->mnHeight );
+ else
+ aSize = SvxPaperInfo::GetPaperSize( pEntry->mePaper );
+
+ // invalid size -> back to default
+ if( !aSize.Width() || !aSize.Height() )
+ aSize = SvxPaperInfo::GetDefaultPaperSize();
+
+ if( !mbPortrait )
+ ::std::swap( aSize.Width(), aSize.Height() );
+
+ return aSize;
+}
+
+void XclPageData::SetScPaperSize( const Size& rSize, bool bPortrait )
+{
+ mbPortrait = bPortrait;
+ mnPaperSize = 0;
+ long nWidth = bPortrait ? rSize.Width() : rSize.Height();
+ long nHeight = bPortrait ? rSize.Height() : rSize.Width();
+ long nMaxWDiff = 80;
+ long nMaxHDiff = 50;
+ for( const XclPaperSize* pEntry = pPaperSizeTable; pEntry != STATIC_TABLE_END( pPaperSizeTable ); ++pEntry )
+ {
+ long nWDiff = Abs( pEntry->mnWidth - nWidth );
+ long nHDiff = Abs( pEntry->mnHeight - nHeight );
+ if( ((nWDiff <= nMaxWDiff) && (nHDiff < nMaxHDiff)) ||
+ ((nWDiff < nMaxWDiff) && (nHDiff <= nMaxHDiff)) )
+ {
+ mnPaperSize = static_cast< sal_uInt16 >( pEntry - pPaperSizeTable );
+ nMaxWDiff = nWDiff;
+ nMaxHDiff = nHDiff;
+ }
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx
new file mode 100644
index 000000000000..ed7aadd0a410
--- /dev/null
+++ b/sc/source/filter/excel/xlpivot.cxx
@@ -0,0 +1,1031 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "dpgroup.hxx"
+#include "dpsave.hxx"
+#include "xestream.hxx"
+#include "xistream.hxx"
+#include "xestring.hxx"
+#include "xlpivot.hxx"
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+using ::com::sun::star::sheet::GeneralFunction;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+
+namespace ScDPSortMode = ::com::sun::star::sheet::DataPilotFieldSortMode;
+namespace ScDPShowItemsMode = ::com::sun::star::sheet::DataPilotFieldShowItemsMode;
+namespace ScDPLayoutMode = ::com::sun::star::sheet::DataPilotFieldLayoutMode;
+namespace ScDPRefItemType = ::com::sun::star::sheet::DataPilotFieldReferenceItemType;
+namespace ScDPGroupBy = ::com::sun::star::sheet::DataPilotFieldGroupBy;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+XclPCItem::XclPCItem() :
+ meType( EXC_PCITEM_INVALID )
+{
+}
+
+XclPCItem::~XclPCItem()
+{
+}
+
+void XclPCItem::SetEmpty()
+{
+ meType = EXC_PCITEM_EMPTY;
+ maText.Erase();
+}
+
+void XclPCItem::SetText( const String& rText )
+{
+ meType = EXC_PCITEM_TEXT;
+ maText = rText;
+}
+
+void XclPCItem::SetDouble( double fValue )
+{
+ meType = EXC_PCITEM_DOUBLE;
+ //! TODO convert double to string
+ maText.Erase();
+ mfValue = fValue;
+}
+
+void XclPCItem::SetDateTime( const DateTime& rDateTime )
+{
+ meType = EXC_PCITEM_DATETIME;
+ //! TODO convert date to string
+ maText.Erase();
+ maDateTime = rDateTime;
+}
+
+void XclPCItem::SetInteger( sal_Int16 nValue )
+{
+ meType = EXC_PCITEM_INTEGER;
+ maText = String::CreateFromInt32( nValue );
+ mnValue = nValue;
+}
+
+void XclPCItem::SetError( sal_uInt16 nError )
+{
+ meType = EXC_PCITEM_ERROR;
+ //! TODO convert error to string
+ maText.Erase();
+ mnError = nError;
+}
+
+void XclPCItem::SetBool( bool bValue )
+{
+ meType = EXC_PCITEM_BOOL;
+ //! TODO convert boolean to string
+ maText.Erase();
+ mbValue = bValue;
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclPCItem::IsEqual( const XclPCItem& rItem ) const
+{
+ if( meType == rItem.meType ) switch( meType )
+ {
+ case EXC_PCITEM_INVALID: return true;
+ case EXC_PCITEM_EMPTY: return true;
+ case EXC_PCITEM_TEXT: return maText == rItem.maText;
+ case EXC_PCITEM_DOUBLE: return mfValue == rItem.mfValue;
+ case EXC_PCITEM_DATETIME: return maDateTime == rItem.maDateTime;
+ case EXC_PCITEM_INTEGER: return mnValue == rItem.mnValue;
+ case EXC_PCITEM_BOOL: return mbValue == rItem.mbValue;
+ case EXC_PCITEM_ERROR: return mnError == rItem.mnError;
+ default: DBG_ERRORFILE( "XclPCItem::IsEqual - unknown pivot cache item type" );
+ }
+ return false;
+}
+
+bool XclPCItem::IsEmpty() const
+{
+ return meType == EXC_PCITEM_EMPTY;
+}
+
+const String* XclPCItem::GetText() const
+{
+ return (meType == EXC_PCITEM_TEXT) ? &maText : 0;
+}
+
+const double* XclPCItem::GetDouble() const
+{
+ return (meType == EXC_PCITEM_DOUBLE) ? &mfValue : 0;
+}
+
+const DateTime* XclPCItem::GetDateTime() const
+{
+ return (meType == EXC_PCITEM_DATETIME) ? &maDateTime : 0;
+}
+
+const sal_Int16* XclPCItem::GetInteger() const
+{
+ return (meType == EXC_PCITEM_INTEGER) ? &mnValue : 0;
+}
+
+const sal_uInt16* XclPCItem::GetError() const
+{
+ return (meType == EXC_PCITEM_ERROR) ? &mnError : 0;
+}
+
+const bool* XclPCItem::GetBool() const
+{
+ return (meType == EXC_PCITEM_BOOL) ? &mbValue : 0;
+}
+
+// Field settings =============================================================
+
+XclPCFieldInfo::XclPCFieldInfo() :
+ mnFlags( 0 ),
+ mnGroupChild( 0 ),
+ mnGroupBase( 0 ),
+ mnVisItems( 0 ),
+ mnGroupItems( 0 ),
+ mnBaseItems( 0 ),
+ mnOrigItems( 0 )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo )
+{
+ rStrm >> rInfo.mnFlags
+ >> rInfo.mnGroupChild
+ >> rInfo.mnGroupBase
+ >> rInfo.mnVisItems
+ >> rInfo.mnGroupItems
+ >> rInfo.mnBaseItems
+ >> rInfo.mnOrigItems;
+ if( rStrm.GetRecLeft() >= 3 )
+ rInfo.maName = rStrm.ReadUniString();
+ else
+ rInfo.maName.Erase();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnFlags
+ << rInfo.mnGroupChild
+ << rInfo.mnGroupBase
+ << rInfo.mnVisItems
+ << rInfo.mnGroupItems
+ << rInfo.mnBaseItems
+ << rInfo.mnOrigItems
+ << XclExpString( rInfo.maName );
+}
+
+// Numeric grouping field settings ============================================
+
+XclPCNumGroupInfo::XclPCNumGroupInfo() :
+ mnFlags( EXC_SXNUMGROUP_AUTOMIN | EXC_SXNUMGROUP_AUTOMAX )
+{
+ SetNumType();
+}
+
+void XclPCNumGroupInfo::SetNumType()
+{
+ SetXclDataType( EXC_SXNUMGROUP_TYPE_NUM );
+}
+
+sal_Int32 XclPCNumGroupInfo::GetScDateType() const
+{
+ sal_Int32 nScType = 0;
+ switch( GetXclDataType() )
+ {
+ case EXC_SXNUMGROUP_TYPE_SEC: nScType = ScDPGroupBy::SECONDS; break;
+ case EXC_SXNUMGROUP_TYPE_MIN: nScType = ScDPGroupBy::MINUTES; break;
+ case EXC_SXNUMGROUP_TYPE_HOUR: nScType = ScDPGroupBy::HOURS; break;
+ case EXC_SXNUMGROUP_TYPE_DAY: nScType = ScDPGroupBy::DAYS; break;
+ case EXC_SXNUMGROUP_TYPE_MONTH: nScType = ScDPGroupBy::MONTHS; break;
+ case EXC_SXNUMGROUP_TYPE_QUART: nScType = ScDPGroupBy::QUARTERS; break;
+ case EXC_SXNUMGROUP_TYPE_YEAR: nScType = ScDPGroupBy::YEARS; break;
+ default: DBG_ERROR1( "XclPCNumGroupInfo::GetScDateType - unexpected date type %d", GetXclDataType() );
+ }
+ return nScType;
+}
+
+void XclPCNumGroupInfo::SetScDateType( sal_Int32 nScType )
+{
+ sal_uInt16 nXclType = EXC_SXNUMGROUP_TYPE_NUM;
+ switch( nScType )
+ {
+ case ScDPGroupBy::SECONDS: nXclType = EXC_SXNUMGROUP_TYPE_SEC; break;
+ case ScDPGroupBy::MINUTES: nXclType = EXC_SXNUMGROUP_TYPE_MIN; break;
+ case ScDPGroupBy::HOURS: nXclType = EXC_SXNUMGROUP_TYPE_HOUR; break;
+ case ScDPGroupBy::DAYS: nXclType = EXC_SXNUMGROUP_TYPE_DAY; break;
+ case ScDPGroupBy::MONTHS: nXclType = EXC_SXNUMGROUP_TYPE_MONTH; break;
+ case ScDPGroupBy::QUARTERS: nXclType = EXC_SXNUMGROUP_TYPE_QUART; break;
+ case ScDPGroupBy::YEARS: nXclType = EXC_SXNUMGROUP_TYPE_YEAR; break;
+ default: DBG_ERROR1( "XclPCNumGroupInfo::SetScDateType - unexpected date type %d", nScType );
+ }
+ SetXclDataType( nXclType );
+}
+
+sal_uInt16 XclPCNumGroupInfo::GetXclDataType() const
+{
+ return ::extract_value< sal_uInt16 >( mnFlags, 2, 4 );
+}
+
+void XclPCNumGroupInfo::SetXclDataType( sal_uInt16 nXclType )
+{
+ ::insert_value( mnFlags, nXclType, 2, 4 );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo )
+{
+ return rStrm >> rInfo.mnFlags;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo )
+{
+ return rStrm << rInfo.mnFlags;
+}
+
+// Base class for pivot cache fields ==========================================
+
+XclPCField::XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx ) :
+ meFieldType( eFieldType ),
+ mnFieldIdx( nFieldIdx )
+{
+}
+
+XclPCField::~XclPCField()
+{
+}
+
+bool XclPCField::IsSupportedField() const
+{
+ return (meFieldType != EXC_PCFIELD_CALCED) && (meFieldType != EXC_PCFIELD_UNKNOWN);
+}
+
+bool XclPCField::IsStandardField() const
+{
+ return meFieldType == EXC_PCFIELD_STANDARD;
+}
+
+//UNUSED2008-05 bool XclPCField::IsCalculatedField() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return meFieldType == EXC_PCFIELD_CALCED;
+//UNUSED2008-05 }
+
+bool XclPCField::IsStdGroupField() const
+{
+ return meFieldType == EXC_PCFIELD_STDGROUP;
+}
+
+bool XclPCField::IsNumGroupField() const
+{
+ return meFieldType == EXC_PCFIELD_NUMGROUP;
+}
+
+bool XclPCField::IsDateGroupField() const
+{
+ return (meFieldType == EXC_PCFIELD_DATEGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
+}
+
+bool XclPCField::IsGroupField() const
+{
+ return IsStdGroupField() || IsNumGroupField() || IsDateGroupField();
+}
+
+bool XclPCField::IsGroupBaseField() const
+{
+ return ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
+}
+
+bool XclPCField::IsGroupChildField() const
+{
+ return (meFieldType == EXC_PCFIELD_STDGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
+}
+
+sal_uInt16 XclPCField::GetBaseFieldIndex() const
+{
+ return IsGroupChildField() ? maFieldInfo.mnGroupBase : mnFieldIdx;
+}
+
+bool XclPCField::HasOrigItems() const
+{
+ return IsSupportedField() && ((maFieldInfo.mnOrigItems > 0) || HasPostponedItems());
+}
+
+bool XclPCField::HasInlineItems() const
+{
+ return (IsStandardField() || IsGroupField()) && ((maFieldInfo.mnGroupItems > 0) || (maFieldInfo.mnOrigItems > 0));
+}
+
+bool XclPCField::HasPostponedItems() const
+{
+ return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
+}
+
+bool XclPCField::Has16BitIndexes() const
+{
+ return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT );
+}
+
+// Pivot cache settings =======================================================
+
+/** Contains data for a pivot cache (SXDB record). */
+XclPCInfo::XclPCInfo() :
+ mnSrcRecs( 0 ),
+ mnStrmId( 0xFFFF ),
+ mnFlags( EXC_SXDB_DEFAULTFLAGS ),
+ mnBlockRecs( EXC_SXDB_BLOCKRECS ),
+ mnStdFields( 0 ),
+ mnTotalFields( 0 ),
+ mnSrcType( EXC_SXDB_SRC_SHEET )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo )
+{
+ rStrm >> rInfo.mnSrcRecs
+ >> rInfo.mnStrmId
+ >> rInfo.mnFlags
+ >> rInfo.mnBlockRecs
+ >> rInfo.mnStdFields
+ >> rInfo.mnTotalFields;
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mnSrcType;
+ rInfo.maUserName = rStrm.ReadUniString();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnSrcRecs
+ << rInfo.mnStrmId
+ << rInfo.mnFlags
+ << rInfo.mnBlockRecs
+ << rInfo.mnStdFields
+ << rInfo.mnTotalFields
+ << sal_uInt16( 0 )
+ << rInfo.mnSrcType
+ << XclExpString( rInfo.maUserName );
+}
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+// cached name ================================================================
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName )
+{
+ sal_uInt16 nStrLen;
+ rStrm >> nStrLen;
+ rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING;
+ if( rCachedName.mbUseCache )
+ rCachedName.maName.Erase();
+ else
+ rCachedName.maName = rStrm.ReadUniString( nStrLen );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName )
+{
+ if( rCachedName.mbUseCache )
+ rStrm << EXC_PT_NOSTRING;
+ else
+ rStrm << XclExpString( rCachedName.maName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+const String* XclPTVisNameInfo::GetVisName() const
+{
+ return HasVisName() ? &maVisName.maName : 0;
+}
+
+void XclPTVisNameInfo::SetVisName( const String& rName )
+{
+ maVisName.maName = rName;
+ maVisName.mbUseCache = rName.Len() == 0;
+}
+
+// Field item settings ========================================================
+
+XclPTItemInfo::XclPTItemInfo() :
+ mnType( EXC_SXVI_TYPE_DATA ),
+ mnFlags( EXC_SXVI_DEFAULTFLAGS ),
+ mnCacheIdx( EXC_SXVI_DEFAULT_CACHE )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo )
+{
+ return rStrm
+ >> rInfo.mnType
+ >> rInfo.mnFlags
+ >> rInfo.mnCacheIdx
+ >> rInfo.maVisName;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnType
+ << rInfo.mnFlags
+ << rInfo.mnCacheIdx
+ << rInfo.maVisName;
+}
+
+// General field settings =====================================================
+
+XclPTFieldInfo::XclPTFieldInfo() :
+ mnAxes( EXC_SXVD_AXIS_NONE ),
+ mnSubtCount( 1 ),
+ mnSubtotals( EXC_SXVD_SUBT_DEFAULT ),
+ mnItemCount( 0 ),
+ mnCacheIdx( EXC_SXVD_DEFAULT_CACHE )
+{
+}
+
+DataPilotFieldOrientation XclPTFieldInfo::GetApiOrient( sal_uInt16 nMask ) const
+{
+ using namespace ::com::sun::star::sheet;
+ DataPilotFieldOrientation eOrient = DataPilotFieldOrientation_HIDDEN;
+ sal_uInt16 nUsedAxes = mnAxes & nMask;
+ if( nUsedAxes & EXC_SXVD_AXIS_ROW )
+ eOrient = DataPilotFieldOrientation_ROW;
+ else if( nUsedAxes & EXC_SXVD_AXIS_COL )
+ eOrient = DataPilotFieldOrientation_COLUMN;
+ else if( nUsedAxes & EXC_SXVD_AXIS_PAGE )
+ eOrient = DataPilotFieldOrientation_PAGE;
+ else if( nUsedAxes & EXC_SXVD_AXIS_DATA )
+ eOrient = DataPilotFieldOrientation_DATA;
+ return eOrient;
+}
+
+void XclPTFieldInfo::AddApiOrient( DataPilotFieldOrientation eOrient )
+{
+ using namespace ::com::sun::star::sheet;
+ switch( eOrient )
+ {
+ case DataPilotFieldOrientation_ROW: mnAxes |= EXC_SXVD_AXIS_ROW; break;
+ case DataPilotFieldOrientation_COLUMN: mnAxes |= EXC_SXVD_AXIS_COL; break;
+ case DataPilotFieldOrientation_PAGE: mnAxes |= EXC_SXVD_AXIS_PAGE; break;
+ case DataPilotFieldOrientation_DATA: mnAxes |= EXC_SXVD_AXIS_DATA; break;
+ default:;
+ }
+}
+
+//! TODO: should be a Sequence<GeneralFunction> in ScDPSaveData
+void XclPTFieldInfo::GetSubtotals( XclPTSubtotalVec& rSubtotals ) const
+{
+ rSubtotals.clear();
+ rSubtotals.reserve( 16 );
+
+ using namespace ::com::sun::star::sheet;
+ if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) rSubtotals.push_back( GeneralFunction_AUTO );
+ if( mnSubtotals & EXC_SXVD_SUBT_SUM ) rSubtotals.push_back( GeneralFunction_SUM );
+ if( mnSubtotals & EXC_SXVD_SUBT_COUNT ) rSubtotals.push_back( GeneralFunction_COUNT );
+ if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) rSubtotals.push_back( GeneralFunction_AVERAGE );
+ if( mnSubtotals & EXC_SXVD_SUBT_MAX ) rSubtotals.push_back( GeneralFunction_MAX );
+ if( mnSubtotals & EXC_SXVD_SUBT_MIN ) rSubtotals.push_back( GeneralFunction_MIN );
+ if( mnSubtotals & EXC_SXVD_SUBT_PROD ) rSubtotals.push_back( GeneralFunction_PRODUCT );
+ if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) rSubtotals.push_back( GeneralFunction_COUNTNUMS );
+ if( mnSubtotals & EXC_SXVD_SUBT_STDDEV ) rSubtotals.push_back( GeneralFunction_STDEV );
+ if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) rSubtotals.push_back( GeneralFunction_STDEVP );
+ if( mnSubtotals & EXC_SXVD_SUBT_VAR ) rSubtotals.push_back( GeneralFunction_VAR );
+ if( mnSubtotals & EXC_SXVD_SUBT_VARP ) rSubtotals.push_back( GeneralFunction_VARP );
+}
+
+void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals )
+{
+ mnSubtotals = EXC_SXVD_SUBT_NONE;
+ using namespace ::com::sun::star::sheet;
+ for( XclPTSubtotalVec::const_iterator aIt = rSubtotals.begin(), aEnd = rSubtotals.end(); aIt != aEnd; ++aIt )
+ {
+ switch( *aIt )
+ {
+ case GeneralFunction_AUTO: mnSubtotals |= EXC_SXVD_SUBT_DEFAULT; break;
+ case GeneralFunction_SUM: mnSubtotals |= EXC_SXVD_SUBT_SUM; break;
+ case GeneralFunction_COUNT: mnSubtotals |= EXC_SXVD_SUBT_COUNT; break;
+ case GeneralFunction_AVERAGE: mnSubtotals |= EXC_SXVD_SUBT_AVERAGE; break;
+ case GeneralFunction_MAX: mnSubtotals |= EXC_SXVD_SUBT_MAX; break;
+ case GeneralFunction_MIN: mnSubtotals |= EXC_SXVD_SUBT_MIN; break;
+ case GeneralFunction_PRODUCT: mnSubtotals |= EXC_SXVD_SUBT_PROD; break;
+ case GeneralFunction_COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM; break;
+ case GeneralFunction_STDEV: mnSubtotals |= EXC_SXVD_SUBT_STDDEV; break;
+ case GeneralFunction_STDEVP: mnSubtotals |= EXC_SXVD_SUBT_STDDEVP; break;
+ case GeneralFunction_VAR: mnSubtotals |= EXC_SXVD_SUBT_VAR; break;
+ case GeneralFunction_VARP: mnSubtotals |= EXC_SXVD_SUBT_VARP; break;
+ }
+ }
+
+ mnSubtCount = 0;
+ for( sal_uInt16 nMask = 0x8000; nMask; nMask >>= 1 )
+ if( mnSubtotals & nMask )
+ ++mnSubtCount;
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo )
+{
+ // rInfo.mnCacheIdx is not part of the SXVD record
+ return rStrm
+ >> rInfo.mnAxes
+ >> rInfo.mnSubtCount
+ >> rInfo.mnSubtotals
+ >> rInfo.mnItemCount
+ >> rInfo.maVisName;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
+{
+ // rInfo.mnCacheIdx is not part of the SXVD record
+ return rStrm
+ << rInfo.mnAxes
+ << rInfo.mnSubtCount
+ << rInfo.mnSubtotals
+ << rInfo.mnItemCount
+ << rInfo.maVisName;
+}
+
+// Extended field settings ====================================================
+
+XclPTFieldExtInfo::XclPTFieldExtInfo() :
+ mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
+ mnSortField( EXC_SXVDEX_SORT_OWN ),
+ mnShowField( EXC_SXVDEX_SHOW_NONE ),
+ mnNumFmt(0),
+ mpFieldTotalName(NULL)
+{
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiSortMode() const
+{
+ sal_Int32 nSortMode = ScDPSortMode::MANUAL;
+ if( ::get_flag( mnFlags, EXC_SXVDEX_SORT ) )
+ nSortMode = (mnSortField == EXC_SXVDEX_SORT_OWN) ? ScDPSortMode::NAME : ScDPSortMode::DATA;
+ return nSortMode;
+}
+
+void XclPTFieldExtInfo::SetApiSortMode( sal_Int32 nSortMode )
+{
+ bool bSort = (nSortMode == ScDPSortMode::NAME) || (nSortMode == ScDPSortMode::DATA);
+ ::set_flag( mnFlags, EXC_SXVDEX_SORT, bSort );
+ if( nSortMode == ScDPSortMode::NAME )
+ mnSortField = EXC_SXVDEX_SORT_OWN; // otherwise sort field has to be set by caller
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiAutoShowMode() const
+{
+ return ::get_flagvalue( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC,
+ ScDPShowItemsMode::FROM_TOP, ScDPShowItemsMode::FROM_BOTTOM );
+}
+
+void XclPTFieldExtInfo::SetApiAutoShowMode( sal_Int32 nShowMode )
+{
+ ::set_flag( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, nShowMode == ScDPShowItemsMode::FROM_TOP );
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiAutoShowCount() const
+{
+ return ::extract_value< sal_Int32 >( mnFlags, 24, 8 );
+}
+
+void XclPTFieldExtInfo::SetApiAutoShowCount( sal_Int32 nShowCount )
+{
+ ::insert_value( mnFlags, limit_cast< sal_uInt8 >( nShowCount ), 24, 8 );
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiLayoutMode() const
+{
+ sal_Int32 nLayoutMode = ScDPLayoutMode::TABULAR_LAYOUT;
+ if( ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT ) )
+ nLayoutMode = ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP ) ?
+ ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP : ScDPLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
+ return nLayoutMode;
+}
+
+void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
+{
+ ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT, nLayoutMode != ScDPLayoutMode::TABULAR_LAYOUT );
+ ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP, nLayoutMode == ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
+{
+ sal_uInt8 nNameLen = 0;
+ rStrm >> rInfo.mnFlags
+ >> rInfo.mnSortField
+ >> rInfo.mnShowField
+ >> rInfo.mnNumFmt
+ >> nNameLen;
+
+ rStrm.Ignore(10);
+ if (nNameLen != 0xFF)
+ // Custom field total name is used. Pick it up.
+ rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
+
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
+{
+ rStrm << rInfo.mnFlags
+ << rInfo.mnSortField
+ << rInfo.mnShowField
+ << EXC_SXVDEX_FORMAT_NONE;
+
+ if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
+ {
+ rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
+ if (aFinalName.getLength() >= 254)
+ aFinalName = aFinalName.copy(0, 254);
+ sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
+ rStrm << nNameLen;
+ rStrm.WriteZeroBytes(10);
+ rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
+ }
+ else
+ {
+ rStrm << sal_uInt16(0xFFFF);
+ rStrm.WriteZeroBytes(8);
+ }
+ return rStrm;
+}
+
+// Page field settings ========================================================
+
+XclPTPageFieldInfo::XclPTPageFieldInfo() :
+ mnField( 0 ),
+ mnSelItem( EXC_SXPI_ALLITEMS ),
+ mnObjId( 0xFFFF )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo )
+{
+ return rStrm
+ >> rInfo.mnField
+ >> rInfo.mnSelItem
+ >> rInfo.mnObjId;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnField
+ << rInfo.mnSelItem
+ << rInfo.mnObjId;
+}
+
+// Data field settings ========================================================
+
+XclPTDataFieldInfo::XclPTDataFieldInfo() :
+ mnField( 0 ),
+ mnAggFunc( EXC_SXDI_FUNC_SUM ),
+ mnRefType( EXC_SXDI_REF_NORMAL ),
+ mnRefField( 0 ),
+ mnRefItem( 0 ),
+ mnNumFmt( 0 )
+{
+}
+
+GeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const
+{
+ using namespace ::com::sun::star::sheet;
+ GeneralFunction eAggFunc;
+ switch( mnAggFunc )
+ {
+ case EXC_SXDI_FUNC_SUM: eAggFunc = GeneralFunction_SUM; break;
+ case EXC_SXDI_FUNC_COUNT: eAggFunc = GeneralFunction_COUNT; break;
+ case EXC_SXDI_FUNC_AVERAGE: eAggFunc = GeneralFunction_AVERAGE; break;
+ case EXC_SXDI_FUNC_MAX: eAggFunc = GeneralFunction_MAX; break;
+ case EXC_SXDI_FUNC_MIN: eAggFunc = GeneralFunction_MIN; break;
+ case EXC_SXDI_FUNC_PRODUCT: eAggFunc = GeneralFunction_PRODUCT; break;
+ case EXC_SXDI_FUNC_COUNTNUM: eAggFunc = GeneralFunction_COUNTNUMS; break;
+ case EXC_SXDI_FUNC_STDDEV: eAggFunc = GeneralFunction_STDEV; break;
+ case EXC_SXDI_FUNC_STDDEVP: eAggFunc = GeneralFunction_STDEVP; break;
+ case EXC_SXDI_FUNC_VAR: eAggFunc = GeneralFunction_VAR; break;
+ case EXC_SXDI_FUNC_VARP: eAggFunc = GeneralFunction_VARP; break;
+ default: eAggFunc = GeneralFunction_SUM;
+ }
+ return eAggFunc;
+}
+
+void XclPTDataFieldInfo::SetApiAggFunc( GeneralFunction eAggFunc )
+{
+ using namespace ::com::sun::star::sheet;
+ switch( eAggFunc )
+ {
+ case GeneralFunction_SUM: mnAggFunc = EXC_SXDI_FUNC_SUM; break;
+ case GeneralFunction_COUNT: mnAggFunc = EXC_SXDI_FUNC_COUNT; break;
+ case GeneralFunction_AVERAGE: mnAggFunc = EXC_SXDI_FUNC_AVERAGE; break;
+ case GeneralFunction_MAX: mnAggFunc = EXC_SXDI_FUNC_MAX; break;
+ case GeneralFunction_MIN: mnAggFunc = EXC_SXDI_FUNC_MIN; break;
+ case GeneralFunction_PRODUCT: mnAggFunc = EXC_SXDI_FUNC_PRODUCT; break;
+ case GeneralFunction_COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break;
+ case GeneralFunction_STDEV: mnAggFunc = EXC_SXDI_FUNC_STDDEV; break;
+ case GeneralFunction_STDEVP: mnAggFunc = EXC_SXDI_FUNC_STDDEVP; break;
+ case GeneralFunction_VAR: mnAggFunc = EXC_SXDI_FUNC_VAR; break;
+ case GeneralFunction_VARP: mnAggFunc = EXC_SXDI_FUNC_VARP; break;
+ default: mnAggFunc = EXC_SXDI_FUNC_SUM;
+ }
+}
+
+sal_Int32 XclPTDataFieldInfo::GetApiRefType() const
+{
+ namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
+ sal_Int32 nRefType;
+ switch( mnRefType )
+ {
+ case EXC_SXDI_REF_DIFF: nRefType = ScDPRefType::ITEM_DIFFERENCE; break;
+ case EXC_SXDI_REF_PERC: nRefType = ScDPRefType::ITEM_PERCENTAGE; break;
+ case EXC_SXDI_REF_PERC_DIFF: nRefType = ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE; break;
+ case EXC_SXDI_REF_RUN_TOTAL: nRefType = ScDPRefType::RUNNING_TOTAL; break;
+ case EXC_SXDI_REF_PERC_ROW: nRefType = ScDPRefType::ROW_PERCENTAGE; break;
+ case EXC_SXDI_REF_PERC_COL: nRefType = ScDPRefType::COLUMN_PERCENTAGE; break;
+ case EXC_SXDI_REF_PERC_TOTAL: nRefType = ScDPRefType::TOTAL_PERCENTAGE; break;
+ case EXC_SXDI_REF_INDEX: nRefType = ScDPRefType::INDEX; break;
+ default: nRefType = ScDPRefType::NONE;
+ }
+ return nRefType;
+}
+
+void XclPTDataFieldInfo::SetApiRefType( sal_Int32 nRefType )
+{
+ namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
+ switch( nRefType )
+ {
+ case ScDPRefType::ITEM_DIFFERENCE: mnRefType = EXC_SXDI_REF_DIFF; break;
+ case ScDPRefType::ITEM_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC; break;
+ case ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE: mnRefType = EXC_SXDI_REF_PERC_DIFF; break;
+ case ScDPRefType::RUNNING_TOTAL: mnRefType = EXC_SXDI_REF_RUN_TOTAL; break;
+ case ScDPRefType::ROW_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_ROW; break;
+ case ScDPRefType::COLUMN_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_COL; break;
+ case ScDPRefType::TOTAL_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_TOTAL;break;
+ case ScDPRefType::INDEX: mnRefType = EXC_SXDI_REF_INDEX; break;
+ default: mnRefType = EXC_SXDI_REF_NORMAL;
+ }
+}
+
+sal_Int32 XclPTDataFieldInfo::GetApiRefItemType() const
+{
+ sal_Int32 nRefItemType;
+ switch( mnRefItem )
+ {
+ case EXC_SXDI_PREVITEM: nRefItemType = ScDPRefItemType::PREVIOUS; break;
+ case EXC_SXDI_NEXTITEM: nRefItemType = ScDPRefItemType::NEXT; break;
+ default: nRefItemType = ScDPRefItemType::NAMED;
+ }
+ return nRefItemType;
+}
+
+void XclPTDataFieldInfo::SetApiRefItemType( sal_Int32 nRefItemType )
+{
+ switch( nRefItemType )
+ {
+ case ScDPRefItemType::PREVIOUS: mnRefItem = EXC_SXDI_PREVITEM; break;
+ case ScDPRefItemType::NEXT: mnRefItem = EXC_SXDI_NEXTITEM; break;
+ // nothing for named item reference
+ }
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo )
+{
+ return rStrm
+ >> rInfo.mnField
+ >> rInfo.mnAggFunc
+ >> rInfo.mnRefType
+ >> rInfo.mnRefField
+ >> rInfo.mnRefItem
+ >> rInfo.mnNumFmt
+ >> rInfo.maVisName;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnField
+ << rInfo.mnAggFunc
+ << rInfo.mnRefType
+ << rInfo.mnRefField
+ << rInfo.mnRefItem
+ << rInfo.mnNumFmt
+ << rInfo.maVisName;
+}
+
+// Pivot table settings =======================================================
+
+XclPTInfo::XclPTInfo() :
+ mnFirstHeadRow( 0 ),
+ mnCacheIdx( 0xFFFF ),
+ mnDataAxis( EXC_SXVD_AXIS_NONE ),
+ mnDataPos( EXC_SXVIEW_DATALAST ),
+ mnFields( 0 ),
+ mnRowFields( 0 ),
+ mnColFields( 0 ),
+ mnPageFields( 0 ),
+ mnDataFields( 0 ),
+ mnDataRows( 0 ),
+ mnDataCols( 0 ),
+ mnFlags( EXC_SXVIEW_DEFAULTFLAGS ),
+ mnAutoFmtIdx( EXC_SXVIEW_AUTOFMT )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo )
+{
+ sal_uInt16 nTabLen, nDataLen;
+
+ rStrm >> rInfo.maOutXclRange
+ >> rInfo.mnFirstHeadRow
+ >> rInfo.maDataXclPos
+ >> rInfo.mnCacheIdx;
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mnDataAxis >> rInfo.mnDataPos
+ >> rInfo.mnFields
+ >> rInfo.mnRowFields >> rInfo.mnColFields
+ >> rInfo.mnPageFields >> rInfo.mnDataFields
+ >> rInfo.mnDataRows >> rInfo.mnDataCols
+ >> rInfo.mnFlags
+ >> rInfo.mnAutoFmtIdx
+ >> nTabLen >> nDataLen;
+ rInfo.maTableName = rStrm.ReadUniString( nTabLen );
+ rInfo.maDataName = rStrm.ReadUniString( nDataLen );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo )
+{
+ XclExpString aXclTableName( rInfo.maTableName );
+ XclExpString aXclDataName( rInfo.maDataName );
+
+ rStrm << rInfo.maOutXclRange
+ << rInfo.mnFirstHeadRow
+ << rInfo.maDataXclPos
+ << rInfo.mnCacheIdx
+ << sal_uInt16( 0 )
+ << rInfo.mnDataAxis << rInfo.mnDataPos
+ << rInfo.mnFields
+ << rInfo.mnRowFields << rInfo.mnColFields
+ << rInfo.mnPageFields << rInfo.mnDataFields
+ << rInfo.mnDataRows << rInfo.mnDataCols
+ << rInfo.mnFlags
+ << rInfo.mnAutoFmtIdx
+ << aXclTableName.Len() << aXclDataName.Len();
+ aXclTableName.WriteFlagField( rStrm );
+ aXclTableName.WriteBuffer( rStrm );
+ aXclDataName.WriteFlagField( rStrm );
+ aXclDataName.WriteBuffer( rStrm );
+ return rStrm;
+}
+
+// Extended pivot table settings ==============================================
+
+XclPTExtInfo::XclPTExtInfo() :
+ mnSxformulaRecs( 0 ),
+ mnSxselectRecs( 0 ),
+ mnPagePerRow( 0 ),
+ mnPagePerCol( 0 ),
+ mnFlags( EXC_SXEX_DEFAULTFLAGS )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo )
+{
+ rStrm >> rInfo.mnSxformulaRecs;
+ rStrm.Ignore( 6 );
+ return rStrm
+ >> rInfo.mnSxselectRecs
+ >> rInfo.mnPagePerRow
+ >> rInfo.mnPagePerCol
+ >> rInfo.mnFlags;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnSxformulaRecs
+ << EXC_PT_NOSTRING // length of alt. error text
+ << EXC_PT_NOSTRING // length of alt. empty text
+ << EXC_PT_NOSTRING // length of tag
+ << rInfo.mnSxselectRecs
+ << rInfo.mnPagePerRow
+ << rInfo.mnPagePerCol
+ << rInfo.mnFlags
+ << EXC_PT_NOSTRING // length of page field style name
+ << EXC_PT_NOSTRING // length of table style name
+ << EXC_PT_NOSTRING; // length of vacate style name
+}
+
+// ============================================================================
+
+// Pivot table autoformat settings ============================================
+
+/**
+classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
+report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
+report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
+report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
+report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
+report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
+report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
+report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
+report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
+report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
+table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
+table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
+table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
+table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
+table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
+table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
+table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
+table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
+table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
+table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
+none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
+**/
+
+XclPTViewEx9Info::XclPTViewEx9Info() :
+ mbReport( 0 ),
+ mnAutoFormat( 0 ),
+ mnGridLayout( 0x10 )
+{
+}
+
+void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
+{
+ if( rDPObj.GetHeaderLayout() )
+ {
+ mbReport = 0;
+ mnAutoFormat = 1;
+ mnGridLayout = 0;
+ }
+ else
+ {
+ // Report1 for now
+ // TODO : sync with autoformat indicies
+ mbReport = 2;
+ mnAutoFormat = 1;
+ mnGridLayout = 0x10;
+ }
+
+ const ScDPSaveData* pData = rDPObj.GetSaveData();
+ if (pData)
+ {
+ const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
+ if (pGrandTotal)
+ maGrandTotalName = *pGrandTotal;
+ }
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
+{
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mbReport; /// 2 for report* fmts ?
+ rStrm.Ignore( 6 );
+ rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
+ rInfo.maGrandTotalName = rStrm.ReadUniString();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
+{
+ return rStrm
+ << EXC_PT_AUTOFMT_HEADER
+ << rInfo.mbReport
+ << EXC_PT_AUTOFMT_ZERO
+ << EXC_PT_AUTOFMT_FLAGS
+ << rInfo.mnAutoFormat
+ << rInfo.mnGridLayout
+ << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
+}
+
diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx
new file mode 100644
index 000000000000..2b2180db5e6a
--- /dev/null
+++ b/sc/source/filter/excel/xlroot.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlroot.hxx"
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/stritem.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/docfile.hxx>
+#include <vcl/font.hxx>
+#include <editeng/editstat.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "docuno.hxx"
+#include "editutil.hxx"
+#include "drwlayer.hxx"
+#include "scextopt.hxx"
+#include "patattr.hxx"
+#include "fapihelper.hxx"
+#include "xlconst.hxx"
+#include "xlstyle.hxx"
+#include "xlchart.hxx"
+#include "xltracer.hxx"
+#include <unotools/useroptions.hxx>
+#include "root.hxx"
+
+namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::awt::XDevice;
+using ::com::sun::star::awt::DeviceInfo;
+using ::com::sun::star::frame::XFrame;
+using ::com::sun::star::frame::XFramesSupplier;
+using ::com::sun::star::lang::XMultiServiceFactory;
+
+// Global data ================================================================
+
+#ifdef DBG_UTIL
+XclDebugObjCounter::~XclDebugObjCounter()
+{
+ DBG_ASSERT( mnObjCnt == 0, "XclDebugObjCounter::~XclDebugObjCounter - wrong root object count" );
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) :
+ meBiff( eBiff ),
+ meOutput( EXC_OUTPUT_BINARY ),
+ mrMedium( rMedium ),
+ mxRootStrg( xRootStrg ),
+ mrDoc( rDoc ),
+ maDefPassword( CREATE_STRING( "VelvetSweatshop" ) ),
+ meTextEnc( eTextEnc ),
+ meSysLang( Application::GetSettings().GetLanguage() ),
+ meDocLang( Application::GetSettings().GetLanguage() ),
+ meUILang( Application::GetSettings().GetUILanguage() ),
+ mnDefApiScript( ApiScriptType::LATIN ),
+ maScMaxPos( MAXCOL, MAXROW, MAXTAB ),
+ maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
+ maMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
+ mxFontPropSetHlp( new XclFontPropSetHelper ),
+ mxChPropSetHlp( new XclChPropSetHelper ),
+ mxRD( new RootData ),//!
+ mfScreenPixelX( 50.0 ),
+ mfScreenPixelY( 50.0 ),
+ mnCharWidth( 110 ),
+ mnScTab( 0 ),
+ mbExport( bExport )
+{
+ maUserName = SvtUserOptions().GetLastName();
+ if( maUserName.Len() == 0 )
+ maUserName = CREATE_STRING( "Calc" );
+
+ switch( ScGlobal::GetDefaultScriptType() )
+ {
+ case SCRIPTTYPE_LATIN: mnDefApiScript = ApiScriptType::LATIN; break;
+ case SCRIPTTYPE_ASIAN: mnDefApiScript = ApiScriptType::ASIAN; break;
+ case SCRIPTTYPE_COMPLEX: mnDefApiScript = ApiScriptType::COMPLEX; break;
+ default: DBG_ERRORFILE( "XclRootData::XclRootData - unknown script type" );
+ }
+
+ // maximum cell position
+ switch( meBiff )
+ {
+ case EXC_BIFF2: maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ); break;
+ case EXC_BIFF3: maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 ); break;
+ case EXC_BIFF4: maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 ); break;
+ case EXC_BIFF5: maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 ); break;
+ case EXC_BIFF8: maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 ); break;
+ default: DBG_ERROR_BIFF();
+ }
+ maMaxPos.SetCol( ::std::min( maScMaxPos.Col(), maXclMaxPos.Col() ) );
+ maMaxPos.SetRow( ::std::min( maScMaxPos.Row(), maXclMaxPos.Row() ) );
+ maMaxPos.SetTab( ::std::min( maScMaxPos.Tab(), maXclMaxPos.Tab() ) );
+
+ // document URL and path
+ if( const SfxItemSet* pItemSet = mrMedium.GetItemSet() )
+ if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) )
+ maDocUrl = pItem->GetValue();
+ maBasePath = maDocUrl.Copy( 0, maDocUrl.SearchBackward( '/' ) + 1 );
+
+ // extended document options - always own object, try to copy existing data from document
+ if( const ScExtDocOptions* pOldDocOpt = mrDoc.GetExtDocOptions() )
+ mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) );
+ else
+ mxExtDocOpt.reset( new ScExtDocOptions );
+
+ // screen pixel size
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
+ Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW );
+ Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW );
+ Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
+ DeviceInfo aDeviceInfo = xDevice->getInfo();
+ mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0;
+ mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "XclRootData::XclRootData - cannot get output device info" );
+ }
+}
+
+XclRootData::~XclRootData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclRoot::XclRoot( XclRootData& rRootData ) :
+ mrData( rRootData )
+{
+#ifdef DBG_UTIL
+ ++mrData.mnObjCnt;
+#endif
+
+ // filter tracer
+ // do not use CREATE_OUSTRING for conditional expression
+ mrData.mxTracer.reset( new XclTracer( GetDocUrl(), OUString::createFromAscii(
+ IsExport() ? "Office.Tracing/Export/Excel" : "Office.Tracing/Import/Excel" ) ) );
+}
+
+XclRoot::XclRoot( const XclRoot& rRoot ) :
+ mrData( rRoot.mrData )
+{
+#ifdef DBG_UTIL
+ ++mrData.mnObjCnt;
+#endif
+}
+
+XclRoot::~XclRoot()
+{
+#ifdef DBG_UTIL
+ --mrData.mnObjCnt;
+#endif
+}
+
+XclRoot& XclRoot::operator=( const XclRoot& rRoot )
+{
+ (void)rRoot; // avoid compiler warning
+ // allowed for assignment in derived classes - but test if the same root data is used
+ DBG_ASSERT( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
+ return *this;
+}
+
+void XclRoot::SetTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ mrData.meTextEnc = eTextEnc;
+}
+
+void XclRoot::SetCharWidth( const XclFontData& rFontData )
+{
+ mrData.mnCharWidth = 0;
+ if( OutputDevice* pPrinter = GetPrinter() )
+ {
+ Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
+ aFont.SetFamily( rFontData.GetScFamily( GetTextEncoding() ) );
+ aFont.SetCharSet( rFontData.GetFontEncoding() );
+ aFont.SetWeight( rFontData.GetScWeight() );
+ pPrinter->SetFont( aFont );
+ mrData.mnCharWidth = pPrinter->GetTextWidth( String( '0' ) );
+ }
+ if( mrData.mnCharWidth <= 0 )
+ {
+ // #i48717# Win98 with HP LaserJet returns 0
+ DBG_ERRORFILE( "XclRoot::SetCharWidth - invalid character width (no printer?)" );
+ mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
+ }
+}
+
+sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const
+{
+ return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 );
+}
+
+sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const
+{
+ return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 );
+}
+
+String XclRoot::RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const
+{
+ ::std::vector< OUString > aDefaultPasswords;
+ aDefaultPasswords.push_back( mrData.maDefPassword );
+ return ScfApiHelper::QueryPasswordForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords );
+}
+
+bool XclRoot::HasVbaStorage() const
+{
+ SotStorageRef xRootStrg = GetRootStorage();
+ return xRootStrg.Is() && xRootStrg->IsContained( EXC_STORAGE_VBA_PROJECT );
+}
+
+SotStorageRef XclRoot::OpenStorage( SotStorageRef xStrg, const String& rStrgName ) const
+{
+ return mrData.mbExport ?
+ ScfTools::OpenStorageWrite( xStrg, rStrgName ) :
+ ScfTools::OpenStorageRead( xStrg, rStrgName );
+}
+
+SotStorageRef XclRoot::OpenStorage( const String& rStrgName ) const
+{
+ return OpenStorage( GetRootStorage(), rStrgName );
+}
+
+SotStorageStreamRef XclRoot::OpenStream( SotStorageRef xStrg, const String& rStrmName ) const
+{
+ return mrData.mbExport ?
+ ScfTools::OpenStorageStreamWrite( xStrg, rStrmName ) :
+ ScfTools::OpenStorageStreamRead( xStrg, rStrmName );
+}
+
+SotStorageStreamRef XclRoot::OpenStream( const String& rStrmName ) const
+{
+ return OpenStream( GetRootStorage(), rStrmName );
+}
+
+SfxObjectShell* XclRoot::GetDocShell() const
+{
+ return GetDoc().GetDocumentShell();
+}
+
+ScModelObj* XclRoot::GetDocModelObj() const
+{
+ SfxObjectShell* pDocShell = GetDocShell();
+ return pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : 0;
+}
+
+OutputDevice* XclRoot::GetPrinter() const
+{
+ return GetDoc().GetRefDevice();
+}
+
+ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
+{
+ return *GetDoc().GetStyleSheetPool();
+}
+
+ScRangeName& XclRoot::GetNamedRanges() const
+{
+ return *GetDoc().GetRangeName();
+}
+
+ScDBCollection& XclRoot::GetDatabaseRanges() const
+{
+ return *GetDoc().GetDBCollection();
+}
+
+SdrPage* XclRoot::GetSdrPage( SCTAB nScTab ) const
+{
+ return ((nScTab >= 0) && GetDoc().GetDrawLayer()) ?
+ GetDoc().GetDrawLayer()->GetPage( static_cast< sal_uInt16 >( nScTab ) ) : 0;
+}
+
+SvNumberFormatter& XclRoot::GetFormatter() const
+{
+ return *GetDoc().GetFormatTable();
+}
+
+DateTime XclRoot::GetNullDate() const
+{
+ return *GetFormatter().GetNullDate();
+}
+
+double XclRoot::GetDoubleFromDateTime( const DateTime& rDateTime ) const
+{
+ double fValue = rDateTime - GetNullDate();
+ // adjust dates before 1900-03-01 to get correct time values in the range [0.0,1.0)
+ if( rDateTime < DateTime( Date( 1, 3, 1900 ) ) )
+ fValue -= 1.0;
+ return fValue;
+}
+
+DateTime XclRoot::GetDateTimeFromDouble( double fValue ) const
+{
+ DateTime aDateTime = GetNullDate() + fValue;
+ // adjust dates before 1900-03-01 to get correct time values
+ if( aDateTime < DateTime( Date( 1, 3, 1900 ) ) )
+ aDateTime += 1L;
+ return aDateTime;
+}
+
+ScEditEngineDefaulter& XclRoot::GetEditEngine() const
+{
+ if( !mrData.mxEditEngine.get() )
+ {
+ mrData.mxEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) );
+ ScEditEngineDefaulter& rEE = *mrData.mxEditEngine;
+ rEE.SetRefMapMode( MAP_100TH_MM );
+ rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
+ rEE.SetUpdateMode( FALSE );
+ rEE.EnableUndo( FALSE );
+ rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
+ }
+ return *mrData.mxEditEngine;
+}
+
+ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
+{
+ if( !mrData.mxHFEditEngine.get() )
+ {
+ mrData.mxHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), TRUE ) );
+ ScHeaderEditEngine& rEE = *mrData.mxHFEditEngine;
+ rEE.SetRefMapMode( MAP_TWIP ); // headers/footers use twips as default metric
+ rEE.SetUpdateMode( FALSE );
+ rEE.EnableUndo( FALSE );
+ rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
+
+ // set Calc header/footer defaults
+ SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() );
+ SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
+ ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
+ // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
+ pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT );
+ pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK );
+ pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL );
+ rEE.SetDefaults( pEditSet ); // takes ownership
+ }
+ return *mrData.mxHFEditEngine;
+}
+
+EditEngine& XclRoot::GetDrawEditEngine() const
+{
+ if( !mrData.mxDrawEditEng.get() )
+ {
+ mrData.mxDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) );
+ EditEngine& rEE = *mrData.mxDrawEditEng;
+ rEE.SetRefMapMode( MAP_100TH_MM );
+ rEE.SetUpdateMode( FALSE );
+ rEE.EnableUndo( FALSE );
+ rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
+ }
+ return *mrData.mxDrawEditEng;
+}
+
+XclFontPropSetHelper& XclRoot::GetFontPropSetHelper() const
+{
+ return *mrData.mxFontPropSetHlp;
+}
+
+XclChPropSetHelper& XclRoot::GetChartPropSetHelper() const
+{
+ return *mrData.mxChPropSetHlp;
+}
+
+ScExtDocOptions& XclRoot::GetExtDocOptions() const
+{
+ return *mrData.mxExtDocOpt;
+}
+
+XclTracer& XclRoot::GetTracer() const
+{
+ return *mrData.mxTracer;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xlstyle.cxx b/sc/source/filter/excel/xlstyle.cxx
new file mode 100644
index 000000000000..4a48584da7fa
--- /dev/null
+++ b/sc/source/filter/excel/xlstyle.cxx
@@ -0,0 +1,1771 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xlstyle.hxx"
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/font.hxx>
+#include <rtl/tencinfo.h>
+#include <toolkit/unohlp.hxx>
+#include <editeng/svxfont.hxx>
+#include "global.hxx"
+#include "xlroot.hxx"
+
+// Color data =================================================================
+
+/** Standard EGA colors, bright. */
+#define EXC_PALETTE_EGA_COLORS_LIGHT \
+ 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
+/** Standard EGA colors, dark. */
+#define EXC_PALETTE_EGA_COLORS_DARK \
+ 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
+
+/** Default color table for BIFF2. */
+static const ColorData spnDefColorTable2[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT
+};
+
+/** Default color table for BIFF3/BIFF4. */
+static const ColorData spnDefColorTable3[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_PALETTE_EGA_COLORS_DARK
+};
+
+/** Default color table for BIFF5/BIFF7. */
+static const ColorData spnDefColorTable5[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_PALETTE_EGA_COLORS_DARK,
+/* 24 */ 0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF,
+/* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
+/* 40 */ 0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3,
+/* 48 */ 0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696,
+/* 56 */ 0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242
+};
+
+/** Default color table for BIFF8. */
+static const ColorData spnDefColorTable8[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_PALETTE_EGA_COLORS_DARK,
+/* 24 */ 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF,
+/* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
+/* 40 */ 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99,
+/* 48 */ 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696,
+/* 56 */ 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333
+};
+
+#undef EXC_PALETTE_EGA_COLORS_LIGHT
+#undef EXC_PALETTE_EGA_COLORS_DARK
+
+// ----------------------------------------------------------------------------
+
+XclDefaultPalette::XclDefaultPalette( const XclRoot& rRoot ) :
+ mpnColorTable( 0 ),
+ mnTableSize( 0 )
+{
+ const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
+ mnWindowText = rSett.GetWindowTextColor().GetColor();
+ mnWindowBack = rSett.GetWindowColor().GetColor();
+ mnFaceColor = rSett.GetFaceColor().GetColor();
+ mnNoteText = rSett.GetHelpTextColor().GetColor();
+ mnNoteBack = rSett.GetHelpColor().GetColor();
+
+ // default colors
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF2:
+ mpnColorTable = spnDefColorTable2;
+ mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable2 );
+ break;
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ mpnColorTable = spnDefColorTable3;
+ mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable3 );
+ break;
+ case EXC_BIFF5:
+ mpnColorTable = spnDefColorTable5;
+ mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable5 );
+ break;
+ case EXC_BIFF8:
+ mpnColorTable = spnDefColorTable8;
+ mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable8 );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+ColorData XclDefaultPalette::GetDefColorData( sal_uInt16 nXclIndex ) const
+{
+ ColorData nColor;
+ if( nXclIndex < mnTableSize )
+ nColor = mpnColorTable[ nXclIndex ];
+ else switch( nXclIndex )
+ {
+ case EXC_COLOR_WINDOWTEXT3:
+ case EXC_COLOR_WINDOWTEXT:
+ case EXC_COLOR_CHWINDOWTEXT: nColor = mnWindowText; break;
+ case EXC_COLOR_WINDOWBACK3:
+ case EXC_COLOR_WINDOWBACK:
+ case EXC_COLOR_CHWINDOWBACK: nColor = mnWindowBack; break;
+ case EXC_COLOR_BUTTONBACK: nColor = mnFaceColor; break;
+ case EXC_COLOR_CHBORDERAUTO: nColor = COL_BLACK; break; // TODO: really always black?
+ case EXC_COLOR_NOTEBACK: nColor = mnNoteBack; break;
+ case EXC_COLOR_NOTETEXT: nColor = mnNoteText; break;
+ case EXC_COLOR_FONTAUTO: nColor = COL_AUTO; break;
+ default:
+ DBG_ERROR1( "XclDefaultPalette::GetDefColorData - unknown default color index: %d", nXclIndex );
+ nColor = COL_AUTO;
+ }
+ return nColor;
+}
+
+// Font Data ==================================================================
+
+namespace Awt = ::com::sun::star::awt;
+namespace AwtFontFamily = Awt::FontFamily;
+namespace AwtFontUnderline = Awt::FontUnderline;
+namespace AwtFontStrikeout = Awt::FontStrikeout;
+
+// ----------------------------------------------------------------------------
+
+XclFontData::XclFontData()
+{
+ Clear();
+}
+
+XclFontData::XclFontData( const Font& rFont )
+{
+ Clear();
+ FillFromVclFont( rFont );
+}
+
+XclFontData::XclFontData( const SvxFont& rFont )
+{
+ FillFromSvxFont( rFont );
+}
+
+void XclFontData::Clear()
+{
+ maName.Erase();
+ maStyle.Erase();
+ maColor.SetColor( COL_AUTO );
+ mnHeight = 0;
+ mnWeight = EXC_FONTWGHT_DONTKNOW;
+ mnEscapem = EXC_FONTESC_NONE;
+ mnFamily = EXC_FONTFAM_SYSTEM;
+ mnCharSet = EXC_FONTCSET_ANSI_LATIN;
+ mnUnderline = EXC_FONTUNDERL_NONE;
+ mbItalic = mbStrikeout = mbOutline = mbShadow = false;
+}
+
+void XclFontData::FillFromVclFont( const Font& rFont )
+{
+ maName = XclTools::GetXclFontName( rFont.GetName() ); // #106246# substitute with MS fonts
+ maStyle.Erase();
+ maColor = rFont.GetColor();
+ SetScUnderline( rFont.GetUnderline() );
+ mnEscapem = EXC_FONTESC_NONE;
+ SetScHeight( rFont.GetSize().Height() );
+ SetScWeight( rFont.GetWeight() );
+ SetScFamily( rFont.GetFamily() );
+ SetFontEncoding( rFont.GetCharSet() );
+ SetScPosture( rFont.GetItalic() );
+ SetScStrikeout( rFont.GetStrikeout() );
+ mbOutline = rFont.IsOutline();
+ mbShadow = rFont.IsShadow();
+}
+
+void XclFontData::FillFromSvxFont( const SvxFont& rFont )
+{
+ FillFromVclFont( rFont );
+ SetScEscapement( rFont.GetEscapement() );
+}
+
+// *** conversion of VCL/SVX constants *** ------------------------------------
+
+FontFamily XclFontData::GetScFamily( rtl_TextEncoding eDefTextEnc ) const
+{
+ FontFamily eScFamily;
+ // ! format differs from Windows documentation: family is in lower nibble, pitch unknown
+ switch( mnFamily & 0x0F )
+ {
+ case EXC_FONTFAM_ROMAN: eScFamily = FAMILY_ROMAN; break;
+ case EXC_FONTFAM_SWISS: eScFamily = FAMILY_SWISS; break;
+ case EXC_FONTFAM_MODERN: eScFamily = FAMILY_MODERN; break;
+ case EXC_FONTFAM_SCRIPT: eScFamily = FAMILY_SCRIPT; break;
+ case EXC_FONTFAM_DECORATIVE: eScFamily = FAMILY_DECORATIVE; break;
+ default:
+ eScFamily =
+ ((eDefTextEnc == RTL_TEXTENCODING_APPLE_ROMAN) &&
+ (maName.EqualsIgnoreCaseAscii( "Geneva" ) || maName.EqualsIgnoreCaseAscii( "Chicago" ))) ?
+ FAMILY_SWISS : FAMILY_DONTKNOW;
+ }
+ return eScFamily;
+}
+
+rtl_TextEncoding XclFontData::GetFontEncoding() const
+{
+ // convert Windows character set to text encoding identifier
+ return rtl_getTextEncodingFromWindowsCharset( mnCharSet );
+}
+
+FontItalic XclFontData::GetScPosture() const
+{
+ return mbItalic ? ITALIC_NORMAL : ITALIC_NONE;
+}
+
+FontWeight XclFontData::GetScWeight() const
+{
+ FontWeight eScWeight;
+
+ if( !mnWeight ) eScWeight = WEIGHT_DONTKNOW;
+ else if( mnWeight < 150 ) eScWeight = WEIGHT_THIN;
+ else if( mnWeight < 250 ) eScWeight = WEIGHT_ULTRALIGHT;
+ else if( mnWeight < 325 ) eScWeight = WEIGHT_LIGHT;
+ else if( mnWeight < 375 ) eScWeight = WEIGHT_SEMILIGHT;
+ else if( mnWeight < 450 ) eScWeight = WEIGHT_NORMAL;
+ else if( mnWeight < 550 ) eScWeight = WEIGHT_MEDIUM;
+ else if( mnWeight < 650 ) eScWeight = WEIGHT_SEMIBOLD;
+ else if( mnWeight < 750 ) eScWeight = WEIGHT_BOLD;
+ else if( mnWeight < 850 ) eScWeight = WEIGHT_ULTRABOLD;
+ else eScWeight = WEIGHT_BLACK;
+
+ return eScWeight;
+}
+
+FontUnderline XclFontData::GetScUnderline() const
+{
+ FontUnderline eScUnderl = UNDERLINE_NONE;
+ switch( mnUnderline )
+ {
+ case EXC_FONTUNDERL_SINGLE:
+ case EXC_FONTUNDERL_SINGLE_ACC: eScUnderl = UNDERLINE_SINGLE; break;
+ case EXC_FONTUNDERL_DOUBLE:
+ case EXC_FONTUNDERL_DOUBLE_ACC: eScUnderl = UNDERLINE_DOUBLE; break;
+ }
+ return eScUnderl;
+}
+
+SvxEscapement XclFontData::GetScEscapement() const
+{
+ SvxEscapement eScEscapem = SVX_ESCAPEMENT_OFF;
+ switch( mnEscapem )
+ {
+ case EXC_FONTESC_SUPER: eScEscapem = SVX_ESCAPEMENT_SUPERSCRIPT; break;
+ case EXC_FONTESC_SUB: eScEscapem = SVX_ESCAPEMENT_SUBSCRIPT; break;
+ }
+ return eScEscapem;
+}
+
+FontStrikeout XclFontData::GetScStrikeout() const
+{
+ return mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE;
+}
+
+void XclFontData::SetScHeight( sal_Int32 nTwips )
+{
+ mnHeight = static_cast< sal_uInt16 >( ::std::min( nTwips, static_cast<sal_Int32>(0x7FFFL) ) );
+}
+
+void XclFontData::SetScFamily( FontFamily eScFamily )
+{
+ switch( eScFamily )
+ {
+ case FAMILY_DONTKNOW: mnFamily = EXC_FONTFAM_DONTKNOW; break;
+ case FAMILY_DECORATIVE: mnFamily = EXC_FONTFAM_DECORATIVE; break;
+ case FAMILY_MODERN: mnFamily = EXC_FONTFAM_MODERN; break;
+ case FAMILY_ROMAN: mnFamily = EXC_FONTFAM_ROMAN; break;
+ case FAMILY_SCRIPT: mnFamily = EXC_FONTFAM_SCRIPT; break;
+ case FAMILY_SWISS: mnFamily = EXC_FONTFAM_SWISS; break;
+ case FAMILY_SYSTEM: mnFamily = EXC_FONTFAM_SYSTEM; break;
+ default:
+ DBG_ERRORFILE( "XclFontData::SetScFamily - unknown font family" );
+ mnFamily = EXC_FONTFAM_DONTKNOW;
+ }
+}
+
+void XclFontData::SetFontEncoding( rtl_TextEncoding eFontEnc )
+{
+ // convert text encoding identifier to Windows character set
+ mnCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontEnc );
+}
+
+
+void XclFontData::SetScPosture( FontItalic eScPosture )
+{
+ mbItalic = (eScPosture == ITALIC_OBLIQUE) || (eScPosture == ITALIC_NORMAL);
+}
+
+void XclFontData::SetScWeight( FontWeight eScWeight )
+{
+ switch( eScWeight )
+ {
+ case WEIGHT_DONTKNOW: mnWeight = EXC_FONTWGHT_DONTKNOW; break;
+ case WEIGHT_THIN: mnWeight = EXC_FONTWGHT_THIN; break;
+ case WEIGHT_ULTRALIGHT: mnWeight = EXC_FONTWGHT_ULTRALIGHT; break;
+ case WEIGHT_LIGHT: mnWeight = EXC_FONTWGHT_LIGHT; break;
+ case WEIGHT_SEMILIGHT: mnWeight = EXC_FONTWGHT_SEMILIGHT; break;
+ case WEIGHT_NORMAL: mnWeight = EXC_FONTWGHT_NORMAL; break;
+ case WEIGHT_MEDIUM: mnWeight = EXC_FONTWGHT_MEDIUM; break;
+ case WEIGHT_SEMIBOLD: mnWeight = EXC_FONTWGHT_SEMIBOLD; break;
+ case WEIGHT_BOLD: mnWeight = EXC_FONTWGHT_BOLD; break;
+ case WEIGHT_ULTRABOLD: mnWeight = EXC_FONTWGHT_ULTRABOLD; break;
+ case WEIGHT_BLACK: mnWeight = EXC_FONTWGHT_BLACK; break;
+ default: mnWeight = EXC_FONTWGHT_NORMAL;
+ }
+}
+
+void XclFontData::SetScUnderline( FontUnderline eScUnderl )
+{
+ switch( eScUnderl )
+ {
+ case UNDERLINE_NONE:
+ case UNDERLINE_DONTKNOW: mnUnderline = EXC_FONTUNDERL_NONE; break;
+ case UNDERLINE_DOUBLE:
+ case UNDERLINE_DOUBLEWAVE: mnUnderline = EXC_FONTUNDERL_DOUBLE; break;
+ default: mnUnderline = EXC_FONTUNDERL_SINGLE;
+ }
+}
+
+void XclFontData::SetScEscapement( short nScEscapem )
+{
+ if( nScEscapem > 0 )
+ mnEscapem = EXC_FONTESC_SUPER;
+ else if( nScEscapem < 0 )
+ mnEscapem = EXC_FONTESC_SUB;
+ else
+ mnEscapem = EXC_FONTESC_NONE;
+}
+
+void XclFontData::SetScStrikeout( FontStrikeout eScStrikeout )
+{
+ mbStrikeout =
+ (eScStrikeout == STRIKEOUT_SINGLE) || (eScStrikeout == STRIKEOUT_DOUBLE) ||
+ (eScStrikeout == STRIKEOUT_BOLD) || (eScStrikeout == STRIKEOUT_SLASH) ||
+ (eScStrikeout == STRIKEOUT_X);
+}
+
+// *** conversion of API constants *** ----------------------------------------
+
+float XclFontData::GetApiHeight() const
+{
+ return static_cast< float >( mnHeight / TWIPS_PER_POINT );
+}
+
+sal_Int16 XclFontData::GetApiFamily() const
+{
+ sal_Int16 nApiFamily = AwtFontFamily::DONTKNOW;
+ switch( mnFamily )
+ {
+ case FAMILY_DECORATIVE: nApiFamily = AwtFontFamily::DECORATIVE; break;
+ case FAMILY_MODERN: nApiFamily = AwtFontFamily::MODERN; break;
+ case FAMILY_ROMAN: nApiFamily = AwtFontFamily::ROMAN; break;
+ case FAMILY_SCRIPT: nApiFamily = AwtFontFamily::SCRIPT; break;
+ case FAMILY_SWISS: nApiFamily = AwtFontFamily::SWISS; break;
+ case FAMILY_SYSTEM: nApiFamily = AwtFontFamily::SYSTEM; break;
+ }
+ return nApiFamily;
+}
+
+sal_Int16 XclFontData::GetApiFontEncoding() const
+{
+ // API constants are equal to rtl_TextEncoding constants
+ return static_cast< sal_Int16 >( GetFontEncoding() );
+}
+
+Awt::FontSlant XclFontData::GetApiPosture() const
+{
+ return mbItalic ? Awt::FontSlant_ITALIC : Awt::FontSlant_NONE;
+}
+
+float XclFontData::GetApiWeight() const
+{
+ return VCLUnoHelper::ConvertFontWeight( GetScWeight() );
+}
+
+sal_Int16 XclFontData::GetApiUnderline() const
+{
+ sal_Int16 nApiUnderl = AwtFontUnderline::NONE;
+ switch( mnUnderline )
+ {
+ case EXC_FONTUNDERL_SINGLE:
+ case EXC_FONTUNDERL_SINGLE_ACC: nApiUnderl = AwtFontUnderline::SINGLE; break;
+ case EXC_FONTUNDERL_DOUBLE:
+ case EXC_FONTUNDERL_DOUBLE_ACC: nApiUnderl = AwtFontUnderline::DOUBLE; break;
+ }
+ return nApiUnderl;
+}
+
+sal_Int16 XclFontData::GetApiEscapement() const
+{
+ sal_Int16 nApiEscapem = 0;
+ switch( mnEscapem )
+ {
+ case EXC_FONTESC_SUPER: nApiEscapem = 33; break;
+ case EXC_FONTESC_SUB: nApiEscapem = -33; break;
+ }
+ return nApiEscapem;
+}
+
+sal_Int16 XclFontData::GetApiStrikeout() const
+{
+ return mbStrikeout ? AwtFontStrikeout::SINGLE : AwtFontStrikeout::NONE;
+}
+
+void XclFontData::SetApiHeight( float fPoint )
+{
+ mnHeight = static_cast< sal_uInt16 >( ::std::min( fPoint * TWIPS_PER_POINT + 0.5, 32767.0 ) );
+}
+
+void XclFontData::SetApiFamily( sal_Int16 nApiFamily )
+{
+ switch( nApiFamily )
+ {
+ case AwtFontFamily::DECORATIVE: mnFamily = FAMILY_DECORATIVE; break;
+ case AwtFontFamily::MODERN: mnFamily = FAMILY_MODERN; break;
+ case AwtFontFamily::ROMAN: mnFamily = FAMILY_ROMAN; break;
+ case AwtFontFamily::SCRIPT: mnFamily = FAMILY_SCRIPT; break;
+ case AwtFontFamily::SWISS: mnFamily = FAMILY_SWISS; break;
+ case AwtFontFamily::SYSTEM: mnFamily = FAMILY_SYSTEM; break;
+ default: mnFamily = FAMILY_DONTKNOW;
+ }
+}
+
+//UNUSED2009-05 void XclFontData::SetApiFontEncoding( sal_Int16 nApiFontEnc )
+//UNUSED2009-05 {
+//UNUSED2009-05 // API constants are equal to rtl_TextEncoding constants
+//UNUSED2009-05 SetFontEncoding( static_cast< rtl_TextEncoding >( nApiFontEnc ) );
+//UNUSED2009-05 }
+
+void XclFontData::SetApiPosture( Awt::FontSlant eApiPosture )
+{
+ mbItalic =
+ (eApiPosture == Awt::FontSlant_OBLIQUE) ||
+ (eApiPosture == Awt::FontSlant_ITALIC) ||
+ (eApiPosture == Awt::FontSlant_REVERSE_OBLIQUE) ||
+ (eApiPosture == Awt::FontSlant_REVERSE_ITALIC);
+}
+
+void XclFontData::SetApiWeight( float fApiWeight )
+{
+ SetScWeight( VCLUnoHelper::ConvertFontWeight( fApiWeight ) );
+}
+
+void XclFontData::SetApiUnderline( sal_Int16 nApiUnderl )
+{
+ switch( nApiUnderl )
+ {
+ case AwtFontUnderline::NONE:
+ case AwtFontUnderline::DONTKNOW: mnUnderline = EXC_FONTUNDERL_NONE; break;
+ case AwtFontUnderline::DOUBLE:
+ case AwtFontUnderline::DOUBLEWAVE: mnUnderline = EXC_FONTUNDERL_DOUBLE; break;
+ default: mnUnderline = EXC_FONTUNDERL_SINGLE;
+ }
+}
+
+void XclFontData::SetApiEscapement( sal_Int16 nApiEscapem )
+{
+ if( nApiEscapem > 0 )
+ mnEscapem = EXC_FONTESC_SUPER;
+ else if( nApiEscapem < 0 )
+ mnEscapem = EXC_FONTESC_SUB;
+ else
+ mnEscapem = EXC_FONTESC_NONE;
+}
+
+void XclFontData::SetApiStrikeout( sal_Int16 nApiStrikeout )
+{
+ mbStrikeout =
+ (nApiStrikeout != AwtFontStrikeout::NONE) &&
+ (nApiStrikeout != AwtFontStrikeout::DONTKNOW);
+}
+
+// ----------------------------------------------------------------------------
+
+bool operator==( const XclFontData& rLeft, const XclFontData& rRight )
+{
+ return
+ (rLeft.mnHeight == rRight.mnHeight) &&
+ (rLeft.mnWeight == rRight.mnWeight) &&
+ (rLeft.mnUnderline == rRight.mnUnderline) &&
+ (rLeft.maColor == rRight.maColor) &&
+ (rLeft.mnEscapem == rRight.mnEscapem) &&
+ (rLeft.mnFamily == rRight.mnFamily) &&
+ (rLeft.mnCharSet == rRight.mnCharSet) &&
+ (rLeft.mbItalic == rRight.mbItalic) &&
+ (rLeft.mbStrikeout == rRight.mbStrikeout) &&
+ (rLeft.mbOutline == rRight.mbOutline) &&
+ (rLeft.mbShadow == rRight.mbShadow) &&
+ (rLeft.maName == rRight.maName);
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Property names for common font settings. */
+const sal_Char *const sppcPropNamesChCommon[] =
+{
+ "CharUnderline", "CharStrikeout", "CharColor", "CharContoured", "CharShadowed", 0
+};
+/** Property names for Western font settings. */
+const sal_Char *const sppcPropNamesChWstrn[] =
+{
+ "CharFontName", "CharHeight", "CharPosture", "CharWeight", 0
+};
+/** Property names for Asian font settings. */
+const sal_Char *const sppcPropNamesChAsian[] =
+{
+ "CharFontNameAsian", "CharHeightAsian", "CharPostureAsian", "CharWeightAsian", 0
+};
+/** Property names for Complex font settings. */
+const sal_Char *const sppcPropNamesChCmplx[] =
+{
+ "CharFontNameComplex", "CharHeightComplex", "CharPostureComplex", "CharWeightComplex", 0
+};
+/** Property names for escapement. */
+const sal_Char *const sppcPropNamesChEscapement[] =
+{
+ "CharEscapement", "CharEscapementHeight", 0
+};
+const sal_Int8 EXC_API_ESC_HEIGHT = 58; /// Default escapement font height.
+
+/** Property names for Western font settings without font name. */
+const sal_Char *const *const sppcPropNamesChWstrnNoName = sppcPropNamesChWstrn + 1;
+/** Property names for Asian font settings without font name. */
+const sal_Char *const *const sppcPropNamesChAsianNoName = sppcPropNamesChAsian + 1;
+/** Property names for Complex font settings without font name. */
+const sal_Char *const *const sppcPropNamesChCmplxNoName = sppcPropNamesChCmplx + 1;
+
+/** Property names for font settings in form controls. */
+const sal_Char *const sppcPropNamesControl[] =
+{
+ "FontName", "FontFamily", "FontCharset", "FontHeight", "FontSlant",
+ "FontWeight", "FontUnderline", "FontStrikeout", "TextColor", 0
+};
+
+/** Inserts all passed API font settings into the font data object. */
+void lclSetApiFontSettings( XclFontData& rFontData,
+ const String& rApiFontName, float fApiHeight, float fApiWeight,
+ Awt::FontSlant eApiPosture, sal_Int16 nApiUnderl, sal_Int16 nApiStrikeout )
+{
+ rFontData.maName = XclTools::GetXclFontName( rApiFontName );
+ rFontData.SetApiHeight( fApiHeight );
+ rFontData.SetApiWeight( fApiWeight );
+ rFontData.SetApiPosture( eApiPosture );
+ rFontData.SetApiUnderline( nApiUnderl );
+ rFontData.SetApiStrikeout( nApiStrikeout );
+}
+
+/** Writes script dependent properties to a font property set helper. */
+void lclWriteChartFont( ScfPropertySet& rPropSet,
+ ScfPropSetHelper& rHlpName, ScfPropSetHelper& rHlpNoName,
+ const XclFontData& rFontData, bool bHasFontName )
+{
+ // select the font helper
+ ScfPropSetHelper& rPropSetHlp = bHasFontName ? rHlpName : rHlpNoName;
+ // initialize the font helper (must be called before writing any properties)
+ rPropSetHlp.InitializeWrite();
+ // write font name
+ if( bHasFontName )
+ rPropSetHlp << rFontData.maName;
+ // write remaining properties
+ rPropSetHlp << rFontData.GetApiHeight() << rFontData.GetApiPosture() << rFontData.GetApiWeight();
+ // write properties to property set
+ rPropSetHlp.WriteToPropertySet( rPropSet );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclFontPropSetHelper::XclFontPropSetHelper() :
+ maHlpChCommon( sppcPropNamesChCommon ),
+ maHlpChWstrn( sppcPropNamesChWstrn ),
+ maHlpChAsian( sppcPropNamesChAsian ),
+ maHlpChCmplx( sppcPropNamesChCmplx ),
+ maHlpChWstrnNoName( sppcPropNamesChWstrnNoName ),
+ maHlpChAsianNoName( sppcPropNamesChAsianNoName ),
+ maHlpChCmplxNoName( sppcPropNamesChCmplxNoName ),
+ maHlpChEscapement( sppcPropNamesChEscapement ),
+ maHlpControl( sppcPropNamesControl )
+{
+}
+
+void XclFontPropSetHelper::ReadFontProperties( XclFontData& rFontData,
+ const ScfPropertySet& rPropSet, XclFontPropSetType eType, sal_Int16 nScript )
+{
+ switch( eType )
+ {
+ case EXC_FONTPROPSET_CHART:
+ {
+ String aApiFontName;
+ float fApiHeight, fApiWeight;
+ sal_Int16 nApiUnderl = 0, nApiStrikeout = 0;
+ Awt::FontSlant eApiPosture;
+
+ // read script type dependent properties
+ ScfPropSetHelper& rPropSetHlp = GetChartHelper( nScript );
+ rPropSetHlp.ReadFromPropertySet( rPropSet );
+ rPropSetHlp >> aApiFontName >> fApiHeight >> eApiPosture >> fApiWeight;
+ // read common properties
+ maHlpChCommon.ReadFromPropertySet( rPropSet );
+ maHlpChCommon >> nApiUnderl
+ >> nApiStrikeout
+ >> rFontData.maColor
+ >> rFontData.mbOutline
+ >> rFontData.mbShadow;
+
+ // convert API property values to Excel settings
+ lclSetApiFontSettings( rFontData, aApiFontName,
+ fApiHeight, fApiWeight, eApiPosture, nApiUnderl, nApiStrikeout );
+
+ // font escapement
+ sal_Int16 nApiEscapement = 0;
+ sal_Int8 nApiEscHeight = 0;
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement >> nApiEscapement >> nApiEscHeight;
+ rFontData.SetApiEscapement( nApiEscapement );
+ }
+ break;
+
+ case EXC_FONTPROPSET_CONTROL:
+ {
+ String aApiFontName;
+ float fApiHeight, fApiWeight;
+ sal_Int16 nApiFamily, nApiCharSet, nApiPosture, nApiUnderl, nApiStrikeout;
+
+ // read font properties
+ maHlpControl.ReadFromPropertySet( rPropSet );
+ maHlpControl >> aApiFontName
+ >> nApiFamily
+ >> nApiCharSet
+ >> fApiHeight
+ >> nApiPosture
+ >> fApiWeight
+ >> nApiUnderl
+ >> nApiStrikeout
+ >> rFontData.maColor;
+
+ // convert API property values to Excel settings
+ Awt::FontSlant eApiPosture = static_cast< Awt::FontSlant >( nApiPosture );
+ lclSetApiFontSettings( rFontData, aApiFontName,
+ fApiHeight, fApiWeight, eApiPosture, nApiUnderl, nApiStrikeout );
+ rFontData.SetApiFamily( nApiFamily );
+ rFontData.SetFontEncoding( nApiCharSet );
+ }
+ break;
+ }
+}
+
+void XclFontPropSetHelper::WriteFontProperties(
+ ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ const XclFontData& rFontData, bool bHasWstrn, bool bHasAsian, bool bHasCmplx,
+ const Color* pFontColor )
+{
+ switch( eType )
+ {
+ case EXC_FONTPROPSET_CHART:
+ {
+ // write common properties
+ maHlpChCommon.InitializeWrite();
+ const Color& rColor = pFontColor ? *pFontColor : rFontData.maColor;
+ maHlpChCommon << rFontData.GetApiUnderline()
+ << rFontData.GetApiStrikeout()
+ << rColor
+ << rFontData.mbOutline
+ << rFontData.mbShadow;
+ maHlpChCommon.WriteToPropertySet( rPropSet );
+
+ // write script type dependent properties
+ lclWriteChartFont( rPropSet, maHlpChWstrn, maHlpChWstrnNoName, rFontData, bHasWstrn );
+ lclWriteChartFont( rPropSet, maHlpChAsian, maHlpChAsianNoName, rFontData, bHasAsian );
+ lclWriteChartFont( rPropSet, maHlpChCmplx, maHlpChCmplxNoName, rFontData, bHasCmplx );
+
+ // font escapement
+ if( rFontData.GetScEscapement() != SVX_ESCAPEMENT_OFF )
+ {
+ maHlpChEscapement.InitializeWrite();
+ maHlpChEscapement << rFontData.GetApiEscapement() << EXC_API_ESC_HEIGHT;
+ maHlpChEscapement.WriteToPropertySet( rPropSet );
+ }
+ }
+ break;
+
+ case EXC_FONTPROPSET_CONTROL:
+ {
+ maHlpControl.InitializeWrite();
+ maHlpControl << rFontData.maName
+ << rFontData.GetApiFamily()
+ << rFontData.GetApiFontEncoding()
+ << static_cast< sal_Int16 >( rFontData.GetApiHeight() + 0.5 )
+ << rFontData.GetApiPosture()
+ << rFontData.GetApiWeight()
+ << rFontData.GetApiUnderline()
+ << rFontData.GetApiStrikeout()
+ << rFontData.maColor;
+ maHlpControl.WriteToPropertySet( rPropSet );
+ }
+ break;
+ }
+}
+
+ScfPropSetHelper& XclFontPropSetHelper::GetChartHelper( sal_Int16 nScript )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ switch( nScript )
+ {
+ case ApiScriptType::LATIN: return maHlpChWstrn;
+ case ApiScriptType::ASIAN: return maHlpChAsian;
+ case ApiScriptType::COMPLEX: return maHlpChCmplx;
+ default: DBG_ERRORFILE( "XclFontPropSetHelper::GetChartHelper - unknown script type" );
+ }
+ return maHlpChWstrn;
+}
+
+// Number formats =============================================================
+
+namespace {
+
+// ----------------------------------------------------------------------------
+
+/** Special number format index describing a reused format. */
+const NfIndexTableOffset PRV_NF_INDEX_REUSE = NF_INDEX_TABLE_ENTRIES;
+
+/** German primary language not defined, LANGUAGE_GERMAN belongs to Germany. */
+const LanguageType PRV_LANGUAGE_GERMAN_PRIM = LANGUAGE_GERMAN & LANGUAGE_MASK_PRIMARY;
+/** French primary language not defined, LANGUAGE_FRENCH belongs to France. */
+const LanguageType PRV_LANGUAGE_FRENCH_PRIM = LANGUAGE_FRENCH & LANGUAGE_MASK_PRIMARY;
+/** Parent language identifier for Asian languages (LANGUAGE_CHINESE is a primary only ID). */
+const LanguageType PRV_LANGUAGE_ASIAN_PRIM = LANGUAGE_CHINESE;
+
+// ----------------------------------------------------------------------------
+
+/** Stores the number format used in Calc for an Excel built-in number format. */
+struct XclBuiltInFormat
+{
+ sal_uInt16 mnXclNumFmt; /// Excel built-in index.
+ const sal_Char* mpFormat; /// Format string, may be 0 (meOffset used then).
+ NfIndexTableOffset meOffset; /// SvNumberFormatter format index, if mpFormat==0.
+ sal_uInt16 mnXclReuseFmt; /// Use this Excel format, if meOffset==PRV_NF_INDEX_REUSE.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Defines a literal Excel built-in number format. */
+#define EXC_NUMFMT_STRING( nXclNumFmt, pcUtf8 ) \
+ { nXclNumFmt, pcUtf8, NF_NUMBER_STANDARD, 0 }
+
+/** Defines an Excel built-in number format that maps to an own built-in format. */
+#define EXC_NUMFMT_OFFSET( nXclNumFmt, eOffset ) \
+ { nXclNumFmt, 0, eOffset, 0 }
+
+/** Defines an Excel built-in number format that is the same as the specified. */
+#define EXC_NUMFMT_REUSE( nXclNumFmt, nXclReuse ) \
+ { nXclNumFmt, 0, PRV_NF_INDEX_REUSE, nXclReuse }
+
+/** Terminates an Excel built-in number format table. */
+#define EXC_NUMFMT_ENDTABLE() \
+ { EXC_FORMAT_NOTFOUND, 0, NF_NUMBER_STANDARD, 0 }
+
+// ----------------------------------------------------------------------------
+
+// Currency unit characters
+#define UTF8_BAHT "\340\270\277"
+#define UTF8_EURO "\342\202\254"
+#define UTF8_POUND_UK "\302\243"
+#define UTF8_SHEQEL "\342\202\252"
+#define UTF8_WON "\357\277\246"
+#define UTF8_YEN_CS "\357\277\245"
+#define UTF8_YEN_JP "\302\245"
+
+// Japanese/Chinese date/time characters
+#define UTF8_CJ_YEAR "\345\271\264"
+#define UTF8_CJ_MON "\346\234\210"
+#define UTF8_CJ_DAY "\346\227\245"
+#define UTF8_CJ_HOUR "\346\231\202"
+#define UTF8_CJ_MIN "\345\210\206"
+#define UTF8_CJ_SEC "\347\247\222"
+
+// Chinese Simplified date/time characters
+#define UTF8_CS_HOUR "\346\227\266"
+
+// Korean date/time characters
+#define UTF8_KO_YEAR "\353\205\204"
+#define UTF8_KO_MON "\354\233\224"
+#define UTF8_KO_DAY "\354\235\274"
+#define UTF8_KO_HOUR "\354\213\234"
+#define UTF8_KO_MIN "\353\266\204"
+#define UTF8_KO_SEC "\354\264\210"
+
+// ----------------------------------------------------------------------------
+
+/** Default number format table. Last parent of all other tables, used for unknown languages. */
+static const XclBuiltInFormat spBuiltInFormats_DONTKNOW[] =
+{
+ EXC_NUMFMT_OFFSET( 0, NF_NUMBER_STANDARD ), // General
+ EXC_NUMFMT_OFFSET( 1, NF_NUMBER_INT ), // 0
+ EXC_NUMFMT_OFFSET( 2, NF_NUMBER_DEC2 ), // 0.00
+ EXC_NUMFMT_OFFSET( 3, NF_NUMBER_1000INT ), // #,##0
+ EXC_NUMFMT_OFFSET( 4, NF_NUMBER_1000DEC2 ), // #,##0.00
+ // 5...8 contained in file
+ EXC_NUMFMT_OFFSET( 9, NF_PERCENT_INT ), // 0%
+ EXC_NUMFMT_OFFSET( 10, NF_PERCENT_DEC2 ), // 0.00%
+ EXC_NUMFMT_OFFSET( 11, NF_SCIENTIFIC_000E00 ), // 0.00E+00
+ EXC_NUMFMT_OFFSET( 12, NF_FRACTION_1 ), // # ?/?
+ EXC_NUMFMT_OFFSET( 13, NF_FRACTION_2 ), // # ??/??
+
+ // 14...22 date and time formats
+ EXC_NUMFMT_OFFSET( 14, NF_DATE_SYS_DDMMYYYY ),
+ EXC_NUMFMT_OFFSET( 15, NF_DATE_SYS_DMMMYY ),
+ EXC_NUMFMT_OFFSET( 16, NF_DATE_SYS_DDMMM ),
+ EXC_NUMFMT_OFFSET( 17, NF_DATE_SYS_MMYY ),
+ EXC_NUMFMT_OFFSET( 18, NF_TIME_HHMMAMPM ),
+ EXC_NUMFMT_OFFSET( 19, NF_TIME_HHMMSSAMPM ),
+ EXC_NUMFMT_OFFSET( 20, NF_TIME_HHMM ),
+ EXC_NUMFMT_OFFSET( 21, NF_TIME_HHMMSS ),
+ EXC_NUMFMT_OFFSET( 22, NF_DATETIME_SYSTEM_SHORT_HHMM ),
+
+ // 23...36 international formats
+ EXC_NUMFMT_REUSE( 23, 0 ),
+ EXC_NUMFMT_REUSE( 24, 0 ),
+ EXC_NUMFMT_REUSE( 25, 0 ),
+ EXC_NUMFMT_REUSE( 26, 0 ),
+ EXC_NUMFMT_REUSE( 27, 14 ),
+ EXC_NUMFMT_REUSE( 28, 14 ),
+ EXC_NUMFMT_REUSE( 29, 14 ),
+ EXC_NUMFMT_REUSE( 30, 14 ),
+ EXC_NUMFMT_REUSE( 31, 14 ),
+ EXC_NUMFMT_REUSE( 32, 21 ),
+ EXC_NUMFMT_REUSE( 33, 21 ),
+ EXC_NUMFMT_REUSE( 34, 21 ),
+ EXC_NUMFMT_REUSE( 35, 21 ),
+ EXC_NUMFMT_REUSE( 36, 14 ),
+
+ // 37...44 accounting formats
+ // 41...44 contained in file
+ EXC_NUMFMT_STRING( 37, "#,##0;-#,##0" ),
+ EXC_NUMFMT_STRING( 38, "#,##0;[RED]-#,##0" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00;-#,##0.00" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00;[RED]-#,##0.00" ),
+
+ // 45...49 more special formats
+ EXC_NUMFMT_STRING( 45, "mm:ss" ),
+ EXC_NUMFMT_STRING( 46, "[h]:mm:ss" ),
+ EXC_NUMFMT_STRING( 47, "mm:ss.0" ),
+ EXC_NUMFMT_STRING( 48, "##0.0E+0" ),
+ EXC_NUMFMT_OFFSET( 49, NF_TEXT ),
+
+ // 50...81 international formats
+ EXC_NUMFMT_REUSE( 50, 14 ),
+ EXC_NUMFMT_REUSE( 51, 14 ),
+ EXC_NUMFMT_REUSE( 52, 14 ),
+ EXC_NUMFMT_REUSE( 53, 14 ),
+ EXC_NUMFMT_REUSE( 54, 14 ),
+ EXC_NUMFMT_REUSE( 55, 14 ),
+ EXC_NUMFMT_REUSE( 56, 14 ),
+ EXC_NUMFMT_REUSE( 57, 14 ),
+ EXC_NUMFMT_REUSE( 58, 14 ),
+ EXC_NUMFMT_REUSE( 59, 1 ),
+ EXC_NUMFMT_REUSE( 60, 2 ),
+ EXC_NUMFMT_REUSE( 61, 3 ),
+ EXC_NUMFMT_REUSE( 62, 4 ),
+ EXC_NUMFMT_REUSE( 67, 9 ),
+ EXC_NUMFMT_REUSE( 68, 10 ),
+ EXC_NUMFMT_REUSE( 69, 12 ),
+ EXC_NUMFMT_REUSE( 70, 13 ),
+ EXC_NUMFMT_REUSE( 71, 14 ),
+ EXC_NUMFMT_REUSE( 72, 14 ),
+ EXC_NUMFMT_REUSE( 73, 15 ),
+ EXC_NUMFMT_REUSE( 74, 16 ),
+ EXC_NUMFMT_REUSE( 75, 17 ),
+ EXC_NUMFMT_REUSE( 76, 20 ),
+ EXC_NUMFMT_REUSE( 77, 21 ),
+ EXC_NUMFMT_REUSE( 78, 22 ),
+ EXC_NUMFMT_REUSE( 79, 45 ),
+ EXC_NUMFMT_REUSE( 80, 46 ),
+ EXC_NUMFMT_REUSE( 81, 47 ),
+
+ // 82...163 not used, must not occur in a file (Excel may crash)
+
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ENGLISH --------------------------------------------------------------------
+
+/** Base table for English locales. */
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY hh:mm" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_UK[] =
+{
+ EXC_NUMFMT_STRING( 63, UTF8_POUND_UK "#,##0;-" UTF8_POUND_UK "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_POUND_UK "#,##0;[RED]-" UTF8_POUND_UK "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_POUND_UK "#,##0.00;-" UTF8_POUND_UK "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_POUND_UK "#,##0.00;[RED]-" UTF8_POUND_UK "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_EIRE[] =
+{
+ EXC_NUMFMT_STRING( 63, UTF8_EURO "#,##0;-" UTF8_EURO "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_EURO "#,##0;[RED]-" UTF8_EURO "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_EURO "#,##0.00;-" UTF8_EURO "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_EURO "#,##0.00;[RED]-" UTF8_EURO "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_US[] =
+{
+ EXC_NUMFMT_STRING( 14, "M/D/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "M/D/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0_);(#,##0)" ),
+ EXC_NUMFMT_STRING( 38, "#,##0_);[RED](#,##0)" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00_);(#,##0.00)" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00_);[RED](#,##0.00)" ),
+ EXC_NUMFMT_STRING( 63, "$#,##0_);($#,##0)" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0_);[RED]($#,##0)" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00_);($#,##0.00)" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00_);[RED]($#,##0.00)" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_CAN[] =
+{
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 63, "$#,##0;-$#,##0" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0;[RED]-$#,##0" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00;-$#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00;[RED]-$#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_AUS[] =
+{
+ EXC_NUMFMT_STRING( 14, "D/MM/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "D/MM/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 63, "$#,##0;-$#,##0" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0;[RED]-$#,##0" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00;-$#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00;[RED]-$#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_SAFRICA[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY/MM/DD" ),
+ EXC_NUMFMT_OFFSET( 18, NF_TIME_HHMMAMPM ),
+ EXC_NUMFMT_OFFSET( 19, NF_TIME_HHMMSSAMPM ),
+ EXC_NUMFMT_STRING( 22, "YYYY/MM/DD hh:mm" ),
+ EXC_NUMFMT_STRING( 63, "\\R #,##0;\\R -#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\\R #,##0;[RED]\\R -#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\\R #,##0.00;\\R -#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\\R #,##0.00;[RED]\\R -#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// FRENCH ---------------------------------------------------------------------
+
+/** Base table for French locales. */
+static const XclBuiltInFormat spBuiltInFormats_FRENCH[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_FRANCE[] =
+{
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0\\ _" UTF8_EURO ";-#,##0\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0\\ _" UTF8_EURO ";[RED]-#,##0\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00\\ _" UTF8_EURO ";-#,##0.00\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00\\ _" UTF8_EURO ";[RED]-#,##0.00\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0\\ " UTF8_EURO ";-#,##0\\ " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0\\ " UTF8_EURO ";[RED]-#,##0\\ " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00\\ " UTF8_EURO ";-#,##0.00\\ " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00\\ " UTF8_EURO ";[RED]-#,##0.00\\ " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_CANADIAN[] =
+{
+ EXC_NUMFMT_STRING( 22, "YYYY-MM-DD hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0\\ _$_-;#,##0\\ _$-" ),
+ EXC_NUMFMT_STRING( 38, "#,##0\\ _$_-;[RED]#,##0\\ _$-" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00\\ _$_-;#,##0.00\\ _$-" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00\\ _$_-;[RED]#,##0.00\\ _$-" ),
+ EXC_NUMFMT_STRING( 63, "#,##0\\ $_-;#,##0\\ $-" ),
+ EXC_NUMFMT_STRING( 64, "#,##0\\ $_-;[RED]#,##0\\ $-" ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00\\ $_-;#,##0.00\\ $-" ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00\\ $_-;[RED]#,##0.00\\ $-" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_SWISS[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 22, "DD.MM.YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_BELGIAN[] =
+{
+ EXC_NUMFMT_STRING( 14, "D/MM/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "D/MM/YYYY h:mm" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// GERMAN ---------------------------------------------------------------------
+
+/** Base table for German locales. */
+static const XclBuiltInFormat spBuiltInFormats_GERMAN[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD. MMM YY" ),
+ EXC_NUMFMT_STRING( 16, "DD. MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "DD.MM.YYYY hh:mm" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_GERMANY[] =
+{
+ EXC_NUMFMT_STRING( 37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_AUSTRIAN[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 63, UTF8_EURO " #,##0;-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_EURO " #,##0;[RED]-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_EURO " #,##0.00;-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_EURO " #,##0.00;[RED]-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_SWISS[] =
+{
+ EXC_NUMFMT_STRING( 63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_LUXEMBOURG[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_LIECHTENSTEIN[] =
+{
+ EXC_NUMFMT_STRING( 63, "\"CHF \"#,##0;\"CHF \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"CHF \"#,##0;[RED]\"CHF \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"CHF \"#,##0.00;\"CHF \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"CHF \"#,##0.00;[RED]\"CHF \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ITALIAN --------------------------------------------------------------------
+
+static const XclBuiltInFormat spBuiltInFormats_ITALIAN_ITALY[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 63, UTF8_EURO " #,##0;-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_EURO " #,##0;[RED]-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_EURO " #,##0.00;-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_EURO " #,##0.00;[RED]-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ITALIAN_SWISS[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "DD.MM.YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// SWEDISH --------------------------------------------------------------------
+
+static const XclBuiltInFormat spBuiltInFormats_SWEDISH_SWEDEN[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "YYYY-MM-DD hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0 _k_r;-#,##0 _k_r" ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _k_r;[RED]-#,##0 _k_r" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _k_r;-#,##0.00 _k_r" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _k_r;[RED]-#,##0.00 _k_r" ),
+ EXC_NUMFMT_STRING( 63, "#,##0 \"kr\";-#,##0 \"kr\"" ),
+ EXC_NUMFMT_STRING( 64, "#,##0 \"kr\";[RED]-#,##0 \"kr\"" ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 \"kr\";-#,##0.00 \"kr\"" ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 \"kr\";[RED]-#,##0.00 \"kr\"" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_SWEDISH_FINLAND[] =
+{
+ EXC_NUMFMT_STRING( 9, "0 %" ),
+ EXC_NUMFMT_STRING( 10, "0.00 %" ),
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "D.M.YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ASIAN ----------------------------------------------------------------------
+
+/** Base table for Asian locales. */
+static const XclBuiltInFormat spBuiltInFormats_ASIAN[] =
+{
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 23, "$#,##0_);($#,##0)" ),
+ EXC_NUMFMT_STRING( 24, "$#,##0_);[RED]($#,##0)" ),
+ EXC_NUMFMT_STRING( 25, "$#,##0.00_);($#,##0.00)" ),
+ EXC_NUMFMT_STRING( 26, "$#,##0.00_);[RED]($#,##0.00)" ),
+ EXC_NUMFMT_REUSE( 29, 28 ),
+ EXC_NUMFMT_REUSE( 36, 27 ),
+ EXC_NUMFMT_REUSE( 50, 27 ),
+ EXC_NUMFMT_REUSE( 51, 28 ),
+ EXC_NUMFMT_REUSE( 52, 34 ),
+ EXC_NUMFMT_REUSE( 53, 35 ),
+ EXC_NUMFMT_REUSE( 54, 28 ),
+ EXC_NUMFMT_REUSE( 55, 34 ),
+ EXC_NUMFMT_REUSE( 56, 35 ),
+ EXC_NUMFMT_REUSE( 57, 27 ),
+ EXC_NUMFMT_REUSE( 58, 28 ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_JAPANESE[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY/M/D" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 22, "YYYY/M/D h:mm" ),
+ EXC_NUMFMT_STRING( 27, "[$-0411]GE.M.D" ),
+ EXC_NUMFMT_STRING( 28, "[$-0411]GGGE" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 30, "[$-0411]M/D/YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0411]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0411]h" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0411]h" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0411]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON ),
+ EXC_NUMFMT_STRING( 35, "[$-0411]M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 63, UTF8_YEN_JP "#,##0;-" UTF8_YEN_JP "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_YEN_JP "#,##0;[RED]-" UTF8_YEN_JP "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_YEN_JP "#,##0.00;-" UTF8_YEN_JP "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_YEN_JP "#,##0.00;[RED]-" UTF8_YEN_JP "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_KOREAN[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY-MM-DD" ),
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 22, "YYYY-MM-DD h:mm" ),
+ EXC_NUMFMT_STRING( 27, "[$-0412]YYYY" UTF8_CJ_YEAR " MM" UTF8_CJ_MON " DD" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 28, "[$-0412]MM-DD" ),
+ EXC_NUMFMT_STRING( 30, "[$-0412]MM-DD-YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0412]YYYY" UTF8_KO_YEAR " MM" UTF8_KO_MON " DD" UTF8_KO_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0412]h" UTF8_KO_HOUR " mm" UTF8_KO_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0412]h" UTF8_KO_HOUR " mm" UTF8_KO_MIN " ss" UTF8_KO_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0412]YYYY\"/\"MM\"/\"DD" ),
+ EXC_NUMFMT_STRING( 35, "[$-0412]YYYY-MM-DD" ),
+ EXC_NUMFMT_STRING( 63, UTF8_WON "#,##0;-" UTF8_WON "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_WON "#,##0;[RED]-" UTF8_WON "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_WON "#,##0.00;-" UTF8_WON "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_WON "#,##0.00;[RED]-" UTF8_WON "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_CHINESE_SIMPLIFIED[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY-M-D" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 22, "YYYY-M-D h:mm" ),
+ EXC_NUMFMT_STRING( 27, "[$-0804]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON ),
+ EXC_NUMFMT_STRING( 28, "[$-0804]M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 30, "[$-0804]M-D-YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0804]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0804]h" UTF8_CS_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0804]h" UTF8_CS_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0804]AM/PMh" UTF8_CS_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 35, "[$-0804]AM/PMh" UTF8_CS_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_REUSE( 52, 27 ),
+ EXC_NUMFMT_REUSE( 53, 28 ),
+ EXC_NUMFMT_STRING( 63, UTF8_YEN_CS "#,##0;-" UTF8_YEN_CS "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_YEN_CS "#,##0;[RED]-" UTF8_YEN_CS "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_YEN_CS "#,##0.00;-" UTF8_YEN_CS "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_YEN_CS "#,##0.00;[RED]-" UTF8_YEN_CS "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_CHINESE_TRADITIONAL[] =
+{
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "hh:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "hh:mm:ss AM/PM" ),
+ EXC_NUMFMT_OFFSET( 20, NF_TIME_HHMM ),
+ EXC_NUMFMT_OFFSET( 21, NF_TIME_HHMMSS ),
+ EXC_NUMFMT_STRING( 22, "YYYY/M/D hh:mm" ),
+ EXC_NUMFMT_STRING( 23, "US$#,##0_);(US$#,##0)" ),
+ EXC_NUMFMT_STRING( 24, "US$#,##0_);[RED](US$#,##0)" ),
+ EXC_NUMFMT_STRING( 25, "US$#,##0.00_);(US$#,##0.00)" ),
+ EXC_NUMFMT_STRING( 26, "US$#,##0.00_);[RED](US$#,##0.00)" ),
+ EXC_NUMFMT_STRING( 27, "[$-0404]E/M/D" ),
+ EXC_NUMFMT_STRING( 28, "[$-0404]E" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 30, "[$-0404]M/D/YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0404]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0404]hh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0404]hh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0404]AM/PMhh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 35, "[$-0404]AM/PMhh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 63, "$#,##0;-$#,##0" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0;[RED]-$#,##0" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00;-$#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00;[RED]-$#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// OTHER ----------------------------------------------------------------------
+
+static const XclBuiltInFormat spBuiltInFormats_HEBREW[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMMM" ),
+ EXC_NUMFMT_STRING( 17, "MMMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 63, UTF8_SHEQEL " #,##0;" UTF8_SHEQEL " -#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_SHEQEL " #,##0;[RED]" UTF8_SHEQEL " -#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_SHEQEL " #,##0.00;" UTF8_SHEQEL " -#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_SHEQEL " #,##0.00;[RED]" UTF8_SHEQEL " -#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_THAI[] =
+{
+ EXC_NUMFMT_STRING( 14, "D/M/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "D/M/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 59, "t0" ),
+ EXC_NUMFMT_STRING( 60, "t0.00" ),
+ EXC_NUMFMT_STRING( 61, "t#,##0" ),
+ EXC_NUMFMT_STRING( 62, "t#,##0.00" ),
+ EXC_NUMFMT_STRING( 63, "t" UTF8_BAHT "#,##0_);t(" UTF8_BAHT "#,##0)" ),
+ EXC_NUMFMT_STRING( 64, "t" UTF8_BAHT "#,##0_);[RED]t(" UTF8_BAHT "#,##0)" ),
+ EXC_NUMFMT_STRING( 65, "t" UTF8_BAHT "#,##0.00_);t(" UTF8_BAHT "#,##0.00)" ),
+ EXC_NUMFMT_STRING( 66, "t" UTF8_BAHT "#,##0.00_);[RED]t(" UTF8_BAHT "#,##0.00)" ),
+ EXC_NUMFMT_STRING( 67, "t0%" ),
+ EXC_NUMFMT_STRING( 68, "t0.00%" ),
+ EXC_NUMFMT_STRING( 69, "t# ?/?" ),
+ EXC_NUMFMT_STRING( 70, "t# ?\?/?\?" ),
+ EXC_NUMFMT_STRING( 71, "tD/M/EE" ),
+ EXC_NUMFMT_STRING( 72, "tD-MMM-E" ),
+ EXC_NUMFMT_STRING( 73, "tD-MMM" ),
+ EXC_NUMFMT_STRING( 74, "tMMM-E" ),
+ EXC_NUMFMT_STRING( 75, "th:mm" ),
+ EXC_NUMFMT_STRING( 76, "th:mm:ss" ),
+ EXC_NUMFMT_STRING( 77, "tD/M/EE h:mm" ),
+ EXC_NUMFMT_STRING( 78, "tmm:ss" ),
+ EXC_NUMFMT_STRING( 79, "t[h]:mm:ss" ),
+ EXC_NUMFMT_STRING( 80, "tmm:ss.0" ),
+ EXC_NUMFMT_STRING( 81, "D/M/E" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ----------------------------------------------------------------------------
+
+#undef EXC_NUMFMT_ENDTABLE
+#undef EXC_NUMFMT_REUSE
+#undef EXC_NUMFMT_OFFSET
+#undef EXC_NUMFMT_STRING
+
+// ----------------------------------------------------------------------------
+
+/** Specifies a number format table for a specific langauge. */
+struct XclBuiltInFormatTable
+{
+ LanguageType meLanguage; /// The language of this table.
+ LanguageType meParentLang; /// The language of the parent table.
+ const XclBuiltInFormat* mpFormats; /// The number format table.
+};
+
+static const XclBuiltInFormatTable spBuiltInFormatTables[] =
+{ // language parent language format table
+ { LANGUAGE_DONTKNOW, LANGUAGE_NONE, spBuiltInFormats_DONTKNOW },
+
+ { LANGUAGE_ENGLISH, LANGUAGE_DONTKNOW, spBuiltInFormats_ENGLISH },
+ { LANGUAGE_ENGLISH_UK, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_UK },
+ { LANGUAGE_ENGLISH_EIRE, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_EIRE },
+ { LANGUAGE_ENGLISH_US, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_US },
+ { LANGUAGE_ENGLISH_CAN, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_CAN },
+ { LANGUAGE_ENGLISH_AUS, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_AUS },
+ { LANGUAGE_ENGLISH_SAFRICA, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_SAFRICA },
+ { LANGUAGE_ENGLISH_NZ, LANGUAGE_ENGLISH_AUS, 0 },
+
+ { PRV_LANGUAGE_FRENCH_PRIM, LANGUAGE_DONTKNOW, spBuiltInFormats_FRENCH },
+ { LANGUAGE_FRENCH, PRV_LANGUAGE_FRENCH_PRIM, spBuiltInFormats_FRENCH_FRANCE },
+ { LANGUAGE_FRENCH_CANADIAN, PRV_LANGUAGE_FRENCH_PRIM, spBuiltInFormats_FRENCH_CANADIAN },
+ { LANGUAGE_FRENCH_SWISS, PRV_LANGUAGE_FRENCH_PRIM, spBuiltInFormats_FRENCH_SWISS },
+ { LANGUAGE_FRENCH_BELGIAN, LANGUAGE_FRENCH, spBuiltInFormats_FRENCH_BELGIAN },
+ { LANGUAGE_FRENCH_LUXEMBOURG, LANGUAGE_FRENCH, 0 },
+ { LANGUAGE_FRENCH_MONACO, LANGUAGE_FRENCH, 0 },
+
+ { PRV_LANGUAGE_GERMAN_PRIM, LANGUAGE_DONTKNOW, spBuiltInFormats_GERMAN },
+ { LANGUAGE_GERMAN, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_GERMANY },
+ { LANGUAGE_GERMAN_AUSTRIAN, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_AUSTRIAN },
+ { LANGUAGE_GERMAN_SWISS, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_SWISS },
+ { LANGUAGE_GERMAN_LUXEMBOURG, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_LUXEMBOURG },
+ { LANGUAGE_GERMAN_LIECHTENSTEIN, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_LIECHTENSTEIN },
+
+ { LANGUAGE_ITALIAN, LANGUAGE_DONTKNOW, spBuiltInFormats_ITALIAN_ITALY },
+ { LANGUAGE_ITALIAN_SWISS, LANGUAGE_DONTKNOW, spBuiltInFormats_ITALIAN_SWISS },
+
+ { LANGUAGE_SWEDISH, LANGUAGE_DONTKNOW, spBuiltInFormats_SWEDISH_SWEDEN },
+ { LANGUAGE_SWEDISH_FINLAND, LANGUAGE_DONTKNOW, spBuiltInFormats_SWEDISH_FINLAND },
+
+ { PRV_LANGUAGE_ASIAN_PRIM, LANGUAGE_DONTKNOW, spBuiltInFormats_ASIAN },
+ { LANGUAGE_JAPANESE, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_JAPANESE },
+ { LANGUAGE_KOREAN, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_KOREAN },
+ { LANGUAGE_CHINESE_SIMPLIFIED, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_CHINESE_SIMPLIFIED },
+ { LANGUAGE_CHINESE_TRADITIONAL, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_CHINESE_TRADITIONAL },
+
+ { LANGUAGE_HEBREW, LANGUAGE_DONTKNOW, spBuiltInFormats_HEBREW },
+ { LANGUAGE_THAI, LANGUAGE_DONTKNOW, spBuiltInFormats_THAI }
+};
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// ============================================================================
+
+XclNumFmtBuffer::XclNumFmtBuffer( const XclRoot& rRoot ) :
+ meSysLang( rRoot.GetSysLanguage() ),
+ mnStdScNumFmt( rRoot.GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
+{
+ // *** insert default formats (BIFF5+ only)***
+
+ if( rRoot.GetBiff() >= EXC_BIFF5 )
+ InsertBuiltinFormats();
+}
+
+void XclNumFmtBuffer::InitializeImport()
+{
+ maFmtMap.clear();
+}
+
+//UNUSED2008-05 const XclNumFmt* XclNumFmtBuffer::GetFormat( sal_uInt16 nXclNumFmt ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 XclNumFmtMap::const_iterator aIt = maFmtMap.find( nXclNumFmt );
+//UNUSED2008-05 return (aIt != maFmtMap.end()) ? &aIt->second : 0;
+//UNUSED2008-05 }
+
+void XclNumFmtBuffer::InsertFormat( sal_uInt16 nXclNumFmt, const String& rFormat )
+{
+ XclNumFmt& rNumFmt = maFmtMap[ nXclNumFmt ];
+ rNumFmt.maFormat = rFormat;
+ // #i62053# rFormat may be an empty string, meOffset must be initialized
+ rNumFmt.meOffset = NF_NUMBER_STANDARD;
+ rNumFmt.meLanguage = LANGUAGE_SYSTEM;
+}
+
+void XclNumFmtBuffer::InsertBuiltinFormats()
+{
+ // build a map containing tables for all languages
+ typedef ::std::map< LanguageType, const XclBuiltInFormatTable* > XclBuiltInMap;
+ XclBuiltInMap aBuiltInMap;
+ for( const XclBuiltInFormatTable* pTable = spBuiltInFormatTables;
+ pTable != STATIC_TABLE_END( spBuiltInFormatTables ); ++pTable )
+ aBuiltInMap[ pTable->meLanguage ] = pTable;
+
+ // build a list of table pointers for the current language, with all parent tables
+ typedef ::std::vector< const XclBuiltInFormatTable* > XclBuiltInVec;
+ XclBuiltInVec aBuiltInVec;
+ for( XclBuiltInMap::const_iterator aMIt = aBuiltInMap.find( meSysLang ), aMEnd = aBuiltInMap.end();
+ aMIt != aMEnd; aMIt = aBuiltInMap.find( aMIt->second->meParentLang ) )
+ aBuiltInVec.push_back( aMIt->second );
+ // language not supported
+ if( aBuiltInVec.empty() )
+ {
+ DBG_ERROR1( "XclNumFmtBuffer::InsertBuiltinFormats - language 0x%04hX not supported (#i29949#)", meSysLang );
+ XclBuiltInMap::const_iterator aMIt = aBuiltInMap.find( LANGUAGE_DONTKNOW );
+ DBG_ASSERT( aMIt != aBuiltInMap.end(), "XclNumFmtBuffer::InsertBuiltinFormats - default map not found" );
+ if( aMIt != aBuiltInMap.end() )
+ aBuiltInVec.push_back( aMIt->second );
+ }
+
+ // insert the default formats in the format map, from root parent to system language
+ typedef ::std::map< sal_uInt16, sal_uInt16 > XclReuseMap;
+ XclReuseMap aReuseMap;
+ for( XclBuiltInVec::reverse_iterator aVIt = aBuiltInVec.rbegin(), aVEnd = aBuiltInVec.rend(); aVIt != aVEnd; ++aVIt )
+ {
+ // put LANGUAGE_SYSTEM for all entries in default table
+ LanguageType eLang = ((*aVIt)->meLanguage == LANGUAGE_DONTKNOW) ? LANGUAGE_SYSTEM : meSysLang;
+ for( const XclBuiltInFormat* pBuiltIn = (*aVIt)->mpFormats; pBuiltIn && (pBuiltIn->mnXclNumFmt != EXC_FORMAT_NOTFOUND); ++pBuiltIn )
+ {
+ XclNumFmt& rNumFmt = maFmtMap[ pBuiltIn->mnXclNumFmt ];
+
+ rNumFmt.meOffset = pBuiltIn->meOffset;
+ rNumFmt.meLanguage = eLang;
+
+ if( pBuiltIn->mpFormat )
+ rNumFmt.maFormat = String( pBuiltIn->mpFormat, RTL_TEXTENCODING_UTF8 );
+ else
+ rNumFmt.maFormat = EMPTY_STRING;
+
+ if( pBuiltIn->meOffset == PRV_NF_INDEX_REUSE )
+ aReuseMap[ pBuiltIn->mnXclNumFmt ] = pBuiltIn->mnXclReuseFmt;
+ else
+ aReuseMap.erase( pBuiltIn->mnXclNumFmt );
+ }
+ }
+
+ // copy reused number formats
+ for( XclReuseMap::const_iterator aRIt = aReuseMap.begin(), aREnd = aReuseMap.end(); aRIt != aREnd; ++aRIt )
+ maFmtMap[ aRIt->first ] = maFmtMap[ aRIt->second ];
+}
+
+// Cell formatting data (XF) ==================================================
+
+XclCellProt::XclCellProt() :
+ mbLocked( true ), // default in Excel and Calc
+ mbHidden( false )
+{
+}
+
+bool operator==( const XclCellProt& rLeft, const XclCellProt& rRight )
+{
+ return (rLeft.mbLocked == rRight.mbLocked) && (rLeft.mbHidden == rRight.mbHidden);
+}
+
+// ----------------------------------------------------------------------------
+
+XclCellAlign::XclCellAlign() :
+ mnHorAlign( EXC_XF_HOR_GENERAL ),
+ mnVerAlign( EXC_XF_VER_BOTTOM ),
+ mnOrient( EXC_ORIENT_NONE ),
+ mnTextDir( EXC_XF_TEXTDIR_CONTEXT ),
+ mnRotation( EXC_ROT_NONE ),
+ mnIndent( 0 ),
+ mbLineBreak( false ),
+ mbShrink( false )
+{
+}
+
+SvxCellHorJustify XclCellAlign::GetScHorAlign() const
+{
+ SvxCellHorJustify eHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ switch( mnHorAlign )
+ {
+ case EXC_XF_HOR_GENERAL: eHorJust = SVX_HOR_JUSTIFY_STANDARD; break;
+ case EXC_XF_HOR_LEFT: eHorJust = SVX_HOR_JUSTIFY_LEFT; break;
+ case EXC_XF_HOR_CENTER_AS:
+ case EXC_XF_HOR_CENTER: eHorJust = SVX_HOR_JUSTIFY_CENTER; break;
+ case EXC_XF_HOR_RIGHT: eHorJust = SVX_HOR_JUSTIFY_RIGHT; break;
+ case EXC_XF_HOR_FILL: eHorJust = SVX_HOR_JUSTIFY_REPEAT; break;
+ case EXC_XF_HOR_JUSTIFY:
+ case EXC_XF_HOR_DISTRIB: eHorJust = SVX_HOR_JUSTIFY_BLOCK; break;
+ default: DBG_ERRORFILE( "XclCellAlign::GetScHorAlign - unknown horizontal alignment" );
+ }
+ return eHorJust;
+}
+
+SvxCellVerJustify XclCellAlign::GetScVerAlign() const
+{
+ SvxCellVerJustify eVerJust = SVX_VER_JUSTIFY_STANDARD;
+ switch( mnVerAlign )
+ {
+ case EXC_XF_VER_TOP: eVerJust = SVX_VER_JUSTIFY_TOP; break;
+ case EXC_XF_VER_CENTER: eVerJust = SVX_VER_JUSTIFY_CENTER; break;
+ case EXC_XF_VER_BOTTOM: eVerJust = SVX_VER_JUSTIFY_STANDARD; break;
+ case EXC_XF_VER_JUSTIFY:
+ case EXC_XF_VER_DISTRIB: eVerJust = SVX_VER_JUSTIFY_TOP; break;
+ default: DBG_ERRORFILE( "XclCellAlign::GetScVerAlign - unknown vertical alignment" );
+ }
+ return eVerJust;
+}
+
+SvxFrameDirection XclCellAlign::GetScFrameDir() const
+{
+ SvxFrameDirection eFrameDir = FRMDIR_ENVIRONMENT;
+ switch( mnTextDir )
+ {
+ case EXC_XF_TEXTDIR_CONTEXT: eFrameDir = FRMDIR_ENVIRONMENT; break;
+ case EXC_XF_TEXTDIR_LTR: eFrameDir = FRMDIR_HORI_LEFT_TOP; break;
+ case EXC_XF_TEXTDIR_RTL: eFrameDir = FRMDIR_HORI_RIGHT_TOP; break;
+ default: DBG_ERRORFILE( "XclCellAlign::GetScFrameDir - unknown CTL text direction" );
+ }
+ return eFrameDir;
+}
+
+void XclCellAlign::SetScHorAlign( SvxCellHorJustify eHorJust )
+{
+ switch( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD: mnHorAlign = EXC_XF_HOR_GENERAL; break;
+ case SVX_HOR_JUSTIFY_LEFT: mnHorAlign = EXC_XF_HOR_LEFT; break;
+ case SVX_HOR_JUSTIFY_CENTER: mnHorAlign = EXC_XF_HOR_CENTER; break;
+ case SVX_HOR_JUSTIFY_RIGHT: mnHorAlign = EXC_XF_HOR_RIGHT; break;
+ case SVX_HOR_JUSTIFY_BLOCK: mnHorAlign = EXC_XF_HOR_JUSTIFY; break;
+ case SVX_HOR_JUSTIFY_REPEAT: mnHorAlign = EXC_XF_HOR_FILL; break;
+ default: mnHorAlign = EXC_XF_HOR_GENERAL;
+ DBG_ERROR( "XclCellAlign::SetScHorAlign - unknown horizontal alignment" );
+ }
+}
+
+void XclCellAlign::SetScVerAlign( SvxCellVerJustify eVerJust )
+{
+ switch( eVerJust )
+ {
+ case SVX_VER_JUSTIFY_STANDARD: mnVerAlign = EXC_XF_VER_BOTTOM; break;
+ case SVX_VER_JUSTIFY_TOP: mnVerAlign = EXC_XF_VER_TOP; break;
+ case SVX_VER_JUSTIFY_CENTER: mnVerAlign = EXC_XF_VER_CENTER; break;
+ case SVX_VER_JUSTIFY_BOTTOM: mnVerAlign = EXC_XF_VER_BOTTOM; break;
+ default: mnVerAlign = EXC_XF_VER_BOTTOM;
+ DBG_ERROR( "XclCellAlign::SetScVerAlign - unknown vertical alignment" );
+ }
+}
+
+void XclCellAlign::SetScFrameDir( SvxFrameDirection eFrameDir )
+{
+ switch( eFrameDir )
+ {
+ case FRMDIR_ENVIRONMENT: mnTextDir = EXC_XF_TEXTDIR_CONTEXT; break;
+ case FRMDIR_HORI_LEFT_TOP: mnTextDir = EXC_XF_TEXTDIR_LTR; break;
+ case FRMDIR_HORI_RIGHT_TOP: mnTextDir = EXC_XF_TEXTDIR_RTL; break;
+ default: mnTextDir = EXC_XF_TEXTDIR_CONTEXT;
+ DBG_ERRORFILE( "XclCellAlign::SetScFrameDir - unknown CTL text direction" );
+ }
+}
+
+bool operator==( const XclCellAlign& rLeft, const XclCellAlign& rRight )
+{
+ return
+ (rLeft.mnHorAlign == rRight.mnHorAlign) && (rLeft.mnVerAlign == rRight.mnVerAlign) &&
+ (rLeft.mnTextDir == rRight.mnTextDir) && (rLeft.mnOrient == rRight.mnOrient) &&
+ (rLeft.mnRotation == rRight.mnRotation) && (rLeft.mnIndent == rRight.mnIndent) &&
+ (rLeft.mbLineBreak == rRight.mbLineBreak) && (rLeft.mbShrink == rRight.mbShrink);
+}
+
+// ----------------------------------------------------------------------------
+
+XclCellBorder::XclCellBorder() :
+ mnLeftColor( 0 ),
+ mnRightColor( 0 ),
+ mnTopColor( 0 ),
+ mnBottomColor( 0 ),
+ mnDiagColor( 0 ),
+ mnLeftLine( EXC_LINE_NONE ),
+ mnRightLine( EXC_LINE_NONE ),
+ mnTopLine( EXC_LINE_NONE ),
+ mnBottomLine( EXC_LINE_NONE ),
+ mnDiagLine( EXC_LINE_NONE ),
+ mbDiagTLtoBR( false ),
+ mbDiagBLtoTR( false )
+{
+}
+
+bool operator==( const XclCellBorder& rLeft, const XclCellBorder& rRight )
+{
+ return
+ (rLeft.mnLeftColor == rRight.mnLeftColor) && (rLeft.mnRightColor == rRight.mnRightColor) &&
+ (rLeft.mnTopColor == rRight.mnTopColor) && (rLeft.mnBottomColor == rRight.mnBottomColor) &&
+ (rLeft.mnLeftLine == rRight.mnLeftLine) && (rLeft.mnRightLine == rRight.mnRightLine) &&
+ (rLeft.mnTopLine == rRight.mnTopLine) && (rLeft.mnBottomLine == rRight.mnBottomLine) &&
+ (rLeft.mnDiagColor == rRight.mnDiagColor) && (rLeft.mnDiagLine == rRight.mnDiagLine) &&
+ (rLeft.mbDiagTLtoBR == rRight.mbDiagTLtoBR) && (rLeft.mbDiagBLtoTR == rRight.mbDiagBLtoTR);
+}
+
+// ----------------------------------------------------------------------------
+
+XclCellArea::XclCellArea() :
+ mnForeColor( EXC_COLOR_WINDOWTEXT ),
+ mnBackColor( EXC_COLOR_WINDOWBACK ),
+ mnPattern( EXC_PATT_NONE )
+{
+}
+
+bool XclCellArea::IsTransparent() const
+{
+ return (mnPattern == EXC_PATT_NONE) && (mnBackColor == EXC_COLOR_WINDOWBACK);
+}
+
+bool operator==( const XclCellArea& rLeft, const XclCellArea& rRight )
+{
+ return
+ (rLeft.mnForeColor == rRight.mnForeColor) && (rLeft.mnBackColor == rRight.mnBackColor) &&
+ (rLeft.mnPattern == rRight.mnPattern);
+}
+
+// ----------------------------------------------------------------------------
+
+XclXFBase::XclXFBase( bool bCellXF ) :
+ mnParent( bCellXF ? EXC_XF_DEFAULTSTYLE : EXC_XF_STYLEPARENT ),
+ mbCellXF( bCellXF )
+{
+ SetAllUsedFlags( false );
+}
+
+XclXFBase::~XclXFBase()
+{
+}
+
+void XclXFBase::SetAllUsedFlags( bool bUsed )
+{
+ mbProtUsed = mbFontUsed = mbFmtUsed = mbAlignUsed = mbBorderUsed = mbAreaUsed = bUsed;
+}
+
+bool XclXFBase::HasUsedFlags() const
+{
+ return mbProtUsed || mbFontUsed || mbFmtUsed || mbAlignUsed || mbBorderUsed || mbAreaUsed;
+}
+
+bool XclXFBase::Equals( const XclXFBase& rCmp ) const
+{
+ return
+ (mbCellXF == rCmp.mbCellXF) && (mnParent == rCmp.mnParent) &&
+ (mbProtUsed == rCmp.mbProtUsed) && (mbFontUsed == rCmp.mbFontUsed) &&
+ (mbFmtUsed == rCmp.mbFmtUsed) && (mbAlignUsed == rCmp.mbAlignUsed) &&
+ (mbBorderUsed == rCmp.mbBorderUsed) && (mbAreaUsed == rCmp.mbAreaUsed);
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx
new file mode 100644
index 000000000000..0dd988d67586
--- /dev/null
+++ b/sc/source/filter/excel/xltools.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <algorithm>
+#include <math.h>
+#include <sal/mathconf.h>
+#include <unotools/fontcvt.hxx>
+#include <sfx2/objsh.hxx>
+#include <editeng/editstat.hxx>
+#include <filter/msfilter/msvbahelper.hxx>
+#include "xestream.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "editutil.hxx"
+#include "formula/errorcodes.hxx"
+#include "globstr.hrc"
+#include "xlstyle.hxx"
+#include "xlname.hxx"
+#include "xistream.hxx"
+#include "xiroot.hxx"
+#include "xltools.hxx"
+
+using ::rtl::OUString;
+
+// GUID import/export =========================================================
+
+XclGuid::XclGuid()
+{
+ ::std::fill( mpnData, STATIC_TABLE_END( mpnData ), 0 );
+}
+
+XclGuid::XclGuid(
+ sal_uInt32 nData1, sal_uInt16 nData2, sal_uInt16 nData3,
+ sal_uInt8 nData41, sal_uInt8 nData42, sal_uInt8 nData43, sal_uInt8 nData44,
+ sal_uInt8 nData45, sal_uInt8 nData46, sal_uInt8 nData47, sal_uInt8 nData48 )
+{
+ // convert to little endian -> makes streaming easy
+ UInt32ToSVBT32( nData1, mpnData );
+ ShortToSVBT16( nData2, mpnData + 4 );
+ ShortToSVBT16( nData3, mpnData + 6 );
+ mpnData[ 8 ] = nData41;
+ mpnData[ 9 ] = nData42;
+ mpnData[ 10 ] = nData43;
+ mpnData[ 11 ] = nData44;
+ mpnData[ 12 ] = nData45;
+ mpnData[ 13 ] = nData46;
+ mpnData[ 14 ] = nData47;
+ mpnData[ 15 ] = nData48;
+}
+
+bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 )
+{
+ return ::std::equal( rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ), rCmp2.mpnData );
+}
+
+bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 )
+{
+ return ::std::lexicographical_compare(
+ rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ),
+ rCmp2.mpnData, STATIC_TABLE_END( rCmp2.mpnData ) );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid )
+{
+ rStrm.Read( rGuid.mpnData, 16 ); // mpnData always in little endian
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclGuid& rGuid )
+{
+ rStrm.Write( rGuid.mpnData, 16 ); // mpnData already in little endian
+ return rStrm;
+}
+
+// Excel Tools ================================================================
+
+// GUID's ---------------------------------------------------------------------
+
+const XclGuid XclTools::maGuidStdLink(
+ 0x79EAC9D0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
+
+const XclGuid XclTools::maGuidUrlMoniker(
+ 0x79EAC9E0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
+
+const XclGuid XclTools::maGuidFileMoniker(
+ 0x00000303, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
+
+// numeric conversion ---------------------------------------------------------
+
+double XclTools::GetDoubleFromRK( sal_Int32 nRKValue )
+{
+ union
+ {
+ double fVal;
+ sal_math_Double smD;
+ };
+ fVal = 0.0;
+
+ if( ::get_flag( nRKValue, EXC_RK_INTFLAG ) )
+ {
+ sal_Int32 nTemp = nRKValue >> 2;
+ ::set_flag< sal_Int32 >( nTemp, 0xE0000000, nRKValue < 0 );
+ fVal = nTemp;
+ }
+ else
+ {
+ smD.w32_parts.msw = nRKValue & EXC_RK_VALUEMASK;
+ }
+
+ if( ::get_flag( nRKValue, EXC_RK_100FLAG ) )
+ fVal /= 100.0;
+
+ return fVal;
+}
+
+bool XclTools::GetRKFromDouble( sal_Int32& rnRKValue, double fValue )
+{
+ double fFrac, fInt;
+
+ // integer
+ fFrac = modf( fValue, &fInt );
+ if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) ) // 2^29
+ {
+ rnRKValue = static_cast< sal_Int32 >( fInt );
+ rnRKValue <<= 2;
+ rnRKValue |= EXC_RK_INT;
+ return true;
+ }
+
+ // integer/100
+ fFrac = modf( fValue * 100.0, &fInt );
+ if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) )
+ {
+ rnRKValue = static_cast< sal_Int32 >( fInt );
+ rnRKValue <<= 2;
+ rnRKValue |= EXC_RK_INT100;
+ return true;
+ }
+
+ // double
+ return false;
+}
+
+sal_Int32 XclTools::GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked )
+{
+ if( nXclRot == EXC_ROT_STACKED )
+ return nRotForStacked;
+ DBG_ASSERT( nXclRot <= 180, "XclTools::GetScRotation - illegal rotation angle" );
+ return static_cast< sal_Int32 >( (nXclRot <= 180) ? (100 * ((nXclRot > 90) ? (450 - nXclRot) : nXclRot)) : 0 );
+}
+
+sal_uInt8 XclTools::GetXclRotation( sal_Int32 nScRot )
+{
+ sal_Int32 nXclRot = nScRot / 100;
+ if( (0 <= nXclRot) && (nXclRot <= 90) )
+ return static_cast< sal_uInt8 >( nXclRot );
+ if( nXclRot < 180 )
+ return static_cast< sal_uInt8 >( 270 - nXclRot );
+ if( nXclRot < 270 )
+ return static_cast< sal_uInt8 >( nXclRot - 180 );
+ if( nXclRot < 360 )
+ return static_cast< sal_uInt8 >( 450 - nXclRot );
+ return 0;
+}
+
+sal_uInt8 XclTools::GetXclRotFromOrient( sal_uInt8 nXclOrient )
+{
+ switch( nXclOrient )
+ {
+ case EXC_ORIENT_NONE: return EXC_ROT_NONE;
+ case EXC_ORIENT_STACKED: return EXC_ROT_STACKED;
+ case EXC_ORIENT_90CCW: return EXC_ROT_90CCW;
+ case EXC_ORIENT_90CW: return EXC_ROT_90CW;
+ default: DBG_ERRORFILE( "XclTools::GetXclRotFromOrient - unknown text orientation" );
+ }
+ return EXC_ROT_NONE;
+}
+
+sal_uInt8 XclTools::GetXclOrientFromRot( sal_uInt16 nXclRot )
+{
+ if( nXclRot == EXC_ROT_STACKED )
+ return EXC_ORIENT_STACKED;
+ DBG_ASSERT( nXclRot <= 180, "XclTools::GetXclOrientFromRot - unknown text rotation" );
+ if( (45 < nXclRot) && (nXclRot <= 90) )
+ return EXC_ORIENT_90CCW;
+ if( (135 < nXclRot) && (nXclRot <= 180) )
+ return EXC_ORIENT_90CW;
+ return EXC_ORIENT_NONE;
+}
+
+sal_uInt8 XclTools::GetXclErrorCode( USHORT nScError )
+{
+ using namespace ScErrorCodes;
+ switch( nScError )
+ {
+ case errIllegalArgument: return EXC_ERR_VALUE;
+ case errIllegalFPOperation: return EXC_ERR_NUM; // maybe DIV/0 or NUM...
+ case errDivisionByZero: return EXC_ERR_DIV0;
+ case errIllegalParameter: return EXC_ERR_VALUE;
+ case errPairExpected: return EXC_ERR_VALUE;
+ case errOperatorExpected: return EXC_ERR_VALUE;
+ case errVariableExpected: return EXC_ERR_VALUE;
+ case errParameterExpected: return EXC_ERR_VALUE;
+ case errNoValue: return EXC_ERR_VALUE;
+ case errCircularReference: return EXC_ERR_VALUE;
+ case errNoCode: return EXC_ERR_NULL;
+ case errNoRef: return EXC_ERR_REF;
+ case errNoName: return EXC_ERR_NAME;
+ case errNoAddin: return EXC_ERR_NAME;
+ case errNoMacro: return EXC_ERR_NAME;
+ case NOTAVAILABLE: return EXC_ERR_NA;
+ }
+ return EXC_ERR_NA;
+}
+
+USHORT XclTools::GetScErrorCode( sal_uInt8 nXclError )
+{
+ using namespace ScErrorCodes;
+ switch( nXclError )
+ {
+ case EXC_ERR_NULL: return errNoCode;
+ case EXC_ERR_DIV0: return errDivisionByZero;
+ case EXC_ERR_VALUE: return errNoValue;
+ case EXC_ERR_REF: return errNoRef;
+ case EXC_ERR_NAME: return errNoName;
+ case EXC_ERR_NUM: return errIllegalFPOperation;
+ case EXC_ERR_NA: return NOTAVAILABLE;
+ default: DBG_ERRORFILE( "XclTools::GetScErrorCode - unknown error code" );
+ }
+ return NOTAVAILABLE;
+}
+
+double XclTools::ErrorToDouble( sal_uInt8 nXclError )
+{
+ union
+ {
+ double fVal;
+ sal_math_Double smD;
+ };
+ ::rtl::math::setNan( &fVal );
+ smD.nan_parts.fraction_lo = GetScErrorCode( nXclError );
+ return fVal;
+}
+
+XclBoolError XclTools::ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue )
+{
+ XclBoolError eType;
+ if( bErrOrBool )
+ {
+ // error value
+ switch( nValue )
+ {
+ case EXC_ERR_NULL: eType = xlErrNull; break;
+ case EXC_ERR_DIV0: eType = xlErrDiv0; break;
+ case EXC_ERR_VALUE: eType = xlErrValue; break;
+ case EXC_ERR_REF: eType = xlErrRef; break;
+ case EXC_ERR_NAME: eType = xlErrName; break;
+ case EXC_ERR_NUM: eType = xlErrNum; break;
+ case EXC_ERR_NA: eType = xlErrNA; break;
+ default: eType = xlErrUnknown;
+ }
+ rfDblValue = 0.0;
+ }
+ else
+ {
+ // Boolean value
+ eType = nValue ? xlErrTrue : xlErrFalse;
+ rfDblValue = nValue ? 1.0 : 0.0;
+ }
+ return eType;
+}
+
+sal_uInt16 XclTools::GetTwipsFromInch( double fInches )
+{
+ return static_cast< sal_uInt16 >(
+ ::std::min( ::std::max( (fInches * EXC_TWIPS_PER_INCH + 0.5), 0.0 ), 65535.0 ) );
+}
+
+sal_uInt16 XclTools::GetTwipsFromHmm( sal_Int32 nHmm )
+{
+ return GetTwipsFromInch( static_cast< double >( nHmm ) / 1000.0 / CM_PER_INCH );
+}
+
+double XclTools::GetInchFromTwips( sal_Int32 nTwips )
+{
+ return static_cast< double >( nTwips ) / EXC_TWIPS_PER_INCH;
+}
+
+double XclTools::GetInchFromHmm( sal_Int32 nHmm )
+{
+ return GetInchFromTwips( GetTwipsFromHmm( nHmm ) );
+}
+
+sal_Int32 XclTools::GetHmmFromInch( double fInches )
+{
+ return static_cast< sal_Int32 >( fInches * CM_PER_INCH * 1000 );
+}
+
+sal_Int32 XclTools::GetHmmFromTwips( sal_Int32 nTwips )
+{
+ return GetHmmFromInch( GetInchFromTwips( nTwips ) );
+}
+
+USHORT XclTools::GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth )
+{
+ double fScWidth = static_cast< double >( nXclWidth ) / 256.0 * nScCharWidth + 0.5;
+ return limit_cast< USHORT >( fScWidth );
+}
+
+sal_uInt16 XclTools::GetXclColumnWidth( USHORT nScWidth, long nScCharWidth )
+{
+ double fXclWidth = static_cast< double >( nScWidth ) * 256.0 / nScCharWidth + 0.5;
+ return limit_cast< sal_uInt16 >( fXclWidth );
+}
+
+double XclTools::GetXclDefColWidthCorrection( long nXclDefFontHeight )
+{
+ return 40960.0 / ::std::max( nXclDefFontHeight - 15L, 60L ) + 50.0;
+}
+
+// formatting -----------------------------------------------------------------
+
+Color XclTools::GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt16 nXclPattern )
+{
+ // 0x00 == 0% transparence (full rPattColor)
+ // 0x80 == 100% transparence (full rBackColor)
+ static const sal_uInt8 pnRatioTable[] =
+ {
+ 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
+ 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
+ 0x50, 0x70, 0x78 // 16 - 18
+ };
+ return (nXclPattern < STATIC_TABLE_SIZE( pnRatioTable )) ?
+ ScfTools::GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor;
+}
+
+// text encoding --------------------------------------------------------------
+
+namespace {
+
+const struct XclCodePageEntry
+{
+ sal_uInt16 mnCodePage;
+ rtl_TextEncoding meTextEnc;
+}
+pCodePageTable[] =
+{
+ { 437, RTL_TEXTENCODING_IBM_437 }, // OEM US
+// { 720, RTL_TEXTENCODING_IBM_720 }, // OEM Arabic
+ { 737, RTL_TEXTENCODING_IBM_737 }, // OEM Greek
+ { 775, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic
+ { 850, RTL_TEXTENCODING_IBM_850 }, // OEM Latin I
+ { 852, RTL_TEXTENCODING_IBM_852 }, // OEM Latin II (Central European)
+ { 855, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic
+ { 857, RTL_TEXTENCODING_IBM_857 }, // OEM Turkish
+// { 858, RTL_TEXTENCODING_IBM_858 }, // OEM Multilingual Latin I with Euro
+ { 860, RTL_TEXTENCODING_IBM_860 }, // OEM Portugese
+ { 861, RTL_TEXTENCODING_IBM_861 }, // OEM Icelandic
+ { 862, RTL_TEXTENCODING_IBM_862 }, // OEM Hebrew
+ { 863, RTL_TEXTENCODING_IBM_863 }, // OEM Canadian (French)
+ { 864, RTL_TEXTENCODING_IBM_864 }, // OEM Arabic
+ { 865, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic
+ { 866, RTL_TEXTENCODING_IBM_866 }, // OEM Cyrillic (Russian)
+ { 869, RTL_TEXTENCODING_IBM_869 }, // OEM Greek (Modern)
+ { 874, RTL_TEXTENCODING_MS_874 }, // MS Windows Thai
+ { 932, RTL_TEXTENCODING_MS_932 }, // MS Windows Japanese Shift-JIS
+ { 936, RTL_TEXTENCODING_MS_936 }, // MS Windows Chinese Simplified GBK
+ { 949, RTL_TEXTENCODING_MS_949 }, // MS Windows Korean (Wansung)
+ { 950, RTL_TEXTENCODING_MS_950 }, // MS Windows Chinese Traditional BIG5
+ { 1200, RTL_TEXTENCODING_DONTKNOW }, // Unicode (BIFF8) - return *_DONTKNOW to preserve old code page
+ { 1250, RTL_TEXTENCODING_MS_1250 }, // MS Windows Latin II (Central European)
+ { 1251, RTL_TEXTENCODING_MS_1251 }, // MS Windows Cyrillic
+ { 1252, RTL_TEXTENCODING_MS_1252 }, // MS Windows Latin I (BIFF4-BIFF8)
+ { 1253, RTL_TEXTENCODING_MS_1253 }, // MS Windows Greek
+ { 1254, RTL_TEXTENCODING_MS_1254 }, // MS Windows Turkish
+ { 1255, RTL_TEXTENCODING_MS_1255 }, // MS Windows Hebrew
+ { 1256, RTL_TEXTENCODING_MS_1256 }, // MS Windows Arabic
+ { 1257, RTL_TEXTENCODING_MS_1257 }, // MS Windows Baltic
+ { 1258, RTL_TEXTENCODING_MS_1258 }, // MS Windows Vietnamese
+ { 1361, RTL_TEXTENCODING_MS_1361 }, // MS Windows Korean (Johab)
+ { 10000, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
+ { 32768, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
+ { 32769, RTL_TEXTENCODING_MS_1252 } // MS Windows Latin I (BIFF2-BIFF3)
+};
+const XclCodePageEntry* const pCodePageTableEnd = STATIC_TABLE_END( pCodePageTable );
+
+struct XclCodePageEntry_CPPred
+{
+ inline explicit XclCodePageEntry_CPPred( sal_uInt16 nCodePage ) : mnCodePage( nCodePage ) {}
+ inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.mnCodePage == mnCodePage; }
+ sal_uInt16 mnCodePage;
+};
+
+struct XclCodePageEntry_TEPred
+{
+ inline explicit XclCodePageEntry_TEPred( rtl_TextEncoding eTextEnc ) : meTextEnc( eTextEnc ) {}
+ inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.meTextEnc == meTextEnc; }
+ rtl_TextEncoding meTextEnc;
+};
+
+} // namespace
+
+rtl_TextEncoding XclTools::GetTextEncoding( sal_uInt16 nCodePage )
+{
+ const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_CPPred( nCodePage ) );
+ if( pEntry == pCodePageTableEnd )
+ {
+ DBG_ERROR2( "XclTools::GetTextEncoding - unknown code page: 0x%04hX (%d)", nCodePage, nCodePage );
+ return RTL_TEXTENCODING_DONTKNOW;
+ }
+ return pEntry->meTextEnc;
+}
+
+sal_uInt16 XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc )
+{
+ if( eTextEnc == RTL_TEXTENCODING_UNICODE )
+ return 1200; // for BIFF8
+
+ const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_TEPred( eTextEnc ) );
+ if( pEntry == pCodePageTableEnd )
+ {
+ DBG_ERROR1( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc );
+ return 1252;
+ }
+ return pEntry->mnCodePage;
+}
+
+// font names -----------------------------------------------------------------
+
+String XclTools::GetXclFontName( const String& rFontName )
+{
+ // #106246# substitute with MS fonts
+ String aNewName( GetSubsFontName( rFontName, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
+ if( aNewName.Len() )
+ return aNewName;
+ return rFontName;
+}
+
+// built-in defined names -----------------------------------------------------
+
+const String XclTools::maDefNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
+
+static const sal_Char* const ppcDefNames[] =
+{
+ "Consolidate_Area",
+ "Auto_Open",
+ "Auto_Close",
+ "Extract",
+ "Database",
+ "Criteria",
+ "Print_Area",
+ "Print_Titles",
+ "Recorder",
+ "Data_Form",
+ "Auto_Activate",
+ "Auto_Deactivate",
+ "Sheet_Title",
+ "_FilterDatabase"
+};
+
+String XclTools::GetXclBuiltInDefName( sal_Unicode cBuiltIn )
+{
+ DBG_ASSERT( STATIC_TABLE_SIZE( ppcDefNames ) == EXC_BUILTIN_UNKNOWN,
+ "XclTools::GetXclBuiltInDefName - built-in defined name list modified" );
+ String aDefName;
+ if( cBuiltIn < STATIC_TABLE_SIZE( ppcDefNames ) )
+ aDefName.AssignAscii( ppcDefNames[ cBuiltIn ] );
+ else
+ aDefName = String::CreateFromInt32( cBuiltIn );
+ return aDefName;
+}
+
+String XclTools::GetBuiltInDefName( sal_Unicode cBuiltIn )
+{
+ return String( maDefNamePrefix ).Append( GetXclBuiltInDefName( cBuiltIn ) );
+}
+
+sal_Unicode XclTools::GetBuiltInDefNameIndex( const String& rDefName )
+{
+ xub_StrLen nPrefixLen = maDefNamePrefix.Len();
+ if( rDefName.EqualsIgnoreCaseAscii( maDefNamePrefix, 0, nPrefixLen ) )
+ {
+ for( sal_Unicode cBuiltIn = 0; cBuiltIn < EXC_BUILTIN_UNKNOWN; ++cBuiltIn )
+ {
+ String aBuiltInName( GetXclBuiltInDefName( cBuiltIn ) );
+ xub_StrLen nBuiltInLen = aBuiltInName.Len();
+ if( rDefName.EqualsIgnoreCaseAscii( aBuiltInName, nPrefixLen, nBuiltInLen ) )
+ {
+ // name can be followed by underline or space character
+ xub_StrLen nNextCharPos = nPrefixLen + nBuiltInLen;
+ sal_Unicode cNextChar = (rDefName.Len() > nNextCharPos) ? rDefName.GetChar( nNextCharPos ) : '\0';
+ if( (cNextChar == '\0') || (cNextChar == ' ') || (cNextChar == '_') )
+ return cBuiltIn;
+ }
+ }
+ }
+ return EXC_BUILTIN_UNKNOWN;
+}
+
+// built-in style names -------------------------------------------------------
+
+const String XclTools::maStyleNamePrefix1( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
+const String XclTools::maStyleNamePrefix2( RTL_CONSTASCII_USTRINGPARAM( "Excel Built-in " ) );
+
+static const sal_Char* const ppcStyleNames[] =
+{
+ "", // "Normal" not used directly, but localized "Default"
+ "RowLevel_", // outline level will be appended
+ "ColumnLevel_", // outline level will be appended
+ "Comma",
+ "Currency",
+ "Percent",
+ "Comma_0",
+ "Currency_0",
+ "Hyperlink",
+ "Followed_Hyperlink"
+};
+
+String XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, sal_uInt8 nLevel )
+{
+ String aStyleName;
+
+ if( nStyleId == EXC_STYLE_NORMAL ) // "Normal" becomes "Default" style
+ {
+ aStyleName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
+ }
+ else
+ {
+ aStyleName = maStyleNamePrefix1;
+ if( nStyleId < STATIC_TABLE_SIZE( ppcStyleNames ) )
+ aStyleName.AppendAscii( ppcStyleNames[ nStyleId ] );
+ else if( rName.Len() > 0 )
+ aStyleName.Append( rName );
+ else
+ aStyleName.Append( String::CreateFromInt32( nStyleId ) );
+ if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
+ aStyleName.Append( String::CreateFromInt32( nLevel + 1 ) );
+ }
+
+ return aStyleName;
+}
+
+String XclTools::GetBuiltInStyleName( const String& rStyleName )
+{
+ return String( maStyleNamePrefix1 ).Append( rStyleName );
+}
+
+bool XclTools::IsBuiltInStyleName( const String& rStyleName, sal_uInt8* pnStyleId, xub_StrLen* pnNextChar )
+{
+ // "Default" becomes "Normal"
+ if( rStyleName == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ) )
+ {
+ if( pnStyleId ) *pnStyleId = EXC_STYLE_NORMAL;
+ if( pnNextChar ) *pnNextChar = rStyleName.Len();
+ return true;
+ }
+
+ // try the other built-in styles
+ sal_uInt8 nFoundId = 0;
+ xub_StrLen nNextChar = 0;
+
+ xub_StrLen nPrefixLen = 0;
+ if( rStyleName.EqualsIgnoreCaseAscii( maStyleNamePrefix1, 0, maStyleNamePrefix1.Len() ) )
+ nPrefixLen = maStyleNamePrefix1.Len();
+ else if( rStyleName.EqualsIgnoreCaseAscii( maStyleNamePrefix2, 0, maStyleNamePrefix2.Len() ) )
+ nPrefixLen = maStyleNamePrefix2.Len();
+ if( nPrefixLen > 0 )
+ {
+ String aShortName;
+ for( sal_uInt8 nId = 0; nId < STATIC_TABLE_SIZE( ppcStyleNames ); ++nId )
+ {
+ if( nId != EXC_STYLE_NORMAL )
+ {
+ aShortName.AssignAscii( ppcStyleNames[ nId ] );
+ if( rStyleName.EqualsIgnoreCaseAscii( aShortName, nPrefixLen, aShortName.Len() ) &&
+ (nNextChar < nPrefixLen + aShortName.Len()) )
+ {
+ nFoundId = nId;
+ nNextChar = nPrefixLen + aShortName.Len();
+ }
+ }
+ }
+ }
+
+ if( nNextChar > 0 )
+ {
+ if( pnStyleId ) *pnStyleId = nFoundId;
+ if( pnNextChar ) *pnNextChar = nNextChar;
+ return true;
+ }
+
+ if( pnStyleId ) *pnStyleId = EXC_STYLE_USERDEF;
+ if( pnNextChar ) *pnNextChar = 0;
+ return nPrefixLen > 0; // also return true for unknown built-in styles
+}
+
+bool XclTools::GetBuiltInStyleId( sal_uInt8& rnStyleId, sal_uInt8& rnLevel, const String& rStyleName )
+{
+ sal_uInt8 nStyleId;
+ xub_StrLen nNextChar;
+ if( IsBuiltInStyleName( rStyleName, &nStyleId, &nNextChar ) && (nStyleId != EXC_STYLE_USERDEF) )
+ {
+ if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
+ {
+ String aLevel( rStyleName, nNextChar, STRING_LEN );
+ sal_Int32 nLevel = aLevel.ToInt32();
+ if( (String::CreateFromInt32( nLevel ) == aLevel) && (nLevel > 0) && (nLevel <= EXC_STYLE_LEVELCOUNT) )
+ {
+ rnStyleId = nStyleId;
+ rnLevel = static_cast< sal_uInt8 >( nLevel - 1 );
+ return true;
+ }
+ }
+ else if( rStyleName.Len() == nNextChar )
+ {
+ rnStyleId = nStyleId;
+ rnLevel = EXC_STYLE_NOLEVEL;
+ return true;
+ }
+ }
+ rnStyleId = EXC_STYLE_USERDEF;
+ rnLevel = EXC_STYLE_NOLEVEL;
+ return false;
+}
+
+// conditional formatting style names -----------------------------------------
+
+const String XclTools::maCFStyleNamePrefix1( RTL_CONSTASCII_USTRINGPARAM( "Excel_CondFormat_" ) );
+const String XclTools::maCFStyleNamePrefix2( RTL_CONSTASCII_USTRINGPARAM( "ConditionalStyle_" ) );
+
+String XclTools::GetCondFormatStyleName( SCTAB nScTab, sal_Int32 nFormat, sal_uInt16 nCondition )
+{
+ return String( maCFStyleNamePrefix1 ).Append( String::CreateFromInt32( nScTab + 1 ) ).
+ Append( '_' ).Append( String::CreateFromInt32( nFormat + 1 ) ).
+ Append( '_' ).Append( String::CreateFromInt32( nCondition + 1 ) );
+}
+
+bool XclTools::IsCondFormatStyleName( const String& rStyleName, xub_StrLen* pnNextChar )
+{
+ xub_StrLen nPrefixLen = 0;
+ if( rStyleName.EqualsIgnoreCaseAscii( maCFStyleNamePrefix1, 0, maCFStyleNamePrefix1.Len() ) )
+ nPrefixLen = maCFStyleNamePrefix1.Len();
+ else if( rStyleName.EqualsIgnoreCaseAscii( maCFStyleNamePrefix2, 0, maCFStyleNamePrefix2.Len() ) )
+ nPrefixLen = maCFStyleNamePrefix2.Len();
+ if( pnNextChar ) *pnNextChar = nPrefixLen;
+ return nPrefixLen > 0;
+}
+
+// stream handling ------------------------------------------------------------
+
+void XclTools::SkipSubStream( XclImpStream& rStrm )
+{
+ bool bLoop = true;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bLoop = nRecId != EXC_ID_EOF;
+ if( (nRecId == EXC_ID2_BOF) || (nRecId == EXC_ID3_BOF) || (nRecId == EXC_ID4_BOF) || (nRecId == EXC_ID5_BOF) )
+ SkipSubStream( rStrm );
+ }
+}
+
+// Basic macro names ----------------------------------------------------------
+
+const OUString XclTools::maSbMacroPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:Standard." ) );
+const OUString XclTools::maSbMacroSuffix( RTL_CONSTASCII_USTRINGPARAM( "?language=Basic&location=document" ) );
+
+OUString XclTools::GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell )
+{
+ OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" );
+ ::ooo::vba::VBAMacroResolvedInfo aMacroInfo = ::ooo::vba::resolveVBAMacro( pDocShell, rMacroName, false );
+ if( aMacroInfo.IsResolved() )
+ return ::ooo::vba::makeMacroURL( aMacroInfo.ResolvedMacro() );
+ return OUString();
+}
+
+OUString XclTools::GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell )
+{
+ OSL_ENSURE( rModuleName.Len() > 0, "XclTools::GetSbMacroUrl - module name is empty" );
+ OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" );
+ return GetSbMacroUrl( rModuleName + OUString( sal_Unicode( '.' ) ) + rMacroName, pDocShell );
+}
+
+String XclTools::GetXclMacroName( const OUString& rSbMacroUrl )
+{
+ sal_Int32 nSbMacroUrlLen = rSbMacroUrl.getLength();
+ sal_Int32 nMacroNameLen = nSbMacroUrlLen - maSbMacroPrefix.getLength() - maSbMacroSuffix.getLength();
+ if( (nMacroNameLen > 0) && rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroPrefix, 0 ) &&
+ rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroSuffix, nSbMacroUrlLen - maSbMacroSuffix.getLength() ) )
+ return rSbMacroUrl.copy( maSbMacroPrefix.getLength(), nMacroNameLen );
+ return String::EmptyString();
+}
+
+// read/write colors ----------------------------------------------------------
+
+XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor )
+{
+ sal_uInt8 nR, nG, nB, nD;
+ rStrm >> nR >> nG >> nB >> nD;
+ rColor.SetColor( RGB_COLORDATA( nR, nG, nB ) );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor )
+{
+ return rStrm << rColor.GetRed() << rColor.GetGreen() << rColor.GetBlue() << sal_uInt8( 0 );
+}
+
+// ============================================================================
diff --git a/sc/source/filter/excel/xltracer.cxx b/sc/source/filter/excel/xltracer.cxx
new file mode 100644
index 000000000000..7dadbde8198a
--- /dev/null
+++ b/sc/source/filter/excel/xltracer.cxx
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// ============================================================================
+#include "xltracer.hxx"
+#include <filter/msfilter/msfiltertracer.hxx>
+#include "address.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::beans::PropertyValue;
+
+// ============================================================================
+
+// Trace Table details are grouped by functionality using the context entry.
+// Each separate context starts at the next 1000 interval. New entries should
+// be added to their appropriate context. New contexts should be added onto
+// the end. Any gaps in the 1000 sequence or within the 1000 are the result
+// of trace events no longer present.
+static const XclTracerDetails pTracerDetails[] =
+{
+ { eUnKnown, 0, "UNKNOWN", "UNKNOWN", "Unknown trace property." },
+ { eRowLimitExceeded, 1000, "Limits", "Sheet", "Row limit exceeded." },
+ { eTabLimitExceeded, 1001, "Limits", "Sheet", "Sheet limit exceeded." },
+ { ePassword, 2000, "Protection", "Password", "Document is password protected." },
+ { ePrintRange, 3000, "Print", "Print Range", "Print Range present." },
+ { eShortDate, 4000, "CellFormatting", "Short Dates", "Possible Date format issue." },
+ { eBorderLineStyle, 4004, "CellFormatting", "Border", "Line style not supported.", },
+ { eFillPattern, 4005, "CellFormatting", "Pattern", "Fill Pattern not supported.", },
+ { eInvisibleGrid, 5000, "Properties", "Grid Invisible", "Grid invisible on first sheet." },
+ { eFormattedNote, 6000, "Notes", "Formatting", "Text may be formatted." },
+ { eFormulaExtName, 7000, "Formula", "External Name", "External names not supported." },
+ { eFormulaMissingArg, 7001, "Formula", "Missing Argument","Parameter missing." },
+ { ePivotDataSource, 8000, "Chart", "Pivot", "External data source not supported."},
+ { ePivotChartExists, 8001, "Chart", "Pivot", "Pivot Chart not supported."},
+ { eChartUnKnownType, 8002, "Chart", "Type", "Chart Type not supported."},
+ { eChartTrendLines, 8003, "Chart", "Type", "Chart trendlines not supported."},
+ { eChartOnlySheet, 8004, "Chart", "Type", "Chart only sheet not supported."},
+ { eChartRange, 8005, "Chart", "Source Data", "Chart source ranges too complex."},
+ { eChartDSName, 8006, "Chart", "Source Data", "Series titles not linked to cells."},
+ { eChartDataTable, 8007, "Chart", "Legend", "Data table not supported."},
+ { eChartLegendPosition, 8008, "Chart", "Legend", "Position not guaranteed."},
+ { eChartTextFormatting, 8009, "Chart", "Formatting", "Text formatting present."},
+ { eChartEmbeddedObj, 8010, "Chart", "Area", "Object inside chart."},
+ { eChartAxisAuto, 8012, "Chart", "Axis", "Axis interval is automatic."},
+ { eChartInvalidXY, 8013, "Chart", "Scatter", "Unsupported or invalid data range for XY chart."},
+ { eChartErrorBars, 8014, "Chart", "Type", "Chart error bars not supported."},
+ { eChartAxisManual, 8015, "Chart", "Axis", "Manual axis crossing point adjusted."},
+ { eUnsupportedObject, 9000, "Object", "Type", "Limited Object support."},
+ { eObjectNotPrintable, 9001, "Object", "Print", "Object not printable."},
+ { eDVType, 10000, "DataValidation", "Type", "Custom type present."}
+};
+
+XclTracer::XclTracer( const String& rDocUrl, const OUString& rConfigPath ) :
+ maFirstTimes(eTraceLength,true)
+{
+ Sequence< PropertyValue > aConfigData( 1 );
+ aConfigData[ 0 ].Name = CREATE_OUSTRING( "DocumentURL" );
+ aConfigData[ 0 ].Value <<= OUString( rDocUrl );
+ mpTracer.reset( new MSFilterTracer( rConfigPath, &aConfigData ) );
+ mpTracer->StartTracing();
+ mbEnabled = mpTracer->IsEnabled();
+}
+
+XclTracer::~XclTracer()
+{
+ mpTracer->EndTracing();
+}
+
+void XclTracer::AddAttribute( const OUString& rName, const OUString& rValue )
+{
+ if( mbEnabled )
+ mpTracer->AddAttribute( rName, rValue );
+}
+
+void XclTracer::Trace( const OUString& rElementID, const OUString& rMessage )
+{
+ if( mbEnabled )
+ {
+ mpTracer->Trace( rElementID, rMessage );
+ mpTracer->ClearAttributes();
+ }
+}
+
+void XclTracer::TraceLog( XclTracerId eProblem, sal_Int32 nValue )
+{
+ if( mbEnabled )
+ {
+ OUString sID( CREATE_STRING( "SC" ) );
+ sID += OUString::valueOf( static_cast< sal_Int32 >( pTracerDetails[ eProblem ].mnID ) );
+ OUString sProblem = OUString::createFromAscii( pTracerDetails[ eProblem ].mpProblem );
+
+ switch (eProblem)
+ {
+ case eRowLimitExceeded:
+ Context(eProblem,static_cast<SCTAB>(nValue));
+ break;
+ case eTabLimitExceeded:
+ Context(eProblem,static_cast<SCTAB>(nValue));
+ break;
+ default:
+ Context(eProblem);
+ break;
+ }
+ Trace(sID, sProblem);
+ }
+}
+
+void XclTracer::Context( XclTracerId eProblem, SCTAB nTab )
+{
+ OUString sContext = OUString::createFromAscii( pTracerDetails[ eProblem ].mpContext );
+ OUString sDetail = OUString::createFromAscii( pTracerDetails[ eProblem ].mpDetail );
+
+ switch (eProblem)
+ {
+ case eRowLimitExceeded:
+ case eTabLimitExceeded:
+ sDetail += OUString::valueOf( static_cast< sal_Int32 >( nTab + 1 ) );
+ break;
+ default:
+ break;
+ }
+ AddAttribute(sContext, sDetail);
+}
+
+void XclTracer::ProcessTraceOnce(XclTracerId eProblem, SCTAB nTab)
+{
+ if( mbEnabled && maFirstTimes[eProblem])
+ {
+ TraceLog(pTracerDetails[eProblem].meProblemId, nTab);
+ maFirstTimes[eProblem] = false;
+ }
+}
+
+void XclTracer::TraceInvalidAddress( const ScAddress& rPos, const ScAddress& rMaxPos )
+{
+ TraceInvalidRow(rPos.Tab(), rPos.Row(), rMaxPos.Row());
+ TraceInvalidTab(rPos.Tab(), rMaxPos.Tab());
+}
+
+void XclTracer::TraceInvalidRow( SCTAB nTab, sal_uInt32 nRow, sal_uInt32 nMaxRow )
+{
+ if(nRow > nMaxRow)
+ ProcessTraceOnce(eRowLimitExceeded, nTab);
+}
+
+void XclTracer::TraceInvalidTab( SCTAB nTab, SCTAB nMaxTab )
+{
+ if(nTab > nMaxTab)
+ ProcessTraceOnce(eTabLimitExceeded, nTab);
+}
+
+void XclTracer::TracePrintRange()
+{
+ ProcessTraceOnce( ePrintRange);
+}
+
+void XclTracer::TraceDates( sal_uInt16 nNumFmt)
+{
+ // Short Date = 14 and Short Date+Time = 22
+ if(nNumFmt == 14 || nNumFmt == 22)
+ ProcessTraceOnce(eShortDate);
+}
+
+void XclTracer::TraceBorderLineStyle( bool bBorderLineStyle)
+{
+ if(bBorderLineStyle)
+ ProcessTraceOnce(eBorderLineStyle);
+}
+
+void XclTracer::TraceFillPattern( bool bFillPattern)
+{
+ if(bFillPattern)
+ ProcessTraceOnce(eFillPattern);
+}
+
+void XclTracer::TraceFormulaMissingArg()
+{
+ // missing parameter in Formula record
+ ProcessTraceOnce(eFormulaMissingArg);
+}
+
+void XclTracer::TracePivotDataSource( bool bExternal)
+{
+ if(bExternal)
+ ProcessTraceOnce(ePivotDataSource);
+}
+
+void XclTracer::TracePivotChartExists()
+{
+ // Pivot Charts not currently displayed.
+ ProcessTraceOnce(ePivotChartExists);
+}
+
+void XclTracer::TraceChartUnKnownType()
+{
+ ProcessTraceOnce(eChartUnKnownType);
+}
+
+void XclTracer::TraceChartOnlySheet()
+{
+ ProcessTraceOnce(eChartOnlySheet);
+}
+
+void XclTracer::TraceChartDataTable()
+{
+ // Data table is not supported.
+ ProcessTraceOnce(eChartDataTable);
+}
+
+void XclTracer::TraceChartLegendPosition()
+{
+ // If position is set to "not docked or inside the plot area" then
+ // we cannot guarantee the legend position.
+ ProcessTraceOnce(eChartLegendPosition);
+}
+
+void XclTracer::TraceChartEmbeddedObj()
+{
+ // drawing objects e.g. text boxes etc not supported inside charts
+ ProcessTraceOnce(eChartEmbeddedObj);
+}
+
+void XclTracer::TraceUnsupportedObjects()
+{
+ // Called from Excel 5.0 - limited Graphical object support.
+ ProcessTraceOnce(eUnsupportedObject);
+}
+
+void XclTracer::TraceObjectNotPrintable()
+{
+ ProcessTraceOnce(eObjectNotPrintable);
+}
+
+void XclTracer::TraceDVType( bool bType)
+{
+ // Custom types work if 'Data->validity dialog' is not OKed.
+ if(bType)
+ ProcessTraceOnce(eDVType);
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/excel/xlview.cxx b/sc/source/filter/excel/xlview.cxx
new file mode 100644
index 000000000000..8e9df7e0ac1f
--- /dev/null
+++ b/sc/source/filter/excel/xlview.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlview.hxx"
+#include "ftools.hxx"
+
+// Structs ====================================================================
+
+XclDocViewData::XclDocViewData() :
+ mnWinX( 0 ),
+ mnWinY( 0 ),
+ mnWinWidth( 0 ),
+ mnWinHeight( 0 ),
+ mnFlags( EXC_WIN1_HOR_SCROLLBAR | EXC_WIN1_VER_SCROLLBAR | EXC_WIN1_TABBAR ),
+ mnDisplXclTab( 0 ),
+ mnFirstVisXclTab( 0 ),
+ mnXclSelectCnt( 1 ),
+ mnTabBarWidth( 600 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclTabViewData::XclTabViewData() :
+ maFirstXclPos( ScAddress::UNINITIALIZED ),
+ maSecondXclPos( ScAddress::UNINITIALIZED )
+{
+ SetDefaults();
+}
+
+XclTabViewData::~XclTabViewData()
+{
+}
+
+void XclTabViewData::SetDefaults()
+{
+ maSelMap.clear();
+ maGridColor.SetColor( COL_AUTO );
+ maFirstXclPos.Set( 0, 0 );
+ maSecondXclPos.Set( 0, 0 );
+ mnSplitX = mnSplitY = 0;
+ mnNormalZoom = EXC_WIN2_NORMALZOOM_DEF;
+ mnPageZoom = EXC_WIN2_PAGEZOOM_DEF;
+ mnCurrentZoom = 0; // default to mnNormalZoom or mnPageZoom
+ mnActivePane = EXC_PANE_TOPLEFT;
+ mbSelected = mbDisplayed = false;
+ mbMirrored = false;
+ mbFrozenPanes = false;
+ mbPageMode = false;
+ mbDefGridColor = true;
+ mbShowFormulas = false;
+ mbShowGrid = mbShowHeadings = mbShowZeros = mbShowOutline = true;
+ maTabBgColor.SetColor( COL_AUTO );
+}
+
+bool XclTabViewData::IsSplit() const
+{
+ return (mnSplitX > 0) || (mnSplitY > 0);
+}
+
+bool XclTabViewData::HasPane( sal_uInt8 nPaneId ) const
+{
+ switch( nPaneId )
+ {
+ case EXC_PANE_BOTTOMRIGHT: return (mnSplitX > 0) && (mnSplitY > 0);
+ case EXC_PANE_TOPRIGHT: return mnSplitX > 0;
+ case EXC_PANE_BOTTOMLEFT: return mnSplitY > 0;
+ case EXC_PANE_TOPLEFT: return true;
+ }
+ DBG_ERRORFILE( "XclExpPane::HasPane - wrong pane ID" );
+ return false;
+}
+
+const XclSelectionData* XclTabViewData::GetSelectionData( sal_uInt8 nPane ) const
+{
+ XclSelectionMap::const_iterator aIt = maSelMap.find( nPane );
+ return (aIt == maSelMap.end()) ? 0 : aIt->second.get();
+}
+
+XclSelectionData& XclTabViewData::CreateSelectionData( sal_uInt8 nPane )
+{
+ XclSelectionDataRef& rxSelData = maSelMap[ nPane ];
+ if( !rxSelData )
+ rxSelData.reset( new XclSelectionData );
+ return *rxSelData;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/ftools/fapihelper.cxx b/sc/source/filter/ftools/fapihelper.cxx
new file mode 100644
index 000000000000..eeef52aed550
--- /dev/null
+++ b/sc/source/filter/ftools/fapihelper.cxx
@@ -0,0 +1,412 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "fapihelper.hxx"
+
+#include <algorithm>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <comphelper/docpasswordhelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/stritem.hxx>
+#include <svl/itemset.hxx>
+#include "miscuno.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::TypeClass_BOOLEAN;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertyState;
+using ::com::sun::star::lang::XServiceName;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER;
+
+// Static helper functions ====================================================
+
+OUString ScfApiHelper::GetServiceName( Reference< XInterface > xInt )
+{
+ OUString aService;
+ Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
+ if( xServiceName.is() )
+ aService = xServiceName->getServiceName();
+ return aService;
+}
+
+Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( SfxObjectShell* pShell )
+{
+ Reference< XMultiServiceFactory > xFactory;
+ if( pShell )
+ xFactory.set( pShell->GetModel(), UNO_QUERY );
+ return xFactory;
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstance(
+ Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName )
+{
+ Reference< XInterface > xInt;
+ if( xFactory.is() )
+ {
+ try
+ {
+ xInt = xFactory->createInstance( rServiceName );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "ScfApiHelper::CreateInstance - cannot create instance" );
+ }
+ }
+ return xInt;
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstance( SfxObjectShell* pShell, const OUString& rServiceName )
+{
+ return CreateInstance( GetServiceFactory( pShell ), rServiceName );
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
+{
+ return CreateInstance( ::comphelper::getProcessServiceFactory(), rServiceName );
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
+ Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName, const Sequence< Any >& rArgs )
+{
+ Reference< XInterface > xInt;
+ if( xFactory.is() )
+ {
+ try
+ {
+ xInt = xFactory->createInstanceWithArguments( rServiceName, rArgs );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "ScfApiHelper::CreateInstanceWithArgs - cannot create instance" );
+ }
+ }
+ return xInt;
+}
+
+//UNUSED2008-05 Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
+//UNUSED2008-05 SfxObjectShell* pShell, const OUString& rServiceName, const Sequence< Any >& rArgs )
+//UNUSED2008-05 {
+//UNUSED2008-05 return CreateInstanceWithArgs( GetServiceFactory( pShell ), rServiceName, rArgs );
+//UNUSED2008-05 }
+
+Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
+ const OUString& rServiceName, const Sequence< Any >& rArgs )
+{
+ return CreateInstanceWithArgs( ::comphelper::getProcessServiceFactory(), rServiceName, rArgs );
+}
+
+String ScfApiHelper::QueryPasswordForMedium( SfxMedium& rMedium,
+ ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords )
+{
+ OUString aMediaPassword;
+ SfxItemSet* pItemSet = rMedium.GetItemSet();
+ const SfxPoolItem *pPasswordItem;
+ if( pItemSet && (SFX_ITEM_SET == pItemSet->GetItemState( SID_PASSWORD, TRUE, &pPasswordItem )) )
+ aMediaPassword = static_cast< const SfxStringItem* >( pPasswordItem )->GetValue();
+ OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
+
+ bool bIsDefaultPassword = false;
+ OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+ rVerifier, aMediaPassword, rMedium.GetInteractionHandler(), aDocName,
+ ::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword );
+
+ if( !bIsDefaultPassword && (aPassword.getLength() > 0) && pItemSet )
+ pItemSet->Put( SfxStringItem( SID_PASSWORD, aPassword ) );
+
+ return aPassword;
+}
+
+// Property sets ==============================================================
+
+void ScfPropertySet::Set( Reference< XPropertySet > xPropSet )
+{
+ mxPropSet = xPropSet;
+ mxMultiPropSet.set( mxPropSet, UNO_QUERY );
+}
+
+OUString ScfPropertySet::GetServiceName() const
+{
+ return ScfApiHelper::GetServiceName( mxPropSet );
+}
+
+// Get properties -------------------------------------------------------------
+
+bool ScfPropertySet::HasProperty( const OUString& rPropName ) const
+{
+ bool bHasProp = false;
+ try
+ {
+ Reference< XPropertyState > xPropState( mxPropSet, UNO_QUERY_THROW );
+ bHasProp = xPropState->getPropertyState( rPropName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
+ }
+ catch( Exception& )
+ {
+ }
+ return bHasProp;
+}
+
+bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
+{
+ bool bHasValue = false;
+ try
+ {
+ if( mxPropSet.is() )
+ {
+ rValue = mxPropSet->getPropertyValue( rPropName );
+ bHasValue = true;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return bHasValue;
+}
+
+bool ScfPropertySet::GetBoolProperty( const ::rtl::OUString& rPropName ) const
+{
+ Any aAny;
+ return GetAnyProperty( aAny, rPropName ) && ScUnoHelpFunctions::GetBoolFromAny( aAny );
+}
+
+bool ScfPropertySet::GetStringProperty( String& rValue, const OUString& rPropName ) const
+{
+ OUString aOUString;
+ bool bRet = GetProperty( aOUString, rPropName );
+ rValue = aOUString;
+ return bRet;
+}
+
+bool ScfPropertySet::GetColorProperty( Color& rColor, const ::rtl::OUString& rPropName ) const
+{
+ sal_Int32 nApiColor = 0;
+ bool bRet = GetProperty( nApiColor, rPropName );
+ rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
+ return bRet;
+}
+
+void ScfPropertySet::GetProperties( Sequence< Any >& rValues, const Sequence< OUString >& rPropNames ) const
+{
+ try
+ {
+ DBG_ASSERT( mxMultiPropSet.is(), "ScfPropertySet::GetProperties - multi property set not available" );
+ if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
+ {
+ rValues = mxMultiPropSet->getPropertyValues( rPropNames );
+ }
+ else if( mxPropSet.is() )
+ {
+ sal_Int32 nLen = rPropNames.getLength();
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + nLen;
+ rValues.realloc( nLen );
+ Any* pValue = rValues.getArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ *pValue = mxPropSet->getPropertyValue( *pPropName );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// Set properties -------------------------------------------------------------
+
+void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
+{
+ try
+ {
+ if( mxPropSet.is() )
+ mxPropSet->setPropertyValue( rPropName, rValue );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE(
+ ByteString( "ScfPropertySet::SetAnyProperty - cannot set property \"" ).
+ Append( ByteString( String( rPropName ), RTL_TEXTENCODING_ASCII_US ) ).
+ Append( '"' ).
+ GetBuffer() );
+ }
+}
+
+void ScfPropertySet::SetProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
+{
+ DBG_ASSERT( rPropNames.getLength() == rValues.getLength(), "ScfPropertySet::SetProperties - length of sequences different" );
+ try
+ {
+ if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
+ {
+ mxMultiPropSet->setPropertyValues( rPropNames, rValues );
+ }
+ else if( mxPropSet.is() )
+ {
+ DBG_ERRORFILE( "ScfPropertySet::SetProperties - multi property set not available" );
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
+ const Any* pValue = rValues.getConstArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ mxPropSet->setPropertyValue( *pPropName, *pValue );
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "ScfPropertySet::SetAnyProperty - cannot set multiple properties" );
+ }
+}
+
+// ============================================================================
+
+ScfPropSetHelper::ScfPropSetHelper( const sal_Char* const* ppcPropNames ) :
+ mnNextIdx( 0 )
+{
+ DBG_ASSERT( ppcPropNames, "ScfPropSetHelper::ScfPropSetHelper - no strings found" );
+
+ // create OUStrings from ASCII property names
+ typedef ::std::pair< OUString, size_t > IndexedOUString;
+ typedef ::std::vector< IndexedOUString > IndexedOUStringVec;
+ IndexedOUStringVec aPropNameVec;
+ for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
+ {
+ OUString aPropName = OUString::createFromAscii( *ppcPropNames );
+ aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx ) );
+ }
+
+ // sorts the pairs, which will be sorted by first component (the property name)
+ ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
+
+ // resize member sequences
+ size_t nSize = aPropNameVec.size();
+ maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
+ maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
+ maNameOrder.resize( nSize );
+
+ // fill the property name sequence and store original sort order
+ sal_Int32 nSeqIdx = 0;
+ for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
+ aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
+ {
+ maNameSeq[ nSeqIdx ] = aIt->first;
+ maNameOrder[ aIt->second ] = nSeqIdx;
+ }
+}
+
+// read properties ------------------------------------------------------------
+
+void ScfPropSetHelper::ReadFromPropertySet( const ScfPropertySet& rPropSet )
+{
+ rPropSet.GetProperties( maValueSeq, maNameSeq );
+ mnNextIdx = 0;
+}
+
+bool ScfPropSetHelper::ReadValue( UnoAny& rAny )
+{
+ UnoAny* pAny = GetNextAny();
+ if( pAny )
+ rAny = *pAny;
+ return pAny != 0;
+}
+
+bool ScfPropSetHelper::ReadValue( String& rString )
+{
+ OUString aOUString;
+ bool bRet = ReadValue( aOUString );
+ rString = aOUString;
+ return bRet;
+}
+
+bool ScfPropSetHelper::ReadValue( Color& rColor )
+{
+ sal_Int32 nApiColor(0);
+ bool bRet = ReadValue( nApiColor );
+ rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
+ return bRet;
+}
+
+bool ScfPropSetHelper::ReadValue( bool& rbValue )
+{
+ Any aAny;
+ bool bRet = ReadValue( aAny );
+ rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
+ return bRet;
+}
+
+// write properties -----------------------------------------------------------
+
+void ScfPropSetHelper::InitializeWrite( bool bClearAllAnys )
+{
+ mnNextIdx = 0;
+ if( bClearAllAnys )
+ for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
+ maValueSeq[ nIdx ].clear();
+}
+
+void ScfPropSetHelper::WriteValue( const Any& rAny )
+{
+ if( UnoAny* pAny = GetNextAny() )
+ *pAny = rAny;
+}
+
+void ScfPropSetHelper::WriteValue( const bool& rbValue )
+{
+ if( Any* pAny = GetNextAny() )
+ ScUnoHelpFunctions::SetBoolInAny( *pAny, rbValue );
+}
+
+void ScfPropSetHelper::WriteToPropertySet( ScfPropertySet& rPropSet ) const
+{
+ rPropSet.SetProperties( maNameSeq, maValueSeq );
+}
+
+// private --------------------------------------------------------------------
+
+Any* ScfPropSetHelper::GetNextAny()
+{
+ DBG_ASSERT( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
+ Any* pAny = 0;
+ if( mnNextIdx < maNameOrder.size() )
+ pAny = &maValueSeq[ maNameOrder[ mnNextIdx++ ] ];
+ return pAny;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/ftools/fprogressbar.cxx b/sc/source/filter/ftools/fprogressbar.cxx
new file mode 100644
index 000000000000..bcee6f690f48
--- /dev/null
+++ b/sc/source/filter/ftools/fprogressbar.cxx
@@ -0,0 +1,260 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "fprogressbar.hxx"
+#include "global.hxx"
+#include "progress.hxx"
+
+// ============================================================================
+
+ScfProgressBar::ScfProgressSegment::ScfProgressSegment( sal_Size nSize ) :
+ mxProgress( 0 ),
+ mnSize( nSize ),
+ mnPos( 0 )
+{
+}
+
+ScfProgressBar::ScfProgressSegment::~ScfProgressSegment()
+{
+}
+
+// ============================================================================
+
+ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, const String& rText ) :
+ maText( rText )
+{
+ Init( pDocShell );
+}
+
+ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, USHORT nResId ) :
+ maText( ScGlobal::GetRscString( nResId ) )
+{
+ Init( pDocShell );
+}
+
+ScfProgressBar::ScfProgressBar( ScfProgressBar& rParProgress, ScfProgressSegment* pParSegment )
+{
+ Init( rParProgress.mpDocShell );
+ mpParentProgress = &rParProgress;
+ mpParentSegment = pParSegment;
+}
+
+ScfProgressBar::~ScfProgressBar()
+{
+}
+
+void ScfProgressBar::Init( SfxObjectShell* pDocShell )
+{
+ mpDocShell = pDocShell;
+ mpParentProgress = 0;
+ mpParentSegment = mpCurrSegment = 0;
+ mnTotalSize = mnTotalPos = mnUnitSize = mnNextUnitPos = 0;
+ mnSysProgressScale = 1; // used to workaround the ULONG_MAX/100 limit
+ mbInProgress = false;
+}
+
+ScfProgressBar::ScfProgressSegment* ScfProgressBar::GetSegment( sal_Int32 nSegment ) const
+{
+ if( nSegment < 0 )
+ return 0;
+ DBG_ASSERT( maSegments.GetObject( nSegment ), "ScfProgressBar::GetSegment - invalid segment index" );
+ return maSegments.GetObject( nSegment );
+}
+
+void ScfProgressBar::SetCurrSegment( ScfProgressSegment* pSegment )
+{
+ if( mpCurrSegment != pSegment )
+ {
+ mpCurrSegment = pSegment;
+
+ if( mpParentProgress && mpParentSegment )
+ {
+ mpParentProgress->SetCurrSegment( mpParentSegment );
+ }
+ else if( !mxSysProgress.get() && (mnTotalSize > 0) )
+ {
+ // System progress has an internal limit of ULONG_MAX/100.
+ mnSysProgressScale = 1;
+ ULONG nSysTotalSize = static_cast< ULONG >( mnTotalSize );
+ while( nSysTotalSize >= ULONG_MAX / 100 )
+ {
+ nSysTotalSize /= 2;
+ mnSysProgressScale *= 2;
+ }
+ mxSysProgress.reset( new ScProgress( mpDocShell, maText, nSysTotalSize ) );
+ }
+
+ if( !mbInProgress && mpCurrSegment && (mnTotalSize > 0) )
+ {
+ mnUnitSize = mnTotalSize / 256 + 1; // at most 256 calls of system progress
+ mnNextUnitPos = 0;
+ mbInProgress = true;
+ }
+ }
+}
+
+void ScfProgressBar::IncreaseProgressBar( sal_Size nDelta )
+{
+ sal_Size nNewPos = mnTotalPos + nDelta;
+
+ // call back to parent progress bar
+ if( mpParentProgress && mpParentSegment )
+ {
+ // calculate new position of parent progress bar
+ sal_Size nParentPos = static_cast< sal_Size >(
+ static_cast< double >( nNewPos ) * mpParentSegment->mnSize / mnTotalSize );
+ mpParentProgress->ProgressAbs( nParentPos );
+ }
+ // modify system progress bar
+ else if( mxSysProgress.get() )
+ {
+ if( nNewPos >= mnNextUnitPos )
+ {
+ mnNextUnitPos = nNewPos + mnUnitSize;
+ mxSysProgress->SetState( static_cast< ULONG >( nNewPos / mnSysProgressScale ) );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScfProgressBar::IncreaseProgressBar - no progress bar found" );
+ }
+
+ mnTotalPos = nNewPos;
+}
+
+sal_Int32 ScfProgressBar::AddSegment( sal_Size nSize )
+{
+ DBG_ASSERT( !mbInProgress, "ScfProgressBar::AddSegment - already in progress mode" );
+ if( nSize == 0 )
+ return SCF_INV_SEGMENT;
+
+ maSegments.Append( new ScfProgressSegment( nSize ) );
+ mnTotalSize += nSize;
+ return static_cast< sal_Int32 >( maSegments.Count() - 1 );
+}
+
+ScfProgressBar& ScfProgressBar::GetSegmentProgressBar( sal_Int32 nSegment )
+{
+ ScfProgressSegment* pSegment = GetSegment( nSegment );
+ DBG_ASSERT( !pSegment || (pSegment->mnPos == 0), "ScfProgressBar::GetSegmentProgressBar - segment already started" );
+ if( pSegment && (pSegment->mnPos == 0) )
+ {
+ if( !pSegment->mxProgress.get() )
+ pSegment->mxProgress.reset( new ScfProgressBar( *this, pSegment ) );
+ return *pSegment->mxProgress;
+ }
+ return *this;
+}
+
+bool ScfProgressBar::IsFull() const
+{
+ DBG_ASSERT( mbInProgress && mpCurrSegment, "ScfProgressBar::IsFull - no segment started" );
+ return mpCurrSegment && (mpCurrSegment->mnPos >= mpCurrSegment->mnSize);
+}
+
+void ScfProgressBar::ActivateSegment( sal_Int32 nSegment )
+{
+ DBG_ASSERT( mnTotalSize > 0, "ScfProgressBar::ActivateSegment - progress range is zero" );
+ if( mnTotalSize > 0 )
+ SetCurrSegment( GetSegment( nSegment ) );
+}
+
+void ScfProgressBar::ProgressAbs( sal_Size nPos )
+{
+ DBG_ASSERT( mbInProgress && mpCurrSegment, "ScfProgressBar::ProgressAbs - no segment started" );
+ if( mpCurrSegment )
+ {
+ DBG_ASSERT( mpCurrSegment->mnPos <= nPos, "ScfProgressBar::ProgressAbs - delta pos < 0" );
+ DBG_ASSERT( nPos <= mpCurrSegment->mnSize, "ScfProgressBar::ProgressAbs - segment overflow" );
+ if( (mpCurrSegment->mnPos < nPos) && (nPos <= mpCurrSegment->mnSize) )
+ {
+ IncreaseProgressBar( nPos - mpCurrSegment->mnPos );
+ mpCurrSegment->mnPos = nPos;
+ }
+ }
+}
+
+void ScfProgressBar::Progress( sal_Size nDelta )
+{
+ ProgressAbs( mpCurrSegment ? (mpCurrSegment->mnPos + nDelta) : 0 );
+}
+
+// ============================================================================
+
+ScfSimpleProgressBar::ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, const String& rText ) :
+ maProgress( pDocShell, rText )
+{
+ Init( nSize );
+}
+
+ScfSimpleProgressBar::ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, USHORT nResId ) :
+ maProgress( pDocShell, nResId )
+{
+ Init( nSize );
+}
+
+void ScfSimpleProgressBar::Init( sal_Size nSize )
+{
+ sal_Int32 nSegment = maProgress.AddSegment( nSize );
+ if( nSegment >= 0 )
+ maProgress.ActivateSegment( nSegment );
+}
+
+// ============================================================================
+
+//UNUSED2008-05 ScfStreamProgressBar::ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, const String& rText ) :
+//UNUSED2008-05 mrStrm( rStrm )
+//UNUSED2008-05 {
+//UNUSED2008-05 Init( pDocShell, rText );
+//UNUSED2008-05 }
+
+ScfStreamProgressBar::ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, USHORT nResId ) :
+ mrStrm( rStrm )
+{
+ Init( pDocShell, ScGlobal::GetRscString( nResId ) );
+}
+
+void ScfStreamProgressBar::Progress()
+{
+ mxProgress->ProgressAbs( mrStrm.Tell() );
+}
+
+void ScfStreamProgressBar::Init( SfxObjectShell* pDocShell, const String& rText )
+{
+ sal_Size nPos = mrStrm.Tell();
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ sal_Size nSize = mrStrm.Tell();
+ mrStrm.Seek( nPos );
+
+ mxProgress.reset( new ScfSimpleProgressBar( nSize, pDocShell, rText ) );
+ Progress();
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/ftools/ftools.cxx b/sc/source/filter/ftools/ftools.cxx
new file mode 100644
index 000000000000..72e5f115fed0
--- /dev/null
+++ b/sc/source/filter/ftools/ftools.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "ftools.hxx"
+#include <tools/color.hxx>
+#include <unotools/charclass.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/poolitem.hxx>
+#include <sot/storage.hxx>
+
+#include <math.h>
+#include "global.hxx"
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "compiler.hxx"
+
+#include <stdio.h>
+
+// ============================================================================
+// ScFilterTools::ReadLongDouble()
+
+#ifdef _MSC_VER
+#if _MSC_VER <= 800
+#undef __SIMPLE_FUNC
+#define __SIMPLE_FUNC
+#endif
+#endif
+
+double ScfTools::ReadLongDouble( SvStream& rStrm )
+
+#ifdef __SIMPLE_FUNC // for <=VC 1.5
+{
+ long double fRet;
+ rStrm.Read( &fRet, 10 );
+ return static_cast< double >( fRet );
+}
+#undef __SIMPLE_FUNC
+
+#else // detailed for all others
+{
+
+/*
+" M a p p i n g - G u i d e " 10-Byte Intel
+
+77777777 77666666 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 x10
+98765432 10987654 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 Bit-# total
+9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 Byte-#
+76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 Bit-# in Byte
+SEEEEEEE EEEEEEEE IMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM Group
+01111110 00000000 06665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 x10
+14321098 76543210 02109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 Bit in Group
+*/
+
+ register long double lfDouble = 0.0;
+ register long double lfFakt = 256.0;
+ sal_uInt8 pDouble10[ 10 ];
+
+ rStrm.Read( pDouble10, 10 ); // Intel-10 in pDouble10
+
+ lfDouble = static_cast< long double >( pDouble10[ 7 ] ); // Byte 7
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 6 ] ); // Byte 6
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 5 ] ); // Byte 5
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 4 ] ); // Byte 4
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 3 ] ); // Byte 3
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 2 ] ); // Byte 2
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 1 ] ); // Byte 1
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 0 ] ); // Byte 0
+
+ // For value 0.0 all bits are zero; pow(2.0,-16446) does not work with CSet compilers
+ if( lfDouble != 0.0 )
+ {
+ // exponent
+ register sal_Int32 nExp;
+ nExp = pDouble10[ 9 ] & 0x7F;
+ nExp <<= 8;
+ nExp += pDouble10[ 8 ];
+ nExp -= 16446;
+
+ lfDouble *= pow( 2.0, static_cast< double >( nExp ) );
+ }
+
+ // sign
+ if( pDouble10[ 9 ] & 0x80 )
+ lfDouble *= static_cast< long double >( -1.0 );
+
+ return static_cast< double >( lfDouble );
+}
+#endif
+
+// *** common methods *** -----------------------------------------------------
+
+rtl_TextEncoding ScfTools::GetSystemTextEncoding()
+{
+ return gsl_getSystemTextEncoding();
+}
+
+String ScfTools::GetHexStr( sal_uInt16 nValue )
+{
+ const sal_Char pHex[] = "0123456789ABCDEF";
+ String aStr;
+
+ aStr += pHex[ nValue >> 12 ];
+ aStr += pHex[ (nValue >> 8) & 0x000F ];
+ aStr += pHex[ (nValue >> 4) & 0x000F ];
+ aStr += pHex[ nValue & 0x000F ];
+ return aStr;
+}
+
+sal_uInt8 ScfTools::GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans )
+{
+ sal_Int32 nTemp = ((static_cast< sal_Int32 >( nBack ) - nFore) * nTrans) / 0x80 + nFore;
+ return static_cast< sal_uInt8 >( nTemp );
+}
+
+Color ScfTools::GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans )
+{
+ return Color(
+ GetMixedColorComp( rFore.GetRed(), rBack.GetRed(), nTrans ),
+ GetMixedColorComp( rFore.GetGreen(), rBack.GetGreen(), nTrans ),
+ GetMixedColorComp( rFore.GetBlue(), rBack.GetBlue(), nTrans ) );
+}
+
+// *** conversion of names *** ------------------------------------------------
+
+/* XXX As in sc/source/core/tool/rangenam.cxx ScRangeData::IsValidName() */
+
+void ScfTools::ConvertToScDefinedName( String& rName )
+{
+ xub_StrLen nLen = rName.Len();
+ if( nLen && !ScCompiler::IsCharFlagAllConventions( rName, 0, SC_COMPILER_C_CHAR_NAME ) )
+ rName.SetChar( 0, '_' );
+ for( xub_StrLen nPos = 1; nPos < nLen; ++nPos )
+ if( !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME ) )
+ rName.SetChar( nPos, '_' );
+}
+
+// *** streams and storages *** -----------------------------------------------
+
+SotStorageRef ScfTools::OpenStorageRead( SotStorageRef xStrg, const String& rStrgName )
+{
+ SotStorageRef xSubStrg;
+ if( xStrg.Is() && xStrg->IsContained( rStrgName ) )
+ xSubStrg = xStrg->OpenSotStorage( rStrgName, STREAM_STD_READ );
+ return xSubStrg;
+}
+
+SotStorageRef ScfTools::OpenStorageWrite( SotStorageRef xStrg, const String& rStrgName )
+{
+ SotStorageRef xSubStrg;
+ if( xStrg.Is() )
+ xSubStrg = xStrg->OpenSotStorage( rStrgName, STREAM_STD_WRITE );
+ return xSubStrg;
+}
+
+SotStorageStreamRef ScfTools::OpenStorageStreamRead( SotStorageRef xStrg, const String& rStrmName )
+{
+ SotStorageStreamRef xStrm;
+ if( xStrg.Is() && xStrg->IsContained( rStrmName ) && xStrg->IsStream( rStrmName ) )
+ xStrm = xStrg->OpenSotStream( rStrmName, STREAM_STD_READ );
+ return xStrm;
+}
+
+SotStorageStreamRef ScfTools::OpenStorageStreamWrite( SotStorageRef xStrg, const String& rStrmName )
+{
+ DBG_ASSERT( !xStrg || !xStrg->IsContained( rStrmName ), "ScfTools::OpenStorageStreamWrite - stream exists already" );
+ SotStorageStreamRef xStrm;
+ if( xStrg.Is() )
+ xStrm = xStrg->OpenSotStream( rStrmName, STREAM_STD_WRITE | STREAM_TRUNC );
+ return xStrm;
+}
+
+// *** item handling *** ------------------------------------------------------
+
+bool ScfTools::CheckItem( const SfxItemSet& rItemSet, USHORT nWhichId, bool bDeep )
+{
+ return rItemSet.GetItemState( nWhichId, bDeep ) == SFX_ITEM_SET;
+}
+
+bool ScfTools::CheckItems( const SfxItemSet& rItemSet, const USHORT* pnWhichIds, bool bDeep )
+{
+ DBG_ASSERT( pnWhichIds, "ScfTools::CheckItems - no which id list" );
+ for( const USHORT* pnWhichId = pnWhichIds; *pnWhichId != 0; ++pnWhichId )
+ if( CheckItem( rItemSet, *pnWhichId, bDeep ) )
+ return true;
+ return false;
+}
+
+void ScfTools::PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, sal_uInt16 nWhichId, bool bSkipPoolDef )
+{
+ if( !bSkipPoolDef || (rItem != rItemSet.GetPool()->GetDefaultItem( nWhichId )) )
+ rItemSet.Put( rItem, nWhichId );
+}
+
+void ScfTools::PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, bool bSkipPoolDef )
+{
+ PutItem( rItemSet, rItem, rItem.Which(), bSkipPoolDef );
+}
+
+// *** style sheet handling *** -----------------------------------------------
+
+namespace {
+
+ScStyleSheet& lclMakeStyleSheet( ScStyleSheetPool& rPool, const String& rStyleName, SfxStyleFamily eFamily, bool bForceName )
+{
+ // find an unused name
+ String aNewName( rStyleName );
+ sal_Int32 nIndex = 0;
+ SfxStyleSheetBase* pOldStyleSheet = 0;
+ while( SfxStyleSheetBase* pStyleSheet = rPool.Find( aNewName, eFamily ) )
+ {
+ if( !pOldStyleSheet )
+ pOldStyleSheet = pStyleSheet;
+ aNewName.Assign( rStyleName ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) );
+ }
+
+ // rename existing style
+ if( pOldStyleSheet && bForceName )
+ {
+ pOldStyleSheet->SetName( aNewName );
+ aNewName = rStyleName;
+ }
+
+ // create new style sheet
+ return static_cast< ScStyleSheet& >( rPool.Make( aNewName, eFamily, SFXSTYLEBIT_USERDEF ) );
+}
+
+} // namespace
+
+ScStyleSheet& ScfTools::MakeCellStyleSheet( ScStyleSheetPool& rPool, const String& rStyleName, bool bForceName )
+{
+ return lclMakeStyleSheet( rPool, rStyleName, SFX_STYLE_FAMILY_PARA, bForceName );
+}
+
+ScStyleSheet& ScfTools::MakePageStyleSheet( ScStyleSheetPool& rPool, const String& rStyleName, bool bForceName )
+{
+ return lclMakeStyleSheet( rPool, rStyleName, SFX_STYLE_FAMILY_PAGE, bForceName );
+}
+
+// *** byte string import operations *** --------------------------------------
+
+ByteString ScfTools::ReadCString( SvStream& rStrm )
+{
+ ByteString aRet;
+ sal_Char cChar;
+
+ rStrm >> cChar;
+ while( cChar )
+ {
+ aRet += cChar;
+ rStrm >> cChar;
+ }
+ return aRet;
+}
+
+ByteString ScfTools::ReadCString( SvStream& rStrm, sal_Int32& rnBytesLeft )
+{
+ ByteString aRet;
+ sal_Char cChar;
+
+ rStrm >> cChar;
+ rnBytesLeft--;
+ while( cChar )
+ {
+ aRet += cChar;
+ rStrm >> cChar;
+ rnBytesLeft--;
+ }
+
+ return aRet;
+}
+
+void ScfTools::AppendCString( SvStream& rStrm, ByteString& rString )
+{
+ sal_Char cChar;
+
+ rStrm >> cChar;
+ while( cChar )
+ {
+ rString += cChar;
+ rStrm >> cChar;
+ }
+}
+
+void ScfTools::AppendCString( SvStream& rStrm, String& rString, rtl_TextEncoding eTextEnc )
+{
+ ByteString aByteString;
+ AppendCString( rStrm, aByteString );
+ rString += String( aByteString, eTextEnc );
+}
+
+// *** HTML table names <-> named range names *** -----------------------------
+
+const String& ScfTools::GetHTMLDocName()
+{
+ static const String saHTMLDoc( RTL_CONSTASCII_USTRINGPARAM( "HTML_all" ) );
+ return saHTMLDoc;
+}
+
+const String& ScfTools::GetHTMLTablesName()
+{
+ static const String saHTMLTables( RTL_CONSTASCII_USTRINGPARAM( "HTML_tables" ) );
+ return saHTMLTables;
+}
+
+const String& ScfTools::GetHTMLIndexPrefix()
+{
+ static const String saHTMLIndexPrefix( RTL_CONSTASCII_USTRINGPARAM( "HTML_" ) );
+ return saHTMLIndexPrefix;
+
+}
+
+const String& ScfTools::GetHTMLNamePrefix()
+{
+ static const String saHTMLNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "HTML__" ) );
+ return saHTMLNamePrefix;
+}
+
+String ScfTools::GetNameFromHTMLIndex( sal_uInt32 nIndex )
+{
+ String aName( GetHTMLIndexPrefix() );
+ aName += String::CreateFromInt32( static_cast< sal_Int32 >( nIndex ) );
+ return aName;
+}
+
+String ScfTools::GetNameFromHTMLName( const String& rTabName )
+{
+ String aName( GetHTMLNamePrefix() );
+ aName += rTabName;
+ return aName;
+}
+
+bool ScfTools::IsHTMLDocName( const String& rSource )
+{
+ return rSource.EqualsIgnoreCaseAscii( GetHTMLDocName() );
+}
+
+bool ScfTools::IsHTMLTablesName( const String& rSource )
+{
+ return rSource.EqualsIgnoreCaseAscii( GetHTMLTablesName() );
+}
+
+bool ScfTools::GetHTMLNameFromName( const String& rSource, String& rName )
+{
+ rName.Erase();
+ if( rSource.EqualsIgnoreCaseAscii( GetHTMLNamePrefix(), 0, GetHTMLNamePrefix().Len() ) )
+ {
+ rName = rSource.Copy( GetHTMLNamePrefix().Len() );
+ ScGlobal::AddQuotes( rName, '"', false );
+ }
+ else if( rSource.EqualsIgnoreCaseAscii( GetHTMLIndexPrefix(), 0, GetHTMLIndexPrefix().Len() ) )
+ {
+ String aIndex( rSource.Copy( GetHTMLIndexPrefix().Len() ) );
+ if( CharClass::isAsciiNumeric( aIndex ) && (aIndex.ToInt32() > 0) )
+ rName = aIndex;
+ }
+ return rName.Len() > 0;
+}
+
+// ============================================================================
+
+ScFormatFilterPluginImpl::ScFormatFilterPluginImpl()
+{
+}
+
+ScFormatFilterPlugin * SAL_CALL ScFilterCreate(void)
+{
+ return new ScFormatFilterPluginImpl();
+}
+
+// implementation class inside the filters
+
diff --git a/sc/source/filter/ftools/makefile.mk b/sc/source/filter/ftools/makefile.mk
new file mode 100644
index 000000000000..27a960efc6b0
--- /dev/null
+++ b/sc/source/filter/ftools/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=ftools
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/fapihelper.obj \
+ $(SLO)$/fprogressbar.obj \
+ $(SLO)$/ftools.obj
+
+EXCEPTIONSFILES = \
+ $(SLO)$/fapihelper.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx
new file mode 100644
index 000000000000..b4d764dc74a7
--- /dev/null
+++ b/sc/source/filter/html/htmlexp.cxx
@@ -0,0 +1,1341 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#define _SVSTDARR_STRINGSSORTDTOR
+#include <rtl/tencinfo.h>
+
+#include <vcl/svapp.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/editeng.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/frmhtmlw.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/urihelper.hxx>
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#endif
+#include <svl/svstdarr.hxx>
+#include <svl/zforlist.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/parhtml.hxx>
+#include <vcl/outdev.hxx>
+#include <stdio.h>
+
+#include "htmlexp.hxx"
+#include "filter.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "stlpool.hxx"
+#include "scresid.hxx"
+#include "cell.hxx"
+#include "cellform.hxx"
+#include "docoptio.hxx"
+#include "editutil.hxx"
+#include "ftools.hxx"
+
+
+#include <editeng/flditem.hxx>
+#include <editeng/borderline.hxx>
+#include <unotools/syslocale.hxx>
+
+
+// ohne sc.hrc: error C2679: binary '=' : no operator defined which takes a
+// right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
+// bei
+// const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
+// ?!???
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+
+//========================================================================
+
+const static sal_Char __FAR_DATA sMyBegComment[] = "<!-- ";
+const static sal_Char __FAR_DATA sMyEndComment[] = " -->";
+const static sal_Char __FAR_DATA sFontFamily[] = "font-family:";
+const static sal_Char __FAR_DATA sFontSize[] = "font-size:";
+
+const USHORT __FAR_DATA ScHTMLExport::nDefaultFontSize[SC_HTML_FONTSIZES] =
+{
+ HTMLFONTSZ1_DFLT, HTMLFONTSZ2_DFLT, HTMLFONTSZ3_DFLT, HTMLFONTSZ4_DFLT,
+ HTMLFONTSZ5_DFLT, HTMLFONTSZ6_DFLT, HTMLFONTSZ7_DFLT
+};
+
+USHORT ScHTMLExport::nFontSize[SC_HTML_FONTSIZES] = { 0 };
+
+const char* __FAR_DATA ScHTMLExport::pFontSizeCss[SC_HTML_FONTSIZES] =
+{
+ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
+};
+
+const USHORT ScHTMLExport::nCellSpacing = 0;
+const sal_Char __FAR_DATA ScHTMLExport::sIndentSource[nIndentMax+1] =
+ "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+
+//========================================================================
+// Makros fuer HTML-Export
+//========================================================================
+#define OUT_PROLOGUE() (rStrm << sHTML30_Prologue << ScExportBase::sNewLine \
+ << ScExportBase::sNewLine)
+#define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
+#define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, FALSE )
+#define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
+#define OUT_STR_NO_CONV( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc )
+#define OUT_LF() rStrm << ScExportBase::sNewLine << GetIndentStr()
+#define lcl_OUT_LF() rStrm << ScExportBase::sNewLine
+#define TAG_ON_LF( tag ) (TAG_ON( tag ) << ScExportBase::sNewLine << GetIndentStr())
+#define TAG_OFF_LF( tag ) (TAG_OFF( tag ) << ScExportBase::sNewLine << GetIndentStr())
+#define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
+#define OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR( comment ) \
+ << sMyEndComment << ScExportBase::sNewLine \
+ << GetIndentStr())
+#define lcl_OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR_NO_CONV( comment ) \
+ << sMyEndComment << ScExportBase::sNewLine)
+
+#define OUT_SP_CSTR_ASS( s ) rStrm << ' ' << s << '='
+#define APPEND_SPACE( s ) s.AppendAscii(" ")
+
+#define GLOBSTR(id) ScGlobal::GetRscString( id )
+
+
+
+//========================================================================
+
+FltError ScFormatFilterPluginImpl::ScExportHTML( SvStream& rStrm, const String& rBaseURL, ScDocument* pDoc,
+ const ScRange& rRange, const CharSet /*eNach*/, BOOL bAll,
+ const String& rStreamPath, String& rNonConvertibleChars )
+{
+ ScHTMLExport aEx( rStrm, rBaseURL, pDoc, rRange, bAll, rStreamPath );
+ FltError nErr = aEx.Write();
+ rNonConvertibleChars = aEx.GetNonConvertibleChars();
+ return nErr;
+}
+
+
+void lcl_AddStamp( String& rStr, const String& rName,
+ const ::com::sun::star::util::DateTime& rDateTime,
+ const LocaleDataWrapper& rLoc )
+{
+ Date aD(rDateTime.Day, rDateTime.Month, rDateTime.Year);
+ Time aT(rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds,
+ rDateTime.HundredthSeconds);
+ DateTime aDateTime(aD,aT);
+
+ String aStrDate = rLoc.getDate( aDateTime );
+ String aStrTime = rLoc.getTime( aDateTime );
+
+ rStr += GLOBSTR( STR_BY );
+ APPEND_SPACE( rStr );
+ if (rName.Len())
+ rStr += rName;
+ else
+ rStr.AppendAscii( "???" );
+ APPEND_SPACE( rStr );
+ rStr += GLOBSTR( STR_ON );
+ APPEND_SPACE( rStr );
+ if (aStrDate.Len())
+ rStr += aStrDate;
+ else
+ rStr.AppendAscii( "???" );
+ rStr.AppendAscii( ", " );
+ if (aStrTime.Len())
+ rStr += aStrTime;
+ else
+ rStr.AppendAscii( "???" );
+}
+
+
+void lcl_AppendHTMLColorTripel( ByteString& rStr, const Color& rColor )
+{
+ // <font COLOR="#00FF40">hallo</font>
+ sal_Char buf[64];
+ sal_Char* p = buf;
+
+ rStr += "\"#";
+ p += sprintf( p, "%02X", rColor.GetRed() ); // #100211# - checked
+ p += sprintf( p, "%02X", rColor.GetGreen() ); // #100211# - checked
+ p += sprintf( p, "%02X", rColor.GetBlue() ); // #100211# - checked
+ rStr += buf;
+ rStr += '\"';
+}
+
+
+/*void lcl_TagOn( String& rResult, const String& rTag, const String* pStrOpt )
+{
+ rResult = '<';
+ rResult += rTag;
+ if ( pStrOpt )
+ {
+ rResult += ' ';
+ rResult += *pStrOpt;
+ }
+ rResult += '>';
+}
+*/
+
+/*void lcl_TagOff( String& rResult, const String& rTag )
+{
+ rResult = '<'; rResult += rTag; rResult += '>';
+}
+*/
+
+//////////////////////////////////////////////////////////////////////////////
+
+ScHTMLExport::ScHTMLExport( SvStream& rStrmP, const String& rBaseURL, ScDocument* pDocP,
+ const ScRange& rRangeP,
+ BOOL bAllP, const String& rStreamPathP ) :
+ ScExportBase( rStrmP, pDocP, rRangeP ),
+ aBaseURL( rBaseURL ),
+ aStreamPath( rStreamPathP ),
+ pAppWin( Application::GetDefaultDevice() ),
+ pSrcArr( NULL ),
+ pDestArr( NULL ),
+ nUsedTables( 0 ),
+ nIndent( 0 ),
+ bAll( bAllP ),
+ bTabHasGraphics( FALSE ),
+ bCalcAsShown( pDocP->GetDocOptions().IsCalcAsShown() ),
+ bTableDataWidth( TRUE ),
+ bTableDataHeight( TRUE )
+{
+ strcpy( sIndent, sIndentSource ); // #100211# - checked
+ sIndent[0] = 0;
+
+ // set HTML configuration
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+ eDestEnc = (pDoc->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8 : pHtmlOptions->GetTextEncoding());
+ bCopyLocalFileToINet = pHtmlOptions->IsSaveGraphicsLocal();
+ for ( USHORT j=0; j < SC_HTML_FONTSIZES; j++ )
+ {
+ USHORT nSize = pHtmlOptions->GetFontSize( j );
+ // remember in Twips, like our SvxFontHeightItem
+ if ( nSize )
+ nFontSize[j] = nSize * 20;
+ else
+ nFontSize[j] = nDefaultFontSize[j] * 20;
+ }
+
+ const SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
+ {
+ if ( !IsEmptyTable( nTab ) )
+ nUsedTables++;
+ }
+
+ // Content-Id fuer Mail-Export?
+ SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_ORIGURL );
+ if( pItem )
+ {
+ aCId = ((const SfxStringItem *)pItem)->GetValue();
+ DBG_ASSERT( aCId.Len(), "CID ohne Laenge!" );
+ }
+ }
+}
+
+
+ScHTMLExport::~ScHTMLExport()
+{
+ for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
+ delete pE;
+ delete pSrcArr;
+ delete pDestArr;
+}
+
+
+USHORT ScHTMLExport::GetFontSizeNumber( USHORT nHeight )
+{
+ USHORT nSize = 1;
+ for ( USHORT j=SC_HTML_FONTSIZES-1; j>0; j-- )
+ {
+ if( nHeight > (nFontSize[j] + nFontSize[j-1]) / 2 )
+ { // der naechstgelegene
+ nSize = j+1;
+ break;
+ }
+ }
+ return nSize;
+}
+
+const char* ScHTMLExport::GetFontSizeCss( USHORT nHeight )
+{
+ USHORT nSize = GetFontSizeNumber( nHeight );
+ return pFontSizeCss[ nSize-1 ];
+}
+
+
+USHORT ScHTMLExport::ToPixel( USHORT nVal )
+{
+ if( nVal )
+ {
+ nVal = (USHORT)pAppWin->LogicToPixel(
+ Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
+ if( !nVal ) // wo ein Twip ist sollte auch ein Pixel sein
+ nVal = 1;
+ }
+ return nVal;
+}
+
+
+Size ScHTMLExport::MMToPixel( const Size& rSize )
+{
+ Size aSize( rSize );
+ aSize = pAppWin->LogicToPixel( rSize, MapMode( MAP_100TH_MM ) );
+ // wo etwas ist sollte auch ein Pixel sein
+ if ( !aSize.Width() && rSize.Width() )
+ aSize.Width() = 1;
+ if ( !aSize.Height() && rSize.Height() )
+ aSize.Height() = 1;
+ return aSize;
+}
+
+
+ULONG ScHTMLExport::Write()
+{
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_doctype << ' ' << OOO_STRING_SVTOOLS_HTML_doctype32 << '>'
+ << sNewLine << sNewLine;
+ TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html );
+ WriteHeader();
+ OUT_LF();
+ WriteBody();
+ OUT_LF();
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html );
+
+ return rStrm.GetError();
+}
+
+
+void ScHTMLExport::WriteHeader()
+{
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head );
+
+ if ( pDoc->IsClipOrUndo() )
+ { // no real DocInfo available, but some META information like charset needed
+ SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, NULL, sIndent, eDestEnc, &aNonConvertibleChars );
+ }
+ else
+ {
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, xDocProps,
+ sIndent, eDestEnc, &aNonConvertibleChars );
+ OUT_LF();
+
+ //----------------------------------------------------------
+ if (!xDocProps->getPrintedBy().equalsAscii(""))
+ {
+ OUT_COMMENT( GLOBSTR( STR_DOC_INFO ) );
+ String aStrOut( GLOBSTR( STR_DOC_PRINTED ) );
+ aStrOut.AppendAscii( ": " );
+ lcl_AddStamp( aStrOut, xDocProps->getPrintedBy(),
+ xDocProps->getPrintDate(), *ScGlobal::pLocaleData );
+ OUT_COMMENT( aStrOut );
+ }
+ //----------------------------------------------------------
+ }
+ OUT_LF();
+
+ // CSS1 StyleSheet
+ PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_style );
+ rStrm << sMyBegComment; OUT_LF();
+ rStrm << OOO_STRING_SVTOOLS_HTML_body << "," << OOO_STRING_SVTOOLS_HTML_division << "," << OOO_STRING_SVTOOLS_HTML_table << ","
+ << OOO_STRING_SVTOOLS_HTML_thead << "," << OOO_STRING_SVTOOLS_HTML_tbody << "," << OOO_STRING_SVTOOLS_HTML_tfoot << ","
+ << OOO_STRING_SVTOOLS_HTML_tablerow << "," << OOO_STRING_SVTOOLS_HTML_tableheader << ","
+ << OOO_STRING_SVTOOLS_HTML_tabledata << "," << OOO_STRING_SVTOOLS_HTML_parabreak << " { " << sFontFamily;
+ xub_StrLen nFonts = aHTMLStyle.aFontFamilyName.GetTokenCount( ';' );
+ if ( nFonts == 1 )
+ {
+ rStrm << '\"';
+ OUT_STR( aHTMLStyle.aFontFamilyName );
+ rStrm << '\"';
+ }
+ else
+ { // Fontliste, VCL: Semikolon als Separator,
+ // CSS1: Komma als Separator und jeder einzelne Fontname quoted
+ const String& rList = aHTMLStyle.aFontFamilyName;
+ for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
+ {
+ rStrm << '\"';
+ OUT_STR( rList.GetToken( 0, ';', nPos ) );
+ rStrm << '\"';
+ if ( j < nFonts-1 )
+ rStrm << ", ";
+ }
+ }
+ rStrm << "; " << sFontSize
+ << GetFontSizeCss( ( USHORT ) aHTMLStyle.nFontHeight ) << " }";
+ OUT_LF();
+ rStrm << sMyEndComment;
+ IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style );
+
+ IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head );
+}
+
+
+void ScHTMLExport::WriteOverview()
+{
+ if ( nUsedTables > 1 )
+ {
+ IncIndent(1);
+ OUT_HR();
+ IncIndent(1); TAG_ON( OOO_STRING_SVTOOLS_HTML_parabreak ); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_center );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
+ OUT_STR( ScGlobal::GetRscString( STR_OVERVIEW ) );
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head1 );
+
+ String aStr;
+
+ const SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
+ {
+ if ( !IsEmptyTable( nTab ) )
+ {
+ pDoc->GetName( nTab, aStr );
+ rStrm << "<A HREF=\"#table"
+ << ByteString::CreateFromInt32( nTab ).GetBuffer()
+ << "\">";
+ OUT_STR( aStr );
+ rStrm << "</A>";
+ TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_linebreak );
+ }
+ }
+
+ IncIndent(-1); OUT_LF();
+ IncIndent(-1); TAG_OFF( OOO_STRING_SVTOOLS_HTML_center ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_parabreak );
+ }
+}
+
+
+const SfxItemSet& ScHTMLExport::PageDefaults( SCTAB nTab )
+{
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = NULL;
+ DBG_ASSERT( pStylePool, "StylePool not found! :-(" );
+
+ // remember defaults for compare in WriteCell
+ if ( !aHTMLStyle.bInitialized )
+ {
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find(
+ ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
+ SFX_STYLE_FAMILY_PARA );
+ DBG_ASSERT( pStyleSheet, "ParaStyle not found! :-(" );
+ if (!pStyleSheet)
+ pStyleSheet = pStylePool->First();
+ const SfxItemSet& rSetPara = pStyleSheet->GetItemSet();
+
+ aHTMLStyle.nDefaultScriptType = ScGlobal::GetDefaultScriptType();
+ aHTMLStyle.aFontFamilyName = ((const SvxFontItem&)(rSetPara.Get(
+ ScGlobal::GetScriptedWhichID(
+ aHTMLStyle.nDefaultScriptType, ATTR_FONT
+ )))).GetFamilyName();
+ aHTMLStyle.nFontHeight = ((const SvxFontHeightItem&)(rSetPara.Get(
+ ScGlobal::GetScriptedWhichID(
+ aHTMLStyle.nDefaultScriptType, ATTR_FONT_HEIGHT
+ )))).GetHeight();
+ aHTMLStyle.nFontSizeNumber = GetFontSizeNumber( static_cast< USHORT >( aHTMLStyle.nFontHeight ) );
+ }
+
+ // Page style sheet printer settings, e.g. for background graphics.
+ // There's only one background graphic in HTML!
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-(" );
+ if (!pStyleSheet)
+ pStyleSheet = pStylePool->First();
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if ( !aHTMLStyle.bInitialized )
+ {
+ const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
+ aHTMLStyle.aBackgroundColor = pBrushItem->GetColor();
+ aHTMLStyle.bInitialized = TRUE;
+ }
+ return rSet;
+}
+
+
+void ScHTMLExport::BorderToStyle( ByteString& rOut, const char* pBorderName,
+ const SvxBorderLine* pLine, bool& bInsertSemicolon )
+{
+ if ( pLine )
+ {
+ if ( bInsertSemicolon )
+ rOut += "; ";
+
+ // which border
+ ((rOut += "border-") += pBorderName) += ": ";
+
+ // thickness
+ int nWidth = pLine->GetOutWidth();
+ int nPxWidth = ( nWidth > 0 )? std::max( int( nWidth / TWIPS_PER_PIXEL ), 1 ): 0;
+ (rOut += ByteString::CreateFromInt32( nPxWidth )) += "px solid #";
+
+ // color
+ char hex[7];
+ snprintf( hex, 7, "%06x", static_cast< unsigned int >( pLine->GetColor().GetRGBColor() ) );
+ hex[6] = 0;
+
+ rOut += hex;
+
+ bInsertSemicolon = true;
+ }
+}
+
+void ScHTMLExport::WriteBody()
+{
+ const SfxItemSet& rSet = PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
+ const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
+
+ // default Textfarbe schwarz
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_body << ' ' << OOO_STRING_SVTOOLS_HTML_O_text << "=\"#000000\"";
+
+ if ( bAll && GPOS_NONE != pBrushItem->GetGraphicPos() )
+ {
+ const String* pLink = pBrushItem->GetGraphicLink();
+ String aGrfNm;
+
+ // embeddete Grafik -> via WriteGraphic schreiben
+ if( !pLink )
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ aGrfNm = aStreamPath;
+ USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, aGrfNm,
+ CREATE_STRING( "JPG" ), XOUTBMP_USE_NATIVE_IF_POSSIBLE );
+ if( !nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
+ if ( HasCId() )
+ MakeCIdURL( aGrfNm );
+ pLink = &aGrfNm;
+ }
+ }
+ }
+ else
+ {
+ aGrfNm = *pLink;
+ if( bCopyLocalFileToINet || HasCId() )
+ {
+ CopyLocalFileToINet( aGrfNm, aStreamPath );
+ if ( HasCId() )
+ MakeCIdURL( aGrfNm );
+ }
+ else
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
+ pLink = &aGrfNm;
+ }
+ if( pLink )
+ {
+ rStrm << ' ' << OOO_STRING_SVTOOLS_HTML_O_background << "=\"";
+ OUT_STR( URIHelper::simpleNormalizedMakeRelative(
+ aBaseURL,
+ *pLink ) ) << '\"';
+ }
+ }
+ if ( !aHTMLStyle.aBackgroundColor.GetTransparency() )
+ { // A transparent background color should always result in default
+ // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
+ // black #000000 for COL_AUTO which is the same as white #ffffff with
+ // transparency set to 0xff, our default background.
+ OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor );
+ HTMLOutFuncs::Out_Color( rStrm, aHTMLStyle.aBackgroundColor );
+ }
+
+ rStrm << '>'; OUT_LF();
+
+ if ( bAll )
+ WriteOverview();
+
+ WriteTables();
+
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body );
+}
+
+
+void ScHTMLExport::WriteTables()
+{
+ const SCTAB nTabCount = pDoc->GetTableCount();
+ const String aStrTable( ScResId( SCSTR_TABLE ) );
+ String aStr;
+ String aStrOut;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ SCCOL nStartColFix = 0;
+ SCROW nStartRowFix = 0;
+ SCCOL nEndColFix = 0;
+ SCROW nEndRowFix = 0;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if ( bAll )
+ {
+ nStartTab = 0;
+ nEndTab = nTabCount - 1;
+ }
+ else
+ {
+ nStartCol = nStartColFix = aRange.aStart.Col();
+ nStartRow = nStartRowFix = aRange.aStart.Row();
+ nStartTab = aRange.aStart.Tab();
+ nEndCol = nEndColFix = aRange.aEnd.Col();
+ nEndRow = nEndRowFix = aRange.aEnd.Row();
+ nEndTab = aRange.aEnd.Tab();
+ }
+ SCTAB nTableStrNum = 1;
+ for ( SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++ )
+ {
+ if ( !pDoc->IsVisible( nTab ) )
+ continue; // for
+
+ if ( bAll )
+ {
+ if ( !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
+ continue; // for
+
+ if ( nUsedTables > 1 )
+ {
+ aStrOut = aStrTable;
+ aStrOut.AppendAscii( " " );
+ aStrOut += String::CreateFromInt32( nTableStrNum++ );
+ aStrOut.AppendAscii( ": " );
+
+ OUT_HR();
+
+ // Anker festlegen:
+ rStrm << "<A NAME=\"table"
+ << ByteString::CreateFromInt32( nTab ).GetBuffer()
+ << "\">";
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
+ OUT_STR( aStrOut );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis );
+
+ pDoc->GetName( nTab, aStr );
+ OUT_STR( aStr );
+
+ TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis );
+ TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1 );
+ rStrm << "</A>"; OUT_LF();
+ }
+ }
+ else
+ {
+ nStartCol = nStartColFix;
+ nStartRow = nStartRowFix;
+ nEndCol = nEndColFix;
+ nEndRow = nEndRowFix;
+ if ( !TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
+ continue; // for
+ }
+
+ // <TABLE ...>
+ ByteString aByteStrOut = OOO_STRING_SVTOOLS_HTML_table;
+// aStrOut = OOO_STRING_SVTOOLS_HTML_table;
+
+ // FRAME=VOID, we do the styling of the cells in <TD>
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_frame) += '=') += OOO_STRING_SVTOOLS_HTML_TF_void;
+
+ bTabHasGraphics = bTabAlignedLeft = FALSE;
+ if ( bAll && pDrawLayer )
+ PrepareGraphics( pDrawLayer, nTab, nStartCol, nStartRow,
+ nEndCol, nEndRow );
+
+ // more <TABLE ...>
+ if ( bTabAlignedLeft )
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+ // ALIGN=LEFT allow text and graphics to flow around
+ // CELLSPACING
+ (((aByteStrOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=') +=
+ ByteString::CreateFromInt32( nCellSpacing );
+ // COLS=n
+ SCCOL nColCnt = 0;
+ SCCOL nCol;
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ if ( !pDoc->ColHidden(nCol, nTab) )
+ ++nColCnt;
+ }
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=') += ByteString::CreateFromInt32( nColCnt );
+
+ // RULES=NONE, we do the styling of the cells in <TD>
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_rules) += '=') += OOO_STRING_SVTOOLS_HTML_TR_none;
+
+ // BORDER=0, we do the styling of the cells in <TD>
+ ((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += "=0";
+ IncIndent(1); TAG_ON_LF( aByteStrOut.GetBuffer() );
+
+ // <COLGROUP>
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_colgroup );
+ // <COL WIDTH=x> as pre-info for long tables
+ ByteString aByteStr = OOO_STRING_SVTOOLS_HTML_col;
+ aByteStr += ' ';
+ aByteStr += OOO_STRING_SVTOOLS_HTML_O_width;
+ aByteStr += '=';
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ if ( pDoc->ColHidden(nCol, nTab) )
+ continue; // for
+
+ aByteStrOut = aByteStr;
+ aByteStrOut += ByteString::CreateFromInt32(
+ ToPixel( pDoc->GetColWidth( nCol, nTab ) ) );
+ TAG_ON( aByteStrOut.GetBuffer() );
+ }
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup );
+
+ // <TBODY>
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
+ // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
+ // <COL WIDTH=x> specified, but needs a width at every column.
+ bTableDataWidth = TRUE; // widths in first row
+ bool bHasHiddenRows = pDoc->HasHiddenRows(nStartRow, nEndRow, nTab);
+ for ( SCROW nRow=nStartRow; nRow<=nEndRow; nRow++ )
+ {
+ if ( bHasHiddenRows && pDoc->RowHidden(nRow, nTab) )
+ {
+ nRow = pDoc->FirstVisibleRow(nRow+1, nEndRow, nTab);
+ --nRow;
+ continue; // for
+ }
+
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
+ bTableDataHeight = TRUE; // height at every first cell of each row
+ for ( SCCOL nCol2=nStartCol; nCol2<=nEndCol; nCol2++ )
+ {
+ if ( pDoc->ColHidden(nCol2, nTab) )
+ continue; // for
+
+ if ( nCol2 == nEndCol )
+ IncIndent(-1);
+ WriteCell( nCol2, nRow, nTab );
+ bTableDataHeight = FALSE;
+ }
+ bTableDataWidth = FALSE; // widths only in first row
+
+ if ( nRow == nEndRow )
+ IncIndent(-1);
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
+ }
+ IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
+
+ IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table );
+
+ if ( bTabHasGraphics )
+ {
+ // the rest that is not in a cell
+ for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
+ {
+ if ( !pE->bWritten )
+ WriteGraphEntry( pE );
+ delete pE;
+ }
+ aGraphList.Clear();
+ if ( bTabAlignedLeft )
+ { // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
+ aByteStrOut = OOO_STRING_SVTOOLS_HTML_linebreak;
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+ TAG_ON_LF( aByteStrOut.GetBuffer() );
+ }
+ }
+
+ if ( bAll )
+ OUT_COMMENT( CREATE_STRING( "**************************************************************************" ) );
+ }
+}
+
+
+void ScHTMLExport::WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondItemSet = pDoc->GetCondResult( nCol, nRow, nTab );
+
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG, pCondItemSet );
+ if ( rMergeFlagAttr.IsOverlapped() )
+ return ;
+
+ ScAddress aPos( nCol, nRow, nTab );
+ ScHTMLGraphEntry* pGraphEntry = NULL;
+ if ( bTabHasGraphics )
+ {
+ for ( pGraphEntry = aGraphList.First(); pGraphEntry;
+ pGraphEntry = aGraphList.Next() )
+ {
+ if ( pGraphEntry->bInCell && pGraphEntry->aRange.In( aPos ) )
+ {
+ if ( pGraphEntry->aRange.aStart == aPos )
+ break; // for
+ else
+ return ; // ist ein Col/RowSpan, Overlapped
+ }
+ }
+ }
+
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+ ULONG nFormat = pAttr->GetNumberFormat( pFormatter );
+ BOOL bValueData;
+ BYTE nScriptType;
+ if ( pCell )
+ {
+ bValueData = pCell->HasValueData();
+ nScriptType = pDoc->GetScriptType( nCol, nRow, nTab, pCell );
+ }
+ else
+ {
+ bValueData = FALSE;
+ nScriptType = 0;
+ }
+ if ( nScriptType == 0 )
+ nScriptType = aHTMLStyle.nDefaultScriptType;
+
+
+ ByteString aStrTD = OOO_STRING_SVTOOLS_HTML_tabledata;
+
+ // border of the cells
+ SvxBoxItem* pBorder = (SvxBoxItem*) pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER );
+ if ( pBorder && (pBorder->GetTop() || pBorder->GetBottom() || pBorder->GetLeft() || pBorder->GetRight()) )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_style) += "=\"";
+
+ bool bInsertSemicolon = false;
+ BorderToStyle( aStrTD, "top", pBorder->GetTop(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "bottom", pBorder->GetBottom(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "left", pBorder->GetLeft(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "right", pBorder->GetRight(), bInsertSemicolon );
+
+ aStrTD += '"';
+ }
+
+ const sal_Char* pChar;
+ USHORT nWidthPixel;
+ USHORT nHeightPixel;
+
+ const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE, pCondItemSet );
+ if ( pGraphEntry || rMergeAttr.IsMerged() )
+ {
+ SCCOL nC, jC;
+ SCROW nR;
+ ULONG v;
+ if ( pGraphEntry )
+ nC = Max( SCCOL(pGraphEntry->aRange.aEnd.Col() - nCol + 1),
+ SCCOL(rMergeAttr.GetColMerge()) );
+ else
+ nC = rMergeAttr.GetColMerge();
+ if ( nC > 1 )
+ {
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_colspan) += '=') += ByteString::CreateFromInt32( nC );
+ nC = nC + nCol;
+ for ( jC=nCol, v=0; jC<nC; jC++ )
+ v += pDoc->GetColWidth( jC, nTab );
+ nWidthPixel = ToPixel( static_cast< USHORT >( v ) );
+ }
+ else
+ nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
+
+ if ( pGraphEntry )
+ nR = Max( SCROW(pGraphEntry->aRange.aEnd.Row() - nRow + 1),
+ SCROW(rMergeAttr.GetRowMerge()) );
+ else
+ nR = rMergeAttr.GetRowMerge();
+ if ( nR > 1 )
+ {
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_rowspan) += '=') += ByteString::CreateFromInt32( nR );
+ nR += nRow;
+ v = pDoc->GetRowHeight( nRow, nR-1, nTab );
+ nHeightPixel = ToPixel( static_cast< USHORT >( v ) );
+ }
+ else
+ nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
+ }
+ else
+ {
+ nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
+ nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
+ }
+
+ if ( bTableDataWidth )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') += ByteString::CreateFromInt32( nWidthPixel );
+ if ( bTableDataHeight )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') += ByteString::CreateFromInt32( nHeightPixel );
+
+ const SvxFontItem& rFontItem = (const SvxFontItem&) pAttr->GetItem(
+ ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT),
+ pCondItemSet);
+
+ const SvxFontHeightItem& rFontHeightItem = (const SvxFontHeightItem&)
+ pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
+ ATTR_FONT_HEIGHT), pCondItemSet);
+
+ const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem(
+ ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT_WEIGHT),
+ pCondItemSet);
+
+ const SvxPostureItem& rPostureItem = (const SvxPostureItem&)
+ pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
+ ATTR_FONT_POSTURE), pCondItemSet);
+
+ const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&)
+ pAttr->GetItem( ATTR_FONT_UNDERLINE, pCondItemSet );
+
+ const SvxColorItem& rColorItem = (const SvxColorItem&) pAttr->GetItem(
+ ATTR_FONT_COLOR, pCondItemSet );
+
+ const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)
+ pAttr->GetItem( ATTR_HOR_JUSTIFY, pCondItemSet );
+
+ const SvxVerJustifyItem& rVerJustifyItem = (const SvxVerJustifyItem&)
+ pAttr->GetItem( ATTR_VER_JUSTIFY, pCondItemSet );
+
+ const SvxBrushItem& rBrushItem = (const SvxBrushItem&) pAttr->GetItem(
+ ATTR_BACKGROUND, pCondItemSet );
+
+ Color aBgColor;
+ if ( rBrushItem.GetColor().GetTransparency() == 255 )
+ aBgColor = aHTMLStyle.aBackgroundColor; // #55121# keine ungewollte Hintergrundfarbe
+ else
+ aBgColor = rBrushItem.GetColor();
+
+ BOOL bBold = ( WEIGHT_BOLD <= rWeightItem.GetWeight() );
+ BOOL bItalic = ( ITALIC_NONE != rPostureItem.GetPosture() );
+ BOOL bUnderline = ( UNDERLINE_NONE != rUnderlineItem.GetLineStyle() );
+ BOOL bSetFontColor = ( COL_AUTO != rColorItem.GetValue().GetColor() ); // #97650# default is AUTO now
+#if 0
+// keine StyleSheet-Fontangaben: hart fuer jede Zelle
+ BOOL bSetFontName = TRUE;
+ USHORT nSetFontSizeNumber = GetFontSizeNumber( (USHORT)rFontHeightItem.GetHeight() );
+#else
+ BOOL bSetFontName = ( aHTMLStyle.aFontFamilyName != rFontItem.GetFamilyName() );
+ USHORT nSetFontSizeNumber = 0;
+ UINT32 nFontHeight = rFontHeightItem.GetHeight();
+ if ( nFontHeight != aHTMLStyle.nFontHeight )
+ {
+ nSetFontSizeNumber = GetFontSizeNumber( (USHORT) nFontHeight );
+ if ( nSetFontSizeNumber == aHTMLStyle.nFontSizeNumber )
+ nSetFontSizeNumber = 0; // no difference, don't set
+ }
+#endif
+ BOOL bSetFont = (bSetFontColor || bSetFontName || nSetFontSizeNumber);
+
+ //! TODO: we could entirely use CSS1 here instead, but that would exclude
+ //! Netscape 3.0 and Netscape 4.x without JavaScript enabled.
+ //! Do we want that?
+
+ switch( rHorJustifyItem.GetValue() )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ pChar = (bValueData ? OOO_STRING_SVTOOLS_HTML_AL_right : OOO_STRING_SVTOOLS_HTML_AL_left);
+ break;
+ case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_AL_center; break;
+ case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
+ case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_HTML_AL_right; break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default: pChar = OOO_STRING_SVTOOLS_HTML_AL_left; break;
+ }
+
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pChar;
+
+ switch( rVerJustifyItem.GetValue() )
+ {
+ case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case SVX_VER_JUSTIFY_STANDARD:
+ default: pChar = NULL;
+ }
+ if ( pChar )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=') += pChar;
+
+ if ( aHTMLStyle.aBackgroundColor != aBgColor )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
+ lcl_AppendHTMLColorTripel( aStrTD, aBgColor );
+ }
+
+ double fVal = 0.0;
+ if ( bValueData )
+ {
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ fVal = ((ScValueCell*)pCell)->GetValue();
+ if ( bCalcAsShown && fVal != 0.0 )
+ fVal = pDoc->RoundValueAsShown( fVal, nFormat );
+ break;
+ case CELLTYPE_FORMULA:
+ fVal = ((ScFormulaCell*)pCell)->GetValue();
+ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nFormat = ScGlobal::GetStandardFormat( fVal, *pFormatter,
+ nFormat, ((ScFormulaCell*)pCell)->GetFormatType() );
+ break;
+ default:
+ DBG_ERRORFILE( "value data with unsupported cell type" );
+ }
+ }
+ }
+ HTMLOutFuncs::CreateTableDataOptionsValNum( aStrTD, bValueData, fVal,
+ nFormat, *pFormatter, eDestEnc, &aNonConvertibleChars );
+
+ TAG_ON( aStrTD.GetBuffer() );
+
+ if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
+ if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic );
+ if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline );
+
+
+ if ( bSetFont )
+ {
+ ByteString aStr = OOO_STRING_SVTOOLS_HTML_font;
+ if ( bSetFontName )
+ {
+ ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
+ xub_StrLen nFonts = rFontItem.GetFamilyName().GetTokenCount( ';' );
+ if ( nFonts == 1 )
+ {
+ ByteString aTmpStr;
+ HTMLOutFuncs::ConvertStringToHTML( rFontItem.GetFamilyName(),
+ aTmpStr, eDestEnc, &aNonConvertibleChars );
+ aStr += aTmpStr;
+ }
+ else
+ { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
+ const String& rList = rFontItem.GetFamilyName();
+ for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
+ {
+ ByteString aTmpStr;
+ HTMLOutFuncs::ConvertStringToHTML(
+ rList.GetToken( 0, ';', nPos ), aTmpStr, eDestEnc,
+ &aNonConvertibleChars );
+ aStr += aTmpStr;
+ if ( j < nFonts-1 )
+ aStr += ',';
+ }
+ }
+ aStr += '\"';
+ }
+ if ( nSetFontSizeNumber )
+ {
+ (((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
+ += ByteString::CreateFromInt32( nSetFontSizeNumber );
+ }
+ if ( bSetFontColor )
+ {
+ Color aColor = rColorItem.GetValue();
+
+ // always export automatic text color as black
+ if ( aColor.GetColor() == COL_AUTO )
+ aColor.SetColor( COL_BLACK );
+
+ ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ lcl_AppendHTMLColorTripel( aStr, aColor );
+ }
+ TAG_ON( aStr.GetBuffer() );
+ }
+
+ String aStrOut;
+ BOOL bFieldText = FALSE;
+ if ( pCell )
+ { // cell content
+ Color* pColor;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_NOTE :
+ // nothing
+ break;
+ case CELLTYPE_EDIT :
+ bFieldText = WriteFieldText( (const ScEditCell*) pCell );
+ if ( bFieldText )
+ break;
+ //! else: fallthru
+ default:
+ ScCellFormat::GetString( pCell, nFormat, aStrOut, &pColor, *pFormatter );
+ }
+ }
+ if ( !bFieldText )
+ {
+ if ( !aStrOut.Len() )
+ {
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // #42573# keine komplett leere Zelle
+ }
+ else
+ {
+ xub_StrLen nPos = aStrOut.Search( _LF );
+ if ( nPos == STRING_NOTFOUND )
+ {
+ OUT_STR( aStrOut );
+ }
+ else
+ {
+ xub_StrLen nStartPos = 0;
+ do
+ {
+ String aSingleLine( aStrOut, nStartPos, nPos - nStartPos );
+ OUT_STR( aSingleLine );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
+ nStartPos = nPos + 1;
+ }
+ while( ( nPos = aStrOut.Search( _LF, nStartPos ) ) != STRING_NOTFOUND );
+ String aSingleLine( aStrOut, nStartPos, aStrOut.Len() - nStartPos );
+ OUT_STR( aSingleLine );
+ }
+ }
+ }
+ if ( pGraphEntry )
+ WriteGraphEntry( pGraphEntry );
+
+ if ( bSetFont ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font );
+ if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline );
+ if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic );
+ if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
+
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata );
+}
+
+
+BOOL ScHTMLExport::WriteFieldText( const ScEditCell* pCell )
+{
+ BOOL bFields = FALSE;
+ const EditTextObject* pData;
+ pCell->GetData( pData );
+ // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ USHORT nParas = rEngine.GetParagraphCount();
+ if ( nParas )
+ {
+ ESelection aSel( 0, 0, nParas-1, rEngine.GetTextLen( nParas-1 ) );
+ SfxItemSet aSet( rEngine.GetAttribs( aSel ) );
+ SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bFields = TRUE;
+ }
+ if ( bFields )
+ {
+ BOOL bOldUpdateMode = rEngine.GetUpdateMode();
+ rEngine.SetUpdateMode( TRUE ); // no portions if not formatted
+ for ( USHORT nPar=0; nPar < nParas; nPar++ )
+ {
+ if ( nPar > 0 )
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
+ SvUShorts aPortions;
+ rEngine.GetPortions( nPar, aPortions );
+ USHORT nCnt = aPortions.Count();
+ USHORT nStart = 0;
+ for ( USHORT nPos = 0; nPos < nCnt; nPos++ )
+ {
+ USHORT nEnd = aPortions.GetObject( nPos );
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ BOOL bUrl = FALSE;
+ // fields are single characters
+ if ( nEnd == nStart+1 )
+ {
+ const SfxPoolItem* pItem;
+ SfxItemSet aSet = rEngine.GetAttribs( aSel );
+ if ( aSet.GetItemState( EE_FEATURE_FIELD, FALSE, &pItem ) == SFX_ITEM_ON )
+ {
+ const SvxFieldData* pField = ((const SvxFieldItem*)pItem)->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ bUrl = TRUE;
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+// String aFieldText = rEngine.GetText( aSel );
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_anchor << ' ' << OOO_STRING_SVTOOLS_HTML_O_href << "=\"";
+ OUT_STR( pURLField->GetURL() );
+ rStrm << "\">";
+ OUT_STR( pURLField->GetRepresentation() );
+ rStrm << "</" << OOO_STRING_SVTOOLS_HTML_anchor << '>';
+ }
+ }
+ }
+ if ( !bUrl )
+ OUT_STR( rEngine.GetText( aSel ) );
+ nStart = nEnd;
+ }
+ }
+ rEngine.SetUpdateMode( bOldUpdateMode );
+ }
+ return bFields;
+}
+
+
+BOOL ScHTMLExport::CopyLocalFileToINet( String& rFileNm,
+ const String& rTargetNm, BOOL bFileToFile )
+{
+ BOOL bRet = FALSE;
+ INetURLObject aFileUrl, aTargetUrl;
+ aFileUrl.SetSmartURL( rFileNm );
+ aTargetUrl.SetSmartURL( rTargetNm );
+ if( INET_PROT_FILE == aFileUrl.GetProtocol() &&
+ ( (bFileToFile && INET_PROT_FILE == aTargetUrl.GetProtocol()) ||
+ (!bFileToFile && INET_PROT_FILE != aTargetUrl.GetProtocol() &&
+ INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
+ INET_PROT_NEWS >= aTargetUrl.GetProtocol()) ) )
+ {
+ if( pSrcArr )
+ {
+ // wurde die Datei schon verschoben
+ USHORT nPos;
+ if( pSrcArr->Seek_Entry( &rFileNm, &nPos ))
+ {
+ rFileNm = *(*pDestArr)[ nPos ];
+ return TRUE;
+ }
+ }
+ else
+ {
+ pSrcArr = new SvStringsSortDtor( 4, 4 );
+ pDestArr = new SvStringsSortDtor( 4, 4 );
+ }
+
+ String* pSrc = new String( rFileNm );
+ SvFileStream aTmp( aFileUrl.PathToFileName(), STREAM_READ );
+
+ String* pDest = new String( aTargetUrl.GetPartBeforeLastName() );
+ *pDest += String(aFileUrl.GetName());
+
+ if( bFileToFile )
+ {
+ INetURLObject aCpyURL( *pDest );
+ SvFileStream aCpy( aCpyURL.PathToFileName(), STREAM_WRITE );
+ aCpy << aTmp;
+
+ aCpy.Close();
+ bRet = SVSTREAM_OK == aCpy.GetError();
+ }
+ else
+ {
+ SfxMedium aMedium( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE,
+ FALSE );
+
+ // temp. File anlegen
+ // aMedium.DownLoad();
+
+ {
+ SvFileStream aCpy( aMedium.GetPhysicalName(), STREAM_WRITE );
+ aCpy << aTmp;
+ }
+
+ // uebertragen
+ aMedium.Close();
+ aMedium.Commit();
+
+ bRet = 0 == aMedium.GetError();
+ }
+
+ if( bRet )
+ {
+ pSrcArr->Insert( pSrc );
+ pDestArr->Insert( pDest );
+ rFileNm = *pDest;
+ }
+ else
+ {
+ delete pSrc;
+ delete pDest;
+ }
+ }
+
+ return bRet;
+}
+
+
+void ScHTMLExport::MakeCIdURL( String& rURL )
+{
+ if( !aCId.Len() )
+ return;
+
+ INetURLObject aURLObj( rURL );
+ if( INET_PROT_FILE != aURLObj.GetProtocol() )
+ return;
+
+ String aLastName( aURLObj.GetLastName() );
+ DBG_ASSERT( aLastName.Len(), "Dateiname ohne Laenge!" );
+ aLastName.ToLowerAscii();
+
+ rURL.AssignAscii( "cid:" );
+ rURL += aLastName;
+ rURL.AppendAscii( "." );
+ rURL += aCId;
+}
+
+
+void ScHTMLExport::IncIndent( short nVal )
+{
+ sIndent[nIndent] = '\t';
+ nIndent = nIndent + nVal;
+ if ( nIndent < 0 )
+ nIndent = 0;
+ else if ( nIndent > nIndentMax )
+ nIndent = nIndentMax;
+ sIndent[nIndent] = 0;
+}
+
+
+
diff --git a/sc/source/filter/html/htmlexp2.cxx b/sc/source/filter/html/htmlexp2.cxx
new file mode 100644
index 000000000000..341f9afbc739
--- /dev/null
+++ b/sc/source/filter/html/htmlexp2.cxx
@@ -0,0 +1,249 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/xoutbmp.hxx>
+#include <svx/svdxcgv.hxx>
+#include <sot/exchange.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/transfer.hxx>
+#include <svtools/embedtransfer.hxx>
+#include <svl/urihelper.hxx>
+#include <tools/urlobj.hxx>
+
+#include "htmlexp.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "ftools.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+void ScHTMLExport::PrepareGraphics( ScDrawLayer* pDrawLayer, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ if ( pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ) )
+ {
+ SdrPage* pDrawPage = pDrawLayer->GetPage( static_cast<sal_uInt16>(nTab) );
+ if ( pDrawPage )
+ {
+ bTabHasGraphics = TRUE;
+ FillGraphList( pDrawPage, nTab,
+ nStartCol, nStartRow, nEndCol, nEndRow );
+ for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE;
+ pE = aGraphList.Next() )
+ {
+ if ( !pE->bInCell )
+ { // nicht alle in Zellen: einige neben Tabelle
+ bTabAlignedLeft = TRUE;
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void ScHTMLExport::FillGraphList( const SdrPage* pPage, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ ULONG nObjCount = pPage->GetObjCount();
+ if ( nObjCount )
+ {
+ Rectangle aRect;
+ if ( !bAll )
+ aRect = pDoc->GetMMRect( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while ( pObject )
+ {
+ Rectangle aObjRect = pObject->GetCurrentBoundRect();
+ if ( bAll || aRect.IsInside( aObjRect ) )
+ {
+ Size aSpace;
+ ScRange aR = pDoc->GetRange( nTab, aObjRect );
+ // Rectangle in mm/100
+ Size aSize( MMToPixel( aObjRect.GetSize() ) );
+ // If the image is somewhere in a merged range we must
+ // move the anchor to the upper left (THE span cell).
+ pDoc->ExtendOverlapped( aR );
+ SCCOL nCol1 = aR.aStart.Col();
+ SCROW nRow1 = aR.aStart.Row();
+ SCCOL nCol2 = aR.aEnd.Col();
+ SCROW nRow2 = aR.aEnd.Row();
+ // All cells empty under object?
+ BOOL bInCell = (pDoc->GetEmptyLinesInBlock(
+ nCol1, nRow1, nTab, nCol2, nRow2, nTab, DIR_TOP )
+ == static_cast< SCSIZE >( nRow2 - nRow1 )); // rows-1 !
+ if ( bInCell )
+ { // Spacing in spanning cell
+ Rectangle aCellRect = pDoc->GetMMRect(
+ nCol1, nRow1, nCol2, nRow2, nTab );
+ aSpace = MMToPixel( Size(
+ aCellRect.GetWidth() - aObjRect.GetWidth(),
+ aCellRect.GetHeight() - aObjRect.GetHeight() ));
+ aSpace.Width() += (nCol2-nCol1) * (nCellSpacing+1);
+ aSpace.Height() += (nRow2-nRow1) * (nCellSpacing+1);
+ aSpace.Width() /= 2;
+ aSpace.Height() /= 2;
+ }
+ ScHTMLGraphEntry* pE = new ScHTMLGraphEntry( pObject,
+ aR, aSize, bInCell, aSpace );
+ aGraphList.Insert( pE, LIST_APPEND );
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+
+
+void ScHTMLExport::WriteGraphEntry( ScHTMLGraphEntry* pE )
+{
+ SdrObject* pObject = pE->pObject;
+ ByteString aOpt;
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') +=
+ ByteString::CreateFromInt32( pE->aSize.Width() );
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') +=
+ ByteString::CreateFromInt32( pE->aSize.Height() );
+ if ( pE->bInCell )
+ {
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=') +=
+ ByteString::CreateFromInt32( pE->aSpace.Width() );
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=') +=
+ ByteString::CreateFromInt32( pE->aSpace.Height() );
+ }
+ switch ( pObject->GetObjIdentifier() )
+ {
+ case OBJ_GRAF:
+ {
+ const SdrGrafObj* pSGO = (SdrGrafObj*)pObject;
+ const SdrGrafObjGeoData* pGeo = (SdrGrafObjGeoData*)pSGO->GetGeoData();
+ USHORT nMirrorCase = (pGeo->aGeo.nDrehWink == 18000 ?
+ ( pGeo->bMirrored ? 3 : 4 ) : ( pGeo->bMirrored ? 2 : 1 ));
+ BOOL bHMirr = ( ( nMirrorCase == 2 ) || ( nMirrorCase == 4 ) );
+ BOOL bVMirr = ( ( nMirrorCase == 3 ) || ( nMirrorCase == 4 ) );
+ ULONG nXOutFlags = 0;
+ if ( bHMirr )
+ nXOutFlags |= XOUTBMP_MIRROR_HORZ;
+ if ( bVMirr )
+ nXOutFlags |= XOUTBMP_MIRROR_VERT;
+ String aLinkName;
+ if ( pSGO->IsLinkedGraphic() )
+ aLinkName = pSGO->GetFileName();
+ WriteImage( aLinkName, pSGO->GetGraphic(), aOpt, nXOutFlags );
+ pE->bWritten = TRUE;
+ }
+ break;
+ case OBJ_OLE2:
+ {
+ Graphic* pGraphic = ((SdrOle2Obj*)pObject)->GetGraphic();
+ if ( pGraphic )
+ {
+ String aLinkName;
+ WriteImage( aLinkName, *pGraphic, aOpt );
+ pE->bWritten = TRUE;
+ }
+ }
+ break;
+ default:
+ {
+ Graphic aGraph( SdrExchangeView::GetObjGraphic(
+ pDoc->GetDrawLayer(), pObject ) );
+ String aLinkName;
+ WriteImage( aLinkName, aGraph, aOpt );
+ pE->bWritten = TRUE;
+ }
+ }
+}
+
+
+void ScHTMLExport::WriteImage( String& rLinkName, const Graphic& rGrf,
+ const ByteString& rImgOptions, ULONG nXOutFlags )
+{
+ // embeddete Grafik -> via WriteGraphic schreiben
+ if( !rLinkName.Len() )
+ {
+ if( aStreamPath.Len() > 0 )
+ {
+ // Grafik als (JPG-)File speichern
+ String aGrfNm( aStreamPath );
+ nXOutFlags |= XOUTBMP_USE_NATIVE_IF_POSSIBLE;
+ USHORT nErr = XOutBitmap::WriteGraphic( rGrf, aGrfNm,
+ CREATE_STRING( "JPG" ), nXOutFlags );
+ if( !nErr ) // sonst fehlerhaft, da ist nichts auszugeben
+ {
+ rLinkName = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm,
+ URIHelper::GetMaybeFileHdl());
+ if ( HasCId() )
+ MakeCIdURL( rLinkName );
+ }
+ }
+ }
+ else
+ {
+ if( bCopyLocalFileToINet || HasCId() )
+ {
+ CopyLocalFileToINet( rLinkName, aStreamPath );
+ if ( HasCId() )
+ MakeCIdURL( rLinkName );
+ }
+ else
+ rLinkName = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ rLinkName,
+ URIHelper::GetMaybeFileHdl());
+ }
+ if( rLinkName.Len() )
+ { // <IMG SRC="..."[ rImgOptions]>
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_image << ' ' << OOO_STRING_SVTOOLS_HTML_O_src << "=\"";
+ HTMLOutFuncs::Out_String( rStrm, URIHelper::simpleNormalizedMakeRelative(
+ aBaseURL,
+ rLinkName ), eDestEnc ) << '\"';
+ if ( rImgOptions.Len() )
+ rStrm << rImgOptions.GetBuffer();
+ rStrm << '>' << sNewLine << GetIndentStr();
+ }
+}
+
+
+
+
diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx
new file mode 100644
index 000000000000..1c0b9fc8ec33
--- /dev/null
+++ b/sc/source/filter/html/htmlimp.cxx
@@ -0,0 +1,260 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/lrspitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <vcl/svapp.hxx>
+
+#include "htmlimp.hxx"
+#include "htmlpars.hxx"
+#include "filter.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "editutil.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "compiler.hxx"
+#include "rangenam.hxx"
+#include "attrib.hxx"
+#include "ftools.hxx"
+#include "tokenarray.hxx"
+
+
+//------------------------------------------------------------------------
+
+FltError ScFormatFilterPluginImpl::ScImportHTML( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc,
+ ScRange& rRange, double nOutputFactor, BOOL bCalcWidthHeight, SvNumberFormatter* pFormatter,
+ bool bConvertDate )
+{
+ ScHTMLImport aImp( pDoc, rBaseURL, rRange, bCalcWidthHeight );
+ FltError nErr = (FltError) aImp.Read( rStream, rBaseURL );
+ ScRange aR = aImp.GetRange();
+ rRange.aEnd = aR.aEnd;
+ aImp.WriteToDocument( TRUE, nOutputFactor, pFormatter, bConvertDate );
+ return nErr;
+}
+
+ScEEAbsImport *ScFormatFilterPluginImpl::CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, BOOL bCalcWidthHeight )
+{
+ return new ScHTMLImport( pDocP, rBaseURL, rRange, bCalcWidthHeight );
+}
+
+ScHTMLImport::ScHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, BOOL bCalcWidthHeight ) :
+ ScEEImport( pDocP, rRange )
+{
+ Size aPageSize;
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ const String& aPageStyle = mpDoc->GetPageStyle( rRange.aStart.Tab() );
+ ScStyleSheet* pStyleSheet = (ScStyleSheet*)mpDoc->
+ GetStyleSheetPool()->Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &rSet.Get( ATTR_LRSPACE );
+ long nLeftMargin = pLRItem->GetLeft();
+ long nRightMargin = pLRItem->GetRight();
+ const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &rSet.Get( ATTR_ULSPACE );
+ long nTopMargin = pULItem->GetUpper();
+ long nBottomMargin = pULItem->GetLower();
+ aPageSize = ((const SvxSizeItem&) rSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ if ( !aPageSize.Width() || !aPageSize.Height() )
+ {
+ DBG_ERRORFILE("PageSize Null ?!?!?");
+ aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
+ }
+ aPageSize.Width() -= nLeftMargin + nRightMargin;
+ aPageSize.Height() -= nTopMargin + nBottomMargin;
+ aPageSize = pDefaultDev->LogicToPixel( aPageSize, MapMode( MAP_TWIP ) );
+ }
+ else
+ {
+ DBG_ERRORFILE("kein StyleSheet?!?");
+ aPageSize = pDefaultDev->LogicToPixel(
+ SvxPaperInfo::GetPaperSize( PAPER_A4 ), MapMode( MAP_TWIP ) );
+ }
+ if( bCalcWidthHeight )
+ mpParser = new ScHTMLLayoutParser( mpEngine, rBaseURL, aPageSize, pDocP );
+ else
+ mpParser = new ScHTMLQueryParser( mpEngine, pDocP );
+}
+
+
+ScHTMLImport::~ScHTMLImport()
+{
+ // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
+ // Ist gewaehrleistet, da ScEEImport Basisklasse ist
+ delete (ScHTMLParser*) mpParser; // vor EditEngine!
+}
+
+
+void ScHTMLImport::InsertRangeName( ScDocument* pDoc, const String& rName, const ScRange& rRange )
+{
+ ScComplexRefData aRefData;
+ aRefData.InitRange( rRange );
+ ScTokenArray aTokArray;
+ aTokArray.AddDoubleReference( aRefData );
+ ScRangeData* pRangeData = new ScRangeData( pDoc, rName, aTokArray );
+ if( !pDoc->GetRangeName()->Insert( pRangeData ) )
+ delete pRangeData;
+}
+
+void ScHTMLImport::WriteToDocument(
+ BOOL bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
+{
+ ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor, pFormatter, bConvertDate );
+
+ const ScHTMLParser* pParser = GetParser();
+ const ScHTMLTable* pGlobTable = pParser->GetGlobalTable();
+ if( !pGlobTable )
+ return;
+
+ // set cell borders for HTML table cells
+ pGlobTable->ApplyCellBorders( mpDoc, maRange.aStart );
+
+ // correct cell borders for merged cells
+ for ( ScEEParseEntry* pEntry = pParser->First(); pEntry; pEntry = pParser->Next() )
+ {
+ if( (pEntry->nColOverlap > 1) || (pEntry->nRowOverlap > 1) )
+ {
+ SCTAB nTab = maRange.aStart.Tab();
+ const ScMergeAttr* pItem = (ScMergeAttr*) mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_MERGE );
+ if( pItem->IsMerged() )
+ {
+ SCCOL nColMerge = pItem->GetColMerge();
+ SCROW nRowMerge = pItem->GetRowMerge();
+
+ const SvxBoxItem* pToItem = (const SvxBoxItem*)
+ mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_BORDER );
+ SvxBoxItem aNewItem( *pToItem );
+ if( nColMerge > 1 )
+ {
+ const SvxBoxItem* pFromItem = (const SvxBoxItem*)
+ mpDoc->GetAttr( pEntry->nCol + nColMerge - 1, pEntry->nRow, nTab, ATTR_BORDER );
+ aNewItem.SetLine( pFromItem->GetLine( BOX_LINE_RIGHT ), BOX_LINE_RIGHT );
+ }
+ if( nRowMerge > 1 )
+ {
+ const SvxBoxItem* pFromItem = (const SvxBoxItem*)
+ mpDoc->GetAttr( pEntry->nCol, pEntry->nRow + nRowMerge - 1, nTab, ATTR_BORDER );
+ aNewItem.SetLine( pFromItem->GetLine( BOX_LINE_BOTTOM ), BOX_LINE_BOTTOM );
+ }
+ mpDoc->ApplyAttr( pEntry->nCol, pEntry->nRow, nTab, aNewItem );
+ }
+ }
+ }
+
+ // create ranges for HTML tables
+ // 1 - entire document
+ ScRange aNewRange( maRange.aStart );
+ aNewRange.aEnd.IncCol( static_cast<SCsCOL>(pGlobTable->GetDocSize( tdCol )) - 1 );
+ aNewRange.aEnd.IncRow( pGlobTable->GetDocSize( tdRow ) - 1 );
+ InsertRangeName( mpDoc, ScfTools::GetHTMLDocName(), aNewRange );
+
+ // 2 - all tables
+ InsertRangeName( mpDoc, ScfTools::GetHTMLTablesName(), ScRange( maRange.aStart ) );
+
+ // 3 - single tables
+ SCsCOL nColDiff = (SCsCOL)maRange.aStart.Col();
+ SCsROW nRowDiff = (SCsROW)maRange.aStart.Row();
+ SCsTAB nTabDiff = (SCsTAB)maRange.aStart.Tab();
+
+ ScHTMLTable* pTable = NULL;
+ ScHTMLTableId nTableId = SC_HTML_GLOBAL_TABLE;
+ while( (pTable = pGlobTable->FindNestedTable( ++nTableId )) != 0 )
+ {
+ pTable->GetDocRange( aNewRange );
+ aNewRange.Move( nColDiff, nRowDiff, nTabDiff );
+ // insert table number as name
+ InsertRangeName( mpDoc, ScfTools::GetNameFromHTMLIndex( nTableId ), aNewRange );
+ // insert table id as name
+ if( pTable->GetTableName().Len() )
+ {
+ String aName( ScfTools::GetNameFromHTMLName( pTable->GetTableName() ) );
+ USHORT nPos;
+ if( !mpDoc->GetRangeName()->SearchName( aName, nPos ) )
+ InsertRangeName( mpDoc, aName, aNewRange );
+ }
+ }
+}
+
+String ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
+{
+ return ScHTMLImport::GetHTMLRangeNameList( pDoc, rOrigName );
+}
+
+String ScHTMLImport::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
+{
+ DBG_ASSERT( pDoc, "ScHTMLImport::GetHTMLRangeNameList - missing document" );
+
+ String aNewName;
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ ScRangeList aRangeList;
+ xub_StrLen nTokenCnt = rOrigName.GetTokenCount( ';' );
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; nToken++ )
+ {
+ String aToken( rOrigName.GetToken( 0, ';', nStringIx ) );
+ if( pRangeNames && ScfTools::IsHTMLTablesName( aToken ) )
+ { // build list with all HTML tables
+ ULONG nIndex = 1;
+ USHORT nPos;
+ BOOL bLoop = TRUE;
+ while( bLoop )
+ {
+ aToken = ScfTools::GetNameFromHTMLIndex( nIndex++ );
+ bLoop = pRangeNames->SearchName( aToken, nPos );
+ if( bLoop )
+ {
+ const ScRangeData* pRangeData = (*pRangeNames)[ nPos ];
+ ScRange aRange;
+ if( pRangeData && pRangeData->IsReference( aRange ) && !aRangeList.In( aRange ) )
+ {
+ ScGlobal::AddToken( aNewName, aToken, ';' );
+ aRangeList.Append( aRange );
+ }
+ }
+ }
+ }
+ else
+ ScGlobal::AddToken( aNewName, aToken, ';' );
+ }
+ return aNewName;
+}
+
diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
new file mode 100644
index 000000000000..85e77fc3124b
--- /dev/null
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -0,0 +1,3069 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+#define SC_HTMLPARS_CXX
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svtools/htmlcfg.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/eitem.hxx>
+#include <svtools/filter.hxx>
+#include <svtools/parhtml.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmltokn.h>
+#include <sfx2/docfile.hxx>
+
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/tenccvt.hxx>
+
+#include "htmlpars.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "rangelst.hxx"
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+
+using namespace ::com::sun::star;
+
+
+SV_IMPL_VARARR_SORT( ScHTMLColOffset, ULONG );
+
+
+// ============================================================================
+// BASE class for HTML parser classes
+// ============================================================================
+
+ScHTMLParser::ScHTMLParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
+ ScEEParser( pEditEngine ),
+ mpDoc( pDoc )
+{
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+ for( sal_uInt16 nIndex = 0; nIndex < SC_HTML_FONTSIZES; ++nIndex )
+ maFontHeights[ nIndex ] = pHtmlOptions->GetFontSize( nIndex ) * 20;
+}
+
+ScHTMLParser::~ScHTMLParser()
+{
+}
+
+
+// ============================================================================
+
+ScHTMLLayoutParser::ScHTMLLayoutParser( EditEngine* pEditP, const String& rBaseURL, const Size& aPageSizeP, ScDocument* pDocP ) :
+ ScHTMLParser( pEditP, pDocP ),
+ aPageSize( aPageSizeP ),
+ aBaseURL( rBaseURL ),
+ xLockedList( new ScRangeList ),
+ pTables( NULL ),
+ pColOffset( new ScHTMLColOffset ),
+ pLocalColOffset( new ScHTMLColOffset ),
+ nFirstTableCell(0),
+ nTableLevel(0),
+ nTable(0),
+ nMaxTable(0),
+ nColCntStart(0),
+ nMaxCol(0),
+ nTableWidth(0),
+ nColOffset(0),
+ nColOffsetStart(0),
+ nMetaCnt(0),
+ nOffsetTolerance( SC_HTML_OFFSET_TOLERANCE_SMALL ),
+ bTabInTabCell( FALSE ),
+ bFirstRow( TRUE ),
+ bInCell( FALSE ),
+ bInTitle( FALSE )
+{
+ MakeColNoRef( pLocalColOffset, 0, 0, 0, 0 );
+ MakeColNoRef( pColOffset, 0, 0, 0, 0 );
+}
+
+
+ScHTMLLayoutParser::~ScHTMLLayoutParser()
+{
+ ScHTMLTableStackEntry* pS;
+ while ( (pS = aTableStack.Pop()) != 0 )
+ {
+ if ( pList->GetPos( pS->pCellEntry ) == LIST_ENTRY_NOTFOUND )
+ delete pS->pCellEntry;
+ if ( pS->pLocalColOffset != pLocalColOffset )
+ delete pS->pLocalColOffset;
+ delete pS;
+ }
+ if ( pLocalColOffset )
+ delete pLocalColOffset;
+ if ( pColOffset )
+ delete pColOffset;
+ if ( pTables )
+ {
+ for ( Table* pT = (Table*) pTables->First(); pT; pT = (Table*) pTables->Next() )
+ delete pT;
+ delete pTables;
+ }
+}
+
+
+ULONG ScHTMLLayoutParser::Read( SvStream& rStream, const String& rBaseURL )
+{
+ Link aOldLink = pEdit->GetImportHdl();
+ pEdit->SetImportHdl( LINK( this, ScHTMLLayoutParser, HTMLImportHdl ) );
+
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ BOOL bLoading = pObjSh && pObjSh->IsLoading();
+
+ SvKeyValueIteratorRef xValues;
+ SvKeyValueIterator* pAttributes = NULL;
+ if ( bLoading )
+ pAttributes = pObjSh->GetHeaderAttributes();
+ else
+ {
+ // When not loading, set up fake http headers to force the SfxHTMLParser to use UTF8
+ // (used when pasting from clipboard)
+
+ const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
+ if( pCharSet )
+ {
+ String aContentType = String::CreateFromAscii( "text/html; charset=" );
+ aContentType.AppendAscii( pCharSet );
+
+ xValues = new SvKeyValueIterator;
+ xValues->Append( SvKeyValue( String::CreateFromAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ), aContentType ) );
+ pAttributes = xValues;
+ }
+ }
+
+ ULONG nErr = pEdit->Read( rStream, rBaseURL, EE_FORMAT_HTML, pAttributes );
+
+ pEdit->SetImportHdl( aOldLink );
+ // Spaltenbreiten erzeugen
+ Adjust();
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ USHORT nCount = pColOffset->Count();
+ const ULONG* pOff = (const ULONG*) pColOffset->GetData();
+ ULONG nOff = *pOff++;
+ Size aSize;
+ for ( USHORT j = 1; j < nCount; j++, pOff++ )
+ {
+ aSize.Width() = *pOff - nOff;
+ aSize = pDefaultDev->PixelToLogic( aSize, MapMode( MAP_TWIP ) );
+ pColWidths->Insert( j-1, (void*)aSize.Width() );
+ nOff = *pOff;
+ }
+ return nErr;
+}
+
+
+const ScHTMLTable* ScHTMLLayoutParser::GetGlobalTable() const
+{
+ return 0;
+}
+
+
+void ScHTMLLayoutParser::NewActEntry( ScEEParseEntry* pE )
+{
+ ScEEParser::NewActEntry( pE );
+ if ( pE )
+ {
+ if ( !pE->aSel.HasRange() )
+ { // komplett leer, nachfolgender Text landet im gleichen Absatz!
+ pActEntry->aSel.nStartPara = pE->aSel.nEndPara;
+ pActEntry->aSel.nStartPos = pE->aSel.nEndPos;
+ }
+ }
+ pActEntry->aSel.nEndPara = pActEntry->aSel.nStartPara;
+ pActEntry->aSel.nEndPos = pActEntry->aSel.nStartPos;
+}
+
+
+void ScHTMLLayoutParser::EntryEnd( ScEEParseEntry* pE, const ESelection& rSel )
+{
+ if ( rSel.nEndPara >= pE->aSel.nStartPara )
+ {
+ pE->aSel.nEndPara = rSel.nEndPara;
+ pE->aSel.nEndPos = rSel.nEndPos;
+ }
+ else if ( rSel.nStartPara == pE->aSel.nStartPara - 1 && !pE->aSel.HasRange() )
+ { // kein Absatz angehaengt aber leer, nichts tun
+ }
+ else
+ {
+ DBG_ERRORFILE( "EntryEnd: EditEngine ESelection End < Start" );
+ }
+}
+
+
+void ScHTMLLayoutParser::NextRow( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo );
+ if ( nRowMax < ++nRowCnt )
+ nRowMax = nRowCnt;
+ nColCnt = nColCntStart;
+ nColOffset = nColOffsetStart;
+ bFirstRow = FALSE;
+}
+
+
+BOOL ScHTMLLayoutParser::SeekOffset( ScHTMLColOffset* pOffset, USHORT nOffset,
+ SCCOL* pCol, USHORT nOffsetTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::SeekOffset - illegal call" );
+ USHORT nPos;
+ BOOL bFound = pOffset->Seek_Entry( nOffset, &nPos );
+ *pCol = static_cast<SCCOL>(nPos);
+ if ( bFound )
+ return TRUE;
+ USHORT nCount = pOffset->Count();
+ if ( !nCount )
+ return FALSE;
+ // nPos ist Einfuegeposition, da liegt der Naechsthoehere (oder auch nicht)
+ if ( nPos < nCount && (((*pOffset)[nPos] - nOffsetTol) <= nOffset) )
+ return TRUE;
+ // nicht kleiner als alles andere? dann mit Naechstniedrigerem vergleichen
+ else if ( nPos && (((*pOffset)[nPos-1] + nOffsetTol) >= nOffset) )
+ {
+ (*pCol)--;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void ScHTMLLayoutParser::MakeCol( ScHTMLColOffset* pOffset, USHORT& nOffset,
+ USHORT& nWidth, USHORT nOffsetTol, USHORT nWidthTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::MakeCol - illegal call" );
+ SCCOL nPos;
+ if ( SeekOffset( pOffset, nOffset, &nPos, nOffsetTol ) )
+ nOffset = (USHORT)(*pOffset)[nPos];
+ else
+ pOffset->Insert( nOffset );
+ if ( nWidth )
+ {
+ if ( SeekOffset( pOffset, nOffset + nWidth, &nPos, nWidthTol ) )
+ nWidth = (USHORT)(*pOffset)[nPos] - nOffset;
+ else
+ pOffset->Insert( nOffset + nWidth );
+ }
+}
+
+
+void ScHTMLLayoutParser::MakeColNoRef( ScHTMLColOffset* pOffset, USHORT nOffset,
+ USHORT nWidth, USHORT nOffsetTol, USHORT nWidthTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::MakeColNoRef - illegal call" );
+ SCCOL nPos;
+ if ( SeekOffset( pOffset, nOffset, &nPos, nOffsetTol ) )
+ nOffset = (USHORT)(*pOffset)[nPos];
+ else
+ pOffset->Insert( nOffset );
+ if ( nWidth )
+ {
+ if ( !SeekOffset( pOffset, nOffset + nWidth, &nPos, nWidthTol ) )
+ pOffset->Insert( nOffset + nWidth );
+ }
+}
+
+
+void ScHTMLLayoutParser::ModifyOffset( ScHTMLColOffset* pOffset, USHORT& nOldOffset,
+ USHORT& nNewOffset, USHORT nOffsetTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::ModifyOffset - illegal call" );
+ SCCOL nPos;
+ if ( !SeekOffset( pOffset, nOldOffset, &nPos, nOffsetTol ) )
+ {
+ if ( SeekOffset( pOffset, nNewOffset, &nPos, nOffsetTol ) )
+ nNewOffset = (USHORT)(*pOffset)[nPos];
+ else
+ pOffset->Insert( nNewOffset );
+ return ;
+ }
+ nOldOffset = (USHORT)(*pOffset)[nPos];
+ SCCOL nPos2;
+ if ( SeekOffset( pOffset, nNewOffset, &nPos2, nOffsetTol ) )
+ {
+ nNewOffset = (USHORT)(*pOffset)[nPos2];
+ return ;
+ }
+ ULONG* pData = ((ULONG*) pOffset->GetData()) + nPos; //! QAD
+ long nDiff = nNewOffset - nOldOffset;
+ if ( nDiff < 0 )
+ {
+ const ULONG* pStop = pOffset->GetData();
+ do
+ {
+ *pData += nDiff;
+ } while ( pStop < pData-- );
+ }
+ else
+ {
+ const ULONG* pStop = pOffset->GetData() + pOffset->Count();
+ do
+ {
+ *pData += nDiff;
+ } while ( ++pData < pStop );
+ }
+}
+
+
+void ScHTMLLayoutParser::SkipLocked( ScEEParseEntry* pE, BOOL bJoin )
+{
+ if ( ValidCol(pE->nCol) )
+ { // wuerde sonst bei ScAddress falschen Wert erzeugen, evtl. Endlosschleife!
+ BOOL bBadCol = FALSE;
+ BOOL bAgain;
+ ScRange aRange( pE->nCol, pE->nRow, 0,
+ pE->nCol + pE->nColOverlap - 1, pE->nRow + pE->nRowOverlap - 1, 0 );
+ do
+ {
+ bAgain = FALSE;
+ for ( ScRange* pR = xLockedList->First(); pR; pR = xLockedList->Next() )
+ {
+ if ( pR->Intersects( aRange ) )
+ {
+ pE->nCol = pR->aEnd.Col() + 1;
+ SCCOL nTmp = pE->nCol + pE->nColOverlap - 1;
+ if ( pE->nCol > MAXCOL || nTmp > MAXCOL )
+ bBadCol = TRUE;
+ else
+ {
+ bAgain = TRUE;
+ aRange.aStart.SetCol( pE->nCol );
+ aRange.aEnd.SetCol( nTmp );
+ }
+ break;
+ }
+ }
+ } while ( bAgain );
+ if ( bJoin && !bBadCol )
+ xLockedList->Join( aRange );
+ }
+}
+
+
+void ScHTMLLayoutParser::Adjust()
+{
+ for ( ScRange* pR = xLockedList->First(); pR; pR = xLockedList->Next() )
+ delete pR;
+ xLockedList->Clear();
+ ScHTMLAdjustStack aStack;
+ ScHTMLAdjustStackEntry* pS;
+ USHORT nTab = 0;
+ SCCOL nLastCol = SCCOL_MAX;
+ SCROW nNextRow = 0;
+ SCROW nCurRow = 0;
+ USHORT nPageWidth = (USHORT) aPageSize.Width();
+ Table* pTab = NULL;
+ for ( ScEEParseEntry* pE = pList->First(); pE; pE = pList->Next() )
+ {
+ if ( pE->nTab < nTab )
+ { // Table beendet
+ if ( (pS = aStack.Pop()) != 0 )
+ {
+ nLastCol = pS->nLastCol;
+ nNextRow = pS->nNextRow;
+ nCurRow = pS->nCurRow;
+ }
+ delete pS;
+ nTab = pE->nTab;
+ pTab = (pTables ? (Table*) pTables->Get( nTab ) : NULL);
+
+ }
+ SCROW nRow = pE->nRow;
+ if ( pE->nCol <= nLastCol )
+ { // naechste Zeile
+ if ( pE->nRow < nNextRow )
+ pE->nRow = nCurRow = nNextRow;
+ else
+ nCurRow = nNextRow = pE->nRow;
+ SCROW nR;
+ if ( pTab && ((nR = (SCROW)(ULONG)pTab->Get( nCurRow )) != 0) )
+ nNextRow += nR;
+ else
+ nNextRow++;
+ }
+ else
+ pE->nRow = nCurRow;
+ nLastCol = pE->nCol; // eingelesene Col
+ if ( pE->nTab > nTab )
+ { // neue Table
+ aStack.Push( new ScHTMLAdjustStackEntry(
+ nLastCol, nNextRow, nCurRow ) );
+ nTab = pE->nTab;
+ pTab = (pTables ? (Table*) pTables->Get( nTab ) : NULL);
+ // neuer Zeilenabstand
+ SCROW nR;
+ if ( pTab && ((nR = (SCROW)(ULONG)pTab->Get( nCurRow )) != 0) )
+ nNextRow = nCurRow + nR;
+ else
+ nNextRow = nCurRow + 1;
+ }
+ if ( nTab == 0 )
+ pE->nWidth = nPageWidth;
+ else
+ { // echte Table, keine Absaetze auf der Wiese
+ if ( pTab )
+ {
+ SCROW nRowSpan = pE->nRowOverlap;
+ for ( SCROW j=0; j < nRowSpan; j++ )
+ { // aus merged Zeilen resultierendes RowSpan
+ SCROW nRows = (SCROW)(ULONG)pTab->Get( nRow+j );
+ if ( nRows > 1 )
+ {
+ pE->nRowOverlap += nRows - 1;
+ if ( j == 0 )
+ { // merged Zeilen verschieben die naechste Zeile
+ SCROW nTmp = nCurRow + nRows;
+ if ( nNextRow < nTmp )
+ nNextRow = nTmp;
+ }
+ }
+ }
+ }
+ }
+ // echte Col
+ SeekOffset( pColOffset, pE->nOffset, &pE->nCol, nOffsetTolerance );
+ SCCOL nColBeforeSkip = pE->nCol;
+ SkipLocked( pE, FALSE );
+ if ( pE->nCol != nColBeforeSkip )
+ {
+ SCCOL nCount = (SCCOL)pColOffset->Count();
+ if ( nCount <= pE->nCol )
+ {
+ pE->nOffset = (USHORT) (*pColOffset)[nCount-1];
+ MakeCol( pColOffset, pE->nOffset, pE->nWidth, nOffsetTolerance, nOffsetTolerance );
+ }
+ else
+ {
+ pE->nOffset = (USHORT) (*pColOffset)[pE->nCol];
+ }
+ }
+ SCCOL nPos;
+ if ( pE->nWidth && SeekOffset( pColOffset, pE->nOffset + pE->nWidth, &nPos, nOffsetTolerance ) )
+ pE->nColOverlap = (nPos > pE->nCol ? nPos - pE->nCol : 1);
+ else
+ {
+//2do: das muss nicht korrekt sein, ist aber..
+ pE->nColOverlap = 1;
+ }
+ xLockedList->Join( ScRange( pE->nCol, pE->nRow, 0,
+ pE->nCol + pE->nColOverlap - 1, pE->nRow + pE->nRowOverlap - 1, 0 ) );
+ // MaxDimensions mitfuehren
+ SCCOL nColTmp = pE->nCol + pE->nColOverlap;
+ if ( nColMax < nColTmp )
+ nColMax = nColTmp;
+ SCROW nRowTmp = pE->nRow + pE->nRowOverlap;
+ if ( nRowMax < nRowTmp )
+ nRowMax = nRowTmp;
+ }
+ while ( (pS = aStack.Pop()) != 0 )
+ delete pS;
+}
+
+
+USHORT ScHTMLLayoutParser::GetWidth( ScEEParseEntry* pE )
+{
+ if ( pE->nWidth )
+ return pE->nWidth;
+ sal_Int32 nTmp = ::std::min( static_cast<sal_Int32>( pE->nCol -
+ nColCntStart + pE->nColOverlap),
+ static_cast<sal_Int32>( pLocalColOffset->Count() - 1));
+ SCCOL nPos = (nTmp < 0 ? 0 : static_cast<SCCOL>(nTmp));
+ USHORT nOff2 = (USHORT) (*pLocalColOffset)[nPos];
+ if ( pE->nOffset < nOff2 )
+ return nOff2 - pE->nOffset;
+ return 0;
+}
+
+
+void ScHTMLLayoutParser::SetWidths()
+{
+ ScEEParseEntry* pE;
+ SCCOL nCol;
+ if ( !nTableWidth )
+ nTableWidth = (USHORT) aPageSize.Width();
+ SCCOL nColsPerRow = nMaxCol - nColCntStart;
+ if ( nColsPerRow <= 0 )
+ nColsPerRow = 1;
+ if ( pLocalColOffset->Count() <= 2 )
+ { // nur PageSize, es gab keine Width-Angabe
+ USHORT nWidth = nTableWidth / static_cast<USHORT>(nColsPerRow);
+ USHORT nOff = nColOffsetStart;
+ pLocalColOffset->Remove( (USHORT)0, pLocalColOffset->Count() );
+ for ( nCol = 0; nCol <= nColsPerRow; ++nCol, nOff = nOff + nWidth )
+ {
+ MakeColNoRef( pLocalColOffset, nOff, 0, 0, 0 );
+ }
+ nTableWidth = (USHORT)((*pLocalColOffset)[pLocalColOffset->Count() -1 ] - (*pLocalColOffset)[0]);
+ pE = pList->Seek( nFirstTableCell );
+ while ( pE )
+ {
+ if ( pE->nTab == nTable )
+ {
+ pE->nOffset = (USHORT) (*pLocalColOffset)[pE->nCol - nColCntStart];
+ pE->nWidth = 0; // to be recalculated later
+ }
+ pE = pList->Next();
+ }
+ }
+ else
+ { // einige mit einige ohne Width
+ pE = pList->Seek( nFirstTableCell );
+ // #36350# wieso eigentlich kein pE ?!?
+ if ( pE )
+ {
+ USHORT* pOffsets = new USHORT[ nColsPerRow+1 ];
+ memset( pOffsets, 0, (nColsPerRow+1) * sizeof(USHORT) );
+ USHORT* pWidths = new USHORT[ nColsPerRow ];
+ memset( pWidths, 0, nColsPerRow * sizeof(USHORT) );
+ pOffsets[0] = nColOffsetStart;
+ while ( pE )
+ {
+ if ( pE->nTab == nTable && pE->nWidth )
+ {
+ nCol = pE->nCol - nColCntStart;
+ if ( nCol < nColsPerRow )
+ {
+ if ( pE->nColOverlap == 1 )
+ {
+ if ( pWidths[nCol] < pE->nWidth )
+ pWidths[nCol] = pE->nWidth;
+ }
+ else
+ { // try to find a single undefined width
+ USHORT nTotal = 0;
+ BOOL bFound = FALSE;
+ SCCOL nHere = 0;
+ SCCOL nStop = Min( static_cast<SCCOL>(nCol + pE->nColOverlap), nColsPerRow );
+ for ( ; nCol < nStop; nCol++ )
+ {
+ if ( pWidths[nCol] )
+ nTotal = nTotal + pWidths[nCol];
+ else
+ {
+ if ( bFound )
+ {
+ bFound = FALSE;
+ break; // for
+ }
+ bFound = TRUE;
+ nHere = nCol;
+ }
+ }
+ if ( bFound && pE->nWidth > nTotal )
+ pWidths[nHere] = pE->nWidth - nTotal;
+ }
+ }
+ }
+ pE = pList->Next();
+ }
+ USHORT nWidths = 0;
+ USHORT nUnknown = 0;
+ for ( nCol = 0; nCol < nColsPerRow; nCol++ )
+ {
+ if ( pWidths[nCol] )
+ nWidths = nWidths + pWidths[nCol];
+ else
+ nUnknown++;
+ }
+ if ( nUnknown )
+ {
+ USHORT nW = ((nWidths < nTableWidth) ?
+ ((nTableWidth - nWidths) / nUnknown) :
+ (nTableWidth / nUnknown));
+ for ( nCol = 0; nCol < nColsPerRow; nCol++ )
+ {
+ if ( !pWidths[nCol] )
+ pWidths[nCol] = nW;
+ }
+ }
+ for ( nCol = 1; nCol <= nColsPerRow; nCol++ )
+ {
+ pOffsets[nCol] = pOffsets[nCol-1] + pWidths[nCol-1];
+ }
+ pLocalColOffset->Remove( (USHORT)0, pLocalColOffset->Count() );
+ for ( nCol = 0; nCol <= nColsPerRow; nCol++ )
+ {
+ MakeColNoRef( pLocalColOffset, pOffsets[nCol], 0, 0, 0 );
+ }
+ nTableWidth = pOffsets[nColsPerRow] - pOffsets[0];
+
+ pE = pList->Seek( nFirstTableCell );
+ while ( pE )
+ {
+ if ( pE->nTab == nTable )
+ {
+ nCol = pE->nCol - nColCntStart;
+ DBG_ASSERT( nCol < nColsPerRow, "ScHTMLLayoutParser::SetWidths: column overflow" );
+ if ( nCol < nColsPerRow )
+ {
+ pE->nOffset = pOffsets[nCol];
+ nCol = nCol + pE->nColOverlap;
+ if ( nCol > nColsPerRow )
+ nCol = nColsPerRow;
+ pE->nWidth = pOffsets[nCol] - pE->nOffset;
+ }
+ }
+ pE = pList->Next();
+ }
+
+ delete [] pWidths;
+ delete [] pOffsets;
+ }
+ }
+ if ( pLocalColOffset->Count() )
+ {
+ USHORT nMax = (USHORT) (*pLocalColOffset)[pLocalColOffset->Count() - 1];
+ if ( aPageSize.Width() < nMax )
+ aPageSize.Width() = nMax;
+ }
+ pE = pList->Seek( nFirstTableCell );
+ while ( pE )
+ {
+ if ( pE->nTab == nTable )
+ {
+ if ( !pE->nWidth )
+ {
+ pE->nWidth = GetWidth( pE );
+ DBG_ASSERT( pE->nWidth, "SetWidths: pE->nWidth == 0" );
+ }
+ MakeCol( pColOffset, pE->nOffset, pE->nWidth, nOffsetTolerance, nOffsetTolerance );
+ }
+ pE = pList->Next();
+ }
+}
+
+
+void ScHTMLLayoutParser::Colonize( ScEEParseEntry* pE )
+{
+ if ( pE->nCol == SCCOL_MAX )
+ pE->nCol = nColCnt;
+ if ( pE->nRow == SCROW_MAX )
+ pE->nRow = nRowCnt;
+ SCCOL nCol = pE->nCol;
+ SkipLocked( pE ); // Spaltenverdraengung nach rechts
+
+ if ( nCol < pE->nCol )
+ { // verdraengt
+ nCol = pE->nCol - nColCntStart;
+ SCCOL nCount = static_cast<SCCOL>(pLocalColOffset->Count());
+ if ( nCol < nCount )
+ nColOffset = (USHORT) (*pLocalColOffset)[nCol];
+ else
+ nColOffset = (USHORT) (*pLocalColOffset)[nCount - 1];
+ }
+ pE->nOffset = nColOffset;
+ USHORT nWidth = GetWidth( pE );
+ MakeCol( pLocalColOffset, pE->nOffset, nWidth, nOffsetTolerance, nOffsetTolerance );
+ if ( pE->nWidth )
+ pE->nWidth = nWidth;
+ nColOffset = pE->nOffset + nWidth;
+ if ( nTableWidth < nColOffset - nColOffsetStart )
+ nTableWidth = nColOffset - nColOffsetStart;
+}
+
+
+void ScHTMLLayoutParser::CloseEntry( ImportInfo* pInfo )
+{
+ bInCell = FALSE;
+ if ( bTabInTabCell )
+ { // in TableOff vom Stack geholt
+ bTabInTabCell = FALSE;
+ if ( pList->GetPos( pActEntry ) == LIST_ENTRY_NOTFOUND )
+ delete pActEntry;
+ NewActEntry( pList->Last() ); // neuer freifliegender pActEntry
+ return ;
+ }
+ if ( pActEntry->nTab == 0 )
+ pActEntry->nWidth = (USHORT) aPageSize.Width();
+ Colonize( pActEntry );
+ nColCnt = pActEntry->nCol + pActEntry->nColOverlap;
+ if ( nMaxCol < nColCnt )
+ nMaxCol = nColCnt; // TableStack MaxCol
+ if ( nColMax < nColCnt )
+ nColMax = nColCnt; // globales MaxCol fuer ScEEParser GetDimensions!
+ EntryEnd( pActEntry, pInfo->aSelection );
+ ESelection& rSel = pActEntry->aSel;
+ while ( rSel.nStartPara < rSel.nEndPara
+ && pEdit->GetTextLen( rSel.nStartPara ) == 0 )
+ { // vorgehaengte Leerabsaetze strippen
+ rSel.nStartPara++;
+ }
+ while ( rSel.nEndPos == 0 && rSel.nEndPara > rSel.nStartPara )
+ { // angehaengte Leerabsaetze strippen
+ rSel.nEndPara--;
+ rSel.nEndPos = pEdit->GetTextLen( rSel.nEndPara );
+ }
+ if ( rSel.nStartPara > rSel.nEndPara )
+ { // gibt GPF in CreateTextObject
+ DBG_ERRORFILE( "CloseEntry: EditEngine ESelection Start > End" );
+ rSel.nEndPara = rSel.nStartPara;
+ }
+ if ( rSel.HasRange() )
+ pActEntry->aItemSet.Put( SfxBoolItem( ATTR_LINEBREAK, TRUE ) );
+ pList->Insert( pActEntry, LIST_APPEND );
+ NewActEntry( pActEntry ); // neuer freifliegender pActEntry
+}
+
+
+IMPL_LINK( ScHTMLLayoutParser, HTMLImportHdl, ImportInfo*, pInfo )
+{
+#if defined(erDEBUG) //|| 1
+ static ESelection aDebugSel;
+ static String aDebugStr;
+ static SvFileStream* pDebugStrm = NULL;
+ static ULONG nDebugStrmPos = 0;
+ static ULONG nDebugCount = 0;
+ static ULONG nDebugCountAll = 0;
+ static const sal_Char* sDebugState[15] = {
+ "RTFIMP_START", "RTFIMP_END",
+ "RTFIMP_NEXTTOKEN", "RTFIMP_UNKNOWNATTR",
+ "RTFIMP_SETATTR",
+ "RTFIMP_INSERTTEXT",
+ "RTFIMP_INSERTPARA",
+ "HTMLIMP_START", "HTMLIMP_END",
+ "HTMLIMP_NEXTTOKEN", "HTMLIMP_UNKNOWNATTR",
+ "HTMLIMP_SETATTR",
+ "HTMLIMP_INSERTTEXT",
+ "HTMLIMP_INSERTPARA", "HTMLIMP_INSERTFIELD"
+ };
+
+ nDebugCountAll++;
+ if ( pInfo->eState != HTMLIMP_NEXTTOKEN // not too much
+ || pInfo->nToken == HTML_TABLE_ON
+ || pInfo->nToken == HTML_TABLE_OFF
+ || pInfo->nToken == HTML_TABLEROW_ON
+ || pInfo->nToken == HTML_TABLEROW_OFF
+ || pInfo->nToken == HTML_TABLEHEADER_ON
+ || pInfo->nToken == HTML_TABLEHEADER_OFF
+ || pInfo->nToken == HTML_TABLEDATA_ON
+ || pInfo->nToken == HTML_TABLEDATA_OFF
+ || !aDebugSel.IsEqual( pInfo->aSelection )
+ || pInfo->aText.Len() || aDebugStr != pInfo->aText
+ )
+ {
+ aDebugSel = pInfo->aSelection;
+ aDebugStr = pInfo->aText;
+ nDebugCount++;
+ if ( !pDebugStrm )
+ {
+ pDebugStrm = new SvFileStream( "d:\\erdbghtm.log",
+ STREAM_WRITE | STREAM_TRUNC );
+ }
+ else
+ {
+ pDebugStrm->ReOpen();
+ pDebugStrm->Seek( nDebugStrmPos );
+ }
+ SvFileStream& rS = *pDebugStrm;
+ rS.WriteNumber( nDebugCountAll ); rS << ".: ";
+ rS.WriteNumber( nDebugCount ); rS << ". State: ";
+ rS.WriteNumber( (USHORT) pInfo->eState );
+ rS << ' ' << sDebugState[pInfo->eState] << endl;
+ rS << "SPar,SPos EPar,EPos: ";
+ rS.WriteNumber( aDebugSel.nStartPara ); rS << ',';
+ rS.WriteNumber( aDebugSel.nStartPos ); rS << ' ';
+ rS.WriteNumber( aDebugSel.nEndPara ); rS << ',';
+ rS.WriteNumber( aDebugSel.nEndPos ); rS << endl;
+ if ( aDebugStr.Len() )
+ {
+ rS << "Text: \"" << aDebugStr << '\"' << endl;
+ }
+ else
+ {
+ rS << "Text:" << endl;
+ }
+ rS << "Token: "; rS.WriteNumber( pInfo->nToken );
+ switch ( pInfo->nToken )
+ {
+ case HTML_TABLE_ON:
+ rS << " HTML_TABLE_ON";
+ break;
+ case HTML_TABLE_OFF:
+ rS << " HTML_TABLE_OFF";
+ break;
+ case HTML_TABLEROW_ON:
+ rS << " HTML_TABLEROW_ON";
+ break;
+ case HTML_TABLEROW_OFF:
+ rS << " HTML_TABLEROW_OFF";
+ break;
+ case HTML_TABLEHEADER_ON:
+ rS << " HTML_TABLEHEADER_ON";
+ break;
+ case HTML_TABLEHEADER_OFF:
+ rS << " HTML_TABLEHEADER_OFF";
+ break;
+ case HTML_TABLEDATA_ON:
+ rS << " HTML_TABLEDATA_ON";
+ break;
+ case HTML_TABLEDATA_OFF:
+ rS << " HTML_TABLEDATA_OFF";
+ break;
+ }
+ rS << " Value: "; rS.WriteNumber( pInfo->nTokenValue );
+ rS << endl << endl;
+ nDebugStrmPos = pDebugStrm->Tell();
+ pDebugStrm->Close();
+ }
+#endif
+ switch ( pInfo->eState )
+ {
+ case HTMLIMP_NEXTTOKEN:
+ ProcToken( pInfo );
+ break;
+ case HTMLIMP_UNKNOWNATTR:
+ ProcToken( pInfo );
+ break;
+ case HTMLIMP_START:
+ break;
+ case HTMLIMP_END:
+ if ( pInfo->aSelection.nEndPos )
+ {
+ // If text remains: create paragraph, without calling CloseEntry().
+ if( bInCell ) // #108269# ...but only in opened table cells.
+ {
+ bInCell = FALSE;
+ NextRow( pInfo );
+ bInCell = TRUE;
+ }
+ CloseEntry( pInfo );
+ }
+ while ( nTableLevel > 0 )
+ TableOff( pInfo ); // close tables, if </TABLE> missing
+ break;
+ case HTMLIMP_SETATTR:
+ break;
+ case HTMLIMP_INSERTTEXT:
+ break;
+ case HTMLIMP_INSERTPARA:
+ if ( nTableLevel < 1 )
+ {
+ CloseEntry( pInfo );
+ NextRow( pInfo );
+ }
+ break;
+ case HTMLIMP_INSERTFIELD:
+ break;
+ default:
+ DBG_ERRORFILE("HTMLImportHdl: unknown ImportInfo.eState");
+ }
+ return 0;
+}
+
+
+// Groesster Gemeinsamer Teiler nach Euklid (Kettendivision)
+// Sonderfall: 0 und irgendwas geben 1
+SCROW lcl_GGT( SCROW a, SCROW b )
+{
+ if ( !a || !b )
+ return 1;
+ do
+ {
+ if ( a > b )
+ a -= SCROW(a / b) * b;
+ else
+ b -= SCROW(b / a) * a;
+ } while ( a && b );
+ return ((a != 0) ? a : b);
+}
+
+
+// Kleinstes Gemeinsames Vielfaches: a * b / GGT(a,b)
+SCROW lcl_KGV( SCROW a, SCROW b )
+{
+ if ( a > b ) // Ueberlauf unwahrscheinlicher machen
+ return (a / lcl_GGT(a,b)) * b;
+ else
+ return (b / lcl_GGT(a,b)) * a;
+}
+
+
+void ScHTMLLayoutParser::TableDataOn( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo );
+ if ( !nTableLevel )
+ {
+ DBG_ERROR( "Dummbatz-Dok! <TH> oder <TD> ohne vorheriges <TABLE>" );
+ TableOn( pInfo );
+ }
+ bInCell = TRUE;
+ BOOL bHorJustifyCenterTH = (pInfo->nToken == HTML_TABLEHEADER_ON);
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_COLSPAN:
+ {
+ pActEntry->nColOverlap = ( SCCOL ) pOption->GetString().ToInt32();
+ }
+ break;
+ case HTML_O_ROWSPAN:
+ {
+ pActEntry->nRowOverlap = ( SCROW ) pOption->GetString().ToInt32();
+ }
+ break;
+ case HTML_O_ALIGN:
+ {
+ bHorJustifyCenterTH = FALSE;
+ SvxCellHorJustify eVal;
+ const String& rOptVal = pOption->GetString();
+ if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) == COMPARE_EQUAL )
+ eVal = SVX_HOR_JUSTIFY_RIGHT;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) == COMPARE_EQUAL )
+ eVal = SVX_HOR_JUSTIFY_CENTER;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) == COMPARE_EQUAL )
+ eVal = SVX_HOR_JUSTIFY_LEFT;
+ else
+ eVal = SVX_HOR_JUSTIFY_STANDARD;
+ if ( eVal != SVX_HOR_JUSTIFY_STANDARD )
+ pActEntry->aItemSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY) );
+ }
+ break;
+ case HTML_O_VALIGN:
+ {
+ SvxCellVerJustify eVal;
+ const String& rOptVal = pOption->GetString();
+ if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_top ) == COMPARE_EQUAL )
+ eVal = SVX_VER_JUSTIFY_TOP;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_middle ) == COMPARE_EQUAL )
+ eVal = SVX_VER_JUSTIFY_CENTER;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_bottom ) == COMPARE_EQUAL )
+ eVal = SVX_VER_JUSTIFY_BOTTOM;
+ else
+ eVal = SVX_VER_JUSTIFY_STANDARD;
+ pActEntry->aItemSet.Put( SvxVerJustifyItem( eVal, ATTR_VER_JUSTIFY) );
+ }
+ break;
+ case HTML_O_WIDTH:
+ {
+ pActEntry->nWidth = GetWidthPixel( pOption );
+ }
+ break;
+ case HTML_O_BGCOLOR:
+ {
+ Color aColor;
+ pOption->GetColor( aColor );
+ pActEntry->aItemSet.Put(
+ SvxBrushItem( aColor, ATTR_BACKGROUND ) );
+ }
+ break;
+ case HTML_O_SDVAL:
+ {
+ pActEntry->pValStr = new String( pOption->GetString() );
+ }
+ break;
+ case HTML_O_SDNUM:
+ {
+ pActEntry->pNumStr = new String( pOption->GetString() );
+ }
+ break;
+ }
+ }
+ pActEntry->nCol = nColCnt;
+ pActEntry->nRow = nRowCnt;
+ pActEntry->nTab = nTable;
+
+ if ( bHorJustifyCenterTH )
+ pActEntry->aItemSet.Put(
+ SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) );
+}
+
+
+void ScHTMLLayoutParser::TableRowOn( ImportInfo* pInfo )
+{
+ if ( nColCnt > nColCntStart )
+ NextRow( pInfo ); // das optionale TableRowOff war nicht
+ nColOffset = nColOffsetStart;
+}
+
+
+void ScHTMLLayoutParser::TableRowOff( ImportInfo* pInfo )
+{
+ NextRow( pInfo );
+}
+
+
+void ScHTMLLayoutParser::TableDataOff( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo ); // aber nur wenn's auch eine war
+}
+
+
+void ScHTMLLayoutParser::TableOn( ImportInfo* pInfo )
+{
+ String aTabName;
+ bool bBorderOn = false;
+
+ if ( ++nTableLevel > 1 )
+ { // Table in Table
+ USHORT nTmpColOffset = nColOffset; // wird in Colonize noch angepasst
+ Colonize( pActEntry );
+ aTableStack.Push( new ScHTMLTableStackEntry(
+ pActEntry, xLockedList, pLocalColOffset, nFirstTableCell,
+ nColCnt, nRowCnt, nColCntStart, nMaxCol, nTable,
+ nTableWidth, nColOffset, nColOffsetStart,
+ bFirstRow ) );
+ USHORT nLastWidth = nTableWidth;
+ nTableWidth = GetWidth( pActEntry );
+ if ( nTableWidth == nLastWidth && nMaxCol - nColCntStart > 1 )
+ { // es muss mehr als einen geben, also kann dieser nicht alles sein
+ nTableWidth = nLastWidth / static_cast<USHORT>((nMaxCol - nColCntStart));
+ }
+ nLastWidth = nTableWidth;
+ if ( pInfo->nToken == HTML_TABLE_ON )
+ { // es kann auch TD oder TH sein, wenn es vorher kein TABLE gab
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_WIDTH:
+ { // Prozent: von Dokumentbreite bzw. aeusserer Zelle
+ nTableWidth = GetWidthPixel( pOption );
+ }
+ break;
+ case HTML_O_BORDER:
+ bBorderOn = ((pOption->GetString().Len() == 0) || (pOption->GetNumber() != 0));
+ break;
+ case HTML_O_ID:
+ aTabName.Assign( pOption->GetString() );
+ break;
+ }
+ }
+ }
+ bInCell = FALSE;
+ if ( bTabInTabCell && !(nTableWidth < nLastWidth) )
+ { // mehrere Tabellen in einer Zelle, untereinander
+ bTabInTabCell = FALSE;
+ NextRow( pInfo );
+ }
+ else
+ { // in dieser Zelle geht's los, oder nebeneinander
+ bTabInTabCell = FALSE;
+ nColCntStart = nColCnt;
+ nColOffset = nTmpColOffset;
+ nColOffsetStart = nColOffset;
+ }
+
+ ScEEParseEntry* pE = pList->Last();
+ NewActEntry( pE ); // neuer freifliegender pActEntry
+ xLockedList = new ScRangeList;
+ }
+ else
+ { // einfache Table auf Dokumentebene
+ EntryEnd( pActEntry, pInfo->aSelection );
+ if ( pActEntry->aSel.HasRange() )
+ { // noch fliegender Text
+ CloseEntry( pInfo );
+ NextRow( pInfo );
+ }
+ aTableStack.Push( new ScHTMLTableStackEntry(
+ pActEntry, xLockedList, pLocalColOffset, nFirstTableCell,
+ nColCnt, nRowCnt, nColCntStart, nMaxCol, nTable,
+ nTableWidth, nColOffset, nColOffsetStart,
+ bFirstRow ) );
+ // As soon as we have multiple tables we need to be tolerant with the offsets.
+ if (nMaxTable > 0)
+ nOffsetTolerance = SC_HTML_OFFSET_TOLERANCE_LARGE;
+ nTableWidth = 0;
+ if ( pInfo->nToken == HTML_TABLE_ON )
+ { // es kann auch TD oder TH sein, wenn es vorher kein TABLE gab
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_WIDTH:
+ { // Prozent: von Dokumentbreite bzw. aeusserer Zelle
+ nTableWidth = GetWidthPixel( pOption );
+ }
+ break;
+ case HTML_O_BORDER:
+ bBorderOn = ((pOption->GetString().Len() == 0) || (pOption->GetNumber() != 0));
+ break;
+ case HTML_O_ID:
+ aTabName.Assign( pOption->GetString() );
+ break;
+ }
+ }
+ }
+ }
+ nTable = ++nMaxTable;
+ bFirstRow = TRUE;
+ nFirstTableCell = pList->Count();
+
+ pLocalColOffset = new ScHTMLColOffset;
+ MakeColNoRef( pLocalColOffset, nColOffsetStart, 0, 0, 0 );
+}
+
+
+void ScHTMLLayoutParser::TableOff( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo );
+ if ( nColCnt > nColCntStart )
+ TableRowOff( pInfo ); // das optionale TableRowOff war nicht
+ if ( !nTableLevel )
+ {
+ DBG_ERROR( "Dummbatz-Dok! </TABLE> ohne oeffnendes <TABLE>" );
+ return ;
+ }
+ if ( --nTableLevel > 0 )
+ { // Table in Table beendet
+ ScHTMLTableStackEntry* pS = aTableStack.Pop();
+ if ( pS )
+ {
+ ScEEParseEntry* pE = pS->pCellEntry;
+ SCROW nRows = nRowCnt - pS->nRowCnt;
+ if ( nRows > 1 )
+ { // Groesse der Tabelle an dieser Position eintragen
+ SCROW nRow = pS->nRowCnt;
+ USHORT nTab = pS->nTable;
+ if ( !pTables )
+ pTables = new Table;
+ // Hoehen der aeusseren Table
+ Table* pTab1 = (Table*) pTables->Get( nTab );
+ if ( !pTab1 )
+ {
+ pTab1 = new Table;
+ pTables->Insert( nTab, pTab1 );
+ }
+ SCROW nRowSpan = pE->nRowOverlap;
+ SCROW nRowKGV;
+ SCROW nRowsPerRow1; // aeussere Table
+ SCROW nRowsPerRow2; // innere Table
+ if ( nRowSpan > 1 )
+ { // KGV auf das sich aussere und innere Zeilen
+ // abbilden lassen
+ nRowKGV = lcl_KGV( nRowSpan, nRows );
+ nRowsPerRow1 = nRowKGV / nRowSpan;
+ nRowsPerRow2 = nRowKGV / nRows;
+ }
+ else
+ {
+ nRowKGV = nRowsPerRow1 = nRows;
+ nRowsPerRow2 = 1;
+ }
+ Table* pTab2 = NULL;
+ if ( nRowsPerRow2 > 1 )
+ { // Hoehen der inneren Table
+ pTab2 = new Table;
+ pTables->Insert( nTable, pTab2 );
+ }
+ // void* Data-Entry der Table-Class fuer das
+ // Hoehen-Mapping missbrauchen
+ if ( nRowKGV > 1 )
+ {
+ if ( nRowsPerRow1 > 1 )
+ { // aussen
+ for ( SCROW j=0; j < nRowSpan; j++ )
+ {
+ ULONG nRowKey = nRow + j;
+ SCROW nR = (SCROW)(ULONG)pTab1->Get( nRowKey );
+ if ( !nR )
+ pTab1->Insert( nRowKey, (void*) nRowsPerRow1 );
+ else if ( nRowsPerRow1 > nR )
+ pTab1->Replace( nRowKey, (void*) nRowsPerRow1 );
+ //2do: wie geht das noch besser?
+ else if ( nRowsPerRow1 < nR && nRowSpan == 1
+ && nTable == nMaxTable )
+ { // Platz uebrig, evtl. besser mergen
+ SCROW nAdd = nRowsPerRow1 - (nR % nRowsPerRow1);
+ nR += nAdd;
+ if ( (nR % nRows) == 0 )
+ { // nur wenn abbildbar
+ SCROW nR2 = (SCROW)(ULONG)pTab1->Get( nRowKey+1 );
+ if ( nR2 > nAdd )
+ { // nur wenn wirklich Platz
+ pTab1->Replace( nRowKey, (void*) nR );
+ pTab1->Replace( nRowKey+1, (void*) (nR2 - nAdd) );
+ nRowsPerRow2 = nR / nRows;
+ }
+ }
+ }
+ }
+ }
+ if ( nRowsPerRow2 > 1 )
+ { // innen
+ if ( !pTab2 )
+ { // nRowsPerRow2 kann erhoeht worden sein
+ pTab2 = new Table;
+ pTables->Insert( nTable, pTab2 );
+ }
+ for ( SCROW j=0; j < nRows; j++ )
+ {
+ ULONG nRowKey = nRow + j;
+ SCROW nR = (SCROW)(ULONG)pTab2->Get( nRowKey );
+ if ( !nR )
+ pTab2->Insert( nRowKey, (void*) nRowsPerRow2 );
+ else if ( nRowsPerRow2 > nR )
+ pTab2->Replace( nRowKey, (void*) nRowsPerRow2 );
+ }
+ }
+ }
+ }
+
+ SetWidths();
+
+ if ( !pE->nWidth )
+ pE->nWidth = nTableWidth;
+ else if ( pE->nWidth < nTableWidth )
+ {
+ USHORT nOldOffset = pE->nOffset + pE->nWidth;
+ USHORT nNewOffset = pE->nOffset + nTableWidth;
+ ModifyOffset( pS->pLocalColOffset, nOldOffset, nNewOffset, nOffsetTolerance );
+ USHORT nTmp = nNewOffset - pE->nOffset - pE->nWidth;
+ pE->nWidth = nNewOffset - pE->nOffset;
+ pS->nTableWidth = pS->nTableWidth + nTmp;
+ if ( pS->nColOffset >= nOldOffset )
+ pS->nColOffset = pS->nColOffset + nTmp;
+ }
+
+ nColCnt = pE->nCol + pE->nColOverlap;
+ nRowCnt = pS->nRowCnt;
+ nColCntStart = pS->nColCntStart;
+ nMaxCol = pS->nMaxCol;
+ nTable = pS->nTable;
+ nTableWidth = pS->nTableWidth;
+ nFirstTableCell = pS->nFirstTableCell;
+ nColOffset = pS->nColOffset;
+ nColOffsetStart = pS->nColOffsetStart;
+ bFirstRow = pS->bFirstRow;
+ xLockedList = pS->xLockedList;
+ if ( pLocalColOffset )
+ delete pLocalColOffset;
+ pLocalColOffset = pS->pLocalColOffset;
+ delete pActEntry;
+ // pActEntry bleibt erstmal erhalten falls da noch 'ne Table in
+ // der gleichen Zelle aufgemacht werden sollte (in HTML ist ja
+ // alles moeglich..) und wird in CloseEntry deleted
+ pActEntry = pE;
+ delete pS;
+ }
+ bTabInTabCell = TRUE;
+ bInCell = TRUE;
+ }
+ else
+ { // einfache Table beendet
+ SetWidths();
+ ScHTMLTableStackEntry* pS = aTableStack.Pop();
+ nMaxCol = 0;
+ nTable = 0;
+ if ( pS )
+ {
+ if ( pLocalColOffset )
+ delete pLocalColOffset;
+ pLocalColOffset = pS->pLocalColOffset;
+ delete pS;
+ }
+ }
+}
+
+
+void ScHTMLLayoutParser::Image( ImportInfo* pInfo )
+{
+ if ( !pActEntry->pImageList )
+ pActEntry->pImageList = new ScHTMLImageList;
+ ScHTMLImageList* pIL = pActEntry->pImageList;
+ ScHTMLImage* pImage = new ScHTMLImage;
+ pIL->Insert( pImage, LIST_APPEND );
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_SRC:
+ {
+ pImage->aURL = INetURLObject::GetAbsURL( aBaseURL, pOption->GetString() );
+ }
+ break;
+ case HTML_O_ALT:
+ {
+ if ( !pActEntry->bHasGraphic )
+ { // ALT text only if not any image loaded
+ if ( pActEntry->aAltText.Len() )
+ pActEntry->aAltText.AppendAscii( "; " );
+ pActEntry->aAltText += pOption->GetString();
+ }
+ }
+ break;
+ case HTML_O_WIDTH:
+ {
+ pImage->aSize.Width() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_HEIGHT:
+ {
+ pImage->aSize.Height() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_HSPACE:
+ {
+ pImage->aSpace.X() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_VSPACE:
+ {
+ pImage->aSpace.Y() = (long)pOption->GetNumber();
+ }
+ break;
+ }
+ }
+ if ( !pImage->aURL.Len() )
+ {
+ DBG_ERRORFILE( "Image: Grafik ohne URL ?!?" );
+ return ;
+ }
+
+ USHORT nFormat;
+ Graphic* pGraphic = new Graphic;
+ GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter();
+ if ( GRFILTER_OK != GraphicFilter::LoadGraphic( pImage->aURL, pImage->aFilterName,
+ *pGraphic, pFilter, &nFormat ) )
+ {
+ delete pGraphic;
+ return ; // dumm gelaufen
+ }
+ if ( !pActEntry->bHasGraphic )
+ { // discard any ALT text in this cell if we have any image
+ pActEntry->bHasGraphic = TRUE;
+ pActEntry->aAltText.Erase();
+ }
+ pImage->aFilterName = pFilter->GetImportFormatName( nFormat );
+ pImage->pGraphic = pGraphic;
+ if ( !(pImage->aSize.Width() && pImage->aSize.Height()) )
+ {
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ pImage->aSize = pDefaultDev->LogicToPixel( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode() );
+ }
+ if ( pIL->Count() > 0 )
+ {
+ long nWidth = 0;
+ for ( ScHTMLImage* pI = pIL->First(); pI; pI = pIL->Next() )
+ {
+ if ( pI->nDir & nHorizontal )
+ nWidth += pI->aSize.Width() + 2 * pI->aSpace.X();
+ else
+ nWidth = 0;
+ }
+ if ( pActEntry->nWidth
+ && (nWidth + pImage->aSize.Width() + 2 * pImage->aSpace.X()
+ >= pActEntry->nWidth) )
+ pIL->Last()->nDir = nVertical;
+ }
+}
+
+
+void ScHTMLLayoutParser::ColOn( ImportInfo* pInfo )
+{
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_WIDTH:
+ {
+ USHORT nVal = GetWidthPixel( pOption );
+ MakeCol( pLocalColOffset, nColOffset, nVal, 0, 0 );
+ nColOffset = nColOffset + nVal;
+ }
+ break;
+ }
+ }
+}
+
+
+USHORT ScHTMLLayoutParser::GetWidthPixel( const HTMLOption* pOption )
+{
+ const String& rOptVal = pOption->GetString();
+ if ( rOptVal.Search('%') != STRING_NOTFOUND )
+ { // Prozent
+ USHORT nW = (nTableWidth ? nTableWidth : (USHORT) aPageSize.Width());
+ return (USHORT)((pOption->GetNumber() * nW) / 100);
+ }
+ else
+ {
+ if ( rOptVal.Search('*') != STRING_NOTFOUND )
+ { // relativ zu was?!?
+//2do: ColArray aller relativen Werte sammeln und dann MakeCol
+ return 0;
+ }
+ else
+ return (USHORT)pOption->GetNumber(); // Pixel
+ }
+}
+
+
+void ScHTMLLayoutParser::AnchorOn( ImportInfo* pInfo )
+{
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ {
+ pActEntry->pName = new String( pOption->GetString() );
+ }
+ break;
+ }
+ }
+}
+
+
+BOOL ScHTMLLayoutParser::IsAtBeginningOfText( ImportInfo* pInfo )
+{
+ ESelection& rSel = pActEntry->aSel;
+ return rSel.nStartPara == rSel.nEndPara &&
+ rSel.nStartPara <= pInfo->aSelection.nEndPara &&
+ pEdit->GetTextLen( rSel.nStartPara ) == 0;
+}
+
+
+void ScHTMLLayoutParser::FontOn( ImportInfo* pInfo )
+{
+ if ( IsAtBeginningOfText( pInfo ) )
+ { // nur am Anfang des Textes, gilt dann fuer gesamte Zelle
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ USHORT nArrLen = pOptions->Count();
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_FACE :
+ {
+ const String& rFace = pOption->GetString();
+ String aFontName;
+ xub_StrLen nPos = 0;
+ while( nPos != STRING_NOTFOUND )
+ { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
+ String aFName = rFace.GetToken( 0, ',', nPos );
+ aFName.EraseTrailingChars().EraseLeadingChars();
+ if( aFontName.Len() )
+ aFontName += ';';
+ aFontName += aFName;
+ }
+ if ( aFontName.Len() )
+ pActEntry->aItemSet.Put( SvxFontItem( FAMILY_DONTKNOW,
+ aFontName, EMPTY_STRING, PITCH_DONTKNOW,
+ RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+ }
+ break;
+ case HTML_O_SIZE :
+ {
+ USHORT nSize = (USHORT) pOption->GetNumber();
+ if ( nSize == 0 )
+ nSize = 1;
+ else if ( nSize > SC_HTML_FONTSIZES )
+ nSize = SC_HTML_FONTSIZES;
+ pActEntry->aItemSet.Put( SvxFontHeightItem(
+ maFontHeights[nSize-1], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_O_COLOR :
+ {
+ Color aColor;
+ pOption->GetColor( aColor );
+ pActEntry->aItemSet.Put( SvxColorItem( aColor, ATTR_FONT_COLOR ) );
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+void ScHTMLLayoutParser::ProcToken( ImportInfo* pInfo )
+{
+ BOOL bSetLastToken = TRUE;
+ switch ( pInfo->nToken )
+ {
+ case HTML_META:
+ {
+ HTMLParser* pParser = (HTMLParser*) pInfo->pParser;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ pParser->ParseMetaOptions(
+ xDPS->getDocumentProperties(),
+ mpDoc->GetDocumentShell()->GetHeaderAttributes() );
+ }
+ break;
+ case HTML_TITLE_ON:
+ {
+ bInTitle = TRUE;
+ aString.Erase();
+ }
+ break;
+ case HTML_TITLE_OFF:
+ {
+ if ( bInTitle && aString.Len() )
+ {
+ // Leerzeichen von Zeilenumbruechen raus
+ aString.EraseLeadingChars();
+ aString.EraseTrailingChars();
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(),
+ uno::UNO_QUERY_THROW);
+ xDPS->getDocumentProperties()->setTitle(aString);
+ }
+ bInTitle = FALSE;
+ }
+ break;
+ case HTML_TABLE_ON:
+ {
+ TableOn( pInfo );
+ }
+ break;
+ case HTML_COL_ON:
+ {
+ ColOn( pInfo );
+ }
+ break;
+ case HTML_TABLEHEADER_ON: // oeffnet Zelle
+ {
+ if ( bInCell )
+ CloseEntry( pInfo );
+ // bInCell nicht TRUE setzen, das macht TableDataOn
+ pActEntry->aItemSet.Put(
+ SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT) );
+ } // fall thru
+ case HTML_TABLEDATA_ON: // oeffnet Zelle
+ {
+ TableDataOn( pInfo );
+ }
+ break;
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF: // schliesst Zelle
+ {
+ TableDataOff( pInfo );
+ }
+ break;
+ case HTML_TABLEROW_ON: // vor erster Zelle in Row
+ {
+ TableRowOn( pInfo );
+ }
+ break;
+ case HTML_TABLEROW_OFF: // nach letzter Zelle in Row
+ {
+ TableRowOff( pInfo );
+ }
+ break;
+ case HTML_TABLE_OFF:
+ {
+ TableOff( pInfo );
+ }
+ break;
+ case HTML_IMAGE:
+ {
+ Image( pInfo );
+ }
+ break;
+ case HTML_PARABREAK_OFF:
+ { // nach einem Image geht es vertikal weiter
+ if ( pActEntry->pImageList && pActEntry->pImageList->Count() > 0 )
+ pActEntry->pImageList->Last()->nDir = nVertical;
+ }
+ break;
+ case HTML_ANCHOR_ON:
+ {
+ AnchorOn( pInfo );
+ }
+ break;
+ case HTML_FONT_ON :
+ {
+ FontOn( pInfo );
+ }
+ break;
+ case HTML_BIGPRINT_ON :
+ {
+//2do: aktuelle Fontgroesse merken und einen groesser
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxFontHeightItem(
+ maFontHeights[3], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_SMALLPRINT_ON :
+ {
+//2do: aktuelle Fontgroesse merken und einen kleiner
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxFontHeightItem(
+ maFontHeights[0], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_BOLD_ON :
+ case HTML_STRONG_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxWeightItem( WEIGHT_BOLD,
+ ATTR_FONT_WEIGHT ) );
+ }
+ break;
+ case HTML_ITALIC_ON :
+ case HTML_EMPHASIS_ON :
+ case HTML_ADDRESS_ON :
+ case HTML_BLOCKQUOTE_ON :
+ case HTML_BLOCKQUOTE30_ON :
+ case HTML_CITIATION_ON :
+ case HTML_VARIABLE_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxPostureItem( ITALIC_NORMAL,
+ ATTR_FONT_POSTURE ) );
+ }
+ break;
+ case HTML_DEFINSTANCE_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ {
+ pActEntry->aItemSet.Put( SvxWeightItem( WEIGHT_BOLD,
+ ATTR_FONT_WEIGHT ) );
+ pActEntry->aItemSet.Put( SvxPostureItem( ITALIC_NORMAL,
+ ATTR_FONT_POSTURE ) );
+ }
+ }
+ break;
+ case HTML_UNDERLINE_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE,
+ ATTR_FONT_UNDERLINE ) );
+ }
+ break;
+ case HTML_TEXTTOKEN:
+ {
+ if ( bInTitle )
+ aString += pInfo->aText;
+ }
+ break;
+ default:
+ { // nLastToken nicht setzen!
+ bSetLastToken = FALSE;
+ }
+ }
+ if ( bSetLastToken )
+ nLastToken = pInfo->nToken;
+}
+
+
+
+// ============================================================================
+// HTML DATA QUERY PARSER
+// ============================================================================
+
+template< typename Type >
+inline Type getLimitedValue( const Type& rValue, const Type& rMin, const Type& rMax )
+{ return ::std::max( ::std::min( rValue, rMax ), rMin ); }
+
+// ============================================================================
+
+/** Iterates through all HTML tag options of the passed ImportInfo struct. */
+class ScHTMLOptionIterator
+{
+private:
+ const HTMLOptions* mpOptions; /// The options array.
+ const HTMLOption* mpCurrOption; /// Current option.
+ sal_uInt16 mnCount; /// Size of the options array.
+ sal_uInt16 mnIndex; /// Next option to return.
+
+public:
+ explicit ScHTMLOptionIterator( const ImportInfo& rInfo );
+
+ inline bool is() const { return mnIndex < mnCount; }
+ inline const HTMLOption* operator->() const { return mpCurrOption; }
+ inline const HTMLOption& operator*() const { return *mpCurrOption; }
+ ScHTMLOptionIterator& operator++();
+};
+
+// ----------------------------------------------------------------------------
+
+ScHTMLOptionIterator::ScHTMLOptionIterator( const ImportInfo& rInfo ) :
+ mpOptions( 0 ),
+ mpCurrOption( 0 ),
+ mnCount( 0 ),
+ mnIndex( 0 )
+{
+ const HTMLParser* pParser = static_cast< const HTMLParser* >( rInfo.pParser );
+ if( pParser )
+ mpOptions = pParser->GetOptions();
+ if( mpOptions )
+ mnCount = mpOptions->Count();
+ if( mnCount )
+ mpCurrOption = mpOptions->GetObject( 0 );
+}
+
+ScHTMLOptionIterator& ScHTMLOptionIterator::operator++()
+{
+ if( mnIndex < mnCount ) ++mnIndex;
+ mpCurrOption = (mnIndex < mnCount) ? mpOptions->GetObject( mnIndex ) : 0;
+ return *this;
+}
+
+// ============================================================================
+
+ScHTMLEntry::ScHTMLEntry( const SfxItemSet& rItemSet, ScHTMLTableId nTableId ) :
+ ScEEParseEntry( rItemSet ),
+ mbImportAlways( false )
+{
+ nTab = nTableId;
+ bEntirePara = false;
+}
+
+bool ScHTMLEntry::HasContents() const
+{
+ return mbImportAlways || aSel.HasRange() || aAltText.Len() || IsTable();
+}
+
+void ScHTMLEntry::AdjustStart( const ImportInfo& rInfo )
+{
+ // set start position
+ aSel.nStartPara = rInfo.aSelection.nStartPara;
+ aSel.nStartPos = rInfo.aSelection.nStartPos;
+ // adjust end position
+ if( (aSel.nEndPara < aSel.nStartPara) || ((aSel.nEndPara == aSel.nStartPara) && (aSel.nEndPos < aSel.nStartPos)) )
+ {
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos;
+ }
+}
+
+void ScHTMLEntry::AdjustEnd( const ImportInfo& rInfo )
+{
+ DBG_ASSERT( (aSel.nEndPara < rInfo.aSelection.nEndPara) ||
+ ((aSel.nEndPara == rInfo.aSelection.nEndPara) && (aSel.nEndPos <= rInfo.aSelection.nEndPos)),
+ "ScHTMLQueryParser::AdjustEntryEnd - invalid end position" );
+ // set end position
+ aSel.nEndPara = rInfo.aSelection.nEndPara;
+ aSel.nEndPos = rInfo.aSelection.nEndPos;
+}
+
+void ScHTMLEntry::Strip( const EditEngine& rEditEngine )
+{
+ // strip leading empty paragraphs
+ while( (aSel.nStartPara < aSel.nEndPara) && (rEditEngine.GetTextLen( aSel.nStartPara ) <= aSel.nStartPos) )
+ {
+ ++aSel.nStartPara;
+ aSel.nStartPos = 0;
+ }
+ // strip trailing empty paragraphs
+ while( (aSel.nStartPara < aSel.nEndPara) && (aSel.nEndPos == 0) )
+ {
+ --aSel.nEndPara;
+ aSel.nEndPos = rEditEngine.GetTextLen( aSel.nEndPara );
+ }
+}
+
+// ============================================================================
+
+/** A map of ScHTMLTable objects.
+
+ Organizes the tables with a unique table key. Stores nested tables inside
+ the parent table and forms in this way a tree structure of tables. An
+ instance of this class ownes the contained table objects and deletes them
+ on destruction.
+ */
+class ScHTMLTableMap
+{
+private:
+ typedef ::boost::shared_ptr< ScHTMLTable > ScHTMLTablePtr;
+ typedef ::std::map< ScHTMLTableId, ScHTMLTablePtr > ScHTMLTableStdMap;
+
+public:
+ typedef ScHTMLTableStdMap::iterator iterator;
+ typedef ScHTMLTableStdMap::const_iterator const_iterator;
+
+private:
+ ScHTMLTable& mrParentTable; /// Reference to parent table.
+ ScHTMLTableStdMap maTables; /// Container for all table objects.
+ mutable ScHTMLTable* mpCurrTable; /// Current table, used for fast search.
+
+public:
+ explicit ScHTMLTableMap( ScHTMLTable& rParentTable );
+ virtual ~ScHTMLTableMap();
+
+ inline iterator begin() { return maTables.begin(); }
+ inline const_iterator begin() const { return maTables.begin(); }
+ inline iterator end() { return maTables.end(); }
+ inline const_iterator end() const { return maTables.end(); }
+ inline bool empty() const { return maTables.empty(); }
+
+ /** Returns the specified table.
+ @param nTableId Unique identifier of the table.
+ @param bDeep true = searches deep in all nested table; false = only in this container. */
+ ScHTMLTable* FindTable( ScHTMLTableId nTableId, bool bDeep = true ) const;
+
+ /** Inserts a new table into the container. This container owns the created table.
+ @param bPreFormText true = New table is based on preformatted text (<pre> tag). */
+ ScHTMLTable* CreateTable( const ImportInfo& rInfo, bool bPreFormText );
+
+private:
+ /** Sets a working table with its index for search optimization. */
+ inline void SetCurrTable( ScHTMLTable* pTable ) const
+ { if( pTable ) mpCurrTable = pTable; }
+};
+
+// ----------------------------------------------------------------------------
+
+ScHTMLTableMap::ScHTMLTableMap( ScHTMLTable& rParentTable ) :
+ mrParentTable( rParentTable )
+{
+}
+
+ScHTMLTableMap::~ScHTMLTableMap()
+{
+}
+
+ScHTMLTable* ScHTMLTableMap::FindTable( ScHTMLTableId nTableId, bool bDeep ) const
+{
+ ScHTMLTable* pResult = 0;
+ if( mpCurrTable && (nTableId == mpCurrTable->GetTableId()) )
+ pResult = mpCurrTable; // cached table
+ else
+ {
+ const_iterator aFind = maTables.find( nTableId );
+ if( aFind != maTables.end() )
+ pResult = aFind->second.get(); // table from this container
+ }
+
+ // not found -> search deep in nested tables
+ if( !pResult && bDeep )
+ for( const_iterator aIter = begin(), aEnd = end(); !pResult && (aIter != aEnd); ++aIter )
+ pResult = aIter->second->FindNestedTable( nTableId );
+
+ SetCurrTable( pResult );
+ return pResult;
+}
+
+ScHTMLTable* ScHTMLTableMap::CreateTable( const ImportInfo& rInfo, bool bPreFormText )
+{
+ ScHTMLTable* pTable = new ScHTMLTable( mrParentTable, rInfo, bPreFormText );
+ maTables[ pTable->GetTableId() ].reset( pTable );
+ SetCurrTable( pTable );
+ return pTable;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Simplified forward iterator for convenience.
+
+ Before the iterator can be dereferenced, it must be tested with the is()
+ method. The iterator may be invalid directly after construction (e.g. empty
+ container).
+ */
+class ScHTMLTableIterator
+{
+public:
+ /** Constructs the iterator for the passed table map.
+ @param pTableMap Pointer to the table map (is allowed to be NULL). */
+ explicit ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
+
+ inline bool is() const { return 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 )
+{
+ if( pTableMap )
+ {
+ maIter = pTableMap->begin();
+ maEnd = pTableMap->end();
+ }
+}
+
+// ============================================================================
+
+ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
+ mnTableId( rnUnusedId ),
+ mrnUnusedId( rnUnusedId )
+{
+ ++mrnUnusedId;
+}
+
+// ----------------------------------------------------------------------------
+
+ScHTMLTable::ScHTMLTable( ScHTMLTable& rParentTable, const ImportInfo& rInfo, bool bPreFormText ) :
+ mpParentTable( &rParentTable ),
+ maTableId( rParentTable.maTableId.mrnUnusedId ),
+ maTableItemSet( rParentTable.GetCurrItemSet() ),
+ mrEditEngine( rParentTable.mrEditEngine ),
+ mrEEParseList( rParentTable.mrEEParseList ),
+ mpCurrEntryList( 0 ),
+ maSize( 1, 1 ),
+ mbBorderOn( false ),
+ mbPreFormText( bPreFormText ),
+ mbRowOn( false ),
+ mbDataOn( false ),
+ mbPushEmptyLine( false )
+{
+ if( mbPreFormText )
+ {
+ ImplRowOn();
+ ImplDataOn( ScHTMLSize( 1, 1 ) );
+ }
+ else
+ {
+ ProcessFormatOptions( maTableItemSet, rInfo );
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_BORDER:
+ mbBorderOn = ((aIter->GetString().Len() == 0) || (aIter->GetNumber() != 0));
+ break;
+ case HTML_O_ID:
+ maTableName = aIter->GetString();
+ break;
+ }
+ }
+ }
+
+ CreateNewEntry( rInfo );
+}
+
+ScHTMLTable::ScHTMLTable( SfxItemPool& rPool, EditEngine& rEditEngine, ScEEParseList& rEEParseList, ScHTMLTableId& rnUnusedId ) :
+ mpParentTable( 0 ),
+ maTableId( rnUnusedId ),
+ maTableItemSet( rPool ),
+ mrEditEngine( rEditEngine ),
+ mrEEParseList( rEEParseList ),
+ mpCurrEntryList( 0 ),
+ maSize( 1, 1 ),
+ mbBorderOn( false ),
+ mbPreFormText( false ),
+ mbRowOn( false ),
+ mbDataOn( false ),
+ mbPushEmptyLine( false )
+{
+ // open the first "cell" of the document
+ ImplRowOn();
+ ImplDataOn( ScHTMLSize( 1, 1 ) );
+ mxCurrEntry = CreateEntry();
+}
+
+ScHTMLTable::~ScHTMLTable()
+{
+}
+
+const SfxItemSet& ScHTMLTable::GetCurrItemSet() const
+{
+ // first try cell item set, then row item set, then table item set
+ return mxDataItemSet.get() ? *mxDataItemSet : (mxRowItemSet.get() ? *mxRowItemSet : maTableItemSet);
+}
+
+ScHTMLSize ScHTMLTable::GetSpan( const ScHTMLPos& rCellPos ) const
+{
+ ScHTMLSize aSpan( 1, 1 );
+ 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 mxNestedTables.get() ? mxNestedTables->FindTable( nTableId, true ) : 0;
+}
+
+void ScHTMLTable::PutItem( const SfxPoolItem& rItem )
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutItem - no current entry" );
+ if( mxCurrEntry.get() && mxCurrEntry->IsEmpty() )
+ mxCurrEntry->GetItemSet().Put( rItem );
+}
+
+void ScHTMLTable::PutText( const ImportInfo& rInfo )
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
+ if( mxCurrEntry.get() )
+ {
+ if( !mxCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
+ mxCurrEntry->AdjustStart( rInfo );
+ else
+ mxCurrEntry->AdjustEnd( rInfo );
+ }
+}
+
+void ScHTMLTable::InsertPara( const ImportInfo& rInfo )
+{
+ if( mxCurrEntry.get() && mbDataOn && !IsEmptyCell() )
+ mxCurrEntry->SetImportAlways();
+ PushEntry( rInfo );
+ CreateNewEntry( rInfo );
+ InsertLeadingEmptyLine();
+}
+
+void ScHTMLTable::BreakOn()
+{
+ // empty line, if <br> is at start of cell
+ mbPushEmptyLine = !mbPreFormText && mbDataOn && IsEmptyCell();
+}
+
+void ScHTMLTable::HeadingOn()
+{
+ // call directly, InsertPara() has not been called before
+ InsertLeadingEmptyLine();
+}
+
+void ScHTMLTable::InsertLeadingEmptyLine()
+{
+ // empty line, if <p>, </p>, <h?>, or </h*> are not at start of cell
+ mbPushEmptyLine = !mbPreFormText && mbDataOn && !IsEmptyCell();
+}
+
+void ScHTMLTable::AnchorOn()
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
+ // don't skip entries with single hyperlinks
+ if( mxCurrEntry.get() )
+ mxCurrEntry->SetImportAlways();
+}
+
+ScHTMLTable* ScHTMLTable::TableOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo );
+ return InsertNestedTable( rInfo, false );
+}
+
+ScHTMLTable* ScHTMLTable::TableOff( const ImportInfo& rInfo )
+{
+ return mbPreFormText ? this : CloseTable( rInfo );
+}
+
+ScHTMLTable* ScHTMLTable::PreOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo );
+ return InsertNestedTable( rInfo, true );
+}
+
+ScHTMLTable* ScHTMLTable::PreOff( const ImportInfo& rInfo )
+{
+ return mbPreFormText ? CloseTable( rInfo ) : this;
+}
+
+void ScHTMLTable::RowOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no rows allowed in global and preformatted tables
+ {
+ ImplRowOn();
+ ProcessFormatOptions( *mxRowItemSet, rInfo );
+ }
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::RowOff( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no rows allowed in global and preformatted tables
+ ImplRowOff();
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::DataOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no cells allowed in global and preformatted tables
+ {
+ // read needed options from the <td> tag
+ ScHTMLSize aSpanSize( 1, 1 );
+ ::std::auto_ptr< String > pValStr, pNumStr;
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_COLSPAN:
+ aSpanSize.mnCols = static_cast< SCCOL >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
+ break;
+ case HTML_O_ROWSPAN:
+ aSpanSize.mnRows = static_cast< SCROW >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
+ break;
+ case HTML_O_SDVAL:
+ pValStr.reset( new String( aIter->GetString() ) );
+ break;
+ case HTML_O_SDNUM:
+ pNumStr.reset( new String( aIter->GetString() ) );
+ break;
+ }
+ }
+
+ ImplDataOn( aSpanSize );
+ ProcessFormatOptions( *mxDataItemSet, rInfo );
+ CreateNewEntry( rInfo );
+ mxCurrEntry->pValStr = pValStr.release();
+ mxCurrEntry->pNumStr = pNumStr.release();
+ }
+ else
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::DataOff( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no cells allowed in global and preformatted tables
+ ImplDataOff();
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::BodyOn( const ImportInfo& rInfo )
+{
+ bool bPushed = PushEntry( rInfo );
+ if( !mpParentTable )
+ {
+ // #108269# do not start new row, if nothing (no title) precedes the body.
+ if( bPushed || !mbRowOn )
+ ImplRowOn();
+ if( bPushed || !mbDataOn )
+ ImplDataOn( ScHTMLSize( 1, 1 ) );
+ ProcessFormatOptions( *mxDataItemSet, rInfo );
+ }
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::BodyOff( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo );
+ if( !mpParentTable )
+ {
+ ImplDataOff();
+ ImplRowOff();
+ }
+ CreateNewEntry( rInfo );
+}
+
+ScHTMLTable* ScHTMLTable::CloseTable( const ImportInfo& rInfo )
+{
+ if( mpParentTable ) // not allowed to close global table
+ {
+ PushEntry( rInfo, mbDataOn );
+ ImplDataOff();
+ ImplRowOff();
+ mpParentTable->PushTableEntry( GetTableId() );
+ mpParentTable->CreateNewEntry( rInfo );
+ if( mbPreFormText ) // enclose preformatted table with empty lines in parent table
+ mpParentTable->InsertLeadingEmptyLine();
+ return mpParentTable;
+ }
+ return this;
+}
+
+SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
+{
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ size_t nIndex = static_cast< size_t >( nCellPos );
+ if( nIndex >= rSizes.size() ) return 0;
+ return (nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]);
+}
+
+SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const
+{
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ size_t nBeginIdx = static_cast< size_t >( ::std::max< SCCOLROW >( nCellBegin, 0 ) );
+ size_t nEndIdx = static_cast< size_t >( ::std::min< SCCOLROW >( nCellEnd, static_cast< SCCOLROW >( rSizes.size() ) ) );
+ if (nBeginIdx >= nEndIdx ) return 0;
+ return rSizes[ nEndIdx - 1 ] - ((nBeginIdx == 0) ? 0 : rSizes[ nBeginIdx - 1 ]);
+}
+
+SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient ) const
+{
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ return rSizes.empty() ? 0 : rSizes.back();
+}
+
+ScHTMLSize ScHTMLTable::GetDocSize( const ScHTMLPos& rCellPos ) const
+{
+ ScHTMLSize aCellSpan = GetSpan( rCellPos );
+ return ScHTMLSize(
+ static_cast< SCCOL >( GetDocSize( tdCol, rCellPos.mnCol, rCellPos.mnCol + aCellSpan.mnCols ) ),
+ static_cast< SCROW >( GetDocSize( tdRow, rCellPos.mnRow, rCellPos.mnRow + aCellSpan.mnRows ) ) );
+}
+
+SCCOLROW ScHTMLTable::GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
+{
+ return maDocBasePos.Get( eOrient ) + GetDocSize( eOrient, 0, nCellPos );
+}
+
+ScHTMLPos ScHTMLTable::GetDocPos( const ScHTMLPos& rCellPos ) const
+{
+ return ScHTMLPos(
+ static_cast< SCCOL >( GetDocPos( tdCol, rCellPos.mnCol ) ),
+ static_cast< SCROW >( GetDocPos( tdRow, rCellPos.mnRow ) ) );
+}
+
+void ScHTMLTable::GetDocRange( ScRange& rRange ) const
+{
+ rRange.aStart = rRange.aEnd = maDocBasePos.MakeAddr();
+ rRange.aEnd.Move( static_cast< SCsCOL >( GetDocSize( tdCol ) ) - 1, static_cast< SCsROW >( GetDocSize( tdRow ) ) - 1, 0 );
+}
+
+void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const
+{
+ DBG_ASSERT( pDoc, "ScHTMLTable::ApplyCellBorders - no document" );
+ if( pDoc && mbBorderOn )
+ {
+ const SCCOL nLastCol = maSize.mnCols - 1;
+ const SCROW nLastRow = maSize.mnRows - 1;
+ const sal_uInt16 nOuterLine = DEF_LINE_WIDTH_2;
+ const sal_uInt16 nInnerLine = DEF_LINE_WIDTH_0;
+ SvxBorderLine aOuterLine, aInnerLine;
+ aOuterLine.SetColor( Color( COL_BLACK ) );
+ aOuterLine.SetOutWidth( nOuterLine );
+ aInnerLine.SetColor( Color( COL_BLACK ) );
+ aInnerLine.SetOutWidth( nInnerLine );
+ SvxBoxItem aBorderItem( ATTR_BORDER );
+
+ for( SCCOL nCol = 0; nCol <= nLastCol; ++nCol )
+ {
+ SvxBorderLine* pLeftLine = (nCol == 0) ? &aOuterLine : &aInnerLine;
+ SvxBorderLine* pRightLine = (nCol == nLastCol) ? &aOuterLine : &aInnerLine;
+ SCCOL nCellCol1 = static_cast< SCCOL >( GetDocPos( tdCol, nCol ) ) + rFirstPos.Col();
+ SCCOL nCellCol2 = nCellCol1 + static_cast< SCCOL >( GetDocSize( tdCol, nCol ) ) - 1;
+ for( SCROW nRow = 0; nRow <= nLastRow; ++nRow )
+ {
+ SvxBorderLine* pTopLine = (nRow == 0) ? &aOuterLine : &aInnerLine;
+ SvxBorderLine* pBottomLine = (nRow == nLastRow) ? &aOuterLine : &aInnerLine;
+ SCROW nCellRow1 = GetDocPos( tdRow, nRow ) + rFirstPos.Row();
+ SCROW nCellRow2 = nCellRow1 + GetDocSize( tdRow, nRow ) - 1;
+ for( SCCOL nCellCol = nCellCol1; nCellCol <= nCellCol2; ++nCellCol )
+ {
+ aBorderItem.SetLine( (nCellCol == nCellCol1) ? pLeftLine : 0, BOX_LINE_LEFT );
+ aBorderItem.SetLine( (nCellCol == nCellCol2) ? pRightLine : 0, BOX_LINE_RIGHT );
+ for( SCROW nCellRow = nCellRow1; nCellRow <= nCellRow2; ++nCellRow )
+ {
+ aBorderItem.SetLine( (nCellRow == nCellRow1) ? pTopLine : 0, BOX_LINE_TOP );
+ aBorderItem.SetLine( (nCellRow == nCellRow2) ? pBottomLine : 0, BOX_LINE_BOTTOM );
+ pDoc->ApplyAttr( nCellCol, nCellRow, rFirstPos.Tab(), aBorderItem );
+ }
+ }
+ }
+ }
+ }
+
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
+ aIter->ApplyCellBorders( pDoc, rFirstPos );
+}
+
+// ----------------------------------------------------------------------------
+
+bool ScHTMLTable::IsEmptyCell() const
+{
+ return mpCurrEntryList && mpCurrEntryList->empty();
+}
+
+bool ScHTMLTable::IsSpaceCharInfo( const ImportInfo& rInfo )
+{
+ return (rInfo.nToken == HTML_TEXTTOKEN) && (rInfo.aText.Len() == 1) && (rInfo.aText.GetChar( 0 ) == ' ');
+}
+
+ScHTMLTable::ScHTMLEntryPtr ScHTMLTable::CreateEntry() const
+{
+ return ScHTMLEntryPtr( new ScHTMLEntry( GetCurrItemSet() ) );
+}
+
+void ScHTMLTable::CreateNewEntry( const ImportInfo& rInfo )
+{
+ DBG_ASSERT( !mxCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
+ mxCurrEntry = CreateEntry();
+ mxCurrEntry->aSel = rInfo.aSelection;
+}
+
+void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry )
+{
+ // HTML entry list does not own the entries
+ rEntryList.push_back( rxEntry.get() );
+ // mrEEParseList (reference to member of ScEEParser) owns the entries
+ mrEEParseList.Insert( rxEntry.release(), LIST_APPEND );
+}
+
+bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rxEntry )
+{
+ bool bPushed = false;
+ if( rxEntry.get() && rxEntry->HasContents() )
+ {
+ if( mpCurrEntryList )
+ {
+ if( mbPushEmptyLine )
+ {
+ ScHTMLEntryPtr xEmptyEntry = CreateEntry();
+ ImplPushEntryToList( *mpCurrEntryList, xEmptyEntry );
+ mbPushEmptyLine = false;
+ }
+ ImplPushEntryToList( *mpCurrEntryList, rxEntry );
+ bPushed = true;
+ }
+ else if( mpParentTable )
+ {
+ bPushed = mpParentTable->PushEntry( rxEntry );
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScHTMLTable::PushEntry - cannot push entry, no parent found" );
+ }
+ }
+ return bPushed;
+}
+
+bool ScHTMLTable::PushEntry( const ImportInfo& rInfo, bool bLastInCell )
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
+ bool bPushed = false;
+ if( mxCurrEntry.get() )
+ {
+ mxCurrEntry->AdjustEnd( rInfo );
+ mxCurrEntry->Strip( mrEditEngine );
+
+ // import entry always, if it is the last in cell, and cell is still empty
+ if( bLastInCell && IsEmptyCell() )
+ {
+ mxCurrEntry->SetImportAlways();
+ // don't insert empty lines before single empty entries
+ if( mxCurrEntry->IsEmpty() )
+ mbPushEmptyLine = false;
+ }
+
+ bPushed = PushEntry( mxCurrEntry );
+ mxCurrEntry.reset();
+ }
+ return bPushed;
+}
+
+bool ScHTMLTable::PushTableEntry( ScHTMLTableId nTableId )
+{
+ DBG_ASSERT( nTableId != SC_HTML_GLOBAL_TABLE, "ScHTMLTable::PushTableEntry - cannot push global table" );
+ bool bPushed = false;
+ if( nTableId != SC_HTML_GLOBAL_TABLE )
+ {
+ ScHTMLEntryPtr xEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
+ bPushed = PushEntry( xEntry );
+ }
+ return bPushed;
+}
+
+ScHTMLTable* ScHTMLTable::GetExistingTable( ScHTMLTableId nTableId ) const
+{
+ ScHTMLTable* pTable = ((nTableId != SC_HTML_GLOBAL_TABLE) && mxNestedTables.get()) ?
+ mxNestedTables->FindTable( nTableId, false ) : 0;
+ DBG_ASSERT( pTable || (nTableId == SC_HTML_GLOBAL_TABLE), "ScHTMLTable::GetExistingTable - table not found" );
+ return pTable;
+}
+
+ScHTMLTable* ScHTMLTable::InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText )
+{
+ if( !mxNestedTables.get() )
+ mxNestedTables.reset( new ScHTMLTableMap( *this ) );
+ if( bPreFormText ) // enclose new preformatted table with empty lines
+ InsertLeadingEmptyLine();
+ return mxNestedTables->CreateTable( rInfo, bPreFormText );
+}
+
+void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
+{
+ ScRange* pRange;
+
+ /* Find an unused cell by skipping all merged ranges that cover the
+ current cell position stored in maCurrCell. */
+ while( ((pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0) || ((pRange = maHMergedCells.Find( maCurrCell.MakeAddr() )) != 0) )
+ maCurrCell.mnCol = pRange->aEnd.Col() + 1;
+ mpCurrEntryList = &maEntryMap[ maCurrCell ];
+
+ /* If the new cell is merged horizontally, try to find collisions with
+ other vertically merged ranges. In this case, shrink existing
+ vertically merged ranges (do not shrink the new cell). */
+ SCCOL nColEnd = maCurrCell.mnCol + rSpanSize.mnCols;
+ for( ScAddress aAddr( maCurrCell.MakeAddr() ); aAddr.Col() < nColEnd; aAddr.IncCol() )
+ if( (pRange = maVMergedCells.Find( aAddr )) != 0 )
+ pRange->aEnd.SetRow( maCurrCell.mnRow - 1 );
+
+ // insert the new range into the cell lists
+ ScRange aNewRange( maCurrCell.MakeAddr() );
+ aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 );
+ if( rSpanSize.mnRows > 1 )
+ {
+ maVMergedCells.Append( aNewRange );
+ /* Do not insert vertically merged ranges into maUsedCells yet,
+ because they may be shrunken (see above). The final vertically
+ merged ranges are inserted in FillEmptyCells(). */
+ }
+ else
+ {
+ if( rSpanSize.mnCols > 1 )
+ maHMergedCells.Append( aNewRange );
+ /* Insert horizontally merged ranges and single cells into
+ maUsedCells, they will not be changed anymore. */
+ maUsedCells.Join( aNewRange );
+ }
+
+ // adjust table size
+ maSize.mnCols = ::std::max< SCCOL >( maSize.mnCols, aNewRange.aEnd.Col() + 1 );
+ maSize.mnRows = ::std::max< SCROW >( maSize.mnRows, aNewRange.aEnd.Row() + 1 );
+}
+
+void ScHTMLTable::ImplRowOn()
+{
+ if( mbRowOn )
+ ImplRowOff();
+ mxRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
+ maCurrCell.mnCol = 0;
+ mbRowOn = true;
+ mbDataOn = false;
+}
+
+void ScHTMLTable::ImplRowOff()
+{
+ if( mbDataOn )
+ ImplDataOff();
+ if( mbRowOn )
+ {
+ mxRowItemSet.reset();
+ ++maCurrCell.mnRow;
+ mbRowOn = mbDataOn = false;
+ }
+}
+
+void ScHTMLTable::ImplDataOn( const ScHTMLSize& rSpanSize )
+{
+ if( mbDataOn )
+ ImplDataOff();
+ if( !mbRowOn )
+ ImplRowOn();
+ mxDataItemSet.reset( new SfxItemSet( *mxRowItemSet ) );
+ InsertNewCell( rSpanSize );
+ mbDataOn = true;
+ mbPushEmptyLine = false;
+}
+
+void ScHTMLTable::ImplDataOff()
+{
+ if( mbDataOn )
+ {
+ mxDataItemSet.reset();
+ ++maCurrCell.mnCol;
+ mpCurrEntryList = 0;
+ mbDataOn = false;
+ }
+}
+
+void ScHTMLTable::ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo )
+{
+ // special handling for table header cells
+ if( rInfo.nToken == HTML_TABLEHEADER_ON )
+ {
+ rItemSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+ }
+
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_ALIGN:
+ {
+ SvxCellHorJustify eVal = SVX_HOR_JUSTIFY_STANDARD;
+ const String& rOptVal = aIter->GetString();
+ if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) )
+ eVal = SVX_HOR_JUSTIFY_RIGHT;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) )
+ eVal = SVX_HOR_JUSTIFY_CENTER;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) )
+ eVal = SVX_HOR_JUSTIFY_LEFT;
+ if( eVal != SVX_HOR_JUSTIFY_STANDARD )
+ rItemSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY ) );
+ }
+ break;
+
+ case HTML_O_VALIGN:
+ {
+ SvxCellVerJustify eVal = SVX_VER_JUSTIFY_STANDARD;
+ const String& rOptVal = aIter->GetString();
+ if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_top ) )
+ eVal = SVX_VER_JUSTIFY_TOP;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_middle ) )
+ eVal = SVX_VER_JUSTIFY_CENTER;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_bottom ) )
+ eVal = SVX_VER_JUSTIFY_BOTTOM;
+ if( eVal != SVX_VER_JUSTIFY_STANDARD )
+ rItemSet.Put( SvxVerJustifyItem( eVal, ATTR_VER_JUSTIFY ) );
+ }
+ break;
+
+ case HTML_O_BGCOLOR:
+ {
+ Color aColor;
+ aIter->GetColor( aColor );
+ rItemSet.Put( SvxBrushItem( aColor, ATTR_BACKGROUND ) );
+ }
+ break;
+ }
+ }
+}
+
+void ScHTMLTable::SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize )
+{
+ DBG_ASSERT( nCellPos >= 0, "ScHTMLTable::SetDocSize - unexpected negative position" );
+ ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ size_t nIndex = static_cast< size_t >( nCellPos );
+ // expand with height/width == 1
+ while( nIndex >= rSizes.size() )
+ rSizes.push_back( rSizes.empty() ? 1 : (rSizes.back() + 1) );
+ // update size of passed position and all following
+ // #i109987# only grow, don't shrink - use the largest needed size
+ SCsCOLROW nDiff = nSize - ((nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]));
+ if( nDiff > 0 )
+ for( ScSizeVec::iterator aIt = rSizes.begin() + nIndex, aEnd = rSizes.end(); aIt != aEnd; ++aIt )
+ *aIt += nDiff;
+}
+
+void ScHTMLTable::CalcNeededDocSize(
+ ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nCellSpan, SCCOLROW nRealDocSize )
+{
+ SCCOLROW nDiffSize = 0;
+ // in merged columns/rows: reduce needed size by size of leading columns
+ while( nCellSpan > 1 )
+ {
+ nDiffSize += GetDocSize( eOrient, nCellPos );
+ --nCellSpan;
+ ++nCellPos;
+ }
+ // set remaining needed size to last column/row
+ nRealDocSize -= ::std::min< SCCOLROW >( nRealDocSize - 1, nDiffSize );
+ SetDocSize( eOrient, nCellPos, nRealDocSize );
+}
+
+// ----------------------------------------------------------------------------
+
+void ScHTMLTable::FillEmptyCells()
+{
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
+ aIter->FillEmptyCells();
+
+ // insert the final vertically merged ranges into maUsedCells
+ for( 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( !maUsedCells.Find( aAddr ) )
+ {
+ // create a range for the lock list (used to calc. cell span)
+ ScRange aRange( aAddr );
+ do
+ {
+ aRange.aEnd.IncCol();
+ }
+ while( (aRange.aEnd.Col() < maSize.mnCols) && !maUsedCells.Find( aRange.aEnd ) );
+ aRange.aEnd.IncCol( -1 );
+ maUsedCells.Join( aRange );
+
+ // insert a dummy entry
+ ScHTMLEntryPtr xEntry = CreateEntry();
+ ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], xEntry );
+ }
+ }
+ }
+}
+
+void ScHTMLTable::RecalcDocSize()
+{
+ // recalc table sizes recursively from inner to outer
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
+ aIter->RecalcDocSize();
+
+ /* Two passes: first calculates the sizes of single columns/rows, then
+ the sizes of spanned columns/rows. This allows to fill nested tables
+ into merged cells optimally. */
+ static const sal_uInt16 PASS_SINGLE = 0;
+ static const sal_uInt16 PASS_SPANNED = 1;
+ for( sal_uInt16 nPass = PASS_SINGLE; nPass <= PASS_SPANNED; ++nPass )
+ {
+ // iterate through every table cell
+ ScHTMLEntryMap::const_iterator aMapIterEnd = maEntryMap.end();
+ for( ScHTMLEntryMap::const_iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
+ {
+ const ScHTMLPos& rCellPos = aMapIter->first;
+ ScHTMLSize aCellSpan = GetSpan( rCellPos );
+
+ const ScHTMLEntryList& rEntryList = aMapIter->second;
+ ScHTMLEntryList::const_iterator aListIter;
+ ScHTMLEntryList::const_iterator aListIterEnd = rEntryList.end();
+
+ // process the dimension of the current cell in this pass?
+ // (pass is single and span is 1) or (pass is not single and span is not 1)
+ bool bProcessColWidth = ((nPass == PASS_SINGLE) == (aCellSpan.mnCols == 1));
+ bool bProcessRowHeight = ((nPass == PASS_SINGLE) == (aCellSpan.mnRows == 1));
+ if( bProcessColWidth || bProcessRowHeight )
+ {
+ ScHTMLSize aDocSize( 1, 0 ); // resulting size of the cell in document
+
+ // expand the cell size for each cell parse entry
+ for( aListIter = rEntryList.begin(); aListIter != aListIterEnd; ++aListIter )
+ {
+ ScHTMLTable* pTable = GetExistingTable( (*aListIter)->GetTableId() );
+ // find entry with maximum width
+ if( bProcessColWidth && pTable )
+ aDocSize.mnCols = ::std::max( aDocSize.mnCols, static_cast< SCCOL >( pTable->GetDocSize( tdCol ) ) );
+ // add up height of each entry
+ if( bProcessRowHeight )
+ aDocSize.mnRows += pTable ? pTable->GetDocSize( tdRow ) : 1;
+ }
+ if( !aDocSize.mnRows )
+ aDocSize.mnRows = 1;
+
+ if( bProcessColWidth )
+ CalcNeededDocSize( tdCol, rCellPos.mnCol, aCellSpan.mnCols, aDocSize.mnCols );
+ if( bProcessRowHeight )
+ CalcNeededDocSize( tdRow, rCellPos.mnRow, aCellSpan.mnRows, aDocSize.mnRows );
+ }
+ }
+ }
+}
+
+void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
+{
+ maDocBasePos = rBasePos;
+ // after the previous assignment it is allowed to call GetDocPos() methods
+
+ // iterate through every table cell
+ ScHTMLEntryMap::iterator aMapIterEnd = maEntryMap.end();
+ for( ScHTMLEntryMap::iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
+ {
+ // fixed doc position of the entire cell (first entry)
+ const ScHTMLPos aCellDocPos( GetDocPos( aMapIter->first ) );
+ // fixed doc size of the entire cell
+ const ScHTMLSize aCellDocSize( GetDocSize( aMapIter->first ) );
+
+ // running doc position for single entries
+ ScHTMLPos aEntryDocPos( aCellDocPos );
+
+ ScHTMLEntryList& rEntryList = aMapIter->second;
+ ScHTMLEntry* pEntry = 0;
+ ScHTMLEntryList::iterator aListIterEnd = rEntryList.end();
+ for( ScHTMLEntryList::iterator aListIter = rEntryList.begin(); aListIter != aListIterEnd; ++aListIter )
+ {
+ pEntry = *aListIter;
+ if( ScHTMLTable* pTable = GetExistingTable( pEntry->GetTableId() ) )
+ {
+ pTable->RecalcDocPos( aEntryDocPos ); // recalc nested table
+ pEntry->nCol = SCCOL_MAX;
+ pEntry->nRow = SCROW_MAX;
+ SCROW nTableRows = static_cast< SCROW >( pTable->GetDocSize( tdRow ) );
+
+ // use this entry to pad empty space right of table
+ if( mpParentTable ) // ... but not in global table
+ {
+ SCCOL nStartCol = aEntryDocPos.mnCol + static_cast< SCCOL >( pTable->GetDocSize( tdCol ) );
+ SCCOL nNextCol = aEntryDocPos.mnCol + aCellDocSize.mnCols;
+ if( nStartCol < nNextCol )
+ {
+ pEntry->nCol = nStartCol;
+ pEntry->nRow = aEntryDocPos.mnRow;
+ pEntry->nColOverlap = nNextCol - nStartCol;
+ pEntry->nRowOverlap = nTableRows;
+ }
+ }
+ aEntryDocPos.mnRow += nTableRows;
+ }
+ else
+ {
+ pEntry->nCol = aEntryDocPos.mnCol;
+ pEntry->nRow = aEntryDocPos.mnRow;
+ if( mpParentTable ) // do not merge in global table
+ pEntry->nColOverlap = aCellDocSize.mnCols;
+ ++aEntryDocPos.mnRow;
+ }
+ }
+
+ // pEntry points now to last entry.
+ if( pEntry )
+ {
+ if( (pEntry == rEntryList.front()) && (pEntry->GetTableId() == SC_HTML_NO_TABLE) )
+ {
+ // pEntry is the only entry in this cell - merge rows of cell with single non-table entry.
+ pEntry->nRowOverlap = aCellDocSize.mnRows;
+ }
+ else
+ {
+ // #111667# fill up incomplete entry lists
+ SCROW nFirstUnusedRow = aCellDocPos.mnRow + aCellDocSize.mnRows;
+ while( aEntryDocPos.mnRow < nFirstUnusedRow )
+ {
+ ScHTMLEntryPtr xDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
+ xDummyEntry->nCol = aEntryDocPos.mnCol;
+ xDummyEntry->nRow = aEntryDocPos.mnRow;
+ xDummyEntry->nColOverlap = aCellDocSize.mnCols;
+ ImplPushEntryToList( rEntryList, xDummyEntry );
+ ++aEntryDocPos.mnRow;
+ }
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+ScHTMLGlobalTable::ScHTMLGlobalTable( SfxItemPool& rPool, EditEngine& rEditEngine, ScEEParseList& rEEParseList, ScHTMLTableId& rnUnusedId ) :
+ ScHTMLTable( rPool, rEditEngine, rEEParseList, rnUnusedId )
+{
+}
+
+ScHTMLGlobalTable::~ScHTMLGlobalTable()
+{
+}
+
+void ScHTMLGlobalTable::Recalc()
+{
+ // Fills up empty cells with a dummy entry. */
+ FillEmptyCells();
+ // recalc table sizes of all nested tables and this table
+ RecalcDocSize();
+ // recalc document positions of all entries in this table and in nested tables
+ RecalcDocPos( GetDocPos() );
+}
+
+// ============================================================================
+
+ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
+ ScHTMLParser( pEditEngine, pDoc ),
+ mnUnusedId( SC_HTML_GLOBAL_TABLE ),
+ mbTitleOn( false )
+{
+ mxGlobTable.reset( new ScHTMLGlobalTable( *pPool, *pEdit, *pList, mnUnusedId ) );
+ mpCurrTable = mxGlobTable.get();
+}
+
+ScHTMLQueryParser::~ScHTMLQueryParser()
+{
+}
+
+ULONG ScHTMLQueryParser::Read( SvStream& rStrm, const String& rBaseURL )
+{
+ SvKeyValueIteratorRef xValues;
+ SvKeyValueIterator* pAttributes = 0;
+
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ if( pObjSh && pObjSh->IsLoading() )
+ {
+ pAttributes = pObjSh->GetHeaderAttributes();
+ }
+ else
+ {
+ /* When not loading, set up fake HTTP headers to force the SfxHTMLParser
+ to use UTF8 (used when pasting from clipboard) */
+ const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
+ if( pCharSet )
+ {
+ String aContentType = String::CreateFromAscii( "text/html; charset=" );
+ aContentType.AppendAscii( pCharSet );
+
+ xValues = new SvKeyValueIterator;
+ xValues->Append( SvKeyValue( String::CreateFromAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ), aContentType ) );
+ pAttributes = xValues;
+ }
+ }
+
+ Link aOldLink = pEdit->GetImportHdl();
+ pEdit->SetImportHdl( LINK( this, ScHTMLQueryParser, HTMLImportHdl ) );
+ ULONG nErr = pEdit->Read( rStrm, rBaseURL, EE_FORMAT_HTML, pAttributes );
+ pEdit->SetImportHdl( aOldLink );
+
+ mxGlobTable->Recalc();
+ nColMax = static_cast< SCCOL >( mxGlobTable->GetDocSize( tdCol ) - 1 );
+ nRowMax = static_cast< SCROW >( mxGlobTable->GetDocSize( tdRow ) - 1 );
+
+ return nErr;
+}
+
+const ScHTMLTable* ScHTMLQueryParser::GetGlobalTable() const
+{
+ return mxGlobTable.get();
+}
+
+void ScHTMLQueryParser::ProcessToken( const ImportInfo& rInfo )
+{
+ switch( rInfo.nToken )
+ {
+// --- meta data ---
+ case HTML_META: MetaOn( rInfo ); break; // <meta>
+
+// --- title handling ---
+ case HTML_TITLE_ON: TitleOn( rInfo ); break; // <title>
+ case HTML_TITLE_OFF: TitleOff( rInfo ); break; // </title>
+
+// --- body handling ---
+ case HTML_BODY_ON: mpCurrTable->BodyOn( rInfo ); break; // <body>
+ case HTML_BODY_OFF: mpCurrTable->BodyOff( rInfo ); break; // </body>
+
+// --- insert text ---
+ case HTML_TEXTTOKEN: InsertText( rInfo ); break; // any text
+ case HTML_LINEBREAK: mpCurrTable->BreakOn(); break; // <br>
+ case HTML_HEAD1_ON: // <h1>
+ case HTML_HEAD2_ON: // <h2>
+ case HTML_HEAD3_ON: // <h3>
+ case HTML_HEAD4_ON: // <h4>
+ case HTML_HEAD5_ON: // <h5>
+ case HTML_HEAD6_ON: // <h6>
+ case HTML_PARABREAK_ON: mpCurrTable->HeadingOn(); break; // <p>
+
+// --- misc. contents ---
+ case HTML_ANCHOR_ON: mpCurrTable->AnchorOn(); break; // <a>
+
+// --- table handling ---
+ case HTML_TABLE_ON: TableOn( rInfo ); break; // <table>
+ case HTML_TABLE_OFF: TableOff( rInfo ); break; // </table>
+ case HTML_TABLEROW_ON: mpCurrTable->RowOn( rInfo ); break; // <tr>
+ case HTML_TABLEROW_OFF: mpCurrTable->RowOff( rInfo ); break; // </tr>
+ case HTML_TABLEHEADER_ON: // <th>
+ case HTML_TABLEDATA_ON: mpCurrTable->DataOn( rInfo ); break; // <td>
+ case HTML_TABLEHEADER_OFF: // </th>
+ case HTML_TABLEDATA_OFF: mpCurrTable->DataOff( rInfo ); break; // </td>
+ case HTML_PREFORMTXT_ON: PreOn( rInfo ); break; // <pre>
+ case HTML_PREFORMTXT_OFF: PreOff( rInfo ); break; // </pre>
+
+// --- formatting ---
+ case HTML_FONT_ON: FontOn( rInfo ); break; // <font>
+
+ case HTML_BIGPRINT_ON: // <big>
+ //! TODO: store current font size, use following size
+ mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ 3 ], 100, ATTR_FONT_HEIGHT ) );
+ break;
+ case HTML_SMALLPRINT_ON: // <small>
+ //! TODO: store current font size, use preceding size
+ mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ 0 ], 100, ATTR_FONT_HEIGHT ) );
+ break;
+
+ case HTML_BOLD_ON: // <b>
+ case HTML_STRONG_ON: // <strong>
+ mpCurrTable->PutItem( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ break;
+
+ case HTML_ITALIC_ON: // <i>
+ case HTML_EMPHASIS_ON: // <em>
+ case HTML_ADDRESS_ON: // <address>
+ case HTML_BLOCKQUOTE_ON: // <blockquote>
+ case HTML_BLOCKQUOTE30_ON: // <bq>
+ case HTML_CITIATION_ON: // <cite>
+ case HTML_VARIABLE_ON: // <var>
+ mpCurrTable->PutItem( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ break;
+
+ case HTML_DEFINSTANCE_ON: // <dfn>
+ mpCurrTable->PutItem( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ mpCurrTable->PutItem( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ break;
+
+ case HTML_UNDERLINE_ON: // <u>
+ mpCurrTable->PutItem( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+ break;
+ }
+}
+
+void ScHTMLQueryParser::InsertText( const ImportInfo& rInfo )
+{
+ mpCurrTable->PutText( rInfo );
+ if( mbTitleOn )
+ maTitle.Append( rInfo.aText );
+}
+
+void ScHTMLQueryParser::FontOn( const ImportInfo& rInfo )
+{
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_FACE :
+ {
+ const String& rFace = aIter->GetString();
+ String aFontName;
+ xub_StrLen nPos = 0;
+ while( nPos != STRING_NOTFOUND )
+ {
+ // font list separator: VCL = ';' HTML = ','
+ String aFName = rFace.GetToken( 0, ',', nPos );
+ aFName.EraseLeadingAndTrailingChars();
+ ScGlobal::AddToken( aFontName, aFName, ';' );
+ }
+ if ( aFontName.Len() )
+ mpCurrTable->PutItem( SvxFontItem( FAMILY_DONTKNOW,
+ aFontName, EMPTY_STRING, PITCH_DONTKNOW,
+ RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+ }
+ break;
+ case HTML_O_SIZE :
+ {
+ sal_uInt32 nSize = getLimitedValue< sal_uInt32 >( aIter->GetNumber(), 1, SC_HTML_FONTSIZES );
+ mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ nSize - 1 ], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_O_COLOR :
+ {
+ Color aColor;
+ aIter->GetColor( aColor );
+ mpCurrTable->PutItem( SvxColorItem( aColor, ATTR_FONT_COLOR ) );
+ }
+ break;
+ }
+ }
+}
+
+void ScHTMLQueryParser::MetaOn( const ImportInfo& rInfo )
+{
+ if( mpDoc->GetDocumentShell() )
+ {
+ HTMLParser* pParser = static_cast< HTMLParser* >( rInfo.pParser );
+
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ pParser->ParseMetaOptions(
+ xDPS->getDocumentProperties(),
+ mpDoc->GetDocumentShell()->GetHeaderAttributes() );
+ }
+}
+
+void ScHTMLQueryParser::TitleOn( const ImportInfo& /*rInfo*/ )
+{
+ mbTitleOn = true;
+ maTitle.Erase();
+}
+
+void ScHTMLQueryParser::TitleOff( const ImportInfo& rInfo )
+{
+ if( mbTitleOn )
+ {
+ maTitle.EraseLeadingAndTrailingChars();
+ if( maTitle.Len() && mpDoc->GetDocumentShell() ) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+
+ xDPS->getDocumentProperties()->setTitle(maTitle);
+ }
+ InsertText( rInfo );
+ mbTitleOn = false;
+ }
+}
+
+void ScHTMLQueryParser::TableOn( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->TableOn( rInfo );
+}
+
+void ScHTMLQueryParser::TableOff( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->TableOff( rInfo );
+}
+
+void ScHTMLQueryParser::PreOn( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->PreOn( rInfo );
+}
+
+void ScHTMLQueryParser::PreOff( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->PreOff( rInfo );
+}
+
+void ScHTMLQueryParser::CloseTable( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->CloseTable( rInfo );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
+{
+ switch( pInfo->eState )
+ {
+ case HTMLIMP_START:
+ break;
+
+ case HTMLIMP_NEXTTOKEN:
+ case HTMLIMP_UNKNOWNATTR:
+ ProcessToken( *pInfo );
+ break;
+
+ case HTMLIMP_INSERTPARA:
+ mpCurrTable->InsertPara( *pInfo );
+ break;
+
+ case HTMLIMP_SETATTR:
+ case HTMLIMP_INSERTTEXT:
+ case HTMLIMP_INSERTFIELD:
+ break;
+
+ case HTMLIMP_END:
+ while( mpCurrTable->GetTableId() != SC_HTML_GLOBAL_TABLE )
+ CloseTable( *pInfo );
+ break;
+
+ default:
+ DBG_ERRORFILE( "ScHTMLQueryParser::HTMLImportHdl - unknown ImportInfo::eState" );
+ }
+ return 0;
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/html/makefile.mk b/sc/source/filter/html/makefile.mk
new file mode 100644
index 000000000000..93e992c67e31
--- /dev/null
+++ b/sc/source/filter/html/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=html
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/htmlexp.obj \
+ $(SLO)$/htmlexp2.obj \
+ $(SLO)$/htmlimp.obj \
+ $(SLO)$/htmlpars.obj
+
+EXCEPTIONSFILES = \
+ $(SLO)$/htmlexp.obj \
+ $(SLO)$/htmlpars.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/inc/XclExpChangeTrack.hxx b/sc/source/filter/inc/XclExpChangeTrack.hxx
new file mode 100644
index 000000000000..01eb076f6b3d
--- /dev/null
+++ b/sc/source/filter/inc/XclExpChangeTrack.hxx
@@ -0,0 +1,641 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCLEXPCHANGETRACK_HXX
+#define SC_XCLEXPCHANGETRACK_HXX
+
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <rtl/uuid.h>
+#include "bigrange.hxx"
+#include "chgtrack.hxx"
+#include "xelink.hxx"
+#include "ftools.hxx"
+#include "excrecds.hxx"
+
+//___________________________________________________________________
+
+class ScBaseCell;
+
+//___________________________________________________________________
+// XclExpUserBView - one UserBView record for each user
+
+class XclExpUserBView : public ExcRecord
+{
+private:
+ XclExpString sUsername;
+ sal_uInt8 aGUID[ 16 ];
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID );
+
+ inline const sal_uInt8* GetGUID() const { return aGUID; }
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// XclExpUserBViewList - list of UserBView records
+
+class XclExpUserBViewList : public ExcEmptyRec, private List
+{
+private:
+ inline XclExpUserBView* _First() { return (XclExpUserBView*) List::First(); }
+ inline XclExpUserBView* _Next() { return (XclExpUserBView*) List::Next(); }
+
+public:
+ XclExpUserBViewList( const ScChangeTrack& rChangeTrack );
+ virtual ~XclExpUserBViewList();
+
+ inline const XclExpUserBView* First() { return (const XclExpUserBView*) List::First(); }
+ inline const XclExpUserBView* Next() { return (const XclExpUserBView*) List::Next(); }
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpUsersViewBegin - begin of view block (one per sheet)
+
+class XclExpUsersViewBegin : public ExcRecord
+{
+private:
+ sal_uInt8 aGUID[ 16 ];
+ sal_uInt32 nCurrTab;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab );
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// XclExpUsersViewEnd - end of view block (one per sheet)
+
+class XclExpUsersViewEnd : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0191 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0198 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0192 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0197 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record without content
+
+class XclExpChTrEmpty : public ExcRecord
+{
+private:
+ UINT16 nRecNum;
+
+public:
+ inline XclExpChTrEmpty( UINT16 nNum ) : nRecNum( nNum ) {}
+ virtual ~XclExpChTrEmpty();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "Revision Log" stream
+
+class XclExpChTr0x0195 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual ~XclExpChTr0x0195();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "Revision Log" stream
+
+class XclExpChTr0x0194 : public ExcRecord
+{
+private:
+ XclExpString sUsername;
+ DateTime aDateTime;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTr0x0194( const ScChangeTrack& rChangeTrack );
+ virtual ~XclExpChTr0x0194();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+inline XclExpChTr0x0194::XclExpChTr0x0194( const ScChangeTrack& rChangeTrack ) :
+ sUsername( rChangeTrack.GetUser() ),
+ aDateTime( rChangeTrack.GetFixDateTime() )
+{
+}
+
+//___________________________________________________________________
+// XclExpChTrHeader - header record, includes action count
+
+class XclExpChTrHeader : public ExcRecord
+{
+private:
+ sal_uInt8 aGUID[ 16 ];
+ sal_uInt32 nCount;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTrHeader() : nCount( 0 ) {}
+ virtual ~XclExpChTrHeader();
+
+ inline void SetGUID( const sal_uInt8* pGUID ) { memcpy( aGUID, pGUID, 16 ); }
+ inline void SetCount( sal_uInt32 nNew ) { nCount = nNew; }
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// XclExpChTrInfo - header of action group of a user
+
+class XclExpChTrInfo : public ExcRecord
+{
+private:
+ XclExpString sUsername;
+ DateTime aDateTime;
+ sal_uInt8 aGUID[ 16 ];
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTrInfo(
+ const String& rUsername,
+ const DateTime& rDateTime,
+ const sal_uInt8* pGUID );
+ virtual ~XclExpChTrInfo();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+inline XclExpChTrInfo::XclExpChTrInfo( const String& rUsername, const DateTime& rDateTime, const sal_uInt8* pGUID ) :
+ sUsername( rUsername ),
+ aDateTime( rDateTime )
+{
+ memcpy( aGUID, pGUID, 16 );
+}
+
+//___________________________________________________________________
+// XclExpChTrTabIdBuffer - buffer for tab id's
+
+class XclExpChTrTabIdBuffer
+{
+private:
+ sal_uInt16* pBuffer;
+ sal_uInt16* pLast;
+ sal_uInt16 nBufSize;
+ sal_uInt16 nLastId;
+
+public:
+ XclExpChTrTabIdBuffer( sal_uInt16 nCount );
+ XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy );
+ ~XclExpChTrTabIdBuffer();
+
+ void InitFill( sal_uInt16 nIndex );
+ void InitFillup();
+
+ sal_uInt16 GetId( sal_uInt16 nIndex ) const;
+ void Remove();
+
+ inline sal_uInt16 GetBufferCount() const
+ { return static_cast< sal_uInt16 >( (pLast - pBuffer) + 1 ); }
+ inline void GetBufferCopy( sal_uInt16* pDest ) const
+ { memcpy( pDest, pBuffer, sizeof(sal_uInt16) * GetBufferCount() ); }
+};
+
+//___________________________________________________________________
+// XclExpChTrTabIdBufferList
+
+class XclExpChTrTabIdBufferList : private List
+{
+private:
+ inline XclExpChTrTabIdBuffer* First() { return (XclExpChTrTabIdBuffer*) List::First(); }
+ inline XclExpChTrTabIdBuffer* Next() { return (XclExpChTrTabIdBuffer*) List::Next(); }
+
+public:
+ virtual ~XclExpChTrTabIdBufferList();
+
+ inline void Append( XclExpChTrTabIdBuffer* pNew )
+ { List::Insert( pNew, LIST_APPEND ); }
+};
+
+//___________________________________________________________________
+// XclExpChTrTabId - tab id record
+
+class XclExpChTrTabId : public ExcRecord
+{
+private:
+ sal_uInt16* pBuffer;
+ sal_uInt16 nTabCount;
+
+ inline void Clear() { if( pBuffer ) delete[] pBuffer; pBuffer = NULL; }
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTrTabId( sal_uInt16 nCount ) :
+ pBuffer( NULL ), nTabCount( nCount ) {}
+ XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer );
+ virtual ~XclExpChTrTabId();
+
+ void Copy( const XclExpChTrTabIdBuffer& rBuffer );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// XclExpChTrAction - base class for action records
+
+class XclExpChTrAction : public ExcRecord
+{
+private:
+ String sUsername;
+ DateTime aDateTime;
+ sal_uInt32 nIndex; // action number
+ XclExpChTrAction* pAddAction; // additional record for this action
+ sal_Bool bAccepted;
+
+protected:
+ const XclExpTabInfo& rTabInfo; // for table num export (sc num -> xcl num)
+ const XclExpChTrTabIdBuffer& rIdBuffer; // for table num export (xcl num -> tab id)
+ sal_uInt32 nLength; // this is not the record size
+ sal_uInt16 nOpCode; // EXC_CHTR_OP_***
+ sal_Bool bForceInfo;
+
+ XclExpChTrAction( const XclExpChTrAction& rCopy );
+
+ void SetAddAction( XclExpChTrAction* pAction );
+ void AddDependentContents(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ ScChangeTrack& rChangeTrack );
+
+ inline void Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const;
+ inline void Write2DRange( XclExpStream& rStrm, const ScRange& rRange ) const;
+ inline void WriteTabId( XclExpStream& rStrm, SCTAB nTabId ) const;
+
+ // save header data, call SaveActionData()
+ virtual void SaveCont( XclExpStream& rStrm );
+ inline sal_Size GetHeaderByteCount() const { return 12; }
+
+ // overload to save action data without header, called by SaveCont()
+ virtual void SaveActionData( XclExpStream& rStrm ) const = 0;
+ // overload to get action size without header, called by GetLen()
+ virtual sal_Size GetActionByteCount() const = 0;
+
+ // do something before writing the record
+ virtual void PrepareSaveAction( XclExpStream& rStrm ) const;
+ // do something after writing the record
+ virtual void CompleteSaveAction( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrAction(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ sal_uInt16 nNewOpCode = EXC_CHTR_OP_UNKNOWN );
+ virtual ~XclExpChTrAction();
+
+ inline const String& GetUsername() const { return sUsername; }
+ inline const DateTime& GetDateTime() const { return aDateTime; }
+ inline const XclExpChTrTabIdBuffer& GetTabIdBuffer() const { return rIdBuffer; }
+ inline sal_Bool ForceInfoRecord() const { return bForceInfo; }
+
+ // set own index & return new index
+ // could be overloaded to use more indexes per action
+ virtual void SetIndex( sal_uInt32& rIndex );
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual sal_Size GetLen() const;
+};
+
+inline void XclExpChTrAction::Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const
+{
+ rStrm << (sal_uInt16) rAddress.Row()
+ << (sal_uInt16) rAddress.Col();
+}
+
+inline void XclExpChTrAction::Write2DRange( XclExpStream& rStrm, const ScRange& rRange ) const
+{
+ rStrm << (sal_uInt16) rRange.aStart.Row()
+ << (sal_uInt16) rRange.aEnd.Row()
+ << (sal_uInt16) rRange.aStart.Col()
+ << (sal_uInt16) rRange.aEnd.Col();
+}
+
+inline void XclExpChTrAction::WriteTabId( XclExpStream& rStrm, SCTAB nTab ) const
+{
+ rStrm << rIdBuffer.GetId( rTabInfo.GetXclTab( nTab ) );
+}
+
+//___________________________________________________________________
+// XclExpChTrData - cell content itself
+
+struct XclExpChTrData
+{
+ XclExpString* pString;
+ XclTokenArrayRef mxTokArr;
+ XclExpRefLog maRefLog;
+ double fValue;
+ sal_Int32 nRKValue;
+ sal_uInt16 nType;
+ sal_Size nSize;
+
+ XclExpChTrData();
+ ~XclExpChTrData();
+ void Clear();
+
+ void WriteFormula(
+ XclExpStream& rStrm,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+ void Write(
+ XclExpStream& rStrm,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+};
+
+//___________________________________________________________________
+// XclExpChTrCellContent - changed cell content
+
+class XclExpChTrCellContent : public XclExpChTrAction, protected XclExpRoot
+{
+private:
+ XclExpChTrData* pOldData;
+ XclExpChTrData* pNewData;
+ sal_uInt16 nOldLength; // this is not the record size
+
+ void MakeEmptyChTrData( XclExpChTrData*& rpData );
+
+protected:
+ ScAddress aPosition;
+
+ void GetCellData(
+ const ScBaseCell* pScCell,
+ XclExpChTrData*& rpData,
+ sal_uInt32& rXclLength1,
+ sal_uInt16& rXclLength2 );
+
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrCellContent(
+ const ScChangeActionContent& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+ virtual ~XclExpChTrCellContent();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+};
+
+//___________________________________________________________________
+// XclExpChTrInsert - insert/delete columns/rows
+
+class XclExpChTrInsert : public XclExpChTrAction
+{
+protected:
+ ScRange aRange;
+
+ XclExpChTrInsert( const XclExpChTrInsert& rCopy ) :
+ XclExpChTrAction( rCopy ), aRange( rCopy.aRange ) {}
+
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+ virtual void PrepareSaveAction( XclExpStream& rStrm ) const;
+ virtual void CompleteSaveAction( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrInsert(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack );
+ virtual ~XclExpChTrInsert();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+};
+
+//___________________________________________________________________
+// XclExpChTrInsertTab - insert table
+
+class XclExpChTrInsertTab : public XclExpChTrAction, protected XclExpRoot
+{
+private:
+ SCTAB nTab;
+
+protected:
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrInsertTab(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+ virtual ~XclExpChTrInsertTab();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+};
+
+//___________________________________________________________________
+// XclExpChTrMoveRange - move cell range
+
+class XclExpChTrMoveRange : public XclExpChTrAction
+{
+protected:
+ ScRange aSourceRange;
+ ScRange aDestRange;
+
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+ virtual void PrepareSaveAction( XclExpStream& rStrm ) const;
+ virtual void CompleteSaveAction( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrMoveRange(
+ const ScChangeActionMove& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack );
+ virtual ~XclExpChTrMoveRange();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+};
+
+//___________________________________________________________________
+// XclExpChTr0x019A - additional data for delete action
+
+class XclExpChTr0x014A : public XclExpChTrInsert
+{
+protected:
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTr0x014A( const XclExpChTrInsert& rAction );
+ virtual ~XclExpChTr0x014A();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+};
+
+//___________________________________________________________________
+// XclExpChTrActionStack - temporary action stack
+
+class XclExpChTrActionStack : private Stack
+{
+public:
+ virtual ~XclExpChTrActionStack();
+
+ void Push( XclExpChTrAction* pNewRec );
+ inline XclExpChTrAction* Pop() { return (XclExpChTrAction*) Stack::Pop(); }
+
+private:
+ using Stack::Push;
+};
+
+//___________________________________________________________________
+// XclExpChTrRecordList - list of "Revision Log" stream records
+
+class XclExpChTrRecordList : private List
+{
+private:
+ inline ExcRecord* First() { return (ExcRecord*) List::First(); }
+ inline ExcRecord* Next() { return (ExcRecord*) List::Next(); }
+
+public:
+ virtual ~XclExpChTrRecordList();
+
+ using List::Count;
+ void Append( ExcRecord* pNewRec );
+ void Save( XclExpStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChangeTrack - exports the "Revision Log" stream
+
+class XclExpChangeTrack : protected XclExpRoot
+{
+private:
+ XclExpChTrRecordList aRecList;
+ XclExpChTrActionStack aActionStack;
+ XclExpChTrTabIdBufferList aTabIdBufferList;
+ XclExpChTrTabIdBuffer* pTabIdBuffer;
+
+ ScDocument* pTempDoc; // empty document
+
+ sal_uInt32 nNewAction; // action number, 1-based
+ XclExpChTrHeader* pHeader; // header record for last GUID
+ sal_uInt8 aGUID[ 16 ]; // GUID for action info records
+ sal_Bool bValidGUID;
+
+ ScChangeTrack* CreateTempChangeTrack();
+ void PushActionRecord( const ScChangeAction& rAction );
+
+ sal_Bool WriteUserNamesStream();
+
+public:
+ XclExpChangeTrack( const XclExpRoot& rRoot );
+ ~XclExpChangeTrack();
+
+ void Write();
+};
+
+//___________________________________________________________________
+
+#endif
+
diff --git a/sc/source/filter/inc/XclImpChangeTrack.hxx b/sc/source/filter/inc/XclImpChangeTrack.hxx
new file mode 100644
index 000000000000..c850d6681235
--- /dev/null
+++ b/sc/source/filter/inc/XclImpChangeTrack.hxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCLIMPCHANGETRACK_HXX
+#define SC_XCLIMPCHANGETRACK_HXX
+
+#include <tools/datetime.hxx>
+#include "xiroot.hxx"
+#include "xistream.hxx"
+#include "excform.hxx"
+#include "imp_op.hxx"
+
+
+//___________________________________________________________________
+
+class ScBaseCell;
+class ScChangeAction;
+class ScChangeTrack;
+class XclImpChTrFmlConverter;
+
+//___________________________________________________________________
+
+struct XclImpChTrRecHeader
+{
+ sal_uInt32 nSize;
+ sal_uInt32 nIndex;
+ sal_uInt16 nOpCode;
+ sal_uInt16 nAccept;
+};
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpChTrRecHeader& rRecHeader )
+{
+ rStrm >> rRecHeader.nSize >> rRecHeader.nIndex >> rRecHeader.nOpCode >> rRecHeader.nAccept;
+ return rStrm;
+}
+
+//___________________________________________________________________
+
+class XclImpChangeTrack : protected XclImpRoot
+{
+private:
+ XclImpChTrRecHeader aRecHeader;
+ String sOldUsername;
+
+ ScChangeTrack* pChangeTrack;
+ SotStorageStreamRef xInStrm; // input stream
+ XclImpStream* pStrm; // stream import class
+ sal_uInt16 nTabIdCount;
+ sal_Bool bGlobExit; // global exit loop
+
+ enum { nmBase, nmFound, nmNested }
+ eNestedMode; // action with nested content actions
+
+ inline sal_Bool FoundNestedMode() { return eNestedMode == nmFound; }
+
+ void DoAcceptRejectAction( ScChangeAction* pAction );
+ void DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast );
+
+ void DoInsertRange( const ScRange& rRange );
+ void DoDeleteRange( const ScRange& rRange );
+
+ inline sal_uInt8 LookAtuInt8();
+ inline double ReadRK();
+ inline sal_Bool ReadBool();
+ inline void Read2DAddress( ScAddress& rAddress );
+ inline void Read2DRange( ScRange& rRange );
+ SCTAB ReadTabNum();
+ void ReadDateTime( DateTime& rDateTime );
+
+ inline void ReadString( String& rString );
+ inline void IgnoreString();
+
+ sal_Bool CheckRecord( sal_uInt16 nOpCode );
+
+ void ReadFormula(
+ ScTokenArray*& rpTokenArray,
+ const ScAddress& rPosition );
+ void ReadCell(
+ ScBaseCell*& rpCell,
+ sal_uInt32& rFormat,
+ sal_uInt16 nFlags,
+ const ScAddress& rPosition );
+
+ void ReadChTrInsert(); // 0x0137
+ void ReadChTrInfo(); // 0x0138
+ void ReadChTrCellContent(); // 0x013B
+ void ReadChTrTabId(); // 0x013D
+ void ReadChTrMoveRange(); // 0x0140
+ void ReadChTrInsertTab(); // 0x014D
+ void InitNestedMode(); // 0x014E, 0x0150
+ void ReadNestedRecords();
+ sal_Bool EndNestedMode(); // 0x014F, 0x0151
+
+ void ReadRecords();
+
+public:
+ XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm );
+ ~XclImpChangeTrack();
+
+ // reads extended 3D ref info following the formulas, returns sc tab nums
+ // ( called by XclImpChTrFmlConverter::Read3DTabReference() )
+ sal_Bool Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab, ExcelToSc8::ExternalTabInfo& rExtInfo );
+
+ void Apply();
+};
+
+inline sal_uInt8 XclImpChangeTrack::LookAtuInt8()
+{
+ pStrm->PushPosition();
+ sal_uInt8 nValue;
+ *pStrm >> nValue;
+ pStrm->PopPosition();
+ return nValue;
+}
+
+inline double XclImpChangeTrack::ReadRK()
+{
+ return XclTools::GetDoubleFromRK( pStrm->ReadInt32() );
+}
+
+inline sal_Bool XclImpChangeTrack::ReadBool()
+{
+ return (pStrm->ReaduInt16() != 0);
+}
+
+inline void XclImpChangeTrack::Read2DAddress( ScAddress& rAddress )
+{
+ rAddress.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
+ rAddress.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
+}
+
+inline void XclImpChangeTrack::Read2DRange( ScRange& rRange )
+{
+ rRange.aStart.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
+ rRange.aEnd.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
+ rRange.aStart.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
+ rRange.aEnd.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
+}
+
+inline void XclImpChangeTrack::ReadString( String& rString )
+{
+ rString = pStrm->ReadUniString();
+}
+
+inline void XclImpChangeTrack::IgnoreString()
+{
+ pStrm->IgnoreUniString();
+}
+
+//___________________________________________________________________
+// derived class for special 3D ref handling
+
+class XclImpChTrFmlConverter : public ExcelToSc8
+{
+private:
+ XclImpChangeTrack& rChangeTrack;
+
+ virtual bool Read3DTabReference( UINT16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );
+
+public:
+ inline XclImpChTrFmlConverter(
+ const XclImpRoot& rRoot,
+ XclImpChangeTrack& rXclChTr );
+ virtual ~XclImpChTrFmlConverter();
+};
+
+inline XclImpChTrFmlConverter::XclImpChTrFmlConverter(
+ const XclImpRoot& rRoot,
+ XclImpChangeTrack& rXclChTr ) :
+ ExcelToSc8( rRoot ),
+ rChangeTrack( rXclChTr )
+{
+}
+
+//___________________________________________________________________
+
+#endif
+
diff --git a/sc/source/filter/inc/biff.hxx b/sc/source/filter/inc/biff.hxx
new file mode 100644
index 000000000000..479dc0f577f5
--- /dev/null
+++ b/sc/source/filter/inc/biff.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_BASE_HXX
+#define SC_BASE_HXX
+
+#include <sal/config.h>
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include <tools/string.hxx>
+
+#include <tools/color.hxx>
+#include "flttypes.hxx"
+#include "ftools.hxx"
+
+// Stream wrapper class
+class ScBiffReader
+{
+ protected:
+ sal_uInt16 mnId;
+ sal_uInt16 mnLength;
+ sal_uInt32 mnOffset;
+ SvStream *mpStream;
+ bool mbEndOfFile;
+
+ public:
+ ScBiffReader( SfxMedium& rMedium );
+ ~ScBiffReader();
+ bool recordsLeft() { return mpStream && !mpStream->IsEof(); }
+ bool IsEndOfFile() { return mbEndOfFile; }
+ void SetEof( bool bValue ){ mbEndOfFile = bValue; }
+ bool nextRecord();
+ sal_uInt16 getId() { return mnId; }
+ sal_uInt16 getLength() { return mnLength; }
+ SvStream& getStream() { return *mpStream; }
+};
+#endif
+
diff --git a/sc/source/filter/inc/colrowst.hxx b/sc/source/filter/inc/colrowst.hxx
new file mode 100644
index 000000000000..325d380cc19c
--- /dev/null
+++ b/sc/source/filter/inc/colrowst.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_COLROWST_HXX
+#define SC_COLROWST_HXX
+
+#include "xiroot.hxx"
+
+class XclImpStream;
+
+// ============================================================================
+
+class XclImpColRowSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpColRowSettings( const XclImpRoot& rRoot );
+ virtual ~XclImpColRowSettings();
+
+ void SetDefWidth( sal_uInt16 nDefWidth, bool bStdWidthRec = false );
+ void SetWidthRange( SCCOL nCol1, SCCOL nCol2, sal_uInt16 nWidth );
+ void HideCol( SCCOL nCol );
+ void HideColRange( SCCOL nCol1, SCCOL nCol2 );
+
+ void SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlags );
+ void SetHeight( SCROW nRow, sal_uInt16 nHeight );
+ void SetRowSettings( SCROW nRow, sal_uInt16 nHeight, sal_uInt16 nFlags );
+ void SetManualRowHeight( SCROW nScRow );
+
+ void SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex );
+ /** Inserts all column and row settings of the specified sheet, except the hidden flags. */
+ void Convert( SCTAB nScTab );
+ /** Sets the HIDDEN flags at all hidden columns and rows in the specified sheet. */
+ void ConvertHiddenFlags( SCTAB nScTab );
+
+private:
+ ScfUInt16Vec maWidths; /// Column widths in twips.
+ ScfUInt8Vec maColFlags; /// Flags for all columns.
+ ScfUInt16Vec maHeights; /// Row heights in twips.
+ ScfUInt8Vec maRowFlags; /// Flags for all rows.
+
+ SCROW mnLastScRow;
+
+ sal_uInt16 mnDefWidth; /// Default width from DEFCOLWIDTH or STANDARDWIDTH record.
+ sal_uInt16 mnDefHeight; /// Default height from DEFAULTROWHEIGHT record.
+ sal_uInt16 mnDefRowFlags; /// Default row flags from DEFAULTROWHEIGHT record.
+
+ bool mbHasStdWidthRec; /// true = Width from STANDARDWIDTH (overrides DEFCOLWIDTH record).
+ bool mbHasDefHeight; /// true = mnDefHeight and mnDefRowFlags are valid.
+ bool mbDirty;
+};
+
+
+
+
+#endif
+
diff --git a/sc/source/filter/inc/decl.h b/sc/source/filter/inc/decl.h
new file mode 100644
index 000000000000..e888b7dca5fe
--- /dev/null
+++ b/sc/source/filter/inc/decl.h
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_DECL_H
+#define SC_DECL_H
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+enum WKTYP { eWK_UNKNOWN = -2, eWK_1 = 0, eWK_2, eWK3, eWK4, eWK_Error, eWK123 };
+typedef void ( BEARBFKT )( void );
+typedef sal_Char STRING16[ 16 ];
+typedef sal_Char STRING14[ 14 ];
+typedef sal_Char STRING8[ 8 ];
+typedef sal_Char STRING6[ 6 ];
+typedef USHORT USHORT4[ 4 ];
+//typedef unsigned short USHORT4[ 4 ];
+#endif
+
diff --git a/sc/source/filter/inc/dif.hxx b/sc/source/filter/inc/dif.hxx
new file mode 100644
index 000000000000..20b2400cf5a2
--- /dev/null
+++ b/sc/source/filter/inc/dif.hxx
@@ -0,0 +1,227 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_DIF_HXX
+#define SC_DIF_HXX
+
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+
+class SvStream;
+class SvNumberFormatter;
+class ScDocument;
+class ScPatternAttr;
+
+extern const sal_Unicode pKeyTABLE[];
+extern const sal_Unicode pKeyVECTORS[];
+extern const sal_Unicode pKeyTUPLES[];
+extern const sal_Unicode pKeyDATA[];
+extern const sal_Unicode pKeyBOT[];
+extern const sal_Unicode pKeyEOD[];
+extern const sal_Unicode pKeyTRUE[];
+extern const sal_Unicode pKeyFALSE[];
+extern const sal_Unicode pKeyNA[];
+extern const sal_Unicode pKeyV[];
+extern const sal_Unicode pKey1_0[];
+
+
+enum TOPIC
+{
+ T_UNKNOWN,
+ T_TABLE, T_VECTORS, T_TUPLES, T_DATA, T_LABEL, T_COMMENT, T_SIZE,
+ T_PERIODICITY, T_MAJORSTART, T_MINORSTART, T_TRUELENGTH, T_UINITS,
+ T_DISPLAYUNITS,
+ T_END
+};
+
+enum DATASET { D_BOT, D_EOD, D_NUMERIC, D_STRING, D_UNKNOWN, D_SYNT_ERROR };
+
+
+class DifParser
+{
+public:
+ String aData;
+ double fVal;
+ UINT32 nVector;
+ UINT32 nVal;
+ UINT32 nNumFormat;
+ CharSet eCharSet;
+private:
+ SvNumberFormatter* pNumFormatter;
+ SvStream& rIn;
+ BOOL bPlain;
+ String aLookAheadLine;
+
+ bool ReadNextLine( String& rStr );
+ bool LookAhead();
+ DATASET GetNumberDataset( const sal_Unicode* pPossibleNumericData );
+ static inline BOOL IsBOT( const sal_Unicode* pRef );
+ static inline BOOL IsEOD( const sal_Unicode* pRef );
+ static inline BOOL Is1_0( const sal_Unicode* pRef );
+public:
+ DifParser( SvStream&, const UINT32 nOption, ScDocument&, CharSet );
+
+ TOPIC GetNextTopic( void );
+
+ DATASET GetNextDataset( void );
+
+ const sal_Unicode* ScanIntVal( const sal_Unicode* pStart, UINT32& rRet );
+ BOOL ScanFloatVal( const sal_Unicode* pStart );
+
+ inline BOOL IsNumber( const sal_Unicode cChar );
+ inline BOOL IsNumberEnding( const sal_Unicode cChar );
+
+ static inline BOOL IsV( const sal_Unicode* pRef );
+
+ inline BOOL IsPlain( void ) const;
+};
+
+
+inline BOOL DifParser::IsBOT( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKeyBOT[0] &&
+ pRef[ 1 ] == pKeyBOT[1] &&
+ pRef[ 2 ] == pKeyBOT[2] &&
+ pRef[ 3 ] == pKeyBOT[3] );
+}
+
+
+inline BOOL DifParser::IsEOD( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKeyEOD[0] &&
+ pRef[ 1 ] == pKeyEOD[1] &&
+ pRef[ 2 ] == pKeyEOD[2] &&
+ pRef[ 3 ] == pKeyEOD[3] );
+}
+
+
+inline BOOL DifParser::Is1_0( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKey1_0[0] &&
+ pRef[ 1 ] == pKey1_0[1] &&
+ pRef[ 2 ] == pKey1_0[2] &&
+ pRef[ 3 ] == pKey1_0[3] );
+}
+
+
+inline BOOL DifParser::IsV( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKeyV[0] &&
+ pRef[ 1 ] == pKeyV[1] );
+}
+
+
+inline BOOL DifParser::IsNumber( const sal_Unicode cChar )
+{
+ return ( cChar >= '0' && cChar <= '9' );
+}
+
+
+inline BOOL DifParser::IsNumberEnding( const sal_Unicode cChar )
+{
+ return ( cChar == 0x00 );
+}
+
+
+inline BOOL DifParser::IsPlain( void ) const
+{
+ return bPlain;
+}
+
+
+
+
+class DifAttrCache;
+class ScPatternAttr;
+
+
+class DifColumn : private List
+{
+private:
+ friend class DifAttrCache;
+ struct ENTRY
+ {
+ UINT32 nNumFormat;
+
+ SCROW nStart;
+ SCROW nEnd;
+ };
+
+ ENTRY* pAkt;
+
+ inline DifColumn( void );
+ ~DifColumn();
+ void SetLogical( SCROW nRow );
+ void SetNumFormat( SCROW nRow, const UINT32 nNumFormat );
+ void NewEntry( const SCROW nPos, const UINT32 nNumFormat );
+ void Apply( ScDocument&, const SCCOL nCol, const SCTAB nTab, const ScPatternAttr& );
+ void Apply( ScDocument &rDoc, const SCCOL nCol, const SCTAB nTab );
+public: // geht niemanden etwas an...
+};
+
+
+inline DifColumn::DifColumn( void )
+{
+ pAkt = NULL;
+}
+
+
+
+
+class DifAttrCache
+{
+private:
+ DifColumn** ppCols;
+ BOOL bPlain;
+public:
+ DifAttrCache( const BOOL bPlain );
+ ~DifAttrCache();
+ inline void SetLogical( const SCCOL nCol, const SCROW nRow );
+ void SetNumFormat( const SCCOL nCol, const SCROW nRow, const UINT32 nNumFormat );
+ void Apply( ScDocument&, SCTAB nTab );
+};
+
+
+inline void DifAttrCache::SetLogical( const SCCOL nCol, const SCROW nRow )
+{
+ DBG_ASSERT( ValidCol(nCol), "-DifAttrCache::SetLogical(): Col zu gross!" );
+ DBG_ASSERT( bPlain, "*DifAttrCache::SetLogical(): muss Plain sein!" );
+
+ if( !ppCols[ nCol ] )
+ ppCols[ nCol ] = new DifColumn;
+ ppCols[ nCol ]->SetLogical( nRow );
+}
+
+
+#endif
+
+
diff --git a/sc/source/filter/inc/eeimport.hxx b/sc/source/filter/inc/eeimport.hxx
new file mode 100644
index 000000000000..634dfd1b4a33
--- /dev/null
+++ b/sc/source/filter/inc/eeimport.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_EEIMPORT_HXX
+#define SC_EEIMPORT_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include "filter.hxx"
+#include "scdllapi.h"
+
+class ScDocument;
+class ScEEParser;
+class ScTabEditEngine;
+class SvStream;
+class Table;
+
+struct ScEEParseEntry;
+
+class ScEEImport : public ScEEAbsImport
+{
+protected:
+ ScRange maRange;
+ ScDocument* mpDoc;
+ ScEEParser* mpParser;
+ ScTabEditEngine* mpEngine;
+ Table* mpRowHeights;
+
+ BOOL GraphicSize( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScEEParseEntry* );
+ void InsertGraphic( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScEEParseEntry* );
+public:
+ ScEEImport( ScDocument* pDoc, const ScRange& rRange );
+ virtual ~ScEEImport();
+
+ virtual ULONG Read( SvStream& rStream, const String& rBaseURL );
+ virtual ScRange GetRange() { return maRange; }
+ virtual void WriteToDocument( BOOL bSizeColsRows = FALSE,
+ double nOutputFactor = 1.0,
+ SvNumberFormatter* pFormatter = NULL,
+ bool bConvertDate = true );
+};
+
+#endif
diff --git a/sc/source/filter/inc/eeparser.hxx b/sc/source/filter/inc/eeparser.hxx
new file mode 100644
index 000000000000..afc8c959392b
--- /dev/null
+++ b/sc/source/filter/inc/eeparser.hxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EEPARSER_HXX
+#define SC_EEPARSER_HXX
+
+#include <tools/string.hxx>
+#include <tools/gen.hxx>
+#include <vcl/graph.hxx>
+#include <tools/table.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/editdata.hxx>
+#include <address.hxx>
+
+const sal_Char nHorizontal = 1;
+const sal_Char nVertical = 2;
+const sal_Char nHoriVerti = nHorizontal | nVertical;
+
+struct ScHTMLImage
+{
+ String aURL;
+ Size aSize;
+ Point aSpace;
+ String aFilterName;
+ Graphic* pGraphic; // wird von WriteToDocument uebernommen
+ sal_Char nDir; // 1==hori, 2==verti, 3==beides
+
+ ScHTMLImage() :
+ aSize( 0, 0 ), aSpace( 0, 0 ), pGraphic( NULL ),
+ nDir( nHorizontal )
+ {}
+ ~ScHTMLImage()
+ { if ( pGraphic ) delete pGraphic; }
+};
+DECLARE_LIST( ScHTMLImageList, ScHTMLImage* )
+
+struct ScEEParseEntry
+{
+ SfxItemSet aItemSet;
+ ESelection aSel; // Selection in EditEngine
+ String* pValStr; // HTML evtl. SDVAL String
+ String* pNumStr; // HTML evtl. SDNUM String
+ String* pName; // HTML evtl. Anchor/RangeName
+ String aAltText; // HTML IMG ALT Text
+ ScHTMLImageList* pImageList; // Grafiken in dieser Zelle
+ SCCOL nCol; // relativ zum Beginn des Parse
+ SCROW nRow;
+ USHORT nTab; // HTML TableInTable
+ USHORT nTwips; // RTF ColAdjust etc.
+ SCCOL nColOverlap; // merged cells wenn >1
+ SCROW nRowOverlap; // merged cells wenn >1
+ USHORT nOffset; // HTML PixelOffset
+ USHORT nWidth; // HTML PixelWidth
+ BOOL bHasGraphic; // HTML any image loaded
+ bool bEntirePara; // TRUE = use entire paragraph, false = use selection
+
+ ScEEParseEntry( SfxItemPool* pPool ) :
+ aItemSet( *pPool ), pValStr( NULL ),
+ pNumStr( NULL ), pName( NULL ), pImageList( NULL ),
+ nCol(SCCOL_MAX), nRow(SCROW_MAX), nTab(0),
+ nColOverlap(1), nRowOverlap(1),
+ nOffset(0), nWidth(0), bHasGraphic(FALSE), bEntirePara(true)
+ {}
+ ScEEParseEntry( const SfxItemSet& rItemSet ) :
+ aItemSet( rItemSet ), pValStr( NULL ),
+ pNumStr( NULL ), pName( NULL ), pImageList( NULL ),
+ nCol(SCCOL_MAX), nRow(SCROW_MAX), nTab(0),
+ nColOverlap(1), nRowOverlap(1),
+ nOffset(0), nWidth(0), bHasGraphic(FALSE), bEntirePara(true)
+ {}
+ ~ScEEParseEntry()
+ {
+ if ( pValStr )
+ delete pValStr;
+ if ( pNumStr )
+ delete pNumStr;
+ if ( pName )
+ delete pName;
+ if ( pImageList )
+ {
+ for ( ScHTMLImage* pI = pImageList->First();
+ pI; pI = pImageList->Next() )
+ {
+ delete pI;
+ }
+ delete pImageList;
+ }
+ }
+};
+DECLARE_LIST( ScEEParseList, ScEEParseEntry* )
+
+
+class EditEngine;
+
+class ScEEParser
+{
+protected:
+ EditEngine* pEdit;
+ SfxItemPool* pPool;
+ SfxItemPool* pDocPool;
+ ScEEParseList* pList;
+ ScEEParseEntry* pActEntry;
+ Table* pColWidths;
+ int nLastToken;
+ SCCOL nColCnt;
+ SCROW nRowCnt;
+ SCCOL nColMax;
+ SCROW nRowMax;
+
+ void NewActEntry( ScEEParseEntry* );
+
+public:
+ ScEEParser( EditEngine* );
+ virtual ~ScEEParser();
+
+ virtual ULONG Read( SvStream&, const String& rBaseURL ) = 0;
+
+ void GetDimensions( SCCOL& nCols, SCROW& nRows ) const
+ { nCols = nColMax; nRows = nRowMax; }
+ ULONG Count() const { return pList->Count(); }
+ ScEEParseEntry* First() const { return pList->First(); }
+ ScEEParseEntry* Next() const { return pList->Next(); }
+ Table* GetColWidths() const { return pColWidths; }
+};
+
+
+
+#endif
+
diff --git a/sc/source/filter/inc/excdefs.hxx b/sc/source/filter/inc/excdefs.hxx
new file mode 100644
index 000000000000..2d489af7e427
--- /dev/null
+++ b/sc/source/filter/inc/excdefs.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCDEFS_HXX
+#define SC_EXCDEFS_HXX
+
+#include <sal/types.h>
+
+// (0x009B, 0x009D, 0x009E) AUTOFILTER ========================================
+
+// flags
+const sal_uInt16 EXC_AFFLAG_AND = 0x0000;
+const sal_uInt16 EXC_AFFLAG_OR = 0x0001;
+const sal_uInt16 EXC_AFFLAG_ANDORMASK = 0x0003;
+const sal_uInt16 EXC_AFFLAG_SIMPLE1 = 0x0004;
+const sal_uInt16 EXC_AFFLAG_SIMPLE2 = 0x0008;
+const sal_uInt16 EXC_AFFLAG_TOP10 = 0x0010;
+const sal_uInt16 EXC_AFFLAG_TOP10TOP = 0x0020;
+const sal_uInt16 EXC_AFFLAG_TOP10PERC = 0x0040;
+
+// data types
+const sal_uInt8 EXC_AFTYPE_NOTUSED = 0x00;
+const sal_uInt8 EXC_AFTYPE_RK = 0x02;
+const sal_uInt8 EXC_AFTYPE_DOUBLE = 0x04;
+const sal_uInt8 EXC_AFTYPE_STRING = 0x06;
+const sal_uInt8 EXC_AFTYPE_BOOLERR = 0x08;
+const sal_uInt8 EXC_AFTYPE_INVALID = 0x0A;
+const sal_uInt8 EXC_AFTYPE_EMPTY = 0x0C;
+const sal_uInt8 EXC_AFTYPE_NOTEMPTY = 0x0E;
+
+// comparison operands
+const sal_uInt8 EXC_AFOPER_NONE = 0x00;
+const sal_uInt8 EXC_AFOPER_LESS = 0x01;
+const sal_uInt8 EXC_AFOPER_EQUAL = 0x02;
+const sal_uInt8 EXC_AFOPER_LESSEQUAL = 0x03;
+const sal_uInt8 EXC_AFOPER_GREATER = 0x04;
+const sal_uInt8 EXC_AFOPER_NOTEQUAL = 0x05;
+const sal_uInt8 EXC_AFOPER_GREATEREQUAL = 0x06;
+
+// (0x00AE, 0x00AF) SCENARIO, SCENMAN =========================================
+
+#define EXC_SCEN_MAXCELL 32
+
+// defines for change tracking ================================================
+
+#define EXC_STREAM_USERNAMES CREATE_STRING( "User Names" )
+#define EXC_STREAM_REVLOG CREATE_STRING( "Revision Log" )
+
+// opcodes
+#define EXC_CHTR_OP_COLFLAG 0x0001
+#define EXC_CHTR_OP_DELFLAG 0x0002
+#define EXC_CHTR_OP_INSROW 0x0000
+#define EXC_CHTR_OP_INSCOL EXC_CHTR_OP_COLFLAG
+#define EXC_CHTR_OP_DELROW EXC_CHTR_OP_DELFLAG
+#define EXC_CHTR_OP_DELCOL (EXC_CHTR_OP_COLFLAG|EXC_CHTR_OP_DELFLAG)
+#define EXC_CHTR_OP_MOVE 0x0004
+#define EXC_CHTR_OP_INSTAB 0x0005
+#define EXC_CHTR_OP_CELL 0x0008
+#define EXC_CHTR_OP_RENAME 0x0009
+#define EXC_CHTR_OP_NAME 0x000A
+#define EXC_CHTR_OP_FORMAT 0x000B
+#define EXC_CHTR_OP_UNKNOWN 0xFFFF
+
+// data types
+#define EXC_CHTR_TYPE_MASK 0x0007
+#define EXC_CHTR_TYPE_FORMATMASK 0xFF00
+#define EXC_CHTR_TYPE_EMPTY 0x0000
+#define EXC_CHTR_TYPE_RK 0x0001
+#define EXC_CHTR_TYPE_DOUBLE 0x0002
+#define EXC_CHTR_TYPE_STRING 0x0003
+#define EXC_CHTR_TYPE_BOOL 0x0004
+#define EXC_CHTR_TYPE_FORMULA 0x0005
+
+// accept flags
+#define EXC_CHTR_NOTHING 0x0000
+#define EXC_CHTR_ACCEPT 0x0001
+#define EXC_CHTR_REJECT 0x0003
+
+// ============================================================================
+
+#endif // _EXCDEFS_HXX
+
diff --git a/sc/source/filter/inc/excdoc.hxx b/sc/source/filter/inc/excdoc.hxx
new file mode 100644
index 000000000000..5da6a5d38d83
--- /dev/null
+++ b/sc/source/filter/inc/excdoc.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCDOC_HXX
+#define SC_EXCDOC_HXX
+
+#include <tools/solar.h>
+#include "excrecds.hxx"
+#include "xeroot.hxx"
+#include "root.hxx"
+
+//------------------------------------------------------------------ Forwards -
+
+class SvStream;
+class ScBaseCell;
+class ScHorizontalCellIterator;
+class ScDocument;
+class ScProgress;
+
+class NameBuffer;
+
+class XclExpChangeTrack;
+
+
+//------------------------------------------------------------ class ExcTable -
+
+class XclExpCellTable;
+
+class ExcTable : public XclExpRecordBase, public XclExpRoot
+{
+private:
+ typedef XclExpRecordList< ExcBundlesheetBase > ExcBoundsheetList;
+ typedef ScfRef< XclExpCellTable > XclExpCellTableRef;
+
+ XclExpRecordList<> aRecList;
+ XclExpCellTableRef mxCellTable;
+
+ SCTAB mnScTab; // table number SC document
+ UINT16 nExcTab; // table number Excel document
+ UINT16 nAktRow; // fuer'n Iterator
+ UINT16 nAktCol;
+
+ NameBuffer* pTabNames;
+
+ // pRec mit new anlegen und vergessen, delete macht ExcTable selber!
+ void Add( XclExpRecordBase* pRec );
+
+ void FillAsXmlTable( SCTAB nCodeNameIdx );
+
+public:
+ ExcTable( const XclExpRoot& rRoot );
+ ExcTable( const XclExpRoot& rRoot, SCTAB nScTab );
+ ~ExcTable();
+
+ void FillAsHeader( ExcBoundsheetList& rBoundsheetList );
+ void FillAsTable( SCTAB nCodeNameIdx );
+ void FillAsEmptyTable( SCTAB nCodeNameIdx );
+
+ void Write( XclExpStream& );
+ void WriteXml( XclExpXmlStream& );
+};
+
+
+//--------------------------------------------------------- class ExcDocument -
+
+class ExcDocument : protected XclExpRoot
+{
+friend class ExcTable;
+
+private:
+ typedef XclExpRecordList< ExcTable > ExcTableList;
+ typedef ExcTableList::RecordRefType ExcTableRef;
+ typedef XclExpRecordList< ExcBundlesheetBase > ExcBoundsheetList;
+ typedef ExcBoundsheetList::RecordRefType ExcBoundsheetRef;
+
+ ExcTable aHeader;
+
+ ExcTableList maTableList;
+ ExcBoundsheetList maBoundsheetList;
+
+ XclExpChangeTrack* pExpChangeTrack;
+
+public:
+ explicit ExcDocument( const XclExpRoot& rRoot );
+ virtual ~ExcDocument();
+
+ void ReadDoc( void );
+ void Write( SvStream& rSvStrm );
+ void WriteXml( SvStream& rSvStrm );
+};
+
+
+
+
+#endif
+
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
new file mode 100644
index 000000000000..ed771637b704
--- /dev/null
+++ b/sc/source/filter/inc/excform.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCFORM_HXX
+#define SC_EXCFORM_HXX
+
+#include "xlformula.hxx"
+#include "xiroot.hxx"
+#include "formel.hxx"
+
+#include <vector>
+
+class ScRangeList;
+
+
+class ExcelToSc : public ExcelConverterBase, protected XclImpRoot
+{
+protected:
+ enum ExtensionType { EXTENSION_ARRAY, EXTENSION_NLR, EXTENSION_MEMAREA };
+ typedef ::std::vector< ExtensionType > ExtensionTypeVec;
+
+ BOOL bExternName; // wenn External Name gefunden wurde
+ static const UINT16 nRowMask;
+ static const UINT16 nLastInd; // letzter Index fuer Excel->SC-
+ // Token Umsetzung
+ XclFunctionProvider maFuncProv;
+ const XclBiff meBiff;
+
+ // ---------------------------------------------------------------
+ void DoMulArgs( DefTokenId eId, sal_uInt8 nNumArgs, sal_uInt8 mnMinParamCount = 0 );
+
+ void ExcRelToScRel( UINT16 nRow, UINT8 nCol, ScSingleRefData&, const BOOL bName );
+
+public:
+ ExcelToSc( const XclImpRoot& rRoot );
+ virtual ~ExcelToSc();
+ virtual ConvErr Convert( const ScTokenArray*&, XclImpStream& rStrm, sal_Size nFormulaLen,
+ bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const String& rUrl, const ::std::vector<String>& rTabNames );
+
+ virtual BOOL GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen );
+
+ void GetDummy( const ScTokenArray*& );
+ const ScTokenArray* GetBoolErr( XclBoolError );
+ BOOL GetShrFmla( const ScTokenArray*&, XclImpStream& rStrm, sal_Size nFormulaLen );
+
+#if 0
+ // return = TRUE -> String-Record folgt!
+ static BOOL SetCurVal( ScFormulaCell& rCell, double& rCurVal );
+#endif
+ static void SetError( ScFormulaCell& rCell, const ConvErr eErr );
+
+ static inline BOOL IsComplColRange( const UINT16 nCol1, const UINT16 nCol2 );
+ static inline BOOL IsComplRowRange( const UINT16 nRow1, const UINT16 nRow2 );
+
+ void SetComplCol( ScComplexRefData& );
+ void SetComplRow( ScComplexRefData& );
+
+ void ReadExtensions( const ExtensionTypeVec& rExtensions,
+ XclImpStream& aIn );
+ void ReadExtensionArray( unsigned int n,
+ XclImpStream& aIn );
+ void ReadExtensionNlr( XclImpStream& aIn );
+ void ReadExtensionMemArea( XclImpStream& aIn );
+};
+
+
+inline BOOL ExcelToSc::IsComplColRange( const UINT16 nCol1, const UINT16 nCol2 )
+{
+ return ( nCol1 == 0x00 ) && ( nCol2 == 0xFF );
+}
+
+
+inline BOOL ExcelToSc::IsComplRowRange( const UINT16 nRow1, const UINT16 nRow2 )
+{
+ return ( ( nRow1 & 0x3FFF ) == 0x0000 ) && ( ( nRow2 & 0x3FFF ) == 0x3FFF );
+}
+
+// ============================================================================
+
+class XclImpLinkManager;
+
+class ExcelToSc8 : public ExcelToSc
+{
+public:
+
+ struct ExternalTabInfo
+ {
+ String maTabName;
+ sal_uInt16 mnFileId;
+ bool mbExternal;
+
+ ExternalTabInfo();
+ };
+
+private:
+ const XclImpLinkManager& rLinkMan;
+
+ void ExcRelToScRel8( UINT16 nRow, UINT16 nCol, ScSingleRefData&,
+ const BOOL bName );
+
+ bool GetExternalFileIdFromXti( UINT16 nIxti, sal_uInt16& rFileId ) const;
+
+ virtual bool Read3DTabReference( UINT16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );
+
+public:
+ ExcelToSc8( const XclImpRoot& rRoot );
+ virtual ~ExcelToSc8();
+
+ virtual ConvErr Convert( const ScTokenArray*& rpTokArray, XclImpStream& rStrm, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const String& rUrl, const ::std::vector<String>& rTabNames );
+
+ static inline BOOL IsComplRowRange( const UINT16 nRow1, const UINT16 nRow2 );
+
+ virtual BOOL GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen );
+};
+
+
+inline BOOL ExcelToSc8::IsComplRowRange( const UINT16 nRow1, const UINT16 nRow2 )
+{
+ return ( nRow1 == 0x0000 ) && ( nRow2 == 0xFFFF );
+}
+
+
+
+
+
+#endif
diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx
new file mode 100644
index 000000000000..7e4cca15dfe1
--- /dev/null
+++ b/sc/source/filter/inc/excimp8.hxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCIMP8_HXX
+#define SC_EXCIMP8_HXX
+
+#include <string.h>
+#include "imp_op.hxx"
+#include "root.hxx"
+#include "excscen.hxx"
+#include "excdefs.hxx"
+#include "ftools.hxx"
+#include "queryparam.hxx"
+
+class SotStorage;
+
+class ScBaseCell;
+class ScRangeList;
+class ScDBData;
+
+class ScfSimpleProgressBar;
+
+class XclImpStream;
+
+
+
+class ImportExcel8 : public ImportExcel
+{
+public:
+ ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm );
+ virtual ~ImportExcel8( void );
+
+ virtual FltError Read( void );
+
+protected:
+ ExcScenarioList aScenList;
+
+ void Calccount( void ); // 0x0C
+ void Precision( void ); // 0x0E
+ void Delta( void ); // 0x10
+ void Iteration( void ); // 0x11
+ void Boundsheet( void ); // 0x85
+ void FilterMode( void ); // 0x9B
+ void AutoFilterInfo( void ); // 0x9D
+ void AutoFilter( void ); // 0x9E
+ void Scenman( void ); // 0xAE
+ void Scenario( void ); // 0xAF
+ void ReadBasic( void ); // 0xD3
+ void Labelsst( void ); // 0xFD
+
+ void Hlink( void ); // 0x01B8
+ void Codename( BOOL bWBGlobals ); // 0x01BA
+ void SheetProtection( void ); // 0x0867
+
+ virtual void EndSheet( void );
+ virtual void PostDocLoad( void );
+
+private:
+ void LoadDocumentProperties();
+};
+
+
+
+//___________________________________________________________________
+// classes AutoFilterData, AutoFilterBuffer
+
+class XclImpAutoFilterData : private ExcRoot
+{
+private:
+ ScDBData* pCurrDBData;
+ ScQueryParam aParam;
+ SCSIZE nFirstEmpty;
+ BOOL bActive;
+ BOOL bHasConflict;
+ BOOL bCriteria;
+ BOOL bAutoOrAdvanced;
+ ScRange aCriteriaRange;
+ String aFilterName;
+
+ void CreateFromDouble( String& rStr, double fVal );
+ void SetCellAttribs();
+ void InsertQueryParam();
+ void AmendAFName(const BOOL bUseUnNamed);
+
+protected:
+public:
+ XclImpAutoFilterData(
+ RootData* pRoot,
+ const ScRange& rRange,
+ const String& rName );
+
+ inline bool IsActive() const { return bActive; }
+ inline bool IsFiltered() const { return bAutoOrAdvanced; }
+ inline SCTAB Tab() const { return aParam.nTab; }
+ inline SCCOL StartCol() const { return aParam.nCol1; }
+ inline SCROW StartRow() const { return aParam.nRow1; }
+ inline SCCOL EndCol() const { return aParam.nCol2; }
+ inline SCROW EndRow() const { return aParam.nRow2; }
+
+ void ReadAutoFilter( XclImpStream& rStrm );
+
+ inline void Activate() { bActive = TRUE; }
+ void SetAdvancedRange( const ScRange* pRange );
+ void SetExtractPos( const ScAddress& rAddr );
+ inline void SetAutoOrAdvanced() { bAutoOrAdvanced = TRUE; }
+ void Apply( const BOOL bUseUnNamed = FALSE );
+ void CreateScDBData( const BOOL bUseUnNamed );
+ void EnableRemoveFilter();
+};
+
+
+class XclImpAutoFilterBuffer : private List
+{
+private:
+ using List::Insert;
+
+ UINT16 nAFActiveCount;
+
+ inline XclImpAutoFilterData* _First() { return (XclImpAutoFilterData*) List::First(); }
+ inline XclImpAutoFilterData* _Next() { return (XclImpAutoFilterData*) List::Next(); }
+
+ inline void Append( XclImpAutoFilterData* pData )
+ { List::Insert( pData, LIST_APPEND ); }
+protected:
+public:
+ XclImpAutoFilterBuffer();
+ virtual ~XclImpAutoFilterBuffer();
+
+ void Insert( RootData* pRoot, const ScRange& rRange,
+ const String& rName );
+ void AddAdvancedRange( const ScRange& rRange );
+ void AddExtractPos( const ScRange& rRange );
+ void Apply();
+
+ XclImpAutoFilterData* GetByTab( SCTAB nTab );
+ inline void IncrementActiveAF() { nAFActiveCount++; }
+ inline BOOL UseUnNamed() { return nAFActiveCount == 1; }
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
new file mode 100644
index 000000000000..bc960f05b3a5
--- /dev/null
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -0,0 +1,506 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCRECDS_HXX
+#define SC_EXCRECDS_HXX
+
+#include <tools/solar.h>
+#include <svl/zforlist.hxx>
+#include <tools/string.hxx>
+#include <vcl/vclenum.hxx>
+#include <tools/color.hxx>
+
+
+#include <vector>
+#include "olinetab.hxx"
+#include "filter.hxx"
+#include "rangelst.hxx"
+#include "xerecord.hxx"
+#include "xeroot.hxx"
+#include "xeformula.hxx"
+#include "xestring.hxx"
+#include "root.hxx"
+#include "excdefs.hxx"
+#include "cell.hxx"
+
+//------------------------------------------------------------------ Forwards -
+
+class SvxBorderLine;
+
+class SvStream;
+class Font;
+class List;
+class ScPatternAttr;
+class ScTokenArray;
+class ScRangeData;
+class ScDBData;
+class ScEditCell;
+class SfxItemSet;
+class EditTextObject;
+class ScPageHFItem;
+class ScProgress;
+
+class ExcTable;
+
+//----------------------------------------------------------- class ExcRecord -
+
+class ExcRecord : public XclExpRecord
+{
+public:
+ virtual void Save( XclExpStream& rStrm );
+
+ virtual UINT16 GetNum() const = 0;
+ virtual sal_Size GetLen() const = 0;
+
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+private:
+ /** Writes the body of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+
+//--------------------------------------------------------- class ExcEmptyRec -
+
+class ExcEmptyRec : public ExcRecord
+{
+private:
+protected:
+public:
+ virtual void Save( XclExpStream& rStrm );
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+//------------------------------------------------------- class ExcRecordList -
+
+class ExcRecordList : protected List, public ExcEmptyRec
+{
+private:
+protected:
+public:
+ virtual ~ExcRecordList();
+
+ using List::Count;
+
+ inline ExcRecord* First( void ) { return ( ExcRecord* ) List::First(); }
+ inline ExcRecord* Next( void ) { return ( ExcRecord* ) List::Next(); }
+
+ inline void Append( ExcRecord* pNew ) { if( pNew ) List::Insert( pNew, LIST_APPEND ); }
+ inline const ExcRecord* Get( UINT32 nNum ) const { return ( ExcRecord* ) List::GetObject( nNum ); }
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+
+//--------------------------------------------------------- class ExcDummyRec -
+
+class ExcDummyRec : public ExcRecord
+{
+protected:
+public:
+ virtual void Save( XclExpStream& rStrm );
+ virtual UINT16 GetNum() const;
+ virtual const BYTE* GetData() const = 0; // byte data must contain header and body
+};
+
+
+//------------------------------------------------------- class ExcBoolRecord -
+// stores BOOL as 16bit val ( 0x0000 | 0x0001 )
+
+class ExcBoolRecord : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+protected:
+ BOOL bVal;
+
+ inline ExcBoolRecord() : bVal( FALSE ) {}
+
+public:
+ inline ExcBoolRecord( const BOOL bDefault ) : bVal( bDefault ) {}
+
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//--------------------------------------------------------- class ExcBof_Base -
+
+class ExcBof_Base : public ExcRecord
+{
+private:
+protected:
+ UINT16 nDocType;
+ UINT16 nVers;
+ UINT16 nRupBuild;
+ UINT16 nRupYear;
+public:
+ ExcBof_Base( void );
+};
+
+
+//-------------------------------------------------------------- class ExcBof -
+// Header Record fuer WORKSHEETS
+
+class ExcBof : public ExcBof_Base
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ ExcBof( void );
+
+ virtual UINT16 GetNum( void ) const;
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//------------------------------------------------------------- class ExcBofW -
+// Header Record fuer WORKBOOKS
+
+class ExcBofW : public ExcBof_Base
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ ExcBofW( void );
+
+ virtual UINT16 GetNum( void ) const;
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//-------------------------------------------------------------- class ExcEof -
+
+class ExcEof : public ExcRecord
+{
+private:
+public:
+ virtual UINT16 GetNum( void ) const;
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//--------------------------------------------------------- class ExcDummy_00 -
+// INTERFACEHDR to FNGROUPCOUNT (see excrecds.cxx)
+
+class ExcDummy_00 : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const BYTE* GetData( void ) const;
+};
+
+// EXC_ID_WINDOWPROTECTION
+class XclExpWindowProtection : public XclExpBoolRecord
+{
+ public:
+ XclExpWindowProtection(bool bValue);
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// EXC_ID_PROTECT Document Protection
+class XclExpProtection : public XclExpBoolRecord
+{
+ public:
+ XclExpProtection(bool bValue);
+};
+
+class XclExpPassHash : public XclExpRecord
+{
+public:
+ XclExpPassHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aHash);
+ virtual ~XclExpPassHash();
+
+private:
+ virtual void WriteBody(XclExpStream& rStrm);
+
+private:
+ sal_uInt16 mnHash;
+};
+
+
+//-------------------------------------------------------- class ExcDummy_04x -
+// PASSWORD to BOOKBOOL (see excrecds.cxx), no 1904
+
+class ExcDummy_040 : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const BYTE* GetData( void ) const;
+};
+
+
+
+class ExcDummy_041 : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const BYTE* GetData( void ) const;
+};
+
+
+//------------------------------------------------------------- class Exc1904 -
+
+class Exc1904 : public ExcBoolRecord
+{
+public:
+ Exc1904( ScDocument& rDoc );
+ virtual UINT16 GetNum( void ) const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+//------------------------------------------------------ class ExcBundlesheet -
+
+class ExcBundlesheetBase : public ExcRecord
+{
+protected:
+ sal_Size nStrPos;
+ sal_Size nOwnPos; // Position NACH # und Len
+ UINT16 nGrbit;
+ SCTAB nTab;
+
+ ExcBundlesheetBase();
+
+public:
+ ExcBundlesheetBase( RootData& rRootData, SCTAB nTab );
+
+ inline void SetStreamPos( sal_Size nNewStrPos ) { nStrPos = nNewStrPos; }
+ void UpdateStreamPos( XclExpStream& rStrm );
+
+ virtual UINT16 GetNum() const;
+};
+
+
+
+class ExcBundlesheet : public ExcBundlesheetBase
+{
+private:
+ ByteString aName;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ ExcBundlesheet( RootData& rRootData, SCTAB nTab );
+ virtual sal_Size GetLen() const;
+};
+
+//--------------------------------------------------------- class ExcDummy_02 -
+// sheet dummies: CALCMODE to SETUP
+
+class ExcDummy_02a : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const BYTE* GetData( void ) const;
+};
+
+
+// ----------------------------------------------------------------------------
+
+/** This record contains the Windows country IDs for the UI and document language. */
+class XclExpCountry : public XclExpRecord
+{
+public:
+ explicit XclExpCountry( const XclExpRoot& rRoot );
+
+private:
+ sal_uInt16 mnUICountry; /// The UI country ID.
+ sal_uInt16 mnDocCountry; /// The document country ID.
+
+ /** Writes the body of the COUNTRY record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+
+// XclExpWsbool ===============================================================
+
+class XclExpWsbool : public XclExpUInt16Record
+{
+public:
+ explicit XclExpWsbool( bool bFitToPages, SCTAB nScTab = -1, XclExpFilterManager* pManager = NULL );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ SCTAB mnScTab;
+ XclExpFilterManager* mpManager;
+};
+
+
+// ============================================================================
+
+class XclExpFiltermode : public XclExpEmptyRecord
+{
+public:
+ explicit XclExpFiltermode();
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpAutofilterinfo : public XclExpUInt16Record
+{
+public:
+ explicit XclExpAutofilterinfo( const ScAddress& rStartPos, SCCOL nScCol );
+
+ inline const ScAddress GetStartPos() const { return maStartPos; }
+ inline SCCOL GetColCount() const { return static_cast< SCCOL >( GetValue() ); }
+
+private:
+ ScAddress maStartPos;
+};
+
+// ----------------------------------------------------------------------------
+
+class ExcFilterCondition
+{
+private:
+ UINT8 nType;
+ UINT8 nOper;
+ double fVal;
+ XclExpString* pText;
+
+protected:
+public:
+ ExcFilterCondition();
+ ~ExcFilterCondition();
+
+ inline BOOL IsEmpty() const { return (nType == EXC_AFTYPE_NOTUSED); }
+ inline BOOL HasEqual() const { return (nOper == EXC_AFOPER_EQUAL); }
+ ULONG GetTextBytes() const;
+
+ void SetCondition( UINT8 nTp, UINT8 nOp, double fV, String* pT );
+
+ void Save( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+ void SaveText( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpAutofilter : public XclExpRecord, protected XclExpRoot
+{
+private:
+ UINT16 nCol;
+ UINT16 nFlags;
+ ExcFilterCondition aCond[ 2 ];
+
+ BOOL AddCondition( ScQueryConnect eConn, UINT8 nType,
+ UINT8 nOp, double fVal, String* pText,
+ BOOL bSimple = FALSE );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+protected:
+public:
+ XclExpAutofilter( const XclExpRoot& rRoot, UINT16 nC );
+
+ inline UINT16 GetCol() const { return nCol; }
+ inline BOOL HasCondition() const { return !aCond[ 0 ].IsEmpty(); }
+ inline BOOL HasTop10() const { return ::get_flag( nFlags, EXC_AFFLAG_TOP10 ); }
+
+ BOOL AddEntry( const ScQueryEntry& rEntry );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class ExcAutoFilterRecs : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab );
+ virtual ~ExcAutoFilterRecs();
+
+ void AddObjRecs();
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ bool HasFilterMode() const;
+
+private:
+ XclExpAutofilter* GetByCol( SCCOL nCol ); // always 0-based
+ BOOL IsFiltered( SCCOL nCol );
+
+private:
+ typedef XclExpRecordList< XclExpAutofilter > XclExpAutofilterList;
+ typedef XclExpAutofilterList::RecordRefType XclExpAutofilterRef;
+
+ XclExpAutofilterList maFilterList;
+ XclExpFiltermode* pFilterMode;
+ XclExpAutofilterinfo* pFilterInfo;
+ ScRange maRef;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Sheet filter manager. Contains auto filters or advanced filters from all sheets. */
+class XclExpFilterManager : protected XclExpRoot
+{
+public:
+ explicit XclExpFilterManager( const XclExpRoot& rRoot );
+
+ /** Creates the filter records for the specified sheet.
+ @descr Creates and inserts related built-in NAME records. Therefore this
+ function is called from the name buffer itself. */
+ void InitTabFilter( SCTAB nScTab );
+
+ /** Returns a record object containing all filter records for the specified sheet. */
+ XclExpRecordRef CreateRecord( SCTAB nScTab );
+
+ /** Returns whether or not FilterMode is present */
+ bool HasFilterMode( SCTAB nScTab );
+
+private:
+ using XclExpRoot::CreateRecord;
+
+ typedef ScfRef< ExcAutoFilterRecs > XclExpTabFilterRef;
+ typedef ::std::map< SCTAB, XclExpTabFilterRef > XclExpTabFilterMap;
+
+ XclExpTabFilterMap maFilterMap;
+};
+
+
+#endif
+
diff --git a/sc/source/filter/inc/excscen.hxx b/sc/source/filter/inc/excscen.hxx
new file mode 100644
index 000000000000..125f74e9fa54
--- /dev/null
+++ b/sc/source/filter/inc/excscen.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCSCEN_HXX
+#define SC_EXCSCEN_HXX
+
+#include <tools/solar.h>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+
+
+struct RootData;
+class XclImpRoot;
+class XclImpStream;
+class ScDocument;
+
+
+
+class ExcScenarioCell
+{
+private:
+ String aValue;
+public:
+ const UINT16 nCol;
+ const UINT16 nRow;
+
+ ExcScenarioCell( const UINT16 nC, const UINT16 nR );
+ void SetValue( const String& rVal );
+ inline const String& GetValue( void ) const;
+};
+
+
+
+
+class ExcScenario : protected List
+{
+private:
+ friend class ExcScenarioList;
+protected:
+ String* pName;
+ String* pComment;
+ String* pUserName;
+ UINT8 nProtected;
+
+ const UINT16 nTab;
+
+ void Apply( const XclImpRoot& rRoot, const BOOL bLast = FALSE );
+public:
+ ExcScenario( XclImpStream& rIn, const RootData& rRoot );
+ virtual ~ExcScenario();
+};
+
+
+
+
+class ExcScenarioList : protected List
+{
+private:
+ UINT16 nLastScenario;
+ inline ExcScenario* _First( void ) { return ( ExcScenario* ) List::First(); }
+ inline ExcScenario* _Next( void ) { return ( ExcScenario* ) List::Next(); }
+ inline ExcScenario* _Last( void ) { return ( ExcScenario* ) List::Last(); }
+ inline ExcScenario* _Prev( void ) { return ( ExcScenario* ) List::Prev(); }
+protected:
+public:
+ ExcScenarioList( void );
+ virtual ~ExcScenarioList();
+
+ inline void Append( ExcScenario* pNew );
+
+ inline void SetLast( const UINT16 nIndex4Last );
+
+ inline const ExcScenario* First( void );
+ inline const ExcScenario* Next( void );
+
+ using List::Count;
+
+ void Apply( const XclImpRoot& rRoot );
+};
+
+
+
+
+inline const String& ExcScenarioCell::GetValue( void ) const
+{
+ return aValue;
+}
+
+
+
+
+inline ExcScenarioList::ExcScenarioList( void )
+{
+ nLastScenario = 0;
+}
+
+
+inline void ExcScenarioList::Append( ExcScenario* p )
+{
+ List::Insert( p, LIST_APPEND );
+}
+
+
+inline const ExcScenario* ExcScenarioList::First( void )
+{
+ return ( const ExcScenario* ) List::First();
+}
+
+
+inline const ExcScenario* ExcScenarioList::Next( void )
+{
+ return ( const ExcScenario* ) List::Next();
+}
+
+
+inline void ExcScenarioList::SetLast( const UINT16 n )
+{
+ nLastScenario = n;
+}
+
+
+#endif
+
diff --git a/sc/source/filter/inc/exp_op.hxx b/sc/source/filter/inc/exp_op.hxx
new file mode 100644
index 000000000000..79fff8675d84
--- /dev/null
+++ b/sc/source/filter/inc/exp_op.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXP_OP_HXX
+#define SC_EXP_OP_HXX
+
+#include "filter.hxx"
+#include "root.hxx"
+#include "xeroot.hxx"
+
+
+class ScDocument;
+class ScPatternAttr;
+class ScFormulaCell;
+class ExcDocument;
+class SotStorage;
+
+
+class ExportTyp
+{
+protected:
+ SvStream& aOut; // Ausgabe-Stream
+ ScDocument* pD; // Dokument
+ CharSet eZielChar; // Ziel-Zeichensatz
+public:
+ ExportTyp( SvStream& aStream, ScDocument* pDoc, CharSet eDest ):
+ aOut( aStream )
+ {
+ eZielChar = eDest;
+ pD = pDoc;
+ }
+
+ virtual FltError Write() = 0;
+};
+
+
+
+#if ENABLE_LOTUS123_EXPORT
+class ExportWK1 : public ExportTyp
+{
+private:
+ BYTE GenFormByte( const ScPatternAttr& );
+ void Bof();
+ void Eof();
+ void Calcmode();
+ void Calcorder();
+ void Split();
+ void Sync();
+ void Dimensions();
+ void Window1();
+ void Colw();
+ void Blank( const UINT16 nC, const UINT16 nR, const ScPatternAttr& );
+ void Number( const UINT16 nC, const UINT16 nR, const double f, const ScPatternAttr& );
+ void Label( const UINT16 nC, const UINT16 nR, const String&, const ScPatternAttr& );
+ void Formula( const UINT16 nC, const UINT16 nR, const ScFormulaCell*, const ScPatternAttr& );
+ void Protect();
+ void Footer();
+ void Header();
+ void Margins();
+ void Labelfmt();
+ void Calccount();
+ void Cursorw12();
+ void WKString( const UINT16 nC, const UINT16 nR, const ScFormulaCell*, const ScPatternAttr& );
+ void Snrange();
+ void Hidcol();
+ void Cpi();
+public:
+
+ static const USHORT WK1MAXCOL;
+ static const USHORT WK1MAXROW;
+
+ inline ExportWK1( SvStream& r, ScDocument* p, CharSet e ) :
+ ExportTyp( r, p, e ) {};
+
+ FltError Write();
+};
+#endif
+
+
+
+class ExportBiff5 : public ExportTyp, protected XclExpRoot
+{
+private:
+ ExcDocument* pExcDoc;
+
+protected:
+ RootData* pExcRoot;
+
+public:
+ ExportBiff5( XclExpRootData& rExpData, SvStream& rStrm );
+ virtual ~ExportBiff5();
+ FltError Write();
+};
+
+
+
+
+class ExportBiff8 : public ExportBiff5
+{
+public:
+ ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm );
+ virtual ~ExportBiff8();
+};
+
+
+class ExportXml2007 : public ExportTyp, protected XclExpRoot
+{
+private:
+ ExcDocument* pExcDoc;
+
+protected:
+ RootData* pExcRoot;
+
+public:
+ ExportXml2007( XclExpRootData& rExpData, SvStream& rStrm );
+ virtual ~ExportXml2007();
+ FltError Write();
+};
+
+
+#endif
+
+
diff --git a/sc/source/filter/inc/expbase.hxx b/sc/source/filter/inc/expbase.hxx
new file mode 100644
index 000000000000..3744bf497927
--- /dev/null
+++ b/sc/source/filter/inc/expbase.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXPBASE_HXX
+#define SC_EXPBASE_HXX
+
+#include <tools/solar.h>
+#include "global.hxx"
+#include "address.hxx"
+
+
+class SvStream;
+class ScFieldEditEngine;
+
+class ScExportBase
+{
+public:
+#if defined UNX
+ static const sal_Char __FAR_DATA sNewLine;
+#else
+ static const sal_Char __FAR_DATA sNewLine[];
+#endif
+
+protected:
+
+ SvStream& rStrm;
+ ScRange aRange;
+ ScDocument* pDoc;
+ SvNumberFormatter* pFormatter;
+ ScFieldEditEngine* pEditEngine;
+
+public:
+
+ ScExportBase( SvStream&, ScDocument*, const ScRange& );
+ virtual ~ScExportBase();
+
+ // Hidden Cols/Rows an den Raendern trimmen,
+ // return: TRUE wenn Bereich vorhanden
+ // Start/End/Col/Row muessen gueltige Ausgangswerte sein
+ BOOL TrimDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const;
+
+ // Ausgabebereich einer Tabelle ermitteln,
+ // Hidden Cols/Rows an den Raendern beruecksichtigt,
+ // return: TRUE wenn Bereich vorhanden
+ BOOL GetDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const;
+
+ // Tabelle nicht vorhanden oder leer
+ BOOL IsEmptyTable( SCTAB nTab ) const;
+
+ ScFieldEditEngine& GetEditEngine() const;
+
+};
+
+
+#endif // SC_EXPBASE_HXX
+
diff --git a/sc/source/filter/inc/fapihelper.hxx b/sc/source/filter/inc/fapihelper.hxx
new file mode 100644
index 000000000000..8c204f1cef35
--- /dev/null
+++ b/sc/source/filter/inc/fapihelper.hxx
@@ -0,0 +1,352 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FAPIHELPER_HXX
+#define SC_FAPIHELPER_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <tools/color.hxx>
+#include <comphelper/types.hxx>
+#include "ftools.hxx"
+#include "scdllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace comphelper { class IDocPasswordVerifier; }
+
+// Static helper functions ====================================================
+
+class SfxMedium;
+class SfxObjectShell;
+
+/** Static API helper functions. */
+class ScfApiHelper
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > XInterfaceRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > XServiceFactoryRef;
+ typedef ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > UnoAnySequence;
+
+public:
+ /** Converts a tools color to a UNO color value. */
+ inline static sal_Int32 ConvertToApiColor( const Color& rColor )
+ { return static_cast< sal_Int32 >( rColor.GetColor() ); }
+ /** Converts a UNO color value to a tools color. */
+ inline static Color ConvertFromApiColor( sal_Int32 nApiColor )
+ { return Color( static_cast< ColorData >( nApiColor ) ); }
+
+ /** Converts a non-empty vector into a UNO sequence containing elements of the same type. */
+ template< typename Type >
+ static ::com::sun::star::uno::Sequence< Type >
+ VectorToSequence( const ::std::vector< Type >& rVector );
+
+ /** Returns the service name provided via the XServiceName interface, or an empty string on error. */
+ static ::rtl::OUString GetServiceName( XInterfaceRef xInt );
+
+ /** Returns the multi service factory from a document shell. */
+ static XServiceFactoryRef GetServiceFactory( SfxObjectShell* pShell );
+
+ /** Creates an instance from the passed service name, using the passed service factory. */
+ static XInterfaceRef CreateInstance(
+ XServiceFactoryRef xFactory,
+ const ::rtl::OUString& rServiceName );
+
+ /** Creates an instance from the passed service name, using the service factory of the passed object. */
+ static XInterfaceRef CreateInstance(
+ SfxObjectShell* pShell,
+ const ::rtl::OUString& rServiceName );
+
+ /** Creates an instance from the passed service name, using the process service factory. */
+ static XInterfaceRef CreateInstance( const ::rtl::OUString& rServiceName );
+
+ /** Creates an instance from the passed service name, using the passed service factory. */
+ static XInterfaceRef CreateInstanceWithArgs(
+ XServiceFactoryRef xFactory,
+ const ::rtl::OUString& rServiceName,
+ const UnoAnySequence& rArgs );
+
+//UNUSED2008-05 /** Creates an instance from the passed service name, using the service factory of the passed object. */
+//UNUSED2008-05 static XInterfaceRef CreateInstanceWithArgs(
+//UNUSED2008-05 SfxObjectShell* pShell,
+//UNUSED2008-05 const ::rtl::OUString& rServiceName,
+//UNUSED2008-05 const UnoAnySequence& rArgs );
+
+ /** Creates an instance from the passed service name, using the process service factory. */
+ static XInterfaceRef CreateInstanceWithArgs(
+ const ::rtl::OUString& rServiceName,
+ const UnoAnySequence& rArgs );
+
+ /** Opens a password dialog and returns the entered password.
+ @return The entered password or an empty string on 'Cancel' or any error. */
+ static String QueryPasswordForMedium( SfxMedium& rMedium,
+ ::comphelper::IDocPasswordVerifier& rVerifier,
+ const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0 );
+};
+
+template< typename Type >
+::com::sun::star::uno::Sequence< Type > ScfApiHelper::VectorToSequence( const ::std::vector< Type >& rVector )
+{
+ DBG_ASSERT( !rVector.empty(), "ScfApiHelper::VectorToSequence - vector is empty" );
+ return ::com::sun::star::uno::Sequence< Type >( &rVector.front(), static_cast< sal_Int32 >( rVector.size() ) );
+}
+
+// Property sets ==============================================================
+
+/** A wrapper for a UNO property set.
+
+ This class provides functions to silently get and set properties (without
+ exceptions, without the need to check validity of the UNO property set).
+
+ An instance is constructed with the reference to a UNO property set or any
+ other interface (the constructor will query for the XPropertySet interface
+ then). The reference to the property set will be kept as long as the
+ instance of this class is alive.
+
+ The functions GetProperties() and SetProperties() try to handle all passed
+ values at once, using the XMultiPropertySet interface. If the
+ implementation does not support the XMultiPropertySet interface, all
+ properties are handled separately in a loop.
+ */
+class ScfPropertySet
+{
+public:
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > XPropertySetRef;
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XMultiPropertySet > XMultiPropSetRef;
+ typedef ::com::sun::star::uno::Any UnoAny;
+ typedef ::com::sun::star::uno::Sequence< UnoAny > UnoAnySequence;
+ typedef ::com::sun::star::uno::Sequence< ::rtl::OUString > OUStringSequence;
+
+public:
+ inline explicit ScfPropertySet() {}
+ /** Constructs a property set wrapper with the passed UNO property set. */
+ inline explicit ScfPropertySet( XPropertySetRef xPropSet ) { Set( xPropSet ); }
+ /** Constructs a property set wrapper after querying the XPropertySet interface. */
+ template< typename InterfaceType >
+ inline explicit ScfPropertySet( ::com::sun::star::uno::Reference< InterfaceType > xInterface ) { Set( xInterface ); }
+
+ /** Sets the passed UNO property set and releases the old UNO property set. */
+ void Set( XPropertySetRef xPropSet );
+ /** Queries the passed interface for an XPropertySet and releases the old UNO property set. */
+ template< typename InterfaceType >
+ inline void Set( ::com::sun::star::uno::Reference< InterfaceType > xInterface )
+ { Set( XPropertySetRef( xInterface, ::com::sun::star::uno::UNO_QUERY ) ); }
+
+ /** Returns true, if the contained XPropertySet interface is valid. */
+ inline bool Is() const { return mxPropSet.is(); }
+
+ /** Returns the contained XPropertySet interface. */
+ inline XPropertySetRef GetApiPropertySet() const { return mxPropSet; }
+
+ /** Returns the service name provided via the XServiceName interface, or an empty string on error. */
+ ::rtl::OUString GetServiceName() const;
+
+ // Get properties ---------------------------------------------------------
+
+ /** Returns true, if the property set contains the specified property. */
+ bool HasProperty( const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified property from the property set.
+ @return true, if the Any could be filled with the property value. */
+ bool GetAnyProperty( UnoAny& rValue, const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified property from the property set.
+ @return true, if the passed variable could be filled with the property value. */
+ template< typename Type >
+ inline bool GetProperty( Type& rValue, const ::rtl::OUString& rPropName ) const
+ { UnoAny aAny; return GetAnyProperty( aAny, rPropName ) && (aAny >>= rValue); }
+
+ /** Gets the specified Boolean property from the property set.
+ @return true = property contains true; false = property contains false or error occured. */
+ bool GetBoolProperty( const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified Boolean property from the property set.
+ @return true, if the passed Boolean variable could be filled with the property value. */
+ bool GetStringProperty( String& rValue, const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified color property from the property set.
+ @return true, if the passed color variable could be filled with the property value. */
+ bool GetColorProperty( Color& rColor, const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified properties from the property set. Tries to use the XMultiPropertySet interface.
+ @param rPropNames The property names. MUST be ordered alphabetically.
+ @param rValues The related property values. */
+ void GetProperties( UnoAnySequence& rValues, const OUStringSequence& rPropNames ) const;
+
+ // Set properties ---------------------------------------------------------
+
+ /** Puts the passed Any into the property set. */
+ void SetAnyProperty( const ::rtl::OUString& rPropName, const UnoAny& rValue );
+
+ /** Puts the passed value into the property set. */
+ template< typename Type >
+ inline void SetProperty( const ::rtl::OUString& rPropName, const Type& rValue )
+ { SetAnyProperty( rPropName, ::com::sun::star::uno::makeAny( rValue ) ); }
+
+ /** Puts the passed Boolean value into the property set. */
+ inline void SetBoolProperty( const ::rtl::OUString& rPropName, bool bValue )
+ { SetAnyProperty( rPropName, ::comphelper::makeBoolAny( bValue ) ); }
+
+ /** Puts the passed string into the property set. */
+ inline void SetStringProperty( const ::rtl::OUString& rPropName, const String& rValue )
+ { SetProperty( rPropName, ::rtl::OUString( rValue ) ); }
+
+ /** Puts the passed color into the property set. */
+ inline void SetColorProperty( const ::rtl::OUString& rPropName, const Color& rColor )
+ { SetProperty( rPropName, ScfApiHelper::ConvertToApiColor( rColor ) ); }
+
+ /** Puts the passed properties into the property set. Tries to use the XMultiPropertySet interface.
+ @param rPropNames The property names. MUST be ordered alphabetically.
+ @param rValues The related property values. */
+ void SetProperties( const OUStringSequence& rPropNames, const UnoAnySequence& rValues );
+
+ // ------------------------------------------------------------------------
+private:
+ XPropertySetRef mxPropSet; /// The mandatory property set interface.
+ XMultiPropSetRef mxMultiPropSet; /// The optional multi property set interface.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Generic helper class for reading from and writing to property sets.
+
+ Usage:
+ 1) Call the constructor with a null-terminated array of ASCII strings.
+ 2a) Read properties from a property set: Call the ReadFromPropertySet()
+ function, then get the properties with the ReadValue() functions or the
+ operator>> stream operator. The properties are returned in order of the
+ array of property names passed in the constructor.
+ 2b) Write properties to a property set: Call InitializeWrite() to start a
+ new cycle. Set the values with the WriteValue() functions or the
+ operator<< stream operator. The order of the properties is equal to the
+ array of property names passed in the constructor. Finally, call the
+ WriteToPropertySet() function.
+ */
+class ScfPropSetHelper
+{
+public:
+ typedef ::com::sun::star::uno::Any UnoAny;
+
+public:
+ /** @param ppPropNames A null-terminated array of ASCII property names. */
+ explicit ScfPropSetHelper( const sal_Char* const* ppcPropNames );
+
+ // read properties --------------------------------------------------------
+
+ /** Reads all values from the passed property set. */
+ void ReadFromPropertySet( const ScfPropertySet& rPropSet );
+
+ /** Reads the next value from the value sequence. */
+ template< typename Type >
+ bool ReadValue( Type& rValue );
+ /** Reads an Any from the value sequence. */
+ bool ReadValue( UnoAny& rAny );
+ /** Reads a tools string from the value sequence. */
+ bool ReadValue( String& rString );
+ /** Reads a color value from the value sequence. */
+ bool ReadValue( Color& rColor );
+ /** Reads a C++ boolean value from the value sequence. */
+ bool ReadValue( bool& rbValue );
+
+ // write properties -------------------------------------------------------
+
+ /** Must be called before reading or storing property values in the helper. */
+ void InitializeWrite( bool bClearAllAnys = false );
+
+ /** Writes the next value to the value sequence. */
+ template< typename Type >
+ void WriteValue( const Type& rValue );
+ /** Writes an Any to the value sequence. */
+ void WriteValue( const UnoAny& rAny );
+ /** Writes a tools string to the value sequence. */
+ inline void WriteValue( const String& rString )
+ { WriteValue( ::rtl::OUString( rString ) ); }
+ /** Writes a color value to the value sequence. */
+ inline void WriteValue( const Color& rColor )
+ { WriteValue( ScfApiHelper::ConvertToApiColor( rColor ) ); }
+ /** Writes a C++ boolean value to the value sequence. */
+ void WriteValue( const bool& rbValue );
+
+ /** Writes all values to the passed property set. */
+ void WriteToPropertySet( ScfPropertySet& rPropSet ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns a pointer to the next Any to be written to. */
+ UnoAny* GetNextAny();
+
+private:
+ typedef ::com::sun::star::uno::Sequence< ::rtl::OUString > OUStringSequence;
+ typedef ::com::sun::star::uno::Sequence< UnoAny > UnoAnySequence;
+
+ OUStringSequence maNameSeq; /// Sequence of property names.
+ UnoAnySequence maValueSeq; /// Sequence of property values.
+ ScfInt32Vec maNameOrder; /// Maps initial order to alphabetical order.
+ size_t mnNextIdx; /// Counter for next Any to be processed.
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+bool ScfPropSetHelper::ReadValue( Type& rValue )
+{
+ UnoAny* pAny = GetNextAny();
+ return pAny && (*pAny >>= rValue);
+}
+
+template< typename Type >
+void ScfPropSetHelper::WriteValue( const Type& rValue )
+{
+ if( UnoAny* pAny = GetNextAny() )
+ *pAny <<= rValue;
+}
+
+template< typename Type >
+ScfPropSetHelper& operator>>( ScfPropSetHelper& rPropSetHelper, Type& rValue )
+{
+ rPropSetHelper.ReadValue( rValue );
+ return rPropSetHelper;
+}
+
+template< typename Type >
+ScfPropSetHelper& operator<<( ScfPropSetHelper& rPropSetHelper, const Type& rValue )
+{
+ rPropSetHelper.WriteValue( rValue );
+ return rPropSetHelper;
+}
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/filt_pch.hxx b/sc/source/filter/inc/filt_pch.hxx
new file mode 100644
index 000000000000..7ab2aadf1511
--- /dev/null
+++ b/sc/source/filter/inc/filt_pch.hxx
@@ -0,0 +1,321 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ItemID-Defines etc. muessen immer ganz vorne stehen
+
+#include "scitems.hxx"
+
+
+#define _ZFORLIST_DECLARE_TABLE
+
+#define SC_PROGRESS_CXX
+
+// ab hier automatisch per makepch generiert
+// folgende duerfen nicht aufgenommen werden:
+// ...
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+#include <rtl/textenc.h>
+#include <sal/types.h>
+#include <sal/config.h>
+#include <rtl/textcvt.h>
+#include <rtl/string.hxx>
+#include <rtl/string.h>
+#include <rtl/ustring.h>
+#include <rtl/memory.h>
+#include <rtl/ustring.hxx>
+#include <rtl/locale.hxx>
+#include <rtl/locale.h>
+#include <tools/contnr.hxx>
+#include <i18npool/lang.h>
+#include <tools/list.hxx>
+#include <global.hxx>
+#include <tools/stream.hxx>
+#include <tools/errinf.hxx>
+#include <tools/rtti.hxx>
+#include <tools/errcode.hxx>
+#include <tools/ref.hxx>
+#include <tools/link.hxx>
+#include <tools/debug.hxx>
+#include <tools/time.hxx>
+#include <tools/date.hxx>
+#include <svl/svarray.hxx>
+#include <vcl/sv.h>
+#include <vcl/timer.hxx>
+#include <tools/gen.hxx>
+#include <tools/color.hxx>
+#include <tools/color.hxx>
+#include <filter.hxx>
+#include <rangelst.hxx>
+#include <osl/mutex.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <cppu/macros.hxx>
+#include <uno/lbnames.h>
+#include <uno/any2.h>
+#include <uno/data.h>
+#include <typelib/typedescription.h>
+#include <typelib/uik.h>
+#include <typelib/typeclass.h>
+#include <com/sun/star/uno/Type.h>
+#include <com/sun/star/uno/TypeClass.hdl>
+#include <com/sun/star/uno/Type.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <com/sun/star/uno/genfunc.h>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/XInterface.hdl>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/RuntimeException.hdl>
+#include <com/sun/star/uno/Exception.hdl>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <svl/hint.hxx>
+#include <svl/poolitem.hxx>
+#include <document.hxx>
+#include <vcl/prntypes.hxx>
+#include <table.hxx>
+#include <column.hxx>
+#include <markarr.hxx>
+#include <root.hxx>
+#include <flttypes.hxx>
+#include <svl/solar.hrc>
+#include <sfx2/sfxsids.hrc>
+#include <svl/cntwids.hrc>
+#include <sfx2/cntids.hrc>
+#include <tools/mempool.hxx>
+#include <compiler.hxx>
+#include <formula/compiler.hrc>
+#include <sfx2/sfx.hrc>
+#include <scitems.hxx>
+#include <svx/svxids.hrc>
+#include <svl/itemset.hxx>
+#include <svl/memberid.hrc>
+#include <tools/table.hxx>
+#include <flttools.hxx>
+#include <vcl/vclenum.hxx>
+#include <tools/resid.hxx>
+#include <tools/rc.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/fract.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/mapunit.hxx>
+#include <vcl/region.hxx>
+#include <svl/lstner.hxx>
+#include <patattr.hxx>
+#include <vcl/font.hxx>
+#include <svl/cenumitm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/cintitem.hxx>
+#include <svl/brdcst.hxx>
+#include <sot/sotref.hxx>
+#include <tools/globname.hxx>
+#include <sot/factory.hxx>
+#include <sot/object.hxx>
+#include <sot/sotdata.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/alpha.hxx>
+#include <vcl/gdimtf.hxx>
+#include <tools/unqidx.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/animate.hxx>
+#include <vcl/graph.h>
+#include <vcl/gfxlink.hxx>
+#include <rsc/rscsfx.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/accel.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/keycodes.hxx>
+#include <namebuff.hxx>
+#include <tools/shl.hxx>
+#include <tools/pstm.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <vos/types.hxx>
+#include <vos/object.hxx>
+#include <vos/macros.hxx>
+#include <tools/unqid.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <uno/sequence2.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <attrib.hxx>
+#include <svl/zforlist.hxx>
+#include <editeng/fontitem.hxx>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XEventListener.hdl>
+#include <com/sun/star/lang/EventObject.hdl>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <vcl/outdev.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyValue.hdl>
+#include <com/sun/star/beans/PropertyState.hdl>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <collect.hxx>
+#include <vcl/window.hxx>
+#include <vcl/pointr.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/wintypes.hxx>
+#include <vcl/inputctx.hxx>
+#include <vcl/event.hxx>
+#include <tools/ownlist.hxx>
+#include <vcl/cmdevt.hxx>
+#include <vcl/vclenum.hxx>
+#include <cell.hxx>
+#include <osl/interlck.h>
+#include <sfx2/sfxuno.hxx>
+#include <colrowst.hxx>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/URL.hdl>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hdl>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hdl>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XTypeProvider.hdl>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/uuid.h>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/factory.hxx>
+#include <uno/dispatcher.h>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/registry/XRegistryKey.hdl>
+#include <com/sun/star/registry/InvalidRegistryException.hdl>
+#include <com/sun/star/registry/InvalidValueException.hdl>
+#include <com/sun/star/registry/RegistryKeyType.hdl>
+#include <com/sun/star/registry/RegistryValueType.hdl>
+#include <com/sun/star/registry/InvalidRegistryException.hpp>
+#include <com/sun/star/registry/InvalidValueException.hpp>
+#include <com/sun/star/registry/RegistryKeyType.hpp>
+#include <com/sun/star/registry/RegistryValueType.hpp>
+#include <sot/storage.hxx>
+#include <tools/datetime.hxx>
+#include <osl/thread.h>
+#include <imp_op.hxx>
+#include <otlnbuff.hxx>
+#include <tokstack.hxx>
+#include <com/sun/star/container/NoSuchElementException.hdl>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <vcl/svapp.hxx>
+#include <vos/thread.hxx>
+#include <vos/runnable.hxx>
+#include <vos/refernce.hxx>
+#include <vcl/apptypes.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <com/sun/star/lang/WrappedTargetException.hdl>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <sfx2/shell.hxx>
+#include <tools/stack.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XComponent.hdl>
+#include <editeng/svxenum.hxx>
+#include <formel.hxx>
+#include <com/sun/star/container/XElementAccess.hdl>
+#include <com/sun/star/container/XElementAccess.hpp>
+#include <svl/itempool.hxx>
+#include <editeng/eeitem.hxx>
+#include <rangenam.hxx>
+#include <vcl/syswin.hxx>
+#include <svl/smplhint.hxx>
+#include <fontbuff.hxx>
+#include <vcl/ctrl.hxx>
+#include <vcl/field.hxx>
+#include <vcl/spinfld.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/combobox.h>
+#include <vcl/fldunit.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFrame.hdl>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindow.hdl>
+#include <com/sun/star/awt/Rectangle.hdl>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XFocusListener.hdl>
+#include <com/sun/star/awt/FocusEvent.hdl>
+#include <com/sun/star/awt/FocusEvent.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/awt/XKeyListener.hdl>
+#include <com/sun/star/awt/KeyEvent.hdl>
+#include <com/sun/star/awt/InputEvent.hdl>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/InputEvent.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseListener.hdl>
+#include <com/sun/star/awt/MouseEvent.hdl>
+#include <com/sun/star/awt/MouseEvent.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hdl>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hdl>
+#include <com/sun/star/awt/PaintEvent.hdl>
+#include <com/sun/star/awt/PaintEvent.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hdl>
+#include <com/sun/star/awt/WindowEvent.hdl>
+#include <com/sun/star/awt/WindowEvent.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XController.hdl>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModel.hdl>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hdl>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/container/XIndexAccess.hdl>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <excrecds.hxx>
+#include <scerrors.hxx>
+#include <docpool.hxx>
+#include <svx/msdffimp.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hdl>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <tools/urlobj.hxx>
+#include <editeng/colritem.hxx>
+#include <vcl/wrkwin.hxx>
+#include <excimp8.hxx>
+#include <excscen.hxx>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hdl>
+#include <com/sun/star/frame/FrameActionEvent.hdl>
+#include <com/sun/star/frame/FrameAction.hdl>
+#include <com/sun/star/frame/FrameActionEvent.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hdl>
+#include <com/sun/star/frame/XFrames.hpp>
+#include <com/sun/star/frame/XFrames.hdl>
+#include <svx/msdffdef.hxx>
+#include <vcl/image.hxx>
+
+
+
+
diff --git a/sc/source/filter/inc/fkttab.h b/sc/source/filter/inc/fkttab.h
new file mode 100644
index 000000000000..3d834c5cf04d
--- /dev/null
+++ b/sc/source/filter/inc/fkttab.h
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FKTTAB_H
+#define SC_FKTTAB_H
+
+#include "decl.h"
+
+// Prefixes der Operationen
+extern const sal_Char *cPre[ 256 ];
+
+// Infixes der Operationen
+extern const sal_Char *cInf[ 256 ];
+
+// Postfixes der Operationen
+extern const sal_Char *cPost[ 256 ];
+
+// Bearbeitungsfunktion sal_Char *X( sal_Char * )
+extern BEARBFKT *pFkt[ 256 ];
+
+#endif
+
diff --git a/sc/source/filter/inc/flttypes.hxx b/sc/source/filter/inc/flttypes.hxx
new file mode 100644
index 000000000000..0a78889feb8c
--- /dev/null
+++ b/sc/source/filter/inc/flttypes.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FLTTYPES_HXX
+#define SC_FLTTYPES_HXX
+
+enum BiffTyp
+{
+ BiffX = 0x0000,
+ Biff2 = 0x2000, Biff2M = 0x2002, Biff2C = 0x2004,
+ Biff3 = 0x3000, Biff3W = 0x3001, Biff3M = 0x3002, Biff3C = 0x3004,
+ Biff4 = 0x4000, Biff4W = 0x4001, Biff4M = 0x4002, Biff4C = 0x4004,
+ Biff5 = 0x5000, Biff5W = 0x5001, Biff5V = 0x5002, Biff5C = 0x5004, Biff5M4 = 0x5008,
+ Biff8 = 0x8000, Biff8W = 0x8001, Biff8V = 0x8002, Biff8C = 0x8004, Biff8M4 = 0x8008
+};
+
+enum Lotus123Typ
+{
+ Lotus_X,
+ Lotus_WK1,
+ Lotus_WK3,
+ Lotus_WK4,
+ Lotus_FM3
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/formel.hxx b/sc/source/filter/inc/formel.hxx
new file mode 100644
index 000000000000..6c7d4288c372
--- /dev/null
+++ b/sc/source/filter/inc/formel.hxx
@@ -0,0 +1,296 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMEL_HXX
+#define SC_FORMEL_HXX
+
+#include <tools/solar.h>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+#include "tokstack.hxx"
+#include "root.hxx"
+#include <global.hxx>
+#include <compiler.hxx>
+
+
+// ----- forwards --------------------------------------------------------
+
+class XclImpStream;
+class ScTokenArray;
+class ScFormulaCell;
+struct ScSingleRefData;
+struct ScComplexRefData;
+
+
+
+
+//------------------------------------------------------------------------
+
+enum ConvErr
+{
+ ConvOK = 0,
+ ConvErrNi, // nicht implemntierter/unbekannter Opcode aufgetreten
+ ConvErrNoMem, // Fehler beim Speicheranfordern
+ ConvErrExternal,// Add-Ins aus Excel werden nicht umgesetzt
+ ConvErrCount // Nicht alle Bytes der Formel 'erwischt'
+};
+
+
+enum FORMULA_TYPE
+{
+ FT_CellFormula,
+ FT_RangeName,
+ FT_SharedFormula
+};
+
+
+
+
+//--------------------------------------------------------- class ScRangeList -
+
+class _ScRangeList : protected List
+{
+private:
+protected:
+public:
+ virtual ~_ScRangeList();
+ inline void Append( const ScRange& rRange );
+ inline void Append( ScRange* pRange );
+ inline void Append( const ScSingleRefData& rSRD );
+ inline void Append( const ScComplexRefData& rCRD );
+
+ using List::Count;
+ inline BOOL HasRanges( void ) const;
+
+ inline const ScRange* First( void );
+ inline const ScRange* Next( void );
+};
+
+
+inline void _ScRangeList::Append( const ScRange& r )
+{
+ List::Insert( new ScRange( r ), LIST_APPEND );
+}
+
+
+inline void _ScRangeList::Append( ScRange* p )
+{
+ List::Insert( p, LIST_APPEND );
+}
+
+
+inline BOOL _ScRangeList::HasRanges( void ) const
+{
+ return Count() > 0;
+}
+
+
+inline const ScRange* _ScRangeList::First( void )
+{
+ return ( const ScRange* ) List::First();
+}
+
+
+inline const ScRange* _ScRangeList::Next( void )
+{
+ return ( const ScRange* ) List::Next();
+}
+
+
+inline void _ScRangeList::Append( const ScSingleRefData& r )
+{
+ List::Insert( new ScRange( r.nCol, r.nRow, r.nTab ), LIST_APPEND );
+}
+
+
+inline void _ScRangeList::Append( const ScComplexRefData& r )
+{
+ List::Insert( new ScRange( r.Ref1.nCol, r.Ref1.nRow, r.Ref1.nTab,
+ r.Ref2.nCol, r.Ref2.nRow, r.Ref2.nTab ),
+ LIST_APPEND );
+}
+
+
+
+
+//----------------------------------------------------- class ScRangeListTabs -
+
+class _ScRangeListTabs
+{
+private:
+protected:
+ BOOL bHasRanges;
+ _ScRangeList** ppTabLists;
+ _ScRangeList* pAct;
+ UINT16 nAct;
+public:
+ _ScRangeListTabs( void );
+ virtual ~_ScRangeListTabs();
+
+ void Append( ScSingleRefData aSRD, const BOOL bLimit = TRUE );
+ void Append( ScComplexRefData aCRD, const BOOL bLimit = TRUE );
+
+ inline BOOL HasRanges( void ) const;
+
+ const ScRange* First( const UINT16 nTab = 0 );
+ const ScRange* Next( void );
+// const ScRange* NextContinue( void );
+ inline const _ScRangeList* GetActList( void ) const;
+};
+
+
+inline BOOL _ScRangeListTabs::HasRanges( void ) const
+{
+ return bHasRanges;
+}
+
+
+inline const _ScRangeList* _ScRangeListTabs::GetActList( void ) const
+{
+ return pAct;
+}
+
+
+
+
+class ConverterBase
+{
+protected:
+ TokenPool aPool; // User Token + Predefined Token
+ TokenStack aStack;
+ ScAddress aEingPos;
+ ConvErr eStatus;
+ sal_Char* pBuffer; // Universal-Puffer
+ UINT16 nBufferSize; // ...und seine Groesse
+
+ ConverterBase( UINT16 nNewBuffer );
+ virtual ~ConverterBase();
+
+ void Reset();
+
+public:
+ inline SCCOL GetEingabeCol( void ) const { return aEingPos.Col(); }
+ inline SCROW GetEingabeRow( void ) const { return aEingPos.Row(); }
+ inline SCTAB GetEingabeTab( void ) const { return aEingPos.Tab(); }
+ inline ScAddress GetEingPos( void ) const { return aEingPos; }
+};
+
+
+
+class ExcelConverterBase : public ConverterBase
+{
+protected:
+ ExcelConverterBase( UINT16 nNewBuffer );
+ virtual ~ExcelConverterBase();
+
+public:
+ void Reset();
+ void Reset( const ScAddress& rEingPos );
+
+ virtual ConvErr Convert( const ScTokenArray*& rpErg, XclImpStream& rStrm, sal_Size nFormulaLen,
+ bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
+};
+
+
+
+class LotusConverterBase : public ConverterBase
+{
+protected:
+ SvStream& aIn;
+ INT32 nBytesLeft;
+
+ inline void Ignore( const long nSeekRel );
+ inline void Read( sal_Char& nByte );
+ inline void Read( BYTE& nByte );
+ inline void Read( UINT16& nUINT16 );
+ inline void Read( INT16& nINT16 );
+ inline void Read( double& fDouble );
+ inline void Read( UINT32& nUINT32 );
+
+ LotusConverterBase( SvStream& rStr, UINT16 nNewBuffer );
+ virtual ~LotusConverterBase();
+
+public:
+//UNUSED2008-05 void Reset( INT32 nLen );
+//UNUSED2008-05 void Reset( INT32 nLen, const ScAddress& rEingPos );
+ void Reset( const ScAddress& rEingPos );
+
+ virtual ConvErr Convert( const ScTokenArray*& rpErg, INT32& nRest,
+ const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
+
+protected:
+ using ConverterBase::Reset;
+};
+
+
+inline void LotusConverterBase::Ignore( const long nSeekRel )
+{
+ aIn.SeekRel( nSeekRel );
+ nBytesLeft -= nSeekRel;
+}
+
+inline void LotusConverterBase::Read( sal_Char& nByte )
+{
+ aIn >> nByte;
+ nBytesLeft--;
+}
+
+inline void LotusConverterBase::Read( BYTE& nByte )
+{
+ aIn >> nByte;
+ nBytesLeft--;
+}
+
+inline void LotusConverterBase::Read( UINT16& nUINT16 )
+{
+ aIn >> nUINT16;
+ nBytesLeft -= 2;
+}
+
+inline void LotusConverterBase::Read( INT16& nINT16 )
+{
+ aIn >> nINT16;
+ nBytesLeft -= 2;
+}
+
+inline void LotusConverterBase::Read( double& fDouble )
+{
+ aIn >> fDouble;
+ nBytesLeft -= 8;
+}
+
+inline void LotusConverterBase::Read( UINT32& nUINT32 )
+{
+ aIn >> nUINT32;
+ nBytesLeft -= 4;
+}
+
+#endif
+
+
diff --git a/sc/source/filter/inc/fprogressbar.hxx b/sc/source/filter/inc/fprogressbar.hxx
new file mode 100644
index 000000000000..f399d7ea5064
--- /dev/null
+++ b/sc/source/filter/inc/fprogressbar.hxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FPROGRESSBAR_HXX
+#define SC_FPROGRESSBAR_HXX
+
+#include "globstr.hrc"
+#include "ftools.hxx"
+#include "scdllapi.h"
+
+class SfxObjectShell;
+class ScProgress;
+
+// ============================================================================
+
+const sal_Int32 SCF_INV_SEGMENT = -1;
+
+// ============================================================================
+
+/** Progress bar for complex progress representation.
+
+ The progress bar contains one or more segments, each with customable
+ size. Each segment is represented by a unique identifier. While showing the
+ progress bar, several segments can be started simultaneously. The progress
+ bar displays the sum of all started segments on screen.
+
+ It is possible to create a full featured ScfProgressBar object from
+ any segment. This sub progress bar works only on that parent segment, with
+ the effect, that if the sub progress bar reaches 100%, the parent segment is
+ filled completely.
+
+ After adding segments, the progress bar has to be activated. In this step the
+ total size of all segments is calculated. Therefore it is not possible to add
+ more segments from here.
+
+ If a sub progress bar is created from a segment, and the main progress bar
+ has been started (but not the sub progress bar), it is still possible to add
+ segments to the sub progress bar. It is not allowed to get the sub progress bar
+ of a started segment. And it is not allowed to modify the segment containing
+ a sub progress bar directly.
+
+ Following a few code examples, how to use the progress bar.
+
+ Example 1: Simple progress bar (see also ScfSimpleProgressBar below).
+
+ ScfProgressBar aProgress( ... );
+ sal_Int32 nSeg = aProgress.AddSegment( 50 ); // segment with 50 steps (1 step = 2%)
+
+ aProgress.ActivateSegment( nSeg ); // start segment nSeg
+ aProgress.Progress(); // 0->1; display: 2%
+ aProgress.ProgressAbs( 9 ); // 1->9; display: 18%
+
+ Example 2: Progress bar with 2 segments.
+
+ ScfProgressBar aProgress( ... );
+ sal_Int32 nSeg1 = aProgress.AddSegment( 70 ); // segment with 70 steps
+ sal_Int32 nSeg2 = aProgress.AddSegment( 30 ); // segment with 30 steps
+ // both segments: 100 steps (1 step = 1%)
+
+ aProgress.ActivateSegment( nSeg1 ); // start first segment
+ aProgress.Progress(); // 0->1, display: 1%
+ aProgress.Progress( 2 ); // 1->3, display: 3%
+ aProgress.ActivateSegment( nSeg2 ); // start second segment
+ aProgress.Progress( 5 ); // 0->5, display: 8% (5+3 steps)
+ aProgress.ActivateSegment( nSeg1 ); // continue with first segment
+ aProgress.Progress(); // 3->4, display: 9% (5+4 steps)
+
+ Example 3: Progress bar with 2 segments, one contains a sub progress bar.
+
+ ScfProgressBar aProgress( ... );
+ sal_Int32 nSeg1 = aProgress.AddSegment( 75 ); // segment with 75 steps
+ sal_Int32 nSeg2 = aProgress.AddSegment( 25 ); // segment with 25 steps
+ // both segments: 100 steps (1 step = 1%)
+
+ aProgress.ActivateSegment( nSeg1 ); // start first segment
+ aProgress.Progress(); // 0->1, display: 1%
+
+ ScfProgressBar& rSubProgress = aProgress.GetSegmentProgressBar( nSeg2 );
+ // sub progress bar from second segment
+ sal_Int32 nSubSeg = rSubProgress.AddSegment( 5 ); // 5 steps, mapped to second segment
+ // => 1 step = 5 steps in parent = 5%
+
+ rSubProgress.ActivateSegment( nSubSeg ); // start the segment (auto activate parent segment)
+ rSubProgress.Progress(); // 0->1 (0->5 in parent); display: 6% (1+5)
+
+ // not allowed (second segment active): aProgress.Progress();
+ // not allowed (first segment not empty): aProgress.GetSegmentProgressBar( nSeg1 );
+ */
+class ScfProgressBar : ScfNoCopy
+{
+public:
+ explicit ScfProgressBar( SfxObjectShell* pDocShell, const String& rText );
+ explicit ScfProgressBar( SfxObjectShell* pDocShell, USHORT nResId );
+ virtual ~ScfProgressBar();
+
+ /** Adds a new segment to the progress bar.
+ @return the identifier of the segment. */
+ sal_Int32 AddSegment( sal_Size nSize );
+ /** Returns a complete progress bar for the specified segment.
+ @descr The progress bar can be used to create sub segments inside of the
+ segment. Do not delete it (done by root progress bar)!
+ @return A reference to an ScfProgressBar connected to the segment. */
+ ScfProgressBar& GetSegmentProgressBar( sal_Int32 nSegment );
+
+ /** Returns true, if any progress segment has been started. */
+ inline bool IsStarted() const { return mbInProgress; }
+ /** Returns true, if the current progress segment is already full. */
+ bool IsFull() const;
+
+ /** Starts the progress bar or activates another segment. */
+ void ActivateSegment( sal_Int32 nSegment );
+ /** Starts the progress bar (with first segment). */
+ inline void Activate() { ActivateSegment( 0 ); }
+ /** Set current segment to the specified absolute position. */
+ void ProgressAbs( sal_Size nPos );
+ /** Increase current segment by the passed value. */
+ void Progress( sal_Size nDelta = 1 );
+
+private:
+ struct ScfProgressSegment;
+
+ /** Used to create sub progress bars. */
+ explicit ScfProgressBar(
+ ScfProgressBar& rParProgress,
+ ScfProgressSegment* pParSegment );
+
+ /** Initializes all members on construction. */
+ void Init( SfxObjectShell* pDocShell );
+
+ /** Returns the segment specified by list index. */
+ ScfProgressSegment* GetSegment( sal_Int32 nSegment ) const;
+ /** Activates progress bar and sets current segment. */
+ void SetCurrSegment( ScfProgressSegment* pSegment );
+ /** Increases mnTotalPos and calls the system progress bar. */
+ void IncreaseProgressBar( sal_Size nDelta );
+
+private:
+ /** Contains all data of a segment of the progress bar. */
+ struct ScfProgressSegment
+ {
+ typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;
+
+ ScfProgressBarPtr mxProgress; /// Pointer to sub progress bar for this segment.
+ sal_Size mnSize; /// Size of this segment.
+ sal_Size mnPos; /// Current position of this segment.
+
+ explicit ScfProgressSegment( sal_Size nSize );
+ ~ScfProgressSegment();
+ };
+
+ typedef ::std::auto_ptr< ScProgress > ScProgressPtr;
+ typedef ScfDelList< ScfProgressSegment > ScfSegmentList;
+
+ ScfSegmentList maSegments; /// List of progress segments.
+ String maText; /// UI string for system progress.
+
+ ScProgressPtr mxSysProgress; /// System progress bar.
+ SfxObjectShell* mpDocShell; /// The document shell for the progress bar.
+ ScfProgressBar* mpParentProgress; /// Parent progress bar, if this is a segment progress bar.
+ ScfProgressSegment* mpParentSegment; /// Parent segment, if this is a segment progress bar.
+ ScfProgressSegment* mpCurrSegment; /// Current segment for progress.
+
+ sal_Size mnTotalSize; /// Total size of all segments.
+ sal_Size mnTotalPos; /// Sum of positions of all segments.
+ sal_Size mnUnitSize; /// Size between two calls of system progress.
+ sal_Size mnNextUnitPos; /// Limit for next system progress call.
+ sal_Size mnSysProgressScale; /// Additionally scaling factor for system progress.
+ bool mbInProgress; /// true = progress bar started.
+};
+
+// ============================================================================
+
+/** A simplified progress bar with only one segment. */
+class ScfSimpleProgressBar
+{
+public:
+ explicit ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, const String& rText );
+ explicit ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, USHORT nResId );
+
+ /** Set progress bar to the specified position. */
+ inline void ProgressAbs( sal_Size nPos ) { maProgress.ProgressAbs( nPos ); }
+ /** Increase progress bar by 1. */
+ inline void Progress( sal_Size nDelta = 1 ) { maProgress.Progress( nDelta ); }
+
+private:
+ /** Initializes and starts the progress bar. */
+ void Init( sal_Size nSize );
+
+private:
+ ScfProgressBar maProgress; /// The used progress bar.
+};
+
+// ============================================================================
+
+/** A simplified progress bar based on the stream position of an existing stream. */
+class ScfStreamProgressBar
+{
+public:
+//UNUSED2008-05 explicit ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, const String& rText );
+ explicit ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, USHORT nResId = STR_LOAD_DOC );
+
+ /** Sets the progress bar to the current stream position. */
+ void Progress();
+
+private:
+ /** Initializes and starts the progress bar. */
+ void Init( SfxObjectShell* pDocShell, const String& rText );
+
+private:
+ typedef ::std::auto_ptr< ScfSimpleProgressBar > ScfSimpleProgressBarPtr;
+
+ ScfSimpleProgressBarPtr mxProgress; /// The used progress bar.
+ SvStream& mrStrm; /// The used stream.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/ftools.hxx b/sc/source/filter/inc/ftools.hxx
new file mode 100644
index 000000000000..c17aaa70445c
--- /dev/null
+++ b/sc/source/filter/inc/ftools.hxx
@@ -0,0 +1,544 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FTOOLS_HXX
+#define SC_FTOOLS_HXX
+
+#include <vector>
+#include <map>
+#include <limits>
+#include <memory>
+#include <tools/string.hxx>
+#include <tools/list.hxx>
+#include <tools/debug.hxx>
+#include <oox/helper/helper.hxx>
+#include "filter.hxx"
+#include "scdllapi.h"
+
+// Common macros ==============================================================
+
+/** Expands to the size of a STATIC data array. */
+#define STATIC_TABLE_SIZE( array ) (sizeof(array)/sizeof(*(array)))
+/** Expands to a pointer behind the last element of a STATIC data array (like STL end()). */
+#define STATIC_TABLE_END( array ) ((array)+STATIC_TABLE_SIZE(array))
+
+/** Expands to a temporary String, created from an ASCII character array. */
+#define CREATE_STRING( ascii ) String( RTL_CONSTASCII_USTRINGPARAM( ascii ) )
+
+// items and item sets --------------------------------------------------------
+
+/** Expands to the item (with type 'itemtype') with Which-ID 'which'. */
+#define GETITEM( itemset, itemtype, which ) \
+ static_cast< const itemtype & >( (itemset).Get( which ) )
+
+/** Expands to the value (with type 'valuetype') of the item with Which-ID 'which'. */
+#define GETITEMVALUE( itemset, itemtype, which, valuetype ) \
+ static_cast< valuetype >( GETITEM( itemset, itemtype, which ).GetValue() )
+
+/** Expands to the value of the SfxBoolItem with Which-ID 'which'. */
+#define GETITEMBOOL( itemset, which ) \
+ GETITEMVALUE( itemset, SfxBoolItem, which, bool )
+
+// Global static helpers ======================================================
+
+// Value range limit helpers --------------------------------------------------
+
+/** Returns the value, if it is not less than nMin, otherwise nMin. */
+template< typename ReturnType, typename Type >
+inline ReturnType llimit_cast( Type nValue, ReturnType nMin )
+{ return static_cast< ReturnType >( ::std::max< Type >( nValue, nMin ) ); }
+
+/** Returns the value, if it fits into ReturnType, otherwise the minimum value of ReturnType. */
+template< typename ReturnType, typename Type >
+inline ReturnType llimit_cast( Type nValue )
+{ return llimit_cast( nValue, ::std::numeric_limits< ReturnType >::min() ); }
+
+/** Returns the value, if it is not greater than nMax, otherwise nMax. */
+template< typename ReturnType, typename Type >
+inline ReturnType ulimit_cast( Type nValue, ReturnType nMax )
+{ return static_cast< ReturnType >( ::std::min< Type >( nValue, nMax ) ); }
+
+/** Returns the value, if it fits into ReturnType, otherwise the maximum value of ReturnType. */
+template< typename ReturnType, typename Type >
+inline ReturnType ulimit_cast( Type nValue )
+{ return ulimit_cast( nValue, ::std::numeric_limits< ReturnType >::max() ); }
+
+/** Returns the value, if it is not less than nMin and not greater than nMax, otherwise one of the limits. */
+template< typename ReturnType, typename Type >
+inline ReturnType limit_cast( Type nValue, ReturnType nMin, ReturnType nMax )
+{ return static_cast< ReturnType >( ::std::max< Type >( ::std::min< Type >( nValue, nMax ), nMin ) ); }
+
+/** Returns the value, if it fits into ReturnType, otherwise one of the limits of ReturnType. */
+template< typename ReturnType, typename Type >
+inline ReturnType limit_cast( Type nValue )
+{ return limit_cast( nValue, ::std::numeric_limits< ReturnType >::min(), ::std::numeric_limits< ReturnType >::max() ); }
+
+// Read from bitfields --------------------------------------------------------
+
+/** Returns true, if at least one of the bits set in nMask is set in nBitField. */
+template< typename Type >
+inline bool get_flag( Type nBitField, Type nMask )
+{ return (nBitField & nMask) != 0; }
+
+/** Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. */
+template< typename ReturnType, typename Type >
+inline ReturnType get_flagvalue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
+{ return ::get_flag( nBitField, nMask ) ? nSet : nUnset; }
+
+/** Extracts a value from a bit field.
+ @descr Returns in rnRet the data fragment from nBitField, that starts at bit nStartBit
+ (0-based, bit 0 is rightmost) with the width of nBitCount. rnRet will be right-aligned (normalized).
+ For instance: extract_value( n, 0x4321, 8, 4 ) stores 3 in n (value in bits 8-11). */
+template< typename ReturnType, typename Type >
+inline ReturnType extract_value( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
+{ return static_cast< ReturnType >( ((1UL << nBitCount) - 1) & (nBitField >> nStartBit) ); }
+
+// Write to bitfields ---------------------------------------------------------
+
+/** Sets or clears (according to bSet) all set bits of nMask in rnBitField. */
+template< typename Type >
+inline void set_flag( Type& rnBitField, Type nMask, bool bSet = true )
+{ if( bSet ) rnBitField |= nMask; else rnBitField &= ~nMask; }
+
+/** Inserts a value into a bitfield.
+ @descr Inserts the lower nBitCount bits of nValue into rnBitField, starting
+ there at bit nStartBit. Other contents of rnBitField keep unchanged. */
+template< typename Type, typename InsertType >
+void insert_value( Type& rnBitField, InsertType nValue, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
+{
+ unsigned long nMask = ((1UL << nBitCount) - 1);
+ Type nNewValue = static_cast< Type >( nValue & nMask );
+ (rnBitField &= ~(nMask << nStartBit)) |= (nNewValue << nStartBit);
+}
+
+// ============================================================================
+
+/** Deriving from this class prevents copy construction. */
+class ScfNoCopy
+{
+private:
+ ScfNoCopy( const ScfNoCopy& );
+ ScfNoCopy& operator=( const ScfNoCopy& );
+protected:
+ inline ScfNoCopy() {}
+};
+
+// ----------------------------------------------------------------------------
+
+/** Deriving from this class prevents construction in general. */
+class ScfNoInstance : private ScfNoCopy {};
+
+// ============================================================================
+
+/** Simple shared pointer (NOT thread-save, but faster than boost::shared_ptr). */
+template< typename Type >
+class ScfRef
+{
+ template< typename > friend class ScfRef;
+
+public:
+ typedef Type element_type;
+ typedef ScfRef this_type;
+
+ inline explicit ScfRef( element_type* pObj = 0 ) { eat( pObj ); }
+ inline /*implicit*/ ScfRef( const this_type& rRef ) { eat( rRef.mpObj, rRef.mpnCount ); }
+ template< typename Type2 >
+ inline /*implicit*/ ScfRef( const ScfRef< Type2 >& rRef ) { eat( rRef.mpObj, rRef.mpnCount ); }
+ inline ~ScfRef() { rel(); }
+
+ inline void reset( element_type* pObj = 0 ) { rel(); eat( pObj ); }
+ inline this_type& operator=( const this_type& rRef ) { if( this != &rRef ) { rel(); eat( rRef.mpObj, rRef.mpnCount ); } return *this; }
+ template< typename Type2 >
+ inline this_type& operator=( const ScfRef< Type2 >& rRef ) { rel(); eat( rRef.mpObj, rRef.mpnCount ); return *this; }
+
+ inline element_type* get() const { return mpObj; }
+ inline bool is() const { return mpObj != 0; }
+
+ inline element_type* operator->() const { return mpObj; }
+ inline element_type& operator*() const { return *mpObj; }
+
+ inline bool operator!() const { return mpObj == 0; }
+
+private:
+ inline void eat( element_type* pObj, size_t* pnCount = 0 ) { mpObj = pObj; mpnCount = mpObj ? (pnCount ? pnCount : new size_t( 0 )) : 0; if( mpnCount ) ++*mpnCount; }
+ inline void rel() { if( mpnCount && !--*mpnCount ) { DELETEZ( mpObj ); DELETEZ( mpnCount ); } }
+
+private:
+ Type* mpObj;
+ size_t* mpnCount;
+};
+
+template< typename Type >
+inline bool operator==( const ScfRef< Type >& rxRef1, const ScfRef< Type >& rxRef2 )
+{
+ return rxRef1.get() == rxRef2.get();
+}
+
+template< typename Type >
+inline bool operator!=( const ScfRef< Type >& rxRef1, const ScfRef< Type >& rxRef2 )
+{
+ return rxRef1.get() != rxRef2.get();
+}
+
+template< typename Type >
+inline bool operator<( const ScfRef< Type >& rxRef1, const ScfRef< Type >& rxRef2 )
+{
+ return rxRef1.get() < rxRef2.get();
+}
+
+template< typename Type >
+inline bool operator>( const ScfRef< Type >& rxRef1, const ScfRef< Type >& rxRef2 )
+{
+ return rxRef1.get() > rxRef2.get();
+}
+
+template< typename Type >
+inline bool operator<=( const ScfRef< Type >& rxRef1, const ScfRef< Type >& rxRef2 )
+{
+ return rxRef1.get() <= rxRef2.get();
+}
+
+template< typename Type >
+inline bool operator>=( const ScfRef< Type >& rxRef1, const ScfRef< Type >& rxRef2 )
+{
+ return rxRef1.get() >= rxRef2.get();
+}
+
+// ----------------------------------------------------------------------------
+
+/** Template for a map of ref-counted objects with additional accessor functions. */
+template< typename KeyType, typename ObjType >
+class ScfRefMap : public ::std::map< KeyType, ScfRef< ObjType > >
+{
+public:
+ typedef KeyType key_type;
+ typedef ScfRef< ObjType > ref_type;
+ typedef ::std::map< key_type, ref_type > map_type;
+
+ /** Returns true, if the object accossiated to the passed key exists. */
+ inline bool has( key_type nKey ) const
+ {
+ typename map_type::const_iterator aIt = find( nKey );
+ return (aIt != this->end()) && aIt->second.is();
+ }
+
+ /** Returns a reference to the object accossiated to the passed key, or 0 on error. */
+ inline ref_type get( key_type nKey ) const
+ {
+ typename map_type::const_iterator aIt = find( nKey );
+ if( aIt != this->end() ) return aIt->second;
+ return ref_type();
+ }
+};
+
+// ============================================================================
+
+class Color;
+class SfxPoolItem;
+class SfxItemSet;
+class ScStyleSheet;
+class ScStyleSheetPool;
+class SotStorage;
+class SotStorageRef;
+class SotStorageStreamRef;
+class SvStream;
+
+/** Contains static methods used anywhere in the filters. */
+class ScfTools : ScfNoInstance
+{
+public:
+
+// *** common methods *** -----------------------------------------------------
+
+ /** Reads a 10-byte-long-double and converts it to double. */
+ static double ReadLongDouble( SvStream& rStrm );
+ /** Returns system text encoding for byte string conversion. */
+ static rtl_TextEncoding GetSystemTextEncoding();
+ /** Returns a string representing the hexadecimal value of nValue. */
+ static String GetHexStr( sal_uInt16 nValue );
+
+ /** Mixes RGB components with given transparence.
+ @param nTrans Foreground transparence (0x00 == full nFore ... 0x80 = full nBack). */
+ static sal_uInt8 GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans );
+ /** Mixes colors with given transparence.
+ @param nTrans Foreground transparence (0x00 == full rFore ... 0x80 = full rBack). */
+ static Color GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans );
+
+// *** conversion of names *** ------------------------------------------------
+
+ /** Converts a string to a valid Calc defined name or database range name.
+ @descr Defined names in Calc may contain letters, digits (*), underscores, periods (*),
+ colons (*), question marks, and dollar signs.
+ (*) = not allowed at first position. */
+ static void ConvertToScDefinedName( String& rName );
+
+// *** streams and storages *** -----------------------------------------------
+
+ /** Tries to open an existing storage with the specified name in the passed storage (read-only). */
+ static SotStorageRef OpenStorageRead( SotStorageRef xStrg, const String& rStrgName );
+ /** Creates and opens a storage with the specified name in the passed storage (read/write). */
+ static SotStorageRef OpenStorageWrite( SotStorageRef xStrg, const String& rStrgName );
+
+ /** Tries to open an existing stream with the specified name in the passed storage (read-only). */
+ static SotStorageStreamRef OpenStorageStreamRead( SotStorageRef xStrg, const String& rStrmName );
+ /** Creates and opens a stream with the specified name in the passed storage (read/write). */
+ static SotStorageStreamRef OpenStorageStreamWrite( SotStorageRef xStrg, const String& rStrmName );
+
+// *** item handling *** ------------------------------------------------------
+
+ /** Returns true, if the passed item set contains the item.
+ @param bDeep true = Searches in parent item sets too. */
+ static bool CheckItem( const SfxItemSet& rItemSet, USHORT nWhichId, bool bDeep );
+ /** Returns true, if the passed item set contains at least one of the items.
+ @param pnWhichIds Zero-terminated array of Which-IDs.
+ @param bDeep true = Searches in parent item sets too. */
+ static bool CheckItems( const SfxItemSet& rItemSet, const USHORT* pnWhichIds, bool bDeep );
+
+ /** Puts the item into the passed item set.
+ @descr The item will be put into the item set, if bSkipPoolDef is false,
+ or if the item differs from the default pool item.
+ @param rItemSet The destination item set.
+ @param rItem The item to put into the item set.
+ @param nWhichId The Which-ID to set with the item.
+ @param bSkipPoolDef true = Do not put item if it is equal to pool default; false = Always put the item. */
+ static void PutItem(
+ SfxItemSet& rItemSet, const SfxPoolItem& rItem,
+ USHORT nWhichId, bool bSkipPoolDef );
+
+ /** Puts the item into the passed item set.
+ @descr The item will be put into the item set, if bSkipPoolDef is false,
+ or if the item differs from the default pool item.
+ @param rItemSet The destination item set.
+ @param rItem The item to put into the item set.
+ @param bSkipPoolDef true = Do not put item if it is equal to pool default; false = Always put the item. */
+ static void PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, bool bSkipPoolDef );
+
+// *** style sheet handling *** -----------------------------------------------
+
+ /** Creates and returns a cell style sheet and inserts it into the pool.
+ @descr If the style sheet is already in the pool, another unused style name is used.
+ @param bForceName Controls behaviour, if the style already exists:
+ true = Old existing style will be renamed; false = New style gets another name. */
+ static ScStyleSheet& MakeCellStyleSheet(
+ ScStyleSheetPool& rPool,
+ const String& rStyleName, bool bForceName );
+ /** Creates and returns a page style sheet and inserts it into the pool.
+ @descr If the style sheet is already in the pool, another unused style name is used.
+ @param bForceName Controls behaviour, if the style already exists:
+ true = Old existing style will be renamed; false = New style gets another name. */
+ static ScStyleSheet& MakePageStyleSheet(
+ ScStyleSheetPool& rPool,
+ const String& rStyleName, bool bForceName );
+
+// *** byte string import operations *** --------------------------------------
+
+ /** Reads and returns a zero terminted byte string. */
+ static ByteString ReadCString( SvStream& rStrm );
+ /** Reads and returns a zero terminted byte string. */
+ inline static String ReadCString( SvStream& rStrm, rtl_TextEncoding eTextEnc )
+ { return String( ReadCString( rStrm ), eTextEnc ); }
+
+ /** Reads and returns a zero terminted byte string and decreases a stream counter. */
+ static ByteString ReadCString( SvStream& rStrm, sal_Int32& rnBytesLeft );
+ /** Reads and returns a zero terminted byte string and decreases a stream counter. */
+ inline static String ReadCString( SvStream& rStrm, sal_Int32& rnBytesLeft, rtl_TextEncoding eTextEnc )
+ { return String( ReadCString( rStrm, rnBytesLeft ), eTextEnc ); }
+
+ /** Appends a zero terminted byte string. */
+ static void AppendCString( SvStream& rStrm, ByteString& rString );
+ /** Appends a zero terminted byte string. */
+ static void AppendCString( SvStream& rStrm, String& rString, rtl_TextEncoding eTextEnc );
+
+// *** HTML table names <-> named range names *** -----------------------------
+
+ /** Returns the built-in range name for an HTML document. */
+ static const String& GetHTMLDocName();
+ /** Returns the built-in range name for all HTML tables. */
+ static const String& GetHTMLTablesName();
+ /** Returns the built-in range name for an HTML table, specified by table index. */
+ static String GetNameFromHTMLIndex( sal_uInt32 nIndex );
+ /** Returns the built-in range name for an HTML table, specified by table name. */
+ static String GetNameFromHTMLName( const String& rTabName );
+
+ /** Returns true, if rSource is the built-in range name for an HTML document. */
+ static bool IsHTMLDocName( const String& rSource );
+ /** Returns true, if rSource is the built-in range name for all HTML tables. */
+ static bool IsHTMLTablesName( const String& rSource );
+ /** Converts a built-in range name to an HTML table name.
+ @param rSource The string to be determined.
+ @param rName The HTML table name.
+ @return true, if conversion was successful. */
+ static bool GetHTMLNameFromName( const String& rSource, String& rName );
+
+private:
+ /** Returns the prefix for table index names. */
+ static const String& GetHTMLIndexPrefix();
+ /** Returns the prefix for table names. */
+ static const String& GetHTMLNamePrefix();
+};
+
+// Containers =================================================================
+
+typedef ::std::vector< sal_uInt8 > ScfUInt8Vec;
+typedef ::std::vector< sal_Int16 > ScfInt16Vec;
+typedef ::std::vector< sal_uInt16 > ScfUInt16Vec;
+typedef ::std::vector< sal_Int32 > ScfInt32Vec;
+typedef ::std::vector< sal_uInt32 > ScfUInt32Vec;
+typedef ::std::vector< sal_Int64 > ScfInt64Vec;
+typedef ::std::vector< sal_uInt64 > ScfUInt64Vec;
+typedef ::std::vector< String > ScfStringVec;
+
+// ----------------------------------------------------------------------------
+
+/** Template for a list that owns the contained objects.
+ @descr This list stores pointers to objects and deletes the objects itself
+ on destruction. The Clear() method deletes all objects too. */
+template< typename Type > class ScfDelList
+{
+public:
+ inline explicit ScfDelList( USHORT nInitSize = 16, USHORT nResize = 16 ) :
+ maList( nInitSize, nResize ) {}
+ /** Creates a deep copy of the passed list (copy-constructs all contained objects). */
+ inline explicit ScfDelList( const ScfDelList& rSrc ) { *this = rSrc; }
+ virtual ~ScfDelList();
+
+ /** Creates a deep copy of the passed list (copy-constructs all contained objects). */
+ ScfDelList& operator=( const ScfDelList& rSrc );
+
+ inline void Insert( Type* pObj, ULONG nIndex ) { if( pObj ) maList.Insert( pObj, nIndex ); }
+ inline void Append( Type* pObj ) { if( pObj ) maList.Insert( pObj, LIST_APPEND ); }
+ /** Removes the object without deletion. */
+ inline Type* Remove( ULONG nIndex ) { return static_cast< Type* >( maList.Remove( nIndex ) ); }
+ /** Removes and deletes the object. */
+ inline void Delete( ULONG nIndex ) { delete Remove( nIndex ); }
+ /** Exchanges the contained object with the passed, returns the old. */
+ inline Type* Exchange( Type* pObj, ULONG nIndex ) { return static_cast< Type* >( maList.Replace( pObj, nIndex ) ); }
+ /** Replaces (deletes) the contained object. */
+ inline void Replace( Type* pObj, ULONG nIndex ) { delete Exchange( pObj, nIndex ); }
+
+ void Clear();
+ inline ULONG Count() const { return maList.Count(); }
+ inline bool Empty() const { return maList.Count() == 0; }
+
+ inline Type* GetCurObject() const { return static_cast< Type* >( maList.GetCurObject() ); }
+ inline ULONG GetCurPos() const { return maList.GetCurPos(); }
+ inline Type* GetObject( sal_uInt32 nIndex ) const { return static_cast< Type* >( maList.GetObject( nIndex ) ); }
+
+ inline Type* First() const { return static_cast< Type* >( maList.First() ); }
+ inline Type* Last() const { return static_cast< Type* >( maList.Last() ); }
+ inline Type* Next() const { return static_cast< Type* >( maList.Next() ); }
+ inline Type* Prev() const { return static_cast< Type* >( maList.Prev() ); }
+
+private:
+ mutable List maList; /// The base container object.
+};
+
+template< typename Type > ScfDelList< Type >& ScfDelList< Type >::operator=( const ScfDelList& rSrc )
+{
+ Clear();
+ for( const Type* pObj = rSrc.First(); pObj; pObj = rSrc.Next() )
+ Append( new Type( *pObj ) );
+ return *this;
+}
+
+template< typename Type > ScfDelList< Type >::~ScfDelList()
+{
+ Clear();
+}
+
+template< typename Type > void ScfDelList< Type >::Clear()
+{
+ for( Type* pObj = First(); pObj; pObj = Next() )
+ delete pObj;
+ maList.Clear();
+}
+
+// ----------------------------------------------------------------------------
+
+/** Template for a stack that owns the contained objects.
+ @descr This stack stores pointers to objects and deletes the objects
+ itself on destruction. The Clear() method deletes all objects too.
+ The Pop() method removes the top object from stack without deletion. */
+template< typename Type >
+class ScfDelStack : private ScfDelList< Type >
+{
+public:
+ inline ScfDelStack( USHORT nInitSize = 16, USHORT nResize = 16 ) :
+ ScfDelList< Type >( nInitSize, nResize ) {}
+
+ inline void Push( Type* pObj ) { Append( pObj ); }
+ /** Removes the top object without deletion. */
+ inline Type* Pop() { return Remove( Count() - 1 ); }
+
+ inline Type* Top() const { return GetObject( Count() - 1 ); }
+
+ using ScfDelList< Type >::Clear;
+ using ScfDelList< Type >::Count;
+ using ScfDelList< Type >::Empty;
+};
+
+// ----------------------------------------------------------------------------
+class ScFormatFilterPluginImpl : public ScFormatFilterPlugin {
+ public:
+ ScFormatFilterPluginImpl();
+ // various import filters
+ virtual FltError ScImportLotus123( SfxMedium&, ScDocument*, CharSet eSrc = RTL_TEXTENCODING_DONTKNOW );
+ virtual FltError ScImportQuattroPro( SfxMedium &rMedium, ScDocument *pDoc );
+ virtual FltError ScImportExcel( SfxMedium&, ScDocument*, const EXCIMPFORMAT );
+ // eFormat == EIF_AUTO -> passender Filter wird automatisch verwendet
+ // eFormat == EIF_BIFF5 -> nur Biff5-Stream fuehrt zum Erfolg (auch wenn in einem Excel97-Doc)
+ // eFormat == EIF_BIFF8 -> nur Biff8-Stream fuehrt zum Erfolg (nur in Excel97-Docs)
+ // eFormat == EIF_BIFF_LE4 -> nur Nicht-Storage-Dateien _koennen_ zum Erfolg fuehren
+ virtual FltError ScImportStarCalc10( SvStream&, ScDocument* );
+ virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress& rInsPos,
+ const CharSet eSrc = RTL_TEXTENCODING_DONTKNOW, UINT32 nDifOption = SC_DIFOPT_EXCEL );
+ virtual FltError ScImportRTF( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange );
+ virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange,
+ double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE,
+ SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true );
+
+ virtual ScEEAbsImport *CreateRTFImport( ScDocument* pDoc, const ScRange& rRange );
+ virtual ScEEAbsImport *CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, BOOL bCalcWidthHeight );
+ virtual String GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName );
+
+ // various export filters
+#if ENABLE_LOTUS123_EXPORT
+ virtual FltError ScExportLotus123( SvStream&, ScDocument*, ExportFormatLotus, CharSet eDest );
+#endif
+ virtual FltError ScExportExcel5( SfxMedium&, ScDocument*, ExportFormatExcel eFormat, CharSet eDest );
+ virtual FltError ScExportDif( SvStream&, ScDocument*, const ScAddress& rOutPos, const CharSet eDest,
+ UINT32 nDifOption = SC_DIFOPT_EXCEL );
+ virtual FltError ScExportDif( SvStream&, ScDocument*, const ScRange& rRange, const CharSet eDest,
+ UINT32 nDifOption = SC_DIFOPT_EXCEL );
+ virtual FltError ScExportHTML( SvStream&, const String& rBaseURL, ScDocument*, const ScRange& rRange, const CharSet eDest, BOOL bAll,
+ const String& rStreamPath, String& rNonConvertibleChars );
+ virtual FltError ScExportRTF( SvStream&, ScDocument*, const ScRange& rRange, const CharSet eDest );
+};
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/filter/inc/funktion.h b/sc/source/filter/inc/funktion.h
new file mode 100644
index 000000000000..ef8ecabc256a
--- /dev/null
+++ b/sc/source/filter/inc/funktion.h
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUNKTION_H
+#define SC_FUNKTION_H
+
+// Bearbeitungsfunktionen
+void P0( void ); // 0 Parameter
+void P1( void ); // 1 Parameter
+void P2( void ); // 2 Parameter
+void P3( void ); // 3 Parameter
+void P4( void ); // 4 Parameter
+void P5( void ); // 5 Parameter
+void Pn( void ); // n Parameter
+void NI( void ); // nicht implementiert
+void ConstFloat( void ); // 0
+void Variable( void ); // 1
+void LotusRange( void ); // 2
+void FormulaReturn( void ); // 3
+void Klammer( void ); // 4
+void ConstInt( void ); // 5
+void ConstString( void ); // 6
+// ACHTUNG: unbekannte Funktionen -> P0()
+
+#endif
+
diff --git a/sc/source/filter/inc/htmlexp.hxx b/sc/source/filter/inc/htmlexp.hxx
new file mode 100644
index 000000000000..4cdf71b8610d
--- /dev/null
+++ b/sc/source/filter/inc/htmlexp.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HTMLEXP_HXX
+#define SC_HTMLEXP_HXX
+
+#include "global.hxx"
+#include <rtl/textenc.h>
+#include <tools/gen.hxx>
+#include <tools/color.hxx>
+
+#include "expbase.hxx"
+
+
+class ScDocument;
+class SfxItemSet;
+class SdrPage;
+class Graphic;
+class SdrObject;
+class OutputDevice;
+class ScDrawLayer;
+class SvStringsSortDtor;
+class ScEditCell;
+class SvxBorderLine;
+
+struct ScHTMLStyle
+{ // Defaults aus StyleSheet
+ Color aBackgroundColor;
+ String aFontFamilyName;
+ UINT32 nFontHeight; // Item-Value
+ USHORT nFontSizeNumber; // HTML value 1-7
+ BYTE nDefaultScriptType; // Font values are valid for the default script type
+ BOOL bInitialized;
+
+ ScHTMLStyle() : nFontHeight(0), nFontSizeNumber(2), nDefaultScriptType(0),
+ bInitialized(0) {}
+
+ const ScHTMLStyle& operator=( const ScHTMLStyle& r )
+ {
+ aBackgroundColor = r.aBackgroundColor;
+ aFontFamilyName = r.aFontFamilyName;
+ nFontHeight = r.nFontHeight;
+ nFontSizeNumber = r.nFontSizeNumber;
+ nDefaultScriptType = r.nDefaultScriptType;
+ bInitialized = r.bInitialized;
+ return *this;
+ }
+};
+
+struct ScHTMLGraphEntry
+{
+ ScRange aRange; // ueberlagerter Zellbereich
+ Size aSize; // Groesse in Pixeln
+ Size aSpace; // Spacing in Pixeln
+ SdrObject* pObject;
+ BOOL bInCell; // ob in Zelle ausgegeben wird
+ BOOL bWritten;
+
+ ScHTMLGraphEntry( SdrObject* pObj, const ScRange& rRange,
+ const Size& rSize, BOOL bIn, const Size& rSpace ) :
+ aRange( rRange ), aSize( rSize ), aSpace( rSpace ),
+ pObject( pObj ), bInCell( bIn ), bWritten( FALSE ) {}
+};
+
+DECLARE_LIST( ScHTMLGraphList, ScHTMLGraphEntry* )
+
+#define SC_HTML_FONTSIZES 7
+const short nIndentMax = 23;
+
+class ScHTMLExport : public ScExportBase
+{
+ // default HtmlFontSz[1-7]
+ static const USHORT nDefaultFontSize[SC_HTML_FONTSIZES];
+ // HtmlFontSz[1-7] in s*3.ini [user]
+ static USHORT nFontSize[SC_HTML_FONTSIZES];
+ static const char* pFontSizeCss[SC_HTML_FONTSIZES];
+ static const USHORT nCellSpacing;
+ static const sal_Char __FAR_DATA sIndentSource[];
+
+ ScHTMLGraphList aGraphList;
+ ScHTMLStyle aHTMLStyle;
+ String aBaseURL;
+ String aStreamPath;
+ String aCId; // Content-Id fuer Mail-Export
+ OutputDevice* pAppWin; // fuer Pixelei
+ SvStringsSortDtor* pSrcArr; // fuer CopyLocalFileToINet
+ SvStringsSortDtor* pDestArr;
+ String aNonConvertibleChars; // collect nonconvertible characters
+ rtl_TextEncoding eDestEnc;
+ SCTAB nUsedTables;
+ short nIndent;
+ sal_Char sIndent[nIndentMax+1];
+ BOOL bAll; // ganzes Dokument
+ BOOL bTabHasGraphics;
+ BOOL bTabAlignedLeft;
+ BOOL bCalcAsShown;
+ BOOL bCopyLocalFileToINet;
+ BOOL bTableDataWidth;
+ BOOL bTableDataHeight;
+
+ const SfxItemSet& PageDefaults( SCTAB nTab );
+
+ void WriteBody();
+ void WriteHeader();
+ void WriteOverview();
+ void WriteTables();
+ void WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
+ void WriteGraphEntry( ScHTMLGraphEntry* );
+ void WriteImage( String& rLinkName,
+ const Graphic&, const ByteString& rImgOptions,
+ ULONG nXOutFlags = 0 );
+ // nXOutFlags fuer XOutBitmap::WriteGraphic
+
+ // write to stream if and only if URL fields in edit cell
+ BOOL WriteFieldText( const ScEditCell* pCell );
+
+ // kopiere ggfs. eine lokale Datei ins Internet
+ BOOL CopyLocalFileToINet( String& rFileNm,
+ const String& rTargetNm, BOOL bFileToFile = FALSE );
+ BOOL HasCId() { return aCId.Len() > 0; }
+ void MakeCIdURL( String& rURL );
+
+ void PrepareGraphics( ScDrawLayer*, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow );
+ void FillGraphList( const SdrPage*, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow );
+
+ void BorderToStyle( ByteString& rOut, const char* pBorderName,
+ const SvxBorderLine* pLine, bool& bInsertSemicolon );
+
+ USHORT GetFontSizeNumber( USHORT nHeight );
+ const char* GetFontSizeCss( USHORT nHeight );
+ USHORT ToPixel( USHORT nTwips );
+ Size MMToPixel( const Size& r100thMMSize );
+ void IncIndent( short nVal );
+ const sal_Char* GetIndentStr() { return sIndent; }
+
+public:
+ ScHTMLExport( SvStream&, const String&, ScDocument*, const ScRange&,
+ BOOL bAll, const String& aStreamPath );
+ virtual ~ScHTMLExport();
+ ULONG Write();
+ const String& GetNonConvertibleChars() const
+ { return aNonConvertibleChars; }
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/htmlimp.hxx b/sc/source/filter/inc/htmlimp.hxx
new file mode 100644
index 000000000000..0376b3cd72f5
--- /dev/null
+++ b/sc/source/filter/inc/htmlimp.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HTMLIMP_HXX
+#define SC_HTMLIMP_HXX
+
+#include "eeimport.hxx"
+
+class ScHTMLParser;
+
+class ScHTMLImport : public ScEEImport
+{
+private:
+ static void InsertRangeName( ScDocument* pDoc, const String& rName, const ScRange& rRange );
+
+public:
+ ScHTMLImport( ScDocument* pDoc, const String& rBaseURL, const ScRange& rRange, BOOL bCalcWidthHeight = TRUE );
+ virtual ~ScHTMLImport();
+ const ScHTMLParser* GetParser() const { return (ScHTMLParser*)mpParser; }
+
+ virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0,
+ SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true );
+
+ static String GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName );
+};
+
+
+#endif
diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx
new file mode 100644
index 000000000000..f053a1088ff1
--- /dev/null
+++ b/sc/source/filter/inc/htmlpars.hxx
@@ -0,0 +1,638 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HTMLPARS_HXX
+#define SC_HTMLPARS_HXX
+
+#include <tools/stack.hxx>
+
+#include <memory>
+#include <vector>
+#include <list>
+#include <map>
+
+#include "rangelst.hxx"
+#include "eeparser.hxx"
+
+const sal_uInt32 SC_HTML_FONTSIZES = 7; // wie Export, HTML-Options
+
+// Pixel tolerance for SeekOffset and related.
+const USHORT SC_HTML_OFFSET_TOLERANCE_SMALL = 1; // single table
+const USHORT SC_HTML_OFFSET_TOLERANCE_LARGE = 10; // nested
+
+// ============================================================================
+// BASE class for HTML parser classes
+// ============================================================================
+
+class ScHTMLTable;
+
+/** Base class for HTML parser classes. */
+class ScHTMLParser : public ScEEParser
+{
+protected:
+ sal_uInt32 maFontHeights[ SC_HTML_FONTSIZES ];
+ ScDocument* mpDoc; /// The destination document.
+
+public:
+ explicit ScHTMLParser( EditEngine* pEditEngine, ScDocument* pDoc );
+ virtual ~ScHTMLParser();
+
+ virtual ULONG Read( SvStream& rStrm, const String& rBaseURL ) = 0;
+
+ /** Returns the "global table" which contains the entire HTML document. */
+ virtual const ScHTMLTable* GetGlobalTable() const = 0;
+};
+
+
+// ============================================================================
+
+SV_DECL_VARARR_SORT( ScHTMLColOffset, ULONG, 16, 4)
+
+struct ScHTMLTableStackEntry
+{
+ ScRangeListRef xLockedList;
+ ScEEParseEntry* pCellEntry;
+ ScHTMLColOffset* pLocalColOffset;
+ ULONG nFirstTableCell;
+ SCCOL nColCnt;
+ SCROW nRowCnt;
+ SCCOL nColCntStart;
+ SCCOL nMaxCol;
+ USHORT nTable;
+ USHORT nTableWidth;
+ USHORT nColOffset;
+ USHORT nColOffsetStart;
+ BOOL bFirstRow;
+ ScHTMLTableStackEntry( ScEEParseEntry* pE,
+ const ScRangeListRef& rL, ScHTMLColOffset* pTO,
+ ULONG nFTC,
+ SCCOL nCol, SCROW nRow,
+ SCCOL nStart, SCCOL nMax, USHORT nTab,
+ USHORT nTW, USHORT nCO, USHORT nCOS,
+ BOOL bFR )
+ : xLockedList( rL ), pCellEntry( pE ),
+ pLocalColOffset( pTO ),
+ nFirstTableCell( nFTC ),
+ nColCnt( nCol ), nRowCnt( nRow ),
+ nColCntStart( nStart ), nMaxCol( nMax ),
+ nTable( nTab ), nTableWidth( nTW ),
+ nColOffset( nCO ), nColOffsetStart( nCOS ),
+ bFirstRow( bFR )
+ {}
+ ~ScHTMLTableStackEntry() {}
+};
+DECLARE_STACK( ScHTMLTableStack, ScHTMLTableStackEntry* )
+
+struct ScHTMLAdjustStackEntry
+{
+ SCCOL nLastCol;
+ SCROW nNextRow;
+ SCROW nCurRow;
+ ScHTMLAdjustStackEntry( SCCOL nLCol, SCROW nNRow,
+ SCROW nCRow )
+ : nLastCol( nLCol ), nNextRow( nNRow ),
+ nCurRow( nCRow )
+ {}
+};
+DECLARE_STACK( ScHTMLAdjustStack, ScHTMLAdjustStackEntry* )
+
+
+// ============================================================================
+
+class EditEngine;
+class ScDocument;
+class HTMLOption;
+
+class ScHTMLLayoutParser : public ScHTMLParser
+{
+private:
+ Size aPageSize;
+ String aBaseURL;
+ ScHTMLTableStack aTableStack;
+ String aString;
+ ScRangeListRef xLockedList; // je Table
+ Table* pTables;
+ ScHTMLColOffset* pColOffset;
+ ScHTMLColOffset* pLocalColOffset; // je Table
+ ULONG nFirstTableCell; // je Table
+ short nTableLevel;
+ USHORT nTable;
+ USHORT nMaxTable;
+ SCCOL nColCntStart; // erste Col je Table
+ SCCOL nMaxCol; // je Table
+ USHORT nTableWidth; // je Table
+ USHORT nColOffset; // aktuell, Pixel
+ USHORT nColOffsetStart; // Startwert je Table, in Pixel
+ USHORT nMetaCnt; // fuer ParseMetaOptions
+ USHORT nOffsetTolerance; // for use with SeekOffset and related
+ BOOL bCalcWidthHeight; // TRUE: calculate real column width
+ // FALSE: 1 html-col = 1 sc-col
+ BOOL bTabInTabCell;
+ BOOL bFirstRow; // je Table, ob in erster Zeile
+ BOOL bInCell;
+ BOOL bInTitle;
+
+ DECL_LINK( HTMLImportHdl, ImportInfo* );
+ void NewActEntry( ScEEParseEntry* );
+ void EntryEnd( ScEEParseEntry*, const ESelection& );
+ void ProcToken( ImportInfo* );
+ void CloseEntry( ImportInfo* );
+ void NextRow( ImportInfo* );
+ void SkipLocked( ScEEParseEntry*, BOOL bJoin = TRUE );
+ static BOOL SeekOffset( ScHTMLColOffset*, USHORT nOffset,
+ SCCOL* pCol, USHORT nOffsetTol );
+ static void MakeCol( ScHTMLColOffset*, USHORT& nOffset,
+ USHORT& nWidth, USHORT nOffsetTol,
+ USHORT nWidthTol );
+ static void MakeColNoRef( ScHTMLColOffset*, USHORT nOffset,
+ USHORT nWidth, USHORT nOffsetTol,
+ USHORT nWidthTol );
+ static void ModifyOffset( ScHTMLColOffset*, USHORT& nOldOffset,
+ USHORT& nNewOffset, USHORT nOffsetTol );
+ void Colonize( ScEEParseEntry* );
+ USHORT GetWidth( ScEEParseEntry* );
+ void SetWidths();
+ void Adjust();
+
+ USHORT GetWidthPixel( const HTMLOption* );
+ BOOL IsAtBeginningOfText( ImportInfo* );
+
+ void TableOn( ImportInfo* );
+ void ColOn( ImportInfo* );
+ void TableRowOn( ImportInfo* );
+ void TableRowOff( ImportInfo* );
+ void TableDataOn( ImportInfo* );
+ void TableDataOff( ImportInfo* );
+ void TableOff( ImportInfo* );
+ void Image( ImportInfo* );
+ void AnchorOn( ImportInfo* );
+ void FontOn( ImportInfo* );
+
+public:
+ ScHTMLLayoutParser( EditEngine*, const String& rBaseURL, const Size& aPageSize, ScDocument* );
+ virtual ~ScHTMLLayoutParser();
+ virtual ULONG Read( SvStream&, const String& rBaseURL );
+ virtual const ScHTMLTable* GetGlobalTable() const;
+};
+
+
+
+// ============================================================================
+// HTML DATA QUERY PARSER
+// ============================================================================
+
+/** Declares the orientation in or for a table: column or row. */
+enum ScHTMLOrient { tdCol = 0 , tdRow = 1 };
+
+/** Type for a unique identifier for each table. */
+typedef sal_uInt16 ScHTMLTableId;
+/** Identifier of the "global table" (the entire HTML document). */
+const ScHTMLTableId SC_HTML_GLOBAL_TABLE = 0;
+/** Used as table index for normal (non-table) entries in ScHTMLEntry structs. */
+const ScHTMLTableId SC_HTML_NO_TABLE = 0;
+
+// ============================================================================
+
+/** A 2D cell position in an HTML table. */
+struct ScHTMLPos
+{
+ SCCOL mnCol;
+ SCROW mnRow;
+
+ inline explicit ScHTMLPos() : mnCol( 0 ), mnRow( 0 ) {}
+ inline explicit ScHTMLPos( SCCOL nCol, SCROW nRow ) :
+ mnCol( nCol ), mnRow( nRow ) {}
+ inline explicit ScHTMLPos( const ScAddress& rAddr ) { Set( rAddr ); }
+
+ inline SCCOLROW Get( ScHTMLOrient eOrient ) const
+ { return (eOrient == tdCol) ? mnCol : mnRow; }
+ inline void Set( SCCOL nCol, SCROW nRow )
+ { mnCol = nCol; mnRow = nRow; }
+ inline void Set( const ScAddress& rAddr )
+ { Set( rAddr.Col(), rAddr.Row() ); }
+ inline void Move( SCsCOL nColDiff, SCsROW nRowDiff )
+ { mnCol = mnCol + nColDiff; mnRow = mnRow + nRowDiff; }
+ inline ScAddress MakeAddr() const
+ { return ScAddress( mnCol, mnRow, 0 ); }
+};
+
+inline bool operator==( const ScHTMLPos& rPos1, const ScHTMLPos& rPos2 )
+{
+ return (rPos1.mnRow == rPos2.mnRow) && (rPos1.mnCol == rPos2.mnCol);
+}
+
+inline bool operator<( const ScHTMLPos& rPos1, const ScHTMLPos& rPos2 )
+{
+ return (rPos1.mnRow < rPos2.mnRow) || ((rPos1.mnRow == rPos2.mnRow) && (rPos1.mnCol < rPos2.mnCol));
+}
+
+// ----------------------------------------------------------------------------
+
+/** A 2D cell size in an HTML table. */
+struct ScHTMLSize
+{
+ SCCOL mnCols;
+ SCROW mnRows;
+
+ inline explicit ScHTMLSize() : mnCols( 0 ), mnRows( 0 ) {}
+ inline explicit ScHTMLSize( SCCOL nCols, SCROW nRows ) :
+ mnCols( nCols ), mnRows( nRows ) {}
+
+ inline SCCOLROW Get( ScHTMLOrient eOrient ) const
+ { return (eOrient == tdCol) ? mnCols : mnRows; }
+ inline void Set( SCCOL nCols, SCROW nRows )
+ { mnCols = nCols; mnRows = nRows; }
+ inline void Expand( SCsCOL nColDiff, SCsROW nRowDiff )
+ { mnCols = mnCols + nColDiff; mnRows = mnRows + nRowDiff; }
+};
+
+inline bool operator==( const ScHTMLSize& rSize1, const ScHTMLSize& rSize2 )
+{
+ return (rSize1.mnRows == rSize2.mnRows) && (rSize1.mnCols == rSize2.mnCols);
+}
+
+// ============================================================================
+
+/** A single entry containing a line of text or representing a table. */
+struct ScHTMLEntry : public ScEEParseEntry
+{
+public:
+ explicit ScHTMLEntry(
+ const SfxItemSet& rItemSet,
+ ScHTMLTableId nTableId = SC_HTML_NO_TABLE );
+
+ /** Returns true, if the selection of the entry is empty. */
+ inline bool IsEmpty() const { return !aSel.HasRange(); }
+ /** Returns true, if the entry has any content to be imported. */
+ bool HasContents() const;
+ /** Returns true, if the entry represents a table. */
+ inline bool IsTable() const { return nTab != SC_HTML_NO_TABLE; }
+ /** Returns true, if the entry represents a table. */
+ inline ScHTMLTableId GetTableId() const { return nTab; }
+
+ /** Sets or cleares the import always state. */
+ inline void SetImportAlways( bool bSet = true ) { mbImportAlways = bSet; }
+ /** Sets start point of the entry selection to the start of the import info object. */
+ void AdjustStart( const ImportInfo& rInfo );
+ /** Sets end point of the entry selection to the end of the import info object. */
+ void AdjustEnd( const ImportInfo& rInfo );
+ /** Deletes leading and trailing empty paragraphs from the entry. */
+ void Strip( const EditEngine& rEditEngine );
+
+ /** Returns read/write access to the item set of this entry. */
+ inline SfxItemSet& GetItemSet() { return aItemSet; }
+ /** Returns read-only access to the item set of this entry. */
+ inline const SfxItemSet& GetItemSet() const { return aItemSet; }
+
+private:
+ bool mbImportAlways; /// true = Always import this entry.
+};
+
+// ============================================================================
+
+/** This struct handles creation of unique table identifiers. */
+struct ScHTMLTableAutoId
+{
+ const ScHTMLTableId mnTableId; /// The created unique table identifier.
+ ScHTMLTableId& mrnUnusedId; /// Reference to global unused identifier variable.
+
+ /** The constructor assigns an unused identifier to member mnTableId. */
+ explicit ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId );
+};
+
+// ----------------------------------------------------------------------------
+
+class ScHTMLTableMap;
+
+/** Stores data for one table in an HTML document.
+
+ This class does the main work for importing an HTML document. It manages
+ the correct insertion of parse entries into the correct cells and the
+ creation of nested tables. Recalculation of resulting document size and
+ position is done recursively in all nested tables.
+ */
+class ScHTMLTable
+{
+public:
+ /** Creates a new HTML table without content.
+ @descr Internally handles a current cell position. This position is
+ invalid until first calls of RowOn() and DataOn().
+ @param rParentTable Reference to the parent table that owns this table.
+ @param bPreFormText true = Table is based on preformatted text (<pre> tag). */
+ explicit ScHTMLTable(
+ ScHTMLTable& rParentTable,
+ const ImportInfo& rInfo,
+ bool bPreFormText );
+
+ virtual ~ScHTMLTable();
+
+ /** Returns the name of the table, specified in the TABLE tag. */
+ inline const String& GetTableName() const { return maTableName; }
+ /** Returns the unique identifier of the table. */
+ inline ScHTMLTableId GetTableId() const { return maTableId.mnTableId; }
+ /** Returns the table size. */
+ inline const ScHTMLSize& GetSize() const { return maSize; }
+ /** Returns the cell spanning of the specified cell. */
+ ScHTMLSize GetSpan( const ScHTMLPos& rCellPos ) const;
+
+ /** Searches in all nested tables for the specified table.
+ @param nTableId Unique identifier of the table. */
+ ScHTMLTable* FindNestedTable( ScHTMLTableId nTableId ) const;
+
+ /** Puts the item into the item set of the current entry. */
+ void PutItem( const SfxPoolItem& rItem );
+ /** Inserts a text portion into current entry. */
+ void PutText( const ImportInfo& rInfo );
+ /** Inserts a new line, if in preformatted text, else does nothing. */
+ void InsertPara( const ImportInfo& rInfo );
+
+ /** Inserts a line break (<br> tag).
+ @descr Inserts the current entry regardless if it is empty. */
+ void BreakOn();
+ /** Inserts a heading line (<p> and <h*> tags). */
+ void HeadingOn();
+ /** Processes a hyperlink (<a> tag). */
+ void AnchorOn();
+
+ /** Starts a *new* table nested in this table (<table> tag).
+ @return Pointer to the new table. */
+ ScHTMLTable* TableOn( const ImportInfo& rInfo );
+ /** Closes *this* table (</table> tag).
+ @return Pointer to the parent table. */
+ ScHTMLTable* TableOff( const ImportInfo& rInfo );
+ /** Starts a *new* table based on preformatted text (<pre> tag).
+ @return Pointer to the new table. */
+ ScHTMLTable* PreOn( const ImportInfo& rInfo );
+ /** Closes *this* table based on preformatted text (</pre> tag).
+ @return Pointer to the parent table. */
+ ScHTMLTable* PreOff( const ImportInfo& rInfo );
+
+ /** Starts next row (<tr> tag).
+ @descr Cell address is invalid until first call of DataOn(). */
+ void RowOn( const ImportInfo& rInfo );
+ /** Closes the current row (<tr> tag).
+ @descr Cell address is invalid until call of RowOn() and DataOn(). */
+ void RowOff( const ImportInfo& rInfo );
+ /** Starts the next cell (<td> or <th> tag). */
+ void DataOn( const ImportInfo& rInfo );
+ /** Closes the current cell (</td> or </th> tag).
+ @descr Cell address is invalid until next call of DataOn(). */
+ void DataOff( const ImportInfo& rInfo );
+
+ /** Starts the body of the HTML document (<body> tag). */
+ void BodyOn( const ImportInfo& rInfo );
+ /** Closes the body of the HTML document (</body> tag). */
+ void BodyOff( const ImportInfo& rInfo );
+
+ /** Closes *this* table (</table> tag) or preformatted text (</pre> tag).
+ @descr Used to close this table object regardless on opening tag type.
+ @return Pointer to the parent table, or this, if no parent found. */
+ ScHTMLTable* CloseTable( const ImportInfo& rInfo );
+
+ /** Returns the resulting document row/column count of the specified HTML row/column. */
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const;
+ /** Returns the resulting document row/column count in the half-open range [nCellBegin, nCellEnd). */
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const;
+ /** Returns the total document row/column count in the specified direction. */
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient ) const;
+ /** Returns the total document row/column count of the specified HTML cell. */
+ ScHTMLSize GetDocSize( const ScHTMLPos& rCellPos ) const;
+
+ /** Returns the resulting Calc position of the top left edge of the table. */
+ inline const ScHTMLPos& GetDocPos() const { return maDocBasePos; }
+ /** Calculates the resulting Calc position of the specified HTML column/row. */
+ SCCOLROW GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos = 0 ) const;
+ /** Calculates the resulting Calc position of the specified HTML cell. */
+ ScHTMLPos GetDocPos( const ScHTMLPos& rCellPos ) const;
+
+ /** Calculates the current Calc document area of this table. */
+ void GetDocRange( ScRange& rRange ) const;
+
+ /** Applies border formatting to the passed document. */
+ void ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const;
+
+protected:
+ /** Creates a new HTML table without parent.
+ @descr This constructor is used to create the "global table". */
+ explicit ScHTMLTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ScEEParseList& rEEParseList,
+ ScHTMLTableId& rnUnusedId );
+
+ /** Fills all empty cells in this and nested tables with dummy parse entries. */
+ void FillEmptyCells();
+ /** Recalculates the size of all columns/rows in the table, regarding nested tables. */
+ void RecalcDocSize();
+ /** Recalculates the position of all cell entries and nested tables.
+ @param rBasePos The origin of the table in the Calc document. */
+ void RecalcDocPos( const ScHTMLPos& rBasePos );
+
+private:
+ typedef ::std::auto_ptr< ScHTMLTableMap > ScHTMLTableMapPtr;
+ typedef ::std::auto_ptr< SfxItemSet > SfxItemSetPtr;
+ typedef ::std::vector< SCCOLROW > ScSizeVec;
+ typedef ::std::list< ScHTMLEntry* > ScHTMLEntryList;
+ typedef ::std::map< ScHTMLPos, ScHTMLEntryList > ScHTMLEntryMap;
+ typedef ::std::auto_ptr< ScHTMLEntry > ScHTMLEntryPtr;
+
+ /** Returns true, if the current cell does not contain an entry yet. */
+ bool IsEmptyCell() const;
+ /** Returns the item set from cell, row, or table, depending on current state. */
+ const SfxItemSet& GetCurrItemSet() const;
+
+ /** Returns true, if import info represents a space character. */
+ static bool IsSpaceCharInfo( const ImportInfo& rInfo );
+
+ /** Creates and returns a new empty flying entry at position (0,0). */
+ ScHTMLEntryPtr CreateEntry() const;
+ /** Creates a new flying entry.
+ @param rInfo Contains the initial edit engine selection for the entry. */
+ void CreateNewEntry( const ImportInfo& rInfo );
+
+ /** Inserts an empty line in front of the next entry. */
+ void InsertLeadingEmptyLine();
+
+ /** Pushes the passed entry into the list of the current cell. */
+ void ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry );
+ /** Tries to insert the entry into the current cell.
+ @descr If insertion is not possible (i.e., currently no cell open), the
+ entry will be inserted into the parent table.
+ @return true = Entry as been pushed into the current cell; false = Entry dropped. */
+ bool PushEntry( ScHTMLEntryPtr& rxEntry );
+ /** Puts the current entry into the entry list, if it is not empty.
+ @param rInfo The import info struct containing the end position of the current entry.
+ @param bLastInCell true = If cell is still empty, put this entry always.
+ @return true = Entry as been pushed into the current cell; false = Entry dropped. */
+ bool PushEntry( const ImportInfo& rInfo, bool bLastInCell = false );
+ /** Pushes a new entry into current cell which references a nested table.
+ @return true = Entry as been pushed into the current cell; false = Entry dropped. */
+ bool PushTableEntry( ScHTMLTableId nTableId );
+
+ /** Tries to find a table from the table container.
+ @descr Assumes that the table is located in the current container or
+ that the passed table identifier is 0.
+ @param nTableId Unique identifier of the table or 0. */
+ ScHTMLTable* GetExistingTable( ScHTMLTableId nTableId ) const;
+ /** Inserts a nested table in the current cell at the specified position.
+ @param bPreFormText true = New table is based on preformatted text (<pre> tag). */
+ ScHTMLTable* InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText );
+
+ /** Inserts a new cell in an unused position, starting from current cell position. */
+ void InsertNewCell( const ScHTMLSize& rSpanSize );
+
+ /** Set internal states for a new table row. */
+ void ImplRowOn();
+ /** Set internal states for leaving a table row. */
+ void ImplRowOff();
+ /** Set internal states for entering a new table cell. */
+ void ImplDataOn( const ScHTMLSize& rSpanSize );
+ /** Set internal states for leaving a table cell. */
+ void ImplDataOff();
+
+ /** Inserts additional formatting options from import info into the item set. */
+ void ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo );
+
+ /** Updates the document column/row size of the specified column or row.
+ @descr Only increases the present count, never decreases. */
+ void SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize );
+ /** Calculates and sets the resulting size the cell needs in the document.
+ @descr Reduces the needed size in merged cells.
+ @param nCellPos The first column/row position of the (merged) cell.
+ @param nCellSpan The cell spanning in the specified orientation.
+ @param nRealDocSize The raw document size of all entries of the cell. */
+ void CalcNeededDocSize(
+ ScHTMLOrient eOrient, SCCOLROW nCellPos,
+ SCCOLROW nCellSpan, SCCOLROW nRealDocSize );
+
+private:
+ ScHTMLTable* mpParentTable; /// Pointer to parent table.
+ ScHTMLTableMapPtr mxNestedTables; /// Table of nested HTML tables.
+ String maTableName; /// Table name from <table id> option.
+ ScHTMLTableAutoId maTableId; /// Unique identifier of this table.
+ SfxItemSet maTableItemSet; /// Items for the entire table.
+ SfxItemSetPtr mxRowItemSet; /// Items for the current table row.
+ SfxItemSetPtr mxDataItemSet; /// Items for the current cell.
+ ScRangeList maHMergedCells; /// List of all horizontally merged cells.
+ ScRangeList maVMergedCells; /// List of all vertically merged cells.
+ ScRangeList maUsedCells; /// List of all used cells.
+ EditEngine& mrEditEngine; /// Edit engine (from ScEEParser).
+ 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 );
+
+ virtual ~ScHTMLGlobalTable();
+
+ /** Recalculates sizes and resulting positions of all document entries. */
+ void Recalc();
+};
+
+// ============================================================================
+
+/** The HTML parser for data queries. Focuses on data import, not on layout.
+
+ Builds the table structure correctly, ignores extended formatting like
+ pictures or column widths.
+ */
+class ScHTMLQueryParser : public ScHTMLParser
+{
+public:
+ explicit ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc );
+ virtual ~ScHTMLQueryParser();
+
+ virtual ULONG Read( SvStream& rStrm, const String& rBaseURL );
+
+ /** Returns the "global table" which contains the entire HTML document. */
+ virtual const ScHTMLTable* GetGlobalTable() const;
+
+private:
+ /** Handles all possible tags in the HTML document. */
+ void ProcessToken( const ImportInfo& rInfo );
+ /** Inserts a text portion into current entry. */
+ void InsertText( const ImportInfo& rInfo );
+ /** Processes the <font> tag. */
+ void FontOn( const ImportInfo& rInfo );
+
+ /** Processes the <meta> tag. */
+ void MetaOn( const ImportInfo& rInfo );
+ /** Opens the title of the HTML document (<title> tag). */
+ void TitleOn( const ImportInfo& rInfo );
+ /** Closes the title of the HTML document (</title> tag). */
+ void TitleOff( const ImportInfo& rInfo );
+
+ /** Opens a new table at the current position. */
+ void TableOn( const ImportInfo& rInfo );
+ /** Closes the current table. */
+ void TableOff( const ImportInfo& rInfo );
+ /** Opens a new table based on preformatted text. */
+ void PreOn( const ImportInfo& rInfo );
+ /** Closes the current preformatted text table. */
+ void PreOff( const ImportInfo& rInfo );
+
+ /** Closes the current table, regardless on opening tag. */
+ void CloseTable( const ImportInfo& rInfo );
+
+ DECL_LINK( HTMLImportHdl, const ImportInfo* );
+
+private:
+ typedef ::std::auto_ptr< ScHTMLGlobalTable > ScHTMLGlobalTablePtr;
+
+ String maTitle; /// The title of the document.
+ ScHTMLGlobalTablePtr mxGlobTable; /// Contains the entire imported document.
+ ScHTMLTable* mpCurrTable; /// Pointer to current table (performance).
+ ScHTMLTableId mnUnusedId; /// First unused table identifier.
+ bool mbTitleOn; /// true = Inside of <title> </title>.
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx
new file mode 100644
index 000000000000..2df58173a63a
--- /dev/null
+++ b/sc/source/filter/inc/imp_op.hxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_IMP_OP_HXX
+#define SC_IMP_OP_HXX
+
+#include <tools/gen.hxx>
+#include "xiroot.hxx"
+#include "xistream.hxx"
+#include "xistyle.hxx"
+#include "flttypes.hxx"
+#include "namebuff.hxx"
+#include "root.hxx"
+#include "otlnbuff.hxx"
+#include "colrowst.hxx"
+#include "excdefs.hxx"
+
+
+class SfxItemSet;
+class SvStream;
+
+class ScFormulaCell;
+class SdrObject;
+class ScDocument;
+class ScToken;
+class _ScRangeListTabs;
+
+class ExcelToSc;
+
+
+class ImportTyp
+{
+protected:
+ CharSet eQuellChar; // Quell-Zeichensatz
+ ScDocument* pD; // Dokument
+
+public:
+ ImportTyp( ScDocument*, CharSet eSrc );
+ virtual ~ImportTyp();
+
+ virtual FltError Read( void );
+};
+
+class XclImpOutlineDataBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpOutlineDataBuffer( const XclImpRoot& rRoot, SCTAB nScTab );
+ virtual ~XclImpOutlineDataBuffer();
+
+ inline XclImpColRowSettings* GetColRowBuff() const { return mxColRowBuff.get(); }
+ inline XclImpOutlineBuffer* GetColOutline() const { return mxColOutlineBuff.get(); }
+ inline XclImpOutlineBuffer* GetRowOutline() const { return mxRowOutlineBuff.get(); }
+ void Convert();
+
+private:
+ typedef ScfRef< XclImpOutlineBuffer > XclImpOutlineBfrRef;
+ typedef ScfRef< XclImpColRowSettings > XclImpColRowSettRef;
+
+ XclImpOutlineBfrRef mxColOutlineBuff;
+ XclImpOutlineBfrRef mxRowOutlineBuff;
+ XclImpColRowSettRef mxColRowBuff;
+ SCTAB mnScTab;
+};
+
+class ImportExcel : public ImportTyp, protected XclImpRoot
+{
+protected:
+ static const double fExcToTwips; // Umrechnung 1/256 Zeichen -> Twips
+
+ RootData* pExcRoot;
+
+ XclImpStream maStrm; // input stream
+ XclImpStream& aIn; // input stream
+
+ ScfUInt32Vec maSheetOffsets;
+ ScRange maScOleSize; /// Visible range if embedded.
+
+ NameBuffer* pExtNameBuff; // ... externe Namen (Ind.-Basis=1)
+ ExcelToSc* pFormConv; // Formel-Konverter
+
+ XclImpOutlineBuffer* pColOutlineBuff;
+ XclImpOutlineBuffer* pRowOutlineBuff;
+ XclImpColRowSettings* pColRowBuff; // Col/Row-Einstellungen 1 Tabelle
+
+ typedef ScfDelList< XclImpOutlineDataBuffer > XclImpOutlineListBuffer;
+ XclImpOutlineListBuffer* pOutlineListBuffer;
+
+ sal_Int16 mnLastRefIdx;
+ UINT16 nIxfeIndex; // merkt sich Angabe im IXFE-Record
+ UINT16 nLastXF; // letzter XF in Formula-Record
+ SCTAB nBdshtTab; // Counter fuer Boundsheet
+ ScFormulaCell* pLastFormCell; // fuer String-Records
+
+ BOOL bTabTruncated; // wenn Bereichsueberschreitung zum
+ // Abschneiden von Zellen fuehrt
+
+ // Record-Funktionen
+ void ReadFileSharing();
+
+ sal_uInt16 ReadXFIndex( bool bBiff2 );
+
+ void ReadDimensions();
+ void ReadBlank();
+ void ReadInteger();
+ void ReadNumber();
+ void ReadLabel();
+ void ReadBoolErr();
+ void ReadRk();
+
+ void Window1();
+ void Formula25( void ); // 0x06 -> excform.cxx
+ void Row25( void ); // 0x08
+ void Bof2( void ); // 0x09
+ void Eof( void ); // 0x0A
+ void DocProtect( void ); // 0x12
+ void SheetProtect( void ); // 0x12 Sheet Protection
+ void DocPasssword( void ); // 0x13 document password
+ void SheetPassword( void ); // 0x13 sheet password
+ void Externsheet( void ); // 0x17
+ void WinProtection( void ); // 0x19
+ void Columndefault( void ); // 0x20
+ void Array25( void ); // 0x21
+ void Rec1904( void ); // 0x22
+ void Externname25( void ); // 0x23
+ void Colwidth( void ); // 0x24
+ void Defrowheight2( void ); // 0x25
+// void Window1( void ); // 0x3D
+ void Codepage( void ); // 0x42
+ void Ixfe( void ); // 0x44
+ void DefColWidth( void ); // 0x55
+ void Builtinfmtcnt( void ); // 0x56
+ void Colinfo( void ); // 0x7D
+ void Wsbool( void ); // 0x81
+ void Boundsheet( void ); // 0x85
+ void Country( void ); // 0x8C
+ void Hideobj( void ); // 0x8D
+ void Bundleheader( void ); // 0x8F
+ void Standardwidth( void ); // 0x99
+ void Shrfmla( void ); // 0xBC
+ void Mulrk( void ); // 0xBD
+ void Mulblank( void ); // 0xBE
+ void Rstring( void ); // 0xD6
+ void Cellmerging( void ); // 0xE5
+ void Olesize( void ); // 0xDE
+ void ReadUsesElfs(); // 0x0160
+ void Formula3( void ); // 0x0206 -> excform.cxx
+ // 0x0207 -> 0x07
+ void Row34( void ); // 0x0208
+ void Bof3( void ); // 0x0209
+ void Array34( void ); // 0x0221
+ void Externname34( void ); // 0x0223
+ void Defrowheight345( void ); // 0x0225
+ void TableOp( void ); // 0x0236
+ //void Rk( void ); // 0x027E -> 0x7E
+ void Formula4( void ); // 0x0406 -> excform.cxx
+ void Bof4( void ); // 0x0409
+ void Bof5( void ); // 0x0809
+
+ // ---------------------------------------------------------------
+ void Formula( const XclAddress& rXclPos,
+ UINT16 nXF, UINT16 nFormLen, double &rCurVal, BOOL bShrFmla );
+ // -> excform.cxx
+
+ virtual void EndSheet( void );
+ void NeueTabelle( void );
+ const ScTokenArray* ErrorToFormula( BYTE bErrOrVal, BYTE nError,
+ double& rVal );
+
+ virtual void AdjustRowHeight();
+ virtual void PostDocLoad( void );
+
+public:
+ ImportExcel( XclImpRootData& rImpData, SvStream& rStrm );
+
+ virtual ~ImportExcel( void );
+
+ virtual FltError Read( void );
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/lotattr.hxx b/sc/source/filter/inc/lotattr.hxx
new file mode 100644
index 000000000000..7015136f1be1
--- /dev/null
+++ b/sc/source/filter/inc/lotattr.hxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTATTR_HXX
+#define SC_LOTATTR_HXX
+
+#include <tools/solar.h>
+#include <tools/list.hxx>
+#include "patattr.hxx"
+#include "scitems.hxx"
+#include "address.hxx"
+
+// ----- forwards --------------------------------------------------------
+class ScDocument;
+class ScDocumentPool;
+class SvxBorderLine;
+class SvxColorItem;
+class Color;
+
+class LotAttrTable;
+
+
+struct LotAttrWK3
+{
+ UINT8 nFont;
+ UINT8 nLineStyle;
+ UINT8 nFontCol;
+ UINT8 nBack;
+
+ inline BOOL HasStyles( void );
+ inline BOOL IsCentered( void );
+};
+
+
+inline BOOL LotAttrWK3::HasStyles( void )
+{
+ return ( nFont || nLineStyle || nFontCol || ( nBack & 0x7F ) );
+ // !! ohne Center-Bit!!
+}
+
+
+inline BOOL LotAttrWK3::IsCentered( void )
+{
+ return ( nBack & 0x80 );
+}
+
+
+class LotAttrCache : private List
+{
+private:
+ friend class LotAttrTable;
+
+ struct ENTRY
+ {
+ ScPatternAttr* pPattAttr;
+ UINT32 nHash0;
+
+ inline ENTRY( const ScPatternAttr& r ) { pPattAttr = new ScPatternAttr( r ); }
+
+ inline ENTRY( ScPatternAttr* p ) { pPattAttr = p; }
+
+ inline ~ENTRY() { delete pPattAttr; }
+
+ inline BOOL operator ==( const ENTRY& r ) const { return nHash0 == r.nHash0; }
+
+ inline BOOL operator ==( const UINT32& r ) const { return nHash0 == r; }
+ };
+
+ ScDocumentPool* pDocPool;
+ SvxColorItem* ppColorItems[ 6 ]; // 0 und 7 fehlen!
+ SvxColorItem* pBlack;
+ SvxColorItem* pWhite;
+ Color* pColTab;
+
+ inline static void MakeHash( const LotAttrWK3& rAttr, UINT32& rOut )
+ {
+ ( ( UINT8* ) &rOut )[ 0 ] = rAttr.nFont & 0x7F;
+ ( ( UINT8* ) &rOut )[ 1 ] = rAttr.nLineStyle;
+ ( ( UINT8* ) &rOut )[ 2 ] = rAttr.nFontCol;
+ ( ( UINT8* ) &rOut )[ 3 ] = rAttr.nBack;
+ }
+ static void LotusToScBorderLine( UINT8 nLine, SvxBorderLine& );
+ const SvxColorItem& GetColorItem( const UINT8 nLotIndex ) const;
+ const Color& GetColor( const UINT8 nLotIndex ) const;
+public:
+ LotAttrCache( void );
+ ~LotAttrCache();
+
+ const ScPatternAttr& GetPattAttr( const LotAttrWK3& );
+};
+
+
+class LotAttrCol : private List
+{
+private:
+ struct ENTRY
+ {
+ const ScPatternAttr* pPattAttr;
+ SCROW nFirstRow;
+ SCROW nLastRow;
+ };
+
+public:
+ ~LotAttrCol( void );
+ void SetAttr( const SCROW nRow, const ScPatternAttr& );
+ void Apply( const SCCOL nCol, const SCTAB nTab, const BOOL bClear = TRUE );
+ void Clear( void );
+};
+
+
+class LotAttrTable
+{
+private:
+ LotAttrCol pCols[ MAXCOLCOUNT ];
+ LotAttrCache aAttrCache;
+public:
+ LotAttrTable( void );
+ ~LotAttrTable();
+
+ void SetAttr( const SCCOL nColFirst, const SCCOL nColLast, const SCROW nRow, const LotAttrWK3& );
+ void Apply( const SCTAB nTabNum );
+};
+
+
+
+
+
+#endif
+
diff --git a/sc/source/filter/inc/lotfntbf.hxx b/sc/source/filter/inc/lotfntbf.hxx
new file mode 100644
index 000000000000..5c8771814206
--- /dev/null
+++ b/sc/source/filter/inc/lotfntbf.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTFNTBF_HXX
+#define SC_LOTFNTBF_HXX
+
+#include <tools/solar.h>
+
+#include "scitems.hxx"
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+
+// ---------------------------------------------------- class LotusFontBuffer -
+
+// Code in fontbuff.cxx (excel)
+
+class LotusFontBuffer
+{
+private:
+ struct ENTRY
+ {
+ String* pTmpName;
+ SvxFontItem* pFont;
+ SvxFontHeightItem* pHeight;
+ SvxColorItem* pColor;
+ INT32 nType; // < 0 -> undefiniert
+ inline ENTRY( void )
+ {
+ pTmpName = NULL;
+ pFont = NULL;
+ pHeight = NULL;
+ pColor = NULL;
+ nType = -1;
+ }
+ inline ~ENTRY()
+ {
+ if( pTmpName )
+ delete pTmpName;
+ if( pFont )
+ delete pFont;
+ if( pHeight )
+ delete pHeight;
+ if( pColor )
+ delete pColor;
+ }
+ inline void TmpName( const String &rNew )
+ {
+ if( pTmpName )
+ *pTmpName = rNew;
+ else
+ pTmpName = new String( rNew );
+ }
+ inline void Font( SvxFontItem& rNew )
+ {
+ if( pFont )
+ delete pFont;
+ pFont = &rNew;
+ }
+ inline void Height( SvxFontHeightItem& rNew )
+ {
+ if( pHeight )
+ delete pHeight;
+ pHeight = &rNew;
+ }
+ inline void Color( SvxColorItem& rNew )
+ {
+ if( pColor )
+ delete pColor;
+ pColor = &rNew;
+ }
+ inline void Type( const UINT16 nNew ) { nType = nNew; }
+ };
+
+ ENTRY pData[ 8 ];
+ const static UINT16 nSize;
+ void MakeFont( ENTRY* pEntry );
+public:
+ void Fill( const UINT8 nIndex, SfxItemSet& rItemSet );
+ void SetName( const UINT16 nIndex, const String& rName );
+ void SetHeight( const UINT16 nIndex, const UINT16 nHeight );
+ void SetType( const UINT16 nIndex, const UINT16 nType );
+};
+
+
+
+#endif
diff --git a/sc/source/filter/inc/lotform.hxx b/sc/source/filter/inc/lotform.hxx
new file mode 100644
index 000000000000..0a341e29ae51
--- /dev/null
+++ b/sc/source/filter/inc/lotform.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTFORM_HXX
+#define SC_LOTFORM_HXX
+
+#include "formel.hxx"
+#include <tools/string.hxx>
+
+
+
+
+enum FUNC_TYPE
+{
+ FT_Return = 0, // End Formula
+ FT_FuncFix0, // Funktion, 0 Parameter
+ FT_FuncFix1, // Funktion, 0 Parameter
+ FT_FuncFix2, // Funktion, 0 Parameter
+ FT_FuncFix3, // Funktion, 0 Parameter
+ FT_FuncFix4, // Funktion, 0 Parameter
+ FT_FuncVar, // ~, var. P.
+ FT_Neg, // Negierung
+ FT_Op, // Operator
+ FT_NotImpl, // nicht implementiert
+ FT_ConstFloat, // Double (8-Byte)
+ FT_Variable, // Single Ref
+ FT_Range, // Double Ref
+ FT_Braces, // Klammmern
+ FT_ConstInt, // Integer
+ FT_ConstString, // String
+ FT_NOP, // nichts
+ // zusaetzlich ab WK3
+ FT_Cref, // Cell Reference
+ FT_Rref, // Range Reference
+ FT_Nrref, // Named range reference
+ FT_Absnref, // Absolut named range
+ FT_Erref, // Err range reference
+ FT_Ecref, // Err cell reference
+ FT_Econstant, // Err constant
+ FT_Splfunc, // SPLfunction
+ FT_Const10Float,// Float (10-Byte)
+ FT_Snum // Const Short Num
+ // fuer 'Problemfaelle' beim Import
+};
+
+
+
+
+class LotusToSc : public LotusConverterBase
+{
+private:
+ CharSet eSrcChar;
+ TokenId nAddToken; // ')+1.0'
+ TokenId nSubToken; // ~
+ TokenId n0Token; // '0.0';
+ // ---------------------------------------------------------------
+ static FUNC_TYPE IndexToType( BYTE );
+ static DefTokenId IndexToToken( BYTE );
+ static FUNC_TYPE IndexToTypeWK123( BYTE );
+ static DefTokenId IndexToTokenWK123( BYTE );
+ void DoFunc( DefTokenId eOc, BYTE nAnz, const sal_Char* pExtName );
+ void LotusRelToScRel( UINT16 nCol, UINT16 nRow,
+ ScSingleRefData& rSRD );
+ BOOL bWK3; // alternative Codeumsetzung statt fuer < WK1
+ BOOL bWK123; // alternative for 123
+ // -------------------------------------------------------------------
+ void ReadSRD( ScSingleRefData& rSRD, BYTE nFlags );
+ inline void ReadCRD( ScComplexRefData& rCRD, BYTE nFlags );
+ void IncToken( TokenId &rParam );
+ // ACHTUNG: hier wird die aktuelle Token-Kette im Pool
+ // mit '(<rParam>)+1' fortgeschrieben und mit
+ // Store() abgeschlossen!
+ void DecToken( TokenId& rParam );
+ // ACHTUNG: ~
+ void NegToken( TokenId& rParam );
+ // ACHTUNG: wie ~, nur wird '-(<rParam>)' gebildet
+public:
+ LotusToSc( SvStream& aStr, CharSet eSrc, BOOL b );
+ virtual ConvErr Convert( const ScTokenArray*& rpErg, INT32& nRest,
+ const FORMULA_TYPE eFT = FT_CellFormula );
+
+ void Reset( const ScAddress& rEingPos );
+ inline void SetWK3( void );
+
+private:
+ using LotusConverterBase::Reset;
+};
+
+
+inline void LotusToSc::ReadCRD( ScComplexRefData& rCRD, BYTE nRelBit )
+{
+ // erster Teil
+ ReadSRD( rCRD.Ref1, nRelBit );
+
+ // zweiter Teil
+ ReadSRD( rCRD.Ref2, nRelBit >> 3 );
+}
+
+
+inline void LotusToSc::SetWK3( void )
+{
+ bWK3 = TRUE;
+}
+
+
+
+#endif
+
diff --git a/sc/source/filter/inc/lotimpop.hxx b/sc/source/filter/inc/lotimpop.hxx
new file mode 100644
index 000000000000..15c0a2931dc4
--- /dev/null
+++ b/sc/source/filter/inc/lotimpop.hxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTIMPOP_HXX
+#define SC_LOTIMPOP_HXX
+
+#include <tools/string.hxx>
+
+#include "imp_op.hxx"
+#include "flttypes.hxx"
+#include "ftools.hxx"
+#include "lotform.hxx"
+#include "lotattr.hxx"
+
+class ScFormulaCell;
+class LotusFontBuffer;
+class SvxBorderLine;
+
+
+class ImportLotus : public ImportTyp
+{
+private:
+ SvStream* pIn; // benoetigt wegen multiplem Read()!
+ LotusFontBuffer* pFontBuff;
+ LotusToSc aConv;
+ UINT16 nTab; // z.Zt. bearbeitete Tabelle
+ INT32 nExtTab;
+ // -------------------------------------------------------------------
+ // in WK?-Datei
+ void Bof( void ); // 0x0000 00
+ BOOL BofFm3( void ); // 0x0000 00
+ void Columnwidth( UINT16 nRecLen ); // 0x0007 07
+ void Hiddencolumn( UINT16 nRecLen ); // 0x0008 08
+ void Userrange( void ); // 0x0009 09
+ void Errcell( void ); // 0x0014 20
+ void Nacell( void ); // 0x0015 21
+ void Labelcell( void ); // 0x0016 22
+ void Numbercell( void ); // 0x0017 23
+ void Smallnumcell( void ); // 0x0018 24
+ ScFormulaCell* Formulacell( UINT16 nRecLen ); // 0x0019 25
+ void Formulastring( ScFormulaCell& ); // 0x001a 26
+ // 0x001b 27 special
+ void NamedSheet( void ); // 14000
+ void RowPresentation( UINT16 nRecLen ); // 2007
+
+ // -------------------------------------------------------------------
+ // in FM?-Datei
+ void Font_Face( void ); // 174
+ void Font_Type( void ); // 176
+ void Font_Ysize( void ); // 177
+ void _Row( const UINT16 nRecLen ); // 197 ?
+ // -------------------------------------------------------------------
+ inline void Read( ScAddress& );
+ inline void Read( ScRange& );
+ // fuer Addresses/Ranges im Format Row(16)/Tab(8)/Col(8)
+ inline void Read( sal_Char& );
+ inline void Read( BYTE& );
+ inline void Read( UINT16& );
+ inline void Read( INT16& );
+ inline void Read( UINT32& );
+ inline void Read( double& ); // 10-Byte-IEEE lesen
+ inline void Read( LotAttrWK3& );
+ void Read( String& ); // 0-terminierten String einlesen
+ inline void Skip( const UINT16 nNumBytes );
+ // -------------------------------------------------------------------
+public:
+ ImportLotus( SvStream&, ScDocument*, CharSet eSrc );
+
+ virtual ~ImportLotus();
+
+ FltError Read();
+ FltError Read( SvStream& ); // special for *.fm3-Dateien
+};
+
+
+inline void ImportLotus::Read( ScAddress& rAddr )
+{
+ UINT16 nRow;
+ *pIn >> nRow;
+ rAddr.SetRow( static_cast<SCROW>(nRow) );
+ BYTE nByte;
+ *pIn >> nByte;
+ rAddr.SetTab( static_cast<SCTAB>(nByte) );
+ *pIn >> nByte;
+ rAddr.SetCol( static_cast<SCCOL>(nByte) );
+}
+
+
+inline void ImportLotus::Read( ScRange& rRange )
+{
+ Read( rRange.aStart );
+ Read( rRange.aEnd );
+}
+
+
+inline void ImportLotus::Read( sal_Char& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( BYTE& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( UINT16& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( INT16& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( UINT32& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( double& r )
+{
+ r = ScfTools::ReadLongDouble( *pIn );
+}
+
+
+inline void ImportLotus::Read( LotAttrWK3& r )
+{
+ *pIn >> r.nFont >> r.nFontCol >> r.nBack >> r.nLineStyle;
+}
+
+
+inline void ImportLotus::Skip( const UINT16 n )
+{
+ pIn->SeekRel( n );
+}
+
+
+
+#endif
diff --git a/sc/source/filter/inc/lotrange.hxx b/sc/source/filter/inc/lotrange.hxx
new file mode 100644
index 000000000000..ab9acf9f476e
--- /dev/null
+++ b/sc/source/filter/inc/lotrange.hxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTRANGE_HXX
+#define SC_LOTRANGE_HXX
+
+#include <tools/solar.h>
+#include <compiler.hxx>
+
+// --------------------------------------------------------- class LotusRange -
+
+class LotusRangeList;
+
+typedef UINT16 LR_ID;
+#define ID_FAIL 0xFFFF
+
+class LotusRange
+{
+ friend class LotusRangeList;
+private:
+ UINT32 nHash;
+ SCCOL nColStart;
+ SCROW nRowStart;
+ SCCOL nColEnd;
+ SCROW nRowEnd;
+ LR_ID nId;
+ void MakeHash( void );
+ inline void Copy( const LotusRange& );
+ inline void SetId( LR_ID nId );
+public:
+ LotusRange( SCCOL nCol, SCROW nRow );
+ LotusRange( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE );
+ LotusRange( const LotusRange& );
+ inline LotusRange &operator =( const LotusRange& );
+ inline BOOL operator ==( const LotusRange& ) const;
+ inline BOOL operator !=( const LotusRange& ) const;
+ inline BOOL IsSingle( void ) const;
+};
+
+
+inline void LotusRange::Copy( const LotusRange& rCpy )
+{
+ nColStart = rCpy.nColStart;
+ nRowStart = rCpy.nRowStart;
+ nColEnd = rCpy.nColEnd;
+ nRowEnd = rCpy.nRowEnd;
+}
+
+
+inline void LotusRange::SetId( LR_ID nNewId )
+{
+ nId = nNewId;
+}
+
+
+inline LotusRange &LotusRange::operator =( const LotusRange& rCpy )
+{
+ Copy( rCpy );
+ return *this;
+}
+
+
+inline BOOL LotusRange::operator ==( const LotusRange& rRef ) const
+{
+ return ( nHash == rRef.nHash && nColStart == rRef.nColStart &&
+ nRowStart == rRef.nRowStart && nColEnd == rRef.nColEnd &&
+ nRowEnd == rRef.nRowEnd );
+}
+
+
+inline BOOL LotusRange::operator !=( const LotusRange& rRef ) const
+{
+ return ( nHash != rRef.nHash || nColStart != rRef.nColStart ||
+ nRowStart != rRef.nRowStart || nColEnd != rRef.nColEnd ||
+ nRowEnd != rRef.nRowEnd );
+}
+
+
+inline BOOL LotusRange::IsSingle( void ) const
+{
+ return ( nColStart == nColEnd && nRowStart == nRowEnd );
+}
+
+
+
+// ----------------------------------------------------- class LotusRangeList -
+
+class LotusRangeList : private List
+{
+private:
+ LR_ID nIdCnt;
+ ScComplexRefData aComplRef;
+ static SCCOL nEingCol;
+ static SCROW nEingRow;
+public:
+ LotusRangeList( void );
+ ~LotusRangeList( void );
+ inline UINT16 GetIndex( SCCOL nCol, SCROW nRow );
+ inline UINT16 GetIndex( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE );
+ UINT16 GetIndex( const LotusRange& );
+ inline void Append( SCCOL nCol, SCROW nRow, const String& );
+ inline void Append( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE, const String& );
+ void Append( LotusRange* pLR, const String& rName );
+ inline static void SetEing( const SCCOL nCol, const SCROW nRow );
+};
+
+
+inline LR_ID LotusRangeList::GetIndex( SCCOL nCol, SCROW nRow )
+{
+ LotusRange aRef( nCol, nRow );
+ return GetIndex( aRef );
+}
+
+
+inline LR_ID LotusRangeList::GetIndex( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE )
+{
+ LotusRange aRef( nColS, nRowS, nColE, nRowE );
+ return GetIndex( aRef );
+}
+
+
+inline void LotusRangeList::Append( SCCOL nCol, SCROW nRow, const String& rName )
+{
+ Append( new LotusRange( nCol, nRow ), rName );
+}
+
+
+inline void LotusRangeList::Append( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE, const String& r )
+{
+ Append( new LotusRange( nColS, nRowS, nColE, nRowE ), r );
+}
+
+
+inline void LotusRangeList::SetEing( const SCCOL nCol, const SCROW nRow )
+{
+ nEingCol = nCol;
+ nEingRow = nRow;
+}
+
+#endif
+
+
+
diff --git a/sc/source/filter/inc/makefile.mk b/sc/source/filter/inc/makefile.mk
new file mode 100644
index 000000000000..1b35ca49549d
--- /dev/null
+++ b/sc/source/filter/inc/makefile.mk
@@ -0,0 +1,26 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
diff --git a/sc/source/filter/inc/namebuff.hxx b/sc/source/filter/inc/namebuff.hxx
new file mode 100644
index 000000000000..c8182e8c0c17
--- /dev/null
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -0,0 +1,356 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAMEBUFF_HXX
+#define SC_NAMEBUFF_HXX
+
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include "compiler.hxx"
+#include "root.hxx"
+#include "xiroot.hxx"
+
+#include "rangenam.hxx"
+#include <hash_map>
+#include <list>
+
+class ScDocument;
+class ScTokenArray;
+class NameBuffer;
+
+
+
+
+class StringHashEntry
+{
+private:
+ friend class NameBuffer;
+ String aString;
+ UINT32 nHash;
+
+ static UINT32 MakeHashCode( const String& );
+public:
+ inline StringHashEntry( const String& );
+ inline StringHashEntry( void );
+ inline void operator =( const sal_Char* );
+ inline void operator =( const String& );
+ inline void operator =( const StringHashEntry& );
+ inline BOOL operator ==( const StringHashEntry& ) const;
+};
+
+
+inline StringHashEntry::StringHashEntry( void )
+{
+}
+
+
+inline StringHashEntry::StringHashEntry( const String& r ) : aString( r )
+{
+ nHash = MakeHashCode( r );
+}
+
+
+inline void StringHashEntry::operator =( const sal_Char* p )
+{
+ aString.AssignAscii( p );
+ nHash = MakeHashCode( aString );
+}
+
+
+inline void StringHashEntry::operator =( const String& r )
+{
+ aString = r;
+ nHash = MakeHashCode( r );
+}
+
+
+inline void StringHashEntry::operator =( const StringHashEntry& r )
+{
+ nHash = r.nHash;
+ aString = r.aString;
+}
+
+
+inline BOOL StringHashEntry::operator ==( const StringHashEntry& r ) const
+{
+ return ( nHash == r.nHash && aString == r.aString );
+}
+
+
+
+class NameBuffer : private List, public ExcRoot
+{
+private:
+ UINT16 nBase; // Index-Basis
+public:
+// inline NameBuffer( void ); //#94039# prevent empty rootdata
+ inline NameBuffer( RootData* );
+ inline NameBuffer( RootData*, UINT16 nNewBase );
+
+ virtual ~NameBuffer();
+ inline const String* Get( UINT16 nIndex );
+ inline UINT16 GetLastIndex( void );
+ inline void SetBase( UINT16 nNewBase = 0 );
+ void operator <<( const String& rNewString );
+};
+
+//#94039# prevent empty rootdata
+//inline NameBuffer::NameBuffer( void )
+//{
+// nBase = 0;
+//}
+
+
+inline NameBuffer::NameBuffer( RootData* p ) : ExcRoot( p )
+{
+ nBase = 0;
+}
+
+
+inline NameBuffer::NameBuffer( RootData* p, UINT16 nNewBase ) : ExcRoot( p )
+{
+ nBase = nNewBase;
+}
+
+
+inline const String* NameBuffer::Get( UINT16 n )
+{
+ if( n < nBase )
+ return NULL;
+ else
+ {
+ StringHashEntry* pObj = ( StringHashEntry* ) List::GetObject( n );
+
+ if( pObj )
+ return &pObj->aString;
+ else
+ return NULL;
+ }
+}
+
+
+inline UINT16 NameBuffer::GetLastIndex( void )
+{
+ DBG_ASSERT( Count() + nBase <= 0xFFFF, "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
+
+ return ( UINT16 ) ( Count() + nBase );
+}
+
+
+inline void NameBuffer::SetBase( UINT16 nNewBase )
+{
+ nBase = nNewBase;
+}
+
+
+
+
+class ShrfmlaBuffer : public ExcRoot
+{
+ struct ScAddressHashFunc : public std::unary_function< const ScAddress &, size_t >
+ {
+ size_t operator() (const ScAddress &addr) const;
+ };
+ typedef std::hash_map <ScAddress, USHORT, ScAddressHashFunc> ShrfmlaHash;
+ typedef std::list <ScRange> ShrfmlaList;
+
+ ShrfmlaHash index_hash;
+ ShrfmlaList index_list;
+ size_t mnCurrIdx;
+
+public:
+ ShrfmlaBuffer( RootData* pRD );
+ virtual ~ShrfmlaBuffer();
+ void Clear();
+ void Store( const ScRange& rRange, const ScTokenArray& );
+ USHORT Find (const ScAddress & rAddress ) const;
+
+ static String CreateName( const ScRange& );
+ };
+
+
+
+
+class RangeNameBufferWK3 : private List
+{
+private:
+ struct ENTRY
+ {
+ StringHashEntry aStrHashEntry;
+ ScComplexRefData aScComplexRefDataRel;
+ String aScAbsName;
+ UINT16 nAbsInd; // == 0 -> noch keine Abs-Name!
+ UINT16 nRelInd;
+ BOOL bSingleRef;
+ ENTRY( const String& rName, const String& rScName, const ScComplexRefData& rCRD ) :
+ aStrHashEntry( rName ),
+ aScComplexRefDataRel( rCRD ),
+ aScAbsName( rScName )
+ {
+ nAbsInd = 0;
+ aScAbsName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_ABS" ) );
+ }
+ };
+
+ ScTokenArray* pScTokenArray;
+ UINT16 nIntCount;
+public:
+ RangeNameBufferWK3( void );
+ virtual ~RangeNameBufferWK3();
+ void Add( const String& rName, const ScComplexRefData& rCRD );
+ inline void Add( const String& rName, const ScRange& aScRange );
+ BOOL FindRel( const String& rRef, UINT16& rIndex );
+ BOOL FindAbs( const String& rRef, UINT16& rIndex );
+};
+
+
+inline void RangeNameBufferWK3::Add( const String& rName, const ScRange& aScRange )
+{
+ ScComplexRefData aCRD;
+ ScSingleRefData* pSRD;
+ const ScAddress* pScAddr;
+
+ pSRD = &aCRD.Ref1;
+ pScAddr = &aScRange.aStart;
+ pSRD->SetFlag3D( TRUE );
+ pSRD->nCol = pScAddr->Col();
+ pSRD->nRow = pScAddr->Row();
+ pSRD->nTab = pScAddr->Tab();
+
+ // zunaechst ALLE Refs nur absolut
+ pSRD->SetColRel( FALSE );
+ pSRD->SetRowRel( FALSE );
+ pSRD->SetTabRel( FALSE );
+
+ pSRD = &aCRD.Ref2;
+ pScAddr = &aScRange.aEnd;
+ pSRD->SetFlag3D( TRUE );
+ pSRD->nCol = pScAddr->Col();
+ pSRD->nRow = pScAddr->Row();
+ pSRD->nTab = pScAddr->Tab();
+
+ // zunaechst ALLE Refs nur absolut
+ pSRD->SetColRel( FALSE );
+ pSRD->SetRowRel( FALSE );
+ pSRD->SetTabRel( FALSE );
+
+ Add( rName, aCRD );
+}
+
+
+
+
+class ExtSheetBuffer : private List, public ExcRoot
+{
+private:
+ struct Cont
+ {
+ String aFile;
+ String aTab;
+ UINT16 nTabNum; // 0xFFFF -> noch nicht angelegt
+ // 0xFFFE -> versucht anzulegen, ging aber schief
+ // 0xFFFD -> soll im selben Workbook sein, findet's aber nicht
+ BOOL bSWB;
+ BOOL bLink;
+ Cont( const String& rFilePathAndName, const String& rTabName ) :
+ aFile( rFilePathAndName ),
+ aTab( rTabName )
+ {
+ nTabNum = 0xFFFF; // -> Tabelle noch nicht erzeugt
+ bSWB = bLink = FALSE;
+ }
+ Cont( const String& rFilePathAndName, const String& rTabName,
+ const BOOL bSameWB ) :
+ aFile( rFilePathAndName ),
+ aTab( rTabName )
+ {
+ nTabNum = 0xFFFF; // -> Tabelle noch nicht erzeugt
+ bSWB = bSameWB;
+ bLink = FALSE;
+ }
+ };
+public:
+ inline ExtSheetBuffer( RootData* );
+ virtual ~ExtSheetBuffer();
+
+ sal_Int16 Add( const String& rFilePathAndName,
+ const String& rTabName, const BOOL bSameWorkbook = FALSE );
+
+ BOOL GetScTabIndex( UINT16 nExcSheetIndex, UINT16& rIn_LastTab_Out_ScIndex );
+ BOOL IsLink( const UINT16 nExcSheetIndex ) const;
+ BOOL GetLink( const UINT16 nExcSheetIndex, String &rAppl, String &rDoc ) const;
+
+ void Reset( void );
+};
+
+
+inline ExtSheetBuffer::ExtSheetBuffer( RootData* p ) : ExcRoot( p )
+{
+}
+
+
+
+
+struct ExtName
+{
+ String aName;
+ UINT32 nStorageId;
+ UINT16 nFlags;
+
+ inline ExtName( const String& r, sal_uInt16 n ) : aName( r ), nStorageId( 0 ), nFlags( n ) {}
+
+ BOOL IsDDE( void ) const;
+ BOOL IsOLE( void ) const;
+};
+
+
+
+
+class ExtNameBuff : protected XclImpRoot
+{
+public:
+ explicit ExtNameBuff( const XclImpRoot& rRoot );
+
+ void AddDDE( const String& rName, sal_Int16 nRefIdx );
+ void AddOLE( const String& rName, sal_Int16 nRefIdx, UINT32 nStorageId );
+ void AddName( const String& rName, sal_Int16 nRefIdx );
+
+ const ExtName* GetNameByIndex( sal_Int16 nRefIdx, sal_uInt16 nNameIdx ) const;
+
+ void Reset();
+
+private:
+ typedef ::std::vector< ExtName > ExtNameVec;
+ typedef ::std::map< sal_Int16, ExtNameVec > ExtNameMap;
+
+ ExtNameMap maExtNames;
+};
+
+
+#endif
+
+
diff --git a/sc/source/filter/inc/op.h b/sc/source/filter/inc/op.h
new file mode 100644
index 000000000000..2548bdfa34c3
--- /dev/null
+++ b/sc/source/filter/inc/op.h
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OP_H
+#define SC_OP_H
+
+#include <tools/solar.h>
+#include <patattr.hxx>
+
+// OP-Code-Funktionen
+class SvStream;
+void NI( SvStream &aStream, USHORT nLaenge );
+void OP_BOF( SvStream &aStream, USHORT nLaenge );
+void OP_EOF( SvStream &aStream, USHORT nLaenge );
+void OP_Integer( SvStream &aStream, USHORT nLaenge );
+void OP_Number( SvStream &aStream, USHORT nLaenge );
+void OP_Label( SvStream &aStream, USHORT nLaenge );
+//UNUSED2009-05 void OP_Text( SvStream &aStream, USHORT nLaenge ); // WK3
+void OP_Integer3( SvStream &aStream, USHORT nLaenge ); // WK3
+void OP_Number3( SvStream &aStream, USHORT nLaenge ); // WK3
+void OP_Formula( SvStream &aStream, USHORT nLaenge );
+void OP_Formula3( SvStream &aStream, USHORT nLaenge ); // WK3
+void OP_ColumnWidth( SvStream &aStream, USHORT nLaenge );
+void OP_NamedRange( SvStream &aStream, USHORT nLaenge );
+void OP_SymphNamedRange( SvStream &aStream, USHORT nLaenge );
+void OP_Footer( SvStream &aStream, USHORT nLaenge );
+void OP_Header( SvStream &aStream, USHORT nLaenge );
+void OP_Margins( SvStream &aStream, USHORT nLaenge );
+void OP_HiddenCols( SvStream &aStream, USHORT nLaenge );
+void OP_Window1( SvStream &aStream, USHORT nLaenge );
+void OP_Blank( SvStream &aStream, USHORT nLaenge );
+// Lotus 123 bits.
+void OP_BOF123( SvStream &aStream, USHORT nLaenge );
+void OP_EOF123( SvStream &aStream, USHORT nLaenge );
+void OP_Number123( SvStream &aStream, USHORT nLaenge );
+void OP_Label123( SvStream &aStream, USHORT nLaenge );
+void OP_Formula123( SvStream &aStream, USHORT nLaenge );
+void OP_IEEENumber123(SvStream& r, UINT16 n);
+void OP_Note123(SvStream &aStream, USHORT nLaenge);
+void OP_CreatePattern123(SvStream &aStream, USHORT nLaenge);
+void OP_SheetName123( SvStream &rStream, USHORT nLength );
+void OP_HorAlign123(BYTE nAlignPattern, SfxItemSet& rPattern /* const ScPatternAttr& rPattern*/ );
+void OP_VerAlign123(BYTE nAlignPattern, SfxItemSet& rPattern /* const ScPatternAttr& rPattern*/ );
+void OP_ApplyPatternArea123(SvStream& r);
+
+#endif
diff --git a/sc/source/filter/inc/optab.h b/sc/source/filter/inc/optab.h
new file mode 100644
index 000000000000..d70eb1f29bb0
--- /dev/null
+++ b/sc/source/filter/inc/optab.h
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OPTAB_H
+#define SC_OPTAB_H
+
+typedef void ( *OPCODE_FKT )( SvStream &aStream, USHORT nLaenge );
+
+#define FKT_LIMIT 101
+
+#define FKT_LIMIT123 101
+
+#define LOTUS_EOF 0x01
+
+#define LOTUS_FILEPASSWD 0x4b
+
+#define LOTUS_PATTERN 0x284
+
+#define LOTUS_FORMAT_INDEX 0x800
+
+#define LOTUS_FORMAT_INFO 0x801
+
+#define ROW_FORMAT_MARKER 0x106
+
+#define COL_FORMAT_MARKER 0x107
+
+#endif
+
diff --git a/sc/source/filter/inc/otlnbuff.hxx b/sc/source/filter/inc/otlnbuff.hxx
new file mode 100644
index 000000000000..6ccca361345b
--- /dev/null
+++ b/sc/source/filter/inc/otlnbuff.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OTLNBUFF_HXX
+#define SC_OTLNBUFF_HXX
+
+#include <tools/solar.h>
+
+class ScOutlineArray;
+
+class XclImpOutlineBuffer
+{
+ // -> exctools.cxx
+ private:
+ BYTE* pLevel;
+ BOOL* pOuted;
+ BOOL* pHidden;
+ SCSIZE nSize;
+ SCSIZE nLast;
+ BYTE nMaxLevel;
+ ScOutlineArray* pOutlineArray;
+ BOOL bButtonNormal; // TRUE -> right / under
+ public:
+ XclImpOutlineBuffer( SCSIZE nNewSize );
+ ~XclImpOutlineBuffer();
+ void SetLevel( SCSIZE nIndex, BYTE nVal, BOOL bOuted, BOOL bHidden );
+ void SetOutlineArray( ScOutlineArray* pOArray );
+ void Reset( void );
+ void MakeScOutline( void );
+ void SetLevelRange( SCSIZE nF, SCSIZE nL, BYTE nVal,
+ BOOL bOuted, BOOL bHidden );
+
+ inline BOOL HasOutline( void ) const;
+
+ inline void SetButtonMode( const BOOL bRightOrUnder );
+};
+
+
+
+
+inline BOOL XclImpOutlineBuffer::HasOutline( void ) const
+{
+ return nMaxLevel > 0;
+}
+
+
+inline void XclImpOutlineBuffer::SetButtonMode( const BOOL b )
+{
+ bButtonNormal = b;
+}
+
+
+#endif
+
diff --git a/sc/source/filter/inc/qpro.hxx b/sc/source/filter/inc/qpro.hxx
new file mode 100644
index 000000000000..f631da120373
--- /dev/null
+++ b/sc/source/filter/inc/qpro.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_QPRO_HXX
+#define SC_QPRO_HXX
+
+#include <sal/config.h>
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include <tools/string.hxx>
+
+#include <tools/color.hxx>
+#include "flttypes.hxx"
+#include "ftools.hxx"
+#include "qprostyle.hxx"
+#include "biff.hxx"
+
+// Stream wrapper class
+class ScQProReader : public ScBiffReader
+{
+ public:
+ bool recordsLeft();
+ void SetEof( bool bValue ){ mbEndOfFile = bValue; }
+ bool nextRecord();
+ sal_uInt16 getId() { return mnId; }
+ sal_uInt16 getLength() { return mnLength; }
+ void readString( String &rString, sal_uInt16 nLength );
+ ScQProReader( SfxMedium &rMedium );
+ ~ScQProReader(){ };
+ FltError import( ScDocument *pDoc );
+ FltError readSheet( SCTAB nTab, ScDocument* pDoc, ScQProStyle *pStyle );
+};
+#endif
+
diff --git a/sc/source/filter/inc/qproform.hxx b/sc/source/filter/inc/qproform.hxx
new file mode 100644
index 000000000000..18327cd141df
--- /dev/null
+++ b/sc/source/filter/inc/qproform.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_QPROFORM_HXX
+#define SC_QPROFORM_HXX
+
+#include <sal/config.h>
+#include "formel.hxx"
+#include <tools/string.hxx>
+#include "qpro.hxx"
+
+#include <compiler.hxx>
+typedef OpCode DefTokenId;
+
+enum FUNC_TYPE
+{
+ FT_Return,
+ FT_FuncFix0,
+ FT_FuncFix1,
+ FT_FuncFix2,
+ FT_FuncFix3,
+ FT_FuncFix4,
+ FT_FuncFix5,
+ FT_FuncFix6,
+ FT_FuncVar,
+ FT_DLL,
+ FT_Neg,
+ FT_Op,
+ FT_NotImpl,
+ FT_ConstFloat,
+ FT_Range,
+ FT_Braces,
+ FT_ConstInt,
+ FT_ConstString,
+ FT_NOP,
+ FT_Cref
+};
+
+class QProToSc : public ConverterBase
+{
+ private:
+ TokenId mnAddToken;
+ TokenId mnSubToken;
+ TokenId mn0Token;
+ SvStream& maIn;
+
+ public:
+ static const size_t nBufSize = 256;
+ QProToSc( SvStream &aStr, const ScAddress& rRefPos );
+ ~QProToSc(){ };
+ ConvErr Convert( const ScTokenArray*& pArray, sal_uInt16 nLen,
+ const FORMULA_TYPE eFT = FT_CellFormula );
+ void DoFunc( DefTokenId eOc, sal_uInt16 nArgs, const sal_Char* pExtString );
+ void ReadSRD( ScSingleRefData& rR, sal_Int8 nPage, sal_Int8 nCol, sal_uInt16 rRel );
+ void IncToken( TokenId &aParam );
+ DefTokenId IndexToToken( sal_uInt16 nToken );
+ FUNC_TYPE IndexToType( sal_uInt8 nToken );
+ DefTokenId IndexToDLLId( sal_uInt16 nIndex );
+ const sal_Char* getString( sal_uInt8 nIndex );
+};
+#endif
diff --git a/sc/source/filter/inc/qprostyle.hxx b/sc/source/filter/inc/qprostyle.hxx
new file mode 100644
index 000000000000..ffce2630b310
--- /dev/null
+++ b/sc/source/filter/inc/qprostyle.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_QPROSTYLE_HXX
+#define SC_QPROSTYLE_HXX
+
+#include <sal/config.h>
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include <tools/string.hxx>
+
+#include <tools/color.hxx>
+#include "flttypes.hxx"
+#include "ftools.hxx"
+
+class ScQProStyle
+{
+ enum limits { maxsize = 256 };
+ sal_uInt8 maAlign[ maxsize ];
+ sal_uInt8 maFont[ maxsize ];
+ sal_uInt16 maFontRecord[ maxsize ];
+ sal_uInt16 maFontHeight[ maxsize ];
+ String maFontType[ maxsize ];
+
+ public:
+ ScQProStyle();
+ void SetFormat( ScDocument *pDoc, sal_uInt8 nCol, sal_uInt16 nRow, SCTAB nTab, sal_uInt16 nStyle );
+ void setFontRecord(sal_uInt16 nIndex, sal_uInt16 nData, sal_uInt16 nPtSize)
+ {
+ if (nIndex < maxsize)
+ {
+ maFontRecord[ nIndex ] = nData;
+ maFontHeight[ nIndex ] = nPtSize;
+ }
+ }
+ void setFontType( sal_uInt16 nIndex, String &aLabel )
+ { if (nIndex < maxsize) maFontType[ nIndex ] = aLabel; }
+ void setAlign( sal_uInt16 nIndex, sal_uInt8 nData )
+ { if (nIndex < maxsize) maAlign[ nIndex ] = nData; }
+ void setFont( sal_uInt16 nIndex, sal_uInt8 nData )
+ { if (nIndex < maxsize) maFont[ nIndex ] = nData; }
+};
+#endif
diff --git a/sc/source/filter/inc/root.hxx b/sc/source/filter/inc/root.hxx
new file mode 100644
index 000000000000..facc8b1b2fa0
--- /dev/null
+++ b/sc/source/filter/inc/root.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ROOT_HXX
+#define SC_ROOT_HXX
+
+#include <tools/solar.h>
+#include "global.hxx"
+#include "address.hxx"
+#include "flttypes.hxx"
+#include "filter.hxx"
+#include "excdefs.hxx"
+
+class ScRangeName;
+
+class NameBuffer;
+class RangeNameBufferWK3;
+class ShrfmlaBuffer;
+class ExtNameBuff;
+class ExtSheetBuffer;
+class ExcelToSc;
+
+class XclImpColRowSettings;
+class XclImpAutoFilterBuffer;
+class XclImpPivotCacheList;
+class _ScRangeListTabs;
+
+class XclExpChTrTabId;
+class XclExpUserBViewList;
+
+class XclImpRoot;
+class XclExpRoot;
+
+// ---------------------------------------------------------- Excel Imp~/Exp~ -
+
+struct RootData // -> Inkarnation jeweils im ImportExcel-Objekt!
+{
+ BiffTyp eDateiTyp; // feine Differenzierung
+ ExtSheetBuffer* pExtSheetBuff;
+ ShrfmlaBuffer* pShrfmlaBuff;
+ ExtNameBuff* pExtNameBuff;
+ ExcelToSc* pFmlaConverter;
+ XclImpColRowSettings* pColRowBuff; // Col/Row-Einstellungen 1 Tabelle
+
+ // Biff8
+ XclImpAutoFilterBuffer* pAutoFilterBuffer; // ranges for autofilter and advanced filter
+ _ScRangeListTabs* pPrintRanges;
+ _ScRangeListTabs* pPrintTitles;
+
+ // Erweiterungen fuer Export
+ XclExpChTrTabId* pTabId; // pointer to rec list, do not destroy
+ XclExpUserBViewList* pUserBViewList; // pointer to rec list, do not destroy
+
+ XclImpRoot* pIR;
+ XclExpRoot* pER;
+
+ RootData( void ); // -> exctools.cxx
+ ~RootData(); // -> exctools.cxx
+};
+
+class ExcRoot
+{
+protected:
+ RootData* pExcRoot;
+ inline ExcRoot( RootData* pNexExcRoot ) : pExcRoot( pNexExcRoot ) {}
+ inline ExcRoot( const ExcRoot& rCopy ) : pExcRoot( rCopy.pExcRoot ) {}
+};
+
+// ---------------------------------------------------------- Lotus Imp~/Exp~ -
+
+class LotusRangeList;
+class LotusFontBuffer;
+class LotAttrTable;
+
+
+struct LOTUS_ROOT
+{
+ ScDocument* pDoc;
+ LotusRangeList* pRangeNames;
+ ScRangeName* pScRangeName;
+ CharSet eCharsetQ;
+ Lotus123Typ eFirstType;
+ Lotus123Typ eActType;
+ ScRange aActRange;
+ RangeNameBufferWK3* pRngNmBffWK3;
+ LotusFontBuffer* pFontBuff;
+ LotAttrTable* pAttrTable;
+};
+
+extern LOTUS_ROOT* pLotusRoot; // -> Inkarn. in filter.cxx
+
+// ----------------------------------------------------------------------------
+
+#endif
+
diff --git a/sc/source/filter/inc/rtfexp.hxx b/sc/source/filter/inc/rtfexp.hxx
new file mode 100644
index 000000000000..4733d243d1a5
--- /dev/null
+++ b/sc/source/filter/inc/rtfexp.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RTFEXP_HXX
+#define SC_RTFEXP_HXX
+
+#include "expbase.hxx"
+
+
+class ScRTFExport : public ScExportBase
+{
+ ULONG* pCellX; // kumulierte Zellbreiten einer Tabelle
+
+ void WriteTab( SCTAB nTab );
+ void WriteRow( SCTAB nTab, SCROW nRow );
+ void WriteCell( SCTAB nTab, SCROW nRow, SCCOL nCol );
+
+public:
+
+ ScRTFExport( SvStream&, ScDocument*, const ScRange& );
+ virtual ~ScRTFExport();
+
+ ULONG Write();
+};
+
+
+#endif // SC_RTFEXP_HXX
+
diff --git a/sc/source/filter/inc/rtfimp.hxx b/sc/source/filter/inc/rtfimp.hxx
new file mode 100644
index 000000000000..13ade86b7cd5
--- /dev/null
+++ b/sc/source/filter/inc/rtfimp.hxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RTFIMP_HXX
+#define SC_RTFIMP_HXX
+
+#include "eeimport.hxx"
+
+class ScRTFImport : public ScEEImport
+{
+public:
+ ScRTFImport( ScDocument* pDoc, const ScRange& rRange );
+ ~ScRTFImport();
+};
+
+
+#endif
diff --git a/sc/source/filter/inc/rtfparse.hxx b/sc/source/filter/inc/rtfparse.hxx
new file mode 100644
index 000000000000..135e11e572ae
--- /dev/null
+++ b/sc/source/filter/inc/rtfparse.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RTFPARSE_HXX
+#define SC_RTFPARSE_HXX
+
+#include "eeparser.hxx"
+
+#ifdef SC_RTFPARSE_CXX
+
+struct ScRTFCellDefault
+{
+ SfxItemSet aItemSet;
+ SCCOL nCol;
+ USHORT nTwips; // rechter Rand der Zelle
+ SCCOL nColOverlap; // MergeCell wenn >1, merged cells wenn 0
+
+ ScRTFCellDefault( SfxItemPool* pPool ) :
+ aItemSet( *pPool ), nColOverlap(1) {}
+};
+
+DECLARE_LIST( ScRTFDefaultList, ScRTFCellDefault* )
+// Remove: (const unsigned short &) not sufficiently different from (unsigned short)
+// deswegen ULONG, typedef bringt's auch nicht :-(
+SV_DECL_VARARR_SORT( ScRTFColTwips, ULONG, 16, 4)
+
+#else // SC_RTFPARSE_CXX
+
+struct ScRTFCellDefault;
+class ScRTFDefaultList;
+class ScRTFColTwips;
+
+#endif // SC_RTFPARSE_CXX
+
+
+class EditEngine;
+
+class ScRTFParser : public ScEEParser
+{
+private:
+ ScRTFDefaultList* pDefaultList;
+ ScRTFColTwips* pColTwips;
+ ScRTFCellDefault* pInsDefault;
+ ScRTFCellDefault* pActDefault;
+ ScRTFCellDefault* pDefMerge;
+ ULONG nStartAdjust;
+ USHORT nLastWidth;
+ BOOL bNewDef;
+
+ DECL_LINK( RTFImportHdl, ImportInfo* );
+ inline void NextRow();
+ void EntryEnd( ScEEParseEntry*, const ESelection& );
+ void ProcToken( ImportInfo* );
+ void ColAdjust();
+ BOOL SeekTwips( USHORT nTwips, SCCOL* pCol );
+ void NewCellRow( ImportInfo* );
+
+public:
+ ScRTFParser( EditEngine* );
+ virtual ~ScRTFParser();
+ virtual ULONG Read( SvStream&, const String& rBaseURL );
+};
+
+
+#endif
diff --git a/sc/source/filter/inc/scflt.hxx b/sc/source/filter/inc/scflt.hxx
new file mode 100644
index 000000000000..995de274b28b
--- /dev/null
+++ b/sc/source/filter/inc/scflt.hxx
@@ -0,0 +1,764 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCFLT_HXX
+#define SC_SCFLT_HXX
+
+#include "viewopti.hxx"
+#include "collect.hxx"
+#include <tools/solar.h>
+
+// FehlerNummern
+#define errUnknownFormat 1
+#define errUnknownID 2
+#define errOutOfMemory 3
+
+// Identifiers im FileFormat
+#define ColWidthID 1
+#define ColAttrID 2
+#define RowHeightID 3
+#define RowAttrID 4
+#define FontID 5
+#define NameID 6
+#define TableID 7
+#define ObjectID 8
+#define PatternID 9
+#define DataBaseID 10
+
+// Zeilen/Spalten Flags
+#define crfSoftBreak 1
+#define crfHardBreak 2
+#define crfHidden 4
+
+// Zelltypen
+#define ctValue 1
+#define ctString 2
+#define ctFormula 3
+#define ctNote 4
+
+// FontStyles
+#define ffDontCare 0x00
+#define ffRoman 0x10
+#define ffSwiss 0x20
+#define ffModern 0x30
+#define ffScript 0x40
+#define ffDecorative 0x50
+
+// FontWeight
+#define fwNormal 400
+
+// FontAttribute
+#define atNone 0
+#define atBold 1
+#define atItalic 2
+#define atUnderline 4
+#define atStrikeOut 8
+
+// Horizontale Ausrichtung
+#define hjNone 0
+#define hjLeft 1
+#define hjCenter 2
+#define hjRight 3
+
+// Vertikale Ausrichtung
+#define vjNone 0
+#define vjTop 1
+#define vjCenter 2
+#define vjBottom 3
+
+// AusrichtungsFlags
+#define ojWordBreak 0x01
+#define ojBottomTop 0x02
+#define ojTopBottom 0x04
+
+// ZellRaster
+#define raNone 0
+#define raGray12 1
+#define raGray25 2
+#define raGray50 3
+#define raGray75 4
+#define raGray100 5
+
+// Zellschutz
+#define paProtect 1
+#define paHideFormula 2
+#define paHideAll 4
+#define paHidePrint 8
+
+// ZahlenFormatFlags
+#define vfStandard 0
+#define vfMoney 1
+#define vfThousend 2
+#define vfPercent 3
+#define vfExponent 4
+#define vfZerro 5
+#define vfDate 6
+#define vfTime 7
+#define vfBoolean 8
+#define vfStandardRed 9
+#define vfMoneyRed 10
+#define vfThousendRed 11
+#define vfPercentRed 12
+#define vfExponentRed 13
+#define vfFormula 14
+#define vfString 15
+#define vfNone 16
+
+// DatumsFormatFlags
+#define df_NDMY_Long 0
+#define df_DMY_Long 1
+#define df_MY_Long 2
+#define df_NDM_Long 3
+#define df_DM_Long 4
+#define df_M_Long 5
+#define df_NDMY_Short 6
+#define df_DMY_Short 7
+#define df_MY_Short 8
+#define df_NDM_Short 9
+#define df_DM_Short 10
+#define df_M_Short 11
+#define df_Q_Long 12
+#define df_Q_Short 13
+
+// ZeitFormatFlags
+#define tf_HMS_Long 0
+#define tf_HM_Long 1
+#define tf_HMS_Short 2
+#define tf_HM_Short 3
+
+// Attribute fuer FormatVorlage
+#define pfValue 0x01
+#define pfFont 0x02
+#define pfJustify 0x04
+#define pfFrame 0x08
+#define pfRaster 0x10
+#define pfProtection 0x20
+
+// Displayflags fuer die Tabelle
+#define dfFormula 0x0001 // Formeln
+#define dfZerro 0x0002 // Nullwerte
+#define dfGrid 0x0004 // Gitternetz
+#define dfPageBreak 0x0008 // Seitenumbruch
+#define dfColRowBar 0x0010 // Zeilen/Spalten Koepfe (Dummy)
+#define dfSyntax 0x0020 // Syntax Highlighting
+#define dfPrintPage 0x0040 // Druckbildansicht (Dummy)
+#define dfObjectAll 0x0080 // Objekte anzeigen
+#define dfObjectFrame 0x0100 // Objekte als Platzhalter
+#define dfObjectNone 0x0200 // Objekte nicht anzeigen
+#define dfNoteMark 0x0400 // Notizanzeiger
+#define dfProtectMark 0x0800 // Schutzanzeiger
+
+// Objekt Typen
+#define otNone 0 // s.u.
+#define otOle 1
+#define otImage 2
+#define otChart 3
+
+// Grafik Typen
+#define gtNone 0 // Kann nicht vorkommen
+#define gtOle 1 // Ole 1.0 Objekt
+#define gtImage 2 // Image (Bitmap oder Metafile)
+#define gtChart 3 // Chart
+
+// Datum/Uhrzeit
+struct Sc10DateTime
+{
+ USHORT Year;
+ USHORT Month;
+ USHORT Day;
+ USHORT Hour;
+ USHORT Min;
+ USHORT Sec;
+};
+
+// ZahlenFormate
+struct Sc10ValueFormat
+{
+ BYTE Format; // Zahl, Waehrung, Prozent etc.
+ BYTE Info; // Anzahl Nachkommastellen, Anzahl Stellen, bzw. Datums/Zeitformat
+};
+
+// Fontbeschreibung
+struct Sc10LogFont
+{
+ INT16 lfHeight;
+ INT16 lfWidth;
+ INT16 lfEscapement;
+ INT16 lfOrientation;
+ INT16 lfWeight;
+ BYTE lfItalic;
+ BYTE lfUnderline;
+ BYTE lfStrikeOut;
+ BYTE lfCharSet;
+ BYTE lfOutPrecision;
+ BYTE lfClipPrecision;
+ BYTE lfQuality;
+ BYTE lfPitchAndFamily;
+ sal_Char lfFaceName[32];
+
+ int operator==( const Sc10LogFont& rData ) const;
+};
+
+// RGB-Frabwerte
+struct Sc10Color
+{
+ BYTE Dummy;
+ BYTE Blue;
+ BYTE Green;
+ BYTE Red;
+ int operator==( const Sc10Color& rColor ) const;
+};
+
+// Blockbeschreibung
+struct Sc10BlockRect
+{
+ INT16 x1;
+ INT16 y1;
+ INT16 x2;
+ INT16 y2;
+};
+
+// Datenbank-Bereich
+struct Sc10DataBaseRec
+{
+ sal_Char Name[32];
+ INT16 Tab;
+ Sc10BlockRect Block;
+ BYTE RowHeader;
+ INT16 SortField0;
+ BYTE SortUpOrder0;
+ INT16 SortField1;
+ BYTE SortUpOrder1;
+ INT16 SortField2;
+ BYTE SortUpOrder2;
+ BYTE IncludeFormat;
+ INT16 QueryField0;
+ INT16 QueryOp0;
+ BYTE QueryByString0;
+ sal_Char QueryString0[64];
+ double QueryValue0;
+ INT16 QueryConnect1;
+ INT16 QueryField1;
+ INT16 QueryOp1;
+ BYTE QueryByString1;
+ sal_Char QueryString1[64];
+ double QueryValue1;
+ INT16 QueryConnect2;
+ INT16 QueryField2;
+ INT16 QueryOp2;
+ BYTE QueryByString2;
+ sal_Char QueryString2[64];
+ double QueryValue2;
+};
+
+// Kopf/Fusszeilen-Beschreibung
+struct Sc10HeadFootLine
+{
+ sal_Char Title[128];
+ Sc10LogFont LogFont;
+ BYTE HorJustify;
+ BYTE VerJustify;
+ USHORT Raster;
+ USHORT Frame;
+ Sc10Color TextColor;
+ Sc10Color BackColor;
+ Sc10Color RasterColor;
+ USHORT FrameColor; // Nibble Codierte Farben link oben rechts unten
+ USHORT Reserved;
+
+ int operator==( const Sc10HeadFootLine& rData ) const;
+};
+
+// Seitenformat
+struct Sc10PageFormat
+{
+ Sc10HeadFootLine HeadLine;
+ Sc10HeadFootLine FootLine;
+ INT16 Orientation;
+ INT16 Width;
+ INT16 Height;
+ INT16 NonPrintableX;
+ INT16 NonPrintableY;
+ INT16 Left;
+ INT16 Top;
+ INT16 Right;
+ INT16 Bottom;
+ INT16 Head;
+ INT16 Foot;
+ BYTE HorCenter;
+ BYTE VerCenter;
+ BYTE PrintGrid;
+ BYTE PrintColRow;
+ BYTE PrintNote;
+ BYTE TopBottomDir;
+ sal_Char PrintAreaName[32];
+ Sc10BlockRect PrintArea;
+ sal_Char PrnZoom[6]; // Pascal 6 Byte Realzahl
+ USHORT FirstPageNo;
+ INT16 RowRepeatStart;
+ INT16 RowRepeatEnd;
+ INT16 ColRepeatStart;
+ INT16 ColRepeatEnd;
+ sal_Char Reserved[26];
+
+ int operator==( const Sc10PageFormat& rData ) const;
+};
+
+// Tabellenschutz
+struct Sc10TableProtect
+{
+ sal_Char PassWord[16];
+ USHORT Flags;
+ BYTE Protect;
+};
+
+// Documentschutz
+struct Sc10SheetProtect
+{
+ sal_Char PassWord[16];
+ USHORT Flags;
+ BYTE Protect;
+};
+
+// Dateikopf StarCalc 1.0 Datei
+struct Sc10FileHeader
+{
+ sal_Char CopyRight[30];
+ USHORT Version;
+ sal_Char Reserved[32];
+};
+
+// Benutzer-Definierte Datei-Beschreibung
+struct Sc10FileInfo
+{
+ sal_Char Title[64];
+ sal_Char Thema[64];
+ sal_Char Keys[64];
+ sal_Char Note[256];
+ sal_Char InfoLabel0[16];
+ sal_Char InfoLabel1[16];
+ sal_Char InfoLabel2[16];
+ sal_Char InfoLabel3[16];
+ sal_Char Info0[32];
+ sal_Char Info1[32];
+ sal_Char Info2[32];
+ sal_Char Info3[32];
+ sal_Char CreateAuthor[64];
+ sal_Char ChangeAuthor[64];
+ sal_Char PrintAuthor[64];
+ Sc10DateTime CreateDate;
+ Sc10DateTime ChangeDate;
+ Sc10DateTime PrintDate;
+ sal_uInt32 PageCount;
+ sal_uInt32 ChartCount;
+ sal_uInt32 PictureCount;
+ sal_uInt32 GraphCount;
+ sal_uInt32 OleCount;
+ sal_uInt32 NoteCount;
+ sal_uInt32 TextCellCount;
+ sal_uInt32 ValueCellCount;
+ sal_uInt32 FormulaCellCount;
+ sal_uInt32 CellCount;
+ sal_Char Reserved[52];
+};
+
+// Letze Cursorposition
+struct Sc10EditStateInfo
+{
+ // Cursor Position
+ USHORT CarretX;
+ USHORT CarretY;
+ USHORT CarretZ;
+ // Linke obere Ecke der Tabelle im Fenster
+ USHORT DeltaX;
+ USHORT DeltaY;
+ USHORT DeltaZ;
+ // Ueberfluessig in StarCalc 3.0
+ BYTE DataBaseMode;
+ sal_Char Reserved[51];
+};
+
+// Attribut-Eintrag
+struct Sc10ColData
+{
+ USHORT Row;
+ USHORT Value;
+};
+
+// ZellAttribut-Beschreibung
+struct Sc10ColAttr
+{
+ USHORT Count;
+ Sc10ColData* pData;
+
+ Sc10ColAttr() : pData(NULL) {}
+};
+
+// GraphHeader
+struct Sc10GraphHeader
+{
+ BYTE Typ; // Typ der Grafik (Ole-Objekt, Image (Bitmap oder MetaFile), Chart-Object)
+ INT16 CarretX; // ZellPosition der Grafik
+ INT16 CarretY;
+ INT16 CarretZ;
+ INT32 x; // x,y Abstand zum Zellrand in Pixel (Pixel weil ich Grafiken in Fenstern ablege)
+ INT32 y;
+ INT32 w; // w,h Breite und Hoehe in Pixel
+ INT32 h;
+ BYTE IsRelPos; // Ist die Position relativ zur Zelle oder absolute in der Tabelle
+ BYTE DoPrint; // Soll die Grafik ausgedruckt werden
+ USHORT FrameType; // Art der Umrandung um die Grafik (Keine, Einfach, Doppelt, Einfach Dick, Doppelt Dick)
+ BYTE IsTransparent; // Soll der Hintergrund gezeichnet werden
+ Sc10Color FrameColor; // Umrandungsfarbe als RGB-Wert
+ Sc10Color BackColor; // Hintergrundfarbe als RGB-Wert
+ sal_Char Reserved[32]; // Na was wohl
+};
+
+// ImageHeader
+struct Sc10ImageHeader
+{
+ sal_Char FileName[128]; // Dateiname des urspruenglich eingefuegten Bildes
+ INT16 Typ; // Typ der Grafik (Bitmap oder Metafile)
+ BYTE Linked; // Kann nicht vorkommen
+ INT16 x1; // Urspruengliche Groesse der Grafik (nur fuer Metafiles)
+ INT16 y1;
+ INT16 x2;
+ INT16 y2;
+ sal_uInt32 Size; // Groesse der Grafik in BYTES
+};
+
+// ChartHeader
+struct Sc10ChartHeader
+{
+ INT16 MM; // Meatfile Struktur MapMode, Breite, Hoehe
+ INT16 xExt;
+ INT16 yExt;
+ sal_uInt32 Size; // Groesse der Grafik in BYTES
+};
+
+// ChartSheetData
+struct Sc10ChartSheetData
+{
+ BYTE HasTitle; // Hat das Chart Daten aus der Tabell fuer einen Titel
+ INT16 TitleX; // Zellposition des Titels
+ INT16 TitleY;
+ BYTE HasSubTitle; // Hat das Chart Daten aus der Tabell fuer einen Untertitel
+ INT16 SubTitleX; // Zellposition des Untertitels
+ INT16 SubTitleY;
+ BYTE HasLeftTitle; // Hat das Chart Daten aus der Tabelle fuer einen Linken-Titel
+ INT16 LeftTitleX; // Zellposition des Linken-Titels
+ INT16 LeftTitleY;
+ BYTE HasLegend; // Hat das Chart Daten aus der Tabelle fuer eine Legende
+ INT16 LegendX1; // Zellen der Legende
+ INT16 LegendY1;
+ INT16 LegendX2;
+ INT16 LegendY2;
+ BYTE HasLabel; // Hat das Chart Daten aus der Tabelle fuer die Achsbeschriftung
+ INT16 LabelX1; // Zellen der Achsbeschriftung
+ INT16 LabelY1;
+ INT16 LabelX2;
+ INT16 LabelY2;
+ INT16 DataX1; // Zellen der Daten
+ INT16 DataY1;
+ INT16 DataX2;
+ INT16 DataY2;
+ sal_Char Reserved[64];
+};
+
+#define AGPie2D 1 // Pie Chart 2D
+#define AGPie3D 2 // Pie Chart 3D
+#define AGBar2D 3 // Bar Chart 2D
+#define AGBar3D 4 // Bar Chart 3D
+#define AGGantt 5 // Gantt Diagramm
+#define AGLine 6 // Line Chart
+#define AGLogLine 7 // Logarythmic-Coordinate Chart
+#define AGArea 8 // Area Chart
+#define AGHLC 11 // High-Low-Close Chart
+#define AGPolar 10 // Polar-Coordinate Chart
+
+typedef sal_Char Sc10ChartText[30];
+
+struct Sc10ChartTypeData
+{
+ INT16 NumSets;
+ INT16 NumPoints;
+ INT16 DrawMode;
+ INT16 GraphType;
+ INT16 GraphStyle;
+ sal_Char GraphTitle[80];
+ sal_Char BottomTitle[80];
+ INT16 SymbolData[256];
+ INT16 ColorData[256];
+ INT16 ThickLines[256];
+ INT16 PatternData[256];
+ INT16 LinePatternData[256];
+ INT16 NumGraphStyles[11];
+ INT16 ShowLegend;
+ Sc10ChartText LegendText[256];
+ INT16 ExplodePie;
+ INT16 FontUse;
+ INT16 FontFamily[5];
+ INT16 FontStyle[5];
+ INT16 FontSize[5];
+ INT16 GridStyle;
+ INT16 Labels;
+ INT16 LabelEvery;
+ Sc10ChartText LabelText[50];
+ sal_Char LeftTitle[80];
+ sal_Char Reserved[4646];
+};
+
+
+// FontAttribut
+class Sc10FontData : public ScDataObject
+{
+public:
+ INT16 Height;
+ BYTE CharSet;
+ BYTE PitchAndFamily;
+ sal_Char FaceName[32];
+
+ Sc10FontData( const Sc10FontData& rData ) :
+ ScDataObject( rData ),
+ Height( rData.Height ),
+ CharSet( rData.CharSet ),
+ PitchAndFamily( rData.PitchAndFamily )
+ {
+ strncpy( FaceName, rData.FaceName, sizeof(FaceName) );
+ FaceName[sizeof(FaceName)-1] = 0;
+ }
+ Sc10FontData( SvStream& rStream );
+ virtual ScDataObject* Clone() const { return new Sc10FontData(*this); }
+};
+
+
+// Font-Collection
+class Sc10FontCollection : public ScCollection
+{
+protected:
+ ULONG nError;
+public:
+ Sc10FontCollection( SvStream& rStream );
+ ULONG GetError() { return nError; }
+ Sc10FontData* At(USHORT nIndex) { return (Sc10FontData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+//BereichsDaten
+class Sc10NameData : public ScDataObject
+{
+public :
+ sal_Char Name[32];
+ sal_Char Reference[64];
+ sal_Char Reserved[12];
+
+ Sc10NameData(const Sc10NameData& rData) :
+ ScDataObject( rData )
+ {
+ strncpy(Name, rData.Name, sizeof(Name));
+ Name[sizeof(Name)-1] = 0;
+ strncpy(Reference, rData.Reference, sizeof(Reference));
+ Reference[sizeof(Reference)-1] = 0;
+ memcpy(Reserved, rData.Reserved, sizeof(Reserved));
+ }
+ Sc10NameData(SvStream& rStream);
+ virtual ScDataObject* Clone() const { return new Sc10NameData(*this); }
+};
+
+
+// Bereichs-Collection
+class Sc10NameCollection : public ScCollection
+{
+protected:
+ ULONG nError;
+public:
+ Sc10NameCollection(SvStream& rStream);
+ULONG GetError() { return nError; }
+Sc10NameData* At(USHORT nIndex) { return (Sc10NameData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+// Vorlage-Daten
+class Sc10PatternData : public ScDataObject
+{
+public:
+ sal_Char Name[32];
+ Sc10ValueFormat ValueFormat;
+ Sc10LogFont LogFont;
+ USHORT Attr;
+ USHORT Justify;
+ USHORT Frame;
+ USHORT Raster;
+ USHORT nColor;
+ USHORT FrameColor;
+ USHORT Flags;
+ USHORT FormatFlags;
+ sal_Char Reserved[8];
+
+ Sc10PatternData(const Sc10PatternData& rData) :
+ ScDataObject( rData )
+ {
+ strncpy(Name, rData.Name, sizeof(Name));
+ Name[sizeof(Name)-1] = 0;
+ memcpy(&ValueFormat, &rData.ValueFormat, sizeof(ValueFormat));
+ memcpy(&LogFont, &rData.LogFont, sizeof(LogFont));
+ Attr = rData.Attr;
+ Justify = rData.Justify;
+ Frame = rData.Frame;
+ Raster = rData.Raster;
+ nColor = rData.nColor;
+ FrameColor = rData.FrameColor;
+ Flags = rData.Flags;
+ FormatFlags = rData.FormatFlags;
+ memcpy(Reserved, rData.Reserved, sizeof(Reserved));
+ }
+ Sc10PatternData(SvStream& rStream);
+virtual ScDataObject* Clone() const { return new Sc10PatternData(*this); }
+};
+
+
+// Vorlage-Collection
+class Sc10PatternCollection : public ScCollection
+{
+protected:
+ ULONG nError;
+public:
+ Sc10PatternCollection(SvStream& rStream);
+ ULONG GetError() { return nError; }
+ Sc10PatternData* At(USHORT nIndex) { return (Sc10PatternData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+// DatenBank-Daten
+class Sc10DataBaseData : public ScDataObject
+{
+public:
+ Sc10DataBaseRec DataBaseRec;
+
+ Sc10DataBaseData(const Sc10DataBaseData& rData) :
+ ScDataObject( rData )
+ {
+ memcpy(&DataBaseRec, &rData.DataBaseRec, sizeof(DataBaseRec));
+ }
+ Sc10DataBaseData(SvStream& rStream);
+virtual ScDataObject* Clone() const { return new Sc10DataBaseData(*this); }
+};
+
+
+// DatenBank-Collection
+class Sc10DataBaseCollection : public ScCollection
+{
+protected:
+ ULONG nError;
+ sal_Char ActName[32];
+public:
+ Sc10DataBaseCollection(SvStream& rStream);
+ ULONG GetError() { return nError; }
+ Sc10DataBaseData* At(USHORT nIndex) { return (Sc10DataBaseData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+class Sc10PageData : public ScDataObject
+{
+public:
+ Sc10PageFormat aPageFormat;
+ Sc10PageData( const Sc10PageFormat& rFormat ) : aPageFormat(rFormat) {}
+ int operator==( const Sc10PageData& rData ) const
+ { return aPageFormat == rData.aPageFormat; }
+ virtual ScDataObject* Clone() const;
+};
+
+// Seitenformat-Collection
+class Sc10PageCollection : public ScCollection
+{
+public:
+ Sc10PageCollection() : ScCollection(1,1) {};
+ Sc10PageData* At(USHORT nIndex) { return (Sc10PageData*)ScCollection::At(nIndex); }
+ USHORT InsertFormat( const Sc10PageFormat& rData );
+ void PutToDoc( ScDocument* pDoc );
+private:
+ using ScCollection::At;
+};
+
+
+class ScfStreamProgressBar;
+
+// Import-Klasse
+class Sc10Import
+{
+ SvStream& rStream;
+ ScDocument* pDoc;
+ Sc10Color TextPalette[16];
+ Sc10Color BackPalette[16];
+ Sc10Color RasterPalette[16];
+ Sc10Color FramePalette[16];
+ Sc10SheetProtect SheetProtect;
+ Sc10FontCollection* pFontCollection;
+ Sc10NameCollection* pNameCollection;
+ Sc10PatternCollection* pPatternCollection;
+ Sc10DataBaseCollection* pDataBaseCollection;
+ ULONG nError;
+ INT16 TabCount;
+ SCTAB nShowTab;
+ ScViewOptions aSc30ViewOpt;
+ ScfStreamProgressBar* pPrgrsBar;
+
+public:
+ Sc10Import( SvStream& rStr, ScDocument* pDocument );
+ ~Sc10Import();
+
+ ULONG Import();
+ void LoadFileHeader();
+ void LoadFileInfo();
+ void LoadEditStateInfo();
+ void LoadProtect();
+ void LoadViewColRowBar();
+ void LoadScrZoom();
+ void LoadPalette();
+ void LoadFontCollection();
+ void LoadNameCollection();
+ void ImportNameCollection();
+ void LoadPatternCollection();
+ void LoadDataBaseCollection();
+ void LoadTables();
+ void LoadCol(SCCOL Col, SCTAB Tab);
+ void LoadColAttr(SCCOL Col, SCTAB Tab);
+ void LoadAttr(Sc10ColAttr& rAttr);
+ void ChangeFormat(USHORT nFormat, USHORT nInfo, ULONG& nKey);
+ void LoadObjects();
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/scfobj.hxx b/sc/source/filter/inc/scfobj.hxx
new file mode 100644
index 000000000000..4ed1784f4354
--- /dev/null
+++ b/sc/source/filter/inc/scfobj.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCFOBJ_HXX
+#define SC_SCFOBJ_HXX
+
+#include <tools/solar.h>
+
+class ScDocument;
+class Rectangle;
+
+class Sc10InsertObject
+{
+public:
+ static void InsertChart( ScDocument* pDoc, SCTAB nDestTab, const Rectangle& rRect,
+ SCTAB nSrcTab, USHORT nX1, USHORT nY1, USHORT nX2, USHORT nY2 );
+};
+
+
+#endif
+
diff --git a/sc/source/filter/inc/scmem.h b/sc/source/filter/inc/scmem.h
new file mode 100644
index 000000000000..03e30c1e9fc6
--- /dev/null
+++ b/sc/source/filter/inc/scmem.h
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCMEM_H
+#define SC_SCMEM_H
+
+#include <tools/solar.h>
+
+BOOL MemNew( void );
+void MemDelete( void );
+
+#endif
+
diff --git a/sc/source/filter/inc/tokstack.hxx b/sc/source/filter/inc/tokstack.hxx
new file mode 100644
index 000000000000..06a37639be89
--- /dev/null
+++ b/sc/source/filter/inc/tokstack.hxx
@@ -0,0 +1,408 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TOKSTACK_HXX
+#define SC_TOKSTACK_HXX
+
+#include <string.h>
+#include <tools/debug.hxx>
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+
+#include <vector>
+
+typedef OpCode DefTokenId;
+// in PRODUCT version: ambiguity between OpCode (being USHORT) and UINT16
+// Unfortunately a typedef is just a dumb alias and not a real type ...
+//typedef UINT16 TokenId;
+struct TokenId
+{
+ UINT16 nId;
+
+ TokenId() : nId( 0 ) {}
+ TokenId( UINT16 n ) : nId( n ) {}
+ TokenId( const TokenId& r ) : nId( r.nId ) {}
+ inline TokenId& operator =( const TokenId& r ) { nId = r.nId; return *this; }
+ inline TokenId& operator =( UINT16 n ) { nId = n; return *this; }
+ inline operator UINT16&() { return nId; }
+ inline operator const UINT16&() const { return nId; }
+ inline BOOL operator <( UINT16 n ) const { return nId < n; }
+ inline BOOL operator >( UINT16 n ) const { return nId > n; }
+ inline BOOL operator <=( UINT16 n ) const { return nId <= n; }
+ inline BOOL operator >=( UINT16 n ) const { return nId >= n; }
+ inline BOOL operator ==( UINT16 n ) const { return nId == n; }
+ inline BOOL operator !=( UINT16 n ) const { return nId != n; }
+};
+
+
+//------------------------------------------------------------------------
+struct ScComplexRefData;
+class TokenStack;
+class ScToken;
+
+
+enum E_TYPE
+{
+ T_Id, // Id-Folge
+ T_Str, // String
+ T_D, // Double
+ T_Err, // Error code
+ T_RefC, // Cell Reference
+ T_RefA, // Area Reference
+ T_RN, // Range Name
+ T_Ext, // irgendwas Unbekanntes mit Funktionsnamen
+ T_Nlf, // token for natural language formula
+ T_Matrix, // token for inline arrays
+ T_ExtName, // token for external names
+ T_ExtRefC,
+ T_ExtRefA,
+ T_Error // fuer Abfrage im Fehlerfall
+};
+
+
+
+
+class TokenPool
+{
+ // !ACHTUNG!: externe Id-Basis ist 1, interne 0!
+ // Ausgabe Id = 0 -> Fehlerfall
+ private:
+ String** ppP_Str; // Pool fuer Strings
+ UINT16 nP_Str; // ...mit Groesse
+ UINT16 nP_StrAkt; // ...und Schreibmarke
+
+ double* pP_Dbl; // Pool fuer Doubles
+ UINT16 nP_Dbl;
+ UINT16 nP_DblAkt;
+
+ USHORT* pP_Err; // Pool for error codes
+ UINT16 nP_Err;
+ UINT16 nP_ErrAkt;
+
+ ScSingleRefData** ppP_RefTr; // Pool fuer Referenzen
+ UINT16 nP_RefTr;
+ UINT16 nP_RefTrAkt;
+
+ UINT16* pP_Id; // Pool fuer Id-Folgen
+ UINT16 nP_Id;
+ UINT16 nP_IdAkt;
+ UINT16 nP_IdLast; // letzter Folgen-Beginn
+
+ struct EXTCONT
+ {
+ DefTokenId eId;
+ String aText;
+ EXTCONT( const DefTokenId e, const String& r ) :
+ eId( e ), aText( r ){}
+ };
+ EXTCONT** ppP_Ext;
+ UINT16 nP_Ext;
+ UINT16 nP_ExtAkt;
+
+ struct NLFCONT
+ {
+ ScSingleRefData aRef;
+ NLFCONT( const ScSingleRefData& r ) : aRef( r ) {}
+ };
+ NLFCONT** ppP_Nlf;
+ UINT16 nP_Nlf;
+ UINT16 nP_NlfAkt;
+
+ ScMatrix** ppP_Matrix; // Pool fuer Matricies
+ UINT16 nP_Matrix;
+ UINT16 nP_MatrixAkt;
+
+ /** for storage of external names */
+ struct ExtName
+ {
+ sal_uInt16 mnFileId;
+ String maName;
+ };
+ ::std::vector<ExtName> maExtNames;
+
+ /** for storage of external cell references */
+ struct ExtCellRef
+ {
+ sal_uInt16 mnFileId;
+ String maTabName;
+ ScSingleRefData maRef;
+ };
+ ::std::vector<ExtCellRef> maExtCellRefs;
+
+ /** for storage of external area references */
+ struct ExtAreaRef
+ {
+ sal_uInt16 mnFileId;
+ String maTabName;
+ ScComplexRefData maRef;
+ };
+ ::std::vector<ExtAreaRef> maExtAreaRefs;
+
+ UINT16* pElement; // Array mit Indizes fuer Elemente
+ E_TYPE* pType; // ...mit Typ-Info
+ UINT16* pSize; // ...mit Laengenangabe (Anz. UINT16)
+ UINT16 nElement;
+ UINT16 nElementAkt;
+
+ static const UINT16 nScTokenOff;// Offset fuer SC-Token
+#ifdef DBG_UTIL
+ UINT16 nRek; // Rekursionszaehler
+#endif
+ ScTokenArray* pScToken; // Tokenbastler
+
+ void GrowString( void );
+ void GrowDouble( void );
+//UNUSED2009-05 void GrowError( void );
+ void GrowTripel( void );
+ void GrowId( void );
+ void GrowElement( void );
+ void GrowExt( void );
+ void GrowNlf( void );
+ void GrowMatrix( void );
+ void GetElement( const UINT16 nId );
+ void GetElementRek( const UINT16 nId );
+ public:
+ TokenPool( void );
+ ~TokenPool();
+ inline TokenPool& operator <<( const TokenId nId );
+ inline TokenPool& operator <<( const DefTokenId eId );
+ inline TokenPool& operator <<( TokenStack& rStack );
+ void operator >>( TokenId& rId );
+ inline void operator >>( TokenStack& rStack );
+ inline const TokenId Store( void );
+ const TokenId Store( const double& rDouble );
+//UNUSED2008-05 const TokenId StoreError( USHORT nError );
+
+ // nur fuer Range-Names
+ const TokenId Store( const UINT16 nIndex );
+ inline const TokenId Store( const INT16 nWert );
+ const TokenId Store( const String& rString );
+ const TokenId Store( const ScSingleRefData& rTr );
+ const TokenId Store( const ScComplexRefData& rTr );
+
+ const TokenId Store( const DefTokenId eId, const String& rName );
+ // 4 externals (e.g. AddIns, Makros...)
+ const TokenId StoreNlf( const ScSingleRefData& rTr );
+ const TokenId StoreMatrix();
+ const TokenId StoreExtName( sal_uInt16 nFileId, const String& rName );
+ const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+ const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
+
+ inline const TokenId LastId( void ) const;
+ inline const ScTokenArray* operator []( const TokenId nId );
+ void Reset( void );
+ inline E_TYPE GetType( const TokenId& nId ) const;
+ BOOL IsSingleOp( const TokenId& nId, const DefTokenId eId ) const;
+ const String* GetExternal( const TokenId& nId ) const;
+//UNUSED2008-05 const String* GetString( const TokenId& nId ) const;
+ ScMatrix* GetMatrix( unsigned int n ) const;
+};
+
+
+
+
+class TokenStack
+ // Stack fuer Token-Ids: Id 0 sollte reserviert bleiben als
+ // fehlerhafte Id, da z.B. Get() im Fehlerfall 0 liefert
+{
+ private:
+ TokenId* pStack; // Stack als Array
+ UINT16 nPos; // Schreibmarke
+ UINT16 nSize; // Erster Index ausserhalb des Stacks
+ public:
+ TokenStack( UINT16 nNewSize = 1024 );
+ ~TokenStack();
+ inline TokenStack& operator <<( const TokenId nNewId );
+ inline void operator >>( TokenId &rId );
+
+ inline void Reset( void );
+
+ inline bool HasMoreTokens() const { return nPos > 0; }
+ inline const TokenId Get( void );
+};
+
+
+
+
+inline const TokenId TokenStack::Get( void )
+{
+ DBG_ASSERT( nPos > 0,
+ "*TokenStack::Get(): Leer ist leer, ist leer, ist leer, ist..." );
+
+ TokenId nRet;
+
+ if( nPos == 0 )
+ nRet = 0;
+ else
+ {
+ nPos--;
+ nRet = pStack[ nPos ];
+ }
+
+ return nRet;
+}
+
+
+inline TokenStack &TokenStack::operator <<( const TokenId nNewId )
+{// Element auf Stack
+ DBG_ASSERT( nPos < nSize, "*TokenStack::<<(): Stackueberlauf" );
+ if( nPos < nSize )
+ {
+ pStack[ nPos ] = nNewId;
+ nPos++;
+ }
+
+ return *this;
+}
+
+
+inline void TokenStack::operator >>( TokenId& rId )
+{// Element von Stack
+ DBG_ASSERT( nPos > 0,
+ "*TokenStack::>>(): Leer ist leer, ist leer, ist leer, ..." );
+ if( nPos > 0 )
+ {
+ nPos--;
+ rId = pStack[ nPos ];
+ }
+}
+
+
+inline void TokenStack::Reset( void )
+{
+ nPos = 0;
+}
+
+
+
+
+inline TokenPool& TokenPool::operator <<( const TokenId nId )
+{
+ // POST: nId's werden hintereinander im Pool unter einer neuen Id
+ // abgelegt. Vorgang wird mit >> oder Store() abgeschlossen
+ // nId -> ( UINT16 ) nId - 1;
+ DBG_ASSERT( ( UINT16 ) nId < nScTokenOff,
+ "-TokenPool::operator <<: TokenId im DefToken-Bereich!" );
+
+ if( nP_IdAkt >= nP_Id )
+ GrowId();
+
+ pP_Id[ nP_IdAkt ] = ( ( UINT16 ) nId ) - 1;
+ nP_IdAkt++;
+
+ return *this;
+}
+
+
+inline TokenPool& TokenPool::operator <<( const DefTokenId eId )
+{
+ DBG_ASSERT( ( UINT32 ) eId + nScTokenOff < 0xFFFF,
+ "-TokenPool::operator<<: enmum zu gross!" );
+
+ if( nP_IdAkt >= nP_Id )
+ GrowId();
+
+ pP_Id[ nP_IdAkt ] = ( ( UINT16 ) eId ) + nScTokenOff;
+ nP_IdAkt++;
+
+ return *this;
+}
+
+
+inline TokenPool& TokenPool::operator <<( TokenStack& rStack )
+{
+ if( nP_IdAkt >= nP_Id )
+ GrowId();
+
+ pP_Id[ nP_IdAkt ] = ( ( UINT16 ) rStack.Get() ) - 1;
+ nP_IdAkt++;
+
+ return *this;
+}
+
+
+inline void TokenPool::operator >>( TokenStack& rStack )
+{
+ TokenId nId;
+ *this >> nId;
+ rStack << nId;
+}
+
+
+inline const TokenId TokenPool::Store( void )
+{
+ TokenId nId;
+ *this >> nId;
+ return nId;
+}
+
+
+inline const TokenId TokenPool::Store( const INT16 nWert )
+{
+ return Store( ( double ) nWert );
+}
+
+
+inline const TokenId TokenPool::LastId( void ) const
+{
+ return ( TokenId ) nElementAkt; // stimmt, da Ausgabe mit Offset 1!
+}
+
+
+const inline ScTokenArray* TokenPool::operator []( const TokenId nId )
+{
+ pScToken->Clear();
+
+ if( nId )
+ {//...nur wenn nId > 0!
+#ifdef DBG_UTIL
+ nRek = 0;
+#endif
+ GetElement( ( UINT16 ) nId - 1 );
+ }
+
+ return pScToken;
+}
+
+
+inline E_TYPE TokenPool::GetType( const TokenId& rId ) const
+{
+ E_TYPE nRet;
+
+ UINT16 nId = (UINT16) rId - 1;
+
+ if( nId < nElementAkt )
+ nRet = pType[ nId ] ;
+ else
+ nRet = T_Error;
+
+ return nRet;
+}
+
+
+#endif
+
diff --git a/sc/source/filter/inc/tool.h b/sc/source/filter/inc/tool.h
new file mode 100644
index 000000000000..93cc074d89f6
--- /dev/null
+++ b/sc/source/filter/inc/tool.h
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TOOL_H
+#define SC_TOOL_H
+
+#include <attrib.hxx> //!!! noch noetig?????
+#include <document.hxx>
+
+// Defaultwerte
+const BYTE nDezStd = 0; // Dezimalstellen fuer Standard-Zellen
+const BYTE nDezFloat = 2; // " " Float-Zellen
+
+void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char *pString );
+
+void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, BYTE nFormat, BYTE nSt );
+
+void InitPage( void );
+
+String DosToSystem( sal_Char *pSource );
+
+double SnumToDouble( INT16 nVal );
+
+double Snum32ToDouble( UINT32 nValue );
+
+typedef UINT16 StampTyp;
+
+#define MAKE_STAMP(nF,nS) ((nS&0x0F)+((nF&0x7F)*16))
+ // Bit 0...3 = Bit 0...3 von Stellenzahl
+ // Bit 4...10 = Bit 0...6 von Formatbyte
+
+class FormIdent
+{
+private:
+ StampTyp nStamp; // Identifikations-Schluessel
+ SfxUInt32Item* pAttr; // zugehoeriges Attribut
+public:
+ FormIdent( void )
+ {
+ nStamp = 0;
+ pAttr = NULL;
+ }
+
+ FormIdent( BYTE nFormat, BYTE nSt, SfxUInt32Item& rAttr )
+ {
+ nStamp = MAKE_STAMP( nFormat, nSt );
+ pAttr = &rAttr;
+ }
+
+ FormIdent( BYTE nFormat, BYTE nSt )
+ {
+ nStamp = MAKE_STAMP( nFormat, nSt );
+ pAttr = NULL;
+ }
+
+ BOOL operator ==( const FormIdent& rComp ) const
+ {
+ return ( nStamp == rComp.nStamp );
+ }
+
+ BOOL operator ==( const StampTyp& rStamp ) const
+ {
+ return ( nStamp == rStamp );
+ }
+
+ StampTyp GetStamp( void ) const
+ {
+ return nStamp;
+ }
+
+ SfxUInt32Item* GetAttr( void )
+ {
+ return pAttr;
+ }
+
+ void SetStamp( BYTE nFormat, BYTE nSt )
+ {
+ nStamp = MAKE_STAMP( nFormat, nSt );
+ }
+};
+
+
+#define __nSize 2048
+
+
+
+
+class FormCache
+{
+private:
+ FormIdent aIdents[ __nSize ]; //gepufferte Formate
+ BOOL bValid[ __nSize ];
+ FormIdent aCompareIdent; // zum Vergleichen
+ BYTE nDefaultFormat; // Defaultformat der Datei
+ SvNumberFormatter* pFormTable; // Value-Format-Table-Anker
+ StampTyp nIndex;
+ LanguageType eLanguage; // Systemsprache
+
+ SfxUInt32Item* NewAttr( BYTE nFormat, BYTE nSt );
+public:
+ FormCache( ScDocument*, BYTE nNewDefaultFormat = 0xFF );
+ ~FormCache();
+
+ inline const SfxUInt32Item* GetAttr( BYTE nFormat, BYTE nSt );
+ void SetDefaultFormat( BYTE nD = 0xFF )
+ {
+ nDefaultFormat = nD;
+ }
+};
+
+
+inline const SfxUInt32Item* FormCache::GetAttr( BYTE nFormat, BYTE nSt )
+{
+ // PREC: nFormat = Lotus-Format-Byte
+ // nSt = Stellenzahl
+ // POST: return = zu nFormat und nSt passendes SC-Format
+ SfxUInt32Item* pAttr;
+ SfxUInt32Item* pRet;
+
+ aCompareIdent.SetStamp( nFormat, nSt );
+ nIndex = aCompareIdent.GetStamp();
+ DBG_ASSERT( nIndex < __nSize, "FormCache::GetAttr(): Uuuuuuups... so nicht!" );
+ if( bValid[ nIndex ] )
+ pRet = aIdents[ nIndex ].GetAttr();
+ else
+ {
+ // neues Attribut anlegen
+ pAttr = NewAttr( nFormat, nSt );
+ DBG_ASSERT( pAttr, "FormCache::GetAttr(): Nix Speicherus" );
+
+ aIdents[ nIndex ] = FormIdent( nFormat, nSt, *pAttr );
+ bValid[ nIndex ] = TRUE;
+
+ pRet = pAttr;
+ }
+ return pRet;
+}
+
+#endif
+
diff --git a/sc/source/filter/inc/xcl97dum.hxx b/sc/source/filter/inc/xcl97dum.hxx
new file mode 100644
index 000000000000..a76a93321557
--- /dev/null
+++ b/sc/source/filter/inc/xcl97dum.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCL97DUM_HXX
+#define SC_XCL97DUM_HXX
+
+#include "excrecds.hxx"
+
+// --- class ExcDummy8_xx --------------------------------------------
+
+class ExcDummy8_00a : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const BYTE* GetData() const;
+};
+
+
+class ExcDummy8_00b : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const BYTE* GetData() const;
+};
+
+
+class ExcDummy8_040 : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const BYTE* GetData() const;
+};
+
+
+class ExcDummy8_041 : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const BYTE* GetData() const;
+};
+
+
+class ExcDummy8_02 : public ExcDummyRec
+{
+private:
+ static const BYTE pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const BYTE* GetData() const;
+};
+
+
+#endif // _XCL97DUM_HXX
diff --git a/sc/source/filter/inc/xcl97esc.hxx b/sc/source/filter/inc/xcl97esc.hxx
new file mode 100644
index 000000000000..fde03337cc0f
--- /dev/null
+++ b/sc/source/filter/inc/xcl97esc.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCL97ESC_HXX
+#define SC_XCL97ESC_HXX
+
+#include <memory>
+#include <tools/table.hxx>
+#include <tools/stack.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include "xlescher.hxx"
+#include "xeroot.hxx"
+
+// 0 = Export TBX form controls, 1 = Export OCX form controls.
+#define EXC_EXP_OCX_CTRL 0
+
+namespace utl { class TempFile; }
+
+// ============================================================================
+
+class SvStream;
+
+class XclEscherExGlobal : public EscherExGlobal, protected XclExpRoot
+{
+public:
+ explicit XclEscherExGlobal( const XclExpRoot& rRoot );
+
+private:
+ /** Overloaded to create a new temporary file and return its stream. */
+ virtual SvStream* ImplQueryPictureStream();
+
+private:
+ ::std::auto_ptr< ::utl::TempFile > mxPicTempFile;
+ ::std::auto_ptr< SvStream > mxPicStrm;
+};
+
+// ============================================================================
+
+class XclObj;
+class XclExpDffAnchorBase;
+class XclEscherHostAppData;
+class XclEscherClientData;
+class XclEscherClientTextbox;
+#if EXC_EXP_OCX_CTRL
+class XclExpOcxControlObj;
+#else
+class XclExpTbxControlObj;
+#endif
+
+class XclEscherEx : public EscherEx, protected XclExpRoot
+{
+public:
+ explicit XclEscherEx(
+ const XclExpRoot& rRoot,
+ XclExpObjectManager& rObjMgr,
+ SvStream& rStrm,
+ const XclEscherEx* pParent = 0 );
+ virtual ~XclEscherEx();
+
+ /** Called by MSODRAWING record constructors to initialize the DFF stream
+ fragment they will own. returns the DFF fragment identifier. */
+ sal_uInt32 InitNextDffFragment();
+ /** Called after some data has been written to the DFF stream, to update
+ the end position of the DFF fragment owned by an MSODRAWING record. */
+ void UpdateDffFragmentEnd();
+
+ /** Returns the position of the specified DFF stream fragment. */
+ sal_uInt32 GetDffFragmentPos( sal_uInt32 nFragmentKey );
+ /** Returns the size of the specified DFF stream fragment. */
+ sal_uInt32 GetDffFragmentSize( sal_uInt32 nFragmentKey );
+ /** Returns true, if there is more data left in the DFF stream than owned
+ by the last MSODRAWING record. */
+ bool HasPendingDffData();
+
+ /** Creates a new DFF client anchor object and calculates the anchor
+ position of the passed object. Caller takes ownership! */
+ XclExpDffAnchorBase* CreateDffAnchor( const SdrObject& rSdrObj ) const;
+
+ virtual EscherExHostAppData* StartShape(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& rxShape,
+ const Rectangle* pChildAnchor );
+ virtual void EndShape( UINT16 nShapeType, UINT32 nShapeID );
+ virtual EscherExHostAppData* EnterAdditionalTextGroup();
+
+ /// Flush and merge PicStream into EscherStream
+ void EndDocument();
+
+#if EXC_EXP_OCX_CTRL
+ /** Creates an OCX form control OBJ record from the passed form control.
+ @descr Writes the form control data to the 'Ctls' stream. */
+ XclExpOcxControlObj* CreateCtrlObj(
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+
+private:
+ SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream.
+#else
+ /** Creates a TBX form control OBJ record from the passed form control. */
+ XclExpTbxControlObj* CreateCtrlObj(
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+
+private:
+ /** Tries to get the name of a Basic macro from a control. */
+ void ConvertTbxMacro(
+ XclExpTbxControlObj& rTbxCtrlObj,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::awt::XControlModel > xCtrlModel );
+#endif
+
+ void DeleteCurrAppData();
+
+private:
+ XclExpObjectManager& mrObjMgr;
+ Stack aStack;
+ XclObj* pCurrXclObj;
+ XclEscherHostAppData* pCurrAppData;
+ XclEscherClientData* pTheClientData; // always the same
+ XclEscherClientTextbox* pAdditionalText;
+ USHORT nAdditionalText;
+ sal_uInt32 mnNextKey;
+ bool mbIsRootDff;
+};
+
+// --- class XclEscherHostAppData ------------------------------------
+
+class XclEscherHostAppData : public EscherExHostAppData
+{
+private:
+ BOOL bStackedGroup;
+
+public:
+ XclEscherHostAppData() : bStackedGroup( FALSE )
+ {}
+ inline void SetStackedGroup( BOOL b ) { bStackedGroup = b; }
+ inline BOOL IsStackedGroup() const { return bStackedGroup; }
+};
+
+
+
+// ============================================================================
+
+// --- class XclEscherClientData -------------------------------------
+
+class XclEscherClientData : public EscherExClientRecord_Base
+{
+public:
+ XclEscherClientData() {}
+ virtual void WriteData( EscherEx& rEx ) const;
+};
+
+
+// --- class XclEscherClientTextbox ----------------------------------
+
+class SdrTextObj;
+
+class XclEscherClientTextbox : public EscherExClientRecord_Base, protected XclExpRoot
+{
+private:
+ const SdrTextObj& rTextObj;
+ XclObj* pXclObj;
+
+public:
+ XclEscherClientTextbox(
+ const XclExpRoot& rRoot,
+ const SdrTextObj& rObj,
+ XclObj* pObj );
+
+ //! ONLY for the AdditionalText mimic
+ inline void SetXclObj( XclObj* p ) { pXclObj = p; }
+
+ virtual void WriteData( EscherEx& rEx ) const;
+};
+
+
+
+#endif // _XCL97ESC_HXX
diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx
new file mode 100644
index 000000000000..201562fa752c
--- /dev/null
+++ b/sc/source/filter/inc/xcl97rec.hxx
@@ -0,0 +1,592 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCL97REC_HXX
+#define SC_XCL97REC_HXX
+
+#include "excrecds.hxx"
+#include "xcl97esc.hxx"
+#include "xlstyle.hxx"
+
+// ============================================================================
+
+class XclObj;
+class XclExpMsoDrawing;
+
+class XclExpObjList : public List, public ExcEmptyRec, protected XclExpRoot
+{
+public:
+ explicit XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx );
+ virtual ~XclExpObjList();
+
+ XclObj* First() { return (XclObj*) List::First(); }
+ XclObj* Next() { return (XclObj*) List::Next(); }
+
+ /// return: 1-based ObjId
+ ///! count>=0xFFFF: Obj will be deleted, return 0
+ UINT16 Add( XclObj* );
+
+ inline XclExpMsoDrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; }
+
+ /// close groups and DgContainer opened in ctor
+ void EndSheet();
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclEscherEx& mrEscherEx;
+ XclExpMsoDrawing* pMsodrawingPerSheet;
+ XclExpMsoDrawing* pSolverContainer;
+};
+
+
+// --- class XclObj --------------------------------------------------
+
+class XclTxo;
+class SdrTextObj;
+
+class XclObj : public XclExpRecord
+{
+protected:
+ XclEscherEx& mrEscherEx;
+ XclExpMsoDrawing* pMsodrawing;
+ XclExpMsoDrawing* pClientTextbox;
+ XclTxo* pTxo;
+ sal_uInt16 mnObjType;
+ UINT16 nObjId;
+ UINT16 nGrbit;
+ BOOL bFirstOnSheet;
+
+ bool mbOwnEscher; /// true = Escher part created on the fly.
+
+ /** @param bOwnEscher If set to true, this object will create its escher data.
+ See SetOwnEscher() for details. */
+ explicit XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher = false );
+
+ void ImplWriteAnchor( const XclExpRoot& rRoot, const SdrObject* pSdrObj, const Rectangle* pChildAnchor );
+
+ // overwritten for writing MSODRAWING record
+ virtual void WriteBody( XclExpStream& rStrm );
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+ void SaveTextRecs( XclExpStream& rStrm );
+
+public:
+ virtual ~XclObj();
+
+ inline sal_uInt16 GetObjType() const { return mnObjType; }
+
+ inline void SetId( UINT16 nId ) { nObjId = nId; }
+
+ inline void SetLocked( BOOL b )
+ { b ? nGrbit |= 0x0001 : nGrbit &= ~0x0001; }
+ inline void SetPrintable( BOOL b )
+ { b ? nGrbit |= 0x0010 : nGrbit &= ~0x0010; }
+ inline void SetAutoFill( BOOL b )
+ { b ? nGrbit |= 0x2000 : nGrbit &= ~0x2000; }
+ inline void SetAutoLine( BOOL b )
+ { b ? nGrbit |= 0x4000 : nGrbit &= ~0x4000; }
+
+ // set corresponding Excel object type in OBJ/ftCmo
+ void SetEscherShapeType( UINT16 nType );
+ inline void SetEscherShapeTypeGroup() { mnObjType = EXC_OBJTYPE_GROUP; }
+
+ /** If set to true, this object has created its own escher data.
+ @descr This causes the function EscherEx::EndShape() to not post process
+ this object. This is used i.e. for form controls. They are not handled in
+ the svx base code, so the XclExpEscherOcxCtrl c'tor creates the escher data
+ itself. The svx base code does not receive the correct shape ID after the
+ EscherEx::StartShape() call, which would result in deleting the object in
+ EscherEx::EndShape(). */
+ inline void SetOwnEscher( bool bOwnEscher = true ) { mbOwnEscher = bOwnEscher; }
+ /** Returns true, if the object has created the escher data itself.
+ @descr See SetOwnEscher() for details. */
+ inline bool IsOwnEscher() const { return mbOwnEscher; }
+
+ //! actually writes ESCHER_ClientTextbox
+ void SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj );
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+// --- class XclObjComment -------------------------------------------
+
+class XclObjComment : public XclObj
+{
+public:
+ XclObjComment( XclExpObjectManager& rObjMgr,
+ const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible );
+ virtual ~XclObjComment();
+
+ /** c'tor process for formatted text objects above .
+ @descr used to construct the MSODRAWING Escher object properties. */
+ void ProcessEscherObj( const XclExpRoot& rRoot,
+ const Rectangle& rRect, SdrObject* pCaption, bool bVisible );
+
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+
+// --- class XclObjDropDown ------------------------------------------
+
+class XclObjDropDown : public XclObj
+{
+private:
+ BOOL bIsFiltered;
+
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+protected:
+public:
+ XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt );
+ virtual ~XclObjDropDown();
+};
+
+
+// --- class XclTxo --------------------------------------------------
+
+class SdrTextObj;
+
+class XclTxo : public ExcRecord
+{
+public:
+ XclTxo( const String& rString, sal_uInt16 nFontIx = EXC_FONT_APP );
+ XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rEditObj );
+ XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption );
+
+ inline void SetHorAlign( sal_uInt8 nHorAlign ) { mnHorAlign = nHorAlign; }
+ inline void SetVerAlign( sal_uInt8 nVerAlign ) { mnVerAlign = nVerAlign; }
+
+ virtual void Save( XclExpStream& rStrm );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+private:
+ XclExpStringRef mpString; /// Text and formatting data.
+ sal_uInt16 mnRotation; /// Text rotation.
+ sal_uInt8 mnHorAlign; /// Horizontal alignment.
+ sal_uInt8 mnVerAlign; /// Vertical alignment.
+};
+
+
+// --- class XclObjOle -----------------------------------------------
+
+class XclObjOle : public XclObj
+{
+private:
+
+ const SdrObject& rOleObj;
+ SotStorage* pRootStorage;
+
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+public:
+ XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj );
+ virtual ~XclObjOle();
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+
+// --- class XclObjAny -----------------------------------------------
+
+class XclObjAny : public XclObj
+{
+private:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+public:
+ XclObjAny( XclExpObjectManager& rObjMgr );
+ virtual ~XclObjAny();
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+
+// --- class ExcBof8_Base --------------------------------------------
+
+class ExcBof8_Base : public ExcBof_Base
+{
+protected:
+ UINT32 nFileHistory; // bfh
+ UINT32 nLowestBiffVer; // sfo
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ ExcBof8_Base();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+// --- class ExcBofW8 ------------------------------------------------
+// Header Record fuer WORKBOOKS
+
+class ExcBofW8 : public ExcBof8_Base
+{
+public:
+ ExcBofW8();
+};
+
+
+// --- class ExcBof8 -------------------------------------------------
+// Header Record fuer WORKSHEETS
+
+class ExcBof8 : public ExcBof8_Base
+{
+public:
+ ExcBof8();
+};
+
+
+// --- class ExcBundlesheet8 -----------------------------------------
+
+class ExcBundlesheet8 : public ExcBundlesheetBase
+{
+private:
+ String sUnicodeName;
+ XclExpString GetName() const;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ ExcBundlesheet8( RootData& rRootData, SCTAB nTab );
+ ExcBundlesheet8( const String& rString );
+
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+// --- class XclObproj -----------------------------------------------
+
+class XclObproj : public ExcRecord
+{
+public:
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+// ---- class XclCodename --------------------------------------------
+
+class XclCodename : public ExcRecord
+{
+private:
+ XclExpString aName;
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclCodename( const String& );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+// ---- Scenarios ----------------------------------------------------
+// - ExcEScenarioCell a cell of a scenario range
+// - ExcEScenario all ranges of a scenario table
+// - ExcEScenarioManager list of scenario tables
+
+class ExcEScenarioCell
+{
+private:
+ UINT16 nCol;
+ UINT16 nRow;
+ XclExpString sText;
+
+protected:
+public:
+ ExcEScenarioCell( UINT16 nC, UINT16 nR, const String& rTxt );
+
+ inline sal_Size GetStringBytes()
+ { return sText.GetSize(); }
+
+ void WriteAddress( XclExpStream& rStrm );
+ void WriteText( XclExpStream& rStrm );
+
+ void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+class ExcEScenario : public ExcRecord, private List
+{
+private:
+ sal_Size nRecLen;
+ XclExpString sName;
+ XclExpString sComment;
+ XclExpString sUserName;
+ UINT8 nProtected;
+
+ inline ExcEScenarioCell* _First() { return (ExcEScenarioCell*) List::First(); }
+ inline ExcEScenarioCell* _Next() { return (ExcEScenarioCell*) List::Next(); }
+
+ BOOL Append( UINT16 nCol, UINT16 nRow, const String& rTxt );
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+protected:
+public:
+ ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab );
+ virtual ~ExcEScenario();
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+class ExcEScenarioManager : public ExcRecord, private List
+{
+private:
+ UINT16 nActive;
+
+ inline ExcEScenario* _First() { return (ExcEScenario*) List::First(); }
+ inline ExcEScenario* _Next() { return (ExcEScenario*) List::Next(); }
+
+ inline void Append( ExcEScenario* pScen )
+ { List::Insert( pScen, LIST_APPEND ); }
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+protected:
+public:
+ ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab );
+ virtual ~ExcEScenarioManager();
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+// ============================================================================
+
+/** Represents a SHEETPROTECTION record that stores sheet protection
+ options. Note that a sheet still needs to save its sheet protection
+ options even when it's not protected. */
+class XclExpSheetProtectOptions : public XclExpRecord
+{
+public:
+ explicit XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnOptions; /// Encoded sheet protection options.
+};
+
+// ============================================================================
+
+class XclCalccount : public ExcRecord
+{
+private:
+ UINT16 nCount;
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclCalccount( const ScDocument& );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+
+class XclIteration : public ExcRecord
+{
+private:
+ UINT16 nIter;
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclIteration( const ScDocument& );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+
+class XclDelta : public ExcRecord
+{
+private:
+ double fDelta;
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclDelta( const ScDocument& );
+
+ virtual UINT16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+
+class XclRefmode : public XclExpBoolRecord
+{
+public:
+ XclRefmode( const ScDocument& );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpFilePass : public XclExpRecord
+{
+public:
+ explicit XclExpFilePass( const XclExpRoot& rRoot );
+ virtual ~XclExpFilePass();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpRoot& mrRoot;
+};
+
+// ============================================================================
+
+/** Beginning of User Interface Records */
+class XclExpInterfaceHdr : public XclExpUInt16Record
+{
+public:
+ explicit XclExpInterfaceHdr( sal_uInt16 nCodePage );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** End of User Interface Records */
+class XclExpInterfaceEnd : public XclExpRecord
+{
+public:
+ explicit XclExpInterfaceEnd();
+ virtual ~XclExpInterfaceEnd();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Write Access User Name - This record contains the user name, which is
+ the name you type when you install Excel. */
+class XclExpWriteAccess : public XclExpRecord
+{
+public:
+ explicit XclExpWriteAccess();
+ virtual ~XclExpWriteAccess();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpFileSharing : public XclExpRecord
+{
+public:
+ explicit XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly );
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpString maUserName;
+ sal_uInt16 mnPasswordHash;
+ bool mbRecommendReadOnly;
+};
+
+// ============================================================================
+
+class XclExpProt4Rev : public XclExpRecord
+{
+public:
+ explicit XclExpProt4Rev();
+ virtual ~XclExpProt4Rev();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpProt4RevPass : public XclExpRecord
+{
+public:
+ explicit XclExpProt4RevPass();
+ virtual ~XclExpProt4RevPass();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpRecalcId : public XclExpDummyRecord
+{
+public:
+ explicit XclExpRecalcId();
+};
+
+// ============================================================================
+
+class XclExpBookExt : public XclExpDummyRecord
+{
+public:
+ explicit XclExpBookExt();
+};
+
+
+#endif // _XCL97REC_HXX
diff --git a/sc/source/filter/inc/xechart.hxx b/sc/source/filter/inc/xechart.hxx
new file mode 100644
index 000000000000..5bb75e029210
--- /dev/null
+++ b/sc/source/filter/inc/xechart.hxx
@@ -0,0 +1,1275 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XECHART_HXX
+#define SC_XECHART_HXX
+
+#include <tools/gen.hxx>
+#include "xerecord.hxx"
+#include "xlchart.hxx"
+#include "xlformula.hxx"
+#include "xlstyle.hxx"
+#include "xeroot.hxx"
+#include "xestring.hxx"
+
+class Size;
+
+namespace com { namespace sun { namespace star {
+ namespace awt
+ {
+ struct Rectangle;
+ }
+ namespace frame
+ {
+ class XModel;
+ }
+ namespace chart2
+ {
+ struct ScaleData;
+ class XChartDocument;
+ class XDiagram;
+ class XCoordinateSystem;
+ class XChartType;
+ class XDataSeries;
+ class XAxis;
+ class XTitle;
+ class XFormattedString;
+ class XRegressionCurve;
+ namespace data
+ {
+ class XDataSequence;
+ class XLabeledDataSequence;
+ }
+ }
+} } }
+
+// Common =====================================================================
+
+struct XclExpChRootData;
+class XclExpChChart;
+
+/** Base class for complex chart classes, provides access to other components
+ of the chart.
+
+ Keeps also track of future record levels and writes the needed future
+ records on demand.
+ */
+class XclExpChRoot : public XclExpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+
+public:
+ explicit XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData );
+ virtual ~XclExpChRoot();
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclExpChRoot& GetChRoot() const { return *this; }
+ /** Returns the API Chart document model. */
+ XChartDocRef GetChartDocument() const;
+ /** Returns a reference to the parent chart data object. */
+ XclExpChChart& GetChartData() const;
+ /** Returns chart type info for a unique chart type identifier. */
+ const XclChTypeInfo& GetChartTypeInfo( XclChTypeId eType ) const;
+ /** Returns the first fitting chart type info for the passed service name. */
+ const XclChTypeInfo& GetChartTypeInfo( const ::rtl::OUString& rServiceName ) const;
+
+ /** Returns an info struct about auto formatting for the passed object type. */
+ const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
+
+ /** Starts the API chart document conversion. Must be called once before all API conversion. */
+ void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const;
+ /** Finishes the API chart document conversion. Must be called once after all API conversion. */
+ void FinishConversion() const;
+
+ /** Returns true, if the passed color equals to the specified system color. */
+ bool IsSystemColor( const Color& rColor, sal_uInt16 nSysColorIdx ) const;
+ /** Sets a system color and the respective color identifier. */
+ void SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const;
+
+ /** Converts the passed horizontal coordinate from 1/100 mm to Excel chart units. */
+ sal_Int32 CalcChartXFromHmm( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from 1/100 mm to Excel chart units. */
+ sal_Int32 CalcChartYFromHmm( sal_Int32 nPosY ) const;
+ /** Converts the passed rectangle from 1/100 mm to Excel chart units. */
+ XclChRectangle CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const;
+
+ /** Converts the passed horizontal coordinate from a relative position to Excel chart units. */
+ sal_Int32 CalcChartXFromRelative( double fPosX ) const;
+ /** Converts the passed vertical coordinate from a relative position to Excel chart units. */
+ sal_Int32 CalcChartYFromRelative( double fPosY ) const;
+
+ /** Reads all line properties from the passed property set. */
+ void ConvertLineFormat(
+ XclChLineFormat& rLineFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode ) const;
+ /** Reads solid area properties from the passed property set.
+ @return true = object contains complex fill properties. */
+ bool ConvertAreaFormat(
+ XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode ) const;
+ /** Reads gradient or bitmap area properties from the passed property set. */
+ void ConvertEscherFormat(
+ XclChEscherFormat& rEscherFmt,
+ XclChPicFormat& rPicFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode ) const;
+ /** Reads font properties from the passed property set. */
+ sal_uInt16 ConvertFont(
+ const ScfPropertySet& rPropSet,
+ sal_Int16 nScript ) const;
+
+ /** Reads the pie rotation property and returns the converted angle. */
+ static sal_uInt16 ConvertPieRotation( const ScfPropertySet& rPropSet );
+
+protected:
+ /** Called from XclExpChGroupBase::Save, registers a new future record level. */
+ void RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
+ /** Called from XclExpChFutureRecordBase::Save, Initializes the current future record level. */
+ void InitializeFutureRecBlock( XclExpStream& rStrm );
+ /** Called from XclExpChGroupBase::Save, finalizes the current future record level. */
+ void FinalizeFutureRecBlock( XclExpStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpChRootData > XclExpChRootDataRef;
+ XclExpChRootDataRef mxChData; /// Reference to the root data object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for chart record groups. Provides helper functions to write sub records.
+
+ A chart record group consists of a header record, followed by a CHBEGIN
+ record, followed by group sub records, and finished with a CHEND record.
+ */
+class XclExpChGroupBase : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChGroupBase(
+ const XclExpChRoot& rRoot, sal_uInt16 nFrType,
+ sal_uInt16 nRecId, sal_Size nRecSize = 0 );
+ virtual ~XclExpChGroupBase();
+
+ /** Saves the header record. Calls WriteSubRecords() to let derived classes write sub records. */
+ virtual void Save( XclExpStream& rStrm );
+ /** Derived classes return whether there are any records embedded in this group. */
+ virtual bool HasSubRecords() const;
+ /** Derived classes implement writing any records embedded in this group. */
+ virtual void WriteSubRecords( XclExpStream& rStrm ) = 0;
+
+protected:
+ /** Sets context information for future record blocks. */
+ void SetFutureRecordContext( sal_uInt16 nFrContext,
+ sal_uInt16 nFrValue1 = 0, sal_uInt16 nFrValue2 = 0 );
+
+private:
+ XclChFrBlock maFrBlock; /// Future records block settings.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for chart future records. On saving, the record writes missing
+ CHFRBLOCKBEGIN records automatically.
+ */
+class XclExpChFutureRecordBase : public XclExpFutureRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChFutureRecordBase( const XclExpChRoot& rRoot,
+ XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize = 0 );
+
+ /** Writes missing CHFRBLOCKBEGIN records and this record. */
+ virtual void Save( XclExpStream& rStrm );
+};
+
+// Frame formatting ===========================================================
+
+class XclExpChFramePos : public XclExpRecord
+{
+public:
+ explicit XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode );
+
+ /** Returns read/write access to the frame position data. */
+ inline XclChFramePos& GetFramePosData() { return maData; }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChFramePos maData; /// Position of the frame.
+};
+
+typedef ScfRef< XclExpChFramePos > XclExpChFramePosRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChLineFormat : public XclExpRecord
+{
+public:
+ explicit XclExpChLineFormat( const XclExpChRoot& rRoot );
+
+ /** Converts line formatting properties from the passed property set. */
+ void Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+ /** Sets or clears the automatic flag. */
+ inline void SetAuto( bool bAuto ) { ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO, bAuto ); }
+ /** Sets flag to show or hide an axis. */
+ inline void SetShowAxis( bool bShowAxis )
+ { ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS, bShowAxis ); }
+ /** Sets the line format to the specified default type. */
+ void SetDefault( XclChFrameType eDefFrameType );
+
+ /** Returns true, if the line format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO ); }
+ /** Returns true, if the line style is set to something visible. */
+ inline bool HasLine() const { return maData.mnPattern != EXC_CHLINEFORMAT_NONE; }
+ /** Returns true, if the line contains default formatting according to the passed frame type. */
+ bool IsDefault( XclChFrameType eDefFrameType ) const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChLineFormat maData; /// Contents of the CHLINEFORMAT record.
+ sal_uInt32 mnColorId; /// Line color identifier.
+};
+
+typedef ScfRef< XclExpChLineFormat > XclExpChLineFormatRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChAreaFormat : public XclExpRecord
+{
+public:
+ explicit XclExpChAreaFormat( const XclExpChRoot& rRoot );
+
+ /** Converts area formatting properties from the passed property set.
+ @return true = object contains complex fill properties. */
+ bool Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+ /** Sets or clears the automatic flag. */
+ inline void SetAuto( bool bAuto ) { ::set_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO, bAuto ); }
+ /** Sets the area format to the specified default type. */
+ void SetDefault( XclChFrameType eDefFrameType );
+
+ /** Returns true, if the area format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO ); }
+ /** Returns true, if the area style is set to something visible. */
+ inline bool HasArea() const { return maData.mnPattern != EXC_PATT_NONE; }
+ /** Returns true, if the area contains default formatting according to the passed frame type. */
+ bool IsDefault( XclChFrameType eDefFrameType ) const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChAreaFormat maData; /// Contents of the CHAREAFORMAT record.
+ sal_uInt32 mnPattColorId; /// Pattern color identifier.
+ sal_uInt32 mnBackColorId; /// Pattern background color identifier.
+};
+
+typedef ScfRef< XclExpChAreaFormat > XclExpChAreaFormatRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChEscherFormat : public XclExpChGroupBase
+{
+public:
+ explicit XclExpChEscherFormat( const XclExpChRoot& rRoot );
+
+ /** Converts complex area formatting from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+
+ /** Returns true, if the object contains valid formatting data. */
+ bool IsValid() const;
+
+ /** Writes the CHESCHERFORMAT record group to the stream, if complex formatting is extant. */
+ virtual void Save( XclExpStream& rStrm );
+ /** Returns true, if this record group contains a CHPICFORMAT record. */
+ virtual bool HasSubRecords() const;
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Inserts a color from the contained Escher property set into the color palette. */
+ sal_uInt32 RegisterColor( sal_uInt16 nPropId );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChEscherFormat maData; /// Fill properties for complex areas (CHESCHERFORMAT record).
+ XclChPicFormat maPicFmt; /// Image options, e.g. stretched, stacked (CHPICFORMAT record).
+ sal_uInt32 mnColor1Id; /// First fill color identifier.
+ sal_uInt32 mnColor2Id; /// Second fill color identifier.
+};
+
+typedef ScfRef< XclExpChEscherFormat > XclExpChEscherFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Base class for record groups containing frame formatting.
+
+ Frame formatting can be part of several record groups, e.g. CHFRAME,
+ CHDATAFORMAT, CHDROPBAR. It consists of CHLINEFORMAT, CHAREAFORMAT, and
+ CHESCHERFORMAT group.
+ */
+class XclExpChFrameBase
+{
+public:
+ explicit XclExpChFrameBase();
+ virtual ~XclExpChFrameBase();
+
+protected:
+ /** Converts frame formatting properties from the passed property set. */
+ void ConvertFrameBase( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+ /** Sets the frame formatting to the specified default type. */
+ void SetDefaultFrameBase( const XclExpChRoot& rRoot,
+ XclChFrameType eDefFrameType, bool bIsFrame );
+
+ /** Returns true, if the frame contains default formatting (as if the frame is missing). */
+ bool IsDefaultFrameBase( XclChFrameType eDefFrameType ) const;
+
+ /** Writes all contained frame records to the passed stream. */
+ void WriteFrameRecords( XclExpStream& rStrm );
+
+private:
+ XclExpChLineFormatRef mxLineFmt; /// Line format (CHLINEFORMAT record).
+ XclExpChAreaFormatRef mxAreaFmt; /// Area format (CHAREAFORMAT record).
+ XclExpChEscherFormatRef mxEscherFmt; /// Complex area format (CHESCHERFORMAT record).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHFRAME record group containing object frame properties.
+
+ The CHFRAME group consists of: CHFRAME, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclExpChFrame : public XclExpChGroupBase, public XclExpChFrameBase
+{
+public:
+ explicit XclExpChFrame( const XclExpChRoot& rRoot, XclChObjectType eObjType );
+
+ /** Converts frame formatting properties from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+ /** Returns true, if the frame object contains default formats. */
+ bool IsDefault() const;
+ /** Returns true, if the frame object can be deleted because it contains default formats. */
+ bool IsDeleteable() const;
+
+ /** Writes the entire record group. */
+ virtual void Save( XclExpStream& rStrm );
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChFrame maData; /// Contents of the CHFRAME record.
+ XclChObjectType meObjType; /// Type of the represented object.
+};
+
+typedef ScfRef< XclExpChFrame > XclExpChFrameRef;
+
+// Source links ===============================================================
+
+class XclExpChSourceLink : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > XDataSequenceRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString > XFormattedStringRef;
+ typedef ::com::sun::star::uno::Sequence< XFormattedStringRef > XFormattedStringSeq;
+
+public:
+ explicit XclExpChSourceLink( const XclExpChRoot& rRoot, sal_uInt8 nDestType );
+
+ /** Converts the passed source link, returns the number of linked values. */
+ sal_uInt16 ConvertDataSequence( XDataSequenceRef xDataSeq, bool bSplitToColumns, sal_uInt16 nDefCount = 0 );
+ /** Converts the passed sequence of formatted string objects, returns leading font index. */
+ sal_uInt16 ConvertStringSequence( const XFormattedStringSeq& rStringSeq );
+ /** Converts the number format from the passed property set. */
+ void ConvertNumFmt( const ScfPropertySet& rPropSet, bool bPercent );
+
+ /** Returns true, if this source link contains explicit string data. */
+ inline bool HasString() const { return mxString.is() && !mxString->IsEmpty(); }
+
+ /** Writes the CHSOURCELINK record and optionally a CHSTRING record with explicit string data. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChSourceLink maData; /// Contents of the CHSOURCELINK record.
+ XclTokenArrayRef mxLinkFmla; /// Formula with link to source data.
+ XclExpStringRef mxString; /// Text data (CHSTRING record).
+};
+
+typedef ScfRef< XclExpChSourceLink > XclExpChSourceLinkRef;
+
+// Text =======================================================================
+
+/** The CHFONT record containing a font index for text objects. */
+class XclExpChFont : public XclExpUInt16Record
+{
+public:
+ explicit XclExpChFont( sal_uInt16 nFontIdx );
+};
+
+typedef ScfRef< XclExpChFont > XclExpChFontRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHOBJECTLINK record linking a text object to a specific chart object. */
+class XclExpChObjectLink : public XclExpRecord
+{
+public:
+ explicit XclExpChObjectLink( sal_uInt16 nLinkTarget, const XclChDataPointPos& rPointPos );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChObjectLink maData; /// Contents of the CHOBJECTLINK record.
+};
+
+typedef ScfRef< XclExpChObjectLink > XclExpChObjectLinkRef;
+
+// ----------------------------------------------------------------------------
+
+/** Additional data label settings in the future record CHFRLABELPROPS. */
+class XclExpChFrLabelProps : public XclExpChFutureRecordBase
+{
+public:
+ explicit XclExpChFrLabelProps( const XclExpChRoot& rRoot );
+
+ /** Converts separator and the passed data label flags. */
+ void Convert(
+ const ScfPropertySet& rPropSet, bool bShowSeries,
+ bool bShowCateg, bool bShowValue,
+ bool bShowPercent, bool bShowBubble );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChFrLabelProps maData; /// Contents of the CHFRLABELPROPS record.
+};
+
+typedef ScfRef< XclExpChFrLabelProps > XclExpChFrLabelPropsRef;
+
+// ----------------------------------------------------------------------------
+
+/** Base class for objects with font settings. Provides font conversion helper functions. */
+class XclExpChFontBase
+{
+public:
+ virtual ~XclExpChFontBase();
+
+ /** Derived classes set font color and color identifier to internal data structures. */
+ virtual void SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId ) = 0;
+ /** Derived classes set text rotation to internal data structures. */
+ virtual void SetRotation( sal_uInt16 nRotation ) = 0;
+
+ /** Creates a CHFONT record from the passed font index, calls virtual function SetFont(). */
+ void ConvertFontBase( const XclExpChRoot& rRoot, sal_uInt16 nFontIdx );
+ /** Creates a CHFONT record from the passed font index, calls virtual function SetFont(). */
+ void ConvertFontBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet );
+ /** Converts rotation settings, calls virtual function SetRotation(). */
+ void ConvertRotationBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet, bool bSupportsStacked );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTEXT record group containing text object properties.
+
+ The CHTEXT group consists of: CHTEXT, CHBEGIN, CHFRAMEPOS, CHFONT,
+ CHFORMATRUNS, CHSOURCELINK, CHSTRING, CHFRAME group, CHOBJECTLINK, and CHEND.
+ */
+class XclExpChText : public XclExpChGroupBase, public XclExpChFontBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle > XTitleRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclExpChText( const XclExpChRoot& rRoot );
+
+ /** Sets font color and color identifier to internal data structures. */
+ virtual void SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId );
+ /** Sets text rotation to internal data structures. */
+ virtual void SetRotation( sal_uInt16 nRotation );
+
+ /** Converts all text settings of the passed title text object. */
+ void ConvertTitle( XTitleRef xTitle, sal_uInt16 nTarget );
+ /** Converts all text settings of the passed legend. */
+ void ConvertLegend( const ScfPropertySet& rPropSet );
+ /** Converts all settings of the passed data point caption text object. */
+ bool ConvertDataLabel( const ScfPropertySet& rPropSet,
+ const XclChTypeInfo& rTypeInfo, const XclChDataPointPos& rPointPos );
+ /** Converts all settings of the passed trend line equation box. */
+ void ConvertTrendLineEquation( const ScfPropertySet& rPropSet, const XclChDataPointPos& rPointPos );
+
+ /** Returns true, if the string object does not contain any text data. */
+ inline bool HasString() const { return mxSrcLink.is() && mxSrcLink->HasString(); }
+ /** Returns the flags needed for the CHATTACHEDLABEL record. */
+ sal_uInt16 GetAttLabelFlags() const;
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChText maData; /// Contents of the CHTEXT record.
+ XclExpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record).
+ XclExpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record).
+ XclExpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group).
+ XclExpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclExpChObjectLinkRef mxObjLink; /// Link target for this text object.
+ XclExpChFrLabelPropsRef mxLabelProps; /// Extended data label properties (CHFRLABELPROPS record).
+ sal_uInt32 mnTextColorId; /// Text color identifier.
+};
+
+typedef ScfRef< XclExpChText > XclExpChTextRef;
+
+// Data series ================================================================
+
+/** The CHMARKERFORMAT record containing data point marker formatting data. */
+class XclExpChMarkerFormat : public XclExpRecord
+{
+public:
+ explicit XclExpChMarkerFormat( const XclExpChRoot& rRoot );
+
+ /** Converts symbol properties from the passed property set. */
+ void Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx );
+ /** Converts symbol properties for stock charts from the passed property set. */
+ void ConvertStockSymbol( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, bool bCloseSymbol );
+
+ /** Returns true, if markers are enabled. */
+ inline bool HasMarker() const { return maData.mnMarkerType != EXC_CHMARKERFORMAT_NOSYMBOL; }
+ /** Returns true, if border line of markers is visible. */
+ inline bool HasLineColor() const { return !::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_NOLINE ); }
+ /** Returns true, if fill area of markers is visible. */
+ inline bool HasFillColor() const { return !::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_NOFILL ); }
+
+private:
+ /** Registers marker colors in palette and stores color identifiers. */
+ void RegisterColors( const XclExpChRoot& rRoot );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChMarkerFormat maData; /// Contents of the CHMARKERFORMAT record.
+ sal_uInt32 mnLineColorId; /// Border line color identifier.
+ sal_uInt32 mnFillColorId; /// Fill color identifier.
+};
+
+typedef ScfRef< XclExpChMarkerFormat > XclExpChMarkerFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHPIEFORMAT record containing data point formatting data for pie segments. */
+class XclExpChPieFormat : public XclExpUInt16Record
+{
+public:
+ explicit XclExpChPieFormat();
+
+ /** Sets pie segment properties from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+};
+
+typedef ScfRef< XclExpChPieFormat > XclExpChPieFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CH3DDATAFORMAT record containing the bar type in 3D bar charts. */
+class XclExpCh3dDataFormat : public XclExpRecord
+{
+public:
+ explicit XclExpCh3dDataFormat();
+
+ /** Sets 3d bar properties from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclCh3dDataFormat maData; /// Contents of the CH3DDATAFORMAT record.
+};
+
+typedef ScfRef< XclExpCh3dDataFormat > XclExpCh3dDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHATTACHEDLABEL record that contains the type of a data point label. */
+class XclExpChAttachedLabel : public XclExpUInt16Record
+{
+public:
+ explicit XclExpChAttachedLabel( sal_uInt16 nFlags );
+};
+
+typedef ScfRef< XclExpChAttachedLabel > XclExpChAttLabelRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDATAFORMAT record group containing data point properties.
+
+ The CHDATAFORMAT group consists of: CHDATAFORMAT, CHBEGIN, CHFRAME group,
+ CHMARKERFORMAT, CHPIEFORMAT, CH3DDATAFORMAT, CHSERIESFORMAT,
+ CHATTACHEDLABEL, CHEND.
+ */
+class XclExpChDataFormat : public XclExpChGroupBase, public XclExpChFrameBase
+{
+public:
+ explicit XclExpChDataFormat( const XclExpChRoot& rRoot,
+ const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx );
+
+ /** Converts the passed data series or data point formatting. */
+ void ConvertDataSeries( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo );
+ /** Sets default formatting for a series in a stock chart. */
+ void ConvertStockSeries( const ScfPropertySet& rPropSet, bool bCloseSymbol );
+ /** Converts line formatting for the specified object (e.g. trend lines, error bars). */
+ void ConvertLine( const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+
+ /** Returns true, if this objects describes the formatting of an entire series. */
+ inline bool IsSeriesFormat() const { return maData.maPointPos.mnPointIdx == EXC_CHDATAFORMAT_ALLPOINTS; }
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChDataFormat maData; /// Contents of the CHDATAFORMAT record.
+ XclExpChMarkerFormatRef mxMarkerFmt; /// Data point marker (CHMARKERFORMAT record).
+ XclExpChPieFormatRef mxPieFmt; /// Pie segment format (CHPIEFORMAT record).
+ XclExpRecordRef mxSeriesFmt; /// Series properties (CHSERIESFORMAT record).
+ XclExpCh3dDataFormatRef mx3dDataFmt; /// 3D bar format (CH3DDATAFORMAT record).
+ XclExpChAttLabelRef mxAttLabel; /// Data point label type (CHATTACHEDLABEL record).
+};
+
+typedef ScfRef< XclExpChDataFormat > XclExpChDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERTRENDLINE record containing settings for a trend line. */
+class XclExpChSerTrendLine : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclExpChSerTrendLine( const XclExpChRoot& rRoot );
+
+ /** Converts the passed trend line, returns true if trend line type is supported. */
+ bool Convert( XRegressionCurveRef xRegCurve, sal_uInt16 nSeriesIdx );
+
+ /** Returns formatting information of the trend line, created in Convert(). */
+ inline XclExpChDataFormatRef GetDataFormat() const { return mxDataFmt; }
+ /** Returns formatting of the equation text box, created in Convert(). */
+ inline XclExpChTextRef GetDataLabel() const { return mxLabel; }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChSerTrendLine maData; /// Contents of the CHSERTRENDLINE record.
+ XclExpChDataFormatRef mxDataFmt; /// Formatting settings of the trend line.
+ XclExpChTextRef mxLabel; /// Formatting of the equation text box.
+};
+
+typedef ScfRef< XclExpChSerTrendLine > XclExpChSerTrendLineRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERERRORBAR record containing settings for error bars. */
+class XclExpChSerErrorBar : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChSerErrorBar( const XclExpChRoot& rRoot, sal_uInt8 nBarType );
+
+ /** Converts the passed error bar settings, returns true if error bar type is supported. */
+ bool Convert( XclExpChSourceLink& rValueLink, sal_uInt16& rnValueCount, const ScfPropertySet& rPropSet );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChSerErrorBar maData; /// Contents of the CHSERERRORBAR record.
+};
+
+typedef ScfRef< XclExpChSerErrorBar > XclExpChSerErrorBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERIES record group describing a data series in a chart.
+
+ The CHSERIES group consists of: CHSERIES, CHBEGIN, CHSOURCELINK groups,
+ CHDATAFORMAT groups, CHSERGROUP, CHSERPARENT, CHSERERRORBAR,
+ CHSERTRENDLINE, CHEND.
+ */
+class XclExpChSeries : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclExpChSeries( const XclExpChRoot& rRoot, sal_uInt16 nSeriesIdx );
+
+ /** Converts the passed data series (source links and formatting). */
+ bool ConvertDataSeries(
+ XDiagramRef xDiagram, XDataSeriesRef xDataSeries,
+ const XclChExtTypeInfo& rTypeInfo,
+ sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx );
+ /** Converts the passed data series for stock charts. */
+ bool ConvertStockSeries(
+ XDataSeriesRef xDataSeries,
+ const ::rtl::OUString& rValueRole,
+ sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx, bool bCloseSymbol );
+ /** Converts the passed error bar settings (called at trend line child series). */
+ bool ConvertTrendLine( const XclExpChSeries& rParent, XRegressionCurveRef xRegCurve );
+ /** Converts the passed error bar settings (called at error bar child series). */
+ bool ConvertErrorBar( const XclExpChSeries& rParent, const ScfPropertySet& rPropSet, sal_uInt8 nBarId );
+ /** Converts and inserts category ranges for all inserted series. */
+ void ConvertCategSequence( XLabeledDataSeqRef xCategSeq );
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Initializes members of this series to represent a child of the passed series. */
+ void InitFromParent( const XclExpChSeries& rParent );
+ /** Tries to create trend line series objects (called at parent series). */
+ void CreateTrendLines( XDataSeriesRef xDataSeries );
+ /** Tries to create positive and negative error bar series objects (called at parent series). */
+ void CreateErrorBars( const ScfPropertySet& rPropSet,
+ const ::rtl::OUString& rBarPropName,
+ sal_uInt8 nPosBarId, sal_uInt8 nNegBarId );
+ /** Tries to create an error bar series object (called at parent series). */
+ void CreateErrorBar( const ScfPropertySet& rPropSet,
+ const ::rtl::OUString& rShowPropName, sal_uInt8 nBarId );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChDataFormat > XclExpChDataFormatList;
+
+private:
+ XclChSeries maData; /// Contents of the CHSERIES record.
+ XclExpChSourceLinkRef mxTitleLink; /// Link data for series title.
+ XclExpChSourceLinkRef mxValueLink; /// Link data for series values.
+ XclExpChSourceLinkRef mxCategLink; /// Link data for series category names.
+ XclExpChSourceLinkRef mxBubbleLink; /// Link data for series bubble sizes.
+ XclExpChDataFormatRef mxSeriesFmt; /// CHDATAFORMAT group for series format.
+ XclExpChDataFormatList maPointFmts; /// CHDATAFORMAT groups for data point formats.
+ XclExpChSerTrendLineRef mxTrendLine; /// Trend line settings (CHSERTRENDLINE record).
+ XclExpChSerErrorBarRef mxErrorBar; /// Error bar settings (CHSERERRORBAR record).
+ sal_uInt16 mnGroupIdx; /// Chart type group (CHTYPEGROUP group) this series is assigned to.
+ sal_uInt16 mnSeriesIdx; /// 0-based series index.
+ sal_uInt16 mnParentIdx; /// 0-based index of parent series (trend lines and error bars).
+};
+
+typedef ScfRef< XclExpChSeries > XclExpChSeriesRef;
+
+// Chart type groups ==========================================================
+
+/** Represents the chart type record for all supported chart types. */
+class XclExpChType : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+
+public:
+ explicit XclExpChType( const XclExpChRoot& rRoot );
+
+ /** Converts the passed chart type and the contained data series. */
+ void Convert( XDiagramRef xDiagram, XChartTypeRef xChartType,
+ sal_Int32 nApiAxesSetIdx, bool bSwappedAxesSet, bool bHasXLabels );
+ /** Sets stacking mode (standard or percent) for the series in this chart type group. */
+ void SetStacked( bool bPercent );
+
+ /** Returns true, if this is object represents a valid chart type. */
+ inline bool IsValidType() const { return maTypeInfo.meTypeId != EXC_CHTYPEID_UNKNOWN; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChType maData; /// Contents of the chart type record.
+ XclChTypeInfo maTypeInfo; /// Chart type info for the contained type.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHCHART3D record that contains 3D view settings. */
+class XclExpChChart3d : public XclExpRecord
+{
+public:
+ explicit XclExpChChart3d();
+
+ /** Converts 3d settings for the passed chart type. */
+ void Convert( const ScfPropertySet& rPropSet, bool b3dWallChart );
+ /** Sets flag that the data points are clustered on the X axis. */
+ inline void SetClustered() { ::set_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
+
+ /** Returns true, if the data points are clustered on the X axis. */
+ inline bool IsClustered() const { return ::get_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChChart3d maData; /// Contents of the CHCHART3D record.
+};
+
+typedef ScfRef< XclExpChChart3d > XclExpChChart3dRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHLEGEND record group describing the chart legend.
+
+ The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME
+ group, CHTEXT group, CHEND.
+ */
+class XclExpChLegend : public XclExpChGroupBase
+{
+public:
+ explicit XclExpChLegend( const XclExpChRoot& rRoot );
+
+ /** Converts all legend settings from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChLegend maData; /// Contents of the CHLEGEND record.
+ XclExpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record).
+ XclExpChTextRef mxText; /// Legend text format (CHTEXT group).
+ XclExpChFrameRef mxFrame; /// Legend frame format (CHFRAME group).
+};
+
+typedef ScfRef< XclExpChLegend > XclExpChLegendRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDROPBAR record group describing pos/neg bars in line charts.
+
+ The CHDROPBAR group consists of: CHDROPBAR, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclExpChDropBar : public XclExpChGroupBase, public XclExpChFrameBase
+{
+public:
+ explicit XclExpChDropBar( const XclExpChRoot& rRoot, XclChObjectType eObjType );
+
+ /** Converts and writes the contained frame data to the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChObjectType meObjType; /// Type of the dropbar.
+ sal_uInt16 mnBarDist; /// Distance between bars (CHDROPBAR record).
+};
+
+typedef ScfRef< XclExpChDropBar > XclExpChDropBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTYPEGROUP record group describing a group of series.
+
+ The CHTYPEGROUP group consists of: CHTYPEGROUP, CHBEGIN, a chart type
+ record (e.g. CHBAR, CHLINE, CHAREA, CHPIE, ...), CHCHART3D, CHLEGEND group,
+ CHDROPBAR groups, CHCHARTLINE groups (CHCHARTLINE with CHLINEFORMAT),
+ CHDATAFORMAT group, CHEND.
+ */
+class XclExpChTypeGroup : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+
+public:
+ explicit XclExpChTypeGroup( const XclExpChRoot& rRoot, sal_uInt16 nGroupIdx );
+
+ /** Converts the passed chart type to Excel type settings. */
+ void ConvertType( XDiagramRef xDiagram, XChartTypeRef xChartType,
+ sal_Int32 nApiAxesSetIdx, bool b3dChart, bool bSwappedAxesSet, bool bHasXLabels );
+ /** Converts and inserts all series from the passed chart type. */
+ void ConvertSeries( XDiagramRef xDiagram, XChartTypeRef xChartType,
+ sal_Int32 nGroupAxesSetIdx, bool bPercent, bool bConnectorLines );
+ /** Converts and inserts category ranges for all inserted series. */
+ void ConvertCategSequence( XLabeledDataSeqRef xCategSeq );
+ /** Creates a legend object and converts all legend settings. */
+ void ConvertLegend( const ScfPropertySet& rPropSet );
+
+ /** Returns true, if this chart type group contains at least one valid series. */
+ inline bool IsValidGroup() const { return !maSeries.IsEmpty() && maType.IsValidType(); }
+ /** Returns the index of this chart type group format. */
+ inline sal_uInt16 GetGroupIdx() const { return maData.mnGroupIdx; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChExtTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+ /** Returns true, if the chart is three-dimensional. */
+ inline bool Is3dChart() const { return maTypeInfo.mb3dChart; }
+ /** Returns true, if chart type supports wall and floor format. */
+ inline bool Is3dWallChart() const { return Is3dChart() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE); }
+ /** Returns true, if the series in this chart type group are ordered on the Z axis. */
+ inline bool Is3dDeepChart() const { return Is3dWallChart() && mxChart3d.is() && !mxChart3d->IsClustered(); }
+ /** Returns true, if this chart type can be combined with other types. */
+ inline bool IsCombinable2d() const { return !Is3dChart() && maTypeInfo.mbCombinable2d; }
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Returns an unused format index to be used for the next created series. */
+ sal_uInt16 GetFreeFormatIdx() const;
+ /** Creates all data series of any chart type except stock charts. */
+ void CreateDataSeries( XDiagramRef xDiagram,
+ XDataSeriesRef xDataSeries );
+ /** Creates all data series of a stock chart. */
+ void CreateAllStockSeries( XChartTypeRef xChartType,
+ XDataSeriesRef xDataSeries );
+ /** Creates a single data series of a stock chart. */
+ bool CreateStockSeries( XDataSeriesRef xDataSeries,
+ const ::rtl::OUString& rValueRole, bool bCloseSymbol );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChSeries > XclExpChSeriesList;
+ typedef ScfRefMap< sal_uInt16, XclExpChLineFormat > XclExpChLineFormatMap;
+
+ XclChTypeGroup maData; /// Contents of the CHTYPEGROUP record.
+ XclExpChType maType; /// Chart type (e.g. CHBAR, CHLINE, ...).
+ XclChExtTypeInfo maTypeInfo; /// Extended chart type info.
+ XclExpChSeriesList maSeries; /// List of series data (CHSERIES groups).
+ XclExpChChart3dRef mxChart3d; /// 3D settings (CHCHART3D record).
+ XclExpChLegendRef mxLegend; /// Chart legend (CHLEGEND group).
+ XclExpChDropBarRef mxUpBar; /// White dropbars (CHDROPBAR group).
+ XclExpChDropBarRef mxDownBar; /// Black dropbars (CHDROPBAR group).
+ XclExpChLineFormatMap maChartLines; /// Global line formats (CHCHARTLINE group).
+};
+
+typedef ScfRef< XclExpChTypeGroup > XclExpChTypeGroupRef;
+
+// Axes =======================================================================
+
+class XclExpChLabelRange : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChLabelRange( const XclExpChRoot& rRoot );
+
+ /** Converts category axis scaling settings. */
+ void Convert( const ::com::sun::star::chart2::ScaleData& rScaleData, bool bMirrorOrient );
+ /** Converts position settings of a crossing axis at this axis. */
+ void ConvertAxisPosition( const ScfPropertySet& rPropSet );
+ /** Sets flag for tickmark position between categories or on categories. */
+ inline void SetTicksBetweenCateg( bool bTicksBetween )
+ { ::set_flag( maData.mnFlags, EXC_CHLABELRANGE_BETWEEN, bTicksBetween ); }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChLabelRange maData; /// Contents of the CHLABELRANGE record.
+};
+
+typedef ScfRef< XclExpChLabelRange > XclExpChLabelRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChValueRange : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChValueRange( const XclExpChRoot& rRoot );
+
+ /** Converts value axis scaling settings. */
+ void Convert( const ::com::sun::star::chart2::ScaleData& rScaleData );
+ /** Converts position settings of a crossing axis at this axis. */
+ void ConvertAxisPosition( const ScfPropertySet& rPropSet );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChValueRange maData; /// Contents of the CHVALUERANGE record.
+};
+
+typedef ScfRef< XclExpChValueRange > XclExpChValueRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChTick : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChTick( const XclExpChRoot& rRoot );
+
+ /** Converts axis tick mark settings. */
+ void Convert( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nAxisType );
+ /** Sets font color and color identifier to internal data structures. */
+ void SetFontColor( const Color& rColor, sal_uInt32 nColorId );
+ /** Sets text rotation to internal data structures. */
+ void SetRotation( sal_uInt16 nRotation );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChTick maData; /// Contents of the CHTICK record.
+ sal_uInt32 mnTextColorId; /// Axis labels text color identifier.
+};
+
+typedef ScfRef< XclExpChTick > XclExpChTickRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXIS record group describing an entire chart axis.
+
+ The CHAXIS group consists of: CHAXIS, CHBEGIN, CHLABELRANGE, CHEXTRANGE,
+ CHVALUERANGE, CHFORMAT, CHTICK, CHFONT, CHAXISLINE groups (CHAXISLINE with
+ CHLINEFORMAT, CHAREAFORMAT, and CHESCHERFORMAT group), CHEND.
+ */
+class XclExpChAxis : public XclExpChGroupBase, public XclExpChFontBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;
+
+public:
+ explicit XclExpChAxis( const XclExpChRoot& rRoot, sal_uInt16 nAxisType );
+
+ /** Sets font color and color identifier to internal data structures. */
+ virtual void SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId );
+ /** Sets text rotation to internal data structures. */
+ virtual void SetRotation( sal_uInt16 nRotation );
+
+ /** Converts formatting and scaling settings from the passed axis. */
+ void Convert( XAxisRef xAxis, XAxisRef xCrossingAxis, const XclChExtTypeInfo& rTypeInfo );
+ /** Converts and writes 3D wall/floor properties from the passed diagram. */
+ void ConvertWall( XDiagramRef xDiagram );
+
+ /** Returns the type of this axis. */
+ inline sal_uInt16 GetAxisType() const { return maData.mnType; }
+ /** Returns the axis dimension index used by the chart API. */
+ inline sal_Int32 GetApiAxisDimension() const { return maData.GetApiAxisDimension(); }
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChAxis maData; /// Contents of the CHAXIS record.
+ XclExpChLabelRangeRef mxLabelRange; /// Category scaling (CHLABELRANGE record).
+ XclExpChValueRangeRef mxValueRange; /// Value scaling (CHVALUERANGE record).
+ XclExpChTickRef mxTick; /// Axis ticks (CHTICK record).
+ XclExpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclExpChLineFormatRef mxAxisLine; /// Axis line format (CHLINEFORMAT record).
+ XclExpChLineFormatRef mxMajorGrid; /// Major grid line format (CHLINEFORMAT record).
+ XclExpChLineFormatRef mxMinorGrid; /// Minor grid line format (CHLINEFORMAT record).
+ XclExpChFrameRef mxWallFrame; /// Wall/floor format (sub records of CHFRAME group).
+ sal_uInt16 mnNumFmtIdx; /// Index into number format buffer (CHFORMAT record).
+};
+
+typedef ScfRef< XclExpChAxis > XclExpChAxisRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXESSET record group describing an axes set (X/Y/Z axes).
+
+ The CHAXESSET group consists of: CHAXESSET, CHBEGIN, CHFRAMEPOS, CHAXIS
+ groups, CHTEXT groups, CHPLOTFRAME group (CHPLOTFRAME with CHFRAME group),
+ CHTYPEGROUP group, CHEND.
+ */
+class XclExpChAxesSet : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+
+public:
+ explicit XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSetId );
+
+ /** Converts the passed diagram to chart record data.
+ @return First unused chart type group index. */
+ sal_uInt16 Convert( XDiagramRef xDiagram, sal_uInt16 nFirstGroupIdx );
+
+ /** Returns true, if this axes set exists (returns false if this is a dummy object). */
+ inline bool IsValidAxesSet() const { return !maTypeGroups.IsEmpty(); }
+ /** Returns the index of the axes set (primary/secondary). */
+ inline sal_uInt16 GetAxesSetId() const { return maData.mnAxesSetId; }
+ /** Returns the axes set index used by the chart API. */
+ inline sal_Int32 GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); }
+ /** Returns true, if the chart is three-dimensional. */
+ bool Is3dChart() const;
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Returns first inserted chart type group. */
+ XclExpChTypeGroupRef GetFirstTypeGroup() const;
+ /** Returns last inserted chart type group. */
+ XclExpChTypeGroupRef GetLastTypeGroup() const;
+
+ /** Converts a complete axis object including axis title. */
+ void ConvertAxis( XclExpChAxisRef& rxChAxis, sal_uInt16 nAxisType,
+ XclExpChTextRef& rxChAxisTitle, sal_uInt16 nTitleTarget,
+ XCoordSystemRef xCoordSystem, const XclChExtTypeInfo& rTypeInfo,
+ sal_Int32 nCrossingAxisDim );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChTypeGroup > XclExpChTypeGroupList;
+
+ XclChAxesSet maData; /// Contents of the CHAXESSET record.
+ XclExpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record).
+ XclExpChAxisRef mxXAxis; /// The X axis (CHAXIS group).
+ XclExpChAxisRef mxYAxis; /// The Y axis (CHAXIS group).
+ XclExpChAxisRef mxZAxis; /// The Z axis (CHAXIS group).
+ XclExpChTextRef mxXAxisTitle; /// The X axis title (CHTEXT group).
+ XclExpChTextRef mxYAxisTitle; /// The Y axis title (CHTEXT group).
+ XclExpChTextRef mxZAxisTitle; /// The Z axis title (CHTEXT group).
+ XclExpChFrameRef mxPlotFrame; /// Plot area (CHPLOTFRAME group).
+ XclExpChTypeGroupList maTypeGroups; /// Chart type groups (CHTYPEGROUP group).
+};
+
+typedef ScfRef< XclExpChAxesSet > XclExpChAxesSetRef;
+
+// The chart object ===========================================================
+
+/** Represents the CHCHART record group describing the chart contents.
+
+ The CHCHART group consists of: CHCHART, CHBEGIN, SCL, CHPLOTGROWTH, CHFRAME
+ group, CHSERIES groups, CHPROPERTIES, CHDEFAULTTEXT groups (CHDEFAULTTEXT
+ with CHTEXT groups), CHUSEDAXESSETS, CHAXESSET groups, CHTEXT groups, CHEND.
+ */
+class XclExpChChart : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+
+public:
+ explicit XclExpChChart( const XclExpRoot& rRoot,
+ XChartDocRef xChartDoc, const Rectangle& rChartRect );
+
+ /** Creates, registers and returns a new data series object. */
+ XclExpChSeriesRef CreateSeries();
+ /** Removes the last created data series object from the series list. */
+ void RemoveLastSeries();
+ /** Stores a CHTEXT group that describes a data point label. */
+ void SetDataLabel( XclExpChTextRef xText );
+ /** Sets the plot area position and size to manual mode. */
+ void SetManualPlotArea();
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChSeries > XclExpChSeriesList;
+ typedef XclExpRecordList< XclExpChText > XclExpChTextList;
+
+ XclChRectangle maRect; /// Position of the chart on the sheet (CHCHART record).
+ XclExpChSeriesList maSeries; /// List of series data (CHSERIES groups).
+ XclExpChFrameRef mxFrame; /// Chart frame format (CHFRAME group).
+ XclChProperties maProps; /// Chart properties (CHPROPERTIES record).
+ XclExpChAxesSetRef mxPrimAxesSet; /// Primary axes set (CHAXESSET group).
+ XclExpChAxesSetRef mxSecnAxesSet; /// Secondary axes set (CHAXESSET group).
+ XclExpChTextRef mxTitle; /// Chart title (CHTEXT group).
+ XclExpChTextList maLabels; /// Data point labels (CHTEXT groups).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the group of DFF and OBJ records containing all drawing shapes
+ embedded in the chart object.
+ */
+class XclExpChartDrawing : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpChartDrawing(
+ const XclExpRoot& rRoot,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel,
+ const Size& rChartSize );
+ virtual ~XclExpChartDrawing();
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ ScfRef< XclExpObjectManager > mxObjMgr;
+ ScfRef< XclExpRecordBase > mxObjRecs;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the entire chart substream (all records in BOF/EOF block). */
+class XclExpChart : public XclExpSubStream, protected XclExpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > XModelRef;
+
+public:
+ explicit XclExpChart( const XclExpRoot& rRoot,
+ XModelRef xModel, const Rectangle& rChartRect );
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xecontent.hxx b/sc/source/filter/inc/xecontent.hxx
new file mode 100644
index 000000000000..50c9466d2801
--- /dev/null
+++ b/sc/source/filter/inc/xecontent.hxx
@@ -0,0 +1,352 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XECONTENT_HXX
+#define SC_XECONTENT_HXX
+
+#include "rangelst.hxx"
+#include "xlcontent.hxx"
+#include "xladdress.hxx"
+#include "xerecord.hxx"
+#include "xeroot.hxx"
+#include "xestring.hxx"
+#include "xeformula.hxx"
+
+/* ============================================================================
+Classes to export the big Excel document contents (related to several cells or
+globals for the sheet or document).
+- Shared string table
+- Merged cells
+- Hyperlinks
+- Label ranges
+- Conditional formatting
+- Data validation
+- Web Queries
+============================================================================ */
+
+// Shared string table ========================================================
+
+class XclExpSstImpl;
+
+/** Provides export of the SST (shared string table) record.
+ @descr Contains all strings in the document and writes the SST. */
+class XclExpSst : public XclExpRecordBase
+{
+public:
+ explicit XclExpSst();
+ virtual ~XclExpSst();
+
+ /** Inserts a new string into the table.
+ @return The index of the string in the SST, used in other records. */
+ sal_uInt32 Insert( XclExpStringRef xString );
+
+ /** Writes the complete SST and EXTSST records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef ::std::auto_ptr< XclExpSstImpl > XclExpSstImplPtr;
+ XclExpSstImplPtr mxImpl;
+};
+
+// Merged cells ===============================================================
+
+/** Represents a MERGEDCELLS record containing all merged cell ranges in a sheet. */
+class XclExpMergedcells : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpMergedcells( const XclExpRoot& rRoot );
+
+ /** Appends a new range to the list of merged cell ranges. */
+ void AppendRange( const ScRange& rRange, sal_uInt32 nBaseXFId );
+ /** Returns the XF identifier of the top-left cell in a merged range. */
+ sal_uInt32 GetBaseXFId( const ScAddress& rPos ) const;
+
+ /** Writes the record, if it contains at least one merged cell range. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ ScRangeList maMergedRanges; /// All merged cell ranges of the sheet.
+ ScfUInt32Vec maBaseXFIds; /// The XF identifiers of the top-left cells.
+};
+
+// Hyperlinks =================================================================
+
+class SvxURLField;
+class INetURLObject;
+
+/** Provides export of hyperlink data. */
+class XclExpHyperlink : public XclExpRecord
+{
+public:
+ /** Constructs the HLINK record from an URL text field. */
+ explicit XclExpHyperlink( const XclExpRoot& rRoot,
+ const SvxURLField& rUrlField, const ScAddress& rScPos );
+ virtual ~XclExpHyperlink();
+
+ /** Returns the cell representation text or 0, if not available. */
+ inline const String* GetRepr() const { return mxRepr.get(); }
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Builds file name from the passed file URL. Tries to convert to relative file name.
+ @param rnLevel (out-param) The parent directory level.
+ @param rbRel (out-param) true = path is relative. */
+ String BuildFileName(
+ sal_uInt16& rnLevel, bool& rbRel,
+ const String& rUrl, const XclExpRoot& rRoot ) const;
+
+ /** Writes the body of the HLINK record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef ::std::auto_ptr< String > StringPtr;
+ typedef ::std::auto_ptr< SvStream > SvStreamPtr;
+
+ ScAddress maScPos; /// Position of the hyperlink.
+ StringPtr mxRepr; /// Cell representation text.
+ SvStreamPtr mxVarData; /// Buffer stream with variable data.
+ sal_uInt32 mnFlags; /// Option flags.
+ XclExpStringRef mxTextMark; /// Location within mxRepr
+ ::rtl::OUString msTarget; /// Target URL
+};
+
+typedef XclExpRecordList< XclExpHyperlink > XclExpHyperlinkList;
+
+// Label ranges ===============================================================
+
+/** Provides export of the row/column label range list of a sheet. */
+class XclExpLabelranges : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Fills the cell range lists with all ranges of the current sheet. */
+ explicit XclExpLabelranges( const XclExpRoot& rRoot );
+
+ /** Writes the LABELRANGES record if it contains at least one range. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Fills the specified range list with all label headers of the current sheet.
+ @param rRanges The cell range list to fill.
+ @param xLabelRangesRef The core range list with all ranges.
+ @param nScTab The current Calc sheet index. */
+ void FillRangeList( ScRangeList& rScRanges,
+ ScRangePairListRef xLabelRangesRef, SCTAB nScTab );
+
+private:
+ ScRangeList maRowRanges; /// Cell range list for row labels.
+ ScRangeList maColRanges; /// Cell range list for column labels.
+};
+
+// Conditional formatting =====================================================
+
+class ScCondFormatEntry;
+class XclExpCFImpl;
+
+/** Represents a CF record that contains one condition of a conditional format. */
+class XclExpCF : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry );
+ virtual ~XclExpCF();
+
+private:
+ /** Writes the body of the CF record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef ::std::auto_ptr< XclExpCFImpl > XclExpCFImplPtr;
+ XclExpCFImplPtr mxImpl;
+};
+
+// ----------------------------------------------------------------------------
+
+class ScConditionalFormat;
+
+/** Represents a CONDFMT record that contains all conditions of a conditional format.
+ @descr Contains the conditions which are stored in CF records. */
+class XclExpCondfmt : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat& rCondFormat );
+ virtual ~XclExpCondfmt();
+
+ /** Returns true, if this conditional format contains at least one cell range and CF record. */
+ bool IsValid() const;
+
+ /** Writes the CONDFMT record with following CF records, if there is valid data. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the CONDFMT record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpCF > XclExpCFList;
+
+ XclExpCFList maCFList; /// List of CF records.
+ XclRangeList maXclRanges; /// Cell ranges for this conditional format.
+ String msSeqRef; /// OOXML Sequence of References
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all conditional formats of a specific sheet. */
+class XclExpCondFormatBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Constructs CONDFMT and CF records containing the conditional formats of the current sheet. */
+ explicit XclExpCondFormatBuffer( const XclExpRoot& rRoot );
+
+ /** Writes all contained CONDFMT records with their CF records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpCondfmt > XclExpCondfmtList;
+ XclExpCondfmtList maCondfmtList; /// List of CONDFMT records.
+};
+
+// Data Validation ============================================================
+
+class ScValidationData;
+
+/** Provides export of the data of a DV record.
+ @descr This record contains the settings for a data validation. In detail
+ this is a pointer to the core validation data and a cell range list with all
+ affected cells. The handle index is used to optimize list search algorithm. */
+class XclExpDV : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpDV( const XclExpRoot& rRoot, ULONG nScHandle );
+ virtual ~XclExpDV();
+
+ /** Returns the core handle of the validation data. */
+ inline ULONG GetScHandle() const { return mnScHandle; }
+
+ /** Inserts a new cell range into the cell range list. */
+ void InsertCellRange( const ScRange& rPos );
+ /** Converts the Calc range list to the Excel range list.
+ @return false = Resulting range list empty - do not write this record. */
+ bool Finalize();
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the DV record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ ScRangeList maScRanges; /// Calc range list with all affected cells.
+ XclRangeList maXclRanges; /// Excel range list with all affected cells.
+ XclExpString maPromptTitle; /// The prompt title.
+ XclExpString maPromptText; /// The prompt text.
+ XclExpString maErrorTitle; /// The error title.
+ XclExpString maErrorText; /// The error text.
+ XclExpStringRef mxString1; /// String for first condition formula.
+ XclTokenArrayRef mxTokArr1; /// Formula for first condition.
+ ::rtl::OUString msFormula1; /// OOXML Formula for first condition.
+ XclTokenArrayRef mxTokArr2; /// Formula for second condition.
+ ::rtl::OUString msFormula2; /// OOXML Formula for second condition.
+ sal_uInt32 mnFlags; /// Miscellaneous flags.
+ ULONG mnScHandle; /// The core handle for quick list search.
+};
+
+// ----------------------------------------------------------------------------
+
+/** This class contains the DV record list following the DVAL record. */
+class XclExpDval : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpDval( const XclExpRoot& rRoot );
+ virtual ~XclExpDval();
+
+ /** Inserts the cell range into the range list of the DV record with the specified handle. */
+ void InsertCellRange( const ScRange& rRange, ULONG nScHandle );
+
+ /** Writes the DVAL record and the DV record list. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Searches for or creates a XclExpDV record object with the specified handle. */
+ XclExpDV& SearchOrCreateDv( ULONG nScHandle );
+
+ /** Writes the body of the DVAL record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpDV > XclExpDVList;
+ typedef XclExpDVList::RecordRefType XclExpDVRef;
+
+ XclExpDVList maDVList; /// List of DV records
+ XclExpDVRef mxLastFoundDV; /// For search optimization.
+};
+
+// Web Queries ================================================================
+
+/** Contains all records for a web query (linked tables in an HTML document).
+ @descr mode 1 (entire document): mpQryTables==0, mbEntireDoc==true;
+ mode 2 (all tables): mpQryTables==0, mbEntireDoc==false;
+ mode 3 (custom range list): mpQryTables!=0, mbEntireDoc==false. */
+class XclExpWebQuery : public XclExpRecordBase
+{
+public:
+ /** Constructs a web query record container with settings from Calc. */
+ explicit XclExpWebQuery(
+ const String& rRangeName,
+ const String& rUrl,
+ const String& rSource,
+ sal_Int32 nRefrSecs );
+ virtual ~XclExpWebQuery();
+
+ /** Writes all needed records for this web query. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclExpString maDestRange; /// Destination range.
+ XclExpString maUrl; /// Source document URL.
+ XclExpStringRef mxQryTables; /// List of source range names.
+ sal_Int16 mnRefresh; /// Refresh time in minutes.
+ bool mbEntireDoc; /// true = entire document.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all web query records for this document. */
+class XclExpWebQueryBuffer : public XclExpRecordList< XclExpWebQuery >
+{
+public:
+ explicit XclExpWebQueryBuffer( const XclExpRoot& rRoot );
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx
new file mode 100644
index 000000000000..d227db184f1a
--- /dev/null
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -0,0 +1,435 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEESCHER_HXX
+#define SC_XEESCHER_HXX
+
+#include <vcl/graph.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include "xcl97rec.hxx"
+#include "xlescher.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace script { struct ScriptEventDescriptor; }
+} } }
+
+// DFF client anchor ==========================================================
+
+/** Base class for DFF client anchor atoms used in spreadsheets. */
+class XclExpDffAnchorBase : public EscherExClientAnchor_Base, protected XclExpRoot
+{
+public:
+ /** Constructs a dummy client anchor. */
+ explicit XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 );
+
+ /** Sets the flags according to the passed SdrObject. */
+ void SetFlags( const SdrObject& rSdrObj );
+ /** Sets the anchor position and flags according to the passed SdrObject. */
+ void SetSdrObject( const SdrObject& rSdrObj );
+
+ /** Writes the DFF client anchor structure with the current anchor position. */
+ void WriteDffData( EscherEx& rEscherEx ) const;
+
+ /** Called from SVX DFF converter.
+ @param rRect The object anchor rectangle to be exported (in twips). */
+ virtual void WriteData( EscherEx& rEscherEx, const Rectangle& rRect );
+
+private:
+ virtual void ImplSetFlags( const SdrObject& rSdrObj );
+ virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit );
+
+protected: // for access in derived classes
+ XclObjAnchor maAnchor; /// The client anchor data.
+ sal_uInt16 mnFlags; /// Flags for DFF stream export.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of an object in a Calc sheet. */
+class XclExpDffSheetAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffSheetAnchor( const XclExpRoot& rRoot );
+
+private:
+ virtual void ImplSetFlags( const SdrObject& rSdrObj );
+ virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit );
+
+private:
+ SCTAB mnScTab; /// Calc sheet index.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of a shape in an embedded draw page. */
+class XclExpDffEmbeddedAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot,
+ const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY );
+
+private:
+ virtual void ImplSetFlags( const SdrObject& rSdrObj );
+ virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit );
+
+private:
+ Size maPageSize;
+ sal_Int32 mnScaleX;
+ sal_Int32 mnScaleY;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of a note object. */
+class XclExpDffNoteAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of a cell dropdown object. */
+class XclExpDffDropDownAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos );
+};
+
+// MSODRAWING* records ========================================================
+
+/** Base class for records holding DFF stream fragments. */
+class XclExpMsoDrawingBase : public XclExpRecord
+{
+public:
+ explicit XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+protected:
+ XclEscherEx& mrEscherEx; /// Reference to the DFF converter containing the DFF stream.
+ sal_uInt32 mnFragmentKey; /// The key of the DFF stream fragment to be written by this record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** The MSODRAWINGGROUP record contains the DGGCONTAINER with global DFF data
+ such as the picture container.
+ */
+class XclExpMsoDrawingGroup : public XclExpMsoDrawingBase
+{
+public:
+ explicit XclExpMsoDrawingGroup( XclEscherEx& rEscherEx );
+};
+
+// ----------------------------------------------------------------------------
+
+/** One or more MSODRAWING records contain the DFF stream data for a drawing
+ shape.
+ */
+class XclExpMsoDrawing : public XclExpMsoDrawingBase
+{
+public:
+ explicit XclExpMsoDrawing( XclEscherEx& rEscherEx );
+};
+
+// ============================================================================
+
+/** Provides export of bitmap data to an IMGDATA record. */
+class XclExpImgData : public XclExpRecordBase
+{
+public:
+ explicit XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId );
+
+ /** Writes the BITMAP record. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ Graphic maGraphic; /// The VCL graphic.
+ sal_uInt16 mnRecId; /// Record identifier for the IMGDATA record.
+};
+
+// ============================================================================
+
+/** Helper class for form controils to manage spreadsheet links . */
+class XclExpControlHelper : protected XclExpRoot
+{
+public:
+ explicit XclExpControlHelper( const XclExpRoot& rRoot );
+ virtual ~XclExpControlHelper();
+
+protected:
+ /** Tries to get spreadsheet cell link and source range link from the passed shape. */
+ void ConvertSheetLinks(
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+
+ /** Returns the Excel token array of the cell link, or 0, if no link present. */
+ inline const XclTokenArray* GetCellLinkTokArr() const { return mxCellLink.get(); }
+ /** Returns the Excel token array of the source range, or 0, if no link present. */
+ inline const XclTokenArray* GetSourceRangeTokArr() const { return mxSrcRange.get(); }
+ /** Returns the number of entries in the source range, or 0, if no source set. */
+ inline sal_uInt16 GetSourceEntryCount() const { return mnEntryCount; }
+
+ /** Writes a formula with special style only valid in OBJ records. */
+ void WriteFormula( XclExpStream& rStrm, const XclTokenArray& rTokArr ) const;
+ /** Writes a formula subrecord with special style only valid in OBJ records. */
+ void WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId, const XclTokenArray& rTokArr ) const;
+
+private:
+ XclTokenArrayRef mxCellLink; /// Formula for linked cell.
+ XclTokenArrayRef mxSrcRange; /// Formula for source data range.
+ sal_uInt16 mnEntryCount; /// Number of entries in source range.
+};
+
+// ----------------------------------------------------------------------------
+
+#if EXC_EXP_OCX_CTRL
+
+/** Represents an OBJ record for an OCX form control. */
+class XclExpOcxControlObj : public XclObj, public XclExpControlHelper
+{
+public:
+ explicit XclExpOcxControlObj(
+ XclExpObjectManager& rObjMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor,
+ const String& rClassName,
+ sal_uInt32 nStrmStart, sal_uInt32 nStrmSize );
+
+private:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+private:
+ String maClassName; /// Class name of the control.
+ sal_uInt32 mnStrmStart; /// Start position in 'Ctls' stream.
+ sal_uInt32 mnStrmSize; /// Size in 'Ctls' stream.
+};
+
+#else
+
+/** Represents an OBJ record for an TBX form control. */
+class XclExpTbxControlObj : public XclObj, public XclExpControlHelper
+{
+public:
+ explicit XclExpTbxControlObj(
+ XclExpObjectManager& rObjMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+
+ /** Sets the name of a macro attached to this control.
+ @return true = The passed event descriptor was valid, macro name has been found. */
+ bool SetMacroLink( const ::com::sun::star::script::ScriptEventDescriptor& rEvent );
+
+private:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+ /** Writes an ftMacro subrecord containing a macro link, or nothing, if no macro present. */
+ void WriteMacroSubRec( XclExpStream& rStrm );
+ /** Writes a subrecord containing a cell link, or nothing, if no link present. */
+ void WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId );
+ /** Writes the ftSbs sub structure containing scrollbar data. */
+ void WriteSbs( XclExpStream& rStrm );
+
+private:
+ ScfInt16Vec maMultiSel; /// Indexes of all selected entries in a multi selection.
+ XclTokenArrayRef mxMacroLink; /// Token array containing a link to an attached macro.
+ XclTbxEventType meEventType; /// Type of supported macro event.
+ sal_Int32 mnHeight; /// Height of the control.
+ sal_uInt16 mnState; /// Checked/unchecked state.
+ sal_Int16 mnLineCount; /// Combobox dropdown line count.
+ sal_Int16 mnSelEntry; /// Selected entry in combobox (1-based).
+ sal_uInt16 mnScrollValue; /// Scrollbar: Current value.
+ sal_uInt16 mnScrollMin; /// Scrollbar: Minimum value.
+ sal_uInt16 mnScrollMax; /// Scrollbar: Maximum value.
+ sal_uInt16 mnScrollStep; /// Scrollbar: Single step.
+ sal_uInt16 mnScrollPage; /// Scrollbar: Page step.
+ bool mbFlatButton; /// False = 3D button style; True = Flat button style.
+ bool mbFlatBorder; /// False = 3D border style; True = Flat border style.
+ bool mbMultiSel; /// true = Multi selection in listbox.
+ bool mbScrollHor; /// Scrollbar: true = horizontal.
+};
+
+#endif
+
+// ----------------------------------------------------------------------------
+
+class XclExpChart;
+
+/** A chart object. This is the drawing object wrapper for the chart data. */
+class XclExpChartObj : public XclObj, protected XclExpRoot
+{
+public:
+ explicit XclExpChartObj(
+ XclExpObjectManager& rObjMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+ virtual ~XclExpChartObj();
+
+ /** Writes the OBJ record and the entire chart substream. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpChart > XclExpChartRef;
+ XclExpChartRef mxChart; /// The chart itself (BOF/EOF substream data).
+};
+
+// ============================================================================
+
+/** Represents a NOTE record containing the relevant data of a cell note.
+
+ NOTE records differ significantly in various BIFF versions. This class
+ encapsulates all needed actions for each supported BIFF version.
+ BIFF5/BIFF7: Stores the note text and generates a single or multiple NOTE
+ records on saving.
+ BIFF8: Creates the Escher object containing the drawing information and the
+ note text.
+ */
+class XclExpNote : public XclExpRecord
+{
+public:
+ /** Constructs a NOTE record from the passed note object and/or the text.
+ @descr The additional text will be separated from the note text with
+ an empty line.
+ @param rScPos The Calc cell address of the note.
+ @param pScNote The Calc note object. May be 0 to create a note from rAddText only.
+ @param rAddText Additional text appended to the note text. */
+ explicit XclExpNote(
+ const XclExpRoot& rRoot,
+ const ScAddress& rScPos,
+ const ScPostIt* pScNote,
+ const String& rAddText );
+
+ /** Writes the NOTE record, if the respective Escher object is present. */
+ virtual void Save( XclExpStream& rStrm );
+
+ void WriteXml( sal_Int32 nAuthorId, XclExpXmlStream& rStrm );
+
+ const XclExpString& GetAuthor() const { return maAuthor; }
+private:
+ /** Writes the body of the NOTE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpString maAuthor; /// Name of the author.
+ String maOrigNoteText; /// Original main text of the note.
+ ByteString maNoteText; /// Main text of the note (<=BIFF7).
+ ScAddress maScPos; /// Calc cell address of the note.
+ sal_uInt16 mnObjId; /// Escher object ID (BIFF8).
+ bool mbVisible; /// true = permanently visible.
+};
+
+// ============================================================================
+
+class XclExpComments : public XclExpRecord
+{
+public:
+ typedef XclExpRecordList< XclExpNote >
+ XclExpNoteList;
+
+ XclExpComments( SCTAB nTab, XclExpNoteList& rNotes );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ SCTAB mnTab;
+ XclExpNoteList& mrNotes;
+};
+
+// object manager =============================================================
+
+class XclExpObjectManager : public XclExpRoot
+{
+public:
+ explicit XclExpObjectManager( const XclExpRoot& rRoot );
+ virtual ~XclExpObjectManager();
+
+ /** Creates a new DFF client anchor object. Caller takes ownership! May be
+ overwritten in derived classes. */
+ virtual XclExpDffAnchorBase* CreateDffAnchor() const;
+
+ /** Creates and returns the MSODRAWINGGROUP record containing global DFF
+ data in the DGGCONTAINER. */
+ ScfRef< XclExpRecordBase > CreateDrawingGroup();
+
+ /** Initializes the object manager for a new sheet. */
+ void StartSheet();
+
+ /** Processes a drawing page and returns the record block containing all
+ related records (MSODRAWING, OBJ, TXO, charts, etc.). */
+ ScfRef< XclExpRecordBase > ProcessDrawing( SdrPage* pSdrPage );
+ /** Processes a collection of UNO shapes and returns the record block
+ containing all related records (MSODRAWING, OBJ, TXO, charts, etc.). */
+ ScfRef< XclExpRecordBase > ProcessDrawing( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes );
+
+ /** Finalizes the object manager after conversion of all sheets. */
+ void EndDocument();
+
+ inline XclEscherEx& GetEscherEx() { return *mxEscherEx; }
+ XclExpMsoDrawing* GetMsodrawingPerSheet();
+ bool HasObj() const;
+ sal_uInt16 AddObj( XclObj* pObjRec );
+ XclObj* RemoveLastObj();
+
+protected:
+ explicit XclExpObjectManager( const XclExpObjectManager& rParent );
+
+private:
+ void InitStream( bool bTempFile );
+
+private:
+ ScfRef< ::utl::TempFile > mxTempFile;
+ ScfRef< SvStream > mxDffStrm;
+ ScfRef< XclEscherEx > mxEscherEx;
+ ScfRef< XclExpObjList > mxObjList;
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpEmbeddedObjectManager : public XclExpObjectManager
+{
+public:
+ explicit XclExpEmbeddedObjectManager(
+ const XclExpObjectManager& rParent,
+ const Size& rPageSize,
+ sal_Int32 nScaleX, sal_Int32 nScaleY );
+
+ /** Creates a new DFF client anchor object for embedded objects according
+ to the scaling data passed to the constructor. Caller takes ownership! */
+ virtual XclExpDffAnchorBase* CreateDffAnchor() const;
+
+private:
+ Size maPageSize;
+ sal_Int32 mnScaleX;
+ sal_Int32 mnScaleY;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xeformula.hxx b/sc/source/filter/inc/xeformula.hxx
new file mode 100644
index 000000000000..258070f0791e
--- /dev/null
+++ b/sc/source/filter/inc/xeformula.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEFORMULA_HXX
+#define SC_XEFORMULA_HXX
+
+#include "xlformula.hxx"
+#include "xeroot.hxx"
+
+// External reference log =====================================================
+
+/** Log entry for external references in a formula, used i.e. in change tracking. */
+struct XclExpRefLogEntry
+{
+ const XclExpString* mpUrl; /// URL of the document containing the first sheet.
+ const XclExpString* mpFirstTab; /// Name of the first sheet.
+ const XclExpString* mpLastTab; /// Name of the last sheet.
+ sal_uInt16 mnFirstXclTab; /// Calc index of the first sheet.
+ sal_uInt16 mnLastXclTab; /// Calc index of the last sheet.
+
+ explicit XclExpRefLogEntry();
+};
+
+/** Vector containing a log for all external references in a formula, used i.e. in change tracking. */
+typedef ::std::vector< XclExpRefLogEntry > XclExpRefLog;
+
+// Formula compiler ===========================================================
+
+class ScRangeList;
+class XclExpFmlaCompImpl;
+
+/** The formula compiler to create Excel token arrays from Calc token arrays. */
+class XclExpFormulaCompiler : protected XclExpRoot
+{
+public:
+ explicit XclExpFormulaCompiler( const XclExpRoot& rRoot );
+ virtual ~XclExpFormulaCompiler();
+
+ /** Creates and returns the token array of a formula. */
+ XclTokenArrayRef CreateFormula(
+ XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos = 0, XclExpRefLog* pRefLog = 0 );
+
+ /** Creates and returns a token array containing a single cell address. */
+ XclTokenArrayRef CreateFormula( XclFormulaType eType, const ScAddress& rScPos );
+
+ /** Creates and returns a token array containing a single cell range address. */
+ XclTokenArrayRef CreateFormula( XclFormulaType eType, const ScRange& rScRange );
+
+ /** Creates and returns the token array for a cell range list. */
+ XclTokenArrayRef CreateFormula( XclFormulaType eType, const ScRangeList& rScRanges );
+
+ /** Creates a single error token containing the passed error code. */
+ XclTokenArrayRef CreateErrorFormula( sal_uInt8 nErrCode );
+
+ /** Creates a single token for a special cell reference.
+ @descr This is used for array formulas and shared formulas (token tExp),
+ and multiple operation tables (token tTbl). */
+ XclTokenArrayRef CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos );
+
+ /** Creates a single tNameXR token for a reference to an external name.
+ @descr This is used i.e. for linked macros in push buttons. */
+ XclTokenArrayRef CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName );
+
+private:
+ typedef ScfRef< XclExpFmlaCompImpl > XclExpFmlaCompImplRef;
+ XclExpFmlaCompImplRef mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xehelper.hxx b/sc/source/filter/inc/xehelper.hxx
new file mode 100644
index 000000000000..606ce51c889b
--- /dev/null
+++ b/sc/source/filter/inc/xehelper.hxx
@@ -0,0 +1,451 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEHELPER_HXX
+#define SC_XEHELPER_HXX
+
+#include "xladdress.hxx"
+#include "xeroot.hxx"
+#include "xestring.hxx"
+
+// Export progress bar ========================================================
+
+class ScfProgressBar;
+
+/** The main progress bar for the export filter.
+
+ This class encapsulates creation and initialization of sub progress
+ segments. The Activate***Segment() functions activate a specific segement
+ of the main progress bar. The implementation of these functions contain the
+ calculation of the needed size of the segment. Following calls of the
+ Progress() function increase the currently activated sub segment.
+ */
+class XclExpProgressBar : protected XclExpRoot
+{
+public:
+ explicit XclExpProgressBar( const XclExpRoot& rRoot );
+ virtual ~XclExpProgressBar();
+
+ /** Initializes all segments and sub progress bars. */
+ void Initialize();
+
+ /** Increases the number of existing ROW records by 1. */
+ void IncRowRecordCount();
+
+ /** Activates the progress segment to create ROW records. */
+ void ActivateCreateRowsSegment();
+ /** Activates the progress segment to finalize ROW records. */
+ void ActivateFinalRowsSegment();
+
+ /** Increases the currently activated (sub) progress bar by 1 step. */
+ void Progress();
+
+private:
+ typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;
+
+ ScfProgressBarPtr mxProgress; /// Progress bar implementation.
+ ScfProgressBar* mpSubProgress; /// Current sub progress bar.
+
+ ScfProgressBar* mpSubRowCreate; /// Sub progress bar for creating table rows.
+ ScfInt32Vec maSubSegRowCreate; /// Segment ID's for all sheets in sub progress bar.
+
+ ScfProgressBar* mpSubRowFinal; /// Sub progress bar for finalizing ROW records.
+ sal_Int32 mnSegRowFinal; /// Progress segment for finalizing ROW records.
+
+ sal_Size mnRowCount; /// Number of created ROW records.
+};
+
+// Calc->Excel cell address/range conversion ==================================
+
+/** Provides functions to convert Calc cell addresses to Excel cell addresses. */
+class XclExpAddressConverter : public XclAddressConverterBase
+{
+public:
+ explicit XclExpAddressConverter( const XclExpRoot& rRoot );
+
+ // cell address -----------------------------------------------------------
+
+ /** Checks if the passed Calc cell address is valid.
+ @param rScPos The Calc cell address to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is not valid.
+ @return true = Cell address in rScPos is valid. */
+ bool CheckAddress( const ScAddress& rScPos, bool bWarn );
+
+ /** Converts the passed Calc cell address to an Excel cell address.
+ @param rXclPos (Out) The converted Excel cell address, if valid.
+ @param rScPos The Calc cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is not valid.
+ @return true = Cell address returned in rXclPos is valid. */
+ bool ConvertAddress( XclAddress& rXclPos,
+ const ScAddress& rScPos, bool bWarn );
+
+ /** Returns a valid cell address by moving it into allowed dimensions.
+ @param rScPos The Calc cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is invalid.
+ @return The converted Excel cell address. */
+ XclAddress CreateValidAddress( const ScAddress& rScPos, bool bWarn );
+
+ // cell range -------------------------------------------------------------
+
+ /** Checks if the passed cell range is valid (checks start and end position).
+ @param rScRange The Calc cell range to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range is not valid.
+ @return true = Cell range in rScRange is valid. */
+ bool CheckRange( const ScRange& rScRange, bool bWarn );
+
+ /** Checks and eventually crops the cell range to valid dimensions.
+ @descr The start position of the range will not be modified.
+ @param rScRange (In/out) The cell range to validate.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range contains invalid
+ cells. If the range is partly valid, this function sets the warning
+ flag, corrects the range and returns true.
+ @return true = Cell range in rScRange is valid (original or cropped). */
+ bool ValidateRange( ScRange& rScRange, bool bWarn );
+
+ /** Converts the passed Calc cell range to an Excel cell range.
+ @param rXclRange (Out) The converted Excel cell range, if valid.
+ @param rScRange The Calc cell range to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range contains invalid cells.
+ @return true = Cell range returned in rXclRange is valid (original or cropped). */
+ bool ConvertRange( XclRange& rXclRange, const ScRange& rScRange, bool bWarn );
+
+//UNUSED2008-05 /** Returns a valid cell range by moving it into allowed dimensions.
+//UNUSED2008-05 @descr The start and/or end position of the range may be modified.
+//UNUSED2008-05 @param rScRange The Calc cell range to convert.
+//UNUSED2008-05 @param bWarn true = Sets the internal flag that produces a warning box
+//UNUSED2008-05 after loading/saving the file, if the cell range contains invalid cells.
+//UNUSED2008-05 @return The converted Excel cell range. */
+//UNUSED2008-05 XclRange CreateValidRange( const ScRange& rScRange, bool bWarn );
+
+ // cell range list --------------------------------------------------------
+
+//UNUSED2008-05 /** Checks if the passed cell range list is valid.
+//UNUSED2008-05 @param rScRanges The Calc cell range list to check.
+//UNUSED2008-05 @param bWarn true = Sets the internal flag that produces a warning box
+//UNUSED2008-05 after loading/saving the file, if the cell range list contains at
+//UNUSED2008-05 least one invalid range.
+//UNUSED2008-05 @return true = Cell range list in rScRanges is completly valid. */
+//UNUSED2008-05 bool CheckRangeList( const ScRangeList& rScRanges, bool bWarn );
+
+ /** Checks and eventually crops the cell ranges to valid dimensions.
+ @descr The start position of the ranges will not be modified. Cell
+ ranges that fit partly into valid dimensions are cropped
+ accordingly. Cell ranges that do not fit at all, are removed from
+ the cell range list.
+ @param rScRanges (In/out) The cell range list to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if at least one of the cell ranges
+ contains invalid cells. */
+ void ValidateRangeList( ScRangeList& rScRanges, bool bWarn );
+
+ /** Converts the passed Calc cell range list to an Excel cell range list.
+ @descr The start position of the ranges will not be modified. Cell
+ ranges that fit partly into valid dimensions are cropped
+ accordingly. Cell ranges that do not fit at all, are not inserted
+ into the Excel cell range list.
+ @param rXclRanges (Out) The converted Excel cell range list.
+ @param rScRanges The Calc cell range list to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if at least one of the cell ranges
+ contains invalid cells. */
+ void ConvertRangeList( XclRangeList& rXclRanges,
+ const ScRangeList& rScRanges, bool bWarn );
+};
+
+// EditEngine->String conversion ==============================================
+
+class SvxURLField;
+class XclExpHyperlink;
+
+/** Helper to create HLINK records during creation of formatted cell strings.
+
+ In Excel it is not possible to have more than one hyperlink in a cell. This
+ helper detects multiple occurences of hyperlinks and fills a string which
+ is used to create a cell note containing all URLs. Only cells containing
+ one hyperlink are exported as hyperlink cells.
+ */
+class XclExpHyperlinkHelper : protected XclExpRoot
+{
+public:
+ typedef ScfRef< XclExpHyperlink > XclExpHyperlinkRef;
+
+ explicit XclExpHyperlinkHelper( const XclExpRoot& rRoot, const ScAddress& rScPos );
+ ~XclExpHyperlinkHelper();
+
+ /** Processes the passed URL field (tries to create a HLINK record).
+ @return The representation string of the URL field. */
+ String ProcessUrlField( const SvxURLField& rUrlField );
+
+ /** Returns true, if a single HLINK record has been created. */
+ bool HasLinkRecord() const;
+ /** Returns the craeted single HLINk record, or an empty reference. */
+ XclExpHyperlinkRef GetLinkRecord();
+
+ /** Returns true, if multiple URLs have been processed. */
+ inline bool HasMultipleUrls() const { return mbMultipleUrls; }
+ /** Returns a string containing all processed URLs. */
+ inline const String& GetUrlList() { return maUrlList; }
+
+private:
+ XclExpHyperlinkRef mxLinkRec; /// Created HLINK record.
+ ScAddress maScPos; /// Cell position to set at the HLINK record.
+ String maUrlList; /// List with all processed URLs.
+ bool mbMultipleUrls; /// true = Multiple URL fields processed.
+};
+
+// ----------------------------------------------------------------------------
+
+class EditEngine;
+class SdrTextObj;
+class ScStringCell;
+class ScEditCell;
+class ScPatternAttr;
+
+/** This class provides methods to create an XclExpString.
+ @descr The string can be created from an edit engine text object or
+ directly from a Calc edit cell. */
+class XclExpStringHelper : ScfNoInstance
+{
+public:
+ /** Creates a new unformatted string from the passed string.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param rString The source string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ const String& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new unformatted string from the passed character.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param cChar The source character. The NUL character is explicitly allowed.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ sal_Unicode cChar,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Appends an unformatted string to an Excel string object.
+ @descr Selects the correct Append() function depending on the current
+ BIFF version contained in the passed XclExpRoot object.
+ @param rXclString The Excel string object.
+ @param rString The source string. */
+ static void AppendString(
+ XclExpString& rXclString,
+ const XclExpRoot& rRoot,
+ const String& rString );
+
+ /** Appends a character to an Excel string object.
+ @descr Selects the correct Append() function depending on the current
+ BIFF version contained in the passed XclExpRoot object.
+ @param rXclString The Excel string object.
+ @param rString The source string. */
+ static void AppendChar(
+ XclExpString& rXclString,
+ const XclExpRoot& rRoot,
+ sal_Unicode cChar );
+
+ /** Creates a new formatted string from a Calc string cell.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ May create a formatted string object, if the cell text contains
+ different script types.
+ @param rStringCell The Calc string cell object.
+ @param pCellAttr The set item containing the cell formatting.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateCellString(
+ const XclExpRoot& rRoot,
+ const ScStringCell& rStringCell,
+ const ScPatternAttr* pCellAttr,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new formatted string from a Calc edit cell.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param rEditCell The Calc edit cell object.
+ @param pCellAttr The set item containing the cell formatting.
+ @param rLinkHelper Helper object for hyperlink conversion.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateCellString(
+ const XclExpRoot& rRoot,
+ const ScEditCell& rEditCell,
+ const ScPatternAttr* pCellAttr,
+ XclExpHyperlinkHelper& rLinkHelper,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new formatted string from a drawing text box.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param rTextObj The text box object.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ const SdrTextObj& rTextObj,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new formatted string from a edit text string.
+ @param rEditObj The edittext object.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object. */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ const EditTextObject& rEditObj,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Returns the script type first text portion different to WEAK, or the system
+ default script type, if there is only weak script in the passed string. */
+ static sal_Int16 GetLeadingScriptType( const XclExpRoot& rRoot, const String& rString );
+};
+
+// Header/footer conversion ===================================================
+
+class EditEngine;
+
+/** Converts edit engine text objects to an Excel header/footer string.
+ @descr Header/footer content is divided into three parts: Left, center and
+ right portion. All formatting information will be encoded in the Excel string
+ using special character seuences. A control sequence starts with the ampersand
+ character.
+
+ Supported control sequences:
+ &L start of left portion
+ &C start of center portion
+ &R start of right portion
+ &P current page number
+ &N page count
+ &D current date
+ &T current time
+ &A table name
+ &F file name without path
+ &Z file path without file name
+ &Z&F file path and name
+ &U underlining on/off
+ &E double underlining on/off
+ &S strikeout characters on/off
+ &X superscript on/off
+ &Y subscript on/off
+ &"fontname,fontstyle" use font with name 'fontname' and style 'fontstyle'
+ &fontheight set font height in points ('fontheight' is a decimal value)
+
+ Known but unsupported control sequences:
+ &G picture
+ */
+class XclExpHFConverter : protected XclExpRoot, ScfNoCopy
+{
+public:
+ explicit XclExpHFConverter( const XclExpRoot& rRoot );
+
+ /** Generates the header/footer string from the passed edit engine text objects. */
+ void GenerateString(
+ const EditTextObject* pLeftObj,
+ const EditTextObject* pCenterObj,
+ const EditTextObject* pRightObj );
+
+ /** Returns the last generated header/footer string. */
+ inline const String& GetHFString() const { return maHFString; }
+ /** Returns the total height of the last generated header/footer in twips. */
+ inline sal_Int32 GetTotalHeight() const { return mnTotalHeight; }
+
+private:
+ /** Converts the text object contents and stores it in the passed string. */
+ void AppendPortion(
+ const EditTextObject* pTextObj,
+ sal_Unicode cPortionCode );
+
+private:
+ EditEngine& mrEE; /// The header/footer edit engine.
+ String maHFString; /// The last generated header/footer string.
+ sal_Int32 mnTotalHeight; /// Total height of the last header/footer (twips).
+};
+
+// URL conversion =============================================================
+
+/** This class contains static methods to encode a file URL.
+ @descr Excel stores URLs in a format that contains special control characters,
+ i.e. for directory separators or volume names. */
+class XclExpUrlHelper : ScfNoInstance
+{
+public:
+ /** Encodes and returns the URL passed in rAbsUrl to an Excel like URL.
+ @param pTableName Optional pointer to a table name to be encoded in this URL. */
+ static String EncodeUrl( const XclExpRoot& rRoot, const String& rAbsUrl, const String* pTableName = 0 );
+ /** Encodes and returns the passed DDE link to an Excel like DDE link. */
+ static String EncodeDde( const String& rApplic, const String rTopic );
+};
+
+// ----------------------------------------------------------------------------
+class ScDocument;
+class ScMatrix;
+
+/** Contains cached values in a 2-dimensional array. */
+class XclExpCachedMatrix
+{
+ void GetDimensions( SCSIZE & nCols, SCSIZE & nRows ) const;
+public:
+ /** Constructs and fills a new matrix.
+ @param rMatrix The Calc value matrix. */
+ explicit XclExpCachedMatrix( const ScMatrix& rMatrix );
+ ~XclExpCachedMatrix();
+
+ /** Returns the byte count of all contained data. */
+ sal_Size GetSize() const;
+ /** Writes the complete matrix to stream. */
+ void Save( XclExpStream& rStrm ) const;
+
+private:
+ const ScMatrix& mrMatrix;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xelink.hxx b/sc/source/filter/inc/xelink.hxx
new file mode 100644
index 000000000000..c70e496400a4
--- /dev/null
+++ b/sc/source/filter/inc/xelink.hxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XELINK_HXX
+#define SC_XELINK_HXX
+
+#include "markdata.hxx"
+#include "xllink.hxx"
+#include "xerecord.hxx"
+#include "xehelper.hxx"
+#include "xeformula.hxx"
+#include "externalrefmgr.hxx"
+
+class ScRange;
+struct ScSingleRefData;
+struct ScComplexRefData;
+
+/* ============================================================================
+Classes for export of different kinds of internal/external references.
+- 3D cell and cell range links
+- External cell and cell range links
+- External defined names
+- Macro calls
+- Add-in functions
+- DDE links
+- OLE object links
+============================================================================ */
+
+// Excel sheet indexes ========================================================
+
+/** Stores the correct Excel sheet index for each Calc sheet.
+ @descr The class knows all sheets which will not exported
+ (i.e. external link sheets, scenario sheets). */
+class XclExpTabInfo : protected XclExpRoot
+{
+public:
+ /** Initializes the complete buffer from the current exported document. */
+ explicit XclExpTabInfo( const XclExpRoot& rRoot );
+
+ /** Returns true, if the specified Calc sheet will be exported. */
+ bool IsExportTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is used to store external cell contents. */
+ bool IsExternalTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is visible and will be exported. */
+ bool IsVisibleTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is selected and will be exported. */
+ bool IsSelectedTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is the displayed (active) sheet. */
+ bool IsDisplayedTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is displayed in right-to-left mode. */
+ bool IsMirroredTab( SCTAB nScTab ) const;
+ /** Returns the Calc name of the specified sheet. */
+ const String& GetScTabName( SCTAB nScTab ) const;
+
+ /** Returns the Excel sheet index for a given Calc sheet. */
+ sal_uInt16 GetXclTab( SCTAB nScTab ) const;
+
+ /** Returns the Calc sheet index of the nSortedTab-th entry in the sorted sheet names list. */
+ SCTAB GetRealScTab( SCTAB nSortedScTab ) const;
+//UNUSED2009-05 /** Returns the index of the passed Calc sheet in the sorted sheet names list. */
+//UNUSED2009-05 SCTAB GetSortedScTab( SCTAB nScTab ) const;
+
+ /** Returns the number of Calc sheets. */
+ inline SCTAB GetScTabCount() const { return mnScCnt; }
+
+ /** Returns the number of Excel sheets to be exported. */
+ inline sal_uInt16 GetXclTabCount() const { return mnXclCnt; }
+ /** Returns the number of external linked sheets. */
+ inline sal_uInt16 GetXclExtTabCount() const { return mnXclExtCnt; }
+ /** Returns the number of exported selected sheets. */
+ inline sal_uInt16 GetXclSelectedCount() const { return mnXclSelCnt; }
+
+ /** Returns the Excel index of the active, displayed sheet. */
+ inline sal_uInt16 GetDisplayedXclTab() const { return mnDisplXclTab; }
+ /** Returns the Excel index of the first visible sheet. */
+ inline sal_uInt16 GetFirstVisXclTab() const { return mnFirstVisXclTab; }
+
+private:
+ /** Returns true, if any of the passed flags is set for the specified Calc sheet. */
+ bool GetFlag( SCTAB nScTab, sal_uInt8 nFlags ) const;
+ /** Sets or clears (depending on bSet) all passed flags for the specified Calc sheet. */
+ void SetFlag( SCTAB nScTab, sal_uInt8 nFlags, bool bSet = true );
+
+ /** Searches for sheets not to be exported. */
+ void CalcXclIndexes();
+ /** Sorts the names of all tables and stores the indexes of the sorted indexes. */
+ void CalcSortedIndexes();
+
+private:
+ /** Data structure with infoemation about one Calc sheet. */
+ struct XclExpTabInfoEntry
+ {
+ String maScName;
+ sal_uInt16 mnXclTab;
+ sal_uInt8 mnFlags;
+ inline explicit XclExpTabInfoEntry() : mnXclTab( 0 ), mnFlags( 0 ) {}
+ };
+
+ typedef ::std::vector< XclExpTabInfoEntry > XclExpTabInfoVec;
+ typedef ::std::vector< SCTAB > ScTabVec;
+
+ XclExpTabInfoVec maTabInfoVec; /// Array of Calc sheet index information.
+
+ SCTAB mnScCnt; /// Count of Calc sheets.
+ sal_uInt16 mnXclCnt; /// Count of Excel sheets to be exported.
+ sal_uInt16 mnXclExtCnt; /// Count of external link sheets.
+ sal_uInt16 mnXclSelCnt; /// Count of selected and exported sheets.
+ sal_uInt16 mnDisplXclTab; /// Displayed (active) sheet.
+ sal_uInt16 mnFirstVisXclTab; /// First visible sheet.
+
+ ScTabVec maFromSortedVec; /// Sorted Calc sheet index -> real Calc sheet index.
+ ScTabVec maToSortedVec; /// Real Calc sheet index -> sorted Calc sheet index.
+};
+
+// Export link manager ========================================================
+
+class XclExpLinkManagerImpl;
+
+/** Stores all data for internal/external references (the link table). */
+class XclExpLinkManager : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpLinkManager( const XclExpRoot& rRoot );
+ virtual ~XclExpLinkManager();
+
+ /** Searches for an EXTERNSHEET index for the given Calc sheet.
+ @descr See above for the meaning of EXTERNSHEET indexes.
+ @param rnExtSheet (out-param) Returns the EXTERNSHEET index.
+ @param rnXclTab (out-param) Returns the Excel sheet index.
+ @param nScTab The Calc sheet index to process.
+ param pRefLogEntry If not 0, data about the external link is stored here. */
+ void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnXclTab, SCTAB nScTab,
+ XclExpRefLogEntry* pRefLogEntry = 0 );
+ /** Searches for an EXTERNSHEET index for the given Calc sheet range.
+ @descr See above for the meaning of EXTERNSHEET indexes.
+ @param rnExtSheet (out-param) Returns the EXTERNSHEET index.
+ @param rnFirstXclTab (out-param) Returns the Excel sheet index of the first sheet.
+ @param rnXclTab (out-param) Returns the Excel sheet index of the last sheet.
+ @param nFirstScTab The first Calc sheet index to process.
+ @param nLastScTab The last Calc sheet index to process.
+ param pRefLogEntry If not 0, data about the external link is stored here. */
+ void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry = 0 );
+ /** Searches for a special EXTERNSHEET index for the own document. */
+ sal_uInt16 FindExtSheet( sal_Unicode cCode );
+
+ void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry = NULL );
+
+ /** Stores the cell with the given address in a CRN record list. */
+ void StoreCell( const ScSingleRefData& rRef );
+ /** Stores all cells in the given range in a CRN record list. */
+ void StoreCellRange( const ScComplexRefData& rRef );
+
+ void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+
+ void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
+
+ /** Finds or inserts an EXTERNNAME record for an add-in function name.
+ @param rnExtSheet (out-param) Returns the index of the EXTSHEET structure for the add-in function name.
+ @param rnExtName (out-param) Returns the 1-based EXTERNNAME record index.
+ @return true = add-in function inserted; false = error (i.e. not supported in current BIFF). */
+ bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+ /** InsertEuroTool */
+ bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+ /** Finds or inserts an EXTERNNAME record for DDE links.
+ @param rnExtSheet (out-param) Returns the index of the EXTSHEET structure for the DDE link.
+ @param rnExtName (out-param) Returns the 1-based EXTERNNAME record index.
+ @return true = DDE link inserted; false = error (i.e. not supported in current BIFF). */
+ bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ /** Writes the entire Link table. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpLinkManagerImpl > XclExpLinkMgrImplPtr;
+ XclExpLinkMgrImplPtr mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xename.hxx b/sc/source/filter/inc/xename.hxx
new file mode 100644
index 000000000000..f0740735ea28
--- /dev/null
+++ b/sc/source/filter/inc/xename.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XENAME_HXX
+#define SC_XENAME_HXX
+
+#include "xerecord.hxx"
+#include "xlname.hxx"
+#include "xlformula.hxx"
+#include "xeroot.hxx"
+
+// ============================================================================
+
+class ScRangeList;
+class XclExpNameManagerImpl;
+
+/** Manager that stores all internal defined names (NAME records) of the document. */
+class XclExpNameManager : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpNameManager( const XclExpRoot& rRoot );
+ virtual ~XclExpNameManager();
+
+ /** Creates NAME records for built-in and user defined names. */
+ void Initialize();
+
+ /** Inserts the Calc name with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertName( USHORT nScNameIdx );
+ /** Inserts the Calc database range with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertDBRange( USHORT nScDBRangeIdx );
+
+//UNUSED2009-05 /** Inserts a new built-in defined name. */
+//UNUSED2009-05 sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ /** Inserts a new built-in defined name, referring to the passed sheet range. */
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, const ScRange& rRange );
+ /** Inserts a new built-in defined name, referring to the passed sheet range list. */
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, const ScRangeList& rRangeList );
+
+ /** Inserts a new defined name. Sets another unused name, if rName already exists. */
+ sal_uInt16 InsertUniqueName( const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ /** Returns index of an existing name, or creates a name without definition. */
+ sal_uInt16 InsertRawName( const String& rName );
+ /** Searches or inserts a defined name describing a macro name.
+ @param bVBasic true = Visual Basic macro, false = Sheet macro.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ sal_uInt16 InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden = false );
+
+ /** Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names. */
+ const String& GetOrigName( sal_uInt16 nNameIdx ) const;
+ /** Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names. */
+ SCTAB GetScTab( sal_uInt16 nNameIdx ) const;
+ /** Returns true, if the specified defined name is volatile. */
+ bool IsVolatile( sal_uInt16 nNameIdx ) const;
+
+ /** Writes the entire list of NAME records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpNameManagerImpl > XclExpNameMgrImplRef;
+ XclExpNameMgrImplRef mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xepage.hxx b/sc/source/filter/inc/xepage.hxx
new file mode 100644
index 000000000000..b9454a3cdb3c
--- /dev/null
+++ b/sc/source/filter/inc/xepage.hxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEPAGE_HXX
+#define SC_XEPAGE_HXX
+
+#include "xerecord.hxx"
+#include "xlpage.hxx"
+#include "xeroot.hxx"
+
+// Page settings records ======================================================
+
+// Header/footer --------------------------------------------------------------
+
+/** Represents a HEADER or FOOTER record. */
+class XclExpHeaderFooter : public XclExpRecord
+{
+public:
+ explicit XclExpHeaderFooter( sal_uInt16 nRecId, const String& rHdrString );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the header or footer string. Writes an empty record, if no header/footer present. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ String maHdrString; /// Header or footer contents.
+};
+
+// General page settings ------------------------------------------------------
+
+/** Represents a SETUP record that contains common page settings. */
+class XclExpSetup : public XclExpRecord
+{
+public:
+ explicit XclExpSetup( const XclPageData& rPageData );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the contents of the SETUP record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclPageData& mrData; /// Page settings data of current sheet.
+};
+
+// Manual page breaks ---------------------------------------------------------
+
+/** Stores an array of manual page breaks for columns or rows. */
+class XclExpPageBreaks : public XclExpRecord
+{
+public:
+ explicit XclExpPageBreaks(
+ sal_uInt16 nRecId,
+ const ScfUInt16Vec& rPageBreaks,
+ sal_uInt16 nMaxPos );
+
+ /** Writes the record, if the list is not empty. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the page break list. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const ScfUInt16Vec& mrPageBreaks; /// Page settings data of current sheet.
+ sal_uInt16 mnMaxPos; /// Maximum row/column for BIFF8 page breaks.
+};
+
+// Page settings ==============================================================
+
+/** Contains all page (print) settings records for a single sheet. */
+class XclExpPageSettings : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Creates all records containing the current page settings. */
+ explicit XclExpPageSettings( const XclExpRoot& rRoot );
+
+ /** Returns read-only access to the page data. */
+ inline const XclPageData& GetPageData() const { return maData; }
+
+ /** Writes all page settings records to the stream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ XclPageData maData; /// Page settings data.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all page (print) settings records for a chart object. */
+class XclExpChartPageSettings : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Creates all records containing the current page settings. */
+ explicit XclExpChartPageSettings( const XclExpRoot& rRoot );
+
+ /** Returns read-only access to the page data. */
+ inline const XclPageData& GetPageData() const { return maData; }
+
+ /** Writes all page settings records to the stream. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclPageData maData; /// Page settings data.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xepivot.hxx b/sc/source/filter/inc/xepivot.hxx
new file mode 100644
index 000000000000..0c730952e69e
--- /dev/null
+++ b/sc/source/filter/inc/xepivot.hxx
@@ -0,0 +1,486 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEPIVOT_HXX
+#define SC_XEPIVOT_HXX
+
+#include <map>
+#include "xerecord.hxx"
+#include "xlpivot.hxx"
+#include "xeroot.hxx"
+
+class ScDPObject;
+class ScDPSaveData;
+class ScDPSaveDimension;
+class ScDPSaveMember;
+class ScDPDimensionSaveData;
+class ScDPSaveGroupDimension;
+class ScDPSaveNumGroupDimension;
+struct ScDPNumGroupInfo;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+/** Represents a data item in a pivot cache containing data of any type. */
+class XclExpPCItem : public XclExpRecord, public XclPCItem
+{
+public:
+ explicit XclExpPCItem( const String& rText );
+ explicit XclExpPCItem( double fValue );
+ explicit XclExpPCItem( const DateTime& rDateTime );
+ explicit XclExpPCItem( sal_Int16 nValue );
+ explicit XclExpPCItem( bool bValue );
+
+ inline sal_uInt16 GetTypeFlag() const { return mnTypeFlag; }
+
+ bool EqualsText( const String& rText ) const;
+ bool EqualsDouble( double fValue ) const;
+ bool EqualsDateTime( const DateTime& rDateTime ) const;
+ bool EqualsBool( bool bValue ) const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnTypeFlag; /// Data type flag.
+};
+
+// ============================================================================
+
+class XclExpPivotCache;
+
+class XclExpPCField : public XclExpRecord, public XclPCField, protected XclExpRoot
+{
+public:
+ /** Creates a standard pivot cache field, filled from sheet source data. */
+ explicit XclExpPCField( const XclExpRoot& rRoot,
+ const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScRange& rRange );
+ /** Creates a child grouping pivot cache field, filled from the passed grouping info. */
+ explicit XclExpPCField( const XclExpRoot& rRoot,
+ const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim,
+ const XclExpPCField& rBaseField );
+ virtual ~XclExpPCField();
+
+ /** Sets the passed field as direct grouping child field of this field. */
+ void SetGroupChildField( const XclExpPCField& rChildField );
+ /** Converts this standard field into a numeric grouping field. */
+ void ConvertToNumGroup( const ScDPObject& rDPObj, const ScDPSaveNumGroupDimension& rNumGroupDim );
+
+ /** Returns the name of this cache field. */
+ inline const String& GetFieldName() const { return maFieldInfo.maName; }
+
+ /** Returns the number of visible items of this field. */
+ sal_uInt16 GetItemCount() const;
+ /** Returns the specified pivot cache item (returns visible items in groupings). */
+ const XclExpPCItem* GetItem( sal_uInt16 nItemIdx ) const;
+ /** Returns the index of a pivot cache item, or EXC_PC_NOITEM on error. */
+ sal_uInt16 GetItemIndex( const String& rItemName ) const;
+
+ /** Returns the size an item index needs to write out. */
+ sal_Size GetIndexSize() const;
+ /** Writes the item index at the passed source row position as part of the SXINDEXLIST record. */
+ void WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const;
+
+ /** Writes the pivot cache field and all items and other related records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpPCItem > XclExpPCItemList;
+
+ /** Returns the item list that contains the visible items.
+ @descr Visible items are equal to source items in standard fields,
+ but are generated items in grouping and calculated fields. */
+ const XclExpPCItemList& GetVisItemList() const;
+
+ /** Initializes a standard field. Inserts all original source items. */
+ void InitStandardField( const ScRange& rRange );
+ /** Initializes a standard grouping field. Inserts all visible grouping items. */
+ void InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim );
+ /** Initializes a numeric grouping field. Inserts all visible grouping items and the limit settings. */
+ void InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo );
+ /** Initializes a date grouping field. Inserts all visible grouping items and the limit settings. */
+ void InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart );
+
+ /** Inserts the passed index into the item index array of original items. */
+ void InsertItemArrayIndex( size_t nListPos );
+ /** Inserts an original source item. Updates item index array. */
+ void InsertOrigItem( XclExpPCItem* pNewItem );
+ /** Inserts an original text item, if it is not contained already. */
+ void InsertOrigTextItem( const String& rText );
+ /** Inserts an original value item, if it is not contained already. */
+ void InsertOrigDoubleItem( double fValue );
+ /** Inserts an original date/time item, if it is not contained already. */
+ void InsertOrigDateTimeItem( const DateTime& rDateTime );
+ /** Inserts an original boolean item, if it is not contained already. */
+ void InsertOrigBoolItem( bool bValue );
+
+ /** Inserts an item into the grouping item list. Does not change anything else.
+ @return The list index of the new item. */
+ sal_uInt16 InsertGroupItem( XclExpPCItem* pNewItem );
+ /** Generates and inserts all visible items for numeric or date grouping. */
+ void InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart = 0 );
+
+ /** Inserts the SXDOUBLE items that specify the limits for a numeric grouping. */
+ void SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo );
+ /** Inserts the SXDATETIME/SXINTEGER items that specify the limits for a date grouping.
+ @param bUseStep true = Insert the passed step value; false = always insert 1. */
+ void SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep );
+
+ /** Initializes flags and item count fields. */
+ void Finalize();
+
+ /** Writes an SXNUMGROUP record and the additional items for a numeric grouping field. */
+ void WriteSxnumgroup( XclExpStream& rStrm );
+ /** Writes an SXGROUPINFO record describing the item order in grouping fields. */
+ void WriteSxgroupinfo( XclExpStream& rStrm );
+
+ /** Writes the contents of the SXFIELD record for this field. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpPivotCache& mrPCache; /// Parent pivot cache containing this field.
+ XclExpPCItemList maOrigItemList; /// List with original items.
+ XclExpPCItemList maGroupItemList; /// List with grouping items.
+ ScfUInt16Vec maIndexVec; /// Indexes into maItemList.
+ XclExpPCItemList maNumGroupLimits; /// List with limit values for numeric grouping.
+ sal_uInt16 mnTypeFlags; /// Collected item data type flags.
+};
+
+// ============================================================================
+
+class XclExpPivotCache : protected XclExpRoot
+{
+public:
+ explicit XclExpPivotCache( const XclExpRoot& rRoot,
+ const ScDPObject& rDPObj, sal_uInt16 nListIdx );
+
+ /** Returns true, if the cache has been constructed successfully. */
+ inline bool IsValid() const { return mbValid; }
+ /** Returns true, if the item index list will be written. */
+ bool HasItemIndexList() const;
+
+ /** Returns the stream identifier used to create the cache stream. */
+ inline sal_uInt16 GetStreamId() const { return maPCInfo.mnStrmId; }
+ /** Returns the list index of the cache used in pivot table records. */
+ inline sal_uInt16 GetCacheIndex() const { return mnListIdx; }
+
+ /** Returns the number of pivot cache fields. */
+ sal_uInt16 GetFieldCount() const;
+ /** Returns the specified pivot cache field. */
+ const XclExpPCField* GetField( sal_uInt16 nFieldIdx ) const;
+//UNUSED2009-05 /** Returns a pivot cache field by its name. */
+//UNUSED2009-05 const XclExpPCField* GetField( const String& rFieldName ) const;
+ /** Returns true, if this pivot cache contains non-standard fields (e.g. grouping fields). */
+ bool HasAddFields() const;
+
+ /** Returns true, if the passed DP object has the same data source as this cache. */
+ bool HasEqualDataSource( const ScDPObject& rDPObj ) const;
+
+ /** Writes related records into Workbook stream and creates the pivot cache storage stream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Returns read/write access to a pivot cache field. */
+ XclExpPCField* GetFieldAcc( sal_uInt16 nFieldIdx );
+ /** Returns read/write access to a pivot cache field. */
+ XclExpPCField* GetFieldAcc( const String& rFieldName );
+
+ /** Adds all pivot cache fields. */
+ void AddFields( const ScDPObject& rDPObj );
+
+ /** Adds all standard pivot cache fields based on source data. */
+ void AddStdFields( const ScDPObject& rDPObj );
+ /** Adds all grouping pivot cache fields. */
+ void AddGroupFields( const ScDPObject& rDPObj );
+ /** Adds all calculated pivot cache fields. */
+ void AddCalcFields( const ScDPObject& rDPObj );
+
+ /** Writes the DCONREF record containing the source range. */
+ void WriteDconref( XclExpStream& rStrm ) const;
+
+ /** Creates the pivot cache storage stream and writes the cache. */
+ void WriteCacheStream();
+ /** Writes the SXDB record. */
+ void WriteSxdb( XclExpStream& rStrm ) const;
+ /** Writes the SXDBEX record. */
+ void WriteSxdbex( XclExpStream& rStrm ) const;
+ /** Writes the SXINDEXLIST record list containing the item index table. */
+ void WriteSxindexlistList( XclExpStream& rStrm ) const;
+
+private:
+ typedef XclExpRecordList< XclExpPCField > XclExpPCFieldList;
+ typedef XclExpPCFieldList::RecordRefType XclExpPCFieldRef;
+
+ XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record).
+ XclExpPCFieldList maFieldList; /// List of all pivot cache fields.
+ String maTabName; /// Name of source data sheet.
+ ScRange maOrigSrcRange; /// The original sheet source range.
+ ScRange maExpSrcRange; /// The exported sheet source range.
+ ScRange maDocSrcRange; /// The range used to build the cache fields and items.
+ sal_uInt16 mnListIdx; /// List index in pivot cache buffer.
+ bool mbValid; /// true = The cache is valid for export.
+};
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+class XclExpPivotTable;
+
+/** Data field position specifying the pivot table field index (first) and data info index (second). */
+typedef ::std::pair< sal_uInt16, sal_uInt16 > XclPTDataFieldPos;
+
+// ============================================================================
+
+class XclExpPTItem : public XclExpRecord
+{
+public:
+ explicit XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx );
+ explicit XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx, bool bUseCache );
+
+ /** Returns the internal name of this item. */
+ const String& GetItemName() const;
+
+ /** Fills this item with properties from the passed save member. */
+ void SetPropertiesFromMember( const ScDPSaveMember& rSaveMem );
+
+private:
+ /** Writes the SXVI record body describing the pivot table item. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpPCItem* mpCacheItem; /// The referred pivot cache item.
+ XclPTItemInfo maItemInfo; /// General data for this item.
+};
+
+// ============================================================================
+
+class XclExpPTField : public XclExpRecordBase
+{
+public:
+ explicit XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx );
+
+ // data access ------------------------------------------------------------
+
+ /** Returns the name of this field. */
+ const String& GetFieldName() const;
+ /** Returns the pivot table field list index of this field. */
+ sal_uInt16 GetFieldIndex() const;
+
+ /** Returns the index of the last inserted data info struct. */
+ sal_uInt16 GetLastDataInfoIndex() const;
+
+//UNUSED2009-05 /** Returns an item by its name. */
+//UNUSED2009-05 const XclExpPTItem* GetItem( const String& rName ) const;
+ /** Returns the list index of an item by its name.
+ @param nDefaultIdx This value will be returned, if the item could not be found. */
+ sal_uInt16 GetItemIndex( const String& rName, sal_uInt16 nDefaultIdx ) const;
+
+ // fill data --------------------------------------------------------------
+
+ /** Fills this field with row/column/page properties from the passed save dimension. */
+ void SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+ /** Fills this field with data field properties from the passed save dimension. */
+ void SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+
+ /** Appends special items describing the field subtotal entries. */
+ void AppendSubtotalItems();
+
+ // records ----------------------------------------------------------------
+
+ /** Writes an entry for an SXPI record containing own page field info. */
+ void WriteSxpiEntry( XclExpStream& rStrm ) const;
+ /** Writes an SXDI records containing info about a data field. */
+ void WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const;
+
+ /** Writes the entire pivot table field. */
+ virtual void Save( XclExpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns an item by its name. */
+ XclExpPTItem* GetItemAcc( const String& rName );
+
+ /** Appends a special item describing a field subtotal entry. */
+ void AppendSubtotalItem( sal_uInt16 nItemType );
+
+ /** Writes the SXVD record introducing the field. */
+ void WriteSxvd( XclExpStream& rStrm ) const;
+ /** Writes the SXVDEX record containing additional settings. */
+ void WriteSxvdex( XclExpStream& rStrm ) const;
+
+private:
+ typedef ::std::vector< XclPTDataFieldInfo > XclPTDataFieldInfoVec;
+ typedef XclExpRecordList< XclExpPTItem > XclExpPTItemList;
+
+ const XclExpPivotTable& mrPTable; /// Parent pivot table containing this field.
+ const XclExpPCField* mpCacheField; /// The referred pivot cache field.
+ XclPTFieldInfo maFieldInfo; /// General field info (SXVD record).
+ XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record).
+ XclPTPageFieldInfo maPageInfo; /// Page field info (entry in SXPI record).
+ XclPTDataFieldInfoVec maDataInfoVec; /// List of extended data field info (SXDI records).
+ XclExpPTItemList maItemList; /// List of all items of this field.
+};
+
+// ============================================================================
+
+class XclExpPivotTable : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpPivotTable( const XclExpRoot& rRoot,
+ const ScDPObject& rDPObj, const XclExpPivotCache& rPCache );
+
+ /** Returns a pivot cache field. */
+ const XclExpPCField* GetCacheField( sal_uInt16 nCacheIdx ) const;
+
+ /** Returns the output range of the pivot table. */
+ inline SCTAB GetScTab() const { return mnOutScTab; }
+
+ /** Returns a pivot table field by its name. */
+ const XclExpPTField* GetField( sal_uInt16 nFieldIdx ) const;
+ /** Returns a pivot table field by its name. */
+ const XclExpPTField* GetField( const String& rName ) const;
+
+ /** Returns the data-field-only index of the first data field with the passed name.
+ @param nDefaultIdx This value will be returned, if the field could not be found. */
+ sal_uInt16 GetDataFieldIndex( const String& rName, sal_uInt16 nDefaultIdx ) const;
+
+ /** Writes the entire pivot table. */
+ virtual void Save( XclExpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns a pivot table field by its name. */
+ XclExpPTField* GetFieldAcc( const String& rName );
+ /** Returns a pivot table field corresponding to the passed save dimension. */
+ XclExpPTField* GetFieldAcc( const ScDPSaveDimension& rSaveDim );
+
+ // fill data --------------------------------------------------------------
+
+ /** Fills internal members with all properties from the passed save data. */
+ void SetPropertiesFromDP( const ScDPSaveData& rSaveData );
+ /** Fills a pivot table field with all properties from the passed save dimension. */
+ void SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+ /** Fills a pivot table data field with all properties from the passed save dimension. */
+ void SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+
+ /** Initializes any data after processing the entire source DataPilot. */
+ void Finalize();
+
+ // records ----------------------------------------------------------------
+
+ /** Writes the SXVIEW record starting the pivot table. */
+ void WriteSxview( XclExpStream& rStrm ) const;
+ /** Writes an SXIVD record for row field or column field order. */
+ void WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ) const;
+ /** Writes the SXPI record containing page field info. */
+ void WriteSxpi( XclExpStream& rStrm ) const;
+ /** Writes all SXDI records containing info about the data fields. */
+ void WriteSxdiList( XclExpStream& rStrm ) const;
+ /** Writes a dummy SXLI records containing item layout info. */
+ void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const;
+ /** Writes the SXEX records containing additional pivot table info. */
+ void WriteSxex( XclExpStream& rStrm ) const;
+
+ void WriteQsiSxTag( XclExpStream& rStrm ) const;
+ /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */
+ void WriteSxViewEx9( XclExpStream& rStrm ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList;
+ typedef XclExpPTFieldList::RecordRefType XclExpPTFieldRef;
+ typedef ::std::vector< XclPTDataFieldPos > XclPTDataFieldPosVec;
+
+ const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on.
+ XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record).
+ XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
+ XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9)
+ XclExpPTFieldList maFieldList; /// All fields in pivot cache order.
+ ScfUInt16Vec maRowFields; /// Row field indexes.
+ ScfUInt16Vec maColFields; /// Column field indexes.
+ ScfUInt16Vec maPageFields; /// Page field indexes.
+ XclPTDataFieldPosVec maDataFields; /// Data field indexes.
+ XclExpPTField maDataOrientField; /// Special data field orientation field.
+ SCTAB mnOutScTab; /// Sheet index of the output range.
+ bool mbValid; /// true = The pivot table is valid for export.
+ bool mbFilterBtn; /// true = DataPilot has filter button.
+};
+
+// ============================================================================
+
+/** The main class for pivot table export.
+
+ This class contains all pivot caches and pivot tables in a Calc document.
+ It creates the pivot cache streams and pivot table records in the main
+ workbook stream. It supports sharing of pivot caches between multiple pivot
+ tables to decrease file size.
+ */
+class XclExpPivotTableManager : protected XclExpRoot
+{
+public:
+ explicit XclExpPivotTableManager( const XclExpRoot& rRoot );
+
+ /** Creates all pivot tables and caches from the Calc DataPilot objects. */
+ void CreatePivotTables();
+
+ /** Creates a record wrapper for exporting all pivot caches. */
+ XclExpRecordRef CreatePivotCachesRecord();
+ /** Creates a record wrapper for exporting all pivot tables of the specified sheet. */
+ XclExpRecordRef CreatePivotTablesRecord( SCTAB nScTab );
+
+ /** Writes all pivot caches (all Workbook records and cache streams). */
+ void WritePivotCaches( XclExpStream& rStrm );
+ void WritePivotCachesXml( XclExpXmlStream& rStrm );
+ /** Writes all pivot tables of the specified Calc sheet. */
+ void WritePivotTables( XclExpStream& rStrm, SCTAB nScTab );
+ void WritePivotTablesXml( XclExpXmlStream& rStrm, SCTAB nScTab );
+
+private:
+ /** Finds an existing (if enabled in mbShareCaches) or creates a new pivot cache.
+ @return Pointer to the pivot cache or 0, if the passed source range was invalid. */
+ const XclExpPivotCache* CreatePivotCache( const ScDPObject& rDPObj );
+
+private:
+ typedef XclExpRecordList< XclExpPivotCache > XclExpPivotCacheList;
+ typedef XclExpPivotCacheList::RecordRefType XclExpPivotCacheRef;
+ typedef XclExpRecordList< XclExpPivotTable > XclExpPivotTableList;
+ typedef XclExpPivotTableList::RecordRefType XclExpPivotTableRef;
+
+ XclExpPivotCacheList maPCacheList; /// List of all pivot caches.
+ XclExpPivotTableList maPTableList; /// List of all pivot tables.
+ bool mbShareCaches; /// true = Tries to share caches between tables.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xerecord.hxx b/sc/source/filter/inc/xerecord.hxx
new file mode 100644
index 000000000000..a191cd9b1c20
--- /dev/null
+++ b/sc/source/filter/inc/xerecord.hxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XERECORD_HXX
+#define SC_XERECORD_HXX
+
+#include "xlconst.hxx"
+#include "xestream.hxx"
+
+// Base classes to export Excel records =======================================
+
+/** Base class for all Excel records.
+
+ Derive from this class to implement any functionality performed during
+ saving the records - except really writing a record (i.e. write a list of
+ records contained in the class). Derive from XclExpRecord (instead from
+ this class) to write common records.
+ */
+class XclExpRecordBase
+{
+public:
+ virtual ~XclExpRecordBase();
+
+ /** Overwrite this method to do any operation while saving the record. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpDelegatingRecord : public XclExpRecordBase
+{
+public:
+ XclExpDelegatingRecord( XclExpRecordBase* pRecord );
+ ~XclExpDelegatingRecord();
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ XclExpRecordBase* mpRecord;
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlElementRecord : public XclExpRecordBase
+{
+public:
+ XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ virtual ~XclExpXmlElementRecord();
+
+protected:
+ sal_Int32 mnElement;
+ void (*mpAttributes)( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlStartElementRecord : public XclExpXmlElementRecord
+{
+public:
+ XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ virtual ~XclExpXmlStartElementRecord();
+
+ /** Starts the element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlEndElementRecord : public XclExpXmlElementRecord
+{
+public:
+ XclExpXmlEndElementRecord( sal_Int32 nElement );
+ virtual ~XclExpXmlEndElementRecord();
+
+ /** Ends the element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlStartSingleElementRecord : public XclExpXmlElementRecord
+{
+public:
+ XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ virtual ~XclExpXmlStartSingleElementRecord();
+
+ /** Starts the single element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlEndSingleElementRecord : public XclExpRecordBase
+{
+public:
+ XclExpXmlEndSingleElementRecord();
+ virtual ~XclExpXmlEndSingleElementRecord();
+
+ /** Ends the single element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for single records with any content.
+
+ This class handles writing the record header. Derived classes only have to
+ write the record body. Calculating the record size before saving optimizes
+ the write process (the stream does not have to seek back and update the
+ written record size). But it is not required to calculate a valid size
+ (maybe it would be too complex or just impossible until the record is
+ really written).
+ */
+class XclExpRecord : public XclExpRecordBase
+{
+public:
+ /** @param nRecId The record ID of this record. May be set later with SetRecId().
+ @param nRecSize The predicted record size. May be set later with SetRecSize(). */
+ explicit XclExpRecord(
+ sal_uInt16 nRecId = EXC_ID_UNKNOWN,
+ sal_Size nRecSize = 0 );
+
+ virtual ~XclExpRecord();
+
+ /** Returns the current record ID. */
+ inline sal_uInt16 GetRecId() const { return mnRecId; }
+ /** Returns the current record size prediction. */
+ inline sal_Size GetRecSize() const { return mnRecSize; }
+
+ /** Sets a new record ID. */
+ inline void SetRecId( sal_uInt16 nRecId ) { mnRecId = nRecId; }
+ /** Sets a new record size prediction. */
+ inline void SetRecSize( sal_Size nRecSize ) { mnRecSize = nRecSize; }
+ /** Adds a size value to the record size prediction. */
+ inline void AddRecSize( sal_Size nRecSize ) { mnRecSize += nRecSize; }
+ /** Sets record ID and size with one call. */
+ void SetRecHeader( sal_uInt16 nRecId, sal_Size nRecSize );
+
+ /** Writes the record header and calls WriteBody(). */
+ virtual void Save( XclExpStream& rStrm );
+
+protected:
+ /** Writes the body of the record (without record header).
+ @descr Usually this method will be overwritten by derived classes. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_Size mnRecSize; /// The predicted record size.
+ sal_uInt16 mnRecId; /// The record ID.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A record without body. Only the record ID and the size 0 will be written. */
+class XclExpEmptyRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record. */
+ inline explicit XclExpEmptyRecord( sal_uInt16 nRecId );
+};
+
+inline XclExpEmptyRecord::XclExpEmptyRecord( sal_uInt16 nRecId ) :
+ XclExpRecord( nRecId, 0 )
+{
+}
+
+// ============================================================================
+
+/** A record with a single value of type Type.
+ @descr Requires operator<<( XclExpStream&, const Type& ). */
+template< typename Type >
+class XclExpValueRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record.
+ @param rValue The value for the record body.
+ @param nSize Record size. Uses sizeof( Type ), if this parameter is omitted. */
+ inline explicit XclExpValueRecord( sal_uInt16 nRecId, const Type& rValue, sal_Size nSize = sizeof( Type ) ) :
+ XclExpRecord( nRecId, nSize ), maValue( rValue ), mnAttribute( -1 ) {}
+
+ /** Returns the value of the record. */
+ inline const Type& GetValue() const { return maValue; }
+ /** Sets a new record value. */
+ inline void SetValue( const Type& rValue ) { maValue = rValue; }
+
+ /** Sets the OOXML attribute this record corresponds to */
+ XclExpValueRecord* SetAttribute( sal_Int32 nId );
+
+ /** Write the OOXML attribute and its value */
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the record. */
+ inline virtual void WriteBody( XclExpStream& rStrm ) { rStrm << maValue; }
+ // inlining prevents warning in wntmsci10
+
+private:
+ Type maValue; /// The record data.
+ sal_Int32 mnAttribute; /// The OOXML attribute Id
+};
+
+template< typename Type >
+void XclExpValueRecord< Type >::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnAttribute == -1 )
+ return;
+ rStrm.WriteAttributes(
+ mnAttribute, rtl::OString::valueOf( (sal_Int32) maValue ).getStr(),
+ FSEND );
+}
+
+template<>
+void XclExpValueRecord<double>::SaveXml( XclExpXmlStream& rStrm );
+
+template< typename Type >
+XclExpValueRecord< Type >* XclExpValueRecord< Type >::SetAttribute( sal_Int32 nId )
+{
+ mnAttribute = nId;
+ return this;
+}
+
+// ----------------------------------------------------------------------------
+
+/** A record containing an unsigned 16-bit value. */
+typedef XclExpValueRecord< sal_uInt16 > XclExpUInt16Record;
+
+/** A record containing an unsigned 32-bit value. */
+typedef XclExpValueRecord< sal_uInt32 > XclExpUInt32Record;
+
+/** A record containing a double value. */
+typedef XclExpValueRecord< double > XclExpDoubleRecord;
+
+// ----------------------------------------------------------------------------
+
+/** Record which contains a Boolean value.
+ @descr The value is stored as 16-bit value: 0x0000 = FALSE, 0x0001 = TRUE. */
+class XclExpBoolRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record.
+ @param nValue The value for the record body. */
+ inline explicit XclExpBoolRecord( sal_uInt16 nRecId, bool bValue, sal_Int32 nAttribute = -1 ) :
+ XclExpRecord( nRecId, 2 ), mbValue( bValue ), mnAttribute( nAttribute ) {}
+
+ /** Returns the Boolean value of the record. */
+ inline bool GetBool() const { return mbValue; }
+ /** Sets a new Boolean record value. */
+ inline void SetBool( bool bValue ) { mbValue = bValue; }
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ bool mbValue; /// The record data.
+ sal_Int32 mnAttribute; /// The attribute to generate within SaveXml()
+};
+
+// ----------------------------------------------------------------------------
+
+/** Record which exports a memory data array. */
+class XclExpDummyRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record.
+ @param pRecData Pointer to the data array representing the record body.
+ @param nRecSize Size of the data array. */
+ explicit XclExpDummyRecord(
+ sal_uInt16 nRecId, const void* pRecData, sal_Size nRecSize );
+
+ /** Sets a data array. */
+ void SetData( const void* pRecData, sal_Size nRecSize );
+
+private:
+ /** Writes the body of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const void* mpData; /// The record data.
+};
+
+// Future records =============================================================
+
+class XclExpFutureRecord : public XclExpRecord
+{
+public:
+ explicit XclExpFutureRecord( XclFutureRecType eRecType,
+ sal_uInt16 nRecId, sal_Size nRecSize = 0 );
+
+ /** Writes the extended record header and calls WriteBody(). */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclFutureRecType meRecType;
+};
+
+// List of records ============================================================
+
+/** A list of Excel record objects.
+
+ Provides saving the compete list. This class is derived from
+ XclExpRecordBase, so it can be used as record in another record list.
+ Requires RecType::Save( XclExpStream& ).
+ */
+template< typename RecType = XclExpRecordBase >
+class XclExpRecordList : public XclExpRecordBase
+{
+public:
+ typedef ScfRef< RecType > RecordRefType;
+
+ /** Returns pointer to an existing record or 0 on error. */
+ inline bool IsEmpty() const { return maRecs.empty(); }
+ /** Returns pointer to an existing record or 0 on error. */
+ inline size_t GetSize() const { return maRecs.size(); }
+
+ /** Returns true, if the passed index points to an exiting record. */
+ inline bool HasRecord( size_t nPos ) const
+ { return nPos < maRecs.size(); }
+ /** Returns reference to an existing record or empty reference on error. */
+ inline RecordRefType GetRecord( size_t nPos ) const
+ { return (nPos < maRecs.size()) ? maRecs[ nPos ] : RecordRefType(); }
+ /** Returns reference to the first existing record or empty reference, if list is empty. */
+ inline RecordRefType GetFirstRecord() const
+ { return maRecs.empty() ? RecordRefType() : maRecs.front(); }
+ /** Returns reference to the last existing record or empty reference, if list is empty. */
+ inline RecordRefType GetLastRecord() const
+ { return maRecs.empty() ? RecordRefType() : maRecs.back(); }
+
+ /** Inserts a record at the specified position into the list. */
+ inline void InsertRecord( RecordRefType xRec, size_t nPos )
+ { if( xRec.get() ) maRecs.insert( maRecs.begin() + ::std::min( nPos, maRecs.size() ), xRec ); }
+ /** Appends a record to the list. */
+ inline void AppendRecord( RecordRefType xRec )
+ { if( xRec.get() ) maRecs.push_back( xRec ); }
+ /** Replaces the record at the specified position from the list with the passed record. */
+ inline void ReplaceRecord( RecordRefType xRec, size_t nPos )
+ { RemoveRecord( nPos ); InsertRecord( xRec, nPos ); }
+
+ /** Inserts a newly created record at the specified position into the list. */
+ inline void InsertNewRecord( RecType* pRec, size_t nPos )
+ { if( pRec ) InsertRecord( RecordRefType( pRec ), nPos ); }
+ /** Appends a newly created record to the list. */
+ inline void AppendNewRecord( RecType* pRec )
+ { if( pRec ) AppendRecord( RecordRefType( pRec ) ); }
+ /** Replaces the record at the specified position from the list with the passed newly created record. */
+ inline void ReplaceNewRecord( RecType* pRec, size_t nPos )
+ { RemoveRecord( nPos ); InsertNewRecord( pRec, nPos ); }
+
+ /** Removes the record at the specified position from the list. */
+ inline void RemoveRecord( size_t nPos )
+ { if( nPos < maRecs.size() ) maRecs.erase( maRecs.begin() + nPos ); }
+ /** Removes all records from the list. */
+ inline void RemoveAllRecords() { maRecs.clear(); }
+
+ /** Writes the complete record list. */
+ inline virtual void Save( XclExpStream& rStrm )
+ {
+ // inlining prevents warning in wntmsci10
+ for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
+ (*aIt)->Save( rStrm );
+ }
+
+ inline virtual void SaveXml( XclExpXmlStream& rStrm )
+ {
+ // inlining prevents warning in wntmsci10
+ for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
+ (*aIt)->SaveXml( rStrm );
+ }
+
+private:
+ typedef ::std::vector< RecordRefType > RecordVec;
+ RecordVec maRecs;
+};
+
+// ============================================================================
+
+/** Represents a complete substream of records enclosed into a pair of BOF/EOF records. */
+class XclExpSubStream : public XclExpRecordList<>
+{
+public:
+ explicit XclExpSubStream( sal_uInt16 nSubStrmType );
+
+ /** Writes the complete substream, including leading BOF and trailing EOF. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnSubStrmType; /// Substream type, stored in leading BOF record.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx
new file mode 100644
index 000000000000..980590f9d4ff
--- /dev/null
+++ b/sc/source/filter/inc/xeroot.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEROOT_HXX
+#define SC_XEROOT_HXX
+
+#include "xlroot.hxx"
+
+// Forward declarations of objects in public use ==============================
+
+class XclExpStream;
+class XclExpRecordBase;
+class XclExpString;
+
+typedef ScfRef< XclExpRecordBase > XclExpRecordRef;
+typedef ScfRef< XclExpString > XclExpStringRef;
+
+// Global data ================================================================
+
+class XclExpTabInfo;
+class XclExpAddressConverter;
+class XclExpFormulaCompiler;
+class XclExpProgressBar;
+class XclExpSst;
+class XclExpPalette;
+class XclExpFontBuffer;
+class XclExpNumFmtBuffer;
+class XclExpXFBuffer;
+class XclExpLinkManager;
+class XclExpNameManager;
+class XclExpObjectManager;
+class XclExpFilterManager;
+class XclExpPivotTableManager;
+
+/** Stores global buffers and data needed for Excel export filter. */
+struct XclExpRootData : public XclRootData
+{
+ typedef ScfRef< XclExpTabInfo > XclExpTabInfoRef;
+ typedef ScfRef< XclExpAddressConverter > XclExpAddrConvRef;
+ typedef ScfRef< XclExpFormulaCompiler > XclExpFmlaCompRef;
+ typedef ScfRef< XclExpProgressBar > XclExpProgressRef;
+
+ typedef ScfRef< XclExpSst > XclExpSstRef;
+ typedef ScfRef< XclExpPalette > XclExpPaletteRef;
+ typedef ScfRef< XclExpFontBuffer > XclExpFontBfrRef;
+ typedef ScfRef< XclExpNumFmtBuffer > XclExpNumFmtBfrRef;
+ typedef ScfRef< XclExpXFBuffer > XclExpXFBfrRef;
+ typedef ScfRef< XclExpNameManager > XclExpNameMgrRef;
+ typedef ScfRef< XclExpLinkManager > XclExpLinkMgrRef;
+ typedef ScfRef< XclExpObjectManager > XclExpObjectMgrRef;
+ typedef ScfRef< XclExpFilterManager > XclExpFilterMgrRef;
+ typedef ScfRef< XclExpPivotTableManager > XclExpPTableMgrRef;
+
+ XclExpTabInfoRef mxTabInfo; /// Calc->Excel sheet index conversion.
+ XclExpAddrConvRef mxAddrConv; /// The address converter.
+ XclExpFmlaCompRef mxFmlaComp; /// The formula compiler.
+ XclExpProgressRef mxProgress; /// The export progress bar.
+
+ XclExpSstRef mxSst; /// The shared string table.
+ XclExpPaletteRef mxPalette; /// The color buffer.
+ XclExpFontBfrRef mxFontBfr; /// All fonts in the file.
+ XclExpNumFmtBfrRef mxNumFmtBfr; /// All number formats in the file.
+ XclExpXFBfrRef mxXFBfr; /// All XF records in the file.
+ XclExpNameMgrRef mxNameMgr; /// Internal defined names.
+ XclExpLinkMgrRef mxGlobLinkMgr; /// Global link manager for defined names.
+ XclExpLinkMgrRef mxLocLinkMgr; /// Local link manager for a sheet.
+ XclExpObjectMgrRef mxObjMgr; /// All drawing objects.
+ XclExpFilterMgrRef mxFilterMgr; /// Manager for filtered areas in all sheets.
+ XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches.
+
+ bool mbRelUrl; /// true = Store URLs relative.
+
+ explicit XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc );
+ virtual ~XclExpRootData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Access to global data from other classes. */
+class XclExpRoot : public XclRoot
+{
+public:
+ explicit XclExpRoot( XclExpRootData& rExpRootData );
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclExpRoot& GetRoot() const { return *this; }
+ /** Returns true, if URLs should be stored relative to the document location. */
+ inline bool IsRelUrl() const { return mrExpData.mbRelUrl; }
+
+ /** Returns the buffer for Calc->Excel sheet index conversion. */
+ XclExpTabInfo& GetTabInfo() const;
+ /** Returns the address converter. */
+ XclExpAddressConverter& GetAddressConverter() const;
+ /** Returns the formula compiler to produce formula token arrays. */
+ XclExpFormulaCompiler& GetFormulaCompiler() const;
+ /** Returns the export progress bar. */
+ XclExpProgressBar& GetProgressBar() const;
+
+ /** Returns the shared string table. */
+ XclExpSst& GetSst() const;
+ /** Returns the color buffer. */
+ XclExpPalette& GetPalette() const;
+ /** Returns the font buffer. */
+ XclExpFontBuffer& GetFontBuffer() const;
+ /** Returns the number format buffer. */
+ XclExpNumFmtBuffer& GetNumFmtBuffer() const;
+ /** Returns the cell formatting attributes buffer. */
+ XclExpXFBuffer& GetXFBuffer() const;
+ /** Returns the global link manager for defined names. */
+ XclExpLinkManager& GetGlobalLinkManager() const;
+ /** Returns the local link manager for the current sheet. */
+ XclExpLinkManager& GetLocalLinkManager() const;
+ /** Returns the buffer that contains internal defined names. */
+ XclExpNameManager& GetNameManager() const;
+ /** Returns the drawing object manager. */
+ XclExpObjectManager& GetObjectManager() const;
+ /** Returns the filter manager. */
+ XclExpFilterManager& GetFilterManager() const;
+ /** Returns the pivot table manager. */
+ XclExpPivotTableManager& GetPivotTableManager() const;
+
+ /** Is called when export filter starts to create the Excel document (all BIFF versions). */
+ void InitializeConvert();
+ /** Is called when export filter starts to create the workbook global data (>=BIFF5). */
+ void InitializeGlobals();
+ /** Is called when export filter starts to create data for a single sheet (all BIFF versions). */
+ void InitializeTable( SCTAB nScTab );
+ /** Is called before export filter starts to write the records to the stream. */
+ void InitializeSave();
+ /** Returns the reference to a record (or record list) representing a root object.
+ @param nRecId Identifier that specifies which record is returned. */
+ XclExpRecordRef CreateRecord( sal_uInt16 nRecId ) const;
+
+ bool IsDocumentEncrypted() const;
+
+ String GetPassword() const;
+
+private:
+
+ /** Returns the local or global link manager, depending on current context. */
+ XclExpRootData::XclExpLinkMgrRef GetLocalLinkMgrRef() const;
+
+private:
+ mutable XclExpRootData& mrExpData; /// Reference to the global export data struct.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
new file mode 100644
index 000000000000..3308827441dd
--- /dev/null
+++ b/sc/source/filter/inc/xestream.hxx
@@ -0,0 +1,355 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef SC_XESTREAM_HXX
+#define SC_XESTREAM_HXX
+
+#include <map>
+#include <stack>
+#include <string>
+
+#include <oox/core/xmlfilterbase.hxx>
+#include <sax/fshelper.hxx>
+
+#include "xlstream.hxx"
+#include "xestring.hxx"
+
+#include <filter/msfilter/mscodec.hxx>
+#include <vector>
+
+/* ============================================================================
+Output stream class for Excel export
+- CONTINUE record handling
+- ByteString and UniString support
+============================================================================ */
+
+class XclExpRoot;
+class XclExpBiff8Encrypter;
+typedef 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
+ record contents (in BIFF5: 2080 bytes, in BIFF8: 8224 bytes).
+
+ To start writing a record call StartRecord(). Parameters are the record identifier
+ and any calculated record size. This is for optimizing the write process: if the real
+ written data has the same size as the calculated, the stream will not seek back and
+ update the record size field. But it is not mandatory to calculate a size. Each
+ record must be closed by calling EndRecord(). This will check (and update) the record
+ size field.
+
+ If some data exceeds the record size limit, a CONTINUE record is started automatically
+ and the new data will be written to this record.
+
+ If specific data pieces must not be splitted, use SetSliceLen(). For instance:
+ To write a sequence of 16-bit values, where 4 values form a unit and cannot be
+ split, call SetSliceLen( 8 ) first (4*2 bytes == 8).
+
+ To write unicode character arrays, call WriteUnicodeBuffer(). It creates CONTINUE
+ records and repeats the unicode string flag byte automatically. This function is used
+ for instance from the class XclExpString which can write complete unicode strings.
+*/
+class XclExpStream
+{
+public:
+ /** Constructs the Excel record export stream.
+ @param rOutStrm The system output stream to write to.
+ @param nMaxRecSize The maximum allowed size of record content (depending on BIFF type).
+ If 0 is passed, the record size will be set automatically, depending on the current BIFF type. */
+ XclExpStream(
+ SvStream& rOutStrm,
+ const XclExpRoot& rRoot,
+ sal_uInt16 nMaxRecSize = 0 );
+
+ ~XclExpStream();
+
+ /** Returns the filter root data. */
+ inline const XclExpRoot& GetRoot() const { return mrRoot; }
+
+ /** Starts a new record: writes header data, stores calculated record size. */
+ void StartRecord( sal_uInt16 nRecId, sal_Size nRecSize );
+ /** Checks and corrects real record length. Must be called everytime a record is finished. */
+ void EndRecord();
+
+ /** Returns the position inside of current record (starts by 0 in every CONTINUE). */
+ inline sal_uInt16 GetRawRecPos() const { return mnCurrSize; }
+
+ /** Returns the maximum size of a record. */
+ inline sal_uInt16 GetMaxRecSize() const { return mnMaxRecSize; }
+ /** Sets maximum record size (valid only for current record). */
+ inline void SetMaxRecSize( sal_uInt16 nMax ) { mnCurrMaxSize = nMax; }
+ /** Sets maximum size of CONTINUE records (valid only for current record). */
+ inline void SetMaxContSize( sal_uInt16 nMax ) { mnMaxContSize = nMax; }
+
+ /** Sets data slice length. 0 = no slices. */
+ void SetSliceSize( sal_uInt16 nSize );
+
+ XclExpStream& operator<<( sal_Int8 nValue );
+ XclExpStream& operator<<( sal_uInt8 nValue );
+ XclExpStream& operator<<( sal_Int16 nValue );
+ XclExpStream& operator<<( sal_uInt16 nValue );
+ XclExpStream& operator<<( sal_Int32 nValue );
+ XclExpStream& operator<<( sal_uInt32 nValue );
+ XclExpStream& operator<<( float fValue );
+ XclExpStream& operator<<( double fValue );
+
+ /** Writes nBytes bytes from memory. */
+ sal_Size Write( const void* pData, sal_Size nBytes );
+ /** Writes a sequence of nBytes zero bytes (respects slice setting). */
+ void WriteZeroBytes( sal_Size nBytes );
+
+ void WriteZeroBytesToRecord( sal_Size nBytes );
+
+ /** Copies nBytes bytes from current position of the stream rInStrm.
+ @descr Omitting the second parameter means: read to end of stream. */
+ sal_Size CopyFromStream( SvStream& rInStrm, sal_Size nBytes = STREAM_SEEK_TO_END );
+
+ // *** unicode string export is realized with helper class XclExpString ***
+ // (slice length setting has no effect here -> disabled automatically)
+
+//UNUSED2008-05 /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
+//UNUSED2008-05 void WriteUnicodeBuffer( const sal_uInt16* pBuffer, sal_Size nChars, sal_uInt8 nFlags );
+
+ /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
+ void WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags );
+
+ // *** write 8-bit-strings ***
+ // (slice length setting has no effect here -> disabled automatically)
+
+//UNUSED2008-05 /** Writes ByteString buffer (without string length field). */
+//UNUSED2008-05 void WriteByteStringBuffer(
+//UNUSED2008-05 const ByteString& rString,
+//UNUSED2008-05 sal_uInt16 nMaxLen = 0x00FF );
+
+ /** Writes string length field and ByteString buffer. */
+ void WriteByteString(
+ const ByteString& rString,
+ sal_uInt16 nMaxLen = 0x00FF,
+ bool b16BitCount = false );
+
+ /** Writes 8-bit character buffer. */
+ void WriteCharBuffer( const ScfUInt8Vec& rBuffer );
+
+ // *** SvStream access ***
+
+ /** Sets position of system stream (only allowed outside of records). */
+ sal_Size SetSvStreamPos( sal_Size nPos );
+ /** Returns the absolute position of the system stream. */
+ inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); }
+
+ void SetEncrypter( XclExpEncrypterRef xEncrypter );
+
+ bool HasValidEncrypter() const;
+
+ void EnableEncryption( bool bEnable = true );
+
+ void DisableEncryption();
+
+private:
+ /** Writes header data, internal setup. */
+ void InitRecord( sal_uInt16 nRecId );
+ /** Rewrites correct record length, if different from calculated. */
+ void UpdateRecSize();
+ /** Recalculates mnCurrSize and mnSliceSize. */
+ void UpdateSizeVars( sal_Size nSize );
+ /** Writes CONTINUE header, internal setup. */
+ void StartContinue();
+ /** Refreshes counter vars, creates CONTINUE records. */
+ void PrepareWrite( sal_uInt16 nSize );
+ /** Creates CONTINUE record at end of record.
+ @return Maximum data block size remaining. */
+ sal_uInt16 PrepareWrite();
+
+ /** Writes a raw sequence of zero bytes. */
+ void WriteRawZeroBytes( sal_Size nBytes );
+
+private:
+ SvStream& mrStrm; /// Reference to the system output stream.
+ const XclExpRoot& mrRoot; /// Filter root data.
+
+ bool mbUseEncrypter;
+ XclExpEncrypterRef mxEncrypter;
+
+ // length data
+ sal_uInt16 mnMaxRecSize; /// Maximum size of record content.
+ sal_uInt16 mnMaxContSize; /// Maximum size of CONTINUE content.
+ sal_uInt16 mnCurrMaxSize; /// Current maximum, either mnMaxRecSize or mnMaxContSize.
+ sal_uInt16 mnMaxSliceSize; /// Maximum size of data slices (parts that cannot be split).
+ sal_uInt16 mnHeaderSize; /// Record size written in last record header.
+ sal_uInt16 mnCurrSize; /// Count of bytes already written in current record.
+ sal_uInt16 mnSliceSize; /// Count of bytes already written in current slice.
+ sal_Size mnPredictSize; /// Predicted size received from calling function.
+
+ // stream position data
+ sal_Size mnLastSizePos; /// Stream position of size field in current header.
+ bool mbInRec; /// true = currently writing inside of a record.
+};
+
+// ============================================================================
+
+class XclExpBiff8Encrypter
+{
+public:
+ explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] );
+ ~XclExpBiff8Encrypter();
+
+ bool IsValid() const;
+
+ void GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const;
+
+ void Encrypt( SvStream& rStrm, sal_uInt8 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt16 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt32 nData );
+
+ void Encrypt( SvStream& rStrm, sal_Int8 nData );
+ void Encrypt( SvStream& rStrm, sal_Int16 nData );
+ void Encrypt( SvStream& rStrm, sal_Int32 nData );
+
+ void Encrypt( SvStream& rStrm, float fValue );
+ void Encrypt( SvStream& rStrm, double fValue );
+
+ void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes );
+
+private:
+ void Init( const 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:
+ ::msfilter::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;
+};
+
+// ----------------------------------------------------------------------------
+
+
+// ============================================================================
+
+// `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
+#define XESTRING_TO_PSZ(s) \
+ (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL)
+
+class ScAddress;
+class ScDocument;
+class ScRange;
+class ScRangeList;
+class ScTokenArray;
+struct XclAddress;
+struct XclFontData;
+class XclRangeList;
+
+class XclXmlUtils
+{
+ XclXmlUtils();
+ ~XclXmlUtils();
+ XclXmlUtils(const XclXmlUtils&);
+ XclXmlUtils& operator=(const XclXmlUtils&);
+public:
+ static ::rtl::OUString GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId );
+
+ static ::rtl::OString ToOString( const Color& rColor );
+ static ::rtl::OString ToOString( const ::rtl::OUString& s );
+ static ::rtl::OString ToOString( const ScfUInt16Vec& rBuffer );
+ static ::rtl::OString ToOString( const String& s );
+ static ::rtl::OString ToOString( const ScAddress& rRange );
+ static ::rtl::OString ToOString( const ScRange& rRange );
+ static ::rtl::OString ToOString( const ScRangeList& rRangeList );
+ static ::rtl::OString ToOString( const XclAddress& rAddress );
+ static ::rtl::OString ToOString( const XclExpString& s );
+ static ::rtl::OString ToOString( const XclRangeList& rRangeList );
+
+ static ::rtl::OUString ToOUString( const char* s );
+ static ::rtl::OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 );
+ static ::rtl::OUString ToOUString( const String& s );
+ static ::rtl::OUString ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray );
+ static ::rtl::OUString ToOUString( const XclExpString& s );
+ static const char* ToPsz( bool b );
+};
+
+class XclExpXmlStream : public oox::core::XmlFilterBase
+{
+public:
+ XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr, SvStream& rStrm, const XclExpRoot& rRoot );
+ virtual ~XclExpXmlStream();
+
+ /** Returns the filter root data. */
+ inline const XclExpRoot& GetRoot() const { return mrRoot; }
+
+ sax_fastparser::FSHelperPtr& GetCurrentStream();
+ void PushStream( sax_fastparser::FSHelperPtr aStream );
+ void PopStream();
+
+ ::rtl::OUString GetIdForPath( const ::rtl::OUString& rPath );
+ sax_fastparser::FSHelperPtr GetStreamForPath( const ::rtl::OUString& rPath );
+
+ sax_fastparser::FSHelperPtr& WriteAttributes( sal_Int32 nAttribute, ... );
+ sax_fastparser::FSHelperPtr& WriteFontData( const XclFontData& rFontData, sal_Int32 nNameId );
+
+ sax_fastparser::FSHelperPtr CreateOutputStream (
+ const ::rtl::OUString& sFullStream,
+ const ::rtl::OUString& sRelativeStream,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation,
+ const char* sContentType,
+ const char* sRelationshipType,
+ ::rtl::OUString* pRelationshipId = NULL );
+
+ // ignore
+ virtual bool exportDocument() throw();
+
+ // only needed for import; ignore
+ virtual bool importDocument() throw();
+ virtual oox::vml::Drawing* getVmlDrawing();
+ virtual const oox::drawingml::Theme* getCurrentTheme() const;
+ virtual const oox::drawingml::table::TableStyleListPtr getTableStyles();
+ virtual oox::drawingml::chart::ChartConverter& getChartConverter();
+
+ void Trace( const char* format, ...);
+private:
+ virtual ::rtl::OUString implGetImplementationName() const;
+
+ typedef std::map< ::rtl::OUString,
+ std::pair< ::rtl::OUString,
+ sax_fastparser::FSHelperPtr > > XclExpXmlPathToStateMap;
+
+ const XclExpRoot& mrRoot; /// Filter root data.
+ std::stack< sax_fastparser::FSHelperPtr > maStreams;
+ XclExpXmlPathToStateMap maOpenedStreamMap;
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/xestring.hxx b/sc/source/filter/inc/xestring.hxx
new file mode 100644
index 000000000000..b468696cb3ff
--- /dev/null
+++ b/sc/source/filter/inc/xestring.hxx
@@ -0,0 +1,350 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XESTRING_HXX
+#define SC_XESTRING_HXX
+
+#include "xlstring.hxx"
+
+// ============================================================================
+
+class ScEditCell;
+class ScPatternAttr;
+class EditTextObject;
+class XclExpStream;
+class XclExpXmlStream;
+
+/** This class stores an unformatted or formatted string for Excel export.
+
+ The class supports two completely different types of Excel strings:
+ 1) BIFF2-BIFF7 byte strings: The text is encoded as a 8-bit character
+ array. The strings cannot contain any character formatting.
+ 2) BIFF8 Unicode strings: The text may be stored as UCS-2 character array,
+ or compressed to an 8-bit array, if all characters are less than
+ U+0100. Unicode strings may contain a formatting array, that specifies
+ the used FONT record for different ranges of characters.
+
+ The class provides full support for NUL characters in strings. On
+ construction or assignment the passed flags specify the behaviour of the
+ string while it is written to a stream (the 'Write' functions and
+ 'operator<<').
+ */
+class XclExpString
+{
+public:
+ // constructors -----------------------------------------------------------
+
+ /** Constructs an empty BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ explicit XclExpString(
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Constructs an unformatted BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ explicit XclExpString(
+ const String& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+ /** Constructs an unformatted BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ explicit XclExpString(
+ const ::rtl::OUString& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+//UNUSED2008-05 /** Constructs a formatted BIFF8 Unicode string.
+//UNUSED2008-05 @param rFormats The formatting runs.
+//UNUSED2008-05 @param nFlags Modifiers for string export.
+//UNUSED2008-05 @param nMaxLen The maximum number of characters to store in this string. */
+//UNUSED2008-05 explicit XclExpString(
+//UNUSED2008-05 const String& rString,
+//UNUSED2008-05 const XclFormatRunVec& rFormats,
+//UNUSED2008-05 XclStrFlags nFlags = EXC_STR_DEFAULT,
+//UNUSED2008-05 sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+//UNUSED2008-05
+//UNUSED2008-05 /** Constructs a formatted BIFF8 Unicode string.
+//UNUSED2008-05 @param rFormats The formatting runs.
+//UNUSED2008-05 @param nFlags Modifiers for string export.
+//UNUSED2008-05 @param nMaxLen The maximum number of characters to store in this string. */
+//UNUSED2008-05 explicit XclExpString(
+//UNUSED2008-05 const ::rtl::OUString& rString,
+//UNUSED2008-05 const XclFormatRunVec& rFormats,
+//UNUSED2008-05 XclStrFlags nFlags = EXC_STR_DEFAULT,
+//UNUSED2008-05 sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ // assign -----------------------------------------------------------------
+
+ /** Assigns an unformatted string, converts this object to a BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void Assign(
+ const String& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+ /** Assigns a formatted string, converts this object to a BIFF8 Unicode string.
+ @param rFormats The formatting runs.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void Assign(
+ const String& rString,
+ const XclFormatRunVec& rFormats,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+ /** Assigns an unformatted string, converts this object to a BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void Assign(
+ const ::rtl::OUString& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+ /** Assigns a formatted string, converts this object to a BIFF8 Unicode string.
+ @param rFormats The formatting runs.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void Assign(
+ const ::rtl::OUString& rString,
+ const XclFormatRunVec& rFormats,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+ /** Assigns a Unicode character, converts this object to a BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string (for appending). */
+ void Assign(
+ sal_Unicode cChar,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Assigns an unformatted string, converts this object to a BIFF2-BIFF7 byte string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void AssignByte(
+ const String& rString,
+ rtl_TextEncoding eTextEnc,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+//UNUSED2008-05 /** Assigns a character, converts this object to a BIFF2-BIFF7 byte string.
+//UNUSED2008-05 @param nFlags Modifiers for string export.
+//UNUSED2008-05 @param nMaxLen The maximum number of characters to store in this string (for appending). */
+//UNUSED2008-05 void AssignByte(
+//UNUSED2008-05 sal_Unicode cChar,
+//UNUSED2008-05 rtl_TextEncoding eTextEnc,
+//UNUSED2008-05 XclStrFlags nFlags = EXC_STR_DEFAULT,
+//UNUSED2008-05 sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ // append -----------------------------------------------------------------
+
+ /** Appends a string. Uses the string flags used in constructor or last Assign().
+ @descr This object must be a BIFF8 Unicode string. */
+ void Append( const String& rString );
+
+//UNUSED2008-05 /** Appends a string. Uses the string flags used in constructor or last Assign().
+//UNUSED2008-05 @descr This object must be a BIFF8 Unicode string. */
+//UNUSED2008-05 void Append( const ::rtl::OUString& rString );
+//UNUSED2008-05 /** Appends a character. Uses the string flags used in constructor or last Assign().
+//UNUSED2008-05 @descr This object must be a BIFF8 Unicode string. */
+//UNUSED2008-05 void Append( sal_Unicode cChar );
+
+ /** Appends a string. Uses the string flags used in constructor or last Assign().
+ @descr This object must be a BIFF2-BIFF7 byte string. */
+ void AppendByte( const String& rString, rtl_TextEncoding eTextEnc );
+ /** Appends a character. Uses the string flags used in constructor or last Assign().
+ @descr This object must be a BIFF2-BIFF7 byte string. */
+ void AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc );
+
+ // formatting runs --------------------------------------------------------
+
+ /** Sets new formatting runs for the current text. */
+ void SetFormats( const XclFormatRunVec& rFormats );
+ /** Appends a formatting run. nChar must be greater than last contained character index. */
+ void AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate = true );
+ /** Appends a trailing formatting run with the passed font index. */
+ void AppendTrailingFormat( sal_uInt16 nFontIdx );
+ /** Removes formatting runs at the end, if the string contains too much. */
+ void LimitFormatCount( sal_uInt16 nMaxCount );
+ /** Removes and returns the font index for the first char from the formatting runs, otherwise EXC_FONT_NOTFOUND. */
+ sal_uInt16 RemoveLeadingFont();
+
+ // get data ---------------------------------------------------------------
+
+ /** Returns the character count of the string. */
+ inline sal_uInt16 Len() const { return mnLen; }
+ /** Returns true, if the string is empty. */
+ inline bool IsEmpty() const { return mnLen == 0; }
+ /** Returns true, if the string contains line breaks. */
+ inline bool IsWrapped() const { return mbWrapped; }
+ /** Returns true, if this string is equal to the passed string. */
+ bool IsEqual( const XclExpString& rCmp ) const;
+ /** Returns true, if this string is less than the passed string. */
+ bool IsLessThan( const XclExpString& rCmp ) const;
+
+ /** Returns true, if the string contains formatting information. */
+ inline bool IsRich() const { return !maFormats.empty(); }
+ /** Returns the current count of formatting runs for rich strings. */
+ sal_uInt16 GetFormatsCount() const;
+ /** Returns the vector with all formatting runs. */
+ inline const XclFormatRunVec& GetFormats() const { return maFormats; }
+
+ /** Returns the current string flags field to export. */
+ sal_uInt8 GetFlagField() const;
+ /** Returns the byte count the header will take on export. */
+ sal_uInt16 GetHeaderSize() const;
+ /** Returns the byte count the character buffer will take on export. */
+ sal_Size GetBufferSize() const;
+ /** Returns the byte count the whole string will take on export. */
+ sal_Size GetSize() const;
+
+ /** Returns the specified character from the (already encoded) string. */
+ sal_uInt16 GetChar( sal_uInt16 nCharIdx ) const;
+ /** Returns a hash value for the string. */
+ sal_uInt16 GetHash() const;
+
+ const ScfUInt16Vec& GetUnicodeBuffer() const { return maUniBuffer; }
+
+ // streaming --------------------------------------------------------------
+
+ /** Writes the string length field (1 byte or 2 bytes). */
+ void WriteLenField( XclExpStream& rStrm ) const;
+ /** Writes the string flags field (1 byte). */
+ void WriteFlagField( XclExpStream& rStrm ) const;
+ /** Writes 8-bit or 16-bit length field and string flags field. */
+ void WriteHeader( XclExpStream& rStrm ) const;
+ /** Writes the raw character buffer. */
+ void WriteBuffer( XclExpStream& rStrm ) const;
+ /** Writes the raw formatting run buffer. */
+ void WriteFormats( XclExpStream& rStrm, bool bWriteSize = false ) const;
+ /** Writes the complete Unicode string. */
+ void Write( XclExpStream& rStrm ) const;
+
+ /** Writes the string header to memory. */
+ void WriteHeaderToMem( sal_uInt8* pnMem ) const;
+ /** Writes the raw character buffer to memory (8-bit or 16-bit little-endian). */
+ void WriteBufferToMem( sal_uInt8* pnMem ) const;
+ /** Writes the entire string to memory. */
+ void WriteToMem( sal_uInt8* pnMem ) const;
+
+ void WriteXml( XclExpXmlStream& rStrm ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns true, if the flag field should be written. */
+ bool IsWriteFlags() const;
+ /** Returns true, if the formatting run vector should be written. */
+ bool IsWriteFormats() const;
+
+ /** Sets the string length but regards the limit given in mnMaxLen. */
+ void SetStrLen( sal_Int32 nNewLen );
+ /** Inserts the passed character array into the internal character buffer.
+ @param nBegin First index in internal buffer to fill.
+ @param nLen Number of characters to insert. */
+ void CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen );
+ /** Inserts the passed character array into the internal character buffer.
+ @param nBegin First index in internal buffer to fill.
+ @param nLen Number of characters to insert. */
+ void CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen );
+
+ /** Initializes flags, string length, and resizes character buffer.
+ @param nFlags Modifiers for string export.
+ @param nCurrLen The requested number of characters for the string.
+ @param nMaxLen The maximum length allowed of the resulting string.
+ @param bBiff8 true = BIFF8 Unicode string; false = BIFF2-BIFF7 byte string. */
+ void Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 );
+ /** Creates the character buffer from the given Unicode array.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nFlags Modifiers for string export.
+ @param nCurrLen The real count of characters contained in the passed buffer.
+ @param nMaxLen The maximum length allowed of the resulting string. */
+ void Build(
+ const sal_Unicode* pcSource, sal_Int32 nCurrLen,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen );
+ /** Creates the character buffer from the given character array.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nFlags Modifiers for string export.
+ @param nCurrLen The real count of characters contained in the passed buffer.
+ @param nMaxLen The maximum length allowed of the resulting string. */
+ void Build(
+ const sal_Char* pcSource, sal_Int32 nCurrLen,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen );
+
+ /** Initializes string length and resizes character buffers for appending operation.
+ @param nAddLen The number of characters to be appended. */
+ void InitAppend( sal_Int32 nAddLen );
+ /** Appends the given Unicode array to the character buffer.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nAddLen The real count of characters contained in the passed buffer. */
+ void BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen );
+ /** Appends the given character array to the character buffer.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nAddLen The real count of characters contained in the passed buffer. */
+ void BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen );
+
+ /** Initializes write process on stream. */
+ void PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const;
+
+private:
+ ScfUInt16Vec maUniBuffer; /// The Unicode character buffer.
+ ScfUInt8Vec maCharBuffer; /// The byte character buffer.
+ XclFormatRunVec maFormats; /// All formatting runs.
+ sal_uInt16 mnLen; /// Character count to export.
+ sal_uInt16 mnMaxLen; /// Maximum allowed number of characters.
+ bool mbIsBiff8; /// true = BIFF8 Unicode string, false = BIFF2-7 bytestring.
+ bool mbIsUnicode; /// true, if at least one character is >0xFF.
+ bool mb8BitLen; /// true = write 8-bit string length; false = 16-bit.
+ bool mbSmartFlags; /// true = omit flags on empty string; false = always write flags.
+ bool mbSkipFormats; /// true = skip formats on export; false = write complete formatted string.
+ bool mbWrapped; /// true = text contains several paragraphs.
+ bool mbSkipHeader; /// ture = skip length and flags when writing string bytes.
+};
+
+inline bool operator==( const XclExpString& rLeft, const XclExpString& rRight )
+{
+ return rLeft.IsEqual( rRight );
+}
+
+inline bool operator!=( const XclExpString& rLeft, const XclExpString& rRight )
+{
+ return !(rLeft == rRight);
+}
+
+inline bool operator<( const XclExpString& rLeft, const XclExpString& rRight )
+{
+ return rLeft.IsLessThan( rRight );
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclExpString& rString )
+{
+ rString.Write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx
new file mode 100644
index 000000000000..fd7303509688
--- /dev/null
+++ b/sc/source/filter/inc/xestyle.hxx
@@ -0,0 +1,781 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XESTYLE_HXX
+#define SC_XESTYLE_HXX
+
+#include <map>
+#include <tools/mempool.hxx>
+#include <tools/string.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/nfkeytab.hxx>
+#include <editeng/svxfont.hxx>
+#include "xerecord.hxx"
+#include "xlstyle.hxx"
+#include "xeroot.hxx"
+
+/* ============================================================================
+- Buffers for style records (PALETTE, FONT, FORMAT, XF, STYLE).
+============================================================================ */
+
+const sal_uInt16 EXC_ID_FONTLIST = 0x8031; /// For internal use only.
+const sal_uInt16 EXC_ID_FORMATLIST = 0x801E; /// For internal use only.
+const sal_uInt16 EXC_ID_XFLIST = 0x8043; /// For internal use only.
+
+// PALETTE record - color information =========================================
+
+/** Different types of colors in a document. */
+enum XclExpColorType
+{
+ EXC_COLOR_CELLTEXT, /// Text in a cell.
+ EXC_COLOR_CELLBORDER, /// Border of a cell.
+ EXC_COLOR_CELLAREA, /// Background area of a cell.
+ EXC_COLOR_CHARTTEXT, /// Text color in a chart.
+ EXC_COLOR_CHARTLINE, /// Line in a chart.
+ EXC_COLOR_CHARTAREA, /// Area in a chart.
+ EXC_COLOR_CTRLTEXT, /// Text color in a form control.
+ EXC_COLOR_GRID, /// Spreadsheet grid color.
+ EXC_COLOR_TABBG /// Spreadsheet tab bg color.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpPaletteImpl;
+
+/** Stores all used colors in the document.
+
+ Supports color reduction to the maximum count of the current BIFF version.
+ An instance of this class collects all colors in the conversion phase of
+ the export, using the InsertColor() function. It returns a unique
+ identidier for each passed color.
+
+ After the entire document is converted, the Finalize() function will reduce
+ the palette to the number of colors supported by the current BIFF version.
+
+ Then, in the streaming phase, the functions GetColorIndex() and
+ GetMixedColors() return the real Excel palette index for all color
+ identifiers.
+ */
+class XclExpPalette : public XclDefaultPalette, public XclExpRecord
+{
+public:
+ explicit XclExpPalette( const XclExpRoot& rRoot );
+ virtual ~XclExpPalette();
+
+ /** Inserts the color into the list and updates weighting.
+ @param nAutoDefault The Excel palette index for automatic color.
+ @return A unique ID for this color. */
+ sal_uInt32 InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
+ /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
+ static sal_uInt32 GetColorIdFromIndex( sal_uInt16 nIndex );
+
+ /** Reduces the color list to the maximum count of the current BIFF version. */
+ void Finalize();
+
+ /** Returns the Excel palette index of the color with passed color ID. */
+ sal_uInt16 GetColorIndex( sal_uInt32 nColorId ) const;
+
+ /** Returns a foreground and background color for the two passed color IDs.
+ @descr If rnXclPattern contains a solid pattern, this function tries to find
+ the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
+ This will result in a better approximation to the passed foreground color. */
+ void GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
+
+ /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ ColorData GetColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the color for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ inline Color GetColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetColorData( nXclIndex ) ); }
+
+ /** Saves the PALETTE record, if it differs from the default palette. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the PALETTE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef ScfRef< XclExpPaletteImpl > XclExpPaletteImplRef;
+ XclExpPaletteImplRef mxImpl;
+};
+
+// FONT record - font information =============================================
+
+class Font;
+class SvxFont;
+
+const size_t EXC_FONTLIST_NOTFOUND = static_cast< size_t >( -1 );
+
+// ----------------------------------------------------------------------------
+
+/** Static helper functions for font export. */
+class XclExpFontHelper
+{
+public:
+ /** Returns the script type of the first font item found in the item set and its parents. */
+ static sal_Int16 GetFirstUsedScript(
+ const XclExpRoot& rRoot,
+ const SfxItemSet& rItemSet );
+
+ /** Returns a VCL font object filled from the passed item set. */
+ static Font GetFontFromItemSet(
+ const XclExpRoot& rRoot,
+ const SfxItemSet& rItemSet,
+ sal_Int16 nScript );
+
+ /** Returns true, if at least one font related item is set in the passed item set.
+ @param bDeep true = Searches in parent item sets too. */
+ static bool CheckItems(
+ const XclExpRoot& rRoot,
+ const SfxItemSet& rItemSet,
+ sal_Int16 nScript,
+ bool bDeep );
+
+private:
+ XclExpFontHelper();
+ ~XclExpFontHelper();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores all data of an Excel font and provides export of FONT records. */
+class XclExpFont : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpFont( const XclExpRoot& rRoot,
+ const XclFontData& rFontData, XclExpColorType eColorType );
+
+ /** Returns read-only access to font data. */
+ inline const XclFontData& GetFontData() const { return maData; }
+ /** Returns the font color identifier. */
+ inline sal_uInt32 GetFontColorId() const { return mnColorId; }
+ /** Compares this font with the passed font data.
+ @param nHash The hash value calculated from the font data. */
+ virtual bool Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the FONT record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclFontData maData; /// All font attributes.
+ sal_uInt32 mnColorId; /// Unique color ID for text color.
+ sal_uInt32 mnHash; /// Hash value for fast comparison.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Used as placeholder for font index 4, which is not used in Excel. */
+class XclExpBlindFont : public XclExpFont
+{
+public:
+ explicit XclExpBlindFont( const XclExpRoot& rRoot );
+
+ /** Returns always false to never find this font while searching the font list. */
+ virtual bool Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const;
+
+ /** Skips writing this record. */
+ virtual void Save( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class ScPatternAttr;
+
+/** Stores the data of all fonts used in the document. */
+class XclExpFontBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpFontBuffer( const XclExpRoot& rRoot );
+
+ /** Returns the specified font from font list. */
+ const XclExpFont* GetFont( sal_uInt16 nXclFont ) const;
+ /** Returns the application font data of this file, needed e.g. for column width. */
+ const XclFontData& GetAppFontData() const;
+
+ /** Inserts a new font with the passed font data into the buffer if not present.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const XclFontData& rFontData,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the font into the buffer if not present.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const Font& rFont,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the SvxFont into the buffer if not present, e.g. where escapements are used.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const SvxFont& rFont,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the font contained in the passed item set into the buffer, if not present.
+ @param nScript The script type of the font properties to be used.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const SfxItemSet& rItemSet, sal_Int16 nScript,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the font contained in rPattern into the buffer if not present.
+ @param nScript The script type of the font properties to be used.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const ScPatternAttr& rPattern, sal_Int16 nScript,
+ XclExpColorType eColorType, bool bAppFont = false );
+
+ /** Writes all FONT records contained in this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Initializes the default fonts for the current BIFF version. */
+ void InitDefaultFonts();
+ /** Tries to find the passed font and returns the current list index. */
+ size_t Find( const XclFontData& rFontData );
+
+private:
+ typedef XclExpRecordList< XclExpFont > XclExpFontList;
+ typedef XclExpFontList::RecordRefType XclExpFontRef;
+
+ XclExpFontList maFontList; /// List of all FONT records.
+ size_t mnXclMaxSize; /// Maximum number of fonts.
+};
+
+// FORMAT record - number formats =============================================
+
+/** Stores a core number format index with corresponding Excel format index. */
+struct XclExpNumFmt
+{
+ ULONG mnScNumFmt; /// Core index of the number format.
+ sal_uInt16 mnXclNumFmt; /// Resulting Excel format index.
+
+ inline explicit XclExpNumFmt( ULONG nScNumFmt, sal_uInt16 nXclNumFmt ) :
+ mnScNumFmt( nScNumFmt ), mnXclNumFmt( nXclNumFmt ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+class SvNumberFormatter;
+
+/** Stores all number formats used in the document. */
+class XclExpNumFmtBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpNumFmtBuffer( const XclExpRoot& rRoot );
+ virtual ~XclExpNumFmtBuffer();
+
+ /** Returns the core index of the current standard number format. */
+ inline ULONG GetStandardFormat() const { return mnStdFmt; }
+
+ /** Inserts a number format into the format buffer.
+ @param nScNumFmt The core index of the number format.
+ @return The resulting Excel format index. */
+ sal_uInt16 Insert( ULONG nScNumFmt );
+
+ /** Writes all FORMAT records contained in this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the FORMAT record with index nXclIx and format string rFormatStr. */
+ void WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const String& rFormatStr );
+ /** Writes the FORMAT record represented by rFormat. */
+ void WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat );
+
+ String GetFormatCode ( const XclExpNumFmt& rFormat );
+
+private:
+ typedef ::std::auto_ptr< SvNumberFormatter > SvNumberFormatterPtr;
+ typedef ::std::vector< XclExpNumFmt > XclExpNumFmtVec;
+ typedef NfKeywordTable* NfKeywordTablePtr;
+
+ SvNumberFormatterPtr mxFormatter; /// Special number formatter for conversion.
+ XclExpNumFmtVec maFormatMap; /// Maps core formats to Excel indexes.
+ NfKeywordTablePtr mpKeywordTable; /// Replacement table.
+ ULONG mnStdFmt; /// Key for standard number format.
+ sal_uInt16 mnXclOffset; /// Offset to first user defined format.
+};
+
+// XF, STYLE record - Cell formatting =========================================
+
+/** Extends the XclCellProt struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellProt : public XclCellProt
+{
+ /** Fills the protection attributes from the passed item set.
+ @return true = At least one protection item is set. */
+ bool FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle = false );
+
+#if 0
+ /** Fills the data to the passed fields of a BIFF2 XF record. */
+ void FillToXF2( sal_uInt8& rnNumFmt ) const;
+#endif
+ /** Fills the data to the passed fields of a BIFF3-BIFF8 XF record. */
+ void FillToXF3( sal_uInt16& rnProt ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellAlign struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellAlign : public XclCellAlign
+{
+ /** Fills the alignment attributes from the passed item set.
+ @descr Fills only the attributes exported in the passed BIFF version.
+ @param bForceLineBreak true = Set line break flag unconditionally.
+ @return true = At least one alignment item is set. */
+ bool FillFromItemSet( const SfxItemSet& rItemSet,
+ bool bForceLineBreak, XclBiff eBiff, bool bStyle = false );
+
+#if 0
+ /** Fills the data to the passed fields of a BIFF2 XF record. */
+ void FillToXF2( sal_uInt8& rnFlags ) const;
+ /** Fills the data to the passed fields of a BIFF3 XF record. */
+ void FillToXF3( sal_uInt16& rnAlign ) const;
+ /** Fills the data to the passed fields of a BIFF4 XF record. */
+ void FillToXF4( sal_uInt16& rnAlign ) const;
+#endif
+ /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
+ void FillToXF5( sal_uInt16& rnAlign ) const;
+ /** Fills the data to the passed fields of a BIFF8 XF record. */
+ void FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellBorder struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellBorder : public XclCellBorder
+{
+ sal_uInt32 mnLeftColorId; /// Color ID for left line.
+ sal_uInt32 mnRightColorId; /// Color ID for right line.
+ sal_uInt32 mnTopColorId; /// Color ID for top line.
+ sal_uInt32 mnBottomColorId; /// Color ID for bottom line.
+ sal_uInt32 mnDiagColorId; /// Color ID for diagonal line(s).
+
+ explicit XclExpCellBorder();
+
+ /** Fills the border attributes from the passed item set.
+ @descr Fills only the attributes exported in the passed BIFF version.
+ @return true = At least one border item is set. */
+ bool FillFromItemSet( const SfxItemSet& rItemSet,
+ XclExpPalette& rPalette, XclBiff eBiff, bool bStyle = false );
+ /** Fills the mn***Color base members from the mn***ColorId members. */
+ void SetFinalColors( const XclExpPalette& rPalette );
+
+#if 0
+ /** Fills the data to the passed fields of a BIFF2 XF record. */
+ void FillToXF2( sal_uInt8& rnFlags ) const;
+ /** Fills the data to the passed fields of a BIFF3/BIFF4 XF record. */
+ void FillToXF3( sal_uInt32& rnBorder ) const;
+#endif
+ /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
+ void FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const;
+ /** Fills the data to the passed fields of a BIFF8 XF record. */
+ void FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const;
+
+ /** Fills the data to the passed fields of a BIFF8 CF (conditional format) record. */
+ void FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellArea struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellArea : public XclCellArea
+{
+ sal_uInt32 mnForeColorId; /// Foreground color ID.
+ sal_uInt32 mnBackColorId; /// Background color ID.
+
+ explicit XclExpCellArea();
+
+ /** Fills the area attributes from the passed item set.
+ @return true = At least one area item is set. */
+ bool FillFromItemSet(
+ const SfxItemSet& rItemSet, XclExpPalette& rPalette,
+ bool bStyle = false );
+ /** Fills the mn***Color base members from the mn***ColorId members. */
+ void SetFinalColors( const XclExpPalette& rPalette );
+
+#if 0
+ /** Fills the data to the passed fields of a BIFF2 XF record. */
+ void FillToXF2( sal_uInt8& rnFlags ) const;
+ /** Fills the data to the passed fields of a BIFF3/BIFF4 XF record. */
+ void FillToXF3( sal_uInt16& rnArea ) const;
+#endif
+ /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
+ void FillToXF5( sal_uInt32& rnArea ) const;
+ /** Fills the data to the passed fields of a BIFF8 XF record. */
+ void FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const;
+
+ /** Fills the data to the passed fields of a BIFF8 CF (conditional format) record. */
+ void FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A combination of unique XF identifier with real Excel XF index. */
+struct XclExpXFId
+{
+ sal_uInt32 mnXFId; /// Temporary XF identifier.
+ sal_uInt16 mnXFIndex; /// Real Excel XF index.
+
+ explicit XclExpXFId();
+ explicit XclExpXFId( sal_uInt32 nXFId );
+
+ /** Converts the XF identifier in mnXFId to an Excel XF index and stores it in mnXFIndex. */
+ void ConvertXFIndex( const XclExpRoot& rRoot );
+};
+
+// ----------------------------------------------------------------------------
+
+class SfxStyleSheetBase;
+
+/** Represents an XF record which contains all formatting data of a cell or cell style. */
+class XclExpXF : public XclXFBase, public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Constructs a cell XF record from the passed Calc cell formatting. */
+ explicit XclExpXF(
+ const XclExpRoot& rRoot,
+ const ScPatternAttr& rPattern,
+ sal_Int16 nScript,
+ ULONG nScForceNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND,
+ sal_uInt16 nForceXclFont = EXC_FONT_NOTFOUND,
+ bool bForceLineBreak = false );
+ /** Constructs a style XF record from the passed cell style sheet. */
+ explicit XclExpXF(
+ const XclExpRoot& rRoot,
+ const SfxStyleSheetBase& rStyleSheet );
+
+ /** Returns the cell protection settings of this XF. */
+ const XclExpCellProt& GetProtectionData() const { return maProtection; }
+ /** Returns the alignment settings of this XF. */
+ const XclExpCellAlign& GetAlignmentData() const { return maAlignment; }
+ /** Returns the cell border settings of this XF. */
+ const XclExpCellBorder& GetBorderData() const { return maBorder; }
+ /** Returns the cell fill settings of this XF. */
+ const XclExpCellArea& GetAreaData() const { return maArea; }
+
+ /** Returns true, if this XF record represents the passed cell formatting.
+ @descr Searches for cell XFs only. */
+ bool Equals(
+ const ScPatternAttr& rPattern,
+ ULONG nScForceNumFmt,
+ sal_uInt16 nForceXclFont,
+ bool bForceLineBreak ) const;
+
+ /** Returns true, if this XF record represents the passed style.
+ @descr Searches for style XFs only. */
+ bool Equals( const SfxStyleSheetBase& rStyleSheet ) const;
+
+ /** Sets the resulting Excel palette index from all used color IDs (border and area). */
+ void SetFinalColors();
+
+ /** Returns true, if this XF record is completely equal to the passed. */
+ bool Equals( const XclExpXF& rCmpXF ) const;
+
+ void SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+protected:
+ explicit XclExpXF( const XclExpRoot& rRoot, bool bCellXF );
+
+protected: // access for XclExpDefaultXF
+ const SfxItemSet* mpItemSet; /// Pointer to the item set (we do not own it).
+
+ XclExpCellProt maProtection; /// Cell protection flags.
+ XclExpCellAlign maAlignment; /// All alignment attributes.
+ XclExpCellBorder maBorder; /// Border line style.
+ XclExpCellArea maArea; /// Background area style.
+ sal_uInt32 mnParentXFId; /// XF ID of parent XF record.
+ ULONG mnScNumFmt; /// Calc number format index.
+ sal_uInt16 mnXclFont; /// Excel font index.
+ sal_uInt16 mnXclNumFmt; /// Excel number format index.
+ sal_Int32 mnBorderId; /// OOXML Border Index
+ sal_Int32 mnFillId; /// OOXML Fill Index
+
+private:
+ using XclXFBase::Equals;
+
+ /** Initializes with default values. */
+ void InitDefault();
+ /** Fills all members from the passed item set.
+ @param bDefStyle true = This is the "Default"/"Normal" style - needs special handling. */
+ void Init(
+ const SfxItemSet& rItemSet,
+ sal_Int16 nScript,
+ ULONG nForceScNumFmt,
+ sal_uInt16 nForceXclFont,
+ bool bForceLineBreak,
+ bool bDefStyle );
+
+ /** Returns the bits specifying the used attributes.
+ @descr In cell XFs a set bit means a used attribute, in style XF a cleared
+ bit means a used attribute. This method regards the cell/style state.
+ @return The mask based on bit 0 (not yet bit-shifted as needed for export). */
+ sal_uInt8 GetUsedFlags() const;
+
+ void WriteBody5( XclExpStream& rStrm );
+ void WriteBody8( XclExpStream& rStrm );
+
+ /** Writes the contents of the XF record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a default XF record. Supports methods to set attributes directly. */
+class XclExpDefaultXF : public XclExpXF
+{
+public:
+ explicit XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF );
+
+//UNUSED2008-05 /** Sets the parent XF ID. Only allowed for cell XFs. */
+//UNUSED2008-05 void SetParent( sal_uInt32 nParentXFId );
+//UNUSED2008-05
+//UNUSED2008-05 /** Sets all "attribute used" flags explicitely.
+//UNUSED2008-05 @descr The following Set***() functions set the appropriate flag too. */
+//UNUSED2008-05 void SetUsedFlags(
+//UNUSED2008-05 bool bProtUsed, bool bFontUsed, bool bFmtUsed,
+//UNUSED2008-05 bool bAlignUsed, bool bBorderUsed, bool bAreaUsed );
+//UNUSED2008-05 /** Sets the cell protection flags. */
+//UNUSED2008-05 void SetProtection( const XclExpCellProt& rProtection );
+//UNUSED2008-05 /** Sets cell alignment attributes. */
+//UNUSED2008-05 void SetAlignment( const XclExpCellAlign& rAlignment );
+//UNUSED2008-05 /** Sets a cell border style. */
+//UNUSED2008-05 void SetBorder( const XclExpCellBorder& rBorder );
+//UNUSED2008-05 /** Sets a cell area style. */
+//UNUSED2008-05 void SetArea( const XclExpCellArea& rArea );
+
+ /** Sets the Excel font index. */
+ void SetFont( sal_uInt16 nXclFont );
+ /** Sets the Excel number format index. */
+ void SetNumFmt( sal_uInt16 nXclNumFmt );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a STYLE record containing the data of a cell style.
+ @descr The calss is able to store built-in and user-defined styles. */
+class XclExpStyle : public XclExpRecord
+{
+public:
+ explicit XclExpStyle( sal_uInt32 nXFId, const String& rStyleName );
+ explicit XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
+
+ /** Returns true, if this record represents an Excel built-in style. */
+ inline bool IsBuiltIn() const { return mnStyleId != EXC_STYLE_USERDEF; }
+
+ inline const String& GetName() const { return maName; }
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the STYLE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ String maName; /// Name of the cell style.
+ XclExpXFId maXFId; /// XF identifier for style formatting.
+ sal_uInt8 mnStyleId; /// Built-in style identifier.
+ sal_uInt8 mnLevel; /// Outline level for RowLevel and ColLevel styles.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores all XF records (cell formats and cell styles) in the document.
+
+ Stores also the names of user defined cell styles (STYLE records). Supports
+ reduction to the maximum count of XF records of the current BIFF version.
+
+ An instance of this class collects all XF records in the conversion phase
+ of the export, using the Insert() and InsertStyle() functions. It returns a
+ unique identidier for each XF record.
+
+ After the entire document is converted, the Finalize() function will reduce
+ the list to the number of XF records supported by the current BIFF version.
+
+ Then, in the streaming phase, the function GetXFIndex() returns the real
+ Excel XF index for all XF identifiers.
+ */
+class XclExpXFBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpXFBuffer( const XclExpRoot& rRoot );
+
+ /** Inserts predefined built-in styles and user-defined styles. */
+ void Initialize();
+
+ /** Finds or creates a cell XF record for the passed item set.
+ @return A unique XF record ID. */
+ sal_uInt32 Insert( const ScPatternAttr* pPattern, sal_Int16 nScript );
+ /** Finds or creates a cell XF record for the passed item set.
+ @param nForceXclFont The font to be exported. If not equal to EXC_FONT_NOTFOUND,
+ this font index will be used unconditionally and the cell font will be ignored.
+ @param bForceLineBreak true = Set line break flag unconditionally.
+ This is required for cells that contain multi-line text.
+ @return A unique XF record ID. */
+ sal_uInt32 InsertWithFont(
+ const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uInt16 nForceXclFont,
+ bool bForceLineBreak );
+ /** Finds or creates a cell XF record for the passed item set, with custom number format.
+ @param nXFFlags Additional flags allowing to control the creation of an XF.
+ @param nForceScNumFmt The number format to be exported, e.g. formula
+ result type. This format will always overwrite the cell's number format.
+ @param bForceLineBreak true = Set line break flag unconditionally.
+ This is required for cells that contain multi-line text.
+ @return A unique XF record ID. */
+ sal_uInt32 InsertWithNumFmt(
+ const ScPatternAttr* pPattern, sal_Int16 nScript,
+ ULONG nForceScNumFmt,
+ bool bForceLineBreak );
+ /** Inserts the passed cell style. Creates a style XF record and a STYLE record.
+ @return A unique XF record ID. */
+ sal_uInt32 InsertStyle( const SfxStyleSheetBase* pStyleSheet );
+ /** Returns the XF identifier representing a fixed Excel XF index (e.g. for built-in XFs). */
+ static sal_uInt32 GetXFIdFromIndex( sal_uInt16 nXFIndex );
+ /** Returns the XF identifier representing the default cell XF. */
+ static sal_uInt32 GetDefCellXFId();
+
+ /** Returns an XF record by its unique identifier. */
+ const XclExpXF* GetXFById( sal_uInt32 nXFId ) const;
+
+ /** Reduces the XF record list to the maximum allowed number of records. */
+ void Finalize();
+
+ /** Returns the Excel XF index of the XF record with passed XF ID. */
+ sal_uInt16 GetXFIndex( sal_uInt32 nXFId ) const;
+
+ sal_Int32 GetXmlStyleIndex( sal_uInt32 nXFId ) const;
+ sal_Int32 GetXmlCellIndex( sal_uInt32 nXFId ) const;
+
+ /** Writes all XF records contained in this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpXF > XclExpXFList;
+ typedef XclExpXFList::RecordRefType XclExpXFRef;
+ typedef XclExpRecordList< XclExpStyle > XclExpStyleList;
+
+private:
+ /** Returns the XF ID of the cell XF containing the passed format. */
+ sal_uInt32 FindXF( const ScPatternAttr& rPattern, ULONG nForceScNumFmt,
+ sal_uInt16 nForceXclFont, bool bForceLineBreak ) const;
+ /** Returns the XF ID of the style XF containing the passed style. */
+ sal_uInt32 FindXF( const SfxStyleSheetBase& rStyleSheet ) const;
+
+ /** Returns the XF ID of a built-in style XF, searches by style identifier. */
+ sal_uInt32 FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL ) const;
+
+ /** Tries to find the XF record containing the passed format or inserts a new record.
+ @return The XF record ID. */
+ sal_uInt32 InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
+ ULONG nForceScNumFmt,
+ sal_uInt16 nForceXclFont, bool bForceLineBreak );
+ /** Inserts the passed cell style. Creates a style XF record and a STYLE record.
+ @return The XF record ID. */
+ sal_uInt32 InsertStyleXF( const SfxStyleSheetBase& rStyleSheet );
+
+ /** Inserts an XF and a STYLE record for all user defined style sheets. */
+ void InsertUserStyles();
+
+ /** Inserts a built-in XF record without a STYLE record and returns the XF ID.
+ @param bCreateStyleRec true = Creates the related STYLE record. */
+ sal_uInt32 AppendBuiltInXF( XclExpXFRef xXF,
+ sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
+ /** Inserts a built-in XF and STYLE record and returns the XF ID.
+ @param bCreateStyleRec true = Creates the related STYLE record. */
+ sal_uInt32 AppendBuiltInXFWithStyle( XclExpXFRef xXF,
+ sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
+
+ /** Inserts all default XF and STYLE records. */
+ void InsertDefaultRecords();
+
+ /** Appends a XF index to the internal ID<->index maps. */
+ void AppendXFIndex( sal_uInt32 nXFId );
+
+ void AddBorderAndFill( const XclExpXF& rXF );
+ void SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF );
+
+private:
+ /** Extended info about a built-in XF. */
+ struct XclExpBuiltInInfo
+ {
+ sal_uInt8 mnStyleId; /// Built-in style identifier.
+ sal_uInt8 mnLevel; /// Level for RowLevel/ColLevel styles.
+ bool mbPredefined; /// true = XF still predefined.
+ bool mbHasStyleRec; /// true = STYLE record created.
+ explicit XclExpBuiltInInfo();
+ };
+ typedef ::std::map< sal_uInt32, XclExpBuiltInInfo > XclExpBuiltInMap;
+ typedef ::std::vector< XclExpCellBorder > XclExpBorderList;
+ typedef ::std::vector< XclExpCellArea > XclExpFillList;
+
+ XclExpXFList maXFList; /// List of all XF records.
+ XclExpStyleList maStyleList; /// List of all STYLE records.
+ XclExpBuiltInMap maBuiltInMap; /// Contained elements describe built-in XFs.
+ ScfUInt16Vec maXFIndexVec; /// Maps XF IDs to XF indexes.
+ ScfUInt16Vec maStyleIndexes; /// Maps XF IDs to OOXML Style indexes
+ ScfUInt16Vec maCellIndexes; /// Maps XF IDs to OOXML Cell indexes
+ XclExpXFList maSortedXFList; /// List of XF records in XF index order.
+ XclExpBorderList maBorders; /// List of borders used by XF records
+ XclExpFillList maFills; /// List of fills used by XF records
+
+};
+
+// ============================================================================
+
+class XclExpXmlStyleSheet : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpXmlStyleSheet( const XclExpRoot& rRoot );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
new file mode 100644
index 000000000000..723f9dde09e0
--- /dev/null
+++ b/sc/source/filter/inc/xetable.hxx
@@ -0,0 +1,1089 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XETABLE_HXX
+#define SC_XETABLE_HXX
+
+#include "xltable.hxx"
+
+#include <deque>
+#include <tools/mempool.hxx>
+#include "xladdress.hxx"
+#include "xerecord.hxx"
+#include "xestring.hxx"
+#include "xeformula.hxx"
+#include "xestyle.hxx"
+
+/* ============================================================================
+Export of cell tables including row and column description.
+- Managing all used and formatted cells in a sheet.
+- Row and column properties, i.e. width/height, visibility.
+- Find default row formatting and default column formatting.
+- Merged cell ranges.
+============================================================================ */
+
+// ============================================================================
+// Helper records for cell records
+// ============================================================================
+
+/** Represents a STRING record that contains the result of a string formula. */
+class XclExpStringRec : public XclExpRecord
+{
+public:
+ explicit XclExpStringRec( const XclExpRoot& rRoot, const String& rResult );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpStringRef mxResult;
+};
+
+// Additional records for special formula ranges ==============================
+
+/** Base record for additional range formula records (i.e. ARRAY, SHRFMLA). */
+class XclExpRangeFmlaBase : public XclExpRecord
+{
+public:
+ /** Returns true, if the passed cell position is equal to own base position. */
+ bool IsBasePos( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const;
+
+ /** Derived classes create the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const = 0;
+ /** Derived classes return true, if the own formula contains volatile functions. */
+ virtual bool IsVolatile() const = 0;
+
+protected:
+ /** Constructs the record with a single cell. */
+ explicit XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScAddress& rScPos );
+ /** Constructs the record with a cell range. */
+ explicit XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScRange& rScRange );
+
+ /** Extends the cell range to include the passed cell address. */
+ void Extend( const ScAddress& rScPos );
+
+ /** Writes the range address covered by this record. */
+ void WriteRangeAddress( XclExpStream& rStrm ) const;
+
+protected:
+ XclRange maXclRange; /// Range described by this record.
+ XclAddress maBaseXclPos; /// Address of base cell (first FORMULA record).
+};
+
+typedef ScfRef< XclExpRangeFmlaBase > XclExpRangeFmlaRef;
+
+// Array formulas =============================================================
+
+class ScTokenArray;
+
+/** Represents an ARRAY record that contains the token array of a matrix formula.
+
+ An ARRAY record is stored following the first FORMULA record that is part
+ of a matrix formula. All FORMULA records of a matrix formula contain a
+ reference to the ARRAY record, while the ARRAY record contains the formula
+ token array used by all formulas.
+ */
+class XclExpArray : public XclExpRangeFmlaBase
+{
+public:
+ explicit XclExpArray( XclTokenArrayRef xTokArr, const ScRange& rScRange );
+
+ /** Creates and returns the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const;
+ /** Returns true, if the array formula contains volatile functions. */
+ virtual bool IsVolatile() const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclTokenArrayRef mxTokArr; /// The token array of a matrix formula.
+};
+
+typedef ScfRef< XclExpArray > XclExpArrayRef;
+
+// ----------------------------------------------------------------------------
+
+/** Caches all ARRAY records. */
+class XclExpArrayBuffer : protected XclExpRoot
+{
+public:
+ explicit XclExpArrayBuffer( const XclExpRoot& rRoot );
+
+ /** Inserts a new ARRAY record into the buffer and returns it. */
+ XclExpArrayRef CreateArray( const ScTokenArray& rScTokArr, const ScRange& rScRange );
+ /** Tries to find an ARRAY record that corresponds to an ocMatRef token. */
+ XclExpArrayRef FindArray( const ScTokenArray& rScTokArr ) const;
+
+private:
+ typedef ::std::map< ScAddress, XclExpArrayRef > XclExpArrayMap;
+ XclExpArrayMap maRecMap; /// Map containing the ARRAY records.
+};
+
+// Shared formulas ============================================================
+
+/** Represents a SHRFMLA record that contains the token array of a shared formula.
+
+ A SHRFMLA record is stored following the first FORMULA record that is part
+ of a shared formula. All FORMULA records of a shared formula contain a
+ reference to the SHRFMLA record, while the SHRFMLA record contains the
+ formula token array used by all formulas.
+ */
+class XclExpShrfmla : public XclExpRangeFmlaBase
+{
+public:
+ /** Creates a SHRFMLA record that consists of the passed cell address only. */
+ explicit XclExpShrfmla( XclTokenArrayRef xTokArr, const ScAddress& rScPos );
+
+ /** Extends the cell range to include the passed cell address. */
+ void ExtendRange( const ScAddress& rScPos );
+
+ /** Creates and returns the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const;
+ /** Returns true, if the shared formula contains volatile functions. */
+ virtual bool IsVolatile() const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclTokenArrayRef mxTokArr; /// The token array of a shared formula.
+ sal_uInt8 mnUsedCount; /// Number of FORMULA records referring to this record.
+};
+
+typedef ScfRef< XclExpShrfmla > XclExpShrfmlaRef;
+
+// ----------------------------------------------------------------------------
+
+/** Caches all SHRFMLA records and provides functions to update their ranges. */
+class XclExpShrfmlaBuffer : protected XclExpRoot
+{
+public:
+ explicit XclExpShrfmlaBuffer( const XclExpRoot& rRoot );
+
+ /** Tries to create a new or to update an existing SHRFMLA record.
+ @return An empty reference, if the passed token array does not contain
+ a shared formula. If the token array is a shared formula, this
+ function updates its cell range to include the passed cell position,
+ if there is a SHRFMLA record for the passed token array; otherwise
+ this function creates and returns a new SHRFMLA record. */
+ XclExpShrfmlaRef CreateOrExtendShrfmla(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos );
+
+private:
+ typedef ::std::map< const ScTokenArray*, XclExpShrfmlaRef > XclExpShrfmlaMap;
+ XclExpShrfmlaMap maRecMap; /// Map containing the SHRFMLA records.
+};
+
+// Multiple operations ========================================================
+
+struct XclMultipleOpRefs;
+
+/** Represents a TABLEOP record for a multiple operations range. */
+class XclExpTableop : public XclExpRangeFmlaBase
+{
+public:
+ explicit XclExpTableop( const ScAddress& rScPos,
+ const XclMultipleOpRefs& rRefs, sal_uInt8 nScMode );
+
+ /** Returns true, if the cell range has been extended to the passed position.
+ @descr All references passed in rRefs must fit the ranges passed in the constructor. */
+ bool TryExtend( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs );
+
+ /** Finalizes the record. Tests on valid cell range and reference addresses. */
+ void Finalize();
+
+ /** Creates and returns the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const;
+ /** Returns true, if the multiple operations range is volatile. */
+ virtual bool IsVolatile() const;
+ /** Writes the record if it is valid. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Returns true, if the passed cell position can be appended to this record. */
+ bool IsAppendable( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const;
+
+ /** Writes the contents of the TABLEOP record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ SCTAB mnScTab; /// Sheet index of this record.
+ sal_uInt16 mnLastAppXclCol;/// Column index of last appended cell.
+ sal_uInt16 mnColInpXclCol; /// Column index of column input cell.
+ sal_uInt16 mnColInpXclRow; /// Row index of column input cell.
+ sal_uInt16 mnRowInpXclCol; /// Column index of row input cell.
+ sal_uInt16 mnRowInpXclRow; /// Row index of row input cell.
+ sal_uInt8 mnScMode; /// Type of the multiple operation (Calc constant).
+ bool mbValid; /// true = Contains valid references.
+};
+
+typedef ScfRef< XclExpTableop > XclExpTableopRef;
+
+// ----------------------------------------------------------------------------
+
+/** Contains all created TABLEOP records and supports creating or updating them. */
+class XclExpTableopBuffer : protected XclExpRoot
+{
+public:
+ explicit XclExpTableopBuffer( const XclExpRoot& rRoot );
+
+ /** Tries to update an existing or to create a new TABLEOP record.
+ @return Reference to the TABLEOP record for this cell (existing or new),
+ or an empty reference, if rScTokArr does not contain a multiple
+ operations formula. */
+ XclExpTableopRef CreateOrExtendTableop(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos );
+
+ /** Finalizes all contained TABLEOP records. */
+ void Finalize();
+
+private:
+ /** Tries to create a new TABLEOP record, if rRefs contains valid references. */
+ XclExpTableopRef TryCreate( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs );
+
+private:
+ typedef XclExpRecordList< XclExpTableop > XclExpTableopList;
+ XclExpTableopList maTableopList; /// List of all TABLEOP records.
+};
+
+// ============================================================================
+// Cell records
+// ============================================================================
+
+/** The base class of all cell records. */
+class XclExpCellBase : public XclExpRecord
+{
+public:
+ /** Returns the (first) address of the cell(s). */
+ inline const XclAddress& GetXclPos() const { return maXclPos; }
+ /** Returns the (first) Excel column index of the cell(s). */
+ inline sal_uInt16 GetXclCol() const { return maXclPos.mnCol; }
+ /** Returns the Excel row index of the cell. */
+ inline sal_uInt16 GetXclRow() const { return maXclPos.mnRow; }
+
+ /** Derived classes return the column index of the last contained cell. */
+ virtual sal_uInt16 GetLastXclCol() const = 0;
+ /** Derived classes return the XF identifier of the first contained cell. */
+ virtual sal_uInt32 GetFirstXFId() const = 0;
+ /** Derived classes return true, if this record does not contain at least one valid cell. */
+ virtual bool IsEmpty() const = 0;
+ /** Derived classes return whether the cell contains multi-line text. */
+ virtual bool IsMultiLineText() const;
+
+ /** Derived classes try to merge the contents of the passed cell to own data. */
+ virtual bool TryMerge( const XclExpCellBase& rCell );
+ /** Derived classes convert the XF identifier(s) into the Excel XF index(es).
+ @param rXFIndexes The converted XF index(es) are inserted here. */
+ virtual void ConvertXFIndexes( const XclExpRoot& rRoot ) = 0;
+ /** Derived classes for blank cells insert the Excel XF index(es) into the passed vector. */
+ virtual void GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const;
+ /** Derived classes for blank cells remove unused Excel XF index(es). */
+ virtual void RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes );
+
+protected:
+ explicit XclExpCellBase(
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos );
+
+ /** Sets this record to a new column position. */
+ inline void SetXclCol( sal_uInt16 nXclCol ) { maXclPos.mnCol = nXclCol; }
+ /** Sets this record to a new row position. */
+ inline void SetXclRow( sal_uInt16 nXclRow ) { maXclPos.mnRow = nXclRow; }
+
+private:
+ XclAddress maXclPos; /// Address of the cell.
+};
+
+typedef ScfRef< XclExpCellBase > XclExpCellRef;
+
+// Single cell records ========================================================
+
+/** Base class for all cell records not supporting multiple contents. */
+class XclExpSingleCellBase : public XclExpCellBase
+{
+public:
+ /** Returns the last column, which is equal to the first column for single cells. */
+ virtual sal_uInt16 GetLastXclCol() const;
+ /** Return the XF identifier of the cell. */
+ virtual sal_uInt32 GetFirstXFId() const;
+ /** Returns true, if this record does not contain at least one valid cell. */
+ virtual bool IsEmpty() const;
+ /** Converts the XF identifier into the Excel XF index. */
+ virtual void ConvertXFIndexes( const XclExpRoot& rRoot );
+ /** Writes cell address, XF index, and calls WriteContents() for each cell. */
+ virtual void Save( XclExpStream& rStrm );
+
+protected:
+ explicit XclExpSingleCellBase( sal_uInt16 nRecId, sal_Size nContSize,
+ const XclAddress& rXclPos, sal_uInt32 nXFId );
+
+ explicit XclExpSingleCellBase( const XclExpRoot& rRoot,
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uInt32 nForcedXFId );
+
+ inline void SetContSize( sal_Size nContSize ) { mnContSize = nContSize; }
+ inline sal_Size GetContSize() const { return mnContSize; }
+
+ inline void SetXFId( sal_uInt32 nXFId ) { maXFId.mnXFId = nXFId; }
+ inline sal_uInt32 GetXFId() const { return maXFId.mnXFId; }
+
+private:
+ /** Writes cell address, XF index, and calls WriteContents() for each cell. */
+ virtual void WriteBody( XclExpStream& rStrm );
+ /** Derived classes write the contents of the specified cell (without XF index). */
+ virtual void WriteContents( XclExpStream& rStrm ) = 0;
+
+private:
+ XclExpXFId maXFId; /// The XF identifier of the cell formatting.
+ sal_Size mnContSize; /// The size of the cell contents.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a NUMBER record that describes a cell with a double value. */
+class XclExpNumberCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpNumberCell )
+
+public:
+ explicit XclExpNumberCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ double fValue );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ double mfValue; /// The cell value.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a BOOLERR record that describes a cell with a Boolean value. */
+class XclExpBooleanCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpBooleanCell )
+
+public:
+ explicit XclExpBooleanCell( const XclExpRoot rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ bool bValue );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ bool mbValue; /// The cell value.
+};
+
+// ----------------------------------------------------------------------------
+
+//UNUSED2009-05 /** Represents a BOOLERR record that describes a cell with an error code. */
+//UNUSED2009-05 class XclExpErrorCell : public XclExpSingleCellBase
+//UNUSED2009-05 {
+//UNUSED2009-05 DECL_FIXEDMEMPOOL_NEWDEL( XclExpErrorCell )
+//UNUSED2009-05
+//UNUSED2009-05 public:
+//UNUSED2009-05 explicit XclExpErrorCell( const XclExpRoot rRoot, const XclAddress& rXclPos,
+//UNUSED2009-05 const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+//UNUSED2009-05 sal_uInt8 nErrCode );
+//UNUSED2009-05
+//UNUSED2009-05 virtual void SaveXml( XclExpXmlStream& rStrm );
+//UNUSED2009-05 private:
+//UNUSED2009-05 virtual void WriteContents( XclExpStream& rStrm );
+//UNUSED2009-05
+//UNUSED2009-05 private:
+//UNUSED2009-05 sal_uInt8 mnErrCode; /// The error code.
+//UNUSED2009-05 };
+
+// ----------------------------------------------------------------------------
+
+class ScStringCell;
+class ScEditCell;
+class XclExpHyperlinkHelper;
+
+/** Represents a text cell record.
+
+ May contain a BIFF2-BIFF7 LABEL record for a simple string, or a BIFF2-BIFF7
+ RSTRING record for a formatted string, or a BIFF8 LABELSST string for any
+ string (simply stores a reference to the Shared String Table).
+ */
+class XclExpLabelCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpLabelCell )
+
+public:
+ /** Constructs the record from an unformatted Calc string cell. */
+ explicit XclExpLabelCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScStringCell& rCell );
+
+ /** Constructs the record from a formatted Calc edit cell. */
+ explicit XclExpLabelCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScEditCell& rCell, XclExpHyperlinkHelper& rHlinkHelper );
+
+ /** Returns true if the cell contains multi-line text. */
+ virtual bool IsMultiLineText() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Initializes the record contents. Called from constructors. */
+ void Init( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, XclExpStringRef xText );
+
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ XclExpStringRef mxText; /// The cell text.
+ sal_uInt32 mnSstIndex; /// Index into Shared String Table (only used for BIFF8).
+ bool mbLineBreak; /// True = cell has automatic linebreaks enabled.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScFormulaCell;
+
+/** Represents a FORMULA record that describes a cell with a formula. */
+class XclExpFormulaCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpFormulaCell )
+
+public:
+ explicit XclExpFormulaCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScFormulaCell& rScFmlaCell,
+ XclExpArrayBuffer& rArrayBfr,
+ XclExpShrfmlaBuffer& rShrfmlaBfr,
+ XclExpTableopBuffer& rTableopBfr );
+
+ /** Writes the FORMULA record and additional records related to the formula. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ ScFormulaCell& mrScFmlaCell; /// The Calc formula cell.
+ XclTokenArrayRef mxTokArr; /// The token array of the formula.
+ XclExpRangeFmlaRef mxAddRec; /// Additional record for matrix/shared formulas.
+ XclExpRecordRef mxStringRec; /// STRING record for string result.
+};
+
+// Multiple cell records ======================================================
+
+struct XclExpMultiXFId : public XclExpXFId
+{
+ sal_uInt16 mnCount; /// Number of XF identifiers.
+
+ inline explicit XclExpMultiXFId( sal_uInt32 nXFId, sal_uInt16 nCount = 1 ) :
+ XclExpXFId( nXFId ), mnCount( nCount ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for all cell records supporting multiple contents. */
+class XclExpMultiCellBase : public XclExpCellBase
+{
+public:
+ /** Returns the column index of the last cell this record describes. */
+ virtual sal_uInt16 GetLastXclCol() const;
+ /** Return the XF identifier of the first contained cell. */
+ virtual sal_uInt32 GetFirstXFId() const;
+ /** Returns true, if this record does not contain at least one valid cell. */
+ virtual bool IsEmpty() const;
+
+ /** Convert all XF identifiers into the Excel XF indexes. */
+ virtual void ConvertXFIndexes( const XclExpRoot& rRoot );
+ /** Writes the record, calls WriteContents() for each contained cell.
+ @descr May write several records, if unused XF indexes are contained. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+protected:
+ explicit XclExpMultiCellBase( sal_uInt16 nRecId, sal_uInt16 nMulRecId,
+ sal_Size nContSize, const XclAddress& rXclPos );
+
+ /** Sets the size of the remaining contents of one cell (without the XF index). */
+ inline void SetContSize( sal_Size nContSize ) { mnContSize = nContSize; }
+ /** Returns the size of the remaining contents of one cell (without the XF index). */
+ inline sal_Size GetContSize() const { return mnContSize; }
+
+ /** Returns the number of cells this record represents. */
+ sal_uInt16 GetCellCount() const;
+
+ /** Appends the passed XF identifier nCount times to the list of XF identifiers. */
+ void AppendXFId( const XclExpMultiXFId& rXFId );
+ /** Appends the passed cell format nCount times to the list of XF identifiers. */
+ void AppendXFId( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, sal_uInt16 nScript,
+ sal_uInt32 nForcedXFId, sal_uInt16 nCount = 1 );
+
+ /** Tries to merge the XF ID list of the passed cell with the own list. */
+ bool TryMergeXFIds( const XclExpMultiCellBase& rCell );
+ /** Inserts the Excel XF index(es) into the passed vector. */
+ void GetXFIndexes( ScfUInt16Vec& rXFIndexes ) const;
+
+ /** Removes unused Excel XF index(es).
+ @param rXFIndexes Specifies which XF indexes are used. */
+ void RemoveUnusedXFIndexes( const ScfUInt16Vec& rXFIndexes );
+
+private:
+ /** Derived classes write the remaining contents of the specified cell (without XF index).
+ @param nRelCol Relative column index (starts with 0 for first cell of this record). */
+ virtual void WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol ) = 0;
+ virtual void WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol ) = 0;
+
+private:
+ typedef ::std::deque< XclExpMultiXFId > XclExpMultiXFIdDeq;
+
+ sal_uInt16 mnMulRecId; /// Record ID for multiple record variant.
+ sal_Size mnContSize; /// Data size of contents for one cell
+ XclExpMultiXFIdDeq maXFIds; /// The XF identifiers of the cell formatting.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a BLANK or MULBLANK record that describes empty but formatted cells. */
+class XclExpBlankCell : public XclExpMultiCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpBlankCell )
+
+public:
+ explicit XclExpBlankCell( const XclAddress& rXclPos, const XclExpMultiXFId& rXFId );
+
+ explicit XclExpBlankCell( const XclExpRoot& rRoot,
+ const XclAddress& rXclPos, sal_uInt16 nLastXclCol,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId );
+
+ /** Tries to merge the contents of the passed cell to own data. */
+ virtual bool TryMerge( const XclExpCellBase& rCell );
+ /** Inserts the Excel XF index(es) into the passed vector. */
+ virtual void GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const;
+ /** Tries to remove unused Excel XF index(es). */
+ virtual void RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes );
+
+private:
+ /** Writes the remaining contents of the specified cell (without XF index). */
+ virtual void WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol );
+ virtual void WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an RK or MULRK record that describes cells with a compressed double values. */
+class XclExpRkCell : public XclExpMultiCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpRkCell )
+
+public:
+ explicit XclExpRkCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ sal_Int32 nRkValue );
+
+ /** Tries to merge the contents of the passed cell to own data. */
+ virtual bool TryMerge( const XclExpCellBase& rCell );
+
+private:
+ /** Writes the remaining contents of the specified cell (without XF index). */
+ virtual void WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol );
+ virtual void WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol );
+
+private:
+ ScfInt32Vec maRkValues; /// The cell values.
+};
+
+// ============================================================================
+// Rows and Columns
+// ============================================================================
+
+class ScOutlineArray;
+
+/** Base class for buffers containing row or column outline data. */
+class XclExpOutlineBuffer
+{
+public:
+ /** Returns true, if a collapsed group ends at the last processed position. */
+ inline bool IsCollapsed() const { return mbCurrCollapse; }
+ /** Returns the highest level of an open group at the last processed position. */
+ inline sal_uInt8 GetLevel() const { return ::std::min( mnCurrLevel, EXC_OUTLINE_MAX ); }
+
+protected:
+ /** Constructs the outline buffer.
+ @param bRows true = Process row ouline array; false = Process column outline array. */
+ explicit XclExpOutlineBuffer( const XclExpRoot& rRoot, bool bRows );
+
+ /** Updates the current state by processing the settings at the passed Calc position. */
+ void UpdateColRow( SCCOLROW nScPos );
+
+private:
+ /** Data about an outline level. */
+ struct XclExpLevelInfo
+ {
+ SCCOLROW mnScEndPos; /// The end position of a group in a level.
+ bool mbHidden; /// true = Group in this level is hidden.
+ inline explicit XclExpLevelInfo() : mnScEndPos( 0 ), mbHidden( false ) {}
+ };
+ typedef ::std::vector< XclExpLevelInfo > XclExpLevelInfoVec;
+
+ const ScOutlineArray* mpScOLArray; /// Pointer to Calc outline array.
+ XclExpLevelInfoVec maLevelInfos; /// Info for current row and all levels.
+ sal_uInt8 mnCurrLevel; /// Highest level of an open group for current position.
+ bool mbCurrCollapse; /// true = Collapsed group ends at current position.
+};
+
+// ----------------------------------------------------------------------------
+
+/** The outline buffer for column outlines. */
+class XclExpColOutlineBuffer : public XclExpOutlineBuffer
+{
+public:
+ inline explicit XclExpColOutlineBuffer( const XclExpRoot& rRoot ) :
+ XclExpOutlineBuffer( rRoot, false ) {}
+
+ /** Updates the current state by processing the settings of the passed Calc column. */
+ inline void Update( SCCOL nScCol )
+ { UpdateColRow( static_cast< SCCOLROW >( nScCol ) ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** The outline buffer for row outlines. */
+class XclExpRowOutlineBuffer : public XclExpOutlineBuffer
+{
+public:
+ inline explicit XclExpRowOutlineBuffer( const XclExpRoot& rRoot ) :
+ XclExpOutlineBuffer( rRoot, true ) {}
+
+ /** Updates the current state by processing the settings of the passed Calc row. */
+ inline void Update( SCROW nScRow )
+ { UpdateColRow( static_cast< SCCOLROW >( nScRow ) ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a GUTS record containing the level count of row and column outlines. */
+class XclExpGuts : public XclExpRecord
+{
+public:
+ explicit XclExpGuts( const XclExpRoot& rRoot );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnColLevels; /// Number of visible column outline levels.
+ sal_uInt16 mnColWidth; /// Width of column outline area (pixels).
+ sal_uInt16 mnRowLevels; /// Number of visible row outline levels.
+ sal_uInt16 mnRowWidth; /// Width of row outline area (pixels).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a DIMENSIONS record containing the used area of a sheet. */
+class XclExpDimensions : public XclExpRecord
+{
+public:
+ explicit XclExpDimensions( const XclExpRoot& rRoot );
+
+ /** Sets the used area to the record. */
+ void SetDimensions(
+ sal_uInt16 nFirstUsedXclCol, sal_uInt32 nFirstUsedXclRow,
+ sal_uInt16 nFirstFreeXclCol, sal_uInt32 nFirstFreeXclRow );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the contents of the DIMENSIONS record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt32 mnFirstUsedXclRow; /// First used row.
+ sal_uInt32 mnFirstFreeXclRow; /// First unused row after used area.
+ sal_uInt16 mnFirstUsedXclCol; /// First used column.
+ sal_uInt16 mnFirstFreeXclCol; /// First free column after used area.
+};
+
+// ============================================================================
+
+/** Represents the DEFCOLWIDTH record containing the default column width of a sheet.
+
+ Excel stores the default column width in entire character widths of the '0'
+ character using the application default font (i.e. the default width is 10,
+ if the '0' character fits 10 times into a cell in a column with default
+ width.
+
+ The IsDefWidth() function returns true, if the passed width (measured in
+ 1/256 of the width of the '0' character) could be converted exactly to the
+ default width. If the passed width is rounded up or down to get the default
+ width, the function returns false.
+ */
+class XclExpDefcolwidth : public XclExpUInt16Record, protected XclExpRoot
+{
+public:
+ explicit XclExpDefcolwidth( const XclExpRoot& rRoot );
+
+ /** Returns true, if the own default width exactly matches the passed width. */
+ bool IsDefWidth( sal_uInt16 nXclColWidth ) const;
+
+ /** Sets the passed column width (in 1/256 character width) as default width. */
+ void SetDefWidth( sal_uInt16 nXclColWidth );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains the column settings for a range of columns.
+
+ After construction the record contains a temporary XF identifier returned
+ from the XF buffer. After creating the entire Excel document in memory, the
+ ConvertXFIndexes() function converts it into the real Excel XF index.
+ */
+class XclExpColinfo : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Constructs the record with the settings in the Calc document. */
+ explicit XclExpColinfo( const XclExpRoot& rRoot,
+ SCCOL nScCol, SCROW nLastScRow,
+ XclExpColOutlineBuffer& rOutlineBfr );
+
+ /** Converts the XF identifier into the Excel XF index, returns the latter. */
+ sal_uInt16 ConvertXFIndexes();
+
+ /** Tries to merge this record with the passed record.
+ @descr Possible, if passed record directly follows this record and has equal contents.
+ @return true = This record is equal to passed record and has been updated. */
+ bool TryMerge( const XclExpColinfo& rColInfo );
+
+ /** Returns the Excel width of the column(s). */
+ inline sal_uInt16 GetColWidth() const { return mnWidth; }
+ /** Returns the final Excel XF index of the column(s). */
+ inline sal_uInt16 GetXFIndex() const { return maXFId.mnXFIndex; }
+ /** Returns the number of columns represented by this record. */
+ inline sal_uInt16 GetColCount() const { return mnLastXclCol - mnFirstXclCol + 1; }
+
+ /** Returns true, if the column has default format and width. */
+ bool IsDefault( const XclExpDefcolwidth& rDefColWidth ) const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of this COLINFO record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpXFId maXFId; /// The XF identifier for column default format.
+ sal_uInt16 mnWidth; /// Excel width of the column.
+ sal_uInt16 mnFlags; /// Additional column flags.
+ sal_uInt16 mnFirstXclCol; /// Index to first column.
+ sal_uInt16 mnLastXclCol; /// Index to last column.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains COLINFO records for all columns of a Calc sheet.
+
+ On construction one COLINFO record per column is created. After creating
+ the entire Excel document in memory, the ConvertXFIndexes() function converts
+ all temporary XF identifiers into real Excel XF indexes and merges all equal
+ COLINFO records together.
+ */
+class XclExpColinfoBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpColinfoBuffer( const XclExpRoot& rRoot );
+
+ /** Initializes the buffer: finds settings and formatting of all columns.
+ @param nLastScRow Last row used to find default formatting. */
+ void Initialize( SCROW nLastScRow );
+ /** Converts the XF identifiers into the Excel XF indexes and merges equal columns.
+ @param rXFIndexes Returns the final XF indexes of all columns. */
+ void Finalize( ScfUInt16Vec& rXFIndexes );
+
+ /** Writes all COLINFO records of this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpColinfo > XclExpColinfoList;
+ typedef XclExpColinfoList::RecordRefType XclExpColinfoRef;
+
+ XclExpColinfoList maColInfos; /// List of COLINFO records.
+ XclExpDefcolwidth maDefcolwidth; /// The DEFCOLWIDTH record.
+ XclExpColOutlineBuffer maOutlineBfr; /// Buffer for column outline groups.
+};
+
+// ============================================================================
+
+class XclExpRow;
+
+/** Contains all possible default row settings. */
+struct XclExpDefaultRowData
+{
+ sal_uInt16 mnFlags; /// Default flags for unspecified rows.
+ sal_uInt16 mnHeight; /// Default height for unspecified rows.
+
+ explicit XclExpDefaultRowData();
+ explicit XclExpDefaultRowData( const XclExpRow& rRow );
+
+ /** Returns true, if rows are hidden by default. */
+ inline bool IsHidden() const { return ::get_flag( mnFlags, EXC_DEFROW_HIDDEN ); }
+ /** Returns true, if the rows have a manually set height by default. */
+ inline bool IsUnsynced() const { return ::get_flag( mnFlags, EXC_DEFROW_UNSYNCED ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a DEFROWHEIGHT record containing default format for unused rows. */
+class XclExpDefrowheight : public XclExpRecord
+{
+public:
+ explicit XclExpDefrowheight();
+
+ /** Sets the passed default data as current record contents. */
+ void SetDefaultData( const XclExpDefaultRowData& rDefData );
+
+private:
+ /** Writes the contents of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpDefaultRowData maDefData; /// Record data.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a ROW record and additionally contains all cells records of a row.
+
+ This class contains all cell records of a row in a spreadsheet. There are 2
+ cell records in Excel that support storing a range of cells in one record
+ (MULBLANK for multiple blank cells, and MULRK for multiple RK values). The
+ insertion functions try to merge a new inserted cell with existing
+ neighbors, if this is supported by the current type of cell record.
+
+ The Finalize() function converts the XF identifiers of all cell records to
+ the final Excel XF indexes. Then a default
+ */
+class XclExpRow : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Constructs the ROW record and converts the Calc row settings.
+ @param bAlwaysEmpty true = This row will not be filled with blank cells
+ in the Finalize() function. */
+ explicit XclExpRow( const XclExpRoot& rRoot, sal_uInt16 nXclRow,
+ XclExpRowOutlineBuffer& rOutlineBfr, bool bAlwaysEmpty );
+
+ /** Returns the excel row index of this ROW record. */
+ inline sal_uInt16 GetXclRow() const { return mnXclRow; }
+ /** Returns the height of the row in twips. */
+ inline sal_uInt16 GetHeight() const { return mnHeight; }
+ /** Returns true, if this row does not contain at least one valid cell. */
+ inline bool IsEmpty() const { return maCellList.IsEmpty(); }
+ /** Returns true, if this row is hidden. */
+ inline bool IsHidden() const { return ::get_flag( mnFlags, EXC_ROW_HIDDEN ); }
+ /** Returns true, if this row contains a manually set height. */
+ inline bool IsUnsynced() const { return ::get_flag( mnFlags, EXC_ROW_UNSYNCED ); }
+ /** Returns true, if this row is enabled (will be exported). */
+ inline bool IsEnabled() const { return mbEnabled; }
+
+ /** Appends the passed cell object to this row. */
+ void AppendCell( XclExpCellRef xCell, bool bIsMergedBase );
+
+ /** Converts all XF identifiers into the Excel XF indexes. */
+ void Finalize( const ScfUInt16Vec& rColXFIndexes );
+
+ /** Returns the column index of the first used cell in this row.
+ @descr This function can only be called after Finalize(). */
+ sal_uInt16 GetFirstUsedXclCol() const;
+ /** Returns the column index of the first unused cell following all used cells in this row.
+ @descr This function can only be called after Finalize(). */
+ sal_uInt16 GetFirstFreeXclCol() const;
+
+ /** Returns true, if this row may be omitted by using the DEFROWHEIGHT record.
+ @descr A row may be omitted, if it does not contain any cell or
+ explicit default cell formatting, and is not part of an outline.
+ This function can only be called after Finalize(). */
+ bool IsDefaultable() const;
+ /** Disables this row, if it is defaultable and has the passed default format.
+ @descr Disabled rows will not be saved.
+ This function can only be called after Finalize(). */
+ void DisableIfDefault( const XclExpDefaultRowData& rDefRowData );
+
+ /** Writes all cell records of this row. */
+ void WriteCellList( XclExpStream& rStrm );
+
+ /** Writes the ROW record if the row is not disabled (see DisableIfDefault() function). */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Initializes the record data. Called from constructors. */
+ void Init( sal_uInt16 nXclRow, XclExpRowOutlineBuffer* pOutlineBfr );
+ /** Inserts a cell at the specified list position, tries to merge with neighbors. */
+ void InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase );
+
+ /** Writes the contents of the ROW record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpCellBase > XclExpCellList;
+
+ XclExpCellList maCellList; /// List of cell records for this row.
+ sal_uInt16 mnXclRow; /// Excel row index of this row.
+ sal_uInt16 mnHeight; /// Row height in twips.
+ sal_uInt16 mnFlags; /// Flags for the ROW record.
+ sal_uInt16 mnXFIndex; /// Default row formatting.
+ sal_uInt16 mnOutlineLevel; /// Outline Level (for OOXML)
+ bool mbAlwaysEmpty; /// true = Do not add blank cells in Finalize().
+ bool mbEnabled; /// true = Write this ROW record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Collects all rows which contain all cells of a sheet.
+
+ This row buffer automatically creates ROW records when cells are inserted
+ with the AppendCell() function. It is possible to force creation of more
+ ROW records with the CreateRows() function. In both cases, all preceding
+ missing ROW records are inserted too.
+ */
+class XclExpRowBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpRowBuffer( const XclExpRoot& rRoot );
+
+ /** Appends the passed cell object to the row that the cell specifies. */
+ void AppendCell( XclExpCellRef xCell, bool bIsMergedBase );
+ /** Forces insertion of all ROW records before the passed row. */
+ void CreateRows( SCROW nFirstFreeScRow );
+
+ /** Converts all XF identifiers into the Excel XF indexes and calculates default formats.
+ @param rDefRowData (out-param) The default row format is returned here.
+ @param rColXFIndexes The column default XF indexes. */
+ void Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes );
+
+ /** Writes the DIMENSIONS record, all ROW records and all cell records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ XclExpDimensions* GetDimensions();
+
+private:
+ /** Returns access to the specified ROW record. Inserts preceding missing ROW records.
+ @param bRowAlwaysEmpty true = Created rows will not be filled with blank cells
+ in the XclExpRow::Finalize() function. */
+ XclExpRow& GetOrCreateRow( sal_uInt16 nXclRow, bool bRowAlwaysEmpty );
+
+private:
+ typedef XclExpRecordList< XclExpRow > XclExpRowList;
+ typedef XclExpRowList::RecordRefType XclExpRowRef;
+
+ XclExpRowList maRowList; /// List of all ROW records.
+ XclExpRowOutlineBuffer maOutlineBfr; /// Buffer for row outline groups.
+ XclExpDimensions maDimensions; /// DIMENSIONS record for used area.
+ XclExpRow* mpLastUsedRow; /// Last used row for faster access.
+ sal_uInt16 mnLastUsedXclRow; /// Last used row for faster access.
+};
+
+// ============================================================================
+// Cell Table
+// ============================================================================
+
+class XclExpNote;
+class XclExpMergedcells;
+class XclExpHyperlink;
+class XclExpDval;
+
+/** This class contains the cell contents and more of an entire sheet.
+
+ The cell table includes the settings and default formatting of all columns,
+ the settings and default formatting of all used rows, and the contents of
+ all cells of one sheet in a spreadsheet document.
+
+ The constructor does all the work creating the cell table. It reads the
+ Calc sheet and converts all columns, rows, and cells to Excel record data.
+ Additioanlly, hyperlink records, note records, additional records for
+ formula cells, data validation records, and outline records are created.
+
+ The Finalize() function does even more work. It calculates default column
+ settings and removes column records that are equal to this default. The
+ same happens with rows: A default format is calculated for each row, and
+ all blank cells in this row that have the same format are removed. Then,
+ the most used row settings are calculated, and all empty rows that have the
+ same settings are removed too.
+
+ Records that are not stored inside the cell table area in an Excel file
+ (i.e. DEFROWHEIGHT record, NOTE records, MERGEDCELLS record, HLINK records,
+ DVAL and DV records for data validation) can be accessed with the function
+ CreateRecord(). It returns the reference to the respective record (or
+ record list) which can be inserted into a record list.
+ */
+class XclExpCellTable : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpCellTable( const XclExpRoot& rRoot );
+
+ /** Converts all XF identifiers into the Excel XF indexes and calculates default formats. */
+ void Finalize();
+
+ /** Returns the reference to an internal record specified by the passed record id.
+ @param nRecId The record identifier that specifies which record is
+ returned. Possible values are: EXC_ID_DEFROWHEIGHT, EXC_ID_NOTE,
+ EXC_ID_MERGEDCELLS, EXC_ID_HLINK, EXC_ID_DVAL. */
+ XclExpRecordRef CreateRecord( sal_uInt16 nRecId ) const;
+ /** Saves the entire cell table. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpNote > XclExpNoteList;
+ typedef XclExpRecordList< XclExpHyperlink > XclExpHyperlinkList;
+
+ typedef ScfRef< XclExpDefrowheight > XclExpDefrowhRef;
+ typedef ScfRef< XclExpNoteList > XclExpNoteListRef;
+ typedef ScfRef< XclExpMergedcells > XclExpMergedcellsRef;
+ typedef ScfRef< XclExpHyperlinkList > XclExpHyperlinkRef;
+ typedef ScfRef< XclExpDval > XclExpDvalRef;
+
+ XclExpColinfoBuffer maColInfoBfr; /// Buffer for column formatting.
+ XclExpRowBuffer maRowBfr; /// Rows and cell records.
+ XclExpArrayBuffer maArrayBfr; /// Buffer for ARRAY records.
+ XclExpShrfmlaBuffer maShrfmlaBfr; /// Buffer for SHRFMLA records.
+ XclExpTableopBuffer maTableopBfr; /// Buffer for TABLEOP records.
+ XclExpDefrowhRef mxDefrowheight; /// DEFROWHEIGHT record for default row format.
+ XclExpRecordRef mxGuts; /// GUTS record for outline areas.
+ XclExpNoteListRef mxNoteList; /// List of NOTE records.
+ XclExpMergedcellsRef mxMergedcells; /// MERGEDCELLS record for merged cell ranges.
+ XclExpHyperlinkRef mxHyperlinkList; /// List of HLINK records.
+ XclExpDvalRef mxDval; /// Data validation with DVAL and DV records.
+};
+
+#endif
+
diff --git a/sc/source/filter/inc/xeview.hxx b/sc/source/filter/inc/xeview.hxx
new file mode 100644
index 000000000000..61e349ab1e86
--- /dev/null
+++ b/sc/source/filter/inc/xeview.hxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEVIEW_HXX
+#define SC_XEVIEW_HXX
+
+#include "xerecord.hxx"
+#include "xlview.hxx"
+#include "xeroot.hxx"
+
+// Workbook view settings records =============================================
+
+/** Represents the WINDOW1 record containing global workbook view settings. */
+class XclExpWindow1 : public XclExpRecord
+{
+public:
+ explicit XclExpWindow1( const XclExpRoot& rRoot );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the WINDOW1 record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnFlags; /// Option flags.
+ sal_uInt16 mnTabBarSize; /// Size of tabbar relative to window width (per mill).
+};
+
+// Sheet view settings records ================================================
+
+/** Represents a WINDOW2 record with general view settings for a sheet. */
+class XclExpWindow2 : public XclExpRecord
+{
+public:
+ explicit XclExpWindow2( const XclExpRoot& rRoot,
+ const XclTabViewData& rData, sal_uInt32 nGridColorId );
+
+private:
+ /** Writes the contents of the WINDOW2 record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ Color maGridColor; /// Grid color (<=BIFF5).
+ sal_uInt32 mnGridColorId; /// Color ID of grid color (>=BIFF8).
+ sal_uInt16 mnFlags; /// Option flags.
+ XclAddress maFirstXclPos; /// First visible cell.
+ sal_uInt16 mnNormalZoom; /// Zoom factor for normal view.
+ sal_uInt16 mnPageZoom; /// Zoom factor for pagebreak preview.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an SCL record for the zoom factor of the current view of a sheet. */
+class XclExpScl : public XclExpRecord
+{
+public:
+ explicit XclExpScl( sal_uInt16 nZoom );
+
+private:
+ /** Tries to shorten numerator and denominator by the passed value. */
+ void Shorten( sal_uInt16 nFactor );
+ /** Writes the contents of the SCL record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnNum; /// Numerator of the zoom factor.
+ sal_uInt16 mnDenom; /// Denominator of the zoom factor.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a PANE record containing settings for split/frozen windows. */
+class XclExpPane : public XclExpRecord
+{
+public:
+ explicit XclExpPane( const XclTabViewData& rData );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the PANE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnSplitX; /// Split X position, or frozen column.
+ sal_uInt16 mnSplitY; /// Split Y position, or frozen row.
+ XclAddress maSecondXclPos; /// First visible cell in additional panes.
+ sal_uInt8 mnActivePane; /// Active pane (with cell cursor).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a SELECTION record with selection data for a pane. */
+class XclExpSelection : public XclExpRecord
+{
+public:
+ explicit XclExpSelection( const XclTabViewData& rData, sal_uInt8 nPane );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the contents of the SELECTION record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclSelectionData maSelData; /// Selection data.
+ sal_uInt8 mnPane; /// Pane identifier of this selection.
+};
+
+class XclExpTabBgColor : public XclExpRecord
+{
+public:
+ explicit XclExpTabBgColor( const XclTabViewData& rTabViewData );
+
+ /* virtual void SaveXml( XclExpXmlStream& rStrm ); TODO Fix XML Saving Stream */
+private:
+ /** Writes the contents of the SHEETEXT record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclTabViewData& mrTabViewData; /// view settings data of current sheet.
+};
+
+// View settings ==============================================================
+
+/** Contains all view settings records for a single sheet. */
+class XclExpTabViewSettings : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Creates all records containing the view settings of the specified sheet. */
+ explicit XclExpTabViewSettings( const XclExpRoot& rRoot, SCTAB nScTab );
+
+ /** Writes all view settings records to the stream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Creates selection data for the specified pane. */
+ void CreateSelectionData( sal_uInt8 nPane,
+ const ScAddress& rCursor, const ScRangeList& rSelection );
+
+ void WriteWindow2( XclExpStream& rStrm ) const;
+ void WriteScl( XclExpStream& rStrm ) const;
+ void WritePane( XclExpStream& rStrm ) const;
+ void WriteSelection( XclExpStream& rStrm, sal_uInt8 nPane ) const;
+ void WriteTabBgColor( XclExpStream& rStrm ) const;
+
+private:
+ XclTabViewData maData; /// All view settings for a sheet.
+ sal_uInt32 mnGridColorId; /// Color identifier for grid color.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx
new file mode 100644
index 000000000000..d8289b3b671b
--- /dev/null
+++ b/sc/source/filter/inc/xichart.hxx
@@ -0,0 +1,1514 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XICHART_HXX
+#define SC_XICHART_HXX
+
+#include <vector>
+#include <map>
+#include <set>
+#include <list>
+
+#include <svl/itemset.hxx>
+
+#include "rangelst.hxx"
+#include "token.hxx"
+#include "xlchart.hxx"
+#include "xlstyle.hxx"
+#include "xiescher.hxx"
+#include "xistring.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt
+ {
+ struct Rectangle;
+ }
+ namespace frame
+ {
+ class XModel;
+ }
+ namespace drawing
+ {
+ class XShape;
+ }
+ namespace chart2
+ {
+ struct ScaleData;
+ class XChartDocument;
+ class XDiagram;
+ class XCoordinateSystem;
+ class XChartType;
+ class XDataSeries;
+ class XRegressionCurve;
+ class XAxis;
+ class XLegend;
+ class XTitle;
+ class XFormattedString;
+ namespace data
+ {
+ class XDataProvider;
+ class XDataSequence;
+ class XLabeledDataSequence;
+ }
+ }
+} } }
+
+struct XclObjLineData;
+struct XclObjFillData;
+
+// Common =====================================================================
+
+class ScfProgressBar;
+struct XclImpChRootData;
+class XclImpChChart;
+class ScTokenArray;
+
+/** Base class for complex chart classes, provides access to other components of the chart. */
+class XclImpChRoot : public XclImpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+
+public:
+ explicit XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData );
+ virtual ~XclImpChRoot();
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclImpChRoot& GetChRoot() const { return *this; }
+ /** Returns a reference to the parent chart data object. */
+ XclImpChChart& GetChartData() const;
+ /** Returns chart type info for a unique chart type identifier. */
+ const XclChTypeInfo& GetChartTypeInfo( XclChTypeId eType ) const;
+ /** Returns the first fitting chart type info for an Excel chart type record identifier. */
+ const XclChTypeInfo& GetChartTypeInfo( sal_uInt16 nRecId ) const;
+ /** Returns an info struct about auto formatting for the passed object type. */
+ const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
+
+ /** Returns the default text color for charts. */
+ Color GetFontAutoColor() const;
+ /** Returns the automatic line color of linear series. */
+ Color GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const;
+ /** Returns the automatic fill color of filled series. */
+ Color GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const;
+
+ /** Starts the API chart document conversion. Must be called once before all API conversion. */
+ void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const;
+ /** Finishes the API chart document conversion. Must be called once after all API conversion. */
+ void FinishConversion( XclImpDffConverter& rDffConv ) const;
+
+ /** Returns the data provider for the chart document. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >
+ GetDataProvider() const;
+ /** Returns the drawing shape interface of the specified title object. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ GetTitleShape( const XclChTextKey& rTitleKey ) const;
+
+ /** Converts the passed horizontal coordinate from Excel chart units into 1/100 mm. */
+ sal_Int32 CalcHmmFromChartX( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from Excel chart units into 1/100 mm. */
+ sal_Int32 CalcHmmFromChartY( sal_Int32 nPosY ) const;
+ /** Converts the passed rectangle from Excel chart units into 1/100 mm. */
+ ::com::sun::star::awt::Rectangle CalcHmmFromChartRect( const XclChRectangle& rRect ) const;
+
+ /** Converts the passed horizontal coordinate from Excel chart units into a relative position. */
+ double CalcRelativeFromChartX( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from Excel chart units into a relative position. */
+ double CalcRelativeFromChartY( sal_Int32 nPosY ) const;
+
+ /** Writes all line properties to the passed property set. */
+ void ConvertLineFormat(
+ ScfPropertySet& rPropSet,
+ const XclChLineFormat& rLineFmt,
+ XclChPropertyMode ePropMode ) const;
+ /** Writes solid area properties to the passed property set. */
+ void ConvertAreaFormat(
+ ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt,
+ XclChPropertyMode ePropMode ) const;
+ /** Writes gradient or bitmap area properties to the passed property set. */
+ void ConvertEscherFormat(
+ ScfPropertySet& rPropSet,
+ const XclChEscherFormat& rEscherFmt,
+ const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode ) const;
+ /** Writes font properties to the passed property set. */
+ void ConvertFont(
+ ScfPropertySet& rPropSet,
+ sal_uInt16 nFontIdx,
+ const Color* pFontColor = 0 ) const;
+
+ /** Writes the pie rotation property for the passed angle. */
+ static void ConvertPieRotation(
+ ScfPropertySet& rPropSet,
+ sal_uInt16 nAngle );
+
+private:
+ typedef ScfRef< XclImpChRootData > XclImpChRootDataRef;
+ XclImpChRootDataRef mxChData; /// Reference to the root data object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for chart record groups. Provides helper functions to read sub records.
+
+ A chart record group consists of a header record, followed by a CHBEGIN
+ record, followed by group sub records, and finished with a CHEND record.
+ */
+class XclImpChGroupBase
+{
+public:
+ virtual ~XclImpChGroupBase();
+
+ /** Reads the entire record group.
+ @descr First calls ReadHeaderRecord() to read the contents of the
+ header record. Then tries to read the sub records. If next record
+ is a CHBEGIN record, ReadSubRecord() is called for each following
+ record until a CHEND record is found. */
+ void ReadRecordGroup( XclImpStream& rStrm );
+
+ /** Helper to skip a CHBEGIN/CHEND block, includes nested blocks. */
+ static void SkipBlock( XclImpStream& rStrm );
+
+ /** Derived classes implement to read the group header record. */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm ) = 0;
+ /** Derived classes implement to read a record from the group. */
+ virtual void ReadSubRecord( XclImpStream& rStrm ) = 0;
+};
+
+// Frame formatting ===========================================================
+
+class XclImpChFramePos
+{
+public:
+ /** Reads the CHFRAMEPOS record (frame position and size). */
+ void ReadChFramePos( XclImpStream& rStrm );
+
+ /** Returns read-only access to the imported frame position data. */
+ inline const XclChFramePos& GetFramePosData() const { return maData; }
+
+private:
+ XclChFramePos maData; /// Position of the frame.
+};
+
+typedef ScfRef< XclImpChFramePos > XclImpChFramePosRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHLINEFORMAT record containing line formatting data. */
+class XclImpChLineFormat
+{
+public:
+ /** Creates a new line format object with automatic formatting. */
+ inline explicit XclImpChLineFormat() {}
+ /** Creates a new line format object with the passed formatting. */
+ inline explicit XclImpChLineFormat( const XclChLineFormat& rLineFmt ) : maData( rLineFmt ) {}
+
+ /** Reads the CHLINEFORMAT record (basic line properties). */
+ void ReadChLineFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the line format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO ); }
+ /** Returns true, if the line style is set to something visible. */
+ inline bool HasLine() const { return IsAuto() || (maData.mnPattern != EXC_CHLINEFORMAT_NONE); }
+ /** Returns the line width of this line format (returns 'single', if the line is invisible). */
+ inline sal_Int16 GetWeight() const { return (IsAuto() || !HasLine()) ? EXC_CHLINEFORMAT_SINGLE : maData.mnWeight; }
+ /** Returns true, if the "show axis" flag is set. */
+ inline bool IsShowAxis() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS ); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+
+private:
+ XclChLineFormat maData; /// Contents of the CHLINEFORMAT record.
+};
+
+typedef ScfRef< XclImpChLineFormat > XclImpChLineFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHAREAFORMAT record containing simple area formatting data (solid or patterns). */
+class XclImpChAreaFormat
+{
+public:
+ /** Creates a new area format object with automatic formatting. */
+ inline explicit XclImpChAreaFormat() {}
+ /** Creates a new area format object with the passed formatting. */
+ inline explicit XclImpChAreaFormat( const XclChAreaFormat& rAreaFmt ) : maData( rAreaFmt ) {}
+
+ /** Reads the CHAREAFORMAT record (basic fill properties, e.g. transparent or colored). */
+ void ReadChAreaFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the area format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO ); }
+ /** Returns true, if the area style is set to something visible. */
+ inline bool HasArea() const { return IsAuto() || (maData.mnPattern != EXC_PATT_NONE); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+
+private:
+ XclChAreaFormat maData; /// Contents of the CHAREAFORMAT record.
+};
+
+typedef ScfRef< XclImpChAreaFormat > XclImpChAreaFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHESCHERFORMAT record containing complex area formatting data (bitmaps, hatches). */
+class XclImpChEscherFormat : public XclImpChGroupBase
+{
+public:
+ explicit XclImpChEscherFormat( const XclImpRoot& rRoot );
+
+ /** Reads the CHESCHERFORMAT record (complex fill data) (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHESCHERFORMAT group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType ) const;
+
+private:
+ XclChEscherFormat maData; /// Fill properties for complex areas (CHESCHERFORMAT record).
+ XclChPicFormat maPicFmt; /// Image options, e.g. stretched, stacked (CHPICFORMAT record).
+};
+
+typedef ScfRef< XclImpChEscherFormat > XclImpChEscherFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Base class for record groups containing frame formatting.
+
+ Frame formatting can be part of several record groups, e.g. CHFRAME,
+ CHDATAFORMAT, CHDROPBAR. It consists of CHLINEFORMAT, CHAREAFORMAT, and
+ CHESCHERFORMAT group.
+ */
+class XclImpChFrameBase : public XclImpChGroupBase
+{
+public:
+ /** Creates a new frame object without internal formatting objects. */
+ inline explicit XclImpChFrameBase() {}
+ /** Creates a new frame object with specific default formatting. */
+ explicit XclImpChFrameBase( const XclChFormatInfo& rFmtInfo );
+
+ /** Reads a frame formatting record (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Returns true, if the line format is set to automatic. */
+ inline bool IsAutoLine() const { return !mxLineFmt || mxLineFmt->IsAuto(); }
+ /** Returns true, if the line style is set to something visible. */
+ inline bool HasLine() const { return IsAutoLine() || mxLineFmt->HasLine(); }
+ /** Returns the line weight used for this frame. */
+ inline sal_Int16 GetLineWeight() const { return mxLineFmt.is() ? mxLineFmt->GetWeight() : EXC_CHLINEFORMAT_SINGLE; }
+
+ /** Returns true, if the area format is set to automatic. */
+ inline bool IsAutoArea() const { return !mxEscherFmt && (!mxAreaFmt || mxAreaFmt->IsAuto()); }
+ /** Returns true, if the area style is set to something visible. */
+ inline bool HasArea() const { return mxEscherFmt.is() || IsAutoArea() || mxAreaFmt->HasArea(); }
+
+protected:
+ /** Converts and writes the contained line formatting to the passed property set. */
+ void ConvertLineBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+ /** Converts and writes the contained area formatting to the passed property set. */
+ void ConvertAreaBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+ /** Converts and writes the contained data to the passed property set. */
+ void ConvertFrameBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+
+protected:
+ XclImpChLineFormatRef mxLineFmt; /// Line format (CHLINEFORMAT record).
+ XclImpChAreaFormatRef mxAreaFmt; /// Area format (CHAREAFORMAT record).
+ XclImpChEscherFormatRef mxEscherFmt; /// Complex area format (CHESCHERFORMAT record).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHFRAME record group containing object frame properties.
+
+ The CHFRAME group consists of: CHFRAME, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclImpChFrame : public XclImpChFrameBase, protected XclImpChRoot
+{
+public:
+ /** Creates a new frame object with specific default formatting. */
+ explicit XclImpChFrame(
+ const XclImpChRoot& rRoot,
+ XclChObjectType eObjType );
+
+ /** Reads the CHFRAME record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+
+ /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
+ void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclChFrame maData; /// Contents of the CHFRAME record.
+ XclChObjectType meObjType; /// Type of the represented object.
+};
+
+typedef ScfRef< XclImpChFrame > XclImpChFrameRef;
+
+// Source links ===============================================================
+
+class XclImpChSourceLink : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > XDataSequenceRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString > XFormattedStringRef;
+ typedef ::com::sun::star::uno::Sequence< XFormattedStringRef > XFormattedStringSeq;
+
+public:
+ explicit XclImpChSourceLink( const XclImpChRoot& rRoot );
+ virtual ~XclImpChSourceLink();
+
+ /** Reads the CHSOURCELINK record (link to source data). */
+ void ReadChSourceLink( XclImpStream& rStrm );
+ /** Sets explicit string data for this text object. */
+ void SetString( const String& rString );
+ /** Sets formatting runs read from a CHFORMATRUNS record. */
+ void SetTextFormats( const XclFormatRunVec& rFormats );
+
+ /** Returns the destination object (title, values, category, ...). */
+ inline sal_uInt8 GetDestType() const { return maData.mnDestType; }
+ /** Returns the link type (to worksheet, directly, default, ...). */
+ inline sal_uInt8 GetLinkType() const { return maData.mnLinkType; }
+
+ /** Returns true, if the source link contains explicit string data. */
+ inline bool HasString() const { return mxString.is() && !mxString->IsEmpty(); }
+ /** Returns explicit string data or an empty string. */
+ inline const String& GetString() const { return mxString.is() ? mxString->GetText() : String::EmptyString(); }
+ /** Returns the number of data points of this source link. */
+ sal_uInt16 GetCellCount() const;
+
+ /** Converts and writes the contained number format to the passed property set. */
+ void ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const;
+
+ /** Creates a data sequence containing the link into the Calc document. */
+ XDataSequenceRef CreateDataSequence( const ::rtl::OUString& rRole ) const;
+ /** Creates a sequence of formatted string objects. */
+ XFormattedStringSeq CreateStringSequence( const XclImpChRoot& rRoot,
+ sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const;
+
+ void FillSourceLink(::std::vector<ScSharedTokenRef>& rTokens) const;
+
+private:
+ XclChSourceLink maData; /// Contents of the CHSOURCELINK record.
+ XclImpStringRef mxString; /// Text data (CHSTRING record).
+ ScfRef< ScTokenArray> mxTokenArray; /// Token array representing the data ranges.
+};
+
+typedef ScfRef< XclImpChSourceLink > XclImpChSourceLinkRef;
+
+// Text =======================================================================
+
+/** Base class for objects with font settings. Provides font conversion helper functions. */
+class XclImpChFontBase
+{
+public:
+ virtual ~XclImpChFontBase();
+
+ /** Derived classes return the leading font index for the text object. */
+ virtual sal_uInt16 GetFontIndex() const = 0;
+ /** Derived classes return the leading font color for the text object. */
+ virtual Color GetFontColor() const = 0;
+ /** Derived classes return the rotation value for the text object. */
+ virtual sal_uInt16 GetRotation() const = 0;
+
+ /** Converts and writes the contained font settings to the passed property set. */
+ void ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const;
+ /** Converts and writes the contained rotation settings to the passed property set. */
+ void ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** The CHFONT record containing a font index for text objects. */
+class XclImpChFont
+{
+public:
+ explicit XclImpChFont();
+ /** Reads the CHFONT record (font index). */
+ void ReadChFont( XclImpStream& rStrm );
+
+ /** Returns the contained font index. */
+ inline sal_uInt16 GetFontIndex() const { return mnFontIdx; }
+
+private:
+ sal_uInt16 mnFontIdx; /// Index into font buffer.
+};
+
+typedef ScfRef< XclImpChFont > XclImpChFontRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTEXT record group containing text object properties.
+
+ The CHTEXT group consists of: CHTEXT, CHBEGIN, CHFRAMEPOS, CHFONT,
+ CHFORMATRUNS, CHSOURCELINK, CHSTRING, CHFRAME group, CHOBJECTLINK, and CHEND.
+ */
+class XclImpChText : public XclImpChGroupBase, public XclImpChFontBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle > XTitleRef;
+
+public:
+ explicit XclImpChText( const XclImpChRoot& rRoot );
+
+ /** Reads the CHTEXT record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHTEXT group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Returns the leading font index for the text object. */
+ virtual sal_uInt16 GetFontIndex() const;
+ /** Returns the leading font color for the text object. */
+ virtual Color GetFontColor() const;
+ /** Returns the rotation value for the text object. */
+ virtual sal_uInt16 GetRotation() const;
+
+ /** Sets explicit string data for this text object. */
+ void SetString( const String& rString );
+ /** Updates missing parts of this text object from the passed object. */
+ void UpdateText( const XclImpChText* pParentText );
+ /** Updates display type of this data point label text object. */
+ void UpdateDataLabel( bool bCateg, bool bValue, bool bPercent );
+
+ /** Returns the target object this text is linked to. */
+ inline sal_uInt16 GetLinkTarget() const { return maObjLink.mnTarget; }
+ /** Returns the position of the data point label this text is linked to. */
+ inline const XclChDataPointPos& GetPointPos() const { return maObjLink.maPointPos; }
+ /** Returns true, if this text group contains string data. */
+ inline bool HasString() const { return mxSrcLink.is() && mxSrcLink->HasString(); }
+ /** Returns true, if the text object is marked as deleted. */
+ inline bool IsDeleted() const { return ::get_flag( maData.mnFlags, EXC_CHTEXT_DELETED ); }
+
+ /** Converts and writes the contained font settings to the passed property set. */
+ void ConvertFont( ScfPropertySet& rPropSet ) const;
+ /** Converts and writes the contained rotation settings to the passed property set. */
+ void ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const;
+ /** Converts and writes the contained frame data to the passed property set. */
+ void ConvertFrame( ScfPropertySet& rPropSet ) const;
+ /** Converts and writes the contained number format to the passed property set. */
+ void ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const;
+ /** Converts and writes all contained data to the passed data point label property set. */
+ void ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const;
+ /** Creates a title text object. */
+ XTitleRef CreateTitle() const;
+ /** Converts the manual position of the specified title */
+ void ConvertTitlePosition( const XclChTextKey& rTitleKey ) const;
+
+private:
+ using XclImpChRoot::ConvertFont;
+
+ /** Reads a CHFRLABELPROPS record. */
+ void ReadChFrLabelProps( XclImpStream& rStrm );
+
+private:
+ typedef ScfRef< XclChFrLabelProps > XclChFrLabelPropsRef;
+
+ XclChText maData; /// Contents of the CHTEXT record.
+ XclChObjectLink maObjLink; /// Link target for this text object.
+ XclFormatRunVec maFormats; /// Formatting runs (CHFORMATRUNS record).
+ XclImpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record).
+ XclImpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record).
+ XclImpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group).
+ XclImpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclChFrLabelPropsRef mxLabelProps; /// Extended data label properties (CHFRLABELPROPS record).
+};
+
+typedef ScfRef< XclImpChText > XclImpChTextRef;
+
+// Data series ================================================================
+
+/** The CHMARKERFORMAT record containing data point marker formatting data. */
+class XclImpChMarkerFormat
+{
+public:
+ /** Reads the CHMARKERFORMAT record (data point marker properties). */
+ void ReadChMarkerFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the marker format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO ); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet,
+ sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const;
+ /** Sets the marker fill color as main color to the passed property set. */
+ void ConvertColor( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const;
+
+private:
+ XclChMarkerFormat maData; /// Contents of the CHMARKERFORMAT record.
+};
+
+typedef ScfRef< XclImpChMarkerFormat > XclImpChMarkerFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHPIEFORMAT record containing data point formatting data for pie segments. */
+class XclImpChPieFormat
+{
+public:
+ explicit XclImpChPieFormat();
+ /** Reads the CHPIEFORMAT record (pie segment properties). */
+ void ReadChPieFormat( XclImpStream& rStrm );
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ sal_uInt16 mnPieDist; /// Pie distance to diagram center.
+};
+
+typedef ScfRef< XclImpChPieFormat > XclImpChPieFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHSERIESFORMAT record containing additional settings for a data series. */
+class XclImpChSeriesFormat
+{
+public:
+ explicit XclImpChSeriesFormat();
+ /** Reads the CHSERIESFORMAT record (additional settings for a series). */
+ void ReadChSeriesFormat( XclImpStream& rStrm );
+ /** Returns true, if the series line is smoothed. */
+ inline bool HasSpline() const { return ::get_flag( mnFlags, EXC_CHSERIESFORMAT_SMOOTHED ); }
+
+private:
+ sal_uInt16 mnFlags; /// Additional flags.
+};
+
+typedef ScfRef< XclImpChSeriesFormat > XclImpChSeriesFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CH3DDATAFORMAT record containing the bar type in 3D bar charts. */
+class XclImpCh3dDataFormat
+{
+public:
+ /** Reads the CH3DDATAFORMAT record (3D bar properties). */
+ void ReadCh3dDataFormat( XclImpStream& rStrm );
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclCh3dDataFormat maData; /// Contents of the CH3DDATAFORMAT record.
+};
+
+typedef ScfRef< XclImpCh3dDataFormat > XclImpCh3dDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHATTACHEDLABEL record that contains the type of a data point label. */
+class XclImpChAttachedLabel : protected XclImpChRoot
+{
+public:
+ explicit XclImpChAttachedLabel( const XclImpChRoot& rRoot );
+ /** Reads the CHATTACHEDLABEL record (data series/point labels). */
+ void ReadChAttachedLabel( XclImpStream& rStrm );
+ /** Creates a CHTEXT group for the label. Clones xParentText and sets additional label settings */
+ XclImpChTextRef CreateDataLabel( XclImpChTextRef xParent ) const;
+
+private:
+ sal_uInt16 mnFlags; /// Additional flags.
+};
+
+typedef ScfRef< XclImpChAttachedLabel > XclImpChAttLabelRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDATAFORMAT record group containing data point properties.
+
+ The CHDATAFORMAT group consists of: CHDATAFORMAT, CHBEGIN, CHFRAME group,
+ CHMARKERFORMAT, CHPIEFORMAT, CH3DDATAFORMAT, CHSERIESFORMAT,
+ CHATTACHEDLABEL, CHEND.
+ */
+class XclImpChDataFormat : public XclImpChFrameBase, protected XclImpChRoot
+{
+public:
+ explicit XclImpChDataFormat( const XclImpChRoot& rRoot );
+
+ /** Reads the CHDATAFORMAT record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHDATAFORMAT group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Sets this object to the specified data point position. */
+ void SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx );
+ /** Sets type and text formatting for a data point label (CHTEXT group). */
+ inline void SetDataLabel( XclImpChTextRef xLabel ) { mxLabel = xLabel; }
+
+ /** Updates default data format for series group. */
+ void UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo );
+ /** Updates missing series settings from the passed chart type group data format. */
+ void UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt );
+ /** Updates missing data point settings from the passed series format. */
+ void UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt );
+ /** Updates default data format for trend lines. */
+ void UpdateTrendLineFormat();
+
+ /** Returns the position of the data point described by this group. */
+ inline const XclChDataPointPos& GetPointPos() const { return maData.maPointPos; }
+ /** Returns the format index of the data point described by this group. */
+ inline sal_uInt16 GetFormatIdx() const { return maData.mnFormatIdx; }
+ /** Returns true, if markers are set to automatic format. */
+ inline bool IsAutoMarker() const { return !mxMarkerFmt || mxMarkerFmt->IsAuto(); }
+ /** Returns true, if the series line is smoothed. */
+ inline bool HasSpline() const { return mxSeriesFmt.is() && mxSeriesFmt->HasSpline(); }
+ /** Returns the data label text object. */
+ inline XclImpChTextRef GetDataLabel() const { return mxLabel; }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const;
+ /** Writes the line format only, e.g. for trend lines or error bars. */
+ void ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const;
+ /** Writes the area format only for the series or a data point. */
+ void ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const;
+
+private:
+ /** Removes unused formatting (e.g. pie distance in a bar chart). */
+ void RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo );
+ /** Updates or creates the data point label. */
+ void UpdateDataLabel( const XclImpChDataFormat* pParentFmt );
+
+private:
+ XclChDataFormat maData; /// Contents of the CHDATAFORMAT record.
+ XclImpChMarkerFormatRef mxMarkerFmt; /// Data point marker (CHMARKERFORMAT record).
+ XclImpChPieFormatRef mxPieFmt; /// Pie segment format (CHPIEFORMAT record).
+ XclImpChSeriesFormatRef mxSeriesFmt; /// Series properties (CHSERIESFORMAT record).
+ XclImpCh3dDataFormatRef mx3dDataFmt; /// 3D bar format (CH3DDATAFORMAT record).
+ XclImpChAttLabelRef mxAttLabel; /// Data point label type (CHATTACHEDLABEL record).
+ XclImpChTextRef mxLabel; /// Data point label formatting (CHTEXT group).
+};
+
+typedef ScfRef< XclImpChDataFormat > XclImpChDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERTRENDLINE record containing settings for a trend line. */
+class XclImpChSerTrendLine : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclImpChSerTrendLine( const XclImpChRoot& rRoot );
+
+ /** Reads the CHSERTRENDLINE record. */
+ void ReadChSerTrendLine( XclImpStream& rStrm );
+ /** Sets formatting information for the trend line. */
+ inline void SetDataFormat( XclImpChDataFormatRef xDataFmt ) { mxDataFmt = xDataFmt; }
+
+ /** Creates an API object representing this trend line. */
+ XRegressionCurveRef CreateRegressionCurve() const;
+
+private:
+ XclChSerTrendLine maData; /// Contents of the CHSERTRENDLINE record.
+ XclImpChDataFormatRef mxDataFmt; /// Formatting settings of the trend line.
+};
+
+typedef ScfRef< XclImpChSerTrendLine > XclImpChSerTrendLineRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERERRORBAR record containing settings for error bars. */
+class XclImpChSerErrorBar : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > XPropertySetRef;
+
+public:
+ explicit XclImpChSerErrorBar( const XclImpChRoot& rRoot );
+
+ /** Reads the CHSERERRORBAR record. */
+ void ReadChSerErrorBar( XclImpStream& rStrm );
+ /** Sets link and formatting information for the error bars. */
+ void SetSeriesData(
+ XclImpChSourceLinkRef xValueLink,
+ XclImpChDataFormatRef xDataFmt );
+
+ /** Returns the type of this error bar (X/Y, plus/minus). */
+ inline sal_uInt8 GetBarType() const { return maData.mnBarType; }
+ /** Creates a labeled data sequence object from value data link. */
+ XLabeledDataSeqRef CreateValueSequence() const;
+
+ /** Tries to create an error bar API object from the specified Excel error bars. */
+ static XPropertySetRef CreateErrorBar(
+ const XclImpChSerErrorBar* pPosBar,
+ const XclImpChSerErrorBar* pNegBar );
+
+private:
+ XclChSerErrorBar maData; /// Contents of the CHSERERRORBAR record.
+ XclImpChSourceLinkRef mxValueLink; /// Link data for manual error bar values.
+ XclImpChDataFormatRef mxDataFmt; /// Formatting settings of the error bars.
+};
+
+typedef ScfRef< XclImpChSerErrorBar > XclImpChSerErrorBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERIES record group describing a data series in a chart.
+
+ The CHSERIES group consists of: CHSERIES, CHBEGIN, CHSOURCELINK groups,
+ CHDATAFORMAT groups, CHSERGROUP, CHSERPARENT, CHSERERRORBAR,
+ CHSERTRENDLINE, CHEND.
+ */
+class XclImpChSeries : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > XPropertySetRef;
+
+public:
+ explicit XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx );
+
+ /** Reads the CHSERIES record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHSERIES group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Sets a data point or series format (CHDATAFORMAT group) for this series. */
+ void SetDataFormat( XclImpChDataFormatRef xDataFmt );
+ /** Sets a label text (CHTEXT group) attached to a series or data point. */
+ void SetDataLabel( XclImpChTextRef xLabel );
+ /** Adds error bar settings from the passed series to the own series. */
+ void AddChildSeries( const XclImpChSeries& rSeries );
+ /** Updates missing series formatting by using default formatting from axes sets. */
+ void FinalizeDataFormats();
+
+ /** Returns the axes set identifier this series is assigned to (primary/secondary). */
+ inline sal_uInt16 GetGroupIdx() const { return mnGroupIdx; }
+ /** Returns the 0-based series index described by this series. */
+ inline sal_uInt16 GetSeriesIdx() const { return mnSeriesIdx; }
+ /** Returns the 0-based index of the parent series (e.g. of a trend line). */
+ inline sal_uInt16 GetParentIdx() const { return mnParentIdx; }
+ /** Returns the format index of the series used for automatic line and area colors. */
+ inline sal_uInt16 GetFormatIdx() const { return mxSeriesFmt.is() ? mxSeriesFmt->GetFormatIdx() : EXC_CHDATAFORMAT_DEFAULT; }
+ /** Returns true, if the series is child of another series (e.g. trend line). */
+ inline bool HasParentSeries() const { return mnParentIdx != EXC_CHSERIES_INVALID; }
+ /** Returns true, if the series contains child series (e.g. trend lines). */
+ inline bool HasChildSeries() const { return !maTrendLines.empty() || !maErrorBars.empty(); }
+ /** Returns series title or an empty string, if the series does not contain a title. */
+ inline const String& GetTitle() const { return mxTitleLink.is() ? mxTitleLink->GetString() : String::EmptyString(); }
+
+ /** Returns true, if the series line is smoothed. */
+ inline bool HasSpline() const { return mxSeriesFmt.is() && mxSeriesFmt->HasSpline(); }
+
+ /** Creates a labeled data sequence object from value data link. */
+ XLabeledDataSeqRef CreateValueSequence( const ::rtl::OUString& rValueRole ) const;
+ /** Creates a labeled data sequence object from category data link. */
+ XLabeledDataSeqRef CreateCategSequence( const ::rtl::OUString& rCategRole ) const;
+ /** Creates a data series object with initialized source links. */
+ XDataSeriesRef CreateDataSeries() const;
+
+ void FillAllSourceLinks(::std::vector<ScSharedTokenRef>& rTokens) const;
+
+private:
+ /** Reads a CHSOURCELINK record. */
+ void ReadChSourceLink( XclImpStream& rStrm );
+ /** Reads a CHDATAFORMAT group containing series and point formatting. */
+ void ReadChDataFormat( XclImpStream& rStrm );
+ /** Reads a CHSERPARENT record specifying the parent series of this series. */
+ void ReadChSerParent( XclImpStream& rStrm );
+ /** Reads a CHSERTRENDLINE record containing trend line settings. */
+ void ReadChSerTrendLine( XclImpStream& rStrm );
+ /** Reads a CHSERERRORBAR record containing error bar settings. */
+ void ReadChSerErrorBar( XclImpStream& rStrm );
+
+ /** Creates a new CHDATAFORMAT group with the specified point index. */
+ XclImpChDataFormatRef CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx );
+ /** Returns the pointer to a CHDATAFORMAT group reference or 0 for invalid pointer index. */
+ XclImpChDataFormatRef* GetDataFormatRef( sal_uInt16 nPointIdx );
+ /** Returns the pointer to a CHTEXT group reference or 0 for invalid pointer index. */
+ XclImpChTextRef* GetDataLabelRef( sal_uInt16 nPointIdx );
+
+ /** Converts all trend lines and inserts them into the passed API data series object. */
+ void ConvertTrendLines( XDataSeriesRef xDataSeries ) const;
+ /** Tries to create an error bar API object from the specified Excel error bars. */
+ XPropertySetRef CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const;
+
+private:
+ typedef ScfRefMap< sal_uInt16, XclImpChDataFormat > XclImpChDataFormatMap;
+ typedef ScfRefMap< sal_uInt16, XclImpChText > XclImpChTextMap;
+ typedef ::std::list< XclImpChSerTrendLineRef > XclImpChSerTrendLineList;
+ typedef ScfRefMap< sal_uInt8, XclImpChSerErrorBar > XclImpChSerErrorBarMap;
+
+ XclChSeries maData; /// Contents of the CHSERIES record.
+ XclImpChSourceLinkRef mxValueLink; /// Link data for series values.
+ XclImpChSourceLinkRef mxCategLink; /// Link data for series category names.
+ XclImpChSourceLinkRef mxTitleLink; /// Link data for series title.
+ XclImpChSourceLinkRef mxBubbleLink; /// Link data for series bubble sizes.
+ XclImpChDataFormatRef mxSeriesFmt; /// CHDATAFORMAT group for series format.
+ XclImpChDataFormatMap maPointFmts; /// CHDATAFORMAT groups for data point formats.
+ XclImpChTextMap maLabels; /// Data point labels (CHTEXT groups).
+ XclImpChSerTrendLineList maTrendLines; /// Trend line settings (CHSERTRENDLINE records).
+ XclImpChSerErrorBarMap maErrorBars; /// Error bar settings (CHSERERRORBAR records).
+ sal_uInt16 mnGroupIdx; /// Chart type group (CHTYPEGROUP group) this series is assigned to.
+ sal_uInt16 mnSeriesIdx; /// 0-based series index.
+ sal_uInt16 mnParentIdx; /// 0-based index of parent series (trend lines and error bars).
+};
+
+typedef ScfRef< XclImpChSeries > XclImpChSeriesRef;
+
+// Chart type groups ==========================================================
+
+class XclImpChType : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+
+public:
+ explicit XclImpChType( const XclImpChRoot& rRoot );
+
+ /** Reads a chart type record (e.g. CHBAR, CHLINE, CHPIE, ...). */
+ void ReadChType( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize( bool bStockChart );
+
+ /** Returns the record identifier of the chart type record. */
+ inline sal_uInt16 GetRecId() const { return mnRecId; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+ /** Returns true, if the series in this chart type group are stacked on each other (no percentage). */
+ bool IsStacked() const;
+ /** Returns true, if the series in this chart type group are stacked on each other as percentage. */
+ bool IsPercent() const;
+ /** Returns true, if chart type has category labels enabled (may be disabled in radar charts). */
+ bool HasCategoryLabels() const;
+
+ /** Creates a coordinate system according to the contained chart type. */
+ XCoordSystemRef CreateCoordSystem( bool b3dChart ) const;
+ /** Creates and returns an object that represents the contained chart type. */
+ XChartTypeRef CreateChartType( XDiagramRef xDiagram, bool b3dChart ) const;
+
+private:
+ XclChType maData; /// Contents of the chart type record.
+ sal_uInt16 mnRecId; /// Record identifier for chart type.
+ XclChTypeInfo maTypeInfo; /// Chart type info for the contained type.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHCHART3D record that contains 3D view settings. */
+class XclImpChChart3d
+{
+public:
+ /** Reads the CHCHART3D record (properties for 3D charts). */
+ void ReadChChart3d( XclImpStream& rStrm );
+ /** Returns true, if the data points are clustered on the X axis. */
+ inline bool IsClustered() const { return ::get_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const;
+
+private:
+ XclChChart3d maData; /// Contents of the CHCHART3D record.
+};
+
+typedef ScfRef< XclImpChChart3d > XclImpChChart3dRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHLEGEND record group describing the chart legend.
+
+ The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME
+ group, CHTEXT group, CHEND.
+ */
+class XclImpChLegend : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XLegend > XLegendRef;
+
+public:
+ explicit XclImpChLegend( const XclImpChRoot& rRoot );
+
+ /** Reads the CHLEGEND record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHLEGEND group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Creates a new legend object. */
+ XLegendRef CreateLegend() const;
+
+private:
+ XclChLegend maData; /// Contents of the CHLEGEND record.
+ XclImpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record).
+ XclImpChTextRef mxText; /// Legend text format (CHTEXT group).
+ XclImpChFrameRef mxFrame; /// Legend frame format (CHFRAME group).
+};
+
+typedef ScfRef< XclImpChLegend > XclImpChLegendRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDROPBAR record group describing pos/neg bars in line charts.
+
+ The CHDROPBAR group consists of: CHDROPBAR, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclImpChDropBar : public XclImpChFrameBase
+{
+public:
+ explicit XclImpChDropBar( sal_uInt16 nDropBar );
+
+ /** Reads the CHDROPBAR record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+
+ /** Converts and writes the contained frame data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const;
+
+private:
+ sal_uInt16 mnDropBar; /// Drop bar identifier, needed for auto format.
+ sal_uInt16 mnBarDist; /// Distance between bars (CHDROPBAR record).
+};
+
+typedef ScfRef< XclImpChDropBar > XclImpChDropBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTYPEGROUP record group describing a group of series.
+
+ The CHTYPEGROUP group consists of: CHTYPEGROUP, CHBEGIN, a chart type
+ record (e.g. CHBAR, CHLINE, CHAREA, CHPIE, ...), CHCHART3D, CHLEGEND group,
+ CHDEFAULTTEXT groups (CHDEFAULTTEXT with CHTEXT groups), CHDROPBAR groups,
+ CHCHARTLINE groups (CHCHARTLINE with CHLINEFORMAT), CHDATAFORMAT group,
+ CHEND.
+ */
+class XclImpChTypeGroup : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+
+public:
+ explicit XclImpChTypeGroup( const XclImpChRoot& rRoot );
+
+ /** Reads the CHTYPEGROUP record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHTYPEGROUP group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Inserts a series attached to this chart type group.*/
+ void AddSeries( XclImpChSeriesRef xSeries );
+ /** Marks the passed format index as used. PopUnusedFormatIndex() will not return this index. */
+ void SetUsedFormatIndex( sal_uInt16 nFormatIdx );
+ /** Returns the next unused format index and marks it as used. */
+ sal_uInt16 PopUnusedFormatIndex();
+
+ /** Returns the index of this chart type group. */
+ inline sal_uInt16 GetGroupIdx() const { return maData.mnGroupIdx; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChExtTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+ /** Returns true, if this chart type group contains at least one valid series. */
+ inline bool IsValidGroup() const { return !maSeries.empty(); }
+ /** Returns true, if the series in this chart type group are stacked on each other (no percentage). */
+ inline bool IsStacked() const { return maType.IsStacked(); }
+ /** Returns true, if the series in this chart type group are stacked on each other as percentage. */
+ inline bool IsPercent() const { return maType.IsPercent(); }
+ /** Returns true, if the chart is three-dimensional. */
+ inline bool Is3dChart() const { return mxChart3d.is() && maTypeInfo.mbSupports3d; }
+ /** Returns true, if chart type supports wall and floor format in 3d mode. */
+ inline bool Is3dWallChart() const { return Is3dChart() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE); }
+ /** Returns true, if the series in this chart type group are ordered on the Z axis. */
+ inline bool Is3dDeepChart() const { return Is3dWallChart() && mxChart3d.is() && !mxChart3d->IsClustered(); }
+ /** Returns true, if category (X axis) labels are enabled (may be disabled in radar charts). */
+ inline bool HasCategoryLabels() const { return maType.HasCategoryLabels(); }
+ /** Returns true, if points of a series show varying automatic area format. */
+ bool HasVarPointFormat() const;
+ /** Returns true, if bars are connected with lines (stacked bar charts only). */
+ bool HasConnectorLines() const;
+
+ /** Returns the legend object. */
+ inline XclImpChLegendRef GetLegend() const { return mxLegend; }
+ /** Returns the default series data format. */
+ inline XclImpChDataFormatRef GetGroupFormat() const { return mxGroupFmt; }
+ /** Returns series title, if the chart type group contains only one single series. */
+ const String& GetSingleSeriesTitle() const;
+
+ /** Converts and writes all 3D settings to the passed diagram. */
+ void ConvertChart3d( ScfPropertySet& rPropSet ) const;
+ /** Creates a coordinate system according to the contained chart type. */
+ XCoordSystemRef CreateCoordSystem() const;
+ /** Creates and returns an object that represents the contained chart type. */
+ XChartTypeRef CreateChartType( XDiagramRef xDiagram, sal_Int32 nApiAxesSetIdx ) const;
+ /** Creates a labeled data sequence object for axis categories. */
+ XLabeledDataSeqRef CreateCategSequence() const;
+
+private:
+ /** Reads a CHDROPBAR record group. */
+ void ReadChDropBar( XclImpStream& rStrm );
+ /** Reads a CHCHARTLINE record group. */
+ void ReadChChartLine( XclImpStream& rStrm );
+ /** Reads a CHDATAFORMAT record group (default series format). */
+ void ReadChDataFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the chart type group contains a hi-lo line format. */
+ inline bool HasHiLoLine() const { return maChartLines.has( EXC_CHCHARTLINE_HILO ); }
+ /** Returns true, if the chart type group contains drop bar formats. */
+ inline bool HasDropBars() const { return !maDropBars.empty(); }
+
+ /** Inserts the passed series into the chart type. Adds additional properties to the series. */
+ void InsertDataSeries( XChartTypeRef xChartType,
+ XDataSeriesRef xSeries, sal_Int32 nApiAxesSetIdx ) const;
+ /** Creates all data series of any chart type except stock charts. */
+ void CreateDataSeries( XChartTypeRef xChartType, sal_Int32 nApiAxesSetIdx ) const;
+ /** Creates all data series of of a stock chart. */
+ void CreateStockSeries( XChartTypeRef xChartType, sal_Int32 nApiAxesSetIdx ) const;
+
+private:
+ typedef ::std::vector< XclImpChSeriesRef > XclImpChSeriesVec;
+ typedef ScfRefMap< sal_uInt16, XclImpChDropBar > XclImpChDropBarMap;
+ typedef ScfRefMap< sal_uInt16, XclImpChLineFormat > XclImpChLineFormatMap;
+ typedef ::std::set< sal_uInt16 > UInt16Set;
+
+ XclChTypeGroup maData; /// Contents of the CHTYPEGROUP record.
+ XclImpChType maType; /// Chart type (e.g. CHBAR, CHLINE, ...).
+ XclChExtTypeInfo maTypeInfo; /// Extended chart type info.
+ XclImpChSeriesVec maSeries; /// Series attached to this chart type group (CHSERIES groups).
+ XclImpChSeriesRef mxFirstSeries; /// First series in this chart type group (CHSERIES groups).
+ XclImpChChart3dRef mxChart3d; /// 3D settings (CHCHART3D record).
+ XclImpChLegendRef mxLegend; /// Chart legend (CHLEGEND group).
+ XclImpChDropBarMap maDropBars; /// Dropbars (CHDROPBAR group).
+ XclImpChLineFormatMap maChartLines; /// Global line formats (CHCHARTLINE group).
+ XclImpChDataFormatRef mxGroupFmt; /// Default format for all series (CHDATAFORMAT group).
+ UInt16Set maUnusedFormats; /// Contains unused format indexes for automatic colors.
+};
+
+typedef ScfRef< XclImpChTypeGroup > XclImpChTypeGroupRef;
+
+// Axes =======================================================================
+
+class XclImpChLabelRange : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::chart2::ScaleData ScaleData;
+
+public:
+ explicit XclImpChLabelRange( const XclImpChRoot& rRoot );
+ /** Reads the CHLABELRANGE record (category axis scaling properties). */
+ void ReadChLabelRange( XclImpStream& rStrm );
+ /** Converts category axis scaling settings. */
+ void Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const;
+ /** Converts position settings of this axis at a crossing axis. */
+ void ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const;
+
+private:
+ XclChLabelRange maData; /// Contents of the CHLABELRANGE record.
+};
+
+typedef ScfRef< XclImpChLabelRange > XclImpChLabelRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclImpChValueRange : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::chart2::ScaleData ScaleData;
+
+public:
+ explicit XclImpChValueRange( const XclImpChRoot& rRoot );
+ /** Reads the CHVALUERANGE record (numeric axis scaling properties). */
+ void ReadChValueRange( XclImpStream& rStrm );
+ /** Converts value axis scaling settings. */
+ void Convert( ScaleData& rScaleData, bool bMirrorOrient ) const;
+ /** Converts position settings of this axis at a crossing axis. */
+ void ConvertAxisPosition( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclChValueRange maData; /// Contents of the CHVALUERANGE record.
+};
+
+typedef ScfRef< XclImpChValueRange > XclImpChValueRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclImpChTick : protected XclImpChRoot
+{
+public:
+ explicit XclImpChTick( const XclImpChRoot& rRoot );
+ /** Reads the CHTICK record (axis ticks properties). */
+ void ReadChTick( XclImpStream& rStrm );
+
+ /** Returns true, if the axis shows attached labels. */
+ inline bool HasLabels() const { return maData.mnLabelPos != EXC_CHTICK_NOLABEL; }
+ /** Returns the leading font color for the axis labels. */
+ Color GetFontColor() const;
+ /** Returns the rotation value for the axis labels. */
+ sal_uInt16 GetRotation() const;
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclChTick maData; /// Contents of the CHTICK record.
+};
+
+typedef ScfRef< XclImpChTick > XclImpChTickRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXIS record group describing an entire chart axis.
+
+ The CHAXIS group consists of: CHAXIS, CHBEGIN, CHLABELRANGE, CHEXTRANGE,
+ CHVALUERANGE, CHFORMAT, CHTICK, CHFONT, CHAXISLINE groups (CHAXISLINE with
+ CHLINEFORMAT, CHAREAFORMAT, and CHESCHERFORMAT group), CHEND.
+ */
+class XclImpChAxis : public XclImpChGroupBase, public XclImpChFontBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;
+
+public:
+ explicit XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType = EXC_CHAXIS_NONE );
+
+ /** Reads the CHAXIS record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHAXIS group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Returns the font index for the axis labels. */
+ virtual sal_uInt16 GetFontIndex() const;
+ /** Returns the font color for the axis labels. */
+ virtual Color GetFontColor() const;
+ /** Returns the rotation value for axis labels. */
+ virtual sal_uInt16 GetRotation() const;
+
+ /** Returns the type of this axis. */
+ inline sal_uInt16 GetAxisType() const { return maData.mnType; }
+ /** Returns the axis dimension index used by the chart API. */
+ inline sal_Int32 GetApiAxisDimension() const { return maData.GetApiAxisDimension(); }
+ /** Returns true, if the axis is active. */
+ inline bool IsActivated() const { return !mxAxisLine || mxAxisLine->IsShowAxis(); }
+ /** Returns true, if the axis contains caption labels. */
+ inline bool HasLabels() const { return !mxTick || mxTick->HasLabels(); }
+ /** Returns true, if the axis shows its major grid lines. */
+ inline bool HasMajorGrid() const { return mxMajorGrid.is(); }
+ /** Returns true, if the axis shows its minor grid lines. */
+ inline bool HasMinorGrid() const { return mxMinorGrid.is(); }
+
+ /** Creates an API axis object. */
+ XAxisRef CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const;
+ /** Converts and writes 3D wall/floor properties to the passed property set. */
+ void ConvertWall( ScfPropertySet& rPropSet ) const;
+ /** Converts position settings of this axis at a crossing axis. */
+ void ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const;
+
+private:
+ /** Reads a CHAXISLINE record specifying the target for following line properties. */
+ void ReadChAxisLine( XclImpStream& rStrm );
+ /** Creates a CHFRAME object and stores it into the mxWallFrame member. */
+ void CreateWallFrame();
+
+private:
+ XclChAxis maData; /// Contents of the CHAXIS record.
+ XclImpChLabelRangeRef mxLabelRange; /// Category scaling (CHLABELRANGE record).
+ XclImpChValueRangeRef mxValueRange; /// Value scaling (CHVALUERANGE record).
+ XclImpChTickRef mxTick; /// Axis ticks (CHTICK record).
+ XclImpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclImpChLineFormatRef mxAxisLine; /// Axis line format (CHLINEFORMAT record).
+ XclImpChLineFormatRef mxMajorGrid; /// Major grid line format (CHLINEFORMAT record).
+ XclImpChLineFormatRef mxMinorGrid; /// Minor grid line format (CHLINEFORMAT record).
+ XclImpChFrameRef mxWallFrame; /// Wall/floor format (sub records of CHFRAME group).
+ sal_uInt16 mnNumFmtIdx; /// Index into number format buffer (CHFORMAT record).
+};
+
+typedef ScfRef< XclImpChAxis > XclImpChAxisRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXESSET record group describing an axes set (X/Y/Z axes).
+
+ The CHAXESSET group consists of: CHAXESSET, CHBEGIN, CHFRAMEPOS, CHAXIS
+ groups, CHTEXT groups, CHPLOTFRAME group (CHPLOTFRAME with CHFRAME group),
+ CHTYPEGROUP group, CHEND.
+ */
+class XclImpChAxesSet : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;
+
+public:
+ explicit XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId );
+
+ /** Reads the CHAXESSET record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHAXESSET group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Returns true, if this axes set exists (returns false if this is a dummy object). */
+ inline bool IsValidAxesSet() const { return !maTypeGroups.empty(); }
+ /** Returns the index of the axes set (primary/secondary). */
+ inline sal_uInt16 GetAxesSetId() const { return maData.mnAxesSetId; }
+ /** Returns the axes set index used by the chart API. */
+ inline sal_Int32 GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); }
+
+ /** Returns the outer plot area position, if existing. */
+ inline XclImpChFramePosRef GetPlotAreaFramePos() const { return mxFramePos; }
+ /** Returns the specified chart type group. */
+ inline XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const { return maTypeGroups.get( nGroupIdx ); }
+ /** Returns the first chart type group. */
+ XclImpChTypeGroupRef GetFirstTypeGroup() const;
+ /** Looks for a legend in all chart type groups and returns it. */
+ XclImpChLegendRef GetLegend() const;
+ /** Returns series title, if the axes set contains only one single series. */
+ const String& GetSingleSeriesTitle() const;
+
+ /** Creates a coordinate system and converts all series and axis settings. */
+ void Convert( XDiagramRef xDiagram ) const;
+ /** Converts the manual positions of all axis titles. */
+ void ConvertTitlePositions() const;
+
+private:
+ /** Reads a CHAXIS record group containing a single axis. */
+ void ReadChAxis( XclImpStream& rStrm );
+ /** Reads a CHTEXT record group containing an axis title. */
+ void ReadChText( XclImpStream& rStrm );
+ /** Reads the CHPLOTFRAME record group containing diagram area formatting. */
+ void ReadChPlotFrame( XclImpStream& rStrm );
+ /** Reads a CHTYPEGROUP record group containing chart type and chart settings. */
+ void ReadChTypeGroup( XclImpStream& rStrm );
+
+ /** Updates text formatting of the passed axis title with global text formatting. */
+ void UpdateAxisTitle( XclImpChTextRef xTitle );
+
+ /** Creates a coordinate system that contains all chart types for this axes set. */
+ XCoordSystemRef CreateCoordSystem( XDiagramRef xDiagram ) const;
+ /** Creates and inserts an axis into the container and registers the coordinate system. */
+ void ConvertAxis( XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
+ XCoordSystemRef xCoordSystem, const XclImpChAxis* pCrossingAxis ) const;
+ /** Creates and returns an API axis object. */
+ XAxisRef CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const;
+ /** Writes all properties of the background area to the passed diagram. */
+ void ConvertBackground( XDiagramRef xDiagram ) const;
+
+private:
+ typedef ScfRefMap< sal_uInt16, XclImpChTypeGroup > XclImpChTypeGroupMap;
+
+ XclChAxesSet maData; /// Contents of the CHAXESSET record.
+ XclImpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record).
+ XclImpChAxisRef mxXAxis; /// The X axis (CHAXIS group).
+ XclImpChAxisRef mxYAxis; /// The Y axis (CHAXIS group).
+ XclImpChAxisRef mxZAxis; /// The Z axis (CHAXIS group).
+ XclImpChTextRef mxXAxisTitle; /// The X axis title (CHTEXT group).
+ XclImpChTextRef mxYAxisTitle; /// The Y axis title (CHTEXT group).
+ XclImpChTextRef mxZAxisTitle; /// The Z axis title (CHTEXT group).
+ XclImpChFrameRef mxPlotFrame; /// Plot area (CHPLOTFRAME group).
+ XclImpChTypeGroupMap maTypeGroups; /// Chart type groups (CHTYPEGROUP group).
+};
+
+typedef ScfRef< XclImpChAxesSet > XclImpChAxesSetRef;
+
+// The chart object ===========================================================
+
+/** Represents the CHCHART record group describing the chart contents.
+
+ The CHCHART group consists of: CHCHART, CHBEGIN, SCL, CHPLOTGROWTH, CHFRAME
+ group, CHSERIES groups, CHPROPERTIES, CHDEFAULTTEXT groups (CHDEFAULTTEXT
+ with CHTEXT groups), CHUSEDAXESSETS, CHAXESSET groups, CHTEXT groups, CHEND.
+ */
+class XclImpChChart : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+
+public:
+ explicit XclImpChChart( const XclImpRoot& rRoot );
+ virtual ~XclImpChChart();
+
+ /** Reads the CHCHART record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHCHART group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Reads a CHDEFAULTTEXT group (default text formats). */
+ void ReadChDefaultText( XclImpStream& rStrm );
+ /** Reads a CHDATAFORMAT group describing a series format or a data point format. */
+ void ReadChDataFormat( XclImpStream& rStrm );
+
+ /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
+ void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );
+
+ /** Returns the specified chart type group. */
+ XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const;
+ /** Returns the specified default text. */
+ XclImpChTextRef GetDefaultText( XclChTextType eTextType ) const;
+ /** Returns true, if the plot area has benn moved and/or resized manually. */
+ bool IsManualPlotArea() const;
+ /** Returns the number of units on the progress bar needed for the chart. */
+ inline sal_Size GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; }
+
+ /** Converts and writes all properties to the passed chart. */
+ void Convert( XChartDocRef xChartDoc,
+ XclImpDffConverter& rDffConv,
+ const ::rtl::OUString& rObjName,
+ const Rectangle& rChartRect ) const;
+
+private:
+ /** Reads a CHSERIES group (data series source and formatting). */
+ void ReadChSeries( XclImpStream& rStrm );
+ /** Reads a CHPROPERTIES record (global chart properties). */
+ void ReadChProperties( XclImpStream& rStrm );
+ /** Reads a CHAXESSET group (primary/secondary axes set). */
+ void ReadChAxesSet( XclImpStream& rStrm );
+ /** Reads a CHTEXT group (chart title and series/point captions). */
+ void ReadChText( XclImpStream& rStrm );
+
+ /** Final processing after reading the entire chart data. */
+ void Finalize();
+ /** Finalizes series list, assigns child series to parent series. */
+ void FinalizeSeries();
+ /** Assigns all imported CHDATAFORMAT groups to the respective series. */
+ void FinalizeDataFormats();
+ /** Finalizes chart title, tries to detect title auto-generated from series name. */
+ void FinalizeTitle();
+
+ /** Creates and returns a new diagram object and converts global chart settings. */
+ XDiagramRef CreateDiagram() const;
+
+private:
+ typedef ::std::vector< XclImpChSeriesRef > XclImpChSeriesVec;
+ typedef ScfRefMap< XclChDataPointPos, XclImpChDataFormat > XclImpChDataFormatMap;
+ typedef ScfRefMap< sal_uInt16, XclImpChText > XclImpChTextMap;
+
+ XclChRectangle maRect; /// Position of the chart on the sheet (CHCHART record).
+ XclImpChSeriesVec maSeries; /// List of series data (CHSERIES groups).
+ XclImpChDataFormatMap maDataFmts; /// All series and point formats (CHDATAFORMAT groups).
+ XclImpChFrameRef mxFrame; /// Chart frame format (CHFRAME group).
+ XclChProperties maProps; /// Chart properties (CHPROPERTIES record).
+ XclImpChTextMap maDefTexts; /// Default text objects (CHDEFAULTTEXT groups).
+ XclImpChAxesSetRef mxPrimAxesSet; /// Primary axes set (CHAXESSET group).
+ XclImpChAxesSetRef mxSecnAxesSet; /// Secondary axes set (CHAXESSET group).
+ XclImpChTextRef mxTitle; /// Chart title (CHTEXT group).
+ XclImpChLegendRef mxLegend; /// Chart legend (CHLEGEND group).
+};
+
+typedef ScfRef< XclImpChChart > XclImpChChartRef;
+
+// ----------------------------------------------------------------------------
+
+/** Drawing container of a chart. */
+class XclImpChartDrawing : public XclImpDrawing
+{
+public:
+ explicit XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab );
+
+ /** Converts all objects and inserts them into the chart drawing page. */
+ void ConvertObjects(
+ XclImpDffConverter& rDffConv,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel,
+ const Rectangle& rChartRect );
+
+ /** Calculate the resulting rectangle of the passed anchor. */
+ virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const;
+ /** Called whenever an object has been inserted into the draw page. */
+ virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj );
+
+private:
+ Rectangle maChartRect; /// Position and size of the chart shape in 1/100 mm.
+ SCTAB mnScTab; /// Index of the sheet that contains the chart.
+ bool mbOwnTab; /// True = own sheet, false = embedded object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the entire chart substream (all records in BOF/EOF block). */
+class XclImpChart : protected XclImpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > XModelRef;
+
+public:
+ /** Constructs a new chart object.
+ @param bOwnTab True = chart is on an own sheet; false = chart is an embedded object. */
+ explicit XclImpChart( const XclImpRoot& rRoot, bool bOwnTab );
+ virtual ~XclImpChart();
+
+ /** Reads the complete chart substream (BOF/EOF block).
+ @descr The passed stream must be located in the BOF record of the chart substream. */
+ void ReadChartSubStream( XclImpStream& rStrm );
+ /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
+ void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );
+
+ /** Returns the number of units on the progress bar needed for the chart. */
+ sal_Size GetProgressSize() const;
+ /** Returns true, if the chart is based on a pivot table. */
+ inline bool IsPivotChart() const { return mbIsPivotChart; }
+
+ /** Creates the chart object in the passed component. */
+ void Convert( XModelRef xModel,
+ XclImpDffConverter& rDffConv,
+ const ::rtl::OUString& rObjName,
+ const Rectangle& rChartRect ) const;
+
+private:
+ /** Returns (initially creates) the drawing container for embedded shapes. **/
+ XclImpChartDrawing& GetChartDrawing();
+ /** Reads the CHCHART group (entire chart data). */
+ void ReadChChart( XclImpStream& rStrm );
+
+private:
+ typedef ScfRef< XclImpChartDrawing > XclImpChartDrawingRef;
+
+ XclImpChChartRef mxChartData; /// The chart data (CHCHART group).
+ XclImpChartDrawingRef mxChartDrawing; /// Drawing container for embedded shapes.
+ bool mbOwnTab; /// true = own sheet; false = embedded object.
+ bool mbIsPivotChart; /// true = chart is based on a pivot table.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xicontent.hxx b/sc/source/filter/inc/xicontent.hxx
new file mode 100644
index 000000000000..810c435d34bf
--- /dev/null
+++ b/sc/source/filter/inc/xicontent.hxx
@@ -0,0 +1,311 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XICONTENT_HXX
+#define SC_XICONTENT_HXX
+
+#include "global.hxx"
+#include "rangelst.hxx"
+#include "xlcontent.hxx"
+#include "xistring.hxx"
+#include "xiroot.hxx"
+
+#include <map>
+
+/* ============================================================================
+Classes to import the big Excel document contents (related to several cells or
+globals for the document).
+- Shared string tables
+- Hyperlinks
+- Label ranges
+- Conditional formatting
+- Data validation
+- Web queries
+- Stream decryption
+============================================================================ */
+
+// Shared string table ========================================================
+
+class ScBaseCell;
+
+/** The SST (shared string table) contains all strings used in a BIFF8 file.
+
+ This class loads the SST, provides access to the strings, and is able to
+ create Calc string or edit cells.
+ */
+class XclImpSst : protected XclImpRoot
+{
+public:
+ explicit XclImpSst( const XclImpRoot& rRoot );
+
+ /** Reads the entire SST record.
+ @descr Import stream must be located at start of a SST record. */
+ void ReadSst( XclImpStream& rStrm );
+
+ /** Returns a pointer to the string with the passed index. */
+ const XclImpString* GetString( sal_uInt32 nSstIndex ) const;
+
+ /** Creates a new text cell or edit cell for a Calc document.
+ @param nXFIndex Index to XF for first text portion (checks escapement). */
+ ScBaseCell* CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex = 0 ) const;
+
+private:
+ typedef ::std::vector< XclImpString > XclImpStringVec;
+ XclImpStringVec maStrings; /// List with all strings in the SST.
+};
+
+// Hyperlinks =================================================================
+
+/** Provides importing hyperlinks and inserting them into a document. */
+class XclImpHyperlink : ScfNoInstance
+{
+public:
+ /** Reads a HLINK record and inserts it into the document.
+ @descr Import stream must be located at start of a HLINK record. */
+ static void ReadHlink( XclImpStream& rStrm );
+
+ /** Reads the (undocumented) embedded hyperlink data and returns the URL. */
+ static String ReadEmbeddedData( XclImpStream& rStrm );
+
+ /** Inserts the URL into a range of cells. Does not modify value or formula cells. */
+ static void InsertUrl( const XclImpRoot& rRoot, const XclRange& rXclRange, const String& rUrl );
+
+ /** Convert the sheet name with invalid character(s) in URL when the URL is
+ to a location within the same document (e.g. #'Sheet&Name'.A1). */
+ static void ConvertToValidTabName(String& rName);
+};
+
+// Label ranges ===============================================================
+
+/** Provides importing label ranges and inserting them into a document. */
+class XclImpLabelranges : ScfNoInstance
+{
+public:
+ /** Reads a LABELRANGES record and inserts the label ranges into the document.
+ @descr Import stream must be located at start of a LABELRANGES record. */
+ static void ReadLabelranges( XclImpStream& rStrm );
+};
+
+// Conditional formatting =====================================================
+
+class ScConditionalFormat;
+
+/** Represents a conditional format with condition formulas, and formatting attributes. */
+class XclImpCondFormat : protected XclImpRoot
+{
+public:
+ explicit XclImpCondFormat( const XclImpRoot& rRoot, sal_uInt32 nFormatIndex );
+ virtual ~XclImpCondFormat();
+
+ /** Reads a CONDFMT record and initializes this conditional format. */
+ void ReadCondfmt( XclImpStream& rStrm );
+ /** Reads a CF record and adds a new condition and the formatting attributes. */
+ void ReadCF( XclImpStream& rStrm );
+
+ /** Inserts this conditional format into the document. */
+ void Apply();
+
+private:
+ typedef ::std::auto_ptr< ScConditionalFormat > ScCondFmtPtr;
+
+ ScRangeList maRanges; /// Destination cell ranges.
+ ScCondFmtPtr mxScCondFmt; /// Calc conditional format.
+ sal_uInt32 mnFormatIndex; /// Index of this conditional format in list.
+ sal_uInt16 mnCondCount; /// Number of conditions to be inserted.
+ sal_uInt16 mnCondIndex; /// Condition index to be inserted next.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Imports and collects all conditional formatting of a sheet. */
+class XclImpCondFormatManager : protected XclImpRoot
+{
+public:
+ explicit XclImpCondFormatManager( const XclImpRoot& rRoot );
+
+ /** Reads a CONDFMT record and starts a new conditional format to be filled from CF records. */
+ void ReadCondfmt( XclImpStream& rStrm );
+ /** Reads a CF record and inserts the formatting data to the current conditional format. */
+ void ReadCF( XclImpStream& rStrm );
+
+ /** Inserts the conditional formattings into the document. */
+ void Apply();
+
+private:
+ typedef ScfDelList< XclImpCondFormat > XclImpCondFmtList;
+ XclImpCondFmtList maCondFmtList; /// List with all conditional formattings.
+};
+
+// Data Validation ============================================================
+
+/** Provides importing validation data and inserting it into a document. */
+class XclImpValidation : ScfNoInstance
+{
+public:
+ /** Reads a DVAL record and sets marks the dropdown arrow control to be ignored. */
+ static void ReadDval( XclImpStream& rStrm );
+ /** Reads a DV record and inserts validation data into the document. */
+ static void ReadDV( XclImpStream& rStrm );
+};
+
+// Web queries ================================================================
+
+/** Stores the data of one web query. */
+class XclImpWebQuery : ScfNoCopy
+{
+public:
+ explicit XclImpWebQuery( const ScRange& rDestRange );
+
+ /** Reads a PARAMQRY record and sets data to the web query. */
+ void ReadParamqry( XclImpStream& rStrm );
+ /** Reads a WQSTRING record and sets URL. */
+ void ReadWqstring( XclImpStream& rStrm );
+ /** Reads a WEBQRYSETTINGS record and sets refresh rate. */
+ void ReadWqsettings( XclImpStream& rStrm );
+ /** Reads a WEBQRYTABLES record and sets source range list. */
+ void ReadWqtables( XclImpStream& rStrm );
+
+ /** Inserts the web query into the document. */
+ void Apply( ScDocument& rDoc, const String& rFilterName );
+
+private:
+ /** Specifies the type of the web query (which ranges are imported). */
+ enum XclImpWebQueryMode
+ {
+ xlWQUnknown, /// Not specified.
+ xlWQDocument, /// Entire document.
+ xlWQAllTables, /// All tables.
+ xlWQSpecTables /// Specific tables.
+ };
+
+ String maURL; /// Source document URL.
+ String maTables; /// List of source range names.
+ ScRange maDestRange; /// Destination range.
+ XclImpWebQueryMode meMode; /// Current mode of the web query.
+ sal_uInt16 mnRefresh; /// Refresh time in minutes.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclImpWebQueryBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpWebQueryBuffer( const XclImpRoot& rRoot );
+
+ /** Reads the QSI record and creates a new web query in the buffer. */
+ void ReadQsi( XclImpStream& rStrm );
+ /** Reads a PARAMQRY record and sets data to the current web query. */
+ void ReadParamqry( XclImpStream& rStrm );
+ /** Reads a WQSTRING record and sets URL to the current web query. */
+ void ReadWqstring( XclImpStream& rStrm );
+ /** Reads a WEBQRYSETTINGS record and sets refresh rate to the current web query. */
+ void ReadWqsettings( XclImpStream& rStrm );
+ /** Reads a WEBQRYTABLES record and sets source range list to the current web query. */
+ void ReadWqtables( XclImpStream& rStrm );
+
+ /** Inserts all web queries into the document. */
+ void Apply();
+
+private:
+ typedef ScfDelList< XclImpWebQuery > XclImpWebQueryList;
+ XclImpWebQueryList maWQList; /// List of the web query objects.
+};
+
+// Decryption =================================================================
+
+/** Provides static functions to import stream decryption settings. */
+class XclImpDecryptHelper : ScfNoInstance
+{
+public:
+ /** Reads the FILEPASS record, queries a password and sets decryption algorihm.
+ @return Error code that may cause an error message after import. */
+ static ErrCode ReadFilepass( XclImpStream& rStrm );
+};
+
+// ============================================================================
+
+// 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/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx
new file mode 100644
index 000000000000..0167d160f297
--- /dev/null
+++ b/sc/source/filter/inc/xiescher.hxx
@@ -0,0 +1,1275 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIESCHER_HXX
+#define SC_XIESCHER_HXX
+
+#include <vector>
+#include <map>
+#include <filter/msfilter/msdffimp.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <vcl/graph.hxx>
+#include "xlescher.hxx"
+#include "xiroot.hxx"
+#include "xistring.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace drawing { class XShape; }
+ namespace form { class XForm; }
+} } }
+
+class SdrObjList;
+class ScfProgressBar;
+class ScfPropertySet;
+class XclImpChart;
+class XclImpDffConverter;
+class XclImpDrawing;
+
+// Drawing objects ============================================================
+
+class XclImpDrawObjBase;
+typedef ScfRef< XclImpDrawObjBase > XclImpDrawObjRef;
+
+/** Base class for drawing objects (OBJ records). */
+class XclImpDrawObjBase : protected XclImpRoot
+{
+public:
+ explicit XclImpDrawObjBase( const XclImpRoot& rRoot );
+ virtual ~XclImpDrawObjBase();
+
+ /** Reads the BIFF3 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads the BIFF4 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads the BIFF5 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads the BIFF8 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm );
+
+ /** Sets whether this is an area object (then its width and height must be greater than 0). */
+ inline void SetAreaObj( bool bAreaObj ) { mbAreaObj = bAreaObj; }
+ /** If set to true, a new SdrObject will be created while in DFF import. */
+ inline void SetSimpleMacro( bool bMacro ) { mbSimpleMacro = bMacro; }
+
+ /** Sets the object anchor explicitly. */
+ void SetAnchor( const XclObjAnchor& rAnchor );
+ /** Sets shape data from DFF stream. */
+ void SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin );
+
+ /** If set to false, the SdrObject will not be created, processed, or inserted into the draw page. */
+ inline void SetProcessSdrObj( bool bProcess ) { mbProcessSdr = bProcess; }
+ /** If set to false, the SdrObject will be created or processed, but not be inserted into the draw page. */
+ inline void SetInsertSdrObj( bool bInsert ) { mbInsertSdr = bInsert; }
+ /** If set to true, a new SdrObject will be created while in DFF import. */
+ inline void SetCustomDffObj( bool bCustom ) { mbCustomDff = bCustom; }
+
+ /** Returns the sheet index and Excel object identifier from OBJ record. */
+ inline sal_uInt16 GetObjId() const { return mnObjId; }
+ /** Returns the Excel object type from OBJ record. */
+ inline sal_uInt16 GetObjType() const { return mnObjType; }
+ /** Returns the name of this object, may generate a default name. */
+ String GetObjName() const;
+ /** Returns associated macro name, if set, otherwise zero length string. */
+ inline const String& GetMacroName() const { return maMacroName; }
+
+ /** Returns the shape identifier used in the DFF stream. */
+ inline sal_uInt32 GetDffShapeId() const { return mnDffShapeId; }
+ /** Returns the shape flags from the DFF stream. */
+ inline sal_uInt32 GetDffFlags() const { return mnDffFlags; }
+
+ /** Returns true, if the object is hidden. */
+ inline bool IsHidden() const { return mbHidden; }
+ /** Returns true, if the object is visible. */
+ inline bool IsVisible() const { return mbVisible; }
+ /** Returns true, if the object is printable. */
+ inline bool IsPrintable() const { return mbPrintable; }
+
+ /** Returns the object anchor if existing, null otherwise. */
+ const XclObjAnchor* GetAnchor() const;
+ /** Returns true, if the passed size is valid for this object. */
+ bool IsValidSize( const Rectangle& rAnchorRect ) const;
+ /** Returns the range in the sheet covered by this object. */
+ ScRange GetUsedArea( SCTAB nScTab ) const;
+
+ /** Returns true, if the object is valid and will be processed. */
+ inline bool IsProcessSdrObj() const { return mbProcessSdr && !mbHidden; }
+ /** Returns true, if the SdrObject will be created or processed, but not be inserted into the draw page. */
+ inline bool IsInsertSdrObj() const { return mbInsertSdr; }
+
+ /** Returns the needed size on the progress bar (calls virtual DoGetProgressSize() function). */
+ sal_Size GetProgressSize() const;
+ /** Creates and returns an SdrObject from the contained data. Caller takes ownership! */
+ SdrObject* CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const;
+ /** Additional processing for the passed SdrObject before insertion into
+ the drawing page (calls virtual DoPreProcessSdrObj() function). */
+ void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+ /** Additional processing for the passed SdrObject after insertion into the
+ drawing page (calls virtual DoPostProcessSdrObj() function). */
+ void PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+protected:
+ /** Reads the object name in a BIFF5 OBJ record. */
+ void ReadName5( XclImpStream& rStrm, sal_uInt16 nNameLen );
+ /** Reads the macro link in a BIFF3 OBJ record. */
+ void ReadMacro3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the macro link in a BIFF4 OBJ record. */
+ void ReadMacro4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the macro link in a BIFF5 OBJ record. */
+ void ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the ftMacro sub structure in an OBJ record. */
+ void ReadMacro8( XclImpStream& rStrm );
+
+ /** Converts the passed line formatting to the passed SdrObject. */
+ void ConvertLineStyle( SdrObject& rSdrObj, const XclObjLineData& rLineData ) const;
+ /** Converts the passed fill formatting to the passed SdrObject. */
+ void ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillData& rFillData ) const;
+ /** Converts the passed frame flags to the passed SdrObject. */
+ void ConvertFrameStyle( SdrObject& rSdrObj, sal_uInt16 nFrameFlags ) const;
+
+ /** Returns a solid line color from the passed line data struct. */
+ Color GetSolidLineColor( const XclObjLineData& rLineData ) const;
+ /** Returns a solid fill color from the passed fill data struct. */
+ Color GetSolidFillColor( const XclObjFillData& rFillData ) const;
+
+ /** Derived classes read the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Derived classes read the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Derived classes read the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Derived classes read the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+
+ /** Derived classes may return a progress bar size different from 1. */
+ virtual sal_Size DoGetProgressSize() const;
+ /** Derived classes create and return a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Derived classes may perform additional processing for the passed SdrObject before insertion. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+ /** Derived classes may perform additional processing for the passed SdrObject after insertion. */
+ virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ /** Reads the contents of a BIFF3 OBJ record. */
+ void ImplReadObj3( XclImpStream& rStrm );
+ /** Reads the contents of a BIFF4 OBJ record. */
+ void ImplReadObj4( XclImpStream& rStrm );
+ /** Reads the contents of a BIFF5 OBJ record. */
+ void ImplReadObj5( XclImpStream& rStrm );
+ /** Reads the contents of a BIFF8 OBJ record. */
+ void ImplReadObj8( XclImpStream& rStrm );
+
+private:
+ XclObjAnchor maAnchor; /// The position of the object in its parent.
+ sal_uInt16 mnObjId; /// The object identifier (unique per drawing).
+ sal_uInt16 mnObjType; /// The Excel object type from OBJ record.
+ sal_uInt32 mnDffShapeId; /// Shape ID from DFF stream.
+ sal_uInt32 mnDffFlags; /// Shape flags from DFF stream.
+ String maObjName; /// Name of the object.
+ String maMacroName; /// Name of an attached macro.
+ String maHyperlink; /// On-click hyperlink URL.
+ bool mbHasAnchor; /// true = maAnchor is initialized.
+ bool mbHidden; /// true = Object is hidden.
+ bool mbVisible; /// true = Object is visible.
+ bool mbPrintable; /// true = Object is printable.
+ bool mbAreaObj; /// true = Width and height must be greater than 0.
+ bool mbAutoMargin; /// true = Set automatic text margin.
+ bool mbSimpleMacro; /// true = Create simple macro link and hyperlink.
+ bool mbProcessSdr; /// true = Object is valid, do processing and insertion.
+ bool mbInsertSdr; /// true = Insert the SdrObject into draw page.
+ bool mbCustomDff; /// true = Recreate SdrObject in DFF import.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclImpDrawObjVector : public ::std::vector< XclImpDrawObjRef >
+{
+public:
+ inline explicit XclImpDrawObjVector() {}
+
+ /** Tries to insert the passed object into the last group or appends it. */
+ void InsertGrouped( XclImpDrawObjRef xDrawObj );
+
+ /** Returns the needed size on the progress bar for all contained objects. */
+ sal_Size GetProgressSize() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A placeholder object for unknown object types. */
+class XclImpPhObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpPhObj( const XclImpRoot& rRoot );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A group object. */
+class XclImpGroupObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpGroupObj( const XclImpRoot& rRoot );
+
+ /** Tries to insert the drawing object into this or a nested group. */
+ bool TryInsert( XclImpDrawObjRef xDrawObj );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Returns a progress bar size that takes all group children into account. */
+ virtual sal_Size DoGetProgressSize() const;
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclImpDrawObjVector maChildren; /// Grouped objects.
+ sal_uInt16 mnFirstUngrouped; /// Object identfier of first object not grouped into this group.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A line object. */
+class XclImpLineObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpLineObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclObjLineData maLineData; /// BIFF5 line formatting.
+ sal_uInt16 mnArrows; /// Line arrows.
+ sal_uInt8 mnStartPoint; /// Starting point.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A rectangle or oval object. */
+class XclImpRectObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpRectObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads fil data, line data, and frame flags. */
+ void ReadFrameData( XclImpStream& rStrm );
+
+ /** Converts fill formatting, line formattind, and frame style. */
+ void ConvertRectStyle( SdrObject& rSdrObj ) const;
+
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclObjFillData maFillData; /// BIFF5 fill formatting.
+ XclObjLineData maLineData; /// BIFF5 line formatting.
+ sal_uInt16 mnFrameFlags; /// Additional flags.
+};
+
+// ----------------------------------------------------------------------------
+
+/** An oval object. */
+class XclImpOvalObj : public XclImpRectObj
+{
+public:
+ explicit XclImpOvalObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** An arc object. */
+class XclImpArcObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpArcObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclObjFillData maFillData; /// BIFF5 fill formatting.
+ XclObjLineData maLineData; /// BIFF5 line formatting.
+ sal_uInt8 mnQuadrant; /// Visible quadrant of the circle.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A polygon object. */
+class XclImpPolygonObj : public XclImpRectObj
+{
+public:
+ explicit XclImpPolygonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the COORDLIST record following the OBJ record. */
+ void ReadCoordList( XclImpStream& rStrm );
+
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ typedef ::std::vector< Point > PointVector;
+ PointVector maCoords; /// Coordinates relative to bounding rectangle.
+ sal_uInt16 mnPolyFlags; /// Additional flags.
+ sal_uInt16 mnPointCount; /// Polygon point count.
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclImpObjTextData
+{
+ XclObjTextData maData; /// BIFF5 text data.
+ XclImpStringRef mxString; /// Plain or rich string.
+
+ /** Reads a byte string from the passed stream. */
+ void ReadByteString( XclImpStream& rStrm );
+ /** Reads text formatting from the passed stream. */
+ void ReadFormats( XclImpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A drawing object supporting text contents. Used for all simple objects in BIFF8. */
+class XclImpTextObj : public XclImpRectObj
+{
+public:
+ explicit XclImpTextObj( const XclImpRoot& rRoot );
+
+ /** Stores the passed textbox data. */
+ inline void SetTextData( const XclImpObjTextData& rTextData ) { maTextData = rTextData; }
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Inserts the contained text data at the passed object. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+protected:
+ XclImpObjTextData maTextData; /// Textbox data from BIFF5 OBJ or BIFF8 TXO record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A chart object. This is the drawing object wrapper for the chart data. */
+class XclImpChartObj : public XclImpRectObj
+{
+public:
+ /** @param bOwnTab True = chart is on an own sheet; false = chart is an embedded object. */
+ explicit XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab = false );
+
+ /** Reads the complete chart substream (BOF/EOF block). */
+ void ReadChartSubStream( XclImpStream& rStrm );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Returns the needed size on the progress bar. */
+ virtual sal_Size DoGetProgressSize() const;
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Converts the chart document. */
+ virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ /** Calculates the object anchor of a sheet chart (chart fills one page). */
+ void FinalizeTabChart();
+
+private:
+ typedef ScfRef< XclImpChart > XclImpChartRef;
+
+ XclImpChartRef mxChart; /// The chart itself (BOF/EOF substream data).
+ bool mbOwnTab; /// true = own sheet; false = embedded object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A note object, which is a specialized text box objext. */
+class XclImpNoteObj : public XclImpTextObj
+{
+public:
+ explicit XclImpNoteObj( const XclImpRoot& rRoot );
+
+ /** Sets note flags and the note position in the Calc sheet. */
+ void SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags );
+
+protected:
+ /** Inserts the note into the document, sets visibility. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ ScAddress maScPos; /// Cell position of the note object.
+ sal_uInt16 mnNoteFlags; /// Flags from NOTE record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Helper base class for TBX and OCX form controls to manage spreadsheet links. */
+class XclImpControlHelper
+{
+public:
+ explicit XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode );
+ virtual ~XclImpControlHelper();
+
+ /** Returns true, if a linked cell address is present. */
+ inline bool HasCellLink() const { return mxCellLink.is(); }
+ /** Returns true, if a linked source cell range is present. */
+ inline bool HasSourceRange() const { return mxSrcRange.is(); }
+
+ /** Returns the SdrObject from the passed control shape and sets the bounding rectangle. */
+ SdrObject* CreateSdrObjectFromShape(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const Rectangle& rAnchorRect ) const;
+
+ /** Sets additional properties to the form control model, calls virtual DoProcessControl(). */
+ void ProcessControl( const XclImpDrawObjBase& rDrawObj ) const;
+
+protected:
+ /** Reads the formula for the linked cell from the current position of the stream. */
+ void ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize );
+ /** Reads the formula for the source range from the current position of the stream. */
+ void ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize );
+
+ /** Derived classes will set additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+
+private:
+ /** Reads a list of cell ranges from a formula at the current stream position. */
+ void ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm );
+ /** Reads leading formula size and a list of cell ranges from a formula if the leading size is not zero. */
+ void ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize );
+
+private:
+ const XclImpRoot& mrRoot; /// Not derived from XclImpRoot to allow multiple inheritance.
+ mutable ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ mxShape; /// The UNO wrapper of the control shape.
+ ScfRef< ScAddress > mxCellLink; /// Linked cell in the Calc document.
+ ScfRef< ScRange > mxSrcRange; /// Source data range in the Calc document.
+ XclCtrlBindMode meBindMode; /// Value binding mode.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for textbox based form controls. */
+class XclImpTbxObjBase : public XclImpTextObj, public XclImpControlHelper
+{
+public:
+ explicit XclImpTbxObjBase( const XclImpRoot& rRoot );
+
+ /** Sets line and fill formatting from the passed DFF property set. */
+ void SetDffProperties( const DffPropSet& rDffPropSet );
+
+ /** Returns the service name of the control component to be created. */
+ inline ::rtl::OUString GetServiceName() const { return DoGetServiceName(); }
+ /** Fills the passed macro event descriptor. */
+ bool FillMacroDescriptor(
+ ::com::sun::star::script::ScriptEventDescriptor& rDescriptor ) const;
+
+protected:
+ /** Sets control text formatting. */
+ void ConvertFont( ScfPropertySet& rPropSet ) const;
+ /** Sets control label and text formatting. */
+ void ConvertLabel( ScfPropertySet& rPropSet ) const;
+
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Additional processing on the SdrObject, calls new virtual function DoProcessControl(). */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+ /** Derived classes return the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const = 0;
+ /** Derived classes return the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A button control. */
+class XclImpButtonObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpButtonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A checkbox control. */
+class XclImpCheckBoxObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpCheckBoxObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnState;
+ sal_uInt16 mnCheckBoxFlags;
+};
+
+// ----------------------------------------------------------------------------
+
+/** An option button control. */
+class XclImpOptionButtonObj : public XclImpCheckBoxObj
+{
+public:
+ explicit XclImpOptionButtonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnNextInGroup; /// Next option button in a group.
+ sal_uInt16 mnFirstInGroup; /// 1 = Button is the first in a group.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A label control. */
+class XclImpLabelObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpLabelObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A groupbox control. */
+class XclImpGroupBoxObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpGroupBoxObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnGroupBoxFlags;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A dialog control. */
+class XclImpDialogObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpDialogObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** An edit control. */
+class XclImpEditObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpEditObj( const XclImpRoot& rRoot );
+
+protected:
+ /** REturns true, if the field type is numeric. */
+ bool IsNumeric() const;
+
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnContentType;
+ sal_uInt16 mnMultiLine;
+ sal_uInt16 mnScrollBar;
+ sal_uInt16 mnListBoxObjId;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class of scrollable form controls (spin button, scrollbar, listbox, dropdown). */
+class XclImpTbxObjScrollableBase : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpTbxObjScrollableBase( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads scrollbar data. */
+ void ReadSbs( XclImpStream& rStrm );
+
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+
+protected:
+ sal_uInt16 mnValue;
+ sal_uInt16 mnMin;
+ sal_uInt16 mnMax;
+ sal_uInt16 mnStep;
+ sal_uInt16 mnPageStep;
+ sal_uInt16 mnOrient;
+ sal_uInt16 mnThumbWidth;
+ sal_uInt16 mnScrollFlags;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A spinbutton control. */
+class XclImpSpinButtonObj : public XclImpTbxObjScrollableBase
+{
+public:
+ explicit XclImpSpinButtonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A scrollbar control. */
+class XclImpScrollBarObj : public XclImpTbxObjScrollableBase
+{
+public:
+ explicit XclImpScrollBarObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for list controls (listbox, dropdown). */
+class XclImpTbxObjListBase : public XclImpTbxObjScrollableBase
+{
+public:
+ explicit XclImpTbxObjListBase( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads common listbox settings. */
+ void ReadLbsData( XclImpStream& rStrm );
+ /** Sets common listbox/dropdown formatting attributes. */
+ void SetBoxFormatting( ScfPropertySet& rPropSet ) const;
+
+protected:
+ sal_uInt16 mnEntryCount;
+ sal_uInt16 mnSelEntry;
+ sal_uInt16 mnListFlags;
+ sal_uInt16 mnEditObjId;
+ bool mbHasDefFontIdx;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A listbox control. */
+class XclImpListBoxObj : public XclImpTbxObjListBase
+{
+public:
+ explicit XclImpListBoxObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads listbox settings and selection. */
+ void ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft );
+
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ ScfUInt8Vec maSelection;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A dropdown listbox control. */
+class XclImpDropDownObj : public XclImpTbxObjListBase
+{
+public:
+ explicit XclImpDropDownObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Returns the type of the dropdown control. */
+ sal_uInt16 GetDropDownType() const;
+
+ /** Reads dropdown box settings. */
+ void ReadFullLbsData( XclImpStream& rStrm );
+
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnLeft;
+ sal_uInt16 mnTop;
+ sal_uInt16 mnRight;
+ sal_uInt16 mnBottom;
+ sal_uInt16 mnDropDownFlags;
+ sal_uInt16 mnLineCount;
+ sal_uInt16 mnMinWidth;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A picture, an embedded or linked OLE object, or an OCX form control. */
+class XclImpPictureObj : public XclImpRectObj, public XclImpControlHelper
+{
+public:
+ explicit XclImpPictureObj( const XclImpRoot& rRoot );
+
+ /** Returns the graphic imported from the IMGDATA record. */
+ inline const Graphic& GetGraphic() const { return maGraphic; }
+ /** Returns the visible area of the imported graphic. */
+ inline const Rectangle& GetVisArea() const { return maVisArea; }
+
+ /** Returns true, if the OLE object will be shown as symbol. */
+ inline bool IsSymbol() const { return mbSymbol; }
+ /** Returns the storage name for the OLE object. */
+ String GetOleStorageName() const;
+
+ /** Returns true, if this object is an OCX form control. */
+ inline bool IsOcxControl() const { return mbEmbedded && mbControl && mbUseCtlsStrm; }
+ /** Returns the position in the 'Ctls' stream for additional form control data. */
+ inline sal_Size GetCtlsStreamPos() const { return mnCtlsStrmPos; }
+ /** Returns the size in the 'Ctls' stream for additional form control data. */
+ inline sal_Size GetCtlsStreamSize() const { return mnCtlsStrmSize; }
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Overloaded to do additional processing on the SdrObject. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ /** Reads and sets the picture flags from a BIFF3-BIFF5 OBJ picture record. */
+ void ReadFlags3( XclImpStream& rStrm );
+ /** Reads the contents of the OBJFLAGS subrecord. */
+ void ReadFlags8( XclImpStream& rStrm );
+ /** Reads the contents of the OBJPICTFMLA subrecord. */
+ void ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize );
+
+private:
+ Graphic maGraphic; /// Picture or OLE placeholder graphic.
+ Rectangle maVisArea; /// Size of graphic.
+ String maClassName; /// Class name of embedded OLE object.
+ sal_uInt32 mnStorageId; /// Identifier of the storage for this object.
+ sal_Size mnCtlsStrmPos; /// Position in 'Ctls' stream for this control.
+ sal_Size mnCtlsStrmSize; /// Size in 'Ctls' stream for this control.
+ bool mbEmbedded; /// true = Embedded OLE object.
+ bool mbLinked; /// true = Linked OLE object.
+ bool mbSymbol; /// true = Show as symbol.
+ bool mbControl; /// true = Form control, false = OLE object.
+ bool mbUseCtlsStrm; /// true = Form control data in 'Ctls' stream, false = Own storage.
+};
+
+// DFF stream conversion ======================================================
+
+/** The solver container collects all connector rules for connected objects. */
+class XclImpSolverContainer : public SvxMSDffSolverContainer
+{
+public:
+//UNUSED2009-05 /** Reads the entire solver container. Stream must point to begin of container header. */
+//UNUSED2009-05 void ReadSolverContainer( SvStream& rDffStrm );
+
+ /** Inserts information about a new SdrObject. */
+ void InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags );
+ /** Removes inforamtion of an SdrObject (and all child objects if it is a group). */
+ void RemoveSdrObjectInfo( SdrObject& rSdrObj );
+
+ /** Inserts the SdrObject pointers into all connector rules. */
+ void UpdateConnectorRules();
+ /** Removes all contained connector rules. */
+ void RemoveConnectorRules();
+
+private:
+ /** Returns the first connector rule from the internal list. */
+ SvxMSDffConnectorRule* GetFirstRule();
+ /** Returns the next connector rule from the internal list. */
+ SvxMSDffConnectorRule* GetNextRule();
+ /** Updates the data of a connected shape in a connector rule. */
+ void UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags = 0 );
+
+private:
+ /** Stores data about an SdrObject processed during import. */
+ struct XclImpSdrInfo
+ {
+ SdrObject* mpSdrObj; /// Pointer to an SdrObject.
+ sal_uInt32 mnDffFlags; /// Shape flags from DFF stream.
+ inline explicit XclImpSdrInfo() : mpSdrObj( 0 ), mnDffFlags( 0 ) {}
+ inline void Set( SdrObject* pSdrObj, sal_uInt32 nDffFlags )
+ { mpSdrObj = pSdrObj; mnDffFlags = nDffFlags; }
+ };
+ typedef ::std::map< sal_uInt32, XclImpSdrInfo > XclImpSdrInfoMap;
+ typedef ::std::map< SdrObject*, sal_uInt32 > XclImpSdrObjMap;
+
+ XclImpSdrInfoMap maSdrInfoMap; /// Maps shape IDs to SdrObjects and flags.
+ XclImpSdrObjMap maSdrObjMap; /// Maps SdrObjects to shape IDs.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Simple implementation of the SVX DFF manager. Implements resolving palette
+ colors. Used by XclImpDffPropSet (as is), extended by XclImpDffConverter.
+ */
+class XclImpSimpleDffConverter : public SvxMSDffManager, protected XclImpRoot
+{
+public:
+ explicit XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm );
+ virtual ~XclImpSimpleDffConverter();
+
+protected:
+ /** Returns a color from the Excel color palette. */
+ virtual FASTBOOL GetColorFromPalette( USHORT nIndex, Color& rColor ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** This is the central instance for converting binary DFF data into shape
+ objects. Used for all sheet shapes and shapes embedded in chart objects.
+
+ The class derives from SvxMSDffManager and SvxMSConvertOCXControls and
+ contains core implementation of DFF stream import and OCX form control
+ import.
+ */
+class XclImpDffConverter : public XclImpSimpleDffConverter, private SvxMSConvertOCXControls
+{
+public:
+ explicit XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm );
+ virtual ~XclImpDffConverter();
+
+ /** Initializes the internal progress bar with the passed size and starts it. */
+ void StartProgressBar( sal_Size nProgressSize );
+ /** Increase the progress bar by the passed value. */
+ void Progress( sal_Size nDelta = 1 );
+
+ /** Initially called before the objects of the passed drawing manager are converted. */
+ void InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage );
+ /** Processes BIFF5 drawing objects without DFF data, inserts into the passed object list. */
+ void ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj );
+ /** Processes all objects in the passed list. */
+ void ProcessDrawing( const XclImpDrawObjVector& rDrawObjs );
+ /** Processes a drawing container in the passed DFF stream, converts all objects. */
+ void ProcessDrawing( SvStream& rDffStrm );
+ /** Finally called after the objects of the passed drawing manager have been converted. */
+ void FinalizeDrawing();
+
+ /** Creates the SdrObject for the passed Excel TBX form control object. */
+ SdrObject* CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect );
+ /** Creates the SdrObject for the passed Excel OLE object or OCX form control object. */
+ SdrObject* CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect );
+
+ /** Returns true, if the conversion of OLE objects is supported. */
+ bool SupportsOleObjects() const;
+ /** Returns the default text margin in drawing layer units. */
+ inline sal_Int32 GetDefaultTextMargin() const { return mnDefTextMargin; }
+
+private:
+ // virtual functions of SvxMSDffManager
+
+ /** Reads the client anchor from the DFF stream and sets it at the correct object. */
+ virtual void ProcessClientAnchor2(
+ SvStream& rDffStrm,
+ DffRecordHeader& rHeader,
+ void* pClientData,
+ DffObjData& rObjData );
+ /** Processes an DFF object, reads properties from DFF stream. */
+ virtual SdrObject* ProcessObj(
+ SvStream& rDffStrm,
+ DffObjData& rDffObjData,
+ void* pClientData,
+ Rectangle& rTextRect,
+ SdrObject* pOldSdrObj = 0 );
+ /** Returns the BLIP stream position, based on the passed DFF stream position. */
+ virtual ULONG Calc_nBLIPPos( ULONG nOrgVal, ULONG nStreamPos ) const;
+
+ // virtual functions of SvxMSConvertOCXControls
+
+ /** Inserts the passed control rxFComp into the form. Needs call to SetCurrentForm() before. */
+ virtual sal_Bool InsertControl(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::form::XFormComponent >& rxFormComp,
+ const ::com::sun::star::awt::Size& rSize,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::drawing::XShape >* pxShape,
+ BOOL bFloatingCtrl );
+
+private:
+ /** Data per registered drawing manager, will be stacked for recursive calls. */
+ struct XclImpDffConvData
+ {
+ XclImpDrawing& mrDrawing; /// Current drawing container with all drawing objects.
+ SdrModel& mrSdrModel; /// The SdrModel of the drawing manager.
+ SdrPage& mrSdrPage; /// The SdrPage of the drawing manager.
+ XclImpSolverContainer maSolverCont; /// The solver container for connector rules.
+ ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm >
+ mxCtrlForm; /// Controls form of current drawing page.
+ sal_Int32 mnLastCtrlIndex; /// Last insertion index of a form control (for macro events).
+ bool mbHasCtrlForm; /// True = mxCtrlForm is initialized (but maybe still null).
+
+ explicit XclImpDffConvData( XclImpDrawing& rDrawing,
+ SdrModel& rSdrModel, SdrPage& rSdrPage );
+ };
+
+ /** Returns the current drawing manager data struct from top of the stack. */
+ XclImpDffConvData& GetConvData();
+ /** Returns the current drawing manager data struct from top of the stack. */
+ const XclImpDffConvData& GetConvData() const;
+
+ /** Reads contents of a hyperlink property and returns the extracted URL. */
+ String ReadHlinkProperty( SvStream& rDffStrm ) const;
+
+ /** Processes a drawing container (all drawing data of a sheet). */
+ void ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader );
+ /** Processes the global shape group container (all shapes of a sheet). */
+ void ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader );
+ /** Processes the solver container (connectors of a sheet). */
+ void ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader );
+ /** Processes a shape or shape group container (one top-level shape). */
+ void ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader );
+
+ /** Inserts the passed SdrObject into the document. This function takes ownership of pSdrObj! */
+ void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj );
+ /** Initializes the mxCtrlForm referring to the standard controls form. */
+ void InitControlForm();
+
+private:
+ typedef ScfRef< ScfProgressBar > ScfProgressBarRef;
+ typedef ScfRef< XclImpDffConvData > XclImpDffConvDataRef;
+ typedef ::std::vector< XclImpDffConvDataRef > XclImpDffConvDataStack;
+
+ const ::rtl::OUString maStdFormName; /// Standard name of control forms.
+ SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream for OCX form controls.
+ ScfProgressBarRef mxProgress; /// The progress bar used in ProcessObj().
+ XclImpDffConvDataStack maDataStack; /// Stack for registered drawing managers.
+ sal_uInt32 mnOleImpFlags; /// Application OLE import settings.
+ sal_Int32 mnDefTextMargin; /// Default margin in text boxes.
+};
+
+// Drawing manager ============================================================
+
+/** Base class for a container for all objects on a drawing (spreadsheet or
+ embedded chart object). */
+class XclImpDrawing : protected XclImpRoot
+{
+public:
+ explicit XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects );
+ virtual ~XclImpDrawing();
+
+ /** Reads and returns a bitmap from the IMGDATA record. */
+ static Graphic ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm );
+
+ /** Reads a plain OBJ record (without leading DFF data). */
+ void ReadObj( XclImpStream& rStrm );
+ /** Reads the MSODRAWING or MSODRAWINGSELECTION record. */
+ void ReadMsoDrawing( XclImpStream& rStrm );
+
+ /** Returns true, if the conversion of OLE objects is supported. */
+ inline bool SupportsOleObjects() const { return mbOleObjs; }
+ /** Finds the OBJ record data related to the DFF shape at the passed position. */
+ XclImpDrawObjRef FindDrawObj( const DffRecordHeader& rHeader ) const;
+ /** Finds the OBJ record data specified by the passed object identifier. */
+ XclImpDrawObjRef FindDrawObj( sal_uInt16 nObjId ) const;
+ /** Finds the textbox data related to the DFF shape at the passed position. */
+ const XclImpObjTextData* FindTextData( const DffRecordHeader& rHeader ) const;
+
+ /** Sets the object with the passed identification to be skipped on import. */
+ void SetSkipObj( sal_uInt16 nObjId );
+ /** Returns the size of the progress bar shown while processing all objects. */
+ sal_Size GetProgressSize() const;
+
+ /** Derived classes calculate the resulting rectangle of the passed anchor. */
+ virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const = 0;
+ /** Called whenever an object has been inserted into the draw page. */
+ virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) = 0;
+
+protected:
+ /** Appends a new drawing object to the list of raw objects (without DFF data). */
+ void AppendRawObject( const XclImpDrawObjRef& rxDrawObj );
+ /** Converts all objects and inserts them into the current drawing page. */
+ void ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage );
+
+private:
+ /** Reads and returns a bitmap from WMF/PICT format. */
+ static void ReadWmf( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads and returns a bitmap from BMP format. */
+ static void ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm );
+
+ /** Reads contents of an DFF record and append data to internal DFF stream. */
+ void ReadDffRecord( XclImpStream& rStrm );
+ /** Reads a BIFF8 OBJ record following an MSODRAWING record. */
+ void ReadObj8( XclImpStream& rStrm );
+ /** Reads the TXO record and following CONTINUE records containing string and formatting. */
+ void ReadTxo( XclImpStream& rStrm );
+
+private:
+ typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap;
+ typedef ::std::map< sal_uInt16, XclImpDrawObjRef > XclImpObjMapById;
+ typedef ScfRef< XclImpObjTextData > XclImpObjTextRef;
+ typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap;
+
+ XclImpDrawObjVector maRawObjs; /// BIFF5 objects without DFF data.
+ SvMemoryStream maDffStrm; /// Copy of the DFF page stream in memory.
+ XclImpObjMap maObjMap; /// Maps BIFF8 drawing objects to DFF stream position.
+ XclImpObjMapById maObjMapId; /// Maps BIFF8 drawing objects to object ID.
+ XclImpObjTextMap maTextMap; /// Maps BIFF8 TXO textbox data to DFF stream position.
+ ScfUInt16Vec maSkipObjs; /// IDs of all objects to be skipped.
+ bool mbOleObjs; /// True = draw model supports OLE objects.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Drawing manager of a single sheet. */
+class XclImpSheetDrawing : public XclImpDrawing
+{
+public:
+ explicit XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab );
+
+ /** Reads the NOTE record. */
+ void ReadNote( XclImpStream& rStrm );
+ /** Inserts a new chart object and reads the chart substream (BOF/EOF block).
+ @descr Used to import chart sheets, which do not have a corresponding OBJ record. */
+ void ReadTabChart( XclImpStream& rStrm );
+
+ /** Returns the total cell range covered by any shapes in the sheet. */
+ inline const ScRange& GetUsedArea() const { return maScUsedArea; }
+ /** Converts all objects and inserts them into the sheet drawing page. */
+ void ConvertObjects( XclImpDffConverter& rDffConv );
+
+ /** Calculate the resulting rectangle of the passed anchor. */
+ virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const;
+ /** On call, updates the used area of the sheet. */
+ virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj );
+
+private:
+ /** Reads a BIFF3-BIFF5 NOTE record. */
+ void ReadNote3( XclImpStream& rStrm );
+ /** Reads a BIFF8 NOTE record. */
+ void ReadNote8( XclImpStream& rStrm );
+
+private:
+ ScRange maScUsedArea; /// Sheet index and used area in this sheet.
+};
+
+// The object manager =========================================================
+
+/** Stores all drawing and OLE objects and additional data related to these objects. */
+class XclImpObjectManager : protected XclImpRoot
+{
+public:
+ explicit XclImpObjectManager( const XclImpRoot& rRoot );
+ virtual ~XclImpObjectManager();
+
+ /** Reads the MSODRAWINGGROUP record. */
+ void ReadMsoDrawingGroup( XclImpStream& rStrm );
+
+ /** Returns (initially creates) the drawing manager of the specified sheet. */
+ XclImpSheetDrawing& GetSheetDrawing( SCTAB nScTab );
+ /** Inserts all objects into the Calc document. */
+ void ConvertObjects();
+
+ /** Returns the default name for the passed object. */
+ String GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const;
+ /** Returns the used area in the sheet with the passed index. */
+ ScRange GetUsedArea( SCTAB nScTab ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::map< sal_uInt16, String > DefObjNameMap;
+ typedef ScfRef< XclImpSheetDrawing > XclImpSheetDrawingRef;
+ typedef ::std::map< SCTAB, XclImpSheetDrawingRef > XclImpSheetDrawingMap;
+
+ DefObjNameMap maDefObjNames; /// Default base names for all object types.
+ SvMemoryStream maDggStrm; /// Copy of global DFF data (DGG container) in memory.
+ XclImpSheetDrawingMap maSheetDrawings; /// Drawing managers of all sheets.
+};
+
+// DFF property set helper ====================================================
+
+/** This class reads an DFF property set (msofbtOPT record).
+
+ It can return separate property values or an item set which contains items
+ translated from these properties.
+ */
+class XclImpDffPropSet : protected XclImpRoot
+{
+public:
+ explicit XclImpDffPropSet( const XclImpRoot& rRoot );
+
+ /** Reads an DFF property set from the stream.
+ @descr The stream must point to the start of an DFF record containing properties. */
+ void Read( XclImpStream& rStrm );
+
+ /** Returns the specified property or the default value, if not extant. */
+ sal_uInt32 GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault = 0 ) const;
+
+ /** Translates the properties and fills the item set. */
+ void FillToItemSet( SfxItemSet& rItemSet ) const;
+
+private:
+ typedef ::std::auto_ptr< SvMemoryStream > SvMemoryStreamPtr;
+
+ SvMemoryStream maDummyStrm; /// Dummy DGG stream for DFF manager.
+ XclImpSimpleDffConverter maDffConv; /// DFF converter used to resolve palette colors.
+ SvMemoryStreamPtr mxMemStrm; /// Helper stream.
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet );
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xiformula.hxx b/sc/source/filter/inc/xiformula.hxx
new file mode 100644
index 000000000000..6151222746cd
--- /dev/null
+++ b/sc/source/filter/inc/xiformula.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIFORMULA_HXX
+#define SC_XIFORMULA_HXX
+
+#include "xlformula.hxx"
+#include "xiroot.hxx"
+
+// Formula compiler ===========================================================
+
+class ScRangeList;
+class XclImpFmlaCompImpl;
+
+/** The formula compiler to create Calc token arrays from Excel token arrays. */
+class XclImpFormulaCompiler : protected XclImpRoot
+{
+public:
+ explicit XclImpFormulaCompiler( const XclImpRoot& rRoot );
+ virtual ~XclImpFormulaCompiler();
+
+ /** Creates a range list from the passed Excel token array.
+ @param rStrm Stream pointing to additional formula data (e.g. constant array data). */
+ void CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType eType,
+ const XclTokenArray& rXclTokArr, XclImpStream& rStrm );
+
+ /**
+ * Creates a formula token array from the Excel token array. Note that
+ * the caller must create a copy of the token array instance returend by
+ * this function if the caller needs to persistently store the array,
+ * because the pointer points to an array instance on the stack.
+ */
+ const ScTokenArray* CreateFormula( XclFormulaType eType, const XclTokenArray& rXclTokArr );
+
+private:
+ typedef ScfRef< XclImpFmlaCompImpl > XclImpFmlaCompImplRef;
+ XclImpFmlaCompImplRef mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xihelper.hxx b/sc/source/filter/inc/xihelper.hxx
new file mode 100644
index 000000000000..05412c306c0c
--- /dev/null
+++ b/sc/source/filter/inc/xihelper.hxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIHELPER_HXX
+#define SC_XIHELPER_HXX
+
+#include <editeng/editdata.hxx>
+#include "scmatrix.hxx"
+#include "xladdress.hxx"
+#include "xiroot.hxx"
+#include "xistring.hxx"
+
+// Excel->Calc cell address/range conversion ==================================
+
+/** Provides functions to convert Excel cell addresses to Calc cell addresses. */
+class XclImpAddressConverter : public XclAddressConverterBase
+{
+public:
+ explicit XclImpAddressConverter( const XclImpRoot& rRoot );
+
+ // cell address -----------------------------------------------------------
+
+ /** Checks if the passed Excel cell address is valid.
+ @param rXclPos The Excel cell address to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is not valid.
+ @return true = Cell address in rXclPos is valid. */
+ bool CheckAddress( const XclAddress& rXclPos, bool bWarn );
+
+ /** Converts the passed Excel cell address to a Calc cell address.
+ @param rScPos (Out) The converted Calc cell address, if valid.
+ @param rXclPos The Excel cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is invalid.
+ @return true = Cell address returned in rScPos is valid. */
+ bool ConvertAddress( ScAddress& rScPos,
+ const XclAddress& rXclPos, SCTAB nScTab, bool bWarn );
+
+ /** Returns a valid cell address by moving it into allowed dimensions.
+ @param rXclPos The Excel cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is invalid.
+ @return The converted Calc cell address. */
+ ScAddress CreateValidAddress( const XclAddress& rXclPos,
+ SCTAB nScTab, bool bWarn );
+
+ // cell range -------------------------------------------------------------
+
+ /** Checks if the passed cell range is valid (checks start and end position).
+ @param rXclRange The Excel cell range to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range is not valid.
+ @return true = Cell range in rXclRange is valid. */
+ bool CheckRange( const XclRange& rXclRange, bool bWarn );
+
+ /** Converts the passed Excel cell range to a Calc cell range.
+ @param rScRange (Out) The converted Calc cell range, if valid.
+ @param rXclRange The Excel cell range to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range contains invalid cells.
+ @return true = Cell range returned in rScRange is valid (original or cropped). */
+ bool ConvertRange( ScRange& rScRange, const XclRange& rXclRange,
+ SCTAB nScTab1, SCTAB nScTab2, bool bWarn );
+
+//UNUSED2009-05 /** Returns a valid cell range by moving it into allowed dimensions.
+//UNUSED2009-05 @descr The start and/or end position of the range may be modified.
+//UNUSED2009-05 @param rXclRange The Excel cell range to convert.
+//UNUSED2009-05 @param bWarn true = Sets the internal flag that produces a warning box
+//UNUSED2009-05 after loading/saving the file, if the cell range contains invalid cells.
+//UNUSED2009-05 @return The converted Calc cell range. */
+//UNUSED2009-05 ScRange CreateValidRange( const XclRange& rXclRange,
+//UNUSED2009-05 SCTAB nScTab1, SCTAB nScTab2, bool bWarn );
+
+ // cell range list --------------------------------------------------------
+
+//UNUSED2009-05 /** Checks if the passed cell range list is valid.
+//UNUSED2009-05 @param rXclRanges The Excel cell range list to check.
+//UNUSED2009-05 @param bWarn true = Sets the internal flag that produces a warning box
+//UNUSED2009-05 after loading/saving the file, if the cell range list contains at
+//UNUSED2009-05 least one invalid range.
+//UNUSED2009-05 @return true = Cell range list in rScRanges is completly valid. */
+//UNUSED2009-05 bool CheckRangeList( const XclRangeList& rXclRanges, bool bWarn );
+
+ /** Converts the passed Excel cell range list to a Calc cell range list.
+ @descr The start position of the ranges will not be modified. Cell
+ ranges that fit partly into valid dimensions are cropped
+ accordingly. Cell ranges that do not fit at all, are not inserted
+ into the Calc cell range list.
+ @param rScRanges (Out) The converted Calc cell range list.
+ @param rXclRanges The Excel cell range list to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if at least one of the cell ranges
+ contains invalid cells. */
+ void ConvertRangeList( ScRangeList& rScRanges,
+ const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn );
+};
+
+// String->EditEngine conversion ==============================================
+
+class ScBaseCell;
+class EditTextObject;
+
+/** This class provides methods to convert an XclImpString.
+ @The string can be converted to an edit engine text object or directly
+ to a Calc edit cell. */
+class XclImpStringHelper : ScfNoInstance
+{
+public:
+ /** Returns a new edit engine text object.
+ @param nXFIndex Index to XF for first text portion (for escapement). */
+ static EditTextObject* CreateTextObject(
+ const XclImpRoot& rRoot,
+ const XclImpString& rString );
+
+//UNUSED2009-05 /** Returns a new edit engine text object for a cell note.
+//UNUSED2009-05 @param nXFIndex Index to XF for first text portion (for escapement). */
+//UNUSED2009-05 static EditTextObject* CreateNoteObject(
+//UNUSED2009-05 const XclImpRoot& rRoot,
+//UNUSED2009-05 const XclImpString& rString );
+
+ /** Creates a new text cell or edit cell for a Calc document.
+ @param nXFIndex Index to XF for first text portion (for escapement). */
+ static ScBaseCell* CreateCell(
+ const XclImpRoot& rRoot,
+ const XclImpString& rString,
+ sal_uInt16 nXFIndex = 0 );
+};
+
+// Header/footer conversion ===================================================
+
+class EditEngine;
+class EditTextObject;
+class SfxItemSet;
+class SvxFieldItem;
+struct XclFontData;
+
+/** Converts an Excel header/footer string into three edit engine text objects.
+ @descr Header/footer content is divided into three parts: Left, center and
+ right portion. All formatting information is encoded in the Excel string
+ using special character seuences. A control sequence starts with the ampersand
+ character.
+
+ Supported control sequences:
+ &L start of left portion
+ &C start of center portion
+ &R start of right portion
+ &P current page number
+ &N page count
+ &D current date
+ &T current time
+ &A table name
+ &F file name without path (see also &Z&F)
+ &Z file path without file name (converted to full file name, see also &Z&F)
+ &Z&F file path and name
+ &U underlining on/off
+ &E double underlining on/off
+ &S strikeout characters on/off
+ &X superscript on/off
+ &Y subscript on/off
+ &"fontname,fontstyle" use font with name 'fontname' and style 'fontstyle'
+ &fontheight set font height in points ('fontheight' is a decimal value)
+
+ Known but unsupported control sequences:
+ &G picture
+ */
+class XclImpHFConverter : protected XclImpRoot, ScfNoCopy
+{
+public:
+ explicit XclImpHFConverter( const XclImpRoot& rRoot );
+ ~XclImpHFConverter();
+
+ /** Parses the passed string and creates three new edit engine text objects. */
+ void ParseString( const String& rHFString );
+
+ /** Creates a ScPageHFItem and inserts it into the passed item set. */
+ void FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const;
+ /** Returns the total height of the converted header or footer in twips. */
+ sal_Int32 GetTotalHeight() const;
+
+private: // types
+ typedef ::std::auto_ptr< XclFontData > XclFontDataPtr;
+
+ /** Enumerates the supported header/footer portions. */
+ enum XclImpHFPortion { EXC_HF_LEFT, EXC_HF_CENTER, EXC_HF_RIGHT, EXC_HF_PORTION_COUNT };
+
+ /** Contains all information about a header/footer portion. */
+ struct XclImpHFPortionInfo
+ {
+ typedef ScfRef< EditTextObject > EditTextObjectRef;
+ EditTextObjectRef mxObj; /// Edit engine text object.
+ ESelection maSel; /// Edit engine selection.
+ sal_Int32 mnHeight; /// Height of previous lines in twips.
+ sal_uInt16 mnMaxLineHt; /// Maximum font height for the current text line.
+ explicit XclImpHFPortionInfo();
+ };
+ typedef ::std::vector< XclImpHFPortionInfo > XclImpHFPortionInfoVec;
+
+private:
+ /** Returns the current edit engine text object. */
+ inline XclImpHFPortionInfo& GetCurrInfo() { return maInfos[ meCurrObj ]; }
+ /** Returns the current edit engine text object. */
+ inline XclImpHFPortionInfo::EditTextObjectRef& GetCurrObj() { return GetCurrInfo().mxObj; }
+ /** Returns the current selection. */
+ inline ESelection& GetCurrSel() { return GetCurrInfo().maSel; }
+
+ /** Returns the maximum line height of the specified portion. */
+ sal_uInt16 GetMaxLineHeight( XclImpHFPortion ePortion ) const;
+ /** Returns the current maximum line height. */
+ sal_uInt16 GetCurrMaxLineHeight() const;
+
+ /** Updates the maximum line height of the specified portion, using the current font size. */
+ void UpdateMaxLineHeight( XclImpHFPortion ePortion );
+ /** Updates the current maximum line height, using the current font size. */
+ void UpdateCurrMaxLineHeight();
+
+ /** Sets the font attributes at the current selection.
+ @descr After that, the start position of the current selection object is
+ adjusted to the end of the selection. */
+ void SetAttribs();
+ /** Resets font data to application default font. */
+ void ResetFontData();
+
+ /** Inserts maCurrText into edit engine and adjusts the current selection object.
+ @descr The text shall not contain a newline character.
+ The text will be cleared after insertion. */
+ void InsertText();
+ /** Inserts the passed text field and adjusts the current selection object. */
+ void InsertField( const SvxFieldItem& rFieldItem );
+ /** Inserts a line break and adjusts the current selection object. */
+ void InsertLineBreak();
+
+ /** Creates the edit engine text object of current portion from edit engine. */
+ void CreateCurrObject();
+ /** Changes current header/footer portion to eNew.
+ @descr Creates text object of current portion and reinitializes edit engine. */
+ void SetNewPortion( XclImpHFPortion eNew );
+
+private:
+ EditEngine& mrEE; /// The header/footer edit engine.
+ XclImpHFPortionInfoVec maInfos; /// Edit engine text objects for all portions.
+ String maCurrText; /// Current text to insert into edit engine.
+ XclFontDataPtr mxFontData; /// Font data of current text.
+ XclImpHFPortion meCurrObj; /// The current portion.
+};
+
+// URL conversion =============================================================
+
+/** This class contains static methods to decode an URL stored in an Excel file.
+ @descr Excel URLs can contain a sheet name, for instance: path\[test.xls]Sheet1
+ This sheet name will be extracted automatically. */
+class XclImpUrlHelper : ScfNoInstance
+{
+public:
+ /** Decodes an encoded external document URL with optional sheet name.
+ @param rUrl Returns the decoded file name incl. path.
+ @param rTabName Returns the decoded sheet name.
+ @param rbSameWb Returns true, if the URL is a reference to the own workbook.
+ @param rEncodedUrl An encoded URL from Excel. */
+ static void DecodeUrl(
+ String& rUrl,
+ String& rTabName,
+ bool& rbSameWb,
+ const XclImpRoot& rRoot,
+ const String& rEncodedUrl );
+
+ /** Decodes an encoded external document URL without sheet name.
+ @param rUrl Returns the decoded file name incl. path.
+ @param rbSameWb Returns true, if the URL is a reference to the own workbook.
+ @param rEncodedUrl An encoded URL from Excel. */
+ static void DecodeUrl(
+ String& rUrl,
+ bool& rbSameWb,
+ const XclImpRoot& rRoot,
+ const String& rEncodedUrl );
+
+ /** Decodes the passed URL to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ static bool DecodeLink( String& rApplic, String& rTopic, const String rEncUrl );
+};
+
+// Cached values ==============================================================
+
+class ScTokenArray;
+
+/** This class stores one cached value of a cached value list (used for instance in
+ CRN, EXTERNNAME, tArray). */
+class XclImpCachedValue : ScfNoCopy
+{
+public:
+ /** Creates a cached value and reads contents from stream and stores it with its array address. */
+ explicit XclImpCachedValue( XclImpStream& rStrm );
+ virtual ~XclImpCachedValue();
+
+ /** Returns the type of the cached value (EXC_CACHEDVAL_*). */
+ inline sal_uInt8 GetType() const { return mnType; }
+ /** Returns the cached string value, if this value is a string, else an empty string. */
+ inline const String& GetString() const { return mxStr.get() ? *mxStr : EMPTY_STRING; }
+ /** Returns the cached number, if this value has number type, else 0.0. */
+ inline double GetValue() const { return mfValue; }
+ /** Returns the cached Boolean value, if this value has Boolean type, else false. */
+ inline bool GetBool() const { return (mnType == EXC_CACHEDVAL_BOOL) && (mnBoolErr != 0); }
+ /** Returns the cached Calc error code, if this value has Error type, else 0. */
+ inline sal_uInt8 GetXclError() const { return (mnType == EXC_CACHEDVAL_ERROR) ? mnBoolErr : EXC_ERR_NA; }
+ /** Returns the cached Calc error code, if this value has Error type, else 0. */
+ USHORT GetScError() const;
+ /** Returns the token array if this is a Boolean value or error value, else 0. */
+ inline const ScTokenArray* GetBoolErrFmla() const { return mxTokArr.get(); }
+
+protected:
+ typedef ::std::auto_ptr< String > StringPtr;
+ typedef ::std::auto_ptr< const ScTokenArray > ScTokenArrayPtr;
+
+ StringPtr mxStr; /// Cached value is a string.
+ double mfValue; /// Cached value is a double.
+ ScTokenArrayPtr mxTokArr; /// Cached value is a formula or error code or Boolean.
+ sal_uInt8 mnBoolErr; /// Boolean value or Excel error code.
+ sal_uInt8 mnType; /// The type of the cached value (EXC_CACHEDVAL_*).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains cached values in a 2-dimensional array. */
+class XclImpCachedMatrix
+{
+public:
+ explicit XclImpCachedMatrix( XclImpStream& rStrm );
+ ~XclImpCachedMatrix();
+
+ /** Creates a new ScMatrix object and fills it with the contained values. */
+ ScMatrixRef CreateScMatrix() const;
+
+private:
+ typedef ScfDelList< XclImpCachedValue > XclImpValueList;
+
+ XclImpValueList maValueList; /// List of cached cell values.
+ SCSIZE mnScCols; /// Number of cached columns.
+ SCSIZE mnScRows; /// Number of cached rows.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xilink.hxx b/sc/source/filter/inc/xilink.hxx
new file mode 100644
index 000000000000..dbbb4606114e
--- /dev/null
+++ b/sc/source/filter/inc/xilink.hxx
@@ -0,0 +1,210 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XILINK_HXX
+#define SC_XILINK_HXX
+
+#include <map>
+#include "xllink.hxx"
+#include "xiroot.hxx"
+
+/* ============================================================================
+Classes for import of different kinds of internal/external references.
+- 3D cell and cell range links
+- External cell and cell range links
+- External defined names
+- Add-in functions
+- DDE links
+- OLE object links
+============================================================================ */
+
+// Excel sheet indexes ========================================================
+
+/** A buffer containing information about names and creation order of sheets.
+
+ The first purpose of this buffer is to translate original Excel
+ sheet names into Calc sheet indexes. This is not trivial because the filter
+ may rename the Calc sheets during creation. This buffer stores the original
+ Excel sheet names with the corresponding Calc sheet indexes.
+
+ The second purpose is to store the creation order of all sheets inside the
+ Excel workbook. The creation order list is contained in the TABID record
+ and needed to import the change log. Example: If the list contains 3;1;2
+ this means that the second sheet in the file was created first, than the
+ third sheet in the file was created and finally the first sheet.
+ */
+class XclImpTabInfo
+{
+public:
+ // original Excel sheet names ---------------------------------------------
+
+ /** Appends an original Excel sheet name with corresponding Calc sheet index. */
+ void AppendXclTabName( const String& rXclTabName, SCTAB nScTab );
+ /** Inserts a Calc sheet index (increases all following sheet indexes). */
+ void InsertScTab( SCTAB nScTab );
+
+ /** Returns the Calc sheet index from the passed original Excel sheet name. */
+ SCTAB GetScTabFromXclName( const String& rXclTabName ) const;
+
+ // record creation order - TABID record -----------------------------------
+
+ /** Reads the TABID record. */
+ void ReadTabid( XclImpStream& rStrm );
+
+ /** Returns the current sheet index calculated from creation index.
+ @param nCreatedId The creation index of the sheet (1-based).
+ @param nMaxTabId All values greater than this parameter are not used to find the index.
+ @return The 0-based index of the sheet nCreatedId if it is contained in the list.
+ Example: The buffer is 3;5;2;4;1, nCreatedId is 1 and nMaxTabId is 3. The function will
+ return 2 which is the 0-based index of sheet 1 in the list 3;2;1. */
+ sal_uInt16 GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId = 0xFFFF ) const;
+
+private:
+ typedef ::std::map< String, SCTAB > XclTabNameMap;
+
+ XclTabNameMap maTabNames; /// All Excel sheet names with Calc sheet index.
+ ScfUInt16Vec maTabIdVec; /// The vector with sheet indexes.
+};
+
+// External names =============================================================
+
+/** Type of an external name. */
+enum XclImpExtNameType
+{
+ xlExtName, /// An external defined name.
+ xlExtAddIn, /// An add-in function name.
+ xlExtDDE, /// A DDE link range.
+ xlExtOLE, /// An OLE object link.
+ xlExtEuroConvert /// An external in Excel, but internal in OO function name.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclImpCachedMatrix;
+class ScTokenArray;
+class XclImpSupbook;
+
+/** Stores contents of an external name.
+ @descr Supported: External defined names, AddIn names, DDE links and OLE objects. */
+class XclImpExtName
+{
+public:
+ /** Reads the external name from the stream. */
+ explicit XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm,
+ XclSupbookType eSubType, ExcelToSc* pFormulaConv );
+ ~XclImpExtName();
+
+ /** Create and apply the cached list of this DDE Link to the document. */
+ void CreateDdeData( ScDocument& rDoc,
+ const String& rApplc, const String& rExtDoc ) const;
+
+ void CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const;
+
+ bool HasFormulaTokens() const;
+
+ inline XclImpExtNameType GetType() const { return meType; }
+ inline const String& GetName() const { return maName; }
+ inline sal_uInt32 GetStorageId() const { return mnStorageId; }
+
+private:
+ typedef ::std::auto_ptr< XclImpCachedMatrix > XclImpCachedMatrixPtr;
+ typedef ::std::auto_ptr< ScTokenArray > TokenArrayPtr;
+
+ XclImpCachedMatrixPtr mxDdeMatrix; /// Cached results of the DDE link.
+ TokenArrayPtr mxArray; /// Formula tokens for external name.
+ String maName; /// The name of the external name.
+ sal_uInt32 mnStorageId; /// Storage ID for OLE object storages.
+ XclImpExtNameType meType; /// Type of the external name.
+};
+
+// Import link manager ========================================================
+
+class XclImpLinkManagerImpl;
+
+/** This is the central class for the import of all internal/external links.
+ @descr This manager stores all data about external documents with their sheets
+ and cached cell contents. Additionally it handles external names, such as add-in
+ function names, DDE links, and OLE object links.
+ File contents in BIFF8:
+ - Record SUPBOOK: Contains the name of an external document and the names of its sheets.
+ This record is optionally followed by NAME, EXTERNNAME, XCT and CRN records.
+ - Record XCT: Contains the number and sheet index of the following CRN records.
+ - Record CRN: Contains addresses (row and column) and values of external referenced cells.
+ - Record NAME: Contains defined names of the own workbook.
+ - Record EXTERNNAME: Contains external defined names, DDE links, or OLE object links.
+ - Record EXTERNSHEET: Contains indexes to URLs of external documents (SUPBOOKs)
+ and sheet indexes for each external reference used anywhere in the workbook.
+ This record follows a list of SUPBOOK records (with their attached records).
+*/
+class XclImpLinkManager : protected XclImpRoot
+{
+public:
+ explicit XclImpLinkManager( const XclImpRoot& rRoot );
+ ~XclImpLinkManager();
+
+ /** Reads the EXTERNSHEET record. */
+ void ReadExternsheet( XclImpStream& rStrm );
+ /** Reads a SUPBOOK record. */
+ void ReadSupbook( XclImpStream& rStrm );
+ /** Reads an XCT record and appends it to the current SUPBOOK. */
+ void ReadXct( XclImpStream& rStrm );
+ /** Reads a CRN record and appends it to the current SUPBOOK. */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
+ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns true, if the specified XTI entry contains an internal reference. */
+ bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
+ /** Returns the Calc sheet index range of the specified XTI entry.
+ @return true = XTI data found, returned sheet index range is valid. */
+ bool GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
+ sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified external name or 0 on error. */
+ const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
+
+ const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
+
+ const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
+
+ /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified macro name or an empty string on error. */
+ const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
+
+private:
+ typedef ::std::auto_ptr< XclImpLinkManagerImpl > XclImpLinkMgrImplPtr;
+ XclImpLinkMgrImplPtr mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xiname.hxx b/sc/source/filter/inc/xiname.hxx
new file mode 100644
index 000000000000..b5d9ca642d4f
--- /dev/null
+++ b/sc/source/filter/inc/xiname.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XINAME_HXX
+#define SC_XINAME_HXX
+
+#include <map>
+#include "xlname.hxx"
+#include "xiroot.hxx"
+
+//class ScDocument;
+//class ScTokenArray;
+
+// ============================================================================
+
+class ScRangeData;
+
+/** Represents a defined name. It may be related to a single sheet or global. */
+class XclImpName : protected XclImpRoot
+{
+public:
+ explicit XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx );
+
+ inline const String& GetXclName() const { return maXclName; }
+ inline const String& GetScName() const { return maScName; }
+ inline SCTAB GetScTab() const { return mnScTab; }
+ inline const ScRangeData* GetScRangeData() const { return mpScData; }
+ inline bool IsGlobal() const { return mnScTab == SCTAB_MAX; }
+ inline bool IsFunction() const { return mbFunction; }
+ inline bool IsVBName() const { return mbVBName; }
+
+private:
+ String maXclName; /// Original name read from the file.
+ String maScName; /// Name inserted into the Calc document.
+ const ScRangeData* mpScData; /// Pointer to Calc defined name (no ownership).
+ sal_Unicode mcBuiltIn; /// Excel built-in name index.
+ SCTAB mnScTab; /// Calc sheet index of local names.
+ bool mbFunction; /// true = Name refers to a function (add-in or VBA).
+ bool mbVBName; /// true = Visual Basic procedure or function.
+};
+
+// ----------------------------------------------------------------------------
+
+/** This buffer contains all internal defined names of the document.
+ @descr It manages the position of the names in the document, means if they are
+ global or attached to a specific sheet. While inserting the names into the Calc
+ document this buffer resolves conflicts caused by equal names from different
+ sheets. */
+class XclImpNameManager : protected XclImpRoot
+{
+public:
+ explicit XclImpNameManager( const XclImpRoot& rRoot );
+
+ /** Reads a NAME record and creates an entry in this buffer. */
+ void ReadName( XclImpStream& rStrm );
+
+ /** Tries to find the name used in Calc, based on the original Excel defined name.
+ @param nScTab The sheet index for local names or SCTAB_MAX for global names.
+ If no local name is found, tries to find a matching global name.
+ @return Pointer to the defined name or 0 on error. */
+ const XclImpName* FindName( const String& rXclName, SCTAB nScTab = SCTAB_MAX ) const;
+
+ /** Returns the defined name specified by its Excel index.
+ @param nXclNameIdx The index of the internal defined name.
+ @return Pointer to the defined name or 0 on error. */
+ const XclImpName* GetName( sal_uInt16 nXclNameIdx ) const;
+
+private:
+ typedef ScfDelList< XclImpName > XclImpNameList;
+ XclImpNameList maNameList;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xipage.hxx b/sc/source/filter/inc/xipage.hxx
new file mode 100644
index 000000000000..0571e10e7046
--- /dev/null
+++ b/sc/source/filter/inc/xipage.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIPAGE_HXX
+#define SC_XIPAGE_HXX
+
+#include "xlpage.hxx"
+#include "xiroot.hxx"
+
+// Page settings ==============================================================
+
+/** Contains all page (print) settings for a single sheet.
+ @descr Supports reading all related records and creating a page style sheet. */
+class XclImpPageSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpPageSettings( const XclImpRoot& rRoot );
+
+ /** Returns read-only access to the page data. */
+ inline const XclPageData& GetPageData() const { return maData; }
+
+ /** Initializes the object to be used for a new sheet. */
+ void Initialize();
+
+ /** Reads a SETUP record and inserts contained data. */
+ void ReadSetup( XclImpStream& rStrm );
+ /** Reads a ***MARGIN record (reads all 4 margin records). */
+ void ReadMargin( XclImpStream& rStrm );
+ /** Reads a HCENTER or VCENTER record. */
+ void ReadCenter( XclImpStream& rStrm );
+ /** Reads a HEADER or FOOTER record. */
+ void ReadHeaderFooter( XclImpStream& rStrm );
+ /** Reads a HORIZONTALPAGEBREAKS or VERTICALPAGEBREAKS record. */
+ void ReadPageBreaks( XclImpStream& rStrm );
+ /** Reads a PRINTHEADERS record. */
+ void ReadPrintHeaders( XclImpStream& rStrm );
+ /** Reads a PRINTGRIDLINES record. */
+ void ReadPrintGridLines( XclImpStream& rStrm );
+ /** Reads an IMGDATA record and creates the SvxBrushItem. */
+ void ReadImgData( XclImpStream& rStrm );
+
+ /** Overrides paper size and orientation (used in sheet-charts). */
+ void SetPaperSize( sal_uInt16 nXclPaperSize, bool bPortrait );
+ /** Sets or clears the fit-to-pages setting (contained in WSBOOL record). */
+ inline void SetFitToPages( bool bFitToPages ) { maData.mbFitToPages = bFitToPages; }
+
+ /** Creates a page stylesheet from current settings and sets it at current sheet. */
+ void Finalize();
+
+private:
+ XclPageData maData; /// Page settings data.
+ bool mbValidPaper; /// true = Paper size and orientation valid.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx
new file mode 100644
index 000000000000..edac8a0fd99f
--- /dev/null
+++ b/sc/source/filter/inc/xipivot.hxx
@@ -0,0 +1,457 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIPIVOT_HXX
+#define SC_XIPIVOT_HXX
+
+#include <list>
+#include "xlpivot.hxx"
+#include "xiroot.hxx"
+
+class ScDPSaveData;
+class ScDPSaveDimension;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+/** Represents a data item in a pivot cache. */
+class XclImpPCItem : public XclPCItem
+{
+public:
+ explicit XclImpPCItem( XclImpStream& rStrm );
+
+ /** Inserts the item data into the passed document. */
+ void WriteToSource( const XclImpRoot& rRoot, const ScAddress& rScPos ) const;
+
+private:
+ /** Reads an SXDOUBLE record describing a floating-point item. */
+ void ReadSxdouble( XclImpStream& rStrm );
+ /** Reads an SXBOOLEAN record describing a boolean item. */
+ void ReadSxboolean( XclImpStream& rStrm );
+ /** Reads an SXERROR record describing an error code item. */
+ void ReadSxerror( XclImpStream& rStrm );
+ /** Reads an SXINTEGER record describing an integer item. */
+ void ReadSxinteger( XclImpStream& rStrm );
+ /** Reads an SXSTRING record describing a text item. */
+ void ReadSxstring( XclImpStream& rStrm );
+ /** Reads an SXDATETIME record describing a date/time item. */
+ void ReadSxdatetime( XclImpStream& rStrm );
+ /** Reads an SXEMPTY record describing an empty item. */
+ void ReadSxempty( XclImpStream& rStrm );
+};
+
+typedef ScfRef< XclImpPCItem > XclImpPCItemRef;
+
+// ============================================================================
+
+struct ScDPNumGroupInfo;
+class XclImpPivotCache;
+
+/** Represents a field in a pivot cache (a column of data items in the source area). */
+class XclImpPCField : public XclPCField, protected XclImpRoot
+{
+public:
+ /** Creates a pivot cache field by reading an SXFIELD record. */
+ explicit XclImpPCField( const XclImpRoot& rRoot,
+ XclImpPivotCache& rPCache, sal_uInt16 nFieldIdx );
+ virtual ~XclImpPCField();
+
+ // general field/item access ----------------------------------------------
+
+ /** Returns the name of the field, uses the passed visible name if supported. */
+ const String& GetFieldName( const ScfStringVec& rVisNames ) const;
+
+ /** Returns the base field if this is a grouping field. */
+ const XclImpPCField* GetGroupBaseField() const;
+
+ /** Returns the number of items of this field. */
+ sal_uInt16 GetItemCount() const;
+ /** Returns the item at the specified position or 0 on error. */
+ const XclImpPCItem* GetItem( sal_uInt16 nItemIdx ) const;
+ /** Returns the item representing a limit value in numeric/date/time grouping fields.
+ @param nItemIdx One of EXC_SXFIELD_INDEX_MIN, EXC_SXFIELD_INDEX_MAX, or EXC_SXFIELD_INDEX_STEP. */
+ const XclImpPCItem* GetLimitItem( sal_uInt16 nItemIdx ) const;
+
+ /** Inserts the field name into the document. */
+ void WriteFieldNameToSource( SCCOL nScCol, SCTAB nScTab ) const;
+ /** Inserts the specified item data into the document. */
+ void WriteOrigItemToSource( SCROW nScRow, SCTAB nScTab, sal_uInt16 nItemIdx ) const;
+ /** Inserts the data of the last inserted item into the document. */
+ void WriteLastOrigItemToSource( SCROW nScRow, SCTAB nScTab ) const;
+
+ // records ----------------------------------------------------------------
+
+ /** Reads the SXFIELD record describing the field. */
+ void ReadSxfield( XclImpStream& rStrm );
+ /** Reads an item data record describing a new item. */
+ void ReadItem( XclImpStream& rStrm );
+ /** Reads the SXNUMGROUP record describing numeric grouping fields. */
+ void ReadSxnumgroup( XclImpStream& rStrm );
+ /** Reads the SXGROUPINFO record describing the item order in grouping fields. */
+ void ReadSxgroupinfo( XclImpStream& rStrm );
+
+ // grouping ---------------------------------------------------------------
+
+ /** Inserts grouping information of this field into the passed ScDPSaveData. */
+ void ConvertGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ /** Inserts standard grouping information of this field into the passed ScDPSaveData. */
+ void ConvertStdGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+ /** Inserts numeric grouping information of this field into the passed ScDPSaveData. */
+ void ConvertNumGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+ /** Inserts date grouping information of this field into the passed ScDPSaveData. */
+ void ConvertDateGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+
+ /** Returns a Calc struct with numeric grouping data. */
+ ScDPNumGroupInfo GetScNumGroupInfo() const;
+ /** Returns a Calc struct with date grouping data. */
+ ScDPNumGroupInfo GetScDateGroupInfo() const;
+
+ /** Returns a limit value for numeric grouping fields. */
+ const double* GetNumGroupLimit( sal_uInt16 nLimitIdx ) const;
+ /** Returns a limit value for date grouping fields (minimum/maximum only). */
+ const DateTime* GetDateGroupLimit( sal_uInt16 nLimitIdx ) const;
+ /** Returns the step value for date grouping fields. */
+ const sal_Int16* GetDateGroupStep() const;
+
+private:
+ typedef ::std::vector< XclImpPCItemRef > XclImpPCItemVec;
+
+ XclImpPivotCache& mrPCache; /// Parent pivot cache containing this field.
+ XclImpPCItemVec maItems; /// List of all displayed data items.
+ XclImpPCItemVec maOrigItems; /// List of all source data items.
+ XclImpPCItemVec maNumGroupItems; /// List of items containing numeric grouping limits.
+ mutable SCCOL mnSourceScCol; /// Column index of source data for this field.
+ bool mbNumGroupInfoRead; /// true = Numeric grouping info read (SXNUMGROUP record).
+};
+
+typedef ScfRef< XclImpPCField > XclImpPCFieldRef;
+
+// ============================================================================
+
+class XclImpPivotCache : protected XclImpRoot
+{
+public:
+ explicit XclImpPivotCache( const XclImpRoot& rRoot );
+ virtual ~XclImpPivotCache();
+
+ // data access ------------------------------------------------------------
+
+ /** Returns the data source range read from the DCONREF record. */
+ inline const ScRange& GetSourceRange() const { return maSrcRange; }
+
+ /** Returns the number of pivot cache fields. */
+ sal_uInt16 GetFieldCount() const;
+ /** Returns read-only access to a pivot cache field. */
+ const XclImpPCField* GetField( sal_uInt16 nFieldIdx ) const;
+
+ // records ----------------------------------------------------------------
+
+ /** Reads an SXIDSTM record containing a pivot cache stream identifier and the pivot cache. */
+ void ReadSxidstm( XclImpStream& rStrm );
+ /** Reads an SXVS record containing the source type of the pivot cache. */
+ void ReadSxvs( XclImpStream& rStrm );
+ /** Reads a DCONREF record containing the source range of the pivot cache. */
+ void ReadDconref( XclImpStream& rStrm );
+ /** Reads the entire pivot cache stream. Uses decrypter from passed stream. */
+ void ReadPivotCacheStream( XclImpStream& rStrm );
+
+ bool IsRefreshOnLoad() const;
+
+private:
+ typedef ::std::vector< XclImpPCFieldRef > XclImpPCFieldVec;
+
+ XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record).
+ XclImpPCFieldVec maFields; /// List of pivot cache fields.
+ ScRange maSrcRange; /// Source range in the spreadsheet.
+ String maUrl; /// URL of the source data.
+ String maTabName; /// Sheet name of the source data.
+ sal_uInt16 mnStrmId; /// Pivot cache stream identifier.
+ sal_uInt16 mnSrcType; /// Source data type.
+ bool mbSelfRef; /// true = Source data from own document.
+};
+
+typedef ScfRef< XclImpPivotCache > XclImpPivotCacheRef;
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+class XclImpPivotTable;
+
+// ============================================================================
+
+class XclImpPTItem
+{
+public:
+ explicit XclImpPTItem( const XclImpPCField* pCacheField );
+
+ /** Returns the internal name of the item or 0, if no name could be found. */
+ const String* GetItemName() const;
+ /** Returns the displayed name of the item or 0, if no name could be found. */
+ const String* GetVisItemName() const;
+
+ /** Reads an SXVI record containing data of this item. */
+ void ReadSxvi( XclImpStream& rStrm );
+
+ /** Inserts this item into the passed ScDPSaveDimension. */
+ void ConvertItem( ScDPSaveDimension& rSaveDim ) const;
+
+private:
+ XclPTItemInfo maItemInfo; /// General data for this item.
+ const XclImpPCField* mpCacheField; /// Corresponding pivot cache field.
+};
+
+typedef ScfRef< XclImpPTItem > XclImpPTItemRef;
+
+// ============================================================================
+
+class XclImpPTField
+{
+public:
+ explicit XclImpPTField( const XclImpPivotTable& rPTable, sal_uInt16 nCacheIdx );
+
+ // general field/item access ----------------------------------------------
+
+ /** Returns the corresponding pivot cache field of this field. */
+ const XclImpPCField* GetCacheField() const;
+ /** Returns the name of this field that is used to create the Calc dimensions. */
+ const String& GetFieldName() const;
+ /** Returns the internally set visible name of this field. */
+ const String& GetVisFieldName() const;
+
+ /** Returns the specified item. */
+ const XclImpPTItem* GetItem( sal_uInt16 nItemIdx ) const;
+ /** Returns the internal name of the specified item. */
+ const String* GetItemName( sal_uInt16 nItemIdx ) const;
+ /** Returns the displayed name of the specified item. */
+ const String* GetVisItemName( sal_uInt16 nItemIdx ) const;
+
+ /** Returns the flags of the axes this field is part of. */
+ inline sal_uInt16 GetAxes() const { return maFieldInfo.mnAxes; }
+ /** Sets the flags of the axes this field is part of. */
+ inline void SetAxes( sal_uInt16 nAxes ) { maFieldInfo.mnAxes = nAxes; }
+
+ // records ----------------------------------------------------------------
+
+ /** Reads an SXVD record describing the field. */
+ void ReadSxvd( XclImpStream& rStrm );
+ /** Reads an SXVDEX record describing extended options of the field. */
+ void ReadSxvdex( XclImpStream& rStrm );
+ /** Reads an SXVI record describing a new item of this field. */
+ void ReadSxvi( XclImpStream& rStrm );
+
+ // row/column fields ------------------------------------------------------
+
+ void ConvertRowColField( ScDPSaveData& rSaveData ) const;
+
+ // page fields ------------------------------------------------------------
+
+ void SetPageFieldInfo( const XclPTPageFieldInfo& rPageInfo );
+ void ConvertPageField( ScDPSaveData& rSaveData ) const;
+
+ // hidden fields ----------------------------------------------------------
+
+ void ConvertHiddenField( ScDPSaveData& rSaveData ) const;
+
+ // data fields ------------------------------------------------------------
+
+ bool HasDataFieldInfo() const;
+ void AddDataFieldInfo( const XclPTDataFieldInfo& rDataInfo );
+ void ConvertDataField( ScDPSaveData& rSaveData ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ ScDPSaveDimension* ConvertRCPField( ScDPSaveData& rSaveData ) const;
+ void ConvertFieldInfo( ScDPSaveDimension& rSaveDim ) const;
+
+ void ConvertDataField( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const;
+ void ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const;
+ void ConvertItems( ScDPSaveDimension& rSaveDim ) const;
+
+private:
+ typedef ::std::list< XclPTDataFieldInfo > XclPTDataFieldInfoList;
+ typedef ::std::vector< XclImpPTItemRef > XclImpPTItemVec;
+
+ const XclImpPivotTable& mrPTable; /// Parent pivot table containing this field.
+ XclPTFieldInfo maFieldInfo; /// General field info (SXVD record).
+ XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record).
+ XclPTPageFieldInfo maPageInfo; /// Page field info (entry from SXPI record).
+ XclPTDataFieldInfoList maDataInfoList; /// List of extended data field info (SXDI records).
+ XclImpPTItemVec maItems; /// List of all items of this field.
+};
+
+typedef ScfRef< XclImpPTField > XclImpPTFieldRef;
+
+// ============================================================================
+
+class XclImpPivotTable : protected XclImpRoot
+{
+public:
+ explicit XclImpPivotTable( const XclImpRoot& rRoot );
+ virtual ~XclImpPivotTable();
+
+ // cache/field access, misc. ----------------------------------------------
+
+ inline XclImpPivotCacheRef GetPivotCache() const { return mxPCache; }
+ inline const ScfStringVec& GetVisFieldNames() const { return maVisFieldNames; }
+
+ sal_uInt16 GetFieldCount() const;
+ const XclImpPTField* GetField( sal_uInt16 nFieldIdx ) const;
+ XclImpPTField* GetFieldAcc( sal_uInt16 nFieldIdx );
+ const String& GetFieldName( sal_uInt16 nFieldIdx ) const;
+
+ const XclImpPTField* GetDataField( sal_uInt16 nDataFieldIdx ) const;
+ const String& GetDataFieldName( sal_uInt16 nDataFieldIdx ) const;
+
+ // records ----------------------------------------------------------------
+
+ /** Reads an SXVIEW record starting a new pivot table. */
+ void ReadSxview( XclImpStream& rStrm );
+ /** Reads an SXVD record describing a new field. */
+ void ReadSxvd( XclImpStream& rStrm );
+ /** Reads an SXVI record describing a new item of the current field. */
+ void ReadSxvi( XclImpStream& rStrm );
+ /** Reads an SXVDEX record describing extended options of the current field. */
+ void ReadSxvdex( XclImpStream& rStrm );
+ /** Reads an SXIVD record containing the row field or column field order. */
+ void ReadSxivd( XclImpStream& rStrm );
+ /** Reads an SXPI record containing page field data. */
+ void ReadSxpi( XclImpStream& rStrm );
+ /** Reads an SXDI record containing data field data. */
+ void ReadSxdi( XclImpStream& rStrm );
+ /** Reads an SXEX record containing additional settings for the pivot table. */
+ void ReadSxex( XclImpStream& rStrm );
+ /** Reads an SXVIEWEX9 record that specifies the pivot tables
+ * autoformat. */
+ void ReadSxViewEx9( XclImpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+
+ /** Inserts the pivot table into the Calc document. */
+ void Convert();
+
+ void MaybeRefresh();
+
+ void ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData);
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec;
+
+ XclImpPivotCacheRef mxPCache; /// Pivot cache containing field/item names.
+
+ XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record).
+ XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
+ XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record)
+ XclImpPTFieldVec maFields; /// Vector containing all fields.
+ XclImpPTFieldRef mxCurrField; /// Current field for importing additional info.
+ ScfStringVec maVisFieldNames; /// Vector containing all visible field names.
+ ScfUInt16Vec maRowFields; /// Row field indexes.
+ ScfUInt16Vec maColFields; /// Column field indexes.
+ ScfUInt16Vec maPageFields; /// Page field indexes.
+ ScfUInt16Vec maOrigDataFields; /// Original data field indexes.
+ ScfUInt16Vec maFiltDataFields; /// Filtered data field indexes.
+ XclImpPTField maDataOrientField; /// Special data field orientation field.
+ ScRange maOutScRange; /// Output range in the Calc document.
+ ScDPObject* mpDPObj;
+};
+
+typedef ScfRef< XclImpPivotTable > XclImpPivotTableRef;
+
+// ============================================================================
+// ============================================================================
+
+/** The main class for pivot table import.
+
+ This class contains functions to read all records related to pivot tables
+ and pivot caches.
+ */
+class XclImpPivotTableManager : protected XclImpRoot
+{
+public:
+ explicit XclImpPivotTableManager( const XclImpRoot& rRoot );
+ virtual ~XclImpPivotTableManager();
+
+ // pivot cache records ----------------------------------------------------
+
+ /** Returns the pivot cache with the specified 0-based index. */
+ XclImpPivotCacheRef GetPivotCache( sal_uInt16 nCacheIdx );
+
+ /** Reads an SXIDSTM record containing a pivot cache stream identifier and the pivot cache. */
+ void ReadSxidstm( XclImpStream& rStrm );
+ /** Reads an SXVS record containing the source type of a pivot cache. */
+ void ReadSxvs( XclImpStream& rStrm );
+ /** Reads a DCONREF record containing the source range of a pivot cache. */
+ void ReadDconref( XclImpStream& rStrm );
+
+ // pivot table records ----------------------------------------------------
+
+ /** Reads an SXVIEW record describing a new pivot table. */
+ void ReadSxview( XclImpStream& rStrm );
+ /** Reads an SXVD record describing a new field. */
+ void ReadSxvd( XclImpStream& rStrm );
+ /** Reads an SXVDEX record describing extended options of a field. */
+ void ReadSxvdex( XclImpStream& rStrm );
+ /** Reads an SXIVD record containing the row field or column field order. */
+ void ReadSxivd( XclImpStream& rStrm );
+ /** Reads an SXPI record containing page field data. */
+ void ReadSxpi( XclImpStream& rStrm );
+ /** Reads an SXDI record containing data field data. */
+ void ReadSxdi( XclImpStream& rStrm );
+ /** Reads an SXVI record describing a new item of the current field. */
+ void ReadSxvi( XclImpStream& rStrm );
+ /** Reads an SXEX record containing additional settings for a pivot table. */
+ void ReadSxex( XclImpStream& rStrm );
+ /** Reads an SXVIEWEX9 record that specifies the pivot tables
+ * autoformat. */
+ void ReadSxViewEx9( XclImpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+
+ /** Reads all used pivot caches and creates additional sheets for external data sources. */
+ void ReadPivotCaches( XclImpStream& rStrm );
+ /** Inserts all pivot tables into the Calc document. */
+ void ConvertPivotTables();
+
+ void MaybeRefreshPivotTables();
+
+private:
+ typedef ::std::vector< XclImpPivotCacheRef > XclImpPivotCacheVec;
+ typedef ::std::vector< XclImpPivotTableRef > XclImpPivotTableVec;
+
+ XclImpPivotCacheVec maPCaches; /// List of all pivot caches.
+ XclImpPivotTableVec maPTables; /// List of all pivot tables.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx
new file mode 100644
index 000000000000..c5cf284d2d2e
--- /dev/null
+++ b/sc/source/filter/inc/xiroot.hxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIROOT_HXX
+#define SC_XIROOT_HXX
+
+#include "xlroot.hxx"
+
+// Forward declarations of objects in public use ==============================
+
+class XclImpStream;
+class XclImpString;
+
+typedef ScfRef< XclImpString > XclImpStringRef;
+
+// Global data ================================================================
+
+class XclImpAddressConverter;
+class XclImpFormulaCompiler;
+class XclImpSst;
+class XclImpPalette;
+class XclImpFontBuffer;
+class XclImpNumFmtBuffer;
+class XclImpXFBuffer;
+class XclImpXFRangeBuffer;
+class XclImpTabInfo;
+class XclImpNameManager;
+class XclImpLinkManager;
+class XclImpObjectManager;
+class XclImpSheetDrawing;
+class XclImpCondFormatManager;
+class XclImpAutoFilterBuffer;
+class XclImpWebQueryBuffer;
+class XclImpPivotTableManager;
+class XclImpPageSettings;
+class XclImpDocViewSettings;
+class XclImpTabViewSettings;
+class XclImpSheetProtectBuffer;
+class XclImpDocProtectBuffer;
+
+class _ScRangeListTabs;
+class ExcelToSc;
+
+/** Stores global buffers and data needed for Excel import filter. */
+struct XclImpRootData : public XclRootData
+{
+ typedef ScfRef< XclImpAddressConverter > XclImpAddrConvRef;
+ typedef ScfRef< XclImpFormulaCompiler > XclImpFmlaCompRef;
+
+ typedef ScfRef< XclImpSst > XclImpSstRef;
+ typedef ScfRef< XclImpPalette > XclImpPaletteRef;
+ typedef ScfRef< XclImpFontBuffer > XclImpFontBfrRef;
+ typedef ScfRef< XclImpNumFmtBuffer > XclImpNumFmtBfrRef;
+ typedef ScfRef< XclImpXFBuffer > XclImpXFBfrRef;
+ typedef ScfRef< XclImpXFRangeBuffer > XclImpXFRangeBfrRef;
+ typedef ScfRef< XclImpTabInfo > XclImpTabInfoRef;
+ typedef ScfRef< XclImpNameManager > XclImpNameMgrRef;
+ typedef ScfRef< XclImpLinkManager > XclImpLinkMgrRef;
+ typedef ScfRef< XclImpObjectManager > XclImpObjectMgrRef;
+ typedef ScfRef< XclImpCondFormatManager > XclImpCondFmtMgrRef;
+ typedef ScfRef< XclImpWebQueryBuffer > XclImpWebQueryBfrRef;
+ typedef ScfRef< XclImpPivotTableManager > XclImpPTableMgrRef;
+ 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.
+
+ XclImpSstRef mxSst; /// The shared string table.
+ XclImpPaletteRef mxPalette; /// The color buffer.
+ XclImpFontBfrRef mxFontBfr; /// All fonts in the file.
+ XclImpNumFmtBfrRef mxNumFmtBfr; /// All number formats in the file.
+ XclImpXFBfrRef mpXFBfr; /// All XF record data in the file.
+ XclImpXFRangeBfrRef mxXFRangeBfr; /// Buffer of XF index ranges in a sheet.
+
+ XclImpTabInfoRef mxTabInfo; /// Sheet creation order list.
+ XclImpNameMgrRef mxNameMgr; /// Internal defined names.
+ XclImpLinkMgrRef mxLinkMgr; /// Manager for internal/external links.
+
+ XclImpObjectMgrRef mxObjMgr; /// All drawing objects.
+ XclImpCondFmtMgrRef mxCondFmtMgr; /// Conditional formattings.
+ XclImpWebQueryBfrRef mxWebQueryBfr; /// All web queries.
+ XclImpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches.
+
+ XclImpPageSettRef mxPageSett; /// Page settings for current sheet.
+ XclImpDocViewSettRef mxDocViewSett; /// View settings for entire document.
+ XclImpTabViewSettRef mxTabViewSett; /// View settings for current sheet.
+ XclImpTabProtectRef mxTabProtect; /// Sheet protection options for current sheet.
+ XclImpDocProtectRef mxDocProtect; /// Document protection options.
+
+ bool mbHasCodePage; /// true = CODEPAGE record exists.
+ bool mbHasBasic; /// true = document contains VB project.
+
+ explicit XclImpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc );
+ virtual ~XclImpRootData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Access to global data from other classes. */
+class XclImpRoot : public XclRoot
+{
+public:
+ explicit XclImpRoot( XclImpRootData& rImpRootData );
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclImpRoot& GetRoot() const { return *this; }
+
+ /** Sets a code page read from a CODEPAGE record for byte string import. */
+ void SetCodePage( sal_uInt16 nCodePage );
+ /** Sets text encoding from the default application font (in case of missing CODEPAGE record). */
+ void SetAppFontEncoding( rtl_TextEncoding eAppFontEnc );
+
+ /** Is called when import filter starts importing a single sheet (all BIFF versions). */
+ void InitializeTable( SCTAB nScTab );
+ /** Is called when import filter stops importing a single sheet (all BIFF versions). */
+ void FinalizeTable();
+
+ /** Returns the address converter. */
+ XclImpAddressConverter& GetAddressConverter() const;
+ /** Returns the formula converter. */
+ XclImpFormulaCompiler& GetFormulaCompiler() const;
+ /** Returns the old formula converter. */
+ ExcelToSc& GetOldFmlaConverter() const;
+
+ /** Returns the shared string table. */
+ XclImpSst& GetSst() const;
+ /** Returns the color buffer. */
+ XclImpPalette& GetPalette() const;
+ /** Returns the font buffer. */
+ XclImpFontBuffer& GetFontBuffer() const;
+ /** Returns the number format buffer. */
+ XclImpNumFmtBuffer& GetNumFmtBuffer() const;
+ /** Returns the cell formatting attributes buffer. */
+ XclImpXFBuffer& GetXFBuffer() const;
+ /** Returns the buffer of XF index ranges for a sheet. */
+ XclImpXFRangeBuffer& GetXFRangeBuffer() const;
+
+ /** Returns the buffer that contains all print areas in the document. */
+ _ScRangeListTabs& GetPrintAreaBuffer() const;
+ /** Returns the buffer that contains all print titles in the document. */
+ _ScRangeListTabs& GetTitleAreaBuffer() const;
+
+ /** Returns the buffer that contains the sheet creation order. */
+ XclImpTabInfo& GetTabInfo() const;
+ /** Returns the buffer that contains internal defined names. */
+ XclImpNameManager& GetNameManager() const;
+ /** Returns the link manager. */
+ XclImpLinkManager& GetLinkManager() const;
+
+ /** Returns the drawing object manager. */
+ XclImpObjectManager& GetObjectManager() const;
+ /** Returns the drawing container of the current sheet. */
+ XclImpSheetDrawing& GetCurrSheetDrawing() const;
+ /** Returns the conditional formattings manager. */
+ XclImpCondFormatManager& GetCondFormatManager() const;
+ /** Returns the filter manager. */
+ XclImpAutoFilterBuffer& GetFilterManager() const;
+ /** Returns the web query buffer. */
+ XclImpWebQueryBuffer& GetWebQueryBuffer() const;
+ /** Returns the pivot table manager. */
+ XclImpPivotTableManager& GetPivotTableManager() const;
+ /** Returns the sheet protection options of the current sheet. */
+ XclImpSheetProtectBuffer& GetSheetProtectBuffer() const;
+ /** Returns the document protection options. */
+ XclImpDocProtectBuffer& GetDocProtectBuffer() const;
+
+ /** Returns the page settings of the current sheet. */
+ XclImpPageSettings& GetPageSettings() const;
+ /** Returns the view settings of the entire document. */
+ XclImpDocViewSettings& GetDocViewSettings() const;
+ /** Returns the view settings of the current sheet. */
+ XclImpTabViewSettings& GetTabViewSettings() const;
+
+ /** Returns the Calc add-in function name for an Excel function name. */
+ String GetScAddInName( const String& rXclName ) const;
+
+ /** Returns true, if the document contains a VB project. */
+ inline bool HasBasic() const { return mrImpData.mbHasBasic; }
+ /** Called to indicate that the document contains a VB project. */
+ inline void SetHasBasic() { mrImpData.mbHasBasic = true; }
+ /** Reads the CODENAME record and inserts the codename into the document. */
+ void ReadCodeName( XclImpStream& rStrm, bool bGlobals );
+
+private:
+ mutable XclImpRootData& mrImpData; /// Reference to the global import data struct.
+};
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
new file mode 100644
index 000000000000..9b27077d78e7
--- /dev/null
+++ b/sc/source/filter/inc/xistream.hxx
@@ -0,0 +1,529 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XISTREAM_HXX
+#define SC_XISTREAM_HXX
+
+#include <comphelper/docpasswordhelper.hxx>
+#include <filter/msfilter/mscodec.hxx>
+#include "xlstream.hxx"
+#include "xlconst.hxx"
+
+class XclImpRoot;
+
+/* ============================================================================
+Input stream class for Excel import
+- CONTINUE record handling
+- ByteString and UniString support
+- Decryption
+============================================================================ */
+
+// ============================================================================
+// Decryption
+// ============================================================================
+
+class XclImpDecrypter;
+typedef ScfRef< XclImpDecrypter > XclImpDecrypterRef;
+
+/** Base class for BIFF stream decryption. */
+class XclImpDecrypter : public ::comphelper::IDocPasswordVerifier
+{
+public:
+ explicit XclImpDecrypter();
+ virtual ~XclImpDecrypter();
+
+ /** Returns the current error code of the decrypter. */
+ inline ErrCode GetError() const { return mnError; }
+ /** Returns true, if the decoder has been initialized correctly. */
+ inline bool IsValid() const { return mnError == ERRCODE_NONE; }
+
+ /** Creates a (ref-counted) copy of this decrypter object. */
+ XclImpDecrypterRef Clone() const;
+
+ /** Implementation of the ::comphelper::IDocPasswordVerifier interface,
+ calls the new virtual function implVerify(). */
+ virtual ::comphelper::DocPasswordVerifierResult
+ verifyPassword( const ::rtl::OUString& rPassword );
+
+ /** Updates the decrypter on start of a new record or after seeking stream. */
+ void Update( SvStream& rStrm, sal_uInt16 nRecSize );
+ /** Reads and decrypts nBytes bytes and stores data into the existing(!) buffer pData.
+ @return Count of bytes really read. */
+ sal_uInt16 Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes );
+
+protected:
+ /** Protected copy c'tor for OnClone(). */
+ explicit XclImpDecrypter( const XclImpDecrypter& rSrc );
+
+private:
+ /** Implementation of cloning this object. */
+ virtual XclImpDecrypter* OnClone() const = 0;
+ /** Derived classes implement password verification and initialization of
+ the decoder. */
+ virtual bool OnVerify( const ::rtl::OUString& rPassword ) = 0;
+ /** Implementation of updating the decrypter. */
+ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) = 0;
+ /** Implementation of the decryption. */
+ virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ) = 0;
+
+private:
+ ErrCode mnError; /// Decrypter error code.
+ sal_Size mnOldPos; /// Last known stream position.
+ sal_uInt16 mnRecSize; /// Current record size.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Decrypts BIFF5 stream contents. */
+class XclImpBiff5Decrypter : public XclImpDecrypter
+{
+public:
+ explicit XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash );
+
+private:
+ /** Private copy c'tor for OnClone(). */
+ explicit XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc );
+
+ /** Implementation of cloning this object. */
+ virtual XclImpBiff5Decrypter* OnClone() const;
+ /** Implements password verification and initialization of the decoder. */
+ virtual bool OnVerify( const ::rtl::OUString& rPassword );
+ /** Implementation of updating the decrypter. */
+ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize );
+ /** Implementation of the decryption. */
+ virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes );
+
+private:
+ ::msfilter::MSCodec_XorXLS95 maCodec; /// Crypto algorithm implementation.
+ ::std::vector< sal_uInt8 > maPassword;
+ sal_uInt16 mnKey;
+ sal_uInt16 mnHash;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Decrypts BIFF8 stream contents using the given document identifier. */
+class XclImpBiff8Decrypter : public XclImpDecrypter
+{
+public:
+ explicit XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
+ sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] );
+
+private:
+ /** Private copy c'tor for OnClone(). */
+ explicit XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc );
+
+ /** Implementation of cloning this object. */
+ virtual XclImpBiff8Decrypter* OnClone() const;
+ /** Implements password verification and initialization of the decoder. */
+ virtual bool OnVerify( const ::rtl::OUString& rPassword );
+ /** Implementation of updating the decrypter. */
+ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize );
+ /** Implementation of the decryption. */
+ virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes );
+
+ /** Returns the block number corresponding to the passed stream position. */
+ sal_uInt32 GetBlock( sal_Size nStrmPos ) const;
+ /** Returns the block offset corresponding to the passed stream position. */
+ sal_uInt16 GetOffset( sal_Size nStrmPos ) const;
+
+private:
+ ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation.
+ ::std::vector< sal_uInt16 > maPassword;
+ ::std::vector< sal_uInt8 > maSalt;
+ ::std::vector< sal_uInt8 > maVerifier;
+ ::std::vector< sal_uInt8 > maVerifierHash;
+};
+
+// ============================================================================
+// Stream
+// ============================================================================
+
+/** This class represents an Excel stream position.
+ @descr It contains the relevant data for a stream position inside of a record
+ (including CONTINUE records). */
+class XclImpStreamPos
+{
+public:
+ /** Constructs an invalid stream position data object. */
+ explicit XclImpStreamPos();
+
+ /** Sets the stream position data to the passed values. */
+ void Set( const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize,
+ sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
+ bool bValid );
+
+ /** Writes the contained stream position data to the given variables. */
+ void Get( SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize,
+ sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
+ bool& rbValid ) const;
+
+private:
+ sal_Size mnPos; /// Absolute position of the stream.
+ sal_Size mnNextPos; /// Absolute position of next record.
+ sal_Size mnCurrSize; /// Current calculated size of the record.
+ sal_uInt16 mnRawRecId; /// Current raw record ID (including CONTINUEs).
+ sal_uInt16 mnRawRecSize; /// Current raw record size (without following CONTINUEs).
+ sal_uInt16 mnRawRecLeft; /// Bytes left in current raw record (without following CONTINUEs).
+ bool mbValid; /// Read state: false = record overread.
+};
+
+// ============================================================================
+
+/** This class is used to import record oriented streams.
+ @descr An instance is constructed with an SvStream. The SvStream stream is
+ reset to its start while constructing this stream.
+
+ To start reading a record call StartNextRecord(). Now it is possible to
+ read all contents of the record using operator>>() or any of the Read***()
+ functions. If some data exceeds the record size limit, the stream looks for
+ a following CONTINUE record and jumps automatically to it. It is NOT
+ allowed that an atomic data type is split into two records (i.e. 4 bytes of
+ a double in one record and the other 4 bytes in a following CONTINUE).
+
+ Trying to read over the record limits results in a stream error. The
+ IsValid() function indicates that with returning false. From now on it is
+ undefined what data the read functions will return. The error state will be
+ reset, if the record is reset (with the method ResetRecord()) or if the
+ next record is started.
+
+ To switch off the automatic lookup of CONTINUE records, use ResetRecord()
+ with false parameter. This is useful i.e. on import of Escher objects,
+ where sometimes solely CONTINUE records will occur. The automatic lookup
+ keeps switched off until the method ResetRecord() is called with parameter
+ true. All other settings done on the stream (i.e. alternative CONTINUE
+ record identifier, enabled decryption, NUL substitution character) will be
+ reset to default values, if a new record is started.
+
+ The import stream supports decrypting the stream data. The contents of a
+ record (not the record header) will be encrypted by Excel if the file has
+ been stored with password protection. The functions SetDecrypter(),
+ EnableDecryption(), and DisableDecryption() control the usage of the
+ decryption algorithms. SetDecrypter() sets a new decryption algorithm and
+ initially enables it. DisableDecryption() may be used to stop the usage of
+ the decryption temporarily (sometimes record contents are never encrypted,
+ i.e. all BOF records or the stream position in BOUNDSHEET). Decryption will
+ be reenabled automatically, if a new record is started with the function
+ StartNextRecord().
+
+ It is possible to store several stream positions inside a record (including
+ its CONTINUE records). The positions are stored on a stack, which can be
+ controlled with the functions PushPosition(), PopPosition() and
+ RejectPosition(). The stack will be cleared whenever a new record is
+ started with the function StartNextRecord().
+
+ Additionally a single global stream position can be stored which keeps
+ valid during the whole import process (methods StoreGlobalPosition(),
+ SeekGlobalPosition() and DeleteGlobalPosition()). This is the only way to
+ jump back to a previous record (that is a real jump without return).
+*/
+class XclImpStream
+{
+public:
+ /** Detects the BIFF version of the passed workbook stream. */
+ static XclBiff DetectBiffVersion( SvStream& rStrm );
+
+ /** Constructs the Excel record import stream using a TOOLS stream object.
+ @param rInStrm The system input stream. Will be set to its start position.
+ Must exist as long as this object exists.
+ @param bContLookup Automatic CONTINUE lookup on/off. */
+ explicit XclImpStream(
+ SvStream& rInStrm,
+ const XclImpRoot& rRoot,
+ bool bContLookup = true );
+
+ ~XclImpStream();
+
+ /** Returns the filter root data. */
+ inline const XclImpRoot& GetRoot() const { return mrRoot; }
+
+ /** Sets stream pointer to the start of the next record content.
+ @descr Ignores all CONTINUE records of the current record, if automatic
+ CONTINUE usage is switched on.
+ @return false = no record found (end of stream). */
+ bool StartNextRecord();
+ /** Sets stream pointer to the start of the record content for the record
+ at the passed absolute stream position.
+ @return false = no record found (end of stream). */
+ bool StartNextRecord( sal_Size nNextRecPos );
+ /** Sets stream pointer to begin of record content.
+ @param bContLookup Automatic CONTINUE lookup on/off. In difference
+ to other stream settings, this setting is persistent until next call of
+ this function (because it is wanted to receive the next CONTINUE
+ records separately).
+ @param nAltContId Sets an alternative record ID for content
+ continuation. This value is reset automatically when a new record is
+ started with StartNextRecord(). */
+ void ResetRecord( bool bContLookup,
+ sal_uInt16 nAltContId = EXC_ID_UNKNOWN );
+
+ /** Enables decryption of record contents for the rest of the stream. */
+ void SetDecrypter( XclImpDecrypterRef xDecrypter );
+ /** Sets decrypter from another stream. */
+ void CopyDecrypterFrom( const XclImpStream& rStrm );
+ /** Returns true, if a valid decrypter is set at the stream. */
+ bool HasValidDecrypter() const;
+ /** Switches usage of current decryption algorithm on/off.
+ @descr Encryption is re-enabled automatically, if a new record is
+ started using the function StartNextRecord(). */
+ void EnableDecryption( bool bEnable = true );
+ /** Switches usage of current decryption algorithm off.
+ @descr This is a record-local setting. The function StartNextRecord()
+ always enables decryption. */
+ inline void DisableDecryption() { EnableDecryption( false ); }
+
+ /** Pushes current position on user position stack.
+ @descr This stack is emptied when starting a new record with
+ StartNextRecord(). The decryption state (enabled/disabled) is not
+ pushed onto the stack. */
+ void PushPosition();
+ /** Seeks to last position from user position stack.
+ @descr This position will be removed from the stack. */
+ void PopPosition();
+//UNUSED2008-05 /** Removes last position from user position stack, but does not seek to it. */
+//UNUSED2008-05 void RejectPosition();
+
+ /** Stores current position. This position keeps valid in all records. */
+ void StoreGlobalPosition();
+ /** Seeks to the stored global user position. */
+ void SeekGlobalPosition();
+ /** Invalidates global user position. */
+ inline void DeleteGlobalPosition() { mbHasGlobPos = false; }
+
+ /** Returns record reading state: false = record overread. */
+ inline bool IsValid() const { return mbValid; }
+ /** Returns the current record ID. */
+ inline sal_uInt16 GetRecId() const { return mnRecId; }
+ /** Returns the position inside of the whole record content. */
+ sal_Size GetRecPos() const;
+ /** Returns the data size of the whole record without record headers. */
+ sal_Size GetRecSize();
+ /** Returns remaining data size of the whole record without record headers. */
+ sal_Size GetRecLeft();
+ /** Returns the record ID of the following record. */
+ sal_uInt16 GetNextRecId();
+
+ XclImpStream& operator>>( sal_Int8& rnValue );
+ XclImpStream& operator>>( sal_uInt8& rnValue );
+ XclImpStream& operator>>( sal_Int16& rnValue );
+ XclImpStream& operator>>( sal_uInt16& rnValue );
+ XclImpStream& operator>>( sal_Int32& rnValue );
+ XclImpStream& operator>>( sal_uInt32& rnValue );
+ XclImpStream& operator>>( float& rfValue );
+ XclImpStream& operator>>( double& rfValue );
+
+ sal_Int8 ReadInt8();
+ sal_uInt8 ReaduInt8();
+ sal_Int16 ReadInt16();
+ sal_uInt16 ReaduInt16();
+ sal_Int32 ReadInt32();
+ sal_uInt32 ReaduInt32();
+ float ReadFloat();
+ double ReadDouble();
+
+ /** Reads nBytes bytes to the existing(!) buffer pData.
+ @return Count of bytes really read. */
+ sal_Size Read( void* pData, sal_Size nBytes );
+ /** Copies nBytes bytes to rOutStrm.
+ @return Count of bytes really written. */
+ sal_Size CopyToStream( SvStream& rOutStrm, sal_Size nBytes );
+
+ /** Copies the entire record to rOutStrm. The current record position keeps unchanged.
+ @return Count of bytes really written. */
+ sal_Size CopyRecordToStream( SvStream& rOutStrm );
+
+ /** Seeks absolute in record content to the specified position.
+ @descr The value 0 means start of record, independent from physical stream position. */
+ void Seek( sal_Size nPos );
+ /** Seeks forward inside the current record. */
+ void Ignore( sal_Size nBytes );
+
+ // *** special string functions *** ---------------------------------------
+
+ // *** read/ignore unicode strings *** ------------------------------------
+ /* - look for CONTINUE records even if CONTINUE handling disabled
+ (only if inside of a CONTINUE record - for TXO import)
+ - no overread assertions (for Applix wrong string length export bug)
+
+ structure of an Excel unicode string:
+ (1) 2 byte character count
+ (2) 1 byte flags (16-bit-characters, rich string, far east string)
+ (3) [2 byte rich string format run count]
+ (4) [4 byte far east data size]
+ (5) character array
+ (6) [4 * (rich string format run count) byte]
+ (7) [(far east data size) byte]
+ header = (1), (2)
+ ext. header = (3), (4)
+ ext. data = (6), (7)
+ */
+
+ /** Reads ext. header, detects 8/16 bit mode, sets all ext. info.
+ @return Total size of ext. data. */
+ sal_Size ReadUniStringExtHeader(
+ bool& rb16Bit, bool& rbRich, bool& rbFareast,
+ sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags );
+ /** Seeks to begin of character array, detects 8/16 bit mode.
+ @return Total size of ext. data. */
+ sal_Size ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags );
+
+ /** Sets a replacement character for NUL characters.
+ @descr NUL characters must be replaced, because Tools strings cannot
+ handle them. The substitution character is reset to '?' automatically,
+ if a new record is started using the function StartNextRecord().
+ @param cNulSubst The character to use for NUL replacement. It is
+ possible to specify NUL here. in this case strings are terminated when
+ the first NUL occurs during string import. */
+ inline void SetNulSubstChar( sal_Unicode cNulSubst = '?' ) { mcNulSubst = cNulSubst; }
+
+ /** Reads nChars characters and returns the string. */
+ String ReadRawUniString( sal_uInt16 nChars, bool b16Bit );
+ /** Reads ext. header, nChar characters, ext. data and returns the string. */
+ String ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags );
+ /** Reads 8 bit flags, ext. header, nChar characters, ext. data and returns the string. */
+ String ReadUniString( sal_uInt16 nChars );
+ /** Reads 16 bit character count, 8 bit flags, ext. header, character array,
+ ext. data and returns the string. */
+ String ReadUniString();
+
+ /** Ignores nChars characters. */
+ void IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit );
+ /** Ignores ext. header, nChar characters, ext. data. */
+ void IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags );
+ /** Ignores 8 bit flags, ext. header, nChar characters, ext. data. */
+ void IgnoreUniString( sal_uInt16 nChars );
+ /** Ignores 16 bit character count, 8 bit flags, ext. header, character array, ext. data. */
+ void IgnoreUniString();
+
+ // *** read/ignore 8-bit-strings, store in String *** ---------------------
+
+ /** Reads nChar byte characters and returns the string. */
+ String ReadRawByteString( sal_uInt16 nChars );
+ /** Reads 8/16 bit string length, character array and returns the string. */
+ String ReadByteString( bool b16BitLen );
+
+ // *** SvStream functions *** ---------------------------------------------
+
+ /** Returns the absolute stream position. */
+ inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); }
+ /** Returns the stream size. */
+ inline sal_Size GetSvStreamSize() const { return mnStreamSize; }
+
+private:
+ /** Stores current stream position into rPos. */
+ void StorePosition( XclImpStreamPos& rPos );
+ /** Restores stream position contained in rPos. */
+ void RestorePosition( const XclImpStreamPos& rPos );
+
+ /** Seeks to next raw record header and reads record ID and size.
+ @descr This is a "raw" function, means that stream members are
+ inconsistent after return. Does only change mnRawRecId, mnRawRecSize,
+ and the base stream position, but no other members.
+ @return false = No record header found (end of stream). */
+ bool ReadNextRawRecHeader();
+
+ /** Initializes the decrypter to read a new record. */
+ void SetupDecrypter();
+ /** Initializes all members after base stream has been seeked to new raw record. */
+ void SetupRawRecord();
+ /** Initializes all members after base stream has been seeked to new record. */
+ void SetupRecord();
+
+ /** Returns true, if the passed ID is real or alternative continuation record ID. */
+ bool IsContinueId( sal_uInt16 nRecId ) const;
+
+ /** Goes to start of the next CONTINUE record.
+ @descr Stream must be located at the end of a raw record, and handling
+ of CONTINUE records must be enabled.
+ @return Copy of mbValid. */
+ bool JumpToNextContinue();
+ /** Goes to start of the next CONTINUE record while reading strings.
+ @descr Stream must be located at the end of a raw record. If reading
+ has been started in a CONTINUE record, jumps to an existing following
+ CONTINUE record, even if handling of CONTINUE records is disabled (This
+ is a special handling for TXO string data). Reads additional Unicode
+ flag byte at start of the new raw record and sets or resets rb16Bit.
+ @return Copy of mbValid. */
+ bool JumpToNextStringContinue( bool& rb16Bit );
+
+ /** Ensures that reading nBytes bytes is possible with next stream access.
+ @descr Stream must be located at the end of a raw record, and handling
+ of CONTINUE records must be enabled.
+ @return Copy of mbValid. */
+ bool EnsureRawReadSize( sal_uInt16 nBytes );
+ /** Returns the maximum size of raw data possible to read in one block. */
+ sal_uInt16 GetMaxRawReadSize( sal_Size nBytes ) const;
+
+ /** Reads and decrypts nBytes bytes to the existing(!) buffer pData.
+ @return Count of bytes really read. */
+ sal_uInt16 ReadRawData( void* pData, sal_uInt16 nBytes );
+
+ /** Reads 8 bit/16 bit string length. */
+ inline sal_uInt16 ReadByteStrLen( bool b16BitLen )
+ { return b16BitLen ? ReaduInt16() : ReaduInt8(); }
+
+private:
+ typedef ::std::vector< XclImpStreamPos > XclImpStreamPosStack;
+
+ SvStream& mrStrm; /// Reference to the system input stream.
+ const XclImpRoot& mrRoot; /// Filter root data.
+
+ XclImpDecrypterRef mxDecrypter; /// Provides methods to decrypt data.
+
+ XclImpStreamPos maFirstRec; /// Start position of current record.
+ XclImpStreamPosStack maPosStack; /// Stack for record positions.
+
+ XclImpStreamPos maGlobPos; /// User defined position elsewhere in stream.
+ sal_uInt16 mnGlobRecId; /// Record ID for user defined position.
+ bool mbGlobValidRec; /// Was user position a valid record?
+ bool mbHasGlobPos; /// Is user position defined?
+
+ sal_Size mnStreamSize; /// Size of system stream.
+ sal_Size mnNextRecPos; /// Start of next record header.
+ sal_Size mnCurrRecSize; /// Helper for record position.
+ sal_Size mnComplRecSize; /// Size of complete record data (with CONTINUEs).
+ bool mbHasComplRec; /// true = mnComplRecSize is valid.
+
+ sal_uInt16 mnRecId; /// Current record ID (not the CONTINUE ID).
+ sal_uInt16 mnAltContId; /// Alternative record ID for content continuation.
+
+ sal_uInt16 mnRawRecId; /// Current raw record ID (including CONTINUEs).
+ sal_uInt16 mnRawRecSize; /// Current raw record size (without following CONTINUEs).
+ sal_uInt16 mnRawRecLeft; /// Bytes left in current raw record (without following CONTINUEs).
+
+ sal_Unicode mcNulSubst; /// Replacement for NUL characters.
+
+ bool mbCont; /// Automatic CONTINUE lookup on/off.
+ bool mbUseDecr; /// Usage of decryption.
+ bool mbValidRec; /// false = No more records to read.
+ bool mbValid; /// false = Record overread.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xistring.hxx b/sc/source/filter/inc/xistring.hxx
new file mode 100644
index 000000000000..a6f00d26d2e2
--- /dev/null
+++ b/sc/source/filter/inc/xistring.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XISTRING_HXX
+#define SC_XISTRING_HXX
+
+#include "xlstring.hxx"
+
+// Byte/Unicode strings =======================================================
+
+class XclImpStream;
+
+/** This class represents an unformatted or formatted string and provides importing from stream. */
+class XclImpString
+{
+public:
+ /** Constructs an empty string. */
+ explicit XclImpString();
+ /** Constructs an unformatted string. */
+ explicit XclImpString( const String& rString );
+
+ ~XclImpString();
+
+ /** Reads a complete string from the passed stream. */
+ void Read( XclImpStream& rStrm, XclStrFlags nFlags = EXC_STR_DEFAULT );
+
+ /** Sets the passed string data. */
+ inline void SetText( const String& rText ) { maString = rText; }
+ /** Sets the passed formatting buffer. */
+ inline void SetFormats( const XclFormatRunVec& rFormats ) { maFormats = rFormats; }
+ /** Insert a formatting run to the format buffer. */
+ inline void AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx ) { AppendFormat( maFormats, nChar, nFontIdx ); }
+ /** Reads and appends the formatting information (run count and runs) from stream. */
+ inline void ReadFormats( XclImpStream& rStrm ) { ReadFormats( rStrm, maFormats ); }
+ /** Reads and appends nRunCount formatting runs from stream. */
+ inline void ReadFormats( XclImpStream& rStrm, sal_uInt16 nRunCount ) { ReadFormats( rStrm, maFormats, nRunCount ); }
+ /** Reads and appends formatting runs from an OBJ or TXO record. */
+ inline void ReadObjFormats( XclImpStream& rStrm, sal_uInt16 nFormatSize ) { ReadObjFormats( rStrm, maFormats, nFormatSize ); }
+
+ /** Returns true, if the string is empty. */
+ inline bool IsEmpty() const { return maString.Len() == 0; }
+ /** Returns the pure text data of the string. */
+ inline const String& GetText() const { return maString; }
+
+ /** Returns true, if the string contains formatting information. */
+ inline bool IsRich() const { return !maFormats.empty(); }
+ /** Returns the formatting run vector. */
+ inline const XclFormatRunVec& GetFormats() const { return maFormats; }
+
+ /** Insert a formatting run to the passed format buffer. */
+ static void AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx );
+ /** Reads and appends the formatting information (run count and runs) from stream. */
+ static void ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats );
+ /** Reads and appends nRunCount formatting runs from stream. */
+ static void ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount );
+ /** Reads and appends formatting runs from an OBJ or TXO record. */
+ static void ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize );
+
+private:
+ String maString; /// The text data of the string.
+ XclFormatRunVec maFormats; /// All formatting runs.
+};
+
+// String iterator ============================================================
+
+/** Iterates over formatted string portions. */
+class XclImpStringIterator
+{
+public:
+ explicit XclImpStringIterator( const XclImpString& rString );
+
+ /** Returns true, if the iterator references a valid text portion. */
+ inline bool Is() const { return mnTextBeg < mrText.Len(); }
+ /** Returns the index of the current text portion. */
+ inline size_t GetPortionIndex() const { return mnPortion; }
+ /** Returns the string of the current text portion. */
+ String GetPortionText() const;
+ /** Returns the font index of the current text portion. */
+ sal_uInt16 GetPortionFont() const;
+
+ /** Moves iterator to next text portion. */
+ XclImpStringIterator& operator++();
+
+private:
+ const String& mrText; /// The processed string.
+ const XclFormatRunVec& mrFormats; /// The vector of formatting runs.
+ size_t mnPortion; /// Current text portion.
+ xub_StrLen mnTextBeg; /// First character of current portion.
+ xub_StrLen mnTextEnd; /// First character of next portion.
+ size_t mnFormatsBeg; /// Formatting run index for current portion.
+ size_t mnFormatsEnd; /// Formatting run index for next portion.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xistyle.hxx b/sc/source/filter/inc/xistyle.hxx
new file mode 100644
index 000000000000..104002542a17
--- /dev/null
+++ b/sc/source/filter/inc/xistyle.hxx
@@ -0,0 +1,679 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XISTYLE_HXX
+#define SC_XISTYLE_HXX
+
+#include <list>
+#include <tools/mempool.hxx>
+#include "rangelst.hxx"
+#include "patattr.hxx"
+#include "xladdress.hxx"
+#include "xlstyle.hxx"
+#include "xiroot.hxx"
+
+class ScDocumentPool;
+
+/* ============================================================================
+- Buffers for style records (PALETTE, FONT, FORMAT, XF)
+ and a container for XF indexes for every used cell in a sheet.
+============================================================================ */
+
+// PALETTE record - color information =========================================
+
+/** Stores the default colors for the current BIFF version and the contents of
+ a PALETTE record. */
+class XclImpPalette : public XclDefaultPalette
+{
+public:
+ explicit XclImpPalette( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
+ @descr First looks for a color read from file, then looks for a default color.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ ColorData GetColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the color for a (non-zero-based) Excel palette entry.
+ @descr First looks for a color read from file, then looks for a default color.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ inline Color GetColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetColorData( nXclIndex ) ); }
+
+ /** Reads a PALETTE record. */
+ void ReadPalette( XclImpStream& rStrm );
+
+private:
+ typedef ::std::vector< ColorData > ColorDataVec;
+ ColorDataVec maColorTable; /// Colors read from file.
+};
+
+// FONT record - font information =============================================
+
+/** Stores all data of an Excel font and provides import of FONT records. */
+class XclImpFont : protected XclImpRoot
+{
+public:
+ explicit XclImpFont( const XclImpRoot& rRoot );
+
+ /** Constructs a font from font data.
+ @descr Special handling for font style (bold, italic) in font name,
+ overwrites settings in rFontData. */
+ explicit XclImpFont( const XclImpRoot& rRoot, const XclFontData& rFontData );
+
+ /** Sets all font attributes to used or unused. */
+ void SetAllUsedFlags( bool bUsed );
+ /** Sets the passed font data and all used flags to 'used'. */
+ void SetFontData( const XclFontData& rFontData, bool bHasCharSet );
+
+ /** Returns read-only access to font data. */
+ inline const XclFontData& GetFontData() const { return maData; }
+ /** Returns true, if the font character set is valid. */
+ inline bool HasCharSet() const { return mbHasCharSet; }
+ /** Returns true, if the font contains superscript or subscript. */
+ inline bool HasEscapement() const { return maData.mnEscapem != EXC_FONTESC_NONE; }
+ /** Returns the text encoding for strings used with this font. */
+ rtl_TextEncoding GetFontEncoding() const;
+
+ /** Returns true, if this font contains characters for Western scripts. */
+ inline bool HasWesternChars() const { return mbHasWstrn; }
+ /** Returns true, if this font contains characters for Asian scripts (CJK). */
+ inline bool HasAsianChars() const { return mbHasAsian; }
+ /** Returns true, if this font contains characters for Complex scripts (CTL). */
+ inline bool HasComplexChars() const { return mbHasCmplx; }
+
+ /** Reads a FONT record for all BIFF versions. */
+ void ReadFont( XclImpStream& rStrm );
+ /** Reads an EFONT record (BIFF2 font color). */
+ void ReadEfont( XclImpStream& rStrm );
+ /** Reads the font block from a CF (conditional format) record. */
+ void ReadCFFontBlock( XclImpStream& rStrm );
+
+ /** Fills all font properties to the item set.
+ @param rItemSet The destination item set.
+ @param eType The type of Which-IDs.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType,
+ bool bSkipPoolDefs = false ) const;
+ /** Writes all font properties to the passed property set.
+ @param pFontColor If set, overrides internal stored font color. */
+ void WriteFontProperties( ScfPropertySet& rPropSet,
+ XclFontPropSetType eType, const Color* pFontColor = 0 ) const;
+
+private:
+ /** Reads and sets height and flags. */
+ void ReadFontData2( XclImpStream& rStrm );
+ /** Reads and sets height, flags, color, boldness, script, family and charset. */
+ void ReadFontData5( XclImpStream& rStrm );
+
+ /** Reads and sets the font color. */
+ void ReadFontColor( XclImpStream& rStrm );
+
+ /** Reads and sets a byte string as font name. */
+ void ReadFontName2( XclImpStream& rStrm );
+ /** Reads and sets a Unicode string as font name. */
+ void ReadFontName8( XclImpStream& rStrm );
+
+ /** Tests whether the font contains CJK or CTL characters.
+ @descr This is only a weak guess using preselected characters. */
+ void GuessScriptType();
+
+private:
+ XclFontData maData; /// All font attributes.
+ bool mbHasCharSet; /// true = Font contains own character set info.
+ bool mbHasWstrn; /// true = Font contains Western script characters.
+ bool mbHasAsian; /// true = Font contains Asian script characters.
+ bool mbHasCmplx; /// true = Font contains Complex script characters.
+ bool mbFontNameUsed; /// true = Font name, family, charset used.
+ bool mbHeightUsed; /// true = Font height used.
+ bool mbColorUsed; /// true = Color used.
+ bool mbWeightUsed; /// true = Weight used.
+ bool mbEscapemUsed; /// true = Escapement type used.
+ bool mbUnderlUsed; /// true = Underline style used.
+ bool mbItalicUsed; /// true = Italic used.
+ bool mbStrikeUsed; /// true = Strikeout used.
+ bool mbOutlineUsed; /// true = Outlined used.
+ bool mbShadowUsed; /// true = Shadowed used.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores the data of all fonts occurred in an Excel file. */
+class XclImpFontBuffer : protected XclImpRoot, ScfNoCopy
+{
+public:
+ explicit XclImpFontBuffer( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Returns the object that stores all contents of a FONT record. */
+ const XclImpFont* GetFont( sal_uInt16 nFontIndex ) const;
+ /** Returns the application font data of this file, needed i.e. for column width. */
+ inline const XclFontData& GetAppFontData() const { return maAppFont; }
+
+ /** Reads a FONT record. */
+ void ReadFont( XclImpStream& rStrm );
+ /** Reads an EFONT record (BIFF2 font color). */
+ void ReadEfont( XclImpStream& rStrm );
+
+ /** Fills all font properties from a FONT record to the item set.
+ @param rItemSet The destination item set.
+ @param eType The type of Which-IDs.
+ @param nFontIdx The Excel index of the font.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType,
+ sal_uInt16 nFontIdx, bool bSkipPoolDefs = false ) const;
+ /** Writes all font properties to the passed property set.
+ @param pFontColor If set, overrides internal stored font color. */
+ void WriteFontProperties(
+ ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ sal_uInt16 nFontIdx, const Color* pFontColor = 0 ) const;
+ /** Writes default font properties for form controls to the passed property set. */
+ void WriteDefaultCtrlFontProperties( ScfPropertySet& rPropSet ) const;
+
+private:
+ /** Updates the application default font. */
+ void UpdateAppFont( const XclFontData& rFontData, bool bHasCharSet );
+
+private:
+ ScfDelList< XclImpFont > maFontList; /// List of all FONT records in the Excel file.
+ XclFontData maAppFont; /// Application font (for column width).
+ XclImpFont maFont4; /// Built-in font with index 4.
+ XclImpFont maCtrlFont; /// BIFF5 default form controls font (Helv,8pt,bold).
+};
+
+// FORMAT record - number formats =============================================
+
+/** Stores all user defined number formats occured in the file. */
+class XclImpNumFmtBuffer : public XclNumFmtBuffer, protected XclImpRoot
+{
+public:
+ explicit XclImpNumFmtBuffer( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Reads a FORMAT record. */
+ void ReadFormat( XclImpStream& rStrm );
+ /** Creates the number formats in the Calc document. */
+ void CreateScFormats();
+
+ /** Returns the format key with the passed Excel index or NUMBERFORMAT_ENTRY_NOT_FOUND on error. */
+ ULONG GetScFormat( sal_uInt16 nXclNumFmt ) const;
+
+ /** Fills an Excel number format to the passed item set.
+ @param rItemSet The destination item set.
+ @param nXclNumFmt The Excel number format index.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet(
+ SfxItemSet& rItemSet, sal_uInt16 nXclNumFmt,
+ bool bSkipPoolDefs = false ) const;
+ /** Fills a Calc number format to the passed item set.
+ @param rItemSet The destination item set.
+ @param nScNumFmt The Calc number formatter index of the format.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillScFmtToItemSet(
+ SfxItemSet& rItemSet, ULONG nScNumFmt,
+ bool bSkipPoolDefs = false ) const;
+
+private:
+ typedef ::std::map< sal_uInt16, ULONG > XclImpIndexMap;
+
+ XclImpIndexMap maIndexMap; /// Maps Excel format indexes to Calc formats.
+ sal_uInt16 mnNextXclIdx; /// Index counter for BIFF2-BIFF4.
+};
+
+// XF, STYLE record - Cell formatting =========================================
+
+/** Extends the XclCellProt struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellProt : public XclCellProt
+{
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nNumFmt );
+ /** Fills this struct with BIFF3-BIFF8 XF record data. */
+ void FillFromXF3( sal_uInt16 nProt );
+
+ /** Inserts items representing this protection style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellAlign struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellAlign : public XclCellAlign
+{
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nFlags );
+ /** Fills this struct with BIFF3 XF record data. */
+ void FillFromXF3( sal_uInt16 nAlign );
+ /** Fills this struct with BIFF4 XF record data. */
+ void FillFromXF4( sal_uInt16 nAlign );
+ /** Fills this struct with BIFF5/BIFF7 XF record data. */
+ void FillFromXF5( sal_uInt16 nAlign );
+ /** Fills this struct with BIFF8 XF record data. */
+ void FillFromXF8( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib );
+
+ /** Inserts items representing this alignment style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFont, bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellBorder struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellBorder : public XclCellBorder
+{
+ bool mbLeftUsed; /// true = Left line style used.
+ bool mbRightUsed; /// true = Right line style used.
+ bool mbTopUsed; /// true = Top line style used.
+ bool mbBottomUsed; /// true = Bottom line style used.
+ bool mbDiagUsed; /// true = Diagonal line style used.
+
+ explicit XclImpCellBorder();
+
+ /** Sets outer line states and diagonal line states to used or unused. */
+ void SetUsedFlags( bool bOuterUsed, bool bDiagUsed );
+
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nFlags );
+ /** Fills this struct with BIFF3/BIFF4 XF record data. */
+ void FillFromXF3( sal_uInt32 nBorder );
+ /** Fills this struct with BIFF5/BIFF7 XF record data. */
+ void FillFromXF5( sal_uInt32 nBorder, sal_uInt32 nArea );
+ /** Fills this struct with BIFF8 XF record data. */
+ void FillFromXF8( sal_uInt32 nBorder1, sal_uInt32 nBorder2 );
+
+ /** Fills this struct with BIFF8 CF (conditional format) record data. */
+ void FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags );
+
+ /** Returns true, if any of the outer border lines is visible. */
+ bool HasAnyOuterBorder() const;
+
+ /** Inserts a box item representing this border style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet(
+ SfxItemSet& rItemSet,
+ const XclImpPalette& rPalette,
+ bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellArea struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellArea : public XclCellArea
+{
+ bool mbForeUsed; /// true = Foreground color used.
+ bool mbBackUsed; /// true = Background color used.
+ bool mbPattUsed; /// true = Pattern used.
+
+ explicit XclImpCellArea();
+
+ /** Sets colors and pattern state to used or unused. */
+ void SetUsedFlags( bool bUsed );
+
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nFlags );
+ /** Fills this struct with BIFF3/BIFF4 XF record data. */
+ void FillFromXF3( sal_uInt16 nArea );
+ /** Fills this struct with BIFF5/BIFF7 XF record data. */
+ void FillFromXF5( sal_uInt32 nArea );
+ /** Fills this struct with BIFF8 XF record data. */
+ void FillFromXF8( sal_uInt32 nBorder2, sal_uInt16 nArea );
+
+ /** Fills this struct with BIFF8 CF (conditional format) record data. */
+ void FillFromCF8( sal_uInt16 nPattern, sal_uInt16 nColor, sal_uInt32 nFlags );
+
+ /** Inserts a brush item representing this area style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet(
+ SfxItemSet& rItemSet,
+ const XclImpPalette& rPalette,
+ bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an XF record index with additional information. */
+class XclImpXFIndex
+{
+public:
+ inline explicit XclImpXFIndex( sal_uInt16 nXFIndex, bool bBoolCell = false ) :
+ mnXFIndex( nXFIndex ), mbBoolCell( bBoolCell ) {}
+
+ inline sal_uInt16 GetXFIndex() const { return mnXFIndex; }
+ inline bool IsBoolCell() const { return mbBoolCell; }
+
+private:
+ sal_uInt16 mnXFIndex; /// The XF record index.
+ bool mbBoolCell; /// true = A Boolean value cell.
+};
+
+inline bool operator==( const XclImpXFIndex& rLeft, const XclImpXFIndex& rRight )
+{ return (rLeft.GetXFIndex() == rRight.GetXFIndex()) && (rLeft.IsBoolCell() == rRight.IsBoolCell()); }
+
+inline bool operator!=( const XclImpXFIndex& rLeft, const XclImpXFIndex& rRight )
+{ return !(rLeft == rRight); }
+
+// ----------------------------------------------------------------------------
+
+/** Contains all data of a XF record and a Calc item set. */
+class XclImpXF : public XclXFBase, protected XclImpRoot, ScfNoCopy
+{
+public:
+ explicit XclImpXF( const XclImpRoot& rRoot );
+ virtual ~XclImpXF();
+
+ /** Reads an XF record. */
+ void ReadXF( XclImpStream& rStrm );
+
+ inline sal_uInt8 GetHorAlign() const { return maAlignment.mnHorAlign; }
+ inline sal_uInt8 GetVerAlign() const { return maAlignment.mnVerAlign; }
+ inline sal_uInt16 GetFontIndex() const { return mnXclFont; }
+
+ /** Creates a Calc item set containing an item set with all cell properties.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items.
+ @return A read-only reference to the item set stored internally. */
+ const ScPatternAttr& CreatePattern( bool bSkipPoolDefs = false );
+
+ /** Inserts all formatting attributes to the specified area in the Calc document.
+ @param nForcedNumFmt If not set to NUMBERFORMAT_ENTRY_NOT_FOUND, it will overwrite
+ the number format of the XF. */
+ void ApplyPattern(
+ SCCOL nScCol1, SCROW nScRow1,
+ SCCOL nScCol2, SCROW nScRow2,
+ SCTAB nScTab,
+ ULONG nForceScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND );
+
+private:
+ void ReadXF2( XclImpStream& rStrm );
+ void ReadXF3( XclImpStream& rStrm );
+ void ReadXF4( XclImpStream& rStrm );
+ void ReadXF5( XclImpStream& rStrm );
+ void ReadXF8( XclImpStream& rStrm );
+
+ /** Sets all "attribute used" flags according to the passed mask.
+ @descr In cell XFs, a set bit represents "used", in style XFs it is a cleared bit.
+ Therefore mbCellXF must be set correctly before calling this method. */
+ void SetUsedFlags( sal_uInt8 nUsedFlags );
+
+private:
+ typedef ::std::auto_ptr< ScPatternAttr > ScPatternAttrPtr;
+
+ ScPatternAttrPtr mpPattern; /// Calc item set.
+ ScStyleSheet* mpStyleSheet; /// Calc cell style sheet.
+
+ XclImpCellProt maProtection; /// Cell protection flags.
+ XclImpCellAlign maAlignment; /// All alignment attributes.
+ XclImpCellBorder maBorder; /// Border line style.
+ XclImpCellArea maArea; /// Background area style.
+ sal_uInt16 mnXclNumFmt; /// Index to number format.
+ sal_uInt16 mnXclFont; /// Index to font record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all data of a cell style associated with an XF record. */
+class XclImpStyle : protected XclImpRoot
+{
+public:
+ explicit XclImpStyle( const XclImpRoot& rRoot );
+
+ /** Reads a STYLE record. */
+ void ReadStyle( XclImpStream& rStrm );
+
+ inline const String& GetName() const { return maName; }
+ inline sal_uInt16 GetXfId() const { return mnXfId; }
+ inline bool IsBuiltin() const { return mbBuiltin && (mnBuiltinId != EXC_STYLE_USERDEF); }
+ inline sal_uInt8 GetBuiltinId() const { return mnBuiltinId; }
+ inline sal_uInt8 GetLevel() const { return mnLevel; }
+
+ /** Creates a cell style sheet and inserts it into the Calc document.
+ @return The pointer to the cell style sheet, or 0, if there is no style sheet. */
+ ScStyleSheet* CreateStyleSheet();
+ /** Creates the Calc style sheet, if this is a user-defined style. */
+ void CreateUserStyle( const String& rFinalName );
+
+private:
+ String maName; /// Cell style name.
+ sal_uInt16 mnXfId; /// Formatting for this cell style.
+ sal_uInt8 mnBuiltinId; /// Identifier for builtin styles.
+ sal_uInt8 mnLevel; /// Level for builtin column/row styles.
+ bool mbBuiltin; /// True = builtin style.
+ bool mbCustom; /// True = customized builtin style.
+ bool mbHidden; /// True = style not visible in GUI.
+
+ String maFinalName; /// Final name used in the Calc document.
+ ScStyleSheet* mpStyleSheet; /// Calc cell style sheet.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all XF records occured in the file.
+ @descr This class is able to read XF records (BIFF2 - BIFF8) and STYLE records (BIFF8). */
+class XclImpXFBuffer : protected XclImpRoot, ScfNoCopy
+{
+public:
+ explicit XclImpXFBuffer( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Reads an XF record. */
+ void ReadXF( XclImpStream& rStrm );
+ /** Reads a STYLE record. */
+ void ReadStyle( XclImpStream& rStrm );
+
+ /** Returns the object that stores all contents of an XF record. */
+ inline XclImpXF* GetXF( sal_uInt16 nXFIndex ) const
+ { return maXFList.GetObject( nXFIndex ); }
+
+ /** Returns the index to the Excel font used in the specified XF record. */
+ sal_uInt16 GetFontIndex( sal_uInt16 nXFIndex ) const;
+ /** Returns the Excel font used in the specified XF record. */
+ const XclImpFont* GetFont( sal_uInt16 nXFIndex ) const;
+
+ /** Creates all user defined style sheets. */
+ void CreateUserStyles();
+ /** Creates a cell style sheet of the passed XF and inserts it into the Calc document.
+ @return The pointer to the cell style sheet, or 0, if there is no style sheet. */
+ ScStyleSheet* CreateStyleSheet( sal_uInt16 nXFIndex );
+
+ /** Inserts formatting attributes from an XF to the specified area in the Calc document.
+ @param nForcedNumFmt If not set to NUMBERFORMAT_ENTRY_NOT_FOUND, it will overwrite
+ the number format of the XF. */
+ void ApplyPattern(
+ SCCOL nScCol1, SCROW nScRow1,
+ SCCOL nScCol2, SCROW nScRow2,
+ SCTAB nScTab, const XclImpXFIndex& rXFIndex );
+
+private:
+ typedef ScfDelList< XclImpStyle > XclImpStyleList;
+ typedef ::std::map< sal_uInt16, XclImpStyle* > XclImpStyleMap;
+
+ ScfDelList< XclImpXF > maXFList; /// List of contents of all XF record.
+ XclImpStyleList maBuiltinStyles; /// List of built-in cell styles.
+ XclImpStyleList maUserStyles; /// List of user defined cell styles.
+ XclImpStyleMap maStylesByXf; /// Maps XF records to cell styles.
+};
+
+// Buffer for XF indexes in cells =============================================
+
+/** Contains an (encoded) XF index for a range of rows in a single column. */
+class XclImpXFRange
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange )
+
+public:
+ SCROW mnScRow1; /// The first row of an equal-formatted range.
+ SCROW mnScRow2; /// The last row of an equal-formatted range.
+ XclImpXFIndex maXFIndex; /// Extended XF index.
+
+ inline explicit XclImpXFRange( SCROW nScRow, const XclImpXFIndex& rXFIndex );
+ inline explicit XclImpXFRange( SCROW nFirstScRow, SCROW nLastScRow, const XclImpXFIndex& rXFIndex );
+
+ /** Returns true, if nScRow is contained in own row range. */
+ inline bool Contains( SCROW nScRow ) const;
+
+ /** Returns true, if the range has been expanded. */
+ bool Expand( SCROW nScRow, const XclImpXFIndex& rXFIndex );
+ /** Returns true, if the range has been expanded. */
+ bool Expand( const XclImpXFRange& rNextRange );
+};
+
+inline XclImpXFRange::XclImpXFRange( SCROW nScRow, const XclImpXFIndex& rXFIndex ) :
+ mnScRow1( nScRow ),
+ mnScRow2( nScRow ),
+ maXFIndex( rXFIndex )
+{
+}
+
+inline XclImpXFRange::XclImpXFRange( SCROW nFirstScRow, SCROW nLastScRow, const XclImpXFIndex& rXFIndex ) :
+ mnScRow1( nFirstScRow ),
+ mnScRow2( nLastScRow ),
+ maXFIndex( rXFIndex )
+{
+}
+
+inline bool XclImpXFRange::Contains( SCROW nScRow ) const
+{
+ return (mnScRow1 <= nScRow) && (nScRow <= mnScRow2);
+}
+
+// ----------------------------------------------------------------------------
+
+/** Contains the XF indexes for every used cell in a column. */
+class XclImpXFRangeColumn : ScfNoCopy
+{
+public:
+ inline explicit XclImpXFRangeColumn() {}
+
+ /** Returns the first formatted cell range in this column. */
+ inline XclImpXFRange* First() { return maIndexList.First(); }
+ /** Returns the next formatted cell range in this column. */
+ inline XclImpXFRange* Next() { return maIndexList.Next(); }
+
+ /** Inserts a single row range into the list. */
+ void SetDefaultXF( const XclImpXFIndex& rXFIndex );
+
+ /** Inserts a new (encoded) XF index (first try to expand the last range). */
+ void SetXF( SCROW nScRow, const XclImpXFIndex& rXFIndex );
+
+private:
+ /** Finds the previous and next row range from row position nScRow.
+ @descr If an XF still exists, it is contained in rpPrevRange. */
+ void Find(
+ XclImpXFRange*& rpPrevRange,
+ XclImpXFRange*& rpNextRange,
+ ULONG& rnNextIndex,
+ SCROW nScRow ) const;
+
+ /** Tries to concatenate a range with its predecessor.
+ @descr The ranges must have the same XF index and must not have a gap.
+ The resulting range has the index nIndex-1. */
+ void TryConcatPrev( ULONG nIndex );
+
+private:
+ ScfDelList< XclImpXFRange > maIndexList; /// The list of XF index range.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains the XF indexes for every used cell in a single sheet. */
+class XclImpXFRangeBuffer : protected XclImpRoot, ScfNoCopy
+{
+public:
+ explicit XclImpXFRangeBuffer( const XclImpRoot& rRoot );
+ virtual ~XclImpXFRangeBuffer();
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Inserts a new XF index. */
+ void SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for blank cells. */
+ void SetBlankXF( const ScAddress& rScPos, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for boolean cells. */
+ void SetBoolXF( const ScAddress& rScPos, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for all cells in a row. */
+ void SetRowDefXF( SCROW nScRow, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for all cells in a column. */
+ void SetColumnDefXF( SCCOL nScCol, sal_uInt16 nXFIndex );
+
+ /** Inserts a range of hyperlink cells. */
+ void SetHyperlink( const XclRange& rXclRange, const String& rUrl );
+
+ /** Inserts the first cell of a merged cell range. */
+ void SetMerge( SCCOL nScCol, SCROW nScRow );
+ /** Inserts a complete merged cell range. */
+ void SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2 );
+
+ /** Applies styles and cell merging to the current sheet in the document. */
+ void Finalize();
+
+private:
+ /** Insertion mode of an XF index. */
+ enum XclImpXFInsertMode
+ {
+ xlXFModeCell, /// Filled cell.
+ xlXFModeBoolCell, /// Cell with a single Boolean value.
+ xlXFModeBlank, /// Blank cell.
+ xlXFModeRow /// Row default XF.
+ };
+
+private:
+ /** Inserts a new XF index for the specified cell type. */
+ void SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex, XclImpXFInsertMode eMode );
+
+ /** Copies border of the last cell of the range to the first cell to keep it visible
+ when the range is merged.
+ @param nLine
+ BOX_LINE_RIGHT = copy most-right border of top row;
+ BOX_LINE_BOTTOM = copy most-bottom border of first column. */
+ void SetBorderLine( const ScRange& rRange, SCTAB nScTab, USHORT nLine );
+
+private:
+ typedef ScfRef< XclImpXFRangeColumn > XclImpXFRangeColumnRef;
+ typedef ::std::vector< XclImpXFRangeColumnRef > XclImpXFRangeColumnVec;
+ typedef ::std::pair< XclRange, String > XclImpHyperlinkRange;
+ typedef ::std::list< XclImpHyperlinkRange > XclImpHyperlinkList;
+
+ XclImpXFRangeColumnVec maColumns; /// Array of column XF index buffers.
+ XclImpHyperlinkList maHyperlinks; /// Maps URLs to hyperlink cells.
+ ScRangeList maMergeList; /// List of merged cell ranges.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xiview.hxx b/sc/source/filter/inc/xiview.hxx
new file mode 100644
index 000000000000..2451d69ee01c
--- /dev/null
+++ b/sc/source/filter/inc/xiview.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIVIEW_HXX
+#define SC_XIVIEW_HXX
+
+#include "xlview.hxx"
+#include "xiroot.hxx"
+
+// Document view settings =====================================================
+
+/** Contains document view settings (WINDOW1 record). */
+class XclImpDocViewSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpDocViewSettings( const XclImpRoot& rRoot );
+
+ /** Reads a WINDOW1 record. */
+ void ReadWindow1( XclImpStream& rStrm );
+
+ /** Returns the Calc index of the displayed sheet. */
+ SCTAB GetDisplScTab() const;
+
+ /** Sets the view settings at the document. */
+ void Finalize();
+
+private:
+ XclDocViewData maData; /// Document view settings data.
+};
+
+// Sheet view settings ========================================================
+
+/** Contains all view settings for a single sheet.
+
+ Usage:
+ 1) When import filter starts reading a worksheet substream, inizialize an
+ instance of this class with the Initialize() function. This will set
+ all view options to Excel default values.
+ 2) Read all view related records using the Read*() functions.
+ 3) When import filter ends reading a worksheet substream, call Finalize()
+ to set all view settings to the current sheet of the Calc document.
+ */
+class XclImpTabViewSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpTabViewSettings( const XclImpRoot& rRoot );
+
+ /** Initializes the object to be used for a new sheet. */
+ void Initialize();
+
+ /** Reads a WINDOW2 record. */
+ void ReadWindow2( XclImpStream& rStrm, bool bChart );
+ /** Reads an SCL record. */
+ void ReadScl( XclImpStream& rStrm );
+ /** Reads a PANE record. */
+ void ReadPane( XclImpStream& rStrm );
+ /** Reads a SELECTION record. */
+ void ReadSelection( XclImpStream& rStrm );
+ /** Reads a SHEETEXT record (Tab Color). */
+ void ReadTabBgColor( XclImpStream& rStrm, XclImpPalette& rPal );
+ /** Sets the view settings at the current sheet or the extended sheet options object. */
+ void Finalize();
+
+private:
+ XclTabViewData maData; /// Sheet view settings data.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xladdress.hxx b/sc/source/filter/inc/xladdress.hxx
new file mode 100644
index 000000000000..0ac5ca3031a4
--- /dev/null
+++ b/sc/source/filter/inc/xladdress.hxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLADDRESS_HXX
+#define SC_XLADDRESS_HXX
+
+#include <vector>
+#include "address.hxx"
+
+class ScRangeList;
+class XclImpStream;
+class XclExpStream;
+
+// ============================================================================
+
+/** A 2D cell address struct with Excel column and row indexes. */
+struct XclAddress
+{
+ sal_uInt16 mnCol;
+ sal_uInt16 mnRow;
+
+ inline explicit XclAddress( ScAddress::Uninitialized ) {}
+ inline explicit XclAddress() : mnCol( 0 ), mnRow( 0 ) {}
+ inline explicit XclAddress( sal_uInt16 nCol, sal_uInt16 nRow ) : mnCol( nCol ), mnRow( nRow ) {}
+
+ inline void Set( sal_uInt16 nCol, sal_uInt16 nRow ) { mnCol = nCol; mnRow = nRow; }
+
+ void Read( XclImpStream& rStrm, bool bCol16Bit = true );
+ void Write( XclExpStream& rStrm, bool bCol16Bit = true ) const;
+};
+
+inline bool operator==( const XclAddress& rL, const XclAddress& rR )
+{
+ return (rL.mnCol == rR.mnCol) && (rL.mnRow == rR.mnRow);
+}
+
+inline bool operator<( const XclAddress& rL, const XclAddress& rR )
+{
+ return (rL.mnCol < rR.mnCol) || ((rL.mnCol == rR.mnCol) && (rL.mnRow < rR.mnRow));
+}
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclAddress& rXclPos )
+{
+ rXclPos.Read( rStrm );
+ return rStrm;
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclAddress& rXclPos )
+{
+ rXclPos.Write( rStrm );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+/** A 2D cell range address struct with Excel column and row indexes. */
+struct XclRange
+{
+ XclAddress maFirst;
+ XclAddress maLast;
+
+ inline explicit XclRange( ScAddress::Uninitialized e ) : maFirst( e ), maLast( e ) {}
+ inline explicit XclRange() {}
+ inline explicit XclRange( const XclAddress& rPos ) : maFirst( rPos ), maLast( rPos ) {}
+ inline explicit XclRange( const XclAddress& rFirst, const XclAddress& rLast ) : maFirst( rFirst ), maLast( rLast ) {}
+ inline explicit XclRange( sal_uInt16 nCol1, sal_uInt16 nRow1, sal_uInt16 nCol2, sal_uInt16 nRow2 ) :
+ maFirst( nCol1, nRow1 ), maLast( nCol2, nRow2 ) {}
+
+ inline void Set( const XclAddress& rFirst, const XclAddress& rLast )
+ { maFirst = rFirst; maLast = rLast; }
+ inline void Set( sal_uInt16 nCol1, sal_uInt16 nRow1, sal_uInt16 nCol2, sal_uInt16 nRow2 )
+ { maFirst.Set( nCol1, nRow1 ); maLast.Set( nCol2, nRow2 ); }
+
+ inline sal_uInt16 GetColCount() const { return maLast.mnCol - maFirst.mnCol + 1; }
+ inline sal_uInt16 GetRowCount() const { return maLast.mnRow - maFirst.mnRow + 1; }
+ bool Contains( const XclAddress& rPos ) const;
+
+ void Read( XclImpStream& rStrm, bool bCol16Bit = true );
+ void Write( XclExpStream& rStrm, bool bCol16Bit = true ) const;
+};
+
+inline bool operator==( const XclRange& rL, const XclRange& rR )
+{
+ return (rL.maFirst == rR.maFirst) && (rL.maLast == rR.maLast);
+}
+
+inline bool operator<( const XclRange& rL, const XclRange& rR )
+{
+ return (rL.maFirst < rR.maFirst) || ((rL.maFirst == rR.maFirst) && (rL.maLast < rR.maLast));
+}
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclRange& rXclRange )
+{
+ rXclRange.Read( rStrm );
+ return rStrm;
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclRange& rXclRange )
+{
+ rXclRange.Write( rStrm );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+/** A 2D cell range address list with Excel column and row indexes. */
+class XclRangeList : public ::std::vector< XclRange >
+{
+public:
+ inline explicit XclRangeList() {}
+
+ XclRange GetEnclosingRange() const;
+
+ void Read( XclImpStream& rStrm, bool bCol16Bit = true );
+ void Write( XclExpStream& rStrm, bool bCol16Bit = true ) const;
+ void WriteSubList( XclExpStream& rStrm,
+ size_t nBegin, size_t nCount, bool bCol16Bit = true ) const;
+};
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclRangeList& rXclRanges )
+{
+ rXclRanges.Read( rStrm );
+ return rStrm;
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclRangeList& rXclRanges )
+{
+ rXclRanges.Write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+class XclTracer;
+
+/** Base class for import/export address converters. */
+class XclAddressConverterBase
+{
+public:
+ explicit XclAddressConverterBase( XclTracer& rTracer, const ScAddress& rMaxPos );
+ virtual ~XclAddressConverterBase();
+
+ /** Returns whether the "some columns have been cut" warning box should be shown. */
+ inline bool IsColTruncated() const { return mbColTrunc; }
+ /** Returns whether the "some rows have been cut" warning box should be shown. */
+ inline bool IsRowTruncated() const { return mbRowTrunc; }
+ /** Returns whether the "some sheets have been cut" warning box should be shown. */
+ inline bool IsTabTruncated() const { return mbTabTrunc; }
+
+ // ------------------------------------------------------------------------
+
+ /** Checks if the passed sheet index is valid.
+ @param nScTab The sheet index to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the sheet index is not valid.
+ @return true = Sheet index in nScTab is valid. */
+ bool CheckScTab( SCTAB nScTab, bool bWarn );
+
+ // ------------------------------------------------------------------------
+protected:
+ XclTracer& mrTracer; /// Tracer for invalid addresses.
+ ScAddress maMaxPos; /// Default maximum position.
+ sal_uInt16 mnMaxCol; /// Maximum column index, as 16-bit value.
+ sal_uInt16 mnMaxRow; /// Maximum row index, as 16-bit value.
+ bool mbColTrunc; /// Flag for "columns truncated" warning box.
+ bool mbRowTrunc; /// Flag for "rows truncated" warning box.
+ bool mbTabTrunc; /// Flag for "tables truncated" warning box.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx
new file mode 100755
index 000000000000..13eda8619cc0
--- /dev/null
+++ b/sc/source/filter/inc/xlchart.hxx
@@ -0,0 +1,1486 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLCHART_HXX
+#define SC_XLCHART_HXX
+
+// disable/enable support for varied point colors property
+#define EXC_CHART2_VARYCOLORSBY_PROP 0
+// disable/enable restriction to hair lines in 3D bar charts (#i83151#)
+#define EXC_CHART2_3DBAR_HAIRLINES_ONLY 1
+
+#include <map>
+#include <tools/gen.hxx>
+#include "fapihelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace lang { class XMultiServiceFactory; }
+ namespace chart { class XChartDocument; }
+ namespace chart2 { class XChartDocument; }
+ namespace drawing { class XShape; }
+} } }
+
+class XclRoot;
+
+// Property names =============================================================
+
+// service names
+#define SERVICE_DRAWING_BITMAPTABLE CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" )
+#define SERVICE_DRAWING_DASHTABLE CREATE_OUSTRING( "com.sun.star.drawing.DashTable" )
+#define SERVICE_DRAWING_GRADIENTTABLE CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" )
+#define SERVICE_DRAWING_HATCHTABLE CREATE_OUSTRING( "com.sun.star.drawing.HatchTable" )
+
+#define SERVICE_CHART2_AXIS CREATE_OUSTRING( "com.sun.star.chart2.Axis" )
+#define SERVICE_CHART2_CARTESIANCOORDSYS2D CREATE_OUSTRING( "com.sun.star.chart2.CartesianCoordinateSystem2d" )
+#define SERVICE_CHART2_CARTESIANCOORDSYS3D CREATE_OUSTRING( "com.sun.star.chart2.CartesianCoordinateSystem3d" )
+#define SERVICE_CHART2_DATAPROVIDER CREATE_OUSTRING( "com.sun.star.chart2.data.DataProvider" )
+#define SERVICE_CHART2_DATASERIES CREATE_OUSTRING( "com.sun.star.chart2.DataSeries" )
+#define SERVICE_CHART2_DIAGRAM CREATE_OUSTRING( "com.sun.star.chart2.Diagram" )
+#define SERVICE_CHART2_ERRORBAR CREATE_OUSTRING( "com.sun.star.chart2.ErrorBar" )
+#define SERVICE_CHART2_EXPREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.ExponentialRegressionCurve" )
+#define SERVICE_CHART2_FORMATTEDSTRING CREATE_OUSTRING( "com.sun.star.chart2.FormattedString" )
+#define SERVICE_CHART2_LABELEDDATASEQ CREATE_OUSTRING( "com.sun.star.chart2.data.LabeledDataSequence" )
+#define SERVICE_CHART2_LEGEND CREATE_OUSTRING( "com.sun.star.chart2.Legend" )
+#define SERVICE_CHART2_LINEARREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.LinearRegressionCurve" )
+#define SERVICE_CHART2_LINEARSCALING CREATE_OUSTRING( "com.sun.star.chart2.LinearScaling" )
+#define SERVICE_CHART2_LOGREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicRegressionCurve" )
+#define SERVICE_CHART2_LOGSCALING CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicScaling" )
+#define SERVICE_CHART2_POLARCOORDSYS2D CREATE_OUSTRING( "com.sun.star.chart2.PolarCoordinateSystem2d" )
+#define SERVICE_CHART2_POLARCOORDSYS3D CREATE_OUSTRING( "com.sun.star.chart2.PolarCoordinateSystem3d" )
+#define SERVICE_CHART2_POTREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.PotentialRegressionCurve" )
+#define SERVICE_CHART2_TITLE CREATE_OUSTRING( "com.sun.star.chart2.Title" )
+
+// property names
+#define EXC_CHPROP_ADDITIONALSHAPES CREATE_OUSTRING( "AdditionalShapes" )
+#define EXC_CHPROP_ANCHORPOSITION CREATE_OUSTRING( "AnchorPosition" )
+#define EXC_CHPROP_ARRANGEORDER CREATE_OUSTRING( "ArrangeOrder" )
+#define EXC_CHPROP_ATTAXISINDEX CREATE_OUSTRING( "AttachedAxisIndex" )
+#define EXC_CHPROP_ATTRIBDATAPOINTS CREATE_OUSTRING( "AttributedDataPoints" )
+#define EXC_CHPROP_BLACKDAY CREATE_OUSTRING( "BlackDay" )
+#define EXC_CHPROP_COLOR CREATE_OUSTRING( "Color" )
+#define EXC_CHPROP_CONNECTBARS CREATE_OUSTRING( "ConnectBars" )
+#define EXC_CHPROP_CROSSOVERPOSITION CREATE_OUSTRING( "CrossoverPosition" )
+#define EXC_CHPROP_CROSSOVERVALUE CREATE_OUSTRING( "CrossoverValue" )
+#define EXC_CHPROP_CURVESTYLE CREATE_OUSTRING( "CurveStyle" )
+#define EXC_CHPROP_D3DCAMERAGEOMETRY CREATE_OUSTRING( "D3DCameraGeometry" )
+#define EXC_CHPROP_D3DSCENEAMBIENTCOLOR CREATE_OUSTRING( "D3DSceneAmbientColor" )
+#define EXC_CHPROP_D3DSCENELIGHTON1 CREATE_OUSTRING( "D3DSceneLightOn1" )
+#define EXC_CHPROP_D3DSCENELIGHTCOLOR2 CREATE_OUSTRING( "D3DSceneLightColor2" )
+#define EXC_CHPROP_D3DSCENELIGHTDIR2 CREATE_OUSTRING( "D3DSceneLightDirection2" )
+#define EXC_CHPROP_D3DSCENELIGHTON2 CREATE_OUSTRING( "D3DSceneLightOn2" )
+#define EXC_CHPROP_D3DSCENEPERSPECTIVE CREATE_OUSTRING( "D3DScenePerspective" )
+#define EXC_CHPROP_D3DSCENESHADEMODE CREATE_OUSTRING( "D3DSceneShadeMode" )
+#define EXC_CHPROP_D3DTRANSFORMMATRIX CREATE_OUSTRING( "D3DTransformMatrix" )
+#define EXC_CHPROP_DISPLAYLABELS CREATE_OUSTRING( "DisplayLabels" )
+#define EXC_CHPROP_ERRORBARSTYLE CREATE_OUSTRING( "ErrorBarStyle" )
+#define EXC_CHPROP_ERRORBARX CREATE_OUSTRING( "ErrorBarX" )
+#define EXC_CHPROP_ERRORBARY CREATE_OUSTRING( "ErrorBarY" )
+#define EXC_CHPROP_EXPANSION CREATE_OUSTRING( "Expansion" )
+#define EXC_CHPROP_FILLBITMAPMODE CREATE_OUSTRING( "FillBitmapMode" )
+#define EXC_CHPROP_FILLSTYLE CREATE_OUSTRING( "FillStyle" )
+#define EXC_CHPROP_GAPWIDTHSEQ CREATE_OUSTRING( "GapwidthSequence" )
+#define EXC_CHPROP_GEOMETRY3D CREATE_OUSTRING( "Geometry3D" )
+#define EXC_CHPROP_HASMAINTITLE CREATE_OUSTRING( "HasMainTitle" )
+#define EXC_CHPROP_INCLUDEHIDDENCELLS CREATE_OUSTRING( "IncludeHiddenCells" )
+#define EXC_CHPROP_JAPANESE CREATE_OUSTRING( "Japanese" )
+#define EXC_CHPROP_LABEL CREATE_OUSTRING( "Label" )
+#define EXC_CHPROP_LABELPLACEMENT CREATE_OUSTRING( "LabelPlacement" )
+#define EXC_CHPROP_LABELPOSITION CREATE_OUSTRING( "LabelPosition" )
+#define EXC_CHPROP_LABELSEPARATOR CREATE_OUSTRING( "LabelSeparator" )
+#define EXC_CHPROP_MAJORTICKS CREATE_OUSTRING( "MajorTickmarks" )
+#define EXC_CHPROP_MARKPOSITION CREATE_OUSTRING( "MarkPosition" )
+#define EXC_CHPROP_MINORTICKS CREATE_OUSTRING( "MinorTickmarks" )
+#define EXC_CHPROP_MISSINGVALUETREATMENT CREATE_OUSTRING( "MissingValueTreatment" )
+#define EXC_CHPROP_NEGATIVEERROR CREATE_OUSTRING( "NegativeError" )
+#define EXC_CHPROP_NUMBERFORMAT CREATE_OUSTRING( "NumberFormat" )
+#define EXC_CHPROP_OFFSET CREATE_OUSTRING( "Offset" )
+#define EXC_CHPROP_OVERLAPSEQ CREATE_OUSTRING( "OverlapSequence" )
+#define EXC_CHPROP_PERCENTAGENUMFMT CREATE_OUSTRING( "PercentageNumberFormat" )
+#define EXC_CHPROP_PERCENTDIAGONAL CREATE_OUSTRING( "PercentDiagonal" )
+#define EXC_CHPROP_PERSPECTIVE CREATE_OUSTRING( "Perspective" )
+#define EXC_CHPROP_POSITIVEERROR CREATE_OUSTRING( "PositiveError" )
+#define EXC_CHPROP_RELATIVEPOSITION CREATE_OUSTRING( "RelativePosition" )
+#define EXC_CHPROP_RIGHTANGLEDAXES CREATE_OUSTRING( "RightAngledAxes" )
+#define EXC_CHPROP_ROLE CREATE_OUSTRING( "Role" )
+#define EXC_CHPROP_ROTATIONHORIZONTAL CREATE_OUSTRING( "RotationHorizontal" )
+#define EXC_CHPROP_ROTATIONVERTICAL CREATE_OUSTRING( "RotationVertical" )
+#define EXC_CHPROP_SHOW CREATE_OUSTRING( "Show" )
+#define EXC_CHPROP_SHOWCORRELATION CREATE_OUSTRING( "ShowCorrelationCoefficient" )
+#define EXC_CHPROP_SHOWEQUATION CREATE_OUSTRING( "ShowEquation" )
+#define EXC_CHPROP_SHOWFIRST CREATE_OUSTRING( "ShowFirst" )
+#define EXC_CHPROP_SHOWHIGHLOW CREATE_OUSTRING( "ShowHighLow" )
+#define EXC_CHPROP_SHOWNEGATIVEERROR CREATE_OUSTRING( "ShowNegativeError" )
+#define EXC_CHPROP_SHOWPOSITIVEERROR CREATE_OUSTRING( "ShowPositiveError" )
+#define EXC_CHPROP_STACKCHARACTERS CREATE_OUSTRING( "StackCharacters" )
+#define EXC_CHPROP_STACKINGDIR CREATE_OUSTRING( "StackingDirection" )
+#define EXC_CHPROP_STARTINGANGLE CREATE_OUSTRING( "StartingAngle" )
+#define EXC_CHPROP_SWAPXANDYAXIS CREATE_OUSTRING( "SwapXAndYAxis" )
+#define EXC_CHPROP_SYMBOL CREATE_OUSTRING( "Symbol" )
+#define EXC_CHPROP_TEXTBREAK CREATE_OUSTRING( "TextBreak" )
+#define EXC_CHPROP_TEXTOVERLAP CREATE_OUSTRING( "TextOverlap" )
+#define EXC_CHPROP_TEXTROTATION CREATE_OUSTRING( "TextRotation" )
+#define EXC_CHPROP_USERINGS CREATE_OUSTRING( "UseRings" )
+#define EXC_CHPROP_VARYCOLORSBY CREATE_OUSTRING( "VaryColorsByPoint" )
+#define EXC_CHPROP_WEIGHT CREATE_OUSTRING( "Weight" )
+#define EXC_CHPROP_WHITEDAY CREATE_OUSTRING( "WhiteDay" )
+
+// data series roles
+#define EXC_CHPROP_ROLE_CATEG CREATE_OUSTRING( "categories" )
+#define EXC_CHPROP_ROLE_ERRORBARS_NEGX CREATE_OUSTRING( "error-bars-x-negative" )
+#define EXC_CHPROP_ROLE_ERRORBARS_NEGY CREATE_OUSTRING( "error-bars-y-negative" )
+#define EXC_CHPROP_ROLE_ERRORBARS_POSX CREATE_OUSTRING( "error-bars-x-positive" )
+#define EXC_CHPROP_ROLE_ERRORBARS_POSY CREATE_OUSTRING( "error-bars-y-positive" )
+#define EXC_CHPROP_ROLE_LABEL CREATE_OUSTRING( "label" )
+#define EXC_CHPROP_ROLE_SIZES CREATE_OUSTRING( "sizes" )
+#define EXC_CHPROP_ROLE_XVALUES CREATE_OUSTRING( "values-x" )
+#define EXC_CHPROP_ROLE_YVALUES CREATE_OUSTRING( "values-y" )
+#define EXC_CHPROP_ROLE_OPENVALUES CREATE_OUSTRING( "values-first" )
+#define EXC_CHPROP_ROLE_CLOSEVALUES CREATE_OUSTRING( "values-last" )
+#define EXC_CHPROP_ROLE_LOWVALUES CREATE_OUSTRING( "values-min" )
+#define EXC_CHPROP_ROLE_HIGHVALUES CREATE_OUSTRING( "values-max" )
+#define EXC_CHPROP_ROLE_SIZEVALUES CREATE_OUSTRING( "values-size" )
+
+// Constants and Enumerations =================================================
+
+const sal_Size EXC_CHART_PROGRESS_SIZE = 10;
+const sal_uInt16 EXC_CHART_AUTOROTATION = 0xFFFF; /// Automatic rotation, e.g. axis labels (internal use only).
+
+const sal_Int32 EXC_CHART_AXIS_NONE = -1; /// For internal use only.
+const sal_Int32 EXC_CHART_AXIS_X = 0; /// API X axis index.
+const sal_Int32 EXC_CHART_AXIS_Y = 1; /// API Y axis index.
+const sal_Int32 EXC_CHART_AXIS_Z = 2; /// API Z axis index.
+const sal_Int32 EXC_CHART_AXESSET_NONE = -1; /// For internal use only.
+const sal_Int32 EXC_CHART_AXESSET_PRIMARY = 0; /// API primary axes set index.
+const sal_Int32 EXC_CHART_AXESSET_SECONDARY = 1; /// API secondary axes set index.
+
+const sal_Int32 EXC_CHART_TOTALUNITS = 4000; /// Most chart objects are positioned in 1/4000 of chart area.
+const sal_Int32 EXC_CHART_PLOTAREAUNITS = 1000; /// For objects that are positioned in 1/1000 of plot area.
+
+// (0x0850) CHFRINFO ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRINFO = 0x0850;
+
+const sal_uInt8 EXC_CHFRINFO_EXCEL2000 = 9;
+const sal_uInt8 EXC_CHFRINFO_EXCELXP2003 = 10;
+const sal_uInt8 EXC_CHFRINFO_EXCEL2007 = 11;
+
+// (0x0852, 0x0853) CHFRBLOCKBEGIN, CHFRBLOCKEND ------------------------------
+
+const sal_uInt16 EXC_ID_CHFRBLOCKBEGIN = 0x0852;
+const sal_uInt16 EXC_ID_CHFRBLOCKEND = 0x0853;
+
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_AXESSET = 0;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_TEXT = 2;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_AXIS = 4;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_TYPEGROUP = 5;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_DATATABLE = 6;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_FRAME = 7;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_LEGEND = 9;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_LEGENDEX = 10;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_SERIES = 12;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_CHART = 13;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_DATAFORMAT = 14;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_DROPBAR = 15;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_UNKNOWN = 0xFFFF; /// For internal use only.
+
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_TITLE = 0;
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_DEFTEXT = 2;
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_AXISTITLE = 4;
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_DATALABEL = 5;
+
+const sal_uInt16 EXC_CHFRBLOCK_FRAME_STANDARD = 0;
+const sal_uInt16 EXC_CHFRBLOCK_FRAME_PLOTFRAME = 1;
+const sal_uInt16 EXC_CHFRBLOCK_FRAME_BACKGROUND = 2;
+
+// (0x086B) CHFRLABELPROPS ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRLABELPROPS = 0x086B;
+
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWSERIES = 0x0001;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWCATEG = 0x0002;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWVALUE = 0x0004;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWPERCENT = 0x0008;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWBUBBLE = 0x0010;
+
+// (0x1001) CHUNITS -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHUNITS = 0x1001;
+
+const sal_uInt16 EXC_CHUNITS_TWIPS = 0;
+const sal_uInt16 EXC_CHUNITS_PIXELS = 1;
+
+// (0x1002) CHCHART -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHCHART = 0x1002;
+
+// (0x1003) CHSERIES ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERIES = 0x1003;
+
+const sal_uInt16 EXC_CHSERIES_DATE = 0;
+const sal_uInt16 EXC_CHSERIES_NUMERIC = 1;
+const sal_uInt16 EXC_CHSERIES_SEQUENCE = 2;
+const sal_uInt16 EXC_CHSERIES_TEXT = 3;
+
+const sal_uInt16 EXC_CHSERIES_MAXSERIES = 255; /// Maximum valid series index.
+const sal_uInt16 EXC_CHSERIES_INVALID = 0xFFFF; /// Invalid series index (for internal use).
+
+// (0x1006) CHDATAFORMAT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDATAFORMAT = 0x1006;
+
+const sal_uInt16 EXC_CHDATAFORMAT_MAXPOINTCOUNT = 32000; /// Maximum number of data points.
+const sal_uInt16 EXC_CHDATAFORMAT_DEFAULT = 0xFFFD; /// As format index: global default for an axes set.
+const sal_uInt16 EXC_CHDATAFORMAT_UNKNOWN = 0xFFFE; /// As point index: unknown format, don't use.
+const sal_uInt16 EXC_CHDATAFORMAT_ALLPOINTS = 0xFFFF; /// As point index: default for a series.
+
+const sal_uInt16 EXC_CHDATAFORMAT_OLDCOLORS = 0x0001;
+
+// (0x1007) CHLINEFORMAT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLINEFORMAT = 0x1007;
+
+const sal_uInt16 EXC_CHLINEFORMAT_SOLID = 0;
+const sal_uInt16 EXC_CHLINEFORMAT_DASH = 1;
+const sal_uInt16 EXC_CHLINEFORMAT_DOT = 2;
+const sal_uInt16 EXC_CHLINEFORMAT_DASHDOT = 3;
+const sal_uInt16 EXC_CHLINEFORMAT_DASHDOTDOT = 4;
+const sal_uInt16 EXC_CHLINEFORMAT_NONE = 5;
+const sal_uInt16 EXC_CHLINEFORMAT_DARKTRANS = 6;
+const sal_uInt16 EXC_CHLINEFORMAT_MEDTRANS = 7;
+const sal_uInt16 EXC_CHLINEFORMAT_LIGHTTRANS = 8;
+
+const sal_Int16 EXC_CHLINEFORMAT_HAIR = -1;
+const sal_Int16 EXC_CHLINEFORMAT_SINGLE = 0;
+const sal_Int16 EXC_CHLINEFORMAT_DOUBLE = 1;
+const sal_Int16 EXC_CHLINEFORMAT_TRIPLE = 2;
+
+const sal_uInt16 EXC_CHLINEFORMAT_AUTO = 0x0001;
+const sal_uInt16 EXC_CHLINEFORMAT_SHOWAXIS = 0x0004;
+
+// (0x1009) CHMARKERFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHMARKERFORMAT = 0x1009;
+
+const sal_uInt16 EXC_CHMARKERFORMAT_NOSYMBOL = 0;
+const sal_uInt16 EXC_CHMARKERFORMAT_SQUARE = 1;
+const sal_uInt16 EXC_CHMARKERFORMAT_DIAMOND = 2;
+const sal_uInt16 EXC_CHMARKERFORMAT_TRIANGLE = 3;
+const sal_uInt16 EXC_CHMARKERFORMAT_CROSS = 4;
+const sal_uInt16 EXC_CHMARKERFORMAT_STAR = 5;
+const sal_uInt16 EXC_CHMARKERFORMAT_DOWJ = 6;
+const sal_uInt16 EXC_CHMARKERFORMAT_STDDEV = 7;
+const sal_uInt16 EXC_CHMARKERFORMAT_CIRCLE = 8;
+const sal_uInt16 EXC_CHMARKERFORMAT_PLUS = 9;
+
+const sal_uInt32 EXC_CHMARKERFORMAT_HAIRSIZE = 60; /// Automatic symbol size for hair lines.
+const sal_uInt32 EXC_CHMARKERFORMAT_SINGLESIZE = 100; /// Automatic symbol size for single lines.
+const sal_uInt32 EXC_CHMARKERFORMAT_DOUBLESIZE = 140; /// Automatic symbol size for double lines.
+const sal_uInt32 EXC_CHMARKERFORMAT_TRIPLESIZE = 180; /// Automatic symbol size for triple lines.
+
+const sal_uInt16 EXC_CHMARKERFORMAT_AUTO = 0x0001;
+const sal_uInt16 EXC_CHMARKERFORMAT_NOFILL = 0x0010;
+const sal_uInt16 EXC_CHMARKERFORMAT_NOLINE = 0x0020;
+
+// (0x100A) CHAREAFORMAT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAREAFORMAT = 0x100A;
+
+const sal_uInt16 EXC_CHAREAFORMAT_AUTO = 0x0001;
+const sal_uInt16 EXC_CHAREAFORMAT_INVERTNEG = 0x0002;
+
+// (0x100B) CHPIEFORMAT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPIEFORMAT = 0x100B;
+
+// (0x100C) CHATTACHEDLABEL ---------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHATTACHEDLABEL = 0x100C;
+
+const sal_uInt16 EXC_CHATTLABEL_SHOWVALUE = 0x0001;
+const sal_uInt16 EXC_CHATTLABEL_SHOWPERCENT = 0x0002;
+const sal_uInt16 EXC_CHATTLABEL_SHOWCATEGPERC = 0x0004;
+const sal_uInt16 EXC_CHATTLABEL_SMOOTHED = 0x0008; /// Smoothed line.
+const sal_uInt16 EXC_CHATTLABEL_SHOWCATEG = 0x0010;
+const sal_uInt16 EXC_CHATTLABEL_SHOWBUBBLE = 0x0020;
+
+// (0x100D) CHSTRING ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSTRING = 0x100D;
+
+// (0x1014) CHTYPEGROUP -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHTYPEGROUP = 0x1014;
+
+const sal_uInt16 EXC_CHTYPEGROUP_VARIEDCOLORS = 0x0001; /// Varied colors for points.
+
+// (0x1015) CHLEGEND ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLEGEND = 0x1015;
+
+const sal_uInt8 EXC_CHLEGEND_BOTTOM = 0;
+const sal_uInt8 EXC_CHLEGEND_CORNER = 1;
+const sal_uInt8 EXC_CHLEGEND_TOP = 2;
+const sal_uInt8 EXC_CHLEGEND_RIGHT = 3;
+const sal_uInt8 EXC_CHLEGEND_LEFT = 4;
+const sal_uInt8 EXC_CHLEGEND_NOTDOCKED = 7;
+
+const sal_uInt8 EXC_CHLEGEND_CLOSE = 0;
+const sal_uInt8 EXC_CHLEGEND_MEDIUM = 1;
+const sal_uInt8 EXC_CHLEGEND_OPEN = 2;
+
+const sal_uInt16 EXC_CHLEGEND_DOCKED = 0x0001;
+const sal_uInt16 EXC_CHLEGEND_AUTOSERIES = 0x0002;
+const sal_uInt16 EXC_CHLEGEND_AUTOPOSX = 0x0004;
+const sal_uInt16 EXC_CHLEGEND_AUTOPOSY = 0x0008;
+const sal_uInt16 EXC_CHLEGEND_STACKED = 0x0010;
+const sal_uInt16 EXC_CHLEGEND_DATATABLE = 0x0020;
+
+// (0x1017) CHBAR, CHCOLUMN ---------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHBAR = 0x1017;
+
+const sal_uInt16 EXC_CHBAR_HORIZONTAL = 0x0001;
+const sal_uInt16 EXC_CHBAR_STACKED = 0x0002;
+const sal_uInt16 EXC_CHBAR_PERCENT = 0x0004;
+const sal_uInt16 EXC_CHBAR_SHADOW = 0x0008;
+
+// (0x1018, 0x101A) CHLINE, CHAREA --------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLINE = 0x1018;
+const sal_uInt16 EXC_ID_CHAREA = 0x101A;
+
+const sal_uInt16 EXC_CHLINE_STACKED = 0x0001;
+const sal_uInt16 EXC_CHLINE_PERCENT = 0x0002;
+const sal_uInt16 EXC_CHLINE_SHADOW = 0x0004;
+
+// (0x1019) CHPIE -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPIE = 0x1019;
+
+const sal_uInt16 EXC_CHPIE_SHADOW = 0x0001;
+const sal_uInt16 EXC_CHPIE_LINES = 0x0002;
+
+// (0x101B) CHSCATTER ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSCATTER = 0x101B;
+
+const sal_uInt16 EXC_CHSCATTER_AREA = 1; /// Bubble area refers to value.
+const sal_uInt16 EXC_CHSCATTER_WIDTH = 2; /// Bubble width refers to value.
+
+const sal_uInt16 EXC_CHSCATTER_BUBBLES = 0x0001;
+const sal_uInt16 EXC_CHSCATTER_SHOWNEG = 0x0002;
+const sal_uInt16 EXC_CHSCATTER_SHADOW = 0x0004;
+
+// (0x001C) CHCHARTLINE -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHCHARTLINE = 0x101C;
+
+const sal_uInt16 EXC_CHCHARTLINE_DROP = 0; /// Drop lines.
+const sal_uInt16 EXC_CHCHARTLINE_HILO = 1; /// Hi-lo lines.
+const sal_uInt16 EXC_CHCHARTLINE_CONNECT = 2; /// Connector lines in stacked bar charts.
+
+// (0x101D) CHAXIS ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAXIS = 0x101D;
+
+const sal_uInt16 EXC_CHAXIS_X = 0;
+const sal_uInt16 EXC_CHAXIS_Y = 1;
+const sal_uInt16 EXC_CHAXIS_Z = 2;
+const sal_uInt16 EXC_CHAXIS_NONE = 0xFFFF; /// For internal use only.
+
+// (0x101E) CHTICK ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHTICK = 0x101E;
+
+const sal_uInt8 EXC_CHTICK_INSIDE = 0x01;
+const sal_uInt8 EXC_CHTICK_OUTSIDE = 0x02;
+
+const sal_uInt8 EXC_CHTICK_NOLABEL = 0;
+const sal_uInt8 EXC_CHTICK_LOW = 1; /// Below diagram/right of diagram.
+const sal_uInt8 EXC_CHTICK_HIGH = 2; /// Above diagram/left of diagram.
+const sal_uInt8 EXC_CHTICK_NEXT = 3; /// Next to axis.
+
+const sal_uInt8 EXC_CHTICK_TRANSPARENT = 1;
+const sal_uInt8 EXC_CHTICK_OPAQUE = 2;
+
+const sal_uInt16 EXC_CHTICK_AUTOCOLOR = 0x0001;
+const sal_uInt16 EXC_CHTICK_AUTOFILL = 0x0002;
+const sal_uInt16 EXC_CHTICK_AUTOROT = 0x0020;
+
+// (0x101F) CHVALUERANGE ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHVALUERANGE = 0x101F;
+
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMIN = 0x0001;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMAX = 0x0002;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMAJOR = 0x0004;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMINOR = 0x0008;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOCROSS = 0x0010;
+const sal_uInt16 EXC_CHVALUERANGE_LOGSCALE = 0x0020;
+const sal_uInt16 EXC_CHVALUERANGE_REVERSE = 0x0040; /// Axis direction reversed.
+const sal_uInt16 EXC_CHVALUERANGE_MAXCROSS = 0x0080; /// Other axis crosses at own maximum.
+const sal_uInt16 EXC_CHVALUERANGE_BIT8 = 0x0100; /// This bit is always set in BIFF5+.
+
+// (0x1020) CHLABELRANGE -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLABELRANGE = 0x1020;
+
+const sal_uInt16 EXC_CHLABELRANGE_BETWEEN = 0x0001; /// Axis between categories.
+const sal_uInt16 EXC_CHLABELRANGE_MAXCROSS = 0x0002; /// Other axis crosses at own maximum.
+const sal_uInt16 EXC_CHLABELRANGE_REVERSE = 0x0004; /// Axis direction reversed.
+
+// (0x1021) CHAXISLINE --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAXISLINE = 0x1021;
+
+const sal_uInt16 EXC_CHAXISLINE_AXISLINE = 0; /// Axis line itself.
+const sal_uInt16 EXC_CHAXISLINE_MAJORGRID = 1; /// Major grid line.
+const sal_uInt16 EXC_CHAXISLINE_MINORGRID = 2; /// Minor grid line.
+const sal_uInt16 EXC_CHAXISLINE_WALLS = 3; /// Walls (X, Z axis), floor (Y axis).
+
+// (0x1024) CHDEFAULTTEXT -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDEFAULTTEXT = 0x1024;
+
+const sal_uInt16 EXC_CHDEFTEXT_TEXTLABEL = 0; /// Default for text data labels (not used?).
+const sal_uInt16 EXC_CHDEFTEXT_NUMLABEL = 1; /// Default for numeric data labels (not used?).
+const sal_uInt16 EXC_CHDEFTEXT_GLOBAL = 2; /// Default text for all chart objects.
+const sal_uInt16 EXC_CHDEFTEXT_AXESSET = 3; /// Default text for axes and data points (BIFF8 only).
+const sal_uInt16 EXC_CHDEFTEXT_NONE = 0xFFFF; /// No default text available.
+
+// (0x1025) CHTEXT ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHTEXT = 0x1025;
+
+const sal_uInt8 EXC_CHTEXT_ALIGN_TOPLEFT = 1; /// Horizontal: left, vertical: top.
+const sal_uInt8 EXC_CHTEXT_ALIGN_CENTER = 2;
+const sal_uInt8 EXC_CHTEXT_ALIGN_BOTTOMRIGHT = 3; /// Horizontal: right, vertical: bottom.
+const sal_uInt8 EXC_CHTEXT_ALIGN_JUSTIFY = 4;
+const sal_uInt8 EXC_CHTEXT_ALIGN_DISTRIBUTE = 5;
+
+const sal_uInt16 EXC_CHTEXT_TRANSPARENT = 1;
+const sal_uInt16 EXC_CHTEXT_OPAQUE = 2;
+
+const sal_uInt16 EXC_CHTEXT_AUTOCOLOR = 0x0001; /// Automatic text color.
+const sal_uInt16 EXC_CHTEXT_SHOWSYMBOL = 0x0002; /// Legend symbol for data point caption.
+const sal_uInt16 EXC_CHTEXT_SHOWVALUE = 0x0004; /// Data point caption is the value.
+const sal_uInt16 EXC_CHTEXT_VERTICAL = 0x0008;
+const sal_uInt16 EXC_CHTEXT_AUTOTEXT = 0x0010; /// Label text generated from chart data.
+const sal_uInt16 EXC_CHTEXT_AUTOGEN = 0x0020; /// Text object is inserted automatically.
+const sal_uInt16 EXC_CHTEXT_DELETED = 0x0040; /// Text object is removed.
+const sal_uInt16 EXC_CHTEXT_AUTOFILL = 0x0080; /// Automatic text background mode (transparent/opaque).
+const sal_uInt16 EXC_CHTEXT_SHOWCATEGPERC = 0x0800; /// Data point caption is category and percent.
+const sal_uInt16 EXC_CHTEXT_SHOWPERCENT = 0x1000; /// Data point caption as percent.
+const sal_uInt16 EXC_CHTEXT_SHOWBUBBLE = 0x2000; /// Show bubble size.
+const sal_uInt16 EXC_CHTEXT_SHOWCATEG = 0x4000; /// Data point caption is category name.
+
+const sal_uInt16 EXC_CHTEXT_POS_DEFAULT = 0;
+const sal_uInt16 EXC_CHTEXT_POS_OUTSIDE = 1;
+const sal_uInt16 EXC_CHTEXT_POS_INSIDE = 2;
+const sal_uInt16 EXC_CHTEXT_POS_CENTER = 3;
+const sal_uInt16 EXC_CHTEXT_POS_AXIS = 4;
+const sal_uInt16 EXC_CHTEXT_POS_ABOVE = 5;
+const sal_uInt16 EXC_CHTEXT_POS_BELOW = 6;
+const sal_uInt16 EXC_CHTEXT_POS_LEFT = 7;
+const sal_uInt16 EXC_CHTEXT_POS_RIGHT = 8;
+const sal_uInt16 EXC_CHTEXT_POS_AUTO = 9;
+const sal_uInt16 EXC_CHTEXT_POS_MOVED = 10;
+
+// (0x1026) CHFONT ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFONT = 0x1026;
+
+// (0x1027) CHOBJECTLINK ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHOBJECTLINK = 0x1027;
+
+// link targets
+const sal_uInt16 EXC_CHOBJLINK_NONE = 0; /// No link target.
+const sal_uInt16 EXC_CHOBJLINK_TITLE = 1; /// Chart title.
+const sal_uInt16 EXC_CHOBJLINK_YAXIS = 2; /// Value axis (Y axis).
+const sal_uInt16 EXC_CHOBJLINK_XAXIS = 3; /// Category axis (X axis).
+const sal_uInt16 EXC_CHOBJLINK_DATA = 4; /// Data series/point.
+const sal_uInt16 EXC_CHOBJLINK_ZAXIS = 7; /// Series axis (Z axis).
+const sal_uInt16 EXC_CHOBJLINK_AXISUNIT = 12; /// Unit name for axis labels.
+
+// (0x1032) CHFRAME -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRAME = 0x1032;
+
+const sal_uInt16 EXC_CHFRAME_STANDARD = 0;
+const sal_uInt16 EXC_CHFRAME_SHADOW = 4;
+
+const sal_uInt16 EXC_CHFRAME_AUTOSIZE = 0x0001;
+const sal_uInt16 EXC_CHFRAME_AUTOPOS = 0x0002;
+
+// (0x1033, 0x1034) CHBEGIN, CHEND --------------------------------------------
+
+const sal_uInt16 EXC_ID_CHBEGIN = 0x1033;
+const sal_uInt16 EXC_ID_CHEND = 0x1034;
+
+// (0x1035) CHPLOTFRAME -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPLOTFRAME = 0x1035;
+
+// (0x103A) CHCHART3D ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHCHART3D = 0x103A;
+
+const sal_uInt16 EXC_CHCHART3D_REAL3D = 0x0001; /// true = real 3d perspective.
+const sal_uInt16 EXC_CHCHART3D_CLUSTER = 0x0002; /// false = Z axis, true = clustered/stacked.
+const sal_uInt16 EXC_CHCHART3D_AUTOHEIGHT = 0x0004; /// true = automatic height to width ratio.
+const sal_uInt16 EXC_CHCHART3D_HASWALLS = 0x0010; /// true = 3d chart has walls/floor.
+const sal_uInt16 EXC_CHCHART3D_2DWALLS = 0x0020; /// true = 2d wall/gridlines, no floor.
+
+// (0x103C) CHPICFORMAT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPICFORMAT = 0x103C;
+
+const sal_uInt16 EXC_CHPICFORMAT_NONE = 0; /// For internal use only.
+const sal_uInt16 EXC_CHPICFORMAT_STRETCH = 1; /// Bitmap stretched to area.
+const sal_uInt16 EXC_CHPICFORMAT_STACK = 2; /// Bitmap stacked.
+const sal_uInt16 EXC_CHPICFORMAT_SCALE = 3; /// Bitmap scaled to axis scale.
+
+const sal_uInt16 EXC_CHPICFORMAT_WMF = 2;
+const sal_uInt16 EXC_CHPICFORMAT_BMP = 9;
+const sal_uInt16 EXC_CHPICFORMAT_DEFAULT = 19;
+
+const sal_uInt16 EXC_CHPICFORMAT_WINDOWS = 0x0001;
+const sal_uInt16 EXC_CHPICFORMAT_MACOS = 0x0002;
+const sal_uInt16 EXC_CHPICFORMAT_FORMATONLY = 0x0100;
+const sal_uInt16 EXC_CHPICFORMAT_DEFAULTFLAGS = 0x0E00; /// Default flags for export.
+
+// (0x103D) CHDROPBAR ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDROPBAR = 0x103D;
+
+const sal_uInt16 EXC_CHDROPBAR_UP = 0;
+const sal_uInt16 EXC_CHDROPBAR_DOWN = 1;
+const sal_uInt16 EXC_CHDROPBAR_NONE = 0xFFFF;
+
+// (0x103E, 0x1040) CHRADARLINE, CHRADARAREA ----------------------------------
+
+const sal_uInt16 EXC_ID_CHRADARLINE = 0x103E;
+const sal_uInt16 EXC_ID_CHRADARAREA = 0x1040;
+
+const sal_uInt16 EXC_CHRADAR_AXISLABELS = 0x0001;
+const sal_uInt16 EXC_CHRADAR_SHADOW = 0x0002;
+
+// (0x103F) CHSURFACE ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSURFACE = 0x103F;
+
+const sal_uInt16 EXC_CHSURFACE_FILLED = 0x0001;
+const sal_uInt16 EXC_CHSURFACE_SHADING = 0x0002;
+
+// (0x1041) CHAXESSET ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAXESSET = 0x1041;
+
+const sal_uInt16 EXC_CHAXESSET_PRIMARY = 0;
+const sal_uInt16 EXC_CHAXESSET_SECONDARY = 1;
+const sal_uInt16 EXC_CHAXESSET_NONE = 0xFFFF; /// For internal use.
+
+// (0x1044) CHPROPERTIES ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPROPERTIES = 0x1044;
+
+const sal_uInt16 EXC_CHPROPS_MANSERIES = 0x0001; /// Manual series allocation.
+const sal_uInt16 EXC_CHPROPS_SHOWVISIBLEONLY = 0x0002; /// Show visible cells only.
+const sal_uInt16 EXC_CHPROPS_NORESIZE = 0x0004; /// Do not resize chart with window.
+const sal_uInt16 EXC_CHPROPS_MANPLOTAREA = 0x0008; /// Manual plot area mode.
+const sal_uInt16 EXC_CHPROPS_USEMANPLOTAREA = 0x0010; /// Manual plot area layout in CHFRAMEPOS record.
+
+const sal_uInt8 EXC_CHPROPS_EMPTY_SKIP = 0; /// Skip empty values.
+const sal_uInt8 EXC_CHPROPS_EMPTY_ZERO = 1; /// Plot empty values as zero.
+const sal_uInt8 EXC_CHPROPS_EMPTY_INTERPOLATE = 2; /// Interpolate empty values.
+
+// (0x1045) CHSERGROUP --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERGROUP = 0x1045;
+
+const sal_uInt16 EXC_CHSERGROUP_NONE = 0xFFFF; /// For internal use: no chart type group.
+
+// (0x1048, 0x0858) CHPIVOTREF ------------------------------------------------
+
+const sal_uInt16 EXC_ID5_CHPIVOTREF = 0x1048;
+const sal_uInt16 EXC_ID8_CHPIVOTREF = 0x0858;
+
+// (0x104A) CHSERPARENT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERPARENT = 0x104A;
+
+// (0x104B) CHSERTRENDLINE ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERTRENDLINE = 0x104B;
+
+const sal_uInt8 EXC_CHSERTREND_POLYNOMIAL = 0; /// If order is 1, trend line is linear.
+const sal_uInt8 EXC_CHSERTREND_EXPONENTIAL = 1;
+const sal_uInt8 EXC_CHSERTREND_LOGARITHMIC = 2;
+const sal_uInt8 EXC_CHSERTREND_POWER = 3;
+const sal_uInt8 EXC_CHSERTREND_MOVING_AVG = 4;
+
+// (0x104E) CHFORMAT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFORMAT = 0x104E;
+
+// (0x104F) CHFRAMEPOS --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRAMEPOS = 0x104F;
+
+const sal_uInt16 EXC_CHFRAMEPOS_POINTS = 0;
+const sal_uInt16 EXC_CHFRAMEPOS_ABSSIZE_POINTS = 1;
+const sal_uInt16 EXC_CHFRAMEPOS_PARENT = 2;
+const sal_uInt16 EXC_CHFRAMEPOS_DEFOFFSET_PLOT = 3;
+const sal_uInt16 EXC_CHFRAMEPOS_CHARTSIZE = 5;
+
+// (0x1050) CHFORMATRUNS ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFORMATRUNS = 0x1050;
+
+// (0x1051) CHSOURCELINK ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSOURCELINK = 0x1051;
+
+const sal_uInt8 EXC_CHSRCLINK_TITLE = 0;
+const sal_uInt8 EXC_CHSRCLINK_VALUES = 1;
+const sal_uInt8 EXC_CHSRCLINK_CATEGORY = 2;
+const sal_uInt8 EXC_CHSRCLINK_BUBBLES = 3;
+
+const sal_uInt8 EXC_CHSRCLINK_DEFAULT = 0;
+const sal_uInt8 EXC_CHSRCLINK_DIRECTLY = 1;
+const sal_uInt8 EXC_CHSRCLINK_WORKSHEET = 2;
+
+const sal_uInt16 EXC_CHSRCLINK_NUMFMT = 0x0001;
+
+// (0x105B) CHSERERRORBAR -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERERRORBAR = 0x105B;
+
+const sal_uInt8 EXC_CHSERERR_NONE = 0; /// For internal use only.
+const sal_uInt8 EXC_CHSERERR_XPLUS = 1;
+const sal_uInt8 EXC_CHSERERR_XMINUS = 2;
+const sal_uInt8 EXC_CHSERERR_YPLUS = 3;
+const sal_uInt8 EXC_CHSERERR_YMINUS = 4;
+
+const sal_uInt8 EXC_CHSERERR_PERCENT = 1;
+const sal_uInt8 EXC_CHSERERR_FIXED = 2;
+const sal_uInt8 EXC_CHSERERR_STDDEV = 3;
+const sal_uInt8 EXC_CHSERERR_CUSTOM = 4;
+const sal_uInt8 EXC_CHSERERR_STDERR = 5;
+
+const sal_uInt8 EXC_CHSERERR_END_BLANK = 0; /// Line end: blank.
+const sal_uInt8 EXC_CHSERERR_END_TSHAPE = 1; /// Line end: t-shape.
+
+// (0x105D) CHSERIESFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERIESFORMAT = 0x105D;
+
+const sal_uInt16 EXC_CHSERIESFORMAT_SMOOTHED = 0x0001;
+const sal_uInt16 EXC_CHSERIESFORMAT_BUBBLE3D = 0x0002;
+const sal_uInt16 EXC_CHSERIESFORMAT_SHADOW = 0x0004;
+
+// (0x105F) CH3DDATAFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CH3DDATAFORMAT = 0x105F;
+
+const sal_uInt8 EXC_CH3DDATAFORMAT_RECT = 0; /// Rectangular base.
+const sal_uInt8 EXC_CH3DDATAFORMAT_CIRC = 1; /// Circular base.
+
+const sal_uInt8 EXC_CH3DDATAFORMAT_STRAIGHT = 0; /// Straight to top.
+const sal_uInt8 EXC_CH3DDATAFORMAT_SHARP = 1; /// Sharp top.
+const sal_uInt8 EXC_CH3DDATAFORMAT_TRUNC = 2; /// Shart top, truncated.
+
+// (0x1061) CHPIEEXT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPIEEXT = 0x1061;
+
+// (0x1066) CHESCHERFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHESCHERFORMAT = 0x1066;
+
+// Other record IDs -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHWRAPPEDRECORD = 0x0851;
+const sal_uInt16 EXC_ID_CHUNITPROPERTIES = 0x0857;
+const sal_uInt16 EXC_ID_CHUSEDAXESSETS = 0x1046;
+const sal_uInt16 EXC_ID_CHLABELRANGE2 = 0x1062;
+const sal_uInt16 EXC_ID_CHPLOTGROWTH = 0x1064;
+const sal_uInt16 EXC_ID_CHSERINDEX = 0x1065;
+const sal_uInt16 EXC_ID_CHUNKNOWN = 0xFFFF;
+
+// ============================================================================
+// Structs and classes
+// ============================================================================
+
+// Common =====================================================================
+
+struct XclChRectangle
+{
+ sal_Int32 mnX; /// X position of the object in 1/4000 of chart width.
+ sal_Int32 mnY; /// Y position of the object in 1/4000 of chart height.
+ sal_Int32 mnWidth; /// Width of the object in 1/4000 of chart width.
+ sal_Int32 mnHeight; /// Height of the object in 1/4000 of chart height.
+
+ explicit XclChRectangle();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Specifies the position of a data series or data point. */
+struct XclChDataPointPos
+{
+ sal_uInt16 mnSeriesIdx; /// Series index of series or a data point.
+ sal_uInt16 mnPointIdx; /// Index of a data point inside a series.
+
+ explicit XclChDataPointPos(
+ sal_uInt16 nSeriesIdx = EXC_CHSERIES_INVALID,
+ sal_uInt16 nPointIdx = EXC_CHDATAFORMAT_ALLPOINTS );
+};
+
+bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR );
+
+// ----------------------------------------------------------------------------
+
+/** Contains the type and context of a block of future records which are
+ guarded by CHFRBLOCKBEGIN and CHFRBLOCKEND records. */
+struct XclChFrBlock
+{
+ sal_uInt16 mnType; /// Type of the future record block.
+ sal_uInt16 mnContext; /// Context dependent on type.
+ sal_uInt16 mnValue1; /// Optional primary value for current context.
+ sal_uInt16 mnValue2; /// Optional secondary value for current context.
+
+ explicit XclChFrBlock( sal_uInt16 nType );
+};
+
+// Frame formatting ===========================================================
+
+struct XclChFramePos
+{
+ XclChRectangle maRect; /// Object dependent position data.
+ sal_uInt16 mnTLMode; /// Top-left position mode.
+ sal_uInt16 mnBRMode; /// Bottom-right position mode.
+
+ explicit XclChFramePos();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChLineFormat
+{
+ Color maColor; /// Line color.
+ sal_uInt16 mnPattern; /// Line pattern (solid, dashed, ...).
+ sal_Int16 mnWeight; /// Line weight (hairline, single, ...).
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChLineFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChAreaFormat
+{
+ Color maPattColor; /// Pattern color.
+ Color maBackColor; /// Pattern background color.
+ sal_uInt16 mnPattern; /// Fill pattern.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChAreaFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+class SfxItemSet;
+class EscherPropertyContainer;
+
+struct XclChEscherFormat
+{
+ typedef ScfRef< SfxItemSet > SfxItemSetRef;
+ typedef ScfRef< EscherPropertyContainer > EscherPropSetRef;
+
+ SfxItemSetRef mxItemSet; /// Item set for Escher properties import.
+ EscherPropSetRef mxEscherSet; /// Container for Escher properties export.
+
+ explicit XclChEscherFormat();
+ ~XclChEscherFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChPicFormat
+{
+ sal_uInt16 mnBmpMode; /// Bitmap mode, e.g. stretched, stacked.
+ sal_uInt16 mnFormat; /// Image data format (WMF, BMP).
+ sal_uInt16 mnFlags; /// Additional flags.
+ double mfScale; /// Picture scaling (units).
+
+ explicit XclChPicFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChFrame
+{
+ sal_uInt16 mnFormat; /// Format type of the frame.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChFrame();
+};
+
+// Source links ===============================================================
+
+struct XclChSourceLink
+{
+ sal_uInt8 mnDestType; /// Type of the destination (title, values, ...).
+ sal_uInt8 mnLinkType; /// Link type (directly, linked to worksheet, ...).
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnNumFmtIdx; /// Number format index.
+
+ explicit XclChSourceLink();
+};
+
+// Text =======================================================================
+
+struct XclChObjectLink
+{
+ XclChDataPointPos maPointPos; /// Position of the data point.
+ sal_uInt16 mnTarget; /// Target of the link.
+
+ explicit XclChObjectLink();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChFrLabelProps
+{
+ String maSeparator; /// Separator between label values.
+ sal_uInt16 mnFlags; /// Flags indicating which values to be displayed.
+
+ explicit XclChFrLabelProps();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChText
+{
+ XclChRectangle maRect; /// Position of the text object.
+ Color maTextColor; /// Text color.
+ sal_uInt8 mnHAlign; /// Horizontal alignment.
+ sal_uInt8 mnVAlign; /// Vertical alignment.
+ sal_uInt16 mnBackMode; /// Background mode: transparent, opaque.
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnFlags2; /// Text object placement and text direction (BIFF8+).
+ sal_uInt16 mnRotation; /// Text object rotation (BIFF8+).
+
+ explicit XclChText();
+};
+
+// Data series ================================================================
+
+struct XclChMarkerFormat
+{
+ Color maLineColor; /// Border line color.
+ Color maFillColor; /// Fill color.
+ sal_uInt32 mnMarkerSize; /// Size of a marker
+ sal_uInt16 mnMarkerType; /// Marker type (none, diamond, ...).
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChMarkerFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclCh3dDataFormat
+{
+ sal_uInt8 mnBase; /// Base form.
+ sal_uInt8 mnTop; /// Top egde mode.
+
+ explicit XclCh3dDataFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChDataFormat
+{
+ XclChDataPointPos maPointPos; /// Position of the data point or series.
+ sal_uInt16 mnFormatIdx; /// Formatting index for automatic colors.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChDataFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChSerTrendLine
+{
+ double mfIntercept; /// Forced intercept.
+ double mfForecastFor; /// Counter to forecast forward.
+ double mfForecastBack; /// Counter to forecast backward.
+ sal_uInt8 mnLineType; /// Type of the trend line.
+ sal_uInt8 mnOrder; /// Polynomial order or moving average counter.
+ sal_uInt8 mnShowEquation; /// 1 = Show equation.
+ sal_uInt8 mnShowRSquared; /// 1 = Show R-squared.
+
+ explicit XclChSerTrendLine();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChSerErrorBar
+{
+ double mfValue; /// Fixed value for several source types.
+ sal_uInt16 mnValueCount; /// Number of custom error values.
+ sal_uInt8 mnBarType; /// Type of the error bar (X/Y).
+ sal_uInt8 mnSourceType; /// Type of source values.
+ sal_uInt8 mnLineEnd; /// Type of the line ends.
+
+ explicit XclChSerErrorBar();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChSeries
+{
+ sal_uInt16 mnCategType; /// Data type for category entries.
+ sal_uInt16 mnValueType; /// Data type for value entries.
+ sal_uInt16 mnBubbleType; /// Data type for bubble entries.
+ sal_uInt16 mnCategCount; /// Number of category entries.
+ sal_uInt16 mnValueCount; /// Number of value entries.
+ sal_uInt16 mnBubbleCount; /// Number of bubble entries.
+
+ explicit XclChSeries();
+};
+
+// Chart type groups ==========================================================
+
+struct XclChType
+{
+ sal_Int16 mnOverlap; /// Bar overlap width (CHBAR).
+ sal_Int16 mnGap; /// Gap between bars (CHBAR).
+ sal_uInt16 mnRotation; /// Rotation angle of first pie (CHPIE).
+ sal_uInt16 mnPieHole; /// Hole size in donut chart (CHPIE).
+ sal_uInt16 mnBubbleSize; /// Bubble size in bubble chart (CHSCATTER).
+ sal_uInt16 mnBubbleType; /// Bubble type in bubble chart (CHSCATTER).
+ sal_uInt16 mnFlags; /// Additional flags (all chart types).
+
+ explicit XclChType();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChChart3d
+{
+ sal_uInt16 mnRotation; /// Rotation (0...359deg).
+ sal_Int16 mnElevation; /// Elevation (-90...+90deg).
+ sal_uInt16 mnEyeDist; /// Eye distance to chart (0...100).
+ sal_uInt16 mnRelHeight; /// Height relative to width.
+ sal_uInt16 mnRelDepth; /// Depth relative to width.
+ sal_uInt16 mnDepthGap; /// Space between series.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChChart3d();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChLegend
+{
+ XclChRectangle maRect; /// Position of the legend.
+ sal_uInt8 mnDockMode; /// Docking mode.
+ sal_uInt8 mnSpacing; /// Spacing between elements.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChLegend();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChTypeGroup
+{
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnGroupIdx; /// Chart type group index.
+
+ explicit XclChTypeGroup();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChProperties
+{
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt8 mnEmptyMode; /// Plotting mode for empty cells.
+
+ explicit XclChProperties();
+};
+
+// Axes =======================================================================
+
+struct XclChLabelRange
+{
+ sal_uInt16 mnCross; /// Crossing position of other axis.
+ sal_uInt16 mnLabelFreq; /// Frequency of labels.
+ sal_uInt16 mnTickFreq; /// Frequency of ticks.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChLabelRange();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChValueRange
+{
+ double mfMin; /// Minimum value on axis.
+ double mfMax; /// Maximum value on axis.
+ double mfMajorStep; /// Distance for major grid lines.
+ double mfMinorStep; /// Distance for minor grid lines.
+ double mfCross; /// Crossing position of other axis.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChValueRange();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChTick
+{
+ Color maTextColor; /// Tick labels color.
+ sal_uInt8 mnMajor; /// Type of tick marks of major grid.
+ sal_uInt8 mnMinor; /// Type of tick marks of minor grid.
+ sal_uInt8 mnLabelPos; /// Position of labels relative to axis.
+ sal_uInt8 mnBackMode; /// Background mode: transparent, opaque.
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnRotation; /// Tick labels angle (BIFF8+).
+
+ explicit XclChTick();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChAxis
+{
+ sal_uInt16 mnType; /// Axis type.
+
+ explicit XclChAxis();
+
+ /** Returns the axis dimension index used by the chart API. */
+ sal_Int32 GetApiAxisDimension() const;
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChAxesSet
+{
+ XclChRectangle maRect; /// Position of the axes set (inner plot area).
+ sal_uInt16 mnAxesSetId; /// Primary/secondary axes set.
+
+ explicit XclChAxesSet();
+
+ /** Returns the axes set index used by the chart API. */
+ sal_Int32 GetApiAxesSetIndex() const;
+};
+
+// Property mode ==============================================================
+
+/** Specifies the type of a formatting. This results in different property names. */
+enum XclChPropertyMode
+{
+ EXC_CHPROPMODE_COMMON, /// Common objects, no special handling.
+ EXC_CHPROPMODE_LINEARSERIES, /// Specific to data series drawn as lines.
+ EXC_CHPROPMODE_FILLEDSERIES /// Specific to data series drawn as areas.
+};
+
+// Static helper functions ====================================================
+
+/** Contains static helper functions for the chart filters. */
+class XclChartHelper
+{
+public:
+ /** Returns a palette index for automatic series line colors. */
+ static sal_uInt16 GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx );
+ /** Returns a palette index for automatic series fill colors. */
+ static sal_uInt16 GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx );
+ /** Returns a transparency value for automatic series fill colors. */
+ static sal_uInt8 GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx );
+ /** Returns an automatic symbol index for the passed format index. */
+ static sal_uInt16 GetAutoMarkerType( sal_uInt16 nFormatIdx );
+ /** Returns true, if the passed marker type is filled. */
+ static bool HasMarkerFillColor( sal_uInt16 nMarkerType );
+ /** Returns the role name for a manual data source for error bars. */
+ static ::rtl::OUString GetErrorBarValuesRole( sal_uInt8 nBarType );
+};
+
+// Chart formatting info provider =============================================
+
+/** Enumerates different object types for specific automatic formatting behaviour. */
+enum XclChObjectType
+{
+ EXC_CHOBJTYPE_BACKGROUND, /// Chart background.
+ EXC_CHOBJTYPE_PLOTFRAME, /// Wall formatting in 2d charts.
+ EXC_CHOBJTYPE_WALL3D, /// Wall formatting in 3d charts.
+ EXC_CHOBJTYPE_FLOOR3D, /// Floor formatting in 3d charts.
+ EXC_CHOBJTYPE_TEXT, /// Text boxes (titles, data point labels).
+ EXC_CHOBJTYPE_LEGEND, /// Chart legend.
+ EXC_CHOBJTYPE_LINEARSERIES, /// Series formatting in a chart supporting line formatting only.
+ EXC_CHOBJTYPE_FILLEDSERIES, /// Series formatting in a chart supporting area formatting.
+ EXC_CHOBJTYPE_AXISLINE, /// Axis line format.
+ EXC_CHOBJTYPE_GRIDLINE, /// Axis grid line format.
+ EXC_CHOBJTYPE_TRENDLINE, /// Series trend line.
+ EXC_CHOBJTYPE_ERRORBAR, /// Series error bar.
+ EXC_CHOBJTYPE_CONNECTLINE, /// Data point connector line.
+ EXC_CHOBJTYPE_HILOLINE, /// High/low lines in stock charts.
+ EXC_CHOBJTYPE_WHITEDROPBAR, /// White-day drop bar in stock charts.
+ EXC_CHOBJTYPE_BLACKDROPBAR /// Black-day drop bar in stock charts.
+};
+
+/** Enumerates different types to handle missing frame objects. */
+enum XclChFrameType
+{
+ EXC_CHFRAMETYPE_AUTO, /// Missing frame represents automatic formatting.
+ EXC_CHFRAMETYPE_INVISIBLE /// Missing frame represents invisible formatting.
+};
+
+/** Contains information about auto formatting of a specific chart object type. */
+struct XclChFormatInfo
+{
+ XclChObjectType meObjType; /// Object type for automatic format.
+ XclChPropertyMode mePropMode; /// Property mode for property set helper.
+ sal_uInt16 mnAutoLineColorIdx; /// Automatic line color index.
+ sal_Int16 mnAutoLineWeight; /// Automatic line weight (hairline, single, ...).
+ sal_uInt16 mnAutoPattColorIdx; /// Automatic fill pattern color index.
+ XclChFrameType meDefFrameType; /// Default format type for missing frame objects.
+ bool mbCreateDefFrame; /// true = Create missing frame objects on import.
+ bool mbDeleteDefFrame; /// true = Delete default frame formatting on export.
+ bool mbIsFrame; /// true = Object is a frame, false = Object is a line.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Provides access to chart auto formatting for all available object types. */
+class XclChFormatInfoProvider
+{
+public:
+ explicit XclChFormatInfoProvider();
+
+ /** Returns an info struct about auto formatting for the passed object type. */
+ const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
+
+private:
+ typedef ::std::map< XclChObjectType, const XclChFormatInfo* > XclFmtInfoMap;
+ XclFmtInfoMap maInfoMap; /// Maps object type to formatting data.
+};
+
+// Chart type info provider ===================================================
+
+/** Enumerates all kinds of different chart types. */
+enum XclChTypeId
+{
+ EXC_CHTYPEID_BAR, /// Vertical bar chart.
+ EXC_CHTYPEID_HORBAR, /// Horizontal bar chart.
+ EXC_CHTYPEID_LINE, /// Line chart.
+ EXC_CHTYPEID_AREA, /// Area chart.
+ EXC_CHTYPEID_STOCK, /// Stock chart.
+ EXC_CHTYPEID_RADARLINE, /// Linear radar chart.
+ EXC_CHTYPEID_RADARAREA, /// Filled radar chart.
+ EXC_CHTYPEID_PIE, /// Pie chart.
+ EXC_CHTYPEID_DONUT, /// Donut chart.
+ EXC_CHTYPEID_PIEEXT, /// Pie-to-pie or pie-to-bar chart.
+ EXC_CHTYPEID_SCATTER, /// Scatter (XY) chart.
+ EXC_CHTYPEID_BUBBLES, /// Bubble chart.
+ EXC_CHTYPEID_SURFACE, /// Surface chart.
+ EXC_CHTYPEID_UNKNOWN /// Default for unknown chart types.
+};
+
+/** Enumerates different categories of similar chart types. */
+enum XclChTypeCateg
+{
+ EXC_CHTYPECATEG_BAR, /// Bar charts (horizontal or vertical).
+ EXC_CHTYPECATEG_LINE, /// Line charts (line, area, stock charts).
+ EXC_CHTYPECATEG_RADAR, /// Radar charts (linear or filled).
+ EXC_CHTYPECATEG_PIE, /// Pie and donut charts.
+ EXC_CHTYPECATEG_SCATTER, /// Scatter and bubble charts.
+ EXC_CHTYPECATEG_SURFACE /// Surface charts.
+};
+
+/** Enumerates modes for varying point colors in a series. */
+enum XclChVarPointMode
+{
+ EXC_CHVARPOINT_NONE, /// No varied colors supported.
+ EXC_CHVARPOINT_SINGLE, /// Only supported, if type group contains only one series.
+ EXC_CHVARPOINT_MULTI /// Supported for multiple series in a chart type group.
+};
+
+/** Contains information for a chart type. */
+struct XclChTypeInfo
+{
+ XclChTypeId meTypeId; /// Unique chart type identifier.
+ XclChTypeCateg meTypeCateg; /// Chart type category this type belongs to.
+ sal_uInt16 mnRecId; /// Record identifier written to the file.
+ const sal_Char* mpcServiceName; /// Service name of the type.
+ XclChVarPointMode meVarPointMode; /// Mode for varying point colors.
+ sal_Int32 mnDefaultLabelPos; /// Default data label position (API constant).
+ bool mbCombinable2d; /// true = Types can be combined in one axes set.
+ bool mbSupports3d; /// true = 3d type allowed, false = Only 2d type.
+ bool mbPolarCoordSystem; /// true = Polar, false = Cartesian.
+ bool mbSeriesIsFrame2d; /// true = Series with area formatting (2d charts).
+ bool mbSeriesIsFrame3d; /// true = Series with area formatting (3d charts).
+ bool mbSingleSeriesVis; /// true = Only first series visible.
+ bool mbCategoryAxis; /// true = X axis contains categories.
+ bool mbSwappedAxesSet; /// true = X and Y axes are swapped.
+ bool mbSupportsStacking; /// true = Series can be stacked on each other.
+ bool mbReverseSeries; /// true = Insert unstacked series in reverse order.
+ bool mbTicksBetweenCateg; /// true = X axis ticks between categories.
+};
+
+/** Extended chart type information and access functions. */
+struct XclChExtTypeInfo : public XclChTypeInfo
+{
+ bool mb3dChart; /// Chart is actually a 3D chart.
+ bool mbSpline; /// Series lines are smoothed.
+
+ explicit XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo );
+
+ void Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline );
+
+ /** Returns true, if this chart type supports area formatting for its series. */
+ inline bool IsSeriesFrameFormat() const
+ { return mb3dChart ? mbSeriesIsFrame3d : mbSeriesIsFrame2d; }
+ /** Returns the correct object type identifier for series and data points. */
+ inline XclChObjectType GetSeriesObjectType() const
+ { return IsSeriesFrameFormat() ? EXC_CHOBJTYPE_FILLEDSERIES : EXC_CHOBJTYPE_LINEARSERIES; }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Provides access to chart type info structs for all available chart types. */
+class XclChTypeInfoProvider
+{
+public:
+ explicit XclChTypeInfoProvider();
+
+ /** Returns chart type info for a unique chart type identifier. */
+ const XclChTypeInfo& GetTypeInfo( XclChTypeId eType ) const;
+ /** Returns the first fitting chart type info for an Excel chart type record identifier. */
+ const XclChTypeInfo& GetTypeInfoFromRecId( sal_uInt16 nRecId ) const;
+ /** Returns the first fitting chart type info for the passed service name. */
+ const XclChTypeInfo& GetTypeInfoFromService( const ::rtl::OUString& rServiceName ) const;
+
+private:
+ typedef ::std::map< XclChTypeId, const XclChTypeInfo* > XclChTypeInfoMap;
+ XclChTypeInfoMap maInfoMap; /// Maps chart types to type info data.
+};
+
+// Chart text and title object helpers ========================================
+
+/** Enumerates different text box types for default text formatting and title
+ positioning. */
+enum XclChTextType
+{
+ EXC_CHTEXTTYPE_TITLE, /// Chart title.
+ EXC_CHTEXTTYPE_LEGEND, /// Chart legend.
+ EXC_CHTEXTTYPE_AXISTITLE, /// Chart axis titles.
+ EXC_CHTEXTTYPE_AXISLABEL, /// Chart axis labels.
+ EXC_CHTEXTTYPE_DATALABEL /// Data point labels.
+};
+
+/** A map key for text and title objects. */
+struct XclChTextKey : public ::std::pair< XclChTextType, ::std::pair< sal_uInt16, sal_uInt16 > >
+{
+ inline explicit XclChTextKey( XclChTextType eTextType, sal_uInt16 nMainIdx = 0, sal_uInt16 nSubIdx = 0 )
+ { first = eTextType; second.first = nMainIdx; second.second = nSubIdx; }
+};
+
+/** Function prototype receiving a chart document and returning a title shape. */
+typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ (*XclChGetShapeFunc)( const ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartDocument >& );
+
+// Property helpers ===========================================================
+
+class XclChObjectTable
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > XNameContainerRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > XServiceFactoryRef;
+
+public:
+ explicit XclChObjectTable( XServiceFactoryRef xFactory,
+ const ::rtl::OUString& rServiceName, const ::rtl::OUString& rObjNameBase );
+
+ /** Returns a named formatting object from the chart document. */
+ ::com::sun::star::uno::Any GetObject( const ::rtl::OUString& rObjName );
+ /** Insertes a named formatting object into the chart document. */
+ ::rtl::OUString InsertObject( const ::com::sun::star::uno::Any& rObj );
+
+private:
+ XServiceFactoryRef mxFactory; /// Factory to create the container.
+ XNameContainerRef mxContainer; /// Container for the objects.
+ ::rtl::OUString maServiceName; /// Service name to create the container.
+ ::rtl::OUString maObjNameBase; /// Base of names for inserted objects.
+ sal_Int32 mnIndex; /// Index to create unique identifiers.
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclFontData;
+
+/** Helper class for usage of property sets. */
+class XclChPropSetHelper
+{
+public:
+ explicit XclChPropSetHelper();
+
+ /** Reads all line properties from the passed property set. */
+ void ReadLineProperties(
+ XclChLineFormat& rLineFmt,
+ XclChObjectTable& rDashTable,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode );
+ /** Reads solid area properties from the passed property set.
+ @return true = object contains complex fill properties. */
+ bool ReadAreaProperties(
+ XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode );
+ /** Reads gradient or bitmap area properties from the passed property set. */
+ void ReadEscherProperties(
+ XclChEscherFormat& rEscherFmt,
+ XclChPicFormat& rPicFmt,
+ XclChObjectTable& rGradientTable,
+ XclChObjectTable& rHatchTable,
+ XclChObjectTable& rBitmapTable,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode );
+ /** Reads all marker properties from the passed property set. */
+ void ReadMarkerProperties(
+ XclChMarkerFormat& rMarkerFmt,
+ const ScfPropertySet& rPropSet,
+ sal_uInt16 nFormatIdx );
+ /** Reads rotation properties from the passed property set. */
+ sal_uInt16 ReadRotationProperties(
+ const ScfPropertySet& rPropSet,
+ bool bSupportsStacked );
+
+ /** Writes all line properties to the passed property set. */
+ void WriteLineProperties(
+ ScfPropertySet& rPropSet,
+ XclChObjectTable& rDashTable,
+ const XclChLineFormat& rLineFmt,
+ XclChPropertyMode ePropMode );
+ /** Writes solid area properties to the passed property set. */
+ void WriteAreaProperties(
+ ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt,
+ XclChPropertyMode ePropMode );
+ /** Writes gradient or bitmap area properties to the passed property set. */
+ void WriteEscherProperties(
+ ScfPropertySet& rPropSet,
+ XclChObjectTable& rGradientTable,
+ XclChObjectTable& rHatchTable,
+ XclChObjectTable& rBitmapTable,
+ const XclChEscherFormat& rEscherFmt,
+ const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode );
+ /** Writes all marker properties to the passed property set. */
+ void WriteMarkerProperties(
+ ScfPropertySet& rPropSet,
+ const XclChMarkerFormat& rMarkerFmt );
+ /** Writes rotation properties to the passed property set. */
+ void WriteRotationProperties(
+ ScfPropertySet& rPropSet,
+ sal_uInt16 nRotation,
+ bool bSupportsStacked );
+
+private:
+ /** Returns a line property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetLineHelper( XclChPropertyMode ePropMode );
+ /** Returns an area property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetAreaHelper( XclChPropertyMode ePropMode );
+ /** Returns a gradient property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetGradientHelper( XclChPropertyMode ePropMode );
+ /** Returns a hatch property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetHatchHelper( XclChPropertyMode ePropMode );
+
+private:
+ ScfPropSetHelper maLineHlpCommon; /// Properties for lines in common objects.
+ ScfPropSetHelper maLineHlpLinear; /// Properties for lines in linear series.
+ ScfPropSetHelper maLineHlpFilled; /// Properties for lines in filled series.
+ ScfPropSetHelper maAreaHlpCommon; /// Properties for areas in common objects.
+ ScfPropSetHelper maAreaHlpFilled; /// Properties for areas in filled series.
+ ScfPropSetHelper maGradHlpCommon; /// Properties for gradients in common objects.
+ ScfPropSetHelper maGradHlpFilled; /// Properties for gradients in filled series.
+ ScfPropSetHelper maHatchHlpCommon; /// Properties for hatches in common objects.
+ ScfPropSetHelper maHatchHlpFilled; /// Properties for hatches in filled series.
+ ScfPropSetHelper maBitmapHlp; /// Properties for bitmaps.
+};
+
+// ============================================================================
+
+/** Base struct for internal root data structs for import and export. */
+struct XclChRootData
+{
+ typedef ScfRef< XclChTypeInfoProvider > XclChTypeProvRef;
+ typedef ScfRef< XclChFormatInfoProvider > XclChFmtInfoProvRef;
+ typedef ScfRef< XclChObjectTable > XclChObjectTableRef;
+ typedef ::std::map< XclChTextKey, XclChGetShapeFunc > XclChGetShapeFuncMap;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >
+ mxChartDoc; /// The chart document.
+ Rectangle maChartRect; /// Position and size of the chart shape.
+ XclChTypeProvRef mxTypeInfoProv; /// Provides info about chart types.
+ XclChFmtInfoProvRef mxFmtInfoProv; /// Provides info about auto formatting.
+ XclChObjectTableRef mxLineDashTable; /// Container for line dash styles.
+ XclChObjectTableRef mxGradientTable; /// Container for gradient fill styles.
+ XclChObjectTableRef mxHatchTable; /// Container for hatch fill styles.
+ XclChObjectTableRef mxBitmapTable; /// Container for bitmap fill styles.
+ XclChGetShapeFuncMap maGetShapeFuncs; /// Maps title shape getter functions.
+ sal_Int32 mnBorderGapX; /// Border gap to chart space in 1/100mm.
+ sal_Int32 mnBorderGapY; /// Border gap to chart space in 1/100mm.
+ double mfUnitSizeX; /// Size of a chart X unit (1/4000 of chart width) in 1/100 mm.
+ double mfUnitSizeY; /// Size of a chart Y unit (1/4000 of chart height) in 1/100 mm.
+
+ explicit XclChRootData();
+ virtual ~XclChRootData();
+
+ /** Starts the API chart document conversion. Must be called once before any API access. */
+ void InitConversion(
+ const XclRoot& rRoot,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc,
+ const Rectangle& rChartRect );
+ /** Finishes the API chart document conversion. Must be called once before any API access. */
+ void FinishConversion();
+
+ /** Returns the drawing shape interface of the specified title object. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ GetTitleShape( const XclChTextKey& rTitleKey ) const;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlconst.hxx b/sc/source/filter/inc/xlconst.hxx
new file mode 100644
index 000000000000..42160aae7529
--- /dev/null
+++ b/sc/source/filter/inc/xlconst.hxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLCONST_HXX
+#define SC_XLCONST_HXX
+
+#include "address.hxx"
+
+// Common =====================================================================
+
+// BIFF versions --------------------------------------------------------------
+
+/** An enumeration for all Excel file format types (BIFF types). */
+enum XclBiff
+{
+ EXC_BIFF2 = 0, /// MS Excel 2.1
+ EXC_BIFF3, /// MS Excel 3.0
+ EXC_BIFF4, /// MS Excel 4.0
+ EXC_BIFF5, /// MS Excel 5.0, MS Excel 7.0 (95)
+ EXC_BIFF8, /// MS Excel 8.0 (97), 9.0 (2000), 10.0 (XP), 11.0 (2003)
+ EXC_BIFF_UNKNOWN /// Unknown BIFF version.
+};
+
+/** An enumeration for all Excel output format types. */
+enum XclOutput
+{
+ EXC_OUTPUT_BINARY, /// MS Excel binary .xls
+ EXC_OUTPUT_XML_2007, /// MS Excel 2007 .xlsx
+};
+
+// Excel sheet dimensions -----------------------------------------------------
+
+const SCCOL EXC_MAXCOL2 = 255;
+const SCROW EXC_MAXROW2 = 16383;
+const SCTAB EXC_MAXTAB2 = 0;
+
+const SCCOL EXC_MAXCOL3 = EXC_MAXCOL2;
+const SCROW EXC_MAXROW3 = EXC_MAXROW2;
+const SCTAB EXC_MAXTAB3 = EXC_MAXTAB2;
+
+const SCCOL EXC_MAXCOL4 = EXC_MAXCOL3;
+const SCROW EXC_MAXROW4 = EXC_MAXROW3;
+const SCTAB EXC_MAXTAB4 = 32767;
+
+const SCCOL EXC_MAXCOL5 = EXC_MAXCOL4;
+const SCROW EXC_MAXROW5 = EXC_MAXROW4;
+const SCTAB EXC_MAXTAB5 = EXC_MAXTAB4;
+
+const SCCOL EXC_MAXCOL8 = EXC_MAXCOL5;
+const SCROW EXC_MAXROW8 = 65535;
+const SCTAB EXC_MAXTAB8 = EXC_MAXTAB5;
+
+const sal_uInt16 EXC_NOTAB = SAL_MAX_UINT16; /// An invalid Excel sheet index, for common use.
+const SCTAB SCTAB_INVALID = SCTAB_MAX; /// An invalid Calc sheet index, for common use.
+const SCTAB SCTAB_GLOBAL = SCTAB_MAX; /// A Calc sheet index for the workbook globals.
+
+// Storage/stream names -------------------------------------------------------
+
+#define EXC_STORAGE_OLE_LINKED CREATE_STRING( "LNK" )
+#define EXC_STORAGE_OLE_EMBEDDED CREATE_STRING( "MBD" )
+#define EXC_STORAGE_VBA_PROJECT CREATE_STRING( "_VBA_PROJECT_CUR" )
+#define EXC_STORAGE_VBA CREATE_STRING( "VBA" )
+
+#define EXC_STREAM_BOOK CREATE_STRING( "Book" )
+#define EXC_STREAM_WORKBOOK CREATE_STRING( "Workbook" )
+#define EXC_STREAM_CTLS CREATE_STRING( "Ctls" )
+
+// Encoded URLs ---------------------------------------------------------------
+
+const sal_Unicode EXC_URLSTART_ENCODED = '\x01'; /// Encoded URL.
+const sal_Unicode EXC_URLSTART_SELF = '\x02'; /// Reference to own workbook.
+const sal_Unicode EXC_URLSTART_SELFENCODED = '\x03'; /// Encoded self reference.
+const sal_Unicode EXC_URLSTART_OWNDOC = '\x04'; /// Reference to own workbook (BIFF5/BIFF7).
+
+const sal_Unicode EXC_URL_DOSDRIVE = '\x01'; /// DOS drive letter or UNC server name.
+const sal_Unicode EXC_URL_DRIVEROOT = '\x02'; /// Root directory of current drive.
+const sal_Unicode EXC_URL_SUBDIR = '\x03'; /// Directory name delimiter.
+const sal_Unicode EXC_URL_PARENTDIR = '\x04'; /// Parent directory.
+const sal_Unicode EXC_URL_RAW = '\x05'; /// Unencoded URL.
+const sal_Unicode EXC_URL_SHEETNAME = '\x09'; /// Sheet name starts here (BIFF4).
+
+const sal_Unicode EXC_DDE_DELIM = '\x03'; /// DDE application-topic delimiter
+
+// Error codes ----------------------------------------------------------------
+
+const sal_uInt8 EXC_ERR_NULL = 0x00;
+const sal_uInt8 EXC_ERR_DIV0 = 0x07;
+const sal_uInt8 EXC_ERR_VALUE = 0x0F;
+const sal_uInt8 EXC_ERR_REF = 0x17;
+const sal_uInt8 EXC_ERR_NAME = 0x1D;
+const sal_uInt8 EXC_ERR_NUM = 0x24;
+const sal_uInt8 EXC_ERR_NA = 0x2A;
+
+// Cached values list (EXTERNNAME, ptgArray, ...) -----------------------------
+
+const sal_uInt8 EXC_CACHEDVAL_EMPTY = 0x00;
+const sal_uInt8 EXC_CACHEDVAL_DOUBLE = 0x01;
+const sal_uInt8 EXC_CACHEDVAL_STRING = 0x02;
+const sal_uInt8 EXC_CACHEDVAL_BOOL = 0x04;
+const sal_uInt8 EXC_CACHEDVAL_ERROR = 0x10;
+
+// RK values ------------------------------------------------------------------
+
+const sal_Int32 EXC_RK_100FLAG = 0x00000001;
+const sal_Int32 EXC_RK_INTFLAG = 0x00000002;
+const sal_Int32 EXC_RK_VALUEMASK = 0xFFFFFFFC;
+
+const sal_Int32 EXC_RK_DBL = 0x00000000;
+const sal_Int32 EXC_RK_DBL100 = EXC_RK_100FLAG;
+const sal_Int32 EXC_RK_INT = EXC_RK_INTFLAG;
+const sal_Int32 EXC_RK_INT100 = EXC_RK_100FLAG | EXC_RK_INTFLAG;
+
+// Measures -------------------------------------------------------------------
+
+const sal_Int32 EXC_POINTS_PER_INCH = 72;
+const sal_Int32 EXC_TWIPS_PER_INCH = EXC_POINTS_PER_INCH * 20;
+
+const sal_uInt8 EXC_ORIENT_NONE = 0; /// Text orientation: not rotated.
+const sal_uInt8 EXC_ORIENT_STACKED = 1; /// Text orientation: vertically stacked.
+const sal_uInt8 EXC_ORIENT_90CCW = 2; /// Text orientation: 90 deg counterclockwise.
+const sal_uInt8 EXC_ORIENT_90CW = 3; /// Text orientation: 90 deg clockwise.
+
+const sal_uInt8 EXC_ROT_NONE = 0; /// Text rotation: not rotated.
+const sal_uInt8 EXC_ROT_90CCW = 90; /// Text rotation: 90 deg counterclockwise.
+const sal_uInt8 EXC_ROT_90CW = 180; /// Text rotation: 90 deg clockwise.
+const sal_uInt8 EXC_ROT_STACKED = 255; /// Text rotation: vertically stacked.
+
+// Records (ordered by lowest record ID) ======================================
+
+// (0x0009, 0x0209, 0x0409, 0x0809) BOF ---------------------------------------
+
+const sal_uInt16 EXC_ID2_BOF = 0x0009;
+const sal_uInt16 EXC_ID3_BOF = 0x0209;
+const sal_uInt16 EXC_ID4_BOF = 0x0409;
+const sal_uInt16 EXC_ID5_BOF = 0x0809;
+
+const sal_uInt16 EXC_BOF_BIFF2 = 0x0200;
+const sal_uInt16 EXC_BOF_BIFF3 = 0x0300;
+const sal_uInt16 EXC_BOF_BIFF4 = 0x0400;
+const sal_uInt16 EXC_BOF_BIFF5 = 0x0500;
+const sal_uInt16 EXC_BOF_BIFF8 = 0x0600;
+
+const sal_uInt16 EXC_BOF_GLOBALS = 0x0005; /// BIFF5-BIFF8 workbook globals.
+const sal_uInt16 EXC_BOF_VBMODULE = 0x0006; /// BIFF5-BIFF8 Visual BASIC module.
+const sal_uInt16 EXC_BOF_SHEET = 0x0010; /// Regular worksheet.
+const sal_uInt16 EXC_BOF_CHART = 0x0020; /// Chart sheet.
+const sal_uInt16 EXC_BOF_MACROSHEET = 0x0040; /// Macro sheet.
+const sal_uInt16 EXC_BOF_WORKSPACE = 0x0100; /// Workspace.
+const sal_uInt16 EXC_BOF_UNKNOWN = 0xFFFF; /// Internal use only.
+
+// (0x000A) EOF ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EOF = 0x000A;
+
+// (0x0012) PROTECT -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PROTECT = 0x0012;
+
+// (0x0013) PASSWORD ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PASSWORD = 0x0013;
+
+// (0x0019) WINDOWPROTECT -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_WINDOWPROTECT = 0x0019;
+
+// (0x0042) CODEPAGE ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CODEPAGE = 0x0042;
+
+// (0x0081) WSBOOL ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_WSBOOL = 0x0081;
+
+const sal_uInt16 EXC_WSBOOL_ROWBELOW = 0x0040;
+const sal_uInt16 EXC_WSBOOL_COLBELOW = 0x0080;
+const sal_uInt16 EXC_WSBOOL_FITTOPAGE = 0x0100;
+
+const sal_uInt16 EXC_WSBOOL_DEFAULTFLAGS = 0x04C1;
+
+// (0x0086) WRITEPROT ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_WRITEPROT = 0x0086;
+
+// (0x008C) COUNTRY -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_COUNTRY = 0x008C;
+
+// (0x009B) FILTERMODE --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_FILTERMODE = 0x009B;
+
+// (0x009C) FNGROUPCOUNT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_FNGROUPCOUNT = 0x009C;
+
+// (0x009D) AUTOFILTERINFO ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_AUTOFILTERINFO = 0x009D;
+
+// (0x009E) AUTOFILTER --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_AUTOFILTER = 0x009E;
+
+// (0x00BF, 0x00C0, 0x00C1) TOOLBARHDR, TOOLBAREND, MMS -----------------------
+
+const sal_uInt16 EXC_ID_TOOLBARHDR = 0x00BF;
+const sal_uInt16 EXC_ID_TOOLBAREND = 0x00C0;
+const sal_uInt16 EXC_ID_MMS = 0x00C1;
+
+// (0x00E1, 0x00E2) INTERFACEHDR, INTERFACEEND --------------------------------
+
+const sal_uInt16 EXC_ID_INTERFACEHDR = 0x00E1;
+const sal_uInt16 EXC_ID_INTERFACEEND = 0x00E2;
+
+// (0x0160) USESELFS ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_USESELFS = 0x0160;
+
+// (0x0161) DSF ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_DSF = 0x0161;
+
+// (0x01AA,0x01AB) USERSVIEWBEGIN, USERSVIEWEND -------------------------------
+
+const sal_uInt16 EXC_ID_USERSVIEWBEGIN = 0x01AA;
+const sal_uInt16 EXC_ID_USERSVIEWEND = 0x01AB;
+
+// (0x01BA) CODENAME ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CODENAME = 0x01BA;
+
+// (0x01C0) XL9FILE -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_XL9FILE = 0x01C0;
+
+// (0x8xx) Future records -----------------------------------------------------
+
+/** Enumerates different header types of future records. */
+enum XclFutureRecType
+{
+ EXC_FUTUREREC_SIMPLE, /// Record identifier and empty flags field.
+ EXC_FUTUREREC_UNUSEDREF /// Record identifier, empty flags field, unused range address.
+};
+
+const sal_uInt16 EXC_FUTUREREC_EMPTYFLAGS = 0x0000;
+const sal_uInt16 EXC_FUTUREREC_HASREF = 0x0001;
+const sal_uInt16 EXC_FUTUREREC_ALERT = 0x0002;
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlcontent.hxx b/sc/source/filter/inc/xlcontent.hxx
new file mode 100644
index 000000000000..41e916472e70
--- /dev/null
+++ b/sc/source/filter/inc/xlcontent.hxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLCONTENT_HXX
+#define SC_XLCONTENT_HXX
+
+#include <sal/types.h>
+
+// Constants ==================================================================
+
+// (0x005B) FILESHARING -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_FILESHARING = 0x005B;
+
+// (0x00E5) MERGEDCELLS -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_MERGEDCELLS = 0x00E5;
+const sal_uInt16 EXC_MERGEDCELLS_MAXCOUNT = 1027;
+
+// (0x002F) FILEPASS ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_FILEPASS = 0x002F;
+
+const sal_uInt16 EXC_FILEPASS_BIFF5 = 0x0000;
+const sal_uInt16 EXC_FILEPASS_BIFF8 = 0x0001;
+const sal_uInt16 EXC_FILEPASS_BIFF8_STD = 0x0001;
+const sal_uInt16 EXC_FILEPASS_BIFF8_STRONG = 0x0002;
+
+// (0x00FC, 0x00FF) SST, EXTSST -----------------------------------------------
+
+const sal_uInt16 EXC_ID_SST = 0x00FC;
+const sal_uInt16 EXC_ID_EXTSST = 0x00FF;
+
+// (0x015F) LABELRANGES -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_LABELRANGES = 0x015F;
+
+// (0x01B0) CONDFMT, (0x01B1) CF ----------------------------------------------
+
+const sal_uInt16 EXC_ID_CONDFMT = 0x01B0;
+const sal_uInt16 EXC_ID_CF = 0x01B1;
+
+const sal_uInt8 EXC_CF_TYPE_NONE = 0x00;
+const sal_uInt8 EXC_CF_TYPE_CELL = 0x01;
+const sal_uInt8 EXC_CF_TYPE_FMLA = 0x02;
+
+const sal_uInt8 EXC_CF_CMP_NONE = 0x00;
+const sal_uInt8 EXC_CF_CMP_BETWEEN = 0x01;
+const sal_uInt8 EXC_CF_CMP_NOT_BETWEEN = 0x02;
+const sal_uInt8 EXC_CF_CMP_EQUAL = 0x03;
+const sal_uInt8 EXC_CF_CMP_NOT_EQUAL = 0x04;
+const sal_uInt8 EXC_CF_CMP_GREATER = 0x05;
+const sal_uInt8 EXC_CF_CMP_LESS = 0x06;
+const sal_uInt8 EXC_CF_CMP_GREATER_EQUAL = 0x07;
+const sal_uInt8 EXC_CF_CMP_LESS_EQUAL = 0x08;
+
+const sal_uInt32 EXC_CF_BORDER_LEFT = 0x00000400; /// Left border line modified?
+const sal_uInt32 EXC_CF_BORDER_RIGHT = 0x00000800; /// Right border line modified?
+const sal_uInt32 EXC_CF_BORDER_TOP = 0x00001000; /// Top border line modified?
+const sal_uInt32 EXC_CF_BORDER_BOTTOM = 0x00002000; /// Bottom border line modified?
+const sal_uInt32 EXC_CF_BORDER_ALL = 0x00003C00; /// Any border line modified?
+const sal_uInt32 EXC_CF_AREA_PATTERN = 0x00010000; /// Pattern modified?
+const sal_uInt32 EXC_CF_AREA_FGCOLOR = 0x00020000; /// Foreground color modified?
+const sal_uInt32 EXC_CF_AREA_BGCOLOR = 0x00040000; /// Background color modified?
+const sal_uInt32 EXC_CF_AREA_ALL = 0x00070000; /// Any area attribute modified?
+const sal_uInt32 EXC_CF_ALLDEFAULT = 0x003FFFFF; /// Default flags.
+const sal_uInt32 EXC_CF_BLOCK_FONT = 0x04000000; /// Font block present?
+const sal_uInt32 EXC_CF_BLOCK_BORDER = 0x10000000; /// Border block present?
+const sal_uInt32 EXC_CF_BLOCK_AREA = 0x20000000; /// Pattern block present?
+
+const sal_uInt32 EXC_CF_FONT_STYLE = 0x00000002; /// Font posture or weight modified?
+const sal_uInt32 EXC_CF_FONT_STRIKEOUT = 0x00000080; /// Font cancellation modified?
+const sal_uInt32 EXC_CF_FONT_ALLDEFAULT = 0x0000009A; /// Default flags.
+
+const sal_uInt32 EXC_CF_FONT_UNDERL = 0x00000001; /// Font underline type modified?
+const sal_uInt32 EXC_CF_FONT_ESCAPEM = 0x00000001; /// Font escapement type modified?
+
+// (0x01B2) DVAL --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_DVAL = 0x01B2;
+const sal_uInt32 EXC_DVAL_NOOBJ = 0xFFFFFFFF;
+
+// (0x01BE) DV ----------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_DV = 0x01BE;
+
+// data validation flags
+const sal_uInt32 EXC_DV_STRINGLIST = 0x00000080;
+const sal_uInt32 EXC_DV_IGNOREBLANK = 0x00000100;
+const sal_uInt32 EXC_DV_SUPPRESSDROPDOWN = 0x00000200;
+const sal_uInt32 EXC_DV_SHOWPROMPT = 0x00040000;
+const sal_uInt32 EXC_DV_SHOWERROR = 0x00080000;
+
+// data validation data mode
+const sal_uInt32 EXC_DV_MODE_MASK = 0x0000000F;
+const sal_uInt32 EXC_DV_MODE_ANY = 0x00000000;
+const sal_uInt32 EXC_DV_MODE_WHOLE = 0x00000001;
+const sal_uInt32 EXC_DV_MODE_DECIMAL = 0x00000002;
+const sal_uInt32 EXC_DV_MODE_LIST = 0x00000003;
+const sal_uInt32 EXC_DV_MODE_DATE = 0x00000004;
+const sal_uInt32 EXC_DV_MODE_TIME = 0x00000005;
+const sal_uInt32 EXC_DV_MODE_TEXTLEN = 0x00000006;
+const sal_uInt32 EXC_DV_MODE_CUSTOM = 0x00000007;
+
+// data validation conditions
+const sal_uInt32 EXC_DV_COND_MASK = 0x00F00000;
+const sal_uInt32 EXC_DV_COND_BETWEEN = 0x00000000;
+const sal_uInt32 EXC_DV_COND_NOTBETWEEN = 0x00100000;
+const sal_uInt32 EXC_DV_COND_EQUAL = 0x00200000;
+const sal_uInt32 EXC_DV_COND_NOTEQUAL = 0x00300000;
+const sal_uInt32 EXC_DV_COND_GREATER = 0x00400000;
+const sal_uInt32 EXC_DV_COND_LESS = 0x00500000;
+const sal_uInt32 EXC_DV_COND_EQGREATER = 0x00600000;
+const sal_uInt32 EXC_DV_COND_EQLESS = 0x00700000;
+
+// data validation error style
+const sal_uInt32 EXC_DV_ERROR_MASK = 0x00000070;
+const sal_uInt32 EXC_DV_ERROR_STOP = 0x00000000;
+const sal_uInt32 EXC_DV_ERROR_WARNING = 0x00000010;
+const sal_uInt32 EXC_DV_ERROR_INFO = 0x00000020;
+
+// (0x01B8) HLINK -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_HLINK = 0x01B8;
+
+const sal_uInt32 EXC_HLINK_BODY = 0x00000001; /// Contains file link or URL.
+const sal_uInt32 EXC_HLINK_ABS = 0x00000002; /// Absolute path.
+const sal_uInt32 EXC_HLINK_DESCR = 0x00000014; /// Description.
+const sal_uInt32 EXC_HLINK_MARK = 0x00000008; /// Text mark.
+const sal_uInt32 EXC_HLINK_FRAME = 0x00000080; /// Target frame.
+const sal_uInt32 EXC_HLINK_UNC = 0x00000100; /// UNC path.
+
+// web queries ================================================================
+
+#define EXC_WEBQRY_FILTER "calc_HTML_WebQuery"
+
+// (0x00CD) WQSTRING
+const sal_uInt16 EXC_ID_WQSTRING = 0x00CD;
+
+// (0x00DC) PARAMQRY
+const sal_uInt16 EXC_ID_PQRY = 0x00DC;
+const sal_uInt16 EXC_PQRYTYPE_ODBC = 1; /// Source type: ODBC.
+const sal_uInt16 EXC_PQRYTYPE_WEBQUERY = 4; /// Source type: webquery.
+const sal_uInt16 EXC_PQRY_ODBC = 0x0008; /// ODBC connection.
+const sal_uInt16 EXC_PQRY_WEBQUERY = 0x0040; /// Web query.
+const sal_uInt16 EXC_PQRY_TABLES = 0x0100; /// All tables.
+
+// (0x01AD) QSI
+const sal_uInt16 EXC_ID_QSI = 0x01AD;
+const sal_uInt16 EXC_QSI_DEFAULTFLAGS = 0x0349; /// Flags for export.
+
+// (0x0802) unknown record
+const sal_uInt16 EXC_ID_0802 = 0x0802;
+
+// (0x0803) WEBQRYSETTINGS
+const sal_uInt16 EXC_ID_WQSETT = 0x0803;
+const sal_uInt16 EXC_WQSETT_ALL = 0x0000; /// All tables or entire document.
+const sal_uInt16 EXC_WQSETT_SPECTABLES = 0x0002; /// Specific tables.
+const sal_uInt16 EXC_WQSETT_DEFAULTFLAGS = 0x0023; /// Flags for export.
+const sal_uInt16 EXC_WQSETT_NOFORMAT = 0x0001;
+const sal_uInt16 EXC_WQSETT_FORMATRTF = 0x0002;
+const sal_uInt16 EXC_WQSETT_FORMATFULL = 0x0003;
+
+// (0x0804) WEBQRYTABLES
+const sal_uInt16 EXC_ID_WQTABLES = 0x0804;
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx
new file mode 100644
index 000000000000..921da6b8741b
--- /dev/null
+++ b/sc/source/filter/inc/xlescher.hxx
@@ -0,0 +1,450 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLESCHER_HXX
+#define SC_XLESCHER_HXX
+
+#include <tools/gen.hxx>
+#include <vcl/mapunit.hxx>
+#include "fapihelper.hxx"
+#include "xladdress.hxx"
+#include "xlstyle.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace drawing { class XShape; }
+ namespace awt { class XControlModel; }
+ namespace script { struct ScriptEventDescriptor; }
+} } }
+
+class SdrObject;
+class Rectangle;
+class ScDocument;
+class SvStream;
+class XclImpStream;
+class XclExpStream;
+
+// Constants and Enumerations =================================================
+
+// (0x001C) NOTE --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_NOTE = 0x001C;
+const sal_uInt16 EXC_NOTE_VISIBLE = 0x0002;
+const sal_uInt16 EXC_NOTE5_MAXLEN = 2048;
+
+// (0x005D) OBJ ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_OBJ = 0x005D;
+
+const sal_uInt16 EXC_OBJ_INVALID_ID = 0;
+
+// object types
+const sal_uInt16 EXC_OBJTYPE_GROUP = 0;
+const sal_uInt16 EXC_OBJTYPE_LINE = 1;
+const sal_uInt16 EXC_OBJTYPE_RECTANGLE = 2;
+const sal_uInt16 EXC_OBJTYPE_OVAL = 3;
+const sal_uInt16 EXC_OBJTYPE_ARC = 4;
+const sal_uInt16 EXC_OBJTYPE_CHART = 5;
+const sal_uInt16 EXC_OBJTYPE_TEXT = 6;
+const sal_uInt16 EXC_OBJTYPE_BUTTON = 7;
+const sal_uInt16 EXC_OBJTYPE_PICTURE = 8;
+const sal_uInt16 EXC_OBJTYPE_POLYGON = 9; // new in BIFF4
+const sal_uInt16 EXC_OBJTYPE_CHECKBOX = 11; // new in BIFF5
+const sal_uInt16 EXC_OBJTYPE_OPTIONBUTTON = 12;
+const sal_uInt16 EXC_OBJTYPE_EDIT = 13;
+const sal_uInt16 EXC_OBJTYPE_LABEL = 14;
+const sal_uInt16 EXC_OBJTYPE_DIALOG = 15;
+const sal_uInt16 EXC_OBJTYPE_SPIN = 16;
+const sal_uInt16 EXC_OBJTYPE_SCROLLBAR = 17;
+const sal_uInt16 EXC_OBJTYPE_LISTBOX = 18;
+const sal_uInt16 EXC_OBJTYPE_GROUPBOX = 19;
+const sal_uInt16 EXC_OBJTYPE_DROPDOWN = 20;
+const sal_uInt16 EXC_OBJTYPE_NOTE = 25; // new in BIFF8
+const sal_uInt16 EXC_OBJTYPE_DRAWING = 30;
+const sal_uInt16 EXC_OBJTYPE_UNKNOWN = 0xFFFF; /// For internal use only.
+
+// BIFF3-BIFF5 flags
+const sal_uInt16 EXC_OBJ_HIDDEN = 0x0100;
+const sal_uInt16 EXC_OBJ_VISIBLE = 0x0200;
+const sal_uInt16 EXC_OBJ_PRINTABLE = 0x0400;
+
+// BIFF5 line formatting
+const sal_uInt8 EXC_OBJ_LINE_AUTOCOLOR = 64;
+
+const sal_uInt8 EXC_OBJ_LINE_SOLID = 0;
+const sal_uInt8 EXC_OBJ_LINE_DASH = 1;
+const sal_uInt8 EXC_OBJ_LINE_DOT = 2;
+const sal_uInt8 EXC_OBJ_LINE_DASHDOT = 3;
+const sal_uInt8 EXC_OBJ_LINE_DASHDOTDOT = 4;
+const sal_uInt8 EXC_OBJ_LINE_MEDTRANS = 5;
+const sal_uInt8 EXC_OBJ_LINE_DARKTRANS = 6;
+const sal_uInt8 EXC_OBJ_LINE_LIGHTTRANS = 7;
+const sal_uInt8 EXC_OBJ_LINE_NONE = 255;
+
+const sal_uInt8 EXC_OBJ_LINE_HAIR = 0;
+const sal_uInt8 EXC_OBJ_LINE_THIN = 1;
+const sal_uInt8 EXC_OBJ_LINE_MEDIUM = 2;
+const sal_uInt8 EXC_OBJ_LINE_THICK = 3;
+
+const sal_uInt8 EXC_OBJ_LINE_AUTO = 0x01;
+
+const sal_uInt8 EXC_OBJ_ARROW_NONE = 0;
+const sal_uInt8 EXC_OBJ_ARROW_OPEN = 1;
+const sal_uInt8 EXC_OBJ_ARROW_FILLED = 2;
+const sal_uInt8 EXC_OBJ_ARROW_OPENBOTH = 3;
+const sal_uInt8 EXC_OBJ_ARROW_FILLEDBOTH = 4;
+
+const sal_uInt8 EXC_OBJ_ARROW_NARROW = 0;
+const sal_uInt8 EXC_OBJ_ARROW_MEDIUM = 1;
+const sal_uInt8 EXC_OBJ_ARROW_WIDE = 2;
+
+const sal_uInt8 EXC_OBJ_LINE_TL = 0;
+const sal_uInt8 EXC_OBJ_LINE_TR = 1;
+const sal_uInt8 EXC_OBJ_LINE_BR = 2;
+const sal_uInt8 EXC_OBJ_LINE_BL = 3;
+
+// BIFF5 fill formatting
+const sal_uInt8 EXC_OBJ_FILL_AUTOCOLOR = 65;
+
+const sal_uInt8 EXC_OBJ_FILL_AUTO = 0x01;
+
+// BIFF5 frame formatting
+const sal_uInt16 EXC_OBJ_FRAME_SHADOW = 0x0002;
+
+// BIFF5 text objects
+const sal_uInt8 EXC_OBJ_HOR_LEFT = 1;
+const sal_uInt8 EXC_OBJ_HOR_CENTER = 2;
+const sal_uInt8 EXC_OBJ_HOR_RIGHT = 3;
+const sal_uInt8 EXC_OBJ_HOR_JUSTIFY = 4;
+
+const sal_uInt8 EXC_OBJ_VER_TOP = 1;
+const sal_uInt8 EXC_OBJ_VER_CENTER = 2;
+const sal_uInt8 EXC_OBJ_VER_BOTTOM = 3;
+const sal_uInt8 EXC_OBJ_VER_JUSTIFY = 4;
+
+const sal_uInt16 EXC_OBJ_ORIENT_NONE = 0;
+const sal_uInt16 EXC_OBJ_ORIENT_STACKED = 1; /// Stacked top to bottom.
+const sal_uInt16 EXC_OBJ_ORIENT_90CCW = 2; /// 90 degr. counterclockwise.
+const sal_uInt16 EXC_OBJ_ORIENT_90CW = 3; /// 90 degr. clockwise.
+
+const sal_uInt16 EXC_OBJ_TEXT_AUTOSIZE = 0x0080;
+const sal_uInt16 EXC_OBJ_TEXT_LOCKED = 0x0200;
+
+const sal_Int32 EXC_OBJ_TEXT_MARGIN = 20000; /// Automatic text margin (EMUs).
+
+// BIFF5 arc objects
+const sal_uInt8 EXC_OBJ_ARC_TR = 0;
+const sal_uInt8 EXC_OBJ_ARC_TL = 1;
+const sal_uInt8 EXC_OBJ_ARC_BL = 2;
+const sal_uInt8 EXC_OBJ_ARC_BR = 3;
+
+// BIFF5 polygon objects
+const sal_uInt16 EXC_OBJ_POLY_CLOSED = 0x0100;
+
+// BIFF5 pictures/OLE objects
+const sal_uInt16 EXC_OBJ_PIC_MANUALSIZE = 0x0001;
+const sal_uInt16 EXC_OBJ_PIC_DDE = 0x0002;
+const sal_uInt16 EXC_OBJ_PIC_SYMBOL = 0x0008;
+const sal_uInt16 EXC_OBJ_PIC_CONTROL = 0x0010; /// Form control (BIFF8).
+const sal_uInt16 EXC_OBJ_PIC_CTLSSTREAM = 0x0020; /// Data in Ctls stream (BIFF8).
+const sal_uInt16 EXC_OBJ_PIC_AUTOLOAD = 0x0200; /// Auto-load form control (BIFF8).
+
+// BIFF5 button objects
+const sal_uInt16 EXC_OBJ_BUTTON_DEFAULT = 0x0001;
+const sal_uInt16 EXC_OBJ_BUTTON_HELP = 0x0002;
+const sal_uInt16 EXC_OBJ_BUTTON_CANCEL = 0x0004;
+const sal_uInt16 EXC_OBJ_BUTTON_CLOSE = 0x0008;
+
+// BIFF5 checkboxs, radio buttons
+const sal_uInt16 EXC_OBJ_CHECKBOX_UNCHECKED = 0;
+const sal_uInt16 EXC_OBJ_CHECKBOX_CHECKED = 1;
+const sal_uInt16 EXC_OBJ_CHECKBOX_TRISTATE = 2;
+const sal_uInt16 EXC_OBJ_CHECKBOX_FLAT = 0x0001;
+
+// BIFF5 editbox objects
+const sal_uInt16 EXC_OBJ_EDIT_TEXT = 0;
+const sal_uInt16 EXC_OBJ_EDIT_INTEGER = 1;
+const sal_uInt16 EXC_OBJ_EDIT_DOUBLE = 2;
+const sal_uInt16 EXC_OBJ_EDIT_REFERENCE = 3;
+const sal_uInt16 EXC_OBJ_EDIT_FORMULA = 4;
+
+// BIFF5 scrollbars/spinbuttons
+const sal_uInt16 EXC_OBJ_SCROLLBAR_MIN = 0;
+const sal_uInt16 EXC_OBJ_SCROLLBAR_MAX = 30000;
+
+const sal_uInt16 EXC_OBJ_SCROLLBAR_HOR = 0x0001;
+
+const sal_uInt16 EXC_OBJ_SCROLLBAR_DEFFLAGS = 0x0001;
+const sal_uInt16 EXC_OBJ_SCROLLBAR_FLAT = 0x0008;
+
+// BIFF5 listboxes/dropdowns
+const sal_uInt8 EXC_OBJ_LISTBOX_SINGLE = 0; /// Single selection.
+const sal_uInt8 EXC_OBJ_LISTBOX_MULTI = 1; /// Multi selection.
+const sal_uInt8 EXC_OBJ_LISTBOX_RANGE = 2; /// Range selection.
+
+const sal_uInt16 EXC_OBJ_LISTBOX_EDIT = 0x0002;
+const sal_uInt16 EXC_OBJ_LISTBOX_FLAT = 0x0008;
+
+// BIFF5 dropdown listboxes
+const sal_uInt16 EXC_OBJ_DROPDOWN_LISTBOX = 0; /// Listbox, text not editable.
+const sal_uInt16 EXC_OBJ_DROPDOWN_COMBOBOX = 1; /// Dropdown listbox with editable text.
+const sal_uInt16 EXC_OBJ_DROPDOWN_SIMPLE = 2; /// Dropdown button only, no text area.
+const sal_uInt16 EXC_OBJ_DROPDOWN_MAX = 3;
+const sal_uInt16 EXC_OBJ_DROPDOWN_FILTERED = 0x0008; /// Drowdown style: filtered.
+
+// BIFF5 groupboxes
+const sal_uInt16 EXC_OBJ_GROUPBOX_FLAT = 0x0001;
+
+// BIFF8 sub records
+const sal_uInt16 EXC_ID_OBJEND = 0x0000; /// End of OBJ.
+const sal_uInt16 EXC_ID_OBJMACRO = 0x0004; /// Macro link.
+const sal_uInt16 EXC_ID_OBJBUTTON = 0x0005; /// Button data.
+const sal_uInt16 EXC_ID_OBJGMO = 0x0006; /// Group marker.
+const sal_uInt16 EXC_ID_OBJCF = 0x0007; /// Clipboard format.
+const sal_uInt16 EXC_ID_OBJFLAGS = 0x0008; /// Option flags.
+const sal_uInt16 EXC_ID_OBJPICTFMLA = 0x0009; /// OLE link formula.
+const sal_uInt16 EXC_ID_OBJCBLS = 0x000A; /// Check box/radio button data.
+const sal_uInt16 EXC_ID_OBJRBO = 0x000B; /// Radio button group data.
+const sal_uInt16 EXC_ID_OBJSBS = 0x000C; /// Scroll bar data.
+const sal_uInt16 EXC_ID_OBJNTS = 0x000D; /// Note data.
+const sal_uInt16 EXC_ID_OBJSBSFMLA = 0x000E; /// Scroll bar/list box/combo box cell link.
+const sal_uInt16 EXC_ID_OBJGBODATA = 0x000F; /// Group box data.
+const sal_uInt16 EXC_ID_OBJEDODATA = 0x0010; /// Edit box data.
+const sal_uInt16 EXC_ID_OBJRBODATA = 0x0011; /// Radio button group data.
+const sal_uInt16 EXC_ID_OBJCBLSDATA = 0x0012; /// Check box/radio button data.
+const sal_uInt16 EXC_ID_OBJLBSDATA = 0x0013; /// List box/combo box data.
+const sal_uInt16 EXC_ID_OBJCBLSFMLA = 0x0014; /// Check box/radio button cell link.
+const sal_uInt16 EXC_ID_OBJCMO = 0x0015; /// Common object settings.
+const sal_uInt16 EXC_ID_OBJUNKNOWN = 0xFFFF; /// For internal use only.
+
+// BIFF8 OBJCMO: flags
+const sal_uInt16 EXC_OBJCMO_PRINTABLE = 0x0010; /// Object printable.
+const sal_uInt16 EXC_OBJCMO_AUTOLINE = 0x2000; /// Automatic line formatting.
+const sal_uInt16 EXC_OBJCMO_AUTOFILL = 0x4000; /// Automatic fill formatting.
+
+/** Value binding mode for cells linked to form controls. */
+enum XclCtrlBindMode
+{
+ EXC_CTRL_BINDCONTENT, /// Binds cell to content of control.
+ EXC_CTRL_BINDPOSITION /// Binds cell to position in control (e.g. listbox selection index).
+};
+
+// (0x007F) IMGDATA -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID3_IMGDATA = 0x007F;
+const sal_uInt16 EXC_ID8_IMGDATA = 0x00E9;
+
+const sal_uInt16 EXC_IMGDATA_WMF = 2;
+const sal_uInt16 EXC_IMGDATA_BMP = 9;
+
+const sal_uInt16 EXC_IMGDATA_WIN = 1;
+const sal_uInt16 EXC_IMGDATA_MAC = 2;
+
+const sal_uInt32 EXC_IMGDATA_MAXREC8 = 0x201C;
+const sal_uInt32 EXC_IMGDATA_MAXCONT8 = 0x2014;
+
+// (0x00A9) COORDLIST ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_COORDLIST = 0x00A9;
+
+// (0x00EB) MSODRAWINGGROUP ---------------------------------------------------
+
+const sal_uInt16 EXC_ID_MSODRAWINGGROUP = 0x00EB;
+
+// (0x00EC) MSODRAWING --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_MSODRAWING = 0x00EC;
+
+// additional flags not extant in svx headers
+const sal_uInt16 EXC_ESC_ANCHOR_POSLOCKED = 0x0001;
+const sal_uInt16 EXC_ESC_ANCHOR_SIZELOCKED = 0x0002;
+const sal_uInt16 EXC_ESC_ANCHOR_LOCKED = EXC_ESC_ANCHOR_POSLOCKED|EXC_ESC_ANCHOR_SIZELOCKED;
+
+// (0x00ED) MSODRAWINGSELECTION -----------------------------------------------
+
+const sal_uInt16 EXC_ID_MSODRAWINGSEL = 0x00ED;
+
+// (0x01B6) TXO ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_TXO = 0x01B6;
+
+// TXO constants are eqzal to BIFF5 OBJ text object flags
+
+// Structs and classes ========================================================
+
+/** Identifies a drawing object by sheet index and object identifier. */
+struct XclObjId
+{
+ SCTAB mnScTab; /// Calc sheet index.
+ sal_uInt16 mnObjId; /// Excel object identifier.
+
+ explicit XclObjId();
+ explicit XclObjId( SCTAB nScTab, sal_uInt16 nObjId );
+};
+
+bool operator==( const XclObjId& rL, const XclObjId& rR );
+bool operator<( const XclObjId& rL, const XclObjId& rR );
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of an object in a Calc document. */
+struct XclObjAnchor : public XclRange
+{
+ sal_uInt16 mnLX; /// X offset in left column (1/1024 of column width).
+ sal_uInt16 mnTY; /// Y offset in top row (1/256 of row height).
+ sal_uInt16 mnRX; /// X offset in right column (1/1024 of column width).
+ sal_uInt16 mnBY; /// Y offset in bottom row (1/256 of row height).
+
+ explicit XclObjAnchor();
+
+ /** Calculates a rectangle from the contained coordinates. */
+ Rectangle GetRect( const XclRoot& rRoot, SCTAB nScTab, MapUnit eMapUnit ) const;
+ /** Initializes the anchor coordinates for a sheet. */
+ void SetRect( const XclRoot& rRoot, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit );
+
+ /** Initializes the anchor coordinates for an embedded draw page. */
+ void SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY,
+ const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor );
+};
+
+template< typename StreamType >
+StreamType& operator>>( StreamType& rStrm, XclObjAnchor& rAnchor )
+{
+ return rStrm
+ >> rAnchor.maFirst.mnCol >> rAnchor.mnLX
+ >> rAnchor.maFirst.mnRow >> rAnchor.mnTY
+ >> rAnchor.maLast.mnCol >> rAnchor.mnRX
+ >> rAnchor.maLast.mnRow >> rAnchor.mnBY;
+}
+
+template< typename StreamType >
+StreamType& operator<<( StreamType& rStrm, const XclObjAnchor& rAnchor )
+{
+ return rStrm
+ << rAnchor.maFirst.mnCol << rAnchor.mnLX
+ << rAnchor.maFirst.mnRow << rAnchor.mnTY
+ << rAnchor.maLast.mnCol << rAnchor.mnRX
+ << rAnchor.maLast.mnRow << rAnchor.mnBY;
+}
+
+// ----------------------------------------------------------------------------
+
+struct XclObjLineData
+{
+ sal_uInt8 mnColorIdx;
+ sal_uInt8 mnStyle;
+ sal_uInt8 mnWidth;
+ sal_uInt8 mnAuto;
+
+ explicit XclObjLineData();
+
+ inline bool IsAuto() const { return ::get_flag( mnAuto, EXC_OBJ_LINE_AUTO ); }
+ inline bool IsVisible() const { return IsAuto() || (mnStyle != EXC_OBJ_LINE_NONE); }
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjLineData& rLineData );
+
+// ----------------------------------------------------------------------------
+
+struct XclObjFillData
+{
+ sal_uInt8 mnBackColorIdx;
+ sal_uInt8 mnPattColorIdx;
+ sal_uInt8 mnPattern;
+ sal_uInt8 mnAuto;
+
+ explicit XclObjFillData();
+
+ inline bool IsAuto() const { return ::get_flag( mnAuto, EXC_OBJ_FILL_AUTO ); }
+ inline bool IsFilled() const { return IsAuto() || (mnPattern != EXC_PATT_NONE); }
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjFillData& rFillData );
+
+// ----------------------------------------------------------------------------
+
+struct XclObjTextData
+{
+ sal_uInt16 mnTextLen;
+ sal_uInt16 mnFormatSize;
+ sal_uInt16 mnLinkSize;
+ sal_uInt16 mnDefFontIdx;
+ sal_uInt16 mnFlags;
+ sal_uInt16 mnOrient;
+ sal_uInt16 mnButtonFlags;
+ sal_uInt16 mnShortcut;
+ sal_uInt16 mnShortcutEA;
+
+ explicit XclObjTextData();
+
+ /** Reads text data from a BIFF3/BIFF4 OBJ record. */
+ void ReadObj3( XclImpStream& rStrm );
+ /** Reads text data from a BIFF5 OBJ record. */
+ void ReadObj5( XclImpStream& rStrm );
+ /** Reads text data from a BIFF8 TXO record. */
+ void ReadTxo8( XclImpStream& rStrm );
+
+ inline sal_uInt8 GetHorAlign() const { return ::extract_value< sal_uInt8 >( mnFlags, 1, 3 ); }
+ inline sal_uInt8 GetVerAlign() const { return ::extract_value< sal_uInt8 >( mnFlags, 4, 3 ); }
+};
+
+// ============================================================================
+
+enum XclTbxEventType
+{
+ EXC_TBX_EVENT_ACTION, /// XActionListener.actionPerformed
+ EXC_TBX_EVENT_MOUSE, /// XMouseListener.mouseReleased
+ EXC_TBX_EVENT_TEXT, /// XTextListener.textChanged
+ EXC_TBX_EVENT_VALUE, /// XAdjustmentListener.adjustmentValueChanged
+ EXC_TBX_EVENT_CHANGE /// XChangeListener.changed
+};
+
+// ----------------------------------------------------------------------------
+
+/** Provides static helper functions for form controls. */
+class XclControlHelper
+{
+public:
+ /** Returns the API control model from the passed API shape object. */
+ static ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >
+ GetControlModel( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ /** Fills the macro descriptor according to the passed macro name. */
+ static bool FillMacroDescriptor(
+ ::com::sun::star::script::ScriptEventDescriptor& rDescriptor,
+ XclTbxEventType eEventType,
+ const String& rXclMacroName,
+ SfxObjectShell* pDocShell = 0 );
+ /** Tries to extract an Excel macro name from the passed macro descriptor. */
+ static String ExtractFromMacroDescriptor(
+ const ::com::sun::star::script::ScriptEventDescriptor& rDescriptor,
+ XclTbxEventType eEventType );
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlformula.hxx b/sc/source/filter/inc/xlformula.hxx
new file mode 100644
index 000000000000..83bab2acd24a
--- /dev/null
+++ b/sc/source/filter/inc/xlformula.hxx
@@ -0,0 +1,569 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLFORMULA_HXX
+#define SC_XLFORMULA_HXX
+
+#include <map>
+#include <formula/opcode.hxx>
+#include "address.hxx"
+#include "ftools.hxx"
+
+// Constants ==================================================================
+
+const size_t EXC_TOKARR_MAXLEN = 4096; /// Maximum size of a token array.
+
+// Token class flags ----------------------------------------------------------
+
+const sal_uInt8 EXC_TOKCLASS_MASK = 0x60;
+const sal_uInt8 EXC_TOKCLASS_NONE = 0x00; /// 00-1F: Base tokens.
+const sal_uInt8 EXC_TOKCLASS_REF = 0x20; /// 20-3F: Reference class tokens.
+const sal_uInt8 EXC_TOKCLASS_VAL = 0x40; /// 40-5F: Value class tokens.
+const sal_uInt8 EXC_TOKCLASS_ARR = 0x60; /// 60-7F: Array class tokens.
+
+// Base tokens ----------------------------------------------------------------
+
+const sal_uInt8 EXC_TOKID_MASK = 0x1F;
+
+const sal_uInt8 EXC_TOKID_NONE = 0x00; /// Placeholder for invalid token id.
+const sal_uInt8 EXC_TOKID_EXP = 0x01; /// Array or shared formula reference.
+const sal_uInt8 EXC_TOKID_TBL = 0x02; /// Multiple operation reference.
+const sal_uInt8 EXC_TOKID_ADD = 0x03; /// Addition operator.
+const sal_uInt8 EXC_TOKID_SUB = 0x04; /// Subtraction operator.
+const sal_uInt8 EXC_TOKID_MUL = 0x05; /// Multiplication operator.
+const sal_uInt8 EXC_TOKID_DIV = 0x06; /// Division operator.
+const sal_uInt8 EXC_TOKID_POWER = 0x07; /// Power operator.
+const sal_uInt8 EXC_TOKID_CONCAT = 0x08; /// String concatenation operator.
+const sal_uInt8 EXC_TOKID_LT = 0x09; /// Less than operator.
+const sal_uInt8 EXC_TOKID_LE = 0x0A; /// Less than or equal operator.
+const sal_uInt8 EXC_TOKID_EQ = 0x0B; /// Equal operator.
+const sal_uInt8 EXC_TOKID_GE = 0x0C; /// Greater than or equal operator.
+const sal_uInt8 EXC_TOKID_GT = 0x0D; /// Greater than operator.
+const sal_uInt8 EXC_TOKID_NE = 0x0E; /// Not equal operator.
+const sal_uInt8 EXC_TOKID_ISECT = 0x0F; /// Intersection operator.
+const sal_uInt8 EXC_TOKID_LIST = 0x10; /// List operator.
+const sal_uInt8 EXC_TOKID_RANGE = 0x11; /// Range operator.
+const sal_uInt8 EXC_TOKID_UPLUS = 0x12; /// Unary plus.
+const sal_uInt8 EXC_TOKID_UMINUS = 0x13; /// Unary minus.
+const sal_uInt8 EXC_TOKID_PERCENT = 0x14; /// Percent sign.
+const sal_uInt8 EXC_TOKID_PAREN = 0x15; /// Parentheses.
+const sal_uInt8 EXC_TOKID_MISSARG = 0x16; /// Missing argument.
+const sal_uInt8 EXC_TOKID_STR = 0x17; /// String constant.
+const sal_uInt8 EXC_TOKID_NLR = 0x18; /// Natural language reference (NLR).
+const sal_uInt8 EXC_TOKID_ATTR = 0x19; /// Special attribute.
+const sal_uInt8 EXC_TOKID_SHEET = 0x1A; /// Start of a sheet reference (BIFF2-BIFF4).
+const sal_uInt8 EXC_TOKID_ENDSHEET = 0x1B; /// End of a sheet reference (BIFF2-BIFF4).
+const sal_uInt8 EXC_TOKID_ERR = 0x1C; /// Error constant.
+const sal_uInt8 EXC_TOKID_BOOL = 0x1D; /// Boolean constant.
+const sal_uInt8 EXC_TOKID_INT = 0x1E; /// Integer constant.
+const sal_uInt8 EXC_TOKID_NUM = 0x1F; /// Floating-point constant.
+
+// Base IDs of classified tokens ----------------------------------------------
+
+const sal_uInt8 EXC_TOKID_ARRAY = 0x00; /// Array constant.
+const sal_uInt8 EXC_TOKID_FUNC = 0x01; /// Function, fixed number of arguments.
+const sal_uInt8 EXC_TOKID_FUNCVAR = 0x02; /// Function, variable number of arguments.
+const sal_uInt8 EXC_TOKID_NAME = 0x03; /// Defined name.
+const sal_uInt8 EXC_TOKID_REF = 0x04; /// 2D cell reference.
+const sal_uInt8 EXC_TOKID_AREA = 0x05; /// 2D area reference.
+const sal_uInt8 EXC_TOKID_MEMAREA = 0x06; /// Constant reference subexpression.
+const sal_uInt8 EXC_TOKID_MEMERR = 0x07; /// Deleted reference subexpression.
+const sal_uInt8 EXC_TOKID_MEMNOMEM = 0x08; /// Constant reference subexpression without result.
+const sal_uInt8 EXC_TOKID_MEMFUNC = 0x09; /// Variable reference subexpression.
+const sal_uInt8 EXC_TOKID_REFERR = 0x0A; /// Deleted 2D cell reference.
+const sal_uInt8 EXC_TOKID_AREAERR = 0x0B; /// Deleted 2D area reference.
+const sal_uInt8 EXC_TOKID_REFN = 0x0C; /// Relative 2D cell reference (in names).
+const sal_uInt8 EXC_TOKID_AREAN = 0x0D; /// Relative 2D area reference (in names).
+const sal_uInt8 EXC_TOKID_MEMAREAN = 0x0E; /// Reference subexpression (in names).
+const sal_uInt8 EXC_TOKID_MEMNOMEMN = 0x0F; /// Reference subexpression (in names) without result.
+const sal_uInt8 EXC_TOKID_FUNCCE = 0x18;
+const sal_uInt8 EXC_TOKID_NAMEX = 0x19; /// External reference.
+const sal_uInt8 EXC_TOKID_REF3D = 0x1A; /// 3D cell reference.
+const sal_uInt8 EXC_TOKID_AREA3D = 0x1B; /// 3D area reference.
+const sal_uInt8 EXC_TOKID_REFERR3D = 0x1C; /// Deleted 3D cell reference.
+const sal_uInt8 EXC_TOKID_AREAERR3D = 0x1D; /// Deleted 3D area reference
+
+// specific token constants ---------------------------------------------------
+
+const sal_uInt16 EXC_TOK_STR_MAXLEN = 255; /// Maximum string length of a tStr token.
+
+const sal_uInt8 EXC_TOK_BOOL_FALSE = 0; /// FALSE value of a tBool token.
+const sal_uInt8 EXC_TOK_BOOL_TRUE = 1; /// TRUE value of a tBool token.
+
+const sal_uInt8 EXC_TOK_ATTR_VOLATILE = 0x01; /// Volatile function.
+const sal_uInt8 EXC_TOK_ATTR_IF = 0x02; /// Start of true condition in IF function.
+const sal_uInt8 EXC_TOK_ATTR_CHOOSE = 0x04; /// Jump array of CHOOSE function.
+const sal_uInt8 EXC_TOK_ATTR_GOTO = 0x08; /// Jump to token.
+const sal_uInt8 EXC_TOK_ATTR_SUM = 0x10; /// SUM function with one parameter.
+const sal_uInt8 EXC_TOK_ATTR_ASSIGN = 0x20; /// BASIC style assignment.
+const sal_uInt8 EXC_TOK_ATTR_SPACE = 0x40; /// Spaces in formula representation.
+
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP = 0x00; /// Spaces before next token.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_BR = 0x01; /// Line breaks before next token.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_OPEN = 0x02; /// Spaces before opening parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_BR_OPEN = 0x03; /// Line breaks before opening parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_CLOSE = 0x04; /// Spaces before closing parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_BR_CLOSE = 0x05; /// Line breaks before closing parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_PRE = 0x06; /// Spaces before formula (BIFF3).
+
+const sal_uInt16 EXC_TOK_FUNCVAR_CMD = 0x8000; /// Macro command.
+const sal_uInt16 EXC_TOK_FUNCVAR_INDEXMASK = 0x7FFF; /// Mask for function/command index.
+const sal_uInt8 EXC_TOK_FUNCVAR_PROMPT = 0x80; /// User prompt for macro commands.
+const sal_uInt8 EXC_TOK_FUNCVAR_COUNTMASK = 0x7F; /// Mask for parameter count.
+
+const sal_uInt16 EXC_TOK_REF_COLREL = 0x4000; /// True = Column is relative.
+const sal_uInt16 EXC_TOK_REF_ROWREL = 0x8000; /// True = Row is relative.
+
+const sal_uInt8 EXC_TOK_NLR_ERR = 0x01; /// NLR: Invalid/deleted.
+const sal_uInt8 EXC_TOK_NLR_ROWR = 0x02; /// NLR: Row index.
+const sal_uInt8 EXC_TOK_NLR_COLR = 0x03; /// NLR: Column index.
+const sal_uInt8 EXC_TOK_NLR_ROWV = 0x06; /// NLR: Value in row.
+const sal_uInt8 EXC_TOK_NLR_COLV = 0x07; /// NLR: Value in column.
+const sal_uInt8 EXC_TOK_NLR_RANGE = 0x0A; /// NLR: Range.
+const sal_uInt8 EXC_TOK_NLR_SRANGE = 0x0B; /// Stacked NLR: Range.
+const sal_uInt8 EXC_TOK_NLR_SROWR = 0x0C; /// Stacked NLR: Row index.
+const sal_uInt8 EXC_TOK_NLR_SCOLR = 0x0D; /// Stacked NLR: Column index.
+const sal_uInt8 EXC_TOK_NLR_SROWV = 0x0E; /// Stacked NLR: Value in row.
+const sal_uInt8 EXC_TOK_NLR_SCOLV = 0x0F; /// Stacked NLR: Value in column.
+const sal_uInt8 EXC_TOK_NLR_RANGEERR = 0x10; /// NLR: Invalid/deleted range.
+const sal_uInt8 EXC_TOK_NLR_SXNAME = 0x1D; /// NLR: Pivot table name.
+const sal_uInt16 EXC_TOK_NLR_REL = 0x8000; /// True = Natural language ref is relative.
+
+const sal_uInt32 EXC_TOK_NLR_ADDREL = 0x80000000; /// NLR relative (in appended data).
+const sal_uInt32 EXC_TOK_NLR_ADDMASK = 0x3FFFFFFF; /// Mask for number of appended ranges.
+
+// ----------------------------------------------------------------------------
+
+/** Type of a formula. */
+enum XclFormulaType
+{
+ EXC_FMLATYPE_CELL, /// Simple cell formula, also used in change tracking.
+ EXC_FMLATYPE_MATRIX, /// Matrix (array) formula.
+ EXC_FMLATYPE_SHARED, /// Shared formula.
+ EXC_FMLATYPE_CONDFMT, /// Conditional format.
+ EXC_FMLATYPE_DATAVAL, /// Data validation.
+ EXC_FMLATYPE_NAME, /// Defined name.
+ EXC_FMLATYPE_CHART, /// Chart source ranges.
+ EXC_FMLATYPE_CONTROL, /// Spreadsheet links in form controls.
+ EXC_FMLATYPE_WQUERY, /// Web query source range.
+ EXC_FMLATYPE_LISTVAL /// List (cell range) validation.
+};
+
+// Function parameter info ====================================================
+
+/** Enumerates validity modes for a function parameter. */
+enum XclFuncParamValidity
+{
+ EXC_PARAM_NONE = 0, /// Default for an unspecified entry in a C-array.
+ EXC_PARAM_REGULAR, /// Parameter supported by Calc and Excel.
+ EXC_PARAM_CALCONLY, /// Parameter supported by Calc only.
+ EXC_PARAM_EXCELONLY /// Parameter supported by Excel only.
+};
+
+/** Enumerates different types of token class conversion in function parameters. */
+enum XclFuncParamConv
+{
+ EXC_PARAMCONV_ORG, /// Use original class of current token.
+ EXC_PARAMCONV_VAL, /// Convert tokens to VAL class.
+ EXC_PARAMCONV_ARR, /// Convert tokens to ARR class.
+ EXC_PARAMCONV_RPT, /// Repeat parent conversion in VALTYPE parameters.
+ EXC_PARAMCONV_RPX, /// Repeat parent conversion in REFTYPE parameters.
+ EXC_PARAMCONV_RPO /// Repeat parent conversion in operands of operators.
+};
+
+/** Structure that contains all needed information for a parameter in a
+ function.
+
+ The member meValid specifies which application supports the parameter. If
+ set to CALCONLY, import filters have to insert a default value for this
+ parameter, and export filters have to skip the parameter. If set to
+ EXCELONLY, import filters have to skip the parameter, and export filters
+ have to insert a default value for this parameter.
+
+ The member mbValType specifies whether the parameter requires tokens to be
+ of value type (VAL or ARR class).
+
+ If set to false, the parameter is called to be REFTYPE. Tokens with REF
+ default class can be inserted for the parameter (e.g. tAreaR tokens).
+
+ If set to true, the parameter is called to be VALTYPE. Tokens with REF
+ class need to be converted to VAL tokens first (e.g. tAreaR will be
+ converted to tAreaV), and further conversion is done according to this
+ new token class.
+
+ The member meConv specifies how to convert the current token class of the
+ token inserted for the parameter. If the token class is still REF this
+ means that the token has default REF class and the parameter is REFTYPE
+ (see member mbValType), the token will not be converted at all and remains
+ in REF class. Otherwise, token class conversion is depending on the actual
+ token class of the return value of the function containing this parameter.
+ The function may return REF class (tFuncR, tFuncVarR, tFuncCER), or it may
+ return VAL or ARR class (tFuncV, tFuncA, tFuncVarV, tFuncVarA, tFuncCEV,
+ tFuncCEA). Even if the function is able to return REF class, it may return
+ VAL or ARR class instead due to the VALTYPE data type of the parent
+ function parameter that calls the own function. Example: The INDIRECT
+ function returns REF class by default. But if called from a VALTYPE
+ function parameter, e.g. in the formula =ABS(INDIRECT("A1")), it returns
+ VAL or ARR class instead. Additionally, the repeating conversion types RPT
+ and RPX rely on the conversion executed for the function token class.
+
+ 1) ORG:
+ Use the original class of the token (VAL or ARR), regardless of any
+ conversion done for the function return class.
+
+ 2) VAL:
+ Convert ARR tokens to VAL class, regardless of any conversion done for
+ the function return class.
+
+ 3) ARR:
+ Convert VAL tokens to ARR class, regardless of any conversion done for
+ the function return class.
+
+ 4) RPT:
+ If the own function returns REF class (thus it is called from a REFTYPE
+ parameter, see above), and the parent conversion type (for the function
+ return class) was ORG, VAL, or ARR, ignore that conversion and always
+ use VAL conversion for the own token instead. If the parent conversion
+ type was RPT or RPX, repeat the conversion that would have been used if
+ the function would return value type.
+ If the own function returns value type (VAL or ARR class, see above),
+ and the parent conversion type (for the function return class) was ORG,
+ VAL, ARR, or RPT, repeat this conversion for the own token. If the
+ parent conversion type was RPX, always use ORG conversion type for the
+ own token instead.
+
+ 5) RPX:
+ This type of conversion only occurs in functions returning VAL class by
+ default. If the own token is value type, and the VAL return class of
+ the own function has been changed to ARR class (due to direct ARR
+ conversion, or due to ARR conversion repeated by RPT or RPX), set the
+ own token to ARR type. Otherwise use the original token type (VAL
+ conversion from parent parameter will not be repeated at all). If
+ nested functions have RPT or value-type RPX parameters, they will not
+ repeat this conversion type, but will use ORG conversion instead (see
+ description of RPT above).
+
+ 6) RPO:
+ This type of conversion is only used for the operands of all operators
+ (unary and binary arithmetic operators, comparison operators, and range
+ operators). It is not used for function parameters. On conversion, it
+ will be replaced by the last conversion type that was not the RPO
+ conversion. This leads to a slightly different behaviour than the RPT
+ conversion for operands in conjunction with a parent RPX conversion.
+ */
+struct XclFuncParamInfo
+{
+ XclFuncParamValidity meValid; /// Parameter validity.
+ XclFuncParamConv meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
+};
+
+// Function data ==============================================================
+
+const sal_uInt8 EXC_FUNC_MAXPARAM = 30; /// Maximum parameter count.
+
+const size_t EXC_FUNCINFO_PARAMINFO_COUNT = 5; /// Number of parameter info entries.
+
+const sal_uInt8 EXC_FUNCFLAG_VOLATILE = 0x01; /// Result is volatile (e.g. NOW() function).
+const sal_uInt8 EXC_FUNCFLAG_IMPORTONLY = 0x02; /// Only used in import filter.
+const sal_uInt8 EXC_FUNCFLAG_EXPORTONLY = 0x04; /// Only used in export filter.
+
+// selected function IDs
+const sal_uInt16 EXC_FUNCID_IF = 1;
+const sal_uInt16 EXC_FUNCID_SUM = 4;
+const sal_uInt16 EXC_FUNCID_AND = 36;
+const sal_uInt16 EXC_FUNCID_OR = 37;
+const sal_uInt16 EXC_FUNCID_CHOOSE = 100;
+const sal_uInt16 EXC_FUNCID_EXTERNCALL = 255;
+
+/** Represents information for a spreadsheet function for import and export.
+
+ The member mpParamInfos points to an array of type information structures
+ for all parameters of the function. The last initialized structure
+ describing a regular parameter (member meValid == EXC_PARAMVALID_ALWAYS) in
+ this array is used repeatedly for all following parameters supported by a
+ function.
+ */
+struct XclFunctionInfo
+{
+ OpCode meOpCode; /// Calc function opcode.
+ sal_uInt16 mnXclFunc; /// Excel function index.
+ sal_uInt8 mnMinParamCount; /// Minimum number of parameters.
+ sal_uInt8 mnMaxParamCount; /// Maximum number of parameters.
+ sal_uInt8 mnRetClass; /// Token class of the return value.
+ XclFuncParamInfo mpParamInfos[ EXC_FUNCINFO_PARAMINFO_COUNT ]; /// Information for all parameters.
+ sal_uInt8 mnFlags; /// Additional flags (EXC_FUNCFLAG_* constants).
+ const sal_Char* mpcMacroName; /// Function name, if simulated by a macro call (UTF-8).
+
+ /** Returns true, if the function is volatile. */
+ inline bool IsVolatile() const { return ::get_flag( mnFlags, EXC_FUNCFLAG_VOLATILE ); }
+ /** Returns true, if the function parameter count is fixed. */
+ inline bool IsFixedParamCount() const { return (mnXclFunc != EXC_FUNCID_EXTERNCALL) && (mnMinParamCount == mnMaxParamCount); }
+ /** Returns true, if the function is simulated by a macro call. */
+ inline bool IsMacroFunc() const { return mpcMacroName != 0; }
+ /** Returns the name of the external function as string. */
+ String GetMacroFuncName() const;
+};
+
+// ----------------------------------------------------------------------------
+
+class XclRoot;
+
+/** Provides access to function info structs for all available functions. */
+class XclFunctionProvider
+{
+public:
+ explicit XclFunctionProvider( const XclRoot& rRoot );
+
+ /** Returns the function data for an Excel function index, or 0 on error. */
+ const XclFunctionInfo* GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const;
+ /** Returns the function data for an Excel function simulated by a macro call, or 0 on error. */
+ const XclFunctionInfo* GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const;
+ /** Returns the function data for a Calc opcode, or 0 on error. */
+ const XclFunctionInfo* GetFuncInfoFromOpCode( OpCode eOpCode ) const;
+
+private:
+ void FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd );
+ void FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd );
+
+private:
+ typedef ::std::map< sal_uInt16, const XclFunctionInfo* > XclFuncMap;
+ typedef ::std::map< String, const XclFunctionInfo* > XclMacroNameMap;
+ typedef ::std::map< OpCode, const XclFunctionInfo* > ScFuncMap;
+
+ XclFuncMap maXclFuncMap; /// Maps Excel function indexes to function data.
+ XclMacroNameMap maXclMacroNameMap; /// Maps macro function names to function data.
+ ScFuncMap maScFuncMap; /// Maps Calc opcodes to function data.
+};
+
+// Token array ================================================================
+
+class XclImpStream;
+class XclExpStream;
+
+/** Binary representation of an Excel token array. */
+class XclTokenArray
+{
+public:
+ /** Creates an empty token array. */
+ explicit XclTokenArray( bool bVolatile = false );
+ /** Creates a token array, swaps passed token vector into own data. */
+ explicit XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile = false );
+ /** Creates a token array, swaps passed token vectors into own data. */
+ explicit XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile = false );
+
+ /** Returns true, if the token array is empty. */
+ inline bool Empty() const { return maTokVec.empty(); }
+ /** Returns the size of the token array in bytes. */
+ sal_uInt16 GetSize() const;
+ /** Returns read-only access to the byte vector storing token data. */
+ inline const sal_uInt8* GetData() const { return maTokVec.empty() ? 0 : &maTokVec.front(); }
+ /** Returns true, if the formula contains a volatile function. */
+ inline bool IsVolatile() const { return mbVolatile; }
+
+ /** Reads the size field of the token array. */
+ void ReadSize( XclImpStream& rStrm );
+ /** Reads the tokens of the token array (without size field). */
+ void ReadArray( XclImpStream& rStrm );
+ /** Reads size field and the tokens. */
+ void Read( XclImpStream& rStrm );
+
+ /** Writes the size field of the token array. */
+ void WriteSize( XclExpStream& rStrm ) const;
+ /** Writes the tokens of the token array (without size field). */
+ void WriteArray( XclExpStream& rStrm ) const;
+ /** Writes size field and the tokens. */
+ void Write( XclExpStream& rStrm ) const;
+
+ /** Compares this token array with the passed. */
+ bool operator==( const XclTokenArray& rTokArr ) const;
+
+private:
+ ScfUInt8Vec maTokVec; /// Byte vector containing token data.
+ ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
+ bool mbVolatile; /// True = Formula contains volatile function.
+};
+
+typedef ScfRef< XclTokenArray > XclTokenArrayRef;
+
+/** Calls the Read() function at the passed token array. */
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr );
+/** Calls the Read() function at the passed token array. */
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr );
+/** Calls the Write() function at the passed token array. */
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr );
+/** Calls the Write() function at the passed token array. */
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr );
+
+// ----------------------------------------------------------------------------
+
+namespace formula { class FormulaToken; }
+class ScTokenArray;
+
+/** Special token array iterator for the Excel filters.
+
+ Iterates over a Calc token array without modifying it (therefore the
+ iterator can be used with constant token arrays).
+
+ Usage: Construct a new iterator object and pass a Calc token array, or use
+ the Init() function to assign another Calc token array. As long as the Is()
+ function returns true, the accessor functions can be used to get the
+ current Calc token.
+ */
+class XclTokenArrayIterator
+{
+public:
+ explicit XclTokenArrayIterator();
+ explicit XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces );
+ /** Copy constructor that allows to change the skip-spaces mode. */
+ explicit XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces );
+
+ void Init();
+ void Init( const ScTokenArray& rScTokArr, bool bSkipSpaces );
+
+ inline bool Is() const { return mppScToken != 0; }
+ inline bool operator!() const { return !Is(); }
+ inline const ::formula::FormulaToken* Get() const { return mppScToken ? *mppScToken : 0; }
+ inline const ::formula::FormulaToken* operator->() const { return Get(); }
+ inline const ::formula::FormulaToken& operator*() const { return *Get(); }
+
+ XclTokenArrayIterator& operator++();
+
+private:
+ void NextRawToken();
+ void SkipSpaces();
+
+private:
+ const ::formula::FormulaToken*const* mppScTokenBeg; /// Pointer to first token pointer of token array.
+ const ::formula::FormulaToken*const* mppScTokenEnd; /// Pointer behind last token pointer of token array.
+ const ::formula::FormulaToken*const* mppScToken; /// Pointer to current token pointer of token array.
+ bool mbSkipSpaces; /// true = Skip whitespace tokens.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all cell references that can be extracted from a multiple operations formula. */
+struct XclMultipleOpRefs
+{
+ ScAddress maFmlaScPos; /// Position of the (first) formula cell.
+ ScAddress maColFirstScPos;
+ ScAddress maColRelScPos;
+ ScAddress maRowFirstScPos;
+ ScAddress maRowRelScPos;
+ bool mbDblRefMode; /// true = One formula with row and column values.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A helper with Excel specific token array functions.
+
+ The purpose to not add these functions to ScTokenArray is to prevent code
+ changes in low-level Calc headers and to keep the Excel specific source
+ code in the filter directory. Deriving from ScTokenArray is not viable
+ because that would need expensive copy-constructions of the token arrays.
+ */
+class XclTokenArrayHelper
+{
+public:
+ // token identifiers ------------------------------------------------------
+
+ /** Returns the base token ID of the passed (classified) token ID. */
+ inline static sal_uInt8 GetBaseTokenId( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKID_MASK; }
+ /** Returns the classified token ID from a base ID and the token class. */
+ inline static sal_uInt8 GetTokenId( sal_uInt8 nBaseId, sal_uInt8 nTokenClass );
+
+ /** Returns the token class of the passed token ID. */
+ inline static sal_uInt8 GetTokenClass( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKCLASS_MASK; }
+ /** Changes the token class in the passed classified token ID. */
+ inline static void ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass );
+
+ // strings and string lists -----------------------------------------------
+
+ /** Tries to extract a string from the passed token.
+ @param rString (out-parameter) The string contained in the token.
+ @return true = Passed token is a string token, rString parameter is valid. */
+ static bool GetTokenString( String& rString, const ::formula::FormulaToken& rScToken );
+
+ /** Parses the passed formula and tries to find a single string token, i.e. "abc".
+ @param rString (out-parameter) The string contained in the formula.
+ @return true = String token found, rString parameter is valid. */
+ static bool GetString( String& rString, const ScTokenArray& rScTokArr );
+
+ /** Parses the passed formula and tries to find a string token list, i.e. "abc";"def";"ghi".
+ @descr Returns the unquoted (!) strings in a single string, separated with the
+ passed character. If a comma is specified, the function will return abc,def,ghi from
+ the example above.
+ @param rStringList (out-parameter) All strings contained in the formula as list.
+ @param cSep List separator character.
+ @return true = String token list found, rString parameter is valid. */
+ static bool GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep );
+
+ /** Tries to convert a formula that consists of a single string token to a list of strings.
+ @descr Example: The formula ="abc\ndef\nghi" will be converted to the formula
+ ="abc";"def";"ghi", if the LF character is specified as separator.
+ @param rScTokArr (in/out-parameter) The token array to modify.
+ @param cStringSep The separator in the source string.
+ @param bTrimLeadingSpaces true = remove leading spaces from each token. */
+ static void ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces );
+
+ // shared formulas --------------------------------------------------------
+
+ /** Tries to extract the definition of a shared formula from the passed token array.
+ @descr Shared formulas are stored as hidden defined names in Calc. This
+ function looks if the passed token array consists of the reference to
+ such a hidden defined name and returns its definition on success. */
+ static const ScTokenArray* GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr );
+
+ // multiple operations ----------------------------------------------------
+
+ /** Parses the passed formula and tries to extract references of a multiple operation.
+ @descr Requires that the formula contains a single MULTIPLE.OPERATION function call.
+ Spaces in the formula are silently ignored.
+ @return true = Multiple operation found, and all references successfully extracted. */
+ static bool GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr );
+};
+
+// ----------------------------------------------------------------------------
+
+inline sal_uInt8 XclTokenArrayHelper::GetTokenId( sal_uInt8 nBaseId, sal_uInt8 nTokenClass )
+{
+ DBG_ASSERT( !::get_flag( nBaseId, static_cast< sal_uInt8 >( ~EXC_TOKID_MASK ) ), "XclTokenArrayHelper::GetTokenId - invalid token ID" );
+ DBG_ASSERT( !::get_flag( nTokenClass, static_cast< sal_uInt8 >( ~EXC_TOKCLASS_MASK ) ), "XclTokenArrayHelper::GetTokenId - invalid token class" );
+ return nBaseId | nTokenClass;
+}
+
+inline void XclTokenArrayHelper::ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass )
+{
+ DBG_ASSERT( !::get_flag( nTokenClass, static_cast< sal_uInt8 >( ~EXC_TOKCLASS_MASK ) ), "XclTokenArrayHelper::ChangeTokenClass - invalid token class" );
+ ::set_flag( rnTokenId, EXC_TOKCLASS_MASK, false );
+ ::set_flag( rnTokenId, nTokenClass );
+}
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xllink.hxx b/sc/source/filter/inc/xllink.hxx
new file mode 100644
index 000000000000..3e41fb350acb
--- /dev/null
+++ b/sc/source/filter/inc/xllink.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLLINK_HXX
+#define SC_XLLINK_HXX
+
+#include <sal/types.h>
+
+// Constants and Enumerations =================================================
+
+const sal_uInt16 EXC_TAB_EXTERNAL = 0xFFFE; /// Special sheet index for external links.
+const sal_uInt16 EXC_TAB_DELETED = 0xFFFF; /// Deleted sheet in a 3D reference.
+
+// (0x0016) EXTERNCOUNT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EXTERNCOUNT = 0x0016;
+
+// (0x0017) EXTERNSHEET -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EXTERNSHEET = 0x0017;
+
+const sal_Unicode EXC_EXTSH_URL = '\x01';
+const sal_Unicode EXC_EXTSH_OWNTAB = '\x02';
+const sal_Unicode EXC_EXTSH_TABNAME = '\x03';
+const sal_Unicode EXC_EXTSH_OWNDOC = '\x04';
+const sal_Unicode EXC_EXTSH_ADDIN = '\x3A';
+
+// (0x0023) EXTERNNAME --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EXTERNNAME = 0x0023;
+
+const sal_uInt16 EXC_EXTN_BUILTIN = 0x0001;
+const sal_uInt16 EXC_EXTN_OLE = 0x0010;
+const sal_uInt16 EXC_EXTN_OLE_OR_DDE = 0xFFFE;
+
+const sal_uInt16 EXC_EXTN_EXPDDE_STDDOC = 0x7FEA; /// for export
+const sal_uInt16 EXC_EXTN_EXPDDE = 0x7FE2; /// for export
+
+// (0x0059, 0x005A) XCT, CRN --------------------------------------------------
+
+const sal_uInt16 EXC_ID_XCT = 0x0059;
+const sal_uInt16 EXC_ID_CRN = 0x005A;
+
+// (0x013D) TABID -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_TABID = 0x013D;
+
+// (0x01AE) SUPBOOK -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SUPBOOK = 0x01AE;
+
+const sal_uInt16 EXC_SUPB_SELF = 0x0401;
+const sal_uInt16 EXC_SUPB_ADDIN = 0x3A01;
+
+/** This enumeration specifies the type of a SUPBOOK record. */
+enum XclSupbookType
+{
+ EXC_SBTYPE_UNKNOWN, /// unknown SUPBOOK record type.
+ EXC_SBTYPE_SELF, /// SUPBOOK is used for internal references.
+ EXC_SBTYPE_EXTERN, /// SUPBOOK is used for external references.
+ EXC_SBTYPE_ADDIN, /// SUPBOOK contains add-in functions.
+ EXC_SBTYPE_SPECIAL, /// SUPBOOK is used for DDE or OLE links.
+ EXC_SBTYPE_EUROTOOL /// SUPBOOK is uesd for EUROCONVERT.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlname.hxx b/sc/source/filter/inc/xlname.hxx
new file mode 100644
index 000000000000..5bfcf9164892
--- /dev/null
+++ b/sc/source/filter/inc/xlname.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLNAME_HXX
+#define SC_XLNAME_HXX
+
+#include <sal/types.h>
+
+// Constants and Enumerations =================================================
+
+// (0x0018, 0x0218) NAME ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_NAME = 0x0018;
+const sal_uInt16 EXC_ID34_NAME = 0x0218;
+
+// flags
+const sal_uInt16 EXC_NAME_DEFAULT = 0x0000;
+const sal_uInt16 EXC_NAME_HIDDEN = 0x0001;
+const sal_uInt16 EXC_NAME_FUNC = 0x0002;
+const sal_uInt16 EXC_NAME_VB = 0x0004;
+const sal_uInt16 EXC_NAME_PROC = 0x0008;
+const sal_uInt16 EXC_NAME_CALCEXP = 0x0010;
+const sal_uInt16 EXC_NAME_BUILTIN = 0x0020;
+const sal_uInt16 EXC_NAME_FGROUPMASK = 0x0FC0;
+const sal_uInt16 EXC_NAME_BIG = 0x1000;
+
+const sal_uInt8 EXC_NAME2_FUNC = 0x02; /// BIFF2 function/command flag.
+
+const sal_uInt16 EXC_NAME_GLOBAL = 0; /// 0 = Globally defined name.
+
+// codes for built-in names
+const sal_Unicode EXC_BUILTIN_CONSOLIDATEAREA = '\x00';
+const sal_Unicode EXC_BUILTIN_AUTOOPEN = '\x01';
+const sal_Unicode EXC_BUILTIN_AUTOCLOSE = '\x02';
+const sal_Unicode EXC_BUILTIN_EXTRACT = '\x03';
+const sal_Unicode EXC_BUILTIN_DATABASE = '\x04';
+const sal_Unicode EXC_BUILTIN_CRITERIA = '\x05';
+const sal_Unicode EXC_BUILTIN_PRINTAREA = '\x06';
+const sal_Unicode EXC_BUILTIN_PRINTTITLES = '\x07';
+const sal_Unicode EXC_BUILTIN_RECORDER = '\x08';
+const sal_Unicode EXC_BUILTIN_DATAFORM = '\x09';
+const sal_Unicode EXC_BUILTIN_AUTOACTIVATE = '\x0A';
+const sal_Unicode EXC_BUILTIN_AUTODEACTIVATE = '\x0B';
+const sal_Unicode EXC_BUILTIN_SHEETTITLE = '\x0C';
+const sal_Unicode EXC_BUILTIN_FILTERDATABASE = '\x0D';
+const sal_Unicode EXC_BUILTIN_UNKNOWN = '\x0E';
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlpage.hxx b/sc/source/filter/inc/xlpage.hxx
new file mode 100644
index 000000000000..f6860595cd20
--- /dev/null
+++ b/sc/source/filter/inc/xlpage.hxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLPAGE_HXX
+#define SC_XLPAGE_HXX
+
+#include <tools/gen.hxx>
+#include "xltools.hxx"
+
+// Constants and Enumerations =================================================
+
+// (0x0014, 0x0015) HEADER, FOOTER --------------------------------------------
+
+const sal_uInt16 EXC_ID_HEADER = 0x0014;
+const sal_uInt16 EXC_ID_FOOTER = 0x0015;
+
+// (0x001A, 0x001B) VERTICAL-, HORIZONTALPAGEBREAKS ---------------------------
+
+const sal_uInt16 EXC_ID_VERPAGEBREAKS = 0x001A;
+const sal_uInt16 EXC_ID_HORPAGEBREAKS = 0x001B;
+
+// (0x0026, 0x0027, 0x0028, 0x0029) LEFT-, RIGHT-, TOP-, BOTTOMMARGIN ---------
+
+const sal_uInt16 EXC_ID_LEFTMARGIN = 0x0026;
+const sal_uInt16 EXC_ID_RIGHTMARGIN = 0x0027;
+const sal_uInt16 EXC_ID_TOPMARGIN = 0x0028;
+const sal_uInt16 EXC_ID_BOTTOMMARGIN = 0x0029;
+
+const sal_Int32 EXC_MARGIN_DEFAULT_LR = 1900; /// Left/right default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_TB = 2500; /// Top/bottom default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_HF = 1300; /// Header/footer default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_HLR = 1900; /// Left/right header default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_FLR = 1900; /// Left/right footer default margin in 1/100mm.
+
+// (0x002A, 0x002B) PRINTHEADERS, PRINTGRIDLINES ------------------------------
+
+const sal_uInt16 EXC_ID_PRINTHEADERS = 0x002A;
+const sal_uInt16 EXC_ID_PRINTGRIDLINES = 0x002B;
+
+// (0x0033) PRINTSIZE ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PRINTSIZE = 0x0033;
+
+const sal_uInt16 EXC_PRINTSIZE_SCREEN = 1;
+const sal_uInt16 EXC_PRINTSIZE_PAGE = 2;
+const sal_uInt16 EXC_PRINTSIZE_FULL = 3;
+
+// (0x0082, 0x0083, 0x0084) GRIDSET, HCENTER, VCENTER -------------------------
+
+const sal_uInt16 EXC_ID_GRIDSET = 0x0082;
+const sal_uInt16 EXC_ID_HCENTER = 0x0083;
+const sal_uInt16 EXC_ID_VCENTER = 0x0084;
+
+// (0x00A1) SETUP -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SETUP = 0x00A1;
+
+const sal_uInt16 EXC_SETUP_INROWS = 0x0001;
+const sal_uInt16 EXC_SETUP_PORTRAIT = 0x0002;
+const sal_uInt16 EXC_SETUP_INVALID = 0x0004;
+const sal_uInt16 EXC_SETUP_BLACKWHITE = 0x0008;
+const sal_uInt16 EXC_SETUP_DRAFT = 0x0010;
+const sal_uInt16 EXC_SETUP_PRINTNOTES = 0x0020;
+const sal_uInt16 EXC_SETUP_STARTPAGE = 0x0080;
+const sal_uInt16 EXC_SETUP_NOTES_END = 0x0200;
+
+const sal_uInt16 EXC_PAPERSIZE_DEFAULT = 0;
+
+// ============================================================================
+
+// Page settings ==============================================================
+
+class SvxBrushItem;
+class SfxPrinter;
+
+/** Contains all page (print) settings for a single sheet. */
+struct XclPageData : ScfNoCopy
+{
+ typedef ::std::auto_ptr< SvxBrushItem > SvxBrushItemPtr;
+
+ ScfUInt16Vec maHorPageBreaks; /// Horizontal page breaks.
+ ScfUInt16Vec maVerPageBreaks; /// Vertical page breaks.
+ SvxBrushItemPtr mxBrushItem; /// Background bitmap.
+ String maHeader; /// Excel header string (empty = off).
+ String maFooter; /// Excel footer string (empty = off).
+ double mfLeftMargin; /// Left margin in inches.
+ double mfRightMargin; /// Right margin in inches.
+ double mfTopMargin; /// Top margin in inches.
+ double mfBottomMargin; /// Bottom margin in inches.
+ double mfHeaderMargin; /// Margin main page to header.
+ double mfFooterMargin; /// Margin main page to footer.
+ double mfHdrLeftMargin; /// Left margin to header.
+ double mfHdrRightMargin; /// Right margin to header.
+ double mfFtrLeftMargin; /// Left margin to footer.
+ double mfFtrRightMargin; /// Right margin to footer.
+ sal_uInt16 mnPaperSize; /// Index into paper size table.
+ sal_uInt16 mnCopies; /// Number of copies.
+ sal_uInt16 mnStartPage; /// Start page number.
+ sal_uInt16 mnScaling; /// Scaling in percent.
+ sal_uInt16 mnFitToWidth; /// Fit to number of pages in width.
+ sal_uInt16 mnFitToHeight; /// Fit to number of pages in height.
+ sal_uInt16 mnHorPrintRes; /// Horizontal printing resolution.
+ sal_uInt16 mnVerPrintRes; /// Vertical printing resolution.
+ bool mbValid; /// false = some of the values are not valid.
+ bool mbPortrait; /// true = portrait; false = landscape.
+ bool mbPrintInRows; /// true = in rows; false = in columns.
+ bool mbBlackWhite; /// true = black/white; false = colors.
+ bool mbDraftQuality; /// true = draft; false = default quality.
+ bool mbPrintNotes; /// true = print notes.
+ bool mbManualStart; /// true = mnStartPage valid; false = automatic.
+ bool mbFitToPages; /// true = fit to pages; false = scale in percent.
+ bool mbHorCenter; /// true = centered horizontally; false = left aligned.
+ bool mbVerCenter; /// true = centered vertically; false = top aligned.
+ bool mbPrintHeadings; /// true = print column and row headings.
+ bool mbPrintGrid; /// true = print grid lines.
+
+ explicit XclPageData();
+ ~XclPageData();
+
+ /** Sets Excel default page settings. */
+ void SetDefaults();
+
+ /** Returns the real paper size (twips) from the paper size index and paper orientation. */
+ Size GetScPaperSize() const;
+ /** Sets the Excel paper size index and paper orientation from Calc paper size (twips). */
+ void SetScPaperSize( const Size& rSize, bool bPortrait );
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx
new file mode 100644
index 000000000000..ad48c05a93f4
--- /dev/null
+++ b/sc/source/filter/inc/xlpivot.hxx
@@ -0,0 +1,817 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLPIVOT_HXX
+#define SC_XLPIVOT_HXX
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <tools/datetime.hxx>
+#include "ftools.hxx"
+#include "xladdress.hxx"
+#include "dpobject.hxx"
+
+#include <memory>
+
+class XclImpStream;
+class XclExpStream;
+
+// Constants and Enumerations =================================================
+
+// misc -----------------------------------------------------------------------
+
+#define EXC_STORAGE_PTCACHE CREATE_STRING( "_SX_DB_CUR" )
+
+// strings
+const sal_uInt16 EXC_PT_NOSTRING = 0xFFFF;
+const sal_uInt16 EXC_PT_MAXSTRLEN = 0xFFFE;
+
+// pivot cache fields
+const size_t EXC_PC_MAXFIELDCOUNT = 0xFFFE;
+const sal_uInt16 EXC_PC_NOFIELD = 0xFFFF;
+const xub_StrLen EXC_PC_MAXSTRLEN = 255;
+
+// pivot cache items
+const size_t EXC_PC_MAXITEMCOUNT = 32500;
+const sal_uInt16 EXC_PC_NOITEM = 0xFFFF;
+
+// pivot table fields
+const sal_uInt16 EXC_PT_MAXFIELDCOUNT = 0xFFFE;
+const sal_uInt16 EXC_PT_MAXROWCOLCOUNT = EXC_PT_MAXFIELDCOUNT;
+const sal_uInt16 EXC_PT_MAXPAGECOUNT = 256;
+const sal_uInt16 EXC_PT_MAXDATACOUNT = 256;
+
+// pivot table items
+const sal_uInt16 EXC_PT_MAXITEMCOUNT = 32500;
+
+const sal_uInt16 EXC_PT_AUTOFMT_HEADER = 0x810;
+const sal_uInt16 EXC_PT_AUTOFMT_ZERO = 0;
+const sal_uInt32 EXC_PT_AUTOFMT_FLAGS = 0x20;
+
+/** Data type of a pivot cache item. */
+enum XclPCItemType
+{
+ EXC_PCITEM_INVALID, /// Special state, not used in Excel files.
+ EXC_PCITEM_EMPTY, /// Empty cell.
+ EXC_PCITEM_TEXT, /// String data.
+ EXC_PCITEM_DOUBLE, /// Floating-point value.
+ EXC_PCITEM_DATETIME, /// Date/time.
+ EXC_PCITEM_INTEGER, /// 16-bit integer value.
+ EXC_PCITEM_BOOL, /// Boolean value.
+ EXC_PCITEM_ERROR /// Error code.
+};
+
+/** Specifies the type of a pivot cache field. */
+enum XclPCFieldType
+{
+ EXC_PCFIELD_STANDARD, /// Standard field without grouping.
+ EXC_PCFIELD_STDGROUP, /// Standard grouping field.
+ EXC_PCFIELD_NUMGROUP, /// Numeric grouping field.
+ EXC_PCFIELD_DATEGROUP, /// First date grouping field (opt. with child grouping field).
+ EXC_PCFIELD_DATECHILD, /// Additional date grouping field.
+ EXC_PCFIELD_CALCED, /// Calculated field.
+ EXC_PCFIELD_UNKNOWN /// Unknown field state, handled like standard field.
+};
+
+// (0x0051,0x0052) DCONREF, DCONNAME ------------------------------------------
+
+const sal_uInt16 EXC_ID_DCONREF = 0x0051;
+const sal_uInt16 EXC_ID_DCONNAME = 0x0052;
+
+// (0x00B0) SXVIEW ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXVIEW = 0x00B0;
+
+const sal_uInt16 EXC_SXVIEW_ROWGRAND = 0x0001;
+const sal_uInt16 EXC_SXVIEW_COLGRAND = 0x0002;
+const sal_uInt16 EXC_SXVIEW_DEFAULTFLAGS = 0x0208;
+
+const sal_uInt16 EXC_SXVIEW_DATALAST = 0xFFFF;
+const sal_uInt16 EXC_SXVIEW_AUTOFMT = 0x0001;
+
+// (0x00B1) SXVD --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXVD = 0x00B1;
+
+const sal_uInt16 EXC_SXVD_AXIS_NONE = 0x0000;
+const sal_uInt16 EXC_SXVD_AXIS_ROW = 0x0001;
+const sal_uInt16 EXC_SXVD_AXIS_COL = 0x0002;
+const sal_uInt16 EXC_SXVD_AXIS_PAGE = 0x0004;
+const sal_uInt16 EXC_SXVD_AXIS_DATA = 0x0008;
+const sal_uInt16 EXC_SXVD_AXIS_ROWCOL = EXC_SXVD_AXIS_ROW | EXC_SXVD_AXIS_COL;
+const sal_uInt16 EXC_SXVD_AXIS_ROWCOLPAGE = EXC_SXVD_AXIS_ROWCOL | EXC_SXVD_AXIS_PAGE;
+
+const sal_uInt16 EXC_SXVD_SUBT_NONE = 0x0000;
+const sal_uInt16 EXC_SXVD_SUBT_DEFAULT = 0x0001;
+const sal_uInt16 EXC_SXVD_SUBT_SUM = 0x0002;
+const sal_uInt16 EXC_SXVD_SUBT_COUNT = 0x0004;
+const sal_uInt16 EXC_SXVD_SUBT_AVERAGE = 0x0008;
+const sal_uInt16 EXC_SXVD_SUBT_MAX = 0x0010;
+const sal_uInt16 EXC_SXVD_SUBT_MIN = 0x0020;
+const sal_uInt16 EXC_SXVD_SUBT_PROD = 0x0040;
+const sal_uInt16 EXC_SXVD_SUBT_COUNTNUM = 0x0080;
+const sal_uInt16 EXC_SXVD_SUBT_STDDEV = 0x0100;
+const sal_uInt16 EXC_SXVD_SUBT_STDDEVP = 0x0200;
+const sal_uInt16 EXC_SXVD_SUBT_VAR = 0x0400;
+const sal_uInt16 EXC_SXVD_SUBT_VARP = 0x0800;
+
+const sal_uInt16 EXC_SXVD_DEFAULT_CACHE = EXC_PC_NOFIELD;
+
+// (0x00B2) SXVI --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXVI = 0x00B2;
+
+const sal_uInt16 EXC_SXVI_TYPE_PAGE = 0x00FE;
+const sal_uInt16 EXC_SXVI_TYPE_NULL = 0x00FF;
+const sal_uInt16 EXC_SXVI_TYPE_DATA = 0x0000;
+const sal_uInt16 EXC_SXVI_TYPE_DEFAULT = 0x0001;
+const sal_uInt16 EXC_SXVI_TYPE_SUM = 0x0002;
+const sal_uInt16 EXC_SXVI_TYPE_COUNT = 0x0003;
+const sal_uInt16 EXC_SXVI_TYPE_AVERAGE = 0x0004;
+const sal_uInt16 EXC_SXVI_TYPE_MAX = 0x0005;
+const sal_uInt16 EXC_SXVI_TYPE_MIN = 0x0006;
+const sal_uInt16 EXC_SXVI_TYPE_PROD = 0x0007;
+const sal_uInt16 EXC_SXVI_TYPE_COUNTNUM = 0x0008;
+const sal_uInt16 EXC_SXVI_TYPE_STDDEV = 0x0009;
+const sal_uInt16 EXC_SXVI_TYPE_STDDEVP = 0x000A;
+const sal_uInt16 EXC_SXVI_TYPE_VAR = 0x000B;
+const sal_uInt16 EXC_SXVI_TYPE_VARP = 0x000C;
+const sal_uInt16 EXC_SXVI_TYPE_GRAND = 0x000D;
+
+const sal_uInt16 EXC_SXVI_DEFAULTFLAGS = 0x0000;
+const sal_uInt16 EXC_SXVI_HIDDEN = 0x0001;
+const sal_uInt16 EXC_SXVI_HIDEDETAIL = 0x0002;
+const sal_uInt16 EXC_SXVI_FORMULA = 0x0004;
+const sal_uInt16 EXC_SXVI_MISSING = 0x0008;
+
+const sal_uInt16 EXC_SXVI_DEFAULT_CACHE = EXC_PC_NOFIELD;
+
+// (0x00B4) SXIVD -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXIVD = 0x00B4;
+const sal_uInt16 EXC_SXIVD_DATA = 0xFFFE;
+
+// (0x00B5) SXLI --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXLI = 0x00B5;
+const sal_uInt16 EXC_SXLI_DEFAULTFLAGS = 0x0000;
+
+// (0x00B6) SXPI --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXPI = 0x00B6;
+const sal_uInt16 EXC_SXPI_ALLITEMS = 0x7FFD;
+
+// (0x00C5) SXDI --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXDI = 0x00C5;
+
+const sal_uInt16 EXC_SXDI_FUNC_SUM = 0x0000;
+const sal_uInt16 EXC_SXDI_FUNC_COUNT = 0x0001;
+const sal_uInt16 EXC_SXDI_FUNC_AVERAGE = 0x0002;
+const sal_uInt16 EXC_SXDI_FUNC_MAX = 0x0003;
+const sal_uInt16 EXC_SXDI_FUNC_MIN = 0x0004;
+const sal_uInt16 EXC_SXDI_FUNC_PRODUCT = 0x0005;
+const sal_uInt16 EXC_SXDI_FUNC_COUNTNUM = 0x0006;
+const sal_uInt16 EXC_SXDI_FUNC_STDDEV = 0x0007;
+const sal_uInt16 EXC_SXDI_FUNC_STDDEVP = 0x0008;
+const sal_uInt16 EXC_SXDI_FUNC_VAR = 0x0009;
+const sal_uInt16 EXC_SXDI_FUNC_VARP = 0x000A;
+
+const sal_uInt16 EXC_SXDI_REF_NORMAL = 0x0000;
+const sal_uInt16 EXC_SXDI_REF_DIFF = 0x0001;
+const sal_uInt16 EXC_SXDI_REF_PERC = 0x0002;
+const sal_uInt16 EXC_SXDI_REF_PERC_DIFF = 0x0003;
+const sal_uInt16 EXC_SXDI_REF_RUN_TOTAL = 0x0004;
+const sal_uInt16 EXC_SXDI_REF_PERC_ROW = 0x0005;
+const sal_uInt16 EXC_SXDI_REF_PERC_COL = 0x0006;
+const sal_uInt16 EXC_SXDI_REF_PERC_TOTAL = 0x0007;
+const sal_uInt16 EXC_SXDI_REF_INDEX = 0x0008;
+
+const sal_uInt16 EXC_SXDI_PREVITEM = 0x7FFB;
+const sal_uInt16 EXC_SXDI_NEXTITEM = 0x7FFC;
+
+// (0x00C6) SXDB --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXDB = 0x00C6;
+
+const sal_uInt16 EXC_SXDB_SAVEDATA = 0x0001;
+const sal_uInt16 EXC_SXDB_INVALID = 0x0002;
+const sal_uInt16 EXC_SXDB_REFRESH_LOAD = 0x0004;
+const sal_uInt16 EXC_SXDB_OPT_CACHE = 0x0008;
+const sal_uInt16 EXC_SXDB_BG_QUERY = 0x0010;
+const sal_uInt16 EXC_SXDB_ENABLE_REFRESH = 0x0020;
+const sal_uInt16 EXC_SXDB_DEFAULTFLAGS = EXC_SXDB_SAVEDATA | EXC_SXDB_ENABLE_REFRESH;
+
+const sal_uInt16 EXC_SXDB_BLOCKRECS = 0x1FFF;
+
+const sal_uInt16 EXC_SXDB_SRC_SHEET = 0x0001;
+const sal_uInt16 EXC_SXDB_SRC_EXTERN = 0x0002;
+const sal_uInt16 EXC_SXDB_SRC_CONSOLID = 0x0004;
+const sal_uInt16 EXC_SXDB_SRC_SCENARIO = 0x0008;
+
+// (0x00C7) SXFIELD -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXFIELD = 0x00C7;
+
+const sal_uInt16 EXC_SXFIELD_HASITEMS = 0x0001;
+const sal_uInt16 EXC_SXFIELD_POSTPONE = 0x0002;
+const sal_uInt16 EXC_SXFIELD_CALCED = 0x0004;
+const sal_uInt16 EXC_SXFIELD_HASCHILD = 0x0008;
+const sal_uInt16 EXC_SXFIELD_NUMGROUP = 0x0010;
+const sal_uInt16 EXC_SXFIELD_16BIT = 0x0200;
+
+const sal_uInt16 EXC_SXFIELD_DATA_MASK = 0x0DE0;
+// known data types
+const sal_uInt16 EXC_SXFIELD_DATA_NONE = 0x0000; /// Special state for groupings.
+const sal_uInt16 EXC_SXFIELD_DATA_STR = 0x0480; /// Only strings, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_INT = 0x0520; /// Only integers, opt. with doubles.
+const sal_uInt16 EXC_SXFIELD_DATA_DBL = 0x0560; /// Only doubles, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_STR_INT = 0x05A0; /// Only strings and integers, opt. with doubles.
+const sal_uInt16 EXC_SXFIELD_DATA_STR_DBL = 0x05E0; /// Only strings and doubles, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_DATE = 0x0900; /// Only dates, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_DATE_EMP = 0x0980; /// Dates and empty strings, nothing else (?).
+const sal_uInt16 EXC_SXFIELD_DATA_DATE_NUM = 0x0D00; /// Dates with integers or doubles without strings.
+const sal_uInt16 EXC_SXFIELD_DATA_DATE_STR = 0x0D80; /// Dates and strings, opt. with integers or doubles.
+
+const sal_uInt16 EXC_SXFIELD_INDEX_MIN = 0; /// List index for minimum item in groupings.
+const sal_uInt16 EXC_SXFIELD_INDEX_MAX = 1; /// List index for maximum item in groupings.
+const sal_uInt16 EXC_SXFIELD_INDEX_STEP = 2; /// List index for step item in groupings.
+
+// (0x00C8) SXINDEXLIST -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXINDEXLIST = 0x00C8;
+
+// (0x00C9) SXDOUBLE ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXDOUBLE = 0x00C9;
+
+// (0x00CA) SXBOOLEAN ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXBOOLEAN = 0x00CA;
+
+// (0x00CB) SXERROR -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXERROR = 0x00CB;
+
+// (0x00CC) SXINTEGER ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXINTEGER = 0x00CC;
+
+// (0x00CD) SXSTRING ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXSTRING = 0x00CD;
+
+// (0x00CE) SXDATETIME --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXDATETIME = 0x00CE;
+
+// (0x00CF) SXEMPTY -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXEMPTY = 0x00CF;
+
+// (0x00D5) SXIDSTM -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXIDSTM = 0x00D5;
+
+// (0x00D8) SXNUMGROUP --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXNUMGROUP = 0x00D8;
+
+const sal_uInt16 EXC_SXNUMGROUP_AUTOMIN = 0x0001;
+const sal_uInt16 EXC_SXNUMGROUP_AUTOMAX = 0x0002;
+
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_SEC = 1;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_MIN = 2;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_HOUR = 3;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_DAY = 4;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_MONTH = 5;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_QUART = 6;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_YEAR = 7;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_NUM = 8;
+
+// (0x00D9) SXGROUPINFO -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXGROUPINFO = 0x00D9;
+
+// (0x00DC) SXEXT -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXEXT = 0x00DC;
+
+// (0x00E3) SXVS --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXVS = 0x00E3;
+
+const sal_uInt16 EXC_SXVS_UNKNOWN = 0x0000;
+const sal_uInt16 EXC_SXVS_SHEET = 0x0001;
+const sal_uInt16 EXC_SXVS_EXTERN = 0x0002;
+const sal_uInt16 EXC_SXVS_CONSOLID = 0x0004;
+const sal_uInt16 EXC_SXVS_PIVOTTAB = 0x0008;
+const sal_uInt16 EXC_SXVS_SCENARIO = 0x0010;
+
+// (0x00F0) SXRULE ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXRULE = 0x00F0;
+
+// (0x00F1) SXEX --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXEX = 0x00F1;
+
+const sal_uInt32 EXC_SXEX_DRILLDOWN = 0x00020000;
+const sal_uInt32 EXC_SXEX_DEFAULTFLAGS = 0x004F0200;
+
+// (0x00F2) SXFILT ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXFILT = 0x00F2;
+
+// (0x00F5) -------------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_00F5 = 0x00F5; /// Unknown record
+
+// (0x00F6) SXNAME ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXNAME = 0x00F6;
+
+// (0x00F8) SXPAIR ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXPAIR = 0x00F8;
+
+// (0x00F9) SXFMLA ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXFMLA = 0x00F9;
+
+// (0x0100) SXVDEX ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXVDEX = 0x0100;
+
+const sal_uInt32 EXC_SXVDEX_SHOWALL = 0x00000001;
+const sal_uInt32 EXC_SXVDEX_SORT = 0x00000200;
+const sal_uInt32 EXC_SXVDEX_SORT_ASC = 0x00000400;
+const sal_uInt32 EXC_SXVDEX_AUTOSHOW = 0x00000800;
+const sal_uInt32 EXC_SXVDEX_AUTOSHOW_ASC = 0x00001000;
+const sal_uInt32 EXC_SXVDEX_LAYOUT_REPORT = 0x00200000;
+const sal_uInt32 EXC_SXVDEX_LAYOUT_BLANK = 0x00400000;
+const sal_uInt32 EXC_SXVDEX_LAYOUT_TOP = 0x00800000;
+const sal_uInt32 EXC_SXVDEX_DEFAULTFLAGS = 0x0A00001E | EXC_SXVDEX_SORT_ASC | EXC_SXVDEX_AUTOSHOW_ASC;
+
+const sal_uInt16 EXC_SXVDEX_SORT_OWN = 0xFFFF;
+const sal_uInt16 EXC_SXVDEX_SHOW_NONE = 0xFFFF;
+const sal_uInt16 EXC_SXVDEX_FORMAT_NONE = 0x0000;
+
+// (0x0103) SXFORMULA ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXFORMULA = 0x0103;
+
+// (0x0122) SXDBEX ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXDBEX = 0x0122;
+const double EXC_SXDBEX_CREATION_DATE = 51901.029652778;
+
+// (0x01BB) SXFDBTYPE ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXFDBTYPE = 0x01BB;
+const sal_uInt16 EXC_SXFDBTYPE_DEFAULT = 0x0000;
+
+// (0x0810) SXVIEWEX9 ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVIEWEX9 = 0x0810;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+/** Represents a data item of any type in a pivot cache. Supposed as base class for import and export. */
+class XclPCItem
+{
+public:
+ explicit XclPCItem();
+ virtual ~XclPCItem();
+
+ /** Sets the item to 'empty' type. */
+ void SetEmpty();
+ /** Sets the item to 'text' type and adds the passed text. */
+ void SetText( const String& rText );
+ /** Sets the item to 'double' type and adds the passed value. */
+ void SetDouble( double fValue );
+ /** Sets the item to 'date/time' type and adds the passed date. */
+ void SetDateTime( const DateTime& rDateTime );
+ /** Sets the item to 'integer' type and adds the passed value. */
+ void SetInteger( sal_Int16 nValue );
+ /** Sets the item to 'error' type and adds the passed Excel error code. */
+ void SetError( sal_uInt16 nError );
+ /** Sets the item to 'boolean' type and adds the passed Boolean value. */
+ void SetBool( bool bValue );
+
+ /** Returns the current item type. */
+ inline XclPCItemType GetType() const { return meType; }
+ /** Returns the text representation of the item. */
+ inline const String& ConvertToText() const { return maText; }
+
+ /** Returns true, if the passed iterm equals this item. */
+ bool IsEqual( const XclPCItem& rItem ) const;
+
+ /** Returns true, if the item type is 'empty'. */
+ bool IsEmpty() const;
+ /** Returns pointer to text, if the item type is 'text', otherwise 0. */
+ const String* GetText() const;
+ /** Returns pointer to value, if the item type is 'double', otherwise 0. */
+ const double* GetDouble() const;
+ /** Returns pointer to date, if the item type is 'date/time', otherwise 0. */
+ const DateTime* GetDateTime() const;
+ /** Returns pointer to integer, if the item type is 'integer', otherwise 0. */
+ const sal_Int16* GetInteger() const;
+ /** Returns pointer to error code, if the item type is 'error', otherwise 0. */
+ const sal_uInt16* GetError() const;
+ /** Returns pointer to Boolean value, if the item type is 'boolean', otherwise 0. */
+ const bool* GetBool() const;
+
+private:
+ XclPCItemType meType; /// Type of the item.
+ String maText; /// Text representation of the item.
+ DateTime maDateTime; /// Value of a date/time item.
+ union
+ {
+ double mfValue; /// Value of a floating-point item.
+ sal_Int16 mnValue; /// Value of an integer item.
+ sal_uInt16 mnError; /// Error code of an error item.
+ bool mbValue; /// Value of a boolean item.
+ };
+};
+
+inline bool operator==( const XclPCItem& rLeft, const XclPCItem& rRight ) { return rLeft.IsEqual( rRight ); }
+inline bool operator!=( const XclPCItem& rLeft, const XclPCItem& rRight ) { return !(rLeft == rRight); }
+
+// Field settings =============================================================
+
+/** Contains data for a pivot cache field (SXFIELD record). */
+struct XclPCFieldInfo
+{
+ String maName; /// Name of the pivot cache field.
+ sal_uInt16 mnFlags; /// Various flags.
+ sal_uInt16 mnGroupChild; /// Field containing grouping info for this field.
+ sal_uInt16 mnGroupBase; /// Base field if this field contains grouping info.
+ sal_uInt16 mnVisItems; /// Number of visible items for this field.
+ sal_uInt16 mnGroupItems; /// Number of special items in a grouping field.
+ sal_uInt16 mnBaseItems; /// Number of items in the base field.
+ sal_uInt16 mnOrigItems; /// Number of original source data items.
+
+ explicit XclPCFieldInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo );
+
+// Numeric grouping field settings ============================================
+
+/** Contains data for a numeric grouping field (SXNUMGROUP record). */
+struct XclPCNumGroupInfo
+{
+ sal_uInt16 mnFlags; /// Various flags.
+
+ explicit XclPCNumGroupInfo();
+
+ void SetNumType();
+
+ sal_Int32 GetScDateType() const;
+ void SetScDateType( sal_Int32 nScType );
+
+ sal_uInt16 GetXclDataType() const;
+ void SetXclDataType( sal_uInt16 nXclType );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo );
+
+// Base class for pivot cache fields ==========================================
+
+/** Represents a field in a pivot cache. Supposed as base class for import and export. */
+class XclPCField
+{
+public:
+ explicit XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx );
+ virtual ~XclPCField();
+
+ /** Returns the index of this field in the containing pivot cache. */
+ inline sal_uInt16 GetFieldIndex() const { return mnFieldIdx; }
+
+ /** Returns true, if the type of the field is supported by Calc. */
+ bool IsSupportedField() const;
+
+ /** Returns true, if this is a standard field build directly from source data. */
+ bool IsStandardField() const;
+
+//UNUSED2008-05 /** Returns true, if the items of the field are calculated from a formula. */
+//UNUSED2008-05 bool IsCalculatedField() const;
+
+ /** Returns true, if this field is a grouping field. */
+ bool IsStdGroupField() const;
+ /** Returns true, if this field is a numeric grouping field. */
+ bool IsNumGroupField() const;
+ /** Returns true, if this field is a date/time grouping field. */
+ bool IsDateGroupField() const;
+ /** Returns true, if this field is a grouping field of any type. */
+ bool IsGroupField() const;
+
+ /** Returns true, if this field has a child field in a grouping. */
+ bool IsGroupBaseField() const;
+ /** Returns true, if this field is a child field in a grouping (it has a base field). */
+ bool IsGroupChildField() const;
+ /** Returns the index of the base field, if exists, otherwise the own index. */
+ sal_uInt16 GetBaseFieldIndex() const;
+
+ /** Returns true, if the field is based on a column in the source data area. */
+ bool HasOrigItems() const;
+ /** Returns true, if any items are stored after the SXFIELD record. */
+ bool HasInlineItems() const;
+ /** Returns true, if the items are stored separately after the last field. */
+ bool HasPostponedItems() const;
+ /** Returns true, if the item indexes in the SXINDEXLIST record are stored as 16-bit values. */
+ bool Has16BitIndexes() const;
+
+protected:
+ XclPCFieldInfo maFieldInfo; /// Pivot cache field info (SXFIELD record).
+ XclPCFieldType meFieldType; /// Type of this pivot cache field.
+ sal_uInt16 mnFieldIdx; /// Own field index in pivot cache.
+ ScfUInt16Vec maGroupOrder; /// Order of items in a grouping field (SXGROUPINFO record).
+ XclPCNumGroupInfo maNumGroupInfo; /// Info for numeric grouping (SXNUMGROUP record).
+};
+
+// Pivot cache settings =======================================================
+
+/** Contains data for a pivot cache (SXDB record). */
+struct XclPCInfo
+{
+ sal_uInt32 mnSrcRecs; /// Records in source database.
+ sal_uInt16 mnStrmId; /// Stream identifier.
+ sal_uInt16 mnFlags; /// Flags for the cache.
+ sal_uInt16 mnBlockRecs; /// Records in a source database block.
+ sal_uInt16 mnStdFields; /// Number of standard pivot cache fields.
+ sal_uInt16 mnTotalFields; /// Number of all fields (standard, grouped, calculated).
+ sal_uInt16 mnSrcType; /// Database type.
+ String maUserName; /// Name of user who last modified the cache.
+
+ explicit XclPCInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo );
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+// cached name ================================================================
+
+/** A name for various pivot table info structs. Includes 'use cache' state. */
+struct XclPTCachedName
+{
+ String maName; /// The visible name, if used.
+ bool mbUseCache; /// true = Use name in cache instead of maName.
+
+ inline explicit XclPTCachedName() : mbUseCache( true ) {}
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName );
+
+// ----------------------------------------------------------------------------
+
+/** Base struct for named info structs. Supports explicit naming and using the cache. */
+struct XclPTVisNameInfo
+{
+ XclPTCachedName maVisName; /// The displayed name of the item.
+
+ /** Returns true, if the name is set explicitly (maVisName.mbUseCache is false). */
+ inline bool HasVisName() const { return !maVisName.mbUseCache; }
+ /** Returns the name, if set explicitly (maVisName.mbUseCache is false). */
+ const String* GetVisName() const;
+ /** Sets the visible name and enables usage of cache if name is empty. */
+ void SetVisName( const String& rName );
+};
+
+// Field item settings ========================================================
+
+/** Contains data for a pivot table data item (SXVI record). */
+struct XclPTItemInfo : public XclPTVisNameInfo
+{
+ sal_uInt16 mnType; /// Type of the item (e.g. data, function, grand total).
+ sal_uInt16 mnFlags; /// Several flags.
+ sal_uInt16 mnCacheIdx; /// Index into cache for item name.
+
+ explicit XclPTItemInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo );
+
+// General field settings =====================================================
+
+typedef ::std::vector< USHORT > XclPTSubtotalVec;
+
+/** Contains data for a pivot table field (SXVD record). */
+struct XclPTFieldInfo : public XclPTVisNameInfo
+{
+ sal_uInt16 mnAxes; /// Flags for axes this field is part of.
+ sal_uInt16 mnSubtCount; /// Number of subtotal functions.
+ sal_uInt16 mnSubtotals; /// Bitfield for subtotal functions.
+ sal_uInt16 mnItemCount; /// Number of items of this field.
+ sal_uInt16 mnCacheIdx; /// Index into cache for field name (not part of record).
+
+ explicit XclPTFieldInfo();
+
+ /** Returns the API enum representing the orientation (first of row/col/page/data).
+ @param nMask Restricts the axes taken into account.
+ @return The first found axis orientation, that is allowed in nMask parameter. */
+ ::com::sun::star::sheet::DataPilotFieldOrientation GetApiOrient( sal_uInt16 nMask ) const;
+ /** Adds the axis orientation represented by the passed API enum. */
+ void AddApiOrient( ::com::sun::star::sheet::DataPilotFieldOrientation eOrient );
+
+ /** Returns a vector of all set subtotal functions. */
+ void GetSubtotals( XclPTSubtotalVec& rSubtotals ) const;
+ /** Sets the subtotal functions contained in the passed sequence. */
+ void SetSubtotals( const XclPTSubtotalVec& rSubtotals );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo );
+
+// Extended field settings ====================================================
+
+/** Contains extended data for a pivot table field (SXVDEX record). */
+struct XclPTFieldExtInfo
+{
+ sal_uInt32 mnFlags; /// Several flags and number of items for AutoShow.
+ sal_uInt16 mnSortField; /// Index to data field sorting bases on.
+ sal_uInt16 mnShowField; /// Index to data field AutoShow bases on.
+ sal_uInt16 mnNumFmt;
+ ::std::auto_ptr<rtl::OUString> mpFieldTotalName;
+
+ explicit XclPTFieldExtInfo();
+
+ /** Returns the API constant representing the sorting mode. */
+ sal_Int32 GetApiSortMode() const;
+ /** Sets the sorting mode represented by the passed API constant. */
+ void SetApiSortMode( sal_Int32 nSortMode );
+
+ /** Returns the API constant representing the AutoShow mode. */
+ sal_Int32 GetApiAutoShowMode() const;
+ /** Sets the AutoShow mode represented by the passed API constant. */
+ void SetApiAutoShowMode( sal_Int32 nShowMode );
+
+ /** Returns the number of items to be shown in AutoShow mode. */
+ sal_Int32 GetApiAutoShowCount() const;
+ /** Sets the number of items to be shown in AutoShow mode. */
+ void SetApiAutoShowCount( sal_Int32 nShowCount );
+
+ /** Returns the API constant representing the layout mode. */
+ sal_Int32 GetApiLayoutMode() const;
+ /** Sets the layout mode represented by the passed API constant. */
+ void SetApiLayoutMode( sal_Int32 nLayoutMode );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo );
+
+// Page field settings ========================================================
+
+/** Contains data for a pivot table page field (part of SXPI record). */
+struct XclPTPageFieldInfo
+{
+ sal_uInt16 mnField; /// Base field for this page info.
+ sal_uInt16 mnSelItem; /// Index to selected item.
+ sal_uInt16 mnObjId; /// Escher object ID of dropdown listbox.
+
+ explicit XclPTPageFieldInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo );
+
+// Data field settings ========================================================
+
+/** Contains data for a pivot table data field (SXDI record). */
+struct XclPTDataFieldInfo : public XclPTVisNameInfo
+{
+ sal_uInt16 mnField; /// Base field for this data info.
+ sal_uInt16 mnAggFunc; /// Data aggregation function.
+ sal_uInt16 mnRefType; /// Result reference type.
+ sal_uInt16 mnRefField; /// Index to SXVD of referred field used for the results.
+ sal_uInt16 mnRefItem; /// Index to SXVI of referred item of the used field.
+ sal_uInt16 mnNumFmt; /// Number format of the results.
+
+ explicit XclPTDataFieldInfo();
+
+ /** Returns the API enum representing the aggregation function. */
+ ::com::sun::star::sheet::GeneralFunction GetApiAggFunc() const;
+ /** Sets the aggregation function represented by the passed API enum. */
+ void SetApiAggFunc( ::com::sun::star::sheet::GeneralFunction eAggFunc );
+
+ /** Returns the API constant representing the result reference type. */
+ sal_Int32 GetApiRefType() const;
+ /** Sets the result reference type represented by the passed API constant. */
+ void SetApiRefType( sal_Int32 nRefType );
+
+ /** Returns the API constant representing the result reference item type. */
+ sal_Int32 GetApiRefItemType() const;
+ /** Sets the result reference item type represented by the passed API constant. */
+ void SetApiRefItemType( sal_Int32 nRefItemType );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo );
+
+// Pivot table settings =======================================================
+
+/** Contains data for a pivot table (SXVIEW record). */
+struct XclPTInfo
+{
+ String maTableName; /// The name of the pivot table.
+ String maDataName; /// The visible name of the data field.
+ XclRange maOutXclRange; /// Output range.
+ XclAddress maDataXclPos; /// First cell containing data.
+ sal_uInt16 mnFirstHeadRow; /// First heading row.
+ sal_uInt16 mnCacheIdx; /// 0-based index of the pivot cache.
+ sal_uInt16 mnDataAxis; /// Orientation of data fields.
+ sal_uInt16 mnDataPos; /// Position of data fields.
+ sal_uInt16 mnFields; /// Number of all fields.
+ sal_uInt16 mnRowFields; /// Number of row fields.
+ sal_uInt16 mnColFields; /// Number of column fields.
+ sal_uInt16 mnPageFields; /// Number of page fields.
+ sal_uInt16 mnDataFields; /// Number of data fields.
+ sal_uInt16 mnDataRows; /// Number of rows containing data.
+ sal_uInt16 mnDataCols; /// Number of columns containing data.
+ sal_uInt16 mnFlags; /// Flags for the entire pivot table.
+ sal_uInt16 mnAutoFmtIdx; /// Index to pivot table autoformat.
+
+ explicit XclPTInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo );
+
+// Extended pivot table settings ==============================================
+
+/** Extended information about a pivot table (SXEX record). */
+struct XclPTExtInfo
+{
+ sal_uInt16 mnSxformulaRecs; /// Number of SXFORMULA records.
+ sal_uInt16 mnSxselectRecs; /// Number of SXSELECT records.
+ sal_uInt16 mnPagePerRow; /// Number of page fields per row.
+ sal_uInt16 mnPagePerCol; /// Number of page fields per column.
+ sal_uInt32 mnFlags; /// Flags for the entire pivot table.
+
+ explicit XclPTExtInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo );
+
+// ============================================================================
+
+// Pivot table autoformat settings ==============================================
+
+/** Pivot table autoformat settings (SXVIEWEX9 record). */
+struct XclPTViewEx9Info
+{
+ sal_uInt32 mbReport; /// 2 for report* fmts ?
+ sal_uInt8 mnAutoFormat; /// AutoFormat ID
+ sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern
+ String maGrandTotalName;
+
+ explicit XclPTViewEx9Info();
+ void Init( const ScDPObject& rDPObj );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo );
+
+// ============================================================================
+#endif
+
diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx
new file mode 100644
index 000000000000..2f029c74baa9
--- /dev/null
+++ b/sc/source/filter/inc/xlroot.hxx
@@ -0,0 +1,289 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLROOT_HXX
+#define SC_XLROOT_HXX
+
+#include <i18npool/lang.h>
+#include <sot/storage.hxx>
+#include "xlconst.hxx"
+#include "xltools.hxx"
+
+namespace comphelper { class IDocPasswordVerifier; }
+
+// Forward declarations of objects in public use ==============================
+
+class DateTime;
+
+struct XclAddress;
+struct XclRange;
+class XclRangeList;
+class XclTokenArray;
+
+// Global data ================================================================
+
+#ifdef DBG_UTIL
+/** Counts the number of created root objects. */
+struct XclDebugObjCounter
+{
+ sal_Int32 mnObjCnt;
+ inline explicit XclDebugObjCounter() : mnObjCnt( 0 ) {}
+ ~XclDebugObjCounter();
+};
+#endif
+
+// ----------------------------------------------------------------------------
+
+class SfxMedium;
+class ScEditEngineDefaulter;
+class ScHeaderEditEngine;
+class EditEngine;
+class ScExtDocOptions;
+class XclFontPropSetHelper;
+class XclChPropSetHelper;
+class XclTracer;
+
+struct RootData;//!
+
+/** Stores global buffers and data needed elsewhere in the Excel filters. */
+struct XclRootData
+#ifdef DBG_UTIL
+ : public XclDebugObjCounter
+#endif
+{
+ typedef ScfRef< ScEditEngineDefaulter > ScEEDefaulterRef;
+ typedef ScfRef< ScHeaderEditEngine > ScHeaderEERef;
+ typedef ScfRef< EditEngine > EditEngineRef;
+ typedef ScfRef< XclFontPropSetHelper > XclFontPropSetHlpRef;
+ typedef ScfRef< XclChPropSetHelper > XclChPropSetHlpRef;
+ typedef ScfRef< ScExtDocOptions > ScExtDocOptRef;
+ typedef ScfRef< XclTracer > XclTracerRef;
+ typedef ScfRef< RootData > RootDataRef;
+
+ XclBiff meBiff; /// Current BIFF version.
+ XclOutput meOutput; /// Current Output format.
+ SfxMedium& mrMedium; /// The medium to import from.
+ SotStorageRef mxRootStrg; /// The root OLE storage of imported/exported file.
+ ScDocument& mrDoc; /// The source or destination document.
+ String maDocUrl; /// Document URL of imported/exported file.
+ String maBasePath; /// Base path of imported/exported file (path of maDocUrl).
+ String maUserName; /// Current user name.
+ const String maDefPassword; /// The default password used for stream encryption.
+ rtl_TextEncoding meTextEnc; /// Text encoding to import/export byte strings.
+ LanguageType meSysLang; /// System language.
+ LanguageType meDocLang; /// Document language (import: from file, export: from system).
+ LanguageType meUILang; /// UI language (import: from file, export: from system).
+ sal_Int16 mnDefApiScript; /// Default script type for blank cells (API constant).
+ ScAddress maScMaxPos; /// Highest Calc cell position.
+ ScAddress maXclMaxPos; /// Highest Excel cell position.
+ ScAddress maMaxPos; /// Highest position valid in Calc and Excel.
+
+ ScEEDefaulterRef mxEditEngine; /// Edit engine for rich strings etc.
+ ScHeaderEERef mxHFEditEngine; /// Edit engine for header/footer.
+ EditEngineRef mxDrawEditEng; /// Edit engine for text boxes.
+
+ XclFontPropSetHlpRef mxFontPropSetHlp; /// Property set helper for fonts.
+ XclChPropSetHlpRef mxChPropSetHlp; /// Property set helper for chart filter.
+
+ ScExtDocOptRef mxExtDocOpt; /// Extended document options.
+ XclTracerRef mxTracer; /// Filter tracer.
+ RootDataRef mxRD; /// Old RootData struct. Will be removed.
+
+ double mfScreenPixelX; /// Width of a screen pixel (1/100 mm).
+ double mfScreenPixelY; /// Height of a screen pixel (1/100 mm).
+ long mnCharWidth; /// Width of '0' in default font (twips).
+ SCTAB mnScTab; /// Current Calc sheet index.
+ const bool mbExport; /// false = Import, true = Export.
+
+ explicit XclRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc,
+ rtl_TextEncoding eTextEnc, bool bExport );
+ virtual ~XclRootData();
+};
+
+// ----------------------------------------------------------------------------
+
+class SfxObjectShell;
+class ScModelObj;
+class OutputDevice;
+class SvNumberFormatter;
+class SdrPage;
+class ScDocumentPool;
+class ScStyleSheetPool;
+class ScRangeName;
+class ScDBCollection;
+struct XclFontData;
+
+/** Access to global data for a filter object (imported or exported document) from other classes. */
+class XclRoot
+{
+public:
+ explicit XclRoot( XclRootData& rRootData );
+ XclRoot( const XclRoot& rRoot );
+
+ virtual ~XclRoot();
+
+ XclRoot& operator=( const XclRoot& rRoot );
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclRoot& GetRoot() const { return *this; }
+ /** Returns old RootData struct. Deprecated. */
+ inline RootData& GetOldRoot() const { return *mrData.mxRD; }
+
+ /** Returns the current BIFF version of the importer/exporter. */
+ inline XclBiff GetBiff() const { return mrData.meBiff; }
+ /** Returns the current output format of the importer/exporter. */
+ inline XclOutput GetOutput() const { return mrData.meOutput; }
+ /** Returns true, if currently a document is imported. */
+ inline bool IsImport() const { return !mrData.mbExport; }
+ /** Returns true, if currently a document is exported. */
+ inline bool IsExport() const { return mrData.mbExport; }
+ /** Returns the text encoding to import/export byte strings. */
+ inline rtl_TextEncoding GetTextEncoding() const { return mrData.meTextEnc; }
+ /** Returns the system language, i.e. for number formats. */
+ inline LanguageType GetSysLanguage() const { return mrData.meSysLang; }
+ /** Returns the document language. */
+ inline LanguageType GetDocLanguage() const { return mrData.meDocLang; }
+ /** Returns the UI language. */
+ inline LanguageType GetUILanguage() const { return mrData.meUILang; }
+ /** Returns the default script type, e.g. for blank cells. */
+ inline sal_Int16 GetDefApiScript() const { return mrData.mnDefApiScript; }
+ /** Returns the width of the '0' character (default font) for the current printer (twips). */
+ inline long GetCharWidth() const { return mrData.mnCharWidth; }
+ /** Returns the current Calc sheet index. */
+ inline bool IsInGlobals() const { return mrData.mnScTab == SCTAB_GLOBAL; }
+ /** Returns the current Calc sheet index. */
+ inline SCTAB GetCurrScTab() const { return mrData.mnScTab; }
+
+ /** Calculates the width of the passed number of pixels in 1/100 mm. */
+ sal_Int32 GetHmmFromPixelX( double fPixelX ) const;
+ /** Calculates the height of the passed number of pixels in 1/100 mm. */
+ sal_Int32 GetHmmFromPixelY( double fPixelY ) const;
+
+ /** Returns the medium to import from. */
+ inline SfxMedium& GetMedium() const { return mrData.mrMedium; }
+ /** Returns the document URL of the imported/exported file. */
+ inline const String& GetDocUrl() const { return mrData.maDocUrl; }
+ /** Returns the base path of the imported/exported file. */
+ inline const String& GetBasePath() const { return mrData.maBasePath; }
+ /** Returns the current user name. */
+ inline const String& GetUserName() const { return mrData.maUserName; }
+
+ /** Returns the default password used for stream encryption. */
+ inline const String& GetDefaultPassword() const { return mrData.maDefPassword; }
+ /** Requests and verifies a password from the medium or the user. */
+ String RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
+
+ /** Returns the OLE2 root storage of the imported/exported file.
+ @return Pointer to root storage or 0, if the file is a simple stream. */
+ inline SotStorageRef GetRootStorage() const { return mrData.mxRootStrg; }
+ /** Returns true, if the document contains a VBA storage. */
+ bool HasVbaStorage() const;
+
+ /** Tries to open a storage as child of the specified storage for reading or writing. */
+ SotStorageRef OpenStorage( SotStorageRef xStrg, const String& rStrgName ) const;
+ /** Tries to open a storage as child of the root storage for reading or writing. */
+ SotStorageRef OpenStorage( const String& rStrgName ) const;
+ /** Tries to open a new stream in the specified storage for reading or writing. */
+ SotStorageStreamRef OpenStream( SotStorageRef xStrg, const String& rStrmName ) const;
+ /** Tries to open a new stream in the root storage for reading or writing. */
+ SotStorageStreamRef OpenStream( const String& rStrmName ) const;
+
+ /** Returns the destination document (import) or source document (export). */
+ inline ScDocument& GetDoc() const { return mrData.mrDoc; }
+ /** Returns pointer to the destination document (import) or source document (export). */
+ inline ScDocument* GetDocPtr() const { return &mrData.mrDoc; }
+ /** Returns the object shell of the Calc document. May be 0 (i.e. import from clipboard). */
+ SfxObjectShell* GetDocShell() const;
+ /** Returns the object model of the Calc document. */
+ ScModelObj* GetDocModelObj() const;
+ /** Returns pointer to the printer of the Calc document. */
+ OutputDevice* GetPrinter() const;
+ /** Returns the style sheet pool of the Calc document. */
+ ScStyleSheetPool& GetStyleSheetPool() const;
+ /** Returns the defined names container of the Calc document. */
+ ScRangeName& GetNamedRanges() const;
+ /** Returns the database ranges container of the Calc document. */
+ ScDBCollection& GetDatabaseRanges() const;
+ /** Returns the drawing layer page of the passed sheet, if present. */
+ SdrPage* GetSdrPage( SCTAB nScTab ) const;
+
+ /** Returns the number formatter of the Calc document. */
+ SvNumberFormatter& GetFormatter() const;
+ /** Returns the null date of the current number formatter. */
+ DateTime GetNullDate() const;
+ /** Converts a date/time value to a floating-point value. */
+ double GetDoubleFromDateTime( const DateTime& rDateTime ) const;
+ /** Converts a floating-point value to a date/time value. */
+ DateTime GetDateTimeFromDouble( double fValue ) const;
+
+ /** Returns the edit engine for import/export of rich strings etc. */
+ ScEditEngineDefaulter& GetEditEngine() const;
+ /** Returns the edit engine for import/export of headers/footers. */
+ ScHeaderEditEngine& GetHFEditEngine() const;
+ /** Returns the edit engine for import/export of drawing text boxes. */
+ EditEngine& GetDrawEditEngine() const;
+
+ /** Returns the property set helper for fonts. */
+ XclFontPropSetHelper& GetFontPropSetHelper() const;
+ /** Returns the property set helper for the chart filters. */
+ XclChPropSetHelper& GetChartPropSetHelper() const;
+
+ /** Returns the extended document options. */
+ ScExtDocOptions& GetExtDocOptions() const;
+ /** Returns the filter tracer. */
+ XclTracer& GetTracer() const;
+
+ /** Returns the highest possible cell address in a Calc document. */
+ inline const ScAddress& GetScMaxPos() const { return mrData.maScMaxPos; }
+ /** Returns the highest possible cell address in an Excel document (using current BIFF version). */
+ inline const ScAddress& GetXclMaxPos() const { return mrData.maXclMaxPos; }
+ /** Returns the highest possible cell address valid in Calc and Excel (using current BIFF version). */
+ inline const ScAddress& GetMaxPos() const { return mrData.maMaxPos; }
+
+ /** Sets the document language. */
+ inline void SetDocLanguage( LanguageType eLang ) { mrData.meDocLang = eLang; }
+ /** Sets the UI language, i.e. if it has been read from a file. */
+ inline void SetUILanguage( LanguageType eLang ) { mrData.meUILang = eLang; }
+ /** Sets the text encoding to import/export byte strings. */
+ void SetTextEncoding( rtl_TextEncoding eTextEnc );
+ /** Sets the width of the '0' character (default font) for the current printer (twips).
+ @param rFontData The font used for the '0' character. */
+ void SetCharWidth( const XclFontData& rFontData );
+ /** Sets the current Calc sheet index. */
+ inline void SetCurrScTab( SCTAB nScTab ) { mrData.mnScTab = nScTab; }
+ /** Increases the current Calc sheet index by 1. */
+ inline void IncCurrScTab() { ++mrData.mnScTab; }
+
+private:
+ mutable XclRootData& mrData; /// Reference to the global data struct.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlstream.hxx b/sc/source/filter/inc/xlstream.hxx
new file mode 100644
index 000000000000..0a9074371c33
--- /dev/null
+++ b/sc/source/filter/inc/xlstream.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLSTREAM_HXX
+#define SC_XLSTREAM_HXX
+
+#include <tools/stream.hxx>
+#include <svx/svxerr.hxx>
+#include "ftools.hxx"
+
+// Constants ==================================================================
+
+const sal_Size EXC_REC_SEEK_TO_BEGIN = 0;
+const sal_Size EXC_REC_SEEK_TO_END = static_cast< sal_Size >( -1 );
+
+const sal_uInt16 EXC_MAXRECSIZE_BIFF5 = 2080;
+const sal_uInt16 EXC_MAXRECSIZE_BIFF8 = 8224;
+
+const ErrCode EXC_ENCR_ERROR_WRONG_PASS = ERRCODE_SVX_WRONGPASS;
+const ErrCode EXC_ENCR_ERROR_UNSUPP_CRYPT = ERRCODE_SVX_READ_FILTER_CRYPT;
+const sal_uInt16 EXC_ENCR_BLOCKSIZE = 1024;
+
+const sal_uInt16 EXC_ID_UNKNOWN = SAL_MAX_UINT16;
+const sal_uInt16 EXC_ID_CONT = 0x003C;
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlstring.hxx b/sc/source/filter/inc/xlstring.hxx
new file mode 100644
index 000000000000..5ee505e25024
--- /dev/null
+++ b/sc/source/filter/inc/xlstring.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLSTRING_HXX
+#define SC_XLSTRING_HXX
+
+#include "ftools.hxx"
+
+// Constants and enumerations =================================================
+
+/** Flags used to specify import/export mode of strings. */
+typedef sal_uInt16 XclStrFlags;
+
+const XclStrFlags EXC_STR_DEFAULT = 0x0000; /// Default string settings.
+const XclStrFlags EXC_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 characters (default: try to compress). BIFF8 only.
+const XclStrFlags EXC_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit).
+const XclStrFlags EXC_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only.
+const XclStrFlags EXC_STR_SEPARATEFORMATS = 0x0008; /// Import: Keep old formats when reading unformatted string (default: clear formats); Export: Write unformatted string.
+const XclStrFlags EXC_STR_NOHEADER = 0x0010; /// Export: Don't write the length and flag fields.
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt16 EXC_STR_MAXLEN_8BIT = 0x00FF;
+const sal_uInt16 EXC_STR_MAXLEN = 0xFFFF;
+
+const sal_uInt8 EXC_STRF_16BIT = 0x01;
+const sal_uInt8 EXC_STRF_FAREAST = 0x04;
+const sal_uInt8 EXC_STRF_RICH = 0x08;
+const sal_uInt8 EXC_STRF_UNKNOWN = 0xF2;
+
+// Fixed-size characters
+const sal_uInt8 EXC_LF_C = '\x0A'; /// LF character (used for line break).
+const sal_uInt16 EXC_LF = EXC_LF_C; /// LF character (unicode).
+const sal_uInt8 EXC_NUL_C = '\x00'; /// NUL chararcter.
+const sal_uInt16 EXC_NUL = EXC_NUL_C; /// NUL chararcter (unicode).
+
+// Rich-string formatting runs ================================================
+
+/** Represents a formatting run for rich-strings.
+
+ An Excel formatting run stores the first formatted character in a
+ rich-string and the index of a font used to format this and the following
+ characters.
+ */
+struct XclFormatRun
+{
+ sal_uInt16 mnChar; /// First character this format applies to.
+ sal_uInt16 mnFontIdx; /// Excel font index for the next characters.
+
+ explicit inline XclFormatRun() : mnChar( 0 ), mnFontIdx( 0 ) {}
+ explicit inline XclFormatRun( sal_uInt16 nChar, sal_uInt16 nFontIdx ) :
+ mnChar( nChar ), mnFontIdx( nFontIdx ) {}
+};
+
+inline bool operator==( const XclFormatRun& rLeft, const XclFormatRun& rRight )
+{
+ return (rLeft.mnChar == rRight.mnChar) && (rLeft.mnFontIdx == rRight.mnFontIdx);
+}
+
+inline bool operator<( const XclFormatRun& rLeft, const XclFormatRun& rRight )
+{
+ return (rLeft.mnChar < rRight.mnChar) || ((rLeft.mnChar == rRight.mnChar) && (rLeft.mnFontIdx < rRight.mnFontIdx));
+}
+
+// ----------------------------------------------------------------------------
+
+/** A vector with all formatting runs for a rich-string. */
+typedef ::std::vector< XclFormatRun > XclFormatRunVec;
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlstyle.hxx b/sc/source/filter/inc/xlstyle.hxx
new file mode 100644
index 000000000000..604b53a1f8ff
--- /dev/null
+++ b/sc/source/filter/inc/xlstyle.hxx
@@ -0,0 +1,619 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLSTYLE_HXX
+#define SC_XLSTYLE_HXX
+
+#include <map>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <tools/color.hxx>
+#include <vcl/vclenum.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/frmdir.hxx>
+#include <svl/zforlist.hxx>
+#include "fapihelper.hxx"
+
+class XclRoot;
+
+// Constants and Enumerations =================================================
+
+// Line styles ----------------------------------------------------------------
+
+const sal_uInt8 EXC_LINE_NONE = 0x00;
+const sal_uInt8 EXC_LINE_THIN = 0x01;
+const sal_uInt8 EXC_LINE_MEDIUM = 0x02;
+const sal_uInt8 EXC_LINE_THICK = 0x05;
+const sal_uInt8 EXC_LINE_DOUBLE = 0x06;
+const sal_uInt8 EXC_LINE_HAIR = 0x07;
+
+// Background patterns --------------------------------------------------------
+
+const sal_uInt8 EXC_PATT_NONE = 0x00;
+const sal_uInt8 EXC_PATT_SOLID = 0x01;
+const sal_uInt8 EXC_PATT_50_PERC = 0x02;
+const sal_uInt8 EXC_PATT_75_PERC = 0x03;
+const sal_uInt8 EXC_PATT_25_PERC = 0x04;
+const sal_uInt8 EXC_PATT_12_5_PERC = 0x11;
+const sal_uInt8 EXC_PATT_6_25_PERC = 0x12;
+
+// (0x001E, 0x041E) FORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_FORMAT = 0x001E;
+const sal_uInt16 EXC_ID4_FORMAT = 0x041E;
+
+const sal_uInt16 EXC_FORMAT_OFFSET5 = 164;
+const sal_uInt16 EXC_FORMAT_OFFSET8 = 164;
+const sal_uInt16 EXC_FORMAT_NOTFOUND = 0xFFFF;
+
+// (0x0031) FONT --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID2_FONT = 0x0031;
+const sal_uInt16 EXC_ID3_FONT = 0x0231;
+
+const sal_uInt16 EXC_FONT_APP = 0; /// Application font index.
+const sal_uInt16 EXC_FONT_NOTFOUND = 0xFFFF;
+
+const size_t EXC_FONT_MAXCOUNT4 = 0x00FF;
+const size_t EXC_FONT_MAXCOUNT5 = 0x00FF;
+const size_t EXC_FONT_MAXCOUNT8 = 0xFFFF;
+
+// families
+const sal_uInt8 EXC_FONTFAM_DONTKNOW = 0x00;
+const sal_uInt8 EXC_FONTFAM_ROMAN = 0x01;
+const sal_uInt8 EXC_FONTFAM_SWISS = 0x02;
+const sal_uInt8 EXC_FONTFAM_SYSTEM = EXC_FONTFAM_SWISS;
+const sal_uInt8 EXC_FONTFAM_MODERN = 0x03;
+const sal_uInt8 EXC_FONTFAM_SCRIPT = 0x04;
+const sal_uInt8 EXC_FONTFAM_DECORATIVE = 0x05;
+
+// charsets
+const sal_uInt8 EXC_FONTCSET_ANSI_LATIN = 0x00;
+
+// attributes
+const sal_uInt16 EXC_FONTATTR_NONE = 0x0000;
+const sal_uInt16 EXC_FONTATTR_BOLD = 0x0001;
+const sal_uInt16 EXC_FONTATTR_ITALIC = 0x0002;
+const sal_uInt16 EXC_FONTATTR_UNDERLINE = 0x0004;
+const sal_uInt16 EXC_FONTATTR_STRIKEOUT = 0x0008;
+const sal_uInt16 EXC_FONTATTR_OUTLINE = 0x0010;
+const sal_uInt16 EXC_FONTATTR_SHADOW = 0x0020;
+
+// weight
+const sal_uInt16 EXC_FONTWGHT_DONTKNOW = 0;
+const sal_uInt16 EXC_FONTWGHT_THIN = 100;
+const sal_uInt16 EXC_FONTWGHT_ULTRALIGHT = 200;
+const sal_uInt16 EXC_FONTWGHT_LIGHT = 300;
+const sal_uInt16 EXC_FONTWGHT_SEMILIGHT = 350;
+const sal_uInt16 EXC_FONTWGHT_NORMAL = 400;
+const sal_uInt16 EXC_FONTWGHT_MEDIUM = 500;
+const sal_uInt16 EXC_FONTWGHT_SEMIBOLD = 600;
+const sal_uInt16 EXC_FONTWGHT_BOLD = 700;
+const sal_uInt16 EXC_FONTWGHT_ULTRABOLD = 800;
+const sal_uInt16 EXC_FONTWGHT_BLACK = 900;
+
+// underline
+const sal_uInt8 EXC_FONTUNDERL_NONE = 0x00;
+const sal_uInt8 EXC_FONTUNDERL_SINGLE = 0x01;
+const sal_uInt8 EXC_FONTUNDERL_DOUBLE = 0x02;
+const sal_uInt8 EXC_FONTUNDERL_SINGLE_ACC = 0x21;
+const sal_uInt8 EXC_FONTUNDERL_DOUBLE_ACC = 0x22;
+
+// escapement
+const sal_uInt16 EXC_FONTESC_NONE = 0x00;
+const sal_uInt16 EXC_FONTESC_SUPER = 0x01;
+const sal_uInt16 EXC_FONTESC_SUB = 0x02;
+
+// (0x0043, 0x0243, 0x0443, 0x00E0) XF ----------------------------------------
+
+const sal_uInt16 EXC_ID2_XF = 0x0043;
+const sal_uInt16 EXC_ID3_XF = 0x0243;
+const sal_uInt16 EXC_ID4_XF = 0x0443;
+const sal_uInt16 EXC_ID5_XF = 0x00E0;
+
+const sal_uInt32 EXC_XF_MAXCOUNT = 4050; /// Maximum number of all XF records.
+const sal_uInt32 EXC_XF_MAXSTYLECOUNT = 1536; /// Arbitrary maximum number of style XFs.
+const sal_uInt16 EXC_XF_DEFAULTSTYLE = 0; /// Excel index to default style XF.
+const sal_uInt16 EXC_XF_DEFAULTCELL = 15; /// Excel index to default cell XF.
+const sal_uInt16 EXC_XF_NOTFOUND = 0xFFFF; /// Special index for "not found" state.
+
+const sal_uInt32 EXC_XFID_NOTFOUND = 0xFFFFFFFF;
+
+const sal_uInt16 EXC_XF_LOCKED = 0x0001;
+const sal_uInt16 EXC_XF_HIDDEN = 0x0002;
+const sal_uInt16 EXC_XF_STYLE = 0x0004;
+const sal_uInt16 EXC_XF_STYLEPARENT = 0x0FFF; /// Syles don't have a parent.
+const sal_uInt16 EXC_XF_LINEBREAK = 0x0008; /// Automatic line break.
+const sal_uInt16 EXC_XF_SHRINK = 0x0010; /// Shrink to fit into cell.
+
+const sal_uInt8 EXC_XF_DIFF_VALFMT = 0x01;
+const sal_uInt8 EXC_XF_DIFF_FONT = 0x02;
+const sal_uInt8 EXC_XF_DIFF_ALIGN = 0x04;
+const sal_uInt8 EXC_XF_DIFF_BORDER = 0x08;
+const sal_uInt8 EXC_XF_DIFF_AREA = 0x10;
+const sal_uInt8 EXC_XF_DIFF_PROT = 0x20;
+
+const sal_uInt8 EXC_XF_HOR_GENERAL = 0x00;
+const sal_uInt8 EXC_XF_HOR_LEFT = 0x01;
+const sal_uInt8 EXC_XF_HOR_CENTER = 0x02;
+const sal_uInt8 EXC_XF_HOR_RIGHT = 0x03;
+const sal_uInt8 EXC_XF_HOR_FILL = 0x04;
+const sal_uInt8 EXC_XF_HOR_JUSTIFY = 0x05;
+const sal_uInt8 EXC_XF_HOR_CENTER_AS = 0x06;
+const sal_uInt8 EXC_XF_HOR_DISTRIB = 0x07;
+
+const sal_uInt8 EXC_XF_VER_TOP = 0x00;
+const sal_uInt8 EXC_XF_VER_CENTER = 0x01;
+const sal_uInt8 EXC_XF_VER_BOTTOM = 0x02;
+const sal_uInt8 EXC_XF_VER_JUSTIFY = 0x03;
+const sal_uInt8 EXC_XF_VER_DISTRIB = 0x04;
+
+const sal_uInt8 EXC_XF_TEXTDIR_CONTEXT = 0x00;
+const sal_uInt8 EXC_XF_TEXTDIR_LTR = 0x01;
+const sal_uInt8 EXC_XF_TEXTDIR_RTL = 0x02;
+
+const sal_uInt8 EXC_XF2_VALFMT_MASK = 0x3F;
+const sal_uInt8 EXC_XF2_LOCKED = 0x40;
+const sal_uInt8 EXC_XF2_HIDDEN = 0x80;
+const sal_uInt8 EXC_XF2_LEFTLINE = 0x08;
+const sal_uInt8 EXC_XF2_RIGHTLINE = 0x10;
+const sal_uInt8 EXC_XF2_TOPLINE = 0x20;
+const sal_uInt8 EXC_XF2_BOTTOMLINE = 0x40;
+const sal_uInt8 EXC_XF2_BACKGROUND = 0x80;
+
+const sal_uInt16 EXC_XF8_SHRINK = 0x0010; /// Shrink to fit into cell.
+const sal_uInt16 EXC_XF8_MERGE = 0x0020;
+
+const sal_uInt32 EXC_XF_DIAGONAL_TL_TO_BR = 0x40000000; /// Top-left to bottom-right.
+const sal_uInt32 EXC_XF_DIAGONAL_BL_TO_TR = 0x80000000; /// Bottom-left to top-right.
+const sal_uInt32 EXC_XF_DIAGONAL_BOTH = 0xC0000000; /// Both.
+
+// (0x0045) EFONT -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EFONT = 0x0045;
+
+// (0x0092) PALETTE -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PALETTE = 0x0092;
+
+const sal_uInt16 EXC_COLOR_BIFF2_BLACK = 0;
+const sal_uInt16 EXC_COLOR_BIFF2_WHITE = 1;
+
+const sal_uInt16 EXC_COLOR_USEROFFSET = 8; /// First user defined color.
+const sal_uInt16 EXC_COLOR_WINDOWTEXT3 = 24; /// System window text color (BIFF3-BIFF4).
+const sal_uInt16 EXC_COLOR_WINDOWBACK3 = 25; /// System window background color (BIFF3-BIFF4).
+const sal_uInt16 EXC_COLOR_WINDOWTEXT = 64; /// System window text color (>=BIFF5).
+const sal_uInt16 EXC_COLOR_WINDOWBACK = 65; /// System window background color (>=BIFF5).
+const sal_uInt16 EXC_COLOR_BUTTONBACK = 67; /// System button background color (face color).
+const sal_uInt16 EXC_COLOR_CHWINDOWTEXT = 77; /// System window text color (BIFF8 charts).
+const sal_uInt16 EXC_COLOR_CHWINDOWBACK = 78; /// System window background color (BIFF8 charts).
+const sal_uInt16 EXC_COLOR_CHBORDERAUTO = 79; /// Automatic frame border for series (BIFF8 charts).
+const sal_uInt16 EXC_COLOR_NOTEBACK = 80; /// Note background color.
+const sal_uInt16 EXC_COLOR_NOTETEXT = 81; /// Note text color.
+const sal_uInt16 EXC_COLOR_FONTAUTO = 0x7FFF; /// Font auto color (system window text color).
+
+// (0x0293) STYLE -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_STYLE = 0x0293;
+
+const sal_uInt16 EXC_STYLE_BUILTIN = 0x8000;
+const sal_uInt16 EXC_STYLE_XFMASK = 0x0FFF;
+
+const sal_uInt8 EXC_STYLE_NORMAL = 0x00; /// "Normal" style.
+const sal_uInt8 EXC_STYLE_ROWLEVEL = 0x01; /// "RowLevel_*" styles.
+const sal_uInt8 EXC_STYLE_COLLEVEL = 0x02; /// "ColLevel_*" styles.
+const sal_uInt8 EXC_STYLE_COMMA = 0x03; /// "Comma" style.
+const sal_uInt8 EXC_STYLE_CURRENCY = 0x04; /// "Currency" style.
+const sal_uInt8 EXC_STYLE_PERCENT = 0x05; /// "Percent" style.
+const sal_uInt8 EXC_STYLE_COMMA_0 = 0x06; /// "Comma [0]" style.
+const sal_uInt8 EXC_STYLE_CURRENCY_0 = 0x07; /// "Currency [0]" style.
+const sal_uInt8 EXC_STYLE_HYPERLINK = 0x08; /// "Hyperlink" style.
+const sal_uInt8 EXC_STYLE_FOLLOWED_HYPERLINK= 0x09; /// "Followed_Hyperlink" style.
+const sal_uInt8 EXC_STYLE_USERDEF = 0xFF; /// No built-in style.
+
+const sal_uInt8 EXC_STYLE_LEVELCOUNT = 7; /// Number of outline level styles.
+const sal_uInt8 EXC_STYLE_NOLEVEL = 0xFF; /// Default value for unused level.
+
+// (0x0892) STYLEEXT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_STYLEEXT = 0x0892;
+
+const sal_uInt8 EXC_STYLEEXT_BUILTIN = 0x01;
+const sal_uInt8 EXC_STYLEEXT_HIDDEN = 0x02;
+const sal_uInt8 EXC_STYLEEXT_CUSTOM = 0x04;
+
+// Structs and classes ========================================================
+
+// Color data =================================================================
+
+/** Stores all default colors for a specific BIFF version. */
+class XclDefaultPalette
+{
+public:
+ explicit XclDefaultPalette( const XclRoot& rRoot );
+
+ /** Returns the color count in the current palette. */
+ inline sal_uInt32 GetColorCount() const { return mnTableSize - EXC_COLOR_USEROFFSET; }
+
+ /** Returns the default RGB color data for a (non-zero-based) Excel color or COL_AUTO on error. */
+ ColorData GetDefColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the default color for a (non-zero-based) Excel color or COL_AUTO on error. */
+ inline Color GetDefColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetDefColorData( nXclIndex ) ); }
+
+ /** Returns true, if the passed Excel color index is a system color. */
+ inline bool IsSystemColor( sal_uInt16 nXclIndex ) const { return nXclIndex >= mnTableSize; }
+
+private:
+ const ColorData* mpnColorTable; /// The table with RGB values.
+ ColorData mnWindowText; /// System window text color.
+ ColorData mnWindowBack; /// System window background color.
+ ColorData mnFaceColor; /// System button background color.
+ ColorData mnNoteText; /// Note text color.
+ ColorData mnNoteBack; /// Note background color.
+ sal_uInt32 mnTableSize; /// The color table size.
+};
+
+// Font data ==================================================================
+
+class Font;
+class SvxFont;
+
+/** This struct helps reading and writing Excel fonts.
+
+ It stores all Excel compatible properties of a font. In detail this is the
+ name, family, character set, height, color, boldness, posture, script,
+ underline, strikeout, outline and shadow of the font.
+ */
+struct XclFontData
+{
+ String maName; /// Font name.
+ String maStyle; /// String with styles (bold, italic).
+ Color maColor; /// Font color.
+ sal_uInt16 mnHeight; /// Font height in twips (1/20 of a point).
+ sal_uInt16 mnWeight; /// Boldness: 400=normal, 700=bold.
+ sal_uInt16 mnEscapem; /// Escapement type.
+ sal_uInt8 mnFamily; /// Windows font family.
+ sal_uInt8 mnCharSet; /// Windows character set.
+ sal_uInt8 mnUnderline; /// Underline style.
+ bool mbItalic; /// true = Italic.
+ bool mbStrikeout; /// true = Struck out.
+ bool mbOutline; /// true = Outlined.
+ bool mbShadow; /// true = Shadowed.
+
+ /** Constructs an empty font data structure. */
+ explicit XclFontData();
+ /** Constructs a font data structure and fills it with the passed font attributes (except color). */
+ explicit XclFontData( const Font& rFont );
+ /** As directly above but also fills in the escapement member. */
+ explicit XclFontData( const SvxFont& rFont );
+
+ /** Resets all members to default (empty) values. */
+ void Clear();
+ /** Fills all members (except color and escapement) from the passed font. */
+ void FillFromVclFont( const Font& rFont );
+ /** Fills all members (except color) from the passed SVX font. */
+ void FillFromSvxFont( const SvxFont& rFont );
+
+// *** conversion of VCL/SVX constants *** ------------------------------------
+
+ /** Returns the Calc font family. */
+ FontFamily GetScFamily( rtl_TextEncoding eDefTextEnc ) const;
+ /** Returns the font text encoding. */
+ rtl_TextEncoding GetFontEncoding() const;
+ /** Returns the Calc font posture. */
+ FontItalic GetScPosture() const;
+ /** Returns the Calc font weight. */
+ FontWeight GetScWeight() const;
+ /** Returns the Calc font underline style. */
+ FontUnderline GetScUnderline() const;
+ /** Returns the Calc escapement style. */
+ SvxEscapement GetScEscapement() const;
+ /** Returns the Calc strike-out style. */
+ FontStrikeout GetScStrikeout() const;
+
+ /** Sets the Calc font height (in twips). */
+ void SetScHeight( sal_Int32 nTwips );
+ /** Sets the Calc font family. */
+ void SetScFamily( FontFamily eScFamily );
+ /** Sets the font text encoding. */
+ void SetFontEncoding( rtl_TextEncoding eFontEnc );
+ /** Sets the Calc font posture. */
+ void SetScPosture( FontItalic eScPosture );
+ /** Sets the Calc font weight. */
+ void SetScWeight( FontWeight eScWeight );
+ /** Sets the Calc underline style. */
+ void SetScUnderline( FontUnderline eScUnderl );
+ /** Sets the Calc escapement style. */
+ void SetScEscapement( short nScEscapem );
+ /** Sets the Calc strike-out style. */
+ void SetScStrikeout( FontStrikeout eScStrikeout );
+
+// *** conversion of API constants *** ----------------------------------------
+
+ /** Returns the API font height. */
+ float GetApiHeight() const;
+ /** Returns the API font family. */
+ sal_Int16 GetApiFamily() const;
+ /** Returns the API font text encoding. */
+ sal_Int16 GetApiFontEncoding() const;
+ /** Returns the API font posture. */
+ ::com::sun::star::awt::FontSlant GetApiPosture() const;
+ /** Returns the API font weight. */
+ float GetApiWeight() const;
+ /** Returns the API font underline style. */
+ sal_Int16 GetApiUnderline() const;
+ /** Returns the API escapement style. */
+ sal_Int16 GetApiEscapement() const;
+ /** Returns the API font strike-out style. */
+ sal_Int16 GetApiStrikeout() const;
+
+ /** Sets the API font height. */
+ void SetApiHeight( float fPoint );
+ /** Sets the API font family. */
+ void SetApiFamily( sal_Int16 nApiFamily );
+//UNUSED2009-05 /** Sets the API font text encoding. */
+//UNUSED2009-05 void SetApiFontEncoding( sal_Int16 nApiFontEnc );
+ /** Sets the API font posture. */
+ void SetApiPosture( ::com::sun::star::awt::FontSlant eApiPosture );
+ /** Sets the API font weight. */
+ void SetApiWeight( float fApiWeight );
+ /** Sets the API font underline style. */
+ void SetApiUnderline( sal_Int16 nApiUnderl );
+ /** Sets the API escapement style. */
+ void SetApiEscapement( sal_Int16 nApiEscapem );
+ /** Sets the API font strike-out style. */
+ void SetApiStrikeout( sal_Int16 nApiStrikeout );
+};
+
+bool operator==( const XclFontData& rLeft, const XclFontData& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates different types of Which-IDs for font items. */
+enum XclFontItemType
+{
+ EXC_FONTITEM_CELL, /// Use Calc Which-IDs (ATTR_*).
+ EXC_FONTITEM_EDITENG, /// Use edit engine Which-IDs (EE_CHAR_*).
+ EXC_FONTITEM_HF, /// Use header/footer edit engine Which-IDs (EE_CHAR_*).
+ EXC_FONTITEM_NOTE /// Use note edit engine Which-IDs (EE_CHAR_*), special font handling.
+};
+
+/** Enumerates different types for objects with font settings (using different property names). */
+enum XclFontPropSetType
+{
+ EXC_FONTPROPSET_CHART, /// All text objects in charts.
+ EXC_FONTPROPSET_CONTROL /// Text formatting in form controls.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Helper class for usage of property sets. */
+class XclFontPropSetHelper
+{
+public:
+ explicit XclFontPropSetHelper();
+
+ /** Reads all font properties from the passed property set. */
+ void ReadFontProperties( XclFontData& rFontData,
+ const ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ sal_Int16 nScript = -1 );
+
+ /** Writes all font properties to the passed property set, uses passed color as font color. */
+ void WriteFontProperties(
+ ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ const XclFontData& rFontData,
+ bool bHasWstrn, bool bHasAsian, bool bHasCmplx,
+ const Color* pFontColor = 0 );
+
+private:
+ /** Returns a chart property set helper according to the passed script type. */
+ ScfPropSetHelper& GetChartHelper( sal_Int16 nScript );
+
+private:
+ ScfPropSetHelper maHlpChCommon; /// Chart properties for all scripts.
+ ScfPropSetHelper maHlpChWstrn; /// Chart properties for Western script.
+ ScfPropSetHelper maHlpChAsian; /// Chart properties for Asian script.
+ ScfPropSetHelper maHlpChCmplx; /// Chart properties for Complex script.
+ ScfPropSetHelper maHlpChWstrnNoName; /// Chart properties for Western script, no font name.
+ ScfPropSetHelper maHlpChAsianNoName; /// Chart properties for Asian script, no font name.
+ ScfPropSetHelper maHlpChCmplxNoName; /// Chart properties for Complex script, no font name.
+ ScfPropSetHelper maHlpChEscapement; /// Chart properties for font escapement.
+ ScfPropSetHelper maHlpControl; /// Properties for form controls.
+};
+
+// Number formats =============================================================
+
+struct XclNumFmt
+{
+ String maFormat; /// Format string, may be empty (meOffset used then).
+ NfIndexTableOffset meOffset; /// SvNumberFormatter format index, if maFormat is empty.
+ LanguageType meLanguage; /// Language type to be set with the number format.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclNumFmtBuffer
+{
+public:
+ explicit XclNumFmtBuffer( const XclRoot& rRoot );
+
+ /** Returns the core index of the current standard number format. */
+ inline ULONG GetStdScNumFmt() const { return mnStdScNumFmt; }
+
+protected:
+ typedef ::std::map< sal_uInt16, XclNumFmt > XclNumFmtMap;
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void InitializeImport();
+
+ /** Returns the current number format map. */
+ inline const XclNumFmtMap& GetFormatMap() const { return maFmtMap; }
+
+//UNUSED2008-05 /** Returns the number format with the specified Excel format index. */
+//UNUSED2008-05 const XclNumFmt* GetFormat( sal_uInt16 nXclNumFmt ) const;
+
+ /** Inserts a new number format for the specified Excel format index. */
+ void InsertFormat( sal_uInt16 nXclNumFmt, const String& rFormat );
+
+private:
+ /** Inserts built-in number formats for the current system language. */
+ void InsertBuiltinFormats();
+
+ XclNumFmtMap maFmtMap; /// Map containing all default and user-defined formats.
+ LanguageType meSysLang; /// Current system language.
+ ULONG mnStdScNumFmt; /// Calc format key for standard number format.
+};
+
+// Cell formatting data (XF) ==================================================
+
+/** Contains all cell protection attributes. */
+struct XclCellProt
+{
+ bool mbLocked; /// true = Locked against editing.
+ bool mbHidden; /// true = Formula is hidden.
+
+ explicit XclCellProt();
+};
+
+bool operator==( const XclCellProt& rLeft, const XclCellProt& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains all cell alignment attributes. */
+struct XclCellAlign
+{
+ sal_uInt8 mnHorAlign; /// Horizontal alignment.
+ sal_uInt8 mnVerAlign; /// Vertical alignment.
+ sal_uInt8 mnOrient; /// Text orientation.
+ sal_uInt8 mnTextDir; /// CTL text direction.
+ sal_uInt8 mnRotation; /// Text rotation angle.
+ sal_uInt8 mnIndent; /// Indentation.
+ bool mbLineBreak; /// true = Multi-line text.
+ bool mbShrink; /// true = Shrink to fit cell size.
+
+ explicit XclCellAlign();
+
+ /** Returns the Calc horizontal alignment. */
+ SvxCellHorJustify GetScHorAlign() const;
+ /** Returns the Calc vertical alignment. */
+ SvxCellVerJustify GetScVerAlign() const;
+ /** Returns the Calc frame direction. */
+ SvxFrameDirection GetScFrameDir() const;
+
+ /** Sets the Calc horizontal alignment. */
+ void SetScHorAlign( SvxCellHorJustify eHorJust );
+ /** Sets the Calc vertical alignment. */
+ void SetScVerAlign( SvxCellVerJustify eVerJust );
+ /** Sets the Calc frame direction. */
+ void SetScFrameDir( SvxFrameDirection eFrameDir );
+};
+
+bool operator==( const XclCellAlign& rLeft, const XclCellAlign& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains color and line style for each cell border line. */
+struct XclCellBorder
+{
+ sal_uInt16 mnLeftColor; /// Palette index for left line.
+ sal_uInt16 mnRightColor; /// Palette index for right line.
+ sal_uInt16 mnTopColor; /// Palette index for top line.
+ sal_uInt16 mnBottomColor; /// Palette index for bottom line.
+ sal_uInt16 mnDiagColor; /// Palette index for diagonal line(s).
+ sal_uInt8 mnLeftLine; /// Style of left line.
+ sal_uInt8 mnRightLine; /// Style of right line.
+ sal_uInt8 mnTopLine; /// Style of top line.
+ sal_uInt8 mnBottomLine; /// Style of bottom line.
+ sal_uInt8 mnDiagLine; /// Style of diagonal line(s).
+ bool mbDiagTLtoBR; /// true = Top-left to bottom-right on.
+ bool mbDiagBLtoTR; /// true = Bottom-left to top-right on.
+
+ explicit XclCellBorder();
+};
+
+bool operator==( const XclCellBorder& rLeft, const XclCellBorder& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains background colors and pattern for a cell. */
+struct XclCellArea
+{
+ sal_uInt16 mnForeColor; /// Palette index to foreground color.
+ sal_uInt16 mnBackColor; /// Palette index to background color.
+ sal_uInt8 mnPattern; /// Fill pattern.
+
+ explicit XclCellArea();
+
+ /** Returns true, if the area represents transparent state. */
+ bool IsTransparent() const;
+};
+
+bool operator==( const XclCellArea& rLeft, const XclCellArea& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains base members for XF record import/export.
+ @descr In detail this class stores the XF type (cell/style), the index to the
+ parent style XF and all "attribute used" flags, which reflect the state of
+ specific attribute groups (true = user has changed the attributes). */
+class XclXFBase
+{
+public:
+ explicit XclXFBase( bool bCellXF );
+ virtual ~XclXFBase();
+
+ /** Sets all "attribute used" flags to the passed state. */
+ void SetAllUsedFlags( bool bUsed );
+ /** Returns true, if any "attribute used" flags are ste in this XF. */
+ bool HasUsedFlags() const;
+
+ /** Returns true, if this is a hard cell format. */
+ inline bool IsCellXF() const { return mbCellXF; }
+ /** Returns true, if this is a cell style. */
+ inline bool IsStyleXF() const { return !IsCellXF(); }
+
+protected:
+ /** Returns true, if this object is equal to the passed. */
+ bool Equals( const XclXFBase& rCmp ) const;
+
+protected:
+ sal_uInt16 mnParent; /// Index to parent style XF.
+ bool mbCellXF; /// true = cell XF, false = style XF.
+ bool mbProtUsed; /// true = cell protection used.
+ bool mbFontUsed; /// true = font index used.
+ bool mbFmtUsed; /// true = number format used.
+ bool mbAlignUsed; /// true = alignment used.
+ bool mbBorderUsed; /// true = border data used.
+ bool mbAreaUsed; /// true = area data used.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xltable.hxx b/sc/source/filter/inc/xltable.hxx
new file mode 100644
index 000000000000..6b8f650568a9
--- /dev/null
+++ b/sc/source/filter/inc/xltable.hxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLTABLE_HXX
+#define SC_XLTABLE_HXX
+
+#include <sal/types.h>
+
+// Constants and Enumerations =================================================
+
+// Specials for outlines ------------------------------------------------------
+
+const sal_uInt8 EXC_OUTLINE_MAX = 7;
+const sal_uInt8 EXC_OUTLINE_COUNT = EXC_OUTLINE_MAX + 1;
+
+// (0x0000, 0x0200) DIMENSIONS ------------------------------------------------
+
+const sal_uInt16 EXC_ID2_DIMENSIONS = 0x0000;
+const sal_uInt16 EXC_ID3_DIMENSIONS = 0x0200;
+
+// (0x0001, 0x0201) BLANK -----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_BLANK = 0x0001;
+const sal_uInt16 EXC_ID3_BLANK = 0x0201;
+
+// (0x0002) INTEGER -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID2_INTEGER = 0x0002;
+
+// (0x0003, 0x0203) NUMBER ----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_NUMBER = 0x0003;
+const sal_uInt16 EXC_ID3_NUMBER = 0x0203;
+
+// (0x0004, 0x0204) LABEL -----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_LABEL = 0x0004;
+const sal_uInt16 EXC_ID3_LABEL = 0x0204;
+
+const sal_uInt8 EXC_LABEL_MAXLEN = 0xFF;
+
+// (0x0005, 0x0205) BOOLERR ---------------------------------------------------
+
+const sal_uInt16 EXC_ID2_BOOLERR = 0x0005;
+const sal_uInt16 EXC_ID3_BOOLERR = 0x0205;
+
+const sal_uInt8 EXC_BOOLERR_BOOL = 0x00;
+const sal_uInt8 EXC_BOOLERR_ERROR = 0x01;
+
+// (0x0006, 0x0206, 0x0406) FORMULA -------------------------------------------
+
+const sal_uInt16 EXC_ID2_FORMULA = 0x0006;
+const sal_uInt16 EXC_ID3_FORMULA = 0x0206;
+const sal_uInt16 EXC_ID4_FORMULA = 0x0406;
+
+const sal_uInt16 EXC_FORMULA_RECALC_ALWAYS = 0x0001;
+const sal_uInt16 EXC_FORMULA_RECALC_ONLOAD = 0x0002;
+const sal_uInt16 EXC_FORMULA_SHARED = 0x0008;
+const sal_uInt16 EXC_FORMULA_DEFAULTFLAGS = EXC_FORMULA_RECALC_ONLOAD;
+
+const sal_uInt8 EXC_FORMULA_RES_STRING = 0x00; /// Result is a string.
+const sal_uInt8 EXC_FORMULA_RES_BOOL = 0x01; /// Result is Boolean value.
+const sal_uInt8 EXC_FORMULA_RES_ERROR = 0x02; /// Result is error code.
+const sal_uInt8 EXC_FORMULA_RES_EMPTY = 0x03; /// Result is empty cell (BIFF8 only).
+
+// (0x0007, 0x0207) STRING ----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_STRING = 0x0007;
+const sal_uInt16 EXC_ID3_STRING = 0x0207;
+
+// (0x0008, 0x0208) ROW -------------------------------------------------------
+
+const sal_uInt16 EXC_ID2_ROW = 0x0008;
+const sal_uInt16 EXC_ID3_ROW = 0x0208;
+
+const sal_uInt16 EXC_ROW_COLLAPSED = 0x0010;
+const sal_uInt16 EXC_ROW_HIDDEN = 0x0020;
+const sal_uInt16 EXC_ROW_UNSYNCED = 0x0040;
+const sal_uInt16 EXC_ROW_USEDEFXF = 0x0080;
+const sal_uInt16 EXC_ROW_DEFAULTFLAGS = 0x0100;
+
+const sal_uInt16 EXC_ROW_XFMASK = 0x0FFF;
+
+const sal_uInt16 EXC_ROW_DEFAULTHEIGHT = 255;
+const sal_uInt16 EXC_ROW_FLAGDEFHEIGHT = 0x8000;
+const sal_uInt16 EXC_ROW_HEIGHTMASK = 0x7FFF;
+
+const sal_uInt16 EXC_ROW_ROWBLOCKSIZE = 32; /// Number of rows in a row block.
+
+// (0x0020) COLUMNDEFAULT -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_COLUMNDEFAULT = 0x0020;
+
+// (0x0021, 0x0221) ARRAY -----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_ARRAY = 0x0021;
+const sal_uInt16 EXC_ID3_ARRAY = 0x0221;
+
+const sal_uInt16 EXC_ARRAY_RECALC_ALWAYS = 0x0001;
+const sal_uInt16 EXC_ARRAY_RECALC_ONLOAD = 0x0002;
+const sal_uInt16 EXC_ARRAY_DEFAULTFLAGS = EXC_ARRAY_RECALC_ONLOAD;
+
+// (0x0024) COLWIDTH ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_COLWIDTH = 0x0024;
+
+// (0x0025, 0x0225) DEFAULTROWHEIGHT ------------------------------------------
+
+const sal_uInt16 EXC_ID2_DEFROWHEIGHT = 0x0025;
+const sal_uInt16 EXC_ID3_DEFROWHEIGHT = 0x0225;
+
+const sal_uInt16 EXC_DEFROW_UNSYNCED = 0x0001;
+const sal_uInt16 EXC_DEFROW_HIDDEN = 0x0002;
+const sal_uInt16 EXC_DEFROW_SPACEABOVE = 0x0004;
+const sal_uInt16 EXC_DEFROW_SPACEBELOW = 0x0008;
+const sal_uInt16 EXC_DEFROW_DEFAULTFLAGS = 0x0000;
+
+const sal_uInt16 EXC_DEFROW_DEFAULTHEIGHT = 255;
+
+// (0x0036, 0x0236) TABLEOP ---------------------------------------------------
+
+const sal_uInt16 EXC_ID2_TABLEOP = 0x0036;
+const sal_uInt16 EXC_ID3_TABLEOP = 0x0236;
+
+const sal_uInt16 EXC_TABLEOP_RECALC_ALWAYS = 0x0001;
+const sal_uInt16 EXC_TABLEOP_RECALC_ONLOAD = 0x0002;
+const sal_uInt16 EXC_TABLEOP_ROW = 0x0004;
+const sal_uInt16 EXC_TABLEOP_BOTH = 0x0008;
+const sal_uInt16 EXC_TABLEOP_DEFAULTFLAGS = EXC_TABLEOP_RECALC_ONLOAD;
+
+// (0x0037) TABLEOP2 ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID2_TABLEOP2 = 0x0037;
+
+// (0x0055) DEFCOLWIDTH -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_DEFCOLWIDTH = 0x0055;
+const sal_uInt16 EXC_DEFCOLWIDTH_DEF = 10;
+
+// (0x007D) COLINFO -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_COLINFO = 0x007D;
+
+const sal_uInt16 EXC_COLINFO_HIDDEN = 0x0001;
+const sal_uInt16 EXC_COLINFO_COLLAPSED = 0x1000;
+
+// (0x0080) GUTS --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_GUTS = 0x0080;
+
+// (0x00BD) MULRK -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_MULRK = 0x00BD;
+
+// (0x00BE) MULBLANK ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_MULBLANK = 0x00BE;
+
+// (0x00D6) RSTRING -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_RSTRING = 0x00D6;
+
+// (0x00FD) LABELSST ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_LABELSST = 0x00FD;
+
+// (0x027E) RK ----------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_RK = 0x027E;
+
+// (0x04BC) SHRFMLA -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SHRFMLA = 0x04BC;
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx
new file mode 100644
index 000000000000..efe20a583104
--- /dev/null
+++ b/sc/source/filter/inc/xltools.hxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLTOOLS_HXX
+#define SC_XLTOOLS_HXX
+
+#include "address.hxx"
+#include "ftools.hxx"
+
+class SfxObjectShell;
+
+// BIFF versions ==============================================================
+
+#define DBG_ERROR_BIFF() DBG_ERRORFILE( "Unknown BIFF type!" )
+#define DBG_ASSERT_BIFF( c ) DBG_ASSERT( c, "Unknown BIFF type!" )
+
+// Enumerations ===============================================================
+
+/** An enumeration for all Excel error codes and the values true and false. */
+enum XclBoolError
+{
+ xlErrNull, /// The error code #NULL!
+ xlErrDiv0, /// The error code #DIV/0!
+ xlErrValue, /// The error code #VALUE!
+ xlErrRef, /// The error code #REF!
+ xlErrName, /// The error code #NAME?
+ xlErrNum, /// The error code #NUM!
+ xlErrNA, /// The error code #N/A!
+ xlErrTrue, /// The Boolean value true.
+ xlErrFalse, /// The Boolean value false.
+ xlErrUnknown /// For unknown codes and values.
+};
+
+// GUID import/export =========================================================
+
+class XclImpStream;
+class XclExpStream;
+
+/** This struct stores a GUID (class ID) and supports reading, writing and comparison. */
+struct XclGuid
+{
+ sal_uInt8 mpnData[ 16 ]; /// Stores GUID always in little endian.
+
+ explicit XclGuid();
+ explicit XclGuid(
+ sal_uInt32 nData1,
+ sal_uInt16 nData2, sal_uInt16 nData3,
+ sal_uInt8 nData41, sal_uInt8 nData42,
+ sal_uInt8 nData43, sal_uInt8 nData44,
+ sal_uInt8 nData45, sal_uInt8 nData46,
+ sal_uInt8 nData47, sal_uInt8 nData48 );
+};
+
+bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 );
+inline bool operator!=( const XclGuid& rCmp1, const XclGuid& rCmp2 ) { return !(rCmp1 == rCmp2); }
+bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 );
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclGuid& rGuid );
+
+// Excel Tools ================================================================
+
+class SvStream;
+class ScDocument;
+
+/** This class contains static helper methods for the Excel import and export filters. */
+class XclTools : ScfNoInstance
+{
+public:
+ // GUID's -----------------------------------------------------------------
+
+ static const XclGuid maGuidStdLink; /// GUID of StdLink (HLINK record).
+ static const XclGuid maGuidUrlMoniker; /// GUID of URL moniker (HLINK record).
+ static const XclGuid maGuidFileMoniker; /// GUID of file moniker (HLINK record).
+
+ // numeric conversion -----------------------------------------------------
+
+ /** Calculates the double value from an RK value (encoded integer or double). */
+ static double GetDoubleFromRK( sal_Int32 nRKValue );
+ /** Calculates an RK value (encoded integer or double) from a double value.
+ @param rnRKValue Returns the calculated RK value.
+ @param fValue The double value.
+ @return true = An RK value could be created. */
+ static bool GetRKFromDouble( sal_Int32& rnRKValue, double fValue );
+
+ /** Calculates an angle (in 1/100 of degrees) from an Excel angle value.
+ @param nRotForStacked This value will be returned, if nXclRot contains 'stacked'. */
+ static sal_Int32 GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked );
+ /** Calculates the Excel angle value from an angle in 1/100 of degrees. */
+ static sal_uInt8 GetXclRotation( sal_Int32 nScRot );
+
+ /** Calculates BIFF8 rotation angle from BIFF2-BIFF5 text orientation. */
+ static sal_uInt8 GetXclRotFromOrient( sal_uInt8 nXclOrient );
+ /** Calculates BIFF2-BIFF5 text orientation from BIFF8 rotation angle. */
+ static sal_uInt8 GetXclOrientFromRot( sal_uInt16 nXclRot );
+
+ /** Converts a Calc error code to an Excel error code. */
+ static sal_uInt8 GetXclErrorCode( USHORT nScError );
+ /** Converts an Excel error code to a Calc error code. */
+ static USHORT GetScErrorCode( sal_uInt8 nXclError );
+
+ /** Converts the passed BIFF error to a double containing the respective Calc error code. */
+ static double ErrorToDouble( sal_uInt8 nXclError );
+ /** Gets a translated error code or Boolean value from Excel error codes.
+ @param rfDblValue Returns 0.0 for error codes or the value of a Boolean (0.0 or 1.0).
+ @param bErrorOrBool false = nError is a Boolean value; true = is an error value.
+ @param nValue The error code or Boolean value. */
+ static XclBoolError ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue );
+
+ /** Returns the length in twips calculated from a length in inches. */
+ static sal_uInt16 GetTwipsFromInch( double fInches );
+ /** Returns the length in twips calculated from a length in 1/100 mm. */
+ static sal_uInt16 GetTwipsFromHmm( sal_Int32 nHmm );
+
+ /** Returns the length in inches calculated from a length in twips. */
+ static double GetInchFromTwips( sal_Int32 nTwips );
+ /** Returns the length in inches calculated from a length in 1/100 mm. */
+ static double GetInchFromHmm( sal_Int32 nHmm );
+
+ /** Returns the length in 1/100 mm calculated from a length in inches. */
+ static sal_Int32 GetHmmFromInch( double fInches );
+ /** Returns the length in 1/100 mm calculated from a length in twips. */
+ static sal_Int32 GetHmmFromTwips( sal_Int32 nTwips );
+
+ /** Returns the Calc column width (twips) for the passed Excel width.
+ @param nScCharWidth Width of the '0' character in Calc (twips). */
+ static USHORT GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth );
+ /** Returns the Excel column width for the passed Calc width (twips).
+ @param nScCharWidth Width of the '0' character in Calc (twips). */
+ static sal_uInt16 GetXclColumnWidth( USHORT nScWidth, long nScCharWidth );
+
+ /** Returns a correction value to convert column widths from/to default column widths.
+ @param nXclDefFontHeight Excel height of application default font. */
+ static double GetXclDefColWidthCorrection( long nXclDefFontHeight );
+
+ // formatting -------------------------------------------------------------
+
+ /** Returns the best fitting color for an Excel pattern area format. */
+ static Color GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt16 nXclPattern );
+
+ // text encoding ----------------------------------------------------------
+
+ /** Returns a text encoding from an Excel code page.
+ @return The corresponding text encoding or RTL_TEXTENCODING_DONTKNOW. */
+ static rtl_TextEncoding GetTextEncoding( sal_uInt16 nCodePage );
+
+ /** Returns an Excel code page from a text encoding. */
+ static sal_uInt16 GetXclCodePage( rtl_TextEncoding eTextEnc );
+
+ // font names -------------------------------------------------------------
+
+ /** Returns the matching Excel font name for a passed Calc font name. */
+ static String GetXclFontName( const String& rFontName );
+
+ // built-in defined names -------------------------------------------------
+
+ /** Returns the raw English UI representation of a built-in defined name used in NAME records.
+ @param cBuiltIn Excel index of the built-in name. */
+ static String GetXclBuiltInDefName( sal_Unicode cBuiltIn );
+ /** Returns the Calc UI representation of a built-in defined name used in NAME records.
+ @descr Adds a prefix to the representation returned by GetXclBuiltInDefName().
+ @param cBuiltIn Excel index of the built-in name. */
+ static String GetBuiltInDefName( sal_Unicode cBuiltIn );
+ /** Returns the Excel built-in name index of the passed defined name from Calc.
+ @descr Ignores any characters following a valid representation of a built-in name.
+ @param pcBuiltIn (out-param) If not 0, the index of the built-in name will be returned here.
+ @return true = passed string is a built-in name; false = user-defined name. */
+ static sal_Unicode GetBuiltInDefNameIndex( const String& rDefName );
+
+ // built-in style names ---------------------------------------------------
+
+ /** Returns the specified built-in cell style name.
+ @param nStyleId The identifier of the built-in style.
+ @param rName Default name for unknown styles.
+ @param nLevel The zero-based outline level for RowLevel and ColLevel styles.
+ @return The style name or an empty string, if the parameters are not valid. */
+ static String GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, sal_uInt8 nLevel );
+ /** Returns the passed style name with a special built-in prefix. */
+ static String GetBuiltInStyleName( const String& rStyleName );
+ /** Returns true, if the passed string is a name of an Excel built-in style.
+ @param pnStyleId If not 0, the found style identifier will be returned here.
+ @param pnNextChar If not 0, the index of the char after the evaluated substring will be returned here. */
+ static bool IsBuiltInStyleName( const String& rStyleName, sal_uInt8* pnStyleId = 0, xub_StrLen* pnNextChar = 0 );
+ /** Returns the Excel built-in style identifier of a passed style name.
+ @param rnStyleId The style identifier is returned here.
+ @param rnLevel The zero-based outline level for RowLevel and ColLevel styles is returned here.
+ @param rStyleName The style name to examine.
+ @return true = passed string is a built-in style name, false = user style. */
+ static bool GetBuiltInStyleId(
+ sal_uInt8& rnStyleId, sal_uInt8& rnLevel,
+ const String& rStyleName );
+
+ // conditional formatting style names -------------------------------------
+
+ /** Returns the style name for a single condition of a conditional formatting.
+ @param nScTab The current Calc sheet index.
+ @param nFormat The zero-based index of the conditional formatting.
+ @param nCondition The zero-based index of the condition.
+ @return A style sheet name in the form "Excel_CondFormat_<sheet>_<format>_<condition>". */
+ static String GetCondFormatStyleName( SCTAB nScTab, sal_Int32 nFormat, sal_uInt16 nCondition );
+ /** Returns true, if the passed string is a name of a conditional format style created by Excel import.
+ @param pnNextChar If not 0, the index of the char after the evaluated substring will be returned here. */
+ static bool IsCondFormatStyleName( const String& rStyleName, xub_StrLen* pnNextChar = 0 );
+
+ // stream handling --------------------------------------------------------
+
+ /** Skips a substream (BOF/EOF record block). Includes all embedded substreams. */
+ static void SkipSubStream( XclImpStream& rStrm );
+
+ // Basic macro names ------------------------------------------------------
+
+ /** Returns the full StarBasic macro URL from an Excel macro name. */
+ static ::rtl::OUString GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell = 0 );
+ /** Returns the full StarBasic macro URL from an Excel module and macro name. */
+ static ::rtl::OUString GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell = 0 );
+ /** Returns the Excel macro name from a full StarBasic macro URL. */
+ static String GetXclMacroName( const ::rtl::OUString& rSbMacroUrl );
+
+// ------------------------------------------------------------------------
+private:
+ static const String maDefNamePrefix; /// Prefix for built-in defined names.
+ static const String maStyleNamePrefix1; /// Prefix for built-in cell style names.
+ static const String maStyleNamePrefix2; /// Prefix for built-in cell style names from OOX filter.
+ static const String maCFStyleNamePrefix1; /// Prefix for cond. formatting style names.
+ static const String maCFStyleNamePrefix2; /// Prefix for cond. formatting style names from OOX filter.
+ static const ::rtl::OUString maSbMacroPrefix; /// Prefix for StarBasic macros.
+ static const ::rtl::OUString maSbMacroSuffix; /// Suffix for StarBasic macros.
+};
+
+// read/write colors ----------------------------------------------------------
+
+/** Reads a color from the passed stream.
+ @descr The color has the format (all values 8-bit): Red, Green, Blue, 0. */
+XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor );
+
+/** Reads a color to the passed stream.
+ @descr The color has the format (all values 8-bit): Red, Green, Blue, 0. */
+XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor );
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xltracer.hxx b/sc/source/filter/inc/xltracer.hxx
new file mode 100644
index 000000000000..73ed3d0502c3
--- /dev/null
+++ b/sc/source/filter/inc/xltracer.hxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef SC_XLTRACER_HXX
+#define SC_XLTRACER_HXX
+
+#include "global.hxx" // ScAddress
+#include "xltools.hxx"
+
+// As Trace features become implemented, we can safely delete the enum entry as
+// we use the member mnID to keep track of the actual trace tag ID value.
+enum XclTracerId
+{
+ eUnKnown , /// unused but allows us to set the correct index
+ eRowLimitExceeded ,
+ eTabLimitExceeded ,
+ ePassword ,
+ ePrintRange ,
+ eShortDate ,
+ eBorderLineStyle ,
+ eFillPattern ,
+ eInvisibleGrid ,
+ eFormattedNote ,
+ eFormulaExtName ,
+ eFormulaMissingArg ,
+ ePivotDataSource ,
+ ePivotChartExists ,
+ eChartUnKnownType ,
+ eChartTrendLines ,
+ eChartErrorBars ,
+ eChartOnlySheet ,
+ eChartRange ,
+ eChartDSName,
+ eChartDataTable,
+ eChartLegendPosition,
+ eChartTextFormatting,
+ eChartEmbeddedObj,
+ eChartAxisAuto,
+ eChartAxisManual,
+ eChartInvalidXY,
+ eUnsupportedObject ,
+ eObjectNotPrintable ,
+ eDVType,
+ eTraceLength /// this *should* always be the final entry
+};
+
+struct XclTracerDetails
+{
+ XclTracerId meProblemId; /// Excel Import Trace index.
+ sal_uInt32 mnID; /// actual ID Index trace tag Value
+ const sal_Char* mpContext; /// Context for problem e.g. Limits
+ const sal_Char* mpDetail; /// Context Detail e.g. SheetX
+ const sal_Char* mpProblem; /// Description of problem
+};
+
+
+// ============================================================================
+
+class MSFilterTracer;
+
+/** This class wraps an MSFilterTracer to create trace logs for import/export filters. */
+class XclTracer
+{
+public:
+ explicit XclTracer( const String& rDocUrl, const ::rtl::OUString& rConfigPath );
+ virtual ~XclTracer();
+
+ /** Returns true, if tracing is enabled. */
+ inline bool IsEnabled() const { return mbEnabled; }
+
+ /** Adds an attribute to be traced with the next Trace() call. */
+ void AddAttribute( const ::rtl::OUString& rName, const ::rtl::OUString& rValue );
+
+ /** Creates an element including all attributes set up to this call.
+ @descr Removes all attributes after the element is traced. */
+ void Trace( const ::rtl::OUString& rElementID, const ::rtl::OUString& rMessage );
+
+ /** Calls Trace() with a known document properties problem. */
+ void TraceLog( XclTracerId eProblem, sal_Int32 nValue = 0 );
+
+ /** Calls AddAttribute() to create the Context & Detail for known problems. */
+ void Context( XclTracerId eProblem, SCTAB nTab = 0 );
+
+ /** Ensure that particular traces are logged once per document. */
+ void ProcessTraceOnce(XclTracerId eProblem, SCTAB nTab = 0);
+
+ void TraceInvalidAddress(const ScAddress& rPos, const ScAddress& rMaxPos);
+ void TraceInvalidRow( SCTAB nTab, sal_uInt32 nRow, sal_uInt32 nMaxrow );
+ void TraceInvalidTab( SCTAB nTab, SCTAB nMaxTab);
+ void TracePrintRange();
+ void TraceDates(sal_uInt16 nNumFmt);
+ void TraceBorderLineStyle(bool bBorderLineStyle);
+ void TraceFillPattern(bool bFillPattern);
+ void TraceFormulaMissingArg();
+ void TracePivotDataSource(bool bExternal);
+ void TracePivotChartExists();
+ void TraceChartUnKnownType();
+ void TraceChartOnlySheet();
+ void TraceChartDataTable();
+ void TraceChartLegendPosition();
+ void TraceChartEmbeddedObj();
+ void TraceUnsupportedObjects();
+ void TraceObjectNotPrintable();
+ void TraceDVType(bool bType);
+
+ /** Returns the SVX filter tracer for usage in external code (i.e. Escher). */
+ inline MSFilterTracer& GetBaseTracer() { return *mpTracer; }
+
+private:
+ typedef ::std::auto_ptr< MSFilterTracer > MSFilterTracerPtr;
+ MSFilterTracerPtr mpTracer;
+ bool mbEnabled;
+ typedef ::std::vector< bool > BoolVec;
+ /** array of flags corresponding to each entry in the XclTracerDetails table. */
+ BoolVec maFirstTimes;
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/inc/xlview.hxx b/sc/source/filter/inc/xlview.hxx
new file mode 100644
index 000000000000..c0c9d4b3d6e1
--- /dev/null
+++ b/sc/source/filter/inc/xlview.hxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLVIEW_HXX
+#define SC_XLVIEW_HXX
+
+#include <map>
+#include <tools/color.hxx>
+#include "ftools.hxx"
+#include "xladdress.hxx"
+
+// Constants and enumerations =================================================
+
+const sal_uInt16 EXC_ZOOM_MIN = 10;
+const sal_uInt16 EXC_ZOOM_MAX = 400;
+
+// (0x001D) SELECTION ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SELECTION = 0x001D;
+
+// (0x003D) WINDOW1 -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_WINDOW1 = 0x003D;
+
+const sal_uInt16 EXC_WIN1_HIDDEN = 0x0001;
+const sal_uInt16 EXC_WIN1_MINIMIZED = 0x0002;
+const sal_uInt16 EXC_WIN1_HOR_SCROLLBAR = 0x0008;
+const sal_uInt16 EXC_WIN1_VER_SCROLLBAR = 0x0010;
+const sal_uInt16 EXC_WIN1_TABBAR = 0x0020;
+
+// (0x003E, 0x023E) WINDOW2 ---------------------------------------------------
+
+const sal_uInt16 EXC_ID2_WINDOW2 = 0x003E;
+const sal_uInt16 EXC_ID_WINDOW2 = 0x023E;
+
+const sal_uInt16 EXC_WIN2_SHOWFORMULAS = 0x0001;
+const sal_uInt16 EXC_WIN2_SHOWGRID = 0x0002;
+const sal_uInt16 EXC_WIN2_SHOWHEADINGS = 0x0004;
+const sal_uInt16 EXC_WIN2_FROZEN = 0x0008;
+const sal_uInt16 EXC_WIN2_SHOWZEROS = 0x0010;
+const sal_uInt16 EXC_WIN2_DEFGRIDCOLOR = 0x0020;
+const sal_uInt16 EXC_WIN2_MIRRORED = 0x0040;
+const sal_uInt16 EXC_WIN2_SHOWOUTLINE = 0x0080;
+const sal_uInt16 EXC_WIN2_FROZENNOSPLIT = 0x0100;
+const sal_uInt16 EXC_WIN2_SELECTED = 0x0200;
+const sal_uInt16 EXC_WIN2_DISPLAYED = 0x0400;
+const sal_uInt16 EXC_WIN2_PAGEBREAKMODE = 0x0800;
+
+const sal_uInt16 EXC_WIN2_NORMALZOOM_DEF = 100; /// Default zoom for normal view.
+const sal_uInt16 EXC_WIN2_PAGEZOOM_DEF = 60; /// Default zoom for pagebreak preview.
+
+// (0x0041) PANE --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PANE = 0x0041;
+
+const sal_uInt8 EXC_PANE_BOTTOMRIGHT = 0; /// Bottom-right pane.
+const sal_uInt8 EXC_PANE_TOPRIGHT = 1; /// Right, or top-right pane.
+const sal_uInt8 EXC_PANE_BOTTOMLEFT = 2; /// Bottom, or bottom-left pane.
+const sal_uInt8 EXC_PANE_TOPLEFT = 3; /// Single, top, left, or top-left pane.
+
+// (0x00A0) SCL ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SCL = 0x00A0;
+
+// (0x0862) SHEETEXT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SHEETEXT = 0x0862; /// header id for sheetext
+const sal_uInt8 EXC_SHEETEXT_TABCOLOR = 0x7F; /// mask for tab color
+const sal_uInt16 EXC_COLOR_NOTABBG = 0x7F; /// Excel ignores Tab color when set to this value...
+// Structs ====================================================================
+
+/** Contains all view settings for the entire document. */
+struct XclDocViewData
+{
+ sal_uInt16 mnWinX; /// X position of the document window (twips).
+ sal_uInt16 mnWinY; /// Y position of the document window (twips).
+ sal_uInt16 mnWinWidth; /// Width of the document window (twips).
+ sal_uInt16 mnWinHeight; /// Height of the document window (twips).
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnDisplXclTab; /// Displayed (active) sheet.
+ sal_uInt16 mnFirstVisXclTab; /// First visible sheet.
+ sal_uInt16 mnXclSelectCnt; /// Number of selected sheets.
+ sal_uInt16 mnTabBarWidth; /// Width of sheet tabbar (1/1000 of window width).
+
+ explicit XclDocViewData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all settings for a selection in a single pane of a sheet. */
+struct XclSelectionData
+{
+ XclAddress maXclCursor; /// Cell cursor position.
+ XclRangeList maXclSelection; /// Selected cell ranges.
+ sal_uInt16 mnCursorIdx; /// Index of cursor in selection list.
+
+ inline explicit XclSelectionData() : mnCursorIdx( 0 ) {}
+};
+
+typedef ScfRef< XclSelectionData > XclSelectionDataRef;
+
+// ----------------------------------------------------------------------------
+
+/** Contains all view settings for a single sheet. */
+struct XclTabViewData
+{
+ typedef ::std::map< sal_uInt8, XclSelectionDataRef > XclSelectionMap;
+
+ XclSelectionMap maSelMap; /// Selections of all panes.
+ Color maGridColor; /// Grid color.
+ XclAddress maFirstXclPos; /// First visible cell.
+ XclAddress maSecondXclPos; /// First visible cell in additional panes.
+ sal_uInt16 mnSplitX; /// Split X position, or number of frozen columns.
+ sal_uInt16 mnSplitY; /// Split Y position, or number of frozen rows.
+ sal_uInt16 mnNormalZoom; /// Zoom factor for normal view.
+ sal_uInt16 mnPageZoom; /// Zoom factor for pagebreak preview.
+ sal_uInt16 mnCurrentZoom; /// Zoom factor for current view.
+ sal_uInt8 mnActivePane; /// Active pane (with cell cursor).
+ bool mbSelected; /// true = Sheet is selected.
+ bool mbDisplayed; /// true = Sheet is displayed (active).
+ bool mbMirrored; /// true = Mirrored (right-to-left) sheet.
+ bool mbFrozenPanes; /// true = Frozen panes; false = split window.
+ bool mbPageMode; /// true = Pagebreak preview; false = Normal view.
+ bool mbDefGridColor; /// true = Default grid color.
+ bool mbShowFormulas; /// true = Show formulas instead of results.
+ bool mbShowGrid; /// true = Show cell grid.
+ bool mbShowHeadings; /// true = Show column/row headings.
+ bool mbShowZeros; /// true = Show zero value zells.
+ bool mbShowOutline; /// true = Show outlines.
+ Color maTabBgColor; /// Tab Color default = (COL_AUTO )
+ bool IsDefaultTabBgColor() const { return maTabBgColor == Color(COL_AUTO) ? TRUE : FALSE; };
+ sal_uInt32 mnTabBgColorId; /// pallette color id
+
+ explicit XclTabViewData();
+ ~XclTabViewData();
+
+ /** Sets Excel default view settings. */
+ void SetDefaults();
+
+ /** Returns true, if the window is split in any direction. */
+ bool IsSplit() const;
+ /** Returns true, if the specified pane (EXC_PANE_*) is available. */
+ bool HasPane( sal_uInt8 nPaneId ) const;
+
+ /** Returns the selection data, if available, otherwise 0. */
+ const XclSelectionData* GetSelectionData( sal_uInt8 nPane ) const;
+ /** Returns read/write access to the selection data of the specified pane. */
+ XclSelectionData& CreateSelectionData( sal_uInt8 nPane );
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/lotus/expop.cxx b/sc/source/filter/lotus/expop.cxx
new file mode 100644
index 000000000000..7ecc9127b49d
--- /dev/null
+++ b/sc/source/filter/lotus/expop.cxx
@@ -0,0 +1,412 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+
+#include "exp_op.hxx"
+
+#if ENABLE_LOTUS123_EXPORT
+const USHORT ExportWK1::WK1MAXCOL = 255;
+const USHORT ExportWK1::WK1MAXROW = 8191;
+
+BYTE ExportWK1::GenFormByte( const ScPatternAttr& /*aAttr*/ )
+{
+ return 0xFF;
+}
+
+
+inline void ExportWK1::Bof()
+{ // (0x00)
+ aOut << ( USHORT ) 0x00 << ( USHORT ) 2 << ( USHORT ) 0x0406; // Version 1-2-3/2, Symhony/1.1
+}
+
+
+inline void ExportWK1::Eof()
+{ // (0x01)
+ aOut << ( USHORT ) 0x01 << ( USHORT ) 0;
+}
+
+
+inline void ExportWK1::Calcmode()
+{ // (0x02)
+ // Calculationmode = automatic
+ aOut << ( USHORT ) 0x02 << ( USHORT ) 1 << ( BYTE ) 0xFF;
+}
+
+
+inline void ExportWK1::Calcorder()
+{ // (0x03)
+ // order = natural
+ aOut << ( USHORT ) 0x03 << ( USHORT ) 1 << ( BYTE ) 0x00;
+}
+
+
+inline void ExportWK1::Split()
+{ // (0x04)
+ // not split
+ aOut << ( USHORT ) 0x04 << ( USHORT ) 1 << ( BYTE ) 0x00;
+}
+
+
+inline void ExportWK1::Sync()
+{ // (0x05)
+ // not synchronized
+ aOut << ( USHORT ) 0x05 << ( USHORT ) 1 << ( BYTE ) 0x00;
+}
+
+
+inline void ExportWK1::Dimensions()
+{ // (0x06)
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aOut << ( USHORT ) 0x06 << ( USHORT ) 8 << ( USHORT ) 0 << ( USHORT ) 0; // Starting Col/Row
+ pD->GetPrintArea( 0, nEndCol, nEndRow );
+#if SC_ROWLIMIT_MORE_THAN_64K
+#error row limit 64k
+#endif
+ USHORT nCol = static_cast<USHORT>(nEndCol);
+ USHORT nRow = static_cast<USHORT>(nEndRow);
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Dimensions(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Dimensions(): Row > WK1MAXROW" );
+ aOut << nCol << nRow; // Ending Col/Row
+}
+
+
+inline void ExportWK1::Window1()
+{ // (0x07)
+ aOut << ( USHORT ) 0x07 << ( USHORT ) 32
+ << ( USHORT ) 0 << ( USHORT ) 0 // Cursor Col/Row
+ << ( BYTE ) 0xFF // Format: protected, special, default
+ << ( BYTE ) 0 // Dummy
+ << ( USHORT ) 9 // Default column width
+ << ( USHORT ) 8 << ( USHORT ) 14// Number of cols/rows on screen
+ << ( USHORT ) 0 << ( USHORT ) 0 // Left col / top row
+ // Rest aus Doku-Beispiel
+ << ( USHORT ) 0 << ( USHORT ) 0 // Number of title cols / rows
+ << ( USHORT ) 0 << ( USHORT ) 0 // Left title col / top title row
+ << ( USHORT ) 0x0004 << ( USHORT ) 0x0004// Top-left col / row
+ << ( USHORT ) 0x0048 // Number of cols in window
+ << ( USHORT ) 0x00; // Dummy
+}
+
+
+inline void ExportWK1::Colw()
+{ // (0x08)
+ // ACHTUNG: muss nach Window1 und vor hidden cols record kommen!
+ USHORT nWidth;
+ BYTE nWidthSpaces;
+ for( USHORT nCol = 0 ; nCol < 256 ; nCol++ )
+ {
+ nWidth = pD->GetColWidth( static_cast<SCCOL>(nCol), 0 );
+ nWidthSpaces = ( BYTE ) ( nWidth / TWIPS_PER_CHAR );
+ aOut << ( USHORT ) 0x08 << ( USHORT ) 3 << nCol << nWidthSpaces;
+ }
+}
+
+
+void ExportWK1::Blank( const USHORT nCol, const USHORT nRow, const ScPatternAttr& aAttr )
+{ // (0x0C)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Blank(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Blank(): Row > WK1MAXROW" );
+
+ aOut << ( USHORT ) 0x0C << ( USHORT ) 5 << GenFormByte( aAttr ) << nCol << nRow;
+}
+
+
+void ExportWK1::Number( const USHORT nCol, const USHORT nRow, const double fWert, const ScPatternAttr &aAttr )
+{ // (0x0E)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Number(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Number(): Row > WK1MAXROW" );
+
+ aOut << ( USHORT ) 0x0E << ( USHORT ) 13 << GenFormByte( aAttr ) << nCol << nRow << fWert;
+}
+
+
+void ExportWK1::Label( const USHORT nCol, const USHORT nRow, const String& rStr, const ScPatternAttr& aAttr )
+{ // (0x0F)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
+
+ ByteString aStr( rStr, eZielChar );
+
+ USHORT nLaenge = 7; // Anzahl Bytes vor String+Nullbyte am Ende + Alignment-Char
+
+ xub_StrLen nAnz = aStr.Len();
+
+
+ if( nAnz > 240 ) // max. 240 Zeichen im String
+ nAnz = 240;
+
+ nLaenge = nLaenge + ( USHORT ) nAnz; // + Stringlaenge
+
+ aOut << ( USHORT ) 0x0F << nLaenge << GenFormByte( aAttr ) << nCol << nRow << ( sal_Char ) '\'';
+ // ACHTUNG: ZUNAECHST NUR LEFT ALIGNMENT
+
+ aOut.Write( aStr.GetBuffer(), nAnz );
+
+ aOut << ( BYTE ) 0x00; // ...und Nullterminator anhaengen
+}
+
+
+void ExportWK1::Formula( const USHORT nCol, const USHORT nRow, const ScFormulaCell* pFC, const ScPatternAttr& aAttr )
+{ // (0x10)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Formula(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Formula(): Row > WK1MAXROW" );
+
+ USHORT nLaenge = 15; // Bytes bis Formel
+ double fErgebnis;
+
+ // zunaechst nur Dummy-Angaben (Formel := Ergebnis der Berechnung )
+ nLaenge += 9+1;
+
+ fErgebnis = ( ( ScFormulaCell* ) pFC )->GetValue();
+
+ aOut << ( USHORT ) 0x10 << ( USHORT ) nLaenge
+ << GenFormByte( aAttr ) << nCol << nRow
+ << fErgebnis
+ << ( USHORT ) 9+1 // Dummy-Formula-Size
+ << ( BYTE ) 0x00 // constant, floating point
+ << fErgebnis
+ << ( BYTE ) 0x03; // return
+}
+
+
+inline void ExportWK1::Protect()
+{ // (0x24)
+ //Global protection off
+ aOut << ( USHORT ) 0x24 << ( USHORT ) 1 << ( BYTE ) 0x00;
+}
+
+
+inline void ExportWK1::Footer()
+{ // (0x25)
+ // zunaechst nur leerer C-String
+ aOut << ( USHORT ) 0x25 << ( USHORT ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
+ for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
+ aOut << ( BYTE ) 0x00;
+}
+
+
+inline void ExportWK1::Header()
+{ // (0x26)
+ // zunaechst nur leerer C-String
+ aOut << ( USHORT ) 0x26 << ( USHORT ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
+ for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
+ aOut << ( BYTE ) 0x00;
+}
+
+
+inline void ExportWK1::Margins()
+{ // (0x28)
+ aOut << ( USHORT ) 0x28 << ( USHORT ) 10
+ << ( USHORT ) 4 << ( USHORT ) 76 // Left/right margin
+ << ( USHORT ) 66 // Page length
+ << ( USHORT ) 2 << ( USHORT ) 2; // Top/Bottom margin
+}
+
+
+inline void ExportWK1::Labelfmt()
+{ // (0x29)
+ // Global label alignment = left
+ aOut << ( USHORT ) 0x29 << ( USHORT ) 1 << ( BYTE ) 0x27;
+}
+
+
+inline void ExportWK1::Calccount()
+{ // (0x2F)
+ // Iteration count = 16 (oder so aehnlich)
+ aOut << ( USHORT ) 0x2F << ( USHORT ) 1 << ( BYTE ) 16;
+}
+
+
+inline void ExportWK1::Cursorw12()
+{ // (0x31)
+ // Cursor location in window 1
+ aOut << ( USHORT ) 0x31 << ( USHORT ) 1 << ( BYTE ) 1;
+}
+
+
+void ExportWK1::WKString( const USHORT /*nCol*/, const USHORT /*nRow*/, const ScFormulaCell* /*pFC*/, const ScPatternAttr& /*aAttr*/ )
+{ // (0x33)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+/* DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
+
+ String aStr;
+ ( ( ScFormulaCell * ) pFC )->GetString( aStr ); // Formeltext zunaechst so belassen
+
+ USHORT nLaenge = 6; // Anzahl Bytes vor String+Nullbyte am Ende
+
+ USHORT nAnz = aStr.Len();
+
+ if( nAnz > 240 ) // max. 240 Zeichen im String
+ nAnz = 240;
+
+ nLaenge += nAnz; // + Stringlaenge
+
+ aOut << ( USHORT ) 0x33 << nLaenge
+ << GenFormByte( aAttr ) << nCol << nRow;
+
+ // Zeichenweise String ausgeben
+ for( USHORT nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ aOut << aStr[ nLauf ];
+
+ aOut << ( BYTE ) 0x00; // ...und Nullterminator anhaengen
+*/
+ }
+
+
+inline void ExportWK1::Snrange()
+{ // (0x47)
+ //aOut << ( USHORT ) 0x47 << ( USHORT ) x
+/* ScRangeName *pRanges = pD->GetRangeName();
+ ScRangeData *pData;
+ String aName;
+
+ USHORT nAnz = pRanges->GetCount();
+
+ for( USHORT nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ {
+ pData = pRanges[ nLauf ];
+
+ }
+*/
+}
+
+
+inline void ExportWK1::Hidcol()
+{ // (0x64)
+ sal_uInt32 nHide = 0x00000000; // ...niemand ist versteckt
+
+ aOut << ( USHORT ) 0x64 << ( USHORT ) 32;
+
+ for( int nLauf = 0 ; nLauf < 8 ; nLauf++ )
+ aOut << nHide; // 8 * 32 Bits = 256
+}
+
+
+inline void ExportWK1::Cpi()
+{ // (0x96)
+ //aOut << ( USHORT ) 0x96 << ( USHORT ) x;
+}
+
+
+FltError ExportWK1::Write()
+{
+ Bof();
+ //Dimensions();
+ //Cpi();
+ //Calccount();
+ //Calcmode();
+ //Calcorder();
+ //Split();
+ //Sync();
+ //Window1();
+ Colw();
+ //Hidcol();
+ //Cursorw12();
+ //Snrange();
+ //Protect();
+ //Footer();
+ //Header();
+ //Margins();
+ //Labelfmt();
+
+ // Zellen-Bemachung
+ ScDocumentIterator aIter( pD, 0, 0 );
+ ScBaseCell* pCell;
+ USHORT nCol, nRow;
+ SCTAB nTab;
+ const ScPatternAttr* pPatAttr;
+
+ if( aIter.GetFirst() )
+ do
+ { // ueber alle Zellen der ersten Tabelle iterieren
+ pPatAttr = aIter.GetPattern();
+ pCell = aIter.GetCell();
+ SCCOL nScCol;
+ SCROW nScRow;
+ aIter.GetPos( nScCol, nScRow, nTab );
+#if SC_ROWLIMIT_MORE_THAN_64K
+#error row limit 64k
+#endif
+ nCol = static_cast<USHORT>(nScCol);
+ nRow = static_cast<USHORT>(nScRow);
+
+ switch( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ {
+ double fVal;
+ fVal = ( ( ScValueCell * ) pCell)->GetValue();
+ Number( nCol, nRow, fVal, *pPatAttr );
+ }
+ break;
+ case CELLTYPE_STRING:
+ {
+ String aStr;
+ ( ( ScStringCell * ) pCell)->GetString( aStr );
+ Label( nCol, nRow, aStr, *pPatAttr );
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ Formula( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
+ WKString( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
+ }
+ break;
+ case CELLTYPE_NOTE:
+ case CELLTYPE_NONE:
+ break;
+ default:
+ DBG_ASSERT( FALSE, "ExportWK1::Write(): unbekannter Celltype!" );
+ }
+ }
+ while( aIter.GetNext() );
+
+ Eof();
+
+ return eERR_OK;
+}
+#endif
+
+
diff --git a/sc/source/filter/lotus/export.cxx b/sc/source/filter/lotus/export.cxx
new file mode 100644
index 000000000000..a9be45e24f23
--- /dev/null
+++ b/sc/source/filter/lotus/export.cxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "scerrors.hxx"
+#include "exp_op.hxx"
+
+#if ENABLE_LOTUS123_EXPORT
+FltError ScFormatFilterPluginImpl::ScExportLotus123( SvStream& aStream, ScDocument* pDoc, ExportFormatLotus eFormat, CharSet eDest )
+{
+ switch( eFormat )
+ {
+ case ExpWK1:
+ {
+ ExportWK1 aWKFile( aStream, pDoc, eDest );
+ aWKFile.Write();
+ }
+ break;
+ case ExpWK3:
+ return eERR_NI;
+ default:
+ return eERR_NI;
+ }
+
+ return eERR_OK;
+}
+#endif
+
+
diff --git a/sc/source/filter/lotus/filter.cxx b/sc/source/filter/lotus/filter.cxx
new file mode 100644
index 000000000000..3a6e39b7d818
--- /dev/null
+++ b/sc/source/filter/lotus/filter.cxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// Das geht: Versionserkennung WKS, WK1 und WK3
+// ...Rest steht in op.cpp
+
+//------------------------------------------------------------------------
+
+#include <tools/solar.h>
+#include <string.h>
+#include <map>
+
+#include "filter.hxx"
+#include "document.hxx"
+#include "compiler.hxx"
+#include "scerrors.hxx"
+
+#include "root.hxx"
+#include "lotrange.hxx"
+#include "optab.h"
+#include "scmem.h"
+#include "decl.h"
+#include "tool.h"
+
+#include "fprogressbar.hxx"
+
+#include "op.h"
+
+// Konstanten ------------------------------------------------------------
+const UINT16 nBOF = 0x0000;
+
+
+
+// externe Variablen -----------------------------------------------------
+extern WKTYP eTyp; // Typ der gerade in bearbeitung befindlichen Datei
+WKTYP eTyp;
+
+extern BOOL bEOF; // zeigt Ende der Datei
+BOOL bEOF;
+
+extern CharSet eCharNach; // Zeichenkonvertierung von->nach
+CharSet eCharNach;
+
+extern CharSet eCharVon;
+CharSet eCharVon;
+
+extern ScDocument* pDoc; // Aufhaenger zum Dokumentzugriff
+ScDocument* pDoc;
+
+
+extern sal_Char* pPuffer; // -> memory.cxx
+extern sal_Char* pDummy1; // -> memory.cxx
+
+extern OPCODE_FKT pOpFkt[ FKT_LIMIT ];
+ // -> optab.cxx, Tabelle moeglicher Opcodes
+extern OPCODE_FKT pOpFkt123[ FKT_LIMIT123 ];
+ // -> optab.cxx, Table of possible Opcodes
+
+extern long nDateiLaenge; // -> datei.cpp, ...der gerade offenen Datei
+
+LOTUS_ROOT* pLotusRoot = NULL;
+
+
+std::map<UINT16, ScPatternAttr> aLotusPatternPool;
+
+static FltError
+generate_Opcodes( SvStream& aStream, ScDocument& rDoc,
+ ScfStreamProgressBar& aPrgrsBar, WKTYP eType )
+{
+ OPCODE_FKT *pOps;
+ int nOps;
+
+ switch(eType)
+ {
+ case eWK_1:
+ case eWK_2:
+ pOps = pOpFkt;
+ nOps = FKT_LIMIT;
+ break;
+ case eWK123:
+ pOps = pOpFkt123;
+ nOps = FKT_LIMIT123;
+ break;
+ case eWK3: return eERR_NI;
+ case eWK_Error: return eERR_FORMAT;
+ default: return eERR_UNKN_WK;
+ }
+
+ // #i76299# seems that SvStream::IsEof() does not work correctly
+ aStream.Seek( STREAM_SEEK_TO_END );
+ sal_Size nStrmSize = aStream.Tell();
+ aStream.Seek( STREAM_SEEK_TO_BEGIN );
+ while( !bEOF && !aStream.IsEof() && (aStream.Tell() < nStrmSize) )
+ {
+ UINT16 nOpcode, nLength;
+
+ aStream >> nOpcode >> nLength;
+ aPrgrsBar.Progress();
+ if( nOpcode == LOTUS_EOF )
+ bEOF = TRUE;
+
+ else if( nOpcode == LOTUS_FILEPASSWD )
+ return eERR_FILEPASSWD;
+
+ else if( nOpcode < nOps )
+ pOps[ nOpcode ] ( aStream, nLength );
+
+ else if( eType == eWK123 &&
+ nOpcode == LOTUS_PATTERN )
+ {
+ // This is really ugly - needs re-factoring ...
+ aStream.SeekRel(nLength);
+ aStream >> nOpcode >> nLength;
+ if ( nOpcode == 0x29a)
+ {
+ aStream.SeekRel(nLength);
+ aStream >> nOpcode >> nLength;
+ if ( nOpcode == 0x804 )
+ {
+ aStream.SeekRel(nLength);
+ OP_ApplyPatternArea123(aStream);
+ }
+ else
+ aStream.SeekRel(nLength);
+ }
+ else
+ aStream.SeekRel(nLength);
+ }
+ else
+ aStream.SeekRel( nLength );
+ }
+
+ MemDelete();
+
+ rDoc.CalcAfterLoad();
+
+ return eERR_OK;
+}
+
+WKTYP ScanVersion( SvStream& aStream )
+{
+ // PREC: pWKDatei: Zeiger auf offene Datei
+ // POST: return: Typ der Datei
+ UINT16 nOpcode, nVersNr, nRecLen;
+
+ // erstes Byte muss wegen BOF zwingend 0 sein!
+ aStream >> nOpcode;
+ if( nOpcode != nBOF )
+ return eWK_UNKNOWN;
+
+ aStream >> nRecLen >> nVersNr;
+
+ if( aStream.IsEof() )
+ return eWK_Error;
+
+ switch( nVersNr )
+ {
+ case 0x0404:
+ if( nRecLen == 2 )
+ return eWK_1;
+ else
+ return eWK_UNKNOWN;
+
+ case 0x0406:
+ if( nRecLen == 2 )
+ return eWK_2;
+ else
+ return eWK_UNKNOWN;
+
+ case 0x1000:
+ aStream >> nVersNr;
+ if( aStream.IsEof() ) return eWK_Error;
+ if( nVersNr == 0x0004 && nRecLen == 26 )
+ { // 4 Bytes von 26 gelesen->22 ueberlesen
+ aStream.Read( pDummy1, 22 );
+ return eWK3;
+ }
+ break;
+ case 0x1003:
+ if( nRecLen == 0x1a )
+ return eWK123;
+ else
+ return eWK_UNKNOWN;
+ case 0x1005:
+ if( nRecLen == 0x1a )
+ return eWK123;
+ else
+ return eWK_UNKNOWN;
+ }
+
+ return eWK_UNKNOWN;
+}
+
+FltError ScImportLotus123old( SvStream& aStream, ScDocument* pDocument, CharSet eSrc )
+{
+ aStream.Seek( 0UL );
+
+ // Zeiger auf Dokument global machen
+ pDoc = pDocument;
+
+ bEOF = FALSE;
+
+ eCharVon = eSrc;
+
+ // Speicher besorgen
+ if( !MemNew() )
+ return eERR_NOMEM;
+
+ InitPage(); // Seitenformat initialisieren (nur Tab 0!)
+
+ // Progressbar starten
+ ScfStreamProgressBar aPrgrsBar( aStream, pDocument->GetDocumentShell() );
+
+ // Datei-Typ ermitteln
+ eTyp = ScanVersion( aStream );
+
+ aLotusPatternPool.clear();
+
+ return generate_Opcodes( aStream, *pDoc, aPrgrsBar, eTyp );
+}
+
+
diff --git a/sc/source/filter/lotus/lotattr.cxx b/sc/source/filter/lotus/lotattr.cxx
new file mode 100644
index 000000000000..6a05585cf326
--- /dev/null
+++ b/sc/source/filter/lotus/lotattr.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+
+#include "document.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+
+#include "lotattr.hxx"
+#include "lotfntbf.hxx"
+#include "root.hxx"
+
+
+
+void LotAttrCache::LotusToScBorderLine( UINT8 nLine, SvxBorderLine& aBL )
+{
+ static const UINT16 pPara[ 4 ][ 3 ] =
+ {
+ { 0,0,0 },
+ { DEF_LINE_WIDTH_1, 0, 0 },
+ { DEF_LINE_WIDTH_2, 0, 0 },
+ { DEF_LINE_WIDTH_1, DEF_LINE_WIDTH_1, DEF_LINE_WIDTH_1 }
+ };
+
+ nLine &= 0x03;
+
+ if( nLine )
+ {
+ aBL.SetOutWidth( pPara[ nLine ][ 0 ] );
+ aBL.SetInWidth( pPara[ nLine ][ 1 ] );
+ aBL.SetDistance( pPara[ nLine ][ 2 ] );
+ }
+}
+
+
+const SvxColorItem& LotAttrCache::GetColorItem( const UINT8 nLotIndex ) const
+{
+ DBG_ASSERT( nLotIndex > 0 && nLotIndex < 7,
+ "-LotAttrCache::GetColorItem(): so nicht!" );
+
+ return *ppColorItems[ nLotIndex - 1 ];
+}
+
+
+const Color& LotAttrCache::GetColor( const UINT8 nLotIndex ) const
+{
+ // Farbe <-> Index passt fuer Background, nicht aber fuer Fonts (0 <-> 7)!
+ DBG_ASSERT( nLotIndex < 8, "*LotAttrCache::GetColor(): Index > 7!" );
+ return pColTab[ nLotIndex ];
+}
+
+
+LotAttrCache::LotAttrCache( void )
+{
+ pDocPool = pLotusRoot->pDoc->GetPool();
+
+ pColTab = new Color [ 8 ];
+ pColTab[ 0 ] = Color( COL_WHITE );
+ pColTab[ 1 ] = Color( COL_LIGHTBLUE );
+ pColTab[ 2 ] = Color( COL_LIGHTGREEN );
+ pColTab[ 3 ] = Color( COL_LIGHTCYAN );
+ pColTab[ 4 ] = Color( COL_LIGHTRED );
+ pColTab[ 5 ] = Color( COL_LIGHTMAGENTA );
+ pColTab[ 6 ] = Color( COL_YELLOW );
+ pColTab[ 7 ] = Color( COL_BLACK );
+
+ ppColorItems[ 0 ] = new SvxColorItem( GetColor( 1 ), ATTR_FONT_COLOR ); // 1
+ ppColorItems[ 1 ] = new SvxColorItem( GetColor( 2 ), ATTR_FONT_COLOR );
+ ppColorItems[ 2 ] = new SvxColorItem( GetColor( 3 ), ATTR_FONT_COLOR );
+ ppColorItems[ 3 ] = new SvxColorItem( GetColor( 4 ), ATTR_FONT_COLOR );
+ ppColorItems[ 4 ] = new SvxColorItem( GetColor( 5 ), ATTR_FONT_COLOR );
+ ppColorItems[ 5 ] = new SvxColorItem( GetColor( 6 ), ATTR_FONT_COLOR ); // 6
+
+ pBlack = new SvxColorItem( Color( COL_BLACK ), ATTR_FONT_COLOR );
+ pWhite = new SvxColorItem( Color( COL_WHITE ), ATTR_FONT_COLOR );
+}
+
+
+LotAttrCache::~LotAttrCache()
+{
+ ENTRY* pAkt = ( ENTRY* ) List::First();
+
+ while( pAkt )
+ {
+ delete pAkt;
+ pAkt = ( ENTRY* ) List::Next();
+ }
+
+ for( UINT16 nCnt = 0 ; nCnt < 6 ; nCnt++ )
+ delete ppColorItems[ nCnt ];
+
+ delete pBlack;
+ delete pWhite;
+
+ delete[] pColTab;
+}
+
+
+const ScPatternAttr& LotAttrCache::GetPattAttr( const LotAttrWK3& rAttr )
+{
+ UINT32 nRefHash;
+ ENTRY* pAkt = ( ENTRY* ) List::First();
+
+ MakeHash( rAttr, nRefHash );
+
+ while( pAkt )
+ {
+ if( *pAkt == nRefHash )
+ return *pAkt->pPattAttr;
+
+ pAkt = ( ENTRY* ) List::Next();
+ }
+
+ // neues PatternAttribute erzeugen
+ ScPatternAttr* pNewPatt = new ScPatternAttr( pDocPool );
+ SfxItemSet& rItemSet = pNewPatt->GetItemSet();
+ pAkt = new ENTRY( pNewPatt );
+
+ pAkt->nHash0 = nRefHash;
+
+ pLotusRoot->pFontBuff->Fill( rAttr.nFont, rItemSet );
+
+ UINT8 nLine = rAttr.nLineStyle;
+ if( nLine )
+ {
+ SvxBoxItem aBox( ATTR_BORDER );
+ SvxBorderLine aTop, aLeft, aBottom, aRight;
+
+ LotusToScBorderLine( nLine, aLeft );
+ nLine >>= 2;
+ LotusToScBorderLine( nLine, aRight );
+ nLine >>= 2;
+ LotusToScBorderLine( nLine, aTop );
+ nLine >>= 2;
+ LotusToScBorderLine( nLine, aBottom );
+
+ aBox.SetLine( &aTop, BOX_LINE_TOP );
+ aBox.SetLine( &aLeft, BOX_LINE_LEFT );
+ aBox.SetLine( &aBottom, BOX_LINE_BOTTOM );
+ aBox.SetLine( &aRight, BOX_LINE_RIGHT );
+
+ rItemSet.Put( aBox );
+ }
+
+ UINT8 nFontCol = rAttr.nFontCol & 0x07;
+ if( nFontCol )
+ {
+ // nFontCol > 0
+ if( nFontCol < 7 )
+ rItemSet.Put( GetColorItem( nFontCol ) );
+ else
+ rItemSet.Put( *pWhite );
+ }
+
+ UINT8 nBack = rAttr.nBack & 0x1F;
+ if( nBack )
+ rItemSet.Put( SvxBrushItem( GetColor( nBack & 0x07 ), ATTR_BACKGROUND ) );
+
+ if( rAttr.nBack & 0x80 )
+ {
+ SvxHorJustifyItem aHorJustify(SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY );
+ rItemSet.Put( aHorJustify );
+ }
+
+ List::Insert( pAkt, LIST_APPEND );
+
+ return *pNewPatt;
+ }
+
+
+LotAttrCol::~LotAttrCol()
+{
+ Clear();
+}
+
+
+void LotAttrCol::SetAttr( const SCROW nRow, const ScPatternAttr& rAttr )
+{
+ DBG_ASSERT( ValidRow(nRow), "*LotAttrCol::SetAttr(): ... und rums?!" );
+
+ ENTRY* pAkt = ( ENTRY* ) List::Last();
+
+ if( pAkt )
+ {
+ if( ( pAkt->nLastRow == nRow - 1 ) && ( &rAttr == pAkt->pPattAttr ) )
+ pAkt->nLastRow = nRow;
+ else
+ {
+ pAkt = new ENTRY;
+
+ pAkt->pPattAttr = &rAttr;
+ pAkt->nFirstRow = pAkt->nLastRow = nRow;
+ List::Insert( pAkt, LIST_APPEND );
+ }
+ }
+ else
+ { // erster Eintrag
+ pAkt = new ENTRY;
+ pAkt->pPattAttr = &rAttr;
+ pAkt->nFirstRow = pAkt->nLastRow = nRow;
+ List::Insert( pAkt, LIST_APPEND );
+ }
+}
+
+
+void LotAttrCol::Apply( const SCCOL nColNum, const SCTAB nTabNum, const BOOL /*bClear*/ )
+{
+ ScDocument* pDoc = pLotusRoot->pDoc;
+ ENTRY* pAkt = ( ENTRY* ) List::First();
+
+ while( pAkt )
+ {
+ pDoc->ApplyPatternAreaTab( nColNum, pAkt->nFirstRow, nColNum, pAkt->nLastRow,
+ nTabNum, *pAkt->pPattAttr );
+
+ pAkt = ( ENTRY* ) List::Next();
+ }
+}
+
+
+void LotAttrCol::Clear( void )
+{
+ ENTRY* pAkt = ( ENTRY* ) List::First();
+
+ while( pAkt )
+ {
+ delete pAkt;
+ pAkt = ( ENTRY* ) List::Next();
+ }
+}
+
+
+LotAttrTable::LotAttrTable( void )
+{
+}
+
+
+LotAttrTable::~LotAttrTable()
+{
+}
+
+
+void LotAttrTable::SetAttr( const SCCOL nColFirst, const SCCOL nColLast, const SCROW nRow,
+ const LotAttrWK3& rAttr )
+{
+ const ScPatternAttr& rPattAttr = aAttrCache.GetPattAttr( rAttr );
+ SCCOL nColCnt;
+
+ for( nColCnt = nColFirst ; nColCnt <= nColLast ; nColCnt++ )
+ pCols[ nColCnt ].SetAttr( nRow, rPattAttr );
+}
+
+
+void LotAttrTable::Apply( const SCTAB nTabNum )
+{
+ SCCOL nColCnt;
+ for( nColCnt = 0 ; nColCnt <= MAXCOL ; nColCnt++ )
+ pCols[ nColCnt ].Apply( nColCnt, nTabNum ); // macht auch gleich ein Clear() am Ende
+}
+
+
+
+
diff --git a/sc/source/filter/lotus/lotform.cxx b/sc/source/filter/lotus/lotform.cxx
new file mode 100644
index 000000000000..e39891568e33
--- /dev/null
+++ b/sc/source/filter/lotus/lotform.cxx
@@ -0,0 +1,2074 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "decl.h"
+#include "lotform.hxx"
+#include "compiler.hxx"
+#include "lotrange.hxx"
+#include "namebuff.hxx"
+#include "root.hxx"
+#include "ftools.hxx"
+#include "tool.h"
+
+#include <math.h>
+
+extern WKTYP eTyp;
+
+static const sal_Char* GetAddInName( const UINT8 nIndex );
+
+static DefTokenId lcl_KnownAddIn( const ByteString& sTest );
+
+//extern double decipher_Number123( UINT32 nValue );
+
+
+void LotusToSc::DoFunc( DefTokenId eOc, BYTE nAnz, const sal_Char* pExtString )
+{
+ TokenId eParam[ 256 ];
+ INT32 nLauf;
+ TokenId nMerk0, nMerk1;
+
+ BOOL bAddIn = FALSE;
+ BOOL bNeg = FALSE;
+
+ DBG_ASSERT( nAnz < 128, "-LotusToSc::DoFunc(): Neee! -so viel kann ich nicht!" );
+
+ if( eOc == ocNoName )
+ {
+ ByteString t;
+ if( pExtString )
+ {
+ const ByteString s( "@<<@123>>" );
+
+ t = pExtString;
+
+ xub_StrLen n = t.Search( s );
+ if( n != STRING_NOTFOUND )
+ t.Erase( 0, n + s.Len() );
+
+ t.EraseTrailingChars( '(' );
+
+ eOc = lcl_KnownAddIn( t );
+
+ if( eOc == ocNoName )
+ t.Insert( "L123_", 0 );
+ }
+ else
+ t = "#UNKNOWN FUNC NAME#";
+
+ if( eOc == ocNoName )
+ {
+ bAddIn = TRUE;
+ nMerk0 = aPool.Store( eOc, String( t, eSrcChar ) );
+
+ aPool << nMerk0;
+ }
+ }
+
+ for( nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ aStack >> eParam[ nLauf ];
+
+ // Spezialfaelle...
+ switch( eOc )
+ {
+ case ocIndex:
+ DBG_ASSERT( nAnz > 2, "+LotusToSc::DoFunc(): ocIndex braucht mind. 2 Parameter!" );
+ nMerk0 = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nMerk0;
+ IncToken( eParam[ 0 ] );
+ IncToken( eParam[ 1 ] );
+ break;
+ case ocIRR:
+ {
+ DBG_ASSERT( nAnz == 2, "+LotusToSc::DoFunc(): ocIRR hat nur 2 Parameter!" );
+ nMerk0 = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nMerk0;
+ }
+ break;
+ case ocGetYear:
+ {
+ nMerk0 = aPool.Store( 1900.0 );
+ aPool << ocOpen;
+ }
+ break;
+ case ocChose:
+ {// 1. Parameter ++
+ IncToken( eParam[ nAnz - 1 ] );
+ }
+ break;
+ case ocFind:
+ case ocHLookup:
+ case ocVLookup:
+ {// letzten Parameter ++
+ IncToken( eParam[ 0 ] );
+ }
+ break;
+ case ocMid:
+ case ocReplace:
+ {// 2. Parameter ++
+ IncToken( eParam[ nAnz - 2 ] );
+ }
+ break;
+ case ocZins:
+ {
+ // neue Anzahl = 4!
+ DBG_ASSERT( nAnz == 3,
+ "*LotusToSc::DoFunc(): ZINS() hat 3 Parameter!" );
+ nAnz = 4;
+ eParam[ 3 ] = eParam[ 0 ]; // 3. -> 1.
+ eParam[ 0 ] = eParam[ 2 ]; // 1. -> 4.
+ NegToken( eParam[ 1 ] ); // 2. -> -2. (+ 2. -> 3.)
+ eParam[ 2 ] = n0Token; // -> 2. als Default
+ }
+ break;
+ default:;
+ }
+ // ................
+
+
+ if( !bAddIn )
+ aPool << eOc;
+
+ aPool << ocOpen;
+
+ if( nAnz > 0 )
+ {
+ INT16 nNull = -1; // gibt einen auszulassenden Parameter an
+ // ACHTUNG: 0 ist der letzte Parameter, nAnz-1 der erste
+
+ INT16 nLast = nAnz - 1;
+
+ if( eOc == ocRMZ )
+ { // Extrawurst ocRMZ letzter Parameter negiert!
+ // zusaetzlich: 1. -> 3., 3. -> 2., 2. -> 1.
+ DBG_ASSERT( nAnz == 3,
+ "+LotusToSc::DoFunc(): ocRMZ hat genau 3 Parameter!" );
+ aPool << eParam[ 1 ] << ocSep << eParam[ 0 ] << ocSep
+ << ocNegSub << eParam[ 2 ];
+ }
+ else
+ { // Normalfall
+ // [Parameter{;Parameter}]
+ aPool << eParam[ nLast ];
+
+ for( nLauf = nLast - 1 ; nLauf >= 0 ; nLauf-- )
+ {
+ if( nLauf != nNull )
+ aPool << ocSep << eParam[ nLauf ];
+ }
+ }
+ }
+
+
+ // Spezialfaelle...
+ if( eOc == ocGetYear )
+ {
+ aPool << ocClose << ocSub << nMerk0;
+ }
+ else if( eOc == ocFixed )
+ {
+ aPool << ocSep << ocTrue << ocOpen << ocClose;
+ }
+ else if( eOc == ocFind )
+ {
+ nMerk1 = aPool.Store();
+ DecToken( nMerk1 );
+ aPool << nMerk1;
+ }
+
+ aPool << ocClose;
+
+ // ................
+
+ aPool >> aStack;
+
+ if( bNeg )
+ {
+ aPool << ocOpen << ocSub << aStack << ocClose;
+ aPool >> aStack;
+ }
+}
+
+
+void LotusToSc::LotusRelToScRel( UINT16 nCol, UINT16 nRow, ScSingleRefData& rSRD )
+{
+ // Col-Bemachung
+ if( nCol & 0x8000 )
+ {
+ rSRD.SetColRel( TRUE );
+ if( nCol & 0x0080 )
+ nCol |= 0xFF00;
+ else
+ nCol &= 0x00FF;
+ // #i36252# first cast unsigned 16-bit to signed 16-bit, and then to SCsCOL
+ rSRD.nRelCol = static_cast< SCsCOL >( static_cast< sal_Int16 >( nCol ) );
+ }
+ else
+ {
+ rSRD.SetColRel( FALSE );
+ rSRD.nCol = static_cast< SCsCOL >( nCol & 0x00FF );
+ }
+
+ // Row-Bemachung
+ if( nRow & 0x8000 )
+ {
+ rSRD.SetRowRel( TRUE );
+ // vorzeichenrichtige Erweiterung
+ switch( eTyp )
+ {
+ // 5432 1098 7654 3210
+ // 8421 8421 8421 8421
+ // xxx xxxx xxxx
+ case eWK_1:
+ if( nRow & 0x0400 )
+ nRow |= 0xF800;
+ else
+ nRow &= 0x07FF;
+ break;
+ // 8421 8421 8421 8421
+ // x xxxx xxxx xxxx
+ case eWK_2:
+ if( nRow & 0x1000 )
+ nRow |= 0xE000;
+ else
+ nRow &= 0x1FFF;
+ break;
+ default:
+ DBG_ERROR( "*LotusToSc::LotusRelToScRel(): etwas vergessen...?" );
+ }
+ }
+ else
+ {
+ rSRD.SetRowRel( FALSE );
+ switch( eTyp )
+ {
+ // 5432 1098 7654 3210
+ // 8421 8421 8421 8421
+ // xxx xxxx xxxx
+ case eWK_1:
+ nRow &= 0x07FF;
+ break;
+ // 8421 8421 8421 8421
+ // xx xxxx xxxx xxxx
+ case eWK_2:
+ nRow &= 0x3FFF;
+ break;
+ default:
+ DBG_ERROR( "*LotusToSc::LotusRelToScRel(): etwas vergessen...?" );
+ }
+ }
+
+ if( rSRD.IsRowRel() )
+ // #i36252# first cast unsigned 16-bit to signed 16-bit, and then to SCsROW
+ rSRD.nRelRow = static_cast< SCsROW >( static_cast< sal_Int16 >( nRow ) );
+ else
+ rSRD.nRow = static_cast< SCsROW >( nRow );
+
+ if( rSRD.IsRowRel() || rSRD.IsColRel() )
+ rSRD.CalcAbsIfRel( aEingPos );
+}
+
+
+void LotusToSc::ReadSRD( ScSingleRefData& rSRD, BYTE nRelBit )
+{
+ BYTE nTab, nCol;
+ UINT16 nRow;
+
+ Read( nRow );
+ Read( nTab );
+ Read( nCol );
+
+ BOOL b3D = ( static_cast< SCTAB >( nTab ) != aEingPos.Tab() );
+
+ rSRD.SetColRel( ( nRelBit & 0x01 ) != 0 );
+ rSRD.nCol = static_cast< SCsCOL >( nCol );
+
+ rSRD.SetRowRel( ( nRelBit & 0x02 ) != 0 );
+ rSRD.nRow = static_cast< SCsROW >( nRow );
+
+ rSRD.SetTabRel( ( ( nRelBit & 0x04) != 0 ) || !b3D );
+ rSRD.nTab = static_cast< SCsTAB >( nTab );
+
+ rSRD.SetFlag3D( b3D );
+
+ rSRD.CalcRelFromAbs( aEingPos );
+}
+
+
+void LotusToSc::IncToken( TokenId &rParam )
+{
+ aPool << ocOpen << rParam << nAddToken;
+ rParam = aPool.Store();
+}
+
+
+void LotusToSc::DecToken( TokenId &rParam )
+{
+ aPool << ocOpen << rParam << nSubToken;
+ rParam = aPool.Store();
+}
+
+
+void LotusToSc::NegToken( TokenId &rParam )
+{
+ aPool << ocNegSub << ocOpen << rParam << ocClose;
+ rParam = aPool.Store();
+}
+
+
+void LotusToSc::Reset( const ScAddress& rEingPos )
+{
+ LotusConverterBase::Reset( rEingPos );
+
+ TokenId nEins = aPool.Store( 1.0 );
+
+ aPool << ocClose << ocAdd << nEins;
+ nAddToken = aPool.Store();
+
+ aPool << ocClose << ocSub << nEins;
+ nSubToken = aPool.Store();
+
+ n0Token = aPool.Store( 0.0 );
+}
+
+
+LotusToSc::LotusToSc( SvStream &rStream, CharSet e, BOOL b ) :
+ LotusConverterBase( rStream, 128 )
+{
+ eSrcChar = e;
+ bWK3 = FALSE;
+ bWK123 = b;
+}
+
+
+typedef FUNC_TYPE ( FuncType1 ) ( BYTE );
+typedef DefTokenId ( FuncType2 ) ( BYTE );
+
+
+ConvErr LotusToSc::Convert( const ScTokenArray*& rpErg, INT32& rRest,
+ const FORMULA_TYPE /*eFT*/ )
+{
+ BYTE nOc;
+ BYTE nAnz;
+ BYTE nRelBits;
+ UINT16 nStrLen;
+ UINT16 nRngIndex;
+ FUNC_TYPE eType = FT_NOP;
+ TokenId nMerk0;
+ DefTokenId eOc;
+ const sal_Char* pExtName = 0;
+ RangeNameBufferWK3& rRangeNameBufferWK3 = *pLotusRoot->pRngNmBffWK3;
+
+ ScComplexRefData aCRD;
+ aCRD.InitFlags();
+ ScSingleRefData& rR = aCRD.Ref1;
+
+ LR_ID nId;
+ TokenId nNewId;
+
+ LotusRangeList& rRangeList = *pLotusRoot->pRangeNames;
+
+ FuncType1* pIndexToType;
+ FuncType2* pIndexToToken;
+
+ if( bWK3 )
+ { // for > WK3
+ pIndexToType = IndexToTypeWK123;
+ pIndexToToken = IndexToTokenWK123;
+ }
+ else if( bWK123 )
+ {
+ pIndexToType = IndexToTypeWK123;
+ pIndexToToken = IndexToTokenWK123;
+ }
+ else
+ {
+ pIndexToType = IndexToType;
+ pIndexToToken = IndexToToken;
+
+ rR.SetTabRel( TRUE );
+ rR.nTab = aEingPos.Tab();
+ rR.nRelTab = 0;
+ rR.SetFlag3D( FALSE );
+ }
+
+ aCRD.Ref2 = rR;
+
+ nBytesLeft = rRest;
+
+ while( eType ) // != FT_Return (==0)
+ {
+ Read( nOc );
+
+ if( nBytesLeft < 0 )
+ {
+ rpErg = aPool[ aStack.Get() ];
+ return ConvErrCount;
+ }
+
+ eType = ( pIndexToType )( nOc );
+ eOc = ( pIndexToToken)( nOc );
+ if( eOc == ocNoName )
+ pExtName = GetAddInName( nOc );
+
+ switch( eType )
+ {
+ case FT_Return:
+ if( bWK3 || bWK123 )
+ nBytesLeft = 0; // wird ab WK3 nicht benutzt
+
+ rRest = nBytesLeft;
+ break;
+ case FT_NotImpl:
+ case FT_FuncFix0: DoFunc( eOc, 0, pExtName ); break;
+ case FT_FuncFix1: DoFunc( eOc, 1, pExtName ); break;
+ case FT_FuncFix2: DoFunc( eOc, 2, pExtName ); break;
+ case FT_FuncFix3: DoFunc( eOc, 3, pExtName ); break;
+ case FT_FuncFix4: DoFunc( eOc, 4, pExtName ); break;
+ case FT_FuncVar:
+ Read( nAnz );
+ DoFunc( eOc, nAnz, pExtName );
+ break;
+ case FT_Neg:
+ aPool << ocOpen << ocNegSub << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case FT_Op:
+ aStack >> nMerk0;
+ aPool << aStack << eOc << nMerk0;
+ aPool >> aStack;
+ break;
+ case FT_ConstFloat:
+ {
+ double fDouble;
+ Read( fDouble );
+ aStack << aPool.Store( fDouble );
+ }
+ break;
+ case FT_Variable:
+ {
+ UINT16 nCol, nRow;
+ Read( nCol );
+ Read( nRow );
+
+ LotusRelToScRel( nCol, nRow, rR );
+
+ if( bWK3 )
+ nNewId = aPool.Store( rR );
+ else
+ {
+ nId = rRangeList.GetIndex( rR.nCol, rR.nRow );
+
+ if( nId == ID_FAIL )
+ // kein Range dazu
+ nNewId = aPool.Store( rR );
+ else
+ nNewId = aPool.Store( ( UINT16 ) nId );
+ }
+
+ aStack << nNewId;
+ }
+ break;
+ case FT_Range:
+ {
+ UINT16 nColS, nRowS, nColE, nRowE;
+ Read( nColS );
+ Read( nRowS );
+ Read( nColE );
+ Read( nRowE );
+
+ LotusRelToScRel( nColS, nRowS, rR );
+ LotusRelToScRel( nColE, nRowE, aCRD.Ref2 );
+
+ if( bWK3 )
+ nNewId = aPool.Store( aCRD );
+ else
+ {
+ nId = rRangeList.GetIndex(
+ rR.nCol, rR.nRow, aCRD.Ref2.nCol, aCRD.Ref2.nRow );
+
+ if( nId == ID_FAIL )
+ // kein Range dazu
+ nNewId = aPool.Store( aCRD );
+ else
+ nNewId = aPool.Store( ( UINT16 ) nId );
+ }
+
+ aStack << nNewId;
+ }
+ break;
+ case FT_Braces:
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case FT_ConstInt:
+ {
+ INT16 nVal;
+ Read( nVal );
+ aStack << aPool.Store( ( double ) nVal );
+ }
+ break;
+ case FT_ConstString:
+ {
+ String aTmp( ScfTools::ReadCString( aIn, nBytesLeft, eSrcChar ) );
+
+ aStack << aPool.Store( aTmp );
+ }
+ break;
+ case FT_NOP:
+ break;
+ // ------------------------------------------ fuer > WK3 -
+ case FT_Cref:
+ Read( nRelBits );
+ ReadSRD( rR, nRelBits );
+ aStack << aPool.Store( rR );
+ break;
+ case FT_Rref:
+ Read( nRelBits );
+ ReadCRD( aCRD, nRelBits );
+ aStack << aPool.Store( aCRD );
+ break;
+ case FT_Nrref:
+ {
+ String aTmp( ScfTools::ReadCString( aIn, nBytesLeft, eSrcChar ) );
+ if( rRangeNameBufferWK3.FindRel( aTmp, nRngIndex ) )
+ aStack << aPool.Store( nRngIndex );
+ else
+ {
+ String aText( RTL_CONSTASCII_USTRINGPARAM( "NRREF " ) );
+ aText += aTmp;
+ aStack << aPool.Store( aText );
+ }
+ }
+ break;
+ case FT_Absnref:
+ {
+ String aTmp( ScfTools::ReadCString( aIn, nBytesLeft, eSrcChar ) );
+ if( rRangeNameBufferWK3.FindAbs( aTmp, nRngIndex ) )
+ aStack << aPool.Store( nRngIndex );
+ else
+ {
+ String aText( RTL_CONSTASCII_USTRINGPARAM( "ABSNREF " ) );
+ aText += aTmp;
+ aStack << aPool.Store( aText );
+ }
+ }
+ break;
+ case FT_Erref:
+ Ignore( 4 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case FT_Ecref:
+ Ignore( 5 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case FT_Econstant:
+ Ignore( 10 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case FT_Splfunc:
+ {
+ Read( nAnz );
+ Read( nStrLen );
+
+ if( nStrLen )
+ {
+// String t( ReadString( aIn, nStrLen, eSrcChar ) );
+ sal_Char* p = new sal_Char[ nStrLen + 1 ];
+ aIn.Read( p, nStrLen );
+ p[ nStrLen ] = 0x00;
+
+ DoFunc( ocNoName, nAnz, p );
+
+ delete[] p;
+ }
+ else
+ DoFunc( ocNoName, nAnz, NULL );
+ }
+ break;
+ case FT_Const10Float:
+ if ( bWK123 )
+ {
+ double fValue;
+ Read( fValue );
+ aStack << aPool.Store( fValue );
+ }
+ else aStack << aPool.Store( ScfTools::ReadLongDouble( aIn ) );
+ break;
+ case FT_Snum:
+ if ( bWK123 )
+ {
+ UINT32 nValue;
+
+ Read( nValue );
+ double fValue = Snum32ToDouble( nValue );
+ aStack << aPool.Store( fValue );
+ }
+ else
+ {
+ INT16 nVal;
+ Read( nVal );
+ aStack << aPool.Store( SnumToDouble( nVal ) );
+ }
+ break;
+ default:
+ DBG_ERROR( "*LotusToSc::Convert(): unbekannter enum!" );
+ }
+ }
+
+ rpErg = aPool[ aStack.Get() ];
+
+ DBG_ASSERT( nBytesLeft >= 0, "*LotusToSc::Convert(): zuviel verarbeitet!");
+ DBG_ASSERT( nBytesLeft <= 0, "*LotusToSc::Convert(): wat is mit'm Rest?" );
+
+ if( rRest )
+ aIn.SeekRel( nBytesLeft ); // eventuellen Rest/Ueberlauf korrigieren
+
+ rRest = 0;
+
+ return ConvOK;
+}
+
+
+FUNC_TYPE LotusToSc::IndexToType( BYTE nIndex )
+{
+ static const FUNC_TYPE pType[ 256 ] =
+ { // Code Bezeichnung
+ FT_ConstFloat, // 0 8-Byte-IEEE-Float
+ FT_Variable, // 1 Variable
+ FT_Range, // 2 Bereich
+ FT_Return, // 3 return
+ FT_Braces, // 4 Klammer
+ FT_ConstInt, // 5 2-Byte-Integer
+ FT_ConstString, // 6 ASCII-String
+ FT_NOP, // 7 NOP
+ FT_Neg, // 8 Negation
+ FT_Op, // 9 Addition
+ FT_Op, // 10 Subtraktion
+ FT_Op, // 11 Multiplikation
+ FT_Op, // 12 Division
+ FT_Op, // 13 Potenzierung
+ FT_Op, // 14 Gleichheit
+ FT_Op, // 15 Ungleich
+ FT_Op, // 16 Kleiner-gleich
+ FT_Op, // 17 Groesser-gleich
+ FT_Op, // 18 Kleiner
+ FT_Op, // 19 Groesser
+ FT_Op, // 20 And (logisch)
+ FT_Op, // 21 Or (logisch)
+ FT_FuncFix1, // 22 Not (logisch)
+ FT_NOP, // 23 unaeres Plus
+ FT_NotImpl, // 24
+ FT_NotImpl, // 25
+ FT_NotImpl, // 26
+ FT_NotImpl, // 27
+ FT_NotImpl, // 28
+ FT_NotImpl, // 29
+ FT_NotImpl, // 30
+ FT_FuncFix0, // 31 Not applicable
+ FT_FuncFix0, // 32 Error
+ FT_FuncFix1, // 33 Betrag ABS()
+ FT_FuncFix1, // 34 Ganzzahl INT()
+ FT_FuncFix1, // 35 Quadratwurzel
+ FT_FuncFix1, // 36 Zehnerlogarithmus
+ FT_FuncFix1, // 37 Natuerlicher Logarithmus
+ FT_FuncFix0, // 38 PI
+ FT_FuncFix1, // 39 Sinus
+ FT_FuncFix1, // 40 Cosinus
+ FT_FuncFix1, // 41 Tangens
+ FT_FuncFix2, // 42 Arcus-Tangens 2 (4.Quadrant) <----- richtig? -
+ FT_FuncFix1, // 43 Arcus-Tangens (2.Quadrant)
+ FT_FuncFix1, // 44 Arcus-Sinus
+ FT_FuncFix1, // 45 Arcus-Cosinus
+ FT_FuncFix1, // 46 Exponentialfunktion
+ FT_FuncFix2, // 47 Modulo
+ FT_FuncVar, // 48 Auswahl
+ FT_FuncFix1, // 49 Is not applicable?
+ FT_FuncFix1, // 50 Is Error?
+ FT_FuncFix0, // 51 FALSE
+ FT_FuncFix0, // 52 TRUE
+ FT_FuncFix0, // 53 Zufallszahl
+ FT_FuncFix3, // 54 Datum
+ FT_FuncFix0, // 55 Heute
+ FT_FuncFix3, // 56 Payment
+ FT_FuncFix3, // 57 Present Value
+ FT_FuncFix3, // 58 Future Value
+ FT_FuncFix3, // 59 If ... then ... else ...
+ FT_FuncFix1, // 60 Tag des Monats
+ FT_FuncFix1, // 61 Monat
+ FT_FuncFix1, // 62 Jahr
+ FT_FuncFix2, // 63 Runden
+ FT_FuncFix3, // 64 Zeit
+ FT_FuncFix1, // 65 Stunde
+ FT_FuncFix1, // 66 Minute
+ FT_FuncFix1, // 67 Sekunde
+ FT_FuncFix1, // 68 Ist Zahl?
+ FT_FuncFix1, // 69 Ist Text?
+ FT_FuncFix1, // 70 Len()
+ FT_FuncFix1, // 71 Val()
+ FT_FuncFix2, // 72 String()
+ FT_FuncFix3, // 73 Mid()
+ FT_FuncFix1, // 74 Char()
+ FT_FuncFix1, // 75 Ascii()
+ FT_FuncFix3, // 76 Find()
+ FT_FuncFix1, // 77 Datevalue
+ FT_FuncFix1, // 78 Timevalue
+ FT_FuncFix1, // 79 Cellpointer
+ FT_FuncVar, // 80 Sum()
+ FT_FuncVar, // 81 Avg()
+ FT_FuncVar, // 82 Cnt()
+ FT_FuncVar, // 83 Min()
+ FT_FuncVar, // 84 Max()
+ FT_FuncFix3, // 85 Vlookup()
+ FT_FuncFix2, // 86 Npv()
+ FT_FuncVar, // 87 Var()
+ FT_FuncVar, // 88 Std()
+ FT_FuncFix2, // 89 Irr()
+ FT_FuncFix3, // 90 Hlookup()
+ FT_FuncFix3, // 91 ?
+ FT_FuncFix3, // 92 ?
+ FT_FuncFix3, // 93 ?
+ FT_FuncFix3, // 94 ?
+ FT_FuncFix3, // 95 ?
+ FT_FuncFix3, // 96 ?
+ FT_FuncFix3, // 97 ?
+ FT_FuncFix3, // 98 Index() <- richtig? -
+ FT_FuncFix1, // 99 Cols()
+ FT_FuncFix1, // 100 Rows()
+ FT_FuncFix2, // 101 Repeat()
+ FT_FuncFix1, // 102 Upper()
+ FT_FuncFix1, // 103 Lower()
+ FT_FuncFix2, // 104 Left()
+ FT_FuncFix2, // 105 Right()
+ FT_FuncFix4, // 106 Replace()
+ FT_FuncFix1, // 107 Proper()
+ FT_FuncFix2, // 108 Cell()
+ FT_FuncFix1, // 109 Trim()
+ FT_FuncFix1, // 110 Clean()
+ FT_FuncFix1, // 111 F()
+ FT_FuncFix1, // 112 Wert() (oder W()?)
+ FT_FuncFix2, // 113 Exact()
+ FT_NotImpl, // 114 Call()
+ FT_FuncFix1, // 115 @@()
+ FT_FuncFix3, // 116 Rate()
+ FT_FuncFix1, // 117 Term()
+ FT_FuncFix1, // 118 Cterm()
+ FT_FuncFix3, // 119 Sln()
+ FT_FuncFix4, // 120 Syd(), Soy()
+ FT_FuncFix4, // 121 Ddb()
+ FT_NotImpl, // 122
+ FT_NotImpl, // 123
+ FT_NotImpl, // 124
+ FT_NotImpl, // 125
+ FT_NotImpl, // 126
+ FT_NotImpl, // 127
+ FT_NotImpl, // 128
+ FT_NotImpl, // 129
+ FT_NotImpl, // 130
+ FT_NotImpl, // 131
+ FT_NotImpl, // 132
+ FT_NotImpl, // 133
+ FT_NotImpl, // 134
+ FT_NotImpl, // 135
+ FT_NotImpl, // 136
+ FT_NotImpl, // 137
+ FT_NotImpl, // 138
+ FT_NotImpl, // 139
+ FT_NotImpl, // 140
+ FT_NotImpl, // 141
+ FT_NotImpl, // 142
+ FT_NotImpl, // 143
+ FT_NotImpl, // 144
+ FT_NotImpl, // 145
+ FT_NotImpl, // 146
+ FT_NotImpl, // 147
+ FT_NotImpl, // 148
+ FT_NotImpl, // 149
+ FT_NotImpl, // 150
+ FT_NotImpl, // 151
+ FT_NotImpl, // 152
+ FT_NotImpl, // 153
+ FT_NotImpl, // 154
+ FT_NotImpl, // 155
+ FT_FuncVar, // 156 ?
+ FT_NotImpl, // 157
+ FT_NotImpl, // 158
+ FT_NotImpl, // 159
+ FT_NotImpl, // 160
+ FT_NotImpl, // 161
+ FT_NotImpl, // 162
+ FT_NotImpl, // 163
+ FT_NotImpl, // 164
+ FT_NotImpl, // 165
+ FT_NotImpl, // 166
+ FT_NotImpl, // 167
+ FT_NotImpl, // 168
+ FT_NotImpl, // 169
+ FT_NotImpl, // 170
+ FT_NotImpl, // 171
+ FT_NotImpl, // 172
+ FT_NotImpl, // 173
+ FT_NotImpl, // 174
+ FT_NotImpl, // 175
+ FT_NotImpl, // 176
+ FT_NotImpl, // 177
+ FT_NotImpl, // 178
+ FT_NotImpl, // 179
+ FT_NotImpl, // 180
+ FT_NotImpl, // 181
+ FT_NotImpl, // 182
+ FT_NotImpl, // 183
+ FT_NotImpl, // 184
+ FT_NotImpl, // 185
+ FT_NotImpl, // 186
+ FT_NotImpl, // 187
+ FT_NotImpl, // 188
+ FT_NotImpl, // 189
+ FT_NotImpl, // 190
+ FT_NotImpl, // 191
+ FT_NotImpl, // 192
+ FT_NotImpl, // 193
+ FT_NotImpl, // 194
+ FT_NotImpl, // 195
+ FT_NotImpl, // 196
+ FT_NotImpl, // 197
+ FT_NotImpl, // 198
+ FT_NotImpl, // 199
+ FT_NotImpl, // 200
+ FT_NotImpl, // 201
+ FT_NotImpl, // 202
+ FT_NotImpl, // 203
+ FT_NotImpl, // 204
+ FT_NotImpl, // 205
+ FT_FuncVar, // 206 ?
+ FT_NotImpl, // 207
+ FT_NotImpl, // 208
+ FT_NotImpl, // 209
+ FT_NotImpl, // 210
+ FT_NotImpl, // 211
+ FT_NotImpl, // 212
+ FT_NotImpl, // 213
+ FT_NotImpl, // 214
+ FT_NotImpl, // 215
+ FT_NotImpl, // 216
+ FT_NotImpl, // 217
+ FT_NotImpl, // 218
+ FT_NotImpl, // 219
+ FT_NotImpl, // 220
+ FT_NotImpl, // 221
+ FT_NotImpl, // 222
+ FT_NotImpl, // 223
+ FT_NotImpl, // 224
+ FT_NotImpl, // 225
+ FT_NotImpl, // 226
+ FT_NotImpl, // 227
+ FT_NotImpl, // 228
+ FT_NotImpl, // 229
+ FT_NotImpl, // 230
+ FT_NotImpl, // 231
+ FT_NotImpl, // 232
+ FT_NotImpl, // 233
+ FT_NotImpl, // 234
+ FT_NotImpl, // 235
+ FT_NotImpl, // 236
+ FT_NotImpl, // 237
+ FT_NotImpl, // 238
+ FT_NotImpl, // 239
+ FT_NotImpl, // 240
+ FT_NotImpl, // 241
+ FT_NotImpl, // 242
+ FT_NotImpl, // 243
+ FT_NotImpl, // 244
+ FT_NotImpl, // 245
+ FT_NotImpl, // 246
+ FT_NotImpl, // 247
+ FT_NotImpl, // 248
+ FT_NotImpl, // 249
+ FT_NotImpl, // 250
+ FT_NotImpl, // 251
+ FT_NotImpl, // 252
+ FT_NotImpl, // 253
+ FT_NotImpl, // 254
+ FT_FuncVar, // 255 ?
+ };
+ return pType[ nIndex ];
+}
+
+
+DefTokenId LotusToSc::IndexToToken( BYTE nIndex )
+{
+ static const DefTokenId pToken[ 256 ] =
+ { // Code Bezeichnung
+ ocPush, // 0 8-Byte-IEEE-Float
+ ocPush, // 1 Variable
+ ocPush, // 2 Bereich
+ ocPush, // 3 return
+ ocPush, // 4 Klammer
+ ocPush, // 5 2-Byte-Integer
+ ocPush, // 6 ASCII-String
+ ocPush, // 7 NOP
+ ocNegSub, // 8 Negation
+ ocAdd, // 9 Addition
+ ocSub, // 10 Subtraktion
+ ocMul, // 11 Multiplikation
+ ocDiv, // 12 Division
+ ocPow, // 13 Potenzierung
+ ocEqual, // 14 Gleichheit
+ ocNotEqual, // 15 Ungleich
+ ocLessEqual, // 16 Kleiner-gleich
+ ocGreaterEqual, // 17 Groesser-gleich
+ ocLess, // 18 Kleiner
+ ocGreater, // 19 Groesser
+ ocAnd, // 20 And (logisch)
+ ocOr, // 21 Or (logisch)
+ ocNot, // 22 Not (logisch)
+ ocPush, // 23 unaeres Plus
+ ocNoName, // 24
+ ocNoName, // 25
+ ocNoName, // 26
+ ocNoName, // 27
+ ocNoName, // 28
+ ocNoName, // 29
+ ocNoName, // 30
+ ocNotAvail, // 31 Not available
+ ocNoName, // 32 Error
+ ocAbs, // 33 Betrag ABS()
+ ocInt, // 34 Ganzzahl INT()
+ ocSqrt, // 35 Quadratwurzel
+ ocLog10, // 36 Zehnerlogarithmus
+ ocLn, // 37 Natuerlicher Logarithmus
+ ocPi, // 38 PI
+ ocSin, // 39 Sinus
+ ocCos, // 40 Cosinus
+ ocTan, // 41 Tangens
+ ocArcTan2, // 42 Arcus-Tangens 2 (4.Quadrant)
+ ocArcTan, // 43 Arcus-Tangens (2.Quadrant)
+ ocArcSin, // 44 Arcus-Sinus
+ ocArcCos, // 45 Arcus-Cosinus
+ ocExp, // 46 Exponentialfunktion
+ ocMod, // 47 Modulo
+ ocChose, // 48 Auswahl
+ ocIsNA, // 49 Is not available?
+ ocIsError, // 50 Is Error?
+ ocFalse, // 51 FALSE
+ ocTrue, // 52 TRUE
+ ocRandom, // 53 Zufallszahl
+ ocGetDate, // 54 Datum
+ ocGetActDate, // 55 Heute
+ ocRMZ, // 56 Payment
+ ocBW, // 57 Present Value
+ ocZW, // 58 Future Value
+ ocIf, // 59 If ... then ... else ...
+ ocGetDay, // 60 Tag des Monats
+ ocGetMonth, // 61 Monat
+ ocGetYear, // 62 Jahr
+ ocRound, // 63 Runden
+ ocGetTime, // 64 Zeit
+ ocGetHour, // 65 Stunde
+ ocGetMin, // 66 Minute
+ ocGetSec, // 67 Sekunde
+ ocIsValue, // 68 Ist Zahl?
+ ocIsString, // 69 Ist Text?
+ ocLen, // 70 Len()
+ ocValue, // 71 Val()
+ ocFixed, // 72 String() ocFixed ersatzweise + Spezialfall
+ ocMid, // 73 Mid()
+ ocChar, // 74 Char()
+ ocCode, // 75 Ascii()
+ ocFind, // 76 Find()
+ ocGetDateValue, // 77 Datevalue
+ ocGetTimeValue, // 78 Timevalue
+ ocNoName, // 79 Cellpointer
+ ocSum, // 80 Sum()
+ ocAverage, // 81 Avg()
+ ocCount, // 82 Cnt()
+ ocMin, // 83 Min()
+ ocMax, // 84 Max()
+ ocVLookup, // 85 Vlookup()
+ ocNPV, // 86 Npv()
+ ocVar, // 87 Var()
+ ocNormDist, // 88 Std()
+ ocIRR, // 89 Irr()
+ ocHLookup, // 90 Hlookup()
+ ocDBSum, // 91 XlfDsum
+ ocDBAverage, // 92 XlfDaverage
+ ocDBCount, // 93 XlfDcount
+ ocDBMin, // 94 XlfDmin
+ ocDBMax, // 95 XlfDmax
+ ocDBVar, // 96 XlfDvar
+ ocDBStdDev, // 97 XlfDstdev
+ ocIndex, // 98 Index()
+ ocColumns, // 99 Cols()
+ ocRows, // 100 Rows()
+ ocRept, // 101 Repeat()
+ ocUpper, // 102 Upper()
+ ocLower, // 103 Lower()
+ ocLeft, // 104 Left()
+ ocRight, // 105 Right()
+ ocReplace, // 106 Replace()
+ ocPropper, // 107 Proper()
+ ocNoName, // 108 Cell()
+ ocTrim, // 109 Trim()
+ ocClean, // 110 Clean()
+ ocFalse, // 111 F()
+ ocTrue, // 112 W()
+ ocExact, // 113 Exact()
+ ocNoName, // 114 Call()
+ ocIndirect, // 115 @@()
+ ocZins, // 116 Rate()
+ ocNoName, // 117 Term()
+ ocNoName, // 118 Cterm()
+ ocLIA, // 119 Sln()
+ ocDIA, // 120 Syd(), Soy()
+ ocGDA, // 121 Ddb()
+ ocNoName, // 122
+ ocNoName, // 123
+ ocNoName, // 124
+ ocNoName, // 125
+ ocNoName, // 126
+ ocNoName, // 127
+ ocNoName, // 128
+ ocNoName, // 129
+ ocNoName, // 130
+ ocNoName, // 131
+ ocNoName, // 132
+ ocNoName, // 133
+ ocNoName, // 134
+ ocNoName, // 135
+ ocNoName, // 136
+ ocNoName, // 137
+ ocNoName, // 138
+ ocNoName, // 139
+ ocNoName, // 140
+ ocNoName, // 141
+ ocNoName, // 142
+ ocNoName, // 143
+ ocNoName, // 144
+ ocNoName, // 145
+ ocNoName, // 146
+ ocNoName, // 147
+ ocNoName, // 148
+ ocNoName, // 149
+ ocNoName, // 150
+ ocNoName, // 151
+ ocNoName, // 152
+ ocNoName, // 153
+ ocNoName, // 154
+ ocNoName, // 155
+ ocNoName, // 156 ?
+ ocNoName, // 157
+ ocNoName, // 158
+ ocNoName, // 159
+ ocNoName, // 160
+ ocNoName, // 161
+ ocNoName, // 162
+ ocNoName, // 163
+ ocNoName, // 164
+ ocNoName, // 165
+ ocNoName, // 166
+ ocNoName, // 167
+ ocNoName, // 168
+ ocNoName, // 169
+ ocNoName, // 170
+ ocNoName, // 171
+ ocNoName, // 172
+ ocNoName, // 173
+ ocNoName, // 174
+ ocNoName, // 175
+ ocNoName, // 176
+ ocNoName, // 177
+ ocNoName, // 178
+ ocNoName, // 179
+ ocNoName, // 180
+ ocNoName, // 181
+ ocNoName, // 182
+ ocNoName, // 183
+ ocNoName, // 184
+ ocNoName, // 185
+ ocNoName, // 186
+ ocNoName, // 187
+ ocNoName, // 188
+ ocNoName, // 189
+ ocNoName, // 190
+ ocNoName, // 191
+ ocNoName, // 192
+ ocNoName, // 193
+ ocNoName, // 194
+ ocNoName, // 195
+ ocNoName, // 196
+ ocNoName, // 197
+ ocNoName, // 198
+ ocNoName, // 199
+ ocNoName, // 200
+ ocNoName, // 201
+ ocNoName, // 202
+ ocNoName, // 203
+ ocNoName, // 204
+ ocNoName, // 205
+ ocNoName, // 206 ?
+ ocNoName, // 207
+ ocNoName, // 208
+ ocNoName, // 209
+ ocNoName, // 210
+ ocNoName, // 211
+ ocNoName, // 212
+ ocNoName, // 213
+ ocNoName, // 214
+ ocNoName, // 215
+ ocNoName, // 216
+ ocNoName, // 217
+ ocNoName, // 218
+ ocNoName, // 219
+ ocNoName, // 220
+ ocNoName, // 221
+ ocNoName, // 222
+ ocNoName, // 223
+ ocNoName, // 224
+ ocNoName, // 225
+ ocNoName, // 226
+ ocNoName, // 227
+ ocNoName, // 228
+ ocNoName, // 229
+ ocNoName, // 230
+ ocNoName, // 231
+ ocNoName, // 232
+ ocNoName, // 233
+ ocNoName, // 234
+ ocNoName, // 235
+ ocNoName, // 236
+ ocNoName, // 237
+ ocNoName, // 238
+ ocNoName, // 239
+ ocNoName, // 240
+ ocNoName, // 241
+ ocNoName, // 242
+ ocNoName, // 243
+ ocNoName, // 244
+ ocNoName, // 245
+ ocNoName, // 246
+ ocNoName, // 247
+ ocNoName, // 248
+ ocNoName, // 249
+ ocNoName, // 250
+ ocNoName, // 251
+ ocNoName, // 252
+ ocNoName, // 253
+ ocNoName, // 254
+ ocNoName // 255 ?
+ };
+
+ return pToken[ nIndex ];
+}
+
+
+FUNC_TYPE LotusToSc::IndexToTypeWK123( BYTE nIndex )
+{
+ static const FUNC_TYPE pType[ 256 ] =
+ { // Code Bezeichnung
+ FT_Const10Float, // 0 8-Byte-IEEE-Long-Number
+ FT_Cref, // 1 Cell Reference
+ FT_Rref, // 2 Area Reference
+ FT_Return, // 3 return
+ FT_Braces, // 4 Klammer
+ FT_Snum, // 5 Short-Number
+ FT_ConstString, // 6 ASCII-String
+ FT_Nrref, // 7 Named range reference
+ FT_Absnref, // 8 Absolut named range
+ FT_Erref, // 9 Err range reference
+ FT_Ecref, // 10 Err cell reference
+ FT_Econstant, // 11 Err constant
+ FT_NotImpl, // 12
+ FT_NotImpl, // 13
+ FT_Neg, // 14 Negation
+ FT_Op, // 15 Addition
+ FT_Op, // 16 Subtraktion
+ FT_Op, // 17 Multiplikation
+ FT_Op, // 18 Division
+ FT_Op, // 19 Potenzierung
+ FT_Op, // 20 Gleichheit
+ FT_Op, // 21 Ungleich
+ FT_Op, // 22 Kleiner-gleich
+ FT_Op, // 23 Groesser-gleich
+ FT_Op, // 24 Kleiner
+ FT_Op, // 25 Groesser
+ FT_Op, // 26 And (logisch)
+ FT_Op, // 27 Or (logisch)
+ FT_FuncFix1, // 28 Not (logisch)
+ FT_NOP, // 29 unaeres Plus
+ FT_Op, // 30 Concatenation
+ FT_FuncFix0, // 31 Not applicable
+ FT_FuncFix0, // 32 Error
+ FT_FuncFix1, // 33 Betrag ABS()
+ FT_FuncFix1, // 34 Ganzzahl INT()
+ FT_FuncFix1, // 35 Quadratwurzel
+ FT_FuncFix1, // 36 Zehnerlogarithmus
+ FT_FuncFix1, // 37 Natuerlicher Logarithmus
+ FT_FuncFix0, // 38 PI
+ FT_FuncFix1, // 39 Sinus
+ FT_FuncFix1, // 40 Cosinus
+ FT_FuncFix1, // 41 Tangens
+ FT_FuncFix2, // 42 Arcus-Tangens 2 (4.Quadrant)
+ FT_FuncFix1, // 43 Arcus-Tangens (2.Quadrant)
+ FT_FuncFix1, // 44 Arcus-Sinus
+ FT_FuncFix1, // 45 Arcus-Cosinus
+ FT_FuncFix1, // 46 Exponentialfunktion
+ FT_FuncFix2, // 47 Modulo
+ FT_FuncVar, // 48 Auswahl
+ FT_FuncFix1, // 49 Is not applicable?
+ FT_FuncFix1, // 50 Is Error?
+ FT_FuncFix0, // 51 FALSE
+ FT_FuncFix0, // 52 TRUE
+ FT_FuncFix0, // 53 Zufallszahl
+ FT_FuncFix3, // 54 Datum
+ FT_FuncFix0, // 55 Heute
+ FT_FuncFix3, // 56 Payment
+ FT_FuncFix3, // 57 Present Value
+ FT_FuncFix3, // 58 Future Value
+ FT_FuncFix3, // 59 If ... then ... else ...
+ FT_FuncFix1, // 60 Tag des Monats
+ FT_FuncFix1, // 61 Monat
+ FT_FuncFix1, // 62 Jahr
+ FT_FuncFix2, // 63 Runden
+ FT_FuncFix3, // 64 Zeit
+ FT_FuncFix1, // 65 Stunde
+ FT_FuncFix1, // 66 Minute
+ FT_FuncFix1, // 67 Sekunde
+ FT_FuncFix1, // 68 Ist Zahl?
+ FT_FuncFix1, // 69 Ist Text?
+ FT_FuncFix1, // 70 Len()
+ FT_FuncFix1, // 71 Val()
+ FT_FuncFix2, // 72 String()
+ FT_FuncFix3, // 73 Mid()
+ FT_FuncFix1, // 74 Char()
+ FT_FuncFix1, // 75 Ascii()
+ FT_FuncFix3, // 76 Find()
+ FT_FuncFix1, // 77 Datevalue
+ FT_FuncFix1, // 78 Timevalue
+ FT_FuncFix1, // 79 Cellpointer
+ FT_FuncVar, // 80 Sum()
+ FT_FuncVar, // 81 Avg()
+ FT_FuncVar, // 82 Cnt()
+ FT_FuncVar, // 83 Min()
+ FT_FuncVar, // 84 Max()
+ FT_FuncFix3, // 85 Vlookup()
+ FT_FuncFix2, // 86 Npv()
+ FT_FuncVar, // 87 Var()
+ FT_FuncVar, // 88 Std()
+ FT_FuncFix2, // 89 Irr()
+ FT_FuncFix3, // 90 Hlookup()
+ FT_FuncVar, // 91 Dsum <-------- neu! -
+ FT_FuncVar, // 92 Davg <-------- neu! -
+ FT_FuncVar, // 93 Dcnt <-------- neu! -
+ FT_FuncVar, // 94 Dmin <-------- neu! -
+ FT_FuncVar, // 95 Dmax <-------- neu! -
+ FT_FuncVar, // 96 Dvar <-------- neu! -
+ FT_FuncVar, // 97 Dstd <-------- neu! -
+ FT_FuncVar, // 98 Index() <-------- change! -
+ FT_FuncFix1, // 99 Cols() <-------- neu! -
+ FT_FuncFix1, // 100 Rows() <-------- neu! -
+ FT_FuncFix2, // 101 Repeat() <-------- neu! -
+ FT_FuncFix1, // 102 Upper() <-------- neu! -
+ FT_FuncFix1, // 103 Lower() <-------- neu! -
+ FT_FuncFix2, // 104 Left() <-------- neu! -
+ FT_FuncFix2, // 105 Right() <-------- neu! -
+ FT_FuncFix4, // 106 Replace() <-------- neu! -
+ FT_FuncFix1, // 107 Proper() <-------- neu! -
+ FT_FuncFix2, // 108 Cell() <-------- neu! -
+ FT_FuncFix1, // 109 Trim() <-------- neu! -
+ FT_FuncFix1, // 110 Clean() <-------- neu! -
+ FT_FuncFix1, // 111 S() <--------- change in Bez. -
+ FT_FuncFix1, // 112 N() <--------- change in Bez. -
+ FT_FuncFix2, // 113 Exact() <-------- neu! -
+ FT_NotImpl, // 114 App <--------- change in Bez. -
+ FT_FuncFix1, // 115 @@() <-------- neu! -
+ FT_FuncFix3, // 116 Rate() <-------- neu! -
+ FT_FuncFix3, // 117 Term() <--------- change in Anz.
+ FT_FuncFix3, // 118 Cterm() <--------- change in Anz.
+ FT_FuncFix3, // 119 Sln() <-------- neu! -
+ FT_FuncFix4, // 120 Syd() <-------- neu! -
+ FT_FuncFix4, // 121 Ddb() <-------- neu! -
+ FT_Splfunc, // 122 Splfunc <-------- neu! -
+ FT_FuncFix1, // 123 Sheets <-------- neu! -
+ FT_FuncFix1, // 124 Info <-------- neu! -
+ FT_FuncVar, // 125 Sumproduct <-------- neu! -
+ FT_FuncFix1, // 126 Isrange <-------- neu! -
+ FT_FuncVar, // 127 Dget <-------- neu! -
+ FT_FuncVar, // 128 Dquery <-------- neu! -
+ FT_FuncFix4, // 129 Coord <-------- neu! -
+ FT_NOP, // 130 Reserved (internal) <-------- neu! -
+ FT_FuncFix0, // 131 Today <-------- neu! -
+ FT_FuncVar, // 132 Vdb <-------- neu! -
+ FT_FuncVar, // 133 Dvars <-------- neu! -
+ FT_FuncVar, // 134 Dstds <-------- neu! -
+ FT_FuncVar, // 135 Vars <-------- neu! -
+ FT_FuncVar, // 136 Stds <-------- neu! -
+ FT_FuncFix2, // 137 D360 <-------- neu! -
+ FT_NOP, // 138 Reserved (internal) <-------- neu! -
+ FT_FuncFix0, // 139 Isapp <-------- neu! - Anzahl ? -
+ FT_FuncVar, // 140 Isaaf <-------- neu! - Anzahl ? -
+ FT_FuncFix1, // 141 Weekday <-------- neu! -
+ FT_FuncFix3, // 142 Datedif <-------- neu! -
+ FT_FuncVar, // 143 Rank <-------- neu! -
+ FT_FuncFix2, // 144 Numberstring <-------- neu! -
+ FT_FuncFix1, // 145 Datestring <-------- neu! -
+ FT_FuncFix1, // 146 Decimal <-------- neu! -
+ FT_FuncFix1, // 147 Hex <-------- neu! -
+ FT_FuncFix4, // 148 Db <-------- neu! -
+ FT_FuncFix4, // 149 Pmti <-------- neu! -
+ FT_FuncFix4, // 150 Spi <-------- neu! -
+ FT_FuncFix1, // 151 Fullp <-------- neu! -
+ FT_FuncFix1, // 152 Halfp <-------- neu! -
+ FT_FuncVar, // 153 Pureavg <-------- neu! -
+ FT_FuncVar, // 154 Purecount <-------- neu! -
+ FT_FuncVar, // 155 Puremax <-------- neu! -
+ FT_FuncVar, // 156 Puremin <-------- neu! -
+ FT_FuncVar, // 157 Purestd <-------- neu! -
+ FT_FuncVar, // 158 Purevar <-------- neu! -
+ FT_FuncVar, // 159 Purestds <-------- neu! -
+ FT_FuncVar, // 160 Purevars <-------- neu! -
+ FT_FuncFix3, // 161 Pmt2 <-------- neu! -
+ FT_FuncFix3, // 162 Pv2 <-------- neu! -
+ FT_FuncFix3, // 163 Fv2 <-------- neu! -
+ FT_FuncFix3, // 164 Term2 <-------- neu! -
+ FT_NotImpl, // 165 --- <-------- neu! - Anzahl ? -
+ FT_FuncFix2, // 166 D360 (US-Version)
+ FT_NotImpl, // 167
+ FT_NotImpl, // 168
+ FT_NotImpl, // 169
+ FT_NotImpl, // 170
+ FT_NotImpl, // 171
+ FT_NotImpl, // 172
+ FT_NotImpl, // 173
+ FT_NotImpl, // 174
+ FT_NotImpl, // 175
+ FT_NotImpl, // 176
+ FT_NotImpl, // 177
+ FT_NotImpl, // 178
+ FT_NotImpl, // 179
+ FT_NotImpl, // 180
+ FT_NotImpl, // 181
+ FT_NotImpl, // 182
+ FT_NotImpl, // 183
+ FT_NotImpl, // 184
+ FT_NotImpl, // 185
+ FT_FuncVar, // 186 Solver <-------- neu! -
+ FT_NotImpl, // 187
+ FT_NotImpl, // 188
+ FT_NotImpl, // 189
+ FT_NotImpl, // 190
+ FT_NotImpl, // 191
+ FT_NotImpl, // 192
+ FT_NotImpl, // 193
+ FT_NotImpl, // 194
+ FT_NotImpl, // 195
+ FT_NotImpl, // 196
+ FT_NotImpl, // 197
+ FT_NotImpl, // 198
+ FT_NotImpl, // 199
+ FT_NotImpl, // 200
+ FT_NotImpl, // 201
+ FT_NotImpl, // 202
+ FT_NotImpl, // 203
+ FT_NotImpl, // 204
+ FT_NotImpl, // 205
+ FT_NotImpl, // 206
+ FT_NotImpl, // 207
+ FT_NotImpl, // 208
+ FT_NotImpl, // 209
+ FT_NotImpl, // 210
+ FT_NotImpl, // 211
+ FT_NotImpl, // 212
+ FT_NotImpl, // 213
+ FT_NotImpl, // 214
+ FT_NotImpl, // 215
+ FT_NotImpl, // 216
+ FT_NotImpl, // 217
+ FT_NotImpl, // 218
+ FT_NotImpl, // 219
+ FT_NotImpl, // 220
+ FT_NotImpl, // 221
+ FT_NotImpl, // 222
+ FT_NotImpl, // 223
+ FT_NotImpl, // 224
+ FT_NotImpl, // 225
+ FT_NotImpl, // 226
+ FT_NotImpl, // 227
+ FT_NotImpl, // 228
+ FT_NotImpl, // 229
+ FT_NotImpl, // 230
+ FT_NotImpl, // 231
+ FT_NotImpl, // 232
+ FT_NotImpl, // 233
+ FT_NotImpl, // 234
+ FT_NotImpl, // 235
+ FT_NotImpl, // 236
+ FT_NotImpl, // 237
+ FT_NotImpl, // 238
+ FT_NotImpl, // 239
+ FT_NotImpl, // 240
+ FT_NotImpl, // 241
+ FT_NotImpl, // 242
+ FT_NotImpl, // 243
+ FT_NotImpl, // 244
+ FT_NotImpl, // 245
+ FT_NotImpl, // 246
+ FT_NotImpl, // 247
+ FT_NotImpl, // 248
+ FT_NotImpl, // 249
+ FT_NotImpl, // 250
+ FT_NotImpl, // 251
+ FT_NotImpl, // 252
+ FT_NotImpl, // 253
+ FT_NotImpl, // 254
+ FT_NotImpl, // 255
+ };
+ return pType[ nIndex ];
+}
+
+
+DefTokenId LotusToSc::IndexToTokenWK123( BYTE nIndex )
+{
+ static const DefTokenId pToken[ 256 ] =
+ { // Code Bezeichnung
+ ocPush, // 0 8-Byte-IEEE-Long-Numbers
+ ocPush, // 1 Variable
+ ocPush, // 2 Bereich
+ ocPush, // 3 return
+ ocPush, // 4 Klammer
+ ocPush, // 5 Numbers
+ ocPush, // 6 ASCII-String
+ ocPush, // 7 Named range reference
+ ocPush, // 8 Absolut named range
+ ocPush, // 9 Err range reference
+ ocPush, // 10 Err cell reference
+ ocPush, // 11 Err constant
+ ocPush, // 12
+ ocPush, // 13
+ ocNegSub, // 14 Negation
+ ocAdd, // 15 Addition
+ ocSub, // 16 Subtraktion
+ ocMul, // 17 Multiplikation
+ ocDiv, // 18 Division
+ ocPow, // 19 Potenzierung
+ ocEqual, // 20 Gleichheit
+ ocNotEqual, // 21 Ungleich
+ ocLessEqual, // 22 Kleiner-gleich
+ ocGreaterEqual, // 23 Groesser-gleich
+ ocLess, // 24 Kleiner
+ ocGreater, // 25 Groesser
+ ocAnd, // 26 And (logisch)
+ ocOr, // 27 Or (logisch)
+ ocNot, // 28 Not (logisch)
+ ocPush, // 29 unaeres Plus
+ ocAmpersand, // 30 Concatenation
+ ocNotAvail, // 31 Not available
+ ocNoName, // 32 Error
+ ocAbs, // 33 Betrag ABS()
+ ocInt, // 34 Ganzzahl INT()
+ ocSqrt, // 35 Quadratwurzel
+ ocLog10, // 36 Zehnerlogarithmus
+ ocLn, // 37 Natuerlicher Logarithmus
+ ocPi, // 38 PI
+ ocSin, // 39 Sinus
+ ocCos, // 40 Cosinus
+ ocTan, // 41 Tangens
+ ocArcTan2, // 42 Arcus-Tangens 2 (4.Quadrant)
+ ocArcTan, // 43 Arcus-Tangens (2.Quadrant)
+ ocArcSin, // 44 Arcus-Sinus
+ ocArcCos, // 45 Arcus-Cosinus
+ ocExp, // 46 Exponentialfunktion
+ ocMod, // 47 Modulo
+ ocChose, // 48 Auswahl
+ ocIsNA, // 49 Is not available?
+ ocIsError, // 50 Is Error?
+ ocFalse, // 51 FALSE
+ ocTrue, // 52 TRUE
+ ocRandom, // 53 Zufallszahl
+ ocGetDate, // 54 Datum
+ ocGetActDate, // 55 Heute
+ ocRMZ, // 56 Payment
+ ocBW, // 57 Present Value
+ ocZW, // 58 Future Value
+ ocIf, // 59 If ... then ... else ...
+ ocGetDay, // 60 Tag des Monats
+ ocGetMonth, // 61 Monat
+ ocGetYear, // 62 Jahr
+ ocRound, // 63 Runden
+ ocGetTime, // 64 Zeit
+ ocGetHour, // 65 Stunde
+ ocGetMin, // 66 Minute
+ ocGetSec, // 67 Sekunde
+ ocIsValue, // 68 Ist Zahl?
+ ocIsString, // 69 Ist Text?
+ ocLen, // 70 Len()
+ ocValue, // 71 Val()
+ ocFixed, // 72 String() ocFixed ersatzweise + Spezialfall
+ ocMid, // 73 Mid()
+ ocChar, // 74 Char()
+ ocCode, // 75 Ascii()
+ ocFind, // 76 Find()
+ ocGetDateValue, // 77 Datevalue
+ ocGetTimeValue, // 78 Timevalue
+ ocNoName, // 79 Cellpointer
+ ocSum, // 80 Sum()
+ ocAverage, // 81 Avg()
+ ocCount, // 82 Cnt()
+ ocMin, // 83 Min()
+ ocMax, // 84 Max()
+ ocVLookup, // 85 Vlookup()
+ ocNPV, // 86 Npv()
+ ocVar, // 87 Var()
+ ocStDev, // 88 Std()
+ ocIRR, // 89 Irr()
+ ocHLookup, // 90 Hlookup()
+ ocDBSum, // 91 XlfDsum
+ ocDBAverage, // 92 XlfDaverage
+ ocDBCount, // 93 XlfDcount
+ ocDBMin, // 94 XlfDmin
+ ocDBMax, // 95 XlfDmax
+ ocDBVar, // 96 XlfDvar
+ ocDBStdDev, // 97 XlfDstdev
+ ocIndex, // 98 Index()
+ ocColumns, // 99 Cols()
+ ocRows, // 100 Rows()
+ ocRept, // 101 Repeat()
+ ocUpper, // 102 Upper()
+ ocLower, // 103 Lower()
+ ocLeft, // 104 Left()
+ ocRight, // 105 Right()
+ ocReplace, // 106 Replace()
+ ocPropper, // 107 Proper()
+ ocNoName, // 108 Cell()
+ ocTrim, // 109 Trim()
+ ocClean, // 110 Clean()
+ ocNoName, // 111 F() (Excel: T()?)
+ ocNoName, // 112 W()
+ ocExact, // 113 Exact()
+ ocNoName, // 114 Call()
+ ocIndirect, // 115 @@()
+ ocZins, // 116 Rate()
+ ocNoName, // 117 Term()
+ ocNoName, // 118 Cterm()
+ ocLIA, // 119 Sln()
+ ocDIA, // 120 Syd(), Soy()
+ ocGDA, // 121 Ddb()
+ ocNoName, // 122 Splfunc
+ ocNoName, // 123 Sheets
+ ocNoName, // 124 Info
+ ocSumProduct, // 125 Sumproduct
+ ocNoName, // 126 Isrange
+ ocDBGet, // 127 Dget
+ ocNoName, // 128 Dquery
+ ocNoName, // 129 Coord
+ ocNoName, // 130 Reserved (internal)
+ ocGetActDate, // 131 Today
+ ocNoName, // 132 Vdb
+ ocDBVarP, // 133 Dvars
+ ocDBStdDevP, // 134 Dstds
+ ocVarP, // 135 Vars
+ ocStDevP, // 136 Stds
+ ocGetDiffDate360, // 137 D360
+ ocNoName, // 138 Reserved (internal)
+ ocNoName, // 139 Isapp
+ ocNoName, // 140 Isaaf
+ ocGetDayOfWeek, // 141 Weekday
+ ocGetDiffDate, // 142 Datedif
+ ocRank, // 143 Rank
+ ocNoName, // 144 Numberstring
+ ocNoName, // 145 Datestring
+ ocNoName, // 146 Decimal
+ ocNoName, // 147 Hex
+ ocNoName, // 148 Db
+ ocNoName, // 149 Pmti
+ ocNoName, // 150 Spi
+ ocNoName, // 151 Fullp
+ ocNoName, // 152 Halfp
+ ocNoName, // 153 Pureavg
+ ocCount2, // 154 Purecount
+ ocNoName, // 155 Puremax
+ ocNoName, // 156 Puremin
+ ocNoName, // 157 Purestd
+ ocNoName, // 158 Purevar
+ ocNoName, // 159 Purestds
+ ocNoName, // 160 Purevars
+ ocNoName, // 161 Pmt2
+ ocNoName, // 162 Pv2
+ ocNoName, // 163 Fv2
+ ocNoName, // 164 Term2
+ ocNoName, // 165 --- <-------- neu! - Anzahl ? -
+ ocGetDiffDate360, // 166 D360 (US-Version, ersatzweise wie ander D360-Funktion)
+ ocNoName, // 167
+ ocNoName, // 168
+ ocNoName, // 169
+ ocNoName, // 170
+ ocNoName, // 171
+ ocNoName, // 172
+ ocNoName, // 173
+ ocNoName, // 174
+ ocNoName, // 175
+ ocNoName, // 176
+ ocNoName, // 177
+ ocNoName, // 178
+ ocNoName, // 179
+ ocNoName, // 180
+ ocNoName, // 181
+ ocNoName, // 182
+ ocNoName, // 183
+ ocNoName, // 184
+ ocNoName, // 185
+ ocNoName, // 186
+ ocNoName, // 187
+ ocNoName, // 188
+ ocNoName, // 189
+ ocNoName, // 190
+ ocNoName, // 191
+ ocNoName, // 192
+ ocNoName, // 193
+ ocNoName, // 194
+ ocNoName, // 195
+ ocNoName, // 196
+ ocNoName, // 197
+ ocNoName, // 198
+ ocNoName, // 199
+ ocNoName, // 200
+ ocNoName, // 201
+ ocNoName, // 202
+ ocNoName, // 203
+ ocNoName, // 204
+ ocNoName, // 205
+ ocNoName, // 206 ?
+ ocNoName, // 207
+ ocNoName, // 208
+ ocNoName, // 209
+ ocNoName, // 210
+ ocNoName, // 211
+ ocNoName, // 212
+ ocNoName, // 213
+ ocNoName, // 214
+ ocNoName, // 215
+ ocNoName, // 216
+ ocNoName, // 217
+ ocNoName, // 218
+ ocNoName, // 219
+ ocNoName, // 220
+ ocNoName, // 221
+ ocNoName, // 222
+ ocNoName, // 223
+ ocNoName, // 224
+ ocNoName, // 225
+ ocNoName, // 226
+ ocNoName, // 227
+ ocNoName, // 228
+ ocNoName, // 229
+ ocNoName, // 230
+ ocNoName, // 231
+ ocNoName, // 232
+ ocNoName, // 233
+ ocNoName, // 234
+ ocNoName, // 235
+ ocNoName, // 236
+ ocNoName, // 237
+ ocNoName, // 238
+ ocNoName, // 239
+ ocNoName, // 240
+ ocNoName, // 241
+ ocNoName, // 242
+ ocNoName, // 243
+ ocNoName, // 244
+ ocNoName, // 245
+ ocNoName, // 246
+ ocNoName, // 247
+ ocNoName, // 248
+ ocNoName, // 249
+ ocNoName, // 250
+ ocNoName, // 251
+ ocNoName, // 252
+ ocNoName, // 253
+ ocNoName, // 254
+ ocNoName // 255 ?
+ };
+
+ return pToken[ nIndex ];
+}
+
+
+
+
+const sal_Char* GetAddInName( const UINT8 n )
+{
+ static const sal_Char* pNames[ 256 ] =
+ {
+ NULL, // 0 8-Byte-IEEE-Float
+ NULL, // 1 Variable
+ NULL, // 2 Bereich
+ NULL, // 3 return
+ NULL, // 4 Klammer
+ NULL, // 5 2-Byte-Integer
+ NULL, // 6 ASCII-String
+ NULL, // 7 Named range reference
+ NULL, // 8 Absolut named range
+ NULL, // 9 Err range reference
+ NULL, // 10 Err cell reference
+ NULL, // 11 Err constant
+ NULL, // 12
+ NULL, // 13
+ NULL, // 14 Negation
+ NULL, // 15 Addition
+ NULL, // 16 Subtraktion
+ NULL, // 17 Multiplikation
+ NULL, // 18 Division
+ NULL, // 19 Potenzierung
+ NULL, // 20 Gleichheit
+ NULL, // 21 Ungleich
+ NULL, // 22 Kleiner-gleich
+ NULL, // 23 Groesser-gleich
+ NULL, // 24 Kleiner
+ NULL, // 25 Groesser
+ NULL, // 26 And (logisch)
+ NULL, // 27 Or (logisch)
+ NULL, // 28 Not (logisch)
+ NULL, // 29 unaeres Plus
+ NULL, // 30 Concatenation
+ NULL, // 31 Not applicable
+ NULL, // 32 Error
+ NULL, // 33 Betrag ABS()
+ NULL, // 34 Ganzzahl INT()
+ NULL, // 35 Quadratwurzel
+ NULL, // 36 Zehnerlogarithmus
+ NULL, // 37 Natuerlicher Logarithmus
+ NULL, // 38 PI
+ NULL, // 39 Sinus
+ NULL, // 40 Cosinus
+ NULL, // 41 Tangens
+ NULL, // 42 Arcus-Tangens 2 (4.Quadrant)
+ NULL, // 43 Arcus-Tangens (2.Quadrant)
+ NULL, // 44 Arcus-Sinus
+ NULL, // 45 Arcus-Cosinus
+ NULL, // 46 Exponentialfunktion
+ NULL, // 47 Modulo
+ NULL, // 48 Auswahl
+ NULL, // 49 Is not applicable?
+ NULL, // 50 Is Error?
+ NULL, // 51 FALSE
+ NULL, // 52 TRUE
+ NULL, // 53 Zufallszahl
+ NULL, // 54 Datum
+ NULL, // 55 Heute
+ NULL, // 56 Payment
+ NULL, // 57 Present Value
+ NULL, // 58 Future Value
+ NULL, // 59 If ... then ... else ...
+ NULL, // 60 Tag des Monats
+ NULL, // 61 Monat
+ NULL, // 62 Jahr
+ NULL, // 63 Runden
+ NULL, // 64 Zeit
+ NULL, // 65 Stunde
+ NULL, // 66 Minute
+ NULL, // 67 Sekunde
+ NULL, // 68 Ist Zahl?
+ NULL, // 69 Ist Text?
+ NULL, // 70 Len()
+ NULL, // 71 Val()
+ NULL, // 72 String() ocFixed ersatzweise + Spezialfall
+ NULL, // 73 Mid()
+ NULL, // 74 Char()
+ NULL, // 75 Ascii()
+ NULL, // 76 Find()
+ NULL, // 77 Datevalue
+ NULL, // 78 Timevalue
+ "ZELLZEIGER", // 79 Cellpointer
+ NULL, // 80 Sum()
+ NULL, // 81 Avg()
+ NULL, // 82 Cnt()
+ NULL, // 83 Min()
+ NULL, // 84 Max()
+ NULL, // 85 Vlookup()
+ NULL, // 86 Npv()
+ NULL, // 87 Var()
+ NULL, // 88 Std()
+ NULL, // 89 Irr()
+ NULL, // 90 Hlookup()
+ NULL, // 91 XlfDsum
+ NULL, // 92 XlfDaverage
+ NULL, // 93 XlfDcount
+ NULL, // 94 XlfDmin
+ NULL, // 95 XlfDmax
+ NULL, // 96 XlfDvar
+ NULL, // 97 XlfDstdev
+ NULL, // 98 Index()
+ NULL, // 99 Cols()
+ NULL, // 100 Rows()
+ NULL, // 101 Repeat()
+ NULL, // 102 Upper()
+ NULL, // 103 Lower()
+ NULL, // 104 Left()
+ NULL, // 105 Right()
+ NULL, // 106 Replace()
+ NULL, // 107 Proper()
+ "ZELLE", // 108 Cell()
+ NULL, // 109 Trim()
+ NULL, // 110 Clean()
+ "F", // 111 F() (Excel: T()?)
+ "W", // 112 W()
+ NULL, // 113 Exact()
+ NULL, // 114 Call()
+ NULL, // 115 @@()
+ NULL, // 116 Rate()
+ "ANN", // 117 Term()
+ NULL, // 118 Cterm()
+ NULL, // 119 Sln()
+ NULL, // 120 Syd(), Soy()
+ NULL, // 121 Ddb()
+ "SplFunc", // 122 Splfunc
+ "BLAETTER", // 123 Sheets
+ "INFO", // 124 Info
+ NULL, // 125 Sumproduct
+ "ISTBEREICH", // 126 Isrange
+ NULL, // 127 Dget
+ "DABFRAGE", // 128 Dquery
+ "KOORD", // 129 Coord
+ NULL, // 130 Reserved (internal)
+ NULL, // 131 Today
+ NULL, // 132 Vdb
+ NULL, // 133 Dvars
+ NULL, // 134 Dstds
+ NULL, // 135 Vars
+ NULL, // 136 Stds
+ NULL, // 137 D360
+ NULL, // 138 Reserved (internal)
+ NULL, // 139 Isapp
+ "ISTDEFZUS", // 140 Isaaf
+ NULL, // 141 Weekday
+ NULL, // 142 Datedif
+ NULL, // 143 Rank
+ NULL, // 144 Numberstring
+ "DATUMFOLGE", // 145 Datestring
+ "DEZIMAL", // 146 Decimal
+ "HEX", // 147 Hex
+ NULL, // 148 Db
+ NULL, // 149 Pmti
+ NULL, // 150 Spi
+ NULL, // 151 Fullp
+ NULL, // 152 Halfp
+ "PURMITTELWERT", // 153 Pureavg
+ "PURANZAHL", // 154 Purecount
+ "PURMAX", // 155 Puremax
+ "PURMIN", // 156 Puremin
+ "PURSTDABW", // 157 Purestd
+ "PURVAR", // 158 Purevar
+ "PURSTDABWP", // 159 Purestds
+ "PURVARP", // 160 Purevars
+ NULL, // 161 Pmt2
+ NULL, // 162 Pv2
+ NULL, // 163 Fv2
+ NULL, // 164 Term2
+ NULL, // 165 --- <-------- neu! - Anzahl ? -
+ NULL, // 166 D360 (US-Version, ersatzweise wie ander D360-Funktion)
+ NULL, // 167
+ NULL, // 168
+ NULL, // 169
+ NULL, // 170
+ NULL, // 171
+ NULL, // 172
+ NULL, // 173
+ NULL, // 174
+ NULL, // 175
+ NULL, // 176
+ NULL, // 177
+ NULL, // 178
+ NULL, // 179
+ NULL, // 180
+ NULL, // 181
+ NULL, // 182
+ NULL, // 183
+ NULL, // 184
+ NULL, // 185
+ NULL, // 186
+ NULL, // 187
+ NULL, // 188
+ NULL, // 189
+ NULL, // 190
+ NULL, // 191
+ NULL, // 192
+ NULL, // 193
+ NULL, // 194
+ NULL, // 195
+ NULL, // 196
+ NULL, // 197
+ NULL, // 198
+ NULL, // 199
+ NULL, // 200
+ NULL, // 201
+ NULL, // 202
+ NULL, // 203
+ NULL, // 204
+ NULL, // 205
+ NULL, // 206 ?
+ NULL, // 207
+ NULL, // 208
+ NULL, // 209
+ NULL, // 210
+ NULL, // 211
+ NULL, // 212
+ NULL, // 213
+ NULL, // 214
+ NULL, // 215
+ NULL, // 216
+ NULL, // 217
+ NULL, // 218
+ NULL, // 219
+ NULL, // 220
+ NULL, // 221
+ NULL, // 222
+ NULL, // 223
+ NULL, // 224
+ NULL, // 225
+ NULL, // 226
+ NULL, // 227
+ NULL, // 228
+ NULL, // 229
+ NULL, // 230
+ NULL, // 231
+ NULL, // 232
+ NULL, // 233
+ NULL, // 234
+ NULL, // 235
+ NULL, // 236
+ NULL, // 237
+ NULL, // 238
+ NULL, // 239
+ NULL, // 240
+ NULL, // 241
+ NULL, // 242
+ NULL, // 243
+ NULL, // 244
+ NULL, // 245
+ NULL, // 246
+ NULL, // 247
+ NULL, // 248
+ NULL, // 249
+ NULL, // 250
+ NULL, // 251
+ NULL, // 252
+ NULL, // 253
+ NULL, // 254
+ NULL // 255 ?
+ };
+
+ return pNames[ n ];
+}
+
+
+DefTokenId lcl_KnownAddIn( const ByteString& sTest )
+{
+ DefTokenId eId = ocNoName;
+
+ if( sTest == "FACT" )
+ eId = ocFact;
+ else if(sTest== "ISEMPTY")
+ eId=ocIsEmpty;
+ else if(sTest== "DEGTORAD")
+ eId=ocRad;
+ else if(sTest== "RADTODEG")
+ eId=ocDeg;
+ else if(sTest== "SIGN")
+ eId=ocPlusMinus;
+ else if(sTest== "ACOSH")
+ eId=ocArcCosHyp;
+ else if(sTest== "ACOTH")
+ eId=ocArcCotHyp;
+ else if(sTest== "ASINH")
+ eId=ocArcSinHyp;
+ else if(sTest== "ATANH")
+ eId=ocArcTanHyp;
+ else if(sTest== "COSH")
+ eId=ocCosHyp;
+ else if(sTest== "COTH")
+ eId=ocCotHyp;
+ else if(sTest== "SINH")
+ eId=ocSinHyp;
+ else if(sTest== "TANH")
+ eId=ocTanHyp;
+ else if(sTest== "EVEN")
+ eId=ocIsEven;
+ else if(sTest== "ODD")
+ eId=ocIsOdd;
+ else if(sTest== "ACOT")
+ eId=ocArcCot;
+ else if(sTest== "COT")
+ eId=ocCot;
+ else if(sTest== "ACOT")
+ eId=ocArcCot;
+ else if(sTest== "TRUNC")
+ eId=ocTrunc;
+ else if(sTest== "GEOMEAN")
+ eId=ocGeoMean;
+ else if(sTest== "HARMEAN")
+ eId=ocHarMean;
+ else if(sTest== "CORREL")
+ eId=ocCorrel;
+ else if(sTest== "MEDIAN")
+ eId=ocMedian;
+ else if(sTest== "COV")
+ eId=ocCovar;
+ else if(sTest== "SKEWNESS")
+ eId=ocSchiefe;
+ else if(sTest== "CHITEST")
+ eId=ocChiTest;
+ else if(sTest== "FTEST")
+ eId=ocFTest;
+ else if(sTest== "AVEDEV")
+ eId=ocAveDev;
+ else if(sTest== "PRODUCT")
+ eId=ocProduct;
+ else if(sTest== "PERMUT")
+ eId=ocVariationen;
+ else if(sTest== "GAMMALN")
+ eId=ocGammaLn;
+ else if(sTest== "POISSON")
+ eId=ocPoissonDist;
+ else if(sTest== "NORMAL")
+ eId=ocNormDist;
+ else if(sTest== "CRITBINOMIAL")
+ eId=ocKritBinom;
+ return eId;
+
+
+}
+
diff --git a/sc/source/filter/lotus/lotimpop.cxx b/sc/source/filter/lotus/lotimpop.cxx
new file mode 100644
index 000000000000..2f6f81b7279c
--- /dev/null
+++ b/sc/source/filter/lotus/lotimpop.cxx
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "lotimpop.hxx"
+#include <vos/mutex.hxx>
+
+#include "attrib.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "compiler.hxx"
+#include "global.hxx"
+
+#include "root.hxx"
+#include "lotfntbf.hxx"
+#include "lotform.hxx"
+#include "tool.h"
+#include "namebuff.hxx"
+#include "lotrange.hxx"
+#include "lotattr.hxx"
+
+
+static NAMESPACE_VOS( OMutex ) aLotImpSemaphore;
+
+
+ImportLotus::ImportLotus( SvStream& aStream, ScDocument* pDoc, CharSet eQ ) :
+ ImportTyp( pDoc, eQ ),
+ pIn( &aStream ),
+ aConv( *pIn, eQ, FALSE )
+{
+ // good point to start locking of import lotus
+ aLotImpSemaphore.acquire();
+
+ pLotusRoot = new LOTUS_ROOT;
+ pLotusRoot->pDoc = pDoc;
+ pLotusRoot->pRangeNames = new LotusRangeList;
+ pLotusRoot->pScRangeName = pDoc->GetRangeName();
+ pLotusRoot->eCharsetQ = eQ;
+ pLotusRoot->eFirstType = Lotus_X;
+ pLotusRoot->eActType = Lotus_X;
+ pLotusRoot->pRngNmBffWK3 = new RangeNameBufferWK3;
+ pFontBuff = pLotusRoot->pFontBuff = new LotusFontBuffer;
+ pLotusRoot->pAttrTable = new LotAttrTable;
+}
+
+
+ImportLotus::~ImportLotus()
+{
+ delete pLotusRoot->pRangeNames;
+ delete pLotusRoot->pRngNmBffWK3;
+ delete pFontBuff;
+ delete pLotusRoot->pAttrTable;
+ delete pLotusRoot;
+
+#ifdef DBG_UTIL
+ pLotusRoot = NULL;
+#endif
+
+ // no need 4 pLotusRoot anymore
+ aLotImpSemaphore.release();
+}
+
+
+void ImportLotus::Bof( void )
+{
+ UINT16 nFileCode, nFileSub, nSaveCnt;
+ BYTE nMajorId, nMinorId, nFlags;
+
+ Read( nFileCode );
+ Read( nFileSub );
+ Read( pLotusRoot->aActRange );
+ Read( nSaveCnt );
+ Read( nMajorId );
+ Read( nMinorId );
+ Skip( 1 );
+ Read( nFlags );
+
+ if( nFileSub == 0x0004 )
+ {
+ if( nFileCode == 0x1000 )
+ {// <= WK3
+ pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK3;
+ }
+ else if( nFileCode == 0x1002 )
+ {// WK4
+ pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK4;
+ }
+ }
+}
+
+
+BOOL ImportLotus::BofFm3( void )
+{
+ UINT16 nFileCode, nFileSub;
+
+ Read( nFileCode );
+ Read( nFileSub );
+
+ return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) );
+}
+
+
+void ImportLotus::Columnwidth( UINT16 nRecLen )
+{
+ DBG_ASSERT( nRecLen >= 4, "*ImportLotus::Columnwidth(): Record zu kurz!" );
+
+ BYTE nLTab, nWindow2;
+ UINT16 nCnt = ( nRecLen - 4 ) / 2;
+
+ Read( nLTab );
+ Read( nWindow2 );
+
+ if( !pD->HasTable( static_cast<SCTAB> (nLTab) ) )
+ pD->MakeTable( static_cast<SCTAB> (nLTab) );
+
+ if( !nWindow2 )
+ {
+ Skip( 2 );
+
+ BYTE nCol, nSpaces;
+
+ while( nCnt )
+ {
+ Read( nCol );
+ Read( nSpaces );
+ // ACHTUNG: Korrekturfaktor nach 'Augenmass' ermittelt!
+ pD->SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), ( UINT16 ) ( TWIPS_PER_CHAR * 1.28 * nSpaces ) );
+
+ nCnt--;
+ }
+ }
+}
+
+
+void ImportLotus::Hiddencolumn( UINT16 nRecLen )
+{
+ DBG_ASSERT( nRecLen >= 4, "*ImportLotus::Hiddencolumn(): Record zu kurz!" );
+
+ BYTE nLTab, nWindow2;
+ UINT16 nCnt = ( nRecLen - 4 ) / 2;
+
+ Read( nLTab );
+ Read( nWindow2 );
+
+ if( !nWindow2 )
+ {
+ Skip( 2 );
+
+ BYTE nCol;
+
+ while( nCnt )
+ {
+ Read( nCol );
+
+ pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
+ nCnt--;
+ }
+ }
+}
+
+
+void ImportLotus::Userrange( void )
+{
+ UINT16 nRangeType;
+ ScRange aScRange;
+ sal_Char* pBuffer = new sal_Char[ 32 ];
+
+ Read( nRangeType );
+
+ pIn->Read( pBuffer, 16 );
+ pBuffer[ 16 ] = ( sal_Char ) 0x00; // zur Sicherheit...
+ String aName( pBuffer, eQuellChar );
+
+ Read( aScRange );
+
+ pLotusRoot->pRngNmBffWK3->Add( aName, aScRange );
+ delete[] pBuffer;
+}
+
+
+void ImportLotus::Errcell( void )
+{
+ ScAddress aA;
+
+ Read( aA );
+
+ pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#ERR!" ) ), (BOOL)TRUE );
+}
+
+
+void ImportLotus::Nacell( void )
+{
+ ScAddress aA;
+
+ Read( aA );
+
+ pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#NA!" ) ), (BOOL)TRUE );
+}
+
+
+void ImportLotus::Labelcell( void )
+{
+ ScAddress aA;
+ String aLabel;
+ sal_Char cAlign;
+
+ Read( aA );
+ Read( cAlign );
+ Read( aLabel );
+
+// aLabel.Convert( pLotusRoot->eCharsetQ );
+
+ pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( aLabel ), (BOOL)TRUE );
+}
+
+
+void ImportLotus::Numbercell( void )
+ {
+ ScAddress aAddr;
+ double fVal;
+
+ Read( aAddr );
+ Read( fVal );
+
+ pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(),
+ new ScValueCell( fVal ), (BOOL)TRUE );
+ }
+
+
+void ImportLotus::Smallnumcell( void )
+ {
+ ScAddress aAddr;
+ INT16 nVal;
+
+ Read( aAddr );
+ Read( nVal );
+
+ pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(),
+ new ScValueCell( SnumToDouble( nVal ) ), ( BOOL ) TRUE );
+ }
+
+
+ScFormulaCell *ImportLotus::Formulacell( UINT16 n )
+ {
+ DBG_ASSERT( pIn, "-ImportLotus::Formulacell(): Null-Stream -> Rums!" );
+
+ ScAddress aAddr;
+
+ Read( aAddr );
+ Skip( 10 );
+
+ n -= 14;
+
+ const ScTokenArray* pErg;
+ INT32 nRest = n;
+
+ aConv.Reset( aAddr );
+ aConv.SetWK3();
+ aConv.Convert( pErg, nRest );
+
+ ScFormulaCell* pZelle = new ScFormulaCell( pD, aAddr, pErg );
+
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+
+ pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(), pZelle, (BOOL)TRUE );
+
+ return NULL;
+ }
+
+
+void ImportLotus::Read( String &r )
+{
+ ScfTools::AppendCString( *pIn, r, eQuellChar );
+}
+
+
+void ImportLotus::RowPresentation( UINT16 nRecLen )
+{
+ DBG_ASSERT( nRecLen > 4, "*ImportLotus::RowPresentation(): Record zu kurz!" );
+
+ BYTE nLTab, nFlags;
+ UINT16 nRow, nHeight;
+ UINT16 nCnt = ( nRecLen - 4 ) / 8;
+
+ Read( nLTab );
+ Skip( 1 );
+
+ while( nCnt )
+ {
+ Read( nRow );
+ Read( nHeight );
+ Skip( 2 );
+ Read( nFlags );
+ Skip( 1 );
+
+ if( nFlags & 0x02 ) // Fixed / Strech to fit fonts
+ { // fixed
+ // Height in Lotus in 1/32 Points
+ nHeight *= 20; // -> 32 * TWIPS
+ nHeight /= 32; // -> TWIPS
+
+ pD->SetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), pD->GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CR_MANUALSIZE );
+
+ pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
+ }
+
+ nCnt--;
+ }
+}
+
+
+void ImportLotus::NamedSheet( void )
+{
+ UINT16 nLTab;
+ String aName;
+
+ Read( nLTab );
+ Read( aName );
+
+ if( pD->HasTable( static_cast<SCTAB> (nLTab) ) )
+ pD->RenameTab( static_cast<SCTAB> (nLTab), aName );
+ else
+ pD->InsertTab( static_cast<SCTAB> (nLTab), aName );
+}
+
+
+void ImportLotus::Font_Face( void )
+{
+ BYTE nNum;
+ String aName;
+
+ Read( nNum );
+
+ // ACHTUNG: QUICK-HACK gegen unerklaerliche Loops
+ if( nNum > 7 )
+ return;
+ // ACHTUNG
+
+ Read( aName );
+
+ pFontBuff->SetName( nNum, aName );
+}
+
+
+void ImportLotus::Font_Type( void )
+{
+ static const UINT16 nAnz = 8;
+ UINT16 nCnt;
+ UINT16 nType;
+
+ for( nCnt = 0 ; nCnt < nAnz ; nCnt++ )
+ {
+ Read( nType );
+ pFontBuff->SetType( nCnt, nType );
+ }
+}
+
+
+void ImportLotus::Font_Ysize( void )
+{
+ static const UINT16 nAnz = 8;
+ UINT16 nCnt;
+ UINT16 nSize;
+
+ for( nCnt = 0 ; nCnt < nAnz ; nCnt++ )
+ {
+ Read( nSize );
+ pFontBuff->SetHeight( nCnt, nSize );
+ }
+}
+
+
+void ImportLotus::_Row( const UINT16 nRecLen )
+ {
+ DBG_ASSERT( nExtTab >= 0, "*ImportLotus::_Row(): Kann hier nicht sein!" );
+
+ UINT16 nRow;
+ UINT16 nHeight;
+ UINT16 nCntDwn = ( nRecLen - 4 ) / 5;
+ SCCOL nColCnt = 0;
+ UINT8 nRepeats;
+ LotAttrWK3 aAttr;
+
+ BOOL bCenter = FALSE;
+ SCCOL nCenterStart = 0, nCenterEnd = 0;
+
+ Read( nRow );
+ Read( nHeight );
+
+ nHeight &= 0x0FFF;
+ nHeight *= 22;
+
+ if( nHeight )
+ pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab), nHeight );
+
+ while( nCntDwn )
+ {
+ Read( aAttr );
+ Read( nRepeats );
+
+ if( aAttr.HasStyles() )
+ pLotusRoot->pAttrTable->SetAttr(
+ nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), static_cast<SCROW> (nRow), aAttr );
+
+ // hier und NICHT in class LotAttrTable, weil nur Attributiert wird,
+ // wenn die anderen Attribute gesetzt sind
+ // -> bei Center-Attribute wird generell zentriert gesetzt
+ if( aAttr.IsCentered() )
+ {
+ if( bCenter )
+ {
+ if( pD->HasData( nColCnt, static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab) ) )
+ {// neue Center nach vorheriger Center
+ pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
+ nCenterStart = nColCnt;
+ }
+ }
+ else
+ {// ganz neue Center
+ bCenter = TRUE;
+ nCenterStart = nColCnt;
+ }
+ nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
+ }
+ else
+ {
+ if( bCenter )
+ {// evtl. alte Center bemachen
+ pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
+ bCenter = FALSE;
+ }
+ }
+
+ nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
+ nColCnt++;
+
+ nCntDwn--;
+ }
+
+ if( bCenter )
+ // evtl. alte Center bemachen
+ pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
+ }
+
+
diff --git a/sc/source/filter/lotus/lotread.cxx b/sc/source/filter/lotus/lotread.cxx
new file mode 100644
index 000000000000..917337fa91d5
--- /dev/null
+++ b/sc/source/filter/lotus/lotread.cxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "document.hxx"
+
+#include "scerrors.hxx"
+#include "root.hxx"
+#include "lotimpop.hxx"
+#include "lotattr.hxx"
+#include "fprogressbar.hxx"
+
+
+class ScFormulaCell;
+
+
+FltError ImportLotus::Read()
+{
+ enum STATE
+ {
+ S_START, // analyse first BOF
+ S_WK1, // in WK1-Stream
+ S_WK3, // in WK3-Section
+ S_WK4, // ...
+ S_FM3, // ...
+ S_END // Import finished
+ };
+
+ UINT16 nOp;
+ UINT16 nSubType;
+ UINT16 nRecLen;
+ UINT32 nNextRec = 0UL;
+ FltError eRet = eERR_OK;
+// ScFormulaCell *pLastFormCell;
+
+ STATE eAkt = S_START;
+
+ nTab = 0;
+ nExtTab = -2;
+
+ pIn->Seek( nNextRec );
+
+ // Progressbar starten
+ ScfStreamProgressBar aPrgrsBar( *pIn, pD->GetDocumentShell() );
+
+ while( eAkt != S_END )
+ {
+ *pIn >> nOp >> nRecLen;
+
+ if( pIn->IsEof() )
+ eAkt = S_END;
+
+ nNextRec += nRecLen + 4;
+
+ switch( eAkt )
+ {
+ // -----------------------------------------------------------
+ case S_START: // S_START
+ if( nOp )
+ {
+ eRet = SCERR_IMPORT_UNKNOWN_WK;
+ eAkt = S_END;
+ }
+ else
+ {
+ if( nRecLen > 2 )
+ {
+ Bof();
+ switch( pLotusRoot->eFirstType )
+ {
+ case Lotus_WK1: eAkt = S_WK1; break;
+ case Lotus_WK3: eAkt = S_WK3; break;
+ case Lotus_WK4: eAkt = S_WK4; break;
+ case Lotus_FM3: eAkt = S_FM3; break;
+ default:
+ eRet = SCERR_IMPORT_UNKNOWN_WK;
+ eAkt = S_END;
+ }
+ }
+ else
+ {
+ eAkt = S_END; // hier kommt wat fuer <= WK1 hinne!
+ eRet = 0xFFFFFFFF;
+ }
+ }
+ break;
+ // -----------------------------------------------------------
+ case S_WK1: // S_WK1
+ break;
+ // -----------------------------------------------------------
+ case S_WK3: // S_WK3
+ case S_WK4: // S_WK4
+ switch( nOp )
+ {
+ case 0x0001: // EOF
+ eAkt = S_FM3;
+ nTab++;
+ break;
+
+ case 0x0002: // PASSWORD
+ eRet = eERR_FILEPASSWD;
+ eAkt = S_END;
+ break;
+
+ case 0x0007: // COLUMNWIDTH
+ Columnwidth( nRecLen );
+ break;
+
+ case 0x0008: // HIDDENCOLUMN
+ Hiddencolumn( nRecLen );
+ break;
+
+ case 0x0009: // USERRANGE
+ Userrange();
+ break;
+
+ case 0x0013: // FORMAT
+
+ break;
+ case 0x0014: // ERRCELL
+ Errcell();
+ break;
+
+ case 0x0015: // NACELL
+ Nacell();
+ break;
+
+ case 0x0016: // LABELCELL
+ Labelcell();
+ break;
+
+ case 0x0017: // NUMBERCELL
+ Numbercell();
+ break;
+
+ case 0x0018: // SMALLNUMCELL
+ Smallnumcell();
+ break;
+
+ case 0x0019: // FORMULACELL
+ Formulacell( nRecLen );
+ break;
+
+ case 0x001b: // extended attributes
+ Read( nSubType );
+ nRecLen -= 2;
+ switch( nSubType )
+ {
+ case 2007: // ROW PRESENTATION
+ RowPresentation( nRecLen );
+ break;
+
+ case 14000: // NAMED SHEET
+ NamedSheet();
+ break;
+ }
+ }
+
+ break;
+ // -----------------------------------------------------------
+ case S_FM3: // S_FM3
+ break;
+ // -----------------------------------------------------------
+ case S_END: // S_END
+ break;
+ // -----------------------------------------------------------
+#ifdef DBG_UTIL
+ default:
+ DBG_ERROR( "*ImportLotus::Read(): State unbekannt!" );
+ eAkt = S_END;
+#endif
+ }
+
+ DBG_ASSERT( nNextRec >= pIn->Tell(),
+ "*ImportLotus::Read(): Etwas zu gierig..." );
+
+ pIn->Seek( nNextRec );
+ aPrgrsBar.Progress();
+ }
+
+ // duemmliche Namen eliminieren
+ SCTAB nTabs = pD->GetTableCount();
+ SCTAB nCnt;
+ String aTabName;
+ String aBaseName;
+ String aRef( RTL_CONSTASCII_USTRINGPARAM( "temp" ) );
+ if( nTabs != 0 )
+ {
+ if( nTabs > 1 )
+ {
+ pD->GetName( 0, aBaseName );
+ aBaseName.Erase( aBaseName.Len() - 1 );
+ }
+ for( nCnt = 1 ; nCnt < nTabs ; nCnt++ )
+ {
+ DBG_ASSERT( pD->HasTable( nCnt ),
+ "-ImportLotus::Read(): Wo ist meine Tabelle?!" );
+ pD->GetName( nCnt, aTabName );
+ if( aTabName == aRef )
+ {
+ aTabName = aBaseName;
+ pD->CreateValidTabName( aTabName );
+ pD->RenameTab( nCnt, aTabName );
+ }
+ }
+ }
+
+ pD->CalcAfterLoad();
+
+ return eRet;
+}
+
+
+FltError ImportLotus::Read( SvStream& rIn )
+{
+ pIn = &rIn;
+
+ BOOL bRead = TRUE;
+ UINT16 nOp;
+ UINT16 nRecLen;
+ UINT32 nNextRec = 0UL;
+ FltError eRet = eERR_OK;
+
+ nTab = 0;
+ nExtTab = -1;
+
+ pIn->Seek( nNextRec );
+
+ // Progressbar starten
+ ScfStreamProgressBar aPrgrsBar( *pIn, pD->GetDocumentShell() );
+
+ while( bRead )
+ {
+ *pIn >> nOp >> nRecLen;
+
+ if( pIn->IsEof() )
+ bRead = FALSE;
+ else
+ {
+ nNextRec += nRecLen + 4;
+
+ switch( nOp )
+ {
+ case 0x0000: // BOF
+ if( nRecLen != 26 || !BofFm3() )
+ {
+ bRead = FALSE;
+ eRet = eERR_FORMAT;
+ }
+ break;
+
+ case 0x0001: // EOF
+ bRead = FALSE;
+ DBG_ASSERT( nTab == 0,
+ "-ImportLotus::Read( SvStream& ): Zweimal EOF nicht erlaubt" );
+ nTab++;
+ break;
+
+ case 174: // FONT_FACE
+ Font_Face();
+ break;
+
+ case 176: // FONT_TYPE
+ Font_Type();
+ break;
+
+ case 177: // FONT_YSIZE
+ Font_Ysize();
+ break;
+
+ case 195:
+ if( nExtTab >= 0 )
+ pLotusRoot->pAttrTable->Apply( ( SCTAB ) nExtTab );
+ nExtTab++;
+ break;
+ case 197:
+ _Row( nRecLen );
+ break;
+ }
+
+ DBG_ASSERT( nNextRec >= pIn->Tell(),
+ "*ImportLotus::Read(): Etwas zu gierig..." );
+ pIn->Seek( nNextRec );
+ aPrgrsBar.Progress();
+ }
+ }
+
+ pLotusRoot->pAttrTable->Apply( ( SCTAB ) nExtTab );
+
+ return eRet;
+}
+
+
+
diff --git a/sc/source/filter/lotus/lotus.cxx b/sc/source/filter/lotus/lotus.cxx
new file mode 100644
index 000000000000..a1a428c5dbeb
--- /dev/null
+++ b/sc/source/filter/lotus/lotus.cxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "lotimpop.hxx"
+
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+
+#include "scerrors.hxx"
+#include "root.hxx"
+#include "filtopt.hxx"
+#include "ftools.hxx"
+
+//------------------------------------------------------------------------
+
+extern FltError ScImportLotus123old( SvStream&, ScDocument*, CharSet eSrc );
+ // alter Krempel in filter.cxx!
+
+FltError ScFormatFilterPluginImpl::ScImportLotus123( SfxMedium& rMedium, ScDocument* pDocument, CharSet eSrc )
+{
+ ScFilterOptions aFilterOpt;
+ BOOL bWithWK3 = aFilterOpt.GetWK3Flag();
+
+ SvStream* pStream = rMedium.GetInStream();
+
+ if( !pStream )
+ return eERR_OPEN;
+
+ FltError eRet;
+
+ pStream->Seek( 0UL );
+
+ pStream->SetBufferSize( 32768 );
+
+ ImportLotus aLotusImport( *pStream, pDocument, eSrc );
+
+ if( bWithWK3 )
+ eRet = aLotusImport.Read();
+ else
+ eRet = 0xFFFFFFFF; // WK1 /WKS erzwingen
+
+ // ACHTUNG: QUICK-HACK fuer WK1 / WKS <-> WK3 / WK4
+ if( eRet == 0xFFFFFFFF )
+ {
+ pStream->Seek( 0UL );
+
+ pStream->SetBufferSize( 32768 );
+
+ eRet = ScImportLotus123old( *pStream, pDocument, eSrc );
+
+ pStream->SetBufferSize( 0 );
+
+ return eRet;
+ }
+
+ if( eRet != eERR_OK )
+ return eRet;
+
+ if( pLotusRoot->eFirstType == Lotus_WK3 )
+ {// versuchen *.FM3-File zu laden
+ INetURLObject aURL( rMedium.GetURLObject() );
+ aURL.setExtension( CREATE_STRING( "FM3" ) );
+ SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_STD_READ, TRUE );
+ pStream = aMedium.GetInStream();
+ if ( pStream )
+ {
+ if( aLotusImport.Read( *pStream ) != eERR_OK )
+ eRet = SCWARN_IMPORT_WRONG_FM3;
+ }
+ else
+ eRet = SCWARN_IMPORT_OPEN_FM3;
+ }
+
+ return eRet;
+}
+
diff --git a/sc/source/filter/lotus/makefile.mk b/sc/source/filter/lotus/makefile.mk
new file mode 100644
index 000000000000..8fb2360ea2ca
--- /dev/null
+++ b/sc/source/filter/lotus/makefile.mk
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=lotus
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+AUTOSEG=true
+
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/filter.obj \
+ $(SLO)$/lotus.obj \
+ $(SLO)$/lotimpop.obj \
+ $(SLO)$/lotread.obj \
+ $(SLO)$/lotform.obj \
+ $(SLO)$/memory.obj \
+ $(SLO)$/op.obj \
+ $(SLO)$/optab.obj \
+ $(SLO)$/tool.obj \
+ $(SLO)$/expop.obj \
+ $(SLO)$/export.obj \
+ $(SLO)$/lotattr.obj
+
+EXCEPTIONSFILES = \
+ $(SLO)$/op.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/lotus/memory.cxx b/sc/source/filter/lotus/memory.cxx
new file mode 100644
index 000000000000..1ac1fa5c470f
--- /dev/null
+++ b/sc/source/filter/lotus/memory.cxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// Bemerkung: Variablen nicht ueber Headerfile, Module muessen sich
+// selbst per extern ihre Sachen besorgen!
+
+
+
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+
+#include "attrib.hxx"
+
+#include "decl.h"
+#include "tool.h"
+
+extern const long nStackSize;
+extern const int nAnzNRange;
+
+extern ScDocument* pDoc;
+
+const long nStackSize = 8L * 1024; // -> form_xxx.cpp
+const int nAnzNRange = 2048; // -> tool_xxx.cpp, max. 2048 Named Ranges
+
+sal_Char* pPuffer; // -> flt_xxx.cxx
+sal_Char* pDummy1; // -> flt_xxx.cxx, ScanVersion()
+sal_Char* pDummy2; // -> tool.cxx, CreateTable()
+
+extern BYTE* pFormelBuffer; // -> tool.cxx, fuer OP_Formula()
+BYTE* pFormelBuffer;
+
+extern FormCache* pValueFormCache; // -> tool.cxx
+
+sal_Char* pStack; // -> formel.cxx
+sal_Char* pPuffer0; // -> formel.cxx
+sal_Char* pPuffer1; // -> formel.cxx
+extern const int nMaxPar;
+const int nMaxPar = 128; // max. 128 Parameter werden unterstuetzt
+sal_Char** pPar; // -> formel.cxx, Pn()
+
+#ifndef _DOS // -> op.cxx
+sal_Char* pAnsi;
+#endif
+sal_Char* pErgebnis; // -> op.cxx
+
+extern BOOL bFormInit; // -> tool.cxx, fuer GetFormHandle()
+BOOL bFormInit;
+
+extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter,
+ *pAttrRepeat, *pAttrStandard; // -> tool.cxx, fuer GetFormAttr()
+extern ScProtectionAttr* pAttrUnprot; // -> tool.cxx, fuer PutFormString()
+
+
+
+BOOL MemNew( void )
+{
+ pPuffer = new sal_Char [ 32L*1024L ];
+
+ pDummy1 = new sal_Char [ 32 ];
+
+ pDummy2 = new sal_Char [ 32 ];
+
+ pStack = new sal_Char [ nStackSize * 3 ]; // alle drei auf einmal
+
+ pPuffer0 = pStack + nStackSize;
+ pPuffer1 = pPuffer0 + nStackSize;
+
+ pAnsi = new sal_Char [ 2048 ];
+
+ pErgebnis = new sal_Char [ 32L*1024L ];
+
+ pPar = new sal_Char *[ nMaxPar ];
+
+ pFormelBuffer = new BYTE[ 4096 ];
+
+ pValueFormCache = new FormCache( pDoc );
+
+ // fuer tool.cxx::PutFormString()
+ pAttrUnprot = new ScProtectionAttr( TRUE );
+ pAttrRight = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY );
+ pAttrLeft = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY );
+ pAttrCenter = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY );
+ pAttrRepeat = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_REPEAT, ATTR_HOR_JUSTIFY );
+ pAttrStandard = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY );
+ bFormInit = TRUE;
+
+ return TRUE;
+}
+
+
+void MemDelete( void )
+{
+ delete[] pPuffer;
+ delete[] pDummy1;
+ delete[] pDummy2;
+ delete[] pStack;
+ delete[] pAnsi;
+ delete[] pErgebnis;
+ delete[] pPar;
+ delete[] pFormelBuffer;
+
+ delete pValueFormCache;
+ delete pAttrRight;
+ delete pAttrLeft;
+ delete pAttrCenter;
+ delete pAttrRepeat;
+ delete pAttrStandard;
+ delete pAttrUnprot;
+}
+
+
+
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx
new file mode 100644
index 000000000000..4ab0c8bb3b14
--- /dev/null
+++ b/sc/source/filter/lotus/op.cxx
@@ -0,0 +1,684 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------------
+
+#include <tools/solar.h>
+#include <rtl/math.hxx>
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#if defined( ICC )
+#include <stdlib.h>
+#endif
+
+#include "scitems.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+
+#include "cell.hxx"
+#include "rangenam.hxx"
+#include "document.hxx"
+#include "postit.hxx"
+
+#include "op.h"
+#include "optab.h"
+#include "tool.h"
+//#include "math.h"
+#include "decl.h"
+#include "lotform.hxx"
+#include "lotrange.hxx"
+
+#include "root.hxx"
+
+#include "ftools.hxx"
+
+#include <vector>
+#include <map>
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#if defined( MAC ) || defined( ICC )
+#include <stdlib.h>
+#endif
+
+extern sal_Char* pAnsi; // -> memory.cxx, Puffer zum Umwandeln von OEM->ANSI
+extern sal_Char* pErgebnis; // -> memory.cxx, Ergebnispuffer
+extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
+extern BOOL bEOF; // -> filter.cxx, zeigt Dateiende an
+extern sal_Char* pPuffer0; // -> memory.cxx
+extern sal_Char* pPuffer1;
+extern BYTE nDefaultFormat; // -> tool.cxx, Default-Zellenformat
+extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
+extern BYTE* pFormelBuffer; // -> memory.cxx, fuer
+extern CharSet eCharVon; // -> filter.cxx, character set specified
+
+static UINT16 nDefWidth = ( UINT16 ) ( TWIPS_PER_CHAR * 10 );
+
+extern std::map<UINT16, ScPatternAttr> aLotusPatternPool;
+
+void NI( SvStream& r, UINT16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_BOF( SvStream& r, UINT16 /*n*/ )
+{
+ r.SeekRel( 2 ); // Versionsnummer ueberlesen
+}
+
+
+void OP_EOF( SvStream& /*r*/, UINT16 /*n*/ )
+{
+ bEOF = TRUE;
+}
+
+
+void OP_Integer( SvStream& r, UINT16 /*n*/ )
+{
+ BYTE nFormat;
+ UINT16 nCol, nRow;
+ SCTAB nTab = 0;
+ INT16 nValue;
+
+ r >> nFormat >> nCol >> nRow >> nValue;
+
+ ScValueCell* pZelle = new ScValueCell( ( double ) nValue );
+ pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( BOOL ) TRUE );
+
+ // 0 Stellen nach'm Komma!
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, 0 );
+}
+
+
+void OP_Number( SvStream& r, UINT16 /*n*/ )
+{
+ BYTE nFormat;
+ UINT16 nCol, nRow;
+ SCTAB nTab = 0;
+ double fValue;
+
+ r >> nFormat >> nCol >> nRow >> fValue;
+
+ fValue = ::rtl::math::round( fValue, 15 );
+ ScValueCell* pZelle = new ScValueCell( fValue );
+ pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( BOOL ) TRUE );
+
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat );
+}
+
+
+void OP_Label( SvStream& r, UINT16 n )
+{
+ BYTE nFormat;
+ UINT16 nCol, nRow;
+ SCTAB nTab = 0;
+
+ r >> nFormat >> nCol >> nRow;
+ n -= 5;
+
+ sal_Char* pText = new sal_Char[n + 1];
+ r.Read( pText, n );
+ pText[n] = 0;
+
+ nFormat &= 0x80; // Bit 7 belassen
+ nFormat |= 0x75; // protected egal, special-text gesetzt
+
+ PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pText );
+
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezStd );
+
+ delete [] pText;
+}
+
+
+//UNUSED2009-05 void OP_Text( SvStream& r, UINT16 n ) // WK3
+//UNUSED2009-05 {
+//UNUSED2009-05 UINT16 nRow;
+//UNUSED2009-05 BYTE nCol, nTab;
+//UNUSED2009-05 sal_Char pText[ 256 ];
+//UNUSED2009-05
+//UNUSED2009-05 r >> nRow >> nTab >> nCol;
+//UNUSED2009-05 n -= 4;
+//UNUSED2009-05
+//UNUSED2009-05 r.Read( pText, n );
+//UNUSED2009-05 pText[ n ] = 0; // zur Sicherheit Nullterminator anhaengen
+//UNUSED2009-05
+//UNUSED2009-05 PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), static_cast<SCTAB> (nTab), pText );
+//UNUSED2009-05 }
+
+
+void OP_Formula( SvStream& r, UINT16 /*n*/ )
+{
+ BYTE nFormat;
+ UINT16 nCol, nRow, nFormulaSize;
+ SCTAB nTab = 0;
+
+ r >> nFormat >> nCol >> nRow;
+ r.SeekRel( 8 ); // Ergebnis ueberspringen
+ r >> nFormulaSize;
+
+ const ScTokenArray* pErg;
+ INT32 nBytesLeft = nFormulaSize;
+ ScAddress aAddress( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab );
+
+ LotusToSc aConv( r, pLotusRoot->eCharsetQ, FALSE );
+ aConv.Reset( aAddress );
+ aConv.Convert( pErg, nBytesLeft );
+
+ ScFormulaCell* pZelle = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
+
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+
+ pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( BOOL ) TRUE );
+
+ // nFormat = Standard -> Nachkommastellen wie Float
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat );
+}
+
+
+void OP_ColumnWidth( SvStream& r, UINT16 /*n*/ )
+{
+ UINT16 nCol, nBreite;
+ BYTE nWidthSpaces;
+ SCTAB nTab = 0;
+
+ r >> nCol >> nWidthSpaces;
+
+ if( nWidthSpaces )
+ // Annahme: 10cpi-Zeichensatz
+ nBreite = ( UINT16 ) ( TWIPS_PER_CHAR * nWidthSpaces );
+ else
+ {
+ pDoc->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), 0, true);
+ nBreite = nDefWidth;
+ }
+
+ pDoc->SetColWidth( static_cast<SCCOL> (nCol), nTab, nBreite );
+}
+
+
+void OP_NamedRange( SvStream& r, UINT16 /*n*/ )
+ {
+ // POST: waren Koordinaten ungueltig, wird nicht gespeichert
+ UINT16 nColSt, nRowSt, nColEnd, nRowEnd;
+ sal_Char cPuffer[ 32 ];
+
+ r.Read( cPuffer, 16 );
+
+ r >> nColSt >> nRowSt >> nColEnd >> nRowEnd;
+
+ LotusRange* pRange;
+
+ if( nColSt == nColEnd && nRowSt == nRowEnd )
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) );
+ else
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt), static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) );
+
+ if( isdigit( *cPuffer ) )
+ { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
+ *pAnsi = 'A';
+ strcpy( pAnsi + 1, cPuffer ); // #100211# - checked
+ }
+ else
+ strcpy( pAnsi, cPuffer ); // #100211# - checked
+
+ String aTmp( pAnsi, pLotusRoot->eCharsetQ );
+
+ ScfTools::ConvertToScDefinedName( aTmp );
+
+ pLotusRoot->pRangeNames->Append( pRange, aTmp );
+}
+
+
+void OP_SymphNamedRange( SvStream& r, UINT16 /*n*/ )
+{
+ // POST: waren Koordinaten ungueltig, wird nicht gespeichert
+ UINT16 nColSt, nRowSt, nColEnd, nRowEnd;
+ BYTE nType;
+ sal_Char* pName;
+ sal_Char cPuffer[ 32 ];
+
+ r.Read( cPuffer, 16 );
+ cPuffer[ 16 ] = 0;
+ pName = cPuffer;
+
+ r >> nColSt >> nRowSt >> nColEnd >> nRowEnd >> nType;
+
+ LotusRange* pRange;
+
+ if( nType )
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) );
+ else
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt), static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) );
+
+ if( isdigit( *cPuffer ) )
+ { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
+ *pAnsi = 'A';
+ strcpy( pAnsi + 1, cPuffer ); // #100211# - checked
+ }
+ else
+ strcpy( pAnsi, cPuffer ); // #100211# - checked
+
+ String aTmp( pAnsi, pLotusRoot->eCharsetQ );
+ ScfTools::ConvertToScDefinedName( aTmp );
+
+ pLotusRoot->pRangeNames->Append( pRange, aTmp );
+}
+
+
+void OP_Footer( SvStream& r, UINT16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_Header( SvStream& r, UINT16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_Margins( SvStream& r, UINT16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_HiddenCols( SvStream& r, UINT16 /*n*/ )
+{
+ UINT16 nByte, nBit;
+ SCCOL nCount;
+ BYTE nAkt;
+ nCount = 0;
+
+ for( nByte = 0 ; nByte < 32 ; nByte++ ) // 32 Bytes mit ...
+ {
+ r >> nAkt;
+ for( nBit = 0 ; nBit < 8 ; nBit++ ) // ...jeweils 8 Bits = 256 Bits
+ {
+ if( nAkt & 0x01 ) // unterstes Bit gesetzt?
+ // -> Hidden Col
+ pDoc->SetColHidden(nCount, nCount, 0, true);
+
+ nCount++;
+ nAkt = nAkt / 2; // der Naechste bitte...
+ }
+ }
+}
+
+
+void OP_Window1( SvStream& r, UINT16 n )
+{
+ r.SeekRel( 4 ); // Cursor Pos ueberspringen
+
+ r >> nDefaultFormat;
+
+ r.SeekRel( 1 ); // 'unused' ueberspringen
+
+ r >> nDefWidth;
+
+ r.SeekRel( n - 8 ); // und den Rest ueberspringen
+
+ nDefWidth = ( UINT16 ) ( TWIPS_PER_CHAR * nDefWidth );
+
+ // statt Defaulteinstellung in SC alle Cols zu Fuss setzen
+ for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
+ pDoc->SetColWidth( nCol, 0, nDefWidth );
+}
+
+
+void OP_Blank( SvStream& r, UINT16 /*n*/ )
+{
+ UINT16 nCol, nRow;
+ BYTE nFormat;
+ r >> nFormat >> nCol >> nRow;
+
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), 0, nFormat, nDezFloat );
+}
+
+void OP_BOF123( SvStream& r, UINT16 /*n*/ )
+{
+ r.SeekRel( 26 );
+}
+
+
+void OP_EOF123( SvStream& /*r*/, UINT16 /*n*/ )
+{
+ bEOF = TRUE;
+}
+
+void OP_Label123( SvStream& r, UINT16 n )
+{
+ BYTE nTab, nCol;
+ UINT16 nRow;
+ r >> nRow >> nTab >> nCol;
+ n -= 4;
+
+ sal_Char* pText = new sal_Char[n + 1];
+ r.Read( pText, n );
+ pText[ n ] = 0;
+
+ PutFormString( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pText );
+
+ delete []pText;
+}
+
+void OP_Number123( SvStream& r, UINT16 /*n*/ )
+{
+ BYTE nCol,nTab;
+ UINT16 nRow;
+ UINT32 nValue;
+
+ r >> nRow >> nTab >> nCol >> nValue;
+ double fValue = Snum32ToDouble( nValue );
+
+ ScValueCell *pCell = new ScValueCell( fValue );
+ pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (BOOL) TRUE );
+}
+
+void OP_Formula123( SvStream& r, UINT16 n )
+{
+ BYTE nCol,nTab;
+ UINT16 nRow;
+
+ r >> nRow >> nTab >> nCol;
+ r.SeekRel( 8 ); // Result- jump over
+
+ const ScTokenArray* pErg;
+ INT32 nBytesLeft = n - 12;
+ ScAddress aAddress( nCol, nRow, nTab );
+
+ LotusToSc aConv( r, pLotusRoot->eCharsetQ, TRUE );
+ aConv.Reset( aAddress );
+ aConv.Convert( pErg, nBytesLeft );
+
+ ScFormulaCell* pCell = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
+
+ pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+
+ pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (BOOL) TRUE );
+}
+
+void OP_IEEENumber123( SvStream& r, UINT16 /*n*/ )
+{
+ BYTE nCol,nTab;
+ UINT16 nRow;
+ double dValue;
+
+ r >> nRow >> nTab >> nCol >> dValue;
+
+ ScValueCell *pCell = new ScValueCell(dValue);
+ pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (BOOL) TRUE );
+}
+
+void OP_Note123( SvStream& r, UINT16 n)
+{
+ BYTE nTab, nCol;
+ UINT16 nRow;
+ r >> nRow >> nTab >> nCol;
+ n -= 4;
+
+ sal_Char* pText = new sal_Char[n + 1];
+ r.Read( pText, n );
+ pText[ n ] = 0;
+
+ String aNoteText(pText,pLotusRoot->eCharsetQ);
+ delete [] pText;
+
+ ScAddress aPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab) );
+ ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
+}
+
+void OP_HorAlign123( BYTE nAlignPattern, SfxItemSet& rPatternItemSet )
+{
+// pre: Pattern is stored in the last 3 bites of the 21st byte
+// post: Appropriate Horizontal Alignement is set in rPattern according to the bit pattern.
+//
+// LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
+// LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
+
+ nAlignPattern = ( nAlignPattern & 0x07);
+
+ switch (nAlignPattern)
+ {
+ case 1:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
+ break;
+ case 2:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) );
+ break;
+ case 3:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) );
+ break;
+ case 4:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) );
+ break;
+ case 6:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_BLOCK, ATTR_HOR_JUSTIFY ) );
+ break;
+ default:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) );
+ break;
+ }
+}
+
+void OP_VerAlign123( BYTE nAlignPattern,SfxItemSet& rPatternItemSet )
+{
+// pre: Pattern is stored in the last 3 bites of the 22nd byte
+// post: Appropriate Verticle Alignement is set in rPattern according to the bit pattern.
+//
+// TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
+
+ nAlignPattern = ( nAlignPattern & 0x07);
+
+ switch (nAlignPattern)
+ {
+ case 0:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) );
+ break;
+ case 1:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY) );
+ break;
+ case 2:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY) );
+ break;
+ case 4:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY) );
+ break;
+ default:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) );
+ break;
+ }
+}
+
+void OP_CreatePattern123( SvStream& r, UINT16 n)
+{
+ UINT16 nCode,nPatternId;
+
+ ScPatternAttr aPattern(pDoc->GetPool());
+ SfxItemSet& rItemSet = aPattern.GetItemSet();
+
+ r >> nCode;
+ n = n - 2;
+
+ if ( nCode == 0x0fd2 )
+ {
+ r >> nPatternId;
+
+ BYTE Hor_Align, Ver_Align, temp;
+ BOOL bIsBold,bIsUnderLine,bIsItalics;
+
+ r.SeekRel(12);
+
+ // Read 17th Byte
+ r >> temp;
+
+ bIsBold = (temp & 0x01);
+ bIsItalics = (temp & 0x02);
+ bIsUnderLine = (temp & 0x04);
+
+ if ( bIsBold )
+ rItemSet.Put( SvxWeightItem(WEIGHT_BOLD,ATTR_FONT_WEIGHT) );
+ if ( bIsItalics )
+ rItemSet.Put( SvxPostureItem(ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ if ( bIsUnderLine )
+ rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+
+ r.SeekRel(3);
+
+ // Read 21st Byte
+ r >> Hor_Align;
+ OP_HorAlign123( Hor_Align, rItemSet );
+
+ r >> Ver_Align;
+ OP_VerAlign123( Ver_Align, rItemSet );
+
+ aLotusPatternPool.insert( std::map<UINT16, ScPatternAttr>::value_type( nPatternId, aPattern ) );
+ n = n - 20;
+ }
+ r.SeekRel(n);
+}
+
+void OP_SheetName123( SvStream& rStream, USHORT nLength )
+{
+ if (nLength <= 4)
+ {
+ rStream.SeekRel(nLength);
+ return;
+ }
+
+ // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)]
+
+ sal_uInt16 nDummy;
+ rStream >> nDummy; // ignore the first 2 bytes (B0 36).
+ rStream >> nDummy;
+ SCTAB nSheetNum = static_cast<SCTAB>(nDummy);
+ pDoc->MakeTable(nSheetNum);
+
+ ::std::vector<sal_Char> sSheetName;
+ sSheetName.reserve(nLength-4);
+ for (USHORT i = 4; i < nLength; ++i)
+ {
+ sal_Char c;
+ rStream >> c;
+ sSheetName.push_back(c);
+ }
+
+ if (!sSheetName.empty())
+ {
+ String aName(&sSheetName[0], eCharVon);
+ pDoc->RenameTab(nSheetNum, aName);
+ }
+}
+
+void OP_ApplyPatternArea123( SvStream& rStream )
+{
+ UINT16 nOpcode, nLength;
+ UINT16 nCol = 0, nColCount = 0, nRow = 0, nRowCount = 0, nTab = 0, nData, nTabCount = 0, nLevel = 0;
+
+ do
+ {
+ rStream >> nOpcode >> nLength;
+ switch ( nOpcode )
+ {
+ case ROW_FORMAT_MARKER:
+ nLevel++;
+ break;
+ case COL_FORMAT_MARKER:
+ nLevel--;
+ if( nLevel == 1 )
+ {
+ nTab = nTab + nTabCount;
+ nCol = 0; nColCount = 0;
+ nRow = 0; nRowCount = 0;
+ }
+ break;
+ case LOTUS_FORMAT_INDEX:
+ if( nLength >= 2 )
+ {
+ rStream >> nData;
+ rStream.SeekRel( nLength - 2 );
+ if( nLevel == 1 )
+ nTabCount = nData;
+ else if( nLevel == 2 )
+ {
+ nCol = nCol + nColCount;
+ nColCount = nData;
+ if ( nCol > 0xff ) // 256 is the max col size supported by 123
+ nCol = 0;
+ }
+ else if( nLevel == 3 )
+ {
+ nRow = nRow + nRowCount;
+ nRowCount = nData;
+ if ( nRow > 0x1fff ) // 8192 is the max row size supported by 123
+ nRow = 0;
+ }
+ }
+ else
+ rStream.SeekRel( nLength );
+ break;
+ case LOTUS_FORMAT_INFO:
+ if( nLength >= 2 )
+ {
+ rStream >> nData;
+ rStream.SeekRel( nLength - 2 );
+ for( int i = 0; i < nTabCount; i++)
+ {
+ std::map<UINT16, ScPatternAttr>::iterator loc = aLotusPatternPool.find( nData );
+
+ // #126338# apparently, files with invalid index occur in the wild -> don't crash then
+ DBG_ASSERT( loc != aLotusPatternPool.end(), "invalid format index" );
+ if ( loc != aLotusPatternPool.end() )
+ pDoc->ApplyPatternAreaTab( nCol, nRow, nCol + nColCount - 1, nRow + nRowCount - 1, static_cast< SCTAB >( nTab + i ), loc->second );
+ }
+ }
+ else
+ rStream.SeekRel( nLength );
+ break;
+ default:
+ rStream.SeekRel( nLength );
+ break;
+ }
+ }
+ while( nLevel && !rStream.IsEof() );
+
+ aLotusPatternPool.clear();
+}
diff --git a/sc/source/filter/lotus/optab.cxx b/sc/source/filter/lotus/optab.cxx
new file mode 100644
index 000000000000..503d271a5b74
--- /dev/null
+++ b/sc/source/filter/lotus/optab.cxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "op.h"
+#include "optab.h"
+
+
+// Bearbeitungsfunktion sal_Char *X( sal_Char * )
+OPCODE_FKT pOpFkt[ FKT_LIMIT ] =
+{ // Code
+ OP_BOF, // 0
+ OP_EOF, // 1
+ NI, // 2
+ NI, // 3
+ NI, // 4
+ NI, // 5
+ NI, // 6
+ OP_Window1, // 7
+ OP_ColumnWidth, // 8
+ NI, // 9
+ NI, // 10
+ OP_NamedRange, // 11
+ OP_Blank, // 12
+ OP_Integer, // 13
+ OP_Number, // 14
+ OP_Label, // 15
+ OP_Formula, // 16
+ NI, // 17
+ NI, // 18
+ NI, // 19
+ NI, // 20
+ NI, // 21
+ NI, // 22
+ NI, // 23
+ NI, // 24
+ NI, // 25
+ NI, // 26
+ NI, // 27
+ NI, // 28
+ NI, // 29
+ NI, // 30
+ NI, // 31
+ NI, // 32
+ NI, // 33
+ NI, // 34
+ NI, // 35
+ NI, // 36
+ OP_Footer, // 37
+ OP_Header, // 38
+ NI, // 39
+ OP_Margins, // 40
+ NI, // 41
+ NI, // 42
+ NI, // 43
+ NI, // 44
+ NI, // 45
+ NI, // 46
+ NI, // 47
+ NI, // 48
+ NI, // 49
+ NI, // 50
+ NI, // 51
+ NI, // 52
+ NI, // 53
+ NI, // 54
+ NI, // 55
+ NI, // 56
+ NI, // 57
+ NI, // 58
+ NI, // 59
+ NI, // 60
+ NI, // 61
+ NI, // 62
+ NI, // 63
+ NI, // 64
+ NI, // 65
+ NI, // 66
+ NI, // 67
+ NI, // 68
+ NI, // 69
+ NI, // 70
+ OP_SymphNamedRange, // 71
+ NI, // 72
+ NI, // 73
+ NI, // 74
+ NI, // 75
+ NI, // 76
+ NI, // 77
+ NI, // 78
+ NI, // 79
+ NI, // 80
+ NI, // 81
+ NI, // 82
+ NI, // 83
+ NI, // 84
+ NI, // 85
+ NI, // 86
+ NI, // 87
+ NI, // 88
+ NI, // 89
+ NI, // 90
+ NI, // 91
+ NI, // 92
+ NI, // 93
+ NI, // 94
+ NI, // 95
+ NI, // 96
+ NI, // 97
+ NI, // 98
+ NI, // 99
+ OP_HiddenCols, // 100
+};
+
+
+OPCODE_FKT pOpFkt123[ FKT_LIMIT123 ] =
+{ // Code
+ OP_BOF123, // 0
+ OP_EOF123, // 1
+ NI, // 2
+ NI, // 3
+ NI, // 4
+ NI, // 5
+ NI, // 6
+ NI, // 7
+ NI, // 8
+ NI, // 9
+ NI, // 10
+ NI, // 11
+ NI, // 12
+ NI, // 13
+ NI, // 14
+ NI, // 15
+ NI, // 16
+ NI, // 17
+ NI, // 18
+ NI, // 19
+ NI, // 20
+ NI, // 21
+ OP_Label123, // 22
+ NI, // 23
+ NI, // 24
+ NI, // 25
+ NI, // 26
+ OP_CreatePattern123, // 27
+ NI, // 28
+ NI, // 29
+ NI, // 30
+ NI, // 31
+ NI, // 32
+ NI, // 33
+ NI, // 34
+ OP_SheetName123, // 35
+ NI, // 36
+ OP_Number123, // 37
+ OP_Note123, // 38
+ OP_IEEENumber123, // 39
+ OP_Formula123, // 40
+ NI, // 41
+ NI, // 42
+ NI, // 43
+ NI, // 44
+ NI, // 45
+ NI, // 46
+ NI, // 47
+ NI, // 48
+ NI, // 49
+ NI, // 50
+ NI, // 51
+ NI, // 52
+ NI, // 53
+ NI, // 54
+ NI, // 55
+ NI, // 56
+ NI, // 57
+ NI, // 58
+ NI, // 59
+ NI, // 60
+ NI, // 61
+ NI, // 62
+ NI, // 63
+ NI, // 64
+ NI, // 65
+ NI, // 66
+ NI, // 67
+ NI, // 68
+ NI, // 69
+ NI, // 70
+ NI, // 71
+ NI, // 72
+ NI, // 73
+ NI, // 74
+ NI, // 75
+ NI, // 76
+ NI, // 77
+ NI, // 78
+ NI, // 79
+ NI, // 80
+ NI, // 81
+ NI, // 82
+ NI, // 83
+ NI, // 84
+ NI, // 85
+ NI, // 86
+ NI, // 87
+ NI, // 88
+ NI, // 89
+ NI, // 90
+ NI, // 91
+ NI, // 92
+ NI, // 93
+ NI, // 94
+ NI, // 95
+ NI, // 96
+ NI, // 97
+ NI, // 98
+ NI, // 99
+ NI // 100
+};
+
diff --git a/sc/source/filter/lotus/tool.cxx b/sc/source/filter/lotus/tool.cxx
new file mode 100644
index 000000000000..0e99b1140c2a
--- /dev/null
+++ b/sc/source/filter/lotus/tool.cxx
@@ -0,0 +1,651 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/solar.h>
+
+#include "cell.hxx"
+#include "rangenam.hxx"
+#include "compiler.hxx"
+
+#include "tool.h"
+#include "decl.h"
+#include "root.hxx"
+#include "lotrange.hxx"
+#include "namebuff.hxx"
+#include "ftools.hxx"
+
+#include <math.h>
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+//--------------------------------------------------------- EXTERNE VARIABLEN -
+extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
+extern sal_Char* pDummy2; // -> memory.cxx
+extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
+extern CharSet eCharNach; // -> filter.cxx, Zeichenkonvertierung von->nach
+
+extern BOOL bFormInit; // -> memory.cxx, fuer GetFormHandle()
+
+//--------------------------------------------------------- GLOBALE VARIABLEN -
+BYTE nDefaultFormat; // -> op.cpp, Standard-Zellenformat
+
+extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
+extern ScProtectionAttr* pAttrUnprot;
+extern SfxUInt32Item** pAttrValForms;
+
+SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
+ // -> in memory.cxx initialisiert
+ScProtectionAttr* pAttrUnprot; // -> " memory.cxx "
+
+extern FormCache* pValueFormCache; // -> in memory.cxx initialisiert
+FormCache* pValueFormCache;
+
+SCCOL LotusRangeList::nEingCol;
+SCROW LotusRangeList::nEingRow;
+
+
+
+
+void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString )
+{
+ // Label-Format-Auswertung
+ DBG_ASSERT( pString != NULL, "PutFormString(): pString == NULL" );
+
+ sal_Char cForm;
+ SvxHorJustifyItem* pJustify = NULL;
+
+ cForm = *pString;
+
+ switch( cForm )
+ {
+ case '"': // rechtsbuendig
+ pJustify = pAttrRight;
+ pString++;
+ break;
+ case '\'': // linksbuendig
+ pJustify = pAttrLeft;
+ pString++;
+ break;
+ case '^': // zentriert
+ pJustify = pAttrCenter;
+ pString++;
+ break;
+ case '|': // printer command
+ pString = NULL;
+ break;
+ case '\\': // Wiederholung
+ pJustify = pAttrRepeat;
+ pString++;
+ break;
+ default: // kenn' ich nicht!
+ pJustify = pAttrStandard;
+ }
+
+ if( pString )
+ {
+ pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
+ ScStringCell* pZelle = new ScStringCell( String( pString, pLotusRoot->eCharsetQ ) );
+ pDoc->PutCell( nCol, nRow, nTab, pZelle, ( BOOL ) TRUE );
+ }
+}
+
+
+
+
+void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, BYTE nFormat, BYTE nSt )
+{
+ // PREC: nSt = Standard-Dezimalstellenanzahl
+ pDoc->ApplyAttr( nCol, nRow, nTab, *( pValueFormCache->GetAttr( nFormat, nSt ) ) );
+
+ ScProtectionAttr aAttr;
+
+ aAttr.SetProtection( nFormat & 0x80 );
+
+ pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
+}
+
+void InitPage( void )
+{ // Seitenformat initialisieren, d.h. Default-Werte von SC holen
+ //scGetPageFormat( 0, &aPage );
+}
+
+
+double SnumToDouble( INT16 nVal )
+{
+ const double pFacts[ 8 ] = {
+ 5000.0,
+ 500.0,
+ 0.05,
+ 0.005,
+ 0.0005,
+ 0.00005,
+ 0.0625,
+ 0.015625 };
+
+ double fVal;
+
+ if( nVal & 0x0001 )
+ {
+ fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
+ fVal *= ( INT16 ) ( nVal >> 4 );
+ }
+ else
+ fVal = ( INT16 ) ( nVal >> 1 );
+
+ return fVal;
+}
+
+double Snum32ToDouble( UINT32 nValue )
+{
+ double fValue, temp;
+
+ fValue = nValue >> 6;
+ temp = nValue & 0x0f;
+ if (temp)
+ {
+ if (nValue & 0x00000010)
+ fValue /= pow((double)10, temp);
+ else
+ fValue *= pow((double)10, temp);
+ }
+
+ if ((nValue & 0x00000020))
+ fValue = -fValue;
+ return fValue;
+}
+
+
+FormCache::FormCache( ScDocument* pDoc1, BYTE nNewDefaultFormat )
+{ // Default-Format ist 'Default'
+ nDefaultFormat = nNewDefaultFormat;
+ pFormTable = pDoc1->GetFormatTable();
+ for( UINT16 nC = 0 ; nC < __nSize ; nC++ )
+ bValid[ nC ] = FALSE;
+ eLanguage = ScGlobal::eLnge;
+}
+
+
+FormCache::~FormCache()
+{
+ for( UINT16 nC = 0 ; nC < __nSize ; nC++ )
+ delete aIdents[ nC ].GetAttr();
+}
+
+
+SfxUInt32Item* FormCache::NewAttr( BYTE nFormat, BYTE nSt )
+{
+ // neues Format erzeugen
+ BYTE nL, nH; // Low-/High-Nibble
+ BYTE nForm = nFormat;
+ String aFormString;
+ const sal_Char* pFormString = 0;
+ INT16 eType = NUMBERFORMAT_ALL;
+ UINT32 nIndex1;
+ UINT32 nHandle;
+ BOOL bDefault = FALSE;
+ //void GenerateFormat( aFormString, eType, COUNTRY_SYSTEM, LANGUAGE_SYSTEM,
+ // BOOL bThousand, BOOL IsRed, UINT16 nPrecision, UINT16 nAnzLeading );
+
+ if( nForm == 0xFF ) // Default-Format?
+ nForm = nDefaultFormat;
+
+ // Aufdroeseln in Low- und High-Nibble
+ nL = nFormat & 0x0F;
+ nH = ( nFormat & 0xF0 ) / 16;
+
+ nH &= 0x07; // Bits 4-6 'rausziehen
+ switch( nH )
+ {
+ case 0x00: // Festkommaformat (fixed)
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ break;
+ case 0x01: // Exponentdarstellung (scientific notation)
+ //fExponent;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_SCIENTIFIC, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ break;
+ case 0x02: // Waehrungsdarstellung (currency)
+ //fMoney;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_CURRENCY, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ break;
+ case 0x03: // Prozent
+ //fPercent;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_PERCENT, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ break;
+ case 0x04: // Komma
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, TRUE, FALSE, nL, 1 );
+ break;
+ case 0x05: // frei
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ break;
+ case 0x06: // frei
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ nIndex1 = 0;
+ break;
+ case 0x07: // Spezialformat
+ switch( nL )
+ {
+ case 0x00: // +/-
+ //fStandard;nSt;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, TRUE, nSt, 1 );
+ break;
+ case 0x01: // generelles Format
+ //fStandard;nSt;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nSt, 1 );
+ break;
+ case 0x02: // Datum: Tag, Monat, Jahr
+ //fDate;dfDayMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MM.JJJJ";
+ break;
+ case 0x03: // Datum: Tag, Monat
+ //fDate;dfDayMonthLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MMMM";
+ break;
+ case 0x04: // Datum: Monat, Jahr
+ //fDate;dfMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "MM.JJJJ";
+ break;
+ case 0x05: // Textformate
+ //fString;nSt;
+ eType = NUMBERFORMAT_TEXT;
+ pFormString = "@";
+ break;
+ case 0x06: // versteckt
+ //wFlag |= paHideAll;bSetFormat = FALSE;
+ eType = NUMBERFORMAT_NUMBER;
+ pFormString = "";
+ break;
+ case 0x07: // Time: hour, min, sec
+ //fTime;tfHourMinSec24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM:SS";
+ break;
+ case 0x08: // Time: hour, min
+ //fTime;tfHourMin24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM";
+ break;
+ case 0x09: // Date, intern INT32 1
+ //fDate;dfDayMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MM.JJJJ";
+ break;
+ case 0x0A: // Date, intern INT32 2
+ //fDate;dfDayMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MM.JJJJ";
+ break;
+ case 0x0B: // Time, intern INT32 1
+ //fTime;tfHourMinSec24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM:SS";
+ break;
+ case 0x0C: // Time, intern INT32 2
+ //fTime;tfHourMinSec24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM:SS";
+ break;
+ case 0x0F: // Standardeinstellung
+ //fStandard;nSt;
+ bDefault = TRUE;
+ break;
+ default:
+ //fStandard;nSt;
+ bDefault = TRUE;
+ break;
+ }
+ break;
+ default:
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, FALSE, FALSE, nL, 1 );
+ nIndex1 = 0;
+ break;
+ }
+
+ // Format in Table schieben
+ if( bDefault )
+ nHandle = 0;
+ else
+ {
+ if( pFormString )
+ aFormString.AssignAscii( pFormString );
+
+ xub_StrLen nDummy;
+ pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
+ }
+
+ return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( UINT32 ) nHandle );
+}
+
+
+
+
+void LotusRange::MakeHash( void )
+{
+ // 33222222222211111111110000000000
+ // 10987654321098765432109876543210
+ // ******** nColS
+ // ******** nColE
+ // **************** nRowS
+ // **************** nRowE
+ nHash = static_cast<UINT32>(nColStart);
+ nHash += static_cast<UINT32>(nColEnd) << 6;
+ nHash += static_cast<UINT32>(nRowStart) << 12;
+ nHash += static_cast<UINT32>(nRowEnd ) << 16;
+}
+
+
+LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
+{
+ nColStart = nColEnd = nCol;
+ nRowStart = nRowEnd = nRow;
+ nId = ID_FAIL;
+ MakeHash();
+}
+
+
+LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
+{
+ nColStart = nCS;
+ nColEnd = nCE;
+ nRowStart = nRS;
+ nRowEnd = nRE;
+ nId = ID_FAIL;
+ MakeHash();
+}
+
+
+LotusRange::LotusRange( const LotusRange& rCpy )
+{
+ Copy( rCpy );
+}
+
+
+
+
+
+LotusRangeList::LotusRangeList( void )
+{
+ aComplRef.InitFlags();
+
+ ScSingleRefData* pSingRef;
+ nIdCnt = 1;
+
+ pSingRef = &aComplRef.Ref1;
+ pSingRef->nTab = pSingRef->nRelTab = 0;
+ pSingRef->SetColRel( FALSE );
+ pSingRef->SetRowRel( FALSE );
+ pSingRef->SetTabRel( TRUE );
+ pSingRef->SetFlag3D( FALSE );
+
+ pSingRef = &aComplRef.Ref2;
+ pSingRef->nTab = pSingRef->nRelTab = 0;
+ pSingRef->SetColRel( FALSE );
+ pSingRef->SetRowRel( FALSE );
+ pSingRef->SetTabRel( TRUE );
+ pSingRef->SetFlag3D( FALSE );
+}
+
+
+LotusRangeList::~LotusRangeList( void )
+ {
+ LotusRange *pDel = ( LotusRange * ) List::First();
+
+ while( pDel )
+ {
+ delete pDel;
+ pDel = ( LotusRange * ) List::Next();
+ }
+ }
+
+
+LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
+{
+ LotusRange* pComp = ( LotusRange* ) List::First();
+
+ while( pComp )
+ {
+ if( *pComp == rRef )
+ return pComp->nId;
+ pComp = ( LotusRange* ) List::Next();
+ }
+
+ return ID_FAIL;
+}
+
+
+void LotusRangeList::Append( LotusRange* pLR, const String& rName )
+{
+ DBG_ASSERT( pLR, "*LotusRangeList::Append(): das wird nichts!" );
+ List::Insert( pLR, CONTAINER_APPEND );
+
+ ScTokenArray aTokArray;
+
+ ScSingleRefData* pSingRef = &aComplRef.Ref1;
+
+ pSingRef->nCol = pLR->nColStart;
+ pSingRef->nRow = pLR->nRowStart;
+
+ if( pLR->IsSingle() )
+ aTokArray.AddSingleReference( *pSingRef );
+ else
+ {
+ pSingRef = &aComplRef.Ref2;
+ pSingRef->nCol = pLR->nColEnd;
+ pSingRef->nRow = pLR->nRowEnd;
+ aTokArray.AddDoubleReference( aComplRef );
+ }
+
+ ScRangeData* pData = new ScRangeData(
+ pLotusRoot->pDoc, rName, aTokArray );
+
+ pLotusRoot->pScRangeName->Insert( pData );
+
+ pLR->SetId( nIdCnt );
+
+ nIdCnt++;
+}
+
+
+
+
+RangeNameBufferWK3::RangeNameBufferWK3( void )
+{
+ pScTokenArray = new ScTokenArray;
+ nIntCount = 1;
+}
+
+
+RangeNameBufferWK3::~RangeNameBufferWK3()
+{
+ ENTRY* pDel = ( ENTRY* ) List::First();
+
+ while( pDel )
+ {
+ delete pDel;
+ pDel = ( ENTRY* ) List::Next();
+ }
+
+ delete pScTokenArray;
+}
+
+
+void RangeNameBufferWK3::Add( const String& rOrgName, const ScComplexRefData& rCRD )
+{
+ String aScName( rOrgName );
+ ScfTools::ConvertToScDefinedName( aScName );
+
+ register ENTRY* pInsert = new ENTRY( rOrgName, aScName, rCRD );
+
+ List::Insert( pInsert, CONTAINER_APPEND );
+
+ pScTokenArray->Clear();
+
+ register const ScSingleRefData& rRef1 = rCRD.Ref1;
+ register const ScSingleRefData& rRef2 = rCRD.Ref2;
+
+ if( rRef1.nCol == rRef2.nCol && rRef1.nRow == rRef2.nRow && rRef1.nTab == rRef2.nTab )
+ {
+ pScTokenArray->AddSingleReference( rCRD.Ref1 );
+ pInsert->bSingleRef = TRUE;
+ }
+ else
+ {
+ pScTokenArray->AddDoubleReference( rCRD );
+ pInsert->bSingleRef = FALSE;
+ }
+
+ ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray );
+
+ pInsert->nRelInd = nIntCount;
+ pData->SetIndex( nIntCount );
+ nIntCount++;
+
+ pLotusRoot->pScRangeName->Insert( pData );
+}
+
+
+BOOL RangeNameBufferWK3::FindRel( const String& rRef, UINT16& rIndex )
+{
+ StringHashEntry aRef( rRef );
+
+ ENTRY* pFind = ( ENTRY* ) List::First();
+
+ while( pFind )
+ {
+ if( aRef == pFind->aStrHashEntry )
+ {
+ rIndex = pFind->nRelInd;
+ return TRUE;
+ }
+ pFind = ( ENTRY* ) List::Next();
+ }
+
+ return FALSE;
+}
+
+
+BOOL RangeNameBufferWK3::FindAbs( const String& rRef, UINT16& rIndex )
+{
+ String aTmp( rRef );
+ StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
+
+ ENTRY* pFind = ( ENTRY* ) List::First();
+
+ while( pFind )
+ {
+ if( aRef == pFind->aStrHashEntry )
+ {
+ // eventuell neuen Range Name aufbauen
+ if( pFind->nAbsInd )
+ rIndex = pFind->nAbsInd;
+ else
+ {
+ ScSingleRefData* pRef = &pFind->aScComplexRefDataRel.Ref1;
+ pScTokenArray->Clear();
+
+ pRef->SetColRel( FALSE );
+ pRef->SetRowRel( FALSE );
+ pRef->SetTabRel( TRUE );
+
+ if( pFind->bSingleRef )
+ pScTokenArray->AddSingleReference( *pRef );
+ else
+ {
+ pRef = &pFind->aScComplexRefDataRel.Ref2;
+ pRef->SetColRel( FALSE );
+ pRef->SetRowRel( FALSE );
+ pRef->SetTabRel( TRUE );
+ pScTokenArray->AddDoubleReference( pFind->aScComplexRefDataRel );
+ }
+
+ ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, pFind->aScAbsName, *pScTokenArray );
+
+ rIndex = pFind->nAbsInd = nIntCount;
+ pData->SetIndex( rIndex );
+ nIntCount++;
+
+ pLotusRoot->pScRangeName->Insert( pData );
+ }
+
+ return TRUE;
+ }
+ pFind = ( ENTRY* ) List::Next();
+ }
+
+ return FALSE;
+}
+
+
diff --git a/sc/source/filter/qpro/biff.cxx b/sc/source/filter/qpro/biff.cxx
new file mode 100644
index 000000000000..1d490358d315
--- /dev/null
+++ b/sc/source/filter/qpro/biff.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sal/config.h>
+#include <stdio.h>
+#include <sfx2/docfile.hxx>
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "biff.hxx"
+
+ScBiffReader::ScBiffReader( SfxMedium & rMedium ) :
+ mnId(0),
+ mnLength(0),
+ mnOffset(0)
+{
+ mpStream = rMedium.GetInStream();
+ if( mpStream )
+ {
+ mpStream->SetBufferSize( 65535 );
+ mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
+ }
+}
+
+ScBiffReader::~ScBiffReader()
+{
+ if( mpStream )
+ mpStream->SetBufferSize( 0 );
+}
+
+bool ScBiffReader::nextRecord()
+{
+ if( !recordsLeft() )
+ return false;
+
+ if( IsEndOfFile() )
+ return false;
+
+ sal_uInt32 nPos = mpStream->Tell();
+ if( nPos != mnOffset + mnLength )
+ mpStream->Seek( mnOffset + mnLength );
+
+ mnLength = mnId = 0;
+ *mpStream >> mnId >> mnLength;
+
+ mnOffset = mpStream->Tell();
+#ifdef DEBUG
+ fprintf( stderr, "Read record 0x%x length 0x%x at offset 0x%x\n",
+ (unsigned)mnId, (unsigned)mnLength, (unsigned)mnOffset );
+
+#if 1 // rather verbose
+ int len = mnLength;
+ while (len > 0) {
+ int i, chunk = len < 16 ? len : 16;
+ unsigned char data[16];
+ mpStream->Read( data, chunk );
+
+ for (i = 0; i < chunk; i++)
+ fprintf( stderr, "%.2x ", data[i] );
+ fprintf( stderr, "| " );
+ for (i = 0; i < chunk; i++)
+ fprintf( stderr, "%c", data[i] < 127 && data[i] > 30 ? data[i] : '.' );
+ fprintf( stderr, "\n" );
+
+ len -= chunk;
+ }
+ mpStream->Seek( mnOffset );
+#endif
+#endif
+ return true;
+}
+
diff --git a/sc/source/filter/qpro/makefile.mk b/sc/source/filter/qpro/makefile.mk
new file mode 100644
index 000000000000..fa8b018f23b7
--- /dev/null
+++ b/sc/source/filter/qpro/makefile.mk
@@ -0,0 +1,57 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=qpro
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+AUTOSEG=true
+
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/qpro.obj \
+ $(SLO)$/qproform.obj \
+ $(SLO)$/qprostyle.obj \
+ $(SLO)$/biff.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/qpro/qpro.cxx b/sc/source/filter/qpro/qpro.cxx
new file mode 100644
index 000000000000..084aab135f70
--- /dev/null
+++ b/sc/source/filter/qpro/qpro.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sal/config.h>
+#include <stdio.h>
+#include <sfx2/docfile.hxx>
+
+#include "qproform.hxx"
+#include "qpro.hxx"
+#include "qprostyle.hxx"
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "biff.hxx"
+#include <tools/stream.hxx>
+
+FltError ScQProReader::readSheet( SCTAB nTab, ScDocument* pDoc, ScQProStyle *pStyle )
+{
+ FltError eRet = eERR_OK;
+ sal_uInt8 nCol, nDummy;
+ sal_uInt16 nRow;
+ sal_uInt16 nStyle;
+ bool bEndOfSheet = false;
+
+#ifdef DEBUG
+ fprintf( stderr, "Read sheet (%d)\n", nTab );
+#endif
+
+ while( eERR_OK == eRet && !bEndOfSheet && nextRecord() )
+ {
+ switch( getId() )
+ {
+ case 0x000f:{ // Label cell
+ String aLabel;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nDummy;
+ readString( aLabel, getLength() - 7 );
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( aLabel, pDoc ), (BOOL) TRUE );
+ }
+ break;
+
+ case 0x00cb: // End of sheet
+ bEndOfSheet = true;
+ break;
+
+ case 0x000c: // Blank cell
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle;
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ break;
+
+ case 0x000d:{ // Integer cell
+ sal_Int16 nValue;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue;
+ ScValueCell* pInteger = new ScValueCell( ( double ) nValue );
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell(nCol ,nRow, nTab ,pInteger,(BOOL) TRUE);
+ }
+ break;
+
+ case 0x000e:{ // Floating point cell
+ double nValue;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue;
+ ScValueCell* pFloat = new ScValueCell( nValue );
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell( nCol, nRow, nTab, pFloat, (BOOL) TRUE );
+ }
+ break;
+
+ case 0x0010:{ // Formula cell
+ double nValue;
+ sal_uInt16 nState, nLen;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue >> nState >> nLen;
+ ScAddress aAddr( nCol, nRow, nTab );
+ const ScTokenArray *pArray;
+ QProToSc aConv( *mpStream, aAddr );
+ if (ConvOK != aConv.Convert( pArray, nLen ))
+ eRet = eERR_FORMAT;
+ else
+ {
+ ScFormulaCell *pFormula = new ScFormulaCell( pDoc, aAddr, pArray );
+ nStyle = nStyle >> 3;
+ pFormula->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell( nCol, nRow, nTab, pFormula, ( BOOL ) TRUE );
+ }
+ }
+ break;
+ }
+ }
+ return eRet;
+}
+
+FltError ScFormatFilterPluginImpl::ScImportQuattroPro( SfxMedium &rMedium, ScDocument *pDoc )
+{
+ FltError eRet = eERR_OK;
+ ScQProReader aReader( rMedium );
+ eRet = aReader.import( pDoc );
+ return eRet;
+}
+
+ScQProReader::ScQProReader( SfxMedium &rMedium ):
+ ScBiffReader( rMedium )
+{
+}
+
+FltError ScQProReader::import( ScDocument *pDoc )
+{
+ FltError eRet = eERR_OK;
+ sal_uInt16 nVersion;
+ sal_uInt16 i = 1, j = 1;
+ SCTAB nTab = 0;
+ SetEof( FALSE );
+
+ if( !recordsLeft() )
+ return eERR_OPEN;
+
+ ScQProStyle *pStyleElement = new ScQProStyle;
+
+ while( nextRecord() && eRet == eERR_OK)
+ {
+ switch( getId() )
+ {
+ case 0x0000: // Begginning of file
+ *mpStream >> nVersion;
+ break;
+
+ case 0x00ca: // Beginning of sheet
+ if( nTab <= MAXTAB )
+ {
+ if( nTab < 26 )
+ {
+ String aName;
+ aName.Append( sal_Unicode( 'A' + nTab ) );
+ if (!nTab)
+ pDoc->RenameTab( nTab, aName, FALSE, FALSE);
+ else
+ pDoc->InsertTab( nTab, aName );
+ }
+ eRet = readSheet( nTab, pDoc, pStyleElement );
+ nTab++;
+ }
+ break;
+
+ case 0x0001: // End of file
+ SetEof( TRUE );
+ break;
+
+ case 0x00ce:{ // Attribute cell
+ sal_uInt8 nFormat, nAlign, nFont;
+ sal_Int16 nColor;
+ *mpStream >> nFormat >> nAlign >> nColor >> nFont;
+ pStyleElement->setAlign( i, nAlign );
+ pStyleElement->setFont( i, nFont );
+ i++;
+ }
+ break;
+
+ case 0x00cf:{ // Font description
+ sal_uInt16 nPtSize, nFontAttr;
+ String aLabel;
+ *mpStream >> nPtSize >> nFontAttr;
+ pStyleElement->setFontRecord( j, nFontAttr, nPtSize );
+ readString( aLabel, getLength() - 4 );
+ pStyleElement->setFontType( j, aLabel );
+ j++;
+ }
+ break;
+ }
+ }
+ pDoc->CalcAfterLoad();
+ delete pStyleElement;
+ return eRet;
+}
+
+bool ScQProReader::recordsLeft()
+{
+ bool bValue = ScBiffReader::recordsLeft();
+ return bValue;
+}
+
+bool ScQProReader::nextRecord()
+{
+ bool bValue = ScBiffReader::nextRecord();
+ return bValue;
+}
+
+void ScQProReader::readString( String &rString, sal_uInt16 nLength )
+{
+ sal_Char* pText = new sal_Char[ nLength + 1 ];
+ mpStream->Read( pText, nLength );
+ pText[ nLength ] = 0;
+ rString = String( pText, mpStream->GetStreamCharSet() );
+ delete [] pText;
+}
diff --git a/sc/source/filter/qpro/qproform.cxx b/sc/source/filter/qpro/qproform.cxx
new file mode 100644
index 000000000000..9cb4a2d7b245
--- /dev/null
+++ b/sc/source/filter/qpro/qproform.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sal/config.h>
+#include "qpro.hxx"
+
+#include "qproform.hxx"
+#include "formel.hxx"
+#include "compiler.hxx"
+#include <tokstack.hxx>
+#include "ftools.hxx"
+
+void QProToSc::ReadSRD( ScSingleRefData& rSRD, sal_Int8 nPage, sal_Int8 nCol, sal_uInt16 nRelBit )
+{
+ UINT16 nTmp = nRelBit & 0x1fff;
+ rSRD.InitAddress( ScAddress( nCol, (~nTmp + 1), 0 ) );
+ if( nRelBit & 0x4000 )
+ {
+ rSRD.nRelCol = nCol;
+ rSRD.SetColRel( TRUE );
+ }
+ else
+ {
+ rSRD.nCol = nCol;
+ rSRD.SetColRel( FALSE );
+ }
+ if( nRelBit & 0x2000 )
+ {
+ rSRD.nRelRow = (~nTmp + 1);
+ rSRD.nRelRow = (INT16)(nTmp << 3);
+ rSRD.nRelRow /= 8;
+ rSRD.SetRowRel( TRUE );
+ }
+ else
+ {
+ rSRD.nRow = nTmp;
+ rSRD.SetRowRel( FALSE );
+ }
+ if( nRelBit & 0x8000 )
+ {
+ rSRD.nRelTab = nPage;
+ rSRD.SetTabRel( TRUE );
+ // absolute tab needed in caller for comparison in case of DoubleRef
+ rSRD.nTab = aEingPos.Tab() + nPage;
+ }
+ else
+ {
+ rSRD.nTab = nPage;
+ rSRD.SetTabRel( FALSE );
+ }
+ if (rSRD.nTab != aEingPos.Tab())
+ rSRD.SetFlag3D( TRUE);
+}
+
+QProToSc::QProToSc( SvStream& rStream, const ScAddress& rRefPos ) :
+ ConverterBase( 128 ),
+ maIn( rStream )
+{
+ aEingPos = rRefPos;
+}
+
+void QProToSc::DoFunc( DefTokenId eOc, sal_uInt16 nArgs, const sal_Char* pExtString )
+{
+ TokenId eParam[ nBufSize ];
+ INT32 nCount;
+ TokenId nPush, nPush1;
+
+ BOOL bAddIn = FALSE;
+ BOOL bNeg = FALSE;
+
+ if( eOc == ocNoName )
+ {
+ bAddIn = TRUE;
+ if( pExtString )
+ {
+ ByteString s;
+ s = pExtString;
+ s.Insert( "QPRO_", 0 );
+ nPush = aPool.Store( eOc, String( s, maIn.GetStreamCharSet() ) );
+ aPool << nPush;
+ }
+ else
+ aPool << ocNoName;
+ }
+
+ if( nArgs < nBufSize )
+ {
+ for( nCount = 0; nCount < nArgs ; nCount++ )
+ aStack >> eParam[ nCount ];
+ }
+ else
+ return;
+
+ switch( eOc )
+ {
+ case ocIndex:
+ nPush = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nPush;
+ IncToken( eParam[ 0 ] );
+ IncToken( eParam[ 1 ] );
+ break;
+
+ case ocIRR:
+ nPush = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nPush;
+ break;
+
+ case ocGetYear:
+ nPush = aPool.Store( 1900.0 );
+ aPool << ocOpen;
+ break;
+
+ default:
+ break;
+ }
+
+ if( !bAddIn )
+ aPool << eOc;
+
+ aPool << ocOpen;
+
+ if( nArgs> 0 )
+ {
+ INT16 nNull = -1;
+ INT16 nLast = nArgs- 1;
+
+ if( eOc == ocZGZ )
+ aPool << eParam[ 2 ] << ocSep << eParam[ 1 ] << ocSep << eParam[ 0 ];
+ if( eOc == ocZinsZ )
+ aPool << eParam[ 3 ] << ocSep << eParam[ 2 ] << ocSep << eParam[ 1 ] << ocSep << eParam[ 0 ];
+ else
+ {
+ aPool << eParam[ nLast ];
+ for( nCount = nLast - 1 ; nCount >= 0 ; nCount-- )
+ {
+ if( nCount != nNull )
+ aPool << ocSep << eParam[ nCount ];
+ }
+ }
+ }
+
+ if( eOc == ocGetYear )
+ aPool << ocClose << ocSub << nPush;
+ else if( eOc == ocFixed )
+ aPool << ocSep << ocTrue << ocOpen << ocClose;
+
+ aPool << ocClose;
+ aPool >> aStack;
+
+ if( bNeg )
+ {
+ aPool << ocOpen << ocSub << aStack << ocClose;
+ aPool >> aStack;
+ }
+}
+
+void QProToSc::IncToken( TokenId &rParam )
+{
+ aPool << ocOpen << rParam << mnAddToken;
+ rParam = aPool.Store();
+}
+
+#define SAFEDEC_OR_RET(nRef, amt, ret) \
+do { \
+ if (nRef < amt)\
+ return ret; \
+ nRef-=amt; \
+} while(0)
+
+ConvErr QProToSc::Convert( const ScTokenArray*& pArray, sal_uInt16 /*nLen*/, const FORMULA_TYPE /*eFT*/ )
+{
+ sal_uInt8 nFmla[ nBufSize ], i, nArg, nArgArray[ nBufSize ];
+ sal_Int8 nCol, nPage;
+ sal_uInt16 nInt, nIntCount = 0, nStringCount = 0, nFloatCount = 0, nDLLCount = 0, nIntArray[ nBufSize ], nArgCount = 0;
+ String sStringArray[ nBufSize ];
+ sal_uInt16 nDummy, nDLLId, nDLLArray[ nBufSize ];
+ sal_uInt16 nNote, nRef, nRelBits;
+ TokenId nPush;
+ ScComplexRefData aCRD;
+ ScSingleRefData aSRD;
+ FUNC_TYPE eType;
+ DefTokenId eOc;
+ double nFloatArray[ nBufSize ], nFloat;
+ const sal_Char* pExtString = 0;
+
+ aCRD.InitFlags();
+ aSRD.InitFlags();
+ maIn >> nRef;
+
+ if( nRef < nBufSize )
+ {
+ for( i=0; i < nRef; i++)
+ {
+ maIn >> nFmla[i];
+
+ if( nFmla[ i ] == 0x05 )
+ {
+ maIn >> nInt;
+ nIntArray[ nIntCount ] = nInt;
+ SAFEDEC_OR_RET(nRef, 2, ConvErrCount);
+ nIntCount++;
+ }
+
+ if( nFmla[ i ] == 0x00 )
+ {
+ maIn >> nFloat;
+ nFloatArray[ nFloatCount ] = nFloat;
+ SAFEDEC_OR_RET(nRef, 8, ConvErrCount);
+ nFloatCount++;
+ }
+
+ if( nFmla[ i ] == 0x1a )
+ {
+ maIn >> nArg >> nDummy >> nDLLId;
+ nArgArray[ nArgCount ] = nArg;
+ nDLLArray[ nDLLCount ] = nDLLId;
+ SAFEDEC_OR_RET(nRef, 5, ConvErrCount);
+ nDLLCount++;
+ nArgCount++;
+ }
+ if( nFmla[ i ] == 0x06 )
+ {
+ String aTmp( ScfTools::ReadCString( maIn ), maIn.GetStreamCharSet() );
+ sStringArray[ nStringCount ] = aTmp;
+ nStringCount++;
+ SAFEDEC_OR_RET(nRef, aTmp.Len() + 1, ConvErrCount);
+ }
+ }
+ }
+ else
+ return ConvErrCount;
+
+ i = 0, nIntCount = 0, nFloatCount = 0, nDLLCount = 0, nArgCount = 0, nStringCount =0;
+
+ while( i < nRef && ( nFmla[ i ] != 0x03 ) )
+ {
+ eType = IndexToType( nFmla[ i ] );
+ eOc = IndexToToken( nFmla[ i ] );
+ if( eOc == ocNoName )
+ pExtString = getString( nFmla[ i ] );
+
+ switch( eType )
+ {
+ case FT_NotImpl:
+ DoFunc( ocNoName, 0, pExtString );
+ break;
+
+ case FT_FuncFix0:
+ DoFunc( eOc, 0, NULL );
+ break;
+
+ case FT_FuncFix1:
+ DoFunc( eOc, 1, NULL );
+ break;
+
+ case FT_FuncFix2:
+ DoFunc( eOc, 2, NULL );
+ break;
+
+ case FT_FuncFix3:
+ DoFunc( eOc, 3, NULL );
+ break;
+
+ case FT_FuncFix4:
+ DoFunc( eOc, 4, NULL );
+ break;
+
+ case FT_FuncFix5:
+ DoFunc( eOc, 5, NULL );
+ break;
+
+ case FT_FuncFix6:
+ DoFunc( eOc, 6, NULL );
+ break;
+
+ case FT_DLL:{
+ eOc = IndexToDLLId( nDLLArray[ nDLLCount ] );
+ sal_uInt8 nPar = nArgArray[ nArgCount ];
+ DoFunc( eOc, nPar, NULL );
+ nDLLCount++;
+ nArgCount++;
+ }
+ break;
+
+ case FT_Cref : // Single cell reference
+ maIn >> nNote >> nCol >> nPage >> nRelBits;
+ ReadSRD( aSRD, nPage, nCol, nRelBits );
+ aStack << aPool.Store( aSRD );
+ break;
+
+ case FT_Range: // Block reference
+ maIn >> nNote >> nCol >> nPage >> nRelBits;
+ ReadSRD( aCRD.Ref1, nPage, nCol, nRelBits );
+ maIn >> nCol >> nPage >> nRelBits;
+ ReadSRD( aCRD.Ref2, nPage, nCol, nRelBits );
+ // Sheet name of second corner is not displayed if identical
+ if (aCRD.Ref1.IsFlag3D() && aCRD.Ref1.nTab == aCRD.Ref2.nTab &&
+ aCRD.Ref1.IsTabRel() == aCRD.Ref2.IsTabRel())
+ aCRD.Ref2.SetFlag3D( FALSE);
+ aStack << aPool.Store( aCRD );
+ break;
+
+ case FT_FuncVar:{ // Sum of a sequence of numbers
+ sal_uInt8 nArgs;
+ i++;
+ nArgs = nFmla[ i ];
+ DoFunc( eOc, nArgs, NULL );
+ }
+ break;
+
+ case FT_Op: // operators
+ aStack >> nPush;
+ aPool << aStack << eOc << nPush;
+ aPool >> aStack;
+ break;
+
+ case FT_Braces:
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+
+ case FT_ConstInt:{
+ sal_uInt16 nVal;
+ nVal = nIntArray[ nIntCount ];
+ aStack << aPool.Store( ( double ) nVal );
+ nIntCount++;
+ }
+ break;
+
+ case FT_ConstFloat:{
+ double nVal;
+ nVal = nFloatArray[ nFloatCount ];
+ aStack << aPool.Store( nVal );
+ nFloatCount++;
+ }
+ break;
+
+ case FT_ConstString:{
+ String aLabel;
+ aLabel = sStringArray[ nStringCount ];
+ aStack << aPool.Store( aLabel );
+ nStringCount++;
+ }
+ break;
+
+ case FT_Neg:
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+
+ case FT_NOP: // indicates invalid opcode.
+ case FT_Return: // indicates end of formula
+ break;
+ }
+ i++;
+ }
+ pArray = aPool[ aStack.Get() ];
+ return ConvOK;
+}
+
+static const struct
+{
+ DefTokenId nToken;
+ FUNC_TYPE nType;
+} aFuncMap[] = {
+ { ocPush, FT_ConstFloat },
+ { ocPush, FT_Cref },
+ { ocPush, FT_Range },
+ { ocPush, FT_Return },
+ { ocPush, FT_Braces },
+ { ocPush, FT_ConstInt },
+ { ocPush, FT_ConstString },
+ { ocPush, FT_NOP },
+ { ocNegSub, FT_Neg }, // 0x08
+ { ocAdd, FT_Op },
+ { ocSub, FT_Op },
+ { ocMul, FT_Op },
+ { ocDiv, FT_Op },
+ { ocPow, FT_Op },
+ { ocEqual, FT_Op },
+ { ocNotEqual, FT_Op },
+ { ocLessEqual, FT_Op }, // 0x10
+ { ocGreaterEqual, FT_Op },
+ { ocLess, FT_Op },
+ { ocGreater, FT_Op },
+ { ocAnd, FT_Op },
+ { ocOr, FT_Op },
+ { ocNot, FT_FuncFix1 },
+ { ocPush, FT_NOP }, // Unary plus
+ { ocAddress, FT_FuncFix4 }, // Address of
+ { ocNoName, FT_NotImpl }, // Halt function
+ { ocNoName, FT_DLL }, // DLL function
+ { ocNoName, FT_NOP }, // Extended operands
+ { ocNoName, FT_NOP }, // Extended operands
+ { ocNoName, FT_NOP }, // Reserved
+ { ocNoName, FT_NOP }, // Reserved
+ { ocNotAvail, FT_FuncFix0 }, // NA
+ { ocNoName, FT_FuncFix0 }, // Error // 0x20
+ { ocAbs, FT_FuncFix1 },
+ { ocInt, FT_FuncFix1 },
+ { ocSqrt, FT_FuncFix1 },
+ { ocLog10, FT_FuncFix1 },
+ { ocLn, FT_FuncFix1 },
+ { ocPi, FT_FuncFix0 },
+ { ocSin, FT_FuncFix1 },
+ { ocCos, FT_FuncFix1 },
+ { ocTan, FT_FuncFix1 },
+ { ocArcTan2, FT_FuncFix2 },
+ { ocArcTan, FT_FuncFix1 },
+ { ocArcSin, FT_FuncFix1 },
+ { ocArcCos, FT_FuncFix1 },
+ { ocExp, FT_FuncFix1 },
+ { ocMod, FT_FuncFix2 },
+ { ocChose, FT_FuncVar }, // 0x30
+ { ocIsNA, FT_FuncFix1 },
+ { ocIsError, FT_FuncFix1 },
+ { ocFalse, FT_FuncFix0 },
+ { ocTrue, FT_FuncFix0 },
+ { ocRandom, FT_FuncFix0 },
+ { ocGetDate, FT_FuncFix3 },
+ { ocGetActTime, FT_FuncFix0 },
+ { ocNoName, FT_NotImpl }, // QPro Pmt
+ { ocNoName, FT_NotImpl }, // QPro Pv
+ { ocNoName, FT_NotImpl }, // QPro Fv
+ { ocIf, FT_FuncFix3 },
+ { ocGetDay, FT_FuncFix1 },
+ { ocGetMonth, FT_FuncFix1 },
+ { ocGetYear, FT_FuncFix1 },
+ { ocRound, FT_FuncFix2 },
+ { ocGetTime, FT_FuncFix3 }, // 0x40
+ { ocGetHour, FT_FuncFix1 },
+ { ocGetMin, FT_FuncFix1 },
+ { ocGetSec, FT_FuncFix1 },
+ { ocIsValue, FT_FuncFix1 },
+ { ocIsString, FT_FuncFix1 },
+ { ocLen, FT_FuncFix1 },
+ { ocValue, FT_FuncFix1 },
+ { ocFixed, FT_FuncFix2 },
+ { ocMid, FT_FuncFix3 },
+ { ocChar, FT_FuncFix1 },
+ { ocCode, FT_FuncFix1 },
+ { ocFind, FT_FuncFix3 },
+ { ocGetDateValue, FT_FuncFix1 },
+ { ocGetTimeValue, FT_FuncFix1 },
+ { ocNoName, FT_NotImpl },
+ { ocSum, FT_FuncVar }, // 0x50
+ { ocAverage, FT_FuncVar },
+ { ocCount, FT_FuncVar },
+ { ocMin, FT_FuncVar },
+ { ocMax, FT_FuncVar },
+ { ocVLookup, FT_FuncFix3 },
+ { ocNPV, FT_FuncFix2 },
+ { ocVar, FT_FuncVar },
+ { ocNormDist, FT_FuncVar },
+ { ocIRR, FT_FuncFix2 },
+ { ocHLookup, FT_FuncFix3 },
+ { ocDBSum, FT_FuncFix3 },
+ { ocDBAverage, FT_FuncFix3 },
+ { ocDBCount, FT_FuncFix3 },
+ { ocDBMin, FT_FuncFix3 },
+ { ocDBMax, FT_FuncFix3 },
+ { ocDBVar, FT_FuncFix3 }, // 0x60
+ { ocDBStdDev, FT_FuncFix3 },
+ { ocNoName, FT_NotImpl },
+ { ocColumns, FT_FuncFix1 },
+ { ocRows, FT_FuncFix1 },
+ { ocRept, FT_FuncFix2 },
+ { ocUpper, FT_FuncFix1 },
+ { ocLower, FT_FuncFix1 },
+ { ocLeft, FT_FuncFix2 },
+ { ocRight, FT_FuncFix2 },
+ { ocReplace, FT_FuncFix4 },
+ { ocPropper, FT_FuncFix1 },
+ { ocCell, FT_FuncFix2 },
+ { ocTrim, FT_FuncFix1 },
+ { ocClean, FT_FuncFix1 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl }, // 0x70
+ { ocExact, FT_FuncFix2 },
+ { ocNoName, FT_NotImpl }, // Call()
+ { ocIndirect, FT_FuncFix1 },
+ { ocZGZ, FT_FuncFix3 }, // Interest
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocLIA, FT_FuncFix3 },
+ { ocDIA, FT_FuncFix4 },
+ { ocGDA, FT_FuncFix4 },
+ { ocStDevP, FT_FuncVar },
+ { ocVarP, FT_FuncVar },
+ { ocDBStdDevP, FT_FuncVar },
+ { ocDBVarP, FT_FuncVar },
+ { ocBW, FT_FuncFix3 }, // QPro Pval
+ { ocRMZ, FT_FuncFix5 }, // QPro Paymt
+ { ocZW, FT_FuncFix3 }, // QPro Fval // 0x80
+ { ocZZR, FT_FuncFix5 },
+ { ocZins, FT_FuncFix5 },
+ { ocZinsZ, FT_FuncFix4 },
+ { ocKapz, FT_FuncFix6 },
+ { ocSumProduct, FT_FuncFix2 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocDeg, FT_FuncFix1 },
+ { ocRad, FT_FuncFix1 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocGetActDate, FT_FuncFix0 },
+ { ocNPV, FT_FuncFix2 },
+ { ocNoName, FT_NotImpl }, // 0x90
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NOP },
+ { ocNoName, FT_NOP }, // 147
+ { ocNoName, FT_NOP }, // 148
+ { ocNoName, FT_NOP }, // 149
+ { ocNoName, FT_NOP }, // 150
+ { ocNoName, FT_NOP }, // 151
+ { ocNoName, FT_NOP }, // 152
+ { ocNoName, FT_NOP }, // 153
+ { ocTable, FT_FuncFix1 },
+ { ocNoName, FT_NOP }, // 155 - opcodes do not represent any function.
+ { ocNoName, FT_NOP }, // 156
+ { ocIndex, FT_FuncFix4 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl }, // Gives the property of the particular object
+ { ocNoName, FT_NotImpl }, // Dynamic Data Exchange Link // 0x100
+ { ocNoName, FT_NotImpl } // gives properties of DOS menus
+};
+
+const int nIndexCount = sizeof( aFuncMap ) / sizeof( aFuncMap[ 0 ] );
+
+DefTokenId QProToSc::IndexToToken( sal_uInt16 nIndex )
+{
+ if( nIndex < nIndexCount )
+ return aFuncMap[ nIndex ].nToken;
+ return ocNoName;
+}
+
+FUNC_TYPE QProToSc::IndexToType( sal_uInt8 nIndex )
+{
+ if( nIndex < nIndexCount )
+ return aFuncMap[ nIndex ].nType;
+ return FT_NotImpl;
+}
+
+DefTokenId QProToSc::IndexToDLLId( sal_uInt16 nIndex )
+{
+ DefTokenId eId;
+ switch( nIndex )
+ {
+ case 0x0001:
+ eId = ocAveDev;
+ break;
+
+ case 0x0024:
+ eId = ocGCD;
+ break;
+
+ case 0x0025:
+ eId = ocLCM;
+ break;
+
+ case 0x0027:
+ eId = ocCeil;
+ break;
+
+ case 0x0028:
+ eId = ocEven;
+ break;
+
+ case 0x0022:
+ eId = ocFact;
+ break;
+
+ case 0x002a:
+ eId = ocFloor;
+ break;
+
+ case 0x002d:
+ eId = ocOdd;
+ break;
+
+ case 0x0006:
+ eId = ocBetaDist;
+ break;
+
+ case 0x0008:
+ eId = ocBetaInv;
+ break;
+
+ case 0x0010:
+ eId = ocCovar;
+ break;
+
+ case 0x000b:
+ eId = ocChiInv;
+ break;
+
+ case 0x003d:
+ eId = ocLaufz;
+ break;
+
+ case 0x0019:
+ eId = ocFInv;
+ break;
+
+ case 0x001a:
+ eId = ocFisher;
+ break;
+
+ case 0x001b:
+ eId = ocFisherInv;
+ break;
+
+ case 0x0030:
+ eId = ocMedian;
+ break;
+
+ default:
+ eId = ocNoName;
+ break;
+ }
+ return eId;
+}
+
+const sal_Char* QProToSc::getString( sal_uInt8 nIndex )
+{
+ const sal_Char* pExtString = 0;
+ switch( nIndex )
+ {
+ case 57:
+ pExtString = "Pv";
+ break;
+
+ case 58:
+ pExtString = "Fv";
+ break;
+
+ case 98:
+ pExtString = "Index2D";
+ break;
+
+ case 111:
+ pExtString = "S";
+ break;
+
+ case 112:
+ pExtString = "N";
+ break;
+
+ case 114:
+ pExtString = "CALL";
+ break;
+
+ case 117:
+ pExtString = "TERM";
+ break;
+
+ case 118:
+ pExtString = "CTERM";
+ break;
+
+ case 134:
+ pExtString = "MEMAVAIL";
+ break;
+
+ case 135:
+ pExtString = "MEMEMSAVAIL";
+ break;
+
+ case 136:
+ pExtString = "FILEEXISTS";
+ break;
+
+ case 137:
+ pExtString = "CURVALUE";
+ break;
+
+ case 140:
+ pExtString = "HEX";
+ break;
+
+ case 141:
+ pExtString = "NUM";
+ break;
+
+ case 145:
+ pExtString = "VERSION";
+ break;
+
+ case 157:
+ pExtString = "INDEX3D";
+ break;
+
+ case 158:
+ pExtString = "CELLINDEX3D";
+ break;
+
+ case 159:
+ pExtString = "PROPERTY";
+ break;
+
+ case 160:
+ pExtString = "DDE";
+ break;
+
+ case 161:
+ pExtString = "COMMAND";
+ break;
+
+ default:
+ pExtString = NULL;
+ break;
+ }
+ return pExtString;
+}
diff --git a/sc/source/filter/qpro/qprostyle.cxx b/sc/source/filter/qpro/qprostyle.cxx
new file mode 100644
index 000000000000..6213cbb4ebf2
--- /dev/null
+++ b/sc/source/filter/qpro/qprostyle.cxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <sal/config.h>
+#include <stdio.h>
+#include <sfx2/docfile.hxx>
+
+#include "qproform.hxx"
+#include "qpro.hxx"
+#include "qprostyle.hxx"
+
+#include <tools/color.hxx>
+#include <scitems.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <map>
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+
+ScQProStyle::ScQProStyle()
+{
+ rtl_fillMemory (maAlign, sizeof (maAlign), 0);
+ rtl_fillMemory (maFont, sizeof (maFont), 0);
+ rtl_fillMemory (maFontRecord, sizeof (maFontRecord), 0);
+ rtl_fillMemory (maFontHeight, sizeof (maFontHeight), 0);
+}
+
+void ScQProStyle::SetFormat( ScDocument *pDoc, sal_uInt8 nCol, sal_uInt16 nRow, SCTAB nTab, sal_uInt16 nStyle )
+{
+ if (nStyle >= maxsize)
+ return;
+
+ ScPatternAttr aPattern(pDoc->GetPool());
+ SfxItemSet& rItemSet = aPattern.GetItemSet();
+
+ sal_uInt8 nTmp = maAlign[ nStyle ];
+ sal_uInt8 nHor = ( nTmp & 0x07 );
+ sal_uInt8 nVer = ( nTmp & 0x18 );
+ sal_uInt8 nOrient = ( nTmp & 0x60 );
+
+ // Horizontal Alignment
+ SvxCellHorJustify eJustify = SVX_HOR_JUSTIFY_STANDARD;
+ switch( nHor )
+ {
+ case 0x00:
+ eJustify = SVX_HOR_JUSTIFY_STANDARD;
+ break;
+
+ case 0x01:
+ eJustify = SVX_HOR_JUSTIFY_LEFT;
+ break;
+
+ case 0x02:
+ eJustify = SVX_HOR_JUSTIFY_CENTER;
+ break;
+
+ case 0x03:
+ eJustify = SVX_HOR_JUSTIFY_RIGHT;
+ break;
+
+ case 0x04:
+ eJustify = SVX_HOR_JUSTIFY_BLOCK;
+ break;
+ }
+ rItemSet.Put( SvxHorJustifyItem( eJustify, ATTR_HOR_JUSTIFY ) );
+
+ // Vertical Alignment
+ SvxCellVerJustify eVerJustify = SVX_VER_JUSTIFY_STANDARD;
+ switch( nVer )
+ {
+ case 0x00:
+ eVerJustify = SVX_VER_JUSTIFY_BOTTOM;
+ break;
+
+ case 0x08:
+ eVerJustify = SVX_VER_JUSTIFY_CENTER;
+ break;
+
+ case 0x10:
+ eVerJustify = SVX_VER_JUSTIFY_TOP;
+ break;
+ }
+
+ rItemSet.Put(SvxVerJustifyItem( eVerJustify, ATTR_VER_JUSTIFY ) );
+
+ // Orientation
+ SvxCellOrientation eOrient = SVX_ORIENTATION_STANDARD;
+ switch( nOrient )
+ {
+ case 0x20:
+ eOrient = SVX_ORIENTATION_TOPBOTTOM;
+ break;
+
+ }
+ rItemSet.Put( SvxOrientationItem( eOrient, 0) );
+
+ // Wrap cell contents
+ if( nTmp & 0x80 )
+ {
+ SfxBoolItem aWrapItem( ATTR_LINEBREAK );
+ aWrapItem.SetValue( TRUE );
+ rItemSet.Put( aWrapItem );
+ }
+
+ // Font Attributes
+ sal_uInt16 nTmpFnt = maFontRecord[ maFont[ nStyle ] ];
+ BOOL bIsBold, bIsItalic, bIsUnderLine, bIsStrikeThrough;
+
+ bIsBold = ( nTmpFnt & 0x0001 ) != 0;
+ bIsItalic = ( nTmpFnt & 0x0002 ) != 0;
+ bIsUnderLine = ( nTmpFnt & 0x0004 ) != 0;
+ bIsStrikeThrough = (nTmpFnt & 0x0020 ) != 0;
+
+ if( bIsBold )
+ rItemSet.Put( SvxWeightItem( WEIGHT_BOLD,ATTR_FONT_WEIGHT) );
+ if( bIsItalic )
+ rItemSet.Put( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ if( bIsUnderLine )
+ rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+
+ if (maFontHeight[ maFont [ nStyle ] ])
+ rItemSet.Put( SvxFontHeightItem( (ULONG) (20 * maFontHeight[ maFont[ nStyle ] ] ), 100, ATTR_FONT_HEIGHT ) );
+
+ String fntName = maFontType[ maFont[ nStyle ] ];
+ rItemSet.Put( SvxFontItem( FAMILY_SYSTEM, fntName, EMPTY_STRING, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+
+ pDoc->ApplyPattern( nCol, nRow, nTab, aPattern );
+}
diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx
new file mode 100644
index 000000000000..7fb3d16c6c8d
--- /dev/null
+++ b/sc/source/filter/rtf/eeimpars.cxx
@@ -0,0 +1,636 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/adjitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/sfxhtml.hxx>
+#include <svtools/parhtml.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/syslocale.hxx>
+#include <unotools/charclass.hxx>
+
+#include "eeimport.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "editutil.hxx"
+#include "stlsheet.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "eeparser.hxx"
+#include "drwlayer.hxx"
+#include "rangenam.hxx"
+#include "progress.hxx"
+
+#include "globstr.hrc"
+
+// in fuins1.cxx
+extern void ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage );
+
+//------------------------------------------------------------------------
+
+ScEEImport::ScEEImport( ScDocument* pDocP, const ScRange& rRange ) :
+ maRange( rRange ),
+ mpDoc( pDocP ),
+ mpParser( NULL ),
+ mpRowHeights( new Table )
+{
+ const ScPatternAttr* pPattern = mpDoc->GetPattern(
+ maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
+ mpEngine = new ScTabEditEngine( *pPattern, mpDoc->GetEditPool() );
+ mpEngine->SetUpdateMode( FALSE );
+ mpEngine->EnableUndo( FALSE );
+}
+
+
+ScEEImport::~ScEEImport()
+{
+ // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
+ // Ist gewaehrleistet, da ScEEImport Basisklasse ist
+ delete mpEngine; // nach Parser!
+ delete mpRowHeights;
+}
+
+
+ULONG ScEEImport::Read( SvStream& rStream, const String& rBaseURL )
+{
+ ULONG nErr = mpParser->Read( rStream, rBaseURL );
+
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ mpParser->GetDimensions( nEndCol, nEndRow );
+ if ( nEndCol != 0 )
+ {
+ nEndCol += maRange.aStart.Col() - 1;
+ if ( nEndCol > MAXCOL )
+ nEndCol = MAXCOL;
+ }
+ else
+ nEndCol = maRange.aStart.Col();
+ if ( nEndRow != 0 )
+ {
+ nEndRow += maRange.aStart.Row() - 1;
+ if ( nEndRow > MAXROW )
+ nEndRow = MAXROW;
+ }
+ else
+ nEndRow = maRange.aStart.Row();
+ maRange.aEnd.Set( nEndCol, nEndRow, maRange.aStart.Tab() );
+
+ return nErr;
+}
+
+
+void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
+{
+ ScProgress* pProgress = new ScProgress( mpDoc->GetDocumentShell(),
+ ScGlobal::GetRscString( STR_LOAD_DOC ), mpParser->Count() );
+ ULONG nProgress = 0;
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nTab;
+ SCROW nOverlapRowMax, nLastMergedRow;
+ SCCOL nMergeColAdd;
+ nStartCol = maRange.aStart.Col();
+ nStartRow = maRange.aStart.Row();
+ nTab = maRange.aStart.Tab();
+ nEndCol = maRange.aEnd.Col();
+ nEndRow = maRange.aEnd.Row();
+ nOverlapRowMax = 0;
+ nMergeColAdd = 0;
+ nLastMergedRow = SCROW_MAX;
+ BOOL bHasGraphics = FALSE;
+ ScEEParseEntry* pE;
+ if (!pFormatter)
+ pFormatter = mpDoc->GetFormatTable();
+ bool bNumbersEnglishUS = false;
+ if (pFormatter->GetLanguage() == LANGUAGE_SYSTEM)
+ {
+ // Automatic language option selected. Check for the global 'use US English' option.
+ SvxHtmlOptions aOpt;
+ bNumbersEnglishUS = aOpt.IsNumbersEnglishUS();
+ }
+ ScDocumentPool* pDocPool = mpDoc->GetPool();
+ ScRangeName* pRangeNames = mpDoc->GetRangeName();
+ for ( pE = mpParser->First(); pE; pE = mpParser->Next() )
+ {
+ SCROW nRow = nStartRow + pE->nRow;
+ if ( nRow != nLastMergedRow )
+ nMergeColAdd = 0;
+ SCCOL nCol = nStartCol + pE->nCol + nMergeColAdd;
+ // RowMerge feststellen, pures ColMerge und ColMerge der ersten
+ // MergeRow bereits beim parsen
+ if ( nRow <= nOverlapRowMax )
+ {
+ while ( nCol <= MAXCOL && mpDoc->HasAttrib( nCol, nRow, nTab,
+ nCol, nRow, nTab, HASATTR_OVERLAPPED ) )
+ {
+ nCol++;
+ nMergeColAdd++;
+ }
+ nLastMergedRow = nRow;
+ }
+ // fuer zweiten Durchlauf eintragen
+ pE->nCol = nCol;
+ pE->nRow = nRow;
+ if ( ValidCol(nCol) && ValidRow(nRow) )
+ {
+ SfxItemSet aSet = mpEngine->GetAttribs( pE->aSel );
+ // Default raus, wir setzen selber links/rechts je nachdem ob Text
+ // oder Zahl; EditView.GetAttribs liefert immer kompletten Set
+ // mit Defaults aufgefuellt
+ const SfxPoolItem& rItem = aSet.Get( EE_PARA_JUST );
+ if ( ((const SvxAdjustItem&)rItem).GetAdjust() == SVX_ADJUST_LEFT )
+ aSet.ClearItem( EE_PARA_JUST );
+
+ // Testen, ob einfacher String ohne gemischte Attribute
+ BOOL bSimple = ( pE->aSel.nStartPara == pE->aSel.nEndPara );
+ for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END && bSimple; nId++)
+ {
+ const SfxPoolItem* pItem = 0;
+ SfxItemState eState = aSet.GetItemState( nId, TRUE, &pItem );
+ if (eState == SFX_ITEM_DONTCARE)
+ bSimple = FALSE;
+ else if (eState == SFX_ITEM_SET)
+ {
+ if ( nId == EE_CHAR_ESCAPEMENT ) // Hoch-/Tiefstellen immer ueber EE
+ {
+ if ( (SvxEscapement)((const SvxEscapementItem*)pItem)->GetEnumValue()
+ != SVX_ESCAPEMENT_OFF )
+ bSimple = FALSE;
+ }
+ }
+ }
+ if ( bSimple )
+ { // Feldbefehle enthalten?
+ SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bSimple = FALSE;
+ }
+
+ // HTML
+ String aValStr, aNumStr;
+ double fVal;
+ sal_uInt32 nNumForm = 0;
+ LanguageType eNumLang = LANGUAGE_NONE;
+ if ( pE->pNumStr )
+ { // SDNUM muss sein wenn SDVAL
+ aNumStr = *pE->pNumStr;
+ if ( pE->pValStr )
+ aValStr = *pE->pValStr;
+ fVal = SfxHTMLParser::GetTableDataOptionsValNum(
+ nNumForm, eNumLang, aValStr, aNumStr, *pFormatter );
+ }
+
+ // Attribute setzen
+ ScPatternAttr aAttr( pDocPool );
+ aAttr.GetFromEditItemSet( &aSet );
+ SfxItemSet& rSet = aAttr.GetItemSet();
+ if ( aNumStr.Len() )
+ {
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumForm ) );
+ rSet.Put( SvxLanguageItem( eNumLang, ATTR_LANGUAGE_FORMAT ) );
+ }
+ const SfxItemSet& rESet = pE->aItemSet;
+ if ( rESet.Count() )
+ {
+ const SfxPoolItem* pItem;
+ if ( rESet.GetItemState( ATTR_BACKGROUND, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_BORDER, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_SHADOW, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ // HTML
+ if ( rESet.GetItemState( ATTR_HOR_JUSTIFY, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_VER_JUSTIFY, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_LINEBREAK, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_FONT_COLOR, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_FONT_UNDERLINE, FALSE, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ // HTML LATIN/CJK/CTL script type dependent
+ const SfxPoolItem* pFont;
+ if ( rESet.GetItemState( ATTR_FONT, FALSE, &pFont) != SFX_ITEM_SET )
+ pFont = 0;
+ const SfxPoolItem* pHeight;
+ if ( rESet.GetItemState( ATTR_FONT_HEIGHT, FALSE, &pHeight) != SFX_ITEM_SET )
+ pHeight = 0;
+ const SfxPoolItem* pWeight;
+ if ( rESet.GetItemState( ATTR_FONT_WEIGHT, FALSE, &pWeight) != SFX_ITEM_SET )
+ pWeight = 0;
+ const SfxPoolItem* pPosture;
+ if ( rESet.GetItemState( ATTR_FONT_POSTURE, FALSE, &pPosture) != SFX_ITEM_SET )
+ pPosture = 0;
+ if ( pFont || pHeight || pWeight || pPosture )
+ {
+ String aStr( mpEngine->GetText( pE->aSel ) );
+ BYTE nScriptType = mpDoc->GetStringScriptType( aStr );
+ const BYTE nScripts[3] = { SCRIPTTYPE_LATIN,
+ SCRIPTTYPE_ASIAN, SCRIPTTYPE_COMPLEX };
+ for ( BYTE i=0; i<3; ++i )
+ {
+ if ( nScriptType & nScripts[i] )
+ {
+ if ( pFont )
+ rSet.Put( *pFont, ScGlobal::GetScriptedWhichID(
+ nScripts[i], ATTR_FONT ));
+ if ( pHeight )
+ rSet.Put( *pHeight, ScGlobal::GetScriptedWhichID(
+ nScripts[i], ATTR_FONT_HEIGHT ));
+ if ( pWeight )
+ rSet.Put( *pWeight, ScGlobal::GetScriptedWhichID(
+ nScripts[i], ATTR_FONT_WEIGHT ));
+ if ( pPosture )
+ rSet.Put( *pPosture, ScGlobal::GetScriptedWhichID(
+ nScripts[i], ATTR_FONT_POSTURE ));
+ }
+ }
+ }
+ }
+ if ( pE->nColOverlap > 1 || pE->nRowOverlap > 1 )
+ { // merged cells, mit SfxItemSet Put schneller als mit
+ // nachtraeglichem ScDocument DoMerge
+ ScMergeAttr aMerge( pE->nColOverlap, pE->nRowOverlap );
+ rSet.Put( aMerge );
+ SCROW nRO = 0;
+ if ( pE->nColOverlap > 1 )
+ mpDoc->ApplyFlagsTab( nCol+1, nRow,
+ nCol + pE->nColOverlap - 1, nRow, nTab,
+ SC_MF_HOR );
+ if ( pE->nRowOverlap > 1 )
+ {
+ nRO = nRow + pE->nRowOverlap - 1;
+ mpDoc->ApplyFlagsTab( nCol, nRow+1,
+ nCol, nRO , nTab,
+ SC_MF_VER );
+ if ( nRO > nOverlapRowMax )
+ nOverlapRowMax = nRO;
+ }
+ if ( pE->nColOverlap > 1 && pE->nRowOverlap > 1 )
+ mpDoc->ApplyFlagsTab( nCol+1, nRow+1,
+ nCol + pE->nColOverlap - 1, nRO, nTab,
+ SC_MF_HOR | SC_MF_VER );
+ }
+ const ScStyleSheet* pStyleSheet =
+ mpDoc->GetPattern( nCol, nRow, nTab )->GetStyleSheet();
+ aAttr.SetStyleSheet( (ScStyleSheet*)pStyleSheet );
+ mpDoc->SetPattern( nCol, nRow, nTab, aAttr, TRUE );
+
+ // Daten eintragen
+ if (bSimple)
+ {
+ if ( aValStr.Len() )
+ mpDoc->SetValue( nCol, nRow, nTab, fVal );
+ else if ( !pE->aSel.HasRange() )
+ {
+ // maybe ALT text of IMG or similar
+ mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, pFormatter );
+ // wenn SelRange komplett leer kann nachfolgender Text im gleichen Absatz liegen!
+ }
+ else
+ {
+ String aStr;
+ if( pE->bEntirePara )
+ {
+ aStr = mpEngine->GetText( pE->aSel.nStartPara );
+ }
+ else
+ {
+ aStr = mpEngine->GetText( pE->aSel );
+ aStr.EraseLeadingAndTrailingChars();
+ }
+
+ // TODO: RTF import should follow the language tag,
+ // currently this follows the HTML options for both, HTML
+ // and RTF.
+ bool bEnUsRecognized = false;
+ if (bNumbersEnglishUS)
+ {
+ pFormatter->ChangeIntl( LANGUAGE_ENGLISH_US);
+ sal_uInt32 nIndex = pFormatter->GetStandardIndex( LANGUAGE_ENGLISH_US);
+ double fEnVal = 0.0;
+ if (pFormatter->IsNumberFormat( aStr, nIndex, fEnVal))
+ {
+ bEnUsRecognized = true;
+ sal_uInt32 nNewIndex =
+ pFormatter->GetFormatForLanguageIfBuiltIn(
+ nIndex, LANGUAGE_SYSTEM);
+ DBG_ASSERT( nNewIndex != nIndex, "ScEEImport::WriteToDocument: NumbersEnglishUS not a built-in format?");
+ pFormatter->GetInputLineString( fEnVal, nNewIndex, aStr);
+ }
+ pFormatter->ChangeIntl( LANGUAGE_SYSTEM);
+ }
+
+ // #105460#, #i4180# String cells can't contain tabs or linebreaks
+ // -> replace with spaces
+ aStr.SearchAndReplaceAll( (sal_Unicode)'\t', (sal_Unicode)' ' );
+ aStr.SearchAndReplaceAll( (sal_Unicode)'\n', (sal_Unicode)' ' );
+
+ if (bNumbersEnglishUS && !bEnUsRecognized)
+ mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr));
+ else
+ mpDoc->SetString( nCol, nRow, nTab, aStr, pFormatter, bConvertDate );
+ }
+ }
+ else
+ {
+ EditTextObject* pObject = mpEngine->CreateTextObject( pE->aSel );
+ mpDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pObject,
+ mpDoc, mpEngine->GetEditTextObjectPool() ) );
+ delete pObject;
+ }
+ if ( pE->pImageList )
+ bHasGraphics |= GraphicSize( nCol, nRow, nTab, pE );
+ if ( pE->pName )
+ { // Anchor Name => RangeName
+ USHORT nIndex;
+ if ( !pRangeNames->SearchName( *pE->pName, nIndex ) )
+ {
+ ScRangeData* pData = new ScRangeData( mpDoc, *pE->pName,
+ ScAddress( nCol, nRow, nTab ) );
+ pRangeNames->Insert( pData );
+ }
+ }
+ }
+ pProgress->SetStateOnPercent( ++nProgress );
+ }
+ if ( bSizeColsRows )
+ {
+ // Spaltenbreiten
+ Table* pColWidths = mpParser->GetColWidths();
+ if ( pColWidths->Count() )
+ {
+ nProgress = 0;
+ pProgress->SetState( nProgress, nEndCol - nStartCol + 1 );
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; nCol++ )
+ {
+ USHORT nWidth = (USHORT)(ULONG) pColWidths->Get( nCol );
+ if ( nWidth )
+ mpDoc->SetColWidth( nCol, nTab, nWidth );
+ pProgress->SetState( ++nProgress );
+ }
+ }
+ DELETEZ( pProgress ); // SetOptimalHeight hat seinen eigenen ProgressBar
+ // Zeilenhoehen anpassen, Basis 100% Zoom
+ Fraction aZoom( 1, 1 );
+ double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom
+ / nOutputFactor; // Faktor ist Drucker zu Bildschirm
+ double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom;
+ VirtualDevice aVirtDev;
+ mpDoc->SetOptimalHeight( 0, nEndRow, 0,
+ static_cast< USHORT >( ScGlobal::nLastRowHeightExtra ), &aVirtDev,
+ nPPTX, nPPTY, aZoom, aZoom, FALSE );
+ if ( mpRowHeights->Count() )
+ {
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow++ )
+ {
+ USHORT nHeight = (USHORT)(ULONG) mpRowHeights->Get( nRow );
+ if ( nHeight > mpDoc->GetRowHeight( nRow, nTab ) )
+ mpDoc->SetRowHeight( nRow, nTab, nHeight );
+ }
+ }
+ }
+ if ( bHasGraphics )
+ { // Grafiken einfuegen
+ for ( pE = mpParser->First(); pE; pE = mpParser->Next() )
+ {
+ if ( pE->pImageList )
+ {
+ SCCOL nCol = pE->nCol;
+ SCROW nRow = pE->nRow;
+ if ( ValidCol(nCol) && ValidRow(nRow) )
+ InsertGraphic( nCol, nRow, nTab, pE );
+ }
+ }
+ }
+ if ( pProgress )
+ delete pProgress;
+}
+
+
+BOOL ScEEImport::GraphicSize( SCCOL nCol, SCROW nRow, SCTAB /*nTab*/,
+ ScEEParseEntry* pE )
+{
+ ScHTMLImageList* pIL = pE->pImageList;
+ if ( !pIL || !pIL->Count() )
+ return FALSE;
+ BOOL bHasGraphics = FALSE;
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ long nWidth, nHeight;
+ nWidth = nHeight = 0;
+ sal_Char nDir = nHorizontal;
+ for ( ScHTMLImage* pI = pIL->First(); pI; pI = pIL->Next() )
+ {
+ if ( pI->pGraphic )
+ bHasGraphics = TRUE;
+ Size aSizePix = pI->aSize;
+ aSizePix.Width() += 2 * pI->aSpace.X();
+ aSizePix.Height() += 2 * pI->aSpace.Y();
+ Size aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MAP_TWIP ) );
+ if ( nDir & nHorizontal )
+ nWidth += aLogicSize.Width();
+ else if ( nWidth < aLogicSize.Width() )
+ nWidth = aLogicSize.Width();
+ if ( nDir & nVertical )
+ nHeight += aLogicSize.Height();
+ else if ( nHeight < aLogicSize.Height() )
+ nHeight = aLogicSize.Height();
+ nDir = pI->nDir;
+ }
+ // Spaltenbreiten
+ Table* pColWidths = mpParser->GetColWidths();
+ long nThisWidth = (long) pColWidths->Get( nCol );
+ long nColWidths = nThisWidth;
+ SCCOL nColSpanCol = nCol + pE->nColOverlap;
+ for ( SCCOL nC = nCol + 1; nC < nColSpanCol; nC++ )
+ {
+ nColWidths += (long) pColWidths->Get( nC );
+ }
+ if ( nWidth > nColWidths )
+ { // Differenz nur in der ersten Spalte eintragen
+ if ( nThisWidth )
+ pColWidths->Replace( nCol, (void*)(nWidth - nColWidths + nThisWidth) );
+ else
+ pColWidths->Insert( nCol, (void*)(nWidth - nColWidths) );
+ }
+ // Zeilenhoehen, Differenz auf alle betroffenen Zeilen verteilen
+ SCROW nRowSpan = pE->nRowOverlap;
+ nHeight /= nRowSpan;
+ if ( nHeight == 0 )
+ nHeight = 1; // fuer eindeutigen Vergleich
+ for ( SCROW nR = nRow; nR < nRow + nRowSpan; nR++ )
+ {
+ long nRowHeight = (long) mpRowHeights->Get( nR );
+ if ( nHeight > nRowHeight )
+ {
+ if ( nRowHeight )
+ mpRowHeights->Replace( nR, (void*)nHeight );
+ else
+ mpRowHeights->Insert( nR, (void*)nHeight );
+ }
+ }
+ return bHasGraphics;
+}
+
+
+void ScEEImport::InsertGraphic( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScEEParseEntry* pE )
+{
+ ScHTMLImageList* pIL = pE->pImageList;
+ if ( !pIL || !pIL->Count() )
+ return ;
+ ScDrawLayer* pModel = mpDoc->GetDrawLayer();
+ if (!pModel)
+ {
+ mpDoc->InitDrawLayer();
+ pModel = mpDoc->GetDrawLayer();
+ }
+ SdrPage* pPage = pModel->GetPage( static_cast<sal_uInt16>(nTab) );
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+
+ Point aCellInsertPos(
+ (long)((double) mpDoc->GetColOffset( nCol, nTab ) * HMM_PER_TWIPS),
+ (long)((double) mpDoc->GetRowOffset( nRow, nTab ) * HMM_PER_TWIPS) );
+
+ Point aInsertPos( aCellInsertPos );
+ Point aSpace;
+ Size aLogicSize;
+ sal_Char nDir = nHorizontal;
+ for ( ScHTMLImage* pI = pIL->First(); pI; pI = pIL->Next() )
+ {
+ if ( nDir & nHorizontal )
+ { // horizontal
+ aInsertPos.X() += aLogicSize.Width();
+ aInsertPos.X() += aSpace.X();
+ aInsertPos.Y() = aCellInsertPos.Y();
+ }
+ else
+ { // vertikal
+ aInsertPos.X() = aCellInsertPos.X();
+ aInsertPos.Y() += aLogicSize.Height();
+ aInsertPos.Y() += aSpace.Y();
+ }
+ // Offset des Spacings drauf
+ aSpace = pDefaultDev->PixelToLogic( pI->aSpace, MapMode( MAP_100TH_MM ) );
+ aInsertPos += aSpace;
+
+ Size aSizePix = pI->aSize;
+ aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MAP_100TH_MM ) );
+ // Groesse begrenzen
+ ::ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
+
+ if ( pI->pGraphic )
+ {
+ Rectangle aRect ( aInsertPos, aLogicSize );
+ SdrGrafObj* pObj = new SdrGrafObj( *pI->pGraphic, aRect );
+ // #118522# calling SetGraphicLink here doesn't work
+ pObj->SetName( pI->aURL );
+
+ pPage->InsertObject( pObj );
+
+ // #118522# SetGraphicLink has to be used after inserting the object,
+ // otherwise an empty graphic is swapped in and the contact stuff crashes.
+ // See #i37444#.
+ pObj->SetGraphicLink( pI->aURL, pI->aFilterName );
+
+ pObj->SetLogicRect( aRect ); // erst nach InsertObject !!!
+ }
+ nDir = pI->nDir;
+ }
+}
+
+
+ScEEParser::ScEEParser( EditEngine* pEditP ) :
+ pEdit( pEditP ),
+ pPool( EditEngine::CreatePool() ),
+ pDocPool( new ScDocumentPool ),
+ pList( new ScEEParseList ),
+ pColWidths( new Table ),
+ nLastToken(0),
+ nColCnt(0),
+ nRowCnt(0),
+ nColMax(0),
+ nRowMax(0)
+{
+ // pPool wird spaeter bei RTFIMP_START dem SvxRTFParser untergejubelt
+ pPool->SetSecondaryPool( pDocPool );
+ pPool->FreezeIdRanges();
+ NewActEntry( NULL );
+}
+
+
+ScEEParser::~ScEEParser()
+{
+ delete pActEntry;
+ delete pColWidths;
+ for ( ScEEParseEntry* pE = pList->First(); pE; pE = pList->Next() )
+ delete pE;
+ delete pList;
+
+ // Pool erst loeschen nachdem die Listen geloescht wurden
+ pPool->SetSecondaryPool( NULL );
+ SfxItemPool::Free(pDocPool);
+ SfxItemPool::Free(pPool);
+}
+
+
+void ScEEParser::NewActEntry( ScEEParseEntry* pE )
+{ // neuer freifliegender pActEntry
+ pActEntry = new ScEEParseEntry( pPool );
+ pActEntry->aSel.nStartPara = (pE ? pE->aSel.nEndPara + 1 : 0);
+ pActEntry->aSel.nStartPos = 0;
+}
+
+
+
+
diff --git a/sc/source/filter/rtf/expbase.cxx b/sc/source/filter/rtf/expbase.cxx
new file mode 100644
index 000000000000..cd3f30ef9c9f
--- /dev/null
+++ b/sc/source/filter/rtf/expbase.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "expbase.hxx"
+#include "document.hxx"
+#include "editutil.hxx"
+
+
+//------------------------------------------------------------------
+
+#if defined(UNX)
+const sal_Char __FAR_DATA ScExportBase::sNewLine = '\012';
+#else
+const sal_Char __FAR_DATA ScExportBase::sNewLine[] = "\015\012";
+#endif
+
+
+ScExportBase::ScExportBase( SvStream& rStrmP, ScDocument* pDocP,
+ const ScRange& rRangeP )
+ :
+ rStrm( rStrmP ),
+ aRange( rRangeP ),
+ pDoc( pDocP ),
+ pFormatter( pDocP->GetFormatTable() ),
+ pEditEngine( NULL )
+{
+}
+
+
+ScExportBase::~ScExportBase()
+{
+ delete pEditEngine;
+}
+
+
+BOOL ScExportBase::GetDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const
+{
+ pDoc->GetDataStart( nTab, nStartCol, nStartRow );
+ pDoc->GetPrintArea( nTab, nEndCol, nEndRow, TRUE );
+ return TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+
+BOOL ScExportBase::TrimDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const
+{
+ SCCOL nLastCol;
+ while ( nStartCol <= nEndCol && pDoc->ColHidden(nStartCol, nTab, nLastCol))
+ ++nStartCol;
+ while ( nStartCol <= nEndCol && pDoc->ColHidden(nEndCol, nTab, nLastCol))
+ --nEndCol;
+ nStartRow = pDoc->FirstVisibleRow(nStartRow, nEndRow, nTab);
+ nEndRow = pDoc->LastVisibleRow(nStartRow, nEndRow, nTab);
+ return nStartCol <= nEndCol && nStartRow <= nEndRow && nEndRow !=
+ ::std::numeric_limits<SCROW>::max();
+}
+
+
+BOOL ScExportBase::IsEmptyTable( SCTAB nTab ) const
+{
+ if ( !pDoc->HasTable( nTab ) || !pDoc->IsVisible( nTab ) )
+ return TRUE;
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ return !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+
+ScFieldEditEngine& ScExportBase::GetEditEngine() const
+{
+ if ( !pEditEngine )
+ ((ScExportBase*)this)->pEditEngine = new ScFieldEditEngine( pDoc->GetEditPool() );
+ return *pEditEngine;
+}
+
+
diff --git a/sc/source/filter/rtf/makefile.mk b/sc/source/filter/rtf/makefile.mk
new file mode 100644
index 000000000000..a680751de620
--- /dev/null
+++ b/sc/source/filter/rtf/makefile.mk
@@ -0,0 +1,59 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=rtf
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/eeimpars.obj \
+ $(SLO)$/expbase.obj \
+ $(SLO)$/rtfexp.obj \
+ $(SLO)$/rtfimp.obj \
+ $(SLO)$/rtfparse.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/rtf/rtfexp.cxx b/sc/source/filter/rtf/rtfexp.cxx
new file mode 100644
index 000000000000..c817fc2844eb
--- /dev/null
+++ b/sc/source/filter/rtf/rtfexp.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svx/algitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svl/style.hxx>
+#include <svtools/rtfout.hxx>
+#include <svtools/rtfkeywd.hxx>
+
+#include "rtfexp.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "cell.hxx"
+#include "cellform.hxx"
+#include "editutil.hxx"
+#include "stlpool.hxx"
+#include "ftools.hxx"
+
+//------------------------------------------------------------------
+
+FltError ScFormatFilterPluginImpl::ScExportRTF( SvStream& rStrm, ScDocument* pDoc,
+ const ScRange& rRange, const CharSet /*eNach*/ )
+{
+ ScRTFExport aEx( rStrm, pDoc, rRange );
+ return aEx.Write();
+}
+
+
+ScRTFExport::ScRTFExport( SvStream& rStrmP, ScDocument* pDocP, const ScRange& rRangeP )
+ :
+ ScExportBase( rStrmP, pDocP, rRangeP ),
+ pCellX( new ULONG[ MAXCOL+2 ] )
+{
+}
+
+
+ScRTFExport::~ScRTFExport()
+{
+ delete [] pCellX;
+}
+
+
+ULONG ScRTFExport::Write()
+{
+ rStrm << '{' << OOO_STRING_SVTOOLS_RTF_RTF;
+ rStrm << OOO_STRING_SVTOOLS_RTF_ANSI << sNewLine;
+
+#if 0
+// das ist noch nicht ausgegoren
+/*
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = NULL;
+ DBG_ASSERT( pStylePool, "StylePool not found! :-(" );
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find( STRING_STANDARD, SFX_STYLE_FAMILY_PARA );
+ DBG_ASSERT( pStyleSheet, "ParaStyle not found! :-(" );
+ const SfxItemSet& rSetPara = pStyleSheet->GetItemSet();
+
+ // fonttbl
+ String aFontFamilyName(
+ ((const SvxFontItem&)(rSetPara.Get( ATTR_FONT ))).GetFamilyName() );
+ rStrm << OOO_STRING_SVTOOLS_RTF_DEFF << '0'
+ << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL
+ << '{' << OOO_STRING_SVTOOLS_RTF_F << '0' << OOO_STRING_SVTOOLS_RTF_FNIL << ' ' << aFontFamilyName.GetStr() << ";}"
+ << '}' << sNewLine;
+
+ // hier kaeme die colortbl
+
+ // stylesheet
+ UINT32 nFontHeight =
+ ((const SvxFontHeightItem&)(rSetPara.Get( ATTR_FONT_HEIGHT ))).GetHeight();
+ rStrm << '{' << OOO_STRING_SVTOOLS_RTF_STYLESHEET
+ << '{' << OOO_STRING_SVTOOLS_RTF_FS << String( UINT32(nFontHeight / TWIPS_PER_POINT) ).GetStr()
+ << ' ' << pStyleSheet->GetName().GetStr() << ";}"
+ << '}' << sNewLine;
+*/
+#endif
+
+ // Daten
+ for ( SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); nTab++ )
+ {
+ if ( nTab > aRange.aStart.Tab() )
+ rStrm << OOO_STRING_SVTOOLS_RTF_PAR;
+ WriteTab( nTab );
+ }
+
+ rStrm << '}' << sNewLine;
+ return rStrm.GetError();
+}
+
+
+void ScRTFExport::WriteTab( SCTAB nTab )
+{
+ rStrm << '{' << sNewLine;
+ if ( pDoc->HasTable( nTab ) )
+ {
+ memset( &pCellX[0], 0, (MAXCOL+2) * sizeof(ULONG) );
+ SCCOL nCol;
+ SCCOL nEndCol = aRange.aEnd.Col();
+ for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ pCellX[nCol+1] = pCellX[nCol] + pDoc->GetColWidth( nCol, nTab );
+ }
+
+ SCROW nEndRow = aRange.aEnd.Row();
+ for ( SCROW nRow = aRange.aStart.Row(); nRow <= nEndRow; nRow++ )
+ {
+ WriteRow( nTab, nRow );
+ }
+ }
+ rStrm << '}' << sNewLine;
+}
+
+
+void ScRTFExport::WriteRow( SCTAB nTab, SCROW nRow )
+{
+ rStrm << OOO_STRING_SVTOOLS_RTF_TROWD << OOO_STRING_SVTOOLS_RTF_TRGAPH << "30" << OOO_STRING_SVTOOLS_RTF_TRLEFT << "-30";
+ rStrm << OOO_STRING_SVTOOLS_RTF_TRRH << ByteString::CreateFromInt32( pDoc->GetRowHeight( nRow, nTab ) ).GetBuffer();
+ SCCOL nCol;
+ SCCOL nEndCol = aRange.aEnd.Col();
+ for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+ const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE );
+ const SvxVerJustifyItem& rVerJustifyItem= (const SvxVerJustifyItem&)pAttr->GetItem( ATTR_VER_JUSTIFY );
+
+ const sal_Char* pChar;
+
+ if ( rMergeAttr.GetColMerge() != 0 )
+ rStrm << OOO_STRING_SVTOOLS_RTF_CLMGF;
+ else
+ {
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG );
+ if ( rMergeFlagAttr.IsHorOverlapped() )
+ rStrm << OOO_STRING_SVTOOLS_RTF_CLMRG;
+ }
+
+ switch( rVerJustifyItem.GetValue() )
+ {
+ case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALT; break;
+ case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALC; break;
+ case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break;
+ case SVX_VER_JUSTIFY_STANDARD: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break; //! Bottom
+ default: pChar = NULL; break;
+ }
+ if ( pChar )
+ rStrm << pChar;
+
+ rStrm << OOO_STRING_SVTOOLS_RTF_CELLX << ByteString::CreateFromInt32( pCellX[nCol+1] ).GetBuffer();
+ if ( (nCol & 0x0F) == 0x0F )
+ rStrm << sNewLine; // Zeilen nicht zu lang werden lassen
+ }
+ rStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN << OOO_STRING_SVTOOLS_RTF_INTBL << sNewLine;
+
+ ULONG nStrmPos = rStrm.Tell();
+ for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ WriteCell( nTab, nRow, nCol );
+ if ( rStrm.Tell() - nStrmPos > 255 )
+ { // Zeilen nicht zu lang werden lassen
+ rStrm << sNewLine;
+ nStrmPos = rStrm.Tell();
+ }
+ }
+ rStrm << OOO_STRING_SVTOOLS_RTF_ROW << sNewLine;
+}
+
+
+void ScRTFExport::WriteCell( SCTAB nTab, SCROW nRow, SCCOL nCol )
+{
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG );
+ if ( rMergeFlagAttr.IsHorOverlapped() )
+ {
+ rStrm << OOO_STRING_SVTOOLS_RTF_CELL;
+ return ;
+ }
+
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ BOOL bValueData;
+ String aContent;
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_NOTE :
+ bValueData = FALSE;
+ break; // nix
+ case CELLTYPE_EDIT :
+ {
+ bValueData = FALSE;
+ EditEngine& rEngine = GetEditEngine();
+ const EditTextObject* pObj;
+ ((const ScEditCell*)pCell)->GetData( pObj );
+ if ( pObj )
+ {
+ rEngine.SetText( *pObj );
+ aContent = rEngine.GetText( LINEEND_LF ); // LineFeed zwischen Absaetzen!
+ }
+ }
+ break;
+ default:
+ {
+ bValueData = pCell->HasValueData();
+ ULONG nFormat = pAttr->GetNumberFormat( pFormatter );
+ Color* pColor;
+ ScCellFormat::GetString( pCell, nFormat, aContent, &pColor, *pFormatter );
+ }
+ }
+ }
+ else
+ bValueData = FALSE;
+
+ BOOL bResetPar, bResetAttr;
+ bResetPar = bResetAttr = FALSE;
+
+ const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)pAttr->GetItem( ATTR_HOR_JUSTIFY );
+ const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem( ATTR_FONT_WEIGHT );
+ const SvxPostureItem& rPostureItem = (const SvxPostureItem&) pAttr->GetItem( ATTR_FONT_POSTURE );
+ const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&) pAttr->GetItem( ATTR_FONT_UNDERLINE );
+
+ const sal_Char* pChar;
+
+ switch( rHorJustifyItem.GetValue() )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ pChar = (bValueData ? OOO_STRING_SVTOOLS_RTF_QR : OOO_STRING_SVTOOLS_RTF_QL);
+ break;
+ case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_RTF_QC; break;
+ case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_RTF_QJ; break;
+ case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_RTF_QR; break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default: pChar = OOO_STRING_SVTOOLS_RTF_QL; break;
+ }
+ rStrm << pChar;
+
+ if ( rWeightItem.GetWeight() >= WEIGHT_BOLD )
+ { // bold
+ bResetAttr = TRUE;
+ rStrm << OOO_STRING_SVTOOLS_RTF_B;
+ }
+ if ( rPostureItem.GetPosture() != ITALIC_NONE )
+ { // italic
+ bResetAttr = TRUE;
+ rStrm << OOO_STRING_SVTOOLS_RTF_I;
+ }
+ if ( rUnderlineItem.GetLineStyle() != UNDERLINE_NONE )
+ { // underline
+ bResetAttr = TRUE;
+ rStrm << OOO_STRING_SVTOOLS_RTF_UL;
+ }
+
+ rStrm << ' ';
+ RTFOutFuncs::Out_String( rStrm, aContent );
+ rStrm << OOO_STRING_SVTOOLS_RTF_CELL;
+
+ if ( bResetPar )
+ rStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_INTBL;
+ if ( bResetAttr )
+ rStrm << OOO_STRING_SVTOOLS_RTF_PLAIN;
+}
+
+
diff --git a/sc/source/filter/rtf/rtfimp.cxx b/sc/source/filter/rtf/rtfimp.cxx
new file mode 100644
index 000000000000..83b48b1fa2b1
--- /dev/null
+++ b/sc/source/filter/rtf/rtfimp.cxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#ifndef PCH
+#include "global.hxx"
+#include "document.hxx"
+#include "filter.hxx"
+#endif
+#include "editutil.hxx"
+#include "rtfimp.hxx"
+#include "rtfparse.hxx"
+#include "ftools.hxx"
+
+
+FltError ScFormatFilterPluginImpl::ScImportRTF( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc, ScRange& rRange )
+{
+ ScRTFImport aImp( pDoc, rRange );
+ FltError nErr = (FltError) aImp.Read( rStream, rBaseURL );
+ ScRange aR = aImp.GetRange();
+ rRange.aEnd = aR.aEnd;
+ aImp.WriteToDocument();
+ return nErr;
+}
+
+ScEEAbsImport *ScFormatFilterPluginImpl::CreateRTFImport( ScDocument* pDoc, const ScRange& rRange )
+{
+ return new ScRTFImport( pDoc, rRange );
+}
+
+
+ScRTFImport::ScRTFImport( ScDocument* pDocP, const ScRange& rRange ) :
+ ScEEImport( pDocP, rRange )
+{
+ mpParser = new ScRTFParser( mpEngine );
+}
+
+
+ScRTFImport::~ScRTFImport()
+{
+ // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
+ // Ist gewaehrleistet, da ScEEImport Basisklasse ist
+ delete (ScRTFParser*) mpParser; // vor EditEngine!
+}
+
+
+
diff --git a/sc/source/filter/rtf/rtfparse.cxx b/sc/source/filter/rtf/rtfparse.cxx
new file mode 100644
index 000000000000..b3373bbf4596
--- /dev/null
+++ b/sc/source/filter/rtf/rtfparse.cxx
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/editeng.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/svxrtf.hxx>
+#include <vcl/outdev.hxx>
+#include <svtools/rtftoken.h>
+
+#define SC_RTFPARSE_CXX
+#include "rtfparse.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+
+#define SC_RTFTWIPTOL 10 // 10 Twips Toleranz bei Spaltenbestimmung
+
+
+
+SV_IMPL_VARARR_SORT( ScRTFColTwips, ULONG );
+
+
+
+ScRTFParser::ScRTFParser( EditEngine* pEditP ) :
+ ScEEParser( pEditP ),
+ pDefaultList( new ScRTFDefaultList ),
+ pColTwips( new ScRTFColTwips ),
+ pActDefault( NULL ),
+ pDefMerge( NULL ),
+ nStartAdjust( (ULONG)~0 ),
+ nLastWidth(0),
+ bNewDef( FALSE )
+{
+ // RTF default FontSize 12Pt
+ long nMM = OutputDevice::LogicToLogic( 12, MAP_POINT, MAP_100TH_MM );
+ pPool->SetPoolDefaultItem( SvxFontHeightItem( nMM, 100, EE_CHAR_FONTHEIGHT ) );
+ // freifliegender pInsDefault
+ pInsDefault = new ScRTFCellDefault( pPool );
+}
+
+
+ScRTFParser::~ScRTFParser()
+{
+ delete pInsDefault;
+ delete pColTwips;
+ for ( ScRTFCellDefault* pD = pDefaultList->First(); pD; pD = pDefaultList->Next() )
+ delete pD;
+ delete pDefaultList;
+}
+
+
+ULONG ScRTFParser::Read( SvStream& rStream, const String& rBaseURL )
+{
+ Link aOldLink = pEdit->GetImportHdl();
+ pEdit->SetImportHdl( LINK( this, ScRTFParser, RTFImportHdl ) );
+ ULONG nErr = pEdit->Read( rStream, rBaseURL, EE_FORMAT_RTF );
+ if ( nLastToken == RTF_PAR )
+ {
+ ScEEParseEntry* pE = pList->Last();
+ if ( pE
+ // komplett leer
+ && (( pE->aSel.nStartPara == pE->aSel.nEndPara
+ && pE->aSel.nStartPos == pE->aSel.nEndPos)
+ // leerer Paragraph
+ || ( pE->aSel.nStartPara + 1 == pE->aSel.nEndPara
+ && pE->aSel.nStartPos == pEdit->GetTextLen( pE->aSel.nStartPara )
+ && pE->aSel.nEndPos == 0 )) )
+ { // den letzten leeren Absatz nicht uebernehmen
+ pList->Remove();
+ delete pE;
+ }
+ }
+ ColAdjust();
+ pEdit->SetImportHdl( aOldLink );
+ return nErr;
+}
+
+
+void ScRTFParser::EntryEnd( ScEEParseEntry* pE, const ESelection& aSel )
+{
+ // Paragraph -2 stript den angehaengten leeren Paragraph
+ pE->aSel.nEndPara = aSel.nEndPara - 2;
+ // obwohl das nEndPos heisst, ist das letzte Position + 1
+ pE->aSel.nEndPos = pEdit->GetTextLen( aSel.nEndPara - 1 );
+}
+
+
+inline void ScRTFParser::NextRow()
+{
+ if ( nRowMax < ++nRowCnt )
+ nRowMax = nRowCnt;
+}
+
+
+BOOL ScRTFParser::SeekTwips( USHORT nTwips, SCCOL* pCol )
+{
+ USHORT nPos;
+ BOOL bFound = pColTwips->Seek_Entry( nTwips, &nPos );
+ *pCol = static_cast<SCCOL>(nPos);
+ if ( bFound )
+ return TRUE;
+ USHORT nCount = pColTwips->Count();
+ if ( !nCount )
+ return FALSE;
+ SCCOL nCol = *pCol;
+ // nCol ist Einfuegeposition, da liegt der Naechsthoehere (oder auch nicht)
+ if ( nCol < static_cast<SCCOL>(nCount) && (((*pColTwips)[nCol] - SC_RTFTWIPTOL) <= nTwips) )
+ return TRUE;
+ // nicht kleiner als alles andere? dann mit Naechstniedrigerem vergleichen
+ else if ( nCol != 0 && (((*pColTwips)[nCol-1] + SC_RTFTWIPTOL) >= nTwips) )
+ {
+ (*pCol)--;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void ScRTFParser::ColAdjust()
+{
+ if ( nStartAdjust != (ULONG)~0 )
+ {
+ SCCOL nCol = 0;
+ ScEEParseEntry* pE;
+ pE = pList->Seek( nStartAdjust );
+ while ( pE )
+ {
+ if ( pE->nCol == 0 )
+ nCol = 0;
+ pE->nCol = nCol;
+ if ( pE->nColOverlap > 1 )
+ nCol = nCol + pE->nColOverlap; // merged cells mit \clmrg
+ else
+ {
+ SeekTwips( pE->nTwips, &nCol );
+ if ( ++nCol <= pE->nCol )
+ nCol = pE->nCol + 1; // verschobene Zell-X
+ pE->nColOverlap = nCol - pE->nCol; // merged cells ohne \clmrg
+ }
+ if ( nCol > nColMax )
+ nColMax = nCol;
+ pE = pList->Next();
+ }
+ nStartAdjust = (ULONG)~0;
+ pColTwips->Remove( (USHORT)0, pColTwips->Count() );
+ }
+}
+
+
+IMPL_LINK( ScRTFParser, RTFImportHdl, ImportInfo*, pInfo )
+{
+ switch ( pInfo->eState )
+ {
+ case RTFIMP_NEXTTOKEN:
+ ProcToken( pInfo );
+ break;
+ case RTFIMP_UNKNOWNATTR:
+ ProcToken( pInfo );
+ break;
+ case RTFIMP_START:
+ {
+ SvxRTFParser* pParser = (SvxRTFParser*) pInfo->pParser;
+ pParser->SetAttrPool( pPool );
+ RTFPardAttrMapIds& rMap = pParser->GetPardMap();
+ rMap.nBrush = ATTR_BACKGROUND;
+ rMap.nBox = ATTR_BORDER;
+ rMap.nShadow = ATTR_SHADOW;
+ }
+ break;
+ case RTFIMP_END:
+ if ( pInfo->aSelection.nEndPos )
+ { // falls noch Text: letzten Absatz erzeugen
+ pActDefault = NULL;
+ pInfo->nToken = RTF_PAR;
+ // EditEngine hat keinen leeren Paragraph mehr angehaengt
+ // den EntryEnd strippen koennte
+ pInfo->aSelection.nEndPara++;
+ ProcToken( pInfo );
+ }
+ break;
+ case RTFIMP_SETATTR:
+ break;
+ case RTFIMP_INSERTTEXT:
+ break;
+ case RTFIMP_INSERTPARA:
+ break;
+ default:
+ DBG_ERRORFILE("unknown ImportInfo.eState");
+ }
+ return 0;
+}
+
+
+// bei RTF_INTBL bzw. am Anfang von erstem RTF_CELL nach RTF_CELLX wenn es
+// kein RTF_INTBL gab, bad behavior
+void ScRTFParser::NewCellRow( ImportInfo* /*pInfo*/ )
+{
+ if ( bNewDef )
+ {
+ ScRTFCellDefault* pD;
+ bNewDef = FALSE;
+ // rechts nicht buendig? => neue Tabelle
+ if ( nLastWidth
+ && ((pD = pDefaultList->Last()) != 0) && pD->nTwips != nLastWidth )
+ {
+ SCCOL n1, n2;
+ if ( !( SeekTwips( nLastWidth, &n1 )
+ && SeekTwips( pD->nTwips, &n2 ) && n1 == n2) )
+ ColAdjust();
+ }
+ // TwipCols aufbauen, erst nach nLastWidth Vergleich!
+ for ( pD = pDefaultList->First(); pD; pD = pDefaultList->Next() )
+ {
+ SCCOL n;
+ if ( !SeekTwips( pD->nTwips, &n ) )
+ pColTwips->Insert( pD->nTwips );
+ }
+ }
+ pDefMerge = NULL;
+ pActDefault = pDefaultList->First();
+ DBG_ASSERT( pActDefault, "NewCellRow: pActDefault==0" );
+}
+
+
+/*
+ SW:
+ ~~~
+ [\par]
+ \trowd \cellx \cellx ...
+ \intbl \cell \cell ...
+ \row
+ [\par]
+ [\trowd \cellx \cellx ...]
+ \intbl \cell \cell ...
+ \row
+ [\par]
+
+ M$-Word:
+ ~~~~~~~~
+ [\par]
+ \trowd \cellx \cellx ...
+ \intbl \cell \cell ...
+ \intbl \row
+ [\par]
+ [\trowd \cellx \cellx ...]
+ \intbl \cell \cell ...
+ \intbl \row
+ [\par]
+
+ */
+
+void ScRTFParser::ProcToken( ImportInfo* pInfo )
+{
+ ScRTFCellDefault* pD;
+ ScEEParseEntry* pE;
+ switch ( pInfo->nToken )
+ {
+ case RTF_TROWD: // denotes table row defauls, before RTF_CELLX
+ {
+ if ( (pD = pDefaultList->Last()) != 0 )
+ nLastWidth = pD->nTwips;
+ nColCnt = 0;
+ for ( pD = pDefaultList->First(); pD; pD = pDefaultList->Next() )
+ delete pD;
+ pDefaultList->Clear();
+ pDefMerge = NULL;
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CLMGF: // The first cell of cells to be merged
+ {
+ pDefMerge = pInsDefault;
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CLMRG: // A cell to be merged with the preceding cell
+ {
+ if ( !pDefMerge )
+ pDefMerge = pDefaultList->Last();
+ DBG_ASSERT( pDefMerge, "RTF_CLMRG: pDefMerge==0" );
+ if ( pDefMerge ) // sonst rottes RTF
+ pDefMerge->nColOverlap++; // mehrere nacheinander moeglich
+ pInsDefault->nColOverlap = 0; // Flag: ignoriere diese
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CELLX: // closes cell default
+ {
+ bNewDef = TRUE;
+ pInsDefault->nCol = nColCnt;
+ pInsDefault->nTwips = pInfo->nTokenValue; // rechter Zellenrand
+ pDefaultList->Insert( pInsDefault, LIST_APPEND );
+ // neuer freifliegender pInsDefault
+ pInsDefault = new ScRTFCellDefault( pPool );
+ if ( ++nColCnt > nColMax )
+ nColMax = nColCnt;
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_INTBL: // before the first RTF_CELL
+ {
+ // einmal ueber NextToken und einmal ueber UnknownAttrToken
+ // oder z.B. \intbl ... \cell \pard \intbl ... \cell
+ if ( nLastToken != RTF_INTBL && nLastToken != RTF_CELL && nLastToken != RTF_PAR )
+ {
+ NewCellRow( pInfo );
+ nLastToken = pInfo->nToken;
+ }
+ }
+ break;
+ case RTF_CELL: // denotes the end of a cell.
+ {
+ DBG_ASSERT( pActDefault, "RTF_CELL: pActDefault==0" );
+ if ( bNewDef || !pActDefault )
+ NewCellRow( pInfo ); // davor war kein \intbl, bad behavior
+ // rottes RTF? retten was zu retten ist
+ if ( !pActDefault )
+ pActDefault = pInsDefault;
+ if ( pActDefault->nColOverlap > 0 )
+ { // nicht merged mit vorheriger
+ pActEntry->nCol = pActDefault->nCol;
+ pActEntry->nColOverlap = pActDefault->nColOverlap;
+ pActEntry->nTwips = pActDefault->nTwips;
+ pActEntry->nRow = nRowCnt;
+ pActEntry->aItemSet.Set( pActDefault->aItemSet );
+ EntryEnd( pActEntry, pInfo->aSelection );
+
+ if ( nStartAdjust == (ULONG)~0 )
+ nStartAdjust = pList->Count();
+ pList->Insert( pActEntry, LIST_APPEND );
+ NewActEntry( pActEntry ); // neuer freifliegender pActEntry
+ }
+ else
+ { // aktuelle Twips der MergeCell zuweisen
+ if ( (pE = pList->Last()) != 0 )
+ pE->nTwips = pActDefault->nTwips;
+ // Selection des freifliegenden pActEntry anpassen
+ // Paragraph -1 wg. Textaufbruch in EditEngine waehrend Parse
+ pActEntry->aSel.nStartPara = pInfo->aSelection.nEndPara - 1;
+ }
+ pActDefault = pDefaultList->Next();
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_ROW: // means the end of a row
+ {
+ NextRow();
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_PAR: // Paragraph
+ {
+ if ( !pActDefault )
+ { // text not in table
+ ColAdjust(); // close the processing table
+ pActEntry->nCol = 0;
+ pActEntry->nRow = nRowCnt;
+ EntryEnd( pActEntry, pInfo->aSelection );
+ pList->Insert( pActEntry, LIST_APPEND );
+ NewActEntry( pActEntry ); // new pActEntry
+ NextRow();
+ }
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ default:
+ { // do not set nLastToken
+ switch ( pInfo->nToken & ~(0xff | RTF_TABLEDEF) )
+ {
+ case RTF_SHADINGDEF:
+ ((SvxRTFParser*)pInfo->pParser)->ReadBackgroundAttr(
+ pInfo->nToken, pInsDefault->aItemSet, TRUE );
+ break;
+ case RTF_BRDRDEF:
+ ((SvxRTFParser*)pInfo->pParser)->ReadBorderAttr(
+ pInfo->nToken, pInsDefault->aItemSet, TRUE );
+ break;
+ }
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/filter/starcalc/makefile.mk b/sc/source/filter/starcalc/makefile.mk
new file mode 100644
index 000000000000..836f6b0d3621
--- /dev/null
+++ b/sc/source/filter/starcalc/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=scflt
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+AUTOSEG=true
+
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/scflt.obj \
+ $(SLO)$/scfobj.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx
new file mode 100644
index 000000000000..c9bf2a90a7a5
--- /dev/null
+++ b/sc/source/filter/starcalc/scflt.cxx
@@ -0,0 +1,2511 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "global.hxx"
+#include "sc.hrc"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "document.hxx"
+#include "collect.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "filter.hxx"
+#include "scflt.hxx"
+#include "cell.hxx"
+#include "scfobj.hxx"
+#include "docoptio.hxx"
+#include "viewopti.hxx"
+#include "postit.hxx"
+#include "globstr.hrc"
+#include "ftools.hxx"
+#include "tabprotection.hxx"
+
+#include "fprogressbar.hxx"
+
+using namespace com::sun::star;
+
+#define DEFCHARSET RTL_TEXTENCODING_MS_1252
+
+#define SC10TOSTRING(p) String(p,DEFCHARSET)
+
+const SCCOL SC10MAXCOL = 255; // #i85906# don't try to load more columns than there are in the file
+
+
+void lcl_ReadFileHeader(SvStream& rStream, Sc10FileHeader& rFileHeader)
+{
+ rStream.Read(&rFileHeader.CopyRight, sizeof(rFileHeader.CopyRight));
+ rStream >> rFileHeader.Version;
+ rStream.Read(&rFileHeader.Reserved, sizeof(rFileHeader.Reserved));
+}
+
+
+void lcl_ReadTabProtect(SvStream& rStream, Sc10TableProtect& rProtect)
+{
+ rStream.Read(&rProtect.PassWord, sizeof(rProtect.PassWord));
+ rStream >> rProtect.Flags;
+ rStream >> rProtect.Protect;
+}
+
+
+void lcl_ReadSheetProtect(SvStream& rStream, Sc10SheetProtect& rProtect)
+{
+ rStream.Read(&rProtect.PassWord, sizeof(rProtect.PassWord));
+ rStream >> rProtect.Flags;
+ rStream >> rProtect.Protect;
+}
+
+
+void lcl_ReadRGB(SvStream& rStream, Sc10Color& rColor)
+{
+ rStream >> rColor.Dummy;
+ rStream >> rColor.Blue;
+ rStream >> rColor.Green;
+ rStream >> rColor.Red;
+}
+
+
+void lcl_ReadPalette(SvStream& rStream, Sc10Color* pPalette)
+{
+ for (USHORT i = 0; i < 16; i++)
+ lcl_ReadRGB(rStream, pPalette[i]);
+}
+
+
+void lcl_ReadValueFormat(SvStream& rStream, Sc10ValueFormat& rFormat)
+{
+ rStream >> rFormat.Format;
+ rStream >> rFormat.Info;
+}
+
+
+void lcl_ReadLogFont(SvStream& rStream, Sc10LogFont& rFont)
+{
+ rStream >> rFont.lfHeight;
+ rStream >> rFont.lfWidth;
+ rStream >> rFont.lfEscapement;
+ rStream >> rFont.lfOrientation;
+ rStream >> rFont.lfWeight;
+ rStream >> rFont.lfItalic;
+ rStream >> rFont.lfUnderline;
+ rStream >> rFont.lfStrikeOut;
+ rStream >> rFont.lfCharSet;
+ rStream >> rFont.lfOutPrecision;
+ rStream >> rFont.lfClipPrecision;
+ rStream >> rFont.lfQuality;
+ rStream >> rFont.lfPitchAndFamily;
+ rStream.Read(&rFont.lfFaceName, sizeof(rFont.lfFaceName));
+}
+
+
+void lcl_ReadBlockRect(SvStream& rStream, Sc10BlockRect& rBlock)
+{
+ rStream >> rBlock.x1;
+ rStream >> rBlock.y1;
+ rStream >> rBlock.x2;
+ rStream >> rBlock.y2;
+}
+
+
+void lcl_ReadHeadFootLine(SvStream& rStream, Sc10HeadFootLine& rLine)
+{
+ rStream.Read(&rLine.Title, sizeof(rLine.Title));
+ lcl_ReadLogFont(rStream, rLine.LogFont);
+ rStream >> rLine.HorJustify;
+ rStream >> rLine.VerJustify;
+ rStream >> rLine.Raster;
+ rStream >> rLine.Frame;
+ lcl_ReadRGB(rStream, rLine.TextColor);
+ lcl_ReadRGB(rStream, rLine.BackColor);
+ lcl_ReadRGB(rStream, rLine.RasterColor);
+ rStream >> rLine.FrameColor;
+ rStream >> rLine.Reserved;
+}
+
+
+void lcl_ReadPageFormat(SvStream& rStream, Sc10PageFormat& rFormat)
+{
+ lcl_ReadHeadFootLine(rStream, rFormat.HeadLine);
+ lcl_ReadHeadFootLine(rStream, rFormat.FootLine);
+ rStream >> rFormat.Orientation;
+ rStream >> rFormat.Width;
+ rStream >> rFormat.Height;
+ rStream >> rFormat.NonPrintableX;
+ rStream >> rFormat.NonPrintableY;
+ rStream >> rFormat.Left;
+ rStream >> rFormat.Top;
+ rStream >> rFormat.Right;
+ rStream >> rFormat.Bottom;
+ rStream >> rFormat.Head;
+ rStream >> rFormat.Foot;
+ rStream >> rFormat.HorCenter;
+ rStream >> rFormat.VerCenter;
+ rStream >> rFormat.PrintGrid;
+ rStream >> rFormat.PrintColRow;
+ rStream >> rFormat.PrintNote;
+ rStream >> rFormat.TopBottomDir;
+ rStream.Read(&rFormat.PrintAreaName, sizeof(rFormat.PrintAreaName));
+ lcl_ReadBlockRect(rStream, rFormat.PrintArea);
+ rStream.Read(&rFormat.PrnZoom, sizeof(rFormat.PrnZoom));
+ rStream >> rFormat.FirstPageNo;
+ rStream >> rFormat.RowRepeatStart;
+ rStream >> rFormat.RowRepeatEnd;
+ rStream >> rFormat.ColRepeatStart;
+ rStream >> rFormat.ColRepeatEnd;
+ rStream.Read(&rFormat.Reserved, sizeof(rFormat.Reserved));
+}
+
+
+void lcl_ReadGraphHeader(SvStream& rStream, Sc10GraphHeader& rHeader)
+{
+ rStream >> rHeader.Typ;
+ rStream >> rHeader.CarretX;
+ rStream >> rHeader.CarretY;
+ rStream >> rHeader.CarretZ;
+ rStream >> rHeader.x;
+ rStream >> rHeader.y;
+ rStream >> rHeader.w;
+ rStream >> rHeader.h;
+ rStream >> rHeader.IsRelPos;
+ rStream >> rHeader.DoPrint;
+ rStream >> rHeader.FrameType;
+ rStream >> rHeader.IsTransparent;
+ lcl_ReadRGB(rStream, rHeader.FrameColor);
+ lcl_ReadRGB(rStream, rHeader.BackColor);
+ rStream.Read(&rHeader.Reserved, sizeof(rHeader.Reserved));
+}
+
+
+void lcl_ReadImageHeaer(SvStream& rStream, Sc10ImageHeader& rHeader)
+{
+ rStream.Read(&rHeader.FileName, sizeof(rHeader.FileName));
+ rStream >> rHeader.Typ;
+ rStream >> rHeader.Linked;
+ rStream >> rHeader.x1;
+ rStream >> rHeader.y1;
+ rStream >> rHeader.x2;
+ rStream >> rHeader.y2;
+ rStream >> rHeader.Size;
+}
+
+
+void lcl_ReadChartHeader(SvStream& rStream, Sc10ChartHeader& rHeader)
+{
+ rStream >> rHeader.MM;
+ rStream >> rHeader.xExt;
+ rStream >> rHeader.yExt;
+ rStream >> rHeader.Size;
+}
+
+
+void lcl_ReadChartSheetData(SvStream& rStream, Sc10ChartSheetData& rSheetData)
+{
+ rStream >> rSheetData.HasTitle;
+ rStream >> rSheetData.TitleX;
+ rStream >> rSheetData.TitleY;
+ rStream >> rSheetData.HasSubTitle;
+ rStream >> rSheetData.SubTitleX;
+ rStream >> rSheetData.SubTitleY;
+ rStream >> rSheetData.HasLeftTitle;
+ rStream >> rSheetData.LeftTitleX;
+ rStream >> rSheetData.LeftTitleY;
+ rStream >> rSheetData.HasLegend;
+ rStream >> rSheetData.LegendX1;
+ rStream >> rSheetData.LegendY1;
+ rStream >> rSheetData.LegendX2;
+ rStream >> rSheetData.LegendY2;
+ rStream >> rSheetData.HasLabel;
+ rStream >> rSheetData.LabelX1;
+ rStream >> rSheetData.LabelY1;
+ rStream >> rSheetData.LabelX2;
+ rStream >> rSheetData.LabelY2;
+ rStream >> rSheetData.DataX1;
+ rStream >> rSheetData.DataY1;
+ rStream >> rSheetData.DataX2;
+ rStream >> rSheetData.DataY2;
+ rStream.Read(&rSheetData.Reserved, sizeof(rSheetData.Reserved));
+}
+
+
+void lcl_ReadChartTypeData(SvStream& rStream, Sc10ChartTypeData& rTypeData)
+{
+ rStream >> rTypeData.NumSets;
+ rStream >> rTypeData.NumPoints;
+ rStream >> rTypeData.DrawMode;
+ rStream >> rTypeData.GraphType;
+ rStream >> rTypeData.GraphStyle;
+ rStream.Read(&rTypeData.GraphTitle, sizeof(rTypeData.GraphTitle));
+ rStream.Read(&rTypeData.BottomTitle, sizeof(rTypeData.BottomTitle));
+ USHORT i;
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.SymbolData[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.ColorData[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.ThickLines[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.PatternData[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.LinePatternData[i];
+ for (i = 0; i < 11; i++)
+ rStream >> rTypeData.NumGraphStyles[i];
+ rStream >> rTypeData.ShowLegend;
+ for (i = 0; i < 256; i++)
+ rStream.Read(&rTypeData.LegendText[i], sizeof(Sc10ChartText));
+ rStream >> rTypeData.ExplodePie;
+ rStream >> rTypeData.FontUse;
+ for (i = 0; i < 5; i++)
+ rStream >> rTypeData.FontFamily[i];
+ for (i = 0; i < 5; i++)
+ rStream >> rTypeData.FontStyle[i];
+ for (i = 0; i < 5; i++)
+ rStream >> rTypeData.FontSize[i];
+ rStream >> rTypeData.GridStyle;
+ rStream >> rTypeData.Labels;
+ rStream >> rTypeData.LabelEvery;
+ for (i = 0; i < 50; i++)
+ rStream.Read(&rTypeData.LabelText[i], sizeof(Sc10ChartText));
+ rStream.Read(&rTypeData.LeftTitle, sizeof(rTypeData.LeftTitle));
+ rStream.Read(&rTypeData.Reserved, sizeof(rTypeData.Reserved));
+ //rStream.Read(&rTypeData, sizeof(rTypeData));
+}
+
+double lcl_PascalToDouble(sal_Char* tp6)
+{
+// #i68483# bah! this was broken forever...
+// struct
+// {
+// sal_uInt8 be ; /* biased exponent */
+// sal_uInt16 v1 ; /* lower 16 bits of mantissa */
+// sal_uInt16 v2 ; /* next 16 bits of mantissa */
+// sal_uInt8 v3:7; /* upper 7 bits of mantissa */
+// sal_uInt8 s :1; /* sign bit */
+// } real;
+//
+// memcpy (&real, tp6, 6);
+// if (real.be == 0)
+// return 0.0;
+// return (((((128 +real.v3) * 65536.0) + real.v2) * 65536.0 + real.v1) *
+// ldexp ((real.s? -1.0: 1.0), real.be - (129+39)));
+
+ sal_uInt8* pnUnsigned = reinterpret_cast< sal_uInt8* >( tp6 );
+ // biased exponent
+ sal_uInt8 be = pnUnsigned[ 0 ];
+ // lower 16 bits of mantissa
+ sal_uInt16 v1 = static_cast< sal_uInt16 >( pnUnsigned[ 2 ] * 256 + pnUnsigned[ 1 ] );
+ // next 16 bits of mantissa
+ sal_uInt16 v2 = static_cast< sal_uInt16 >( pnUnsigned[ 4 ] * 256 + pnUnsigned[ 3 ] );
+ // upper 7 bits of mantissa
+ sal_uInt8 v3 = static_cast< sal_uInt8 >( pnUnsigned[ 5 ] & 0x7F );
+ // sign bit
+ bool s = (pnUnsigned[ 5 ] & 0x80) != 0;
+
+ if (be == 0)
+ return 0.0;
+ return (((((128 + v3) * 65536.0) + v2) * 65536.0 + v1) *
+ ldexp ((s ? -1.0 : 1.0), be - (129+39)));
+}
+
+
+void lcl_ChangeColor( USHORT nIndex, Color& rColor )
+{
+ ColorData aCol;
+
+ switch( nIndex )
+ {
+ case 1: aCol = COL_RED; break;
+ case 2: aCol = COL_GREEN; break;
+ case 3: aCol = COL_BROWN; break;
+ case 4: aCol = COL_BLUE; break;
+ case 5: aCol = COL_MAGENTA; break;
+ case 6: aCol = COL_CYAN; break;
+ case 7: aCol = COL_GRAY; break;
+ case 8: aCol = COL_LIGHTGRAY; break;
+ case 9: aCol = COL_LIGHTRED; break;
+ case 10: aCol = COL_LIGHTGREEN; break;
+ case 11: aCol = COL_YELLOW; break;
+ case 12: aCol = COL_LIGHTBLUE; break;
+ case 13: aCol = COL_LIGHTMAGENTA; break;
+ case 14: aCol = COL_LIGHTCYAN; break;
+ case 15: aCol = COL_WHITE; break;
+ default: aCol = COL_BLACK;
+ }
+
+ rColor.SetColor( aCol );
+}
+
+String lcl_MakeOldPageStyleFormatName( USHORT i )
+{
+ String aName = ScGlobal::GetRscString( STR_PAGESTYLE );
+ aName.AppendAscii( " " );
+ aName += String::CreateFromInt32( i + 1 );
+
+ return aName;
+}
+
+//--------------------------------------------
+// Font
+//--------------------------------------------
+
+
+Sc10FontData::Sc10FontData(SvStream& rStream)
+{
+ rStream >> Height;
+ rStream >> CharSet;
+ rStream >> PitchAndFamily;
+ USHORT nLen;
+ rStream >> nLen;
+ rStream.Read(FaceName, nLen);
+}
+
+
+Sc10FontCollection::Sc10FontCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ USHORT ID;
+ rStream >> ID;
+ if (ID == FontID)
+ {
+ USHORT nAnz;
+ rStream >> nAnz;
+ for (USHORT i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10FontData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ DBG_ERROR( "FontID" );
+ nError = errUnknownID;
+ }
+}
+
+
+//--------------------------------------------
+// Benannte-Bereiche
+//--------------------------------------------
+
+
+Sc10NameData::Sc10NameData(SvStream& rStream)
+{
+ BYTE nLen;
+ rStream >> nLen;
+ rStream.Read(Name, sizeof(Name) - 1);
+ Name[nLen] = 0;
+
+ rStream >> nLen;
+ rStream.Read(Reference, sizeof(Reference) - 1);
+ Reference[nLen] = 0;
+ rStream.Read(Reserved, sizeof(Reserved));
+}
+
+
+Sc10NameCollection::Sc10NameCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ USHORT ID;
+ rStream >> ID;
+ if (ID == NameID)
+ {
+ USHORT nAnz;
+ rStream >> nAnz;
+ for (USHORT i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10NameData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ DBG_ERROR( "NameID" );
+ nError = errUnknownID;
+ }
+}
+
+//--------------------------------------------
+// Vorlagen
+//--------------------------------------------
+
+
+Sc10PatternData::Sc10PatternData(SvStream& rStream)
+{
+ rStream.Read(Name, sizeof(Name));
+ //rStream.Read(&ValueFormat, sizeof(ValueFormat));
+ //rStream.Read(&LogFont, sizeof(LogFont));
+ lcl_ReadValueFormat(rStream, ValueFormat);
+ lcl_ReadLogFont(rStream, LogFont);
+
+ rStream >> Attr;
+ rStream >> Justify;
+ rStream >> Frame;
+ rStream >> Raster;
+ rStream >> nColor;
+ rStream >> FrameColor;
+ rStream >> Flags;
+ rStream >> FormatFlags;
+ rStream.Read(Reserved, sizeof(Reserved));
+}
+
+
+Sc10PatternCollection::Sc10PatternCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ USHORT ID;
+ rStream >> ID;
+ if (ID == PatternID)
+ {
+ USHORT nAnz;
+ rStream >> nAnz;
+ for (USHORT i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10PatternData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ DBG_ERROR( "PatternID" );
+ nError = errUnknownID;
+ }
+}
+
+
+//--------------------------------------------
+// Datenbank
+//--------------------------------------------
+
+
+Sc10DataBaseData::Sc10DataBaseData(SvStream& rStream)
+{
+ //rStream.Read(&DataBaseRec, sizeof(DataBaseRec));
+ rStream.Read(&DataBaseRec.Name, sizeof(DataBaseRec.Name));
+ rStream >> DataBaseRec.Tab;
+ lcl_ReadBlockRect(rStream, DataBaseRec.Block);
+ rStream >> DataBaseRec.RowHeader;
+ rStream >> DataBaseRec.SortField0;
+ rStream >> DataBaseRec.SortUpOrder0;
+ rStream >> DataBaseRec.SortField1;
+ rStream >> DataBaseRec.SortUpOrder1;
+ rStream >> DataBaseRec.SortField2;
+ rStream >> DataBaseRec.SortUpOrder2;
+ rStream >> DataBaseRec.IncludeFormat;
+
+ rStream >> DataBaseRec.QueryField0;
+ rStream >> DataBaseRec.QueryOp0;
+ rStream >> DataBaseRec.QueryByString0;
+ rStream.Read(&DataBaseRec.QueryString0, sizeof(DataBaseRec.QueryString0));
+ DataBaseRec.QueryValue0 = ScfTools::ReadLongDouble(rStream);
+
+ rStream >> DataBaseRec.QueryConnect1;
+ rStream >> DataBaseRec.QueryField1;
+ rStream >> DataBaseRec.QueryOp1;
+ rStream >> DataBaseRec.QueryByString1;
+ rStream.Read(&DataBaseRec.QueryString1, sizeof(DataBaseRec.QueryString1));
+ DataBaseRec.QueryValue1 = ScfTools::ReadLongDouble(rStream);
+
+ rStream >> DataBaseRec.QueryConnect2;
+ rStream >> DataBaseRec.QueryField2;
+ rStream >> DataBaseRec.QueryOp2;
+ rStream >> DataBaseRec.QueryByString2;
+ rStream.Read(&DataBaseRec.QueryString2, sizeof(DataBaseRec.QueryString2));
+ DataBaseRec.QueryValue2 = ScfTools::ReadLongDouble(rStream);
+}
+
+
+Sc10DataBaseCollection::Sc10DataBaseCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ USHORT ID;
+ rStream >> ID;
+ if (ID == DataBaseID)
+ {
+ rStream.Read(ActName, sizeof(ActName));
+ USHORT nAnz;
+ rStream >> nAnz;
+ for (USHORT i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10DataBaseData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ DBG_ERROR( "DataBaseID" );
+ nError = errUnknownID;
+ }
+}
+
+
+int Sc10LogFont::operator==( const Sc10LogFont& rData ) const
+{
+ return !strcmp( lfFaceName, rData.lfFaceName )
+ && lfHeight == rData.lfHeight
+ && lfWidth == rData.lfWidth
+ && lfEscapement == rData.lfEscapement
+ && lfOrientation == rData.lfOrientation
+ && lfWeight == rData.lfWeight
+ && lfItalic == rData.lfItalic
+ && lfUnderline == rData.lfUnderline
+ && lfStrikeOut == rData.lfStrikeOut
+ && lfCharSet == rData.lfCharSet
+ && lfOutPrecision == rData.lfOutPrecision
+ && lfClipPrecision == rData.lfClipPrecision
+ && lfQuality == rData.lfQuality
+ && lfPitchAndFamily == rData.lfPitchAndFamily;
+}
+
+
+int Sc10Color::operator==( const Sc10Color& rColor ) const
+{
+ return ((Red == rColor.Red) && (Green == rColor.Green) && (Blue == rColor.Blue));
+}
+
+
+int Sc10HeadFootLine::operator==( const Sc10HeadFootLine& rData ) const
+{
+ return !strcmp(Title, rData.Title)
+ && LogFont == rData.LogFont
+ && HorJustify == rData.HorJustify
+ && VerJustify == rData.VerJustify
+ && Raster == rData.Raster
+ && Frame == rData.Frame
+ && TextColor == rData.TextColor
+ && BackColor == rData.BackColor
+ && RasterColor == rData.RasterColor
+ && FrameColor == rData.FrameColor
+ && Reserved == rData.Reserved;
+}
+
+
+int Sc10PageFormat::operator==( const Sc10PageFormat& rData ) const
+{
+ return !strcmp(PrintAreaName, rData.PrintAreaName)
+ && HeadLine == rData.HeadLine
+ && FootLine == rData.FootLine
+ && Orientation == rData.Orientation
+ && Width == rData.Width
+ && Height == rData.Height
+ && NonPrintableX == rData.NonPrintableX
+ && NonPrintableY == rData.NonPrintableY
+ && Left == rData.Left
+ && Top == rData.Top
+ && Right == rData.Right
+ && Bottom == rData.Bottom
+ && Head == rData.Head
+ && Foot == rData.Foot
+ && HorCenter == rData.HorCenter
+ && VerCenter == rData.VerCenter
+ && PrintGrid == rData.PrintGrid
+ && PrintColRow == rData.PrintColRow
+ && PrintNote == rData.PrintNote
+ && TopBottomDir == rData.TopBottomDir
+ && FirstPageNo == rData.FirstPageNo
+ && RowRepeatStart == rData.RowRepeatStart
+ && RowRepeatEnd == rData.RowRepeatEnd
+ && ColRepeatStart == rData.ColRepeatStart
+ && ColRepeatEnd == rData.ColRepeatEnd
+ && !memcmp( PrnZoom, rData.PrnZoom, sizeof(PrnZoom) )
+ && !memcmp( &PrintArea, &rData.PrintArea, sizeof(PrintArea) );
+}
+
+
+USHORT Sc10PageCollection::InsertFormat( const Sc10PageFormat& rData )
+{
+ for (USHORT i=0; i<nCount; i++)
+ if (At(i)->aPageFormat == rData)
+ return i;
+
+ Insert( new Sc10PageData(rData) );
+
+ return nCount-1;
+}
+
+
+static inline UINT8 GetMixedCol( const UINT8 nB, const UINT8 nF, const UINT16 nFak )
+{
+ INT32 nT = nB - nF;
+ nT *= ( INT32 ) nFak;
+ nT /= 0xFFFF;
+ nT += nF;
+ return ( UINT8 ) nT;
+}
+static inline Color GetMixedColor( const Color& rFore, const Color& rBack, UINT16 nFact )
+{
+ return Color( GetMixedCol( rBack.GetRed(), rFore.GetRed(), nFact ),
+ GetMixedCol( rBack.GetGreen(), rFore.GetGreen(), nFact ),
+ GetMixedCol( rBack.GetBlue(), rFore.GetBlue(), nFact ) );
+}
+
+
+void Sc10PageCollection::PutToDoc( ScDocument* pDoc )
+{
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ EditEngine aEditEngine( pDoc->GetEnginePool() );
+ EditTextObject* pEmptyObject = aEditEngine.CreateTextObject();
+
+ for (USHORT i=0; i<nCount; i++)
+ {
+ Sc10PageFormat* pPage = &At(i)->aPageFormat;
+
+ pPage->Width = (short) ( pPage->Width * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Height = (short) ( pPage->Height * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Top = (short) ( pPage->Top * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Bottom = (short) ( pPage->Bottom * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Left = (short) ( pPage->Left * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Right = (short) ( pPage->Right * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Head = (short) ( pPage->Head * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Foot = (short) ( pPage->Foot * ( 72.0 / 72.27 ) + 0.5 );
+
+ String aName = lcl_MakeOldPageStyleFormatName( i );
+
+ ScStyleSheet* pSheet = (ScStyleSheet*) &pStylePool->Make( aName,
+ SFX_STYLE_FAMILY_PAGE,
+ SFXSTYLEBIT_USERDEF | SCSTYLEBIT_STANDARD );
+ // #i68483# set page style name at sheet...
+ pDoc->SetPageStyle( static_cast< SCTAB >( i ), aName );
+
+ SfxItemSet* pSet = &pSheet->GetItemSet();
+
+ for (USHORT nHeadFoot=0; nHeadFoot<2; nHeadFoot++)
+ {
+ Sc10HeadFootLine* pHeadFootLine = nHeadFoot ? &pPage->FootLine : &pPage->HeadLine;
+
+ SfxItemSet aEditAttribs(aEditEngine.GetEmptyItemSet());
+ FontFamily eFam = FAMILY_DONTKNOW;
+ switch (pPage->HeadLine.LogFont.lfPitchAndFamily & 0xF0)
+ {
+ case ffDontCare: eFam = FAMILY_DONTKNOW; break;
+ case ffRoman: eFam = FAMILY_ROMAN; break;
+ case ffSwiss: eFam = FAMILY_SWISS; break;
+ case ffModern: eFam = FAMILY_MODERN; break;
+ case ffScript: eFam = FAMILY_SCRIPT; break;
+ case ffDecorative: eFam = FAMILY_DECORATIVE; break;
+ default: eFam = FAMILY_DONTKNOW; break;
+ }
+ aEditAttribs.Put( SvxFontItem(
+ eFam,
+ SC10TOSTRING( pHeadFootLine->LogFont.lfFaceName ), EMPTY_STRING,
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ),
+ EE_CHAR_FONTINFO );
+ aEditAttribs.Put( SvxFontHeightItem( Abs( pHeadFootLine->LogFont.lfHeight ), 100, EE_CHAR_FONTHEIGHT ),
+ EE_CHAR_FONTHEIGHT);
+
+ Sc10Color nColor = pHeadFootLine->TextColor;
+ Color TextColor( nColor.Red, nColor.Green, nColor.Blue );
+ aEditAttribs.Put(SvxColorItem(TextColor, EE_CHAR_COLOR), EE_CHAR_COLOR);
+ // FontAttr
+ if (pHeadFootLine->LogFont.lfWeight != fwNormal)
+ aEditAttribs.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT), EE_CHAR_WEIGHT);
+ if (pHeadFootLine->LogFont.lfItalic != 0)
+ aEditAttribs.Put(SvxPostureItem(ITALIC_NORMAL, EE_CHAR_ITALIC), EE_CHAR_ITALIC);
+ if (pHeadFootLine->LogFont.lfUnderline != 0)
+ aEditAttribs.Put(SvxUnderlineItem(UNDERLINE_SINGLE, EE_CHAR_UNDERLINE), EE_CHAR_UNDERLINE);
+ if (pHeadFootLine->LogFont.lfStrikeOut != 0)
+ aEditAttribs.Put(SvxCrossedOutItem(STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT), EE_CHAR_STRIKEOUT);
+ String aText( pHeadFootLine->Title, DEFCHARSET );
+ aEditEngine.SetText( aText );
+ aEditEngine.QuickSetAttribs( aEditAttribs, ESelection( 0, 0, 0, aText.Len() ) );
+
+ EditTextObject* pObject = aEditEngine.CreateTextObject();
+ ScPageHFItem aHeaderItem(nHeadFoot ? ATTR_PAGE_FOOTERRIGHT : ATTR_PAGE_HEADERRIGHT);
+ switch (pHeadFootLine->HorJustify)
+ {
+ case hjCenter:
+ aHeaderItem.SetLeftArea(*pEmptyObject);
+ aHeaderItem.SetCenterArea(*pObject);
+ aHeaderItem.SetRightArea(*pEmptyObject);
+ break;
+ case hjRight:
+ aHeaderItem.SetLeftArea(*pEmptyObject);
+ aHeaderItem.SetCenterArea(*pEmptyObject);
+ aHeaderItem.SetRightArea(*pObject);
+ break;
+ default:
+ aHeaderItem.SetLeftArea(*pObject);
+ aHeaderItem.SetCenterArea(*pEmptyObject);
+ aHeaderItem.SetRightArea(*pEmptyObject);
+ break;
+ }
+ delete pObject;
+ pSet->Put( aHeaderItem );
+
+ SfxItemSet aSetItemItemSet( *pDoc->GetPool(),
+ ATTR_BACKGROUND, ATTR_BACKGROUND,
+ ATTR_BORDER, ATTR_SHADOW,
+ ATTR_PAGE_SIZE, ATTR_PAGE_SIZE,
+ ATTR_LRSPACE, ATTR_ULSPACE,
+ ATTR_PAGE_ON, ATTR_PAGE_SHARED,
+ 0 );
+ nColor = pHeadFootLine->BackColor;
+ Color aBColor( nColor.Red, nColor.Green, nColor.Blue );
+ nColor = pHeadFootLine->RasterColor;
+ Color aRColor( nColor.Red, nColor.Green, nColor.Blue );
+
+ UINT16 nFact;
+ BOOL bSwapCol = FALSE;
+ switch (pHeadFootLine->Raster)
+ {
+ case raNone: nFact = 0xffff; bSwapCol = TRUE; break;
+ case raGray12: nFact = (0xffff / 100) * 12; break;
+ case raGray25: nFact = (0xffff / 100) * 25; break;
+ case raGray50: nFact = (0xffff / 100) * 50; break;
+ case raGray75: nFact = (0xffff / 100) * 75; break;
+ default: nFact = 0xffff;
+ }
+ if( bSwapCol )
+ aSetItemItemSet.Put( SvxBrushItem( GetMixedColor( aBColor, aRColor, nFact ), ATTR_BACKGROUND ) );
+ else
+ aSetItemItemSet.Put( SvxBrushItem( GetMixedColor( aRColor, aBColor, nFact ), ATTR_BACKGROUND ) );
+
+ if (pHeadFootLine->Frame != 0)
+ {
+ USHORT nLeft = 0;
+ USHORT nTop = 0;
+ USHORT nRight = 0;
+ USHORT nBottom = 0;
+ USHORT fLeft = (pHeadFootLine->Frame & 0x000F);
+ USHORT fTop = (pHeadFootLine->Frame & 0x00F0) / 0x0010;
+ USHORT fRight = (pHeadFootLine->Frame & 0x0F00) / 0x0100;
+ USHORT fBottom = (pHeadFootLine->Frame & 0xF000) / 0x1000;
+ if (fLeft > 1)
+ nLeft = 50;
+ else if (fLeft > 0)
+ nLeft = 20;
+ if (fTop > 1)
+ nTop = 50;
+ else if (fTop > 0)
+ nTop = 20;
+ if (fRight > 1)
+ nRight = 50;
+ else if (fRight > 0)
+ nRight = 20;
+ if (fBottom > 1)
+ nBottom = 50;
+ else if (fBottom > 0)
+ nBottom = 20;
+ Color ColorLeft(COL_BLACK);
+ Color ColorTop(COL_BLACK);
+ Color ColorRight(COL_BLACK);
+ Color ColorBottom(COL_BLACK);
+ USHORT cLeft = (pHeadFootLine->FrameColor & 0x000F);
+ USHORT cTop = (pHeadFootLine->FrameColor & 0x00F0) >> 4;
+ USHORT cRight = (pHeadFootLine->FrameColor & 0x0F00) >> 8;
+ USHORT cBottom = (pHeadFootLine->FrameColor & 0xF000) >> 12;
+ lcl_ChangeColor(cLeft, ColorLeft);
+ lcl_ChangeColor(cTop, ColorTop);
+ lcl_ChangeColor(cRight, ColorRight);
+ lcl_ChangeColor(cBottom, ColorBottom);
+ SvxBorderLine aLine;
+ SvxBoxItem aBox( ATTR_BORDER );
+ aLine.SetOutWidth(nLeft);
+ aLine.SetColor(ColorLeft);
+ aBox.SetLine(&aLine, BOX_LINE_LEFT);
+ aLine.SetOutWidth(nTop);
+ aLine.SetColor(ColorTop);
+ aBox.SetLine(&aLine, BOX_LINE_TOP);
+ aLine.SetOutWidth(nRight);
+ aLine.SetColor(ColorRight);
+ aBox.SetLine(&aLine, BOX_LINE_RIGHT);
+ aLine.SetOutWidth(nBottom);
+ aLine.SetColor(ColorBottom);
+ aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
+
+ aSetItemItemSet.Put(aBox);
+ }
+
+ pSet->Put( SvxULSpaceItem( 0, 0, ATTR_ULSPACE ) );
+
+ if (nHeadFoot==0)
+ aSetItemItemSet.Put( SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, pPage->Top - pPage->Head ) ) );
+ else
+ aSetItemItemSet.Put( SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, pPage->Bottom - pPage->Foot ) ) );
+
+ aSetItemItemSet.Put(SfxBoolItem( ATTR_PAGE_ON, TRUE ));
+ aSetItemItemSet.Put(SfxBoolItem( ATTR_PAGE_DYNAMIC, FALSE ));
+ aSetItemItemSet.Put(SfxBoolItem( ATTR_PAGE_SHARED, TRUE ));
+
+ pSet->Put( SvxSetItem( nHeadFoot ? ATTR_PAGE_FOOTERSET : ATTR_PAGE_HEADERSET,
+ aSetItemItemSet ) );
+ }
+
+ SvxPageItem aPageItem(ATTR_PAGE);
+ aPageItem.SetPageUsage( SVX_PAGE_ALL );
+ aPageItem.SetLandscape( pPage->Orientation != 1 );
+ aPageItem.SetNumType( SVX_ARABIC );
+ pSet->Put(aPageItem);
+
+ pSet->Put(SvxLRSpaceItem( pPage->Left, pPage->Right, 0,0, ATTR_LRSPACE ));
+ pSet->Put(SvxULSpaceItem( pPage->Top, pPage->Bottom, ATTR_ULSPACE ));
+
+ pSet->Put(SfxBoolItem( ATTR_PAGE_HORCENTER, pPage->HorCenter ));
+ pSet->Put(SfxBoolItem( ATTR_PAGE_VERCENTER, pPage->VerCenter ));
+
+ //----------------
+ // Area-Parameter:
+ //----------------
+ {
+ ScRange* pRepeatRow = NULL;
+ ScRange* pRepeatCol = NULL;
+
+ if ( pPage->ColRepeatStart >= 0 )
+ pRepeatCol = new ScRange( static_cast<SCCOL> (pPage->ColRepeatStart), 0, 0 );
+ if ( pPage->RowRepeatStart >= 0 )
+ pRepeatRow = new ScRange( 0, static_cast<SCROW> (pPage->RowRepeatStart), 0 );
+
+
+ if ( pRepeatRow || pRepeatCol )
+ {
+ //
+ // an allen Tabellen setzen
+ //
+ for ( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ pDoc->SetRepeatColRange( nTab, pRepeatCol );
+ pDoc->SetRepeatRowRange( nTab, pRepeatRow );
+ }
+ }
+
+ delete pRepeatRow;
+ delete pRepeatCol;
+ }
+
+ //-----------------
+ // Table-Parameter:
+ //-----------------
+ pSet->Put( SfxBoolItem( ATTR_PAGE_NOTES, pPage->PrintNote ) );
+ pSet->Put( SfxBoolItem( ATTR_PAGE_GRID, pPage->PrintGrid ) );
+ pSet->Put( SfxBoolItem( ATTR_PAGE_HEADERS, pPage->PrintColRow ) );
+ pSet->Put( SfxBoolItem( ATTR_PAGE_TOPDOWN, pPage->TopBottomDir ) );
+ pSet->Put( ScViewObjectModeItem( ATTR_PAGE_CHARTS, VOBJ_MODE_SHOW ) );
+ pSet->Put( ScViewObjectModeItem( ATTR_PAGE_OBJECTS, VOBJ_MODE_SHOW ) );
+ pSet->Put( ScViewObjectModeItem( ATTR_PAGE_DRAWINGS, VOBJ_MODE_SHOW ) );
+ pSet->Put( SfxUInt16Item( ATTR_PAGE_SCALE,
+ (UINT16)( lcl_PascalToDouble( pPage->PrnZoom ) * 100 ) ) );
+ pSet->Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 1 ) );
+
+ pSet->Put( SvxSizeItem( ATTR_PAGE_SIZE, Size( pPage->Width, pPage->Height ) ) );
+ }
+
+ delete pEmptyObject;
+}
+
+
+ScDataObject* Sc10PageData::Clone() const
+{
+ return new Sc10PageData(aPageFormat);
+}
+
+
+//--------------------------------------------
+// Import
+//--------------------------------------------
+
+
+Sc10Import::Sc10Import(SvStream& rStr, ScDocument* pDocument ) :
+ rStream (rStr),
+ pDoc (pDocument),
+ pFontCollection (NULL),
+ pNameCollection (NULL),
+ pPatternCollection (NULL),
+ pDataBaseCollection (NULL),
+ nError (0),
+ nShowTab (0)
+{
+ pPrgrsBar = NULL;
+}
+
+
+Sc10Import::~Sc10Import()
+{
+ pDoc->CalcAfterLoad();
+ pDoc->UpdateAllCharts();
+
+ delete pFontCollection;
+ delete pNameCollection;
+ delete pPatternCollection;
+ delete pDataBaseCollection;
+
+ DBG_ASSERT( pPrgrsBar == NULL,
+ "*Sc10Import::Sc10Import(): Progressbar lebt noch!?" );
+}
+
+
+ULONG Sc10Import::Import()
+{
+ pPrgrsBar = new ScfStreamProgressBar( rStream, pDoc->GetDocumentShell() );
+
+ ScDocOptions aOpt = pDoc->GetDocOptions();
+ aOpt.SetDate( 1, 1, 1900 );
+ aOpt.SetYear2000( 18 + 1901 ); // ab SO51 src513e vierstellig
+ pDoc->SetDocOptions( aOpt );
+ pDoc->GetFormatTable()->ChangeNullDate( 1, 1, 1900 );
+
+ LoadFileHeader(); pPrgrsBar->Progress();
+ if (!nError) { LoadFileInfo(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadEditStateInfo(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadProtect(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadViewColRowBar(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadScrZoom(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadPalette(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadFontCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadNameCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadPatternCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadDataBaseCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadTables(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadObjects(); pPrgrsBar->Progress(); }
+ if (!nError) { ImportNameCollection(); pPrgrsBar->Progress(); }
+ pDoc->SetViewOptions( aSc30ViewOpt );
+
+#ifdef DBG_UTIL
+ if (nError)
+ {
+ DBG_ERROR( ByteString::CreateFromInt32( nError ).GetBuffer() );
+ }
+#endif
+
+ delete pPrgrsBar;
+#ifdef DBG_UTIL
+ pPrgrsBar = NULL;
+#endif
+
+ return nError;
+}
+
+
+void Sc10Import::LoadFileHeader()
+{
+ Sc10FileHeader FileHeader;
+ //rStream.Read(&FileHeader, sizeof(FileHeader));
+ lcl_ReadFileHeader(rStream, FileHeader);
+
+ nError = rStream.GetError();
+ if ( nError == 0 )
+ {
+ sal_Char Sc10CopyRight[32];
+ strcpy(Sc10CopyRight, "Blaise-Tabelle"); // #100211# - checked
+ Sc10CopyRight[14] = 10;
+ Sc10CopyRight[15] = 13;
+ Sc10CopyRight[16] = 0;
+ if ((strcmp(FileHeader.CopyRight, Sc10CopyRight) != 0)
+ || (FileHeader.Version < 101)
+ || (FileHeader.Version > 102))
+ nError = errUnknownFormat;
+ }
+}
+
+
+void Sc10Import::LoadFileInfo()
+{
+ Sc10FileInfo FileInfo;
+ rStream.Read(&FileInfo, sizeof(FileInfo));
+
+ nError = rStream.GetError();
+ // Achtung Info Uebertragen
+}
+
+
+
+void Sc10Import::LoadEditStateInfo()
+{
+ Sc10EditStateInfo EditStateInfo;
+ rStream.Read(&EditStateInfo, sizeof(EditStateInfo));
+
+ nError = rStream.GetError();
+ nShowTab = static_cast<SCTAB>(EditStateInfo.DeltaZ);
+ // Achtung Cursorposition und Offset der Tabelle Uebertragen (soll man das machen??)
+}
+
+
+void Sc10Import::LoadProtect()
+{
+ //rStream.Read(&SheetProtect, sizeof(SheetProtect));
+ lcl_ReadSheetProtect(rStream, SheetProtect);
+ nError = rStream.GetError();
+
+ ScDocProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(SheetProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(SheetProtect.PassWord));
+ pDoc->SetDocProtection(&aProtection);
+}
+
+
+void Sc10Import::LoadViewColRowBar()
+{
+ BYTE ViewColRowBar;
+ rStream >> ViewColRowBar;
+ nError = rStream.GetError();
+ aSc30ViewOpt.SetOption( VOPT_HEADER, (BOOL)ViewColRowBar );
+}
+
+
+void Sc10Import::LoadScrZoom()
+{
+ // Achtung Zoom ist leider eine 6Byte TP real Zahl (keine Ahnung wie die Umzusetzen ist)
+ sal_Char cZoom[6];
+ rStream.Read(cZoom, sizeof(cZoom));
+ nError = rStream.GetError();
+}
+
+
+void Sc10Import::LoadPalette()
+{
+ //rStream.Read(TextPalette, sizeof(TextPalette));
+ //rStream.Read(BackPalette, sizeof(BackPalette));
+ //rStream.Read(RasterPalette, sizeof(RasterPalette));
+ //rStream.Read(FramePalette, sizeof(FramePalette));
+ lcl_ReadPalette(rStream, TextPalette);
+ lcl_ReadPalette(rStream, BackPalette);
+ lcl_ReadPalette(rStream, RasterPalette);
+ lcl_ReadPalette(rStream, FramePalette);
+
+ nError = rStream.GetError();
+}
+
+
+void Sc10Import::LoadFontCollection()
+{
+ pFontCollection = new Sc10FontCollection(rStream);
+}
+
+
+void Sc10Import::LoadNameCollection()
+{
+ pNameCollection = new Sc10NameCollection(rStream);
+}
+
+
+void Sc10Import::ImportNameCollection()
+{
+ ScRangeName* pRN = pDoc->GetRangeName();
+
+ for (USHORT i = 0; i < pNameCollection->GetCount(); i++)
+ {
+ Sc10NameData* pName = pNameCollection->At( i );
+ pRN->Insert( new ScRangeData( pDoc,
+ SC10TOSTRING( pName->Name ),
+ SC10TOSTRING( pName->Reference ) ) );
+ }
+}
+
+
+void Sc10Import::LoadPatternCollection()
+{
+ pPatternCollection = new Sc10PatternCollection( rStream );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ for( USHORT i = 0 ; i < pPatternCollection->GetCount() ; i++ )
+ {
+ Sc10PatternData* pPattern = pPatternCollection->At( i );
+ String aName( pPattern->Name, DEFCHARSET );
+ SfxStyleSheetBase* pStyle = pStylePool->Find( aName, SFX_STYLE_FAMILY_PARA );
+ if( pStyle == NULL )
+ pStylePool->Make( aName, SFX_STYLE_FAMILY_PARA );
+ else
+ {
+ pPattern->Name[ 27 ] = 0;
+ strcat( pPattern->Name, "_Old" ); // #100211# - checked
+ aName = SC10TOSTRING( pPattern->Name );
+ pStylePool->Make( aName, SFX_STYLE_FAMILY_PARA );
+ }
+ pStyle = pStylePool->Find( aName, SFX_STYLE_FAMILY_PARA );
+ if( pStyle != NULL )
+ {
+ SfxItemSet &rItemSet = pStyle->GetItemSet();
+ // Font
+ if( ( pPattern->FormatFlags & pfFont ) == pfFont )
+ {
+ FontFamily eFam = FAMILY_DONTKNOW;
+ switch( pPattern->LogFont.lfPitchAndFamily & 0xF0 )
+ {
+ case ffDontCare : eFam = FAMILY_DONTKNOW; break;
+ case ffRoman : eFam = FAMILY_ROMAN; break;
+ case ffSwiss : eFam = FAMILY_SWISS; break;
+ case ffModern : eFam = FAMILY_MODERN; break;
+ case ffScript : eFam = FAMILY_SCRIPT; break;
+ case ffDecorative : eFam = FAMILY_DECORATIVE; break;
+ default: eFam = FAMILY_DONTKNOW; break;
+ }
+ rItemSet.Put( SvxFontItem( eFam, SC10TOSTRING( pPattern->LogFont.lfFaceName ), EMPTY_STRING,
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+ rItemSet.Put( SvxFontHeightItem( Abs( pPattern->LogFont.lfHeight ), 100, ATTR_FONT_HEIGHT ) );
+ Color TextColor( COL_BLACK );
+ lcl_ChangeColor( ( pPattern->nColor & 0x000F ), TextColor );
+ rItemSet.Put( SvxColorItem( TextColor, ATTR_FONT_COLOR ) );
+ // FontAttr
+ if( pPattern->LogFont.lfWeight != fwNormal )
+ rItemSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ if( pPattern->LogFont.lfItalic != 0 )
+ rItemSet.Put( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ if( pPattern->LogFont.lfUnderline != 0 )
+ rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+ if( pPattern->LogFont.lfStrikeOut != 0 )
+ rItemSet.Put( SvxCrossedOutItem( STRIKEOUT_SINGLE, ATTR_FONT_CROSSEDOUT ) );
+ }
+ // Ausrichtung
+ if( ( pPattern->FormatFlags & pfJustify ) == pfJustify )
+ {
+ USHORT HorJustify = ( pPattern->Justify & 0x000F );
+ USHORT VerJustify = ( pPattern->Justify & 0x00F0 ) >> 4;
+ USHORT OJustify = ( pPattern->Justify & 0x0F00 ) >> 8;
+ USHORT EJustify = ( pPattern->Justify & 0xF000 ) >> 12;
+ if( HorJustify != 0 )
+ switch( HorJustify )
+ {
+ case hjLeft:
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
+ break;
+ case hjCenter:
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+ break;
+ case hjRight:
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) );
+ break;
+ }
+ if( VerJustify != 0 )
+ switch( VerJustify )
+ {
+ case vjTop:
+ rItemSet.Put( SvxVerJustifyItem( SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY ) );
+ break;
+ case vjCenter:
+ rItemSet.Put( SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
+ break;
+ case vjBottom:
+ rItemSet.Put( SvxVerJustifyItem( SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY ) );
+ break;
+ }
+
+ if( ( OJustify & ojWordBreak ) == ojWordBreak )
+ rItemSet.Put( SfxBoolItem( TRUE ) );
+ if( ( OJustify & ojBottomTop ) == ojBottomTop )
+ rItemSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
+ else if( ( OJustify & ojTopBottom ) == ojTopBottom )
+ rItemSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
+
+ INT16 Margin = Max( ( USHORT ) 20, ( USHORT ) ( EJustify * 20 ) );
+// if( ( ( OJustify & ojBottomTop ) == ojBottomTop ) ||
+// ( ( OJustify & ojBottomTop ) == ojBottomTop ) )
+// vielleicht so?
+ if( ( ( OJustify & ojBottomTop ) == ojBottomTop ) )
+ rItemSet.Put( SvxMarginItem( 20, Margin, 20, Margin, ATTR_MARGIN ) );
+ else
+ rItemSet.Put( SvxMarginItem( Margin, 20, Margin, 20, ATTR_MARGIN ) );
+ }
+
+ // Frame
+ if( ( pPattern->FormatFlags & pfFrame ) == pfFrame )
+ {
+ if( pPattern->Frame != 0 )
+ {
+ USHORT nLeft = 0;
+ USHORT nTop = 0;
+ USHORT nRight = 0;
+ USHORT nBottom = 0;
+ USHORT fLeft = ( pPattern->Frame & 0x000F );
+ USHORT fTop = ( pPattern->Frame & 0x00F0 ) / 0x0010;
+ USHORT fRight = ( pPattern->Frame & 0x0F00 ) / 0x0100;
+ USHORT fBottom = ( pPattern->Frame & 0xF000 ) / 0x1000;
+
+ if( fLeft > 1 )
+ nLeft = 50;
+ else if( fLeft > 0 )
+ nLeft = 20;
+
+ if( fTop > 1 )
+ nTop = 50;
+ else if( fTop > 0 )
+ nTop = 20;
+
+ if( fRight > 1 )
+ nRight = 50;
+ else if( fRight > 0 )
+ nRight = 20;
+
+ if( fBottom > 1 )
+ nBottom = 50;
+ else if( fBottom > 0 )
+ nBottom = 20;
+
+ Color ColorLeft( COL_BLACK );
+ Color ColorTop( COL_BLACK );
+ Color ColorRight( COL_BLACK );
+ Color ColorBottom( COL_BLACK );
+
+ USHORT cLeft = ( pPattern->FrameColor & 0x000F );
+ USHORT cTop = ( pPattern->FrameColor & 0x00F0 ) >> 4;
+ USHORT cRight = ( pPattern->FrameColor & 0x0F00 ) >> 8;
+ USHORT cBottom = ( pPattern->FrameColor & 0xF000 ) >> 12;
+
+ lcl_ChangeColor( cLeft, ColorLeft );
+ lcl_ChangeColor( cTop, ColorTop );
+ lcl_ChangeColor( cRight, ColorRight );
+ lcl_ChangeColor( cBottom, ColorBottom );
+
+ SvxBorderLine aLine;
+ SvxBoxItem aBox( ATTR_BORDER );
+
+ aLine.SetOutWidth( nLeft );
+ aLine.SetColor( ColorLeft );
+ aBox.SetLine( &aLine, BOX_LINE_LEFT );
+ aLine.SetOutWidth( nTop );
+ aLine.SetColor( ColorTop );
+ aBox.SetLine( &aLine, BOX_LINE_TOP );
+ aLine.SetOutWidth( nRight );
+ aLine.SetColor( ColorRight );
+ aBox.SetLine( &aLine, BOX_LINE_RIGHT );
+ aLine.SetOutWidth( nBottom );
+ aLine.SetColor( ColorBottom );
+ aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+ rItemSet.Put( aBox );
+ }
+ }
+ // Raster
+ if( ( pPattern->FormatFlags & pfRaster ) == pfRaster )
+ {
+ if( pPattern->Raster != 0 )
+ {
+ USHORT nBColor = ( pPattern->nColor & 0x00F0 ) >> 4;
+ USHORT nRColor = ( pPattern->nColor & 0x0F00 ) >> 8;
+ Color aBColor( COL_BLACK );
+
+ lcl_ChangeColor( nBColor, aBColor );
+
+ if( nBColor == 0 )
+ aBColor.SetColor( COL_WHITE );
+ else if( nBColor == 15 )
+ aBColor.SetColor( COL_BLACK );
+
+ Color aRColor( COL_BLACK );
+ lcl_ChangeColor( nRColor, aRColor );
+ UINT16 nFact;
+ BOOL bSwapCol = FALSE;
+ BOOL bSetItem = TRUE;
+ switch (pPattern->Raster)
+ {
+ case raNone: nFact = 0xffff; bSwapCol = TRUE; bSetItem = (nBColor > 0); break;
+ case raGray12: nFact = (0xffff / 100) * 12; break;
+ case raGray25: nFact = (0xffff / 100) * 25; break;
+ case raGray50: nFact = (0xffff / 100) * 50; break;
+ case raGray75: nFact = (0xffff / 100) * 75; break;
+ default: nFact = 0xffff; bSetItem = (nRColor < 15);
+ }
+ if ( bSetItem )
+ {
+ if( bSwapCol )
+ rItemSet.Put( SvxBrushItem( GetMixedColor( aBColor, aRColor, nFact ), ATTR_BACKGROUND ) );
+ else
+ rItemSet.Put( SvxBrushItem( GetMixedColor( aRColor, aBColor, nFact ), ATTR_BACKGROUND ) );
+ }
+ }
+ }
+ // ZahlenFormate
+ if( ( pPattern->ValueFormat.Format != 0 ) &&
+ ( ( pPattern->FormatFlags & pfValue ) == pfValue ) )
+ {
+ ULONG nKey = 0;
+ ChangeFormat( pPattern->ValueFormat.Format, pPattern->ValueFormat.Info, nKey );
+ rItemSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, ( UINT32 ) nKey ) );
+ }
+
+ // Zellattribute (Schutz, Versteckt...)
+ if( ( pPattern->Flags != 0 ) &&
+ ( ( pPattern->FormatFlags & pfProtection ) == pfProtection ) )
+ {
+ BOOL bProtect = ( ( pPattern->Flags & paProtect ) == paProtect );
+ BOOL bHFormula = ( ( pPattern->Flags & paHideFormula ) == paHideFormula );
+ BOOL bHCell = ( ( pPattern->Flags & paHideAll ) == paHideAll );
+ BOOL bHPrint = ( ( pPattern->Flags & paHidePrint ) == paHidePrint );
+ rItemSet.Put( ScProtectionAttr( bProtect, bHFormula, bHCell, bHPrint ) );
+ }
+ } // if Style != 0
+ } // for (i = 0; i < GetCount()
+}
+
+
+void Sc10Import::LoadDataBaseCollection()
+{
+ pDataBaseCollection = new Sc10DataBaseCollection(rStream);
+ for( USHORT i = 0 ; i < pDataBaseCollection->GetCount() ; i++ )
+ {
+ Sc10DataBaseData* pOldData = pDataBaseCollection->At(i);
+ ScDBData* pNewData = new ScDBData( SC10TOSTRING( pOldData->DataBaseRec.Name ),
+ ( SCTAB ) pOldData->DataBaseRec.Tab,
+ ( SCCOL ) pOldData->DataBaseRec.Block.x1,
+ ( SCROW ) pOldData->DataBaseRec.Block.y1,
+ ( SCCOL ) pOldData->DataBaseRec.Block.x2,
+ ( SCROW ) pOldData->DataBaseRec.Block.y2,
+ TRUE,
+ ( BOOL) pOldData->DataBaseRec.RowHeader );
+ pDoc->GetDBCollection()->Insert( pNewData );
+ }
+}
+
+
+void Sc10Import::LoadTables()
+{
+ Sc10PageCollection aPageCollection;
+
+ INT16 nTabCount;
+ rStream >> nTabCount;
+ for (INT16 Tab = 0; (Tab < nTabCount) && (nError == 0); Tab++)
+ {
+ Sc10PageFormat PageFormat;
+ INT16 DataBaseIndex;
+ Sc10TableProtect TabProtect;
+ INT16 TabNo;
+ sal_Char TabName[128];
+ USHORT Display;
+ BYTE Visible;
+ USHORT ID;
+ USHORT DataCount;
+ USHORT DataStart;
+ USHORT DataEnd;
+ USHORT DataValue;
+ USHORT Count;
+ USHORT i;
+ String aStr; // Universal-Konvertierungs-String
+
+
+ //rStream.Read(&PageFormat, sizeof(PageFormat));
+ lcl_ReadPageFormat(rStream, PageFormat);
+
+ USHORT nAt = aPageCollection.InsertFormat(PageFormat);
+ String aPageName = lcl_MakeOldPageStyleFormatName( nAt );
+
+ pPrgrsBar->Progress();
+
+ rStream >> DataBaseIndex;
+
+ //rStream.Read(&TabProtect, sizeof(TabProtect));
+ lcl_ReadTabProtect(rStream, TabProtect);
+
+ ScTableProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(TabProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(TabProtect.PassWord));
+ pDoc->SetTabProtection(static_cast<SCTAB>(Tab), &aProtection);
+
+ rStream >> TabNo;
+
+ BYTE nLen;
+ rStream >> nLen;
+ rStream.Read(TabName, sizeof(TabName) - 1);
+ TabName[nLen] = 0;
+
+ //----------------------------------------------------------
+ rStream >> Display;
+
+ if ( Tab == (INT16)nShowTab )
+ {
+ ScVObjMode eObjMode = VOBJ_MODE_SHOW;
+
+ aSc30ViewOpt.SetOption( VOPT_FORMULAS, IS_SET(dfFormula,Display) );
+ aSc30ViewOpt.SetOption( VOPT_NULLVALS, IS_SET(dfZerro,Display) );
+ aSc30ViewOpt.SetOption( VOPT_SYNTAX, IS_SET(dfSyntax,Display) );
+ aSc30ViewOpt.SetOption( VOPT_NOTES, IS_SET(dfNoteMark,Display) );
+ aSc30ViewOpt.SetOption( VOPT_VSCROLL, TRUE );
+ aSc30ViewOpt.SetOption( VOPT_HSCROLL, TRUE );
+ aSc30ViewOpt.SetOption( VOPT_TABCONTROLS, TRUE );
+ aSc30ViewOpt.SetOption( VOPT_OUTLINER, TRUE );
+ aSc30ViewOpt.SetOption( VOPT_GRID, IS_SET(dfGrid,Display) );
+
+ // VOPT_HEADER wird in LoadViewColRowBar() gesetzt
+
+ if ( IS_SET(dfObjectAll,Display) ) // Objekte anzeigen
+ eObjMode = VOBJ_MODE_SHOW;
+ else if ( IS_SET(dfObjectFrame,Display) ) // Objekte als Platzhalter
+ eObjMode = VOBJ_MODE_SHOW;
+ else if ( IS_SET(dfObjectNone,Display) ) // Objekte nicht anzeigen
+ eObjMode = VOBJ_MODE_HIDE;
+
+ aSc30ViewOpt.SetObjMode( VOBJ_TYPE_OLE, eObjMode );
+ aSc30ViewOpt.SetObjMode( VOBJ_TYPE_CHART, eObjMode );
+ aSc30ViewOpt.SetObjMode( VOBJ_TYPE_DRAW, eObjMode );
+ }
+
+ /* wofuer wird das benoetigt? Da in SC 1.0 die Anzeigeflags pro Tabelle gelten und nicht pro View
+ Dieses Flag in die ViewOptions eintragen bei Gelegenheit, Sollte der Stephan Olk machen
+ USHORT nDisplayMask = 0xFFFF;
+ USHORT nDisplayValue = 0;
+ if (Tab == 0)
+ nDisplayValue = Display;
+ else
+ {
+ USHORT nDiff = Display ^ nDisplayValue;
+ nDisplayMask &= ~nDiff;
+ }
+ */
+ //--------------------------------------------------------------------
+ rStream >> Visible;
+
+ nError = rStream.GetError();
+ if (nError != 0) return;
+
+ if (TabNo == 0)
+ pDoc->RenameTab(static_cast<SCTAB> (TabNo), SC10TOSTRING( TabName ), FALSE);
+ else
+ pDoc->InsertTab(SC_TAB_APPEND, SC10TOSTRING( TabName ) );
+
+ pDoc->SetPageStyle( static_cast<SCTAB>(Tab), aPageName );
+
+ if (Visible == 0) pDoc->SetVisible(static_cast<SCTAB> (TabNo), FALSE);
+
+ // ColWidth
+ rStream >> ID;
+ if (ID != ColWidthID)
+ {
+ DBG_ERROR( "ColWidthID" );
+ nError = errUnknownID;
+ return;
+ }
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ for (SCCOL j = static_cast<SCCOL>(DataStart); j <= static_cast<SCCOL>(DataEnd); j++) pDoc->SetColWidth(j, static_cast<SCTAB> (TabNo), DataValue);
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // ColAttr
+ rStream >> ID;
+ if (ID != ColAttrID)
+ {
+ DBG_ERROR( "ColAttrID" );
+ nError = errUnknownID;
+ return;
+ }
+
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ if (DataValue != 0)
+ {
+ bool bPageBreak = ((DataValue & crfSoftBreak) == crfSoftBreak);
+ bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak);
+ bool bHidden = ((DataValue & crfHidden) == crfHidden);
+ for (SCCOL k = static_cast<SCCOL>(DataStart); k <= static_cast<SCCOL>(DataEnd); k++)
+ {
+ pDoc->SetColHidden(k, k, static_cast<SCTAB>(TabNo), bHidden);
+ pDoc->SetColBreak(k, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
+ }
+ }
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // RowHeight
+ rStream >> ID;
+ if (ID != RowHeightID)
+ {
+ DBG_ERROR( "RowHeightID" );
+ nError = errUnknownID;
+ return;
+ }
+
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ pDoc->SetRowHeightRange(static_cast<SCROW> (DataStart), static_cast<SCROW> (DataEnd), static_cast<SCTAB> (TabNo), DataValue);
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // RowAttr
+ rStream >> ID;
+ if (ID != RowAttrID)
+ {
+ DBG_ERROR( "RowAttrID" );
+ nError = errUnknownID;
+ return;
+ }
+
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ if (DataValue != 0)
+ {
+ bool bPageBreak = ((DataValue & crfSoftBreak) == crfSoftBreak);
+ bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak);
+ bool bHidden = ((DataValue & crfHidden) == crfHidden);
+ for (SCROW l = static_cast<SCROW>(DataStart); l <= static_cast<SCROW>(DataEnd); l++)
+ {
+ pDoc->SetRowHidden(l, l, static_cast<SCTAB> (TabNo), bHidden);
+ pDoc->SetRowBreak(l, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
+ }
+ }
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // DataTable
+ rStream >> ID;
+ if (ID != TableID)
+ {
+ DBG_ERROR( "TableID" );
+ nError = errUnknownID;
+ return;
+ }
+ for (SCCOL Col = 0; (Col <= SC10MAXCOL) && (nError == 0); Col++)
+ {
+ rStream >> Count;
+ nError = rStream.GetError();
+ if ((Count != 0) && (nError == 0))
+ LoadCol(Col, static_cast<SCTAB> (TabNo));
+ }
+ DBG_ASSERT( nError == 0, "Stream" );
+ }
+ pPrgrsBar->Progress();
+
+ aPageCollection.PutToDoc( pDoc );
+}
+
+
+void Sc10Import::LoadCol(SCCOL Col, SCTAB Tab)
+{
+ LoadColAttr(Col, Tab);
+
+ USHORT CellCount;
+ BYTE CellType;
+ USHORT Row;
+ rStream >> CellCount;
+ SCROW nScCount = static_cast< SCROW >( CellCount );
+ if (nScCount > MAXROW) nError = errUnknownFormat;
+ for (USHORT i = 0; (i < CellCount) && (nError == 0); i++)
+ {
+ rStream >> CellType;
+ rStream >> Row;
+ nError = rStream.GetError();
+ if (nError == 0)
+ {
+ switch (CellType)
+ {
+ case ctValue :
+ {
+ const SfxPoolItem* pValueFormat = pDoc->GetAttr(Col, static_cast<SCROW> (Row), Tab, ATTR_VALUE_FORMAT);
+ ULONG nFormat = ((SfxUInt32Item*)pValueFormat)->GetValue();
+ double Value = ScfTools::ReadLongDouble(rStream);
+ //rStream.Read(&Value, sizeof(Value));
+
+ // Achtung hier ist eine Anpassung Notwendig wenn Ihr das Basisdatum aendert
+ // In StarCalc 1.0 entspricht 0 dem 01.01.1900
+ // if ((nFormat >= 30) && (nFormat <= 35))
+ // Value += 0;
+ if ((nFormat >= 40) && (nFormat <= 45))
+ Value /= 86400.0;
+ pDoc->SetValue(Col, static_cast<SCROW> (Row), Tab, Value);
+ break;
+ }
+ case ctString :
+ {
+ BYTE Len;
+ sal_Char s[256];
+ rStream >> Len;
+ rStream.Read(s, Len);
+ s[Len] = 0;
+
+ pDoc->SetString( Col, static_cast<SCROW> (Row), Tab, SC10TOSTRING( s ) );
+ break;
+ }
+ case ctFormula :
+ {
+ /*double Value =*/ ScfTools::ReadLongDouble(rStream);
+ BYTE Len;
+ sal_Char s[256];
+ //rStream.Read(&Value, sizeof(Value));
+ rStream >> Len;
+ rStream.Read(&s[1], Len);
+ s[0] = '=';
+ s[Len + 1] = 0;
+ ScFormulaCell* pCell = new ScFormulaCell( pDoc, ScAddress( Col, static_cast<SCROW> (Row), Tab ) );
+ pCell->SetHybridFormula( SC10TOSTRING( s ),formula::FormulaGrammar::GRAM_NATIVE );
+ pDoc->PutCell( Col, static_cast<SCROW> (Row), Tab, pCell, (BOOL)TRUE );
+ break;
+ }
+ case ctNote :
+ break;
+ default :
+ nError = errUnknownFormat;
+ break;
+ }
+ USHORT NoteLen;
+ rStream >> NoteLen;
+ if (NoteLen != 0)
+ {
+ sal_Char* pNote = new sal_Char[NoteLen+1];
+ rStream.Read(pNote, NoteLen);
+ pNote[NoteLen] = 0;
+ String aNoteText( SC10TOSTRING(pNote));
+ delete [] pNote;
+ ScAddress aPos( Col, static_cast<SCROW>(Row), Tab );
+ ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
+ }
+ }
+ pPrgrsBar->Progress();
+ }
+}
+
+
+void Sc10Import::LoadColAttr(SCCOL Col, SCTAB Tab)
+{
+ Sc10ColAttr aFont;
+ Sc10ColAttr aAttr;
+ Sc10ColAttr aJustify;
+ Sc10ColAttr aFrame;
+ Sc10ColAttr aRaster;
+ Sc10ColAttr aValue;
+ Sc10ColAttr aColor;
+ Sc10ColAttr aFrameColor;
+ Sc10ColAttr aFlag;
+ Sc10ColAttr aPattern;
+
+ if (nError == 0) LoadAttr(aFont);
+ if (nError == 0) LoadAttr(aAttr);
+ if (nError == 0) LoadAttr(aJustify);
+ if (nError == 0) LoadAttr(aFrame);
+ if (nError == 0) LoadAttr(aRaster);
+ if (nError == 0) LoadAttr(aValue);
+ if (nError == 0) LoadAttr(aColor);
+ if (nError == 0) LoadAttr(aFrameColor);
+ if (nError == 0) LoadAttr(aFlag);
+ if (nError == 0) LoadAttr(aPattern);
+
+ if (nError == 0)
+ {
+ SCROW nStart;
+ SCROW nEnd;
+ USHORT i;
+ UINT16 nLimit;
+ UINT16 nValue1;
+ Sc10ColData *pColData;
+
+ // Font (Name, Groesse)
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aFont.Count;
+ pColData = aFont.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ //nEnd = aFont.pData[i].Row;
+ nEnd = static_cast<SCROW>(pColData->Row);
+ //if ((nStart <= nEnd) && (aFont.pData[i].Value != 0))
+ if ((nStart <= nEnd) && (pColData->Value))
+ {
+ FontFamily eFam = FAMILY_DONTKNOW;
+ //Sc10FontData* pFont = pFontCollection->At(aFont.pData[i].Value);
+ Sc10FontData* pFont = pFontCollection->At(pColData->Value);
+ switch (pFont->PitchAndFamily & 0xF0)
+ {
+ case ffDontCare : eFam = FAMILY_DONTKNOW; break;
+ case ffRoman : eFam = FAMILY_ROMAN; break;
+ case ffSwiss : eFam = FAMILY_SWISS; break;
+ case ffModern : eFam = FAMILY_MODERN; break;
+ case ffScript : eFam = FAMILY_SCRIPT; break;
+ case ffDecorative : eFam = FAMILY_DECORATIVE; break;
+ default: eFam = FAMILY_DONTKNOW; break;
+ }
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(SvxFontItem(eFam, SC10TOSTRING( pFont->FaceName ), EMPTY_STRING,
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ));
+ aScPattern.GetItemSet().Put(SvxFontHeightItem(Abs(pFont->Height), 100, ATTR_FONT_HEIGHT ));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Fontfarbe
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aColor.Count;
+ pColData = aColor.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ //nEnd = aColor.pData[i].Row;
+ nEnd = static_cast<SCROW>(pColData->Row);
+ //if ((nStart <= nEnd) && (aColor.pData[i].Value != 0))
+ if ((nStart <= nEnd) && (pColData->Value))
+ {
+ Color TextColor(COL_BLACK);
+ lcl_ChangeColor((pColData->Value & 0x000F), TextColor);
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(SvxColorItem(TextColor, ATTR_FONT_COLOR ));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Fontattribute (Fett, Kursiv...)
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aAttr.Count;
+ pColData = aAttr.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ nValue1 = pColData->Value;
+ if ((nStart <= nEnd) && (nValue1))
+ {
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ if ((nValue1 & atBold) == atBold)
+ aScPattern.GetItemSet().Put(SvxWeightItem(WEIGHT_BOLD, ATTR_FONT_WEIGHT));
+ if ((nValue1 & atItalic) == atItalic)
+ aScPattern.GetItemSet().Put(SvxPostureItem(ITALIC_NORMAL, ATTR_FONT_POSTURE));
+ if ((nValue1 & atUnderline) == atUnderline)
+ aScPattern.GetItemSet().Put(SvxUnderlineItem(UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE));
+ if ((nValue1 & atStrikeOut) == atStrikeOut)
+ aScPattern.GetItemSet().Put(SvxCrossedOutItem(STRIKEOUT_SINGLE, ATTR_FONT_CROSSEDOUT));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Zellausrichtung
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aJustify.Count;
+ pColData = aJustify.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ nValue1 = pColData->Value;
+ if ((nStart <= nEnd) && (nValue1))
+ {
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ USHORT HorJustify = (nValue1 & 0x000F);
+ USHORT VerJustify = (nValue1 & 0x00F0) >> 4;
+ USHORT OJustify = (nValue1 & 0x0F00) >> 8;
+ USHORT EJustify = (nValue1 & 0xF000) >> 12;
+
+ switch (HorJustify)
+ {
+ case hjLeft:
+ aScPattern.GetItemSet().Put(SvxHorJustifyItem(SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY));
+ break;
+ case hjCenter:
+ aScPattern.GetItemSet().Put(SvxHorJustifyItem(SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY));
+ break;
+ case hjRight:
+ aScPattern.GetItemSet().Put(SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY));
+ break;
+ }
+
+ switch (VerJustify)
+ {
+ case vjTop:
+ aScPattern.GetItemSet().Put(SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY));
+ break;
+ case vjCenter:
+ aScPattern.GetItemSet().Put(SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY));
+ break;
+ case vjBottom:
+ aScPattern.GetItemSet().Put(SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY));
+ break;
+ }
+
+ if (OJustify & ojWordBreak)
+ aScPattern.GetItemSet().Put(SfxBoolItem(TRUE));
+ if (OJustify & ojBottomTop)
+ aScPattern.GetItemSet().Put(SfxInt32Item(ATTR_ROTATE_VALUE,9000));
+ else if (OJustify & ojTopBottom)
+ aScPattern.GetItemSet().Put(SfxInt32Item(ATTR_ROTATE_VALUE,27000));
+
+ INT16 Margin = Max((USHORT)20, (USHORT)(EJustify * 20));
+ if (((OJustify & ojBottomTop) == ojBottomTop) || ((OJustify & ojBottomTop) == ojBottomTop))
+ aScPattern.GetItemSet().Put(SvxMarginItem(20, Margin, 20, Margin, ATTR_MARGIN));
+ else
+ aScPattern.GetItemSet().Put(SvxMarginItem(Margin, 20, Margin, 20, ATTR_MARGIN));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+ // Umrandung
+ BOOL bEnd = FALSE;
+ USHORT nColorIndex = 0;
+ USHORT nFrameIndex = 0;
+
+ // Special Fix...
+ const UINT32 nHelpMeStart = 100;
+ UINT32 nHelpMe = nHelpMeStart;
+ USHORT nColorIndexOld = nColorIndex;
+ USHORT nFrameIndexOld = nColorIndex;
+
+ nEnd = 0;
+ nStart = 0;
+ while( !bEnd && nHelpMe )
+ {
+ pColData = &aFrame.pData[ nFrameIndex ];
+
+ USHORT nValue = pColData->Value;
+ USHORT nLeft = 0;
+ USHORT nTop = 0;
+ USHORT nRight = 0;
+ USHORT nBottom = 0;
+ USHORT fLeft = ( nValue & 0x000F );
+ USHORT fTop = ( nValue & 0x00F0 ) >> 4;
+ USHORT fRight = ( nValue & 0x0F00 ) >> 8;
+ USHORT fBottom = ( nValue & 0xF000 ) >> 12;
+
+ if( fLeft > 1 )
+ nLeft = 50;
+ else if( fLeft > 0 )
+ nLeft = 20;
+
+ if( fTop > 1 )
+ nTop = 50;
+ else if( fTop > 0 )
+ nTop = 20;
+
+ if( fRight > 1 )
+ nRight = 50;
+ else if( fRight > 0 )
+ nRight = 20;
+
+ if( fBottom > 1 )
+ nBottom = 50;
+ else if( fBottom > 0 )
+ nBottom = 20;
+
+ Color ColorLeft( COL_BLACK );
+ Color ColorTop( COL_BLACK );
+ Color ColorRight( COL_BLACK );
+ Color ColorBottom( COL_BLACK );
+ USHORT nFrmColVal = aFrameColor.pData[ nColorIndex ].Value;
+ SCROW nFrmColRow = static_cast<SCROW>(aFrameColor.pData[ nColorIndex ].Row);
+ USHORT cLeft = ( nFrmColVal & 0x000F );
+ USHORT cTop = ( nFrmColVal & 0x00F0 ) >> 4;
+ USHORT cRight = ( nFrmColVal & 0x0F00 ) >> 8;
+ USHORT cBottom = ( nFrmColVal & 0xF000 ) >> 12;
+
+ lcl_ChangeColor( cLeft, ColorLeft );
+ lcl_ChangeColor( cTop, ColorTop );
+ lcl_ChangeColor( cRight, ColorRight );
+ lcl_ChangeColor( cBottom, ColorBottom );
+
+ if( static_cast<SCROW>(pColData->Row) < nFrmColRow )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ if( nFrameIndex < ( aFrame.Count - 1 ) )
+ nFrameIndex++;
+ }
+ else if( static_cast<SCROW>(pColData->Row) > nFrmColRow )
+ {
+ nEnd = static_cast<SCROW>(aFrameColor.pData[ nColorIndex ].Row);
+ if( nColorIndex < ( aFrameColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ else
+ {
+ nEnd = nFrmColRow;
+ if( nFrameIndex < (aFrame.Count - 1 ) )
+ nFrameIndex++;
+ if( nColorIndex < ( aFrameColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ if( ( nStart <= nEnd ) && ( nValue != 0 ) )
+ {
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ SvxBorderLine aLine;
+ SvxBoxItem aBox( ATTR_BORDER );
+
+ aLine.SetOutWidth( nLeft );
+ aLine.SetColor( ColorLeft );
+ aBox.SetLine( &aLine, BOX_LINE_LEFT );
+
+ aLine.SetOutWidth( nTop );
+ aLine.SetColor( ColorTop );
+ aBox.SetLine( &aLine, BOX_LINE_TOP );
+
+ aLine.SetOutWidth( nRight );
+ aLine.SetColor( ColorRight );
+ aBox.SetLine( &aLine, BOX_LINE_RIGHT );
+
+ aLine.SetOutWidth( nBottom );
+ aLine.SetColor( ColorBottom );
+ aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+
+ aScPattern.GetItemSet().Put( aBox );
+ pDoc->ApplyPatternAreaTab( Col, nStart, Col, nEnd, Tab, aScPattern );
+ }
+ nStart = nEnd + 1;
+
+ bEnd = ( nFrameIndex == ( aFrame.Count - 1 ) ) && ( nColorIndex == ( aFrameColor.Count - 1 ) );
+
+ if( nColorIndexOld != nColorIndex || nFrameIndexOld != nFrameIndex )
+ {
+ nColorIndexOld = nColorIndex;
+ nFrameIndexOld = nFrameIndex;
+ nHelpMe = nHelpMeStart;
+ }
+ else
+ nHelpMe--;
+
+ pColData++;
+ }
+
+ // ACHTUNG: Code bis hier ueberarbeitet ... jetzt hab' ich keinen Bock mehr! (GT)
+
+ // Hintergrund (Farbe, Raster)
+ USHORT nRasterIndex = 0;
+ bEnd = FALSE;
+ nColorIndex = 0;
+ nEnd = 0;
+ nStart = 0;
+
+ // Special Fix...
+ nHelpMe = nHelpMeStart;
+ USHORT nRasterIndexOld = nRasterIndex;
+
+ while( !bEnd && nHelpMe )
+ {
+ USHORT nBColor = ( aColor.pData[ nColorIndex ].Value & 0x00F0 ) >> 4;
+ USHORT nRColor = ( aColor.pData[ nColorIndex ].Value & 0x0F00 ) >> 8;
+ Color aBColor( COL_BLACK );
+
+ lcl_ChangeColor( nBColor, aBColor );
+
+ if( nBColor == 0 )
+ aBColor.SetColor( COL_WHITE );
+ else if( nBColor == 15 )
+ aBColor.SetColor( COL_BLACK );
+
+ Color aRColor( COL_BLACK );
+
+ lcl_ChangeColor( nRColor, aRColor );
+
+ ScPatternAttr aScPattern( pDoc->GetPool() );
+
+ UINT16 nFact;
+ BOOL bSwapCol = FALSE;
+ BOOL bSetItem = TRUE;
+ switch ( aRaster.pData[ nRasterIndex ].Value )
+ {
+ case raNone: nFact = 0xffff; bSwapCol = TRUE; bSetItem = (nBColor > 0); break;
+ case raGray12: nFact = (0xffff / 100) * 12; break;
+ case raGray25: nFact = (0xffff / 100) * 25; break;
+ case raGray50: nFact = (0xffff / 100) * 50; break;
+ case raGray75: nFact = (0xffff / 100) * 75; break;
+ default: nFact = 0xffff; bSetItem = (nRColor < 15);
+ }
+ if ( bSetItem )
+ {
+ if( bSwapCol )
+ aScPattern.GetItemSet().Put( SvxBrushItem( GetMixedColor( aBColor, aRColor, nFact ), ATTR_BACKGROUND ) );
+ else
+ aScPattern.GetItemSet().Put( SvxBrushItem( GetMixedColor( aRColor, aBColor, nFact ), ATTR_BACKGROUND ) );
+ }
+ if( aRaster.pData[ nRasterIndex ].Row < aColor.pData[ nColorIndex ].Row )
+ {
+ nEnd = static_cast<SCROW>(aRaster.pData[ nRasterIndex ].Row);
+ if( nRasterIndex < ( aRaster.Count - 1 ) )
+ nRasterIndex++;
+ }
+ else if( aRaster.pData[ nRasterIndex ].Row > aColor.pData[ nColorIndex ].Row )
+ {
+ nEnd = static_cast<SCROW>(aColor.pData[ nColorIndex ].Row);
+ if( nColorIndex < ( aColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ else
+ {
+ nEnd = static_cast<SCROW>(aColor.pData[ nColorIndex ].Row);
+ if( nRasterIndex < ( aRaster.Count - 1 ) )
+ nRasterIndex++;
+ if( nColorIndex < ( aColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ if( nStart <= nEnd )
+ pDoc->ApplyPatternAreaTab( Col, nStart, Col, nEnd, Tab, aScPattern );
+
+ nStart = nEnd + 1;
+
+ bEnd = ( nRasterIndex == ( aRaster.Count - 1 ) ) && ( nColorIndex == ( aColor.Count - 1 ) );
+
+ if( nColorIndexOld != nColorIndex || nRasterIndexOld != nRasterIndex )
+ {
+ nColorIndexOld = nColorIndex;
+ nRasterIndexOld = nRasterIndex;
+ nHelpMe = nHelpMeStart;
+ }
+ else
+ nHelpMe--;
+
+ nHelpMe--;
+ }
+
+ // Zahlenformate
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aValue.Count;
+ pColData = aValue.pData;
+ for (i=0; i<nLimit; i++, pColData++)
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ nValue1 = pColData->Value;
+ if ((nStart <= nEnd) && (nValue1))
+ {
+ ULONG nKey = 0;
+ USHORT nFormat = (nValue1 & 0x00FF);
+ USHORT nInfo = (nValue1 & 0xFF00) >> 8;
+ ChangeFormat(nFormat, nInfo, nKey);
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(SfxUInt32Item(ATTR_VALUE_FORMAT, (UINT32)nKey));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Zellattribute (Schutz, Versteckt...)
+ nStart = 0;
+ nEnd = 0;
+ for (i=0; i<aFlag.Count; i++)
+ {
+ nEnd = static_cast<SCROW>(aFlag.pData[i].Row);
+ if ((nStart <= nEnd) && (aFlag.pData[i].Value != 0))
+ {
+ BOOL bProtect = ((aFlag.pData[i].Value & paProtect) == paProtect);
+ BOOL bHFormula = ((aFlag.pData[i].Value & paHideFormula) == paHideFormula);
+ BOOL bHCell = ((aFlag.pData[i].Value & paHideAll) == paHideAll);
+ BOOL bHPrint = ((aFlag.pData[i].Value & paHidePrint) == paHidePrint);
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(ScProtectionAttr(bProtect, bHFormula, bHCell, bHPrint));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // ZellVorlagen
+ nStart = 0;
+ nEnd = 0;
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ for (i=0; i<aPattern.Count; i++)
+ {
+ nEnd = static_cast<SCROW>(aPattern.pData[i].Row);
+ if ((nStart <= nEnd) && (aPattern.pData[i].Value != 0))
+ {
+ USHORT nPatternIndex = (aPattern.pData[i].Value & 0x00FF) - 1;
+ Sc10PatternData* pPattern = pPatternCollection->At(nPatternIndex);
+ if (pPattern != NULL)
+ {
+ ScStyleSheet* pStyle = (ScStyleSheet*) pStylePool->Find(
+ SC10TOSTRING( pPattern->Name ), SFX_STYLE_FAMILY_PARA);
+
+ if (pStyle != NULL)
+ pDoc->ApplyStyleAreaTab(Col, nStart, Col, nEnd, Tab, *pStyle);
+ }
+ }
+ nStart = nEnd + 1;
+ }
+ }
+
+ delete[] aFont.pData;
+ delete[] aAttr.pData;
+ delete[] aJustify.pData;
+ delete[] aFrame.pData;
+ delete[] aRaster.pData;
+ delete[] aValue.pData;
+ delete[] aColor.pData;
+ delete[] aFrameColor.pData;
+ delete[] aFlag.pData;
+ delete[] aPattern.pData;
+}
+
+
+void Sc10Import::LoadAttr(Sc10ColAttr& rAttr)
+{
+ rStream >> rAttr.Count;
+ rAttr.pData = new Sc10ColData[rAttr.Count];
+ if (rAttr.pData != NULL)
+ {
+ for (USHORT i = 0; i < rAttr.Count; i++)
+ {
+ rStream >> rAttr.pData[i].Row;
+ rStream >> rAttr.pData[i].Value;
+ }
+ //rStream.Read(rAttr.pData, rAttr.Count * sizeof(Sc10ColData));
+ nError = rStream.GetError();
+ }
+ else
+ nError = errOutOfMemory;
+}
+
+
+void Sc10Import::ChangeFormat(USHORT nFormat, USHORT nInfo, ULONG& nKey)
+{
+ // Achtung: Die Formate werden nur auf die StarCalc 3.0 internen Formate gemappt
+ // Korrekterweise muessten zum Teil neue Formate erzeugt werden (sollte Stephan sich ansehen)
+ nKey = 0;
+ switch (nFormat)
+ {
+ case vfStandard :
+ if (nInfo > 0)
+ nKey = 2;
+ break;
+ case vfMoney :
+ if (nInfo > 0)
+ nKey = 21;
+ else
+ nKey = 20;
+ break;
+ case vfThousend :
+ if (nInfo > 0)
+ nKey = 4;
+ else
+ nKey = 5;
+ break;
+ case vfPercent :
+ if (nInfo > 0)
+ nKey = 11;
+ else
+ nKey = 10;
+ break;
+ case vfExponent :
+ nKey = 60;
+ break;
+ case vfZerro :
+ // Achtung kein Aequivalent
+ break;
+ case vfDate :
+ switch (nInfo)
+ {
+ case df_NDMY_Long :
+ nKey = 31;
+ break;
+ case df_DMY_Long :
+ nKey = 30;
+ break;
+ case df_MY_Long :
+ nKey = 32;
+ break;
+ case df_NDM_Long :
+ nKey = 31;
+ break;
+ case df_DM_Long :
+ nKey = 33;
+ break;
+ case df_M_Long :
+ nKey = 34;
+ break;
+ case df_NDMY_Short :
+ nKey = 31;
+ break;
+ case df_DMY_Short :
+ nKey = 30;
+ break;
+ case df_MY_Short :
+ nKey = 32;
+ break;
+ case df_NDM_Short :
+ nKey = 31;
+ break;
+ case df_DM_Short :
+ nKey = 33;
+ break;
+ case df_M_Short :
+ nKey = 34;
+ break;
+ case df_Q_Long :
+ nKey = 35;
+ break;
+ case df_Q_Short :
+ nKey = 35;
+ break;
+ default :
+ nKey = 30;
+ break;
+ }
+ break;
+ case vfTime :
+ switch (nInfo)
+ {
+ case tf_HMS_Long :
+ nKey = 41;
+ break;
+ case tf_HM_Long :
+ nKey = 40;
+ break;
+ case tf_HMS_Short :
+ nKey = 43;
+ break;
+ case tf_HM_Short :
+ nKey = 42;
+ break;
+ default :
+ nKey = 41;
+ break;
+ }
+ break;
+ case vfBoolean :
+ nKey = 99;
+ break;
+ case vfStandardRed :
+ if (nInfo > 0)
+ nKey = 2;
+ break;
+ case vfMoneyRed :
+ if (nInfo > 0)
+ nKey = 23;
+ else
+ nKey = 22;
+ break;
+ case vfThousendRed :
+ if (nInfo > 0)
+ nKey = 4;
+ else
+ nKey = 5;
+ break;
+ case vfPercentRed :
+ if (nInfo > 0)
+ nKey = 11;
+ else
+ nKey = 10;
+ break;
+ case vfExponentRed :
+ nKey = 60;
+ break;
+ case vfFormula :
+ break;
+ case vfString :
+ break;
+ default :
+ break;
+ }
+}
+
+
+void Sc10Import::LoadObjects()
+{
+ USHORT ID;
+ rStream >> ID;
+ if (rStream.IsEof()) return;
+ if (ID == ObjectID)
+ {
+#ifdef SC10_SHOW_OBJECTS
+ // Achtung nur zu Debugzwecken
+ //-----------------------------------
+ pDoc->InsertTab(SC_TAB_APPEND, "GraphObjects");
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+ SCTAB nTab = 0;
+ pDoc->GetTable("GraphObjects", nTab);
+ pDoc->SetString(nCol++, nRow, nTab, "ObjectTyp");
+ pDoc->SetString(nCol++, nRow, nTab, "Col");
+ pDoc->SetString(nCol++, nRow, nTab, "Row");
+ pDoc->SetString(nCol++, nRow, nTab, "Tab");
+ pDoc->SetString(nCol++, nRow, nTab, "X");
+ pDoc->SetString(nCol++, nRow, nTab, "Y");
+ pDoc->SetString(nCol++, nRow, nTab, "W");
+ pDoc->SetString(nCol++, nRow, nTab, "H");
+ //-----------------------------------
+#endif
+
+ USHORT nAnz;
+ rStream >> nAnz;
+ sal_Char Reserved[32];
+ rStream.Read(Reserved, sizeof(Reserved));
+ nError = rStream.GetError();
+ if ((nAnz > 0) && (nError == 0))
+ {
+ BYTE ObjectType;
+ Sc10GraphHeader GraphHeader;
+ BOOL IsOleObject = FALSE; // Achtung dies ist nur ein Notnagel
+ for (USHORT i = 0; (i < nAnz) && (nError == 0) && !rStream.IsEof() && !IsOleObject; i++)
+ {
+ rStream >> ObjectType;
+ //rStream.Read(&GraphHeader, sizeof(GraphHeader));
+ lcl_ReadGraphHeader(rStream, GraphHeader);
+
+ double nPPTX = ScGlobal::nScreenPPTX;
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ long nStartX = 0;
+ for (SCsCOL nX=0; nX<GraphHeader.CarretX; nX++)
+ nStartX += pDoc->GetColWidth(nX, static_cast<SCTAB>(GraphHeader.CarretZ));
+ nStartX = (long) ( nStartX * HMM_PER_TWIPS );
+ nStartX += (long) ( GraphHeader.x / nPPTX * HMM_PER_TWIPS );
+ long nSizeX = (long) ( GraphHeader.w / nPPTX * HMM_PER_TWIPS );
+ long nStartY = pDoc->GetRowHeight( 0,
+ static_cast<SCsROW>(GraphHeader.CarretY) - 1,
+ static_cast<SCTAB>(GraphHeader.CarretZ));
+ nStartY = (long) ( nStartY * HMM_PER_TWIPS );
+ nStartY += (long) ( GraphHeader.y / nPPTY * HMM_PER_TWIPS );
+ long nSizeY = (long) ( GraphHeader.h / nPPTY * HMM_PER_TWIPS );
+
+#ifdef SC10_SHOW_OBJECTS
+ // Achtung nur zu Debugzwecken
+ //-----------------------------------
+ nCol = 0;
+ nRow++;
+ switch (ObjectType)
+ {
+ case otOle :
+ pDoc->SetString(nCol++, nRow, nTab, "Ole-Object");
+ break;
+ case otImage :
+ pDoc->SetString(nCol++, nRow, nTab, "Image-Object");
+ break;
+ case otChart :
+ pDoc->SetString(nCol++, nRow, nTab, "Chart-Object");
+ break;
+ default :
+ pDoc->SetString(nCol++, nRow, nTab, "ERROR");
+ break;
+ }
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.CarretX);
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.CarretY);
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.CarretZ);
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.x);
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.y);
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.w);
+ pDoc->SetValue(nCol++, nRow, nTab, GraphHeader.h);
+ //-----------------------------------
+#endif
+
+ switch (ObjectType)
+ {
+ case otOle :
+ // Achtung hier muss sowas wie OleLoadFromStream passieren
+ IsOleObject = TRUE;
+ break;
+ case otImage :
+ {
+ Sc10ImageHeader ImageHeader;
+ //rStream.Read(&ImageHeader, sizeof(ImageHeader));
+ lcl_ReadImageHeaer(rStream, ImageHeader);
+
+ // Achtung nun kommen die Daten (Bitmap oder Metafile)
+ // Typ = 1 Device Dependend Bitmap DIB
+ // Typ = 2 MetaFile
+ rStream.SeekRel(ImageHeader.Size);
+
+ if( ImageHeader.Typ != 1 && ImageHeader.Typ != 2 )
+ nError = errUnknownFormat;
+ break;
+ }
+ case otChart :
+ {
+ Sc10ChartHeader ChartHeader;
+ Sc10ChartSheetData ChartSheetData;
+ Sc10ChartTypeData* pTypeData = new Sc10ChartTypeData;
+ //rStream.Read(&ChartHeader, sizeof(ChartHeader));
+ lcl_ReadChartHeader(rStream, ChartHeader);
+
+ //! altes Metafile verwenden ??
+ rStream.SeekRel(ChartHeader.Size);
+
+ //rStream.Read(&ChartSheetData, sizeof(ChartSheetData));
+ lcl_ReadChartSheetData(rStream, ChartSheetData);
+
+ //rStream.Read(pTypeData, sizeof(Sc10ChartTypeData));
+ lcl_ReadChartTypeData(rStream, *pTypeData);
+
+ Rectangle aRect( Point(nStartX,nStartY), Size(nSizeX,nSizeY) );
+ Sc10InsertObject::InsertChart( pDoc, static_cast<SCTAB>(GraphHeader.CarretZ), aRect,
+ static_cast<SCTAB>(GraphHeader.CarretZ),
+ ChartSheetData.DataX1, ChartSheetData.DataY1,
+ ChartSheetData.DataX2, ChartSheetData.DataY2 );
+
+ delete pTypeData;
+ }
+ break;
+ default :
+ nError = errUnknownFormat;
+ break;
+ }
+ nError = rStream.GetError();
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR( "ObjectID" );
+ nError = errUnknownID;
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------------------------
+
+FltError ScFormatFilterPluginImpl::ScImportStarCalc10( SvStream& rStream, ScDocument* pDocument )
+{
+ rStream.Seek( 0UL );
+ Sc10Import aImport( rStream, pDocument );
+ return ( FltError ) aImport.Import();
+}
+
+
+
diff --git a/sc/source/filter/starcalc/scfobj.cxx b/sc/source/filter/starcalc/scfobj.cxx
new file mode 100644
index 000000000000..c0f575313459
--- /dev/null
+++ b/sc/source/filter/starcalc/scfobj.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+
+
+using namespace com::sun::star;
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <unotools/moduleoptions.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <sfx2/objsh.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/app.hxx>
+#include <sot/clsids.hxx>
+#include "address.hxx"
+
+#include "scfobj.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "chartarr.hxx"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//==================================================================
+
+void Sc10InsertObject::InsertChart( ScDocument* pDoc, SCTAB nDestTab, const Rectangle& rRect,
+ SCTAB nSrcTab, USHORT nX1, USHORT nY1, USHORT nX2, USHORT nY2 )
+{
+ // wenn Chart nicht installiert ist, darf nicht auf SCH_MOD zugegriffen werden!
+ if ( !SvtModuleOptions().IsChart() )
+ return;
+
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = pDoc->GetDocumentShell()->
+ GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aName );
+ if ( xObj.is() )
+ {
+ SdrOle2Obj* pSdrOle2Obj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aName, rRect );
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ {
+ pDoc->InitDrawLayer();
+ pModel = pDoc->GetDrawLayer();
+ DBG_ASSERT(pModel,"Draw Layer ?");
+ }
+
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nDestTab));
+ DBG_ASSERT(pPage,"Page ?");
+ pPage->InsertObject(pSdrOle2Obj);
+
+ pSdrOle2Obj->SetLogicRect(rRect); // erst nach InsertObject !!!
+ awt::Size aSz;
+ aSz.Width = rRect.GetSize().Width();
+ aSz.Height = rRect.GetSize().Height();
+ xObj->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, aSz );
+
+ // hier kann das Chart noch nicht mit Daten gefuettert werden,
+ // weil die Formeln noch nicht berechnet sind.
+ // Deshalb in die ChartCollection, die Daten werden dann im
+ // Sc10Import dtor geholt.
+
+ ScChartCollection* pColl = pDoc->GetChartCollection();
+ pColl->Insert( new ScChartArray( pDoc, nSrcTab, static_cast<SCCOL>(nX1), static_cast<SCROW>(nY1), static_cast<SCCOL>(nX2), static_cast<SCROW>(nY2), aName ) );
+ }
+}
+
+
+
diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
new file mode 100644
index 000000000000..42cb37250c5c
--- /dev/null
+++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
@@ -0,0 +1,1248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sot/storage.hxx>
+#include "XclExpChangeTrack.hxx"
+#include "xeformula.hxx"
+#include "cell.hxx"
+#include "xcl97rec.hxx"
+
+//___________________________________________________________________
+// local functions
+
+void lcl_WriteDateTime( XclExpStream& rStrm, const DateTime& rDateTime )
+{
+ rStrm.SetSliceSize( 7 );
+ rStrm << (sal_uInt16) rDateTime.GetYear()
+ << (sal_uInt8) rDateTime.GetMonth()
+ << (sal_uInt8) rDateTime.GetDay()
+ << (sal_uInt8) rDateTime.GetHour()
+ << (sal_uInt8) rDateTime.GetMin()
+ << (sal_uInt8) rDateTime.GetSec();
+ rStrm.SetSliceSize( 0 );
+}
+
+// write string and fill rest of <nLength> with zero bytes
+// <nLength> is without string header
+void lcl_WriteFixedString( XclExpStream& rStrm, const XclExpString& rString, sal_Size nLength )
+{
+ sal_Size nStrBytes = rString.GetBufferSize();
+ DBG_ASSERT( nLength >= nStrBytes, "lcl_WriteFixedString - String too long" );
+ if( rString.Len() > 0 )
+ rStrm << rString;
+ if( nLength > nStrBytes )
+ rStrm.WriteZeroBytes( nLength - nStrBytes );
+}
+
+inline void lcl_GenerateGUID( sal_uInt8* pGUID, sal_Bool& rValidGUID )
+{
+ rtl_createUuid( pGUID, rValidGUID ? pGUID : NULL, sal_False );
+ rValidGUID = sal_True;
+}
+
+inline void lcl_WriteGUID( XclExpStream& rStrm, const sal_uInt8* pGUID )
+{
+ rStrm.SetSliceSize( 16 );
+ for( sal_Size nIndex = 0; nIndex < 16; nIndex++ )
+ rStrm << pGUID[ nIndex ];
+ rStrm.SetSliceSize( 0 );
+}
+
+//___________________________________________________________________
+
+XclExpUserBView::XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID ) :
+ sUsername( rUsername )
+{
+ memcpy( aGUID, pGUID, 16 );
+}
+
+void XclExpUserBView::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt32) 0xFF078014
+ << (sal_uInt32) 0x00000001;
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm.WriteZeroBytes( 8 );
+ rStrm << (sal_uInt32) 1200
+ << (sal_uInt32) 1000
+ << (sal_uInt16) 1000
+ << (sal_uInt16) 0x0CF7
+ << (sal_uInt16) 0x0000
+ << (sal_uInt16) 0x0001
+ << (sal_uInt16) 0x0000;
+ if( sUsername.Len() > 0 )
+ rStrm << sUsername;
+}
+
+UINT16 XclExpUserBView::GetNum() const
+{
+ return 0x01A9;
+}
+
+sal_Size XclExpUserBView::GetLen() const
+{
+ return 50 + ((sUsername.Len() > 0) ? sUsername.GetSize() : 0);
+}
+
+//___________________________________________________________________
+
+XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack& rChangeTrack )
+{
+ sal_uInt8 aGUID[ 16 ];
+ sal_Bool bValidGUID = sal_False;
+ const ScStrCollection& rStrColl = rChangeTrack.GetUserCollection();
+ for( USHORT nIndex = 0; nIndex < rStrColl.GetCount(); nIndex++ )
+ {
+ const StrData* pStrData = (const StrData*) rStrColl.At( nIndex );
+ lcl_GenerateGUID( aGUID, bValidGUID );
+ if( pStrData )
+ List::Insert( new XclExpUserBView( pStrData->GetString(), aGUID ), LIST_APPEND );
+ }
+}
+
+XclExpUserBViewList::~XclExpUserBViewList()
+{
+ for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() )
+ delete pRec;
+}
+
+void XclExpUserBViewList::Save( XclExpStream& rStrm )
+{
+ for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() )
+ pRec->Save( rStrm );
+}
+
+//___________________________________________________________________
+
+XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab ) :
+ nCurrTab( nTab )
+{
+ memcpy( aGUID, pGUID, 16 );
+}
+
+void XclExpUsersViewBegin::SaveCont( XclExpStream& rStrm )
+{
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm << nCurrTab
+ << (sal_uInt32) 100
+ << (sal_uInt32) 64
+ << (sal_uInt32) 3
+ << (sal_uInt32) 0x0000003C
+ << (sal_uInt16) 0
+ << (sal_uInt16) 3
+ << (sal_uInt16) 0
+ << (sal_uInt16) 3
+ << (double) 0
+ << (double) 0
+ << (sal_Int16) -1
+ << (sal_Int16) -1;
+}
+
+UINT16 XclExpUsersViewBegin::GetNum() const
+{
+ return 0x01AA;
+}
+
+sal_Size XclExpUsersViewBegin::GetLen() const
+{
+ return 64;
+}
+
+//___________________________________________________________________
+
+void XclExpUsersViewEnd::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0001;
+}
+
+UINT16 XclExpUsersViewEnd::GetNum() const
+{
+ return 0x01AB;
+}
+
+sal_Size XclExpUsersViewEnd::GetLen() const
+{
+ return 2;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0191::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0000;
+}
+
+UINT16 XclExpChTr0x0191::GetNum() const
+{
+ return 0x0191;
+}
+
+sal_Size XclExpChTr0x0191::GetLen() const
+{
+ return 2;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0198::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0006
+ << (sal_uInt16) 0x0000;
+}
+
+UINT16 XclExpChTr0x0198::GetNum() const
+{
+ return 0x0198;
+}
+
+sal_Size XclExpChTr0x0198::GetLen() const
+{
+ return 4;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0192::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << sal_uInt16( 0x0022 );
+ rStrm.WriteZeroBytes( 510 );
+}
+
+UINT16 XclExpChTr0x0192::GetNum() const
+{
+ return 0x0192;
+}
+
+sal_Size XclExpChTr0x0192::GetLen() const
+{
+ return 512;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0197::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0000;
+}
+
+UINT16 XclExpChTr0x0197::GetNum() const
+{
+ return 0x0197;
+}
+
+sal_Size XclExpChTr0x0197::GetLen() const
+{
+ return 2;
+}
+
+//___________________________________________________________________
+
+XclExpChTrEmpty::~XclExpChTrEmpty()
+{
+}
+
+UINT16 XclExpChTrEmpty::GetNum() const
+{
+ return nRecNum;
+}
+
+sal_Size XclExpChTrEmpty::GetLen() const
+{
+ return 0;
+}
+
+//___________________________________________________________________
+
+XclExpChTr0x0195::~XclExpChTr0x0195()
+{
+}
+
+void XclExpChTr0x0195::SaveCont( XclExpStream& rStrm )
+{
+ rStrm.WriteZeroBytes( 162 );
+}
+
+UINT16 XclExpChTr0x0195::GetNum() const
+{
+ return 0x0195;
+}
+
+sal_Size XclExpChTr0x0195::GetLen() const
+{
+ return 162;
+}
+
+//___________________________________________________________________
+
+XclExpChTr0x0194::~XclExpChTr0x0194()
+{
+}
+
+void XclExpChTr0x0194::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt32) 0;
+ lcl_WriteDateTime( rStrm, aDateTime );
+ rStrm << (sal_uInt8) 0;
+ lcl_WriteFixedString( rStrm, sUsername, 147 );
+}
+
+UINT16 XclExpChTr0x0194::GetNum() const
+{
+ return 0x0194;
+}
+
+sal_Size XclExpChTr0x0194::GetLen() const
+{
+ return 162;
+}
+
+//___________________________________________________________________
+
+XclExpChTrHeader::~XclExpChTrHeader()
+{
+}
+
+void XclExpChTrHeader::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0006
+ << (sal_uInt16) 0x0000
+ << (sal_uInt16) 0x000D;
+ lcl_WriteGUID( rStrm, aGUID );
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm << nCount
+ << (sal_uInt16) 0x0001
+ << (sal_uInt32) 0x00000000
+ << (sal_uInt16) 0x001E;
+}
+
+UINT16 XclExpChTrHeader::GetNum() const
+{
+ return 0x0196;
+}
+
+sal_Size XclExpChTrHeader::GetLen() const
+{
+ return 50;
+}
+
+//___________________________________________________________________
+
+XclExpChTrInfo::~XclExpChTrInfo()
+{
+}
+
+void XclExpChTrInfo::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt32) 0xFFFFFFFF
+ << (sal_uInt32) 0x00000000
+ << (sal_uInt32) 0x00000020
+ << (sal_uInt16) 0xFFFF;
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm << (sal_uInt16) 0x04B0;
+ lcl_WriteFixedString( rStrm, sUsername, 113 );
+ lcl_WriteDateTime( rStrm, aDateTime );
+ rStrm << (sal_uInt8) 0x0000
+ << (sal_uInt16) 0x0002;
+}
+
+UINT16 XclExpChTrInfo::GetNum() const
+{
+ return 0x0138;
+}
+
+sal_Size XclExpChTrInfo::GetLen() const
+{
+ return 158;
+}
+
+//___________________________________________________________________
+
+XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) :
+ nBufSize( nCount ),
+ nLastId( nCount )
+{
+ pBuffer = new sal_uInt16[ nBufSize ];
+ memset( pBuffer, 0, sizeof(sal_uInt16) * nBufSize );
+ pLast = pBuffer + nBufSize - 1;
+}
+
+XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy ) :
+ nBufSize( rCopy.nBufSize ),
+ nLastId( rCopy.nLastId )
+{
+ pBuffer = new sal_uInt16[ nBufSize ];
+ memcpy( pBuffer, rCopy.pBuffer, sizeof(sal_uInt16) * nBufSize );
+ pLast = pBuffer + nBufSize - 1;
+}
+
+XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer()
+{
+ delete[] pBuffer;
+}
+
+void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex )
+{
+ DBG_ASSERT( nIndex < nLastId, "XclExpChTrTabIdBuffer::Insert - out of range" );
+
+ sal_uInt16 nFreeCount = 0;
+ for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
+ {
+ if( !*pElem )
+ nFreeCount++;
+ if( nFreeCount > nIndex )
+ {
+ *pElem = nLastId--;
+ return;
+ }
+ }
+}
+
+void XclExpChTrTabIdBuffer::InitFillup()
+{
+ sal_uInt16 nFreeCount = 1;
+ for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
+ if( !*pElem )
+ *pElem = nFreeCount++;
+ nLastId = nBufSize;
+}
+
+sal_uInt16 XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex ) const
+{
+ DBG_ASSERT( nIndex < nBufSize, "XclExpChTrTabIdBuffer::GetId - out of range" );
+ return pBuffer[ nIndex ];
+}
+
+void XclExpChTrTabIdBuffer::Remove()
+{
+ DBG_ASSERT( pBuffer <= pLast, "XclExpChTrTabIdBuffer::Remove - buffer empty" );
+ sal_uInt16* pElem = pBuffer;
+ while( (pElem <= pLast) && (*pElem != nLastId) )
+ pElem++;
+ while( pElem < pLast )
+ {
+ *pElem = *(pElem + 1);
+ pElem++;
+ }
+ pLast--;
+ nLastId--;
+}
+
+//___________________________________________________________________
+
+XclExpChTrTabIdBufferList::~XclExpChTrTabIdBufferList()
+{
+ for( XclExpChTrTabIdBuffer* pBuffer = First(); pBuffer; pBuffer = Next() )
+ delete pBuffer;
+}
+
+//___________________________________________________________________
+
+XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer ) :
+ nTabCount( rBuffer.GetBufferCount() )
+{
+ pBuffer = new sal_uInt16[ nTabCount ];
+ rBuffer.GetBufferCopy( pBuffer );
+}
+
+XclExpChTrTabId::~XclExpChTrTabId()
+{
+ Clear();
+}
+
+void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
+{
+ Clear();
+ nTabCount = rBuffer.GetBufferCount();
+ pBuffer = new sal_uInt16[ nTabCount ];
+ rBuffer.GetBufferCopy( pBuffer );
+}
+
+void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
+{
+ rStrm.EnableEncryption();
+ if( pBuffer )
+ for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
+ rStrm << *pElem;
+ else
+ for( sal_uInt16 nIndex = 1; nIndex <= nTabCount; nIndex++ )
+ rStrm << nIndex;
+}
+
+UINT16 XclExpChTrTabId::GetNum() const
+{
+ return 0x013D;
+}
+
+sal_Size XclExpChTrTabId::GetLen() const
+{
+ return nTabCount << 1;
+}
+
+//___________________________________________________________________
+
+// ! does not copy additional actions
+XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) :
+ ExcRecord( rCopy ),
+ sUsername( rCopy.sUsername ),
+ aDateTime( rCopy.aDateTime ),
+ nIndex( 0 ),
+ pAddAction( 0 ),
+ bAccepted( rCopy.bAccepted ),
+ rTabInfo( rCopy.rTabInfo ),
+ rIdBuffer( rCopy.rIdBuffer ),
+ nLength( rCopy.nLength ),
+ nOpCode( rCopy.nOpCode ),
+ bForceInfo( rCopy.bForceInfo )
+{
+}
+
+XclExpChTrAction::XclExpChTrAction(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ sal_uInt16 nNewOpCode ) :
+ sUsername( rAction.GetUser() ),
+ aDateTime( rAction.GetDateTime() ),
+ nIndex( 0 ),
+ pAddAction( NULL ),
+ bAccepted( rAction.IsAccepted() ),
+ rTabInfo( rRoot.GetTabInfo() ),
+ rIdBuffer( rTabIdBuffer ),
+ nLength( 0 ),
+ nOpCode( nNewOpCode ),
+ bForceInfo( sal_False )
+{
+ aDateTime.SetSec( 0 );
+ aDateTime.Set100Sec( 0 );
+}
+
+XclExpChTrAction::~XclExpChTrAction()
+{
+ if( pAddAction )
+ delete pAddAction;
+}
+
+void XclExpChTrAction::SetAddAction( XclExpChTrAction* pAction )
+{
+ if( pAddAction )
+ pAddAction->SetAddAction( pAction );
+ else
+ pAddAction = pAction;
+}
+
+void XclExpChTrAction::AddDependentContents(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ ScChangeTrack& rChangeTrack )
+{
+ ScChangeActionTable aActionTable;
+ rChangeTrack.GetDependents( (ScChangeAction*)(&rAction), aActionTable );
+ for( const ScChangeAction* pDepAction = aActionTable.First(); pDepAction; pDepAction = aActionTable.Next() )
+ if( pDepAction->GetType() == SC_CAT_CONTENT )
+ SetAddAction( new XclExpChTrCellContent(
+ *((const ScChangeActionContent*) pDepAction), rRoot, rIdBuffer ) );
+}
+
+void XclExpChTrAction::SetIndex( sal_uInt32& rIndex )
+{
+ nIndex = rIndex++;
+}
+
+void XclExpChTrAction::SaveCont( XclExpStream& rStrm )
+{
+ DBG_ASSERT( nOpCode != EXC_CHTR_OP_UNKNOWN, "XclExpChTrAction::SaveCont - unknown action" );
+ rStrm << nLength
+ << nIndex
+ << nOpCode
+ << (sal_uInt16)(bAccepted ? EXC_CHTR_ACCEPT : EXC_CHTR_NOTHING);
+ SaveActionData( rStrm );
+}
+
+void XclExpChTrAction::PrepareSaveAction( XclExpStream& /*rStrm*/ ) const
+{
+}
+
+void XclExpChTrAction::CompleteSaveAction( XclExpStream& /*rStrm*/ ) const
+{
+}
+
+void XclExpChTrAction::Save( XclExpStream& rStrm )
+{
+ PrepareSaveAction( rStrm );
+ ExcRecord::Save( rStrm );
+ if( pAddAction )
+ pAddAction->Save( rStrm );
+ CompleteSaveAction( rStrm );
+}
+
+sal_Size XclExpChTrAction::GetLen() const
+{
+ return GetHeaderByteCount() + GetActionByteCount();
+}
+
+//___________________________________________________________________
+
+XclExpChTrData::XclExpChTrData() :
+ pString( NULL ),
+ fValue( 0.0 ),
+ nRKValue( 0 ),
+ nType( EXC_CHTR_TYPE_EMPTY ),
+ nSize( 0 )
+{
+}
+
+XclExpChTrData::~XclExpChTrData()
+{
+ Clear();
+}
+
+void XclExpChTrData::Clear()
+{
+ DELETEZ( pString );
+ mxTokArr.reset();
+ maRefLog.clear();
+ fValue = 0.0;
+ nRKValue = 0;
+ nType = EXC_CHTR_TYPE_EMPTY;
+ nSize = 0;
+}
+
+void XclExpChTrData::WriteFormula( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
+{
+ DBG_ASSERT( mxTokArr.is() && !mxTokArr->Empty(), "XclExpChTrData::Write - no formula" );
+ rStrm << *mxTokArr;
+
+ for( XclExpRefLog::const_iterator aIt = maRefLog.begin(), aEnd = maRefLog.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mpUrl && aIt->mpFirstTab )
+ {
+ rStrm << *aIt->mpUrl << (sal_uInt8) 0x01 << *aIt->mpFirstTab << (sal_uInt8) 0x02;
+ }
+ else
+ {
+ bool bSingleTab = aIt->mnFirstXclTab == aIt->mnLastXclTab;
+ rStrm.SetSliceSize( bSingleTab ? 6 : 8 );
+ rStrm << (sal_uInt8) 0x01 << (sal_uInt8) 0x02 << (sal_uInt8) 0x00;
+ rStrm << rTabIdBuffer.GetId( aIt->mnFirstXclTab );
+ if( bSingleTab )
+ rStrm << (sal_uInt8) 0x02;
+ else
+ rStrm << (sal_uInt8) 0x00 << rTabIdBuffer.GetId( aIt->mnLastXclTab );
+ }
+ }
+ rStrm.SetSliceSize( 0 );
+ rStrm << (sal_uInt8) 0x00;
+}
+
+void XclExpChTrData::Write( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
+{
+ switch( nType )
+ {
+ case EXC_CHTR_TYPE_RK:
+ rStrm << nRKValue;
+ break;
+ case EXC_CHTR_TYPE_DOUBLE:
+ rStrm << fValue;
+ break;
+ case EXC_CHTR_TYPE_STRING:
+ DBG_ASSERT( pString, "XclExpChTrData::Write - no string" );
+ rStrm << *pString;
+ break;
+ case EXC_CHTR_TYPE_FORMULA:
+ WriteFormula( rStrm, rTabIdBuffer );
+ break;
+ }
+}
+
+//___________________________________________________________________
+
+XclExpChTrCellContent::XclExpChTrCellContent(
+ const ScChangeActionContent& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_CELL ),
+ XclExpRoot( rRoot ),
+ pOldData( 0 ),
+ pNewData( 0 ),
+ aPosition( rAction.GetBigRange().MakeRange().aStart )
+{
+ sal_uInt32 nDummy32;
+ sal_uInt16 nDummy16;
+ GetCellData( rAction.GetOldCell(), pOldData, nDummy32, nOldLength );
+ GetCellData( rAction.GetNewCell(), pNewData, nLength, nDummy16 );
+}
+
+XclExpChTrCellContent::~XclExpChTrCellContent()
+{
+ if( pOldData )
+ delete pOldData;
+ if( pNewData )
+ delete pNewData;
+}
+
+void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData*& rpData )
+{
+ if( rpData )
+ rpData->Clear();
+ else
+ rpData = new XclExpChTrData;
+}
+
+void XclExpChTrCellContent::GetCellData(
+ const ScBaseCell* pScCell,
+ XclExpChTrData*& rpData,
+ sal_uInt32& rXclLength1,
+ sal_uInt16& rXclLength2 )
+{
+ MakeEmptyChTrData( rpData );
+ rXclLength1 = 0x0000003A;
+ rXclLength2 = 0x0000;
+
+ if( !pScCell )
+ {
+ delete rpData;
+ rpData = NULL;
+ return;
+ }
+
+ switch( pScCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ {
+ rpData->fValue = ((const ScValueCell*) pScCell)->GetValue();
+ if( XclTools::GetRKFromDouble( rpData->nRKValue, rpData->fValue ) )
+ {
+ rpData->nType = EXC_CHTR_TYPE_RK;
+ rpData->nSize = 4;
+ rXclLength1 = 0x0000003E;
+ rXclLength2 = 0x0004;
+ }
+ else
+ {
+ rpData->nType = EXC_CHTR_TYPE_DOUBLE;
+ rpData->nSize = 8;
+ rXclLength1 = 0x00000042;
+ rXclLength2 = 0x0008;
+ }
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ String sCellStr;
+ if( pScCell->GetCellType() == CELLTYPE_STRING )
+ ((const ScStringCell*) pScCell)->GetString( sCellStr );
+ else
+ ((const ScEditCell*) pScCell)->GetString( sCellStr );
+ rpData->pString = new XclExpString( sCellStr, EXC_STR_DEFAULT, 32766 );
+ rpData->nType = EXC_CHTR_TYPE_STRING;
+ rpData->nSize = 3 + rpData->pString->GetSize();
+ rXclLength1 = 64 + (sCellStr.Len() << 1);
+ rXclLength2 = 6 + (sal_uInt16)(sCellStr.Len() << 1);
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ const ScFormulaCell* pFmlCell = (const ScFormulaCell*) pScCell;
+ const ScTokenArray* pTokenArray = pFmlCell->GetCode();
+ if( pTokenArray )
+ {
+ XclExpRefLog& rRefLog = rpData->maRefLog;
+ rpData->mxTokArr = GetFormulaCompiler().CreateFormula(
+ EXC_FMLATYPE_CELL, *pTokenArray, &pFmlCell->aPos, &rRefLog );
+ rpData->nType = EXC_CHTR_TYPE_FORMULA;
+ sal_Size nSize = rpData->mxTokArr->GetSize() + 3;
+
+ for( XclExpRefLog::const_iterator aIt = rRefLog.begin(), aEnd = rRefLog.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mpUrl && aIt->mpFirstTab )
+ nSize += aIt->mpUrl->GetSize() + aIt->mpFirstTab->GetSize() + 2;
+ else
+ nSize += (aIt->mnFirstXclTab == aIt->mnLastXclTab) ? 6 : 8;
+ }
+ rpData->nSize = ::std::min< sal_Size >( nSize, 0xFFFF );
+ rXclLength1 = 0x00000052;
+ rXclLength2 = 0x0018;
+ }
+ }
+ break;
+ default:;
+ }
+}
+
+void XclExpChTrCellContent::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aPosition.Tab() );
+ rStrm << (sal_uInt16)((pOldData ? (pOldData->nType << 3) : 0x0000) | (pNewData ? pNewData->nType : 0x0000))
+ << (sal_uInt16) 0x0000;
+ Write2DAddress( rStrm, aPosition );
+ rStrm << nOldLength
+ << (sal_uInt32) 0x00000000;
+ if( pOldData )
+ pOldData->Write( rStrm, rIdBuffer );
+ if( pNewData )
+ pNewData->Write( rStrm, rIdBuffer );
+}
+
+UINT16 XclExpChTrCellContent::GetNum() const
+{
+ return 0x013B;
+}
+
+sal_Size XclExpChTrCellContent::GetActionByteCount() const
+{
+ sal_Size nLen = 16;
+ if( pOldData )
+ nLen += pOldData->nSize;
+ if( pNewData )
+ nLen += pNewData->nSize;
+ return nLen;
+}
+
+//___________________________________________________________________
+
+XclExpChTrInsert::XclExpChTrInsert(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer ),
+ aRange( rAction.GetBigRange().MakeRange() )
+{
+ nLength = 0x00000030;
+ switch( rAction.GetType() )
+ {
+ case SC_CAT_INSERT_COLS: nOpCode = EXC_CHTR_OP_INSCOL; break;
+ case SC_CAT_INSERT_ROWS: nOpCode = EXC_CHTR_OP_INSROW; break;
+ case SC_CAT_DELETE_COLS: nOpCode = EXC_CHTR_OP_DELCOL; break;
+ case SC_CAT_DELETE_ROWS: nOpCode = EXC_CHTR_OP_DELROW; break;
+ default:
+ DBG_ERROR( "XclExpChTrInsert::XclExpChTrInsert - unknown action" );
+ }
+
+ if( nOpCode & EXC_CHTR_OP_COLFLAG )
+ {
+ aRange.aStart.SetRow( 0 );
+ aRange.aEnd.SetRow( rRoot.GetXclMaxPos().Row() );
+ }
+ else
+ {
+ aRange.aStart.SetCol( 0 );
+ aRange.aEnd.SetCol( rRoot.GetXclMaxPos().Col() );
+ }
+
+ if( nOpCode & EXC_CHTR_OP_DELFLAG )
+ {
+ SetAddAction( new XclExpChTr0x014A( *this ) );
+ AddDependentContents( rAction, rRoot, rChangeTrack );
+ }
+}
+
+XclExpChTrInsert::~XclExpChTrInsert()
+{
+}
+
+void XclExpChTrInsert::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aRange.aStart.Tab() );
+ rStrm << (sal_uInt16) 0x0000;
+ Write2DRange( rStrm, aRange );
+ rStrm << (sal_uInt32) 0x00000000;
+}
+
+void XclExpChTrInsert::PrepareSaveAction( XclExpStream& rStrm ) const
+{
+ if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
+ XclExpChTrEmpty( 0x0150 ).Save( rStrm );
+}
+
+void XclExpChTrInsert::CompleteSaveAction( XclExpStream& rStrm ) const
+{
+ if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
+ XclExpChTrEmpty( 0x0151 ).Save( rStrm );
+}
+
+UINT16 XclExpChTrInsert::GetNum() const
+{
+ return 0x0137;
+}
+
+sal_Size XclExpChTrInsert::GetActionByteCount() const
+{
+ return 16;
+}
+
+//___________________________________________________________________
+
+XclExpChTrInsertTab::XclExpChTrInsertTab(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_INSTAB ),
+ XclExpRoot( rRoot ),
+ nTab( (SCTAB) rAction.GetBigRange().aStart.Tab() )
+{
+ nLength = 0x0000021C;
+ bForceInfo = sal_True;
+}
+
+XclExpChTrInsertTab::~XclExpChTrInsertTab()
+{
+}
+
+void XclExpChTrInsertTab::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, nTab );
+ rStrm << sal_uInt32( 0 );
+ lcl_WriteFixedString( rStrm, XclExpString( GetTabInfo().GetScTabName( nTab ) ), 127 );
+ lcl_WriteDateTime( rStrm, GetDateTime() );
+ rStrm.WriteZeroBytes( 133 );
+}
+
+UINT16 XclExpChTrInsertTab::GetNum() const
+{
+ return 0x014D;
+}
+
+sal_Size XclExpChTrInsertTab::GetActionByteCount() const
+{
+ return 276;
+}
+
+//___________________________________________________________________
+
+XclExpChTrMoveRange::XclExpChTrMoveRange(
+ const ScChangeActionMove& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_MOVE ),
+ aDestRange( rAction.GetBigRange().MakeRange() )
+{
+ nLength = 0x00000042;
+ aSourceRange = aDestRange;
+ sal_Int32 nDCols, nDRows, nDTabs;
+ rAction.GetDelta( nDCols, nDRows, nDTabs );
+ aSourceRange.aStart.IncRow( (SCROW) -nDRows );
+ aSourceRange.aStart.IncCol( (SCCOL) -nDCols );
+ aSourceRange.aStart.IncTab( (SCTAB) -nDTabs );
+ aSourceRange.aEnd.IncRow( (SCROW) -nDRows );
+ aSourceRange.aEnd.IncCol( (SCCOL) -nDCols );
+ aSourceRange.aEnd.IncTab( (SCTAB) -nDTabs );
+ AddDependentContents( rAction, rRoot, rChangeTrack );
+}
+
+XclExpChTrMoveRange::~XclExpChTrMoveRange()
+{
+}
+
+void XclExpChTrMoveRange::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aDestRange.aStart.Tab() );
+ Write2DRange( rStrm, aSourceRange );
+ Write2DRange( rStrm, aDestRange );
+ WriteTabId( rStrm, aSourceRange.aStart.Tab() );
+ rStrm << (sal_uInt32) 0x00000000;
+}
+
+void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream& rStrm ) const
+{
+ XclExpChTrEmpty( 0x014E ).Save( rStrm );
+}
+
+void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream& rStrm ) const
+{
+ XclExpChTrEmpty( 0x014F ).Save( rStrm );
+}
+
+UINT16 XclExpChTrMoveRange::GetNum() const
+{
+ return 0x0140;
+}
+
+sal_Size XclExpChTrMoveRange::GetActionByteCount() const
+{
+ return 24;
+}
+
+//___________________________________________________________________
+
+XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert& rAction ) :
+ XclExpChTrInsert( rAction )
+{
+ nLength = 0x00000026;
+ nOpCode = EXC_CHTR_OP_FORMAT;
+}
+
+XclExpChTr0x014A::~XclExpChTr0x014A()
+{
+}
+
+void XclExpChTr0x014A::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aRange.aStart.Tab() );
+ rStrm << (sal_uInt16) 0x0003
+ << (sal_uInt16) 0x0001;
+ Write2DRange( rStrm, aRange );
+}
+
+UINT16 XclExpChTr0x014A::GetNum() const
+{
+ return 0x014A;
+}
+
+sal_Size XclExpChTr0x014A::GetActionByteCount() const
+{
+ return 14;
+}
+
+//___________________________________________________________________
+
+XclExpChTrActionStack::~XclExpChTrActionStack()
+{
+ while( XclExpChTrAction* pRec = Pop() )
+ delete pRec;
+}
+
+void XclExpChTrActionStack::Push( XclExpChTrAction* pNewRec )
+{
+ DBG_ASSERT( pNewRec, "XclExpChTrActionStack::Push - NULL pointer" );
+ if( pNewRec )
+ Stack::Push( pNewRec );
+}
+
+//___________________________________________________________________
+
+XclExpChTrRecordList::~XclExpChTrRecordList()
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ delete pRec;
+}
+
+void XclExpChTrRecordList::Append( ExcRecord* pNewRec )
+{
+ DBG_ASSERT( pNewRec, "XclExpChTrRecordList::Append - NULL pointer" );
+ if( pNewRec )
+ List::Insert( pNewRec, LIST_APPEND );
+}
+
+void XclExpChTrRecordList::Save( XclExpStream& rStrm )
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ pRec->Save( rStrm );
+}
+
+//___________________________________________________________________
+
+XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ aRecList(),
+ aActionStack(),
+ aTabIdBufferList(),
+ pTabIdBuffer( NULL ),
+ pTempDoc( NULL ),
+ nNewAction( 1 ),
+ pHeader( NULL ),
+ bValidGUID( sal_False )
+{
+ DBG_ASSERT( GetOldRoot().pTabId, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
+ if( !GetOldRoot().pTabId )
+ return;
+
+ ScChangeTrack* pTempChangeTrack = CreateTempChangeTrack();
+ if (!pTempChangeTrack)
+ return;
+
+ pTabIdBuffer = new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() );
+ aTabIdBufferList.Append( pTabIdBuffer );
+
+ // calculate final table order (tab id list)
+ const ScChangeAction* pScAction;
+ for( pScAction = pTempChangeTrack->GetLast(); pScAction; pScAction = pScAction->GetPrev() )
+ {
+ if( pScAction->GetType() == SC_CAT_INSERT_TABS )
+ {
+ SCTAB nScTab = static_cast< SCTAB >( pScAction->GetBigRange().aStart.Tab() );
+ pTabIdBuffer->InitFill( GetTabInfo().GetXclTab( nScTab ) );
+ }
+ }
+ pTabIdBuffer->InitFillup();
+ GetOldRoot().pTabId->Copy( *pTabIdBuffer );
+
+ // get actions in reverse order
+ pScAction = pTempChangeTrack->GetLast();
+ while( pScAction )
+ {
+ PushActionRecord( *pScAction );
+ const ScChangeAction* pPrevAction = pScAction->GetPrev();
+ pTempChangeTrack->Undo( pScAction->GetActionNumber(), pScAction->GetActionNumber() );
+ pScAction = pPrevAction;
+ }
+
+ // build record list
+ pHeader = new XclExpChTrHeader;
+ aRecList.Append( pHeader );
+ aRecList.Append( new XclExpChTr0x0195 );
+ aRecList.Append( new XclExpChTr0x0194( *pTempChangeTrack ) );
+
+ String sLastUsername;
+ DateTime aLastDateTime;
+ sal_uInt32 nIndex = 1;
+ while( XclExpChTrAction* pAction = aActionStack.Pop() )
+ {
+ if( (nIndex == 1) || pAction->ForceInfoRecord() ||
+ (pAction->GetUsername() != sLastUsername) ||
+ (pAction->GetDateTime() != aLastDateTime) )
+ {
+ lcl_GenerateGUID( aGUID, bValidGUID );
+ sLastUsername = pAction->GetUsername();
+ aLastDateTime = pAction->GetDateTime();
+ aRecList.Append( new XclExpChTrInfo( sLastUsername, aLastDateTime, aGUID ) );
+ aRecList.Append( new XclExpChTrTabId( pAction->GetTabIdBuffer() ) );
+ pHeader->SetGUID( aGUID );
+ }
+ pAction->SetIndex( nIndex );
+ aRecList.Append( pAction );
+ }
+
+ pHeader->SetGUID( aGUID );
+ pHeader->SetCount( nIndex - 1 );
+ aRecList.Append( new ExcEof );
+}
+
+XclExpChangeTrack::~XclExpChangeTrack()
+{
+ if( pTempDoc )
+ delete pTempDoc;
+}
+
+ScChangeTrack* XclExpChangeTrack::CreateTempChangeTrack()
+{
+ // get original change track
+ ScChangeTrack* pOrigChangeTrack = GetDoc().GetChangeTrack();
+ DBG_ASSERT( pOrigChangeTrack, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" );
+ if( !pOrigChangeTrack )
+ return NULL;
+
+ // create empty document
+ pTempDoc = new ScDocument;
+ DBG_ASSERT( pTempDoc, "XclExpChangeTrack::CreateTempChangeTrack - no temp document" );
+ if( !pTempDoc )
+ return NULL;
+
+ // adjust table count
+ SCTAB nOrigCount = GetDoc().GetTableCount();
+ String sTabName;
+ for( sal_Int32 nIndex = 0; nIndex < nOrigCount; nIndex++ )
+ {
+ pTempDoc->CreateValidTabName( sTabName );
+ pTempDoc->InsertTab( SC_TAB_APPEND, sTabName );
+ }
+ DBG_ASSERT( nOrigCount == pTempDoc->GetTableCount(),
+ "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" );
+ if( nOrigCount != pTempDoc->GetTableCount() )
+ return sal_False;
+
+ return pOrigChangeTrack->Clone(pTempDoc);
+}
+
+void XclExpChangeTrack::PushActionRecord( const ScChangeAction& rAction )
+{
+ XclExpChTrAction* pXclAction = NULL;
+ ScChangeTrack* pTempChangeTrack = pTempDoc->GetChangeTrack();
+ switch( rAction.GetType() )
+ {
+ case SC_CAT_CONTENT:
+ pXclAction = new XclExpChTrCellContent( (const ScChangeActionContent&) rAction, GetRoot(), *pTabIdBuffer );
+ break;
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_COLS:
+ if (pTempChangeTrack)
+ pXclAction = new XclExpChTrInsert( rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
+ break;
+ case SC_CAT_INSERT_TABS:
+ {
+ pXclAction = new XclExpChTrInsertTab( rAction, GetRoot(), *pTabIdBuffer );
+ XclExpChTrTabIdBuffer* pNewBuffer = new XclExpChTrTabIdBuffer( *pTabIdBuffer );
+ pNewBuffer->Remove();
+ aTabIdBufferList.Append( pNewBuffer );
+ pTabIdBuffer = pNewBuffer;
+ }
+ break;
+ case SC_CAT_MOVE:
+ if (pTempChangeTrack)
+ pXclAction = new XclExpChTrMoveRange( (const ScChangeActionMove&) rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
+ break;
+ default:;
+ }
+ if( pXclAction )
+ aActionStack.Push( pXclAction );
+}
+
+sal_Bool XclExpChangeTrack::WriteUserNamesStream()
+{
+ sal_Bool bRet = sal_False;
+ SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_USERNAMES );
+ DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
+ if( xSvStrm.Is() )
+ {
+ XclExpStream aXclStrm( *xSvStrm, GetRoot() );
+ XclExpChTr0x0191().Save( aXclStrm );
+ XclExpChTr0x0198().Save( aXclStrm );
+ XclExpChTr0x0192().Save( aXclStrm );
+ XclExpChTr0x0197().Save( aXclStrm );
+ xSvStrm->Commit();
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+void XclExpChangeTrack::Write()
+{
+ if( !aRecList.Count() )
+ return;
+
+ if( WriteUserNamesStream() )
+ {
+ SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_REVLOG );
+ DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::Write - no stream" );
+ if( xSvStrm.Is() )
+ {
+ XclExpStream aXclStrm( *xSvStrm, GetRoot(), EXC_MAXRECSIZE_BIFF8 + 8 );
+ aRecList.Save( aXclStrm );
+ xSvStrm->Commit();
+ }
+ }
+}
+
diff --git a/sc/source/filter/xcl97/XclImpChangeTrack.cxx b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
new file mode 100644
index 000000000000..96a301e1bef5
--- /dev/null
+++ b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
@@ -0,0 +1,502 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "XclImpChangeTrack.hxx"
+#include <tools/debug.hxx>
+#include <sot/storage.hxx>
+#include <svl/zforlist.hxx>
+#include "chgviset.hxx"
+#include "cell.hxx"
+#include "chgtrack.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "externalrefmgr.hxx"
+
+//___________________________________________________________________
+// class XclImpChangeTrack
+
+XclImpChangeTrack::XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm ) :
+ XclImpRoot( rRoot ),
+ aRecHeader(),
+ sOldUsername(),
+ pChangeTrack( NULL ),
+ pStrm( NULL ),
+ nTabIdCount( 0 ),
+ bGlobExit( sal_False ),
+ eNestedMode( nmBase )
+{
+ // Verify that the User Names stream exists before going any further. Excel adds both
+ // "Revision Log" and "User Names" streams when Change Tracking is active but the Revision log
+ // remains if Change Tracking is turned off.
+ SotStorageStreamRef xUserStrm = OpenStream( EXC_STREAM_USERNAMES );
+ if( !xUserStrm.Is() )
+ return;
+
+ xInStrm = OpenStream( EXC_STREAM_REVLOG );
+ if( xInStrm.Is() )
+ {
+ xInStrm->Seek( STREAM_SEEK_TO_END );
+ ULONG nStreamLen = xInStrm->Tell();
+ if( (xInStrm->GetErrorCode() == ERRCODE_NONE) && (nStreamLen != STREAM_SEEK_TO_END) )
+ {
+ xInStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ pStrm = new XclImpStream( *xInStrm, GetRoot() );
+ pStrm->CopyDecrypterFrom( rBookStrm );
+ pChangeTrack = new ScChangeTrack( GetDocPtr() );
+
+ sOldUsername = pChangeTrack->GetUser();
+ pChangeTrack->SetUseFixDateTime( TRUE );
+
+ ReadRecords();
+ }
+ }
+}
+
+XclImpChangeTrack::~XclImpChangeTrack()
+{
+ delete pChangeTrack;
+ delete pStrm;
+}
+
+void XclImpChangeTrack::DoAcceptRejectAction( ScChangeAction* pAction )
+{
+ if( !pAction ) return;
+ switch( aRecHeader.nAccept )
+ {
+ case EXC_CHTR_ACCEPT:
+ pChangeTrack->Accept( pAction );
+ break;
+ case EXC_CHTR_REJECT:
+ break;
+ }
+}
+
+void XclImpChangeTrack::DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast )
+{
+ for( sal_uInt32 nIndex = nFirst; nIndex <= nLast; nIndex++ )
+ DoAcceptRejectAction( pChangeTrack->GetAction( nIndex ) );
+}
+
+void XclImpChangeTrack::DoInsertRange( const ScRange& rRange )
+{
+ sal_uInt32 nFirst = pChangeTrack->GetActionMax() + 1;
+ pChangeTrack->AppendInsert( rRange );
+ sal_uInt32 nLast = pChangeTrack->GetActionMax();
+ DoAcceptRejectAction( nFirst, nLast );
+}
+
+void XclImpChangeTrack::DoDeleteRange( const ScRange& rRange )
+{
+ ULONG nFirst, nLast;
+ pChangeTrack->AppendDeleteRange( rRange, NULL, nFirst, nLast );
+ DoAcceptRejectAction( nFirst, nLast );
+}
+
+SCTAB XclImpChangeTrack::ReadTabNum()
+{
+ return static_cast<SCTAB>(GetTabInfo().GetCurrentIndex(
+ pStrm->ReaduInt16(), nTabIdCount ));
+}
+
+void XclImpChangeTrack::ReadDateTime( DateTime& rDateTime )
+{
+ sal_uInt16 nYear;
+ sal_uInt8 nMonth, nDay, nHour, nMin, nSec;
+
+ *pStrm >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec;
+
+ rDateTime.SetYear( nYear );
+ rDateTime.SetMonth( nMonth );
+ rDateTime.SetDay( nDay );
+ rDateTime.SetHour( nHour );
+ rDateTime.SetMin( nMin );
+ rDateTime.SetSec( nSec );
+ rDateTime.Set100Sec( 0 );
+}
+
+sal_Bool XclImpChangeTrack::CheckRecord( sal_uInt16 nOpCode )
+{
+ if( (nOpCode != EXC_CHTR_OP_UNKNOWN) && (aRecHeader.nOpCode != nOpCode) )
+ {
+ DBG_ERROR( "XclImpChangeTrack::CheckRecord - unknown action" );
+ return sal_False;
+ }
+ return aRecHeader.nIndex != 0;
+}
+
+sal_Bool XclImpChangeTrack::Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab, ExcelToSc8::ExternalTabInfo& rExtInfo )
+{
+ if( LookAtuInt8() == 0x01 )
+ {
+ rExtInfo.mbExternal = false;
+ // internal ref - read tab num and return sc tab num (position in TABID list)
+ pStrm->Ignore( 3 );
+ rFirstTab = static_cast< SCTAB >( GetTabInfo().GetCurrentIndex( pStrm->ReaduInt16(), nTabIdCount ) );
+ sal_uInt8 nFillByte = pStrm->ReaduInt8();
+ rLastTab = (nFillByte == 0x00) ?
+ static_cast< SCTAB >( GetTabInfo().GetCurrentIndex( pStrm->ReaduInt16(), nTabIdCount ) ) : rFirstTab;
+ }
+ else
+ {
+ // external ref - read doc and tab name and find sc tab num
+ // - URL
+ String aEncUrl( pStrm->ReadUniString() );
+ String aUrl;
+ bool bSelf;
+ XclImpUrlHelper::DecodeUrl( aUrl, bSelf, GetRoot(), aEncUrl );
+ pStrm->Ignore( 1 );
+ // - sheet name, always separated from URL
+ String aTabName( pStrm->ReadUniString() );
+ pStrm->Ignore( 1 );
+
+ rExtInfo.mbExternal = true;
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ pRefMgr->convertToAbsName(aUrl);
+ rExtInfo.mnFileId = pRefMgr->getExternalFileId(aUrl);
+ rExtInfo.maTabName = aTabName;
+ rFirstTab = rLastTab = 0;
+ }
+ return sal_True;
+}
+
+void XclImpChangeTrack::ReadFormula( ScTokenArray*& rpTokenArray, const ScAddress& rPosition )
+{
+ sal_uInt16 nFmlSize;
+ *pStrm >> nFmlSize;
+
+ // create a memory stream and copy the formula to be able to read simultaneously
+ // the formula and the additional 3D tab ref data following the formula
+ // here we have to simulate an Excel record to be able to use an XclImpStream...
+ // 2do: remove the stream member from formula converter and add it as a parameter
+ // to the Convert() routine (to prevent the construction/destruction of the
+ // converter in each formula)
+ SvMemoryStream aMemStrm;
+ aMemStrm << (sal_uInt16) 0x0001 << nFmlSize;
+ pStrm->CopyToStream( aMemStrm, nFmlSize );
+ XclImpStream aFmlaStrm( aMemStrm, GetRoot() );
+ aFmlaStrm.StartNextRecord();
+ XclImpChTrFmlConverter aFmlConv( GetRoot(), *this );
+
+ // read the formula, 3D tab refs from extended data
+ const ScTokenArray* pArray = NULL;
+ aFmlConv.Reset( rPosition );
+ BOOL bOK = (aFmlConv.Convert( pArray, aFmlaStrm, nFmlSize, false, FT_CellFormula) == ConvOK); // JEG : Check This
+ rpTokenArray = (bOK && pArray) ? new ScTokenArray( *pArray ) : NULL;
+ pStrm->Ignore( 1 );
+}
+
+void XclImpChangeTrack::ReadCell(
+ ScBaseCell*& rpCell,
+ sal_uInt32& rFormat,
+ sal_uInt16 nFlags,
+ const ScAddress& rPosition )
+{
+ rpCell = NULL;
+ rFormat = 0;
+ switch( nFlags & EXC_CHTR_TYPE_MASK )
+ {
+ case EXC_CHTR_TYPE_EMPTY:
+ break;
+ case EXC_CHTR_TYPE_RK:
+ {
+ double fValue = ReadRK();
+ if( pStrm->IsValid() )
+ rpCell = new ScValueCell( fValue );
+ }
+ break;
+ case EXC_CHTR_TYPE_DOUBLE:
+ {
+ double fValue;
+ *pStrm >> fValue;
+ if( pStrm->IsValid() )
+ rpCell = new ScValueCell( fValue );
+ }
+ break;
+ case EXC_CHTR_TYPE_STRING:
+ {
+ String sString( pStrm->ReadUniString() );
+ if( pStrm->IsValid() )
+ rpCell = new ScStringCell( sString );
+ }
+ break;
+ case EXC_CHTR_TYPE_BOOL:
+ {
+ double fValue = (double) ReadBool();
+ if( pStrm->IsValid() )
+ {
+ rpCell = new ScValueCell( fValue );
+ rFormat = GetFormatter().GetStandardFormat( NUMBERFORMAT_LOGICAL, ScGlobal::eLnge );
+ }
+ }
+ break;
+ case EXC_CHTR_TYPE_FORMULA:
+ {
+ ScTokenArray* pTokenArray = NULL;
+ ReadFormula( pTokenArray, rPosition );
+ if( pStrm->IsValid() && pTokenArray )
+ rpCell = new ScFormulaCell( GetDocPtr(), rPosition, pTokenArray );
+ }
+ break;
+ default:
+ DBG_ERROR( "XclImpChangeTrack::ReadCell - unknown data type" );
+ }
+}
+
+void XclImpChangeTrack::ReadChTrInsert()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_UNKNOWN ) )
+ {
+ if( (aRecHeader.nOpCode != EXC_CHTR_OP_INSROW) &&
+ (aRecHeader.nOpCode != EXC_CHTR_OP_INSCOL) &&
+ (aRecHeader.nOpCode != EXC_CHTR_OP_DELROW) &&
+ (aRecHeader.nOpCode != EXC_CHTR_OP_DELCOL) )
+ {
+ DBG_ERROR( "XclImpChangeTrack::ReadChTrInsert - unknown action" );
+ return;
+ }
+
+ ScRange aRange;
+ aRange.aStart.SetTab( ReadTabNum() );
+ aRange.aEnd.SetTab( aRange.aStart.Tab() );
+ pStrm->Ignore( 2 );
+ Read2DRange( aRange );
+
+ if( aRecHeader.nOpCode & EXC_CHTR_OP_COLFLAG )
+ aRange.aEnd.SetRow( MAXROW );
+ else
+ aRange.aEnd.SetCol( MAXCOL );
+
+ BOOL bValid = pStrm->IsValid();
+ if( FoundNestedMode() )
+ ReadNestedRecords();
+
+ if( bValid )
+ {
+ if( aRecHeader.nOpCode & EXC_CHTR_OP_DELFLAG )
+ DoDeleteRange( aRange );
+ else
+ DoInsertRange( aRange );
+ }
+ }
+}
+
+void XclImpChangeTrack::ReadChTrInfo()
+{
+ pStrm->DisableDecryption();
+ pStrm->Ignore( 32 );
+ String sUsername( pStrm->ReadUniString() );
+ if( !pStrm->IsValid() ) return;
+
+ if( sUsername.Len() )
+ pChangeTrack->SetUser( sUsername );
+ pStrm->Seek( 148 );
+ if( !pStrm->IsValid() ) return;
+
+ DateTime aDateTime;
+ ReadDateTime( aDateTime );
+ if( pStrm->IsValid() )
+ pChangeTrack->SetFixDateTimeLocal( aDateTime );
+}
+
+void XclImpChangeTrack::ReadChTrCellContent()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_CELL ) )
+ {
+ ScAddress aPosition;
+ SCTAB nTab = ReadTabNum();
+ aPosition.SetTab( nTab );
+ sal_uInt16 nValueType;
+ *pStrm >> nValueType;
+ sal_uInt16 nOldValueType = (nValueType >> 3) & EXC_CHTR_TYPE_MASK;
+ sal_uInt16 nNewValueType = nValueType & EXC_CHTR_TYPE_MASK;
+ pStrm->Ignore( 2 );
+ Read2DAddress( aPosition );
+ sal_uInt16 nOldSize;
+ *pStrm >> nOldSize;
+ DBG_ASSERT( (nOldSize == 0) == (nOldValueType == EXC_CHTR_TYPE_EMPTY),
+ "XclImpChangeTrack::ReadChTrCellContent - old value mismatch" );
+ pStrm->Ignore( 4 );
+ switch( nValueType & EXC_CHTR_TYPE_FORMATMASK )
+ {
+ case 0x0000: break;
+ case 0x1100: pStrm->Ignore( 16 ); break;
+ case 0x1300: pStrm->Ignore( 8 ); break;
+ default: DBG_ERROR( "XclImpChangeTrack::ReadChTrCellContent - unknown format info" );
+ }
+
+ ScBaseCell* pOldCell;
+ ScBaseCell* pNewCell;
+ sal_uInt32 nOldFormat;
+ sal_uInt32 nNewFormat;
+ ReadCell( pOldCell, nOldFormat, nOldValueType, aPosition );
+ ReadCell( pNewCell, nNewFormat, nNewValueType, aPosition );
+ if( !pStrm->IsValid() || (pStrm->GetRecLeft() > 0) )
+ {
+ DBG_ERROR( "XclImpChangeTrack::ReadChTrCellContent - bytes left, action ignored" );
+ if( pOldCell )
+ pOldCell->Delete();
+ if( pNewCell )
+ pNewCell->Delete();
+ }
+ else
+ {
+ ScChangeActionContent* pNewAction =
+ pChangeTrack->AppendContentOnTheFly( aPosition, pOldCell, pNewCell, nOldFormat, nNewFormat );
+ DoAcceptRejectAction( pNewAction );
+ }
+ }
+}
+
+void XclImpChangeTrack::ReadChTrTabId()
+{
+ if( nTabIdCount == 0 ) // read only 1st time, otherwise calculated by <ReadChTrInsertTab()>
+ nTabIdCount = static_cast< sal_uInt16 >( pStrm->GetRecLeft() >> 1 );
+}
+
+void XclImpChangeTrack::ReadChTrMoveRange()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_MOVE ) )
+ {
+ ScRange aSourceRange;
+ ScRange aDestRange;
+ aDestRange.aStart.SetTab( ReadTabNum() );
+ aDestRange.aEnd.SetTab( aDestRange.aStart.Tab() );
+ Read2DRange( aSourceRange );
+ Read2DRange( aDestRange );
+ aSourceRange.aStart.SetTab( ReadTabNum() );
+ aSourceRange.aEnd.SetTab( aSourceRange.aStart.Tab() );
+
+ BOOL bValid = pStrm->IsValid();
+ if( FoundNestedMode() )
+ ReadNestedRecords();
+
+ if( bValid )
+ {
+ pChangeTrack->AppendMove( aSourceRange, aDestRange, NULL );
+ DoAcceptRejectAction( pChangeTrack->GetLast() );
+ }
+ }
+}
+
+void XclImpChangeTrack::ReadChTrInsertTab()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_INSTAB ) )
+ {
+ SCTAB nTab = ReadTabNum();
+ if( pStrm->IsValid() )
+ {
+ nTabIdCount++;
+ DoInsertRange( ScRange( 0, 0, nTab, MAXCOL, MAXROW, nTab ) );
+ }
+ }
+}
+
+void XclImpChangeTrack::InitNestedMode()
+{
+ DBG_ASSERT( eNestedMode == nmBase, "XclImpChangeTrack::InitNestedMode - unexpected nested mode" );
+ if( eNestedMode == nmBase )
+ eNestedMode = nmFound;
+}
+
+void XclImpChangeTrack::ReadNestedRecords()
+{
+ DBG_ASSERT( eNestedMode == nmFound, "XclImpChangeTrack::StartNestedMode - missing nested mode" );
+ if( eNestedMode == nmFound )
+ {
+ eNestedMode = nmNested;
+ ReadRecords();
+ }
+}
+
+sal_Bool XclImpChangeTrack::EndNestedMode()
+{
+ DBG_ASSERT( eNestedMode != nmBase, "XclImpChangeTrack::EndNestedMode - missing nested mode" );
+ sal_Bool bReturn = (eNestedMode == nmNested);
+ eNestedMode = nmBase;
+ return bReturn;
+}
+
+void XclImpChangeTrack::ReadRecords()
+{
+ sal_Bool bExitLoop = sal_False;
+
+ while( !bExitLoop && !bGlobExit && pStrm->StartNextRecord() )
+ {
+ switch( pStrm->GetRecId() )
+ {
+ case 0x000A: bGlobExit = sal_True; break;
+ case 0x0137: ReadChTrInsert(); break;
+ case 0x0138: ReadChTrInfo(); break;
+ case 0x013B: ReadChTrCellContent(); break;
+ case 0x013D: ReadChTrTabId(); break;
+ case 0x0140: ReadChTrMoveRange(); break;
+ case 0x014D: ReadChTrInsertTab(); break;
+ case 0x014E:
+ case 0x0150: InitNestedMode(); break;
+ case 0x014F:
+ case 0x0151: bExitLoop = EndNestedMode(); break;
+ }
+ }
+}
+
+void XclImpChangeTrack::Apply()
+{
+ if( pChangeTrack )
+ {
+ pChangeTrack->SetUser( sOldUsername );
+ pChangeTrack->SetUseFixDateTime( FALSE );
+
+ GetDoc().SetChangeTrack( pChangeTrack );
+ pChangeTrack = NULL;
+
+ ScChangeViewSettings aSettings;
+ aSettings.SetShowChanges( TRUE );
+ GetDoc().SetChangeViewSettings( aSettings );
+ }
+}
+
+//___________________________________________________________________
+// class XclImpChTrFmlConverter
+
+XclImpChTrFmlConverter::~XclImpChTrFmlConverter()
+{
+}
+
+// virtual, called from ExcToSc8::Convert()
+bool XclImpChTrFmlConverter::Read3DTabReference( UINT16 /*nIxti*/, SCTAB& rFirstTab, SCTAB& rLastTab,
+ ExternalTabInfo& rExtInfo )
+{
+ return rChangeTrack.Read3DTabRefInfo( rFirstTab, rLastTab, rExtInfo );
+}
+
diff --git a/sc/source/filter/xcl97/makefile.mk b/sc/source/filter/xcl97/makefile.mk
new file mode 100644
index 000000000000..3ce71ba142df
--- /dev/null
+++ b/sc/source/filter/xcl97/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=xcl97
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/xcl97esc.obj \
+ $(SLO)$/xcl97rec.obj \
+ $(SLO)$/XclImpChangeTrack.obj \
+ $(SLO)$/XclExpChangeTrack.obj
+
+EXCEPTIONSFILES = \
+ $(SLO)$/xcl97esc.obj \
+ $(SLO)$/xcl97rec.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/xcl97/xcl97dum.cxx b/sc/source/filter/xcl97/xcl97dum.cxx
new file mode 100644
index 000000000000..1550fa97ed40
--- /dev/null
+++ b/sc/source/filter/xcl97/xcl97dum.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "xcl97dum.hxx"
+
+
+// --- ExcDummy8_xx Data ---------------------------------------------
+
+// ... (8+) := neu in Biff8, ... (8*) := anders in Biff8
+
+const BYTE ExcDummy8_00a::pMyData[] = {
+ 0xe1, 0x00, 0x02, 0x00, 0xb0, 0x04, // INTERFACEHDR
+ 0xc1, 0x00, 0x02, 0x00, 0x00, 0x00, // MMS
+ 0xe2, 0x00, 0x00, 0x00, // INTERFACEEND
+ 0x5c, 0x00, 0x70, 0x00, // WRITEACCESS (8*)
+ 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20, // "Calc"
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x42, 0x00, 0x02, 0x00, 0xb0, 0x04, // CODEPAGE
+ 0x61, 0x01, 0x02, 0x00, 0x00, 0x00 // DSF (8+)
+};
+const sal_Size ExcDummy8_00a::nMyLen = sizeof(ExcDummy8_00a::pMyData);
+
+ // TABID (8+): ExcTabid
+
+const BYTE ExcDummy8_00b::pMyData[] = {
+ 0x9c, 0x00, 0x02, 0x00, 0x0e, 0x00 // FNGROUPCOUNT
+};
+const sal_Size ExcDummy8_00b::nMyLen = sizeof(ExcDummy8_00b::pMyData);
+
+
+const BYTE ExcDummy8_040::pMyData[] = {
+ 0xaf, 0x01, 0x02, 0x00, 0x00, 0x00, // PROT4REV (8+)
+ 0xbc, 0x01, 0x02, 0x00, 0x00, 0x00, // PROT4REVPASS (8+)
+// 0x3d, 0x00, 0x12, 0x00, 0xe0, 0x01, 0x5a, 0x00, 0xcf, // WINDOW1
+// 0x3f, 0x4e, 0x2a, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+// 0x01, 0x00, 0x58, 0x02,
+ 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, // BACKUP
+ 0x8d, 0x00, 0x02, 0x00, 0x00, 0x00 // HIDEOBJ
+};
+const sal_Size ExcDummy8_040::nMyLen = sizeof(ExcDummy8_040::pMyData);
+
+
+const BYTE ExcDummy8_041::pMyData[] = {
+ 0xb7, 0x01, 0x02, 0x00, 0x00, 0x00, // REFRESHALL (8+)
+ 0xda, 0x00, 0x02, 0x00, 0x00, 0x00 // BOOKBOOL
+};
+const sal_Size ExcDummy8_041::nMyLen = sizeof(ExcDummy8_041::pMyData);
+
+
+
+const BYTE ExcDummy8_02::pMyData[] = {
+ 0x5f, 0x00, 0x02, 0x00, 0x01, 0x00 // SAVERECALC
+ };
+const sal_Size ExcDummy8_02::nMyLen = sizeof(ExcDummy8_02::pMyData);
+
+
+// --- class ExcDummy8_xx --------------------------------------------
+
+sal_Size ExcDummy8_00a::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy8_00a::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_00b::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy8_00b::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_040::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy8_040::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_041::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy8_041::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_02::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const BYTE* ExcDummy8_02::GetData() const
+{
+ return pMyData;
+}
+
diff --git a/sc/source/filter/xcl97/xcl97esc.cxx b/sc/source/filter/xcl97/xcl97esc.cxx
new file mode 100644
index 000000000000..a7c6dee67dc5
--- /dev/null
+++ b/sc/source/filter/xcl97/xcl97esc.cxx
@@ -0,0 +1,512 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/embed/XClassifiedObject.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+
+#include <svx/svdpage.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/fmglob.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <vcl/outdev.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/debug.hxx>
+#include <svx/sdasitm.hxx>
+
+#include <sot/exchange.hxx>
+#include "xeescher.hxx"
+
+#include "global.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "xcl97rec.hxx"
+#include "xehelper.hxx"
+#include "xechart.hxx"
+#include "xcl97esc.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::embed::XClassifiedObject;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::form::XFormsSupplier;
+using ::com::sun::star::script::ScriptEventDescriptor;
+using ::com::sun::star::script::XEventAttacherManager;
+
+// ============================================================================
+
+XclEscherExGlobal::XclEscherExGlobal( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+SvStream* XclEscherExGlobal::ImplQueryPictureStream()
+{
+ mxPicTempFile.reset( new ::utl::TempFile );
+ if( mxPicTempFile->IsValid() )
+ {
+ mxPicTempFile->EnableKillingFile();
+ mxPicStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxPicTempFile->GetURL(), STREAM_STD_READWRITE ) );
+ mxPicStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ }
+ return mxPicStrm.get();
+}
+
+// ============================================================================
+
+XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, XclExpObjectManager& rObjMgr, SvStream& rStrm, const XclEscherEx* pParent ) :
+ EscherEx( pParent ? pParent->mxGlobal : EscherExGlobalRef( new XclEscherExGlobal( rRoot ) ), rStrm ),
+ XclExpRoot( rRoot ),
+ mrObjMgr( rObjMgr ),
+ pCurrXclObj( NULL ),
+ pCurrAppData( NULL ),
+ pTheClientData( new XclEscherClientData ),
+ pAdditionalText( NULL ),
+ nAdditionalText( 0 ),
+ mnNextKey( 0 ),
+ mbIsRootDff( pParent == 0 )
+{
+ InsertPersistOffset( mnNextKey, 0 );
+}
+
+
+XclEscherEx::~XclEscherEx()
+{
+ DBG_ASSERT( !aStack.Count(), "~XclEscherEx: stack not empty" );
+ DeleteCurrAppData();
+ delete pTheClientData;
+}
+
+
+sal_uInt32 XclEscherEx::InitNextDffFragment()
+{
+ /* Current value of mnNextKey will be used by caller to refer to the
+ starting point of the DFF fragment. The key exists already in the
+ PersistTable (has been inserted by c'tor of previous call of
+ InitNextDffFragment(), has been updated by UpdateDffFragmentEnd(). */
+ sal_uInt32 nPersistKey = mnNextKey;
+
+ /* Prepare the next key that is used by caller as end point of the DFF
+ fragment. Will be updated by caller when writing to the DFF stream,
+ using the UpdateDffFragmentEnd() function. This is needed to find DFF
+ data written by the SVX base class implementation without interaction,
+ e.g. the solver container that will be written after the last shape. */
+ ++mnNextKey;
+ InsertPersistOffset( mnNextKey, mpOutStrm->Tell() );
+
+ return nPersistKey;
+}
+
+void XclEscherEx::UpdateDffFragmentEnd()
+{
+ // update existing fragment key with new stream position
+ ReplacePersistOffset( mnNextKey, mpOutStrm->Tell() );
+}
+
+sal_uInt32 XclEscherEx::GetDffFragmentPos( sal_uInt32 nFragmentKey )
+{
+ /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
+ is non-const due to tools/List usage. */
+ return GetPersistOffset( nFragmentKey );
+}
+
+sal_uInt32 XclEscherEx::GetDffFragmentSize( sal_uInt32 nFragmentKey )
+{
+ /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
+ is non-const due to tools/List usage. */
+ return GetDffFragmentPos( nFragmentKey + 1 ) - GetDffFragmentPos( nFragmentKey );
+}
+
+bool XclEscherEx::HasPendingDffData()
+{
+ /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
+ is non-const due to tools/List usage. */
+ return GetDffFragmentPos( mnNextKey ) < GetStreamPos();
+}
+
+XclExpDffAnchorBase* XclEscherEx::CreateDffAnchor( const SdrObject& rSdrObj ) const
+{
+ // the object manager creates the correct anchor type according to context
+ XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor();
+ // pass the drawing object, that will calculate the anchor position
+ pAnchor->SetSdrObject( rSdrObj );
+ return pAnchor;
+}
+
+namespace {
+
+bool lcl_IsFontwork( const SdrObject* pObj )
+{
+ bool bIsFontwork = false;
+ if( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE )
+ {
+ const OUString aTextPath = CREATE_OUSTRING( "TextPath" );
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)
+ pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ if( Any* pAny = rGeometryItem.GetPropertyValueByName( aTextPath, aTextPath ) )
+ *pAny >>= bIsFontwork;
+ }
+ return bIsFontwork;
+}
+
+} // namespace
+
+EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape, const Rectangle* pChildAnchor )
+{
+ if ( nAdditionalText )
+ nAdditionalText++;
+ BOOL bInGroup = ( pCurrXclObj != NULL );
+ if ( bInGroup )
+ { // stacked recursive group object
+ if ( !pCurrAppData->IsStackedGroup() )
+ { //! UpdateDffFragmentEnd only once
+ pCurrAppData->SetStackedGroup( TRUE );
+ UpdateDffFragmentEnd();
+ }
+ }
+ aStack.Push( pCurrXclObj );
+ aStack.Push( pCurrAppData );
+ pCurrAppData = new XclEscherHostAppData;
+ SdrObject* pObj = GetSdrObjectFromXShape( rxShape );
+ if ( !pObj )
+ pCurrXclObj = new XclObjAny( mrObjMgr ); // just what is it?!?
+ else
+ {
+ pCurrXclObj = NULL;
+ sal_uInt16 nObjType = pObj->GetObjIdentifier();
+
+ if( nObjType == OBJ_OLE2 )
+ {
+ // no OLE objects in embedded drawings (chart shapes)
+ if( mbIsRootDff )
+ {
+ //! not-const because GetObjRef may load the OLE object
+ Reference < XClassifiedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), UNO_QUERY );
+ if ( xObj.is() )
+ {
+ SvGlobalName aObjClsId( xObj->getClassID() );
+ if ( SotExchange::IsChart( aObjClsId ) )
+ { // yes, it's a chart diagram
+ mrObjMgr.AddObj( new XclExpChartObj( mrObjMgr, rxShape, pChildAnchor ) );
+ pCurrXclObj = NULL; // no metafile or whatsoever
+ }
+ else // metafile and OLE object
+ pCurrXclObj = new XclObjOle( mrObjMgr, *pObj );
+ }
+ else // just a metafile
+ pCurrXclObj = new XclObjAny( mrObjMgr );
+ }
+ else
+ pCurrXclObj = new XclObjAny( mrObjMgr );
+ }
+ else if( nObjType == OBJ_UNO )
+ {
+#if EXC_EXP_OCX_CTRL
+ // no ActiveX controls in embedded drawings (chart shapes)
+ if( mbIsRootDff )
+ pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor );
+#else
+ pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor );
+#endif
+ if( !pCurrXclObj )
+ pCurrXclObj = new XclObjAny( mrObjMgr ); // just a metafile
+ }
+ else if( !ScDrawLayer::IsNoteCaption( pObj ) )
+ {
+ // #107540# ignore permanent note shapes
+ // #i12190# do not ignore callouts (do not filter by object type ID)
+ pCurrXclObj = new XclObjAny( mrObjMgr ); // just a metafile
+ }
+ }
+ if ( pCurrXclObj )
+ {
+ if ( !mrObjMgr.AddObj( pCurrXclObj ) )
+ { // maximum count reached, object got deleted
+ pCurrXclObj = NULL;
+ }
+ else
+ {
+ pCurrAppData->SetClientData( pTheClientData );
+ if ( nAdditionalText == 0 )
+ {
+ if ( pObj )
+ {
+ if ( !bInGroup )
+ {
+ /* Create a dummy anchor carrying the flags. Real
+ coordinates are calculated later in virtual call of
+ WriteData(EscherEx&,const Rectangle&). */
+ XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor();
+ pAnchor->SetFlags( *pObj );
+ pCurrAppData->SetClientAnchor( pAnchor );
+ }
+ const SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pObj );
+ if( pTextObj && !lcl_IsFontwork( pTextObj ) && (pObj->GetObjIdentifier() != OBJ_CAPTION) )
+ {
+ const OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
+ if( pParaObj )
+ pCurrAppData->SetClientTextbox(
+ new XclEscherClientTextbox( GetRoot(), *pTextObj, pCurrXclObj ) );
+ }
+ }
+ else
+ {
+ if ( !bInGroup )
+ pCurrAppData->SetClientAnchor( mrObjMgr.CreateDffAnchor() );
+ }
+ }
+ else if ( nAdditionalText == 3 )
+ {
+ if ( pAdditionalText )
+ {
+ pAdditionalText->SetXclObj( pCurrXclObj );
+ pCurrAppData->SetClientTextbox( pAdditionalText );
+ }
+ }
+ }
+ }
+ if ( !pCurrXclObj )
+ pCurrAppData->SetDontWriteShape( TRUE );
+ return pCurrAppData;
+}
+
+
+void XclEscherEx::EndShape( UINT16 nShapeType, UINT32 nShapeID )
+{
+ // own escher data created? -> never delete such objects
+ bool bOwnEscher = pCurrXclObj && pCurrXclObj->IsOwnEscher();
+
+ // post process the current object - not for objects with own escher data
+ if( pCurrXclObj && !bOwnEscher )
+ {
+ // escher data of last shape not written? -> delete it from object list
+ if( nShapeID == 0 )
+ {
+ XclObj* pLastObj = mrObjMgr.RemoveLastObj();
+ DBG_ASSERT( pLastObj == pCurrXclObj, "XclEscherEx::EndShape - wrong object" );
+ DELETEZ( pLastObj );
+ pCurrXclObj = 0;
+ }
+
+ if( pCurrXclObj )
+ {
+ // set shape type
+ if ( pCurrAppData->IsStackedGroup() )
+ pCurrXclObj->SetEscherShapeTypeGroup();
+ else
+ {
+ pCurrXclObj->SetEscherShapeType( nShapeType );
+ UpdateDffFragmentEnd();
+ }
+ }
+ }
+
+ // get next object from stack
+ DeleteCurrAppData();
+ pCurrAppData = static_cast< XclEscherHostAppData* >( aStack.Pop() );
+ pCurrXclObj = static_cast< XclObj* >( aStack.Pop() );
+ if( nAdditionalText == 3 )
+ nAdditionalText = 0;
+}
+
+
+EscherExHostAppData* XclEscherEx::EnterAdditionalTextGroup()
+{
+ nAdditionalText = 1;
+ pAdditionalText = (XclEscherClientTextbox*) pCurrAppData->GetClientTextbox();
+ pCurrAppData->SetClientTextbox( NULL );
+ return pCurrAppData;
+}
+
+
+void XclEscherEx::EndDocument()
+{
+ if( mbIsRootDff )
+ Flush( static_cast< XclEscherExGlobal& >( *mxGlobal ).GetPictureStream() );
+
+ // seek back DFF stream to prepare saving the MSODRAWING[GROUP] records
+ mpOutStrm->Seek( 0 );
+}
+
+#if EXC_EXP_OCX_CTRL
+
+XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor )
+{
+ ::std::auto_ptr< XclExpOcxControlObj > xOcxCtrl;
+
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
+ if( xCtrlModel.is() )
+ {
+ // output stream
+ if( !mxCtlsStrm.Is() )
+ mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
+ if( mxCtlsStrm.Is() )
+ {
+ String aClassName;
+ sal_uInt32 nStrmStart = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() );
+
+ // writes from xCtrlModel into mxCtlsStrm, raw class name returned in aClassName
+ if( SvxMSConvertOCXControls::WriteOCXExcelKludgeStream( mxCtlsStrm, xCtrlModel, xShape->getSize(), aClassName ) )
+ {
+ sal_uInt32 nStrmSize = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() - nStrmStart );
+ // adjust the class name to "Forms.***.1"
+ aClassName.InsertAscii( "Forms.", 0 ).AppendAscii( ".1" );
+ xOcxCtrl.reset( new XclExpOcxControlObj( mrObjMgr, xShape, pChildAnchor, aClassName, nStrmStart, nStrmSize ) );
+ }
+ }
+ }
+ return xOcxCtrl.release();
+}
+
+#else
+
+XclExpTbxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor )
+{
+ ::std::auto_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( mrObjMgr, xShape, pChildAnchor ) );
+ if( xTbxCtrl->GetObjType() == EXC_OBJTYPE_UNKNOWN )
+ xTbxCtrl.reset();
+
+ if( xTbxCtrl.get() )
+ {
+ // find attached macro
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
+ ConvertTbxMacro( *xTbxCtrl, xCtrlModel );
+ }
+ return xTbxCtrl.release();
+}
+
+void XclEscherEx::ConvertTbxMacro( XclExpTbxControlObj& rTbxCtrlObj, Reference< XControlModel > xCtrlModel )
+{
+ SdrPage* pSdrPage = GetSdrPage( GetCurrScTab() );
+ if( xCtrlModel.is() && GetDocShell() && pSdrPage ) try
+ {
+ Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xFormsIA( xFormsSupplier->getForms(), UNO_QUERY_THROW );
+
+ // 1) try to find the index of the processed control in the form
+
+ Reference< XIndexAccess > xFormIA; // needed in step 2) below
+ sal_Int32 nFoundIdx = -1;
+
+ // search all existing forms in the draw page
+ for( sal_Int32 nFormIdx = 0, nFormCount = xFormsIA->getCount();
+ (nFoundIdx < 0) && (nFormIdx < nFormCount); ++nFormIdx )
+ {
+ // get the XIndexAccess interface of the form with index nFormIdx
+ if( xFormIA.set( xFormsIA->getByIndex( nFormIdx ), UNO_QUERY ) )
+ {
+ // search all elements (controls) of the current form by index
+ for( sal_Int32 nCtrlIdx = 0, nCtrlCount = xFormIA->getCount();
+ (nFoundIdx < 0) && (nCtrlIdx < nCtrlCount); ++nCtrlIdx )
+ {
+ // compare implementation pointers of the control models
+ Reference< XControlModel > xCurrModel( xFormIA->getByIndex( nCtrlIdx ), UNO_QUERY );
+ if( xCtrlModel.get() == xCurrModel.get() )
+ nFoundIdx = nCtrlIdx;
+ }
+ }
+ }
+
+ // 2) try to find an attached macro
+
+ if( xFormIA.is() && (nFoundIdx >= 0) )
+ {
+ Reference< XEventAttacherManager > xEventMgr( xFormIA, UNO_QUERY_THROW );
+ // loop over all events attached to the found control
+ const Sequence< ScriptEventDescriptor > aEventSeq( xEventMgr->getScriptEvents( nFoundIdx ) );
+ bool bFound = false;
+ for( sal_Int32 nEventIdx = 0, nEventCount = aEventSeq.getLength();
+ !bFound && (nEventIdx < nEventCount); ++nEventIdx )
+ {
+ // try to set the event data at the Excel control object, returns true on success
+ bFound = rTbxCtrlObj.SetMacroLink( aEventSeq[ nEventIdx ] );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+#endif
+
+void XclEscherEx::DeleteCurrAppData()
+{
+ if ( pCurrAppData )
+ {
+ delete pCurrAppData->GetClientAnchor();
+// delete pCurrAppData->GetClientData();
+ delete pCurrAppData->GetClientTextbox();
+ delete pCurrAppData;
+ }
+}
+
+// ============================================================================
+
+// --- class XclEscherClientData -------------------------------------
+
+void XclEscherClientData::WriteData( EscherEx& rEx ) const
+{ // actual data is in the following OBJ record
+ rEx.AddAtom( 0, ESCHER_ClientData );
+}
+
+
+// --- class XclEscherClientTextbox -------------------------------------
+
+XclEscherClientTextbox::XclEscherClientTextbox( const XclExpRoot& rRoot,
+ const SdrTextObj& rObj, XclObj* pObj )
+ :
+ XclExpRoot( rRoot ),
+ rTextObj( rObj ),
+ pXclObj( pObj )
+{
+}
+
+
+void XclEscherClientTextbox::WriteData( EscherEx& /*rEx*/ ) const
+{
+ pXclObj->SetText( GetRoot(), rTextObj );
+}
+
+
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
new file mode 100644
index 000000000000..df6bdcbbe671
--- /dev/null
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -0,0 +1,1448 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svdpool.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/editobj.hxx>
+#include <svx/svdoole2.hxx>
+#include <sot/storage.hxx>
+#include <svl/itemset.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/unoapi.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/math.hxx>
+#include <svl/zformat.hxx>
+#include "cell.hxx"
+#include "drwlayer.hxx"
+
+#include "xcl97rec.hxx"
+#include "xcl97esc.hxx"
+#include "editutil.hxx"
+#include "xecontent.hxx"
+#include "xeescher.hxx"
+#include "xestyle.hxx"
+#include "xelink.hxx"
+
+#include "scitems.hxx"
+
+#include <unotools/fltrcfg.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <filter/msfilter/msoleexp.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+
+#include <stdio.h>
+
+#include "document.hxx"
+#include "conditio.hxx"
+#include "rangelst.hxx"
+#include "stlpool.hxx"
+#include "viewopti.hxx"
+#include "scextopt.hxx"
+#include "docoptio.hxx"
+#include "patattr.hxx"
+#include "tabprotection.hxx"
+
+#include <oox/core/tokens.hxx>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::drawing::XShape;
+
+// ============================================================================
+
+XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) :
+ XclExpRoot( rRoot ),
+ mrEscherEx( rEscherEx ),
+ pSolverContainer( 0 )
+{
+ pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx );
+ // open the DGCONTAINER and the patriarch group shape
+ mrEscherEx.OpenContainer( ESCHER_DgContainer );
+ Rectangle aRect( 0, 0, 0, 0 );
+ mrEscherEx.EnterGroup( &aRect );
+ mrEscherEx.UpdateDffFragmentEnd();
+}
+
+XclExpObjList::~XclExpObjList()
+{
+ for ( XclObj* p = First(); p; p = Next() )
+ delete p;
+ delete pMsodrawingPerSheet;
+ delete pSolverContainer;
+}
+
+UINT16 XclExpObjList::Add( XclObj* pObj )
+{
+ DBG_ASSERT( Count() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" );
+ if ( Count() < 0xFFFF )
+ {
+ Insert( pObj, LIST_APPEND );
+ UINT16 nCnt = (UINT16) Count();
+ pObj->SetId( nCnt );
+ return nCnt;
+ }
+ else
+ {
+ delete pObj;
+ return 0;
+ }
+}
+
+void XclExpObjList::EndSheet()
+{
+ // Is there still something in the stream? -> The solver container
+ if( mrEscherEx.HasPendingDffData() )
+ pSolverContainer = new XclExpMsoDrawing( mrEscherEx );
+
+ // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING
+ mrEscherEx.CloseContainer();
+}
+
+void XclExpObjList::Save( XclExpStream& rStrm )
+{
+ //! Escher must be written, even if there are no objects
+ pMsodrawingPerSheet->Save( rStrm );
+
+ for ( XclObj* p = First(); p; p = Next() )
+ p->Save( rStrm );
+
+ if( pSolverContainer )
+ pSolverContainer->Save( rStrm );
+}
+
+// --- class XclObj --------------------------------------------------
+
+XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) :
+ XclExpRecord( EXC_ID_OBJ, 26 ),
+ mrEscherEx( rObjMgr.GetEscherEx() ),
+ pClientTextbox( NULL ),
+ pTxo( NULL ),
+ mnObjType( nObjType ),
+ nObjId(0),
+ nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked
+ bFirstOnSheet( !rObjMgr.HasObj() ),
+ mbOwnEscher( bOwnEscher )
+{
+ //! first object continues the first MSODRAWING record
+ if ( bFirstOnSheet )
+ pMsodrawing = rObjMgr.GetMsodrawingPerSheet();
+ else
+ pMsodrawing = new XclExpMsoDrawing( mrEscherEx );
+}
+
+XclObj::~XclObj()
+{
+ if ( !bFirstOnSheet )
+ delete pMsodrawing;
+ delete pClientTextbox;
+ delete pTxo;
+}
+
+void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor )
+{
+ if( pChildAnchor )
+ {
+ mrEscherEx.AddChildAnchor( *pChildAnchor );
+ }
+ else if( pSdrObj )
+ {
+ ::std::auto_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) );
+ xDffAnchor->WriteDffData( mrEscherEx );
+ }
+}
+
+void XclObj::SetEscherShapeType( UINT16 nType )
+{
+//2do: what about the other defined ot... types?
+ switch ( nType )
+ {
+ case ESCHER_ShpInst_Line :
+ mnObjType = EXC_OBJTYPE_LINE;
+ break;
+ case ESCHER_ShpInst_Rectangle :
+ case ESCHER_ShpInst_RoundRectangle :
+ mnObjType = EXC_OBJTYPE_RECTANGLE;
+ break;
+ case ESCHER_ShpInst_Ellipse :
+ mnObjType = EXC_OBJTYPE_OVAL;
+ break;
+ case ESCHER_ShpInst_Arc :
+ mnObjType = EXC_OBJTYPE_ARC;
+ break;
+ case ESCHER_ShpInst_TextBox :
+ mnObjType = EXC_OBJTYPE_TEXT;
+ break;
+ case ESCHER_ShpInst_PictureFrame :
+ mnObjType = EXC_OBJTYPE_PICTURE;
+ break;
+ default:
+ mnObjType = EXC_OBJTYPE_DRAWING;
+ }
+}
+
+void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj )
+{
+ DBG_ASSERT( !pClientTextbox, "XclObj::SetText: already set" );
+ if ( !pClientTextbox )
+ {
+ mrEscherEx.UpdateDffFragmentEnd();
+ pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
+ mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
+ mrEscherEx.UpdateDffFragmentEnd();
+ pTxo = new XclTxo( rRoot, rObj );
+ }
+}
+
+void XclObj::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" );
+
+ // create a substream to be able to create subrecords
+ SvMemoryStream aMemStrm;
+ ::std::auto_ptr< XclExpStream > pXclStrm( new XclExpStream( aMemStrm, rStrm.GetRoot() ) );
+
+ // write the ftCmo subrecord
+ pXclStrm->StartRecord( EXC_ID_OBJCMO, 18 );
+ *pXclStrm << mnObjType << nObjId << nGrbit;
+ pXclStrm->WriteZeroBytes( 12 );
+ pXclStrm->EndRecord();
+
+ // write other subrecords
+ WriteSubRecs( *pXclStrm );
+
+ // write the ftEnd subrecord
+ pXclStrm->StartRecord( EXC_ID_OBJEND, 0 );
+ pXclStrm->EndRecord();
+
+ // copy the data to the OBJ record
+ pXclStrm.reset();
+ aMemStrm.Seek( 0 );
+ rStrm.CopyFromStream( aMemStrm );
+}
+
+void XclObj::Save( XclExpStream& rStrm )
+{
+ // MSODRAWING record (msofbtSpContainer)
+ if ( !bFirstOnSheet )
+ pMsodrawing->Save( rStrm );
+
+ // OBJ
+ XclExpRecord::Save( rStrm );
+
+ // second MSODRAWING record and TXO and CONTINUE records
+ SaveTextRecs( rStrm );
+}
+
+void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ )
+{
+}
+
+void XclObj::SaveTextRecs( XclExpStream& rStrm )
+{
+ // MSODRAWING record (msofbtClientTextbox)
+ if ( pClientTextbox )
+ pClientTextbox->Save( rStrm );
+ // TXO and CONTINUE records
+ if ( pTxo )
+ pTxo->Save( rStrm );
+}
+
+// --- class XclObjComment -------------------------------------------
+
+XclObjComment::XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_NOTE, true )
+{
+ ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible);
+ // TXO
+ pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption );
+}
+
+void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible )
+{
+ Reference<XShape> aXShape;
+ EscherPropertyContainer aPropOpt;
+
+ if(pCaption)
+ {
+ aXShape = GetXShapeForSdrObject(pCaption);
+ Reference< XPropertySet > aXPropSet( aXShape, UNO_QUERY );
+ if( aXPropSet.is() )
+ {
+ aPropOpt.CreateFillProperties( aXPropSet, sal_True);
+
+ aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // undocumented
+ aPropOpt.AddOpt( 0x0158, 0x00000000 ); // undocumented
+
+ sal_uInt32 nValue = 0;
+ if(!aPropOpt.GetOpt( ESCHER_Prop_FitTextToShape, nValue ))
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
+
+ if(aPropOpt.GetOpt( ESCHER_Prop_fillColor, nValue ))
+ {
+ // If the Colour is the same as the 'ToolTip' System colour then
+ // use the default rather than the explicit colour value. This will
+ // be incorrect where user has chosen to use this colour explicity.
+ Color aColor = Color( (BYTE)nValue, (BYTE)( nValue >> 8 ), (BYTE)( nValue >> 16 ) );
+ const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
+ if(aColor == rSett.GetHelpColor().GetColor())
+ {
+ aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
+ aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
+ }
+ }
+ else
+ aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
+
+ if(!aPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nValue ))
+ aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
+ if(!aPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ))
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 ); // bool field
+ if(!aPropOpt.GetOpt( ESCHER_Prop_shadowColor, nValue ))
+ aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x00000000 );
+ if(!aPropOpt.GetOpt( ESCHER_Prop_fshadowObscured, nValue )) // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // bool field
+ }
+ }
+
+ nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ sal_uInt32 nFlags = 0x000A0000;
+ ::set_flag( nFlags, sal_uInt32(2), !bVisible );
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the
+ //! base OBJ's MSODRAWING record Escher data is completed.
+ pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
+ mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
+ mrEscherEx.UpdateDffFragmentEnd();
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+}
+
+XclObjComment::~XclObjComment()
+{
+}
+
+void XclObjComment::Save( XclExpStream& rStrm )
+{
+ // content of this record
+ XclObj::Save( rStrm );
+}
+
+// --- class XclObjDropDown ------------------------------------------
+
+XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ),
+ bIsFiltered( bFilt )
+{
+ SetLocked( TRUE );
+ SetPrintable( FALSE );
+ SetAutoFill( TRUE );
+ SetAutoLine( FALSE );
+ nGrbit |= 0x0100; // undocumented
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ EscherPropertyContainer aPropOpt;
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.UpdateDffFragmentEnd();
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+
+ // old size + ftSbs + ftLbsData
+ AddRecSize( 24 + 20 );
+}
+
+XclObjDropDown::~XclObjDropDown()
+{
+}
+
+void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm )
+{
+ // ftSbs subrecord - Scroll bars (dummy)
+ rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
+ rStrm.WriteZeroBytes( 20 );
+ rStrm.EndRecord();
+
+ // ftLbsData subrecord - Listbox data
+ sal_uInt16 nDropDownFlags = 0;
+ ::insert_value( nDropDownFlags, EXC_OBJ_DROPDOWN_SIMPLE, 0, 2 );
+ ::set_flag( nDropDownFlags, EXC_OBJ_DROPDOWN_FILTERED, bIsFiltered );
+ rStrm.StartRecord( EXC_ID_OBJLBSDATA, 16 );
+ rStrm << (UINT32)0 << (UINT16)0 << (UINT16)0x0301 << (UINT16)0
+ << nDropDownFlags << sal_uInt16( 20 ) << sal_uInt16( 130 );
+ rStrm.EndRecord();
+}
+
+// --- class XclTxo --------------------------------------------------
+
+sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet )
+{
+ sal_uInt8 nHorAlign = EXC_OBJ_HOR_LEFT;
+
+ switch( static_cast< const SvxAdjustItem& >( rItemSet.Get( EE_PARA_JUST ) ).GetAdjust() )
+ {
+ case SVX_ADJUST_LEFT: nHorAlign = EXC_OBJ_HOR_LEFT; break;
+ case SVX_ADJUST_CENTER: nHorAlign = EXC_OBJ_HOR_CENTER; break;
+ case SVX_ADJUST_RIGHT: nHorAlign = EXC_OBJ_HOR_RIGHT; break;
+ case SVX_ADJUST_BLOCK: nHorAlign = EXC_OBJ_HOR_JUSTIFY; break;
+ default:;
+ }
+ return nHorAlign;
+}
+
+sal_uInt8 lcl_GetVerAlignFromItemSet( const SfxItemSet& rItemSet )
+{
+ sal_uInt8 nVerAlign = EXC_OBJ_VER_TOP;
+
+ switch( static_cast< const SdrTextVertAdjustItem& >( rItemSet.Get( SDRATTR_TEXT_VERTADJUST ) ).GetValue() )
+ {
+ case SDRTEXTVERTADJUST_TOP: nVerAlign = EXC_OBJ_VER_TOP; break;
+ case SDRTEXTVERTADJUST_CENTER: nVerAlign = EXC_OBJ_VER_CENTER; break;
+ case SDRTEXTVERTADJUST_BOTTOM: nVerAlign = EXC_OBJ_VER_BOTTOM; break;
+ case SDRTEXTVERTADJUST_BLOCK: nVerAlign = EXC_OBJ_VER_JUSTIFY; break;
+ }
+ return nVerAlign;
+}
+
+XclTxo::XclTxo( const String& rString, sal_uInt16 nFontIx ) :
+ mpString( new XclExpString( rString ) ),
+ mnRotation( EXC_OBJ_ORIENT_NONE ),
+ mnHorAlign( EXC_OBJ_HOR_LEFT ),
+ mnVerAlign( EXC_OBJ_VER_TOP )
+{
+ if( mpString->Len() )
+ {
+ // If there is text, Excel *needs* the 2nd CONTINUE record with at least two format runs
+ mpString->AppendFormat( 0, nFontIx );
+ mpString->AppendFormat( mpString->Len(), EXC_FONT_APP );
+ }
+}
+
+XclTxo::XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rTextObj ) :
+ mpString( XclExpStringHelper::CreateString( rRoot, rTextObj ) ),
+ mnRotation( EXC_OBJ_ORIENT_NONE ),
+ mnHorAlign( EXC_OBJ_HOR_LEFT ),
+ mnVerAlign( EXC_OBJ_VER_TOP )
+{
+ // additional alignment and orientation items
+ const SfxItemSet& rItemSet = rTextObj.GetMergedItemSet();
+
+ // horizontal alignment
+ SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
+
+ // vertical alignment
+ SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
+
+ // rotation
+ long nAngle = rTextObj.GetRotateAngle();
+ if( (4500 < nAngle) && (nAngle < 13500) )
+ mnRotation = EXC_OBJ_ORIENT_90CCW;
+ else if( (22500 < nAngle) && (nAngle < 31500) )
+ mnRotation = EXC_OBJ_ORIENT_90CW;
+ else
+ mnRotation = EXC_OBJ_ORIENT_NONE;
+}
+
+XclTxo::XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption ) :
+ mpString( XclExpStringHelper::CreateString( rRoot, rEditObj ) ),
+ mnRotation( EXC_OBJ_ORIENT_NONE ),
+ mnHorAlign( EXC_OBJ_HOR_LEFT ),
+ mnVerAlign( EXC_OBJ_VER_TOP )
+{
+ if(pCaption)
+ {
+ // Excel has one alignment per NoteObject while Calc supports
+ // one alignment per paragraph - use the first paragraph
+ // alignment (if set) as our overall alignment.
+ String aParaText( rEditObj.GetText( 0 ) );
+ if( aParaText.Len() )
+ {
+ SfxItemSet aSet( rEditObj.GetParaAttribs( 0));
+ const SfxPoolItem* pItem = NULL;
+ if( aSet.GetItemState( EE_PARA_JUST, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ SvxAdjust eEEAlign = static_cast< const SvxAdjustItem& >( *pItem ).GetAdjust();
+ pCaption->SetMergedItem( SvxAdjustItem( eEEAlign, EE_PARA_JUST ) );
+ }
+ }
+ const SfxItemSet& rItemSet = pCaption->GetMergedItemSet();
+
+ // horizontal alignment
+ SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
+
+ // vertical alignment
+ SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
+
+ // orientation alignment
+ const SvxWritingModeItem& rItem = static_cast< const SvxWritingModeItem& >( rItemSet.Get( SDRATTR_TEXTDIRECTION ) );
+ if( rItem.GetValue() == com::sun::star::text::WritingMode_TB_RL )
+ mnRotation = EXC_OBJ_ORIENT_90CW;
+ }
+}
+
+void XclTxo::SaveCont( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mpString.get(), "XclTxo::SaveCont - missing string" );
+
+ // #i96858# do not save existing string formatting if text is empty
+ sal_uInt16 nRunLen = mpString->IsEmpty() ? 0 : (8 * mpString->GetFormatsCount());
+ // alignment
+ sal_uInt16 nFlags = 0;
+ ::insert_value( nFlags, mnHorAlign, 1, 3 );
+ ::insert_value( nFlags, mnVerAlign, 4, 3 );
+
+ rStrm << nFlags << mnRotation;
+ rStrm.WriteZeroBytes( 6 );
+ rStrm << mpString->Len() << nRunLen << sal_uInt32( 0 );
+}
+
+void XclTxo::Save( XclExpStream& rStrm )
+{
+ // Write the TXO part
+ ExcRecord::Save( rStrm );
+
+ // CONTINUE records are only written if there is some text
+ if( !mpString->IsEmpty() )
+ {
+ // CONTINUE for character array
+ rStrm.StartRecord( EXC_ID_CONT, mpString->GetBufferSize() + 1 );
+ rStrm << static_cast< sal_uInt8 >( mpString->GetFlagField() & EXC_STRF_16BIT ); // only Unicode flag
+ mpString->WriteBuffer( rStrm );
+ rStrm.EndRecord();
+
+ // CONTINUE for formatting runs
+ rStrm.StartRecord( EXC_ID_CONT, 8 * mpString->GetFormatsCount() );
+ const XclFormatRunVec& rFormats = mpString->GetFormats();
+ for( XclFormatRunVec::const_iterator aIt = rFormats.begin(), aEnd = rFormats.end(); aIt != aEnd; ++aIt )
+ rStrm << aIt->mnChar << aIt->mnFontIdx << sal_uInt32( 0 );
+ rStrm.EndRecord();
+ }
+}
+
+UINT16 XclTxo::GetNum() const
+{
+ return EXC_ID_TXO;
+}
+
+sal_Size XclTxo::GetLen() const
+{
+ return 18;
+}
+
+// --- class XclObjOle -------------------------------------------
+
+XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ),
+ rOleObj( rObj ),
+ pRootStorage( rObjMgr.GetRoot().GetRootStorage() )
+{
+}
+
+XclObjOle::~XclObjOle()
+{
+}
+
+void XclObjOle::WriteSubRecs( XclExpStream& rStrm )
+{
+ // write only as embedded, not linked
+ String aStorageName( RTL_CONSTASCII_USTRINGPARAM( "MBD" ) );
+ sal_Char aBuf[ sizeof(UINT32) * 2 + 1 ];
+ // FIXME Eeek! Is this just a way to get a unique id?
+ UINT32 nPictureId = UINT32(sal_uIntPtr(this) >> 2);
+ sprintf( aBuf, "%08X", static_cast< unsigned int >( nPictureId ) ); // #100211# - checked
+ aStorageName.AppendAscii( aBuf );
+ SotStorageRef xOleStg = pRootStorage->OpenSotStorage( aStorageName,
+ STREAM_READWRITE| STREAM_SHARE_DENYALL );
+ if( xOleStg.Is() )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj&)rOleObj).GetObjRef() );
+ if ( xObj.is() )
+ {
+ // set version to "old" version, because it must be
+ // saved in MS notation.
+ UINT32 nFl = 0;
+ SvtFilterOptions* pFltOpts = SvtFilterOptions::Get();
+ if( pFltOpts )
+ {
+ if( pFltOpts->IsMath2MathType() )
+ nFl |= OLE_STARMATH_2_MATHTYPE;
+
+ if( pFltOpts->IsWriter2WinWord() )
+ nFl |= OLE_STARWRITER_2_WINWORD;
+
+ if( pFltOpts->IsCalc2Excel() )
+ nFl |= OLE_STARCALC_2_EXCEL;
+
+ if( pFltOpts->IsImpress2PowerPoint() )
+ nFl |= OLE_STARIMPRESS_2_POWERPOINT;
+ }
+
+ SvxMSExportOLEObjects aOLEExpFilt( nFl );
+ aOLEExpFilt.ExportOLEObject( xObj, *xOleStg );
+
+ // OBJCF subrecord, undocumented as usual
+ rStrm.StartRecord( EXC_ID_OBJCF, 2 );
+ rStrm << UINT16(0x0002);
+ rStrm.EndRecord();
+
+ // OBJFLAGS subrecord, undocumented as usual
+ rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
+ sal_uInt16 nFlags = EXC_OBJ_PIC_MANUALSIZE;
+ ::set_flag( nFlags, EXC_OBJ_PIC_SYMBOL, ((SdrOle2Obj&)rOleObj).GetAspect() == embed::Aspects::MSOLE_ICON );
+ rStrm << nFlags;
+ rStrm.EndRecord();
+
+ // OBJPICTFMLA subrecord, undocumented as usual
+ XclExpString aName( xOleStg->GetUserName() );
+ UINT16 nPadLen = (UINT16)(aName.GetSize() & 0x01);
+ UINT16 nFmlaLen = static_cast< sal_uInt16 >( 12 + aName.GetSize() + nPadLen );
+ UINT16 nSubRecLen = nFmlaLen + 6;
+
+ rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nSubRecLen );
+ rStrm << nFmlaLen
+ << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
+ << sal_uInt32( 0 ) << sal_uInt8( 3 )
+ << aName;
+ if( nPadLen )
+ rStrm << sal_uInt8( 0 ); // pad byte
+ rStrm << nPictureId;
+ rStrm.EndRecord();
+ }
+ }
+}
+
+void XclObjOle::Save( XclExpStream& rStrm )
+{
+ // content of this record
+ XclObj::Save( rStrm );
+}
+
+// --- class XclObjAny -------------------------------------------
+
+XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN )
+{
+}
+
+XclObjAny::~XclObjAny()
+{
+}
+
+void XclObjAny::WriteSubRecs( XclExpStream& rStrm )
+{
+ if( mnObjType == EXC_OBJTYPE_GROUP )
+ // ftGmo subrecord
+ rStrm << EXC_ID_OBJGMO << UINT16(2) << UINT16(0);
+}
+
+void XclObjAny::Save( XclExpStream& rStrm )
+{
+ if( mnObjType == EXC_OBJTYPE_GROUP )
+ // old size + ftGmo
+ AddRecSize( 6 );
+
+ // content of this record
+ XclObj::Save( rStrm );
+}
+
+// --- class ExcBof8_Base --------------------------------------------
+
+ExcBof8_Base::ExcBof8_Base()
+{
+ nVers = 0x0600;
+ nRupBuild = 0x0dbb;
+ nRupYear = 0x07cc;
+// nFileHistory = 0x00000001; // last edited by Microsoft Excel for Windows
+ nFileHistory = 0x00000000;
+ nLowestBiffVer = 0x00000006; // Biff8
+}
+
+
+void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
+{
+ rStrm.DisableEncryption();
+ rStrm << nVers << nDocType << nRupBuild << nRupYear
+ << nFileHistory << nLowestBiffVer;
+}
+
+
+UINT16 ExcBof8_Base::GetNum() const
+{
+ return 0x0809;
+}
+
+
+sal_Size ExcBof8_Base::GetLen() const
+{
+ return 16;
+}
+
+
+// --- class ExcBof8 -------------------------------------------------
+
+ExcBof8::ExcBof8()
+{
+ nDocType = 0x0010;
+}
+
+
+// --- class ExcBofW8 ------------------------------------------------
+
+ExcBofW8::ExcBofW8()
+{
+ nDocType = 0x0005;
+}
+
+
+// --- class ExcBundlesheet8 -----------------------------------------
+
+ExcBundlesheet8::ExcBundlesheet8( RootData& rRootData, SCTAB _nTab ) :
+ ExcBundlesheetBase( rRootData, static_cast<sal_uInt16>(_nTab) ),
+ sUnicodeName( rRootData.pER->GetTabInfo().GetScTabName( _nTab ) )
+{
+}
+
+
+ExcBundlesheet8::ExcBundlesheet8( const String& rString ) :
+ ExcBundlesheetBase(),
+ sUnicodeName( rString )
+{
+}
+
+
+XclExpString ExcBundlesheet8::GetName() const
+{
+ return XclExpString( sUnicodeName, EXC_STR_8BITLENGTH );
+}
+
+
+void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
+{
+ nOwnPos = rStrm.GetSvStreamPos();
+ // write dummy position, real position comes later
+ rStrm.DisableEncryption();
+ rStrm << sal_uInt32(0);
+ rStrm.EnableEncryption();
+ rStrm << nGrbit << GetName();
+}
+
+
+sal_Size ExcBundlesheet8::GetLen() const
+{ // Text max 255 chars
+ return 8 + GetName().GetBufferSize();
+}
+
+
+void ExcBundlesheet8::SaveXml( XclExpXmlStream& rStrm )
+{
+ OUString sId;
+ rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", nTab+1),
+ XclXmlUtils::GetStreamName( NULL, "worksheets/sheet", nTab+1),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
+ &sId );
+
+ rStrm.GetCurrentStream()->singleElement( XML_sheet,
+ XML_name, XclXmlUtils::ToOString( sUnicodeName ).getStr(),
+ XML_sheetId, rtl::OString::valueOf( (sal_Int32)( nTab+1 ) ).getStr(),
+ XML_state, nGrbit == 0x0000 ? "visible" : "hidden",
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+}
+
+
+
+// --- class XclObproj -----------------------------------------------
+
+UINT16 XclObproj::GetNum() const
+{
+ return 0x00D3;
+}
+
+
+sal_Size XclObproj::GetLen() const
+{
+ return 0;
+}
+
+
+// ---- class XclCodename --------------------------------------------
+
+XclCodename::XclCodename( const String& r ) : aName( r )
+{
+}
+
+
+void XclCodename::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << aName;
+}
+
+
+UINT16 XclCodename::GetNum() const
+{
+ return 0x01BA;
+}
+
+
+sal_Size XclCodename::GetLen() const
+{
+ return aName.GetSize();
+}
+
+
+
+// ---- Scenarios ----------------------------------------------------
+
+ExcEScenarioCell::ExcEScenarioCell( UINT16 nC, UINT16 nR, const String& rTxt ) :
+ nCol( nC ),
+ nRow( nR ),
+ sText( rTxt, EXC_STR_DEFAULT, 255 )
+{
+}
+
+void ExcEScenarioCell::WriteAddress( XclExpStream& rStrm )
+{
+ rStrm << nRow << nCol;
+}
+
+void ExcEScenarioCell::WriteText( XclExpStream& rStrm )
+{
+ rStrm << sText;
+}
+
+void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_inputCells,
+ // OOXTODO: XML_deleted,
+ // OOXTODO: XML_numFmtId,
+ XML_r, XclXmlUtils::ToOString( ScAddress( nCol, nRow, 0 ) ).getStr(),
+ // OOXTODO: XML_undone,
+ XML_val, XclXmlUtils::ToOString( sText ).getStr(),
+ FSEND );
+}
+
+
+
+
+ExcEScenario::ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab )
+{
+ String sTmpName;
+ String sTmpComm;
+ Color aDummyCol;
+ USHORT nFlags;
+
+ ScDocument& rDoc = rRoot.GetDoc();
+ rDoc.GetName( nTab, sTmpName );
+ sName.Assign( sTmpName, EXC_STR_8BITLENGTH );
+ nRecLen = 8 + sName.GetBufferSize();
+
+ rDoc.GetScenarioData( nTab, sTmpComm, aDummyCol, nFlags );
+ sComment.Assign( sTmpComm, EXC_STR_DEFAULT, 255 );
+ if( sComment.Len() )
+ nRecLen += sComment.GetSize();
+ nProtected = (nFlags & SC_SCENARIO_PROTECT) ? 1 : 0;
+
+ sUserName.Assign( rRoot.GetUserName(), EXC_STR_DEFAULT, 255 );
+ nRecLen += sUserName.GetSize();
+
+ const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab );
+ if( !pRList )
+ return;
+
+ BOOL bContLoop = TRUE;
+ SCROW nRow;
+ SCCOL nCol;
+ String sText;
+ double fVal;
+
+ for( UINT32 nRange = 0; (nRange < pRList->Count()) && bContLoop; nRange++ )
+ {
+ const ScRange* pRange = pRList->GetObject( nRange );
+ for( nRow = pRange->aStart.Row(); (nRow <= pRange->aEnd.Row()) && bContLoop; nRow++ )
+ for( nCol = pRange->aStart.Col(); (nCol <= pRange->aEnd.Col()) && bContLoop; nCol++ )
+ {
+ if( rDoc.HasValueData( nCol, nRow, nTab ) )
+ {
+ rDoc.GetValue( nCol, nRow, nTab, fVal );
+ sText = ::rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0),
+ TRUE );
+ }
+ else
+ rDoc.GetString( nCol, nRow, nTab, sText );
+ bContLoop = Append( static_cast<sal_uInt16>(nCol),
+ static_cast<sal_uInt16>(nRow), sText );
+ }
+ }
+}
+
+ExcEScenario::~ExcEScenario()
+{
+ for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
+ delete pCell;
+}
+
+BOOL ExcEScenario::Append( UINT16 nCol, UINT16 nRow, const String& rTxt )
+{
+ if( List::Count() == EXC_SCEN_MAXCELL )
+ return FALSE;
+
+ ExcEScenarioCell* pCell = new ExcEScenarioCell( nCol, nRow, rTxt );
+ List::Insert( pCell, LIST_APPEND );
+ nRecLen += 6 + pCell->GetStringBytes(); // 4 bytes address, 2 bytes ifmt
+ return TRUE;
+}
+
+void ExcEScenario::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (UINT16) List::Count() // number of cells
+ << nProtected // fProtection
+ << (UINT8) 0 // fHidden
+ << (UINT8) sName.Len() // length of scen name
+ << (UINT8) sComment.Len() // length of comment
+ << (UINT8) sUserName.Len(); // length of user name
+ sName.WriteFlagField( rStrm );
+ sName.WriteBuffer( rStrm );
+
+ rStrm << sUserName;
+
+ if( sComment.Len() )
+ rStrm << sComment;
+
+ ExcEScenarioCell* pCell;
+ for( pCell = _First(); pCell; pCell = _Next() )
+ pCell->WriteAddress( rStrm ); // pos of cell
+ for( pCell = _First(); pCell; pCell = _Next() )
+ pCell->WriteText( rStrm ); // string content
+ rStrm.SetSliceSize( 2 );
+ rStrm.WriteZeroBytes( 2 * List::Count() ); // date format
+}
+
+UINT16 ExcEScenario::GetNum() const
+{
+ return 0x00AF;
+}
+
+sal_Size ExcEScenario::GetLen() const
+{
+ return nRecLen;
+}
+
+void ExcEScenario::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_scenario,
+ XML_name, XclXmlUtils::ToOString( sName ).getStr(),
+ XML_locked, XclXmlUtils::ToPsz( nProtected ),
+ // OOXTODO: XML_hidden,
+ XML_count, OString::valueOf( (sal_Int32) List::Count() ).getStr(),
+ XML_user, XESTRING_TO_PSZ( sUserName ),
+ XML_comment, XESTRING_TO_PSZ( sComment ),
+ FSEND );
+
+ for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
+ pCell->SaveXml( rStrm );
+
+ rWorkbook->endElement( XML_scenario );
+}
+
+
+
+
+ExcEScenarioManager::ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ) :
+ nActive( 0 )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ if( rDoc.IsScenario( nTab ) )
+ return;
+
+ SCTAB nFirstTab = nTab + 1;
+ SCTAB nNewTab = nFirstTab;
+
+ while( rDoc.IsScenario( nNewTab ) )
+ {
+ Append( new ExcEScenario( rRoot, nNewTab ) );
+
+ if( rDoc.IsActiveScenario( nNewTab ) )
+ nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab);
+ nNewTab++;
+ }
+}
+
+ExcEScenarioManager::~ExcEScenarioManager()
+{
+ for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
+ delete pScen;
+}
+
+void ExcEScenarioManager::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (UINT16) List::Count() // number of scenarios
+ << nActive // active scen
+ << nActive // last displayed
+ << (UINT16) 0; // reference areas
+}
+
+void ExcEScenarioManager::Save( XclExpStream& rStrm )
+{
+ if( List::Count() )
+ ExcRecord::Save( rStrm );
+
+ for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
+ pScen->Save( rStrm );
+}
+
+void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( ! List::Count() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_scenarios,
+ XML_current, OString::valueOf( (sal_Int32)nActive ).getStr(),
+ XML_show, OString::valueOf( (sal_Int32)nActive ).getStr(),
+ // OOXTODO: XML_sqref,
+ FSEND );
+
+ for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
+ pScen->SaveXml( rStrm );
+
+ rWorkbook->endElement( XML_scenarios );
+}
+
+UINT16 ExcEScenarioManager::GetNum() const
+{
+ return 0x00AE;
+}
+
+sal_Size ExcEScenarioManager::GetLen() const
+{
+ return 8;
+}
+
+// ============================================================================
+
+struct XclExpTabProtectOption
+{
+ ScTableProtection::Option eOption;
+ sal_uInt16 nMask;
+};
+
+XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
+ XclExpRecord( 0x0867, 23 )
+{
+ static const XclExpTabProtectOption aTable[] =
+ {
+ { ScTableProtection::OBJECTS, 0x0001 },
+ { ScTableProtection::SCENARIOS, 0x0002 },
+ { ScTableProtection::FORMAT_CELLS, 0x0004 },
+ { ScTableProtection::FORMAT_COLUMNS, 0x0008 },
+ { ScTableProtection::FORMAT_ROWS, 0x0010 },
+ { ScTableProtection::INSERT_COLUMNS, 0x0020 },
+ { ScTableProtection::INSERT_ROWS, 0x0040 },
+ { ScTableProtection::INSERT_HYPERLINKS, 0x0080 },
+
+ { ScTableProtection::DELETE_COLUMNS, 0x0100 },
+ { ScTableProtection::DELETE_ROWS, 0x0200 },
+ { ScTableProtection::SELECT_LOCKED_CELLS, 0x0400 },
+ { ScTableProtection::SORT, 0x0800 },
+ { ScTableProtection::AUTOFILTER, 0x1000 },
+ { ScTableProtection::PIVOT_TABLES, 0x2000 },
+ { ScTableProtection::SELECT_UNLOCKED_CELLS, 0x4000 },
+
+ { ScTableProtection::NONE, 0x0000 }
+ };
+
+ mnOptions = 0x0000;
+ ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
+ if (!pProtect)
+ return;
+
+ for (int i = 0; aTable[i].nMask != 0x0000; ++i)
+ {
+ if ( pProtect->isOptionEnabled(aTable[i].eOption) )
+ mnOptions |= aTable[i].nMask;
+ }
+}
+
+void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nBytes = 0x0867;
+ rStrm << nBytes;
+
+ sal_uChar nZero = 0x00;
+ for (int i = 0; i < 9; ++i)
+ rStrm << nZero;
+
+ nBytes = 0x0200;
+ rStrm << nBytes;
+ nBytes = 0x0100;
+ rStrm << nBytes;
+ nBytes = 0xFFFF;
+ rStrm << nBytes << nBytes;
+
+ rStrm << mnOptions;
+ nBytes = 0;
+ rStrm << nBytes;
+}
+
+// ============================================================================
+
+
+
+
+void XclCalccount::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nCount;
+}
+
+
+XclCalccount::XclCalccount( const ScDocument& rDoc )
+{
+ nCount = rDoc.GetDocOptions().GetIterCount();
+}
+
+
+UINT16 XclCalccount::GetNum() const
+{
+ return 0x000C;
+}
+
+
+sal_Size XclCalccount::GetLen() const
+{
+ return 2;
+}
+
+
+void XclCalccount::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_iterateCount, OString::valueOf( (sal_Int32)nCount ).getStr(),
+ FSEND );
+}
+
+
+
+
+void XclIteration::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nIter;
+}
+
+
+XclIteration::XclIteration( const ScDocument& rDoc )
+{
+ nIter = rDoc.GetDocOptions().IsIter()? 1 : 0;
+}
+
+
+UINT16 XclIteration::GetNum() const
+{
+ return 0x0011;
+}
+
+
+sal_Size XclIteration::GetLen() const
+{
+ return 2;
+}
+
+
+void XclIteration::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_iterate, XclXmlUtils::ToPsz( nIter == 1 ),
+ FSEND );
+}
+
+
+
+
+void XclDelta::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << fDelta;
+}
+
+
+
+XclDelta::XclDelta( const ScDocument& rDoc )
+{
+ fDelta = rDoc.GetDocOptions().GetIterEps();
+}
+
+
+UINT16 XclDelta::GetNum() const
+{
+ return 0x0010;
+}
+
+
+sal_Size XclDelta::GetLen() const
+{
+ return 8;
+}
+
+
+void XclDelta::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_iterateDelta, OString::valueOf( fDelta ).getStr(),
+ FSEND );
+}
+
+// ============================================================================
+
+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);
+}
+
+// ============================================================================
+
+XclExpInterfaceHdr::XclExpInterfaceHdr( sal_uInt16 nCodePage ) :
+ XclExpUInt16Record( EXC_ID_INTERFACEHDR, nCodePage )
+{
+}
+
+void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.DisableEncryption();
+ rStrm << GetValue();
+}
+
+// ============================================================================
+
+XclExpInterfaceEnd::XclExpInterfaceEnd() :
+ XclExpRecord(0x00E2, 0) {}
+
+XclExpInterfaceEnd::~XclExpInterfaceEnd() {}
+
+void XclExpInterfaceEnd::WriteBody( XclExpStream& rStrm )
+{
+ // Don't forget to re-enable encryption.
+ rStrm.EnableEncryption();
+}
+
+// ============================================================================
+
+XclExpWriteAccess::XclExpWriteAccess() :
+ XclExpRecord(0x005C, 112)
+{
+}
+
+XclExpWriteAccess::~XclExpWriteAccess()
+{
+}
+
+void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
+{
+ static const sal_uInt8 aData[] = {
+ 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
+
+ sal_Size nDataSize = sizeof(aData);
+ for (sal_Size i = 0; i < nDataSize; ++i)
+ rStrm << aData[i];
+}
+
+// ============================================================================
+
+XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ) :
+ XclExpRecord( EXC_ID_FILESHARING ),
+ mnPasswordHash( nPasswordHash ),
+ mbRecommendReadOnly( bRecommendReadOnly )
+{
+ if( rRoot.GetBiff() <= EXC_BIFF5 )
+ maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ maUserName.Assign( rRoot.GetUserName() );
+}
+
+void XclExpFileSharing::Save( XclExpStream& rStrm )
+{
+ if( (mnPasswordHash != 0) || mbRecommendReadOnly )
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpFileSharing::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << sal_uInt16( mbRecommendReadOnly ? 1 : 0 ) << mnPasswordHash << maUserName;
+}
+
+// ============================================================================
+
+XclExpProt4Rev::XclExpProt4Rev() :
+ XclExpRecord(0x01AF, 2)
+{
+}
+
+XclExpProt4Rev::~XclExpProt4Rev()
+{
+}
+
+void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+XclExpProt4RevPass::XclExpProt4RevPass() :
+ XclExpRecord(0x01BC, 2)
+{
+}
+
+XclExpProt4RevPass::~XclExpProt4RevPass()
+{
+}
+
+void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+static const sal_uInt8 nDataRecalcId[] = {
+ 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
+};
+
+XclExpRecalcId::XclExpRecalcId() :
+ XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
+{
+}
+
+// ============================================================================
+
+static const sal_uInt8 nDataBookExt[] = {
+ 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02
+};
+
+XclExpBookExt::XclExpBookExt() :
+ XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
+{
+}
+
+// ============================================================================
+
+XclRefmode::XclRefmode( const ScDocument& rDoc ) :
+ XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
+{
+}
+
+void XclRefmode::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_refMode, GetBool() ? "A1" : "R1C1",
+ FSEND );
+}
+
diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
new file mode 100644
index 000000000000..b124e77ac745
--- /dev/null
+++ b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
@@ -0,0 +1,273 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLCalculationSettingsContext.hxx"
+#include "xmlimprt.hxx"
+#include "unonames.hxx"
+#include "docoptio.hxx"
+#include "document.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <comphelper/extract.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLCalculationSettingsContext::ScXMLCalculationSettingsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ fIterationEpsilon(0.001),
+ nIterationCount(100),
+ nYear2000(1930),
+ bIsIterationEnabled(sal_False),
+ bCalcAsShown(sal_False),
+ bIgnoreCase(sal_False),
+ bLookUpLabels(sal_True),
+ bMatchWholeCell(sal_True),
+ bUseRegularExpressions(sal_True)
+{
+ aNullDate.Day = 30;
+ aNullDate.Month = 12;
+ aNullDate.Year = 1899;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_CASE_SENSITIVE))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bIgnoreCase = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_PRECISION_AS_SHOWN))
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ bCalcAsShown = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bMatchWholeCell = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_AUTOMATIC_FIND_LABELS))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bLookUpLabels = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_NULL_YEAR))
+ {
+ sal_Int32 nTemp;
+ GetScImport().GetMM100UnitConverter().convertNumber(nTemp, sValue);
+ nYear2000 = static_cast<sal_uInt16>(nTemp);
+ }
+ else if (IsXMLToken(aLocalName, XML_USE_REGULAR_EXPRESSIONS))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bUseRegularExpressions = sal_False;
+ }
+ }
+ }
+}
+
+ScXMLCalculationSettingsContext::~ScXMLCalculationSettingsContext()
+{
+}
+
+SvXMLImportContext *ScXMLCalculationSettingsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_NULL_DATE))
+ pContext = new ScXMLNullDateContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ else if (IsXMLToken(rLName, XML_ITERATION))
+ pContext = new ScXMLIterationContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLCalculationSettingsContext::EndElement()
+{
+ if (GetScImport().GetModel().is())
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (GetScImport().GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN)), uno::makeAny(bCalcAsShown) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE)), uno::makeAny(bIgnoreCase) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS)), uno::makeAny(bLookUpLabels) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE)), uno::makeAny(bMatchWholeCell) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED)), uno::makeAny(bUseRegularExpressions) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED)), uno::makeAny(bIsIterationEnabled) );
+ xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT)), uno::makeAny(nIterationCount) );
+ xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON)), uno::makeAny(fIterationEpsilon) );
+ xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE)), uno::makeAny(aNullDate) );
+ if (GetScImport().GetDocument())
+ {
+ GetScImport().LockSolarMutex();
+ ScDocOptions aDocOptions (GetScImport().GetDocument()->GetDocOptions());
+ aDocOptions.SetYear2000(nYear2000);
+ GetScImport().GetDocument()->SetDocOptions(aDocOptions);
+ GetScImport().UnlockSolarMutex();
+ }
+ }
+ }
+}
+
+ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLCalculationSettingsContext* pCalcSet) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DATE_VALUE))
+ {
+ util::DateTime aDateTime;
+ GetScImport().GetMM100UnitConverter().convertDateTime(aDateTime, sValue);
+ util::Date aDate;
+ aDate.Day = aDateTime.Day;
+ aDate.Month = aDateTime.Month;
+ aDate.Year = aDateTime.Year;
+ pCalcSet->SetNullDate(aDate);
+ }
+ }
+}
+
+ScXMLNullDateContext::~ScXMLNullDateContext()
+{
+}
+
+SvXMLImportContext *ScXMLNullDateContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLNullDateContext::EndElement()
+{
+}
+
+ScXMLIterationContext::ScXMLIterationContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLCalculationSettingsContext* pCalcSet) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_STATUS))
+ {
+ if (IsXMLToken(sValue, XML_ENABLE))
+ pCalcSet->SetIterationStatus(sal_True);
+ }
+ else if (IsXMLToken(aLocalName, XML_STEPS))
+ {
+ sal_Int32 nSteps;
+ GetScImport().GetMM100UnitConverter().convertNumber(nSteps, sValue);
+ pCalcSet->SetIterationCount(nSteps);
+ }
+ else if (IsXMLToken(aLocalName, XML_MAXIMUM_DIFFERENCE))
+ {
+ double fDif;
+ GetScImport().GetMM100UnitConverter().convertDouble(fDif, sValue);
+ pCalcSet->SetIterationEpsilon(fDif);
+ }
+ }
+ }
+}
+
+ScXMLIterationContext::~ScXMLIterationContext()
+{
+}
+
+SvXMLImportContext *ScXMLIterationContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLIterationContext::EndElement()
+{
+}
diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.hxx b/sc/source/filter/xml/XMLCalculationSettingsContext.hxx
new file mode 100644
index 000000000000..8fe5a7f1db1c
--- /dev/null
+++ b/sc/source/filter/xml/XMLCalculationSettingsContext.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCALCULATIONSETTINGSCONTEXT_HXX
+#define SC_XMLCALCULATIONSETTINGSCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/util/Date.hpp>
+
+class ScXMLImport;
+
+class ScXMLCalculationSettingsContext : public SvXMLImportContext
+{
+ com::sun::star::util::Date aNullDate;
+ double fIterationEpsilon;
+ sal_Int32 nIterationCount;
+ sal_uInt16 nYear2000;
+ sal_Bool bIsIterationEnabled;
+ sal_Bool bCalcAsShown;
+ sal_Bool bIgnoreCase;
+ sal_Bool bLookUpLabels;
+ sal_Bool bMatchWholeCell;
+ sal_Bool bUseRegularExpressions;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLCalculationSettingsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLCalculationSettingsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void SetNullDate(const com::sun::star::util::Date& aDate) { aNullDate = aDate; }
+ void SetIterationStatus(const sal_Bool bValue) { bIsIterationEnabled = bValue; }
+ void SetIterationCount(const sal_Int32 nValue) { nIterationCount = nValue; }
+ void SetIterationEpsilon(const double fValue) { fIterationEpsilon = fValue; }
+ virtual void EndElement();
+};
+
+class ScXMLNullDateContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLNullDateContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList, ScXMLCalculationSettingsContext* pCalcSet);
+
+ virtual ~ScXMLNullDateContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLIterationContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLIterationContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList, ScXMLCalculationSettingsContext* pCalcSet);
+
+ virtual ~ScXMLIterationContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLCellRangeSourceContext.cxx b/sc/source/filter/xml/XMLCellRangeSourceContext.cxx
new file mode 100644
index 000000000000..9826e8385075
--- /dev/null
+++ b/sc/source/filter/xml/XMLCellRangeSourceContext.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//___________________________________________________________________
+#include "XMLCellRangeSourceContext.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "xmlimprt.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+
+
+//___________________________________________________________________
+
+ScMyImpCellRangeSource::ScMyImpCellRangeSource() :
+ nColumns( 0 ),
+ nRows( 0 ),
+ nRefresh( 0 )
+{
+}
+
+
+//___________________________________________________________________
+
+ScXMLCellRangeSourceContext::ScXMLCellRangeSourceContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList,
+ ScMyImpCellRangeSource* pCellRangeSource ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableCellRangeSourceAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( nIndex ));
+ const OUString& sValue(xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME:
+ pCellRangeSource->sSourceStr = sValue;
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME:
+ pCellRangeSource->sFilterName = sValue;
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS:
+ pCellRangeSource->sFilterOptions = sValue;
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF:
+ pCellRangeSource->sURL = GetScImport().GetAbsoluteReference(sValue);
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN:
+ {
+ sal_Int32 nValue;
+ if( SvXMLUnitConverter::convertNumber( nValue, sValue, 1 ) )
+ pCellRangeSource->nColumns = nValue;
+ else
+ pCellRangeSource->nColumns = 1;
+ }
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW:
+ {
+ sal_Int32 nValue;
+ if( SvXMLUnitConverter::convertNumber( nValue, sValue, 1 ) )
+ pCellRangeSource->nRows = nValue;
+ else
+ pCellRangeSource->nRows = 1;
+ }
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY:
+ {
+ double fTime;
+ if( SvXMLUnitConverter::convertTime( fTime, sValue ) )
+ pCellRangeSource->nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 );
+ }
+ break;
+ }
+ }
+}
+
+ScXMLCellRangeSourceContext::~ScXMLCellRangeSourceContext()
+{
+}
+
+SvXMLImportContext *ScXMLCellRangeSourceContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLCellRangeSourceContext::EndElement()
+{
+}
+
diff --git a/sc/source/filter/xml/XMLCellRangeSourceContext.hxx b/sc/source/filter/xml/XMLCellRangeSourceContext.hxx
new file mode 100644
index 000000000000..fde1b5534134
--- /dev/null
+++ b/sc/source/filter/xml/XMLCellRangeSourceContext.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCELLRANGESOURCECONTEXT_HXX
+#define SC_XMLCELLRANGESOURCECONTEXT_HXX
+
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+struct ScMyImpCellRangeSource
+{
+ ::rtl::OUString sSourceStr;
+ ::rtl::OUString sFilterName;
+ ::rtl::OUString sFilterOptions;
+ ::rtl::OUString sURL;
+ sal_Int32 nColumns;
+ sal_Int32 nRows;
+ sal_Int32 nRefresh;
+
+ ScMyImpCellRangeSource();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLCellRangeSourceContext : public SvXMLImportContext
+{
+private:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLCellRangeSourceContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList,
+ ScMyImpCellRangeSource* pCellRangeSource
+ );
+ virtual ~ScXMLCellRangeSourceContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx
new file mode 100644
index 000000000000..5cd97e0714a9
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx
@@ -0,0 +1,817 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLChangeTrackingExportHelper.hxx"
+#include "xmlexprt.hxx"
+#include "XMLConverter.hxx"
+#include "document.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "cell.hxx"
+#include "textuno.hxx"
+#include "rangeutl.hxx"
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <svl/zforlist.hxx>
+
+#define SC_CHANGE_ID_PREFIX "ct"
+
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+ScChangeTrackingExportHelper::ScChangeTrackingExportHelper(ScXMLExport& rTempExport)
+ : rExport(rTempExport),
+ pChangeTrack(NULL),
+ pEditTextObj(NULL),
+ pDependings(NULL),
+ sChangeIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX))
+{
+ pChangeTrack = rExport.GetDocument() ? rExport.GetDocument()->GetChangeTrack() : NULL;
+ pDependings = new ScChangeActionTable();
+}
+
+ScChangeTrackingExportHelper::~ScChangeTrackingExportHelper()
+{
+ if (pDependings)
+ delete pDependings;
+}
+
+rtl::OUString ScChangeTrackingExportHelper::GetChangeID(const sal_uInt32 nActionNumber)
+{
+ rtl::OUStringBuffer sBuffer(sChangeIDPrefix);
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nActionNumber));
+ return sBuffer.makeStringAndClear();
+}
+
+void ScChangeTrackingExportHelper::GetAcceptanceState(const ScChangeAction* pAction)
+{
+ if (pAction->IsRejected())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_REJECTED);
+ else if (pAction->IsAccepted())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_ACCEPTED);
+}
+
+void ScChangeTrackingExportHelper::WriteBigRange(const ScBigRange& rBigRange, XMLTokenEnum aName)
+{
+ sal_Int32 nStartColumn;
+ sal_Int32 nEndColumn;
+ sal_Int32 nStartRow;
+ sal_Int32 nEndRow;
+ sal_Int32 nStartSheet;
+ sal_Int32 nEndSheet;
+ rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
+ nEndColumn, nEndRow, nEndSheet);
+ if ((nStartColumn == nEndColumn) && (nStartRow == nEndRow) && (nStartSheet == nEndSheet))
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COLUMN, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartRow);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ROW, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
+ }
+ else
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_COLUMN, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartRow);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_ROW, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_TABLE, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nEndColumn);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_COLUMN, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nEndRow);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_ROW, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nEndSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_TABLE, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aBigRangeElem(rExport, XML_NAMESPACE_TABLE, aName, sal_True, sal_True);
+}
+
+void ScChangeTrackingExportHelper::WriteChangeInfo(const ScChangeAction* pAction)
+{
+ SvXMLElementExport aElemInfo (rExport, XML_NAMESPACE_OFFICE, XML_CHANGE_INFO, sal_True, sal_True);
+
+ {
+ SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC,
+ XML_CREATOR, sal_True,
+ sal_False );
+ rtl::OUString sAuthor(pAction->GetUser());
+ rExport.Characters(sAuthor);
+ }
+
+ {
+ rtl::OUStringBuffer sDate;
+ ScXMLConverter::ConvertDateTimeToString(pAction->GetDateTimeUTC(), sDate);
+ SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC,
+ XML_DATE, sal_True,
+ sal_False );
+ rExport.Characters(sDate.makeStringAndClear());
+ }
+
+ rtl::OUString sComment(pAction->GetComment());
+ if (sComment.getLength())
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sComment, bPrevCharWasSpace);
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteGenerated(const ScChangeAction* pGeneratedAction)
+{
+#ifdef DBG_UTIL
+ sal_uInt32 nActionNumber(pGeneratedAction->GetActionNumber());
+ DBG_ASSERT(pChangeTrack->IsGenerated(nActionNumber), "a not generated action found");
+#endif
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True);
+ WriteBigRange(pGeneratedAction->GetBigRange(), XML_CELL_ADDRESS);
+ String sValue;
+ static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewString(sValue);
+ WriteCell(static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewCell(), sValue);
+}
+
+void ScChangeTrackingExportHelper::WriteDeleted(const ScChangeAction* pDeletedAction)
+{
+ sal_uInt32 nActionNumber(pDeletedAction->GetActionNumber());
+ if (pDeletedAction->GetType() == SC_CAT_CONTENT)
+ {
+ const ScChangeActionContent* pContentAction = static_cast<const ScChangeActionContent*>(pDeletedAction);
+ if (pContentAction)
+ {
+ if (!pChangeTrack->IsGenerated(nActionNumber))
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True);
+ if (static_cast<const ScChangeActionContent*>(pDeletedAction)->IsTopContent() && pDeletedAction->IsDeletedIn())
+ {
+ String sValue;
+ pContentAction->GetNewString(sValue);
+ WriteCell(pContentAction->GetNewCell(), sValue);
+ }
+ }
+ else
+ WriteGenerated(pContentAction);
+ }
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_DELETION, sal_True, sal_True);
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteDepending(const ScChangeAction* pDependAction)
+{
+ sal_uInt32 nActionNumber(pDependAction->GetActionNumber());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
+
+ // #i80033# save old "dependence" element if backward compatibility is requested,
+ // correct "dependency" element otherwise
+ const bool bSaveBackwardsCompatible = ( rExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );
+ SvXMLElementExport aDependElem(rExport, XML_NAMESPACE_TABLE,
+ bSaveBackwardsCompatible ? XML_DEPENDENCE : XML_DEPENDENCY,
+ sal_True, sal_True);
+}
+
+void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction)
+{
+ if (pAction->HasDependent())
+ {
+ SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True);
+ const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDependentEntry();
+ while (pEntry)
+ {
+ WriteDepending(pEntry->GetAction());
+ pEntry = pEntry->GetNext();
+ }
+ }
+ if (pAction->HasDeleted())
+ {
+ SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DELETIONS, sal_True, sal_True);
+ const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDeletedEntry();
+ while (pEntry)
+ {
+ WriteDeleted(pEntry->GetAction());
+ pEntry = pEntry->GetNext();
+ }
+ /*if (pAction->IsDeleteType())
+ {
+ ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction);
+ if (pDelAction)
+ {
+ const ScChangeActionCellListEntry* pCellEntry = pDelAction->GetFirstCellEntry();
+ while (pCellEntry)
+ {
+ WriteGenerated(pCellEntry->GetContent());
+ pCellEntry = pCellEntry->GetNext();
+ }
+ }
+ }
+ else if (pAction->GetType() == SC_CAT_MOVE)
+ {
+ ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction);
+ if (pMoveAction)
+ {
+ const ScChangeActionCellListEntry* pCellEntry = pMoveAction->GetFirstCellEntry();
+ while (pCellEntry)
+ {
+ WriteGenerated(pCellEntry->GetContent());
+ pCellEntry = pCellEntry->GetNext();
+ }
+ }
+ }*/
+ }
+}
+
+/*void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction)
+{
+ pChangeTrack->GetDependents(pAction, *pDependings);
+ if (pDependings->Count())
+ {
+ SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True);
+ ScChangeAction* pDependAction = pDependings->First();
+ while (pDependAction != NULL)
+ {
+ WriteDepending(pDependAction);
+ pDependAction = pDependings->Next();
+ }
+ }
+}*/
+
+void ScChangeTrackingExportHelper::WriteEmptyCell()
+{
+ SvXMLElementExport aElemEmptyCell(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+}
+
+void ScChangeTrackingExportHelper::SetValueAttributes(const double& fValue, const String& sValue)
+{
+ sal_Bool bSetAttributes(sal_False);
+ if (sValue.Len())
+ {
+ sal_uInt32 nIndex;
+ double fTempValue;
+ if (rExport.GetDocument() && rExport.GetDocument()->GetFormatTable()->IsNumberFormat(sValue, nIndex, fTempValue))
+ {
+ sal_uInt16 nType = rExport.GetDocument()->GetFormatTable()->GetType(nIndex);
+ if ((nType & NUMBERFORMAT_DEFINED) == NUMBERFORMAT_DEFINED)
+ nType -= NUMBERFORMAT_DEFINED;
+ switch(nType)
+ {
+ case NUMBERFORMAT_DATE:
+ {
+ if ( rExport.GetMM100UnitConverter().setNullDate(rExport.GetModel()) )
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_DATE);
+ rtl::OUStringBuffer sBuffer;
+ rExport.GetMM100UnitConverter().convertDateTime(sBuffer, fTempValue);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear());
+ bSetAttributes = sal_True;
+ }
+ }
+ break;
+ case NUMBERFORMAT_TIME:
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME);
+ rtl::OUStringBuffer sBuffer;
+ rExport.GetMM100UnitConverter().convertTime(sBuffer, fTempValue);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear());
+ bSetAttributes = sal_True;
+ }
+ break;
+ }
+ }
+ }
+ if (!bSetAttributes)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertDouble(sBuffer, fValue);
+ rtl::OUString sNumValue(sBuffer.makeStringAndClear());
+ if (sNumValue.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sNumValue);
+ }
+}
+
+
+void ScChangeTrackingExportHelper::WriteValueCell(const ScBaseCell* pCell, const String& sValue)
+{
+ const ScValueCell* pValueCell = static_cast<const ScValueCell*>(pCell);
+ if (pValueCell)
+ {
+ SetValueAttributes(pValueCell->GetValue(), sValue);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+/* if (sValue.Len())
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sValue, bPrevCharWasSpace);
+ }*/
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteStringCell(const ScBaseCell* pCell)
+{
+ const ScStringCell* pStringCell = static_cast<const ScStringCell*>(pCell);
+ if (pStringCell)
+ {
+ String sString;
+ pStringCell->GetString(sString);
+ rtl::OUString sOUString(sString);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ if (sOUString.getLength())
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sOUString, bPrevCharWasSpace);
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteEditCell(const ScBaseCell* pCell)
+{
+ const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pCell);
+ if (pEditCell)
+ {
+ String sString;
+ pEditCell->GetString(sString);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ if (sString.Len())
+ {
+ if (!pEditTextObj)
+ {
+ pEditTextObj = new ScEditEngineTextObj();
+ xText.set(pEditTextObj);
+ }
+ pEditTextObj->SetText(*(pEditCell->GetData()));
+ if (xText.is())
+ rExport.GetTextParagraphExport()->exportText(xText, sal_False, sal_False);
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteFormulaCell(const ScBaseCell* pCell, const String& sValue)
+{
+ ScBaseCell* pBaseCell = const_cast<ScBaseCell*>(pCell);
+ ScFormulaCell* pFormulaCell = static_cast<ScFormulaCell*>(pBaseCell);
+ if (pFormulaCell)
+ {
+ rtl::OUString sAddress;
+ const ScDocument* pDoc = rExport.GetDocument();
+ ScRangeStringConverter::GetStringFromAddress(sAddress, pFormulaCell->aPos, pDoc, ::formula::FormulaGrammar::CONV_OOO);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_ADDRESS, sAddress);
+ const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
+ sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
+ String sFormula;
+ pFormulaCell->GetFormula(sFormula, eGrammar);
+ rtl::OUString sOUFormula(sFormula);
+ sal_uInt8 nMatrixFlag(pFormulaCell->GetMatrixFlag());
+ if (nMatrixFlag)
+ {
+ if (nMatrixFlag == MM_FORMULA)
+ {
+ SCCOL nColumns;
+ SCROW nRows;
+ pFormulaCell->GetMatColsRows(nColumns, nRows);
+ rtl::OUStringBuffer sColumns;
+ rtl::OUStringBuffer sRows;
+ SvXMLUnitConverter::convertNumber(sColumns, static_cast<sal_Int32>(nColumns));
+ SvXMLUnitConverter::convertNumber(sRows, static_cast<sal_Int32>(nRows));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MATRIX_COVERED, XML_TRUE);
+ }
+ rtl::OUString sMatrixFormula = sOUFormula.copy(1, sOUFormula.getLength() - 2);
+ rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sMatrixFormula, sal_False );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
+ }
+ else
+ {
+ rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sFormula, sal_False );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
+ }
+ if (pFormulaCell->IsValue())
+ {
+ SetValueAttributes(pFormulaCell->GetValue(), sValue);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ String sCellValue;
+ pFormulaCell->GetString(sCellValue);
+ rtl::OUString sOUValue(sCellValue);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ if (sOUValue.getLength())
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sOUValue, bPrevCharWasSpace);
+ }
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteCell(const ScBaseCell* pCell, const String& sValue)
+{
+ if (pCell)
+ {
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_NONE:
+ WriteEmptyCell();
+ break;
+ case CELLTYPE_VALUE:
+ WriteValueCell(pCell, sValue);
+ break;
+ case CELLTYPE_STRING:
+ WriteStringCell(pCell);
+ break;
+ case CELLTYPE_EDIT:
+ WriteEditCell(pCell);
+ break;
+ case CELLTYPE_FORMULA:
+ WriteFormulaCell(pCell, sValue);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ WriteEmptyCell();
+}
+
+void ScChangeTrackingExportHelper::WriteContentChange(ScChangeAction* pAction)
+{
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_CHANGE, sal_True, sal_True);
+ const ScChangeAction* pConstAction = pAction;
+ WriteBigRange(pConstAction->GetBigRange(), XML_CELL_ADDRESS);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+ {
+ ScChangeActionContent* pPrevAction = static_cast<ScChangeActionContent*>(pAction)->GetPrevContent();
+ if (pPrevAction)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pPrevAction->GetActionNumber()));
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_PREVIOUS, sal_True, sal_True);
+ String sValue;
+ static_cast<ScChangeActionContent*>(pAction)->GetOldString(sValue);
+ WriteCell(static_cast<ScChangeActionContent*>(pAction)->GetOldCell(), sValue);
+ }
+}
+
+void ScChangeTrackingExportHelper::AddInsertionAttributes(const ScChangeAction* pConstAction)
+{
+ sal_Int32 nPosition(0);
+ sal_Int32 nCount(0);
+ sal_Int32 nStartPosition(0);
+ sal_Int32 nEndPosition(0);
+ sal_Int32 nStartColumn;
+ sal_Int32 nEndColumn;
+ sal_Int32 nStartRow;
+ sal_Int32 nEndRow;
+ sal_Int32 nStartSheet;
+ sal_Int32 nEndSheet;
+ const ScBigRange& rBigRange = pConstAction->GetBigRange();
+ rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
+ nEndColumn, nEndRow, nEndSheet);
+ switch (pConstAction->GetType())
+ {
+ case SC_CAT_INSERT_COLS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
+ nStartPosition = nStartColumn;
+ nEndPosition = nEndColumn;
+ }
+ break;
+ case SC_CAT_INSERT_ROWS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
+ nStartPosition = nStartRow;
+ nEndPosition = nEndRow;
+ }
+ break;
+ case SC_CAT_INSERT_TABS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
+ nStartPosition = nStartSheet;
+ nEndPosition = nEndSheet;
+ }
+ break;
+ default :
+ {
+ DBG_ERROR("wrong insertion type");
+ }
+ break;
+ }
+ nPosition = nStartPosition;
+ nCount = nEndPosition - nStartPosition + 1;
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nPosition);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ DBG_ASSERT(nCount > 0, "wrong insertion count");
+ if (nCount > 1)
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, nCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNT, sBuffer.makeStringAndClear());
+ }
+ if (pConstAction->GetType() != SC_CAT_INSERT_TABS)
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteInsertion(ScChangeAction* pAction)
+{
+ AddInsertionAttributes(pAction);
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_INSERTION, sal_True, sal_True);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+}
+
+void ScChangeTrackingExportHelper::AddDeletionAttributes(const ScChangeActionDel* pDelAction, const ScChangeActionDel* /* pLastAction */)
+{
+ sal_Int32 nPosition(0);
+ const ScBigRange& rBigRange = pDelAction->GetBigRange();
+ sal_Int32 nStartColumn(0);
+ sal_Int32 nEndColumn(0);
+ sal_Int32 nStartRow(0);
+ sal_Int32 nEndRow(0);
+ sal_Int32 nStartSheet(0);
+ sal_Int32 nEndSheet(0);
+ rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
+ nEndColumn, nEndRow, nEndSheet);
+ switch (pDelAction->GetType())
+ {
+ case SC_CAT_DELETE_COLS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
+ nPosition = nStartColumn;
+ }
+ break;
+ case SC_CAT_DELETE_ROWS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
+ nPosition = nStartRow;
+ }
+ break;
+ case SC_CAT_DELETE_TABS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
+ nPosition = nStartSheet;
+ //DBG_ERROR("not implemented feature");
+ }
+ break;
+ default :
+ {
+ DBG_ERROR("wrong deletion type");
+ }
+ break;
+ }
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nPosition);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ if (pDelAction->GetType() != SC_CAT_DELETE_TABS)
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
+ if (pDelAction->IsMultiDelete() && !pDelAction->GetDx() && !pDelAction->GetDy())
+ {
+ const ScChangeAction* p = pDelAction->GetNext();
+ sal_Bool bAll(sal_False);
+ sal_Int32 nSlavesCount (1);
+ while (!bAll && p)
+ {
+ if ( !p || p->GetType() != pDelAction->GetType() )
+ bAll = sal_True;
+ else
+ {
+ const ScChangeActionDel* pDel = (const ScChangeActionDel*) p;
+ if ( (pDel->GetDx() > pDelAction->GetDx() || pDel->GetDy() > pDelAction->GetDy()) &&
+ pDel->GetBigRange() == pDelAction->GetBigRange() )
+ {
+ ++nSlavesCount;
+ p = p->GetNext();
+ }
+ else
+ bAll = sal_True;
+ }
+ }
+
+ SvXMLUnitConverter::convertNumber(sBuffer, nSlavesCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MULTI_DELETION_SPANNED, sBuffer.makeStringAndClear());
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteCutOffs(const ScChangeActionDel* pAction)
+{
+ const ScChangeActionIns* pCutOffIns = pAction->GetCutOffInsert();
+ const ScChangeActionDelMoveEntry* pLinkMove = pAction->GetFirstMoveEntry();
+ if (pCutOffIns || pLinkMove)
+ {
+ SvXMLElementExport aCutOffsElem (rExport, XML_NAMESPACE_TABLE, XML_CUT_OFFS, sal_True, sal_True);
+ rtl::OUStringBuffer sBuffer;
+ if (pCutOffIns)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pCutOffIns->GetActionNumber()));
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pAction->GetCutOffCount()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ SvXMLElementExport aInsertCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_INSERTION_CUT_OFF, sal_True, sal_True);
+ }
+ while (pLinkMove)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pLinkMove->GetAction()->GetActionNumber()));
+ if (pLinkMove->GetCutOffFrom() == pLinkMove->GetCutOffTo())
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ }
+ else
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_POSITION, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffTo()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_POSITION, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aMoveCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT_CUT_OFF, sal_True, sal_True);
+ pLinkMove = pLinkMove->GetNext();
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteDeletion(ScChangeAction* pAction)
+{
+ ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction);
+ AddDeletionAttributes(pDelAction, pDelAction);
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_DELETION, sal_True, sal_True);
+ WriteChangeInfo(pDelAction);
+ WriteDependings(pDelAction);
+ WriteCutOffs(pDelAction);
+}
+
+void ScChangeTrackingExportHelper::WriteMovement(ScChangeAction* pAction)
+{
+ const ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction);
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT, sal_True, sal_True);
+ WriteBigRange(pMoveAction->GetFromRange(), XML_SOURCE_RANGE_ADDRESS);
+ WriteBigRange(pMoveAction->GetBigRange(), XML_TARGET_RANGE_ADDRESS);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+}
+
+void ScChangeTrackingExportHelper::WriteRejection(ScChangeAction* pAction)
+{
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_REJECTION, sal_True, sal_True);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+}
+
+void ScChangeTrackingExportHelper::CollectCellAutoStyles(const ScBaseCell* pBaseCell)
+{
+ if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_EDIT))
+ {
+ const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pBaseCell);
+ if (pEditCell)
+ {
+ if (!pEditTextObj)
+ {
+ pEditTextObj = new ScEditEngineTextObj();
+ xText.set(pEditTextObj);
+ }
+ pEditTextObj->SetText(*(pEditCell->GetData()));
+ if (xText.is())
+ rExport.GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False);
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::CollectActionAutoStyles(ScChangeAction* pAction)
+{
+ if (pAction->GetType() == SC_CAT_CONTENT)
+ {
+ if (pChangeTrack->IsGenerated(pAction->GetActionNumber()))
+ CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
+ else
+ {
+ CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetOldCell());
+ if (static_cast<ScChangeActionContent*>(pAction)->IsTopContent() && pAction->IsDeletedIn())
+ CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WorkWithChangeAction(ScChangeAction* pAction)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pAction->GetActionNumber()));
+ GetAcceptanceState(pAction);
+ if (pAction->IsRejecting())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REJECTING_CHANGE_ID, GetChangeID(pAction->GetRejectAction()));
+ if (pAction->GetType() == SC_CAT_CONTENT)
+ WriteContentChange(pAction);
+ else if (pAction->IsInsertType())
+ WriteInsertion(pAction);
+ else if (pAction->IsDeleteType())
+ WriteDeletion(pAction);
+ else if (pAction->GetType() == SC_CAT_MOVE)
+ WriteMovement(pAction);
+ else if (pAction->GetType() == SC_CAT_REJECT)
+ WriteRejection(pAction);
+ else
+ {
+ DBG_ERROR("not a writeable type");
+ }
+ rExport.CheckAttrList();
+}
+
+void ScChangeTrackingExportHelper::CollectAutoStyles()
+{
+ if (pChangeTrack)
+ {
+ sal_uInt32 nCount (pChangeTrack->GetActionMax());
+ if (nCount)
+ {
+ ScChangeAction* pAction = pChangeTrack->GetFirst();
+ CollectActionAutoStyles(pAction);
+ ScChangeAction* pLastAction = pChangeTrack->GetLast();
+ while (pAction != pLastAction)
+ {
+ pAction = pAction->GetNext();
+ CollectActionAutoStyles(pAction);
+ }
+ pAction = pChangeTrack->GetFirstGenerated();
+ while (pAction)
+ {
+ CollectActionAutoStyles(pAction);
+ pAction = pAction->GetNext();
+ }
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::CollectAndWriteChanges()
+{
+ if (pChangeTrack)
+ {
+/* if (pChangeTrack->IsProtected())
+ {
+ rtl::OUStringBuffer aBuffer;
+ SvXMLUnitConverter::encodeBase64(aBuffer, pChangeTrack->GetProtection());
+ if (aBuffer.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
+ }*/
+ SvXMLElementExport aCangeListElem(rExport, XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, sal_True, sal_True);
+ {
+ ScChangeAction* pAction = pChangeTrack->GetFirst();
+ if (pAction)
+ {
+ WorkWithChangeAction(pAction);
+ ScChangeAction* pLastAction = pChangeTrack->GetLast();
+ while (pAction != pLastAction)
+ {
+ pAction = pAction->GetNext();
+ WorkWithChangeAction(pAction);
+ }
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx
new file mode 100644
index 000000000000..f07f0ed905a0
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCHANGETRACKINGEXPORTHELPER_HXX
+#define SC_XMLCHANGETRACKINGEXPORTHELPER_HXX
+
+#include <xmloff/xmltoken.hxx>
+#include <list>
+#include <com/sun/star/text/XText.hpp>
+#include <rtl/ustrbuf.hxx>
+
+class ScChangeAction;
+class ScChangeTrack;
+class ScXMLExport;
+class ScBaseCell;
+class ScChangeActionDel;
+class ScBigRange;
+class ScEditEngineTextObj;
+class ScChangeActionTable;
+class String;
+class DateTime;
+
+typedef std::list<ScChangeActionDel*> ScMyDeletionsList;
+
+class ScChangeTrackingExportHelper
+{
+ ScXMLExport& rExport;
+
+ ScChangeTrack* pChangeTrack;
+ ScEditEngineTextObj* pEditTextObj;
+ ScChangeActionTable* pDependings;
+ rtl::OUString sChangeIDPrefix;
+ com::sun::star::uno::Reference<com::sun::star::text::XText> xText;
+
+ rtl::OUString GetChangeID(const sal_uInt32 nActionNumber);
+ void GetAcceptanceState(const ScChangeAction* pAction);
+
+ void WriteBigRange(const ScBigRange& rBigRange, xmloff::token::XMLTokenEnum aName);
+ void WriteChangeInfo(const ScChangeAction* pAction);
+ void WriteGenerated(const ScChangeAction* pDependAction);
+ void WriteDeleted(const ScChangeAction* pDependAction);
+ void WriteDepending(const ScChangeAction* pDependAction);
+ void WriteDependings(ScChangeAction* pAction);
+
+ void WriteEmptyCell();
+ void SetValueAttributes(const double& fValue, const String& sValue);
+ void WriteValueCell(const ScBaseCell* pCell, const String& sValue);
+ void WriteStringCell(const ScBaseCell* pCell);
+ void WriteEditCell(const ScBaseCell* pCell);
+ void WriteFormulaCell(const ScBaseCell* pCell, const String& sValue);
+ void WriteCell(const ScBaseCell* pCell, const String& sValue);
+
+ void WriteContentChange(ScChangeAction* pAction);
+ void AddInsertionAttributes(const ScChangeAction* pAction);
+ void WriteInsertion(ScChangeAction* pAction);
+ void AddDeletionAttributes(const ScChangeActionDel* pAction, const ScChangeActionDel* pLastAction);
+ void WriteDeletionCells(ScChangeActionDel* pAction);
+ void WriteCutOffs(const ScChangeActionDel* pAction);
+ void WriteDeletion(ScChangeAction* pAction);
+ void WriteMovement(ScChangeAction* pAction);
+ void WriteRejection(ScChangeAction* pAction);
+
+ void CollectCellAutoStyles(const ScBaseCell* pBaseCell);
+ void CollectActionAutoStyles(ScChangeAction* pAction);
+ void WorkWithChangeAction(ScChangeAction* pAction);
+public:
+ ScChangeTrackingExportHelper(ScXMLExport& rExport);
+ ~ScChangeTrackingExportHelper();
+
+ void CollectAutoStyles();
+ void CollectAndWriteChanges();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx
new file mode 100644
index 000000000000..d928444dd8ce
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx
@@ -0,0 +1,935 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLChangeTrackingImportHelper.hxx"
+#include "XMLConverter.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "chgviset.hxx"
+#include "rangeutl.hxx"
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <svl/zforlist.hxx>
+#include <xmloff/xmluconv.hxx>
+
+#define SC_CHANGE_ID_PREFIX "ct"
+
+ScMyCellInfo::ScMyCellInfo()
+ : pCell(NULL),
+ sFormulaAddress(),
+ sFormula(),
+ sInputString(),
+ fValue(0.0),
+ nMatrixCols(0),
+ nMatrixRows(0),
+ eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
+ nType(NUMBERFORMAT_ALL),
+ nMatrixFlag(MM_NONE)
+{
+}
+
+ScMyCellInfo::ScMyCellInfo(ScBaseCell* pTempCell, const rtl::OUString& rFormulaAddress, const rtl::OUString& rFormula,
+ const formula::FormulaGrammar::Grammar eTempGrammar, const rtl::OUString& rInputString,
+ const double& rValue, const sal_uInt16 nTempType, const sal_uInt8 nTempMatrixFlag, const sal_Int32 nTempMatrixCols,
+ const sal_Int32 nTempMatrixRows)
+ : pCell(pTempCell),
+ sFormulaAddress(rFormulaAddress),
+ sFormula(rFormula),
+ sInputString(rInputString),
+ fValue(rValue),
+ nMatrixCols(nTempMatrixCols),
+ nMatrixRows(nTempMatrixRows),
+ eGrammar( eTempGrammar),
+ nType(nTempType),
+ nMatrixFlag(nTempMatrixFlag)
+{
+}
+
+ScMyCellInfo::~ScMyCellInfo()
+{
+ if (pCell)
+ pCell->Delete();
+}
+
+ScBaseCell* ScMyCellInfo::CreateCell(ScDocument* pDoc)
+{
+ if (pDoc)
+ {
+ if (!pCell && sFormula.getLength() && sFormulaAddress.getLength())
+ {
+ ScAddress aPos;
+ sal_Int32 nOffset(0);
+ ScRangeStringConverter::GetAddressFromString(aPos, sFormulaAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset);
+ pCell = new ScFormulaCell(pDoc, aPos, sFormula, eGrammar, nMatrixFlag);
+ static_cast<ScFormulaCell*>(pCell)->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows));
+ }
+
+ if ((nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME) && sInputString.Len() == 0)
+ {
+ sal_uInt32 nFormat(0);
+ if (nType == NUMBERFORMAT_DATE)
+ nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge );
+ else if (nType == NUMBERFORMAT_TIME)
+ nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_TIME, ScGlobal::eLnge );
+ pDoc->GetFormatTable()->GetInputLineString(fValue, nFormat, sInputString);
+ }
+ }
+
+ return pCell ? pCell->CloneWithoutNote( *pDoc ) : 0;
+}
+
+ScMyDeleted::ScMyDeleted()
+ : pCellInfo(NULL)
+{
+}
+
+ScMyDeleted::~ScMyDeleted()
+{
+ if (pCellInfo)
+ delete pCellInfo;
+}
+
+ScMyGenerated::ScMyGenerated(ScMyCellInfo* pTempCellInfo, const ScBigRange& aTempBigRange)
+ : aBigRange(aTempBigRange),
+ nID(0),
+ pCellInfo(pTempCellInfo)
+{
+}
+
+ScMyGenerated::~ScMyGenerated()
+{
+ if (pCellInfo)
+ delete pCellInfo;
+}
+
+ScMyBaseAction::ScMyBaseAction(const ScChangeActionType nTempActionType)
+ : aDependencies(),
+ aDeletedList(),
+ nActionNumber(0),
+ nRejectingNumber(0),
+ nPreviousAction(0),
+ nActionType(nTempActionType),
+ nActionState(SC_CAS_VIRGIN)
+{
+}
+
+ScMyBaseAction::~ScMyBaseAction()
+{
+}
+
+ScMyInsAction::ScMyInsAction(const ScChangeActionType nActionTypeP)
+ : ScMyBaseAction(nActionTypeP)
+{
+}
+
+ScMyInsAction::~ScMyInsAction()
+{
+}
+
+ScMyDelAction::ScMyDelAction(const ScChangeActionType nActionTypeP)
+ : ScMyBaseAction(nActionTypeP),
+ aGeneratedList(),
+ pInsCutOff(NULL),
+ aMoveCutOffs(),
+ nD(0)
+{
+}
+
+ScMyDelAction::~ScMyDelAction()
+{
+ if (pInsCutOff)
+ delete pInsCutOff;
+}
+
+ScMyMoveAction::ScMyMoveAction()
+ : ScMyBaseAction(SC_CAT_MOVE),
+ aGeneratedList(),
+ pMoveRanges(NULL)
+{
+}
+
+ScMyMoveAction::~ScMyMoveAction()
+{
+ if (pMoveRanges)
+ delete pMoveRanges;
+}
+
+
+ScMyContentAction::ScMyContentAction()
+ : ScMyBaseAction(SC_CAT_CONTENT),
+ pCellInfo(NULL)
+{
+}
+
+ScMyContentAction::~ScMyContentAction()
+{
+ if (pCellInfo)
+ delete pCellInfo;
+}
+
+ScMyRejAction::ScMyRejAction()
+ : ScMyBaseAction(SC_CAT_REJECT)
+{
+}
+
+ScMyRejAction::~ScMyRejAction()
+{
+}
+
+ScXMLChangeTrackingImportHelper::ScXMLChangeTrackingImportHelper()
+ : aUsers(),
+ aActions(),
+ pDoc(NULL),
+ pTrack(NULL),
+ pCurrentAction(NULL),
+ sIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX)),
+ nMultiSpanned(0),
+ nMultiSpannedSlaveCount(0),
+ bChangeTrack(sal_False)
+{
+ nPrefixLength = sIDPrefix.getLength();
+}
+
+ScXMLChangeTrackingImportHelper::~ScXMLChangeTrackingImportHelper()
+{
+}
+
+void ScXMLChangeTrackingImportHelper::StartChangeAction(const ScChangeActionType nActionType)
+{
+ DBG_ASSERT(!pCurrentAction, "a not inserted action");
+ switch (nActionType)
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ {
+ pCurrentAction = new ScMyInsAction(nActionType);
+ }
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ pCurrentAction = new ScMyDelAction(nActionType);
+ }
+ break;
+ case SC_CAT_MOVE:
+ {
+ pCurrentAction = new ScMyMoveAction();
+ }
+ break;
+ case SC_CAT_CONTENT:
+ {
+ pCurrentAction = new ScMyContentAction();
+ }
+ break;
+ case SC_CAT_REJECT:
+ {
+ pCurrentAction = new ScMyRejAction();
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+sal_uInt32 ScXMLChangeTrackingImportHelper::GetIDFromString(const rtl::OUString& sID)
+{
+ sal_uInt32 nResult(0);
+ sal_uInt32 nLength(sID.getLength());
+ if (nLength)
+ {
+ if (sID.compareTo(sIDPrefix, nPrefixLength) == 0)
+ {
+ rtl::OUString sValue(sID.copy(nPrefixLength, nLength - nPrefixLength));
+ sal_Int32 nValue;
+ SvXMLUnitConverter::convertNumber(nValue, sValue);
+ DBG_ASSERT(nValue > 0, "wrong change action ID");
+ nResult = nValue;
+ }
+ else
+ {
+ DBG_ERROR("wrong change action ID");
+ }
+ }
+ return nResult;
+}
+
+void ScXMLChangeTrackingImportHelper::SetActionInfo(const ScMyActionInfo& aInfo)
+{
+ pCurrentAction->aInfo = aInfo;
+ String aUser(aInfo.sUser);
+ StrData* pStrData = new StrData( aUser );
+ if ( !aUsers.Insert( pStrData ) )
+ delete pStrData;
+}
+
+void ScXMLChangeTrackingImportHelper::SetPreviousChange(const sal_uInt32 nPreviousAction,
+ ScMyCellInfo* pCellInfo)
+{
+ DBG_ASSERT(pCurrentAction->nActionType == SC_CAT_CONTENT, "wrong action type");
+ ScMyContentAction* pAction = static_cast<ScMyContentAction*>(pCurrentAction);
+ pAction->nPreviousAction = nPreviousAction;
+ pAction->pCellInfo = pCellInfo;
+}
+
+void ScXMLChangeTrackingImportHelper::SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable)
+{
+ DBG_ASSERT(((pCurrentAction->nActionType != SC_CAT_MOVE) &&
+ (pCurrentAction->nActionType != SC_CAT_CONTENT) &&
+ (pCurrentAction->nActionType != SC_CAT_REJECT)), "wrong action type");
+ DBG_ASSERT(nCount > 0, "wrong count");
+ switch(pCurrentAction->nActionType)
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_DELETE_COLS:
+ {
+ pCurrentAction->aBigRange.Set(nPosition, nInt32Min, nTable,
+ nPosition + nCount - 1, nInt32Max, nTable);
+ }
+ break;
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_DELETE_ROWS:
+ {
+ pCurrentAction->aBigRange.Set(nInt32Min, nPosition, nTable,
+ nInt32Max, nPosition + nCount - 1, nTable);
+ }
+ break;
+ case SC_CAT_INSERT_TABS:
+ case SC_CAT_DELETE_TABS:
+ {
+ pCurrentAction->aBigRange.Set(nInt32Min, nInt32Min, nPosition,
+ nInt32Max, nInt32Max, nPosition + nCount - 1);
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID)
+{
+ ScMyDeleted* pDeleted = new ScMyDeleted();
+ pDeleted->nID = nID;
+ pCurrentAction->aDeletedList.push_front(pDeleted);
+}
+
+void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo)
+{
+ ScMyDeleted* pDeleted = new ScMyDeleted();
+ pDeleted->nID = nID;
+ pDeleted->pCellInfo = pCellInfo;
+ pCurrentAction->aDeletedList.push_front(pDeleted);
+}
+
+void ScXMLChangeTrackingImportHelper::SetMultiSpanned(const sal_Int16 nTempMultiSpanned)
+{
+ if (nTempMultiSpanned)
+ {
+ DBG_ASSERT(((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)), "wrong action type");
+ nMultiSpanned = nTempMultiSpanned;
+ nMultiSpannedSlaveCount = 0;
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition)
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->pInsCutOff = new ScMyInsertionCutOff(nID, nPosition);
+ }
+ else
+ {
+ DBG_ERROR("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition)
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->aMoveCutOffs.push_front(ScMyMoveCutOff(nID, nStartPosition, nEndPosition));
+ }
+ else
+ {
+ DBG_ERROR("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange)
+{
+ if (pCurrentAction->nActionType == SC_CAT_MOVE)
+ {
+ static_cast<ScMyMoveAction*>(pCurrentAction)->pMoveRanges = new ScMyMoveRanges(aSourceRange, aTargetRange);
+ }
+ else
+ {
+ DBG_ERROR("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::GetMultiSpannedRange()
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ if (nMultiSpannedSlaveCount)
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->nD = nMultiSpannedSlaveCount;
+ }
+ ++nMultiSpannedSlaveCount;
+ if (nMultiSpannedSlaveCount >= nMultiSpanned)
+ {
+ nMultiSpanned = 0;
+ nMultiSpannedSlaveCount = 0;
+ }
+ }
+ else
+ {
+ DBG_ERROR("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange)
+{
+ ScMyGenerated* pGenerated = new ScMyGenerated(pCellInfo, aBigRange);
+ if (pCurrentAction->nActionType == SC_CAT_MOVE)
+ {
+ static_cast<ScMyMoveAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated);
+ }
+ else if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated);
+ }
+ else
+ {
+ DBG_ERROR("try to insert a generated action to a wrong action");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::EndChangeAction()
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ GetMultiSpannedRange();
+ if (pCurrentAction && pCurrentAction->nActionNumber > 0)
+ aActions.push_back(pCurrentAction);
+ else
+ {
+ DBG_ERROR("no current action");
+ }
+ pCurrentAction = NULL;
+}
+
+void ScXMLChangeTrackingImportHelper::ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime)
+{
+ Date aDate(aInfo.aDateTime.Day, aInfo.aDateTime.Month, aInfo.aDateTime.Year);
+ Time aTime(aInfo.aDateTime.Hours, aInfo.aDateTime.Minutes, aInfo.aDateTime.Seconds, aInfo.aDateTime.HundredthSeconds);
+ aDateTime.SetDate( aDate.GetDate() );
+ aDateTime.SetTime( aTime.GetTime() );
+
+ // #97286# old files didn't store 100th seconds, enable again
+ if ( aInfo.aDateTime.HundredthSeconds )
+ pTrack->SetTime100thSeconds( TRUE );
+
+ StrData aStrData( aInfo.sUser );
+ USHORT nPos;
+ if ( pTrack->GetUserCollection().Search( &aStrData, nPos ) )
+ {
+ const StrData* pUser = static_cast<const StrData*>( pTrack->GetUserCollection().At( nPos ) );
+ if ( pUser )
+ rUser = pUser->GetString();
+ else
+ rUser = aInfo.sUser; // shouldn't happen
+ }
+ else
+ rUser = aInfo.sUser; // shouldn't happen
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateInsertAction(ScMyInsAction* pAction)
+{
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionIns(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType);
+ return pNewAction;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateDeleteAction(ScMyDelAction* pAction)
+{
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionDel(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType, pAction->nD, pTrack);
+ return pNewAction;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateMoveAction(ScMyMoveAction* pAction)
+{
+ DBG_ASSERT(pAction->pMoveRanges, "no move ranges");
+ if (pAction->pMoveRanges)
+ {
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionMove(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->pMoveRanges->aTargetRange, aUser, aDateTime, sComment, pAction->pMoveRanges->aSourceRange , pTrack);
+ return pNewAction;
+ }
+ return NULL;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateRejectionAction(ScMyRejAction* pAction)
+{
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionReject(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment);
+ return pNewAction;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateContentAction(ScMyContentAction* pAction)
+{
+ ScBaseCell* pCell = NULL;
+ if (pAction->pCellInfo)
+ pCell = pAction->pCellInfo->CreateCell(pDoc);
+
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionContent(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment, pCell, pDoc, pAction->pCellInfo->sInputString);
+ return pNewAction;
+}
+
+void ScXMLChangeTrackingImportHelper::CreateGeneratedActions(ScMyGeneratedList& rList)
+{
+ if (!rList.empty())
+ {
+ ScMyGeneratedList::iterator aItr(rList.begin());
+ ScMyGeneratedList::iterator aEndItr(rList.end());
+ while (aItr != aEndItr)
+ {
+ if (((*aItr)->nID == 0))
+ {
+ ScBaseCell* pCell = NULL;
+ if ((*aItr)->pCellInfo)
+ pCell = (*aItr)->pCellInfo->CreateCell(pDoc);
+
+ if (pCell)
+ {
+ (*aItr)->nID = pTrack->AddLoadedGenerated(pCell, (*aItr)->aBigRange, (*aItr)->pCellInfo->sInputString );
+ DBG_ASSERT((*aItr)->nID, "could not insert generated action");
+ }
+ }
+ ++aItr;
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct)
+{
+ if (!pAction->aGeneratedList.empty())
+ {
+ DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
+ (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
+ if (pDelAct)
+ {
+ ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin());
+ ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end());
+ while (aItr != aEndItr)
+ {
+ DBG_ASSERT((*aItr)->nID, "a not inserted generated action");
+ pDelAct->SetDeletedInThis((*aItr)->nID, pTrack);
+ if (*aItr)
+ delete *aItr;
+ aItr = pAction->aGeneratedList.erase(aItr);
+ }
+ }
+ }
+ if (pAction->pInsCutOff)
+ {
+ DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
+ (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
+ ScChangeAction* pChangeAction = pTrack->GetAction(pAction->pInsCutOff->nID);
+ if (pChangeAction && pChangeAction->IsInsertType())
+ {
+ ScChangeActionIns* pInsAction = static_cast<ScChangeActionIns*>(pChangeAction);
+ if (pInsAction && pDelAct)
+ pDelAct->SetCutOffInsert(pInsAction, static_cast<sal_Int16>(pAction->pInsCutOff->nPosition));
+ }
+ else
+ {
+ DBG_ERROR("no cut off insert action");
+ }
+ }
+ if (!pAction->aMoveCutOffs.empty())
+ {
+ DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
+ (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
+ ScMyMoveCutOffs::iterator aItr(pAction->aMoveCutOffs.begin());
+ ScMyMoveCutOffs::iterator aEndItr(pAction->aMoveCutOffs.end());
+ while(aItr != aEndItr)
+ {
+ ScChangeAction* pChangeAction = pTrack->GetAction(aItr->nID);
+ if (pChangeAction && (pChangeAction->GetType() == SC_CAT_MOVE))
+ {
+ ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*>(pChangeAction);
+ if (pMoveAction && pDelAct)
+ pDelAct->AddCutOffMove(pMoveAction, static_cast<sal_Int16>(aItr->nStartPosition),
+ static_cast<sal_Int16>(aItr->nEndPosition));
+ }
+ else
+ {
+ DBG_ERROR("no cut off move action");
+ }
+ aItr = pAction->aMoveCutOffs.erase(aItr);
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct)
+{
+ if (!pAction->aGeneratedList.empty())
+ {
+ if (pAction->nActionType == SC_CAT_MOVE)
+ {
+ if (pMoveAct)
+ {
+ ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin());
+ ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end());
+ while (aItr != aEndItr)
+ {
+ DBG_ASSERT((*aItr)->nID, "a not inserted generated action");
+ pMoveAct->SetDeletedInThis((*aItr)->nID, pTrack);
+ if (*aItr)
+ delete *aItr;
+ aItr = pAction->aGeneratedList.erase(aItr);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent)
+{
+ if (pAction->nPreviousAction)
+ {
+ DBG_ASSERT(pAction->nActionType == SC_CAT_CONTENT, "wrong action type");
+ ScChangeAction* pPrevAct = pTrack->GetAction(pAction->nPreviousAction);
+ if (pPrevAct)
+ {
+ ScChangeActionContent* pPrevActContent = static_cast<ScChangeActionContent*>(pPrevAct);
+ if (pPrevActContent && pActContent)
+ {
+ pActContent->SetPrevContent(pPrevActContent);
+ pPrevActContent->SetNextContent(pActContent);
+ const ScBaseCell* pOldCell = pActContent->GetOldCell();
+ if (pOldCell)
+ {
+ ScBaseCell* pNewCell = pOldCell->CloneWithoutNote( *pDoc );
+ if (pNewCell)
+ {
+ pPrevActContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING);
+ pPrevActContent->SetNewValue(pActContent->GetOldCell(), pDoc);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetDependencies(ScMyBaseAction* pAction)
+{
+ ScChangeAction* pAct = pTrack->GetAction(pAction->nActionNumber);
+ if (pAct)
+ {
+ if (!pAction->aDependencies.empty())
+ {
+ ScMyDependencies::iterator aItr(pAction->aDependencies.begin());
+ ScMyDependencies::iterator aEndItr(pAction->aDependencies.end());
+ while(aItr != aEndItr)
+ {
+ pAct->AddDependent(*aItr, pTrack);
+ aItr = pAction->aDependencies.erase(aItr);
+ }
+ }
+ if (!pAction->aDeletedList.empty())
+ {
+ ScMyDeletedList::iterator aItr(pAction->aDeletedList.begin());
+ ScMyDeletedList::iterator aEndItr(pAction->aDeletedList.end());
+ while(aItr != aEndItr)
+ {
+ pAct->SetDeletedInThis((*aItr)->nID, pTrack);
+ ScChangeAction* pDeletedAct = pTrack->GetAction((*aItr)->nID);
+ if ((pDeletedAct->GetType() == SC_CAT_CONTENT) && (*aItr)->pCellInfo)
+ {
+ ScChangeActionContent* pContentAct = static_cast<ScChangeActionContent*>(pDeletedAct);
+ if (pContentAct && (*aItr)->pCellInfo)
+ {
+ ScBaseCell* pCell = (*aItr)->pCellInfo->CreateCell(pDoc);
+ if (!ScBaseCell::CellEqual(pCell, pContentAct->GetNewCell()))
+ {
+ // #i40704# Don't overwrite SetNewCell result by calling SetNewValue,
+ // instead pass the input string to SetNewCell.
+ pContentAct->SetNewCell(pCell, pDoc, (*aItr)->pCellInfo->sInputString);
+ }
+ }
+ }
+ if (*aItr)
+ delete *aItr;
+ aItr = pAction->aDeletedList.erase(aItr);
+ }
+ }
+ if ((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS))
+ SetDeletionDependencies(static_cast<ScMyDelAction*>(pAction), static_cast<ScChangeActionDel*>(pAct));
+ else if (pAction->nActionType == SC_CAT_MOVE)
+ SetMovementDependencies(static_cast<ScMyMoveAction*>(pAction), static_cast<ScChangeActionMove*>(pAct));
+ else if (pAction->nActionType == SC_CAT_CONTENT)
+ SetContentDependencies(static_cast<ScMyContentAction*>(pAction), static_cast<ScChangeActionContent*>(pAct));
+ }
+ else
+ {
+ DBG_ERROR("could not find the action");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetNewCell(ScMyContentAction* pAction)
+{
+ ScChangeAction* pChangeAction = pTrack->GetAction(pAction->nActionNumber);
+ if (pChangeAction)
+ {
+ ScChangeActionContent* pChangeActionContent = static_cast<ScChangeActionContent*>(pChangeAction);
+ if (pChangeActionContent)
+ {
+ if (pChangeActionContent->IsTopContent() && !pChangeActionContent->IsDeletedIn())
+ {
+ sal_Int32 nCol, nRow, nTab, nCol2, nRow2, nTab2;
+ pAction->aBigRange.GetVars(nCol, nRow, nTab, nCol2, nRow2, nTab2);
+ if ((nCol >= 0) && (nCol <= MAXCOL) &&
+ (nRow >= 0) && (nRow <= MAXROW) &&
+ (nTab >= 0) && (nTab <= MAXTAB))
+ {
+ ScAddress aAddress (static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow),
+ static_cast<SCTAB>(nTab));
+ ScBaseCell* pCell = pDoc->GetCell(aAddress);
+ if (pCell)
+ {
+ ScBaseCell* pNewCell = NULL;
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ pNewCell = pCell->CloneWithoutNote( *pDoc );
+ else
+ {
+ sal_uInt8 nMatrixFlag = static_cast<ScFormulaCell*>(pCell)->GetMatrixFlag();
+ String sFormula;
+ // With GRAM_ODFF reference detection is faster on compilation.
+ /* FIXME: new cell should be created with a clone
+ * of the token array instead. Any reason why this
+ * wasn't done? */
+ static_cast<ScFormulaCell*>(pCell)->GetFormula(sFormula,formula::FormulaGrammar::GRAM_ODFF);
+ rtl::OUString sOUFormula(sFormula);
+
+ // #i87826# [Collaboration] Rejected move destroys formulas
+ // FIXME: adjust ScFormulaCell::GetFormula(), so that the right formula string
+ // is returned and no further string handling is necessary
+ rtl::OUString sOUFormula2;
+ if ( nMatrixFlag != MM_NONE )
+ {
+ sOUFormula2 = sOUFormula.copy( 2, sOUFormula.getLength() - 3 );
+ }
+ else
+ {
+ sOUFormula2 = sOUFormula.copy( 1, sOUFormula.getLength() - 1 );
+ }
+
+ String sFormula2(sOUFormula2);
+ pNewCell = new ScFormulaCell(pDoc, aAddress, sFormula2,formula::FormulaGrammar::GRAM_ODFF, nMatrixFlag);
+ if (pNewCell)
+ {
+ if (nMatrixFlag == MM_FORMULA)
+ {
+ SCCOL nCols;
+ SCROW nRows;
+ static_cast<ScFormulaCell*>(pCell)->GetMatColsRows(nCols, nRows);
+ static_cast<ScFormulaCell*>(pNewCell)->SetMatColsRows(nCols, nRows);
+ }
+ static_cast<ScFormulaCell*>(pNewCell)->SetInChangeTrack(sal_True);
+ }
+ }
+ pChangeActionContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING);
+ // #i40704# don't overwrite the formula string from above with pCell's content
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ pChangeActionContent->SetNewValue(pCell, pDoc);
+ }
+ }
+ else
+ {
+ DBG_ERROR("wrong cell position");
+ }
+ }
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pTempDoc)
+{
+ pDoc = pTempDoc;
+ if (pDoc)
+ {
+ pTrack = new ScChangeTrack(pDoc, aUsers);
+ // #97286# old files didn't store 100th seconds, disable until encountered
+ pTrack->SetTime100thSeconds( FALSE );
+
+ ScMyActions::iterator aItr(aActions.begin());
+ ScMyActions::iterator aEndItr(aActions.end());
+ while (aItr != aEndItr)
+ {
+ ScChangeAction* pAction = NULL;
+
+ switch ((*aItr)->nActionType)
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ {
+ pAction = CreateInsertAction(static_cast<ScMyInsAction*>(*aItr));
+ }
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ ScMyDelAction* pDelAct = static_cast<ScMyDelAction*>(*aItr);
+ pAction = CreateDeleteAction(pDelAct);
+ CreateGeneratedActions(pDelAct->aGeneratedList);
+ }
+ break;
+ case SC_CAT_MOVE:
+ {
+ ScMyMoveAction* pMovAct = static_cast<ScMyMoveAction*>(*aItr);
+ pAction = CreateMoveAction(pMovAct);
+ CreateGeneratedActions(pMovAct->aGeneratedList);
+ }
+ break;
+ case SC_CAT_CONTENT:
+ {
+ pAction = CreateContentAction(static_cast<ScMyContentAction*>(*aItr));
+ }
+ break;
+ case SC_CAT_REJECT:
+ {
+ pAction = CreateRejectionAction(static_cast<ScMyRejAction*>(*aItr));
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (pAction)
+ pTrack->AppendLoaded(pAction);
+ else
+ {
+ DBG_ERROR("no action");
+ }
+
+ ++aItr;
+ }
+ if (pTrack->GetLast())
+ pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber());
+
+ aItr = aActions.begin();
+ aEndItr = aActions.end();
+ while (aItr != aEndItr)
+ {
+ SetDependencies(*aItr);
+
+ if ((*aItr)->nActionType == SC_CAT_CONTENT)
+ ++aItr;
+ else
+ {
+ if (*aItr)
+ delete (*aItr);
+ aItr = aActions.erase(aItr);
+ }
+ }
+
+ aItr = aActions.begin();
+ aEndItr = aActions.end();
+ while (aItr != aEndItr)
+ {
+ DBG_ASSERT((*aItr)->nActionType == SC_CAT_CONTENT, "wrong action type");
+ SetNewCell(static_cast<ScMyContentAction*>(*aItr));
+ if (*aItr)
+ delete (*aItr);
+ aItr = aActions.erase(aItr);
+ }
+ if (aProtect.getLength())
+ pTrack->SetProtection(aProtect);
+ else if (pDoc->GetChangeTrack() && pDoc->GetChangeTrack()->IsProtected())
+ pTrack->SetProtection(pDoc->GetChangeTrack()->GetProtection());
+
+ if ( pTrack->GetLast() )
+ pTrack->SetLastSavedActionNumber(pTrack->GetLast()->GetActionNumber());
+
+ pDoc->SetChangeTrack(pTrack);
+ }
+}
diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx
new file mode 100644
index 000000000000..9857683b13ac
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx
@@ -0,0 +1,249 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCHANGETRACKINGIMPORTHELPER_HXX
+#define SC_XMLCHANGETRACKINGIMPORTHELPER_HXX
+
+#include "chgtrack.hxx"
+#include <list>
+#include <com/sun/star/util/DateTime.hpp>
+
+class ScBaseCell;
+class ScDocument;
+class DateTime;
+
+struct ScMyActionInfo
+{
+ rtl::OUString sUser;
+ rtl::OUString sComment;
+ com::sun::star::util::DateTime aDateTime;
+};
+
+struct ScMyCellInfo
+{
+ ScBaseCell* pCell;
+ rtl::OUString sFormulaAddress;
+ rtl::OUString sFormula;
+ String sInputString;
+ double fValue;
+ sal_Int32 nMatrixCols;
+ sal_Int32 nMatrixRows;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_uInt16 nType;
+ sal_uInt8 nMatrixFlag;
+
+ ScMyCellInfo(ScBaseCell* pCell, const rtl::OUString& sFormulaAddress, const rtl::OUString& sFormula,
+ const formula::FormulaGrammar::Grammar eGrammar, const rtl::OUString& sInputString,
+ const double& fValue, const sal_uInt16 nType, const sal_uInt8 nMatrixFlag, const sal_Int32 nMatrixCols,
+ const sal_Int32 nMatrixRows);
+ ~ScMyCellInfo();
+
+ ScBaseCell* CreateCell(ScDocument* pDoc);
+
+private:
+ ScMyCellInfo(); // disabled
+};
+
+struct ScMyDeleted
+{
+ sal_uInt32 nID;
+ ScMyCellInfo* pCellInfo;
+
+ ScMyDeleted();
+ ~ScMyDeleted();
+};
+
+typedef std::list<ScMyDeleted*> ScMyDeletedList;
+
+struct ScMyGenerated
+{
+ ScBigRange aBigRange;
+ sal_uInt32 nID;
+ ScMyCellInfo* pCellInfo;
+
+ ScMyGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange);
+ ~ScMyGenerated();
+};
+
+typedef std::list<ScMyGenerated*> ScMyGeneratedList;
+
+struct ScMyInsertionCutOff
+{
+ sal_uInt32 nID;
+ sal_Int32 nPosition;
+
+ ScMyInsertionCutOff(const sal_uInt32 nTempID, const sal_Int32 nTempPosition) :
+ nID(nTempID), nPosition(nTempPosition) {}
+};
+
+struct ScMyMoveCutOff
+{
+ sal_uInt32 nID;
+ sal_Int32 nStartPosition;
+ sal_Int32 nEndPosition;
+
+ ScMyMoveCutOff(const sal_uInt32 nTempID, const sal_Int32 nStartPos, const sal_Int32 nEndPos) :
+ nID(nTempID), nStartPosition(nStartPos), nEndPosition(nEndPos) {}
+};
+
+typedef std::list<ScMyMoveCutOff> ScMyMoveCutOffs;
+
+struct ScMyMoveRanges
+{
+ ScBigRange aSourceRange;
+ ScBigRange aTargetRange;
+
+ ScMyMoveRanges(const ScBigRange& aSource, const ScBigRange aTarget) :
+ aSourceRange(aSource), aTargetRange(aTarget) {}
+};
+
+typedef std::list<sal_uInt32> ScMyDependencies;
+
+struct ScMyBaseAction
+{
+ ScMyActionInfo aInfo;
+ ScBigRange aBigRange;
+ ScMyDependencies aDependencies;
+ ScMyDeletedList aDeletedList;
+ sal_uInt32 nActionNumber;
+ sal_uInt32 nRejectingNumber;
+ sal_uInt32 nPreviousAction;
+ ScChangeActionType nActionType;
+ ScChangeActionState nActionState;
+
+ ScMyBaseAction(const ScChangeActionType nActionType);
+ virtual ~ScMyBaseAction();
+};
+
+struct ScMyInsAction : public ScMyBaseAction
+{
+ ScMyInsAction(const ScChangeActionType nActionType);
+ ~ScMyInsAction();
+};
+
+struct ScMyDelAction : public ScMyBaseAction
+{
+ ScMyGeneratedList aGeneratedList;
+ ScMyInsertionCutOff* pInsCutOff;
+ ScMyMoveCutOffs aMoveCutOffs;
+ sal_Int32 nD;
+
+ ScMyDelAction(const ScChangeActionType nActionType);
+ ~ScMyDelAction();
+};
+
+struct ScMyMoveAction : public ScMyBaseAction
+{
+ ScMyGeneratedList aGeneratedList;
+ ScMyMoveRanges* pMoveRanges;
+
+ ScMyMoveAction();
+ ~ScMyMoveAction();
+};
+
+struct ScMyContentAction : public ScMyBaseAction
+{
+ ScMyCellInfo* pCellInfo;
+
+ ScMyContentAction();
+ ~ScMyContentAction();
+};
+
+struct ScMyRejAction : public ScMyBaseAction
+{
+ ScMyRejAction();
+ ~ScMyRejAction();
+};
+
+typedef std::list<ScMyBaseAction*> ScMyActions;
+
+class ScChangeViewSettings;
+
+class ScXMLChangeTrackingImportHelper
+{
+ ScStrCollection aUsers;
+ ScMyActions aActions;
+ com::sun::star::uno::Sequence<sal_Int8> aProtect;
+ ScDocument* pDoc;
+ ScChangeTrack* pTrack;
+ ScMyBaseAction* pCurrentAction;
+ rtl::OUString sIDPrefix;
+ sal_uInt32 nPrefixLength;
+ sal_Int16 nMultiSpanned;
+ sal_Int16 nMultiSpannedSlaveCount;
+ sal_Bool bChangeTrack;
+
+private:
+ void ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime);
+ ScChangeAction* CreateInsertAction(ScMyInsAction* pAction);
+ ScChangeAction* CreateDeleteAction(ScMyDelAction* pAction);
+ ScChangeAction* CreateMoveAction(ScMyMoveAction* pAction);
+ ScChangeAction* CreateRejectionAction(ScMyRejAction* pAction);
+ ScChangeAction* CreateContentAction(ScMyContentAction* pAction);
+
+ void CreateGeneratedActions(ScMyGeneratedList& rList);
+
+public:
+ ScXMLChangeTrackingImportHelper();
+ ~ScXMLChangeTrackingImportHelper();
+
+ void SetChangeTrack(sal_Bool bValue) { bChangeTrack = bValue; }
+ void SetProtection(const com::sun::star::uno::Sequence<sal_Int8>& rProtect) { aProtect = rProtect; }
+ void StartChangeAction(const ScChangeActionType nActionType);
+
+ sal_uInt32 GetIDFromString(const rtl::OUString& sID);
+
+ void SetActionNumber(const sal_uInt32 nActionNumber) { pCurrentAction->nActionNumber = nActionNumber; }
+ void SetActionState(const ScChangeActionState nActionState) { pCurrentAction->nActionState = nActionState; }
+ void SetRejectingNumber(const sal_uInt32 nRejectingNumber) { pCurrentAction->nRejectingNumber = nRejectingNumber; }
+ void SetActionInfo(const ScMyActionInfo& aInfo);
+ void SetBigRange(const ScBigRange& aBigRange) { pCurrentAction->aBigRange = aBigRange; }
+ void SetPreviousChange(const sal_uInt32 nPreviousAction, ScMyCellInfo* pCellInfo);
+ void SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable);
+ void AddDependence(const sal_uInt32 nID) { pCurrentAction->aDependencies.push_front(nID); }
+ void AddDeleted(const sal_uInt32 nID);
+ void AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo);
+ void SetMultiSpanned(const sal_Int16 nMultiSpanned);
+ void SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition);
+ void AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition);
+ void SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange);
+ void GetMultiSpannedRange();
+ void AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange);
+
+ void EndChangeAction();
+
+ void SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct);
+ void SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct);
+ void SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent);
+ void SetDependencies(ScMyBaseAction* pAction);
+
+ void SetNewCell(ScMyContentAction* pAction);
+
+ void CreateChangeTrack(ScDocument* pDoc);
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLCodeNameProvider.cxx b/sc/source/filter/xml/XMLCodeNameProvider.cxx
new file mode 100755
index 000000000000..ca4bac7eb511
--- /dev/null
+++ b/sc/source/filter/xml/XMLCodeNameProvider.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "XMLCodeNameProvider.hxx"
+#include "document.hxx"
+
+using namespace rtl;
+using namespace com::sun::star;
+
+sal_Bool XMLCodeNameProvider::_getCodeName( const uno::Any& aAny, String& rCodeName )
+{
+ uno::Sequence<beans::PropertyValue> aProps;
+ if( !(aAny >>= aProps) )
+ return sal_False;
+
+ OUString sCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") );
+ sal_Int32 nPropCount = aProps.getLength();
+ for( sal_Int32 i=0; i<nPropCount; i++ )
+ {
+ if( aProps[i].Name == sCodeNameProp )
+ {
+ OUString sCodeName;
+ if( aProps[i].Value >>= sCodeName )
+ {
+ rCodeName = sCodeName;
+ return sal_True;
+ }
+ }
+ }
+
+ return sal_False;
+}
+
+
+XMLCodeNameProvider::XMLCodeNameProvider( ScDocument* pDoc ) :
+ mpDoc( pDoc ),
+ msDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ),
+ msCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") )
+{
+}
+
+XMLCodeNameProvider::~XMLCodeNameProvider()
+{
+}
+
+::sal_Bool SAL_CALL XMLCodeNameProvider::hasByName( const OUString& aName )
+ throw (uno::RuntimeException )
+{
+ if( aName == msDocName )
+ return mpDoc->GetCodeName().Len() > 0;
+
+ SCTAB nCount = mpDoc->GetTableCount();
+ String sName( aName );
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ return sCodeName.Len() > 0;
+ }
+ }
+
+ return sal_False;
+}
+
+uno::Any SAL_CALL XMLCodeNameProvider::getByName( const OUString& aName )
+ throw (container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aRet;
+ uno::Sequence<beans::PropertyValue> aProps(1);
+ aProps[0].Name = msCodeNameProp;
+ if( aName == msDocName )
+ {
+ OUString sUCodeName( mpDoc->GetCodeName() );
+ aProps[0].Value <<= sUCodeName;
+ aRet <<= aProps;
+ return aRet;
+ }
+
+ SCTAB nCount = mpDoc->GetTableCount();
+ String sName( aName );
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ OUString sUCodeName( sCodeName );
+ aProps[0].Value <<= sUCodeName;
+ aRet <<= aProps;
+ return aRet;
+ }
+ }
+
+ return aRet;
+}
+
+uno::Sequence< OUString > SAL_CALL XMLCodeNameProvider::getElementNames( )
+ throw (uno::RuntimeException)
+{
+ SCTAB nCount = mpDoc->GetTableCount() + 1;
+ uno::Sequence< rtl::OUString > aNames( nCount );
+ sal_Int32 nRealCount = 0;
+
+ if( mpDoc->GetCodeName().Len() )
+ aNames[nRealCount++] = msDocName;
+
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ if( sCodeName.Len() > 0 )
+ {
+ if( mpDoc->GetName( i, sSheetName ) )
+ aNames[nRealCount++] = sSheetName;
+ }
+ }
+
+ if( nCount != nRealCount )
+ aNames.realloc( nRealCount );
+
+ return aNames;
+}
+
+uno::Type SAL_CALL XMLCodeNameProvider::getElementType( )
+ throw (uno::RuntimeException)
+{
+ return uno::Type();
+}
+
+::sal_Bool SAL_CALL XMLCodeNameProvider::hasElements()
+ throw (uno::RuntimeException )
+{
+ if( mpDoc->GetCodeName().Len() > 0 )
+ return sal_True;
+
+ SCTAB nCount = mpDoc->GetTableCount();
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ if( sCodeName.Len() > 0 && mpDoc->GetName( i, sSheetName ) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void XMLCodeNameProvider::set( const uno::Reference< container::XNameAccess>& xNameAccess, ScDocument *pDoc )
+{
+ uno::Any aAny;
+ OUString sDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") );
+ String sCodeName;
+ if( xNameAccess->hasByName( sDocName ) )
+ {
+ aAny = xNameAccess->getByName( sDocName );
+ if( _getCodeName( aAny, sCodeName ) )
+ pDoc->SetCodeName( sCodeName );
+ }
+
+ SCTAB nCount = pDoc->GetTableCount();
+ String sSheetName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ if( pDoc->GetName( i, sSheetName ) &&
+ xNameAccess->hasByName( sSheetName ) )
+ {
+ aAny = xNameAccess->getByName( sSheetName );
+ if( _getCodeName( aAny, sCodeName ) )
+ pDoc->SetCodeName( i, sCodeName );
+ }
+ }
+}
diff --git a/sc/source/filter/xml/XMLCodeNameProvider.hxx b/sc/source/filter/xml/XMLCodeNameProvider.hxx
new file mode 100755
index 000000000000..39d84409c555
--- /dev/null
+++ b/sc/source/filter/xml/XMLCodeNameProvider.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCODENAMEPROVIDER_HXX
+#define SC_XMLCODENAMEPROVIDER_HXX
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class ScDocument;
+class String;
+
+class XMLCodeNameProvider : public ::cppu::WeakImplHelper1< ::com::sun::star::container::XNameAccess >
+{
+ ScDocument* mpDoc;
+ ::rtl::OUString msDocName;
+ ::rtl::OUString msCodeNameProp;
+
+ static sal_Bool _getCodeName( const ::com::sun::star::uno::Any& aAny,
+ String& rCodeName );
+
+public:
+ XMLCodeNameProvider( ScDocument* pDoc );
+ virtual ~XMLCodeNameProvider();
+
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL hasElements()
+ throw (::com::sun::star::uno::RuntimeException );
+
+ static void set( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNameAccess, ScDocument *pDoc );
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLColumnRowGroupExport.cxx b/sc/source/filter/xml/XMLColumnRowGroupExport.cxx
new file mode 100644
index 000000000000..4c2929de02e3
--- /dev/null
+++ b/sc/source/filter/xml/XMLColumnRowGroupExport.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLColumnRowGroupExport.hxx"
+#include "xmlexprt.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+
+#include <algorithm>
+
+using namespace xmloff::token;
+
+ScMyColumnRowGroup::ScMyColumnRowGroup()
+{
+}
+
+sal_Bool ScMyColumnRowGroup::operator<(const ScMyColumnRowGroup& rGroup) const
+{
+ if (rGroup.nField > nField)
+ return sal_True;
+ else
+ if (rGroup.nField == nField && rGroup.nLevel > nLevel)
+ return sal_True;
+ else
+ return sal_False;
+}
+
+ScMyOpenCloseColumnRowGroup::ScMyOpenCloseColumnRowGroup(ScXMLExport& rTempExport, sal_uInt32 nToken)
+ : rExport(rTempExport),
+ rName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XMLTokenEnum(nToken)))),
+ aTableStart(),
+ aTableEnd()
+{
+}
+
+ScMyOpenCloseColumnRowGroup::~ScMyOpenCloseColumnRowGroup()
+{
+}
+
+void ScMyOpenCloseColumnRowGroup::NewTable()
+{
+ aTableStart.clear();
+ aTableEnd.clear();
+}
+
+void ScMyOpenCloseColumnRowGroup::AddGroup(const ScMyColumnRowGroup& aGroup, const sal_Int32 nEndField)
+{
+ aTableStart.push_back(aGroup);
+ aTableEnd.push_back(nEndField);
+}
+
+sal_Bool ScMyOpenCloseColumnRowGroup::IsGroupStart(const sal_Int32 nField)
+{
+ sal_Bool bGroupStart(sal_False);
+ if (!aTableStart.empty())
+ {
+ ScMyColumnRowGroupVec::iterator aItr(aTableStart.begin());
+ sal_Int32 nItrField = aItr->nField;
+ if ( nItrField < nField )
+ {
+ // #103327# when used to find repeated rows at the beginning of a group,
+ // aTableStart may contain entries before nField. They must be skipped here
+ // (they will be used for OpenGroups later in the right order).
+
+ ScMyColumnRowGroupVec::iterator aEnd(aTableStart.end());
+ while ( aItr != aEnd && nItrField < nField )
+ {
+ ++aItr;
+ if ( aItr != aEnd )
+ nItrField = aItr->nField;
+ }
+ }
+
+ if (nItrField == nField)
+ bGroupStart = sal_True;
+ }
+ return bGroupStart;
+}
+
+void ScMyOpenCloseColumnRowGroup::OpenGroup(const ScMyColumnRowGroup& rGroup)
+{
+ if (!rGroup.bDisplay)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
+ rExport.StartElement( rName, sal_True);
+}
+
+void ScMyOpenCloseColumnRowGroup::OpenGroups(const sal_Int32 nField)
+{
+ ScMyColumnRowGroupVec::iterator aItr(aTableStart.begin());
+ ScMyColumnRowGroupVec::iterator aEndItr(aTableStart.end());
+ sal_Bool bReady(sal_False);
+ while(!bReady && aItr != aEndItr)
+ {
+ if (aItr->nField == nField)
+ {
+ OpenGroup(*aItr);
+ aItr = aTableStart.erase(aItr);
+ }
+ else
+ bReady = sal_True;
+ }
+}
+
+sal_Bool ScMyOpenCloseColumnRowGroup::IsGroupEnd(const sal_Int32 nField)
+{
+ sal_Bool bGroupEnd(sal_False);
+ if (!aTableEnd.empty())
+ {
+ if (*(aTableEnd.begin()) == nField)
+ bGroupEnd = sal_True;
+ }
+ return bGroupEnd;
+}
+
+void ScMyOpenCloseColumnRowGroup::CloseGroup()
+{
+ rExport.EndElement( rName, sal_True );
+}
+
+void ScMyOpenCloseColumnRowGroup::CloseGroups(const sal_Int32 nField)
+{
+ ScMyFieldGroupVec::iterator aItr(aTableEnd.begin());
+ ScMyFieldGroupVec::iterator aEndItr(aTableEnd.end());
+ sal_Bool bReady(sal_False);
+ while(!bReady && aItr != aEndItr)
+ {
+ if (*aItr == nField)
+ {
+ CloseGroup();
+ aItr = aTableEnd.erase(aItr);
+ }
+ else
+ bReady = sal_True;
+ }
+}
+
+sal_Int32 ScMyOpenCloseColumnRowGroup::GetLast()
+{
+ sal_Int32 maximum(-1);
+ ScMyFieldGroupVec::iterator i(aTableEnd.begin());
+ ScMyFieldGroupVec::iterator endi(aTableEnd.end());
+ while (i != endi)
+ {
+ if (*i > maximum)
+ maximum = *i;
+ ++i;
+ }
+ return maximum;
+}
+
+void ScMyOpenCloseColumnRowGroup::Sort()
+{
+ aTableStart.sort();
+ aTableEnd.sort();
+}
+
diff --git a/sc/source/filter/xml/XMLColumnRowGroupExport.hxx b/sc/source/filter/xml/XMLColumnRowGroupExport.hxx
new file mode 100644
index 000000000000..51a93445ccfb
--- /dev/null
+++ b/sc/source/filter/xml/XMLColumnRowGroupExport.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCOLUMNROWGROUPEXPORT_HXX
+#define SC_XMLCOLUMNROWGROUPEXPORT_HXX
+
+#include <list>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+struct ScMyColumnRowGroup
+{
+ sal_Int32 nField;
+ sal_Int16 nLevel;
+ sal_Bool bDisplay;
+
+ ScMyColumnRowGroup();
+ sal_Bool operator< (const ScMyColumnRowGroup& rGroup) const;
+};
+
+typedef std::list <ScMyColumnRowGroup> ScMyColumnRowGroupVec;
+typedef std::list <sal_Int32> ScMyFieldGroupVec;
+
+class ScXMLExport;
+class ScMyOpenCloseColumnRowGroup
+{
+ ScXMLExport& rExport;
+ const rtl::OUString rName;
+ ScMyColumnRowGroupVec aTableStart;
+ ScMyFieldGroupVec aTableEnd;
+
+ void OpenGroup(const ScMyColumnRowGroup& rGroup);
+ void CloseGroup();
+public:
+ ScMyOpenCloseColumnRowGroup(ScXMLExport& rExport, sal_uInt32 nToken);
+ ~ScMyOpenCloseColumnRowGroup();
+
+ void NewTable();
+ void AddGroup(const ScMyColumnRowGroup& aGroup, const sal_Int32 nEndField);
+ sal_Bool IsGroupStart(const sal_Int32 nField);
+ void OpenGroups(const sal_Int32 nField);
+ sal_Bool IsGroupEnd(const sal_Int32 nField);
+ void CloseGroups(const sal_Int32 nField);
+ sal_Int32 GetLast();
+ void Sort();
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLConsolidationContext.cxx b/sc/source/filter/xml/XMLConsolidationContext.cxx
new file mode 100644
index 000000000000..0ca5fc360533
--- /dev/null
+++ b/sc/source/filter/xml/XMLConsolidationContext.cxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//___________________________________________________________________
+#include "XMLConsolidationContext.hxx"
+#include "document.hxx"
+#include "rangeutl.hxx"
+#include "xmlimprt.hxx"
+#include "XMLConverter.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScXMLConsolidationContext::ScXMLConsolidationContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ eFunction( SUBTOTAL_FUNC_NONE ),
+ bLinkToSource( sal_False ),
+ bTargetAddr(sal_False)
+{
+ rImport.LockSolarMutex();
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetConsolidationAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONSOLIDATION_ATTR_FUNCTION:
+ eFunction = ScXMLConverter::GetSubTotalFuncFromString( sValue );
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES:
+ sSourceList = sValue;
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS:
+ {
+ sal_Int32 nOffset(0);
+ bTargetAddr = ScRangeStringConverter::GetAddressFromString(
+ aTargetAddr, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset );
+ }
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_USE_LABEL:
+ sUseLabel = sValue;
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE:
+ bLinkToSource = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLConsolidationContext::~ScXMLConsolidationContext()
+{
+}
+
+SvXMLImportContext *ScXMLConsolidationContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLConsolidationContext::EndElement()
+{
+ if (bTargetAddr)
+ {
+ ScConsolidateParam aConsParam;
+ aConsParam.nCol = aTargetAddr.Col();
+ aConsParam.nRow = aTargetAddr.Row();
+ aConsParam.nTab = aTargetAddr.Tab();
+ aConsParam.eFunction = eFunction;
+
+ sal_Bool bError = sal_False;
+ USHORT nCount = (USHORT) Min( ScRangeStringConverter::GetTokenCount( sSourceList ), (sal_Int32)0xFFFF );
+ ScArea** ppAreas = nCount ? new ScArea*[ nCount ] : NULL;
+ if( ppAreas )
+ {
+ sal_Int32 nOffset = 0;
+ USHORT nIndex;
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ ppAreas[ nIndex ] = new ScArea;
+ if ( !ScRangeStringConverter::GetAreaFromString(
+ *ppAreas[ nIndex ], sSourceList, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ) )
+ {
+ bError = sal_True; //! handle error
+ }
+ }
+
+ aConsParam.SetAreas( ppAreas, nCount );
+
+ // array is copied in SetAreas
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ delete ppAreas[nIndex];
+ delete[] ppAreas;
+ }
+
+ aConsParam.bByCol = aConsParam.bByRow = FALSE;
+ if( IsXMLToken(sUseLabel, XML_COLUMN ) )
+ aConsParam.bByCol = TRUE;
+ else if( IsXMLToken( sUseLabel, XML_ROW ) )
+ aConsParam.bByRow = TRUE;
+ else if( IsXMLToken( sUseLabel, XML_BOTH ) )
+ aConsParam.bByCol = aConsParam.bByRow = TRUE;
+
+ aConsParam.bReferenceData = bLinkToSource;
+
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if( pDoc )
+ pDoc->SetConsolidateDlgData( &aConsParam );
+ }
+ GetScImport().UnlockSolarMutex();
+}
+
diff --git a/sc/source/filter/xml/XMLConsolidationContext.hxx b/sc/source/filter/xml/XMLConsolidationContext.hxx
new file mode 100644
index 000000000000..52061c715ae7
--- /dev/null
+++ b/sc/source/filter/xml/XMLConsolidationContext.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCONSOLIDATIONCONTEXT_HXX
+#define SC_XMLCONSOLIDATIONCONTEXT_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+class ScXMLConsolidationContext : public SvXMLImportContext
+{
+private:
+ ::rtl::OUString sSourceList;
+ ::rtl::OUString sUseLabel;
+ ScAddress aTargetAddr;
+ ScSubTotalFunc eFunction;
+ sal_Bool bLinkToSource;
+ sal_Bool bTargetAddr;
+
+protected:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLConsolidationContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual ~ScXMLConsolidationContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLConverter.cxx b/sc/source/filter/xml/XMLConverter.cxx
new file mode 100644
index 000000000000..4de6246f4f28
--- /dev/null
+++ b/sc/source/filter/xml/XMLConverter.cxx
@@ -0,0 +1,670 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "XMLConverter.hxx"
+#include <com/sun/star/util/DateTime.hpp>
+#include <tools/datetime.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "rangelst.hxx"
+#include "rangeutl.hxx"
+#include "docuno.hxx"
+#include "convuno.hxx"
+#include "document.hxx"
+#include "ftools.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScDocument* ScXMLConverter::GetScDocument( uno::Reference< frame::XModel > xModel )
+{
+ if (xModel.is())
+ {
+ ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
+ return pDocObj ? pDocObj->GetDocument() : NULL;
+ }
+ return NULL;
+}
+
+
+//___________________________________________________________________
+sheet::GeneralFunction ScXMLConverter::GetFunctionFromString( const OUString& sFunction )
+{
+ if( IsXMLToken(sFunction, XML_SUM ) )
+ return sheet::GeneralFunction_SUM;
+ if( IsXMLToken(sFunction, XML_AUTO ) )
+ return sheet::GeneralFunction_AUTO;
+ if( IsXMLToken(sFunction, XML_COUNT ) )
+ return sheet::GeneralFunction_COUNT;
+ if( IsXMLToken(sFunction, XML_COUNTNUMS ) )
+ return sheet::GeneralFunction_COUNTNUMS;
+ if( IsXMLToken(sFunction, XML_PRODUCT ) )
+ return sheet::GeneralFunction_PRODUCT;
+ if( IsXMLToken(sFunction, XML_AVERAGE ) )
+ return sheet::GeneralFunction_AVERAGE;
+ if( IsXMLToken(sFunction, XML_MAX ) )
+ return sheet::GeneralFunction_MAX;
+ if( IsXMLToken(sFunction, XML_MIN ) )
+ return sheet::GeneralFunction_MIN;
+ if( IsXMLToken(sFunction, XML_STDEV ) )
+ return sheet::GeneralFunction_STDEV;
+ if( IsXMLToken(sFunction, XML_STDEVP ) )
+ return sheet::GeneralFunction_STDEVP;
+ if( IsXMLToken(sFunction, XML_VAR ) )
+ return sheet::GeneralFunction_VAR;
+ if( IsXMLToken(sFunction, XML_VARP ) )
+ return sheet::GeneralFunction_VARP;
+ return sheet::GeneralFunction_NONE;
+}
+
+ScSubTotalFunc ScXMLConverter::GetSubTotalFuncFromString( const OUString& sFunction )
+{
+ if( IsXMLToken(sFunction, XML_SUM ) )
+ return SUBTOTAL_FUNC_SUM;
+ if( IsXMLToken(sFunction, XML_COUNT ) )
+ return SUBTOTAL_FUNC_CNT;
+ if( IsXMLToken(sFunction, XML_COUNTNUMS ) )
+ return SUBTOTAL_FUNC_CNT2;
+ if( IsXMLToken(sFunction, XML_PRODUCT ) )
+ return SUBTOTAL_FUNC_PROD;
+ if( IsXMLToken(sFunction, XML_AVERAGE ) )
+ return SUBTOTAL_FUNC_AVE;
+ if( IsXMLToken(sFunction, XML_MAX ) )
+ return SUBTOTAL_FUNC_MAX;
+ if( IsXMLToken(sFunction, XML_MIN ) )
+ return SUBTOTAL_FUNC_MIN;
+ if( IsXMLToken(sFunction, XML_STDEV ) )
+ return SUBTOTAL_FUNC_STD;
+ if( IsXMLToken(sFunction, XML_STDEVP ) )
+ return SUBTOTAL_FUNC_STDP;
+ if( IsXMLToken(sFunction, XML_VAR ) )
+ return SUBTOTAL_FUNC_VAR;
+ if( IsXMLToken(sFunction, XML_VARP ) )
+ return SUBTOTAL_FUNC_VARP;
+ return SUBTOTAL_FUNC_NONE;
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::GetStringFromFunction(
+ OUString& rString,
+ const sheet::GeneralFunction eFunction,
+ sal_Bool bAppendStr )
+{
+ OUString sFuncStr;
+ switch( eFunction )
+ {
+ case sheet::GeneralFunction_AUTO: sFuncStr = GetXMLToken( XML_AUTO ); break;
+ case sheet::GeneralFunction_AVERAGE: sFuncStr = GetXMLToken( XML_AVERAGE ); break;
+ case sheet::GeneralFunction_COUNT: sFuncStr = GetXMLToken( XML_COUNT ); break;
+ case sheet::GeneralFunction_COUNTNUMS: sFuncStr = GetXMLToken( XML_COUNTNUMS ); break;
+ case sheet::GeneralFunction_MAX: sFuncStr = GetXMLToken( XML_MAX ); break;
+ case sheet::GeneralFunction_MIN: sFuncStr = GetXMLToken( XML_MIN ); break;
+ case sheet::GeneralFunction_NONE: sFuncStr = GetXMLToken( XML_NONE ); break;
+ case sheet::GeneralFunction_PRODUCT: sFuncStr = GetXMLToken( XML_PRODUCT ); break;
+ case sheet::GeneralFunction_STDEV: sFuncStr = GetXMLToken( XML_STDEV ); break;
+ case sheet::GeneralFunction_STDEVP: sFuncStr = GetXMLToken( XML_STDEVP ); break;
+ case sheet::GeneralFunction_SUM: sFuncStr = GetXMLToken( XML_SUM ); break;
+ case sheet::GeneralFunction_VAR: sFuncStr = GetXMLToken( XML_VAR ); break;
+ case sheet::GeneralFunction_VARP: sFuncStr = GetXMLToken( XML_VARP ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRangeStringConverter::AssignString( rString, sFuncStr, bAppendStr );
+}
+
+void ScXMLConverter::GetStringFromFunction(
+ OUString& rString,
+ const ScSubTotalFunc eFunction,
+ sal_Bool bAppendStr )
+{
+ OUString sFuncStr;
+ switch( eFunction )
+ {
+ case SUBTOTAL_FUNC_AVE: sFuncStr = GetXMLToken( XML_AVERAGE ); break;
+ case SUBTOTAL_FUNC_CNT: sFuncStr = GetXMLToken( XML_COUNT ); break;
+ case SUBTOTAL_FUNC_CNT2: sFuncStr = GetXMLToken( XML_COUNTNUMS ); break;
+ case SUBTOTAL_FUNC_MAX: sFuncStr = GetXMLToken( XML_MAX ); break;
+ case SUBTOTAL_FUNC_MIN: sFuncStr = GetXMLToken( XML_MIN ); break;
+ case SUBTOTAL_FUNC_NONE: sFuncStr = GetXMLToken( XML_NONE ); break;
+ case SUBTOTAL_FUNC_PROD: sFuncStr = GetXMLToken( XML_PRODUCT ); break;
+ case SUBTOTAL_FUNC_STD: sFuncStr = GetXMLToken( XML_STDEV ); break;
+ case SUBTOTAL_FUNC_STDP: sFuncStr = GetXMLToken( XML_STDEVP ); break;
+ case SUBTOTAL_FUNC_SUM: sFuncStr = GetXMLToken( XML_SUM ); break;
+ case SUBTOTAL_FUNC_VAR: sFuncStr = GetXMLToken( XML_VAR ); break;
+ case SUBTOTAL_FUNC_VARP: sFuncStr = GetXMLToken( XML_VARP ); break;
+ }
+ ScRangeStringConverter::AssignString( rString, sFuncStr, bAppendStr );
+}
+
+
+//___________________________________________________________________
+
+sheet::DataPilotFieldOrientation ScXMLConverter::GetOrientationFromString(
+ const OUString& rString )
+{
+ if( IsXMLToken(rString, XML_COLUMN ) )
+ return sheet::DataPilotFieldOrientation_COLUMN;
+ if( IsXMLToken(rString, XML_ROW ) )
+ return sheet::DataPilotFieldOrientation_ROW;
+ if( IsXMLToken(rString, XML_PAGE ) )
+ return sheet::DataPilotFieldOrientation_PAGE;
+ if( IsXMLToken(rString, XML_DATA ) )
+ return sheet::DataPilotFieldOrientation_DATA;
+ return sheet::DataPilotFieldOrientation_HIDDEN;
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::GetStringFromOrientation(
+ OUString& rString,
+ const sheet::DataPilotFieldOrientation eOrientation,
+ sal_Bool bAppendStr )
+{
+ OUString sOrientStr;
+ switch( eOrientation )
+ {
+ case sheet::DataPilotFieldOrientation_HIDDEN:
+ sOrientStr = GetXMLToken( XML_HIDDEN );
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ sOrientStr = GetXMLToken( XML_COLUMN );
+ break;
+ case sheet::DataPilotFieldOrientation_ROW:
+ sOrientStr = GetXMLToken( XML_ROW );
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ sOrientStr = GetXMLToken( XML_PAGE );
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ sOrientStr = GetXMLToken( XML_DATA );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRangeStringConverter::AssignString( rString, sOrientStr, bAppendStr );
+}
+
+
+//___________________________________________________________________
+
+ScDetectiveObjType ScXMLConverter::GetDetObjTypeFromString( const OUString& rString )
+{
+ if( IsXMLToken(rString, XML_FROM_SAME_TABLE ) )
+ return SC_DETOBJ_ARROW;
+ if( IsXMLToken(rString, XML_FROM_ANOTHER_TABLE ) )
+ return SC_DETOBJ_FROMOTHERTAB;
+ if( IsXMLToken(rString, XML_TO_ANOTHER_TABLE ) )
+ return SC_DETOBJ_TOOTHERTAB;
+ return SC_DETOBJ_NONE;
+}
+
+sal_Bool ScXMLConverter::GetDetOpTypeFromString( ScDetOpType& rDetOpType, const OUString& rString )
+{
+ if( IsXMLToken(rString, XML_TRACE_DEPENDENTS ) )
+ rDetOpType = SCDETOP_ADDSUCC;
+ else if( IsXMLToken(rString, XML_TRACE_PRECEDENTS ) )
+ rDetOpType = SCDETOP_ADDPRED;
+ else if( IsXMLToken(rString, XML_TRACE_ERRORS ) )
+ rDetOpType = SCDETOP_ADDERROR;
+ else if( IsXMLToken(rString, XML_REMOVE_DEPENDENTS ) )
+ rDetOpType = SCDETOP_DELSUCC;
+ else if( IsXMLToken(rString, XML_REMOVE_PRECEDENTS ) )
+ rDetOpType = SCDETOP_DELPRED;
+ else
+ return sal_False;
+ return sal_True;
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::GetStringFromDetObjType(
+ OUString& rString,
+ const ScDetectiveObjType eObjType,
+ sal_Bool bAppendStr )
+{
+ OUString sTypeStr;
+ switch( eObjType )
+ {
+ case SC_DETOBJ_ARROW:
+ sTypeStr = GetXMLToken( XML_FROM_SAME_TABLE );
+ break;
+ case SC_DETOBJ_FROMOTHERTAB:
+ sTypeStr = GetXMLToken( XML_FROM_ANOTHER_TABLE );
+ break;
+ case SC_DETOBJ_TOOTHERTAB:
+ sTypeStr = GetXMLToken( XML_TO_ANOTHER_TABLE );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRangeStringConverter::AssignString( rString, sTypeStr, bAppendStr );
+}
+
+void ScXMLConverter::GetStringFromDetOpType(
+ OUString& rString,
+ const ScDetOpType eOpType,
+ sal_Bool bAppendStr )
+{
+ OUString sTypeStr;
+ switch( eOpType )
+ {
+ case SCDETOP_ADDSUCC:
+ sTypeStr = GetXMLToken( XML_TRACE_DEPENDENTS );
+ break;
+ case SCDETOP_ADDPRED:
+ sTypeStr = GetXMLToken( XML_TRACE_PRECEDENTS );
+ break;
+ case SCDETOP_ADDERROR:
+ sTypeStr = GetXMLToken( XML_TRACE_ERRORS );
+ break;
+ case SCDETOP_DELSUCC:
+ sTypeStr = GetXMLToken( XML_REMOVE_DEPENDENTS );
+ break;
+ case SCDETOP_DELPRED:
+ sTypeStr = GetXMLToken( XML_REMOVE_PRECEDENTS );
+ break;
+ }
+ ScRangeStringConverter::AssignString( rString, sTypeStr, bAppendStr );
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::ParseFormula(OUString& sFormula, const sal_Bool bIsFormula)
+{
+ OUStringBuffer sBuffer(sFormula.getLength());
+ sal_Bool bInQuotationMarks(sal_False);
+ sal_Bool bInDoubleQuotationMarks(sal_False);
+ sal_Int16 nCountBraces(0);
+ sal_Unicode chPrevious('=');
+ for (sal_Int32 i = 0; i < sFormula.getLength(); ++i)
+ {
+ if (sFormula[i] == '\'' && !bInDoubleQuotationMarks &&
+ chPrevious != '\\')
+ bInQuotationMarks = !bInQuotationMarks;
+ else if (sFormula[i] == '"' && !bInQuotationMarks)
+ bInDoubleQuotationMarks = !bInDoubleQuotationMarks;
+ if (bInQuotationMarks || bInDoubleQuotationMarks)
+ sBuffer.append(sFormula[i]);
+ else if (sFormula[i] == '[')
+ ++nCountBraces;
+ else if (sFormula[i] == ']')
+ nCountBraces--;
+ else if ((sFormula[i] != '.') ||
+ ((nCountBraces == 0) && bIsFormula) ||
+ !((chPrevious == '[') || (chPrevious == ':') || (chPrevious == ' ') || (chPrevious == '=')))
+ sBuffer.append(sFormula[i]);
+ chPrevious = sFormula[i];
+ }
+
+ DBG_ASSERT(nCountBraces == 0, "there are some braces still open");
+ sFormula = sBuffer.makeStringAndClear();
+}
+
+
+//_____________________________________________________________________
+
+void ScXMLConverter::ConvertDateTimeToString(const DateTime& aDateTime, rtl::OUStringBuffer& sDate)
+{
+ util::DateTime aAPIDateTime;
+ ConvertCoreToAPIDateTime(aDateTime, aAPIDateTime);
+ SvXMLUnitConverter::convertDateTime(sDate, aAPIDateTime);
+}
+
+//UNUSED2008-05 void ScXMLConverter::ConvertStringToDateTime(const rtl::OUString& sDate, DateTime& aDateTime, SvXMLUnitConverter* /* pUnitConverter */)
+//UNUSED2008-05 {
+//UNUSED2008-05 com::sun::star::util::DateTime aAPIDateTime;
+//UNUSED2008-05 SvXMLUnitConverter::convertDateTime(aAPIDateTime, sDate);
+//UNUSED2008-05 ConvertAPIToCoreDateTime(aAPIDateTime, aDateTime);
+//UNUSED2008-05 }
+
+void ScXMLConverter::ConvertCoreToAPIDateTime(const DateTime& aDateTime, util::DateTime& rDateTime)
+{
+ rDateTime.Year = aDateTime.GetYear();
+ rDateTime.Month = aDateTime.GetMonth();
+ rDateTime.Day = aDateTime.GetDay();
+ rDateTime.Hours = aDateTime.GetHour();
+ rDateTime.Minutes = aDateTime.GetMin();
+ rDateTime.Seconds = aDateTime.GetSec();
+ rDateTime.HundredthSeconds = aDateTime.Get100Sec();
+}
+
+void ScXMLConverter::ConvertAPIToCoreDateTime(const util::DateTime& aDateTime, DateTime& rDateTime)
+{
+ Date aDate(aDateTime.Day, aDateTime.Month, aDateTime.Year);
+ Time aTime(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds);
+ DateTime aTempDateTime (aDate, aTime);
+ rDateTime = aTempDateTime;
+}
+
+// ============================================================================
+
+namespace {
+
+/** Enumerates different types of condition tokens. */
+enum ScXMLConditionTokenType
+{
+ XML_COND_TYPE_KEYWORD, /// Simple keyword without parentheses, e.g. 'and'.
+ XML_COND_TYPE_COMPARISON, /// Comparison rule, e.g. 'cell-content()<=2'.
+ XML_COND_TYPE_FUNCTION0, /// Function without parameters, e.g. 'cell-content-is-whole-number()'.
+ XML_COND_TYPE_FUNCTION1, /// Function with 1 parameter, e.g. 'is-true-formula(1+1=2)'.
+ XML_COND_TYPE_FUNCTION2 /// Function with 2 parameters, e.g. 'cell-content-is-between(1,2)'.
+};
+
+struct ScXMLConditionInfo
+{
+ ScXMLConditionToken meToken;
+ ScXMLConditionTokenType meType;
+ sheet::ValidationType meValidation;
+ sheet::ConditionOperator meOperator;
+ const sal_Char* mpcIdentifier;
+ sal_Int32 mnIdentLength;
+};
+
+static const ScXMLConditionInfo spConditionInfos[] =
+{
+ { XML_COND_AND, XML_COND_TYPE_KEYWORD, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "and" ) },
+ { XML_COND_CELLCONTENT, XML_COND_TYPE_COMPARISON, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content" ) },
+ { XML_COND_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-between" ) },
+ { XML_COND_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-not-between" ) },
+ { XML_COND_ISWHOLENUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_WHOLE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-whole-number" ) },
+ { XML_COND_ISDECIMALNUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DECIMAL, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-decimal-number" ) },
+ { XML_COND_ISDATE, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DATE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-date" ) },
+ { XML_COND_ISTIME, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_TIME, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-time" ) },
+ { XML_COND_ISINLIST, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_LIST, sheet::ConditionOperator_EQUAL, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-in-list" ) },
+ { XML_COND_TEXTLENGTH, XML_COND_TYPE_COMPARISON, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length" ) },
+ { XML_COND_TEXTLENGTH_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-between" ) },
+ { XML_COND_TEXTLENGTH_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-not-between" ) },
+ { XML_COND_ISTRUEFORMULA, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_CUSTOM, sheet::ConditionOperator_FORMULA, RTL_CONSTASCII_STRINGPARAM( "is-true-formula" ) }
+};
+
+void lclSkipWhitespace( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ while( (rpcString < pcEnd) && (*rpcString <= ' ') ) ++rpcString;
+}
+
+const ScXMLConditionInfo* lclGetConditionInfo( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ lclSkipWhitespace( rpcString, pcEnd );
+ /* Search the end of an identifier name; assuming that valid identifiers
+ consist of [a-z-] only. */
+ const sal_Unicode* pcIdStart = rpcString;
+ while( (rpcString < pcEnd) && (((*rpcString >= 'a') && (*rpcString <= 'z')) || (*rpcString == '-')) ) ++rpcString;
+ sal_Int32 nLength = static_cast< sal_Int32 >( rpcString - pcIdStart );
+
+ // search the table for an entry
+ if( nLength > 0 )
+ for( const ScXMLConditionInfo* pInfo = spConditionInfos; pInfo < STATIC_TABLE_END( spConditionInfos ); ++pInfo )
+ if( (nLength == pInfo->mnIdentLength) && (::rtl_ustr_ascii_shortenedCompare_WithLength( pcIdStart, nLength, pInfo->mpcIdentifier, nLength ) == 0) )
+ return pInfo;
+
+ return 0;
+}
+
+sheet::ConditionOperator lclGetConditionOperator( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ // check for double-char operators
+ if( (rpcString + 1 < pcEnd) && (rpcString[ 1 ] == '=') )
+ {
+ sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
+ switch( *rpcString )
+ {
+ case '!': eOperator = sheet::ConditionOperator_NOT_EQUAL; break;
+ case '<': eOperator = sheet::ConditionOperator_LESS_EQUAL; break;
+ case '>': eOperator = sheet::ConditionOperator_GREATER_EQUAL; break;
+ }
+ if( eOperator != sheet::ConditionOperator_NONE )
+ {
+ rpcString += 2;
+ return eOperator;
+ }
+ }
+
+ // check for single-char operators
+ if( rpcString < pcEnd )
+ {
+ sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
+ switch( *rpcString )
+ {
+ case '=': eOperator = sheet::ConditionOperator_EQUAL; break;
+ case '<': eOperator = sheet::ConditionOperator_LESS; break;
+ case '>': eOperator = sheet::ConditionOperator_GREATER; break;
+ }
+ if( eOperator != sheet::ConditionOperator_NONE )
+ {
+ ++rpcString;
+ return eOperator;
+ }
+ }
+
+ return sheet::ConditionOperator_NONE;
+}
+
+/** Skips a literal string in a formula expression.
+
+ @param rpcString
+ (in-out) On call, must point to the first character of the string
+ following the leading string delimiter character. On return, points to
+ the trailing string delimiter character if existing, otherwise to
+ pcEnd.
+
+ @param pcEnd
+ The end of the string to parse.
+
+ @param cQuoteChar
+ The string delimiter character enclosing the string.
+ */
+void lclSkipExpressionString( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cQuoteChar )
+{
+ if( rpcString < pcEnd )
+ {
+ sal_Int32 nLength = static_cast< sal_Int32 >( pcEnd - rpcString );
+ sal_Int32 nNextQuote = ::rtl_ustr_indexOfChar_WithLength( rpcString, nLength, cQuoteChar );
+ if( nNextQuote >= 0 )
+ rpcString += nNextQuote;
+ else
+ rpcString = pcEnd;
+ }
+}
+
+/** Skips a formula expression. Processes embedded parentheses, braces, and
+ literal strings.
+
+ @param rpcString
+ (in-out) On call, must point to the first character of the expression.
+ On return, points to the passed end character if existing, otherwise to
+ pcEnd.
+
+ @param pcEnd
+ The end of the string to parse.
+
+ @param cEndChar
+ The termination character following the expression.
+ */
+void lclSkipExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar )
+{
+ while( rpcString < pcEnd )
+ {
+ if( *rpcString == cEndChar )
+ return;
+ switch( *rpcString )
+ {
+ case '(': lclSkipExpression( ++rpcString, pcEnd, ')' ); break;
+ case '{': lclSkipExpression( ++rpcString, pcEnd, '}' ); break;
+ case '"': lclSkipExpressionString( ++rpcString, pcEnd, '"' ); break;
+ case '\'': lclSkipExpressionString( ++rpcString, pcEnd, '\'' ); break;
+ }
+ if( rpcString < pcEnd ) ++rpcString;
+ }
+}
+
+/** Extracts a formula expression. Processes embedded parentheses, braces, and
+ literal strings.
+
+ @param rpcString
+ (in-out) On call, must point to the first character of the expression.
+ On return, points *behind* the passed end character if existing,
+ otherwise to pcEnd.
+
+ @param pcEnd
+ The end of the string to parse.
+
+ @param cEndChar
+ The termination character following the expression.
+ */
+OUString lclGetExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar )
+{
+ OUString aExp;
+ const sal_Unicode* pcExpStart = rpcString;
+ lclSkipExpression( rpcString, pcEnd, cEndChar );
+ if( rpcString < pcEnd )
+ {
+ aExp = OUString( pcExpStart, static_cast< sal_Int32 >( rpcString - pcExpStart ) ).trim();
+ ++rpcString;
+ }
+ return aExp;
+}
+
+/** Tries to skip an empty pair of parentheses (which may contain whitespace
+ characters).
+
+ @return
+ True on success, rpcString points behind the closing parentheses then.
+ */
+bool lclSkipEmptyParentheses( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ if( (rpcString < pcEnd) && (*rpcString == '(') )
+ {
+ lclSkipWhitespace( ++rpcString, pcEnd );
+ if( (rpcString < pcEnd) && (*rpcString == ')') )
+ {
+ ++rpcString;
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+/*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
new file mode 100644
index 000000000000..94766ebe08ff
--- /dev/null
+++ b/sc/source/filter/xml/XMLConverter.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCONVERTER_HXX
+#define SC_XMLCONVERTER_HXX
+
+#include "global.hxx"
+#include "detfunc.hxx"
+#include "detdata.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+
+class ScDocument;
+class DateTime;
+class SvXMLUnitConverter;
+
+
+//___________________________________________________________________
+
+class ScXMLConverter
+{
+public:
+ inline ScXMLConverter() {}
+ inline ~ScXMLConverter() {}
+
+// helper methods
+ static ScDocument* GetScDocument(
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel );
+
+// IMPORT: GeneralFunction / ScSubTotalFunc
+ static ::com::sun::star::sheet::GeneralFunction
+ GetFunctionFromString(
+ const ::rtl::OUString& rString );
+ static ScSubTotalFunc GetSubTotalFuncFromString(
+ const ::rtl::OUString& rString );
+
+// EXPORT: GeneralFunction / ScSubTotalFunc
+ static void GetStringFromFunction(
+ ::rtl::OUString& rString,
+ const ::com::sun::star::sheet::GeneralFunction eFunction,
+ sal_Bool bAppendStr = sal_False );
+ static void GetStringFromFunction(
+ ::rtl::OUString& rString,
+ const ScSubTotalFunc eFunction,
+ sal_Bool bAppendStr = sal_False );
+
+// IMPORT: DataPilotFieldOrientation
+ static ::com::sun::star::sheet::DataPilotFieldOrientation
+ GetOrientationFromString(
+ const ::rtl::OUString& rString );
+
+// EXPORT: DataPilotFieldOrientation
+ static void GetStringFromOrientation(
+ ::rtl::OUString& rString,
+ const ::com::sun::star::sheet::DataPilotFieldOrientation eOrientation,
+ sal_Bool bAppendStr = sal_False );
+
+// IMPORT: Detective
+ static ScDetectiveObjType
+ GetDetObjTypeFromString(
+ const ::rtl::OUString& rString );
+ static sal_Bool GetDetOpTypeFromString(
+ ScDetOpType& rDetOpType,
+ const ::rtl::OUString& rString );
+
+// EXPORT: Detective
+ static void GetStringFromDetObjType(
+ ::rtl::OUString& rString,
+ const ScDetectiveObjType eObjType,
+ sal_Bool bAppendStr = sal_False );
+ static void GetStringFromDetOpType(
+ ::rtl::OUString& rString,
+ const ScDetOpType eOpType,
+ sal_Bool bAppendStr = sal_False );
+
+// IMPORT: Formulas
+ static void ParseFormula(
+ ::rtl::OUString& sFormula,
+ const sal_Bool bIsFormula = sal_True);
+// EXPORT: Core Date Time
+ static void ConvertDateTimeToString(const DateTime& aDateTime, rtl::OUStringBuffer& sDate);
+//UNUSED2008-05 // IMPORT: Core Date Time
+//UNUSED2008-05 static void ConvertStringToDateTime(const rtl::OUString& sDate, DateTime& aDateTime, SvXMLUnitConverter* pUnitConverter);
+
+ static void ConvertCoreToAPIDateTime(const DateTime& aDateTime, com::sun::star::util::DateTime& rDateTime);
+
+ static void ConvertAPIToCoreDateTime(const com::sun::star::util::DateTime& aDateTime, DateTime& rDateTime);
+};
+
+// ============================================================================
+
+enum ScXMLConditionToken
+{
+ XML_COND_INVALID, /// Token not recognized.
+ XML_COND_AND, /// The 'and' token.
+ XML_COND_CELLCONTENT, /// The 'cell-content' token.
+ XML_COND_ISBETWEEN, /// The 'cell-content-is-between' token.
+ XML_COND_ISNOTBETWEEN, /// The 'cell-content-is-not-between' token.
+ XML_COND_ISWHOLENUMBER, /// The 'cell-content-is-whole-number' token.
+ XML_COND_ISDECIMALNUMBER, /// The 'cell-content-is-decimal-number' token.
+ XML_COND_ISDATE, /// The 'cell-content-is-date' token.
+ XML_COND_ISTIME, /// The 'cell-content-is-time' token.
+ XML_COND_ISINLIST, /// The 'cell-content-is-in-list' token.
+ XML_COND_TEXTLENGTH, /// The 'cell-content-text-length' token.
+ XML_COND_TEXTLENGTH_ISBETWEEN, /// The 'cell-content-text-length-is-between' token.
+ XML_COND_TEXTLENGTH_ISNOTBETWEEN, /// The 'cell-content-text-length-is-not-between' token.
+ XML_COND_ISTRUEFORMULA /// The 'is-true-formula' token.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Result of an attempt to parse a single condition in a 'condition' attribute
+ value of e.g. conditional formatting or data validation.
+ */
+struct ScXMLConditionParseResult
+{
+ ScXMLConditionToken meToken; /// The leading condition token.
+ ::com::sun::star::sheet::ValidationType
+ meValidation; /// A data validation type if existing.
+ ::com::sun::star::sheet::ConditionOperator
+ meOperator; /// A comparison operator if existing.
+ ::rtl::OUString maOperand1; /// First operand of the token or comparison value.
+ ::rtl::OUString maOperand2; /// Second operand of 'between' conditions.
+ sal_Int32 mnEndIndex; /// Index of first character following the condition.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScXMLConditionHelper
+{
+public:
+ /** Parses the next condition in a 'condition' attribute value of e.g.
+ conditional formatting or data validation.
+ */
+ static void parseCondition(
+ ScXMLConditionParseResult& rParseResult,
+ const ::rtl::OUString& rAttribute,
+ sal_Int32 nStartIndex );
+
+private:
+ ScXMLConditionHelper();
+ ~ScXMLConditionHelper();
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLDDELinksContext.cxx b/sc/source/filter/xml/XMLDDELinksContext.cxx
new file mode 100644
index 000000000000..d7fafe1d9423
--- /dev/null
+++ b/sc/source/filter/xml/XMLDDELinksContext.cxx
@@ -0,0 +1,490 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLDDELinksContext.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <tools/debug.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // here are no attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDDELinksContext::~ScXMLDDELinksContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK))
+ pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDELinksContext::EndElement()
+{
+}
+
+ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aDDELinkTable(),
+ aDDELinkRow(),
+ sApplication(),
+ sTopic(),
+ sItem(),
+ nPosition(-1),
+ nColumns(0),
+ nRows(0),
+ nMode(SC_DDE_DEFAULT)
+{
+ // here are no attributes
+}
+
+ScXMLDDELinkContext::~ScXMLDDELinkContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE))
+ pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE))
+ pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDELinkContext::CreateDDELink()
+{
+ if (GetScImport().GetDocument() &&
+ sApplication.getLength() &&
+ sTopic.getLength() &&
+ sItem.getLength())
+ {
+ String sAppl(sApplication);
+ String sTop(sTopic);
+ String sIt(sItem);
+ GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode);
+ sal_uInt16 nPos;
+ if(GetScImport().GetDocument()->FindDdeLink(sAppl, sTop, sIt, nMode, nPos))
+ nPosition = nPos;
+ else
+ nPosition = -1;
+ DBG_ASSERT(nPosition > -1, "DDE Link not inserted");
+ }
+}
+
+void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell)
+{
+ aDDELinkRow.push_back(aCell);
+}
+
+void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP)
+{
+ for (sal_Int32 i = 0; i < nRowsP; ++i)
+ aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end());
+ aDDELinkRow.clear();
+}
+
+void ScXMLDDELinkContext::EndElement()
+{
+ if (nPosition > -1 && nColumns && nRows && GetScImport().GetDocument())
+ {
+ bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size());
+ DBG_ASSERT( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count");
+ // Excel writes bad ODF in that it does not write the
+ // table:number-columns-repeated attribute of the
+ // <table:table-column> element, but apparently uses the number of
+ // <table:table-cell> elements within a <table:table-row> element to
+ // determine the column count instead. Be lenient ...
+ if (!bSizeMatch && nColumns == 1)
+ {
+ nColumns = aDDELinkTable.size() / nRows;
+ DBG_ASSERT( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(),
+ "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either");
+ }
+ ScMatrixRef pMatrix = new ScMatrix( static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows) );
+ sal_Int32 nCol(0);
+ sal_Int32 nRow(-1);
+ sal_Int32 nIndex(0);
+ ScDDELinkCells::iterator aItr(aDDELinkTable.begin());
+ ScDDELinkCells::iterator aEndItr(aDDELinkTable.end());
+ while (aItr != aEndItr)
+ {
+ if (nIndex % nColumns == 0)
+ {
+ ++nRow;
+ nCol = 0;
+ }
+ else
+ ++nCol;
+
+ SCSIZE nScCol( static_cast< SCSIZE >( nCol ) );
+ SCSIZE nScRow( static_cast< SCSIZE >( nRow ) );
+ if( aItr->bEmpty )
+ pMatrix->PutEmpty( nScCol, nScRow );
+ else if( aItr->bString )
+ pMatrix->PutString( aItr->sValue, nScCol, nScRow );
+ else
+ pMatrix->PutDouble( aItr->fValue, nScCol, nScRow );
+
+ ++nIndex;
+ ++aItr;
+ }
+
+ GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< USHORT >( nPosition ), pMatrix );
+ }
+}
+
+ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink)
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_DDE_APPLICATION))
+ pDDELink->SetApplication(sValue);
+ else if (IsXMLToken(aLocalName, XML_DDE_TOPIC))
+ pDDELink->SetTopic(sValue);
+ else if (IsXMLToken(aLocalName, XML_DDE_ITEM))
+ pDDELink->SetItem(sValue);
+ }
+ else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE))
+ {
+ if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER))
+ pDDELink->SetMode(SC_DDE_ENGLISH);
+ else if (IsXMLToken(sValue, XML_KEEP_TEXT))
+ pDDELink->SetMode(SC_DDE_TEXT);
+ else
+ pDDELink->SetMode(SC_DDE_DEFAULT);
+ }
+ }
+}
+
+ScXMLDDESourceContext::~ScXMLDDESourceContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDESourceContext::EndElement()
+{
+ pDDELink->CreateDDELink();
+}
+
+ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink)
+{
+ // here are no attributes
+}
+
+ScXMLDDETableContext::~ScXMLDDETableContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = NULL;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_TABLE_COLUMN))
+ pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
+ else if (IsXMLToken(rLName, XML_TABLE_ROW))
+ pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
+ }
+
+ if (!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDETableContext::EndElement()
+{
+}
+
+ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink)
+{
+ if( !xAttrList.is() ) return;
+ sal_Int32 nCols(1);
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
+ GetScImport().GetMM100UnitConverter().convertNumber(nCols, sValue);
+ }
+ pDDELink->AddColumns(nCols);
+}
+
+ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDEColumnContext::EndElement()
+{
+}
+
+ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink),
+ nRows(1)
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED))
+ GetScImport().GetMM100UnitConverter().convertNumber(nRows, sValue);
+ }
+ pDDELink->AddRows(nRows);
+}
+
+ScXMLDDERowContext::~ScXMLDDERowContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = NULL;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ if (IsXMLToken(rLName, XML_TABLE_CELL))
+ pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
+
+ if (!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDERowContext::EndElement()
+{
+ pDDELink->AddRowsToTable(nRows);
+}
+
+ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sValue(),
+ fValue(),
+ nCells(1),
+ bString(sal_True),
+ bString2(sal_True),
+ bEmpty(sal_True),
+ pDDELink(pTempDDELink)
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sTempValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
+ {
+ if (IsXMLToken(sTempValue, XML_STRING))
+ bString = sal_True;
+ else
+ bString = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_STRING_VALUE))
+ {
+ sValue = sTempValue;
+ bEmpty = sal_False;
+ bString2 = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_VALUE))
+ {
+ GetScImport().GetMM100UnitConverter().convertDouble(fValue, sTempValue);
+ bEmpty = sal_False;
+ bString2 = sal_False;
+ }
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
+ GetScImport().GetMM100UnitConverter().convertNumber(nCells, sTempValue);
+ }
+ }
+}
+
+ScXMLDDECellContext::~ScXMLDDECellContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDECellContext::EndElement()
+{
+ DBG_ASSERT(bString == bString2, "something wrong with this type");
+ ScDDELinkCell aCell;
+ aCell.sValue = sValue;
+ aCell.fValue = fValue;
+ aCell.bEmpty = bEmpty;
+ aCell.bString = bString2;
+ for(sal_Int32 i = 0; i < nCells; ++i)
+ pDDELink->AddCellToRow(aCell);
+}
diff --git a/sc/source/filter/xml/XMLDDELinksContext.hxx b/sc/source/filter/xml/XMLDDELinksContext.hxx
new file mode 100644
index 000000000000..e9c1db58548f
--- /dev/null
+++ b/sc/source/filter/xml/XMLDDELinksContext.hxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLDDELINKSCONTEXT_HXX
+#define SC_XMLDDELINKSCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+#include <list>
+
+class ScXMLImport;
+
+class ScXMLDDELinksContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDELinksContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDDELinksContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+struct ScDDELinkCell
+{
+ rtl::OUString sValue;
+ double fValue;
+ sal_Bool bString;
+ sal_Bool bEmpty;
+};
+
+typedef std::list<ScDDELinkCell> ScDDELinkCells;
+
+class ScXMLDDELinkContext : public SvXMLImportContext
+{
+ ScDDELinkCells aDDELinkTable;
+ ScDDELinkCells aDDELinkRow;
+ rtl::OUString sApplication;
+ rtl::OUString sTopic;
+ rtl::OUString sItem;
+ sal_Int32 nPosition;
+ sal_Int32 nColumns;
+ sal_Int32 nRows;
+ sal_uInt8 nMode;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDELinkContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDDELinkContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void SetApplication(const rtl::OUString& sValue) { sApplication = sValue; }
+ void SetTopic(const rtl::OUString& sValue) { sTopic = sValue; }
+ void SetItem(const rtl::OUString& sValue) { sItem = sValue; }
+ void SetMode(const sal_uInt8 nValue) { nMode = nValue; }
+ void CreateDDELink();
+ void AddColumns(const sal_Int32 nValue) { nColumns += nValue; }
+ void AddRows(const sal_Int32 nValue) { nRows += nValue; }
+ void AddCellToRow(const ScDDELinkCell& aCell);
+ void AddRowsToTable(const sal_Int32 nRows);
+
+ virtual void EndElement();
+};
+
+class ScXMLDDESourceContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDESourceContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDESourceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDETableContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDETableContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDETableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDEColumnContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDEColumnContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDEColumnContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDERowContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+ sal_Int32 nRows;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDERowContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDERowContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDECellContext : public SvXMLImportContext
+{
+ rtl::OUString sValue;
+ double fValue;
+ sal_Int32 nCells;
+ sal_Bool bString;
+ sal_Bool bString2;
+ sal_Bool bEmpty;
+
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDECellContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDECellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLDetectiveContext.cxx b/sc/source/filter/xml/XMLDetectiveContext.cxx
new file mode 100644
index 000000000000..c127ca518266
--- /dev/null
+++ b/sc/source/filter/xml/XMLDetectiveContext.cxx
@@ -0,0 +1,265 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//___________________________________________________________________
+#include "XMLDetectiveContext.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "convuno.hxx"
+#include "xmlimprt.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <algorithm>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScMyImpDetectiveObj::ScMyImpDetectiveObj() :
+ aSourceRange(),
+ eObjType( SC_DETOBJ_NONE ),
+ bHasError( sal_False )
+{
+}
+
+//___________________________________________________________________
+
+sal_Bool ScMyImpDetectiveOp::operator<(const ScMyImpDetectiveOp& rDetOp) const
+{
+ return (nIndex < rDetOp.nIndex);
+}
+
+void ScMyImpDetectiveOpArray::Sort()
+{
+ aDetectiveOpList.sort();
+}
+
+sal_Bool ScMyImpDetectiveOpArray::GetFirstOp( ScMyImpDetectiveOp& rDetOp )
+{
+ if( aDetectiveOpList.empty() )
+ return sal_False;
+ ScMyImpDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
+ rDetOp = *aItr;
+ aDetectiveOpList.erase( aItr );
+ return sal_True;
+}
+
+
+//___________________________________________________________________
+
+ScXMLDetectiveContext::ScXMLDetectiveContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDetectiveObjVec( pNewDetectiveObjVec )
+{
+}
+
+ScXMLDetectiveContext::~ScXMLDetectiveContext()
+{
+}
+
+SvXMLImportContext *ScXMLDetectiveContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext* pContext = NULL;
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDetectiveElemTokenMap();
+
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED:
+ pContext = new ScXMLDetectiveHighlightedContext( GetScImport(), nPrefix, rLName, xAttrList, pDetectiveObjVec );
+ break;
+ case XML_TOK_DETECTIVE_ELEM_OPERATION:
+ pContext = new ScXMLDetectiveOperationContext( GetScImport(), nPrefix, rLName, xAttrList );
+ break;
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDetectiveContext::EndElement()
+{
+}
+
+
+//___________________________________________________________________
+
+ScXMLDetectiveHighlightedContext::ScXMLDetectiveHighlightedContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec ):
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDetectiveObjVec( pNewDetectiveObjVec ),
+ aDetectiveObj(),
+ bValid( sal_False )
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDetectiveHighlightedAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE:
+ {
+ sal_Int32 nOffset(0);
+ GetScImport().LockSolarMutex();
+ bValid = ScRangeStringConverter::GetRangeFromString( aDetectiveObj.aSourceRange, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset );
+ GetScImport().UnlockSolarMutex();
+ }
+ break;
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION:
+ aDetectiveObj.eObjType = ScXMLConverter::GetDetObjTypeFromString( sValue );
+ break;
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR:
+ aDetectiveObj.bHasError = IsXMLToken(sValue, XML_TRUE);
+ break;
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID:
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ aDetectiveObj.eObjType = SC_DETOBJ_CIRCLE;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDetectiveHighlightedContext::~ScXMLDetectiveHighlightedContext()
+{
+}
+
+SvXMLImportContext *ScXMLDetectiveHighlightedContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLDetectiveHighlightedContext::EndElement()
+{
+ switch( aDetectiveObj.eObjType )
+ {
+ case SC_DETOBJ_ARROW:
+ case SC_DETOBJ_TOOTHERTAB:
+ break;
+ case SC_DETOBJ_FROMOTHERTAB:
+ case SC_DETOBJ_CIRCLE:
+ bValid = sal_True;
+ break;
+ default:
+ bValid = sal_False;
+ }
+ if( bValid )
+ pDetectiveObjVec->push_back( aDetectiveObj );
+}
+
+
+//___________________________________________________________________
+
+ScXMLDetectiveOperationContext::ScXMLDetectiveOperationContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aDetectiveOp(),
+ bHasType( sal_False )
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDetectiveOperationAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DETECTIVE_OPERATION_ATTR_NAME:
+ bHasType = ScXMLConverter::GetDetOpTypeFromString( aDetectiveOp.eOpType, sValue );
+ break;
+ case XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX:
+ {
+ sal_Int32 nValue;
+ if( SvXMLUnitConverter::convertNumber( nValue, sValue, 0 ) )
+ aDetectiveOp.nIndex = nValue;
+ }
+ break;
+ }
+ }
+ ScUnoConversion::FillScAddress( aDetectiveOp.aPosition, rImport.GetTables().GetRealCellPos() );
+}
+
+ScXMLDetectiveOperationContext::~ScXMLDetectiveOperationContext()
+{
+}
+
+SvXMLImportContext *ScXMLDetectiveOperationContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLDetectiveOperationContext::EndElement()
+{
+ if( bHasType && (aDetectiveOp.nIndex >= 0) )
+ GetScImport().GetDetectiveOpArray()->AddDetectiveOp( aDetectiveOp );
+}
+
diff --git a/sc/source/filter/xml/XMLDetectiveContext.hxx b/sc/source/filter/xml/XMLDetectiveContext.hxx
new file mode 100644
index 000000000000..30a8bc600bb0
--- /dev/null
+++ b/sc/source/filter/xml/XMLDetectiveContext.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLDETECTIVECONTEXT_HXX
+#define SC_XMLDETECTIVECONTEXT_HXX
+
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "detfunc.hxx"
+#include "detdata.hxx"
+
+#include <list>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+struct ScMyImpDetectiveObj
+{
+ ScRange aSourceRange;
+ ScDetectiveObjType eObjType;
+ sal_Bool bHasError;
+
+ ScMyImpDetectiveObj();
+};
+
+typedef ::std::vector< ScMyImpDetectiveObj > ScMyImpDetectiveObjVec;
+
+
+//___________________________________________________________________
+
+struct ScMyImpDetectiveOp
+{
+ ScAddress aPosition;
+ ScDetOpType eOpType;
+ sal_Int32 nIndex;
+
+ inline ScMyImpDetectiveOp() : nIndex( -1 ) {}
+ sal_Bool operator<(const ScMyImpDetectiveOp& rDetOp) const;
+};
+
+typedef ::std::list< ScMyImpDetectiveOp > ScMyImpDetectiveOpList;
+
+class ScMyImpDetectiveOpArray
+{
+private:
+ ScMyImpDetectiveOpList aDetectiveOpList;
+
+public:
+ inline ScMyImpDetectiveOpArray() :
+ aDetectiveOpList() {}
+
+ inline void AddDetectiveOp( const ScMyImpDetectiveOp& rDetOp )
+ { aDetectiveOpList.push_back( rDetOp ); }
+
+ void Sort();
+ sal_Bool GetFirstOp( ScMyImpDetectiveOp& rDetOp );
+};
+
+
+//___________________________________________________________________
+
+class ScXMLDetectiveContext : public SvXMLImportContext
+{
+private:
+ ScMyImpDetectiveObjVec* pDetectiveObjVec;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDetectiveContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec
+ );
+ virtual ~ScXMLDetectiveContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLDetectiveHighlightedContext : public SvXMLImportContext
+{
+private:
+ ScMyImpDetectiveObjVec* pDetectiveObjVec;
+ ScMyImpDetectiveObj aDetectiveObj;
+ sal_Bool bValid;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDetectiveHighlightedContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec
+ );
+ virtual ~ScXMLDetectiveHighlightedContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLDetectiveOperationContext : public SvXMLImportContext
+{
+private:
+ ScMyImpDetectiveOp aDetectiveOp;
+ sal_Bool bHasType;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDetectiveOperationContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual ~ScXMLDetectiveOperationContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLEmptyContext.cxx b/sc/source/filter/xml/XMLEmptyContext.cxx
new file mode 100644
index 000000000000..dbba2732ecee
--- /dev/null
+++ b/sc/source/filter/xml/XMLEmptyContext.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "XMLEmptyContext.hxx"
+#include "xmlimprt.hxx"
+
+//------------------------------------------------------------------
+
+ScXMLEmptyContext::ScXMLEmptyContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+}
+
+ScXMLEmptyContext::~ScXMLEmptyContext()
+{
+}
+
+SvXMLImportContext *ScXMLEmptyContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLName);
+
+ return pContext;
+}
+
+void ScXMLEmptyContext::EndElement()
+{
+}
diff --git a/sc/source/filter/xml/XMLEmptyContext.hxx b/sc/source/filter/xml/XMLEmptyContext.hxx
new file mode 100644
index 000000000000..ab8b69ad8403
--- /dev/null
+++ b/sc/source/filter/xml/XMLEmptyContext.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLEMPTYCONTEXT_HXX
+#define SC_XMLEMPTYCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+class ScXMLImport;
+
+class ScXMLEmptyContext : public SvXMLImportContext
+{
+ rtl::OUString sPrintRanges;
+ sal_Bool bStartFormPage;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLEmptyContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName);
+
+ virtual ~ScXMLEmptyContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLExportDDELinks.cxx b/sc/source/filter/xml/XMLExportDDELinks.cxx
new file mode 100644
index 000000000000..a29394bf850b
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDDELinks.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportDDELinks.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "xmlexprt.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include <com/sun/star/sheet/XDDELink.hpp>
+
+class ScMatrix;
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+ScXMLExportDDELinks::ScXMLExportDDELinks(ScXMLExport& rTempExport)
+ : rExport(rTempExport)
+{
+}
+
+ScXMLExportDDELinks::~ScXMLExportDDELinks()
+{
+}
+
+sal_Bool ScXMLExportDDELinks::CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
+ const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue)
+{
+ if (bEmpty == bPrevEmpty)
+ if (bEmpty)
+ return sal_True;
+ else if (bString == bPrevString)
+ if (bString)
+ return (sPrevValue == sValue);
+ else
+ return (fPrevValue == fValue);
+ else
+ return sal_False;
+ else
+ return sal_False;
+}
+
+void ScXMLExportDDELinks::WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat)
+{
+ rtl::OUStringBuffer sBuffer;
+ if (!bEmpty)
+ {
+ if (bString)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, rtl::OUString(sValue));
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
+ rExport.GetMM100UnitConverter().convertDouble(sBuffer, fValue);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sBuffer.makeStringAndClear());
+ }
+ }
+ if (nRepeat > 1)
+ {
+ rExport.GetMM100UnitConverter().convertNumber(sBuffer, nRepeat);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+}
+
+void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos)
+{
+ const ScMatrix* pMatrix(NULL);
+ if (rExport.GetDocument())
+ pMatrix = rExport.GetDocument()->GetDdeLinkResultMatrix( static_cast<USHORT>(nPos) );
+ if (pMatrix)
+ {
+ SCSIZE nuCol;
+ SCSIZE nuRow;
+ pMatrix->GetDimensions( nuCol, nuRow );
+ sal_Int32 nRowCount = static_cast<sal_Int32>(nuRow);
+ sal_Int32 nColCount = static_cast<sal_Int32>(nuCol);
+ SvXMLElementExport aTableElem(rExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
+ rtl::OUStringBuffer sBuffer;
+ if (nColCount > 1)
+ {
+ rExport.GetMM100UnitConverter().convertNumber(sBuffer, nColCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, sBuffer.makeStringAndClear());
+ }
+ {
+ SvXMLElementExport aElemCol(rExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
+ }
+ sal_Bool bPrevString(sal_True);
+ sal_Bool bPrevEmpty(sal_True);
+ double fPrevValue;
+ String sPrevValue;
+ sal_Int32 nRepeatColsCount(1);
+ for(sal_Int32 nRow = 0; nRow < nRowCount; ++nRow)
+ {
+ SvXMLElementExport aElemRow(rExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+ for(sal_Int32 nColumn = 0; nColumn < nColCount; ++nColumn)
+ {
+ ScMatValType nType = SC_MATVAL_VALUE;
+ const ScMatrixValue* pMatVal = pMatrix->Get( static_cast<SCSIZE>(nColumn), static_cast<SCSIZE>(nRow), nType );
+ BOOL bIsString = ScMatrix::IsNonValueType( nType);
+
+ if (nColumn == 0)
+ {
+ bPrevEmpty = !pMatVal;
+ bPrevString = bIsString;
+ if( bIsString )
+ sPrevValue = pMatVal->GetString();
+ else
+ fPrevValue = pMatVal->fVal;
+ }
+ else
+ {
+ double fValue;
+ String sValue;
+ sal_Bool bEmpty(!pMatVal);
+ sal_Bool bString(bIsString);
+ if( bIsString )
+ sValue = pMatVal->GetString();
+ else
+ fValue = pMatVal->fVal;
+
+ if (CellsEqual(bPrevEmpty, bPrevString, sPrevValue, fPrevValue,
+ bEmpty, bString, sValue, fValue))
+ ++nRepeatColsCount;
+ else
+ {
+ WriteCell(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, nRepeatColsCount);
+ nRepeatColsCount = 1;
+ bPrevEmpty = bEmpty;
+ fPrevValue = fValue;
+ sPrevValue = sValue;
+ }
+ }
+ }
+ WriteCell(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, nRepeatColsCount);
+ nRepeatColsCount = 1;
+ }
+ }
+}
+
+void ScXMLExportDDELinks::WriteDDELinks(uno::Reference<sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndex(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DDELINKS))), uno::UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nCount = xIndex->getCount();
+ if (nCount)
+ {
+ SvXMLElementExport aElemDDEs(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINKS, sal_True, sal_True);
+ for (sal_uInt16 nDDELink = 0; nDDELink < nCount; ++nDDELink)
+ {
+ uno::Reference<sheet::XDDELink> xDDELink(xIndex->getByIndex(nDDELink), uno::UNO_QUERY);
+ if (xDDELink.is())
+ {
+ SvXMLElementExport aElemDDE(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINK, sal_True, sal_True);
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION, xDDELink->getApplication());
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC, xDDELink->getTopic());
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM, xDDELink->getItem());
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_AUTOMATIC_UPDATE, XML_TRUE);
+ BYTE nMode;
+ if (rExport.GetDocument() &&
+ rExport.GetDocument()->GetDdeLinkMode(nDDELink, nMode))
+ {
+ switch (nMode)
+ {
+ case SC_DDE_ENGLISH :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_INTO_ENGLISH_NUMBER);
+ break;
+ case SC_DDE_TEXT :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_KEEP_TEXT);
+ break;
+ }
+ }
+ SvXMLElementExport(rExport, XML_NAMESPACE_OFFICE, XML_DDE_SOURCE, sal_True, sal_True);
+ }
+ WriteTable(nDDELink);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/XMLExportDDELinks.hxx b/sc/source/filter/xml/XMLExportDDELinks.hxx
new file mode 100644
index 000000000000..245a95934449
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDDELinks.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTDDELINKS_HXX
+#define SC_XMLEXPORTDDELINKS_HXX
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+class String;
+class ScXMLExport;
+
+class ScXMLExportDDELinks
+{
+ ScXMLExport& rExport;
+
+ sal_Bool CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
+ const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue);
+ void WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat);
+ void WriteTable(const sal_Int32 nPos);
+public:
+ ScXMLExportDDELinks(ScXMLExport& rExport);
+ ~ScXMLExportDDELinks();
+ void WriteDDELinks(::com::sun::star::uno::Reference < ::com::sun::star::sheet::XSpreadsheetDocument >& xSpreadDoc);
+};
+
+#endif
+
+
diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx
new file mode 100644
index 000000000000..f8cba5ecf6c3
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDataPilot.cxx
@@ -0,0 +1,898 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportDataPilot.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <rtl/math.hxx>
+#include "xmlexprt.hxx"
+#include "XMLConverter.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+#include "dociter.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "scitems.hxx"
+#include "dpsave.hxx"
+#include "dpshttab.hxx"
+#include "dpsdbtab.hxx"
+#include "dpdimsave.hxx"
+#include "dpgroup.hxx"
+#include "rangeutl.hxx"
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
+ : rExport(rTempExport),
+ pDoc( NULL )
+{
+}
+
+ScXMLExportDataPilot::~ScXMLExportDataPilot()
+{
+}
+
+rtl::OUString ScXMLExportDataPilot::getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions,
+ const sal_Bool bIsString, const double dVal, const String& sVal) const
+{
+ switch (aFilterOperator)
+ {
+ case SC_EQUAL :
+ {
+ rtl::OUString sReturn;
+ if (bUseRegularExpressions)
+ sReturn = GetXMLToken(XML_MATCH);
+ else
+ sReturn = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+
+ if (!bIsString && sVal == EMPTY_STRING)
+ {
+ if (dVal == SC_EMPTYFIELDS)
+ sReturn = GetXMLToken(XML_EMPTY);
+ else if (dVal == SC_NONEMPTYFIELDS)
+ sReturn = GetXMLToken(XML_NOEMPTY);
+ }
+
+ return sReturn;
+ }
+ case SC_NOT_EQUAL :
+ {
+ if (bUseRegularExpressions)
+ return GetXMLToken(XML_NOMATCH);
+ else
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ }
+ case SC_BOTPERC :
+ return GetXMLToken(XML_BOTTOM_PERCENT);
+ case SC_BOTVAL :
+ return GetXMLToken(XML_BOTTOM_VALUES);
+ case SC_GREATER :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ case SC_GREATER_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ case SC_LESS :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ case SC_LESS_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ case SC_TOPPERC :
+ return GetXMLToken(XML_TOP_PERCENT);
+ case SC_TOPVAL :
+ return GetXMLToken(XML_TOP_VALUES);
+ default:
+ DBG_ERROR("This FilterOperator is not supported.");
+ }
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+}
+
+void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(sal_Int32(aQueryEntry.nField)));
+ if (bIsCaseSensitive)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+ if (aQueryEntry.bQueryByString)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, *aQueryEntry.pStr);
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rtl::OUString(*aQueryEntry.pStr));
+ }
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getDPOperatorXML(aQueryEntry.eOp, bUseRegularExpressions,
+ aQueryEntry.bQueryByString, aQueryEntry.nVal, *aQueryEntry.pStr));
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
+}
+
+void ScXMLExportDataPilot::WriteDPFilter(const ScQueryParam& aQueryParam)
+{
+ SCSIZE nQueryEntryCount = aQueryParam.GetEntryCount();
+ if (nQueryEntryCount > 0)
+ {
+ sal_Bool bAnd(sal_False);
+ sal_Bool bOr(sal_False);
+ sal_Bool bHasEntries(sal_True);
+ SCSIZE nEntries(0);
+ SCSIZE j;
+
+ for ( j = 0; (j < nQueryEntryCount) && bHasEntries; ++j)
+ {
+ ScQueryEntry aEntry = aQueryParam.GetEntry(j);
+ if (aEntry.bDoQuery)
+ {
+ if (nEntries > 0)
+ {
+ if (aEntry.eConnect == SC_AND)
+ bAnd = sal_True;
+ else
+ bOr = sal_True;
+ }
+ ++nEntries;
+ }
+ else
+ bHasEntries = sal_False;
+ }
+ nQueryEntryCount = nEntries;
+ if (nQueryEntryCount)
+ {
+ // There is never a target range in a data pilot.
+/* if (!aQueryParam.bInplace)
+ {
+ ScAddress aTargetAddress(aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab);
+ rtl::OUString sAddress;
+ ScXMLConverter::GetStringFromAddress( sAddress, aTargetAddress, pDoc );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sAddress);
+ }*/
+ if(!((aQueryParam.nCol1 == aQueryParam.nCol2) && (aQueryParam.nRow1 == aQueryParam.nRow2) &&
+ (static_cast<SCCOLROW>(aQueryParam.nCol1) == static_cast<SCCOLROW>(aQueryParam.nRow1)) &&
+ (aQueryParam.nCol1 == 0) && (aQueryParam.nTab == SCTAB_MAX)))
+ {
+ ScRange aConditionRange(aQueryParam.nCol1, aQueryParam.nRow1, aQueryParam.nTab,
+ aQueryParam.nCol2, aQueryParam.nRow2, aQueryParam.nTab);
+ rtl::OUString sConditionRange;
+ ScRangeStringConverter::GetStringFromRange( sConditionRange, aConditionRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sConditionRange);
+ }
+ if (!aQueryParam.bDuplicate)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
+ SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
+ rExport.CheckAttrList();
+ if (nQueryEntryCount == 1)
+ {
+ WriteDPCondition(aQueryParam.GetEntry(0), aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ else if (bOr && !bAnd)
+ {
+ SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ for (j = 0; j < nQueryEntryCount; ++j)
+ {
+ WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ else if (bAnd && !bOr)
+ {
+ SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
+ for (j = 0; j < nQueryEntryCount; ++j)
+ {
+ WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ else
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ ScQueryEntry aPrevFilterField(aQueryParam.GetEntry(0));
+ ScQueryConnect aConnection = aQueryParam.GetEntry(1).eConnect;
+ sal_Bool bOpenAndElement;
+ rtl::OUString aName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND)));
+ if (aConnection == SC_AND)
+ {
+ rExport.StartElement( aName, sal_True );
+ bOpenAndElement = sal_True;
+ }
+ else
+ bOpenAndElement = sal_False;
+ for (j = 1; j < nQueryEntryCount; ++j)
+ {
+ if (aConnection != aQueryParam.GetEntry(j).eConnect)
+ {
+ aConnection = aQueryParam.GetEntry(j).eConnect;
+ if (aQueryParam.GetEntry(j).eConnect == SC_AND)
+ {
+ rExport.StartElement( aName, sal_True );
+ bOpenAndElement = sal_True;
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ aPrevFilterField = aQueryParam.GetEntry(j);
+ if (j == nQueryEntryCount - 1)
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = sal_False;
+ }
+ }
+ else
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ aPrevFilterField = aQueryParam.GetEntry(j);
+ if (bOpenAndElement)
+ {
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = sal_False;
+ }
+ if (j == nQueryEntryCount - 1)
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ }
+ else
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ aPrevFilterField = aQueryParam.GetEntry(j);
+ if (j == nQueryEntryCount - 1)
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteFieldReference(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldReference* pRef = pDim->GetReferenceValue();
+ if (pRef)
+ {
+ rtl::OUString sValueStr;
+ switch (pRef->ReferenceType)
+ {
+ case sheet::DataPilotFieldReferenceType::NONE :
+ sValueStr = GetXMLToken(XML_NONE);
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE :
+ sValueStr = GetXMLToken(XML_MEMBER_DIFFERENCE);
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE :
+ sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE_DIFFERENCE);
+ break;
+ case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL :
+ sValueStr = GetXMLToken(XML_RUNNING_TOTAL);
+ break;
+ case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_ROW_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_COLUMN_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_TOTAL_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::INDEX :
+ sValueStr = GetXMLToken(XML_INDEX);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, sValueStr);
+
+ if (pRef->ReferenceField.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NAME, pRef->ReferenceField);
+
+ if (pRef->ReferenceItemType == sheet::DataPilotFieldReferenceItemType::NAMED)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, XML_NAMED);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_NAME, pRef->ReferenceItemName);
+ }
+ else
+ {
+ sValueStr = rtl::OUString();
+ switch(pRef->ReferenceItemType)
+ {
+ case sheet::DataPilotFieldReferenceItemType::PREVIOUS :
+ sValueStr = GetXMLToken(XML_PREVIOUS);
+ break;
+ case sheet::DataPilotFieldReferenceItemType::NEXT :
+ sValueStr = GetXMLToken(XML_NEXT);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, sValueStr);
+ }
+ SvXMLElementExport aElemDPFR(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+}
+
+void ScXMLExportDataPilot::WriteSortInfo(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldSortInfo* pSortInfo = pDim->GetSortInfo();
+ if (pSortInfo)
+ {
+ if (pSortInfo->IsAscending)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_ASCENDING);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+
+ rtl::OUString sValueStr;
+ switch (pSortInfo->Mode)
+ {
+ case sheet::DataPilotFieldSortMode::NONE:
+ sValueStr = GetXMLToken(XML_NONE);
+ break;
+ case sheet::DataPilotFieldSortMode::MANUAL:
+ sValueStr = GetXMLToken(XML_MANUAL);
+ break;
+ case sheet::DataPilotFieldSortMode::NAME:
+ sValueStr = GetXMLToken(XML_NAME);
+ break;
+ case sheet::DataPilotFieldSortMode::DATA:
+ sValueStr = GetXMLToken(XML_DATA);
+ if (pSortInfo->Field.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pSortInfo->Field);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SORT_MODE, sValueStr);
+ SvXMLElementExport aElemDPLSI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExportDataPilot::WriteAutoShowInfo(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldAutoShowInfo* pAutoInfo = pDim->GetAutoShowInfo();
+ if (pAutoInfo)
+ {
+ if (pAutoInfo->IsEnabled)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_FALSE);
+
+ rtl::OUString sValueStr;
+ switch (pAutoInfo->ShowItemsMode)
+ {
+ case sheet::DataPilotFieldShowItemsMode::FROM_TOP:
+ sValueStr = GetXMLToken(XML_FROM_TOP);
+ break;
+ case sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM:
+ sValueStr = GetXMLToken(XML_FROM_BOTTOM);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_MEMBER_MODE, sValueStr);
+
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, pAutoInfo->ItemCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_COUNT, sBuffer.makeStringAndClear());
+
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pAutoInfo->DataField);
+
+ SvXMLElementExport aElemDPLAI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldLayoutInfo* pLayoutInfo = pDim->GetLayoutInfo();
+ if (pLayoutInfo)
+ {
+ if (pLayoutInfo->AddEmptyLines)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_FALSE);
+
+ rtl::OUString sValueStr;
+ switch (pLayoutInfo->LayoutMode)
+ {
+ case sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT:
+ sValueStr = GetXMLToken(XML_TABULAR_LAYOUT);
+ break;
+ case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
+ sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_TOP);
+ break;
+ case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
+ sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_BOTTOM);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LAYOUT_MODE, sValueStr);
+ SvXMLElementExport aElemDPLLI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
+{
+ using sheet::GeneralFunction;
+
+ sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
+ const OUString* pLayoutName = NULL;
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ // Export display names only for 1.2 extended or later.
+ pLayoutName = pDim->GetSubtotalName();
+
+ if (nSubTotalCount > 0)
+ {
+ SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
+ {
+ rtl::OUString sFunction;
+ GeneralFunction nFunc = static_cast<GeneralFunction>(pDim->GetSubTotalFunc(nSubTotal));
+ ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
+ if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
+{
+ const ScDPSaveDimension::MemberList &rMembers = pDim->GetMembers();
+ if (rMembers.begin() != rMembers.end())
+ {
+ SvXMLElementExport aElemDPMs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
+
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Export display names only for ODF 1.2 extended or later.
+ const OUString* pLayoutName = (*i)->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ }
+
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetShowDetails());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, sBuffer.makeStringAndClear());
+ SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteLevels(ScDPSaveDimension* pDim)
+{
+ // #i114202# GetShowEmpty is only valid if HasShowEmpty is true.
+ if (pDim->HasShowEmpty())
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertBool(sBuffer, pDim->GetShowEmpty());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aElemDPL(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, sal_True, sal_True);
+
+ WriteSubTotals(pDim);
+ WriteMembers(pDim);
+ WriteAutoShowInfo(pDim);
+ WriteSortInfo(pDim);
+ WriteLayoutInfo(pDim);
+ rExport.CheckAttrList();
+}
+
+void ScXMLExportDataPilot::WriteDatePart(sal_Int32 nPart)
+{
+ switch(nPart)
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_SECONDS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MINUTES);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_HOURS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_DAYS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MONTHS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_QUARTERS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_YEARS);
+ }
+ break;
+ }
+}
+
+void ScXMLExportDataPilot::WriteNumGroupInfo(const ScDPNumGroupInfo& rGroupInfo)
+{
+ DBG_ASSERT(rGroupInfo.Enable, "group dimension should be enabled");
+ if (rGroupInfo.DateValues)
+ {
+ if (rGroupInfo.AutoStart)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, XML_AUTO);
+ else
+ {
+ rtl::OUStringBuffer sDate;
+ rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.Start);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, sDate.makeStringAndClear());
+ }
+ if (rGroupInfo.AutoEnd)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, XML_AUTO);
+ else
+ {
+ rtl::OUStringBuffer sDate;
+ rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.End);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, sDate.makeStringAndClear());
+ }
+ }
+ else
+ {
+ if (rGroupInfo.AutoStart)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, XML_AUTO);
+ else
+ {
+ rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Start,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, sValue);
+ }
+ if (rGroupInfo.AutoEnd)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, XML_AUTO);
+ else
+ {
+ rtl::OUStringBuffer sDate;
+ rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.End,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, sValue);
+ }
+ }
+ rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Step,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STEP, sValue);
+}
+
+void ScXMLExportDataPilot::WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim)
+{
+ if (pGroupDim)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, pGroupDim->GetSourceDimName());
+ if (pGroupDim->GetDatePart())
+ {
+ WriteDatePart(pGroupDim->GetDatePart());
+ WriteNumGroupInfo(pGroupDim->GetDateInfo());
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim)
+{
+ if (pNumGroupDim)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
+ if (pNumGroupDim->GetDatePart())
+ {
+ WriteDatePart(pNumGroupDim->GetDatePart());
+ WriteNumGroupInfo(pNumGroupDim->GetDateInfo());
+ }
+ else
+ {
+ WriteNumGroupInfo(pNumGroupDim->GetInfo());
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
+{
+ const ScDPSaveGroupDimension* pGroupDim = NULL;
+ const ScDPSaveNumGroupDimension* pNumGroupDim = NULL;
+ if (pDimData)
+ {
+ pGroupDim = pDimData->GetNamedGroupDim(pDim->GetName());
+ WriteGroupDimAttributes(pGroupDim);
+ pNumGroupDim = pDimData->GetNumGroupDim(pDim->GetName());
+ WriteNumGroupDim(pNumGroupDim);
+
+ DBG_ASSERT((!pGroupDim || !pNumGroupDim), "there should be no NumGroup and Group at the same field");
+ }
+ if (pGroupDim || pNumGroupDim)
+ {
+ SvXMLElementExport aElemDPGs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, sal_True, sal_True);
+ if (pGroupDim)
+ {
+ if (!pGroupDim->GetDatePart())
+ {
+ sal_Int32 nCount = pGroupDim->GetGroupCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( i );
+ if (pGroup)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, pGroup->GetGroupName());
+ SvXMLElementExport aElemDPG(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUP, sal_True, sal_True);
+ sal_Int32 nElemCount = pGroup->GetElementCount();
+ for(sal_Int32 j = 0; j < nElemCount; ++j)
+ {
+ const String* pElem = pGroup->GetElementByIndex( j );
+ if (pElem)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, *pElem);
+ SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Export display names only for ODF 1.2 extended or later.
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ }
+
+ if (pDim->IsDataLayout())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
+ rtl::OUString sValueStr;
+ ScXMLConverter::GetStringFromOrientation( sValueStr,
+ (sheet::DataPilotFieldOrientation) pDim->GetOrientation() );
+ if( sValueStr.getLength() )
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, sValueStr );
+ if (pDim->GetOrientation() == sheet::DataPilotFieldOrientation_PAGE)
+ if (pDim->HasCurrentPage())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, pDim->GetCurrentPage());
+ if (pDim->GetUsedHierarchy() != 1)
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, pDim->GetUsedHierarchy());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, sBuffer.makeStringAndClear());
+ }
+ ScXMLConverter::GetStringFromFunction( sValueStr,
+ (sheet::GeneralFunction) pDim->GetFunction() );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sValueStr);
+
+ SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, sal_True, sal_True);
+ WriteFieldReference(pDim);
+ WriteLevels(pDim);
+ if( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_DATA )
+ WriteGroupDimElements(pDim, pDimData);
+}
+
+void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
+{
+ List aDimensions = pDPSave->GetDimensions();
+ sal_Int32 nDimCount = aDimensions.Count();
+ for (sal_Int32 nDim = 0; nDim < nDimCount; nDim++)
+ {
+ WriteDimension((ScDPSaveDimension*)aDimensions.GetObject(nDim), pDPSave->GetExistingDimensionData());
+ }
+}
+
+void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient);
+ if (pGrandTotal)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal);
+
+ SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
+}
+
+void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
+{
+ pDoc = rExport.GetDocument();
+ if (pDoc)
+ {
+ ScDPCollection* pDPs = pDoc->GetDPCollection();
+ if (pDPs)
+ {
+ sal_Int16 nDPCount = pDPs->GetCount();
+ if (nDPCount > 0)
+ {
+ SvXMLElementExport aElemDPs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (sal_Int16 i = 0; i < nDPCount; ++i)
+ {
+ ScDPSaveData* pDPSave = (*pDPs)[i]->GetSaveData();
+ if (pDPSave)
+ {
+ ScRange aOutRange((*pDPs)[i]->GetOutRange());
+ rtl::OUString sTargetRangeAddress;
+ ScRangeStringConverter::GetStringFromRange( sTargetRangeAddress, aOutRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ ScDocAttrIterator aAttrItr(pDoc, aOutRange.aStart.Tab(),
+ aOutRange.aStart.Col(), aOutRange.aStart.Row(),
+ aOutRange.aEnd.Col(), aOutRange.aEnd.Row());
+ SCCOL nCol;
+ SCROW nRow1, nRow2;
+ rtl::OUString sOUButtonList;
+ const ScPatternAttr* pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
+ while (pAttr)
+ {
+ ScMergeFlagAttr& rItem = (ScMergeFlagAttr&)pAttr->GetItem(ATTR_MERGE_FLAG);
+ if (rItem.HasButton())
+ {
+ for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow)
+ {
+ ScAddress aButtonAddr(nCol, nButtonRow, aOutRange.aStart.Tab());
+ ScRangeStringConverter::GetStringFromAddress(
+ sOUButtonList, aButtonAddr, pDoc, ::formula::FormulaGrammar::CONV_OOO, ' ', sal_True );
+ }
+ }
+ pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
+ }
+ rtl::OUString sName((*pDPs)[i]->GetName());
+ rtl::OUString sApplicationData((*pDPs)[i]->GetTag());
+ sal_Bool bRowGrand = pDPSave->GetRowGrand();
+ sal_Bool bColumnGrand = pDPSave->GetColumnGrand();
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, sApplicationData);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sTargetRangeAddress);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BUTTONS, sOUButtonList);
+ if (!(bRowGrand && bColumnGrand))
+ {
+ if (bRowGrand)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_ROW);
+ else if (bColumnGrand)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_COLUMN);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_NONE);
+ }
+ if (pDPSave->GetIgnoreEmptyRows())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TRUE);
+ if (pDPSave->GetRepeatIfEmpty())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TRUE);
+ if (!pDPSave->GetFilterButton())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_FALSE);
+ if (!pDPSave->GetDrillDown())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE);
+ SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True);
+
+ // grand total elements.
+
+ const OUString* pGrandTotalName = pDPSave->GetGrandTotalName();
+ if (pGrandTotalName && rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Use the new data-pilot-grand-total element.
+ if (bRowGrand && bColumnGrand)
+ {
+ WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
+ }
+ else
+ {
+ WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
+ WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
+ }
+ }
+
+ rExport.CheckAttrList();
+ if ((*pDPs)[i]->IsSheetData())
+ {
+ const ScSheetSourceDesc* pSheetSource = (*pDPs)[i]->GetSheetDesc();
+ rtl::OUString sCellRangeAddress;
+ ScRangeStringConverter::GetStringFromRange( sCellRangeAddress, pSheetSource->aSourceRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sCellRangeAddress);
+ SvXMLElementExport aElemSCR(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ WriteDPFilter(pSheetSource->aQueryParam);
+ }
+ else if ((*pDPs)[i]->IsImportData())
+ {
+ const ScImportSourceDesc* pImpSource = (*pDPs)[i]->GetImportSourceDesc();
+ switch (pImpSource->nType)
+ {
+ case sheet::DataImportMode_NONE : break;
+ case sheet::DataImportMode_QUERY :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, rtl::OUString(pImpSource->aObject));
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_TABLE :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, rtl::OUString(pImpSource->aObject));
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_SQL :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, rtl::OUString(pImpSource->aObject));
+ if (!pImpSource->bNative)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ break;
+ }
+ }
+ else if ((*pDPs)[i]->IsServiceData())
+ {
+ const ScDPServiceDesc* pServSource = (*pDPs)[i]->GetDPServiceDesc();
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString(pServSource->aServiceName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_NAME, rtl::OUString(pServSource->aParSource));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OBJECT_NAME, rtl::OUString(pServSource->aParName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USER_NAME, rtl::OUString(pServSource->aParUser));
+ // #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content
+ // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, rtl::OUString(pServSource->aParPass));
+ SvXMLElementExport aElemSD(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ WriteDimensions(pDPSave);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx
new file mode 100644
index 000000000000..600d96aa1d73
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDataPilot.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTDATAPILOT_HXX
+#define SC_XMLEXPORTDATAPILOT_HXX
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <rtl/ustring.hxx>
+#include "global.hxx"
+#include "xmloff/xmltoken.hxx"
+
+class ScXMLExport;
+class ScDocument;
+class ScDPSaveDimension;
+class ScDPSaveData;
+class ScDPDimensionSaveData;
+class ScDPSaveGroupDimension;
+class ScDPSaveNumGroupDimension;
+struct ScDPNumGroupInfo;
+struct ScQueryParam;
+
+class ScXMLExportDataPilot
+{
+ ScXMLExport& rExport;
+ ScDocument* pDoc;
+
+ rtl::OUString getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions,
+ const sal_Bool bIsString, const double dVal, const String& sVal) const;
+ void WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions);
+ void WriteDPFilter(const ScQueryParam& aQueryParam);
+
+ void WriteFieldReference(ScDPSaveDimension* pDim);
+ void WriteSortInfo(ScDPSaveDimension* pDim);
+ void WriteAutoShowInfo(ScDPSaveDimension* pDim);
+ void WriteLayoutInfo(ScDPSaveDimension* pDim);
+ void WriteSubTotals(ScDPSaveDimension* pDim);
+ void WriteMembers(ScDPSaveDimension* pDim);
+ void WriteLevels(ScDPSaveDimension* pDim);
+ void WriteDatePart(sal_Int32 nPart);
+ void WriteNumGroupInfo(const ScDPNumGroupInfo& pGroupInfo);
+ void WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim);
+ void WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
+ void WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim);
+ void WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
+ void WriteDimensions(ScDPSaveData* pDPSave);
+
+ void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const ::rtl::OUString* pGrandTotal);
+
+public:
+ ScXMLExportDataPilot(ScXMLExport& rExport);
+ ~ScXMLExportDataPilot();
+ void WriteDataPilots(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreaDoc);
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
new file mode 100644
index 000000000000..3c7ee76c41e8
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -0,0 +1,699 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportDatabaseRanges.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include "xmlexprt.hxx"
+#include "XMLExportIterator.hxx"
+#include "XMLConverter.hxx"
+#include "unonames.hxx"
+#include "dbcolect.hxx"
+#include "document.hxx"
+#include "globstr.hrc"
+#include "XMLExportSharedData.hxx"
+#include "rangeutl.hxx"
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/table/TableSortFieldType.hpp>
+#include <com/sun/star/sheet/XSubTotalField.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <tools/debug.hxx>
+#include <comphelper/extract.hxx>
+
+//! not found in unonames.hxx
+#define SC_USERLIST "UserList"
+#define SC_SORTASCENDING "SortAscending"
+#define SC_ENABLEUSERSORTLIST "EnableUserSortList"
+#define SC_USERSORTLISTINDEX "UserSortListIndex"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport)
+ : rExport(rTempExport),
+ pDoc( NULL )
+{
+}
+
+ScXMLExportDatabaseRanges::~ScXMLExportDatabaseRanges()
+{
+}
+
+ScMyEmptyDatabaseRangesContainer ScXMLExportDatabaseRanges::GetEmptyDatabaseRanges()
+{
+ ScMyEmptyDatabaseRangesContainer aSkipRanges;
+ if (rExport.GetModel().is())
+ {
+ sal_Int32 nSkipRangesCount = 0;
+ uno::Reference <beans::XPropertySet> xPropertySet (rExport.GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
+ rExport.CheckAttrList();
+ if (xDatabaseRanges.is())
+ {
+ uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames());
+ sal_Int32 nDatabaseRangesCount = aRanges.getLength();
+ for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
+ {
+ rtl::OUString sDatabaseRangeName(aRanges[i]);
+ uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
+ if (xDatabaseRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY);
+ if (xDatabaseRangePropertySet.is() &&
+ ::cppu::any2bool(xDatabaseRangePropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)))))
+ {
+ uno::Sequence <beans::PropertyValue> aImportProperties(xDatabaseRange->getImportDescriptor());
+ sal_Int32 nLength = aImportProperties.getLength();
+ sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
+ for (sal_Int32 j = 0; j < nLength; ++j)
+ if (aImportProperties[j].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
+ aImportProperties[j].Value >>= nSourceType;
+ if (nSourceType != sheet::DataImportMode_NONE)
+ {
+ table::CellRangeAddress aArea = xDatabaseRange->getDataArea();
+ aSkipRanges.AddNewEmptyDatabaseRange(aArea);
+
+ // #105276#; set last row/column so default styles are collected
+ rExport.GetSharedData()->SetLastColumn(aArea.Sheet, aArea.EndColumn);
+ rExport.GetSharedData()->SetLastRow(aArea.Sheet, aArea.EndRow);
+ }
+ }
+ }
+ }
+ if (nSkipRangesCount > 1)
+ aSkipRanges.Sort();
+ }
+ }
+ }
+ return aSkipRanges;
+}
+
+void ScXMLExportDatabaseRanges::WriteImportDescriptor(const uno::Sequence <beans::PropertyValue> aImportDescriptor)
+{
+ sal_Int32 nProperties = aImportDescriptor.getLength();
+ rtl::OUString sDatabaseName;
+ rtl::OUString sConRes;
+ rtl::OUString sSourceObject;
+ sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
+ sal_Bool bNative = sal_False;
+ for (sal_Int16 i = 0; i < nProperties; ++i)
+ {
+ if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME)))
+ aImportDescriptor[i].Value >>= sDatabaseName;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES)))
+ aImportDescriptor[i].Value >>= sConRes;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ)))
+ aImportDescriptor[i].Value >>= sSourceObject;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
+ aImportDescriptor[i].Value >>= nSourceType;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE)))
+ bNative = ::cppu::any2bool(aImportDescriptor[i].Value);
+ }
+ switch (nSourceType)
+ {
+ case sheet::DataImportMode_NONE : break;
+ case sheet::DataImportMode_QUERY :
+ {
+ if (sDatabaseName.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, sSourceObject);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
+ if (sConRes.getLength())
+ {
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_TABLE :
+ {
+ if (sDatabaseName.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sSourceObject);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
+ if (sConRes.getLength())
+ {
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_SQL :
+ {
+ if (sDatabaseName.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, sSourceObject);
+ if (!bNative)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
+ if (sConRes.getLength())
+ {
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const
+{
+ switch (aFilterOperator)
+ {
+ case sheet::FilterOperator2::EQUAL :
+ {
+ if (bUseRegularExpressions)
+ return GetXMLToken(XML_MATCH);
+ else
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ }
+ case sheet::FilterOperator2::NOT_EQUAL :
+ {
+ if (bUseRegularExpressions)
+ return GetXMLToken(XML_NOMATCH);
+ else
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ }
+ case sheet::FilterOperator2::BOTTOM_PERCENT :
+ return GetXMLToken(XML_BOTTOM_PERCENT);
+ case sheet::FilterOperator2::BOTTOM_VALUES :
+ return GetXMLToken(XML_BOTTOM_VALUES);
+ case sheet::FilterOperator2::EMPTY :
+ return GetXMLToken(XML_EMPTY);
+ case sheet::FilterOperator2::GREATER :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ case sheet::FilterOperator2::GREATER_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ case sheet::FilterOperator2::LESS :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ case sheet::FilterOperator2::LESS_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ case sheet::FilterOperator2::NOT_EMPTY :
+ return GetXMLToken(XML_NOEMPTY);
+ case sheet::FilterOperator2::TOP_PERCENT :
+ return GetXMLToken(XML_TOP_PERCENT);
+ case sheet::FilterOperator2::TOP_VALUES :
+ return GetXMLToken(XML_TOP_VALUES);
+ case sheet::FilterOperator2::CONTAINS :
+ return GetXMLToken(XML_CONTAINS);
+ case sheet::FilterOperator2::DOES_NOT_CONTAIN :
+ return GetXMLToken(XML_DOES_NOT_CONTAIN);
+ case sheet::FilterOperator2::BEGINS_WITH :
+ return GetXMLToken(XML_BEGINS_WITH);
+ case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH :
+ return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
+ case sheet::FilterOperator2::ENDS_WITH :
+ return GetXMLToken(XML_ENDS_WITH);
+ case sheet::FilterOperator2::DOES_NOT_END_WITH :
+ return GetXMLToken(XML_DOES_NOT_END_WITH);
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+}
+
+void ScXMLExportDatabaseRanges::WriteCondition(const sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aFilterField.Field));
+ if (bIsCaseSensitive)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+ if (aFilterField.IsNumeric)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ rtl::OUStringBuffer sBuffer;
+ rExport.GetMM100UnitConverter().convertDouble(sBuffer, aFilterField.NumericValue);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, sBuffer.makeStringAndClear());
+ }
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aFilterField.StringValue);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(aFilterField.Operator, bUseRegularExpressions));
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
+}
+
+void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName)
+{
+ uno::Sequence< sheet::TableFilterField2 > aTableFilterFields( xSheetFilterDescriptor->getFilterFields2() );
+ sal_Int32 nTableFilterFields = aTableFilterFields.getLength();
+ if (nTableFilterFields > 0)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT)))))
+ {
+ table::CellAddress aOutputPosition;
+ if (xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS))) >>= aOutputPosition)
+ {
+ rtl::OUString sOUCellAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress);
+ }
+ }
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ ScRange aAdvSource;
+ if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ {
+ rtl::OUString sOUCellAddress;
+ ScRangeStringConverter::GetStringFromRange( sOUCellAddress, aAdvSource, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sOUCellAddress);
+ }
+
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
+ SvXMLElementExport aElemF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
+ rExport.CheckAttrList();
+ sal_Bool bIsCaseSensitive = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE))));
+ sal_Bool bUseRegularExpressions = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX))));
+ sal_Bool bAnd = sal_False;
+ sal_Bool bOr = sal_False;
+ for (sal_Int32 i = 1; i < nTableFilterFields; ++i)
+ {
+ if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND)
+ bAnd = sal_True;
+ else
+ bOr = sal_True;
+ }
+ if (bOr && !bAnd)
+ {
+ SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nTableFilterFields; ++i)
+ {
+ WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ else if (bAnd && !bOr)
+ {
+ SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nTableFilterFields; ++i)
+ {
+ WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ else if (nTableFilterFields == 1)
+ {
+ WriteCondition(aTableFilterFields[0], bIsCaseSensitive, bUseRegularExpressions);
+ }
+ else
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ sheet::TableFilterField2 aPrevFilterField = aTableFilterFields[0];
+ sheet::FilterConnection aConnection = aTableFilterFields[1].Connection;
+ sal_Bool bOpenAndElement;
+ rtl::OUString aName = rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
+ if (aConnection == sheet::FilterConnection_AND)
+ {
+ rExport.StartElement( aName, sal_True);
+ bOpenAndElement = sal_True;
+ }
+ else
+ bOpenAndElement = sal_False;
+ for (sal_Int32 i = 1; i < nTableFilterFields; ++i)
+ {
+ if (aConnection != aTableFilterFields[i].Connection)
+ {
+ aConnection = aTableFilterFields[i].Connection;
+ if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND)
+ {
+ rExport.StartElement( aName, sal_True );
+ bOpenAndElement = sal_True;
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ aPrevFilterField = aTableFilterFields[i];
+ if (i == nTableFilterFields - 1)
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = sal_False;
+ }
+ }
+ else
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ aPrevFilterField = aTableFilterFields[i];
+ if (bOpenAndElement)
+ {
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = sal_False;
+ }
+ if (i == nTableFilterFields - 1)
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ }
+ else
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ aPrevFilterField = aTableFilterFields[i];
+ if (i == nTableFilterFields - 1)
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ if(bOpenAndElement)
+ rExport.EndElement(aName, sal_True);
+ }
+ }
+ }
+}
+
+void ScXMLExportDatabaseRanges::WriteSortDescriptor(const uno::Sequence <beans::PropertyValue> aSortProperties)
+{
+ uno::Sequence <table::TableSortField> aSortFields;
+ sal_Bool bBindFormatsToContent (sal_True);
+ sal_Bool bCopyOutputData (sal_False);
+// sal_Bool bIsCaseSensitive (sal_False);
+ sal_Bool bIsUserListEnabled (sal_False);
+ table::CellAddress aOutputPosition;
+ sal_Int32 nUserListIndex = 0;
+ sal_Int32 nProperties = aSortProperties.getLength();
+ sal_Int32 i;
+ for (i = 0; i < nProperties; ++i)
+ {
+ if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_BINDFMT) == 0)
+ bBindFormatsToContent = ::cppu::any2bool(aSortProperties[i].Value);
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COPYOUT) == 0)
+ bCopyOutputData = ::cppu::any2bool(aSortProperties[i].Value);
+// no longer supported
+/* else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISCASE) == 0)
+ bIsCaseSensitive = ::cppu::any2bool(aSortProperties[i].Value);*/
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISULIST) == 0)
+ bIsUserListEnabled = ::cppu::any2bool(aSortProperties[i].Value);
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_OUTPOS) == 0)
+ aSortProperties[i].Value >>= aOutputPosition;
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_UINDEX) == 0)
+ aSortProperties[i].Value >>= nUserListIndex;
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_SORTFLD) == 0)
+ aSortProperties[i].Value >>= aSortFields;
+// no longer supported
+/* else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COLLLOC) == 0)
+ aSortProperties[i].Value >>= aCollatorLocale;
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COLLALG) == 0)
+ aSortProperties[i].Value >>= sCollatorAlgorithm;*/
+ }
+ sal_Int32 nSortFields = aSortFields.getLength();
+ if (nSortFields > 0)
+ {
+ if (!bBindFormatsToContent)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+ if (bCopyOutputData)
+ {
+ rtl::OUString sOUCellAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress);
+ }
+// no longer supported
+// if (bIsCaseSensitive)
+// rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+
+ if (aSortFields[0].IsCaseSensitive)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+#ifdef DBG_UTIL
+ sal_Bool bCaseSensitive(aSortFields[0].IsCaseSensitive);
+ for (i = 1; i < nSortFields; ++i)
+ {
+ DBG_ASSERT(bCaseSensitive == aSortFields[i].IsCaseSensitive, "seems that it is now possible to have every field case sensitive");
+ }
+#endif
+// no longer supported
+/* if (aCollatorLocale.Language.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aCollatorLocale.Language);
+ if (aCollatorLocale.Country.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aCollatorLocale.Country);
+ if (sCollatorAlgorithm.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, sCollatorAlgorithm);*/
+ if (aSortFields[0].CollatorLocale.Language.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aSortFields[0].CollatorLocale.Language);
+ if (aSortFields[0].CollatorLocale.Country.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aSortFields[0].CollatorLocale.Country);
+ if (aSortFields[0].CollatorAlgorithm.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aSortFields[0].CollatorAlgorithm);
+#ifdef DBG_UTIL
+ rtl::OUString sLanguage(aSortFields[0].CollatorLocale.Language);
+ rtl::OUString sCountry(aSortFields[0].CollatorLocale.Country);
+ rtl::OUString sAlgorithm(aSortFields[0].CollatorAlgorithm);
+ for (i = 1; i < nSortFields; ++i)
+ {
+ DBG_ASSERT(sLanguage == aSortFields[i].CollatorLocale.Language, "seems that it is now possible to have every field localized");
+ DBG_ASSERT(sCountry == aSortFields[i].CollatorLocale.Country, "seems that it is now possible to have every field localized");
+ DBG_ASSERT(sAlgorithm == aSortFields[i].CollatorAlgorithm, "seems that it is now possible to have every field localized");
+ }
+#endif
+ SvXMLElementExport aElemS(rExport, XML_NAMESPACE_TABLE, XML_SORT, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (i = 0; i < nSortFields; ++i)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSortFields[i].Field));
+ if (!aSortFields[i].IsAscending)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+ if (!bIsUserListEnabled)
+ {
+ switch (aSortFields[i].FieldType)
+ {
+ case table::TableSortFieldType_ALPHANUMERIC :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TEXT);
+ break;
+ case table::TableSortFieldType_AUTOMATIC :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
+ break;
+ case table::TableSortFieldType_NUMERIC :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST)) + rtl::OUString::valueOf(nUserListIndex));
+ SvXMLElementExport aElemSb(rExport, XML_NAMESPACE_TABLE, XML_SORT_BY, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+}
+
+void ScXMLExportDatabaseRanges::WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName)
+{
+ uno::Reference <container::XIndexAccess> xIndexAccess (xSubTotalDescriptor, uno::UNO_QUERY);
+ if (xIndexAccess.is())
+ {
+ sal_Int32 nSubTotalFields = xIndexAccess->getCount();
+ if (nSubTotalFields > 0)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (xSubTotalDescriptor, uno::UNO_QUERY);
+// sal_Bool bEnableUserSortList = sal_False;
+// sal_Bool bSortAscending = sal_True;
+// sal_Int32 nUserSortListIndex = 0;
+ if (xPropertySet.is())
+ {
+ if (!::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+// bSortAscending = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SORTASCENDING))));
+// if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ENABLEUSERSORTLIST)))))
+// xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERSORTLISTINDEX))) >>= nUserSortListIndex;
+ }
+ SvXMLElementExport aElemSTRs(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, sal_True, sal_True);
+ rExport.CheckAttrList();
+ {
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam(aSubTotalParam);
+ if (aSubTotalParam.bDoSort)
+ {
+ if (!aSubTotalParam.bAscending)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+ if (aSubTotalParam.bUserDef)
+ {
+ rtl::OUString sUserList(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST));
+ sUserList += rtl::OUString::valueOf(aSubTotalParam.nUserIndex);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, sUserList);
+ }
+ SvXMLElementExport aElemSGs(rExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+ for (sal_Int32 i = 0; i < nSubTotalFields; ++i)
+ {
+ uno::Reference <sheet::XSubTotalField> xSubTotalField(xIndexAccess->getByIndex(i), uno::UNO_QUERY);
+ if (xSubTotalField.is())
+ {
+ sal_Int32 nGroupColumn = xSubTotalField->getGroupColumn();
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nGroupColumn));
+ SvXMLElementExport aElemSTR(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ uno::Sequence <sheet::SubTotalColumn> aSubTotalColumns = xSubTotalField->getSubTotalColumns();
+ sal_Int32 nSubTotalColumns = aSubTotalColumns.getLength();
+ for (sal_Int32 j = 0; j < nSubTotalColumns; ++j)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSubTotalColumns[j].Column));
+ rtl::OUString sFunction;
+ ScXMLConverter::GetStringFromFunction( sFunction, aSubTotalColumns[j].Function );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
+ SvXMLElementExport aElemSTF(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ pDoc = rExport.GetDocument();
+ if (pDoc)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
+ rExport.CheckAttrList();
+ if (xDatabaseRanges.is())
+ {
+ uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames());
+ sal_Int32 nDatabaseRangesCount = aRanges.getLength();
+ if (nDatabaseRangesCount > 0)
+ {
+ SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
+ {
+ rtl::OUString sDatabaseRangeName(aRanges[i]);
+ uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
+ if (xDatabaseRange.is())
+ {
+ rtl::OUString sOUUnbenannt (ScGlobal::GetRscString(STR_DB_NONAME));
+ if (sOUUnbenannt != sDatabaseRangeName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sDatabaseRangeName);
+ table::CellRangeAddress aRangeAddress(xDatabaseRange->getDataArea());
+ rtl::OUString sOUAddress;
+ ScRangeStringConverter::GetStringFromRange( sOUAddress, aRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute (XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUAddress);
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ if (pDBData->HasImportSelection())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
+ if (pDBData->HasAutoFilter())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE);
+ uno::Reference <beans::XPropertySet> xPropertySetDatabaseRange (xDatabaseRange, uno::UNO_QUERY);
+ if (xPropertySetDatabaseRange.is())
+ {
+ if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE);
+ if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE);
+ if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE);
+ }
+
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ uno::Sequence <beans::PropertyValue> aSortProperties(xDatabaseRange->getSortDescriptor());
+ if (xSheetFilterDescriptor.is())
+ {
+ uno::Reference <beans::XPropertySet> xFilterProperties (xSheetFilterDescriptor, uno::UNO_QUERY);
+ if (xFilterProperties.is())
+ {
+ if (!::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE);
+
+ // #98317#; there is no orientation on the filter
+/* table::TableOrientation eFilterOrient(table::TableOrientation_ROWS);
+ if (::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT)))))
+ eFilterOrient = table::TableOrientation_ROWS;*/
+
+ sal_Bool bSortColumns(sal_True);
+ sal_Bool bFound(sal_False);
+ sal_Int32 nProperty(0);
+ while (!bFound && (nProperty < aSortProperties.getLength()))
+ {
+ if (aSortProperties[nProperty].Name.compareToAscii(SC_UNONAME_ISSORTCOLUMNS) == 0)
+ {
+ bSortColumns = ::cppu::any2bool(aSortProperties[nProperty].Value);
+ bFound = sal_True;
+ }
+ else
+ ++nProperty;
+ }
+
+ if (bSortColumns)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN);
+ }
+ }
+ sal_Int32 nRefresh( pDBData->GetRefreshDelay() );
+ if( nRefresh )
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
+ rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
+ }
+ SvXMLElementExport aElemDR(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ WriteImportDescriptor(xDatabaseRange->getImportDescriptor());
+ if (xSheetFilterDescriptor.is())
+ WriteFilterDescriptor(xSheetFilterDescriptor, sDatabaseRangeName);
+ WriteSortDescriptor(aSortProperties);
+ WriteSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor(), sDatabaseRangeName);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.hxx b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
new file mode 100644
index 000000000000..a581eb1271f1
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTDATABASERANGES_HXX
+#define SC_XMLEXPORTDATABASERANGES_HXX
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+class ScXMLExport;
+class ScDocument;
+class ScMyEmptyDatabaseRangesContainer;
+
+class ScXMLExportDatabaseRanges
+{
+ ScXMLExport& rExport;
+ ScDocument* pDoc;
+
+ void WriteImportDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aImportDescriptor);
+ rtl::OUString getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const;
+ void WriteCondition(const com::sun::star::sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions);
+ void WriteFilterDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName);
+ void WriteSortDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aSortProperties);
+ void WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName);
+public:
+ ScXMLExportDatabaseRanges(ScXMLExport& rExport);
+ ~ScXMLExportDatabaseRanges();
+ ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges();
+ void WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc);
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLExportIterator.cxx b/sc/source/filter/xml/XMLExportIterator.cxx
new file mode 100644
index 000000000000..154fdebed95e
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportIterator.cxx
@@ -0,0 +1,892 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportIterator.hxx"
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <tools/debug.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include "dociter.hxx"
+#include "convuno.hxx"
+#include "xmlexprt.hxx"
+#include "XMLExportSharedData.hxx"
+#include "XMLStylesExportHelper.hxx"
+#include "document.hxx"
+
+#include <algorithm>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+
+//==============================================================================
+
+ScMyIteratorBase::ScMyIteratorBase()
+{
+}
+
+ScMyIteratorBase::~ScMyIteratorBase()
+{
+}
+
+void ScMyIteratorBase::UpdateAddress( table::CellAddress& rCellAddress )
+{
+ table::CellAddress aNewAddr( rCellAddress );
+ if( GetFirstAddress( aNewAddr ) )
+ {
+ if( (aNewAddr.Sheet == rCellAddress.Sheet) &&
+ ((aNewAddr.Row < rCellAddress.Row) ||
+ ((aNewAddr.Row == rCellAddress.Row) && (aNewAddr.Column < rCellAddress.Column))) )
+ rCellAddress = aNewAddr;
+ }
+}
+
+
+//==============================================================================
+
+sal_Bool ScMyShape::operator<(const ScMyShape& aShape) const
+{
+ if( aAddress.Tab() != aShape.aAddress.Tab() )
+ return (aAddress.Tab() < aShape.aAddress.Tab());
+ else if( aAddress.Row() != aShape.aAddress.Row() )
+ return (aAddress.Row() < aShape.aAddress.Row());
+ else
+ return (aAddress.Col() < aShape.aAddress.Col());
+}
+
+ScMyShapesContainer::ScMyShapesContainer()
+ : aShapeList()
+{
+}
+
+ScMyShapesContainer::~ScMyShapesContainer()
+{
+}
+
+void ScMyShapesContainer::AddNewShape( const ScMyShape& aShape )
+{
+ aShapeList.push_back(aShape);
+}
+
+sal_Bool ScMyShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aShapeList.empty() )
+ {
+ ScUnoConversion::FillApiAddress( rCellAddress, aShapeList.begin()->aAddress );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyShapesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aShapeList.clear();
+ ScAddress aAddress;
+ ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
+
+ ScMyShapeList::iterator aItr(aShapeList.begin());
+ ScMyShapeList::iterator aEndItr(aShapeList.end());
+ while( (aItr != aEndItr) && (aItr->aAddress == aAddress) )
+ {
+ rMyCell.aShapeList.push_back(*aItr);
+ aItr = aShapeList.erase(aItr);
+ }
+ rMyCell.bHasShape = !rMyCell.aShapeList.empty();
+}
+
+void ScMyShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyShapeList::iterator aItr = aShapeList.begin();
+ while( (aItr != aShapeList.end()) && (aItr->aAddress.Tab() == nSkip) )
+ aItr = aShapeList.erase(aItr);
+}
+
+void ScMyShapesContainer::Sort()
+{
+ aShapeList.sort();
+}
+
+sal_Bool ScMyNoteShape::operator<(const ScMyNoteShape& aNote) const
+{
+ if( aPos.Tab() != aNote.aPos.Tab() )
+ return (aPos.Tab() < aNote.aPos.Tab());
+ else if( aPos.Row() != aNote.aPos.Row() )
+ return (aPos.Row() < aNote.aPos.Row());
+ else
+ return (aPos.Col() < aNote.aPos.Col());
+}
+
+ScMyNoteShapesContainer::ScMyNoteShapesContainer()
+ : aNoteShapeList()
+{
+}
+
+ScMyNoteShapesContainer::~ScMyNoteShapesContainer()
+{
+}
+
+void ScMyNoteShapesContainer::AddNewNote( const ScMyNoteShape& aNote )
+{
+ aNoteShapeList.push_back(aNote);
+}
+
+sal_Bool ScMyNoteShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int16 nTable = rCellAddress.Sheet;
+ if( !aNoteShapeList.empty() )
+ {
+ ScUnoConversion::FillApiAddress( rCellAddress, aNoteShapeList.begin()->aPos );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.xNoteShape.clear();
+ ScAddress aAddress;
+ ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
+
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos == aAddress) )
+ {
+ rMyCell.xNoteShape = aItr->xShape;
+ aItr = aNoteShapeList.erase(aItr);
+ }
+}
+
+void ScMyNoteShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos.Tab() == nSkip) )
+ aItr = aNoteShapeList.erase(aItr);
+}
+
+void ScMyNoteShapesContainer::Sort()
+{
+ aNoteShapeList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyMergedRange::operator<(const ScMyMergedRange& aRange) const
+{
+ if( aCellRange.Sheet != aRange.aCellRange.Sheet )
+ return (aCellRange.Sheet < aRange.aCellRange.Sheet);
+ else if( aCellRange.StartRow != aRange.aCellRange.StartRow )
+ return (aCellRange.StartRow < aRange.aCellRange.StartRow);
+ else
+ return (aCellRange.StartColumn < aRange.aCellRange.StartColumn);
+}
+
+
+ScMyMergedRangesContainer::ScMyMergedRangesContainer()
+ : aRangeList()
+{
+}
+
+ScMyMergedRangesContainer::~ScMyMergedRangesContainer()
+{
+}
+
+void ScMyMergedRangesContainer::AddRange(const table::CellRangeAddress aMergedRange)
+{
+ sal_Int32 nStartRow(aMergedRange.StartRow);
+ sal_Int32 nEndRow(aMergedRange.EndRow);
+
+ ScMyMergedRange aRange;
+ aRange.bIsFirst = sal_True;
+ aRange.aCellRange = aMergedRange;
+ aRange.aCellRange.EndRow = nStartRow;
+ aRange.nRows = nEndRow - nStartRow + 1;
+ aRangeList.push_back( aRange );
+
+ aRange.bIsFirst = sal_False;
+ aRange.nRows = 0;
+ for( sal_Int32 nRow = nStartRow + 1; nRow <= nEndRow; ++nRow )
+ {
+ aRange.aCellRange.StartRow = aRange.aCellRange.EndRow = nRow;
+ aRangeList.push_back(aRange);
+ }
+}
+
+sal_Bool ScMyMergedRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aRangeList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, aRangeList.begin()->aCellRange );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyMergedRangesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bIsMergedBase = rMyCell.bIsCovered = sal_False;
+ ScMyMergedRangeList::iterator aItr(aRangeList.begin());
+ if( aItr != aRangeList.end() )
+ {
+ table::CellAddress aFirstAddress;
+ ScUnoConversion::FillApiStartAddress( aFirstAddress, aItr->aCellRange );
+ if( aFirstAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.aMergeRange = aItr->aCellRange;
+ if (aItr->bIsFirst)
+ rMyCell.aMergeRange.EndRow = rMyCell.aMergeRange.StartRow + aItr->nRows - 1;
+ rMyCell.bIsMergedBase = aItr->bIsFirst;
+ rMyCell.bIsCovered = !aItr->bIsFirst;
+ if( aItr->aCellRange.StartColumn < aItr->aCellRange.EndColumn )
+ {
+ ++(aItr->aCellRange.StartColumn);
+ aItr->bIsFirst = sal_False;
+ }
+ else
+ aRangeList.erase(aItr);
+ }
+ }
+}
+
+void ScMyMergedRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyMergedRangeList::iterator aItr = aRangeList.begin();
+ while( (aItr != aRangeList.end()) && (aItr->aCellRange.Sheet == nSkip) )
+ aItr = aRangeList.erase(aItr);
+}
+
+void ScMyMergedRangesContainer::Sort()
+{
+ aRangeList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyAreaLink::Compare( const ScMyAreaLink& rAreaLink ) const
+{
+ return (GetRowCount() == rAreaLink.GetRowCount()) &&
+ (sFilter == rAreaLink.sFilter) &&
+ (sFilterOptions == rAreaLink.sFilterOptions) &&
+ (sURL == rAreaLink.sURL) &&
+ (sSourceStr == rAreaLink.sSourceStr);
+}
+
+sal_Bool ScMyAreaLink::operator<(const ScMyAreaLink& rAreaLink ) const
+{
+ if( aDestRange.Sheet != rAreaLink.aDestRange.Sheet )
+ return (aDestRange.Sheet < rAreaLink.aDestRange.Sheet);
+ else if( aDestRange.StartRow != rAreaLink.aDestRange.StartRow )
+ return (aDestRange.StartRow < rAreaLink.aDestRange.StartRow);
+ else
+ return (aDestRange.StartColumn < rAreaLink.aDestRange.StartColumn);
+}
+
+ScMyAreaLinksContainer::ScMyAreaLinksContainer() :
+ aAreaLinkList()
+{
+}
+
+ScMyAreaLinksContainer::~ScMyAreaLinksContainer()
+{
+}
+
+sal_Bool ScMyAreaLinksContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aAreaLinkList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, aAreaLinkList.begin()->aDestRange );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyAreaLinksContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bHasAreaLink = sal_False;
+ ScMyAreaLinkList::iterator aItr(aAreaLinkList.begin());
+ if( aItr != aAreaLinkList.end() )
+ {
+ table::CellAddress aAddress;
+ ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
+ if( aAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.bHasAreaLink = sal_True;
+ rMyCell.aAreaLink = *aItr;
+ aItr = aAreaLinkList.erase( aItr );
+ sal_Bool bFound = sal_True;
+ while (aItr != aAreaLinkList.end() && bFound)
+ {
+ ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
+ if (aAddress == rMyCell.aCellAddress)
+ {
+ DBG_ERROR("more than one linked range on one cell");
+ aItr = aAreaLinkList.erase( aItr );
+ }
+ else
+ bFound = sal_False;
+ }
+ }
+ }
+}
+
+void ScMyAreaLinksContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyAreaLinkList::iterator aItr = aAreaLinkList.begin();
+ while( (aItr != aAreaLinkList.end()) && (aItr->aDestRange.Sheet == nSkip) )
+ aItr = aAreaLinkList.erase(aItr);
+}
+
+void ScMyAreaLinksContainer::Sort()
+{
+ aAreaLinkList.sort();
+}
+
+//==============================================================================
+
+ScMyCellRangeAddress::ScMyCellRangeAddress(const table::CellRangeAddress& rRange)
+ : table::CellRangeAddress(rRange)
+{
+}
+
+sal_Bool ScMyCellRangeAddress::operator<(const ScMyCellRangeAddress& rRange ) const
+{
+ if( Sheet != rRange.Sheet )
+ return (Sheet < rRange.Sheet);
+ else if( StartRow != rRange.StartRow )
+ return (StartRow < rRange.StartRow);
+ else
+ return (StartColumn < rRange.StartColumn);
+}
+
+ScMyEmptyDatabaseRangesContainer::ScMyEmptyDatabaseRangesContainer()
+ : aDatabaseList()
+{
+}
+
+ScMyEmptyDatabaseRangesContainer::~ScMyEmptyDatabaseRangesContainer()
+{
+}
+
+void ScMyEmptyDatabaseRangesContainer::AddNewEmptyDatabaseRange(const table::CellRangeAddress& aCellRange)
+{
+ sal_Int32 nStartRow(aCellRange.StartRow);
+ sal_Int32 nEndRow(aCellRange.EndRow);
+ ScMyCellRangeAddress aRange( aCellRange );
+ for( sal_Int32 nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ aRange.StartRow = aRange.EndRow = nRow;
+ aDatabaseList.push_back( aRange );
+ }
+}
+
+sal_Bool ScMyEmptyDatabaseRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDatabaseList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, *(aDatabaseList.begin()) );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyEmptyDatabaseRangesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bHasEmptyDatabase = sal_False;
+ ScMyEmptyDatabaseRangeList::iterator aItr(aDatabaseList.begin());
+ if( aItr != aDatabaseList.end() )
+ {
+ table::CellAddress aFirstAddress;
+ ScUnoConversion::FillApiStartAddress( aFirstAddress, *aItr );
+ if( aFirstAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.bHasEmptyDatabase = sal_True;
+ if( aItr->StartColumn < aItr->EndColumn )
+ ++(aItr->StartColumn);
+ else
+ aDatabaseList.erase(aItr);
+ }
+ }
+}
+
+void ScMyEmptyDatabaseRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyEmptyDatabaseRangeList::iterator aItr = aDatabaseList.begin();
+ while( (aItr != aDatabaseList.end()) && (aItr->Sheet == nSkip) )
+ aItr = aDatabaseList.erase(aItr);
+}
+
+void ScMyEmptyDatabaseRangesContainer::Sort()
+{
+ aDatabaseList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyDetectiveObj::operator<( const ScMyDetectiveObj& rDetObj) const
+{
+ if( aPosition.Sheet != rDetObj.aPosition.Sheet )
+ return (aPosition.Sheet < rDetObj.aPosition.Sheet);
+ else if( aPosition.Row != rDetObj.aPosition.Row )
+ return (aPosition.Row < rDetObj.aPosition.Row);
+ else
+ return (aPosition.Column < rDetObj.aPosition.Column);
+}
+
+ScMyDetectiveObjContainer::ScMyDetectiveObjContainer() :
+ aDetectiveObjList()
+{
+}
+
+ScMyDetectiveObjContainer::~ScMyDetectiveObjContainer()
+{
+}
+
+void ScMyDetectiveObjContainer::AddObject( ScDetectiveObjType eObjType, const SCTAB nSheet,
+ const ScAddress& rPosition, const ScRange& rSourceRange,
+ sal_Bool bHasError )
+{
+ if( (eObjType == SC_DETOBJ_ARROW) ||
+ (eObjType == SC_DETOBJ_FROMOTHERTAB) ||
+ (eObjType == SC_DETOBJ_TOOTHERTAB) ||
+ (eObjType == SC_DETOBJ_CIRCLE) )
+ {
+ ScMyDetectiveObj aDetObj;
+ aDetObj.eObjType = eObjType;
+ if( eObjType == SC_DETOBJ_TOOTHERTAB )
+ ScUnoConversion::FillApiAddress( aDetObj.aPosition, rSourceRange.aStart );
+ else
+ ScUnoConversion::FillApiAddress( aDetObj.aPosition, rPosition );
+ ScUnoConversion::FillApiRange( aDetObj.aSourceRange, rSourceRange );
+
+ // #111064#; take the sheet where the object is found and not the sheet given in the ranges, because they are not always true
+ if (eObjType != SC_DETOBJ_FROMOTHERTAB)
+ {
+ // if the ObjType == SC_DETOBJ_FROMOTHERTAB then the SourceRange is not used and so it has not to be tested and changed
+ DBG_ASSERT(aDetObj.aPosition.Sheet == aDetObj.aSourceRange.Sheet, "It seems to be possible to have different sheets");
+ aDetObj.aSourceRange.Sheet = nSheet;
+ }
+ aDetObj.aPosition.Sheet = nSheet;
+
+ aDetObj.bHasError = bHasError;
+ aDetectiveObjList.push_back( aDetObj );
+ }
+}
+
+sal_Bool ScMyDetectiveObjContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDetectiveObjList.empty() )
+ {
+ rCellAddress = aDetectiveObjList.begin()->aPosition;
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyDetectiveObjContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aDetectiveObjVec.clear();
+ ScMyDetectiveObjList::iterator aItr(aDetectiveObjList.begin());
+ ScMyDetectiveObjList::iterator aEndItr(aDetectiveObjList.end());
+ while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
+ {
+ rMyCell.aDetectiveObjVec.push_back( *aItr );
+ aItr = aDetectiveObjList.erase( aItr );
+ }
+ rMyCell.bHasDetectiveObj = (rMyCell.aDetectiveObjVec.size() != 0);
+}
+
+void ScMyDetectiveObjContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveObjList::iterator aItr = aDetectiveObjList.begin();
+ while( (aItr != aDetectiveObjList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveObjList.erase(aItr);
+}
+
+void ScMyDetectiveObjContainer::Sort()
+{
+ aDetectiveObjList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyDetectiveOp::operator<( const ScMyDetectiveOp& rDetOp) const
+{
+ if( aPosition.Sheet != rDetOp.aPosition.Sheet )
+ return (aPosition.Sheet < rDetOp.aPosition.Sheet);
+ else if( aPosition.Row != rDetOp.aPosition.Row )
+ return (aPosition.Row < rDetOp.aPosition.Row);
+ else
+ return (aPosition.Column < rDetOp.aPosition.Column);
+}
+
+ScMyDetectiveOpContainer::ScMyDetectiveOpContainer() :
+ aDetectiveOpList()
+{
+}
+
+ScMyDetectiveOpContainer::~ScMyDetectiveOpContainer()
+{
+}
+
+void ScMyDetectiveOpContainer::AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex )
+{
+ ScMyDetectiveOp aDetOp;
+ aDetOp.eOpType = eOpType;
+ ScUnoConversion::FillApiAddress( aDetOp.aPosition, rPosition );
+ aDetOp.nIndex = nIndex;
+ aDetectiveOpList.push_back( aDetOp );
+}
+
+sal_Bool ScMyDetectiveOpContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDetectiveOpList.empty() )
+ {
+ rCellAddress = aDetectiveOpList.begin()->aPosition;
+ return (nTable == rCellAddress.Sheet);
+ }
+ return sal_False;
+}
+
+void ScMyDetectiveOpContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aDetectiveOpVec.clear();
+ ScMyDetectiveOpList::iterator aItr(aDetectiveOpList.begin());
+ ScMyDetectiveOpList::iterator aEndItr(aDetectiveOpList.end());
+ while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
+ {
+ rMyCell.aDetectiveOpVec.push_back( *aItr );
+ aItr = aDetectiveOpList.erase( aItr );
+ }
+ rMyCell.bHasDetectiveOp = (rMyCell.aDetectiveOpVec.size() != 0);
+}
+
+void ScMyDetectiveOpContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
+ while( (aItr != aDetectiveOpList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveOpList.erase(aItr);
+}
+
+void ScMyDetectiveOpContainer::Sort()
+{
+ aDetectiveOpList.sort();
+}
+
+//==============================================================================
+
+ScMyCell::ScMyCell() :
+ aShapeList(),
+ aDetectiveObjVec(),
+ nValidationIndex(-1),
+ pBaseCell(NULL),
+ bIsAutoStyle( sal_False ),
+ bHasShape( sal_False ),
+ bIsMergedBase( sal_False ),
+ bIsCovered( sal_False ),
+ bHasAreaLink( sal_False ),
+ bHasEmptyDatabase( sal_False ),
+ bHasDetectiveObj( sal_False ),
+ bHasDetectiveOp( sal_False ),
+ bIsEditCell( sal_False ),
+ bKnowWhetherIsEditCell( sal_False ),
+ bHasStringValue( sal_False ),
+ bHasDoubleValue( sal_False ),
+ bHasXText( sal_False ),
+ bIsMatrixBase( sal_False ),
+ bIsMatrixCovered( sal_False ),
+ bHasAnnotation( sal_False )
+{
+}
+
+ScMyCell::~ScMyCell()
+{
+}
+
+//==============================================================================
+
+sal_Bool ScMyExportAnnotation::operator<(const ScMyExportAnnotation& rAnno) const
+{
+ if( aCellAddress.Row != rAnno.aCellAddress.Row )
+ return (aCellAddress.Row < rAnno.aCellAddress.Row);
+ else
+ return (aCellAddress.Column < rAnno.aCellAddress.Column);
+}
+
+
+ScMyNotEmptyCellsIterator::ScMyNotEmptyCellsIterator(ScXMLExport& rTempXMLExport)
+ : pShapes(NULL),
+ pNoteShapes(NULL),
+ pEmptyDatabaseRanges(NULL),
+ pMergedRanges(NULL),
+ pAreaLinks(NULL),
+ pDetectiveObj(NULL),
+ pDetectiveOp(NULL),
+ rExport(rTempXMLExport),
+ pCellItr(NULL),
+ nCurrentTable(SCTAB_MAX)
+{
+}
+
+ScMyNotEmptyCellsIterator::~ScMyNotEmptyCellsIterator()
+{
+ Clear();
+}
+
+void ScMyNotEmptyCellsIterator::Clear()
+{
+ if (pCellItr)
+ delete pCellItr;
+ if (!aAnnotations.empty())
+ {
+ DBG_ERROR("not all Annotations saved");
+ aAnnotations.clear();
+ }
+ pCellItr = NULL;
+ pShapes = NULL;
+ pNoteShapes = NULL;
+ pMergedRanges = NULL;
+ pAreaLinks = NULL;
+ pEmptyDatabaseRanges = NULL;
+ pDetectiveObj = NULL;
+ pDetectiveOp = NULL;
+ nCurrentTable = SCTAB_MAX;
+}
+
+void ScMyNotEmptyCellsIterator::UpdateAddress( table::CellAddress& rAddress )
+{
+ if( pCellItr->ReturnNext( nCellCol, nCellRow ) )
+ {
+ rAddress.Column = nCellCol;
+ rAddress.Row = nCellRow;
+ }
+}
+
+void ScMyNotEmptyCellsIterator::SetCellData( ScMyCell& rMyCell, table::CellAddress& rAddress )
+{
+ rMyCell.aCellAddress = rAddress;
+ rMyCell.bHasStringValue = sal_False;
+ rMyCell.bHasDoubleValue = sal_False;
+ rMyCell.bHasXText = sal_False;
+ rMyCell.bKnowWhetherIsEditCell = sal_False;
+ rMyCell.bIsEditCell = sal_False;
+ if( (nCellCol == rAddress.Column) && (nCellRow == rAddress.Row) )
+ pCellItr->GetNext( nCellCol, nCellRow );
+}
+
+void ScMyNotEmptyCellsIterator::SetMatrixCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bIsMatrixCovered = sal_False;
+ rMyCell.bIsMatrixBase = sal_False;
+
+ sal_Bool bIsMatrixBase(sal_False);
+
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rMyCell.aCellAddress );
+ CellType eCalcType = rExport.GetDocument()->GetCellType( aScAddress );
+ switch (eCalcType)
+ {
+ case CELLTYPE_VALUE:
+ rMyCell.nType = table::CellContentType_VALUE;
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ rMyCell.nType = table::CellContentType_TEXT;
+ break;
+ case CELLTYPE_FORMULA:
+ rMyCell.nType = table::CellContentType_FORMULA;
+ break;
+ default:
+ rMyCell.nType = table::CellContentType_EMPTY;
+ }
+
+ if (rMyCell.nType == table::CellContentType_FORMULA)
+ if( rExport.IsMatrix( aScAddress, rMyCell.aMatrixRange, bIsMatrixBase ) )
+ {
+ rMyCell.bIsMatrixBase = bIsMatrixBase;
+ rMyCell.bIsMatrixCovered = !bIsMatrixBase;
+ }
+}
+
+void ScMyNotEmptyCellsIterator::HasAnnotation(ScMyCell& aCell)
+{
+ aCell.bHasAnnotation = sal_False;
+ if (!aAnnotations.empty())
+ {
+ ScMyExportAnnotationList::iterator aItr(aAnnotations.begin());
+ if ((aCell.aCellAddress.Column == aItr->aCellAddress.Column) &&
+ (aCell.aCellAddress.Row == aItr->aCellAddress.Row))
+ {
+ aCell.xAnnotation.set(aItr->xAnnotation);
+ uno::Reference<text::XSimpleText> xSimpleText(aCell.xAnnotation, uno::UNO_QUERY);
+ if (aCell.xAnnotation.is() && xSimpleText.is())
+ {
+ aCell.sAnnotationText = xSimpleText->getString();
+ if (aCell.sAnnotationText.getLength())
+ aCell.bHasAnnotation = sal_True;
+ }
+ aAnnotations.erase(aItr);
+ }
+ }
+
+ // test - bypass the API
+ // if (xCellRange.is())
+ // aCell.xCell.set(xCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row));
+}
+
+void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable,
+ uno::Reference<sheet::XSpreadsheet>& rxTable)
+{
+ DBG_ASSERT(aAnnotations.empty(), "not all Annotations saved");
+ aLastAddress.Row = 0;
+ aLastAddress.Column = 0;
+ aLastAddress.Sheet = nTable;
+ if (nCurrentTable != nTable)
+ {
+ nCurrentTable = nTable;
+ if (pCellItr)
+ delete pCellItr;
+ pCellItr = new ScHorizontalCellIterator(rExport.GetDocument(), nCurrentTable, 0, 0,
+ static_cast<SCCOL>(rExport.GetSharedData()->GetLastColumn(nCurrentTable)), static_cast<SCROW>(rExport.GetSharedData()->GetLastRow(nCurrentTable)));
+ xTable.set(rxTable);
+ xCellRange.set(xTable, uno::UNO_QUERY);
+ uno::Reference<sheet::XSheetAnnotationsSupplier> xSheetAnnotationsSupplier (xTable, uno::UNO_QUERY);
+ if (xSheetAnnotationsSupplier.is())
+ {
+ uno::Reference<container::XEnumerationAccess> xAnnotationAccess ( xSheetAnnotationsSupplier->getAnnotations(), uno::UNO_QUERY);
+ if (xAnnotationAccess.is())
+ {
+ uno::Reference<container::XEnumeration> xAnnotations(xAnnotationAccess->createEnumeration());
+ if (xAnnotations.is())
+ {
+ while (xAnnotations->hasMoreElements())
+ {
+ ScMyExportAnnotation aAnnotation;
+ aAnnotation.xAnnotation.set(xAnnotations->nextElement(), uno::UNO_QUERY);
+ if (aAnnotation.xAnnotation.is())
+ {
+ aAnnotation.aCellAddress = aAnnotation.xAnnotation->getPosition();
+ aAnnotations.push_back(aAnnotation);
+ }
+ }
+ if (!aAnnotations.empty())
+ aAnnotations.sort();
+ }
+ }
+ }
+ }
+}
+
+void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip)
+{
+ // Skip entries for a sheet that is copied instead of saving normally.
+ // Cells (including aAnnotations) are handled separately in SetCurrentTable.
+
+ if( pShapes )
+ pShapes->SkipTable(nSkip);
+ if( pNoteShapes )
+ pNoteShapes->SkipTable(nSkip);
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SkipTable(nSkip);
+ if( pMergedRanges )
+ pMergedRanges->SkipTable(nSkip);
+ if( pAreaLinks )
+ pAreaLinks->SkipTable(nSkip);
+ if( pDetectiveObj )
+ pDetectiveObj->SkipTable(nSkip);
+ if( pDetectiveOp )
+ pDetectiveOp->SkipTable(nSkip);
+}
+
+sal_Bool ScMyNotEmptyCellsIterator::GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles)
+{
+ table::CellAddress aAddress( nCurrentTable, MAXCOL + 1, MAXROW + 1 );
+
+ UpdateAddress( aAddress );
+ if( pShapes )
+ pShapes->UpdateAddress( aAddress );
+ if( pNoteShapes )
+ pNoteShapes->UpdateAddress( aAddress );
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->UpdateAddress( aAddress );
+ if( pMergedRanges )
+ pMergedRanges->UpdateAddress( aAddress );
+ if( pAreaLinks )
+ pAreaLinks->UpdateAddress( aAddress );
+ if( pDetectiveObj )
+ pDetectiveObj->UpdateAddress( aAddress );
+ if( pDetectiveOp )
+ pDetectiveOp->UpdateAddress( aAddress );
+
+ sal_Bool bFoundCell((aAddress.Column <= MAXCOL) && (aAddress.Row <= MAXROW));
+ if( bFoundCell )
+ {
+ SetCellData( aCell, aAddress );
+ if( pShapes )
+ pShapes->SetCellData( aCell );
+ if( pNoteShapes )
+ pNoteShapes->SetCellData( aCell );
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SetCellData( aCell );
+ if( pMergedRanges )
+ pMergedRanges->SetCellData( aCell );
+ if( pAreaLinks )
+ pAreaLinks->SetCellData( aCell );
+ if( pDetectiveObj )
+ pDetectiveObj->SetCellData( aCell );
+ if( pDetectiveOp )
+ pDetectiveOp->SetCellData( aCell );
+
+ HasAnnotation( aCell );
+ SetMatrixCellData( aCell );
+ sal_Bool bIsAutoStyle;
+ // Ranges before the previous cell are not needed by ExportFormatRanges anymore and can be removed
+ sal_Int32 nRemoveBeforeRow = aLastAddress.Row;
+ aCell.nStyleIndex = pCellStyles->GetStyleNameIndex(aCell.aCellAddress.Sheet,
+ aCell.aCellAddress.Column, aCell.aCellAddress.Row,
+ bIsAutoStyle, aCell.nValidationIndex, aCell.nNumberFormat, nRemoveBeforeRow);
+ aLastAddress = aCell.aCellAddress;
+ aCell.bIsAutoStyle = bIsAutoStyle;
+
+ //#102799#; if the cell is in a DatabaseRange which should saved empty, the cell should have the type empty
+ if (aCell.bHasEmptyDatabase)
+ aCell.nType = table::CellContentType_EMPTY;
+ }
+ return bFoundCell;
+}
+
diff --git a/sc/source/filter/xml/XMLExportIterator.hxx b/sc/source/filter/xml/XMLExportIterator.hxx
new file mode 100644
index 000000000000..dfd3a4d59ac1
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportIterator.hxx
@@ -0,0 +1,413 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTITERATOR_HXX
+#define SC_XMLEXPORTITERATOR_HXX
+
+#include <vector>
+#include <list>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include "global.hxx"
+#include "detfunc.hxx"
+#include "detdata.hxx"
+
+class ScHorizontalCellIterator;
+struct ScMyCell;
+class ScXMLExport;
+class ScFormatRangeStyles;
+class ScBaseCell;
+
+//==============================================================================
+
+class ScMyIteratorBase
+{
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ) = 0;
+
+public:
+ ScMyIteratorBase();
+ virtual ~ScMyIteratorBase();
+
+ virtual void SetCellData( ScMyCell& rMyCell ) = 0;
+ virtual void Sort() = 0;
+
+ virtual void UpdateAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+};
+
+//==============================================================================
+
+struct ScMyShape
+{
+ ScAddress aAddress;
+ ScAddress aEndAddress;
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape;
+
+ sal_Bool operator<(const ScMyShape& aShape) const;
+};
+
+typedef std::list<ScMyShape> ScMyShapeList;
+
+class ScMyShapesContainer : ScMyIteratorBase
+{
+private:
+ ScMyShapeList aShapeList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyShapesContainer();
+ virtual ~ScMyShapesContainer();
+
+ using ScMyIteratorBase::UpdateAddress;
+ void AddNewShape(const ScMyShape& aShape);
+ sal_Bool HasShapes() { return !aShapeList.empty(); }
+ const ScMyShapeList* GetShapes() { return &aShapeList; }
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+struct ScMyNoteShape
+{
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape;
+ ScAddress aPos;
+
+ sal_Bool operator<(const ScMyNoteShape& aNote) const;
+};
+
+typedef std::list<ScMyNoteShape> ScMyNoteShapeList;
+
+class ScMyNoteShapesContainer : ScMyIteratorBase
+{
+private:
+ ScMyNoteShapeList aNoteShapeList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyNoteShapesContainer();
+ virtual ~ScMyNoteShapesContainer();
+
+ using ScMyIteratorBase::UpdateAddress;
+ void AddNewNote(const ScMyNoteShape& aNote);
+ sal_Bool HasNotes() { return !aNoteShapeList.empty(); }
+ const ScMyNoteShapeList* GetNotes() { return &aNoteShapeList; }
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyMergedRange
+{
+ com::sun::star::table::CellRangeAddress aCellRange;
+ sal_Int32 nRows;
+ sal_Bool bIsFirst;
+ sal_Bool operator<(const ScMyMergedRange& aRange) const;
+};
+
+typedef std::list<ScMyMergedRange> ScMyMergedRangeList;
+
+class ScMyMergedRangesContainer : ScMyIteratorBase
+{
+private:
+ ScMyMergedRangeList aRangeList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyMergedRangesContainer();
+ virtual ~ScMyMergedRangesContainer();
+ void AddRange(const com::sun::star::table::CellRangeAddress aMergedRange);
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort(); // + remove doublets
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyAreaLink
+{
+ ::rtl::OUString sFilter;
+ ::rtl::OUString sFilterOptions;
+ ::rtl::OUString sURL;
+ ::rtl::OUString sSourceStr;
+ ::com::sun::star::table::CellRangeAddress aDestRange;
+ sal_Int32 nRefresh;
+
+ inline ScMyAreaLink() : nRefresh( 0 ) {}
+
+ inline sal_Int32 GetColCount() const { return aDestRange.EndColumn - aDestRange.StartColumn + 1; }
+ inline sal_Int32 GetRowCount() const { return aDestRange.EndRow - aDestRange.StartRow + 1; }
+
+ sal_Bool Compare( const ScMyAreaLink& rAreaLink ) const;
+ sal_Bool operator<(const ScMyAreaLink& rAreaLink ) const;
+};
+
+typedef ::std::list< ScMyAreaLink > ScMyAreaLinkList;
+
+class ScMyAreaLinksContainer : ScMyIteratorBase
+{
+private:
+ ScMyAreaLinkList aAreaLinkList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyAreaLinksContainer();
+ virtual ~ScMyAreaLinksContainer();
+
+ inline void AddNewAreaLink( const ScMyAreaLink& rAreaLink )
+ { aAreaLinkList.push_back( rAreaLink ); }
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyCellRangeAddress : com::sun::star::table::CellRangeAddress
+{
+ ScMyCellRangeAddress(const com::sun::star::table::CellRangeAddress& rRange);
+ sal_Bool operator<(const ScMyCellRangeAddress& rCellRangeAddress ) const;
+};
+
+typedef std::list<ScMyCellRangeAddress> ScMyEmptyDatabaseRangeList;
+
+class ScMyEmptyDatabaseRangesContainer : ScMyIteratorBase
+{
+private:
+ ScMyEmptyDatabaseRangeList aDatabaseList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyEmptyDatabaseRangesContainer();
+ virtual ~ScMyEmptyDatabaseRangesContainer();
+ void AddNewEmptyDatabaseRange(const com::sun::star::table::CellRangeAddress& aCellRangeAddress);
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyDetectiveObj
+{
+ ::com::sun::star::table::CellAddress aPosition;
+ ::com::sun::star::table::CellRangeAddress aSourceRange;
+ ScDetectiveObjType eObjType;
+ sal_Bool bHasError;
+ sal_Bool operator<(const ScMyDetectiveObj& rDetObj) const;
+};
+
+typedef ::std::list< ScMyDetectiveObj > ScMyDetectiveObjList;
+typedef ::std::vector< ScMyDetectiveObj > ScMyDetectiveObjVec;
+
+class ScMyDetectiveObjContainer : ScMyIteratorBase
+{
+private:
+ ScMyDetectiveObjList aDetectiveObjList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyDetectiveObjContainer();
+ virtual ~ScMyDetectiveObjContainer();
+
+ void AddObject(
+ ScDetectiveObjType eObjType,
+ const SCTAB nSheet,
+ const ScAddress& rPosition,
+ const ScRange& rSourceRange,
+ sal_Bool bHasError );
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyDetectiveOp
+{
+ ::com::sun::star::table::CellAddress aPosition;
+ ScDetOpType eOpType;
+ sal_Int32 nIndex;
+ sal_Bool operator<(const ScMyDetectiveOp& rDetOp) const;
+};
+
+typedef ::std::list< ScMyDetectiveOp > ScMyDetectiveOpList;
+typedef ::std::vector< ScMyDetectiveOp > ScMyDetectiveOpVec;
+
+class ScMyDetectiveOpContainer : ScMyIteratorBase
+{
+private:
+ ScMyDetectiveOpList aDetectiveOpList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyDetectiveOpContainer();
+ virtual ~ScMyDetectiveOpContainer();
+
+ void AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex );
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+// contains data to export for the current cell position
+struct ScMyCell
+{
+// com::sun::star::uno::Reference<com::sun::star::table::XCell> xCell;
+// com::sun::star::uno::Reference<com::sun::star::text::XText> xText;
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation;
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xNoteShape;
+ com::sun::star::table::CellAddress aCellAddress;
+ com::sun::star::table::CellRangeAddress aMergeRange;
+ com::sun::star::table::CellRangeAddress aMatrixRange;
+
+ rtl::OUString sStringValue;
+ rtl::OUString sAnnotationText;
+
+ ScMyAreaLink aAreaLink;
+ ScMyShapeList aShapeList;
+ ScMyDetectiveObjVec aDetectiveObjVec;
+ ScMyDetectiveOpVec aDetectiveOpVec;
+
+ double fValue;
+ sal_Int32 nValidationIndex;
+ sal_Int32 nStyleIndex;
+ sal_Int32 nNumberFormat;
+ com::sun::star::table::CellContentType nType;
+
+ ScBaseCell* pBaseCell;
+
+ sal_Bool bIsAutoStyle;
+
+ sal_Bool bHasShape;
+ sal_Bool bIsMergedBase;
+ sal_Bool bIsCovered;
+ sal_Bool bHasAreaLink;
+ sal_Bool bHasEmptyDatabase;
+ sal_Bool bHasDetectiveObj;
+ sal_Bool bHasDetectiveOp;
+
+ sal_Bool bIsEditCell;
+ sal_Bool bKnowWhetherIsEditCell;
+ sal_Bool bHasStringValue;
+ sal_Bool bHasDoubleValue;
+ sal_Bool bHasXText;
+
+ sal_Bool bIsMatrixBase;
+ sal_Bool bIsMatrixCovered;
+ sal_Bool bHasAnnotation;
+
+ ScMyCell();
+ ~ScMyCell();
+};
+
+//==============================================================================
+
+struct ScMyExportAnnotation
+{
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation;
+ com::sun::star::table::CellAddress aCellAddress;
+ sal_Bool operator<(const ScMyExportAnnotation& rAnno) const;
+};
+
+typedef ::std::list< ScMyExportAnnotation > ScMyExportAnnotationList;
+
+class ScMyNotEmptyCellsIterator
+{
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet> xTable;
+ com::sun::star::uno::Reference<com::sun::star::table::XCellRange> xCellRange;
+ com::sun::star::table::CellAddress aLastAddress;
+ ScMyExportAnnotationList aAnnotations;
+
+ ScMyShapesContainer* pShapes;
+ ScMyNoteShapesContainer* pNoteShapes;
+ ScMyEmptyDatabaseRangesContainer* pEmptyDatabaseRanges;
+ ScMyMergedRangesContainer* pMergedRanges;
+ ScMyAreaLinksContainer* pAreaLinks;
+ ScMyDetectiveObjContainer* pDetectiveObj;
+ ScMyDetectiveOpContainer* pDetectiveOp;
+
+ ScXMLExport& rExport;
+ ScHorizontalCellIterator* pCellItr;
+
+ SCCOL nCellCol;
+ SCROW nCellRow;
+ SCTAB nCurrentTable;
+
+ void UpdateAddress( ::com::sun::star::table::CellAddress& rAddress );
+ void SetCellData( ScMyCell& rMyCell, ::com::sun::star::table::CellAddress& rAddress );
+
+ void SetMatrixCellData( ScMyCell& rMyCell );
+ void HasAnnotation( ScMyCell& aCell );
+public:
+ ScMyNotEmptyCellsIterator(ScXMLExport& rExport);
+ ~ScMyNotEmptyCellsIterator();
+
+ void Clear();
+
+ inline void SetShapes(ScMyShapesContainer* pNewShapes)
+ { pShapes = pNewShapes; }
+ inline void SetNoteShapes(ScMyNoteShapesContainer* pNewNoteShapes)
+ { pNoteShapes = pNewNoteShapes; }
+ inline void SetEmptyDatabaseRanges(ScMyEmptyDatabaseRangesContainer* pNewEmptyDatabaseRanges)
+ { pEmptyDatabaseRanges = pNewEmptyDatabaseRanges; }
+ inline void SetMergedRanges(ScMyMergedRangesContainer* pNewMergedRanges)
+ { pMergedRanges = pNewMergedRanges; }
+ inline void SetAreaLinks(ScMyAreaLinksContainer* pNewAreaLinks)
+ { pAreaLinks = pNewAreaLinks; }
+ inline void SetDetectiveObj(ScMyDetectiveObjContainer* pNewDetectiveObj)
+ { pDetectiveObj = pNewDetectiveObj; }
+ inline void SetDetectiveOp(ScMyDetectiveOpContainer* pNewDetectiveOp)
+ { pDetectiveOp = pNewDetectiveOp; }
+
+ void SetCurrentTable(const SCTAB nTable,
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& rxTable);
+ void SkipTable(SCTAB nSkip);
+
+ sal_Bool GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles);
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLExportSharedData.cxx b/sc/source/filter/xml/XMLExportSharedData.cxx
new file mode 100644
index 000000000000..eede3aa73499
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportSharedData.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportSharedData.hxx"
+#include "XMLExportIterator.hxx"
+#include <tools/debug.hxx>
+
+using namespace com::sun::star;
+
+ScMySharedData::ScMySharedData(const sal_Int32 nTempTableCount) :
+ nLastColumns(nTempTableCount, 0),
+ nLastRows(nTempTableCount, 0),
+ pTableShapes(NULL),
+ pDrawPages(NULL),
+ pShapesContainer(NULL),
+ pDetectiveObjContainer(new ScMyDetectiveObjContainer()),
+ pNoteShapes(NULL),
+ nTableCount(nTempTableCount)
+{
+}
+
+ScMySharedData::~ScMySharedData()
+{
+ if (pShapesContainer)
+ delete pShapesContainer;
+ if (pTableShapes)
+ delete pTableShapes;
+ if (pDrawPages)
+ delete pDrawPages;
+ if (pDetectiveObjContainer)
+ delete pDetectiveObjContainer;
+ if (pNoteShapes)
+ delete pNoteShapes;
+}
+
+void ScMySharedData::SetLastColumn(const sal_Int32 nTable, const sal_Int32 nCol)
+{
+ if(nCol > nLastColumns[nTable]) nLastColumns[nTable] = nCol;
+}
+
+sal_Int32 ScMySharedData::GetLastColumn(const sal_Int32 nTable)
+{
+ return nLastColumns[nTable];
+}
+
+void ScMySharedData::SetLastRow(const sal_Int32 nTable, const sal_Int32 nRow)
+{
+ if(nRow > nLastRows[nTable]) nLastRows[nTable] = nRow;
+}
+
+sal_Int32 ScMySharedData::GetLastRow(const sal_Int32 nTable)
+{
+ return nLastRows[nTable];
+}
+
+void ScMySharedData::AddDrawPage(const ScMyDrawPage& aDrawPage, const sal_Int32 nTable)
+{
+ if (!pDrawPages)
+ pDrawPages = new ScMyDrawPages(nTableCount, ScMyDrawPage());
+ (*pDrawPages)[nTable] = aDrawPage;
+}
+
+void ScMySharedData::SetDrawPageHasForms(const sal_Int32 nTable, sal_Bool bHasForms)
+{
+ DBG_ASSERT(pDrawPages, "DrawPages not collected");
+ if (pDrawPages)
+ (*pDrawPages)[nTable].bHasForms = bHasForms;
+}
+
+uno::Reference<drawing::XDrawPage> ScMySharedData::GetDrawPage(const sal_Int32 nTable)
+{
+ DBG_ASSERT(pDrawPages, "DrawPages not collected");
+ if (pDrawPages)
+ return (*pDrawPages)[nTable].xDrawPage;
+ else
+ return uno::Reference<drawing::XDrawPage>();
+}
+
+sal_Bool ScMySharedData::HasForm(const sal_Int32 nTable, uno::Reference<drawing::XDrawPage>& xDrawPage)
+{
+ sal_Bool bResult(sal_False);
+ if (pDrawPages)
+ {
+ if ((*pDrawPages)[nTable].bHasForms)
+ {
+ bResult = sal_True;
+ xDrawPage = (*pDrawPages)[nTable].xDrawPage;
+ }
+ }
+ return bResult;
+}
+
+void ScMySharedData::AddNewShape(const ScMyShape& aMyShape)
+{
+ if (!pShapesContainer)
+ pShapesContainer = new ScMyShapesContainer();
+ pShapesContainer->AddNewShape(aMyShape);
+}
+
+void ScMySharedData::SortShapesContainer()
+{
+ if (pShapesContainer)
+ pShapesContainer->Sort();
+}
+
+sal_Bool ScMySharedData::HasShapes()
+{
+ return ((pShapesContainer && pShapesContainer->HasShapes()) ||
+ (pTableShapes && !pTableShapes->empty()));
+}
+
+void ScMySharedData::AddTableShape(const sal_Int32 nTable, const uno::Reference<drawing::XShape>& xShape)
+{
+ if (!pTableShapes)
+ pTableShapes = new ScMyTableShapes(nTableCount);
+ (*pTableShapes)[nTable].push_back(xShape);
+}
+
+void ScMySharedData::AddNoteObj(const uno::Reference<drawing::XShape>& xShape, const ScAddress& rPos)
+{
+ if (!pNoteShapes)
+ pNoteShapes = new ScMyNoteShapesContainer();
+ ScMyNoteShape aNote;
+ aNote.xShape = xShape;
+ aNote.aPos = rPos;
+ pNoteShapes->AddNewNote(aNote);
+}
+
+void ScMySharedData::SortNoteShapes()
+{
+ if (pNoteShapes)
+ pNoteShapes->Sort();
+}
diff --git a/sc/source/filter/xml/XMLExportSharedData.hxx b/sc/source/filter/xml/XMLExportSharedData.hxx
new file mode 100644
index 000000000000..e808101805fd
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportSharedData.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTSHAREDDATA_HXX
+#define SC_XMLEXPORTSHAREDDATA_HXX
+
+#include "global.hxx"
+#include <com/sun/star/drawing/XDrawPage.hpp>
+
+#include <vector>
+#include <list>
+
+struct ScMyDrawPage
+{
+ com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> xDrawPage;
+ sal_Bool bHasForms;
+
+ ScMyDrawPage() : bHasForms(sal_False) {}
+};
+
+typedef std::list< com::sun::star::uno::Reference<com::sun::star::drawing::XShape> > ScMyTableXShapes;
+typedef std::vector<ScMyTableXShapes> ScMyTableShapes;
+typedef std::vector<ScMyDrawPage> ScMyDrawPages;
+
+class ScMyShapesContainer;
+class ScMyDetectiveObjContainer;
+struct ScMyShape;
+class ScMyNoteShapesContainer;
+
+class ScMySharedData
+{
+ std::vector<sal_Int32> nLastColumns;
+ std::vector<sal_Int32> nLastRows;
+ ScMyTableShapes* pTableShapes;
+ ScMyDrawPages* pDrawPages;
+ ScMyShapesContainer* pShapesContainer;
+ ScMyDetectiveObjContainer* pDetectiveObjContainer;
+ ScMyNoteShapesContainer* pNoteShapes;
+ sal_Int32 nTableCount;
+public:
+ ScMySharedData(const sal_Int32 nTableCount);
+ ~ScMySharedData();
+
+ void SetLastColumn(const sal_Int32 nTable, const sal_Int32 nCol);
+ void SetLastRow(const sal_Int32 nTable, const sal_Int32 nRow);
+ sal_Int32 GetLastColumn(const sal_Int32 nTable);
+ sal_Int32 GetLastRow(const sal_Int32 nTable);
+ void AddDrawPage(const ScMyDrawPage& aDrawPage, const sal_Int32 nTable);
+ void SetDrawPageHasForms(const sal_Int32 nTable, sal_Bool bHasForms);
+ com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> GetDrawPage(const sal_Int32 nTable);
+ sal_Bool HasDrawPage() { return pDrawPages != NULL; }
+ sal_Bool HasForm(const sal_Int32 nTable, com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage>& xDrawPage);
+ void AddNewShape(const ScMyShape& aMyShape);
+ void SortShapesContainer();
+ ScMyShapesContainer* GetShapesContainer() { return pShapesContainer; }
+ sal_Bool HasShapes();
+ void AddTableShape(const sal_Int32 nTable, const com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& xShape);
+ ScMyTableShapes* GetTableShapes() { return pTableShapes; }
+ ScMyDetectiveObjContainer* GetDetectiveObjContainer() { return pDetectiveObjContainer; }
+ void AddNoteObj(const com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& xShape, const ScAddress& rPos);
+ void SortNoteShapes();
+ ScMyNoteShapesContainer* GetNoteShapes() { return pNoteShapes; }
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx
new file mode 100644
index 000000000000..66f3ea613a3a
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -0,0 +1,1267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLStylesExportHelper.hxx"
+#include "global.hxx"
+#include "unonames.hxx"
+#include "XMLConverter.hxx"
+#include "xmlexprt.hxx"
+#include "document.hxx"
+#include "rangeutl.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/XMLEventExport.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+#include <comphelper/extract.hxx>
+#include <sfx2/app.hxx>
+
+#include <algorithm>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+ScMyValidation::ScMyValidation()
+ : sName(),
+ sErrorMessage(),
+ sErrorTitle(),
+ sImputMessage(),
+ sImputTitle(),
+ sFormula1(),
+ sFormula2(),
+ bShowErrorMessage(sal_False),
+ bShowImputMessage(sal_False),
+ bIgnoreBlanks(sal_False)
+{
+}
+
+ScMyValidation::~ScMyValidation()
+{
+}
+
+sal_Bool ScMyValidation::IsEqual(const ScMyValidation& aVal) const
+{
+ if (aVal.bIgnoreBlanks == bIgnoreBlanks &&
+ aVal.bShowImputMessage == bShowImputMessage &&
+ aVal.bShowErrorMessage == bShowErrorMessage &&
+ aVal.aBaseCell.Sheet == aBaseCell.Sheet &&
+ aVal.aBaseCell.Column == aBaseCell.Column &&
+ aVal.aBaseCell.Row == aBaseCell.Row &&
+ aVal.aAlertStyle == aAlertStyle &&
+ aVal.aValidationType == aValidationType &&
+ aVal.aOperator == aOperator &&
+ aVal.sErrorTitle == sErrorTitle &&
+ aVal.sImputTitle == sImputTitle &&
+ aVal.sErrorMessage == sErrorMessage &&
+ aVal.sImputMessage == sImputMessage &&
+ aVal.sFormula1 == sFormula1 &&
+ aVal.sFormula2 == sFormula2)
+ return sal_True;
+ else
+ return sal_False;
+}
+
+ScMyValidationsContainer::ScMyValidationsContainer()
+ : aValidationVec(),
+ sEmptyString(),
+ sERRALSTY(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)),
+ sIGNOREBL(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)),
+ sSHOWLIST(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)),
+ sTYPE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)),
+ sSHOWINP(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)),
+ sSHOWERR(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)),
+ sINPTITLE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)),
+ sINPMESS(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)),
+ sERRTITLE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)),
+ sERRMESS(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)),
+ sOnError(RTL_CONSTASCII_USTRINGPARAM("OnError")),
+ sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
+ sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic")),
+ sScript(RTL_CONSTASCII_USTRINGPARAM("Script")),
+ sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
+ sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName"))
+{
+}
+
+ScMyValidationsContainer::~ScMyValidationsContainer()
+{
+}
+
+sal_Bool ScMyValidationsContainer::AddValidation(const uno::Any& aTempAny,
+ sal_Int32& nValidationIndex)
+{
+ sal_Bool bAdded(sal_False);
+ uno::Reference<beans::XPropertySet> xPropertySet(aTempAny, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ rtl::OUString sErrorMessage;
+ xPropertySet->getPropertyValue(sERRMESS) >>= sErrorMessage;
+ rtl::OUString sErrorTitle;
+ xPropertySet->getPropertyValue(sERRTITLE) >>= sErrorTitle;
+ rtl::OUString sImputMessage;
+ xPropertySet->getPropertyValue(sINPMESS) >>= sImputMessage;
+ rtl::OUString sImputTitle;
+ xPropertySet->getPropertyValue(sINPTITLE) >>= sImputTitle;
+ sal_Bool bShowErrorMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(sSHOWERR));
+ sal_Bool bShowImputMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(sSHOWINP));
+ sheet::ValidationType aValidationType;
+ xPropertySet->getPropertyValue(sTYPE) >>= aValidationType;
+ if (bShowErrorMessage || bShowImputMessage || aValidationType != sheet::ValidationType_ANY ||
+ sErrorMessage.getLength() || sErrorTitle.getLength() || sImputMessage.getLength() || sImputTitle.getLength())
+ {
+ ScMyValidation aValidation;
+ aValidation.sErrorMessage = sErrorMessage;
+ aValidation.sErrorTitle = sErrorTitle;
+ aValidation.sImputMessage = sImputMessage;
+ aValidation.sImputTitle = sImputTitle;
+ aValidation.bShowErrorMessage = bShowErrorMessage;
+ aValidation.bShowImputMessage = bShowImputMessage;
+ aValidation.aValidationType = aValidationType;
+ aValidation.bIgnoreBlanks = ::cppu::any2bool(xPropertySet->getPropertyValue(sIGNOREBL));
+ xPropertySet->getPropertyValue(sSHOWLIST) >>= aValidation.nShowList;
+ xPropertySet->getPropertyValue(sERRALSTY) >>= aValidation.aAlertStyle;
+ uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY);
+ if (xCondition.is())
+ {
+ aValidation.sFormula1 = xCondition->getFormula1();
+ aValidation.sFormula2 = xCondition->getFormula2();
+ aValidation.aOperator = xCondition->getOperator();
+ aValidation.aBaseCell = xCondition->getSourcePosition();
+ }
+ //ScMyValidationRange aValidationRange;
+ sal_Bool bEqualFound(sal_False);
+ sal_Int32 i(0);
+ sal_Int32 nCount(aValidationVec.size());
+ while (i < nCount && !bEqualFound)
+ {
+ bEqualFound = aValidationVec[i].IsEqual(aValidation);
+ if (!bEqualFound)
+ ++i;
+ }
+ if (bEqualFound)
+ nValidationIndex = i;
+ else
+ {
+ sal_Int32 nNameIndex(nCount + 1);
+ rtl::OUString sCount(rtl::OUString::valueOf(nNameIndex));
+ rtl::OUString sPrefix(RTL_CONSTASCII_USTRINGPARAM("val"));
+ aValidation.sName += sPrefix;
+ aValidation.sName += sCount;
+ aValidationVec.push_back(aValidation);
+ nValidationIndex = nCount;
+ bAdded = sal_True;
+ }
+ }
+ }
+ return bAdded;
+}
+
+rtl::OUString ScMyValidationsContainer::GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation)
+{
+ /* ATTENTION! Should the condition to not write sheet::ValidationType_ANY
+ * ever be changed, adapt the conditional call of
+ * MarkUsedExternalReferences() in
+ * ScTableValidationObj::ScTableValidationObj() accordingly! */
+ rtl::OUString sCondition;
+ if (aValidation.aValidationType != sheet::ValidationType_ANY)
+ {
+ switch (aValidation.aValidationType)
+ {
+ //case sheet::ValidationType_CUSTOM
+ case sheet::ValidationType_DATE :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-date()"));
+ break;
+ case sheet::ValidationType_DECIMAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-decimal-number()"));
+ break;
+ case sheet::ValidationType_LIST :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-in-list("));
+ sCondition += aValidation.sFormula1;
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ break;
+ case sheet::ValidationType_TEXT_LEN :
+ if (aValidation.aOperator != sheet::ConditionOperator_BETWEEN &&
+ aValidation.aOperator != sheet::ConditionOperator_NOT_BETWEEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length()"));
+ break;
+ case sheet::ValidationType_TIME :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-time()"));
+ break;
+ case sheet::ValidationType_WHOLE :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-whole-number()"));
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if (aValidation.aValidationType != sheet::ValidationType_LIST &&
+ (aValidation.sFormula1.getLength() ||
+ (aValidation.aOperator == sheet::ConditionOperator_BETWEEN &&
+ aValidation.aOperator == sheet::ConditionOperator_NOT_BETWEEN &&
+ aValidation.sFormula2.getLength())))
+ {
+ if (aValidation.aValidationType != sheet::ValidationType_TEXT_LEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" and "));
+ if (aValidation.aOperator != sheet::ConditionOperator_BETWEEN &&
+ aValidation.aOperator != sheet::ConditionOperator_NOT_BETWEEN)
+ {
+ if (aValidation.aValidationType != sheet::ValidationType_TEXT_LEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content()"));
+ switch (aValidation.aOperator)
+ {
+ case sheet::ConditionOperator_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ break;
+ case sheet::ConditionOperator_GREATER :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ break;
+ case sheet::ConditionOperator_GREATER_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ break;
+ case sheet::ConditionOperator_LESS :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ break;
+ case sheet::ConditionOperator_LESS_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ break;
+ case sheet::ConditionOperator_NOT_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ sCondition += aValidation.sFormula1;
+ }
+ else
+ {
+ if (aValidation.aValidationType == sheet::ValidationType_TEXT_LEN)
+ {
+ if (aValidation.aOperator == sheet::ConditionOperator_BETWEEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-between("));
+ else
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-not-between("));
+ }
+ else
+ {
+ if (aValidation.aOperator == sheet::ConditionOperator_BETWEEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between("));
+ else
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between("));
+ }
+ sCondition += aValidation.sFormula1;
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ sCondition += aValidation.sFormula2;
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ }
+ }
+ else
+ if (aValidation.aValidationType == sheet::ValidationType_TEXT_LEN)
+ sCondition = rtl::OUString();
+ }
+ if (sCondition.getLength())
+ {
+ const formula::FormulaGrammar::Grammar eGrammar = rExport.GetDocument()->GetStorageGrammar();
+ sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
+ sCondition = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sCondition, sal_False );
+ }
+
+ return sCondition;
+}
+
+rtl::OUString ScMyValidationsContainer::GetBaseCellAddress(ScDocument* pDoc, const table::CellAddress& aCell)
+{
+ rtl::OUString sAddress;
+ ScRangeStringConverter::GetStringFromAddress( sAddress, aCell, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ return sAddress;
+}
+
+void ScMyValidationsContainer::WriteMessage(ScXMLExport& rExport,
+ const rtl::OUString& sTitle, const rtl::OUString& sOUMessage,
+ const sal_Bool bShowMessage, const sal_Bool bIsHelpMessage)
+{
+ if (sTitle.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TITLE, sTitle);
+ if (bShowMessage)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
+ SvXMLElementExport* pMessage(NULL);
+ if (bIsHelpMessage)
+ pMessage = new SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_HELP_MESSAGE, sal_True, sal_True);
+ else
+ pMessage = new SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_ERROR_MESSAGE, sal_True, sal_True);
+ if (sOUMessage.getLength())
+ {
+ sal_Int32 i(0);
+ rtl::OUStringBuffer sTemp;
+ String sMessage(sOUMessage);
+ rtl::OUString sText (sMessage.ConvertLineEnd(LINEEND_LF));
+ sal_Bool bPrevCharWasSpace(sal_True);
+ while(i < sText.getLength())
+ {
+ if ((sText[i] == '\n'))
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ rExport.GetTextParagraphExport()->exportText(sTemp.makeStringAndClear(), bPrevCharWasSpace);
+ }
+ else
+ sTemp.append(sText[i]);
+ ++i;
+ }
+ if (sTemp.getLength())
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ rExport.GetTextParagraphExport()->exportText(sTemp.makeStringAndClear(), bPrevCharWasSpace);
+ }
+ }
+ if (pMessage)
+ delete pMessage;
+}
+
+void ScMyValidationsContainer::WriteValidations(ScXMLExport& rExport)
+{
+ if (aValidationVec.size())
+ {
+ SvXMLElementExport aElemVs(rExport, XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATIONS, sal_True, sal_True);
+ ScMyValidationVec::iterator aItr(aValidationVec.begin());
+ ScMyValidationVec::iterator aEndItr(aValidationVec.end());
+ while (aItr != aEndItr)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aItr->sName);
+ rtl::OUString sCondition(GetCondition(rExport, *aItr));
+ if (sCondition.getLength())
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION, sCondition);
+ if (aItr->bIgnoreBlanks)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_FALSE);
+ if (aItr->aValidationType == sheet::ValidationType_LIST)
+ {
+ switch (aItr->nShowList)
+ {
+ case sheet::TableValidationVisibility::INVISIBLE:
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_NO);
+ break;
+ case sheet::TableValidationVisibility::UNSORTED:
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_UNSORTED);
+ break;
+ case sheet::TableValidationVisibility::SORTEDASCENDING:
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_SORTED_ASCENDING);
+ break;
+ default:
+ DBG_ERROR("unknown ListType");
+ }
+ }
+ }
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, GetBaseCellAddress(rExport.GetDocument(), aItr->aBaseCell));
+ SvXMLElementExport aElemV(rExport, XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, sal_True, sal_True);
+ if (aItr->bShowImputMessage || aItr->sImputMessage.getLength() || aItr->sImputTitle.getLength())
+ {
+ WriteMessage(rExport, aItr->sImputTitle, aItr->sImputMessage, aItr->bShowImputMessage, sal_True);
+ }
+ if (aItr->bShowErrorMessage || aItr->sErrorMessage.getLength() || aItr->sErrorTitle.getLength())
+ {
+ switch (aItr->aAlertStyle)
+ {
+ case sheet::ValidationAlertStyle_INFO :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_INFORMATION);
+ WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, sal_False);
+ }
+ break;
+ case sheet::ValidationAlertStyle_WARNING :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_WARNING);
+ WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, sal_False);
+ }
+ break;
+ case sheet::ValidationAlertStyle_STOP :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_STOP);
+ WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, sal_False);
+ }
+ break;
+ case sheet::ValidationAlertStyle_MACRO :
+ {
+ {
+ //rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aItr->sErrorTitle);
+ if (aItr->bShowErrorMessage)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_EXECUTE, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_EXECUTE, XML_FALSE);
+ SvXMLElementExport aEMElem(rExport, XML_NAMESPACE_TABLE, XML_ERROR_MACRO, sal_True, sal_True);
+ }
+ {
+ // #i47525# for a script URL the type and the property name for the URL
+ // are both "Script", for a simple macro name the type is "StarBasic"
+ // and the property name is "MacroName".
+ bool bScriptURL = SfxApplication::IsXScriptURL( aItr->sErrorTitle );
+
+ uno::Sequence<beans::PropertyValue> aSeq(3);
+ beans::PropertyValue* pArr(aSeq.getArray());
+ pArr[0].Name = sEventType;
+ pArr[0].Value <<= bScriptURL ? sScript : sStarBasic;
+ pArr[1].Name = sLibrary;
+ pArr[1].Value <<= sEmptyString;
+ pArr[2].Name = bScriptURL ? sScript : sMacroName;
+ pArr[2].Value <<= aItr->sErrorTitle;
+
+ // 2) export the sequence
+ rExport.GetEventExport().ExportSingleEvent( aSeq, sOnError);
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ ++aItr;
+ }
+ }
+}
+
+const rtl::OUString& ScMyValidationsContainer::GetValidationName(const sal_Int32 nIndex)
+{
+ DBG_ASSERT( static_cast<size_t>(nIndex) < aValidationVec.size(), "out of range" );
+ return aValidationVec[nIndex].sName;
+}
+
+//==============================================================================
+
+sal_Int32 ScMyDefaultStyles::GetStyleNameIndex(const ScFormatRangeStyles* pCellStyles,
+ const sal_Int32 nTable, const sal_Int32 nPos,
+ const sal_Int32 i, const sal_Bool bRow, sal_Bool& bIsAutoStyle)
+{
+ if (bRow)
+ return pCellStyles->GetStyleNameIndex(nTable, nPos, i,
+ bIsAutoStyle);
+ else
+ return pCellStyles->GetStyleNameIndex(nTable, i, nPos,
+ bIsAutoStyle);
+}
+
+void ScMyDefaultStyles::FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc,
+ const sal_Bool bRow)
+{
+ if (pDoc)
+ {
+ SCTAB nTab = static_cast<SCTAB>(nTable);
+ sal_Int32 nPos;
+ sal_Int32 nLast;
+ ScMyDefaultStyleList* pDefaults;
+ if (bRow)
+ {
+ pDefaults = pRowDefaults;
+ nLast = nLastRow;
+ }
+ else
+ {
+ pDefaults = pColDefaults;
+ nLast = nLastCol;
+ }
+ sal_Bool bPrevAutoStyle(sal_False);
+ sal_Bool bIsAutoStyle;
+ sal_Bool bResult;
+ sal_Int32 nPrevIndex(0);
+ sal_Int32 nIndex;
+ sal_Int32 nRepeat(0);
+ sal_Int32 nEmptyRepeat(0);
+ for (sal_Int32 i = nLast; i >= 0; --i)
+ {
+ if (bRow)
+ {
+ SCCOL nCol;
+ bResult = pDoc->GetRowDefault(nTab,
+ static_cast<SCROW>(i), static_cast<SCCOL>(nLastCol), nCol);
+ nPos = static_cast<sal_Int32>(nCol);
+ }
+ else
+ {
+ SCROW nRow;
+ bResult = pDoc->GetColDefault(nTab,
+ static_cast<SCCOL>(i), static_cast<SCROW>(nLastRow), nRow);
+ nPos = static_cast<sal_Int32>(nRow);
+ }
+ if (bResult)
+ {
+ nEmptyRepeat = 0;
+ if (!nRepeat)
+ {
+ nPrevIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i,
+ bRow, bPrevAutoStyle);
+ (*pDefaults)[i].nIndex = nPrevIndex;
+ (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle;
+ nRepeat = 1;
+ }
+ else
+ {
+ nIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i,
+ bRow, bIsAutoStyle);
+ if ((nIndex != nPrevIndex) || (bIsAutoStyle != bPrevAutoStyle))
+ {
+ nRepeat = 1;
+ nPrevIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i,
+ bRow, bPrevAutoStyle);
+ (*pDefaults)[i].nIndex = nPrevIndex;
+ (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle;
+ }
+ else
+ {
+ (*pDefaults)[i].nIndex = nPrevIndex;
+ (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle;
+ ++nRepeat;
+ if (nRepeat > 1)
+ (*pDefaults)[i].nRepeat = nRepeat;
+ }
+ }
+ }
+ else
+ {
+ nRepeat = 0;
+ if (!nEmptyRepeat)
+ nEmptyRepeat = 1;
+ else
+ {
+ ++nEmptyRepeat;
+ if (nEmptyRepeat > 1)
+ (*pDefaults)[i].nRepeat = nEmptyRepeat;
+ }
+ }
+ }
+ }
+}
+
+void ScMyDefaultStyles::FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc)
+{
+ if (pRowDefaults)
+ delete pRowDefaults;
+ pRowDefaults = new ScMyDefaultStyleList(nLastRow + 1);
+ FillDefaultStyles(nTable, nLastRow, nLastCol, pCellStyles, pDoc, sal_True);
+ if (pColDefaults)
+ delete pColDefaults;
+ pColDefaults = new ScMyDefaultStyleList(nLastCol + 1);
+ FillDefaultStyles(nTable, nLastRow, nLastCol, pCellStyles, pDoc, sal_False);
+}
+
+ScMyDefaultStyles::~ScMyDefaultStyles()
+{
+ if (pRowDefaults)
+ delete pRowDefaults;
+ if (pColDefaults)
+ delete pColDefaults;
+}
+
+ScMyRowFormatRange::ScMyRowFormatRange()
+ : nStartColumn(0),
+ nRepeatColumns(0),
+ nRepeatRows(0),
+ nIndex(-1),
+ nValidationIndex(-1),
+ bIsAutoStyle(sal_True)
+{
+}
+
+sal_Bool ScMyRowFormatRange::operator< (const ScMyRowFormatRange& rRange) const
+{
+ return (nStartColumn < rRange.nStartColumn);
+}
+
+ScRowFormatRanges::ScRowFormatRanges()
+ : aRowFormatRanges(),
+ pRowDefaults(NULL),
+ pColDefaults(NULL),
+ nSize(0)
+{
+}
+
+ScRowFormatRanges::ScRowFormatRanges(const ScRowFormatRanges* pRanges)
+ : aRowFormatRanges(pRanges->aRowFormatRanges),
+ pRowDefaults(pRanges->pRowDefaults),
+ pColDefaults(pRanges->pColDefaults),
+ nSize(pRanges->nSize)
+{
+}
+
+ScRowFormatRanges::~ScRowFormatRanges()
+{
+}
+
+void ScRowFormatRanges::Clear()
+{
+ aRowFormatRanges.clear();
+ nSize = 0;
+}
+
+void ScRowFormatRanges::AddRange(const sal_Int32 nPrevStartCol, const sal_Int32 nRepeat, const sal_Int32 nPrevIndex,
+ const sal_Bool bPrevAutoStyle, const ScMyRowFormatRange& rFormatRange)
+{
+ sal_Int32 nIndex(-1);
+ if ((nPrevIndex != rFormatRange.nIndex) ||
+ (bPrevAutoStyle != rFormatRange.bIsAutoStyle))
+ nIndex = rFormatRange.nIndex;
+
+ sal_Bool bInserted(sal_False);
+ if (!aRowFormatRanges.empty())
+ {
+ ScMyRowFormatRange* pRange(&aRowFormatRanges.back());
+ if (pRange)
+ {
+ if ((nPrevStartCol == (pRange->nStartColumn + pRange->nRepeatColumns)) &&
+ (pRange->bIsAutoStyle == rFormatRange.bIsAutoStyle) &&
+ (pRange->nIndex == nIndex) &&
+ (pRange->nValidationIndex == rFormatRange.nValidationIndex))
+ {
+ if (rFormatRange.nRepeatRows < pRange->nRepeatRows)
+ pRange->nRepeatRows = rFormatRange.nRepeatRows;
+ pRange->nRepeatColumns += nRepeat;
+ bInserted = sal_True;
+ }
+ }
+ }
+ if (!bInserted)
+ {
+ ScMyRowFormatRange aRange;
+ aRange.nStartColumn = nPrevStartCol;
+ aRange.nRepeatColumns = nRepeat;
+ aRange.nRepeatRows = rFormatRange.nRepeatRows;
+ aRange.nValidationIndex = rFormatRange.nValidationIndex;
+ aRange.bIsAutoStyle = rFormatRange.bIsAutoStyle;
+ aRange.nIndex = nIndex;
+ aRowFormatRanges.push_back(aRange);
+ ++nSize;
+ }
+}
+
+void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange,
+ const sal_Int32 nRow)
+{
+ DBG_ASSERT(pRowDefaults, "no row defaults");
+ DBG_ASSERT(pColDefaults, "no column defaults");
+ sal_uInt32 nEnd (rFormatRange.nRepeatRows + nRow - 1);
+ sal_Int32 nPrevIndex((*pRowDefaults)[nRow].nIndex);
+ sal_Bool bPrevAutoStyle((*pRowDefaults)[nRow].bIsAutoStyle);
+ sal_uInt32 i(nRow + 1);
+ sal_Bool bReady(sal_False);
+ while ((i < nEnd) && !bReady && (i < pRowDefaults->size()))
+ {
+ if ((nPrevIndex != (*pRowDefaults)[i].nIndex) ||
+ (bPrevAutoStyle != (*pRowDefaults)[i].bIsAutoStyle))
+ bReady = sal_True;
+ else
+ i += (*pRowDefaults)[i].nRepeat;
+ }
+ if (i > nEnd)
+ i = nEnd;
+ if (bReady)
+ rFormatRange.nRepeatRows = i - nRow + 1;
+ if (nPrevIndex == -1)
+ {
+ nPrevIndex = (*pColDefaults)[rFormatRange.nStartColumn].nIndex;
+ bPrevAutoStyle = (*pColDefaults)[rFormatRange.nStartColumn].bIsAutoStyle;
+ sal_uInt32 nPrevStartCol(rFormatRange.nStartColumn);
+ sal_uInt32 nRepeat((*pColDefaults)[rFormatRange.nStartColumn].nRepeat);
+ nEnd = rFormatRange.nStartColumn + rFormatRange.nRepeatColumns;
+ for(i = nPrevStartCol + nRepeat; i < nEnd; i += (*pColDefaults)[i].nRepeat)
+ {
+ DBG_ASSERT(sal_uInt32(nPrevStartCol + nRepeat) <= nEnd, "something wents wrong");
+ if ((nPrevIndex != (*pColDefaults)[i].nIndex) ||
+ (bPrevAutoStyle != (*pColDefaults)[i].bIsAutoStyle))
+ {
+ AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange);
+ nPrevStartCol = i;
+ nRepeat = (*pColDefaults)[i].nRepeat;
+ nPrevIndex = (*pColDefaults)[i].nIndex;
+ bPrevAutoStyle = (*pColDefaults)[i].bIsAutoStyle;
+ }
+ else
+ nRepeat += (*pColDefaults)[i].nRepeat;
+ }
+ if (sal_uInt32(nPrevStartCol + nRepeat) > nEnd)
+ nRepeat = nEnd - nPrevStartCol;
+ AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange);
+ }
+ else if ((nPrevIndex == rFormatRange.nIndex) &&
+ (bPrevAutoStyle == rFormatRange.bIsAutoStyle))
+ {
+ rFormatRange.nIndex = -1;
+ aRowFormatRanges.push_back(rFormatRange);
+ ++nSize;
+ }
+}
+
+sal_Bool ScRowFormatRanges::GetNext(ScMyRowFormatRange& aFormatRange)
+{
+ ScMyRowFormatRangesList::iterator aItr(aRowFormatRanges.begin());
+ if (aItr != aRowFormatRanges.end())
+ {
+ aFormatRange = (*aItr);
+ aRowFormatRanges.erase(aItr);
+ --nSize;
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Int32 ScRowFormatRanges::GetMaxRows()
+{
+ ScMyRowFormatRangesList::iterator aItr(aRowFormatRanges.begin());
+ ScMyRowFormatRangesList::iterator aEndItr(aRowFormatRanges.end());
+ sal_Int32 nMaxRows = MAXROW + 1;
+ if (aItr != aEndItr)
+ while (aItr != aEndItr)
+ {
+ if ((*aItr).nRepeatRows < nMaxRows)
+ nMaxRows = (*aItr).nRepeatRows;
+ ++aItr;
+ }
+ else
+ {
+ DBG_ERROR("no ranges found");
+ }
+ return nMaxRows;
+}
+
+sal_Int32 ScRowFormatRanges::GetSize()
+{
+ return nSize;
+}
+
+void ScRowFormatRanges::Sort()
+{
+ aRowFormatRanges.sort();
+}
+
+// ============================================================================
+ScMyFormatRange::ScMyFormatRange()
+ : nStyleNameIndex(-1),
+ nValidationIndex(-1),
+ bIsAutoStyle(sal_True)
+{
+}
+
+sal_Bool ScMyFormatRange::operator<(const ScMyFormatRange& rRange) const
+{
+ if (aRangeAddress.StartRow < rRange.aRangeAddress.StartRow)
+ return sal_True;
+ else
+ if (aRangeAddress.StartRow == rRange.aRangeAddress.StartRow)
+ return (aRangeAddress.StartColumn < rRange.aRangeAddress.StartColumn);
+ else
+ return sal_False;
+}
+
+ScFormatRangeStyles::ScFormatRangeStyles()
+ : aTables(),
+ aStyleNames(),
+ aAutoStyleNames()
+{
+}
+
+ScFormatRangeStyles::~ScFormatRangeStyles()
+{
+ ScMyOUStringVec::iterator i(aStyleNames.begin());
+ ScMyOUStringVec::iterator endi(aStyleNames.end());
+ while (i != endi)
+ {
+ delete *i;
+ ++i;
+ }
+ i = aAutoStyleNames.begin();
+ endi = aAutoStyleNames.end();
+ while (i != endi)
+ {
+ delete *i;
+ ++i;
+ }
+ ScMyFormatRangeListVec::iterator j(aTables.begin());
+ ScMyFormatRangeListVec::iterator endj(aTables.end());
+ while (j != endj)
+ {
+ delete *j;
+ ++j;
+ }
+}
+
+void ScFormatRangeStyles::AddNewTable(const sal_Int32 nTable)
+{
+ sal_Int32 nSize = aTables.size() - 1;
+ if (nTable > nSize)
+ for (sal_Int32 i = nSize; i < nTable; ++i)
+ {
+ ScMyFormatRangeAddresses* aRangeAddresses(new ScMyFormatRangeAddresses);
+ aTables.push_back(aRangeAddresses);
+ }
+}
+
+sal_Bool ScFormatRangeStyles::AddStyleName(rtl::OUString* rpString, sal_Int32& rIndex, const sal_Bool bIsAutoStyle)
+{
+ if (bIsAutoStyle)
+ {
+ aAutoStyleNames.push_back(rpString);
+ rIndex = aAutoStyleNames.size() - 1;
+ return sal_True;
+ }
+ else
+ {
+ sal_Int32 nCount(aStyleNames.size());
+ sal_Bool bFound(sal_False);
+ sal_Int32 i(nCount - 1);
+ while ((i >= 0) && (!bFound))
+ {
+ if (aStyleNames.at(i)->equals(*rpString))
+ bFound = sal_True;
+ else
+ i--;
+ }
+ if (bFound)
+ {
+ rIndex = i;
+ return sal_False;
+ }
+ else
+ {
+ aStyleNames.push_back(rpString);
+ rIndex = aStyleNames.size() - 1;
+ return sal_True;
+ }
+ }
+}
+
+sal_Int32 ScFormatRangeStyles::GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix, sal_Bool& bIsAutoStyle)
+{
+ sal_Int32 nPrefixLength(rPrefix.getLength());
+ rtl::OUString sTemp(rString.copy(nPrefixLength));
+ sal_Int32 nIndex(sTemp.toInt32());
+ if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aAutoStyleNames.size() && aAutoStyleNames.at(nIndex - 1)->equals(rString))
+ {
+ bIsAutoStyle = sal_True;
+ return nIndex - 1;
+ }
+ else
+ {
+ sal_Int32 i(0);
+ sal_Bool bFound(sal_False);
+ while (!bFound && static_cast<size_t>(i) < aStyleNames.size())
+ {
+ if (aStyleNames[i]->equals(rString))
+ bFound = sal_True;
+ else
+ ++i;
+ }
+ if (bFound)
+ {
+ bIsAutoStyle = sal_False;
+ return i;
+ }
+ else
+ {
+ i = 0;
+ while (!bFound && static_cast<size_t>(i) < aAutoStyleNames.size())
+ {
+ if (aAutoStyleNames[i]->equals(rString))
+ bFound = sal_True;
+ else
+ ++i;
+ }
+ if (bFound)
+ {
+ bIsAutoStyle = sal_True;
+ return i;
+ }
+ else
+ return -1;
+ }
+ }
+}
+
+sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable,
+ const sal_Int32 nColumn, const sal_Int32 nRow, sal_Bool& bIsAutoStyle) const
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
+ ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
+ ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
+ while (aItr != aEndItr)
+ {
+ if (((*aItr).aRangeAddress.StartColumn <= nColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nColumn) &&
+ ((*aItr).aRangeAddress.StartRow <= nRow) &&
+ ((*aItr).aRangeAddress.EndRow >= nRow))
+ {
+ bIsAutoStyle = aItr->bIsAutoStyle;
+ return (*aItr).nStyleNameIndex;
+ }
+ else
+ ++aItr;
+ }
+ return -1;
+}
+
+sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow,
+ sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
+ ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
+ ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
+ while (aItr != aEndItr)
+ {
+ if (((*aItr).aRangeAddress.StartColumn <= nColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nColumn) &&
+ ((*aItr).aRangeAddress.StartRow <= nRow) &&
+ ((*aItr).aRangeAddress.EndRow >= nRow))
+ {
+ bIsAutoStyle = aItr->bIsAutoStyle;
+ nValidationIndex = aItr->nValidationIndex;
+ nNumberFormat = aItr->nNumberFormat;
+ if (((*pRowDefaults)[nRow].nIndex != -1))
+ {
+ if (((*pRowDefaults)[nRow].nIndex == (*aItr).nStyleNameIndex) &&
+ ((*pRowDefaults)[nRow].bIsAutoStyle == (*aItr).bIsAutoStyle))
+ return -1;
+ else
+ return (*aItr).nStyleNameIndex;
+ }
+ else if (((*pColDefaults)[nColumn].nIndex != -1) &&
+ ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
+ ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
+ return -1;
+ else
+ return (*aItr).nStyleNameIndex;
+ }
+ else
+ {
+ if ((*aItr).aRangeAddress.EndRow < nRemoveBeforeRow)
+ aItr = pFormatRanges->erase(aItr);
+ else
+ ++aItr;
+ }
+ }
+ return -1;
+}
+
+void ScFormatRangeStyles::GetFormatRanges(const sal_Int32 nStartColumn, const sal_Int32 nEndColumn, const sal_Int32 nRow,
+ const sal_Int32 nTable, ScRowFormatRanges* pRowFormatRanges)
+{
+ sal_Int32 nTotalColumns(nEndColumn - nStartColumn + 1);
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
+ ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
+ ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
+ sal_Int32 nColumns = 0;
+ while (aItr != aEndItr && nColumns < nTotalColumns)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ table::CellRangeAddress aTempRangeAddress((*aItr).aRangeAddress);
+#endif
+ if (((*aItr).aRangeAddress.StartRow <= nRow) &&
+ ((*aItr).aRangeAddress.EndRow >= nRow))
+ {
+ if ((((*aItr).aRangeAddress.StartColumn <= nStartColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nStartColumn)) ||
+ (((*aItr).aRangeAddress.StartColumn <= nEndColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nEndColumn)) ||
+ (((*aItr).aRangeAddress.StartColumn >= nStartColumn) &&
+ ((*aItr).aRangeAddress.EndColumn <= nEndColumn)))
+ {
+ ScMyRowFormatRange aRange;
+ aRange.nIndex = aItr->nStyleNameIndex;
+ aRange.nValidationIndex = aItr->nValidationIndex;
+ aRange.bIsAutoStyle = aItr->bIsAutoStyle;
+ if ((aItr->aRangeAddress.StartColumn < nStartColumn) &&
+ (aItr->aRangeAddress.EndColumn >= nStartColumn))
+ {
+ if (aItr->aRangeAddress.EndColumn >= nEndColumn)
+ aRange.nRepeatColumns = nTotalColumns;
+ else
+ aRange.nRepeatColumns = aItr->aRangeAddress.EndColumn - nStartColumn + 1;
+ aRange.nStartColumn = nStartColumn;
+ }
+ else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) &&
+ (aItr->aRangeAddress.EndColumn <= nEndColumn))
+ {
+ aRange.nRepeatColumns = aItr->aRangeAddress.EndColumn - aItr->aRangeAddress.StartColumn + 1;
+ aRange.nStartColumn = aItr->aRangeAddress.StartColumn;
+ }
+ else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) &&
+ (aItr->aRangeAddress.StartColumn <= nEndColumn) &&
+ (aItr->aRangeAddress.EndColumn > nEndColumn))
+ {
+ aRange.nRepeatColumns = nEndColumn - aItr->aRangeAddress.StartColumn + 1;
+ aRange.nStartColumn = aItr->aRangeAddress.StartColumn;
+ }
+ aRange.nRepeatRows = aItr->aRangeAddress.EndRow - nRow + 1;
+ pRowFormatRanges->AddRange(aRange, nRow);
+ nColumns += aRange.nRepeatColumns;
+ }
+ ++aItr;
+ }
+ else
+ if(aItr->aRangeAddress.EndRow < nRow)
+ aItr = pFormatRanges->erase(aItr);
+ else
+ ++aItr;
+ }
+ pRowFormatRanges->Sort();
+}
+
+void ScFormatRangeStyles::AddRangeStyleName(const table::CellRangeAddress aCellRangeAddress,
+ const sal_Int32 nStringIndex, const sal_Bool bIsAutoStyle, const sal_Int32 nValidationIndex,
+ const sal_Int32 nNumberFormat)
+{
+ ScMyFormatRange aFormatRange;
+ aFormatRange.aRangeAddress = aCellRangeAddress;
+ aFormatRange.nStyleNameIndex = nStringIndex;
+ aFormatRange.nValidationIndex = nValidationIndex;
+ aFormatRange.nNumberFormat = nNumberFormat;
+ aFormatRange.bIsAutoStyle = bIsAutoStyle;
+ DBG_ASSERT(static_cast<size_t>(aCellRangeAddress.Sheet) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[aCellRangeAddress.Sheet]);
+ pFormatRanges->push_back(aFormatRange);
+}
+
+rtl::OUString* ScFormatRangeStyles::GetStyleNameByIndex(const sal_Int32 nIndex, const sal_Bool bIsAutoStyle)
+{
+ if (bIsAutoStyle)
+ return aAutoStyleNames[nIndex];
+ else
+ return aStyleNames[nIndex];
+}
+
+void ScFormatRangeStyles::Sort()
+{
+ sal_Int32 nTables = aTables.size();
+ for (sal_Int16 i = 0; i < nTables; ++i)
+ if (!aTables[i]->empty())
+ aTables[i]->sort();
+}
+
+//===========================================================================
+
+ScColumnRowStylesBase::ScColumnRowStylesBase()
+ : aStyleNames()
+{
+}
+
+ScColumnRowStylesBase::~ScColumnRowStylesBase()
+{
+ ScMyOUStringVec::iterator i(aStyleNames.begin());
+ ScMyOUStringVec::iterator endi(aStyleNames.end());
+ while (i != endi)
+ {
+ delete *i;
+ ++i;
+ }
+}
+
+sal_Int32 ScColumnRowStylesBase::AddStyleName(rtl::OUString* pString)
+{
+ aStyleNames.push_back(pString);
+ return aStyleNames.size() - 1;
+}
+
+sal_Int32 ScColumnRowStylesBase::GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix)
+{
+ sal_Int32 nPrefixLength(rPrefix.getLength());
+ rtl::OUString sTemp(rString.copy(nPrefixLength));
+ sal_Int32 nIndex(sTemp.toInt32());
+ if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aStyleNames.size() && aStyleNames.at(nIndex - 1)->equals(rString))
+ return nIndex - 1;
+ else
+ {
+ sal_Int32 i(0);
+ sal_Bool bFound(sal_False);
+ while (!bFound && static_cast<size_t>(i) < aStyleNames.size())
+ {
+ if (aStyleNames.at(i)->equals(rString))
+ bFound = sal_True;
+ else
+ ++i;
+ }
+ if (bFound)
+ return i;
+ else
+ return -1;
+ }
+}
+
+rtl::OUString* ScColumnRowStylesBase::GetStyleNameByIndex(const sal_Int32 nIndex)
+{
+ if ( nIndex < 0 || nIndex >= sal::static_int_cast<sal_Int32>( aStyleNames.size() ) )
+ {
+ // #123981# should no longer happen, use first style then
+ DBG_ERRORFILE("GetStyleNameByIndex: invalid index");
+ return aStyleNames[0];
+ }
+
+ return aStyleNames[nIndex];
+}
+
+//===========================================================================
+
+ScColumnStyles::ScColumnStyles()
+ : ScColumnRowStylesBase(),
+ aTables()
+{
+}
+
+ScColumnStyles::~ScColumnStyles()
+{
+}
+
+void ScColumnStyles::AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields)
+{
+ sal_Int32 nSize(aTables.size() - 1);
+ if (nTable > nSize)
+ for (sal_Int32 i = nSize; i < nTable; ++i)
+ {
+ ScMyColumnStyleVec aFieldsVec(nFields + 1, ScColumnStyle());
+ aTables.push_back(aFieldsVec);
+ }
+}
+
+sal_Int32 ScColumnStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField,
+ sal_Bool& bIsVisible)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ if (static_cast<size_t>(nField) < aTables[nTable].size())
+ {
+ bIsVisible = aTables[nTable][nField].bIsVisible;
+ return aTables[nTable][nField].nIndex;
+ }
+ else
+ {
+ bIsVisible = aTables[nTable][aTables[nTable].size() - 1].bIsVisible;
+ return aTables[nTable][aTables[nTable].size() - 1].nIndex;
+ }
+}
+
+void ScColumnStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField,
+ const sal_Int32 nStringIndex, const sal_Bool bIsVisible)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ DBG_ASSERT(aTables[nTable].size() >= static_cast<sal_uInt32>(nField), "wrong field");
+ ScColumnStyle aStyle;
+ aStyle.nIndex = nStringIndex;
+ aStyle.bIsVisible = bIsVisible;
+ if (aTables[nTable].size() == static_cast<sal_uInt32>(nField))
+ aTables[nTable].push_back(aStyle);
+ aTables[nTable][nField] = aStyle;
+}
+
+rtl::OUString* ScColumnStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField)
+{
+ sal_Bool bTemp;
+ return GetStyleNameByIndex(GetStyleNameIndex(nTable, nField, bTemp));
+}
+
+//===========================================================================
+
+ScRowStyles::ScRowStyles()
+ : ScColumnRowStylesBase(),
+ aTables()
+{
+}
+
+ScRowStyles::~ScRowStyles()
+{
+}
+
+void ScRowStyles::AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields)
+{
+ sal_Int32 nSize(aTables.size() - 1);
+ if (nTable > nSize)
+ for (sal_Int32 i = nSize; i < nTable; ++i)
+ {
+ ScMysalInt32Vec aFieldsVec(nFields + 1, -1);
+ aTables.push_back(aFieldsVec);
+ }
+}
+
+sal_Int32 ScRowStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ if (static_cast<size_t>(nField) < aTables[nTable].size())
+ return aTables[nTable][nField];
+ else
+ return aTables[nTable][aTables[nTable].size() - 1];
+}
+
+void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField,
+ const sal_Int32 nStringIndex)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ DBG_ASSERT(aTables[nTable].size() >= static_cast<size_t>(nField), "wrong field");
+ if (aTables[nTable].size() == static_cast<size_t>(nField))
+ aTables[nTable].push_back(nStringIndex);
+ else
+ aTables[nTable][nField] = nStringIndex;
+}
+
+void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField,
+ const sal_Int32 nStringIndex, const sal_Int32 nEndField)
+{
+ DBG_ASSERT( nStartField <= nEndField, "bad field range");
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ DBG_ASSERT(aTables[nTable].size() >= static_cast<size_t>(nStartField), "wrong field");
+ ScMysalInt32Vec& rTable = aTables[nTable];
+ size_t nSize = rTable.size();
+ if (nSize == static_cast<size_t>(nStartField))
+ rTable.insert( rTable.end(), static_cast<size_t>(nEndField - nStartField + 1), nStringIndex);
+ else
+ {
+ size_t nField = static_cast<size_t>(nStartField);
+ for ( ; nField < nSize && nField <= static_cast<size_t>(nEndField); ++nField)
+ rTable[nField] = nStringIndex;
+ if (nField <= static_cast<size_t>(nEndField))
+ rTable.insert( rTable.end(), static_cast<size_t>(nEndField - nField + 1), nStringIndex);
+ }
+}
+
+rtl::OUString* ScRowStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField)
+{
+ return GetStyleNameByIndex(GetStyleNameIndex(nTable, nField));
+}
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.hxx b/sc/source/filter/xml/XMLStylesExportHelper.hxx
new file mode 100644
index 000000000000..79b19b7ce9ab
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesExportHelper.hxx
@@ -0,0 +1,294 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLESEXPORTHELPER_HXX
+#define SC_XMLSTYLESEXPORTHELPER_HXX
+
+#include <vector>
+#include <list>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+
+class ScDocument;
+class ScXMLExport;
+
+struct ScMyValidation
+{
+ rtl::OUString sName;
+ rtl::OUString sErrorMessage;
+ rtl::OUString sErrorTitle;
+ rtl::OUString sImputMessage;
+ rtl::OUString sImputTitle;
+ rtl::OUString sFormula1;
+ rtl::OUString sFormula2;
+ com::sun::star::table::CellAddress aBaseCell;
+ com::sun::star::sheet::ValidationAlertStyle aAlertStyle;
+ com::sun::star::sheet::ValidationType aValidationType;
+ com::sun::star::sheet::ConditionOperator aOperator;
+ sal_Int16 nShowList;
+ sal_Bool bShowErrorMessage;
+ sal_Bool bShowImputMessage;
+ sal_Bool bIgnoreBlanks;
+
+ ScMyValidation();
+ ~ScMyValidation();
+
+ sal_Bool IsEqual(const ScMyValidation& aVal) const;
+};
+
+typedef std::vector<ScMyValidation> ScMyValidationVec;
+
+class ScMyValidationsContainer
+{
+private:
+ ScMyValidationVec aValidationVec;
+ const rtl::OUString sEmptyString;
+ const rtl::OUString sERRALSTY;
+ const rtl::OUString sIGNOREBL;
+ const rtl::OUString sSHOWLIST;
+ const rtl::OUString sTYPE;
+ const rtl::OUString sSHOWINP;
+ const rtl::OUString sSHOWERR;
+ const rtl::OUString sINPTITLE;
+ const rtl::OUString sINPMESS;
+ const rtl::OUString sERRTITLE;
+ const rtl::OUString sERRMESS;
+ const rtl::OUString sOnError;
+ const rtl::OUString sEventType;
+ const rtl::OUString sStarBasic;
+ const rtl::OUString sScript;
+ const rtl::OUString sLibrary;
+ const rtl::OUString sMacroName;
+
+public:
+ ScMyValidationsContainer();
+ ~ScMyValidationsContainer();
+ sal_Bool AddValidation(const com::sun::star::uno::Any& aAny,
+ sal_Int32& nValidationIndex);
+ rtl::OUString GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation);
+ rtl::OUString GetBaseCellAddress(ScDocument* pDoc, const com::sun::star::table::CellAddress& aCell);
+ void WriteMessage(ScXMLExport& rExport,
+ const rtl::OUString& sTitle, const rtl::OUString& sMessage,
+ const sal_Bool bShowMessage, const sal_Bool bIsHelpMessage);
+ void WriteValidations(ScXMLExport& rExport);
+ const rtl::OUString& GetValidationName(const sal_Int32 nIndex);
+};
+
+//==============================================================================
+
+struct ScMyDefaultStyle
+{
+ sal_Int32 nIndex;
+ sal_Int32 nRepeat;
+ sal_Bool bIsAutoStyle;
+
+ ScMyDefaultStyle() : nIndex(-1), nRepeat(1),
+ bIsAutoStyle(sal_True) {}
+};
+
+typedef std::vector<ScMyDefaultStyle> ScMyDefaultStyleList;
+
+class ScFormatRangeStyles;
+
+class ScMyDefaultStyles
+{
+ ScMyDefaultStyleList* pRowDefaults;
+ ScMyDefaultStyleList* pColDefaults;
+
+ sal_Int32 GetStyleNameIndex(const ScFormatRangeStyles* pCellStyles,
+ const sal_Int32 nTable, const sal_Int32 nPos,
+ const sal_Int32 i, const sal_Bool bRow, sal_Bool& bIsAutoStyle);
+ void FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc,
+ const sal_Bool bRow);
+public:
+ ScMyDefaultStyles() : pRowDefaults(NULL), pColDefaults(NULL) {}
+ ~ScMyDefaultStyles();
+
+ void FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc);
+
+ const ScMyDefaultStyleList* GetRowDefaults() { return pRowDefaults; }
+ const ScMyDefaultStyleList* GetColDefaults() { return pColDefaults; }
+};
+
+struct ScMyRowFormatRange
+{
+ sal_Int32 nStartColumn;
+ sal_Int32 nRepeatColumns;
+ sal_Int32 nRepeatRows;
+ sal_Int32 nIndex;
+ sal_Int32 nValidationIndex;
+ sal_Bool bIsAutoStyle;
+
+ ScMyRowFormatRange();
+ sal_Bool operator<(const ScMyRowFormatRange& rRange) const;
+};
+
+typedef std::list<ScMyRowFormatRange> ScMyRowFormatRangesList;
+
+class ScRowFormatRanges
+{
+ ScMyRowFormatRangesList aRowFormatRanges;
+ const ScMyDefaultStyleList* pRowDefaults;
+ const ScMyDefaultStyleList* pColDefaults;
+ sal_uInt32 nSize;
+
+ void AddRange(const sal_Int32 nPrevStartCol, const sal_Int32 nRepeat, const sal_Int32 nPrevIndex,
+ const sal_Bool bPrevAutoStyle, const ScMyRowFormatRange& rFormatRange);
+
+public:
+ ScRowFormatRanges();
+ ScRowFormatRanges(const ScRowFormatRanges* pRanges);
+ ~ScRowFormatRanges();
+
+ void SetRowDefaults(const ScMyDefaultStyleList* pDefaults) { pRowDefaults = pDefaults; }
+ void SetColDefaults(const ScMyDefaultStyleList* pDefaults) { pColDefaults = pDefaults; }
+ void Clear();
+ void AddRange(ScMyRowFormatRange& rFormatRange, const sal_Int32 nStartRow);
+ sal_Bool GetNext(ScMyRowFormatRange& rFormatRange);
+ sal_Int32 GetMaxRows();
+ sal_Int32 GetSize();
+ void Sort();
+};
+
+typedef std::vector<rtl::OUString*> ScMyOUStringVec;
+
+struct ScMyFormatRange
+{
+ com::sun::star::table::CellRangeAddress aRangeAddress;
+ sal_Int32 nStyleNameIndex;
+ sal_Int32 nValidationIndex;
+ sal_Int32 nNumberFormat;
+ sal_Bool bIsAutoStyle;
+
+ ScMyFormatRange();
+ sal_Bool operator< (const ScMyFormatRange& rRange) const;
+};
+
+typedef std::list<ScMyFormatRange> ScMyFormatRangeAddresses;
+typedef std::vector<ScMyFormatRangeAddresses*> ScMyFormatRangeListVec;
+
+class ScFormatRangeStyles
+{
+ ScMyFormatRangeListVec aTables;
+ ScMyOUStringVec aStyleNames;
+ ScMyOUStringVec aAutoStyleNames;
+ const ScMyDefaultStyleList* pRowDefaults;
+ const ScMyDefaultStyleList* pColDefaults;
+
+public:
+ ScFormatRangeStyles();
+ ~ScFormatRangeStyles();
+
+ void SetRowDefaults(const ScMyDefaultStyleList* pDefaults) { pRowDefaults = pDefaults; }
+ void SetColDefaults(const ScMyDefaultStyleList* pDefaults) { pColDefaults = pDefaults; }
+ void AddNewTable(const sal_Int32 nTable);
+ sal_Bool AddStyleName(rtl::OUString* pString, sal_Int32& rIndex, const sal_Bool bIsAutoStyle = sal_True);
+ sal_Int32 GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix, sal_Bool& bIsAutoStyle);
+ // does not delete ranges
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow,
+ sal_Bool& bIsAutoStyle) const;
+ // deletes not necessary ranges if wanted
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow,
+ sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow);
+ void GetFormatRanges(const sal_Int32 nStartColumn, const sal_Int32 nEndColumn, const sal_Int32 nRow,
+ const sal_Int32 nTable, ScRowFormatRanges* pFormatRanges);
+ void AddRangeStyleName(const com::sun::star::table::CellRangeAddress aCellRangeAddress, const sal_Int32 nStringIndex,
+ const sal_Bool bIsAutoStyle, const sal_Int32 nValidationIndex, const sal_Int32 nNumberFormat);
+ rtl::OUString* GetStyleNameByIndex(const sal_Int32 nIndex, const sal_Bool bIsAutoStyle);
+ void Sort();
+};
+
+class ScColumnRowStylesBase
+{
+ ScMyOUStringVec aStyleNames;
+
+public:
+ ScColumnRowStylesBase();
+ virtual ~ScColumnRowStylesBase();
+
+ virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) = 0;
+ sal_Int32 AddStyleName(rtl::OUString* pString);
+ sal_Int32 GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix);
+ virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField) = 0;
+ rtl::OUString* GetStyleNameByIndex(const sal_Int32 nIndex);
+};
+
+struct ScColumnStyle
+{
+ sal_Int32 nIndex;
+ sal_Bool bIsVisible;
+
+ ScColumnStyle() : nIndex(-1), bIsVisible(sal_True) {}
+};
+
+
+typedef std::vector<ScColumnStyle> ScMyColumnStyleVec;
+typedef std::vector<ScMyColumnStyleVec> ScMyColumnVectorVec;
+
+class ScColumnStyles : public ScColumnRowStylesBase
+{
+ ScMyColumnVectorVec aTables;
+
+public:
+ ScColumnStyles();
+ ~ScColumnStyles();
+
+ virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields);
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField,
+ sal_Bool& bIsVisible);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex, const sal_Bool bIsVisible);
+ virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField);
+};
+
+typedef std::vector<sal_Int32> ScMysalInt32Vec;
+typedef std::vector<ScMysalInt32Vec> ScMyRowVectorVec;
+
+class ScRowStyles : public ScColumnRowStylesBase
+{
+ ScMyRowVectorVec aTables;
+
+public:
+ ScRowStyles();
+ ~ScRowStyles();
+
+ virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields);
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField, const sal_Int32 nStringIndex, const sal_Int32 nEndField);
+ virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField);
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.cxx b/sc/source/filter/xml/XMLStylesImportHelper.cxx
new file mode 100644
index 000000000000..492c7a63ee30
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesImportHelper.cxx
@@ -0,0 +1,587 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLStylesImportHelper.hxx"
+#include "xmlimprt.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/util/NumberFormat.hpp>
+
+using namespace com::sun::star;
+
+void ScMyStyleNumberFormats::AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat)
+{
+ aSet.insert(ScMyStyleNumberFormat(rStyleName, nNumberFormat));
+}
+
+sal_Int32 ScMyStyleNumberFormats::GetStyleNumberFormat(const rtl::OUString& rStyleName)
+{
+ ScMyStyleNumberFormat aStyleNumberFormat(rStyleName);
+ ScMyStyleNumberFormatSet::iterator aItr(aSet.find(aStyleNumberFormat));
+ if (aItr == aSet.end())
+ return -1;
+ else
+ return aItr->nNumberFormat;
+}
+
+ScMyStyleRanges::ScMyStyleRanges()
+ :
+ pTextList(NULL),
+ pNumberList(NULL),
+ pTimeList(NULL),
+ pDateTimeList(NULL),
+ pPercentList(NULL),
+ pLogicalList(NULL),
+ pUndefinedList(NULL),
+ pCurrencyList(NULL)
+{
+}
+
+ScMyStyleRanges::~ScMyStyleRanges()
+{
+ if (pTextList)
+ delete pTextList;
+ if (pNumberList)
+ delete pNumberList;
+ if (pTimeList)
+ delete pTimeList;
+ if (pDateTimeList)
+ delete pDateTimeList;
+ if (pPercentList)
+ delete pPercentList;
+ if (pLogicalList)
+ delete pLogicalList;
+ if (pUndefinedList)
+ delete pUndefinedList;
+ if (pCurrencyList)
+ delete pCurrencyList;
+}
+
+void ScMyStyleRanges::AddRange(const ScRange& rRange, ScRangeList* pList,
+ const rtl::OUString* pStyleName, const sal_Int16 nType,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges)
+{
+ pList->Join(rRange);
+ DBG_ASSERT(nMaxRanges > 0, "MaxRanges to less");
+ if (pList->Count() > nMaxRanges)
+ {
+ sal_Int32 nCount(pList->Count());
+ ScRange* pRange(NULL);
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ pRange = pList->GetObject(i);
+ if (pRange && (pRange->aEnd.Row() + 1 < rRange.aStart.Row()))
+ {
+ rImport.SetStyleToRange(*pRange, pStyleName, nType, NULL);
+ delete pRange;
+ pRange = NULL;
+ pList->Remove(i);
+ }
+ }
+ }
+}
+
+void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange, ScRangeListRef xList,
+ const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges)
+{
+ xList->Join(rRange);
+ DBG_ASSERT(nMaxRanges > 0, "MaxRanges to less");
+ if (xList->Count() > nMaxRanges)
+ {
+ sal_Int32 nCount(xList->Count());
+ ScRange* pRange(NULL);
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ pRange = xList->GetObject(i);
+ if (pRange && (pRange->aEnd.Row() + 1 < rRange.aStart.Row()))
+ {
+ rImport.SetStyleToRange(*pRange, pStyleName, util::NumberFormat::CURRENCY, pCurrency);
+ delete pRange;
+ pRange = NULL;
+ xList->Remove(i);
+ }
+ }
+ }
+}
+
+void ScMyStyleRanges::AddRange(const ScRange& rRange,
+ const rtl::OUString* pStyleName, const sal_Int16 nType,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges)
+{
+ switch (nType)
+ {
+ case util::NumberFormat::NUMBER:
+ {
+ if (!pNumberList)
+ pNumberList = new ScRangeList();
+ AddRange(rRange, pNumberList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ case util::NumberFormat::TEXT:
+ {
+ if (!pTextList)
+ pTextList = new ScRangeList();
+ AddRange(rRange, pTextList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ case util::NumberFormat::TIME:
+ {
+ if (!pTimeList)
+ pTimeList = new ScRangeList();
+ AddRange(rRange, pTimeList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ case util::NumberFormat::DATETIME:
+ {
+ if (!pDateTimeList)
+ pDateTimeList = new ScRangeList();
+ AddRange(rRange, pDateTimeList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ case util::NumberFormat::PERCENT:
+ {
+ if (!pPercentList)
+ pPercentList = new ScRangeList();
+ AddRange(rRange, pPercentList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ case util::NumberFormat::LOGICAL:
+ {
+ if (!pLogicalList)
+ pLogicalList = new ScRangeList();
+ AddRange(rRange, pLogicalList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ case util::NumberFormat::UNDEFINED:
+ {
+ if (!pUndefinedList)
+ pUndefinedList = new ScRangeList();
+ AddRange(rRange, pUndefinedList, pStyleName, nType, rImport, nMaxRanges);
+ }
+ break;
+ default:
+ {
+ DBG_ERROR("wrong type");
+ }
+ break;
+ }
+}
+
+void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange,
+ const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges)
+{
+ if (!pCurrencyList)
+ pCurrencyList = new ScMyCurrencyStylesSet();
+ ScMyCurrencyStyle aStyle;
+ if (pCurrency)
+ aStyle.sCurrency = *pCurrency;
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->find(aStyle));
+ if (aItr == pCurrencyList->end())
+ {
+ std::pair<ScMyCurrencyStylesSet::iterator, bool> aPair(pCurrencyList->insert(aStyle));
+ if (aPair.second)
+ {
+ aItr = aPair.first;
+ AddCurrencyRange(rRange, aItr->xRanges, pStyleName, pCurrency, rImport, nMaxRanges);
+ }
+ }
+ else
+ aItr->xRanges->Join(rRange);
+}
+
+void ScMyStyleRanges::InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy,
+ const SCsTAB nDz, ScDocument* pDoc)
+{
+ UpdateRefMode aRefMode(URM_INSDEL);
+ if (pNumberList)
+ pNumberList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pTextList)
+ pTextList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pTimeList)
+ pTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pDateTimeList)
+ pDateTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pPercentList)
+ pPercentList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pLogicalList)
+ pLogicalList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pUndefinedList)
+ pUndefinedList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ if (pCurrencyList)
+ {
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+ ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+ ++aItr;
+ }
+ }
+}
+
+void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
+{
+ InsertColRow(ScRange(0, static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab),
+ MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 0, 1, 0, pDoc);
+}
+
+void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
+{
+ InsertColRow(ScRange(static_cast<SCCOL>(nCol), 0, static_cast<SCTAB>(nTab),
+ MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 1, 0, 0, pDoc);
+}
+
+void ScMyStyleRanges::SetStylesToRanges(ScRangeList* pList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport)
+{
+ sal_Int32 nCount(pList->Count());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ rImport.SetStyleToRange(*pList->GetObject(i), pStyleName, nCellType, pCurrency);
+}
+
+void ScMyStyleRanges::SetStylesToRanges(ScRangeListRef xList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport)
+{
+ sal_Int32 nCount(xList->Count());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ rImport.SetStyleToRange(*xList->GetObject(i), pStyleName, nCellType, pCurrency);
+}
+
+void ScMyStyleRanges::SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport)
+{
+ if (pNumberList)
+ SetStylesToRanges(pNumberList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport);
+ if (pTextList)
+ SetStylesToRanges(pTextList, pStyleName, util::NumberFormat::TEXT, NULL, rImport);
+ if (pTimeList)
+ SetStylesToRanges(pTimeList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
+ if (pDateTimeList)
+ SetStylesToRanges(pDateTimeList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport);
+ if (pPercentList)
+ SetStylesToRanges(pPercentList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport);
+ if (pLogicalList)
+ SetStylesToRanges(pLogicalList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport);
+ if (pUndefinedList)
+ SetStylesToRanges(pUndefinedList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport);
+ if (pCurrencyList)
+ {
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+ ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+ while (aItr != aEndItr)
+ {
+ SetStylesToRanges(aItr->xRanges, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport);
+ ++aItr;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+ScMyStylesImportHelper::ScMyStylesImportHelper(ScXMLImport& rTempImport)
+ :
+ aRowDefaultStyle(aCellStyles.end()),
+ rImport(rTempImport),
+ pStyleName(NULL),
+ pPrevStyleName(NULL),
+ pCurrency(NULL),
+ pPrevCurrency(NULL),
+ nMaxRanges(0),
+ bPrevRangeAdded(sal_True)
+{
+}
+
+ScMyStylesImportHelper::~ScMyStylesImportHelper()
+{
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ if (pPrevCurrency)
+ delete pPrevCurrency;
+ if (pStyleName)
+ delete pStyleName;
+ if (pCurrency)
+ delete pCurrency;
+}
+
+void ScMyStylesImportHelper::ResetAttributes()
+{
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ if (pPrevCurrency)
+ delete pPrevCurrency;
+ pPrevStyleName = pStyleName;
+ pPrevCurrency = pCurrency;
+ nPrevCellType = nCellType;
+ pStyleName = NULL;
+ pCurrency = NULL;
+ nCellType = 0;
+}
+
+ScMyStylesSet::iterator ScMyStylesImportHelper::GetIterator(const rtl::OUString* pStyleNameP)
+{
+ ScMyStyle aStyle;
+ if (pStyleNameP)
+ aStyle.sStyleName = *pStyleNameP;
+ else
+ {
+ DBG_ERROR("here is no stylename given");
+ }
+ ScMyStylesSet::iterator aItr(aCellStyles.find(aStyle));
+ if (aItr == aCellStyles.end())
+ {
+ std::pair<ScMyStylesSet::iterator, bool> aPair(aCellStyles.insert(aStyle));
+ if (aPair.second)
+ aItr = aPair.first;
+ else
+ {
+ DBG_ERROR("not possible to insert style");
+ return aCellStyles.end();
+ }
+ }
+ return aItr;
+}
+
+void ScMyStylesImportHelper::AddDefaultRange(const ScRange& rRange)
+{
+ DBG_ASSERT(aRowDefaultStyle != aCellStyles.end(), "no row default style");
+ if (!aRowDefaultStyle->sStyleName.getLength())
+ {
+ SCCOL nStartCol(rRange.aStart.Col());
+ SCCOL nEndCol(rRange.aEnd.Col());
+ if (aColDefaultStyles.size() > sal::static_int_cast<sal_uInt32>(nStartCol))
+ {
+ ScMyStylesSet::iterator aPrevItr(aColDefaultStyles[nStartCol]);
+ DBG_ASSERT(aColDefaultStyles.size() > sal::static_int_cast<sal_uInt32>(nEndCol), "to much columns");
+ for (SCCOL i = nStartCol + 1; (i <= nEndCol) && (i < sal::static_int_cast<SCCOL>(aColDefaultStyles.size())); ++i)
+ {
+ if (aPrevItr != aColDefaultStyles[i])
+ {
+ DBG_ASSERT(aPrevItr != aCellStyles.end(), "no column default style");
+ ScRange aRange(rRange);
+ aRange.aStart.SetCol(nStartCol);
+ aRange.aEnd.SetCol(i - 1);
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ pPrevStyleName = new rtl::OUString(aPrevItr->sStyleName);
+ AddSingleRange(aRange);
+ nStartCol = i;
+ aPrevItr = aColDefaultStyles[i];
+ }
+ }
+ if (aPrevItr != aCellStyles.end())
+ {
+ ScRange aRange(rRange);
+ aRange.aStart.SetCol(nStartCol);
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ pPrevStyleName = new rtl::OUString(aPrevItr->sStyleName);
+ AddSingleRange(aRange);
+ }
+ else
+ {
+ DBG_ERRORFILE("no column default style");
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("to much columns");
+ }
+ }
+ else
+ {
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ pPrevStyleName = new rtl::OUString(aRowDefaultStyle->sStyleName);
+ AddSingleRange(rRange);
+ }
+}
+
+void ScMyStylesImportHelper::AddSingleRange(const ScRange& rRange)
+{
+ if (nMaxRanges == 0)
+ nMaxRanges = aColDefaultStyles.size();
+ ScMyStylesSet::iterator aItr(GetIterator(pPrevStyleName));
+ if (aItr != aCellStyles.end())
+ {
+ if (nPrevCellType != util::NumberFormat::CURRENCY)
+ aItr->xRanges->AddRange(rRange, pPrevStyleName, nPrevCellType,
+ rImport, nMaxRanges);
+ else
+ aItr->xRanges->AddCurrencyRange(rRange, pPrevStyleName, pPrevCurrency,
+ rImport, nMaxRanges);
+ }
+}
+
+void ScMyStylesImportHelper::AddRange()
+{
+ if (pPrevStyleName && pPrevStyleName->getLength())
+ AddSingleRange(aPrevRange);
+ else
+ AddDefaultRange(aPrevRange);
+ ResetAttributes();
+}
+
+void ScMyStylesImportHelper::AddColumnStyle(const rtl::OUString& sStyleName, const sal_Int32 nColumn, const sal_Int32 nRepeat)
+{
+ (void)nColumn; // avoid warning in product version
+ DBG_ASSERT(static_cast<sal_uInt32>(nColumn) == aColDefaultStyles.size(), "some columns are absent");
+ ScMyStylesSet::iterator aItr(GetIterator(&sStyleName));
+ DBG_ASSERT(aItr != aCellStyles.end(), "no column default style");
+ aColDefaultStyles.reserve(aColDefaultStyles.size() + nRepeat);
+ for (sal_Int32 i = 0; i < nRepeat; ++i)
+ aColDefaultStyles.push_back(aItr);
+}
+
+void ScMyStylesImportHelper::SetRowStyle(const rtl::OUString& sStyleName)
+{
+ aRowDefaultStyle = GetIterator(&sStyleName);
+}
+
+void ScMyStylesImportHelper::SetAttributes(rtl::OUString* pStyleNameP,
+ rtl::OUString* pCurrencyP, const sal_Int16 nCellTypeP)
+{
+ if (this->pStyleName)
+ delete this->pStyleName;
+ if (this->pCurrency)
+ delete this->pCurrency;
+ this->pStyleName = pStyleNameP;
+ this->pCurrency = pCurrencyP;
+ this->nCellType = nCellTypeP;
+}
+
+void ScMyStylesImportHelper::AddRange(const ScRange& rRange)
+{
+ if (!bPrevRangeAdded)
+ {
+ sal_Bool bAddRange(sal_False);
+ if (nCellType == nPrevCellType &&
+ IsEqual(pStyleName, pPrevStyleName) &&
+ IsEqual(pCurrency, pPrevCurrency))
+ {
+ if (rRange.aStart.Row() == aPrevRange.aStart.Row())
+ {
+ if (rRange.aEnd.Row() == aPrevRange.aEnd.Row())
+ {
+ DBG_ASSERT(aPrevRange.aEnd.Col() + 1 == rRange.aStart.Col(), "something wents wrong");
+ aPrevRange.aEnd.SetCol(rRange.aEnd.Col());
+ }
+ else
+ bAddRange = sal_True;
+ }
+ else
+ {
+ if (rRange.aStart.Col() == aPrevRange.aStart.Col() &&
+ rRange.aEnd.Col() == aPrevRange.aEnd.Col())
+ {
+ DBG_ASSERT(aPrevRange.aEnd.Row() + 1 == rRange.aStart.Row(), "something wents wrong");
+ aPrevRange.aEnd.SetRow(rRange.aEnd.Row());
+ }
+ else
+ bAddRange = sal_True;
+ }
+ }
+ else
+ bAddRange = sal_True;
+ if (bAddRange)
+ {
+ AddRange();
+ aPrevRange = rRange;
+ }
+ }
+ else
+ {
+ aPrevRange = rRange;
+ ResetAttributes();
+ bPrevRangeAdded = sal_False;
+ }
+}
+
+void ScMyStylesImportHelper::AddCell(const com::sun::star::table::CellAddress& rAddress)
+{
+ ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet );
+ ScRange aScRange( aScAddress, aScAddress );
+ AddRange(aScRange);
+}
+
+void ScMyStylesImportHelper::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
+{
+ rImport.LockSolarMutex();
+ ScMyStylesSet::iterator aItr(aCellStyles.begin());
+ ScMyStylesSet::iterator aEndItr(aCellStyles.end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->InsertRow(nRow, nTab, pDoc);
+ ++aItr;
+ }
+ rImport.UnlockSolarMutex();
+}
+
+void ScMyStylesImportHelper::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
+{
+ rImport.LockSolarMutex();
+ ScMyStylesSet::iterator aItr(aCellStyles.begin());
+ ScMyStylesSet::iterator aEndItr(aCellStyles.end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->InsertCol(nCol, nTab, pDoc);
+ ++aItr;
+ }
+ rImport.UnlockSolarMutex();
+}
+
+void ScMyStylesImportHelper::EndTable()
+{
+ if (!bPrevRangeAdded)
+ {
+ AddRange();
+ bPrevRangeAdded = sal_True;
+ }
+ nMaxRanges = 0;
+}
+
+void ScMyStylesImportHelper::SetStylesToRanges()
+{
+ ScMyStylesSet::iterator aItr(aCellStyles.begin());
+ ScMyStylesSet::iterator aEndItr(aCellStyles.end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->SetStylesToRanges(&aItr->sStyleName, rImport);
+ ++aItr;
+ }
+ aColDefaultStyles.clear();
+ aCellStyles.clear();
+ nMaxRanges = 0;
+}
+
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.hxx b/sc/source/filter/xml/XMLStylesImportHelper.hxx
new file mode 100644
index 000000000000..3a15dbeff52a
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesImportHelper.hxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLESIMPORTHELPER_HXX
+#define SC_XMLSTYLESIMPORTHELPER_HXX
+
+#include "rangelst.hxx"
+#include <rtl/ustring.hxx>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <set>
+#include <vector>
+
+class ScXMLImport;
+
+struct ScMyStyleNumberFormat
+{
+ rtl::OUString sStyleName;
+ sal_Int32 nNumberFormat;
+
+ ScMyStyleNumberFormat() : nNumberFormat(-1) {}
+ ScMyStyleNumberFormat(const rtl::OUString& rStyleName) :
+ sStyleName(rStyleName), nNumberFormat(-1) {}
+ ScMyStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nFormat) :
+ sStyleName(rStyleName), nNumberFormat(nFormat) {}
+};
+
+struct LessStyleNumberFormat
+{
+ sal_Bool operator() (const ScMyStyleNumberFormat& rValue1, const ScMyStyleNumberFormat& rValue2) const
+ {
+ return rValue1.sStyleName < rValue2.sStyleName;
+ }
+};
+
+typedef std::set< ScMyStyleNumberFormat, LessStyleNumberFormat > ScMyStyleNumberFormatSet;
+
+class ScMyStyleNumberFormats
+{
+ ScMyStyleNumberFormatSet aSet;
+
+public:
+ void AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat);
+ sal_Int32 GetStyleNumberFormat(const rtl::OUString& rStyleName);
+};
+
+struct ScMyCurrencyStyle
+{
+ rtl::OUString sCurrency;
+ ScRangeListRef xRanges;
+
+ ScMyCurrencyStyle() : xRanges(new ScRangeList()) {}
+ ~ScMyCurrencyStyle() {}
+};
+
+struct LessCurrencyStyle
+{
+ sal_Bool operator() (const ScMyCurrencyStyle& rValue1, const ScMyCurrencyStyle& rValue2) const
+ {
+ return rValue1.sCurrency < rValue2.sCurrency;
+ }
+};
+
+typedef std::set<ScMyCurrencyStyle, LessCurrencyStyle> ScMyCurrencyStylesSet;
+
+class ScMyStyleRanges : public SvRefBase
+{
+ ScRangeList* pTextList;
+ ScRangeList* pNumberList;
+ ScRangeList* pTimeList;
+ ScRangeList* pDateTimeList;
+ ScRangeList* pPercentList;
+ ScRangeList* pLogicalList;
+ ScRangeList* pUndefinedList;
+ ScMyCurrencyStylesSet* pCurrencyList;
+
+ void AddRange(const ScRange& rRange, ScRangeList* pList,
+ const rtl::OUString* pStyleName, const sal_Int16 nType,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+ void AddCurrencyRange(const ScRange& rRange, ScRangeListRef xList,
+ const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+ void InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy,
+ const SCsTAB nDz, ScDocument* pDoc);
+ void SetStylesToRanges(ScRangeList* pList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport);
+ void SetStylesToRanges(ScRangeListRef xList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport);
+public:
+ ScMyStyleRanges();
+ ~ScMyStyleRanges();
+ void AddRange(const ScRange& rRange,
+ const rtl::OUString* pStyleName, const sal_Int16 nType,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+ void AddCurrencyRange(const ScRange& rRange,
+ const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+ void InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc);
+ void InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc);
+ void SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport);
+};
+SV_DECL_IMPL_REF( ScMyStyleRanges );
+
+struct ScMyStyle
+{
+ rtl::OUString sStyleName;
+ ScMyStyleRangesRef xRanges;
+
+ ScMyStyle() : xRanges(new ScMyStyleRanges()) {}
+ ~ScMyStyle() {}
+};
+
+struct LessStyle
+{
+ sal_Bool operator() (const ScMyStyle& rValue1, const ScMyStyle& rValue2) const
+ {
+ return rValue1.sStyleName < rValue2.sStyleName;
+ }
+};
+
+typedef std::set<ScMyStyle, LessStyle> ScMyStylesSet;
+typedef std::vector<ScMyStylesSet::iterator> ScMyStyles;
+
+class ScMyStylesImportHelper
+{
+ ScMyStylesSet aCellStyles;
+ ScMyStyles aColDefaultStyles;
+ ScMyStylesSet::iterator aRowDefaultStyle;
+ ScXMLImport& rImport;
+ rtl::OUString* pStyleName;
+ rtl::OUString* pPrevStyleName;
+ rtl::OUString* pCurrency;
+ rtl::OUString* pPrevCurrency;
+ ScRange aPrevRange;
+ sal_uInt32 nMaxRanges;
+ sal_Int16 nCellType;
+ sal_Int16 nPrevCellType;
+ sal_Bool bPrevRangeAdded;
+
+ void ResetAttributes();
+ ScMyStylesSet::iterator GetIterator(const rtl::OUString* pStyleName);
+ void AddDefaultRange(const ScRange& rRange);
+ void AddSingleRange(const ScRange& rRange);
+ void AddRange();
+ sal_Bool IsEqual(const rtl::OUString* pFirst, const rtl::OUString* pSecond)
+ {
+ return ((pFirst && pSecond && pFirst->equals(*pSecond)) ||
+ (!pFirst && !pSecond) ||
+ (!pFirst && pSecond && !pSecond->getLength()) ||
+ (!pSecond && pFirst && !pFirst->getLength()));
+ }
+public:
+ ScMyStylesImportHelper(ScXMLImport& rImport);
+ ~ScMyStylesImportHelper();
+ void AddColumnStyle(const rtl::OUString& rStyleName, const sal_Int32 nColumn, const sal_Int32 nRepeat);
+ void SetRowStyle(const rtl::OUString& rStyleName);
+ void SetAttributes(rtl::OUString* pStyleName,
+ rtl::OUString* pCurrency, const sal_Int16 nCellType);
+ void AddRange(const ScRange& rRange);
+ void AddCell(const com::sun::star::table::CellAddress& rAddress);
+ void InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc); // a row is inserted before nRow
+ void InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc); // a col is inserted before nCol
+ void EndTable();
+ void SetStylesToRanges();
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
new file mode 100644
index 000000000000..fb0b1235007e
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
@@ -0,0 +1,268 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/text/XText.hpp>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include "XMLTableHeaderFooterContext.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <comphelper/extract.hxx>
+
+#include "unonames.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace xmloff::token;
+
+
+TYPEINIT1( XMLTableHeaderFooterContext, SvXMLImportContext );
+
+XMLTableHeaderFooterContext::XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList,
+ const Reference < XPropertySet > & rPageStylePropSet,
+ sal_Bool bFooter, sal_Bool bLft ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xPropSet( rPageStylePropSet ),
+ sOn( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_FTRON : SC_UNO_PAGE_HDRON ) ),
+ sShareContent( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_FTRSHARED : SC_UNO_PAGE_HDRSHARED ) ),
+ sContent( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_RIGHTFTRCON : SC_UNO_PAGE_RIGHTHDRCON ) ),
+ sContentLeft( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_LEFTFTRCONT : SC_UNO_PAGE_LEFTHDRCONT ) ),
+ bDisplay( sal_True ),
+ bInsertContent( sal_True ),
+ bLeft( bLft ),
+ bContainsLeft(sal_False),
+ bContainsRight(sal_False),
+ bContainsCenter(sal_False)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ OUString aLName;
+ sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLName ));
+ const OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ // TODO: use a map here
+ if( XML_NAMESPACE_STYLE == nPrefix )
+ {
+ if( IsXMLToken(aLName, XML_DISPLAY ) )
+ bDisplay = IsXMLToken(rValue, XML_TRUE);
+ }
+ }
+ if( bLeft )
+ {
+ sal_Bool bOn(::cppu::any2bool(xPropSet->getPropertyValue( sOn )));
+
+ if( bOn && bDisplay )
+ {
+ if( ::cppu::any2bool(xPropSet->getPropertyValue( sShareContent )) )
+ // Don't share headers any longer
+ xPropSet->setPropertyValue( sShareContent, uno::makeAny(sal_False) );
+ }
+ else
+ {
+ if( !::cppu::any2bool(xPropSet->getPropertyValue( sShareContent )) )
+ // share headers
+ xPropSet->setPropertyValue( sShareContent, uno::makeAny(sal_True) );
+ }
+ }
+ else
+ {
+ sal_Bool bOn(::cppu::any2bool(xPropSet->getPropertyValue( sOn )));
+ if ( bOn != bDisplay )
+ xPropSet->setPropertyValue( sOn, uno::makeAny(bDisplay) );
+ }
+ if (bLeft)
+ sCont = sContentLeft;
+ else
+ sCont = sContent;
+ xPropSet->getPropertyValue( sCont ) >>= xHeaderFooterContent;
+}
+
+XMLTableHeaderFooterContext::~XMLTableHeaderFooterContext()
+{
+}
+
+SvXMLImportContext *XMLTableHeaderFooterContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) &&
+ IsXMLToken(rLocalName, XML_P))
+ {
+ if (!xTextCursor.is())
+ {
+ if( xHeaderFooterContent.is() )
+ {
+ uno::Reference < text::XText > xText(xHeaderFooterContent->getCenterText());
+ xText->setString(sEmpty);
+ xTextCursor.set(xText->createTextCursor());
+ xOldTextCursor.set(GetImport().GetTextImport()->GetCursor());
+ GetImport().GetTextImport()->SetCursor( xTextCursor );
+ bContainsCenter = sal_True;
+ }
+ }
+ pContext =
+ GetImport().GetTextImport()->CreateTextChildContext(GetImport(),
+ nPrefix,
+ rLocalName,
+ xAttrList);
+ }
+ else
+ {
+ if (nPrefix == XML_NAMESPACE_STYLE)
+ {
+ if (xHeaderFooterContent.is())
+ {
+ uno::Reference < text::XText > xText;
+ if (IsXMLToken(rLocalName, XML_REGION_LEFT ))
+ {
+ xText.set(xHeaderFooterContent->getLeftText());
+ bContainsLeft = sal_True;
+ }
+ else if (IsXMLToken(rLocalName, XML_REGION_CENTER ))
+ {
+ xText.set(xHeaderFooterContent->getCenterText());
+ bContainsCenter = sal_True;
+ }
+ else if (IsXMLToken(rLocalName, XML_REGION_RIGHT ))
+ {
+ xText.set(xHeaderFooterContent->getRightText());
+ bContainsRight = sal_True;
+ }
+ if (xText.is())
+ {
+ xText->setString(sEmpty);
+ //SvXMLImport aSvXMLImport( GetImport() );
+ uno::Reference < text::XTextCursor > xTempTextCursor(xText->createTextCursor());
+ pContext = new XMLHeaderFooterRegionContext( GetImport(), nPrefix, rLocalName, xAttrList, xTempTextCursor);
+ }
+ }
+ }
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void XMLTableHeaderFooterContext::EndElement()
+{
+ if( GetImport().GetTextImport()->GetCursor().is() )
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), sEmpty,
+ sal_True );
+ }
+ GetImport().GetTextImport()->ResetCursor();
+ }
+ if (xOldTextCursor.is())
+ GetImport().GetTextImport()->SetCursor(xOldTextCursor);
+ if (xHeaderFooterContent.is())
+ {
+ if (!bContainsLeft)
+ xHeaderFooterContent->getLeftText()->setString(sEmpty);
+ if (!bContainsCenter)
+ xHeaderFooterContent->getCenterText()->setString(sEmpty);
+ if (!bContainsRight)
+ xHeaderFooterContent->getRightText()->setString(sEmpty);
+
+ xPropSet->setPropertyValue( sCont, uno::makeAny(xHeaderFooterContent) );
+ }
+}
+
+TYPEINIT1( XMLHeaderFooterRegionContext, SvXMLImportContext );
+
+XMLHeaderFooterRegionContext::XMLHeaderFooterRegionContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference<
+ xml::sax::XAttributeList > & /* xAttrList */,
+ uno::Reference< text::XTextCursor >& xCursor ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xTextCursor ( xCursor )
+{
+ xOldTextCursor.set(GetImport().GetTextImport()->GetCursor());
+ GetImport().GetTextImport()->SetCursor( xTextCursor );
+}
+
+XMLHeaderFooterRegionContext::~XMLHeaderFooterRegionContext()
+{
+}
+
+SvXMLImportContext *XMLHeaderFooterRegionContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) &&
+ IsXMLToken(rLocalName, XML_P))
+ {
+ pContext =
+ GetImport().GetTextImport()->CreateTextChildContext(GetImport(),
+ nPrefix,
+ rLocalName,
+ xAttrList);
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void XMLHeaderFooterRegionContext::EndElement()
+{
+ if( GetImport().GetTextImport()->GetCursor().is() )
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ OUString sEmpty;
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), sEmpty,
+ sal_True );
+ }
+ GetImport().GetTextImport()->ResetCursor();
+ }
+ if (xOldTextCursor.is())
+ GetImport().GetTextImport()->SetCursor(xOldTextCursor);
+}
diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
new file mode 100644
index 000000000000..a3ce9c4c970d
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLTABLEHEADERFOOTERCONTEXT_HXX_
+#define SC_XMLTABLEHEADERFOOTERCONTEXT_HXX_
+
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace text { class XTextCursor; }
+ namespace beans { class XPropertySet; }
+} } }
+
+class XMLTableHeaderFooterContext: public SvXMLImportContext
+{
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor > xTextCursor;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor > xOldTextCursor;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::beans::XPropertySet > xPropSet;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::sheet::XHeaderFooterContent > xHeaderFooterContent;
+
+ const ::rtl::OUString sOn;
+ const ::rtl::OUString sShareContent;
+ const ::rtl::OUString sContent;
+ const ::rtl::OUString sContentLeft;
+ const ::rtl::OUString sEmpty;
+ rtl::OUString sCont;
+
+ sal_Bool bDisplay;
+ sal_Bool bInsertContent;
+ sal_Bool bLeft;
+ sal_Bool bContainsLeft;
+ sal_Bool bContainsRight;
+ sal_Bool bContainsCenter;
+
+public:
+ TYPEINFO();
+
+ XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const ::com::sun::star::uno::Reference <
+ ::com::sun::star::beans::XPropertySet > & rPageStylePropSet,
+ sal_Bool bFooter, sal_Bool bLft );
+
+ virtual ~XMLTableHeaderFooterContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual void EndElement();
+};
+
+class XMLHeaderFooterRegionContext: public SvXMLImportContext
+{
+private:
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor >& xTextCursor;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor > xOldTextCursor;
+
+public:
+ TYPEINFO();
+
+ XMLHeaderFooterRegionContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ com::sun::star::uno::Reference< com::sun::star::text::XTextCursor >& xCursor );
+
+ virtual ~XMLHeaderFooterRegionContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual void EndElement();
+};
+
+
+#endif
diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.cxx b/sc/source/filter/xml/XMLTableMasterPageExport.cxx
new file mode 100644
index 000000000000..91f27ab646a7
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableMasterPageExport.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <tools/debug.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "XMLTableMasterPageExport.hxx"
+#include <comphelper/extract.hxx>
+
+#include "unonames.hxx"
+#include "xmlexprt.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace xmloff::token;
+
+XMLTableMasterPageExport::XMLTableMasterPageExport( ScXMLExport& rExp ) :
+ XMLTextMasterPageExport ( rExp )
+{
+}
+
+XMLTableMasterPageExport::~XMLTableMasterPageExport()
+{
+}
+
+void XMLTableMasterPageExport::exportHeaderFooterContent(
+ const Reference< XText >& rText,
+ sal_Bool bAutoStyles, sal_Bool bProgress )
+{
+ DBG_ASSERT( rText.is(), "There is the text" );
+
+ if( bAutoStyles )
+ GetExport().GetTextParagraphExport()
+ ->collectTextAutoStyles( rText, bProgress, sal_False );
+ else
+ {
+ GetExport().GetTextParagraphExport()->exportTextDeclarations( rText );
+ GetExport().GetTextParagraphExport()->exportText( rText, bProgress, sal_False );
+ }
+}
+
+void XMLTableMasterPageExport::exportHeaderFooter(const com::sun::star::uno::Reference < com::sun::star::sheet::XHeaderFooterContent >& xHeaderFooter,
+ const XMLTokenEnum aName,
+ const sal_Bool bDisplay)
+{
+ if( xHeaderFooter.is() )
+ {
+ Reference < XText > xCenter(xHeaderFooter->getCenterText());
+ Reference < XText > xLeft(xHeaderFooter->getLeftText());
+ Reference < XText > xRight(xHeaderFooter->getRightText());
+ if (xCenter.is() && xLeft.is() && xRight.is())
+ {
+ rtl::OUString sCenter (xCenter->getString());
+ rtl::OUString sLeft (xLeft->getString());
+ rtl::OUString sRight (xRight->getString());
+
+ if( !bDisplay )
+ GetExport().AddAttribute( XML_NAMESPACE_STYLE,
+ XML_DISPLAY, XML_FALSE );
+ SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
+ aName, sal_True, sal_True );
+ if (sCenter.getLength() && !sLeft.getLength() && !sRight.getLength())
+ exportHeaderFooterContent( xCenter, sal_False, sal_False );
+ else
+ {
+ if (sLeft.getLength())
+ {
+ SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE,
+ XML_REGION_LEFT, sal_True, sal_True );
+ exportHeaderFooterContent( xLeft, sal_False, sal_False );
+ }
+ if (sCenter.getLength())
+ {
+ SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE,
+ XML_REGION_CENTER, sal_True, sal_True );
+ exportHeaderFooterContent( xCenter, sal_False, sal_False );
+ }
+ if (sRight.getLength())
+ {
+ SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE,
+ XML_REGION_RIGHT, sal_True, sal_True );
+ exportHeaderFooterContent( xRight, sal_False, sal_False );
+ }
+ }
+ }
+ }
+}
+
+void XMLTableMasterPageExport::exportMasterPageContent(
+ const Reference < XPropertySet > & rPropSet,
+ sal_Bool bAutoStyles )
+{
+ Reference < sheet::XHeaderFooterContent > xHeader(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_RIGHTHDRCON ) ) ), uno::UNO_QUERY);
+
+ Reference < sheet::XHeaderFooterContent > xHeaderLeft(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_LEFTHDRCONT ) ) ), uno::UNO_QUERY);
+
+ Reference < sheet::XHeaderFooterContent > xFooter(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_RIGHTFTRCON ) ) ), uno::UNO_QUERY);
+
+ Reference < sheet::XHeaderFooterContent > xFooterLeft(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_LEFTFTRCONT ) ) ), uno::UNO_QUERY);
+
+ if( bAutoStyles )
+ {
+ if( xHeader.is() )
+ {
+ exportHeaderFooterContent( xHeader->getCenterText(), sal_True, sal_False );
+ exportHeaderFooterContent( xHeader->getLeftText(), sal_True, sal_False );
+ exportHeaderFooterContent( xHeader->getRightText(), sal_True, sal_False );
+ }
+ if( xHeaderLeft.is())
+ {
+ exportHeaderFooterContent( xHeaderLeft->getCenterText(), sal_True, sal_False );
+ exportHeaderFooterContent( xHeaderLeft->getLeftText(), sal_True, sal_False );
+ exportHeaderFooterContent( xHeaderLeft->getRightText(), sal_True, sal_False );
+ }
+ if( xFooter.is() )
+ {
+ exportHeaderFooterContent( xFooter->getCenterText(), sal_True, sal_False );
+ exportHeaderFooterContent( xFooter->getLeftText(), sal_True, sal_False );
+ exportHeaderFooterContent( xFooter->getRightText(), sal_True, sal_False );
+ }
+ if( xFooterLeft.is())
+ {
+ exportHeaderFooterContent( xFooterLeft->getCenterText(), sal_True, sal_False );
+ exportHeaderFooterContent( xFooterLeft->getLeftText(), sal_True, sal_False );
+ exportHeaderFooterContent( xFooterLeft->getRightText(), sal_True, sal_False );
+ }
+ }
+ else
+ {
+ sal_Bool bHeader(::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_HDRON ) ) )));
+
+ exportHeaderFooter(xHeader, XML_HEADER, bHeader );
+
+ sal_Bool bLeftHeader(!::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_HDRSHARED ) ) )) && bHeader);
+
+ exportHeaderFooter( xHeaderLeft, XML_HEADER_LEFT, bLeftHeader );
+
+ sal_Bool bFooter(::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_FTRON ) ) )));
+
+ exportHeaderFooter( xFooter, XML_FOOTER, bFooter );
+
+ sal_Bool bLeftFooter = (!::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_FTRSHARED ) ) )) && bFooter);
+
+ exportHeaderFooter( xFooterLeft, XML_FOOTER_LEFT, bLeftFooter );
+ }
+}
+
diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.hxx b/sc/source/filter/xml/XMLTableMasterPageExport.hxx
new file mode 100644
index 000000000000..0a277bec0bb9
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableMasterPageExport.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLEMASTERPAGEEXPORT_HXX
+#define SC_XMLTABLEMASTERPAGEEXPORT_HXX
+
+#include <rtl/ustring.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/XMLTextMasterPageExport.hxx>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+
+#include "xmlexprt.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace text { class XText; }
+} } }
+
+class XMLTableMasterPageExport : public XMLTextMasterPageExport
+{
+ void exportHeaderFooter(const com::sun::star::uno::Reference < com::sun::star::sheet::XHeaderFooterContent >& xHeaderFooter,
+ const xmloff::token::XMLTokenEnum aName,
+ const sal_Bool bDisplay);
+
+protected:
+ virtual void exportHeaderFooterContent(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::text::XText >& rText,
+ sal_Bool bAutoStyles, sal_Bool bProgress );
+
+ virtual void exportMasterPageContent(
+ const ::com::sun::star::uno::Reference <
+ ::com::sun::star::beans::XPropertySet > & rPropSet,
+ sal_Bool bAutoStyles );
+
+public:
+ XMLTableMasterPageExport( ScXMLExport& rExp );
+ ~XMLTableMasterPageExport();
+};
+
+
+#endif // _XMLOFF_XMLTABLEMASTERPAGEEXPORT_HXX
+
diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
new file mode 100644
index 000000000000..cc425e0f4d65
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
@@ -0,0 +1,215 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "xmlimprt.hxx"
+#include "XMLConverter.hxx"
+#include "drwlayer.hxx"
+#include "xmlannoi.hxx"
+#include "rangeutl.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/svdobj.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#define SC_LAYERID "LayerID"
+
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+XMLTableShapeImportHelper::XMLTableShapeImportHelper(
+ ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper ) :
+ XMLShapeImportHelper(rImp, rImp.GetModel(), pImpMapper ),
+ pAnnotationContext(NULL),
+ bOnTable(sal_False)
+{
+}
+
+XMLTableShapeImportHelper::~XMLTableShapeImportHelper()
+{
+}
+
+void XMLTableShapeImportHelper::SetLayer(uno::Reference<drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const
+{
+ if (sType.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ControlShape"))))
+ nLayerID = SC_LAYER_CONTROLS;
+ if (nLayerID != -1)
+ {
+ uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY );
+ if( xShapeProp.is() )
+ xShapeProp->setPropertyValue(OUString( RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ) ), uno::makeAny(nLayerID) );
+ }
+}
+
+void XMLTableShapeImportHelper::finishShape(
+ uno::Reference< drawing::XShape >& rShape,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList,
+ uno::Reference< drawing::XShapes >& rShapes )
+{
+ bool bNote = false;
+ XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
+ static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
+ ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
+ if (rShapes == rTables.GetCurrentXShapes())
+ {
+ if (!pAnnotationContext)
+ {
+ sal_Int32 nEndX(-1);
+ sal_Int32 nEndY(-1);
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ table::CellAddress aEndCell;
+ rtl::OUString* pRangeList(NULL);
+ sal_Int16 nLayerID(-1);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(
+ static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName,
+ &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_END_CELL_ADDRESS))
+ {
+ sal_Int32 nOffset(0);
+ ScRangeStringConverter::GetAddressFromString(aEndCell, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset);
+ }
+ else if (IsXMLToken(aLocalName, XML_END_X))
+ static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndX, rValue);
+ else if (IsXMLToken(aLocalName, XML_END_Y))
+ static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndY, rValue);
+ else if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
+ if (IsXMLToken(rValue, XML_TRUE))
+ nLayerID = SC_LAYER_BACK;
+ }
+ else if(nPrefix == XML_NAMESPACE_DRAW)
+ {
+ if (IsXMLToken(aLocalName, XML_NOTIFY_ON_UPDATE_OF_RANGES))
+ pRangeList = new rtl::OUString(rValue);
+ }
+ }
+ SetLayer(rShape, nLayerID, rShape->getShapeType());
+
+ if (!bOnTable)
+ {
+ rTables.AddShape(rShape,
+ pRangeList, aStartCell, aEndCell, nEndX, nEndY);
+ SvxShape* pShapeImp = SvxShape::getImplementation(rShape);
+ if (pShapeImp)
+ {
+ SdrObject *pSdrObj = pShapeImp->GetSdrObject();
+ if (pSdrObj)
+ ScDrawLayer::SetAnchor(pSdrObj, SCA_CELL);
+ }
+ }
+ else
+ {
+ if ( pRangeList )
+ {
+ // #i78086# If there are notification ranges, the ChartListener must be created
+ // also when anchored to the sheet
+ // -> call AddShape with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
+
+ table::CellAddress aInvalidPos( -1, -1, -1 );
+ rTables.AddShape(rShape,
+ pRangeList, aInvalidPos, aInvalidPos, 0, 0);
+ }
+
+ SvxShape* pShapeImp = SvxShape::getImplementation(rShape);
+ if (pShapeImp)
+ {
+ SdrObject *pSdrObj = pShapeImp->GetSdrObject();
+ if (pSdrObj)
+ ScDrawLayer::SetAnchor(pSdrObj, SCA_PAGE);
+ }
+ }
+ }
+ else // shape is annotation
+ {
+ // get the style names for stream copying
+ rtl::OUString aStyleName;
+ rtl::OUString aTextStyle;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_DRAW)
+ {
+ if (IsXMLToken(aLocalName, XML_STYLE_NAME))
+ aStyleName = xAttrList->getValueByIndex( i );
+ else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME))
+ aTextStyle = xAttrList->getValueByIndex( i );
+ }
+ }
+
+ pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
+ bNote = true;
+ }
+ }
+ else //#99532# this are grouped shapes which should also get the layerid
+ {
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ sal_Int16 nLayerID(-1);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
+ if (IsXMLToken(rValue, XML_TRUE))
+ nLayerID = SC_LAYER_BACK;
+ }
+ }
+ SetLayer(rShape, nLayerID, rShape->getShapeType());
+ }
+
+ if (!bNote)
+ {
+ // any shape other than a note prevents copying the sheet
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData();
+ pSheetData->BlockSheet( rTables.GetCurrentSheet() );
+ }
+
+ static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
+}
diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.hxx b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
new file mode 100644
index 000000000000..94a64312c8ed
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESHAPEIMPORTHELPER_HXX
+#define SC_XMLTABLESHAPEIMPORTHELPER_HXX
+
+#include <xmloff/shapeimport.hxx>
+#include <com/sun/star/table/CellAddress.hpp>
+
+class ScXMLImport;
+class ScXMLAnnotationContext;
+
+class XMLTableShapeImportHelper : public XMLShapeImportHelper
+{
+ ::com::sun::star::table::CellAddress aStartCell;
+ ScXMLAnnotationContext* pAnnotationContext;
+ sal_Bool bOnTable;
+
+public:
+
+ XMLTableShapeImportHelper( ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper=0 );
+ ~XMLTableShapeImportHelper();
+
+ void SetLayer(com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const;
+ virtual void finishShape(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList,
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes);
+
+
+ void SetCell (const ::com::sun::star::table::CellAddress& rAddress) { aStartCell = rAddress; }
+ void SetOnTable (const sal_Bool bTempOnTable) { bOnTable = bTempOnTable; }
+ void SetAnnotation(ScXMLAnnotationContext* pAnnotation) { pAnnotationContext = pAnnotation; }
+
+ ScXMLAnnotationContext* GetAnnotationContext() const { return pAnnotationContext; }
+};
+
+
+#endif
diff --git a/sc/source/filter/xml/XMLTableShapeResizer.cxx b/sc/source/filter/xml/XMLTableShapeResizer.cxx
new file mode 100644
index 000000000000..415057c219f2
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeResizer.cxx
@@ -0,0 +1,385 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLTableShapeResizer.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+#include "xmlimprt.hxx"
+#include "chartlis.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+#include "reftokenhelper.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <memory>
+#include <vector>
+
+using namespace ::com::sun::star;
+using ::std::auto_ptr;
+using ::std::vector;
+using ::rtl::OUString;
+
+ScMyShapeResizer::ScMyShapeResizer(ScXMLImport& rTempImport)
+ : rImport(rTempImport),
+ aShapes(),
+ pCollection(NULL)
+{
+}
+
+ScMyShapeResizer::~ScMyShapeResizer()
+{
+}
+
+sal_Bool ScMyShapeResizer::IsOLE(uno::Reference< drawing::XShape >& rShape) const
+{
+ return rShape->getShapeType().equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.OLE2Shape")));
+}
+
+void ScMyShapeResizer::CreateChartListener(ScDocument* pDoc,
+ const rtl::OUString& rName,
+ const rtl::OUString* pRangeList)
+{
+ if (!pDoc || !pRangeList)
+ // These are minimum required.
+ return;
+
+ if (!pRangeList->getLength())
+ {
+ pDoc->AddOLEObjectToCollection(rName);
+ return;
+ }
+
+ OUString aRangeStr;
+ ScRangeStringConverter::GetStringFromXMLRangeString(aRangeStr, *pRangeList, pDoc);
+ if (!aRangeStr.getLength())
+ {
+ pDoc->AddOLEObjectToCollection(rName);
+ return;
+ }
+
+ if (!pCollection)
+ pCollection = pDoc->GetChartListenerCollection();
+
+ if (!pCollection)
+ return;
+
+ auto_ptr< vector<ScSharedTokenRef> > pRefTokens(new vector<ScSharedTokenRef>);
+ ScRefTokenHelper::compileRangeRepresentation(*pRefTokens, aRangeStr, pDoc);
+ if (!pRefTokens->empty())
+ {
+ ScChartListener* pCL(new ScChartListener(rName, pDoc, pRefTokens.release()));
+
+ //for loading binary files e.g.
+ //if we have the flat filter we need to set the dirty flag thus the visible charts get repainted
+ //otherwise the charts keep their first visual representation which was created at a moment where the calc itself was not loaded completly and is incorect therefor
+ if( (rImport.getImportFlags() & IMPORT_ALL) == IMPORT_ALL )
+ pCL->SetDirty( TRUE );
+ else
+ {
+ // #i104899# If a formula cell is already dirty, further changes aren't propagated.
+ // This can happen easily now that row heights aren't updated for all sheets.
+ pDoc->InterpretDirtyCells( *pCL->GetRangeList() );
+ }
+
+ pCollection->Insert( pCL );
+ pCL->StartListeningTo();
+ }
+}
+
+void ScMyShapeResizer::AddShape(uno::Reference <drawing::XShape>& rShape,
+ rtl::OUString* pRangeList,
+ table::CellAddress& rStartAddress, table::CellAddress& rEndAddress,
+ sal_Int32 nEndX, sal_Int32 nEndY)
+{
+ ScMyToResizeShape aShape;
+ aShape.xShape.set(rShape);
+ aShape.pRangeList = pRangeList;
+ aShape.aEndCell = rEndAddress;
+ aShape.aStartCell = rStartAddress;
+ aShape.nEndY = nEndY;
+ aShape.nEndX = nEndX;
+ aShapes.push_back(aShape);
+}
+
+void ScMyShapeResizer::GetNewShapeSizePos(ScDocument* pDoc, const Rectangle& rStartRect,
+ const table::CellAddress& rEndCell,
+ awt::Point& rPoint, awt::Size& rSize,
+ sal_Int32& rEndX, sal_Int32& rEndY) const
+{
+ awt::Point aRefPoint;
+ BOOL bNegativePage(pDoc->IsNegativePage(rEndCell.Sheet));
+ if (bNegativePage)
+ aRefPoint.X = rStartRect.Right();
+ else
+ aRefPoint.X = rStartRect.Left();
+ aRefPoint.Y = rStartRect.Top();
+ Rectangle aRect(pDoc->GetMMRect(
+ static_cast<SCCOL>(rEndCell.Column), static_cast<SCROW>(rEndCell.Row),
+ static_cast<SCCOL>(rEndCell.Column), static_cast<SCROW>(rEndCell.Row), rEndCell.Sheet ));
+ if (bNegativePage)
+ rEndX = -rEndX + aRect.Right();
+ else
+ rEndX += aRect.Left();
+ rEndY += aRect.Top();
+ rPoint.X += aRefPoint.X;
+ if (bNegativePage)
+ {
+ if (rPoint.X < rStartRect.Left())
+ rPoint.X = rStartRect.Left() + 2; // increment by 2 100th_mm because the cellwidth is internal in twips
+ }
+ else
+ {
+ if (rPoint.X > rStartRect.Right())
+ rPoint.X = rStartRect.Right() - 2; // decrement by 2 100th_mm because the cellwidth is internal in twips
+ }
+ rPoint.Y += aRefPoint.Y;
+ if (rPoint.Y > rStartRect.Bottom())
+ rPoint.Y = rStartRect.Bottom() - 2; // decrement by 2 100th_mm because the cellheight is internal in twips
+ if (bNegativePage)
+ {
+ rSize.Width = -(rEndX - rPoint.X);
+ }
+ else
+ rSize.Width = rEndX - rPoint.X;
+ rSize.Height = rEndY - rPoint.Y;
+}
+
+void ScMyShapeResizer::ResizeShapes()
+{
+ if (!aShapes.empty() && rImport.GetModel().is())
+ {
+ rtl::OUString sRowHeight(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLHGT));
+ rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName"));
+ rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
+ rtl::OUString sConnectorShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ConnectorShape") );
+ rtl::OUString sCaptionShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape") );
+ rtl::OUString sStartShape(RTL_CONSTASCII_USTRINGPARAM("StartShape"));
+ rtl::OUString sEndShape(RTL_CONSTASCII_USTRINGPARAM("EndShape"));
+ rtl::OUString sStartPosition(RTL_CONSTASCII_USTRINGPARAM("StartPosition"));
+ rtl::OUString sEndPosition(RTL_CONSTASCII_USTRINGPARAM("EndPosition"));
+ uno::Reference<table::XCellRange> xTableRow;
+ uno::Reference<sheet::XSpreadsheet> xSheet;
+ uno::Reference<table::XTableRows> xTableRows;
+ sal_Int32 nOldRow(-1);
+ sal_Int32 nOldSheet(-1);
+ ScMyToResizeShapes::iterator aItr(aShapes.begin());
+ ScMyToResizeShapes::iterator aEndItr(aShapes.end());
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ ScDocument* pDoc(rImport.GetDocument());
+ if ( pDoc && xIndex.is() )
+ {
+ rImport.LockSolarMutex();
+ while (aItr != aEndItr)
+ {
+ // #i78086# invalid cell position is used to call CreateChartListener only
+ if ( aItr->aEndCell.Sheet >= 0 )
+ {
+ if ((nOldSheet != aItr->aEndCell.Sheet) || !xSheet.is())
+ {
+ nOldSheet = aItr->aEndCell.Sheet;
+ xSheet.set(xIndex->getByIndex(nOldSheet), uno::UNO_QUERY);
+ if (xSheet.is())
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet, uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ xTableRows = xColumnRowRange->getRows();
+ }
+ }
+ if (xTableRows.is())
+ {
+ if (nOldRow != aItr->aEndCell.Row || !xTableRow.is())
+ {
+ nOldRow = aItr->aEndCell.Row;
+ xTableRows->getByIndex(nOldRow) >>= xTableRow;
+ }
+ if (xTableRow.is())
+ {
+ uno::Reference <beans::XPropertySet> xRowProperties(xTableRow, uno::UNO_QUERY);
+ if (xRowProperties.is())
+ {
+ sal_Int32 nHeight;
+ if (xRowProperties->getPropertyValue(sRowHeight) >>= nHeight)
+ {
+ Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(aItr->aStartCell.Column), static_cast<SCROW>(aItr->aStartCell.Row),
+ static_cast<SCCOL>(aItr->aStartCell.Column), static_cast<SCROW>(aItr->aStartCell.Row), aItr->aStartCell.Sheet);
+ awt::Point aPoint(aItr->xShape->getPosition());
+ awt::Size aSize(aItr->xShape->getSize());
+ if (pDoc->IsNegativePage(static_cast<SCTAB>(nOldSheet)))
+ aPoint.X += aSize.Width;
+ if (aItr->nEndY >= 0 && aItr->nEndX >= 0)
+ {
+ if (aItr->xShape->getShapeType().equals(sConnectorShape))
+ {
+ //#103122#; handle connected Connectorshapes
+ uno::Reference<beans::XPropertySet> xShapeProps (aItr->xShape, uno::UNO_QUERY);
+ if(xShapeProps.is())
+ {
+ uno::Reference<drawing::XShape> xStartShape(xShapeProps->getPropertyValue( sStartShape ), uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xEndShape(xShapeProps->getPropertyValue( sEndShape ), uno::UNO_QUERY);
+ if (!xStartShape.is() && !xEndShape.is())
+ {
+ awt::Size aOldSize(aSize);
+ GetNewShapeSizePos(pDoc, aRec, aItr->aEndCell, aPoint, aSize, aItr->nEndX, aItr->nEndY);
+ aItr->xShape->setPosition(aPoint);
+ if( (aSize.Width != aOldSize.Width) ||
+ (aSize.Height != aOldSize.Height) )
+ aItr->xShape->setSize(aSize);
+ }
+ else if (xStartShape.is() && xEndShape.is())
+ {
+ // do nothing, because they are connected
+ }
+ else
+ {
+ // only one point is connected, the other should be moved
+
+ rtl::OUString sProperty;
+ if (xStartShape.is())
+ {
+ awt::Point aEndPoint;
+ xShapeProps->getPropertyValue(sEndPosition) >>= aEndPoint;
+ aPoint.X = aRec.Left() + aEndPoint.X;
+ aPoint.Y = aRec.Top() + aEndPoint.Y;
+ sProperty = sEndPosition;
+ }
+ else
+ {
+ awt::Point aStartPoint;
+ xShapeProps->getPropertyValue(sStartPosition) >>= aStartPoint;
+ aPoint.X = aRec.Left() + aStartPoint.X;
+ aPoint.Y = aRec.Top() + aStartPoint.Y;
+ sProperty = sStartPosition;
+ }
+ xShapeProps->setPropertyValue(sProperty, uno::makeAny(aPoint));
+ }
+ }
+ }
+ else
+ {
+ awt::Size aOldSize(aSize);
+ GetNewShapeSizePos(pDoc, aRec, aItr->aEndCell, aPoint, aSize, aItr->nEndX, aItr->nEndY);
+ if (pDoc->IsNegativePage(static_cast<SCTAB>(nOldSheet)))
+ aPoint.X -= aSize.Width;
+ aItr->xShape->setPosition(aPoint);
+ if( (aSize.Width != aOldSize.Width) ||
+ (aSize.Height != aOldSize.Height) )
+ aItr->xShape->setSize(aSize);
+ }
+ }
+ else
+ {
+ if (aItr->xShape->getShapeType().equals(sCaptionShape))
+ {
+ Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
+
+ awt::Point aCaptionPoint;
+ uno::Reference< beans::XPropertySet > xShapeProps(aItr->xShape, uno::UNO_QUERY);
+ if (xShapeProps.is())
+ {
+ try
+ {
+ xShapeProps->getPropertyValue( sCaptionPoint ) >>= aCaptionPoint;
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("This Captionshape has no CaptionPoint property.");
+ }
+ }
+ Point aCorePoint(aPoint.X, aPoint.Y);
+ Point aCoreCaptionPoint(aCaptionPoint.X, aCaptionPoint.Y);
+ aCoreCaptionPoint += aCorePoint;
+ aRectangle.Union(Rectangle(aCoreCaptionPoint, aCoreCaptionPoint));
+
+ Point aBeforeRightBottomPoint(aRectangle.BottomRight());
+
+ aRectangle += aRec.TopLeft();
+ if (aRectangle.Left() > aRec.Right())
+ aRectangle -= (Point(aRectangle.Left() - aRec.Right() + 2, 0));
+ if (aRectangle.Top() > aRec.Bottom())
+ aRectangle -= (Point(0, aRectangle.Top() - aRec.Bottom() + 2));
+
+ Point aDifferencePoint(aRectangle.BottomRight() - aBeforeRightBottomPoint);
+ aPoint.X += aDifferencePoint.X();
+ aPoint.Y += aDifferencePoint.Y();
+
+ aItr->xShape->setPosition(aPoint);
+ }
+ else
+ {
+ // #96159# it is possible, that shapes have a negative position
+ // this is now handled here
+ DBG_ERROR("no or negative end address of this shape");
+ awt::Point aRefPoint;
+ aRefPoint.X = aRec.Left();
+ aRefPoint.Y = aRec.Top();
+ aPoint.X += aRefPoint.X;
+ if (aPoint.X > aRec.Right())
+ aPoint.X = aRec.Right() - 2; // decrement by 2 100th_mm because the cellheight is internal in twips
+ aPoint.Y += aRefPoint.Y;
+ if (aPoint.Y > aRec.Bottom())
+ aPoint.Y = aRec.Bottom() - 2; // decrement by 2 100th_mm because the cellheight is internal in twips
+ aItr->xShape->setPosition(aPoint);
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("something wents wrong");
+ }
+ }
+ // #i78086# call CreateChartListener also for invalid position (anchored to sheet)
+ if (IsOLE(aItr->xShape))
+ {
+ uno::Reference < beans::XPropertySet > xShapeProps ( aItr->xShape, uno::UNO_QUERY );
+ uno::Reference < beans::XPropertySetInfo > xShapeInfo(xShapeProps->getPropertySetInfo());
+ rtl::OUString sName;
+ if (xShapeProps.is() && xShapeInfo.is() && xShapeInfo->hasPropertyByName(sPersistName) &&
+ (xShapeProps->getPropertyValue(sPersistName) >>= sName))
+ CreateChartListener(pDoc, sName, aItr->pRangeList);
+ }
+ if (aItr->pRangeList)
+ delete aItr->pRangeList;
+ aItr = aShapes.erase(aItr);
+ }
+ rImport.UnlockSolarMutex();
+// if (pCollection)
+// pDoc->SetChartListenerCollection(pCollection);
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/XMLTableShapeResizer.hxx b/sc/source/filter/xml/XMLTableShapeResizer.hxx
new file mode 100644
index 000000000000..9ece92995101
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeResizer.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESHAPERESIZER_HXX
+#define SC_XMLTABLESHAPERESIZER_HXX
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <list>
+
+class ScXMLImport;
+class ScChartListenerCollection;
+class ScDocument;
+class Rectangle;
+
+struct ScMyToResizeShape
+{
+ com::sun::star::uno::Reference <com::sun::star::drawing::XShape> xShape;
+ rtl::OUString* pRangeList;
+ com::sun::star::table::CellAddress aEndCell;
+ com::sun::star::table::CellAddress aStartCell;
+ sal_Int32 nEndX;
+ sal_Int32 nEndY;
+
+ ScMyToResizeShape() : pRangeList(NULL) {}
+};
+
+typedef std::list<ScMyToResizeShape> ScMyToResizeShapes;
+
+class ScMyShapeResizer
+{
+ ScXMLImport& rImport;
+ ScMyToResizeShapes aShapes;
+ ScChartListenerCollection* pCollection;
+
+ sal_Bool IsOLE(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape) const;
+ void CreateChartListener(ScDocument* pDoc,
+ const rtl::OUString& rName,
+ const rtl::OUString* pRangeList);
+ void GetNewShapeSizePos(ScDocument* pDoc, const Rectangle& rStartRect,
+ const com::sun::star::table::CellAddress& rEndCell,
+ com::sun::star::awt::Point& rPoint, com::sun::star::awt::Size& rSize,
+ sal_Int32& rEndX, sal_Int32& rEndY) const;
+public:
+ ScMyShapeResizer(ScXMLImport& rImport);
+ ~ScMyShapeResizer();
+
+ void AddShape(com::sun::star::uno::Reference <com::sun::star::drawing::XShape>& rShape,
+ rtl::OUString* pRangeList,
+ com::sun::star::table::CellAddress& rStartAddress,
+ com::sun::star::table::CellAddress& rEndAddress,
+ sal_Int32 nEndX, sal_Int32 nEndY);
+ void ResizeShapes();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLTableShapesContext.cxx b/sc/source/filter/xml/XMLTableShapesContext.cxx
new file mode 100644
index 000000000000..d841e1c4c748
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapesContext.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLTableShapesContext.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+ScXMLTableShapesContext::ScXMLTableShapesContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // here are no attributes
+}
+
+ScXMLTableShapesContext::~ScXMLTableShapesContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableShapesContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (!pContext)
+ {
+ ScXMLImport& rXMLImport(GetScImport());
+ uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
+ if (xShapes.is())
+ {
+ XMLTableShapeImportHelper* pTableShapeImport((XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get());
+ pTableShapeImport->SetOnTable(sal_True);
+ pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
+ rXMLImport, nPrefix, rLName, xAttrList, xShapes);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableShapesContext::EndElement()
+{
+}
+
diff --git a/sc/source/filter/xml/XMLTableShapesContext.hxx b/sc/source/filter/xml/XMLTableShapesContext.hxx
new file mode 100644
index 000000000000..f12cb56d30da
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapesContext.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESHAPESCONTEXT_HXX
+#define SC_XMLTABLESHAPESCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+class ScXMLImport;
+
+class ScXMLTableShapesContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLTableShapesContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLTableShapesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLTableSourceContext.cxx b/sc/source/filter/xml/XMLTableSourceContext.cxx
new file mode 100644
index 000000000000..00f5c9184a53
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableSourceContext.cxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLTableSourceContext.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "xmlsubti.hxx"
+#include "tablink.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableSourceContext::ScXMLTableSourceContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sLink(),
+ sTableName(),
+ sFilterName(),
+ sFilterOptions(),
+ nRefresh(0),
+ nMode(sheet::SheetLinkMode_NORMAL)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+ if(nPrefix == XML_NAMESPACE_XLINK)
+ {
+ if (IsXMLToken(aLocalName, XML_HREF))
+ sLink = GetScImport().GetAbsoluteReference(sValue);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_TABLE_NAME))
+ sTableName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_NAME))
+ sFilterName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS))
+ sFilterOptions = sValue;
+ else if (IsXMLToken(aLocalName, XML_MODE))
+ {
+ if (IsXMLToken(sValue, XML_COPY_RESULTS_ONLY))
+ nMode = sheet::SheetLinkMode_VALUE;
+ }
+ else if (IsXMLToken(aLocalName, XML_REFRESH_DELAY))
+ {
+ double fTime;
+ if( SvXMLUnitConverter::convertTime( fTime, sValue ) )
+ nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 );
+ }
+ }
+ }
+}
+
+ScXMLTableSourceContext::~ScXMLTableSourceContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableSourceContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLTableSourceContext::EndElement()
+{
+ if (sLink.getLength())
+ {
+ uno::Reference <sheet::XSheetLinkable> xLinkable (GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (xLinkable.is() && pDoc)
+ {
+ GetScImport().LockSolarMutex();
+ if (pDoc->RenameTab( static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()),
+ GetScImport().GetTables().GetCurrentSheetName(), sal_False, sal_True))
+ {
+ String aFileString(sLink);
+ String aFilterString(sFilterName);
+ String aOptString(sFilterOptions);
+ String aSheetString(sTableName);
+
+ aFileString = ScGlobal::GetAbsDocName( aFileString, pDoc->GetDocumentShell() );
+ if ( !aFilterString.Len() )
+ ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, FALSE, FALSE );
+
+ BYTE nLinkMode = SC_LINK_NONE;
+ if ( nMode == sheet::SheetLinkMode_NORMAL )
+ nLinkMode = SC_LINK_NORMAL;
+ else if ( nMode == sheet::SheetLinkMode_VALUE )
+ nLinkMode = SC_LINK_VALUE;
+
+ pDoc->SetLink( static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()),
+ nLinkMode, aFileString, aFilterString, aOptString,
+ aSheetString, nRefresh );
+ }
+ GetScImport().UnlockSolarMutex();
+ }
+ }
+}
+
diff --git a/sc/source/filter/xml/XMLTableSourceContext.hxx b/sc/source/filter/xml/XMLTableSourceContext.hxx
new file mode 100644
index 000000000000..2d72a4a3364c
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableSourceContext.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESOURCECONTEXT_HXX
+#define SC_XMLTABLESOURCECONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/sheet/SheetLinkMode.hpp>
+
+class ScXMLImport;
+
+class ScXMLTableSourceContext : public SvXMLImportContext
+{
+ rtl::OUString sLink;
+ rtl::OUString sTableName;
+ rtl::OUString sFilterName;
+ rtl::OUString sFilterOptions;
+ sal_Int32 nRefresh;
+ com::sun::star::sheet::SheetLinkMode nMode;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLTableSourceContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLTableSourceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLTextPContext.cxx b/sc/source/filter/xml/XMLTextPContext.cxx
new file mode 100644
index 000000000000..d6d02567b9bd
--- /dev/null
+++ b/sc/source/filter/xml/XMLTextPContext.cxx
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLTextPContext.hxx"
+#include "xmlimprt.hxx"
+#include "xmlcelli.hxx"
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/text/XTextCursor.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+class ScXMLTextTContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLTextTContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLTextPContext* pTextPContext);
+
+ virtual ~ScXMLTextTContext();
+};
+
+
+ScXMLTextTContext::ScXMLTextTContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLTextPContext* pTextPContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ if (pTextPContext)
+ {
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ rtl::OUString aLocalName;
+ sal_Int32 nCount(1);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex( i ), &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(aLocalName, XML_C))
+ nCount = sValue.toInt32();
+ }
+ pTextPContext->AddSpaces(nCount);
+ }
+}
+
+ScXMLTextTContext::~ScXMLTextTContext()
+{
+}
+
+//------------------------------------------------------------------
+
+ScXMLTextPContext::ScXMLTextPContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList,
+ ScXMLTableRowCellContext* pTempCellContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xAttrList(xTempAttrList),
+ pTextPContext(NULL),
+ pCellContext(pTempCellContext),
+ sLName(rLName),
+ sSimpleContent(),
+ pContentBuffer(NULL),
+ nPrefix(nPrfx),
+ bIsOwn(sal_True)
+{
+ // here are no attributes
+}
+
+ScXMLTextPContext::~ScXMLTextPContext()
+{
+ if (pTextPContext)
+ delete pTextPContext;
+ if (pContentBuffer)
+ delete pContentBuffer;
+}
+
+void ScXMLTextPContext::AddSpaces(sal_Int32 nSpaceCount)
+{
+ // use pContentBuffer
+ if ( !pContentBuffer )
+ pContentBuffer = new rtl::OUStringBuffer( sSimpleContent );
+
+ sal_Char* pChars = new sal_Char[nSpaceCount];
+ memset(pChars, ' ', nSpaceCount);
+ pContentBuffer->appendAscii(pChars, nSpaceCount);
+}
+
+SvXMLImportContext *ScXMLTextPContext::CreateChildContext( USHORT nTempPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList )
+{
+ SvXMLImportContext *pContext(NULL);
+ if (!pTextPContext &&
+ (nTempPrefix == XML_NAMESPACE_TEXT) &&
+ IsXMLToken(rLName, XML_S))
+ pContext = new ScXMLTextTContext( GetScImport(), nTempPrefix, rLName, xTempAttrList, this);
+ else
+ {
+ if (!pTextPContext)
+ {
+ rtl::OUString sSetString;
+ if ( pContentBuffer )
+ sSetString = pContentBuffer->makeStringAndClear();
+ else
+ sSetString = sSimpleContent;
+
+ sal_Unicode cNonSpace(0);
+
+ sal_Int32 nLength = sSetString.getLength();
+ if ( nLength > 0 )
+ {
+ sal_Unicode cLast = sSetString.getStr()[ nLength - 1 ];
+ if ( cLast != (sal_Unicode)' ' )
+ {
+ // #i53253# To keep XMLParaContext's whitespace handling in sync,
+ // if there's a non-space character at the end of the existing string,
+ // it has to be processed by XMLParaContext.
+
+ cNonSpace = cLast;
+ sSetString = sSetString.copy( 0, nLength - 1 ); // remove from the string for SetCursorOnTextImport
+ }
+ }
+
+ pCellContext->SetCursorOnTextImport( sSetString );
+
+ pTextPContext = GetScImport().GetTextImport()->CreateTextChildContext(
+ GetScImport(), nPrefix, sLName, xAttrList);
+
+ if ( cNonSpace != 0 )
+ {
+ // pass non-space character through XMLParaContext, so a following space isn't ignored
+ pTextPContext->Characters( rtl::OUString( cNonSpace ) );
+ }
+ }
+ if (pTextPContext)
+ pContext = pTextPContext->CreateChildContext(nTempPrefix, rLName, xTempAttrList);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetScImport(), nTempPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTextPContext::Characters( const ::rtl::OUString& rChars )
+{
+ if (!pTextPContext)
+ {
+ // For the first call to an empty context, copy (ref-counted) the OUString.
+ // The OUStringBuffer is used only if there is more complex content.
+
+ if ( !pContentBuffer && sSimpleContent.getLength() == 0 )
+ sSimpleContent = rChars;
+ else
+ {
+ if ( !pContentBuffer )
+ pContentBuffer = new rtl::OUStringBuffer( sSimpleContent );
+ pContentBuffer->append(rChars);
+ }
+ }
+ else
+ pTextPContext->Characters(rChars);
+}
+
+void ScXMLTextPContext::EndElement()
+{
+ if (!pTextPContext)
+ {
+ if ( pContentBuffer )
+ pCellContext->SetString(pContentBuffer->makeStringAndClear());
+ else
+ pCellContext->SetString(sSimpleContent);
+ }
+ else
+ {
+ pTextPContext->EndElement();
+ GetScImport().SetRemoveLastChar(sal_True);
+ }
+}
+
diff --git a/sc/source/filter/xml/XMLTextPContext.hxx b/sc/source/filter/xml/XMLTextPContext.hxx
new file mode 100644
index 000000000000..a920e13f84a3
--- /dev/null
+++ b/sc/source/filter/xml/XMLTextPContext.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTEXTPCONTEXT_HXX
+#define SC_XMLTEXTPCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+class ScXMLTableRowCellContext;
+
+class ScXMLTextPContext : public SvXMLImportContext
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList> xAttrList;
+ SvXMLImportContext* pTextPContext;
+ ScXMLTableRowCellContext* pCellContext;
+ rtl::OUString sLName;
+ rtl::OUString sSimpleContent; // copy of the first Character call's argument
+ rtl::OUStringBuffer* pContentBuffer; // used if there's more than one string
+ USHORT nPrefix;
+ sal_Bool bIsOwn;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLTextPContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLTableRowCellContext* pCellContext);
+
+ virtual ~ScXMLTextPContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+
+ void AddSpaces(sal_Int32 nSpaceCount);
+};
+
+#endif
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.cxx b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
new file mode 100644
index 000000000000..cf415142213a
--- /dev/null
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
@@ -0,0 +1,2025 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "XMLTrackedChangesContext.hxx"
+#include "xmlimprt.hxx"
+#include "xmlconti.hxx"
+#include "XMLConverter.hxx"
+#include "cell.hxx"
+#include "textuno.hxx"
+#include "editutil.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <svl/zforlist.hxx>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+
+using rtl::OUString;
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeInfoContext : public SvXMLImportContext
+{
+ ScMyActionInfo aInfo;
+ ::rtl::OUStringBuffer sAuthorBuffer;
+ ::rtl::OUStringBuffer sDateTimeBuffer;
+ ::rtl::OUStringBuffer sCommentBuffer;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ sal_uInt32 nParagraphCount;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLChangeInfoContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLChangeInfoContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLBigRangeContext : public SvXMLImportContext
+{
+ ScBigRange& rBigRange;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLBigRangeContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScBigRange& rBigRange);
+ virtual ~ScXMLBigRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLCellContentDeletionContext : public SvXMLImportContext
+{
+ rtl::OUString sFormulaAddress;
+ rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
+ rtl::OUString sInputString;
+ ScBigRange aBigRange;
+ double fValue;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScBaseCell* pCell;
+ sal_uInt32 nID;
+ sal_Int32 nMatrixCols;
+ sal_Int32 nMatrixRows;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_uInt16 nType;
+ sal_uInt8 nMatrixFlag;
+ sal_Bool bBigRange;
+ sal_Bool bContainsCell;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLCellContentDeletionContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLCellContentDeletionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDependenceContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDependenceContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDependenceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDependingsContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDependingsContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDependingsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeDeletionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLChangeDeletionContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLChangeDeletionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDeletionsContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDeletionsContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDeletionsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeCellContext;
+
+class ScXMLChangeTextPContext : public SvXMLImportContext
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList> xAttrList;
+ rtl::OUString sLName;
+ rtl::OUStringBuffer sText;
+ ScXMLChangeCellContext* pChangeCellContext;
+ SvXMLImportContext* pTextPContext;
+ USHORT nPrefix;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLChangeTextPContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeCellContext* pChangeCellContext);
+
+ virtual ~ScXMLChangeTextPContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeCellContext : public SvXMLImportContext
+{
+ rtl::OUString sText;
+ rtl::OUString& rInputString;
+ ScBaseCell*& rOldCell;
+ ScEditEngineTextObj* pEditTextObj;
+ double& rDateTimeValue;
+ double fValue;
+ sal_uInt16& rType;
+// sal_Bool bIsMatrix;
+// sal_Bool bIsCoveredMatrix;
+ sal_Bool bEmpty;
+ sal_Bool bFirstParagraph;
+ sal_Bool bString;
+ sal_Bool bFormula;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLChangeCellContext( ScXMLImport& rImport, 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& rFormula, rtl::OUString& rFormulaNmsp,
+ formula::FormulaGrammar::Grammar& rGrammar,
+ rtl::OUString& rInputString, double& fValue, sal_uInt16& nType,
+ sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows);
+ virtual ~ScXMLChangeCellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void CreateTextPContext(sal_Bool bIsNewParagraph);
+ sal_Bool IsEditCell() { return pEditTextObj != 0; }
+ void SetText(const rtl::OUString& sTempText) { sText = sTempText; }
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLPreviousContext : public SvXMLImportContext
+{
+ rtl::OUString sFormulaAddress;
+ rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
+ rtl::OUString sInputString;
+ double fValue;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScBaseCell* pOldCell;
+ sal_uInt32 nID;
+ sal_Int32 nMatrixCols;
+ sal_Int32 nMatrixRows;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_uInt16 nType;
+ sal_uInt8 nMatrixFlag;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLPreviousContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLPreviousContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLContentChangeContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScBigRange aBigRange;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLContentChangeContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLContentChangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLInsertionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLInsertionContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLInsertionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLInsertionCutOffContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLInsertionCutOffContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLInsertionCutOffContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLMovementCutOffContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLMovementCutOffContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLMovementCutOffContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLCutOffsContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLCutOffsContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLCutOffsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDeletionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDeletionContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDeletionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLMovementContext : public SvXMLImportContext
+{
+ ScBigRange aSourceRange;
+ ScBigRange aTargetRange;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLMovementContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLMovementContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLRejectionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLRejectionContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLRejectionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//------------------------------------------------------------------
+
+ScXMLTrackedChangesContext::ScXMLTrackedChangesContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ rImport.LockSolarMutex();
+ pChangeTrackingImportHelper->SetChangeTrack(sal_True);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_PROTECTION_KEY))
+ {
+ if (sValue.getLength())
+ {
+ uno::Sequence<sal_Int8> aPass;
+ SvXMLUnitConverter::decodeBase64(aPass, sValue);
+ pChangeTrackingImportHelper->SetProtection(aPass);
+ }
+ }
+ }
+ }
+}
+
+ScXMLTrackedChangesContext::~ScXMLTrackedChangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLTrackedChangesContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CELL_CONTENT_CHANGE))
+ {
+ pContext = new ScXMLContentChangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_INSERTION))
+ {
+ pContext = new ScXMLInsertionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_DELETION))
+ {
+ pContext = new ScXMLDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_MOVEMENT))
+ {
+ pContext = new ScXMLMovementContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_REJECTION))
+ {
+ pContext = new ScXMLRejectionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLTrackedChangesContext::EndElement()
+{
+}
+
+ScXMLChangeInfoContext::ScXMLChangeInfoContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aInfo(),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
+ nParagraphCount(0)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_CHG_AUTHOR))
+ {
+ sAuthorBuffer = sValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_CHG_DATE_TIME))
+ {
+ sDateTimeBuffer = sValue;
+ }
+ }
+ }
+}
+
+ScXMLChangeInfoContext::~ScXMLChangeInfoContext()
+{
+}
+
+SvXMLImportContext *ScXMLChangeInfoContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if( XML_NAMESPACE_DC == nPrefix )
+ {
+ if( IsXMLToken( rLocalName, XML_CREATOR ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLocalName, xAttrList, sAuthorBuffer);
+ else if( IsXMLToken( rLocalName, XML_DATE ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLocalName, xAttrList, sDateTimeBuffer);
+ }
+ else if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLocalName, XML_P)) )
+ {
+ if(nParagraphCount)
+ sCommentBuffer.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLocalName, xAttrList, sCommentBuffer);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLChangeInfoContext::EndElement()
+{
+ aInfo.sUser = sAuthorBuffer.makeStringAndClear();
+ GetScImport().GetMM100UnitConverter().convertDateTime(aInfo.aDateTime, sDateTimeBuffer.makeStringAndClear());
+ aInfo.sComment = sCommentBuffer.makeStringAndClear();
+ pChangeTrackingImportHelper->SetActionInfo(aInfo);
+}
+
+ScXMLBigRangeContext::ScXMLBigRangeContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScBigRange& rTempBigRange ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ rBigRange(rTempBigRange)
+{
+ sal_Bool bColumn(sal_False);
+ sal_Bool bRow(sal_False);
+ sal_Bool bTable(sal_False);
+ sal_Int32 nColumn(0);
+ sal_Int32 nRow(0);
+ sal_Int32 nTable(0);
+ sal_Int32 nStartColumn(0);
+ sal_Int32 nEndColumn(0);
+ sal_Int32 nStartRow(0);
+ sal_Int32 nEndRow(0);
+ sal_Int32 nStartTable(0);
+ sal_Int32 nEndTable(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_COLUMN))
+ {
+ SvXMLUnitConverter::convertNumber(nColumn, sValue);
+ bColumn = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_ROW))
+ {
+ SvXMLUnitConverter::convertNumber(nRow, sValue);
+ bRow = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ SvXMLUnitConverter::convertNumber(nTable, sValue);
+ bTable = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_START_COLUMN))
+ SvXMLUnitConverter::convertNumber(nStartColumn, sValue);
+ else if (IsXMLToken(aLocalName, XML_END_COLUMN))
+ SvXMLUnitConverter::convertNumber(nEndColumn, sValue);
+ else if (IsXMLToken(aLocalName, XML_START_ROW))
+ SvXMLUnitConverter::convertNumber(nStartRow, sValue);
+ else if (IsXMLToken(aLocalName, XML_END_ROW))
+ SvXMLUnitConverter::convertNumber(nEndRow, sValue);
+ else if (IsXMLToken(aLocalName, XML_START_TABLE))
+ SvXMLUnitConverter::convertNumber(nStartTable, sValue);
+ else if (IsXMLToken(aLocalName, XML_END_TABLE))
+ SvXMLUnitConverter::convertNumber(nEndTable, sValue);
+ }
+ }
+ if (bColumn)
+ nStartColumn = nEndColumn = nColumn;
+ if (bRow)
+ nStartRow = nEndRow = nRow;
+ if (bTable)
+ nStartTable = nEndTable = nTable;
+ rBigRange.Set(nStartColumn, nStartRow, nStartTable,
+ nEndColumn, nEndRow, nEndTable);
+}
+
+ScXMLBigRangeContext::~ScXMLBigRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLBigRangeContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLBigRangeContext::EndElement()
+{
+}
+
+ScXMLCellContentDeletionContext::ScXMLCellContentDeletionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
+ pCell(NULL),
+ nID(0),
+ nMatrixCols(0),
+ nMatrixRows(0),
+ nType(NUMBERFORMAT_ALL),
+ nMatrixFlag(MM_NONE),
+ bBigRange(sal_False),
+ bContainsCell(sal_False)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+}
+
+ScXMLCellContentDeletionContext::~ScXMLCellContentDeletionContext()
+{
+}
+
+SvXMLImportContext *ScXMLCellContentDeletionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL))
+ {
+ bContainsCell = sal_True;
+ pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
+ pCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows );
+ }
+ else if (IsXMLToken(rLocalName, XML_CELL_ADDRESS))
+ {
+ DBG_ASSERT(!nID, "a action with a ID should not contain a BigRange");
+ bBigRange = sal_True;
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aBigRange);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLCellContentDeletionContext::EndElement()
+{
+ ScMyCellInfo* pCellInfo(new ScMyCellInfo(pCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType,
+ nMatrixFlag, nMatrixCols, nMatrixRows));
+ if (nID)
+ pChangeTrackingImportHelper->AddDeleted(nID, pCellInfo);
+ else
+ pChangeTrackingImportHelper->AddGenerated(pCellInfo, aBigRange);
+}
+
+ScXMLDependenceContext::ScXMLDependenceContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ pChangeTrackingImportHelper->AddDependence(nID);
+}
+
+ScXMLDependenceContext::~ScXMLDependenceContext()
+{
+}
+
+SvXMLImportContext *ScXMLDependenceContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLDependenceContext::EndElement()
+{
+}
+
+ScXMLDependingsContext::ScXMLDependingsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ // here are no attributes
+}
+
+ScXMLDependingsContext::~ScXMLDependingsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDependingsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ // #i80033# read both old (dependence) and new (dependency) elements
+ if (IsXMLToken(rLocalName, XML_DEPENDENCE) || IsXMLToken(rLocalName, XML_DEPENDENCY))
+ pContext = new ScXMLDependenceContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLDependingsContext::EndElement()
+{
+}
+
+ScXMLChangeDeletionContext::ScXMLChangeDeletionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ pChangeTrackingImportHelper->AddDeleted(nID);
+}
+
+ScXMLChangeDeletionContext::~ScXMLChangeDeletionContext()
+{
+}
+
+SvXMLImportContext *ScXMLChangeDeletionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLChangeDeletionContext::EndElement()
+{
+}
+
+ScXMLDeletionsContext::ScXMLDeletionsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ // here are no attributes
+}
+
+ScXMLDeletionsContext::~ScXMLDeletionsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDeletionsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CHANGE_DELETION))
+ pContext = new ScXMLChangeDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_CELL_CONTENT_DELETION))
+ pContext = new ScXMLCellContentDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLDeletionsContext::EndElement()
+{
+}
+
+ScXMLChangeTextPContext::ScXMLChangeTextPContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList,
+ ScXMLChangeCellContext* pTempChangeCellContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xAttrList(xTempAttrList),
+ sLName(rLName),
+ sText(),
+ pChangeCellContext(pTempChangeCellContext),
+ pTextPContext(NULL),
+ nPrefix(nPrfx)
+{
+ // here are no attributes
+}
+
+ScXMLChangeTextPContext::~ScXMLChangeTextPContext()
+{
+ if (pTextPContext)
+ delete pTextPContext;
+}
+
+SvXMLImportContext *ScXMLChangeTextPContext::CreateChildContext( USHORT nTempPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLName, XML_S)) && !pTextPContext)
+ {
+ sal_Int32 nRepeat(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrfx(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ if ((nPrfx == XML_NAMESPACE_TEXT) && (IsXMLToken(aLocalName, XML_C)))
+ nRepeat = sValue.toInt32();
+ }
+ if (nRepeat)
+ for (sal_Int32 j = 0; j < nRepeat; ++j)
+ sText.append(static_cast<sal_Unicode>(' '));
+ else
+ sText.append(static_cast<sal_Unicode>(' '));
+ }
+ else
+ {
+ if (!pChangeCellContext->IsEditCell())
+ pChangeCellContext->CreateTextPContext(sal_False);
+ sal_Bool bWasContext (sal_True);
+ if (!pTextPContext)
+ {
+ bWasContext = sal_False;
+ pTextPContext = GetScImport().GetTextImport()->CreateTextChildContext(
+ GetScImport(), nPrefix, sLName, xAttrList);
+ }
+ if (pTextPContext)
+ {
+ if (!bWasContext)
+ pTextPContext->Characters(sText.makeStringAndClear());
+ pContext = pTextPContext->CreateChildContext(nTempPrefix, rLName, xTempAttrList);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLChangeTextPContext::Characters( const ::rtl::OUString& rChars )
+{
+ if (!pTextPContext)
+ sText.append(rChars);
+ else
+ pTextPContext->Characters(rChars);
+}
+
+void ScXMLChangeTextPContext::EndElement()
+{
+ if (!pTextPContext)
+ pChangeCellContext->SetText(sText.makeStringAndClear());
+}
+
+ScXMLChangeCellContext::ScXMLChangeCellContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScBaseCell*& rTempOldCell, rtl::OUString& rAddress,
+ rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp,
+ formula::FormulaGrammar::Grammar& rGrammar,
+ rtl::OUString& rTempInputString, double& fDateTimeValue, sal_uInt16& nType,
+ sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ rInputString(rTempInputString),
+ rOldCell(rTempOldCell),
+ pEditTextObj(NULL),
+ rDateTimeValue(fDateTimeValue),
+ rType(nType),
+ bEmpty(sal_True),
+ bFirstParagraph(sal_True),
+ bString(sal_True),
+ bFormula(sal_False)
+{
+ sal_Bool bIsMatrix(sal_False);
+ sal_Bool bIsCoveredMatrix(sal_False);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_FORMULA))
+ {
+ bEmpty = sal_False;
+ GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, rGrammar, sValue );
+ bFormula = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_CELL_ADDRESS))
+ {
+ rAddress = sValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_MATRIX_COVERED))
+ {
+ bIsCoveredMatrix = IsXMLToken(sValue, XML_TRUE);
+ }
+ else if (IsXMLToken(aLocalName, XML_NUMBER_MATRIX_COLUMNS_SPANNED))
+ {
+ bIsMatrix = sal_True;
+ SvXMLUnitConverter::convertNumber(nMatrixCols, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_NUMBER_MATRIX_ROWS_SPANNED))
+ {
+ bIsMatrix = sal_True;
+ SvXMLUnitConverter::convertNumber(nMatrixRows, sValue);
+ }
+ }
+ else if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_FLOAT))
+ bString = sal_False;
+ else if (IsXMLToken(sValue, XML_DATE))
+ {
+ rType = NUMBERFORMAT_DATE;
+ bString = sal_False;
+ }
+ else if (IsXMLToken(sValue, XML_TIME))
+ {
+ rType = NUMBERFORMAT_TIME;
+ bString = sal_False;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_VALUE))
+ {
+ SvXMLUnitConverter::convertDouble(fValue, sValue);
+ bEmpty = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_DATE_VALUE))
+ {
+ bEmpty = sal_False;
+ if (GetScImport().GetMM100UnitConverter().setNullDate(GetScImport().GetModel()))
+ GetScImport().GetMM100UnitConverter().convertDateTime(rDateTimeValue, sValue);
+ fValue = rDateTimeValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_TIME_VALUE))
+ {
+ bEmpty = sal_False;
+ GetScImport().GetMM100UnitConverter().convertTime(rDateTimeValue, sValue);
+ fValue = rDateTimeValue;
+ }
+ }
+ }
+ if (bIsCoveredMatrix)
+ nMatrixFlag = MM_REFERENCE;
+ else if (bIsMatrix && nMatrixRows && nMatrixCols)
+ nMatrixFlag = MM_FORMULA;
+}
+
+ScXMLChangeCellContext::~ScXMLChangeCellContext()
+{
+}
+
+SvXMLImportContext *ScXMLChangeCellContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLocalName, XML_P)))
+ {
+ bEmpty = sal_False;
+ if (bFirstParagraph)
+ {
+ pContext = new ScXMLChangeTextPContext(GetScImport(), nPrefix, rLocalName, xAttrList, this);
+ bFirstParagraph = sal_False;
+ }
+ else
+ {
+ if (!pEditTextObj)
+ CreateTextPContext(sal_True);
+ pContext = GetScImport().GetTextImport()->CreateTextChildContext(
+ GetScImport(), nPrefix, rLocalName, xAttrList);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLChangeCellContext::CreateTextPContext(sal_Bool bIsNewParagraph)
+{
+ if (GetScImport().GetDocument())
+ {
+ pEditTextObj = new ScEditEngineTextObj();
+ pEditTextObj->acquire();
+ pEditTextObj->GetEditEngine()->SetEditTextObjectPool(GetScImport().GetDocument()->GetEditPool());
+ uno::Reference <text::XText> xText(pEditTextObj);
+ if (xText.is())
+ {
+ uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor());
+ if (bIsNewParagraph)
+ {
+ xText->setString(sText);
+ xTextCursor->gotoEnd(sal_False);
+ uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY);
+ if (xTextRange.is())
+ xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, sal_False);
+ }
+ GetScImport().GetTextImport()->SetCursor(xTextCursor);
+ }
+ }
+}
+
+void ScXMLChangeCellContext::EndElement()
+{
+ if (!bEmpty)
+ {
+ if (pEditTextObj)
+ {
+ if (GetImport().GetTextImport()->GetCursor().is())
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ OUString sEmpty;
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), sEmpty,
+ sal_True );
+ }
+ }
+ if (GetScImport().GetDocument())
+ rOldCell = new ScEditCell(pEditTextObj->CreateTextObject(), GetScImport().GetDocument(), GetScImport().GetDocument()->GetEditPool());
+ GetScImport().GetTextImport()->ResetCursor();
+ // delete pEditTextObj;
+ pEditTextObj->release();
+ }
+ else
+ {
+ if (!bFormula)
+ {
+ if (sText.getLength() && bString)
+ rOldCell = new ScStringCell(sText);
+ else
+ rOldCell = new ScValueCell(fValue);
+ if (rType == NUMBERFORMAT_DATE || rType == NUMBERFORMAT_TIME)
+ rInputString = sText;
+ }
+ else
+ {
+ // do nothing, this has to do later (on another place)
+ /*ScAddress aCellPos;
+ rOldCell = new ScFormulaCell(GetScImport().GetDocument(), aCellPos, sFormula);
+ if (bString)
+ static_cast<ScFormulaCell*>(rOldCell)->SetString(sValue);
+ else
+ static_cast<ScFormulaCell*>(rOldCell)->SetDouble(fValue);
+ static_cast<ScFormulaCell*>(rOldCell)->SetInChangeTrack(sal_True);
+ if (bIsCoveredMatrix)
+ static_cast<ScFormulaCell*>(rOldCell)->SetMatrixFlag(MM_REFERENCE);
+ else if (bIsMatrix && nMatrixRows && nMatrixCols)
+ {
+ static_cast<ScFormulaCell*>(rOldCell)->SetMatrixFlag(MM_FORMULA);
+ static_cast<ScFormulaCell*>(rOldCell)->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows));
+ }*/
+ }
+ }
+ }
+ else
+ rOldCell = NULL;
+}
+
+ScXMLPreviousContext::ScXMLPreviousContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
+ pOldCell(NULL),
+ nID(0),
+ nMatrixCols(0),
+ nMatrixRows(0),
+ eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
+ nType(NUMBERFORMAT_ALL),
+ nMatrixFlag(MM_NONE)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+}
+
+ScXMLPreviousContext::~ScXMLPreviousContext()
+{
+}
+
+SvXMLImportContext *ScXMLPreviousContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TABLE) && (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL)))
+ pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
+ pOldCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLPreviousContext::EndElement()
+{
+ pChangeTrackingImportHelper->SetPreviousChange(nID, new ScMyCellInfo(pOldCell, sFormulaAddress, sFormula, eGrammar, sInputString,
+ fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows));
+}
+
+ScXMLContentChangeContext::ScXMLContentChangeContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(SC_CAT_CONTENT);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+}
+
+ScXMLContentChangeContext::~ScXMLContentChangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentChangeContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CELL_ADDRESS))
+ {
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aBigRange);
+ }
+ else if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ {
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_PREVIOUS))
+ {
+ pContext = new ScXMLPreviousContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLContentChangeContext::EndElement()
+{
+ pChangeTrackingImportHelper->SetBigRange(aBigRange);
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLInsertionContext::ScXMLInsertionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ sal_Int32 nPosition(0);
+ sal_Int32 nCount(1);
+ sal_Int32 nTable(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+ ScChangeActionType nActionType(SC_CAT_INSERT_COLS);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_ROW))
+ nActionType = SC_CAT_INSERT_ROWS;
+ else if (IsXMLToken(sValue, XML_TABLE))
+ nActionType = SC_CAT_INSERT_TABS;
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ SvXMLUnitConverter::convertNumber(nTable, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_COUNT))
+ {
+ SvXMLUnitConverter::convertNumber(nCount, sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(nActionType);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+ pChangeTrackingImportHelper->SetPosition(nPosition, nCount, nTable);
+}
+
+ScXMLInsertionContext::~ScXMLInsertionContext()
+{
+}
+
+SvXMLImportContext *ScXMLInsertionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLInsertionContext::EndElement()
+{
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLInsertionCutOffContext::ScXMLInsertionCutOffContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int32 nPosition(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ }
+ }
+ pChangeTrackingImportHelper->SetInsertionCutOff(nID, nPosition);
+}
+
+ScXMLInsertionCutOffContext::~ScXMLInsertionCutOffContext()
+{
+}
+
+SvXMLImportContext *ScXMLInsertionCutOffContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLInsertionCutOffContext::EndElement()
+{
+}
+
+ScXMLMovementCutOffContext::ScXMLMovementCutOffContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int32 nPosition(0);
+ sal_Int32 nStartPosition(0);
+ sal_Int32 nEndPosition(0);
+ sal_Bool bPosition(sal_False);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ bPosition = sal_True;
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_START_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nStartPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_END_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nEndPosition, sValue);
+ }
+ }
+ }
+ if (bPosition)
+ nStartPosition = nEndPosition = nPosition;
+ pChangeTrackingImportHelper->AddMoveCutOff(nID, nStartPosition, nEndPosition);
+}
+
+ScXMLMovementCutOffContext::~ScXMLMovementCutOffContext()
+{
+}
+
+SvXMLImportContext *ScXMLMovementCutOffContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLMovementCutOffContext::EndElement()
+{
+}
+
+ScXMLCutOffsContext::ScXMLCutOffsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ // here are no attributes
+}
+
+ScXMLCutOffsContext::~ScXMLCutOffsContext()
+{
+}
+
+SvXMLImportContext *ScXMLCutOffsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_INSERTION_CUT_OFF))
+ pContext = new ScXMLInsertionCutOffContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_MOVEMENT_CUT_OFF))
+ pContext = new ScXMLMovementCutOffContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLCutOffsContext::EndElement()
+{
+}
+
+ScXMLDeletionContext::ScXMLDeletionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ sal_Int32 nPosition(0);
+ sal_Int32 nMultiSpanned(0);
+ sal_Int32 nTable(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+ ScChangeActionType nActionType(SC_CAT_DELETE_COLS);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_ROW))
+ {
+ nActionType = SC_CAT_DELETE_ROWS;
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ nActionType = SC_CAT_DELETE_TABS;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ SvXMLUnitConverter::convertNumber(nTable, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_MULTI_DELETION_SPANNED))
+ {
+ SvXMLUnitConverter::convertNumber(nMultiSpanned, sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(nActionType);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+ pChangeTrackingImportHelper->SetPosition(nPosition, 1, nTable);
+ pChangeTrackingImportHelper->SetMultiSpanned(static_cast<sal_Int16>(nMultiSpanned));
+}
+
+ScXMLDeletionContext::~ScXMLDeletionContext()
+{
+}
+
+SvXMLImportContext *ScXMLDeletionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_CUT_OFFS) || rLocalName.equalsAsciiL("cut_offs", 8))
+ pContext = new ScXMLCutOffsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else
+ {
+ DBG_ERROR("don't know this");
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLDeletionContext::EndElement()
+{
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLMovementContext::ScXMLMovementContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(SC_CAT_MOVE);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+}
+
+ScXMLMovementContext::~ScXMLMovementContext()
+{
+}
+
+SvXMLImportContext *ScXMLMovementContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_SOURCE_RANGE_ADDRESS))
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aSourceRange);
+ else if (IsXMLToken(rLocalName, XML_TARGET_RANGE_ADDRESS))
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aTargetRange);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLMovementContext::EndElement()
+{
+ pChangeTrackingImportHelper->SetMoveRanges(aSourceRange, aTargetRange);
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLRejectionContext::ScXMLRejectionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(SC_CAT_MOVE);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+}
+
+ScXMLRejectionContext::~ScXMLRejectionContext()
+{
+}
+
+SvXMLImportContext *ScXMLRejectionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLRejectionContext::EndElement()
+{
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+
+
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.hxx b/sc/source/filter/xml/XMLTrackedChangesContext.hxx
new file mode 100644
index 000000000000..ec66fe7f22e7
--- /dev/null
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTRACKEDCHANGESCONTEXT_HXX
+#define SC_XMLTRACKEDCHANGESCONTEXT_HXX
+
+#include "XMLChangeTrackingImportHelper.hxx"
+#include "chgtrack.hxx"
+#include <xmloff/xmlictxt.hxx>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+class ScXMLChangeTrackingImportHelper;
+class ScEditEngineTextObj;
+
+class ScXMLTrackedChangesContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLTrackedChangesContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLTrackedChangesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/makefile.mk b/sc/source/filter/xml/makefile.mk
new file mode 100644
index 000000000000..7f9f2d529a90
--- /dev/null
+++ b/sc/source/filter/xml/makefile.mk
@@ -0,0 +1,109 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=xml
+
+ENABLE_EXCEPTIONS=TRUE
+
+AUTOSEG=true
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\pch\filt_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/sheetdata.obj \
+ $(SLO)$/xmlwrap.obj \
+ $(SLO)$/xmlimprt.obj \
+ $(SLO)$/xmlexprt.obj \
+ $(SLO)$/xmlbodyi.obj \
+ $(SLO)$/xmltabi.obj \
+ $(SLO)$/xmlexternaltabi.obj \
+ $(SLO)$/xmlrowi.obj \
+ $(SLO)$/xmlcelli.obj \
+ $(SLO)$/xmlconti.obj \
+ $(SLO)$/xmlcoli.obj \
+ $(SLO)$/xmlsubti.obj \
+ $(SLO)$/xmlnexpi.obj \
+ $(SLO)$/xmldrani.obj \
+ $(SLO)$/xmlfilti.obj \
+ $(SLO)$/xmlsorti.obj \
+ $(SLO)$/xmlstyle.obj \
+ $(SLO)$/xmlstyli.obj \
+ $(SLO)$/xmldpimp.obj \
+ $(SLO)$/xmlannoi.obj \
+ $(SLO)$/xmlsceni.obj \
+ $(SLO)$/xmlcvali.obj \
+ $(SLO)$/XMLTableMasterPageExport.obj \
+ $(SLO)$/xmllabri.obj \
+ $(SLO)$/XMLTableHeaderFooterContext.obj \
+ $(SLO)$/XMLDetectiveContext.obj \
+ $(SLO)$/XMLCellRangeSourceContext.obj \
+ $(SLO)$/XMLConsolidationContext.obj \
+ $(SLO)$/XMLConverter.obj \
+ $(SLO)$/XMLExportIterator.obj \
+ $(SLO)$/XMLColumnRowGroupExport.obj \
+ $(SLO)$/XMLStylesExportHelper.obj \
+ $(SLO)$/XMLStylesImportHelper.obj \
+ $(SLO)$/XMLExportDataPilot.obj \
+ $(SLO)$/XMLExportDatabaseRanges.obj \
+ $(SLO)$/XMLTableShapeImportHelper.obj \
+ $(SLO)$/XMLTableShapesContext.obj \
+ $(SLO)$/XMLExportDDELinks.obj \
+ $(SLO)$/XMLDDELinksContext.obj \
+ $(SLO)$/XMLCalculationSettingsContext.obj \
+ $(SLO)$/XMLTableSourceContext.obj \
+ $(SLO)$/XMLTextPContext.obj \
+ $(SLO)$/XMLTableShapeResizer.obj \
+ $(SLO)$/XMLChangeTrackingExportHelper.obj \
+ $(SLO)$/xmlfonte.obj \
+ $(SLO)$/XMLChangeTrackingImportHelper.obj \
+ $(SLO)$/XMLTrackedChangesContext.obj \
+ $(SLO)$/XMLExportSharedData.obj \
+ $(SLO)$/XMLEmptyContext.obj \
+ $(SLO)$/XMLCodeNameProvider.obj
+
+
+NOOPTFILES= \
+ $(SLO)$/xmlcvali.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/filter/xml/sheetdata.cxx b/sc/source/filter/xml/sheetdata.cxx
new file mode 100644
index 000000000000..947c1370fa4b
--- /dev/null
+++ b/sc/source/filter/xml/sheetdata.cxx
@@ -0,0 +1,283 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <xmloff/families.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/string.hxx>
+#include <tools/debug.hxx>
+
+#include "sheetdata.hxx"
+
+// -----------------------------------------------------------------------
+
+ScSheetSaveData::ScSheetSaveData() :
+ mnStartTab( -1 ),
+ mnStartOffset( -1 ),
+ maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) ),
+ mbInSupportedSave( false )
+{
+}
+
+ScSheetSaveData::~ScSheetSaveData()
+{
+}
+
+void ScSheetSaveData::AddCellStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maCellStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddColumnStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maColumnStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddRowStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maRowStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddTableStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maTableStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::HandleNoteStyles( const rtl::OUString& rStyleName, const rtl::OUString& rTextName, const ScAddress& rCellPos )
+{
+ // only consecutive duplicates (most common case) are filtered out here,
+ // the others are found when the styles are created
+
+ if ( rStyleName == maPreviousNote.maStyleName &&
+ rTextName == maPreviousNote.maTextStyle &&
+ rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
+ {
+ // already stored for the same sheet - ignore
+ return;
+ }
+
+ ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
+ maPreviousNote = aNewEntry;
+ maNoteStyles.push_back( aNewEntry );
+}
+
+void ScSheetSaveData::AddNoteContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ if ( nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
+ maNoteParaStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+ else
+ maNoteTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+}
+
+void ScSheetSaveData::AddTextStyle( const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ maTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+}
+
+void ScSheetSaveData::BlockSheet( sal_Int32 nTab )
+{
+ if ( nTab >= (sal_Int32)maBlocked.size() )
+ maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
+
+ maBlocked[nTab] = true;
+}
+
+bool ScSheetSaveData::IsSheetBlocked( sal_Int32 nTab ) const
+{
+ if ( nTab < (sal_Int32)maBlocked.size() )
+ return maBlocked[nTab];
+ else
+ return false;
+}
+
+void ScSheetSaveData::AddStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= (sal_Int32)maStreamEntries.size() )
+ maStreamEntries.resize( nTab + 1 );
+
+ maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::StartStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset )
+{
+ DBG_ASSERT( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
+
+ mnStartTab = nTab;
+ mnStartOffset = nStartOffset;
+}
+
+void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
+{
+ if ( mnStartTab >= 0 )
+ {
+ AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
+ mnStartTab = -1;
+ mnStartOffset = -1;
+ }
+}
+
+void ScSheetSaveData::GetStreamPos( sal_Int32 nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
+{
+ if ( nTab < (sal_Int32)maStreamEntries.size() )
+ {
+ const ScStreamEntry& rEntry = maStreamEntries[nTab];
+ rStartOffset = rEntry.mnStartOffset;
+ rEndOffset = rEntry.mnEndOffset;
+ }
+ else
+ rStartOffset = rEndOffset = -1;
+}
+
+bool ScSheetSaveData::HasStreamPos( sal_Int32 nTab ) const
+{
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ GetStreamPos( nTab, nStartOffset, nEndOffset );
+ return ( nStartOffset >= 0 && nEndOffset >= 0 );
+}
+
+void ScSheetSaveData::ResetSaveEntries()
+{
+ maSaveEntries.clear();
+}
+
+void ScSheetSaveData::AddSavePos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= (sal_Int32)maSaveEntries.size() )
+ maSaveEntries.resize( nTab + 1 );
+
+ maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::UseSaveEntries()
+{
+ maStreamEntries = maSaveEntries;
+}
+
+void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // the initial namespaces are just removed from the list of loaded namespaces,
+ // so only a hash_set of the prefixes is needed.
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ maInitialPrefixes.insert( aIter->first );
+ ++aIter;
+ }
+}
+
+void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ // ignore the initial namespaces
+ if ( maInitialPrefixes.find( aIter->first ) == maInitialPrefixes.end() )
+ {
+ const NameSpaceEntry& rEntry = aIter->second.getBody();
+ maLoadedNamespaces.push_back( ScLoadedNamespaceEntry( rEntry.sPrefix, rEntry.sName, rEntry.nKey ) );
+ }
+ ++aIter;
+ }
+}
+
+bool lcl_NameInHash( const NameSpaceHash& rNameHash, const rtl::OUString& rName )
+{
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ if ( aIter->second->sName == rName )
+ return true;
+
+ ++aIter;
+ }
+ return false; // not found
+}
+
+bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const
+{
+ // Add the loaded namespaces to the name space map.
+
+ // first loop: only look for conflicts
+ // (if the loaded namespaces were added first, this might not be necessary)
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ std::vector<ScLoadedNamespaceEntry>::const_iterator aIter = maLoadedNamespaces.begin();
+ std::vector<ScLoadedNamespaceEntry>::const_iterator aEnd = maLoadedNamespaces.end();
+ while (aIter != aEnd)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ {
+ if ( lcl_NameInHash( rNameHash, aIter->maName ) )
+ {
+ // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
+ // so this is also considered a conflict
+ return false;
+ }
+ }
+ else if ( aHashIter->second->sName != aIter->maName )
+ {
+ // same prefix, but different name: loaded namespaces can't be used
+ return false;
+ }
+ ++aIter;
+ }
+
+ // only if there were no conflicts, add the entries that aren't in the map already
+ // (the key is needed if the same namespace is added later within an element)
+ aIter = maLoadedNamespaces.begin();
+ while (aIter != aEnd)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ rNamespaces.Add( aIter->maPrefix, aIter->maName, aIter->mnKey );
+ ++aIter;
+ }
+
+ return true; // success
+}
+
+bool ScSheetSaveData::IsInSupportedSave() const
+{
+ return mbInSupportedSave;
+}
+
+void ScSheetSaveData::SetInSupportedSave( bool bSet )
+{
+ mbInSupportedSave = bSet;
+}
+
diff --git a/sc/source/filter/xml/xmlannoi.cxx b/sc/source/filter/xml/xmlannoi.cxx
new file mode 100644
index 000000000000..14fc34954564
--- /dev/null
+++ b/sc/source/filter/xml/xmlannoi.cxx
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlannoi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlconti.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLAnnotationData::ScXMLAnnotationData() :
+ mbUseShapePos( false ),
+ mbShown( false )
+{
+}
+
+ScXMLAnnotationData::~ScXMLAnnotationData()
+{
+}
+
+//------------------------------------------------------------------
+
+ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport,
+ 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),
+ bHasTextP(sal_False),
+ pCellContext(pTempCellContext),
+ pShapeContext(NULL)
+{
+ uno::Reference<drawing::XShapes> xLocalShapes (GetScImport().GetTables().GetCurrentXShapes());
+ if (xLocalShapes.is())
+ {
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ pTableShapeImport->SetAnnotation(this);
+ pShapeContext = GetScImport().GetShapeImport()->CreateGroupChildContext(
+ GetScImport(), nPrfx, rLName, xAttrList, xLocalShapes, sal_True);
+ }
+
+ pCellContext = pTempCellContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAnnotationAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR:
+ {
+ maAuthorBuffer = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE:
+ {
+ maCreateDateBuffer = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING:
+ {
+ maCreateDateStringBuffer = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY:
+ {
+ mrAnnotationData.mbShown = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_X:
+ {
+ mrAnnotationData.mbUseShapePos = true;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_Y:
+ {
+ mrAnnotationData.mbUseShapePos = true;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLAnnotationContext::~ScXMLAnnotationContext()
+{
+}
+
+void ScXMLAnnotationContext::StartElement(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList)
+{
+ if (pShapeContext)
+ pShapeContext->StartElement(xAttrList);
+}
+
+SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( XML_NAMESPACE_DC == nPrefix )
+ {
+ if( IsXMLToken( rLName, XML_CREATOR ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLName, xAttrList, maAuthorBuffer);
+ else if( IsXMLToken( rLName, XML_DATE ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLName, xAttrList, maCreateDateBuffer);
+ }
+ else if( XML_NAMESPACE_META == nPrefix )
+ {
+ if( IsXMLToken( rLName, XML_DATE_STRING ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLName, xAttrList, maCreateDateStringBuffer);
+ }
+/* else if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_P) )
+ {
+ if (!bHasTextP)
+ {
+ bHasTextP = sal_True;
+ maTextBuffer.setLength(0);
+ }
+ if(nParagraphCount)
+ maTextBuffer.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, maTextBuffer);
+ }*/
+
+ if( !pContext && pShapeContext )
+ pContext = pShapeContext->CreateChildContext(nPrefix, rLName, xAttrList);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLAnnotationContext::Characters( const ::rtl::OUString& rChars )
+{
+ if (!bHasTextP)
+ maTextBuffer.append(rChars);
+}
+
+void ScXMLAnnotationContext::EndElement()
+{
+ if (pShapeContext)
+ {
+ pShapeContext->EndElement();
+ delete pShapeContext;
+ }
+
+ mrAnnotationData.maAuthor = maAuthorBuffer.makeStringAndClear();
+ mrAnnotationData.maCreateDate = maCreateDateBuffer.makeStringAndClear();
+ if (!mrAnnotationData.maCreateDate.getLength())
+ mrAnnotationData.maCreateDate = maCreateDateStringBuffer.makeStringAndClear();
+ mrAnnotationData.maSimpleText = maTextBuffer.makeStringAndClear();
+
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ pTableShapeImport->SetAnnotation(NULL);
+}
+
+void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes,
+ const rtl::OUString& rStyleName, const rtl::OUString& rTextStyle )
+{
+ mrAnnotationData.mxShape = rxShape;
+ mrAnnotationData.mxShapes = rxShapes;
+ mrAnnotationData.maStyleName = rStyleName;
+ mrAnnotationData.maTextStyle = rTextStyle;
+}
+
+void ScXMLAnnotationContext::AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection )
+{
+ mrAnnotationData.maContentStyles.push_back( ScXMLAnnotationStyleEntry( nFamily, rName, rSelection ) );
+}
+
diff --git a/sc/source/filter/xml/xmlannoi.hxx b/sc/source/filter/xml/xmlannoi.hxx
new file mode 100644
index 000000000000..ad2eed21b23a
--- /dev/null
+++ b/sc/source/filter/xml/xmlannoi.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLANNOI_HXX
+#define SC_XMLANNOI_HXX
+
+#include <memory>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <editeng/editdata.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+class ScXMLImport;
+class ScXMLTableRowCellContext;
+
+struct ScXMLAnnotationStyleEntry
+{
+ sal_uInt16 mnFamily;
+ rtl::OUString maName;
+ ESelection maSelection;
+
+ ScXMLAnnotationStyleEntry( sal_uInt16 nFam, const rtl::OUString& rNam, const ESelection& rSel ) :
+ mnFamily( nFam ),
+ maName( rNam ),
+ maSelection( rSel )
+ {
+ }
+};
+
+struct ScXMLAnnotationData
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ mxShape;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+ mxShapes;
+ ::rtl::OUString maAuthor;
+ ::rtl::OUString maCreateDate;
+ ::rtl::OUString maSimpleText;
+ ::rtl::OUString maStyleName;
+ ::rtl::OUString maTextStyle;
+ bool mbUseShapePos;
+ bool mbShown;
+ std::vector<ScXMLAnnotationStyleEntry> maContentStyles;
+
+ explicit ScXMLAnnotationData();
+ ~ScXMLAnnotationData();
+};
+
+class ScXMLAnnotationContext : public SvXMLImportContext
+{
+public:
+
+ ScXMLAnnotationContext( ScXMLImport& rImport, 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();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void StartElement(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+
+ void SetShape(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::rtl::OUString& rStyleName, const ::rtl::OUString& rTextStyle );
+
+ void AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection );
+
+private:
+ ScXMLAnnotationData& mrAnnotationData;
+ rtl::OUStringBuffer maTextBuffer;
+ rtl::OUStringBuffer maAuthorBuffer;
+ rtl::OUStringBuffer maCreateDateBuffer;
+ rtl::OUStringBuffer maCreateDateStringBuffer;
+ sal_Int32 nParagraphCount;
+ sal_Bool bHasTextP;
+ ScXMLTableRowCellContext* pCellContext;
+ SvXMLImportContext* pShapeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+};
+
+
+#endif
+
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
new file mode 100644
index 000000000000..00c87cd661d7
--- /dev/null
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <cstdio>
+
+#include "document.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
+
+#include "xmlbodyi.hxx"
+#include "xmltabi.hxx"
+#include "xmlnexpi.hxx"
+#include "xmldrani.hxx"
+#include "xmlimprt.hxx"
+#include "xmldpimp.hxx"
+#include "xmlcvali.hxx"
+#include "xmlstyli.hxx"
+#include "xmllabri.hxx"
+#include "XMLConsolidationContext.hxx"
+#include "XMLDDELinksContext.hxx"
+#include "XMLCalculationSettingsContext.hxx"
+#include "XMLTrackedChangesContext.hxx"
+#include "XMLEmptyContext.hxx"
+#include "scerrors.hxx"
+#include "tabprotection.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <sal/types.h>
+#include <tools/debug.hxx>
+
+#include <memory>
+
+using rtl::OUString;
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sPassword(),
+ bProtected(sal_False),
+ bHadCalculationSettings(sal_False),
+ pChangeTrackingImportHelper(NULL)
+{
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc)
+ {
+ // ODF 1.1 and earlier => GRAM_PODF; ODF 1.2 and later => GRAM_ODFF;
+ // no version => earlier than 1.2 => GRAM_PODF.
+ formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF;
+ OUString aVer( rImport.GetODFVersion());
+ sal_Int32 nLen = aVer.getLength();
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "\n ScXMLBodyContext ODFVersion: nLen: %d, str: %s\n",
+ (int)nLen, OUStringToOString( aVer, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ if (!nLen)
+ eGrammar = formula::FormulaGrammar::GRAM_PODF;
+ else
+ {
+ // In case there was a micro version, e.g. "1.2.3", this would
+ // still yield major.minor, but pParsedEnd (5th parameter, not
+ // passed here) would point before string end upon return.
+ double fVer = ::rtl::math::stringToDouble( aVer, '.', 0, NULL, NULL);
+ if (fVer < 1.2)
+ eGrammar = formula::FormulaGrammar::GRAM_PODF;
+ }
+ pDoc->SetStorageGrammar( eGrammar);
+ }
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_STRUCTURE_PROTECTED))
+ bProtected = IsXMLToken(sValue, XML_TRUE);
+ else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY))
+ sPassword = sValue;
+ }
+ }
+}
+
+ScXMLBodyContext::~ScXMLBodyContext()
+{
+}
+
+SvXMLImportContext *ScXMLBodyContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before the next child element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetBodyElemTokenMap();
+// sal_Bool bOrdered = sal_False;
+// sal_Bool bHeading = sal_False;
+ switch( rTokenMap.Get( nPrefix, rLocalName ) )
+ {
+// case XML_TOK_TEXT_H:
+// bHeading = TRUE;
+// case XML_TOK_TEXT_P:
+// pContext = new SwXMLParaContext( GetSwImport(),nPrefix, rLocalName,
+// xAttrList, bHeading );
+// break;
+// case XML_TOK_TEXT_ORDERED_LIST:
+// bOrdered = TRUE;
+// case XML_TOK_TEXT_UNORDERED_LIST:
+// pContext = new SwXMLListBlockContext( GetSwImport(),nPrefix, rLocalName,
+// xAttrList, bOrdered );
+// break;
+ case XML_TOK_BODY_TRACKED_CHANGES :
+ {
+ pChangeTrackingImportHelper = GetScImport().GetChangeTrackingImportHelper();
+ if (pChangeTrackingImportHelper)
+ pContext = new ScXMLTrackedChangesContext( GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ break;
+ case XML_TOK_BODY_CALCULATION_SETTINGS :
+ pContext = new ScXMLCalculationSettingsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
+ bHadCalculationSettings = sal_True;
+ break;
+ case XML_TOK_BODY_CONTENT_VALIDATIONS :
+ pContext = new ScXMLContentValidationsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
+ break;
+ case XML_TOK_BODY_LABEL_RANGES:
+ pContext = new ScXMLLabelRangesContext( GetScImport(), nPrefix, rLocalName, xAttrList );
+ break;
+ case XML_TOK_BODY_TABLE:
+ {
+ if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB)
+ {
+ GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW);
+ pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLocalName);
+ }
+ else
+ {
+ pContext = new ScXMLTableContext( GetScImport(),nPrefix, rLocalName,
+ xAttrList );
+ }
+ }
+ break;
+ case XML_TOK_BODY_NAMED_EXPRESSIONS:
+ pContext = new ScXMLNamedExpressionsContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DATABASE_RANGES:
+ pContext = new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DATABASE_RANGE:
+ pContext = new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DATA_PILOT_TABLES:
+ pContext = new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_CONSOLIDATION:
+ pContext = new ScXMLConsolidationContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DDE_LINKS:
+ pContext = new ScXMLDDELinksContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLBodyContext::Characters( const OUString& )
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before any content (whitespace) within the spreadsheet element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+ // otherwise ignore
+}
+
+void ScXMLBodyContext::EndElement()
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before the closing tag of spreadsheet element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+
+ if ( pSheetData )
+ {
+ // store the loaded namespaces (for the office:spreadsheet element),
+ // so the prefixes in copied stream fragments remain valid
+ const SvXMLNamespaceMap& rNamespaces = GetImport().GetNamespaceMap();
+ pSheetData->StoreLoadedNamespaces( rNamespaces );
+ }
+
+ if (!bHadCalculationSettings)
+ {
+ // #111055#; set calculation settings defaults if there is no calculation settings element
+ SvXMLImportContext *pContext = new ScXMLCalculationSettingsContext( GetScImport(), XML_NAMESPACE_TABLE, GetXMLToken(XML_CALCULATION_SETTINGS), NULL );
+ pContext->EndElement();
+ }
+ GetScImport().LockSolarMutex();
+ ScMyImpDetectiveOpArray* pDetOpArray = GetScImport().GetDetectiveOpArray();
+ ScDocument* pDoc = GetScImport().GetDocument();
+ ScMyImpDetectiveOp aDetOp;
+
+ if (pDoc && GetScImport().GetModel().is())
+ {
+ if (pDetOpArray)
+ {
+ pDetOpArray->Sort();
+ while( pDetOpArray->GetFirstOp( aDetOp ) )
+ {
+ ScDetOpData aOpData( aDetOp.aPosition, aDetOp.eOpType );
+ pDoc->AddDetectiveOperation( aOpData );
+ }
+ }
+
+ if (pChangeTrackingImportHelper)
+ pChangeTrackingImportHelper->CreateChangeTrack(GetScImport().GetDocument());
+
+#if 0
+ // #i57869# table styles are applied before the contents now
+
+ std::vector<rtl::OUString> aTableStyleNames(GetScImport().GetTableStyle());
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetScImport().GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() && !aTableStyleNames.empty())
+ {
+ uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ sal_Int32 nTableCount = xIndex->getCount();
+ sal_Int32 nSize(aTableStyleNames.size());
+ DBG_ASSERT(nTableCount == nSize, "every table should have a style name");
+ for(sal_uInt32 i = 0; i < nTableCount; i++)
+ {
+ if (i < nSize)
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xIndex->getByIndex(i), uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ rtl::OUString sTableStyleName(aTableStyleNames[i]);
+ XMLTableStylesContext *pStyles = (XMLTableStylesContext *)GetScImport().GetAutoStyles();
+ if ( pStyles && sTableStyleName.getLength() )
+ {
+ XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_TABLE, sTableStyleName, sal_True);
+ if (pStyle)
+ pStyle->FillPropertySet(xProperties);
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ // #i37959# handle document protection after the sheet settings
+ if (bProtected)
+ {
+ ::std::auto_ptr<ScDocProtection> pProtection(new ScDocProtection);
+ pProtection->setProtected(true);
+
+ uno::Sequence<sal_Int8> aPass;
+ if (sPassword.getLength())
+ {
+ SvXMLUnitConverter::decodeBase64(aPass, sPassword);
+ pProtection->setPasswordHash(aPass, PASSHASH_OOO);
+ }
+
+ pDoc->SetDocProtection(pProtection.get());
+ }
+ }
+ GetScImport().UnlockSolarMutex();
+}
+
diff --git a/sc/source/filter/xml/xmlbodyi.hxx b/sc/source/filter/xml/xmlbodyi.hxx
new file mode 100644
index 000000000000..e61e413ff79b
--- /dev/null
+++ b/sc/source/filter/xml/xmlbodyi.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLBODYI_HXX
+#define SC_XMLBODYI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+class ScXMLChangeTrackingImportHelper;
+
+class ScXMLBodyContext : public SvXMLImportContext
+{
+ rtl::OUString sPassword;
+ sal_Bool bProtected;
+ sal_Bool bHadCalculationSettings;
+
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLBodyContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual ~ScXMLBodyContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+ virtual void Characters( const ::rtl::OUString& rChars );
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
new file mode 100644
index 000000000000..ae5a7bcebe66
--- /dev/null
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -0,0 +1,1127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlcelli.hxx"
+#include "xmlimprt.hxx"
+#include "xmltabi.hxx"
+#include "xmlstyli.hxx"
+#include "xmlannoi.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "cellsuno.hxx"
+#include "docuno.hxx"
+#include "unonames.hxx"
+#include "postit.hxx"
+#include "sheetdata.hxx"
+
+#include "XMLTableShapeImportHelper.hxx"
+#include "XMLTextPContext.hxx"
+#include "XMLStylesImportHelper.hxx"
+
+#include "arealink.hxx"
+#include <sfx2/linkmgr.hxx>
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "scerrors.hxx"
+#include "editutil.hxx"
+#include "cell.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <svx/unoapi.hxx>
+#include <svl/languageoptions.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <tools/date.hxx>
+#include <i18npool/lang.h>
+#include <comphelper/extract.hxx>
+
+#define SC_CURRENCYSYMBOL "CurrencySymbol"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempIsCovered,
+ const sal_Int32 nTempRepeatedRows ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pContentValidationName(NULL),
+ pDetectiveObjVec(NULL),
+ pCellRangeSource(NULL),
+ fValue(0.0),
+ nMergedRows(1),
+ nMergedCols(1),
+ nRepeatedRows(nTempRepeatedRows),
+ nCellsRepeated(1),
+ rXMLImport((ScXMLImport&)rImport),
+ eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
+ nCellType(util::NumberFormat::TEXT),
+ bIsMerged(sal_False),
+ bIsMatrix(sal_False),
+ bHasSubTable(sal_False),
+ bIsCovered(bTempIsCovered),
+ bIsEmpty(sal_True),
+ bHasTextImport(sal_False),
+ bIsFirstTextImport(sal_False),
+ bSolarMutexLocked(sal_False),
+ bFormulaTextResult(sal_False)
+{
+ rXMLImport.SetRemoveLastChar(sal_False);
+ rXMLImport.GetTables().AddColumn(bTempIsCovered);
+ const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ rtl::OUString aLocalName;
+ rtl::OUString* pStyleName = NULL;
+ rtl::OUString* pCurrencySymbol = NULL;
+ const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex(i), &aLocalName);
+
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+ sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
+ pStyleName = new rtl::OUString(sValue);
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
+ DBG_ASSERT(!pContentValidationName, "here should be only one Validation Name");
+ pContentValidationName = new rtl::OUString(sValue);
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
+ bIsMerged = sal_True;
+ nMergedRows = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
+ bIsMerged = sal_True;
+ nMergedCols = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
+ bIsMatrix = sal_True;
+ nMatrixCols = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
+ bIsMatrix = sal_True;
+ nMatrixRows = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
+ nCellsRepeated = std::max( sValue.toInt32(), (sal_Int32) 1 );
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
+ nCellType = GetScImport().GetCellType(sValue);
+ bIsEmpty = sal_False;
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue);
+ bIsEmpty = sal_False;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
+ {
+ if (sValue.getLength() && rXMLImport.SetNullDateOnUnitConverter())
+ {
+ rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
+ bIsEmpty = sal_False;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ rXMLImport.GetMM100UnitConverter().convertTime(fValue, sValue);
+ bIsEmpty = sal_False;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ DBG_ASSERT(!pOUTextValue, "here should be only one string value");
+ pOUTextValue.reset(sValue);
+ bIsEmpty = sal_False;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ if ( IsXMLToken(sValue, XML_TRUE) )
+ fValue = 1.0;
+ else if ( IsXMLToken(sValue, XML_FALSE) )
+ fValue = 0.0;
+ else
+ rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue);
+ bIsEmpty = sal_False;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
+ {
+ if (sValue.getLength())
+ {
+ DBG_ASSERT(!pOUFormula, "here should be only one formula");
+ rtl::OUString aFormula, aFormulaNmsp;
+ rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
+ pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) );
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
+ pCurrencySymbol = new rtl::OUString(sValue);
+ break;
+ default:
+ ;
+ }
+ }
+ if (pOUFormula)
+ {
+ if (nCellType == util::NumberFormat::TEXT)
+ bFormulaTextResult = sal_True;
+ nCellType = util::NumberFormat::UNDEFINED;
+ }
+ rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType);
+}
+
+ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
+{
+ if (pContentValidationName)
+ delete pContentValidationName;
+ if (pDetectiveObjVec)
+ delete pDetectiveObjVec;
+ if (pCellRangeSource)
+ delete pCellRangeSource;
+}
+
+void ScXMLTableRowCellContext::LockSolarMutex()
+{
+ if (!bSolarMutexLocked)
+ {
+ GetScImport().LockSolarMutex();
+ bSolarMutexLocked = sal_True;
+ }
+}
+
+void ScXMLTableRowCellContext::UnlockSolarMutex()
+{
+ if (bSolarMutexLocked)
+ {
+ GetScImport().UnlockSolarMutex();
+ bSolarMutexLocked = sal_False;
+ }
+}
+
+void ScXMLTableRowCellContext::SetCursorOnTextImport(const rtl::OUString& rOUTempText)
+{
+ com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (CellExists(aCellPos))
+ {
+ uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
+ if (xCellRange.is())
+ {
+ xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row));
+ if (xBaseCell.is())
+ {
+ xLockable.set(xBaseCell, uno::UNO_QUERY);
+ if (xLockable.is())
+ xLockable->addActionLock();
+ uno::Reference<text::XText> xText(xBaseCell, uno::UNO_QUERY);
+ if (xText.is())
+ {
+ uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor());
+ if (xTextCursor.is())
+ {
+ xTextCursor->setString(rOUTempText);
+ xTextCursor->gotoEnd(sal_False);
+ rXMLImport.GetTextImport()->SetCursor(xTextCursor);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("this method should only be called for a existing cell");
+ }
+}
+
+SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = rXMLImport.GetTableRowCellElemTokenMap();
+ sal_Bool bTextP(sal_False);
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROW_CELL_P:
+ {
+ bIsEmpty = sal_False;
+ bTextP = sal_True;
+ com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) &&
+ !rXMLImport.GetTables().IsPartOfMatrix(aCellPos.Column, aCellPos.Row))
+ {
+ if (!bHasTextImport)
+ {
+ bIsFirstTextImport = sal_True;
+ bHasTextImport = sal_True;
+ pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
+ }
+ else
+ {
+ // com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (CellExists(aCellPos))
+ {
+ if (bIsFirstTextImport && !rXMLImport.GetRemoveLastChar())
+ {
+ if (pOUTextContent)
+ {
+ SetCursorOnTextImport(*pOUTextContent);
+ pOUTextContent.reset();
+ }
+ else
+ SetCursorOnTextImport(rtl::OUString());
+ rXMLImport.SetRemoveLastChar(sal_True);
+ uno::Reference < text::XTextCursor > xTextCursor(rXMLImport.GetTextImport()->GetCursor());
+ if (xTextCursor.is())
+ {
+ uno::Reference < text::XText > xText (xTextCursor->getText());
+ uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY);
+ if (xText.is() && xTextRange.is())
+ xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, sal_False);
+ }
+ }
+ pContext = rXMLImport.GetTextImport()->CreateTextChildContext(
+ rXMLImport, nPrefix, rLName, xAttrList);
+ bIsFirstTextImport = sal_False;
+ }
+ }
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_TABLE:
+ {
+ const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ rtl::OUString aLocalName;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ sal_uInt16 nAttrPrefix = rXMLImport.GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex( i ), &aLocalName );
+ if ( nAttrPrefix == XML_NAMESPACE_TABLE
+ && IsXMLToken(aLocalName, XML_IS_SUB_TABLE))
+ {
+ bHasSubTable = IsXMLToken(xAttrList->getValueByIndex( i ), XML_TRUE);
+ }
+ }
+ DBG_ASSERT(bHasSubTable, "it should be a subtable");
+ pContext = new ScXMLTableContext( rXMLImport , nPrefix,
+ rLName, xAttrList,
+ sal_True, nMergedCols);
+ nMergedCols = 1;
+ bIsMerged = sal_False;
+ }
+ break;
+ 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, *mxAnnotationData, this);
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
+ {
+ bIsEmpty = sal_False;
+ if (!pDetectiveObjVec)
+ pDetectiveObjVec = new ScMyImpDetectiveObjVec();
+ pContext = new ScXMLDetectiveContext(
+ rXMLImport, nPrefix, rLName, pDetectiveObjVec );
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE:
+ {
+ bIsEmpty = sal_False;
+ if (!pCellRangeSource)
+ pCellRangeSource = new ScMyImpCellRangeSource();
+ pContext = new ScXMLCellRangeSourceContext(
+ rXMLImport, nPrefix, rLName, xAttrList, pCellRangeSource );
+ }
+ break;
+ }
+
+ if (!pContext && !bTextP)
+ {
+ com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
+ if (xShapes.is())
+ {
+ if (aCellPos.Column > MAXCOL)
+ aCellPos.Column = MAXCOL;
+ if (aCellPos.Row > MAXROW)
+ aCellPos.Row = MAXROW;
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get();
+ pTableShapeImport->SetOnTable(sal_False);
+ pTableShapeImport->SetCell(aCellPos);
+ pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
+ rXMLImport, nPrefix, rLName, xAttrList, xShapes);
+ if (pContext)
+ {
+ bIsEmpty = sal_False;
+ rXMLImport.ProgressBarIncrement(sal_False);
+ }
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+sal_Bool ScXMLTableRowCellContext::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
+ table::CellRangeAddress& aCellAddress) const
+{
+ table::CellAddress aCell; // don't need to set the sheet, because every sheet can contain the same count of cells.
+ aCell.Column = nCol;
+ aCell.Row = nRow;
+ if (CellExists(aCell))
+ {
+ uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
+ uno::Reference<sheet::XSpreadsheet> xTable (xMergeSheetCellRange->getSpreadsheet());
+ uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor (xTable->createCursorByRange(xMergeSheetCellRange));
+ if (xMergeSheetCursor.is())
+ {
+ xMergeSheetCursor->collapseToMergedArea();
+ uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
+ if (xMergeCellAddress.is())
+ {
+ aCellAddress = xMergeCellAddress->getRangeAddress();
+ if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
+ aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
+ return sal_False;
+ else
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+void ScXMLTableRowCellContext::DoMerge(const com::sun::star::table::CellAddress& aCellPos,
+ const sal_Int32 nCols, const sal_Int32 nRows)
+{
+ if (CellExists(aCellPos))
+ {
+ uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
+ if ( xCellRange.is() )
+ {
+ // Stored merge range may actually be of a larger extend than what
+ // we support, in which case getCellRangeByPosition() throws
+ // IndexOutOfBoundsException. Do nothing then.
+ try
+ {
+ table::CellRangeAddress aCellAddress;
+ if (IsMerged(xCellRange, aCellPos.Column, aCellPos.Row, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_False);
+ }
+
+ //merge
+ uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn + nCols, aCellAddress.EndRow + nRows), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ }
+ catch ( lang::IndexOutOfBoundsException & )
+ {
+ DBG_ERRORFILE("ScXMLTableRowCellContext::DoMerge: range to be merged larger than what we support");
+ }
+ }
+ }
+}
+
+void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet)
+{
+ if (pContentValidationName)
+ {
+ ScMyImportValidation aValidation;
+ aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
+ if (rXMLImport.GetValidation(*pContentValidationName, aValidation))
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML))), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (aValidation.sErrorMessage.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)), uno::makeAny(aValidation.sErrorMessage));
+ if (aValidation.sErrorTitle.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)), uno::makeAny(aValidation.sErrorTitle));
+ if (aValidation.sImputMessage.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)), uno::makeAny(aValidation.sImputMessage));
+ if (aValidation.sImputTitle.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)), uno::makeAny(aValidation.sImputTitle));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)), uno::makeAny(aValidation.bShowErrorMessage));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)), uno::makeAny(aValidation.bShowImputMessage));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)), uno::makeAny(aValidation.aValidationType));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)), uno::makeAny(aValidation.bIgnoreBlanks));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)), uno::makeAny(aValidation.nShowList));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)), uno::makeAny(aValidation.aAlertStyle));
+ uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY);
+ if (xCondition.is())
+ {
+ xCondition->setFormula1(aValidation.sFormula1);
+ xCondition->setFormula2(aValidation.sFormula2);
+ xCondition->setOperator(aValidation.aOperator);
+ // #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 and formula namespace
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP1)), uno::makeAny(aValidation.sFormulaNmsp1));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP2)), uno::makeAny(aValidation.sFormulaNmsp2));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR1)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar1)));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR2)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar2)));
+ }
+ }
+ xPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML)), uno::makeAny(xPropertySet));
+
+ // For now, any sheet with validity is blocked from stream-copying.
+ // Later, the validation names could be stored along with the style names.
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
+ pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() );
+ }
+ }
+}
+
+void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCellRange>& xCellRange,
+ const table::CellAddress& aCellAddress)
+{
+ if (CellExists(aCellAddress) && pContentValidationName && pContentValidationName->getLength())
+ {
+ sal_Int32 nBottom = aCellAddress.Row + nRepeatedRows - 1;
+ sal_Int32 nRight = aCellAddress.Column + nCellsRepeated - 1;
+ if (nBottom > MAXROW)
+ nBottom = MAXROW;
+ if (nRight > MAXCOL)
+ nRight = MAXCOL;
+ uno::Reference <beans::XPropertySet> xProperties (xCellRange->getCellRangeByPosition(aCellAddress.Column, aCellAddress.Row,
+ nRight, nBottom), uno::UNO_QUERY);
+ if (xProperties.is())
+ SetContentValidation(xProperties);
+ }
+}
+
+void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCell>& xCell)
+{
+ if (pContentValidationName && pContentValidationName->getLength())
+ {
+ uno::Reference <beans::XPropertySet> xProperties (xCell, uno::UNO_QUERY);
+ if (xProperties.is())
+ SetContentValidation(xProperties);
+ }
+}
+
+void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddress)
+{
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if( !pDoc || !mxAnnotationData.get() )
+ return;
+
+ LockSolarMutex();
+
+ ScAddress aPos;
+ ScUnoConversion::FillScAddress( aPos, aCellAddress );
+ ScPostIt* pNote = 0;
+
+ uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes();
+ uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY );
+ sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0;
+
+ DBG_ASSERT( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(),
+ "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" );
+ if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() )
+ {
+ DBG_ASSERT( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" );
+ SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape );
+ DBG_ASSERT( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" );
+
+ /* Try to reuse the drawing object already created (but only if the
+ note is visible, and the object is a caption object). */
+ if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos )
+ {
+ if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
+ {
+ OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" );
+ // create the cell note with the caption object
+ pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, aPos, *pCaption, true );
+ // forget pointer to object (do not create note again below)
+ pObject = 0;
+ }
+ }
+
+ // drawing object has not been used to create a note -> use shape data
+ if( pObject )
+ {
+ // rescue settings from drawing object before the shape is removed
+ ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) );
+ ::std::auto_ptr< OutlinerParaObject > xOutlinerObj;
+ if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() )
+ xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) );
+ Rectangle aCaptionRect;
+ if( mxAnnotationData->mbUseShapePos )
+ aCaptionRect = pObject->GetLogicRect();
+ // remove the shape from the drawing page, this invalidates pObject
+ mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape );
+ pObject = 0;
+ // update current number of existing objects
+ if( xShapesIA.is() )
+ nOldShapeCount = xShapesIA->getCount();
+
+ // an outliner object is required (empty note captions not allowed)
+ if( xOutlinerObj.get() )
+ {
+ // create cell note with all data from drawing object
+ pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, aPos,
+ xItemSet.release(), xOutlinerObj.release(),
+ aCaptionRect, mxAnnotationData->mbShown, false );
+ }
+ }
+ }
+ else if( mxAnnotationData->maSimpleText.getLength() > 0 )
+ {
+ // create note from simple text
+ pNote = ScNoteUtil::CreateNoteFromString( *pDoc, aPos,
+ mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false );
+ }
+
+ // set author and date
+ if( pNote )
+ {
+ double fDate;
+ rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate );
+ SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
+ sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM );
+ String aDate;
+ Color* pColor = 0;
+ Color** ppColor = &pColor;
+ pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor );
+ pNote->SetDate( aDate );
+ pNote->SetAuthor( mxAnnotationData->maAuthor );
+ }
+
+ // register a shape that has been newly created in the ScNoteUtil functions
+ if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) )
+ {
+ uno::Reference< drawing::XShape > xShape;
+ rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
+ }
+
+ // store the style names for stream copying
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, aPos );
+
+ std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin();
+ std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end();
+ while (aIter != aEnd)
+ {
+ pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, aPos, aIter->maSelection );
+ ++aIter;
+ }
+}
+
+// core implementation
+void ScXMLTableRowCellContext::SetDetectiveObj( const table::CellAddress& rPosition )
+{
+ if( CellExists(rPosition) && pDetectiveObjVec && pDetectiveObjVec->size() )
+ {
+ LockSolarMutex();
+ ScDetectiveFunc aDetFunc( rXMLImport.GetDocument(), rPosition.Sheet );
+ uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
+ ScMyImpDetectiveObjVec::iterator aItr(pDetectiveObjVec->begin());
+ ScMyImpDetectiveObjVec::iterator aEndItr(pDetectiveObjVec->end());
+ while(aItr != aEndItr)
+ {
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rPosition );
+ aDetFunc.InsertObject( aItr->eObjType, aScAddress, aItr->aSourceRange, aItr->bHasError );
+ if (xShapesIndex.is())
+ {
+ sal_Int32 nShapes = xShapesIndex->getCount();
+ uno::Reference < drawing::XShape > xShape;
+ rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
+ }
+ ++aItr;
+ }
+ }
+}
+
+// core implementation
+void ScXMLTableRowCellContext::SetCellRangeSource( const table::CellAddress& rPosition )
+{
+ if( CellExists(rPosition) && pCellRangeSource && pCellRangeSource->sSourceStr.getLength() &&
+ pCellRangeSource->sFilterName.getLength() && pCellRangeSource->sURL.getLength() )
+ {
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if (pDoc)
+ {
+ LockSolarMutex();
+ ScRange aDestRange( static_cast<SCCOL>(rPosition.Column), static_cast<SCROW>(rPosition.Row), rPosition.Sheet,
+ static_cast<SCCOL>(rPosition.Column + pCellRangeSource->nColumns - 1),
+ static_cast<SCROW>(rPosition.Row + pCellRangeSource->nRows - 1), rPosition.Sheet );
+ String sFilterName( pCellRangeSource->sFilterName );
+ String sSourceStr( pCellRangeSource->sSourceStr );
+ ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL,
+ sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh );
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, pCellRangeSource->sURL, &sFilterName, &sSourceStr );
+ }
+ }
+}
+
+bool lcl_IsEmptyOrNote( ScDocument* pDoc, const table::CellAddress& rCurrentPos )
+{
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rCurrentPos );
+ ScBaseCell* pCell = pDoc->GetCell( aScAddress );
+ return ( !pCell || pCell->GetCellType() == CELLTYPE_NOTE );
+}
+
+void ScXMLTableRowCellContext::EndElement()
+{
+ if (!bHasSubTable)
+ {
+ if (bHasTextImport && rXMLImport.GetRemoveLastChar())
+ {
+ if (rXMLImport.GetTextImport()->GetCursor().is())
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), rtl::OUString(),
+ sal_True );
+ }
+ rXMLImport.GetTextImport()->ResetCursor();
+ }
+ }
+ table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (aCellPos.Column > 0 && nRepeatedRows > 1)
+ aCellPos.Row -= (nRepeatedRows - 1);
+ uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
+ if (xCellRange.is())
+ {
+ if (bIsMerged)
+ DoMerge(aCellPos, nMergedCols - 1, nMergedRows - 1);
+ if ( !pOUFormula )
+ {
+ ::boost::optional< rtl::OUString > pOUText;
+
+ if(nCellType == util::NumberFormat::TEXT)
+ {
+ if (xLockable.is())
+ xLockable->removeActionLock();
+
+ // #i61702# The formatted text content of xBaseCell / xLockable is invalidated,
+ // so it can't be used after calling removeActionLock (getString always uses the document).
+
+ if (CellExists(aCellPos) && ((nCellsRepeated > 1) || (nRepeatedRows > 1)))
+ {
+ if (!xBaseCell.is())
+ {
+ try
+ {
+ xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row));
+ }
+ catch (lang::IndexOutOfBoundsException&)
+ {
+ DBG_ERRORFILE("It seems here are to many columns or rows");
+ }
+ }
+ uno::Reference <text::XText> xTempText (xBaseCell, uno::UNO_QUERY);
+ if (xTempText.is())
+ {
+ pOUText.reset(xTempText->getString());
+ }
+ }
+ if ( (!pOUTextContent && !pOUText && !pOUTextValue)
+ && ( (pOUTextContent && !pOUTextContent->getLength()) || !pOUTextContent )
+ && ( (pOUText && !pOUText->getLength()) || !pOUText )
+ && ( (pOUTextValue && !pOUTextValue->getLength()) || !pOUTextValue ))
+ bIsEmpty = sal_True;
+ }
+ sal_Bool bWasEmpty = bIsEmpty;
+// uno::Reference <table::XCell> xCell;
+ table::CellAddress aCurrentPos( aCellPos );
+ if ((pContentValidationName && pContentValidationName->getLength()) ||
+ mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource)
+ bIsEmpty = sal_False;
+
+ ScMyTables& rTables = rXMLImport.GetTables();
+ for (sal_Int32 i = 0; i < nCellsRepeated; ++i)
+ {
+ aCurrentPos.Column = aCellPos.Column + i;
+ if (i > 0)
+ rTables.AddColumn(sal_False);
+ if (!bIsEmpty)
+ {
+ for (sal_Int32 j = 0; j < nRepeatedRows; ++j)
+ {
+ aCurrentPos.Row = aCellPos.Row + j;
+ if ((aCurrentPos.Column == 0) && (j > 0))
+ {
+ rTables.AddRow();
+ rTables.AddColumn(sal_False);
+ }
+ if (CellExists(aCurrentPos))
+ {
+ // test - bypass the API
+ // if (xBaseCell.is() && (aCurrentPos == aCellPos))
+ // xCell.set(xBaseCell);
+ // else
+ // {
+ // try
+ // {
+ // xCell.set(xCellRange->getCellByPosition(aCurrentPos.Column, aCurrentPos.Row));
+ // }
+ // catch (lang::IndexOutOfBoundsException&)
+ // {
+ // DBG_ERRORFILE("It seems here are to many columns or rows");
+ // }
+ // }
+
+ // test - bypass the API
+ // if ((!(bIsCovered) || (xCell->getType() == table::CellContentType_EMPTY)))
+ if ((!(bIsCovered) || lcl_IsEmptyOrNote( rXMLImport.GetDocument(), aCurrentPos )))
+ {
+ switch (nCellType)
+ {
+ case util::NumberFormat::TEXT:
+ {
+ sal_Bool bDoIncrement = sal_True;
+ if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row))
+ {
+ LockSolarMutex();
+ // test - bypass the API
+ // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell);
+ // if (pCellObj)
+ // {
+ // if(pOUTextValue && pOUTextValue->getLength())
+ // pCellObj->SetFormulaResultString(*pOUTextValue);
+ // else if (pOUTextContent && pOUTextContent->getLength())
+ // pCellObj->SetFormulaResultString(*pOUTextContent);
+ // else if ( i > 0 && pOUText && pOUText->getLength() )
+ // {
+ // pCellObj->SetFormulaResultString(*pOUText);
+ // }
+ // else
+ // bDoIncrement = sal_False;
+ // }
+ // else
+ // bDoIncrement = sal_False;
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
+ ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress );
+ bDoIncrement = ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA );
+ if ( bDoIncrement )
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if (pOUTextValue && pOUTextValue->getLength())
+ pFCell->SetHybridString( *pOUTextValue );
+ else if (pOUTextContent && pOUTextContent->getLength())
+ pFCell->SetHybridString( *pOUTextContent );
+ else if ( i > 0 && pOUText && pOUText->getLength() )
+ pFCell->SetHybridString( *pOUText );
+ else
+ bDoIncrement = sal_False;
+ }
+ }
+ else
+ {
+ // test - bypass the API
+ // uno::Reference <text::XText> xText (xCell, uno::UNO_QUERY);
+ // if (xText.is())
+ // {
+ // if(pOUTextValue && pOUTextValue->getLength())
+ // xText->setString(*pOUTextValue);
+ // else if (pOUTextContent && pOUTextContent->getLength())
+ // xText->setString(*pOUTextContent);
+ // else if ( i > 0 && pOUText && pOUText->getLength() )
+ // {
+ // xText->setString(*pOUText);
+ // }
+ // else
+ // bDoIncrement = sal_False;
+ // }
+ LockSolarMutex();
+ ScBaseCell* pNewCell = NULL;
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if (pOUTextValue && pOUTextValue->getLength())
+ pNewCell = ScBaseCell::CreateTextCell( *pOUTextValue, pDoc );
+ else if (pOUTextContent && pOUTextContent->getLength())
+ pNewCell = ScBaseCell::CreateTextCell( *pOUTextContent, pDoc );
+ else if ( i > 0 && pOUText && pOUText->getLength() )
+ pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc );
+
+ bDoIncrement = pNewCell != NULL;
+ if ( bDoIncrement )
+ {
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
+ pDoc->PutCell( aScAddress, pNewCell );
+ }
+ }
+ // #i56027# This is about setting simple text, not edit cells,
+ // so ProgressBarIncrement must be called with bEditCell = FALSE.
+ // Formatted text that is put into the cell by the child context
+ // is handled below (bIsEmpty is TRUE then).
+ if (bDoIncrement || bHasTextImport)
+ rXMLImport.ProgressBarIncrement(sal_False);
+ }
+ break;
+ case util::NumberFormat::NUMBER:
+ case util::NumberFormat::PERCENT:
+ case util::NumberFormat::CURRENCY:
+ case util::NumberFormat::TIME:
+ case util::NumberFormat::DATETIME:
+ case util::NumberFormat::LOGICAL:
+ {
+ if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row))
+ {
+ LockSolarMutex();
+ // test - bypass the API
+ // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell);
+ // if (pCellObj)
+ // pCellObj->SetFormulaResultDouble(fValue);
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
+ ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ static_cast<ScFormulaCell*>(pCell)->SetHybridDouble( fValue );
+ }
+ else
+ {
+ // test - bypass the API
+ // xCell->setValue(fValue);
+ LockSolarMutex();
+
+ // #i62435# Initialize the value cell's script type
+ // if the default style's number format is latin-only.
+ // If the cell uses a different format, the script type
+ // will be reset when the style is applied.
+
+ ScBaseCell* pNewCell = new ScValueCell(fValue);
+ if ( rXMLImport.IsLatinDefaultStyle() )
+ pNewCell->SetScriptType( SCRIPTTYPE_LATIN );
+ rXMLImport.GetDocument()->PutCell(
+ sal::static_int_cast<SCCOL>( aCurrentPos.Column ),
+ sal::static_int_cast<SCROW>( aCurrentPos.Row ),
+ sal::static_int_cast<SCTAB>( aCurrentPos.Sheet ),
+ pNewCell );
+ }
+ rXMLImport.ProgressBarIncrement(sal_False);
+ }
+ break;
+ default:
+ {
+ DBG_ERROR("no cell type given");
+ }
+ break;
+ }
+ }
+
+ SetAnnotation(aCurrentPos);
+ SetDetectiveObj( aCurrentPos );
+ SetCellRangeSource( aCurrentPos );
+ }
+ else
+ {
+ if (!bWasEmpty || mxAnnotationData.get())
+ {
+ if (aCurrentPos.Row > MAXROW)
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
+ else
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
+ }
+ }
+ }
+ }
+ else
+ {
+ // #i56027# If the child context put formatted text into the cell,
+ // bIsEmpty is TRUE and ProgressBarIncrement has to be called
+ // with bEditCell = TRUE.
+ if (bHasTextImport)
+ rXMLImport.ProgressBarIncrement(sal_True);
+ if ((i == 0) && (aCellPos.Column == 0))
+ for (sal_Int32 j = 1; j < nRepeatedRows; ++j)
+ {
+ rTables.AddRow();
+ rTables.AddColumn(sal_False);
+ }
+ }
+ }
+ if (nCellsRepeated > 1 || nRepeatedRows > 1)
+ {
+ SetCellProperties(xCellRange, aCellPos); // set now only the validation for the complete range with the given cell as start cell
+ //SetType(xCellRange, aCellPos);
+ SCCOL nStartCol(aCellPos.Column < MAXCOL ? static_cast<SCCOL>(aCellPos.Column) : MAXCOL);
+ SCROW nStartRow(aCellPos.Row < MAXROW ? static_cast<SCROW>(aCellPos.Row) : MAXROW);
+ SCCOL nEndCol(aCellPos.Column + nCellsRepeated - 1 < MAXCOL ? static_cast<SCCOL>(aCellPos.Column + nCellsRepeated - 1) : MAXCOL);
+ SCROW nEndRow(aCellPos.Row + nRepeatedRows - 1 < MAXROW ? static_cast<SCROW>(aCellPos.Row + nRepeatedRows - 1) : MAXROW);
+ ScRange aScRange( nStartCol, nStartRow, aCellPos.Sheet,
+ nEndCol, nEndRow, aCellPos.Sheet );
+ rXMLImport.GetStylesImportHelper()->AddRange(aScRange);
+ }
+ else if (CellExists(aCellPos))
+ {
+ rXMLImport.GetStylesImportHelper()->AddCell(aCellPos);
+
+ // test - bypass the API
+ // SetCellProperties(xCell); // set now only the validation
+ SetCellProperties(xCellRange, aCellPos);
+
+ //SetType(xTempCell);
+ }
+ }
+ else // if ( !pOUFormula )
+ {
+ if (CellExists(aCellPos))
+ {
+ uno::Reference <table::XCell> xCell;
+ try
+ {
+ xCell.set(xCellRange->getCellByPosition(aCellPos.Column , aCellPos.Row));
+ }
+ catch (lang::IndexOutOfBoundsException&)
+ {
+ DBG_ERRORFILE("It seems here are to many columns or rows");
+ }
+ if (xCell.is())
+ {
+ SetCellProperties(xCell); // set now only the validation
+ DBG_ASSERT(((nCellsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
+ rXMLImport.GetStylesImportHelper()->AddCell(aCellPos);
+ if (!bIsMatrix)
+ {
+ LockSolarMutex();
+ ScCellObj* pCellObj =
+ static_cast<ScCellObj*>(ScCellRangesBase::getImplementation(
+ xCell));
+ if (pCellObj)
+ {
+ pCellObj->SetFormulaWithGrammar( pOUFormula->first, pOUFormula->second, eGrammar);
+ if (bFormulaTextResult && pOUTextValue && pOUTextValue->getLength())
+ pCellObj->SetFormulaResultString( *pOUTextValue);
+ else if (fValue != 0.0)
+ pCellObj->SetFormulaResultDouble( fValue);
+ }
+ }
+ else
+ {
+ if (nMatrixCols > 0 && nMatrixRows > 0)
+ {
+ rXMLImport.GetTables().AddMatrixRange(
+ aCellPos.Column, aCellPos.Row,
+ aCellPos.Column + nMatrixCols - 1,
+ aCellPos.Row + nMatrixRows - 1,
+ pOUFormula->first, pOUFormula->second, eGrammar);
+ }
+ }
+ SetAnnotation( aCellPos );
+ SetDetectiveObj( aCellPos );
+ SetCellRangeSource( aCellPos );
+ rXMLImport.ProgressBarIncrement(sal_False);
+ }
+ }
+ else
+ {
+ if (aCellPos.Row > MAXROW)
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
+ else
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
+ }
+
+ } // if ( !pOUFormula )
+ }
+ UnlockSolarMutex();
+ }
+ bIsMerged = sal_False;
+ bHasSubTable = sal_False;
+ nMergedCols = 1;
+ nMergedRows = 1;
+ nCellsRepeated = 1;
+}
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
new file mode 100644
index 000000000000..6a63e785f959
--- /dev/null
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCELLI_HXX
+#define SC_XMLCELLI_HXX
+
+#include <memory>
+#include "XMLDetectiveContext.hxx"
+#include "XMLCellRangeSourceContext.hxx"
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/table/XCell.hpp>
+#include <tools/time.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+
+#include "formula/grammar.hxx"
+#include <boost/optional.hpp>
+
+class ScXMLImport;
+struct ScXMLAnnotationData;
+
+class ScXMLTableRowCellContext : public SvXMLImportContext
+{
+ typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > FormulaWithNamespace;
+ com::sun::star::uno::Reference<com::sun::star::table::XCell> xBaseCell;
+ com::sun::star::uno::Reference<com::sun::star::document::XActionLockable> xLockable;
+ ::boost::optional< rtl::OUString > pOUTextValue;
+ ::boost::optional< rtl::OUString > pOUTextContent;
+ ::boost::optional< FormulaWithNamespace > pOUFormula;
+ rtl::OUString* pContentValidationName;
+ ::std::auto_ptr< ScXMLAnnotationData > mxAnnotationData;
+ ScMyImpDetectiveObjVec* pDetectiveObjVec;
+ ScMyImpCellRangeSource* pCellRangeSource;
+ double fValue;
+ sal_Int32 nMergedRows, nMergedCols;
+ sal_Int32 nMatrixRows, nMatrixCols;
+ sal_Int32 nRepeatedRows;
+ sal_Int32 nCellsRepeated;
+ ScXMLImport& rXMLImport;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_Int16 nCellType;
+ sal_Bool bIsMerged;
+ sal_Bool bIsMatrix;
+ sal_Bool bHasSubTable;
+ sal_Bool bIsCovered;
+ sal_Bool bIsEmpty;
+ sal_Bool bHasTextImport;
+ sal_Bool bIsFirstTextImport;
+ sal_Bool bSolarMutexLocked;
+ sal_Bool bFormulaTextResult;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ sal_Int16 GetCellType(const rtl::OUString& sOUValue) const;
+
+ sal_Bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange,
+ const sal_Int32 nCol, const sal_Int32 nRow,
+ com::sun::star::table::CellRangeAddress& aCellAddress) const;
+ void DoMerge(const com::sun::star::table::CellAddress& aCellPos,
+ const sal_Int32 nCols, const sal_Int32 nRows);
+
+ void SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet);
+ void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCellRange>& xCellRange,
+ const com::sun::star::table::CellAddress& aCellAddress);
+ void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell);
+
+ void LockSolarMutex();
+ void UnlockSolarMutex();
+
+ sal_Bool CellExists(const com::sun::star::table::CellAddress& aCellPos) const
+ {
+ return (aCellPos.Column <= MAXCOL && aCellPos.Row <= MAXROW);
+ }
+
+public:
+
+ ScXMLTableRowCellContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bIsCovered, const sal_Int32 nRepeatedRows );
+
+ virtual ~ScXMLTableRowCellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ inline void SetString(const rtl::OUString& rOUTempText) { pOUTextContent.reset(rOUTempText); }
+ void SetCursorOnTextImport(const rtl::OUString& rOUTempText);
+
+ void SetAnnotation(const ::com::sun::star::table::CellAddress& rPosition );
+ void SetDetectiveObj( const ::com::sun::star::table::CellAddress& rPosition );
+ void SetCellRangeSource( const ::com::sun::star::table::CellAddress& rPosition );
+
+ virtual void EndElement();
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/xmlcoli.cxx b/sc/source/filter/xml/xmlcoli.cxx
new file mode 100644
index 000000000000..6ea5b0192ab2
--- /dev/null
+++ b/sc/source/filter/xml/xmlcoli.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlcoli.hxx"
+#include "xmlimprt.hxx"
+#include "global.hxx"
+#include "xmlstyli.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "olinetab.hxx"
+#include "sheetdata.hxx"
+#include "unonames.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableColContext::ScXMLTableColContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sVisibility(GetXMLToken(XML_VISIBLE))
+{
+ nColCount = 1;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableColAttrTokenMap();
+
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_COL_ATTR_REPEATED:
+ {
+ nColCount = sValue.toInt32();
+ }
+ break;
+ case XML_TOK_TABLE_COL_ATTR_STYLE_NAME:
+ {
+ sStyleName = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_COL_ATTR_VISIBILITY:
+ {
+ sVisibility = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME:
+ {
+ sCellStyleName = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLTableColContext::~ScXMLTableColContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableColContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+/*
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetTableRowElemTokenMap();
+ sal_Bool bHeader = sal_False;
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROW_CELL:
+// if( IsInsertCellPossible() )
+ pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ case XML_TOK_TABLE_ROW_COVERED_CELL:
+// if( IsInsertCellPossible() )
+ pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ }*/
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableColContext::EndElement()
+{
+ ScXMLImport& rXMLImport = GetScImport();
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ sal_Int32 nCurrentColumn = rXMLImport.GetTables().GetCurrentColumn();
+ uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
+ if(xSheet.is())
+ {
+ sal_Int32 nLastColumn(nCurrentColumn + nColCount - 1);
+ if (nLastColumn > MAXCOL)
+ nLastColumn = MAXCOL;
+ if (nCurrentColumn > MAXCOL)
+ nCurrentColumn = MAXCOL;
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet->getCellRangeByPosition(nCurrentColumn, 0, nLastColumn, 0), uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xColumnProperties(xColumnRowRange->getColumns(), uno::UNO_QUERY);
+ if (xColumnProperties.is())
+ {
+ if (sStyleName.getLength())
+ {
+ XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rXMLImport.GetAutoStyles();
+ if ( pStyles )
+ {
+ XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_COLUMN, sStyleName, sal_True);
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xColumnProperties);
+
+ if ( nSheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddColumnStyle( sStyleName, ScAddress( (SCCOL)nCurrentColumn, 0, (SCTAB)nSheet ) );
+ pStyle->SetLastSheet(nSheet);
+ }
+ }
+ }
+ }
+ rtl::OUString sVisible(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLVIS));
+ sal_Bool bValue(sal_True);
+ if (!IsXMLToken(sVisibility, XML_VISIBLE))
+ bValue = sal_False;
+ xColumnProperties->setPropertyValue(sVisible, uno::makeAny(bValue));
+ }
+ }
+ }
+
+ // #i57915# ScXMLImport::SetStyleToRange can't handle empty style names.
+ // The default for a column if there is no attribute is the style "Default" (programmatic API name).
+ if ( !sCellStyleName.getLength() )
+ sCellStyleName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Default" ));
+
+ GetScImport().GetTables().AddColCount(nColCount);
+ GetScImport().GetTables().AddColStyle(nColCount, sCellStyleName);
+}
+
+ScXMLTableColsContext::ScXMLTableColsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempHeader, const sal_Bool bTempGroup) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ nHeaderStartCol(0),
+ nHeaderEndCol(0),
+ nGroupStartCol(0),
+ nGroupEndCol(0),
+ bHeader(bTempHeader),
+ bGroup(bTempGroup),
+ bGroupDisplay(sal_True)
+{
+ // don't have any attributes
+ if (bHeader)
+ nHeaderStartCol = rImport.GetTables().GetCurrentColumn();
+ else if (bGroup)
+ {
+ nGroupStartCol = rImport.GetTables().GetCurrentColumn();
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DISPLAY))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bGroupDisplay = sal_False;
+ }
+ }
+ }
+}
+
+ScXMLTableColsContext::~ScXMLTableColsContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableColsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetTableColsElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_COLS_COL_GROUP:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_True );
+ break;
+ case XML_TOK_TABLE_COLS_HEADER_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, sal_False );
+ break;
+ case XML_TOK_TABLE_COLS_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_False );
+ break;
+ case XML_TOK_TABLE_COLS_COL:
+ pContext = new ScXMLTableColContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableColsContext::EndElement()
+{
+ ScXMLImport& rXMLImport = GetScImport();
+ if (bHeader)
+ {
+ nHeaderEndCol = rXMLImport.GetTables().GetCurrentColumn();
+ nHeaderEndCol--;
+ if (nHeaderStartCol <= nHeaderEndCol)
+ {
+ uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
+ if (xPrintAreas.is())
+ {
+ if (!xPrintAreas->getPrintTitleColumns())
+ {
+ xPrintAreas->setPrintTitleColumns(sal_True);
+ table::CellRangeAddress aColumnHeaderRange;
+ aColumnHeaderRange.StartColumn = nHeaderStartCol;
+ aColumnHeaderRange.EndColumn = nHeaderEndCol;
+ xPrintAreas->setTitleColumns(aColumnHeaderRange);
+ }
+ else
+ {
+ table::CellRangeAddress aColumnHeaderRange(xPrintAreas->getTitleColumns());
+ aColumnHeaderRange.EndColumn = nHeaderEndCol;
+ xPrintAreas->setTitleColumns(aColumnHeaderRange);
+ }
+ }
+ }
+ }
+ else if (bGroup)
+ {
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ nGroupEndCol = rXMLImport.GetTables().GetCurrentColumn();
+ nGroupEndCol--;
+ if (nGroupStartCol <= nGroupEndCol)
+ {
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc)
+ {
+ rXMLImport.LockSolarMutex();
+ ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(static_cast<SCTAB>(nSheet), sal_True);
+ ScOutlineArray* pColArray = pOutlineTable ? pOutlineTable->GetColArray() : NULL;
+ if (pColArray)
+ {
+ sal_Bool bResized;
+ pColArray->Insert(static_cast<SCCOL>(nGroupStartCol), static_cast<SCCOL>(nGroupEndCol), bResized, !bGroupDisplay, sal_True);
+ }
+ rXMLImport.UnlockSolarMutex();
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/xmlcoli.hxx b/sc/source/filter/xml/xmlcoli.hxx
new file mode 100644
index 000000000000..2edb496b4b28
--- /dev/null
+++ b/sc/source/filter/xml/xmlcoli.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCOLI_HXX
+#define SC_XMLCOLI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+class ScXMLTableColContext : public SvXMLImportContext
+{
+ sal_Int32 nColCount;
+ rtl::OUString sStyleName;
+ rtl::OUString sVisibility;
+ rtl::OUString sCellStyleName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableColContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableColContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLTableColsContext : public SvXMLImportContext
+{
+ sal_Int32 nHeaderStartCol;
+ sal_Int32 nHeaderEndCol;
+ sal_Int32 nGroupStartCol;
+ sal_Int32 nGroupEndCol;
+ sal_Bool bHeader;
+ sal_Bool bGroup;
+ sal_Bool bGroupDisplay;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableColsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bHeader, const sal_Bool bGroup);
+
+ virtual ~ScXMLTableColsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlconti.cxx b/sc/source/filter/xml/xmlconti.cxx
new file mode 100644
index 000000000000..3a0f5ef3126e
--- /dev/null
+++ b/sc/source/filter/xml/xmlconti.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlconti.hxx"
+#include "xmlimprt.hxx"
+#include "global.hxx"
+#include "document.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLContentContext::ScXMLContentContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ rtl::OUStringBuffer& sTempValue) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sOUText(),
+ sValue(sTempValue)
+{
+}
+
+ScXMLContentContext::~ScXMLContentContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_S))
+ {
+ sal_Int32 nRepeat(0);
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& sAttrValue(xAttrList->getValueByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrfx = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ if ((nPrfx == XML_NAMESPACE_TEXT) && IsXMLToken(aLocalName, XML_C))
+ nRepeat = sAttrValue.toInt32();
+ }
+ if (nRepeat)
+ for (sal_Int32 j = 0; j < nRepeat; ++j)
+ sOUText.append(static_cast<sal_Unicode>(' '));
+ else
+ sOUText.append(static_cast<sal_Unicode>(' '));
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLContentContext::Characters( const ::rtl::OUString& rChars )
+{
+ sOUText.append(rChars);
+}
+
+void ScXMLContentContext::EndElement()
+{
+ sValue.append(sOUText);
+}
diff --git a/sc/source/filter/xml/xmlconti.hxx b/sc/source/filter/xml/xmlconti.hxx
new file mode 100644
index 000000000000..83151a934d48
--- /dev/null
+++ b/sc/source/filter/xml/xmlconti.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCONTI_HXX
+#define SC_XMLCONTI_HXX
+
+#include <xmloff/xmlimp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+
+class ScXMLContentContext : public SvXMLImportContext
+{
+ rtl::OUStringBuffer sOUText;
+ rtl::OUStringBuffer& sValue;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLContentContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ rtl::OUStringBuffer& sValue);
+
+ virtual ~ScXMLContentContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlcvali.cxx b/sc/source/filter/xml/xmlcvali.cxx
new file mode 100644
index 000000000000..451b085afe9e
--- /dev/null
+++ b/sc/source/filter/xml/xmlcvali.cxx
@@ -0,0 +1,696 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlcvali.hxx"
+#include "xmlimprt.hxx"
+#include "xmlconti.hxx"
+#include "document.hxx"
+#include "XMLConverter.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/XMLEventsImportContext.hxx>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+#include <tools/debug.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
+
+class ScXMLContentValidationContext : public SvXMLImportContext
+{
+ rtl::OUString sName;
+ rtl::OUString sHelpTitle;
+ rtl::OUString sHelpMessage;
+ rtl::OUString sErrorTitle;
+ rtl::OUString sErrorMessage;
+ rtl::OUString sErrorMessageType;
+ rtl::OUString sBaseCellAddress;
+ rtl::OUString sCondition;
+ sal_Int16 nShowList;
+ sal_Bool bAllowEmptyCell;
+ sal_Bool bDisplayHelp;
+ sal_Bool bDisplayError;
+
+ SvXMLImportContextRef xEventContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ com::sun::star::sheet::ValidationAlertStyle GetAlertStyle() const;
+ void SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const;
+ void GetCondition( ScMyImportValidation& rValidation ) const;
+
+public:
+
+ ScXMLContentValidationContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLContentValidationContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetHelpMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const sal_Bool bDisplay);
+ void SetErrorMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const rtl::OUString& sMessageType, const sal_Bool bDisplay);
+ void SetErrorMacro(const sal_Bool bExecute);
+};
+
+class ScXMLHelpMessageContext : public SvXMLImportContext
+{
+ rtl::OUString sTitle;
+ rtl::OUStringBuffer sMessage;
+ sal_Int32 nParagraphCount;
+ sal_Bool bDisplay;
+
+ ScXMLContentValidationContext* pValidationContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLHelpMessageContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pValidationContext);
+
+ virtual ~ScXMLHelpMessageContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLErrorMessageContext : public SvXMLImportContext
+{
+ rtl::OUString sTitle;
+ rtl::OUStringBuffer sMessage;
+ rtl::OUString sMessageType;
+ sal_Int32 nParagraphCount;
+ sal_Bool bDisplay;
+
+ ScXMLContentValidationContext* pValidationContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLErrorMessageContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pValidationContext);
+
+ virtual ~ScXMLErrorMessageContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLErrorMacroContext : public SvXMLImportContext
+{
+ rtl::OUString sName;
+ sal_Bool bExecute;
+
+ ScXMLContentValidationContext* pValidationContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLErrorMacroContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pValidationContext);
+
+ virtual ~ScXMLErrorMacroContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//------------------------------------------------------------------
+
+ScXMLContentValidationsContext::ScXMLContentValidationsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // here are no attributes
+}
+
+ScXMLContentValidationsContext::~ScXMLContentValidationsContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentValidationsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationsElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_CONTENT_VALIDATION:
+ pContext = new ScXMLContentValidationContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLContentValidationsContext::EndElement()
+{
+}
+
+ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ nShowList(sheet::TableValidationVisibility::UNSORTED),
+ bAllowEmptyCell(sal_True),
+ bDisplayHelp(sal_False),
+ bDisplayError(sal_False)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONTENT_VALIDATION_NAME:
+ sName = sValue;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_CONDITION:
+ sCondition = sValue;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS:
+ sBaseCellAddress = sValue;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL:
+ if (IsXMLToken(sValue, XML_FALSE))
+ bAllowEmptyCell = sal_False;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST:
+ {
+ if (IsXMLToken(sValue, XML_NO))
+ {
+ nShowList = sheet::TableValidationVisibility::INVISIBLE;
+ }
+ else if (IsXMLToken(sValue, XML_UNSORTED))
+ {
+ nShowList = sheet::TableValidationVisibility::UNSORTED;
+ }
+ else if (IsXMLToken(sValue, XML_SORTED_ASCENDING))
+ {
+ nShowList = sheet::TableValidationVisibility::SORTEDASCENDING;
+ }
+ }
+ break;
+ }
+ }
+}
+
+ScXMLContentValidationContext::~ScXMLContentValidationContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentValidationContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE:
+ pContext = new ScXMLHelpMessageContext( GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE:
+ pContext = new ScXMLErrorMessageContext( GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO:
+ pContext = new ScXMLErrorMacroContext( GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS:
+ pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName );
+ xEventContext = pContext;
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+sheet::ValidationAlertStyle ScXMLContentValidationContext::GetAlertStyle() const
+{
+ if (IsXMLToken(sErrorMessageType, XML_MACRO))
+ return sheet::ValidationAlertStyle_MACRO;
+ if (IsXMLToken(sErrorMessageType, XML_STOP))
+ return sheet::ValidationAlertStyle_STOP;
+ if (IsXMLToken(sErrorMessageType, XML_WARNING))
+ return sheet::ValidationAlertStyle_WARNING;
+ if (IsXMLToken(sErrorMessageType, XML_INFORMATION))
+ return sheet::ValidationAlertStyle_INFO;
+ // default for unknown
+ return sheet::ValidationAlertStyle_STOP;
+}
+
+void ScXMLContentValidationContext::SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const
+{
+ reGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ if( bHasNmsp )
+ {
+ // the entire attribute contains a namespace: internal namespace not allowed
+ rFormula = rCondition;
+ rFormulaNmsp = rGlobNmsp;
+ reGrammar = eGlobGrammar;
+ }
+ else
+ {
+ // the attribute does not contain a namespace: try to find a namespace of an external grammar
+ GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, reGrammar, rCondition, true );
+ if( reGrammar != FormulaGrammar::GRAM_EXTERNAL )
+ reGrammar = eGlobGrammar;
+ }
+}
+
+void ScXMLContentValidationContext::GetCondition( ScMyImportValidation& rValidation ) const
+{
+ rValidation.aValidationType = sheet::ValidationType_ANY; // #b6343997# default if no condition is given
+ rValidation.aOperator = sheet::ConditionOperator_NONE;
+
+ if( sCondition.getLength() > 0 )
+ {
+ // extract leading namespace from condition string
+ OUString aCondition, aConditionNmsp;
+ FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sCondition );
+ bool bHasNmsp = aCondition.getLength() < sCondition.getLength();
+
+ // parse a condition from the attribute string
+ ScXMLConditionParseResult aParseResult;
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
+
+ /* Check the result. A valid value in aParseResult.meToken implies
+ that the other members of aParseResult are filled with valid data
+ for that token. */
+ bool bSecondaryPart = false;
+ switch( aParseResult.meToken )
+ {
+ case XML_COND_TEXTLENGTH: // condition is 'cell-content-text-length()<operator><expression>'
+ case XML_COND_TEXTLENGTH_ISBETWEEN: // condition is 'cell-content-text-length-is-between(<expression1>,<expression2>)'
+ case XML_COND_TEXTLENGTH_ISNOTBETWEEN: // condition is 'cell-content-text-length-is-not-between(<expression1>,<expression2>)'
+ case XML_COND_ISINLIST: // condition is 'cell-content-is-in-list(<expression>)'
+ rValidation.aValidationType = aParseResult.meValidation;
+ rValidation.aOperator = aParseResult.meOperator;
+ break;
+
+ case XML_COND_ISWHOLENUMBER: // condition is 'cell-content-is-whole-number() and <condition>'
+ case XML_COND_ISDECIMALNUMBER: // condition is 'cell-content-is-decimal-number() and <condition>'
+ case XML_COND_ISDATE: // condition is 'cell-content-is-date() and <condition>'
+ case XML_COND_ISTIME: // condition is 'cell-content-is-time() and <condition>'
+ rValidation.aValidationType = aParseResult.meValidation;
+ bSecondaryPart = true;
+ break;
+
+ default:; // unacceptable or unknown condition
+ }
+
+ /* Parse the following 'and <condition>' part of some conditions. This
+ updates the members of aParseResult that will contain the operands
+ and comparison operator then. */
+ if( bSecondaryPart )
+ {
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+ if( aParseResult.meToken == XML_COND_AND )
+ {
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+ switch( aParseResult.meToken )
+ {
+ case XML_COND_CELLCONTENT: // condition is 'and cell-content()<operator><expression>'
+ case XML_COND_ISBETWEEN: // condition is 'and cell-content-is-between(<expression1>,<expression2>)'
+ case XML_COND_ISNOTBETWEEN: // condition is 'and cell-content-is-not-between(<expression1>,<expression2>)'
+ rValidation.aOperator = aParseResult.meOperator;
+ break;
+ default:; // unacceptable or unknown condition
+ }
+ }
+ }
+
+ // a validation type (date, integer) without a condition isn't possible
+ if( rValidation.aOperator == sheet::ConditionOperator_NONE )
+ rValidation.aValidationType = sheet::ValidationType_ANY;
+
+ // parse the formulas
+ if( rValidation.aValidationType != sheet::ValidationType_ANY )
+ {
+ SetFormula( rValidation.sFormula1, rValidation.sFormulaNmsp1, rValidation.eGrammar1,
+ aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp );
+ SetFormula( rValidation.sFormula2, rValidation.sFormulaNmsp2, rValidation.eGrammar2,
+ aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp );
+ }
+ }
+}
+
+void ScXMLContentValidationContext::EndElement()
+{
+ // #i36650# event-listeners element moved up one level
+ if (xEventContext.Is())
+ {
+ rtl::OUString sOnError(RTL_CONSTASCII_USTRINGPARAM("OnError"));
+ XMLEventsImportContext* pEvents =
+ (XMLEventsImportContext*)&xEventContext;
+ uno::Sequence<beans::PropertyValue> aValues;
+ pEvents->GetEventSequence( sOnError, aValues );
+
+ sal_Int32 nLength = aValues.getLength();
+ for( sal_Int32 i = 0; i < nLength; i++ )
+ {
+ // #i47525# must allow "MacroName" or "Script"
+ if ( aValues[i].Name.equalsAsciiL( "MacroName", sizeof("MacroName")-1 ) ||
+ aValues[i].Name.equalsAsciiL( "Script", sizeof("Script")-1 ) )
+ {
+ aValues[i].Value >>= sErrorTitle;
+ break;
+ }
+ }
+ }
+
+ ScMyImportValidation aValidation;
+ aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
+ aValidation.sName = sName;
+ aValidation.sBaseCellAddress = sBaseCellAddress;
+ aValidation.sImputTitle = sHelpTitle;
+ aValidation.sImputMessage = sHelpMessage;
+ aValidation.sErrorTitle = sErrorTitle;
+ aValidation.sErrorMessage = sErrorMessage;
+ GetCondition( aValidation );
+ aValidation.aAlertStyle = GetAlertStyle();
+ aValidation.bShowErrorMessage = bDisplayError;
+ aValidation.bShowImputMessage = bDisplayHelp;
+ aValidation.bIgnoreBlanks = bAllowEmptyCell;
+ aValidation.nShowList = nShowList;
+ GetScImport().AddValidation(aValidation);
+}
+
+void ScXMLContentValidationContext::SetHelpMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const sal_Bool bDisplay)
+{
+ sHelpTitle = sTitle;
+ sHelpMessage = sMessage;
+ bDisplayHelp = bDisplay;
+}
+
+void ScXMLContentValidationContext::SetErrorMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage,
+ const rtl::OUString& sMessageType, const sal_Bool bDisplay)
+{
+ sErrorTitle = sTitle;
+ sErrorMessage = sMessage;
+ sErrorMessageType = sMessageType;
+ bDisplayError = bDisplay;
+}
+
+void ScXMLContentValidationContext::SetErrorMacro(const sal_Bool bExecute)
+{
+ sErrorMessageType = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("macro"));
+ bDisplayError = bExecute;
+}
+
+ScXMLHelpMessageContext::ScXMLHelpMessageContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pTempValidationContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sTitle(),
+ sMessage(),
+ nParagraphCount(0),
+ bDisplay(sal_False)
+{
+ pValidationContext = pTempValidationContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationHelpMessageAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_HELP_MESSAGE_ATTR_TITLE:
+ sTitle = sValue;
+ break;
+ case XML_TOK_HELP_MESSAGE_ATTR_DISPLAY:
+ bDisplay = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLHelpMessageContext::~ScXMLHelpMessageContext()
+{
+}
+
+SvXMLImportContext *ScXMLHelpMessageContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationMessageElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_P:
+ {
+ if(nParagraphCount)
+ sMessage.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sMessage);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLHelpMessageContext::EndElement()
+{
+ pValidationContext->SetHelpMessage(sTitle, sMessage.makeStringAndClear(), bDisplay);
+}
+
+ScXMLErrorMessageContext::ScXMLErrorMessageContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pTempValidationContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sTitle(),
+ sMessage(),
+ sMessageType(),
+ nParagraphCount(0),
+ bDisplay(sal_False)
+{
+ pValidationContext = pTempValidationContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationErrorMessageAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_ERROR_MESSAGE_ATTR_TITLE:
+ sTitle = sValue;
+ break;
+ case XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE:
+ sMessageType = sValue;
+ break;
+ case XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY:
+ bDisplay = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLErrorMessageContext::~ScXMLErrorMessageContext()
+{
+}
+
+SvXMLImportContext *ScXMLErrorMessageContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationMessageElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_P:
+ {
+ if(nParagraphCount)
+ sMessage.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sMessage);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLErrorMessageContext::EndElement()
+{
+ pValidationContext->SetErrorMessage(sTitle, sMessage.makeStringAndClear(), sMessageType, bDisplay);
+}
+
+ScXMLErrorMacroContext::ScXMLErrorMacroContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pTempValidationContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sName(),
+ bExecute(sal_False)
+{
+ pValidationContext = pTempValidationContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationErrorMacroAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_ERROR_MACRO_ATTR_NAME:
+ sName = sValue;
+ break;
+ case XML_TOK_ERROR_MACRO_ATTR_EXECUTE:
+ bExecute = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLErrorMacroContext::~ScXMLErrorMacroContext()
+{
+}
+
+SvXMLImportContext *ScXMLErrorMacroContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = NULL;
+
+ if ((nPrefix == XML_NAMESPACE_SCRIPT) && IsXMLToken(rLName, XML_EVENTS))
+ {
+ pContext = new XMLEventsImportContext(GetImport(), nPrefix, rLName);
+ }
+ if (!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLErrorMacroContext::EndElement()
+{
+ pValidationContext->SetErrorMacro( bExecute );
+}
diff --git a/sc/source/filter/xml/xmlcvali.hxx b/sc/source/filter/xml/xmlcvali.hxx
new file mode 100644
index 000000000000..226d2e2d91b5
--- /dev/null
+++ b/sc/source/filter/xml/xmlcvali.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCVALI_HXX
+#define SC_XMLCVALI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+
+class ScXMLContentValidationsContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLContentValidationsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLContentValidationsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx
new file mode 100644
index 000000000000..ba107347b46a
--- /dev/null
+++ b/sc/source/filter/xml/xmldpimp.cxx
@@ -0,0 +1,1835 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmldpimp.hxx"
+#include "xmlimprt.hxx"
+#include "xmlfilti.hxx"
+#include "xmlsorti.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "dpshttab.hxx"
+#include "dpsdbtab.hxx"
+#include "attrib.hxx"
+#include "XMLConverter.hxx"
+#include "dpgroup.hxx"
+#include "dpdimsave.hxx"
+#include "rangeutl.hxx"
+#include "dpoutputgeometry.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+//#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XAttributeList;
+using ::rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLDataPilotTablesContext::ScXMLDataPilotTablesContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // has no Attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDataPilotTablesContext::~ScXMLDataPilotTablesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLDataPilotTablesContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTablesElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_TABLE :
+ {
+ pContext = new ScXMLDataPilotTableContext( GetScImport(), nPrefix,
+ rLName, xAttrList);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotTablesContext::EndElement()
+{
+}
+
+ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() :
+ mbVisible(true) {}
+
+ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDoc(GetScImport().GetDocument()),
+ pDPObject(NULL),
+ pDPSave(NULL),
+ pDPDimSaveData(NULL),
+ sDataPilotTableName(),
+ sApplicationData(),
+ sGrandTotal(GetXMLToken(XML_BOTH)),
+ mnRowFieldCount(0),
+ mnColFieldCount(0),
+ mnPageFieldCount(0),
+ mnDataFieldCount(0),
+ bIsNative(sal_True),
+ bIgnoreEmptyRows(sal_False),
+ bIdentifyCategories(sal_False),
+ bTargetRangeAddress(sal_False),
+ bSourceCellRange(sal_False),
+ bShowFilter(sal_True),
+ bDrillDown(sal_True)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_NAME :
+ {
+ sDataPilotTableName = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA :
+ {
+ sApplicationData = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL :
+ {
+ sGrandTotal = sValue;
+ if (IsXMLToken(sValue, XML_BOTH))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = true;
+ }
+ else if (IsXMLToken(sValue, XML_ROW))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = false;
+ }
+ else if (IsXMLToken(sValue, XML_COLUMN))
+ {
+ maRowGrandTotal.mbVisible = false;
+ maColGrandTotal.mbVisible = true;
+ }
+ else
+ {
+ maRowGrandTotal.mbVisible = false;
+ maColGrandTotal.mbVisible = false;
+ }
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS :
+ {
+ bIgnoreEmptyRows = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES :
+ {
+ bIdentifyCategories = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ sal_Int32 nOffset(0);
+ bTargetRangeAddress = ScRangeStringConverter::GetRangeFromString( aTargetRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS :
+ {
+ sButtons = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON :
+ {
+ bShowFilter = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN :
+ {
+ bDrillDown = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+
+ pDPObject = new ScDPObject(pDoc);
+ pDPSave = new ScDPSaveData();
+}
+
+ScXMLDataPilotTableContext::~ScXMLDataPilotTableContext()
+{
+ delete pDPDimSaveData;
+}
+
+SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTableElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL :
+ {
+ pContext = new ScXMLDPSourceSQLContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = SQL;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE :
+ {
+ pContext = new ScXMLDPSourceTableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = TABLE;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY :
+ {
+ pContext = new ScXMLDPSourceQueryContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = QUERY;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE :
+ {
+ pContext = new ScXMLSourceServiceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = SERVICE;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL:
+ {
+ pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE :
+ {
+ pContext = new ScXMLSourceCellRangeContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = CELLRANGE;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD :
+ pContext = new ScXMLDataPilotFieldContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotTableContext::SetButtons()
+{
+ ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter, ScDPOutputGeometry::ODF);
+ aGeometry.setColumnFieldCount(mnColFieldCount);
+ aGeometry.setRowFieldCount(mnRowFieldCount);
+ aGeometry.setPageFieldCount(mnPageFieldCount);
+ aGeometry.setDataFieldCount(mnDataFieldCount);
+
+ OUString sAddress;
+ sal_Int32 nOffset = 0;
+ while( nOffset >= 0 )
+ {
+ ScRangeStringConverter::GetTokenByOffset( sAddress, sButtons, nOffset );
+ if( nOffset >= 0 )
+ {
+ ScAddress aScAddress;
+ sal_Int32 nAddrOffset(0);
+ if (pDoc && ScRangeStringConverter::GetAddressFromString( aScAddress, sAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nAddrOffset ))
+ {
+ ScDPOutputGeometry::FieldType eType = aGeometry.getFieldButtonType(aScAddress);
+
+ sal_Int16 nMFlag = SC_MF_BUTTON;
+ if (eType == ScDPOutputGeometry::Column || eType == ScDPOutputGeometry::Row)
+ nMFlag |= SC_MF_BUTTON_POPUP;
+
+ // Use the cell's string value to see if this field contains a
+ // hidden member. Isn't there a better way? GetString() is
+ // quite expensive...
+ String aCellStr;
+ pDoc->GetString(aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aCellStr);
+ if (maHiddenMemberFields.count(aCellStr))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+
+ pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag);
+ }
+ }
+ }
+
+ if ( pDPObject )
+ pDPObject->RefreshAfterLoad();
+}
+
+void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember)
+{
+ if (pDPSave)
+ {
+ // #91045# if a dimension with that name has already been inserted,
+ // mark the new one as duplicate
+ if ( !pDim->IsDataLayout() &&
+ pDPSave->GetExistingDimensionByName(pDim->GetName()) )
+ pDim->SetDupFlag( TRUE );
+
+ if (!pDim->IsDataLayout())
+ {
+ switch (pDim->GetOrientation())
+ {
+ case sheet::DataPilotFieldOrientation_ROW:
+ ++mnRowFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ ++mnColFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ ++mnPageFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ ++mnDataFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_HIDDEN:
+ default:
+ ;
+ }
+
+ if (bHasHiddenMember)
+ {
+ // the layout name takes priority over the original name,
+ // since this data is used against cell values.
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maHiddenMemberFields.insert(*pLayoutName);
+ else
+ maHiddenMemberFields.insert(pDim->GetName());
+ }
+ }
+ pDPSave->AddDimension(pDim);
+ }
+}
+
+void ScXMLDataPilotTableContext::AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim)
+{
+ if (!pDPDimSaveData)
+ pDPDimSaveData = new ScDPDimensionSaveData();
+ pDPDimSaveData->AddNumGroupDimension(aNumGroupDim);
+}
+
+void ScXMLDataPilotTableContext::AddGroupDim(const ScDPSaveGroupDimension& aGroupDim)
+{
+ if (!pDPDimSaveData)
+ pDPDimSaveData = new ScDPDimensionSaveData();
+ pDPDimSaveData->AddGroupDimension(aGroupDim);
+}
+
+void ScXMLDataPilotTableContext::EndElement()
+{
+ if (bTargetRangeAddress)
+ {
+ pDPObject->SetName(sDataPilotTableName);
+ pDPObject->SetTag(sApplicationData);
+ pDPObject->SetOutRange(aTargetRangeAddress);
+ switch (nSourceType)
+ {
+ case SQL :
+ {
+ ScImportSourceDesc aImportDesc;
+ aImportDesc.aDBName = sDatabaseName;
+ aImportDesc.aObject = sSourceObject;
+ aImportDesc.nType = sheet::DataImportMode_SQL;
+ aImportDesc.bNative = bIsNative;
+ pDPObject->SetImportDesc(aImportDesc);
+ }
+ break;
+ case TABLE :
+ {
+ ScImportSourceDesc aImportDesc;
+ aImportDesc.aDBName = sDatabaseName;
+ aImportDesc.aObject = sSourceObject;
+ aImportDesc.nType = sheet::DataImportMode_TABLE;
+ pDPObject->SetImportDesc(aImportDesc);
+ }
+ break;
+ case QUERY :
+ {
+ ScImportSourceDesc aImportDesc;
+ aImportDesc.aDBName = sDatabaseName;
+ aImportDesc.aObject = sSourceObject;
+ aImportDesc.nType = sheet::DataImportMode_QUERY;
+ pDPObject->SetImportDesc(aImportDesc);
+ }
+ break;
+ case SERVICE :
+ {
+ ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceName, sServiceSourceObject,
+ sServiceUsername, sServicePassword);
+ pDPObject->SetServiceData(aServiceDesk);
+ }
+ break;
+ case CELLRANGE :
+ {
+ if (bSourceCellRange)
+ {
+ ScSheetSourceDesc aSheetDesc;
+ aSheetDesc.aSourceRange = aSourceCellRangeAddress;
+ aSheetDesc.aQueryParam = aSourceQueryParam;
+ pDPObject->SetSheetDesc(aSheetDesc);
+ }
+ }
+ break;
+ }
+
+ pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
+ pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
+ if (maRowGrandTotal.maDisplayName.getLength())
+ // TODO: Right now, we only support one grand total name for both
+ // column and row totals. Take the value from the row total for
+ // now.
+ pDPSave->SetGrandTotalName(maRowGrandTotal.maDisplayName);
+
+ pDPSave->SetIgnoreEmptyRows(bIgnoreEmptyRows);
+ pDPSave->SetRepeatIfEmpty(bIdentifyCategories);
+ pDPSave->SetFilterButton(bShowFilter);
+ pDPSave->SetDrillDown(bDrillDown);
+ if (pDPDimSaveData)
+ pDPSave->SetDimensionData(pDPDimSaveData);
+ pDPObject->SetSaveData(*pDPSave);
+ if (pDoc)
+ {
+ ScDPCollection* pDPCollection = pDoc->GetDPCollection();
+
+ // #i94570# Names have to be unique, or the tables can't be accessed by API.
+ if ( pDPCollection->GetByName(pDPObject->GetName()) )
+ pDPObject->SetName( String() ); // ignore the invalid name, create a new name in AfterXMLLoading
+
+ pDPObject->SetAlive(sal_True);
+ pDPCollection->InsertNewTable(pDPObject);
+ }
+ SetButtons();
+ }
+}
+
+void ScXMLDataPilotTableContext::SetGrandTotal(
+ XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
+{
+ switch (eOrientation)
+ {
+ case XML_BOTH:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_ROW:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_COLUMN:
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ default:
+ ;
+ }
+}
+
+ScXMLDPSourceSQLContext::ScXMLDPSourceSQLContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceSQLAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME :
+ {
+ pDataPilotTable->SetDatabaseName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT :
+ {
+ pDataPilotTable->SetSourceObject(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT :
+ {
+ pDataPilotTable->SetNative(!IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPSourceSQLContext::~ScXMLDPSourceSQLContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPSourceSQLContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPSourceSQLContext::EndElement()
+{
+}
+
+ScXMLDPSourceTableContext::ScXMLDPSourceTableContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME :
+ {
+ pDataPilotTable->SetDatabaseName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME :
+ {
+ pDataPilotTable->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPSourceTableContext::~ScXMLDPSourceTableContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPSourceTableContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPSourceTableContext::EndElement()
+{
+}
+
+ScXMLDPSourceQueryContext::ScXMLDPSourceQueryContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceQueryAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME :
+ {
+ pDataPilotTable->SetDatabaseName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME :
+ {
+ pDataPilotTable->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPSourceQueryContext::~ScXMLDPSourceQueryContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPSourceQueryContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPSourceQueryContext::EndElement()
+{
+}
+
+ScXMLSourceServiceContext::ScXMLSourceServiceContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableSourceServiceAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_SERVICE_ATTR_NAME :
+ {
+ pDataPilotTable->SetServiceName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME :
+ {
+ pDataPilotTable->SetServiceSourceName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME :
+ {
+ pDataPilotTable->SetServiceSourceObject(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME :
+ {
+ pDataPilotTable->SetServiceUsername(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD :
+ {
+ pDataPilotTable->SetServicePassword(sValue);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSourceServiceContext::~ScXMLSourceServiceContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceServiceContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceServiceContext::EndElement()
+{
+}
+
+ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport()
+{
+ return static_cast<ScXMLImport&>(GetImport());
+}
+
+ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName, const Reference<XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mpTableContext(pTableContext),
+ meOrientation(NONE),
+ mbVisible(false)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotGrandTotalAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex(i);
+ const OUString& rAttrValue = xAttrList->getValueByIndex(i);
+
+ OUString aLocalName;
+ USHORT nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
+ switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
+ {
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY:
+ mbVisible = IsXMLToken(rAttrValue, XML_TRUE);
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION:
+ if (IsXMLToken(rAttrValue, XML_BOTH))
+ meOrientation = BOTH;
+ else if (IsXMLToken(rAttrValue, XML_ROW))
+ meOrientation = ROW;
+ else if (IsXMLToken(rAttrValue, XML_COLUMN))
+ meOrientation = COLUMN;
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT:
+ maDisplayName = rAttrValue;
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext()
+{
+}
+
+SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext(
+ USHORT /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return NULL;
+}
+
+void ScXMLDataPilotGrandTotalContext::EndElement()
+{
+ XMLTokenEnum eOrient = XML_NONE;
+ switch (meOrientation)
+ {
+ case BOTH:
+ eOrient = XML_BOTH;
+ break;
+ case ROW:
+ eOrient = XML_ROW;
+ break;
+ case COLUMN:
+ eOrient = XML_COLUMN;
+ break;
+ default:
+ ;
+ }
+ mpTableContext->SetGrandTotal(eOrient, mbVisible, maDisplayName);
+}
+
+ScXMLSourceCellRangeContext::ScXMLSourceCellRangeContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableSourceCellRangeAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS :
+ {
+ ScRange aSourceRangeAddress;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aSourceRangeAddress, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ pDataPilotTable->SetSourceCellRangeAddress(aSourceRangeAddress);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSourceCellRangeContext::~ScXMLSourceCellRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceCellRangeContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTableSourceCellRangeElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER :
+ pContext = new ScXMLDPFilterContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotTable);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceCellRangeContext::EndElement()
+{
+}
+
+ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable),
+ pDim(NULL),
+ fStart(0.0),
+ fEnd(0.0),
+ fStep(0.0),
+ nUsedHierarchy(1),
+ nGroupPart(0),
+ bSelectedPage(sal_False),
+ bIsGroupField(sal_False),
+ bDateValue(sal_False),
+ bAutoStart(sal_False),
+ bAutoEnd(sal_False),
+ mbHasHiddenMember(false)
+{
+ sal_Bool bHasName(sal_False);
+ sal_Bool bDataLayout(sal_False);
+ OUString aDisplayName;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotFieldAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME :
+ {
+ sName = sValue;
+ bHasName = sal_True;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT:
+ {
+ aDisplayName = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD :
+ {
+ bDataLayout = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION :
+ {
+ nFunction = (sal_Int16) ScXMLConverter::GetFunctionFromString( sValue );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION :
+ {
+ nOrientation = (sal_Int16) ScXMLConverter::GetOrientationFromString( sValue );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE :
+ {
+ sSelectedPage = sValue;
+ bSelectedPage = sal_True;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY :
+ {
+ nUsedHierarchy = sValue.toInt32();
+ }
+ break;
+ }
+ }
+ if (bHasName)
+ {
+ pDim = new ScDPSaveDimension(String(sName), bDataLayout);
+ if (aDisplayName.getLength())
+ pDim->SetLayoutName(aDisplayName);
+ }
+}
+
+ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotFieldContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotFieldElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL :
+ pContext = new ScXMLDataPilotLevelContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE :
+ pContext = new ScXMLDataPilotFieldReferenceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS :
+ pContext = new ScXMLDataPilotGroupsContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotFieldContext::AddMember(ScDPSaveMember* pMember)
+{
+ if (pDim)
+ pDim->AddMember(pMember);
+
+ if (!pMember->GetIsVisible())
+ // This member is hidden.
+ mbHasHiddenMember = true;
+}
+
+void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName)
+{
+ if (pDim)
+ pDim->SetSubtotalName(rName);
+}
+
+void ScXMLDataPilotFieldContext::AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName)
+{
+ ScXMLDataPilotGroup aGroup;
+ aGroup.aMembers = rMembers;
+ aGroup.aName = rName;
+ aGroups.push_back(aGroup);
+}
+
+void ScXMLDataPilotFieldContext::EndElement()
+{
+ if (pDim)
+ {
+ pDim->SetUsedHierarchy(nUsedHierarchy);
+ pDim->SetFunction(nFunction);
+ pDim->SetOrientation(nOrientation);
+ if (bSelectedPage)
+ {
+ String sPage(sSelectedPage);
+ pDim->SetCurrentPage(&sPage);
+ }
+ pDataPilotTable->AddDimension(pDim, mbHasHiddenMember);
+ if (bIsGroupField)
+ {
+ ScDPNumGroupInfo aInfo;
+ aInfo.Enable = sal_True;
+ aInfo.DateValues = bDateValue;
+ aInfo.AutoStart = bAutoStart;
+ aInfo.AutoEnd = bAutoEnd;
+ aInfo.Start = fStart;
+ aInfo.End = fEnd;
+ aInfo.Step = fStep;
+ if (sGroupSource.getLength())
+ {
+ ScDPSaveGroupDimension aGroupDim(sGroupSource, sName);
+ if (nGroupPart)
+ aGroupDim.SetDateInfo(aInfo, nGroupPart);
+ else
+ {
+ ::std::vector<ScXMLDataPilotGroup>::const_iterator aItr(aGroups.begin());
+ ::std::vector<ScXMLDataPilotGroup>::const_iterator aEndItr(aGroups.end());
+ while (aItr != aEndItr)
+ {
+ ScDPSaveGroupItem aItem(aItr->aName);
+ ::std::vector<rtl::OUString>::const_iterator aMembersItr(aItr->aMembers.begin());
+ ::std::vector<rtl::OUString>::const_iterator aMembersEndItr(aItr->aMembers.end());
+ while (aMembersItr != aMembersEndItr)
+ {
+ aItem.AddElement(*aMembersItr);
+ ++aMembersItr;
+ }
+ ++aItr;
+ aGroupDim.AddGroupItem(aItem);
+ }
+ }
+ pDataPilotTable->AddGroupDim(aGroupDim);
+ }
+ else //NumGroup
+ {
+ ScDPSaveNumGroupDimension aNumGroupDim(sName, aInfo);
+ if (nGroupPart)
+ aNumGroupDim.SetDateInfo(aInfo, nGroupPart);
+ pDataPilotTable->AddGroupDim(aNumGroupDim);
+ }
+ }
+ }
+}
+
+ScXMLDataPilotFieldReferenceContext::ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldReference aReference;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_NONE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::NONE;
+ else if (IsXMLToken(sValue, XML_MEMBER_DIFFERENCE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE;
+ else if (IsXMLToken(sValue, XML_MEMBER_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_MEMBER_PERCENTAGE_DIFFERENCE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE;
+ else if (IsXMLToken(sValue, XML_RUNNING_TOTAL))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::RUNNING_TOTAL;
+ else if (IsXMLToken(sValue, XML_ROW_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_COLUMN_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_TOTAL_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_INDEX))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::INDEX;
+ }
+ else if (IsXMLToken(aLocalName, XML_FIELD_NAME))
+ {
+ aReference.ReferenceField = sValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_MEMBER_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_NAMED))
+ aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NAMED;
+ else if (IsXMLToken(sValue, XML_PREVIOUS))
+ aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::PREVIOUS;
+ else if (IsXMLToken(sValue, XML_NEXT))
+ aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NEXT;
+ }
+ else if (IsXMLToken(aLocalName, XML_MEMBER_NAME))
+ {
+ aReference.ReferenceItemName = sValue;
+ }
+ }
+ }
+ pDataPilotField->SetFieldReference(aReference);
+}
+
+ScXMLDataPilotFieldReferenceContext::~ScXMLDataPilotFieldReferenceContext()
+{
+}
+
+ScXMLDataPilotLevelContext::ScXMLDataPilotLevelContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotLevelAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY :
+ {
+ pDataPilotField->SetShowEmpty(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDataPilotLevelContext::~ScXMLDataPilotLevelContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotLevelContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotLevelElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS :
+ pContext = new ScXMLDataPilotSubTotalsContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS :
+ pContext = new ScXMLDataPilotMembersContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO :
+ pContext = new ScXMLDataPilotDisplayInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO :
+ pContext = new ScXMLDataPilotSortInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO :
+ pContext = new ScXMLDataPilotLayoutInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotLevelContext::EndElement()
+{
+}
+
+ScXMLDataPilotDisplayInfoContext::ScXMLDataPilotDisplayInfoContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldAutoShowInfo aInfo;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_ENABLED))
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ aInfo.IsEnabled = sal_True;
+ else
+ aInfo.IsEnabled = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_DISPLAY_MEMBER_MODE))
+ {
+ if (IsXMLToken(sValue, XML_FROM_TOP))
+ aInfo.ShowItemsMode = sheet::DataPilotFieldShowItemsMode::FROM_TOP;
+ else if (IsXMLToken(sValue, XML_FROM_BOTTOM))
+ aInfo.ShowItemsMode = sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM;
+ }
+ else if (IsXMLToken(aLocalName, XML_MEMBER_COUNT))
+ {
+ aInfo.ItemCount = sValue.toInt32();
+ }
+ else if (IsXMLToken(aLocalName, XML_DATA_FIELD))
+ {
+ aInfo.DataField = sValue;
+ }
+ }
+ }
+ pDataPilotField->SetAutoShowInfo(aInfo);
+}
+
+ScXMLDataPilotDisplayInfoContext::~ScXMLDataPilotDisplayInfoContext()
+{
+}
+
+ScXMLDataPilotSortInfoContext::ScXMLDataPilotSortInfoContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldSortInfo aInfo;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_ORDER))
+ {
+ if (IsXMLToken(sValue, XML_ASCENDING))
+ aInfo.IsAscending = sal_True;
+ else if (IsXMLToken(sValue, XML_DESCENDING))
+ aInfo.IsAscending = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_SORT_MODE))
+ {
+ if (IsXMLToken(sValue, XML_NONE))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::NONE;
+ else if (IsXMLToken(sValue, XML_MANUAL))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ else if (IsXMLToken(sValue, XML_NAME))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::NAME;
+ else if (IsXMLToken(sValue, XML_DATA))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::DATA;
+ }
+ else if (IsXMLToken(aLocalName, XML_DATA_FIELD))
+ aInfo.Field = sValue;
+ }
+ }
+ pDataPilotField->SetSortInfo(aInfo);
+}
+
+ScXMLDataPilotSortInfoContext::~ScXMLDataPilotSortInfoContext()
+{
+}
+
+ScXMLDataPilotLayoutInfoContext::ScXMLDataPilotLayoutInfoContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldLayoutInfo aInfo;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_ADD_EMPTY_LINES))
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ aInfo.AddEmptyLines = sal_True;
+ else
+ aInfo.AddEmptyLines = sal_False;
+ }
+ else if (IsXMLToken(aLocalName, XML_LAYOUT_MODE))
+ {
+ if (IsXMLToken(sValue, XML_TABULAR_LAYOUT))
+ aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT;
+ else if (IsXMLToken(sValue, XML_OUTLINE_SUBTOTALS_TOP))
+ aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP;
+ else if (IsXMLToken(sValue, XML_OUTLINE_SUBTOTALS_BOTTOM))
+ aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
+ }
+ }
+ }
+ pDataPilotField->SetLayoutInfo(aInfo);}
+
+ScXMLDataPilotLayoutInfoContext::~ScXMLDataPilotLayoutInfoContext()
+{
+}
+
+ScXMLDataPilotSubTotalsContext::ScXMLDataPilotSubTotalsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField),
+ nFunctionCount(0),
+ pFunctions(NULL)
+{
+
+ // has no attributes
+}
+
+ScXMLDataPilotSubTotalsContext::~ScXMLDataPilotSubTotalsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotSubTotalsElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL :
+ pContext = new ScXMLDataPilotSubTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotSubTotalsContext::EndElement()
+{
+ pDataPilotField->SetSubTotals(pFunctions, nFunctionCount);
+ if (maDisplayName.getLength())
+ pDataPilotField->SetSubTotalName(maDisplayName);
+}
+
+void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
+{
+ if (nFunctionCount)
+ {
+ ++nFunctionCount;
+ sal_uInt16* pTemp = new sal_uInt16[nFunctionCount];
+ for (sal_Int16 i = 0; i < nFunctionCount - 1; ++i)
+ pTemp[i] = pFunctions[i];
+ pTemp[nFunctionCount - 1] = nFunction;
+ delete[] pFunctions;
+ pFunctions = pTemp;
+ }
+ else
+ {
+ nFunctionCount = 1;
+ pFunctions = new sal_uInt16[nFunctionCount];
+ pFunctions[0] = nFunction;
+ }
+}
+
+void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName)
+{
+ maDisplayName = rName;
+}
+
+ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotSubTotalsContext* pTempDataPilotSubTotals) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotSubTotals(pTempDataPilotSubTotals)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotSubTotalAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION :
+ {
+ pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>(
+ ScXMLConverter::GetFunctionFromString( sValue ) ) );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT:
+ pDataPilotSubTotals->SetDisplayName(sValue);
+ break;
+ }
+ }
+}
+
+ScXMLDataPilotSubTotalContext::~ScXMLDataPilotSubTotalContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotSubTotalContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotSubTotalContext::EndElement()
+{
+}
+
+ScXMLDataPilotMembersContext::ScXMLDataPilotMembersContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ // has no attributes
+}
+
+ScXMLDataPilotMembersContext::~ScXMLDataPilotMembersContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotMembersContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotMembersElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER :
+ pContext = new ScXMLDataPilotMemberContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotMembersContext::EndElement()
+{
+}
+
+ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField),
+ bDisplay( sal_True ),
+ bDisplayDetails( sal_True ),
+ bHasName( sal_False )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotMemberAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME :
+ {
+ sName = sValue;
+ bHasName = sal_True;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT:
+ {
+ maDisplayName = sValue;
+ }
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY :
+ {
+ bDisplay = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS :
+ {
+ bDisplayDetails = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDataPilotMemberContext::~ScXMLDataPilotMemberContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotMemberContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotMemberContext::EndElement()
+{
+ if (bHasName) // #i53407# don't check sName, empty name is allowed
+ {
+ ScDPSaveMember* pMember = new ScDPSaveMember(String(sName));
+ if (maDisplayName.getLength())
+ pMember->SetLayoutName(maDisplayName);
+ pMember->SetIsVisible(bDisplay);
+ pMember->SetShowDetails(bDisplayDetails);
+ pDataPilotField->AddMember(pMember);
+ }
+}
+
+ScXMLDataPilotGroupsContext::ScXMLDataPilotGroupsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ rtl::OUString sGroupSource;
+ double fStart(0.0);
+ double fEnd(0.0);
+ double fStep(0.0);
+ sal_Int32 nGroupPart(0);
+ sal_Bool bDateValue(sal_False);
+ sal_Bool bAutoStart(sal_True);
+ sal_Bool bAutoEnd(sal_True);
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ (void)nPrefix; //! compare below!
+
+ if (IsXMLToken(aLocalName, XML_SOURCE_FIELD_NAME))
+ sGroupSource = sValue;
+ else if (IsXMLToken(aLocalName, XML_DATE_START))
+ {
+ bDateValue = sal_True;
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoStart = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDateTime(fStart, sValue);
+ bAutoStart = sal_False;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_DATE_END))
+ {
+ bDateValue = sal_True;
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoEnd = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDateTime(fEnd, sValue);
+ bAutoEnd = sal_False;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_START))
+ {
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoStart = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDouble(fStart, sValue);
+ bAutoStart = sal_False;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_END))
+ {
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoEnd = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDouble(fEnd, sValue);
+ bAutoEnd = sal_False;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_STEP))
+ GetScImport().GetMM100UnitConverter().convertDouble(fStep, sValue);
+ else if (IsXMLToken(aLocalName, XML_GROUPED_BY))
+ {
+ if (IsXMLToken(sValue, XML_SECONDS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS;
+ else if (IsXMLToken(sValue, XML_MINUTES))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES;
+ else if (IsXMLToken(sValue, XML_HOURS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::HOURS;
+ else if (IsXMLToken(sValue, XML_DAYS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::DAYS;
+ else if (IsXMLToken(sValue, XML_MONTHS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS;
+ else if (IsXMLToken(sValue, XML_QUARTERS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS;
+ else if (IsXMLToken(sValue, XML_YEARS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::YEARS;
+ }
+ }
+ pDataPilotField->SetGrouping(sGroupSource, fStart, fEnd, fStep, nGroupPart, bDateValue, bAutoStart, bAutoEnd);
+}
+
+ScXMLDataPilotGroupsContext::~ScXMLDataPilotGroupsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotGroupsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_DATA_PILOT_GROUP))
+ pContext = new ScXMLDataPilotGroupContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotGroupsContext::EndElement()
+{
+}
+
+ScXMLDataPilotGroupContext::ScXMLDataPilotGroupContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_NAME))
+ sName = sValue;
+ }
+ }
+}
+
+ScXMLDataPilotGroupContext::~ScXMLDataPilotGroupContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotGroupContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_DATA_PILOT_MEMBER))
+ pContext = new ScXMLDataPilotGroupMemberContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotGroupContext::EndElement()
+{
+ pDataPilotField->AddGroup(aMembers, sName);
+}
+
+ScXMLDataPilotGroupMemberContext::ScXMLDataPilotGroupMemberContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotGroupContext* pTempDataPilotGroup) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotGroup(pTempDataPilotGroup)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_NAME))
+ sName = sValue;
+ }
+ }
+}
+
+ScXMLDataPilotGroupMemberContext::~ScXMLDataPilotGroupMemberContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotGroupMemberContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotGroupMemberContext::EndElement()
+{
+ if (sName.getLength())
+ pDataPilotGroup->AddMember(sName);
+}
diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx
new file mode 100644
index 000000000000..32300138bc3b
--- /dev/null
+++ b/sc/source/filter/xml/xmldpimp.hxx
@@ -0,0 +1,693 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLDPIMP_HXX
+#define SC_XMLDPIMP_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+
+#include "global.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "queryparam.hxx"
+
+#include <hash_set>
+
+class ScXMLImport;
+class ScDPSaveNumGroupDimension;
+class ScDPSaveGroupDimension;
+
+enum ScMySourceType
+{
+ SQL,
+ TABLE,
+ QUERY,
+ SERVICE,
+ CELLRANGE
+};
+
+class ScXMLDataPilotTablesContext : public SvXMLImportContext
+{
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotTablesContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDataPilotTablesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotTableContext : public SvXMLImportContext
+{
+ typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash > StringSet;
+ StringSet maHiddenMemberFields;
+
+ struct GrandTotalItem
+ {
+ ::rtl::OUString maDisplayName;
+ bool mbVisible;
+ GrandTotalItem();
+ };
+ ScDocument* pDoc;
+ ScDPObject* pDPObject;
+ ScDPSaveData* pDPSave;
+ ScDPDimensionSaveData* pDPDimSaveData;
+ GrandTotalItem maRowGrandTotal;
+ GrandTotalItem maColGrandTotal;
+ rtl::OUString sDataPilotTableName;
+ rtl::OUString sApplicationData;
+ rtl::OUString sGrandTotal;
+ rtl::OUString sDatabaseName;
+ rtl::OUString sSourceObject;
+ rtl::OUString sServiceName;
+ rtl::OUString sServiceSourceName;
+ rtl::OUString sServiceSourceObject;
+ rtl::OUString sServiceUsername;
+ rtl::OUString sServicePassword;
+ rtl::OUString sButtons;
+ ScRange aSourceCellRangeAddress;
+ ScRange aTargetRangeAddress;
+ ScRange aFilterSourceRange;
+ ScAddress aFilterOutputPosition;
+ ScQueryParam aSourceQueryParam;
+ ScMySourceType nSourceType;
+ sal_uInt32 mnRowFieldCount;
+ sal_uInt32 mnColFieldCount;
+ sal_uInt32 mnPageFieldCount;
+ sal_uInt32 mnDataFieldCount;
+ sal_Bool bIsNative;
+ sal_Bool bIgnoreEmptyRows;
+ sal_Bool bIdentifyCategories;
+ sal_Bool bUseRegularExpression;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bSkipDuplicates;
+ sal_Bool bFilterCopyOutputData;
+ sal_Bool bTargetRangeAddress;
+ sal_Bool bSourceCellRange;
+ sal_Bool bShowFilter;
+ sal_Bool bDrillDown;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotTableContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDataPilotTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetGrandTotal(::xmloff::token::XMLTokenEnum eOrientation, bool bVisible, const ::rtl::OUString& rDisplayName);
+ void SetDatabaseName(const rtl::OUString& sValue) { sDatabaseName = sValue; }
+ void SetSourceObject(const rtl::OUString& sValue) { sSourceObject = sValue; }
+ void SetNative(const sal_Bool bValue) { bIsNative = bValue; }
+ void SetServiceName(const rtl::OUString& sValue) { sServiceName = sValue; }
+ void SetServiceSourceName(const rtl::OUString& sValue) { sServiceSourceName = sValue; }
+ void SetServiceSourceObject(const rtl::OUString& sValue) { sServiceSourceObject = sValue; }
+ void SetServiceUsername(const rtl::OUString& sValue) { sServiceUsername = sValue; }
+ void SetServicePassword(const rtl::OUString& sValue) { sServicePassword = sValue; }
+ void SetSourceCellRangeAddress(const ScRange& aValue) { aSourceCellRangeAddress = aValue; bSourceCellRange = sal_True; }
+ void SetSourceQueryParam(const ScQueryParam& aValue) { aSourceQueryParam = aValue; }
+// void SetFilterUseRegularExpressions(const sal_Bool bValue) { aSourceQueryParam.bRegExp = bValue; }
+ void SetFilterOutputPosition(const ScAddress& aValue) { aFilterOutputPosition = aValue; }
+ void SetFilterCopyOutputData(const sal_Bool bValue) { bFilterCopyOutputData = bValue; }
+ void SetFilterSourceRange(const ScRange& aValue) { aFilterSourceRange = aValue; }
+// void SetFilterIsCaseSensitive(const sal_Bool bValue) { aSourceQueryParam.bCaseSens = bValue; }
+// void SetFilterSkipDuplicates(const sal_Bool bValue) { aSourceQueryParam.bDuplicate = !bValue; }
+ void AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember);
+ void AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim);
+ void AddGroupDim(const ScDPSaveGroupDimension& aGroupDim);
+ void SetButtons();
+};
+
+class ScXMLDPSourceSQLContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPSourceSQLContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDPSourceSQLContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPSourceTableContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPSourceTableContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDPSourceTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPSourceQueryContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPSourceQueryContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDPSourceQueryContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceServiceContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceServiceContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLSourceServiceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotGrandTotalContext : public SvXMLImportContext
+{
+ enum Orientation { COLUMN, ROW, BOTH, NONE };
+
+ ScXMLImport& GetScImport();
+
+ ScXMLDataPilotTableContext* mpTableContext;
+ ::rtl::OUString maDisplayName;
+ Orientation meOrientation;
+ bool mbVisible;
+
+public:
+ ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, USHORT nPrefix, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext );
+
+ virtual ~ScXMLDataPilotGrandTotalContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceCellRangeContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceCellRangeContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLSourceCellRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+struct ScXMLDataPilotGroup
+{
+ ::std::vector<rtl::OUString> aMembers;
+ rtl::OUString aName;
+};
+
+class ScXMLDataPilotFieldContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+ ScDPSaveDimension* pDim;
+
+ ::std::vector<ScXMLDataPilotGroup> aGroups;
+ rtl::OUString sGroupSource;
+ rtl::OUString sSelectedPage;
+ rtl::OUString sName;
+ double fStart;
+ double fEnd;
+ double fStep;
+ sal_Int32 nUsedHierarchy;
+ sal_Int32 nGroupPart;
+ sal_Int16 nFunction;
+ sal_Int16 nOrientation;
+ sal_Bool bShowEmpty:1;
+ sal_Bool bSelectedPage:1;
+ sal_Bool bIsGroupField:1;
+ sal_Bool bDateValue:1;
+ sal_Bool bAutoStart:1;
+ sal_Bool bAutoEnd:1;
+ bool mbHasHiddenMember:1;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotFieldContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDataPilotFieldContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); }
+ void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); }
+ void AddMember(ScDPSaveMember* pMember);
+ void SetSubTotalName(const ::rtl::OUString& rName);
+ void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); }
+ void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); }
+ void SetSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo& aInfo) { if (pDim) pDim->SetSortInfo(&aInfo); }
+ void SetLayoutInfo(const com::sun::star::sheet::DataPilotFieldLayoutInfo& aInfo) { if (pDim) pDim->SetLayoutInfo(&aInfo); }
+ void SetGrouping(const rtl::OUString& rGroupSource, const double& rStart, const double& rEnd, const double& rStep,
+ sal_Int32 nPart, sal_Bool bDate, sal_Bool bAutoSt, sal_Bool bAutoE)
+ {
+ bIsGroupField = sal_True;
+ sGroupSource = rGroupSource;
+ fStart = rStart;
+ fEnd = rEnd;
+ fStep = rStep;
+ nGroupPart = nPart;
+ bDateValue = bDate;
+ bAutoStart = bAutoSt;
+ bAutoEnd = bAutoE;
+ }
+ void AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName);
+};
+
+class ScXMLDataPilotFieldReferenceContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldReference aReference;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotFieldReferenceContext();
+};
+
+class ScXMLDataPilotLevelContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotLevelContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotLevelContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotDisplayInfoContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldAutoShowInfo aInfo;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotDisplayInfoContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotDisplayInfoContext();
+};
+
+class ScXMLDataPilotSortInfoContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldSortInfo aInfo;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotSortInfoContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotSortInfoContext();
+};
+
+class ScXMLDataPilotLayoutInfoContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldLayoutInfo aInfo;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotLayoutInfoContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotLayoutInfoContext();
+};
+
+class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ sal_Int16 nFunctionCount;
+ sal_uInt16* pFunctions;
+ ::rtl::OUString maDisplayName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotFieldContext* GetDataPilotField() { return pDataPilotField; }
+
+ ScXMLDataPilotSubTotalsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotSubTotalsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+ void AddFunction(sal_Int16 nFunction);
+ void SetDisplayName(const ::rtl::OUString& rName);
+};
+
+class ScXMLDataPilotSubTotalContext : public SvXMLImportContext
+{
+ ScXMLDataPilotSubTotalsContext* pDataPilotSubTotals;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotSubTotalContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotSubTotalsContext* pDataPilotSubTotals);
+
+ virtual ~ScXMLDataPilotSubTotalContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotMembersContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotMembersContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotMembersContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotMemberContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ rtl::OUString sName;
+ rtl::OUString maDisplayName;
+ sal_Bool bDisplay;
+ sal_Bool bDisplayDetails;
+ sal_Bool bHasName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotMemberContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotMemberContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotGroupsContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotGroupsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotGroupsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotGroupContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ rtl::OUString sName;
+ ::std::vector<rtl::OUString> aMembers;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotGroupContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotGroupContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void AddMember(const rtl::OUString& sMember) { aMembers.push_back(sMember); }
+};
+
+class ScXMLDataPilotGroupMemberContext : public SvXMLImportContext
+{
+ ScXMLDataPilotGroupContext* pDataPilotGroup;
+
+ rtl::OUString sName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotGroupMemberContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotGroupContext* pDataPilotGroup);
+
+ virtual ~ScXMLDataPilotGroupMemberContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
new file mode 100644
index 000000000000..c5731dfc28fb
--- /dev/null
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -0,0 +1,991 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmldrani.hxx"
+#include "xmlimprt.hxx"
+#include "xmlfilti.hxx"
+#include "xmlsorti.hxx"
+#include "document.hxx"
+#include "globstr.hrc"
+#include "docuno.hxx"
+#include "dbcolect.hxx"
+#include "datauno.hxx"
+#include "attrib.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <comphelper/extract.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/xml/sax/XLocator.hpp>
+
+#define SC_ENABLEUSERSORTLIST "EnableUserSortList"
+#define SC_USERSORTLISTINDEX "UserSortListIndex"
+#define SC_USERLIST "UserList"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // has no attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLDatabaseRangesContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangesElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATABASE_RANGE :
+ {
+ pContext = new ScXMLDatabaseRangeContext( GetScImport(), nPrefix,
+ rLName, xAttrList);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDatabaseRangesContext::EndElement()
+{
+}
+
+ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sDatabaseRangeName(ScGlobal::GetRscString(STR_DB_NONAME)),
+ aSortSequence(),
+ eOrientation(table::TableOrientation_ROWS),
+ nRefresh(0),
+ nSubTotalsUserListIndex(0),
+ bContainsSort(sal_False),
+ bContainsSubTotal(sal_False),
+ bNative(sal_True),
+ bIsSelection(sal_False),
+ bKeepFormats(sal_False),
+ bMoveCells(sal_False),
+ bStripData(sal_False),
+ bContainsHeader(sal_True),
+ bAutoFilter(sal_False),
+ bSubTotalsBindFormatsToContent(sal_False),
+ bSubTotalsIsCaseSensitive(sal_False),
+ bSubTotalsInsertPageBreaks(sal_False),
+ bSubTotalsSortGroups(sal_False),
+ bSubTotalsEnabledUserList(sal_False),
+ bSubTotalsAscending(sal_True),
+ bFilterCopyOutputData(sal_False),
+ bFilterIsCaseSensitive(sal_False),
+ bFilterSkipDuplicates(sal_False),
+ bFilterUseRegularExpressions(sal_False),
+ bFilterConditionSourceRange(sal_False)
+{
+ nSourceType = sheet::DataImportMode_NONE;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATABASE_RANGE_ATTR_NAME :
+ {
+ sDatabaseRangeName = sValue;
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION :
+ {
+ bIsSelection = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES :
+ {
+ bKeepFormats = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE :
+ {
+ bMoveCells = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA :
+ {
+ bStripData = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION :
+ {
+ if (IsXMLToken(sValue, XML_COLUMN))
+ eOrientation = table::TableOrientation_COLUMNS;
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER :
+ {
+ bContainsHeader = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS :
+ {
+ bAutoFilter = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ sRangeAddress = sValue;
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY :
+ {
+ double fTime;
+ if( SvXMLUnitConverter::convertTime( fTime, sValue ) )
+ nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 );
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLDatabaseRangeContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangeElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATABASE_RANGE_SOURCE_SQL :
+ {
+ pContext = new ScXMLSourceSQLContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_SOURCE_TABLE :
+ {
+ pContext = new ScXMLSourceTableContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_SOURCE_QUERY :
+ {
+ pContext = new ScXMLSourceQueryContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER :
+ {
+ pContext = new ScXMLFilterContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_SORT :
+ {
+ bContainsSort = sal_True;
+ pContext = new ScXMLSortContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES :
+ {
+ bContainsSubTotal = sal_True;
+ pContext = new ScXMLSubTotalRulesContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDatabaseRangeContext::EndElement()
+{
+ if (GetScImport().GetModel().is())
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet( GetScImport().GetModel(), uno::UNO_QUERY );
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc && xPropertySet.is())
+ {
+ uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
+ if (xDatabaseRanges.is())
+ {
+ table::CellRangeAddress aCellRangeAddress;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aCellRangeAddress, sRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ sal_Bool bInsert(sal_True);
+ try
+ {
+ xDatabaseRanges->addNewByName(sDatabaseRangeName, aCellRangeAddress);
+ }
+ catch ( uno::RuntimeException& rRuntimeException )
+ {
+ bInsert = sal_False;
+ rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("DatabaseRange "));
+ sErrorMessage += sDatabaseRangeName;
+ sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" could not be created with the range "));
+ sErrorMessage += sRangeAddress;
+ uno::Sequence<rtl::OUString> aSeq(1);
+ aSeq[0] = sErrorMessage;
+ uno::Reference<xml::sax::XLocator> xLocator;
+ GetScImport().SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rRuntimeException.Message, xLocator);
+ }
+ if (bInsert)
+ {
+ uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
+ if (xDatabaseRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY);
+ if (xDatabaseRangePropertySet.is())
+ {
+ xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM)), uno::makeAny(bKeepFormats));
+ xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS)), uno::makeAny(bMoveCells));
+ xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)), uno::makeAny(bStripData));
+ }
+ uno::Sequence <beans::PropertyValue> aImportDescriptor(xDatabaseRange->getImportDescriptor());
+ sal_Int32 nImportProperties = aImportDescriptor.getLength();
+ for (sal_Int16 i = 0; i < nImportProperties; ++i)
+ {
+ if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME)))
+ {
+ if (sDatabaseName.getLength())
+ {
+ aImportDescriptor[i].Value <<= sDatabaseName;
+ }
+ else
+ {
+ aImportDescriptor[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES));
+ aImportDescriptor[i].Value <<= sConnectionRessource;
+ }
+ }
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ)))
+ aImportDescriptor[i].Value <<= sSourceObject;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
+ aImportDescriptor[i].Value <<= nSourceType;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE)))
+ aImportDescriptor[i].Value <<= bNative;
+ }
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ pDBData->SetImportSelection(bIsSelection);
+ pDBData->SetAutoFilter(bAutoFilter);
+ if (bAutoFilter)
+ pDoc->ApplyFlagsTab( static_cast<SCCOL>(aCellRangeAddress.StartColumn), static_cast<SCROW>(aCellRangeAddress.StartRow),
+ static_cast<SCCOL>(aCellRangeAddress.EndColumn), static_cast<SCROW>(aCellRangeAddress.StartRow),
+ aCellRangeAddress.Sheet, SC_MF_AUTO );
+ ScImportParam aImportParam;
+ ScImportDescriptor::FillImportParam(aImportParam, aImportDescriptor);
+ pDBData->SetImportParam(aImportParam);
+ if (bContainsSort)
+ {
+ sal_uInt32 nOldSize(aSortSequence.getLength());
+ aSortSequence.realloc(nOldSize + 1);
+ beans::PropertyValue aProperty;
+ aProperty.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT));
+ aProperty.Value <<= eOrientation;
+ aSortSequence[nOldSize] = aProperty;
+ ScSortParam aSortParam;
+ ScSortDescriptor::FillSortParam(aSortParam, aSortSequence);
+
+ //#98317#; until now the Fields are relative to the left top edge of the range, but the
+ // core wants to have the absolute position (column/row)
+ SCCOLROW nFieldStart = aSortParam.bByRow ? static_cast<SCCOLROW>(aCellRangeAddress.StartColumn) : static_cast<SCCOLROW>(aCellRangeAddress.StartRow);
+ for (sal_uInt16 i = 0; i < MAXSORT; ++i)
+ {
+ if (aSortParam.bDoSort[i])
+ aSortParam.nField[i] += nFieldStart;
+ }
+
+ pDBData->SetSortParam(aSortParam);
+ }
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ if (xSheetFilterDescriptor.is())
+ {
+ uno::Reference <beans::XPropertySet> xFilterPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY);
+ if (xFilterPropertySet.is())
+ {
+ sal_Bool bOrientation(table::TableOrientation_COLUMNS == eOrientation);
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT)), uno::makeAny(bOrientation));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR)), uno::makeAny(bContainsHeader));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT)), uno::makeAny(bFilterCopyOutputData));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)), uno::makeAny(bFilterIsCaseSensitive));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP)), uno::makeAny(bFilterSkipDuplicates));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX)), uno::makeAny(bFilterUseRegularExpressions));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS)), uno::makeAny(aFilterOutputPosition));
+ }
+ xSheetFilterDescriptor->setFilterFields2(aFilterFields);
+ if (bFilterConditionSourceRange)
+ {
+ ScRange aAdvSource;
+ ScUnoConversion::FillScRange( aAdvSource, aFilterConditionSourceRangeAddress );
+ pDBData->SetAdvancedQuerySource(&aAdvSource);
+ }
+ }
+ if (bContainsSubTotal)
+ {
+ uno::Reference <sheet::XSubTotalDescriptor> xSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor());
+ if (xSubTotalDescriptor.is())
+ {
+ uno::Reference <beans::XPropertySet> xSubTotalPropertySet (xSubTotalDescriptor, uno::UNO_QUERY);
+ if( xSubTotalPropertySet.is())
+ {
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT)), uno::makeAny(bSubTotalsBindFormatsToContent));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ENABLEUSERSORTLIST)), uno::makeAny(bSubTotalsEnabledUserList));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERSORTLISTINDEX)), uno::makeAny(nSubTotalsUserListIndex));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK)), uno::makeAny(bSubTotalsInsertPageBreaks));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)), uno::makeAny(bSubTotalsIsCaseSensitive));
+ }
+ ScSubTotalParam aSubTotalParam;
+ aSubTotalParam.bDoSort = bSubTotalsSortGroups;
+ aSubTotalParam.bAscending = bSubTotalsAscending;
+ aSubTotalParam.bUserDef = bSubTotalsEnabledUserList;
+ aSubTotalParam.nUserIndex = nSubTotalsUserListIndex;
+ pDBData->SetSubTotalParam(aSubTotalParam);
+ std::vector < ScSubTotalRule >::iterator aItr(aSubTotalRules.begin());
+ while (!aSubTotalRules.empty())
+ {
+ xSubTotalDescriptor->addNew(aItr->aSubTotalColumns, aItr->nSubTotalRuleGroupFieldNumber);
+ aItr = aSubTotalRules.erase(aItr);
+ }
+ }
+ }
+ if ( pDBData->HasImportParam() && !pDBData->HasImportSelection() )
+ {
+ pDBData->SetRefreshDelay( nRefresh );
+ pDBData->SetRefreshHandler( pDBCollection->GetRefreshHandler() );
+ pDBData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+ScXMLSourceSQLContext::ScXMLSourceSQLContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceSQLAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME :
+ {
+ sDBName = sValue;
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT :
+ {
+ pDatabaseRangeContext->SetSourceObject(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT :
+ {
+ pDatabaseRangeContext->SetNative(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_SQL);
+}
+
+ScXMLSourceSQLContext::~ScXMLSourceSQLContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceSQLContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ( nPrefix == XML_NAMESPACE_FORM )
+ {
+ if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0))
+ {
+ pContext = new ScXMLConResContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceSQLContext::EndElement()
+{
+ if (sDBName.getLength())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLSourceTableContext::ScXMLSourceTableContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME :
+ {
+ sDBName = sValue;
+ }
+ break;
+ case XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME :
+ {
+ pDatabaseRangeContext->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_TABLE);
+}
+
+ScXMLSourceTableContext::~ScXMLSourceTableContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceTableContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ( nPrefix == XML_NAMESPACE_FORM )
+ {
+ if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0))
+ {
+ pContext = new ScXMLConResContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceTableContext::EndElement()
+{
+ if (sDBName.getLength())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLSourceQueryContext::ScXMLSourceQueryContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceQueryAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME :
+ {
+ sDBName = sValue;
+ }
+ break;
+ case XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME :
+ {
+ pDatabaseRangeContext->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_QUERY);
+}
+
+ScXMLSourceQueryContext::~ScXMLSourceQueryContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceQueryContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ( nPrefix == XML_NAMESPACE_FORM )
+ {
+ if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0))
+ {
+ pContext = new ScXMLConResContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceQueryContext::EndElement()
+{
+ if (sDBName.getLength())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLConResContext::ScXMLConResContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext( pTempDatabaseRangeContext )
+{
+ rtl::OUString sConRes;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ if (nPrefix == XML_NAMESPACE_XLINK)
+ {
+ if (IsXMLToken(aLocalName, XML_HREF))
+ sConRes = sValue;
+ }
+ }
+ if (sConRes.getLength())
+ pDatabaseRangeContext->SetConnectionRessource(sConRes);
+}
+
+ScXMLConResContext::~ScXMLConResContext()
+{
+}
+
+SvXMLImportContext *ScXMLConResContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLConResContext::EndElement()
+{
+}
+
+ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSubTotalRulesAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT :
+ {
+ pDatabaseRangeContext->SetSubTotalsBindFormatsToContent(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ case XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE :
+ {
+ pDatabaseRangeContext->SetSubTotalsIsCaseSensitive(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ case XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE :
+ {
+ pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalRulesContext::~ScXMLSubTotalRulesContext()
+{
+}
+
+SvXMLImportContext *ScXMLSubTotalRulesContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangeSubTotalRulesElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULES_SORT_GROUPS :
+ {
+ pContext = new ScXMLSortGroupsContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ break;
+ case XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE :
+ {
+ pContext = new ScXMLSubTotalRuleContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSubTotalRulesContext::EndElement()
+{
+}
+
+ScXMLSortGroupsContext::ScXMLSortGroupsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ pDatabaseRangeContext->SetSubTotalsSortGroups(sal_True);
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRulesSortGroupsAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE :
+ {
+ if (sValue.getLength() > 8)
+ {
+ rtl::OUString sTemp = sValue.copy(0, 8);
+ if (sTemp.compareToAscii(SC_USERLIST) == 0)
+ {
+ pDatabaseRangeContext->SetSubTotalsEnabledUserList(sal_True);
+ sTemp = sValue.copy(8);
+ pDatabaseRangeContext->SetSubTotalsUserListIndex(static_cast<sal_Int16>(sTemp.toInt32()));
+ }
+ else
+ {
+ //if (IsXMLToken(sValue, XML_AUTOMATIC))
+ //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
+ // is not supported by StarOffice
+ }
+ }
+ else
+ {
+ //if (IsXMLToken(sValue, XML_TEXT))
+ //aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
+ // is not supported by StarOffice
+ //else if (IsXMLToken(sValue, XML_NUMBER))
+ //aSortField.FieldType = util::SortFieldType_NUMERIC;
+ // is not supported by StarOffice
+ }
+ }
+ break;
+ case XML_TOK_SORT_GROUPS_ATTR_ORDER :
+ {
+ if (IsXMLToken(sValue, XML_ASCENDING))
+ pDatabaseRangeContext->SetSubTotalsAscending(sal_True);
+ else
+ pDatabaseRangeContext->SetSubTotalsAscending(sal_False);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSortGroupsContext::~ScXMLSortGroupsContext()
+{
+}
+
+SvXMLImportContext *ScXMLSortGroupsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSortGroupsContext::EndElement()
+{
+}
+
+ScXMLSubTotalRuleContext::ScXMLSubTotalRuleContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRulesSubTotalRuleAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER :
+ {
+ aSubTotalRule.nSubTotalRuleGroupFieldNumber = static_cast<sal_Int16>(sValue.toInt32());
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalRuleContext::~ScXMLSubTotalRuleContext()
+{
+}
+
+SvXMLImportContext *ScXMLSubTotalRuleContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetSubTotalRulesSubTotalRuleElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD :
+ {
+ pContext = new ScXMLSubTotalFieldContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSubTotalRuleContext::EndElement()
+{
+ if (pDatabaseRangeContext)
+ pDatabaseRangeContext->AddSubTotalRule(aSubTotalRule);
+}
+
+ScXMLSubTotalFieldContext::ScXMLSubTotalFieldContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSubTotalRuleContext* pTempSubTotalRuleContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pSubTotalRuleContext(pTempSubTotalRuleContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRuleSubTotalFieldAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER :
+ {
+ sFieldNumber = sValue;
+ }
+ break;
+ case XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION :
+ {
+ sFunction = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalFieldContext::~ScXMLSubTotalFieldContext()
+{
+}
+
+SvXMLImportContext *ScXMLSubTotalFieldContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSubTotalFieldContext::EndElement()
+{
+ sheet::SubTotalColumn aSubTotalColumn;
+ aSubTotalColumn.Column = sFieldNumber.toInt32();
+ aSubTotalColumn.Function = ScXMLConverter::GetFunctionFromString( sFunction );
+ pSubTotalRuleContext->AddSubTotalColumn(aSubTotalColumn);
+}
+
diff --git a/sc/source/filter/xml/xmldrani.hxx b/sc/source/filter/xml/xmldrani.hxx
new file mode 100644
index 000000000000..e170c9eb84c0
--- /dev/null
+++ b/sc/source/filter/xml/xmldrani.hxx
@@ -0,0 +1,362 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLDRANI_HXX
+#define SC_XMLDRANI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/SubTotalColumn.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+
+class ScXMLImport;
+
+class ScXMLDatabaseRangesContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDatabaseRangesContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDatabaseRangesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+struct ScSubTotalRule
+{
+ sal_Int16 nSubTotalRuleGroupFieldNumber;
+ com::sun::star::uno::Sequence <com::sun::star::sheet::SubTotalColumn> aSubTotalColumns;
+};
+
+class ScXMLDatabaseRangeContext : public SvXMLImportContext
+{
+ rtl::OUString sDatabaseRangeName;
+ rtl::OUString sConnectionRessource;
+ rtl::OUString sRangeAddress;
+ rtl::OUString sDatabaseName;
+ rtl::OUString sSourceObject;
+ com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aSortSequence;
+ com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2> aFilterFields;
+ std::vector < ScSubTotalRule > aSubTotalRules;
+ com::sun::star::table::CellAddress aFilterOutputPosition;
+ com::sun::star::table::CellRangeAddress aFilterConditionSourceRangeAddress;
+ com::sun::star::sheet::DataImportMode nSourceType;
+ com::sun::star::table::TableOrientation eOrientation;
+ sal_Int32 nRefresh;
+ sal_Int16 nSubTotalsUserListIndex;
+ sal_Int16 nSubTotalRuleGroupFieldNumber;
+ sal_Bool bContainsSort;
+ sal_Bool bContainsSubTotal;
+ sal_Bool bNative;
+ sal_Bool bIsSelection;
+ sal_Bool bKeepFormats;
+ sal_Bool bMoveCells;
+ sal_Bool bStripData;
+ sal_Bool bContainsHeader;
+ sal_Bool bAutoFilter;
+ sal_Bool bSubTotalsBindFormatsToContent;
+ sal_Bool bSubTotalsIsCaseSensitive;
+ sal_Bool bSubTotalsInsertPageBreaks;
+ sal_Bool bSubTotalsSortGroups;
+ sal_Bool bSubTotalsEnabledUserList;
+ sal_Bool bSubTotalsAscending;
+ sal_Bool bFilterCopyOutputData;
+ sal_Bool bFilterIsCaseSensitive;
+ sal_Bool bFilterSkipDuplicates;
+ sal_Bool bFilterUseRegularExpressions;
+ sal_Bool bFilterConditionSourceRange;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDatabaseRangeContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDatabaseRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetDatabaseName(const rtl::OUString sTempDatabaseName) { sDatabaseName = sTempDatabaseName; }
+ void SetConnectionRessource(const rtl::OUString sTempConRes) { sConnectionRessource = sTempConRes; }
+ void SetSourceObject(const rtl::OUString sTempSourceObject) { sSourceObject = sTempSourceObject; }
+ void SetSourceType(const com::sun::star::sheet::DataImportMode nTempSourceType) { nSourceType = nTempSourceType; }
+ void SetNative(const sal_Bool bTempNative) { bNative = bTempNative; }
+ void SetSubTotalsBindFormatsToContent(const sal_Bool bTemp ) { bSubTotalsBindFormatsToContent = bTemp; }
+ void SetSubTotalsIsCaseSensitive(const sal_Bool bTemp) { bSubTotalsIsCaseSensitive = bTemp; }
+ void SetSubTotalsInsertPageBreaks(const sal_Bool bTemp) { bSubTotalsInsertPageBreaks = bTemp; }
+ void SetSubTotalsEnabledUserList(const sal_Bool bTemp) { bSubTotalsEnabledUserList = bTemp; }
+ void SetSubTotalsUserListIndex(const sal_Int16 nTemp) { nSubTotalsUserListIndex = nTemp; }
+ void SetSubTotalsAscending(const sal_Bool bTemp) { bSubTotalsAscending = bTemp; }
+ void SetSubTotalsSortGroups(const sal_Bool bTemp) { bSubTotalsSortGroups = bTemp; }
+ void AddSubTotalRule(const ScSubTotalRule& rRule) { aSubTotalRules.push_back(rRule); }
+ void SetSortSequence(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& aTempSortSequence) { aSortSequence = aTempSortSequence; }
+ void SetFilterCopyOutputData(const sal_Bool bTemp) { bFilterCopyOutputData = bTemp; }
+ void SetFilterIsCaseSensitive(const sal_Bool bTemp) { bFilterIsCaseSensitive = bTemp; }
+ void SetFilterSkipDuplicates(const sal_Bool bTemp) { bFilterSkipDuplicates = bTemp; }
+ void SetFilterUseRegularExpressions(const sal_Bool bTemp) { bFilterUseRegularExpressions = bTemp; }
+ void SetFilterFields(const com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2>& aTemp) { aFilterFields = aTemp; }
+ void SetFilterOutputPosition(const com::sun::star::table::CellAddress& aTemp) { aFilterOutputPosition = aTemp; }
+ void SetFilterConditionSourceRangeAddress(const com::sun::star::table::CellRangeAddress& aTemp) { aFilterConditionSourceRangeAddress = aTemp;
+ bFilterConditionSourceRange = sal_True; }
+};
+
+class ScXMLSourceSQLContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ rtl::OUString sDBName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceSQLContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSourceSQLContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceTableContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ rtl::OUString sDBName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceTableContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSourceTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceQueryContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ rtl::OUString sDBName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceQueryContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSourceQueryContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLConResContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLConResContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLConResContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSubTotalRulesContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSubTotalRulesContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSubTotalRulesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSortGroupsContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSortGroupsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSortGroupsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSubTotalRuleContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ ScSubTotalRule aSubTotalRule;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSubTotalRuleContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSubTotalRuleContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void AddSubTotalColumn(const com::sun::star::sheet::SubTotalColumn aSubTotalColumn)
+ { aSubTotalRule.aSubTotalColumns.realloc(aSubTotalRule.aSubTotalColumns.getLength() + 1);
+ aSubTotalRule.aSubTotalColumns[aSubTotalRule.aSubTotalColumns.getLength() - 1] = aSubTotalColumn; }
+};
+
+class ScXMLSubTotalFieldContext : public SvXMLImportContext
+{
+ ScXMLSubTotalRuleContext* pSubTotalRuleContext;
+ rtl::OUString sFieldNumber;
+ rtl::OUString sFunction;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSubTotalFieldContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSubTotalRuleContext* pSubTotalRuleContext);
+
+ virtual ~ScXMLSubTotalFieldContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
new file mode 100644
index 000000000000..ca5403e3b18d
--- /dev/null
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -0,0 +1,4611 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+
+#include "xmlexprt.hxx"
+#include "XMLConverter.hxx"
+#include "xmlstyle.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+#include "olinetab.hxx"
+#include "cellsuno.hxx"
+#include "cell.hxx"
+#include "rangenam.hxx"
+#include "XMLTableMasterPageExport.hxx"
+#include "drwlayer.hxx"
+#include "XMLExportDataPilot.hxx"
+#include "XMLExportDatabaseRanges.hxx"
+#include "XMLExportDDELinks.hxx"
+#include "XMLExportIterator.hxx"
+#include "XMLColumnRowGroupExport.hxx"
+#include "XMLStylesExportHelper.hxx"
+#include "XMLChangeTrackingExportHelper.hxx"
+#include "sheetdata.hxx"
+#include "docoptio.hxx"
+#include "XMLExportSharedData.hxx"
+#include "chgviset.hxx"
+#include "docuno.hxx"
+#include "textuno.hxx"
+#include "chartlis.hxx"
+#include "unoguard.hxx"
+#include "scitems.hxx"
+#include "docpool.hxx"
+#include "userdat.hxx"
+#include "dociter.hxx"
+#include "chgtrack.hxx"
+#include "rangeutl.hxx"
+#include "convuno.hxx"
+#include "postit.hxx"
+#include "externalrefmgr.hxx"
+#include "editutil.hxx"
+#include "tabprotection.hxx"
+
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/txtparae.hxx>
+#include <xmloff/xmlcnitm.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/XMLEventExport.hxx>
+
+#include <rtl/ustring.hxx>
+
+#include <tools/debug.hxx>
+#include "tools/color.hxx"
+#include <rtl/math.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/unoshape.hxx>
+#include <comphelper/extract.hxx>
+#include <editeng/eeitem.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XAreaLinks.hpp>
+#include <com/sun/star/sheet/XAreaLink.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/sheet/XLabelRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+#include <com/sun/star/form/XFormsSupplier2.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+#include "XMLCodeNameProvider.hxx"
+
+#include <sfx2/objsh.hxx>
+
+#include <vector>
+
+//! not found in unonames.hxx
+#define SC_STANDARDFORMAT "StandardFormat"
+#define SC_LAYERID "LayerID"
+
+#define SC_DEFAULT_TABLE_COUNT 3
+#define SC_VIEWCHANGES_COUNT 13
+#define SC_SHOW_CHANGES 0
+#define SC_SHOW_ACCEPTED_CHANGES 1
+#define SC_SHOW_REJECTED_CHANGES 2
+#define SC_SHOW_CHANGES_BY_DATETIME 3
+#define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
+#define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
+#define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
+#define SC_SHOW_CHANGES_BY_AUTHOR 7
+#define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
+#define SC_SHOW_CHANGES_BY_COMMENT 9
+#define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
+#define SC_SHOW_CHANGES_BY_RANGES 11
+#define SC_SHOW_CHANGES_BY_RANGES_LIST 12
+
+using namespace rtl;
+using namespace formula;
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::std::vector;
+using ::com::sun::star::uno::UNO_QUERY;
+
+//----------------------------------------------------------------------------
+
+namespace
+{
+OUString lcl_RangeSequenceToString(
+ const uno::Sequence< OUString > & rRanges,
+ const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter )
+{
+ OUStringBuffer aResult;
+ const sal_Int32 nMaxIndex( rRanges.getLength() - 1 );
+ const sal_Unicode cSep( sal_Char(' '));
+ for( sal_Int32 i=0; i<=nMaxIndex; ++i )
+ {
+ OUString aRange( rRanges[i] );
+ if( xFormatConverter.is())
+ aRange = xFormatConverter->convertRangeToXML( aRange );
+ aResult.append( aRange );
+ if( i < nMaxIndex )
+ aResult.append( cSep );
+ }
+ return aResult.makeStringAndClear();
+}
+
+OUString lcl_GetRawString( ScDocument* pDoc, const ScAddress& rPos )
+{
+ // return text/edit cell string content, with line feeds in edit cells
+
+ String aVal; // document uses tools-strings
+ if (pDoc)
+ {
+ ScBaseCell* pCell = pDoc->GetCell( rPos );
+ if (pCell)
+ {
+ CellType eType = pCell->GetCellType();
+ if ( eType == CELLTYPE_STRING )
+ static_cast<ScStringCell*>(pCell)->GetString(aVal); // string cell: content
+ else if ( eType == CELLTYPE_EDIT )
+ {
+ // edit cell: text with line breaks
+ const EditTextObject* pData = static_cast<ScEditCell*>(pCell)->GetData();
+ if (pData)
+ {
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ aVal = rEngine.GetText( LINEEND_LF );
+ }
+ }
+ }
+ }
+ return aVal;
+}
+} // anonymous namespace
+
+//----------------------------------------------------------------------------
+
+OUString SAL_CALL ScXMLOOoExport_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_getImplementationName() );
+ return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_ALL);
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_ALL );
+}
+
+OUString SAL_CALL ScXMLOOoExport_Meta_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLMetaExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Meta_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Meta_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_META);
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_META );
+}
+
+OUString SAL_CALL ScXMLOOoExport_Styles_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLStylesExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Styles_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Styles_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLOOoExport_Content_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLContentExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Content_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Content_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLOOoExport_Settings_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLSettingsExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Settings_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Settings_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_SETTINGS);
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_SETTINGS );
+}
+
+// Oasis Filter
+
+OUString SAL_CALL ScXMLOasisExport_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_ALL|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Meta_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Meta_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Meta_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_META|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Styles_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Styles_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Styles_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Content_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Content_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Content_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Settings_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Settings_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Settings_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_SETTINGS|EXPORT_OASIS);
+}
+//----------------------------------------------------------------------------
+
+class ScXMLShapeExport : public XMLShapeExport
+{
+public:
+ ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {}
+ ~ScXMLShapeExport();
+
+ /** is called before a shape element for the given XShape is exported */
+ virtual void onExport( const uno::Reference < drawing::XShape >& xShape );
+};
+
+ScXMLShapeExport::~ScXMLShapeExport()
+{
+}
+
+void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape )
+{
+ uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
+ if( xShapeProp.is() )
+ {
+ sal_Int16 nLayerID = 0;
+ if( (xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ))) >>= nLayerID) && (nLayerID == SC_LAYER_BACK) )
+ GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+sal_Int16 ScXMLExport::GetFieldUnit()
+{
+ com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xProperties(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" )) ),
+ com::sun::star::uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ sal_Int16 nFieldUnit = 0;
+ if (xProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Metric"))) >>= nFieldUnit)
+ return nFieldUnit;
+ }
+ return 0;
+}
+
+
+// #110680#
+ScXMLExport::ScXMLExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nExportFlag)
+: SvXMLExport( xServiceFactory, SvXMLUnitConverter::GetMapUnit(GetFieldUnit()), XML_SPREADSHEET, nExportFlag ),
+ pDoc(NULL),
+ nSourceStreamPos(0),
+ pNumberFormatAttributesExportHelper(NULL),
+ pSharedData(NULL),
+ pColumnStyles(NULL),
+ pRowStyles(NULL),
+ pCellStyles(NULL),
+ pRowFormatRanges(NULL),
+ aTableStyles(),
+ pGroupColumns (NULL),
+ pGroupRows (NULL),
+ pDefaults(NULL),
+ pChartListener(NULL),
+ pCurrentCell(NULL),
+ pMergedRangesContainer(NULL),
+ pValidationsContainer(NULL),
+ pCellsItr(NULL),
+ pChangeTrackingExportHelper(NULL),
+ sLayerID(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID )),
+ sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")),
+ nOpenRow(-1),
+ nProgressCount(0),
+ nCurrentTable(0),
+ bHasRowHeader(sal_False),
+ bRowHeaderOpen(sal_False),
+ mbShowProgress( sal_False )
+{
+ if (getExportFlags() & EXPORT_CONTENT)
+ {
+ pGroupColumns = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP);
+ pGroupRows = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP);
+ pColumnStyles = new ScColumnStyles();
+ pRowStyles = new ScRowStyles();
+ pRowFormatRanges = new ScRowFormatRanges();
+ pMergedRangesContainer = new ScMyMergedRangesContainer();
+ pValidationsContainer = new ScMyValidationsContainer();
+ pCellsItr = new ScMyNotEmptyCellsIterator(*this);
+ pDefaults = new ScMyDefaultStyles();
+ }
+ pCellStyles = new ScFormatRangeStyles();
+
+ // document is not set here - create ScChangeTrackingExportHelper later
+
+ xScPropHdlFactory = new XMLScPropHdlFactory;
+ xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory);
+ xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory);
+ xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesProperties, xScPropHdlFactory);
+ xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesProperties, xScPropHdlFactory);
+ xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper);
+ xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
+ xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper);
+ xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper);
+ xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper);
+
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)),
+ xCellStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)));
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)),
+ xColumnStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX)));
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)),
+ xRowStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX)));
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)),
+ xTableStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX)));
+
+ if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
+ {
+ // This name is reserved for the external ref cache tables. This
+ // should not conflict with user-defined styles since this name is
+ // used for a table style which is not available in the UI.
+ sExternalRefTabStyleName = rtl::OUString::createFromAscii("ta_extref");
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName);
+
+ sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME));
+ sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME));
+ sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED));
+ sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA));
+ sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE));
+ sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE));
+ sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL));
+ sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL));
+ sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN));
+ sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW));
+ sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE));
+ sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
+ }
+}
+
+
+ScXMLExport::~ScXMLExport()
+{
+ if (pGroupColumns)
+ delete pGroupColumns;
+ if (pGroupRows)
+ delete pGroupRows;
+ if (pColumnStyles)
+ delete pColumnStyles;
+ if (pRowStyles)
+ delete pRowStyles;
+ if (pCellStyles)
+ delete pCellStyles;
+ if (pRowFormatRanges)
+ delete pRowFormatRanges;
+ if (pMergedRangesContainer)
+ delete pMergedRangesContainer;
+ if (pValidationsContainer)
+ delete pValidationsContainer;
+ if (pChangeTrackingExportHelper)
+ delete pChangeTrackingExportHelper;
+ if (pChartListener)
+ delete pChartListener;
+ if (pCellsItr)
+ delete pCellsItr;
+ if (pDefaults)
+ delete pDefaults;
+ if (pNumberFormatAttributesExportHelper)
+ delete pNumberFormatAttributesExportHelper;
+}
+
+void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream )
+{
+ xSourceStream = xNewStream;
+
+ if ( xSourceStream.is() )
+ {
+ // make sure it's a plain UTF-8 stream as written by OOo itself
+
+ const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ sal_Int32 nLen = strlen(pXmlHeader);
+
+ uno::Sequence<sal_Int8> aFileStart(nLen);
+ sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen );
+
+ if ( nRead != nLen || rtl_compareMemory( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 )
+ {
+ // invalid - ignore stream, save normally
+ xSourceStream.clear();
+ }
+ else
+ {
+ // keep track of the bytes already read
+ nSourceStreamPos = nRead;
+
+ const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ if (pSheetData)
+ {
+ // add the loaded namespaces to the name space map
+
+ if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) )
+ {
+ // conflicts in the namespaces - ignore the stream, save normally
+ xSourceStream.clear();
+ }
+ }
+ }
+ }
+}
+
+sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const
+{
+ NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt);
+ if (itr == aNumFmtIndexMap.end())
+ return -1;
+
+ return itr->second;
+}
+
+sal_Bool ScXMLExport::HasDrawPages(uno::Reference <sheet::XSpreadsheetDocument>& xDoc)
+{
+ uno::Reference <beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY );
+ return (xDocProps.is() && ::cppu::any2bool( xDocProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_HASDRAWPAGES))) ));
+}
+
+void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount)
+{
+ if (GetModel().is())
+ {
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ nTableCount = xIndex->getCount();
+ if (!pSharedData)
+ CreateSharedData(nTableCount);
+ pCellStyles->AddNewTable(nTableCount - 1);
+ pDoc->InitializeAllNoteCaptions( true );
+ if (HasDrawPages(xSpreadDoc))
+ {
+ rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
+ for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xDrawPageSupplier.is())
+ {
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage());
+ ScMyDrawPage aDrawPage;
+ aDrawPage.bHasForms = sal_False;
+ aDrawPage.xDrawPage.set(xDrawPage);
+ pSharedData->AddDrawPage(aDrawPage, nTable);
+ uno::Reference<container::XIndexAccess> xShapesIndex (xDrawPage, uno::UNO_QUERY);
+ if (xShapesIndex.is())
+ {
+ sal_Int32 nShapes(xShapesIndex->getCount());
+ for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape)
+ {
+ uno::Reference<drawing::XShape> xShape(xShapesIndex->getByIndex(nShape), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
+ if( xShapeProp.is() )
+ {
+ sal_Int16 nLayerID = 0;
+ if( xShapeProp->getPropertyValue(sLayerID) >>= nLayerID )
+ {
+ if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
+ CollectInternalShape( xShape );
+ else
+ {
+ ++nShapesCount;
+ SvxShape* pShapeImp(SvxShape::getImplementation(xShape));
+ if (pShapeImp)
+ {
+ SdrObject *pSdrObj(pShapeImp->GetSdrObject());
+ if (pSdrObj)
+ {
+ if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
+ {
+ if (pDoc)
+ {
+
+ awt::Point aPoint(xShape->getPosition());
+ awt::Size aSize(xShape->getSize());
+ rtl::OUString sType(xShape->getShapeType());
+ Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
+ if ( sType.equals(sCaptionShape) )
+ {
+ awt::Point aRelativeCaptionPoint;
+ xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
+ Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
+ Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
+ aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
+ aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
+ }
+ ScRange aRange(pDoc->GetRange(static_cast<SCTAB>(nTable), aRectangle));
+ ScMyShape aMyShape;
+ aMyShape.aAddress = aRange.aStart;
+ aMyShape.aEndAddress = aRange.aEnd;
+ aMyShape.xShape = xShape;
+ pSharedData->AddNewShape(aMyShape);
+ pSharedData->SetLastColumn(nTable, aRange.aStart.Col());
+ pSharedData->SetLastRow(nTable, aRange.aStart.Row());
+ }
+ }
+ else
+ pSharedData->AddTableShape(nTable, xShape);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ sal_Int32 nRef(nCellCount + (2 * nTableCount) + (2 * nShapesCount));
+ GetProgressBarHelper()->SetReference(nRef);
+ GetProgressBarHelper()->SetValue(0);
+}
+
+void ScXMLExport::CollectShapesAutoStyles(const sal_Int32 nTableCount)
+{
+ // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
+ // it's initialized using this dummy list. The iterator contains shapes
+ // from all sheets, so it can't be declared inside the nTable loop where
+ // it is used.
+ ScMyShapeList aDummyInitList;
+
+ pSharedData->SortShapesContainer();
+ pSharedData->SortNoteShapes();
+ const ScMyShapeList* pShapeList(NULL);
+ ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end();
+ if (pSharedData->GetShapesContainer())
+ {
+ pShapeList = pSharedData->GetShapesContainer()->GetShapes();
+ aShapeItr = pShapeList->begin();
+ }
+ if (pSharedData->HasDrawPage())
+ {
+ for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable));
+ uno::Reference<drawing::XShapes> xShapes (xDrawPage, uno::UNO_QUERY);
+
+ if (xShapes.is())
+ {
+ GetShapeExport()->seekShapes(xShapes);
+ uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
+ if( xFormsSupplier.is() && xFormsSupplier->hasForms() )
+ {
+ GetFormExport()->examineForms(xDrawPage);
+ pSharedData->SetDrawPageHasForms(nTable, sal_True);
+ }
+ ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
+ if (pTableShapes)
+ {
+ ScMyTableXShapes::iterator aItr((*pTableShapes)[nTable].begin());
+ ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nTable].end());
+ while (aItr != aEndItr)
+ {
+ GetShapeExport()->collectShapeAutoStyles(*aItr);
+ IncrementProgressBar(sal_False);
+ ++aItr;
+ }
+ }
+ if (pShapeList)
+ {
+ ScMyShapeList::const_iterator aEndItr(pShapeList->end());
+ while (aShapeItr != aEndItr && (static_cast<sal_Int32>(aShapeItr->aAddress.Tab()) == nTable))
+ {
+ GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape);
+ IncrementProgressBar(sal_False);
+ ++aShapeItr;
+ }
+ }
+ const ScMyNoteShapeList* pNoteShapes = NULL;
+ ScMyNoteShapeList::const_iterator aNoteShapeItr;
+ ScMyNoteShapeList::const_iterator aNoteShapeEndItr;
+ if (pSharedData->GetNoteShapes())
+ {
+ pNoteShapes = pSharedData->GetNoteShapes()->GetNotes();
+ if (pNoteShapes)
+ {
+ aNoteShapeItr = pNoteShapes->begin();
+ aNoteShapeEndItr = pNoteShapes->end();
+ }
+ }
+ if (pNoteShapes)
+ {
+ while (aNoteShapeItr != aNoteShapeEndItr)
+ {
+ if (static_cast<sal_Int32>(aNoteShapeItr->aPos.Tab()) == nTable)
+ GetShapeExport()->collectShapeAutoStyles(aNoteShapeItr->xShape);
+ ++aNoteShapeItr;
+ }
+ }
+ }
+ }
+ }
+ pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added
+}
+
+void ScXMLExport::_ExportMeta()
+{
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ GetAutoStylePool()->ClearEntries();
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+
+ uno::Sequence<beans::NamedValue> stats(3);
+ stats[0] = beans::NamedValue(::rtl::OUString::createFromAscii("TableCount"),
+ uno::makeAny(nTableCount));
+ stats[1] = beans::NamedValue(::rtl::OUString::createFromAscii("CellCount"),
+ uno::makeAny(nCellCount));
+ stats[2] = beans::NamedValue(::rtl::OUString::createFromAscii("ObjectCount"),
+ uno::makeAny(nShapesCount));
+
+ // update document statistics at the model
+ uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xPropSup->getDocumentProperties());
+ if (xDocProps.is()) {
+ xDocProps->setDocumentStatistics(stats);
+ }
+
+ // export document properties
+ SvXMLExport::_ExportMeta();
+}
+
+void ScXMLExport::_ExportFontDecls()
+{
+ GetFontAutoStylePool(); // make sure the pool is created
+ SvXMLExport::_ExportFontDecls();
+}
+
+table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
+{
+ table::CellRangeAddress aCellAddress;
+ uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor());
+ uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY);
+ uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
+ if (xUsedArea.is() && xCellAddress.is())
+ {
+ xUsedArea->gotoEndOfUsedArea(sal_True);
+ aCellAddress = xCellAddress->getRangeAddress();
+ }
+ return aCellAddress;
+}
+
+void ScXMLExport::GetAreaLinks( uno::Reference< sheet::XSpreadsheetDocument>& xSpreadDoc,
+ ScMyAreaLinksContainer& rAreaLinks )
+{
+ uno::Reference< beans::XPropertySet > xPropSet( xSpreadDoc, uno::UNO_QUERY );
+ if( !xPropSet.is() ) return;
+
+ uno::Reference< container::XIndexAccess > xLinksIAccess( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AREALINKS ) ) ), uno::UNO_QUERY);
+ if( xLinksIAccess.is() )
+ {
+ const OUString sFilter( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTER ) );
+ const OUString sFilterOpt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTOPT ) );
+ const OUString sURL( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_LINKURL ) );
+ const OUString sRefresh( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_REFDELAY ) );
+
+ sal_Int32 nCount(xLinksIAccess->getCount());
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XAreaLink > xAreaLink(xLinksIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
+ if( xAreaLink.is() )
+ {
+ ScMyAreaLink aAreaLink;
+ aAreaLink.aDestRange = xAreaLink->getDestArea();
+ aAreaLink.sSourceStr = xAreaLink->getSourceArea();
+ uno::Reference< beans::XPropertySet > xLinkProp( xAreaLink, uno::UNO_QUERY );
+ if( xLinkProp.is() )
+ {
+ xLinkProp->getPropertyValue( sFilter ) >>= aAreaLink.sFilter;
+ xLinkProp->getPropertyValue( sFilterOpt ) >>= aAreaLink.sFilterOptions;
+ xLinkProp->getPropertyValue( sURL ) >>= aAreaLink.sURL;
+ xLinkProp->getPropertyValue( sRefresh ) >>= aAreaLink.nRefresh;
+ }
+ rAreaLinks.AddNewAreaLink( aAreaLink );
+ }
+ }
+ }
+ rAreaLinks.Sort();
+}
+
+// core implementation
+void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp )
+{
+ if (pDoc)
+ {
+ ScDetOpList* pOpList(pDoc->GetDetOpList());
+ if( pOpList )
+ {
+ sal_uInt32 nCount(pOpList->Count());
+ for( sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ ScDetOpData* pDetData(pOpList->GetObject( static_cast<USHORT>(nIndex) ));
+ if( pDetData )
+ {
+ const ScAddress& rDetPos = pDetData->GetPos();
+ SCTAB nTab = rDetPos.Tab();
+ if ( nTab < pDoc->GetTableCount() )
+ {
+ rDetOp.AddOperation( pDetData->GetOperation(), rDetPos, nIndex );
+
+ // #123981# cells with detective operations are written even if empty
+ pSharedData->SetLastColumn( nTab, rDetPos.Col() );
+ pSharedData->SetLastRow( nTab, rDetPos.Row() );
+ }
+ }
+ }
+ rDetOp.Sort();
+ }
+ }
+}
+
+void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
+ const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible)
+{
+ CheckAttrList();
+ AddAttribute(sAttrStyleName, *pColumnStyles->GetStyleNameByIndex(nStyleIndex));
+ if (!bIsVisible)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
+ if (nRepeatColumns > 1)
+ {
+ OUString sOUEndCol(OUString::valueOf(static_cast <sal_Int32> (nRepeatColumns)));
+ AddAttribute(sAttrColumnsRepeated, sOUEndCol);
+ }
+ if (nIndex != -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
+ SvXMLElementExport aElemC(*this, sElemCol, sal_True, sal_True);
+}
+
+void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
+ const sal_Int32 nStyleIndex, const sal_Bool bIsVisible)
+{
+ sal_Int32 nRepeat(1);
+ sal_Int32 nPrevIndex((*pDefaults->GetColDefaults())[nColumn].nIndex);
+ sal_Bool bPrevAutoStyle((*pDefaults->GetColDefaults())[nColumn].bIsAutoStyle);
+ for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i)
+ {
+ if (((*pDefaults->GetColDefaults())[i].nIndex != nPrevIndex) ||
+ ((*pDefaults->GetColDefaults())[i].bIsAutoStyle != bPrevAutoStyle))
+ {
+ WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
+ nPrevIndex = (*pDefaults->GetColDefaults())[i].nIndex;
+ bPrevAutoStyle = (*pDefaults->GetColDefaults())[i].bIsAutoStyle;
+ nRepeat = 1;
+ }
+ else
+ ++nRepeat;
+ }
+ WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
+}
+
+void ScXMLExport::OpenHeaderColumn()
+{
+ StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True );
+}
+
+void ScXMLExport::CloseHeaderColumn()
+{
+ EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True);
+}
+
+void ScXMLExport::ExportColumns(const sal_Int32 nTable, const table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader)
+{
+ sal_Int32 nColsRepeated (1);
+ rtl::OUString sParent;
+ sal_Int32 nIndex;
+ sal_Int32 nPrevColumn(0);
+ sal_Bool bPrevIsVisible (sal_True);
+ sal_Bool bWasHeader (sal_False);
+ sal_Bool bIsHeader (sal_False);
+ sal_Bool bIsClosed (sal_True);
+ sal_Bool bIsFirst (sal_False);
+ sal_Int32 nPrevIndex (-1);
+ sal_Int32 nColumn;
+ for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn)
+ {
+ CheckAttrList();
+ sal_Bool bIsVisible(sal_True);
+ nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible);
+
+ bIsHeader = bHasColumnHeader && (aColumnHeaderRange.StartColumn <= nColumn) && (nColumn <= aColumnHeaderRange.EndColumn);
+ if (bIsHeader != bWasHeader)
+ {
+ if (bIsHeader)
+ {
+ bIsFirst = sal_False;
+ if (nColumn > 0)
+ {
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ pGroupColumns->CloseGroups(nColumn - 1);
+ }
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ nPrevColumn = nColumn;
+ nColsRepeated = 1;
+ bIsFirst = sal_True;
+ if(pGroupColumns->IsGroupStart(nColumn))
+ pGroupColumns->OpenGroups(nColumn);
+ OpenHeaderColumn();
+ bWasHeader = sal_True;
+ bIsClosed = sal_False;
+ }
+ else
+ {
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ CloseHeaderColumn();
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ pGroupColumns->CloseGroups(nColumn - 1);
+ if(pGroupColumns->IsGroupStart(nColumn))
+ pGroupColumns->OpenGroups(nColumn);
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ nPrevColumn = nColumn;
+ nColsRepeated = 1;
+ bWasHeader = sal_False;
+ bIsClosed = sal_True;
+ }
+ }
+ else if (nColumn == 0)
+ {
+ if (pGroupColumns->IsGroupStart(nColumn))
+ pGroupColumns->OpenGroups(nColumn);
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ bIsFirst = sal_True;
+ }
+ else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) &&
+ !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1))
+ ++nColsRepeated;
+ else
+ {
+ bIsFirst = sal_False;
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ {
+ if (bIsHeader)
+ CloseHeaderColumn();
+ pGroupColumns->CloseGroups(nColumn - 1);
+ if (bIsHeader)
+ OpenHeaderColumn();
+ }
+ if (pGroupColumns->IsGroupStart(nColumn))
+ {
+ if (bIsHeader)
+ CloseHeaderColumn();
+ pGroupColumns->OpenGroups(nColumn);
+ if (bIsHeader)
+ OpenHeaderColumn();
+ }
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ nPrevColumn = nColumn;
+ nColsRepeated = 1;
+ }
+ }
+ //if (nColsRepeated > 1 || bIsFirst)
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ if (!bIsClosed)
+ CloseHeaderColumn();
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ pGroupColumns->CloseGroups(nColumn - 1);
+}
+
+void ScXMLExport::ExportExternalRefCacheStyles()
+{
+ sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex(
+ "NumberFormat", XML_NAMESPACE_STYLE, OUString::createFromAscii("data-style-name"));
+
+ if (nEntryIndex < 0)
+ // No entry index for the number format is found.
+ return;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ if (!pRefMgr->hasExternalData())
+ // No external reference data cached.
+ return;
+
+ // Export each unique number format used in the external ref cache.
+ vector<sal_uInt32> aNumFmts;
+ pRefMgr->getAllCachedNumberFormats(aNumFmts);
+ const OUString aDefaultStyle = OUString::createFromAscii("Default").intern();
+ for (vector<sal_uInt32>::const_iterator itr = aNumFmts.begin(), itrEnd = aNumFmts.end();
+ itr != itrEnd; ++itr)
+ {
+ sal_Int32 nNumFmt = static_cast<sal_Int32>(*itr);
+
+ addDataStyle(nNumFmt);
+
+ uno::Any aVal;
+ aVal <<= nNumFmt;
+ vector<XMLPropertyState> aProps;
+ aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
+ aVal <<= aDefaultStyle;
+ aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
+
+ OUString aName;
+ sal_Int32 nIndex;
+ if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps))
+ {
+ OUString* pTemp(new OUString(aName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex, true))
+ delete pTemp;
+ }
+ else
+ {
+ sal_Bool bIsAuto;
+ nIndex = pCellStyles->GetIndexOfStyleName(
+ aName, OUString::createFromAscii(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX), bIsAuto);
+ }
+
+ // store the number format to index mapping for later use.
+ aNumFmtIndexMap.insert(NumberFormatIndexMap::value_type(nNumFmt, nIndex));
+ }
+}
+
+void ScXMLExport::WriteRowContent()
+{
+ ScMyRowFormatRange aRange;
+ sal_Int32 nIndex(-1);
+#ifdef DBG_UTIL
+ sal_Int32 nPrevCol(0);
+#endif
+ sal_Int32 nCols(0);
+ sal_Int32 nPrevValidationIndex(-1);
+ sal_Bool bIsAutoStyle(sal_True);
+ sal_Bool bIsFirst(sal_True);
+ while (pRowFormatRanges->GetNext(aRange))
+ {
+#ifdef DBG_UTIL
+ DBG_ASSERT(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing");
+#endif
+ if (bIsFirst)
+ {
+ nIndex = aRange.nIndex;
+ nPrevValidationIndex = aRange.nValidationIndex;
+ bIsAutoStyle = aRange.bIsAutoStyle;
+ nCols = aRange.nRepeatColumns;
+ bIsFirst = sal_False;
+#ifdef DBG_UTIL
+ nPrevCol = aRange.nStartColumn;
+#endif
+ }
+ else
+ {
+ if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) ||
+ (aRange.nIndex == nIndex && nIndex == -1)) &&
+ nPrevValidationIndex == aRange.nValidationIndex)
+ nCols += aRange.nRepeatColumns;
+ else
+ {
+ if (nIndex != -1)
+ AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
+ if (nPrevValidationIndex > -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
+ if (nCols > 1)
+ {
+ rtl::OUStringBuffer aBuf;
+ GetMM100UnitConverter().convertNumber(aBuf, nCols);
+ AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
+ }
+ SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
+ nIndex = aRange.nIndex;
+ bIsAutoStyle = aRange.bIsAutoStyle;
+ nCols = aRange.nRepeatColumns;
+ nPrevValidationIndex = aRange.nValidationIndex;
+#ifdef DBG_UTIL
+ nPrevCol = aRange.nStartColumn;
+#endif
+ }
+ }
+ }
+ if (!bIsFirst)
+ {
+ table::CellAddress aCellAddress;
+ if (nIndex != -1)
+ AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
+ if (nPrevValidationIndex > -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
+ if (nCols > 1)
+ {
+ rtl::OUStringBuffer aBuf;
+ GetMM100UnitConverter().convertNumber(aBuf, nCols);
+ AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
+ }
+ SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
+ }
+}
+
+void ScXMLExport::WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex,
+ const sal_Int8 nFlag, const sal_Int32 nEqualRows)
+{
+ AddAttribute(sAttrStyleName, *pRowStyles->GetStyleNameByIndex(nIndex));
+ if (nFlag)
+ if (nFlag & CR_HIDDEN)
+ {
+ if (nFlag & CR_FILTERED)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER);
+ else
+ AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
+ }
+ if (nEqualRows > 1)
+ {
+ rtl::OUStringBuffer aBuf;
+ GetMM100UnitConverter().convertNumber(aBuf, nEqualRows);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aBuf.makeStringAndClear());
+ }
+
+ const ScMyDefaultStyleList& rRowDefaults = *pDefaults->GetRowDefaults();
+ if ( nRow >= sal::static_int_cast<sal_Int32>( rRowDefaults.size() ) )
+ {
+ // #123981# used to happen with detective operations - if there are more cases, use the last row's style
+ DBG_ERRORFILE("WriteRowStartTag: not enough defaults");
+ nRow = rRowDefaults.size() - 1;
+ }
+ sal_Int32 nCellStyleIndex(rRowDefaults[nRow].nIndex);
+ if (nCellStyleIndex != -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME,
+ *pCellStyles->GetStyleNameByIndex(nCellStyleIndex,
+ (*pDefaults->GetRowDefaults())[nRow].bIsAutoStyle));
+ StartElement( sElemRow, sal_True);
+}
+
+void ScXMLExport::OpenHeaderRows()
+{
+ StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
+ bRowHeaderOpen = sal_True;
+}
+
+void ScXMLExport::CloseHeaderRows()
+{
+ EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
+}
+
+void ScXMLExport::OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEqualRows)
+{
+ nOpenRow = nStartRow;
+ if (pGroupRows->IsGroupStart(nStartRow))
+ {
+ if (bHasRowHeader && bRowHeaderOpen)
+ CloseHeaderRows();
+ pGroupRows->OpenGroups(nStartRow);
+ if (bHasRowHeader && bRowHeaderOpen)
+ OpenHeaderRows();
+ }
+ if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.StartRow && nStartRow <= aRowHeaderRange.EndRow)
+ {
+ if (nStartRow == aRowHeaderRange.StartRow)
+ OpenHeaderRows();
+ sal_Int32 nEquals;
+ if (aRowHeaderRange.EndRow < nStartRow + nEqualRows - 1)
+ nEquals = aRowHeaderRange.EndRow - nStartRow + 1;
+ else
+ nEquals = nEqualRows;
+ WriteRowStartTag(nStartRow, nIndex, nFlag, nEquals);
+ nOpenRow = nStartRow + nEquals - 1;
+ if (nEquals < nEqualRows)
+ {
+ CloseRow(nStartRow + nEquals - 1);
+ WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows - nEquals);
+ nOpenRow = nStartRow + nEqualRows - 1;
+ }
+ }
+ else
+ WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows);
+}
+
+void ScXMLExport::OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag,
+ const sal_Int32 nStartRow, const sal_Int32 nEqualRows)
+{
+ OpenNewRow(nIndex, nFlag, nStartRow, nEqualRows);
+ WriteRowContent();
+ CloseRow(nStartRow + nEqualRows - 1);
+ pRowFormatRanges->Clear();
+}
+
+void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow)
+{
+ if (nRepeatRow > 1)
+ {
+ sal_Int32 nPrevIndex(0), nIndex;
+ sal_Int8 nPrevFlag(0);
+ sal_Int8 nFlag(0);
+ sal_Int32 nEqualRows(1);
+ sal_Int32 nEndRow(nStartRow + nRepeatRow);
+ sal_Int32 nRow;
+ for (nRow = nStartRow; nRow < nEndRow; ++nRow)
+ {
+ if (nRow == nStartRow)
+ {
+ nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
+ if (pDoc)
+ nPrevFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
+ }
+ else
+ {
+ nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
+ if (pDoc)
+ nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
+ if (nIndex == nPrevIndex && nFlag == nPrevFlag &&
+ !(bHasRowHeader && ((nRow == aRowHeaderRange.StartRow) || (nRow - 1 == aRowHeaderRange.EndRow))) &&
+ !(pGroupRows->IsGroupStart(nRow)) &&
+ !(pGroupRows->IsGroupEnd(nRow - 1)))
+ ++nEqualRows;
+ else
+ {
+ if (nRow < nEndRow)
+ {
+ ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges);
+ OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
+ delete pRowFormatRanges;
+ pRowFormatRanges = pTempRowFormatRanges;
+ }
+ else
+ OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
+ nEqualRows = 1;
+ nPrevIndex = nIndex;
+ nPrevFlag = nFlag;
+ }
+ }
+ }
+ OpenNewRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
+ }
+ else
+ {
+ sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow);
+ sal_Int8 nFlag(0);
+ if (pDoc)
+ nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nStartRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
+ OpenNewRow(nIndex, nFlag, nStartRow, 1);
+ }
+ nOpenRow = nStartRow + nRepeatRow - 1;
+}
+
+void ScXMLExport::CloseRow(const sal_Int32 nRow)
+{
+ if (nOpenRow > -1)
+ {
+ EndElement(sElemRow, sal_True);
+ if (bHasRowHeader && nRow == aRowHeaderRange.EndRow)
+ {
+ CloseHeaderRows();
+ bRowHeaderOpen = sal_False;
+ }
+ if (pGroupRows->IsGroupEnd(nRow))
+ {
+ if (bHasRowHeader && bRowHeaderOpen)
+ CloseHeaderRows();
+ pGroupRows->CloseGroups(nRow);
+ if (bHasRowHeader && bRowHeaderOpen)
+ OpenHeaderRows();
+ }
+ }
+ nOpenRow = -1;
+}
+
+void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
+ const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet)
+{
+ pRowFormatRanges->Clear();
+ if (nStartRow == nEndRow)
+ {
+ pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges);
+ if (nOpenRow == - 1)
+ OpenRow(nSheet, nStartRow, 1);
+ WriteRowContent();
+ pRowFormatRanges->Clear();
+ }
+ else
+ {
+ if (nOpenRow > -1)
+ {
+ pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ CloseRow(nStartRow);
+ sal_Int32 nRows(1);
+ sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
+ while (nRows < nTotalRows)
+ {
+ pRowFormatRanges->Clear();
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
+ DBG_ASSERT(nMaxRows, "something wents wrong");
+ if (nMaxRows >= nTotalRows - nRows)
+ {
+ OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows);
+ nRows += nTotalRows - nRows;
+ }
+ else
+ {
+ OpenRow(nSheet, nStartRow + nRows, nMaxRows);
+ nRows += nMaxRows;
+ }
+ if (!pRowFormatRanges->GetSize())
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ CloseRow(nStartRow + nRows - 1);
+ }
+ if (nTotalRows == 1)
+ CloseRow(nStartRow);
+ OpenRow(nSheet, nEndRow, 1);
+ pRowFormatRanges->Clear();
+ pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ }
+ else
+ {
+ sal_Int32 nRows(0);
+ sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
+ while (nRows < nTotalRows)
+ {
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
+ if (nMaxRows >= nTotalRows - nRows)
+ {
+ OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows);
+ nRows += nTotalRows - nRows;
+ }
+ else
+ {
+ OpenRow(nSheet, nStartRow + nRows, nMaxRows);
+ nRows += nMaxRows;
+ }
+ if (!pRowFormatRanges->GetSize())
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ CloseRow(nStartRow + nRows - 1);
+ }
+ OpenRow(nSheet, nEndRow, 1);
+ pRowFormatRanges->Clear();
+ pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ }
+ }
+}
+
+void ScXMLExport::GetColumnRowHeader(sal_Bool& rHasColumnHeader, table::CellRangeAddress& rColumnHeaderRange,
+ sal_Bool& rHasRowHeader, table::CellRangeAddress& rRowHeaderRange,
+ rtl::OUString& rPrintRanges) const
+{
+ uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY);
+ if (xPrintAreas.is())
+ {
+ rHasRowHeader = xPrintAreas->getPrintTitleRows();
+ rHasColumnHeader = xPrintAreas->getPrintTitleColumns();
+ rRowHeaderRange = xPrintAreas->getTitleRows();
+ rColumnHeaderRange = xPrintAreas->getTitleColumns();
+ uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() );
+ ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO );
+ }
+}
+
+void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups)
+{
+ sal_Int32 nDepth(pFields->GetDepth());
+ for(sal_Int32 i = 0; i < nDepth; ++i)
+ {
+ sal_Int32 nFields = pFields->GetCount(static_cast<USHORT>(i));
+ for (sal_Int32 j = 0; j < nFields; ++j)
+ {
+ ScMyColumnRowGroup aGroup;
+ ScOutlineEntry* pEntry(pFields->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j)));
+ aGroup.nField = pEntry->GetStart();
+ aGroup.nLevel = static_cast<sal_Int16>(i);
+ aGroup.bDisplay = !(pEntry->IsHidden());
+ pGroups->AddGroup(aGroup, pEntry->GetEnd());
+ }
+ }
+ if (nDepth)
+ pGroups->Sort();
+}
+
+void ScXMLExport::FillColumnRowGroups()
+{
+ if (pDoc)
+ {
+ ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable), sal_False );
+ if(pOutlineTable)
+ {
+ ScOutlineArray* pCols(pOutlineTable->GetColArray());
+ ScOutlineArray* pRows(pOutlineTable->GetRowArray());
+ if (pCols)
+ FillFieldGroup(pCols, pGroupColumns);
+ if (pRows)
+ FillFieldGroup(pRows, pGroupRows);
+ pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast());
+ pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast());
+ }
+ }
+}
+
+void ScXMLExport::SetBodyAttributes()
+{
+ if (pDoc && pDoc->IsDocProtected())
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
+ rtl::OUStringBuffer aBuffer;
+ uno::Sequence<sal_Int8> aPassHash;
+ 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());
+ }
+}
+
+static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput,
+ const uno::Reference< io::XOutputStream >& xOutput,
+ sal_Int32 nCount )
+{
+ const sal_Int32 nBufSize = 16*1024;
+ uno::Sequence<sal_Int8> aSequence(nBufSize);
+
+ sal_Int32 nRemaining = nCount;
+ bool bFirst = true;
+
+ while ( nRemaining > 0 )
+ {
+ sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) );
+ if (bFirst)
+ {
+ // safety check: Make sure the copied part actually points to the start of an element
+ if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') )
+ {
+ return false; // abort and set an error
+ }
+ bFirst = false;
+ }
+ if (nRead == nRemaining)
+ {
+ // safety check: Make sure the copied part also ends at the end of an element
+ if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') )
+ {
+ return false; // abort and set an error
+ }
+ }
+
+ if ( nRead == nBufSize )
+ {
+ xOutput->writeBytes( aSequence );
+ nRemaining -= nRead;
+ }
+ else
+ {
+ if ( nRead > 0 )
+ {
+ uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead );
+ xOutput->writeBytes( aTempBuf );
+ }
+ nRemaining = 0;
+ }
+ }
+ return true; // successful
+}
+
+static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip )
+{
+ // skipBytes in zip stream is implemented as reading.
+ // For now, split into several calls to avoid allocating a large buffer.
+ // Later, skipBytes should be changed.
+
+ const sal_Int32 nMaxSize = 32*1024;
+
+ if ( nBytesToSkip > 0 )
+ {
+ sal_Int32 nRemaining = nBytesToSkip;
+ while ( nRemaining > 0 )
+ {
+ sal_Int32 nSkip = std::min( nRemaining, nMaxSize );
+ xInput->skipBytes( nSkip );
+ nRemaining -= nSkip;
+ }
+ }
+}
+
+void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
+{
+ uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
+ uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY );
+ if ( xDestSource.is() )
+ {
+ uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream();
+ uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY );
+ if ( xDestSeek.is() )
+ {
+ // temporary: set same stream again to clear buffer
+ xDestSource->setOutputStream( xDestStream );
+
+ if ( getExportFlags() & EXPORT_PRETTY )
+ {
+ ByteString aOutStr("\n ");
+ uno::Sequence<sal_Int8> aOutSeq( (sal_Int8*)aOutStr.GetBuffer(), aOutStr.Len() );
+ xDestStream->writeBytes( aOutSeq );
+ }
+
+ rNewStart = (sal_Int32)xDestSeek->getPosition();
+
+ if ( nStartOffset > nSourceStreamPos )
+ lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos );
+
+ if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
+ {
+ // If copying went wrong, set an error.
+ // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
+
+ uno::Sequence<OUString> aEmptySeq;
+ SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
+ }
+ nSourceStreamPos = nEndOffset;
+
+ rNewEnd = (sal_Int32)xDestSeek->getPosition();
+ }
+ }
+}
+
+void ScXMLExport::_ExportContent()
+{
+ nCurrentTable = 0;
+ if (!pSharedData)
+ {
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+ DBG_ERROR("no shared data setted");
+ }
+ ScXMLExportDatabaseRanges aExportDatabaseRanges(*this);
+ if (!GetModel().is())
+ return;
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+ if ( !xSpreadDoc.is() )
+ return;
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
+ if (pSheetData)
+ pSheetData->ResetSaveEntries();
+
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ //_GetNamespaceMap().ClearQNamesCache();
+ pChangeTrackingExportHelper->CollectAndWriteChanges();
+ WriteCalculationSettings(xSpreadDoc);
+ sal_Int32 nTableCount(xIndex->getCount());
+ ScMyAreaLinksContainer aAreaLinks;
+ GetAreaLinks( xSpreadDoc, aAreaLinks );
+ ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges());
+ ScMyDetectiveOpContainer aDetectiveOpContainer;
+ GetDetectiveOpList( aDetectiveOpContainer );
+
+ pCellStyles->Sort();
+ pMergedRangesContainer->Sort();
+ pSharedData->GetDetectiveObjContainer()->Sort();
+
+ pCellsItr->Clear();
+ pCellsItr->SetShapes( pSharedData->GetShapesContainer() );
+ pCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() );
+ pCellsItr->SetMergedRanges( pMergedRangesContainer );
+ pCellsItr->SetAreaLinks( &aAreaLinks );
+ pCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges );
+ pCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() );
+ pCellsItr->SetDetectiveOp( &aDetectiveOpContainer );
+
+ if (nTableCount > 0)
+ pValidationsContainer->WriteValidations(*this);
+ WriteTheLabelRanges( xSpreadDoc );
+ for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable))
+ pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
+
+ if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() )
+ {
+ sal_Int32 nNewStart = -1;
+ sal_Int32 nNewEnd = -1;
+ CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd );
+
+ // store position of copied sheet in output
+ pSheetData->AddSavePos( nTable, nNewStart, nNewEnd );
+
+ // skip iterator entries for this sheet
+ pCellsItr->SkipTable(static_cast<SCTAB>(nTable));
+ }
+ else
+ {
+ uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xTable.is())
+ {
+ xCurrentTable.set(xTable);
+ xCurrentTableCellRange.set(xTable, uno::UNO_QUERY);
+ uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY );
+ if ( xName.is() )
+ {
+ nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
+ rtl::OUString sOUTableName(xName->getName());
+ AddAttribute(sAttrName, sOUTableName);
+ AddAttribute(sAttrStyleName, aTableStyles[nTable]);
+
+ uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY);
+ if (xProtectable.is() && xProtectable->isProtected())
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
+ rtl::OUStringBuffer aBuffer;
+ if (pDoc)
+ {
+ 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());
+ }
+ rtl::OUString sPrintRanges;
+ table::CellRangeAddress aColumnHeaderRange;
+ sal_Bool bHasColumnHeader;
+ GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges);
+ if( sPrintRanges.getLength() )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges );
+ else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable)))
+ AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE);
+ SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True);
+ CheckAttrList();
+
+ if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) &&
+ getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
+ {
+ // store sheet events
+ uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY);
+ GetEventExport().ExportExt( xEvents );
+ }
+
+ WriteTableSource();
+ WriteScenario();
+ uno::Reference<drawing::XDrawPage> xDrawPage;
+ if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is())
+ {
+ ::xmloff::OOfficeFormsExport aForms(*this);
+ GetFormExport()->exportForms( xDrawPage );
+ sal_Bool bRet(GetFormExport()->seekPage( xDrawPage ));
+ DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" );
+ (void)bRet; // avoid warning in product version
+ }
+ if (pSharedData->HasDrawPage())
+ {
+ GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY));
+ WriteTableShapes();
+ }
+ table::CellRangeAddress aRange(GetEndAddress(xTable, nTable));
+ pSharedData->SetLastColumn(nTable, aRange.EndColumn);
+ pSharedData->SetLastRow(nTable, aRange.EndRow);
+ pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable);
+ pGroupColumns->NewTable();
+ pGroupRows->NewTable();
+ FillColumnRowGroups();
+ if (bHasColumnHeader)
+ pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn);
+ bRowHeaderOpen = sal_False;
+ if (bHasRowHeader)
+ pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow);
+ pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable),
+ pSharedData->GetLastColumn(nTable), pCellStyles, pDoc);
+ pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults());
+ pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults());
+ pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults());
+ pCellStyles->SetColDefaults(pDefaults->GetColDefaults());
+ ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader);
+ sal_Bool bIsFirst(sal_True);
+ sal_Int32 nEqualCells(0);
+ ScMyCell aCell;
+ ScMyCell aPrevCell;
+ while(pCellsItr->GetNext(aCell, pCellStyles))
+ {
+ if (bIsFirst)
+ {
+ ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
+ aPrevCell = aCell;
+ bIsFirst = sal_False;
+ }
+ else
+ {
+ if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) &&
+ (aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column))
+ {
+ if(IsCellEqual(aPrevCell, aCell))
+ ++nEqualCells;
+ else
+ {
+ SetRepeatAttribute(nEqualCells);
+ WriteCell(aPrevCell);
+ nEqualCells = 0;
+ aPrevCell = aCell;
+ }
+ }
+ else
+ {
+ SetRepeatAttribute(nEqualCells);
+ WriteCell(aPrevCell);
+ ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
+ aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
+ nEqualCells = 0;
+ aPrevCell = aCell;
+ }
+ }
+ }
+ if (!bIsFirst)
+ {
+ SetRepeatAttribute(nEqualCells);
+ WriteCell(aPrevCell);
+ ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
+ pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
+ }
+ else
+ ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
+ CloseRow(pSharedData->GetLastRow(nTable));
+ nEqualCells = 0;
+ }
+ }
+ }
+ IncrementProgressBar(sal_False);
+ }
+ }
+ WriteExternalRefCaches();
+ WriteNamedExpressions(xSpreadDoc);
+ aExportDatabaseRanges.WriteDatabaseRanges(xSpreadDoc);
+ ScXMLExportDataPilot aExportDataPilot(*this);
+ aExportDataPilot.WriteDataPilots(xSpreadDoc);
+ WriteConsolidation();
+ ScXMLExportDDELinks aExportDDELinks(*this);
+ aExportDDELinks.WriteDDELinks(xSpreadDoc);
+ IncrementProgressBar(sal_True, 0);
+ GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
+}
+
+void ScXMLExport::_ExportStyles( sal_Bool bUsed )
+{
+ if (!pSharedData)
+ {
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+ //DBG_ERROR("no shared data setted");
+ }
+ ScXMLStyleExport aStylesExp(*this, rtl::OUString(), GetAutoStylePool().get());
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY);
+ if (xProperties.is())
+ aStylesExp.exportDefaultStyle(xProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper);
+ if (pSharedData->HasShapes())
+ {
+ GetShapeExport()->ExportGraphicDefaults();
+/* xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Defaults")));
+ uno::Reference <beans::XPropertySet> xDrawProperties(xInterface, uno::UNO_QUERY);
+ if (xDrawProperties.is())
+ aStylesExp.exportDefaultStyle(xDrawProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), GetShapeExport()->CreateShapePropMapper(*this));*/
+ }
+ }
+ uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY);
+ if (xStyleFamiliesSupplier.is())
+ {
+ uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
+ if (xStylesFamilies.is())
+ {
+ uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles"))), uno::UNO_QUERY);
+ if (xCellStyles.is())
+ {
+ sal_Int32 nCount(xCellStyles->getCount());
+ rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY);
+ if (xCellProperties.is())
+ {
+ sal_Int32 nNumberFormat = 0;
+ if (xCellProperties->getPropertyValue(sNumberFormat) >>= nNumberFormat)
+ addDataStyle(nNumberFormat);
+ }
+ }
+ }
+ }
+ }
+ }
+ exportDataStyles();
+
+ aStylesExp.exportStyleFamily(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper, FALSE, XML_STYLE_FAMILY_TABLE_CELL);
+
+ SvXMLExport::_ExportStyles(bUsed);
+}
+
+void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties,
+ const uno::Reference<sheet::XSpreadsheet>& xTable,
+ sal_Int32 nTable, const rtl::OUString* pOldName)
+{
+ //! pass xCellRanges instead
+ uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY );
+
+ rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
+ rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
+
+ rtl::OUString sStyleName;
+ sal_Int32 nNumberFormat(-1);
+ sal_Int32 nValidationIndex(-1);
+ std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
+ std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
+ std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
+ sal_Int32 nCount(0);
+ while (aItr != aEndItr)
+ {
+ if (aItr->mnIndex != -1)
+ {
+ switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
+ {
+ case CTF_SC_VALIDATION :
+ {
+ pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
+ // this is not very slow, because it is most the last property or
+ // if it is not the last property it is the property before the last property,
+ // so in the worst case only one property has to be copied, but in the best case no
+ // property has to be copied
+ aItr = xPropStates.erase(aItr);
+ aEndItr = xPropStates.end(); // #120346# old aEndItr is invalidated!
+ }
+ break;
+ case CTF_SC_CELLSTYLE :
+ {
+ aItr->maValue >>= sStyleName;
+ aItr->mnIndex = -1;
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ case CTF_SC_NUMBERFORMAT :
+ {
+ if (aItr->maValue >>= nNumberFormat)
+ addDataStyle(nNumberFormat);
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ default:
+ {
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ }
+ }
+ else
+ {
+ ++aItr;
+ ++nCount;
+ }
+ }
+ if (nCount == 1) // this is the CellStyle and should be removed if alone
+ xPropStates.clear();
+ if (nNumberFormat == -1)
+ xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
+ if (sStyleName.getLength())
+ {
+ if (xPropStates.size())
+ {
+ sal_Int32 nIndex;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName);
+ // add to pCellStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex))
+ delete pTemp;
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ sal_Bool bIsAutoStyle(sal_True);
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex))
+ delete pTemp;
+ }
+ else
+ nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
+
+ uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
+ table::CellRangeAddress* pAddresses(aAddresses.getArray());
+ sal_Bool bGetMerge(sal_True);
+ for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
+ {
+ pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
+ pSharedData->SetLastRow(nTable, pAddresses->EndRow);
+ pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
+ if (bGetMerge)
+ bGetMerge = GetMerged(pAddresses, xTable);
+ }
+ }
+ }
+ else
+ {
+ rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName)));
+ sal_Int32 nIndex(0);
+ if (!pCellStyles->AddStyleName(pTemp, nIndex, sal_False))
+ {
+ delete pTemp;
+ pTemp = NULL;
+ }
+ if ( !pOldName )
+ {
+ uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
+ table::CellRangeAddress* pAddresses(aAddresses.getArray());
+ sal_Bool bGetMerge(sal_True);
+ for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
+ {
+ if (bGetMerge)
+ bGetMerge = GetMerged(pAddresses, xTable);
+ pCellStyles->AddRangeStyleName(*pAddresses, nIndex, sal_False, nValidationIndex, nNumberFormat);
+ if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1)
+ {
+ pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
+ pSharedData->SetLastRow(nTable, pAddresses->EndRow);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible)
+{
+ rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
+
+ std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
+ if(xPropStates.size())
+ {
+ std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
+ std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
+ while (aItr != aEndItr)
+ {
+ if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
+ {
+ aItr->maValue >>= rIsVisible;
+ break;
+ }
+ ++aItr;
+ }
+
+ rtl::OUString sParent;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName);
+ // add to pColumnStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ rIndex = pColumnStyles->AddStyleName(pTemp);
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ rIndex = pColumnStyles->AddStyleName(pTemp);
+ }
+ else
+ rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
+ }
+ }
+}
+
+void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex)
+{
+ rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
+
+ std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
+ if(xPropStates.size())
+ {
+ rtl::OUString sParent;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName);
+ // add to pRowStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ rIndex = pRowStyles->AddStyleName(pTemp);
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ rIndex = pRowStyles->AddStyleName(pTemp);
+ }
+ else
+ rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
+ }
+ }
+}
+
+uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex )
+{
+ uno::Any aRet;
+ uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() );
+ try
+ {
+ sal_Int32 nSkip = nIndex;
+ while ( nSkip > 0 )
+ {
+ (void) xEnum->nextElement();
+ --nSkip;
+ }
+ aRet = xEnum->nextElement();
+ }
+ catch (container::NoSuchElementException&)
+ {
+ // leave aRet empty
+ }
+ return aRet;
+}
+
+void ScXMLExport::_ExportAutoStyles()
+{
+ if (!GetModel().is())
+ return;
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+ if (!xSpreadDoc.is())
+ return;
+
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if (!xIndex.is())
+ return;
+
+ if (getExportFlags() & EXPORT_CONTENT)
+ {
+ // re-create automatic styles with old names from stored data
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
+ if (pSheetData && pDoc)
+ {
+ // formulas have to be calculated now, to detect changed results
+ // (during normal save, they will be calculated anyway)
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (pDoc->IsStreamValid(nTab))
+ {
+ ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty
+ pCell = aIter.GetNext();
+ }
+ }
+
+ // stored cell styles
+ const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end();
+ while (aCellIter != aCellEnd)
+ {
+ ScAddress aPos = aCellIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference <beans::XPropertySet> xProperties(
+ xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
+
+ AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName);
+ }
+ ++aCellIter;
+ }
+
+ // stored column styles
+ const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end();
+ while (aColumnIter != aColumnEnd)
+ {
+ ScAddress aPos = aColumnIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
+ uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
+
+ sal_Int32 nIndex(-1);
+ sal_Bool bIsVisible(sal_True);
+ AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible );
+ }
+ ++aColumnIter;
+ }
+
+ // stored row styles
+ const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end();
+ while (aRowIter != aRowEnd)
+ {
+ ScAddress aPos = aRowIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
+ uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
+
+ sal_Int32 nIndex(-1);
+ AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex );
+ }
+ ++aRowIter;
+ }
+
+ // stored table styles
+ const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end();
+ while (aTableIter != aTableEnd)
+ {
+ ScAddress aPos = aTableIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromTable needed?
+ uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xTableProperties.is())
+ {
+ std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aTableIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName);
+ }
+ }
+ ++aTableIter;
+ }
+
+ // stored styles for notes
+
+ UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
+ GetShapeExport(); // make sure the graphics styles family is added
+
+ const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
+ std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin();
+ std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end();
+ while (aNoteIter != aNoteEnd)
+ {
+ ScAddress aPos = aNoteIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromNote needed?
+
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ // all uno shapes are created anyway in CollectSharedData
+ uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
+ if (xShapeProperties.is())
+ {
+ if ( aNoteIter->maStyleName.getLength() )
+ {
+ std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteIter->maStyleName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName);
+ }
+ if ( aNoteIter->maTextStyle.getLength() )
+ {
+ std::vector<XMLPropertyState> xPropStates(
+ GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteIter->maTextStyle );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
+ }
+ }
+ }
+ }
+ ++aNoteIter;
+ }
+
+ // note paragraph styles
+
+ //UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this );
+ UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
+
+ const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end();
+ while (aNoteParaIter != aNoteParaEnd)
+ {
+ ScAddress aPos = aNoteParaIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xParaProp(
+ lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY );
+ if ( xParaProp.is() )
+ {
+ std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteParaIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
+ }
+ }
+ }
+ ++aNoteParaIter;
+ }
+
+ // note text styles
+
+ UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
+
+ const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end();
+ while (aNoteTextIter != aNoteTextEnd)
+ {
+ ScAddress aPos = aNoteTextIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
+ ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp );
+ if (pCursor)
+ {
+ pCursor->SetSelection( aNoteTextIter->maSelection );
+
+ std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteTextIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
+ }
+ }
+ }
+ ++aNoteTextIter;
+ }
+
+ // stored text styles
+
+ //UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
+
+ const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end();
+ while (aTextIter != aTextEnd)
+ {
+ ScAddress aPos = aTextIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromText needed?
+ //! cache sheet object
+
+ uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
+ ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp );
+ if (pCursor)
+ {
+ pCursor->SetSelection( aTextIter->maSelection );
+
+ std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aTextIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
+ }
+ }
+ ++aTextIter;
+ }
+ }
+
+ ExportExternalRefCacheStyles();
+
+ if (!pSharedData)
+ {
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+ //DBG_ERROR("no shared data setted");
+ }
+ sal_Int32 nTableCount(xIndex->getCount());
+ pCellStyles->AddNewTable(nTableCount - 1);
+ CollectShapesAutoStyles(nTableCount);
+ for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) &&
+ pSheetData->HasStreamPos(nTable) && xSourceStream.is();
+
+ uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xTable.is())
+ {
+ // table styles array must be complete, including copied tables - Add should find the stored style
+ uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
+ if (xTableProperties.is())
+ {
+ std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
+ if(xPropStates.size())
+ {
+ rtl::OUString sParent;
+ rtl::OUString sName;
+ GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
+ aTableStyles.push_back(sName);
+ }
+ }
+ }
+ // collect other auto-styles only for non-copied sheets
+ if (xTable.is() && !bUseStream)
+ {
+ uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
+ if ( xCellFormatRanges.is() )
+ {
+ uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
+ if (xFormatRangesIndex.is())
+ {
+ sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount());
+ GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount);
+ for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange)
+ {
+ uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY);
+ if (xCellRanges.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ AddStyleFromCells(xProperties, xTable, nTable, NULL);
+ IncrementProgressBar(sal_False);
+ }
+ }
+ }
+ }
+ }
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ {
+ if (pDoc)
+ {
+ pDoc->SyncColRowFlags();
+ uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
+ if (xTableColumns.is())
+ {
+ sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable)));
+ pSharedData->SetLastColumn(nTable, nColumns);
+ table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
+ if (aCellAddress.EndColumn > nColumns)
+ {
+ ++nColumns;
+ pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn);
+ }
+// else if (nColumns < MAXCOL)
+// pColumnStyles->AddNewTable(nTable, ++nColumns);
+ else
+ pColumnStyles->AddNewTable(nTable, nColumns);
+ sal_Int32 nColumn = 0;
+ while (/*nColumn <= nColumns && */nColumn <= MAXCOL)
+ {
+ sal_Int32 nIndex(-1);
+ sal_Bool bIsVisible(sal_True);
+ uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
+ if (xColumnProperties.is())
+ {
+ AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible );
+ //if(xPropStates.size())
+ pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
+ }
+ sal_Int32 nOld(nColumn);
+ nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn));
+ for (sal_Int32 i = nOld + 1; i < nColumn; ++i)
+ pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
+ }
+ if (aCellAddress.EndColumn > nColumns)
+ {
+ sal_Bool bIsVisible(sal_True);
+ sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible));
+ for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i)
+ pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
+ }
+ }
+ uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
+ if (xTableRows.is())
+ {
+ sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable)));
+ pSharedData->SetLastRow(nTable, nRows);
+ table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
+ if (aCellAddress.EndRow > nRows)
+ {
+ ++nRows;
+ pRowStyles->AddNewTable(nTable, aCellAddress.EndRow);
+ }
+// else if (nRows < MAXROW)
+// pRowStyles->AddNewTable(nTable, ++nRows);
+ else
+ pRowStyles->AddNewTable(nTable, nRows);
+ sal_Int32 nRow = 0;
+ while (nRow <= nRows && nRow <= MAXROW)
+ {
+ sal_Int32 nIndex = 0;
+ uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
+ if(xRowProperties.is())
+ {
+ AddStyleFromRow( xRowProperties, NULL, nIndex );
+ //if(xPropStates.size())
+ pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
+ }
+ sal_Int32 nOld(nRow);
+ nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false);
+ if (nRow > nOld + 1)
+ pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
+ }
+ if (aCellAddress.EndRow > nRows)
+ {
+ sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows));
+ pRowStyles->AddFieldStyleName(nTable, nRows + 1, nIndex, aCellAddress.EndRow);
+ }
+ }
+ }
+ }
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY);
+ if (xCellRangesQuery.is())
+ {
+ uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED));
+ uno::Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY);
+ if (xSheetCellRanges.is() && xSheetOperation.is())
+ {
+ sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT)));
+ uno::Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells());
+ if (xCellsAccess.is())
+ {
+ GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount);
+ uno::Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration());
+ if (xCells.is())
+ {
+ sal_uInt32 nCount2(0);
+ while (xCells->hasMoreElements())
+ {
+ uno::Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY);
+ if (xText.is())
+ GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False);
+ ++nCount2;
+ IncrementProgressBar(sal_False);
+ }
+ if(nCount2 > nCount)
+ GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount);
+ }
+ }
+ }
+ }
+ }
+ IncrementProgressBar(sal_False);
+ }
+ pChangeTrackingExportHelper->CollectAutoStyles();
+
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+ exportAutoDataStyles();
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+
+ GetShapeExport()->exportAutoStyles();
+ GetFormExport()->exportAutoStyles( );
+
+ if (pDoc)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ // #i100879# write the table style for cached tables only if there are cached tables
+ // (same logic as in ExportExternalRefCacheStyles)
+ if (pRefMgr->hasExternalData())
+ {
+ // Special table style for the external ref cache tables.
+ AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName);
+ AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE);
+ SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
+ SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True);
+ }
+ }
+ }
+
+ if (getExportFlags() & EXPORT_MASTERSTYLES)
+ {
+ GetPageExport()->collectAutoStyles(sal_True);
+ GetPageExport()->exportAutoStyles();
+ }
+
+ // #i30251#; only write Text Styles once
+
+ if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES))
+ GetTextParagraphExport()->exportTextAutoStyles();
+}
+
+void ScXMLExport::_ExportMasterStyles()
+{
+ GetPageExport()->exportMasterStyles( sal_True );
+}
+
+void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape )
+{
+ // detective objects and notes
+ if( SvxShape* pShapeImp = SvxShape::getImplementation( xShape ) )
+ {
+ if( SdrObject* pObject = pShapeImp->GetSdrObject() )
+ {
+ // collect note caption objects from all layers (internal or hidden)
+ if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) )
+ {
+ pSharedData->AddNoteObj( xShape, pCaptData->maStart );
+
+ // #i60851# When the file is saved while editing a new note,
+ // the cell is still empty -> last column/row must be updated
+ DBG_ASSERT( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" );
+ pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() );
+ pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() );
+ }
+ // other objects from internal layer only (detective)
+ else if( pObject->GetLayer() == SC_LAYER_INTERN )
+ {
+ ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) );
+ ScAddress aPosition;
+ ScRange aSourceRange;
+ sal_Bool bRedLine;
+ ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType(
+ pObject, nCurrentTable, aPosition, aSourceRange, bRedLine );
+ pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine );
+ }
+ }
+ }
+}
+
+//UNUSED2008-05 sal_Bool ScXMLExport::GetMerge (const uno::Reference <sheet::XSpreadsheet>& xTable,
+//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow,
+//UNUSED2008-05 table::CellRangeAddress& aCellAddress)
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
+//UNUSED2008-05 if (xSheetCellRange.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
+//UNUSED2008-05 if (xCursor.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
+//UNUSED2008-05 xCursor->collapseToMergedArea();
+//UNUSED2008-05 aCellAddress = xCellAddress->getRangeAddress();
+//UNUSED2008-05 return sal_True;
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 return sal_False;
+//UNUSED2008-05 }
+
+sal_Bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress,
+ const uno::Reference <sheet::XSpreadsheet>& xTable)
+{
+ sal_Bool bReady(sal_False);
+ sal_Int32 nRow(pCellAddress->StartRow);
+ sal_Int32 nCol(pCellAddress->StartColumn);
+ sal_Int32 nEndRow(pCellAddress->EndRow);
+ sal_Int32 nEndCol(pCellAddress->EndColumn);
+ sal_Bool bRowInc(nEndRow > nRow);
+ while(!bReady && nRow <= nEndRow && nCol <= nEndCol)
+ {
+ uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
+ if (xSheetCellRange.is())
+ {
+ uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
+ if(xCursor.is())
+ {
+ uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
+ xCursor->collapseToMergedArea();
+ table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress());
+ if ((aCellAddress2.EndRow > nRow ||
+ aCellAddress2.EndColumn > nCol) &&
+ aCellAddress2.StartRow == nRow &&
+ aCellAddress2.StartColumn == nCol)
+ {
+ pMergedRangesContainer->AddRange(aCellAddress2);
+ pSharedData->SetLastColumn(aCellAddress2.Sheet, aCellAddress2.EndColumn);
+ pSharedData->SetLastRow(aCellAddress2.Sheet, aCellAddress2.EndRow);
+ }
+ else
+ bReady = sal_True;
+ }
+ }
+ if (!bReady)
+ {
+ if (bRowInc)
+ ++nRow;
+ else
+ ++nCol;
+ }
+ }
+ DBG_ASSERT(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible");
+ return !bReady;
+}
+
+//UNUSED2008-05 sal_Bool ScXMLExport::IsMatrix (const uno::Reference <table::XCellRange>& xCellRange,
+//UNUSED2008-05 const uno::Reference <sheet::XSpreadsheet>& xTable,
+//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow,
+//UNUSED2008-05 table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
+//UNUSED2008-05 {
+//UNUSED2008-05 bIsFirst = sal_False;
+//UNUSED2008-05 uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
+//UNUSED2008-05 if (xArrayFormulaRange.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula());
+//UNUSED2008-05 if (sArrayFormula.getLength())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xArrayFormulaRange, uno::UNO_QUERY);
+//UNUSED2008-05 if (xMatrixSheetCellRange.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange));
+//UNUSED2008-05 if (xMatrixSheetCursor.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 xMatrixSheetCursor->collapseToCurrentArray();
+//UNUSED2008-05 uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY);
+//UNUSED2008-05 if (xMatrixCellAddress.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 aCellAddress = xMatrixCellAddress->getRangeAddress();
+//UNUSED2008-05 if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) &&
+//UNUSED2008-05 (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow))
+//UNUSED2008-05 {
+//UNUSED2008-05 bIsFirst = sal_True;
+//UNUSED2008-05 return sal_True;
+//UNUSED2008-05 }
+//UNUSED2008-05 else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow ||
+//UNUSED2008-05 aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow)
+//UNUSED2008-05 return sal_True;
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 bIsFirst = sal_True;
+//UNUSED2008-05 return sal_True;
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 return sal_False;
+//UNUSED2008-05 }
+
+sal_Bool ScXMLExport::IsMatrix (const ScAddress& aCell,
+ table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
+{
+ bIsFirst = sal_False;
+
+ ScRange aMatrixRange;
+
+ if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange))
+ {
+ ScUnoConversion::FillApiRange( aCellAddress, aMatrixRange );
+ if ((aCellAddress.StartColumn == aCell.Col() && aCellAddress.StartRow == aCell.Row()) &&
+ (aCellAddress.EndColumn > aCell.Col() || aCellAddress.EndRow > aCell.Row()))
+ {
+ bIsFirst = sal_True;
+ return sal_True;
+ }
+ else if (aCellAddress.StartColumn != aCell.Col() || aCellAddress.StartRow != aCell.Row() ||
+ aCellAddress.EndColumn != aCell.Col() || aCellAddress.EndRow != aCell.Row())
+ return sal_True;
+ else
+ {
+ bIsFirst = sal_True;
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+
+/* uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCell, uno::UNO_QUERY);
+ if (xArrayFormulaRange.is())
+ {
+ rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula());
+ if (sArrayFormula.getLength())
+ {
+ uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xCell, uno::UNO_QUERY);
+ if (xMatrixSheetCellRange.is())
+ {
+ uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange));
+ if (xMatrixSheetCursor.is())
+ {
+ xMatrixSheetCursor->collapseToCurrentArray();
+ uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY);
+ if (xMatrixCellAddress.is())
+ {
+ aCellAddress = xMatrixCellAddress->getRangeAddress();
+ if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) &&
+ (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow))
+ {
+ bIsFirst = sal_True;
+ return sal_True;
+ }
+ else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow ||
+ aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow)
+ return sal_True;
+ else
+ {
+ bIsFirst = sal_True;
+ return sal_True;
+ }
+ }
+ }
+ }
+ }
+ }
+ return sal_False;*/
+}
+
+sal_Bool ScXMLExport::GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const
+{
+ if (rMyCell.bHasStringValue)
+ return sal_True;
+ else
+ {
+/* if (!rMyCell.bHasXText)
+ {
+ rMyCell.xText.set(xCurrentTableCellRange->getCellByPosition(rMyCell.aCellAddress.Column, rMyCell.aCellAddress.Row), uno::UNO_QUERY);
+ rMyCell.bHasXText = sal_True;
+ }*/
+// if (rMyCell.xText.is())
+// {
+ rMyCell.sStringValue = ScCellObj::GetOutputString_Impl(pDoc, aPos);
+ rMyCell.bHasStringValue = sal_True;
+ return sal_True;
+// }
+ }
+}
+
+void ScXMLExport::WriteCell (ScMyCell& aCell)
+{
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress( aCellPos, aCell.aCellAddress );
+ if (aCell.nStyleIndex != -1)
+ AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle));
+ if (aCell.nValidationIndex > -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex));
+ sal_Bool bIsMatrix(aCell.bIsMatrixBase || aCell.bIsMatrixCovered);
+ sal_Bool bIsFirstMatrixCell(aCell.bIsMatrixBase);
+ if (bIsFirstMatrixCell)
+ {
+ sal_Int32 nColumns(aCell.aMatrixRange.EndColumn - aCell.aMatrixRange.StartColumn + 1);
+ sal_Int32 nRows(aCell.aMatrixRange.EndRow - aCell.aMatrixRange.StartRow + 1);
+ rtl::OUStringBuffer sColumns;
+ rtl::OUStringBuffer sRows;
+ SvXMLUnitConverter::convertNumber(sColumns, nColumns);
+ SvXMLUnitConverter::convertNumber(sRows, nRows);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
+ }
+ sal_Bool bIsEmpty(sal_False);
+ switch (aCell.nType)
+ {
+ case table::CellContentType_EMPTY :
+ {
+ bIsEmpty = sal_True;
+ }
+ break;
+ case table::CellContentType_VALUE :
+ {
+ if (!aCell.bHasDoubleValue)
+ {
+ aCell.fValue = pDoc->GetValue( aCellPos );
+ aCell.bHasDoubleValue = sal_True;
+ }
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ aCell.nNumberFormat, aCell.fValue);
+ }
+ break;
+ case table::CellContentType_TEXT :
+ {
+ if (GetCellText(aCell, aCellPos))
+ {
+ rtl::OUString sFormula(lcl_GetRawString(pDoc, aCellPos));
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ sFormula, aCell.sStringValue, sal_True, sal_True);
+ }
+ }
+ break;
+ case table::CellContentType_FORMULA :
+ {
+ ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aCellPos) : NULL;
+ if (pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ rtl::OUStringBuffer sFormula;
+ ScFormulaCell* pFormulaCell((ScFormulaCell*) pBaseCell);
+ if (!bIsMatrix || (bIsMatrix && bIsFirstMatrixCell))
+ {
+ const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
+ sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
+ pFormulaCell->GetFormula(sFormula, eGrammar);
+ rtl::OUString sOUFormula(sFormula.makeStringAndClear());
+ if (!bIsMatrix)
+ {
+ AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula, sal_False ));
+ }
+ else
+ {
+ AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula.copy(1, sOUFormula.getLength() - 2), sal_False ));
+ }
+ }
+ if (pFormulaCell->IsValue())
+ {
+ sal_Bool bIsStandard;
+ rtl::OUString sCurrency;
+ GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard);
+ if (bIsStandard)
+ {
+ if (pDoc)
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ pFormulaCell->GetStandardFormat(*pDoc->GetFormatTable(), 0),
+ pDoc->GetValue( aCellPos ));
+ }
+ else
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ aCell.nNumberFormat, pDoc->GetValue( aCellPos ));
+ }
+ else
+ {
+ if (GetCellText(aCell, aCellPos))
+ if (aCell.sStringValue.getLength())
+ {
+ AddAttribute(sAttrValueType, XML_STRING);
+ AddAttribute(sAttrStringValue, aCell.sStringValue);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ rtl::OUString* pCellString(&sElemCell);
+ if (aCell.bIsCovered)
+ {
+ pCellString = &sElemCoveredCell;
+ }
+ else
+ {
+ if (aCell.bIsMergedBase)
+ {
+ sal_Int32 nColumns(aCell.aMergeRange.EndColumn - aCell.aMergeRange.StartColumn + 1);
+ sal_Int32 nRows(aCell.aMergeRange.EndRow - aCell.aMergeRange.StartRow + 1);
+ rtl::OUStringBuffer sColumns;
+ rtl::OUStringBuffer sRows;
+ SvXMLUnitConverter::convertNumber(sColumns, nColumns);
+ SvXMLUnitConverter::convertNumber(sRows, nRows);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, sColumns.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, sRows.makeStringAndClear());
+ }
+ }
+ SvXMLElementExport aElemC(*this, *pCellString, sal_True, sal_True);
+ CheckAttrList();
+ WriteAreaLink(aCell);
+ WriteAnnotation(aCell);
+ WriteDetective(aCell);
+
+ sal_Bool bEditCell = sal_False;
+
+ if (!bIsEmpty)
+ {
+ if ((aCell.nType == table::CellContentType_TEXT && IsEditCell(aCell)) ||
+ (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell)))
+ {
+ bEditCell = sal_True;
+ uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY);
+ if ( xText.is())
+ GetTextParagraphExport()->exportText(xText, sal_False, sal_False);
+ }
+ else
+ {
+ SvXMLElementExport aElemP(*this, sElemP, sal_True, sal_False);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ if (GetCellText(aCell, aCellPos))
+ GetTextParagraphExport()->exportText(aCell.sStringValue, bPrevCharWasSpace);
+ }
+ }
+ WriteShapes(aCell);
+ if (!bIsEmpty)
+ IncrementProgressBar(bEditCell);
+}
+
+void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
+{
+ uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
+//BM sal_Bool bMemChart(sal_False); // das muss man jetzt umbenennen :-)
+ bool bIsChart( false );
+ rtl::OUString sPropCLSID (RTL_CONSTASCII_USTRINGPARAM("CLSID"));
+ rtl::OUString sPropModel (RTL_CONSTASCII_USTRINGPARAM("Model"));
+ rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName"));
+ if (xShapeProps.is())
+ {
+ sal_Int32 nZOrder = 0;
+ if (xShapeProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))) >>= nZOrder)
+ {
+ rtl::OUStringBuffer sBuffer;
+ GetMM100UnitConverter().convertNumber(sBuffer, nZOrder);
+ AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, sBuffer.makeStringAndClear());
+ }
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo();
+ if( xPropSetInfo->hasPropertyByName( sPropCLSID ) )
+ {
+ rtl::OUString sCLSID;
+ if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID)
+ {
+ if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
+ {
+ // we have a chart
+ ::rtl::OUString sRanges;
+ if ( pDoc )
+ {
+ ::rtl::OUString aChartName;
+ xShapeProps->getPropertyValue( sPersistName ) >>= aChartName;
+ ScRange aEmptyRange;
+ ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
+ USHORT nIndex = 0;
+ ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
+ if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
+ {
+ ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
+ if ( pListener )
+ {
+ const ScRangeListRef& rRangeList = pListener->GetRangeList();
+ if ( rRangeList.Is() )
+ {
+ ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO );
+ if ( sRanges.getLength() > 0 )
+ {
+ bIsChart = true;
+ SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
+ if ( pAttrList )
+ {
+ pAttrList->AddAttribute(
+ GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges );
+ }
+ GetShapeExport()->exportShape( xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList );
+ }
+ }
+ }
+ }
+ }
+
+ if ( sRanges.getLength() == 0 )
+ {
+ uno::Reference< frame::XModel > xChartModel;
+ if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) &&
+ xChartModel.is())
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY );
+ if( xChartDoc.is() && xReceiver.is() &&
+ ! xChartDoc->hasInternalDataProvider())
+ {
+ // we have a chart that gets its data from Calc
+ bIsChart = true;
+ uno::Sequence< ::rtl::OUString > aRepresentations(
+ xReceiver->getUsedRangeRepresentations());
+ SvXMLAttributeList* pAttrList = 0;
+ if(aRepresentations.getLength())
+ {
+ // add the ranges used by the chart to the shape
+ // element to be able to start listening after
+ // load (when the chart is not yet loaded)
+ uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
+ sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
+ pAttrList = new SvXMLAttributeList();
+ pAttrList->AddAttribute(
+ GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
+ }
+ GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
+ }
+ }
+ }
+
+//BM rtl::OUString sOUName;
+//BM xShapeProps->getPropertyValue(sPersistName) >>= sOUName;
+//BM String sName(sOUName);
+//BM if (!pChartListener)
+//BM {
+//BM String aEmptyString;
+//BM ScRange aRange;
+//BM pChartListener = new ScChartListener ( aEmptyString, GetDocument(), aRange );
+//BM }
+//BM if(pChartListener)
+//BM {
+//BM USHORT nIndex(0);
+//BM pChartListener->SetString( sName );
+//BM if ( GetDocument() && GetDocument()->GetChartListenerCollection()->Search( pChartListener, nIndex ) )
+//BM {
+//BM const ScRangeListRef& rRangeListRef(((ScChartListener*)
+//BM (GetDocument()->GetChartListenerCollection()->
+//BM At( nIndex )))->GetRangeList());
+//BM if (rRangeListRef.Is())
+//BM {
+//BM bMemChart = sal_True;
+//BM rtl::OUString sRanges;
+//BM ScRangeStringConverter::GetStringFromRangeList(sRanges, rRangeListRef, GetDocument());
+//BM SvXMLAttributeList* pAttrList = NULL;
+//BM if (sRanges.getLength())
+//BM {
+//BM pAttrList = new SvXMLAttributeList();
+//BM pAttrList->AddAttribute(
+//BM GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
+//BM }
+//BM GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
+//BM }
+//BM }
+//BM else
+//BM {
+//BM bMemChart = sal_True;
+//BM SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
+//BM pAttrList->AddAttribute(
+//BM GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), rtl::OUString() );
+//BM GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
+//BM }
+//BM }
+
+/* SchMemChart* pMemChart = pDoc->FindChartData(sName);
+ if (pMemChart && pMemChart->GetSeriesAddresses().getLength())
+ {
+ bMemChart = sal_True;
+ rtl::OUString sRanges(pMemChart->getXMLStringForChartRange());
+ if (sRanges.getLength())
+ AddAttribute(XML_NAMESPACE_DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES, sRanges);
+ GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint);
+ }*/
+ }
+ }
+ }
+ }
+ if (!bIsChart)
+ GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint);
+ IncrementProgressBar(sal_False);
+}
+
+void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
+{
+ if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc )
+ {
+ awt::Point aPoint;
+ Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row),
+ static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row), static_cast<SCTAB>(rMyCell.aCellAddress.Sheet));
+ BOOL bNegativePage(pDoc->IsNegativePage(rMyCell.aCellAddress.Sheet));
+ if (bNegativePage)
+ aPoint.X = aRec.Right();
+ else
+ aPoint.X = aRec.Left();
+ aPoint.Y = aRec.Top();
+ ScMyShapeList::const_iterator aItr = rMyCell.aShapeList.begin();
+ ScMyShapeList::const_iterator aEndItr(rMyCell.aShapeList.end());
+ while (aItr != aEndItr)
+ {
+ if (aItr->xShape.is())
+ {
+ if (bNegativePage)
+ aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X;
+ if ( !aItr->xShape->getShapeType().equals(sCaptionShape) )
+ {
+ awt::Point aEndPoint;
+ Rectangle aEndRec(pDoc->GetMMRect(aItr->aEndAddress.Col(), aItr->aEndAddress.Row(),
+ aItr->aEndAddress.Col(), aItr->aEndAddress.Row(), aItr->aEndAddress.Tab()));
+ rtl::OUString sEndAddress;
+ ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress);
+ if (bNegativePage)
+ aEndPoint.X = -aEndRec.Right();
+ else
+ aEndPoint.X = aEndRec.Left();
+ aEndPoint.Y = aEndRec.Top();
+ awt::Point aStartPoint(aItr->xShape->getPosition());
+ awt::Size aSize(aItr->xShape->getSize());
+ sal_Int32 nEndX;
+ if (bNegativePage)
+ nEndX = -aStartPoint.X - aEndPoint.X;
+ else
+ nEndX = aStartPoint.X + aSize.Width - aEndPoint.X;
+ sal_Int32 nEndY(aStartPoint.Y + aSize.Height - aEndPoint.Y);
+ rtl::OUStringBuffer sBuffer;
+ GetMM100UnitConverter().convertMeasure(sBuffer, nEndX);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear());
+ GetMM100UnitConverter().convertMeasure(sBuffer, nEndY);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear());
+ }
+ ExportShape(aItr->xShape, &aPoint);
+ }
+ ++aItr;
+ }
+ }
+}
+
+void ScXMLExport::WriteTableShapes()
+{
+ ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
+ if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty())
+ {
+ DBG_ASSERT(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table");
+ SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, sal_True, sal_False);
+ ScMyTableXShapes::iterator aItr((*pTableShapes)[nCurrentTable].begin());
+ ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nCurrentTable].end());
+ while (aItr != aEndItr)
+ {
+ if (aItr->is())
+ {
+ if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable)))
+ {
+ awt::Point aPoint((*aItr)->getPosition());
+ awt::Size aSize((*aItr)->getSize());
+ aPoint.X += aPoint.X + aSize.Width;
+ aPoint.Y = 0;
+ ExportShape(*aItr, &aPoint);
+ }
+ else
+ ExportShape(*aItr, NULL);
+ }
+ aItr = (*pTableShapes)[nCurrentTable].erase(aItr);
+ }
+ }
+}
+
+void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell )
+{
+ if( rMyCell.bHasAreaLink )
+ {
+ const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink;
+ AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr );
+ AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter );
+ if( rAreaLink.sFilterOptions.getLength() )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions );
+ OUStringBuffer sValue;
+ SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetColCount() );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, sValue.makeStringAndClear() );
+ SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetRowCount() );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, sValue.makeStringAndClear() );
+ if( rAreaLink.nRefresh )
+ {
+ SvXMLUnitConverter::convertTime( sValue, (double)rAreaLink.nRefresh / 86400 );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() );
+ }
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, sal_True, sal_True );
+ }
+}
+
+void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape)
+{
+ if (pCurrentCell && pCurrentCell->xNoteShape.is() && pCurrentCell->xNoteShape.get() == xShape.get() && pCurrentCell->xAnnotation.is())
+ {
+ rtl::OUString sAuthor(pCurrentCell->xAnnotation->getAuthor());
+ if (sAuthor.getLength())
+ {
+ SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
+ XML_CREATOR, sal_True,
+ sal_False );
+ Characters(sAuthor);
+ }
+
+ String aDate(pCurrentCell->xAnnotation->getDate());
+ if (pDoc)
+ {
+ SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
+ double fDate;
+ sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
+ if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
+ {
+ rtl::OUStringBuffer sBuf;
+ GetMM100UnitConverter().convertDateTime(sBuf, fDate,sal_True);
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
+ XML_DATE, sal_True,
+ sal_False );
+ Characters(sBuf.makeStringAndClear());
+ }
+ else
+ {
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
+ XML_DATE_STRING, sal_True,
+ sal_False );
+ Characters(rtl::OUString(aDate));
+ }
+ }
+ else
+ {
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
+ XML_DATE_STRING, sal_True,
+ sal_False );
+ Characters(rtl::OUString(aDate));
+ }
+ }
+}
+
+void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell)
+{
+ if( rMyCell.bHasAnnotation && rMyCell.xAnnotation.is())
+ {
+/* rtl::OUString sAuthor(rMyCell.xAnnotation->getAuthor());
+ if (sAuthor.getLength())
+ {
+ SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
+ XML_CREATOR, sal_True,
+ sal_False );
+ rtl::OUString sAuthor(sAuthor);
+ Characters(sAuthor);
+ }
+
+ String aDate(rMyCell.xAnnotation->getDate());
+ if (pDoc)
+ {
+ SvNumberFormatter* pNumForm(pDoc->GetFormatTable());
+ double fDate;
+ sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
+ if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
+ {
+ rtl::OUStringBuffer sBuf;
+ GetMM100UnitConverter().convertDateTime(sBuf, fDate);
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
+ XML_DATE, sal_True,
+ sal_False );
+ Characters(sBuf.makeStringAndClear());
+ }
+ else
+ {
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
+ XML_DATE_STRING, sal_True,
+ sal_False );
+ Characters(rtl::OUString(aDate));
+ }
+ }
+ else
+ {
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
+ XML_DATE_STRING, sal_True,
+ sal_False );
+ Characters(rtl::OUString(aDate));
+ }*/
+
+ if (rMyCell.xAnnotation->getIsVisible())
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE);
+
+ pCurrentCell = &rMyCell;
+
+ if(rMyCell.xNoteShape.is())
+ GetShapeExport()->exportShape(rMyCell.xNoteShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL);
+
+ pCurrentCell = NULL;
+
+ rMyCell.xNoteShape.clear();
+ }
+}
+
+void ScXMLExport::WriteDetective( const ScMyCell& rMyCell )
+{
+ if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp )
+ {
+ const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec;
+ const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec;
+ sal_Int32 nObjCount(rObjVec.size());
+ sal_Int32 nOpCount(rOpVec.size());
+ if( nObjCount || nOpCount )
+ {
+ SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, sal_True, sal_True );
+ OUString sString;
+ ScMyDetectiveObjVec::const_iterator aObjItr(rObjVec.begin());
+ ScMyDetectiveObjVec::const_iterator aEndObjItr(rObjVec.end());
+ while(aObjItr != aEndObjItr)
+ {
+ if (aObjItr->eObjType != SC_DETOBJ_CIRCLE)
+ {
+ if( (aObjItr->eObjType == SC_DETOBJ_ARROW) || (aObjItr->eObjType == SC_DETOBJ_TOOTHERTAB))
+ {
+ ScRangeStringConverter::GetStringFromRange( sString, aObjItr->aSourceRange, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString );
+ }
+ ScXMLConverter::GetStringFromDetObjType( sString, aObjItr->eObjType );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString );
+ if( aObjItr->bHasError )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE );
+ }
+ else
+ AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE );
+ SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, sal_True, sal_True );
+ ++aObjItr;
+ }
+ OUStringBuffer aBuffer;
+ ScMyDetectiveOpVec::const_iterator aOpItr(rOpVec.begin());
+ ScMyDetectiveOpVec::const_iterator aEndOpItr(rOpVec.end());
+ while(aOpItr != aEndOpItr)
+ {
+ OUString sOpString;
+ ScXMLConverter::GetStringFromDetOpType( sOpString, aOpItr->eOpType );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString );
+ SvXMLUnitConverter::convertNumber( aBuffer, aOpItr->nIndex );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, aBuffer.makeStringAndClear() );
+ SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, sal_True, sal_True );
+ ++aOpItr;
+ }
+ }
+ }
+}
+
+void ScXMLExport::SetRepeatAttribute (const sal_Int32 nEqualCellCount)
+{
+ if (nEqualCellCount > 0)
+ {
+ sal_Int32 nTemp(nEqualCellCount + 1);
+ OUString sOUEqualCellCount(OUString::valueOf(nTemp));
+ AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount);
+ IncrementProgressBar(sal_False, nEqualCellCount);
+ }
+}
+
+sal_Bool ScXMLExport::IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const
+{
+ return (aCell1.nType == aCell2.nType);
+}
+
+sal_Bool ScXMLExport::IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell) const
+{
+ ScAddress aCoreAddress(static_cast<SCCOL>(aAddress.Column),
+ static_cast<SCROW>(aAddress.Row),
+ static_cast<SCTAB>(aAddress.Sheet));
+ ScBaseCell* pBaseCell = GetDocument() ? GetDocument()->GetCell(aCoreAddress) : NULL;
+ if (pMyCell)
+ pMyCell->pBaseCell = pBaseCell;
+
+ if (pBaseCell)
+ return (pBaseCell->GetCellType() == CELLTYPE_EDIT);
+ return sal_False;
+}
+
+//UNUSED2008-05 sal_Bool ScXMLExport::IsEditCell(const com::sun::star::uno::Reference <com::sun::star::table::XCell>& xCell) const
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<sheet::XCellAddressable> xAddressable (xCell, uno::UNO_QUERY);
+//UNUSED2008-05 if ( xAddressable.is() )
+//UNUSED2008-05 return IsEditCell(xAddressable->getCellAddress());
+//UNUSED2008-05 return sal_False;
+//UNUSED2008-05 }
+
+sal_Bool ScXMLExport::IsEditCell(ScMyCell& rCell) const
+{
+ if (rCell.bKnowWhetherIsEditCell)
+ return rCell.bIsEditCell;
+ else
+ {
+ rCell.bIsEditCell = IsEditCell(rCell.aCellAddress, &rCell);
+ rCell.bKnowWhetherIsEditCell = sal_True;
+ return rCell.bIsEditCell;
+ }
+}
+
+sal_Bool ScXMLExport::IsMultiLineFormulaCell(ScMyCell& rCell) const
+{
+ if (rCell.pBaseCell)
+ {
+ if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
+ return false;
+
+ return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
+ }
+
+ ScAddress aAddr(static_cast<SCCOL>(rCell.aCellAddress.Column),
+ static_cast<SCROW>(rCell.aCellAddress.Row),
+ static_cast<SCTAB>(rCell.aCellAddress.Sheet));
+ ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aAddr) : NULL;
+ if (!pBaseCell)
+ return false;
+
+ rCell.pBaseCell = pBaseCell;
+ if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
+ return false;
+
+ return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
+}
+
+//UNUSED2008-05 sal_Bool ScXMLExport::IsAnnotationEqual(const uno::Reference<table::XCell>& /* xCell1 */,
+//UNUSED2008-05 const uno::Reference<table::XCell>& /* xCell2 */)
+//UNUSED2008-05 {
+//UNUSED2008-05 // no longer compareable, because the position and size and other attributes can also differ
+//UNUSED2008-05
+//UNUSED2008-05 /* uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor1(xCell1, uno::UNO_QUERY);
+//UNUSED2008-05 uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor2(xCell2, uno::UNO_QUERY);
+//UNUSED2008-05 if (xSheetAnnotationAnchor1.is() && xSheetAnnotationAnchor2.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation1(xSheetAnnotationAnchor1->getAnnotation());
+//UNUSED2008-05 uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation2(xSheetAnnotationAnchor2->getAnnotation());
+//UNUSED2008-05 uno::Reference<text::XSimpleText> xSimpleText1(xSheetAnnotation1, uno::UNO_QUERY);
+//UNUSED2008-05 uno::Reference<text::XSimpleText> xSimpleText2(xSheetAnnotation2, uno::UNO_QUERY);
+//UNUSED2008-05 if (xSheetAnnotation1.is() && xSimpleText1.is() &&
+//UNUSED2008-05 xSheetAnnotation2.is() && xSimpleText2.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 rtl::OUString sText1(xSimpleText1->getString());
+//UNUSED2008-05 rtl::OUString sText2(xSimpleText2->getString());
+//UNUSED2008-05 sal_Int32 nLength1(sText1.getLength());
+//UNUSED2008-05 sal_Int32 nLength2(sText2.getLength());
+//UNUSED2008-05 if (nLength1 && nLength2)
+//UNUSED2008-05 if (sText1 == sText2 &&
+//UNUSED2008-05 xSheetAnnotation1->getAuthor() == xSheetAnnotation2->getAuthor() &&
+//UNUSED2008-05 xSheetAnnotation1->getDate() == xSheetAnnotation2->getDate() &&
+//UNUSED2008-05 xSheetAnnotation1->getIsVisible() == xSheetAnnotation2->getIsVisible())
+//UNUSED2008-05 return sal_True;
+//UNUSED2008-05 else
+//UNUSED2008-05 return sal_False;
+//UNUSED2008-05 else
+//UNUSED2008-05 if (nLength1 || nLength2)
+//UNUSED2008-05 return sal_False;
+//UNUSED2008-05 else
+//UNUSED2008-05 return sal_True;
+//UNUSED2008-05 }
+//UNUSED2008-05 }*/
+//UNUSED2008-05 return sal_False;
+//UNUSED2008-05 }
+
+sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2)
+{
+ ScAddress aCellPos1;
+ ScUnoConversion::FillScAddress( aCellPos1, aCell1.aCellAddress );
+ ScAddress aCellPos2;
+ ScUnoConversion::FillScAddress( aCellPos2, aCell2.aCellAddress );
+ sal_Bool bIsEqual = sal_False;
+ if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase &&
+ aCell1.bIsCovered == aCell2.bIsCovered &&
+ !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase &&
+ aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered &&
+ aCell1.bHasAnnotation == aCell2.bHasAnnotation &&
+ !aCell1.bHasShape && !aCell2.bHasShape &&
+ aCell1.bHasAreaLink == aCell2.bHasAreaLink &&
+ !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj)
+ {
+ if( (aCell1.bHasAreaLink &&
+ (aCell1.aAreaLink.GetColCount() == 1) &&
+ (aCell2.aAreaLink.GetColCount() == 1) &&
+ aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) ||
+ !aCell1.bHasAreaLink )
+ {
+ if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && sal_False/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable
+ {
+ if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) ||
+ ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) &&
+ (aCell1.nValidationIndex == aCell2.nValidationIndex) &&
+ IsCellTypeEqual(aCell1, aCell2))
+ {
+ switch ( aCell1.nType )
+ {
+ case table::CellContentType_EMPTY :
+ {
+ bIsEqual = sal_True;
+ }
+ break;
+ case table::CellContentType_VALUE :
+ {
+ if(!aCell1.bHasDoubleValue)
+ {
+ aCell1.fValue = pDoc->GetValue( aCellPos1 );
+ aCell1.bHasDoubleValue = sal_True;
+ }
+ if (!aCell2.bHasDoubleValue)
+ {
+ aCell2.fValue = pDoc->GetValue( aCellPos2 );
+ aCell2.bHasDoubleValue = sal_True;
+ }
+ // #i29101# number format may be different from column default styles,
+ // but can lead to different value types, so it must also be compared
+ bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) &&
+ (aCell1.fValue == aCell2.fValue);
+ }
+ break;
+ case table::CellContentType_TEXT :
+ {
+ if (IsEditCell(aCell1) || IsEditCell(aCell2))
+ bIsEqual = sal_False;
+ else
+ {
+ if (GetCellText(aCell1, aCellPos1) && GetCellText(aCell2, aCellPos2))
+ {
+ bIsEqual = (aCell1.sStringValue == aCell2.sStringValue) &&
+ (lcl_GetRawString(pDoc, aCellPos1) == lcl_GetRawString(pDoc, aCellPos2));
+ }
+ else
+ bIsEqual = sal_False;
+ }
+ }
+ break;
+ case table::CellContentType_FORMULA :
+ {
+ bIsEqual = sal_False;
+ }
+ break;
+ default :
+ {
+ bIsEqual = sal_False;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ return bIsEqual;
+}
+
+void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ sal_Bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN))) ));
+ sal_Bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE))) ));
+ sal_Bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS))) ));
+ sal_Bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE))) ));
+ sal_Bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED))) ));
+ sal_Bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED))) ));
+ sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0);
+ sal_Int32 nIterationCount(100);
+ xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT))) >>= nIterationCount;
+ double fIterationEpsilon = 0;
+ xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON))) >>= fIterationEpsilon;
+ util::Date aNullDate;
+ xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE))) >>= aNullDate;
+ if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions ||
+ bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) ||
+ aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930)
+ {
+ if (bIgnoreCase)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE);
+ if (bCalcAsShown)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE);
+ if (!bMatchWholeCell)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE);
+ if (!bLookUpLabels)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE);
+ if (!bUseRegularExpressions)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE);
+ if (nYear2000 != 1930)
+ {
+ rtl::OUStringBuffer sBuffer;
+ GetMM100UnitConverter().convertNumber(sBuffer, nYear2000);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True);
+ {
+ if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899)
+ {
+ rtl::OUStringBuffer sDate;
+ GetMM100UnitConverter().convertDateTime(sDate, 0.0, aNullDate);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear());
+ SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True);
+ }
+ if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001))
+ {
+ rtl::OUStringBuffer sBuffer;
+ if (bIsIterationEnabled)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE);
+ if (nIterationCount != 100)
+ {
+ GetMM100UnitConverter().convertNumber(sBuffer, nIterationCount);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, sBuffer.makeStringAndClear());
+ }
+ if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001))
+ {
+ GetMM100UnitConverter().convertDouble(sBuffer, fIterationEpsilon);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, sal_True, sal_True);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExport::WriteTableSource()
+{
+ uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY);
+ if (xLinkable.is() && GetModel().is())
+ {
+ sheet::SheetLinkMode nMode (xLinkable->getLinkMode());
+ if (nMode != sheet::SheetLinkMode_NONE)
+ {
+ rtl::OUString sLink (xLinkable->getLinkUrl());
+ uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY);
+ if (xProps.is())
+ {
+ uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETLINKS))), uno::UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nCount(xIndex->getCount());
+ if (nCount)
+ {
+ sal_Bool bFound(sal_False);
+ uno::Reference <beans::XPropertySet> xLinkProps;
+ for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i)
+ {
+ xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY);
+ if (xLinkProps.is())
+ {
+ rtl::OUString sNewLink;
+ if (xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_LINKURL))) >>= sNewLink)
+ bFound = sLink.equals(sNewLink);
+ }
+ }
+ if (bFound && xLinkProps.is())
+ {
+ rtl::OUString sFilter;
+ rtl::OUString sFilterOptions;
+ rtl::OUString sTableName (xLinkable->getLinkSheetName());
+ sal_Int32 nRefresh(0);
+ xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTER))) >>= sFilter;
+ xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTOPT))) >>= sFilterOptions;
+ xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_REFDELAY))) >>= nRefresh;
+ if (sLink.getLength())
+ {
+ AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink));
+ if (sTableName.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName);
+ if (sFilter.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter);
+ if (sFilterOptions.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions);
+ if (nMode != sheet::SheetLinkMode_NORMAL)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
+ if( nRefresh )
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
+ }
+ SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// core implementation
+void ScXMLExport::WriteScenario()
+{
+ if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable)))
+ {
+ String sComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+ pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags);
+ if (!(nFlags & SC_SCENARIO_SHOWFRAME))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE);
+ rtl::OUStringBuffer aBuffer;
+ SvXMLUnitConverter::convertColor(aBuffer, aColor);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear());
+ if (!(nFlags & SC_SCENARIO_TWOWAY))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE);
+ if (!(nFlags & SC_SCENARIO_ATTRIB))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE);
+ if (nFlags & SC_SCENARIO_VALUE)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE);
+ if (nFlags & SC_SCENARIO_PROTECT)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
+ SvXMLUnitConverter::convertBool(aBuffer, pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable)));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear());
+ const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable));
+ rtl::OUString sRangeListStr;
+ ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr);
+ if (sComment.Len())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, rtl::OUString(sComment));
+ SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc )
+{
+ uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY );
+ if( !xDocProp.is() ) return;
+
+ sal_Int32 nCount(0);
+ uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLLABELRNG ) ) ), uno::UNO_QUERY);
+ if( xColRangesIAccess.is() )
+ nCount += xColRangesIAccess->getCount();
+
+ uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ROWLABELRNG ) ) ), uno::UNO_QUERY);
+ if( xRowRangesIAccess.is() )
+ nCount += xRowRangesIAccess->getCount();
+
+ if( nCount )
+ {
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, sal_True, sal_True );
+ WriteLabelRanges( xColRangesIAccess, sal_True );
+ WriteLabelRanges( xRowRangesIAccess, sal_False );
+ }
+}
+
+void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn )
+{
+ if( !xRangesIAccess.is() ) return;
+
+ sal_Int32 nCount(xRangesIAccess->getCount());
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
+ if( xRange.is() )
+ {
+ OUString sRangeStr;
+ table::CellRangeAddress aCellRange( xRange->getLabelArea() );
+ ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr );
+ aCellRange = xRange->getDataArea();
+ ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW );
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, sal_True, sal_True );
+ }
+ }
+}
+
+void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XNamedRanges> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NAMEDRANGES))), uno::UNO_QUERY);
+ CheckAttrList();
+ if (xNamedRanges.is())
+ {
+ uno::Sequence <rtl::OUString> aRangesNames(xNamedRanges->getElementNames());
+ sal_Int32 nNamedRangesCount(aRangesNames.getLength());
+ if (nNamedRangesCount > 0)
+ {
+ if (pDoc)
+ {
+ ScRangeName* pNamedRanges(pDoc->GetRangeName());
+ SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nNamedRangesCount; ++i)
+ {
+ CheckAttrList();
+ rtl::OUString sNamedRange(aRangesNames[i]);
+ uno::Reference <sheet::XNamedRange> xNamedRange(xNamedRanges->getByName(sNamedRange), uno::UNO_QUERY);
+ if (xNamedRange.is())
+ {
+ uno::Reference <container::XNamed> xNamed (xNamedRange, uno::UNO_QUERY);
+ uno::Reference <sheet::XCellRangeReferrer> xCellRangeReferrer (xNamedRange, uno::UNO_QUERY);
+ if (xNamed.is() && xCellRangeReferrer.is())
+ {
+ rtl::OUString sOUName(xNamed->getName());
+ AddAttribute(sAttrName, sOUName);
+
+ OUString sOUBaseCellAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUBaseCellAddress,
+ xNamedRange->getReferencePosition(), pDoc, FormulaGrammar::CONV_OOO, ' ', sal_False, SCA_ABS_3D );
+ AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sOUBaseCellAddress);
+
+ sal_uInt16 nRangeIndex;
+ String sName(sOUName);
+ pNamedRanges->SearchName(sName, nRangeIndex);
+ ScRangeData* pNamedRange((*pNamedRanges)[nRangeIndex]); //should get directly and not with ScDocument
+ String sContent;
+ pNamedRange->GetSymbol(sContent, pDoc->GetStorageGrammar());
+ rtl::OUString sOUTempContent(sContent);
+ uno::Reference <table::XCellRange> xCellRange(xCellRangeReferrer->getReferredCells());
+ if(xCellRange.is())
+ {
+ rtl::OUString sOUContent(sOUTempContent.copy(1, sOUTempContent.getLength() - 2));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sOUContent);
+ sal_Int32 nRangeType(xNamedRange->getType());
+ rtl::OUStringBuffer sBufferRangeType;
+ if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER)
+ sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN));
+ if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER)
+ {
+ if (sBufferRangeType.getLength() > 0)
+ sBufferRangeType.appendAscii(" ");
+ sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW));
+ }
+ if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA)
+ {
+ if (sBufferRangeType.getLength() > 0)
+ sBufferRangeType.appendAscii(" ");
+ sBufferRangeType.append(GetXMLToken(XML_FILTER));
+ }
+ if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA)
+ {
+ if (sBufferRangeType.getLength() > 0)
+ sBufferRangeType.appendAscii(" ");
+ sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE));
+ }
+ rtl::OUString sRangeType = sBufferRangeType.makeStringAndClear();
+ if (sRangeType.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType);
+ SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, sal_True, sal_True);
+ }
+ else
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sOUTempContent);
+ SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExport::WriteExternalRefCaches()
+{
+ if (!pDoc)
+ return;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pRefMgr->resetSrcFileData(GetOrigFileName());
+ sal_uInt16 nCount = pRefMgr->getExternalFileCount();
+ for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
+ {
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ continue;
+
+ vector<String> aTabNames;
+ pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+ if (aTabNames.empty())
+ continue;
+
+ for (vector<String>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end();
+ itr != itrEnd; ++itr)
+ {
+ ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
+ if (!pTable.get() || !pTable->isReferenced())
+ continue;
+
+ OUStringBuffer aBuf;
+ aBuf.append(sal_Unicode('\''));
+ aBuf.append(*pUrl);
+ aBuf.append(sal_Unicode('\''));
+ aBuf.append(sal_Unicode('#'));
+ aBuf.append(*itr);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aBuf.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName);
+ SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
+ {
+ const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId);
+ if (pExtFileData)
+ {
+ String aRelUrl;
+ if (pExtFileData->maRelativeName.Len())
+ aRelUrl = pExtFileData->maRelativeName;
+ else
+ aRelUrl = GetRelativeReference(pExtFileData->maRelativeName);
+ AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr);
+ if (pExtFileData->maFilterName.Len())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName);
+ if (pExtFileData->maFilterOptions.Len())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
+ }
+ SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
+ }
+
+ // Determine maximum column count of used area, for repeated cells.
+ SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere..
+ vector<SCROW> aRows;
+ pTable->getAllRows(aRows);
+ for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
+ itrRow != itrRowEnd; ++itrRow)
+ {
+ SCROW nRow = *itrRow;
+ vector<SCCOL> aCols;
+ pTable->getAllCols(nRow, aCols);
+ if (!aCols.empty())
+ {
+ SCCOL nCol = aCols.back();
+ if (nMaxColsUsed <= nCol)
+ nMaxColsUsed = nCol + 1;
+ }
+ }
+
+ // Column definitions have to be present to make a valid file
+ {
+ if (nMaxColsUsed > 1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
+ OUString::valueOf(static_cast<sal_Int32>(nMaxColsUsed)));
+ SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
+ }
+
+ // Write cache content for this table.
+ SCROW nLastRow = 0;
+ bool bFirstRow = true;
+ for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
+ itrRow != itrRowEnd; ++itrRow)
+ {
+ SCROW nRow = *itrRow;
+ if (bFirstRow)
+ {
+ if (nRow > 0)
+ {
+ if (nRow > 1)
+ {
+ OUStringBuffer aVal;
+ aVal.append(nRow);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+ else
+ {
+ SCROW nRowGap = nRow - nLastRow;
+ if (nRowGap > 1)
+ {
+ if (nRowGap > 2)
+ {
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nRowGap-1));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+ SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+
+ vector<SCCOL> aCols;
+ pTable->getAllCols(nRow, aCols);
+ SCCOL nLastCol = 0;
+ bool bFirstCol = true;
+ for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end();
+ itrCol != itrColEnd; ++itrCol)
+ {
+ SCCOL nCol = *itrCol;
+ if (bFirstCol)
+ {
+ if (nCol > 0)
+ {
+ if (nCol > 1)
+ {
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nCol));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+ else
+ {
+ SCCOL nColGap = nCol - nLastCol;
+ if (nColGap > 1)
+ {
+ if (nColGap > 2)
+ {
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nColGap-1));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+
+ // Write out this cell.
+ sal_uInt32 nNumFmt = 0;
+ ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt);
+ OUString aStrVal;
+ if (pToken.get())
+ {
+ sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt);
+ if (nIndex >= 0)
+ {
+ const OUString aStyleName = *pCellStyles->GetStyleNameByIndex(nIndex, true);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName);
+ }
+
+ switch(pToken->GetType())
+ {
+ case svDouble:
+ {
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
+ OUStringBuffer aVal;
+ aVal.append(pToken->GetDouble());
+ aStrVal = aVal.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal);
+ }
+ break;
+ case svString:
+ {
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ aStrVal = pToken->GetString();
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
+ Characters(aStrVal);
+
+ nLastCol = nCol;
+ bFirstCol = false;
+ }
+ nLastRow = nRow;
+ bFirstRow = false;
+ }
+ }
+ }
+}
+
+// core implementation
+void ScXMLExport::WriteConsolidation()
+{
+ if (pDoc)
+ {
+ const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData());
+ if( pCons )
+ {
+ OUString sStrData;
+
+ ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData );
+
+ sStrData = OUString();
+ for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex )
+ ScRangeStringConverter::GetStringFromArea( sStrData, *pCons->ppDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, sal_True );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData );
+
+ ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData );
+
+ if( pCons->bByCol && !pCons->bByRow )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN );
+ else if( !pCons->bByCol && pCons->bByRow )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW );
+ else if( pCons->bByCol && pCons->bByRow )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH );
+
+ if( pCons->bReferenceData )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE );
+
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, sal_True, sal_True );
+ }
+ }
+}
+
+SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool()
+{
+ return new ScXMLAutoStylePoolP(*this);
+}
+
+XMLPageExport* ScXMLExport::CreatePageExport()
+{
+ return new XMLTableMasterPageExport( *this );
+}
+
+void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : NULL);
+ if (pViewSettings)
+ {
+ sal_Int32 nChangePos(rProps.getLength());
+ rProps.realloc(nChangePos + 1);
+ beans::PropertyValue* pProps(rProps.getArray());
+ if (pProps)
+ {
+ uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT);
+ beans::PropertyValue* pChangeProps(aChangeProps.getArray());
+ if (pChangeProps)
+ {
+ pChangeProps[SC_SHOW_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChanges"));
+ pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges();
+ pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowAcceptedChanges"));
+ pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted();
+ pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRejectedChanges"));
+ pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected();
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetime"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate();
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeMode"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode());
+ util::DateTime aDateTime;
+ ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheFirstDateTime(), aDateTime);
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeFirstDatetime"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= aDateTime;
+ ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheLastDateTime(), aDateTime);
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeSecondDatetime"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= aDateTime;
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthor"));
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor();
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthorName"));
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= rtl::OUString (pViewSettings->GetTheAuthorToShow());
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByComment"));
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment();
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByCommentText"));
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= rtl::OUString (pViewSettings->GetTheComment());
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRanges"));
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange();
+ rtl::OUString sRangeList;
+ ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO);
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRangesList"));
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList;
+
+ pProps[nChangePos].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesViewSettings"));
+ pProps[nChangePos].Value <<= aChangeProps;
+ }
+ }
+ }
+}
+
+void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ rProps.realloc(4);
+ beans::PropertyValue* pProps(rProps.getArray());
+ if(pProps)
+ {
+ if (GetModel().is())
+ {
+ ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
+ if (pDocObj)
+ {
+ SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
+ if (pEmbeddedObj)
+ {
+ Rectangle aRect(pEmbeddedObj->GetVisArea());
+ sal_uInt16 i(0);
+ pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaTop"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY());
+ pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaLeft"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX());
+ pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaWidth"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth());
+ pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaHeight"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight());
+ }
+ }
+ }
+ }
+ GetChangeTrackViewSettings(rProps);
+}
+
+
+
+
+void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY);
+ if (xProperties.is())
+ SvXMLUnitConverter::convertPropertySet(rProps, xProperties);
+
+ sal_Int32 nPropsToAdd = 0;
+ rtl::OUStringBuffer aTrackedChangesKey;
+ if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
+ {
+ SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection());
+ if (aTrackedChangesKey.getLength())
+ ++nPropsToAdd;
+ }
+
+ uno::Reference <container::XNameAccess> xCodeNameAccess;
+ DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
+ if( pDoc && pDoc->IsInVBAMode() )
+ {
+ xCodeNameAccess = new XMLCodeNameProvider( pDoc );
+ if( xCodeNameAccess.is() && xCodeNameAccess->hasElements() )
+ ++nPropsToAdd;
+ else
+ xCodeNameAccess = 0;
+ }
+
+ if( nPropsToAdd > 0 )
+ {
+ sal_Int32 nCount(rProps.getLength());
+ rProps.realloc(nCount + nPropsToAdd);
+ if (aTrackedChangesKey.getLength())
+ {
+ rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey"));
+ rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear();
+ ++nCount;
+ }
+ if( xCodeNameAccess.is() )
+ {
+ rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration"));
+ rProps[nCount].Value <<= xCodeNameAccess;
+ }
+ }
+ }
+ }
+}
+
+XMLShapeExport* ScXMLExport::CreateShapeExport()
+{
+ return new ScXMLShapeExport(*this);
+}
+
+void ScXMLExport::CreateSharedData(const sal_Int32 nTableCount)
+{
+ pSharedData = new ScMySharedData(nTableCount);
+}
+
+XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper()
+{
+ if (!pNumberFormatAttributesExportHelper)
+ pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this );
+ return pNumberFormatAttributesExportHelper;
+}
+
+void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib)
+{
+ const SfxPoolItem* pItem;
+ sal_uInt16 nItems(pPool->GetItemCount( nAttrib ));
+ for( sal_uInt16 i = 0; i < nItems; ++i )
+ {
+ if( 0 != (pItem = pPool->GetItem( nAttrib, i ) ) )
+ {
+ const SvXMLAttrContainerItem *pUnknown((const SvXMLAttrContainerItem *)pItem);
+ if( (pUnknown->GetAttrCount() > 0) )
+ {
+ sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
+ while( USHRT_MAX != nIdx )
+ {
+ if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
+ {
+ const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
+ // Add namespace declaration for unknown attributes if
+ // there aren't existing ones for the prefix used by the
+ // attibutes
+ _GetNamespaceMap().Add( rPrefix,
+ pUnknown->GetNamespace( nIdx ),
+ XML_NAMESPACE_UNKNOWN );
+ }
+ nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
+ }
+ }
+ }
+ }
+
+ // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
+ _GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_PRESENTATION ),
+ GetXMLToken( XML_N_PRESENTATION ),
+ XML_NAMESPACE_PRESENTATION );
+}
+
+void ScXMLExport::IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc)
+{
+ nProgressCount += nInc;
+ if (bEditCell || nProgressCount > 100)
+ {
+ GetProgressBarHelper()->Increment(nProgressCount);
+ nProgressCount = 0;
+ }
+}
+
+sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass )
+{
+ if( (getExportFlags() & (EXPORT_FONTDECLS|EXPORT_STYLES|
+ EXPORT_MASTERSTYLES|EXPORT_CONTENT)) != 0 )
+ {
+ if (GetDocument())
+ {
+ CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF);
+ CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS);
+ CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS);
+ ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS);
+ CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS);
+ CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES);
+ }
+
+ // sheet events use officeooo namespace
+ if( (getExportFlags() & EXPORT_CONTENT) != 0 &&
+ getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
+ {
+ bool bAnySheetEvents = false;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (pDoc->GetSheetEvents(nTab))
+ bAnySheetEvents = true;
+ if (bAnySheetEvents)
+ _GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_OFFICE_EXT ),
+ GetXMLToken( XML_N_OFFICE_EXT ),
+ XML_NAMESPACE_OFFICE_EXT );
+ }
+ }
+ }
+ return SvXMLExport::exportDoc( eClass );
+}
+
+// XExporter
+void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SvXMLExport::setSourceDocument( xComponent );
+
+ pDoc = ScXMLConverter::GetScDocument( GetModel() );
+ DBG_ASSERT( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" );
+ if (!pDoc)
+ throw lang::IllegalArgumentException();
+
+ // create ScChangeTrackingExportHelper after document is known
+ pChangeTrackingExportHelper = new ScChangeTrackingExportHelper(*this);
+
+ // Set the document's storage grammar corresponding to the ODF version that
+ // is to be written.
+ SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion();
+ switch (meODFDefaultVersion)
+ {
+ // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
+ case SvtSaveOptions::ODFVER_010:
+ case SvtSaveOptions::ODFVER_011:
+ pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF);
+ break;
+ default:
+ pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF);
+ }
+}
+
+// XFilter
+sal_Bool SAL_CALL ScXMLExport::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDoc)
+ pDoc->DisableIdle(TRUE);
+ sal_Bool bReturn(SvXMLExport::filter(aDescriptor));
+ if (pDoc)
+ pDoc->DisableIdle(FALSE);
+ return bReturn;
+}
+
+void SAL_CALL ScXMLExport::cancel()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDoc)
+ pDoc->DisableIdle(FALSE);
+ SvXMLExport::cancel();
+}
+
+// XInitialization
+void SAL_CALL ScXMLExport::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SvXMLExport::initialize(aArguments);
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ScXMLExport::getImplementationName( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_uInt16 nFlags = getExportFlags();
+ if (nFlags & EXPORT_OASIS)
+ {
+ nFlags |= EXPORT_OASIS;
+ switch( nFlags )
+ {
+ case EXPORT_ALL:
+ return ScXMLOasisExport_getImplementationName();
+ case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
+ return ScXMLOasisExport_Styles_getImplementationName();
+ case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
+ return ScXMLOasisExport_Content_getImplementationName();
+ case EXPORT_META:
+ return ScXMLOasisExport_Meta_getImplementationName();
+ case EXPORT_SETTINGS:
+ return ScXMLOasisExport_Settings_getImplementationName();
+ default:
+ // generic name for 'unknown' cases
+ return ScXMLOasisExport_getImplementationName();
+ }
+ }
+ else
+ {
+ switch( nFlags )
+ {
+ case EXPORT_ALL:
+ return ScXMLOOoExport_getImplementationName();
+ case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
+ return ScXMLOOoExport_Styles_getImplementationName();
+ case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
+ return ScXMLOOoExport_Content_getImplementationName();
+ case EXPORT_META:
+ return ScXMLOOoExport_Meta_getImplementationName();
+ case EXPORT_SETTINGS:
+ return ScXMLOOoExport_Settings_getImplementationName();
+ default:
+ // generic name for 'unknown' cases
+ return ScXMLOOoExport_getImplementationName();
+ }
+ }
+ return SvXMLExport::getImplementationName();
+}
+
+sal_Bool SAL_CALL ScXMLExport::supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return SvXMLExport::supportsService( ServiceName );
+}
+
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ScXMLExport::getSupportedServiceNames( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return SvXMLExport::getSupportedServiceNames();
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL ScXMLExport::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return SvXMLExport::getSomething(aIdentifier);
+}
+
+void ScXMLExport::DisposingModel()
+{
+ SvXMLExport::DisposingModel();
+ pDoc = NULL;
+ xCurrentTable = 0;
+}
+
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
new file mode 100644
index 000000000000..e024fc6a0de0
--- /dev/null
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLEXPRT_HXX
+#define SC_XMLEXPRT_HXX
+
+#include <xmloff/xmlexp.hxx>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace beans { class XPropertySet; }
+} } }
+
+#include <hash_map>
+
+class ScOutlineArray;
+class SvXMLExportPropertyMapper;
+class ScMyShapesContainer;
+class ScMyMergedRangesContainer;
+class ScMyValidationsContainer;
+class ScMyNotEmptyCellsIterator;
+class ScChangeTrackingExportHelper;
+class ScColumnStyles;
+class ScRowStyles;
+class ScFormatRangeStyles;
+class ScRowFormatRanges;
+class ScMyOpenCloseColumnRowGroup;
+class ScMyAreaLinksContainer;
+class ScMyDetectiveOpContainer;
+struct ScMyCell;
+class ScDocument;
+class ScMySharedData;
+class ScMyDefaultStyles;
+class XMLNumberFormatAttributesExportHelper;
+class ScChartListener;
+class SfxItemPool;
+class ScAddress;
+class ScBaseCell;
+
+typedef std::vector< com::sun::star::uno::Reference < com::sun::star::drawing::XShapes > > ScMyXShapesVec;
+
+class ScXMLExport : public SvXMLExport
+{
+ ScDocument* pDoc;
+ com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet> xCurrentTable;
+ com::sun::star::uno::Reference <com::sun::star::table::XCellRange> xCurrentTableCellRange;
+
+ com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xSourceStream;
+ sal_Int32 nSourceStreamPos;
+
+ UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory;
+ UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xRowStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xTableStylesPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xCellStylesExportPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xColumnStylesExportPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xRowStylesExportPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xTableStylesExportPropertySetMapper;
+ XMLNumberFormatAttributesExportHelper* pNumberFormatAttributesExportHelper;
+ typedef ::std::hash_map<sal_Int32, sal_Int32> NumberFormatIndexMap;
+ NumberFormatIndexMap aNumFmtIndexMap;
+ ScMySharedData* pSharedData;
+ ScColumnStyles* pColumnStyles;
+ ScRowStyles* pRowStyles;
+ ScFormatRangeStyles* pCellStyles;
+ ScRowFormatRanges* pRowFormatRanges;
+ std::vector<rtl::OUString> aTableStyles;
+ com::sun::star::table::CellRangeAddress aRowHeaderRange;
+ ScMyOpenCloseColumnRowGroup* pGroupColumns;
+ ScMyOpenCloseColumnRowGroup* pGroupRows;
+ ScMyDefaultStyles* pDefaults;
+ ScChartListener* pChartListener;
+ const ScMyCell* pCurrentCell;
+
+ ScMyMergedRangesContainer* pMergedRangesContainer;
+ ScMyValidationsContainer* pValidationsContainer;
+ ScMyNotEmptyCellsIterator* pCellsItr;
+ ScChangeTrackingExportHelper* pChangeTrackingExportHelper;
+ const rtl::OUString sLayerID;
+ const rtl::OUString sCaptionShape;
+ rtl::OUString sExternalRefTabStyleName;
+ rtl::OUString sAttrName;
+ rtl::OUString sAttrStyleName;
+ rtl::OUString sAttrColumnsRepeated;
+ rtl::OUString sAttrFormula;
+ rtl::OUString sAttrValueType;
+ rtl::OUString sAttrStringValue;
+ rtl::OUString sElemCell;
+ rtl::OUString sElemCoveredCell;
+ rtl::OUString sElemCol;
+ rtl::OUString sElemRow;
+ rtl::OUString sElemTab;
+ rtl::OUString sElemP;
+ sal_Int32 nOpenRow;
+ sal_Int32 nProgressCount;
+ sal_uInt16 nCurrentTable;
+ sal_Bool bHasRowHeader;
+ sal_Bool bRowHeaderOpen;
+ sal_Bool mbShowProgress;
+
+ sal_Int32 GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const;
+ sal_Bool HasDrawPages(com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xDoc);
+ void CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount);
+ void CollectShapesAutoStyles(const sal_Int32 nTableCount);
+ void WriteTablesView(const com::sun::star::uno::Any& aTableView);
+ void WriteView(const com::sun::star::uno::Any& aView);
+ virtual void _ExportFontDecls();
+ virtual void _ExportStyles( sal_Bool bUsed );
+ virtual void _ExportAutoStyles();
+ virtual void _ExportMasterStyles();
+ virtual void SetBodyAttributes();
+ virtual void _ExportContent();
+ virtual void _ExportMeta();
+
+ void CollectInternalShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ com::sun::star::table::CellRangeAddress GetEndAddress(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& xTable,
+ const sal_Int32 nTable);
+// ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges();
+ void GetAreaLinks( com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, ScMyAreaLinksContainer& rAreaLinks );
+ void GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp );
+ void WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
+ const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible);
+ void WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
+ const sal_Int32 nStyleIndex, const sal_Bool bIsVisible);
+ void OpenHeaderColumn();
+ void CloseHeaderColumn();
+ void ExportColumns(const sal_Int32 nTable, const com::sun::star::table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader);
+ void ExportExternalRefCacheStyles();
+ void ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
+ const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet);
+ void WriteRowContent();
+ void WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nEmptyRows);
+ void OpenHeaderRows();
+ void CloseHeaderRows();
+ void OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows);
+ void OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag,
+ const sal_Int32 nStartRow, const sal_Int32 nEmptyRows);
+ void OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow);
+ void CloseRow(const sal_Int32 nRow);
+ void GetColumnRowHeader(sal_Bool& bHasColumnHeader, com::sun::star::table::CellRangeAddress& aColumnHeaderRange,
+ sal_Bool& bHasRowHeader, com::sun::star::table::CellRangeAddress& aRowHeaderRange,
+ rtl::OUString& rPrintRanges) const;
+ void FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups);
+ void FillColumnRowGroups();
+
+//UNUSED2008-05 sal_Bool GetMerge (const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable,
+//UNUSED2008-05 sal_Int32 nCol, sal_Int32 nRow,
+//UNUSED2008-05 com::sun::star::table::CellRangeAddress& aCellAddress);
+
+ sal_Bool GetMerged (const com::sun::star::table::CellRangeAddress* pCellRange,
+ const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable);
+
+ sal_Bool GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const;
+
+ void WriteCell (ScMyCell& aCell);
+ void WriteAreaLink(const ScMyCell& rMyCell);
+ void WriteAnnotation(ScMyCell& rMyCell);
+ void WriteDetective(const ScMyCell& rMyCell);
+ void ExportShape(const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape, com::sun::star::awt::Point* pPoint);
+ void WriteShapes(const ScMyCell& rMyCell);
+ void WriteTableShapes();
+ void SetRepeatAttribute (const sal_Int32 nEqualCellCount);
+
+ sal_Bool IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const;
+ sal_Bool IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell = NULL) const;
+//UNUSED2008-05 sal_Bool IsEditCell(const com::sun::star::uno::Reference <com::sun::star::table::XCell>& xCell) const;
+ sal_Bool IsEditCell(ScMyCell& rCell) const;
+ sal_Bool IsMultiLineFormulaCell(ScMyCell& rCell) const;
+//UNUSED2008-05 sal_Bool IsAnnotationEqual(const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell1,
+//UNUSED2008-05 const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell2);
+ sal_Bool IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2);
+
+ void WriteCalculationSettings(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc);
+ void WriteTableSource();
+ void WriteScenario(); // core implementation
+ void WriteTheLabelRanges(const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument >& xSpreadDoc);
+ void WriteLabelRanges( const com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn );
+ void WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc);
+ void WriteExternalRefCaches();
+ void WriteConsolidation(); // core implementation
+
+ void CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib);
+
+ void AddStyleFromCells(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xProperties,
+ const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheet >& xTable,
+ sal_Int32 nTable, const rtl::OUString* pOldName );
+ void AddStyleFromColumn(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xColumnProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible );
+ void AddStyleFromRow(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xRowProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex );
+
+ void IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc = 1);
+
+ void CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd );
+
+protected:
+ virtual SvXMLAutoStylePoolP* CreateAutoStylePool();
+ virtual XMLPageExport* CreatePageExport();
+ virtual XMLShapeExport* CreateShapeExport();
+ virtual XMLFontAutoStylePool* CreateFontAutoStylePool();
+public:
+ // #110680#
+ ScXMLExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nExportFlag);
+
+ virtual ~ScXMLExport();
+
+ static sal_Int16 GetFieldUnit();
+ inline ScDocument* GetDocument() { return pDoc; }
+ inline const ScDocument* GetDocument() const { return pDoc; }
+//UNUSED2008-05 sal_Bool IsMatrix (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange,
+//UNUSED2008-05 const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable,
+//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow,
+//UNUSED2008-05 com::sun::star::table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const;
+ sal_Bool IsMatrix (const ScAddress& aCell,
+ com::sun::star::table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const;
+
+ UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() { return xCellStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() { return xTableStylesPropertySetMapper; }
+
+ void SetSourceStream( const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xNewStream );
+
+ void GetChangeTrackViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
+ virtual void GetViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
+ virtual void GetConfigurationSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
+
+ virtual void exportAnnotationMeta( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape);
+
+ void CreateSharedData(const sal_Int32 nTableCount);
+ void SetSharedData(ScMySharedData* pTemp) { pSharedData = pTemp; }
+ ScMySharedData* GetSharedData() { return pSharedData; }
+ XMLNumberFormatAttributesExportHelper* GetNumberFormatAttributesExportHelper();
+
+ // Export the document.
+ virtual sal_uInt32 exportDoc( enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_TOKEN_INVALID );
+
+ // XExporter
+ virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual void DisposingModel();
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/xmlexternaltabi.cxx b/sc/source/filter/xml/xmlexternaltabi.cxx
new file mode 100644
index 000000000000..083a73d81872
--- /dev/null
+++ b/sc/source/filter/xml/xmlexternaltabi.cxx
@@ -0,0 +1,437 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlexternaltabi.hxx"
+#include "xmlimprt.hxx"
+#include "xmltabi.hxx"
+#include "xmlstyli.hxx"
+
+#include "token.hxx"
+#include "document.hxx"
+
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/util/NumberFormat.hpp>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XAttributeList;
+
+// ============================================================================
+
+ScXMLExternalRefTabSourceContext::ScXMLExternalRefTabSourceContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo)
+{
+ using namespace ::xmloff::token;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i);
+ rtl::OUString aLocalName;
+ sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+ if (nAttrPrefix == XML_NAMESPACE_XLINK)
+ {
+ if (IsXMLToken(aLocalName, XML_HREF))
+ maRelativeUrl = sValue;
+ }
+ else if (nAttrPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_TABLE_NAME))
+ maTableName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_NAME))
+ maFilterName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS))
+ maFilterOptions = sValue;
+ }
+ }
+}
+
+ScXMLExternalRefTabSourceContext::~ScXMLExternalRefTabSourceContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefTabSourceContext::CreateChildContext(
+ USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+/**
+ * Make sure the URL is a valid relative URL, mainly to avoid storing
+ * absolute URL as relative URL by accident. For now, we only check the first
+ * three characters which are assumed to be always '../', because the relative
+ * URL for an external document is always in reference to the content.xml
+ * fragment of the original document.
+ */
+static bool lcl_isValidRelativeURL(const OUString& rUrl)
+{
+ sal_Int32 n = ::std::min( rUrl.getLength(), static_cast<sal_Int32>(3));
+ if (n < 3)
+ return false;
+ const sal_Unicode* p = rUrl.getStr();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (i < 2 && c != '.')
+ // the path must begin with '..'
+ return false;
+ else if (i == 2 && c != '/')
+ // a '/' path separator must follow
+ return false;
+ }
+ return true;
+}
+
+void ScXMLExternalRefTabSourceContext::EndElement()
+{
+ ScDocument* pDoc = mrScImport.GetDocument();
+ if (!pDoc)
+ return;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ if (lcl_isValidRelativeURL(maRelativeUrl))
+ pRefMgr->setRelativeFileName(mrExternalRefInfo.mnFileId, maRelativeUrl);
+ pRefMgr->setFilterData(mrExternalRefInfo.mnFileId, maFilterName, maFilterOptions);
+}
+
+// ============================================================================
+
+ScXMLExternalRefRowsContext::ScXMLExternalRefRowsContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& /* xAttrList */, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo)
+{
+}
+
+ScXMLExternalRefRowsContext::~ScXMLExternalRefRowsContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefRowsContext::CreateChildContext(
+ USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+ // #i101319# row elements inside group, rows or header-rows
+ // are treated like row elements directly in the table element
+
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowsElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROWS_ROW_GROUP:
+ case XML_TOK_TABLE_ROWS_HEADER_ROWS:
+ case XML_TOK_TABLE_ROWS_ROWS:
+ return new ScXMLExternalRefRowsContext(
+ mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+ case XML_TOK_TABLE_ROWS_ROW:
+ return new ScXMLExternalRefRowContext(
+ mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+ default:
+ ;
+ }
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefRowsContext::EndElement()
+{
+}
+
+// ============================================================================
+
+ScXMLExternalRefRowContext::ScXMLExternalRefRowContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo),
+ mnRepeatRowCount(1)
+{
+ mrExternalRefInfo.mnCol = 0;
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap = mrScImport.GetTableRowAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i);
+ rtl::OUString aLocalName;
+ sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+
+ switch (rAttrTokenMap.Get(nAttrPrefix, aLocalName))
+ {
+ case XML_TOK_TABLE_ROW_ATTR_REPEATED:
+ {
+ mnRepeatRowCount = std::max(sValue.toInt32(), static_cast<sal_Int32>(1));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLExternalRefRowContext::~ScXMLExternalRefRowContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefRowContext::CreateChildContext(
+ USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ if (nToken == XML_TOK_TABLE_ROW_CELL || nToken == XML_TOK_TABLE_ROW_COVERED_CELL)
+ return new ScXMLExternalRefCellContext(mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefRowContext::EndElement()
+{
+ ScExternalRefCache::TableTypeRef pTab = mrExternalRefInfo.mpCacheTable;
+
+ for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
+ {
+ // Performance: duplicates of a non-existent row will still not exist.
+ // Don't find that out for every cell.
+ // External references often are a sparse matrix.
+ if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow))
+ {
+ mrExternalRefInfo.mnRow += mnRepeatRowCount;
+ return;
+ }
+
+ for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j)
+ {
+ ScExternalRefCache::TokenRef pToken = pTab->getCell(
+ static_cast<SCCOL>(j), static_cast<SCROW>(mrExternalRefInfo.mnRow));
+
+ if (pToken.get())
+ {
+ pTab->setCell(static_cast<SCCOL>(j),
+ static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken);
+ }
+ }
+ }
+ mrExternalRefInfo.mnRow += mnRepeatRowCount;
+}
+
+// ============================================================================
+
+ScXMLExternalRefCellContext::ScXMLExternalRefCellContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo),
+ mfCellValue(0.0),
+ mnRepeatCount(1),
+ mnNumberFormat(-1),
+ mnCellType(::com::sun::star::util::NumberFormat::UNDEFINED),
+ mbIsNumeric(false),
+ mbIsEmpty(true)
+{
+ using namespace ::xmloff::token;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ OUString aLocalName;
+ sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex(i), &aLocalName);
+
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+ sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
+
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
+ {
+ XMLTableStylesContext* pStyles = static_cast<XMLTableStylesContext*>(mrScImport.GetAutoStyles());
+ const XMLTableStyleContext* pStyle = static_cast<const XMLTableStyleContext*>(
+ pStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sValue, true));
+ if (pStyle)
+ mnNumberFormat = const_cast<XMLTableStyleContext*>(pStyle)->GetNumberFormat();
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
+ {
+ mnRepeatCount = ::std::max(sValue.toInt32(), static_cast<sal_Int32>(1));
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
+ {
+ mnCellType = mrScImport.GetCellType(sValue);
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ mrScImport.GetMM100UnitConverter().convertDouble(mfCellValue, sValue);
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
+ {
+ if (sValue.getLength() && mrScImport.SetNullDateOnUnitConverter())
+ {
+ mrScImport.GetMM100UnitConverter().convertDateTime(mfCellValue, sValue);
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ mrScImport.GetMM100UnitConverter().convertTime(mfCellValue, sValue);
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ maCellString = sValue;
+ mbIsNumeric = false;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ mfCellValue = IsXMLToken(sValue, XML_TRUE) ? 1.0 : 0.0;
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+ScXMLExternalRefCellContext::~ScXMLExternalRefCellContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefCellContext::CreateChildContext(
+ USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowCellElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ if (nToken == XML_TOK_TABLE_ROW_CELL_P)
+ return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, *this);
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefCellContext::EndElement()
+{
+ if (maCellString.getLength())
+ mbIsEmpty = false;
+
+ for (sal_Int32 i = 0; i < mnRepeatCount; ++i, ++mrExternalRefInfo.mnCol)
+ {
+ if (mbIsEmpty)
+ continue;
+
+ ScExternalRefCache::TokenRef aToken;
+ if (mbIsNumeric)
+ aToken.reset(new formula::FormulaDoubleToken(mfCellValue));
+ else
+ aToken.reset(new formula::FormulaStringToken(maCellString));
+
+ sal_uInt32 nNumFmt = mnNumberFormat >= 0 ? static_cast<sal_uInt32>(mnNumberFormat) : 0;
+ mrExternalRefInfo.mpCacheTable->setCell(
+ static_cast<SCCOL>(mrExternalRefInfo.mnCol),
+ static_cast<SCROW>(mrExternalRefInfo.mnRow),
+ aToken, nNumFmt);
+ }
+}
+
+void ScXMLExternalRefCellContext::SetCellString(const OUString& rStr)
+{
+ maCellString = rStr;
+}
+
+// ============================================================================
+
+ScXMLExternalRefCellTextContext::ScXMLExternalRefCellTextContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& /*xAttrList*/,
+ ScXMLExternalRefCellContext& rParent ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrParent(rParent)
+{
+}
+
+ScXMLExternalRefCellTextContext::~ScXMLExternalRefCellTextContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefCellTextContext::CreateChildContext(
+ USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefCellTextContext::Characters(const OUString& rChar)
+{
+ maCellStrBuf.append(rChar);
+}
+
+void ScXMLExternalRefCellTextContext::EndElement()
+{
+ mrParent.SetCellString(maCellStrBuf.makeStringAndClear());
+}
diff --git a/sc/source/filter/xml/xmlexternaltabi.hxx b/sc/source/filter/xml/xmlexternaltabi.hxx
new file mode 100644
index 000000000000..6aaff181315e
--- /dev/null
+++ b/sc/source/filter/xml/xmlexternaltabi.hxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXTERNALTABI_HXX
+#define SC_XMLEXTERNALTABI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include "rtl/ustrbuf.hxx"
+
+class ScXMLImport;
+struct ScXMLExternalTabData;
+
+class ScXMLExternalRefTabSourceContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefTabSourceContext( ScXMLImport& rImport, USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefTabSourceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+
+ ::rtl::OUString maRelativeUrl;
+ ::rtl::OUString maTableName;
+ ::rtl::OUString maFilterName;
+ ::rtl::OUString maFilterOptions;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefRowsContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefRowsContext( ScXMLImport& rImport, USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefRowsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefRowContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefRowContext( ScXMLImport& rImport, USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefRowContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+ sal_Int32 mnRepeatRowCount;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefCellContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefCellContext( ScXMLImport& rImport, USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefCellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetCellString(const ::rtl::OUString& rStr);
+
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+ ::rtl::OUString maCellString;
+ double mfCellValue;
+ sal_Int32 mnRepeatCount;
+ sal_Int32 mnNumberFormat;
+ sal_Int16 mnCellType;
+ bool mbIsNumeric;
+ bool mbIsEmpty;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefCellTextContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefCellTextContext( ScXMLImport& rImport, USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalRefCellContext& rParent );
+
+ virtual ~ScXMLExternalRefCellTextContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters(const ::rtl::OUString& rChar);
+
+ virtual void EndElement();
+
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalRefCellContext& mrParent;
+
+ ::rtl::OUStringBuffer maCellStrBuf;
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlfilti.cxx b/sc/source/filter/xml/xmlfilti.cxx
new file mode 100644
index 000000000000..55670d97637d
--- /dev/null
+++ b/sc/source/filter/xml/xmlfilti.cxx
@@ -0,0 +1,785 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlfilti.hxx"
+#include "xmlimprt.hxx"
+#include "docuno.hxx"
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLFilterContext::ScXMLFilterContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext),
+ aFilterFields(),
+ bSkipDuplicates(sal_False),
+ bCopyOutputData(sal_False),
+ bUseRegularExpressions(sal_False),
+ bConnectionOr(sal_True),
+ bNextConnectionOr(sal_True),
+ bConditionSourceRange(sal_False)
+{
+ ScDocument* pDoc(GetScImport().GetDocument());
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ ScRange aScRange;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart );
+ bCopyOutputData = sal_True;
+ }
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
+ {
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ bConditionSourceRange = sal_True;
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
+ {
+ // not supported by StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
+ {
+ bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLFilterContext::~ScXMLFilterContext()
+{
+}
+
+SvXMLImportContext *ScXMLFilterContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_OR:
+ {
+ pContext = new ScXMLOrContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLFilterContext::EndElement()
+{
+ pDatabaseRangeContext->SetFilterUseRegularExpressions(bUseRegularExpressions);
+ if (bCopyOutputData)
+ {
+ pDatabaseRangeContext->SetFilterOutputPosition(aOutputPosition);
+ pDatabaseRangeContext->SetFilterCopyOutputData(bCopyOutputData);
+ }
+ else
+ pDatabaseRangeContext->SetFilterCopyOutputData(sal_False);
+ pDatabaseRangeContext->SetFilterIsCaseSensitive(bIsCaseSensitive);
+ pDatabaseRangeContext->SetFilterSkipDuplicates(bSkipDuplicates);
+ pDatabaseRangeContext->SetFilterFields(aFilterFields);
+ if (bConditionSourceRange)
+ pDatabaseRangeContext->SetFilterConditionSourceRangeAddress(aConditionSourceRangeAddress);
+}
+
+ScXMLAndContext::ScXMLAndContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext)
+{
+ pFilterContext->OpenConnection(sal_False);
+}
+
+ScXMLAndContext::~ScXMLAndContext()
+{
+}
+
+SvXMLImportContext *ScXMLAndContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_OR:
+ {
+ // not supported in StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLAndContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLOrContext::ScXMLOrContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext)
+{
+ pFilterContext->OpenConnection(sal_True);
+}
+
+ScXMLOrContext::~ScXMLOrContext()
+{
+}
+
+SvXMLImportContext *ScXMLOrContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLOrContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLConditionContext::ScXMLConditionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext),
+ bIsCaseSensitive(sal_False)
+{
+ sDataType = GetXMLToken(XML_TEXT);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
+ {
+ nField = sValue.toInt32();
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
+ {
+ bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_DATA_TYPE :
+ {
+ sDataType = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_VALUE :
+ {
+ sConditionValue = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_OPERATOR :
+ {
+ sOperator = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLConditionContext::~ScXMLConditionContext()
+{
+}
+
+SvXMLImportContext *ScXMLConditionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLConditionContext::getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const
+{
+ bUseRegularExpressions = sal_False;
+ if (IsXMLToken(sTempOperator, XML_MATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = sheet::FilterOperator2::EQUAL;
+ }
+ else if (IsXMLToken(sTempOperator, XML_NOMATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = sheet::FilterOperator2::NOT_EQUAL;
+ }
+ else if (sTempOperator.compareToAscii("=") == 0)
+ aFilterOperator = sheet::FilterOperator2::EQUAL;
+ else if (sTempOperator.compareToAscii("!=") == 0)
+ aFilterOperator = sheet::FilterOperator2::NOT_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
+ aFilterOperator = sheet::FilterOperator2::BOTTOM_PERCENT;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
+ aFilterOperator = sheet::FilterOperator2::BOTTOM_VALUES;
+ else if (IsXMLToken(sTempOperator, XML_EMPTY))
+ aFilterOperator = sheet::FilterOperator2::EMPTY;
+ else if (sTempOperator.compareToAscii(">") == 0)
+ aFilterOperator = sheet::FilterOperator2::GREATER;
+ else if (sTempOperator.compareToAscii(">=") == 0)
+ aFilterOperator = sheet::FilterOperator2::GREATER_EQUAL;
+ else if (sTempOperator.compareToAscii("<") == 0)
+ aFilterOperator = sheet::FilterOperator2::LESS;
+ else if (sTempOperator.compareToAscii("<=") == 0)
+ aFilterOperator = sheet::FilterOperator2::LESS_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_NOEMPTY))
+ aFilterOperator = sheet::FilterOperator2::NOT_EMPTY;
+ else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
+ aFilterOperator = sheet::FilterOperator2::TOP_PERCENT;
+ else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
+ aFilterOperator = sheet::FilterOperator2::TOP_VALUES;
+ else if (IsXMLToken(sTempOperator, XML_CONTAINS))
+ aFilterOperator = sheet::FilterOperator2::CONTAINS;
+ else if (IsXMLToken(sTempOperator, XML_DOES_NOT_CONTAIN))
+ aFilterOperator = sheet::FilterOperator2::DOES_NOT_CONTAIN;
+ else if (IsXMLToken(sTempOperator, XML_BEGINS_WITH))
+ aFilterOperator = sheet::FilterOperator2::BEGINS_WITH;
+ else if (IsXMLToken(sTempOperator, XML_DOES_NOT_BEGIN_WITH))
+ aFilterOperator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH;
+ else if (IsXMLToken(sTempOperator, XML_ENDS_WITH))
+ aFilterOperator = sheet::FilterOperator2::ENDS_WITH;
+ else if (IsXMLToken(sTempOperator, XML_DOES_NOT_END_WITH))
+ aFilterOperator = sheet::FilterOperator2::DOES_NOT_END_WITH;
+}
+
+void ScXMLConditionContext::EndElement()
+{
+ sheet::TableFilterField2 aFilterField;
+ if (pFilterContext->GetConnection())
+ aFilterField.Connection = sheet::FilterConnection_OR;
+ else
+ aFilterField.Connection = sheet::FilterConnection_AND;
+ pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
+ sal_Bool bUseRegularExpressions;
+ getOperatorXML(sOperator, aFilterField.Operator, bUseRegularExpressions);
+ pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
+ aFilterField.Field = nField;
+ if (IsXMLToken(sDataType, XML_NUMBER))
+ {
+ aFilterField.NumericValue = sConditionValue.toDouble();
+ aFilterField.IsNumeric = sal_True;
+ }
+ else
+ {
+ aFilterField.StringValue = sConditionValue;
+ aFilterField.IsNumeric = sal_False;
+ }
+ pFilterContext->AddFilterField(aFilterField);
+}
+
+//==========================================================================
+
+ScXMLDPFilterContext::ScXMLDPFilterContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTableContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTableContext),
+ aFilterFields(),
+ nFilterFieldCount(0),
+ bSkipDuplicates(sal_False),
+ bCopyOutputData(sal_False),
+ bUseRegularExpressions(sal_False),
+ bConnectionOr(sal_True),
+ bNextConnectionOr(sal_True),
+ bConditionSourceRange(sal_False)
+{
+ ScDocument* pDoc(GetScImport().GetDocument());
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ ScRange aScRange;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ aOutputPosition = aScRange.aStart;
+ bCopyOutputData = sal_True;
+ }
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
+ {
+ sal_Int32 nOffset(0);
+ if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ bConditionSourceRange = sal_True;
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
+ {
+ // not supported by StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
+ {
+ bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPFilterContext::~ScXMLDPFilterContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPFilterContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_OR:
+ {
+ pContext = new ScXMLDPOrContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPFilterContext::EndElement()
+{
+ aFilterFields.bRegExp = bUseRegularExpressions;
+ aFilterFields.bCaseSens = bIsCaseSensitive;
+ aFilterFields.bDuplicate = !bSkipDuplicates;
+// pDataPilotTable->SetFilterUseRegularExpressions(bUseRegularExpressions);
+ if (bCopyOutputData)
+ {
+ pDataPilotTable->SetFilterOutputPosition(aOutputPosition);
+ pDataPilotTable->SetFilterCopyOutputData(bCopyOutputData);
+ }
+ else
+ pDataPilotTable->SetFilterCopyOutputData(sal_False);
+// pDataPilotTable->SetFilterIsCaseSensitive(bIsCaseSensitive);
+// pDataPilotTable->SetFilterSkipDuplicates(bSkipDuplicates);
+ pDataPilotTable->SetSourceQueryParam(aFilterFields);
+ if (bConditionSourceRange)
+ pDataPilotTable->SetFilterSourceRange(aConditionSourceRangeAddress);
+}
+
+void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry& aFilterField)
+{
+ aFilterFields.Resize(nFilterFieldCount + 1);
+ ScQueryEntry& rEntry(aFilterFields.GetEntry(nFilterFieldCount));
+ rEntry = aFilterField;
+ rEntry.bDoQuery = sal_True;
+ ++nFilterFieldCount;
+}
+
+ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDPFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ pFilterContext = pTempFilterContext;
+ pFilterContext->OpenConnection(sal_False);
+}
+
+ScXMLDPAndContext::~ScXMLDPAndContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPAndContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_OR:
+ {
+ // not supported in StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPAndContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDPFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext)
+{
+ pFilterContext->OpenConnection(sal_True);
+}
+
+ScXMLDPOrContext::~ScXMLDPOrContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPOrContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPOrContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext),
+ sDataType(GetXMLToken(XML_TEXT)),
+ bIsCaseSensitive(sal_False)
+{
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
+ {
+ nField = sValue.toInt32();
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
+ {
+ bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_DATA_TYPE :
+ {
+ sDataType = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_VALUE :
+ {
+ sConditionValue = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_OPERATOR :
+ {
+ sOperator = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPConditionContext::~ScXMLDPConditionContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPConditionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLDPConditionContext::getOperatorXML(const rtl::OUString sTempOperator, ScQueryOp& aFilterOperator, sal_Bool& bUseRegularExpressions,
+ double& dVal) const
+{
+ bUseRegularExpressions = sal_False;
+ if (IsXMLToken(sTempOperator, XML_MATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = SC_EQUAL;
+ }
+ else if (IsXMLToken(sTempOperator, XML_NOMATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = SC_NOT_EQUAL;
+ }
+ else if (sTempOperator.compareToAscii("=") == 0)
+ aFilterOperator = SC_EQUAL;
+ else if (sTempOperator.compareToAscii("!=") == 0)
+ aFilterOperator = SC_NOT_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
+ aFilterOperator = SC_BOTPERC;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
+ aFilterOperator = SC_BOTVAL;
+ else if (IsXMLToken(sTempOperator, XML_EMPTY))
+ dVal = SC_EMPTYFIELDS;
+ else if (sTempOperator.compareToAscii(">") == 0)
+ aFilterOperator = SC_GREATER;
+ else if (sTempOperator.compareToAscii(">=") == 0)
+ aFilterOperator = SC_GREATER_EQUAL;
+ else if (sTempOperator.compareToAscii("<") == 0)
+ aFilterOperator = SC_LESS;
+ else if (sTempOperator.compareToAscii("<=") == 0)
+ aFilterOperator = SC_LESS_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_NOEMPTY))
+ dVal = SC_NONEMPTYFIELDS;
+ else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
+ aFilterOperator = SC_TOPPERC;
+ else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
+ aFilterOperator = SC_TOPVAL;
+}
+
+void ScXMLDPConditionContext::EndElement()
+{
+ ScQueryEntry aFilterField;
+ if (pFilterContext->GetConnection())
+ aFilterField.eConnect = SC_OR;
+ else
+ aFilterField.eConnect = SC_AND;
+ pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
+ sal_Bool bUseRegularExpressions;
+ double dVal(0.0);
+ getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions, dVal);
+ pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
+ aFilterField.nField = nField;
+ if (IsXMLToken(sDataType, XML_NUMBER))
+ {
+ aFilterField.nVal = sConditionValue.toDouble();
+ *aFilterField.pStr = sConditionValue;
+ aFilterField.bQueryByString = sal_False;
+ if (dVal != 0.0)
+ {
+ aFilterField.nVal = dVal;
+ *aFilterField.pStr = EMPTY_STRING;
+ }
+ }
+ else
+ {
+ aFilterField.pStr = new String(sConditionValue);
+ aFilterField.bQueryByString = sal_True;
+ aFilterField.nVal = 0;
+ }
+ pFilterContext->AddFilterField(aFilterField);
+}
+
+
+
diff --git a/sc/source/filter/xml/xmlfilti.hxx b/sc/source/filter/xml/xmlfilti.hxx
new file mode 100644
index 000000000000..df222eeb23c2
--- /dev/null
+++ b/sc/source/filter/xml/xmlfilti.hxx
@@ -0,0 +1,310 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLFILTI_HXX
+#define SC_XMLFILTI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/sheet/FilterOperator.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <tools/stack.hxx>
+
+#include "xmldrani.hxx"
+#include "xmldpimp.hxx"
+
+class ScXMLImport;
+
+class ScXMLFilterContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2> aFilterFields;
+ com::sun::star::table::CellAddress aOutputPosition;
+ com::sun::star::table::CellRangeAddress aConditionSourceRangeAddress;
+ sal_Int16 nUserListIndex;
+ sal_Bool bSkipDuplicates;
+ sal_Bool bCopyOutputData;
+ sal_Bool bUseRegularExpressions;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bEnabledUserList;
+ sal_Bool bConnectionOr;
+ sal_Bool bNextConnectionOr;
+ sal_Bool bConditionSourceRange;
+ Stack aConnectionOrStack;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLFilterContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLFilterContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetIsCaseSensitive(const sal_Bool bTemp) { bIsCaseSensitive = bTemp; }
+ void SetUseRegularExpressions(const sal_Bool bTemp) { if (!bUseRegularExpressions) bUseRegularExpressions = bTemp;}
+ void OpenConnection(const sal_Bool bTemp) { sal_Bool* pTemp = new sal_Bool; *pTemp = bConnectionOr;
+ bConnectionOr = bNextConnectionOr; bNextConnectionOr = bTemp;
+ aConnectionOrStack.Push(pTemp);}
+ void CloseConnection() { sal_Bool* pTemp = static_cast <sal_Bool*> (aConnectionOrStack.Pop()); bConnectionOr = *pTemp; bNextConnectionOr = *pTemp; delete pTemp;}
+ sal_Bool GetConnection() { sal_Bool bTemp = bConnectionOr; bConnectionOr = bNextConnectionOr; return bTemp; }
+ void AddFilterField(const com::sun::star::sheet::TableFilterField2 aFilterField) { aFilterFields.realloc(aFilterFields.getLength() + 1);
+ aFilterFields[aFilterFields.getLength() - 1] = aFilterField; }
+};
+
+class ScXMLAndContext : public SvXMLImportContext
+{
+ ScXMLFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLAndContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLAndContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLOrContext : public SvXMLImportContext
+{
+ ScXMLFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLOrContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLOrContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLConditionContext : public SvXMLImportContext
+{
+ ScXMLFilterContext* pFilterContext;
+
+ rtl::OUString sDataType;
+ rtl::OUString sConditionValue;
+ rtl::OUString sOperator;
+ sal_Int32 nField;
+ sal_Bool bIsCaseSensitive;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLConditionContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLConditionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const;
+ virtual void EndElement();
+};
+
+// Datapilot (Core)
+
+class ScXMLDPFilterContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ ScQueryParam aFilterFields;
+ ScAddress aOutputPosition;
+ ScRange aConditionSourceRangeAddress;
+ sal_uInt8 nFilterFieldCount;
+ sal_Int16 nUserListIndex;
+ sal_Bool bSkipDuplicates;
+ sal_Bool bCopyOutputData;
+ sal_Bool bUseRegularExpressions;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bEnabledUserList;
+ sal_Bool bConnectionOr;
+ sal_Bool bNextConnectionOr;
+ sal_Bool bConditionSourceRange;
+ Stack aConnectionOrStack;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPFilterContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTableContext);
+
+ virtual ~ScXMLDPFilterContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetIsCaseSensitive(const sal_Bool bTemp) { bIsCaseSensitive = bTemp; }
+ void SetUseRegularExpressions(const sal_Bool bTemp) { if (!bUseRegularExpressions) bUseRegularExpressions = bTemp;}
+ void OpenConnection(const sal_Bool bTemp) { sal_Bool* pTemp = new sal_Bool; *pTemp = bConnectionOr;
+ bConnectionOr = bNextConnectionOr; bNextConnectionOr = bTemp;
+ aConnectionOrStack.Push(pTemp);}
+ void CloseConnection() { sal_Bool* pTemp = static_cast <sal_Bool*> (aConnectionOrStack.Pop()); bConnectionOr = *pTemp; bNextConnectionOr = *pTemp; delete pTemp;}
+ sal_Bool GetConnection() { sal_Bool bTemp = bConnectionOr; bConnectionOr = bNextConnectionOr; return bTemp; }
+ void AddFilterField (const ScQueryEntry& aFilterField);
+};
+
+class ScXMLDPAndContext : public SvXMLImportContext
+{
+ ScXMLDPFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPAndContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLDPAndContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPOrContext : public SvXMLImportContext
+{
+ ScXMLDPFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPOrContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLDPOrContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPConditionContext : public SvXMLImportContext
+{
+ ScXMLDPFilterContext* pFilterContext;
+
+ rtl::OUString sDataType;
+ rtl::OUString sConditionValue;
+ rtl::OUString sOperator;
+ sal_Int32 nField;
+ sal_Bool bIsCaseSensitive;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPConditionContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLDPConditionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void getOperatorXML(const rtl::OUString sTempOperator, ScQueryOp& aFilterOperator, sal_Bool& bUseRegularExpressions,
+ double& dVal) const;
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlfonte.cxx b/sc/source/filter/xml/xmlfonte.cxx
new file mode 100644
index 000000000000..5cbb2604581f
--- /dev/null
+++ b/sc/source/filter/xml/xmlfonte.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#ifdef PRECOMPILED
+#include "filt_pch.hxx"
+#endif
+
+
+#include "scitems.hxx"
+
+#include <editeng/eeitem.hxx>
+
+
+#include <xmloff/XMLFontAutoStylePool.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editeng.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "xmlexprt.hxx"
+#include "stlpool.hxx"
+#include "attrib.hxx"
+
+class ScXMLFontAutoStylePool_Impl: public XMLFontAutoStylePool
+{
+ void AddFontItems(sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const SfxItemPool* pItemPool, const sal_Bool bExportDefaults);
+ public:
+
+ ScXMLFontAutoStylePool_Impl( ScXMLExport& rExport );
+
+};
+
+void ScXMLFontAutoStylePool_Impl::AddFontItems(sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const SfxItemPool* pItemPool, const sal_Bool bExportDefaults)
+{
+ const SfxPoolItem* pItem;
+ for( sal_uInt16 i=0; i < nIdCount; ++i )
+ {
+ sal_uInt16 nWhichId(pWhichIds[i]);
+ if (bExportDefaults && (0 != (pItem = &pItemPool->GetDefaultItem(nWhichId))))
+ {
+ const SvxFontItem *pFont((const SvxFontItem *)pItem);
+ Add( pFont->GetFamilyName(), pFont->GetStyleName(),
+ sal::static_int_cast<sal_Int16>(pFont->GetFamily()),
+ sal::static_int_cast<sal_Int16>(pFont->GetPitch()),
+ pFont->GetCharSet() );
+ }
+ sal_uInt16 nItems(pItemPool->GetItemCount( nWhichId ));
+ for( sal_uInt16 j = 0; j < nItems; ++j )
+ {
+ if( 0 != (pItem = pItemPool->GetItem( nWhichId, j ) ) )
+ {
+ const SvxFontItem *pFont((const SvxFontItem *)pItem);
+ Add( pFont->GetFamilyName(), pFont->GetStyleName(),
+ sal::static_int_cast<sal_Int16>(pFont->GetFamily()),
+ sal::static_int_cast<sal_Int16>(pFont->GetPitch()),
+ pFont->GetCharSet() );
+ }
+ }
+ }
+}
+
+ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(
+ ScXMLExport& rExportP ) :
+ XMLFontAutoStylePool( rExportP )
+{
+ sal_uInt16 aWhichIds[3] = { ATTR_FONT, ATTR_CJK_FONT,
+ ATTR_CTL_FONT };
+ sal_uInt16 aEditWhichIds[3] = { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
+ EE_CHAR_FONTINFO_CTL };
+ sal_uInt16 aPageWhichIds[4] = { ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERLEFT,
+ ATTR_PAGE_HEADERRIGHT, ATTR_PAGE_FOOTERRIGHT };
+
+ const SfxItemPool* pItemPool(rExportP.GetDocument() ? rExportP.GetDocument()->GetPool() : NULL);
+ AddFontItems(aWhichIds, 3, pItemPool, sal_True);
+ const SfxItemPool* pEditPool(rExportP.GetDocument()->GetEditPool());
+ AddFontItems(aEditWhichIds, 3, pEditPool, sal_False);
+
+ SfxStyleSheetIterator* pItr(rExportP.GetDocument() ? rExportP.GetDocument()->GetStyleSheetPool()->CreateIterator(SFX_STYLE_FAMILY_PAGE, 0xFFFF) : NULL);
+ if(pItr)
+ {
+ SfxStyleSheetBase* pStyle(pItr->First());
+ SfxItemPool* pPageEditPool(EditEngine::CreatePool());
+ EditEngine aEditEngine(pPageEditPool);
+ while (pStyle)
+ {
+ const SfxItemPool& rPagePool(pStyle->GetPool().GetPool());
+ for (sal_uInt8 j = 0; j < 4; ++j)
+ {
+ sal_uInt16 nPageWhichId(aPageWhichIds[j]);
+ sal_uInt16 nPageHFItems(rPagePool.GetItemCount(nPageWhichId));
+ const ScPageHFItem* pPageItem;
+ for (sal_uInt16 k = 0; k < nPageHFItems; ++k)
+ {
+ if (0 != (pPageItem = static_cast<const ScPageHFItem*>(rPagePool.GetItem(nPageWhichId, k))))
+ {
+ const EditTextObject* pLeftArea(pPageItem->GetLeftArea());
+ if (pLeftArea)
+ {
+ aEditEngine.SetText(*pLeftArea);
+ AddFontItems(aEditWhichIds, 3, pPageEditPool, sal_False);
+ }
+ const EditTextObject* pCenterArea(pPageItem->GetCenterArea());
+ if (pCenterArea)
+ {
+ aEditEngine.SetText(*pCenterArea);
+ AddFontItems(aEditWhichIds, 3, pPageEditPool, sal_False);
+ }
+ const EditTextObject* pRightArea(pPageItem->GetRightArea());
+ if (pRightArea)
+ {
+ aEditEngine.SetText(*pRightArea);
+ AddFontItems(aEditWhichIds, 3, pPageEditPool, sal_False);
+ }
+ }
+ }
+ }
+ pStyle = pItr->Next();
+ }
+ }
+}
+
+
+XMLFontAutoStylePool* ScXMLExport::CreateFontAutoStylePool()
+{
+ return new ScXMLFontAutoStylePool_Impl( *this );
+}
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
new file mode 100644
index 000000000000..269e1dd9a7e4
--- /dev/null
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -0,0 +1,3048 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/zforlist.hxx>
+
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/i18nmap.hxx>
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlmetai.hxx>
+#include <sfx2/objsh.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include <xmloff/xmlscripti.hxx>
+#include <xmloff/XMLFontStylesContext.hxx>
+#include <xmloff/DocumentSettingsContext.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlerror.hxx>
+
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <svl/languageoptions.hxx>
+
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "nameuno.hxx"
+#include "xmlbodyi.hxx"
+#include "xmlstyli.hxx"
+#include "unoguard.hxx"
+#include "ViewSettingsSequenceDefines.hxx"
+
+#include "patattr.hxx"
+
+#include "XMLConverter.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "XMLChangeTrackingImportHelper.hxx"
+#include "chgviset.hxx"
+#include "XMLStylesImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "unonames.hxx"
+#include "rangeutl.hxx"
+#include "postit.hxx"
+#include "formulaparserpool.hxx"
+#include <comphelper/extract.hxx>
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/CellInsertMode.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <tools/urlobj.hxx>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#define SC_LOCALE "Locale"
+#define SC_STANDARDFORMAT "StandardFormat"
+#define SC_CURRENCYSYMBOL "CurrencySymbol"
+#define SC_NAMEDRANGES "NamedRanges"
+#define SC_REPEAT_COLUMN "repeat-column"
+#define SC_REPEAT_ROW "repeat-row"
+#define SC_FILTER "filter"
+#define SC_PRINT_RANGE "print-range"
+
+using namespace com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
+
+OUString SAL_CALL ScXMLImport_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_ALL);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_ALL );
+}
+
+OUString SAL_CALL ScXMLImport_Meta_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Meta_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Meta_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_META );
+}
+
+OUString SAL_CALL ScXMLImport_Styles_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Styles_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Styles_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_STYLES|IMPORT_AUTOSTYLES|IMPORT_MASTERSTYLES|IMPORT_FONTDECLS);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_STYLES|IMPORT_AUTOSTYLES|IMPORT_MASTERSTYLES|IMPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLImport_Content_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Content_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Content_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META|IMPORT_STYLES|IMPORT_MASTERSTYLES|IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_SETTINGS|IMPORT_FONTDECLS);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLImport_Settings_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Settings_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Settings_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_SETTINGS);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_SETTINGS );
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowCellAttrTokenMap()
+{
+ static __FAR_DATA SvXMLTokenMapEntry aTableRowCellAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED },
+ { XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE },
+ { XML_NAMESPACE_OFFICE, XML_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_DATE_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_TIME_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_STRING_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE },
+ { XML_NAMESPACE_TABLE, XML_FORMULA, XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA },
+ { XML_NAMESPACE_OFFICE, XML_CURRENCY, XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY },
+ XML_TOKEN_MAP_END
+ };
+
+ if ( !pTableRowCellAttrTokenMap )
+ pTableRowCellAttrTokenMap = new SvXMLTokenMap( aTableRowCellAttrTokenMap );
+ return *pTableRowCellAttrTokenMap;
+}
+
+//----------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// NB: virtually inherit so we can multiply inherit properly
+// in ScXMLFlatDocContext_Impl
+class ScXMLDocContext_Impl : public virtual SvXMLImportContext
+{
+protected:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDocContext_Impl( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList );
+ virtual ~ScXMLDocContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList );
+};
+
+ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */ ) :
+SvXMLImportContext( rImport, nPrfx, rLName )
+{
+
+}
+
+ScXMLDocContext_Impl::~ScXMLDocContext_Impl()
+{
+}
+
+// context for flat file xml format
+class ScXMLFlatDocContext_Impl
+ : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
+{
+public:
+ ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+ USHORT i_nPrefix, const OUString & i_rLName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps,
+ const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder);
+
+ virtual ~ScXMLFlatDocContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ USHORT i_nPrefix, const OUString& i_rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList);
+};
+
+ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+ USHORT i_nPrefix, const OUString & i_rLName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps,
+ const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder) :
+SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
+ScXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName, i_xAttrList),
+SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
+ i_xDocProps, i_xDocBuilder)
+{
+}
+
+ScXMLFlatDocContext_Impl::~ScXMLFlatDocContext_Impl() { }
+
+
+SvXMLImportContext *ScXMLFlatDocContext_Impl::CreateChildContext(
+ USHORT i_nPrefix, const OUString& i_rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
+{
+ // behave like meta base class iff we encounter office:meta
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDocElemTokenMap();
+ if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) {
+ return SvXMLMetaDocumentContext::CreateChildContext(
+ i_nPrefix, i_rLocalName, i_xAttrList );
+ } else {
+ return ScXMLDocContext_Impl::CreateChildContext(
+ i_nPrefix, i_rLocalName, i_xAttrList );
+ }
+}
+
+class ScXMLBodyContext_Impl : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const
+ { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLBodyContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+ virtual ~ScXMLBodyContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+};
+
+ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList > & /* xAttrList */ ) :
+SvXMLImportContext( rImport, nPrfx, rLName )
+{
+}
+
+ScXMLBodyContext_Impl::~ScXMLBodyContext_Impl()
+{
+}
+
+SvXMLImportContext *ScXMLBodyContext_Impl::CreateChildContext(
+ sal_uInt16 /* nPrefix */,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ return GetScImport().CreateBodyContext( rLocalName, xAttrList );
+}
+
+SvXMLImportContext *ScXMLDocContext_Impl::CreateChildContext( USHORT nPrefix,
+ const rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetDocElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLocalName ) )
+ {
+ case XML_TOK_DOC_FONTDECLS:
+ if (GetScImport().getImportFlags() & IMPORT_FONTDECLS)
+ pContext = GetScImport().CreateFontDeclsContext(nPrefix, rLocalName, xAttrList);
+ break;
+ case XML_TOK_DOC_STYLES:
+ if (GetScImport().getImportFlags() & IMPORT_STYLES)
+ pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, sal_False);
+ break;
+ case XML_TOK_DOC_AUTOSTYLES:
+ if (GetScImport().getImportFlags() & IMPORT_AUTOSTYLES)
+ pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, sal_True);
+ break;
+ case XML_TOK_DOC_MASTERSTYLES:
+ if (GetScImport().getImportFlags() & IMPORT_MASTERSTYLES)
+ pContext = new ScXMLMasterStylesContext( GetImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_DOC_META:
+ DBG_WARNING("XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
+ break;
+ case XML_TOK_DOC_SCRIPTS:
+ if (GetScImport().getImportFlags() & IMPORT_SCRIPTS)
+ pContext = GetScImport().CreateScriptContext( rLocalName );
+ break;
+ case XML_TOK_DOC_BODY:
+ if (GetScImport().getImportFlags() & IMPORT_CONTENT)
+ pContext = new ScXMLBodyContext_Impl( GetScImport(), nPrefix,
+ rLocalName, xAttrList );
+ break;
+ case XML_TOK_DOC_SETTINGS:
+ if (GetScImport().getImportFlags() & IMPORT_SETTINGS)
+ pContext = new XMLDocumentSettingsContext(GetScImport(), nPrefix, rLocalName, xAttrList );
+ break;
+ }
+
+ if(!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDocElemTokenMap()
+{
+ if( !pDocElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDocTokenMap[] =
+ {
+ { XML_NAMESPACE_OFFICE, XML_FONT_FACE_DECLS, XML_TOK_DOC_FONTDECLS },
+ { XML_NAMESPACE_OFFICE, XML_STYLES, XML_TOK_DOC_STYLES },
+ { XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES, XML_TOK_DOC_AUTOSTYLES },
+ { XML_NAMESPACE_OFFICE, XML_MASTER_STYLES, XML_TOK_DOC_MASTERSTYLES },
+ { XML_NAMESPACE_OFFICE, XML_META, XML_TOK_DOC_META },
+ { XML_NAMESPACE_OFFICE, XML_SCRIPTS, XML_TOK_DOC_SCRIPTS },
+ { XML_NAMESPACE_OFFICE, XML_BODY, XML_TOK_DOC_BODY },
+ { XML_NAMESPACE_OFFICE, XML_SETTINGS, XML_TOK_DOC_SETTINGS },
+ XML_TOKEN_MAP_END
+ };
+
+ pDocElemTokenMap = new SvXMLTokenMap( aDocTokenMap );
+
+ } // if( !pDocElemTokenMap )
+
+ return *pDocElemTokenMap;
+}
+
+
+const SvXMLTokenMap& ScXMLImport::GetBodyElemTokenMap()
+{
+ if( !pBodyElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aBodyTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, XML_TOK_BODY_TRACKED_CHANGES },
+ { XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, XML_TOK_BODY_CALCULATION_SETTINGS },
+ { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATIONS, XML_TOK_BODY_CONTENT_VALIDATIONS },
+ { XML_NAMESPACE_TABLE, XML_LABEL_RANGES, XML_TOK_BODY_LABEL_RANGES },
+ { XML_NAMESPACE_TABLE, XML_TABLE, XML_TOK_BODY_TABLE },
+ { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, XML_TOK_BODY_NAMED_EXPRESSIONS },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, XML_TOK_BODY_DATABASE_RANGES },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, XML_TOK_BODY_DATABASE_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, XML_TOK_BODY_DATA_PILOT_TABLES },
+ { XML_NAMESPACE_TABLE, XML_CONSOLIDATION, XML_TOK_BODY_CONSOLIDATION },
+ { XML_NAMESPACE_TABLE, XML_DDE_LINKS, XML_TOK_BODY_DDE_LINKS },
+ XML_TOKEN_MAP_END
+ };
+
+ pBodyElemTokenMap = new SvXMLTokenMap( aBodyTokenMap );
+ } // if( !pBodyElemTokenMap )
+
+ return *pBodyElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationsElemTokenMap()
+{
+ if( !pContentValidationsElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, XML_TOK_CONTENT_VALIDATION },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationsElemTokenMap = new SvXMLTokenMap( aContentValidationsElemTokenMap );
+ } // if( !pContentValidationsElemTokenMap )
+
+ return *pContentValidationsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationElemTokenMap()
+{
+ if( !pContentValidationElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_HELP_MESSAGE, XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE },
+ { XML_NAMESPACE_TABLE, XML_ERROR_MESSAGE, XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE },
+ { XML_NAMESPACE_TABLE, XML_ERROR_MACRO, XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO },
+ { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationElemTokenMap = new SvXMLTokenMap( aContentValidationElemTokenMap );
+ } // if( !pContentValidationElemTokenMap )
+
+ return *pContentValidationElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationAttrTokenMap()
+{
+ if( !pContentValidationAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_CONTENT_VALIDATION_NAME },
+ { XML_NAMESPACE_TABLE, XML_CONDITION, XML_TOK_CONTENT_VALIDATION_CONDITION },
+ { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationAttrTokenMap = new SvXMLTokenMap( aContentValidationAttrTokenMap );
+ } // if( !pContentValidationAttrTokenMap )
+
+ return *pContentValidationAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationMessageElemTokenMap()
+{
+ if( !pContentValidationMessageElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationMessageElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TEXT, XML_P, XML_TOK_P },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationMessageElemTokenMap = new SvXMLTokenMap( aContentValidationMessageElemTokenMap );
+ } // if( !pContentValidationMessageElemTokenMap )
+
+ return *pContentValidationMessageElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationHelpMessageAttrTokenMap()
+{
+ if( !pContentValidationHelpMessageAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationHelpMessageAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TITLE, XML_TOK_HELP_MESSAGE_ATTR_TITLE },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_HELP_MESSAGE_ATTR_DISPLAY },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationHelpMessageAttrTokenMap = new SvXMLTokenMap( aContentValidationHelpMessageAttrTokenMap );
+ } // if( !pContentValidationHelpMessageAttrTokenMap )
+
+ return *pContentValidationHelpMessageAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationErrorMessageAttrTokenMap()
+{
+ if( !pContentValidationErrorMessageAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationErrorMessageAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TITLE, XML_TOK_ERROR_MESSAGE_ATTR_TITLE },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationErrorMessageAttrTokenMap = new SvXMLTokenMap( aContentValidationErrorMessageAttrTokenMap );
+ } // if( !pContentValidationErrorMessageAttrTokenMap )
+
+ return *pContentValidationErrorMessageAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationErrorMacroAttrTokenMap()
+{
+ if( !pContentValidationErrorMacroAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aContentValidationErrorMacroAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_ERROR_MACRO_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_EXECUTE, XML_TOK_ERROR_MACRO_ATTR_EXECUTE },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationErrorMacroAttrTokenMap = new SvXMLTokenMap( aContentValidationErrorMacroAttrTokenMap );
+ } // if( !pContentValidationErrorMacroAttrTokenMap )
+
+ return *pContentValidationErrorMacroAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetLabelRangesElemTokenMap()
+{
+ if( !pLabelRangesElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aLabelRangesElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_LABEL_RANGE, XML_TOK_LABEL_RANGE_ELEM },
+ XML_TOKEN_MAP_END
+ };
+
+ pLabelRangesElemTokenMap = new SvXMLTokenMap( aLabelRangesElemTokenMap );
+ } // if( !pLabelRangesElemTokenMap )
+
+ return *pLabelRangesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetLabelRangeAttrTokenMap()
+{
+ if( !pLabelRangeAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aLabelRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_LABEL_RANGE_ATTR_ORIENTATION },
+ XML_TOKEN_MAP_END
+ };
+
+ pLabelRangeAttrTokenMap = new SvXMLTokenMap( aLabelRangeAttrTokenMap );
+ } // if( !pLabelRangeAttrTokenMap )
+
+ return *pLabelRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableElemTokenMap()
+{
+ if( !pTableElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COL_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_HEADER_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COL },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP, XML_TOK_TABLE_ROW_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, XML_TOK_TABLE_HEADER_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROW },
+ { XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, XML_TOK_TABLE_SOURCE },
+ { XML_NAMESPACE_TABLE, XML_SCENARIO, XML_TOK_TABLE_SCENARIO },
+ { XML_NAMESPACE_TABLE, XML_SHAPES, XML_TOK_TABLE_SHAPES },
+ { XML_NAMESPACE_OFFICE, XML_FORMS, XML_TOK_TABLE_FORMS },
+ { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS },
+ { XML_NAMESPACE_OFFICE_EXT, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableElemTokenMap = new SvXMLTokenMap( aTableTokenMap );
+ } // if( !pTableElemTokenMap )
+
+ return *pTableElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowsElemTokenMap()
+{
+ if( !pTableRowsElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableRowsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP, XML_TOK_TABLE_ROWS_ROW_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, XML_TOK_TABLE_ROWS_HEADER_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROWS_ROW },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowsElemTokenMap = new SvXMLTokenMap( aTableRowsElemTokenMap );
+ } // if( !pTableRowsElemTokenMap )
+
+ return *pTableRowsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableColsElemTokenMap()
+{
+ if( !pTableColsElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableColsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COLS_COL_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_COLS_HEADER_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COLS_COL },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableColsElemTokenMap = new SvXMLTokenMap( aTableColsElemTokenMap );
+ } // if( !pTableColsElemTokenMap )
+
+ return *pTableColsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableAttrTokenMap()
+{
+ if( !pTableAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTION },
+ { XML_NAMESPACE_TABLE, XML_PRINT_RANGES, XML_TOK_TABLE_PRINT_RANGES },
+ { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, XML_TOK_TABLE_PASSWORD },
+ { XML_NAMESPACE_TABLE, XML_PRINT, XML_TOK_TABLE_PRINT },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableAttrTokenMap = new SvXMLTokenMap( aTableAttrTokenMap );
+ } // if( !pTableAttrTokenMap )
+
+ return *pTableAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableScenarioAttrTokenMap()
+{
+ if( !pTableScenarioAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableScenarioAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER },
+ { XML_NAMESPACE_TABLE, XML_BORDER_COLOR, XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR },
+ { XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK },
+ { XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES },
+ { XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS },
+ { XML_NAMESPACE_TABLE, XML_IS_ACTIVE, XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE },
+ { XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES },
+ { XML_NAMESPACE_TABLE, XML_COMMENT, XML_TOK_TABLE_SCENARIO_ATTR_COMMENT },
+ { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableScenarioAttrTokenMap = new SvXMLTokenMap( aTableScenarioAttrTokenMap );
+ } // if( !pTableScenarioAttrTokenMap )
+
+ return *pTableScenarioAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableColAttrTokenMap()
+{
+ if( !pTableColAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableColAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_COL_ATTR_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_COL_ATTR_REPEATED },
+ { XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_TOK_TABLE_COL_ATTR_VISIBILITY },
+ { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableColAttrTokenMap = new SvXMLTokenMap( aTableColAttrTokenMap );
+ } // if( !pTableColAttrTokenMap )
+
+ return *pTableColAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowElemTokenMap()
+{
+ if( !pTableRowElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableRowTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_CELL, XML_TOK_TABLE_ROW_CELL },
+ { XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL, XML_TOK_TABLE_ROW_COVERED_CELL },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowElemTokenMap = new SvXMLTokenMap( aTableRowTokenMap );
+ } // if( !pTableRowElemTokenMap )
+
+ return *pTableRowElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowAttrTokenMap()
+{
+ if( !pTableRowAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableRowAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_ROW_ATTR_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_TOK_TABLE_ROW_ATTR_VISIBILITY },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, XML_TOK_TABLE_ROW_ATTR_REPEATED },
+ { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME },
+ // { XML_NAMESPACE_TABLE, XML_USE_OPTIMAL_HEIGHT, XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowAttrTokenMap = new SvXMLTokenMap( aTableRowAttrTokenMap );
+ } // if( !pTableRowAttrTokenMap )
+
+ return *pTableRowAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowCellElemTokenMap()
+{
+ if( !pTableRowCellElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableRowCellTokenMap[] =
+ {
+ { XML_NAMESPACE_TEXT, XML_P, XML_TOK_TABLE_ROW_CELL_P },
+ { XML_NAMESPACE_TABLE, XML_SUB_TABLE, XML_TOK_TABLE_ROW_CELL_TABLE },
+ { XML_NAMESPACE_OFFICE, XML_ANNOTATION, XML_TOK_TABLE_ROW_CELL_ANNOTATION },
+ { XML_NAMESPACE_TABLE, XML_DETECTIVE, XML_TOK_TABLE_ROW_CELL_DETECTIVE },
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowCellElemTokenMap = new SvXMLTokenMap( aTableRowCellTokenMap );
+ } // if( !pTableRowCellElemTokenMap )
+
+ return *pTableRowCellElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableAnnotationAttrTokenMap()
+{
+ if( !pTableAnnotationAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableAnnotationAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_OFFICE, XML_AUTHOR, XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR },
+ { XML_NAMESPACE_OFFICE, XML_CREATE_DATE, XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE },
+ { XML_NAMESPACE_OFFICE, XML_CREATE_DATE_STRING, XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING },
+ { XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY },
+ { XML_NAMESPACE_SVG, XML_X, XML_TOK_TABLE_ANNOTATION_ATTR_X },
+ { XML_NAMESPACE_SVG, XML_Y, XML_TOK_TABLE_ANNOTATION_ATTR_Y },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableAnnotationAttrTokenMap = new SvXMLTokenMap( aTableAnnotationAttrTokenMap );
+ } // if( !pTableAnnotationAttrTokenMap )
+
+ return *pTableAnnotationAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDetectiveElemTokenMap()
+{
+ if( !pDetectiveElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDetectiveElemTokenMap[]=
+ {
+ { XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED },
+ { XML_NAMESPACE_TABLE, XML_OPERATION, XML_TOK_DETECTIVE_ELEM_OPERATION },
+ XML_TOKEN_MAP_END
+ };
+
+ pDetectiveElemTokenMap = new SvXMLTokenMap( aDetectiveElemTokenMap );
+ } // if( !pDetectiveElemTokenMap )
+
+ return *pDetectiveElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDetectiveHighlightedAttrTokenMap()
+{
+ if( !pDetectiveHighlightedAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDetectiveHighlightedAttrTokenMap[]=
+ {
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DIRECTION, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION },
+ { XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR },
+ { XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID },
+ XML_TOKEN_MAP_END
+ };
+
+ pDetectiveHighlightedAttrTokenMap = new SvXMLTokenMap( aDetectiveHighlightedAttrTokenMap );
+ } // if( !pDetectiveHighlightedAttrTokenMap )
+
+ return *pDetectiveHighlightedAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDetectiveOperationAttrTokenMap()
+{
+ if( !pDetectiveOperationAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDetectiveOperationAttrTokenMap[]=
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DETECTIVE_OPERATION_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_INDEX, XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX },
+ XML_TOKEN_MAP_END
+ };
+
+ pDetectiveOperationAttrTokenMap = new SvXMLTokenMap( aDetectiveOperationAttrTokenMap );
+ } // if( !pDetectiveOperationAttrTokenMap )
+
+ return *pDetectiveOperationAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableCellRangeSourceAttrTokenMap()
+{
+ if( !pTableCellRangeSourceAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aTableCellRangeSourceAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_FILTER_NAME, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME },
+ { XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS },
+ { XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN },
+ { XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW },
+ { XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableCellRangeSourceAttrTokenMap = new SvXMLTokenMap( aTableCellRangeSourceAttrTokenMap );
+ } // if( !pTableCellRangeSourceAttrTokenMap )
+
+ return *pTableCellRangeSourceAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetNamedExpressionsElemTokenMap()
+{
+ if( !pNamedExpressionsElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aNamedExpressionsTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAMED_RANGE, XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE },
+ { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION },
+ XML_TOKEN_MAP_END
+ };
+
+ pNamedExpressionsElemTokenMap = new SvXMLTokenMap( aNamedExpressionsTokenMap );
+ } // if( !pNamedExpressionsElemTokenMap )
+
+ return *pNamedExpressionsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetNamedRangeAttrTokenMap()
+{
+ if( !pNamedRangeAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aNamedRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_NAMED_RANGE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS },
+ XML_TOKEN_MAP_END
+ };
+
+ pNamedRangeAttrTokenMap = new SvXMLTokenMap( aNamedRangeAttrTokenMap );
+ } // if( !pNamedRangeAttrTokenMap )
+
+ return *pNamedRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetNamedExpressionAttrTokenMap()
+{
+ if( !pNamedExpressionAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aNamedExpressionAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_NAMED_EXPRESSION_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_EXPRESSION, XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION },
+ XML_TOKEN_MAP_END
+ };
+
+ pNamedExpressionAttrTokenMap = new SvXMLTokenMap( aNamedExpressionAttrTokenMap );
+ } // if( !pNamedExpressionAttrTokenMap )
+
+ return *pNamedExpressionAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangesElemTokenMap()
+{
+ if( !pDatabaseRangesElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangesTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, XML_TOK_DATABASE_RANGE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangesElemTokenMap = new SvXMLTokenMap( aDatabaseRangesTokenMap );
+ } // if( !pDatabaseRangesElemTokenMap )
+
+ return *pDatabaseRangesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeElemTokenMap()
+{
+ if( !pDatabaseRangeElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATABASE_RANGE_SOURCE_SQL },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATABASE_RANGE_SOURCE_TABLE },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATABASE_RANGE_SOURCE_QUERY },
+ { XML_NAMESPACE_TABLE, XML_FILTER, XML_TOK_FILTER },
+ { XML_NAMESPACE_TABLE, XML_SORT, XML_TOK_SORT },
+ { XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeElemTokenMap = new SvXMLTokenMap( aDatabaseRangeTokenMap );
+ } // if( !pDatabaseRangeElemTokenMap )
+
+ return *pDatabaseRangeElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeAttrTokenMap()
+{
+ if( !pDatabaseRangeAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATABASE_RANGE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION },
+ { XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES },
+ { XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE },
+ { XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS },
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeAttrTokenMap );
+ } // if( !pDatabaseRangeAttrTokenMap )
+
+ return *pDatabaseRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceSQLAttrTokenMap()
+{
+ if( !pDatabaseRangeSourceSQLAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSourceSQLAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_SQL_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_SQL_ATTR_CONNECTION_RESSOURCE},
+ { XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT },
+ { XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSourceSQLAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceSQLAttrTokenMap );
+ } // if( !pDatabaseRangeSourceSQLAttrTokenMap )
+
+ return *pDatabaseRangeSourceSQLAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceTableAttrTokenMap()
+{
+ if( !pDatabaseRangeSourceTableAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSourceTableAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_TABLE_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_TABLE_ATTR_CONNECTION_RESSOURCE },
+ { XML_NAMESPACE_TABLE, XML_TABLE_NAME, XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSourceTableAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceTableAttrTokenMap );
+ } // if( !pDatabaseRangeSourceTableAttrTokenMap )
+
+ return *pDatabaseRangeSourceTableAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceQueryAttrTokenMap()
+{
+ if( !pDatabaseRangeSourceQueryAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSourceQueryAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_QUERY_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_QUERY_ATTR_CONNECTION_RESSOURCE },
+ { XML_NAMESPACE_TABLE, XML_QUERY_NAME, XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSourceQueryAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceQueryAttrTokenMap );
+ } // if( !pDatabaseRangeSourceQueryAttrTokenMap )
+
+ return *pDatabaseRangeSourceQueryAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetFilterElemTokenMap()
+{
+ if( !pFilterElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aFilterTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FILTER_AND, XML_TOK_FILTER_AND },
+ { XML_NAMESPACE_TABLE, XML_FILTER_OR, XML_TOK_FILTER_OR },
+ { XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, XML_TOK_FILTER_CONDITION },
+ XML_TOKEN_MAP_END
+ };
+
+ pFilterElemTokenMap = new SvXMLTokenMap( aFilterTokenMap );
+ } // if( !pFilterElemTokenMap )
+
+ return *pFilterElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetFilterAttrTokenMap()
+{
+ if( !pFilterAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aFilterAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE, XML_TOK_FILTER_ATTR_CONDITION_SOURCE },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES },
+ XML_TOKEN_MAP_END
+ };
+
+ pFilterAttrTokenMap = new SvXMLTokenMap( aFilterAttrTokenMap );
+ } // if( !pFilterAttrTokenMap )
+
+ return *pFilterAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetFilterConditionAttrTokenMap()
+{
+ if( !pFilterConditionAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aFilterConditionAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_CONDITION_ATTR_FIELD_NUMBER },
+ { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_CONDITION_ATTR_CASE_SENSITIVE },
+ { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_CONDITION_ATTR_DATA_TYPE },
+ { XML_NAMESPACE_TABLE, XML_VALUE, XML_TOK_CONDITION_ATTR_VALUE },
+ { XML_NAMESPACE_TABLE, XML_OPERATOR, XML_TOK_CONDITION_ATTR_OPERATOR },
+ XML_TOKEN_MAP_END
+ };
+
+ pFilterConditionAttrTokenMap = new SvXMLTokenMap( aFilterConditionAttrTokenMap );
+ } // if( !pFilterConditionAttrTokenMap )
+
+ return *pFilterConditionAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSortElemTokenMap()
+{
+ if( !pSortElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSortTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SORT_BY, XML_TOK_SORT_SORT_BY },
+ XML_TOKEN_MAP_END
+ };
+
+ pSortElemTokenMap = new SvXMLTokenMap( aSortTokenMap );
+ } // if( !pSortElemTokenMap )
+
+ return *pSortElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSortAttrTokenMap()
+{
+ if( !pSortAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSortAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT },
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_SORT_ATTR_CASE_SENSITIVE },
+ { XML_NAMESPACE_TABLE, XML_LANGUAGE, XML_TOK_SORT_ATTR_LANGUAGE },
+ { XML_NAMESPACE_TABLE, XML_COUNTRY, XML_TOK_SORT_ATTR_COUNTRY },
+ { XML_NAMESPACE_TABLE, XML_ALGORITHM, XML_TOK_SORT_ATTR_ALGORITHM },
+ XML_TOKEN_MAP_END
+ };
+
+ pSortAttrTokenMap = new SvXMLTokenMap( aSortAttrTokenMap );
+ } // if( !pSortAttrTokenMap )
+
+ return *pSortAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSortSortByAttrTokenMap()
+{
+ if( !pSortSortByAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSortSortByAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_SORT_BY_ATTR_FIELD_NUMBER },
+ { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_SORT_BY_ATTR_DATA_TYPE },
+ { XML_NAMESPACE_TABLE, XML_ORDER, XML_TOK_SORT_BY_ATTR_ORDER },
+ XML_TOKEN_MAP_END
+ };
+
+ pSortSortByAttrTokenMap = new SvXMLTokenMap( aSortSortByAttrTokenMap );
+ } // if( !pSortSortByAttrTokenMap )
+
+ return *pSortSortByAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSubTotalRulesElemTokenMap()
+{
+ if( !pDatabaseRangeSubTotalRulesElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSubTotalRulesTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SORT_GROUPS, XML_TOK_SUBTOTAL_RULES_SORT_GROUPS },
+ { XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSubTotalRulesElemTokenMap = new SvXMLTokenMap( aDatabaseRangeSubTotalRulesTokenMap );
+ } // if( !pDatabaseRangeSubTotalRulesElemTokenMap )
+
+ return *pDatabaseRangeSubTotalRulesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSubTotalRulesAttrTokenMap()
+{
+ if( !pDatabaseRangeSubTotalRulesAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSubTotalRulesAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT },
+ { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE },
+ { XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSubTotalRulesAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSubTotalRulesAttrTokenMap );
+ } // if( !pDatabaseRangeSubTotalRulesAttrTokenMap )
+
+ return *pDatabaseRangeSubTotalRulesAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSortGroupsAttrTokenMap()
+{
+ if( !pSubTotalRulesSortGroupsAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSubTotalRulesSortGroupsAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE },
+ { XML_NAMESPACE_TABLE, XML_ORDER, XML_TOK_SORT_GROUPS_ATTR_ORDER },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRulesSortGroupsAttrTokenMap = new SvXMLTokenMap( aSubTotalRulesSortGroupsAttrTokenMap );
+ } // if( !pSubTotalRulesSortGroupsAttrTokenMap )
+
+ return *pSubTotalRulesSortGroupsAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSubTotalRuleElemTokenMap()
+{
+ if( !pSubTotalRulesSubTotalRuleElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSubTotalRulesSubTotalRuleTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRulesSubTotalRuleElemTokenMap = new SvXMLTokenMap( aSubTotalRulesSubTotalRuleTokenMap );
+ } // if( !pSubTotalRulesSubTotalRuleElemTokenMap )
+
+ return *pSubTotalRulesSubTotalRuleElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSubTotalRuleAttrTokenMap()
+{
+ if( !pSubTotalRulesSubTotalRuleAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSubTotalRulesSubTotalRuleAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRulesSubTotalRuleAttrTokenMap = new SvXMLTokenMap( aSubTotalRulesSubTotalRuleAttrTokenMap );
+ } // if( !pSubTotalRulesSubTotalRuleAttrTokenMap )
+
+ return *pSubTotalRulesSubTotalRuleAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRuleSubTotalFieldAttrTokenMap()
+{
+ if( !pSubTotalRuleSubTotalFieldAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aSubTotalRuleSubTotalFieldAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER },
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRuleSubTotalFieldAttrTokenMap = new SvXMLTokenMap( aSubTotalRuleSubTotalFieldAttrTokenMap );
+ } // if( !pSubTotalRuleSubTotalFieldAttrTokenMap )
+
+ return *pSubTotalRuleSubTotalFieldAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTablesElemTokenMap()
+{
+ if( !pDataPilotTablesElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotTablesElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, XML_TOK_DATA_PILOT_TABLE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTablesElemTokenMap = new SvXMLTokenMap( aDataPilotTablesElemTokenMap );
+ } // if( !pDataPilotTablesElemTokenMap )
+
+ return *pDataPilotTablesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableAttrTokenMap()
+{
+ if( !pDataPilotTableAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_TABLE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA },
+ { XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL },
+ { XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS },
+ { XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES },
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_BUTTONS, XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS },
+ { XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON },
+ { XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableAttrTokenMap = new SvXMLTokenMap( aDataPilotTableAttrTokenMap );
+ } // if( !pDataPilotTableAttrTokenMap )
+
+ return *pDataPilotTableAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap()
+{
+ if( !pDataPilotTableElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableElemTokenMap = new SvXMLTokenMap( aDataPilotTableElemTokenMap );
+ } // if( !pDataPilotTableElemTokenMap )
+
+ return *pDataPilotTableElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap()
+{
+ if( !pDataPilotTableSourceServiceAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableSourceServiceAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_SOURCE_SERVICE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_NAME, XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME },
+ { XML_NAMESPACE_TABLE, XML_OBJECT_NAME, XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME },
+ { XML_NAMESPACE_TABLE, XML_USER_NAME, XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME },
+ { XML_NAMESPACE_TABLE, XML_PASSWORD, XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableSourceServiceAttrTokenMap = new SvXMLTokenMap( aDataPilotTableSourceServiceAttrTokenMap );
+ } // if( !pDataPilotTableSourceServiceAttrTokenMap )
+
+ return *pDataPilotTableSourceServiceAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap()
+{
+ if (!pDataPilotGrandTotalAttrTokenMap)
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap );
+ }
+
+ return *pDataPilotGrandTotalAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap()
+{
+ if( !pDataPilotTableSourceCellRangeAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableSourceCellRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS},
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableSourceCellRangeAttrTokenMap = new SvXMLTokenMap( aDataPilotTableSourceCellRangeAttrTokenMap );
+ } // if( !pDataPilotTableSourceCellRangeAttrTokenMap )
+
+ return *pDataPilotTableSourceCellRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeElemTokenMap()
+{
+ if( !pDataPilotTableSourceCellRangeElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableSourceCellRangeElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FILTER, XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER},
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableSourceCellRangeElemTokenMap = new SvXMLTokenMap( aDataPilotTableSourceCellRangeElemTokenMap );
+ } // if( !pDataPilotTableSourceCellRangeElemTokenMap )
+
+ return *pDataPilotTableSourceCellRangeElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap()
+{
+ if( !pDataPilotFieldAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT },
+ { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD },
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE },
+ { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotFieldAttrTokenMap = new SvXMLTokenMap( aDataPilotFieldAttrTokenMap );
+ } // if( !pDataPilotFieldAttrTokenMap )
+
+ return *pDataPilotFieldAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldElemTokenMap()
+{
+ if( !pDataPilotFieldElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotFieldElemTokenMap = new SvXMLTokenMap( aDataPilotFieldElemTokenMap );
+ } // if( !pDataPilotFieldElemTokenMap )
+
+ return *pDataPilotFieldElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelAttrTokenMap()
+{
+ if( !pDataPilotLevelAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotLevelAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotLevelAttrTokenMap = new SvXMLTokenMap( aDataPilotLevelAttrTokenMap );
+ } // if( !pDataPilotLevelAttrTokenMap )
+
+ return *pDataPilotLevelAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelElemTokenMap()
+{
+ if( !pDataPilotLevelElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotLevelElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotLevelElemTokenMap = new SvXMLTokenMap( aDataPilotLevelElemTokenMap );
+ } // if( !pDataPilotLevelElemTokenMap )
+
+ return *pDataPilotLevelElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalsElemTokenMap()
+{
+ if( !pDataPilotSubTotalsElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotSubTotalsElemTokenMap = new SvXMLTokenMap( aDataPilotSubTotalsElemTokenMap );
+ } // if( !pDataPilotSubTotalsElemTokenMap )
+
+ return *pDataPilotSubTotalsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap()
+{
+ if( !pDataPilotSubTotalAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotSubTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotSubTotalAttrTokenMap );
+ } // if( !pDataPilotSubTotalAttrTokenMap )
+
+ return *pDataPilotSubTotalAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotMembersElemTokenMap()
+{
+ if( !pDataPilotMembersElemTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotMembersElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotMembersElemTokenMap = new SvXMLTokenMap( aDataPilotMembersElemTokenMap );
+ } // if( !pDataPilotMembersElemTokenMap )
+
+ return *pDataPilotMembersElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap()
+{
+ if( !pDataPilotMemberAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotMemberAttrTokenMap = new SvXMLTokenMap( aDataPilotMemberAttrTokenMap );
+ } // if( !pDataPilotMemberAttrTokenMap )
+
+ return *pDataPilotMemberAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetConsolidationAttrTokenMap()
+{
+ if( !pConsolidationAttrTokenMap )
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aConsolidationAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_CONSOLIDATION_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES },
+ { XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_TOK_CONSOLIDATION_ATTR_USE_LABEL },
+ { XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE },
+ XML_TOKEN_MAP_END
+ };
+
+ pConsolidationAttrTokenMap = new SvXMLTokenMap( aConsolidationAttrTokenMap );
+ } // if( !pConsolidationAttrTokenMap )
+
+ return *pConsolidationAttrTokenMap;
+}
+
+
+SvXMLImportContext *ScXMLImport::CreateContext( USHORT nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( (XML_NAMESPACE_OFFICE == nPrefix) &&
+ ( IsXMLToken(rLocalName, XML_DOCUMENT_STYLES) ||
+ IsXMLToken(rLocalName, XML_DOCUMENT_CONTENT) ||
+ IsXMLToken(rLocalName, XML_DOCUMENT_SETTINGS) )) {
+ pContext = new ScXMLDocContext_Impl( *this, nPrefix, rLocalName,
+ xAttrList );
+ } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
+ ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) {
+ pContext = CreateMetaContext(rLocalName);
+ } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
+ ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) {
+ uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
+ mxServiceFactory->createInstance(::rtl::OUString::createFromAscii(
+ "com.sun.star.xml.dom.SAXDocumentBuilder")),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ // flat OpenDocument file format
+ pContext = new ScXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
+ xAttrList, xDPS->getDocumentProperties(), xDocBuilder);
+ }
+ else
+ pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
+
+ return pContext;
+}
+
+// #110680#
+ScXMLImport::ScXMLImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nImportFlag)
+: SvXMLImport( xServiceFactory, nImportFlag ),
+ pDoc( NULL ),
+ pChangeTrackingImportHelper(NULL),
+ pStylesImportHelper(NULL),
+ sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT)),
+ sLocale(RTL_CONSTASCII_USTRINGPARAM(SC_LOCALE)),
+ sCellStyle(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLSTYL)),
+ sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(SC_STANDARDFORMAT)),
+ sType(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)),
+// pScAutoStylePool(new SvXMLAutoStylePoolP),
+// pParaItemMapper( 0 ),
+// pI18NMap( new SvI18NMap ),
+ pDocElemTokenMap( 0 ),
+ pStylesElemTokenMap( 0 ),
+ pStylesAttrTokenMap( 0 ),
+ pStyleElemTokenMap( 0 ),
+ pBodyElemTokenMap( 0 ),
+ pContentValidationsElemTokenMap( 0 ),
+ pContentValidationElemTokenMap( 0 ),
+ pContentValidationAttrTokenMap( 0 ),
+ pContentValidationMessageElemTokenMap( 0 ),
+ pContentValidationHelpMessageAttrTokenMap( 0 ),
+ pContentValidationErrorMessageAttrTokenMap( 0 ),
+ pContentValidationErrorMacroAttrTokenMap( 0 ),
+ pLabelRangesElemTokenMap( 0 ),
+ pLabelRangeAttrTokenMap( 0 ),
+ pTableElemTokenMap( 0 ),
+ pTableRowsElemTokenMap( 0 ),
+ pTableColsElemTokenMap( 0 ),
+ pTableScenarioAttrTokenMap( 0 ),
+ pTableAttrTokenMap( 0 ),
+ pTableColAttrTokenMap( 0 ),
+ pTableRowElemTokenMap( 0 ),
+ pTableRowAttrTokenMap( 0 ),
+ pTableRowCellElemTokenMap( 0 ),
+ pTableRowCellAttrTokenMap( 0 ),
+ pTableAnnotationAttrTokenMap( 0 ),
+ pDetectiveElemTokenMap( 0 ),
+ pDetectiveHighlightedAttrTokenMap( 0 ),
+ pDetectiveOperationAttrTokenMap( 0 ),
+ pTableCellRangeSourceAttrTokenMap( 0 ),
+ pNamedExpressionsElemTokenMap( 0 ),
+ pNamedRangeAttrTokenMap( 0 ),
+ pNamedExpressionAttrTokenMap( 0 ),
+ pDatabaseRangesElemTokenMap( 0 ),
+ pDatabaseRangeElemTokenMap( 0 ),
+ pDatabaseRangeAttrTokenMap( 0 ),
+ pDatabaseRangeSourceSQLAttrTokenMap( 0 ),
+ pDatabaseRangeSourceTableAttrTokenMap( 0 ),
+ pDatabaseRangeSourceQueryAttrTokenMap( 0 ),
+ pFilterElemTokenMap( 0 ),
+ pFilterAttrTokenMap( 0 ),
+ pFilterConditionAttrTokenMap( 0 ),
+ pSortElemTokenMap( 0 ),
+ pSortAttrTokenMap( 0 ),
+ pSortSortByAttrTokenMap( 0 ),
+ pDatabaseRangeSubTotalRulesElemTokenMap( 0 ),
+ pDatabaseRangeSubTotalRulesAttrTokenMap( 0 ),
+ pSubTotalRulesSortGroupsAttrTokenMap( 0 ),
+ pSubTotalRulesSubTotalRuleElemTokenMap( 0 ),
+ pSubTotalRulesSubTotalRuleAttrTokenMap( 0 ),
+ pSubTotalRuleSubTotalFieldAttrTokenMap( 0 ),
+ pDataPilotTablesElemTokenMap( 0 ),
+ pDataPilotTableAttrTokenMap( 0 ),
+ pDataPilotTableElemTokenMap( 0 ),
+ pDataPilotTableSourceServiceAttrTokenMap( 0 ),
+ pDataPilotGrandTotalAttrTokenMap(NULL),
+ pDataPilotTableSourceCellRangeElemTokenMap( 0 ),
+ pDataPilotTableSourceCellRangeAttrTokenMap( 0 ),
+ pDataPilotFieldAttrTokenMap( 0 ),
+ pDataPilotFieldElemTokenMap( 0 ),
+ pDataPilotLevelAttrTokenMap( 0 ),
+ pDataPilotLevelElemTokenMap( 0 ),
+ pDataPilotSubTotalsElemTokenMap( 0 ),
+ pDataPilotSubTotalAttrTokenMap( 0 ),
+ pDataPilotMembersElemTokenMap( 0 ),
+ pDataPilotMemberAttrTokenMap( 0 ),
+ pConsolidationAttrTokenMap( 0 ),
+ aTables(*this),
+ pMyNamedExpressions(NULL),
+ pMyLabelRanges(NULL),
+ pValidations(NULL),
+ pDetectiveOpArray(NULL),
+ pScUnoGuard(NULL),
+ pNumberFormatAttributesExportHelper(NULL),
+ pStyleNumberFormats(NULL),
+ sPrevStyleName(),
+ sPrevCurrency(),
+ nSolarMutexLocked(0),
+ nProgressCount(0),
+ nStyleFamilyMask( 0 ),
+ nPrevCellType(0),
+ bLoadDoc( sal_True ),
+ bRemoveLastChar(sal_False),
+ bNullDateSetted(sal_False),
+ bSelfImportingXMLSet(sal_False),
+ bLatinDefaultStyle(sal_False),
+ bFromWrapper(sal_False)
+{
+ pStylesImportHelper = new ScMyStylesImportHelper(*this);
+
+ xScPropHdlFactory = new XMLScPropHdlFactory;
+ xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory);
+ xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory);
+ xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesImportProperties, xScPropHdlFactory);
+ xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesImportProperties, xScPropHdlFactory);
+
+ // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
+ GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_PRESENTATION ),
+ GetXMLToken( XML_N_PRESENTATION ),
+ XML_NAMESPACE_PRESENTATION );
+
+ // initialize cell type map.
+ const struct { XMLTokenEnum _token; sal_Int16 _type; } aCellTypePairs[] =
+ {
+ { XML_FLOAT, util::NumberFormat::NUMBER },
+ { XML_STRING, util::NumberFormat::TEXT },
+ { XML_TIME, util::NumberFormat::TIME },
+ { XML_DATE, util::NumberFormat::DATETIME },
+ { XML_PERCENTAGE, util::NumberFormat::PERCENT },
+ { XML_CURRENCY, util::NumberFormat::CURRENCY },
+ { XML_BOOLEAN, util::NumberFormat::LOGICAL }
+ };
+ size_t n = sizeof(aCellTypePairs)/sizeof(aCellTypePairs[0]);
+ for (size_t i = 0; i < n; ++i)
+ {
+ aCellTypeMap.insert(
+ CellTypeMap::value_type(
+ GetXMLToken(aCellTypePairs[i]._token), aCellTypePairs[i]._type));
+ }
+}
+
+ScXMLImport::~ScXMLImport() throw()
+{
+ // delete pI18NMap;
+ delete pDocElemTokenMap;
+ delete pStylesElemTokenMap;
+ delete pStylesAttrTokenMap;
+ delete pStyleElemTokenMap;
+ delete pBodyElemTokenMap;
+ delete pContentValidationsElemTokenMap;
+ delete pContentValidationElemTokenMap;
+ delete pContentValidationAttrTokenMap;
+ delete pContentValidationMessageElemTokenMap;
+ delete pContentValidationHelpMessageAttrTokenMap;
+ delete pContentValidationErrorMessageAttrTokenMap;
+ delete pContentValidationErrorMacroAttrTokenMap;
+ delete pLabelRangesElemTokenMap;
+ delete pLabelRangeAttrTokenMap;
+ delete pTableElemTokenMap;
+ delete pTableRowsElemTokenMap;
+ delete pTableColsElemTokenMap;
+ delete pTableAttrTokenMap;
+ delete pTableScenarioAttrTokenMap;
+ delete pTableColAttrTokenMap;
+ delete pTableRowElemTokenMap;
+ delete pTableRowAttrTokenMap;
+ delete pTableRowCellElemTokenMap;
+ delete pTableRowCellAttrTokenMap;
+ delete pTableAnnotationAttrTokenMap;
+ delete pDetectiveElemTokenMap;
+ delete pDetectiveHighlightedAttrTokenMap;
+ delete pDetectiveOperationAttrTokenMap;
+ delete pTableCellRangeSourceAttrTokenMap;
+ delete pNamedExpressionsElemTokenMap;
+ delete pNamedRangeAttrTokenMap;
+ delete pNamedExpressionAttrTokenMap;
+ delete pDatabaseRangesElemTokenMap;
+ delete pDatabaseRangeElemTokenMap;
+ delete pDatabaseRangeAttrTokenMap;
+ delete pDatabaseRangeSourceSQLAttrTokenMap;
+ delete pDatabaseRangeSourceTableAttrTokenMap;
+ delete pDatabaseRangeSourceQueryAttrTokenMap;
+ delete pFilterElemTokenMap;
+ delete pFilterAttrTokenMap;
+ delete pFilterConditionAttrTokenMap;
+ delete pSortElemTokenMap;
+ delete pSortAttrTokenMap;
+ delete pSortSortByAttrTokenMap;
+ delete pDatabaseRangeSubTotalRulesElemTokenMap;
+ delete pDatabaseRangeSubTotalRulesAttrTokenMap;
+ delete pSubTotalRulesSortGroupsAttrTokenMap;
+ delete pSubTotalRulesSubTotalRuleElemTokenMap;
+ delete pSubTotalRulesSubTotalRuleAttrTokenMap;
+ delete pSubTotalRuleSubTotalFieldAttrTokenMap;
+ delete pDataPilotTablesElemTokenMap;
+ delete pDataPilotTableAttrTokenMap;
+ delete pDataPilotTableElemTokenMap;
+ delete pDataPilotTableSourceServiceAttrTokenMap;
+ delete pDataPilotTableSourceCellRangeAttrTokenMap;
+ delete pDataPilotTableSourceCellRangeElemTokenMap;
+ delete pDataPilotFieldAttrTokenMap;
+ delete pDataPilotFieldElemTokenMap;
+ delete pDataPilotLevelAttrTokenMap;
+ delete pDataPilotLevelElemTokenMap;
+ delete pDataPilotSubTotalsElemTokenMap;
+ delete pDataPilotSubTotalAttrTokenMap;
+ delete pDataPilotMembersElemTokenMap;
+ delete pDataPilotMemberAttrTokenMap;
+ delete pConsolidationAttrTokenMap;
+
+ // if (pScAutoStylePool)
+ // delete pScAutoStylePool;
+ if (pChangeTrackingImportHelper)
+ delete pChangeTrackingImportHelper;
+ if (pNumberFormatAttributesExportHelper)
+ delete pNumberFormatAttributesExportHelper;
+ if (pStyleNumberFormats)
+ delete pStyleNumberFormats;
+ if (pStylesImportHelper)
+ delete pStylesImportHelper;
+
+ if (pScUnoGuard)
+ delete pScUnoGuard;
+
+ if (pMyNamedExpressions)
+ delete pMyNamedExpressions;
+ if (pMyLabelRanges)
+ delete pMyLabelRanges;
+ if (pValidations)
+ delete pValidations;
+ if (pDetectiveOpArray)
+ delete pDetectiveOpArray;
+}
+
+// ---------------------------------------------------------------------
+
+SvXMLImportContext *ScXMLImport::CreateFontDeclsContext(const USHORT nPrefix, const ::rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext *pContext = NULL;
+ if (!pContext)
+ {
+ XMLFontStylesContext *pFSContext(
+ new XMLFontStylesContext( *this, nPrefix,
+ rLocalName, xAttrList,
+ gsl_getSystemTextEncoding() ));
+ SetFontDecls( pFSContext );
+ pContext = pFSContext;
+ }
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateStylesContext(const ::rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList, sal_Bool bIsAutoStyle )
+{
+ SvXMLImportContext *pContext(NULL);
+ if (!pContext)
+ {
+ pContext = new XMLTableStylesContext(*this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList, bIsAutoStyle);
+ if (bIsAutoStyle)
+ //xAutoStyles = pContext;
+ SetAutoStyles((SvXMLStylesContext*)pContext);
+ else
+ //xStyles = pContext;
+ SetStyles((SvXMLStylesContext*)pContext);
+ }
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateBodyContext(const ::rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ //GetShapeImport()->SetAutoStylesContext((XMLTableStylesContext *)&xAutoStyles);
+ //GetChartImport()->SetAutoStylesContext(GetAutoStyles()/*(XMLTableStylesContext *)&xAutoStyles*/);
+
+ return new ScXMLBodyContext(*this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList);
+}
+
+SvXMLImportContext *ScXMLImport::CreateMetaContext(
+ const OUString& rLocalName )
+{
+ SvXMLImportContext *pContext(0);
+
+ if( !IsStylesOnlyMode() && (getImportFlags() & IMPORT_META))
+ {
+ uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
+ mxServiceFactory->createInstance(::rtl::OUString::createFromAscii(
+ "com.sun.star.xml.dom.SAXDocumentBuilder")),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ pContext = new SvXMLMetaDocumentContext(*this,
+ XML_NAMESPACE_OFFICE, rLocalName,
+ xDPS->getDocumentProperties(), xDocBuilder);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( *this,
+ XML_NAMESPACE_OFFICE, rLocalName );
+
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateScriptContext(
+ const OUString& rLocalName )
+{
+ SvXMLImportContext *pContext(0);
+
+ if( !(IsStylesOnlyMode()) )
+ {
+ pContext = new XMLScriptContext( *this,
+ XML_NAMESPACE_OFFICE, rLocalName,
+ GetModel() );
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( *this, XML_NAMESPACE_OFFICE,
+ rLocalName );
+
+ return pContext;
+}
+
+void ScXMLImport::SetStatistics(
+ const uno::Sequence<beans::NamedValue> & i_rStats)
+{
+ static const char* s_stats[] =
+ { "TableCount", "CellCount", "ObjectCount", 0 };
+
+ SvXMLImport::SetStatistics(i_rStats);
+
+ sal_uInt32 nCount(0);
+ for (sal_Int32 i = 0; i < i_rStats.getLength(); ++i) {
+ for (const char** pStat = s_stats; *pStat != 0; ++pStat) {
+ if (i_rStats[i].Name.equalsAscii(*pStat)) {
+ sal_Int32 val = 0;
+ if (i_rStats[i].Value >>= val) {
+ nCount += val;
+ } else {
+ DBG_ERROR("ScXMLImport::SetStatistics: invalid entry");
+ }
+ }
+ }
+ }
+
+ if (nCount)
+ {
+ GetProgressBarHelper()->SetReference(nCount);
+ GetProgressBarHelper()->SetValue(0);
+ }
+}
+
+sal_Int16 ScXMLImport::GetCellType(const OUString& rStrValue) const
+{
+ CellTypeMap::const_iterator itr = aCellTypeMap.find(rStrValue);
+ if (itr != aCellTypeMap.end())
+ return itr->second;
+
+ return util::NumberFormat::UNDEFINED;
+}
+
+XMLShapeImportHelper* ScXMLImport::CreateShapeImport()
+{
+ /*UniReference < XMLPropertySetMapper > xShapeStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScShapeStylesProperties, xScPropHdlFactory);
+ SvXMLImportPropertyMapper *pShapeStylesImportPropertySetMapper = new SvXMLImportPropertyMapper( xShapeStylesPropertySetMapper );*/
+
+ return new XMLTableShapeImportHelper( *this/*, pShapeStylesImportPropertySetMapper*/ );
+}
+
+sal_Bool ScXMLImport::GetValidation(const rtl::OUString& sName, ScMyImportValidation& aValidation)
+{
+ if (pValidations)
+ {
+ sal_Bool bFound(sal_False);
+ ScMyImportValidations::iterator aItr(pValidations->begin());
+ ScMyImportValidations::iterator aEndItr(pValidations->end());
+ while(aItr != aEndItr && !bFound)
+ {
+ if (aItr->sName == sName)
+ {
+ // #b4974740# source position must be set as string,
+ // so sBaseCellAddress no longer has to be converted here
+
+ bFound = sal_True;
+ }
+ else
+ ++aItr;
+ }
+ if (bFound)
+ aValidation = *aItr;
+ return bFound;
+ }
+ return sal_False;
+}
+
+ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper()
+{
+ if (!pChangeTrackingImportHelper)
+ pChangeTrackingImportHelper = new ScXMLChangeTrackingImportHelper();
+ return pChangeTrackingImportHelper;
+}
+
+void ScXMLImport::InsertStyles()
+{
+ GetStyles()->CopyStylesToDoc(sal_True);
+
+ // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now
+ if ( getImportFlags() & IMPORT_CONTENT )
+ ExamineDefaultStyle();
+}
+
+void ScXMLImport::ExamineDefaultStyle()
+{
+ if (pDoc)
+ {
+ // #i62435# after inserting the styles, check if the default style has a latin-script-only
+ // number format (then, value cells can be pre-initialized with western script type)
+
+ const ScPatternAttr* pDefPattern = pDoc->GetDefPattern();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ if ( pFormatter && pDefPattern )
+ {
+ sal_uInt32 nKey = pDefPattern->GetNumberFormat(pFormatter);
+ const SvNumberformat* pFormat = pFormatter->GetEntry(nKey);
+ if ( pFormat && pFormat->IsStandard() )
+ {
+ // The standard format is all-latin if the decimal separator dosen't
+ // have a different script type
+
+ String aDecSep;
+ LanguageType nFormatLang = pFormat->GetLanguage();
+ if ( nFormatLang == LANGUAGE_SYSTEM )
+ aDecSep = ScGlobal::pLocaleData->getNumDecimalSep();
+ else
+ {
+ LocaleDataWrapper aLocaleData( pDoc->GetServiceManager(),
+ MsLangId::convertLanguageToLocale( nFormatLang ) );
+ aDecSep = aLocaleData.getNumDecimalSep();
+ }
+
+ BYTE nScript = pDoc->GetStringScriptType( aDecSep );
+ if ( nScript == 0 || nScript == SCRIPTTYPE_LATIN )
+ bLatinDefaultStyle = sal_True;
+ }
+ }
+ }
+}
+
+void ScXMLImport::SetChangeTrackingViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rChangeProps)
+{
+ if (pDoc)
+ {
+ sal_Int32 nCount(rChangeProps.getLength());
+ if (nCount)
+ {
+ LockSolarMutex();
+ sal_Int16 nTemp16(0);
+ ScChangeViewSettings* pViewSettings(new ScChangeViewSettings());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rtl::OUString sName(rChangeProps[i].Name);
+ if (sName.compareToAscii("ShowChanges") == 0)
+ pViewSettings->SetShowChanges(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowAcceptedChanges") == 0)
+ pViewSettings->SetShowAccepted(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowRejectedChanges") == 0)
+ pViewSettings->SetShowRejected(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByDatetime") == 0)
+ pViewSettings->SetHasDate(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByDatetimeMode") == 0)
+ {
+ if (rChangeProps[i].Value >>= nTemp16)
+ pViewSettings->SetTheDateMode(ScChgsDateMode(nTemp16));
+ }
+ else if (sName.compareToAscii("ShowChangesByDatetimeFirstDatetime") == 0)
+ {
+ util::DateTime aDateTime;
+ if (rChangeProps[i].Value >>= aDateTime)
+ {
+ DateTime aCoreDateTime;
+ ScXMLConverter::ConvertAPIToCoreDateTime(aDateTime, aCoreDateTime);
+ pViewSettings->SetTheFirstDateTime(aCoreDateTime);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByDatetimeSecondDatetime") == 0)
+ {
+ util::DateTime aDateTime;
+ if (rChangeProps[i].Value >>= aDateTime)
+ {
+ DateTime aCoreDateTime;
+ ScXMLConverter::ConvertAPIToCoreDateTime(aDateTime, aCoreDateTime);
+ pViewSettings->SetTheLastDateTime(aCoreDateTime);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByAuthor") == 0)
+ pViewSettings->SetHasAuthor(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByAuthorName") == 0)
+ {
+ rtl::OUString sOUName;
+ if (rChangeProps[i].Value >>= sOUName)
+ {
+ String sAuthorName(sOUName);
+ pViewSettings->SetTheAuthorToShow(sAuthorName);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByComment") == 0)
+ pViewSettings->SetHasComment(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByCommentText") == 0)
+ {
+ rtl::OUString sOUComment;
+ if (rChangeProps[i].Value >>= sOUComment)
+ {
+ String sComment(sOUComment);
+ pViewSettings->SetTheComment(sComment);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByRanges") == 0)
+ pViewSettings->SetHasRange(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByRangesList") == 0)
+ {
+ rtl::OUString sRanges;
+ if ((rChangeProps[i].Value >>= sRanges) && sRanges.getLength())
+ {
+ ScRangeList aRangeList;
+ ScRangeStringConverter::GetRangeListFromString(
+ aRangeList, sRanges, GetDocument(), FormulaGrammar::CONV_OOO);
+ pViewSettings->SetTheRangeList(aRangeList);
+ }
+ }
+ }
+ pDoc->SetChangeViewSettings(*pViewSettings);
+ UnlockSolarMutex();
+ }
+ }
+}
+
+void ScXMLImport::SetViewSettings(const uno::Sequence<beans::PropertyValue>& aViewProps)
+{
+ sal_Int32 nCount(aViewProps.getLength());
+ sal_Int32 nHeight(0);
+ sal_Int32 nLeft(0);
+ sal_Int32 nTop(0);
+ sal_Int32 nWidth(0);
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rtl::OUString sName(aViewProps[i].Name);
+ if (sName.compareToAscii("VisibleAreaHeight") == 0)
+ aViewProps[i].Value >>= nHeight;
+ else if (sName.compareToAscii("VisibleAreaLeft") == 0)
+ aViewProps[i].Value >>= nLeft;
+ else if (sName.compareToAscii("VisibleAreaTop") == 0)
+ aViewProps[i].Value >>= nTop;
+ else if (sName.compareToAscii("VisibleAreaWidth") == 0)
+ aViewProps[i].Value >>= nWidth;
+ else if (sName.compareToAscii("TrackedChangesViewSettings") == 0)
+ {
+ uno::Sequence<beans::PropertyValue> aChangeProps;
+ if(aViewProps[i].Value >>= aChangeProps)
+ SetChangeTrackingViewSettings(aChangeProps);
+ }
+ }
+ if (nHeight && nWidth)
+ {
+ if (GetModel().is())
+ {
+ ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
+ if (pDocObj)
+ {
+ SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
+ if (pEmbeddedObj)
+ {
+ Rectangle aRect;
+ aRect.setX( nLeft );
+ aRect.setY( nTop );
+ aRect.setWidth( nWidth );
+ aRect.setHeight( nHeight );
+ pEmbeddedObj->SetVisArea(aRect);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyValue>& aConfigProps)
+{
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ sal_Int32 nCount(aConfigProps.getLength());
+ rtl::OUString sCTName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey"));
+ rtl::OUString sSCName(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration"));
+ for (sal_Int32 i = nCount - 1; i >= 0; --i)
+ {
+ if (aConfigProps[i].Name == sCTName)
+ {
+ rtl::OUString sKey;
+ if (aConfigProps[i].Value >>= sKey)
+ {
+ uno::Sequence<sal_Int8> aPass;
+ SvXMLUnitConverter::decodeBase64(aPass, sKey);
+ if (aPass.getLength())
+ {
+ if (pDoc->GetChangeTrack())
+ pDoc->GetChangeTrack()->SetProtection(aPass);
+ else
+ {
+ ScStrCollection aUsers;
+ ScChangeTrack* pTrack = new ScChangeTrack(pDoc, aUsers);
+ pTrack->SetProtection(aPass);
+ pDoc->SetChangeTrack(pTrack);
+ }
+ }
+ }
+ }
+ else if (aConfigProps[i].Name == sSCName)
+ {
+ uno::Type aType = aConfigProps[i].Value.getValueType();
+ uno::Reference<beans::XPropertySet> xImportInfo =
+ getImportInfo();
+
+ if (xImportInfo.is() &&
+ (aType.equals(getCppuType(
+ (uno::Reference<container::XNameContainer> *)0 ) ) ||
+ aType.equals(getCppuType(
+ (uno::Reference<container::XNameAccess> *)0 ) ) ) )
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
+ xImportInfo->getPropertySetInfo();
+ if (xPropertySetInfo.is() &&
+ xPropertySetInfo->hasPropertyByName(sSCName) )
+ {
+ xImportInfo->setPropertyValue(sSCName,
+ aConfigProps[i].Value );
+ }
+ }
+ }
+ }
+ uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings")));
+ uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY);
+ if (xProperties.is())
+ SvXMLUnitConverter::convertPropertySet(xProperties, aConfigProps);
+ }
+ }
+}
+
+sal_Int32 ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey, const rtl::OUString& rCurrency)
+{
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ {
+ uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
+ if (xLocalNumberFormats.is())
+ {
+ rtl::OUString sFormatString;
+ try
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xLocalNumberFormats->getByKey(nKey));
+ if (xProperties.is())
+ {
+ lang::Locale aLocale;
+ if (GetDocument() && (xProperties->getPropertyValue(sLocale) >>= aLocale))
+ {
+ LockSolarMutex();
+ LocaleDataWrapper aLocaleData( GetDocument()->GetServiceManager(), aLocale );
+ rtl::OUStringBuffer aBuffer(15);
+ aBuffer.appendAscii("#");
+ aBuffer.append( aLocaleData.getNumThousandSep() );
+ aBuffer.appendAscii("##0");
+ aBuffer.append( aLocaleData.getNumDecimalSep() );
+ aBuffer.appendAscii("00 [$");
+ aBuffer.append(rCurrency);
+ aBuffer.appendAscii("]");
+ UnlockSolarMutex();
+ sFormatString = aBuffer.makeStringAndClear();
+ sal_Int32 nNewKey = xLocalNumberFormats->queryKey(sFormatString, aLocale, sal_True);
+ if (nNewKey == -1)
+ nNewKey = xLocalNumberFormats->addNew(sFormatString, aLocale);
+ return nNewKey;
+ }
+ }
+ }
+ catch ( util::MalformedNumberFormatException& rException )
+ {
+ rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Fehler im Formatstring "));
+ sErrorMessage += sFormatString;
+ sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" an Position "));
+ sErrorMessage += rtl::OUString::valueOf(rException.CheckPos);
+ uno::Sequence<rtl::OUString> aSeq(1);
+ aSeq[0] = sErrorMessage;
+ uno::Reference<xml::sax::XLocator> xLocator;
+ SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rException.Message, xLocator);
+ }
+ }
+ }
+ return nKey;
+}
+
+sal_Bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat, const rtl::OUString& sCurrentCurrency, const rtl::OUString& sBankSymbol)
+{
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ {
+ uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
+ if (xLocalNumberFormats.is())
+ {
+ try
+ {
+ uno::Reference <beans::XPropertySet> xNumberPropertySet(xLocalNumberFormats->getByKey(nNumberFormat));
+ if (xNumberPropertySet.is())
+ {
+ rtl::OUString sTemp;
+ if ( xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURRENCYSYMBOL))) >>= sTemp)
+ {
+ if (sCurrentCurrency.equals(sTemp))
+ return sal_True;
+ // #i61657# This may be a legacy currency symbol that changed in the meantime.
+ if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency, sBankSymbol) != NULL)
+ return true;
+ // In the rare case that sCurrentCurrency is not the
+ // currency symbol, but a matching ISO code
+ // abbreviation instead that was obtained through
+ // XMLNumberFormatAttributesExportHelper::GetCellType(),
+ // check with the number format's symbol. This happens,
+ // for example, in the es_BO locale, where a legacy
+ // B$,BOB matched B$->BOP, which leads to
+ // sCurrentCurrency being BOP, and the previous call
+ // with BOP,BOB didn't find an entry, but B$,BOB will.
+ return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp, sBankSymbol) != NULL;
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Numberformat not found");
+ }
+ }
+ }
+ return sal_False;
+}
+
+void ScXMLImport::SetType(uno::Reference <beans::XPropertySet>& rProperties,
+ sal_Int32& rNumberFormat,
+ const sal_Int16 nCellType,
+ const rtl::OUString& rCurrency)
+{
+ if ((nCellType != util::NumberFormat::TEXT) && (nCellType != util::NumberFormat::UNDEFINED))
+ {
+ if (rNumberFormat == -1)
+ rProperties->getPropertyValue( sNumberFormat ) >>= rNumberFormat;
+ DBG_ASSERT(rNumberFormat != -1, "no NumberFormat");
+ sal_Bool bIsStandard;
+ // sCurrentCurrency may be the ISO code abbreviation if the currency
+ // symbol matches such, or if no match found the symbol itself!
+ rtl::OUString sCurrentCurrency;
+ sal_Int32 nCurrentCellType(
+ GetNumberFormatAttributesExportHelper()->GetCellType(
+ rNumberFormat, sCurrentCurrency, bIsStandard) & ~util::NumberFormat::DEFINED);
+ if ((nCellType != nCurrentCellType) && !((nCellType == util::NumberFormat::NUMBER &&
+ ((nCurrentCellType == util::NumberFormat::SCIENTIFIC) ||
+ (nCurrentCellType == util::NumberFormat::FRACTION) ||
+ (nCurrentCellType == util::NumberFormat::LOGICAL) ||
+ (nCurrentCellType == 0))) || (nCurrentCellType == util::NumberFormat::TEXT)) && !((nCellType == util::NumberFormat::DATETIME) &&
+ (nCurrentCellType == util::NumberFormat::DATE)))
+ {
+ if (!xNumberFormats.is())
+ {
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ xNumberFormats.set(xNumberFormatsSupplier->getNumberFormats());
+ }
+ if (xNumberFormats.is())
+ {
+ try
+ {
+ uno::Reference < beans::XPropertySet> xNumberFormatProperties(xNumberFormats->getByKey(rNumberFormat));
+ if (xNumberFormatProperties.is())
+ {
+ if (nCellType != util::NumberFormat::CURRENCY)
+ {
+ lang::Locale aLocale;
+ if ( xNumberFormatProperties->getPropertyValue(sLocale) >>= aLocale )
+ {
+ if (!xNumberFormatTypes.is())
+ xNumberFormatTypes.set(uno::Reference <util::XNumberFormatTypes>(xNumberFormats, uno::UNO_QUERY));
+ rProperties->setPropertyValue( sNumberFormat, uno::makeAny(xNumberFormatTypes->getStandardFormat(nCellType, aLocale)) );
+ }
+ }
+ else if (rCurrency.getLength() && sCurrentCurrency.getLength())
+ {
+ if (!sCurrentCurrency.equals(rCurrency))
+ if (!IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
+ rProperties->setPropertyValue( sNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency)));
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Numberformat not found");
+ }
+ }
+ }
+ else
+ {
+ if ((nCellType == util::NumberFormat::CURRENCY) && rCurrency.getLength() && sCurrentCurrency.getLength() &&
+ !sCurrentCurrency.equals(rCurrency) && !IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
+ rProperties->setPropertyValue( sNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency)));
+ }
+ }
+}
+
+void ScXMLImport::AddStyleRange(const table::CellRangeAddress& rCellRange)
+{
+ if (!xSheetCellRanges.is() && GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRanges"))), uno::UNO_QUERY));
+ DBG_ASSERT(xSheetCellRanges.is(), "didn't get SheetCellRanges");
+
+ }
+ xSheetCellRanges->addRangeAddress(rCellRange, sal_False);
+}
+
+void ScXMLImport::SetStyleToRanges()
+{
+ if (sPrevStyleName.getLength())
+ {
+ uno::Reference <beans::XPropertySet> xProperties (xSheetCellRanges, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ XMLTableStylesContext *pStyles((XMLTableStylesContext *)GetAutoStyles());
+ XMLTableStyleContext* pStyle( pStyles ? (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName, sal_True) : NULL );
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xProperties);
+ sal_Int32 nNumberFormat(pStyle->GetNumberFormat());
+ SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+
+ // store first cell of first range for each style, once per sheet
+ uno::Sequence<table::CellRangeAddress> aAddresses(xSheetCellRanges->getRangeAddresses());
+ if ( aAddresses.getLength() > 0 )
+ {
+ const table::CellRangeAddress& rRange = aAddresses[0];
+ if ( rRange.Sheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ pSheetData->AddCellStyle( sPrevStyleName,
+ ScAddress( (SCCOL)rRange.StartColumn, (SCROW)rRange.StartRow, (SCTAB)rRange.Sheet ) );
+ pStyle->SetLastSheet(rRange.Sheet);
+ }
+ }
+ }
+ else
+ {
+ xProperties->setPropertyValue(sCellStyle, uno::makeAny(GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName )));
+ sal_Int32 nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName));
+ sal_Bool bInsert(nNumberFormat == -1);
+ SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+ if (bInsert)
+ GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName, nNumberFormat);
+ }
+ }
+ }
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(
+ xMultiServiceFactory->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRanges"))),
+ uno::UNO_QUERY));
+ }
+ DBG_ASSERT(xSheetCellRanges.is(), "didn't get SheetCellRanges");
+}
+
+void ScXMLImport::SetStyleToRange(const ScRange& rRange, const rtl::OUString* pStyleName,
+ const sal_Int16 nCellType, const rtl::OUString* pCurrency)
+{
+ if (!sPrevStyleName.getLength())
+ {
+ nPrevCellType = nCellType;
+ if (pStyleName)
+ sPrevStyleName = *pStyleName;
+ if (pCurrency)
+ sPrevCurrency = *pCurrency;
+ else if (sPrevCurrency.getLength())
+ sPrevCurrency = sEmpty;
+ }
+ else if ((nCellType != nPrevCellType) ||
+ ((pStyleName && !pStyleName->equals(sPrevStyleName)) ||
+ (!pStyleName && sPrevStyleName.getLength())) ||
+ ((pCurrency && !pCurrency->equals(sPrevCurrency)) ||
+ (!pCurrency && sPrevCurrency.getLength())))
+ {
+ SetStyleToRanges();
+ nPrevCellType = nCellType;
+ if (pStyleName)
+ sPrevStyleName = *pStyleName;
+ else if(sPrevStyleName.getLength())
+ sPrevStyleName = sEmpty;
+ if (pCurrency)
+ sPrevCurrency = *pCurrency;
+ else if(sPrevCurrency.getLength())
+ sPrevCurrency = sEmpty;
+ }
+ table::CellRangeAddress aCellRange;
+ aCellRange.StartColumn = rRange.aStart.Col();
+ aCellRange.StartRow = rRange.aStart.Row();
+ aCellRange.Sheet = rRange.aStart.Tab();
+ aCellRange.EndColumn = rRange.aEnd.Col();
+ aCellRange.EndRow = rRange.aEnd.Row();
+ AddStyleRange(aCellRange);
+}
+
+sal_Bool ScXMLImport::SetNullDateOnUnitConverter()
+{
+ if (!bNullDateSetted)
+ bNullDateSetted = GetMM100UnitConverter().setNullDate(GetModel());
+ DBG_ASSERT(bNullDateSetted, "could not set the null date");
+ return bNullDateSetted;
+}
+
+XMLNumberFormatAttributesExportHelper* ScXMLImport::GetNumberFormatAttributesExportHelper()
+{
+ if (!pNumberFormatAttributesExportHelper)
+ pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier());
+ return pNumberFormatAttributesExportHelper;
+}
+
+ScMyStyleNumberFormats* ScXMLImport::GetStyleNumberFormats()
+{
+ if (!pStyleNumberFormats)
+ pStyleNumberFormats = new ScMyStyleNumberFormats();
+ return pStyleNumberFormats;
+}
+
+void ScXMLImport::SetStylesToRangesFinished()
+{
+ SetStyleToRanges();
+ sPrevStyleName = sEmpty;
+}
+
+// XImporter
+void SAL_CALL ScXMLImport::setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ LockSolarMutex();
+ SvXMLImport::setTargetDocument( xDoc );
+
+ uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY);
+ pDoc = ScXMLConverter::GetScDocument( xModel );
+ DBG_ASSERT( pDoc, "ScXMLImport::setTargetDocument - no ScDocument!" );
+ if (!pDoc)
+ throw lang::IllegalArgumentException();
+
+ bFromWrapper = pDoc->IsXMLFromWrapper(); // UnlockSolarMutex below still works normally
+
+ uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
+ if (xActionLockable.is())
+ xActionLockable->addActionLock();
+ UnlockSolarMutex();
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ScXMLImport::getImplementationName( )
+throw(::com::sun::star::uno::RuntimeException)
+{
+ switch( getImportFlags() )
+ {
+ case IMPORT_ALL:
+ return ScXMLImport_getImplementationName();
+ case (IMPORT_STYLES|IMPORT_MASTERSTYLES|IMPORT_AUTOSTYLES|IMPORT_FONTDECLS):
+ return ScXMLImport_Styles_getImplementationName();
+ case (IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_FONTDECLS):
+ return ScXMLImport_Content_getImplementationName();
+ case IMPORT_META:
+ return ScXMLImport_Meta_getImplementationName();
+ case IMPORT_SETTINGS:
+ return ScXMLImport_Settings_getImplementationName();
+ default:
+ // generic name for 'unknown' cases
+ return ScXMLImport_getImplementationName();
+ }
+ return SvXMLImport::getImplementationName();
+}
+
+// ::com::sun::star::xml::sax::XDocumentHandler
+void SAL_CALL ScXMLImport::startDocument(void)
+throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
+{
+ LockSolarMutex();
+ SvXMLImport::startDocument();
+ if (pDoc && !pDoc->IsImportingXML())
+ {
+ ScModelObj::getImplementation(GetModel())->BeforeXMLLoading();
+ bSelfImportingXMLSet = sal_True;
+ }
+
+ // if content and styles are loaded with separate imports,
+ // set bLatinDefaultStyle flag at the start of the content import
+ sal_uInt16 nFlags = getImportFlags();
+ if ( ( nFlags & IMPORT_CONTENT ) && !( nFlags & IMPORT_STYLES ) )
+ ExamineDefaultStyle();
+
+ if (getImportFlags() & IMPORT_CONTENT)
+ {
+ if (GetModel().is())
+ {
+ // store initial namespaces, to find the ones that were added from the file later
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap();
+ pSheetData->StoreInitialNamespaces(rNamespaces);
+ }
+ }
+
+ UnlockSolarMutex();
+}
+
+sal_Int32 ScXMLImport::GetRangeType(const rtl::OUString sRangeType) const
+{
+ sal_Int32 nRangeType(0);
+ rtl::OUStringBuffer sBuffer;
+ sal_Int16 i = 0;
+ while (i <= sRangeType.getLength())
+ {
+ if ((sRangeType[i] == ' ') || (i == sRangeType.getLength()))
+ {
+ rtl::OUString sTemp = sBuffer.makeStringAndClear();
+ if (sTemp.compareToAscii(SC_REPEAT_COLUMN) == 0)
+ nRangeType |= sheet::NamedRangeFlag::COLUMN_HEADER;
+ else if (sTemp.compareToAscii(SC_REPEAT_ROW) == 0)
+ nRangeType |= sheet::NamedRangeFlag::ROW_HEADER;
+ else if (sTemp.compareToAscii(SC_FILTER) == 0)
+ nRangeType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
+ else if (sTemp.compareToAscii(SC_PRINT_RANGE) == 0)
+ nRangeType |= sheet::NamedRangeFlag::PRINT_AREA;
+ }
+ else if (i < sRangeType.getLength())
+ sBuffer.append(sRangeType[i]);
+ ++i;
+ }
+ return nRangeType;
+}
+
+void ScXMLImport::SetLabelRanges()
+{
+ ScMyLabelRanges* pLabelRanges = GetLabelRanges();
+ if (pLabelRanges)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Any aColAny = xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COLLABELRNG)));
+ uno::Any aRowAny = xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ROWLABELRNG)));
+
+ uno::Reference< sheet::XLabelRanges > xColRanges;
+ uno::Reference< sheet::XLabelRanges > xRowRanges;
+
+ if ( ( aColAny >>= xColRanges ) && ( aRowAny >>= xRowRanges ) )
+ {
+ table::CellRangeAddress aLabelRange;
+ table::CellRangeAddress aDataRange;
+
+ ScMyLabelRanges::iterator aItr = pLabelRanges->begin();
+ while (aItr != pLabelRanges->end())
+ {
+ sal_Int32 nOffset1(0);
+ sal_Int32 nOffset2(0);
+ FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;
+
+ if (ScRangeStringConverter::GetRangeFromString( aLabelRange, (*aItr)->sLabelRangeStr, GetDocument(), eConv, nOffset1 ) &&
+ ScRangeStringConverter::GetRangeFromString( aDataRange, (*aItr)->sDataRangeStr, GetDocument(), eConv, nOffset2 ))
+ {
+ if ( (*aItr)->bColumnOrientation )
+ xColRanges->addNew( aLabelRange, aDataRange );
+ else
+ xRowRanges->addNew( aLabelRange, aDataRange );
+ }
+
+ delete *aItr;
+ aItr = pLabelRanges->erase(aItr);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLImport::SetNamedRanges()
+{
+ ScMyNamedExpressions* pNamedExpressions(GetNamedExpressions());
+ if (pNamedExpressions)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XNamedRanges> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_NAMEDRANGES))), uno::UNO_QUERY);
+ if (xNamedRanges.is())
+ {
+ ScMyNamedExpressions::iterator aItr(pNamedExpressions->begin());
+ ScMyNamedExpressions::const_iterator aEndItr(pNamedExpressions->end());
+ table::CellAddress aCellAddress;
+ rtl::OUString sTempContent(RTL_CONSTASCII_USTRINGPARAM("0"));
+ while (aItr != aEndItr)
+ {
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetAddressFromString(
+ aCellAddress, (*aItr)->sBaseCellAddress, GetDocument(), FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ try
+ {
+ xNamedRanges->addNewByName((*aItr)->sName, sTempContent, aCellAddress, GetRangeType((*aItr)->sRangeType));
+ }
+ catch( uno::RuntimeException& )
+ {
+ DBG_ERROR("here are some Named Ranges with the same name");
+ uno::Reference < container::XIndexAccess > xIndex(xNamedRanges, uno::UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nMax(xIndex->getCount());
+ sal_Bool bInserted(sal_False);
+ sal_Int32 nCount(1);
+ rtl::OUStringBuffer sName((*aItr)->sName);
+ sName.append(sal_Unicode('_'));
+ while (!bInserted && nCount <= nMax)
+ {
+ rtl::OUStringBuffer sTemp(sName);
+ sTemp.append(rtl::OUString::valueOf(nCount));
+ try
+ {
+ xNamedRanges->addNewByName(sTemp.makeStringAndClear(), sTempContent, aCellAddress, GetRangeType((*aItr)->sRangeType));
+ bInserted = sal_True;
+ }
+ catch( uno::RuntimeException& )
+ {
+ ++nCount;
+ }
+ }
+ }
+ }
+ }
+ ++aItr;
+ }
+ aItr = pNamedExpressions->begin();
+ while (aItr != aEndItr)
+ {
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetAddressFromString(
+ aCellAddress, (*aItr)->sBaseCellAddress, GetDocument(), FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ uno::Reference <sheet::XNamedRange> xNamedRange(xNamedRanges->getByName((*aItr)->sName), uno::UNO_QUERY);
+ if (xNamedRange.is())
+ {
+ LockSolarMutex();
+ ScNamedRangeObj* pNamedRangeObj = ScNamedRangeObj::getImplementation( xNamedRange);
+ if (pNamedRangeObj)
+ {
+ sTempContent = (*aItr)->sContent;
+ // Get rid of leading sheet dots in simple ranges.
+ if (!(*aItr)->bIsExpression)
+ ScXMLConverter::ParseFormula( sTempContent, false);
+ pNamedRangeObj->SetContentWithGrammar( sTempContent, (*aItr)->eGrammar);
+ }
+ UnlockSolarMutex();
+ }
+ }
+ delete *aItr;
+ aItr = pNamedExpressions->erase(aItr);
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL ScXMLImport::endDocument(void)
+throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
+{
+ LockSolarMutex();
+ if (getImportFlags() & IMPORT_CONTENT)
+ {
+ if (GetModel().is())
+ {
+ uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
+ if (xViewDataSupplier.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData());
+ if (xIndexAccess.is() && xIndexAccess->getCount() > 0)
+ {
+ uno::Sequence< beans::PropertyValue > aSeq;
+ if (xIndexAccess->getByIndex(0) >>= aSeq)
+ {
+ sal_Int32 nCount (aSeq.getLength());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rtl::OUString sName(aSeq[i].Name);
+ if (sName.compareToAscii(SC_ACTIVETABLE) == 0)
+ {
+ rtl::OUString sValue;
+ if(aSeq[i].Value >>= sValue)
+ {
+ String sTabName(sValue);
+ SCTAB nTab(0);
+ if (pDoc->GetTable(sTabName, nTab))
+ {
+ pDoc->SetVisibleTab(nTab);
+ i = nCount;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ SetLabelRanges();
+ SetNamedRanges();
+ }
+ GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
+ if (pDoc)
+ pDoc->CompileXML();
+
+ if (pDoc && GetModel().is())
+ {
+ // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
+ // in UpdateRowHeights can already clear the flags again)
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (!pSheetData->IsSheetBlocked( nTab ))
+ pDoc->SetStreamValid( nTab, TRUE );
+ }
+
+ aTables.UpdateRowHeights();
+ aTables.ResizeShapes();
+ }
+ if (GetModel().is())
+ {
+ uno::Reference<document::XActionLockable> xActionLockable(GetModel(), uno::UNO_QUERY);
+ if (xActionLockable.is())
+ xActionLockable->removeActionLock();
+ }
+ SvXMLImport::endDocument();
+
+ if (pDoc && bSelfImportingXMLSet)
+ {
+ ScModelObj::getImplementation(GetModel())->AfterXMLLoading(sal_True);
+ }
+
+ UnlockSolarMutex();
+}
+
+// XEventListener
+void ScXMLImport::DisposingModel()
+{
+ SvXMLImport::DisposingModel();
+ pDoc = NULL;
+}
+
+void ScXMLImport::LockSolarMutex()
+{
+ // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
+ // so there's no need to allocate (and later delete) the ScUnoGuard.
+ if (bFromWrapper)
+ {
+ DBG_TESTSOLARMUTEX();
+ return;
+ }
+
+ if (nSolarMutexLocked == 0)
+ {
+ DBG_ASSERT(!pScUnoGuard, "Solar Mutex is locked");
+ pScUnoGuard = new ScUnoGuard();
+ }
+ ++nSolarMutexLocked;
+}
+
+
+void ScXMLImport::UnlockSolarMutex()
+{
+ if (nSolarMutexLocked > 0)
+ {
+ nSolarMutexLocked--;
+ if (nSolarMutexLocked == 0)
+ {
+ DBG_ASSERT(pScUnoGuard, "Solar Mutex is always unlocked");
+ delete pScUnoGuard;
+ pScUnoGuard = NULL;
+ }
+ }
+}
+
+sal_Int32 ScXMLImport::GetByteOffset()
+{
+ sal_Int32 nOffset = -1;
+ uno::Reference<xml::sax::XLocator> xLocator = GetLocator();
+ uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY ); //! should use different interface
+ if ( xSeek.is() )
+ nOffset = (sal_Int32)xSeek->getPosition();
+ return nOffset;
+}
+
+void ScXMLImport::SetRangeOverflowType(sal_uInt32 nType)
+{
+ // #i31130# Overflow is stored in the document, because the ScXMLImport object
+ // isn't available in ScXMLImportWrapper::ImportFromComponent when using the
+ // OOo->Oasis transformation.
+
+ if ( pDoc )
+ pDoc->SetRangeOverflowType( nType );
+}
+
+void ScXMLImport::ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc)
+{
+ nProgressCount += nInc;
+ if (bEditCell || nProgressCount > 100)
+ {
+ GetProgressBarHelper()->Increment(nProgressCount);
+ nProgressCount = 0;
+ }
+}
+
+sal_Int32 ScXMLImport::GetVisibleSheet()
+{
+ // Get the visible sheet number from model's view data (after settings were loaded),
+ // or 0 (default: first sheet) if no settings available.
+
+ uno::Reference<document::XViewDataSupplier> xSupp(GetModel(), uno::UNO_QUERY);
+ if (xSupp.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndex = xSupp->getViewData();
+ if ( xIndex.is() && xIndex->getCount() > 0 )
+ {
+ uno::Any aAny( xIndex->getByIndex(0) );
+ uno::Sequence<beans::PropertyValue> aViewSettings; // settings for (first) view
+ if ( aAny >>= aViewSettings )
+ {
+ sal_Int32 nCount = aViewSettings.getLength();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ if ( aViewSettings[i].Name.compareToAscii(SC_ACTIVETABLE) == 0 )
+ {
+ rtl::OUString sValue;
+ if(aViewSettings[i].Value >>= sValue)
+ {
+ String sTabName(sValue);
+ SCTAB nTab = 0;
+ if (pDoc->GetTable(sTabName, nTab))
+ return nTab;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void ScXMLImport::ExtractFormulaNamespaceGrammar(
+ OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const
+{
+ // parse the attribute value, extract namespace ID, literal namespace, and formula string
+ rFormulaNmsp = OUString();
+ sal_uInt16 nNsId = GetNamespaceMap()._GetKeyByAttrName( rAttrValue, 0, &rFormula, &rFormulaNmsp, 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
new file mode 100644
index 000000000000..9771655ebd4b
--- /dev/null
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -0,0 +1,1048 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLIMPRT_HXX
+#define SC_XMLIMPRT_HXX
+
+#include <rsc/rscsfx.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/xmlstyle.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <tools/time.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include "xmlsubti.hxx"
+#include "global.hxx"
+#include "formula/grammar.hxx"
+
+#include "xmlstyle.hxx"
+#include "XMLDetectiveContext.hxx"
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+
+#include <vector>
+#include <hash_map>
+
+class ScRangeList;
+class ScMyStyleNumberFormats;
+class XMLNumberFormatAttributesExportHelper;
+
+enum ScXMLDocTokens
+{
+ XML_TOK_DOC_FONTDECLS,
+ XML_TOK_DOC_STYLES,
+ XML_TOK_DOC_AUTOSTYLES,
+ XML_TOK_DOC_MASTERSTYLES,
+ XML_TOK_DOC_META,
+ XML_TOK_DOC_SCRIPTS,
+ XML_TOK_DOC_BODY,
+ XML_TOK_DOC_SETTINGS,
+ XML_TOK_OFFICE_END=XML_TOK_UNKNOWN
+};
+
+enum ScXMLStylesTokens
+{
+ XML_TOK_STYLES_STYLE
+};
+
+enum ScXMLStylesAttrTokens
+{
+ XML_TOK_STYLES_STYLE_NAME,
+ XML_TOK_STYLES_STYLE_FAMILY,
+ XML_TOK_STYLES_STYLE_PARENT_STYLE_NAME
+};
+
+enum ScXMLStyleTokens
+{
+ XML_TOK_STYLE_PROPERTIES
+};
+
+enum ScXMLBodyTokens
+{
+ XML_TOK_BODY_TRACKED_CHANGES,
+ XML_TOK_BODY_CALCULATION_SETTINGS,
+ XML_TOK_BODY_CONTENT_VALIDATIONS,
+ XML_TOK_BODY_LABEL_RANGES,
+ XML_TOK_BODY_TABLE,
+ XML_TOK_BODY_NAMED_EXPRESSIONS,
+ XML_TOK_BODY_DATABASE_RANGES,
+ XML_TOK_BODY_DATABASE_RANGE,
+ XML_TOK_BODY_DATA_PILOT_TABLES,
+ XML_TOK_BODY_CONSOLIDATION,
+ XML_TOK_BODY_DDE_LINKS
+};
+
+enum ScXMLContentValidationsElemTokens
+{
+ XML_TOK_CONTENT_VALIDATION
+};
+
+enum ScXMLContentValidationElemTokens
+{
+ XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE,
+ XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE,
+ XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO,
+ XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS
+};
+
+enum ScXMLContentValidationAttrTokens
+{
+ XML_TOK_CONTENT_VALIDATION_NAME,
+ XML_TOK_CONTENT_VALIDATION_CONDITION,
+ XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS,
+ XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL,
+ XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST
+};
+
+enum ScXMLContentValidationMessageElemTokens
+{
+ XML_TOK_P
+};
+
+enum ScXMLContentValidationHelpMessageAttrTokens
+{
+ XML_TOK_HELP_MESSAGE_ATTR_TITLE,
+ XML_TOK_HELP_MESSAGE_ATTR_DISPLAY
+};
+
+enum ScXMLContentValidationErrorMessageAttrTokens
+{
+ XML_TOK_ERROR_MESSAGE_ATTR_TITLE,
+ XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY,
+ XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE
+};
+
+enum ScXMLContentValidationErrorMacroAttrTokens
+{
+ XML_TOK_ERROR_MACRO_ATTR_NAME,
+ XML_TOK_ERROR_MACRO_ATTR_EXECUTE
+};
+
+enum ScXMLLabelRangesElemTokens
+{
+ XML_TOK_LABEL_RANGE_ELEM
+};
+
+enum ScXMLLabelRangeAttrTokens
+{
+ XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE,
+ XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE,
+ XML_TOK_LABEL_RANGE_ATTR_ORIENTATION
+};
+
+enum ScXMLTableTokens
+{
+ XML_TOK_TABLE_COL_GROUP,
+ XML_TOK_TABLE_HEADER_COLS,
+ XML_TOK_TABLE_COLS,
+ XML_TOK_TABLE_COL,
+ XML_TOK_TABLE_ROW_GROUP,
+ XML_TOK_TABLE_HEADER_ROWS,
+ XML_TOK_TABLE_ROWS,
+ XML_TOK_TABLE_ROW,
+ XML_TOK_TABLE_SOURCE,
+ XML_TOK_TABLE_SCENARIO,
+ XML_TOK_TABLE_SHAPES,
+ XML_TOK_TABLE_FORMS,
+ XML_TOK_TABLE_EVENT_LISTENERS,
+ XML_TOK_TABLE_EVENT_LISTENERS_EXT
+};
+
+enum ScXMLTableRowsTokens
+{
+ XML_TOK_TABLE_ROWS_ROW_GROUP,
+ XML_TOK_TABLE_ROWS_HEADER_ROWS,
+ XML_TOK_TABLE_ROWS_ROWS,
+ XML_TOK_TABLE_ROWS_ROW
+};
+
+enum ScXMLTableColsTokens
+{
+ XML_TOK_TABLE_COLS_COL_GROUP,
+ XML_TOK_TABLE_COLS_HEADER_COLS,
+ XML_TOK_TABLE_COLS_COLS,
+ XML_TOK_TABLE_COLS_COL
+};
+
+enum ScXMLTableAttrTokens
+{
+ XML_TOK_TABLE_NAME,
+ XML_TOK_TABLE_STYLE_NAME,
+ XML_TOK_TABLE_PROTECTION,
+ XML_TOK_TABLE_PRINT_RANGES,
+ XML_TOK_TABLE_PASSWORD,
+ XML_TOK_TABLE_PRINT
+};
+
+enum ScXMLTableScenarioAttrTokens
+{
+ XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER,
+ XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR,
+ XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK,
+ XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES,
+ XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS,
+ XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE,
+ XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES,
+ XML_TOK_TABLE_SCENARIO_ATTR_COMMENT,
+ XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED
+};
+
+enum ScXMLTableColAttrTokens
+{
+ XML_TOK_TABLE_COL_ATTR_STYLE_NAME,
+ XML_TOK_TABLE_COL_ATTR_REPEATED,
+ XML_TOK_TABLE_COL_ATTR_VISIBILITY,
+ XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME
+};
+
+enum ScXMLTableRowTokens
+{
+ XML_TOK_TABLE_ROW_CELL,
+ XML_TOK_TABLE_ROW_COVERED_CELL
+};
+
+enum ScXMLTableRowAttrTokens
+{
+ XML_TOK_TABLE_ROW_ATTR_STYLE_NAME,
+ XML_TOK_TABLE_ROW_ATTR_VISIBILITY,
+ XML_TOK_TABLE_ROW_ATTR_REPEATED,
+ XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME
+// XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT
+};
+
+enum ScXMLTableRowCellTokens
+{
+ XML_TOK_TABLE_ROW_CELL_P,
+ XML_TOK_TABLE_ROW_CELL_TABLE,
+ XML_TOK_TABLE_ROW_CELL_ANNOTATION,
+ XML_TOK_TABLE_ROW_CELL_DETECTIVE,
+ XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE
+};
+
+enum ScXMLTableRowCellAttrTokens
+{
+ XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME,
+ XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED,
+ XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA,
+ XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY
+};
+
+enum ScXMLAnnotationAttrTokens
+{
+ XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR,
+ XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE,
+ XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING,
+ XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY,
+ XML_TOK_TABLE_ANNOTATION_ATTR_X,
+ XML_TOK_TABLE_ANNOTATION_ATTR_Y
+};
+
+enum ScXMLDetectiveElemTokens
+{
+ XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED,
+ XML_TOK_DETECTIVE_ELEM_OPERATION
+};
+
+enum ScXMLDetectiveHighlightedAttrTokens
+{
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE,
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION,
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR,
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID
+};
+
+enum ScXMLDetectiveOperationAttrTokens
+{
+ XML_TOK_DETECTIVE_OPERATION_ATTR_NAME,
+ XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX
+};
+
+enum ScXMLCellRangeSourceAttrTokens
+{
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY
+};
+
+enum ScXMLNamedExpressionsTokens
+{
+ XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE,
+ XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION
+};
+
+enum ScXMLNamedRangeAttrTokens
+{
+ XML_TOK_NAMED_RANGE_ATTR_NAME,
+ XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS,
+ XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS,
+ XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS
+};
+
+enum ScXMLNamedExpressionAttrTokens
+{
+ XML_TOK_NAMED_EXPRESSION_ATTR_NAME,
+ XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS,
+ XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION
+};
+
+enum ScXMLDatabaseRangesTokens
+{
+ XML_TOK_DATABASE_RANGE
+};
+
+enum ScXMLDatabaseRangeTokens
+{
+ XML_TOK_DATABASE_RANGE_SOURCE_SQL,
+ XML_TOK_DATABASE_RANGE_SOURCE_TABLE,
+ XML_TOK_DATABASE_RANGE_SOURCE_QUERY,
+ XML_TOK_FILTER,
+ XML_TOK_SORT,
+ XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES
+};
+
+enum ScXMLDatabaseRangeAttrTokens
+{
+ XML_TOK_DATABASE_RANGE_ATTR_NAME,
+ XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION,
+ XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES,
+ XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE,
+ XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA,
+ XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION,
+ XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER,
+ XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS,
+ XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY
+};
+
+enum ScXMLDatabaseRangeSourceSQLAttrTokens
+{
+ XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME,
+ XML_TOK_SOURCE_SQL_ATTR_HREF,
+ XML_TOK_SOURCE_SQL_ATTR_CONNECTION_RESSOURCE,
+ XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT,
+ XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT
+};
+
+enum ScXMLDatabaseRangeSourceTableAttrTokens
+{
+ XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME,
+ XML_TOK_SOURCE_TABLE_ATTR_HREF,
+ XML_TOK_SOURCE_TABLE_ATTR_CONNECTION_RESSOURCE,
+ XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME
+};
+
+enum ScXMLDatabaseRangeSourceQueryAttrTokens
+{
+ XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME,
+ XML_TOK_SOURCE_QUERY_ATTR_HREF,
+ XML_TOK_SOURCE_QUERY_ATTR_CONNECTION_RESSOURCE,
+ XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME
+};
+
+enum ScXMLFilterTokens
+{
+ XML_TOK_FILTER_AND,
+ XML_TOK_FILTER_OR,
+ XML_TOK_FILTER_CONDITION
+};
+
+enum ScXMLFilterAttrTokens
+{
+ XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS,
+ XML_TOK_FILTER_ATTR_CONDITION_SOURCE,
+ XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES
+};
+
+enum ScXMLFilterConditionAttrTokens
+{
+ XML_TOK_CONDITION_ATTR_FIELD_NUMBER,
+ XML_TOK_CONDITION_ATTR_CASE_SENSITIVE,
+ XML_TOK_CONDITION_ATTR_DATA_TYPE,
+ XML_TOK_CONDITION_ATTR_VALUE,
+ XML_TOK_CONDITION_ATTR_OPERATOR
+};
+
+enum ScXMLSortTokens
+{
+ XML_TOK_SORT_SORT_BY
+};
+
+enum ScXMLSortAttrTokens
+{
+ XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT,
+ XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_SORT_ATTR_CASE_SENSITIVE,
+ XML_TOK_SORT_ATTR_LANGUAGE,
+ XML_TOK_SORT_ATTR_COUNTRY,
+ XML_TOK_SORT_ATTR_ALGORITHM
+};
+
+enum ScXMLSortSortByAttrTokens
+{
+ XML_TOK_SORT_BY_ATTR_FIELD_NUMBER,
+ XML_TOK_SORT_BY_ATTR_DATA_TYPE,
+ XML_TOK_SORT_BY_ATTR_ORDER
+};
+
+enum ScXMLDatabaseRangeSubTotalRulesTokens
+{
+ XML_TOK_SUBTOTAL_RULES_SORT_GROUPS,
+ XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE
+};
+
+enum ScXMLDatabaseRangeSubTotalRulesAttrTokens
+{
+ XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT,
+ XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE,
+ XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE
+};
+
+enum ScXMLSubTotalRulesSortGroupsAttrTokens
+{
+ XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE,
+ XML_TOK_SORT_GROUPS_ATTR_ORDER
+};
+
+enum ScXMLSubTotalRulesSubTotalRuleTokens
+{
+ XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD
+};
+
+enum ScXMLSubTotalRulesSubTotalRuleAttrTokens
+{
+ XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER
+};
+
+enum ScXMLSubTotalRuleSubTotalField
+{
+ XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER,
+ XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION
+};
+
+enum ScXMLDataPilotTablesElemTokens
+{
+ XML_TOK_DATA_PILOT_TABLE
+};
+
+enum ScXMLDataPilotTableAttrTokens
+{
+ XML_TOK_DATA_PILOT_TABLE_ATTR_NAME,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN
+};
+
+enum ScXMLDataPilotTableElemTokens
+{
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD
+};
+
+enum ScXMLDataPilotTableSourceServiceAttrTokens
+{
+ XML_TOK_SOURCE_SERVICE_ATTR_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD
+};
+
+enum ScXMLDataPilotGrandTotalAttrTokens
+{
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT
+};
+
+enum ScXMLDataPilotTableSourceCellRangeElemTokens
+{
+ XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER
+};
+
+enum ScXMLDataPilotTableSourceCellRangeAttrTokens
+{
+ XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS
+};
+
+enum ScXMLDataPilotFieldAttrTokens
+{
+ XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY
+};
+
+enum ScXMLDataPilotFieldElemTokens
+{
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS
+};
+
+enum ScXMLDataPilotLevelAttrTokens
+{
+ XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY
+};
+
+enum ScXMLDataPilotLevelElemTokens
+{
+ XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS,
+ XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO
+};
+
+enum ScXMLDataPilotSubTotalsElemTokens
+{
+ XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL
+};
+
+enum ScXMLDataPilotSubTotalAttrTokens
+{
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT
+};
+
+enum ScXMLDataPilotMembersElemTokens
+{
+ XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER
+};
+
+enum ScXMLDataPilotMemberAttrTokens
+{
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS
+};
+
+enum ScXMLConsolidationAttrTokens
+{
+ XML_TOK_CONSOLIDATION_ATTR_FUNCTION,
+ XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES,
+ XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS,
+ XML_TOK_CONSOLIDATION_ATTR_USE_LABEL,
+ XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE
+};
+
+
+class SvI18NMap;
+class SvXMLTokenMap;
+//class SvXMLImportItemMapper;
+class SvXMLStyleContext;
+class SfxItemSet;
+class SvXMLNumFmtHelper;
+class XMLShapeImportHelper;
+class ScXMLChangeTrackingImportHelper;
+class ScUnoGuard;
+
+struct tScMyCellRange
+{
+ sal_Int16 Sheet;
+ sal_Int32 StartColumn, EndColumn;
+ sal_Int32 StartRow, EndRow;
+};
+
+struct ScMyNamedExpression
+{
+ rtl::OUString sName;
+ rtl::OUString sContent;
+ rtl::OUString sContentNmsp;
+ rtl::OUString sBaseCellAddress;
+ rtl::OUString sRangeType;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_Bool bIsExpression;
+};
+
+typedef std::list<const ScMyNamedExpression*> ScMyNamedExpressions;
+
+struct ScMyLabelRange
+{
+ rtl::OUString sLabelRangeStr;
+ rtl::OUString sDataRangeStr;
+ sal_Bool bColumnOrientation;
+};
+
+typedef std::list<const ScMyLabelRange*> ScMyLabelRanges;
+
+struct ScMyImportValidation
+{
+ rtl::OUString sName;
+ rtl::OUString sImputTitle;
+ rtl::OUString sImputMessage;
+ rtl::OUString sErrorTitle;
+ rtl::OUString sErrorMessage;
+ rtl::OUString sFormula1;
+ rtl::OUString sFormula2;
+ rtl::OUString sFormulaNmsp1;
+ rtl::OUString sFormulaNmsp2;
+ rtl::OUString sBaseCellAddress; // #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 eGrammar1;
+ formula::FormulaGrammar::Grammar eGrammar2;
+ sal_Int16 nShowList;
+ sal_Bool bShowErrorMessage;
+ sal_Bool bShowImputMessage;
+ sal_Bool bIgnoreBlanks;
+};
+
+typedef std::vector<ScMyImportValidation> ScMyImportValidations;
+typedef std::list<SvXMLImportContext*> ScMyViewContextList;
+class ScMyStylesImportHelper;
+
+class ScXMLImport: public SvXMLImport
+{
+ typedef ::std::hash_map< ::rtl::OUString, sal_Int16, ::rtl::OUStringHash > CellTypeMap;
+ CellTypeMap aCellTypeMap;
+
+ ScDocument* pDoc;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScMyViewContextList aViewContextList;
+ ScMyStylesImportHelper* pStylesImportHelper;
+ rtl::OUString sNumberFormat;
+ rtl::OUString sLocale;
+ rtl::OUString sCellStyle;
+ rtl::OUString sStandardFormat;
+ rtl::OUString sType;
+
+// SvXMLAutoStylePoolP *pScAutoStylePool;
+ UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory;
+ UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xRowStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xTableStylesPropertySetMapper;
+// SvXMLImportContextRef xStyles;
+// SvXMLImportContextRef xAutoStyles;
+
+// SvXMLImportItemMapper *pParaItemMapper;// paragraph item import
+// SvI18NMap *pI18NMap; // name mapping for I18N
+ SvXMLTokenMap *pDocElemTokenMap;
+ SvXMLTokenMap *pStylesElemTokenMap;
+ SvXMLTokenMap *pStylesAttrTokenMap;
+ SvXMLTokenMap *pStyleElemTokenMap;
+ SvXMLTokenMap *pBodyElemTokenMap;
+ SvXMLTokenMap *pContentValidationsElemTokenMap;
+ SvXMLTokenMap *pContentValidationElemTokenMap;
+ SvXMLTokenMap *pContentValidationAttrTokenMap;
+ SvXMLTokenMap *pContentValidationMessageElemTokenMap;
+ SvXMLTokenMap *pContentValidationHelpMessageAttrTokenMap;
+ SvXMLTokenMap *pContentValidationErrorMessageAttrTokenMap;
+ SvXMLTokenMap *pContentValidationErrorMacroAttrTokenMap;
+ SvXMLTokenMap *pLabelRangesElemTokenMap;
+ SvXMLTokenMap *pLabelRangeAttrTokenMap;
+ SvXMLTokenMap *pTableElemTokenMap;
+ SvXMLTokenMap *pTableRowsElemTokenMap;
+ SvXMLTokenMap *pTableColsElemTokenMap;
+ SvXMLTokenMap *pTableScenarioAttrTokenMap;
+ SvXMLTokenMap *pTableAttrTokenMap;
+ SvXMLTokenMap *pTableColAttrTokenMap;
+ SvXMLTokenMap *pTableRowElemTokenMap;
+ SvXMLTokenMap *pTableRowAttrTokenMap;
+ SvXMLTokenMap *pTableRowCellElemTokenMap;
+ SvXMLTokenMap *pTableRowCellAttrTokenMap;
+ SvXMLTokenMap *pTableAnnotationAttrTokenMap;
+ SvXMLTokenMap *pDetectiveElemTokenMap;
+ SvXMLTokenMap *pDetectiveHighlightedAttrTokenMap;
+ SvXMLTokenMap *pDetectiveOperationAttrTokenMap;
+ SvXMLTokenMap *pTableCellRangeSourceAttrTokenMap;
+ SvXMLTokenMap *pNamedExpressionsElemTokenMap;
+ SvXMLTokenMap *pNamedRangeAttrTokenMap;
+ SvXMLTokenMap *pNamedExpressionAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangesElemTokenMap;
+ SvXMLTokenMap *pDatabaseRangeElemTokenMap;
+ SvXMLTokenMap *pDatabaseRangeAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSourceSQLAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSourceTableAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSourceQueryAttrTokenMap;
+ SvXMLTokenMap *pFilterElemTokenMap;
+ SvXMLTokenMap *pFilterAttrTokenMap;
+ SvXMLTokenMap *pFilterConditionAttrTokenMap;
+ SvXMLTokenMap *pSortElemTokenMap;
+ SvXMLTokenMap *pSortAttrTokenMap;
+ SvXMLTokenMap *pSortSortByAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSubTotalRulesElemTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSubTotalRulesAttrTokenMap;
+ SvXMLTokenMap *pSubTotalRulesSortGroupsAttrTokenMap;
+ SvXMLTokenMap *pSubTotalRulesSubTotalRuleElemTokenMap;
+ SvXMLTokenMap *pSubTotalRulesSubTotalRuleAttrTokenMap;
+ SvXMLTokenMap *pSubTotalRuleSubTotalFieldAttrTokenMap;
+ SvXMLTokenMap *pDataPilotTablesElemTokenMap;
+ SvXMLTokenMap *pDataPilotTableAttrTokenMap;
+ SvXMLTokenMap *pDataPilotTableElemTokenMap;
+ SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap;
+ SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap;
+ SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap;
+ SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap;
+ SvXMLTokenMap *pDataPilotFieldAttrTokenMap;
+ SvXMLTokenMap *pDataPilotFieldElemTokenMap;
+ SvXMLTokenMap *pDataPilotLevelAttrTokenMap;
+ SvXMLTokenMap *pDataPilotLevelElemTokenMap;
+ SvXMLTokenMap *pDataPilotSubTotalsElemTokenMap;
+ SvXMLTokenMap *pDataPilotSubTotalAttrTokenMap;
+ SvXMLTokenMap *pDataPilotMembersElemTokenMap;
+ SvXMLTokenMap *pDataPilotMemberAttrTokenMap;
+ SvXMLTokenMap *pConsolidationAttrTokenMap;
+
+ ScMyTables aTables;
+
+ ScMyNamedExpressions* pMyNamedExpressions;
+ ScMyLabelRanges* pMyLabelRanges;
+ ScMyImportValidations* pValidations;
+ ScMyImpDetectiveOpArray* pDetectiveOpArray;
+ ScUnoGuard* pScUnoGuard;
+
+ std::vector<rtl::OUString> aTableStyles;
+ XMLNumberFormatAttributesExportHelper* pNumberFormatAttributesExportHelper;
+ ScMyStyleNumberFormats* pStyleNumberFormats;
+ com::sun::star::uno::Reference <com::sun::star::util::XNumberFormats> xNumberFormats;
+ com::sun::star::uno::Reference <com::sun::star::util::XNumberFormatTypes> xNumberFormatTypes;
+
+ com::sun::star::uno::Reference <com::sun::star::sheet::XSheetCellRangeContainer> xSheetCellRanges;
+
+ rtl::OUString sEmpty;
+ rtl::OUString sPrevStyleName;
+ rtl::OUString sPrevCurrency;
+ sal_uInt32 nSolarMutexLocked;
+ sal_Int32 nProgressCount;
+ sal_uInt16 nStyleFamilyMask;// Mask of styles to load
+ sal_Int16 nPrevCellType;
+ sal_Bool bLoadDoc; // Load doc or styles only
+ sal_Bool bRemoveLastChar;
+ sal_Bool bNullDateSetted;
+ sal_Bool bSelfImportingXMLSet;
+ sal_Bool bLatinDefaultStyle; // latin-only number format in default style?
+ sal_Bool bFromWrapper; // called from ScDocShell / ScXMLImportWrapper?
+
+
+protected:
+
+ // This method is called after the namespace map has been updated, but
+ // before a context for the current element has been pushed.
+ virtual SvXMLImportContext *CreateContext(USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual XMLShapeImportHelper* CreateShapeImport();
+
+public:
+ // #110680#
+ ScXMLImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nImportFlag);
+
+ ~ScXMLImport() throw();
+
+ // namespace office
+ // NB: in contrast to other CreateFooContexts, this particular one handles
+ // the root element (i.e. office:document-meta)
+ SvXMLImportContext *CreateMetaContext(
+ const ::rtl::OUString& rLocalName );
+ SvXMLImportContext *CreateFontDeclsContext(const USHORT nPrefix, const ::rtl::OUString& rLocalName,
+ const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList);
+ SvXMLImportContext *CreateScriptContext(
+ const ::rtl::OUString& rLocalName );
+ SvXMLImportContext *CreateStylesContext(const ::rtl::OUString& rLocalName,
+ const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList, sal_Bool bAutoStyles );
+// SvXMLImportContext *CreateUseStylesContext(const ::rtl::OUString& rLocalName ,
+// const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList);
+ SvXMLImportContext *CreateBodyContext(
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void SetStatistics(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue> & i_rStats);
+
+ inline ScDocument* GetDocument() { return pDoc; }
+ inline const ScDocument* GetDocument() const { return pDoc; }
+
+ ScMyTables& GetTables() { return aTables; }
+
+ sal_uInt16 GetStyleFamilyMask() const { return nStyleFamilyMask; }
+ sal_Bool IsStylesOnlyMode() const { return !bLoadDoc; }
+
+ sal_Bool IsLatinDefaultStyle() const { return bLatinDefaultStyle; }
+
+ sal_Int16 GetCellType(const ::rtl::OUString& rStrValue) const;
+
+// SvI18NMap& GetI18NMap() { return *pI18NMap; }
+
+// inline const SvXMLImportItemMapper& GetParaItemMapper() const;
+// SvXMLImportContext *CreateParaItemImportContext( USHORT nPrefix,
+// const ::rtl::OUString& rLocalName,
+// const ::com::sun::star::uno::Reference<
+// ::com::sun::star::xml::sax::XAttributeList& xAttrList,
+// SfxItemSet& rItemSet );
+
+ UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() const { return xCellStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetColumnStylesPropertySetMapper() const { return xColumnStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetRowStylesPropertySetMapper() const { return xRowStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() const { return xTableStylesPropertySetMapper; }
+// SvXMLImportContextRef GetAutoStyles() const { return xAutoStyles; }
+// SvXMLImportContextRef GetStyles() const { return xStyles; }
+
+ const SvXMLTokenMap& GetDocElemTokenMap();
+//UNUSED2008-05 const SvXMLTokenMap& GetStylesElemTokenMap();
+//UNUSED2008-05 const SvXMLTokenMap& GetStylesAttrTokenMap();
+//UNUSED2008-05 const SvXMLTokenMap& GetStyleElemTokenMap();
+ const SvXMLTokenMap& GetBodyElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationsElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationAttrTokenMap();
+ const SvXMLTokenMap& GetContentValidationMessageElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationHelpMessageAttrTokenMap();
+ const SvXMLTokenMap& GetContentValidationErrorMessageAttrTokenMap();
+ const SvXMLTokenMap& GetContentValidationErrorMacroAttrTokenMap();
+ const SvXMLTokenMap& GetLabelRangesElemTokenMap();
+ const SvXMLTokenMap& GetLabelRangeAttrTokenMap();
+ const SvXMLTokenMap& GetTableElemTokenMap();
+ const SvXMLTokenMap& GetTableRowsElemTokenMap();
+ const SvXMLTokenMap& GetTableColsElemTokenMap();
+ const SvXMLTokenMap& GetTableAttrTokenMap();
+ const SvXMLTokenMap& GetTableScenarioAttrTokenMap();
+ const SvXMLTokenMap& GetTableColAttrTokenMap();
+ const SvXMLTokenMap& GetTableRowElemTokenMap();
+ const SvXMLTokenMap& GetTableRowAttrTokenMap();
+ const SvXMLTokenMap& GetTableRowCellElemTokenMap();
+ const SvXMLTokenMap& GetTableRowCellAttrTokenMap();
+ const SvXMLTokenMap& GetTableAnnotationAttrTokenMap();
+ const SvXMLTokenMap& GetDetectiveElemTokenMap();
+ const SvXMLTokenMap& GetDetectiveHighlightedAttrTokenMap();
+ const SvXMLTokenMap& GetDetectiveOperationAttrTokenMap();
+ const SvXMLTokenMap& GetTableCellRangeSourceAttrTokenMap();
+ const SvXMLTokenMap& GetNamedExpressionsElemTokenMap();
+ const SvXMLTokenMap& GetNamedRangeAttrTokenMap();
+ const SvXMLTokenMap& GetNamedExpressionAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangesElemTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeElemTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSourceSQLAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSourceTableAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSourceQueryAttrTokenMap();
+ const SvXMLTokenMap& GetFilterElemTokenMap();
+ const SvXMLTokenMap& GetFilterAttrTokenMap();
+ const SvXMLTokenMap& GetFilterConditionAttrTokenMap();
+ const SvXMLTokenMap& GetSortElemTokenMap();
+ const SvXMLTokenMap& GetSortAttrTokenMap();
+ const SvXMLTokenMap& GetSortSortByAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSubTotalRulesElemTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSubTotalRulesAttrTokenMap();
+ const SvXMLTokenMap& GetSubTotalRulesSortGroupsAttrTokenMap();
+ const SvXMLTokenMap& GetSubTotalRulesSubTotalRuleElemTokenMap();
+ const SvXMLTokenMap& GetSubTotalRulesSubTotalRuleAttrTokenMap();
+ const SvXMLTokenMap& GetSubTotalRuleSubTotalFieldAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotTablesElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotFieldElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotLevelAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotLevelElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotSubTotalsElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotSubTotalAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotMembersElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotMemberAttrTokenMap();
+ const SvXMLTokenMap& GetConsolidationAttrTokenMap();
+// const SvXMLTokenMap& GetTextPElemTokenMap();
+// const SvXMLTokenMap& GetTextPAttrTokenMap();
+// const SvXMLTokenMap& GetStyleStylesElemTokenMap();
+// const SvXMLTokenMap& GetTextListBlockAttrTokenMap();
+// const SvXMLTokenMap& GetTextListBlockElemTokenMap();
+
+ void AddNamedExpression(const ScMyNamedExpression* pMyNamedExpression) {
+ if (!pMyNamedExpressions)
+ pMyNamedExpressions = new ScMyNamedExpressions();
+ pMyNamedExpressions->push_back(pMyNamedExpression); }
+ ScMyNamedExpressions* GetNamedExpressions() { return pMyNamedExpressions; }
+
+ void AddLabelRange(const ScMyLabelRange* pMyLabelRange) {
+ if (!pMyLabelRanges)
+ pMyLabelRanges = new ScMyLabelRanges();
+ pMyLabelRanges->push_back(pMyLabelRange); }
+ ScMyLabelRanges* GetLabelRanges() { return pMyLabelRanges; }
+
+ void AddValidation(const ScMyImportValidation& rValidation) {
+ if (!pValidations)
+ pValidations = new ScMyImportValidations();
+ pValidations->push_back(rValidation); }
+ sal_Bool GetValidation(const rtl::OUString& sName, ScMyImportValidation& aValidation);
+
+ inline ScMyImpDetectiveOpArray* GetDetectiveOpArray() {
+ if (!pDetectiveOpArray)
+ pDetectiveOpArray = new ScMyImpDetectiveOpArray();
+ return pDetectiveOpArray; }
+
+ void SetRemoveLastChar(sal_Bool bValue) { bRemoveLastChar = bValue; }
+ sal_Bool GetRemoveLastChar() { return bRemoveLastChar; }
+
+ ScXMLChangeTrackingImportHelper* GetChangeTrackingImportHelper();
+ void AddViewContext(SvXMLImportContext* pContext) { aViewContextList.push_back(pContext); }
+ void InsertStyles();
+
+ void SetChangeTrackingViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rChangeProps);
+ virtual void SetViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aViewProps);
+ virtual void SetConfigurationSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aConfigProps);
+
+ void SetTableStyle(const rtl::OUString& rValue) { aTableStyles.push_back(rValue); }
+ std::vector<rtl::OUString> GetTableStyle() { return aTableStyles; }
+ ScMyStylesImportHelper* GetStylesImportHelper() { return pStylesImportHelper; }
+ sal_Int32 SetCurrencySymbol(const sal_Int32 nKey, const rtl::OUString& rCurrency);
+ sal_Bool IsCurrencySymbol(const sal_Int32 nNumberFormat, const rtl::OUString& sCurrencySymbol, const rtl::OUString& sBankSymbol);
+ void SetType(com::sun::star::uno::Reference <com::sun::star::beans::XPropertySet>& rProperties,
+ sal_Int32& rNumberFormat,
+ const sal_Int16 nCellType,
+ const rtl::OUString& rCurrency);
+
+ void ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc = 1);
+
+private:
+ void AddStyleRange(const com::sun::star::table::CellRangeAddress& rCellRange);
+ void SetStyleToRanges();
+
+ void ExamineDefaultStyle();
+public:
+ void SetStyleToRange(const ScRange& rRange, const rtl::OUString* pStyleName,
+ const sal_Int16 nCellType, const rtl::OUString* pCurrency);
+ sal_Bool SetNullDateOnUnitConverter();
+ XMLNumberFormatAttributesExportHelper* GetNumberFormatAttributesExportHelper();
+ ScMyStyleNumberFormats* GetStyleNumberFormats();
+
+ void SetStylesToRangesFinished();
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::xml::sax::XDocumentHandler
+ virtual void SAL_CALL startDocument(void)
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL endDocument(void)
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ virtual void DisposingModel();
+
+ void LockSolarMutex();
+ void UnlockSolarMutex();
+
+ sal_Int32 GetByteOffset();
+
+ void SetRangeOverflowType(sal_uInt32 nType);
+
+ sal_Int32 GetRangeType(const rtl::OUString sRangeType) const;
+ void SetNamedRanges();
+ void SetLabelRanges();
+ void AddDefaultNote( const com::sun::star::table::CellAddress& aCell );
+
+ sal_Int32 GetVisibleSheet();
+ /** Extracts the formula string, the formula grammar namespace URL, and a
+ grammar enum value from the passed formula attribute value.
+
+ @param rFormula
+ (out-parameter) Returns the plain formula string with the leading
+ equality sign if existing.
+
+ @param rFormulaNmsp
+ (out-parameter) Returns the URL of the formula grammar namespace if
+ the attribute value contains the prefix of an unknown namespace.
+
+ @param reGrammar
+ (out-parameter) Returns the exact formula grammar if the formula
+ is in a supported ODF format (e.g. FormulaGrammar::GRAM_PODF for
+ ODF 1.0/1.1 formulas, or FormulaGrammar::GRAM_ODFF for ODF 1.2
+ formulas a.k.a. OpenFormula). Returns the default storage grammar,
+ if the attribute value does not contain a namespace prefix. Returns
+ the special value FormulaGrammar::GRAM_EXTERNAL, if an unknown
+ namespace could be extracted from the formula which will be
+ contained in the parameter rFormulaNmsp then.
+
+ @param rAttrValue
+ The value of the processed formula attribute.
+
+ @param bRestrictToExternalNmsp
+ If set to TRUE, only namespaces of external formula grammars will
+ be recognized. Internal namespace prefixes (e.g. 'oooc:' or 'of:'
+ will be considered to be part of the formula, e.g. an expression
+ with range operator.
+ */
+ void ExtractFormulaNamespaceGrammar(
+ ::rtl::OUString& rFormula,
+ ::rtl::OUString& rFormulaNmsp,
+ ::formula::FormulaGrammar::Grammar& reGrammar,
+ const ::rtl::OUString& rAttrValue,
+ bool bRestrictToExternalNmsp = false ) const;
+};
+
+#endif
+
diff --git a/sc/source/filter/xml/xmllabri.cxx b/sc/source/filter/xml/xmllabri.cxx
new file mode 100644
index 000000000000..70ec803cc46f
--- /dev/null
+++ b/sc/source/filter/xml/xmllabri.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//___________________________________________________________________
+#include "xmllabri.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include "xmlimprt.hxx"
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScXMLLabelRangesContext::ScXMLLabelRangesContext(
+ ScXMLImport& rImport,
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ ):
+ SvXMLImportContext( rImport, nPrefix, rLName )
+{
+ rImport.LockSolarMutex();
+}
+
+ScXMLLabelRangesContext::~ScXMLLabelRangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext* ScXMLLabelRangesContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList )
+{
+ SvXMLImportContext* pContext(NULL);
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetLabelRangesElemTokenMap());
+
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_LABEL_RANGE_ELEM:
+ pContext = new ScXMLLabelRangeContext( GetScImport(), nPrefix, rLName, xAttrList );
+ break;
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLLabelRangesContext::EndElement()
+{
+}
+
+
+//___________________________________________________________________
+
+ScXMLLabelRangeContext::ScXMLLabelRangeContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ bColumnOrientation( sal_False )
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetLabelRangeAttrTokenMap());
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ USHORT nPrefix (GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE:
+ sLabelRangeStr = sValue;
+ break;
+ case XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE:
+ sDataRangeStr = sValue;
+ break;
+ case XML_TOK_LABEL_RANGE_ATTR_ORIENTATION:
+ bColumnOrientation = IsXMLToken(sValue, XML_COLUMN );
+ break;
+ }
+ }
+}
+
+ScXMLLabelRangeContext::~ScXMLLabelRangeContext()
+{
+}
+
+SvXMLImportContext* ScXMLLabelRangeContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLLabelRangeContext::EndElement()
+{
+ // #b5071088# Label ranges must be stored as strings until all sheets are loaded
+ // (like named expressions).
+
+ ScMyLabelRange* pLabelRange = new ScMyLabelRange;
+
+ pLabelRange->sLabelRangeStr = sLabelRangeStr;
+ pLabelRange->sDataRangeStr = sDataRangeStr;
+ pLabelRange->bColumnOrientation = bColumnOrientation;
+
+ GetScImport().AddLabelRange(pLabelRange);
+}
+
diff --git a/sc/source/filter/xml/xmllabri.hxx b/sc/source/filter/xml/xmllabri.hxx
new file mode 100644
index 000000000000..c3cbd6532c90
--- /dev/null
+++ b/sc/source/filter/xml/xmllabri.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLLABRI_HXX
+#define SC_XMLLABRI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+class ScXMLLabelRangesContext : public SvXMLImportContext
+{
+private:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLLabelRangesContext(
+ ScXMLImport& rImport,
+ USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual ~ScXMLLabelRangesContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLLabelRangeContext : public SvXMLImportContext
+{
+private:
+ ::rtl::OUString sLabelRangeStr;
+ ::rtl::OUString sDataRangeStr;
+ sal_Bool bColumnOrientation;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLLabelRangeContext(
+ ScXMLImport& rImport,
+ USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual ~ScXMLLabelRangeContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlnexpi.cxx b/sc/source/filter/xml/xmlnexpi.cxx
new file mode 100644
index 000000000000..3ef17c321f23
--- /dev/null
+++ b/sc/source/filter/xml/xmlnexpi.cxx
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <rtl/ustrbuf.hxx>
+
+#include "xmlnexpi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlcelli.hxx"
+#include "docuno.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "XMLConverter.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+ScXMLNamedExpressionsContext::ScXMLNamedExpressionsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+/* sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetNamedRangeAttrTokenMap();
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ }
+ }*/
+ rImport.LockSolarMutex();
+}
+
+ScXMLNamedExpressionsContext::~ScXMLNamedExpressionsContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLNamedExpressionsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetNamedExpressionsElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE:
+ pContext = new ScXMLNamedRangeContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ case XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION:
+ pContext = new ScXMLNamedExpressionContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLNamedExpressionsContext::EndElement()
+{
+ // happends in ScXMLImport::EndDocument()
+ // because it has to be set after the Database Ranges
+}
+
+ScXMLNamedRangeContext::ScXMLNamedRangeContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression);
+ // A simple table:cell-range-address is not a formula expression, stored
+ // without [] brackets but with dot, .A1
+ pNamedExpression->eGrammar = formula::FormulaGrammar::mergeToGrammar(
+ GetScImport().GetDocument()->GetStorageGrammar(),
+ formula::FormulaGrammar::CONV_OOO);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetNamedRangeAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_NAMED_RANGE_ATTR_NAME :
+ {
+ pNamedExpression->sName = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS :
+ {
+ pNamedExpression->sContent = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS :
+ {
+ pNamedExpression->sBaseCellAddress = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS :
+ {
+ pNamedExpression->sRangeType = sValue;
+ }
+ break;
+ }
+ }
+ pNamedExpression->bIsExpression = sal_False;
+ GetScImport().AddNamedExpression(pNamedExpression);
+}
+
+ScXMLNamedRangeContext::~ScXMLNamedRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLNamedRangeContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+/* const SvXMLTokenMap& rTokenMap = GetScImport().GetTableElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ }*/
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLNamedRangeContext::EndElement()
+{
+}
+
+ScXMLNamedExpressionContext::ScXMLNamedExpressionContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetNamedExpressionAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_NAMED_EXPRESSION_ATTR_NAME :
+ {
+ pNamedExpression->sName = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION :
+ {
+ GetScImport().ExtractFormulaNamespaceGrammar(
+ pNamedExpression->sContent, pNamedExpression->sContentNmsp,
+ pNamedExpression->eGrammar, sValue );
+ }
+ break;
+ case XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS :
+ {
+ pNamedExpression->sBaseCellAddress = sValue;
+ }
+ break;
+ }
+ }
+ pNamedExpression->bIsExpression = sal_True;
+ GetScImport().AddNamedExpression(pNamedExpression);
+}
+
+ScXMLNamedExpressionContext::~ScXMLNamedExpressionContext()
+{
+}
+
+SvXMLImportContext *ScXMLNamedExpressionContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+/* const SvXMLTokenMap& rTokenMap = GetScImport().GetTableElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ }*/
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );;
+}
+
+void ScXMLNamedExpressionContext::EndElement()
+{
+}
+
diff --git a/sc/source/filter/xml/xmlnexpi.hxx b/sc/source/filter/xml/xmlnexpi.hxx
new file mode 100644
index 000000000000..94d0b2738d52
--- /dev/null
+++ b/sc/source/filter/xml/xmlnexpi.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLNEXPI_HXX
+#define SC_XMLNEXPI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+class ScXMLNamedExpressionsContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLNamedExpressionsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLNamedExpressionsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLNamedRangeContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLNamedRangeContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLNamedRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLNamedExpressionContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLNamedExpressionContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLNamedExpressionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlrowi.cxx b/sc/source/filter/xml/xmlrowi.cxx
new file mode 100644
index 000000000000..a2ce08890c30
--- /dev/null
+++ b/sc/source/filter/xml/xmlrowi.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlrowi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlcelli.hxx"
+#include "global.hxx"
+#include "xmlstyli.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "olinetab.hxx"
+#include "sheetdata.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+
+#include <com/sun/star/table/CellAddress.hpp>
+
+#define SC_ISVISIBLE "IsVisible"
+#define SC_OPTIMALHEIGHT "OptimalHeight"
+#define SC_ISFILTERED "IsFiltered"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableRowContext::ScXMLTableRowContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sVisibility(GetXMLToken(XML_VISIBLE)),
+ nRepeatedRows(1),
+ bHasCell(sal_False)
+{
+ rtl::OUString sCellStyleName;
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableRowAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_ROW_ATTR_STYLE_NAME:
+ {
+ sStyleName = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ROW_ATTR_VISIBILITY:
+ {
+ sVisibility = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ROW_ATTR_REPEATED:
+ {
+ nRepeatedRows = std::max( sValue.toInt32(), (sal_Int32) 1 );
+ }
+ break;
+ case XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME:
+ {
+ sCellStyleName = sValue;
+ }
+ break;
+ /*case XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT:
+ {
+ sOptimalHeight = sValue;
+ }
+ break;*/
+ }
+ }
+ GetScImport().GetTables().AddRow();
+ GetScImport().GetTables().SetRowStyle(sCellStyleName);
+}
+
+ScXMLTableRowContext::~ScXMLTableRowContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableRowContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROW_CELL:
+// if( IsInsertCellPossible() )
+ {
+ bHasCell = sal_True;
+ pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
+ rLName, xAttrList, sal_False, nRepeatedRows
+ //this
+ );
+ }
+ break;
+ case XML_TOK_TABLE_ROW_COVERED_CELL:
+// if( IsInsertCellPossible() )
+ {
+ bHasCell = sal_True;
+ pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
+ rLName, xAttrList, sal_True, nRepeatedRows
+ //this
+ );
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableRowContext::EndElement()
+{
+ ScXMLImport& rXMLImport(GetScImport());
+ if (!bHasCell && nRepeatedRows > 1)
+ {
+ for (sal_Int32 i = 0; i < nRepeatedRows - 1; ++i) //one row is always added
+ GetScImport().GetTables().AddRow();
+ DBG_ERRORFILE("it seems here is a nonvalid file; possible missing of table:table-cell element");
+ }
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ sal_Int32 nCurrentRow(rXMLImport.GetTables().GetCurrentRow());
+ uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if(xSheet.is())
+ {
+ sal_Int32 nFirstRow(nCurrentRow - nRepeatedRows + 1);
+ if (nFirstRow > MAXROW)
+ nFirstRow = MAXROW;
+ if (nCurrentRow > MAXROW)
+ nCurrentRow = MAXROW;
+ uno::Reference <table::XCellRange> xCellRange(xSheet->getCellRangeByPosition(0, nFirstRow, 0, nCurrentRow));
+ if (xCellRange.is())
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xCellRange, uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xRowProperties(xColumnRowRange->getRows(), uno::UNO_QUERY);
+ if (xRowProperties.is())
+ {
+ if (sStyleName.getLength())
+ {
+ XMLTableStylesContext *pStyles((XMLTableStylesContext *)rXMLImport.GetAutoStyles());
+ if ( pStyles )
+ {
+ XMLTableStyleContext* pStyle((XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_ROW, sStyleName, sal_True));
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xRowProperties);
+
+ if ( nSheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddRowStyle( sStyleName, ScAddress( 0, (SCROW)nFirstRow, (SCTAB)nSheet ) );
+ pStyle->SetLastSheet(nSheet);
+ }
+ }
+ }
+ }
+ sal_Bool bVisible (sal_True);
+ sal_Bool bFiltered (sal_False);
+ if (IsXMLToken(sVisibility, XML_COLLAPSE))
+ {
+ bVisible = sal_False;
+ }
+ else if (IsXMLToken(sVisibility, XML_FILTER))
+ {
+ bVisible = sal_False;
+ bFiltered = sal_True;
+ }
+
+ // #i116164# call SetRowHidden/SetRowFiltered directly, so the tree doesn't have to be rebuilt
+ // to compare with existing hidden flags.
+ if (!bVisible && pDoc)
+ pDoc->SetRowHidden((SCROW)nFirstRow, (SCROW)nCurrentRow, (SCTAB)nSheet, true);
+ if (bFiltered && pDoc)
+ pDoc->SetRowFiltered((SCROW)nFirstRow, (SCROW)nCurrentRow, (SCTAB)nSheet, true);
+
+ //if (!bVisible)
+ // xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISVISIBLE)), uno::makeAny(bVisible));
+ //if (bFiltered)
+ // xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISFILTERED)), uno::makeAny(bFiltered));
+ }
+ }
+ }
+ }
+}
+
+ScXMLTableRowsContext::ScXMLTableRowsContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempHeader, const sal_Bool bTempGroup ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ nHeaderStartRow(0),
+ nHeaderEndRow(0),
+ nGroupStartRow(0),
+ nGroupEndRow(0),
+ bHeader(bTempHeader),
+ bGroup(bTempGroup),
+ bGroupDisplay(sal_True)
+{
+ // don't have any attributes
+ if (bHeader)
+ {
+ nHeaderStartRow = rImport.GetTables().GetCurrentRow();
+ ++nHeaderStartRow;
+ }
+ else if (bGroup)
+ {
+ nGroupStartRow = rImport.GetTables().GetCurrentRow();
+ ++nGroupStartRow;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_DISPLAY))
+ bGroupDisplay = IsXMLToken(sValue, XML_TRUE);
+ }
+ }
+}
+
+ScXMLTableRowsContext::~ScXMLTableRowsContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableRowsContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowsElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROWS_ROW_GROUP:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_True );
+ break;
+ case XML_TOK_TABLE_ROWS_HEADER_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, sal_False );
+ break;
+ case XML_TOK_TABLE_ROWS_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_False );
+ break;
+ case XML_TOK_TABLE_ROWS_ROW:
+ pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableRowsContext::EndElement()
+{
+ ScXMLImport& rXMLImport(GetScImport());
+ if (bHeader)
+ {
+ nHeaderEndRow = rXMLImport.GetTables().GetCurrentRow();
+ if (nHeaderStartRow <= nHeaderEndRow)
+ {
+ uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
+ if (xPrintAreas.is())
+ {
+ if (!xPrintAreas->getPrintTitleRows())
+ {
+ xPrintAreas->setPrintTitleRows(sal_True);
+ table::CellRangeAddress aRowHeaderRange;
+ aRowHeaderRange.StartRow = nHeaderStartRow;
+ aRowHeaderRange.EndRow = nHeaderEndRow;
+ xPrintAreas->setTitleRows(aRowHeaderRange);
+ }
+ else
+ {
+ table::CellRangeAddress aRowHeaderRange(xPrintAreas->getTitleRows());
+ aRowHeaderRange.EndRow = nHeaderEndRow;
+ xPrintAreas->setTitleRows(aRowHeaderRange);
+ }
+ }
+ }
+ }
+ else if (bGroup)
+ {
+ nGroupEndRow = rXMLImport.GetTables().GetCurrentRow();
+ sal_Int32 nSheet(rXMLImport.GetTables().GetCurrentSheet());
+ if (nGroupStartRow <= nGroupEndRow)
+ {
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (pDoc)
+ {
+ GetScImport().LockSolarMutex();
+ ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(nSheet), sal_True));
+ ScOutlineArray* pRowArray(pOutlineTable->GetRowArray());
+ sal_Bool bResized;
+ pRowArray->Insert(static_cast<SCROW>(nGroupStartRow), static_cast<SCROW>(nGroupEndRow), bResized, !bGroupDisplay, sal_True);
+ GetScImport().UnlockSolarMutex();
+ }
+ }
+ }
+}
diff --git a/sc/source/filter/xml/xmlrowi.hxx b/sc/source/filter/xml/xmlrowi.hxx
new file mode 100644
index 000000000000..558555b233e3
--- /dev/null
+++ b/sc/source/filter/xml/xmlrowi.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLROWI_HXX
+#define SC_XMLROWI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+class ScXMLTableRowContext : public SvXMLImportContext
+{
+ rtl::OUString sStyleName;
+ rtl::OUString sVisibility;
+ sal_Int32 nRepeatedRows;
+ sal_Bool bHasCell;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableRowContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableRowContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLTableRowsContext : public SvXMLImportContext
+{
+ sal_Int32 nHeaderStartRow;
+ sal_Int32 nHeaderEndRow;
+ sal_Int32 nGroupStartRow;
+ sal_Int32 nGroupEndRow;
+ sal_Bool bHeader;
+ sal_Bool bGroup;
+ sal_Bool bGroupDisplay;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableRowsContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bHeader, const sal_Bool bGroup);
+
+ virtual ~ScXMLTableRowsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlsceni.cxx b/sc/source/filter/xml/xmlsceni.cxx
new file mode 100644
index 000000000000..652dd0a1dd43
--- /dev/null
+++ b/sc/source/filter/xml/xmlsceni.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "document.hxx"
+#include "xmlimprt.hxx"
+#include "xmlsceni.hxx"
+#include "docuno.hxx"
+#include "attrib.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLTableScenarioContext::ScXMLTableScenarioContext(
+ ScXMLImport& rImport,
+ USHORT nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ):
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aBorderColor( COL_BLACK ),
+ bDisplayBorder( sal_True ),
+ bCopyBack( sal_True ),
+ bCopyStyles( sal_True ),
+ bCopyFormulas( sal_True ),
+ bIsActive( sal_False ),
+ bProtected( sal_False )
+{
+ rImport.LockSolarMutex();
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableScenarioAttrTokenMap());
+ for( sal_Int16 i = 0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER:
+ {
+ bDisplayBorder = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR:
+ {
+ SvXMLUnitConverter::convertColor(aBorderColor, sValue);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK:
+ {
+ bCopyBack = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES:
+ {
+ bCopyStyles = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS:
+ {
+ bCopyFormulas = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE:
+ {
+ bIsActive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES:
+ {
+ ScRangeStringConverter::GetRangeListFromString(
+ aScenarioRanges, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO );
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COMMENT:
+ {
+ sComment = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED:
+ {
+ bProtected = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLTableScenarioContext::~ScXMLTableScenarioContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLTableScenarioContext::CreateChildContext(
+ USHORT nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLTableScenarioContext::EndElement()
+{
+ SCTAB nCurrTable( sal::static_int_cast<SCTAB>( GetScImport().GetTables().GetCurrentSheet() ) );
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (pDoc)
+ {
+ pDoc->SetScenario( nCurrTable, TRUE );
+ USHORT nFlags( 0 );
+ if( bDisplayBorder )
+ nFlags |= SC_SCENARIO_SHOWFRAME;
+ if( bCopyBack )
+ nFlags |= SC_SCENARIO_TWOWAY;
+ if( bCopyStyles )
+ nFlags |= SC_SCENARIO_ATTRIB;
+ if( !bCopyFormulas )
+ nFlags |= SC_SCENARIO_VALUE;
+ if( bProtected )
+ nFlags |= SC_SCENARIO_PROTECT;
+ pDoc->SetScenarioData( nCurrTable, String( sComment ), aBorderColor, nFlags );
+ for( sal_Int32 i = 0; i < static_cast<sal_Int32>(aScenarioRanges.Count()); ++i )
+ {
+ ScRange* pRange(aScenarioRanges.GetObject( i ));
+ if( pRange )
+ pDoc->ApplyFlagsTab( pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row(), nCurrTable, SC_MF_SCENARIO );
+ }
+ pDoc->SetActiveScenario( nCurrTable, bIsActive );
+ }
+}
+
diff --git a/sc/source/filter/xml/xmlsceni.hxx b/sc/source/filter/xml/xmlsceni.hxx
new file mode 100644
index 000000000000..f3a5a75fa563
--- /dev/null
+++ b/sc/source/filter/xml/xmlsceni.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLSCENI_HXX
+#define SC_XMLSCENI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <tools/color.hxx>
+#include "rangelst.hxx"
+
+class ScXMLImport;
+
+class ScXMLTableScenarioContext : public SvXMLImportContext
+{
+private:
+ rtl::OUString sComment;
+ Color aBorderColor;
+ ScRangeList aScenarioRanges;
+ sal_Bool bDisplayBorder;
+ sal_Bool bCopyBack;
+ sal_Bool bCopyStyles;
+ sal_Bool bCopyFormulas;
+ sal_Bool bIsActive;
+ sal_Bool bProtected;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableScenarioContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableScenarioContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlsorti.cxx b/sc/source/filter/xml/xmlsorti.cxx
new file mode 100644
index 000000000000..ff007240b12b
--- /dev/null
+++ b/sc/source/filter/xml/xmlsorti.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlsorti.hxx"
+#include "xmlimprt.hxx"
+#include "docuno.hxx"
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "unonames.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <comphelper/extract.hxx>
+#include <xmloff/xmltoken.hxx>
+
+#define SC_USERLIST "UserList"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLSortContext::ScXMLSortContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext),
+ sCountry(),
+ sLanguage(),
+ sAlgorithm(),
+ nUserListIndex(0),
+ bCopyOutputData(sal_False),
+ bBindFormatsToContent(sal_True),
+ bIsCaseSensitive(sal_False),
+ bEnabledUserList(sal_False)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetSortAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT :
+ {
+ bBindFormatsToContent = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ ScRange aScRange;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart );
+ bCopyOutputData = sal_True;
+ }
+ }
+ break;
+ case XML_TOK_SORT_ATTR_CASE_SENSITIVE :
+ {
+ bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_SORT_ATTR_LANGUAGE :
+ sLanguage = sValue;
+ break;
+ case XML_TOK_SORT_ATTR_COUNTRY :
+ sCountry = sValue;
+ break;
+ case XML_TOK_SORT_ATTR_ALGORITHM :
+ sAlgorithm = sValue;
+ break;
+ }
+ }
+}
+
+ScXMLSortContext::~ScXMLSortContext()
+{
+}
+
+SvXMLImportContext *ScXMLSortContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetSortElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SORT_SORT_BY :
+ {
+ pContext = new ScXMLSortByContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSortContext::EndElement()
+{
+ sal_Int32 nLangLength(sLanguage.getLength());
+ sal_Int32 nCountryLength(sCountry.getLength());
+ sal_Int32 nAlgoLength(sAlgorithm.getLength());
+ sal_uInt8 i (0);
+ if (nLangLength || nCountryLength)
+ ++i;
+ if (nAlgoLength)
+ ++i;
+ uno::Sequence <beans::PropertyValue> aSortDescriptor(7 + i);
+ aSortDescriptor[0].Name = rtl::OUString::createFromAscii(SC_UNONAME_BINDFMT);
+ aSortDescriptor[0].Value = ::cppu::bool2any(bBindFormatsToContent);
+ aSortDescriptor[1].Name = rtl::OUString::createFromAscii(SC_UNONAME_COPYOUT);
+ aSortDescriptor[1].Value = ::cppu::bool2any(bCopyOutputData);
+ aSortDescriptor[2].Name = rtl::OUString::createFromAscii(SC_UNONAME_ISCASE);
+ aSortDescriptor[2].Value = ::cppu::bool2any(bIsCaseSensitive);
+ aSortDescriptor[3].Name = rtl::OUString::createFromAscii(SC_UNONAME_ISULIST);
+ aSortDescriptor[3].Value = ::cppu::bool2any(bEnabledUserList);
+ aSortDescriptor[4].Name = rtl::OUString::createFromAscii(SC_UNONAME_OUTPOS);
+ aSortDescriptor[4].Value <<= aOutputPosition;
+ aSortDescriptor[5].Name = rtl::OUString::createFromAscii(SC_UNONAME_UINDEX);
+ aSortDescriptor[5].Value <<= nUserListIndex;
+ aSortDescriptor[6].Name = rtl::OUString::createFromAscii(SC_UNONAME_SORTFLD);
+ aSortDescriptor[6].Value <<= aSortFields;
+ if (nLangLength || nCountryLength)
+ {
+ lang::Locale aLocale;
+ aLocale.Language = sLanguage;
+ aLocale.Country = sCountry;
+ aSortDescriptor[7].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COLLLOC));
+ aSortDescriptor[7].Value <<= aLocale;
+ }
+ if (nAlgoLength)
+ {
+ aSortDescriptor[6 + i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COLLALG));
+ aSortDescriptor[6 + i].Value <<= sAlgorithm;
+ }
+ pDatabaseRangeContext->SetSortSequence(aSortDescriptor);
+}
+
+void ScXMLSortContext::AddSortField(const rtl::OUString& sFieldNumber, const rtl::OUString& sDataType, const rtl::OUString& sOrder)
+{
+ util::SortField aSortField;
+ aSortField.Field = sFieldNumber.toInt32();
+ if (IsXMLToken(sOrder, XML_ASCENDING))
+ aSortField.SortAscending = sal_True;
+ else
+ aSortField.SortAscending = sal_False;
+ if (sDataType.getLength() > 8)
+ {
+ rtl::OUString sTemp = sDataType.copy(0, 8);
+ if (sTemp.compareToAscii(SC_USERLIST) == 0)
+ {
+ bEnabledUserList = sal_True;
+ sTemp = sDataType.copy(8);
+ nUserListIndex = static_cast<sal_Int16>(sTemp.toInt32());
+ }
+ else
+ {
+ if (IsXMLToken(sDataType, XML_AUTOMATIC))
+ aSortField.FieldType = util::SortFieldType_AUTOMATIC;
+ }
+ }
+ else
+ {
+ if (IsXMLToken(sDataType, XML_TEXT))
+ aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
+ else if (IsXMLToken(sDataType, XML_NUMBER))
+ aSortField.FieldType = util::SortFieldType_NUMERIC;
+ }
+ aSortFields.realloc(aSortFields.getLength() + 1);
+ aSortFields[aSortFields.getLength() - 1] = aSortField;
+}
+
+ScXMLSortByContext::ScXMLSortByContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSortContext* pTempSortContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pSortContext(pTempSortContext),
+ sDataType(GetXMLToken(XML_AUTOMATIC)),
+ sOrder(GetXMLToken(XML_ASCENDING))
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetSortSortByAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SORT_BY_ATTR_FIELD_NUMBER :
+ {
+ sFieldNumber = sValue;
+ }
+ break;
+ case XML_TOK_SORT_BY_ATTR_DATA_TYPE :
+ {
+ sDataType = sValue;
+ }
+ break;
+ case XML_TOK_SORT_BY_ATTR_ORDER :
+ {
+ sOrder = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSortByContext::~ScXMLSortByContext()
+{
+}
+
+SvXMLImportContext *ScXMLSortByContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLSortByContext::EndElement()
+{
+ pSortContext->AddSortField(sFieldNumber, sDataType, sOrder);
+}
+
diff --git a/sc/source/filter/xml/xmlsorti.hxx b/sc/source/filter/xml/xmlsorti.hxx
new file mode 100644
index 000000000000..30ac31e0dd22
--- /dev/null
+++ b/sc/source/filter/xml/xmlsorti.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLSORTI_HXX
+#define SC_XMLSORTI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/util/SortField.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include "xmldrani.hxx"
+
+class ScXMLImport;
+
+class ScXMLSortContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ com::sun::star::uno::Sequence <com::sun::star::util::SortField> aSortFields;
+ com::sun::star::table::CellAddress aOutputPosition;
+ rtl::OUString sCountry;
+ rtl::OUString sLanguage;
+ rtl::OUString sAlgorithm;
+ sal_Int16 nUserListIndex;
+ sal_Bool bCopyOutputData;
+ sal_Bool bBindFormatsToContent;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bEnabledUserList;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSortContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSortContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void AddSortField(const rtl::OUString& sFieldNumber, const rtl::OUString& sDataType, const rtl::OUString& sOrder);
+};
+
+class ScXMLSortByContext : public SvXMLImportContext
+{
+ ScXMLSortContext* pSortContext;
+
+ rtl::OUString sFieldNumber;
+ rtl::OUString sDataType;
+ rtl::OUString sOrder;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSortByContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSortContext* pTempSortContext);
+
+ virtual ~ScXMLSortByContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlstyle.cxx b/sc/source/filter/xml/xmlstyle.cxx
new file mode 100644
index 000000000000..d061ea24b194
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyle.cxx
@@ -0,0 +1,1876 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "xmlstyle.hxx"
+#include "xmlexprt.hxx"
+#include "xmlimprt.hxx"
+
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltypes.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmlnumfe.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/attrlist.hxx>
+#include <xmloff/contextid.hxx>
+#include <xmloff/txtprmap.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/util/CellProtection.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <comphelper/extract.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+using namespace com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
+
+#define MAP(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010 }
+#define MAP_EXT(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_LATEST }
+#define MAP_END() { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0, SvtSaveOptions::ODFVER_010 }
+
+const XMLPropertyMapEntry aXMLScCellStylesProperties[] =
+{
+ MAP( "AsianVerticalMode", XML_NAMESPACE_STYLE, XML_GLYPH_ORIENTATION_VERTICAL, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTICAL, 0),
+ MAP( "BottomBorder", XML_NAMESPACE_FO, XML_BORDER_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_BOTTOMBORDER ),
+ MAP( "BottomBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_BOTTOMBORDERWIDTH ),
+ MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "CellProtection", XML_NAMESPACE_STYLE, XML_CELL_PROTECT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_CELLPROTECTION|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "CellProtection", XML_NAMESPACE_STYLE, XML_PRINT_CONTENT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_PRINTCONTENT|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "CellStyle", XML_NAMESPACE_STYLE, XML_STYLE, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING, CTF_SC_CELLSTYLE ),
+ MAP( "ConditionalFormatXML", XML_NAMESPACE_STYLE, XML_MAP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_IMPORT_MAP ),
+ MAP( "ConditionalFormatXML", XML_NAMESPACE_STYLE, XML_MAP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MAP ),
+ MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_DIAGONALBLTR ),
+ MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALBLTRWIDTH ), // #i102690# for old files
+ MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR_WIDTHS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALBLTRWIDTHS ),
+ MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_DIAGONALTLBR ),
+ MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALTLBRWIDTH ), // #i102690# for old files
+ MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR_WIDTHS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALTLBRWIDTHS ),
+ MAP( "HoriJustify", XML_NAMESPACE_FO, XML_TEXT_ALIGN, XML_TYPE_PROP_PARAGRAPH|XML_SC_TYPE_HORIJUSTIFY|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "HoriJustify", XML_NAMESPACE_STYLE, XML_TEXT_ALIGN_SOURCE, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_HORIJUSTIFYSOURCE|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "HoriJustify", XML_NAMESPACE_STYLE, XML_REPEAT_CONTENT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_HORIJUSTIFYREPEAT|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsTextWrapped", XML_NAMESPACE_FO, XML_WRAP_OPTION, XML_TYPE_PROP_TABLE_CELL|XML_SC_ISTEXTWRAPPED, 0 ),
+ MAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_ALLBORDER ),
+ MAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_LEFTBORDER ),
+ MAP( "LeftBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_ALLBORDERWIDTH ),
+ MAP( "LeftBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_LEFTBORDERWIDTH ),
+ MAP( "NumberFormat", XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_NUMBER|MID_FLAG_SPECIAL_ITEM, CTF_SC_NUMBERFORMAT),
+ MAP( "Orientation", XML_NAMESPACE_STYLE, XML_DIRECTION, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ORIENTATION, 0 ),
+ MAP( "ParaBottomMargin", XML_NAMESPACE_FO, XML_PADDING, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_ALLPADDING ),
+ MAP( "ParaBottomMargin", XML_NAMESPACE_FO, XML_PADDING_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_BOTTOMPADDING ),
+ MAP( "ParaIndent", XML_NAMESPACE_FO, XML_MARGIN_LEFT, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_MEASURE16, 0 ),
+// MAP( "ParaIsHyphenation", XML_NAMESPACE_FO, XML_HYPHENATE, XML_TYPE_PROP_TEXT|XML_TYPE_BOOL, 0 ),
+ MAP( "ParaLeftMargin", XML_NAMESPACE_FO, XML_PADDING_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_LEFTPADDING ),
+ MAP( "ParaRightMargin", XML_NAMESPACE_FO, XML_PADDING_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_RIGHTPADDING ),
+ MAP( "ParaTopMargin", XML_NAMESPACE_FO, XML_PADDING_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_TOPPADDING ),
+ MAP( "RightBorder", XML_NAMESPACE_FO, XML_BORDER_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_RIGHTBORDER ),
+ MAP( "RightBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_RIGHTBORDERWIDTH ),
+ MAP( "RotateAngle", XML_NAMESPACE_STYLE, XML_ROTATION_ANGLE, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ROTATEANGLE, 0 ),
+ MAP( "RotateReference", XML_NAMESPACE_STYLE, XML_ROTATION_ALIGN, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ROTATEREFERENCE, 0),
+ MAP( "ShadowFormat", XML_NAMESPACE_STYLE, XML_SHADOW, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_TEXT_SHADOW, 0 ),
+ MAP( "ShrinkToFit", XML_NAMESPACE_STYLE, XML_SHRINK_TO_FIT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BOOL, 0 ),
+ MAP( "StandardDecimals", XML_NAMESPACE_STYLE, XML_DECIMAL_PLACES, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_NUMBER16, 0 ),
+ MAP( "TopBorder", XML_NAMESPACE_FO, XML_BORDER_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_TOPBORDER ),
+ MAP( "TopBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_TOPBORDERWIDTH ),
+ MAP( "UserDefinedAttributes", XML_NAMESPACE_TEXT, XML_XMLNS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_ATTRIBUTE_CONTAINER | MID_FLAG_SPECIAL_ITEM, 0 ),
+ MAP( "ValidationXML", XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BUILDIN_CMP_ONLY, CTF_SC_VALIDATION ),
+ MAP( "VertJustify", XML_NAMESPACE_STYLE, XML_VERTICAL_ALIGN, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTJUSTIFY, 0),
+// MAP( "WritingMode", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT, 0 ),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScColumnStylesProperties[] =
+{
+ MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_COLUMN|XML_SC_TYPE_BREAKBEFORE, 0),
+ MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE_COLUMN|XML_SC_TYPE_EQUAL|MID_FLAG_SPECIAL_ITEM, CTF_SC_ISVISIBLE ),
+ MAP( "Width", XML_NAMESPACE_STYLE, XML_COLUMN_WIDTH, XML_TYPE_PROP_TABLE_COLUMN|XML_TYPE_MEASURE, 0 ),
+// MAP( "OptimalWidth", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_COLUMN_WIDTH, XML_TYPE_PROP_TABLE_COLUMN|XML_TYPE_BOOL, 0),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScRowStylesImportProperties[] =
+{
+ // #i57867# Include background color (CellBackColor/IsCellBackgroundTransparent) for import only.
+ // Import and export should use the same map, with MID_FLAG_NO_PROPERTY_EXPORT for the background entries,
+ // but this doesn't work at the moment because SvXMLImportPropertyMapper compares MID_FLAG_NO_PROPERTY to 0.
+ // If this is changed (not for 2.0.x), a single map can be used again.
+
+ MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_MEASURE, CTF_SC_ROWHEIGHT),
+ MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_ROW|XML_SC_TYPE_BREAKBEFORE, CTF_SC_ROWBREAKBEFORE),
+ MAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_BOOL, CTF_SC_ROWOPTIMALHEIGHT),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScRowStylesProperties[] =
+{
+ MAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_MEASURE, CTF_SC_ROWHEIGHT),
+ MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_ROW|XML_SC_TYPE_BREAKBEFORE, CTF_SC_ROWBREAKBEFORE),
+ MAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_BOOL, CTF_SC_ROWOPTIMALHEIGHT),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScTableStylesImportProperties[] =
+{
+ // #i57869# Include background color (CellBackColor/IsCellBackgroundTransparent) for import only.
+ // Import and export should use the same map, with MID_FLAG_NO_PROPERTY_EXPORT for the background entries,
+ // but this doesn't work at the moment because SvXMLImportPropertyMapper compares MID_FLAG_NO_PROPERTY to 0.
+ // If this is changed (not for 2.0.x), a single map can be used again.
+
+ MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ),
+ MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ),
+ MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ),
+ MAP( "TabColor", XML_NAMESPACE_TABLE, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ),
+ MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScTableStylesProperties[] =
+{
+ MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ),
+ MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ),
+ MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ),
+ MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ),
+ MAP_END()
+};
+
+ScXMLCellExportPropertyMapper::ScXMLCellExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLCellExportPropertyMapper::~ScXMLCellExportPropertyMapper()
+{
+}
+
+void ScXMLCellExportPropertyMapper::ContextFilter(
+ ::std::vector< XMLPropertyState >& rProperties,
+ uno::Reference< beans::XPropertySet > rPropSet ) const
+{
+ XMLPropertyState* pPadding = NULL;
+ XMLPropertyState* pPadding_Bottom = NULL;
+ XMLPropertyState* pPadding_Left = NULL;
+ XMLPropertyState* pPadding_Right = NULL;
+ XMLPropertyState* pPadding_Top = NULL;
+
+ XMLPropertyState* pBorder = NULL;
+ XMLPropertyState* pBorder_Bottom = NULL;
+ XMLPropertyState* pBorder_Left = NULL;
+ XMLPropertyState* pBorder_Right = NULL;
+ XMLPropertyState* pBorder_Top = NULL;
+ XMLPropertyState* pSWBorder = NULL;
+ XMLPropertyState* pSWBorder_Bottom = NULL;
+ XMLPropertyState* pSWBorder_Left = NULL;
+ XMLPropertyState* pSWBorder_Right = NULL;
+ XMLPropertyState* pSWBorder_Top = NULL;
+ XMLPropertyState* pDiagonalTLBR = NULL;
+ XMLPropertyState* pDiagonalBLTR = NULL;
+
+ XMLPropertyState* pAllBorderWidthState = NULL;
+ XMLPropertyState* pLeftBorderWidthState = NULL;
+ XMLPropertyState* pRightBorderWidthState = NULL;
+ XMLPropertyState* pTopBorderWidthState = NULL;
+ XMLPropertyState* pBottomBorderWidthState = NULL;
+ XMLPropertyState* pSWAllBorderWidthState = NULL;
+ XMLPropertyState* pSWLeftBorderWidthState = NULL;
+ XMLPropertyState* pSWRightBorderWidthState = NULL;
+ XMLPropertyState* pSWTopBorderWidthState = NULL;
+ XMLPropertyState* pSWBottomBorderWidthState = NULL;
+ XMLPropertyState* pDiagonalTLBRWidthState = NULL;
+ XMLPropertyState* pDiagonalBLTRWidthState = NULL;
+
+ XMLPropertyState* pParaMarginLeft = NULL;
+ XMLPropertyState* pParaMarginLeftRel = NULL;
+ XMLPropertyState* pParaMarginRight = NULL;
+ XMLPropertyState* pParaMarginRightRel = NULL;
+ XMLPropertyState* pParaMarginTop = NULL;
+ XMLPropertyState* pParaMarginTopRel = NULL;
+ XMLPropertyState* pParaMarginBottom = NULL;
+ XMLPropertyState* pParaMarginBottomRel = NULL;
+
+ XMLPropertyState* pParaAdjust = NULL;
+ XMLPropertyState* pParaAdjustLast = NULL;
+
+ ::std::vector< XMLPropertyState >::iterator aEndIter(rProperties.end());
+ for( ::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin();
+ aIter != aEndIter; ++aIter )
+ {
+ XMLPropertyState* propertie = &(*aIter);
+ if (propertie->mnIndex != -1)
+ {
+ switch( getPropertySetMapper()->GetEntryContextId( propertie->mnIndex ) )
+ {
+ case CTF_SC_ALLPADDING: pPadding = propertie; break;
+ case CTF_SC_BOTTOMPADDING: pPadding_Bottom = propertie; break;
+ case CTF_SC_LEFTPADDING: pPadding_Left = propertie; break;
+ case CTF_SC_RIGHTPADDING: pPadding_Right = propertie; break;
+ case CTF_SC_TOPPADDING: pPadding_Top = propertie; break;
+ case CTF_SC_ALLBORDER: pBorder = propertie; break;
+ case CTF_SC_LEFTBORDER: pBorder_Left = propertie; break;
+ case CTF_SC_RIGHTBORDER: pBorder_Right = propertie; break;
+ case CTF_SC_BOTTOMBORDER: pBorder_Bottom = propertie; break;
+ case CTF_SC_TOPBORDER: pBorder_Top = propertie; break;
+ case CTF_SC_ALLBORDERWIDTH: pAllBorderWidthState = propertie; break;
+ case CTF_SC_LEFTBORDERWIDTH: pLeftBorderWidthState = propertie; break;
+ case CTF_SC_RIGHTBORDERWIDTH: pRightBorderWidthState = propertie; break;
+ case CTF_SC_TOPBORDERWIDTH: pTopBorderWidthState = propertie; break;
+ case CTF_SC_BOTTOMBORDERWIDTH: pBottomBorderWidthState = propertie; break;
+ case CTF_ALLBORDER: pSWBorder = propertie; break;
+ case CTF_LEFTBORDER: pSWBorder_Left = propertie; break;
+ case CTF_RIGHTBORDER: pSWBorder_Right = propertie; break;
+ case CTF_BOTTOMBORDER: pSWBorder_Bottom = propertie; break;
+ case CTF_TOPBORDER: pSWBorder_Top = propertie; break;
+ case CTF_ALLBORDERWIDTH: pSWAllBorderWidthState = propertie; break;
+ case CTF_LEFTBORDERWIDTH: pSWLeftBorderWidthState = propertie; break;
+ case CTF_RIGHTBORDERWIDTH: pSWRightBorderWidthState = propertie; break;
+ case CTF_TOPBORDERWIDTH: pSWTopBorderWidthState = propertie; break;
+ case CTF_BOTTOMBORDERWIDTH: pSWBottomBorderWidthState = propertie; break;
+ case CTF_SC_DIAGONALTLBR: pDiagonalTLBR = propertie; break;
+ case CTF_SC_DIAGONALTLBRWIDTH: pDiagonalTLBRWidthState = propertie; break;
+ case CTF_SC_DIAGONALBLTR: pDiagonalBLTR = propertie; break;
+ case CTF_SC_DIAGONALBLTRWIDTH: pDiagonalBLTRWidthState = propertie; break;
+ case CTF_SD_SHAPE_PARA_ADJUST: pParaAdjust = propertie; break;
+ case CTF_PARA_ADJUSTLAST: pParaAdjustLast = propertie; break;
+ case CTF_PARALEFTMARGIN: pParaMarginLeft = propertie; break;
+ case CTF_PARALEFTMARGIN_REL: pParaMarginLeftRel = propertie; break;
+ case CTF_PARARIGHTMARGIN: pParaMarginRight = propertie; break;
+ case CTF_PARARIGHTMARGIN_REL: pParaMarginRightRel = propertie; break;
+ case CTF_PARATOPMARGIN: pParaMarginTop = propertie; break;
+ case CTF_PARATOPMARGIN_REL: pParaMarginTopRel = propertie; break;
+ case CTF_PARABOTTOMMARGIN: pParaMarginBottom = propertie; break;
+ case CTF_PARABOTTOMMARGIN_REL: pParaMarginBottomRel = propertie; break;
+ }
+ }
+ }
+
+ if (pPadding && pPadding_Bottom && pPadding_Left && pPadding_Right && pPadding_Top)
+ {
+ sal_Int32 nBottom = 0, nTop = 0, nLeft = 0, nRight = 0;
+ if ((pPadding_Bottom->maValue >>= nBottom) &&
+ (pPadding_Left->maValue >>= nLeft) &&
+ (pPadding_Right->maValue >>= nRight) &&
+ (pPadding_Top->maValue >>= nTop))
+ {
+ if ((nBottom == nTop) && (nLeft == nRight) && (nTop == nLeft))
+ {
+ pPadding_Bottom->mnIndex = -1;
+ pPadding_Bottom->maValue.clear();
+ pPadding_Left->mnIndex = -1;
+ pPadding_Left->maValue.clear();
+ pPadding_Right->mnIndex = -1;
+ pPadding_Right->maValue.clear();
+ pPadding_Top->mnIndex = -1;
+ pPadding_Top->maValue.clear();
+ }
+ else
+ {
+ pPadding->mnIndex = -1;
+ pPadding->maValue.clear();
+ }
+ }
+ }
+ if( pBorder )
+ {
+ if( pBorder_Left && pBorder_Right && pBorder_Top && pBorder_Bottom )
+ {
+ table::BorderLine aLeft, aRight, aTop, aBottom;
+
+ pBorder_Left->maValue >>= aLeft;
+ pBorder_Right->maValue >>= aRight;
+ pBorder_Top->maValue >>= aTop;
+ pBorder_Bottom->maValue >>= aBottom;
+ if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth &&
+ aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance &&
+ aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
+ aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
+ aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth &&
+ aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance )
+ {
+ pBorder_Left->mnIndex = -1;
+ pBorder_Left->maValue.clear();
+ pBorder_Right->mnIndex = -1;
+ pBorder_Right->maValue.clear();
+ pBorder_Top->mnIndex = -1;
+ pBorder_Top->maValue.clear();
+ pBorder_Bottom->mnIndex = -1;
+ pBorder_Bottom->maValue.clear();
+ }
+ else
+ {
+ pBorder->mnIndex = -1;
+ pBorder->maValue.clear();
+ }
+ }
+ else
+ {
+ pBorder->mnIndex = -1;
+ pBorder->maValue.clear();
+ }
+ }
+ if( pAllBorderWidthState )
+ {
+ if( pLeftBorderWidthState && pRightBorderWidthState && pTopBorderWidthState && pBottomBorderWidthState )
+ {
+ table::BorderLine aLeft, aRight, aTop, aBottom;
+
+ pLeftBorderWidthState->maValue >>= aLeft;
+ pRightBorderWidthState->maValue >>= aRight;
+ pTopBorderWidthState->maValue >>= aTop;
+ pBottomBorderWidthState->maValue >>= aBottom;
+ if( aLeft.InnerLineWidth == aRight.InnerLineWidth && aLeft.OuterLineWidth == aRight.OuterLineWidth &&
+ aLeft.LineDistance == aRight.LineDistance && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
+ aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
+ aLeft.InnerLineWidth == aBottom.InnerLineWidth && aLeft.OuterLineWidth == aBottom.OuterLineWidth &&
+ aLeft.LineDistance == aBottom.LineDistance )
+ {
+ pLeftBorderWidthState->mnIndex = -1;
+ pLeftBorderWidthState->maValue.clear();
+ pRightBorderWidthState->mnIndex = -1;
+ pRightBorderWidthState->maValue.clear();
+ pTopBorderWidthState->mnIndex = -1;
+ pTopBorderWidthState->maValue.clear();
+ pBottomBorderWidthState->mnIndex = -1;
+ pBottomBorderWidthState->maValue.clear();
+ }
+ else
+ {
+ pAllBorderWidthState->mnIndex = -1;
+ pAllBorderWidthState->maValue.clear();
+ }
+ }
+ else
+ {
+ pAllBorderWidthState->mnIndex = -1;
+ pAllBorderWidthState->maValue.clear();
+ }
+ }
+
+ if (pParaAdjust)
+ {
+ pParaAdjust->mnIndex = -1;
+ pParaAdjust->maValue.clear();
+ }
+ if (pParaAdjustLast)
+ {
+ pParaAdjustLast->mnIndex = -1;
+ pParaAdjustLast->maValue.clear();
+ }
+ if (pSWBorder)
+ {
+ pSWBorder->mnIndex = -1;
+ pSWBorder->maValue.clear();
+ }
+ if (pSWBorder_Left)
+ {
+ pSWBorder_Left->mnIndex = -1;
+ pSWBorder_Left->maValue.clear();
+ }
+ if (pSWBorder_Right)
+ {
+ pSWBorder_Right->mnIndex = -1;
+ pSWBorder_Right->maValue.clear();
+ }
+ if (pSWBorder_Bottom)
+ {
+ pSWBorder_Bottom->mnIndex = -1;
+ pSWBorder_Bottom->maValue.clear();
+ }
+ if (pSWBorder_Top)
+ {
+ pSWBorder_Top->mnIndex = -1;
+ pSWBorder_Top->maValue.clear();
+ }
+ if (pSWAllBorderWidthState)
+ {
+ pSWAllBorderWidthState->mnIndex = -1;
+ pSWAllBorderWidthState->maValue.clear();
+ }
+ if (pSWLeftBorderWidthState)
+ {
+ pSWLeftBorderWidthState->mnIndex = -1;
+ pSWLeftBorderWidthState->maValue.clear();
+ }
+ if (pSWRightBorderWidthState)
+ {
+ pSWRightBorderWidthState->mnIndex = -1;
+ pSWRightBorderWidthState->maValue.clear();
+ }
+ if (pSWTopBorderWidthState)
+ {
+ pSWTopBorderWidthState->mnIndex = -1;
+ pSWTopBorderWidthState->maValue.clear();
+ }
+ if (pSWBottomBorderWidthState)
+ {
+ pSWBottomBorderWidthState->mnIndex = -1;
+ pSWBottomBorderWidthState->maValue.clear();
+ }
+
+ if (pParaMarginLeft)
+ {
+ pParaMarginLeft->mnIndex = -1;
+ pParaMarginLeft->maValue.clear();
+ }
+ if (pParaMarginLeftRel)
+ {
+ pParaMarginLeftRel->mnIndex = -1;
+ pParaMarginLeftRel->maValue.clear();
+ }
+ if (pParaMarginRight)
+ {
+ pParaMarginRight->mnIndex = -1;
+ pParaMarginRight->maValue.clear();
+ }
+ if (pParaMarginRightRel)
+ {
+ pParaMarginRightRel->mnIndex = -1;
+ pParaMarginRightRel->maValue.clear();
+ }
+ if (pParaMarginTop)
+ {
+ pParaMarginTop->mnIndex = -1;
+ pParaMarginTop->maValue.clear();
+ }
+ if (pParaMarginTopRel)
+ {
+ pParaMarginTopRel->mnIndex = -1;
+ pParaMarginTopRel->maValue.clear();
+ }
+ if (pParaMarginBottom)
+ {
+ pParaMarginBottom->mnIndex = -1;
+ pParaMarginBottom->maValue.clear();
+ }
+ if (pParaMarginBottomRel)
+ {
+ pParaMarginBottomRel->mnIndex = -1;
+ pParaMarginBottomRel->maValue.clear();
+ }
+
+ // #i102690# old diagonal line attribute names without "s" are only read, not written
+ if (pDiagonalTLBRWidthState)
+ {
+ pDiagonalTLBRWidthState->mnIndex = -1;
+ pDiagonalTLBRWidthState->maValue.clear();
+ }
+ if (pDiagonalBLTRWidthState)
+ {
+ pDiagonalBLTRWidthState->mnIndex = -1;
+ pDiagonalBLTRWidthState->maValue.clear();
+ }
+
+ SvXMLExportPropertyMapper::ContextFilter(rProperties, rPropSet);
+}
+
+/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+void ScXMLCellExportPropertyMapper::handleSpecialItem(
+ SvXMLAttributeList& /* rAttrList */,
+ const XMLPropertyState& /* rProperty */,
+ const SvXMLUnitConverter& /* rUnitConverter */,
+ const SvXMLNamespaceMap& /* rNamespaceMap */,
+ const ::std::vector< XMLPropertyState > * /* pProperties */,
+ sal_uInt32 /* nIdx */ ) const
+{
+ // the SpecialItem NumberFormat must not be handled by this method
+ // the SpecialItem ConditionlaFormat must not be handled by this method
+ // the SpecialItem CharBackColor must not be handled by this method
+}
+
+ScXMLRowExportPropertyMapper::ScXMLRowExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLRowExportPropertyMapper::~ScXMLRowExportPropertyMapper()
+{
+}
+
+void ScXMLRowExportPropertyMapper::ContextFilter(
+ ::std::vector< XMLPropertyState >& /* rProperties */,
+ uno::Reference< beans::XPropertySet > /* rPropSet */ ) const
+{
+ //#108550#; don't filter the height, so other applications know the calculated height
+
+/* XMLPropertyState* pHeight = NULL;
+ XMLPropertyState* pOptimalHeight = NULL;
+
+ for( ::std::vector< XMLPropertyState >::iterator propertie = rProperties.begin();
+ propertie != rProperties.end();
+ ++propertie )
+ {
+ switch( getPropertySetMapper()->GetEntryContextId( propertie->mnIndex ) )
+ {
+ case CTF_SC_ROWHEIGHT: pHeight = propertie; break;
+ case CTF_SC_ROWOPTIMALHEIGHT: pOptimalHeight = propertie; break;
+ }
+ }
+ if ((pHeight && pOptimalHeight && ::cppu::any2bool( pOptimalHeight->maValue )) ||
+ (pHeight && !pOptimalHeight))
+ {
+ pHeight->mnIndex = -1;
+ pHeight->maValue.clear();
+ }
+ if (pOptimalHeight)
+ {
+ pOptimalHeight->mnIndex = -1;
+ pOptimalHeight->maValue.clear();
+ }*/
+}
+
+ScXMLColumnExportPropertyMapper::ScXMLColumnExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLColumnExportPropertyMapper::~ScXMLColumnExportPropertyMapper()
+{
+}
+
+/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+void ScXMLColumnExportPropertyMapper::handleSpecialItem(
+ SvXMLAttributeList& /* rAttrList */,
+ const XMLPropertyState& /* rProperty */,
+ const SvXMLUnitConverter& /* rUnitConverter */,
+ const SvXMLNamespaceMap& /* rNamespaceMap */,
+ const ::std::vector< XMLPropertyState > * /* pProperties */,
+ sal_uInt32 /* nIdx */ ) const
+{
+ // the SpecialItem IsVisible must not be handled by this method
+}
+
+ScXMLTableExportPropertyMapper::ScXMLTableExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLTableExportPropertyMapper::~ScXMLTableExportPropertyMapper()
+{
+}
+
+/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+void ScXMLTableExportPropertyMapper::handleSpecialItem(
+ SvXMLAttributeList& /* rAttrList */,
+ const XMLPropertyState& /* rProperty */,
+ const SvXMLUnitConverter& /* rUnitConverter */,
+ const SvXMLNamespaceMap& /* rNamespaceMap */,
+ const ::std::vector< XMLPropertyState > * /* pProperties */,
+ sal_uInt32 /* nIdx */ ) const
+{
+ // the SpecialItem PageStyle must not be handled by this method
+}
+
+void ScXMLAutoStylePoolP::exportStyleAttributes(
+ SvXMLAttributeList& rAttrList,
+ sal_Int32 nFamily,
+ const ::std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp
+ , const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const
+{
+ SvXMLAutoStylePoolP::exportStyleAttributes( rAttrList, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap );
+ if (nFamily == XML_STYLE_FAMILY_TABLE_CELL)
+ {
+ ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin());
+ ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end());
+ while (i != endi)
+ {
+ UniReference< XMLPropertySetMapper > aPropMapper(rScXMLExport.GetCellStylesPropertySetMapper());
+ sal_Int16 nContextID(aPropMapper->GetEntryContextId(i->mnIndex));
+ switch (nContextID)
+ {
+ case CTF_SC_NUMBERFORMAT :
+ {
+ sal_Int32 nNumberFormat = 0;
+ if (i->maValue >>= nNumberFormat)
+ {
+ rtl::OUString sAttrValue(rScXMLExport.getDataStyleName(nNumberFormat));
+ if (sAttrValue.getLength())
+ {
+ GetExport().AddAttribute(
+ aPropMapper->GetEntryNameSpace(i->mnIndex),
+ aPropMapper->GetEntryXMLName(i->mnIndex),
+ sAttrValue );
+ }
+ }
+ }
+ break;
+ }
+ ++i;
+ }
+ }
+ else if (nFamily == XML_STYLE_FAMILY_TABLE_TABLE)
+ {
+ ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin());
+ ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end());
+ while(i != endi)
+ {
+ UniReference< XMLPropertySetMapper > aPropMapper(rScXMLExport.GetTableStylesPropertySetMapper());
+ sal_Int16 nContextID(aPropMapper->GetEntryContextId(i->mnIndex));
+ switch (nContextID)
+ {
+ case CTF_SC_MASTERPAGENAME :
+ {
+ rtl::OUString sName;
+ if (i->maValue >>= sName)
+ {
+ GetExport().AddAttribute(
+ aPropMapper->GetEntryNameSpace(i->mnIndex),
+ aPropMapper->GetEntryXMLName(i->mnIndex),
+ GetExport().EncodeStyleName( sName ));
+ }
+ }
+ break;
+ }
+ ++i;
+ }
+ }
+}
+
+void ScXMLAutoStylePoolP::exportStyleContent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
+ sal_Int32 nFamily,
+ const std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp
+ , const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const
+{
+ SvXMLAutoStylePoolP::exportStyleContent( rHandler, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap );
+ if (nFamily == XML_STYLE_FAMILY_TABLE_CELL)
+ {
+ sal_Bool bNotFound = sal_True;
+ ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin());
+ ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end());
+ while ((i != endi) && bNotFound)
+ {
+ if (i->mnIndex != -1)
+ {
+ sal_Int16 nContextID = rScXMLExport.GetCellStylesPropertySetMapper()->GetEntryContextId(i->mnIndex);
+ switch (nContextID)
+ {
+ case CTF_SC_MAP :
+ {
+ uno::Reference<container::XIndexAccess> xIndex( i->maValue, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ sal_Int32 nConditionCount(xIndex->getCount());
+ for (sal_Int32 nCondition = 0; nCondition < nConditionCount; ++nCondition)
+ {
+ uno::Reference <sheet::XSheetConditionalEntry> xSheetConditionalEntry(xIndex->getByIndex(nCondition), uno::UNO_QUERY);
+ if (xSheetConditionalEntry.is())
+ {
+ rtl::OUString sStyleName(xSheetConditionalEntry->getStyleName());
+ uno::Reference <sheet::XSheetCondition> xSheetCondition(xSheetConditionalEntry, uno::UNO_QUERY);
+ if (xSheetCondition.is())
+ {
+ sheet::ConditionOperator aOperator = xSheetCondition->getOperator();
+ if (aOperator != sheet::ConditionOperator_NONE)
+ {
+ if (aOperator == sheet::ConditionOperator_FORMULA)
+ {
+ rtl::OUString sCondition(RTL_CONSTASCII_USTRINGPARAM("is-true-formula("));
+ sCondition += xSheetCondition->getFormula1();
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_CONDITION, sCondition);
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME, rScXMLExport.EncodeStyleName( sStyleName ));
+ OUString sOUBaseAddress;
+ ScDocument* pDoc = rScXMLExport.GetDocument();
+ ScRangeStringConverter::GetStringFromAddress( sOUBaseAddress,
+ xSheetCondition->getSourcePosition(), pDoc, FormulaGrammar::CONV_OOO );
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_BASE_CELL_ADDRESS, sOUBaseAddress);
+ SvXMLElementExport aMElem(rScXMLExport, XML_NAMESPACE_STYLE, XML_MAP, sal_True, sal_True);
+ }
+ else
+ {
+ rtl::OUString sCondition;
+ if (aOperator == sheet::ConditionOperator_BETWEEN ||
+ aOperator == sheet::ConditionOperator_NOT_BETWEEN)
+ {
+ if (aOperator == sheet::ConditionOperator_BETWEEN)
+ sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between("));
+ else
+ sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between("));
+ sCondition += xSheetCondition->getFormula1();
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ sCondition += xSheetCondition->getFormula2();
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ }
+ else
+ {
+ sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content()"));
+ switch (aOperator)
+ {
+ case sheet::ConditionOperator_LESS:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ break;
+ case sheet::ConditionOperator_GREATER:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ break;
+ case sheet::ConditionOperator_LESS_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ break;
+ case sheet::ConditionOperator_GREATER_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ break;
+ case sheet::ConditionOperator_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ break;
+ case sheet::ConditionOperator_NOT_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ sCondition += xSheetCondition->getFormula1();
+ }
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_CONDITION, sCondition);
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME, rScXMLExport.EncodeStyleName( sStyleName ));
+ OUString sOUBaseAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUBaseAddress,
+ xSheetCondition->getSourcePosition(), rScXMLExport.GetDocument(), FormulaGrammar::CONV_OOO );
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_BASE_CELL_ADDRESS, sOUBaseAddress);
+ SvXMLElementExport aMElem(rScXMLExport, XML_NAMESPACE_STYLE, XML_MAP, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ ++i;
+ }
+ }
+}
+
+ScXMLAutoStylePoolP::ScXMLAutoStylePoolP(ScXMLExport& rTempScXMLExport):
+ SvXMLAutoStylePoolP(rTempScXMLExport),
+ rScXMLExport(rTempScXMLExport)
+{
+}
+
+ScXMLAutoStylePoolP::~ScXMLAutoStylePoolP()
+{
+}
+
+
+void ScXMLStyleExport::exportStyleAttributes(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & rStyle )
+{
+ uno::Reference< beans::XPropertySet > xPropSet( rStyle, uno::UNO_QUERY );
+ if (xPropSet.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo(xPropSet->getPropertySetInfo());
+ rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"));
+ if( xPropSetInfo->hasPropertyByName( sNumberFormat ) )
+ {
+ uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
+ if( xPropState.is() && (beans::PropertyState_DIRECT_VALUE ==
+ xPropState->getPropertyState( sNumberFormat )) )
+ {
+ sal_Int32 nNumberFormat = 0;
+ if (xPropSet->getPropertyValue( sNumberFormat ) >>= nNumberFormat)
+ GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME,
+ GetExport().getDataStyleName(nNumberFormat) );
+ }
+ }
+ }
+}
+
+void ScXMLStyleExport::exportStyleContent(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & /* rStyle */ )
+{
+}
+
+ScXMLStyleExport::ScXMLStyleExport(
+ SvXMLExport& rExp,
+ const ::rtl::OUString& rPoolStyleName,
+ SvXMLAutoStylePoolP *pAutoStyleP )
+ : XMLStyleExport(rExp, rPoolStyleName, pAutoStyleP)
+{
+}
+
+ScXMLStyleExport::~ScXMLStyleExport()
+{
+}
+
+XMLScPropHdlFactory::XMLScPropHdlFactory()
+ : XMLPropertyHandlerFactory()
+{
+}
+
+XMLScPropHdlFactory::~XMLScPropHdlFactory()
+{
+}
+
+const XMLPropertyHandler* XMLScPropHdlFactory::GetPropertyHandler( sal_Int32 nType ) const
+{
+ nType &= MID_FLAG_MASK;
+
+ XMLPropertyHandler* pHdl((XMLPropertyHandler*)XMLPropertyHandlerFactory::GetPropertyHandler( nType ));
+ if(!pHdl)
+ {
+ switch(nType)
+ {
+ case XML_SC_TYPE_CELLPROTECTION :
+ {
+ pHdl = new XmlScPropHdl_CellProtection;
+ }
+ break;
+ case XML_SC_TYPE_PRINTCONTENT :
+ {
+ pHdl = new XmlScPropHdl_PrintContent;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFY :
+ {
+ pHdl = new XmlScPropHdl_HoriJustify;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFYSOURCE :
+ {
+ pHdl = new XmlScPropHdl_HoriJustifySource;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFYREPEAT :
+ {
+ pHdl = new XmlScPropHdl_HoriJustifyRepeat;
+ }
+ break;
+ case XML_SC_TYPE_ORIENTATION :
+ {
+ pHdl = new XmlScPropHdl_Orientation;
+ }
+ break;
+ case XML_SC_TYPE_ROTATEANGLE :
+ {
+ pHdl = new XmlScPropHdl_RotateAngle;
+ }
+ break;
+ case XML_SC_TYPE_ROTATEREFERENCE :
+ {
+ pHdl = new XmlScPropHdl_RotateReference;
+ }
+ break;
+ case XML_SC_TYPE_VERTJUSTIFY :
+ {
+ pHdl = new XmlScPropHdl_VertJustify;
+ }
+ break;
+ case XML_SC_TYPE_BREAKBEFORE :
+ {
+ pHdl = new XmlScPropHdl_BreakBefore;
+ }
+ break;
+ case XML_SC_ISTEXTWRAPPED :
+ {
+ pHdl = new XmlScPropHdl_IsTextWrapped;
+ }
+ break;
+ case XML_SC_TYPE_EQUAL :
+ {
+ pHdl = new XmlScPropHdl_IsEqual;
+ }
+ break;
+ case XML_SC_TYPE_VERTICAL :
+ {
+ pHdl = new XmlScPropHdl_Vertical;
+ }
+ break;
+ }
+
+ if(pHdl)
+ PutHdlCache(nType, pHdl);
+ }
+
+ return pHdl;
+}
+
+XmlScPropHdl_CellProtection::~XmlScPropHdl_CellProtection()
+{
+}
+
+bool XmlScPropHdl_CellProtection::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ util::CellProtection aCellProtection1, aCellProtection2;
+
+ if((r1 >>= aCellProtection1) && (r2 >>= aCellProtection2))
+ {
+ return ((aCellProtection1.IsHidden == aCellProtection2.IsHidden) &&
+ (aCellProtection1.IsLocked == aCellProtection2.IsLocked) &&
+ (aCellProtection1.IsFormulaHidden == aCellProtection2.IsFormulaHidden));
+ }
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_CellProtection::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ util::CellProtection aCellProtection;
+ sal_Bool bDefault(sal_False);
+ if (!rValue.hasValue())
+ {
+ aCellProtection.IsHidden = sal_False;
+ aCellProtection.IsLocked = sal_True;
+ aCellProtection.IsFormulaHidden = sal_False;
+ aCellProtection.IsPrintHidden = sal_False;
+ bDefault = sal_True;
+ }
+ if ((rValue >>= aCellProtection) || bDefault)
+ {
+ if (!IsXMLToken(rStrImpValue, XML_NONE))
+ {
+ if (!IsXMLToken(rStrImpValue, XML_HIDDEN_AND_PROTECTED))
+ {
+ if (!IsXMLToken(rStrImpValue, XML_PROTECTED))
+ {
+ if (!IsXMLToken(rStrImpValue, XML_FORMULA_HIDDEN))
+ {
+ sal_Int16 i(0);
+ while (i < rStrImpValue.getLength() && rStrImpValue[i] != ' ')
+ ++i;
+ rtl::OUString sFirst(rStrImpValue.copy(0, i));
+ rtl::OUString sSecond(rStrImpValue.copy(i + 1));
+ aCellProtection.IsFormulaHidden = sal_False;
+ aCellProtection.IsHidden = sal_False;
+ aCellProtection.IsLocked = sal_False;
+ if ((IsXMLToken(sFirst, XML_PROTECTED)) || (IsXMLToken(sSecond, XML_PROTECTED)))
+ aCellProtection.IsLocked = sal_True;
+ if ((IsXMLToken(sFirst, XML_FORMULA_HIDDEN)) || (IsXMLToken(sSecond, XML_FORMULA_HIDDEN)))
+ aCellProtection.IsFormulaHidden = sal_True;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = sal_True;
+ aCellProtection.IsHidden = sal_False;
+ aCellProtection.IsLocked = sal_False;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = sal_False;
+ aCellProtection.IsHidden = sal_False;
+ aCellProtection.IsLocked = sal_True;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = sal_True;
+ aCellProtection.IsHidden = sal_True;
+ aCellProtection.IsLocked = sal_True;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = sal_False;
+ aCellProtection.IsHidden = sal_False;
+ aCellProtection.IsLocked = sal_False;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_CellProtection::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+ util::CellProtection aCellProtection;
+
+ if(rValue >>= aCellProtection)
+ {
+ if (!(aCellProtection.IsFormulaHidden || aCellProtection.IsHidden || aCellProtection.IsLocked))
+ {
+ rStrExpValue = GetXMLToken(XML_NONE);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsHidden)
+ {
+ // #i105964# "Hide all" implies "Protected" in the UI, so it must be saved as "hidden-and-protected"
+ // even if "IsLocked" is not set in the CellProtection struct.
+ rStrExpValue = GetXMLToken(XML_HIDDEN_AND_PROTECTED);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsLocked && !(aCellProtection.IsFormulaHidden || aCellProtection.IsHidden))
+ {
+ rStrExpValue = GetXMLToken(XML_PROTECTED);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsFormulaHidden && !(aCellProtection.IsLocked || aCellProtection.IsHidden))
+ {
+ rStrExpValue = GetXMLToken(XML_FORMULA_HIDDEN);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsFormulaHidden && aCellProtection.IsLocked)
+ {
+ rStrExpValue = GetXMLToken(XML_PROTECTED);
+ rStrExpValue += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
+ rStrExpValue += GetXMLToken(XML_FORMULA_HIDDEN);
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_PrintContent::~XmlScPropHdl_PrintContent()
+{
+}
+
+bool XmlScPropHdl_PrintContent::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ util::CellProtection aCellProtection1, aCellProtection2;
+
+ if((r1 >>= aCellProtection1) && (r2 >>= aCellProtection2))
+ {
+ return (aCellProtection1.IsPrintHidden == aCellProtection2.IsPrintHidden);
+ }
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_PrintContent::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+ util::CellProtection aCellProtection;
+ sal_Bool bDefault(sal_False);
+ if (!rValue.hasValue())
+ {
+ aCellProtection.IsHidden = sal_False;
+ aCellProtection.IsLocked = sal_True;
+ aCellProtection.IsFormulaHidden = sal_False;
+ aCellProtection.IsPrintHidden = sal_False;
+ bDefault = sal_True;
+ }
+ if ((rValue >>= aCellProtection) || bDefault)
+ {
+ sal_Bool bValue;
+ if (SvXMLUnitConverter::convertBool(bValue, rStrImpValue))
+ {
+ aCellProtection.IsPrintHidden = !bValue;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_PrintContent::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ util::CellProtection aCellProtection;
+ if(rValue >>= aCellProtection)
+ {
+ rtl::OUStringBuffer sValue;
+ SvXMLUnitConverter::convertBool(sValue, !aCellProtection.IsPrintHidden);
+ rStrExpValue = sValue.makeStringAndClear();
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_HoriJustify::~XmlScPropHdl_HoriJustify()
+{
+}
+
+bool XmlScPropHdl_HoriJustify::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellHoriJustify aHoriJustify1, aHoriJustify2;
+
+ if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2))
+ return (aHoriJustify1 == aHoriJustify2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_HoriJustify::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ table::CellHoriJustify nValue = table::CellHoriJustify_LEFT;
+ rValue >>= nValue;
+ if (nValue != table::CellHoriJustify_REPEAT)
+ {
+ if (IsXMLToken(rStrImpValue, XML_START))
+ {
+ nValue = table::CellHoriJustify_LEFT;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_END))
+ {
+ nValue = table::CellHoriJustify_RIGHT;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_CENTER))
+ {
+ nValue = table::CellHoriJustify_CENTER;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_JUSTIFY))
+ {
+ nValue = table::CellHoriJustify_BLOCK;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ }
+ else
+ bRetval = sal_True;
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_HoriJustify::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellHoriJustify nVal;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellHoriJustify_REPEAT:
+ case table::CellHoriJustify_LEFT:
+ {
+ rStrExpValue = GetXMLToken(XML_START);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellHoriJustify_RIGHT:
+ {
+ rStrExpValue = GetXMLToken(XML_END);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellHoriJustify_CENTER:
+ {
+ rStrExpValue = GetXMLToken(XML_CENTER);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellHoriJustify_BLOCK:
+ {
+ rStrExpValue = GetXMLToken(XML_JUSTIFY);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_HoriJustifySource::~XmlScPropHdl_HoriJustifySource()
+{
+}
+
+bool XmlScPropHdl_HoriJustifySource::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellHoriJustify aHoriJustify1, aHoriJustify2;
+
+ if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2))
+ return (aHoriJustify1 == aHoriJustify2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifySource::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if (IsXMLToken(rStrImpValue, XML_FIX))
+ {
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_VALUE_TYPE))
+ {
+ table::CellHoriJustify nValue(table::CellHoriJustify_STANDARD);
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifySource::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellHoriJustify nVal;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ if (nVal == table::CellHoriJustify_STANDARD)
+ {
+ rStrExpValue = GetXMLToken(XML_VALUE_TYPE);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_FIX);
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_HoriJustifyRepeat::~XmlScPropHdl_HoriJustifyRepeat()
+{
+}
+
+bool XmlScPropHdl_HoriJustifyRepeat::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellHoriJustify aHoriJustify1, aHoriJustify2;
+
+ if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2))
+ return (aHoriJustify1 == aHoriJustify2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifyRepeat::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if (IsXMLToken(rStrImpValue, XML_FALSE))
+ {
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TRUE))
+ {
+ table::CellHoriJustify nValue = table::CellHoriJustify_REPEAT;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifyRepeat::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellHoriJustify nVal;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ if (nVal == table::CellHoriJustify_REPEAT)
+ {
+ rStrExpValue = GetXMLToken(XML_TRUE);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_FALSE);
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_Orientation::~XmlScPropHdl_Orientation()
+{
+}
+
+bool XmlScPropHdl_Orientation::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellOrientation aOrientation1, aOrientation2;
+
+ if((r1 >>= aOrientation1) && (r2 >>= aOrientation2))
+ return (aOrientation1 == aOrientation2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_Orientation::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ table::CellOrientation nValue;
+ if (IsXMLToken(rStrImpValue, XML_LTR))
+ {
+ nValue = table::CellOrientation_STANDARD;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TTB))
+ {
+ nValue = table::CellOrientation_STACKED;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_Orientation::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellOrientation nVal;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellOrientation_STACKED :
+ {
+ rStrExpValue = GetXMLToken(XML_TTB);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ rStrExpValue = GetXMLToken(XML_LTR);
+ bRetval = sal_True;
+ }
+ break;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_RotateAngle::~XmlScPropHdl_RotateAngle()
+{
+}
+
+bool XmlScPropHdl_RotateAngle::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Int32 aAngle1 = 0, aAngle2 = 0;
+
+ if((r1 >>= aAngle1) && (r2 >>= aAngle2))
+ return (aAngle1 == aAngle2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_RotateAngle::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ sal_Int32 nValue;
+ if (SvXMLUnitConverter::convertNumber(nValue, rStrImpValue))
+ {
+ nValue *= 100;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_RotateAngle::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Int32 nVal = 0;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ rtl::OUStringBuffer sValue;
+ SvXMLUnitConverter::convertNumber(sValue, sal_Int32(nVal / 100));
+ rStrExpValue = sValue.makeStringAndClear();
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_RotateReference::~XmlScPropHdl_RotateReference()
+{
+}
+
+bool XmlScPropHdl_RotateReference::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellVertJustify aReference1, aReference2;
+
+ if((r1 >>= aReference1) && (r2 >>= aReference2))
+ return (aReference1 == aReference2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_RotateReference::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ table::CellVertJustify nValue;
+ if (IsXMLToken(rStrImpValue, XML_NONE))
+ {
+ nValue = table::CellVertJustify_STANDARD;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_BOTTOM))
+ {
+ nValue = table::CellVertJustify_BOTTOM;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TOP))
+ {
+ nValue = table::CellVertJustify_TOP;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_CENTER))
+ {
+ nValue = table::CellVertJustify_CENTER;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_RotateReference::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellVertJustify nVal;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellVertJustify_BOTTOM :
+ {
+ rStrExpValue = GetXMLToken(XML_BOTTOM);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify_CENTER :
+ {
+ rStrExpValue = GetXMLToken(XML_CENTER);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify_STANDARD :
+ {
+ rStrExpValue = GetXMLToken(XML_NONE);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify_TOP :
+ {
+ rStrExpValue = GetXMLToken(XML_TOP);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_VertJustify::~XmlScPropHdl_VertJustify()
+{
+}
+
+bool XmlScPropHdl_VertJustify::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellVertJustify aReference1, aReference2;
+
+ if((r1 >>= aReference1) && (r2 >>= aReference2))
+ return (aReference1 == aReference2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_VertJustify::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ table::CellVertJustify nValue;
+ if (IsXMLToken(rStrImpValue, XML_AUTOMATIC))
+ {
+ nValue = table::CellVertJustify_STANDARD;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_BOTTOM))
+ {
+ nValue = table::CellVertJustify_BOTTOM;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TOP))
+ {
+ nValue = table::CellVertJustify_TOP;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_MIDDLE))
+ {
+ nValue = table::CellVertJustify_CENTER;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_VertJustify::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellVertJustify nVal;
+ sal_Bool bRetval(sal_False);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellVertJustify_BOTTOM :
+ {
+ rStrExpValue = GetXMLToken(XML_BOTTOM);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify_CENTER :
+ {
+ rStrExpValue = GetXMLToken(XML_MIDDLE);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify_STANDARD :
+ {
+ rStrExpValue = GetXMLToken(XML_AUTOMATIC);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify_TOP :
+ {
+ rStrExpValue = GetXMLToken(XML_TOP);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_BreakBefore::~XmlScPropHdl_BreakBefore()
+{
+}
+
+bool XmlScPropHdl_BreakBefore::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Bool aBreak1 = 0, aBreak2 = 0;
+
+ if((r1 >>= aBreak1) && (r2 >>= aBreak2))
+ return (aBreak1 == aBreak2);
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_BreakBefore::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ sal_Bool bValue;
+ if (IsXMLToken(rStrImpValue, XML_AUTO))
+ {
+ bValue = sal_False;
+ rValue = ::cppu::bool2any(bValue);
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_PAGE))
+ {
+ bValue = sal_True;
+ rValue = ::cppu::bool2any(bValue);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_BreakBefore::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if(::cppu::any2bool(rValue))
+ {
+ rStrExpValue = GetXMLToken(XML_PAGE);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_AUTO);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_IsTextWrapped::~XmlScPropHdl_IsTextWrapped()
+{
+}
+
+bool XmlScPropHdl_IsTextWrapped::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ return (::cppu::any2bool(r1) == ::cppu::any2bool(r2));
+}
+
+sal_Bool XmlScPropHdl_IsTextWrapped::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if (IsXMLToken(rStrImpValue, XML_WRAP))
+ {
+ rValue = ::cppu::bool2any(sal_True);
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_NO_WRAP))
+ {
+ rValue = ::cppu::bool2any(sal_False);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_IsTextWrapped::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if (::cppu::any2bool(rValue))
+ {
+ rStrExpValue = GetXMLToken(XML_WRAP);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_NO_WRAP);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_IsEqual::importXML( const ::rtl::OUString& /* rStrImpValue */,
+ ::com::sun::star::uno::Any& /* rValue */,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ DBG_ERROR("should never be called");
+ return sal_False;
+}
+
+sal_Bool XmlScPropHdl_IsEqual::exportXML( ::rtl::OUString& /* rStrExpValue */,
+ const ::com::sun::star::uno::Any& /* rValue */,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ DBG_ERROR("should never be called");
+ return sal_False;
+}
+
+XmlScPropHdl_Vertical::~XmlScPropHdl_Vertical()
+{
+}
+
+bool XmlScPropHdl_Vertical::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ return (::cppu::any2bool(r1) == ::cppu::any2bool(r2));
+}
+
+sal_Bool XmlScPropHdl_Vertical::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if (IsXMLToken(rStrImpValue, XML_AUTO))
+ {
+ rValue = ::cppu::bool2any(sal_True);
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_0))
+ {
+ rValue = ::cppu::bool2any(sal_False);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_Vertical::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(sal_False);
+
+ if (::cppu::any2bool(rValue))
+ {
+ rStrExpValue = GetXMLToken(XML_AUTO);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_0);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
diff --git a/sc/source/filter/xml/xmlstyle.hxx b/sc/source/filter/xml/xmlstyle.hxx
new file mode 100644
index 000000000000..f8abf5e6443d
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyle.hxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLE_HXX
+#define SC_XMLSTYLE_HXX
+
+#include <xmloff/maptype.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/xmltypes.hxx>
+#include <xmloff/xmlprmap.hxx>
+#include <xmloff/prhdlfac.hxx>
+#include <xmloff/styleexp.hxx>
+#include <xmloff/xmlexppr.hxx>
+#include <xmloff/contextid.hxx>
+
+extern const XMLPropertyMapEntry aXMLScCellStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScColumnStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScRowStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScRowStylesImportProperties[];
+extern const XMLPropertyMapEntry aXMLScTableStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScTableStylesImportProperties[];
+
+//CellStyles
+#define XML_SC_TYPE_CELLPROTECTION (XML_SC_TYPES_START + 1)
+#define XML_SC_TYPE_PRINTCONTENT (XML_SC_TYPES_START + 2)
+#define XML_SC_TYPE_HORIJUSTIFY (XML_SC_TYPES_START + 3)
+#define XML_SC_TYPE_HORIJUSTIFYSOURCE (XML_SC_TYPES_START + 4)
+#define XML_SC_TYPE_HORIJUSTIFYREPEAT (XML_SC_TYPES_START + 5)
+#define XML_SC_TYPE_ORIENTATION (XML_SC_TYPES_START + 6)
+#define XML_SC_TYPE_ROTATEANGLE (XML_SC_TYPES_START + 7)
+#define XML_SC_TYPE_ROTATEREFERENCE (XML_SC_TYPES_START + 8)
+#define XML_SC_TYPE_BORDERLEFT (XML_SC_TYPES_START + 9)
+#define XML_SC_TYPE_BORDERRIGHT (XML_SC_TYPES_START + 10)
+#define XML_SC_TYPE_BORDERTOP (XML_SC_TYPES_START + 11)
+#define XML_SC_TYPE_BORDERBOTTOM (XML_SC_TYPES_START + 12)
+#define XML_SC_TYPE_VERTJUSTIFY (XML_SC_TYPES_START + 13)
+#define XML_SC_ISTEXTWRAPPED (XML_SC_TYPES_START + 14)
+#define XML_SC_TYPE_EQUAL (XML_SC_TYPES_START + 15)
+#define XML_SC_TYPE_VERTICAL (XML_SC_TYPES_START + 16)
+
+#define CTF_SC_HORIJUSTIFY (XML_SC_CTF_START + 1)
+#define CTF_SC_HORIJUSTIFY_SOURCE (XML_SC_CTF_START + 2)
+#define CTF_SC_ALLPADDING (XML_SC_CTF_START + 3)
+#define CTF_SC_BOTTOMPADDING (XML_SC_CTF_START + 4)
+#define CTF_SC_LEFTPADDING (XML_SC_CTF_START + 5)
+#define CTF_SC_RIGHTPADDING (XML_SC_CTF_START + 6)
+#define CTF_SC_TOPPADDING (XML_SC_CTF_START + 7)
+#define CTF_SC_ALLBORDER (XML_SC_CTF_START + 8)
+#define CTF_SC_LEFTBORDER (XML_SC_CTF_START + 9)
+#define CTF_SC_RIGHTBORDER (XML_SC_CTF_START + 10)
+#define CTF_SC_TOPBORDER (XML_SC_CTF_START + 11)
+#define CTF_SC_BOTTOMBORDER (XML_SC_CTF_START + 12)
+#define CTF_SC_ALLBORDERWIDTH (XML_SC_CTF_START + 13)
+#define CTF_SC_LEFTBORDERWIDTH (XML_SC_CTF_START + 14)
+#define CTF_SC_RIGHTBORDERWIDTH (XML_SC_CTF_START + 15)
+#define CTF_SC_TOPBORDERWIDTH (XML_SC_CTF_START + 16)
+#define CTF_SC_BOTTOMBORDERWIDTH (XML_SC_CTF_START + 17)
+#define CTF_SC_NUMBERFORMAT (XML_SC_CTF_START + 18)
+#define CTF_SC_MAP (XML_SC_CTF_START + 19)
+#define CTF_SC_PARAINDENT (XML_SC_CTF_START + 20)
+#define CTF_SC_OLDTEXTBACKGROUND (XML_SC_CTF_START + 21)
+#define CTF_SC_IMPORT_MAP (XML_SC_CTF_START + 22)
+#define CTF_SC_CELLSTYLE (XML_SC_CTF_START + 23)
+#define CTF_SC_VALIDATION (XML_SC_CTF_START + 24)
+#define CTF_SC_DIAGONALTLBR (XML_SC_CTF_START + 25)
+#define CTF_SC_DIAGONALTLBRWIDTH (XML_SC_CTF_START + 26)
+#define CTF_SC_DIAGONALBLTR (XML_SC_CTF_START + 27)
+#define CTF_SC_DIAGONALBLTRWIDTH (XML_SC_CTF_START + 28)
+#define CTF_SC_DIAGONALTLBRWIDTHS (XML_SC_CTF_START + 29)
+#define CTF_SC_DIAGONALBLTRWIDTHS (XML_SC_CTF_START + 30)
+
+#define CTF_SC_ROWHEIGHT (XML_SC_CTF_START + 50)
+#define CTF_SC_ROWOPTIMALHEIGHT (XML_SC_CTF_START + 51)
+#define CTF_SC_ROWBREAKBEFORE (XML_SC_CTF_START + 52)
+#define CTF_SC_ISVISIBLE (XML_SC_CTF_START + 53)
+
+#define CTF_SC_MASTERPAGENAME (XML_SC_CTF_START + 53)
+
+//ColumnStyles
+#define XML_SC_TYPE_BREAKBEFORE (XML_SC_TYPES_START + 50)
+
+class ScXMLExport;
+class ScXMLImport;
+
+class ScXMLCellExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+protected:
+ /** Application-specific filter. By default do nothing. */
+ virtual void ContextFilter(
+ ::std::vector< XMLPropertyState >& rProperties,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > rPropSet ) const;
+public:
+ ScXMLCellExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLCellExportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+ virtual void handleSpecialItem(
+ SvXMLAttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties = 0,
+ sal_uInt32 nIdx = 0 ) const;
+};
+
+class ScXMLRowExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+protected:
+ /** Application-specific filter. By default do nothing. */
+ virtual void ContextFilter(
+ ::std::vector< XMLPropertyState >& rProperties,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > rPropSet ) const;
+public:
+ ScXMLRowExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLRowExportPropertyMapper();
+};
+
+class ScXMLColumnExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+public:
+ ScXMLColumnExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLColumnExportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+ virtual void handleSpecialItem(
+ SvXMLAttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties = 0,
+ sal_uInt32 nIdx = 0 ) const;
+};
+
+class ScXMLTableExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+protected:
+public:
+ ScXMLTableExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLTableExportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+ virtual void handleSpecialItem(
+ SvXMLAttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties = 0,
+ sal_uInt32 nIdx = 0 ) const;
+};
+
+class ScXMLAutoStylePoolP : public SvXMLAutoStylePoolP
+{
+ ScXMLExport& rScXMLExport;
+
+ virtual void exportStyleAttributes(
+ SvXMLAttributeList& rAttrList,
+ sal_Int32 nFamily,
+ const ::std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const;
+
+ virtual void exportStyleContent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
+ sal_Int32 nFamily,
+ const ::std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp
+ , const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const;
+
+public:
+ ScXMLAutoStylePoolP(ScXMLExport& rScXMLExport);
+ virtual ~ScXMLAutoStylePoolP();
+};
+
+class ScXMLStyleExport : public XMLStyleExport
+{
+ virtual void exportStyleAttributes(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & rStyle );
+ virtual void exportStyleContent(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & rStyle );
+public:
+ ScXMLStyleExport(
+ SvXMLExport& rExp,
+ const ::rtl::OUString& rPoolStyleName,
+ SvXMLAutoStylePoolP *pAutoStyleP=0 );
+ virtual ~ScXMLStyleExport();
+};
+
+class XMLScPropHdlFactory : public XMLPropertyHandlerFactory
+{
+public:
+ XMLScPropHdlFactory();
+ virtual ~XMLScPropHdlFactory();
+ virtual const XMLPropertyHandler* GetPropertyHandler( sal_Int32 nType ) const;
+};
+
+class XmlScPropHdl_CellProtection : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_CellProtection();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_PrintContent : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_PrintContent();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_HoriJustify : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_HoriJustify();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_HoriJustifySource : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_HoriJustifySource();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_HoriJustifyRepeat : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_HoriJustifyRepeat();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_Orientation : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_Orientation();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_RotateAngle : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_RotateAngle();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_RotateReference : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_RotateReference();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_VertJustify : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_VertJustify();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_BreakBefore : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_BreakBefore();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_IsTextWrapped : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_IsTextWrapped();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_IsEqual : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_IsEqual() {}
+ virtual bool equals( const ::com::sun::star::uno::Any& /* r1 */, const ::com::sun::star::uno::Any& /* r2 */ ) const { return sal_True; }
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_Vertical : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_Vertical();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx
new file mode 100644
index 000000000000..3866bba63239
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -0,0 +1,1087 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "xmlstyli.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmlimppr.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include <xmloff/XMLGraphicsDefaultStyle.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <comphelper/extract.hxx>
+#include <xmloff/xmlprcon.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <tools/debug.hxx>
+#include "XMLTableHeaderFooterContext.hxx"
+#include "XMLConverter.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "xmlannoi.hxx"
+#include "textuno.hxx"
+#include "cellsuno.hxx"
+
+#include "docuno.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+
+#define XML_LINE_LEFT 0
+#define XML_LINE_RIGHT 1
+#define XML_LINE_TOP 2
+#define XML_LINE_BOTTOM 3
+
+#define XML_LINE_TLBR 0
+#define XML_LINE_BLTR 1
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace xmloff::token;
+//using namespace ::com::sun::star::text;
+using namespace ::formula;
+
+ScXMLCellImportPropertyMapper::ScXMLCellImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImportP) :
+ SvXMLImportPropertyMapper( rMapper, rImportP )
+{
+}
+
+ScXMLCellImportPropertyMapper::~ScXMLCellImportPropertyMapper()
+{
+}
+
+void ScXMLCellImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
+{
+ static const sal_Int16 aPaddingCTF[4] = { CTF_SC_LEFTPADDING, CTF_SC_RIGHTPADDING,
+ CTF_SC_TOPPADDING, CTF_SC_BOTTOMPADDING };
+ static const sal_Int16 aBorderCTF[4] = { CTF_SC_LEFTBORDER, CTF_SC_RIGHTBORDER,
+ CTF_SC_TOPBORDER, CTF_SC_BOTTOMBORDER };
+
+ SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex);
+ XMLPropertyState* pAllPaddingProperty(NULL);
+ XMLPropertyState* pPadding[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pNewPadding[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pAllBorderProperty = NULL;
+ XMLPropertyState* pBorders[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pNewBorders[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pAllBorderWidthProperty = NULL;
+ XMLPropertyState* pBorderWidths[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pDiagBorders[2] = { 0 };
+ XMLPropertyState* pOldDiagBorderWidths[2] = { 0 }; // old attribute names without "s"
+ XMLPropertyState* pDiagBorderWidths[2] = { 0 };
+
+ ::std::vector< XMLPropertyState >::iterator endproperty(rProperties.end());
+ for (::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin();
+ aIter != endproperty; ++aIter)
+ {
+ XMLPropertyState*property = &(*aIter);
+ if (property->mnIndex != -1)
+ {
+ sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex);
+ switch (nContextID)
+ {
+ case CTF_SC_ALLPADDING : pAllPaddingProperty = &*property; break;
+ case CTF_SC_LEFTPADDING : pPadding[XML_LINE_LEFT] = &*property; break;
+ case CTF_SC_RIGHTPADDING : pPadding[XML_LINE_RIGHT] = &*property; break;
+ case CTF_SC_TOPPADDING : pPadding[XML_LINE_TOP] = &*property; break;
+ case CTF_SC_BOTTOMPADDING : pPadding[XML_LINE_BOTTOM] = &*property; break;
+ case CTF_SC_ALLBORDER : pAllBorderProperty = &*property; break;
+ case CTF_SC_LEFTBORDER : pBorders[XML_LINE_LEFT] = &*property; break;
+ case CTF_SC_RIGHTBORDER : pBorders[XML_LINE_RIGHT] = &*property; break;
+ case CTF_SC_TOPBORDER : pBorders[XML_LINE_TOP] = &*property; break;
+ case CTF_SC_BOTTOMBORDER : pBorders[XML_LINE_BOTTOM] = &*property; break;
+ case CTF_SC_ALLBORDERWIDTH : pAllBorderWidthProperty = &*property; break;
+ case CTF_SC_LEFTBORDERWIDTH : pBorderWidths[XML_LINE_LEFT] = &*property; break;
+ case CTF_SC_RIGHTBORDERWIDTH : pBorderWidths[XML_LINE_RIGHT] = &*property; break;
+ case CTF_SC_TOPBORDERWIDTH : pBorderWidths[XML_LINE_TOP] = &*property; break;
+ case CTF_SC_BOTTOMBORDERWIDTH : pBorderWidths[XML_LINE_BOTTOM] = &*property; break;
+ case CTF_SC_DIAGONALTLBR : pDiagBorders[XML_LINE_TLBR] = &*property; break;
+ case CTF_SC_DIAGONALBLTR : pDiagBorders[XML_LINE_BLTR] = &*property; break;
+ case CTF_SC_DIAGONALTLBRWIDTH : pOldDiagBorderWidths[XML_LINE_TLBR] = &*property; break;
+ case CTF_SC_DIAGONALTLBRWIDTHS : pDiagBorderWidths[XML_LINE_TLBR] = &*property; break;
+ case CTF_SC_DIAGONALBLTRWIDTH : pOldDiagBorderWidths[XML_LINE_BLTR] = &*property; break;
+ case CTF_SC_DIAGONALBLTRWIDTHS : pDiagBorderWidths[XML_LINE_BLTR] = &*property; break;
+ }
+ }
+ }
+ sal_uInt16 i;
+
+ // #i27594#; copy Value, but don't insert
+ if (pAllBorderWidthProperty)
+ pAllBorderWidthProperty->mnIndex = -1;
+ if (pAllBorderProperty)
+ pAllBorderProperty->mnIndex = -1;
+ if (pAllPaddingProperty)
+ pAllPaddingProperty->mnIndex = -1;
+
+ for (i = 0; i < 4; ++i)
+ {
+ if (pAllPaddingProperty && !pPadding[i])
+ pNewPadding[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aPaddingCTF[i]), pAllPaddingProperty->maValue);
+ if (pAllBorderProperty && !pBorders[i])
+ {
+ pNewBorders[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aBorderCTF[i]), pAllBorderProperty->maValue);
+ pBorders[i] = pNewBorders[i];
+ }
+ if( !pBorderWidths[i] )
+ pBorderWidths[i] = pAllBorderWidthProperty;
+ else
+ pBorderWidths[i]->mnIndex = -1;
+ if( pBorders[i] )
+ {
+ table::BorderLine aBorderLine;
+ pBorders[i]->maValue >>= aBorderLine;
+ if( pBorderWidths[i] )
+ {
+ table::BorderLine aBorderLineWidth;
+ pBorderWidths[i]->maValue >>= aBorderLineWidth;
+ aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
+ aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
+ aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
+ pBorders[i]->maValue <<= aBorderLine;
+ }
+ }
+ }
+ for( i = 0; i < 2; ++i )
+ {
+ if( pDiagBorders[i] && ( pDiagBorderWidths[i] || pOldDiagBorderWidths[i] ) )
+ {
+ table::BorderLine aBorderLine;
+ pDiagBorders[i]->maValue >>= aBorderLine;
+ table::BorderLine aBorderLineWidth;
+ if (pDiagBorderWidths[i])
+ pDiagBorderWidths[i]->maValue >>= aBorderLineWidth; // prefer new attribute
+ else
+ pOldDiagBorderWidths[i]->maValue >>= aBorderLineWidth;
+ aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
+ aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
+ aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
+ pDiagBorders[i]->maValue <<= aBorderLine;
+ if (pDiagBorderWidths[i])
+ pDiagBorderWidths[i]->mnIndex = -1;
+ if (pOldDiagBorderWidths[i])
+ pOldDiagBorderWidths[i]->mnIndex = -1; // reset mnIndex for old and new attribute if both are present
+ }
+ }
+
+ for (i = 0; i < 4; ++i)
+ {
+ if (pNewPadding[i])
+ {
+ rProperties.push_back(*pNewPadding[i]);
+ delete pNewPadding[i];
+ }
+ if (pNewBorders[i])
+ {
+ rProperties.push_back(*pNewBorders[i]);
+ delete pNewBorders[i];
+ }
+ }
+}
+
+ScXMLRowImportPropertyMapper::ScXMLRowImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImportP) :
+ SvXMLImportPropertyMapper( rMapper, rImportP )
+{
+}
+
+ScXMLRowImportPropertyMapper::~ScXMLRowImportPropertyMapper()
+{
+}
+
+void ScXMLRowImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
+{
+ SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex);
+ XMLPropertyState* pHeight(NULL);
+ XMLPropertyState* pOptimalHeight(NULL);
+ XMLPropertyState* pPageBreak(NULL);
+ ::std::vector< XMLPropertyState >::iterator endproperty(rProperties.end());
+ for (::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin();
+ aIter != endproperty; ++aIter)
+ {
+ XMLPropertyState* property = &(*aIter);
+ if (property->mnIndex != -1)
+ {
+ sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex);
+ switch (nContextID)
+ {
+ case CTF_SC_ROWHEIGHT : pHeight = property; break;
+ case CTF_SC_ROWOPTIMALHEIGHT : pOptimalHeight = property; break;
+ case CTF_SC_ROWBREAKBEFORE : pPageBreak = property; break;
+ }
+ }
+ }
+ if (pPageBreak)
+ {
+ if(!(::cppu::any2bool(pPageBreak->maValue)))
+ pPageBreak->mnIndex = -1;
+ }
+ if (pOptimalHeight)
+ {
+ if (::cppu::any2bool(pOptimalHeight->maValue))
+ {
+ if (pHeight)
+ {
+ // set the stored height, but keep "optimal" flag:
+ // pass the height value as OptimalHeight property (only allowed while loading!)
+ pOptimalHeight->maValue = pHeight->maValue;
+ pHeight->mnIndex = -1;
+ }
+ else
+ pOptimalHeight->mnIndex = -1;
+ }
+ }
+ else if (pHeight)
+ {
+ rProperties.push_back(XMLPropertyState(maPropMapper->FindEntryIndex(CTF_SC_ROWOPTIMALHEIGHT), ::cppu::bool2any( sal_False )));
+ }
+ // don't access pointers to rProperties elements after push_back!
+}
+
+class ScXMLMapContext : public SvXMLImportContext
+{
+ rtl::OUString sApplyStyle;
+ rtl::OUString sCondition;
+ rtl::OUString sBaseCell;
+public:
+
+ ScXMLMapContext(
+ SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const rtl::OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+ virtual ~ScXMLMapContext();
+
+ const rtl::OUString& GetApplyStyle() const { return sApplyStyle; }
+ const rtl::OUString& GetCondition() const { return sCondition; }
+ const rtl::OUString& GetBaseCell() const { return sBaseCell; }
+};
+
+ScXMLMapContext::ScXMLMapContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName, const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+ : SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ const OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ // TODO: use a map here
+ if( XML_NAMESPACE_STYLE == nPrefix )
+ {
+ if( IsXMLToken(aLocalName, XML_CONDITION ) )
+ sCondition = rValue;
+ else if( IsXMLToken(aLocalName, XML_APPLY_STYLE_NAME ) )
+ sApplyStyle = GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, rValue);
+ else if ( IsXMLToken(aLocalName, XML_BASE_CELL_ADDRESS ) )
+ sBaseCell = rValue;
+ }
+ }
+}
+
+ScXMLMapContext::~ScXMLMapContext()
+{
+}
+
+namespace {
+
+template< typename Type >
+inline void lclAppendProperty( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rPropName, const Type& rValue )
+{
+ sal_Int32 nLength = rProps.getLength();
+ rProps.realloc( nLength + 1 );
+ rProps[ nLength ].Name = rPropName;
+ rProps[ nLength ].Value <<= rValue;
+}
+
+} // namespace
+
+void XMLTableStyleContext::SetOperator( uno::Sequence< beans::PropertyValue >& rProps, sheet::ConditionOperator eOp ) const
+{
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_OPERATOR ) ), eOp );
+}
+
+void XMLTableStyleContext::SetBaseCellAddress( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rBaseCell ) const
+{
+ /* #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::SetStyle( uno::Sequence<beans::PropertyValue>& rProps, const OUString& rApplyStyle ) const
+{
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_STYLENAME ) ), rApplyStyle );
+}
+
+void XMLTableStyleContext::SetFormula( uno::Sequence< beans::PropertyValue >& rProps,
+ sal_Int32 nFormulaIdx, const OUString& rFormula, const OUString& rFormulaNmsp,
+ FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const
+{
+ OUString aFormula, aFormulaNmsp;
+ FormulaGrammar::Grammar eNewGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ if( bHasNmsp )
+ {
+ // the entire attribute contains a namespace: internal namespace not allowed
+ aFormula = rFormula;
+ aFormulaNmsp = rFormulaNmsp;
+ eNewGrammar = eGrammar;
+ }
+ else
+ {
+ // the attribute does not contain a namespace: try to find a namespace of an external grammar
+ GetScImport().ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eNewGrammar, rFormula, true );
+ if( eNewGrammar != FormulaGrammar::GRAM_EXTERNAL )
+ eNewGrammar = eGrammar;
+ }
+
+ // add formula, formula namespace, and grammar with appropriate property names
+ sal_Int32 nGrammar = static_cast< sal_Int32 >( eNewGrammar );
+ switch( nFormulaIdx )
+ {
+ case 1:
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA1 ) ), aFormula );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP1 ) ), aFormulaNmsp );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR1 ) ), nGrammar );
+ break;
+ case 2:
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA2 ) ), aFormula );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP2 ) ), aFormulaNmsp );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR2 ) ), nGrammar );
+ break;
+ default:
+ OSL_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
+{
+ if (sTempCondition.getLength() && sApplyStyle.getLength())
+ {
+ uno::Reference<sheet::XSheetConditionalEntries> xConditionalEntries(aAny, uno::UNO_QUERY);
+ if (xConditionalEntries.is())
+ {
+ uno::Sequence<beans::PropertyValue> aProps;
+ if (sBaseCell.getLength())
+ SetBaseCellAddress(aProps, sBaseCell);
+ SetStyle(aProps, sApplyStyle);
+
+ // extract leading namespace from condition string
+ OUString aCondition, aConditionNmsp;
+ FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sTempCondition );
+ bool bHasNmsp = aCondition.getLength() < sTempCondition.getLength();
+
+ // parse a condition from the attribute string
+ ScXMLConditionParseResult aParseResult;
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
+
+ /* Check the result. A valid value in aParseResult.meToken implies
+ that the other members of aParseResult are filled with valid
+ data for that token. */
+ switch( aParseResult.meToken )
+ {
+ case XML_COND_CELLCONTENT: // condition is 'cell-content()<operator><expression>'
+ case XML_COND_ISTRUEFORMULA: // condition is 'is-true-formula(<expression>)'
+ case XML_COND_ISBETWEEN: // condition is 'cell-content-is-between(<expression1>,<expression2>)'
+ case XML_COND_ISNOTBETWEEN: // condition is 'cell-content-is-not-between(<expression1>,<expression2>)'
+ SetOperator( aProps, aParseResult.meOperator );
+ SetFormula( aProps, 1, aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp );
+ SetFormula( aProps, 2, aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp );
+ break;
+
+ default:; // unacceptable or unknown condition
+ }
+
+ xConditionalEntries->addNew( aProps );
+ aAny <<= xConditionalEntries;
+ }
+ }
+}
+
+void XMLTableStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
+ const OUString& rLocalName,
+ const OUString& rValue )
+{
+ // TODO: use a map here
+ if( IsXMLToken(rLocalName, XML_DATA_STYLE_NAME ) )
+ sDataStyleName = rValue;
+ else if ( IsXMLToken(rLocalName, XML_MASTER_PAGE_NAME ) )
+ sPageStyle = rValue;
+ else
+ XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
+}
+
+struct ScXMLMapContent
+{
+ rtl::OUString sCondition;
+ rtl::OUString sApplyStyle;
+ rtl::OUString sBaseCell;
+};
+
+TYPEINIT1( XMLTableStyleContext, XMLPropStyleContext );
+
+XMLTableStyleContext::XMLTableStyleContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) :
+ XMLPropStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ),
+ sDataStyleName(),
+ sNumberFormat(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))),
+ pStyles(&rStyles),
+ nNumberFormat(-1),
+ nLastSheet(-1),
+ bConditionalFormatCreated(sal_False),
+ bParentSet(sal_False)
+{
+}
+
+XMLTableStyleContext::~XMLTableStyleContext()
+{
+}
+
+SvXMLImportContext *XMLTableStyleContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext(NULL);
+
+ if( (XML_NAMESPACE_STYLE == nPrefix) &&
+ IsXMLToken(rLocalName, XML_MAP ) )
+ {
+ pContext = new ScXMLMapContext(GetImport(), nPrefix, rLocalName, xAttrList);
+
+ ScXMLMapContent aMap;
+ aMap.sCondition = ((ScXMLMapContext*)pContext)->GetCondition();
+ aMap.sApplyStyle = ((ScXMLMapContext*)pContext)->GetApplyStyle();
+ aMap.sBaseCell = ((ScXMLMapContext*)pContext)->GetBaseCell();
+ aMaps.push_back(aMap);
+ }
+ if (!pContext)
+ pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName,
+ xAttrList );
+ return pContext;
+}
+
+void XMLTableStyleContext::FillPropertySet(
+ const uno::Reference< XPropertySet > & rPropSet )
+{
+ if (!IsDefaultStyle())
+ {
+ if (GetFamily() == XML_STYLE_FAMILY_TABLE_CELL)
+ {
+ if (!bParentSet)
+ {
+ AddProperty(CTF_SC_CELLSTYLE, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, GetParentName() )));
+ bParentSet = sal_True;
+ }
+ sal_Int32 nNumFmt = GetNumberFormat();
+ if (nNumFmt >= 0)
+ AddProperty(CTF_SC_NUMBERFORMAT, uno::makeAny(nNumFmt));
+ if (!bConditionalFormatCreated && (aMaps.size() > 0))
+ {
+ aConditionalFormat = rPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONDXML)));
+ std::vector<ScXMLMapContent>::iterator aItr(aMaps.begin());
+ std::vector<ScXMLMapContent>::iterator aEndItr(aMaps.end());
+ while(aItr != aEndItr)
+ {
+ //rPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CONDITIONALFORMAT)),
+ GetConditionalFormat(aConditionalFormat, aItr->sCondition, aItr->sApplyStyle, aItr->sBaseCell);
+
+ ++aItr;
+ }
+ AddProperty(CTF_SC_IMPORT_MAP, aConditionalFormat);
+ bConditionalFormatCreated = sal_True;
+ }
+ }
+ else if (GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE)
+ {
+ if (sPageStyle.getLength())
+ AddProperty(CTF_SC_MASTERPAGENAME, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle )));
+ }
+ }
+ XMLPropStyleContext::FillPropertySet(rPropSet);
+}
+
+void XMLTableStyleContext::SetDefaults()
+{
+ if ((GetFamily() == XML_STYLE_FAMILY_TABLE_CELL) && GetImport().GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetImport().GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY);
+ if (xProperties.is())
+ FillPropertySet(xProperties);
+ }
+ }
+}
+
+void XMLTableStyleContext::AddProperty(const sal_Int16 nContextID, const uno::Any& rValue)
+{
+ XMLPropertyState* property = FindProperty(nContextID);
+ if (property)
+ property->mnIndex = -1; // #i46996# remove old property, so it isn't double
+ sal_Int32 nIndex(static_cast<XMLTableStylesContext *>(pStyles)->GetIndex(nContextID));
+ DBG_ASSERT(nIndex != -1, "Property not found in Map");
+ XMLPropertyState aPropState(nIndex, rValue);
+ GetProperties().push_back(aPropState); // has to be insertes in a sort order later
+}
+
+XMLPropertyState* XMLTableStyleContext::FindProperty(const sal_Int16 nContextID)
+{
+ XMLPropertyState* pRet = NULL;
+ UniReference < XMLPropertySetMapper > xPrMap;
+ UniReference < SvXMLImportPropertyMapper > xImpPrMap =
+ pStyles->GetImportPropertyMapper( GetFamily() );
+ DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" );
+ if( xImpPrMap.is() )
+ xPrMap = xImpPrMap->getPropertySetMapper();
+ if( xPrMap.is() )
+ {
+ ::std::vector< XMLPropertyState >::iterator endproperty(GetProperties().end());
+ ::std::vector< XMLPropertyState >::iterator aIter(GetProperties().begin());
+ while(!pRet && aIter != endproperty)
+ {
+ XMLPropertyState* property = &(*aIter);
+ if (property->mnIndex != -1 && xPrMap->GetEntryContextId(property->mnIndex) == nContextID)
+ {
+ pRet = property;
+ }
+ else
+ ++aIter;
+ }
+ }
+ return pRet;
+}
+
+sal_Int32 XMLTableStyleContext::GetNumberFormat()
+{
+ if (nNumberFormat < 0 && sDataStyleName.getLength())
+ {
+ const SvXMLNumFormatContext* pStyle = static_cast<const SvXMLNumFormatContext*>(
+ pStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, sal_True));
+
+ if (!pStyle)
+ {
+ XMLTableStylesContext* pMyStyles = static_cast<XMLTableStylesContext*>(GetScImport().GetStyles());
+ if (pMyStyles)
+ pStyle = static_cast<const SvXMLNumFormatContext*>(
+ pMyStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, sal_True));
+ else
+ {
+ DBG_ERROR("not possible to get style");
+ }
+ }
+ if (pStyle)
+ nNumberFormat = const_cast<SvXMLNumFormatContext*>(pStyle)->GetKey();
+ }
+ return nNumberFormat;
+}
+
+// ----------------------------------------------------------------------------
+
+SvXMLStyleContext *XMLTableStylesContext::CreateStyleStyleChildContext(
+ sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLStyleContext *pStyle;
+ // use own wrapper for text and paragraph, to record style usage
+ if (nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH || nFamily == XML_STYLE_FAMILY_TEXT_TEXT)
+ pStyle = new ScCellTextStyleContext( GetImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily );
+ else
+ pStyle = SvXMLStylesContext::CreateStyleStyleChildContext(
+ nFamily, nPrefix, rLocalName, xAttrList );
+
+ if (!pStyle)
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily );
+ break;
+ }
+ }
+
+ return pStyle;
+}
+
+SvXMLStyleContext *XMLTableStylesContext::CreateDefaultStyleStyleChildContext(
+ sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLStyleContext *pStyle(SvXMLStylesContext::CreateDefaultStyleStyleChildContext( nFamily, nPrefix,
+ rLocalName,
+ xAttrList ));
+ if (!pStyle)
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily, sal_True);
+ break;
+ case XML_STYLE_FAMILY_SD_GRAPHICS_ID:
+ pStyle = new XMLGraphicsDefaultStyle( GetScImport(), nPrefix, rLocalName,
+ xAttrList, *this);
+ break;
+ }
+ }
+
+ return pStyle;
+}
+
+XMLTableStylesContext::XMLTableStylesContext( SvXMLImport& rImport,
+ sal_uInt16 nPrfx ,
+ const OUString& rLName ,
+ const uno::Reference< XAttributeList > & xAttrList,
+ const sal_Bool bTempAutoStyles ) :
+ SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ),
+ sCellStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CellStyle" ) )),
+ sColumnStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME ))),
+ sRowStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME ))),
+ sTableStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME ))),
+ nNumberFormatIndex(-1),
+ nConditionalFormatIndex(-1),
+ nCellStyleIndex(-1),
+ nMasterPageNameIndex(-1),
+ bAutoStyles(bTempAutoStyles)
+{
+}
+
+XMLTableStylesContext::~XMLTableStylesContext()
+{
+}
+
+void XMLTableStylesContext::EndElement()
+{
+ SvXMLStylesContext::EndElement();
+ if (bAutoStyles)
+ GetImport().GetTextImport()->SetAutoStyles( this );
+ else
+ ((ScXMLImport&)GetImport()).InsertStyles();
+}
+
+UniReference < SvXMLImportPropertyMapper >
+ XMLTableStylesContext::GetImportPropertyMapper(
+ sal_uInt16 nFamily ) const
+{
+ UniReference < SvXMLImportPropertyMapper > xMapper(SvXMLStylesContext::GetImportPropertyMapper(nFamily));
+
+ if (!xMapper.is())
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ {
+ if( !xCellImpPropMapper.is() )
+ {
+ ((XMLTableStylesContext *)this)->xCellImpPropMapper =
+ new ScXMLCellImportPropertyMapper( GetScImport().GetCellStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xCellImpPropMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(const_cast<SvXMLImport&>(GetImport()), const_cast<XMLFontStylesContext*>(GetScImport().GetFontDecls())));
+ }
+ xMapper = xCellImpPropMapper;
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ {
+ if( !xColumnImpPropMapper.is() )
+ ((XMLTableStylesContext *)this)->xColumnImpPropMapper =
+ new SvXMLImportPropertyMapper( GetScImport().GetColumnStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xMapper = xColumnImpPropMapper;
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ {
+ if( !xRowImpPropMapper.is() )
+ ((XMLTableStylesContext *)this)->xRowImpPropMapper =
+ new ScXMLRowImportPropertyMapper( GetScImport().GetRowStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xMapper = xRowImpPropMapper;
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ {
+ if( !xTableImpPropMapper.is() )
+ ((XMLTableStylesContext *)this)->xTableImpPropMapper =
+ new SvXMLImportPropertyMapper( GetScImport().GetTableStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xMapper = xTableImpPropMapper;
+ }
+ break;
+ }
+ }
+
+ return xMapper;
+}
+
+uno::Reference < XNameContainer >
+ XMLTableStylesContext::GetStylesContainer( sal_uInt16 nFamily ) const
+{
+ uno::Reference < XNameContainer > xStyles(SvXMLStylesContext::GetStylesContainer(nFamily));
+ if (!xStyles.is())
+ {
+ OUString sName;
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ {
+ if( xTableStyles.is() )
+ xStyles.set(xTableStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "TableStyles" ) ));
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ {
+ if( xCellStyles.is() )
+ xStyles.set(xCellStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CellStyles" ) ));
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ {
+ if( xColumnStyles.is() )
+ xStyles.set(xColumnStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnStyles" ) ));
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ {
+ if( xRowStyles.is() )
+ xStyles.set(xRowStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowStyles" ) ));
+ }
+ break;
+ }
+ if( !xStyles.is() && sName.getLength() && GetScImport().GetModel().is() )
+ {
+ uno::Reference< XStyleFamiliesSupplier > xFamiliesSupp(
+ GetScImport().GetModel(), UNO_QUERY );
+ if (xFamiliesSupp.is())
+ {
+ uno::Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies());
+
+ try
+ {
+ xStyles.set(xFamilies->getByName( sName ), uno::UNO_QUERY);
+ }
+ catch ( uno::Exception& )
+ {
+ // #i97680# Named table/column/row styles aren't supported, getByName will throw an exception.
+ // For better interoperability, these styles should then be handled as automatic styles.
+ // For now, NULL is returned (and the style is ignored).
+ }
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ ((XMLTableStylesContext *)this)->xTableStyles.set(xStyles);
+ break;
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ ((XMLTableStylesContext *)this)->xCellStyles.set(xStyles);
+ break;
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ ((XMLTableStylesContext *)this)->xColumnStyles.set(xStyles);
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ ((XMLTableStylesContext *)this)->xRowStyles.set(xStyles);
+ break;
+ }
+ }
+ }
+ }
+
+ return xStyles;
+}
+
+OUString XMLTableStylesContext::GetServiceName( sal_uInt16 nFamily ) const
+{
+ rtl::OUString sServiceName(SvXMLStylesContext::GetServiceName(nFamily));
+ if (!sServiceName.getLength())
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ sServiceName = sColumnStyleServiceName;
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ sServiceName = sRowStyleServiceName;
+ break;
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ sServiceName = sCellStyleServiceName;
+ break;
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ sServiceName = sTableStyleServiceName;
+ break;
+ }
+ }
+ return sServiceName;
+}
+
+sal_Int32 XMLTableStylesContext::GetIndex(const sal_Int16 nContextID)
+{
+ if (nContextID == CTF_SC_CELLSTYLE)
+ {
+ if (nCellStyleIndex == -1)
+ nCellStyleIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nCellStyleIndex;
+ }
+ else if (nContextID == CTF_SC_NUMBERFORMAT)
+ {
+ if (nNumberFormatIndex == -1)
+ nNumberFormatIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nNumberFormatIndex;
+ }
+ else if (nContextID == CTF_SC_IMPORT_MAP)
+ {
+ if (nConditionalFormatIndex == -1)
+ nConditionalFormatIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nConditionalFormatIndex;
+ }
+ else if (nContextID == CTF_SC_MASTERPAGENAME)
+ {
+ if (nMasterPageNameIndex == -1)
+ nMasterPageNameIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_TABLE)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nMasterPageNameIndex;
+ }
+ else
+ return -1;
+}
+
+// ---------------------------------------------------------------------------
+TYPEINIT1( ScXMLMasterStylesContext, SvXMLStylesContext );
+
+sal_Bool ScXMLMasterStylesContext::InsertStyleFamily( sal_uInt16 ) const
+{
+ return sal_True;
+}
+
+ScXMLMasterStylesContext::ScXMLMasterStylesContext(
+ SvXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< XAttributeList > & xAttrList ) :
+ SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList )
+{
+}
+
+ScXMLMasterStylesContext::~ScXMLMasterStylesContext()
+{
+}
+
+SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< XAttributeList > & xAttrList )
+{
+ SvXMLStyleContext *pContext(0);
+
+ if( (XML_NAMESPACE_STYLE == nPrefix) &&
+ IsXMLToken(rLocalName, XML_MASTER_PAGE) &&
+ InsertStyleFamily( XML_STYLE_FAMILY_MASTER_PAGE ) )
+ pContext = new ScMasterPageContext(
+ GetImport(), nPrefix, rLocalName, xAttrList,
+ !GetImport().GetTextImport()->IsInsertMode() );
+
+ // any other style will be ignored here!
+
+ return pContext;
+}
+
+SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleStyleChildContext(
+ sal_uInt16 /* nFamily */,
+ sal_uInt16 /* nPrefix */,
+ const OUString& /* rLocalName */,
+ const uno::Reference< XAttributeList > & /* xAttrList */ )
+{
+ return 0;
+}
+
+void ScXMLMasterStylesContext::EndElement()
+{
+ FinishStyles(sal_True);
+}
+
+TYPEINIT1( ScMasterPageContext, XMLTextMasterPageContext );
+
+ScMasterPageContext::ScMasterPageContext( SvXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< XAttributeList > & xAttrList,
+ sal_Bool bOverwrite ) :
+ XMLTextMasterPageContext( rImport, nPrfx, rLName, xAttrList, bOverwrite ),
+ bContainsRightHeader(sal_False),
+ bContainsRightFooter(sal_False)
+{
+}
+
+ScMasterPageContext::~ScMasterPageContext()
+{
+}
+
+SvXMLImportContext *ScMasterPageContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< XAttributeList > & xAttrList )
+{
+ return XMLTextMasterPageContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
+}
+
+SvXMLImportContext *ScMasterPageContext::CreateHeaderFooterContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const sal_Bool bFooter,
+ const sal_Bool bLeft )
+{
+ if (!bLeft)
+ {
+ if (bFooter)
+ bContainsRightFooter = sal_True;
+ else
+ bContainsRightHeader = sal_True;
+ }
+ if (!xPropSet.is())
+ xPropSet.set(GetStyle(), UNO_QUERY );
+ return new XMLTableHeaderFooterContext( GetImport(),
+ nPrefix, rLocalName,
+ xAttrList,
+ xPropSet,
+ bFooter, bLeft );
+}
+
+void ScMasterPageContext::ClearContent(const rtl::OUString& rContent)
+{
+ if (!xPropSet.is())
+ xPropSet.set(GetStyle(), UNO_QUERY );
+
+ if (xPropSet.is())
+ {
+ uno::Reference < sheet::XHeaderFooterContent > xHeaderFooterContent(xPropSet->getPropertyValue( rContent ), uno::UNO_QUERY);
+ if (xHeaderFooterContent.is())
+ {
+ xHeaderFooterContent->getLeftText()->setString(sEmpty);
+ xHeaderFooterContent->getCenterText()->setString(sEmpty);
+ xHeaderFooterContent->getRightText()->setString(sEmpty);
+ xPropSet->setPropertyValue( rContent, uno::makeAny(xHeaderFooterContent) );
+ }
+ }
+}
+
+void ScMasterPageContext::Finish( sal_Bool bOverwrite )
+{
+ XMLTextMasterPageContext::Finish(bOverwrite);
+ if (!bContainsRightFooter)
+ ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTFTRCON)));
+ if (!bContainsRightHeader)
+ ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTHDRCON)));
+}
+
+// ---------------------------------------------------------------------------
+
+ScCellTextStyleContext::ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const rtl::OUString& rLName, const uno::Reference<xml::sax::XAttributeList> & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) :
+ XMLTextStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ),
+ nLastSheet(-1)
+{
+}
+
+ScCellTextStyleContext::~ScCellTextStyleContext()
+{
+}
+
+void ScCellTextStyleContext::FillPropertySet( const uno::Reference<beans::XPropertySet>& xPropSet )
+{
+ XMLTextStyleContext::FillPropertySet( xPropSet );
+
+ ScXMLImport& rXMLImport = GetScImport();
+
+ ScCellTextCursor* pCellImp = ScCellTextCursor::getImplementation( xPropSet );
+ if (pCellImp)
+ {
+ ScAddress aPos = pCellImp->GetCellObj().GetPosition();
+ if ( static_cast<sal_Int32>(aPos.Tab()) != nLastSheet )
+ {
+ ESelection aSel = pCellImp->GetSelection();
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
+ pSheetData->AddTextStyle( GetName(), aPos, aSel );
+
+ nLastSheet = static_cast<sal_Int32>(aPos.Tab());
+ }
+ }
+ else if ( rXMLImport.GetTables().GetCurrentSheet() != nLastSheet )
+ {
+ ScDrawTextCursor* pDrawImp = ScDrawTextCursor::getImplementation( xPropSet );
+ if (pDrawImp)
+ {
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ ScXMLAnnotationContext* pAnnotationContext = pTableShapeImport->GetAnnotationContext();
+ if (pAnnotationContext)
+ {
+ pAnnotationContext->AddContentStyle( GetFamily(), GetName(), pDrawImp->GetSelection() );
+ nLastSheet = rXMLImport.GetTables().GetCurrentSheet();
+ }
+ }
+
+ // if it's a different shape, BlockSheet is called from XMLTableShapeImportHelper::finishShape
+ // formatted text in page headers/footers can be ignored
+ }
+}
+
diff --git a/sc/source/filter/xml/xmlstyli.hxx b/sc/source/filter/xml/xmlstyli.hxx
new file mode 100644
index 000000000000..b2a8589f5524
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyli.hxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLI_HXX
+#define SC_XMLSTYLI_HXX
+
+#include <rtl/ustring.hxx>
+#include <vector>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/maptype.hxx>
+#include <xmloff/prstylei.hxx>
+#include <xmloff/xmlimppr.hxx>
+#include <xmloff/XMLTextMasterPageContext.hxx>
+#include <xmloff/XMLTextMasterStylesContext.hxx>
+#include <xmloff/txtstyli.hxx>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include "xmlimprt.hxx"
+
+class ScSheetSaveData;
+
+class ScXMLCellImportPropertyMapper : public SvXMLImportPropertyMapper
+{
+protected:
+
+public:
+
+ ScXMLCellImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImport);
+ virtual ~ScXMLCellImportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */
+/* virtual sal_Bool handleSpecialItem(
+ XMLPropertyState& rProperty,
+ ::std::vector< XMLPropertyState >& rProperties,
+ const ::rtl::OUString& rValue,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap ) const;*/
+
+ /** this method is called for every item that has the MID_FLAG_NO_ITEM_IMPORT flag set */
+/* virtual sal_Bool handleNoItem(
+ sal_Int32 nIndex,
+ ::std::vector< XMLPropertyState >& rProperties,
+ const ::rtl::OUString& rValue,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap ) const;*/
+
+ /** This method is called when all attributes have been processed. It may be used to remove items that are incomplete */
+ virtual void finished(
+ ::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const;
+};
+
+class ScXMLRowImportPropertyMapper : public SvXMLImportPropertyMapper
+{
+protected:
+
+public:
+
+ ScXMLRowImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImport);
+ virtual ~ScXMLRowImportPropertyMapper();
+
+ /** This method is called when all attributes have been processed. It may be used to remove items that are incomplete */
+ virtual void finished(
+ ::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const;
+};
+struct ScXMLMapContent;
+
+class XMLTableStyleContext : public XMLPropStyleContext
+{
+ ::rtl::OUString sDataStyleName;
+ rtl::OUString sPageStyle;
+ const rtl::OUString sNumberFormat;
+ SvXMLStylesContext* pStyles;
+ std::vector<ScXMLMapContent> aMaps;
+ com::sun::star::uno::Any aConditionalFormat;
+ sal_Int32 nNumberFormat;
+ sal_Int32 nLastSheet;
+ sal_Bool bConditionalFormatCreated;
+ sal_Bool bParentSet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ void SetOperator(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ ::com::sun::star::sheet::ConditionOperator eOp ) const;
+
+ void SetBaseCellAddress(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ const ::rtl::OUString& rBaseCell ) const;
+
+ void SetStyle(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ const ::rtl::OUString& rApplyStyle ) const;
+
+ void SetFormula(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ sal_Int32 nFormulaIdx, const ::rtl::OUString& rFormula,
+ const ::rtl::OUString& rFormulaNmsp, ::formula::FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const;
+
+ void GetConditionalFormat(
+ ::com::sun::star::uno::Any& aAny, const rtl::OUString& sCondition,
+ const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const;
+protected:
+
+ virtual void SetAttribute( sal_uInt16 nPrefixKey,
+ const ::rtl::OUString& rLocalName,
+ const ::rtl::OUString& rValue );
+
+public:
+
+ TYPEINFO();
+
+ XMLTableStyleContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle = sal_False );
+ virtual ~XMLTableStyleContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual void FillPropertySet(const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet );
+
+ virtual void SetDefaults();
+
+ void AddProperty(sal_Int16 nContextID, const com::sun::star::uno::Any& aValue);
+ XMLPropertyState* FindProperty(const sal_Int16 nContextID);
+
+ sal_Int32 GetNumberFormat();// { return nNumberFormat; }
+
+ sal_Int32 GetLastSheet() const { return nLastSheet; }
+ void SetLastSheet(sal_Int32 nNew) { nLastSheet = nNew; }
+
+private:
+ using XMLPropStyleContext::SetStyle;
+};
+
+class XMLTableStylesContext : public SvXMLStylesContext
+{
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xCellStyles;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xColumnStyles;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xRowStyles;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xTableStyles;
+ const ::rtl::OUString sCellStyleServiceName;
+ const ::rtl::OUString sColumnStyleServiceName;
+ const ::rtl::OUString sRowStyleServiceName;
+ const ::rtl::OUString sTableStyleServiceName;
+ sal_Int32 nNumberFormatIndex;
+ sal_Int32 nConditionalFormatIndex;
+ sal_Int32 nCellStyleIndex;
+ sal_Int32 nMasterPageNameIndex;
+ sal_Bool bAutoStyles;
+
+ UniReference < SvXMLImportPropertyMapper > xCellImpPropMapper;
+ UniReference < SvXMLImportPropertyMapper > xColumnImpPropMapper;
+ UniReference < SvXMLImportPropertyMapper > xRowImpPropMapper;
+ UniReference < SvXMLImportPropertyMapper > xTableImpPropMapper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+protected:
+
+ // Create a style context.
+ virtual SvXMLStyleContext *CreateStyleStyleChildContext(
+ sal_uInt16 nFamily,
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual SvXMLStyleContext *CreateDefaultStyleStyleChildContext(
+ sal_uInt16 nFamily, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+// virtual SvXMLImportPropertyMapper *GetImpPropMapper();
+
+public:
+
+ XMLTableStylesContext( SvXMLImport& rImport, sal_uInt16 nPrfx ,
+ const ::rtl::OUString& rLName ,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const sal_Bool bAutoStyles );
+ virtual ~XMLTableStylesContext();
+
+ // Create child element.
+/* virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );*/
+
+ virtual void EndElement();
+
+ virtual UniReference < SvXMLImportPropertyMapper > GetImportPropertyMapper(
+ sal_uInt16 nFamily ) const;
+ virtual ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer >
+ GetStylesContainer( sal_uInt16 nFamily ) const;
+ virtual ::rtl::OUString GetServiceName( sal_uInt16 nFamily ) const;
+
+ sal_Int32 GetIndex(const sal_Int16 nContextID);
+};
+
+class ScXMLMasterStylesContext : public SvXMLStylesContext
+{
+protected:
+ virtual SvXMLStyleContext *CreateStyleChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual SvXMLStyleContext *CreateStyleStyleChildContext( sal_uInt16 nFamily,
+ sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual sal_Bool InsertStyleFamily( sal_uInt16 nFamily ) const;
+
+public:
+ TYPEINFO();
+
+ ScXMLMasterStylesContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList);
+
+ virtual ~ScXMLMasterStylesContext();
+ virtual void EndElement();
+};
+
+namespace com { namespace sun { namespace star {
+ namespace style { class XStyle; }
+} } }
+
+class ScMasterPageContext : public XMLTextMasterPageContext
+{
+ com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet;
+ const rtl::OUString sEmpty;
+ sal_Bool bContainsRightHeader;
+ sal_Bool bContainsRightFooter;
+
+ void ClearContent(const rtl::OUString& rContent);
+public:
+
+ TYPEINFO();
+
+ ScMasterPageContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ sal_Bool bOverwrite );
+ virtual ~ScMasterPageContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual SvXMLImportContext *CreateHeaderFooterContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const sal_Bool bFooter,
+ const sal_Bool bLeft );
+
+ virtual void Finish( sal_Bool bOverwrite );
+};
+
+class ScCellTextStyleContext : public XMLTextStyleContext
+{
+ sal_Int32 nLastSheet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
+ sal_Bool bDefaultStyle = sal_False );
+ virtual ~ScCellTextStyleContext();
+
+ // overload FillPropertySet to store style information
+ virtual void FillPropertySet(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet );
+};
+
+
+#endif
+
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
new file mode 100644
index 000000000000..89077eb4bee9
--- /dev/null
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -0,0 +1,833 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "xmlsubti.hxx"
+#include "global.hxx"
+#include "xmlstyli.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "markdata.hxx"
+#include "XMLConverter.hxx"
+#include "docuno.hxx"
+#include "cellsuno.hxx"
+#include "XMLStylesImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "tabprotection.hxx"
+#include <svx/svdpage.hxx>
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/CellInsertMode.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+
+#include <memory>
+
+using ::std::auto_ptr;
+
+//------------------------------------------------------------------
+
+using namespace com::sun::star;
+
+ScMyTableData::ScMyTableData(sal_Int32 nSheet, sal_Int32 nCol, sal_Int32 nRow)
+ : nColsPerCol(nDefaultColCount, 1),
+ nRealCols(nDefaultColCount + 1, 0),
+ nRowsPerRow(nDefaultRowCount, 1),
+ nRealRows(nDefaultRowCount + 1, 0),
+ nChangedCols()
+{
+ aTableCellPos.Sheet = sal::static_int_cast<sal_Int16>( nSheet );
+ aTableCellPos.Column = nCol;
+ aTableCellPos.Row = nRow;
+
+ for (sal_Int32 i = 0; i < 3; ++i)
+ nRealCols[i] = i;
+ for (sal_Int32 j = 0; j < 3; ++j)
+ nRealRows[j] = j;
+
+ nSpannedCols = 1;
+ nColCount = 0;
+ nSubTableSpanned = 1;
+}
+
+ScMyTableData::~ScMyTableData()
+{
+}
+
+void ScMyTableData::AddRow()
+{
+ ++aTableCellPos.Row;
+ if (static_cast<sal_uInt32>(aTableCellPos.Row) >= nRowsPerRow.size())
+ {
+ nRowsPerRow.resize(nRowsPerRow.size() + nDefaultRowCount, 1);
+ nRealRows.resize(nRowsPerRow.size() + nDefaultRowCount + 1, 0);
+ }
+ nRealRows[aTableCellPos.Row + 1] = nRealRows[aTableCellPos.Row] + nRowsPerRow[aTableCellPos.Row];
+}
+
+void ScMyTableData::AddColumn()
+{
+ ++aTableCellPos.Column;
+ if (static_cast<sal_uInt32>(aTableCellPos.Column) >= nColsPerCol.size())
+ {
+ nColsPerCol.resize(nColsPerCol.size() + nDefaultColCount, 1);
+ nRealCols.resize(nColsPerCol.size() + nDefaultColCount + 1, 0);
+ }
+ nRealCols[aTableCellPos.Column + 1] = nRealCols[aTableCellPos.Column] + nColsPerCol[aTableCellPos.Column];
+}
+
+sal_Int32 ScMyTableData::GetRealCols(const sal_Int32 nIndex, const sal_Bool /* bIsNormal */) const
+{
+ return (nIndex < 0) ? 0 : nRealCols[nIndex];
+}
+
+sal_Int32 ScMyTableData::GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const
+{
+ ScMysalIntList::const_iterator i(nChangedCols.begin());
+ ScMysalIntList::const_iterator endi(nChangedCols.end());
+ while ((i != endi) && ((*i < nToIndex) && !(*i >= nFromIndex)))
+ ++i;
+ if (i == endi)
+ return -1;
+ else
+ if ((*i >= nFromIndex) && (*i < nToIndex))
+ return *i;
+ else
+ return -1;
+}
+
+void ScMyTableData::SetChangedCols(const sal_Int32 nValue)
+{
+ ScMysalIntList::iterator i(nChangedCols.begin());
+ ScMysalIntList::iterator endi(nChangedCols.end());
+ while ((i != endi) && (*i < nValue))
+ {
+ ++i;
+ }
+ if ((i == endi) || (*i != nValue))
+ nChangedCols.insert(i, nValue);
+}
+
+/*******************************************************************************************************************************/
+
+ScMyTables::ScMyTables(ScXMLImport& rTempImport)
+ : rImport(rTempImport),
+ aResizeShapes(rTempImport),
+ nCurrentColStylePos(0),
+ nCurrentDrawPage( -1 ),
+ nCurrentXShapes( -1 ),
+ nTableCount( 0 ),
+ nCurrentSheet( -1 )
+{
+ aTableVec.resize(nDefaultTabCount, NULL);
+}
+
+ScMyTables::~ScMyTables()
+{
+ ScMyTableData* pTable;
+ while (nTableCount > 0)
+ {
+ pTable = aTableVec[nTableCount - 1];
+ delete pTable;
+ aTableVec[nTableCount - 1] = NULL;
+ --nTableCount;
+ }
+}
+
+void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName,
+ const sal_Bool bTempProtection, const rtl::OUString& sTempPassword)
+{
+ if (rImport.GetModel().is())
+ {
+ nCurrentColStylePos = 0;
+ sCurrentSheetName = sTableName;
+ ScMyTableData* aTable;
+ while (nTableCount > 0)
+ {
+ aTable = aTableVec[nTableCount - 1];
+ delete aTable;
+ aTableVec[nTableCount - 1] = NULL;
+ --nTableCount;
+ }
+ ++nCurrentSheet;
+
+ bProtection = bTempProtection;
+ sPassword = sTempPassword;
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference <sheet::XSpreadsheets> xSheets(xSpreadDoc->getSheets());
+ if (xSheets.is())
+ {
+ if (nCurrentSheet > 0)
+ {
+ try
+ {
+ xSheets->insertNewByName(sTableName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
+ }
+ catch ( uno::RuntimeException& )
+ {
+ ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+ if (pDoc)
+ {
+ rImport.LockSolarMutex();
+ String sTabName(String::CreateFromAscii("Table"));
+ pDoc->CreateValidTabName(sTabName);
+ rtl::OUString sOUTabName(sTabName);
+ xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
+ rImport.UnlockSolarMutex();
+ }
+ }
+ }
+ uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ xCurrentSheet.set(xIndex->getByIndex(nCurrentSheet), uno::UNO_QUERY);
+ if ( xCurrentSheet.is() )
+ {
+ xCurrentCellRange.set(xCurrentSheet, uno::UNO_QUERY);
+ if (!(nCurrentSheet > 0))
+ {
+ uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
+ if ( xNamed.is() )
+ try
+ {
+ xNamed->setName(sTableName);
+ }
+ catch ( uno::RuntimeException& )
+ {
+ ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+ if (pDoc)
+ {
+ rImport.LockSolarMutex();
+ String sTabName(String::CreateFromAscii("Table"));
+ pDoc->CreateValidTabName(sTabName);
+ rtl::OUString sOUTabName(sTabName);
+ xNamed->setName(sOUTabName);
+ rImport.UnlockSolarMutex();
+ }
+ }
+ }
+ rImport.SetTableStyle(sStyleName);
+
+ if ( sStyleName.getLength() )
+ {
+ // #i57869# All table style properties for all sheets are now applied here,
+ // before importing the contents.
+ // This is needed for the background color.
+ // Sheet visibility has special handling in ScDocFunc::SetTableVisible to
+ // allow hiding the first sheet.
+ // RTL layout is only remembered, not actually applied, so the shapes can
+ // be loaded before mirroring.
+
+ uno::Reference <beans::XPropertySet> xProperties(xCurrentSheet, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rImport.GetAutoStyles();
+ if (pStyles)
+ {
+ XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True);
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xProperties);
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) );
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ NewTable(1);
+}
+
+sal_Bool ScMyTables::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
+ table::CellRangeAddress& aCellAddress) const
+{
+ uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ {
+ uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xMergeable, uno::UNO_QUERY);
+ uno::Reference<sheet::XSpreadsheet> xTable(xMergeSheetCellRange->getSpreadsheet());
+ uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor(xTable->createCursorByRange(xMergeSheetCellRange));
+ if (xMergeSheetCursor.is())
+ {
+ xMergeSheetCursor->collapseToMergedArea();
+ uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
+ if (xMergeCellAddress.is())
+ {
+ aCellAddress = xMergeCellAddress->getRangeAddress();
+ if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
+ aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
+ return sal_False;
+ else
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+void ScMyTables::UnMerge()
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_False);
+ }
+ }
+}
+
+void ScMyTables::DoMerge(sal_Int32 nCount)
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_False);
+ }
+
+ //merge
+ uno::Reference <table::XCellRange> xMergeCellRange;
+ if (nCount == -1)
+ xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn
+ + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) - 1,
+ aCellAddress.EndRow
+ + aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) - 1));
+ else
+ xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.StartColumn
+ + nCount - 1,
+ aCellAddress.EndRow));
+ uno::Reference <util::XMergeable> xMergeable (xMergeCellRange, uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ }
+}
+
+void ScMyTables::InsertRow()
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ sal_Int32 nRow(GetRealCellPos().Row);
+ for (sal_Int32 j = 0; j < GetRealCellPos().Column - aTableVec[nTableCount - 1]->GetColumn() - 1; ++j)
+ {
+ if (IsMerged(xCurrentCellRange, j, nRow - 1, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_False);
+ }
+
+ //merge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow + 1), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ j += aCellAddress.EndColumn - aCellAddress.StartColumn;
+ }
+ rImport.GetStylesImportHelper()->InsertRow(nRow, nCurrentSheet, rImport.GetDocument());
+ }
+}
+
+void ScMyTables::NewRow()
+{
+ if (nTableCount > 1)
+ if (aTableVec[nTableCount - 1]->GetRealRows(aTableVec[nTableCount - 1]->GetRow()) >
+ aTableVec[nTableCount - 2]->GetRowsPerRow(aTableVec[nTableCount - 2]->GetRow()) - 1)
+ {
+ if (GetRealCellPos().Column > 0)
+ InsertRow();
+ for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--)
+ {
+ sal_Int32 nRow = aTableVec[i - 1]->GetRow();
+ aTableVec[i - 1]->SetRowsPerRow(nRow,
+ aTableVec[i - 1]->GetRowsPerRow(nRow) + 1);
+ aTableVec[i - 1]->SetRealRows(nRow + 1,
+ aTableVec[i - 1]->GetRealRows(nRow)
+ + aTableVec[i - 1]->GetRowsPerRow(nRow));
+ }
+ }
+}
+
+void ScMyTables::AddRow()
+{
+ aTableVec[nTableCount - 1]->AddRow();
+ aTableVec[nTableCount - 1]->SetFirstColumn();
+ sal_Int32 nRow = aTableVec[nTableCount - 1]->GetRow();
+ if (nRow > 0)
+ NewRow();
+ aTableVec[nTableCount - 1]->SetRealRows(nRow + 1,
+ aTableVec[nTableCount - 1]->GetRealRows(nRow)
+ + aTableVec[nTableCount - 1]->GetRowsPerRow(nRow));
+}
+
+void ScMyTables::SetRowStyle(const rtl::OUString& rCellStyleName)
+{
+ rImport.GetStylesImportHelper()->SetRowStyle(rCellStyleName);
+}
+
+void ScMyTables::InsertColumn()
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ sal_Int32 nCol(GetRealCellPos().Column);
+ for (sal_Int32 j = 0; j <= GetRealCellPos().Row - aTableVec[nTableCount - 1]->GetRow() - 1; ++j)
+ {
+ table::CellRangeAddress aTempCellAddress;
+ if (IsMerged(xCurrentCellRange, nCol - 1, j, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_False);
+ aTempCellAddress = aCellAddress;
+ aTempCellAddress.StartColumn = aTempCellAddress.EndColumn + 1;
+ aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
+ }
+ else
+ {
+ aTempCellAddress = aCellAddress;
+ aTempCellAddress.StartColumn += 1;
+ aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
+ }
+
+ //insert Cell
+ sheet::CellInsertMode aCellInsertMode(sheet::CellInsertMode_RIGHT);
+ uno::Reference <sheet::XCellRangeMovement> xCellRangeMovement (xCurrentSheet, uno::UNO_QUERY);
+ xCellRangeMovement->insertCells(aTempCellAddress, aCellInsertMode);
+
+ //merge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn + 1, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ j += aCellAddress.EndRow - aCellAddress.StartRow;
+ }
+ rImport.GetStylesImportHelper()->InsertCol(nCol, nCurrentSheet, rImport.GetDocument());
+ }
+}
+
+void ScMyTables::NewColumn(sal_Bool bIsCovered)
+{
+ if (!bIsCovered)
+ {
+ sal_Int32 nColCount(aTableVec[nTableCount - 1]->GetColCount());
+ sal_Int32 nSpannedCols(aTableVec[nTableCount - 1]->GetSpannedCols());
+ if ( (nSpannedCols > nColCount) &&
+ (aTableVec[nTableCount - 1]->GetRow() == 0) &&
+ (aTableVec[nTableCount - 1]->GetColumn() == 0) )
+ {
+ if (nColCount > 0)
+ {
+ sal_Int32 FirstColsSpanned(nSpannedCols / nColCount);
+ sal_Int32 LastColSpanned(FirstColsSpanned
+ + (nSpannedCols % nColCount));
+ for (sal_Int32 i = 0; i < nColCount - 1; ++i)
+ {
+ aTableVec[nTableCount - 1]->SetColsPerCol(i, FirstColsSpanned);
+ aTableVec[nTableCount - 1]->SetRealCols(i + 1,
+ aTableVec[nTableCount - 1]->GetRealCols(i)
+ + FirstColsSpanned);
+ }
+ aTableVec[nTableCount - 1]->SetColsPerCol(nColCount - 1, LastColSpanned);
+ aTableVec[nTableCount - 1]->SetRealCols(nColCount - 1 + 1,
+ aTableVec[nTableCount - 1]->GetRealCols(nColCount - 1)
+ + LastColSpanned);
+ }
+ }
+ if (aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) > nSpannedCols - 1)
+ {
+ if ( aTableVec[nTableCount - 1]->GetRow() == 0)
+ {
+ InsertColumn();
+ for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--)
+ {
+ sal_Int32 nColPos = aTableVec[i - 1]->GetColumn() +
+ aTableVec[i]->GetSpannedCols() - 1;
+ aTableVec[i - 1]->SetColsPerCol(nColPos,
+ aTableVec[i - 1]->GetColsPerCol(nColPos) +
+ aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()));
+ aTableVec[i - 1]->SetRealCols(nColPos + 1,
+ aTableVec[i - 1]->GetRealCols(nColPos)
+ + aTableVec[i - 1]->GetColsPerCol(nColPos));
+ aTableVec[i - 1]->SetChangedCols(nColPos);
+ }
+ }
+ }
+ }
+}
+
+void ScMyTables::AddColumn(sal_Bool bIsCovered)
+{
+ aTableVec[nTableCount - 1]->AddColumn();
+ if (aTableVec[nTableCount - 1]->GetSubTableSpanned() > 1)
+ aTableVec[nTableCount - 1]->SetSubTableSpanned(aTableVec[nTableCount - 1]->GetSubTableSpanned() - 1);
+ else
+ {
+ NewColumn(bIsCovered);
+ // if (!bIsCovered)
+ aTableVec[nTableCount - 1]->SetRealCols(aTableVec[nTableCount - 1]->GetColumn() + 1,
+ aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn())
+ + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()));
+ if ((!bIsCovered) || (bIsCovered &&
+ (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1)))
+ {
+ if ((aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) > 1) ||
+ (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1))
+ DoMerge();
+ }
+ }
+}
+
+void ScMyTables::NewTable(sal_Int32 nTempSpannedCols)
+{
+ ++nTableCount;
+ if (static_cast<sal_uInt32>(nTableCount) >= aTableVec.size())
+ aTableVec.resize(aTableVec.size() + nDefaultTabCount);
+ ScMyTableData* aTable(new ScMyTableData(nCurrentSheet));
+ if (nTableCount > 1)
+ {
+ ScMyTableData* pTableData = aTableVec[nTableCount - 2];
+ const sal_Int32 nCol(pTableData->GetColumn());
+ const sal_Int32 nColCount(pTableData->GetColCount());
+ const sal_Int32 nColsPerCol(pTableData->GetColsPerCol(nCol));
+ sal_Int32 nSpannedCols(pTableData->GetSpannedCols());
+ sal_Int32 nTemp(nSpannedCols - nColCount);
+ sal_Int32 nTemp2(nCol - (nColCount - 1));
+ if ((nTemp > 0) && (nTemp2 == 0))
+ nTempSpannedCols *= (nTemp + 1);
+ else
+ if (nColsPerCol > 1)
+ nTempSpannedCols *= nColsPerCol;
+
+ sal_Int32 nToMerge;
+ if (nSpannedCols > nColCount)
+ nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount);
+ else
+ nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol);
+ if (nToMerge > nCol)
+ nTempSpannedCols += nToMerge;
+ }
+ aTable->SetSpannedCols(nTempSpannedCols);
+ aTableVec[nTableCount - 1] = aTable;
+ if (nTableCount > 1)
+ {
+ aTableVec[nTableCount - 2]->SetSubTableSpanned(aTable->GetSpannedCols());
+ UnMerge();
+ }
+}
+
+void ScMyTables::UpdateRowHeights()
+{
+ if (rImport.GetModel().is())
+ {
+ rImport.LockSolarMutex();
+ // update automatic row heights
+
+ // For sheets with any kind of shapes (including notes),
+ // update row heights immediately (before setting the positions).
+ // For sheets without shapes, set "pending" flag
+ // and update row heights when a sheet is shown.
+ // The current sheet (from view settings) is always updated immediately.
+
+ ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+ if (pDoc)
+ {
+ SCTAB nCount = pDoc->GetTableCount();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+
+ SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() );
+
+ ScMarkData aUpdateSheets;
+ for (SCTAB nTab=0; nTab<nCount; ++nTab)
+ {
+ const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL;
+ if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) )
+ aUpdateSheets.SelectTable( nTab, TRUE );
+ else
+ pDoc->SetPendingRowHeights( nTab, TRUE );
+ }
+
+ if (aUpdateSheets.GetSelectCount())
+ {
+ pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results)
+ ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
+ pDoc->LockStreamValid( false );
+ }
+ }
+
+ rImport.UnlockSolarMutex();
+ }
+}
+
+void ScMyTables::DeleteTable()
+{
+ rImport.LockSolarMutex();
+
+ nCurrentColStylePos = 0;
+ if (nTableCount > 0)
+ {
+ ScMyTableData* aTable = aTableVec[nTableCount - 1];
+ delete aTable;
+ aTableVec[nTableCount - 1] = NULL;
+ nTableCount--;
+ }
+ if (nTableCount == 0) // only set the styles if all subtables are importet and the table is finished
+ {
+ rImport.GetStylesImportHelper()->SetStylesToRanges();
+ rImport.SetStylesToRangesFinished();
+ }
+
+ //#i48793#; has to be set before protection
+ if (!aMatrixRangeList.empty())
+ {
+ ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin();
+ ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
+ while(aItr != aEndItr)
+ {
+ SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
+ ++aItr;
+ }
+ aMatrixRangeList.clear();
+ }
+
+ if (rImport.GetDocument() && bProtection)
+ {
+ uno::Sequence<sal_Int8> aPass;
+ SvXMLUnitConverter::decodeBase64(aPass, sPassword);
+ 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();
+
+ //#95582#; find out whether it was possible to set the sheet name
+ // test it here, because if it is a linked table the name is changed by importing
+ // the linking informations
+ uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
+ if ( xNamed.is() )
+ {
+ rtl::OUString sCurrentName(xNamed->getName());
+ if (sCurrentName != sCurrentSheetName && rImport.GetDocument())
+ {
+ rImport.GetDocument()->RenameTab( static_cast<SCTAB>(nCurrentSheet),
+ sCurrentSheetName, sal_False, sal_True);
+
+/* rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Could not create a table with the name "));
+ sErrorMessage += sCurrentSheetName;
+ sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(". The new name is "));
+ sErrorMessage += sCurrentName;
+ uno::Sequence<rtl::OUString> aSeq(1);
+ aSeq[0] = sErrorMessage;
+ uno::Reference<xml::sax::XLocator> xLocator;
+ rImport.SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rtl::OUString(), xLocator);*/
+ }
+ }
+}
+
+table::CellAddress ScMyTables::GetRealCellPos()
+{
+ sal_Int32 nRow(0);
+ sal_Int32 nCol(0);
+ for (sal_Int32 i = 0; i < nTableCount; ++i)
+ {
+ ScMyTableData* pTableData = aTableVec[i];
+ nCol += pTableData->GetRealCols(pTableData->GetColumn());
+ nRow += pTableData->GetRealRows(pTableData->GetRow());
+ }
+ aRealCellPos.Row = nRow;
+ aRealCellPos.Column = nCol;
+ aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ return aRealCellPos;
+}
+
+void ScMyTables::AddColCount(sal_Int32 nTempColCount)
+{
+ aTableVec[nTableCount - 1]->SetColCount(aTableVec[nTableCount - 1]->GetColCount() + nTempColCount);
+}
+
+void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName)
+{
+ DBG_ASSERT(nTableCount == 1, "not possible to use default styles on columns in subtables");
+ rImport.GetStylesImportHelper()->AddColumnStyle(rCellStyleName, nCurrentColStylePos, nRepeat);
+ nCurrentColStylePos += nRepeat;
+}
+
+uno::Reference< drawing::XDrawPage > ScMyTables::GetCurrentXDrawPage()
+{
+ if( (nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is() )
+ {
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier( xCurrentSheet, uno::UNO_QUERY );
+ if( xDrawPageSupplier.is() )
+ xDrawPage.set(xDrawPageSupplier->getDrawPage());
+ nCurrentDrawPage = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ }
+ return xDrawPage;
+}
+
+uno::Reference< drawing::XShapes > ScMyTables::GetCurrentXShapes()
+{
+ if( (nCurrentSheet != nCurrentXShapes) || !xShapes.is() )
+ {
+ xShapes.set(GetCurrentXDrawPage(), uno::UNO_QUERY);
+ rImport.GetShapeImport()->startPage(xShapes);
+ rImport.GetShapeImport()->pushGroupForSorting ( xShapes );
+ nCurrentXShapes = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ return xShapes;
+ }
+ else
+ return xShapes;
+}
+
+sal_Bool ScMyTables::HasDrawPage()
+{
+ return !((nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is());
+}
+
+sal_Bool ScMyTables::HasXShapes()
+{
+ return !((nCurrentSheet != nCurrentXShapes) || !xShapes.is());
+}
+
+void ScMyTables::AddShape(uno::Reference <drawing::XShape>& rShape,
+ rtl::OUString* pRangeList,
+ table::CellAddress& rStartAddress, table::CellAddress& rEndAddress,
+ sal_Int32 nEndX, sal_Int32 nEndY)
+{
+ 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 rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
+{
+ DBG_ASSERT(nEndRow >= nStartRow, "wrong row order");
+ DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order");
+ table::CellRangeAddress aRange;
+ aRange.StartColumn = nStartColumn;
+ aRange.StartRow = nStartRow;
+ aRange.EndColumn = nEndColumn;
+ aRange.EndRow = nEndRow;
+ aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar);
+ aMatrixRangeList.push_back(aMRange);
+}
+
+sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
+{
+ sal_Bool bResult(sal_False);
+ if (!aMatrixRangeList.empty())
+ {
+ ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin());
+ ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end());
+ sal_Bool bReady(sal_False);
+ while(!bReady && aItr != aEndItr)
+ {
+ if (nCurrentSheet > aItr->aRange.Sheet)
+ {
+ DBG_ERROR("should never hapen, because the list should be cleared in DeleteTable");
+ aItr = aMatrixRangeList.erase(aItr);
+ }
+ else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn))
+ {
+ SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
+ aItr = aMatrixRangeList.erase(aItr);
+ }
+ else if (nColumn < aItr->aRange.StartColumn)
+ bReady = sal_True;
+ else if (nColumn >= aItr->aRange.StartColumn && nColumn <= aItr->aRange.EndColumn && nRow >= aItr->aRange.StartRow && nRow <= aItr->aRange.EndRow)
+ {
+ bReady = sal_True;
+ bResult = sal_True;
+ }
+ else
+ ++aItr;
+ }
+ }
+ return bResult;
+}
+
+void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
+{
+ uno::Reference <table::XCellRange> xMatrixCellRange(
+ GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow,
+ rRange.EndColumn, rRange.EndRow));
+ if (xMatrixCellRange.is())
+ {
+ uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange(xMatrixCellRange, uno::UNO_QUERY);
+ if (xArrayFormulaRange.is())
+ {
+ ScCellRangeObj* pCellRangeObj =
+ static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation(
+ xMatrixCellRange));
+ if (pCellRangeObj)
+ pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar);
+ }
+ }
+}
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
new file mode 100644
index 000000000000..6e39844b5b8f
--- /dev/null
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLSUBTI_HXX
+#define SC_XMLSUBTI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include <vector>
+#include <list>
+#include "XMLTableShapeResizer.hxx"
+#include "formula/grammar.hxx"
+
+class ScXMLImport;
+
+typedef std::vector<sal_Int32> ScMysalIntVec;
+typedef std::list<sal_Int32> ScMysalIntList;
+
+const ScMysalIntVec::size_type nDefaultRowCount = 20;
+const ScMysalIntVec::size_type nDefaultColCount = 20;
+const ScMysalIntVec::size_type nDefaultTabCount = 10;
+
+class ScMyTableData
+{
+private:
+ com::sun::star::table::CellAddress aTableCellPos;
+ ScMysalIntVec nColsPerCol;
+ ScMysalIntVec nRealCols;
+ ScMysalIntVec nRowsPerRow;
+ ScMysalIntVec nRealRows;
+ sal_Int32 nSpannedCols;
+ sal_Int32 nColCount;
+ sal_Int32 nSubTableSpanned;
+ ScMysalIntList nChangedCols;
+public:
+ ScMyTableData(sal_Int32 nSheet = -1, sal_Int32 nCol = -1, sal_Int32 nRow = -1);
+ ~ScMyTableData();
+ com::sun::star::table::CellAddress GetCellPos() const { return aTableCellPos; }
+ sal_Int32 GetRow() const { return aTableCellPos.Row; }
+ sal_Int32 GetColumn() const { return aTableCellPos.Column; }
+ void AddRow();
+ void AddColumn();
+ void SetFirstColumn() { aTableCellPos.Column = -1; }
+ sal_Int32 GetColsPerCol(const sal_Int32 nIndex) const { return nColsPerCol[nIndex]; }
+ void SetColsPerCol(const sal_Int32 nIndex, sal_Int32 nValue = 1) { nColsPerCol[nIndex] = nValue; }
+ sal_Int32 GetRealCols(const sal_Int32 nIndex, const sal_Bool bIsNormal = sal_True) const;
+ void SetRealCols(const sal_Int32 nIndex, const sal_Int32 nValue) { nRealCols[nIndex] = nValue; }
+ sal_Int32 GetRowsPerRow(const sal_Int32 nIndex) const { return nRowsPerRow[nIndex]; }
+ void SetRowsPerRow(const sal_Int32 nIndex, const sal_Int32 nValue = 1) { nRowsPerRow[nIndex] = nValue; }
+ sal_Int32 GetRealRows(const sal_Int32 nIndex) const { return nIndex < 0 ? 0 : nRealRows[nIndex]; }
+ void SetRealRows(const sal_Int32 nIndex, const sal_Int32 nValue) { nRealRows[nIndex] = nValue; }
+ sal_Int32 GetSpannedCols() const { return nSpannedCols; }
+ void SetSpannedCols(const sal_Int32 nTempSpannedCols) { nSpannedCols = nTempSpannedCols; }
+ sal_Int32 GetColCount() const { return nColCount; }
+ void SetColCount(const sal_Int32 nTempColCount) { nColCount = nTempColCount; }
+ sal_Int32 GetSubTableSpanned() const { return nSubTableSpanned; }
+ void SetSubTableSpanned(const sal_Int32 nValue) { nSubTableSpanned = nValue; }
+ sal_Int32 GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const;
+ void SetChangedCols(const sal_Int32 nValue);
+};
+
+//*******************************************************************************************************************************
+
+struct ScMatrixRange
+{
+ rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
+ formula::FormulaGrammar::Grammar eGrammar;
+ com::sun::star::table::CellRangeAddress aRange;
+ ScMatrixRange(const com::sun::star::table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammarP) :
+ sFormula(rFormula),
+ sFormulaNmsp(rFormulaNmsp),
+ eGrammar(eGrammarP),
+ aRange(rRange)
+ {
+ }
+};
+
+class ScMyTables
+{
+private:
+ typedef std::list<ScMatrixRange> ScMyMatrixRangeList;
+
+ ScXMLImport& rImport;
+
+ ScMyShapeResizer aResizeShapes;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > xCurrentSheet;
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > xCurrentCellRange;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xDrawPage;
+ ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShapes > xShapes;
+ rtl::OUString sCurrentSheetName;
+ rtl::OUString sPassword;
+ std::vector<ScMyTableData*> aTableVec;
+ ScMyMatrixRangeList aMatrixRangeList;
+ com::sun::star::table::CellAddress aRealCellPos;
+ sal_Int32 nCurrentColStylePos;
+ sal_Int16 nCurrentDrawPage;
+ sal_Int16 nCurrentXShapes;
+ sal_Int32 nTableCount;
+ sal_Int32 nCurrentSheet;
+ sal_Bool bProtection;
+
+ sal_Bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange,
+ const sal_Int32 nCol, const sal_Int32 nRow,
+ com::sun::star::table::CellRangeAddress& aCellAddress) const;
+ void UnMerge();
+ void DoMerge(sal_Int32 nCount = -1);
+ void InsertRow();
+ void NewRow();
+ void InsertColumn();
+ void NewColumn(sal_Bool bIsCovered);
+public:
+ ScMyTables(ScXMLImport& rImport);
+ ~ScMyTables();
+ void NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName,
+ const sal_Bool bProtection, const rtl::OUString& sPassword);
+ void AddRow();
+ void SetRowStyle(const rtl::OUString& rCellStyleName);
+ void AddColumn(sal_Bool bIsCovered);
+ void NewTable(sal_Int32 nTempSpannedCols);
+ void UpdateRowHeights();
+ void ResizeShapes() { aResizeShapes.ResizeShapes(); }
+ void DeleteTable();
+ com::sun::star::table::CellAddress GetRealCellPos();
+ void AddColCount(sal_Int32 nTempColCount);
+ void AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName);
+ rtl::OUString GetCurrentSheetName() const { return sCurrentSheetName; }
+ sal_Int32 GetCurrentSheet() const { return nCurrentSheet; }
+ sal_Int32 GetCurrentColumn() const { return aTableVec[nTableCount - 1]->GetColCount(); }
+ sal_Int32 GetCurrentRow() const { return aTableVec[nTableCount - 1]->GetRow(); }
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >
+ GetCurrentXSheet() { return xCurrentSheet; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ GetCurrentXCellRange() { return xCurrentCellRange; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >
+ GetCurrentXDrawPage();
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+ GetCurrentXShapes();
+ sal_Bool HasDrawPage();
+ sal_Bool HasXShapes();
+ void AddShape(com::sun::star::uno::Reference <com::sun::star::drawing::XShape>& rShape,
+ rtl::OUString* pRangeList,
+ com::sun::star::table::CellAddress& rStartAddress,
+ com::sun::star::table::CellAddress& rEndAddress,
+ sal_Int32 nEndX, sal_Int32 nEndY);
+
+ void AddMatrixRange( sal_Int32 nStartColumn,
+ sal_Int32 nStartRow,
+ sal_Int32 nEndColumn,
+ sal_Int32 nEndRow,
+ const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp,
+ const formula::FormulaGrammar::Grammar );
+
+ sal_Bool IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow);
+ void SetMatrix( const com::sun::star::table::CellRangeAddress& rRange,
+ const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp,
+ const formula::FormulaGrammar::Grammar );
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
new file mode 100644
index 000000000000..69f00106b7c7
--- /dev/null
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -0,0 +1,422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmltabi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlrowi.hxx"
+#include "xmlcoli.hxx"
+#include "xmlsceni.hxx"
+#include "xmlexternaltabi.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "olinetab.hxx"
+#include "XMLConverter.hxx"
+#include "XMLTableShapesContext.hxx"
+#include "XMLTableSourceContext.hxx"
+#include "XMLStylesImportHelper.hxx"
+#include "rangeutl.hxx"
+#include "externalrefmgr.hxx"
+#include "sheetdata.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/formsimp.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/XMLEventsImportContext.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+/**
+ * Determine whether this table is an external reference cache from its
+ * name. There is currently no way of determining whether a table is a
+ * regular table or an external reference cache other than examining the
+ * name itself. We should probably introduce a new boolean value for
+ * table:table element and use it instead of doing this, to make it more
+ * reliable and future-proof.
+ *
+ * @param rName
+ *
+ * @return
+ */
+static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rUrl, rtl::OUString& rExtTabName)
+{
+ // 'file:///path/to/file.ods'#MySheet
+ // 'file:///path/to/file.ods'#MySheet with space
+ // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
+ // That's allowed.)
+
+ static const sal_Unicode aPrefix[] = {
+ '\'', 'f', 'i', 'l', 'e', ':', '/', '/'
+ };
+
+ rtl::OUStringBuffer aUrlBuf, aTabNameBuf;
+ aUrlBuf.appendAscii("file://");
+ sal_Int32 n = rName.getLength();
+ const sal_Unicode* p = rName.getStr();
+
+ bool bInUrl = true;
+ sal_Unicode cPrev = 0;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (i <= 7)
+ {
+ // Checking the prefix 'file://'.
+ if (c != aPrefix[i])
+ return false;
+ }
+ else if (bInUrl)
+ {
+ // parsing file URL
+ if (c == '#')
+ {
+ if (cPrev != '\'')
+ return false;
+
+ rUrl = aUrlBuf.makeStringAndClear();
+ rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
+ bInUrl = false;
+ }
+ else
+ aUrlBuf.append(c);
+ }
+ else
+ // parsing sheet name.
+ aTabNameBuf.append(c);
+
+ cPrev = c;
+ }
+
+ if (bInUrl)
+ return false;
+
+ if (aTabNameBuf.getLength() == 0)
+ return false;
+
+ rExtTabName = aTabNameBuf.makeStringAndClear();
+
+ return true;
+}
+
+ScXMLExternalTabData::ScXMLExternalTabData() :
+ mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
+{
+}
+
+//------------------------------------------------------------------
+
+ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
+ USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempIsSubTable,
+ const sal_Int32 nSpannedCols) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pExternalRefInfo(NULL),
+ nStartOffset(-1),
+ bStartFormPage(sal_False),
+ bPrintEntireSheet(sal_True)
+{
+ // get start offset in file (if available)
+ nStartOffset = GetScImport().GetByteOffset();
+
+ if (!bTempIsSubTable)
+ {
+ sal_Bool bProtection(sal_False);
+ rtl::OUString sName;
+ rtl::OUString sStyleName;
+ rtl::OUString sPassword;
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_NAME:
+ sName = sValue;
+ break;
+ case XML_TOK_TABLE_STYLE_NAME:
+ sStyleName = sValue;
+ break;
+ case XML_TOK_TABLE_PROTECTION:
+ bProtection = IsXMLToken(sValue, XML_TRUE);
+ break;
+ case XML_TOK_TABLE_PRINT_RANGES:
+ sPrintRanges = sValue;
+ break;
+ case XML_TOK_TABLE_PASSWORD:
+ sPassword = sValue;
+ break;
+ case XML_TOK_TABLE_PRINT:
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bPrintEntireSheet = sal_False;
+ }
+ break;
+ }
+ }
+
+ rtl::OUString aExtUrl, aExtTabName;
+ if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
+ {
+ // This is an external ref cache table.
+ pExternalRefInfo.reset(new ScXMLExternalTabData);
+ pExternalRefInfo->maFileUrl = aExtUrl;
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
+ pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true);
+ pExternalRefInfo->mpCacheTable->setWholeTableCached();
+ }
+ }
+ else
+ {
+ // This is a regular table.
+ GetScImport().GetTables().NewSheet(sName, sStyleName, bProtection, sPassword);
+ }
+ }
+ else
+ {
+ GetScImport().GetTables().NewTable(nSpannedCols);
+ }
+}
+
+ScXMLTableContext::~ScXMLTableContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap());
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLName);
+ if (pExternalRefInfo.get())
+ {
+ // We only care about the table-row and table-source elements for
+ // external cache data.
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROW_GROUP:
+ case XML_TOK_TABLE_HEADER_ROWS:
+ case XML_TOK_TABLE_ROWS:
+ // #i101319# don't discard rows in groups or header (repeat range)
+ return new ScXMLExternalRefRowsContext(
+ GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
+ case XML_TOK_TABLE_ROW:
+ return new ScXMLExternalRefRowContext(
+ GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
+ case XML_TOK_TABLE_SOURCE:
+ return new ScXMLExternalRefTabSourceContext(
+ GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
+ default:
+ ;
+ }
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLName);
+ }
+
+ SvXMLImportContext *pContext(0);
+
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_COL_GROUP:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_True );
+ break;
+ case XML_TOK_TABLE_HEADER_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, sal_False );
+ break;
+ case XML_TOK_TABLE_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_False );
+ break;
+ case XML_TOK_TABLE_COL:
+ pContext = new ScXMLTableColContext( GetScImport(), nPrefix,
+ rLName, xAttrList );
+ break;
+ case XML_TOK_TABLE_ROW_GROUP:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_True );
+ break;
+ case XML_TOK_TABLE_HEADER_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, sal_False );
+ break;
+ case XML_TOK_TABLE_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_False, sal_False );
+ break;
+ case XML_TOK_TABLE_ROW:
+ pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ case XML_TOK_TABLE_SOURCE:
+ pContext = new ScXMLTableSourceContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ case XML_TOK_TABLE_SCENARIO:
+ pContext = new ScXMLTableScenarioContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ case XML_TOK_TABLE_SHAPES:
+ pContext = new ScXMLTableShapesContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ case XML_TOK_TABLE_FORMS:
+ {
+ GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
+ bStartFormPage = sal_True;
+ pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName );
+ }
+ break;
+ case XML_TOK_TABLE_EVENT_LISTENERS:
+ case XML_TOK_TABLE_EVENT_LISTENERS_EXT:
+ {
+ // use XEventsSupplier interface of the sheet
+ uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
+ pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName, xSupplier );
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableContext::EndElement()
+{
+ // get end offset in file (if available)
+// sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+
+ GetScImport().LockSolarMutex();
+ GetScImport().GetStylesImportHelper()->EndTable();
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (pDoc)
+ {
+ if (sPrintRanges.getLength())
+ {
+ uno::Reference< sheet::XPrintAreas > xPrintAreas( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
+ if( xPrintAreas.is() )
+ {
+ uno::Sequence< table::CellRangeAddress > aRangeList;
+ ScRangeStringConverter::GetRangeListFromString( aRangeList, sPrintRanges, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ xPrintAreas->setPrintAreas( aRangeList );
+ }
+ }
+ else if (bPrintEntireSheet) pDoc->SetPrintEntireSheet(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()));
+
+ ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()), sal_False));
+ if (pOutlineTable)
+ {
+ ScOutlineArray* pColArray(pOutlineTable->GetColArray());
+ sal_Int32 nDepth(pColArray->GetDepth());
+ sal_Int32 i;
+ for (i = 0; i < nDepth; ++i)
+ {
+ sal_Int32 nCount(pColArray->GetCount(static_cast<USHORT>(i)));
+ for (sal_Int32 j = 0; j < nCount; ++j)
+ {
+ ScOutlineEntry* pEntry(pColArray->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j)));
+ if (pEntry->IsHidden())
+ pColArray->SetVisibleBelow(static_cast<USHORT>(i), static_cast<USHORT>(j), sal_False);
+ }
+ }
+ ScOutlineArray* pRowArray(pOutlineTable->GetRowArray());
+ nDepth = pRowArray->GetDepth();
+ for (i = 0; i < nDepth; ++i)
+ {
+ sal_Int32 nCount(pRowArray->GetCount(static_cast<USHORT>(i)));
+ for (sal_Int32 j = 0; j < nCount; ++j)
+ {
+ ScOutlineEntry* pEntry(pRowArray->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j)));
+ if (pEntry->IsHidden())
+ pRowArray->SetVisibleBelow(static_cast<USHORT>(i), static_cast<USHORT>(j), sal_False);
+ }
+ }
+ }
+ if (GetScImport().GetTables().HasDrawPage())
+ {
+ if (GetScImport().GetTables().HasXShapes())
+ {
+ GetScImport().GetShapeImport()->popGroupAndSort();
+ uno::Reference < drawing::XShapes > xTempShapes(GetScImport().GetTables().GetCurrentXShapes());
+ GetScImport().GetShapeImport()->endPage(xTempShapes);
+ }
+ if (bStartFormPage)
+ GetScImport().GetFormImport()->endPage();
+ }
+
+ GetScImport().GetTables().DeleteTable();
+ GetScImport().ProgressBarIncrement(sal_False);
+
+ // store stream positions
+ if (!pExternalRefInfo.get() && nStartOffset >= 0 /* && nEndOffset >= 0 */)
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet();
+ // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
+ pSheetData->StartStreamPos( nTab, nStartOffset );
+ }
+ }
+ GetScImport().UnlockSolarMutex();
+}
+
diff --git a/sc/source/filter/xml/xmltabi.hxx b/sc/source/filter/xml/xmltabi.hxx
new file mode 100644
index 000000000000..c066b8bf3a9e
--- /dev/null
+++ b/sc/source/filter/xml/xmltabi.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLTABI_HXX
+#define SC_XMLTABI_HXX
+
+#include "externalrefmgr.hxx"
+
+#include <xmloff/xmlictxt.hxx>
+#include <memory>
+
+class ScXMLImport;
+
+struct ScXMLExternalTabData
+{
+ String maFileUrl;
+ ScExternalRefCache::TableTypeRef mpCacheTable;
+ sal_Int32 mnRow;
+ sal_Int32 mnCol;
+ sal_uInt16 mnFileId;
+
+ ScXMLExternalTabData();
+};
+
+class ScXMLTableContext : public SvXMLImportContext
+{
+ rtl::OUString sPrintRanges;
+ ::std::auto_ptr<ScXMLExternalTabData> pExternalRefInfo;
+ sal_Int32 nStartOffset;
+ sal_Bool bStartFormPage;
+ sal_Bool bPrintEntireSheet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableContext( ScXMLImport& rImport, USHORT nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempIsSubTable = sal_False,
+ const sal_Int32 nSpannedCols = 0);
+
+ virtual ~ScXMLTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
new file mode 100644
index 000000000000..dbe647bc433f
--- /dev/null
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -0,0 +1,1024 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <rsc/rscsfx.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <tools/debug.hxx>
+#include <vos/xception.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <svx/xmlgrhlp.hxx>
+#include <svtools/sfxecode.hxx>
+#include <sfx2/frame.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <tools/urlobj.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/xml/sax/XErrorHandler.hpp>
+#include <com/sun/star/xml/sax/XEntityResolver.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XDTDHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <comphelper/extract.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <comphelper/genericpropertyset.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+
+#include <svx/xmleohlp.hxx>
+#include <rtl/logfile.hxx>
+#include <unotools/saveopt.hxx>
+
+#include "document.hxx"
+#include "xmlwrap.hxx"
+#include "xmlimprt.hxx"
+#include "xmlexprt.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "scerrors.hxx"
+#include "XMLExportSharedData.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
+#include "XMLCodeNameProvider.hxx"
+
+#define MAP_LEN(x) x, sizeof(x) - 1
+
+using namespace com::sun::star;
+using ::rtl::OUString;
+
+// -----------------------------------------------------------------------
+
+ScXMLImportWrapper::ScXMLImportWrapper(ScDocument& rD, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) :
+ rDoc(rD),
+ pMedium(pM),
+ xStorage(xStor)
+{
+ DBG_ASSERT( pMedium || xStorage.is(), "ScXMLImportWrapper: Medium or Storage must be set" );
+}
+
+//UNUSED2008-05 uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator(
+//UNUSED2008-05 uno::Reference < frame::XModel> & rModel)
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ERROR( "The status indicator from medium must be used!" );
+//UNUSED2008-05
+//UNUSED2008-05 uno::Reference<task::XStatusIndicator> xStatusIndicator;
+//UNUSED2008-05
+//UNUSED2008-05 if (rModel.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<frame::XController> xController( rModel->getCurrentController());
+//UNUSED2008-05 if ( xController.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 uno::Reference<task::XStatusIndicatorFactory> xFactory( xController->getFrame(), uno::UNO_QUERY );
+//UNUSED2008-05 if ( xFactory.is())
+//UNUSED2008-05 {
+//UNUSED2008-05 try
+//UNUSED2008-05 {
+//UNUSED2008-05 xStatusIndicator.set(xFactory->createStatusIndicator());
+//UNUSED2008-05 }
+//UNUSED2008-05 catch ( lang::DisposedException e )
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ERROR("Exception while trying to get a Status Indicator");
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05 return xStatusIndicator;
+//UNUSED2008-05 }
+
+uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator()
+{
+ uno::Reference<task::XStatusIndicator> xStatusIndicator;
+ if (pMedium)
+ {
+ SfxItemSet* pSet = pMedium->GetItemSet();
+ if (pSet)
+ {
+ const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL));
+ if (pItem)
+ xStatusIndicator.set(pItem->GetValue(), uno::UNO_QUERY);
+ }
+ }
+ return xStatusIndicator;
+}
+
+sal_uInt32 ScXMLImportWrapper::ImportFromComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory,
+ uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xXMLParser,
+ xml::sax::InputSource& aParserInput,
+ const rtl::OUString& sComponentName, const rtl::OUString& sDocName,
+ const rtl::OUString& sOldDocName, uno::Sequence<uno::Any>& aArgs,
+ sal_Bool bMustBeSuccessfull)
+{
+ uno::Reference < io::XStream > xDocStream;
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetStorage();
+
+ // Get data source ...
+
+// uno::Reference< uno::XInterface > xPipe;
+// uno::Reference< io::XActiveDataSource > xSource;
+
+ sal_Bool bEncrypted = sal_False;
+ rtl::OUString sStream(sDocName);
+ if( xStorage.is() )
+ {
+ try
+ {
+ uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
+ if ( xAccess->hasByName(sDocName) && xStorage->isStreamElement( sDocName) )
+ xDocStream = xStorage->openStreamElement( sDocName, embed::ElementModes::READ );
+ else if (sOldDocName.getLength() && xAccess->hasByName(sOldDocName) && xStorage->isStreamElement( sOldDocName) )
+ {
+ xDocStream = xStorage->openStreamElement( sOldDocName, embed::ElementModes::READ );
+ sStream = sOldDocName;
+ }
+ else
+ return sal_False;
+
+ aParserInput.aInputStream = xDocStream->getInputStream();
+ uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
+
+ uno::Any aAny = xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
+ aAny >>= bEncrypted;
+ }
+ catch( packages::WrongPasswordException& )
+ {
+ return ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( packages::zip::ZipIOException& )
+ {
+ return ERRCODE_IO_BROKENPACKAGE;
+ }
+ catch( uno::Exception& )
+ {
+ return SCERR_IMPORT_UNKNOWN;
+ }
+ }
+ // #99667#; no longer necessary
+/* else if ( pMedium )
+ {
+ // if there is a medium and if this medium has a load environment,
+ // we get an active data source from the medium.
+ pMedium->GetInStream()->Seek( 0 );
+ xSource = pMedium->GetDataSource();
+ DBG_ASSERT( xSource.is(), "got no data source from medium" );
+ if( !xSource.is() )
+ return sal_False;
+
+ // get a pipe for connecting the data source to the parser
+ xPipe = xServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.io.Pipe") );
+ DBG_ASSERT( xPipe.is(),
+ "XMLReader::Read: com.sun.star.io.Pipe service missing" );
+ if( !xPipe.is() )
+ return sal_False;
+
+ // connect pipe's output stream to the data source
+ uno::Reference<io::XOutputStream> xPipeOutput( xPipe, uno::UNO_QUERY );
+ xSource->setOutputStream( xPipeOutput );
+
+ aParserInput.aInputStream =
+ uno::Reference< io::XInputStream >( xPipe, uno::UNO_QUERY );
+ }*/
+ else
+ return SCERR_IMPORT_UNKNOWN;
+
+ // set Base URL
+ uno::Reference< beans::XPropertySet > xInfoSet;
+ if( aArgs.getLength() > 0 )
+ aArgs.getConstArray()[0] >>= xInfoSet;
+ DBG_ASSERT( xInfoSet.is(), "missing property set" );
+ if( xInfoSet.is() )
+ {
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( sStream ) );
+ }
+
+ sal_uInt32 nReturn(0);
+ rDoc.SetRangeOverflowType(0); // is modified by the importer if limits are exceeded
+
+ uno::Reference<xml::sax::XDocumentHandler> xDocHandler(
+ xServiceFactory->createInstanceWithArguments(
+ sComponentName, aArgs ),
+ uno::UNO_QUERY );
+ DBG_ASSERT( xDocHandler.is(), "can't get Calc importer" );
+ uno::Reference<document::XImporter> xImporter( xDocHandler, uno::UNO_QUERY );
+ uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY );
+ if (xImporter.is())
+ xImporter->setTargetDocument( xComponent );
+
+ // connect parser and filter
+ uno::Reference<xml::sax::XParser> xParser( xXMLParser, uno::UNO_QUERY );
+ xParser->setDocumentHandler( xDocHandler );
+
+ // parse
+/* if( xSource.is() )
+ {
+ uno::Reference<io::XActiveDataControl> xSourceControl( xSource, uno::UNO_QUERY );
+ if( xSourceControl.is() )
+ xSourceControl->start();
+ }*/
+
+ try
+ {
+ xParser->parseStream( aParserInput );
+ }
+ catch( xml::sax::SAXParseException& r )
+ {
+ // sax parser sends wrapped exceptions,
+ // try to find the original one
+ xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
+ sal_Bool bTryChild = sal_True;
+
+ while( bTryChild )
+ {
+ xml::sax::SAXException aTmp;
+ if ( aSaxEx.WrappedException >>= aTmp )
+ aSaxEx = aTmp;
+ else
+ bTryChild = sal_False;
+ }
+
+ packages::zip::ZipIOException aBrokenPackage;
+ if ( aSaxEx.WrappedException >>= aBrokenPackage )
+ return ERRCODE_IO_BROKENPACKAGE;
+ else if( bEncrypted )
+ nReturn = ERRCODE_SFX_WRONGPASSWORD;
+ else
+ {
+
+#ifdef DBG_UTIL
+ ByteString aError( "SAX parse exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+
+ String sErr( String::CreateFromInt32( r.LineNumber ));
+ sErr += ',';
+ sErr += String::CreateFromInt32( r.ColumnNumber );
+
+ if( sDocName.getLength() )
+ {
+ nReturn = *new TwoStringErrorInfo(
+ (bMustBeSuccessfull ? SCERR_IMPORT_FILE_ROWCOL
+ : SCWARN_IMPORT_FILE_ROWCOL),
+ sDocName, sErr,
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
+ }
+ else
+ {
+ DBG_ASSERT( bMustBeSuccessfull, "Warnings are not supported" );
+ nReturn = *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL, sErr,
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
+ }
+ }
+ }
+ catch( xml::sax::SAXException& r )
+ {
+ packages::zip::ZipIOException aBrokenPackage;
+ if ( r.WrappedException >>= aBrokenPackage )
+ return ERRCODE_IO_BROKENPACKAGE;
+ else if( bEncrypted )
+ nReturn = ERRCODE_SFX_WRONGPASSWORD;
+ else
+ {
+
+#ifdef DBG_UTIL
+ ByteString aError( "SAX exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = SCERR_IMPORT_FORMAT;
+ }
+ }
+ catch( packages::zip::ZipIOException& r )
+ {
+#ifdef DBG_UTIL
+ ByteString aError( "Zip exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = ERRCODE_IO_BROKENPACKAGE;
+ }
+ catch( io::IOException& r )
+ {
+#ifdef DBG_UTIL
+ ByteString aError( "IO exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = SCERR_IMPORT_OPEN;
+ }
+ catch( uno::Exception& r )
+ {
+#ifdef DBG_UTIL
+ ByteString aError( "uno exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = SCERR_IMPORT_UNKNOWN;
+ }
+
+ // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler,
+ // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer.
+ // So the overflow warning ErrorCode is now stored in the document.
+ // Export works differently, there getImplementation still works.
+
+ if (rDoc.HasRangeOverflow() && !nReturn)
+ nReturn = rDoc.GetRangeOverflowType();
+
+ // free the component
+ xParser->setDocumentHandler( NULL );
+
+ // success!
+ return nReturn;
+}
+
+sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Import" );
+
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
+ if( !xServiceFactory.is() )
+ return sal_False;
+
+ xml::sax::InputSource aParserInput;
+ if (pMedium)
+ aParserInput.sSystemId = OUString(pMedium->GetName());
+
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetStorage();
+
+ // get parser
+ uno::Reference<uno::XInterface> xXMLParser(
+ xServiceFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) ));
+ DBG_ASSERT( xXMLParser.is(), "com.sun.star.xml.sax.Parser service missing" );
+ if( !xXMLParser.is() )
+ return sal_False;
+
+ // get filter
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ if ( pObjSh )
+ {
+ rtl::OUString sEmpty;
+ uno::Reference<frame::XModel> xModel(pObjSh->GetModel());
+
+ /** property map for export info set */
+ comphelper::PropertyMapEntry aImportInfoMap[] =
+ {
+ { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference<uno::XInterface> *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) );
+
+ // ---- get BuildId from parent container if available
+
+ uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY );
+ if( xChild.is() )
+ {
+ uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
+ if( xParentSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
+ {
+ xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
+ }
+ }
+ }
+
+ // -------------------------------------
+
+ uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator());
+ if (xStatusIndicator.is())
+ {
+ sal_Int32 nProgressRange(1000000);
+ xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_LOAD_DOC)), nProgressRange);
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange));
+ }
+
+ // Set base URI
+ OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
+ ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : ::rtl::OUString();
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
+
+ // TODO/LATER: do not do it for embedded links
+ if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() )
+ {
+ OUString aName;
+ if ( pMedium && pMedium->GetItemSet() )
+ {
+ const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+ pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+ if ( pDocHierarchItem )
+ aName = pDocHierarchItem->GetValue();
+ }
+ else
+ aName = ::rtl::OUString::createFromAscii( "dummyObjectName" );
+
+ if( aName.getLength() )
+ {
+ sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
+ }
+ }
+
+ sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+
+ sal_uInt32 nMetaRetval(0);
+ if(!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aMetaArgs(1);
+ uno::Any* pMetaArgs = aMetaArgs.getArray();
+ pMetaArgs[0] <<= xInfoSet;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import start" );
+
+ nMetaRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs,
+ sal_False);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import end" );
+ }
+
+ SvXMLGraphicHelper* pGraphicHelper = NULL;
+ uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
+
+ uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
+ SvXMLEmbeddedObjectHelper *pObjectHelper = NULL;
+
+ if( xStorage.is() )
+ {
+ pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
+ xGrfContainer = pGraphicHelper;
+
+ if( pObjSh )
+ {
+ pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_READ, sal_False );
+ xObjectResolver = pObjectHelper;
+ }
+ }
+ uno::Sequence<uno::Any> aStylesArgs(4);
+ uno::Any* pStylesArgs = aStylesArgs.getArray();
+ pStylesArgs[0] <<= xInfoSet;
+ pStylesArgs[1] <<= xGrfContainer;
+ pStylesArgs[2] <<= xStatusIndicator;
+ pStylesArgs[3] <<= xObjectResolver;
+
+ sal_uInt32 nSettingsRetval(0);
+ if (!bStylesOnly)
+ {
+ // Settings must be loaded first because of the printer setting,
+ // which is needed in the page styles (paper tray).
+
+ uno::Sequence<uno::Any> aSettingsArgs(1);
+ uno::Any* pSettingsArgs = aSettingsArgs.getArray();
+ pSettingsArgs[0] <<= xInfoSet;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import start" );
+
+ nSettingsRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
+ sEmpty, aSettingsArgs, sal_False);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import end" );
+ }
+
+ sal_uInt32 nStylesRetval(0);
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import start" );
+
+ nStylesRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
+ sEmpty, aStylesArgs, sal_True);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import end" );
+ }
+
+ sal_uInt32 nDocRetval(0);
+ if (!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aDocArgs(4);
+ uno::Any* pDocArgs = aDocArgs.getArray();
+ pDocArgs[0] <<= xInfoSet;
+ pDocArgs[1] <<= xGrfContainer;
+ pDocArgs[2] <<= xStatusIndicator;
+ pDocArgs[3] <<= xObjectResolver;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import start" );
+
+ nDocRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content.xml")), aDocArgs,
+ sal_True);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import end" );
+ }
+ if( pGraphicHelper )
+ SvXMLGraphicHelper::Destroy( pGraphicHelper );
+
+ if( pObjectHelper )
+ SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+
+ sal_Bool bRet(sal_False);
+ if (bStylesOnly)
+ {
+ if (nStylesRetval)
+ nError = nStylesRetval;
+ else
+ bRet = sal_True;
+ }
+ else
+ {
+ if (nDocRetval)
+ {
+ nError = nDocRetval;
+ if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW ||
+ nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW ||
+ nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW ||
+ nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW)
+ bRet = sal_True;
+ }
+ else if (nStylesRetval)
+ nError = nStylesRetval;
+ else if (nMetaRetval)
+ nError = nMetaRetval;
+ else if (nSettingsRetval)
+ nError = nSettingsRetval;
+ else
+ bRet = sal_True;
+ }
+
+ // set BuildId on XModel for later OLE object loading
+ if( xInfoSet.is() )
+ {
+ uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
+ if( xModelSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
+ OUString sBuildPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
+ if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) )
+ {
+ xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) );
+ }
+ }
+
+ // Set Code Names
+ uno::Any aAny = xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration") ));
+ uno::Reference <container::XNameAccess> xCodeNameAccess;
+ if( aAny >>= xCodeNameAccess )
+ XMLCodeNameProvider::set( xCodeNameAccess, &rDoc );
+ }
+
+ // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
+ return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval;
+ }
+ return sal_False;
+}
+
+bool lcl_HasValidStream(ScDocument& rDoc)
+{
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ if ( pObjSh->IsDocShared() )
+ return false; // never copy stream from shared file
+
+ // don't read remote file again
+ // (could instead re-use medium directly in that case)
+ SfxMedium* pSrcMed = rDoc.GetDocumentShell()->GetMedium();
+ if ( !pSrcMed || pSrcMed->IsRemote() )
+ return false;
+
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (rDoc.IsStreamValid(nTab))
+ return true;
+ return false;
+}
+
+sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory,
+ uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xWriter,
+ uno::Sequence<beans::PropertyValue>& aDescriptor, const rtl::OUString& sName,
+ const rtl::OUString& sMediaType, const rtl::OUString& sComponentName,
+ const sal_Bool bPlainText, uno::Sequence<uno::Any>& aArgs, ScMySharedData*& pSharedData)
+{
+ sal_Bool bRet(sal_False);
+ uno::Reference<io::XOutputStream> xOut;
+ uno::Reference<io::XStream> xStream;
+
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetOutputStorage();
+
+ if( xStorage.is() )
+ {
+ // #96807#; trunc stream before use, because it could be an existing stream
+ // and the new content could be shorter than the old content. In this case
+ // would not all be over written by the new content and the xml file
+ // would not be valid.
+ xStream = xStorage->openStreamElement( sName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+ uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
+ if (xSet.is())
+ {
+ xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType));
+ OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
+ if (bPlainText)
+ xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), uno::makeAny(sal_False));
+
+ // even plain stream should be encrypted in encrypted documents
+ xSet->setPropertyValue( aUseCommonPassPropName, uno::makeAny(sal_True) );
+ }
+
+ xOut = xStream->getOutputStream();
+ }
+ // #99667#; no longer necessary
+/* else if ( pMedium )
+ {
+ xOut = pMedium->GetDataSink();
+ }*/
+
+ // set Base URL
+ uno::Reference< beans::XPropertySet > xInfoSet;
+ if( aArgs.getLength() > 0 )
+ aArgs.getConstArray()[0] >>= xInfoSet;
+ DBG_ASSERT( xInfoSet.is(), "missing property set" );
+ if( xInfoSet.is() )
+ {
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( sName ) );
+ }
+
+ uno::Reference<io::XActiveDataSource> xSrc( xWriter, uno::UNO_QUERY );
+ xSrc->setOutputStream( xOut );
+
+ uno::Reference<document::XFilter> xFilter(
+ xServiceFactory->createInstanceWithArguments( sComponentName , aArgs ),
+ uno::UNO_QUERY );
+ DBG_ASSERT( xFilter.is(), "can't get exporter" );
+ uno::Reference<document::XExporter> xExporter( xFilter, uno::UNO_QUERY );
+ uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY );
+ if (xExporter.is())
+ xExporter->setSourceDocument( xComponent );
+
+ if ( xFilter.is() )
+ {
+ ScXMLExport* pExport = static_cast<ScXMLExport*>(SvXMLExport::getImplementation(xFilter));
+ pExport->SetSharedData(pSharedData);
+
+ // if there are sheets to copy, get the source stream
+ if ( sName.equalsAscii("content.xml") && lcl_HasValidStream(rDoc) &&
+ ( pExport->getExportFlags() & EXPORT_OASIS ) )
+ {
+ // old stream is still in this file's storage - open read-only
+
+ // #i106854# use the document's storage directly, without a temporary SfxMedium
+ uno::Reference<embed::XStorage> xTmpStorage = rDoc.GetDocumentShell()->GetStorage();
+ uno::Reference<io::XStream> xSrcStream;
+ uno::Reference<io::XInputStream> xSrcInput;
+
+ // #i108978# If an embedded object is saved and no events are notified, don't use the stream
+ // because without the ...DONE events, stream positions aren't updated.
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xModel)->GetSheetSaveData();
+ if (pSheetData && pSheetData->IsInSupportedSave())
+ {
+ try
+ {
+ if (xTmpStorage.is())
+ xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ );
+ if (xSrcStream.is())
+ xSrcInput = xSrcStream->getInputStream();
+ }
+ catch (uno::Exception&)
+ {
+ // stream not available (for example, password protected) - save normally (xSrcInput is null)
+ }
+ }
+
+ pExport->SetSourceStream( xSrcInput );
+ bRet = xFilter->filter( aDescriptor );
+ pExport->SetSourceStream( uno::Reference<io::XInputStream>() );
+
+ // If there was an error, reset all stream flags, so the next save attempt will use normal saving.
+ // #i110692# For embedded objects, the stream may be unavailable for one save operation (m_pAntiImpl)
+ // and become available again later. But after saving normally once, the stream positions aren't
+ // valid anymore, so the flags also have to be reset if the stream wasn't available.
+ if ( !bRet || !xSrcInput.is() )
+ {
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (rDoc.IsStreamValid(nTab))
+ rDoc.SetStreamValid(nTab, FALSE);
+ }
+ }
+ else
+ bRet = xFilter->filter( aDescriptor );
+
+ pSharedData = pExport->GetSharedData();
+
+ //stream is closed by SAX parser
+ //if (xOut.is())
+ // xOut->closeOutput();
+ }
+ return bRet;
+}
+
+sal_Bool ScXMLImportWrapper::Export(sal_Bool bStylesOnly)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Export" );
+
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory(comphelper::getProcessServiceFactory());
+ DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
+ if( !xServiceFactory.is() )
+ return sal_False;
+
+ uno::Reference<uno::XInterface> xWriter(xServiceFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) ));
+ DBG_ASSERT( xWriter.is(), "com.sun.star.xml.sax.Writer service missing" );
+ if(!xWriter.is())
+ return sal_False;
+
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetOutputStorage();
+
+ uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY );
+
+ OUString sFileName;
+ OUString sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml"));
+ if (pMedium)
+ sFileName = pMedium->GetName();
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ uno::Sequence<beans::PropertyValue> aDescriptor(1);
+ beans::PropertyValue* pProps = aDescriptor.getArray();
+ pProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
+ pProps[0].Value <<= sFileName;
+
+ /** property map for export info set */
+ comphelper::PropertyMapEntry aExportInfoMap[] =
+ {
+ { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "WrittenNumberStyles" ), 0, &::getCppuType((uno::Sequence<sal_Int32>*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StyleNames" ), 0, &::getCppuType( (uno::Sequence<rtl::OUString>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StyleFamilies" ), 0, &::getCppuType( (uno::Sequence<sal_Int32>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
+
+ if ( pObjSh && xStorage.is() )
+ {
+ pObjSh->UpdateDocInfoForSave(); // update information
+
+ uno::Reference<frame::XModel> xModel(pObjSh->GetModel());
+ uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator());
+ sal_Int32 nProgressRange(1000000);
+ if(xStatusIndicator.is())
+ xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_SAVE_DOC)), nProgressRange);
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange));
+
+ SvtSaveOptions aSaveOpt;
+ sal_Bool bUsePrettyPrinting(aSaveOpt.IsPrettyPrinting());
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(bUsePrettyPrinting));
+
+ const OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") );
+ xInfoSet->setPropertyValue( sTargetStorage, uno::Any( xStorage ) );
+
+ OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
+ ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL( true ) : ::rtl::OUString();
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
+
+ // TODO/LATER: do not do it for embedded links
+ if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() )
+ {
+ OUString aName = ::rtl::OUString::createFromAscii( "dummyObjectName" );
+ if ( pMedium && pMedium->GetItemSet() )
+ {
+ const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+ pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+ if ( pDocHierarchItem )
+ aName = pDocHierarchItem->GetValue();
+ }
+
+ if( aName.getLength() )
+ {
+ sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
+ }
+ }
+
+ sal_Bool bMetaRet(pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
+ sal_Bool bStylesRet (sal_False);
+ sal_Bool bDocRet(sal_False);
+ sal_Bool bSettingsRet(sal_False);
+ ScMySharedData* pSharedData = NULL;
+
+ sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+
+ // meta export
+ if (!bStylesOnly && !bMetaRet)
+ {
+ uno::Sequence<uno::Any> aMetaArgs(3);
+ uno::Any* pMetaArgs = aMetaArgs.getArray();
+ pMetaArgs[0] <<= xInfoSet;
+ pMetaArgs[1] <<= xHandler;
+ pMetaArgs[2] <<= xStatusIndicator;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export start" );
+
+ bMetaRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaExporter")),
+ sal_True, aMetaArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export end" );
+ }
+
+ uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
+ SvXMLEmbeddedObjectHelper *pObjectHelper = 0;
+
+ uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
+ SvXMLGraphicHelper* pGraphicHelper = 0;
+
+ if( xStorage.is() )
+ {
+ pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, FALSE );
+ xGrfContainer = pGraphicHelper;
+ }
+
+ if( pObjSh )
+ {
+ pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, sal_False );
+ xObjectResolver = pObjectHelper;
+ }
+
+ // styles export
+
+ {
+ uno::Sequence<uno::Any> aStylesArgs(5);
+ uno::Any* pStylesArgs = aStylesArgs.getArray();
+ pStylesArgs[0] <<= xInfoSet;
+ pStylesArgs[1] <<= xGrfContainer;
+ pStylesArgs[2] <<= xStatusIndicator;
+ pStylesArgs[3] <<= xHandler;
+ pStylesArgs[4] <<= xObjectResolver;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export start" );
+
+ bStylesRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesExporter")),
+ sal_False, aStylesArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export end" );
+ }
+
+ // content export
+
+ if (!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aDocArgs(5);
+ uno::Any* pDocArgs = aDocArgs.getArray();
+ pDocArgs[0] <<= xInfoSet;
+ pDocArgs[1] <<= xGrfContainer;
+ pDocArgs[2] <<= xStatusIndicator;
+ pDocArgs[3] <<= xHandler;
+ pDocArgs[4] <<= xObjectResolver;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export start" );
+
+ bDocRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("content.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentExporter")),
+ sal_False, aDocArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export end" );
+ }
+
+ if( pGraphicHelper )
+ SvXMLGraphicHelper::Destroy( pGraphicHelper );
+
+ if( pObjectHelper )
+ SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
+
+ // settings export
+
+ if (!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aSettingsArgs(3);
+ uno::Any* pSettingsArgs = aSettingsArgs.getArray();
+ pSettingsArgs[0] <<= xInfoSet;
+ pSettingsArgs[1] <<= xHandler;
+ pSettingsArgs[2] <<= xStatusIndicator;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export start" );
+
+ bSettingsRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsExporter")),
+ sal_False, aSettingsArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export end" );
+ }
+
+ if (pSharedData)
+ delete pSharedData;
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+ return bStylesRet && ((!bStylesOnly && bDocRet && bMetaRet && bSettingsRet) || bStylesOnly);
+ }
+
+ // later: give string descriptor as parameter for doc type
+
+ return sal_False;
+}
+
+
+
diff --git a/sc/source/ui/Accessibility/AccessibilityHints.cxx b/sc/source/ui/Accessibility/AccessibilityHints.cxx
new file mode 100644
index 000000000000..6c276b806e88
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibilityHints.cxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "AccessibilityHints.hxx"
+
+using namespace ::com::sun::star;
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccWinFocusLostHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccWinFocusLostHint - the current window lost its focus (to another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccWinFocusLostHint::ScAccWinFocusLostHint(
+ const uno::Reference< uno::XInterface >& xOld )
+ :
+ xOldAccessible(xOld)
+{
+}
+
+ScAccWinFocusLostHint::~ScAccWinFocusLostHint()
+{
+}
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccWinFocusGotHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccWinFocusGotHint - the window got the focus (from another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccWinFocusGotHint::ScAccWinFocusGotHint(
+ const uno::Reference< uno::XInterface >& xNew )
+ :
+ xNewAccessible(xNew)
+{
+}
+
+ScAccWinFocusGotHint::~ScAccWinFocusGotHint()
+{
+}
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccGridWinFocusLostHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccGridWinFocusLostHint - the current grid window lost its focus (to another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccGridWinFocusLostHint::ScAccGridWinFocusLostHint(ScSplitPos eOld,
+ const uno::Reference< uno::XInterface >& xOld )
+ :
+ ScAccWinFocusLostHint(xOld),
+ eOldGridWin(eOld)
+{
+}
+
+ScAccGridWinFocusLostHint::~ScAccGridWinFocusLostHint()
+{
+}
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccGridWinFocusGotHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccGridWinFocusGotHint - the grid window got the focus (from another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccGridWinFocusGotHint::ScAccGridWinFocusGotHint(ScSplitPos eNew,
+ const uno::Reference< uno::XInterface >& xNew )
+ :
+ ScAccWinFocusGotHint(xNew),
+ eNewGridWin(eNew)
+{
+}
+
+ScAccGridWinFocusGotHint::~ScAccGridWinFocusGotHint()
+{
+}
diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx
new file mode 100644
index 000000000000..434ea2dea40c
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleCell.cxx
@@ -0,0 +1,459 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleCell.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include "AccessibleText.hxx"
+#include "AccessibleDocument.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "miscuno.hxx"
+#include "unoguard.hxx"
+#include "editsrc.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <editeng/brshitem.hxx>
+#include <comphelper/sequence.hxx>
+#include <float.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleCell::ScAccessibleCell(
+ const uno::Reference<XAccessible>& rxParent,
+ ScTabViewShell* pViewShell,
+ ScAddress& rCellAddress,
+ sal_Int32 nIndex,
+ ScSplitPos eSplitPos,
+ ScAccessibleDocument* pAccDoc)
+ :
+ ScAccessibleCellBase(rxParent, GetDocument(pViewShell), rCellAddress, nIndex),
+ ::accessibility::AccessibleStaticTextBase(CreateEditSource(pViewShell, rCellAddress, eSplitPos)),
+ mpViewShell(pViewShell),
+ mpAccDoc(pAccDoc),
+ meSplitPos(eSplitPos)
+{
+ if (pViewShell)
+ pViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessibleCell::~ScAccessibleCell()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleCell::Init()
+{
+ ScAccessibleCellBase::Init();
+
+ SetEventSource(this);
+}
+
+void SAL_CALL ScAccessibleCell::disposing()
+{
+ ScUnoGuard aGuard;
+ // #100593# dispose in AccessibleStaticTextBase
+ Dispose();
+
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ mpAccDoc = NULL;
+
+ ScAccessibleCellBase::disposing();
+}
+
+ //===== XInterface =====================================================
+
+IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase )
+
+ //===== XTypeProvider ===================================================
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase )
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleCell::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ return AccessibleStaticTextBase::getAccessibleAtPoint(rPoint);
+}
+
+void SAL_CALL ScAccessibleCell::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is() && mpViewShell)
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ {
+ xAccessibleComponent->grabFocus();
+ mpViewShell->SetCursor(maCellAddress.Col(), maCellAddress.Row());
+ }
+ }
+}
+
+Rectangle ScAccessibleCell::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aCellRect(GetBoundingBox());
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessibleCell::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+ if (mpViewShell)
+ {
+ long nSizeX, nSizeY;
+ mpViewShell->GetViewData()->GetMergeSizePixel(
+ maCellAddress.Col(), maCellAddress.Row(), nSizeX, nSizeY);
+ aCellRect.SetSize(Size(nSizeX, nSizeY));
+ aCellRect.SetPos(mpViewShell->GetViewData()->GetScrPos(maCellAddress.Col(), maCellAddress.Row(), meSplitPos, TRUE));
+
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ {
+ Rectangle aRect(pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()));
+ aRect.Move(-aRect.Left(), -aRect.Top());
+ aCellRect = aRect.Intersection(aCellRect);
+ }
+
+ /* #i19430# Gnopernicus reads text partly if it sticks out of the cell
+ boundaries. This leads to wrong results in cases where the cell
+ text is rotated, because rotation is not taken into account when
+ calculating the visible part of the text. In these cases we will
+ simply expand the cell size to the width of the unrotated text. */
+ if (mpDoc)
+ {
+ const SfxInt32Item* pItem = static_cast< const SfxInt32Item* >(
+ mpDoc->GetAttr( maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_ROTATE_VALUE ) );
+ if( pItem && (pItem->GetValue() != 0) )
+ {
+ Rectangle aParaRect = GetParagraphBoundingBox();
+ if( !aParaRect.IsEmpty() && (aCellRect.GetWidth() < aParaRect.GetWidth()) )
+ aCellRect.SetSize( Size( aParaRect.GetWidth(), aCellRect.GetHeight() ) );
+ }
+ }
+ }
+ if (aCellRect.IsEmpty())
+ aCellRect.SetPos(Point(-1, -1));
+ return aCellRect;
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleCell::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ return AccessibleStaticTextBase::getAccessibleChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessibleCell::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ return AccessibleStaticTextBase::getAccessibleChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleCell::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ if (IsEditable(xParentStates))
+ {
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::RESIZABLE);
+ }
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
+ if (IsOpaque(xParentStates))
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ pStateSet->AddState(AccessibleStateType::SELECTABLE);
+ if (IsSelected())
+ pStateSet->AddState(AccessibleStateType::SELECTED);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::TRANSIENT);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ ScAccessibleCell::getAccessibleRelationSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ utl::AccessibleRelationSetHelper* pRelationSet = NULL;
+ if (mpAccDoc)
+ pRelationSet = mpAccDoc->GetRelationSet(&maCellAddress);
+ if (!pRelationSet)
+ pRelationSet = new utl::AccessibleRelationSetHelper();
+ FillDependends(pRelationSet);
+ FillPrecedents(pRelationSet);
+ return pRelationSet;
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleCell::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCell"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleCell::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AccessibleCell"));
+
+ return aSequence;
+}
+
+ //==== internal =========================================================
+
+sal_Bool ScAccessibleCell::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpDoc == NULL) || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessibleCell::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ sal_Bool bEditable(sal_True);
+ if (rxParentStates.is() && !rxParentStates->contains(AccessibleStateType::EDITABLE) &&
+ mpDoc)
+ {
+ // here I have to test whether the protection of the table should influence this cell.
+ const ScProtectionAttr* pItem = (const ScProtectionAttr*)mpDoc->GetAttr(
+ maCellAddress.Col(), maCellAddress.Row(),
+ maCellAddress.Tab(), ATTR_PROTECTION);
+ if (pItem)
+ bEditable = !pItem->GetProtection();
+ }
+ return bEditable;
+}
+
+sal_Bool ScAccessibleCell::IsOpaque(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ // test whether there is a background color
+ sal_Bool bOpaque(sal_True);
+ if (mpDoc)
+ {
+ const SvxBrushItem* pItem = (const SvxBrushItem*)mpDoc->GetAttr(
+ maCellAddress.Col(), maCellAddress.Row(),
+ maCellAddress.Tab(), ATTR_BACKGROUND);
+ if (pItem)
+ bOpaque = pItem->GetColor() != COL_TRANSPARENT;
+ }
+ return bOpaque;
+}
+
+sal_Bool ScAccessibleCell::IsSelected()
+{
+ sal_Bool bResult(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsCellMarked(maCellAddress.Col(), maCellAddress.Row());
+ }
+ return bResult;
+}
+
+ScDocument* ScAccessibleCell::GetDocument(ScTabViewShell* pViewShell)
+{
+ ScDocument* pDoc = NULL;
+ if (pViewShell && pViewShell->GetViewData())
+ pDoc = pViewShell->GetViewData()->GetDocument();
+ return pDoc;
+}
+
+::std::auto_ptr< SvxEditSource > ScAccessibleCell::CreateEditSource(ScTabViewShell* pViewShell, ScAddress aCell, ScSplitPos eSplitPos)
+{
+ ::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData
+ ( new ScAccessibleCellTextData( pViewShell, aCell, eSplitPos, this ) );
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleCellTextData));
+
+ return pEditSource;
+}
+
+void ScAccessibleCell::FillDependends(utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ if (mpDoc)
+ {
+ ScCellIterator aCellIter( mpDoc, 0,0, maCellAddress.Tab(), MAXCOL,MAXROW, maCellAddress.Tab() );
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ sal_Bool bFound(sal_False);
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ while ( !bFound && aIter.GetNextRef( aRef ) )
+ {
+ if (aRef.In(maCellAddress))
+ bFound = sal_True;
+ }
+ if (bFound)
+ AddRelation(ScAddress(aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab()), AccessibleRelationType::CONTROLLER_FOR, pRelationSet);
+ }
+ pCell = aCellIter.GetNext();
+ }
+ }
+}
+
+void ScAccessibleCell::FillPrecedents(utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ if (mpDoc)
+ {
+ ScBaseCell* pBaseCell = mpDoc->GetCell(maCellAddress);
+ if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_FORMULA))
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pBaseCell;
+
+ ScDetectiveRefIter aIter( pFCell );
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef ) )
+ {
+ AddRelation( aRef, AccessibleRelationType::CONTROLLED_BY, pRelationSet);
+ }
+ }
+ }
+}
+
+void ScAccessibleCell::AddRelation(const ScAddress& rCell,
+ const sal_uInt16 aRelationType,
+ utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ AddRelation(ScRange(rCell, rCell), aRelationType, pRelationSet);
+}
+
+void ScAccessibleCell::AddRelation(const ScRange& rRange,
+ const sal_uInt16 aRelationType,
+ utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ uno::Reference < XAccessibleTable > xTable ( getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY );
+ if (xTable.is())
+ {
+ sal_uInt32 nCount(static_cast<sal_uInt32>(rRange.aEnd.Col() -
+ rRange.aStart.Col() + 1) * (rRange.aEnd.Row() -
+ rRange.aStart.Row() + 1));
+ uno::Sequence < uno::Reference < uno::XInterface > > aTargetSet( nCount );
+ uno::Reference < uno::XInterface >* pTargetSet = aTargetSet.getArray();
+ if (pTargetSet)
+ {
+ sal_uInt32 nPos(0);
+ for (sal_uInt32 nRow = rRange.aStart.Row(); nRow <= sal::static_int_cast<sal_uInt32>(rRange.aEnd.Row()); ++nRow)
+ {
+ for (sal_uInt32 nCol = rRange.aStart.Col(); nCol <= sal::static_int_cast<sal_uInt32>(rRange.aEnd.Col()); ++nCol)
+ {
+ pTargetSet[nPos] = xTable->getAccessibleCellAt(nRow, nCol);
+ ++nPos;
+ }
+ }
+ DBG_ASSERT(nCount == nPos, "something wents wrong");
+ }
+ AccessibleRelation aRelation;
+ aRelation.RelationType = aRelationType;
+ aRelation.TargetSet = aTargetSet;
+ pRelationSet->AddRelation(aRelation);
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx
new file mode 100644
index 000000000000..cc93d0a93350
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleCellBase.hxx"
+#include "attrib.hxx"
+#include "scitems.hxx"
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "docfunc.hxx"
+#include "cell.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+#include "unonames.hxx"
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <tools/debug.hxx>
+#include <editeng/brshitem.hxx>
+#include <rtl/uuid.h>
+#include <comphelper/sequence.hxx>
+#include <sfx2/objsh.hxx>
+
+#include <float.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleCellBase::ScAccessibleCellBase(
+ const uno::Reference<XAccessible>& rxParent,
+ ScDocument* pDoc,
+ const ScAddress& rCellAddress,
+ sal_Int32 nIndex)
+ :
+ ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL),
+ maCellAddress(rCellAddress),
+ mpDoc(pDoc),
+ mnIndex(nIndex)
+{
+}
+
+ScAccessibleCellBase::~ScAccessibleCellBase()
+{
+}
+
+ //===== XAccessibleComponent ============================================
+
+sal_Bool SAL_CALL ScAccessibleCellBase::isVisible( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ // test whether the cell is hidden (column/row - hidden/filtered)
+ sal_Bool bVisible(sal_True);
+ if (mpDoc)
+ {
+ bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab());
+ bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab());
+ bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab());
+ bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab());
+
+ if (bColHidden || bColFiltered || bRowHidden || bRowFiltered)
+ bVisible = sal_False;
+ }
+ return bVisible;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDoc)
+ {
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ if ( pObjSh )
+ {
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
+ uno::Reference<sheet::XSpreadsheet> xTable;
+ if (aTable>>=xTable)
+ {
+ uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
+ if (xCell.is())
+ {
+ uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
+ if (xCellProps.is())
+ {
+ uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CCOLOR)));
+ aAny >>= nColor;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return nColor;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+
+ if (mpDoc)
+ {
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ if ( pObjSh )
+ {
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
+ uno::Reference<sheet::XSpreadsheet> xTable;
+ if (aTable>>=xTable)
+ {
+ uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
+ if (xCell.is())
+ {
+ uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
+ if (xCellProps.is())
+ {
+ uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLBACK)));
+ aAny >>= nColor;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return nColor;
+}
+
+ //===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleCellBase::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleCellBase::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32
+ ScAccessibleCellBase::getAccessibleIndexInParent(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return mnIndex;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleCellBase::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_CELL_DESCR));
+
+ return sDescription;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleCellBase::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName( ScResId(STR_ACC_CELL_NAME) );
+ String sAddress;
+ // Document not needed, because only the cell address, but not the tablename is needed
+ // always us OOO notation
+ maCellAddress.Format( sAddress, SCA_VALID, NULL );
+ sName.SearchAndReplaceAscii("%1", sAddress);
+ /* #i65103# ZoomText merges cell address and contents, e.g. if value 2 is
+ contained in cell A1, ZT reads "cell A twelve" instead of "cell A1 - 2".
+ Simple solution: Append a space character to the cell address. */
+ sName.Append( ' ' );
+ return rtl::OUString(sName);
+}
+
+ //===== XAccessibleValue ================================================
+
+uno::Any SAL_CALL
+ ScAccessibleCellBase::getCurrentValue( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Any aAny;
+ if (mpDoc)
+ aAny <<= mpDoc->GetValue(maCellAddress);
+
+ return aAny;
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ double fValue = 0;
+ sal_Bool bResult(sal_False);
+ if((aNumber >>= fValue) && mpDoc && mpDoc->GetDocumentShell())
+ {
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ if (IsEditable(xParentStates))
+ {
+ ScDocShell* pDocShell = (ScDocShell*) mpDoc->GetDocumentShell();
+ ScDocFunc aFunc(*pDocShell);
+ bResult = aFunc.PutCell( maCellAddress, new ScValueCell(fValue), TRUE );
+ }
+ }
+ return bResult;
+}
+
+uno::Any SAL_CALL
+ ScAccessibleCellBase::getMaximumValue( )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny;
+ aAny <<= DBL_MAX;
+
+ return aAny;
+}
+
+uno::Any SAL_CALL
+ ScAccessibleCellBase::getMinimumValue( )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny;
+ aAny <<= -DBL_MAX;
+
+ return aAny;
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleCellBase::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCellBase"));
+}
+
+ //===== XTypeProvider ===================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleCellBase::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+sal_Bool ScAccessibleCellBase::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ sal_Bool bEditable(sal_False);
+ if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE))
+ bEditable = sal_True;
+ return bEditable;
+}
diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx
new file mode 100644
index 000000000000..0f1fcfa337a5
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx
@@ -0,0 +1,628 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleContextBase.hxx"
+#include "unoguard.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <toolkit/helper/convert.hxx>
+#include <svl/smplhint.hxx>
+#include <comphelper/sequence.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <vcl/unohelp.hxx>
+#include <tools/color.hxx>
+#include <comphelper/accessibleeventnotifier.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+DBG_NAME(ScAccessibleContextBase)
+
+ScAccessibleContextBase::ScAccessibleContextBase(
+ const uno::Reference<XAccessible>& rxParent,
+ const sal_Int16 aRole)
+ :
+ ScAccessibleContextBaseWeakImpl(m_aMutex),
+ mxParent(rxParent),
+ mnClientId(0),
+ maRole(aRole)
+{
+ DBG_CTOR(ScAccessibleContextBase, NULL);
+}
+
+
+ScAccessibleContextBase::~ScAccessibleContextBase(void)
+{
+ DBG_DTOR(ScAccessibleContextBase, NULL);
+
+ if (!IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleContextBase::Init()
+{
+ // hold reference to make sure that the destructor is not called
+ uno::Reference< XAccessibleContext > xOwnContext(this);
+
+ if (mxParent.is())
+ {
+ uno::Reference< XAccessibleEventBroadcaster > xBroadcaster (mxParent->getAccessibleContext(), uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->addEventListener(this);
+ }
+ msName = createAccessibleName();
+ msDescription = createAccessibleDescription();
+}
+
+void SAL_CALL ScAccessibleContextBase::disposing()
+{
+ ScUnoGuard aGuard;
+// CommitDefunc(); not necessary and should not be send, because it cost a lot of time
+
+ // hold reference to make sure that the destructor is not called
+ uno::Reference< XAccessibleContext > xOwnContext(this);
+
+ if ( mnClientId )
+ {
+ sal_Int32 nTemClientId(mnClientId);
+ mnClientId = 0;
+ comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nTemClientId, *this );
+ }
+
+ if (mxParent.is())
+ {
+ uno::Reference< XAccessibleEventBroadcaster > xBroadcaster (mxParent->getAccessibleContext(), uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->removeEventListener(this);
+ mxParent = NULL;
+ }
+
+ ScAccessibleContextBaseWeakImpl::disposing();
+}
+
+//===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleContextBase::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleContextBaseWeakImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBaseImplEvent::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleContextBase::acquire()
+ throw ()
+{
+ ScAccessibleContextBaseWeakImpl::acquire();
+}
+
+void SAL_CALL ScAccessibleContextBase::release()
+ throw ()
+{
+ ScAccessibleContextBaseWeakImpl::release();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessibleContextBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ if (rRef.GetId() == SFX_HINT_DYING)
+ {
+ // it seems the Broadcaster is dying, since the view is dying
+ dispose();
+ }
+ }
+}
+
+//===== XAccessible =========================================================
+
+uno::Reference< XAccessibleContext> SAL_CALL
+ ScAccessibleContextBase::getAccessibleContext(void)
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//===== XAccessibleComponent ================================================
+
+sal_Bool SAL_CALL ScAccessibleContextBase::containsPoint(const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return Rectangle (Point(), GetBoundingBox().GetSize()).IsInside(VCLPoint(rPoint));
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleContextBase::getAccessibleAtPoint(
+ const awt::Point& /* rPoint */ )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+ return uno::Reference<XAccessible>();
+}
+
+awt::Rectangle SAL_CALL ScAccessibleContextBase::getBounds( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTRectangle(GetBoundingBox());
+}
+
+awt::Point SAL_CALL ScAccessibleContextBase::getLocation( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTPoint(GetBoundingBox().TopLeft());
+}
+
+awt::Point SAL_CALL ScAccessibleContextBase::getLocationOnScreen( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTPoint(GetBoundingBoxOnScreen().TopLeft());
+}
+
+awt::Size SAL_CALL ScAccessibleContextBase::getSize( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTSize(GetBoundingBox().GetSize());
+}
+
+sal_Bool SAL_CALL ScAccessibleContextBase::isShowing( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Bool bShowing(sal_False);
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleComponent> xParentComponent (mxParent->getAccessibleContext(), uno::UNO_QUERY);
+ if (xParentComponent.is())
+ {
+ Rectangle aParentBounds(VCLRectangle(xParentComponent->getBounds()));
+ Rectangle aBounds(VCLRectangle(getBounds()));
+ bShowing = aBounds.IsOver(aParentBounds);
+ }
+ }
+ return bShowing;
+}
+
+sal_Bool SAL_CALL ScAccessibleContextBase::isVisible( )
+ throw (uno::RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL ScAccessibleContextBase::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+sal_Int32 SAL_CALL ScAccessibleContextBase::getForeground( )
+ throw (uno::RuntimeException)
+{
+ return COL_BLACK;
+}
+
+sal_Int32 SAL_CALL ScAccessibleContextBase::getBackground( )
+ throw (uno::RuntimeException)
+{
+ return COL_WHITE;
+}
+
+//===== XAccessibleContext ==================================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleContextBase::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return 0;
+}
+
+uno::Reference<XAccessible> SAL_CALL
+ ScAccessibleContextBase::getAccessibleChild(sal_Int32 /* nIndex */)
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return uno::Reference<XAccessible>();
+}
+
+uno::Reference<XAccessible> SAL_CALL
+ ScAccessibleContextBase::getAccessibleParent(void)
+ throw (uno::RuntimeException)
+{
+ return mxParent;
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleContextBase::getAccessibleIndexInParent(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ // Use a simple but slow solution for now. Optimize later.
+ // Return -1 to indicate that this object's parent does not know about the
+ // object.
+ sal_Int32 nIndex(-1);
+
+ // Iterate over all the parent's children and search for this object.
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext (
+ mxParent->getAccessibleContext());
+ if (xParentContext.is())
+ {
+ sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
+ for (sal_Int32 i=0; i<nChildCount; ++i)
+ {
+ uno::Reference<XAccessible> xChild (xParentContext->getAccessibleChild (i));
+ if (xChild.is())
+ {
+ if (xChild.get() == this)
+ nIndex = i;
+ }
+ }
+ }
+ }
+
+ return nIndex;
+}
+
+sal_Int16 SAL_CALL
+ ScAccessibleContextBase::getAccessibleRole(void)
+ throw (uno::RuntimeException)
+{
+ return maRole;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::getAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!msDescription.getLength())
+ {
+ OUString sDescription(createAccessibleDescription());
+// DBG_ASSERT(sDescription.getLength(), "We should give always a descripition.");
+
+ if (msDescription != sDescription)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= msDescription;
+ aEvent.NewValue <<= sDescription;
+
+ msDescription = sDescription;
+
+ CommitChange(aEvent);
+ }
+ }
+ return msDescription;
+}
+
+OUString SAL_CALL
+ ScAccessibleContextBase::getAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!msName.getLength())
+ {
+ OUString sName(createAccessibleName());
+ DBG_ASSERT(sName.getLength(), "We should give always a name.");
+
+ if (msName != sName)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::NAME_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= msName;
+ aEvent.NewValue <<= sName;
+
+ msName = sName;
+
+ CommitChange(aEvent);
+ }
+ }
+ return msName;
+}
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ ScAccessibleContextBase::getAccessibleRelationSet(void)
+ throw (uno::RuntimeException)
+{
+ return new utl::AccessibleRelationSetHelper();
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleContextBase::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ return uno::Reference<XAccessibleStateSet>();
+}
+
+lang::Locale SAL_CALL
+ ScAccessibleContextBase::getLocale(void)
+ throw (IllegalAccessibleComponentStateException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext (
+ mxParent->getAccessibleContext());
+ if (xParentContext.is())
+ return xParentContext->getLocale ();
+ }
+
+ // No locale and no parent. Therefore throw exception to indicate this
+ // cluelessness.
+ throw IllegalAccessibleComponentStateException ();
+}
+
+ //===== XAccessibleEventBroadcaster =====================================
+
+void SAL_CALL
+ ScAccessibleContextBase::addEventListener(
+ const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!IsDefunc())
+ {
+ if (!mnClientId)
+ mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
+ comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
+ }
+ }
+}
+
+void SAL_CALL
+ ScAccessibleContextBase::removeEventListener(
+ const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ if (!IsDefunc() && mnClientId)
+ {
+ sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
+ if ( !nListenerCount )
+ {
+ // no listeners anymore
+ // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
+ // and at least to us not firing any events anymore, in case somebody calls
+ // NotifyAccessibleEvent, again
+ comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
+ mnClientId = 0;
+ }
+ }
+ }
+}
+
+ //===== XAccessibleEventListener ========================================
+
+void SAL_CALL ScAccessibleContextBase::disposing(
+ const lang::EventObject& rSource )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (rSource.Source == mxParent)
+ dispose();
+}
+
+void SAL_CALL ScAccessibleContextBase::notifyEvent(
+ const AccessibleEventObject& /* aEvent */ )
+ throw (uno::RuntimeException)
+{
+}
+
+//===== XServiceInfo ========================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleContextBase"));
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleContextBase::supportsService(const OUString& sServiceName)
+ throw (uno::RuntimeException)
+{
+ // Iterate over all supported service names and return true if on of them
+ // matches the given name.
+ uno::Sequence< ::rtl::OUString> aSupportedServices (
+ getSupportedServiceNames ());
+ sal_Int32 nLength(aSupportedServices.getLength());
+ const OUString* pServiceNames = aSupportedServices.getConstArray();
+ for (int i=0; i<nLength; ++i, ++pServiceNames)
+ if (sServiceName == *pServiceNames)
+ return sal_True;
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleContextBase::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence<OUString> aServiceNames(2);
+ OUString* pServiceNames = aServiceNames.getArray();
+ if (pServiceNames)
+ {
+ pServiceNames[0] = OUString(RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.Accessible"));
+ pServiceNames[1] = OUString(RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext"));
+ }
+
+ return aServiceNames;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleContextBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleContextBaseWeakImpl::getTypes(), ScAccessibleContextBaseImplEvent::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleContextBase::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//===== internal ============================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return rtl::OUString();
+}
+
+void ScAccessibleContextBase::CommitChange(const AccessibleEventObject& rEvent) const
+{
+ if (mnClientId)
+ comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
+}
+
+void ScAccessibleContextBase::ChangeName()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::NAME_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
+ aEvent.OldValue <<= msName;
+
+ msName = rtl::OUString(); // reset the name so it will be hold again
+ getAccessibleName(); // create the new name
+
+ aEvent.NewValue <<= msName;
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleContextBase::CommitFocusGained() const
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::STATE_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
+ aEvent.NewValue <<= AccessibleStateType::FOCUSED;
+
+ CommitChange(aEvent);
+
+ ::vcl::unohelper::NotifyAccessibleStateEventGlobally(aEvent);
+}
+
+void ScAccessibleContextBase::CommitFocusLost() const
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::STATE_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
+ aEvent.OldValue <<= AccessibleStateType::FOCUSED;
+
+ CommitChange(aEvent);
+
+ vcl::unohelper::NotifyAccessibleStateEventGlobally(aEvent);
+}
+
+Rectangle ScAccessibleContextBase::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+ return Rectangle();
+}
+
+Rectangle ScAccessibleContextBase::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+ return Rectangle();
+}
+
+void ScAccessibleContextBase::IsObjectValid() const
+ throw (lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ throw lang::DisposedException();
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleCsvControl.cxx b/sc/source/ui/Accessibility/AccessibleCsvControl.cxx
new file mode 100644
index 000000000000..e99bd1971e4c
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleCsvControl.cxx
@@ -0,0 +1,1680 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleCsvControl.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
+#include <tools/debug.hxx>
+#include <rtl/uuid.h>
+#include <toolkit/helper/convert.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <comphelper/sequence.hxx>
+#include "scitems.hxx"
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/langitem.hxx>
+#include "csvcontrol.hxx"
+#include "csvruler.hxx"
+#include "csvgrid.hxx"
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include <svtools/colorcfg.hxx>
+// ause
+#include "editutil.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::utl::AccessibleRelationSetHelper;
+using ::utl::AccessibleStateSetHelper;
+using ::accessibility::AccessibleStaticTextBase;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::lang::DisposedException;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::beans::PropertyValue;
+using namespace ::com::sun::star::accessibility;
+
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt16 nRulerRole = AccessibleRole::TEXT;
+const sal_uInt16 nGridRole = AccessibleRole::TABLE;
+const sal_uInt16 nCellRole = AccessibleRole::TEXT;
+
+#define CREATE_OUSTRING( name ) OUString( RTL_CONSTASCII_USTRINGPARAM( name ) )
+
+#define RULER_IMPL_NAME "ScAccessibleCsvRuler"
+#define GRID_IMPL_NAME "ScAccessibleCsvGrid"
+#define CELL_IMPL_NAME "ScAccessibleCsvCell"
+
+const sal_Unicode cRulerDot = '.';
+const sal_Unicode cRulerLine = '|';
+
+const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
+const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
+
+
+// CSV base control ===========================================================
+
+DBG_NAME( ScAccessibleCsvControl )
+
+ScAccessibleCsvControl::ScAccessibleCsvControl(
+ const Reference< XAccessible >& rxParent,
+ ScCsvControl& rControl,
+ sal_uInt16 nRole ) :
+ ScAccessibleContextBase( rxParent, nRole ),
+ mpControl( &rControl )
+{
+ DBG_CTOR( ScAccessibleCsvControl, NULL );
+}
+
+ScAccessibleCsvControl::~ScAccessibleCsvControl()
+{
+ DBG_DTOR( ScAccessibleCsvControl, NULL );
+ implDispose();
+}
+
+void SAL_CALL ScAccessibleCsvControl::disposing()
+{
+ ScUnoGuard aGuard;
+ mpControl = NULL;
+ ScAccessibleContextBase::disposing();
+}
+
+
+// XAccessibleComponent -------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const AwtPoint& /* rPoint */ )
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvControl::isVisible() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetControl().IsVisible();
+}
+
+void SAL_CALL ScAccessibleCsvControl::grabFocus() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ implGetControl().GrabFocus();
+}
+
+
+// events ---------------------------------------------------------------------
+
+void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
+{
+ if( bFocused )
+ CommitFocusGained();
+ else
+ CommitFocusLost();
+}
+
+void ScAccessibleCsvControl::SendCaretEvent()
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
+}
+
+void ScAccessibleCsvControl::SendVisibleEvent()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ CommitChange( aEvent );
+}
+
+void ScAccessibleCsvControl::SendSelectionEvent()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ CommitChange( aEvent );
+}
+
+void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
+}
+
+void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
+}
+
+void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
+}
+
+
+// helpers --------------------------------------------------------------------
+
+Rectangle ScAccessibleCsvControl::GetBoundingBoxOnScreen() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetControl().GetWindowExtentsRelative( NULL );
+}
+
+Rectangle ScAccessibleCsvControl::GetBoundingBox() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetControl().GetWindowExtentsRelative( implGetControl().GetAccessibleParentWindow() );
+}
+
+void ScAccessibleCsvControl::getUuid( Sequence< sal_Int8 >& rSeq )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ if( !rSeq.hasElements() )
+ {
+ rSeq.realloc( 16 );
+ rtl_createUuid( reinterpret_cast< sal_uInt8* >( rSeq.getArray() ), NULL, sal_True );
+ }
+}
+
+void ScAccessibleCsvControl::ensureAlive() const throw( DisposedException )
+{
+ if( !implIsAlive() )
+ throw DisposedException();
+}
+
+ScCsvControl& ScAccessibleCsvControl::implGetControl() const
+{
+ DBG_ASSERT( mpControl, "ScAccessibleCsvControl::implGetControl - missing control" );
+ return *mpControl;
+}
+
+Reference< XAccessible > ScAccessibleCsvControl::implGetChildByRole(
+ const Reference< XAccessible >& rxParentObj, sal_uInt16 nRole ) throw( RuntimeException )
+{
+ Reference< XAccessible > xAccObj;
+ if( rxParentObj.is() )
+ {
+ Reference< XAccessibleContext > xParentCtxt = rxParentObj->getAccessibleContext();
+ if( xParentCtxt.is() )
+ {
+ sal_Int32 nCount = xParentCtxt->getAccessibleChildCount();
+ sal_Int32 nIndex = 0;
+ while( !xAccObj.is() && (nIndex < nCount) )
+ {
+ Reference< XAccessible > xCurrObj = xParentCtxt->getAccessibleChild( nIndex );
+ if( xCurrObj.is() )
+ {
+ Reference< XAccessibleContext > xCurrCtxt = xCurrObj->getAccessibleContext();
+ if( xCurrCtxt.is() && (xCurrCtxt->getAccessibleRole() == nRole) )
+ xAccObj = xCurrObj;
+ }
+ ++nIndex;
+ }
+ }
+ }
+ return xAccObj;
+}
+
+AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet()
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper();
+ if( implIsAlive() )
+ {
+ const ScCsvControl& rCtrl = implGetControl();
+ pStateSet->AddState( AccessibleStateType::OPAQUE );
+ if( rCtrl.IsEnabled() )
+ pStateSet->AddState( AccessibleStateType::ENABLED );
+ if( isShowing() )
+ pStateSet->AddState( AccessibleStateType::SHOWING );
+ if( isVisible() )
+ pStateSet->AddState( AccessibleStateType::VISIBLE );
+ }
+ else
+ pStateSet->AddState( AccessibleStateType::DEFUNC );
+ return pStateSet;
+}
+
+void ScAccessibleCsvControl::implDispose()
+{
+ if( implIsAlive() )
+ {
+ // prevent multiple call of dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+Point ScAccessibleCsvControl::implGetAbsPos( const Point& rPos ) const
+{
+ return rPos + implGetControl().GetWindowExtentsRelative( NULL ).TopLeft();
+}
+
+
+// Ruler ======================================================================
+
+/** Converts a ruler cursor position to API text index. */
+sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
+{
+ sal_Int32 nApiPos = nRulerPos;
+ sal_Int32 nStart = (nRulerPos - 1) / 10;
+ sal_Int32 nExp = 1;
+ while( nStart >= nExp )
+ {
+ nApiPos += nStart - nExp + 1;
+ nExp *= 10;
+ }
+ return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
+}
+
+/** Converts an API text index to a ruler cursor position. */
+sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
+{
+ sal_Int32 nDiv = 10;
+ sal_Int32 nExp = 10;
+ sal_Int32 nRulerPos = 0;
+ sal_Int32 nApiBase = 0;
+ sal_Int32 nApiLimit = 10;
+ while( nApiPos >= nApiLimit )
+ {
+ ++nDiv;
+ nRulerPos = nExp;
+ nExp *= 10;
+ nApiBase = nApiLimit;
+ nApiLimit = lcl_GetApiPos( nExp );
+ }
+ sal_Int32 nRelPos = nApiPos - nApiBase;
+ return nRulerPos + nRelPos / nDiv * 10 + ::std::max( nRelPos % nDiv - nDiv + 10L, 0L );
+}
+
+/** Expands the sequence's size and returns the base index of the new inserted elements. */
+inline sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
+{
+ DBG_ASSERT( nExp > 0, "lcl_ExpandSequence - invalid value" );
+ rSeq.realloc( rSeq.getLength() + nExp );
+ return rSeq.getLength() - nExp;
+}
+
+/** Fills the property value rVal with the specified name and value from the item. */
+inline void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
+{
+ rVal.Name = rPropName;
+ rItem.QueryValue( rVal.Value, nMID );
+}
+
+/** Fills the sequence with all font attributes of rFont. */
+void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const Font& rFont )
+{
+ SvxFontItem aFontItem( rFont.GetFamily(), rFont.GetName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
+ SvxFontHeightItem aHeightItem( rFont.GetSize().Height(), 100, ATTR_FONT_HEIGHT );
+ SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
+
+ sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontName" ), aFontItem, MID_FONT_FAMILY_NAME );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontFamily" ), aFontItem, MID_FONT_FAMILY );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontStyleName" ), aFontItem, MID_FONT_STYLE_NAME );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontCharSet" ), aFontItem, MID_FONT_PITCH );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontPitch" ), aFontItem, MID_FONT_CHAR_SET );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharHeight" ), aHeightItem, MID_FONTHEIGHT );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharLocale" ), aLangItem, MID_LANG_LOCALE );
+}
+
+
+
+// ----------------------------------------------------------------------------
+
+DBG_NAME( ScAccessibleCsvRuler )
+
+ScAccessibleCsvRuler::ScAccessibleCsvRuler( ScCsvRuler& rRuler ) :
+ ScAccessibleCsvControl( rRuler.GetAccessibleParentWindow()->GetAccessible(), rRuler, nRulerRole )
+{
+ DBG_CTOR( ScAccessibleCsvRuler, NULL );
+ constructStringBuffer();
+}
+
+ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
+{
+ DBG_DTOR( ScAccessibleCsvRuler, NULL );
+ implDispose();
+}
+
+// XAccessibleComponent -----------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( )
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRuler().GetSettings().GetStyleSettings().GetLabelTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( )
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRuler().GetSettings().GetStyleSettings().GetFaceColor().GetColor();
+}
+
+// XAccessibleContext ---------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount() throw( RuntimeException )
+{
+ ensureAlive();
+ return 0;
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ throw IndexOutOfBoundsException();
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
+ Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nGridRole );
+ if( xAccObj.is() )
+ {
+ Sequence< Reference< XInterface > > aSeq( 1 );
+ aSeq[ 0 ] = xAccObj;
+ pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
+ }
+ return pRelationSet;
+}
+
+Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = implCreateStateSet();
+ if( implIsAlive() )
+ {
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
+ if( implGetRuler().HasFocus() )
+ pStateSet->AddState( AccessibleStateType::FOCUSED );
+ }
+ return pStateSet;
+}
+
+
+// XAccessibleText ------------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nIndex );
+ ScCsvRuler& rRuler = implGetRuler();
+ sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
+ rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
+ return rRuler.GetRulerCursorPos() != nOldCursor;
+}
+
+sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nIndex );
+ return maBuffer.charAt( nIndex );
+}
+
+Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& /* aRequestedAttributes */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+ Sequence< PropertyValue > aSeq;
+ lcl_FillFontAttributes( aSeq, implGetRuler().GetFont() );
+//! TODO split attribute: waiting for #102221#
+// if( implHasSplit( nIndex ) )
+// {
+// sal_Int32 nIndex = lcl_ExpandSequence( aSeq, 1 );
+// aSeq[ nIndex ].Name = CREATE_OUSTRING( "..." );
+// aSeq[ nIndex ].Value <<= ...;
+// }
+ return aSeq;
+}
+
+ScAccessibleCsvRuler::AwtRectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+ ScCsvRuler& rRuler = implGetRuler();
+ Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
+ AwtRectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetSizePixel().Height() );
+ // #107054# do not return rectangle out of window
+ sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
+ if( aRect.X >= nWidth )
+ throw IndexOutOfBoundsException();
+ if( aRect.X + aRect.Width > nWidth )
+ aRect.Width = nWidth - aRect.X;
+ return aRect;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetTextLength();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const AwtPoint& rPoint )
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ScCsvRuler& rRuler = implGetRuler();
+ // #107054# use object's coordinate system, convert to API position
+ return lcl_GetApiPos( ::std::min( ::std::max( rRuler.GetPosFromX( rPoint.X ), static_cast<sal_Int32>(0) ), rRuler.GetPosCount() ) );
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText() throw( RuntimeException )
+{
+ ensureAlive();
+ return OUString();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart() throw( RuntimeException )
+{
+ ensureAlive();
+ return -1;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd() throw( RuntimeException )
+{
+ ensureAlive();
+ return -1;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ return sal_False;
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::getText() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return OUString( maBuffer.getStr(), implGetTextLength() );
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidRange( nStartIndex, nEndIndex );
+ return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
+}
+
+TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
+ throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+
+ TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
+ return aResult;
+
+ ensureValidIndex( nIndex );
+
+ OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
+
+ switch( nTextType )
+ {
+ // single character
+ case AccessibleTextType::CHARACTER:
+ {
+ aResult.SegmentStart = nIndex;
+ aResultText.append( maBuffer.charAt( nIndex ) );
+ }
+ break;
+
+ // entire number or single dot/line
+ case AccessibleTextType::WORD:
+ case AccessibleTextType::GLYPH:
+ aResult.SegmentStart = nIndex;
+ if( nRulerPos % 10 )
+ aResultText.append( maBuffer.charAt( nIndex ) );
+ else
+ aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
+ break;
+
+ // entire text
+ case AccessibleTextType::SENTENCE:
+ case AccessibleTextType::PARAGRAPH:
+ case AccessibleTextType::LINE:
+ aResult.SegmentStart = 0;
+ aResultText.append( maBuffer.getStr(), implGetTextLength() );
+ break;
+
+ // equal-formatted text
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
+ sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
+ aResult.SegmentStart = nFirstIndex;
+ aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
+ }
+ break;
+
+ default:
+ throw RuntimeException();
+ }
+
+ aResult.SegmentText = aResultText.makeStringAndClear();
+ aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
+ return aResult;
+}
+
+TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
+ throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+
+ TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
+
+ switch( nTextType )
+ {
+ // single character
+ case AccessibleTextType::CHARACTER:
+ if( nIndex > 0 )
+ aResult = getTextAtIndex( nIndex - 1, nTextType );
+ // else empty
+ break;
+
+ // entire number or single dot/line
+ case AccessibleTextType::WORD:
+ case AccessibleTextType::GLYPH:
+ if( nRulerPos > 0 )
+ aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
+ // else empty
+ break;
+
+ // entire text
+ case AccessibleTextType::SENTENCE:
+ case AccessibleTextType::PARAGRAPH:
+ case AccessibleTextType::LINE:
+ // empty
+ break;
+
+ // equal-formatted text
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
+ if( nFirstIndex > 0 )
+ aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
+ // else empty
+ }
+ break;
+
+ default:
+ throw RuntimeException();
+ }
+ return aResult;
+}
+
+TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
+ throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+
+ TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
+ sal_Int32 nLastValid = implGetTextLength();
+
+ switch( nTextType )
+ {
+ // single character
+ case AccessibleTextType::CHARACTER:
+ if( nIndex < nLastValid )
+ aResult = getTextAtIndex( nIndex + 1, nTextType );
+ // else empty
+ break;
+
+ // entire number or single dot/line
+ case AccessibleTextType::WORD:
+ case AccessibleTextType::GLYPH:
+ if( nRulerPos < implGetRuler().GetPosCount() )
+ aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
+ // else empty
+ break;
+
+ // entire text
+ case AccessibleTextType::SENTENCE:
+ case AccessibleTextType::PARAGRAPH:
+ case AccessibleTextType::LINE:
+ // empty
+ break;
+
+ // equal-formatted text
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
+ if( nLastIndex < nLastValid )
+ aResult = getTextAtIndex( nLastIndex + 1, nTextType );
+ // else empty
+ }
+ break;
+
+ default:
+ throw RuntimeException();
+ }
+ return aResult;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ return sal_False;
+}
+
+
+// XInterface -----------------------------------------------------------------
+
+Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( RuntimeException )
+{
+ Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
+ return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
+}
+
+void SAL_CALL ScAccessibleCsvRuler::acquire() throw ()
+{
+ ScAccessibleCsvControl::acquire();
+}
+
+void SAL_CALL ScAccessibleCsvRuler::release() throw ()
+{
+ ScAccessibleCsvControl::release();
+}
+
+
+// XServiceInfo ---------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvRuler::getImplementationName() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( RULER_IMPL_NAME );
+}
+
+
+// XTypeProvider --------------------------------------------------------------
+
+Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes() throw( RuntimeException )
+{
+ Sequence< ::com::sun::star::uno::Type > aSeq( 1 );
+ aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleText >* >( NULL ) );
+ return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
+}
+
+Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId() throw( RuntimeException )
+{
+ static Sequence< sal_Int8 > aSeq;
+ getUuid( aSeq );
+ return aSeq;
+}
+
+
+// events ---------------------------------------------------------------------
+
+void ScAccessibleCsvRuler::SendCaretEvent()
+{
+ sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
+ if( nPos != CSV_POS_INVALID )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CARET_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= nPos;
+ CommitChange( aEvent );
+ }
+}
+
+
+// helpers --------------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleName() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVRULER_NAME ) );
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleDescription() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVRULER_DESCR ) );
+}
+
+void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
+ throw IndexOutOfBoundsException();
+}
+
+void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nIndex < 0) || (nIndex > implGetTextLength()) )
+ throw IndexOutOfBoundsException();
+}
+
+void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( rnStartIndex > rnEndIndex )
+ ::std::swap( rnStartIndex, rnEndIndex );
+ if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
+ throw IndexOutOfBoundsException();
+}
+
+ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
+{
+ return static_cast< ScCsvRuler& >( implGetControl() );
+}
+
+void ScAccessibleCsvRuler::constructStringBuffer() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ // extend existing string buffer to new ruler size
+ sal_Int32 nRulerCount = implGetRuler().GetPosCount();
+ sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
+ for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
+ {
+ switch( nRulerPos % 10 )
+ {
+ case 0: maBuffer.append( nRulerPos ); break;
+ case 5: maBuffer.append( cRulerLine ); break;
+ default: maBuffer.append( cRulerDot );
+ }
+ }
+}
+
+sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
+{
+ return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
+}
+
+bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
+{
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
+ return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
+}
+
+sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
+{
+ bool bSplit = implHasSplit( nApiPos );
+ while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
+ --nApiPos;
+ return nApiPos;
+}
+
+sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
+{
+ bool bSplit = implHasSplit( nApiPos );
+ sal_Int32 nLength = implGetTextLength();
+ while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
+ ++nApiPos;
+ return nApiPos;
+}
+
+
+// Grid =======================================================================
+
+/** Converts a grid columnm index to an API column index. */
+inline sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
+{
+ return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
+}
+
+/** Converts an API columnm index to a ScCsvGrid column index. */
+inline sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
+{
+ return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
+}
+
+
+// ----------------------------------------------------------------------------
+
+DBG_NAME( ScAccessibleCsvGrid )
+
+ScAccessibleCsvGrid::ScAccessibleCsvGrid( ScCsvGrid& rGrid ) :
+ ScAccessibleCsvControl( rGrid.GetAccessibleParentWindow()->GetAccessible(), rGrid, nGridRole )
+{
+ DBG_CTOR( ScAccessibleCsvGrid, NULL );
+}
+
+ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
+{
+ DBG_DTOR( ScAccessibleCsvGrid, NULL );
+ implDispose();
+}
+
+
+// XAccessibleComponent -------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint )
+ throw( RuntimeException )
+{
+ Reference< XAccessible > xRet;
+ if( containsPoint( rPoint ) )
+ {
+ ScUnoGuard aGuard;
+ ensureAlive();
+
+ const ScCsvGrid& rGrid = implGetGrid();
+ // #102679#; use <= instead of <, because the offset is the size and not the point
+ sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
+ lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
+ sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
+ (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
+ xRet = implCreateCellObj( nRow, nColumn );
+ }
+ return xRet;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
+}
+
+// XAccessibleContext ---------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetCellCount();
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nIndex );
+ return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) );
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
+ Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nRulerRole );
+ if( xAccObj.is() )
+ {
+ Sequence< Reference< XInterface > > aSeq( 1 );
+ aSeq[ 0 ] = xAccObj;
+ pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
+ }
+ return pRelationSet;
+}
+
+Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = implCreateStateSet();
+ if( implIsAlive() )
+ {
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE );
+ pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ if( implGetGrid().HasFocus() )
+ pStateSet->AddState( AccessibleStateType::FOCUSED );
+ }
+ else
+ pStateSet->AddState( AccessibleStateType::DEFUNC );
+ return pStateSet;
+}
+
+
+// XAccessibleTable -----------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRowCount();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetColumnCount();
+}
+
+OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( nRow, 0 );
+ return implGetCellText( nRow, 0 );
+}
+
+OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( 0, nColumn );
+ return implGetCellText( 0, nColumn );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return 1;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return 1;
+}
+
+Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return Sequence< sal_Int32 >();
+}
+
+Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+
+ ScCsvGrid& rGrid = implGetGrid();
+ Sequence< sal_Int32 > aSeq( implGetColumnCount() );
+
+ sal_Int32 nSeqIx = 0;
+ sal_uInt32 nColIx = rGrid.GetFirstSelected();
+ for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
+ aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
+
+ aSeq.realloc( nSeqIx );
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nColumn );
+ return implIsColumnSelected( nColumn );
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return implCreateCellObj( nRow, nColumn );
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ return isAccessibleColumnSelected( nColumn );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return implGetIndex( nRow, nColumn );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ return implGetRow( nChildIndex );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ return implGetColumn( nChildIndex );
+}
+
+
+// XAccessibleSelection -------------------------------------------------------
+
+void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ sal_Int32 nColumn = implGetColumn( nChildIndex );
+ if( nChildIndex == 0 )
+ implGetGrid().SelectAll();
+ else
+ implSelectColumn( nColumn, true );
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ sal_Int32 nColumn = implGetColumn( nChildIndex );
+ return implIsColumnSelected( nColumn );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ implGetGrid().SelectAll( false );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren() throw( RuntimeException )
+{
+ selectAccessibleChild( 0 );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRowCount() * implGetSelColumnCount();
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ sal_Int32 nColumns = implGetSelColumnCount();
+ if( nColumns == 0 )
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nRow = nSelectedChildIndex / nColumns;
+ sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
+ return getAccessibleCellAt( nRow, nColumn );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ sal_Int32 nColumns = implGetSelColumnCount();
+ if( nColumns == 0 )
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
+ ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
+ if( nColumn > 0 )
+ implSelectColumn( nColumn, false );
+}
+
+
+// XInterface -----------------------------------------------------------------
+
+Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( RuntimeException )
+{
+ Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
+ return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::acquire() throw ()
+{
+ ScAccessibleCsvControl::acquire();
+}
+
+void SAL_CALL ScAccessibleCsvGrid::release() throw ()
+{
+ ScAccessibleCsvControl::release();
+}
+
+
+// XServiceInfo ---------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvGrid::getImplementationName() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( GRID_IMPL_NAME );
+}
+
+
+// XTypeProvider --------------------------------------------------------------
+
+Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes() throw( RuntimeException )
+{
+ Sequence< ::com::sun::star::uno::Type > aSeq( 2 );
+ aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleTable >* >( NULL ) );
+ aSeq[ 1 ] = getCppuType( static_cast< const Reference< XAccessibleSelection >* >( NULL ) );
+ return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
+}
+
+Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( RuntimeException )
+{
+ static Sequence< sal_Int8 > aSeq;
+ getUuid( aSeq );
+ return aSeq;
+}
+
+
+// events ---------------------------------------------------------------------
+
+void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
+{
+ ScAccessibleCsvControl::SendFocusEvent( bFocused );
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ (bFocused ? aEvent.NewValue : aEvent.OldValue) <<=
+ getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
+ CommitChange( aEvent );
+}
+
+void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
+{
+ if( nFirstColumn <= nLastColumn )
+ {
+ AccessibleTableModelChange aModelChange(
+ AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
+ lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= aModelChange;
+ CommitChange( aEvent );
+ }
+}
+
+void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
+{
+ if( nFirstColumn <= nLastColumn )
+ {
+ AccessibleTableModelChange aModelChange(
+ AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1,
+ lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= aModelChange;
+ CommitChange( aEvent );
+ }
+}
+
+void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
+{
+ if( nFirstColumn <= nLastColumn )
+ {
+ AccessibleTableModelChange aModelChange(
+ AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1,
+ lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= aModelChange;
+ CommitChange( aEvent );
+ }
+}
+
+
+// helpers --------------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleName() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVGRID_NAME ) );
+}
+
+OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleDescription() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVGRID_DESCR ) );
+}
+
+void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
+ throw IndexOutOfBoundsException();
+}
+
+void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
+ throw IndexOutOfBoundsException();
+}
+
+ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
+{
+ return static_cast< ScCsvGrid& >( implGetControl() );
+}
+
+bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
+{
+ return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
+}
+
+void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
+{
+ if( nColumn > 0 )
+ implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
+{
+ return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
+{
+ return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ sal_Int32 nCount = 0;
+ for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
+ ++nCount;
+ return nCount;
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ sal_Int32 nColumn = 0;
+ for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
+ {
+ if( nColumn == nSelColumn )
+ return static_cast< sal_Int32 >( nColIx + 1 );
+ ++nColumn;
+ }
+ return 0;
+}
+
+String ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
+ String aCellStr;
+ if( (nColumn > 0) && (nRow > 0) )
+ aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
+ else if( nRow > 0 )
+ aCellStr = String::CreateFromInt32( nLine + 1L );
+ else if( nColumn > 0 )
+ aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
+ return aCellStr;
+}
+
+
+ScAccessibleCsvControl* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const
+{
+ return new ScAccessibleCsvCell( implGetGrid(), implGetCellText( nRow, nColumn ), nRow, nColumn );
+}
+
+
+// ============================================================================
+
+DBG_NAME( ScAccessibleCsvCell )
+
+ScAccessibleCsvCell::ScAccessibleCsvCell(
+ ScCsvGrid& rGrid,
+ const String& rCellText,
+ sal_Int32 nRow, sal_Int32 nColumn ) :
+ ScAccessibleCsvControl( rGrid.GetAccessible(), rGrid, nCellRole ),
+ AccessibleStaticTextBase( SvxEditSourcePtr( NULL ) ),
+ maCellText( rCellText ),
+ mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
+ mnColumn( lcl_GetGridColumn( nColumn ) ),
+ mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
+{
+ DBG_CTOR( ScAccessibleCsvCell, NULL );
+ SetEditSource( implCreateEditSource() );
+}
+
+ScAccessibleCsvCell::~ScAccessibleCsvCell()
+{
+ DBG_DTOR( ScAccessibleCsvCell, NULL );
+}
+
+void SAL_CALL ScAccessibleCsvCell::disposing()
+{
+ ScUnoGuard aGuard;
+ SetEditSource( SvxEditSourcePtr( NULL ) );
+ ScAccessibleCsvControl::disposing();
+}
+
+
+// XAccessibleComponent -------------------------------------------------------
+
+void SAL_CALL ScAccessibleCsvCell::grabFocus() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ScCsvGrid& rGrid = implGetGrid();
+ rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
+}
+
+// XAccessibleContext -----------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount() throw( RuntimeException )
+{
+ return AccessibleStaticTextBase::getAccessibleChildCount();
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ return AccessibleStaticTextBase::getAccessibleChild( nIndex );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return mnIndex;
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return new AccessibleRelationSetHelper();
+}
+
+Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = implCreateStateSet();
+ if( implIsAlive() )
+ {
+ const ScCsvGrid& rGrid = implGetGrid();
+ pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
+ if( mnColumn != CSV_COLUMN_HEADER )
+ pStateSet->AddState( AccessibleStateType::SELECTABLE );
+ if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
+ pStateSet->AddState( AccessibleStateType::ACTIVE );
+ if( rGrid.IsSelected( mnColumn ) )
+ pStateSet->AddState( AccessibleStateType::SELECTED );
+ }
+ return pStateSet;
+}
+
+// XInterface -----------------------------------------------------------------
+
+IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
+
+// XTypeProvider --------------------------------------------------------------
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
+
+// XServiceInfo ---------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvCell::getImplementationName() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( CELL_IMPL_NAME );
+}
+
+// helpers --------------------------------------------------------------------
+
+Rectangle ScAccessibleCsvCell::GetBoundingBoxOnScreen() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ Rectangle aRect( implGetBoundingBox() );
+ aRect.SetPos( implGetAbsPos( aRect.TopLeft() ) );
+ return aRect;
+}
+
+Rectangle ScAccessibleCsvCell::GetBoundingBox() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetBoundingBox();
+}
+
+OUString SAL_CALL ScAccessibleCsvCell::createAccessibleName() throw( RuntimeException )
+{
+ return maCellText;
+}
+
+OUString SAL_CALL ScAccessibleCsvCell::createAccessibleDescription() throw( RuntimeException )
+{
+ return OUString();
+}
+
+ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
+{
+ return static_cast< ScCsvGrid& >( implGetControl() );
+}
+
+Point ScAccessibleCsvCell::implGetRealPos() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ return Point(
+ (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
+ (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
+}
+
+sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ return rGrid.GetCharWidth() * nChars;
+}
+
+Size ScAccessibleCsvCell::implGetRealSize() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ return Size(
+ (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
+ (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
+}
+
+Rectangle ScAccessibleCsvCell::implGetBoundingBox() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ Rectangle aClipRect( Point( 0, 0 ), rGrid.GetSizePixel() );
+ if( mnColumn != CSV_COLUMN_HEADER )
+ {
+ aClipRect.Left() = rGrid.GetFirstX();
+ aClipRect.Right() = rGrid.GetLastX();
+ }
+ if( mnLine != CSV_LINE_HEADER )
+ aClipRect.Top() = rGrid.GetHdrHeight();
+
+ Rectangle aRect( implGetRealPos(), implGetRealSize() );
+ aRect.Intersection( aClipRect );
+ if( (aRect.GetWidth() <= 0) || (aRect.GetHeight() <= 0) )
+ aRect.SetSize( Size( -1, -1 ) );
+ return aRect;
+}
+
+::std::auto_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ Rectangle aBoundRect( implGetBoundingBox() );
+ aBoundRect -= implGetRealPos();
+
+ ::std::auto_ptr< ScAccessibleTextData > pCsvTextData( new ScAccessibleCsvTextData(
+ &rGrid, rGrid.GetEditEngine(), maCellText, aBoundRect, implGetRealSize() ) );
+
+ ::std::auto_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( pCsvTextData ) );
+ return pEditSource;
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx
new file mode 100644
index 000000000000..1848c7bfefc0
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx
@@ -0,0 +1,739 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleDataPilotControl.hxx"
+#include "unoguard.hxx"
+#include "fieldwnd.hxx"
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <rtl/uuid.h>
+#include <tools/gen.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+class ScAccessibleDataPilotButton
+ : public ScAccessibleContextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleDataPilotButton(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow,
+ sal_Int32 nIndex);
+
+ virtual void Init();
+
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ void SetIndex(sal_Int32 nIndex) { mnIndex = nIndex; }
+ void NameChanged();
+ void SetFocused();
+ void ResetFocused();
+protected:
+ virtual ~ScAccessibleDataPilotButton(void);
+public:
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVisible( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void) throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return this objects index among the parents children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleIndexInParent(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScDPFieldWindow* mpDPFieldWindow;
+ sal_Int32 mnIndex;
+};
+
+ //===== internal ========================================================
+ScAccessibleDataPilotControl::ScAccessibleDataPilotControl(
+ const uno::Reference<XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow)
+ :
+ ScAccessibleContextBase(rxParent, AccessibleRole::GROUP_BOX),
+ mpDPFieldWindow(pDPFieldWindow)
+{
+ if (mpDPFieldWindow)
+ maChildren.resize(mpDPFieldWindow->GetFieldCount());
+}
+
+ScAccessibleDataPilotControl::~ScAccessibleDataPilotControl(void)
+{
+ if (!IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleDataPilotControl::Init()
+{
+}
+
+void SAL_CALL ScAccessibleDataPilotControl::disposing()
+{
+ ScUnoGuard aGuard;
+ mpDPFieldWindow = NULL;
+
+ ScAccessibleContextBase::disposing();
+}
+
+void ScAccessibleDataPilotControl::AddField(sal_Int32 nNewIndex)
+{
+ sal_Bool bAdded(sal_False);
+ if (static_cast<sal_uInt32>(nNewIndex) == maChildren.size())
+ {
+ maChildren.push_back(AccessibleWeak());
+ bAdded = sal_True;
+ }
+ else if (static_cast<sal_uInt32>(nNewIndex) < maChildren.size())
+ {
+ ::std::vector < AccessibleWeak >::iterator aItr = maChildren.begin() + nNewIndex;
+ maChildren.insert(aItr, AccessibleWeak());
+
+ ::std::vector < AccessibleWeak >::iterator aEndItr = maChildren.end();
+ aItr = maChildren.begin() + nNewIndex + 1;
+ uno::Reference< XAccessible > xTempAcc;
+ sal_Int32 nIndex = nNewIndex + 1;
+ while (aItr != aEndItr)
+ {
+ xTempAcc = aItr->xWeakAcc;
+ if (xTempAcc.is() && aItr->pAcc)
+ aItr->pAcc->SetIndex(nIndex);
+ ++nIndex;
+ ++aItr;
+ }
+ bAdded = sal_True;
+ }
+ else
+ {
+ DBG_ERRORFILE("did not recognize a child count change");
+ }
+
+ if (bAdded)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= getAccessibleChild(nNewIndex);
+
+ CommitChange(aEvent); // new child - event
+ }
+}
+
+void ScAccessibleDataPilotControl::RemoveField(sal_Int32 nOldIndex)
+{
+ sal_Bool bRemoved(sal_False);
+ uno::Reference< XAccessible > xTempAcc;
+ ScAccessibleDataPilotButton* pField = NULL;
+ if (static_cast<sal_uInt32>(nOldIndex) < maChildren.size())
+ {
+ xTempAcc = getAccessibleChild(nOldIndex);
+ pField = maChildren[nOldIndex].pAcc;
+
+ ::std::vector < AccessibleWeak >::iterator aItr = maChildren.begin() + nOldIndex;
+ aItr = maChildren.erase(aItr);
+
+ ::std::vector < AccessibleWeak >::iterator aEndItr = maChildren.end();
+ uno::Reference< XAccessible > xItrAcc;
+ while (aItr != aEndItr)
+ {
+ xItrAcc = aItr->xWeakAcc;
+ if (xItrAcc.is() && aItr->pAcc)
+ aItr->pAcc->SetIndex(nOldIndex);
+ ++nOldIndex;
+ ++aItr;
+ }
+ bRemoved = sal_True;
+ }
+ else
+ {
+ DBG_ERRORFILE("did not recognize a child count change");
+ }
+
+ if (bRemoved)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= xTempAcc;
+
+ CommitChange(aEvent); // gone child - event
+
+ if (pField)
+ pField->dispose();
+ }
+}
+
+void ScAccessibleDataPilotControl::FieldFocusChange(sal_Int32 nOldIndex, sal_Int32 nNewIndex)
+{
+ DBG_ASSERT(static_cast<sal_uInt32>(nOldIndex) < maChildren.size() &&
+ static_cast<sal_uInt32>(nNewIndex) < maChildren.size(), "did not recognize a child count change");
+
+ uno::Reference < XAccessible > xTempAcc = maChildren[nOldIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nOldIndex].pAcc)
+ maChildren[nOldIndex].pAcc->ResetFocused();
+
+ xTempAcc = maChildren[nNewIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nNewIndex].pAcc)
+ maChildren[nNewIndex].pAcc->SetFocused();
+}
+
+void ScAccessibleDataPilotControl::FieldNameChange(sal_Int32 nIndex)
+{
+ DBG_ASSERT(static_cast<sal_uInt32>(nIndex) < maChildren.size(), "did not recognize a child count change");
+
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nIndex].pAcc)
+ maChildren[nIndex].pAcc->ChangeName();
+}
+
+void ScAccessibleDataPilotControl::GotFocus()
+{
+ if (mpDPFieldWindow)
+ {
+ DBG_ASSERT(static_cast<sal_uInt32>(mpDPFieldWindow->GetFieldCount()) == maChildren.size(), "did not recognize a child count change");
+
+ sal_Int32 nIndex(mpDPFieldWindow->GetSelectedField());
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nIndex].pAcc)
+ maChildren[nIndex].pAcc->SetFocused();
+ }
+}
+
+void ScAccessibleDataPilotControl::LostFocus()
+{
+ if (mpDPFieldWindow)
+ {
+ DBG_ASSERT(static_cast<sal_uInt32>(mpDPFieldWindow->GetFieldCount()) == maChildren.size(), "did not recognize a child count change");
+
+ sal_Int32 nIndex(mpDPFieldWindow->GetSelectedField());
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nIndex].pAcc)
+ maChildren[nIndex].pAcc->ResetFocused();
+ }
+}
+
+ ///===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDataPilotControl::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xAcc;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ {
+ Point aAbsPoint(VCLPoint(rPoint));
+ Point aControlEdge(GetBoundingBoxOnScreen().TopLeft());
+ Point aRelPoint(aAbsPoint - aControlEdge);
+ size_t nChildIndex(0);
+ if (mpDPFieldWindow->GetFieldIndex(aRelPoint, nChildIndex))
+ xAcc = getAccessibleChild(static_cast< long >( nChildIndex ));
+ }
+ }
+ return xAcc;
+}
+
+sal_Bool SAL_CALL ScAccessibleDataPilotControl::isVisible( )
+ throw (uno::RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL ScAccessibleDataPilotControl::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ mpDPFieldWindow->GrabFocus();
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getForeground( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
+ }
+ return nColor;
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getBackground( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ if (mpDPFieldWindow->GetType() == TYPE_SELECT)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
+ }
+ else
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
+ }
+ }
+ return nColor;
+}
+
+ ///===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetFieldCount();
+ else
+ return 0;
+}
+
+uno::Reference< XAccessible> SAL_CALL ScAccessibleDataPilotControl::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAcc;
+ if (mpDPFieldWindow)
+ {
+ if (nIndex < 0 || static_cast< size_t >( nIndex ) >= mpDPFieldWindow->GetFieldCount())
+ throw lang::IndexOutOfBoundsException();
+
+ DBG_ASSERT(static_cast<sal_uInt32>(mpDPFieldWindow->GetFieldCount()) == maChildren.size(), "did not recognize a child count change");
+
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (!xTempAcc.is())
+ {
+ maChildren[nIndex].pAcc = new ScAccessibleDataPilotButton(this, mpDPFieldWindow, nIndex);
+ xTempAcc = maChildren[nIndex].pAcc;
+ maChildren[nIndex].xWeakAcc = xTempAcc;
+ }
+
+ xAcc = xTempAcc;
+ }
+ return xAcc;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotControl::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+
+ if (IsDefunc())
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+
+ return pStateSet;
+}
+
+ ///===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotControl"));
+}
+
+ ///===== XTypeProvider ===================================================
+
+uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotControl::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+ //===== internal ========================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetDescription();
+
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetName();
+
+ return rtl::OUString();
+}
+
+Rectangle ScAccessibleDataPilotControl::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetWindowExtentsRelative(NULL);
+ else
+ return Rectangle();
+}
+
+Rectangle ScAccessibleDataPilotControl::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetWindowExtentsRelative(mpDPFieldWindow->GetAccessibleParentWindow());
+ else
+ return Rectangle();
+}
+
+
+//===============================================================================
+
+ScAccessibleDataPilotButton::ScAccessibleDataPilotButton(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow,
+ sal_Int32 nIndex)
+ : ScAccessibleContextBase(rxParent, AccessibleRole::PUSH_BUTTON),
+ mpDPFieldWindow(pDPFieldWindow),
+ mnIndex(nIndex)
+{
+}
+
+ScAccessibleDataPilotButton::~ScAccessibleDataPilotButton(void)
+{
+ if (!IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleDataPilotButton::Init()
+{
+}
+
+void SAL_CALL ScAccessibleDataPilotButton::disposing()
+{
+ ScUnoGuard aGuard;
+ mpDPFieldWindow = NULL;
+
+ ScAccessibleContextBase::disposing();
+}
+
+void ScAccessibleDataPilotButton::SetFocused()
+{
+ CommitFocusGained();
+}
+
+void ScAccessibleDataPilotButton::ResetFocused()
+{
+ CommitFocusLost();
+}
+
+ ///===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDataPilotButton::getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& /* rPoint */ )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessibleDataPilotButton::isVisible( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL ScAccessibleDataPilotButton::grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ {
+ mpDPFieldWindow->GrabFocusWithSel(getAccessibleIndexInParent());
+ }
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getForeground( )
+throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
+ }
+ return nColor;
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getBackground( )
+throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
+ }
+ return nColor;
+}
+
+ ///===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return 0;
+}
+
+uno::Reference< XAccessible> SAL_CALL ScAccessibleDataPilotButton::getAccessibleChild(sal_Int32 /* nIndex */)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException)
+{
+ throw lang::IndexOutOfBoundsException();
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getAccessibleIndexInParent(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return mnIndex;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotButton::getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+
+ if (IsDefunc())
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ pStateSet->AddState(AccessibleStateType::FOCUSABLE);
+ if (mpDPFieldWindow && (sal::static_int_cast<sal_Int32>(mpDPFieldWindow->GetSelectedField()) == mnIndex))
+ pStateSet->AddState(AccessibleStateType::FOCUSED);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+
+ return pStateSet;
+}
+
+ ///===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotButton"));
+}
+
+ ///===== XTypeProvider ===================================================
+
+uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotButton::getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetFieldText(getAccessibleIndexInParent());
+
+ return rtl::OUString();
+}
+
+Rectangle ScAccessibleDataPilotButton::GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ Rectangle aRect(GetBoundingBox());
+
+ if (mpDPFieldWindow)
+ {
+ Point aParentPos(mpDPFieldWindow->GetWindowExtentsRelative(NULL).TopLeft());
+ aRect.Move(aParentPos.getX(), aParentPos.getY());
+ }
+
+ return aRect;
+}
+
+Rectangle ScAccessibleDataPilotButton::GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ if (mpDPFieldWindow)
+ return Rectangle (mpDPFieldWindow->GetFieldPosition(const_cast<ScAccessibleDataPilotButton*> (this)->getAccessibleIndexInParent()), mpDPFieldWindow->GetFieldSize());
+ else
+ return Rectangle();
+}
diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx
new file mode 100644
index 000000000000..4c65632fb45e
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx
@@ -0,0 +1,2120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleDocument.hxx"
+#include "AccessibleSpreadsheet.hxx"
+#include "tabvwsh.hxx"
+#include "AccessibilityHints.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "unoguard.hxx"
+#include "shapeuno.hxx"
+#include "DrawModelBroadcaster.hxx"
+#include "drawview.hxx"
+#include "gridwin.hxx"
+#include "AccessibleEditObject.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#endif
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/ShapeTypeHandler.hxx>
+#include <svx/AccessibleShape.hxx>
+#include <svx/AccessibleShapeTreeInfo.hxx>
+#include <svx/AccessibleShapeInfo.hxx>
+#include <comphelper/sequence.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/unoshcol.hxx>
+#include <svx/unoshape.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <list>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using ::std::for_each;
+
+ //===== internal ========================================================
+
+struct ScAccessibleShapeData
+{
+ ScAccessibleShapeData() : pAccShape(NULL), pRelationCell(NULL), bSelected(sal_False), bSelectable(sal_True) {}
+ ~ScAccessibleShapeData();
+ mutable ::accessibility::AccessibleShape* pAccShape;
+ mutable ScAddress* pRelationCell; // if it is NULL this shape is anchored on the table
+// SdrObject* pShape;
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
+ mutable sal_Bool bSelected;
+ sal_Bool bSelectable;
+};
+
+ScAccessibleShapeData::~ScAccessibleShapeData()
+{
+ if (pAccShape)
+ {
+ pAccShape->dispose();
+ pAccShape->release();
+ }
+}
+
+struct ScShapeDataLess
+{
+ rtl::OUString msLayerId;
+ rtl::OUString msZOrder;
+ ScShapeDataLess()
+ : msLayerId(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )),
+ msZOrder(RTL_CONSTASCII_USTRINGPARAM( "ZOrder" ))
+ {
+ }
+ void ConvertLayerId(sal_Int16& rLayerID) const // changes the number of the LayerId so it the accessibility order
+ {
+ switch (rLayerID)
+ {
+ case SC_LAYER_FRONT:
+ rLayerID = 1;
+ break;
+ case SC_LAYER_BACK:
+ rLayerID = 0;
+ break;
+ case SC_LAYER_INTERN:
+ rLayerID = 2;
+ break;
+ case SC_LAYER_CONTROLS:
+ rLayerID = 3;
+ break;
+ }
+ }
+ sal_Bool LessThanSheet(const ScAccessibleShapeData* pData) const
+ {
+ sal_Bool bResult(sal_False);
+ uno::Reference< beans::XPropertySet> xProps(pData->xShape, uno::UNO_QUERY);
+ if (xProps.is())
+ {
+ uno::Any aPropAny = xProps->getPropertyValue(msLayerId);
+ sal_Int16 nLayerID = 0;
+ if( (aPropAny >>= nLayerID) )
+ {
+ if (nLayerID == SC_LAYER_BACK)
+ bResult = sal_True;
+ }
+ }
+ return bResult;
+ }
+ sal_Bool operator()(const ScAccessibleShapeData* pData1, const ScAccessibleShapeData* pData2) const
+ {
+ sal_Bool bResult(sal_False);
+ if (pData1 && pData2)
+ {
+ uno::Reference< beans::XPropertySet> xProps1(pData1->xShape, uno::UNO_QUERY);
+ uno::Reference< beans::XPropertySet> xProps2(pData2->xShape, uno::UNO_QUERY);
+ if (xProps1.is() && xProps2.is())
+ {
+ uno::Any aPropAny1 = xProps1->getPropertyValue(msLayerId);
+ uno::Any aPropAny2 = xProps2->getPropertyValue(msLayerId);
+ sal_Int16 nLayerID1(0);
+ sal_Int16 nLayerID2(0);
+ if( (aPropAny1 >>= nLayerID1) && (aPropAny2 >>= nLayerID2) )
+ {
+ if (nLayerID1 == nLayerID2)
+ {
+ uno::Any aAny1 = xProps1->getPropertyValue(msZOrder);
+ sal_Int32 nZOrder1 = 0;
+ uno::Any aAny2 = xProps2->getPropertyValue(msZOrder);
+ sal_Int32 nZOrder2 = 0;
+ if ( (aAny1 >>= nZOrder1) && (aAny2 >>= nZOrder2) )
+ bResult = (nZOrder1 < nZOrder2);
+ }
+ else
+ {
+ ConvertLayerId(nLayerID1);
+ ConvertLayerId(nLayerID2);
+ bResult = (nLayerID1 < nLayerID2);
+ }
+ }
+ }
+ }
+ else if (pData1 && !pData2)
+ bResult = LessThanSheet(pData1);
+ else if (!pData1 && pData2)
+ bResult = !LessThanSheet(pData2);
+ else
+ bResult = sal_False;
+ return bResult;
+ }
+};
+
+struct DeselectShape
+{
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData)
+ {
+ pAccShapeData->bSelected = sal_False;
+ if (pAccShapeData->pAccShape)
+ pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED);
+ }
+ }
+};
+
+struct SelectShape
+{
+ uno::Reference < drawing::XShapes > xShapes;
+ SelectShape(uno::Reference<drawing::XShapes>& xTemp) : xShapes(xTemp) {}
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData && pAccShapeData->bSelectable)
+ {
+ pAccShapeData->bSelected = sal_True;
+ if (pAccShapeData->pAccShape)
+ pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED);
+ if (xShapes.is())
+ xShapes->add(pAccShapeData->xShape);
+ }
+ }
+};
+
+struct Destroy
+{
+ void operator() (ScAccessibleShapeData* pData)
+ {
+ if (pData)
+ DELETEZ(pData);
+ }
+};
+
+class ScChildrenShapes : public SfxListener,
+ public ::accessibility::IAccessibleParent
+{
+public:
+ ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
+ ~ScChildrenShapes();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== IAccessibleParent ===============================================
+
+ virtual sal_Bool ReplaceChild (
+ ::accessibility::AccessibleShape* pCurrentChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
+ const long _nIndex,
+ const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
+ ) throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== Internal ========================================================
+ void SetDrawBroadcaster();
+
+ sal_Int32 GetCount() const;
+ uno::Reference< XAccessible > Get(const ScAccessibleShapeData* pData) const;
+ uno::Reference< XAccessible > Get(sal_Int32 nIndex) const;
+ uno::Reference< XAccessible > GetAt(const awt::Point& rPoint) const;
+
+ // gets the index of the shape starting on 0 (without the index of the table)
+ // returns the selected shape
+ sal_Bool IsSelected(sal_Int32 nIndex,
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape) const;
+
+ sal_Bool SelectionChanged();
+
+ void Select(sal_Int32 nIndex);
+ void DeselectAll(); // deselect also the table
+ void SelectAll();
+ sal_Int32 GetSelectedCount() const;
+ uno::Reference< XAccessible > GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const;
+ void Deselect(sal_Int32 nChildIndex);
+
+ SdrPage* GetDrawPage() const;
+
+ utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;
+
+ void VisAreaChanged() const;
+private:
+ typedef std::vector<ScAccessibleShapeData*> SortedShapes;
+
+ mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order
+
+ mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo;
+ mutable com::sun::star::uno::Reference<com::sun::star::view::XSelectionSupplier> xSelectionSupplier;
+ mutable sal_uInt32 mnSdrObjCount;
+ mutable sal_uInt32 mnShapesSelected;
+ ScTabViewShell* mpViewShell;
+ ScAccessibleDocument* mpAccessibleDocument;
+ ScSplitPos meSplitPos;
+
+ void FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const;
+ sal_Bool FindSelectedShapesChanges(const com::sun::star::uno::Reference<com::sun::star::drawing::XShapes>& xShapes, sal_Bool bCommitChange) const;
+ void FillSelectionSupplier() const;
+
+ ScAddress* GetAnchor(const uno::Reference<drawing::XShape>& xShape) const;
+ uno::Reference<XAccessibleRelationSet> GetRelationSet(const ScAccessibleShapeData* pData) const;
+ void CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const;
+ void SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const;
+ void AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const;
+ void RemoveShape(const uno::Reference<drawing::XShape>& xShape) const;
+
+ sal_Bool FindShape(const uno::Reference<drawing::XShape>& xShape, SortedShapes::iterator& rItr) const;
+
+ sal_Int8 Compare(const ScAccessibleShapeData* pData1,
+ const ScAccessibleShapeData* pData2) const;
+};
+
+ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
+ :
+ mnShapesSelected(0),
+ mpViewShell(pViewShell),
+ mpAccessibleDocument(pAccessibleDocument),
+ meSplitPos(eSplitPos)
+{
+ FillSelectionSupplier();
+ maZOrderedShapes.push_back(NULL); // add an element which represents the table
+
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (mnShapesSelected)
+ {
+ //set flag on every selected shape
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+ if (xShapes.is())
+ FindSelectedShapesChanges(xShapes, sal_False);
+ }
+ if (pViewShell)
+ {
+ SfxBroadcaster* pDrawBC = pViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ {
+ StartListening(*pDrawBC);
+
+ maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
+ maShapeTreeInfo.SetSdrView(pViewShell->GetViewData()->GetScDrawView());
+ maShapeTreeInfo.SetController(NULL);
+ maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos));
+ maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
+ }
+ }
+}
+
+ScChildrenShapes::~ScChildrenShapes()
+{
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy());
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ }
+}
+
+void ScChildrenShapes::SetDrawBroadcaster()
+{
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ {
+ StartListening(*pDrawBC, TRUE);
+
+ maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(mpViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
+ maShapeTreeInfo.SetSdrView(mpViewShell->GetViewData()->GetScDrawView());
+ maShapeTreeInfo.SetController(NULL);
+ maShapeTreeInfo.SetWindow(mpViewShell->GetWindowByPos(meSplitPos));
+ maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
+ }
+ }
+}
+
+void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SdrHint ) )
+ {
+ const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
+ if (pSdrHint)
+ {
+ SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
+ if (pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->GetPage() == GetDrawPage()) &&
+ (pObj->GetPage() == pObj->GetObjList()) ) //#108480# only do something if the object lies direct on the page
+ {
+ switch (pSdrHint->GetKind())
+ {
+ case HINT_OBJCHG : // Objekt geaendert
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ ScShapeDataLess aLess;
+ std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), aLess); // sort, because the z index or layer could be changed
+ CheckWhetherAnchorChanged(xShape);
+ }
+ }
+ break;
+ case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ AddShape(xShape, sal_True);
+ }
+ break;
+ case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ RemoveShape(xShape);
+ }
+ break;
+ default :
+ {
+ // other events are not interesting
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurrentChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
+ const long _nIndex, const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo)
+ throw (uno::RuntimeException)
+{
+ // create the new child
+ ::accessibility::AccessibleShape* pReplacement = ::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
+ ::accessibility::AccessibleShapeInfo ( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex ),
+ _rShapeTreeInfo
+ );
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pReplacement ); // keep this alive (do this before calling Init!)
+ if ( pReplacement )
+ pReplacement->Init();
+
+ sal_Bool bResult(sal_False);
+ if (pCurrentChild && pReplacement)
+ {
+ DBG_ASSERT(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted");
+ SortedShapes::iterator aItr;
+ FindShape(pCurrentChild->GetXShape(), aItr);
+ if (aItr != maZOrderedShapes.end() && (*aItr))
+ {
+ if ((*aItr)->pAccShape)
+ {
+ DBG_ASSERT((*aItr)->pAccShape == pCurrentChild, "wrong child found");
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.OldValue <<= uno::makeAny(uno::Reference<XAccessible>(pCurrentChild));
+
+ mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
+
+ pCurrentChild->dispose();
+ }
+ (*aItr)->pAccShape = pReplacement;
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.NewValue <<= uno::makeAny(uno::Reference<XAccessible>(pReplacement));
+
+ mpAccessibleDocument->CommitChange(aEvent); // child is new - event
+ bResult = sal_True;
+ }
+ }
+ return bResult;
+}
+
+sal_Int32 ScChildrenShapes::GetCount() const
+{
+ SdrPage* pDrawPage = GetDrawPage();
+ if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in
+ {
+ mnSdrObjCount = pDrawPage->GetObjCount();
+ maZOrderedShapes.reserve(mnSdrObjCount + 1); // the table is always in
+ for (sal_uInt32 i = 0; i < mnSdrObjCount; ++i)
+ {
+ SdrObject* pObj = pDrawPage->GetObj(i);
+ if (pObj/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/)
+ {
+ uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ AddShape(xShape, sal_False); //inserts in the correct order
+ }
+ }
+ }
+ return maZOrderedShapes.size();
+}
+
+uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
+{
+ if (!pData)
+ return NULL;
+
+ if (!pData->pAccShape)
+ {
+ ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
+ ::accessibility::AccessibleShapeInfo aShapeInfo(pData->xShape, mpAccessibleDocument, const_cast<ScChildrenShapes*>(this));
+ pData->pAccShape = rShapeHandler.CreateAccessibleObject(
+ aShapeInfo, maShapeTreeInfo);
+ if (pData->pAccShape)
+ {
+ pData->pAccShape->acquire();
+ pData->pAccShape->Init();
+ if (pData->bSelected)
+ pData->pAccShape->SetState(AccessibleStateType::SELECTED);
+ if (!pData->bSelectable)
+ pData->pAccShape->ResetState(AccessibleStateType::SELECTABLE);
+ pData->pAccShape->SetRelationSet(GetRelationSet(pData));
+ }
+ }
+ return pData->pAccShape;
+ }
+
+uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const
+{
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size())
+ return NULL;
+
+ return Get(maZOrderedShapes[nIndex]);
+}
+
+uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ if(mpViewShell)
+ {
+ sal_Int32 i(maZOrderedShapes.size() - 1);
+ sal_Bool bFound(sal_False);
+ while (!bFound && i >= 0)
+ {
+ ScAccessibleShapeData* pShape = maZOrderedShapes[i];
+ if (pShape)
+ {
+ if (!pShape->pAccShape)
+ Get(pShape);
+
+ if (pShape->pAccShape)
+ {
+ Point aPoint(VCLPoint(rPoint));
+ aPoint -= VCLRectangle(pShape->pAccShape->getBounds()).TopLeft();
+ if (pShape->pAccShape->containsPoint(AWTPoint(aPoint)))
+ {
+ xAccessible = pShape->pAccShape;
+ bFound = sal_True;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("I should have an accessible shape now!");
+ }
+ }
+ else
+ bFound = sal_True; // this is the sheet and it lies before the rest of the shapes which are background shapes
+
+ --i;
+ }
+ }
+ return xAccessible;
+}
+
+sal_Bool ScChildrenShapes::IsSelected(sal_Int32 nIndex,
+ uno::Reference<drawing::XShape>& rShape) const
+{
+ sal_Bool bResult (sal_False);
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ if (!maZOrderedShapes[nIndex])
+ return sal_False;
+
+ bResult = maZOrderedShapes[nIndex]->bSelected;
+ rShape = maZOrderedShapes[nIndex]->xShape;
+
+#ifdef DBG_UTIL // test whether it is truly selected by a slower method
+ uno::Reference< drawing::XShape > xReturnShape;
+ sal_Bool bDebugResult(sal_False);
+ uno::Reference<container::XIndexAccess> xIndexAccess;
+ xSelectionSupplier->getSelection() >>= xIndexAccess;
+
+ if (xIndexAccess.is())
+ {
+ sal_Int32 nCount(xIndexAccess->getCount());
+ if (nCount)
+ {
+ uno::Reference< drawing::XShape > xShape;
+ uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape;
+ sal_Int32 i(0);
+ while (!bDebugResult && (i < nCount))
+ {
+ xIndexAccess->getByIndex(i) >>= xShape;
+ if (xShape.is() && (xIndexShape.get() == xShape.get()))
+ {
+ bDebugResult = sal_True;
+ xReturnShape = xShape;
+ }
+ else
+ ++i;
+ }
+ }
+ }
+ DBG_ASSERT((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result");
+#endif
+
+ return bResult;
+}
+
+sal_Bool ScChildrenShapes::SelectionChanged()
+{
+ sal_Bool bResult(sal_False);
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+
+ bResult = FindSelectedShapesChanges(xShapes, sal_True);
+
+ return bResult;
+}
+
+void ScChildrenShapes::Select(sal_Int32 nIndex)
+{
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ if (!maZOrderedShapes[nIndex])
+ return;
+
+ uno::Reference<drawing::XShape> xShape;
+ if (!IsSelected(nIndex, xShape) && maZOrderedShapes[nIndex]->bSelectable)
+ {
+ uno::Reference<drawing::XShapes> xShapes;
+ xSelectionSupplier->getSelection() >>= xShapes;
+
+ if (!xShapes.is())
+ xShapes = new SvxShapeCollection();
+
+ xShapes->add(maZOrderedShapes[nIndex]->xShape);
+
+ try
+ {
+ xSelectionSupplier->select(uno::makeAny(xShapes));
+ maZOrderedShapes[nIndex]->bSelected = sal_True;
+ if (maZOrderedShapes[nIndex]->pAccShape)
+ maZOrderedShapes[nIndex]->pAccShape->SetState(AccessibleStateType::SELECTED);
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ }
+ }
+}
+
+void ScChildrenShapes::DeselectAll()
+{
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ sal_Bool bSomethingSelected(sal_True);
+ try
+ {
+ xSelectionSupplier->select(uno::Any()); //deselects all
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ DBG_ERRORFILE("nothing selected before");
+ bSomethingSelected = sal_False;
+ }
+
+ if (bSomethingSelected)
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), DeselectShape());
+}
+
+void ScChildrenShapes::SelectAll()
+{
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (maZOrderedShapes.size() > 1)
+ {
+ uno::Reference<drawing::XShapes> xShapes;
+ xShapes = new SvxShapeCollection();
+
+ try
+ {
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), SelectShape(xShapes));
+ xSelectionSupplier->select(uno::makeAny(xShapes));
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ SelectionChanged(); // find all selected shapes and set the flags
+ }
+ }
+}
+
+void ScChildrenShapes::FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const
+{
+ uno::Reference<container::XIndexAccess> xIndexAccess;
+ xSelectionSupplier->getSelection() >>= xIndexAccess;
+
+ if (xIndexAccess.is())
+ {
+ sal_uInt32 nCount(xIndexAccess->getCount());
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference<drawing::XShape> xShape;
+ xIndexAccess->getByIndex(i) >>= xShape;
+ if (xShape.is())
+ rShapes.push_back(xShape);
+ }
+ }
+}
+
+sal_Int32 ScChildrenShapes::GetSelectedCount() const
+{
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ std::vector < uno::Reference < drawing::XShape > > aShapes;
+ FillShapes(aShapes);
+
+ return aShapes.size();
+}
+
+uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const
+{
+ uno::Reference< XAccessible > xAccessible;
+
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with shapes
+
+ if (!bTabSelected)
+ {
+ std::vector < uno::Reference < drawing::XShape > > aShapes;
+ FillShapes(aShapes);
+
+ SortedShapes::iterator aItr;
+ if (FindShape(aShapes[nSelectedChildIndex], aItr))
+ xAccessible = Get(aItr - maZOrderedShapes.begin());
+ }
+ else
+ {
+ SortedShapes::iterator aItr = maZOrderedShapes.begin();
+ SortedShapes::iterator aEndItr = maZOrderedShapes.end();
+ sal_Bool bFound(sal_False);
+ while(!bFound && aItr != aEndItr)
+ {
+ if (*aItr)
+ {
+ if ((*aItr)->bSelected)
+ {
+ if (nSelectedChildIndex == 0)
+ bFound = sal_True;
+ else
+ --nSelectedChildIndex;
+ }
+ }
+ else
+ {
+ if (nSelectedChildIndex == 0)
+ bFound = sal_True;
+ else
+ --nSelectedChildIndex;
+ }
+ if (!bFound)
+ ++aItr;
+ }
+ if (bFound && *aItr)
+ xAccessible = (*aItr)->pAccShape;
+ }
+
+ return xAccessible;
+}
+
+void ScChildrenShapes::Deselect(sal_Int32 nChildIndex)
+{
+ uno::Reference<drawing::XShape> xShape;
+ if (IsSelected(nChildIndex, xShape)) // returns false if it is the sheet
+ {
+ if (xShape.is())
+ {
+ uno::Reference<drawing::XShapes> xShapes;
+ xSelectionSupplier->getSelection() >>= xShapes;
+ if (xShapes.is())
+ xShapes->remove(xShape);
+
+ try
+ {
+ xSelectionSupplier->select(uno::makeAny(xShapes));
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ DBG_ERRORFILE("something not selectable");
+ }
+
+ maZOrderedShapes[nChildIndex]->bSelected = sal_False;
+ if (maZOrderedShapes[nChildIndex]->pAccShape)
+ maZOrderedShapes[nChildIndex]->pAccShape->ResetState(AccessibleStateType::SELECTED);
+ }
+ }
+}
+
+
+SdrPage* ScChildrenShapes::GetDrawPage() const
+{
+ SCTAB nTab(mpAccessibleDocument->getVisibleTable());
+ SdrPage* pDrawPage = NULL;
+ if (mpViewShell)
+ {
+ ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
+ if (pDoc && pDoc->GetDrawLayer())
+ {
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
+ pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
+ }
+ }
+ return pDrawPage;
+}
+
+struct SetRelation
+{
+ const ScChildrenShapes* mpChildrenShapes;
+ mutable utl::AccessibleRelationSetHelper* mpRelationSet;
+ const ScAddress* mpAddress;
+ SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress)
+ :
+ mpChildrenShapes(pChildrenShapes),
+ mpRelationSet(NULL),
+ mpAddress(pAddress)
+ {
+ }
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData &&
+ ((!pAccShapeData->pRelationCell && !mpAddress) ||
+ (pAccShapeData->pRelationCell && mpAddress && (*(pAccShapeData->pRelationCell) == *mpAddress))))
+ {
+ if (!mpRelationSet)
+ mpRelationSet = new utl::AccessibleRelationSetHelper();
+
+ AccessibleRelation aRelation;
+ aRelation.TargetSet.realloc(1);
+ aRelation.TargetSet[0] = mpChildrenShapes->Get(pAccShapeData);
+ aRelation.RelationType = AccessibleRelationType::CONTROLLER_FOR;
+
+ mpRelationSet->AddRelation(aRelation);
+ }
+ }
+};
+
+utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const
+{
+ SetRelation aSetRelation(this, pAddress);
+ ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation);
+ return aSetRelation.mpRelationSet;
+}
+
+sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, sal_Bool /* bCommitChange */) const
+{
+ sal_Bool bResult(sal_False);
+ SortedShapes aShapesList;
+ uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY);
+ if (xIndexAcc.is())
+ {
+ mnShapesSelected = xIndexAcc->getCount();
+ for (sal_uInt32 i = 0; i < mnShapesSelected; ++i)
+ {
+ uno::Reference< drawing::XShape > xShape;
+ xIndexAcc->getByIndex(i) >>= xShape;
+ if (xShape.is())
+ {
+ ScAccessibleShapeData* pShapeData = new ScAccessibleShapeData();
+ pShapeData->xShape = xShape;
+ aShapesList.push_back(pShapeData);
+ }
+ }
+ }
+ else
+ mnShapesSelected = 0;
+ ScShapeDataLess aLess;
+ std::sort(aShapesList.begin(), aShapesList.end(), aLess);
+
+ SortedShapes::iterator aXShapesItr(aShapesList.begin());
+ SortedShapes::const_iterator aXShapesEndItr(aShapesList.end());
+ SortedShapes::iterator aDataItr(maZOrderedShapes.begin());
+ SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end());
+ SortedShapes::const_iterator aFocusedItr = aDataEndItr;
+ while((aDataItr != aDataEndItr))
+ {
+ if (*aDataItr) // is it realy a shape or only the sheet
+ {
+ sal_Int8 nComp(0);
+ if (aXShapesItr == aXShapesEndItr)
+ nComp = -1; // simulate that the Shape is lower, so the selction state will be removed
+ else
+ nComp = Compare(*aDataItr, *aXShapesItr);
+ if (nComp == 0)
+ {
+ if (!(*aDataItr)->bSelected)
+ {
+ (*aDataItr)->bSelected = sal_True;
+ if ((*aDataItr)->pAccShape)
+ {
+ (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED);
+ (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
+ bResult = sal_True;
+ }
+ aFocusedItr = aDataItr;
+ }
+ ++aDataItr;
+ ++aXShapesItr;
+ }
+ else if (nComp < 0)
+ {
+ if ((*aDataItr)->bSelected)
+ {
+ (*aDataItr)->bSelected = sal_False;
+ if ((*aDataItr)->pAccShape)
+ {
+ (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED);
+ (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
+ bResult = sal_True;
+ }
+ }
+ ++aDataItr;
+ }
+ else
+ {
+ DBG_ERRORFILE("here is a selected shape which is not in the childlist");
+ ++aXShapesItr;
+ --mnShapesSelected;
+ }
+ }
+ else
+ ++aDataItr;
+ }
+ if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1))
+ (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED);
+
+ std::for_each(aShapesList.begin(), aShapesList.end(), Destroy());
+
+ return bResult;
+}
+
+void ScChildrenShapes::FillSelectionSupplier() const
+{
+ if (!xSelectionSupplier.is() && mpViewShell)
+ {
+ SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame();
+ if (pViewFrame)
+ {
+ xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ {
+ if (mpAccessibleDocument)
+ xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument);
+ uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+ if (xShapes.is())
+ mnShapesSelected = xShapes->getCount();
+ }
+ }
+ }
+}
+
+ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const
+{
+ ScAddress* pAddress = NULL;
+ if (mpViewShell)
+ {
+ SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
+ uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY);
+ if (pShapeImp && xShapeProp.is())
+ {
+ SdrObject *pSdrObj = pShapeImp->GetSdrObject();
+ if (pSdrObj)
+ {
+ if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
+ {
+ ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
+ if (pDoc)
+ {
+ rtl::OUString sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape"));
+ awt::Point aPoint(xShape->getPosition());
+ awt::Size aSize(xShape->getSize());
+ rtl::OUString sType(xShape->getShapeType());
+ Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
+ if ( sType.equals(sCaptionShape) )
+ {
+ awt::Point aRelativeCaptionPoint;
+ rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
+ xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
+ Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
+ Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
+ aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
+ aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
+ }
+ ScRange aRange = pDoc->GetRange(mpAccessibleDocument->getVisibleTable(), aRectangle);
+ pAddress = new ScAddress(aRange.aStart);
+ }
+ }
+// else
+// do nothing, because it is always a NULL Pointer
+ }
+ }
+ }
+
+ return pAddress;
+}
+
+uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const
+{
+ utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper();
+
+ if(pData && pRelationSet && mpAccessibleDocument)
+ {
+ uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table
+ if (pData->pRelationCell && xAccessible.is())
+ {
+ uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccTable.is())
+ xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col());
+ }
+ AccessibleRelation aRelation;
+ aRelation.TargetSet.realloc(1);
+ aRelation.TargetSet[0] = xAccessible;
+ aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY;
+ pRelationSet->AddRelation(aRelation);
+ }
+
+ return pRelationSet;
+}
+
+void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const
+{
+ SortedShapes::iterator aItr;
+ if (FindShape(xShape, aItr))
+ SetAnchor(xShape, *aItr);
+}
+
+void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const
+{
+ if (pData)
+ {
+ ScAddress* pAddress = GetAnchor(xShape);
+ if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) ||
+ (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell))
+ {
+ if (pData->pRelationCell)
+ delete pData->pRelationCell;
+ pData->pRelationCell = pAddress;
+ if (pData->pAccShape)
+ pData->pAccShape->SetRelationSet(GetRelationSet(pData));
+ }
+ }
+}
+
+void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const
+{
+ SortedShapes::iterator aFindItr;
+ if (!FindShape(xShape, aFindItr))
+ {
+ ScAccessibleShapeData* pShape = new ScAccessibleShapeData();
+ pShape->xShape = xShape;
+ SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape);
+ SetAnchor(xShape, pShape);
+
+ uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY);
+ if (xShapeProp.is())
+ {
+ uno::Any aPropAny = xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )));
+ sal_Int16 nLayerID = 0;
+ if( aPropAny >>= nLayerID )
+ {
+ if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
+ pShape->bSelectable = sal_False;
+ else
+ pShape->bSelectable = sal_True;
+ }
+ }
+
+
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+ if (xEnumAcc.is())
+ {
+ uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration();
+ if (xEnum.is())
+ {
+ uno::Reference<drawing::XShape> xSelectedShape;
+ sal_Bool bFound(sal_False);
+ while (!bFound && xEnum->hasMoreElements())
+ {
+ xEnum->nextElement() >>= xSelectedShape;
+ if (xShape.is() && (xShape.get() == xSelectedShape.get()))
+ {
+ pShape->bSelected = sal_True;
+ bFound = sal_True;
+ }
+ }
+ }
+ }
+ if (mpAccessibleDocument && bCommitChange)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin());
+
+ mpAccessibleDocument->CommitChange(aEvent); // new child - event
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("shape is always in the list");
+ }
+}
+
+void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const
+{
+ SortedShapes::iterator aItr;
+ if (FindShape(xShape, aItr))
+ {
+ if (mpAccessibleDocument)
+ {
+ uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin()));
+
+ delete *aItr;
+ maZOrderedShapes.erase(aItr);
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.OldValue <<= uno::makeAny(xOldAccessible);
+
+ mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
+ }
+ else
+ {
+ delete *aItr;
+ maZOrderedShapes.erase(aItr);
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("shape was not in internal list");
+ }
+}
+
+sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const
+{
+ sal_Bool bResult(sal_False);
+ ScAccessibleShapeData aShape;
+ aShape.xShape = xShape;
+ ScShapeDataLess aLess;
+ rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess);
+ if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get()))
+ bResult = sal_True; // if the shape is found
+
+#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
+ SortedShapes::iterator aDebugItr = maZOrderedShapes.begin();
+ SortedShapes::iterator aEndItr = maZOrderedShapes.end();
+ sal_Bool bFound(sal_False);
+ while (!bFound && aDebugItr != aEndItr)
+ {
+ if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get()))
+ bFound = sal_True;
+ else
+ ++aDebugItr;
+ }
+ sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end());
+ DBG_ASSERT((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found");
+#endif
+ return bResult;
+}
+
+sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1,
+ const ScAccessibleShapeData* pData2) const
+{
+ ScShapeDataLess aLess;
+
+ sal_Bool bResult1(aLess(pData1, pData2));
+ sal_Bool bResult2(aLess(pData2, pData1));
+
+ sal_Int8 nResult(0);
+ if (!bResult1 && bResult2)
+ nResult = 1;
+ else if (bResult1 && !bResult2)
+ nResult = -1;
+
+ return nResult;
+}
+
+struct ScVisAreaChanged
+{
+ ScAccessibleDocument* mpAccDoc;
+ ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {}
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData && pAccShapeData->pAccShape)
+ {
+ pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc);
+ }
+ }
+};
+
+void ScChildrenShapes::VisAreaChanged() const
+{
+ ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument);
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged);
+}
+
+// ============================================================================
+
+ScAccessibleDocument::ScAccessibleDocument(
+ const uno::Reference<XAccessible>& rxParent,
+ ScTabViewShell* pViewShell,
+ ScSplitPos eSplitPos)
+ : ScAccessibleDocumentBase(rxParent),
+ mpViewShell(pViewShell),
+ meSplitPos(eSplitPos),
+ mpAccessibleSpreadsheet(NULL),
+ mpChildrenShapes(NULL),
+ mpTempAccEdit(NULL),
+ mbCompleteSheetSelected(sal_False)
+{
+ if (pViewShell)
+ {
+ pViewShell->AddAccessibilityObject(*this);
+ Window *pWin = pViewShell->GetWindowByPos(eSplitPos);
+ if( pWin )
+ {
+ pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
+ USHORT nCount = pWin->GetChildCount();
+ for( sal_uInt16 i=0; i < nCount; ++i )
+ {
+ Window *pChildWin = pWin->GetChild( i );
+ if( pChildWin &&
+ AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
+ AddChild( pChildWin->GetAccessible(), sal_False );
+ }
+ }
+ if (pViewShell->GetViewData()->HasEditView( eSplitPos ))
+ {
+ uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewShell->GetViewData()->GetEditView(eSplitPos),
+ pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(),
+ CellInEditMode);
+ AddChild(xAcc, sal_False);
+ }
+ }
+ maVisArea = GetVisibleArea_Impl();
+}
+
+void ScAccessibleDocument::Init()
+{
+ if(!mpChildrenShapes)
+ mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos);
+}
+
+ScAccessibleDocument::~ScAccessibleDocument(void)
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessibleDocument::disposing()
+{
+ ScUnoGuard aGuard;
+ FreeAccessibleSpreadsheet();
+ if (mpViewShell)
+ {
+ Window *pWin = mpViewShell->GetWindowByPos(meSplitPos);
+ if( pWin )
+ pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
+
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ if (mpChildrenShapes)
+ DELETEZ(mpChildrenShapes);
+
+ ScAccessibleDocumentBase::disposing();
+}
+
+void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ )
+ throw (uno::RuntimeException)
+{
+ disposing();
+}
+
+ //===== SfxListener =====================================================
+
+IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
+{
+ DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
+ if ( pEvent && pEvent->ISA( VclWindowEvent ) )
+ {
+ VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
+ DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
+ switch ( pVclEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
+ {
+ Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
+ if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
+ {
+ AddChild( pChildWin->GetAccessible(), sal_True );
+ }
+ }
+ break;
+ case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children
+ {
+ Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
+ if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
+ {
+ RemoveChild( pChildWin->GetAccessible(), sal_True );
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( ScAccGridWinFocusLostHint ) )
+ {
+ const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint;
+ if (rRef.GetOldGridWin() == meSplitPos)
+ {
+ if (mxTempAcc.is() && mpTempAccEdit)
+ mpTempAccEdit->LostFocus();
+ else if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->LostFocus();
+ else
+ CommitFocusLost();
+ }
+ }
+ else if (rHint.ISA( ScAccGridWinFocusGotHint ) )
+ {
+ const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint;
+ if (rRef.GetNewGridWin() == meSplitPos)
+ {
+ if (mxTempAcc.is() && mpTempAccEdit)
+ mpTempAccEdit->GotFocus();
+ else if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->GotFocus();
+ else
+ CommitFocusGained();
+ }
+ }
+ else if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
+ mpAccessibleSpreadsheet)
+ {
+ FreeAccessibleSpreadsheet();
+ if (mpChildrenShapes)
+ DELETEZ(mpChildrenShapes);
+
+ // #124567# Accessibility: Shapes / form controls after reload not accessible
+ if ( !mpChildrenShapes )
+ {
+ mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos );
+ }
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent); // all childs changed
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
+ {
+ if (mpChildrenShapes)
+ mpChildrenShapes->SetDrawBroadcaster();
+ }
+ else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell
+ {
+ if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos))
+ {
+ mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos),
+ mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(),
+ rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), CellInEditMode);
+ uno::Reference<XAccessible> xAcc = mpTempAccEdit;
+
+ AddChild(xAcc, sal_True);
+
+ if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->LostFocus();
+ else
+ CommitFocusLost();
+
+ mpTempAccEdit->GotFocus();
+ }
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE)
+ {
+ if (mxTempAcc.is())
+ {
+ if (mpTempAccEdit)
+ mpTempAccEdit->LostFocus();
+
+ mpTempAccEdit = NULL;
+ RemoveChild(mxTempAcc, sal_True);
+
+ if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->GotFocus();
+ else
+ CommitFocusGained();
+ }
+ }
+ else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED))
+ {
+ Rectangle aOldVisArea(maVisArea);
+ maVisArea = GetVisibleArea_Impl();
+
+ if (maVisArea != aOldVisArea)
+ {
+ if (maVisArea.GetSize() != aOldVisArea.GetSize())
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+
+ if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->BoundingBoxChanged();
+ }
+ else if (mpAccessibleSpreadsheet)
+ {
+ mpAccessibleSpreadsheet->VisAreaChanged();
+ }
+ if (mpChildrenShapes)
+ mpChildrenShapes->VisAreaChanged();
+ }
+ }
+ }
+
+ ScAccessibleDocumentBase::Notify(rBC, rHint);
+}
+
+void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bSelectionChanged(sal_False);
+ if (mpAccessibleSpreadsheet)
+ {
+ sal_Bool bOldSelected(mbCompleteSheetSelected);
+ mbCompleteSheetSelected = IsTableSelected();
+ if (bOldSelected != mbCompleteSheetSelected)
+ {
+ mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
+ bSelectionChanged = sal_True;
+ }
+ }
+
+ if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
+ bSelectionChanged = sal_True;
+
+ if (bSelectionChanged)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+ }
+}
+
+ //===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleDocument::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleDocument::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xAccessible = NULL;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpChildrenShapes)
+ xAccessible = mpChildrenShapes->GetAt(rPoint);
+ if(!xAccessible.is())
+ {
+ if (mxTempAcc.is())
+ {
+ uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext());
+ uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ Rectangle aBound(VCLRectangle(xComp->getBounds()));
+ if (aBound.IsInside(VCLPoint(rPoint)))
+ xAccessible = mxTempAcc;
+ }
+ }
+ if (!xAccessible.is())
+ xAccessible = GetAccessibleSpreadsheet();
+ }
+ }
+ return xAccessible;
+}
+
+void SAL_CALL ScAccessibleDocument::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ {
+ xAccessibleComponent->grabFocus();
+ // grab only focus if it does not have the focus and it is not hidden
+ if (mpViewShell && mpViewShell->GetViewData() &&
+ (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
+ mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
+ {
+ mpViewShell->ActivatePart(meSplitPos);
+ }
+ }
+ }
+}
+
+ //===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+sal_Int32 SAL_CALL
+ ScAccessibleDocument::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nCount(1);
+ if (mpChildrenShapes)
+ nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
+
+ if (mxTempAcc.is())
+ ++nCount;
+
+ return nCount;
+}
+
+ /// Return the specified child or NULL if index is invalid.
+uno::Reference<XAccessible> SAL_CALL
+ ScAccessibleDocument::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAccessible;
+ if (nIndex >= 0)
+ {
+ sal_Int32 nCount(1);
+ if (mpChildrenShapes)
+ {
+ xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
+ nCount = mpChildrenShapes->GetCount(); //there is always a table
+ }
+ if (!xAccessible.is())
+ {
+ if (nIndex < nCount)
+ xAccessible = GetAccessibleSpreadsheet();
+ else if (nIndex == nCount && mxTempAcc.is())
+ xAccessible = mxTempAcc;
+ }
+ }
+
+ if (!xAccessible.is())
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+ /// Return the set of current states.
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleDocument::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ if (IsEditable(xParentStates))
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+ ///===== XAccessibleSelection ===========================================
+
+void SAL_CALL
+ ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ {
+ sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
+ if (mxTempAcc.is())
+ ++nCount;
+ if (nChildIndex < 0 || nChildIndex >= nCount)
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
+ if (xAccessible.is())
+ {
+ sal_Bool bWasTableSelected(IsTableSelected());
+
+ if (mpChildrenShapes)
+ mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
+
+ if (bWasTableSelected)
+ mpViewShell->SelectAll();
+ }
+ else
+ {
+ if (mpViewShell)
+ mpViewShell->SelectAll();
+ }
+ }
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Bool bResult(sal_False);
+
+ if (mpChildrenShapes)
+ {
+ sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
+ if (mxTempAcc.is())
+ ++nCount;
+ if (nChildIndex < 0 || nChildIndex >= nCount)
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
+ if (xAccessible.is())
+ {
+ uno::Reference<drawing::XShape> xShape;
+ bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is to high
+ }
+ else
+ {
+ if (mxTempAcc.is() && nChildIndex == nCount)
+ bResult = sal_True;
+ else
+ bResult = IsTableSelected();
+ }
+ }
+ return bResult;
+}
+
+void SAL_CALL
+ ScAccessibleDocument::clearAccessibleSelection( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ mpChildrenShapes->DeselectAll(); //deselects all (also the table)
+}
+
+void SAL_CALL
+ ScAccessibleDocument::selectAllAccessibleChildren( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ mpChildrenShapes->SelectAll();
+
+ // select table after shapes, because while selecting shapes the table will be deselected
+ if (mpViewShell)
+ {
+ mpViewShell->SelectAll();
+ }
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleDocument::getSelectedAccessibleChildCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nCount(0);
+
+ if (mpChildrenShapes)
+ nCount = mpChildrenShapes->GetSelectedCount();
+
+ if (IsTableSelected())
+ ++nCount;
+
+ if (mxTempAcc.is())
+ ++nCount;
+
+ return nCount;
+}
+
+uno::Reference<XAccessible > SAL_CALL
+ ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAccessible;
+ if (mpChildrenShapes)
+ {
+ sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
+ if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bTabMarked(IsTableSelected());
+
+ if (mpChildrenShapes)
+ xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
+ if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
+ xAccessible = mxTempAcc;
+ else if (bTabMarked)
+ xAccessible = GetAccessibleSpreadsheet();
+ }
+
+ DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed");
+
+ return xAccessible;
+}
+
+void SAL_CALL
+ ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ {
+ sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
+ if (mxTempAcc.is())
+ ++nCount;
+ if (nChildIndex < 0 || nChildIndex >= nCount)
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bTabMarked(IsTableSelected());
+
+ uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
+ if (xAccessible.is())
+ {
+ if (mpChildrenShapes)
+ mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
+
+ if (bTabMarked)
+ mpViewShell->SelectAll(); // select the table again
+ }
+ else if (bTabMarked)
+ mpViewShell->Unmark();
+ }
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessibleDocument::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleDocument::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleDocument::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+///===== IAccessibleViewForwarder ========================================
+
+sal_Bool ScAccessibleDocument::IsValid (void) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
+}
+
+Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
+{
+ Rectangle aVisRect(GetBoundingBox());
+
+ Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point
+ aPoint.setX(-aPoint.getX());
+ aPoint.setY(-aPoint.getY());
+ aVisRect.SetPos(aPoint);
+
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
+
+ return aVisRect;
+}
+
+Rectangle ScAccessibleDocument::GetVisibleArea() const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return maVisArea;
+}
+
+Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Point aPoint;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ {
+ aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
+ aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
+ }
+ return aPoint;
+}
+
+Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Size aSize;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
+ return aSize;
+}
+
+Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Point aPoint;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ {
+ aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
+ aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
+ }
+ return aPoint;
+}
+
+Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Size aSize;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
+ return aSize;
+}
+
+ //===== internal ========================================================
+
+utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
+{
+ utl::AccessibleRelationSetHelper* pRelationSet = NULL;
+ if (mpChildrenShapes)
+ pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
+ return pRelationSet;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleDocument::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR));
+ return sDescription;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleDocument::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME));
+ sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
+ sName += rtl::OUString::valueOf(nNumber);
+ return sName;
+}
+
+Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(NULL);
+ }
+ return aRect;
+}
+
+Rectangle ScAccessibleDocument::GetBoundingBox() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
+ }
+ return aRect;
+}
+
+SCTAB ScAccessibleDocument::getVisibleTable() const
+{
+ SCTAB nVisibleTable(0);
+ if (mpViewShell && mpViewShell->GetViewData())
+ nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
+ return nVisibleTable;
+}
+
+uno::Reference < XAccessible >
+ ScAccessibleDocument::GetAccessibleSpreadsheet()
+{
+ if (!mpAccessibleSpreadsheet && mpViewShell)
+ {
+ mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
+ mpAccessibleSpreadsheet->acquire();
+ mpAccessibleSpreadsheet->Init();
+ mbCompleteSheetSelected = IsTableSelected();
+ }
+ return mpAccessibleSpreadsheet;
+}
+
+void ScAccessibleDocument::FreeAccessibleSpreadsheet()
+{
+ if (mpAccessibleSpreadsheet)
+ {
+ mpAccessibleSpreadsheet->dispose();
+ mpAccessibleSpreadsheet->release();
+ mpAccessibleSpreadsheet = NULL;
+ }
+}
+
+sal_Bool ScAccessibleDocument::IsTableSelected() const
+{
+ sal_Bool bResult (sal_False);
+ if(mpViewShell)
+ {
+ SCTAB nTab(getVisibleTable());
+ //#103800#; use a copy of MarkData
+ ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
+ aMarkData.MarkToMulti();
+ if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+sal_Bool ScAccessibleDocument::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessibleDocument::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ // what is with document protection or readonly documents?
+ return sal_True;
+}
+
+void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
+{
+ DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before");
+ if (xAcc.is())
+ {
+ mxTempAcc = xAcc;
+ if( bFireEvent )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext>(this);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= mxTempAcc;
+ CommitChange( aEvent );
+ }
+ }
+}
+
+void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
+{
+ DBG_ASSERT(mxTempAcc.is(), "this object should be added before");
+ if (xAcc.is())
+ {
+ DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
+ if( bFireEvent )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext>(this);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= mxTempAcc;
+ CommitChange( aEvent );
+ }
+ mxTempAcc = NULL;
+ }
+}
+
+rtl::OUString ScAccessibleDocument::GetCurrentCellName() const
+{
+ String sName( ScResId(STR_ACC_CELL_NAME) );
+ if (mpViewShell)
+ {
+ String sAddress;
+ // Document not needed, because only the cell address, but not the tablename is needed
+ mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL );
+ sName.SearchAndReplaceAscii("%1", sAddress);
+ }
+ return rtl::OUString(sName);
+}
+
+rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const
+{
+ return rtl::OUString();
+}
diff --git a/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx b/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx
new file mode 100644
index 000000000000..76be8e67aa07
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleDocumentBase.hxx"
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+ //===== internal ========================================================
+
+ScAccessibleDocumentBase::ScAccessibleDocumentBase(
+ const uno::Reference<XAccessible>& rxParent)
+ : ScAccessibleContextBase(rxParent, AccessibleRole::DOCUMENT)
+{
+}
+
+ScAccessibleDocumentBase::~ScAccessibleDocumentBase(void)
+{
+}
diff --git a/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx
new file mode 100644
index 000000000000..894e57d3802e
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx
@@ -0,0 +1,1942 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleDocumentPagePreview.hxx"
+#include "AccessiblePreviewTable.hxx"
+#include "AccessiblePageHeader.hxx"
+#include "AccessibilityHints.hxx"
+#include "AccessibleText.hxx"
+#include "document.hxx"
+#include "prevwsh.hxx"
+#include "prevloc.hxx"
+#include "unoguard.hxx"
+#include "drwlayer.hxx"
+#include "editsrc.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "DrawModelBroadcaster.hxx"
+#include "docsh.hxx"
+#include "drawview.hxx"
+#include "preview.hxx"
+#include "postit.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+
+#include <unotools/accessiblestatesethelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <svx/AccessibleShape.hxx>
+#include <svx/ShapeTypeHandler.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <svx/unoshape.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//=========================================================================
+
+typedef std::list< uno::Reference< XAccessible > > ScXAccList;
+
+
+struct ScAccNote
+{
+ String maNoteText;
+ Rectangle maRect;
+ ScAddress maNoteCell;
+ ::accessibility::AccessibleTextHelper* mpTextHelper;
+ sal_Int32 mnParaCount;
+ sal_Bool mbMarkNote;
+
+ ScAccNote() : mpTextHelper(NULL), mnParaCount(0) {}
+};
+
+class ScNotesChilds
+{
+public:
+ ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
+ ~ScNotesChilds();
+ void Init(const Rectangle& rVisRect, sal_Int32 nOffset);
+
+ sal_Int32 GetChildsCount() const;
+ uno::Reference<XAccessible> GetChild(sal_Int32 nIndex) const;
+ uno::Reference<XAccessible> GetAt(const awt::Point& rPoint) const;
+
+ void DataChanged(const Rectangle& rVisRect);
+ void SetOffset(sal_Int32 nNewOffset);
+private:
+ ScPreviewShell* mpViewShell;
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ typedef std::vector<ScAccNote> ScAccNotes;
+ mutable ScAccNotes maNotes;
+ mutable ScAccNotes maMarks;
+ sal_Int32 mnParagraphs;
+ sal_Int32 mnOffset;
+
+ ::accessibility::AccessibleTextHelper* CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const;
+ sal_Int32 AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes);
+
+ sal_Int8 CompareCell(const ScAddress& aCell1, const ScAddress& aCell2);
+ void CollectChilds(const ScAccNote& rNote, ScXAccList& rList);
+ sal_Int32 CheckChanges(const ScPreviewLocationData& rData, const Rectangle& rVisRect,
+ sal_Bool bMark, ScAccNotes& rOldNotes, ScAccNotes& rNewNotes,
+ ScXAccList& rOldParas, ScXAccList& rNewParas);
+
+ inline ScDocument* GetDocument() const;
+};
+
+ScNotesChilds::ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
+ : mpViewShell(pViewShell),
+ mpAccDoc(pAccDoc),
+ mnParagraphs(0),
+ mnOffset(0)
+{
+}
+
+struct DeleteAccNote
+{
+ void operator()(ScAccNote& rNote)
+ {
+ if (rNote.mpTextHelper)
+ DELETEZ( rNote.mpTextHelper);
+ }
+};
+
+ScNotesChilds::~ScNotesChilds()
+{
+ std::for_each(maNotes.begin(), maNotes.end(), DeleteAccNote());
+ std::for_each(maMarks.begin(), maMarks.end(), DeleteAccNote());
+}
+
+::accessibility::AccessibleTextHelper* ScNotesChilds::CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const
+{
+ ::accessibility::AccessibleTextHelper* pTextHelper = NULL;
+
+ ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
+ (new ScAccessibleNoteTextData(mpViewShell, rString, aCellPos, bMarkNote));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
+
+ pTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource);
+
+ if (pTextHelper)
+ {
+ pTextHelper->SetEventSource(mpAccDoc);
+ pTextHelper->SetStartIndex(nChildOffset);
+ pTextHelper->SetOffset(rVisRect.TopLeft());
+ }
+
+ return pTextHelper;
+}
+
+sal_Int32 ScNotesChilds::AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes)
+{
+ sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
+
+ rNotes.reserve(nCount);
+
+ sal_Int32 nParagraphs(0);
+ ScDocument* pDoc = GetDocument();
+ if (pDoc)
+ {
+ ScAccNote aNote;
+ aNote.mbMarkNote = bMark;
+ if (bMark)
+ aNote.mnParaCount = 1;
+ for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
+ {
+ if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
+ {
+ if (bMark)
+ {
+ // Document not needed, because only the cell address, but not the tablename is needed
+ aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
+ }
+ else
+ {
+ if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
+ aNote.maNoteText = pNote->GetText();
+ aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
+ if (aNote.mpTextHelper)
+ aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
+ }
+ nParagraphs += aNote.mnParaCount;
+ rNotes.push_back(aNote);
+ }
+ }
+ }
+ return nParagraphs;
+}
+
+void ScNotesChilds::Init(const Rectangle& rVisRect, sal_Int32 nOffset)
+{
+ if (mpViewShell && !mnParagraphs)
+ {
+ mnOffset = nOffset;
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+
+ mnParagraphs = AddNotes(rData, rVisRect, sal_False, maMarks);
+ mnParagraphs += AddNotes(rData, rVisRect, sal_True, maNotes);
+ }
+}
+
+sal_Int32 ScNotesChilds::GetChildsCount() const
+{
+ return mnParagraphs;
+}
+
+struct ScParaFound
+{
+ sal_Int32 mnIndex;
+ ScParaFound(sal_Int32 nIndex) : mnIndex(nIndex) {}
+ sal_Bool operator() (const ScAccNote& rNote)
+ {
+ sal_Bool bResult(sal_False);
+ if (rNote.mnParaCount > mnIndex)
+ bResult = sal_True;
+ else
+ mnIndex -= rNote.mnParaCount;
+ return bResult;
+ }
+};
+
+uno::Reference<XAccessible> ScNotesChilds::GetChild(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+
+ if (nIndex < mnParagraphs)
+ {
+ if (nIndex < static_cast<sal_Int32>(maMarks.size()))
+ {
+ ScAccNotes::iterator aEndItr = maMarks.end();
+ ScParaFound aParaFound(nIndex);
+ ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aParaFound);
+ if (aItr != aEndItr)
+ {
+ DBG_ASSERT((aItr->maNoteCell == maMarks[nIndex].maNoteCell) && (aItr->mbMarkNote == maMarks[nIndex].mbMarkNote), "wrong note found");
+ }
+ else
+ {
+ DBG_ERRORFILE("wrong note found");
+ }
+ if (!aItr->mpTextHelper)
+ aItr->mpTextHelper = CreateTextHelper(maMarks[nIndex].maNoteText, maMarks[nIndex].maRect, maMarks[nIndex].maNoteCell, maMarks[nIndex].mbMarkNote, nIndex + mnOffset); // the marks are the first and every mark has only one paragraph
+ xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
+ }
+ else
+ {
+ nIndex -= maMarks.size();
+ ScAccNotes::iterator aEndItr = maNotes.end();
+ ScParaFound aParaFound(nIndex);
+ ScAccNotes::iterator aItr = std::find_if(maNotes.begin(), aEndItr, aParaFound);
+ if (aEndItr != aItr)
+ {
+ if (!aItr->mpTextHelper)
+ aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, (nIndex - aParaFound.mnIndex) + mnOffset + maMarks.size());
+ xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
+ }
+ }
+ }
+
+ return xAccessible;
+}
+
+struct ScPointFound
+{
+ Rectangle maPoint;
+ sal_Int32 mnParagraphs;
+ ScPointFound(const Point& rPoint) : maPoint(rPoint, Size(0, 0)), mnParagraphs(0) {}
+ sal_Bool operator() (const ScAccNote& rNote)
+ {
+ sal_Bool bResult(sal_False);
+ if (maPoint.IsInside(rNote.maRect))
+ bResult = sal_True;
+ else
+ mnParagraphs += rNote.mnParaCount;
+ return bResult;
+ }
+};
+
+uno::Reference<XAccessible> ScNotesChilds::GetAt(const awt::Point& rPoint) const
+{
+ uno::Reference<XAccessible> xAccessible;
+
+ ScPointFound aPointFound(Point(rPoint.X, rPoint.Y));
+
+ ScAccNotes::iterator aEndItr = maMarks.end();
+ ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aPointFound);
+ if (aEndItr == aItr)
+ {
+ aEndItr = maNotes.end();
+ aItr = std::find_if(maNotes.begin(), aEndItr, aPointFound);
+ }
+ if (aEndItr != aItr)
+ {
+ if (!aItr->mpTextHelper)
+ aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, aPointFound.mnParagraphs + mnOffset);
+ xAccessible = aItr->mpTextHelper->GetAt(rPoint);
+ }
+
+ return xAccessible;
+}
+
+sal_Int8 ScNotesChilds::CompareCell(const ScAddress& aCell1, const ScAddress& aCell2)
+{
+ DBG_ASSERT(aCell1.Tab() == aCell2.Tab(), "the notes should be on the same table");
+ sal_Int8 nResult(0);
+ if (aCell1 != aCell2)
+ {
+ if (aCell1.Row() == aCell2.Row())
+ nResult = (aCell1.Col() < aCell2.Col()) ? -1 : 1;
+ else
+ nResult = (aCell1.Row() < aCell2.Row()) ? -1 : 1;
+ }
+ return nResult;
+}
+
+void ScNotesChilds::CollectChilds(const ScAccNote& rNote, ScXAccList& rList)
+{
+ if (rNote.mpTextHelper)
+ for (sal_Int32 i = 0; i < rNote.mnParaCount; ++i)
+ rList.push_back(rNote.mpTextHelper->GetChild(i + rNote.mpTextHelper->GetStartIndex()));
+}
+
+sal_Int32 ScNotesChilds::CheckChanges(const ScPreviewLocationData& rData,
+ const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rOldNotes,
+ ScAccNotes& rNewNotes, ScXAccList& rOldParas, ScXAccList& rNewParas)
+{
+ sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
+
+ rNewNotes.reserve(nCount);
+
+ sal_Int32 nParagraphs(0);
+ ScDocument* pDoc = GetDocument();
+ if (pDoc)
+ {
+ ScAccNote aNote;
+ aNote.mbMarkNote = bMark;
+ if (bMark)
+ aNote.mnParaCount = 1;
+ ScAccNotes::iterator aItr = rOldNotes.begin();
+ ScAccNotes::iterator aEndItr = rOldNotes.end();
+ sal_Bool bAddNote(sal_False);
+ for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
+ {
+ if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
+ {
+ if (bMark)
+ {
+ // Document not needed, because only the cell address, but not the tablename is needed
+ aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
+ }
+ else
+ {
+ if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
+ aNote.maNoteText = pNote->GetText();
+ }
+
+ sal_Int8 nCompare(-1); // if there are no more old childs it is always a new one
+ if (aItr != aEndItr)
+ nCompare = CompareCell(aNote.maNoteCell, aItr->maNoteCell);
+ if (nCompare == 0)
+ {
+ if (aNote.maNoteText == aItr->maNoteText)
+ {
+ aNote.mpTextHelper = aItr->mpTextHelper;
+ if (aNote.maRect != aItr->maRect) //neue VisArea setzen
+ {
+ aNote.mpTextHelper->SetOffset(aNote.maRect.TopLeft());
+ aNote.mpTextHelper->UpdateChildren();
+ //DBG_ASSERT(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
+ // could be changed, because only a part of the note is visible
+ }
+ }
+ else
+ {
+ aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
+ if (aNote.mpTextHelper)
+ aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
+ // collect removed childs
+ CollectChilds(*aItr, rOldParas);
+ DELETEZ(aItr->mpTextHelper);
+ // collect new childs
+ CollectChilds(aNote, rNewParas);
+ }
+ bAddNote = sal_True;
+ // not necessary, because this branch should not be reached if it is the end
+ //if (aItr != aEndItr)
+ ++aItr;
+ }
+ else if (nCompare < 0)
+ {
+ aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
+ if (aNote.mpTextHelper)
+ aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
+ // collect new childs
+ CollectChilds(aNote, rNewParas);
+ bAddNote = sal_True;
+ }
+ else
+ {
+ // collect removed childs
+ CollectChilds(*aItr, rOldParas);
+ DELETEZ(aItr->mpTextHelper);
+
+ // no note to add
+ // not necessary, because this branch should not be reached if it is the end
+ //if (aItr != aEndItr)
+ ++aItr;
+ }
+ if (bAddNote)
+ {
+ nParagraphs += aNote.mnParaCount;
+ rNewNotes.push_back(aNote);
+ bAddNote = sal_False;
+ }
+ }
+ }
+ }
+ return nParagraphs;
+}
+
+struct ScChildGone
+{
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ ScChildGone(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
+ void operator() (const uno::Reference<XAccessible>& xAccessible) const
+ {
+ if (mpAccDoc)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
+ aEvent.OldValue <<= xAccessible;
+
+ mpAccDoc->CommitChange(aEvent); // gone child - event
+ }
+ }
+};
+
+struct ScChildNew
+{
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ ScChildNew(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
+ void operator() (const uno::Reference<XAccessible>& xAccessible) const
+ {
+ if (mpAccDoc)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
+ aEvent.NewValue <<= xAccessible;
+
+ mpAccDoc->CommitChange(aEvent); // new child - event
+ }
+ }
+};
+
+void ScNotesChilds::DataChanged(const Rectangle& rVisRect)
+{
+ if (mpViewShell && mpAccDoc)
+ {
+ ScXAccList aNewParas;
+ ScXAccList aOldParas;
+ ScAccNotes aNewMarks;
+ mnParagraphs = CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_True, maMarks, aNewMarks, aOldParas, aNewParas);
+ maMarks = aNewMarks;
+ ScAccNotes aNewNotes;
+ mnParagraphs += CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_False, maNotes, aNewNotes, aOldParas, aNewParas);
+ maNotes = aNewNotes;
+
+ std::for_each(aOldParas.begin(), aOldParas.end(), ScChildGone(mpAccDoc));
+ std::for_each(aNewParas.begin(), aNewParas.end(), ScChildNew(mpAccDoc));
+ }
+}
+
+struct ScChangeOffset
+{
+ sal_Int32 mnDiff;
+ ScChangeOffset(sal_Int32 nDiff) : mnDiff(nDiff) {}
+ void operator() (const ScAccNote& rNote)
+ {
+ if (rNote.mpTextHelper)
+ rNote.mpTextHelper->SetStartIndex(rNote.mpTextHelper->GetStartIndex() + mnDiff);
+ }
+};
+
+void ScNotesChilds::SetOffset(sal_Int32 nNewOffset)
+{
+ sal_Int32 nDiff(nNewOffset - mnOffset);
+ if (nDiff != 0)
+ {
+ std::for_each(maMarks.begin(), maMarks.end(), ScChangeOffset(nDiff));
+ std::for_each(maNotes.begin(), maNotes.end(), ScChangeOffset(nDiff));
+ mnOffset = nNewOffset;
+ }
+}
+
+inline ScDocument* ScNotesChilds::GetDocument() const
+{
+ ScDocument* pDoc = NULL;
+ if (mpViewShell)
+ pDoc = mpViewShell->GetDocument();
+ return pDoc;
+}
+
+class ScIAccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder
+{
+public:
+ ScIAccessibleViewForwarder();
+ ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
+ ScAccessibleDocumentPagePreview* pAccDoc,
+ const MapMode& aMapMode);
+ ~ScIAccessibleViewForwarder();
+
+ ///===== IAccessibleViewForwarder ========================================
+
+ virtual sal_Bool IsValid (void) const;
+ virtual Rectangle GetVisibleArea() const;
+ virtual Point LogicToPixel (const Point& rPoint) const;
+ virtual Size LogicToPixel (const Size& rSize) const;
+ virtual Point PixelToLogic (const Point& rPoint) const;
+ virtual Size PixelToLogic (const Size& rSize) const;
+
+private:
+ ScPreviewShell* mpViewShell;
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ MapMode maMapMode;
+ sal_Bool mbValid;
+};
+
+ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
+ : mbValid(sal_False)
+{
+}
+
+ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
+ ScAccessibleDocumentPagePreview* pAccDoc,
+ const MapMode& aMapMode)
+ : mpViewShell(pViewShell),
+ mpAccDoc(pAccDoc),
+ maMapMode(aMapMode),
+ mbValid(sal_True)
+{
+}
+
+ScIAccessibleViewForwarder::~ScIAccessibleViewForwarder()
+{
+}
+
+///===== IAccessibleViewForwarder ========================================
+
+sal_Bool ScIAccessibleViewForwarder::IsValid (void) const
+{
+ ScUnoGuard aGuard;
+ return mbValid;
+}
+
+Rectangle ScIAccessibleViewForwarder::GetVisibleArea() const
+{
+ ScUnoGuard aGuard;
+ Rectangle aVisRect;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ {
+ aVisRect.SetSize(pWin->GetOutputSizePixel());
+ aVisRect.SetPos(Point(0, 0));
+
+ aVisRect = pWin->PixelToLogic(aVisRect, maMapMode);
+ }
+
+ return aVisRect;
+}
+
+Point ScIAccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ Point aPoint;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin && mpAccDoc)
+ {
+ Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
+ aPoint = pWin->LogicToPixel(rPoint, maMapMode) + aRect.TopLeft();
+ }
+
+ return aPoint;
+}
+
+Size ScIAccessibleViewForwarder::LogicToPixel (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ Size aSize;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->LogicToPixel(rSize, maMapMode);
+ return aSize;
+}
+
+Point ScIAccessibleViewForwarder::PixelToLogic (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ Point aPoint;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin && mpAccDoc)
+ {
+ Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
+ aPoint = pWin->PixelToLogic(rPoint - aRect.TopLeft(), maMapMode);
+ }
+ return aPoint;
+}
+
+Size ScIAccessibleViewForwarder::PixelToLogic (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ Size aSize;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->PixelToLogic(rSize, maMapMode);
+ return aSize;
+}
+
+struct ScShapeChild
+{
+ ScShapeChild() : mpAccShape(NULL) {}
+ ScShapeChild(const ScShapeChild& rOld);
+ ~ScShapeChild();
+ mutable ::accessibility::AccessibleShape* mpAccShape;
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxShape;
+ sal_Int32 mnRangeId;
+};
+
+ScShapeChild::ScShapeChild(const ScShapeChild& rOld)
+:
+mpAccShape(rOld.mpAccShape),
+mxShape(rOld.mxShape),
+mnRangeId(rOld.mnRangeId)
+{
+ if (mpAccShape)
+ mpAccShape->acquire();
+}
+
+ScShapeChild::~ScShapeChild()
+{
+ if (mpAccShape)
+ {
+ mpAccShape->dispose();
+ mpAccShape->release();
+ }
+}
+
+struct ScShapeChildLess
+{
+ sal_Bool operator()(const ScShapeChild& rChild1, const ScShapeChild& rChild2) const
+ {
+ sal_Bool bResult(sal_False);
+ if (rChild1.mxShape.is() && rChild2.mxShape.is())
+ bResult = (rChild1.mxShape.get() < rChild2.mxShape.get());
+ return bResult;
+ }
+};
+
+typedef std::vector<ScShapeChild> ScShapeChildVec;
+
+struct ScShapeRange
+{
+ ScShapeChildVec maBackShapes;
+ ScShapeChildVec maForeShapes; // inclusive internal shapes
+ ScShapeChildVec maControls;
+ Rectangle maPixelRect;
+ MapMode maMapMode;
+ ScIAccessibleViewForwarder maViewForwarder;
+};
+
+typedef std::vector<ScShapeRange> ScShapeRangeVec;
+
+class ScShapeChilds : public SfxListener,
+ public ::accessibility::IAccessibleParent
+{
+public:
+ ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
+ ~ScShapeChilds();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== IAccessibleParent ==============================================
+
+ virtual sal_Bool ReplaceChild (
+ ::accessibility::AccessibleShape* pCurrentChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
+ const long _nIndex,
+ const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
+ ) throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== Internal ========================================================
+
+ void Init();
+
+ sal_Int32 GetBackShapeCount() const;
+ uno::Reference<XAccessible> GetBackShape(sal_Int32 nIndex) const;
+ sal_Int32 GetForeShapeCount() const;
+ uno::Reference<XAccessible> GetForeShape(sal_Int32 nIndex) const;
+ sal_Int32 GetControlCount() const;
+ uno::Reference<XAccessible> GetControl(sal_Int32 nIndex) const;
+ uno::Reference<XAccessible> GetForegroundShapeAt(const awt::Point& rPoint) const; // inclusive controls
+ uno::Reference<XAccessible> GetBackgroundShapeAt(const awt::Point& rPoint) const;
+
+ void DataChanged();
+ void VisAreaChanged() const;
+
+ void SetDrawBroadcaster();
+private:
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ ScPreviewShell* mpViewShell;
+ ScShapeRangeVec maShapeRanges;
+
+ void FindChanged(ScShapeChildVec& aOld, ScShapeChildVec& aNew) const;
+ void FindChanged(ScShapeRange& aOld, ScShapeRange& aNew) const;
+ ::accessibility::AccessibleShape* GetAccShape(const ScShapeChild& rShape) const;
+ ::accessibility::AccessibleShape* GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const;
+ void FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId);
+//UNUSED2008-05 sal_Bool FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const;
+
+// void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
+// void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
+ SdrPage* GetDrawPage() const;
+};
+
+ScShapeChilds::ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
+ :
+ mpAccDoc(pAccDoc),
+ mpViewShell(pViewShell),
+ maShapeRanges(SC_PREVIEW_MAXRANGES)
+{
+ if (pViewShell)
+ {
+ SfxBroadcaster* pDrawBC = pViewShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+ }
+}
+
+ScShapeChilds::~ScShapeChilds()
+{
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ }
+}
+
+void ScShapeChilds::SetDrawBroadcaster()
+{
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC, TRUE);
+ }
+}
+
+void ScShapeChilds::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SdrHint ) )
+ {
+ const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
+ if (pSdrHint)
+ {
+ SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
+ if (pObj && (pObj->GetPage() == GetDrawPage()))
+ {
+ switch (pSdrHint->GetKind())
+ {
+ case HINT_OBJCHG : // Objekt geaendert
+ {
+ }
+ break;
+ // no longer necessary
+/* case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ AddShape(xShape, pObj->GetLayer());
+ }
+ break;
+ case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ RemoveShape(xShape, pObj->GetLayer());
+ }
+ break;*/
+ default :
+ {
+ // other events are not interesting
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ScShapeChilds::FindChanged(ScShapeChildVec& rOld, ScShapeChildVec& rNew) const
+{
+ ScShapeChildVec::iterator aOldItr = rOld.begin();
+ ScShapeChildVec::iterator aOldEnd = rOld.end();
+ ScShapeChildVec::const_iterator aNewItr = rNew.begin();
+ ScShapeChildVec::const_iterator aNewEnd = rNew.begin();
+ uno::Reference<XAccessible> xAcc;
+ while ((aNewItr != aNewEnd) && (aOldItr != aOldEnd))
+ {
+ if (aNewItr->mxShape.get() == aOldItr->mxShape.get())
+ {
+ ++aOldItr;
+ ++aNewItr;
+ }
+ else if (aNewItr->mxShape.get() < aOldItr->mxShape.get())
+ {
+ xAcc = GetAccShape(*aNewItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aNewItr;
+ }
+ else
+ {
+ xAcc = GetAccShape(*aOldItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aOldItr;
+ }
+ }
+ while (aOldItr != aOldEnd)
+ {
+ xAcc = GetAccShape(*aOldItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aOldItr;
+ }
+ while (aNewItr != aNewEnd)
+ {
+ xAcc = GetAccShape(*aNewItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aNewItr;
+ }
+}
+
+void ScShapeChilds::FindChanged(ScShapeRange& rOld, ScShapeRange& rNew) const
+{
+ FindChanged(rOld.maBackShapes, rNew.maBackShapes);
+ FindChanged(rOld.maForeShapes, rNew.maForeShapes);
+ FindChanged(rOld.maControls, rNew.maControls);
+}
+
+void ScShapeChilds::DataChanged()
+{
+ ScShapeRangeVec aOldShapeRanges(maShapeRanges);
+ maShapeRanges.clear();
+ maShapeRanges.resize(SC_PREVIEW_MAXRANGES);
+ Init();
+ for (sal_Int32 i = 0; i < SC_PREVIEW_MAXRANGES; ++i)
+ {
+ FindChanged(aOldShapeRanges[i], maShapeRanges[i]);
+ }
+}
+
+struct ScVisAreaChanged
+{
+ const ScIAccessibleViewForwarder* mpViewForwarder;
+ ScVisAreaChanged(const ScIAccessibleViewForwarder* pViewForwarder) : mpViewForwarder(pViewForwarder) {}
+ void operator() (const ScShapeChild& rAccShapeData) const
+ {
+ if (rAccShapeData.mpAccShape)
+ {
+ rAccShapeData.mpAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpViewForwarder);
+ }
+ }
+};
+
+void ScShapeChilds::VisAreaChanged() const
+{
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while (aItr != aEndItr)
+ {
+ ScVisAreaChanged aVisAreaChanged(&(aItr->maViewForwarder));
+ std::for_each(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), aVisAreaChanged);
+ std::for_each(aItr->maControls.begin(), aItr->maControls.end(), aVisAreaChanged);
+ std::for_each(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), aVisAreaChanged);
+ ++aItr;
+ }
+}
+
+ ///===== IAccessibleParent ==============================================
+
+sal_Bool ScShapeChilds::ReplaceChild (::accessibility::AccessibleShape* /* pCurrentChild */,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& /* _rxShape */,
+ const long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo& /* _rShapeTreeInfo */)
+ throw (uno::RuntimeException)
+{
+ DBG_ERRORFILE("should not be called in the page preview");
+ return sal_False;
+}
+
+ ///===== Internal ========================================================
+
+void ScShapeChilds::Init()
+{
+ if(mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ MapMode aMapMode;
+ Rectangle aPixelPaintRect;
+ sal_uInt8 nRangeId;
+ sal_uInt16 nCount(rData.GetDrawRanges());
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId);
+ FillShapes(aPixelPaintRect, aMapMode, nRangeId);
+ }
+ }
+}
+
+sal_Int32 ScShapeChilds::GetBackShapeCount() const
+{
+ sal_Int32 nCount(0);
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
+ nCount += aItr->maBackShapes.size();
+ return nCount;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetBackShape(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while ((aItr != aEndItr) && !xAccessible.is())
+ {
+ sal_Int32 nCount(aItr->maBackShapes.size());
+ if(nIndex < nCount)
+ xAccessible = GetAccShape(aItr->maBackShapes, nIndex);
+ else
+ ++aItr;
+ nIndex -= nCount;
+ }
+
+ if (nIndex >= 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+sal_Int32 ScShapeChilds::GetForeShapeCount() const
+{
+ sal_Int32 nCount(0);
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
+ nCount += aItr->maForeShapes.size();
+ return nCount;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetForeShape(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while ((aItr != aEndItr) && !xAccessible.is())
+ {
+ sal_Int32 nCount(aItr->maForeShapes.size());
+ if(nIndex < nCount)
+ xAccessible = GetAccShape(aItr->maForeShapes, nIndex);
+ else
+ ++aItr;
+ nIndex -= nCount;
+ }
+
+ if (nIndex >= 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+sal_Int32 ScShapeChilds::GetControlCount() const
+{
+ sal_Int32 nCount(0);
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
+ nCount += aItr->maControls.size();
+ return nCount;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetControl(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while ((aItr != aEndItr) && !xAccessible.is())
+ {
+ sal_Int32 nCount(aItr->maControls.size());
+ if(nIndex < nCount)
+ xAccessible = GetAccShape(aItr->maControls, nIndex);
+ else
+ ++aItr;
+ nIndex -= nCount;
+ }
+
+ if (nIndex >= 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+struct ScShapePointFound
+{
+ Point maPoint;
+ ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {}
+ sal_Bool operator() (const ScShapeChild& rShape)
+ {
+ sal_Bool bResult(sal_False);
+ if ((VCLRectangle(rShape.mpAccShape->getBounds())).IsInside(maPoint))
+ bResult = sal_True;
+ return bResult;
+ }
+};
+
+uno::Reference<XAccessible> ScShapeChilds::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls
+{
+ uno::Reference<XAccessible> xAcc;
+
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ while((aItr != aEndItr) && !xAcc.is())
+ {
+ ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), ScShapePointFound(rPoint));
+ if (aFindItr != aItr->maForeShapes.end())
+ xAcc = GetAccShape(*aFindItr);
+ else
+ {
+ ScShapeChildVec::const_iterator aCtrlItr = std::find_if(aItr->maControls.begin(), aItr->maControls.end(), ScShapePointFound(rPoint));
+ if (aCtrlItr != aItr->maControls.end())
+ xAcc = GetAccShape(*aCtrlItr);
+ else
+ ++aItr;
+ }
+ }
+
+ return xAcc;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetBackgroundShapeAt(const awt::Point& rPoint) const
+{
+ uno::Reference<XAccessible> xAcc;
+
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ while((aItr != aEndItr) && !xAcc.is())
+ {
+ ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), ScShapePointFound(rPoint));
+ if (aFindItr != aItr->maBackShapes.end())
+ xAcc = GetAccShape(*aFindItr);
+ else
+ ++aItr;
+ }
+
+ return xAcc;
+}
+
+::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChild& rShape) const
+{
+ if (!rShape.mpAccShape)
+ {
+ ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
+ ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc, const_cast<ScShapeChilds*>(this));
+
+ if (mpViewShell)
+ {
+ ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo;
+ aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView());
+ aShapeTreeInfo.SetController(NULL);
+ aShapeTreeInfo.SetWindow(mpViewShell->GetWindow());
+ aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder));
+ rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo);
+ if (rShape.mpAccShape)
+ {
+ rShape.mpAccShape->acquire();
+ rShape.mpAccShape->Init();
+ }
+ }
+ }
+ return rShape.mpAccShape;
+}
+
+::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const
+{
+ return (GetAccShape(rShapes[nIndex]));
+}
+
+void ScShapeChilds::FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId)
+{
+ DBG_ASSERT(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects");
+ SdrPage* pPage = GetDrawPage();
+ Window* pWin = mpViewShell->GetWindow();
+ if (pPage && pWin)
+ {
+ sal_Bool bForeAdded(sal_False);
+ sal_Bool bBackAdded(sal_False);
+ sal_Bool bControlAdded(sal_False);
+ Rectangle aClippedPixelPaintRect(aPixelPaintRect);
+ if (mpAccDoc)
+ {
+ Rectangle aRect2(Point(0,0), mpAccDoc->GetBoundingBoxOnScreen().GetSize());
+ aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2);
+ }
+ maShapeRanges[nRangeId].maPixelRect = aClippedPixelPaintRect;
+ maShapeRanges[nRangeId].maMapMode = aMapMode;
+ ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode);
+ maShapeRanges[nRangeId].maViewForwarder = aViewForwarder;
+ sal_uInt32 nCount(pPage->GetObjCount());
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ SdrObject* pObj = pPage->GetObj(i);
+ if (pObj)
+ {
+ uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ Rectangle aRect(pWin->LogicToPixel(VCLPoint(xShape->getPosition()), aMapMode), pWin->LogicToPixel(VCLSize(xShape->getSize()), aMapMode));
+ if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty())
+ {
+ ScShapeChild aShape;
+ aShape.mxShape = xShape;
+ aShape.mnRangeId = nRangeId;
+ switch (pObj->GetLayer())
+ {
+ case SC_LAYER_INTERN:
+ case SC_LAYER_FRONT:
+ {
+ maShapeRanges[nRangeId].maForeShapes.push_back(aShape);
+ bForeAdded = sal_True;
+ }
+ break;
+ case SC_LAYER_BACK:
+ {
+ maShapeRanges[nRangeId].maBackShapes.push_back(aShape);
+ bBackAdded = sal_True;
+ }
+ break;
+ case SC_LAYER_CONTROLS:
+ {
+ maShapeRanges[nRangeId].maControls.push_back(aShape);
+ bControlAdded = sal_True;
+ }
+ break;
+ default:
+ {
+ DBG_ERRORFILE("I don't know this layer.");
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (bForeAdded)
+ std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess());
+ if (bBackAdded)
+ std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess());
+ if (bControlAdded)
+ std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess());
+ }
+}
+
+//UNUSED2008-05 sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_Bool bResult(sal_False);
+//UNUSED2008-05 ScShapeChild aShape;
+//UNUSED2008-05 aShape.mxShape = xShape;
+//UNUSED2008-05 rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess());
+//UNUSED2008-05 if (rItr->mxShape.get() == xShape.get())
+//UNUSED2008-05 bResult = sal_True; // if the shape is found
+//UNUSED2008-05
+//UNUSED2008-05 /*#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
+//UNUSED2008-05 ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape);
+//UNUSED2008-05 DBG_ASSERT(rItr == aDebugItr, "wrong Shape found");
+//UNUSED2008-05 #endif*/
+//UNUSED2008-05 return bResult;
+//UNUSED2008-05 }
+
+/*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
+{
+ uno::Reference < XAccessible > xNew;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ {
+ ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
+ sal_Bool bNotify(sal_False);
+ uno::Reference <XAccessible> xAcc;
+ while (aItr != aEndItr)
+ {
+ Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode));
+ Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize()));
+ if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty())
+ {
+ ScShapeChild aShape;
+ aShape.mxShape = xShape;
+ switch (aLayerID)
+ {
+ case SC_LAYER_INTERN:
+ case SC_LAYER_FRONT:
+ {
+ SetAnchor(aShape);
+ aItr->maForeShapes.push_back(aShape);
+ std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess());
+
+ }
+ break;
+ case SC_LAYER_BACK:
+ {
+ aItr->maBackShapes.push_back(aShape);
+ std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess());
+ }
+ break;
+ case SC_LAYER_CONTROLS:
+ {
+ SetAnchor(aShape);
+ aItr->maControls.push_back(aShape);
+ std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess());
+ }
+ break;
+ default:
+ {
+ DBG_ERRORFILE("I don't know this layer.");
+ }
+ break;
+ }
+ if (bNotify)
+ {
+ xAcc = GetAccShape(aShape);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ bNotify = sal_False;
+ }
+ xAcc = NULL;
+ }
+ ++aItr;
+ }
+ }
+}*/
+
+/*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr)
+{
+ sal_Bool bResult(sal_False);
+ if (aItr->mpAccShape)
+ {
+ bResult = sal_True;
+ xAcc = aItr->mpAccShape;
+ }
+ else
+ DBG_ERRORFILE("No Accessible object found. Don't know how to notify.");
+ return bResult;
+}*/
+
+/*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
+{
+ ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
+ ScShapeChildVec::iterator aEraseItr;
+ sal_Bool bNotify(sal_False);
+ uno::Reference <XAccessible> xAcc;
+ while (aItr != aEndItr)
+ {
+ switch (aLayerID)
+ {
+ case SC_LAYER_INTERN:
+ case SC_LAYER_FRONT:
+ {
+ if (FindShape(aItr->maForeShapes, xShape, aEraseItr))
+ {
+ bNotify = HaveToNotify(xAcc, aEraseItr);
+ aItr->maForeShapes.erase(aEraseItr);
+ }
+ }
+ break;
+ case SC_LAYER_BACK:
+ {
+ if (FindShape(aItr->maBackShapes, xShape, aEraseItr))
+ {
+ bNotify = HaveToNotify(xAcc, aEraseItr);
+ aItr->maBackShapes.erase(aEraseItr);
+ }
+ }
+ break;
+ case SC_LAYER_CONTROLS:
+ {
+ if (FindShape(aItr->maControls, xShape, aEraseItr))
+ {
+ bNotify = HaveToNotify(xAcc, aEraseItr);
+ aItr->maControls.erase(aEraseItr);
+ }
+ }
+ break;
+ default:
+ {
+ DBG_ERRORFILE("I don't know this layer.");
+ }
+ break;
+ }
+ if (bNotify)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ bNotify = sal_False;
+ }
+ xAcc = NULL;
+ ++aItr;
+ }
+}*/
+
+SdrPage* ScShapeChilds::GetDrawPage() const
+{
+ SCTAB nTab( mpViewShell->GetLocationData().GetPrintTab() );
+ SdrPage* pDrawPage = NULL;
+ if (mpViewShell)
+ {
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ if (pDoc && pDoc->GetDrawLayer())
+ {
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
+ pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
+ }
+ }
+ return pDrawPage;
+}
+
+struct ScPagePreviewCountData
+{
+ // order is background shapes, header, table or notes, footer, foreground shapes, controls
+
+ Rectangle aVisRect;
+ long nBackShapes;
+ long nHeaders;
+ long nTables;
+ long nNoteParagraphs;
+ long nFooters;
+ long nForeShapes;
+ long nControls;
+
+ ScPagePreviewCountData( const ScPreviewLocationData& rData, Window* pSizeWindow,
+ ScNotesChilds* pNotesChilds, ScShapeChilds* pShapeChilds );
+
+ long GetTotal() const
+ {
+ return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls;
+ }
+};
+
+ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData,
+ Window* pSizeWindow, ScNotesChilds* pNotesChilds,
+ ScShapeChilds* pShapeChilds) :
+ nBackShapes( 0 ),
+ nHeaders( 0 ),
+ nTables( 0 ),
+ nNoteParagraphs( 0 ),
+ nFooters( 0 ),
+ nForeShapes( 0 ),
+ nControls( 0 )
+{
+ Size aOutputSize;
+ if ( pSizeWindow )
+ aOutputSize = pSizeWindow->GetOutputSizePixel();
+ Point aPoint;
+ aVisRect = Rectangle( aPoint, aOutputSize );
+
+ Rectangle aObjRect;
+
+ if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
+ nHeaders = 1;
+
+ if ( rData.GetFooterPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
+ nFooters = 1;
+
+ if ( rData.HasCellsInRange( aVisRect ) )
+ nTables = 1;
+
+ //! shapes...
+ nBackShapes = pShapeChilds->GetBackShapeCount();
+ nForeShapes = pShapeChilds->GetForeShapeCount();
+ nControls = pShapeChilds->GetControlCount();
+
+ // there are only notes if there is no table
+ if (nTables == 0)
+ nNoteParagraphs = pNotesChilds->GetChildsCount();
+}
+
+//===== internal ========================================================
+
+ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
+ const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) :
+ ScAccessibleDocumentBase(rxParent),
+ mpViewShell(pViewShell),
+ mpNotesChilds(NULL),
+ mpShapeChilds(NULL),
+ mpTable(NULL),
+ mpHeader(NULL),
+ mpFooter(NULL)
+{
+ if (pViewShell)
+ pViewShell->AddAccessibilityObject(*this);
+
+// GetNotesChilds(); not neccessary and reduces the creation performance
+// GetShapeChilds();
+}
+
+ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void)
+{
+ if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessibleDocumentPagePreview::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpTable)
+ {
+ mpTable->release();
+ mpTable = NULL;
+ }
+ if (mpHeader)
+ {
+ mpHeader->release();
+ mpHeader = NULL;
+ }
+ if (mpFooter)
+ {
+ mpFooter->release();
+ mpFooter = NULL;
+ }
+
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ // #100593# no need to Dispose the AccessibleTextHelper,
+ // as long as mpNotesChilds are destructed here
+ if (mpNotesChilds)
+ DELETEZ(mpNotesChilds);
+
+ if (mpShapeChilds)
+ DELETEZ(mpShapeChilds);
+
+ ScAccessibleDocumentBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_DATACHANGED))
+ {
+ if (mpTable) // if there is no table there is nothing to notify, because no one recongnizes the change
+ {
+ {
+ uno::Reference<XAccessible> xAcc = mpTable;
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= xAcc;
+ CommitChange(aEvent);
+ }
+
+ mpTable->dispose();
+ mpTable->release();
+ mpTable = NULL;
+ }
+
+ Size aOutputSize;
+ Window* pSizeWindow = mpViewShell->GetWindow();
+ if ( pSizeWindow )
+ aOutputSize = pSizeWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ GetNotesChilds()->DataChanged(aVisRect);
+
+ GetShapeChilds()->DataChanged();
+
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ if (aCount.nTables > 0)
+ {
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+
+ {
+ uno::Reference<XAccessible> xAcc = mpTable;
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= xAcc;
+ CommitChange(aEvent);
+ }
+ }
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
+ {
+ GetShapeChilds()->SetDrawBroadcaster();
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ Size aOutputSize;
+ Window* pSizeWindow = mpViewShell->GetWindow();
+ if ( pSizeWindow )
+ aOutputSize = pSizeWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ GetNotesChilds()->DataChanged(aVisRect);
+
+ GetShapeChilds()->VisAreaChanged();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+ else if ( rHint.ISA(ScAccWinFocusLostHint) )
+ {
+ CommitFocusLost();
+ }
+ else if ( rHint.ISA(ScAccWinFocusGotHint) )
+ {
+ CommitFocusGained();
+ }
+ ScAccessibleDocumentBase::Notify(rBC, rHint);
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xAccessible;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ( mpViewShell )
+ {
+ xAccessible = GetShapeChilds()->GetForegroundShapeAt(rPoint);
+ if (!xAccessible.is())
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+/* if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) )
+ {
+ if ( !mpTable && (aCount.nTables > 0) )
+ {
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+ }
+ xAccessible = mpTable;
+ }*/
+ if ( !mpTable && (aCount.nTables > 0) )
+ {
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+ }
+ if (mpTable && VCLRectangle(mpTable->getBounds()).IsInside(VCLPoint(rPoint)))
+ xAccessible = mpTable;
+ }
+ if (!xAccessible.is())
+ xAccessible = GetNotesChilds()->GetAt(rPoint);
+ if (!xAccessible.is())
+ {
+ if (!mpHeader || !mpFooter)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ if (!mpHeader)
+ {
+ mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, aCount.nBackShapes + aCount.nHeaders - 1);
+ mpHeader->acquire();
+ }
+ if (!mpFooter)
+ {
+ mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 );
+ mpFooter->acquire();
+ }
+ }
+
+ Point aPoint(VCLPoint(rPoint));
+
+ if (VCLRectangle(mpHeader->getBounds()).IsInside(aPoint))
+ xAccessible = mpHeader;
+ else if (VCLRectangle(mpFooter->getBounds()).IsInside(aPoint))
+ xAccessible = mpFooter;
+ }
+ if (!xAccessible.is())
+ xAccessible = GetShapeChilds()->GetBackgroundShapeAt(rPoint);
+ }
+ }
+
+ return xAccessible;
+}
+
+void SAL_CALL ScAccessibleDocumentPagePreview::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ {
+ // just grab the focus for the window
+ xAccessibleComponent->grabFocus();
+ }
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChildCount(void) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ long nRet = 0;
+ if ( mpViewShell )
+ {
+ ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+ nRet = aCount.GetTotal();
+ }
+
+ return nRet;
+}
+
+uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAccessible;
+
+ if ( mpViewShell )
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ if ( nIndex < aCount.nBackShapes )
+ {
+ xAccessible = GetShapeChilds()->GetBackShape(nIndex);
+ }
+ else if ( nIndex < aCount.nBackShapes + aCount.nHeaders )
+ {
+ if ( !mpHeader )
+ {
+ mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, nIndex );
+ mpHeader->acquire();
+ }
+
+ xAccessible = mpHeader;
+ }
+ else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables )
+ {
+ if ( !mpTable )
+ {
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+ }
+ xAccessible = mpTable;
+ }
+ else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs )
+ {
+ xAccessible = GetNotesChilds()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders);
+ }
+ else if ( (nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters) )
+ {
+ if ( !mpFooter )
+ {
+ mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, nIndex );
+ mpFooter->acquire();
+ }
+ xAccessible = mpFooter;
+ }
+ else
+ {
+ sal_Int32 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters));
+ if (nIdx < aCount.nForeShapes)
+ xAccessible = GetShapeChilds()->GetForeShape(nIdx);
+ else
+ xAccessible = GetShapeChilds()->GetControl(nIdx - aCount.nForeShapes);
+ }
+ }
+
+ if ( !xAccessible.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+ /// Return the set of current states.
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ // never editable
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL ScAccessibleDocumentPagePreview::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleDocumentPagePreview::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//===== internal ========================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_PREVIEWDOC_DESCR));
+ return sDescription;
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sName = String(ScResId(STR_ACC_PREVIEWDOC_NAME));
+ return sName;
+}
+
+Rectangle ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(NULL);
+ }
+ return aRect;
+}
+
+Rectangle ScAccessibleDocumentPagePreview::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
+ }
+ return aRect;
+}
+
+sal_Bool ScAccessibleDocumentPagePreview::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+ScNotesChilds* ScAccessibleDocumentPagePreview::GetNotesChilds()
+{
+ if (!mpNotesChilds && mpViewShell)
+ {
+ mpNotesChilds = new ScNotesChilds(mpViewShell, this);
+
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ mpNotesChilds->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders);
+ }
+ return mpNotesChilds;
+}
+
+ScShapeChilds* ScAccessibleDocumentPagePreview::GetShapeChilds()
+{
+ if (!mpShapeChilds && mpViewShell)
+ {
+ mpShapeChilds = new ScShapeChilds(mpViewShell, this);
+ mpShapeChilds->Init();
+ }
+
+ return mpShapeChilds;
+}
+
+//UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable()
+//UNUSED2009-05 {
+//UNUSED2009-05 if (!mpTable)
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( mpViewShell )
+//UNUSED2009-05 {
+//UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+//UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+//UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+//UNUSED2009-05 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+//UNUSED2009-05
+//UNUSED2009-05 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+//UNUSED2009-05 mpTable->acquire();
+//UNUSED2009-05 mpTable->Init();
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 return mpTable;
+//UNUSED2009-05 }
+
+//UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged()
+//UNUSED2009-05 {
+//UNUSED2009-05 if (mpViewShell)
+//UNUSED2009-05 {
+//UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+//UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+//UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+//UNUSED2009-05 if(mpHeader)
+//UNUSED2009-05 mpHeader->SetCurrentIndexInParent(aCount.nBackShapes);
+//UNUSED2009-05 if (mpTable)
+//UNUSED2009-05 mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders);
+//UNUSED2009-05 if (mpFooter)
+//UNUSED2009-05 mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs);
+//UNUSED2009-05
+//UNUSED2009-05 if (mpNotesChilds)
+//UNUSED2009-05 mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders);
+//UNUSED2009-05 }
+//UNUSED2009-05 }
diff --git a/sc/source/ui/Accessibility/AccessibleEditObject.cxx b/sc/source/ui/Accessibility/AccessibleEditObject.cxx
new file mode 100644
index 000000000000..fd7cbaf454c1
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleEditObject.cxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleEditObject.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include "unoguard.hxx"
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+#include <svx/svdmodel.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleEditObject::ScAccessibleEditObject(
+ const uno::Reference<XAccessible>& rxParent,
+ EditView* pEditView, Window* pWin, const rtl::OUString& rName,
+ const rtl::OUString& rDescription, EditObjectType eObjectType)
+ :
+ ScAccessibleContextBase(rxParent, AccessibleRole::TEXT_FRAME),
+ mpTextHelper(NULL),
+ mpEditView(pEditView),
+ mpWindow(pWin),
+ meObjectType(eObjectType),
+ mbHasFocus(sal_False)
+{
+ CreateTextHelper();
+ SetName(rName);
+ SetDescription(rDescription);
+}
+
+ScAccessibleEditObject::~ScAccessibleEditObject()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessibleEditObject::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpTextHelper)
+ DELETEZ(mpTextHelper);
+
+ ScAccessibleContextBase::disposing();
+}
+
+void ScAccessibleEditObject::LostFocus()
+{
+ mbHasFocus = sal_False;
+ if (mpTextHelper)
+ mpTextHelper->SetFocus(sal_False);
+ CommitFocusLost();
+}
+
+void ScAccessibleEditObject::GotFocus()
+{
+ mbHasFocus = sal_True;
+ CommitFocusGained();
+ if (mpTextHelper)
+ mpTextHelper->SetFocus(sal_True);
+}
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+Rectangle ScAccessibleEditObject::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aScreenBounds;
+
+ if ( mpWindow )
+ {
+ if ( meObjectType == CellInEditMode )
+ {
+ if ( mpEditView && mpEditView->GetEditEngine() )
+ {
+ MapMode aMapMode( mpEditView->GetEditEngine()->GetRefMapMode() );
+ aScreenBounds = mpWindow->LogicToPixel( mpEditView->GetOutputArea(), aMapMode );
+ Point aCellLoc = aScreenBounds.TopLeft();
+ Rectangle aWindowRect = mpWindow->GetWindowExtentsRelative( NULL );
+ Point aWindowLoc = aWindowRect.TopLeft();
+ Point aPos( aCellLoc.getX() + aWindowLoc.getX(), aCellLoc.getY() + aWindowLoc.getY() );
+ aScreenBounds.SetPos( aPos );
+ }
+ }
+ else
+ {
+ aScreenBounds = mpWindow->GetWindowExtentsRelative( NULL );
+ }
+ }
+
+ return aScreenBounds;
+}
+
+Rectangle ScAccessibleEditObject::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aBounds( GetBoundingBoxOnScreen() );
+
+ if ( mpWindow )
+ {
+ uno::Reference< XAccessible > xThis( mpWindow->GetAccessible() );
+ if ( xThis.is() )
+ {
+ uno::Reference< XAccessibleContext > xContext( xThis->getAccessibleContext() );
+ if ( xContext.is() )
+ {
+ uno::Reference< XAccessible > xParent( xContext->getAccessibleParent() );
+ if ( xParent.is() )
+ {
+ uno::Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY );
+ if ( xParentComponent.is() )
+ {
+ Point aScreenLoc = aBounds.TopLeft();
+ awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen();
+ Point aPos( aScreenLoc.getX() - aParentScreenLoc.X, aScreenLoc.getY() - aParentScreenLoc.Y );
+ aBounds.SetPos( aPos );
+ }
+ }
+ }
+ }
+ }
+
+ return aBounds;
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleEditObject::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessibleEditObject::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleEditObject::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ // all states are const, because this object exists only in one state
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::SENSITIVE);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleEditObject::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+// DBG_ERRORFILE("Should never be called, because is set in the constructor.")
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleEditObject::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERRORFILE("Should never be called, because is set in the constructor.");
+ return rtl::OUString();
+}
+
+ ///===== XAccessibleEventBroadcaster =====================================
+
+void SAL_CALL
+ ScAccessibleEditObject::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (!mpTextHelper)
+ CreateTextHelper();
+
+ mpTextHelper->AddEventListener(xListener);
+
+ ScAccessibleContextBase::addEventListener(xListener);
+}
+
+void SAL_CALL
+ ScAccessibleEditObject::removeEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (!mpTextHelper)
+ CreateTextHelper();
+
+ mpTextHelper->RemoveEventListener(xListener);
+
+ ScAccessibleContextBase::removeEventListener(xListener);
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleEditObject::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleEditObject"));
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleEditObject::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+ //==== internal =========================================================
+
+sal_Bool ScAccessibleEditObject::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessibleEditObject::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData;
+ if (meObjectType == CellInEditMode || meObjectType == EditControl)
+ {
+ pAccessibleTextData.reset
+ (new ScAccessibleEditObjectTextData(mpEditView, mpWindow));
+ }
+ else
+ {
+ pAccessibleTextData.reset
+ (new ScAccessibleEditLineTextData(NULL, mpWindow));
+ }
+
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));
+ mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
+ mpTextHelper->SetEventSource(this);
+ mpTextHelper->SetFocus(mbHasFocus);
+
+ // #i54814# activate cell in edit mode
+ if( meObjectType == CellInEditMode )
+ {
+ // do not activate cell object, if top edit line is active
+ const ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if( pInputHdl && !pInputHdl->IsTopMode() )
+ {
+ SdrHint aHint( HINT_BEGEDIT );
+ mpTextHelper->GetEditSource().GetBroadcaster().Broadcast( aHint );
+ }
+ }
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
new file mode 100644
index 000000000000..02fb5c12463e
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
@@ -0,0 +1,398 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleGlobal.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "AccessibleFilterMenuItem.hxx"
+#include "unoguard.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+
+#include "tools/gen.hxx"
+#include "editeng/unoedsrc.hxx"
+#include "editeng/editdata.hxx"
+#include "editeng/outliner.hxx"
+#include "vcl/unohelp.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleStateType;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+using ::std::for_each;
+using ::std::vector;
+
+// ============================================================================
+
+namespace {
+
+class AddRemoveEventListener : public ::std::unary_function<void, Reference<XAccessible> >
+{
+public:
+ explicit AddRemoveEventListener(const Reference<XAccessibleEventListener>& rListener, bool bAdd) :
+ mxListener(rListener), mbAdd(bAdd) {}
+
+ void operator() (const Reference<XAccessible>& xAccessible) const
+ {
+ if (!xAccessible.is())
+ return;
+
+ Reference<XAccessibleEventBroadcaster> xBc(xAccessible, UNO_QUERY);
+ if (xBc.is())
+ {
+ if (mbAdd)
+ xBc->addEventListener(mxListener);
+ else
+ xBc->removeEventListener(mxListener);
+ }
+ }
+private:
+ Reference<XAccessibleEventListener> mxListener;
+ bool mbAdd;
+};
+
+}
+
+// ============================================================================
+
+ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos, ScDocument* pDoc) :
+ ScAccessibleContextBase(rxParent, AccessibleRole::MENU),
+ mnMenuPos(nMenuPos),
+ mpWindow(pWin),
+ mpDoc(pDoc),
+ mbEnabled(true)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterMenu::~ScAccessibleFilterMenu()
+{
+}
+
+// XAccessibleComponent
+
+Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& /*rPoint*/ )
+ throw (RuntimeException)
+{
+ return this;
+}
+
+sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException)
+{
+ return mpWindow->IsVisible();
+}
+
+void ScAccessibleFilterMenu::grabFocus()
+ throw (RuntimeException)
+{
+}
+
+sal_Int32 ScAccessibleFilterMenu::getForeground()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+sal_Int32 ScAccessibleFilterMenu::getBackground()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+// XAccessibleContext
+
+OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException)
+{
+ return ScAccessibleContextBase::getAccessibleName();
+}
+
+sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ return getMenuItemCount();
+}
+
+Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex)
+ throw (RuntimeException, IndexOutOfBoundsException)
+{
+ if (maMenuItems.size() <= static_cast<size_t>(nIndex))
+ throw IndexOutOfBoundsException();
+
+ return maMenuItems[nIndex];
+}
+
+Reference<XAccessibleStateSet> ScAccessibleFilterMenu::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ updateStates();
+ return mxStateSet;
+}
+
+OUString ScAccessibleFilterMenu::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterMenu");
+}
+
+// XAccessibleEventBroadcaster
+
+void ScAccessibleFilterMenu::addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ ScAccessibleContextBase::addEventListener(xListener);
+ for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true));
+}
+
+void ScAccessibleFilterMenu::removeEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ ScAccessibleContextBase::removeEventListener(xListener);
+ for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false));
+}
+
+// XAccessibleSelection
+
+void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ mpWindow->setSelectedMenuItem(nChildIndex, false, true);
+}
+
+sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ return mpWindow->isMenuItemSelected(static_cast<size_t>(nChildIndex));
+}
+
+void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException)
+{
+ mpWindow->clearSelectedMenuItem();
+}
+
+void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException)
+{
+ // not suported - this is a menu, you can't select all menu items.
+}
+
+sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException)
+{
+ // Since this is a menu, either one menu item is selected, or none at all.
+ return mpWindow->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED ? 0 : 1;
+}
+
+Reference<XAccessible> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ return maMenuItems[nChildIndex];
+}
+
+void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ mpWindow->selectMenuItem(nChildIndex, false, false);
+}
+
+// XInterface
+
+uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType )
+ throw (RuntimeException)
+{
+ Any any = ScAccessibleContextBase::queryInterface(rType);
+ if (any.hasValue())
+ return any;
+
+ return ScAccessibleFilterMenu_BASE::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleFilterMenu::acquire() throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleFilterMenu::release() throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+// XTypeProvider
+
+Sequence<sal_Int8> ScAccessibleFilterMenu::getImplementationId()
+ throw (RuntimeException)
+{
+ Sequence<sal_Int8> aId(16);
+ return aId;
+}
+
+Rectangle ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const
+ throw (RuntimeException)
+{
+ if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
+ return Rectangle();
+
+ // Menu object's bounding box is the bounding box of the menu item that
+ // launches the menu, which belongs to the parent window.
+ ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
+ if (!pParentWin)
+ return Rectangle();
+
+ if (!pParentWin->IsVisible())
+ return Rectangle();
+
+ Point aPos = pParentWin->OutputToAbsoluteScreenPixel(Point(0,0));
+ Point aMenuPos;
+ Size aMenuSize;
+ pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aPos + aMenuPos, aMenuSize);
+ return aRect;
+}
+
+Rectangle ScAccessibleFilterMenu::GetBoundingBox() const
+ throw (RuntimeException)
+{
+ if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
+ return Rectangle();
+
+ // Menu object's bounding box is the bounding box of the menu item that
+ // launches the menu, which belongs to the parent window.
+ ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
+ if (!pParentWin)
+ return Rectangle();
+
+ if (!pParentWin->IsVisible())
+ return Rectangle();
+
+ Point aMenuPos;
+ Size aMenuSize;
+ pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aMenuPos, aMenuSize);
+ return aRect;
+}
+
+void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos)
+{
+ // Check weather this menu item is a sub menu or a regular menu item.
+ ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos);
+ Reference<XAccessible> xAccessible;
+ if (pSubMenu)
+ {
+ xAccessible = pSubMenu->CreateAccessible();
+ ScAccessibleFilterMenu* p =
+ static_cast<ScAccessibleFilterMenu*>(xAccessible.get());
+ p->setEnabled(bEnabled);
+ p->setMenuPos(nMenuPos);
+ }
+ else
+ {
+ xAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos));
+ ScAccessibleFilterMenuItem* p =
+ static_cast<ScAccessibleFilterMenuItem*>(xAccessible.get());
+ p->setEnabled(bEnabled);
+ }
+ maMenuItems.push_back(xAccessible);
+}
+
+void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos)
+{
+ mnMenuPos = nMenuPos;
+}
+
+void ScAccessibleFilterMenu::setEnabled(bool bEnabled)
+{
+ mbEnabled = bEnabled;
+}
+
+sal_Int32 ScAccessibleFilterMenu::getMenuItemCount() const
+{
+ return maMenuItems.size();
+}
+
+bool ScAccessibleFilterMenu::isSelected() const
+{
+ // Check to see if any of the child menu items is selected.
+ return mpWindow->isMenuItemSelected(mnMenuPos);
+}
+
+bool ScAccessibleFilterMenu::isFocused() const
+{
+ return isSelected();
+}
+
+void ScAccessibleFilterMenu::updateStates()
+{
+ if (!mxStateSet.is())
+ mxStateSet.set(new ScAccessibleStateSet);
+
+ ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
+ mxStateSet.get());
+
+ p->clear();
+
+ p->insert(ENABLED);
+ p->insert(FOCUSABLE);
+ p->insert(SELECTABLE);
+ p->insert(SENSITIVE);
+ p->insert(OPAQUE);
+
+ if (isFocused())
+ p->insert(FOCUSED);
+
+ if (isSelected())
+ p->insert(SELECTED);
+}
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
new file mode 100644
index 000000000000..0da1e6858a75
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+#include "AccessibleFilterMenuItem.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/TextSegment.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleStateType;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+
+ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem(
+ const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) :
+ ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM),
+ mpWindow(pWin),
+ maName(rName),
+ mnMenuPos(nMenuPos),
+ mbEnabled(true)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem()
+{
+}
+
+sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+Reference<XAccessible> ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 /*nIndex*/)
+ throw (RuntimeException, IndexOutOfBoundsException)
+{
+ throw IndexOutOfBoundsException();
+}
+
+Reference<XAccessibleStateSet> ScAccessibleFilterMenuItem::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ updateStateSet();
+ return mxStateSet;
+}
+
+OUString ScAccessibleFilterMenuItem::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterMenuItem");
+}
+
+// XAccessibleAction
+
+sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException)
+{
+ return 1;
+}
+
+sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ mpWindow->executeMenuItem(mnMenuPos);
+ return true;
+}
+
+OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return OUString::createFromAscii("click");
+}
+
+Reference<XAccessibleKeyBinding> ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding(
+ sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return Reference<XAccessibleKeyBinding>();
+}
+
+Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType )
+ throw (RuntimeException)
+{
+ Any any = ScAccessibleContextBase::queryInterface(rType);
+ if (any.hasValue())
+ return any;
+
+ return ScAccessibleFilterMenuItem_BASE::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleFilterMenuItem::release() throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+bool ScAccessibleFilterMenuItem::isSelected() const
+{
+ return mpWindow->isMenuItemSelected(mnMenuPos);
+}
+
+bool ScAccessibleFilterMenuItem::isFocused() const
+{
+ return isSelected();
+}
+
+void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled)
+{
+ mbEnabled = bEnabled;
+}
+
+Rectangle ScAccessibleFilterMenuItem::GetBoundingBoxOnScreen() const
+ throw (RuntimeException)
+{
+ if (!mpWindow->IsVisible())
+ return Rectangle();
+
+ Point aPos = mpWindow->OutputToAbsoluteScreenPixel(Point(0,0));
+ Point aMenuPos;
+ Size aMenuSize;
+ mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aPos + aMenuPos, aMenuSize);
+ return aRect;
+}
+
+Rectangle ScAccessibleFilterMenuItem::GetBoundingBox() const
+ throw (RuntimeException)
+{
+ if (!mpWindow->IsVisible())
+ return Rectangle();
+
+ Point aMenuPos;
+ Size aMenuSize;
+ mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aMenuPos, aMenuSize);
+ return aRect;
+}
+
+void ScAccessibleFilterMenuItem::updateStateSet()
+{
+ if (!mxStateSet.is())
+ mxStateSet.set(new ScAccessibleStateSet);
+
+ ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
+ mxStateSet.get());
+
+ p->clear();
+
+ p->insert(ENABLED);
+ p->insert(FOCUSABLE);
+ p->insert(SELECTABLE);
+ p->insert(SENSITIVE);
+ p->insert(OPAQUE);
+
+ if (isFocused())
+ p->insert(FOCUSED);
+
+ if (isSelected())
+ p->insert(SELECTED);
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
new file mode 100644
index 000000000000..2af69faa33c8
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleFilterTopWindow.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+
+ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow(
+ const Reference<XAccessible>& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) :
+ ScAccessibleFilterMenu(rxParent, pWin, rName, ScMenuFloatingWindow::MENU_NOT_SELECTED, pDoc),
+ mpWindow(pWin),
+ mpDoc(pDoc)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow()
+{
+}
+
+// XAccessibleContext
+
+sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException)
+{
+ sal_Int32 nMenuCount = getMenuItemCount();
+ return nMenuCount + 6;
+}
+
+Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChild(
+ sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException)
+{
+ if (nIndex >= getAccessibleChildCount())
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nMenuCount = getMenuItemCount();
+ if (nIndex < nMenuCount)
+ return ScAccessibleFilterMenu::getAccessibleChild(nIndex);
+
+ nIndex -= nMenuCount;
+ switch (nIndex)
+ {
+ case 0:
+ return mxAccListBox;
+ case 1:
+ return mxAccToggleAll;
+ case 2:
+ return mxAccSingleOnBtn;
+ case 3:
+ return mxAccSingleOffBtn;
+ case 4:
+ return mxAccOkBtn;
+ case 5:
+ return mxAccCancelBtn;
+ default:
+ ;
+ }
+
+ return Reference<XAccessible>();
+}
+
+OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterTopWindow");
+}
+
+void ScAccessibleFilterTopWindow::setAccessibleChild(
+ const Reference<XAccessible>& rAccessible, ChildControlType eType)
+{
+ switch (eType)
+ {
+ case LISTBOX:
+ mxAccListBox = rAccessible;
+ break;
+ case TOGGLE_ALL:
+ mxAccToggleAll = rAccessible;
+ break;
+ case SINGLE_ON_BTN:
+ mxAccSingleOnBtn = rAccessible;
+ break;
+ case SINGLE_OFF_BTN:
+ mxAccSingleOffBtn = rAccessible;
+ break;
+ case OK_BTN:
+ mxAccOkBtn = rAccessible;
+ break;
+ case CANCEL_BTN:
+ mxAccCancelBtn = rAccessible;
+ break;
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleGlobal.cxx b/sc/source/ui/Accessibility/AccessibleGlobal.cxx
new file mode 100644
index 000000000000..ac2562fa9bd5
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleGlobal.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::std::set;
+
+ScAccessibleStateSet::ScAccessibleStateSet()
+{
+}
+
+ScAccessibleStateSet::~ScAccessibleStateSet()
+{
+}
+
+// XAccessibleStateSet
+
+sal_Bool SAL_CALL ScAccessibleStateSet::isEmpty() throw (RuntimeException)
+{
+ return maStates.empty();
+}
+
+sal_Bool SAL_CALL ScAccessibleStateSet::contains(sal_Int16 nState)
+ throw (RuntimeException)
+{
+ return maStates.count(nState) != 0;
+}
+
+sal_Bool SAL_CALL ScAccessibleStateSet::containsAll(
+ const Sequence<sal_Int16>& aStateSet) throw (RuntimeException)
+{
+ sal_Int32 n = aStateSet.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ if (!maStates.count(aStateSet[i]))
+ // This state is not set.
+ return false;
+ }
+ // All specified states are set.
+ return true;
+}
+
+Sequence<sal_Int16> SAL_CALL ScAccessibleStateSet::getStates()
+ throw (RuntimeException)
+{
+ Sequence<sal_Int16> aSeq(0);
+ set<sal_Int16>::const_iterator itr = maStates.begin(), itrEnd = maStates.end();
+ for (size_t i = 0; itr != itrEnd; ++itr, ++i)
+ {
+ aSeq.realloc(i+1);
+ aSeq[i] = *itr;
+ }
+ return aSeq;
+}
+
+void ScAccessibleStateSet::insert(sal_Int16 nState)
+{
+ maStates.insert(nState);
+}
+
+void ScAccessibleStateSet::clear()
+{
+ maStates.clear();
+}
+
diff --git a/sc/source/ui/Accessibility/AccessiblePageHeader.cxx b/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
new file mode 100644
index 000000000000..6c28d22b0236
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
@@ -0,0 +1,441 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessiblePageHeader.hxx"
+#include "AccessiblePageHeaderArea.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "prevloc.hxx"
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+#include <vcl/window.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <svl/style.hxx>
+#include <svl/itempool.hxx>
+#include <editeng/editobj.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+const sal_uInt8 MAX_AREAS = 3;
+
+//===== internal ============================================================
+struct Acquire
+{
+ void operator() (ScAccessiblePageHeaderArea* pArea)
+ {
+ if (pArea)
+ pArea->acquire();
+ }
+};
+
+struct Release
+{
+ void operator() (ScAccessiblePageHeaderArea*& pArea)
+ {
+ if (pArea)
+ pArea->release();
+ }
+};
+
+struct Dispose
+{
+ void operator() (ScAccessiblePageHeaderArea*& pArea)
+ {
+ if (pArea)
+ {
+ pArea->dispose();
+ pArea->release();
+ }
+ pArea = NULL;
+ }
+};
+
+ScAccessiblePageHeader::ScAccessiblePageHeader( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, sal_Bool bHeader, sal_Int32 nIndex ) :
+ScAccessibleContextBase( rxParent, bHeader ? AccessibleRole::HEADER : AccessibleRole::FOOTER ),
+ mpViewShell( pViewShell ),
+ mnIndex( nIndex ),
+ mbHeader( bHeader ),
+ maAreas(MAX_AREAS, NULL),
+ mnChildCount(-1)
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePageHeader::~ScAccessiblePageHeader()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePageHeader::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ std::for_each(maAreas.begin(), maAreas.end(), Dispose());
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePageHeader::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_DATACHANGED))
+ {
+ ScHFAreas aOldAreas(maAreas);
+ std::for_each(aOldAreas.begin(), aOldAreas.end(), Acquire());
+ mnChildCount = -1;
+ getAccessibleChildCount();
+ for (sal_uInt8 i = 0; i < MAX_AREAS; ++i)
+ {
+ if ((aOldAreas[i] && maAreas[i] && !ScGlobal::EETextObjEqual(aOldAreas[i]->GetEditTextObject(), maAreas[i]->GetEditTextObject())) ||
+ (aOldAreas[i] && !maAreas[i]) || (!aOldAreas[i] && maAreas[i]))
+ {
+ if (aOldAreas[i] && aOldAreas[i]->GetEditTextObject())
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue = uno::makeAny(uno::Reference<XAccessible>(aOldAreas[i]));
+
+ CommitChange(aEvent); // child gone - event
+ aOldAreas[i]->dispose();
+ }
+ if (maAreas[i] && maAreas[i]->GetEditTextObject())
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue = uno::makeAny(uno::Reference<XAccessible>(maAreas[i]));
+
+ CommitChange(aEvent); // new child - event
+ }
+ }
+ }
+ std::for_each(aOldAreas.begin(), aOldAreas.end(), Release());
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleAtPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+
+ if (containsPoint(aPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ sal_Int32 nCount(getAccessibleChildCount()); // fill the areas
+
+ if (nCount)
+ {
+ // return the first with content, because they have all the same Bounding Box
+ sal_uInt8 i(0);
+ while(!xRet.is() && i < MAX_AREAS)
+ {
+ if (maAreas[i])
+ xRet = maAreas[i];
+ else
+ ++i;
+ }
+ }
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePageHeader::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleChildCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if((mnChildCount < 0) && mpViewShell)
+ {
+ mnChildCount = 0;
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ if (pDoc)
+ {
+ // find out how many regions (left,center, right) are with content
+
+ SfxStyleSheetBase* pStyle = pDoc->GetStyleSheetPool()->Find(pDoc->GetPageStyle(mpViewShell->GetLocationData().GetPrintTab()), SFX_STYLE_FAMILY_PAGE);
+ if (pStyle)
+ {
+ sal_uInt16 nPageWhichId(0);
+ if (mbHeader)
+ nPageWhichId = mpViewShell->GetLocationData().IsHeaderLeft() ? ATTR_PAGE_HEADERLEFT : ATTR_PAGE_HEADERRIGHT;
+ else
+ nPageWhichId = mpViewShell->GetLocationData().IsFooterLeft() ? ATTR_PAGE_FOOTERLEFT : ATTR_PAGE_FOOTERRIGHT;
+
+ const ScPageHFItem& rPageItem = static_cast<const ScPageHFItem&>(pStyle->GetItemSet().Get(nPageWhichId));
+ AddChild(rPageItem.GetLeftArea(), 0, SVX_ADJUST_LEFT);
+ AddChild(rPageItem.GetCenterArea(), 1, SVX_ADJUST_CENTER);
+ AddChild(rPageItem.GetRightArea(), 2, SVX_ADJUST_RIGHT);
+ }
+ }
+ }
+
+ return mnChildCount;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleChild( sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ uno::Reference<XAccessible> xRet;
+
+ if(mnChildCount < 0)
+ getAccessibleChildCount();
+
+ ScHFAreas::iterator aItr = maAreas.begin();
+ ScHFAreas::iterator aEndItr = maAreas.end();
+ while (!xRet.is() && (nIndex >= 0) && (aItr != aEndItr))
+ {
+ if (*aItr)
+ {
+ if (nIndex == 0)
+ xRet = *aItr;
+ else
+ --nIndex;
+ }
+ else
+ ++aItr;
+ }
+
+ if ( !xRet.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleIndexInParent() throw (uno::RuntimeException)
+{
+ return mnIndex;
+}
+
+uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePageHeader::getAccessibleStateSet()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePageHeader::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePageHeader"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePageHeader::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleHeaderFooterView"));
+
+ return aSequence;
+}
+
+//==== internal =========================================================
+
+::rtl::OUString SAL_CALL ScAccessiblePageHeader::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ String sDesc(ScResId(mbHeader ? STR_ACC_HEADER_DESCR : STR_ACC_FOOTER_DESCR));
+ sDesc.SearchAndReplaceAscii("%1", String(ScResId(SCSTR_UNKNOWN)));
+ return rtl::OUString( sDesc );
+}
+
+::rtl::OUString SAL_CALL ScAccessiblePageHeader::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName(ScResId(mbHeader ? STR_ACC_HEADER_NAME : STR_ACC_FOOTER_NAME));
+ sName.SearchAndReplaceAscii("%1", String(ScResId(SCSTR_UNKNOWN)));
+ return rtl::OUString( sName );
+}
+
+Rectangle ScAccessiblePageHeader::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect(GetBoundingBox());
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePageHeader::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ if ( mbHeader )
+ rData.GetHeaderPosition( aRect );
+ else
+ rData.GetFooterPosition( aRect );
+
+ // the Rectangle could contain negative coordinates so it should be cliped
+ Rectangle aClipRect(Point(0, 0), aRect.GetSize());
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ aClipRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
+ aRect = aClipRect.GetIntersection(aRect);
+ }
+ if (aRect.IsEmpty())
+ aRect.SetSize(Size(-1, -1));
+
+ return aRect;
+}
+
+sal_Bool ScAccessiblePageHeader::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessiblePageHeader::AddChild(const EditTextObject* pArea, sal_uInt32 nIndex, SvxAdjust eAdjust)
+{
+ if (pArea && (pArea->GetText(0).Len() || (pArea->GetParagraphCount() > 1)))
+ {
+ if (maAreas[nIndex])
+ {
+ if (!ScGlobal::EETextObjEqual(maAreas[nIndex]->GetEditTextObject(), pArea))
+ {
+ maAreas[nIndex]->release();
+ maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
+ maAreas[nIndex]->acquire();
+ }
+ }
+ else
+ {
+ maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
+ maAreas[nIndex]->acquire();
+ }
+ ++mnChildCount;
+ }
+ else
+ {
+ if (maAreas[nIndex])
+ {
+ maAreas[nIndex]->release();
+ maAreas[nIndex] = NULL;
+ }
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx b/sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx
new file mode 100644
index 000000000000..10c6a9eff13f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx
@@ -0,0 +1,330 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <tools/gen.hxx>
+#include "AccessiblePageHeaderArea.hxx"
+#include "AccessibleText.hxx"
+#include "AccessibilityHints.hxx"
+#include "unoguard.hxx"
+#include "editsrc.hxx"
+#include "prevwsh.hxx"
+#include "prevloc.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <editeng/editobj.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <rtl/uuid.h>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+ //===== internal ========================================================
+
+ScAccessiblePageHeaderArea::ScAccessiblePageHeaderArea(
+ const uno::Reference<XAccessible>& rxParent,
+ ScPreviewShell* pViewShell,
+ const EditTextObject* pEditObj,
+ sal_Bool bHeader,
+ SvxAdjust eAdjust)
+ : ScAccessibleContextBase(rxParent, AccessibleRole::TEXT),
+ mpEditObj(pEditObj->Clone()),
+ mpTextHelper(NULL),
+ mpViewShell(pViewShell),
+ mbHeader(bHeader),
+ meAdjust(eAdjust)
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePageHeaderArea::~ScAccessiblePageHeaderArea(void)
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePageHeaderArea::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ if (mpTextHelper)
+ DELETEZ(mpTextHelper);
+ if (mpEditObj)
+ DELETEZ(mpEditObj);
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePageHeaderArea::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ if (mpTextHelper)
+ mpTextHelper->UpdateChildren();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeaderArea::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessiblePageHeaderArea::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessiblePageHeaderArea::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessiblePageHeaderArea::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc())
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ========================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessiblePageHeaderArea::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessiblePageHeaderArea"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessiblePageHeaderArea::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AccessiblePageHeaderFooterAreasView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessiblePageHeaderArea::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//===== internal ==============================================================
+rtl::OUString SAL_CALL ScAccessiblePageHeaderArea::createAccessibleDescription(void)
+ throw(uno::RuntimeException)
+{
+ rtl::OUString sDesc;
+ switch (meAdjust)
+ {
+ case SVX_ADJUST_LEFT :
+ sDesc = String(ScResId(STR_ACC_LEFTAREA_DESCR));
+ break;
+ case SVX_ADJUST_RIGHT:
+ sDesc = String(ScResId(STR_ACC_RIGHTAREA_DESCR));
+ break;
+ case SVX_ADJUST_CENTER:
+ sDesc = String(ScResId(STR_ACC_CENTERAREA_DESCR));
+ break;
+ default:
+ DBG_ERRORFILE("wrong adjustment found");
+ }
+
+ return sDesc;
+}
+
+rtl::OUString SAL_CALL ScAccessiblePageHeaderArea::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sName;
+ switch (meAdjust)
+ {
+ case SVX_ADJUST_LEFT :
+ sName = String(ScResId(STR_ACC_LEFTAREA_NAME));
+ break;
+ case SVX_ADJUST_RIGHT:
+ sName = String(ScResId(STR_ACC_RIGHTAREA_NAME));
+ break;
+ case SVX_ADJUST_CENTER:
+ sName = String(ScResId(STR_ACC_CENTERAREA_NAME));
+ break;
+ default:
+ DBG_ERRORFILE("wrong adjustment found");
+ }
+
+ return sName;
+}
+
+Rectangle ScAccessiblePageHeaderArea::GetBoundingBoxOnScreen(void) const
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xContext = mxParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xComp(xContext, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ // has the same size and position on screen like the parent
+ aRect = Rectangle(VCLPoint(xComp->getLocationOnScreen()), VCLRectangle(xComp->getBounds()).GetSize());
+ }
+ }
+ return aRect;
+}
+
+Rectangle ScAccessiblePageHeaderArea::GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xContext = mxParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xComp(xContext, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ // has the same size and position on screen like the parent and so the pos is (0, 0)
+ Rectangle aNewRect(Point(0, 0), VCLRectangle(xComp->getBounds()).GetSize());
+ aRect = aNewRect;
+ }
+ }
+
+ return aRect;
+}
+
+void ScAccessiblePageHeaderArea::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessibleHeaderTextData
+ (new ScAccessibleHeaderTextData(mpViewShell, mpEditObj, mbHeader, meAdjust));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleHeaderTextData));
+
+ mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
+ mpTextHelper->SetEventSource(this);
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessiblePreviewCell.cxx b/sc/source/ui/Accessibility/AccessiblePreviewCell.cxx
new file mode 100644
index 000000000000..c07eb0844b7f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePreviewCell.cxx
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <tools/gen.hxx>
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include "AccessiblePreviewCell.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "prevloc.hxx"
+#include "document.hxx"
+#include <svx/AccessibleTextHelper.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <editeng/brshitem.hxx>
+#include <vcl/window.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessiblePreviewCell::ScAccessiblePreviewCell( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, /* const */ ScAddress& rCellAddress,
+ sal_Int32 nIndex ) :
+ ScAccessibleCellBase( rxParent, ( pViewShell ? pViewShell->GetDocument() : NULL ), rCellAddress, nIndex ),
+ mpViewShell( pViewShell ),
+ mpTextHelper(NULL)
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePreviewCell::~ScAccessiblePreviewCell()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePreviewCell::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ if (mpTextHelper)
+ DELETEZ(mpTextHelper);
+
+ ScAccessibleCellBase::disposing();
+}
+
+void ScAccessiblePreviewCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ if (mpTextHelper)
+ mpTextHelper->UpdateChildren();
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewCell::getAccessibleAtPoint( const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePreviewCell::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewCell::getAccessibleChildCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewCell::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewCell::getAccessibleStateSet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ if (IsOpaque(xParentStates))
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::TRANSIENT);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ // #111635# MANAGES_DESCENDANTS (for paragraphs)
+ pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePreviewCell::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewCell"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewCell::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessiblePreviewCell::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//==== internal =========================================================
+
+Rectangle ScAccessiblePreviewCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+ if (mpViewShell)
+ {
+ mpViewShell->GetLocationData().GetCellPosition( maCellAddress, aCellRect );
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePreviewCell::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+ if (mpViewShell)
+ {
+ mpViewShell->GetLocationData().GetCellPosition( maCellAddress, aCellRect );
+ uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewCell*>(this)->getAccessibleParent();
+ if (xAccParent.is())
+ {
+ uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
+ if (xAccParentComp.is())
+ {
+ Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
+ aCellRect.setX(aCellRect.getX() - aParentRect.getX());
+ aCellRect.setY(aCellRect.getY() - aParentRect.getY());
+ }
+ }
+ }
+ return aCellRect;
+}
+
+sal_Bool ScAccessiblePreviewCell::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpDoc == NULL) || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessiblePreviewCell::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ return sal_False;
+}
+
+sal_Bool ScAccessiblePreviewCell::IsOpaque(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ // test whether there is a background color
+ //! could be moved to ScAccessibleCellBase
+
+ sal_Bool bOpaque(sal_True);
+ if (mpDoc)
+ {
+ const SvxBrushItem* pItem = (const SvxBrushItem*)mpDoc->GetAttr(
+ maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_BACKGROUND);
+ if (pItem)
+ bOpaque = pItem->GetColor() != COL_TRANSPARENT;
+ }
+ return bOpaque;
+}
+
+void ScAccessiblePreviewCell::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewCellTextData
+ (new ScAccessiblePreviewCellTextData(mpViewShell, maCellAddress));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewCellTextData));
+
+ mpTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
+ mpTextHelper->SetEventSource( this );
+
+ // #111635# paragraphs in preview are transient
+ ::accessibility::AccessibleTextHelper::VectorOfStates aChildStates;
+ aChildStates.push_back( AccessibleStateType::TRANSIENT );
+ mpTextHelper->SetAdditionalChildStates( aChildStates );
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx b/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx
new file mode 100644
index 000000000000..3bb66ae01d4f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <tools/gen.hxx>
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include <svx/AccessibleTextHelper.hxx>
+#include "AccessiblePreviewHeaderCell.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "prevloc.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <vcl/window.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <comphelper/sequence.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessiblePreviewHeaderCell::ScAccessiblePreviewHeaderCell( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell,
+ const ScAddress& rCellPos, sal_Bool bIsColHdr, sal_Bool bIsRowHdr,
+ sal_Int32 nIndex ) :
+ ScAccessibleContextBase( rxParent, AccessibleRole::TABLE_CELL ),
+ mpViewShell( pViewShell ),
+ mpTextHelper( NULL ),
+ mnIndex( nIndex ),
+ maCellPos( rCellPos ),
+ mbColumnHeader( bIsColHdr ),
+ mbRowHeader( bIsRowHdr ),
+ mpTableInfo( NULL )
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePreviewHeaderCell::~ScAccessiblePreviewHeaderCell()
+{
+ if (mpViewShell)
+ mpViewShell->RemoveAccessibilityObject(*this);
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ if (mpTableInfo)
+ DELETEZ (mpTableInfo);
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePreviewHeaderCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ ULONG nId = rRef.GetId();
+ if (nId == SC_HINT_ACC_VISAREACHANGED)
+ {
+ if (mpTextHelper)
+ mpTextHelper->UpdateChildren();
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // column / row layout may change with any document change,
+ // so it must be invalidated
+ DELETEZ( mpTableInfo );
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessiblePreviewHeaderCellImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+//===== XAccessibleValue ================================================
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getCurrentValue() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ double fValue(0.0);
+ if (mbColumnHeader)
+ fValue = maCellPos.Col();
+ else
+ fValue = maCellPos.Row();
+
+ uno::Any aAny;
+ aAny <<= fValue;
+ return aAny;
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewHeaderCell::setCurrentValue( const uno::Any& /* aNumber */ )
+ throw (uno::RuntimeException)
+{
+ // it is not possible to set a value
+ return sal_False;
+}
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMaximumValue() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ double fValue(0.0);
+ if (mbColumnHeader)
+ fValue = MAXCOL;
+ else
+ fValue = MAXROW;
+ uno::Any aAny;
+ aAny <<= fValue;
+ return aAny;
+}
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumValue() throw (uno::RuntimeException)
+{
+ double fValue(0.0);
+ uno::Any aAny;
+ aAny <<= fValue;
+ return aAny;
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleAtPoint( const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChildCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent() throw (uno::RuntimeException)
+{
+ return mnIndex;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleStateSet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::TRANSIENT);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewHeaderCell"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewHeaderCell::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewHeaderCell::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessiblePreviewHeaderCellImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessiblePreviewHeaderCell::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//==== internal =========================================================
+
+Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+
+ FillTableInfo();
+
+ if (mpTableInfo)
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
+
+ aCellRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
+ }
+
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ FillTableInfo();
+
+ if (mpTableInfo)
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
+
+ Rectangle aCellRect( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
+ uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewHeaderCell*>(this)->getAccessibleParent();
+ if (xAccParent.is())
+ {
+ uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
+ if (xAccParentComp.is())
+ {
+ Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
+ aCellRect.setX(aCellRect.getX() - aParentRect.getX());
+ aCellRect.setY(aCellRect.getY() - aParentRect.getY());
+ }
+ }
+ return aCellRect;
+ }
+ return Rectangle();
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleDescription() throw(uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_HEADERCELL_DESCR));
+ return sDescription;
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleName() throw(uno::RuntimeException)
+{
+ rtl::OUString sName = String(ScResId(STR_ACC_HEADERCELL_NAME));
+
+ if ( mbColumnHeader )
+ {
+ if ( mbRowHeader )
+ {
+ //! name for corner cell?
+
+// sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column/Row Header"));
+ }
+ else
+ {
+ // name of column header
+ sName += ScColToAlpha( maCellPos.Col() );
+ }
+ }
+ else
+ {
+ // name of row header
+ sName += rtl::OUString::valueOf( (sal_Int32) ( maCellPos.Row() + 1 ) );
+ }
+
+ return sName;
+}
+
+sal_Bool ScAccessiblePreviewHeaderCell::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessiblePreviewHeaderCell::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
+ (new ScAccessiblePreviewHeaderCellTextData(mpViewShell, String(getAccessibleName()), maCellPos, mbColumnHeader, mbRowHeader));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
+
+ mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
+ mpTextHelper->SetEventSource(this);
+ }
+}
+
+void ScAccessiblePreviewHeaderCell::FillTableInfo() const
+{
+ if ( mpViewShell && !mpTableInfo )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+
+ mpTableInfo = new ScPreviewTableInfo;
+ mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessiblePreviewTable.cxx b/sc/source/ui/Accessibility/AccessiblePreviewTable.cxx
new file mode 100644
index 000000000000..e3fe26f47b4d
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePreviewTable.cxx
@@ -0,0 +1,769 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include "AccessiblePreviewTable.hxx"
+#include "AccessiblePreviewCell.hxx"
+#include "AccessiblePreviewHeaderCell.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "prevloc.hxx"
+#include "attrib.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+#include <vcl/window.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <comphelper/sequence.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessiblePreviewTable::ScAccessiblePreviewTable( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, sal_Int32 nIndex ) :
+ ScAccessibleContextBase( rxParent, AccessibleRole::TABLE ),
+ mpViewShell( pViewShell ),
+ mnIndex( nIndex ),
+ mpTableInfo( NULL )
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePreviewTable::~ScAccessiblePreviewTable()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePreviewTable::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ if (mpTableInfo)
+ DELETEZ (mpTableInfo);
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePreviewTable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ ULONG nId = rRef.GetId();
+ if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // column / row layout may change with any document change,
+ // so it must be invalidated
+ DELETEZ( mpTableInfo );
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessiblePreviewTable::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessiblePreviewTableImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessiblePreviewTable::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessiblePreviewTable::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+//===== XAccessibleTable ================================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRet = 0;
+ if ( mpTableInfo )
+ nRet = mpTableInfo->GetRows();
+ return nRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRet = 0;
+ if ( mpTableInfo )
+ nRet = mpTableInfo->GetCols();
+ return nRet;
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleRowDescription( sal_Int32 nRow )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // is not supported or specified so not implemented
+/* ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ rtl::OUString sName;
+ if ( mpTableInfo && nRow >= 0 && nRow < mpTableInfo->GetRows() )
+ {
+ const ScPreviewColRowInfo& rInfo = mpTableInfo->GetRowInfo()[nRow];
+ if ( rInfo.bIsHeader )
+ {
+ //! name of column headers row?
+
+ sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column Headers"));
+ }
+ else
+ {
+ // normal row name
+ sName = rtl::OUString::valueOf( (sal_Int32) ( rInfo.nDocIndex + 1 ) );
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();*/
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return rtl::OUString();
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // is not supported or specified so not implemented
+/* ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ rtl::OUString sName;
+ if ( mpTableInfo && nColumn >= 0 && nColumn < mpTableInfo->GetCols() )
+ {
+ const ScPreviewColRowInfo& rInfo = mpTableInfo->GetColInfo()[nColumn];
+ if ( rInfo.bIsHeader )
+ {
+ //! name of row headers column?
+
+ sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Row Headers"));
+ }
+ else
+ {
+ // normal column name
+ sName = ScColToAlpha( rInfo.nDocIndex );
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();*/
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return rtl::OUString();
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRows = 1;
+ if ( mpViewShell && mpTableInfo && nColumn >= 0 && nRow >= 0 &&
+ nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
+
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ {
+ // header cells only span a single cell
+ }
+ else
+ {
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ const ScMergeAttr* pItem = (const ScMergeAttr*)pDoc->GetAttr(
+ static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
+ if ( pItem && pItem->GetRowMerge() > 0 )
+ nRows = pItem->GetRowMerge();
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nRows;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nColumns = 1;
+ if ( mpViewShell && mpTableInfo && nColumn >= 0 && nRow >= 0 &&
+ nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
+
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ {
+ // header cells only span a single cell
+ }
+ else
+ {
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ const ScMergeAttr* pItem = (const ScMergeAttr*)pDoc->GetAttr(
+ static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
+ if ( pItem && pItem->GetColMerge() > 0 )
+ nColumns = pItem->GetColMerge();
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nColumns;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleRowHeaders() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnHeaders() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleRows() throw (uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+ return uno::Sequence<sal_Int32>(0);
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleColumns() throw (uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+ return uno::Sequence<sal_Int32>(0);
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleRowSelected( sal_Int32 nRow )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return sal_False;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ uno::Reference<XAccessible> xRet;
+ if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ // index iterates horizontally
+ long nNewIndex = nRow * mpTableInfo->GetCols() + nColumn;
+
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
+
+ ScAddress aCellPos( static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab() );
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ {
+ ScAccessiblePreviewHeaderCell* pHeaderCell = new ScAccessiblePreviewHeaderCell( this, mpViewShell, aCellPos,
+ rRowInfo.bIsHeader, rColInfo.bIsHeader, nNewIndex );
+ xRet = pHeaderCell;
+ pHeaderCell->Init();
+ }
+ else
+ {
+ ScAccessiblePreviewCell* pCell = new ScAccessiblePreviewCell( this, mpViewShell, aCellPos, nNewIndex );
+ xRet = pCell;
+ pCell->Init();
+ }
+ }
+
+ if ( !xRet.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCaption() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleSummary() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ // index iterates horizontally
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return sal_False;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRet = 0;
+ if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ // index iterates horizontally
+ nRet = nRow * mpTableInfo->GetCols() + nColumn;
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRow( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRow = 0;
+ if ( mpTableInfo && nChildIndex >= 0 && nChildIndex < static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
+ {
+ nRow = nChildIndex / mpTableInfo->GetCols();
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nRow;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumn( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nCol = 0;
+ if ( mpTableInfo && nChildIndex >= 0 && nChildIndex < static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
+ {
+ nCol = nChildIndex % static_cast<sal_Int32>(mpTableInfo->GetCols());
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nCol;
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleAtPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(aPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ if ( mpTableInfo )
+ {
+ SCCOL nCols = mpTableInfo->GetCols();
+ SCROW nRows = mpTableInfo->GetRows();
+ const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
+ const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
+
+ Rectangle aScreenRect(GetBoundingBox());
+
+ awt::Point aMovedPoint = aPoint;
+ aMovedPoint.X += aScreenRect.Left();
+ aMovedPoint.Y += aScreenRect.Top();
+
+ if ( nCols > 0 && nRows > 0 && aMovedPoint.X >= pColInfo[0].nPixelStart && aMovedPoint.Y >= pRowInfo[0].nPixelStart )
+ {
+ SCCOL nColIndex = 0;
+ while ( nColIndex < nCols && aMovedPoint.X > pColInfo[nColIndex].nPixelEnd )
+ ++nColIndex;
+ SCROW nRowIndex = 0;
+ while ( nRowIndex < nRows && aMovedPoint.Y > pRowInfo[nRowIndex].nPixelEnd )
+ ++nRowIndex;
+ if ( nColIndex < nCols && nRowIndex < nRows )
+ {
+ try
+ {
+ xRet = getAccessibleCellAt( nRowIndex, nColIndex );
+ }
+ catch (uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePreviewTable::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleChildCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ long nRet = 0;
+ if ( mpTableInfo )
+ nRet = static_cast<sal_Int32>(mpTableInfo->GetCols()) * mpTableInfo->GetRows();
+ return nRet;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleChild( sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ uno::Reference<XAccessible> xRet;
+ if ( mpTableInfo )
+ {
+ long nColumns = mpTableInfo->GetCols();
+ if ( nColumns > 0 )
+ {
+ // nCol, nRow are within the visible table, not the document
+ long nCol = nIndex % nColumns;
+ long nRow = nIndex / nColumns;
+
+ xRet = getAccessibleCellAt( nRow, nCol );
+ }
+ }
+
+ if ( !xRet.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndexInParent() throw (uno::RuntimeException)
+{
+ return mnIndex;
+}
+
+uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePreviewTable::getAccessibleStateSet()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePreviewTable::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewTable"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewTable::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleTableView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider ===================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewTable::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessiblePreviewTableImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScAccessiblePreviewTable::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//==== internal =========================================================
+
+::rtl::OUString SAL_CALL ScAccessiblePreviewTable::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ String sDesc(ScResId(STR_ACC_TABLE_DESCR));
+/* if (mpViewShell && mpViewShell->GetDocument())
+ {
+ FillTableInfo();
+
+ if ( mpTableInfo )
+ {
+ String sCoreName;
+ if (mpViewShell->GetDocument()->GetName( mpTableInfo->GetTab(), sCoreName ))
+ sDesc.SearchAndReplaceAscii("%1", sCoreName);
+ }
+ }
+ sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
+ return rtl::OUString(sDesc);
+}
+
+::rtl::OUString SAL_CALL ScAccessiblePreviewTable::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName(ScResId(STR_ACC_TABLE_NAME));
+
+ if (mpViewShell && mpViewShell->GetDocument())
+ {
+ FillTableInfo();
+
+ if ( mpTableInfo )
+ {
+ String sCoreName;
+ if (mpViewShell->GetDocument()->GetName( mpTableInfo->GetTab(), sCoreName ))
+ sName.SearchAndReplaceAscii("%1", sCoreName);
+ }
+ }
+
+ return rtl::OUString(sName);
+}
+
+Rectangle ScAccessiblePreviewTable::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect(GetBoundingBox());
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePreviewTable::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ FillTableInfo();
+
+ Rectangle aRect;
+ if ( mpTableInfo )
+ {
+ SCCOL nColumns = mpTableInfo->GetCols();
+ SCROW nRows = mpTableInfo->GetRows();
+ if ( nColumns > 0 && nRows > 0 )
+ {
+ const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
+ const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
+
+ aRect = Rectangle( pColInfo[0].nPixelStart,
+ pRowInfo[0].nPixelStart,
+ pColInfo[nColumns-1].nPixelEnd,
+ pRowInfo[nRows-1].nPixelEnd );
+ }
+ }
+ return aRect;
+}
+
+sal_Bool ScAccessiblePreviewTable::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessiblePreviewTable::FillTableInfo() const
+{
+ if ( mpViewShell && !mpTableInfo )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+
+ mpTableInfo = new ScPreviewTableInfo;
+ mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
new file mode 100644
index 000000000000..f85fb22531aa
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
@@ -0,0 +1,999 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleSpreadsheet.hxx"
+#include "AccessibilityHints.hxx"
+#include "AccessibleCell.hxx"
+#include "AccessibleDocument.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "unoguard.hxx"
+#include "hints.hxx"
+#include "scmod.hxx"
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
+ ScAccessibleDocument* pAccDoc,
+ ScTabViewShell* pViewShell,
+ SCTAB nTab,
+ ScSplitPos eSplitPos)
+ :
+ ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell),
+ ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))),
+ mbIsSpreadsheet( sal_True )
+{
+ ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos );
+}
+
+ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
+ ScAccessibleSpreadsheet& rParent, const ScRange& rRange ) :
+ ScAccessibleTableBase( rParent.mpAccDoc, rParent.mpDoc, rRange),
+ mbIsSpreadsheet( sal_False )
+{
+ ConstructScAccessibleSpreadsheet( rParent.mpAccDoc, rParent.mpViewShell, rParent.mnTab, rParent.meSplitPos );
+}
+
+ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet()
+{
+ if (mpMarkedRanges)
+ delete mpMarkedRanges;
+ if (mpSortedMarkedCells)
+ delete mpSortedMarkedCells;
+ if (mpViewShell)
+ mpViewShell->RemoveAccessibilityObject(*this);
+}
+
+void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet(
+ ScAccessibleDocument* pAccDoc,
+ ScTabViewShell* pViewShell,
+ SCTAB nTab,
+ ScSplitPos eSplitPos)
+{
+ mpViewShell = pViewShell;
+ mpMarkedRanges = 0;
+ mpSortedMarkedCells = 0;
+ mpAccDoc = pAccDoc;
+ mpAccCell = 0;
+ meSplitPos = eSplitPos;
+ mnTab = nTab;
+ mbHasSelection = sal_False;
+ mbDelIns = sal_False;
+ mbIsFocusSend = sal_False;
+ maVisCells = GetVisCells(GetVisArea(mpViewShell, meSplitPos));
+ if (mpViewShell)
+ {
+ mpViewShell->AddAccessibilityObject(*this);
+
+ const ScViewData& rViewData = *mpViewShell->GetViewData();
+ const ScMarkData& rMarkData = rViewData.GetMarkData();
+ maActiveCell = rViewData.GetCurPos();
+ mbHasSelection = rMarkData.GetTableSelect(maActiveCell.Tab()) &&
+ (rMarkData.IsMarked() || rMarkData.IsMultiMarked());
+ mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
+ mpAccCell->acquire();
+ mpAccCell->Init();
+ }
+}
+
+void SAL_CALL ScAccessibleSpreadsheet::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ if (mpAccCell)
+ {
+ mpAccCell->release();
+ mpAccCell = NULL;
+ }
+
+ ScAccessibleTableBase::disposing();
+}
+
+void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState)
+{
+ if (mpMarkedRanges)
+ DELETEZ(mpMarkedRanges);
+ if (mpSortedMarkedCells)
+ DELETEZ(mpSortedMarkedCells);
+
+ mbHasSelection = bNewState;
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::STATE_CHANGED;
+ if (bNewState)
+ aEvent.NewValue = uno::makeAny(AccessibleStateType::SELECTED);
+ else
+ aEvent.OldValue = uno::makeAny(AccessibleStateType::SELECTED);
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleSpreadsheet::LostFocus()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ uno::Reference< XAccessible > xOld = mpAccCell;
+ aEvent.OldValue <<= xOld;
+
+ CommitChange(aEvent);
+
+ CommitFocusLost();
+}
+
+void ScAccessibleSpreadsheet::GotFocus()
+{
+ CommitFocusGained();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ uno::Reference< XAccessible > xNew = mpAccCell;
+ aEvent.NewValue <<= xNew;
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleSpreadsheet::BoundingBoxChanged()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleSpreadsheet::VisAreaChanged()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+}
+
+ //===== SfxListener =====================================================
+
+void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_ACC_CURSORCHANGED))
+ {
+ if (mpViewShell)
+ {
+ ScAddress aNewCell = mpViewShell->GetViewData()->GetCurPos();
+ sal_Bool bNewMarked(mpViewShell->GetViewData()->GetMarkData().GetTableSelect(aNewCell.Tab()) &&
+ (mpViewShell->GetViewData()->GetMarkData().IsMarked() ||
+ mpViewShell->GetViewData()->GetMarkData().IsMultiMarked()));
+ sal_Bool bNewCellSelected(isAccessibleSelected(aNewCell.Row(), aNewCell.Col()));
+ if ((bNewMarked != mbHasSelection) ||
+ (!bNewCellSelected && bNewMarked) ||
+ (bNewCellSelected && mbHasSelection))
+ {
+ if (mpMarkedRanges)
+ DELETEZ(mpMarkedRanges);
+ if (mpSortedMarkedCells)
+ DELETEZ(mpSortedMarkedCells);
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ mbHasSelection = bNewMarked;
+
+ CommitChange(aEvent);
+ }
+
+ // active descendant changed event (new cell selected)
+ bool bFireActiveDescChanged = (aNewCell != maActiveCell) &&
+ (aNewCell.Tab() == maActiveCell.Tab()) && IsFocused();
+
+ /* Remember old active cell and set new active cell.
+ #i82409# always update the class members mpAccCell and
+ maActiveCell, even if the sheet is not focused, e.g. when
+ using the name box in the toolbar. */
+ uno::Reference< XAccessible > xOld = mpAccCell;
+ mpAccCell->release();
+ mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col());
+ mpAccCell->acquire();
+ mpAccCell->Init();
+ uno::Reference< XAccessible > xNew = mpAccCell;
+ maActiveCell = aNewCell;
+
+ // #i14108# fire event only if sheet is focused
+ if( bFireActiveDescChanged )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= xOld;
+ aEvent.NewValue <<= xNew;
+ CommitChange(aEvent);
+ }
+ }
+ }
+ else if ((rRef.GetId() == SC_HINT_DATACHANGED))
+ {
+ if (!mbDelIns)
+ CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE);
+ else
+ mbDelIns = sal_False;
+ }
+ // no longer needed, because the document calls the VisAreaChanged method
+/* else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);*/
+ // commented out, because to use a ModelChangeEvent is not the right way
+ // at the moment there is no way, but the Java/Gnome Api should be extended sometime
+/* if (mpViewShell)
+ {
+ Rectangle aNewVisCells(GetVisCells(GetVisArea(mpViewShell, meSplitPos)));
+
+ Rectangle aNewPos(aNewVisCells);
+
+ if (aNewVisCells.IsOver(maVisCells))
+ aNewPos.Union(maVisCells);
+ else
+ CommitTableModelChange(maVisCells.Top(), maVisCells.Left(), maVisCells.Bottom(), maVisCells.Right(), AccessibleTableModelChangeType::UPDATE);
+
+ maVisCells = aNewVisCells;
+
+ CommitTableModelChange(aNewPos.Top(), aNewPos.Left(), aNewPos.Bottom(), aNewPos.Right(), AccessibleTableModelChangeType::UPDATE);
+ }
+ }*/
+ // no longer needed, because the document calls the BoundingBoxChanged method
+/* else if (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+ }*/
+ }
+ else if (rHint.ISA( ScUpdateRefHint ))
+ {
+ const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+ if (rRef.GetMode() == URM_INSDEL && rRef.GetDz() == 0) //#107250# test whether table is inserted or deleted
+ {
+ if (((rRef.GetRange().aStart.Col() == maRange.aStart.Col()) &&
+ (rRef.GetRange().aEnd.Col() == maRange.aEnd.Col())) ||
+ ((rRef.GetRange().aStart.Row() == maRange.aStart.Row()) &&
+ (rRef.GetRange().aEnd.Row() == maRange.aEnd.Row())))
+ {
+ // ignore next SC_HINT_DATACHANGED notification
+ mbDelIns = sal_True;
+
+ sal_Int16 nId(0);
+ SCsCOL nX(rRef.GetDx());
+ SCsROW nY(rRef.GetDy());
+ ScRange aRange(rRef.GetRange());
+ if ((nX < 0) || (nY < 0))
+ {
+ DBG_ASSERT(!((nX < 0) && (nY < 0)), "should not be possible to remove row and column at the same time");
+ nId = AccessibleTableModelChangeType::DELETE;
+ if (nX < 0)
+ {
+ nX = -nX;
+ nY = aRange.aEnd.Row() - aRange.aStart.Row();
+ }
+ else
+ {
+ nY = -nY;
+ nX = aRange.aEnd.Col() - aRange.aStart.Col();
+ }
+ }
+ else if ((nX > 0) || (nY > 0))
+ {
+ DBG_ASSERT(!((nX > 0) && (nY > 0)), "should not be possible to add row and column at the same time");
+ nId = AccessibleTableModelChangeType::INSERT;
+ if (nX < 0)
+ nY = aRange.aEnd.Row() - aRange.aStart.Row();
+ else
+ nX = aRange.aEnd.Col() - aRange.aStart.Col();
+ }
+ else
+ {
+ DBG_ERROR("is it a deletion or a insertion?");
+ }
+
+ CommitTableModelChange(rRef.GetRange().aStart.Row(),
+ rRef.GetRange().aStart.Col(),
+ rRef.GetRange().aStart.Row() + nY,
+ rRef.GetRange().aStart.Col() + nX, nId);
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ uno::Reference< XAccessible > xNew = mpAccCell;
+ aEvent.NewValue <<= xNew;
+
+ CommitChange(aEvent);
+ }
+ }
+ }
+
+ ScAccessibleTableBase::Notify(rBC, rHint);
+}
+
+ //===== XAccessibleTable ================================================
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ if( mpDoc && mbIsSpreadsheet )
+ {
+ if( const ScRange* pRowRange = mpDoc->GetRepeatRowRange( mnTab ) )
+ {
+ SCROW nStart = pRowRange->aStart.Row();
+ SCROW nEnd = pRowRange->aEnd.Row();
+ if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXROW) )
+ xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( 0, nStart, mnTab, MAXCOL, nEnd, mnTab ) ) );
+ }
+ }
+ return xAccessibleTable;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleColumnHeaders( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ if( mpDoc && mbIsSpreadsheet )
+ {
+ if( const ScRange* pColRange = mpDoc->GetRepeatColRange( mnTab ) )
+ {
+ SCCOL nStart = pColRange->aStart.Col();
+ SCCOL nEnd = pColRange->aEnd.Col();
+ if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXCOL) )
+ xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( nStart, 0, mnTab, nEnd, MAXROW, mnTab ) ) );
+ }
+ }
+ return xAccessibleTable;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleRows( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Sequence<sal_Int32> aSequence;
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1);
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ sal_Int32* pSequence = aSequence.getArray();
+ sal_Int32 nCount(0);
+ for (SCROW i = maRange.aStart.Row(); i <= maRange.aEnd.Row(); ++i)
+ {
+ if (rMarkdata.IsRowMarked(i))
+ {
+ pSequence[nCount] = i;
+ ++nCount;
+ }
+ }
+ aSequence.realloc(nCount);
+ }
+ else
+ aSequence.realloc(0);
+ return aSequence;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleColumns( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Sequence<sal_Int32> aSequence;
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ sal_Int32* pSequence = aSequence.getArray();
+ sal_Int32 nCount(0);
+ for (SCCOL i = maRange.aStart.Col(); i <= maRange.aEnd.Col(); ++i)
+ {
+ if (rMarkdata.IsColumnMarked(i))
+ {
+ pSequence[nCount] = i;
+ ++nCount;
+ }
+ }
+ aSequence.realloc(nCount);
+ }
+ else
+ aSequence.realloc(0);
+ return aSequence;
+}
+
+sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nRow )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bResult(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsRowMarked((SCROW)nRow);
+ }
+ return bResult;
+}
+
+sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bResult(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsColumnMarked((SCCOL)nColumn);
+ }
+ return bResult;
+}
+
+ScAccessibleCell* ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn)
+{
+ ScAccessibleCell* pAccessibleCell = NULL;
+ ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn),
+ static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab());
+ if ((aCellAddress == maActiveCell) && mpAccCell)
+ {
+ pAccessibleCell = mpAccCell;
+ }
+ else
+ pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc);
+
+ return pAccessibleCell;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
+ nRow < 0 ||
+ nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
+ nColumn < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference<XAccessible> xAccessible;
+ ScAccessibleCell* pAccessibleCell = GetAccessibleCellAt(nRow, nColumn);
+ xAccessible = pAccessibleCell;
+ pAccessibleCell->Init();
+ return xAccessible;
+}
+
+sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
+ (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bResult(sal_False);
+ if (mpViewShell)
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsCellMarked(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow));
+ }
+ return bResult;
+}
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< XAccessible > xAccessible;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpViewShell)
+ {
+ SCsCOL nX;
+ SCsROW nY;
+ mpViewShell->GetViewData()->GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY);
+ xAccessible = getAccessibleCellAt(nY, nX);
+ }
+ }
+ return xAccessible;
+}
+
+void SAL_CALL ScAccessibleSpreadsheet::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getForeground( )
+ throw (uno::RuntimeException)
+{
+ return COL_BLACK;
+}
+
+sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getBackground( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
+}
+
+ //===== XAccessibleContext ==============================================
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL ScAccessibleSpreadsheet::getAccessibleRelationSet(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ utl::AccessibleRelationSetHelper* pRelationSet = NULL;
+ if(mpAccDoc)
+ pRelationSet = mpAccDoc->GetRelationSet(NULL);
+ if (!pRelationSet)
+ pRelationSet = new utl::AccessibleRelationSetHelper();
+ return pRelationSet;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleSpreadsheet::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
+ if (IsEditable(xParentStates))
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::FOCUSABLE);
+ if (IsFocused())
+ pStateSet->AddState(AccessibleStateType::FOCUSED);
+ pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ pStateSet->AddState(AccessibleStateType::SELECTABLE);
+ if (IsCompleteSheetSelected())
+ pStateSet->AddState(AccessibleStateType::SELECTED);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+ ///===== XAccessibleSelection ===========================================
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
+ throw lang::IndexOutOfBoundsException();
+
+ if (mpViewShell)
+ {
+ sal_Int32 nCol(getAccessibleColumn(nChildIndex));
+ sal_Int32 nRow(getAccessibleRow(nChildIndex));
+
+ SelectCell(nRow, nCol, sal_False);
+ }
+}
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::clearAccessibleSelection( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpViewShell)
+ {
+ mpViewShell->Unmark();
+ }
+}
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::selectAllAccessibleChildren( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpViewShell)
+ {
+ mpViewShell->SelectAll();
+ }
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleSpreadsheet::getSelectedAccessibleChildCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nResult(0);
+ if (mpViewShell)
+ {
+ if (!mpMarkedRanges)
+ {
+ mpMarkedRanges = new ScRangeList();
+ ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
+ aMarkData.MarkToMulti();
+ aMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_False);
+ }
+ // is possible, because there shouldn't be overlapped ranges in it
+ if (mpMarkedRanges)
+ nResult = mpMarkedRanges->GetCellCount();
+ }
+ return nResult;
+}
+
+uno::Reference<XAccessible > SAL_CALL
+ ScAccessibleSpreadsheet::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference < XAccessible > xAccessible;
+ if (mpViewShell)
+ {
+ if (!mpMarkedRanges)
+ {
+ mpMarkedRanges = new ScRangeList();
+ mpViewShell->GetViewData()->GetMarkData().FillRangeListWithMarks(mpMarkedRanges, sal_False);
+ }
+ if (mpMarkedRanges)
+ {
+ if (!mpSortedMarkedCells)
+ CreateSortedMarkedCells();
+ if (mpSortedMarkedCells)
+ {
+ if ((nSelectedChildIndex < 0) ||
+ (mpSortedMarkedCells->size() <= static_cast<sal_uInt32>(nSelectedChildIndex)))
+ throw lang::IndexOutOfBoundsException();
+ else
+ xAccessible = getAccessibleCellAt((*mpSortedMarkedCells)[nSelectedChildIndex].Row(), (*mpSortedMarkedCells)[nSelectedChildIndex].Col());
+ }
+ }
+ }
+ return xAccessible;
+}
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
+ throw lang::IndexOutOfBoundsException();
+
+ if (mpViewShell)
+ {
+ sal_Int32 nCol(getAccessibleColumn(nChildIndex));
+ sal_Int32 nRow(getAccessibleRow(nChildIndex));
+
+ if (mpViewShell->GetViewData()->GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)))
+ SelectCell(nRow, nCol, sal_True);
+ }
+}
+
+void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect)
+{
+ mpViewShell->SetTabNo( maRange.aStart.Tab() );
+
+ mpViewShell->DoneBlockMode( sal_True ); // continue selecting
+ mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, sal_False, sal_False );
+
+ mpViewShell->SelectionChanged();
+}
+
+void ScAccessibleSpreadsheet::CreateSortedMarkedCells()
+{
+ mpSortedMarkedCells = new std::vector<ScMyAddress>();
+ mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount());
+ ScRange* pRange = mpMarkedRanges->First();
+ while (pRange)
+ {
+ if (pRange->aStart.Tab() != pRange->aEnd.Tab())
+ {
+ if ((maActiveCell.Tab() >= pRange->aStart.Tab()) ||
+ maActiveCell.Tab() <= pRange->aEnd.Tab())
+ {
+ ScRange aRange(*pRange);
+ aRange.aStart.SetTab(maActiveCell.Tab());
+ aRange.aEnd.SetTab(maActiveCell.Tab());
+ AddMarkedRange(aRange);
+ }
+ else
+ {
+ DBG_ERROR("Range of wrong table");
+ }
+ }
+ else if(pRange->aStart.Tab() == maActiveCell.Tab())
+ AddMarkedRange(*pRange);
+ else
+ {
+ DBG_ERROR("Range of wrong table");
+ }
+ pRange = mpMarkedRanges->Next();
+ }
+ std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end());
+}
+
+void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange)
+{
+ for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+ {
+ for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
+ {
+ ScMyAddress aCell(nCol, nRow, maActiveCell.Tab());
+ mpSortedMarkedCells->push_back(aCell);
+ }
+ }
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleSpreadsheet::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleSpreadsheet"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleSpreadsheet::getSupportedServiceNames (void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleTableBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheet"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleSpreadsheet::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+///===== XAccessibleEventBroadcaster =====================================
+
+void SAL_CALL ScAccessibleSpreadsheet::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ ScAccessibleTableBase::addEventListener(xListener);
+
+ if (!mbIsFocusSend)
+ {
+ mbIsFocusSend = sal_True;
+ CommitFocusGained();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= getAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
+
+ CommitChange(aEvent);
+ }
+}
+
+ //==== internal =========================================================
+
+Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(NULL);
+ }
+ return aRect;
+}
+
+Rectangle ScAccessibleSpreadsheet::GetBoundingBox() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ //#101986#; extends to the same window, because the parent is the document and it has the same window
+ aRect = pWindow->GetWindowExtentsRelative(pWindow);
+ }
+ return aRect;
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ sal_Bool bProtected(sal_False);
+ if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab()))
+ bProtected = sal_True;
+ return !bProtected;
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsFocused()
+{
+ sal_Bool bFocused(sal_False);
+ if (mpViewShell)
+ {
+ if (mpViewShell->GetViewData()->GetActivePart() == meSplitPos)
+ bFocused = mpViewShell->GetActiveWin()->HasFocus();
+ }
+ return bFocused;
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected()
+{
+ sal_Bool bResult(sal_False);
+ if(mpViewShell)
+ {
+ //#103800#; use a copy of MarkData
+ ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
+ aMarkData.MarkToMulti();
+ if (aMarkData.IsAllMarked(maRange))
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+ScDocument* ScAccessibleSpreadsheet::GetDocument(ScTabViewShell* pViewShell)
+{
+ ScDocument* pDoc = NULL;
+ if (pViewShell)
+ pDoc = pViewShell->GetViewData()->GetDocument();
+ return pDoc;
+}
+
+Rectangle ScAccessibleSpreadsheet::GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
+{
+ Rectangle aVisArea;
+ if (pViewShell)
+ {
+ Window* pWindow = pViewShell->GetWindowByPos(eSplitPos);
+ if (pWindow)
+ {
+ aVisArea.SetPos(pViewShell->GetViewData()->GetPixPos(eSplitPos));
+ aVisArea.SetSize(pWindow->GetSizePixel());
+ }
+ }
+ return aVisArea;
+}
+
+Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea)
+{
+ if (mpViewShell)
+ {
+ SCsCOL nStartX, nEndX;
+ SCsROW nStartY, nEndY;
+
+ mpViewShell->GetViewData()->GetPosFromPixel( 1, 1, meSplitPos, nStartX, nStartY);
+ mpViewShell->GetViewData()->GetPosFromPixel( rVisArea.GetWidth(), rVisArea.GetHeight(), meSplitPos, nEndX, nEndY);
+
+ return Rectangle(nStartX, nStartY, nEndX, nEndY);
+ }
+ else
+ return Rectangle();
+}
diff --git a/sc/source/ui/Accessibility/AccessibleTableBase.cxx b/sc/source/ui/Accessibility/AccessibleTableBase.cxx
new file mode 100644
index 000000000000..2d46d3eb776b
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleTableBase.cxx
@@ -0,0 +1,495 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "AccessibleTableBase.hxx"
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <comphelper/sequence.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleTableBase::ScAccessibleTableBase(
+ const uno::Reference<XAccessible>& rxParent,
+ ScDocument* pDoc,
+ const ScRange& rRange)
+ :
+ ScAccessibleContextBase (rxParent, AccessibleRole::TABLE),
+ maRange(rRange),
+ mpDoc(pDoc)
+{
+}
+
+ScAccessibleTableBase::~ScAccessibleTableBase()
+{
+}
+
+void SAL_CALL ScAccessibleTableBase::disposing()
+{
+ ScUnoGuard aGuard;
+ mpDoc = NULL;
+
+ ScAccessibleContextBase::disposing();
+}
+
+ //===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleTableBase::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleTableBase::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleTableBase::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+ //===== XAccessibleTable ================================================
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
+}
+
+::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("Here should be a implementation to fill the description");
+
+ if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("Here should be a implementation to fill the description");
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
+ return rtl::OUString();
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
+ (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Int32 nCount(1); // the same cell
+ nRow += maRange.aStart.Row();
+ nColumn += maRange.aStart.Col();
+
+ if (mpDoc)
+ {
+ SCROW nEndRow(0);
+ SCCOL nEndCol(0);
+ if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
+ nEndCol, nEndRow, maRange.aStart.Tab()))
+ {
+ if (nEndRow > nRow)
+ nCount = nEndRow - nRow + 1;
+ }
+ }
+
+ return nCount;
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
+ (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Int32 nCount(1); // the same cell
+ nRow += maRange.aStart.Row();
+ nColumn += maRange.aStart.Col();
+
+ if (mpDoc)
+ {
+ SCROW nEndRow(0);
+ SCCOL nEndCol(0);
+ if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
+ nEndCol, nEndRow, maRange.aStart.Tab()))
+ {
+ if (nEndCol > nColumn)
+ nCount = nEndCol - nColumn + 1;
+ }
+ }
+
+ return nCount;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ DBG_ERROR("Here should be a implementation to fill the row headers");
+
+ //CommitChange
+ return xAccessibleTable;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ DBG_ERROR("Here should be a implementation to fill the column headers");
+
+ //CommitChange
+ return xAccessibleTable;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Sequence< sal_Int32 > aSequence;
+ return aSequence;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Sequence< sal_Int32 > aSequence;
+ return aSequence;
+}
+
+sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ return sal_False;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Reference< XAccessible > xAccessible;
+ return xAccessible;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Reference< XAccessible > xAccessible;
+ return xAccessible;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Reference< XAccessible > xAccessible;
+ return xAccessible;
+}
+
+sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ return sal_False;
+}
+
+ //===== XAccessibleExtendedTable ========================================
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
+ nRow < 0 ||
+ nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
+ nColumn < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ nRow -= maRange.aStart.Row();
+ nColumn -= maRange.aStart.Col();
+ return (nRow * (maRange.aEnd.Col() + 1)) + nColumn;
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleTableBase::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return static_cast<sal_Int32>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) *
+ (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+// return 1;
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nIndex >= getAccessibleChildCount() || nIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Int32 nRow(0);
+ sal_Int32 nColumn(0);
+ sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+ nRow = nIndex / nTemp;
+ nColumn = nIndex % nTemp;
+ return getAccessibleCellAt(nRow, nColumn);
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleTableBase::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ String sDesc(ScResId(STR_ACC_TABLE_DESCR));
+/* String sCoreName;
+ if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
+ sDesc.SearchAndReplaceAscii("%1", sCoreName);
+ sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
+ return rtl::OUString(sDesc);
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleTableBase::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName(ScResId(STR_ACC_TABLE_NAME));
+ String sCoreName;
+ if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
+ sName.SearchAndReplaceAscii("%1", sCoreName);
+ return rtl::OUString(sName);
+}
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ ScAccessibleTableBase::getAccessibleRelationSet(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return uno::Reference<XAccessibleRelationSet>();
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleTableBase::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ uno::Reference< XAccessibleStateSet > xAccessibleStateSet;
+ return xAccessibleStateSet;
+}
+
+ ///===== XAccessibleSelection ===========================================
+
+void SAL_CALL
+ ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // I don't need to guard, because the called funtions have a guard
+// ScUnoGuard aGuard;
+ if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
+ throw lang::IndexOutOfBoundsException();
+ return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex));
+}
+
+void SAL_CALL
+ ScAccessibleTableBase::clearAccessibleSelection( )
+ throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL
+ ScAccessibleTableBase::selectAllAccessibleChildren( )
+ throw (uno::RuntimeException)
+{
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleTableBase::getSelectedAccessibleChildCount( )
+ throw (uno::RuntimeException)
+{
+ sal_Int32 nResult(0);
+ return nResult;
+}
+
+uno::Reference<XAccessible > SAL_CALL
+ ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference < XAccessible > xAccessible;
+ return xAccessible;
+}
+
+void SAL_CALL
+ ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleTableBase::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleTableBase"));
+}
+
+ //===== XTypeProvider ===================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleTableBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleTableBase::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId)
+{
+ AccessibleTableModelChange aModelChange;
+ aModelChange.FirstRow = nStartRow;
+ aModelChange.FirstColumn = nStartCol;
+ aModelChange.LastRow = nEndRow;
+ aModelChange.LastColumn = nEndCol;
+ aModelChange.Type = nId;
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= aModelChange;
+
+ CommitChange(aEvent);
+}
diff --git a/sc/source/ui/Accessibility/AccessibleText.cxx b/sc/source/ui/Accessibility/AccessibleText.cxx
new file mode 100644
index 000000000000..4073e23f837f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleText.cxx
@@ -0,0 +1,1911 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <memory>
+#include "AccessibleText.hxx"
+#include "AccessibleCell.hxx"
+#include "tabvwsh.hxx"
+#include "editutil.hxx"
+#include "document.hxx"
+#include "scmod.hxx"
+#include "prevwsh.hxx"
+#include "docsh.hxx"
+#include "prevloc.hxx"
+#include "unoguard.hxx"
+#include "patattr.hxx"
+#include "inputwin.hxx"
+#include <editeng/unofored.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/unoedhlp.hxx>
+#include <vcl/virdev.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/algitem.hxx>
+
+
+// ============================================================================
+
+class ScViewForwarder : public SvxViewForwarder
+{
+ ScTabViewShell* mpViewShell;
+ ScAddress maCellPos;
+ ScSplitPos meSplitPos;
+public:
+ ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos, const ScAddress& rCell);
+ virtual ~ScViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+};
+
+ScViewForwarder::ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos, const ScAddress& rCell)
+ :
+ mpViewShell(pViewShell),
+ maCellPos(rCell),
+ meSplitPos(eSplitPos)
+{
+}
+
+ScViewForwarder::~ScViewForwarder()
+{
+}
+
+BOOL ScViewForwarder::IsValid() const
+{
+ return mpViewShell != NULL;
+}
+
+Rectangle ScViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ {
+ aVisArea.SetSize(pWindow->GetSizePixel());
+
+ ScHSplitPos eWhichH = ((meSplitPos == SC_SPLIT_TOPLEFT) || (meSplitPos == SC_SPLIT_BOTTOMLEFT)) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+ ScVSplitPos eWhichV = ((meSplitPos == SC_SPLIT_TOPLEFT) || (meSplitPos == SC_SPLIT_TOPRIGHT)) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+
+ Point aBaseCellPos(mpViewShell->GetViewData()->GetScrPos(mpViewShell->GetViewData()->GetPosX(eWhichH),
+ mpViewShell->GetViewData()->GetPosY(eWhichV), meSplitPos, sal_True));
+ Point aCellPos(mpViewShell->GetViewData()->GetScrPos(maCellPos.Col(), maCellPos.Row(), meSplitPos, sal_True));
+ aVisArea.SetPos(aCellPos - aBaseCellPos);
+ }
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+Point ScViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ return pWindow->LogicToPixel( rPoint, rMapMode );
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ return pWindow->PixelToLogic( rPoint, rMapMode );
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+void ScViewForwarder::SetInvalid()
+{
+ mpViewShell = NULL;
+}
+
+// ============================================================================
+
+class ScEditObjectViewForwarder : public SvxViewForwarder
+{
+ Window* mpWindow;
+ // --> OD 2005-12-21 #i49561#
+ // - EditView needed for access to its visible area.
+ const EditView* mpEditView;
+ // <--
+public:
+ // --> OD 2005-12-21 #i49561#
+ ScEditObjectViewForwarder( Window* pWindow,
+ const EditView* _pEditView);
+ // <--
+ virtual ~ScEditObjectViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+};
+
+// --> OD 2005-12-21 #i49561#
+ScEditObjectViewForwarder::ScEditObjectViewForwarder( Window* pWindow,
+ const EditView* _pEditView )
+ :
+ mpWindow(pWindow),
+ mpEditView( _pEditView )
+{
+}
+// <--
+
+ScEditObjectViewForwarder::~ScEditObjectViewForwarder()
+{
+}
+
+BOOL ScEditObjectViewForwarder::IsValid() const
+{
+ return (mpWindow != NULL);
+}
+
+Rectangle ScEditObjectViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpWindow)
+ {
+ Rectangle aVisRect(mpWindow->GetWindowExtentsRelative(mpWindow->GetAccessibleParentWindow()));
+
+ aVisRect.SetPos(Point(0, 0));
+
+ aVisArea = aVisRect;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+Point ScEditObjectViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ {
+ // --> OD 2005-12-21 #i49561# - consider offset of the visible area
+ // of the EditView before converting point to pixel.
+ Point aPoint( rPoint );
+ if ( mpEditView )
+ {
+ Rectangle aEditViewVisArea( mpEditView->GetVisArea() );
+ aPoint += aEditViewVisArea.TopLeft();
+ }
+ return mpWindow->LogicToPixel( aPoint, rMapMode );
+ // <--
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScEditObjectViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ {
+ // --> OD 2005-12-21 #i49561# - consider offset of the visible area
+ // of the EditView after converting point to logic.
+ Point aPoint( mpWindow->PixelToLogic( rPoint, rMapMode ) );
+ if ( mpEditView )
+ {
+ Rectangle aEditViewVisArea( mpEditView->GetVisArea() );
+ aPoint -= aEditViewVisArea.TopLeft();
+ }
+ return aPoint;
+ // <--
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+void ScEditObjectViewForwarder::SetInvalid()
+{
+ mpWindow = NULL;
+}
+
+// ============================================================================
+
+class ScPreviewViewForwarder : public SvxViewForwarder
+{
+protected:
+ ScPreviewShell* mpViewShell;
+ mutable ScPreviewTableInfo* mpTableInfo;
+public:
+ ScPreviewViewForwarder(ScPreviewShell* pViewShell);
+ virtual ~ScPreviewViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+
+ Rectangle GetVisRect() const;
+
+ // clips the VisArea and calculates with the negativ coordinates
+ Rectangle CorrectVisArea(const Rectangle& rVisArea) const;
+};
+
+ScPreviewViewForwarder::ScPreviewViewForwarder(ScPreviewShell* pViewShell)
+ :
+ mpViewShell(pViewShell),
+ mpTableInfo(NULL)
+{
+}
+
+ScPreviewViewForwarder::~ScPreviewViewForwarder()
+{
+ delete mpTableInfo;
+}
+
+BOOL ScPreviewViewForwarder::IsValid() const
+{
+ return mpViewShell != NULL;
+}
+
+Rectangle ScPreviewViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ DBG_ERROR("should be implemented in an abrevated class");
+ return aVisArea;
+}
+
+Point ScPreviewViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ MapMode aMapMode(pWindow->GetMapMode().GetMapUnit());
+ Point aPoint2( OutputDevice::LogicToLogic( rPoint, rMapMode, aMapMode) );
+ return pWindow->LogicToPixel(aPoint2);
+ }
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScPreviewViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ MapMode aMapMode(pWindow->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint1( pWindow->PixelToLogic( rPoint ) );
+ Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
+ aMapMode.GetMapUnit(),
+ rMapMode ) );
+ return aPoint2;
+ }
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+void ScPreviewViewForwarder::SetInvalid()
+{
+ mpViewShell = NULL;
+}
+
+Rectangle ScPreviewViewForwarder::GetVisRect() const
+{
+ if ( mpViewShell )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ return aVisRect;
+ }
+ return Rectangle();
+}
+
+Rectangle ScPreviewViewForwarder::CorrectVisArea(const Rectangle& rVisArea) const
+{
+ Rectangle aVisArea(rVisArea);
+ Point aPos = aVisArea.TopLeft(); // get first the position to remember negative positions after clipping
+
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aVisArea = pWin->GetWindowExtentsRelative(pWin).GetIntersection(aVisArea);
+
+ sal_Int32 nX(aPos.getX());
+ sal_Int32 nY(aPos.getY());
+
+ if (nX > 0)
+ nX = 0;
+ else if (nX < 0)
+ nX = -nX;
+ if (nY > 0)
+ nY = 0;
+ else if (nY < 0)
+ nY = -nY;
+ aVisArea.SetPos(Point(nX, nY));
+
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewHeaderFooterViewForwarder : public ScPreviewViewForwarder
+{
+ sal_Bool mbHeader;
+public:
+ ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell, sal_Bool bHeader);
+ virtual ~ScPreviewHeaderFooterViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewHeaderFooterViewForwarder::ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell, sal_Bool bHeader)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ mbHeader(bHeader)
+{
+}
+
+ScPreviewHeaderFooterViewForwarder::~ScPreviewHeaderFooterViewForwarder()
+{
+}
+
+Rectangle ScPreviewHeaderFooterViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ if ( mbHeader )
+ rData.GetHeaderPosition( aVisArea );
+ else
+ rData.GetFooterPosition( aVisArea );
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewCellViewForwarder : public ScPreviewViewForwarder
+{
+ ScAddress maCellPos;
+public:
+ ScPreviewCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos);
+ virtual ~ScPreviewCellViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewCellViewForwarder::ScPreviewCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ maCellPos(aCellPos)
+{
+}
+
+ScPreviewCellViewForwarder::~ScPreviewCellViewForwarder()
+{
+}
+
+Rectangle ScPreviewCellViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ aVisArea = rData.GetCellOutputRect(maCellPos);
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewHeaderCellViewForwarder : public ScPreviewViewForwarder
+{
+ ScAddress maCellPos;
+ sal_Bool mbColHeader;
+ sal_Bool mbRowHeader;
+public:
+ ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bColHeader, sal_Bool bRowHeader);
+ virtual ~ScPreviewHeaderCellViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewHeaderCellViewForwarder::ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bColHeader, sal_Bool bRowHeader)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ maCellPos(aCellPos),
+ mbColHeader(bColHeader),
+ mbRowHeader(bRowHeader)
+{
+}
+
+ScPreviewHeaderCellViewForwarder::~ScPreviewHeaderCellViewForwarder()
+{
+}
+
+Rectangle ScPreviewHeaderCellViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ aVisArea = rData.GetHeaderCellOutputRect(GetVisRect(), maCellPos, mbColHeader);
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewNoteViewForwarder : public ScPreviewViewForwarder
+{
+ ScAddress maCellPos;
+ sal_Bool mbNoteMark;
+public:
+ ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bNoteMark);
+ virtual ~ScPreviewNoteViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewNoteViewForwarder::ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bNoteMark)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ maCellPos(aCellPos),
+ mbNoteMark(bNoteMark)
+{
+}
+
+ScPreviewNoteViewForwarder::~ScPreviewNoteViewForwarder()
+{
+}
+
+Rectangle ScPreviewNoteViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ aVisArea = rData.GetNoteInRangeOutputRect(GetVisRect(), mbNoteMark, maCellPos);
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScEditViewForwarder : public SvxEditViewForwarder
+{
+ EditView* mpEditView;
+ Window* mpWindow;
+public:
+ ScEditViewForwarder(EditView* pEditView, Window* pWin);
+ virtual ~ScEditViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual sal_Bool GetSelection( ESelection& rSelection ) const;
+ virtual sal_Bool SetSelection( const ESelection& rSelection );
+ virtual sal_Bool Copy();
+ virtual sal_Bool Cut();
+ virtual sal_Bool Paste();
+
+ void GrabFocus();
+
+ void SetInvalid();
+};
+
+ScEditViewForwarder::ScEditViewForwarder(EditView* pEditView, Window* pWin)
+ : mpEditView(pEditView),
+ mpWindow(pWin)
+{
+ GrabFocus();
+}
+
+ScEditViewForwarder::~ScEditViewForwarder()
+{
+}
+
+BOOL ScEditViewForwarder::IsValid() const
+{
+ sal_Bool bResult(sal_False);
+ if (mpWindow && mpEditView)
+ {
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+Rectangle ScEditViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (IsValid() && mpEditView->GetEditEngine())
+ {
+ MapMode aMapMode(mpEditView->GetEditEngine()->GetRefMapMode());
+
+ aVisArea = mpWindow->LogicToPixel( mpEditView->GetVisArea(), aMapMode );
+ }
+ else
+ {
+ DBG_ERROR("this EditViewForwarder is no longer valid");
+ }
+ return aVisArea;
+}
+
+Point ScEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ return mpWindow->LogicToPixel( rPoint, rMapMode );
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ return mpWindow->PixelToLogic( rPoint, rMapMode );
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+sal_Bool ScEditViewForwarder::GetSelection( ESelection& rSelection ) const
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ rSelection = mpEditView->GetSelection();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::SetSelection( const ESelection& rSelection )
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->SetSelection(rSelection);
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::Copy()
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->Copy();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::Cut()
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->Cut();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::Paste()
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->Paste();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+void ScEditViewForwarder::GrabFocus()
+{
+}
+
+void ScEditViewForwarder::SetInvalid()
+{
+ mpWindow = NULL;
+ mpEditView = NULL;
+}
+
+// ============================================================================
+
+// ScAccessibleCellTextData: shared data between sub objects of a accessible cell text object
+
+ScAccessibleCellTextData::ScAccessibleCellTextData(ScTabViewShell* pViewShell,
+ const ScAddress& rP, ScSplitPos eSplitPos, ScAccessibleCell* pAccCell)
+ : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
+ mpViewForwarder(NULL),
+ mpEditViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ meSplitPos(eSplitPos),
+ mbViewEditEngine(sal_False),
+ mpAccessibleCell( pAccCell )
+{
+}
+
+ScAccessibleCellTextData::~ScAccessibleCellTextData()
+{
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+ if (mpEditViewForwarder)
+ delete mpEditViewForwarder;
+}
+
+void ScAccessibleCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL; // invalid now
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ if (mpEditViewForwarder)
+ mpEditViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleCellBaseTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessibleCellTextData::Clone() const
+{
+ return new ScAccessibleCellTextData( mpViewShell, aCellPos, meSplitPos, mpAccessibleCell );
+}
+
+void ScAccessibleCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
+{
+// #104893#; don't use the input string
+// ScCellTextData::GetCellText(rCellPos, rText);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ // #104893#; use the displayed string
+ pDoc->GetString(rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText);
+ if (mpViewShell)
+ {
+ const ScViewOptions& aOptions = mpViewShell->GetViewData()->GetOptions();
+ CellType aCellType;
+ pDoc->GetCellType(rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), aCellType);
+ if (aCellType == CELLTYPE_FORMULA && aOptions.GetOption( VOPT_FORMULAS ))
+ {
+ pDoc->GetFormula( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText);
+ }
+ else if (!aOptions.GetOption( VOPT_NULLVALS ))
+ {
+ if ((aCellType == CELLTYPE_VALUE || aCellType == CELLTYPE_FORMULA) && pDoc->GetValue(rCellPos) == 0.0)
+ rText.Erase();
+ }
+ }
+ }
+}
+
+SvxTextForwarder* ScAccessibleCellTextData::GetTextForwarder()
+{
+/* sal_Bool bHasForwarder(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData() &&
+ (mpViewShell->GetViewData()->GetCurPos() == aCellPos) &&
+ (mpViewShell->GetViewData()->HasEditView(meSplitPos)) &&
+ (mpViewShell->GetViewData()->GetEditViewCol() == aCellPos.Col()) &&
+ (mpViewShell->GetViewData()->GetEditViewRow() == aCellPos.Row()))
+ {
+ if (!mbViewEditEngine)
+ {
+ if (pForwarder)
+ DELETEZ( pForwarder );
+ if (pEditEngine)
+ DELETEZ( pEditEngine );
+
+ SCCOL nCol;
+ SCROW nRow;
+ EditView* pEditView;
+ mpViewShell->GetViewData()->GetEditView( meSplitPos, pEditView, nCol, nRow );
+ if (pEditView)
+ {
+ pEditEngine = (ScFieldEditEngine*)pEditView->GetEditEngine();
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ bHasForwarder = sal_True;
+ }
+ }
+ else
+ bHasForwarder = sal_True;
+ }
+ else if (mbViewEditEngine)
+ {
+ // remove Forwarder created with EditEngine from EditView
+ if (pForwarder)
+ DELETEZ( pForwarder );
+ pEditEngine->SetNotifyHdl(Link());
+ // don't delete, because it is the EditEngine of the EditView
+ pEditEngine = NULL;
+ mbViewEditEngine = sal_False;
+ }
+
+ if (!bHasForwarder)*/
+ ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
+
+ ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL );
+ if ( pDoc && pEditEngine && mpViewShell )
+ {
+ long nSizeX, nSizeY;
+ mpViewShell->GetViewData()->GetMergeSizePixel(
+ aCellPos.Col(), aCellPos.Row(), nSizeX, nSizeY);
+
+ Size aSize(nSizeX, nSizeY);
+
+ // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
+ long nIndent = 0;
+ const SvxHorJustifyItem* pHorJustifyItem = static_cast< const SvxHorJustifyItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY ) );
+ SvxCellHorJustify eHorJust = ( pHorJustifyItem ? static_cast< SvxCellHorJustify >( pHorJustifyItem->GetValue() ) : SVX_HOR_JUSTIFY_STANDARD );
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ {
+ const SfxUInt16Item* pIndentItem = static_cast< const SfxUInt16Item* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_INDENT ) );
+ if ( pIndentItem )
+ {
+ nIndent = static_cast< long >( pIndentItem->GetValue() );
+ }
+ }
+
+ const SvxMarginItem* pMarginItem = static_cast< const SvxMarginItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_MARGIN ) );
+ ScViewData* pViewData = mpViewShell->GetViewData();
+ double nPPTX = ( pViewData ? pViewData->GetPPTX() : 0 );
+ double nPPTY = ( pViewData ? pViewData->GetPPTY() : 0 );
+ long nLeftM = ( pMarginItem ? static_cast< long >( ( pMarginItem->GetLeftMargin() + nIndent ) * nPPTX ) : 0 );
+ long nTopM = ( pMarginItem ? static_cast< long >( pMarginItem->GetTopMargin() * nPPTY ) : 0 );
+ long nRightM = ( pMarginItem ? static_cast< long >( pMarginItem->GetRightMargin() * nPPTX ) : 0 );
+ long nBottomM = ( pMarginItem ? static_cast< long >( pMarginItem->GetBottomMargin() * nPPTY ) : 0 );
+ long nWidth = aSize.getWidth() - nLeftM - nRightM;
+ aSize.setWidth( nWidth );
+ aSize.setHeight( aSize.getHeight() - nTopM - nBottomM );
+
+ Window* pWin = mpViewShell->GetWindowByPos( meSplitPos );
+ if ( pWin )
+ {
+ aSize = pWin->PixelToLogic( aSize, pEditEngine->GetRefMapMode() );
+ }
+
+ /* #i19430# Gnopernicus reads text partly if it sticks out of the cell
+ boundaries. This leads to wrong results in cases where the cell text
+ is rotated, because rotation is not taken into account when calcu-
+ lating the visible part of the text. In these cases we will expand
+ the cell size passed as paper size to the edit engine. The function
+ accessibility::AccessibleStaticTextBase::GetParagraphBoundingBox()
+ (see svx/source/accessibility/AccessibleStaticTextBase.cxx) will
+ return the size of the complete text then, which is used to expand
+ the cell bounding box in ScAccessibleCell::GetBoundingBox()
+ (see sc/source/ui/Accessibility/AccessibleCell.cxx). */
+ const SfxInt32Item* pItem = static_cast< const SfxInt32Item* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_ROTATE_VALUE ) );
+ if( pItem && (pItem->GetValue() != 0) )
+ {
+ pEditEngine->SetPaperSize( Size( LONG_MAX, aSize.getHeight() ) );
+ long nTxtWidth = static_cast< long >( pEditEngine->CalcTextWidth() );
+ aSize.setWidth( std::max( aSize.getWidth(), nTxtWidth + 2 ) );
+ }
+ else
+ {
+ // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
+ const SfxBoolItem* pLineBreakItem = static_cast< const SfxBoolItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_LINEBREAK ) );
+ bool bLineBreak = ( pLineBreakItem && pLineBreakItem->GetValue() );
+ if ( !bLineBreak )
+ {
+ long nTxtWidth = static_cast< long >( pEditEngine->CalcTextWidth() );
+ aSize.setWidth( ::std::max( aSize.getWidth(), nTxtWidth ) );
+ }
+ }
+
+ pEditEngine->SetPaperSize( aSize );
+
+ // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
+ if ( eHorJust == SVX_HOR_JUSTIFY_STANDARD && pDoc->HasValueData( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
+ {
+ pEditEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+ }
+
+ Size aTextSize;
+ if ( pWin )
+ {
+ aTextSize = pWin->LogicToPixel( Size( pEditEngine->CalcTextWidth(), pEditEngine->GetTextHeight() ), pEditEngine->GetRefMapMode() );
+ }
+ long nTextWidth = aTextSize.Width();
+ long nTextHeight = aTextSize.Height();
+
+ long nOffsetX = nLeftM;
+ long nDiffX = nTextWidth - nWidth;
+ if ( nDiffX > 0 )
+ {
+ switch ( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_RIGHT:
+ {
+ nOffsetX -= nDiffX;
+ }
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ {
+ nOffsetX -= nDiffX / 2;
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+ }
+
+ long nOffsetY = 0;
+ const SvxVerJustifyItem* pVerJustifyItem = static_cast< const SvxVerJustifyItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_VER_JUSTIFY ) );
+ SvxCellVerJustify eVerJust = ( pVerJustifyItem ? static_cast< SvxCellVerJustify >( pVerJustifyItem->GetValue() ) : SVX_VER_JUSTIFY_STANDARD );
+ switch ( eVerJust )
+ {
+ case SVX_VER_JUSTIFY_STANDARD:
+ case SVX_VER_JUSTIFY_BOTTOM:
+ {
+ nOffsetY = nSizeY - nBottomM - nTextHeight;
+ }
+ break;
+ case SVX_VER_JUSTIFY_CENTER:
+ {
+ nOffsetY = ( nSizeY - nTopM - nBottomM - nTextHeight ) / 2 + nTopM;
+ }
+ break;
+ default:
+ {
+ nOffsetY = nTopM;
+ }
+ break;
+ }
+
+ if ( mpAccessibleCell )
+ {
+ mpAccessibleCell->SetOffset( Point( nOffsetX, nOffsetY ) );
+ }
+
+ pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+ }
+
+ return pForwarder;
+}
+
+SvxViewForwarder* ScAccessibleCellTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScViewForwarder(mpViewShell, meSplitPos, aCellPos);
+ return mpViewForwarder;
+}
+
+SvxEditViewForwarder* ScAccessibleCellTextData::GetEditViewForwarder( sal_Bool /* bCreate */ )
+{
+ //#102219#; there should no EditViewForwarder be, because the cell is now readonly in this interface
+/* if (!mpEditViewForwarder)
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ EditView* pEditView;
+ mpViewShell->GetViewData()->GetEditView( meSplitPos, pEditView, nCol, nRow );
+
+ mpEditViewForwarder = new ScEditViewForwarder(pEditView, mpViewShell->GetWindowByPos(meSplitPos));
+ }
+ else if (bCreate)
+ mpEditViewForwarder->GrabFocus();
+ return mpEditViewForwarder;*/
+ return NULL;
+}
+
+IMPL_LINK(ScAccessibleCellTextData, NotifyHdl, EENotify*, aNotify)
+{
+ if( aNotify )
+ {
+ ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
+
+ if( aHint.get() )
+ GetBroadcaster().Broadcast( *aHint.get() );
+ }
+
+ return 0;
+}
+
+ScDocShell* ScAccessibleCellTextData::GetDocShell(ScTabViewShell* pViewShell)
+{
+ ScDocShell* pDocSh = NULL;
+ if (pViewShell)
+ pDocSh = pViewShell->GetViewData()->GetDocShell();
+ return pDocSh;
+}
+
+
+// ============================================================================
+
+ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditView, Window* pWin)
+ :
+ mpViewForwarder(NULL),
+ mpEditViewForwarder(NULL),
+ mpEditView(pEditView),
+ mpEditEngine(pEditView ? pEditView->GetEditEngine() : 0),
+ mpForwarder(NULL),
+ mpWindow(pWin)
+{
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
+}
+
+ScAccessibleEditObjectTextData::~ScAccessibleEditObjectTextData()
+{
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+ if (mpEditViewForwarder)
+ delete mpEditViewForwarder;
+ if (mpForwarder)
+ delete mpForwarder;
+}
+
+void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpWindow = NULL;
+ mpEditView = NULL;
+ mpEditEngine = NULL;
+ DELETEZ(mpForwarder);
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ if (mpEditViewForwarder)
+ mpEditViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessibleEditObjectTextData::Clone() const
+{
+ return new ScAccessibleEditObjectTextData(mpEditView, mpWindow);
+}
+
+SvxTextForwarder* ScAccessibleEditObjectTextData::GetTextForwarder()
+{
+ if ((!mpForwarder && mpEditView) || (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet()))
+ {
+ if (!mpEditEngine)
+ mpEditEngine = mpEditView->GetEditEngine();
+ if (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet())
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
+ if(!mpForwarder)
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+ }
+ return mpForwarder;
+}
+
+SvxViewForwarder* ScAccessibleEditObjectTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ {
+ // --> OD 2005-12-21 #i49561#
+ mpViewForwarder = new ScEditObjectViewForwarder( mpWindow, mpEditView );
+ // <--
+ }
+ return mpViewForwarder;
+}
+
+SvxEditViewForwarder* ScAccessibleEditObjectTextData::GetEditViewForwarder( sal_Bool bCreate )
+{
+ if (!mpEditViewForwarder && mpEditView)
+ mpEditViewForwarder = new ScEditViewForwarder(mpEditView, mpWindow);
+ if (bCreate)
+ {
+ if (!mpEditView && mpEditViewForwarder)
+ {
+ DELETEZ(mpEditViewForwarder);
+ }
+ else if (mpEditViewForwarder)
+ mpEditViewForwarder->GrabFocus();
+ }
+ return mpEditViewForwarder;
+}
+
+IMPL_LINK(ScAccessibleEditObjectTextData, NotifyHdl, EENotify*, aNotify)
+{
+ if( aNotify )
+ {
+ ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
+
+ if( aHint.get() )
+ GetBroadcaster().Broadcast( *aHint.get() );
+ }
+
+ return 0;
+}
+
+
+// ============================================================================
+
+ScAccessibleEditLineTextData::ScAccessibleEditLineTextData(EditView* pEditView, Window* pWin)
+ :
+ ScAccessibleEditObjectTextData(pEditView, pWin),
+ mbEditEngineCreated(sal_False)
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)pWin;
+
+ if (pTxtWnd)
+ pTxtWnd->InsertAccessibleTextData( *this );
+}
+
+ScAccessibleEditLineTextData::~ScAccessibleEditLineTextData()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ pTxtWnd->RemoveAccessibleTextData( *this );
+
+ if (mbEditEngineCreated && mpEditEngine)
+ {
+ delete mpEditEngine;
+ mpEditEngine = NULL; // #103346# don't access in ScAccessibleEditObjectTextData dtor!
+ }
+ else if (pTxtWnd && pTxtWnd->GetEditView() && pTxtWnd->GetEditView()->GetEditEngine())
+ {
+ // #103346# the NotifyHdl also has to be removed from the ScTextWnd's EditEngine
+ // (it's set in ScAccessibleEditLineTextData::GetTextForwarder, and mpEditEngine
+ // is reset there)
+ pTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link());
+ }
+}
+
+void ScAccessibleEditLineTextData::Dispose()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ pTxtWnd->RemoveAccessibleTextData( *this );
+
+ ResetEditMode();
+ mpWindow = NULL;
+}
+
+ScAccessibleTextData* ScAccessibleEditLineTextData::Clone() const
+{
+ return new ScAccessibleEditLineTextData(mpEditView, mpWindow);
+}
+
+SvxTextForwarder* ScAccessibleEditLineTextData::GetTextForwarder()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ {
+ mpEditView = pTxtWnd->GetEditView();
+ if (mpEditView)
+ {
+ if (mbEditEngineCreated && mpEditEngine)
+ ResetEditMode();
+ mbEditEngineCreated = sal_False;
+
+ mpEditView = pTxtWnd->GetEditView();
+ ScAccessibleEditObjectTextData::GetTextForwarder(); // fill the mpForwarder
+ mpEditEngine = NULL;
+ }
+ else
+ {
+ if (mpEditEngine && !mbEditEngineCreated)
+ ResetEditMode();
+ if (!mpEditEngine)
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ mpEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ mbEditEngineCreated = sal_True;
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+ // pEditEngine->SetUpdateMode( FALSE );
+ mpEditEngine->EnableUndo( FALSE );
+ mpEditEngine->SetRefMapMode( MAP_100TH_MM );
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+
+ mpEditEngine->SetText(pTxtWnd->GetTextString());
+
+ Size aSize(pTxtWnd->GetSizePixel());
+
+ aSize = pTxtWnd->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
+
+ mpEditEngine->SetPaperSize(aSize);
+
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
+ }
+ }
+ }
+ return mpForwarder;
+}
+
+SvxEditViewForwarder* ScAccessibleEditLineTextData::GetEditViewForwarder( sal_Bool bCreate )
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ {
+ mpEditView = pTxtWnd->GetEditView();
+ if (!mpEditView && bCreate)
+ {
+ if ( !pTxtWnd->IsInputActive() )
+ {
+ pTxtWnd->StartEditEngine();
+ pTxtWnd->GrabFocus();
+// pTxtWnd->SetTextString( rText );
+// pTxtWnd->GetEditView()->SetSelection( rSel );
+
+ mpEditView = pTxtWnd->GetEditView();
+ }
+ }
+ }
+
+ return ScAccessibleEditObjectTextData::GetEditViewForwarder(bCreate);
+}
+
+void ScAccessibleEditLineTextData::ResetEditMode()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (mbEditEngineCreated && mpEditEngine)
+ delete mpEditEngine;
+ else if (pTxtWnd && pTxtWnd->GetEditView() && pTxtWnd->GetEditView()->GetEditEngine())
+ pTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link());
+ mpEditEngine = NULL;
+
+ DELETEZ(mpForwarder);
+ DELETEZ(mpEditViewForwarder);
+ DELETEZ(mpViewForwarder);
+ mbEditEngineCreated = sal_False;
+}
+
+void ScAccessibleEditLineTextData::TextChanged()
+{
+ if (mbEditEngineCreated && mpEditEngine)
+ {
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ mpEditEngine->SetText(pTxtWnd->GetTextString());
+ }
+}
+
+void ScAccessibleEditLineTextData::StartEdit()
+{
+ ResetEditMode();
+ mpEditView = NULL;
+
+ // send HINT_BEGEDIT
+ SdrHint aHint(HINT_BEGEDIT);
+ GetBroadcaster().Broadcast( aHint );
+}
+
+void ScAccessibleEditLineTextData::EndEdit()
+{
+ // send HINT_ENDEDIT
+ SdrHint aHint(HINT_ENDEDIT);
+ GetBroadcaster().Broadcast( aHint );
+
+ ResetEditMode();
+ mpEditView = NULL;
+}
+
+
+// ============================================================================
+
+// ScAccessiblePreviewCellTextData: shared data between sub objects of a accessible cell text object
+
+ScAccessiblePreviewCellTextData::ScAccessiblePreviewCellTextData(ScPreviewShell* pViewShell,
+ const ScAddress& rP)
+ : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell)
+{
+}
+
+ScAccessiblePreviewCellTextData::~ScAccessiblePreviewCellTextData()
+{
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+}
+
+void ScAccessiblePreviewCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL; // invalid now
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleCellBaseTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessiblePreviewCellTextData::Clone() const
+{
+ return new ScAccessiblePreviewCellTextData(mpViewShell, aCellPos);
+}
+
+SvxTextForwarder* ScAccessiblePreviewCellTextData::GetTextForwarder()
+{
+ sal_Bool bEditEngineBefore(pEditEngine != NULL);
+
+ ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
+
+ if (!bEditEngineBefore && pEditEngine)
+ {
+ Size aSize(mpViewShell->GetLocationData().GetCellOutputRect(aCellPos).GetSize());
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->PixelToLogic(aSize, pEditEngine->GetRefMapMode());
+ pEditEngine->SetPaperSize(aSize);
+ }
+
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+
+ return pForwarder;
+}
+
+SvxViewForwarder* ScAccessiblePreviewCellTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewCellViewForwarder(mpViewShell, aCellPos);
+ return mpViewForwarder;
+}
+
+//UNUSED2008-05 IMPL_LINK(ScAccessiblePreviewCellTextData, NotifyHdl, EENotify*, aNotify)
+//UNUSED2008-05 {
+//UNUSED2008-05 if( aNotify )
+//UNUSED2008-05 {
+//UNUSED2008-05 ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify);
+//UNUSED2008-05
+//UNUSED2008-05 if( aHint.get() )
+//UNUSED2008-05 GetBroadcaster().Broadcast( *aHint.get() );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+ScDocShell* ScAccessiblePreviewCellTextData::GetDocShell(ScPreviewShell* pViewShell)
+{
+ ScDocShell* pDocSh = NULL;
+ if (pViewShell && pViewShell->GetDocument())
+ pDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ return pDocSh;
+}
+
+
+// ============================================================================
+
+// ScAccessiblePreviewHeaderCellTextData: shared data between sub objects of a accessible cell text object
+
+ScAccessiblePreviewHeaderCellTextData::ScAccessiblePreviewHeaderCellTextData(ScPreviewShell* pViewShell,
+ const String& rText, const ScAddress& rP, sal_Bool bColHeader, sal_Bool bRowHeader)
+ : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ maText(rText),
+ mbColHeader(bColHeader),
+ mbRowHeader(bRowHeader)
+{
+}
+
+ScAccessiblePreviewHeaderCellTextData::~ScAccessiblePreviewHeaderCellTextData()
+{
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+}
+
+void ScAccessiblePreviewHeaderCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL; // invalid now
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleCellBaseTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessiblePreviewHeaderCellTextData::Clone() const
+{
+ return new ScAccessiblePreviewHeaderCellTextData(mpViewShell, maText, aCellPos, mbColHeader, mbRowHeader);
+}
+
+SvxTextForwarder* ScAccessiblePreviewHeaderCellTextData::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pEditEngine = pDoc->CreateFieldEditEngine();
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ }
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+// pEditEngine->SetUpdateMode( FALSE );
+ pEditEngine->EnableUndo( FALSE );
+ if (pDocShell)
+ pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
+ else
+ pEditEngine->SetRefMapMode( MAP_100TH_MM );
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ if (maText.Len() && pEditEngine)
+ {
+
+ if ( mpViewShell )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ Size aSize(mpViewShell->GetLocationData().GetHeaderCellOutputRect(aVisRect, aCellPos, mbColHeader).GetSize());
+ if (pWindow)
+ aSize = pWindow->PixelToLogic(aSize, pEditEngine->GetRefMapMode());
+ pEditEngine->SetPaperSize(aSize);
+ }
+ pEditEngine->SetText( maText );
+ }
+
+ bDataValid = TRUE;
+
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+
+ return pForwarder;
+}
+
+SvxViewForwarder* ScAccessiblePreviewHeaderCellTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewHeaderCellViewForwarder(mpViewShell, aCellPos, mbColHeader, mbRowHeader);
+ return mpViewForwarder;
+}
+
+//UNUSED2008-05 IMPL_LINK(ScAccessiblePreviewHeaderCellTextData, NotifyHdl, EENotify*, aNotify)
+//UNUSED2008-05 {
+//UNUSED2008-05 if( aNotify )
+//UNUSED2008-05 {
+//UNUSED2008-05 ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify);
+//UNUSED2008-05
+//UNUSED2008-05 if( aHint.get() )
+//UNUSED2008-05 GetBroadcaster().Broadcast( *aHint.get() );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+ScDocShell* ScAccessiblePreviewHeaderCellTextData::GetDocShell(ScPreviewShell* pViewShell)
+{
+ ScDocShell* pDocSh = NULL;
+ if (pViewShell && pViewShell->GetDocument())
+ pDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ return pDocSh;
+}
+
+
+// ============================================================================
+
+ScAccessibleHeaderTextData::ScAccessibleHeaderTextData(ScPreviewShell* pViewShell,
+ const EditTextObject* pEditObj, sal_Bool bHeader, SvxAdjust eAdjust)
+ :
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ mpEditEngine(NULL),
+ mpForwarder(NULL),
+ mpDocSh(NULL),
+ mpEditObj(pEditObj),
+ mbHeader(bHeader),
+ mbDataValid(sal_False),
+ meAdjust(eAdjust)
+{
+ if (pViewShell && pViewShell->GetDocument())
+ mpDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ if (mpDocSh)
+ mpDocSh->GetDocument()->AddUnoObject(*this);
+}
+
+ScAccessibleHeaderTextData::~ScAccessibleHeaderTextData()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ if (mpDocSh)
+ mpDocSh->GetDocument()->RemoveUnoObject(*this);
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl(Link());
+ delete mpEditEngine;
+ delete mpForwarder;
+}
+
+ScAccessibleTextData* ScAccessibleHeaderTextData::Clone() const
+{
+ return new ScAccessibleHeaderTextData(mpViewShell, mpEditObj, mbHeader, meAdjust);
+}
+
+void ScAccessibleHeaderTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL;// invalid now
+ mpDocSh = NULL;
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+}
+
+SvxTextForwarder* ScAccessibleHeaderTextData::GetTextForwarder()
+{
+ if (!mpEditEngine)
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, TRUE );
+
+ pHdrEngine->EnableUndo( FALSE );
+ pHdrEngine->SetRefMapMode( MAP_TWIP );
+
+ // default font must be set, independently of document
+ // -> use global pool from module
+
+ SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
+ const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
+ rPattern.FillEditItemSet( &aDefaults );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ aDefaults.Put( SvxAdjustItem( meAdjust, EE_PARA_JUST ) );
+ pHdrEngine->SetDefaults( aDefaults );
+
+ ScHeaderFieldData aData;
+ if (mpViewShell)
+ mpViewShell->FillFieldData(aData);
+ else
+ ScHeaderFooterTextObj::FillDummyFieldData( aData );
+ pHdrEngine->SetData( aData );
+
+ mpEditEngine = pHdrEngine;
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+ }
+
+ if (mbDataValid)
+ return mpForwarder;
+
+ if ( mpViewShell )
+ {
+ Rectangle aVisRect;
+ mpViewShell->GetLocationData().GetHeaderPosition(aVisRect);
+ Size aSize(aVisRect.GetSize());
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
+ mpEditEngine->SetPaperSize(aSize);
+ }
+ if (mpEditObj)
+ mpEditEngine->SetText(*mpEditObj);
+
+ mbDataValid = sal_True;
+ return mpForwarder;
+}
+
+SvxViewForwarder* ScAccessibleHeaderTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewHeaderFooterViewForwarder(mpViewShell, mbHeader);
+ return mpViewForwarder;
+}
+
+
+// ============================================================================
+
+ScAccessibleNoteTextData::ScAccessibleNoteTextData(ScPreviewShell* pViewShell,
+ const String& sText, const ScAddress& aCellPos, sal_Bool bMarkNote)
+ :
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ mpEditEngine(NULL),
+ mpForwarder(NULL),
+ mpDocSh(NULL),
+ msText(sText),
+ maCellPos(aCellPos),
+ mbMarkNote(bMarkNote),
+ mbDataValid(sal_False)
+{
+ if (pViewShell && pViewShell->GetDocument())
+ mpDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ if (mpDocSh)
+ mpDocSh->GetDocument()->AddUnoObject(*this);
+}
+
+ScAccessibleNoteTextData::~ScAccessibleNoteTextData()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ if (mpDocSh)
+ mpDocSh->GetDocument()->RemoveUnoObject(*this);
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl(Link());
+ delete mpEditEngine;
+ delete mpForwarder;
+}
+
+ScAccessibleTextData* ScAccessibleNoteTextData::Clone() const
+{
+ return new ScAccessibleNoteTextData(mpViewShell, msText, maCellPos, mbMarkNote);
+}
+
+void ScAccessibleNoteTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL;// invalid now
+ mpDocSh = NULL;
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+}
+
+SvxTextForwarder* ScAccessibleNoteTextData::GetTextForwarder()
+{
+ if (!mpEditEngine)
+ {
+ if ( mpDocSh )
+ {
+ ScDocument* pDoc = mpDocSh->GetDocument();
+ mpEditEngine = pDoc->CreateFieldEditEngine();
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ mpEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ }
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+// pEditEngine->SetUpdateMode( FALSE );
+ mpEditEngine->EnableUndo( FALSE );
+ if (mpDocSh)
+ mpEditEngine->SetRefDevice(mpDocSh->GetRefDevice());
+ else
+ mpEditEngine->SetRefMapMode( MAP_100TH_MM );
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+ }
+
+ if (mbDataValid)
+ return mpForwarder;
+
+ if (msText.Len() && mpEditEngine)
+ {
+
+ if ( mpViewShell )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ Size aSize(mpViewShell->GetLocationData().GetNoteInRangeOutputRect(aVisRect, mbMarkNote, maCellPos).GetSize());
+ if (pWindow)
+ aSize = pWindow->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
+ mpEditEngine->SetPaperSize(aSize);
+ }
+ mpEditEngine->SetText( msText );
+ }
+
+ mbDataValid = TRUE;
+
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+
+ return mpForwarder;
+}
+
+SvxViewForwarder* ScAccessibleNoteTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewNoteViewForwarder(mpViewShell, maCellPos, mbMarkNote);
+ return mpViewForwarder;
+}
+
+
+// CSV import =================================================================
+
+class ScCsvViewForwarder : public SvxViewForwarder
+{
+ Rectangle maBoundBox;
+ Window* mpWindow;
+
+public:
+ explicit ScCsvViewForwarder( Window* pWindow, const Rectangle& rBoundBox );
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+};
+
+ScCsvViewForwarder::ScCsvViewForwarder( Window* pWindow, const Rectangle& rBoundBox ) :
+ maBoundBox( rBoundBox ),
+ mpWindow( pWindow )
+{
+}
+
+BOOL ScCsvViewForwarder::IsValid() const
+{
+ return mpWindow != NULL;
+}
+
+Rectangle ScCsvViewForwarder::GetVisArea() const
+{
+ return maBoundBox;
+}
+
+Point ScCsvViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if( !mpWindow ) return Point();
+ return mpWindow->LogicToPixel( rPoint, rMapMode );
+}
+
+Point ScCsvViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if( !mpWindow ) return Point();
+ return mpWindow->PixelToLogic( rPoint, rMapMode );
+}
+
+void ScCsvViewForwarder::SetInvalid()
+{
+ mpWindow = NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+ScAccessibleCsvTextData::ScAccessibleCsvTextData(
+ Window* pWindow, EditEngine* pEditEngine,
+ const String& rCellText, const Rectangle& rBoundBox, const Size& rCellSize ) :
+ mpWindow( pWindow ),
+ mpEditEngine( pEditEngine ),
+ maCellText( rCellText ),
+ maBoundBox( rBoundBox ),
+ maCellSize( rCellSize )
+{
+}
+
+ScAccessibleCsvTextData::~ScAccessibleCsvTextData()
+{
+}
+
+void ScAccessibleCsvTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if( nId == SFX_HINT_DYING )
+ {
+ mpWindow = NULL;
+ mpEditEngine = NULL;
+ if (mpViewForwarder.get())
+ mpViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleTextData::Notify( rBC, rHint );
+}
+
+ScAccessibleTextData* ScAccessibleCsvTextData::Clone() const
+{
+ return new ScAccessibleCsvTextData( mpWindow, mpEditEngine, maCellText, maBoundBox, maCellSize );
+}
+
+SvxTextForwarder* ScAccessibleCsvTextData::GetTextForwarder()
+{
+ if( mpEditEngine )
+ {
+ mpEditEngine->SetPaperSize( maCellSize );
+ mpEditEngine->SetText( maCellText );
+ if( !mpTextForwarder.get() )
+ mpTextForwarder.reset( new SvxEditEngineForwarder( *mpEditEngine ) );
+ }
+ else
+ mpTextForwarder.reset( NULL );
+ return mpTextForwarder.get();
+}
+
+SvxViewForwarder* ScAccessibleCsvTextData::GetViewForwarder()
+{
+ if( !mpViewForwarder.get() )
+ mpViewForwarder.reset( new ScCsvViewForwarder( mpWindow, maBoundBox ) );
+ return mpViewForwarder.get();
+}
+
+SvxEditViewForwarder* ScAccessibleCsvTextData::GetEditViewForwarder( sal_Bool /* bCreate */ )
+{
+ return NULL;
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx b/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx
new file mode 100644
index 000000000000..31bf438772d0
--- /dev/null
+++ b/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "DrawModelBroadcaster.hxx"
+#include <svx/svdmodel.hxx>
+#include <svx/unomod.hxx>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+
+ScDrawModelBroadcaster::ScDrawModelBroadcaster( SdrModel *pDrawModel ) :
+ maEventListeners( maListenerMutex ),
+ mpDrawModel( pDrawModel )
+{
+ if (mpDrawModel)
+ StartListening( *mpDrawModel );
+}
+
+ScDrawModelBroadcaster::~ScDrawModelBroadcaster()
+{
+ if (mpDrawModel)
+ EndListening( *mpDrawModel );
+}
+
+void SAL_CALL ScDrawModelBroadcaster::addEventListener( const uno::Reference< document::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ maEventListeners.addInterface( xListener );
+}
+
+void SAL_CALL ScDrawModelBroadcaster::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ maEventListeners.removeInterface( xListener );
+}
+
+void ScDrawModelBroadcaster::Notify( SfxBroadcaster&,
+ const SfxHint& rHint )
+{
+ const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
+ if( !pSdrHint )
+ return;
+
+ document::EventObject aEvent;
+ if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
+ return;
+
+ ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
+ while( aIter.hasMoreElements() )
+ {
+ uno::Reference < document::XEventListener > xListener( aIter.next(), uno::UNO_QUERY );
+ try
+ {
+ xListener->notifyEvent( aEvent );
+ }
+ catch( uno::RuntimeException& r )
+ {
+ (void) r;
+#if OSL_DEBUG_LEVEL > 1
+ ByteString aError( "Runtime exception caught while notifying shape.:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ }
+ }
+}
diff --git a/sc/source/ui/Accessibility/makefile.mk b/sc/source/ui/Accessibility/makefile.mk
new file mode 100644
index 000000000000..32df95750f85
--- /dev/null
+++ b/sc/source/ui/Accessibility/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=accessibility
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/AccessibleContextBase.obj \
+ $(SLO)$/AccessibleTableBase.obj \
+ $(SLO)$/AccessibleDocument.obj \
+ $(SLO)$/AccessibleGlobal.obj \
+ $(SLO)$/AccessibleSpreadsheet.obj \
+ $(SLO)$/AccessibleCell.obj \
+ $(SLO)$/AccessibilityHints.obj \
+ $(SLO)$/AccessibleDocumentBase.obj \
+ $(SLO)$/AccessibleCellBase.obj \
+ $(SLO)$/AccessibleDocumentPagePreview.obj \
+ $(SLO)$/AccessibleFilterMenu.obj \
+ $(SLO)$/AccessibleFilterMenuItem.obj \
+ $(SLO)$/AccessibleFilterTopWindow.obj \
+ $(SLO)$/AccessiblePreviewTable.obj \
+ $(SLO)$/AccessiblePreviewCell.obj \
+ $(SLO)$/AccessiblePreviewHeaderCell.obj \
+ $(SLO)$/AccessiblePageHeader.obj \
+ $(SLO)$/AccessibleText.obj \
+ $(SLO)$/AccessiblePageHeaderArea.obj \
+ $(SLO)$/DrawModelBroadcaster.obj \
+ $(SLO)$/AccessibleEditObject.obj \
+ $(SLO)$/AccessibleDataPilotControl.obj \
+ $(SLO)$/AccessibleCsvControl.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/AccessibleContextBase.obj \
+ $(SLO)$/AccessibleTableBase.obj \
+ $(SLO)$/AccessibleDocument.obj \
+ $(SLO)$/AccessibleGlobal.obj \
+ $(SLO)$/AccessibleSpreadsheet.obj \
+ $(SLO)$/AccessibleCell.obj \
+ $(SLO)$/AccessibleDocumentBase.obj \
+ $(SLO)$/AccessibleCellBase.obj \
+ $(SLO)$/AccessibleDocumentPagePreview.obj \
+ $(SLO)$/AccessibleFilterMenu.obj \
+ $(SLO)$/AccessibleFilterMenuItem.obj \
+ $(SLO)$/AccessibleFilterTopWindow.obj \
+ $(SLO)$/AccessiblePreviewTable.obj \
+ $(SLO)$/AccessiblePreviewCell.obj \
+ $(SLO)$/AccessiblePreviewHeaderCell.obj \
+ $(SLO)$/AccessiblePageHeader.obj \
+ $(SLO)$/AccessiblePageHeaderArea.obj \
+ $(SLO)$/DrawModelBroadcaster.obj \
+ $(SLO)$/AccessibleEditObject.obj \
+ $(SLO)$/AccessibleDataPilotControl.obj \
+ $(SLO)$/AccessibleCsvControl.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/sc/source/ui/app/client.cxx b/sc/source/ui/app/client.cxx
new file mode 100644
index 000000000000..b1cb325ceb69
--- /dev/null
+++ b/sc/source/ui/app/client.cxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/sotref.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdograf.hxx>
+#include <svtools/embedhlp.hxx>
+
+#include "client.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+ScClient::ScClient( ScTabViewShell* pViewShell, Window* pDraw, SdrModel* pSdrModel, SdrOle2Obj* pObj ) :
+ SfxInPlaceClient( pViewShell, pDraw, pObj->GetAspect() ),
+ pModel( pSdrModel ),
+ pGrafEdit( 0 )
+{
+ SetObject( pObj->GetObjRef() );
+}
+
+__EXPORT ScClient::~ScClient()
+{
+}
+
+SdrOle2Obj* ScClient::GetDrawObj()
+{
+ uno::Reference < embed::XEmbeddedObject > xObj = GetObject();
+ SdrOle2Obj* pOle2Obj = NULL;
+ String aName = GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
+
+ USHORT nPages = pModel->GetPageCount();
+ for (USHORT nPNr=0; nPNr<nPages && !pOle2Obj; nPNr++)
+ {
+ SdrPage* pPage = pModel->GetPage(nPNr);
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !pOle2Obj)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ // name from InfoObject is PersistName
+ if ( ((SdrOle2Obj*)pObject)->GetPersistName() == aName )
+ pOle2Obj = (SdrOle2Obj*)pObject;
+ }
+ pObject = aIter.Next();
+ }
+ }
+ return pOle2Obj;
+}
+
+void __EXPORT ScClient::RequestNewObjectArea( Rectangle& aLogicRect )
+{
+ SfxViewShell* pSfxViewSh = GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh );
+ if (!pViewSh)
+ {
+ DBG_ERROR("Wrong ViewShell");
+ return;
+ }
+
+ Rectangle aOldRect = GetObjArea();
+ SdrOle2Obj* pDrawObj = GetDrawObj();
+ if ( pDrawObj )
+ {
+ if ( pDrawObj->IsResizeProtect() )
+ aLogicRect.SetSize( aOldRect.GetSize() );
+
+ if ( pDrawObj->IsMoveProtect() )
+ aLogicRect.SetPos( aOldRect.TopLeft() );
+ }
+
+ USHORT nTab = pViewSh->GetViewData()->GetTabNo();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
+ if ( pPage && aLogicRect != aOldRect )
+ {
+ Point aPos;
+ Size aSize = pPage->GetSize();
+ if ( aSize.Width() < 0 )
+ {
+ aPos.X() = aSize.Width() + 1; // negative
+ aSize.Width() = -aSize.Width(); // positive
+ }
+ Rectangle aPageRect( aPos, aSize );
+
+ if (aLogicRect.Right() > aPageRect.Right())
+ {
+ long nDiff = aLogicRect.Right() - aPageRect.Right();
+ aLogicRect.Left() -= nDiff;
+ aLogicRect.Right() -= nDiff;
+ }
+ if (aLogicRect.Bottom() > aPageRect.Bottom())
+ {
+ long nDiff = aLogicRect.Bottom() - aPageRect.Bottom();
+ aLogicRect.Top() -= nDiff;
+ aLogicRect.Bottom() -= nDiff;
+ }
+
+ if (aLogicRect.Left() < aPageRect.Left())
+ {
+ long nDiff = aLogicRect.Left() - aPageRect.Left();
+ aLogicRect.Right() -= nDiff;
+ aLogicRect.Left() -= nDiff;
+ }
+ if (aLogicRect.Top() < aPageRect.Top())
+ {
+ long nDiff = aLogicRect.Top() - aPageRect.Top();
+ aLogicRect.Bottom() -= nDiff;
+ aLogicRect.Top() -= nDiff;
+ }
+ }
+}
+
+void __EXPORT ScClient::ObjectAreaChanged()
+{
+ SfxViewShell* pSfxViewSh = GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh );
+ if (!pViewSh)
+ {
+ DBG_ERROR("Wrong ViewShell");
+ return;
+ }
+
+ // Position und Groesse ins Dokument uebernehmen
+ SdrOle2Obj* pDrawObj = GetDrawObj();
+ if (pDrawObj)
+ {
+ pDrawObj->SetLogicRect( GetScaledObjArea() );
+
+ // set document modified (SdrModel::SetChanged is not used)
+ // TODO/LATER: is there a reason that this code is not executed in Draw?
+// SfxViewShell* pSfxViewSh = GetViewShell();
+// ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh );
+ if (pViewSh)
+ pViewSh->GetViewData()->GetDocShell()->SetDrawModified();
+ }
+
+ if (pDrawObj)
+ pViewSh->ScrollToObject( pDrawObj );
+}
+
+void __EXPORT ScClient::ViewChanged()
+{
+ if ( GetAspect() == embed::Aspects::MSOLE_ICON )
+ {
+ // the iconified object seems not to need such a scaling handling
+ // since the replacement image and the size a completely controlled by the container
+ // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here
+
+ return;
+ }
+
+ uno::Reference < embed::XEmbeddedObject > xObj = GetObject();
+
+ // TODO/LEAN: working with Visual Area can switch object to running state
+ awt::Size aSz;
+ try {
+ aSz = xObj->getVisualAreaSize( GetAspect() );
+ } catch ( embed::NoVisualAreaSizeException& )
+ {
+ DBG_ERROR("The visual area size must be available!\n");
+ }
+
+ MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( GetAspect() ) );
+ Size aVisSize = OutputDevice::LogicToLogic( Size( aSz.Width, aSz.Height ), aMapUnit, MAP_100TH_MM );
+
+ // Groesse ins Dokument uebernehmen
+ SdrOle2Obj* pDrawObj = GetDrawObj();
+ if (pDrawObj)
+ {
+ Rectangle aLogicRect = pDrawObj->GetLogicRect();
+ Fraction aFractX = GetScaleWidth();
+ Fraction aFractY = GetScaleHeight();
+ aFractX *= aVisSize.Width();
+ aFractY *= aVisSize.Height();
+ aVisSize = Size( (long) aFractX, (long) aFractY ); // skaliert fuer Draw-Model
+
+ // pClientData->SetObjArea vor pDrawObj->SetLogicRect, damit keine
+ // falschen Skalierungen ausgerechnet werden:
+ //Rectangle aObjArea = aLogicRect;
+ //aObjArea.SetSize( aVisSize ); // Dokument-Groesse vom Server
+ //SetObjArea( aObjArea );
+
+ SfxViewShell* pSfxViewSh = GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh );
+ if ( pViewSh )
+ {
+ Window* pWin = pViewSh->GetActiveWin();
+ if ( pWin->LogicToPixel( aVisSize ) != pWin->LogicToPixel( aLogicRect.GetSize() ) )
+ {
+ aLogicRect.SetSize( aVisSize );
+ pDrawObj->SetLogicRect( aLogicRect );
+
+ // set document modified (SdrModel::SetChanged is not used)
+ pViewSh->GetViewData()->GetDocShell()->SetDrawModified();
+ }
+ }
+ }
+}
+
+void __EXPORT ScClient::MakeVisible()
+{
+ SdrOle2Obj* pDrawObj = GetDrawObj();
+ if (pDrawObj)
+ {
+ SfxViewShell* pSfxViewSh = GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh );
+ if (pViewSh)
+ pViewSh->ScrollToObject( pDrawObj );
+ }
+}
+
diff --git a/sc/source/ui/app/drwtrans.cxx b/sc/source/ui/app/drwtrans.cxx
new file mode 100644
index 000000000000..b256233d7394
--- /dev/null
+++ b/sc/source/ui/app/drwtrans.cxx
@@ -0,0 +1,804 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/streamwrap.hxx>
+
+#include <svx/unomodel.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <comphelper/storagehelper.hxx>
+
+#include <svtools/embedtransfer.hxx>
+#include <sot/storage.hxx>
+#include <vcl/virdev.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdxcgv.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/itempool.hxx>
+#include <svl/urlbmk.hxx>
+#include <tools/urlobj.hxx>
+#include <vos/mutex.hxx>
+
+#include "drwtrans.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "drawview.hxx"
+#include "viewdata.hxx"
+#include "scmod.hxx"
+
+// #108584#
+#include "scitems.hxx"
+
+// #108584#
+#include <editeng/eeitem.hxx>
+
+// #108584#
+#include <editeng/fhgtitem.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define SCDRAWTRANS_TYPE_EMBOBJ 1
+#define SCDRAWTRANS_TYPE_DRAWMODEL 2
+#define SCDRAWTRANS_TYPE_DOCUMENT 3
+
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+ScDrawTransferObj::ScDrawTransferObj( SdrModel* pClipModel, ScDocShell* pContainerShell,
+ const TransferableObjectDescriptor& rDesc ) :
+ pModel( pClipModel ),
+ aObjDesc( rDesc ),
+ pBookmark( NULL ),
+ bGraphic( FALSE ),
+ bGrIsBit( FALSE ),
+ bOleObj( FALSE ),
+ pDragSourceView( NULL ),
+ nDragSourceFlags( 0 ),
+ bDragWasInternal( FALSE ),
+ nSourceDocID( 0 )
+{
+ //
+ // check what kind of objects are contained
+ //
+
+ SdrPage* pPage = pModel->GetPage(0);
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ if (pObject && !aIter.Next()) // exactly one object?
+ {
+ //
+ // OLE object
+ //
+
+ UINT16 nSdrObjKind = pObject->GetObjIdentifier();
+ if (nSdrObjKind == OBJ_OLE2)
+ {
+ // if object has no persistence it must be copied as a part of document
+ try
+ {
+ uno::Reference< embed::XEmbedPersist > xPersObj( ((SdrOle2Obj*)pObject)->GetObjRef(), uno::UNO_QUERY );
+ if ( xPersObj.is() && xPersObj->hasEntry() )
+ bOleObj = TRUE;
+ }
+ catch( uno::Exception& )
+ {}
+ // aOleData is initialized later
+ }
+
+ //
+ // Graphic object
+ //
+
+ if (nSdrObjKind == OBJ_GRAF)
+ {
+ bGraphic = TRUE;
+ if ( ((SdrGrafObj*)pObject)->GetGraphic().GetType() == GRAPHIC_BITMAP )
+ bGrIsBit = TRUE;
+ }
+
+ //
+ // URL button
+ //
+
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject);
+ if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
+ {
+ uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
+ DBG_ASSERT( xControlModel.is(), "uno control without model" );
+ if ( xControlModel.is() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
+
+ rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" );
+ rtl::OUString sPropTargetURL = rtl::OUString::createFromAscii( "TargetURL" );
+ rtl::OUString sPropLabel = rtl::OUString::createFromAscii( "Label" );
+
+ if(xInfo->hasPropertyByName( sPropButtonType ))
+ {
+ uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
+ form::FormButtonType eTmp;
+ if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
+ {
+ // URL
+ if(xInfo->hasPropertyByName( sPropTargetURL ))
+ {
+ aAny = xPropSet->getPropertyValue( sPropTargetURL );
+ rtl::OUString sTmp;
+ if ( (aAny >>= sTmp) && sTmp.getLength() )
+ {
+ String aUrl = sTmp;
+ String aAbs;
+ const SfxMedium* pMedium;
+ if (pContainerShell && (pMedium = pContainerShell->GetMedium()) != NULL)
+ {
+ bool bWasAbs = true;
+ aAbs = pMedium->GetURLObject().smartRel2Abs( aUrl, bWasAbs ).
+ GetMainURL(INetURLObject::NO_DECODE);
+ // full path as stored INetBookmark must be encoded
+ }
+ else
+ aAbs = aUrl;
+
+ // Label
+ String aLabel;
+ if(xInfo->hasPropertyByName( sPropLabel ))
+ {
+ aAny = xPropSet->getPropertyValue( sPropLabel );
+ if ( (aAny >>= sTmp) && sTmp.getLength() )
+ {
+ aLabel = String(sTmp);
+ }
+ }
+ pBookmark = new INetBookmark( aAbs, aLabel );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // get size for object descriptor
+ //
+
+ // #i71538# use complete SdrViews
+ // SdrExchangeView aView(pModel);
+ SdrView aView(pModel);
+ SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
+ aView.MarkAllObj(pPv);
+ aSrcSize = aView.GetAllMarkedRect().GetSize();
+
+ if ( bOleObj ) // single OLE object
+ {
+ SdrOle2Obj* pObj = GetSingleObject();
+ if ( pObj && pObj->GetObjRef().is() )
+ SvEmbedTransferHelper::FillTransferableObjectDescriptor( aObjDesc, pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() );
+ }
+
+ aObjDesc.maSize = aSrcSize;
+ PrepareOLE( aObjDesc );
+
+ //
+ // remember a unique ID of the source document
+ //
+ if ( pContainerShell )
+ {
+ const ScDocument* pDoc = pContainerShell->GetDocument();
+ if ( pDoc )
+ nSourceDocID = pDoc->GetDocumentID();
+ }
+}
+
+ScDrawTransferObj::~ScDrawTransferObj()
+{
+ Application::GetSolarMutex().acquire(); //! ???
+
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetClipData().pDrawClipboard == this )
+ {
+ DBG_ERROR("ScDrawTransferObj wasn't released");
+ pScMod->SetClipObject( NULL, NULL );
+ }
+ if ( pScMod->GetDragData().pDrawTransfer == this )
+ {
+ DBG_ERROR("ScDrawTransferObj wasn't released");
+ pScMod->ResetDragObject();
+ }
+
+ aOleData = TransferableDataHelper(); // clear before releasing the mutex
+ aDocShellRef.Clear();
+
+ delete pModel;
+ aDrawPersistRef.Clear(); // after the model
+
+ delete pBookmark;
+ delete pDragSourceView;
+
+ Application::GetSolarMutex().release(); //! ???
+}
+
+// static
+ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard( Window* )
+{
+ ScDrawTransferObj* pObj = SC_MOD()->GetClipData().pDrawClipboard;
+ return pObj;
+}
+
+BOOL lcl_HasOnlyControls( SdrModel* pModel )
+{
+ BOOL bOnlyControls = FALSE; // default if there are no objects
+
+ if ( pModel )
+ {
+ SdrPage* pPage = pModel->GetPage(0);
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObj = aIter.Next();
+ if ( pObj )
+ {
+ bOnlyControls = TRUE; // only set if there are any objects at all
+ while ( pObj )
+ {
+ if (!pObj->ISA(SdrUnoObj))
+ {
+ bOnlyControls = FALSE;
+ break;
+ }
+ pObj = aIter.Next();
+ }
+ }
+ }
+ }
+
+ return bOnlyControls;
+}
+
+void ScDrawTransferObj::AddSupportedFormats()
+{
+ if ( bGrIsBit ) // single bitmap graphic
+ {
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_SVXB );
+ AddFormat( SOT_FORMAT_BITMAP );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ }
+ else if ( bGraphic ) // other graphic
+ {
+ // #i25616#
+ AddFormat( SOT_FORMATSTR_ID_DRAWING );
+
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_SVXB );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ AddFormat( SOT_FORMAT_BITMAP );
+ }
+ else if ( pBookmark ) // url button
+ {
+// AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_SOLK );
+ AddFormat( SOT_FORMAT_STRING );
+ AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
+ AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
+ AddFormat( SOT_FORMATSTR_ID_DRAWING );
+ }
+ else if ( bOleObj ) // single OLE object
+ {
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+
+ if ( !aOleData.GetTransferable().is() )
+ {
+ SdrOle2Obj* pObj = GetSingleObject();
+ if ( pObj && pObj->GetObjRef().is() )
+ aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ;
+ }
+ if ( aOleData.GetTransferable().is() )
+ {
+ // get format list from object snapshot
+ // (this must be after inserting the default formats!)
+
+ DataFlavorExVector aVector( aOleData.GetDataFlavorExVector() );
+ DataFlavorExVector::iterator aIter( aVector.begin() ), aEnd( aVector.end() );
+
+ while( aIter != aEnd )
+ AddFormat( *aIter++ );
+ }
+ }
+ else // any drawing objects
+ {
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_DRAWING );
+
+ // #103556# leave out bitmap and metafile if there are only controls
+ if ( !lcl_HasOnlyControls( pModel ) )
+ {
+ AddFormat( SOT_FORMAT_BITMAP );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ }
+ }
+
+// if( pImageMap )
+// AddFormat( SOT_FORMATSTR_ID_SVIM );
+}
+
+sal_Bool ScDrawTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ sal_Bool bOK = sal_False;
+ sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
+
+ if ( bOleObj && nFormat != SOT_FORMAT_GDIMETAFILE )
+ {
+ if ( !aOleData.GetTransferable().is() )
+ {
+ SdrOle2Obj* pObj = GetSingleObject();
+ if ( pObj && pObj->GetObjRef().is() )
+ aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ;
+ }
+
+ if( aOleData.GetTransferable().is() && aOleData.HasFormat( rFlavor ) )
+ {
+ ULONG nOldSwapMode = 0;
+
+ if( pModel )
+ {
+ nOldSwapMode = pModel->GetSwapGraphicsMode();
+ pModel->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE );
+ }
+
+ bOK = SetAny( aOleData.GetAny( rFlavor ), rFlavor );
+
+ if( pModel )
+ pModel->SetSwapGraphicsMode( nOldSwapMode );
+
+ return bOK;
+ }
+ }
+
+ if( HasFormat( nFormat ) )
+ {
+ if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
+ {
+ bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
+ }
+ else if ( nFormat == SOT_FORMATSTR_ID_DRAWING )
+ {
+ bOK = SetObject( pModel, SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor );
+ }
+ else if ( nFormat == SOT_FORMAT_BITMAP || nFormat == SOT_FORMAT_GDIMETAFILE )
+ {
+ // #i71538# use complete SdrViews
+ // SdrExchangeView aView( pModel );
+ SdrView aView( pModel );
+ SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
+ DBG_ASSERT( pPv, "pPv not there..." );
+ aView.MarkAllObj( pPv );
+ if ( nFormat == SOT_FORMAT_GDIMETAFILE )
+ bOK = SetGDIMetaFile( aView.GetAllMarkedMetaFile( TRUE ), rFlavor );
+ else
+ bOK = SetBitmap( aView.GetAllMarkedBitmap( TRUE ), rFlavor );
+ }
+ else if ( nFormat == SOT_FORMATSTR_ID_SVXB )
+ {
+ // only enabled for single graphics object
+
+ SdrPage* pPage = pModel->GetPage(0);
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ if (pObject && pObject->GetObjIdentifier() == OBJ_GRAF)
+ {
+ SdrGrafObj* pGraphObj = (SdrGrafObj*) pObject;
+ bOK = SetGraphic( pGraphObj->GetGraphic(), rFlavor );
+ }
+ }
+ }
+ else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ {
+ if ( bOleObj ) // single OLE object
+ {
+ SdrOle2Obj* pObj = GetSingleObject();
+ if ( pObj && pObj->GetObjRef().is() )
+ {
+ bOK = SetObject( pObj->GetObjRef().get(), SCDRAWTRANS_TYPE_EMBOBJ, rFlavor );
+ }
+ }
+ else // create object from contents
+ {
+ //TODO/LATER: needs new Format, because now single OLE and "this" are different
+ InitDocShell(); // set aDocShellRef
+
+ SfxObjectShell* pEmbObj = aDocShellRef;
+ bOK = SetObject( pEmbObj, SCDRAWTRANS_TYPE_DOCUMENT, rFlavor );
+ }
+ }
+ else if( pBookmark )
+ {
+ bOK = SetINetBookmark( *pBookmark, rFlavor );
+ }
+ }
+ return bOK;
+}
+
+sal_Bool ScDrawTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
+ const ::com::sun::star::datatransfer::DataFlavor& /* rFlavor */ )
+{
+ // called from SetObject, put data into stream
+
+ sal_Bool bRet = sal_False;
+ switch (nUserObjectId)
+ {
+ case SCDRAWTRANS_TYPE_DRAWMODEL:
+ {
+ SdrModel* pDrawModel = (SdrModel*)pUserObject;
+ rxOStm->SetBufferSize( 0xff00 );
+
+ // #108584#
+ // for the changed pool defaults from drawing layer pool set those
+ // attributes as hard attributes to preserve them for saving
+ const SfxItemPool& rItemPool = pModel->GetItemPool();
+ const SvxFontHeightItem& rDefaultFontHeight = (const SvxFontHeightItem&)rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT);
+
+ // SW should have no MasterPages
+ DBG_ASSERT(0L == pModel->GetMasterPageCount(), "SW with MasterPages (!)");
+
+ for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++)
+ {
+ const SdrPage* pPage = pModel->GetPage(a);
+ SdrObjListIter aIter(*pPage, IM_DEEPNOGROUPS);
+
+ while(aIter.IsMore())
+ {
+ SdrObject* pObj = aIter.Next();
+ const SvxFontHeightItem& rItem = (const SvxFontHeightItem&)pObj->GetMergedItem(EE_CHAR_FONTHEIGHT);
+
+ if(rItem.GetHeight() == rDefaultFontHeight.GetHeight())
+ {
+ pObj->SetMergedItem(rDefaultFontHeight);
+ }
+ }
+ }
+
+ {
+ com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
+ if( SvxDrawingLayerExport( pDrawModel, xDocOut ) )
+ rxOStm->Commit();
+ }
+
+ bRet = ( rxOStm->GetError() == ERRCODE_NONE );
+ }
+ break;
+
+ case SCDRAWTRANS_TYPE_EMBOBJ:
+ {
+ // impl. for "single OLE"
+ embed::XEmbeddedObject* pEmbObj = (embed::XEmbeddedObject*) pUserObject;
+
+ ::utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ uno::Reference< embed::XStorage > xWorkStore =
+ ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
+
+ uno::Reference < embed::XEmbedPersist > xPers( (embed::XVisualObject*)pEmbObj, uno::UNO_QUERY );
+ if ( xPers.is() )
+ {
+ try
+ {
+ uno::Sequence < beans::PropertyValue > aSeq;
+ ::rtl::OUString aDummyName = ::rtl::OUString::createFromAscii("Dummy");
+ xPers->storeToEntry( xWorkStore, aDummyName, aSeq, aSeq );
+ if ( xWorkStore->isStreamElement( aDummyName ) )
+ {
+ uno::Reference < io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
+ uno::Reference < io::XStream > xNewStream = xWorkStore->openStreamElement( aDummyName, embed::ElementModes::READ );
+ ::comphelper::OStorageHelper::CopyInputToOutput( xNewStream->getInputStream(), xDocOut );
+ }
+ else
+ {
+ uno::Reference < io::XStream > xDocStr( new utl::OStreamWrapper( *rxOStm ) );
+ uno::Reference< embed::XStorage > xDocStg = ::comphelper::OStorageHelper::GetStorageFromStream( xDocStr );
+ uno::Reference < embed::XStorage > xNewStg = xWorkStore->openStorageElement( aDummyName, embed::ElementModes::READ );
+ xNewStg->copyToStorage( xDocStg );
+ uno::Reference < embed::XTransactedObject > xTrans( xDocStg, uno::UNO_QUERY );
+ if ( xTrans.is() )
+ xTrans->commit();
+ }
+
+ rxOStm->Commit();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ break;
+ }
+ case SCDRAWTRANS_TYPE_DOCUMENT:
+ {
+ // impl. for "DocShell"
+ SfxObjectShell* pEmbObj = (SfxObjectShell*) pUserObject;
+
+ try
+ {
+ ::utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ uno::Reference< embed::XStorage > xWorkStore =
+ ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
+
+ // write document storage
+ pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False );
+
+ // mba: no relative ULRs for clipboard!
+ SfxMedium aMedium( xWorkStore, String() );
+ bRet = pEmbObj->DoSaveObjectAs( aMedium, FALSE );
+ pEmbObj->DoSaveCompleted();
+
+ uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ xTransact->commit();
+
+ SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
+ if( pSrcStm )
+ {
+ rxOStm->SetBufferSize( 0xff00 );
+ *rxOStm << *pSrcStm;
+ delete pSrcStm;
+ }
+
+ bRet = TRUE;
+
+ xWorkStore->dispose();
+ xWorkStore = uno::Reference < embed::XStorage >();
+ rxOStm->Commit();
+ }
+ catch ( uno::Exception& )
+ {}
+
+ bRet = ( rxOStm->GetError() == ERRCODE_NONE );
+ }
+ break;
+
+ default:
+ DBG_ERROR("unknown object id");
+ }
+ return bRet;
+}
+
+void ScDrawTransferObj::ObjectReleased()
+{
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetClipData().pDrawClipboard == this )
+ pScMod->SetClipObject( NULL, NULL );
+
+ TransferableHelper::ObjectReleased();
+}
+
+void ScDrawTransferObj::DragFinished( sal_Int8 nDropAction )
+{
+ if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
+ {
+ // move: delete source objects
+
+ if ( pDragSourceView )
+ pDragSourceView->DeleteMarked();
+ }
+
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetDragData().pDrawTransfer == this )
+ pScMod->ResetDragObject();
+
+ DELETEZ( pDragSourceView );
+
+ TransferableHelper::DragFinished( nDropAction );
+}
+
+void ScDrawTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
+{
+ aDrawPersistRef = rRef;
+}
+
+void lcl_InitMarks( SdrMarkView& rDest, const SdrMarkView& rSource, SCTAB nTab )
+{
+ rDest.ShowSdrPage(rDest.GetModel()->GetPage(nTab));
+ SdrPageView* pDestPV = rDest.GetSdrPageView();
+ DBG_ASSERT(pDestPV,"PageView ?");
+
+ const SdrMarkList& rMarkList = rSource.GetMarkedObjectList();
+ ULONG nCount = rMarkList.GetMarkCount();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ rDest.MarkObj(pObj, pDestPV);
+ }
+}
+
+void ScDrawTransferObj::SetDragSource( ScDrawView* pView )
+{
+ DELETEZ( pDragSourceView );
+ pDragSourceView = new SdrView( pView->GetModel() );
+ lcl_InitMarks( *pDragSourceView, *pView, pView->GetTab() );
+
+ //! add as listener with document, delete pDragSourceView if document gone
+}
+
+void ScDrawTransferObj::SetDragSourceObj( SdrObject* pObj, SCTAB nTab )
+{
+ DELETEZ( pDragSourceView );
+ pDragSourceView = new SdrView( pObj->GetModel() );
+ pDragSourceView->ShowSdrPage(pDragSourceView->GetModel()->GetPage(nTab));
+ SdrPageView* pPV = pDragSourceView->GetSdrPageView();
+ pDragSourceView->MarkObj(pObj, pPV);
+
+ //! add as listener with document, delete pDragSourceView if document gone
+}
+
+void ScDrawTransferObj::SetDragSourceFlags( USHORT nFlags )
+{
+ nDragSourceFlags = nFlags;
+}
+
+void ScDrawTransferObj::SetDragWasInternal()
+{
+ bDragWasInternal = TRUE;
+}
+
+SdrOle2Obj* ScDrawTransferObj::GetSingleObject()
+{
+ // if single OLE object was copied, get its object
+
+ SdrPage* pPage = pModel->GetPage(0);
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ if (pObject && pObject->GetObjIdentifier() == OBJ_OLE2)
+ {
+ return (SdrOle2Obj*) pObject;
+ }
+ }
+
+ return NULL;
+}
+
+//
+// initialize aDocShellRef with a live document from the ClipDoc
+//
+
+void ScDrawTransferObj::InitDocShell()
+{
+ if ( !aDocShellRef.Is() )
+ {
+ ScDocShell* pDocSh = new ScDocShell;
+ aDocShellRef = pDocSh; // ref must be there before InitNew
+
+ pDocSh->DoInitNew(NULL);
+
+ ScDocument* pDestDoc = pDocSh->GetDocument();
+ pDestDoc->InitDrawLayer( pDocSh );
+
+ SdrModel* pDestModel = pDestDoc->GetDrawLayer();
+ // #i71538# use complete SdrViews
+ // SdrExchangeView aDestView( pDestModel );
+ SdrView aDestView( pDestModel );
+ aDestView.ShowSdrPage(aDestView.GetModel()->GetPage(0));
+ aDestView.Paste( *pModel, Point( aSrcSize.Width()/2, aSrcSize.Height()/2 ) );
+
+ // put objects to right layer (see ScViewFunc::PasteDataFormat for SOT_FORMATSTR_ID_DRAWING)
+
+ SdrPage* pPage = pDestModel->GetPage(0);
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->ISA(SdrUnoObj) )
+ pObject->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pObject->NbcSetLayer(SC_LAYER_FRONT);
+ pObject = aIter.Next();
+ }
+ }
+
+ Point aTmpPoint;
+ Rectangle aDestArea( aTmpPoint, aSrcSize );
+ pDocSh->SetVisArea( aDestArea );
+
+ ScViewOptions aViewOpt( pDestDoc->GetViewOptions() );
+ aViewOpt.SetOption( VOPT_GRID, FALSE );
+ pDestDoc->SetViewOptions( aViewOpt );
+
+ ScViewData aViewData( pDocSh, NULL );
+ aViewData.SetTabNo( 0 );
+ aViewData.SetScreen( aDestArea );
+ aViewData.SetCurX( 0 );
+ aViewData.SetCurY( 0 );
+ pDocSh->UpdateOle(&aViewData, TRUE);
+ }
+}
+
+const com::sun::star::uno::Sequence< sal_Int8 >& ScDrawTransferObj::getUnoTunnelId()
+{
+ static com::sun::star::uno::Sequence< sal_Int8 > aSeq;
+ if( !aSeq.getLength() )
+ {
+ static osl::Mutex aCreateMutex;
+ osl::Guard< osl::Mutex > aGuard( aCreateMutex );
+ aSeq.realloc( 16 );
+ rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
+ }
+ return aSeq;
+}
+
+sal_Int64 SAL_CALL ScDrawTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException )
+{
+ sal_Int64 nRet;
+ if( ( rId.getLength() == 16 ) &&
+ ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
+ {
+ nRet = reinterpret_cast< sal_Int64 >( this );
+ }
+ else
+ nRet = TransferableHelper::getSomething(rId);
+ return nRet;
+}
+
+
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
new file mode 100644
index 000000000000..55aa0986d2ec
--- /dev/null
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -0,0 +1,3826 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/wghtitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/sound.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/help.hxx>
+#include <vcl/cursor.hxx>
+#include <tools/urlobj.hxx>
+#include <formula/formulahelper.hxx>
+
+#include "inputwin.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "uiitems.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "patattr.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "editutil.hxx"
+#include "collect.hxx"
+#include "appoptio.hxx"
+#include "docoptio.hxx"
+#include "validat.hxx"
+#include "userlist.hxx"
+#include "rfindlst.hxx"
+#include "inputopt.hxx"
+#include "cell.hxx" // fuer Formel-Preview
+#include "compiler.hxx" // fuer Formel-Preview
+#include "editable.hxx"
+#include "funcdesc.hxx"
+
+#define _INPUTHDL_CXX
+#include "inputhdl.hxx"
+
+// max. Ranges im RangeFinder
+#define RANGEFIND_MAX 32
+
+using namespace formula;
+
+// STATIC DATA -----------------------------------------------------------
+
+BOOL ScInputHandler::bOptLoaded = FALSE; // App-Optionen ausgewertet
+BOOL ScInputHandler::bAutoComplete = FALSE; // wird in KeyInput gesetzt
+
+// delimiters (in addition to ScEditUtil) needed for range finder:
+// only characters that are allowed in formulas next to references
+// and the quotation mark (so string constants can be skipped)
+
+static const sal_Char __FAR_DATA pMinDelimiters[] = " !\"";
+
+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;
+
+// String aDelimiters = pEngine->GetWordDelimiters();
+ String aDelimiters = ScEditUtil::ModifyDelimiters(
+ String::CreateFromAscii( pMinDelimiters ) );
+
+ xub_StrLen nColon = aDelimiters.Search(':');
+ if ( nColon != STRING_NOTFOUND )
+ aDelimiters.Erase( nColon, 1 ); // Delimiter ohne Doppelpunkt
+ xub_StrLen nDot = aDelimiters.Search(cSheetSep);
+ if ( nDot != STRING_NOTFOUND )
+ aDelimiters.Erase( nDot, 1 ); // Delimiter ohne Punkt
+
+ const sal_Unicode* pChar = rFormula.GetBuffer();
+ xub_StrLen nLen = rFormula.Len();
+ xub_StrLen nPos = 0;
+ xub_StrLen nStart = 0;
+ USHORT nCount = 0;
+ ScRange aRange;
+ while ( nPos < nLen && nCount < RANGEFIND_MAX )
+ {
+ // Trenner ueberlesen
+ while ( nPos<nLen && ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
+ {
+ if ( pChar[nPos] == '"' ) // String
+ {
+ ++nPos;
+ while (nPos<nLen && pChar[nPos] != '"') // bis zum Ende ueberlesen
+ ++nPos;
+ }
+ ++nPos; // Trennzeichen oder schliessender Quote
+ }
+
+ // Text zwischen Trennern
+ nStart = nPos;
+handle_r1c1:
+ while ( nPos<nLen && !ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
+ ++nPos;
+
+ // for R1C1 '-' in R[-]... or C[-]... are not delimiters
+ // Nothing heroic here to ensure that there are '[]' around a negative
+ // integer. we need to clean up this code.
+ if( nPos < nLen && nPos > 0 &&
+ '-' == pChar[nPos] && '[' == pChar[nPos-1] &&
+ NULL != pDoc &&
+ formula::FormulaGrammar::CONV_XL_R1C1 == pDoc->GetAddressConvention() )
+ {
+ nPos++;
+ goto handle_r1c1;
+ }
+
+ if ( nPos > nStart )
+ {
+ String aTest = rFormula.Copy( nStart, nPos-nStart );
+ const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
+ USHORT nFlags = aRange.ParseAny( aTest, pDoc, aAddrDetails );
+ if ( nFlags & SCA_VALID )
+ {
+ // Tabelle setzen, wenn nicht angegeben
+ if ( (nFlags & SCA_TAB_3D) == 0 )
+ aRange.aStart.SetTab( pActiveViewSh->GetViewData()->GetTabNo() );
+ if ( (nFlags & SCA_TAB2_3D) == 0 )
+ aRange.aEnd.SetTab( aRange.aStart.Tab() );
+
+ if ( ( nFlags & ( SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2 ) ) == 0 )
+ {
+ // #i73766# if a single ref was parsed, set the same "abs" flags for ref2,
+ // so Format doesn't output a double ref because of different flags.
+ USHORT nAbsFlags = nFlags & ( SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE );
+ nFlags |= nAbsFlags << 4;
+ }
+
+ if (!nCount)
+ {
+ pEngine->SetUpdateMode( FALSE );
+ pRangeFindList = new ScRangeFindList( pDocSh->GetTitle() );
+ }
+
+ ScRangeFindData* pNew = new ScRangeFindData( aRange, nFlags, nStart, nPos );
+ pRangeFindList->Insert( pNew );
+
+ ESelection aSel( 0, nStart, 0, nPos );
+ SfxItemSet aSet( pEngine->GetEmptyItemSet() );
+ aSet.Put( SvxColorItem( Color( ScRangeFindList::GetColorName( nCount ) ),
+ EE_CHAR_COLOR ) );
+ pEngine->QuickSetAttribs( aSet, aSel );
+ ++nCount;
+ }
+ }
+
+ // letzten Trenner nicht ueberlesen, koennte ja ein Quote sein (?)
+ }
+
+ if (nCount)
+ {
+ pEngine->SetUpdateMode( TRUE );
+
+ pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) );
+ }
+}
+
+void lcl_Replace( EditView* pView, const String& rNewStr, const ESelection& rOldSel )
+{
+ if ( pView )
+ {
+ ESelection aOldSel = pView->GetSelection();
+ if (aOldSel.HasRange())
+ pView->SetSelection( ESelection( aOldSel.nEndPara, aOldSel.nEndPos,
+ aOldSel.nEndPara, aOldSel.nEndPos ) );
+
+ EditEngine* pEngine = pView->GetEditEngine();
+ pEngine->QuickInsertText( rNewStr, rOldSel );
+
+ // Dummy-InsertText fuer Update und Paint
+ // dafuer muss oben die Selektion aufgehoben werden (vor QuickInsertText)
+ pView->InsertText( EMPTY_STRING, FALSE );
+
+ xub_StrLen nLen = pEngine->GetTextLen(0);
+ ESelection aSel( 0, nLen, 0, nLen );
+ pView->SetSelection( aSel ); // Cursor ans Ende
+ }
+}
+
+void ScInputHandler::UpdateRange( USHORT nIndex, const ScRange& rNew )
+{
+ ScTabViewShell* pDocView = pRefViewSh ? pRefViewSh : pActiveViewSh;
+ if ( pDocView && pRangeFindList && nIndex < pRangeFindList->Count() )
+ {
+ ScRangeFindData* pData = pRangeFindList->GetObject( nIndex );
+ xub_StrLen nOldStart = pData->nSelStart;
+ xub_StrLen nOldEnd = pData->nSelEnd;
+
+ ScRange aJustified = rNew;
+ aJustified.Justify(); // Ref in der Formel immer richtigherum anzeigen
+ String aNewStr;
+ ScDocument* pDoc = pDocView->GetViewData()->GetDocument();
+ const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
+ aJustified.Format( aNewStr, pData->nFlags, pDoc, aAddrDetails );
+ ESelection aOldSel( 0, nOldStart, 0, nOldEnd );
+
+ DataChanging();
+
+ lcl_Replace( pTopView, aNewStr, aOldSel );
+ lcl_Replace( pTableView, aNewStr, aOldSel );
+
+ bInRangeUpdate = TRUE;
+ DataChanged();
+ bInRangeUpdate = FALSE;
+
+ long nDiff = aNewStr.Len() - (long)(nOldEnd-nOldStart);
+
+ pData->aRef = rNew;
+ pData->nSelEnd = (xub_StrLen)(pData->nSelEnd + nDiff);
+
+ USHORT nCount = (USHORT) pRangeFindList->Count();
+ for (USHORT i=nIndex+1; i<nCount; i++)
+ {
+ ScRangeFindData* pNext = pRangeFindList->GetObject( i );
+ pNext->nSelStart = (xub_StrLen)(pNext->nSelStart + nDiff);
+ pNext->nSelEnd = (xub_StrLen)(pNext->nSelEnd + nDiff);
+ }
+ }
+ else
+ {
+ DBG_ERROR("UpdateRange: da fehlt was");
+ }
+}
+
+void ScInputHandler::DeleteRangeFinder()
+{
+ ScTabViewShell* pPaintView = pRefViewSh ? pRefViewSh : pActiveViewSh;
+ if ( pRangeFindList && pPaintView )
+ {
+ ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+ pRangeFindList->SetHidden(TRUE);
+ pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) ); // wegnehmen
+ DELETEZ(pRangeFindList);
+ }
+}
+
+//==================================================================
+
+inline String GetEditText(EditEngine* pEng)
+{
+ return ScEditUtil::GetSpaceDelimitedString(*pEng);
+}
+
+void lcl_RemoveTabs(String& rStr)
+{
+ xub_StrLen nPos;
+ while ( (nPos=rStr.Search('\t')) != STRING_NOTFOUND )
+ rStr.SetChar( nPos, ' ' );
+}
+
+void lcl_RemoveLineEnd(String& rStr)
+{
+ rStr.ConvertLineEnd(LINEEND_LF);
+ xub_StrLen nPos;
+ while ( (nPos=rStr.Search('\n')) != STRING_NOTFOUND )
+ rStr.SetChar( nPos, ' ' );
+}
+
+xub_StrLen lcl_MatchParenthesis( const String& rStr, xub_StrLen nPos )
+{
+ int nDir;
+ sal_Unicode c1, c2 = 0;
+ c1 = rStr.GetChar( nPos );
+ switch ( c1 )
+ {
+ case '(' :
+ c2 = ')';
+ nDir = 1;
+ break;
+ case ')' :
+ c2 = '(';
+ nDir = -1;
+ break;
+ case '<' :
+ c2 = '>';
+ nDir = 1;
+ break;
+ case '>' :
+ c2 = '<';
+ nDir = -1;
+ break;
+ case '{' :
+ c2 = '}';
+ nDir = 1;
+ break;
+ case '}' :
+ c2 = '{';
+ nDir = -1;
+ break;
+ case '[' :
+ c2 = ']';
+ nDir = 1;
+ break;
+ case ']' :
+ c2 = '[';
+ nDir = -1;
+ break;
+ default:
+ nDir = 0;
+ }
+ if ( !nDir )
+ return STRING_NOTFOUND;
+ xub_StrLen nLen = rStr.Len();
+ const sal_Unicode* p0 = rStr.GetBuffer();
+ register const sal_Unicode* p;
+ const sal_Unicode* p1;
+ USHORT nQuotes = 0;
+ if ( nPos < nLen / 2 )
+ {
+ p = p0;
+ p1 = p0 + nPos;
+ }
+ else
+ {
+ p = p0 + nPos;
+ p1 = p0 + nLen;
+ }
+ while ( p < p1 )
+ {
+ if ( *p++ == '\"' )
+ nQuotes++;
+ }
+ // Odd number of quotes that we find ourselves in a string
+ BOOL bLookInString = ((nQuotes % 2) != 0);
+ BOOL bInString = bLookInString;
+ p = p0 + nPos;
+ p1 = (nDir < 0 ? p0 : p0 + nLen) ;
+ USHORT nLevel = 1;
+ while ( p != p1 && nLevel )
+ {
+ p += nDir;
+ if ( *p == '\"' )
+ {
+ bInString = !bInString;
+ if ( bLookInString && !bInString )
+ p = p1; //That's it then
+ }
+ else if ( bInString == bLookInString )
+ {
+ if ( *p == c1 )
+ nLevel++;
+ else if ( *p == c2 )
+ nLevel--;
+ }
+ }
+ if ( nLevel )
+ return STRING_NOTFOUND;
+ return (xub_StrLen) (p - p0);
+}
+
+//==================================================================
+
+ScInputHandler::ScInputHandler()
+ : pInputWin( NULL ),
+ pEngine( NULL ),
+ pTableView( NULL ),
+ pTopView( NULL ),
+ pColumnData( NULL ),
+ pFormulaData( NULL ),
+ pFormulaDataPara( NULL ),
+ pTipVisibleParent( NULL ),
+ nTipVisible( 0 ),
+ pTipVisibleSecParent( NULL ),
+ nTipVisibleSec( 0 ),
+ nAutoPos( SCPOS_INVALID ),
+ bUseTab( FALSE ),
+ bTextValid( TRUE ),
+ nFormSelStart( 0 ),
+ nFormSelEnd( 0 ),
+ nAutoPar( 0 ),
+ eMode( SC_INPUT_NONE ),
+ bModified( FALSE ),
+ bSelIsRef( FALSE ),
+ bFormulaMode( FALSE ),
+ bInRangeUpdate( FALSE ),
+ bParenthesisShown( FALSE ),
+ bCreatingFuncView( FALSE ),
+ bInEnterHandler( FALSE ),
+ bCommandErrorShown( FALSE ),
+ bInOwnChange( FALSE ),
+ bProtected( FALSE ),
+ bCellHasPercentFormat( FALSE ),
+ nValidation( 0 ),
+ eAttrAdjust( SVX_HOR_JUSTIFY_STANDARD ),
+ aScaleX( 1,1 ),
+ aScaleY( 1,1 ),
+ pRefViewSh( NULL ),
+ pLastPattern( NULL ),
+ pEditDefaults( NULL ),
+ bLastIsSymbol( FALSE ),
+ pLastState( NULL ),
+ pDelayTimer( NULL ),
+ pRangeFindList( NULL )
+{
+ // The InputHandler is constructed with the view, so SfxViewShell::Current
+ // doesn't have the right view yet. pActiveViewSh is updated in NotifyChange.
+ pActiveViewSh = NULL;
+
+ // Bindings (nur noch fuer Invalidate benutzt) werden bei Bedarf aktuell geholt
+}
+
+__EXPORT ScInputHandler::~ScInputHandler()
+{
+ // Wenn dies der Applikations-InputHandler ist, wird der dtor erst nach SfxApplication::Main
+ // gerufen, darf sich also auf keine Sfx-Funktionen mehr verlassen
+
+ if ( !SFX_APP()->IsDowning() ) // inplace
+ EnterHandler(); // Eingabe noch abschliessen
+
+ if (SC_MOD()->GetRefInputHdl()==this)
+ SC_MOD()->SetRefInputHdl(NULL);
+
+ if ( pInputWin && pInputWin->GetInputHandler() == this )
+ pInputWin->SetInputHandler( NULL );
+
+ delete pRangeFindList;
+ delete pEditDefaults;
+ delete pEngine;
+ delete pLastState;
+ delete pDelayTimer;
+ delete pColumnData;
+ delete pFormulaData;
+ delete pFormulaDataPara;
+}
+
+void ScInputHandler::SetRefScale( const Fraction& rX, const Fraction& rY )
+{
+ if ( rX != aScaleX || rY != aScaleY )
+ {
+ aScaleX = rX;
+ aScaleY = rY;
+ if (pEngine)
+ {
+ MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
+ pEngine->SetRefMapMode( aMode );
+ }
+ }
+}
+
+void ScInputHandler::UpdateRefDevice()
+{
+ if (!pEngine)
+ return;
+
+ BOOL bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
+ if ( bTextWysiwyg && pActiveViewSh )
+ pEngine->SetRefDevice( pActiveViewSh->GetViewData()->GetDocument()->GetPrinter() );
+ else
+ pEngine->SetRefDevice( NULL );
+
+ MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
+ pEngine->SetRefMapMode( aMode );
+
+ // SetRefDevice(NULL) uses VirtualDevice, SetRefMapMode forces creation of a local VDev,
+ // so the DigitLanguage can be safely modified (might use an own VDev instead of NULL).
+ if ( !( bTextWysiwyg && pActiveViewSh ) )
+ {
+ pEngine->GetRefDevice()->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ }
+}
+
+void ScInputHandler::ImplCreateEditEngine()
+{
+ if ( !pEngine )
+ {
+ if ( pActiveViewSh )
+ {
+ const ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
+ pEngine = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
+ }
+ else
+ pEngine = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE );
+ pEngine->SetWordDelimiters( ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) );
+ UpdateRefDevice(); // also sets MapMode
+ pEngine->SetPaperSize( Size( 1000000, 1000000 ) );
+ pEditDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
+
+ pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_AUTOCORRECT );
+ pEngine->SetModifyHdl( LINK( this, ScInputHandler, ModifyHdl ) );
+ }
+}
+
+void ScInputHandler::UpdateAutoCorrFlag()
+{
+ ULONG nCntrl = pEngine->GetControlWord();
+ ULONG nOld = nCntrl;
+
+ // don't use pLastPattern here (may be invalid because of AutoStyle)
+
+ BOOL bDisable = bLastIsSymbol || bFormulaMode;
+ if ( bDisable )
+ nCntrl &= ~EE_CNTRL_AUTOCORRECT;
+ else
+ nCntrl |= EE_CNTRL_AUTOCORRECT;
+
+ if ( nCntrl != nOld )
+ pEngine->SetControlWord(nCntrl);
+}
+
+void ScInputHandler::UpdateSpellSettings( BOOL bFromStartTab )
+{
+ if ( pActiveViewSh )
+ {
+ ScViewData* pViewData = pActiveViewSh->GetViewData();
+ BOOL bOnlineSpell = pViewData->GetDocument()->GetDocOptions().IsAutoSpell();
+
+ // SetDefaultLanguage is independent of the language attributes,
+ // ScGlobal::GetEditDefaultLanguage is always used.
+ // It must be set every time in case the office language was changed.
+
+ pEngine->SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
+
+ // if called for changed options, update flags only if already editing
+ // if called from StartTable, always update flags
+
+ if ( bFromStartTab || eMode != SC_INPUT_NONE )
+ {
+ ULONG nCntrl = pEngine->GetControlWord();
+ ULONG nOld = nCntrl;
+ if( bOnlineSpell )
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ // kein AutoCorrect auf Symbol-Font (EditEngine wertet Default nicht aus)
+ if ( pLastPattern && pLastPattern->IsSymbolFont() )
+ nCntrl &= ~EE_CNTRL_AUTOCORRECT;
+ else
+ nCntrl |= EE_CNTRL_AUTOCORRECT;
+ if ( nCntrl != nOld )
+ pEngine->SetControlWord(nCntrl);
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() );
+ pEngine->SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( pViewData->GetTabNo() ) );
+ pEngine->SetFirstWordCapitalization( FALSE );
+ }
+
+ // language is set separately, so the speller is needed only if online
+ // spelling is active
+
+ if ( bOnlineSpell ) {
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
+ pEngine->SetSpeller( xXSpellChecker1 );
+ }
+
+ BOOL bHyphen = pLastPattern && ((const SfxBoolItem&)pLastPattern->GetItem(ATTR_HYPHENATE)).GetValue();
+ if ( bHyphen ) {
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
+ pEngine->SetHyphenator( xXHyphenator );
+ }
+ }
+}
+
+//
+// Funktionen/Bereichsnamen etc. als Tip-Hilfe
+//
+
+#define SC_STRTYPE_FUNCTIONS 1
+// die anderen Typen sind in ScDocument::GetFormulaEntries festgelegt
+
+void ScInputHandler::GetFormulaData()
+{
+ if ( pActiveViewSh )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
+
+ if ( pFormulaData )
+ pFormulaData->FreeAll();
+ else
+ pFormulaData = new TypedScStrCollection;
+
+ if( pFormulaDataPara )
+ pFormulaDataPara->FreeAll();
+ else
+ pFormulaDataPara = new TypedScStrCollection;
+
+ // MRU-Funktionen aus dem Funktions-Autopiloten
+ // wie in ScPosWnd::FillFunctions (inputwin.cxx)
+
+ const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
+ USHORT nMRUCount = rOpt.GetLRUFuncListCount();
+ const USHORT* pMRUList = rOpt.GetLRUFuncList();
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ ULONG nListCount = pFuncList->GetCount();
+ if (pMRUList)
+ {
+ for (USHORT i=0; i<nMRUCount; i++)
+ {
+ USHORT nId = pMRUList[i];
+ for (ULONG j=0; j<nListCount; j++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
+ if ( pDesc->nFIndex == nId && pDesc->pFuncName )
+ {
+ String aEntry = *pDesc->pFuncName;
+ aEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
+ TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS );
+ if (!pFormulaData->Insert(pData))
+ delete pData;
+ break; // nicht weitersuchen
+ }
+ }
+ }
+ }
+ for(ULONG i=0;i<nListCount;i++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction( i );
+ if ( pDesc->pFuncName )
+ {
+ pDesc->initArgumentInfo();
+ String aEntry = pDesc->GetSignature();
+ TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS );
+ if (!pFormulaDataPara->Insert(pData))
+ delete pData;
+ }
+ }
+ pDoc->GetFormulaEntries( *pFormulaData );
+ pDoc->GetFormulaEntries( *pFormulaDataPara );
+ }
+}
+
+IMPL_LINK( ScInputHandler, ShowHideTipVisibleParentListener, VclWindowEvent*, pEvent )
+{
+ if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
+ HideTip();
+ return 0;
+}
+
+IMPL_LINK( ScInputHandler, ShowHideTipVisibleSecParentListener, VclWindowEvent*, pEvent )
+{
+ if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
+ HideTipBelow();
+ return 0;
+}
+
+void ScInputHandler::HideTip()
+{
+ if ( nTipVisible )
+ {
+ if (pTipVisibleParent)
+ pTipVisibleParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
+ Help::HideTip( nTipVisible );
+ nTipVisible = 0;
+ pTipVisibleParent = NULL;
+ }
+ aManualTip.Erase();
+}
+void ScInputHandler::HideTipBelow()
+{
+ if ( nTipVisibleSec )
+ {
+ if (pTipVisibleSecParent)
+ pTipVisibleSecParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
+ Help::HideTip( nTipVisibleSec );
+ nTipVisibleSec = 0;
+ pTipVisibleSecParent = NULL;
+ }
+ aManualTip.Erase();
+}
+
+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 )
+ {
+ String aFormula = pEngine->GetText( (USHORT) 0 );
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+ xub_StrLen nLeftParentPos = 0;
+ if( aSel.nEndPos )
+ {
+ if ( aFormula.Len() < aSel.nEndPos )
+ return;
+ xub_StrLen nPos = aSel.nEndPos;
+ String aSelText = aFormula.Copy( 0, nPos );
+ xub_StrLen nNextFStart = 0;
+ xub_StrLen nNextFEnd = 0;
+ xub_StrLen nArgPos = 0;
+ const IFunctionDescription* ppFDesc;
+ ::std::vector< ::rtl::OUString> aArgs;
+ USHORT nArgs;
+ BOOL bFound = FALSE;
+ FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());
+
+ while( !bFound )
+ {
+ aSelText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ nLeftParentPos = lcl_MatchParenthesis( aSelText, aSelText.Len()-1 );
+ if( nLeftParentPos != STRING_NOTFOUND )
+ {
+ 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);
+ if( aHelper.GetNextFunc( aSelText, FALSE, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
+ {
+ if( ppFDesc->getFunctionName().getLength() )
+ {
+ nArgPos = aHelper.GetArgStart( aSelText, nNextFStart, 0 );
+ nArgs = static_cast<USHORT>(ppFDesc->getParameterCount());
+
+ USHORT nActive = 0;
+ USHORT nCount = 0;
+ USHORT nCountSemicolon = 0;
+ USHORT nCountDot = 0;
+ USHORT nStartPosition = 0;
+ USHORT nEndPosition = 0;
+ BOOL bFlag = FALSE;
+ String aNew;
+ USHORT nParAutoPos = SCPOS_INVALID;
+ if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, FALSE ) )
+ {
+ for( USHORT i=0; i < nArgs; i++ )
+ {
+ xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
+ if( nArgPos <= aSelText.Len()-1 )
+ {
+ nActive = i+1;
+ bFlag = TRUE;
+ }
+ nArgPos+=nLength+1;
+ }
+ if( bFlag )
+ {
+ nCountSemicolon = aNew.GetTokenCount(cSep)-1;
+ nCountDot = aNew.GetTokenCount(cSheetSep)-1;
+
+ if( !nCountSemicolon )
+ {
+ for( USHORT i = 0; i < aNew.Len(); i++ )
+ {
+ sal_Unicode cNext = aNew.GetChar( i );
+ if( cNext == '(' )
+ {
+ nStartPosition = i+1;
+ }
+ }
+ }
+ else if( !nCountDot )
+ {
+ for( USHORT i = 0; i < aNew.Len(); i++ )
+ {
+ sal_Unicode cNext = aNew.GetChar( i );
+ if( cNext == '(' )
+ {
+ nStartPosition = i+1;
+ }
+ else if( cNext == cSep )
+ {
+ nCount ++;
+ nEndPosition = i;
+ if( nCount == nActive )
+ {
+ break;
+ }
+ nStartPosition = nEndPosition+1;
+ }
+ }
+ }
+ else
+ {
+ for( USHORT i = 0; i < aNew.Len(); i++ )
+ {
+ sal_Unicode cNext = aNew.GetChar( i );
+ if( cNext == '(' )
+ {
+ nStartPosition = i+1;
+ }
+ else if( cNext == cSep )
+ {
+ nCount ++;
+ nEndPosition = i;
+ if( nCount == nActive )
+ {
+ break;
+ }
+ nStartPosition = nEndPosition+1;
+ }
+ else if( cNext == cSheetSep )
+ {
+ continue;
+ }
+ }
+ }
+
+ if( nStartPosition )
+ {
+ aNew.Insert( 0x25BA, nStartPosition );
+ ShowTipBelow( aNew );
+ bFound = TRUE;
+ }
+ }
+ else
+ {
+ ShowTipBelow( aNew );
+ bFound = TRUE;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ USHORT nPosition = 0;
+ String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
+ if( aText.GetChar( aSel.nEndPos-1 ) == '=' )
+ {
+ break;
+ }
+ String aNew;
+ USHORT nParAutoPos = SCPOS_INVALID;
+ nPosition = aText.Len()+1;
+ if( pFormulaDataPara->FindText( aText, aNew, nParAutoPos, FALSE ) )
+ {
+ if( aFormula.GetChar( nPosition ) =='(' )
+ {
+ ShowTipBelow( aNew );
+ bFound = TRUE;
+ }
+ else
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScInputHandler::ShowTip( const String& rText )
+{
+ // aManualTip muss hinterher von aussen gesetzt werden
+ HideTip();
+
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (pActiveView)
+ {
+ Point aPos;
+ pTipVisibleParent = pActiveView->GetWindow();
+ Cursor* pCur = pActiveView->GetCursor();
+ if (pCur)
+ aPos = pTipVisibleParent->LogicToPixel( pCur->GetPos() );
+ aPos = pTipVisibleParent->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, aPos );
+
+ USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
+ nTipVisible = Help::ShowTip(pTipVisibleParent, aRect, rText, nAlign);
+ pTipVisibleParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
+ }
+}
+
+void ScInputHandler::ShowTipBelow( const String& rText )
+{
+ HideTipBelow();
+
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if ( pActiveView )
+ {
+ Point aPos;
+ pTipVisibleSecParent = pActiveView->GetWindow();
+ Cursor* pCur = pActiveView->GetCursor();
+ if ( pCur )
+ {
+ Point aLogicPos = pCur->GetPos();
+ aLogicPos.Y() += pCur->GetHeight();
+ aPos = pTipVisibleSecParent->LogicToPixel( aLogicPos );
+ }
+ aPos = pTipVisibleSecParent->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, aPos );
+ USHORT nAlign = QUICKHELP_LEFT | QUICKHELP_TOP | QUICKHELP_NOEVADEPOINTER;
+ nTipVisibleSec = Help::ShowTip(pTipVisibleSecParent, aRect, rText, nAlign);
+ pTipVisibleSecParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
+ }
+}
+
+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 )
+ {
+ String aTotal = pEngine->GetText( (USHORT) 0 );
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+
+ // #59348# Durch Differenzen zwischen Tabelle und Eingabezeile
+ // (z.B. Clipboard mit Zeilenumbruechen) kann es sein, dass die Selektion
+ // nicht mehr zur EditEngine passt. Dann halt kommentarlos abbrechen:
+
+ if ( aSel.nEndPos > aTotal.Len() )
+ return;
+
+ // steht der Cursor am Ende eines Wortes?
+
+ if ( aSel.nEndPos > 0 )
+ {
+ xub_StrLen nPos = aSel.nEndPos;
+ String aFormula = aTotal.Copy( 0, nPos );;
+ xub_StrLen nLeftParentPos = 0;
+ xub_StrLen nNextFStart = 0;
+ xub_StrLen nNextFEnd = 0;
+ xub_StrLen nArgPos = 0;
+ const IFunctionDescription* ppFDesc;
+ ::std::vector< ::rtl::OUString> aArgs;
+ USHORT nArgs;
+ BOOL bFound = FALSE;
+
+ String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
+ if ( aText.Len() )
+ {
+ String aNew;
+ nAutoPos = SCPOS_INVALID;
+ if ( pFormulaData->FindText( aText, aNew, nAutoPos, FALSE ) )
+ {
+ ShowTip( aNew );
+ aAutoSearch = aText;
+ }
+ }
+ FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());
+
+ while( !bFound )
+ {
+ aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ nLeftParentPos = lcl_MatchParenthesis( aFormula, aFormula.Len()-1 );
+ if( nLeftParentPos == STRING_NOTFOUND )
+ break;
+
+ // #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);
+ if( aHelper.GetNextFunc( aFormula, FALSE, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
+ {
+ if( ppFDesc->getFunctionName().getLength() )
+ {
+ nArgPos = aHelper.GetArgStart( aFormula, nNextFStart, 0 );
+ nArgs = static_cast<USHORT>(ppFDesc->getParameterCount());
+
+ USHORT nActive = 0;
+ USHORT nCount = 0;
+ USHORT nCountSemicolon = 0;
+ USHORT nCountDot = 0;
+ USHORT nStartPosition = 0;
+ USHORT nEndPosition = 0;
+ BOOL bFlag = FALSE;
+ String aNew;
+ USHORT nParAutoPos = SCPOS_INVALID;
+ if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, FALSE ) )
+ {
+ for( USHORT i=0; i < nArgs; i++ )
+ {
+ xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
+ if( nArgPos <= aFormula.Len()-1 )
+ {
+ nActive = i+1;
+ bFlag = TRUE;
+ }
+ nArgPos+=nLength+1;
+ }
+ if( bFlag )
+ {
+ nCountSemicolon = aNew.GetTokenCount(cSep)-1;
+ nCountDot = aNew.GetTokenCount(cSheetSep)-1;
+
+ if( !nCountSemicolon )
+ {
+ for( USHORT i = 0; i < aNew.Len(); i++ )
+ {
+ sal_Unicode cNext = aNew.GetChar( i );
+ if( cNext == '(' )
+ {
+ nStartPosition = i+1;
+ }
+ }
+ }
+ else if( !nCountDot )
+ {
+ for( USHORT i = 0; i < aNew.Len(); i++ )
+ {
+ sal_Unicode cNext = aNew.GetChar( i );
+ if( cNext == '(' )
+ {
+ nStartPosition = i+1;
+ }
+ else if( cNext == cSep )
+ {
+ nCount ++;
+ nEndPosition = i;
+ if( nCount == nActive )
+ {
+ break;
+ }
+ nStartPosition = nEndPosition+1;
+ }
+ }
+ }
+ else
+ {
+ for( USHORT i = 0; i < aNew.Len(); i++ )
+ {
+ sal_Unicode cNext = aNew.GetChar( i );
+ if( cNext == '(' )
+ {
+ nStartPosition = i+1;
+ }
+ else if( cNext == cSep )
+ {
+ nCount ++;
+ nEndPosition = i;
+ if( nCount == nActive )
+ {
+ break;
+ }
+ nStartPosition = nEndPosition+1;
+ }
+ else if( cNext == cSheetSep )
+ {
+ continue;
+ }
+ }
+ }
+
+ if( nStartPosition )
+ {
+ aNew.Insert( 0x25BA, nStartPosition );
+ ShowTipBelow( aNew );
+ bFound = TRUE;
+ }
+ }
+ else
+ {
+ ShowTipBelow( aNew );
+ bFound = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScInputHandler::NextFormulaEntry( BOOL bBack )
+{
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if ( pActiveView && pFormulaData )
+ {
+ String aNew;
+ if ( pFormulaData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) )
+ ShowTip( aNew ); // als QuickHelp anzeigen
+ }
+
+ // bei Tab wird vorher immer HideCursor gerufen
+
+ if (pActiveView)
+ pActiveView->ShowCursor();
+}
+
+void lcl_CompleteFunction( EditView* pView, const String& rInsert, BOOL& rParInserted )
+{
+ if (pView)
+ {
+ ESelection aSel = pView->GetSelection();
+ --aSel.nStartPos;
+ --aSel.nEndPos;
+ pView->SetSelection(aSel);
+ pView->SelectCurrentWord();
+
+ String aInsStr = rInsert;
+ xub_StrLen nInsLen = aInsStr.Len();
+ BOOL bDoParen = ( nInsLen > 1 && aInsStr.GetChar(nInsLen-2) == '('
+ && aInsStr.GetChar(nInsLen-1) == ')' );
+ if ( bDoParen )
+ {
+ // Klammern hinter Funktionsnamen nicht einfuegen, wenn direkt dahinter
+ // schon eine Klammer steht (z.B. wenn der Funktionsname geaendert wurde,
+ // #39393#).
+
+ ESelection aWordSel = pView->GetSelection();
+ String aOld = pView->GetEditEngine()->GetText((USHORT)0);
+ sal_Unicode cNext = aOld.GetChar(aWordSel.nEndPos);
+ if ( cNext == '(' )
+ {
+ bDoParen = FALSE;
+ aInsStr.Erase( nInsLen - 2 ); // Klammern weglassen
+ }
+ }
+
+ pView->InsertText( aInsStr, FALSE );
+
+ if ( bDoParen ) // Cursor zwischen die Klammern setzen
+ {
+ aSel = pView->GetSelection();
+ --aSel.nStartPos;
+ --aSel.nEndPos;
+ pView->SetSelection(aSel);
+
+ rParInserted = TRUE;
+ }
+ }
+}
+
+void ScInputHandler::PasteFunctionData()
+{
+ if ( pFormulaData && nAutoPos != SCPOS_INVALID )
+ {
+ TypedStrData* pData = (*pFormulaData)[nAutoPos];
+ if (pData)
+ {
+ String aInsert = pData->GetString();
+ BOOL bParInserted = FALSE;
+
+ DataChanging(); // kann nicht neu sein
+ lcl_CompleteFunction( pTopView, aInsert, bParInserted );
+ lcl_CompleteFunction( pTableView, aInsert, bParInserted );
+ DataChanged();
+ ShowTipCursor();
+
+ if (bParInserted)
+ AutoParAdded();
+ }
+ }
+
+ HideTip();
+
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (pActiveView)
+ pActiveView->ShowCursor();
+}
+
+//
+// Selektion berechnen und als Tip-Hilfe anzeigen
+//
+
+String lcl_Calculate( const String& rFormula, ScDocument* pDoc, const ScAddress &rPos )
+{
+ //! mit ScFormulaDlg::CalcValue zusammenfassen und ans Dokument verschieben !!!!
+ //! (Anfuehrungszeichen bei Strings werden nur hier eingefuegt)
+
+ String aValue;
+
+ if (rFormula.Len())
+ {
+ ScFormulaCell* pCell = new ScFormulaCell( pDoc, rPos, rFormula );
+
+ // #35521# HACK! um bei ColRowNames kein #REF! zu bekommen,
+ // wenn ein Name eigentlich als Bereich in die Gesamt-Formel
+ // eingefuegt wird, bei der Einzeldarstellung aber als
+ // single-Zellbezug interpretiert wird
+ BOOL bColRowName = pCell->HasColRowName();
+ if ( bColRowName )
+ {
+ // ColRowName im RPN-Code?
+ if ( pCell->GetCode()->GetCodeLen() <= 1 )
+ { // ==1: einzelner ist als Parameter immer Bereich
+ // ==0: es waere vielleicht einer, wenn..
+ String aBraced( '(' );
+ aBraced += rFormula;
+ aBraced += ')';
+ delete pCell;
+ pCell = new ScFormulaCell( pDoc, rPos, aBraced );
+ }
+ else
+ bColRowName = FALSE;
+ }
+
+ USHORT nErrCode = pCell->GetErrCode();
+ if ( nErrCode == 0 )
+ {
+ SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable());
+ Color* pColor;
+ if ( pCell->IsValue() )
+ {
+ double n = pCell->GetValue();
+ ULONG nFormat = aFormatter.GetStandardFormat( n, 0,
+ pCell->GetFormatType(), ScGlobal::eLnge );
+ aFormatter.GetInputLineString( n, nFormat, aValue );
+ //! display OutputString but insert InputLineString
+ }
+ else
+ {
+ String aStr;
+
+ pCell->GetString( aStr );
+ ULONG nFormat = aFormatter.GetStandardFormat(
+ pCell->GetFormatType(), ScGlobal::eLnge);
+ aFormatter.GetOutputString( aStr, nFormat,
+ aValue, &pColor );
+
+ aValue.Insert('"',0); // in Anfuehrungszeichen
+ aValue+='"';
+ //! Anfuehrungszeichen im String escapen ????
+ }
+
+ ScRange aTestRange;
+ if ( bColRowName || (aTestRange.Parse(rFormula) & SCA_VALID) )
+ aValue.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." )); // Bereich
+ }
+ else
+ aValue = ScGlobal::GetErrorString(nErrCode);
+ delete pCell;
+ }
+
+ return aValue;
+}
+
+void ScInputHandler::FormulaPreview()
+{
+ String aValue;
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if ( pActiveView && pActiveViewSh )
+ {
+ String aPart = pActiveView->GetSelected();
+ if (!aPart.Len())
+ aPart = pEngine->GetText((USHORT)0);
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
+ aValue = lcl_Calculate( aPart, pDoc, aCursorPos );
+ }
+
+ if (aValue.Len())
+ {
+ ShowTip( aValue ); // als QuickHelp anzeigen
+ aManualTip = aValue; // nach ShowTip setzen
+ nAutoPos = SCPOS_INVALID; // Formel-Autocomplete aufheben
+ }
+}
+
+void ScInputHandler::PasteManualTip()
+{
+ // drei Punkte am Ende -> Bereichsreferenz -> nicht einfuegen
+ // (wenn wir mal Matrix-Konstanten haben, kann das geaendert werden)
+
+ xub_StrLen nTipLen = aManualTip.Len();
+ if ( nTipLen && ( nTipLen < 3 || !aManualTip.Copy( nTipLen-3 ).EqualsAscii("...") ) )
+ {
+ DataChanging(); // kann nicht neu sein
+
+ String aInsert = aManualTip;
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (!pActiveView->HasSelection())
+ {
+ // nichts selektiert -> alles selektieren
+ xub_StrLen nOldLen = pEngine->GetTextLen(0);
+ ESelection aAllSel( 0, 0, 0, nOldLen );
+ if ( pTopView )
+ pTopView->SetSelection( aAllSel );
+ if ( pTableView )
+ pTableView->SetSelection( aAllSel );
+ }
+
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+ DBG_ASSERT( !aSel.nStartPara && !aSel.nEndPara, "Zuviele Absaetze in Formel" );
+ if ( !aSel.nStartPos ) // Selektion ab Anfang?
+ {
+ if ( aSel.nEndPos == pEngine->GetTextLen(0) )
+ {
+ // alles selektiert -> Anfuehrungszeichen weglassen
+ if ( aInsert.GetChar(0) == '"' )
+ aInsert.Erase(0,1);
+ xub_StrLen nInsLen = aInsert.Len();
+ if ( nInsLen && aInsert.GetChar(nInsLen-1) == '"' )
+ aInsert.Erase( nInsLen-1 );
+ }
+ else if ( aSel.nEndPos )
+ {
+ // nicht alles selektiert -> Gleichheitszeichen nicht ueberschreiben
+ //! doppelte Gleichheitszeichen auch ???
+
+ aSel.nStartPos = 1;
+ if ( pTopView )
+ pTopView->SetSelection( aSel );
+ if ( pTableView )
+ pTableView->SetSelection( aSel );
+ }
+ }
+ if ( pTopView )
+ pTopView->InsertText( aInsert, TRUE );
+ if ( pTableView )
+ pTableView->InsertText( aInsert, TRUE );
+
+ DataChanged();
+ }
+
+ HideTip();
+}
+
+void ScInputHandler::ResetAutoPar()
+{
+ nAutoPar = 0;
+}
+
+void ScInputHandler::AutoParAdded()
+{
+ ++nAutoPar; // closing parenthesis can be overwritten
+}
+
+BOOL ScInputHandler::CursorAtClosingPar()
+{
+ // test if the cursor is before a closing parenthesis
+
+ // selection from SetReference has been removed before
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if ( pActiveView && !pActiveView->HasSelection() && bFormulaMode )
+ {
+ ESelection aSel = pActiveView->GetSelection();
+ xub_StrLen nPos = aSel.nStartPos;
+ String aFormula = pEngine->GetText((USHORT)0);
+ if ( nPos < aFormula.Len() && aFormula.GetChar(nPos) == ')' )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ScInputHandler::SkipClosingPar()
+{
+ // this is called when a ')' is typed and the cursor is before a ')'
+ // that can be overwritten -> just set the cursor behind the ')'
+
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (pActiveView)
+ {
+ ESelection aSel = pActiveView->GetSelection();
+ ++aSel.nStartPos;
+ ++aSel.nEndPos;
+
+ // this is in a formula (only one paragraph), so the selection
+ // can be used directly for the TopView
+
+ if ( pTopView )
+ pTopView->SetSelection( aSel );
+ if ( pTableView )
+ pTableView->SetSelection( aSel );
+ }
+
+ DBG_ASSERT(nAutoPar, "SkipClosingPar: count is wrong");
+ --nAutoPar;
+}
+
+//
+// Auto-Eingabe
+//
+
+void ScInputHandler::GetColData()
+{
+ if ( pActiveViewSh )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
+
+ if ( pColumnData )
+ pColumnData->FreeAll();
+ else
+ {
+ pColumnData = new TypedScStrCollection;
+ pColumnData->SetCaseSensitive( TRUE ); // equal strings are handled in FindText
+ }
+
+ pDoc->GetDataEntries( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
+ *pColumnData, TRUE );
+ }
+}
+
+void ScInputHandler::UseColData() // beim Tippen
+{
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if ( pActiveView && pColumnData )
+ {
+ // nur anpassen, wenn Cursor am Ende steht
+
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+
+ USHORT nParCnt = pEngine->GetParagraphCount();
+ if ( aSel.nEndPara+1 == nParCnt )
+ {
+ xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
+ if ( aSel.nEndPos == nParLen )
+ {
+ String aText = GetEditText(pEngine);
+ if (aText.Len())
+ {
+ String aNew;
+ nAutoPos = SCPOS_INVALID; // nix
+ if ( pColumnData->FindText( aText, aNew, nAutoPos, FALSE ) )
+ {
+ // #45434# durch dBase Import etc. koennen Umbrueche im String sein,
+ // das wuerde hier mehrere Absaetze ergeben -> nicht gut
+ //! GetExactMatch funktioniert dann auch nicht
+ lcl_RemoveLineEnd( aNew );
+
+ // Absaetze beibehalten, nur den Rest anfuegen
+ //! genaue Ersetzung im EnterHandler !!!
+
+ // ein Space zwischen Absaetzen:
+ ULONG nEdLen = pEngine->GetTextLen() + nParCnt - 1;
+ String aIns = aNew.Copy( (xub_StrLen)nEdLen );
+
+ // selection must be "backwards", so the cursor stays behind the last
+ // typed character
+ ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.Len(),
+ aSel.nEndPara, aSel.nEndPos );
+
+ // when editing in input line, apply to both edit views
+ if ( pTableView )
+ {
+ pTableView->InsertText( aIns, FALSE );
+ pTableView->SetSelection( aSelection );
+ }
+ if ( pTopView )
+ {
+ pTopView->InsertText( aIns, FALSE );
+ pTopView->SetSelection( aSelection );
+ }
+
+ aAutoSearch = aText; // zum Weitersuchen - nAutoPos ist gesetzt
+
+ if ( aText.Len() == aNew.Len() )
+ {
+ // Wenn der eingegebene Text gefunden wurde, TAB nur dann
+ // verschlucken, wenn noch etwas kommt
+
+ String aDummy;
+ USHORT nNextPos = nAutoPos;
+ bUseTab = pColumnData->FindText( aText, aDummy, nNextPos, FALSE );
+ }
+ else
+ bUseTab = TRUE;
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScInputHandler::NextAutoEntry( BOOL bBack )
+{
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if ( pActiveView && pColumnData )
+ {
+ if ( nAutoPos != SCPOS_INVALID && aAutoSearch.Len() )
+ {
+ // stimmt die Selektion noch? (kann per Maus geaendert sein)
+
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+ USHORT nParCnt = pEngine->GetParagraphCount();
+ if ( aSel.nEndPara+1 == nParCnt && aSel.nStartPara == aSel.nEndPara )
+ {
+ String aText = GetEditText(pEngine);
+ xub_StrLen nSelLen = aSel.nEndPos - aSel.nStartPos;
+ xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
+ if ( aSel.nEndPos == nParLen && aText.Len() == aAutoSearch.Len() + nSelLen )
+ {
+ String aNew;
+ if ( pColumnData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) )
+ {
+ bInOwnChange = TRUE; // disable ModifyHdl (reset below)
+
+ lcl_RemoveLineEnd( aNew );
+ String aIns = aNew.Copy( aAutoSearch.Len() );
+
+ // when editing in input line, apply to both edit views
+ if ( pTableView )
+ {
+ pTableView->DeleteSelected();
+ pTableView->InsertText( aIns, FALSE );
+ pTableView->SetSelection( ESelection(
+ aSel.nEndPara, aSel.nStartPos + aIns.Len(),
+ aSel.nEndPara, aSel.nStartPos ) );
+ }
+ if ( pTopView )
+ {
+ pTopView->DeleteSelected();
+ pTopView->InsertText( aIns, FALSE );
+ pTopView->SetSelection( ESelection(
+ aSel.nEndPara, aSel.nStartPos + aIns.Len(),
+ aSel.nEndPara, aSel.nStartPos ) );
+ }
+
+ bInOwnChange = FALSE;
+ }
+ else
+ {
+ // mehr gibts nicht
+
+ Sound::Beep();
+ }
+ }
+ }
+ }
+ }
+
+ // bei Tab wird vorher immer HideCursor gerufen
+
+ if (pActiveView)
+ pActiveView->ShowCursor();
+}
+
+//
+// Klammern hervorheben
+//
+
+void ScInputHandler::UpdateParenthesis()
+{
+ // Klammern suchen
+
+ //! Klammer-Hervorhebung einzeln abschaltbar ????
+
+ BOOL bFound = FALSE;
+ if ( bFormulaMode && eMode != SC_INPUT_TOP )
+ {
+ if ( pTableView && !pTableView->HasSelection() ) // Selektion ist immer unten
+ {
+ ESelection aSel = pTableView->GetSelection();
+ if (aSel.nStartPos)
+ {
+ // Das Zeichen links vom Cursor wird angeschaut
+
+ xub_StrLen nPos = aSel.nStartPos - 1;
+ String aFormula = pEngine->GetText((USHORT)0);
+ sal_Unicode c = aFormula.GetChar(nPos);
+ if ( c == '(' || c == ')' )
+ {
+ xub_StrLen nOther = lcl_MatchParenthesis( aFormula, nPos );
+ if ( nOther != STRING_NOTFOUND )
+ {
+ SfxItemSet aSet( pEngine->GetEmptyItemSet() );
+ aSet.Put( SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
+ //! Unterscheidung, wenn die Zelle schon fett ist !!!!
+
+ if (bParenthesisShown)
+ {
+ // alte Hervorhebung wegnehmen
+ USHORT nCount = pEngine->GetParagraphCount();
+ for (USHORT i=0; i<nCount; i++)
+ pEngine->QuickRemoveCharAttribs( i, EE_CHAR_WEIGHT );
+ }
+
+ ESelection aSelThis( 0,nPos, 0,nPos+1 );
+ pEngine->QuickSetAttribs( aSet, aSelThis );
+ ESelection aSelOther( 0,nOther, 0,nOther+1 );
+ pEngine->QuickSetAttribs( aSet, aSelOther );
+
+ // Dummy-InsertText fuer Update und Paint (Selektion ist leer)
+ pTableView->InsertText( EMPTY_STRING, FALSE );
+
+ bFound = TRUE;
+ }
+ }
+ }
+
+ // mark parenthesis right of cursor if it will be overwritten (nAutoPar)
+ // with different color (COL_LIGHTBLUE) ??
+ }
+ }
+
+ // alte Hervorhebung wegnehmen, wenn keine neue gesetzt
+
+ if ( bParenthesisShown && !bFound && pTableView )
+ {
+ USHORT nCount = pEngine->GetParagraphCount();
+ for (USHORT i=0; i<nCount; i++)
+ pTableView->RemoveCharAttribs( i, EE_CHAR_WEIGHT );
+ }
+
+ bParenthesisShown = bFound;
+}
+
+void ScInputHandler::ViewShellGone(ScTabViewShell* pViewSh) // wird synchron aufgerufen!
+{
+ if ( pViewSh == pActiveViewSh )
+ {
+ delete pLastState;
+ pLastState = NULL;
+ pLastPattern = NULL;
+ }
+
+ if ( pViewSh == pRefViewSh )
+ {
+ //! Die Eingabe kommt aus dem EnterHandler nicht mehr an
+ // Trotzdem wird immerhin der Editmodus beendet
+
+ EnterHandler();
+ bFormulaMode = FALSE;
+ pRefViewSh = NULL;
+ SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
+ SC_MOD()->SetRefInputHdl(NULL);
+ if (pInputWin)
+ pInputWin->SetFormulaMode(FALSE);
+ UpdateAutoCorrFlag();
+ }
+
+ pActiveViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+
+ if ( pActiveViewSh && pActiveViewSh == pViewSh )
+ {
+ DBG_ERROR("pActiveViewSh weg");
+ pActiveViewSh = NULL;
+ }
+
+ if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
+ UpdateRefDevice(); // don't keep old document's printer as RefDevice
+}
+
+void ScInputHandler::UpdateActiveView()
+{
+ ImplCreateEditEngine();
+
+ // #i20588# Don't rely on focus to find the active edit view. Instead, the
+ // active pane at the start of editing is now stored (GetEditActivePart).
+ // GetActiveWin (the currently active pane) fails for ref input across the
+ // panes of a split view.
+
+ Window* pShellWin = pActiveViewSh ?
+ pActiveViewSh->GetWindowByPos( pActiveViewSh->GetViewData()->GetEditActivePart() ) :
+ NULL;
+
+ USHORT nCount = pEngine->GetViewCount();
+ if (nCount > 0)
+ {
+ pTableView = pEngine->GetView(0);
+ for (USHORT i=1; i<nCount; i++)
+ {
+ EditView* pThis = pEngine->GetView(i);
+ Window* pWin = pThis->GetWindow();
+ if ( pWin==pShellWin )
+ pTableView = pThis;
+ }
+ }
+ else
+ pTableView = NULL;
+
+ if (pInputWin)
+ pTopView = pInputWin->GetEditView();
+ else
+ pTopView = NULL;
+}
+
+void ScInputHandler::StopInputWinEngine( BOOL bAll )
+{
+ if (pInputWin)
+ pInputWin->StopEditEngine( bAll );
+
+ pTopView = NULL; // invalid now
+}
+
+EditView* ScInputHandler::GetActiveView()
+{
+ UpdateActiveView();
+ return pTopView ? pTopView : pTableView;
+}
+
+void ScInputHandler::ForgetLastPattern()
+{
+ pLastPattern = NULL;
+ if ( !pLastState && pActiveViewSh )
+ pActiveViewSh->UpdateInputHandler( TRUE ); // Status neu holen
+ else
+ NotifyChange( pLastState, TRUE );
+}
+
+void ScInputHandler::UpdateAdjust( sal_Unicode cTyped )
+{
+ SvxAdjust eSvxAdjust;
+ switch (eAttrAdjust)
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ {
+ BOOL bNumber = FALSE;
+ if (cTyped) // neu angefangen
+ bNumber = (cTyped>='0' && cTyped<='9'); // nur Ziffern sind Zahlen
+ else if ( pActiveViewSh )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
+ bNumber = ( pDoc->GetCellType( aCursorPos ) == CELLTYPE_VALUE );
+ }
+ eSvxAdjust = bNumber ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
+ }
+ break;
+ case SVX_HOR_JUSTIFY_BLOCK:
+ eSvxAdjust = SVX_ADJUST_BLOCK;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ eSvxAdjust = SVX_ADJUST_RIGHT;
+ break;
+ default: // SVX_HOR_JUSTIFY_LEFT
+ eSvxAdjust = SVX_ADJUST_LEFT;
+ break;
+ }
+
+ BOOL bAsianVertical = pLastPattern &&
+ ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_STACKED )).GetValue() &&
+ ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
+ if ( bAsianVertical )
+ {
+ // always edit at top of cell -> LEFT when editing vertically
+ eSvxAdjust = SVX_ADJUST_LEFT;
+ }
+
+ pEditDefaults->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+ pEngine->SetDefaults( *pEditDefaults );
+
+ nEditAdjust = sal::static_int_cast<USHORT>(eSvxAdjust); //! set at ViewData or with PostEditView
+
+ pEngine->SetVertical( bAsianVertical );
+}
+
+void ScInputHandler::RemoveAdjust()
+{
+ // harte Ausrichtungs-Attribute loeschen
+
+ BOOL bUndo = pEngine->IsUndoEnabled();
+ if ( bUndo )
+ pEngine->EnableUndo( FALSE );
+
+ // RemoveParaAttribs removes all paragraph attributes, including EE_PARA_JUST
+#if 0
+ BOOL bChange = FALSE;
+ USHORT nCount = pEngine->GetParagraphCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ const SfxItemSet& rOld = pEngine->GetParaAttribs( i );
+ if ( rOld.GetItemState( EE_PARA_JUST ) == SFX_ITEM_SET )
+ {
+ SfxItemSet aNew( rOld );
+ aNew.ClearItem( EE_PARA_JUST );
+ pEngine->SetParaAttribs( i, aNew );
+ bChange = TRUE;
+ }
+ }
+#endif
+
+ // #89403# non-default paragraph attributes (e.g. from clipboard)
+ // must be turned into character attributes
+ pEngine->RemoveParaAttribs();
+
+ if ( bUndo )
+ pEngine->EnableUndo( TRUE );
+
+ // ER 31.08.00 Only called in EnterHandler, don't change view anymore.
+#if 0
+ if (bChange)
+ {
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ pActiveView->ShowCursor( FALSE, TRUE );
+ }
+#endif
+}
+
+void ScInputHandler::RemoveRangeFinder()
+{
+ // pRangeFindList und Farben loeschen
+
+ pEngine->SetUpdateMode(FALSE);
+ USHORT nCount = pEngine->GetParagraphCount(); // koennte gerade neu eingefuegt worden sein
+ for (USHORT i=0; i<nCount; i++)
+ pEngine->QuickRemoveCharAttribs( i, EE_CHAR_COLOR );
+ pEngine->SetUpdateMode(TRUE);
+
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ pActiveView->ShowCursor( FALSE, TRUE );
+
+ DeleteRangeFinder(); // loescht die Liste und die Markierungen auf der Tabelle
+}
+
+BOOL ScInputHandler::StartTable( sal_Unicode cTyped, BOOL bFromCommand )
+{
+ // returns TRUE if a new edit mode was started
+
+ BOOL bNewTable = FALSE;
+
+ if (!bModified && ValidCol(aCursorPos.Col()))
+ {
+ if (pActiveViewSh)
+ {
+ ImplCreateEditEngine();
+ UpdateActiveView();
+ SyncViews();
+
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
+
+ const ScMarkData& rMark = pActiveViewSh->GetViewData()->GetMarkData();
+ ScEditableTester aTester;
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ aTester.TestSelection( pDoc, rMark );
+ else
+ aTester.TestSelectedBlock( pDoc, aCursorPos.Col(),aCursorPos.Row(),
+ aCursorPos.Col(),aCursorPos.Row(), rMark );
+ if ( aTester.IsEditable() )
+ {
+ // UpdateMode is enabled again in ScViewData::SetEditEngine (and not needed otherwise)
+ pEngine->SetUpdateMode( FALSE );
+
+ // Attribute in EditEngine uebernehmen
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(),
+ aCursorPos.Row(),
+ aCursorPos.Tab() );
+ if (pPattern != pLastPattern)
+ {
+ // Prozent-Format?
+
+ const SfxItemSet& rAttrSet = pPattern->GetItemSet();
+ const SfxPoolItem* pItem;
+
+ if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALUE_FORMAT, TRUE, &pItem ) )
+ {
+ ULONG nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ bCellHasPercentFormat = ( NUMBERFORMAT_PERCENT ==
+ pDoc->GetFormatTable()->GetType( nFormat ) );
+ }
+ else
+ bCellHasPercentFormat = FALSE; // Default: kein Prozent
+
+ // Gueltigkeit angegeben?
+
+ if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALIDDATA, TRUE, &pItem ) )
+ nValidation = ((const SfxUInt32Item*)pItem)->GetValue();
+ else
+ nValidation = 0;
+
+ // EditEngine Defaults
+
+ // Hier auf keinen Fall SetParaAttribs, weil die EditEngine evtl.
+ // schon gefuellt ist (bei Edit-Zellen).
+ // SetParaAttribs wuerde dann den Inhalt aendern
+
+ //! ER 30.08.00 The SetDefaults is now (since MUST/src602
+ //! EditEngine changes) implemented as a SetParaAttribs.
+ //! Any problems?
+
+ pPattern->FillEditItemSet( pEditDefaults );
+ pEngine->SetDefaults( *pEditDefaults );
+ pLastPattern = pPattern;
+ bLastIsSymbol = pPattern->IsSymbolFont();
+
+ // Background color must be known for automatic font color.
+ // For transparent cell background, the document background color must be used.
+
+ Color aBackCol = ((const SvxBrushItem&)
+ pPattern->GetItem( ATTR_BACKGROUND )).GetColor();
+ ScModule* pScMod = SC_MOD();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ if ( aBackCol.GetTransparency() > 0 ||
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+ pEngine->SetBackgroundColor( aBackCol );
+
+ // Ausrichtung
+
+ eAttrAdjust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
+ GetItem(ATTR_HOR_JUSTIFY)).GetValue();
+ if ( eAttrAdjust == SVX_HOR_JUSTIFY_REPEAT &&
+ static_cast<const SfxBoolItem&>(pPattern->GetItem(ATTR_LINEBREAK)).GetValue() )
+ {
+ // #i31843# "repeat" with "line breaks" is treated as default alignment
+ eAttrAdjust = SVX_HOR_JUSTIFY_STANDARD;
+ }
+ }
+
+ // UpdateSpellSettings enables online spelling if needed
+ // -> also call if attributes are unchanged
+
+ UpdateSpellSettings( TRUE ); // uses pLastPattern
+
+ // Edit-Engine fuellen
+
+ String aStr;
+ if (bTextValid)
+ {
+ pEngine->SetText(aCurrentText);
+ aStr = aCurrentText;
+ bTextValid = FALSE;
+ aCurrentText.Erase();
+ }
+ else
+ aStr = GetEditText(pEngine);
+
+ if (aStr.Len() > 3 && // Matrix-Formel ?
+ aStr.GetChar(0) == '{' &&
+ aStr.GetChar(1) == '=' &&
+ aStr.GetChar(aStr.Len()-1) == '}')
+ {
+ aStr.Erase(0,1);
+ aStr.Erase(aStr.Len()-1,1);
+ pEngine->SetText(aStr);
+ if ( pInputWin )
+ pInputWin->SetTextString(aStr);
+ }
+
+ UpdateAdjust( cTyped );
+
+ if ( bAutoComplete )
+ GetColData();
+
+ if ( ( aStr.GetChar(0) == '=' || aStr.GetChar(0) == '+' || aStr.GetChar(0) == '-' ) &&
+ !cTyped && !bCreatingFuncView )
+ InitRangeFinder(aStr); // Formel wird editiert -> RangeFinder
+
+ bNewTable = TRUE; // -> PostEditView-Aufruf
+ }
+ else
+ {
+ bProtected = TRUE;
+ eMode = SC_INPUT_NONE;
+ StopInputWinEngine( TRUE );
+ UpdateFormulaMode();
+ if ( pActiveViewSh && ( !bFromCommand || !bCommandErrorShown ) )
+ {
+ // #97673# Prevent repeated error messages for the same cell from command events
+ // (for keyboard events, multiple messages are wanted).
+ // Set the flag before showing the error message because the command handler
+ // for the next IME command may be called when showing the dialog.
+ if ( bFromCommand )
+ bCommandErrorShown = TRUE;
+
+ pActiveViewSh->GetActiveWin()->GrabFocus();
+ pActiveViewSh->ErrorMessage(aTester.GetMessageId());
+ }
+ }
+ }
+
+ if (!bProtected && pInputWin)
+ pInputWin->SetOkCancelMode();
+ }
+
+ return bNewTable;
+}
+
+void lcl_SetTopSelection( EditView* pEditView, ESelection& rSel )
+{
+ DBG_ASSERT( rSel.nStartPara==0 && rSel.nEndPara==0, "SetTopSelection: Para != 0" );
+
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ USHORT nCount = pEngine->GetParagraphCount();
+ if (nCount > 1)
+ {
+ xub_StrLen nParLen = pEngine->GetTextLen(rSel.nStartPara);
+ while (rSel.nStartPos > nParLen && rSel.nStartPara+1 < nCount)
+ {
+ rSel.nStartPos -= nParLen + 1; // incl. Leerzeichen vom Umbruch
+ nParLen = pEngine->GetTextLen(++rSel.nStartPara);
+ }
+
+ nParLen = pEngine->GetTextLen(rSel.nEndPara);
+ while (rSel.nEndPos > nParLen && rSel.nEndPara+1 < nCount)
+ {
+ rSel.nEndPos -= nParLen + 1; // incl. Leerzeichen vom Umbruch
+ nParLen = pEngine->GetTextLen(++rSel.nEndPara);
+ }
+ }
+
+ ESelection aSel = pEditView->GetSelection();
+
+ if ( rSel.nStartPara != aSel.nStartPara || rSel.nEndPara != aSel.nEndPara
+ || rSel.nStartPos != aSel.nStartPos || rSel.nEndPos != aSel.nEndPos )
+ pEditView->SetSelection( rSel );
+}
+
+void ScInputHandler::SyncViews( EditView* pSourceView )
+{
+ ESelection aSel;
+
+ if (pSourceView)
+ {
+ aSel = pSourceView->GetSelection();
+ if (pTopView && pTopView != pSourceView)
+ pTopView->SetSelection( aSel );
+ if (pTableView && pTableView != pSourceView)
+ lcl_SetTopSelection( pTableView, aSel );
+ }
+ else if (pTopView && pTableView)
+ {
+ aSel = pTopView->GetSelection();
+ lcl_SetTopSelection( pTableView, aSel );
+ }
+}
+
+IMPL_LINK( ScInputHandler, ModifyHdl, void *, EMPTYARG )
+{
+ if ( !bInOwnChange && ( eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE ) &&
+ pEngine && pEngine->GetUpdateMode() && pInputWin )
+ {
+ // #102745# update input line from ModifyHdl for changes that are not
+ // wrapped by DataChanging/DataChanged calls (like Drag&Drop)
+
+ String aText = GetEditText(pEngine);
+ lcl_RemoveTabs(aText);
+ pInputWin->SetTextString(aText);
+ }
+ return 0;
+}
+
+BOOL ScInputHandler::DataChanging( sal_Unicode cTyped, BOOL bFromCommand ) // return TRUE = new view created
+{
+ bInOwnChange = TRUE; // disable ModifyHdl (reset in DataChanged)
+
+ if ( eMode == SC_INPUT_NONE )
+ return StartTable( cTyped, bFromCommand );
+ else
+ return FALSE;
+}
+
+void ScInputHandler::DataChanged( BOOL bFromTopNotify )
+{
+ ImplCreateEditEngine();
+
+ if (eMode==SC_INPUT_NONE)
+ eMode = SC_INPUT_TYPE;
+
+ if ( eMode == SC_INPUT_TOP && pTopView && !bFromTopNotify )
+ {
+ // table EditEngine is formatted below, input line needs formatting after paste
+ // #i20282# not when called from the input line's modify handler
+ pTopView->GetEditEngine()->QuickFormatDoc( TRUE );
+
+ // #i23720# QuickFormatDoc hides the cursor, but can't show it again because it
+ // can't safely access the EditEngine's current view, so the cursor has to be
+ // shown again here.
+ pTopView->ShowCursor();
+ }
+
+ bModified = TRUE;
+ bSelIsRef = FALSE;
+
+ if ( pRangeFindList && !bInRangeUpdate )
+ RemoveRangeFinder(); // Attribute und Markierung loeschen
+
+ UpdateParenthesis(); // Hervorhebung der Klammern neu
+
+ // ER 31.08.00 New SetDefaults sets ParaAttribs, don't clear them away ...
+// RemoveAdjust(); // #40255# harte Ausrichtungs-Attribute loeschen
+
+ if (eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE)
+ {
+ String aText = GetEditText(pEngine);
+ lcl_RemoveTabs(aText);
+
+ if ( pInputWin )
+ pInputWin->SetTextString(aText);
+ }
+
+ // wenn der Cursor vor dem Absatzende steht, werden Teile rechts rausgeschoben
+ // (unabhaengig von eMode) -> View anpassen!
+ // wenn der Cursor am Ende steht, reicht der Status-Handler an der ViewData
+
+ // #93767# first make sure the status handler is called now if the cursor
+ // is outside the visible area
+ pEngine->QuickFormatDoc();
+
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (pActiveView && pActiveViewSh)
+ {
+ ScViewData* pViewData = pActiveViewSh->GetViewData();
+
+ BOOL bNeedGrow = ( nEditAdjust != SVX_ADJUST_LEFT ); // rechtsbuendig immer
+ if (!bNeedGrow)
+ {
+ // Cursor vor dem Ende?
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+ bNeedGrow = ( aSel.nEndPos != pEngine->GetTextLen(aSel.nEndPara) );
+ }
+ if (!bNeedGrow)
+ {
+ bNeedGrow = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+ }
+ if (bNeedGrow)
+ {
+ // adjust inplace view
+ pViewData->EditGrowY();
+ pViewData->EditGrowX();
+ }
+ }
+
+ UpdateFormulaMode();
+ bTextValid = FALSE; // Aenderungen sind nur in der Edit-Engine
+ bInOwnChange = FALSE;
+}
+
+void ScInputHandler::UpdateFormulaMode()
+{
+ SfxApplication* pSfxApp = SFX_APP();
+
+ if ( pEngine->GetParagraphCount() == 1 &&
+ ( pEngine->GetText((USHORT)0).GetChar(0) == '=' ||
+ pEngine->GetText((USHORT)0).GetChar(0) == '+' ||
+ pEngine->GetText((USHORT)0).GetChar(0) == '-' ) &&
+ !bProtected )
+ {
+ if (!bFormulaMode)
+ {
+ bFormulaMode = TRUE;
+ pRefViewSh = pActiveViewSh;
+ pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
+ SC_MOD()->SetRefInputHdl(this);
+ if (pInputWin)
+ pInputWin->SetFormulaMode(TRUE);
+
+ if ( bAutoComplete )
+ GetFormulaData();
+
+ UpdateParenthesis();
+ UpdateAutoCorrFlag();
+ }
+ }
+ else // ausschalten
+ {
+ if (bFormulaMode)
+ {
+ ShowRefFrame();
+ bFormulaMode = FALSE;
+ pRefViewSh = NULL;
+ pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
+ SC_MOD()->SetRefInputHdl(NULL);
+ if (pInputWin)
+ pInputWin->SetFormulaMode(FALSE);
+ UpdateAutoCorrFlag();
+ }
+ }
+}
+
+void ScInputHandler::ShowRefFrame()
+{
+ // #123169# Modifying pActiveViewSh here would interfere with the bInEnterHandler / bRepeat
+ // checks in NotifyChange, and lead to keeping the wrong value in pActiveViewSh.
+ // A local variable is used instead.
+ ScTabViewShell* pVisibleSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ if ( pRefViewSh && pRefViewSh != pVisibleSh )
+ {
+ BOOL bFound = FALSE;
+ SfxViewFrame* pRefFrame = pRefViewSh->GetViewFrame();
+ SfxViewFrame* pOneFrame = SfxViewFrame::GetFirst();
+ while ( pOneFrame && !bFound )
+ {
+ if ( pOneFrame == pRefFrame )
+ bFound = TRUE;
+ pOneFrame = SfxViewFrame::GetNext( *pOneFrame );
+ }
+
+ if (bFound)
+ {
+ // Hier wird sich darauf verlassen, dass Activate synchron funktioniert
+ // (dabei wird pActiveViewSh umgesetzt)
+
+ pRefViewSh->SetActive(); // Appear und SetViewFrame
+
+ // pLastState wird im NotifyChange aus dem Activate richtig gesetzt
+ }
+ else
+ {
+ DBG_ERROR("ViewFrame fuer Referenzeingabe ist nicht mehr da");
+ }
+ }
+}
+
+void ScInputHandler::RemoveSelection()
+{
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (!pActiveView)
+ return;
+
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.nStartPara = aSel.nEndPara;
+ aSel.nStartPos = aSel.nEndPos;
+ if (pTableView)
+ pTableView->SetSelection( aSel );
+ if (pTopView)
+ pTopView->SetSelection( aSel );
+}
+
+void ScInputHandler::InvalidateAttribs()
+{
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ {
+ SfxBindings& rBindings = pViewFrm->GetBindings();
+
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+
+ rBindings.Invalidate( SID_HYPERLINK_GETLINK );
+ }
+}
+
+
+//
+// --------------- public Methoden --------------------------------------------
+//
+
+void ScInputHandler::SetMode( ScInputMode eNewMode )
+{
+ if ( eMode == eNewMode )
+ return;
+
+ ImplCreateEditEngine();
+
+ if (bProtected)
+ {
+ eMode = SC_INPUT_NONE;
+ StopInputWinEngine( TRUE );
+ if (pActiveViewSh)
+ pActiveViewSh->GetActiveWin()->GrabFocus();
+ return;
+ }
+
+ bInOwnChange = TRUE; // disable ModifyHdl (reset below)
+
+ ScInputMode eOldMode = eMode;
+ eMode = eNewMode;
+ if (eOldMode == SC_INPUT_TOP && eNewMode != eOldMode)
+ StopInputWinEngine( FALSE );
+
+ if (eMode==SC_INPUT_TOP || eMode==SC_INPUT_TABLE)
+ {
+ if (eOldMode == SC_INPUT_NONE) // not when switching between modes
+ {
+ if (StartTable(0, FALSE)) // 0 = look at existing document content for text or number
+ {
+ if (pActiveViewSh)
+ pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
+ }
+ }
+
+ USHORT nPara = pEngine->GetParagraphCount()-1;
+ xub_StrLen nLen = pEngine->GetText(nPara).Len();
+ USHORT nCount = pEngine->GetViewCount();
+
+ for (USHORT i=0; i<nCount; i++)
+ {
+ if ( eMode == SC_INPUT_TABLE && eOldMode == SC_INPUT_TOP )
+ {
+ // Selektion bleibt
+ }
+ else
+ {
+ pEngine->GetView(i)->
+ SetSelection( ESelection( nPara, nLen, nPara, nLen ) );
+ }
+ pEngine->GetView(i)->ShowCursor(FALSE);
+ }
+ }
+
+ UpdateActiveView();
+ if (eMode==SC_INPUT_TABLE || eMode==SC_INPUT_TYPE)
+ {
+ if (pTableView)
+ pTableView->SetEditEngineUpdateMode(TRUE);
+ }
+ else
+ {
+ if (pTopView)
+ pTopView->SetEditEngineUpdateMode(TRUE);
+ }
+
+ if (eNewMode != eOldMode)
+ UpdateFormulaMode();
+
+ bInOwnChange = FALSE;
+}
+
+//----------------------------------------------------------------------------------------
+
+// lcl_IsNumber - TRUE, wenn nur Ziffern (dann keine Autokorrektur)
+
+BOOL lcl_IsNumber(const String& rString)
+{
+ xub_StrLen nLen = rString.Len();
+ for (xub_StrLen i=0; i<nLen; i++)
+ {
+ sal_Unicode c = rString.GetChar(i);
+ if ( c < '0' || c > '9' )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void lcl_SelectionToEnd( EditView* pView )
+{
+ if ( pView )
+ {
+ EditEngine* pEngine = pView->GetEditEngine();
+ USHORT nParCnt = pEngine->GetParagraphCount();
+ if ( nParCnt == 0 )
+ nParCnt = 1;
+ ESelection aSel( nParCnt-1, pEngine->GetTextLen(nParCnt-1) ); // empty selection, cursor at the end
+ pView->SetSelection( aSel );
+ }
+}
+
+void ScInputHandler::EnterHandler( BYTE nBlockMode )
+{
+ // #62806# Bei Makro-Aufrufen fuer Gueltigkeit kann Tod und Teufel passieren,
+ // darum dafuer sorgen, dass EnterHandler nicht verschachtelt gerufen wird:
+
+ if (bInEnterHandler) return;
+ bInEnterHandler = TRUE;
+ bInOwnChange = TRUE; // disable ModifyHdl (reset below)
+
+ ImplCreateEditEngine();
+
+ BOOL bMatrix = ( nBlockMode == SC_ENTER_MATRIX );
+
+ SfxApplication* pSfxApp = SFX_APP();
+ EditTextObject* pObject = NULL;
+ ScPatternAttr* pCellAttrs = NULL;
+ BOOL bAttrib = FALSE; // Formatierung vorhanden ?
+ BOOL bForget = FALSE; // wegen Gueltigkeit streichen ?
+
+ String aString = GetEditText(pEngine);
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ if (bModified && pActiveView && aString.Len() && !lcl_IsNumber(aString))
+ {
+ if ( pColumnData && nAutoPos != SCPOS_INVALID )
+ {
+ // #i47125# If AutoInput appended something, do the final AutoCorrect
+ // with the cursor at the end of the input.
+
+ lcl_SelectionToEnd(pTopView);
+ lcl_SelectionToEnd(pTableView);
+ }
+
+ if (pTopView)
+ pTopView->CompleteAutoCorrect(); // #59759# CompleteAutoCorrect fuer beide Views
+ if (pTableView)
+ pTableView->CompleteAutoCorrect();
+ aString = GetEditText(pEngine);
+ }
+ lcl_RemoveTabs(aString);
+
+ // Test, ob zulaessig (immer mit einfachem String)
+
+ if ( bModified && nValidation && pActiveViewSh )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
+ const ScValidationData* pData = pDoc->GetValidationEntry( nValidation );
+ if (pData && pData->HasErrMsg())
+ {
+ // #i67990# don't use pLastPattern in EnterHandler
+ const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
+ BOOL bOk = pData->IsDataValid( aString, *pPattern, aCursorPos );
+
+ if (!bOk)
+ {
+ if ( pActiveViewSh ) // falls aus MouseButtonDown gekommen
+ pActiveViewSh->StopMarking(); // (die InfoBox verschluckt das MouseButtonUp)
+
+ //! es gibt noch Probleme, wenn die Eingabe durch Aktivieren einer
+ //! anderen View ausgeloest wurde
+
+ Window* pParent = Application::GetDefDialogParent();
+ if ( pData->DoError( pParent, aString, aCursorPos ) )
+ bForget = TRUE; // Eingabe nicht uebernehmen
+ }
+ }
+ }
+
+ // check for input into DataPilot table
+
+ if ( bModified && pActiveViewSh && !bForget )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
+ if ( pDPObj )
+ {
+ // any input within the DataPilot table is either a valid renaming
+ // or an invalid action - normal cell input is always aborted
+
+ pActiveViewSh->DataPilotInput( aCursorPos, aString );
+ bForget = TRUE;
+ }
+ }
+
+ pEngine->CompleteOnlineSpelling();
+ BOOL bSpellErrors = !bFormulaMode && pEngine->HasOnlineSpellErrors();
+ if ( bSpellErrors )
+ {
+ // #i3820# If the spell checker flags numerical input as error,
+ // it still has to be treated as number, not EditEngine object.
+
+ if ( pActiveViewSh )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
+ // #i67990# don't use pLastPattern in EnterHandler
+ const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ // without conditional format, as in ScColumn::SetString
+ sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter );
+ double nVal;
+ if ( pFormatter->IsNumberFormat( aString, nFormat, nVal ) )
+ {
+ bSpellErrors = FALSE; // ignore the spelling errors
+ }
+ }
+ }
+
+ // After RemoveAdjust, the EditView must not be repainted (has wrong font size etc).
+ // SetUpdateMode must come after CompleteOnlineSpelling.
+ // The view is hidden in any case below (Broadcast).
+ pEngine->SetUpdateMode( FALSE );
+
+ if ( bModified && !bForget ) // was wird eingeben (Text/Objekt) ?
+ {
+ USHORT nParCnt = pEngine->GetParagraphCount();
+ if ( nParCnt == 0 )
+ nParCnt = 1;
+ ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
+ SfxItemSet aOldAttribs = pEngine->GetAttribs( aSel );
+ const SfxPoolItem* pItem = NULL;
+
+ // find common (cell) attributes before RemoveAdjust
+
+ if ( pActiveViewSh )
+ {
+ SfxItemSet* pCommonAttrs = NULL;
+ for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END; nId++)
+ {
+ SfxItemState eState = aOldAttribs.GetItemState( nId, FALSE, &pItem );
+ if ( eState == SFX_ITEM_SET &&
+ nId != EE_CHAR_ESCAPEMENT && nId != EE_CHAR_PAIRKERNING &&
+ nId != EE_CHAR_KERNING && nId != EE_CHAR_XMLATTRIBS &&
+ *pItem != pEditDefaults->Get(nId) )
+ {
+ if ( !pCommonAttrs )
+ pCommonAttrs = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pCommonAttrs->Put( *pItem );
+ }
+ }
+
+ if ( pCommonAttrs )
+ {
+ ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
+ pCellAttrs = new ScPatternAttr( pDoc->GetPool() );
+ pCellAttrs->GetFromEditItemSet( pCommonAttrs );
+ delete pCommonAttrs;
+ }
+ }
+
+ // clear ParaAttribs (including adjustment)
+
+ RemoveAdjust();
+
+ // check if EditObject is needed
+
+ if ( bSpellErrors || nParCnt > 1 )
+ bAttrib = TRUE;
+ else
+ {
+ for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END && !bAttrib; nId++)
+ {
+ SfxItemState eState = aOldAttribs.GetItemState( nId, FALSE, &pItem );
+ if (eState == SFX_ITEM_DONTCARE)
+ bAttrib = TRUE;
+ else if (eState == SFX_ITEM_SET)
+ {
+ // keep same items in EditEngine as in ScEditAttrTester
+ if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
+ nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
+ {
+ if ( *pItem != pEditDefaults->Get(nId) )
+ bAttrib = TRUE;
+ }
+ }
+ }
+
+ // Feldbefehle enthalten?
+
+ SfxItemState eFieldState = aOldAttribs.GetItemState( EE_FEATURE_FIELD, FALSE );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bAttrib = TRUE;
+
+ // not converted characters?
+
+ SfxItemState eConvState = aOldAttribs.GetItemState( EE_FEATURE_NOTCONV, FALSE );
+ if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
+ bAttrib = TRUE;
+
+ // Formeln immer als Formeln erkennen (#38309#)
+ // (der Test vorher ist trotzdem noetig wegen Zell-Attributen)
+ }
+
+ if (bMatrix)
+ bAttrib = FALSE;
+
+ if (bAttrib)
+ {
+ ULONG nCtrl = pEngine->GetControlWord();
+ ULONG nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
+ if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
+ pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
+ pObject = pEngine->CreateTextObject();
+ }
+ else if (bAutoComplete) // Gross-/Kleinschreibung anpassen
+ {
+ if (pColumnData)
+ pColumnData->GetExactMatch( aString );
+
+ //! effizienter in der Liste suchen (ScUserList, nur einmal ToUpper)
+
+ USHORT nIndex;
+ ScUserListData* pData = ScGlobal::GetUserList()->GetData(aString);
+ if ( pData && pData->GetSubIndex( aString, nIndex ) )
+ aString = pData->GetSubStr( nIndex );
+ }
+ }
+
+ // don't rely on ShowRefFrame switching the active view synchronously
+ // execute the function directly on the correct view's bindings instead
+ // pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
+ ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;
+
+ if (bFormulaMode)
+ {
+ ShowRefFrame();
+
+ if (pExecuteSh)
+ {
+ pExecuteSh->SetTabNo(aCursorPos.Tab());
+ pExecuteSh->ActiveGrabFocus();
+ }
+
+ bFormulaMode = FALSE;
+ pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
+ SC_MOD()->SetRefInputHdl(NULL);
+ if (pInputWin)
+ pInputWin->SetFormulaMode(FALSE);
+ UpdateAutoCorrFlag();
+ }
+ pRefViewSh = NULL; // auch ohne FormulaMode wegen Funktions-AP
+ DeleteRangeFinder();
+ ResetAutoPar();
+
+ BOOL bOldMod = bModified;
+
+ bModified = FALSE;
+ bSelIsRef = FALSE;
+ eMode = SC_INPUT_NONE;
+ StopInputWinEngine( TRUE );
+
+ // #123344# Text input (through number formats) or ApplySelectionPattern modify
+ // the cell's attributes, so pLastPattern is no longer valid
+ pLastPattern = NULL;
+
+ if (bOldMod && !bProtected && !bForget)
+ {
+ // keine typographische Anfuehrungszeichen in Formeln
+
+ if ( aString.GetChar(0) == '=' )
+ {
+ SvxAutoCorrect* pAuto = SvxAutoCorrCfg::Get()->GetAutoCorrect();
+ if ( pAuto )
+ {
+ sal_Unicode cReplace = pAuto->GetStartDoubleQuote();
+ if( !cReplace )
+ cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart().GetChar(0);
+ if ( cReplace != '"' )
+ aString.SearchAndReplaceAll( cReplace, '"' );
+
+ cReplace = pAuto->GetEndDoubleQuote();
+ if( !cReplace )
+ cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd().GetChar(0);
+ if ( cReplace != '"' )
+ aString.SearchAndReplaceAll( cReplace, '"' );
+
+ cReplace = pAuto->GetStartSingleQuote();
+ if( !cReplace )
+ cReplace = ScGlobal::pLocaleData->getQuotationMarkStart().GetChar(0);
+ if ( cReplace != '\'' )
+ aString.SearchAndReplaceAll( cReplace, '\'' );
+
+ cReplace = pAuto->GetEndSingleQuote();
+ if( !cReplace )
+ cReplace = ScGlobal::pLocaleData->getQuotationMarkEnd().GetChar(0);
+ if ( cReplace != '\'' )
+ aString.SearchAndReplaceAll( cReplace, '\'' );
+ }
+ }
+
+ pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW_NOPAINT ) );
+
+ if ( pExecuteSh )
+ {
+ SfxBindings& rBindings = pExecuteSh->GetViewFrame()->GetBindings();
+
+ USHORT nId = FID_INPUTLINE_ENTER;
+ if ( nBlockMode == SC_ENTER_BLOCK )
+ nId = FID_INPUTLINE_BLOCK;
+ else if ( nBlockMode == SC_ENTER_MATRIX )
+ nId = FID_INPUTLINE_MATRIX;
+
+ ScInputStatusItem aItem( FID_INPUTLINE_STATUS,
+ aCursorPos, aCursorPos, aCursorPos,
+ aString, pObject );
+ const SfxPoolItem* aArgs[2];
+ aArgs[0] = &aItem;
+ aArgs[1] = NULL;
+ rBindings.Execute( nId, aArgs );
+ }
+
+ delete pLastState; // pLastState enthaelt noch den alten Text
+ pLastState = NULL;
+ }
+ else
+ pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
+
+ if ( bOldMod && pExecuteSh && pCellAttrs && !bForget )
+ {
+ // mit Eingabe zusammenfassen ?
+ pExecuteSh->ApplySelectionPattern( *pCellAttrs, TRUE, TRUE );
+ pExecuteSh->AdjustBlockHeight();
+ }
+
+ delete pCellAttrs;
+ delete pObject;
+
+ HideTip();
+ HideTipBelow();
+
+ nFormSelStart = nFormSelEnd = 0;
+ aFormText.Erase();
+
+ bInOwnChange = FALSE;
+ bInEnterHandler = FALSE;
+}
+
+void ScInputHandler::CancelHandler()
+{
+ bInOwnChange = TRUE; // disable ModifyHdl (reset below)
+
+ ImplCreateEditEngine();
+
+ bModified = FALSE;
+
+ // don't rely on ShowRefFrame switching the active view synchronously
+ // execute the function directly on the correct view's bindings instead
+ // pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
+ ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;
+
+ if (bFormulaMode)
+ {
+ ShowRefFrame();
+ if (pExecuteSh)
+ {
+ pExecuteSh->SetTabNo(aCursorPos.Tab());
+ pExecuteSh->ActiveGrabFocus();
+ }
+ bFormulaMode = FALSE;
+ SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
+ SC_MOD()->SetRefInputHdl(NULL);
+ if (pInputWin)
+ pInputWin->SetFormulaMode(FALSE);
+ UpdateAutoCorrFlag();
+ }
+ pRefViewSh = NULL; // auch ohne FormulaMode wegen Funktions-AP
+ DeleteRangeFinder();
+ ResetAutoPar();
+
+ eMode = SC_INPUT_NONE;
+ StopInputWinEngine( TRUE );
+ if (pExecuteSh)
+ pExecuteSh->StopEditShell();
+
+ aCursorPos.Set(MAXCOL+1,0,0); // Flag, dass ungueltig
+ pEngine->SetText(String());
+
+ if ( !pLastState && pExecuteSh )
+ pExecuteSh->UpdateInputHandler( TRUE ); // Status neu holen
+ else
+ NotifyChange( pLastState, TRUE );
+
+ nFormSelStart = nFormSelEnd = 0;
+ aFormText.Erase();
+
+ bInOwnChange = FALSE;
+}
+
+BOOL ScInputHandler::IsModalMode( SfxObjectShell* pDocSh )
+{
+ // Referenzen auf unbenanntes Dokument gehen nicht
+
+ return bFormulaMode && pRefViewSh
+ && pRefViewSh->GetViewData()->GetDocument()->GetDocumentShell() != pDocSh
+ && !pDocSh->HasName();
+}
+
+void ScInputHandler::AddRefEntry()
+{
+ const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ UpdateActiveView();
+ if (!pTableView && !pTopView)
+ return; // z.B. FillMode
+
+ DataChanging(); // kann nicht neu sein
+
+ RemoveSelection();
+ if (pTableView)
+ pTableView->InsertText( cSep, FALSE );
+ if (pTopView)
+ pTopView->InsertText( cSep, FALSE );
+
+ DataChanged();
+}
+
+void ScInputHandler::SetReference( const ScRange& rRef, ScDocument* pDoc )
+{
+ HideTip();
+
+ BOOL bOtherDoc = ( pRefViewSh &&
+ pRefViewSh->GetViewData()->GetDocument() != pDoc );
+ if (bOtherDoc)
+ if (!pDoc->GetDocumentShell()->HasName())
+ {
+ // Referenzen auf unbenanntes Dokument gehen nicht
+ // (SetReference sollte dann auch nicht gerufen werden)
+
+ return;
+ }
+
+ UpdateActiveView();
+ if (!pTableView && !pTopView)
+ return; // z.B. FillMode
+
+ // nie das "=" ueberschreiben!
+ EditView* pActiveView = pTopView ? pTopView : pTableView;
+ ESelection aSel = pActiveView->GetSelection();
+ aSel.Adjust();
+ if ( aSel.nStartPara == 0 && aSel.nStartPos == 0 )
+ return;
+
+ DataChanging(); // kann nicht neu sein
+
+ // Selektion umdrehen, falls rueckwaerts (noetig ???)
+
+ if (pTableView)
+ {
+ ESelection aTabSel = pTableView->GetSelection();
+ if (aTabSel.nStartPos > aTabSel.nEndPos && aTabSel.nStartPara == aTabSel.nEndPara)
+ {
+ aTabSel.Adjust();
+ pTableView->SetSelection(aTabSel);
+ }
+ }
+ if (pTopView)
+ {
+ ESelection aTopSel = pTopView->GetSelection();
+ if (aTopSel.nStartPos > aTopSel.nEndPos && aTopSel.nStartPara == aTopSel.nEndPara)
+ {
+ aTopSel.Adjust();
+ pTopView->SetSelection(aTopSel);
+ }
+ }
+
+ // String aus Referenz erzeugen
+
+ String aRefStr;
+ const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
+ if (bOtherDoc)
+ {
+ // Referenz auf anderes Dokument
+
+ DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");
+
+ String aTmp;
+ rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails ); // immer 3d
+
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ // #i75893# convert escaped URL of the document to something user friendly
+// String aFileName = pObjSh->GetMedium()->GetName();
+ String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+
+ aRefStr = '\'';
+ aRefStr += aFileName;
+ aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" ));
+ aRefStr += aTmp;
+ }
+ else
+ {
+ if ( ( rRef.aStart.Tab() != aCursorPos.Tab() ||
+ rRef.aStart.Tab() != rRef.aEnd.Tab() ) && pDoc )
+ rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );
+ else
+ rRef.Format( aRefStr, SCA_VALID, pDoc, aAddrDetails );
+ }
+
+ if (pTableView || pTopView)
+ {
+ if (pTableView)
+ pTableView->InsertText( aRefStr, TRUE );
+ if (pTopView)
+ pTopView->InsertText( aRefStr, TRUE );
+
+ DataChanged();
+ }
+
+ bSelIsRef = TRUE;
+}
+
+void ScInputHandler::InsertFunction( const String& rFuncName, BOOL bAddPar )
+{
+ if ( eMode == SC_INPUT_NONE )
+ {
+ DBG_ERROR("InsertFunction, nicht im Eingabemodus");
+ return;
+ }
+
+ UpdateActiveView();
+ if (!pTableView && !pTopView)
+ return; // z.B. FillMode
+
+ DataChanging(); // kann nicht neu sein
+
+ String aText = rFuncName;
+ if (bAddPar)
+ aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
+
+ if (pTableView)
+ {
+ pTableView->InsertText( aText, FALSE );
+ if (bAddPar)
+ {
+ ESelection aSel = pTableView->GetSelection();
+ --aSel.nStartPos;
+ --aSel.nEndPos;
+ pTableView->SetSelection(aSel);
+ }
+ }
+ if (pTopView)
+ {
+ pTopView->InsertText( aText, FALSE );
+ if (bAddPar)
+ {
+ ESelection aSel = pTopView->GetSelection();
+ --aSel.nStartPos;
+ --aSel.nEndPos;
+ pTopView->SetSelection(aSel);
+ }
+ }
+
+ DataChanged();
+
+ if (bAddPar)
+ AutoParAdded();
+}
+
+void ScInputHandler::ClearText()
+{
+ if ( eMode == SC_INPUT_NONE )
+ {
+ DBG_ERROR("ClearText, nicht im Eingabemodus");
+ return;
+ }
+
+ UpdateActiveView();
+ if (!pTableView && !pTopView)
+ return; // z.B. FillMode
+
+ DataChanging(); // darf nicht neu sein
+
+ String aEmpty;
+ if (pTableView)
+ {
+ pTableView->GetEditEngine()->SetText( aEmpty );
+ pTableView->SetSelection( ESelection(0,0, 0,0) );
+ }
+ if (pTopView)
+ {
+ pTopView->GetEditEngine()->SetText( aEmpty );
+ pTopView->SetSelection( ESelection(0,0, 0,0) );
+ }
+
+ DataChanged();
+}
+
+BOOL ScInputHandler::KeyInput( const KeyEvent& rKEvt, BOOL bStartEdit /* = FALSE */ )
+{
+ if (!bOptLoaded)
+ {
+ bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
+ bOptLoaded = TRUE;
+ }
+
+ KeyCode aCode = rKEvt.GetKeyCode();
+ USHORT nModi = aCode.GetModifier();
+ BOOL bShift = aCode.IsShift();
+ BOOL bControl = aCode.IsMod1();
+ BOOL bAlt = aCode.IsMod2();
+ USHORT nCode = aCode.GetCode();
+ sal_Unicode nChar = rKEvt.GetCharCode();
+
+ // Alt-Return is accepted, everything else with ALT, or CTRL-TAB are not:
+ if (( bAlt && !bControl && nCode != KEY_RETURN ) ||
+ ( bControl && aCode.GetCode() == KEY_TAB ))
+ return FALSE;
+
+ BOOL bInputLine = ( eMode==SC_INPUT_TOP );
+
+ BOOL bUsed = FALSE;
+ BOOL bSkip = FALSE;
+ BOOL bDoEnter = FALSE;
+
+ switch ( nCode )
+ {
+ case KEY_RETURN:
+ if (bControl && !bShift && !bInputLine)
+ bDoEnter = TRUE;
+ else if ( nModi == 0 && nTipVisible && pFormulaData && nAutoPos != SCPOS_INVALID )
+ {
+ PasteFunctionData();
+ bUsed = TRUE;
+ }
+ else if ( nModi == 0 && nTipVisible && aManualTip.Len() )
+ {
+ PasteManualTip();
+ bUsed = TRUE;
+ }
+ else
+ {
+ BYTE nMode = SC_ENTER_NORMAL;
+ if ( bShift && bControl )
+ nMode = SC_ENTER_MATRIX;
+ else if ( bAlt )
+ nMode = SC_ENTER_BLOCK;
+ EnterHandler( nMode );
+
+ if (pActiveViewSh)
+ pActiveViewSh->MoveCursorEnter( bShift && !bControl );
+
+ bUsed = TRUE;
+ }
+ break;
+ case KEY_TAB:
+ if (!bControl && !bAlt)
+ {
+ if ( pFormulaData && nTipVisible && nAutoPos != SCPOS_INVALID )
+ {
+ // blaettern
+
+ NextFormulaEntry( bShift );
+ }
+ else if ( pColumnData && bUseTab && nAutoPos != SCPOS_INVALID )
+ {
+ // in den Eintraegen der AutoEingabe blaettern
+
+ NextAutoEntry( bShift );
+ }
+ else
+ {
+ EnterHandler();
+
+ // TabKeyInput gibt auf manchen Rechnern unter W95 Stackueberlaeufe,
+ // darum direkter Aufruf:
+ if (pActiveViewSh)
+ pActiveViewSh->FindNextUnprot( bShift );
+ }
+ bUsed = TRUE;
+ }
+ break;
+ case KEY_ESCAPE:
+ if ( nTipVisible )
+ {
+ HideTip();
+ bUsed = TRUE;
+ }
+ else if( nTipVisibleSec )
+ {
+ HideTipBelow();
+ bUsed = TRUE;
+ }
+ else if (eMode != SC_INPUT_NONE)
+ {
+ CancelHandler();
+ bUsed = TRUE;
+ }
+ else
+ bSkip = TRUE;
+ break;
+ case KEY_F2:
+ if ( !bShift && !bControl && !bAlt && eMode == SC_INPUT_TABLE )
+ {
+ eMode = SC_INPUT_TYPE;
+ bUsed = TRUE;
+ }
+ break;
+ }
+
+ // Cursortasten nur ausfuehren, wenn schon im Edit-Modus
+ // z.B. wegen Shift-Ctrl-PageDn (ist nicht als Accelerator definiert)
+
+ BOOL bCursorKey = EditEngine::DoesKeyMoveCursor(rKEvt);
+ BOOL bInsKey = ( nCode == KEY_INSERT && !nModi ); // Insert wie Cursortasten behandeln
+ if ( !bUsed && !bSkip && ( bDoEnter || EditEngine::DoesKeyChangeText(rKEvt) ||
+ ( eMode != SC_INPUT_NONE && ( bCursorKey || bInsKey ) ) ) )
+ {
+ HideTip();
+ HideTipBelow();
+
+ if (bSelIsRef)
+ {
+ RemoveSelection();
+ bSelIsRef = FALSE;
+ }
+
+ UpdateActiveView();
+ BOOL bNewView = DataChanging( nChar );
+
+ if (bProtected) // Zelle geschuetzt?
+ bUsed = TRUE; // Key-Event nicht weiterleiten
+ else // Aenderungen erlaubt
+ {
+ if (bNewView ) // neu anlegen
+ {
+ if (pActiveViewSh)
+ pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
+ UpdateActiveView();
+ if (eMode==SC_INPUT_NONE)
+ if (pTableView || pTopView)
+ {
+ String aStrLoP;
+
+ if ( bStartEdit && bCellHasPercentFormat && ((nChar >= '0' && nChar <= '9') || nChar == '-') )
+ aStrLoP = '%';
+
+ if (pTableView)
+ {
+ pTableView->GetEditEngine()->SetText( aStrLoP );
+ if ( aStrLoP.Len() )
+ pTableView->SetSelection( ESelection(0,0, 0,0) ); // before the '%'
+
+ // don't call SetSelection if the string is empty anyway,
+ // to avoid breaking the bInitial handling in ScViewData::EditGrowY
+ }
+ if (pTopView)
+ {
+ pTopView->GetEditEngine()->SetText( aStrLoP );
+ if ( aStrLoP.Len() )
+ pTopView->SetSelection( ESelection(0,0, 0,0) ); // before the '%'
+ }
+ }
+ SyncViews();
+ }
+
+ if (pTableView || pTopView)
+ {
+// pActiveView->SetEditEngineUpdateMode(TRUE); //! gibt Muell !!!!
+
+ if (bDoEnter)
+ {
+ if (pTableView)
+ if( pTableView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
+ bUsed = TRUE;
+ if (pTopView)
+ if( pTopView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
+ bUsed = TRUE;
+ }
+ else if ( nAutoPar && nChar == ')' && CursorAtClosingPar() )
+ {
+ SkipClosingPar();
+ bUsed = TRUE;
+ }
+ else
+ {
+ if (pTableView)
+ if ( pTableView->PostKeyEvent( rKEvt ) )
+ bUsed = TRUE;
+ if (pTopView)
+ if ( pTopView->PostKeyEvent( rKEvt ) )
+ bUsed = TRUE;
+ }
+
+ // Auto-Eingabe:
+
+ if ( bUsed && bAutoComplete )
+ {
+ bUseTab = FALSE;
+ nAutoPos = SCPOS_INVALID; // do not search further
+
+ KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
+ if ( nChar && nChar != 8 && nChar != 127 && // no 'backspace', no 'delete'
+ KEYFUNC_CUT != eFunc) // and no 'CTRL-X'
+ {
+ if (bFormulaMode)
+ UseFormulaData();
+ else
+ UseColData();
+ }
+ }
+
+ // when the selection is changed manually or an opening parenthesis
+ // is typed, stop overwriting parentheses
+ if ( bUsed && nChar == '(' )
+ ResetAutoPar();
+
+ if ( KEY_INSERT == nCode )
+ {
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
+ }
+ if( bUsed && bFormulaMode && ( bCursorKey || bInsKey || nCode == KEY_DELETE || nCode == KEY_BACKSPACE ) )
+ {
+ ShowTipCursor();
+ }
+ }
+
+ DataChanged(); // ruft auch UpdateParenthesis()
+ InvalidateAttribs(); //! in DataChanged ?
+ }
+ }
+
+ if (pTopView && eMode != SC_INPUT_NONE)
+ SyncViews();
+
+ return bUsed;
+}
+
+BOOL ScInputHandler::InputCommand( const CommandEvent& rCEvt, BOOL bForce )
+{
+ BOOL bUsed = FALSE;
+
+ if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
+ {
+ // #90346# for COMMAND_CURSORPOS, do as little as possible, because
+ // with remote VCL, even a ShowCursor will generate another event.
+ if ( eMode != SC_INPUT_NONE )
+ {
+ UpdateActiveView();
+ if (pTableView || pTopView)
+ {
+ if (pTableView)
+ pTableView->Command( rCEvt );
+ else if (pTopView) // call only once
+ pTopView->Command( rCEvt );
+ bUsed = TRUE;
+ }
+ }
+ }
+ else
+ {
+ if ( bForce || eMode != SC_INPUT_NONE )
+ {
+ if (!bOptLoaded)
+ {
+ bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
+ bOptLoaded = TRUE;
+ }
+
+ HideTip();
+ HideTipBelow();
+
+ if ( bSelIsRef )
+ {
+ RemoveSelection();
+ bSelIsRef = FALSE;
+ }
+
+ UpdateActiveView();
+ BOOL bNewView = DataChanging( 0, TRUE );
+
+ if (bProtected) // cell protected
+ bUsed = TRUE; // event is used
+ else // changes allowed
+ {
+ if (bNewView) // create new edit view
+ {
+ if (pActiveViewSh)
+ pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
+ UpdateActiveView();
+ if (eMode==SC_INPUT_NONE)
+ if (pTableView || pTopView)
+ {
+ String aStrLoP;
+ if (pTableView)
+ {
+ pTableView->GetEditEngine()->SetText( aStrLoP );
+ pTableView->SetSelection( ESelection(0,0, 0,0) );
+ }
+ if (pTopView)
+ {
+ pTopView->GetEditEngine()->SetText( aStrLoP );
+ pTopView->SetSelection( ESelection(0,0, 0,0) );
+ }
+ }
+ SyncViews();
+ }
+
+ if (pTableView || pTopView)
+ {
+ if (pTableView)
+ pTableView->Command( rCEvt );
+ if (pTopView)
+ pTopView->Command( rCEvt );
+
+ bUsed = TRUE;
+
+ if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
+ {
+ // AutoInput after ext text input
+
+ nAutoPos = SCPOS_INVALID;
+ if (bFormulaMode)
+ UseFormulaData();
+ else
+ UseColData();
+ }
+ }
+
+ DataChanged(); // calls UpdateParenthesis()
+ InvalidateAttribs(); //! in DataChanged ?
+ }
+ }
+
+ if (pTopView && eMode != SC_INPUT_NONE)
+ SyncViews();
+ }
+
+ return bUsed;
+}
+
+void ScInputHandler::NotifyChange( const ScInputHdlState* pState,
+ BOOL bForce, ScTabViewShell* pSourceSh,
+ BOOL bStopEditing)
+{
+ // #62806# Wenn der Aufruf aus einem Makro-Aufruf im EnterHandler kommt,
+ // gleich abbrechen und nicht den Status durcheinander bringen
+ if (bInEnterHandler)
+ return;
+
+ BOOL bRepeat = (pState == pLastState);
+ if (!bRepeat && pState && pLastState)
+ bRepeat = sal::static_int_cast<BOOL>(*pState == *pLastState);
+ if (bRepeat && !bForce)
+ return;
+
+ bInOwnChange = TRUE; // disable ModifyHdl (reset below)
+
+ if ( pState && !pLastState ) // wieder enablen
+ bForce = TRUE;
+
+ BOOL bHadObject = pLastState && pLastState->GetEditData();
+
+ //! Before EditEngine gets eventually created (so it gets the right pools)
+ if ( pSourceSh )
+ pActiveViewSh = pSourceSh;
+ else
+ pActiveViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+
+ ImplCreateEditEngine();
+
+ if ( pState != pLastState )
+ {
+ delete pLastState;
+ pLastState = pState ? new ScInputHdlState( *pState ) : NULL;
+ }
+
+ if ( pState && pActiveViewSh )
+ {
+ ScModule* pScMod = SC_MOD();
+
+ if ( pState )
+ {
+ BOOL bIgnore = FALSE;
+
+ // hier auch fremde Referenzeingabe beruecksichtigen (z.B. Funktions-AP),
+ // FormEditData falls gerade von der Hilfe auf Calc umgeschaltet wird:
+
+ if ( !bFormulaMode && !pScMod->IsFormulaMode() && !pScMod->GetFormEditData() )
+ {
+ if ( bModified )
+ {
+ if (pState->GetPos() != aCursorPos)
+ {
+ if (!bProtected)
+ EnterHandler();
+ }
+ else
+ bIgnore = TRUE;
+ }
+
+ if ( !bIgnore /* || bRepeat */ )
+ {
+ const ScAddress& rSPos = pState->GetStartPos();
+ const ScAddress& rEPos = pState->GetEndPos();
+ const EditTextObject* pData = pState->GetEditData();
+ String aString = pState->GetString();
+ BOOL bTxtMod = FALSE;
+ ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ aCursorPos = pState->GetPos();
+
+ if ( pData /* || bRepeat */ )
+ bTxtMod = TRUE;
+ else if ( bHadObject )
+ bTxtMod = TRUE;
+ else if ( bTextValid )
+ bTxtMod = ( aString != aCurrentText );
+ else
+ bTxtMod = ( aString != GetEditText(pEngine) );
+
+ if ( bTxtMod || bForce )
+ {
+ if (pData)
+ {
+ pEngine->SetText( *pData );
+ aString = GetEditText(pEngine);
+ lcl_RemoveTabs(aString);
+ bTextValid = FALSE;
+ aCurrentText.Erase();
+ }
+ else
+ {
+ aCurrentText = aString;
+ bTextValid = TRUE; //! erst nur als String merken
+ }
+
+ if ( pInputWin )
+ pInputWin->SetTextString(aString);
+ }
+
+ if ( pInputWin ) // Bereichsanzeige
+ {
+ String aPosStr;
+ const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
+
+ // Ist der Bereich ein Name?
+ //! per Timer suchen ???
+
+ if ( pActiveViewSh )
+ pActiveViewSh->GetViewData()->GetDocument()->
+ GetRangeAtBlock( ScRange( rSPos, rEPos ), &aPosStr );
+
+ if ( !aPosStr.Len() ) // kein Name -> formatieren
+ {
+ USHORT nFlags = 0;
+ if( aAddrDetails.eConv == formula::FormulaGrammar::CONV_XL_R1C1 )
+ nFlags |= SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;
+ if ( rSPos != rEPos )
+ {
+ ScRange r(rSPos, rEPos);
+ nFlags |= (nFlags << 4);
+ r.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
+ }
+ else
+ aCursorPos.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
+ }
+
+ pInputWin->SetPosString(aPosStr);
+ pInputWin->SetSumAssignMode();
+ }
+
+ if (bStopEditing)
+ SFX_APP()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
+
+ // As long as the content is not edited, turn off online spelling.
+ // Online spelling is turned back on in StartTable, after setting
+ // the right language from cell attributes.
+
+ ULONG nCntrl = pEngine->GetControlWord();
+ if ( nCntrl & EE_CNTRL_ONLINESPELLING )
+ pEngine->SetControlWord( nCntrl & ~EE_CNTRL_ONLINESPELLING );
+
+ bModified = FALSE;
+ bSelIsRef = FALSE;
+ bProtected = FALSE;
+ bCommandErrorShown = FALSE;
+ }
+ }
+ }
+
+// bProtected = FALSE;
+
+ if ( pInputWin)
+ {
+ if(!pScMod->IsFormulaMode()&& !pScMod->IsRefDialogOpen()) //BugID 54702
+ { //Wenn RefDialog offen, dann nicht enablen
+ if ( !pInputWin->IsEnabled())
+ {
+ pInputWin->Enable();
+ if(pDelayTimer )
+ {
+ DELETEZ( pDelayTimer );
+ }
+ }
+ }
+ else if(pScMod->IsRefDialogOpen())
+ { // Da jedes Dokument eigenes InputWin hat, sollte
+ if ( !pDelayTimer ) // nochmals Timer gestartet werden, da sonst Ein-
+ { // gabezeile evt. noch aktiv ist.
+ pDelayTimer = new Timer;
+ pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
+ pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
+ pDelayTimer->Start();
+ }
+ }
+ }
+ }
+ else // !pState || !pActiveViewSh
+ {
+ if ( !pDelayTimer )
+ {
+ pDelayTimer = new Timer;
+ pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
+ pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
+ pDelayTimer->Start();
+ }
+ }
+
+ HideTip();
+ HideTipBelow();
+ bInOwnChange = FALSE;
+}
+
+void ScInputHandler::UpdateCellAdjust( SvxCellHorJustify eJust )
+{
+ eAttrAdjust = eJust;
+ UpdateAdjust( 0 );
+}
+
+void ScInputHandler::ResetDelayTimer()
+{
+ if(pDelayTimer!=NULL)
+ {
+ DELETEZ( pDelayTimer );
+
+ if ( pInputWin)
+ {
+ pInputWin->Enable();
+ }
+ }
+}
+
+IMPL_LINK( ScInputHandler, DelayTimer, Timer*, pTimer )
+{
+ if ( pTimer == pDelayTimer )
+ {
+ DELETEZ( pDelayTimer );
+
+ if ( NULL == pLastState || SC_MOD()->IsFormulaMode() || SC_MOD()->IsRefDialogOpen())
+ {
+ //! new method at ScModule to query if function autopilot is open
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
+ {
+ if ( pInputWin)
+ {
+ pInputWin->EnableButtons( FALSE );
+ pInputWin->Disable();
+ }
+ }
+ else if ( !bFormulaMode ) // #39210# Formel auch z.B. bei Hilfe behalten
+ {
+ bInOwnChange = TRUE; // disable ModifyHdl (reset below)
+
+ pActiveViewSh = NULL;
+ pEngine->SetText( EMPTY_STRING );
+ if ( pInputWin )
+ {
+ pInputWin->SetPosString( EMPTY_STRING );
+ pInputWin->SetTextString( EMPTY_STRING );
+ pInputWin->Disable();
+ }
+
+ bInOwnChange = FALSE;
+ }
+ }
+ }
+ return 0;
+}
+
+void ScInputHandler::InputSelection( EditView* pView )
+{
+ SyncViews( pView );
+ ShowTipCursor();
+ UpdateParenthesis(); // Selektion geaendert -> Klammer-Hervorhebung neu
+
+ // when the selection is changed manually, stop overwriting parentheses
+ ResetAutoPar();
+}
+
+void ScInputHandler::InputChanged( EditView* pView, BOOL bFromNotify )
+{
+ ESelection aSelection = pView->GetSelection();
+
+ UpdateActiveView();
+
+ // #i20282# DataChanged needs to know if this is from the input line's modify handler
+ BOOL bFromTopNotify = ( bFromNotify && pView == pTopView );
+
+ BOOL bNewView = DataChanging(); //! kann das hier ueberhaupt sein?
+ aCurrentText = pView->GetEditEngine()->GetText(); // auch den String merken
+ pEngine->SetText( aCurrentText );
+ DataChanged( bFromTopNotify );
+ bTextValid = TRUE; // wird in DataChanged auf FALSE gesetzt
+
+ if ( pActiveViewSh )
+ {
+ ScViewData* pViewData = pActiveViewSh->GetViewData();
+ if ( bNewView )
+ pViewData->GetDocShell()->PostEditView( pEngine, aCursorPos );
+
+ pViewData->EditGrowY();
+ pViewData->EditGrowX();
+ }
+
+ SyncViews( pView );
+}
+
+const String& ScInputHandler::GetEditString()
+{
+ if (pEngine)
+ {
+ aCurrentText = pEngine->GetText(); // immer neu aus Engine
+ bTextValid = TRUE;
+ }
+
+ return aCurrentText;
+}
+
+Size ScInputHandler::GetTextSize()
+{
+ Size aSize;
+ if ( pEngine )
+ aSize = Size( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );
+
+ return aSize;
+}
+
+BOOL ScInputHandler::GetTextAndFields( ScEditEngineDefaulter& rDestEngine )
+{
+ BOOL bRet = FALSE;
+ if (pEngine)
+ {
+ // Feldbefehle enthalten?
+
+ USHORT nParCnt = pEngine->GetParagraphCount();
+ SfxItemSet aSet = pEngine->GetAttribs( ESelection(0,0,nParCnt,0) );
+ SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ {
+ // Inhalt kopieren
+
+ EditTextObject* pObj = pEngine->CreateTextObject();
+ rDestEngine.SetText(*pObj);
+ delete pObj;
+
+ // Attribute loeschen
+
+ for (USHORT i=0; i<nParCnt; i++)
+ rDestEngine.QuickRemoveCharAttribs( i );
+
+ // Absaetze zusammenfassen
+
+ while ( nParCnt > 1 )
+ {
+ xub_StrLen nLen = rDestEngine.GetTextLen( (USHORT)0 );
+ ESelection aSel( 0,nLen, 1,0 );
+ rDestEngine.QuickInsertText( ' ', aSel ); // Umbruch durch Space ersetzen
+ --nParCnt;
+ }
+
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------
+// Methoden fuer FunktionsAutopiloten:
+// InputGetSelection, InputSetSelection, InputReplaceSelection, InputGetFormulaStr
+//------------------------------------------------------------------------
+
+void ScInputHandler::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd )
+{
+ rStart = nFormSelStart;
+ rEnd = nFormSelEnd;
+}
+
+//------------------------------------------------------------------------
+
+EditView* ScInputHandler::GetFuncEditView()
+{
+ UpdateActiveView(); // wegen pTableView
+
+ EditView* pView = NULL;
+ if ( pInputWin )
+ {
+ pInputWin->MakeDialogEditView();
+ pView = pInputWin->GetEditView();
+ }
+ else
+ {
+ if ( eMode != SC_INPUT_TABLE )
+ {
+ bCreatingFuncView = TRUE; // RangeFinder nicht anzeigen
+ SetMode( SC_INPUT_TABLE );
+ bCreatingFuncView = FALSE;
+ if ( pTableView )
+ pTableView->GetEditEngine()->SetText( EMPTY_STRING );
+ }
+ pView = pTableView;
+ }
+
+ return pView;
+}
+
+//------------------------------------------------------------------------
+
+void ScInputHandler::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd )
+{
+ if ( nStart <= nEnd )
+ {
+ nFormSelStart = nStart;
+ nFormSelEnd = nEnd;
+ }
+ else
+ {
+ nFormSelEnd = nStart;
+ nFormSelStart = nEnd;
+ }
+
+ EditView* pView = GetFuncEditView();
+ if (pView)
+ pView->SetSelection( ESelection(0,nStart, 0,nEnd) );
+
+ bModified = TRUE;
+}
+
+//------------------------------------------------------------------------
+
+void ScInputHandler::InputReplaceSelection( const String& rStr )
+{
+ if (!pRefViewSh)
+ pRefViewSh = pActiveViewSh;
+
+ DBG_ASSERT(nFormSelEnd>=nFormSelStart,"Selektion kaputt...");
+
+ xub_StrLen nOldLen = nFormSelEnd-nFormSelStart;
+ xub_StrLen nNewLen = rStr.Len();
+ if (nOldLen)
+ aFormText.Erase( nFormSelStart, nOldLen );
+ if (nNewLen)
+ aFormText.Insert( rStr, nFormSelStart );
+ nFormSelEnd = nFormSelStart + nNewLen;
+
+ EditView* pView = GetFuncEditView();
+ if (pView)
+ {
+ pView->SetEditEngineUpdateMode( FALSE );
+// pView->InsertText( rStr, TRUE );
+ pView->GetEditEngine()->SetText( aFormText );
+ pView->SetSelection( ESelection(0,nFormSelStart, 0,nFormSelEnd) );
+ pView->SetEditEngineUpdateMode( TRUE );
+ }
+ bModified = TRUE;
+}
+
+//------------------------------------------------------------------------
+
+String ScInputHandler::InputGetFormulaStr()
+{
+ return aFormText; //! eigene Membervariable?
+}
+
+//========================================================================
+// ScInputHdlState
+//========================================================================
+
+ScInputHdlState::ScInputHdlState( const ScAddress& rCurPos,
+ const ScAddress& rStartPos,
+ const ScAddress& rEndPos,
+ const String& rString,
+ const EditTextObject* pData )
+ : aCursorPos ( rCurPos ),
+ aStartPos ( rStartPos ),
+ aEndPos ( rEndPos ),
+ aString ( rString ),
+ pEditData ( pData ? pData->Clone() : NULL )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScInputHdlState::ScInputHdlState( const ScInputHdlState& rCpy )
+ : pEditData ( NULL )
+{
+ *this = rCpy;
+}
+
+//------------------------------------------------------------------------
+
+ScInputHdlState::~ScInputHdlState()
+{
+ delete pEditData;
+}
+
+//------------------------------------------------------------------------
+
+int ScInputHdlState::operator==( const ScInputHdlState& r ) const
+{
+ return ( (aStartPos == r.aStartPos)
+ && (aEndPos == r.aEndPos)
+ && (aCursorPos == r.aCursorPos)
+ && (aString == r.aString)
+ && ScGlobal::EETextObjEqual( pEditData, r.pEditData ) );
+}
+
+//------------------------------------------------------------------------
+
+ScInputHdlState& ScInputHdlState::operator=( const ScInputHdlState& r )
+{
+ delete pEditData;
+
+ aCursorPos = r.aCursorPos;
+ aStartPos = r.aStartPos;
+ aEndPos = r.aEndPos;
+ aString = r.aString;
+ pEditData = r.pEditData ? r.pEditData->Clone() : NULL;
+
+ return *this;
+}
+
+
+
+
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
new file mode 100644
index 000000000000..2cabe7f9f2d6
--- /dev/null
+++ b/sc/source/ui/app/inputwin.cxx
@@ -0,0 +1,1819 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <algorithm>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/imgmgr.hxx>
+#include <stdlib.h> // qsort
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/help.hxx>
+#include <svl/stritem.hxx>
+
+#include "inputwin.hxx"
+#include "scmod.hxx"
+#include "uiitems.hxx"
+#include "global.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "editutil.hxx"
+#include "inputhdl.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "appoptio.hxx"
+#include "rangenam.hxx"
+#include <formula/compiler.hrc>
+#include "dbcolect.hxx"
+#include "rangeutl.hxx"
+#include "docfunc.hxx"
+#include "funcdesc.hxx"
+#include <editeng/fontitem.hxx>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include "AccessibleEditObject.hxx"
+#include "AccessibleText.hxx"
+
+#define TEXT_STARTPOS 3
+#define THESIZE 1000000 //!!! langt... :-)
+#define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich?
+
+enum ScNameInputType
+{
+ SC_NAME_INPUT_CELL,
+ SC_NAME_INPUT_RANGE,
+ SC_NAME_INPUT_NAMEDRANGE,
+ SC_NAME_INPUT_DATABASE,
+ SC_NAME_INPUT_ROW,
+ SC_NAME_INPUT_SHEET,
+ SC_NAME_INPUT_DEFINE,
+ SC_NAME_INPUT_BAD_NAME,
+ SC_NAME_INPUT_BAD_SELECTION
+};
+
+
+//==================================================================
+// class ScInputWindowWrapper
+//==================================================================
+
+SFX_IMPL_CHILDWINDOW(ScInputWindowWrapper,FID_INPUTLINE_STATUS)
+
+ScInputWindowWrapper::ScInputWindowWrapper( Window* pParentP,
+ USHORT nId,
+ SfxBindings* pBindings,
+ SfxChildWinInfo* /* pInfo */ )
+ : SfxChildWindow( pParentP, nId )
+{
+ ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings );
+ pWindow = pWin;
+
+ pWin->Show();
+
+ pWin->SetSizePixel( pWin->CalcWindowSizePixel() );
+
+ eChildAlignment = SFX_ALIGN_LOWESTTOP;
+ pBindings->Invalidate( FID_TOGGLEINPUTLINE );
+}
+
+// GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!
+
+SfxChildWinInfo __EXPORT ScInputWindowWrapper::GetInfo() const
+{
+ SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
+ return aInfo;
+}
+
+//==================================================================
+
+#define IMAGE(id) pImgMgr->SeekImage(id, bHC)
+
+//==================================================================
+// class ScInputWindow
+//==================================================================
+
+ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) :
+#ifdef OS2
+// #37192# ohne WB_CLIPCHILDREN wg. os/2 Paintproblem
+ ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK) ),
+#else
+// mit WB_CLIPCHILDREN, sonst Flicker
+ ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK|WB_CLIPCHILDREN) ),
+#endif
+ aWndPos ( this ),
+ aTextWindow ( this ),
+ pInputHdl ( NULL ),
+ pBindings ( pBind ),
+ aTextOk ( ScResId( SCSTR_QHELP_BTNOK ) ), // nicht immer neu aus Resource
+ aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL ) ),
+ aTextSum ( ScResId( SCSTR_QHELP_BTNSUM ) ),
+ aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL ) ),
+ bIsOkCancelMode ( FALSE )
+{
+ ScModule* pScMod = SC_MOD();
+ SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
+
+ // #i73615# don't rely on SfxViewShell::Current while constructing the input line
+ // (also for GetInputHdl below)
+ ScTabViewShell* pViewSh = NULL;
+ SfxDispatcher* pDisp = pBind->GetDispatcher();
+ if ( pDisp )
+ {
+ SfxViewFrame* pViewFrm = pDisp->GetFrame();
+ if ( pViewFrm )
+ pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
+ }
+ DBG_ASSERT( pViewSh, "no view shell for input window" );
+
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ // Positionsfenster, 3 Buttons, Eingabefenster
+ InsertWindow ( 1, &aWndPos, 0, 0 );
+ InsertSeparator ( 1 );
+ InsertItem ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 );
+ InsertItem ( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
+ InsertItem ( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
+ InsertSeparator ( 5 );
+ InsertWindow ( 7, &aTextWindow, 0, 6 );
+
+ aWndPos .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) );
+ aWndPos .SetHelpId ( HID_INSWIN_POS );
+ aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
+ aTextWindow.SetHelpId ( HID_INSWIN_INPUT );
+
+ // kein SetHelpText, die Hilfetexte kommen aus der Hilfe
+
+ SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) );
+ SetHelpId ( SID_INPUT_FUNCTION, HID_INSWIN_CALC );
+
+ SetItemText ( SID_INPUT_SUM, aTextSum );
+ SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
+
+ SetItemText ( SID_INPUT_EQUAL, aTextEqual );
+ SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
+
+ SetHelpId( HID_SC_INPUTWIN ); // fuer die ganze Eingabezeile
+
+ aWndPos .Show();
+ aTextWindow .Show();
+
+ pInputHdl = SC_MOD()->GetInputHdl( pViewSh, FALSE ); // use own handler even if ref-handler is set
+ if (pInputHdl)
+ pInputHdl->SetInputWindow( this );
+
+ if ( pInputHdl && pInputHdl->GetFormString().Len() )
+ {
+ // Umschalten waehrend der Funktionsautopilot aktiv ist
+ // -> Inhalt des Funktionsautopiloten wieder anzeigen
+ //! auch Selektion (am InputHdl gemerkt) wieder anzeigen
+
+ aTextWindow.SetTextString( pInputHdl->GetFormString() );
+ }
+ else if ( pInputHdl && pInputHdl->IsInputMode() )
+ {
+ // wenn waehrend des Editierens die Eingabezeile weg war
+ // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
+ // wieder den gerade editierten Text aus dem InputHandler anzeigen
+
+ aTextWindow.SetTextString( pInputHdl->GetEditString() ); // Text anzeigen
+ if ( pInputHdl->IsTopMode() )
+ pInputHdl->SetMode( SC_INPUT_TABLE ); // Focus kommt eh nach unten
+ }
+ else if ( pViewSh )
+ pViewSh->UpdateInputHandler( TRUE ); // unbedingtes Update
+
+ pImgMgr->RegisterToolBox( this );
+}
+
+__EXPORT ScInputWindow::~ScInputWindow()
+{
+ BOOL bDown = ( ScGlobal::pSysLocale == NULL ); // after Clear?
+
+ // if any view's input handler has a pointer to this input window, reset it
+ // (may be several ones, #74522#)
+ // member pInputHdl is not used here
+
+ if ( !bDown )
+ {
+ TypeId aScType = TYPE(ScTabViewShell);
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh )
+ {
+ ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler();
+ if ( pHdl && pHdl->GetInputWindow() == this )
+ {
+ pHdl->SetInputWindow( NULL );
+ pHdl->StopInputWinEngine( FALSE ); // #125841# reset pTopView pointer
+ }
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+ }
+
+ SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
+}
+
+void ScInputWindow::SetInputHandler( ScInputHandler* pNew )
+{
+ // wird im Activate der View gerufen...
+
+ if ( pNew != pInputHdl )
+ {
+ // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
+ // geloeschten ViewShell, darum hier auf keinen Fall anfassen!
+
+ pInputHdl = pNew;
+ if (pInputHdl)
+ pInputHdl->SetInputWindow( this );
+ }
+}
+
+sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const
+{
+ sal_Bool bSubTotal(sal_False);
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ if ( pViewSh )
+ {
+ ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
+ sal_Int32 nRangeCount (pRangeList->Count());
+ sal_Int32 nRangeIndex (0);
+ while (!bSubTotal && nRangeIndex < nRangeCount)
+ {
+ const ScRange* pRange = pRangeList->GetObject( nRangeIndex );
+ if( pRange )
+ {
+ SCTAB nTabEnd(pRange->aEnd.Tab());
+ SCTAB nTab(pRange->aStart.Tab());
+ while (!bSubTotal && nTab <= nTabEnd)
+ {
+ SCROW nRowEnd(pRange->aEnd.Row());
+ SCROW nRow(pRange->aStart.Row());
+ while (!bSubTotal && nRow <= nRowEnd)
+ {
+ if (pDoc->RowFiltered(nRow, nTab))
+ bSubTotal = sal_True;
+ else
+ ++nRow;
+ }
+ ++nTab;
+ }
+ }
+ ++nRangeIndex;
+ }
+
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nDBCount (pDBCollection->GetCount());
+ sal_uInt16 nDBIndex (0);
+ while (!bSubTotal && nDBIndex < nDBCount)
+ {
+ ScDBData* pDB = (*pDBCollection)[nDBIndex];
+ if (pDB && pDB->HasAutoFilter())
+ {
+ nRangeIndex = 0;
+ while (!bSubTotal && nRangeIndex < nRangeCount)
+ {
+ const ScRange* pRange = pRangeList->GetObject( nRangeIndex );
+ if( pRange )
+ {
+ ScRange aDBArea;
+ pDB->GetArea(aDBArea);
+ if (aDBArea.Intersects(*pRange))
+ bSubTotal = sal_True;
+ }
+ ++nRangeIndex;
+ }
+ }
+ ++nDBIndex;
+ }
+ }
+ return bSubTotal;
+}
+
+void __EXPORT ScInputWindow::Select()
+{
+ ScModule* pScMod = SC_MOD();
+ ToolBox::Select();
+
+ switch ( GetCurItemId() )
+ {
+ case SID_INPUT_FUNCTION:
+ {
+ //! new method at ScModule to query if function autopilot is open
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
+ {
+ pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+
+ // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
+ // zu werden, egal ob's geklappt hat oder nicht
+// SetOkCancelMode();
+ }
+ }
+ break;
+
+ case SID_INPUT_CANCEL:
+ pScMod->InputCancelHandler();
+ SetSumAssignMode();
+ break;
+
+ case SID_INPUT_OK:
+ pScMod->InputEnterHandler();
+ SetSumAssignMode();
+ aTextWindow.Invalidate(); // sonst bleibt Selektion stehen
+ break;
+
+ case SID_INPUT_SUM:
+ {
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ if ( pViewSh )
+ {
+ const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ ScRangeList aMarkRangeList;
+ rMark.FillRangeListWithMarks( &aMarkRangeList, FALSE );
+ ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
+
+ // check if one of the marked ranges is empty
+ bool bEmpty = false;
+ const ULONG nCount = aMarkRangeList.Count();
+ for ( ULONG i = 0; i < nCount; ++i )
+ {
+ const ScRange aRange( *aMarkRangeList.GetObject( i ) );
+ if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() ) )
+ {
+ bEmpty = true;
+ break;
+ }
+ }
+
+ if ( bEmpty )
+ {
+ ScRangeList aRangeList;
+ const BOOL bDataFound = pViewSh->GetAutoSumArea( aRangeList );
+ if ( bDataFound )
+ {
+ const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
+ pViewSh->EnterAutoSum( aRangeList, bSubTotal ); // Block mit Summen fuellen
+ }
+ }
+ else
+ {
+ const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
+ for ( ULONG i = 0; i < nCount; ++i )
+ {
+ const ScRange aRange( *aMarkRangeList.GetObject( i ) );
+ const bool bSetCursor = ( i == nCount - 1 ? true : false );
+ const bool bContinue = ( i != 0 ? true : false );
+ if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
+ {
+ pViewSh->MarkRange( aRange, FALSE, FALSE );
+ pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
+ const ScRangeList aRangeList;
+ const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal );
+ SetFuncString( aFormula );
+ break;
+ }
+ }
+ }
+ }
+ else // nur in Eingabezeile einfuegen
+ {
+ ScRangeList aRangeList;
+ const BOOL bDataFound = pViewSh->GetAutoSumArea( aRangeList );
+ const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
+ const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal );
+ SetFuncString( aFormula );
+
+ if ( bDataFound && pScMod->IsEditMode() )
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
+ if ( pHdl )
+ {
+ pHdl->InitRangeFinder( aFormula );
+
+ //! SetSelection am InputHandler ???
+ //! bSelIsRef setzen ???
+ const xub_StrLen nOpen = aFormula.Search('(');
+ const xub_StrLen nLen = aFormula.Len();
+ if ( nOpen != STRING_NOTFOUND && nLen > nOpen )
+ {
+ sal_uInt8 nAdd(1);
+ if (bSubTotal)
+ nAdd = 3;
+ ESelection aSel(0,nOpen+nAdd,0,nLen-1);
+ EditView* pTableView = pHdl->GetTableView();
+ if (pTableView)
+ pTableView->SetSelection(aSel);
+ EditView* pTopView = pHdl->GetTopView();
+ if (pTopView)
+ pTopView->SetSelection(aSel);
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_INPUT_EQUAL:
+ {
+ aTextWindow.StartEditEngine();
+ if ( pScMod->IsEditMode() ) // nicht, wenn z.B. geschuetzt
+ {
+ aTextWindow.GrabFocus();
+ aTextWindow.SetTextString( '=' );
+
+ EditView* pView = aTextWindow.GetEditView();
+ if (pView)
+ {
+ pView->SetSelection( ESelection(0,1, 0,1) );
+ pScMod->InputChanged(pView);
+ SetOkCancelMode();
+ pView->SetEditEngineUpdateMode(TRUE);
+ }
+ }
+ break;
+ }
+ }
+}
+
+void __EXPORT ScInputWindow::Resize()
+{
+ ToolBox::Resize();
+
+ long nWidth = GetSizePixel().Width();
+ long nLeft = aTextWindow.GetPosPixel().X();
+ Size aSize = aTextWindow.GetSizePixel();
+
+ aSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 );
+ aTextWindow.SetSizePixel( aSize );
+ aTextWindow.Invalidate();
+}
+
+void ScInputWindow::SetFuncString( const String& rString, BOOL bDoEdit )
+{
+ //! new method at ScModule to query if function autopilot is open
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
+ aTextWindow.StartEditEngine();
+
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->IsEditMode() )
+ {
+ if ( bDoEdit )
+ aTextWindow.GrabFocus();
+ aTextWindow.SetTextString( rString );
+ EditView* pView = aTextWindow.GetEditView();
+ if (pView)
+ {
+ xub_StrLen nLen = rString.Len();
+
+ if ( nLen > 0 )
+ {
+ nLen--;
+ pView->SetSelection( ESelection( 0, nLen, 0, nLen ) );
+ }
+
+ pScMod->InputChanged(pView);
+ if ( bDoEdit )
+ SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel
+
+ pView->SetEditEngineUpdateMode(TRUE);
+ }
+ }
+}
+
+void ScInputWindow::SetPosString( const String& rStr )
+{
+ aWndPos.SetPos( rStr );
+}
+
+void ScInputWindow::SetTextString( const String& rString )
+{
+ if (rString.Len() <= 32767)
+ aTextWindow.SetTextString(rString);
+ else
+ {
+ String aNew = rString;
+ aNew.Erase(32767);
+ aTextWindow.SetTextString(aNew);
+ }
+}
+
+void ScInputWindow::SetOkCancelMode()
+{
+ //! new method at ScModule to query if function autopilot is open
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
+
+ ScModule* pScMod = SC_MOD();
+ SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
+ if (!bIsOkCancelMode)
+ {
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
+ RemoveItem( 3 );
+ InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 );
+ InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 );
+ SetItemText ( SID_INPUT_CANCEL, aTextCancel );
+ SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL );
+ SetItemText ( SID_INPUT_OK, aTextOk );
+ SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK );
+ bIsOkCancelMode = TRUE;
+ }
+}
+
+void ScInputWindow::SetSumAssignMode()
+{
+ //! new method at ScModule to query if function autopilot is open
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
+
+ ScModule* pScMod = SC_MOD();
+ SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
+ if (bIsOkCancelMode)
+ {
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
+ RemoveItem( 3 );
+ RemoveItem( 3 );
+ InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
+ InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
+ SetItemText ( SID_INPUT_SUM, aTextSum );
+ SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
+ SetItemText ( SID_INPUT_EQUAL, aTextEqual );
+ SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
+ bIsOkCancelMode = FALSE;
+
+ SetFormulaMode(FALSE); // kein editieren -> keine Formel
+ }
+}
+
+void ScInputWindow::SetFormulaMode( BOOL bSet )
+{
+ aWndPos.SetFormulaMode(bSet);
+ aTextWindow.SetFormulaMode(bSet);
+}
+
+void __EXPORT ScInputWindow::SetText( const String& rString )
+{
+ ToolBox::SetText(rString);
+}
+
+String __EXPORT ScInputWindow::GetText() const
+{
+ return ToolBox::GetText();
+}
+
+
+//UNUSED2008-05 EditView* ScInputWindow::ActivateEdit( const String& rText,
+//UNUSED2008-05 const ESelection& rSel )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( !aTextWindow.IsInputActive() )
+//UNUSED2008-05 {
+//UNUSED2008-05 aTextWindow.StartEditEngine();
+//UNUSED2008-05 aTextWindow.GrabFocus();
+//UNUSED2008-05 aTextWindow.SetTextString( rText );
+//UNUSED2008-05 aTextWindow.GetEditView()->SetSelection( rSel );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return aTextWindow.GetEditView();
+//UNUSED2008-05 }
+
+BOOL ScInputWindow::IsInputActive()
+{
+ return aTextWindow.IsInputActive();
+}
+
+EditView* ScInputWindow::GetEditView()
+{
+ return aTextWindow.GetEditView();
+}
+
+void ScInputWindow::MakeDialogEditView()
+{
+ aTextWindow.MakeDialogEditView();
+}
+
+void ScInputWindow::StopEditEngine( BOOL bAll )
+{
+ aTextWindow.StopEditEngine( bAll );
+}
+
+void ScInputWindow::TextGrabFocus()
+{
+ aTextWindow.GrabFocus();
+}
+
+void ScInputWindow::TextInvalidate()
+{
+ aTextWindow.Invalidate();
+}
+
+void ScInputWindow::SwitchToTextWin()
+{
+ // used for shift-ctrl-F2
+
+ aTextWindow.StartEditEngine();
+ if ( SC_MOD()->IsEditMode() )
+ {
+ aTextWindow.GrabFocus();
+ EditView* pView = aTextWindow.GetEditView();
+ if (pView)
+ {
+ xub_StrLen nLen = pView->GetEditEngine()->GetTextLen(0);
+ ESelection aSel( 0, nLen, 0, nLen );
+ pView->SetSelection( aSel ); // set cursor to end of text
+ }
+ }
+}
+
+void ScInputWindow::PosGrabFocus()
+{
+ aWndPos.GrabFocus();
+}
+
+void ScInputWindow::EnableButtons( BOOL bEnable )
+{
+ // when enabling buttons, always also enable the input window itself
+ if ( bEnable && !IsEnabled() )
+ Enable();
+
+ EnableItem( SID_INPUT_FUNCTION, bEnable );
+ EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable );
+ EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable );
+// Invalidate();
+}
+
+void ScInputWindow::StateChanged( StateChangedType nType )
+{
+ ToolBox::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW ) Resize();
+}
+
+void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ // update item images
+
+ ScModule* pScMod = SC_MOD();
+ SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+ // IMAGE macro uses pScMod, pImgMgr, bHC
+
+ SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) );
+ if ( bIsOkCancelMode )
+ {
+ SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) );
+ SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) );
+ }
+ else
+ {
+ SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) );
+ SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) );
+ }
+ }
+
+ ToolBox::DataChanged( rDCEvt );
+}
+
+//========================================================================
+// Eingabefenster
+//========================================================================
+
+ScTextWnd::ScTextWnd( Window* pParent )
+ : Window ( pParent, WinBits(WB_HIDE | WB_BORDER) ),
+ DragSourceHelper( this ),
+ pEditEngine ( NULL ),
+ pEditView ( NULL ),
+ bIsInsertMode( TRUE ),
+ bFormulaMode ( FALSE ),
+ bInputMode ( FALSE )
+{
+ EnableRTL( FALSE ); // #106269# EditEngine can't be used with VCL EnableRTL
+
+ bIsRTL = GetSettings().GetLayoutRTL();
+
+ // #79096# always use application font, so a font with cjk chars can be installed
+ Font aAppFont = GetFont();
+ aTextFont = aAppFont;
+ aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ Color aBgColor= rStyleSettings.GetWindowColor();
+ Color aTxtColor= rStyleSettings.GetWindowTextColor();
+
+ aTextFont.SetTransparent ( TRUE );
+ aTextFont.SetFillColor ( aBgColor );
+ //aTextFont.SetColor ( COL_FIELDTEXT );
+ aTextFont.SetColor (aTxtColor);
+ aTextFont.SetWeight ( WEIGHT_NORMAL );
+
+ SetSizePixel ( Size(1,TBX_WINDOW_HEIGHT) );
+ SetBackground ( aBgColor );
+ SetLineColor ( COL_BLACK );
+ SetMapMode ( MAP_TWIP );
+ SetPointer ( POINTER_TEXT );
+}
+
+__EXPORT ScTextWnd::~ScTextWnd()
+{
+ delete pEditView;
+ delete pEditEngine;
+ while (!maAccTextDatas.empty()) {
+ maAccTextDatas.back()->Dispose();
+ }
+}
+
+void __EXPORT ScTextWnd::Paint( const Rectangle& rRec )
+{
+ if (pEditView)
+ pEditView->Paint( rRec );
+ else
+ {
+ SetFont( aTextFont );
+
+ long nDiff = GetOutputSizePixel().Height()
+ - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
+// if (nDiff<2) nDiff=2; // mind. 1 Pixel
+
+ long nStartPos = TEXT_STARTPOS;
+ if ( bIsRTL )
+ {
+ // right-align
+ nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS -
+ LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width();
+
+ // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem
+ }
+
+ DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString );
+ }
+}
+
+void __EXPORT ScTextWnd::Resize()
+{
+ if (pEditView)
+ {
+ Size aSize = GetOutputSizePixel();
+ long nDiff = aSize.Height()
+ - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
+
+#ifdef OS2_DOCH_NICHT
+ nDiff-=2; // wird durch 2 geteilt
+ // passt sonst nicht zur normalen Textausgabe
+#endif
+
+ aSize.Width() -= 2 * TEXT_STARTPOS - 1;
+
+ pEditView->SetOutputArea(
+ PixelToLogic( Rectangle( Point( TEXT_STARTPOS, (nDiff > 0) ? nDiff/2 : 1 ),
+ aSize ) ) );
+ }
+}
+
+void __EXPORT ScTextWnd::MouseMove( const MouseEvent& rMEvt )
+{
+ if (pEditView)
+ pEditView->MouseMove( rMEvt );
+}
+
+void __EXPORT ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (!HasFocus())
+ {
+ StartEditEngine();
+ if ( SC_MOD()->IsEditMode() )
+ GrabFocus();
+ }
+
+ if (pEditView)
+ {
+ pEditView->SetEditEngineUpdateMode( TRUE );
+ pEditView->MouseButtonDown( rMEvt );
+ }
+}
+
+void __EXPORT ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if (pEditView)
+ if (pEditView->MouseButtonUp( rMEvt ))
+ {
+ if ( rMEvt.IsMiddle() &&
+ GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
+ {
+ // EditView may have pasted from selection
+ SC_MOD()->InputChanged( pEditView );
+ }
+ else
+ SC_MOD()->InputSelection( pEditView );
+ }
+}
+
+void __EXPORT ScTextWnd::Command( const CommandEvent& rCEvt )
+{
+ bInputMode = TRUE;
+ USHORT nCommand = rCEvt.GetCommand();
+ if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ )
+ {
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell();
+
+ // #109441# don't modify the font defaults here - the right defaults are
+ // already set in StartEditEngine when the EditEngine is created
+
+ // #63263# verhindern, dass die EditView beim View-Umschalten wegkommt
+ pScMod->SetInEditCommand( TRUE );
+ pEditView->Command( rCEvt );
+ pScMod->SetInEditCommand( FALSE );
+
+ // #48929# COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
+ // darum in dem Fall kein InputChanged
+ //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten
+
+ if ( nCommand == COMMAND_STARTDRAG )
+ {
+ // ist auf eine andere View gedraggt worden?
+ ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL )
+ {
+ ScViewData* pViewData = pStartViewSh->GetViewData();
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh );
+ if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) )
+ {
+ pHdl->CancelHandler();
+ pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv
+ }
+ }
+ }
+ else if ( nCommand == COMMAND_CURSORPOS )
+ {
+ // don't call InputChanged for COMMAND_CURSORPOS
+ }
+ else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE )
+ {
+ // #i55929# Font and font size state depends on input language if nothing is selected,
+ // so the slots have to be invalidated when the input language is changed.
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ {
+ SfxBindings& rBindings = pViewFrm->GetBindings();
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ }
+ }
+ else
+ SC_MOD()->InputChanged( pEditView );
+ }
+ else
+ Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern...
+
+ bInputMode = FALSE;
+}
+
+void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
+{
+ if ( pEditView )
+ {
+ CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, TRUE );
+ pEditView->Command( aDragEvent );
+
+ // handling of d&d to different view (CancelHandler) can't be done here,
+ // because the call returns before d&d is complete.
+ }
+}
+
+void __EXPORT ScTextWnd::KeyInput(const KeyEvent& rKEvt)
+{
+ bInputMode = TRUE;
+ if (!SC_MOD()->InputKeyEvent( rKEvt ))
+ {
+ BOOL bUsed = FALSE;
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe
+ if (!bUsed)
+ Window::KeyInput( rKEvt );
+ }
+ bInputMode = FALSE;
+}
+
+void __EXPORT ScTextWnd::GetFocus()
+{
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ pViewSh->SetFormShellAtTop( FALSE ); // focus in input line -> FormShell no longer on top
+}
+
+void __EXPORT ScTextWnd::LoseFocus()
+{
+}
+
+String __EXPORT ScTextWnd::GetText() const
+{
+ // ueberladen, um per Testtool an den Text heranzukommen
+
+ if ( pEditEngine )
+ return pEditEngine->GetText();
+ else
+ return GetTextString();
+}
+
+void ScTextWnd::SetFormulaMode( BOOL bSet )
+{
+ if ( bSet != bFormulaMode )
+ {
+ bFormulaMode = bSet;
+ UpdateAutoCorrFlag();
+ }
+}
+
+void ScTextWnd::UpdateAutoCorrFlag()
+{
+ if ( pEditEngine )
+ {
+ ULONG nControl = pEditEngine->GetControlWord();
+ ULONG nOld = nControl;
+ if ( bFormulaMode )
+ nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln
+ else
+ nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon
+ if ( nControl != nOld )
+ pEditEngine->SetControlWord( nControl );
+ }
+}
+
+void lcl_ExtendEditFontAttribs( SfxItemSet& rSet )
+{
+ const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO );
+ rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK );
+ rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL );
+ const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT );
+ rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK );
+ rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL );
+ const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT );
+ rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
+ rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
+ const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC );
+ rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
+ rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
+ const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE );
+ rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
+ rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
+}
+
+void lcl_ModifyRTLDefaults( SfxItemSet& rSet )
+{
+ rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+
+ // always using rtl writing direction would break formulas
+ //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
+
+ // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
+ // USHORT values in EditLine), so the text may be wrapped and line spacing must be
+ // increased to not see the beginning of the next line.
+ SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
+ aItem.SetPropLineSpace( 200 );
+ rSet.Put( aItem );
+}
+
+void lcl_ModifyRTLVisArea( EditView* pEditView )
+{
+ Rectangle aVisArea = pEditView->GetVisArea();
+ Size aPaper = pEditView->GetEditEngine()->GetPaperSize();
+ long nDiff = aPaper.Width() - aVisArea.Right();
+ aVisArea.Left() += nDiff;
+ aVisArea.Right() += nDiff;
+ pEditView->SetVisArea(aVisArea);
+}
+
+void ScTextWnd::StartEditEngine()
+{
+ // #31147# Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
+ SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ if ( pObjSh && pObjSh->IsInModalMode() )
+ return;
+
+ if ( !pEditView || !pEditEngine )
+ {
+ ScFieldEditEngine* pNew;
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ {
+ const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
+ pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
+ }
+ else
+ pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE );
+ pNew->SetExecuteURL( FALSE );
+ pEditEngine = pNew;
+
+ pEditEngine->SetUpdateMode( FALSE );
+ pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
+ pEditEngine->SetWordDelimiters(
+ ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
+
+ UpdateAutoCorrFlag();
+
+ {
+ SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
+ pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
+ lcl_ExtendEditFontAttribs( *pSet );
+ // turn off script spacing to match DrawText output
+ pSet->Put( SvxScriptSpaceItem( FALSE, EE_PARA_ASIANCJKSPACING ) );
+ if ( bIsRTL )
+ lcl_ModifyRTLDefaults( *pSet );
+ pEditEngine->SetDefaults( pSet );
+ }
+
+ // #57254# Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
+ // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
+
+ BOOL bFilled = FALSE;
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if ( pHdl ) //! Testen, ob's der richtige InputHdl ist?
+ bFilled = pHdl->GetTextAndFields( *pEditEngine );
+
+ pEditEngine->SetUpdateMode( TRUE );
+
+ // aString ist die Wahrheit...
+ if ( bFilled && pEditEngine->GetText() == aString )
+ Invalidate(); // Repaint fuer (hinterlegte) Felder
+ else
+ pEditEngine->SetText(aString); // dann wenigstens den richtigen Text
+
+ pEditView = new EditView( pEditEngine, this );
+ pEditView->SetInsertMode(bIsInsertMode);
+
+ // Text aus Clipboard wird als ASCII einzeilig uebernommen
+ ULONG n = pEditView->GetControlWord();
+ pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );
+
+ pEditEngine->InsertView( pEditView, EE_APPEND );
+
+ Resize();
+
+ if ( bIsRTL )
+ lcl_ModifyRTLVisArea( pEditView );
+
+ pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl));
+
+ if (!maAccTextDatas.empty())
+ maAccTextDatas.back()->StartEdit();
+
+ // as long as EditEngine and DrawText sometimes differ for CTL text,
+ // repaint now to have the EditEngine's version visible
+// SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document
+ BYTE nScript = pDoc->GetStringScriptType( aString );
+ if ( nScript & SCRIPTTYPE_COMPLEX )
+ Invalidate();
+ }
+ }
+
+ SC_MOD()->SetInputMode( SC_INPUT_TOP );
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
+}
+
+IMPL_LINK(ScTextWnd, NotifyHdl, EENotify*, EMPTYARG)
+{
+ if (pEditView && !bInputMode)
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+
+ // #105354# Use the InputHandler's InOwnChange flag to prevent calling InputChanged
+ // while an InputHandler method is modifying the EditEngine content
+
+ if ( pHdl && !pHdl->IsInOwnChange() )
+ pHdl->InputChanged( pEditView, TRUE ); // #i20282# InputChanged must know if called from modify handler
+ }
+
+ return 0;
+}
+
+void ScTextWnd::StopEditEngine( BOOL bAll )
+{
+ if (pEditView)
+ {
+ if (!maAccTextDatas.empty())
+ maAccTextDatas.back()->EndEdit();
+
+ ScModule* pScMod = SC_MOD();
+
+ if (!bAll)
+ pScMod->InputSelection( pEditView );
+ aString = pEditEngine->GetText();
+ bIsInsertMode = pEditView->IsInsertMode();
+ BOOL bSelection = pEditView->HasSelection();
+ pEditEngine->SetModifyHdl(Link());
+ DELETEZ(pEditView);
+ DELETEZ(pEditEngine);
+
+ if ( pScMod->IsEditMode() && !bAll )
+ pScMod->SetInputMode(SC_INPUT_TABLE);
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
+
+ if (bSelection)
+ Invalidate(); // damit Selektion nicht stehenbleibt
+ }
+}
+
+void ScTextWnd::SetTextString( const String& rNewString )
+{
+ if ( rNewString != aString )
+ {
+ bInputMode = TRUE;
+
+ // Position der Aenderung suchen, nur Rest painten
+
+ long nInvPos = 0;
+ long nStartPos = 0;
+ long nTextSize = 0;
+
+ if (!pEditEngine)
+ {
+ BOOL bPaintAll;
+ if ( bIsRTL )
+ bPaintAll = TRUE;
+ else
+ {
+ // test if CTL script type is involved
+ BYTE nOldScript = 0;
+ BYTE nNewScript = 0;
+ SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ // any document can be used (used only for its break iterator)
+ ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
+ nOldScript = pDoc->GetStringScriptType( aString );
+ nNewScript = pDoc->GetStringScriptType( rNewString );
+ }
+ bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX );
+ }
+
+ if ( bPaintAll )
+ {
+ // if CTL is involved, the whole text has to be redrawn
+ Invalidate();
+ }
+ else
+ {
+ xub_StrLen nDifPos;
+ if (rNewString.Len() > aString.Len())
+ nDifPos = rNewString.Match(aString);
+ else
+ nDifPos = aString.Match(rNewString);
+
+ long nSize1 = GetTextWidth(aString);
+ long nSize2 = GetTextWidth(rNewString);
+ if ( nSize1>0 && nSize2>0 )
+ nTextSize = Max( nSize1, nSize2 );
+ else
+ nTextSize = GetOutputSize().Width(); // Ueberlauf
+
+ if (nDifPos == STRING_MATCH)
+ nDifPos = 0;
+
+ // -1 wegen Rundung und "A"
+ Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0));
+ nStartPos = aLogicStart.X();
+ nInvPos = nStartPos;
+ if (nDifPos)
+ nInvPos += GetTextWidth(aString,0,nDifPos);
+
+ USHORT nFlags = 0;
+ if ( nDifPos == aString.Len() ) // only new characters appended
+ nFlags = INVALIDATE_NOERASE; // then background is already clear
+
+ Invalidate( Rectangle( nInvPos, 0,
+ nStartPos+nTextSize, GetOutputSize().Height()-1 ),
+ nFlags );
+ }
+ }
+ else
+ {
+ pEditEngine->SetText(rNewString);
+ }
+
+ aString = rNewString;
+
+ if (!maAccTextDatas.empty())
+ maAccTextDatas.back()->TextChanged();
+
+ bInputMode = FALSE;
+ }
+}
+
+const String& ScTextWnd::GetTextString() const
+{
+ return aString;
+}
+
+BOOL ScTextWnd::IsInputActive()
+{
+ return HasFocus();
+}
+
+EditView* ScTextWnd::GetEditView()
+{
+ return pEditView;
+}
+
+void ScTextWnd::MakeDialogEditView()
+{
+ if ( pEditView ) return;
+
+ ScFieldEditEngine* pNew;
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ {
+ const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
+ pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
+ }
+ else
+ pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE );
+ pNew->SetExecuteURL( FALSE );
+ pEditEngine = pNew;
+
+ pEditEngine->SetUpdateMode( FALSE );
+ pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' );
+ pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
+
+ SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
+ pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
+ lcl_ExtendEditFontAttribs( *pSet );
+ if ( bIsRTL )
+ lcl_ModifyRTLDefaults( *pSet );
+ pEditEngine->SetDefaults( pSet );
+ pEditEngine->SetUpdateMode( TRUE );
+
+ pEditView = new EditView( pEditEngine, this );
+ pEditEngine->InsertView( pEditView, EE_APPEND );
+
+ Resize();
+
+ if ( bIsRTL )
+ lcl_ModifyRTLVisArea( pEditView );
+
+ if (!maAccTextDatas.empty())
+ maAccTextDatas.back()->StartEdit();
+}
+
+void ScTextWnd::ImplInitSettings()
+{
+ bIsRTL = GetSettings().GetLayoutRTL();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ Color aBgColor= rStyleSettings.GetWindowColor();
+ Color aTxtColor= rStyleSettings.GetWindowTextColor();
+
+ aTextFont.SetFillColor ( aBgColor );
+ aTextFont.SetColor (aTxtColor);
+ SetBackground ( aBgColor );
+ Invalidate();
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible()
+{
+ return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this,
+ rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))),
+ rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine);
+}
+
+void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
+{
+ OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == maAccTextDatas.end(),
+ "ScTextWnd::InsertAccessibleTextData - passed object already registered" );
+ maAccTextDatas.push_back( &rTextData );
+}
+
+void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
+{
+ AccTextDataVector::iterator aEnd = maAccTextDatas.end();
+ AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData );
+ OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
+ if( aIt != aEnd )
+ maAccTextDatas.erase( aIt );
+}
+
+// -----------------------------------------------------------------------
+
+void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+ else
+ Window::DataChanged( rDCEvt );
+}
+
+
+//========================================================================
+// Positionsfenster
+//========================================================================
+
+ScPosWnd::ScPosWnd( Window* pParent ) :
+ ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ),
+ pAccel ( NULL ),
+ nTipVisible ( 0 ),
+ bFormulaMode( FALSE )
+{
+ Size aSize( GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:GW99999")) ),
+ GetTextHeight() );
+ aSize.Width() += 25; // ??
+ aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..."
+ SetSizePixel( aSize );
+
+ FillRangeNames();
+
+ StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates
+}
+
+__EXPORT ScPosWnd::~ScPosWnd()
+{
+ EndListening( *SFX_APP() );
+
+ HideTip();
+
+ delete pAccel;
+}
+
+void ScPosWnd::SetFormulaMode( BOOL bSet )
+{
+ if ( bSet != bFormulaMode )
+ {
+ bFormulaMode = bSet;
+
+ if ( bSet )
+ FillFunctions();
+ else
+ FillRangeNames();
+
+ HideTip();
+ }
+}
+
+void ScPosWnd::SetPos( const String& rPosStr )
+{
+ if ( aPosStr != rPosStr )
+ {
+ aPosStr = rPosStr;
+ SetText(aPosStr);
+ }
+}
+
+void ScPosWnd::FillRangeNames()
+{
+ Clear();
+
+ SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
+
+ // per Hand sortieren, weil Funktionen nicht sortiert werden:
+
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ USHORT nCount = pRangeNames->GetCount();
+ if ( nCount > 0 )
+ {
+ USHORT nValidCount = 0;
+ ScRange aDummy;
+ USHORT i;
+ for ( i=0; i<nCount; i++ )
+ {
+ ScRangeData* pData = (*pRangeNames)[i];
+ if (pData->IsValidReference(aDummy))
+ nValidCount++;
+ }
+ if ( nValidCount )
+ {
+ ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
+ USHORT j;
+ for ( i=0, j=0; i<nCount; i++ )
+ {
+ ScRangeData* pData = (*pRangeNames)[i];
+ if (pData->IsValidReference(aDummy))
+ ppSortArray[j++] = pData;
+ }
+#ifndef ICC
+ qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
+ &ScRangeData_QsortNameCompare );
+#else
+ qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
+ ICCQsortNameCompare );
+#endif
+ for ( j=0; j<nValidCount; j++ )
+ InsertEntry( ppSortArray[j]->GetName() );
+ delete [] ppSortArray;
+ }
+ }
+ }
+ SetText(aPosStr);
+}
+
+void ScPosWnd::FillFunctions()
+{
+ Clear();
+
+ String aFirstName;
+ const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
+ USHORT nMRUCount = rOpt.GetLRUFuncListCount();
+ const USHORT* pMRUList = rOpt.GetLRUFuncList();
+ if (pMRUList)
+ {
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ ULONG nListCount = pFuncList->GetCount();
+ for (USHORT i=0; i<nMRUCount; i++)
+ {
+ USHORT nId = pMRUList[i];
+ for (ULONG j=0; j<nListCount; j++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
+ if ( pDesc->nFIndex == nId && pDesc->pFuncName )
+ {
+ InsertEntry( *pDesc->pFuncName );
+ if (!aFirstName.Len())
+ aFirstName = *pDesc->pFuncName;
+ break; // nicht weitersuchen
+ }
+ }
+ }
+ }
+
+ //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
+ //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!
+
+// InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
+
+ SetText(aFirstName);
+}
+
+void __EXPORT ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( !bFormulaMode )
+ {
+ // muss die Liste der Bereichsnamen updgedated werden?
+
+ if ( rHint.ISA(SfxSimpleHint) )
+ {
+ ULONG nHintId = ((SfxSimpleHint&)rHint).GetId();
+ if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL)
+ FillRangeNames();
+ }
+ else if ( rHint.ISA(SfxEventHint) )
+ {
+ ULONG nEventId = ((SfxEventHint&)rHint).GetEventId();
+ if ( nEventId == SFX_EVENT_ACTIVATEDOC )
+ FillRangeNames();
+ }
+ }
+}
+
+void ScPosWnd::HideTip()
+{
+ if ( nTipVisible )
+ {
+ Help::HideTip( nTipVisible );
+ nTipVisible = 0;
+ }
+}
+
+ScNameInputType lcl_GetInputType( const String& rText )
+{
+ ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error
+
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ // test in same order as in SID_CURRENTCELL execute
+
+ ScRange aRange;
+ ScAddress aAddress;
+ ScRangeUtil aRangeUtil;
+ SCTAB nNameTab;
+ sal_Int32 nNumeric;
+
+ if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID )
+ eRet = SC_NAME_INPUT_NAMEDRANGE;
+ else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID )
+ eRet = SC_NAME_INPUT_CELL;
+ else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) )
+ eRet = SC_NAME_INPUT_NAMEDRANGE;
+ else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) )
+ eRet = SC_NAME_INPUT_DATABASE;
+ else if ( ByteString( rText, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() &&
+ ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
+ eRet = SC_NAME_INPUT_ROW;
+ else if ( pDoc->GetTable( rText, nNameTab ) )
+ eRet = SC_NAME_INPUT_SHEET;
+ else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range?
+ {
+ if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ eRet = SC_NAME_INPUT_DEFINE;
+ else
+ eRet = SC_NAME_INPUT_BAD_SELECTION;
+ }
+ else
+ eRet = SC_NAME_INPUT_BAD_NAME;
+ }
+
+ return eRet;
+}
+
+void ScPosWnd::Modify()
+{
+ ComboBox::Modify();
+
+ HideTip();
+
+ if ( !IsTravelSelect() && !bFormulaMode )
+ {
+ // determine the action that would be taken for the current input
+
+ ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view
+ USHORT nStrId = 0;
+ switch ( eType )
+ {
+ case SC_NAME_INPUT_CELL:
+ nStrId = STR_NAME_INPUT_CELL;
+ break;
+ case SC_NAME_INPUT_RANGE:
+ case SC_NAME_INPUT_NAMEDRANGE:
+ nStrId = STR_NAME_INPUT_RANGE; // named range or range reference
+ break;
+ case SC_NAME_INPUT_DATABASE:
+ nStrId = STR_NAME_INPUT_DBRANGE;
+ break;
+ case SC_NAME_INPUT_ROW:
+ nStrId = STR_NAME_INPUT_ROW;
+ break;
+ case SC_NAME_INPUT_SHEET:
+ nStrId = STR_NAME_INPUT_SHEET;
+ break;
+ case SC_NAME_INPUT_DEFINE:
+ nStrId = STR_NAME_INPUT_DEFINE;
+ break;
+ default:
+ // other cases (error): no tip help
+ break;
+ }
+
+ if ( nStrId )
+ {
+ // show the help tip at the text cursor position
+
+ Window* pWin = GetSubEdit();
+ if (!pWin)
+ pWin = this;
+ Point aPos;
+ Cursor* pCur = pWin->GetCursor();
+ if (pCur)
+ aPos = pWin->LogicToPixel( pCur->GetPos() );
+ aPos = pWin->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, aPos );
+
+ String aText = ScGlobal::GetRscString( nStrId );
+ USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
+ nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign);
+ }
+ }
+}
+
+void __EXPORT ScPosWnd::Select()
+{
+ ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag
+
+ HideTip();
+
+ if (!IsTravelSelect())
+ DoEnter();
+}
+
+void ScPosWnd::DoEnter()
+{
+ String aText = GetText();
+ if ( aText.Len() )
+ {
+ if ( bFormulaMode )
+ {
+ ScModule* pScMod = SC_MOD();
+ if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) )
+ {
+ // Funktions-Autopilot
+ //! mit dem bisher eingegebenen Text weiterarbeiten !!!
+
+ //! new method at ScModule to query if function autopilot is open
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
+ pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+ }
+ else
+ {
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
+ if (pHdl)
+ pHdl->InsertFunction( aText );
+ }
+ }
+ else
+ {
+ // depending on the input, select something or create a new named range
+
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ {
+ ScNameInputType eType = lcl_GetInputType( aText );
+ if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION )
+ {
+ USHORT nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION;
+ pViewSh->ErrorMessage( nId );
+ }
+ else if ( eType == SC_NAME_INPUT_DEFINE )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangeName* pNames = pDoc->GetRangeName();
+ ScRange aSelection;
+ USHORT nIndex = 0;
+ if ( pNames && !pNames->SearchName( aText, nIndex ) &&
+ (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) )
+ {
+ ScRangeName aNewRanges( *pNames );
+ ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
+ String aContent;
+ aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
+ if ( aNewRanges.Insert(pNew) )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.ModifyRangeNames( aNewRanges, FALSE );
+ pViewSh->UpdateInputHandler(TRUE);
+ }
+ else
+ delete pNew; // shouldn't happen
+ }
+ }
+ else
+ {
+ // for all selection types, excecute the SID_CURRENTCELL slot
+
+ SfxStringItem aPosItem( SID_CURRENTCELL, aText );
+ SfxBoolItem aUnmarkItem( FN_PARAM_1, TRUE ); // remove existing selection
+
+ pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
+ &aPosItem, &aUnmarkItem, 0L );
+ }
+ }
+ }
+ }
+ else
+ SetText( aPosStr );
+
+ ReleaseFocus_Impl();
+}
+
+long __EXPORT ScPosWnd::Notify( NotifyEvent& rNEvt )
+{
+ long nHandled = 0;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+
+ switch ( pKEvt->GetKeyCode().GetCode() )
+ {
+ case KEY_RETURN:
+ DoEnter();
+ nHandled = 1;
+ break;
+
+ case KEY_ESCAPE:
+ if (nTipVisible)
+ {
+ // escape when the tip help is shown: only hide the tip
+ HideTip();
+ }
+ else
+ {
+ if (!bFormulaMode)
+ SetText( aPosStr );
+ ReleaseFocus_Impl();
+ }
+ nHandled = 1;
+ break;
+ }
+ }
+
+ if ( !nHandled )
+ nHandled = ComboBox::Notify( rNEvt );
+
+ if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ HideTip();
+
+ return nHandled;
+}
+
+void ScPosWnd::ReleaseFocus_Impl()
+{
+ HideTip();
+
+ SfxViewShell* pCurSh = SfxViewShell::Current();
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) );
+ if ( pHdl && pHdl->IsTopMode() )
+ {
+ // Focus wieder in die Eingabezeile?
+
+ ScInputWindow* pInputWin = pHdl->GetInputWindow();
+ if (pInputWin)
+ {
+ pInputWin->TextGrabFocus();
+ return;
+ }
+ }
+
+ // Focus auf die aktive View
+
+ if ( pCurSh )
+ {
+ Window* pShellWnd = pCurSh->GetWindow();
+
+ if ( pShellWnd )
+ pShellWnd->GrabFocus();
+ }
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/app/lnktrans.cxx b/sc/source/ui/app/lnktrans.cxx
new file mode 100644
index 000000000000..2e0f5d276a97
--- /dev/null
+++ b/sc/source/ui/app/lnktrans.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+
+
+#include <svl/urlbmk.hxx>
+
+#include "lnktrans.hxx"
+#include "scmod.hxx"
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+ScLinkTransferObj::ScLinkTransferObj()
+{
+}
+
+ScLinkTransferObj::~ScLinkTransferObj()
+{
+}
+
+void ScLinkTransferObj::SetLinkURL( const String& rURL, const String& rText )
+{
+ aLinkURL = rURL;
+ aLinkText = rText;
+}
+
+void ScLinkTransferObj::AddSupportedFormats()
+{
+ if ( aLinkURL.Len() )
+ {
+ // TransferableHelper::SetINetBookmark formats
+
+ AddFormat( SOT_FORMATSTR_ID_SOLK );
+ AddFormat( SOT_FORMAT_STRING );
+ AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
+ AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
+ AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_FILECONTENT );
+ }
+}
+
+sal_Bool ScLinkTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ sal_Bool bOK = sal_False;
+ if ( aLinkURL.Len() )
+ {
+ INetBookmark aBmk( aLinkURL, aLinkText );
+ bOK = SetINetBookmark( aBmk, rFlavor );
+ }
+ return bOK;
+}
+
+void ScLinkTransferObj::ObjectReleased()
+{
+ TransferableHelper::ObjectReleased();
+}
+
+void ScLinkTransferObj::DragFinished( sal_Int8 nDropAction )
+{
+ ScModule* pScMod = SC_MOD();
+ pScMod->ResetDragObject();
+
+ TransferableHelper::DragFinished( nDropAction );
+}
+
+
diff --git a/sc/source/ui/app/makefile.mk b/sc/source/ui/app/makefile.mk
new file mode 100644
index 000000000000..a7ff3fe86d7d
--- /dev/null
+++ b/sc/source/ui/app/makefile.mk
@@ -0,0 +1,75 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=app
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/scmod.obj \
+ $(SLO)$/scmod2.obj \
+ $(SLO)$/scdll.obj \
+ $(SLO)$/typemap.obj \
+ $(SLO)$/transobj.obj \
+ $(SLO)$/drwtrans.obj \
+ $(SLO)$/lnktrans.obj \
+ $(SLO)$/seltrans.obj \
+ $(SLO)$/inputhdl.obj \
+ $(SLO)$/inputwin.obj \
+ $(SLO)$/rfindlst.obj \
+ $(SLO)$/uiitems.obj \
+ $(SLO)$/msgpool.obj \
+ $(SLO)$/client.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/drwtrans.obj \
+ $(SLO)$/scdll.obj \
+ $(SLO)$/scmod2.obj \
+ $(SLO)$/scmod.obj \
+ $(SLO)$/typemap.obj \
+ $(SLO)$/client.obj \
+ $(SLO)$/inputwin.obj
+
+#LIB3TARGET=$(SLB)$/ysclib.lib
+#LIB3OBJFILES=$(SLO)$/sclib.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SRS)$/app.srs: $(SOLARINCDIR)$/svx$/globlmn.hrc
+
diff --git a/sc/source/ui/app/msgpool.cxx b/sc/source/ui/app/msgpool.cxx
new file mode 100644
index 000000000000..78cb70fa64f0
--- /dev/null
+++ b/sc/source/ui/app/msgpool.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <svx/dialogs.hrc>
+
+#include "sc.hrc"
+#include "docpool.hxx"
+#include "msgpool.hxx"
+
+//------------------------------------------------------------------------
+
+static SfxItemInfo __READONLY_DATA aMsgItemInfos[] =
+{
+ { 0, SFX_ITEM_POOLABLE }, // SCITEM_STRING
+ { 0, SFX_ITEM_POOLABLE }, // SCITEM_SEARCHDATA - nicht mehr benutzt !!!
+ { SID_SORT, SFX_ITEM_POOLABLE }, // SCITEM_SORTDATA
+ { SID_QUERY, SFX_ITEM_POOLABLE }, // SCITEM_QUERYDATA
+ { SID_SUBTOTALS, SFX_ITEM_POOLABLE }, // SCITEM_SUBTDATA
+ { SID_CONSOLIDATE, SFX_ITEM_POOLABLE }, // SCITEM_CONSOLIDATEDATA
+ { SID_PIVOT_TABLE, SFX_ITEM_POOLABLE }, // SCITEM_PIVOTDATA
+ { SID_SOLVE, SFX_ITEM_POOLABLE }, // SCITEM_SOLVEDATA
+ { SID_SCUSERLISTS, SFX_ITEM_POOLABLE }, // SCITEM_USERLIST
+ { SID_PRINTER_NOTFOUND_WARN, SFX_ITEM_POOLABLE } // SCITEM_PRINTWARN
+};
+
+//------------------------------------------------------------------------
+
+ScMessagePool::ScMessagePool()
+ : SfxItemPool ( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScMessagePool")),
+ MSGPOOL_START, MSGPOOL_END,
+ aMsgItemInfos, NULL ),
+ //
+ aGlobalStringItem ( SfxStringItem ( SCITEM_STRING, String() ) ),
+ aGlobalSearchItem ( SvxSearchItem ( SCITEM_SEARCHDATA ) ),
+ aGlobalSortItem ( ScSortItem ( SCITEM_SORTDATA, NULL ) ),
+ aGlobalQueryItem ( ScQueryItem ( SCITEM_QUERYDATA, NULL, NULL ) ),
+ aGlobalSubTotalItem ( ScSubTotalItem ( SCITEM_SUBTDATA, NULL, NULL ) ),
+ aGlobalConsolidateItem ( ScConsolidateItem ( SCITEM_CONSOLIDATEDATA, NULL ) ),
+ aGlobalPivotItem ( ScPivotItem ( SCITEM_PIVOTDATA, NULL, NULL, FALSE ) ),
+ aGlobalSolveItem ( ScSolveItem ( SCITEM_SOLVEDATA, NULL ) ),
+ aGlobalUserListItem ( ScUserListItem ( SCITEM_USERLIST ) ),
+ //
+ aPrintWarnItem ( SfxBoolItem ( SCITEM_PRINTWARN, FALSE ) )
+{
+ ppPoolDefaults = new SfxPoolItem*[MSGPOOL_END - MSGPOOL_START + 1];
+
+ ppPoolDefaults[SCITEM_STRING - MSGPOOL_START] = &aGlobalStringItem;
+ ppPoolDefaults[SCITEM_SEARCHDATA - MSGPOOL_START] = &aGlobalSearchItem;
+ ppPoolDefaults[SCITEM_SORTDATA - MSGPOOL_START] = &aGlobalSortItem;
+ ppPoolDefaults[SCITEM_QUERYDATA - MSGPOOL_START] = &aGlobalQueryItem;
+ ppPoolDefaults[SCITEM_SUBTDATA - MSGPOOL_START] = &aGlobalSubTotalItem;
+ ppPoolDefaults[SCITEM_CONSOLIDATEDATA - MSGPOOL_START] = &aGlobalConsolidateItem;
+ ppPoolDefaults[SCITEM_PIVOTDATA - MSGPOOL_START] = &aGlobalPivotItem;
+ ppPoolDefaults[SCITEM_SOLVEDATA - MSGPOOL_START] = &aGlobalSolveItem;
+ ppPoolDefaults[SCITEM_USERLIST - MSGPOOL_START] = &aGlobalUserListItem;
+ ppPoolDefaults[SCITEM_PRINTWARN - MSGPOOL_START] = &aPrintWarnItem;
+
+ SetDefaults( ppPoolDefaults );
+
+ pDocPool = new ScDocumentPool;
+
+ SetSecondaryPool( pDocPool );
+}
+
+
+__EXPORT ScMessagePool::~ScMessagePool()
+{
+ Delete();
+ SetSecondaryPool( NULL ); // before deleting defaults (accesses defaults)
+
+ for ( USHORT i=0; i <= MSGPOOL_END-MSGPOOL_START; i++ )
+ SetRefCount( *ppPoolDefaults[i], 0 );
+
+ delete[] ppPoolDefaults;
+
+ SfxItemPool::Free(pDocPool);
+}
+
+
+SfxMapUnit __EXPORT ScMessagePool::GetMetric( USHORT nWhich ) const
+{
+ // eigene Attribute: Twips, alles andere 1/100 mm
+
+ if ( nWhich >= ATTR_STARTINDEX && nWhich <= ATTR_ENDINDEX )
+ return SFX_MAPUNIT_TWIP;
+ else
+ return SFX_MAPUNIT_100TH_MM;
+}
+
+
+
+
+
diff --git a/sc/source/ui/app/rfindlst.cxx b/sc/source/ui/app/rfindlst.cxx
new file mode 100644
index 000000000000..3d62c0396b51
--- /dev/null
+++ b/sc/source/ui/app/rfindlst.cxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "rfindlst.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+#define SC_RANGECOLORS 8
+
+static ColorData aColNames[SC_RANGECOLORS] =
+ { COL_LIGHTBLUE, COL_LIGHTRED, COL_LIGHTMAGENTA, COL_GREEN,
+ COL_BLUE, COL_RED, COL_MAGENTA, COL_BROWN };
+
+//==================================================================
+
+ScRangeFindList::ScRangeFindList(const String& rName) :
+ aDocName( rName ),
+ bHidden( FALSE )
+{
+}
+
+ScRangeFindList::~ScRangeFindList()
+{
+ void* pEntry = aEntries.First();
+ while ( pEntry )
+ {
+ delete (ScRangeFindData*) aEntries.Remove( pEntry );
+ pEntry = aEntries.Next();
+ }
+}
+
+ColorData ScRangeFindList::GetColorName( USHORT nIndex ) // static
+{
+ return aColNames[nIndex % SC_RANGECOLORS];
+}
+
+//==================================================================
+
diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx
new file mode 100644
index 000000000000..a1b8f05d2918
--- /dev/null
+++ b/sc/source/ui/app/scdll.cxx
@@ -0,0 +1,419 @@
+/************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/eeitem.hxx>
+
+
+#ifndef _FM_FMOBJFAC_HXX
+#include <svx/fmobjfac.hxx>
+#endif
+#include <svx/objfac3d.hxx>
+#include <svx/tbxcolor.hxx>
+
+#include <sot/clsids.hxx>
+#include <sfx2/taskpane.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/app.hxx>
+#include <avmedia/mediaplayer.hxx>
+#include <avmedia/mediatoolbox.hxx>
+#include <comphelper/types.hxx>
+#include <svx/extrusioncolorcontrol.hxx>
+#include <svx/fontworkgallery.hxx>
+#include <svx/tbxcustomshapes.hxx>
+
+#include <svtools/parhtml.hxx>
+#include <sot/formats.hxx>
+#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC
+
+#include "scitems.hxx" // fuer tbxctrls etc.
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "cfgids.hxx"
+
+//! die Registrierung wird wegen CLOOKs in ein eigenes File wandern muessen...
+
+// Interface-Registrierung
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "prevwsh.hxx"
+#include "drawsh.hxx"
+#include "drformsh.hxx"
+#include "drtxtob.hxx"
+#include "editsh.hxx"
+#include "pivotsh.hxx"
+#include "auditsh.hxx"
+#include "cellsh.hxx"
+#include "oleobjsh.hxx"
+#include "chartsh.hxx"
+#include "graphsh.hxx"
+#include "mediash.hxx"
+#include "pgbrksh.hxx"
+
+#include "docpool.hxx"
+#include "appoptio.hxx"
+
+// Controls
+
+#include <svx/tbxalign.hxx>
+#include <svx/tbxctl.hxx>
+#include <svx/fillctrl.hxx>
+#include <svx/linectrl.hxx>
+#include <svx/tbcontrl.hxx>
+#include <svx/selctrl.hxx>
+#include <svx/insctrl.hxx>
+#include <svx/zoomctrl.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/modctrl.hxx>
+#include <svx/pszctrl.hxx>
+#include <svx/fntctl.hxx>
+#include <svx/fntszctl.hxx>
+#include <svx/grafctrl.hxx>
+#include <svx/galbrws.hxx>
+#include <svx/clipboardctl.hxx>
+#include <svx/lboxctrl.hxx>
+#include <svx/verttexttbxctrl.hxx>
+#include <svx/formatpaintbrushctrl.hxx>
+#include "tbinsert.hxx"
+#include "tbzoomsliderctrl.hxx"
+#include <svx/zoomsliderctrl.hxx>
+
+#include <svx/xmlsecctrl.hxx>
+// Child-Windows
+#include "reffact.hxx"
+#include "navipi.hxx"
+#include "inputwin.hxx"
+#include "spelldialog.hxx"
+#include <svx/fontwork.hxx>
+#include <svx/srchdlg.hxx>
+#include <svx/hyprlink.hxx>
+#include <svx/hyperdlg.hxx>
+#include <svx/imapdlg.hxx>
+
+#include "editutil.hxx"
+#include <svx/svdfield.hxx> // SdrRegisterFieldClasses
+#include <rtl/logfile.hxx>
+
+#include "dwfunctr.hxx"
+#include "acredlin.hxx"
+
+//------------------------------------------------------------------
+
+//UNUSED2008-05 // filter detection can't use ScFilterOptions (in sc-dll),
+//UNUSED2008-05 // so access to wk3 flag must be implemented here again
+//UNUSED2008-05
+//UNUSED2008-05 class ScLibOptions : public utl::ConfigItem
+//UNUSED2008-05 {
+//UNUSED2008-05 BOOL bWK3Flag;
+//UNUSED2008-05
+//UNUSED2008-05 public:
+//UNUSED2008-05 ScLibOptions();
+//UNUSED2008-05 BOOL GetWK3Flag() const { return bWK3Flag; }
+//UNUSED2008-05 };
+//UNUSED2008-05
+//UNUSED2008-05 #define CFGPATH_LIBFILTER "Office.Calc/Filter/Import/Lotus123"
+//UNUSED2008-05 #define ENTRYSTR_WK3 "WK3"
+//UNUSED2008-05
+//UNUSED2008-05 ScLibOptions::ScLibOptions() :
+//UNUSED2008-05 ConfigItem( rtl::OUString::createFromAscii( CFGPATH_LIBFILTER ) ),
+//UNUSED2008-05 bWK3Flag( FALSE )
+//UNUSED2008-05 {
+//UNUSED2008-05 com::sun::star::uno::Sequence<rtl::OUString> aNames(1);
+//UNUSED2008-05 aNames[0] = rtl::OUString::createFromAscii( ENTRYSTR_WK3 );
+//UNUSED2008-05 com::sun::star::uno::Sequence<com::sun::star::uno::Any> aValues = GetProperties(aNames);
+//UNUSED2008-05 if ( aValues.getLength() == 1 && aValues[0].hasValue() )
+//UNUSED2008-05 bWK3Flag = comphelper::getBOOL( aValues[0] );
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------
+
+ScResId::ScResId( USHORT nId ) :
+ ResId( nId, *SC_MOD()->GetResMgr() )
+{
+}
+
+//------------------------------------------------------------------
+
+void ScDLL::Init()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDLL::Init" );
+
+ ScModule **ppShlPtr = (ScModule**) GetAppData(SHL_CALC);
+ if ( *ppShlPtr )
+ return;
+
+ ScDocumentPool::InitVersionMaps(); // wird im ScModule ctor gebraucht
+
+ ScModule* pMod = new ScModule( &ScDocShell::Factory() );
+ (*ppShlPtr) = pMod;
+
+//REMOVE ScDocShell::RegisterFactory( SDT_SC_DOCFACTPRIO );
+
+ ScDocShell::Factory().SetDocumentServiceName( rtl::OUString::createFromAscii( "com.sun.star.sheet.SpreadsheetDocument" ) );
+
+ ScGlobal::Init(); // erst wenn der ResManager initialisiert ist
+ // erst nach ScGlobal::Init duerfen die App-Optionen
+ // initialisiert werden
+
+ // register your view-factories here
+
+ ScTabViewShell ::RegisterFactory(1);
+ ScPreviewShell ::RegisterFactory(2);
+
+ // register your shell-interfaces here
+
+ ScModule ::RegisterInterface(pMod);
+ ScDocShell ::RegisterInterface(pMod);
+ ScTabViewShell ::RegisterInterface(pMod);
+ ScPreviewShell ::RegisterInterface(pMod);
+ ScDrawShell ::RegisterInterface(pMod);
+ ScDrawFormShell ::RegisterInterface(pMod);
+ ScDrawTextObjectBar ::RegisterInterface(pMod);
+ ScEditShell ::RegisterInterface(pMod);
+ ScPivotShell ::RegisterInterface(pMod);
+ ScAuditingShell ::RegisterInterface(pMod);
+ ScFormatShell ::RegisterInterface(pMod);
+ ScCellShell ::RegisterInterface(pMod);
+ ScOleObjectShell ::RegisterInterface(pMod);
+ ScChartShell ::RegisterInterface(pMod);
+ ScGraphicShell ::RegisterInterface(pMod);
+ ScMediaShell ::RegisterInterface(pMod);
+ ScPageBreakShell ::RegisterInterface(pMod);
+
+ // eigene Controller
+ ScTbxInsertCtrl ::RegisterControl(SID_TBXCTL_INSERT, pMod);
+ ScTbxInsertCtrl ::RegisterControl(SID_TBXCTL_INSCELLS, pMod);
+ ScTbxInsertCtrl ::RegisterControl(SID_TBXCTL_INSOBJ, pMod);
+ ScZoomSliderControl ::RegisterControl(SID_PREVIEW_SCALINGFACTOR, pMod);
+
+ // Svx-Toolbox-Controller
+ SvxTbxCtlDraw ::RegisterControl(SID_INSERT_DRAW, pMod);
+ SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_BASIC, pMod);
+ SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_SYMBOL, pMod);
+ SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_ARROW, pMod);
+ SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_FLOWCHART, pMod);
+ SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_CALLOUT, pMod);
+ SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_STAR, pMod);
+ SvxTbxCtlAlign ::RegisterControl(SID_OBJECT_ALIGN, pMod);
+ SvxFillToolBoxControl ::RegisterControl(0, pMod);
+ SvxLineStyleToolBoxControl ::RegisterControl(0, pMod);
+ SvxLineWidthToolBoxControl ::RegisterControl(0, pMod);
+ SvxLineColorToolBoxControl ::RegisterControl(0, pMod);
+ SvxLineEndToolBoxControl ::RegisterControl(SID_ATTR_LINEEND_STYLE, pMod);
+ SvxStyleToolBoxControl ::RegisterControl(SID_STYLE_APPLY, pMod);
+ SvxFontNameToolBoxControl ::RegisterControl(SID_ATTR_CHAR_FONT, pMod);
+// SvxFontHeightToolBoxControl ::RegisterControl(SID_ATTR_CHAR_FONTHEIGHT, pMod);
+ SvxFontColorToolBoxControl ::RegisterControl(SID_ATTR_CHAR_COLOR, pMod);
+ SvxColorToolBoxControl ::RegisterControl(SID_BACKGROUND_COLOR, pMod);
+ SvxFrameToolBoxControl ::RegisterControl(SID_ATTR_BORDER, pMod);
+ SvxFrameLineStyleToolBoxControl ::RegisterControl(SID_FRAME_LINESTYLE, pMod);
+ SvxFrameLineColorToolBoxControl ::RegisterControl(SID_FRAME_LINECOLOR, pMod);
+ SvxClipBoardControl ::RegisterControl(SID_PASTE, pMod );
+ SvxUndoRedoControl ::RegisterControl(SID_UNDO, pMod );
+ SvxUndoRedoControl ::RegisterControl(SID_REDO, pMod );
+ svx::FormatPaintBrushToolBoxControl::RegisterControl(SID_FORMATPAINTBRUSH, pMod );
+
+ SvxGrafModeToolBoxControl ::RegisterControl(SID_ATTR_GRAF_MODE, pMod);
+ SvxGrafRedToolBoxControl ::RegisterControl(SID_ATTR_GRAF_RED, pMod);
+ SvxGrafGreenToolBoxControl ::RegisterControl(SID_ATTR_GRAF_GREEN, pMod);
+ SvxGrafBlueToolBoxControl ::RegisterControl(SID_ATTR_GRAF_BLUE, pMod);
+ SvxGrafLuminanceToolBoxControl ::RegisterControl(SID_ATTR_GRAF_LUMINANCE, pMod);
+ SvxGrafContrastToolBoxControl ::RegisterControl(SID_ATTR_GRAF_CONTRAST, pMod);
+ SvxGrafGammaToolBoxControl ::RegisterControl(SID_ATTR_GRAF_GAMMA, pMod);
+ SvxGrafTransparenceToolBoxControl::RegisterControl(SID_ATTR_GRAF_TRANSPARENCE, pMod);
+ SvxGrafFilterToolBoxControl ::RegisterControl(SID_GRFFILTER, pMod);
+
+ SvxVertTextTbxCtrl::RegisterControl(SID_DRAW_CAPTION_VERTICAL, pMod);
+ SvxVertTextTbxCtrl::RegisterControl(SID_DRAW_TEXT_VERTICAL, pMod);
+ SvxVertTextTbxCtrl::RegisterControl(SID_TEXTDIRECTION_LEFT_TO_RIGHT, pMod);
+ SvxVertTextTbxCtrl::RegisterControl(SID_TEXTDIRECTION_TOP_TO_BOTTOM, pMod);
+ SvxCTLTextTbxCtrl::RegisterControl(SID_ATTR_PARA_LEFT_TO_RIGHT, pMod);
+ SvxCTLTextTbxCtrl::RegisterControl(SID_ATTR_PARA_RIGHT_TO_LEFT, pMod);
+
+ //Media Controller
+ ::avmedia::MediaToolBoxControl::RegisterControl( SID_AVMEDIA_TOOLBOX, pMod );
+
+ // common SFX controller
+ ::sfx2::TaskPaneWrapper::RegisterChildWindow( FALSE, pMod );
+
+ // Svx-StatusBar-Controller
+ SvxInsertStatusBarControl ::RegisterControl(SID_ATTR_INSERT, pMod);
+ SvxSelectionModeControl ::RegisterControl(SID_STATUS_SELMODE, pMod);
+ SvxZoomStatusBarControl ::RegisterControl(SID_ATTR_ZOOM, pMod);
+ SvxZoomSliderControl ::RegisterControl(SID_ATTR_ZOOMSLIDER, pMod);
+ SvxModifyControl ::RegisterControl(SID_DOC_MODIFIED, pMod);
+ XmlSecStatusBarControl ::RegisterControl( SID_SIGNATURE, pMod );
+
+ SvxPosSizeStatusBarControl ::RegisterControl(SID_ATTR_SIZE, pMod);
+
+ // Svx-Menue-Controller
+ SvxFontMenuControl ::RegisterControl(SID_ATTR_CHAR_FONT, pMod);
+ SvxFontSizeMenuControl ::RegisterControl(SID_ATTR_CHAR_FONTHEIGHT, pMod);
+
+ // CustomShape extrusion controller
+ svx::ExtrusionColorControl::RegisterControl( SID_EXTRUSION_3D_COLOR, pMod );
+ svx::FontWorkShapeTypeControl::RegisterControl( SID_FONTWORK_SHAPE_TYPE, pMod );
+
+ // Child-Windows
+
+ // Hack: Eingabezeile mit 42 registrieren, damit sie im PlugIn immer sichtbar ist
+ ScInputWindowWrapper ::RegisterChildWindow(42, pMod, SFX_CHILDWIN_TASK|SFX_CHILDWIN_FORCEDOCK);
+ ScNavigatorDialogWrapper ::RegisterChildWindowContext(
+ sal::static_int_cast<sal_uInt16>(ScTabViewShell::GetInterfaceId()), pMod);
+ ScSolverDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScOptSolverDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScNameDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScPivotLayoutWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScTabOpDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScFilterDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScSpecialFilterDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScDbNameDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScConsolidateDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScPrintAreasDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScCondFormatDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScColRowNameRangesDlgWrapper::RegisterChildWindow(FALSE, pMod);
+ ScFormulaDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+
+ // First docking Window for Calc
+ ScFunctionChildWindow ::RegisterChildWindow(FALSE, pMod);
+
+ // Redlining- Window
+ ScAcceptChgDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ ScSimpleRefDlgWrapper ::RegisterChildWindow(FALSE, pMod, SFX_CHILDWIN_ALWAYSAVAILABLE|SFX_CHILDWIN_NEVERHIDE );
+ ScHighlightChgDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+
+ SvxSearchDialogWrapper ::RegisterChildWindow(FALSE, pMod);
+ SvxHlinkDlgWrapper ::RegisterChildWindow(FALSE, pMod);
+ SvxFontWorkChildWindow ::RegisterChildWindow(FALSE, pMod);
+ SvxHyperlinkDlgWrapper ::RegisterChildWindow(FALSE, pMod, SFX_CHILDWIN_FORCEDOCK);
+ SvxIMapDlgChildWindow ::RegisterChildWindow(FALSE, pMod);
+ GalleryChildWindow ::RegisterChildWindow(FALSE, pMod);
+ ScSpellDialogChildWindow ::RegisterChildWindow(FALSE, pMod);
+ ::avmedia::MediaPlayer ::RegisterChildWindow(FALSE, pMod);
+
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ ScValidityRefChildWin::RegisterChildWindow(FALSE, pMod);
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+
+ // Edit-Engine-Felder, soweit nicht schon in OfficeApplication::Init
+
+ SvClassManager& rClassManager = SvxFieldItem::GetClassManager();
+// rClassManager.SV_CLASS_REGISTER( SvxURLField );
+// rClassManager.SV_CLASS_REGISTER( SvxDateField );
+// rClassManager.SV_CLASS_REGISTER( SvxPageField );
+ rClassManager.SV_CLASS_REGISTER( SvxPagesField );
+// rClassManager.SV_CLASS_REGISTER( SvxTimeField );
+ rClassManager.SV_CLASS_REGISTER( SvxFileField );
+// rClassManager.SV_CLASS_REGISTER( SvxExtFileField );
+ rClassManager.SV_CLASS_REGISTER( SvxTableField );
+
+ SdrRegisterFieldClasses(); // SvDraw-Felder registrieren
+
+ // 3D-Objekt-Factory eintragen
+ E3dObjFactory();
+
+ // ::com::sun::star::form::component::Form-Objekt-Factory eintragen
+ FmFormObjFactory();
+
+ pMod->PutItem( SfxUInt16Item( SID_ATTR_METRIC, sal::static_int_cast<UINT16>(pMod->GetAppOptions().GetAppMetric()) ) );
+
+ // StarOne Services are now handled in the registry
+}
+
+void ScDLL::Exit()
+{
+ // the SxxModule must be destroyed
+ ScModule **ppShlPtr = (ScModule**) GetAppData(SHL_CALC);
+ delete (*ppShlPtr);
+ (*ppShlPtr) = NULL;
+
+ // ScGlobal::Clear ist schon im Module-dtor
+}
+
+//------------------------------------------------------------------
+// Statusbar
+//------------------------------------------------------------------
+
+#define TEXT_WIDTH(s) rStatusBar.GetTextWidth((s))
+
+//UNUSED2008-05 void ScDLL::FillStatusBar(StatusBar &rStatusBar)
+//UNUSED2008-05 {
+//UNUSED2008-05 // Dokumentposition (Tabelle x / y)
+//UNUSED2008-05 rStatusBar.InsertItem( SID_STATUS_DOCPOS,
+//UNUSED2008-05 TEXT_WIDTH( String().Fill( 10, 'X' ) ),
+//UNUSED2008-05 SIB_LEFT|SIB_AUTOSIZE );
+//UNUSED2008-05
+//UNUSED2008-05 // Seitenvorlage
+//UNUSED2008-05 rStatusBar.InsertItem( SID_STATUS_PAGESTYLE,
+//UNUSED2008-05 TEXT_WIDTH( String().Fill( 15, 'X' ) ),
+//UNUSED2008-05 SIB_LEFT|SIB_AUTOSIZE );
+//UNUSED2008-05
+//UNUSED2008-05 // Ma"sstab
+//UNUSED2008-05 rStatusBar.InsertItem( SID_ATTR_ZOOM,
+//UNUSED2008-05 SvxZoomStatusBarControl::GetDefItemWidth(rStatusBar),
+//UNUSED2008-05 SIB_CENTER );
+//UNUSED2008-05
+//UNUSED2008-05 // Einfuege-/Ueberschreibmodus
+//UNUSED2008-05 rStatusBar.InsertItem( SID_ATTR_INSERT,
+//UNUSED2008-05 SvxInsertStatusBarControl::GetDefItemWidth(rStatusBar),
+//UNUSED2008-05 SIB_CENTER );
+//UNUSED2008-05
+//UNUSED2008-05 // Selektionsmodus
+//UNUSED2008-05 rStatusBar.InsertItem( SID_STATUS_SELMODE,
+//UNUSED2008-05 SvxSelectionModeControl::GetDefItemWidth(rStatusBar),
+//UNUSED2008-05 SIB_CENTER );
+//UNUSED2008-05
+//UNUSED2008-05 // Dokument geaendert
+//UNUSED2008-05 rStatusBar.InsertItem( SID_DOC_MODIFIED,
+//UNUSED2008-05 SvxModifyControl::GetDefItemWidth(rStatusBar));
+//UNUSED2008-05
+//UNUSED2008-05 // signatures
+//UNUSED2008-05 rStatusBar.InsertItem( SID_SIGNATURE, XmlSecStatusBarControl::GetDefItemWidth( rStatusBar ), SIB_USERDRAW );
+//UNUSED2008-05 rStatusBar.SetHelpId(SID_SIGNATURE, SID_SIGNATURE);
+//UNUSED2008-05
+//UNUSED2008-05 // Mail
+//UNUSED2008-05 rStatusBar.InsertItem( SID_MAIL_NOTIFY,
+//UNUSED2008-05 TEXT_WIDTH( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Mail")) ),
+//UNUSED2008-05 SIB_CENTER );
+//UNUSED2008-05
+//UNUSED2008-05 // den aktuellen Kontext anzeigen Uhrzeit / FramePos / TabellenInfo / Errors
+//UNUSED2008-05 rStatusBar.InsertItem( SID_ATTR_SIZE,
+//UNUSED2008-05 SvxPosSizeStatusBarControl::GetDefItemWidth(rStatusBar),
+//UNUSED2008-05 SIB_AUTOSIZE|SIB_LEFT|SIB_USERDRAW);
+//UNUSED2008-05 }
+
+#undef TEXT_WIDTH
+
+// DetectFilter functionality has moved - please update your bookmarks
+// see sc/source/ui/unoobj/scdetect.cxx, have a nice day.
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
new file mode 100644
index 000000000000..272852efcf71
--- /dev/null
+++ b/sc/source/ui/app/scmod.cxx
@@ -0,0 +1,2276 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <comphelper/processfactory.hxx>
+
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/app.hxx>
+#include <editeng/eeitem.hxx>
+
+#include <editeng/flditem.hxx>
+#include <editeng/outliner.hxx>
+#include <basic/sbstar.hxx>
+
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objface.hxx>
+
+#include <svx/hyprlink.hxx>
+#include "IAnyRefDialog.hxx"
+
+#include <svtools/ehdl.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <vcl/status.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/macrconf.hxx>
+#include <sfx2/printer.hxx>
+#include <editeng/langitem.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <svl/whiter.hxx>
+#include <svx/selctrl.hxx>
+#include <svx/insctrl.hxx>
+#include <svx/zoomctrl.hxx>
+#include <svx/modctrl.hxx>
+#include <svx/pszctrl.hxx>
+#include <svx/zoomsliderctrl.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/inethist.hxx>
+#include <vcl/waitobj.hxx>
+#include <svx/svxerr.hxx>
+
+
+
+#include "scmod.hxx"
+#include "global.hxx"
+#include "viewopti.hxx"
+#include "docoptio.hxx"
+#include "appoptio.hxx"
+#include "inputopt.hxx"
+#include "printopt.hxx"
+#include "navicfg.hxx"
+#include "addincfg.hxx"
+#include "tabvwsh.hxx"
+#include "prevwsh.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "cfgids.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "msgpool.hxx"
+#include "scresid.hxx"
+#include "anyrefdg.hxx"
+#include "dwfunctr.hxx"
+#include "formdata.hxx"
+//CHINA001 #include "tpview.hxx"
+//CHINA001 #include "tpusrlst.hxx"
+//CHINA001 #include "tpcalc.hxx"
+#include "tpprint.hxx"
+//CHINA001 #include "opredlin.hxx"
+#include "transobj.hxx"
+#include "detfunc.hxx"
+#include "preview.hxx"
+
+#include <svx/xmlsecctrl.hxx>
+
+
+#define ScModule
+#include "scslots.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+#define SC_IDLE_MIN 150
+#define SC_IDLE_MAX 3000
+#define SC_IDLE_STEP 75
+#define SC_IDLE_COUNT 50
+
+static USHORT nIdleCount = 0;
+
+//------------------------------------------------------------------
+
+SFX_IMPL_INTERFACE( ScModule, SfxShell, ScResId(RID_APPTITLE) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_APPLICATION | SFX_VISIBILITY_DESKTOP | SFX_VISIBILITY_STANDARD | SFX_VISIBILITY_CLIENT | SFX_VISIBILITY_VIEWER,
+ ScResId(RID_OBJECTBAR_APP) );
+ SFX_STATUSBAR_REGISTRATION( ScResId(SCCFG_STATUSBAR) ); // nur ID wichtig
+ SFX_CHILDWINDOW_REGISTRATION( SvxHyperlinkDlgWrapper::GetChildWindowId() );
+}
+
+//------------------------------------------------------------------
+
+ScModule::ScModule( SfxObjectFactory* pFact ) :
+ SfxModule( SfxApplication::CreateResManager( "sc" ), FALSE, pFact, NULL ),
+ pSelTransfer( NULL ),
+ pMessagePool( NULL ),
+ pRefInputHandler( NULL ),
+ pViewCfg( NULL ),
+ pDocCfg( NULL ),
+ pAppCfg( NULL ),
+ pInputCfg( NULL ),
+ pPrintCfg( NULL ),
+ pNavipiCfg( NULL ),
+ pAddInCfg( NULL ),
+ pColorConfig( NULL ),
+ pAccessOptions( NULL ),
+ pCTLOptions( NULL ),
+ pUserOptions( NULL ),
+ pErrorHdl( NULL ),
+ pSvxErrorHdl( NULL ),
+ pFormEditData( NULL ),
+ nCurRefDlgId( 0 ),
+ bIsWaterCan( FALSE ),
+ bIsInEditCommand( FALSE ),
+ bIsInExecuteDrop( FALSE ),
+ mbIsInSharedDocLoading( false ),
+ mbIsInSharedDocSaving( false )
+{
+ // im ctor ist der ResManager (DLL-Daten) noch nicht initialisiert!
+
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("StarCalc"))); // fuer Basic
+
+ ResetDragObject();
+ SetClipObject( NULL, NULL );
+
+ // InputHandler braucht nicht mehr angelegt zu werden
+
+ // ErrorHandler anlegen - war in Init()
+ // zwischen OfficeApplication::Init und ScGlobal::Init
+ SvxErrorHandler::Get();
+ pErrorHdl = new SfxErrorHandler( RID_ERRHDLSC,
+ ERRCODE_AREA_SC,
+ ERRCODE_AREA_APP2-1,
+ GetResMgr() );
+
+ aSpellTimer.SetTimeout(10);
+ aSpellTimer.SetTimeoutHdl( LINK( this, ScModule, SpellTimerHdl ) );
+ aIdleTimer.SetTimeout(SC_IDLE_MIN);
+ aIdleTimer.SetTimeoutHdl( LINK( this, ScModule, IdleHandler ) );
+ aIdleTimer.Start();
+
+ pMessagePool = new ScMessagePool;
+ pMessagePool->FreezeIdRanges();
+ SetPool( pMessagePool );
+ ScGlobal::InitTextHeight( pMessagePool );
+
+ StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING
+}
+
+ScModule::~ScModule()
+{
+ DBG_ASSERT( !pSelTransfer, "Selection Transfer object not deleted" );
+
+ // InputHandler braucht nicht mehr geloescht zu werden (gibt keinen an der App mehr)
+
+ SfxItemPool::Free(pMessagePool);
+
+ DELETEZ( pFormEditData );
+
+ delete pErrorHdl;
+// delete pSvxErrorHdl;
+
+ ScGlobal::Clear(); // ruft auch ScDocumentPool::DeleteVersionMaps();
+
+ DeleteCfg(); // wurde mal aus Exit() gerufen
+}
+
+//------------------------------------------------------------------
+void ScModule::ConfigurationChanged( utl::ConfigurationBroadcaster* p, sal_uInt32 )
+{
+ if ( p == pColorConfig || p == pAccessOptions )
+ {
+ // Test if detective objects have to be updated with new colors
+ // (if the detective colors haven't been used yet, there's nothing to update)
+ if ( ScDetectiveFunc::IsColorsInitialized() )
+ {
+ const svtools::ColorConfig& rColors = GetColorConfig();
+ BOOL bArrows =
+ ( ScDetectiveFunc::GetArrowColor() != (ColorData)rColors.GetColorValue(svtools::CALCDETECTIVE).nColor ||
+ ScDetectiveFunc::GetErrorColor() != (ColorData)rColors.GetColorValue(svtools::CALCDETECTIVEERROR).nColor );
+ BOOL bComments =
+ ( ScDetectiveFunc::GetCommentColor() != (ColorData)rColors.GetColorValue(svtools::CALCNOTESBACKGROUND).nColor );
+ if ( bArrows || bComments )
+ {
+ ScDetectiveFunc::InitializeColors(); // get the new colors
+
+ // update detective objects in all open documents
+ SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
+ while ( pObjSh )
+ {
+ if ( pObjSh->Type() == TYPE(ScDocShell) )
+ {
+ ScDocShell* pDocSh = ((ScDocShell*)pObjSh);
+ if ( bArrows )
+ ScDetectiveFunc( pDocSh->GetDocument(), 0 ).UpdateAllArrowColors();
+ if ( bComments )
+ ScDetectiveFunc::UpdateAllComments( *pDocSh->GetDocument() );
+ }
+ pObjSh = SfxObjectShell::GetNext( *pObjSh );
+ }
+ }
+ }
+
+ // force all views to repaint, using the new options
+
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while(pViewShell)
+ {
+ if ( pViewShell->ISA(ScTabViewShell) )
+ {
+ ScTabViewShell* pViewSh = (ScTabViewShell*)pViewShell;
+ pViewSh->PaintGrid();
+ pViewSh->PaintTop();
+ pViewSh->PaintLeft();
+ pViewSh->PaintExtras();
+
+ ScInputHandler* pHdl = pViewSh->GetInputHandler();
+ if ( pHdl )
+ pHdl->ForgetLastPattern(); // EditEngine BackgroundColor may change
+ }
+ else if ( pViewShell->ISA(ScPreviewShell) )
+ {
+ Window* pWin = pViewShell->GetWindow();
+ if (pWin)
+ pWin->Invalidate();
+ }
+ pViewShell = SfxViewShell::GetNext( *pViewShell );
+ }
+ }
+ else if ( p == pCTLOptions )
+ {
+ // for all documents: set digit language for printer, recalc output factor, update row heights
+ SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
+ while ( pObjSh )
+ {
+ if ( pObjSh->Type() == TYPE(ScDocShell) )
+ {
+ ScDocShell* pDocSh = ((ScDocShell*)pObjSh);
+ OutputDevice* pPrinter = pDocSh->GetPrinter();
+ if ( pPrinter )
+ pPrinter->SetDigitLanguage( GetOptDigitLanguage() );
+
+ pDocSh->CalcOutputFactor();
+
+ SCTAB nTabCount = pDocSh->GetDocument()->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ pDocSh->AdjustRowHeight( 0, MAXROW, nTab );
+ }
+ pObjSh = SfxObjectShell::GetNext( *pObjSh );
+ }
+
+ // for all views (table and preview): update digit language
+ SfxViewShell* pSh = SfxViewShell::GetFirst();
+ while ( pSh )
+ {
+ if ( pSh->ISA( ScTabViewShell ) )
+ {
+ ScTabViewShell* pViewSh = (ScTabViewShell*)pSh;
+
+ // set ref-device for EditEngine (re-evaluates digit settings)
+ ScInputHandler* pHdl = GetInputHdl(pViewSh);
+ if (pHdl)
+ pHdl->UpdateRefDevice();
+
+ pViewSh->DigitLanguageChanged();
+ pViewSh->PaintGrid();
+ }
+ else if ( pSh->ISA( ScPreviewShell ) )
+ {
+ ScPreviewShell* pPreviewSh = (ScPreviewShell*)pSh;
+ ScPreview* pPreview = pPreviewSh->GetPreview();
+
+ pPreview->SetDigitLanguage( GetOptDigitLanguage() );
+ pPreview->Invalidate();
+ }
+
+ pSh = SfxViewShell::GetNext( *pSh );
+ }
+ }
+}
+
+void ScModule::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA(SfxSimpleHint) )
+ {
+ ULONG nHintId = ((SfxSimpleHint&)rHint).GetId();
+ if ( nHintId == SFX_HINT_DEINITIALIZING )
+ {
+ // ConfigItems must be removed before ConfigManager
+ DeleteCfg();
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScModule::DeleteCfg()
+{
+ DELETEZ( pViewCfg ); // Speichern passiert vor Exit() automatisch
+ DELETEZ( pDocCfg );
+ DELETEZ( pAppCfg );
+ DELETEZ( pInputCfg );
+ DELETEZ( pPrintCfg );
+ DELETEZ( pNavipiCfg );
+ DELETEZ( pAddInCfg );
+
+ if ( pColorConfig )
+ {
+ pColorConfig->RemoveListener(this);
+ DELETEZ( pColorConfig );
+ }
+ if ( pAccessOptions )
+ {
+ pAccessOptions->RemoveListener(this);
+ DELETEZ( pAccessOptions );
+ }
+ if ( pCTLOptions )
+ {
+ pCTLOptions->RemoveListener(this);
+ DELETEZ( pCTLOptions );
+ }
+ if( pUserOptions )
+ {
+ DELETEZ( pUserOptions );
+ }
+}
+
+//------------------------------------------------------------------
+
+#define TEXT_WIDTH(s) rStatusBar.GetTextWidth((s))
+
+void ScModule::FillStatusBar(StatusBar& rStatusBar)
+{
+ // Dokumentposition (Tabelle x / y)
+ rStatusBar.InsertItem( SID_STATUS_DOCPOS,
+ TEXT_WIDTH( String().Fill( 10, 'X' ) ),
+ SIB_LEFT|SIB_AUTOSIZE );
+ rStatusBar.SetHelpId( SID_STATUS_DOCPOS, SID_STATUS_DOCPOS );
+
+ // Seitenvorlage
+ rStatusBar.InsertItem( SID_STATUS_PAGESTYLE,
+ TEXT_WIDTH( String().Fill( 15, 'X' ) ),
+ SIB_LEFT|SIB_AUTOSIZE );
+ rStatusBar.SetHelpId( SID_STATUS_PAGESTYLE, SID_STATUS_PAGESTYLE );
+
+ // Einfuege-/Ueberschreibmodus
+ rStatusBar.InsertItem( SID_ATTR_INSERT,
+ SvxInsertStatusBarControl::GetDefItemWidth(rStatusBar),
+ SIB_CENTER );
+ rStatusBar.SetHelpId( SID_ATTR_INSERT, SID_ATTR_INSERT );
+
+ // Selektionsmodus
+ rStatusBar.InsertItem( SID_STATUS_SELMODE,
+ SvxSelectionModeControl::GetDefItemWidth(rStatusBar),
+ SIB_CENTER );
+ rStatusBar.SetHelpId( SID_STATUS_SELMODE, SID_STATUS_SELMODE );
+
+ // Dokument geaendert
+ rStatusBar.InsertItem( SID_DOC_MODIFIED,
+ SvxModifyControl::GetDefItemWidth(rStatusBar));
+
+ // signatures
+ rStatusBar.InsertItem( SID_SIGNATURE, XmlSecStatusBarControl::GetDefItemWidth( rStatusBar ), SIB_USERDRAW );
+ rStatusBar.SetHelpId(SID_SIGNATURE, SID_SIGNATURE);
+
+
+ rStatusBar.SetHelpId( SID_DOC_MODIFIED, SID_DOC_MODIFIED );
+
+ // den aktuellen Kontext anzeigen Uhrzeit / FramePos / TabellenInfo / Errors
+ rStatusBar.InsertItem( SID_ATTR_SIZE,
+ SvxPosSizeStatusBarControl::GetDefItemWidth(rStatusBar),
+ SIB_AUTOSIZE|SIB_LEFT|SIB_USERDRAW);
+ rStatusBar.SetHelpId( SID_ATTR_SIZE, SID_ATTR_SIZE );
+
+ // Ma"sstab
+ rStatusBar.InsertItem( SID_ATTR_ZOOM,
+ SvxZoomStatusBarControl::GetDefItemWidth(rStatusBar),
+ SIB_CENTER );
+ rStatusBar.SetHelpId( SID_ATTR_ZOOM, SID_ATTR_ZOOM );
+
+ // ZoomSlider
+ rStatusBar.InsertItem( SID_ATTR_ZOOMSLIDER,
+ TEXT_WIDTH( String().Fill( 15, 'X' ) ),
+ SIB_CENTER );
+ rStatusBar.SetHelpId( SID_ATTR_ZOOMSLIDER, SID_ATTR_ZOOMSLIDER );
+}
+
+#undef TEXT_WIDTH
+
+//------------------------------------------------------------------
+//
+// von der Applikation verschoben:
+//
+//------------------------------------------------------------------
+
+void ScModule::Execute( SfxRequest& rReq )
+{
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : NULL;
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_CHOOSE_DESIGN:
+ {
+ String aMacroName =
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Template.Samples.ShowStyles"));
+ SfxApplication* pApp = SFX_APP();
+ pApp->EnterBasicCall();
+ pApp->GetMacroConfig()->Call( NULL, aMacroName, pApp->GetBasicManager() );
+ pApp->LeaveBasicCall();
+ }
+ break;
+ case SID_EURO_CONVERTER:
+ {
+ String aMacroName =
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Euro.ConvertRun.Main"));
+ SfxApplication* pApp = SFX_APP();
+ pApp->EnterBasicCall();
+ pApp->GetMacroConfig()->Call( NULL, aMacroName, pApp->GetBasicManager() );
+ pApp->LeaveBasicCall();
+ }
+ break;
+ case SID_AUTOSPELL_CHECK:
+ {
+ BOOL bSet;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( nSlot, TRUE, &pItem ) )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+ else
+ { // Toggle
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current());
+ if ( pDocSh )
+ bSet = !pDocSh->GetDocument()->GetDocOptions().IsAutoSpell();
+ else
+ bSet = !GetDocOptions().IsAutoSpell();
+ }
+
+ SfxItemSet aSet( GetPool(), SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK );
+ aSet.Put( SfxBoolItem( SID_AUTOSPELL_CHECK, bSet ) );
+ ModifyOptions( aSet );
+ rReq.Done();
+ }
+ break;
+
+ case SID_ATTR_METRIC:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( nSlot, TRUE, &pItem ) )
+ {
+ FieldUnit eUnit = (FieldUnit)((const SfxUInt16Item*)pItem)->GetValue();
+ switch( eUnit )
+ {
+ case FUNIT_MM: // nur die Einheiten, die auch im Dialog stehen
+ case FUNIT_CM:
+ case FUNIT_INCH:
+ case FUNIT_PICA:
+ case FUNIT_POINT:
+ {
+ PutItem( *pItem );
+ ScAppOptions aNewOpts( GetAppOptions() );
+ aNewOpts.SetAppMetric( eUnit );
+ SetAppOptions( aNewOpts );
+ rReq.Done();
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ break;
+
+ case FID_AUTOCOMPLETE:
+ {
+ ScAppOptions aNewOpts( GetAppOptions() );
+ BOOL bNew = !aNewOpts.GetAutoComplete();
+ aNewOpts.SetAutoComplete( bNew );
+ SetAppOptions( aNewOpts );
+ ScInputHandler::SetAutoComplete( bNew );
+ if (pBindings)
+ pBindings->Invalidate( FID_AUTOCOMPLETE );
+ rReq.Done();
+ }
+ break;
+
+ case SID_DETECTIVE_AUTO:
+ {
+ ScAppOptions aNewOpts( GetAppOptions() );
+ BOOL bNew = !aNewOpts.GetDetectiveAuto();
+ SFX_REQUEST_ARG( rReq, pAuto, SfxBoolItem, SID_DETECTIVE_AUTO, sal_False );
+ if ( pAuto )
+ bNew = pAuto->GetValue();
+
+ aNewOpts.SetDetectiveAuto( bNew );
+ SetAppOptions( aNewOpts );
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_AUTO );
+ rReq.AppendItem( SfxBoolItem( SID_DETECTIVE_AUTO, bNew ) );
+ rReq.Done();
+ }
+ break;
+
+ case SID_PSZ_FUNCTION:
+ if (pReqArgs)
+ {
+ const SfxUInt16Item& rItem = (const SfxUInt16Item&)pReqArgs->Get(SID_PSZ_FUNCTION);
+ DBG_ASSERT(rItem.ISA(SfxUInt16Item),"falscher Parameter");
+
+ ScAppOptions aNewOpts( GetAppOptions() );
+ aNewOpts.SetStatusFunc( rItem.GetValue() );
+ SetAppOptions( aNewOpts );
+
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_TABLE_CELL );
+ pBindings->Update( SID_TABLE_CELL ); // sofort
+
+ pBindings->Invalidate( SID_PSZ_FUNCTION );
+ pBindings->Update( SID_PSZ_FUNCTION );
+ // falls Menue gleich wieder aufgeklappt wird
+ }
+ }
+ break;
+
+ case SID_ATTR_LANGUAGE:
+ case SID_ATTR_CHAR_CJK_LANGUAGE:
+ case SID_ATTR_CHAR_CTL_LANGUAGE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( GetPool().GetWhich(nSlot), TRUE, &pItem ) )
+ {
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current());
+ ScDocument* pDoc = pDocSh ? pDocSh->GetDocument() : NULL;
+ if ( pDoc )
+ {
+ LanguageType eNewLang = ((SvxLanguageItem*)pItem)->GetLanguage();
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ LanguageType eOld = ( nSlot == SID_ATTR_CHAR_CJK_LANGUAGE ) ? eCjk :
+ ( ( nSlot == SID_ATTR_CHAR_CTL_LANGUAGE ) ? eCtl : eLatin );
+ if ( eNewLang != eOld )
+ {
+ if ( nSlot == SID_ATTR_CHAR_CJK_LANGUAGE )
+ eCjk = eNewLang;
+ else if ( nSlot == SID_ATTR_CHAR_CTL_LANGUAGE )
+ eCtl = eNewLang;
+ else
+ eLatin = eNewLang;
+
+ pDoc->SetLanguage( eLatin, eCjk, eCtl );
+
+ ScInputHandler* pInputHandler = GetInputHdl();
+ if ( pInputHandler )
+ pInputHandler->UpdateSpellSettings(); // EditEngine-Flags
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+ if ( pViewSh )
+ pViewSh->UpdateDrawTextOutliner(); // EditEngine-Flags
+
+ pDocSh->SetDocumentModified();
+ }
+ }
+ }
+ }
+ break;
+
+ case FID_FOCUS_POSWND:
+ {
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ {
+ ScInputWindow* pWin = pHdl->GetInputWindow();
+ if (pWin)
+ pWin->PosGrabFocus();
+ }
+ rReq.Done();
+ }
+ break;
+
+ case SID_OPEN_XML_FILTERSETTINGS:
+ {
+ try
+ {
+ com::sun::star::uno::Reference < ::com::sun::star::ui::dialogs::XExecutableDialog > xDialog(::comphelper::getProcessServiceFactory()->createInstance(rtl::OUString::createFromAscii("com.sun.star.comp.ui.XSLTFilterDialog")), com::sun::star::uno::UNO_QUERY);
+ if( xDialog.is() )
+ {
+ xDialog->execute();
+ }
+ }
+ catch( ::com::sun::star::uno::RuntimeException& )
+ {
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR( "ScApplication: Unknown Message." );
+ break;
+ }
+}
+
+void ScModule::GetState( SfxItemSet& rSet )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case FID_AUTOCOMPLETE:
+ rSet.Put( SfxBoolItem( nWhich, GetAppOptions().GetAutoComplete() ) );
+ break;
+ case SID_DETECTIVE_AUTO:
+ rSet.Put( SfxBoolItem( nWhich, GetAppOptions().GetDetectiveAuto() ) );
+ break;
+ case SID_PSZ_FUNCTION:
+ rSet.Put( SfxUInt16Item( nWhich, GetAppOptions().GetStatusFunc() ) );
+ break;
+ case SID_ATTR_METRIC:
+ rSet.Put( SfxUInt16Item( nWhich, sal::static_int_cast<UINT16>(GetAppOptions().GetAppMetric()) ) );
+ break;
+ case SID_AUTOSPELL_CHECK:
+ {
+ BOOL bAuto;
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current());
+ if ( pDocSh )
+ bAuto = pDocSh->GetDocument()->GetDocOptions().IsAutoSpell();
+ else
+ {
+ USHORT nDummyLang, nDummyCjk, nDummyCtl;
+ GetSpellSettings( nDummyLang, nDummyCjk, nDummyCtl, bAuto );
+ }
+ rSet.Put( SfxBoolItem( nWhich, bAuto ) );
+ }
+ break;
+ case SID_ATTR_LANGUAGE:
+ case ATTR_CJK_FONT_LANGUAGE: // WID for SID_ATTR_CHAR_CJK_LANGUAGE
+ case ATTR_CTL_FONT_LANGUAGE: // WID for SID_ATTR_CHAR_CTL_LANGUAGE
+ {
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current());
+ ScDocument* pDoc = pDocSh ? pDocSh->GetDocument() : NULL;
+ if ( pDoc )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ LanguageType eLang = ( nWhich == ATTR_CJK_FONT_LANGUAGE ) ? eCjk :
+ ( ( nWhich == ATTR_CTL_FONT_LANGUAGE ) ? eCtl : eLatin );
+ rSet.Put( SvxLanguageItem( eLang, nWhich ) );
+ }
+ }
+ break;
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+void ScModule::HideDisabledSlots( SfxItemSet& rSet )
+{
+ if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() )
+ {
+ SfxBindings& rBindings = pViewFrm->GetBindings();
+ SfxWhichIter aIter( rSet );
+ for( USHORT nWhich = aIter.FirstWhich(); nWhich != 0; nWhich = aIter.NextWhich() )
+ {
+ ScViewUtil::HideDisabledSlot( rSet, rBindings, nWhich );
+ // always disable the slots
+ rSet.DisableItem( nWhich );
+ }
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void ScModule::ResetDragObject()
+{
+ aDragData.pCellTransfer = NULL;
+ aDragData.pDrawTransfer = NULL;
+
+ aDragData.aLinkDoc.Erase();
+ aDragData.aLinkTable.Erase();
+ aDragData.aLinkArea.Erase();
+ aDragData.pJumpLocalDoc = NULL;
+ aDragData.aJumpTarget.Erase();
+ aDragData.aJumpText.Erase();
+}
+
+void ScModule::SetDragObject( ScTransferObj* pCellObj, ScDrawTransferObj* pDrawObj )
+{
+ ResetDragObject();
+ aDragData.pCellTransfer = pCellObj;
+ aDragData.pDrawTransfer = pDrawObj;
+}
+
+void ScModule::SetDragLink( const String& rDoc, const String& rTab, const String& rArea )
+{
+ ResetDragObject();
+
+ aDragData.aLinkDoc = rDoc;
+ aDragData.aLinkTable = rTab;
+ aDragData.aLinkArea = rArea;
+}
+
+void ScModule::SetDragJump( ScDocument* pLocalDoc, const String& rTarget, const String& rText )
+{
+ ResetDragObject();
+
+ aDragData.pJumpLocalDoc = pLocalDoc;
+ aDragData.aJumpTarget = rTarget;
+ aDragData.aJumpText = rText;
+}
+
+//------------------------------------------------------------------
+
+void ScModule::SetClipObject( ScTransferObj* pCellObj, ScDrawTransferObj* pDrawObj )
+{
+ DBG_ASSERT( !pCellObj || !pDrawObj, "SetClipObject: not allowed to set both objects" );
+
+ aClipData.pCellClipboard = pCellObj;
+ aClipData.pDrawClipboard = pDrawObj;
+}
+
+ScDocument* ScModule::GetClipDoc()
+{
+ // called from document
+
+ ScTransferObj* pObj = ScTransferObj::GetOwnClipboard( NULL );
+ if (pObj)
+ return pObj->GetDocument();
+
+ return NULL;
+}
+
+//------------------------------------------------------------------
+
+void ScModule::SetSelectionTransfer( ScSelectionTransferObj* pNew )
+{
+ pSelTransfer = pNew;
+}
+
+//------------------------------------------------------------------
+
+void ScModule::InitFormEditData()
+{
+ pFormEditData = new ScFormEditData;
+}
+
+void ScModule::ClearFormEditData()
+{
+ DELETEZ( pFormEditData );
+}
+
+//------------------------------------------------------------------
+
+void ScModule::SetViewOptions( const ScViewOptions& rOpt )
+{
+ if ( !pViewCfg )
+ pViewCfg = new ScViewCfg;
+
+ pViewCfg->SetOptions( rOpt );
+}
+
+const ScViewOptions& ScModule::GetViewOptions()
+{
+ if ( !pViewCfg )
+ pViewCfg = new ScViewCfg;
+
+ return *pViewCfg;
+}
+
+void ScModule::SetDocOptions( const ScDocOptions& rOpt )
+{
+ if ( !pDocCfg )
+ pDocCfg = new ScDocCfg;
+
+ pDocCfg->SetOptions( rOpt );
+}
+
+const ScDocOptions& ScModule::GetDocOptions()
+{
+ if ( !pDocCfg )
+ pDocCfg = new ScDocCfg;
+
+ return *pDocCfg;
+}
+
+#ifndef LRU_MAX
+#define LRU_MAX 10
+#endif
+
+void ScModule::InsertEntryToLRUList(USHORT nFIndex)
+{
+ if(nFIndex != 0)
+ {
+ const ScAppOptions& rAppOpt = GetAppOptions();
+ USHORT nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (USHORT)LRU_MAX );
+ USHORT* pLRUListIds = rAppOpt.GetLRUFuncList();
+
+ USHORT aIdxList[LRU_MAX];
+ USHORT n = 0;
+ BOOL bFound = FALSE;
+
+ while ((n < LRU_MAX) && n<nLRUFuncCount) // alte Liste abklappern
+ {
+ if (!bFound && (pLRUListIds[n]== nFIndex))
+ bFound = TRUE; // erster! Treffer
+ else if (bFound)
+ aIdxList[n ] = pLRUListIds[n]; // hinter Treffer kopieren
+ else if ((n+1) < LRU_MAX)
+ aIdxList[n+1] = pLRUListIds[n]; // vor Treffer verschieben
+ n++;
+ }
+ if (!bFound && (n < LRU_MAX)) // Eintrag nicht gefunden?
+ n++; // einen mehr
+ aIdxList[0] = nFIndex; // Current on Top
+
+ ScAppOptions aNewOpts(rAppOpt); // an App melden
+ aNewOpts.SetLRUFuncList(aIdxList, n);
+ SetAppOptions(aNewOpts);
+
+ RecentFunctionsChanged();
+ }
+}
+
+void ScModule::RecentFunctionsChanged()
+{
+ // update function list window
+ USHORT nFuncListID = ScFunctionChildWindow::GetChildWindowId();
+
+ //! notify all views
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && pViewFrm->HasChildWindow(nFuncListID) )
+ {
+ ScFunctionChildWindow* pWnd =(ScFunctionChildWindow*)pViewFrm->GetChildWindow( nFuncListID );
+
+ ScFunctionDockWin* pFuncList=(ScFunctionDockWin*)pWnd->GetWindow();
+
+ pFuncList->InitLRUList();
+ }
+}
+
+void ScModule::SetAppOptions( const ScAppOptions& rOpt )
+{
+ if ( !pAppCfg )
+ pAppCfg = new ScAppCfg;
+
+ pAppCfg->SetOptions( rOpt );
+}
+
+void global_InitAppOptions()
+{
+ SC_MOD()->GetAppOptions();
+}
+
+const ScAppOptions& ScModule::GetAppOptions()
+{
+ if ( !pAppCfg )
+ pAppCfg = new ScAppCfg;
+
+ return *pAppCfg;
+}
+
+void ScModule::SetInputOptions( const ScInputOptions& rOpt )
+{
+ if ( !pInputCfg )
+ pInputCfg = new ScInputCfg;
+
+ pInputCfg->SetOptions( rOpt );
+}
+
+const ScInputOptions& ScModule::GetInputOptions()
+{
+ if ( !pInputCfg )
+ pInputCfg = new ScInputCfg;
+
+ return *pInputCfg;
+}
+
+void ScModule::SetPrintOptions( const ScPrintOptions& rOpt )
+{
+ if ( !pPrintCfg )
+ pPrintCfg = new ScPrintCfg;
+
+ pPrintCfg->SetOptions( rOpt );
+}
+
+const ScPrintOptions& ScModule::GetPrintOptions()
+{
+ if ( !pPrintCfg )
+ pPrintCfg = new ScPrintCfg;
+
+ return *pPrintCfg;
+}
+
+ScNavipiCfg& ScModule::GetNavipiCfg()
+{
+ if ( !pNavipiCfg )
+ pNavipiCfg = new ScNavipiCfg;
+
+ return *pNavipiCfg;
+}
+
+ScAddInCfg& ScModule::GetAddInCfg()
+{
+ if ( !pAddInCfg )
+ pAddInCfg = new ScAddInCfg;
+
+ return *pAddInCfg;
+}
+
+svtools::ColorConfig& ScModule::GetColorConfig()
+{
+ if ( !pColorConfig )
+ {
+ pColorConfig = new svtools::ColorConfig;
+ pColorConfig->AddListener(this);
+ }
+
+ return *pColorConfig;
+}
+
+SvtAccessibilityOptions& ScModule::GetAccessOptions()
+{
+ if ( !pAccessOptions )
+ {
+ pAccessOptions = new SvtAccessibilityOptions;
+ pAccessOptions->AddListener(this);
+ }
+
+ return *pAccessOptions;
+}
+
+SvtCTLOptions& ScModule::GetCTLOptions()
+{
+ if ( !pCTLOptions )
+ {
+ pCTLOptions = new SvtCTLOptions;
+ pCTLOptions->AddListener(this);
+ }
+
+ return *pCTLOptions;
+}
+
+SvtUserOptions& ScModule::GetUserOptions()
+{
+ if( !pUserOptions )
+ {
+ pUserOptions = new SvtUserOptions;
+ }
+ return *pUserOptions;
+}
+
+USHORT ScModule::GetOptDigitLanguage()
+{
+ SvtCTLOptions::TextNumerals eNumerals = GetCTLOptions().GetCTLTextNumerals();
+ return ( eNumerals == SvtCTLOptions::NUMERALS_ARABIC ) ? LANGUAGE_ENGLISH_US :
+ ( eNumerals == SvtCTLOptions::NUMERALS_HINDI) ? LANGUAGE_ARABIC_SAUDI_ARABIA :
+ LANGUAGE_SYSTEM;
+}
+
+//------------------------------------------------------------------
+//
+// Optionen
+//
+//------------------------------------------------------------------
+
+//
+// ModifyOptions - Items aus Calc-Options-Dialog
+// und SID_AUTOSPELL_CHECK
+//
+
+#define IS_AVAILABLE(w,item) (SFX_ITEM_SET==rOptSet.GetItemState((w),TRUE,&item))
+
+void ScModule::ModifyOptions( const SfxItemSet& rOptSet )
+{
+ USHORT nOldSpellLang, nOldCjkLang, nOldCtlLang;
+ BOOL bOldAutoSpell;
+ GetSpellSettings( nOldSpellLang, nOldCjkLang, nOldCtlLang, bOldAutoSpell );
+
+ if (!pAppCfg)
+ GetAppOptions();
+ DBG_ASSERT( pAppCfg, "AppOptions not initialised :-(" );
+
+ if (!pInputCfg)
+ GetInputOptions();
+ DBG_ASSERT( pInputCfg, "InputOptions not initialised :-(" );
+
+ //--------------------------------------------------------------
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : NULL;
+
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current());
+ ScDocument* pDoc = pDocSh ? pDocSh->GetDocument() : NULL;
+ const SfxPoolItem* pItem = NULL;
+ BOOL bRepaint = FALSE;
+ BOOL bUpdateMarks = FALSE;
+ BOOL bUpdateRefDev = FALSE;
+ BOOL bCalcAll = FALSE;
+ BOOL bSaveSpellCheck = FALSE;
+ BOOL bSaveAppOptions = FALSE;
+ BOOL bSaveInputOptions = FALSE;
+
+ //--------------------------------------------------------------------------
+
+ // SFX_APP()->SetOptions( rOptSet );
+
+ // Linguistik nicht mehr
+
+ if ( IS_AVAILABLE(SID_ATTR_METRIC,pItem) )
+ {
+ PutItem( *pItem );
+ pAppCfg->SetAppMetric( (FieldUnit)((const SfxUInt16Item*)pItem)->GetValue() );
+ bSaveAppOptions = TRUE;
+ }
+
+ if ( IS_AVAILABLE(SCITEM_USERLIST,pItem) )
+ {
+ ScGlobal::SetUserList( ((const ScUserListItem*)pItem)->GetUserList() );
+ bSaveAppOptions = TRUE;
+ }
+
+ if ( IS_AVAILABLE(SID_SC_OPT_SYNCZOOM,pItem) )
+ {
+ pAppCfg->SetSynchronizeZoom( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+ bSaveAppOptions = TRUE;
+ }
+
+ //============================================
+ // ViewOptions
+ //============================================
+
+ if ( IS_AVAILABLE(SID_SCVIEWOPTIONS,pItem) )
+ {
+ const ScViewOptions& rNewOpt = ((const ScTpViewItem*)pItem)->GetViewOptions();
+
+ if ( pViewSh )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ const ScViewOptions& rOldOpt = pViewData->GetOptions();
+
+ BOOL bAnchorList = ( rOldOpt.GetOption( VOPT_ANCHOR ) !=
+ rNewOpt.GetOption( VOPT_ANCHOR ) );
+
+ if ( rOldOpt != rNewOpt )
+ {
+ pViewData->SetOptions( rNewOpt ); // veraendert rOldOpt
+ pViewData->GetDocument()->SetViewOptions( rNewOpt );
+ pDocSh->SetDocumentModified();
+ bRepaint = TRUE;
+ }
+ if ( bAnchorList )
+ pViewSh->UpdateAnchorHandles();
+ }
+ SetViewOptions( rNewOpt );
+ if (pBindings)
+ pBindings->Invalidate(SID_HELPLINES_MOVE);
+ }
+
+ //============================================
+ // GridOptions, Auswertung nach ViewOptions,
+ // da GridOptions Member der ViewOptions ist!
+ //============================================
+
+ if ( IS_AVAILABLE(SID_ATTR_GRID_OPTIONS,pItem) )
+ {
+ ScGridOptions aNewGridOpt( (const SvxOptionsGrid&)((const SvxGridItem&)*pItem) );
+
+ if ( pViewSh )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScViewOptions aNewViewOpt( pViewData->GetOptions() );
+ const ScGridOptions& rOldGridOpt = aNewViewOpt.GetGridOptions();
+
+ if ( rOldGridOpt != aNewGridOpt )
+ {
+ aNewViewOpt.SetGridOptions( aNewGridOpt );
+ pViewData->SetOptions( aNewViewOpt );
+ pViewData->GetDocument()->SetViewOptions( aNewViewOpt );
+ pDocSh->SetDocumentModified();
+ bRepaint = TRUE;
+ }
+ }
+ ScViewOptions aNewViewOpt ( GetViewOptions() );
+ aNewViewOpt.SetGridOptions( aNewGridOpt );
+ SetViewOptions( aNewViewOpt );
+ if (pBindings)
+ {
+ pBindings->Invalidate(SID_GRID_VISIBLE);
+ pBindings->Invalidate(SID_GRID_USE);
+ }
+ }
+
+
+ //============================================
+ // DocOptions
+ //============================================
+
+ if ( IS_AVAILABLE(SID_SCDOCOPTIONS,pItem) )
+ {
+ const ScDocOptions& rNewOpt = ((const ScTpCalcItem*)pItem)->GetDocOptions();
+
+ if ( pDoc )
+ {
+ const ScDocOptions& rOldOpt = pDoc->GetDocOptions();
+
+ bRepaint = ( bRepaint || ( rOldOpt != rNewOpt ) );
+ bCalcAll = bRepaint &&
+ ( rOldOpt.IsIter() != rNewOpt.IsIter()
+ || rOldOpt.GetIterCount() != rNewOpt.GetIterCount()
+ || rOldOpt.GetIterEps() != rNewOpt.GetIterEps()
+ || rOldOpt.IsIgnoreCase() != rNewOpt.IsIgnoreCase()
+ || rOldOpt.IsCalcAsShown() != rNewOpt.IsCalcAsShown()
+ || (rNewOpt.IsCalcAsShown() &&
+ rOldOpt.GetStdPrecision() != rNewOpt.GetStdPrecision())
+ || rOldOpt.IsMatchWholeCell() != rNewOpt.IsMatchWholeCell()
+ || rOldOpt.GetYear2000() != rNewOpt.GetYear2000()
+ || rOldOpt.IsFormulaRegexEnabled() != rNewOpt.IsFormulaRegexEnabled()
+ );
+ pDoc->SetDocOptions( rNewOpt );
+ pDocSh->SetDocumentModified();
+ }
+ SetDocOptions( rNewOpt );
+ }
+
+ // nach den eigentlichen DocOptions auch noch die TabDistance setzen
+ if ( IS_AVAILABLE(SID_ATTR_DEFTABSTOP,pItem) )
+ {
+ USHORT nTabDist = ((SfxUInt16Item*)pItem)->GetValue();
+ ScDocOptions aOpt(GetDocOptions());
+ aOpt.SetTabDistance(nTabDist);
+ SetDocOptions( aOpt );
+
+ if ( pDoc )
+ {
+ ScDocOptions aDocOpt(pDoc->GetDocOptions());
+ aDocOpt.SetTabDistance(nTabDist);
+ pDoc->SetDocOptions( aDocOpt );
+ pDocSh->SetDocumentModified();
+ if(pDoc->GetDrawLayer())
+ pDoc->GetDrawLayer()->SetDefaultTabulator(nTabDist);
+ }
+ }
+
+ // AutoSpell nach den Doc-Options (weil Member)
+
+ if ( IS_AVAILABLE(SID_AUTOSPELL_CHECK,pItem) ) // an Doc-Options
+ {
+ BOOL bDoAutoSpell = ((const SfxBoolItem*)pItem)->GetValue();
+
+ if (pDoc)
+ {
+ ScDocOptions aNewOpt = pDoc->GetDocOptions();
+ if ( aNewOpt.IsAutoSpell() != bDoAutoSpell )
+ {
+ aNewOpt.SetAutoSpell( bDoAutoSpell );
+ pDoc->SetDocOptions( aNewOpt );
+
+ if (bDoAutoSpell)
+ pDoc->SetOnlineSpellPos( ScAddress(0,0,0) ); // vorne anfangen
+ else
+ {
+ WaitObject aWait( pDocSh->GetActiveDialogParent() );
+ pDoc->RemoveAutoSpellObj(); // Edit-Text-Objekte wieder zurueckwandeln
+ }
+
+ //#92038#; don't set document modified, because this flag is no longer saved
+// pDocSh->SetDocumentModified();
+
+ bRepaint = TRUE; // weil HideAutoSpell evtl. ungueltig
+ //! alle Views painten ???
+ }
+ }
+
+ if ( bOldAutoSpell != bDoAutoSpell )
+ {
+ SetAutoSpellProperty( bDoAutoSpell );
+ bSaveSpellCheck = TRUE;
+ }
+ if ( pDocSh )
+ pDocSh->PostPaintGridAll(); // wegen Markierungen
+ ScInputHandler* pInputHandler = GetInputHdl();
+ if ( pInputHandler )
+ pInputHandler->UpdateSpellSettings(); // EditEngine-Flags
+ if ( pViewSh )
+ pViewSh->UpdateDrawTextOutliner(); // EditEngine-Flags
+
+ if (pBindings)
+ pBindings->Invalidate( SID_AUTOSPELL_CHECK );
+ }
+
+ //============================================
+ // InputOptions
+ //============================================
+
+ if ( IS_AVAILABLE(SID_SC_INPUT_SELECTIONPOS,pItem) )
+ {
+ pInputCfg->SetMoveDir( ((const SfxUInt16Item*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_SELECTION,pItem) )
+ {
+ pInputCfg->SetMoveSelection( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_EDITMODE,pItem) )
+ {
+ pInputCfg->SetEnterEdit( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_FMT_EXPAND,pItem) )
+ {
+ pInputCfg->SetExtendFormat( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_RANGEFINDER,pItem) )
+ {
+ pInputCfg->SetRangeFinder( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_REF_EXPAND,pItem) )
+ {
+ pInputCfg->SetExpandRefs( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_MARK_HEADER,pItem) )
+ {
+ pInputCfg->SetMarkHeader( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ bUpdateMarks = TRUE;
+ }
+ if ( IS_AVAILABLE(SID_SC_INPUT_TEXTWYSIWYG,pItem) )
+ {
+ BOOL bNew = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( bNew != pInputCfg->GetTextWysiwyg() )
+ {
+ pInputCfg->SetTextWysiwyg( bNew );
+ bSaveInputOptions = TRUE;
+ bUpdateRefDev = TRUE;
+ }
+ }
+ if( IS_AVAILABLE( SID_SC_INPUT_REPLCELLSWARN, pItem ) )
+ {
+ pInputCfg->SetReplaceCellsWarn( ((const SfxBoolItem*)pItem)->GetValue() );
+ bSaveInputOptions = TRUE;
+ }
+
+ //============================================
+ // PrintOptions
+ //============================================
+
+ if ( IS_AVAILABLE(SID_SCPRINTOPTIONS,pItem) )
+ {
+ const ScPrintOptions& rNewOpt = ((const ScTpPrintItem*)pItem)->GetPrintOptions();
+ SetPrintOptions( rNewOpt );
+
+ // broadcast causes all previews to recalc page numbers
+ SFX_APP()->Broadcast( SfxSimpleHint( SID_SCPRINTOPTIONS ) );
+ }
+
+ //----------------------------------------------------------
+
+// if ( bSaveSpellCheck )
+// {
+ // currently LinguProperties are saved only at program exit.
+ // if a save method becomes available, it should be called here.
+// }
+
+ if ( bSaveAppOptions )
+ pAppCfg->OptionsChanged();
+
+ if ( bSaveInputOptions )
+ pInputCfg->OptionsChanged();
+
+ // Neuberechnung anstossen?
+
+ if ( pDoc && bCalcAll )
+ {
+ WaitObject aWait( pDocSh->GetActiveDialogParent() );
+ pDoc->CalcAll();
+ if ( pViewSh )
+ pViewSh->UpdateCharts( TRUE );
+ else
+ ScDBFunc::DoUpdateCharts( ScAddress(), pDoc, TRUE );
+ if (pBindings)
+ pBindings->Invalidate( SID_ATTR_SIZE ); //SvxPosSize-StatusControl-Update
+ }
+
+ if ( pViewSh && bUpdateMarks )
+ pViewSh->UpdateAutoFillMark();
+
+ // View neuzeichnen?
+
+ if ( pViewSh && bRepaint )
+ {
+ pViewSh->UpdateFixPos();
+ pViewSh->PaintGrid();
+ pViewSh->PaintTop();
+ pViewSh->PaintLeft();
+ pViewSh->PaintExtras();
+ pViewSh->InvalidateBorder();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_TOGGLEHEADERS ); // -> Checks im Menue
+ pBindings->Invalidate( FID_TOGGLESYNTAX );
+ }
+ }
+
+ // update ref device (for all documents)
+
+ if ( bUpdateRefDev )
+ {
+ // for all documents: recalc output factor, update row heights
+ SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
+ while ( pObjSh )
+ {
+ if ( pObjSh->Type() == TYPE(ScDocShell) )
+ {
+ ScDocShell* pOneDocSh = ((ScDocShell*)pObjSh);
+ pOneDocSh->CalcOutputFactor();
+ SCTAB nTabCount = pOneDocSh->GetDocument()->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ pOneDocSh->AdjustRowHeight( 0, MAXROW, nTab );
+ }
+ pObjSh = SfxObjectShell::GetNext( *pObjSh );
+ }
+
+ // for all (tab-) views:
+ TypeId aScType = TYPE(ScTabViewShell);
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh )
+ {
+ ScTabViewShell* pOneViewSh = (ScTabViewShell*)pSh;
+
+ // set ref-device for EditEngine
+ ScInputHandler* pHdl = GetInputHdl(pOneViewSh);
+ if (pHdl)
+ pHdl->UpdateRefDevice();
+
+ // update view scale
+ ScViewData* pViewData = pOneViewSh->GetViewData();
+ pOneViewSh->SetZoom( pViewData->GetZoomX(), pViewData->GetZoomY(), FALSE );
+
+ // repaint
+ pOneViewSh->PaintGrid();
+ pOneViewSh->PaintTop();
+ pOneViewSh->PaintLeft();
+
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+ }
+}
+
+#undef IS_AVAILABLE
+
+//------------------------------------------------------------------
+//
+// Input-Handler
+//
+//------------------------------------------------------------------
+
+ScInputHandler* ScModule::GetInputHdl( ScTabViewShell* pViewSh, BOOL bUseRef )
+{
+ if ( pRefInputHandler && bUseRef )
+ return pRefInputHandler;
+
+ ScInputHandler* pHdl = NULL;
+ if ( !pViewSh )
+ {
+ // in case a UIActive embedded object has no ViewShell ( UNO component )
+ // the own calc view shell will be set as current, but no handling should happen
+
+ ScTabViewShell* pCurViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ if ( pCurViewSh && !pCurViewSh->GetUIActiveClient() )
+ pViewSh = pCurViewSh;
+ }
+
+ if ( pViewSh )
+ pHdl = pViewSh->GetInputHandler(); // Viewshell hat jetzt immer einen
+
+ // #57989# wenn keine ViewShell uebergeben oder aktiv, kann NULL herauskommen
+ DBG_ASSERT( pHdl || !pViewSh, "GetInputHdl: kein InputHandler gefunden" );
+ return pHdl;
+}
+
+void ScModule::ViewShellChanged()
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ ScTabViewShell* pShell = ScTabViewShell::GetActiveViewShell();
+ if ( pShell && pHdl )
+ pShell->UpdateInputHandler();
+}
+
+void ScModule::SetInputMode( ScInputMode eMode )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->SetMode( eMode );
+}
+
+BOOL ScModule::IsEditMode()
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ return pHdl && pHdl->IsEditMode();
+}
+
+BOOL ScModule::IsInputMode()
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ return pHdl && pHdl->IsInputMode();
+}
+
+BOOL ScModule::InputKeyEvent( const KeyEvent& rKEvt, BOOL bStartEdit )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ return ( pHdl ? pHdl->KeyInput( rKEvt, bStartEdit ) : FALSE );
+}
+
+void ScModule::InputEnterHandler( BYTE nBlockMode )
+{
+ if ( !SFX_APP()->IsDowning() ) // nicht beim Programmende
+ {
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->EnterHandler( nBlockMode );
+ }
+}
+
+void ScModule::InputCancelHandler()
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->CancelHandler();
+}
+
+void ScModule::InputSelection( EditView* pView )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->InputSelection( pView );
+}
+
+void ScModule::InputChanged( EditView* pView )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->InputChanged( pView );
+}
+
+void ScModule::ViewShellGone( ScTabViewShell* pViewSh )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->ViewShellGone( pViewSh );
+}
+
+void ScModule::SetRefInputHdl( ScInputHandler* pNew )
+{
+ pRefInputHandler = pNew;
+}
+
+ScInputHandler* ScModule::GetRefInputHdl()
+{
+ return pRefInputHandler;
+}
+
+//------------------------------------------------------------------------
+// Olk's Krempel:
+
+void ScModule::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->InputGetSelection( rStart, rEnd );
+}
+
+void ScModule::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->InputSetSelection( nStart, nEnd );
+}
+
+void ScModule::InputReplaceSelection( const String& rStr )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->InputReplaceSelection( rStr );
+}
+
+String ScModule::InputGetFormulaStr()
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ String aStr;
+ if ( pHdl )
+ aStr = pHdl->InputGetFormulaStr();
+ return aStr;
+}
+
+void ScModule::ActivateInputWindow( const String* pStrFormula, BOOL bMatrix )
+{
+ ScInputHandler* pHdl = GetInputHdl();
+ if ( pHdl )
+ {
+ ScInputWindow* pWin = pHdl->GetInputWindow();
+ if ( pStrFormula )
+ {
+ // Formel uebernehmen
+ if ( pWin )
+ {
+ pWin->SetFuncString( *pStrFormula, FALSE );
+ // SetSumAssignMode wegen FALSE nicht noetig
+ }
+ BYTE nMode = bMatrix ? SC_ENTER_MATRIX : SC_ENTER_NORMAL;
+ pHdl->EnterHandler( nMode );
+
+ // ohne Invalidate bleibt die Selektion stehen, wenn die Formel unveraendert ist
+ if (pWin)
+ pWin->TextInvalidate();
+ }
+ else
+ {
+ // Abbrechen
+ if ( pWin )
+ {
+ pWin->SetFuncString( EMPTY_STRING, FALSE );
+ // SetSumAssignMode wegen FALSE nicht noetig
+ }
+ pHdl->CancelHandler();
+ }
+ }
+}
+
+//------------------------------------------------------------------
+//
+// Referenz - Dialoge
+//
+//------------------------------------------------------------------
+
+void ScModule::SetRefDialog( USHORT nId, BOOL bVis, SfxViewFrame* pViewFrm )
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ if(nCurRefDlgId==0 || (nId==nCurRefDlgId && !bVis))
+ {
+ if ( !pViewFrm )
+ pViewFrm = SfxViewFrame::Current();
+
+ // #79379# bindings update causes problems with update of stylist if
+ // current style family has changed
+ //if ( pViewFrm )
+ // pViewFrm->GetBindings().Update(); // to avoid trouble in LockDispatcher
+
+ nCurRefDlgId = bVis ? nId : 0 ; // before SetChildWindow
+
+ if ( pViewFrm )
+ {
+ // store the dialog id also in the view shell
+ SfxViewShell* pViewSh = pViewFrm->GetViewShell();
+ if ( pViewSh && pViewSh->ISA( ScTabViewShell ) )
+ ((ScTabViewShell*)pViewSh)->SetCurRefDlgId( nCurRefDlgId );
+ else
+ {
+ // no ScTabViewShell - possible for example from a Basic macro
+ bVis = FALSE;
+ nCurRefDlgId = 0; // don't set nCurRefDlgId if no dialog is created
+ }
+
+ pViewFrm->SetChildWindow( nId, bVis );
+ }
+
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
+ }
+}
+
+SfxChildWindow* lcl_GetChildWinFromAnyView( USHORT nId )
+{
+ // first try the current view
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ // #i46999# current view frame can be null (for example, when closing help)
+ SfxChildWindow* pChildWnd = pViewFrm ? pViewFrm->GetChildWindow( nId ) : NULL;
+ if ( pChildWnd )
+ return pChildWnd; // found in the current view
+
+ // if not found there, get the child window from any open view
+ // it can be open only in one view because nCurRefDlgId is global
+
+ pViewFrm = SfxViewFrame::GetFirst();
+ while ( pViewFrm )
+ {
+ pChildWnd = pViewFrm->GetChildWindow( nId );
+ if ( pChildWnd )
+ return pChildWnd; // found in any view
+
+ pViewFrm = SfxViewFrame::GetNext( *pViewFrm );
+ }
+
+ return NULL; // none found
+}
+
+BOOL ScModule::IsModalMode(SfxObjectShell* pDocSh)
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ BOOL bIsModal = FALSE;
+
+ if ( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ bIsModal = pChildWnd->IsVisible() &&
+ !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) );
+ }
+ else
+ {
+ // in 592 and above, the dialog isn't visible in other views
+ // if the dialog is open but can't be accessed, disable input
+
+ bIsModal = TRUE;
+ }
+
+ // pChildWnd kann 0 sein, wenn der Dialog nach dem Umschalten
+ // von einer anderen Shell noch nicht erzeugt wurde (z.B. in GetFocus)
+ }
+ else if (pDocSh)
+ {
+ ScInputHandler* pHdl = GetInputHdl();
+ if ( pHdl )
+ bIsModal = pHdl->IsModalMode(pDocSh);
+ }
+
+ return bIsModal;
+}
+
+BOOL ScModule::IsTableLocked()
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ BOOL bLocked = FALSE;
+
+ // bisher nur bei ScAnyRefDlg
+
+ if ( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ if ( pChildWnd )
+ bLocked = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow())->IsTableLocked();
+ else
+ bLocked = TRUE; // for other views, see IsModalMode
+ }
+
+ return bLocked;
+}
+
+BOOL ScModule::IsRefDialogOpen()
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ BOOL bIsOpen = FALSE;
+
+ if ( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ if ( pChildWnd )
+ bIsOpen = pChildWnd->IsVisible();
+ else
+ bIsOpen = TRUE; // for other views, see IsModalMode
+ }
+
+ return bIsOpen;
+}
+
+BOOL ScModule::IsFormulaMode()
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ BOOL bIsFormula = FALSE;
+
+ if ( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ bIsFormula = pChildWnd->IsVisible() && pRefDlg->IsRefInputMode();
+ }
+ }
+ else
+ {
+ ScInputHandler* pHdl = GetInputHdl();
+ if ( pHdl )
+ bIsFormula = pHdl->IsFormulaMode();
+ }
+
+ if (bIsInEditCommand)
+ bIsFormula = TRUE;
+
+ return bIsFormula;
+}
+
+void lcl_MarkedTabs( const ScMarkData& rMark, SCTAB& rStartTab, SCTAB& rEndTab )
+{
+ if (rMark.GetSelectCount() > 1)
+ {
+ BOOL bFirst = TRUE;
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (rMark.GetTableSelect(i))
+ {
+ if (bFirst)
+ rStartTab = i;
+ rEndTab = i;
+ bFirst = FALSE;
+ }
+ }
+}
+
+void ScModule::SetReference( const ScRange& rRef, ScDocument* pDoc,
+ const ScMarkData* pMarkData )
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ // in Ref-Dialogen wird hiermit auch das Zoom-In ausgeloest,
+ // wenn Start und Ende der Ref unterschiedlich sind
+
+ ScRange aNew = rRef;
+ aNew.Justify(); // immer "richtig herum"
+
+ if( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ DBG_ASSERT( pChildWnd, "NoChildWin" );
+ if ( pChildWnd )
+ {
+ if ( nCurRefDlgId == SID_OPENDLG_CONSOLIDATE && pMarkData )
+ {
+ SCTAB nStartTab = aNew.aStart.Tab();
+ SCTAB nEndTab = aNew.aEnd.Tab();
+ lcl_MarkedTabs( *pMarkData, nStartTab, nEndTab );
+ aNew.aStart.SetTab(nStartTab);
+ aNew.aEnd.SetTab(nEndTab);
+ }
+
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+
+ // hide the (color) selection now instead of later from LoseFocus,
+ // don't abort the ref input that causes this call (bDoneRefMode = FALSE)
+ pRefDlg->HideReference( FALSE );
+ pRefDlg->SetReference( aNew, pDoc );
+ }
+ }
+ else
+ {
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->SetReference( aNew, pDoc );
+ else
+ {
+ DBG_ERROR("SetReference ohne Empfaenger");
+ }
+ }
+}
+
+void ScModule::AddRefEntry() // "Mehrfachselektion"
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ if ( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ DBG_ASSERT( pChildWnd, "NoChildWin" );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ pRefDlg->AddRefEntry();
+ }
+ }
+ else
+ {
+ ScInputHandler* pHdl = GetInputHdl();
+ if (pHdl)
+ pHdl->AddRefEntry();
+ }
+}
+
+void ScModule::EndReference()
+{
+ //! move reference dialog handling to view
+ //! (only keep function autopilot here for references to other documents)
+
+ // in Ref-Dialogen wird hiermit auch das Zoom-In wieder aufgehoben
+
+ //! ShowRefFrame am InputHdl, wenn der Funktions-AP offen ist ???
+
+ if ( nCurRefDlgId )
+ {
+ SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
+ DBG_ASSERT( pChildWnd, "NoChildWin" );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ pRefDlg->SetActive();
+ }
+ }
+}
+
+//------------------------------------------------------------------
+//
+// Idle / Online-Spelling
+//
+//------------------------------------------------------------------
+
+void ScModule::AnythingChanged()
+{
+ ULONG nOldTime = aIdleTimer.GetTimeout();
+ if ( nOldTime != SC_IDLE_MIN )
+ aIdleTimer.SetTimeout( SC_IDLE_MIN );
+
+ nIdleCount = 0;
+}
+
+void lcl_CheckNeedsRepaint( ScDocShell* pDocShell )
+{
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ while ( pFrame )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
+ if ( pViewSh )
+ pViewSh->CheckNeedsRepaint();
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
+ }
+}
+
+IMPL_LINK( ScModule, IdleHandler, Timer*, EMPTYARG )
+{
+ if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD ) )
+ {
+ aIdleTimer.Start(); // Timeout unveraendert
+ return 0;
+ }
+
+ BOOL bMore = FALSE;
+ ScDocShell* pDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ BOOL bLinks = pDoc->IdleCheckLinks();
+ BOOL bWidth = pDoc->IdleCalcTextWidth();
+ BOOL bSpell = pDoc->ContinueOnlineSpelling();
+ if ( bSpell )
+ aSpellTimer.Start(); // da ist noch was
+
+ bMore = bLinks || bWidth || bSpell; // ueberhaupt noch was?
+
+ // While calculating a Basic formula, a paint event may have occured,
+ // so check the bNeedsRepaint flags for this document's views
+ if (bWidth)
+ lcl_CheckNeedsRepaint( pDocSh );
+ }
+
+ ULONG nOldTime = aIdleTimer.GetTimeout();
+ ULONG nNewTime = nOldTime;
+ if ( bMore )
+ {
+ nNewTime = SC_IDLE_MIN;
+ nIdleCount = 0;
+ }
+ else
+ {
+ // SC_IDLE_COUNT mal mit initialem Timeout, dann hochzaehlen
+
+ if ( nIdleCount < SC_IDLE_COUNT )
+ ++nIdleCount;
+ else
+ {
+ nNewTime += SC_IDLE_STEP;
+ if ( nNewTime > SC_IDLE_MAX )
+ nNewTime = SC_IDLE_MAX;
+ }
+ }
+ if ( nNewTime != nOldTime )
+ aIdleTimer.SetTimeout( nNewTime );
+
+ aIdleTimer.Start();
+ return 0;
+}
+
+IMPL_LINK( ScModule, SpellTimerHdl, Timer*, EMPTYARG )
+{
+ if ( Application::AnyInput( INPUT_KEYBOARD ) )
+ {
+ aSpellTimer.Start();
+ return 0; // dann spaeter wieder...
+ }
+
+ ScDocShell* pDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if ( pDoc->ContinueOnlineSpelling() )
+ aSpellTimer.Start();
+ }
+ return 0;
+}
+
+ //virtuelle Methoden fuer den Optionendialog
+SfxItemSet* ScModule::CreateItemSet( USHORT nId )
+{
+ SfxItemSet* pRet = 0;
+ if(SID_SC_EDITOPTIONS == nId)
+ {
+ pRet = new SfxItemSet( GetPool(),
+ // TP_CALC:
+ SID_SCDOCOPTIONS, SID_SCDOCOPTIONS,
+ // TP_VIEW:
+ SID_SCVIEWOPTIONS, SID_SCVIEWOPTIONS,
+ SID_SC_OPT_SYNCZOOM, SID_SC_OPT_SYNCZOOM,
+ // TP_INPUT:
+ SID_SC_INPUT_SELECTION,SID_SC_INPUT_MARK_HEADER,
+ SID_SC_INPUT_TEXTWYSIWYG,SID_SC_INPUT_TEXTWYSIWYG,
+ SID_SC_INPUT_REPLCELLSWARN,SID_SC_INPUT_REPLCELLSWARN,
+ // TP_USERLISTS:
+ SCITEM_USERLIST, SCITEM_USERLIST,
+ // TP_PRINT:
+ SID_SCPRINTOPTIONS, SID_SCPRINTOPTIONS,
+ // TP_GRID:
+ SID_ATTR_GRID_OPTIONS, SID_ATTR_GRID_OPTIONS,
+ //
+ SID_ATTR_METRIC, SID_ATTR_METRIC,
+ SID_ATTR_DEFTABSTOP, SID_ATTR_DEFTABSTOP,
+ 0 );
+
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell,
+ SfxObjectShell::Current());
+ ScDocOptions aCalcOpt = pDocSh
+ ? pDocSh->GetDocument()->GetDocOptions()
+ : GetDocOptions();
+
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,
+ SfxViewShell::Current());
+ ScViewOptions aViewOpt = pViewSh
+ ? pViewSh->GetViewData()->GetOptions()
+ : GetViewOptions();
+
+ ScUserListItem aULItem( SCITEM_USERLIST );
+ ScUserList* pUL = ScGlobal::GetUserList();
+
+ // SFX_APP()->GetOptions( aSet );
+
+ pRet->Put( SfxUInt16Item( SID_ATTR_METRIC,
+ sal::static_int_cast<UINT16>(GetAppOptions().GetAppMetric()) ) );
+
+ // TP_CALC
+ pRet->Put( SfxUInt16Item( SID_ATTR_DEFTABSTOP,
+ aCalcOpt.GetTabDistance()));
+ pRet->Put( ScTpCalcItem( SID_SCDOCOPTIONS, aCalcOpt ) );
+
+ // TP_VIEW
+ pRet->Put( ScTpViewItem( SID_SCVIEWOPTIONS, aViewOpt ) );
+ pRet->Put( SfxBoolItem( SID_SC_OPT_SYNCZOOM, GetAppOptions().GetSynchronizeZoom() ) );
+
+ // TP_INPUT
+ const ScInputOptions& rInpOpt = GetInputOptions();
+ pRet->Put( SfxUInt16Item( SID_SC_INPUT_SELECTIONPOS,
+ rInpOpt.GetMoveDir() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_SELECTION,
+ rInpOpt.GetMoveSelection() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_EDITMODE,
+ rInpOpt.GetEnterEdit() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_FMT_EXPAND,
+ rInpOpt.GetExtendFormat() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_RANGEFINDER,
+ rInpOpt.GetRangeFinder() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_REF_EXPAND,
+ rInpOpt.GetExpandRefs() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_MARK_HEADER,
+ rInpOpt.GetMarkHeader() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_TEXTWYSIWYG,
+ rInpOpt.GetTextWysiwyg() ) );
+ pRet->Put( SfxBoolItem( SID_SC_INPUT_REPLCELLSWARN,
+ rInpOpt.GetReplaceCellsWarn() ) );
+
+ // RID_SC_TP_PRINT
+ pRet->Put( ScTpPrintItem( SID_SCPRINTOPTIONS, GetPrintOptions() ) );
+
+ // TP_GRID
+ SvxGridItem* pSvxGridItem = aViewOpt.CreateGridItem();
+ pRet->Put( *pSvxGridItem );
+ delete pSvxGridItem;
+
+ // TP_USERLISTS
+ if ( pUL )
+ aULItem.SetUserList( *pUL );
+ pRet->Put( aULItem );
+
+ }
+ return pRet;
+}
+
+void ScModule::ApplyItemSet( USHORT nId, const SfxItemSet& rSet )
+{
+ if(SID_SC_EDITOPTIONS == nId)
+ {
+ ModifyOptions( rSet );
+ }
+}
+
+SfxTabPage* ScModule::CreateTabPage( USHORT nId, Window* pParent, const SfxItemSet& rSet )
+{
+ SfxTabPage* pRet = NULL;
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ switch(nId)
+ {
+ case SID_SC_TP_LAYOUT:
+ {
+ //CHINA001 pRet = ScTpLayoutOptions::Create(pParent, rSet);
+ ::CreateTabPage ScTpLayoutOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_LAYOUT );
+ if ( ScTpLayoutOptionsCreate )
+ pRet = (*ScTpLayoutOptionsCreate) (pParent, rSet);
+ }
+ break;
+ case SID_SC_TP_CONTENT:
+ {
+ //CHINA001 pRet = ScTpContentOptions::Create(pParent, rSet);
+ ::CreateTabPage ScTpContentOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SCPAGE_CONTENT);
+ if ( ScTpContentOptionsCreate )
+ pRet = (*ScTpContentOptionsCreate)(pParent, rSet);
+ }
+ break;
+ case SID_SC_TP_GRID: pRet = SvxGridTabPage::Create(pParent, rSet); break;
+ case SID_SC_TP_USERLISTS:
+ {
+ //CHINA001 pRet = ScTpUserLists::Create(pParent, rSet);
+ ::CreateTabPage ScTpUserListsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_USERLISTS );
+ if ( ScTpUserListsCreate )
+ pRet = (*ScTpUserListsCreate)( pParent, rSet);
+ }
+ break;
+ case SID_SC_TP_CALC:
+ { //CHINA001 pRet = ScTpCalcOptions::Create(pParent, rSet);
+ ::CreateTabPage ScTpCalcOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_CALC );
+ if ( ScTpCalcOptionsCreate )
+ pRet = (*ScTpCalcOptionsCreate)(pParent, rSet);
+ }
+ break;
+ case SID_SC_TP_CHANGES:
+ { //CHINA001 pRet = ScRedlineOptionsTabPage::Create(pParent, rSet);
+ ::CreateTabPage ScRedlineOptionsTabPageCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_OPREDLINE );
+ if ( ScRedlineOptionsTabPageCreate )
+ pRet =(*ScRedlineOptionsTabPageCreate)(pParent, rSet);
+ }
+ break;
+ case RID_SC_TP_PRINT:
+ {//CHINA001 pRet = ScTpPrintOptions::Create(pParent, rSet);
+ ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT );
+ if ( ScTpPrintOptionsCreate )
+ pRet = (*ScTpPrintOptionsCreate)( pParent, rSet);
+ }
+ break;
+ case RID_OFA_TP_INTERNATIONAL:
+ {
+ SfxAbstractDialogFactory* pSfxFact = SfxAbstractDialogFactory::Create();
+ if ( pSfxFact )
+ {
+ ::CreateTabPage fnCreatePage = pSfxFact->GetTabPageCreatorFunc( nId );
+ if ( fnCreatePage )
+ pRet = (*fnCreatePage)( pParent, rSet );
+ }
+ }
+ }
+
+ DBG_ASSERT( pRet, "ScModule::CreateTabPage(): no valid ID for TabPage!" );
+
+ return pRet;
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScModule, CalcFieldValueHdl, EditFieldInfo*, pInfo )
+{
+ //! mit ScFieldEditEngine zusammenfassen !!!
+
+ if (pInfo)
+ {
+ const SvxFieldItem& rField = pInfo->GetField();
+ const SvxFieldData* pField = rField.GetField();
+
+ if (pField && pField->ISA(SvxURLField))
+ {
+ /******************************************************************
+ * URL-Field
+ ******************************************************************/
+
+ const SvxURLField* pURLField = (const SvxURLField*) pField;
+ String aURL = pURLField->GetURL();
+
+ switch ( pURLField->GetFormat() )
+ {
+ case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
+ case SVXURLFORMAT_REPR:
+ {
+ pInfo->SetRepresentation( pURLField->GetRepresentation() );
+ }
+ break;
+
+ case SVXURLFORMAT_URL:
+ {
+ pInfo->SetRepresentation( aURL );
+ }
+ break;
+ }
+
+ svtools::ColorConfigEntry eEntry =
+ INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? svtools::LINKSVISITED : svtools::LINKS;
+ pInfo->SetTxtColor( GetColorConfig().GetColorValue(eEntry).nColor );
+ }
+ else
+ {
+ DBG_ERROR("unbekannter Feldbefehl");
+ pInfo->SetRepresentation(String('?'));
+ }
+ }
+
+ return 0;
+}
+
+BOOL ScModule::RegisterRefWindow( USHORT nSlotId, Window *pWnd )
+{
+ std::list<Window*> & rlRefWindow = m_mapRefWindow[nSlotId];
+
+ if( std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ) == rlRefWindow.end() )
+ {
+ rlRefWindow.push_back( pWnd );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL ScModule::UnregisterRefWindow( USHORT nSlotId, Window *pWnd )
+{
+ std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId );
+
+ if( iSlot == m_mapRefWindow.end() )
+ return FALSE;
+
+ std::list<Window*> & rlRefWindow = iSlot->second;
+
+ std::list<Window*>::iterator i = std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd );
+
+ if( i == rlRefWindow.end() )
+ return FALSE;
+
+ rlRefWindow.erase( i );
+
+ if( !rlRefWindow.size() )
+ m_mapRefWindow.erase( nSlotId );
+
+ return TRUE;
+}
+
+BOOL ScModule::IsAliveRefDlg( USHORT nSlotId, Window *pWnd )
+{
+ std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId );
+
+ if( iSlot == m_mapRefWindow.end() )
+ return FALSE;
+
+ std::list<Window*> & rlRefWindow = iSlot->second;
+
+ return rlRefWindow.end() != std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd );
+}
+
+Window * ScModule::Find1RefWindow( USHORT nSlotId, Window *pWndAncestor )
+{
+ if (!pWndAncestor)
+ return NULL;
+
+ std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId );
+
+ if( iSlot == m_mapRefWindow.end() )
+ return NULL;
+
+ std::list<Window*> & rlRefWindow = iSlot->second;
+
+ while( Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent;
+
+ for( std::list<Window*>::iterator i = rlRefWindow.begin(); i!=rlRefWindow.end(); i++ )
+ if ( pWndAncestor->IsWindowOrChild( *i, (*i)->IsSystemWindow() ) )
+ return *i;
+
+ return NULL;
+}
+
+Window * ScModule::Find1RefWindow( Window *pWndAncestor )
+{
+ if (!pWndAncestor)
+ return NULL;
+
+ while( Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent;
+
+ for( std::map<USHORT, std::list<Window*> >::iterator i = m_mapRefWindow.begin();
+ i!=m_mapRefWindow.end(); i++ )
+ for( std::list<Window*>::iterator j = i->second.begin(); j!=i->second.end(); j++ )
+ if ( pWndAncestor->IsWindowOrChild( *j, (*j)->IsSystemWindow() ) )
+ return *j;
+
+ return NULL;
+}
+
diff --git a/sc/source/ui/app/scmod2.cxx b/sc/source/ui/app/scmod2.cxx
new file mode 100644
index 000000000000..c92f0bf5d206
--- /dev/null
+++ b/sc/source/ui/app/scmod2.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <editeng/unolingu.hxx>
+#include <unotools/lingucfg.hxx>
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+using namespace com::sun::star;
+
+#include "scmod.hxx"
+
+//------------------------------------------------------------------
+
+#define LINGUPROP_AUTOSPELL "IsSpellAuto"
+
+//------------------------------------------------------------------
+
+// static
+void ScModule::GetSpellSettings( USHORT& rDefLang, USHORT& rCjkLang, USHORT& rCtlLang,
+ BOOL& rAutoSpell )
+{
+ // use SvtLinguConfig instead of service LinguProperties to avoid
+ // loading the linguistic component
+ SvtLinguConfig aConfig;
+
+ SvtLinguOptions aOptions;
+ aConfig.GetOptions( aOptions );
+
+ rDefLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage, ::com::sun::star::i18n::ScriptType::LATIN);
+ rCjkLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK, ::com::sun::star::i18n::ScriptType::ASIAN);
+ rCtlLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL, ::com::sun::star::i18n::ScriptType::COMPLEX);
+ rAutoSpell = aOptions.bIsSpellAuto;
+}
+
+// static
+void ScModule::SetAutoSpellProperty( BOOL bSet )
+{
+ // use SvtLinguConfig instead of service LinguProperties to avoid
+ // loading the linguistic component
+ SvtLinguConfig aConfig;
+
+ uno::Any aAny;
+ aAny <<= bSet;
+ aConfig.SetProperty( rtl::OUString::createFromAscii( LINGUPROP_AUTOSPELL ), aAny );
+}
+
+
+
+// static
+BOOL ScModule::HasThesaurusLanguage( USHORT nLang )
+{
+ if ( nLang == LANGUAGE_NONE )
+ return FALSE;
+
+ lang::Locale aLocale;
+ SvxLanguageToLocale( aLocale, nLang );
+
+ BOOL bHasLang = FALSE;
+ try
+ {
+ uno::Reference< linguistic2::XThesaurus > xThes(LinguMgr::GetThesaurus());
+ if ( xThes.is() )
+ bHasLang = xThes->hasLocale( aLocale );
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR("Error in Thesaurus");
+ }
+
+ return bHasLang;
+}
+
+
diff --git a/sc/source/ui/app/seltrans.cxx b/sc/source/ui/app/seltrans.cxx
new file mode 100644
index 000000000000..0b213709863d
--- /dev/null
+++ b/sc/source/ui/app/seltrans.cxx
@@ -0,0 +1,449 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/form/FormButtonType.hpp>
+
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdouno.hxx>
+
+#include "seltrans.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "scmod.hxx"
+#include "dbfunc.hxx" // for CopyToClip
+#include "docsh.hxx"
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+BOOL lcl_IsURLButton( SdrObject* pObject )
+{
+ BOOL bRet = FALSE;
+
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject);
+ if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
+ {
+ uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
+ DBG_ASSERT( xControlModel.is(), "uno control without model" );
+ if ( xControlModel.is() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
+
+ rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" );
+ if(xInfo->hasPropertyByName( sPropButtonType ))
+ {
+ uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
+ form::FormButtonType eTmp;
+ if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
+ bRet = TRUE;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// static
+
+ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView )
+{
+ ScSelectionTransferObj* pRet = NULL;
+
+ if ( pView )
+ {
+ ScSelectionTransferMode eMode = SC_SELTRANS_INVALID;
+
+ SdrView* pSdrView = pView->GetSdrView();
+ if ( pSdrView )
+ {
+ // handle selection on drawing layer
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+ if ( nMarkCount )
+ {
+ if ( nMarkCount == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ UINT16 nSdrObjKind = pObj->GetObjIdentifier();
+
+ if ( nSdrObjKind == OBJ_GRAF )
+ {
+ if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP )
+ eMode = SC_SELTRANS_DRAW_BITMAP;
+ else
+ eMode = SC_SELTRANS_DRAW_GRAPHIC;
+ }
+ else if ( nSdrObjKind == OBJ_OLE2 )
+ eMode = SC_SELTRANS_DRAW_OLE;
+ else if ( lcl_IsURLButton( pObj ) )
+ eMode = SC_SELTRANS_DRAW_BOOKMARK;
+ }
+
+ if ( eMode == SC_SELTRANS_INVALID )
+ eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection
+ }
+ }
+ if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected
+ {
+ ScRange aRange;
+ ScViewData* pViewData = pView->GetViewData();
+ const ScMarkData& rMark = pViewData->GetMarkData();
+ // allow MultiMarked because GetSimpleArea may be able to merge into a simple range
+ // (GetSimpleArea modifies a local copy of MarkData)
+ // Also allow simple filtered area.
+ ScMarkType eMarkType;
+ if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) &&
+ (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) ||
+ (eMarkType == SC_MARK_SIMPLE_FILTERED)) )
+ {
+ // only for "real" selection, cursor alone isn't used
+ if ( aRange.aStart == aRange.aEnd )
+ eMode = SC_SELTRANS_CELL;
+ else
+ eMode = SC_SELTRANS_CELLS;
+ }
+ }
+
+ if ( eMode != SC_SELTRANS_INVALID )
+ pRet = new ScSelectionTransferObj( pView, eMode );
+ }
+
+ return pRet;
+}
+
+
+ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) :
+ pView( pSource ),
+ eMode( eNewMode ),
+ pCellData( NULL ),
+ pDrawData( NULL )
+{
+ //! store range for StillValid
+}
+
+ScSelectionTransferObj::~ScSelectionTransferObj()
+{
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetSelectionTransfer() == this )
+ {
+ // this is reached when the object wasn't really copied to the selection
+ // (CopyToSelection has no effect under Windows)
+
+ ForgetView();
+ pScMod->SetSelectionTransfer( NULL );
+ }
+
+ DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" );
+}
+
+BOOL ScSelectionTransferObj::StillValid()
+{
+ //! check if view still has same cell selection
+ //! (but return FALSE if data has changed inbetween)
+ return FALSE;
+}
+
+void ScSelectionTransferObj::ForgetView()
+{
+ pView = NULL;
+ eMode = SC_SELTRANS_INVALID;
+
+ if (pCellData)
+ {
+ pCellData->release();
+ pCellData = NULL;
+ }
+ if (pDrawData)
+ {
+ pDrawData->release();
+ pDrawData = NULL;
+ }
+}
+
+void ScSelectionTransferObj::AddSupportedFormats()
+{
+ // AddSupportedFormats must work without actually creating the
+ // "real" transfer object
+
+ switch (eMode)
+ {
+ case SC_SELTRANS_CELL:
+ case SC_SELTRANS_CELLS:
+ // same formats as in ScTransferObj::AddSupportedFormats
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ AddFormat( SOT_FORMAT_BITMAP );
+ AddFormat( SOT_FORMATSTR_ID_HTML );
+ AddFormat( SOT_FORMATSTR_ID_SYLK );
+ AddFormat( SOT_FORMATSTR_ID_LINK );
+ AddFormat( SOT_FORMATSTR_ID_DIF );
+ AddFormat( SOT_FORMAT_STRING );
+ AddFormat( SOT_FORMAT_RTF );
+ if ( eMode == SC_SELTRANS_CELL )
+ AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
+ break;
+
+ // different graphic formats as in ScDrawTransferObj::AddSupportedFormats:
+
+ case SC_SELTRANS_DRAW_BITMAP:
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_SVXB );
+ AddFormat( SOT_FORMAT_BITMAP );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ break;
+
+ case SC_SELTRANS_DRAW_GRAPHIC:
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_SVXB );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ AddFormat( SOT_FORMAT_BITMAP );
+ break;
+
+ case SC_SELTRANS_DRAW_BOOKMARK:
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_SOLK );
+ AddFormat( SOT_FORMAT_STRING );
+ AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
+ AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
+ AddFormat( SOT_FORMATSTR_ID_DRAWING );
+ break;
+
+ case SC_SELTRANS_DRAW_OLE:
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ break;
+
+ case SC_SELTRANS_DRAW_OTHER:
+ // other drawing objects
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMATSTR_ID_DRAWING );
+ AddFormat( SOT_FORMAT_BITMAP );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+void ScSelectionTransferObj::CreateCellData()
+{
+ DBG_ASSERT( !pCellData, "CreateCellData twice" );
+ if ( pView )
+ {
+ ScViewData* pViewData = pView->GetViewData();
+ ScMarkData aNewMark( pViewData->GetMarkData() ); // use local copy for MarkToSimple
+ aNewMark.MarkToSimple();
+
+ // similar to ScViewFunctionSet::BeginDrag
+ if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() )
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ ScRange aSelRange;
+ aNewMark.GetMarkArea( aSelRange );
+ ScDocShellRef aDragShellRef;
+ if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) )
+ {
+ aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
+ aDragShellRef->DoInitNew(NULL);
+ }
+ ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
+
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ // bApi = TRUE -> no error mesages
+ // #i18364# bStopEdit = FALSE -> don't end edit mode
+ // (this may be called from pasting into the edit line)
+ BOOL bCopied = pViewData->GetView()->CopyToClip( pClipDoc, FALSE, TRUE, TRUE, FALSE );
+
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ if ( bCopied )
+ {
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ // SetDragHandlePos is not used - there is no mouse position
+ //? pTransferObj->SetVisibleTab( nTab );
+
+ SfxObjectShellRef aPersistRef( aDragShellRef );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+
+ pTransferObj->SetDragSource( pDocSh, aNewMark );
+
+ pCellData = pTransferObj;
+ pCellData->acquire(); // keep ref count up - released in ForgetView
+ }
+ else
+ delete pClipDoc;
+ }
+ }
+ DBG_ASSERT( pCellData, "can't create CellData" );
+}
+
+//! make static member of ScDrawView
+extern void lcl_CheckOle( const SdrMarkList& rMarkList, BOOL& rAnyOle, BOOL& rOneOle );
+
+void ScSelectionTransferObj::CreateDrawData()
+{
+ DBG_ASSERT( !pDrawData, "CreateDrawData twice" );
+ if ( pView )
+ {
+ // similar to ScDrawView::BeginDrag
+
+ ScDrawView* pDrawView = pView->GetScDrawView();
+ if ( pDrawView )
+ {
+ BOOL bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ //---------------------------------------------------------
+ ScDocShellRef aDragShellRef;
+ if (bAnyOle)
+ {
+ aDragShellRef = new ScDocShell; // ohne Ref lebt die DocShell nicht !!!
+ aDragShellRef->DoInitNew(NULL);
+ }
+ //---------------------------------------------------------
+
+ ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
+ SdrModel* pModel = pDrawView->GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ ScViewData* pViewData = pView->GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ SfxObjectShellRef aPersistRef( aDragShellRef );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+ pTransferObj->SetDragSource( pDrawView ); // copies selection
+
+ pDrawData = pTransferObj;
+ pDrawData->acquire(); // keep ref count up - released in ForgetView
+ }
+ }
+ DBG_ASSERT( pDrawData, "can't create DrawData" );
+}
+
+ScTransferObj* ScSelectionTransferObj::GetCellData()
+{
+ if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) )
+ CreateCellData();
+ return pCellData;
+}
+
+ScDrawTransferObj* ScSelectionTransferObj::GetDrawData()
+{
+ if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC ||
+ eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE ||
+ eMode == SC_SELTRANS_DRAW_OTHER ) )
+ CreateDrawData();
+ return pDrawData;
+}
+
+sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ sal_Bool bOK = sal_False;
+
+ uno::Reference<datatransfer::XTransferable> xSource;
+ switch (eMode)
+ {
+ case SC_SELTRANS_CELL:
+ case SC_SELTRANS_CELLS:
+ xSource = GetCellData();
+ break;
+ case SC_SELTRANS_DRAW_BITMAP:
+ case SC_SELTRANS_DRAW_GRAPHIC:
+ case SC_SELTRANS_DRAW_BOOKMARK:
+ case SC_SELTRANS_DRAW_OLE:
+ case SC_SELTRANS_DRAW_OTHER:
+ xSource = GetDrawData();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if ( xSource.is() )
+ {
+ TransferableDataHelper aHelper( xSource );
+ uno::Any aAny = aHelper.GetAny( rFlavor );
+ bOK = SetAny( aAny, rFlavor );
+ }
+
+ return bOK;
+}
+
+void ScSelectionTransferObj::ObjectReleased()
+{
+ // called when another selection is set from outside
+
+ ForgetView();
+
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetSelectionTransfer() == this )
+ pScMod->SetSelectionTransfer( NULL );
+
+ TransferableHelper::ObjectReleased();
+}
+
+
diff --git a/sc/source/ui/app/template.cxx b/sc/source/ui/app/template.cxx
new file mode 100644
index 000000000000..80dc667c5de6
--- /dev/null
+++ b/sc/source/ui/app/template.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "template.hxx"
+
+//------------------------------------------------------------------------
+
+ScTemplateDlg::ScTemplateDlg(Window * pParent, USHORT nAppResource) :
+// SfxTemplateDlg( pParent, nAppResource )
+ SfxTemplateDialog( pParent )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScTemplateDlg::~ScTemplateDlg()
+{
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScTemplateDlg::New(String &rNewName)
+{
+ return TRUE;
+}
+
+
+void ScTemplateDlg::Edit(const String &)
+{
+}
+
+
+BOOL ScTemplateDlg::Delete(const String &)
+{
+ return TRUE;
+}
+
+
+void ScTemplateDlg::InvalidateTemplates()
+{
+}
+
+
+void ScTemplateDlg::ToggleApplyTemplate()
+{
+}
+
+
+
+
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
new file mode 100644
index 000000000000..4b268b9da791
--- /dev/null
+++ b/sc/source/ui/app/transobj.cxx
@@ -0,0 +1,867 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <sot/storage.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <vos/mutex.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+
+#include "transobj.hxx"
+#include "document.hxx"
+#include "viewopti.hxx"
+#include "editutil.hxx"
+#include "impex.hxx"
+#include "cell.hxx"
+#include "printfun.hxx"
+#include "docfunc.hxx"
+#include "scmod.hxx"
+
+// for InitDocShell
+#include <editeng/paperinf.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/algitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include "docsh.hxx"
+#include "markdata.hxx"
+#include "stlpool.hxx"
+#include "viewdata.hxx"
+#include "dociter.hxx"
+#include "cellsuno.hxx"
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define SCTRANS_TYPE_IMPEX 1
+#define SCTRANS_TYPE_EDIT_RTF 2
+#define SCTRANS_TYPE_EDIT_BIN 3
+#define SCTRANS_TYPE_EMBOBJ 4
+
+// -----------------------------------------------------------------------
+
+// static
+void ScTransferObj::GetAreaSize( ScDocument* pDoc, SCTAB nTab1, SCTAB nTab2, SCROW& nRow, SCCOL& nCol )
+{
+ SCCOL nMaxCol = 0;
+ SCROW nMaxRow = 0;
+ for( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
+ {
+ SCCOL nLastCol = 0;
+ SCROW nLastRow = 0;
+ // GetPrintArea instead of GetCellArea - include drawing objects
+ if( pDoc->GetPrintArea( nTab, nLastCol, nLastRow ) )
+ {
+ if( nLastCol > nMaxCol )
+ nMaxCol = nLastCol;
+ if( nLastRow > nMaxRow )
+ nMaxRow = nLastRow;
+ }
+ }
+ nRow = nMaxRow;
+ nCol = nMaxCol;
+}
+
+// static
+void ScTransferObj::PaintToDev( OutputDevice* pDev, ScDocument* pDoc, double nPrintFactor,
+ const ScRange& rBlock, BOOL bMetaFile )
+{
+ if (!pDoc)
+ return;
+
+ Point aPoint;
+ Rectangle aBound( aPoint, pDev->GetOutputSize() ); //! use size from clip area?
+
+ ScViewData aViewData(NULL,NULL);
+ aViewData.InitData( pDoc );
+
+ aViewData.SetTabNo( rBlock.aEnd.Tab() );
+ aViewData.SetScreen( rBlock.aStart.Col(), rBlock.aStart.Row(),
+ rBlock.aEnd.Col(), rBlock.aEnd.Row() );
+
+ ScPrintFunc::DrawToDev( pDoc, pDev, nPrintFactor, aBound, &aViewData, bMetaFile );
+}
+
+// -----------------------------------------------------------------------
+
+ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDescriptor& rDesc ) :
+ pDoc( pClipDoc ),
+ aObjDesc( rDesc ),
+ nDragHandleX( 0 ),
+ nDragHandleY( 0 ),
+ nDragSourceFlags( 0 ),
+ bDragWasInternal( FALSE ),
+ bUsedForLink( FALSE )
+{
+ DBG_ASSERT(pDoc->IsClipboard(), "wrong document");
+
+ //
+ // get aBlock from clipboard doc
+ //
+
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ pDoc->GetClipStart( nCol1, nRow1 );
+ pDoc->GetClipArea( nCol2, nRow2, TRUE ); // real source area - include filtered rows
+ nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nCol1 );
+ nRow2 = sal::static_int_cast<SCROW>( nRow2 + nRow1 );
+
+ SCCOL nDummy;
+ pDoc->GetClipArea( nDummy, nNonFiltered, FALSE );
+ bHasFiltered = (nNonFiltered < (nRow2 - nRow1));
+ ++nNonFiltered; // to get count instead of diff
+
+ SCTAB nTab1=0;
+ SCTAB nTab2=0;
+ BOOL bFirst = TRUE;
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pDoc->HasTable(i))
+ {
+ if (bFirst)
+ nTab1 = i;
+ nTab2 = i;
+ bFirst = FALSE;
+ }
+ DBG_ASSERT(!bFirst, "no sheet selected");
+
+ // only limit to used cells if whole sheet was marked
+ // (so empty cell areas can be copied)
+ if ( nCol2>=MAXCOL && nRow2>=MAXROW )
+ {
+ SCROW nMaxRow;
+ SCCOL nMaxCol;
+ GetAreaSize( pDoc, nTab1, nTab2, nMaxRow, nMaxCol );
+ if( nMaxRow < nRow2 )
+ nRow2 = nMaxRow;
+ if( nMaxCol < nCol2 )
+ nCol2 = nMaxCol;
+ }
+
+ aBlock = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ nVisibleTab = nTab1; // valid table as default
+
+ Rectangle aMMRect = pDoc->GetMMRect( nCol1,nRow1, nCol2,nRow2, nTab1 );
+ aObjDesc.maSize = aMMRect.GetSize();
+ PrepareOLE( aObjDesc );
+}
+
+ScTransferObj::~ScTransferObj()
+{
+ Application::GetSolarMutex().acquire();
+
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetClipData().pCellClipboard == this )
+ {
+ DBG_ERROR("ScTransferObj wasn't released");
+ pScMod->SetClipObject( NULL, NULL );
+ }
+ if ( pScMod->GetDragData().pCellTransfer == this )
+ {
+ DBG_ERROR("ScTransferObj wasn't released");
+ pScMod->ResetDragObject();
+ }
+
+ delete pDoc; // ScTransferObj is owner of clipboard document
+
+ aDocShellRef.Clear(); // before releasing the mutex
+
+ aDrawPersistRef.Clear(); // after the model
+
+ Application::GetSolarMutex().release();
+}
+
+// static
+ScTransferObj* ScTransferObj::GetOwnClipboard( Window* pUIWin )
+{
+ ScTransferObj* pObj = SC_MOD()->GetClipData().pCellClipboard;
+ if ( pObj && pUIWin )
+ {
+ // check formats to see if pObj is really in the system clipboard
+
+ // pUIWin is NULL when called from core (IsClipboardSource),
+ // in that case don't access the system clipboard, because the call
+ // may be from other clipboard operations (like flushing, #86059#)
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin ) );
+ if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_DIF ) )
+ {
+// DBG_ERROR("ScTransferObj wasn't released");
+ pObj = NULL;
+ }
+ }
+ return pObj;
+}
+
+void ScTransferObj::AddSupportedFormats()
+{
+ AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
+ AddFormat( SOT_FORMAT_GDIMETAFILE );
+ AddFormat( SOT_FORMAT_BITMAP );
+
+ // ScImportExport formats
+ AddFormat( SOT_FORMATSTR_ID_HTML );
+ AddFormat( SOT_FORMATSTR_ID_SYLK );
+ AddFormat( SOT_FORMATSTR_ID_LINK );
+ AddFormat( SOT_FORMATSTR_ID_DIF );
+ AddFormat( SOT_FORMAT_STRING );
+
+ AddFormat( SOT_FORMAT_RTF );
+ if ( aBlock.aStart == aBlock.aEnd )
+ AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
+}
+
+sal_Bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor )
+{
+ sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
+ sal_Bool bOK = sal_False;
+
+ if( HasFormat( nFormat ) )
+ {
+ if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
+ {
+ bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
+ }
+ else if ( ( nFormat == SOT_FORMAT_RTF || nFormat == SOT_FORMATSTR_ID_EDITENGINE ) &&
+ aBlock.aStart == aBlock.aEnd )
+ {
+ // RTF from a single cell is handled by EditEngine
+
+ SCCOL nCol = aBlock.aStart.Col();
+ SCROW nRow = aBlock.aStart.Row();
+ SCTAB nTab = aBlock.aStart.Tab();
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ ScTabEditEngine aEngine( *pPattern, pDoc->GetEditPool() );
+ ScBaseCell* pCell = NULL;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pObj;
+ ((ScEditCell*)pCell)->GetData(pObj);
+ aEngine.SetText( *pObj );
+ }
+ else
+ {
+ String aText;
+ pDoc->GetString( nCol, nRow, nTab, aText );
+ aEngine.SetText(aText);
+ }
+ }
+
+ bOK = SetObject( &aEngine,
+ (nFormat == FORMAT_RTF) ? SCTRANS_TYPE_EDIT_RTF : SCTRANS_TYPE_EDIT_BIN,
+ rFlavor );
+ }
+ else if ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SOT_FORMAT_RTF )
+ {
+ // if this transfer object was used to create a DDE link, filtered rows
+ // have to be included for subsequent calls (to be consistent with link data)
+ if ( nFormat == SOT_FORMATSTR_ID_LINK )
+ bUsedForLink = TRUE;
+
+ BOOL bIncludeFiltered = pDoc->IsCutMode() || bUsedForLink;
+
+ ScImportExport aObj( pDoc, aBlock );
+ if ( bUsedForLink )
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
+ aObj.SetFormulas( pDoc->GetViewOptions().GetOption( VOPT_FORMULAS ) );
+ aObj.SetIncludeFiltered( bIncludeFiltered );
+
+ // DataType depends on format type:
+
+ if ( rFlavor.DataType.equals( ::getCppuType( (const ::rtl::OUString*) 0 ) ) )
+ {
+ rtl::OUString aString;
+ if ( aObj.ExportString( aString, nFormat ) )
+ bOK = SetString( aString, rFlavor );
+ }
+ else if ( rFlavor.DataType.equals( ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) ) )
+ {
+ // SetObject converts a stream into a Int8-Sequence
+ bOK = SetObject( &aObj, SCTRANS_TYPE_IMPEX, rFlavor );
+ }
+ else
+ {
+ DBG_ERROR("unknown DataType");
+ }
+ }
+ else if ( nFormat == SOT_FORMAT_BITMAP )
+ {
+ Rectangle aMMRect = pDoc->GetMMRect( aBlock.aStart.Col(), aBlock.aStart.Row(),
+ aBlock.aEnd.Col(), aBlock.aEnd.Row(),
+ aBlock.aStart.Tab() );
+ VirtualDevice aVirtDev;
+ aVirtDev.SetOutputSizePixel( aVirtDev.LogicToPixel( aMMRect.GetSize(), MAP_100TH_MM ) );
+
+ PaintToDev( &aVirtDev, pDoc, 1.0, aBlock, FALSE );
+
+ aVirtDev.SetMapMode( MapMode( MAP_PIXEL ) );
+ Bitmap aBmp = aVirtDev.GetBitmap( Point(), aVirtDev.GetOutputSize() );
+ bOK = SetBitmap( aBmp, rFlavor );
+ }
+ else if ( nFormat == SOT_FORMAT_GDIMETAFILE )
+ {
+ InitDocShell();
+ SfxObjectShell* pEmbObj = aDocShellRef;
+
+ // like SvEmbeddedTransfer::GetData:
+
+ GDIMetaFile aMtf;
+ VirtualDevice aVDev;
+ MapMode aMapMode( pEmbObj->GetMapUnit() );
+ Rectangle aVisArea( pEmbObj->GetVisArea( ASPECT_CONTENT ) );
+
+ aVDev.EnableOutput( FALSE );
+ aVDev.SetMapMode( aMapMode );
+ aMtf.SetPrefSize( aVisArea.GetSize() );
+ aMtf.SetPrefMapMode( aMapMode );
+ aMtf.Record( &aVDev );
+
+ pEmbObj->DoDraw( &aVDev, Point(), aVisArea.GetSize(), JobSetup(), ASPECT_CONTENT );
+
+ aMtf.Stop();
+ aMtf.WindStart();
+
+ bOK = SetGDIMetaFile( aMtf, rFlavor );
+ }
+ else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ {
+ //TODO/LATER: differentiate between formats?!
+ InitDocShell(); // set aDocShellRef
+
+ SfxObjectShell* pEmbObj = aDocShellRef;
+ bOK = SetObject( pEmbObj, SCTRANS_TYPE_EMBOBJ, rFlavor );
+ }
+ }
+ return bOK;
+}
+
+sal_Bool ScTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
+ const datatransfer::DataFlavor& rFlavor )
+{
+ // called from SetObject, put data into stream
+
+ sal_Bool bRet = sal_False;
+ switch (nUserObjectId)
+ {
+ case SCTRANS_TYPE_IMPEX:
+ {
+ ScImportExport* pImpEx = (ScImportExport*)pUserObject;
+
+ sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
+ // mba: no BaseURL for data exchange
+ if ( pImpEx->ExportStream( *rxOStm, String(), nFormat ) )
+ bRet = ( rxOStm->GetError() == ERRCODE_NONE );
+ }
+ break;
+
+ case SCTRANS_TYPE_EDIT_RTF:
+ case SCTRANS_TYPE_EDIT_BIN:
+ {
+ ScTabEditEngine* pEngine = (ScTabEditEngine*)pUserObject;
+ if ( nUserObjectId == SCTRANS_TYPE_EDIT_RTF )
+ {
+ pEngine->Write( *rxOStm, EE_FORMAT_RTF );
+ bRet = ( rxOStm->GetError() == ERRCODE_NONE );
+ }
+ else
+ {
+ // #107722# can't use Write for EditEngine format because that would
+ // write old format without support for unicode characters.
+ // Get the data from the EditEngine's transferable instead.
+
+ USHORT nParCnt = pEngine->GetParagraphCount();
+ if ( nParCnt == 0 )
+ nParCnt = 1;
+ ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
+
+ uno::Reference<datatransfer::XTransferable> xEditTrans = pEngine->CreateTransferable( aSel );
+ TransferableDataHelper aEditHelper( xEditTrans );
+
+ bRet = aEditHelper.GetSotStorageStream( rFlavor, rxOStm );
+ }
+ }
+ break;
+
+ case SCTRANS_TYPE_EMBOBJ:
+ {
+ // TODO/MBA: testing
+ SfxObjectShell* pEmbObj = (SfxObjectShell*) pUserObject;
+ ::utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ uno::Reference< embed::XStorage > xWorkStore =
+ ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
+
+ // write document storage
+ pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False );
+
+ // mba: no relative ULRs for clipboard!
+ SfxMedium aMedium( xWorkStore, String() );
+ bRet = pEmbObj->DoSaveObjectAs( aMedium, FALSE );
+ pEmbObj->DoSaveCompleted();
+
+ uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ xTransact->commit();
+
+ SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
+ if( pSrcStm )
+ {
+ rxOStm->SetBufferSize( 0xff00 );
+ *rxOStm << *pSrcStm;
+ delete pSrcStm;
+ }
+
+ bRet = TRUE;
+
+ xWorkStore->dispose();
+ xWorkStore = uno::Reference < embed::XStorage >();
+ rxOStm->Commit();
+ }
+ break;
+
+ default:
+ DBG_ERROR("unknown object id");
+ }
+ return bRet;
+}
+
+void ScTransferObj::ObjectReleased()
+{
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetClipData().pCellClipboard == this )
+ pScMod->SetClipObject( NULL, NULL );
+
+ TransferableHelper::ObjectReleased();
+}
+
+void ScTransferObj::DragFinished( sal_Int8 nDropAction )
+{
+ if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
+ {
+ // move: delete source data
+ ScDocShell* pSourceSh = GetSourceDocShell();
+ if (pSourceSh)
+ {
+ ScMarkData aMarkData = GetSourceMarkData();
+ // external drag&drop doesn't copy objects, so they also aren't deleted:
+ // #105703# bApi=TRUE, don't show error messages from drag&drop
+ pSourceSh->GetDocFunc().DeleteContents( aMarkData, IDF_ALL & ~IDF_OBJECTS, TRUE, TRUE );
+ }
+ }
+
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod->GetDragData().pCellTransfer == this )
+ pScMod->ResetDragObject();
+
+ xDragSourceRanges = NULL; // don't keep source after dropping
+
+ TransferableHelper::DragFinished( nDropAction );
+}
+
+void ScTransferObj::SetDragHandlePos( SCCOL nX, SCROW nY )
+{
+ nDragHandleX = nX;
+ nDragHandleY = nY;
+}
+
+void ScTransferObj::SetVisibleTab( SCTAB nNew )
+{
+ nVisibleTab = nNew;
+}
+
+void ScTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
+{
+ aDrawPersistRef = rRef;
+}
+
+void ScTransferObj::SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark )
+{
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, FALSE );
+ xDragSourceRanges = new ScCellRangesObj( pSourceShell, aRanges );
+}
+
+void ScTransferObj::SetDragSourceFlags( USHORT nFlags )
+{
+ nDragSourceFlags = nFlags;
+}
+
+void ScTransferObj::SetDragWasInternal()
+{
+ bDragWasInternal = TRUE;
+}
+
+ScDocument* ScTransferObj::GetSourceDocument()
+{
+ ScDocShell* pSourceDocSh = GetSourceDocShell();
+ if (pSourceDocSh)
+ return pSourceDocSh->GetDocument();
+ return NULL;
+}
+
+ScDocShell* ScTransferObj::GetSourceDocShell()
+{
+ ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
+ if (pRangesObj)
+ return pRangesObj->GetDocShell();
+
+ return NULL; // none set
+}
+
+ScMarkData ScTransferObj::GetSourceMarkData()
+{
+ ScMarkData aMarkData;
+ ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
+ if (pRangesObj)
+ {
+ const ScRangeList& rRanges = pRangesObj->GetRangeList();
+ aMarkData.MarkFromRangeList( rRanges, FALSE );
+ }
+ return aMarkData;
+}
+
+//
+// initialize aDocShellRef with a live document from the ClipDoc
+//
+
+void ScTransferObj::InitDocShell()
+{
+ if ( !aDocShellRef.Is() )
+ {
+ ScDocShell* pDocSh = new ScDocShell;
+ aDocShellRef = pDocSh; // ref must be there before InitNew
+
+ pDocSh->DoInitNew(NULL);
+
+ ScDocument* pDestDoc = pDocSh->GetDocument();
+ ScMarkData aDestMark;
+ aDestMark.SelectTable( 0, TRUE );
+
+ pDestDoc->SetDocOptions( pDoc->GetDocOptions() ); // #i42666#
+
+ String aTabName;
+ pDoc->GetName( aBlock.aStart.Tab(), aTabName );
+ pDestDoc->RenameTab( 0, aTabName, FALSE ); // no UpdateRef (empty)
+
+ pDestDoc->CopyStdStylesFrom( pDoc );
+
+ SCCOL nStartX = aBlock.aStart.Col();
+ SCROW nStartY = aBlock.aStart.Row();
+ SCCOL nEndX = aBlock.aEnd.Col();
+ SCROW nEndY = aBlock.aEnd.Row();
+
+ // widths / heights
+ // (must be copied before CopyFromClip, for drawing objects)
+
+ SCCOL nCol, nLastCol;
+ SCTAB nSrcTab = aBlock.aStart.Tab();
+ pDestDoc->SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab));
+ for (nCol=nStartX; nCol<=nEndX; nCol++)
+ if ( pDoc->ColHidden(nCol, nSrcTab, nLastCol) )
+ pDestDoc->ShowCol( nCol, 0, FALSE );
+ else
+ pDestDoc->SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) );
+
+ ScBitMaskCompressedArray< SCROW, BYTE> & rDestRowFlags =
+ pDestDoc->GetRowFlagsArrayModifiable(0);
+
+ for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow)
+ {
+ BYTE nSourceFlags = pDoc->GetRowFlags(nRow, nSrcTab);
+ SCROW nLastRow = -1;
+ if ( pDoc->RowHidden(nRow, nSrcTab, nLastRow) )
+ pDestDoc->ShowRow( nRow, 0, FALSE );
+ else
+ {
+ pDestDoc->SetRowHeight( nRow, 0, pDoc->GetOriginalHeight( nRow, nSrcTab ) );
+
+ // if height was set manually, that flag has to be copied, too
+ if ( nSourceFlags & CR_MANUALSIZE )
+ rDestRowFlags.OrValue( nRow, CR_MANUALSIZE);
+ }
+ }
+
+ if ( pDoc->GetDrawLayer() )
+ pDocSh->MakeDrawLayer();
+
+ // cell range is copied to the original position, but on the first sheet
+ // -> bCutMode must be set
+ // pDoc is always a Clipboard-document
+
+ ScRange aDestRange( nStartX,nStartY,0, nEndX,nEndY,0 );
+ BOOL bWasCut = pDoc->IsCutMode();
+ if (!bWasCut)
+ pDoc->SetClipArea( aDestRange, TRUE ); // Cut
+ pDestDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL, NULL, pDoc, FALSE );
+ pDoc->SetClipArea( aDestRange, bWasCut );
+
+ StripRefs( pDoc, nStartX,nStartY, nEndX,nEndY, pDestDoc, 0,0 );
+
+ ScRange aMergeRange = aDestRange;
+ pDestDoc->ExtendMerge( aMergeRange, TRUE );
+
+ pDoc->CopyDdeLinks( pDestDoc ); // copy values of DDE Links
+
+ // page format (grid etc) and page size (maximum size for ole object)
+
+ 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 );
+ if (pStyleSheet)
+ {
+ const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet();
+ aPaperSize = ((const SvxSizeItem&) rSourceSet.Get(ATTR_PAGE_SIZE)).GetSize();
+
+ // CopyStyleFrom kopiert SetItems mit richtigem Pool
+ ScStyleSheetPool* pDestPool = pDestDoc->GetStyleSheetPool();
+ pDestPool->CopyStyleFrom( pStylePool, aStyleName, SFX_STYLE_FAMILY_PAGE );
+ }
+
+ ScViewData aViewData( pDocSh, NULL );
+ aViewData.SetScreen( nStartX,nStartY, nEndX,nEndY );
+ aViewData.SetCurX( nStartX );
+ aViewData.SetCurY( nStartY );
+
+ pDestDoc->SetViewOptions( pDoc->GetViewOptions() );
+
+ // Size
+ //! get while copying sizes
+
+ long nPosX = 0;
+ long nPosY = 0;
+
+ for (nCol=0; nCol<nStartX; nCol++)
+ nPosX += pDestDoc->GetColWidth( nCol, 0 );
+ nPosY += pDestDoc->GetRowHeight( 0, nStartY-1, 0 );
+ nPosX = (long) ( nPosX * HMM_PER_TWIPS );
+ nPosY = (long) ( nPosY * HMM_PER_TWIPS );
+
+
+ aPaperSize.Width() *= 2; // limit OLE object to double of page size
+ aPaperSize.Height() *= 2;
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ for (nCol=nStartX; nCol<=nEndX; nCol++)
+ {
+ long nAdd = pDestDoc->GetColWidth( nCol, 0 );
+ if ( nSizeX+nAdd > aPaperSize.Width() && nSizeX ) // above limit?
+ break;
+ nSizeX += nAdd;
+ }
+ for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
+ {
+ long nAdd = pDestDoc->GetRowHeight( nRow, 0 );
+ if ( nSizeY+nAdd > aPaperSize.Height() && nSizeY ) // above limit?
+ break;
+ nSizeY += nAdd;
+ }
+ nSizeX = (long) ( nSizeX * HMM_PER_TWIPS );
+ nSizeY = (long) ( nSizeY * HMM_PER_TWIPS );
+
+// pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) );
+
+ Rectangle aNewArea( Point(nPosX,nPosY), Size(nSizeX,nSizeY) );
+ //TODO/LATER: why twice?!
+ //pDocSh->SvInPlaceObject::SetVisArea( aNewArea );
+ pDocSh->SetVisArea( aNewArea );
+
+ pDocSh->UpdateOle(&aViewData, TRUE);
+
+ //! SetDocumentModified?
+ if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
+ pDestDoc->UpdateChartListenerCollection();
+ }
+}
+
+// static
+SfxObjectShell* ScTransferObj::SetDrawClipDoc( BOOL bAnyOle )
+{
+ // update ScGlobal::pDrawClipDocShellRef
+
+ delete ScGlobal::pDrawClipDocShellRef;
+ if (bAnyOle)
+ {
+ ScGlobal::pDrawClipDocShellRef =
+ new ScDocShellRef(new ScDocShell(SFX_CREATE_MODE_INTERNAL)); // there must be a ref
+ (*ScGlobal::pDrawClipDocShellRef)->DoInitNew(NULL);
+ return *ScGlobal::pDrawClipDocShellRef;
+ }
+ else
+ {
+ ScGlobal::pDrawClipDocShellRef = NULL;
+ return NULL;
+ }
+}
+
+// static
+void ScTransferObj::StripRefs( ScDocument* pDoc,
+ SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
+ ScDocument* pDestDoc, SCCOL nSubX, SCROW nSubY )
+{
+ if (!pDestDoc)
+ {
+ pDestDoc = pDoc;
+ DBG_ASSERT(nSubX==0&&nSubY==0, "can't move within the document");
+ }
+
+ // In a clipboard doc the data don't have to be on the first sheet
+
+ SCTAB nSrcTab = 0;
+ while (nSrcTab<MAXTAB && !pDoc->HasTable(nSrcTab))
+ ++nSrcTab;
+ SCTAB nDestTab = 0;
+ while (nDestTab<MAXTAB && !pDestDoc->HasTable(nDestTab))
+ ++nDestTab;
+
+ if (!pDoc->HasTable(nSrcTab) || !pDestDoc->HasTable(nDestTab))
+ {
+ DBG_ERROR("Sheet not found in ScTransferObj::StripRefs");
+ return;
+ }
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ ScRange aRef;
+
+ ScCellIterator aIter( pDoc, nStartX, nStartY, nSrcTab, nEndX, nEndY, nSrcTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ BOOL bOut = FALSE;
+ ScDetectiveRefIter aRefIter( pFCell );
+ while ( !bOut && aRefIter.GetNextRef( aRef ) )
+ {
+ if ( aRef.aStart.Tab() != nSrcTab || aRef.aEnd.Tab() != nSrcTab ||
+ aRef.aStart.Col() < nStartX || aRef.aEnd.Col() > nEndX ||
+ aRef.aStart.Row() < nStartY || aRef.aEnd.Row() > nEndY )
+ bOut = TRUE;
+ }
+ if (bOut)
+ {
+ SCCOL nCol = aIter.GetCol() - nSubX;
+ SCROW nRow = aIter.GetRow() - nSubY;
+
+ ScBaseCell* pNew = 0;
+ USHORT nErrCode = pFCell->GetErrCode();
+ if (nErrCode)
+ {
+ pNew = new ScStringCell( ScGlobal::GetErrorString(nErrCode) );
+ if ( ((const SvxHorJustifyItem*) pDestDoc->GetAttr(
+ nCol,nRow,nDestTab, ATTR_HOR_JUSTIFY))->GetValue() ==
+ SVX_HOR_JUSTIFY_STANDARD )
+ pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
+ SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY) );
+ }
+ else if (pFCell->IsValue())
+ {
+ double fVal = pFCell->GetValue();
+ pNew = new ScValueCell( fVal );
+ }
+ else
+ {
+ String aStr;
+ pFCell->GetString(aStr);
+ if ( pFCell->IsMultilineResult() )
+ pNew = new ScEditCell( aStr, pDestDoc );
+ else
+ pNew = new ScStringCell( aStr );
+ }
+ pDestDoc->PutCell( nCol,nRow,nDestTab, pNew );
+
+ // number formats
+
+ ULONG nOldFormat = ((const SfxUInt32Item*)
+ pDestDoc->GetAttr(nCol,nRow,nDestTab, ATTR_VALUE_FORMAT))->GetValue();
+ if ( (nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ {
+ ULONG nNewFormat = pFCell->GetStandardFormat( *pFormatter,
+ nOldFormat );
+ pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
+ SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat) );
+ }
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+}
+
+const com::sun::star::uno::Sequence< sal_Int8 >& ScTransferObj::getUnoTunnelId()
+{
+ static com::sun::star::uno::Sequence< sal_Int8 > aSeq;
+ if( !aSeq.getLength() )
+ {
+ static osl::Mutex aCreateMutex;
+ osl::Guard< osl::Mutex > aGuard( aCreateMutex );
+ aSeq.realloc( 16 );
+ rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
+ }
+ return aSeq;
+}
+
+sal_Int64 SAL_CALL ScTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException )
+{
+ sal_Int64 nRet;
+ if( ( rId.getLength() == 16 ) &&
+ ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
+ {
+ nRet = reinterpret_cast< sal_Int64 >( this );
+ }
+ else
+ nRet = TransferableHelper::getSomething(rId);
+ return nRet;
+}
+
+
diff --git a/sc/source/ui/app/typemap.cxx b/sc/source/ui/app/typemap.cxx
new file mode 100644
index 000000000000..4450c00db807
--- /dev/null
+++ b/sc/source/ui/app/typemap.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <svx/svxids.hrc>
+#include "sc.hrc"
+#include "scitems.hxx"
+#include <editeng/memberids.hrc>
+
+
+#define ITEMID_DBTYPE 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#include <sfx2/msg.hxx>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <sfx2/objitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/postattr.hxx>
+#include <editeng/postitem.hxx>
+#include <sfx2/tplpitem.hxx>
+#include <svx/zoomitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <svl/ptitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/algitem.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xtextit0.hxx>
+#include <svx/xftadit.hxx>
+#include <svx/xftdiit.hxx>
+#include <svx/xftstit.hxx>
+#include <svx/xftmrit.hxx>
+#include <svx/xftouit.hxx>
+#include <svx/xftshit.hxx>
+#include <svx/xftshcit.hxx>
+#include <svx/xftshxy.hxx>
+#include <svx/xftsfit.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/grafctrl.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <svx/drawitem.hxx>
+#include <svl/ilstitem.hxx>
+#include <svl/globalnameitem.hxx>
+#include <svx/chrtitem.hxx>
+#include <svx/zoomslideritem.hxx>
+
+// #i25616#
+#include <svx/sdshitm.hxx>
+
+#include <svl/aeitem.hxx>
+#include <avmedia/mediaitem.hxx>
+#include "attrib.hxx"
+
+#define SvxDrawToolItem SfxAllEnumItem
+#define SvxDrawAlignItem SfxAllEnumItem
+#define SvxChooseControlItem SfxEnumItem
+#define avmedia_MediaItem ::avmedia::MediaItem
+
+#define SFX_TYPEMAP
+#include "scslots.hxx"
diff --git a/sc/source/ui/app/uiitems.cxx b/sc/source/ui/app/uiitems.cxx
new file mode 100644
index 000000000000..a63491f0929b
--- /dev/null
+++ b/sc/source/ui/app/uiitems.cxx
@@ -0,0 +1,737 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/editobj.hxx>
+
+#include "userlist.hxx"
+#include "uiitems.hxx"
+#include "dpsave.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScInputStatusItem, SfxPoolItem);
+TYPEINIT1(ScSortItem, SfxPoolItem);
+TYPEINIT1(ScQueryItem, SfxPoolItem);
+TYPEINIT1(ScSubTotalItem, SfxPoolItem);
+TYPEINIT1(ScUserListItem, SfxPoolItem);
+TYPEINIT1(ScConsolidateItem, SfxPoolItem);
+TYPEINIT1(ScPivotItem, SfxPoolItem);
+TYPEINIT1(ScSolveItem, SfxPoolItem);
+TYPEINIT1(ScTabOpItem, SfxPoolItem);
+TYPEINIT1(ScCondFrmtItem, SfxPoolItem);
+
+TYPEINIT1(ScTablesHint, SfxHint);
+TYPEINIT1(ScEditViewHint, SfxHint);
+TYPEINIT1(ScIndexHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScInputStatusItem - Status-Update fuer Eingabezeile
+// -----------------------------------------------------------------------
+
+//UNUSED2008-05 ScInputStatusItem::ScInputStatusItem( USHORT nWhichP,
+//UNUSED2008-05 SCTAB nTab,
+//UNUSED2008-05 SCCOL nCol, SCROW nRow,
+//UNUSED2008-05 SCCOL nStartCol, SCROW nStartRow,
+//UNUSED2008-05 SCCOL nEndCol, SCROW nEndRow,
+//UNUSED2008-05 const String& rString, const EditTextObject* pData )
+//UNUSED2008-05
+//UNUSED2008-05 : SfxPoolItem ( nWhichP ),
+//UNUSED2008-05 aCursorPos ( nCol, nRow, nTab ),
+//UNUSED2008-05 aStartPos ( nStartCol, nStartRow, nTab ),
+//UNUSED2008-05 aEndPos ( nEndCol, nEndRow, nTab ),
+//UNUSED2008-05 aString ( rString ),
+//UNUSED2008-05 pEditData ( pData ? pData->Clone() : NULL )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScInputStatusItem::ScInputStatusItem( USHORT nWhichP,
+ const ScAddress& rCurPos,
+ const ScAddress& rStartPos,
+ const ScAddress& rEndPos,
+ const String& rString,
+ const EditTextObject* pData )
+ : SfxPoolItem ( nWhichP ),
+ aCursorPos ( rCurPos ),
+ aStartPos ( rStartPos ),
+ aEndPos ( rEndPos ),
+ aString ( rString ),
+ pEditData ( pData ? pData->Clone() : NULL )
+{
+}
+
+ScInputStatusItem::ScInputStatusItem( const ScInputStatusItem& rItem )
+ : SfxPoolItem ( rItem ),
+ aCursorPos ( rItem.aCursorPos ),
+ aStartPos ( rItem.aStartPos ),
+ aEndPos ( rItem.aEndPos ),
+ aString ( rItem.aString ),
+ pEditData ( rItem.pEditData ? rItem.pEditData->Clone() : NULL )
+{
+}
+
+__EXPORT ScInputStatusItem::~ScInputStatusItem()
+{
+ delete pEditData;
+}
+
+String __EXPORT ScInputStatusItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("InputStatus"));
+}
+
+int __EXPORT ScInputStatusItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ return ( (aStartPos == ((ScInputStatusItem&)rItem).aStartPos)
+ && (aEndPos == ((ScInputStatusItem&)rItem).aEndPos)
+ && (aCursorPos == ((ScInputStatusItem&)rItem).aCursorPos)
+ && (aString == ((ScInputStatusItem&)rItem).aString) );
+ //! Edit-Daten vergleichen!
+}
+
+SfxPoolItem* __EXPORT ScInputStatusItem::Clone( SfxItemPool * ) const
+{
+ return new ScInputStatusItem( *this );
+}
+
+//
+// ScPaintHint ist nach schints.cxx verschoben
+//
+
+// -----------------------------------------------------------------------
+// ScTablesHint - Views anpassen, wenn Tabellen eingefuegt / geloescht
+// -----------------------------------------------------------------------
+
+ScTablesHint::ScTablesHint(USHORT nNewId, SCTAB nTable1, SCTAB nTable2) :
+ nId( nNewId ),
+ nTab1( nTable1 ),
+ nTab2( nTable2 )
+{
+}
+
+ScTablesHint::~ScTablesHint()
+{
+}
+
+
+// -----------------------------------------------------------------------
+// ScIndexHint
+// -----------------------------------------------------------------------
+
+ScIndexHint::ScIndexHint(USHORT nNewId, USHORT nIdx) :
+ nId( nNewId ),
+ nIndex( nIdx )
+{
+}
+
+ScIndexHint::~ScIndexHint()
+{
+}
+
+
+// -----------------------------------------------------------------------
+// ScEditViewHint - neue EditView fuer Cursorposition anlegen
+// -----------------------------------------------------------------------
+
+ScEditViewHint::ScEditViewHint( ScEditEngineDefaulter* pEngine, const ScAddress& rCurPos ) :
+ pEditEngine( pEngine ),
+ aCursorPos( rCurPos )
+{
+}
+
+ScEditViewHint::~ScEditViewHint()
+{
+}
+
+// -----------------------------------------------------------------------
+// ScSortItem - Daten fuer den Sortierdialog
+// -----------------------------------------------------------------------
+
+ScSortItem::ScSortItem( USHORT nWhichP,
+ ScViewData* ptrViewData,
+ const ScSortParam* pSortData ) :
+ SfxPoolItem ( nWhichP ),
+ pViewData ( ptrViewData )
+{
+ if ( pSortData ) theSortData = *pSortData;
+}
+
+//------------------------------------------------------------------------
+
+ScSortItem::ScSortItem( USHORT nWhichP,
+ const ScSortParam* pSortData ) :
+ SfxPoolItem ( nWhichP ),
+ pViewData ( NULL )
+{
+ if ( pSortData ) theSortData = *pSortData;
+}
+
+//------------------------------------------------------------------------
+
+ScSortItem::ScSortItem( const ScSortItem& rItem ) :
+ SfxPoolItem ( rItem ),
+ pViewData ( rItem.pViewData ),
+ theSortData ( rItem.theSortData )
+{
+}
+
+__EXPORT ScSortItem::~ScSortItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScSortItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("SortItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScSortItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScSortItem& rOther = (const ScSortItem&)rItem;
+
+ return ( (pViewData == rOther.pViewData)
+ && (theSortData == rOther.theSortData) );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScSortItem::Clone( SfxItemPool * ) const
+{
+ return new ScSortItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool ScSortItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /* nMemberUd */ ) const
+{
+ // Return empty value as there is no useful conversion
+ rVal = com::sun::star::uno::Any();
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+// ScQueryItem - Daten fuer den Filterdialog
+// -----------------------------------------------------------------------
+
+ScQueryItem::ScQueryItem( USHORT nWhichP,
+ ScViewData* ptrViewData,
+ const ScQueryParam* pQueryData ) :
+ SfxPoolItem ( nWhichP ),
+ pViewData ( ptrViewData ),
+ bIsAdvanced ( FALSE )
+{
+ if ( pQueryData ) theQueryData = *pQueryData;
+}
+
+//------------------------------------------------------------------------
+
+ScQueryItem::ScQueryItem( USHORT nWhichP,
+ const ScQueryParam* pQueryData ) :
+ SfxPoolItem ( nWhichP ),
+ pViewData ( NULL ),
+ bIsAdvanced ( FALSE )
+{
+ if ( pQueryData ) theQueryData = *pQueryData;
+}
+
+//------------------------------------------------------------------------
+
+ScQueryItem::ScQueryItem( const ScQueryItem& rItem ) :
+ SfxPoolItem ( rItem ),
+ pViewData ( rItem.pViewData ),
+ theQueryData( rItem.theQueryData ),
+ bIsAdvanced ( rItem.bIsAdvanced ),
+ aAdvSource ( rItem.aAdvSource )
+{
+}
+
+__EXPORT ScQueryItem::~ScQueryItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScQueryItem::SetAdvancedQuerySource(const ScRange* pSource)
+{
+ if (pSource)
+ {
+ aAdvSource = *pSource;
+ bIsAdvanced = TRUE;
+ }
+ else
+ bIsAdvanced = FALSE;
+}
+
+BOOL ScQueryItem::GetAdvancedQuerySource(ScRange& rSource) const
+{
+ rSource = aAdvSource;
+ return bIsAdvanced;
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScQueryItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("QueryItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScQueryItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScQueryItem& rQueryItem = (const ScQueryItem&)rItem;
+
+ return ( (pViewData == rQueryItem.pViewData)
+ && (bIsAdvanced == rQueryItem.bIsAdvanced)
+ && (aAdvSource == rQueryItem.aAdvSource)
+ && (theQueryData == rQueryItem.theQueryData) );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScQueryItem::Clone( SfxItemPool * ) const
+{
+ return new ScQueryItem( *this );
+}
+
+// -----------------------------------------------------------------------
+// ScSubTotalItem - Daten fuer den Zwischenergebnisdialog
+// -----------------------------------------------------------------------
+
+ScSubTotalItem::ScSubTotalItem( USHORT nWhichP,
+ ScViewData* ptrViewData,
+ const ScSubTotalParam* pSubTotalData ) :
+ SfxPoolItem ( nWhichP ),
+ pViewData ( ptrViewData )
+{
+ if ( pSubTotalData ) theSubTotalData = *pSubTotalData;
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalItem::ScSubTotalItem( USHORT nWhichP,
+ const ScSubTotalParam* pSubTotalData ) :
+ SfxPoolItem ( nWhichP ),
+ pViewData ( NULL )
+{
+ if ( pSubTotalData ) theSubTotalData = *pSubTotalData;
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalItem::ScSubTotalItem( const ScSubTotalItem& rItem ) :
+ SfxPoolItem ( rItem ),
+ pViewData ( rItem.pViewData ),
+ theSubTotalData ( rItem.theSubTotalData )
+{
+}
+
+__EXPORT ScSubTotalItem::~ScSubTotalItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScSubTotalItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("SubTotalItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScSubTotalItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScSubTotalItem& rSTItem = (const ScSubTotalItem&)rItem;
+
+ return ( (pViewData == rSTItem.pViewData)
+ && (theSubTotalData == rSTItem.theSubTotalData) );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScSubTotalItem::Clone( SfxItemPool * ) const
+{
+ return new ScSubTotalItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool ScSubTotalItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /* nMemberUd */ ) const
+{
+ // Return empty value as there is no useful conversion
+ rVal = com::sun::star::uno::Any();
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+// ScUserListItem - Transporter fuer den Benutzerlisten-TabPage
+// -----------------------------------------------------------------------
+
+ScUserListItem::ScUserListItem( USHORT nWhichP )
+ : SfxPoolItem ( nWhichP ),
+ pUserList ( NULL )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScUserListItem::ScUserListItem( const ScUserListItem& rItem )
+ : SfxPoolItem ( rItem )
+{
+ if ( rItem.pUserList )
+ pUserList = new ScUserList( *(rItem.pUserList) );
+ else
+ pUserList = NULL;
+}
+
+__EXPORT ScUserListItem::~ScUserListItem()
+{
+ delete pUserList;
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScUserListItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScUserListItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScUserListItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScUserListItem& r = (const ScUserListItem&)rItem;
+ BOOL bEqual = FALSE;
+
+ if ( !pUserList || !(r.pUserList) )
+ bEqual = ( !pUserList && !(r.pUserList) );
+ else
+ bEqual = ( *pUserList == *(r.pUserList) );
+
+ return bEqual;
+}
+
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScUserListItem::Clone( SfxItemPool * ) const
+{
+ return new ScUserListItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+void ScUserListItem::SetUserList( const ScUserList& rUserList )
+{
+ delete pUserList;
+ pUserList = new ScUserList( rUserList );
+}
+
+// -----------------------------------------------------------------------
+// ScConsolidateItem - Daten fuer den Konsolidieren-Dialog
+// -----------------------------------------------------------------------
+
+ScConsolidateItem::ScConsolidateItem(
+ USHORT nWhichP,
+ const ScConsolidateParam* pConsolidateData ) :
+ SfxPoolItem ( nWhichP )
+{
+ if ( pConsolidateData ) theConsData = *pConsolidateData;
+}
+
+//------------------------------------------------------------------------
+
+ScConsolidateItem::ScConsolidateItem( const ScConsolidateItem& rItem ) :
+ SfxPoolItem ( rItem ),
+ theConsData ( rItem.theConsData )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScConsolidateItem::~ScConsolidateItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScConsolidateItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScConsolidateItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScConsolidateItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScConsolidateItem& rCItem = (const ScConsolidateItem&)rItem;
+
+ return ( theConsData == rCItem.theConsData);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScConsolidateItem::Clone( SfxItemPool * ) const
+{
+ return new ScConsolidateItem( *this );
+}
+
+
+// -----------------------------------------------------------------------
+// ScPivotItem - Daten fuer den Pivot-Dialog
+// -----------------------------------------------------------------------
+
+ScPivotItem::ScPivotItem( USHORT nWhichP, const ScDPSaveData* pData,
+ const ScRange* pRange, BOOL bNew ) :
+ SfxPoolItem ( nWhichP )
+{
+ // pSaveData must always exist
+ if ( pData )
+ pSaveData = new ScDPSaveData(*pData);
+ else
+ pSaveData = new ScDPSaveData;
+ if ( pRange ) aDestRange = *pRange;
+ bNewSheet = bNew;
+}
+
+//------------------------------------------------------------------------
+
+ScPivotItem::ScPivotItem( const ScPivotItem& rItem ) :
+ SfxPoolItem ( rItem ),
+ aDestRange ( rItem.aDestRange ),
+ bNewSheet ( rItem.bNewSheet )
+{
+ DBG_ASSERT(rItem.pSaveData, "pSaveData");
+ pSaveData = new ScDPSaveData(*rItem.pSaveData);
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScPivotItem::~ScPivotItem()
+{
+ delete pSaveData;
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScPivotItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScPivotItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScPivotItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScPivotItem& rPItem = (const ScPivotItem&)rItem;
+ DBG_ASSERT( pSaveData && rPItem.pSaveData, "pSaveData" );
+ return ( *pSaveData == *rPItem.pSaveData &&
+ aDestRange == rPItem.aDestRange &&
+ bNewSheet == rPItem.bNewSheet );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScPivotItem::Clone( SfxItemPool * ) const
+{
+ return new ScPivotItem( *this );
+}
+
+
+// -----------------------------------------------------------------------
+// ScSolveItem - Daten fuer den Solver-Dialog
+// -----------------------------------------------------------------------
+
+ScSolveItem::ScSolveItem( USHORT nWhichP,
+ const ScSolveParam* pSolveData )
+ : SfxPoolItem ( nWhichP )
+{
+ if ( pSolveData ) theSolveData = *pSolveData;
+}
+
+//------------------------------------------------------------------------
+
+ScSolveItem::ScSolveItem( const ScSolveItem& rItem )
+ : SfxPoolItem ( rItem ),
+ theSolveData ( rItem.theSolveData )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScSolveItem::~ScSolveItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScSolveItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScSolveItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScSolveItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScSolveItem& rPItem = (const ScSolveItem&)rItem;
+
+ return ( theSolveData == rPItem.theSolveData );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScSolveItem::Clone( SfxItemPool * ) const
+{
+ return new ScSolveItem( *this );
+}
+
+// -----------------------------------------------------------------------
+// ScTabOpItem - Daten fuer den TabOp-Dialog
+// -----------------------------------------------------------------------
+
+ScTabOpItem::ScTabOpItem( USHORT nWhichP,
+ const ScTabOpParam* pTabOpData )
+ : SfxPoolItem ( nWhichP )
+{
+ if ( pTabOpData ) theTabOpData = *pTabOpData;
+}
+
+//------------------------------------------------------------------------
+
+ScTabOpItem::ScTabOpItem( const ScTabOpItem& rItem )
+ : SfxPoolItem ( rItem ),
+ theTabOpData ( rItem.theTabOpData )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScTabOpItem::~ScTabOpItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScTabOpItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScTabOpItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScTabOpItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScTabOpItem& rPItem = (const ScTabOpItem&)rItem;
+
+ return ( theTabOpData == rPItem.theTabOpData );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScTabOpItem::Clone( SfxItemPool * ) const
+{
+ return new ScTabOpItem( *this );
+}
+
+
+// -----------------------------------------------------------------------
+// ScCondFrmtItem - Daten fuer den Dialog bedingte Formatierung
+// -----------------------------------------------------------------------
+
+ScCondFrmtItem::ScCondFrmtItem( USHORT nWhichP,
+//! const ScConditionalFormat* pCondFrmt )
+ const ScConditionalFormat& rCondFrmt )
+ : SfxPoolItem ( nWhichP ),
+ theCondFrmtData ( rCondFrmt ) //!
+{
+//! if ( pCondFrmt ) theCondFrmtData = *pCondFrmt;
+}
+
+//------------------------------------------------------------------------
+
+ScCondFrmtItem::ScCondFrmtItem( const ScCondFrmtItem& rItem )
+ : SfxPoolItem ( rItem ),
+ theCondFrmtData ( rItem.theCondFrmtData )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScCondFrmtItem::~ScCondFrmtItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScCondFrmtItem::GetValueText() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScCondFrmtItem"));
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScCondFrmtItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" );
+
+ const ScCondFrmtItem& rPItem = (const ScCondFrmtItem&)rItem;
+
+ return ( theCondFrmtData == rPItem.theCondFrmtData );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT ScCondFrmtItem::Clone( SfxItemPool * ) const
+{
+ return new ScCondFrmtItem( *this );
+}
diff --git a/sc/source/ui/app/wtcdummy.cxx b/sc/source/ui/app/wtcdummy.cxx
new file mode 100644
index 000000000000..a755830cbd71
--- /dev/null
+++ b/sc/source/ui/app/wtcdummy.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <tlgen.hxx>
+
+class SdbColumns
+{
+ public:
+ SdbColumns();
+ ~SdbColumns();
+};
+
+SdbColumns::SdbColumns()
+{
+ DBG_ERROR("WATCOM Hack failed !");
+}
+
+SdbColumns::~SdbColumns()
+{
+ DBG_ERROR("WATCOM Hack failed !");
+}
+
+class SdbRow
+{
+ public:
+ SdbRow();
+ ~SdbRow();
+};
+
+SdbRow::SdbRow()
+{
+ DBG_ERROR("WATCOM Hack failed !");
+}
+
+SdbRow::~SdbRow()
+{
+ DBG_ERROR("WATCOM Hack failed !");
+}
diff --git a/sc/source/ui/attrdlg/attrdlg.cxx b/sc/source/ui/attrdlg/attrdlg.cxx
new file mode 100644
index 000000000000..ca62ebb887a5
--- /dev/null
+++ b/sc/source/ui/attrdlg/attrdlg.cxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "scitems.hxx"
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/tabdlg.hxx>
+//CHINA001 #include <svx/align.hxx>
+//CHINA001 #include <svx/backgrnd.hxx>
+//CHINA001 #include <svx/border.hxx>
+//CHINA001 #include <svx/chardlg.hxx>
+//CHINA001 #include <svx/numfmt.hxx>
+//CHINA001 #include <svx/paragrph.hxx>
+#include <svl/cjkoptions.hxx>
+
+#include "tabpages.hxx"
+#include "attrdlg.hxx"
+#include "scresid.hxx"
+#include "attrdlg.hrc"
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+#include <svx/flagsdef.hxx> //CHINA001
+#include <editeng/flstitem.hxx> //CHINA001
+#include <sfx2/app.hxx> //CHINA001
+
+#if !LAYOUT_SFX_TABDIALOG_BROKEN
+#include <layout/layout-pre.hxx>
+#endif
+
+//==================================================================
+
+ScAttrDlg::ScAttrDlg( SfxViewFrame* pFrameP,
+ Window* pParent,
+ const SfxItemSet* pCellAttrs )
+
+ : SfxTabDialog( pFrameP,
+ pParent,
+ ScResId( RID_SCDLG_ATTR ),
+ pCellAttrs )
+{
+ SvtCJKOptions aCJKOptions;
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "Dialogdiet fail!");//CHINA001
+
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT ), "GetTabPageCreatorFunc fail!");//CHINA001
+#if LAYOUT_SFX_TABDIALOG_BROKEN
+ AddTabPage( TP_NUMBER, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT ), 0 ); //CHINA001 AddTabPage( TP_NUMBER, SvxNumberFormatTabPage::Create, 0 );
+#else
+ String number = rtl::OUString::createFromAscii ("Numbers");
+ AddTabPage( TP_NUMBER, number, pFact->GetTabPageCreatorFunc (RID_SVXPAGE_NUMBERFORMAT), 0, FALSE, TAB_APPEND);
+#endif
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), "GetTabPageCreatorFunc fail!");//CHINA001
+ AddTabPage( TP_FONT, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), 0 ); //CHINA001 AddTabPage( TP_FONT, SvxCharNamePage::Create, 0 );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), "GetTabPageCreatorFunc fail!");//CHINA001
+ AddTabPage( TP_FONTEFF, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), 0 ); //CHINA001 AddTabPage( TP_FONTEFF, SvxCharEffectsPage::Create, 0 );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGNMENT ), "GetTabPageCreatorFunc fail!");//CHINA001
+ AddTabPage( TP_ALIGNMENT, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGNMENT ), 0 ); //CHINA001 AddTabPage( TP_ALIGNMENT, SvxAlignmentTabPage::Create, 0 );
+
+ if ( aCJKOptions.IsAsianTypographyEnabled() )
+ {
+ //CHINA001 AddTabPage( TP_ASIAN, SvxAsianTabPage::Create, 0 );
+// ::CreateTabPage pCreateTabpage = pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN);
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN), "GetTabPageCreatorFunc fail!");//CHINA001
+ AddTabPage( TP_ASIAN, pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN), 0 );
+ }
+ else
+ RemoveTabPage( TP_ASIAN );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), "GetTabPageCreatorFunc fail!");//CHINA001
+ AddTabPage( TP_BORDER, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), 0 ); //CHINA001 AddTabPage( TP_BORDER, SvxBorderTabPage::Create, 0 );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BACKGROUND ), "GetTabPageCreatorFunc fail!");//CHINA001
+ AddTabPage( TP_BACKGROUND, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BACKGROUND ), 0 ); //CHINA001 AddTabPage( TP_BACKGROUND, SvxBackgroundTabPage::Create, 0 );
+ AddTabPage( TP_PROTECTION, ScTabPageProtection::Create, 0 );
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScAttrDlg::~ScAttrDlg()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScAttrDlg::PageCreated( USHORT nPageId, SfxTabPage& rTabPage )
+{
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); //CHINA001
+ switch ( nPageId )
+ {
+ case TP_NUMBER:
+ {
+ //CHINA001 SvxNumberFormatTabPage& rNumPage = (SvxNumberFormatTabPage&)rTabPage;
+
+ //CHINA001 rNumPage.SetOkHdl( LINK( this, ScAttrDlg, OkHandler ) );
+ aSet.Put (SfxLinkItem( SID_LINK_TYPE, LINK( this, ScAttrDlg, OkHandler )));
+ rTabPage.PageCreated(aSet);
+ }
+ break;
+
+ case TP_FONT:
+ {
+ const SfxPoolItem* pInfoItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
+
+ DBG_ASSERT( pInfoItem, "FontListItem not found :-(" );
+
+ //CHINA001 ((SvxCharNamePage&)rTabPage).
+ //CHINA001 SetFontList( *((const SvxFontListItem*)pInfoItem) );
+ aSet.Put (SvxFontListItem(((const SvxFontListItem*)pInfoItem)->GetFontList(), SID_ATTR_CHAR_FONTLIST ));
+ rTabPage.PageCreated(aSet);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScAttrDlg, OkHandler, void*, EMPTYARG )
+{
+ ((Link&)GetOKButton().GetClickHdl()).Call( NULL );
+
+ return 0;
+}
+
+
diff --git a/sc/source/ui/attrdlg/condfrmt.cxx b/sc/source/ui/attrdlg/condfrmt.cxx
new file mode 100644
index 000000000000..5e3b23af8afa
--- /dev/null
+++ b/sc/source/ui/attrdlg/condfrmt.cxx
@@ -0,0 +1,829 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <sfx2/dispatch.hxx>
+#include <svl/stritem.hxx>
+
+#include "tabvwsh.hxx"
+#include "reffact.hxx"
+#include "conditio.hxx"
+#include "stlpool.hxx"
+#include "uiitems.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+
+#include "condfrmt.hrc"
+#include "globstr.hrc"
+
+#define _CONDFRMT_CXX
+#include "condfrmt.hxx"
+#undef _CONDFRMT_CXX
+
+
+//============================================================================
+// class ScConditionalFormat
+
+//----------------------------------------------------------------------------
+// Konstruktor
+
+ScConditionalFormatDlg::ScConditionalFormatDlg(
+ SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocument* pCurDoc,
+ const ScConditionalFormat* pCurrentFormat )
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_CONDFORMAT ),
+
+ aCbxCond1 ( this, ScResId( CBX_COND1 ) ),
+ aLbCond11 ( this, ScResId( LB_COND1_1 ) ),
+ aLbCond12 ( this, ScResId( LB_COND1_2 ) ),
+ aEdtCond11 ( this, this, ScResId( EDT_COND1_1 ) ),
+ aRbCond11 ( this, ScResId( RB_COND1_1 ), &aEdtCond11,this ),
+ aFtCond1And ( this, ScResId( FT_COND1_AND ) ),
+ aEdtCond12 ( this, this, ScResId( EDT_COND1_2 ) ),
+ aRbCond12 ( this, ScResId( RB_COND1_2 ), &aEdtCond12,this ),
+ aFtCond1Template ( this, ScResId( FT_COND1_TEMPLATE ) ),
+ aLbCond1Template ( this, ScResId( LB_COND1_TEMPLATE ) ),
+ aBtnNew1 ( this, ScResId( BTN_COND1_NEW ) ),
+ aFlSep1 ( this, ScResId( FL_SEP1 ) ),
+
+ aCbxCond2 ( this, ScResId( CBX_COND2 ) ),
+ aLbCond21 ( this, ScResId( LB_COND2_1 ) ),
+ aLbCond22 ( this, ScResId( LB_COND2_2 ) ),
+ aEdtCond21 ( this, this, ScResId( EDT_COND2_1 ) ),
+ aRbCond21 ( this, ScResId( RB_COND2_1 ), &aEdtCond21,this ),
+ aFtCond2And ( this, ScResId( FT_COND2_AND ) ),
+ aEdtCond22 ( this, this, ScResId( EDT_COND2_2 ) ),
+ aRbCond22 ( this, ScResId( RB_COND2_2 ), &aEdtCond22,this ),
+ aFtCond2Template ( this, ScResId( FT_COND2_TEMPLATE ) ),
+ aLbCond2Template ( this, ScResId( LB_COND2_TEMPLATE ) ),
+ aBtnNew2 ( this, ScResId( BTN_COND2_NEW ) ),
+ aFlSep2 ( this, ScResId( FL_SEP2 ) ),
+
+ aCbxCond3 ( this, ScResId( CBX_COND3 ) ),
+ aLbCond31 ( this, ScResId( LB_COND3_1 ) ),
+ aLbCond32 ( this, ScResId( LB_COND3_2 ) ),
+ aEdtCond31 ( this, this, ScResId( EDT_COND3_1 ) ),
+ aRbCond31 ( this, ScResId( RB_COND3_1 ), &aEdtCond31,this ),
+ aFtCond3And ( this, ScResId( FT_COND3_AND ) ),
+ aEdtCond32 ( this, this, ScResId( EDT_COND3_2 ) ),
+ aRbCond32 ( this, ScResId( RB_COND3_2 ), &aEdtCond32,this ),
+ aFtCond3Template ( this, ScResId( FT_COND3_TEMPLATE ) ),
+ aLbCond3Template ( this, ScResId( LB_COND3_TEMPLATE ) ),
+ aBtnNew3 ( this, ScResId( BTN_COND3_NEW ) ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ pEdActive ( NULL ),
+ bDlgLostFocus ( FALSE ),
+
+ pDoc ( pCurDoc )
+{
+ Point aPos;
+ String aName;
+ SfxStyleSheetBase* pStyle;
+
+ FreeResource();
+
+ // Handler setzen
+ aCbxCond1.SetClickHdl ( LINK( this, ScConditionalFormatDlg, ClickCond1Hdl ) );
+ aLbCond11.SetSelectHdl( LINK( this, ScConditionalFormatDlg, ChangeCond11Hdl ) );
+ aLbCond12.SetSelectHdl( LINK( this, ScConditionalFormatDlg, ChangeCond12Hdl ) );
+
+ aCbxCond2.SetClickHdl ( LINK( this, ScConditionalFormatDlg, ClickCond2Hdl ) );
+ aLbCond21.SetSelectHdl( LINK( this, ScConditionalFormatDlg, ChangeCond21Hdl ) );
+ aLbCond22.SetSelectHdl( LINK( this, ScConditionalFormatDlg, ChangeCond22Hdl ) );
+
+ aCbxCond3.SetClickHdl ( LINK( this, ScConditionalFormatDlg, ClickCond3Hdl ) );
+ aLbCond31.SetSelectHdl( LINK( this, ScConditionalFormatDlg, ChangeCond31Hdl ) );
+ aLbCond32.SetSelectHdl( LINK( this, ScConditionalFormatDlg, ChangeCond32Hdl ) );
+
+ aBtnOk.SetClickHdl ( LINK( this, ScConditionalFormatDlg, BtnHdl ) );
+//? aBtnCancel.SetClickHdl( LINK( this, ScConditionalFormatDlg, BtnHdl ) );
+
+ Link aLink = LINK( this, ScConditionalFormatDlg, NewBtnHdl );
+ aBtnNew1.SetClickHdl( aLink );
+ aBtnNew2.SetClickHdl( aLink );
+ aBtnNew3.SetClickHdl( aLink );
+
+ aLink = LINK( this, ScConditionalFormatDlg, GetFocusHdl );
+ aEdtCond11.SetGetFocusHdl( aLink );
+ aEdtCond12.SetGetFocusHdl( aLink );
+ aEdtCond21.SetGetFocusHdl( aLink );
+ aEdtCond22.SetGetFocusHdl( aLink );
+ aEdtCond31.SetGetFocusHdl( aLink );
+ aEdtCond32.SetGetFocusHdl( aLink );
+ aRbCond11.SetGetFocusHdl( aLink );
+ aRbCond12.SetGetFocusHdl( aLink );
+ aRbCond21.SetGetFocusHdl( aLink );
+ aRbCond22.SetGetFocusHdl( aLink );
+ aRbCond31.SetGetFocusHdl( aLink );
+ aRbCond32.SetGetFocusHdl( aLink );
+
+ aLink = LINK( this, ScConditionalFormatDlg, LoseFocusHdl );
+ aEdtCond11.SetLoseFocusHdl( aLink );
+ aEdtCond12.SetLoseFocusHdl( aLink );
+ aEdtCond21.SetLoseFocusHdl( aLink );
+ aEdtCond22.SetLoseFocusHdl( aLink );
+ aEdtCond31.SetLoseFocusHdl( aLink );
+ aEdtCond32.SetLoseFocusHdl( aLink );
+ aRbCond11.SetLoseFocusHdl( aLink );
+ aRbCond12.SetLoseFocusHdl( aLink );
+ aRbCond21.SetLoseFocusHdl( aLink );
+ aRbCond22.SetLoseFocusHdl( aLink );
+ aRbCond31.SetLoseFocusHdl( aLink );
+ aRbCond32.SetLoseFocusHdl( aLink );
+
+ // Condition 1
+ aCond1Pos1 = aLbCond12.GetPosPixel(); // Position Edit ohne Listbox
+ aCond1Pos2 = aEdtCond11.GetPosPixel(); // Position Edit mit Listbox
+ aRBtn1Pos1 = aRbCond11.GetPosPixel();
+ aRBtn1Pos2 = aRbCond12.GetPosPixel();
+ aPos = aEdtCond12.GetPosPixel();
+ aPos.X() += aEdtCond12.GetSizePixel().Width(); // rechter Rand
+ aCond1Size3 = aEdtCond11.GetSizePixel();
+ aCond1Size2 = Size( aPos.X() - aCond1Pos2.X(), aCond1Size3.Height() );
+ aCond1Size1 = Size( aPos.X() - aCond1Pos1.X(), aCond1Size3.Height() );
+
+ aCbxCond1.Check();
+ aLbCond11.SelectEntryPos( 0 );
+ aLbCond12.SelectEntryPos( 0 );
+
+ // Condition 2
+ aCond2Pos1 = aLbCond22.GetPosPixel(); // Position Edit ohne Listbox
+ aCond2Pos2 = aEdtCond21.GetPosPixel(); // Position Edit mit Listbox
+ aRBtn2Pos1 = aRbCond21.GetPosPixel();
+ aRBtn2Pos2 = aRbCond22.GetPosPixel();
+ aPos = aEdtCond22.GetPosPixel();
+ aPos.X() += aEdtCond22.GetSizePixel().Width(); // rechter Rand
+ aCond2Size3 = aEdtCond21.GetSizePixel();
+ aCond2Size2 = Size( aPos.X() - aCond2Pos2.X(), aCond2Size3.Height() );
+ aCond2Size1 = Size( aPos.X() - aCond2Pos1.X(), aCond2Size3.Height() );
+
+ aCbxCond2.Check( FALSE );
+ aLbCond21.SelectEntryPos( 0 );
+ aLbCond22.SelectEntryPos( 0 );
+
+ // Condition 3
+ aCond3Pos1 = aLbCond32.GetPosPixel(); // Position Edit ohne Listbox
+ aCond3Pos2 = aEdtCond31.GetPosPixel(); // Position Edit mit Listbox
+ aRBtn3Pos1 = aRbCond31.GetPosPixel();
+ aRBtn3Pos2 = aRbCond32.GetPosPixel();
+ aPos = aEdtCond32.GetPosPixel();
+ aPos.X() += aEdtCond32.GetSizePixel().Width(); // rechter Rand
+ aCond3Size3 = aEdtCond31.GetSizePixel();
+ aCond3Size2 = Size( aPos.X() - aCond3Pos2.X(), aCond3Size3.Height() );
+ aCond3Size1 = Size( aPos.X() - aCond3Pos1.X(), aCond3Size3.Height() );
+
+ aCbxCond3.Check( FALSE );
+ aLbCond31.SelectEntryPos( 0 );
+ aLbCond32.SelectEntryPos( 0 );
+
+ // Vorlagen aus pDoc holen
+ SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
+ for ( pStyle = aStyleIter.First(); pStyle; pStyle = aStyleIter.Next() )
+ {
+ aName = pStyle->GetName();
+ aLbCond1Template.InsertEntry( aName );
+ aLbCond2Template.InsertEntry( aName );
+ aLbCond3Template.InsertEntry( aName );
+ }
+
+ // Vorlagen eintragen
+//! pStyle = pDoc->GetSelectionStyle( /* ??? const ScMarkData& rMark ??? */ );
+ pStyle = NULL; //!
+ if (pStyle)
+ aName = pStyle->GetName();
+ else
+ aName = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
+ aLbCond1Template.SelectEntry( aName );
+ aLbCond2Template.SelectEntry( aName );
+ aLbCond3Template.SelectEntry( aName );
+
+ ScAddress aCurPos;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ ScViewData* pData = pViewShell->GetViewData();
+ aCurPos = ScAddress( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+ }
+
+ // Inhalt aus ConditionalFormat holen
+ if ( pCurrentFormat )
+ {
+ const ScCondFormatEntry* pEntry;
+ if ( pCurrentFormat->Count() > 0 )
+ {
+ pEntry= pCurrentFormat->GetEntry( 0 );
+ aEdtCond11.SetText( pEntry->GetExpression( aCurPos, 0 ) );
+ aLbCond1Template.SelectEntry( pEntry->GetStyle() );
+
+ ScConditionMode eMode = pEntry->GetOperation();
+ if ( eMode == SC_COND_DIRECT ) // via Formel
+ {
+ aLbCond11.SelectEntryPos( 1 );
+ ChangeCond11Hdl( NULL );
+ }
+ else if ( eMode == SC_COND_NONE ) // ???
+ ;
+ else // via Werte
+ {
+ aLbCond12.SelectEntryPos( sal::static_int_cast<USHORT>( eMode ) );
+ if ( ( eMode == SC_COND_BETWEEN ) || ( eMode == SC_COND_NOTBETWEEN ) )
+ aEdtCond12.SetText( pEntry->GetExpression( aCurPos, 1 ) );
+ }
+ }
+
+
+ if ( pCurrentFormat->Count() > 1 )
+ {
+ aCbxCond2.Check( TRUE );
+ pEntry= pCurrentFormat->GetEntry( 1 );
+ aEdtCond21.SetText( pEntry->GetExpression( aCurPos, 0 ) );
+ aLbCond2Template.SelectEntry( pEntry->GetStyle() );
+
+ ScConditionMode eMode = pEntry->GetOperation();
+ if ( eMode == SC_COND_DIRECT ) // via Formel
+ {
+ aLbCond21.SelectEntryPos( 1 );
+ ChangeCond21Hdl( NULL );
+ }
+ else if ( eMode == SC_COND_NONE ) // ???
+ ;
+ else // via Werte
+ {
+ aLbCond22.SelectEntryPos( sal::static_int_cast<USHORT>( eMode ) );
+ if ( ( eMode == SC_COND_BETWEEN ) || ( eMode == SC_COND_NOTBETWEEN ) )
+ aEdtCond22.SetText( pEntry->GetExpression( aCurPos, 1 ) );
+ }
+ }
+
+ if ( pCurrentFormat->Count() > 2 )
+ {
+ aCbxCond3.Check( TRUE );
+ pEntry= pCurrentFormat->GetEntry( 2 );
+ aEdtCond31.SetText( pEntry->GetExpression( aCurPos, 0 ) );
+ aLbCond3Template.SelectEntry( pEntry->GetStyle() );
+
+ ScConditionMode eMode = pEntry->GetOperation();
+ if ( eMode == SC_COND_DIRECT ) // via Formel
+ {
+ aLbCond31.SelectEntryPos( 1 );
+ ChangeCond31Hdl( NULL );
+ }
+ else if ( eMode == SC_COND_NONE ) // ???
+ ;
+ else // via Werte
+ {
+ aLbCond32.SelectEntryPos( sal::static_int_cast<USHORT>( eMode ) );
+ if ( ( eMode == SC_COND_BETWEEN ) || ( eMode == SC_COND_NOTBETWEEN ) )
+ aEdtCond32.SetText( pEntry->GetExpression( aCurPos, 1 ) );
+ }
+ }
+ }
+
+ ClickCond1Hdl( NULL );
+ ClickCond2Hdl( NULL );
+ ClickCond3Hdl( NULL );
+
+ ChangeCond12Hdl( NULL );
+ ChangeCond22Hdl( NULL );
+ ChangeCond32Hdl( NULL );
+
+ aEdtCond11.GrabFocus();
+ pEdActive = &aEdtCond11;
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable(); // Ref-Feld hat Focus
+// SFX_APPWINDOW->Disable();
+}
+
+
+//----------------------------------------------------------------------------
+// Destruktor
+
+__EXPORT ScConditionalFormatDlg::~ScConditionalFormatDlg()
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScConditionalFormatDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( pEdActive )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart(pEdActive);
+
+ String aStr;
+ rRef.Format( aStr, SCR_ABS_3D, pDocP, pDocP->GetAddressConvention () );
+ String aVal( pEdActive->GetText() );
+ Selection aSel( pEdActive->GetSelection() );
+ aSel.Justify();
+ aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ aVal.Insert( aStr, (xub_StrLen)aSel.Min() );
+ Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() );
+ pEdActive->SetRefString( aVal );
+ pEdActive->SetSelection( aNewSel );
+// pEdActive->SetModifyFlag();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScConditionalFormatDlg::AddRefEntry()
+{
+ if ( pEdActive )
+ {
+ String aVal = pEdActive->GetText();
+ aVal += ';';
+ pEdActive->SetText(aVal);
+
+ xub_StrLen nLen = aVal.Len();
+ pEdActive->SetSelection( Selection( nLen, nLen ) );
+// pEdActive->SetModifyFlag();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScConditionalFormatDlg::IsRefInputMode() const
+{
+ return (pEdActive != NULL);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScConditionalFormatDlg::SetActive()
+{
+ if ( bDlgLostFocus )
+ {
+ bDlgLostFocus = FALSE;
+ if( pEdActive )
+ pEdActive->GrabFocus();
+ }
+ else
+ GrabFocus();
+
+ RefInputDone();
+}
+
+
+//----------------------------------------------------------------------------
+// Holt die ausgewaehlte bedingte Formatierung ab
+
+void ScConditionalFormatDlg::GetConditionalFormat( ScConditionalFormat& rCndFmt )
+{
+ ScConditionMode eOper;
+ String sExpr1;
+ String sExpr2;
+ String sStyle;
+ ScAddress aCurPos;
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ ScViewData* pData = pViewShell->GetViewData();
+ aCurPos = ScAddress( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+ }
+
+ if ( aCbxCond1.IsChecked() )
+ {
+ if ( aLbCond11.GetSelectEntryPos() == 1 ) // via Formel
+ eOper = SC_COND_DIRECT;
+ else
+ eOper = (ScConditionMode)aLbCond12.GetSelectEntryPos();
+ sExpr1 = aEdtCond11.GetText();
+ sExpr2 = aEdtCond12.GetText();
+ sStyle = aLbCond1Template.GetSelectEntry();
+ ScCondFormatEntry aNewEntry( eOper, sExpr1, sExpr2, pDoc, aCurPos, sStyle );
+ rCndFmt.AddEntry( aNewEntry );
+ }
+
+ if ( aCbxCond2.IsChecked() )
+ {
+ if ( aLbCond21.GetSelectEntryPos() == 1 ) // via Formel???
+ eOper = SC_COND_DIRECT;
+ else
+ eOper = (ScConditionMode)aLbCond22.GetSelectEntryPos();
+ sExpr1 = aEdtCond21.GetText();
+ sExpr2 = aEdtCond22.GetText();
+ sStyle = aLbCond2Template.GetSelectEntry();
+ ScCondFormatEntry aNewEntry( eOper, sExpr1, sExpr2, pDoc, aCurPos, sStyle );
+ rCndFmt.AddEntry( aNewEntry );
+ }
+
+ if ( aCbxCond3.IsChecked() )
+ {
+ if ( aLbCond31.GetSelectEntryPos() == 1 ) // via Formel???
+ eOper = SC_COND_DIRECT;
+ else
+ eOper = (ScConditionMode)aLbCond32.GetSelectEntryPos();
+ sExpr1 = aEdtCond31.GetText();
+ sExpr2 = aEdtCond32.GetText();
+ sStyle = aLbCond3Template.GetSelectEntry();
+ ScCondFormatEntry aNewEntry( eOper, sExpr1, sExpr2, pDoc, aCurPos, sStyle );
+ rCndFmt.AddEntry( aNewEntry );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Zerstoert den Dialog
+
+BOOL ScConditionalFormatDlg::Close()
+{
+ return DoClose( ScCondFormatDlgWrapper::GetChildWindowId() );
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+
+//----------------------------------------------------------------------------
+// Enabled/Disabled Condition1-Controls
+
+IMPL_LINK( ScConditionalFormatDlg, ClickCond1Hdl, void *, EMPTYARG )
+{
+ BOOL bChecked = aCbxCond1.IsChecked();
+
+ aLbCond11.Enable( bChecked );
+ aLbCond12.Enable( bChecked );
+ aEdtCond11.Enable( bChecked );
+ aRbCond11.Enable( bChecked );
+ aFtCond1And.Enable( bChecked );
+ aEdtCond12.Enable( bChecked );
+ aRbCond12.Enable( bChecked );
+ aFtCond1Template.Enable( bChecked );
+ aLbCond1Template.Enable( bChecked );
+ aBtnNew1.Enable( bChecked );
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// Zellwert/Formel
+
+IMPL_LINK( ScConditionalFormatDlg, ChangeCond11Hdl, void *, EMPTYARG )
+{
+ USHORT nPos = aLbCond11.GetSelectEntryPos();
+
+ if( nPos == 0 ) // Zellwert
+ {
+ aLbCond12.Show();
+ aEdtCond11.SetPosPixel( aCond1Pos2 );
+ }
+ else // Formel
+ {
+ aLbCond12.Hide();
+ aFtCond1And.Hide();
+ aEdtCond12.Hide();
+ aRbCond12.Hide();
+ aRbCond11.SetPosPixel( aRBtn1Pos2 );
+ aEdtCond11.SetPosSizePixel( aCond1Pos1, aCond1Size1 );
+ }
+
+ ChangeCond12Hdl( NULL );
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// zwischen, gleich, groesser, ...
+
+IMPL_LINK( ScConditionalFormatDlg, ChangeCond12Hdl, void *, EMPTYARG )
+{
+ if( aLbCond12.IsVisible() )
+ {
+ USHORT nPos = aLbCond12.GetSelectEntryPos();
+
+ if( nPos == 6 || nPos == 7 ) // zwischen, n. zwischen
+ {
+ aEdtCond11.SetSizePixel( aCond1Size3 );
+ aRbCond11.SetPosPixel( aRBtn1Pos1 );
+ aFtCond1And.Show();
+ aEdtCond12.Show();
+ aRbCond12.Show();
+ }
+ else // gleich, n. gleich ...
+ {
+ aEdtCond12.Hide();
+ aRbCond12.Hide();
+ aFtCond1And.Hide();
+ aRbCond11.SetPosPixel( aRBtn1Pos2 );
+ aEdtCond11.SetSizePixel( aCond1Size2 );
+ }
+ }
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// Enabled/Disabled Condition2-Controls
+
+IMPL_LINK( ScConditionalFormatDlg, ClickCond2Hdl, void *, EMPTYARG )
+{
+ BOOL bChecked = aCbxCond2.IsChecked();
+
+ aLbCond21.Enable( bChecked );
+ aLbCond22.Enable( bChecked );
+ aEdtCond21.Enable( bChecked );
+ aRbCond21.Enable( bChecked );
+ aFtCond2And.Enable( bChecked );
+ aEdtCond22.Enable( bChecked );
+ aRbCond22.Enable( bChecked );
+ aFtCond2Template.Enable( bChecked );
+ aLbCond2Template.Enable( bChecked );
+ aBtnNew2.Enable( bChecked );
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// Zellwert/Formel
+
+IMPL_LINK( ScConditionalFormatDlg, ChangeCond21Hdl, void *, EMPTYARG )
+{
+ USHORT nPos = aLbCond21.GetSelectEntryPos();
+
+ if( nPos == 0 ) // Zellwert
+ {
+ aLbCond22.Show();
+ aEdtCond21.SetPosPixel( aCond2Pos2 );
+ }
+ else // Formel
+ {
+ aLbCond22.Hide();
+ aFtCond2And.Hide();
+ aEdtCond22.Hide();
+ aRbCond22.Hide();
+ aRbCond21.SetPosPixel( aRBtn2Pos2 );
+ aEdtCond21.SetPosSizePixel( aCond2Pos1, aCond2Size1 );
+ }
+
+ ChangeCond22Hdl( NULL );
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// zwischen, gleich, groesser, ...
+
+IMPL_LINK( ScConditionalFormatDlg, ChangeCond22Hdl, void *, EMPTYARG )
+{
+ if( aLbCond22.IsVisible() )
+ {
+ USHORT nPos = aLbCond22.GetSelectEntryPos();
+
+ if( nPos == 6 || nPos == 7 ) // zwischen, n. zwischen
+ {
+ aEdtCond21.SetSizePixel( aCond2Size3 );
+ aRbCond21.SetPosPixel( aRBtn2Pos1 );
+ aFtCond2And.Show();
+ aEdtCond22.Show();
+ aRbCond22.Show();
+ }
+ else // gleich, n. gleich ...
+ {
+ aEdtCond22.Hide();
+ aRbCond22.Hide();
+ aFtCond2And.Hide();
+ aRbCond21.SetPosPixel( aRBtn2Pos2 );
+ aEdtCond21.SetSizePixel( aCond2Size2 );
+ }
+ }
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// Enabled/Disabled Condition3-Controls
+
+IMPL_LINK( ScConditionalFormatDlg, ClickCond3Hdl, void *, EMPTYARG )
+{
+ BOOL bChecked = aCbxCond3.IsChecked();
+
+ aLbCond31.Enable( bChecked );
+ aLbCond32.Enable( bChecked );
+ aEdtCond31.Enable( bChecked );
+ aRbCond31.Enable( bChecked );
+ aFtCond3And.Enable( bChecked );
+ aEdtCond32.Enable( bChecked );
+ aRbCond32.Enable( bChecked );
+ aFtCond3Template.Enable( bChecked );
+ aLbCond3Template.Enable( bChecked );
+ aBtnNew3.Enable( bChecked );
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// Zellwert/Formel
+
+IMPL_LINK( ScConditionalFormatDlg, ChangeCond31Hdl, void *, EMPTYARG )
+{
+ USHORT nPos = aLbCond31.GetSelectEntryPos();
+
+ if( nPos == 0 ) // Zellwert
+ {
+ aLbCond32.Show();
+ aEdtCond31.SetPosPixel( aCond3Pos2 );
+ }
+ else // Formel
+ {
+ aLbCond32.Hide();
+ aFtCond3And.Hide();
+ aEdtCond32.Hide();
+ aRbCond32.Hide();
+ aRbCond31.SetPosPixel( aRBtn3Pos2 );
+ aEdtCond31.SetPosSizePixel( aCond3Pos1, aCond3Size1 );
+ }
+
+ ChangeCond32Hdl( NULL );
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+// zwischen, gleich, groesser, ...
+
+IMPL_LINK( ScConditionalFormatDlg, ChangeCond32Hdl, void *, EMPTYARG )
+{
+ if( aLbCond32.IsVisible() )
+ {
+ USHORT nPos = aLbCond32.GetSelectEntryPos();
+
+ if( nPos == 6 || nPos == 7 ) // zwischen, n. zwischen
+ {
+ aEdtCond31.SetSizePixel( aCond3Size3 );
+ aRbCond31.SetPosPixel( aRBtn3Pos1 );
+ aFtCond3And.Show();
+ aEdtCond32.Show();
+ aRbCond32.Show();
+ }
+ else // gleich, n. gleich ...
+ {
+ aEdtCond32.Hide();
+ aRbCond32.Hide();
+ aFtCond3And.Hide();
+ aRbCond31.SetPosPixel( aRBtn3Pos2 );
+ aEdtCond31.SetSizePixel( aCond3Size2 );
+ }
+ }
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConditionalFormatDlg, GetFocusHdl, Control*, pCtrl )
+{
+ if( (pCtrl == (Control*)&aEdtCond11) || (pCtrl == (Control*)&aRbCond11) )
+ pEdActive = &aEdtCond11;
+ else if( (pCtrl == (Control*)&aEdtCond12) || (pCtrl == (Control*)&aRbCond12) )
+ pEdActive = &aEdtCond12;
+ else if( (pCtrl == (Control*)&aEdtCond21) || (pCtrl == (Control*)&aRbCond21) )
+ pEdActive = &aEdtCond21;
+ else if( (pCtrl == (Control*)&aEdtCond22) || (pCtrl == (Control*)&aRbCond22) )
+ pEdActive = &aEdtCond22;
+ else if( (pCtrl == (Control*)&aEdtCond31) || (pCtrl == (Control*)&aRbCond31) )
+ pEdActive = &aEdtCond31;
+ else if( (pCtrl == (Control*)&aEdtCond32) || (pCtrl == (Control*)&aRbCond32) )
+ pEdActive = &aEdtCond32;
+ else
+ pEdActive = NULL;
+
+ if( pEdActive )
+ pEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConditionalFormatDlg, LoseFocusHdl, Control*, EMPTYARG )
+{
+ bDlgLostFocus = !IsActive();
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+// [OK], [Cancel]
+
+IMPL_LINK( ScConditionalFormatDlg, BtnHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &aBtnOk )
+ {
+ ScConditionalFormat aCondFrmt( 0, pDoc );
+ GetConditionalFormat( aCondFrmt );
+ ScCondFrmtItem aOutItem( FID_CONDITIONAL_FORMAT, aCondFrmt );
+
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( FID_CONDITIONAL_FORMAT,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aOutItem, 0L, 0L );
+ Close();
+ }
+ else if ( pBtn == &aBtnCancel )
+ Close();
+
+ return( 0L );
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConditionalFormatDlg, NewBtnHdl, PushButton*, pBtn )
+{
+ SfxUInt16Item aFamilyItem( SID_STYLE_FAMILY, SFX_STYLE_FAMILY_PARA );
+ SfxStringItem aRefItem( SID_STYLE_REFERENCE, ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
+
+ // unlock the dispatcher so SID_STYLE_NEW can be executed
+ // (SetDispatcherLock would affect all Calc documents)
+ SfxDispatcher* pDisp = GetBindings().GetDispatcher();
+ BOOL bLocked = pDisp->IsLocked();
+ if (bLocked)
+ pDisp->Lock(sal_False);
+
+ // Execute the "new style" slot, complete with undo and all necessary updates.
+ // The return value (SfxUInt16Item) is ignored, look for new styles instead.
+ pDisp->Execute( SID_STYLE_NEW, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD | SFX_CALLMODE_MODAL,
+ &aFamilyItem,
+ &aRefItem,
+ 0L );
+
+ if (bLocked)
+ pDisp->Lock(sal_True);
+
+ // Find the new style and add it into the style list boxes
+ String aNewStyle;
+ SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
+ for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle; pStyle = aStyleIter.Next() )
+ {
+ String aName = pStyle->GetName();
+ if ( aLbCond1Template.GetEntryPos(aName) == LISTBOX_ENTRY_NOTFOUND ) // all lists contain the same entries
+ {
+ aLbCond1Template.InsertEntry( aName );
+ aLbCond2Template.InsertEntry( aName );
+ aLbCond3Template.InsertEntry( aName );
+ // if there are several new styles (from API or a different view),
+ // assume the last one is the result of the dialog
+ aNewStyle = aName;
+ }
+ }
+
+ // select the new style in the list box for which the button was pressed
+ if ( aNewStyle.Len() )
+ {
+ ListBox* pListBox = &aLbCond1Template;
+ if ( pBtn == &aBtnNew2 )
+ pListBox = &aLbCond2Template;
+ else if ( pBtn == &aBtnNew3 )
+ pListBox = &aLbCond3Template;
+
+ pListBox->SelectEntry( aNewStyle );
+ }
+
+ return 0;
+}
+
diff --git a/sc/source/ui/attrdlg/makefile.mk b/sc/source/ui/attrdlg/makefile.mk
new file mode 100644
index 000000000000..378fd1052ff7
--- /dev/null
+++ b/sc/source/ui/attrdlg/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=attrdlg
+LIBTARGET=no
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = attrdlg.cxx \
+ tabpages.cxx \
+ condfrmt.cxx
+
+SLOFILES = $(SLO)$/attrdlg.obj \
+ $(SLO)$/tabpages.obj \
+ $(SLO)$/condfrmt.obj \
+ $(SLO)$/scabstdlg.obj \
+ $(SLO)$/scuiexp.obj \
+ $(SLO)$/scdlgfact.obj
+
+LIB1TARGET = $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO)$/condfrmt.obj \
+ $(SLO)$/scabstdlg.obj
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/sc/source/ui/attrdlg/scabstdlg.cxx b/sc/source/ui/attrdlg/scabstdlg.cxx
new file mode 100644
index 000000000000..b50435041409
--- /dev/null
+++ b/sc/source/ui/attrdlg/scabstdlg.cxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scabstdlg.hxx"
+
+#include <osl/module.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using ::rtl::OUStringBuffer;
+
+typedef ScAbstractDialogFactory* (__LOADONCALLAPI *ScFuncPtrCreateDialogFactory)();
+
+extern "C" { static void SAL_CALL thisModule() {} }
+
+ScAbstractDialogFactory* ScAbstractDialogFactory::Create()
+{
+ ScFuncPtrCreateDialogFactory fp = 0;
+ static ::osl::Module aDialogLibrary;
+
+ OUStringBuffer aStrBuf;
+ aStrBuf.appendAscii( SVLIBRARY("scui") );
+
+ if ( aDialogLibrary.is() || aDialogLibrary.loadRelative( &thisModule, aStrBuf.makeStringAndClear() ) )
+ fp = ( ScAbstractDialogFactory* (__LOADONCALLAPI*)() )
+ aDialogLibrary.getFunctionSymbol( ::rtl::OUString::createFromAscii("CreateDialogFactory") );
+ if ( fp )
+ return fp();
+ return 0;
+}
diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx
new file mode 100644
index 000000000000..73a5f1a1c4ee
--- /dev/null
+++ b/sc/source/ui/attrdlg/scdlgfact.cxx
@@ -0,0 +1,1600 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#if ! ENABLE_LAYOUT_EXPERIMENTAL
+#undef ENABLE_LAYOUT
+#endif
+
+#undef SC_DLLIMPLEMENTATION
+
+#include "scdlgfact.hxx"
+
+#include "sc.hrc" //CHINA001
+#include "scuiasciiopt.hxx" //add for ScImportAsciiDlg
+#include "scuiautofmt.hxx" //add for ScAutoFormatDlg
+#include "corodlg.hxx" //add for ScColRowLabelDlg
+#include "crdlg.hxx" //add for ScColOrRowDlg
+#include "dapidata.hxx" //add for ScDataPilotDatabaseDlg
+#include "dapitype.hxx" //add for ScDataPilotSourceTypeDlg, ScDataPilotServiceDlg
+#include "delcldlg.hxx" //add for ScDeleteCellDlg
+#include "delcodlg.hxx" //add for ScDeleteContentsDlg
+#include "filldlg.hxx" //add for ScFillSeriesDlg
+#include "groupdlg.hxx" //add for ScGroupDlg
+#include "inscldlg.hxx" //add for ScInsertCellDlg
+#include "inscodlg.hxx" //add for ScInsertContentsDlg
+#include "instbdlg.hxx" //add for ScInsertTableDlg
+#include "lbseldlg.hxx" //add for ScSelEntryDlg
+#include "linkarea.hxx" //add for ScLinkedAreaDlg
+#include "mtrindlg.hxx" //add for ScMetricInputDlg
+#include "mvtabdlg.hxx" //add for ScMoveTableDlg
+#include "namecrea.hxx" //add for ScNameCreateDlg
+#include "namepast.hxx" //add for ScNamePasteDlg
+#include "pfiltdlg.hxx" //add for ScPivotFilterDlg
+#include "pvfundlg.hxx" //add for ScDPFunctionDlg
+#include "dpgroupdlg.hxx"
+#include "scendlg.hxx" //add for ScNewScenarioDlg
+#include "shtabdlg.hxx" //add for ScShowTabDlg
+#include "strindlg.hxx" //add for ScStringInputDlg
+#include "tabbgcolordlg.hxx"//add for ScTabBgColorDlg
+#include "scuiimoptdlg.hxx" //add for ScImportOptionsDlg
+#include "attrdlg.hxx" //add for ScAttrDlg
+#include "hfedtdlg.hxx" //add for ScHFEditDlg
+#include "styledlg.hxx" //add for ScStyleDlg
+#include "subtdlg.hxx" //add for ScSubTotalDlg
+#include "textdlgs.hxx" //add for ScCharDlg, ScParagraphDlg
+#include "validate.hxx" //add for ScValidationDlg
+#include "validate.hrc" //add for ScValidationDlg
+#include "sortdlg.hxx" //add for ScSortDlg
+#include "textimportoptions.hxx"
+#include "opredlin.hxx" //add for ScRedlineOptionsTabPage
+#include "tpcalc.hxx" //add for ScTpCalcOptions
+#include "tpprint.hxx" //add for ScTpPrintOptions
+#include "tpstat.hxx" //add for ScDocStatPage
+#include "tpusrlst.hxx" //add for ScTpUserLists
+#include "tpview.hxx" //add for ScTpContentOptions
+
+// ause
+#include "editutil.hxx"
+#include <sfx2/layout.hxx>
+
+IMPL_ABSTDLG_BASE(VclAbstractDialog_Impl); //add for ScColOrRowDlg
+IMPL_ABSTDLG_BASE(AbstractScImportAsciiDlg_Impl);//CHINA001 add for ScImportAsciiDlg
+IMPL_ABSTDLG_BASE(AbstractScAutoFormatDlg_Impl); //CHINA001 add for ScAutoFormatDlg
+IMPL_ABSTDLG_BASE(AbstractScColRowLabelDlg_Impl); //add for ScColRowLabelDlg
+IMPL_ABSTDLG_BASE(AbstractScDataPilotDatabaseDlg_Impl); //add for ScDataPilotDatabaseDlg
+IMPL_ABSTDLG_BASE(AbstractScDataPilotSourceTypeDlg_Impl); //add for ScDataPilotSourceTypeDlg
+IMPL_ABSTDLG_BASE(AbstractScDataPilotServiceDlg_Impl); //add for ScDataPilotServiceDlg
+IMPL_ABSTDLG_BASE(AbstractScDeleteCellDlg_Impl); //add for ScDeleteCellDlg
+IMPL_ABSTDLG_BASE(AbstractScDeleteContentsDlg_Impl); //add for ScDeleteContentsDlg
+IMPL_ABSTDLG_BASE(AbstractScFillSeriesDlg_Impl); //add for ScFillSeriesDlg
+IMPL_ABSTDLG_BASE(AbstractScGroupDlg_Impl); //add for ScGroupDlg
+IMPL_ABSTDLG_BASE(AbstractScInsertCellDlg_Impl); //add for ScInsertCellDlg
+IMPL_ABSTDLG_BASE(AbstractScInsertContentsDlg_Impl); //add for ScInsertContentsDlg
+IMPL_ABSTDLG_BASE(AbstractScInsertTableDlg_Impl); //add for ScInsertTableDlg
+IMPL_ABSTDLG_BASE(AbstractScSelEntryDlg_Impl); //add for ScSelEntryDlg
+IMPL_ABSTDLG2_BASE(AbstractScLinkedAreaDlg_Impl); //add for ScLinkedAreaDlg
+IMPL_ABSTDLG_BASE(AbstractScMetricInputDlg_Impl); //add for ScMetricInputDlg
+IMPL_ABSTDLG_BASE(AbstractScMoveTableDlg_Impl); //add for ScMoveTableDlg
+IMPL_ABSTDLG_BASE(AbstractScNameCreateDlg_Impl); //add for ScNameCreateDlg
+IMPL_ABSTDLG_BASE(AbstractScNamePasteDlg_Impl); //add for ScNamePasteDlg
+IMPL_ABSTDLG_BASE(AbstractScPivotFilterDlg_Impl); //add for ScPivotFilterDlg
+IMPL_ABSTDLG_BASE(AbstractScDPFunctionDlg_Impl); //add for ScDPFunctionDlg
+IMPL_ABSTDLG_BASE(AbstractScDPSubtotalDlg_Impl); //add for ScDPSubtotalDlg
+IMPL_ABSTDLG_BASE(AbstractScDPNumGroupDlg_Impl);
+IMPL_ABSTDLG_BASE(AbstractScDPDateGroupDlg_Impl);
+IMPL_ABSTDLG_BASE(AbstractScDPShowDetailDlg_Impl); //add for ScDPShowDetailDlg
+IMPL_ABSTDLG_BASE(AbstractScNewScenarioDlg_Impl); //add for ScNewScenarioDlg
+IMPL_ABSTDLG_BASE(AbstractScShowTabDlg_Impl); //add for ScShowTabDlg
+IMPL_ABSTDLG_BASE(AbstractScStringInputDlg_Impl); //add for ScStringInputDlg
+IMPL_ABSTDLG_BASE(AbstractScTabBgColorDlg_Impl); //add for ScTabBgColorDlg
+IMPL_ABSTDLG_BASE(AbstractScImportOptionsDlg_Impl); //add for ScImportOptionsDlg
+IMPL_ABSTDLG_BASE(AbstractScTextImportOptionsDlg_Impl);
+IMPL_ABSTDLG_BASE(AbstractTabDialog_Impl); //add for ScAttrDlg, ScHFEditDlg, ScStyleDlg, ScSubTotalDlg,ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg
+
+// AbstractTabDialog_Impl begin
+void AbstractTabDialog_Impl::SetCurPageId( USHORT nId )
+{
+ pDlg->SetCurPageId( nId );
+}
+
+const SfxItemSet* AbstractTabDialog_Impl::GetOutputItemSet() const
+{
+ return pDlg->GetOutputItemSet();
+}
+//add by CHINA001
+const USHORT* AbstractTabDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return pDlg->GetInputRanges( pItem );
+}
+//add by CHINA001
+void AbstractTabDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ pDlg->SetInputSet( pInSet );
+}
+//From class Window.
+void AbstractTabDialog_Impl::SetText( const XubString& rStr )
+{
+ pDlg->SetText( rStr );
+}
+String AbstractTabDialog_Impl::GetText() const
+{
+ return pDlg->GetText();
+}
+
+#if ENABLE_LAYOUT
+namespace layout
+{
+IMPL_ABSTDLG_BASE(AbstractTabDialog_Impl); //add for ScAttrDlg, ScHFEditDlg, ScStyleDlg, ScSubTotalDlg,ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg
+
+// AbstractTabDialog_Impl begin
+void AbstractTabDialog_Impl::SetCurPageId( USHORT nId )
+{
+ pDlg->SetCurPageId( nId );
+}
+
+const SfxItemSet* AbstractTabDialog_Impl::GetOutputItemSet() const
+{
+ return pDlg->GetOutputItemSet();
+}
+//add by CHINA001
+const USHORT* AbstractTabDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return pDlg->GetInputRanges( pItem );
+}
+//add by CHINA001
+void AbstractTabDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ pDlg->SetInputSet( pInSet );
+}
+//From class Window.
+void AbstractTabDialog_Impl::SetText( const XubString& rStr )
+{
+ pDlg->SetText( rStr );
+}
+String AbstractTabDialog_Impl::GetText() const
+{
+ return pDlg->GetText();
+}
+}
+#endif /* ENABLE_LAYOUT */
+
+//add for AbstractTabDialog_Impl end
+// AbstractScImportAsciiDlg_Impl begin
+void AbstractScImportAsciiDlg_Impl::GetOptions( ScAsciiOptions& rOpt )
+{
+ pDlg->GetOptions( rOpt );
+}
+
+void AbstractScImportAsciiDlg_Impl::SetTextToColumnsMode()
+{
+ pDlg->SetTextToColumnsMode();
+}
+
+void AbstractScImportAsciiDlg_Impl::SaveParameters()
+{
+ pDlg->SaveParameters();
+}
+
+// AbstractScImportAsciiDlg_Impl end
+
+//AbstractScAutoFormatDlg_Impl begin
+USHORT AbstractScAutoFormatDlg_Impl::GetIndex() const
+{
+ return pDlg->GetIndex();
+}
+
+String AbstractScAutoFormatDlg_Impl::GetCurrFormatName()
+{
+ return pDlg->GetCurrFormatName();
+}
+
+//AbstractScAutoFormatDlg_Impl end
+
+
+
+//AbstractScColRowLabelDlg_Impl begin
+BOOL AbstractScColRowLabelDlg_Impl::IsCol()
+{
+ return pDlg->IsCol();
+}
+BOOL AbstractScColRowLabelDlg_Impl::IsRow()
+{
+ return pDlg->IsRow();
+}
+
+//AbstractScColRowLabelDlg_Impl end
+
+
+//AbstractScDataPilotDatabaseDlg_Impl begin
+
+
+void AbstractScDataPilotDatabaseDlg_Impl::GetValues( ScImportSourceDesc& rDesc )
+{
+ pDlg->GetValues(rDesc);
+}
+
+//AbstractScDataPilotDatabaseDlg_Impl end
+
+//AbstractScDataPilotSourceTypeDlg_Impl begin
+
+BOOL AbstractScDataPilotSourceTypeDlg_Impl::IsDatabase() const
+{
+ return pDlg->IsDatabase();
+}
+
+BOOL AbstractScDataPilotSourceTypeDlg_Impl::IsExternal() const
+{
+ return pDlg->IsExternal();
+}
+
+//AbstractScDataPilotSourceTypeDlg_Impl end
+
+
+// AbstractScDataPilotServiceDlg_Impl begin
+String AbstractScDataPilotServiceDlg_Impl::GetServiceName() const
+{
+ return pDlg->GetServiceName();
+}
+
+String AbstractScDataPilotServiceDlg_Impl::GetParSource() const
+{
+ return pDlg->GetParSource();
+}
+String AbstractScDataPilotServiceDlg_Impl::GetParName() const
+{
+ return pDlg->GetParName();
+}
+String AbstractScDataPilotServiceDlg_Impl::GetParUser() const
+{
+ return pDlg->GetParUser();
+}
+String AbstractScDataPilotServiceDlg_Impl::GetParPass() const
+{
+ return pDlg->GetParPass();
+}
+
+//AbstractScDataPilotServiceDlg_Impl end
+
+//AbstractScDeleteCellDlg_Impl begin
+DelCellCmd AbstractScDeleteCellDlg_Impl::GetDelCellCmd() const //add for ScDeleteCellDlg
+{
+ return pDlg->GetDelCellCmd();
+}
+//AbstractScDeleteCellDlg_Impl end
+
+//add for AbstractScDeleteContentsDlg_Impl begin
+void AbstractScDeleteContentsDlg_Impl::DisableObjects()
+{
+ pDlg->DisableObjects();
+}
+USHORT AbstractScDeleteContentsDlg_Impl::GetDelContentsCmdBits() const
+{
+ return pDlg->GetDelContentsCmdBits();
+}
+//add for AbstractScDeleteContentsDlg_Impl end
+
+//add for AbstractScFillSeriesDlg_Impl begin
+FillDir AbstractScFillSeriesDlg_Impl::GetFillDir() const
+{
+ return pDlg->GetFillDir();
+}
+
+FillCmd AbstractScFillSeriesDlg_Impl::GetFillCmd() const
+{
+ return pDlg->GetFillCmd();
+}
+
+FillDateCmd AbstractScFillSeriesDlg_Impl::GetFillDateCmd() const
+{
+ return pDlg->GetFillDateCmd();
+}
+
+double AbstractScFillSeriesDlg_Impl::GetStart() const
+{
+ return pDlg->GetStart();
+}
+double AbstractScFillSeriesDlg_Impl::GetStep() const
+{
+ return pDlg->GetStep();
+}
+double AbstractScFillSeriesDlg_Impl::GetMax() const
+{
+ return pDlg->GetMax();
+}
+String AbstractScFillSeriesDlg_Impl::GetStartStr() const
+{
+ return pDlg->GetStartStr();
+}
+void AbstractScFillSeriesDlg_Impl::SetEdStartValEnabled(BOOL bFlag)
+{
+ pDlg->SetEdStartValEnabled(bFlag);
+}
+//add for AbstractScFillSeriesDlg_Impl end
+
+//add for AbstractScGroupDlg_Impl begin
+BOOL AbstractScGroupDlg_Impl::GetColsChecked() const
+{
+ return pDlg->GetColsChecked();
+}
+//add for AbstractScGroupDlg_Impl end
+
+
+//add for AbstractScInsertCellDlg_Impl begin
+InsCellCmd AbstractScInsertCellDlg_Impl::GetInsCellCmd() const
+{
+ return pDlg->GetInsCellCmd();
+}
+
+//add for AbstractScInsertCellDlg_Impl end
+
+
+//add for AbstractScInsertContentsDlg_Impl begin
+USHORT AbstractScInsertContentsDlg_Impl::GetInsContentsCmdBits() const
+{
+ return pDlg->GetInsContentsCmdBits();
+}
+
+
+USHORT AbstractScInsertContentsDlg_Impl::GetFormulaCmdBits() const
+{
+ return pDlg->GetFormulaCmdBits();
+}
+BOOL AbstractScInsertContentsDlg_Impl::IsSkipEmptyCells() const
+{
+ return pDlg->IsSkipEmptyCells();
+}
+BOOL AbstractScInsertContentsDlg_Impl::IsLink() const
+{
+ return pDlg->IsLink();
+}
+void AbstractScInsertContentsDlg_Impl::SetFillMode( BOOL bSet )
+{
+ pDlg->SetFillMode( bSet );
+}
+
+void AbstractScInsertContentsDlg_Impl::SetOtherDoc( BOOL bSet )
+{
+ pDlg->SetOtherDoc( bSet );
+}
+
+BOOL AbstractScInsertContentsDlg_Impl::IsTranspose() const
+{
+ return pDlg->IsTranspose();
+}
+void AbstractScInsertContentsDlg_Impl::SetChangeTrack( BOOL bSet )
+{
+ pDlg->SetChangeTrack( bSet );
+}
+void AbstractScInsertContentsDlg_Impl::SetCellShiftDisabled( int nDisable )
+{
+ pDlg->SetCellShiftDisabled( nDisable );
+}
+
+InsCellCmd AbstractScInsertContentsDlg_Impl::GetMoveMode()
+{
+ return pDlg->GetMoveMode();
+}
+//add for AbstractScInsertContentsDlg_Impl end
+
+
+//add for AbstractScInsertTableDlg_Impl begin
+BOOL AbstractScInsertTableDlg_Impl::GetTablesFromFile()
+{
+ return pDlg->GetTablesFromFile();
+}
+
+BOOL AbstractScInsertTableDlg_Impl::GetTablesAsLink()
+{
+ return pDlg->GetTablesAsLink();
+}
+const String* AbstractScInsertTableDlg_Impl::GetFirstTable( USHORT* pN )
+{
+ return pDlg->GetFirstTable( pN );
+}
+ScDocShell* AbstractScInsertTableDlg_Impl::GetDocShellTables()
+{
+ return pDlg->GetDocShellTables();
+}
+BOOL AbstractScInsertTableDlg_Impl::IsTableBefore()
+{
+ return pDlg->IsTableBefore();
+}
+USHORT AbstractScInsertTableDlg_Impl::GetTableCount()
+{
+ return pDlg->GetTableCount();
+}
+const String* AbstractScInsertTableDlg_Impl::GetNextTable( USHORT* pN )
+{
+ return pDlg->GetNextTable( pN );
+}
+//add for AbstractScInsertTableDlg_Impl end
+
+//add for AbstractScSelEntryDlg_Impl begin
+String AbstractScSelEntryDlg_Impl::GetSelectEntry() const
+{
+ return pDlg->GetSelectEntry();
+}
+//add for AbstractScSelEntryDlg_Impl end
+
+//add for AbstractScLinkedAreaDlg_Impl begin
+void AbstractScLinkedAreaDlg_Impl::InitFromOldLink( const String& rFile, const String& rFilter,
+ const String& rOptions, const String& rSource,
+ ULONG nRefresh )
+{
+ pDlg->InitFromOldLink( rFile, rFilter, rOptions, rSource, nRefresh);
+}
+
+String AbstractScLinkedAreaDlg_Impl::GetURL()
+{
+ return pDlg->GetURL();
+}
+String AbstractScLinkedAreaDlg_Impl::GetFilter()
+{
+ return pDlg->GetFilter();
+}
+String AbstractScLinkedAreaDlg_Impl::GetOptions()
+{
+ return pDlg->GetOptions();
+}
+String AbstractScLinkedAreaDlg_Impl::GetSource()
+{
+ return pDlg->GetSource();
+}
+ULONG AbstractScLinkedAreaDlg_Impl::GetRefresh()
+{
+ return pDlg->GetRefresh();
+}
+//add for AbstractScLinkedAreaDlg_Impl end
+
+
+//add for AbstractScMetricInputDlg_Impl begin
+long AbstractScMetricInputDlg_Impl::GetInputValue( FieldUnit eUnit ) const
+{
+
+ return pDlg->GetInputValue( eUnit );
+}
+//add for AbstractScMetricInputDlg_Impl end
+
+//add for AbstractScMoveTableDlg_Impl begin
+USHORT AbstractScMoveTableDlg_Impl::GetSelectedDocument() const //add for ScMoveTableDlg
+{
+ return pDlg->GetSelectedDocument();
+}
+
+USHORT AbstractScMoveTableDlg_Impl::GetSelectedTable() const
+{
+ return pDlg->GetSelectedTable();
+}
+BOOL AbstractScMoveTableDlg_Impl::GetCopyTable() const
+{
+ return pDlg->GetCopyTable();
+}
+void AbstractScMoveTableDlg_Impl::SetCopyTable(BOOL bFla)
+{
+ return pDlg->SetCopyTable( bFla );
+}
+void AbstractScMoveTableDlg_Impl::EnableCopyTable(BOOL bFlag)
+{
+ return pDlg->EnableCopyTable( bFlag);
+}
+//add for AbstractScMoveTableDlg_Impl end
+
+//add for AbstractScNameCreateDlg_Impl begin
+USHORT AbstractScNameCreateDlg_Impl::GetFlags() const //add for ScNameCreateDlg
+{
+ return pDlg->GetFlags();
+}
+//add for AbstractScNameCreateDlg_Impl end
+
+//add for AbstractScNamePasteDlg_Impl begin
+String AbstractScNamePasteDlg_Impl::GetSelectedName() const //add for ScNamePasteDlg
+{
+ return pDlg->GetSelectedName();
+}
+
+//add for AbstractScNamePasteDlg_Impl end
+
+//add for AbstractScPivotFilterDlg_Impl begin
+const ScQueryItem& AbstractScPivotFilterDlg_Impl::GetOutputItem() //add for ScPivotFilterDlg
+{
+ return pDlg->GetOutputItem();
+}
+//add for AbstractScPivotFilterDlg_Impl end
+
+//add for AbstractScDPFunctionDlg_Impl begin
+USHORT AbstractScDPFunctionDlg_Impl::GetFuncMask() const //add for ScDPFunctionDlg
+{
+ return pDlg->GetFuncMask();
+}
+::com::sun::star::sheet::DataPilotFieldReference AbstractScDPFunctionDlg_Impl::GetFieldRef() const
+{
+ return pDlg->GetFieldRef();
+}
+//add for AbstractScDPFunctionDlg_Impl end
+
+//add for AbstractScDPSubtotalDlg_Impl begin
+USHORT AbstractScDPSubtotalDlg_Impl::GetFuncMask() const //add for ScDPSubtotalDlg
+{
+ return pDlg->GetFuncMask();
+}
+void AbstractScDPSubtotalDlg_Impl::FillLabelData( ScDPLabelData& rLabelData ) const
+{
+ pDlg->FillLabelData( rLabelData );
+}
+//add for AbstractScDPSubtotalDlg_Impl end
+
+ScDPNumGroupInfo AbstractScDPNumGroupDlg_Impl::GetGroupInfo() const
+{
+ return pDlg->GetGroupInfo();
+}
+
+ScDPNumGroupInfo AbstractScDPDateGroupDlg_Impl::GetGroupInfo() const
+{
+ return pDlg->GetGroupInfo();
+}
+
+sal_Int32 AbstractScDPDateGroupDlg_Impl::GetDatePart() const
+{
+ return pDlg->GetDatePart();
+}
+
+//add for AbstractScDPShowDetailDlg_Impl begin
+String AbstractScDPShowDetailDlg_Impl::GetDimensionName() const
+{
+ return pDlg->GetDimensionName();
+}
+//add for AbstractScDPShowDetailDlg_Impl end
+
+//add for AbstractScNewScenarioDlg_Impl begin
+void AbstractScNewScenarioDlg_Impl::SetScenarioData( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags )
+{
+ pDlg->SetScenarioData(rName,rComment, rColor,nFlags);
+}
+
+void AbstractScNewScenarioDlg_Impl::GetScenarioData( String& rName, String& rComment,
+ Color& rColor, USHORT& rFlags ) const
+{
+ pDlg->GetScenarioData( rName,rComment,rColor,rFlags);
+}
+
+//add for AbstractScNewScenarioDlg_Impl end
+
+//add for AbstractScShowTabDlg_Impl begin
+void AbstractScShowTabDlg_Impl::Insert( const String& rString, BOOL bSelected ) //add for ScShowTabDlg
+{
+ pDlg->Insert( rString, bSelected);
+}
+
+USHORT AbstractScShowTabDlg_Impl::GetSelectEntryCount() const
+{
+ return pDlg->GetSelectEntryCount();
+}
+void AbstractScShowTabDlg_Impl::SetDescription(
+ const String& rTitle, const String& rFixedText,
+ ULONG nDlgHelpId, ULONG nLbHelpId )
+{
+ pDlg->SetDescription( rTitle, rFixedText,nDlgHelpId, nLbHelpId );
+}
+USHORT AbstractScShowTabDlg_Impl::GetSelectEntryPos(USHORT nPos) const
+{
+ return pDlg->GetSelectEntryPos( nPos);
+}
+String AbstractScShowTabDlg_Impl::GetSelectEntry(USHORT nPos) const
+{
+ return pDlg->GetSelectEntry(nPos);
+}
+//add for AbstractScShowTabDlg_Impl end
+
+//add for AbstractScStringInputDlg_Impl begin
+void AbstractScStringInputDlg_Impl::GetInputString( String& rString ) const //add for ScStringInputDlg
+{
+ pDlg->GetInputString( rString );
+}
+//add for AbstractScStringInputDlg_Impl end
+
+//add for AbstractScTabBgColorDlg_Impl begin
+void AbstractScTabBgColorDlg_Impl::GetSelectedColor( Color& rColor ) const //add for ScTabBgColorDlg
+{
+ pDlg->GetSelectedColor( rColor );
+}
+//add for AbstractScTabBgColorDlg_Impl end
+
+
+//add for AbstractScImportOptionsDlg_Impl begin
+void AbstractScImportOptionsDlg_Impl::GetImportOptions( ScImportOptions& rOptions ) const //add for ScImportOptionsDlg
+{
+ pDlg->GetImportOptions(rOptions);
+}
+// add for AbstractScImportOptionsDlg_Impl end
+
+//add for AbstractScLangChooserDlg_Impl begin
+LanguageType AbstractScTextImportOptionsDlg_Impl::GetLanguageType() const
+{
+ return pDlg->getLanguageType();
+}
+
+bool AbstractScTextImportOptionsDlg_Impl::IsDateConversionSet() const
+{
+ return pDlg->isDateConversionSet();
+}
+
+//add for AbstractScLangChooserDlg_Impl end
+
+// =========================Factories for createdialog ===================
+
+//add for ScImportAsciiDlg begin
+AbstractScImportAsciiDlg * ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg ( Window* pParent, String aDatName,
+ SvStream* pInStream, int nId, sal_Unicode cSep )
+{
+ ScImportAsciiDlg* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_ASCII :
+ pDlg = new ScImportAsciiDlg( pParent, aDatName,pInStream, cSep );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScImportAsciiDlg_Impl( pDlg );
+ return 0;
+}
+// ScImportAsciiDlg end
+
+AbstractScTextImportOptionsDlg * ScAbstractDialogFactory_Impl::CreateScTextImportOptionsDlg( Window* pParent, int nId )
+{
+ ScTextImportOptionsDlg* pDlg = NULL;
+ switch (nId)
+ {
+ case RID_SCDLG_TEXT_IMPORT_OPTIONS:
+ pDlg = new ScTextImportOptionsDlg(pParent);
+ break;
+ default:
+ ;
+ }
+
+ return pDlg ? new AbstractScTextImportOptionsDlg_Impl(pDlg) : NULL;
+}
+
+//add for ScAutoFormatDlg begin
+
+AbstractScAutoFormatDlg * ScAbstractDialogFactory_Impl::CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg
+ ScAutoFormat* pAutoFormat,
+ const ScAutoFormatData* pSelFormatData,
+ ScDocument* pDoc,
+ int nId)
+{
+ ScAutoFormatDlg* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_AUTOFORMAT :
+ pDlg = new ScAutoFormatDlg( pParent, pAutoFormat,pSelFormatData, pDoc );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScAutoFormatDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScAutoFormatDlg end
+
+//add for ScColRowLabelDlg begin
+
+AbstractScColRowLabelDlg * ScAbstractDialogFactory_Impl::CreateScColRowLabelDlg(Window* pParent, //add for ScColRowLabelDlg
+ int nId,
+ BOOL bCol ,
+ BOOL bRow)
+{
+ ScColRowLabelDlg* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_CHARTCOLROW :
+ pDlg = new ScColRowLabelDlg( pParent, bCol,bRow );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScColRowLabelDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScColRowLabelDlg end
+
+
+//add for ScColOrRowDlg begin
+
+VclAbstractDialog * ScAbstractDialogFactory_Impl::CreateScColOrRowDlg(Window* pParent,
+ const String& rStrTitle,
+ const String& rStrLabel,
+ int nId,
+ BOOL bColDefault)
+{
+ Dialog * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_COLORROW :
+ pDlg = new ScColOrRowDlg( pParent, rStrTitle,rStrLabel,bColDefault );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new VclAbstractDialog_Impl( pDlg );
+ return 0;
+}
+//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
+
+AbstractScDataPilotDatabaseDlg * ScAbstractDialogFactory_Impl::CreateScDataPilotDatabaseDlg (Window* pParent ,
+ int nId ) //add for ScDataPilotDatabaseDlg
+{
+ ScDataPilotDatabaseDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_DAPIDATA :
+ pDlg = new ScDataPilotDatabaseDlg( pParent );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDataPilotDatabaseDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScDataPilotDatabaseDlg end
+
+//add for ScDataPilotSourceTypeDlg begin
+AbstractScDataPilotSourceTypeDlg* ScAbstractDialogFactory_Impl::CreateScDataPilotSourceTypeDlg( Window* pParent,
+ BOOL bEnableExternal,
+ int nId )
+{
+ ScDataPilotSourceTypeDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_DAPITYPE :
+ pDlg = new ScDataPilotSourceTypeDlg( pParent, bEnableExternal );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDataPilotSourceTypeDlg_Impl( pDlg );
+ return 0;
+}
+
+// add for ScDataPilotSourceTypeDlg end
+
+
+//add for ScDataPilotServiceDlg begin
+AbstractScDataPilotServiceDlg* ScAbstractDialogFactory_Impl::CreateScDataPilotServiceDlg( Window* pParent,
+ const com::sun::star::uno::Sequence<rtl::OUString>& rServices,
+ int nId )
+{
+ ScDataPilotServiceDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_DAPISERVICE :
+ pDlg = new ScDataPilotServiceDlg( pParent, rServices );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDataPilotServiceDlg_Impl( pDlg );
+ return 0;
+}
+
+// add for ScDataPilotServiceDlg end
+
+//add for ScDeleteCellDlg begin
+AbstractScDeleteCellDlg* ScAbstractDialogFactory_Impl::CreateScDeleteCellDlg( Window* pParent, int nId,
+ BOOL bDisallowCellMove )
+{
+ ScDeleteCellDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_DELCELL :
+ pDlg = new ScDeleteCellDlg( pParent, bDisallowCellMove );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDeleteCellDlg_Impl( pDlg );
+ return 0;
+}
+
+//add for ScDeleteCellDlg end
+
+//add for ScDeleteContentsDlg begin
+AbstractScDeleteContentsDlg* ScAbstractDialogFactory_Impl::CreateScDeleteContentsDlg(Window* pParent,int nId, //add for ScDeleteContentsDlg
+ USHORT nCheckDefaults )
+{
+ ScDeleteContentsDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_DELCONT :
+ pDlg = new ScDeleteContentsDlg( pParent, nCheckDefaults );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDeleteContentsDlg_Impl( pDlg );
+ return 0;
+}
+
+//add for ScDeleteContentsDlg end
+
+//add for ScFillSeriesDlg begin
+AbstractScFillSeriesDlg* ScAbstractDialogFactory_Impl::CreateScFillSeriesDlg( Window* pParent, //add for ScFillSeriesDlg
+ ScDocument& rDocument,
+ FillDir eFillDir,
+ FillCmd eFillCmd,
+ FillDateCmd eFillDateCmd,
+ String aStartStr,
+ double fStep,
+ double fMax,
+ USHORT nPossDir,
+ int nId)
+{
+ ScFillSeriesDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_FILLSERIES :
+ pDlg = new ScFillSeriesDlg( pParent, rDocument,eFillDir, eFillCmd,eFillDateCmd, aStartStr,fStep,fMax,nPossDir);
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScFillSeriesDlg_Impl( pDlg );
+ return 0;
+}
+
+//add for ScFillSeriesDlg end
+
+//add for ScGroupDlg begin
+AbstractScGroupDlg* ScAbstractDialogFactory_Impl::CreateAbstractScGroupDlg( Window* pParent,
+ USHORT nResId,
+ int nId,
+ BOOL bUnGroup ,
+ BOOL bRows )
+{
+ ScGroupDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_GRP_KILL :
+ case RID_SCDLG_GRP_MAKE :
+ pDlg = new ScGroupDlg( pParent, nResId,bUnGroup, bRows);
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScGroupDlg_Impl( pDlg );
+ return 0;
+}
+
+//add for ScGroupDlg end
+
+
+//add for ScInsertCellDlg begin
+AbstractScInsertCellDlg * ScAbstractDialogFactory_Impl::CreateScInsertCellDlg( Window* pParent, //add for ScInsertCellDlg
+ int nId,
+ BOOL bDisallowCellMove )
+{
+ ScInsertCellDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_INSCELL :
+ pDlg = new ScInsertCellDlg( pParent, bDisallowCellMove);
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScInsertCellDlg_Impl( pDlg );
+ return 0;
+}
+
+//add for ScInsertCellDlg end
+
+//add for ScInsertContentsDlg begin
+AbstractScInsertContentsDlg * ScAbstractDialogFactory_Impl::CreateScInsertContentsDlg( Window* pParent,
+ int nId,
+ USHORT nCheckDefaults,
+ const String* pStrTitle )
+{
+ ScInsertContentsDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_INSCONT :
+ pDlg = new ScInsertContentsDlg( pParent, nCheckDefaults,pStrTitle );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScInsertContentsDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScInsertContentsDlg end
+
+//add for ScInsertTableDlg begin
+AbstractScInsertTableDlg * ScAbstractDialogFactory_Impl::CreateScInsertTableDlg ( Window* pParent, ScViewData& rViewData,
+ SCTAB nTabCount, bool bFromFile, int nId)
+{
+ ScInsertTableDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_INSERT_TABLE :
+ pDlg = new ScInsertTableDlg( pParent, rViewData,nTabCount, bFromFile );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScInsertTableDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScInsertTableDlg end
+
+// add for ScSelEntryDlg begin
+AbstractScSelEntryDlg * ScAbstractDialogFactory_Impl::CreateScSelEntryDlg ( Window* pParent,
+ USHORT nResId,
+ const String& aTitle,
+ const String& aLbTitle,
+ List& aEntryList,
+ int nId )
+{
+ ScSelEntryDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_SELECTDB :
+ pDlg = new ScSelEntryDlg( pParent, nResId,aTitle, aLbTitle, aEntryList );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScSelEntryDlg_Impl( pDlg );
+ return 0;
+}
+// add for ScSelEntryDlg end
+
+//add for ScLinkedAreaDlg begin
+AbstractScLinkedAreaDlg * ScAbstractDialogFactory_Impl::CreateScLinkedAreaDlg ( Window* pParent,
+ int nId)
+{
+ ScLinkedAreaDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_LINKAREA :
+ pDlg = new ScLinkedAreaDlg( pParent );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScLinkedAreaDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScLinkedAreaDlg end
+
+//add for ScMetricInputDlg begin
+AbstractScMetricInputDlg * ScAbstractDialogFactory_Impl::CreateScMetricInputDlg ( Window* pParent,
+ USHORT nResId, // Ableitung fuer jeden Dialog!
+ long nCurrent,
+ long nDefault,
+ int nId ,
+ FieldUnit eFUnit,
+ USHORT nDecimals,
+ long nMaximum ,
+ long nMinimum,
+ long nFirst,
+ long nLast )
+{
+ ScMetricInputDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_ROW_MAN :
+ case RID_SCDLG_ROW_OPT :
+ case RID_SCDLG_COL_MAN :
+ case RID_SCDLG_COL_OPT :
+ pDlg = new ScMetricInputDlg( pParent , nResId,nCurrent ,nDefault, eFUnit,
+ nDecimals, nMaximum , nMinimum , nFirst, nLast);
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScMetricInputDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScMetricInputDlg end
+
+
+//add for ScMoveTableDlg begin
+AbstractScMoveTableDlg * ScAbstractDialogFactory_Impl::CreateScMoveTableDlg( Window* pParent, int nId )
+{
+ ScMoveTableDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_MOVETAB :
+ pDlg = new ScMoveTableDlg( pParent );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScMoveTableDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScMoveTableDlg end
+
+
+//add for ScNameCreateDlg begin
+AbstractScNameCreateDlg * ScAbstractDialogFactory_Impl::CreateScNameCreateDlg ( Window * pParent, USHORT nFlags, int nId )
+{
+ ScNameCreateDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_NAMES_CREATE :
+ pDlg = new ScNameCreateDlg( pParent, nFlags );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScNameCreateDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScNameCreateDlg end
+
+
+//add for ScNamePasteDlg begin
+ AbstractScNamePasteDlg * ScAbstractDialogFactory_Impl::CreateScNamePasteDlg ( Window * pParent, const ScRangeName* pList,
+ int nId , BOOL bInsList )
+{
+ ScNamePasteDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_NAMES_PASTE :
+ pDlg = new ScNamePasteDlg( pParent, pList, bInsList );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScNamePasteDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScNamePasteDlg end
+
+//add for ScPivotFilterDlg begin
+AbstractScPivotFilterDlg * ScAbstractDialogFactory_Impl::CreateScPivotFilterDlg ( Window* pParent,
+ const SfxItemSet& rArgSet, USHORT nSourceTab , int nId )
+{
+ ScPivotFilterDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_PIVOTFILTER :
+ pDlg = new ScPivotFilterDlg( pParent, rArgSet, nSourceTab );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScPivotFilterDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScPivotFilterDlg end
+
+
+//add for ScDPFunctionDlg begin
+AbstractScDPFunctionDlg * ScAbstractDialogFactory_Impl::CreateScDPFunctionDlg ( Window* pParent,
+ int nId,
+ const ScDPLabelDataVec& rLabelVec,
+ const ScDPLabelData& rLabelData,
+ const ScDPFuncData& rFuncData )
+{
+ ScDPFunctionDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_DPDATAFIELD :
+ pDlg = new ScDPFunctionDlg( pParent, rLabelVec, rLabelData, rFuncData );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDPFunctionDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScDPFunctionDlg end
+
+//add for ScDPSubtotalDlg begin
+AbstractScDPSubtotalDlg * ScAbstractDialogFactory_Impl::CreateScDPSubtotalDlg ( Window* pParent,
+ int nId,
+ ScDPObject& rDPObj,
+ const ScDPLabelData& rLabelData,
+ const ScDPFuncData& rFuncData,
+ const ScDPNameVec& rDataFields,
+ bool bEnableLayout )
+{
+ ScDPSubtotalDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_PIVOTSUBT :
+ pDlg = new ScDPSubtotalDlg( pParent, rDPObj, rLabelData, rFuncData, rDataFields, bEnableLayout );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScDPSubtotalDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScDPSubtotalDlg end
+
+AbstractScDPNumGroupDlg * ScAbstractDialogFactory_Impl::CreateScDPNumGroupDlg(
+ Window* pParent, int nId, const ScDPNumGroupInfo& rInfo )
+{
+ if( nId == RID_SCDLG_DPNUMGROUP )
+ return new AbstractScDPNumGroupDlg_Impl( new ScDPNumGroupDlg( pParent, rInfo ) );
+ return 0;
+}
+
+AbstractScDPDateGroupDlg * ScAbstractDialogFactory_Impl::CreateScDPDateGroupDlg(
+ Window* pParent, int nId,
+ const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate )
+{
+ if( nId == RID_SCDLG_DPDATEGROUP )
+ return new AbstractScDPDateGroupDlg_Impl( new ScDPDateGroupDlg( pParent, rInfo, nDatePart, rNullDate ) );
+ return 0;
+}
+
+//add for ScDPShowDetailDlg begin
+AbstractScDPShowDetailDlg * ScAbstractDialogFactory_Impl::CreateScDPShowDetailDlg (
+ Window* pParent, int nId, ScDPObject& rDPObj, USHORT nOrient )
+{
+ if( nId == RID_SCDLG_DPSHOWDETAIL )
+ return new AbstractScDPShowDetailDlg_Impl( new ScDPShowDetailDlg( pParent, rDPObj, nOrient ) );
+ return 0;
+}
+//add for ScDPShowDetailDlg end
+
+//add for ScNewScenarioDlg begin
+AbstractScNewScenarioDlg * ScAbstractDialogFactory_Impl::CreateScNewScenarioDlg ( Window* pParent, const String& rName,
+ int nId,
+ BOOL bEdit , BOOL bSheetProtected )
+{
+ ScNewScenarioDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_NEWSCENARIO :
+ pDlg = new ScNewScenarioDlg( pParent, rName, bEdit,bSheetProtected );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScNewScenarioDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScNewScenarioDlg end
+
+//add for ScShowTabDlg begin
+AbstractScShowTabDlg * ScAbstractDialogFactory_Impl::CreateScShowTabDlg ( Window* pParent, int nId )
+{
+ ScShowTabDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_SHOW_TAB :
+ pDlg = new ScShowTabDlg( pParent);
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScShowTabDlg_Impl( pDlg );
+ return 0;
+}
+
+//add for ScShowTabDlg end
+
+
+//add for ScStringInputDlg begin
+ AbstractScStringInputDlg * ScAbstractDialogFactory_Impl::CreateScStringInputDlg ( Window* pParent,
+ const String& rTitle,
+ const String& rEditTitle,
+ const String& rDefault,
+ ULONG nHelpId ,
+ int nId )
+{
+ ScStringInputDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_STRINPUT :
+ pDlg = new ScStringInputDlg( pParent, rTitle, rEditTitle,rDefault, nHelpId );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScStringInputDlg_Impl( pDlg );
+ return 0;
+}
+ //add for ScStringInputDlg end
+
+//add for ScTabBgColorDlg begin
+AbstractScTabBgColorDlg * ScAbstractDialogFactory_Impl::CreateScTabBgColorDlg (
+ Window* pParent,
+ const String& rTitle,
+ const String& rTabBgColorNoColorText,
+ const Color& rDefaultColor,
+ ULONG nHelpId ,
+ int nId )
+{
+ScTabBgColorDlg * pDlg=NULL;
+switch ( nId )
+{
+ case RID_SCDLG_TAB_BG_COLOR :
+ pDlg = new ScTabBgColorDlg( pParent, rTitle, rTabBgColorNoColorText, rDefaultColor, nHelpId );
+ break;
+ default:
+ break;
+}
+
+if ( pDlg )
+ return new AbstractScTabBgColorDlg_Impl( pDlg );
+return 0;
+}
+//add for ScTabBgColorDlg end
+
+//add for ScImportOptionsDlg begin
+AbstractScImportOptionsDlg * ScAbstractDialogFactory_Impl::CreateScImportOptionsDlg ( Window* pParent,
+ int nId,
+ BOOL bAscii,
+ const ScImportOptions* pOptions,
+ const String* pStrTitle,
+ BOOL bMultiByte,
+ BOOL bOnlyDbtoolsEncodings,
+ BOOL bImport )
+{
+ ScImportOptionsDlg * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_IMPORTOPT :
+ pDlg = new ScImportOptionsDlg( pParent, bAscii, pOptions,pStrTitle, bMultiByte,bOnlyDbtoolsEncodings, bImport );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractScImportOptionsDlg_Impl( pDlg );
+ return 0;
+}
+//add for ScImportOptionsDlg end
+
+#if ENABLE_LAYOUT && !LAYOUT_SFX_TABDIALOG_BROKEN
+#define SfxTabDialog layout::SfxTabDialog
+#define AbstractTabDialog_Impl layout::AbstractTabDialog_Impl
+#endif /* ENABLE_LAYOUT */
+//add for ScAttrDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScAttrDlg( SfxViewFrame* pFrame,
+ Window* pParent,
+ const SfxItemSet* pCellAttrs,
+ int nId)
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_ATTR :
+ pDlg = new ScAttrDlg( pFrame, pParent, pCellAttrs );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+
+}
+//add for ScAttrDlg end
+#undef SfxTabDialog
+#undef AbstractTabDialog_Impl
+
+//add for ScHFEditDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScHFEditDlg( SfxViewFrame* pFrame,
+ Window* pParent,
+ const SfxItemSet& rCoreSet,
+ const String& rPageStyle,
+ int nId,
+ USHORT nResId )
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_HFEDIT :
+ pDlg = new ScHFEditDlg( pFrame, pParent, rCoreSet,rPageStyle, nResId );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScHFEditDlg end
+
+//add for ScStyleDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScStyleDlg( Window* pParent,
+ SfxStyleSheetBase& rStyleBase,
+ USHORT nRscId,
+ int nId)
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_STYLES_PAGE :
+ case RID_SCDLG_STYLES_PAR :
+ pDlg = new ScStyleDlg( pParent, rStyleBase, nRscId );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScStyleDlg end
+
+//add for ScSubTotalDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScSubTotalDlg( Window* pParent,
+ const SfxItemSet* pArgSet,
+ int nId)
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_SUBTOTALS :
+ pDlg = new ScSubTotalDlg( pParent, pArgSet );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScSubTotalDlg end
+
+//add for ScCharDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScCharDlg( Window* pParent, const SfxItemSet* pAttr,
+ const SfxObjectShell* pDocShell, int nId )
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_CHAR :
+ pDlg = new ScCharDlg( pParent, pAttr, pDocShell );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScCharDlg end
+
+//add for ScParagraphDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScParagraphDlg( Window* pParent, const SfxItemSet* pAttr ,
+ int nId )
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_PARAGRAPH :
+ pDlg = new ScParagraphDlg( pParent, pAttr );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScParagraphDlg end
+
+//add for ScValidationDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScValidationDlg( Window* pParent,
+//<!--Modified by PengYunQuan for Validity Cell Range Picker
+// const SfxItemSet* pArgSet,int nId )
+ const SfxItemSet* pArgSet,int nId, ScTabViewShell *pTabVwSh )
+//-->Modified by PengYunQuan for Validity Cell Range Picke
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case TAB_DLG_VALIDATION :
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //pDlg = new ScValidationDlg( pParent, pArgSet );
+ pDlg = new ScValidationDlg( pParent, pArgSet, pTabVwSh );
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScValidationDlg end
+
+#if ENABLE_LAYOUT && !LAYOUT_SFX_TABDIALOG_BROKEN
+#define SfxTabDialog layout::SfxTabDialog
+#define AbstractTabDialog_Impl layout::AbstractTabDialog_Impl
+#endif /* ENABLE_LAYOUT */
+//add for ScSortDlg begin
+SfxAbstractTabDialog * ScAbstractDialogFactory_Impl::CreateScSortDlg( Window* pParent,
+ const SfxItemSet* pArgSet,int nId )
+{
+ SfxTabDialog* pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_SORT :
+ pDlg = new ScSortDlg( pParent, pArgSet );
+ break;
+ default:
+ break;
+ }
+
+ if ( pDlg )
+ return new AbstractTabDialog_Impl( pDlg );
+ return 0;
+}
+#undef SfxTabDialog
+#undef AbstractTabDialog_Impl
+
+//add for ScSortDlg end
+//------------------ Factories for TabPages--------------------
+CreateTabPage ScAbstractDialogFactory_Impl::GetTabPageCreatorFunc( USHORT nId )
+{
+ switch ( nId )
+ {
+ case RID_SCPAGE_OPREDLINE :
+ return ScRedlineOptionsTabPage::Create;
+ //break;
+ case RID_SCPAGE_CALC :
+ return ScTpCalcOptions::Create;
+ //break;
+ case RID_SCPAGE_PRINT :
+ return ScTpPrintOptions::Create;
+ //break;
+ case RID_SCPAGE_STAT :
+ return ScDocStatPage::Create;
+ //break;
+ case RID_SCPAGE_USERLISTS :
+ return ScTpUserLists::Create;
+ //break;
+ case RID_SCPAGE_CONTENT :
+ return ScTpContentOptions::Create;
+ //break;
+ case RID_SCPAGE_LAYOUT :
+ return ScTpLayoutOptions::Create;
+ //break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+GetTabPageRanges ScAbstractDialogFactory_Impl::GetTabPageRangesFunc( USHORT nId )
+{
+ switch ( nId )
+ {
+ case TP_VALIDATION_VALUES :
+ return ScTPValidationValue::GetRanges;
+ //break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void ScDPFunctionDlg_Dummy()
+{
+ // use ScDPListBoxWrapper to avoid warning (this isn't called)
+ ListBox* pListBox = NULL;
+ ScDPListBoxWrapper aWrapper( *pListBox );
+}
+
diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx
new file mode 100644
index 000000000000..cd0f79dd1598
--- /dev/null
+++ b/sc/source/ui/attrdlg/scdlgfact.hxx
@@ -0,0 +1,593 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_DLGFACT_HXX
+#define _SC_DLGFACT_HXX
+
+// include ---------------------------------------------------------------
+#include "scabstdlg.hxx" //CHINA001
+class Dialog;
+class ScImportAsciiDlg;
+class ScAutoFormatDlg;
+class ScColRowLabelDlg;
+class ScDataPilotDatabaseDlg;
+class ScDataPilotSourceTypeDlg;
+class ScDataPilotServiceDlg;
+class ScDeleteCellDlg;
+class ScDeleteContentsDlg;
+class ScFillSeriesDlg;
+class ScGroupDlg;
+class ScInsertCellDlg;
+class ScInsertContentsDlg;
+class ScInsertTableDlg;
+class ScSelEntryDlg;
+class ScLinkedAreaDlg;
+class ScMetricInputDlg;
+class ScMoveTableDlg;
+class ScNameCreateDlg;
+class ScNamePasteDlg;
+class ScPivotFilterDlg;
+class ScDPFunctionDlg;
+class ScDPSubtotalDlg;
+class ScDPNumGroupDlg;
+class ScDPDateGroupDlg;
+class ScDPShowDetailDlg;
+class ScNewScenarioDlg;
+class ScShowTabDlg;
+class ScStringInputDlg;
+class ScTabBgColorDlg;
+class ScImportOptionsDlg;
+class SfxTabDialog;
+class ScSortWarningDlg;
+class ScTextImportOptionsDlg;
+
+#define DECL_ABSTDLG_BASE(Class,DialogClass) \
+ DialogClass* pDlg; \
+public: \
+ Class( DialogClass* p) \
+ : pDlg(p) \
+ {} \
+ virtual ~Class(); \
+ virtual short Execute() ;
+// virtual void Show( BOOL bVisible = TRUE, USHORT nFlags = 0 )
+
+#define DECL_ABSTDLG2_BASE(Class,DialogClass) \
+ DialogClass* pDlg; \
+public: \
+ Class( DialogClass* p) \
+ : pDlg(p) \
+ {} \
+ virtual ~Class(); \
+ virtual void StartExecuteModal( const Link& rEndDialogHdl ); \
+ long GetResult();
+
+#define IMPL_ABSTDLG_BASE(Class) \
+Class::~Class() \
+{ \
+ delete pDlg; \
+} \
+short Class::Execute() \
+{ \
+ return pDlg->Execute(); \
+}
+
+#define IMPL_ABSTDLG2_BASE(Class) \
+Class::~Class() \
+{ \
+ delete pDlg; \
+} \
+void Class::StartExecuteModal( const Link& rEndDialogHdl ) \
+{ \
+ pDlg->StartExecuteModal( rEndDialogHdl ) ; \
+} \
+long Class::GetResult() \
+{ \
+ return pDlg->GetResult(); \
+}
+
+class VclAbstractDialog_Impl : public VclAbstractDialog //add for ScColOrRowDlg
+{
+ DECL_ABSTDLG_BASE(VclAbstractDialog_Impl,Dialog)
+};
+
+class AbstractScImportAsciiDlg_Impl : public AbstractScImportAsciiDlg //add for ScImportAsciiDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScImportAsciiDlg_Impl, ScImportAsciiDlg)
+ virtual void GetOptions( ScAsciiOptions& rOpt );
+ virtual void SetTextToColumnsMode();
+ virtual void SaveParameters();
+};
+
+class AbstractScAutoFormatDlg_Impl : public AbstractScAutoFormatDlg //add for ScAutoFormatDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScAutoFormatDlg_Impl, ScAutoFormatDlg)
+ virtual USHORT GetIndex() const;
+ virtual String GetCurrFormatName();
+};
+
+class AbstractScColRowLabelDlg_Impl : public AbstractScColRowLabelDlg //add for ScColRowLabelDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScColRowLabelDlg_Impl,ScColRowLabelDlg)
+ virtual BOOL IsCol();
+ virtual BOOL IsRow();
+};
+
+class AbstractScDataPilotDatabaseDlg_Impl :public AbstractScDataPilotDatabaseDlg //add for ScDataPilotDatabaseDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScDataPilotDatabaseDlg_Impl, ScDataPilotDatabaseDlg)
+ virtual void GetValues( ScImportSourceDesc& rDesc );
+};
+
+class AbstractScDataPilotSourceTypeDlg_Impl :public AbstractScDataPilotSourceTypeDlg //add for ScDataPilotSourceTypeDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScDataPilotSourceTypeDlg_Impl, ScDataPilotSourceTypeDlg)
+ virtual BOOL IsDatabase() const;
+ virtual BOOL IsExternal() const;
+};
+
+class AbstractScDataPilotServiceDlg_Impl : public AbstractScDataPilotServiceDlg //add for ScDataPilotServiceDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScDataPilotServiceDlg_Impl, ScDataPilotServiceDlg)
+ virtual String GetServiceName() const;
+ virtual String GetParSource() const;
+ virtual String GetParName() const;
+ virtual String GetParUser() const;
+ virtual String GetParPass() const;
+};
+
+class AbstractScDeleteCellDlg_Impl : public AbstractScDeleteCellDlg //add for ScDeleteCellDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScDeleteCellDlg_Impl,ScDeleteCellDlg)
+ virtual DelCellCmd GetDelCellCmd() const;
+};
+
+class AbstractScDeleteContentsDlg_Impl : public AbstractScDeleteContentsDlg //add for ScDeleteContentsDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScDeleteContentsDlg_Impl,ScDeleteContentsDlg)
+ virtual void DisableObjects();
+ virtual USHORT GetDelContentsCmdBits() const;
+};
+
+class AbstractScFillSeriesDlg_Impl:public AbstractScFillSeriesDlg //add for ScFillSeriesDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScFillSeriesDlg_Impl, ScFillSeriesDlg)
+ virtual FillDir GetFillDir() const;
+ virtual FillCmd GetFillCmd() const;
+ virtual FillDateCmd GetFillDateCmd() const;
+ virtual double GetStart() const;
+ virtual double GetStep() const;
+ virtual double GetMax() const;
+ virtual String GetStartStr() const;
+ virtual void SetEdStartValEnabled(BOOL bFlag=FALSE);
+};
+
+class AbstractScGroupDlg_Impl : public AbstractScGroupDlg //add for ScGroupDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScGroupDlg_Impl, ScGroupDlg)
+ virtual BOOL GetColsChecked() const;
+};
+
+class AbstractScInsertCellDlg_Impl : public AbstractScInsertCellDlg //add for ScInsertCellDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScInsertCellDlg_Impl, ScInsertCellDlg)
+ virtual InsCellCmd GetInsCellCmd() const ;
+};
+
+class AbstractScInsertContentsDlg_Impl : public AbstractScInsertContentsDlg //add for ScInsertContentsDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScInsertContentsDlg_Impl, ScInsertContentsDlg)
+ virtual USHORT GetInsContentsCmdBits() const;
+ virtual USHORT GetFormulaCmdBits() const;
+ virtual BOOL IsSkipEmptyCells() const;
+ virtual BOOL IsLink() const;
+ virtual void SetFillMode( BOOL bSet );
+ virtual void SetOtherDoc( BOOL bSet );
+ virtual BOOL IsTranspose() const;
+ virtual void SetChangeTrack( BOOL bSet );
+ virtual void SetCellShiftDisabled( int nDisable );
+ virtual InsCellCmd GetMoveMode();
+};
+
+class AbstractScInsertTableDlg_Impl : public AbstractScInsertTableDlg //add for ScInsertTableDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScInsertTableDlg_Impl, ScInsertTableDlg)
+ virtual BOOL GetTablesFromFile();
+ virtual BOOL GetTablesAsLink();
+ virtual const String* GetFirstTable( USHORT* pN = NULL );
+ virtual ScDocShell* GetDocShellTables();
+ virtual BOOL IsTableBefore();
+ virtual USHORT GetTableCount();
+ virtual const String* GetNextTable( USHORT* pN = NULL );
+
+};
+
+class AbstractScSelEntryDlg_Impl : public AbstractScSelEntryDlg //add for ScSelEntryDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScSelEntryDlg_Impl, ScSelEntryDlg )
+ virtual String GetSelectEntry() const;
+};
+
+class AbstractScLinkedAreaDlg_Impl : public AbstractScLinkedAreaDlg //add for ScLinkedAreaDlg
+{
+ DECL_ABSTDLG2_BASE( AbstractScLinkedAreaDlg_Impl, ScLinkedAreaDlg)
+
+ virtual void InitFromOldLink( const String& rFile, const String& rFilter,
+ const String& rOptions, const String& rSource,
+ ULONG nRefresh );
+ virtual String GetURL();
+ virtual String GetFilter(); // may be empty
+ virtual String GetOptions(); // filter options
+ virtual String GetSource(); // separated by ";"
+ virtual ULONG GetRefresh(); // 0 if disabled
+};
+
+class AbstractScMetricInputDlg_Impl : public AbstractScMetricInputDlg //add for ScMetricInputDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScMetricInputDlg_Impl, ScMetricInputDlg)
+ virtual long GetInputValue( FieldUnit eUnit = FUNIT_TWIP ) const;
+};
+
+class AbstractScMoveTableDlg_Impl : public AbstractScMoveTableDlg //add for ScMoveTableDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScMoveTableDlg_Impl, ScMoveTableDlg)
+ virtual USHORT GetSelectedDocument () const;
+ virtual USHORT GetSelectedTable () const;
+ virtual BOOL GetCopyTable () const;
+ virtual void SetCopyTable (BOOL bFlag=TRUE);
+ virtual void EnableCopyTable (BOOL bFlag=TRUE);
+};
+
+class AbstractScNameCreateDlg_Impl : public AbstractScNameCreateDlg //add for ScNameCreateDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScNameCreateDlg_Impl, ScNameCreateDlg)
+ virtual USHORT GetFlags() const;
+};
+
+class AbstractScNamePasteDlg_Impl : public AbstractScNamePasteDlg //add for ScNamePasteDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScNamePasteDlg_Impl, ScNamePasteDlg )
+ virtual String GetSelectedName() const;
+};
+
+class AbstractScPivotFilterDlg_Impl : public AbstractScPivotFilterDlg //add for ScPivotFilterDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScPivotFilterDlg_Impl, ScPivotFilterDlg)
+ virtual const ScQueryItem& GetOutputItem();
+};
+
+class AbstractScDPFunctionDlg_Impl : public AbstractScDPFunctionDlg //add for ScDPFunctionDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScDPFunctionDlg_Impl, ScDPFunctionDlg)
+ virtual USHORT GetFuncMask() const;
+ virtual ::com::sun::star::sheet::DataPilotFieldReference GetFieldRef() const;
+};
+
+class AbstractScDPSubtotalDlg_Impl : public AbstractScDPSubtotalDlg //add for ScDPSubtotalDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScDPSubtotalDlg_Impl, ScDPSubtotalDlg)
+ virtual USHORT GetFuncMask() const;
+ virtual void FillLabelData( ScDPLabelData& rLabelData ) const;
+};
+
+class AbstractScDPNumGroupDlg_Impl : public AbstractScDPNumGroupDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScDPNumGroupDlg_Impl, ScDPNumGroupDlg )
+ virtual ScDPNumGroupInfo GetGroupInfo() const;
+};
+
+class AbstractScDPDateGroupDlg_Impl : public AbstractScDPDateGroupDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScDPDateGroupDlg_Impl, ScDPDateGroupDlg )
+ virtual ScDPNumGroupInfo GetGroupInfo() const;
+ virtual sal_Int32 GetDatePart() const;
+};
+
+class AbstractScDPShowDetailDlg_Impl : public AbstractScDPShowDetailDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScDPShowDetailDlg_Impl, ScDPShowDetailDlg)
+ virtual String GetDimensionName() const;
+};
+
+class AbstractScNewScenarioDlg_Impl : public AbstractScNewScenarioDlg //add for ScNewScenarioDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScNewScenarioDlg_Impl, ScNewScenarioDlg )
+ virtual void SetScenarioData( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags );
+
+ virtual void GetScenarioData( String& rName, String& rComment,
+ Color& rColor, USHORT& rFlags ) const;
+};
+
+class AbstractScShowTabDlg_Impl : public AbstractScShowTabDlg //add for ScShowTabDlg
+{
+ DECL_ABSTDLG_BASE(AbstractScShowTabDlg_Impl,ScShowTabDlg)
+ virtual void Insert( const String& rString, BOOL bSelected );
+ virtual USHORT GetSelectEntryCount() const;
+ virtual void SetDescription(const String& rTitle, const String& rFixedText,ULONG nDlgHelpId, ULONG nLbHelpId );
+ virtual String GetSelectEntry(USHORT nPos) const;
+ virtual USHORT GetSelectEntryPos(USHORT nPos) const;
+};
+
+class AbstractScStringInputDlg_Impl : public AbstractScStringInputDlg //add for ScStringInputDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScStringInputDlg_Impl, ScStringInputDlg )
+ virtual void GetInputString( String& rString ) const;
+};
+
+class AbstractScTabBgColorDlg_Impl : public AbstractScTabBgColorDlg //add for ScTabBgColorDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScTabBgColorDlg_Impl, ScTabBgColorDlg )
+ virtual void GetSelectedColor( Color& rColor ) const;
+};
+
+class AbstractScImportOptionsDlg_Impl : public AbstractScImportOptionsDlg //add for ScImportOptionsDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScImportOptionsDlg_Impl, ScImportOptionsDlg)
+ virtual void GetImportOptions( ScImportOptions& rOptions ) const;
+};
+
+class AbstractScTextImportOptionsDlg_Impl : public AbstractScTextImportOptionsDlg
+{
+ DECL_ABSTDLG_BASE( AbstractScTextImportOptionsDlg_Impl, ScTextImportOptionsDlg)
+ virtual LanguageType GetLanguageType() const;
+ virtual bool IsDateConversionSet() const;
+};
+
+//add for ScAttrDlg , ScHFEditDlg, ScStyleDlg, ScSubTotalDlg, ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg
+class AbstractTabDialog_Impl : public SfxAbstractTabDialog
+{
+ DECL_ABSTDLG_BASE( AbstractTabDialog_Impl,SfxTabDialog )
+ virtual void SetCurPageId( USHORT nId );
+ virtual const SfxItemSet* GetOutputItemSet() const;
+ virtual const USHORT* GetInputRanges( const SfxItemPool& pItem ); //add by CHINA001
+ virtual void SetInputSet( const SfxItemSet* pInSet ); //add by CHINA001
+ //From class Window.
+ virtual void SetText( const XubString& rStr ); //add by CHINA001
+ virtual String GetText() const; //add by CHINA001
+};
+#if ENABLE_LAYOUT
+namespace layout
+{
+//add for ScAttrDlg , ScHFEditDlg, ScStyleDlg, ScSubTotalDlg, ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg
+class AbstractTabDialog_Impl : public SfxAbstractTabDialog
+{
+ DECL_ABSTDLG_BASE( AbstractTabDialog_Impl,SfxTabDialog )
+ virtual void SetCurPageId( USHORT nId );
+ virtual const SfxItemSet* GetOutputItemSet() const;
+ virtual const USHORT* GetInputRanges( const SfxItemPool& pItem ); //add by CHINA001
+ virtual void SetInputSet( const SfxItemSet* pInSet ); //add by CHINA001
+ //From class Window.
+ virtual void SetText( const XubString& rStr ); //add by CHINA001
+ virtual String GetText() const; //add by CHINA001
+};
+} // end namespace layout
+#endif /* ENABLE_LAYOUT */
+//------------------------------------------------------------------------
+//AbstractDialogFactory_Impl implementations
+class ScAbstractDialogFactory_Impl : public ScAbstractDialogFactory
+{
+
+public:
+ //CHINA001 AbstractSwSaveLabelDlg* CreateSwSaveLabelDlg(SwLabFmtPage* pParent, SwLabRec& rRec, int nId );
+
+ virtual AbstractScImportAsciiDlg * CreateScImportAsciiDlg( Window* pParent, String aDatName, //add for ScImportAsciiDlg
+ SvStream* pInStream, int nId,
+ sal_Unicode cSep = '\t');
+
+ virtual AbstractScTextImportOptionsDlg * CreateScTextImportOptionsDlg( Window* pParent, int nId );
+
+ virtual AbstractScAutoFormatDlg * CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg
+ ScAutoFormat* pAutoFormat,
+ const ScAutoFormatData* pSelFormatData,
+ ScDocument* pDoc,
+ int nId);
+ virtual AbstractScColRowLabelDlg * CreateScColRowLabelDlg (Window* pParent, //add for ScColRowLabelDlg
+ int nId,
+ BOOL bCol = FALSE,
+ BOOL bRow = FALSE);
+
+ virtual VclAbstractDialog * CreateScColOrRowDlg( Window* pParent, //add for ScColOrRowDlg
+ const String& rStrTitle,
+ 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
+
+ virtual AbstractScDataPilotServiceDlg * CreateScDataPilotServiceDlg( Window* pParent, //add for ScDataPilotServiceDlg
+ const com::sun::star::uno::Sequence<rtl::OUString>& rServices,
+ int nId );
+ virtual AbstractScDeleteCellDlg * CreateScDeleteCellDlg( Window* pParent, int nId,
+ BOOL bDisallowCellMove = FALSE ); //add for ScDeleteCellDlg
+
+ virtual AbstractScDeleteContentsDlg * CreateScDeleteContentsDlg(Window* pParent,int nId, //add for ScDeleteContentsDlg
+ USHORT nCheckDefaults = 0 );
+
+ virtual AbstractScFillSeriesDlg * CreateScFillSeriesDlg( Window* pParent, //add for ScFillSeriesDlg
+ ScDocument& rDocument,
+ FillDir eFillDir,
+ FillCmd eFillCmd,
+ FillDateCmd eFillDateCmd,
+ String aStartStr,
+ double fStep,
+ double fMax,
+ USHORT nPossDir,
+ int nId);
+ virtual AbstractScGroupDlg * CreateAbstractScGroupDlg( Window* pParent, //add for ScGroupDlg
+ USHORT nResId,
+ int nId,
+ BOOL bUnGroup = FALSE,
+ BOOL bRows = TRUE );
+
+ virtual AbstractScInsertCellDlg * CreateScInsertCellDlg( Window* pParent, //add for ScInsertCellDlg
+ int nId,
+ BOOL bDisallowCellMove = FALSE );
+
+ virtual AbstractScInsertContentsDlg * CreateScInsertContentsDlg( Window* pParent, //add for ScInsertContentsDlg
+ int nId,
+ USHORT nCheckDefaults = 0,
+ const String* pStrTitle = NULL );
+
+ virtual AbstractScInsertTableDlg * CreateScInsertTableDlg ( Window* pParent, ScViewData& rViewData, //add for ScInsertTableDlg
+ SCTAB nTabCount, bool bFromFile, int nId);
+
+ virtual AbstractScSelEntryDlg * CreateScSelEntryDlg ( Window* pParent, // add for ScSelEntryDlg
+ USHORT nResId,
+ const String& aTitle,
+ const String& aLbTitle,
+ List& aEntryList,
+ int nId );
+
+ virtual AbstractScLinkedAreaDlg * CreateScLinkedAreaDlg ( Window* pParent, //add for ScLinkedAreaDlg
+ int nId);
+
+ virtual AbstractScMetricInputDlg * CreateScMetricInputDlg ( Window* pParent, //add for ScMetricInputDlg
+ USHORT nResId, // Ableitung fuer jeden Dialog!
+ long nCurrent,
+ long nDefault,
+ int nId ,
+ FieldUnit eFUnit = FUNIT_MM,
+ USHORT nDecimals = 2,
+ long nMaximum = 1000,
+ long nMinimum = 0,
+ long nFirst = 1,
+ long nLast = 100 );
+
+ virtual AbstractScMoveTableDlg * CreateScMoveTableDlg( Window* pParent, int nId ); //add for ScMoveTableDlg
+ virtual AbstractScNameCreateDlg * CreateScNameCreateDlg ( Window * pParent, USHORT nFlags, int nId ); //add for ScNameCreateDlg
+
+ virtual AbstractScNamePasteDlg * CreateScNamePasteDlg ( Window * pParent, const ScRangeName* pList, //add for ScNamePasteDlg
+ int nId , BOOL bInsList=TRUE );
+
+ virtual AbstractScPivotFilterDlg * CreateScPivotFilterDlg ( Window* pParent, //add for ScPivotFilterDlg
+ const SfxItemSet& rArgSet, USHORT nSourceTab , int nId );
+
+ virtual AbstractScDPFunctionDlg * CreateScDPFunctionDlg( Window* pParent, int nId,
+ const ScDPLabelDataVec& rLabelVec,
+ const ScDPLabelData& rLabelData,
+ const ScDPFuncData& rFuncData );
+
+ virtual AbstractScDPSubtotalDlg * CreateScDPSubtotalDlg( Window* pParent, int nId,
+ ScDPObject& rDPObj,
+ const ScDPLabelData& rLabelData,
+ const ScDPFuncData& rFuncData,
+ const ScDPNameVec& rDataFields,
+ bool bEnableLayout );
+
+ virtual AbstractScDPNumGroupDlg * CreateScDPNumGroupDlg( Window* pParent,
+ int nId,
+ const ScDPNumGroupInfo& rInfo );
+
+ virtual AbstractScDPDateGroupDlg * CreateScDPDateGroupDlg( Window* pParent,
+ int nId,
+ const ScDPNumGroupInfo& rInfo,
+ sal_Int32 nDatePart,
+ const Date& rNullDate );
+
+ virtual AbstractScDPShowDetailDlg * CreateScDPShowDetailDlg( Window* pParent, int nId,
+ ScDPObject& rDPObj,
+ USHORT nOrient );
+
+ virtual AbstractScNewScenarioDlg * CreateScNewScenarioDlg ( Window* pParent, const String& rName, //add for ScNewScenarioDlg
+ int nId,
+ BOOL bEdit = FALSE, BOOL bSheetProtected = FALSE );
+ virtual AbstractScShowTabDlg * CreateScShowTabDlg ( Window* pParent, int nId ); //add for ScShowTabDlg
+
+ virtual AbstractScStringInputDlg * CreateScStringInputDlg ( Window* pParent, //add for ScStringInputDlg
+ const String& rTitle,
+ const String& rEditTitle,
+ const String& rDefault,
+ ULONG nHelpId ,
+ int nId );
+
+ virtual AbstractScTabBgColorDlg * CreateScTabBgColorDlg ( Window* pParent, //add for ScStringInputDlg
+ const String& rTitle, //Dialog Title
+ const String& rTabBgColorNoColorText, //Label for no tab color
+ const Color& rDefaultColor, //Currently selected Color
+ ULONG nHelpId ,
+ int nId );
+
+ virtual AbstractScImportOptionsDlg * CreateScImportOptionsDlg ( Window* pParent, //add for ScImportOptionsDlg
+ int nId,
+ BOOL bAscii = TRUE,
+ const ScImportOptions* pOptions = NULL,
+ const String* pStrTitle = NULL,
+ BOOL bMultiByte = FALSE,
+ BOOL bOnlyDbtoolsEncodings = FALSE,
+ BOOL bImport = TRUE );
+ virtual SfxAbstractTabDialog * CreateScAttrDlg( SfxViewFrame* pFrame, //add for ScAttrDlg
+ Window* pParent,
+ const SfxItemSet* pCellAttrs,
+ int nId);
+
+ virtual SfxAbstractTabDialog * CreateScHFEditDlg( SfxViewFrame* pFrame, //add for ScHFEditDlg
+ Window* pParent,
+ const SfxItemSet& rCoreSet,
+ const String& rPageStyle,
+ int nId,
+ USHORT nResId = RID_SCDLG_HFEDIT );
+
+ virtual SfxAbstractTabDialog * CreateScStyleDlg( Window* pParent,//add for ScStyleDlg
+ SfxStyleSheetBase& rStyleBase,
+ USHORT nRscId,
+ int nId);
+
+ virtual SfxAbstractTabDialog * CreateScSubTotalDlg( Window* pParent, //add for ScSubTotalDlg
+ const SfxItemSet* pArgSet,
+ int nId);
+ virtual SfxAbstractTabDialog * CreateScCharDlg( Window* pParent, const SfxItemSet* pAttr,//add for ScCharDlg
+ const SfxObjectShell* pDocShell, int nId );
+
+ virtual SfxAbstractTabDialog * CreateScParagraphDlg( Window* pParent, const SfxItemSet* pAttr ,//add for ScParagraphDlg
+ int nId );
+
+ virtual SfxAbstractTabDialog * CreateScValidationDlg( Window* pParent, //add for ScValidationDlg
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ // const SfxItemSet* pArgSet,int nId );
+ const SfxItemSet* pArgSet,int nId, ScTabViewShell *pTabVwSh );
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+
+ virtual SfxAbstractTabDialog * CreateScSortDlg( Window* pParent, //add for ScSortDlg
+ const SfxItemSet* pArgSet,int nId );
+ // For TabPage
+ virtual CreateTabPage GetTabPageCreatorFunc( USHORT nId );
+
+ virtual GetTabPageRanges GetTabPageRangesFunc( USHORT nId );
+
+};
+
+//CHINA001 struct ScDialogsResMgr
+//CHINA001 {
+//CHINA001 static ResMgr* GetResMgr();
+//CHINA001 };
+
+#endif
+
+
diff --git a/sc/source/ui/attrdlg/scuiexp.cxx b/sc/source/ui/attrdlg/scuiexp.cxx
new file mode 100644
index 000000000000..35a0a3a1fb35
--- /dev/null
+++ b/sc/source/ui/attrdlg/scuiexp.cxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+#include "scdlgfact.hxx"
+#include "sal/types.h"
+
+namespace scui
+{
+ static ScAbstractDialogFactory_Impl* pFactory=NULL;
+ ScAbstractDialogFactory_Impl* GetFactory()
+ {
+ if ( !pFactory )
+ pFactory = new ScAbstractDialogFactory_Impl;
+ //if ( !pSwResMgr)
+ // ScDialogsResMgr::GetResMgr();
+ return pFactory;
+ }
+}
+
+extern "C"
+{
+ SAL_DLLPUBLIC_EXPORT ScAbstractDialogFactory* CreateDialogFactory()
+ {
+ return ::scui::GetFactory();
+ }
+}
diff --git a/sc/source/ui/attrdlg/tabpages.cxx b/sc/source/ui/attrdlg/tabpages.cxx
new file mode 100644
index 000000000000..21c769cf0603
--- /dev/null
+++ b/sc/source/ui/attrdlg/tabpages.cxx
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "global.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+
+#include "attrdlg.hrc"
+#include "tabpages.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+static USHORT pProtectionRanges[] =
+{
+ SID_SCATTR_PROTECTION,
+ SID_SCATTR_PROTECTION,
+ 0
+};
+
+//========================================================================
+// Zellschutz-Tabpage:
+//========================================================================
+
+ScTabPageProtection::ScTabPageProtection( Window* pParent,
+ const SfxItemSet& rCoreAttrs )
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_PROTECTION ),
+ rCoreAttrs ),
+ //
+ aFlProtect ( this, ScResId( FL_PROTECTION ) ),
+ aBtnHideCell ( this, ScResId( BTN_HIDE_ALL ) ),
+ aBtnProtect ( this, ScResId( BTN_PROTECTED ) ),
+ aBtnHideFormula ( this, ScResId( BTN_HIDE_FORMULAR ) ),
+ aTxtHint ( this, ScResId( FT_HINT ) ),
+ aFlPrint ( this, ScResId( FL_PRINT ) ),
+ aBtnHidePrint ( this, ScResId( BTN_HIDE_PRINT ) ),
+ aTxtHint2 ( this, ScResId( FT_HINT2 ) )
+{
+ // diese Page braucht ExchangeSupport
+ SetExchangeSupport();
+
+ // States werden in Reset gesetzt
+ bTriEnabled = bDontCare = bProtect = bHideForm = bHideCell = bHidePrint = FALSE;
+
+ aBtnProtect.SetClickHdl( LINK( this, ScTabPageProtection, ButtonClickHdl ) );
+ aBtnHideCell.SetClickHdl( LINK( this, ScTabPageProtection, ButtonClickHdl ) );
+ aBtnHideFormula.SetClickHdl( LINK( this, ScTabPageProtection, ButtonClickHdl ) );
+ aBtnHidePrint.SetClickHdl( LINK( this, ScTabPageProtection, ButtonClickHdl ) );
+
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTabPageProtection::~ScTabPageProtection()
+{
+}
+
+//------------------------------------------------------------------------
+
+USHORT* __EXPORT ScTabPageProtection::GetRanges()
+{
+ return pProtectionRanges;
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTabPageProtection::Create( Window* pParent,
+ const SfxItemSet& rAttrSet )
+{
+ return ( new ScTabPageProtection( pParent, rAttrSet ) );
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScTabPageProtection::Reset( const SfxItemSet& rCoreAttrs )
+{
+ // Variablen initialisieren
+
+ USHORT nWhich = GetWhich( SID_SCATTR_PROTECTION );
+ const ScProtectionAttr* pProtAttr = NULL;
+ SfxItemState eItemState = rCoreAttrs.GetItemState( nWhich, FALSE,
+ (const SfxPoolItem**)&pProtAttr );
+
+ // handelt es sich um ein Default-Item?
+ if ( eItemState == SFX_ITEM_DEFAULT )
+ pProtAttr = (const ScProtectionAttr*)&(rCoreAttrs.Get(nWhich));
+ // bei SFX_ITEM_DONTCARE auf 0 lassen
+
+ bTriEnabled = ( pProtAttr == NULL ); // TriState, wenn DontCare
+ bDontCare = bTriEnabled;
+ if (bTriEnabled)
+ {
+ // Defaults, die erscheinen wenn ein TriState weggeklickt wird:
+ // (weil alles zusammen ein Attribut ist, kann auch nur alles zusammen
+ // auf DontCare stehen - #38543#)
+ bProtect = TRUE;
+ bHideForm = bHideCell = bHidePrint = FALSE;
+ }
+ else
+ {
+ bProtect = pProtAttr->GetProtection();
+ bHideCell = pProtAttr->GetHideCell();
+ bHideForm = pProtAttr->GetHideFormula();
+ bHidePrint = pProtAttr->GetHidePrint();
+ }
+
+ // Controls initialisieren
+
+ aBtnProtect .EnableTriState( bTriEnabled );
+ aBtnHideCell .EnableTriState( bTriEnabled );
+ aBtnHideFormula .EnableTriState( bTriEnabled );
+ aBtnHidePrint .EnableTriState( bTriEnabled );
+
+ UpdateButtons();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTabPageProtection::FillItemSet( SfxItemSet& rCoreAttrs )
+{
+ BOOL bAttrsChanged = FALSE;
+ USHORT nWhich = GetWhich( SID_SCATTR_PROTECTION );
+ const SfxPoolItem* pOldItem = GetOldItem( rCoreAttrs, SID_SCATTR_PROTECTION );
+ const SfxItemSet& rOldSet = GetItemSet();
+ SfxItemState eItemState = rOldSet.GetItemState( nWhich, FALSE );
+ ScProtectionAttr aProtAttr;
+
+ if ( !bDontCare )
+ {
+ aProtAttr.SetProtection( bProtect );
+ aProtAttr.SetHideCell( bHideCell );
+ aProtAttr.SetHideFormula( bHideForm );
+ aProtAttr.SetHidePrint( bHidePrint );
+
+ if ( bTriEnabled )
+ bAttrsChanged = TRUE; // DontCare -> richtiger Wert
+ else
+ bAttrsChanged = !pOldItem || !( aProtAttr == *(const ScProtectionAttr*)pOldItem );
+ }
+
+ //--------------------------------------------------
+
+ if ( bAttrsChanged )
+ rCoreAttrs.Put( aProtAttr );
+ else if ( eItemState == SFX_ITEM_DEFAULT )
+ rCoreAttrs.ClearItem( nWhich );
+
+ return bAttrsChanged;
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScTabPageProtection::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return LEAVE_PAGE;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScTabPageProtection, ButtonClickHdl, TriStateBox*, pBox )
+{
+ TriState eState = pBox->GetState();
+ if ( eState == STATE_DONTKNOW )
+ bDontCare = TRUE; // alles zusammen auf DontCare
+ else
+ {
+ bDontCare = FALSE; // DontCare ueberall aus
+ BOOL bOn = ( eState == STATE_CHECK ); // ausgewaehlter Wert
+
+ if ( pBox == &aBtnProtect )
+ bProtect = bOn;
+ else if ( pBox == &aBtnHideCell )
+ bHideCell = bOn;
+ else if ( pBox == &aBtnHideFormula )
+ bHideForm = bOn;
+ else if ( pBox == &aBtnHidePrint )
+ bHidePrint = bOn;
+ else
+ {
+ DBG_ERRORFILE("falscher Button");
+ }
+ }
+
+ UpdateButtons(); // TriState und Enable-Logik
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+void ScTabPageProtection::UpdateButtons()
+{
+ if ( bDontCare )
+ {
+ aBtnProtect.SetState( STATE_DONTKNOW );
+ aBtnHideCell.SetState( STATE_DONTKNOW );
+ aBtnHideFormula.SetState( STATE_DONTKNOW );
+ aBtnHidePrint.SetState( STATE_DONTKNOW );
+ }
+ else
+ {
+ aBtnProtect.SetState( bProtect ? STATE_CHECK : STATE_NOCHECK );
+ aBtnHideCell.SetState( bHideCell ? STATE_CHECK : STATE_NOCHECK );
+ aBtnHideFormula.SetState( bHideForm ? STATE_CHECK : STATE_NOCHECK );
+ aBtnHidePrint.SetState( bHidePrint ? STATE_CHECK : STATE_NOCHECK );
+ }
+
+ BOOL bEnable = ( aBtnHideCell.GetState() != STATE_CHECK );
+ {
+ aBtnProtect.Enable( bEnable );
+ aBtnHideFormula.Enable( bEnable );
+ }
+}
diff --git a/sc/source/ui/cctrl/cbuttonw.cxx b/sc/source/ui/cctrl/cbuttonw.cxx
new file mode 100644
index 000000000000..6004fdfcfc51
--- /dev/null
+++ b/sc/source/ui/cctrl/cbuttonw.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <vcl/outdev.hxx>
+#include <vcl/window.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/svapp.hxx>
+#include "cbutton.hxx"
+
+//========================================================================
+// class ScDDComboBoxButton
+//========================================================================
+
+ScDDComboBoxButton::ScDDComboBoxButton( OutputDevice* pOutputDevice )
+ : pOut( pOutputDevice )
+{
+ SetOptSizePixel();
+}
+
+// -------------------------------------------------------------------------
+
+__EXPORT ScDDComboBoxButton::~ScDDComboBoxButton()
+{
+}
+
+// -------------------------------------------------------------------------
+
+void ScDDComboBoxButton::SetOutputDevice( OutputDevice* pOutputDevice )
+{
+ pOut = pOutputDevice;
+}
+
+// -------------------------------------------------------------------------
+
+void ScDDComboBoxButton::SetOptSizePixel()
+{
+ aBtnSize = pOut->LogicToPixel( Size(0,11), MAP_APPFONT );
+ //aBtnSize.Width() = GetSystemMetrics( SM_CXVSCROLL ) - 1; // Win SDK-Funktion
+ aBtnSize.Width() = pOut->GetSettings().GetStyleSettings().GetScrollBarSize();
+}
+
+// -------------------------------------------------------------------------
+
+void ScDDComboBoxButton::Draw( const Point& rAt,
+ const Size& rSize,
+ BOOL bState,
+ BOOL bBtnIn /* = FALSE */ )
+{
+ if ( rSize.Width() == 0 || rSize.Height() == 0 )
+ return; // #i43092# rectangle with size 0 would have RECT_EMPTY as end position
+
+ // save old state
+ BOOL bHadFill = pOut->IsFillColor();
+ Color aOldFill = pOut->GetFillColor();
+ BOOL bHadLine = pOut->IsLineColor();
+ Color aOldLine = pOut->GetLineColor();
+ BOOL bOldEnable = pOut->IsMapModeEnabled();
+
+ Size aLogPix( 1, 1 );
+ Rectangle aBtnRect( rAt, rSize );
+ Rectangle aInnerRect = aBtnRect;
+
+ pOut->EnableMapMode( FALSE );
+
+ DecorationView aDecoView( pOut);
+
+ USHORT nButtonStyle = BUTTON_DRAW_DEFAULT;
+ if( bBtnIn ) // gedrueckt?
+ {
+ nButtonStyle = BUTTON_DRAW_PRESSED;
+ }
+
+ aInnerRect=aDecoView.DrawButton( aBtnRect, nButtonStyle );
+
+
+ aInnerRect.Left() += 1;
+ aInnerRect.Top() += 1;
+ aInnerRect.Right() -= 1;
+ aInnerRect.Bottom() -= 1;
+
+ Size aInnerSize = aInnerRect.GetSize();
+ Point aInnerCenter = aInnerRect.Center();
+
+ aInnerRect.Top() = aInnerCenter.Y() - (aInnerSize.Width()>>1);
+ aInnerRect.Bottom()= aInnerCenter.Y() + (aInnerSize.Width()>>1);
+
+ ImpDrawArrow( aInnerRect, bState );
+
+
+ // restore old state
+ pOut->EnableMapMode( bOldEnable );
+ if (bHadLine)
+ pOut->SetLineColor(aOldLine);
+ else
+ pOut->SetLineColor();
+ if (bHadFill)
+ pOut->SetFillColor(aOldFill);
+ else
+ pOut->SetFillColor();
+}
+
+//------------------------------------------------------------------------
+
+void ScDDComboBoxButton::ImpDrawArrow( const Rectangle& rRect,
+ BOOL bState )
+{
+ // no need to save old line and fill color here (is restored after the call)
+
+ Rectangle aPixRect = rRect;
+ Point aCenter = aPixRect.Center();
+ Size aSize = aPixRect.GetSize();
+
+ Size aSize3;
+ aSize3.Width() = aSize.Width() >> 1;
+ aSize3.Height() = aSize.Height() >> 1;
+
+ Size aSize4;
+ aSize4.Width() = aSize.Width() >> 2;
+ aSize4.Height() = aSize.Height() >> 2;
+
+ Rectangle aTempRect = aPixRect;
+
+ const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
+ Color aColor( bState ? COL_LIGHTBLUE : rSett.GetButtonTextColor().GetColor() );
+ pOut->SetFillColor( aColor );
+ pOut->SetLineColor( aColor );
+
+ aTempRect.Left() = aCenter.X() - aSize4.Width();
+ aTempRect.Right() = aCenter.X() + aSize4.Width();
+ aTempRect.Top() = aCenter.Y() - aSize3.Height();
+ aTempRect.Bottom() = aCenter.Y() - 1;
+
+ pOut->DrawRect( aTempRect );
+
+ Point aPos1( aCenter.X()-aSize3.Width(), aCenter.Y() );
+ Point aPos2( aCenter.X()+aSize3.Width(), aCenter.Y() );
+ while( aPos1.X() <= aPos2.X() )
+ {
+ pOut->DrawLine( aPos1, aPos2 );
+ aPos1.X()++; aPos2.X()--;
+ aPos1.Y()++; aPos2.Y()++;
+ }
+
+ pOut->DrawLine( Point( aCenter.X() - aSize3.Width(), aPos1.Y()+1 ),
+ Point( aCenter.X() + aSize3.Width(), aPos1.Y()+1 ) );
+}
+
+
+
+
+
diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx
new file mode 100644
index 000000000000..b90a51ed6bee
--- /dev/null
+++ b/sc/source/ui/cctrl/dpcontrol.cxx
@@ -0,0 +1,1422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpcontrol.hxx"
+#include "dpcontrol.hrc"
+
+#include <vcl/outdev.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/wintypes.hxx>
+#include <vcl/decoview.hxx>
+#include "strload.hxx"
+#include "global.hxx"
+#include "scitems.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+
+#include "AccessibleFilterMenu.hxx"
+#include "AccessibleFilterTopWindow.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::accessibility::XAccessible;
+using ::com::sun::star::accessibility::XAccessibleContext;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::auto_ptr;
+
+ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY, ScDocument* pDoc) :
+ mpDoc(pDoc),
+ mpOutDev(pOutDev),
+ mpStyle(pStyle),
+ mbBaseButton(true),
+ mbPopupButton(false),
+ mbHasHiddenMember(false),
+ mbPopupPressed(false),
+ mbPopupLeft(false)
+{
+ if (pZoomX)
+ maZoomX = *pZoomX;
+ else
+ maZoomX = Fraction(1, 1);
+
+ if (pZoomY)
+ maZoomY = *pZoomY;
+ else
+ maZoomY = Fraction(1, 1);
+}
+
+ScDPFieldButton::~ScDPFieldButton()
+{
+}
+
+void ScDPFieldButton::setText(const OUString& rText)
+{
+ maText = rText;
+}
+
+void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL)
+{
+ maPos = rPos;
+ maSize = rSize;
+ if (bLayoutRTL)
+ {
+ // rPos is the logical-left position, adjust maPos to visual-left (inside the cell border)
+ maPos.X() -= maSize.Width() - 1;
+ }
+}
+
+void ScDPFieldButton::setDrawBaseButton(bool b)
+{
+ mbBaseButton = b;
+}
+
+void ScDPFieldButton::setDrawPopupButton(bool b)
+{
+ mbPopupButton = b;
+}
+
+void ScDPFieldButton::setHasHiddenMember(bool b)
+{
+ mbHasHiddenMember = b;
+}
+
+void ScDPFieldButton::setPopupPressed(bool b)
+{
+ mbPopupPressed = b;
+}
+
+void ScDPFieldButton::setPopupLeft(bool b)
+{
+ mbPopupLeft = b;
+}
+
+void ScDPFieldButton::draw()
+{
+ const long nMargin = 2;
+ bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
+ mpOutDev->EnableMapMode(false);
+
+ if (mbBaseButton)
+ {
+ // Background
+ Rectangle aRect(maPos, maSize);
+ mpOutDev->SetLineColor(mpStyle->GetFaceColor());
+ mpOutDev->SetFillColor(mpStyle->GetFaceColor());
+ mpOutDev->DrawRect(aRect);
+
+ // Border lines
+ mpOutDev->SetLineColor(mpStyle->GetLightColor());
+ mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
+ mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
+
+ mpOutDev->SetLineColor(mpStyle->GetShadowColor());
+ mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
+ Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
+ mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
+ Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
+
+ // Field name.
+ // Get the font and size the same way as in scenario selection (lcl_DrawOneFrame in gridwin4.cxx)
+ Font aTextFont( mpStyle->GetAppFont() );
+ if ( mpDoc )
+ {
+ // use ScPatternAttr::GetFont only for font size
+ Font aAttrFont;
+ static_cast<const ScPatternAttr&>(mpDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
+ GetFont( aAttrFont, SC_AUTOCOL_BLACK, mpOutDev, &maZoomY );
+ aTextFont.SetSize( aAttrFont.GetSize() );
+ }
+ mpOutDev->SetFont(aTextFont);
+ mpOutDev->SetTextColor(mpStyle->GetButtonTextColor());
+
+ Point aTextPos = maPos;
+ long nTHeight = mpOutDev->GetTextHeight();
+ aTextPos.setX(maPos.getX() + nMargin);
+ aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
+
+ mpOutDev->Push(PUSH_CLIPREGION);
+ mpOutDev->IntersectClipRegion(aRect);
+ mpOutDev->DrawText(aTextPos, maText);
+ mpOutDev->Pop();
+ }
+
+ if (mbPopupButton)
+ drawPopupButton();
+
+ mpOutDev->EnableMapMode(bOldMapEnablaed);
+}
+
+void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
+{
+ long nW = maSize.getWidth() / 2;
+ long nH = maSize.getHeight();
+ if (nW > 18)
+ nW = 18;
+ if (nH > 18)
+ nH = 18;
+
+ // #i114944# AutoFilter button is left-aligned in RTL.
+ // DataPilot button is always right-aligned for now, so text output isn't affected.
+ if (mbPopupLeft)
+ rPos.setX(maPos.getX());
+ else
+ rPos.setX(maPos.getX() + maSize.getWidth() - nW);
+ rPos.setY(maPos.getY() + maSize.getHeight() - nH);
+ rSize.setWidth(nW);
+ rSize.setHeight(nH);
+}
+
+void ScDPFieldButton::drawPopupButton()
+{
+ Point aPos;
+ Size aSize;
+ getPopupBoundingBox(aPos, aSize);
+
+ // Background & outer black border
+ mpOutDev->SetLineColor(COL_BLACK);
+ mpOutDev->SetFillColor(mpStyle->GetFaceColor());
+ mpOutDev->DrawRect(Rectangle(aPos, aSize));
+
+ if (!mbPopupPressed)
+ {
+ // border lines
+ mpOutDev->SetLineColor(mpStyle->GetLightColor());
+ mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
+ mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
+
+ mpOutDev->SetLineColor(mpStyle->GetShadowColor());
+ mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
+ Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
+ mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
+ Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
+ }
+
+ // the arrowhead
+ Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
+ mpOutDev->SetLineColor(aArrowColor);
+ mpOutDev->SetFillColor(aArrowColor);
+ Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
+ Point aPos1, aPos2;
+ aPos1.X() = aCenter.X() - 4;
+ aPos2.X() = aCenter.X() + 4;
+ aPos1.Y() = aCenter.Y() - 3;
+ aPos2.Y() = aCenter.Y() - 3;
+
+ if (mbPopupPressed)
+ {
+ aPos1.X() += 1;
+ aPos2.X() += 1;
+ aPos1.Y() += 1;
+ aPos2.Y() += 1;
+ }
+
+ do
+ {
+ ++aPos1.X();
+ --aPos2.X();
+ ++aPos1.Y();
+ ++aPos2.Y();
+ mpOutDev->DrawLine(aPos1, aPos2);
+ }
+ while (aPos1 != aPos2);
+
+ if (mbHasHiddenMember)
+ {
+ // tiny little box to display in presence of hidden member(s).
+ Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
+ if (mbPopupPressed)
+ {
+ aBoxPos.X() += 1;
+ aBoxPos.Y() += 1;
+ }
+ Size aBoxSize(3, 3);
+ mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
+ }
+}
+
+// ============================================================================
+
+ScMenuFloatingWindow::MenuItemData::MenuItemData() :
+ mbEnabled(true),
+ mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
+ mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
+ mpSubMenu(NULL),
+ mnMenuPos(MENU_NOT_SELECTED),
+ mpParent(pParent)
+{
+ maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
+ maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
+}
+
+void ScMenuFloatingWindow::SubMenuItemData::reset()
+{
+ mpSubMenu = NULL;
+ mnMenuPos = MENU_NOT_SELECTED;
+ maTimer.Stop();
+}
+
+IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG )
+{
+ mpParent->handleMenuTimeout(this);
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;
+
+ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) :
+ PopupMenuFloatingWindow(pParent),
+ maOpenTimer(this),
+ maCloseTimer(this),
+ maName(OUString::createFromAscii("ScMenuFloatingWindow")),
+ mnSelectedMenu(MENU_NOT_SELECTED),
+ mnClickedMenu(MENU_NOT_SELECTED),
+ mpDoc(pDoc),
+ mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
+ mpActiveSubMenu(NULL)
+{
+ SetMenuStackLevel(nMenuStackLevel);
+
+ // TODO: How do we get the right font to use here ?
+ const sal_uInt16 nPopupFontHeight = 12;
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ maLabelFont = rStyle.GetLabelFont();
+ maLabelFont.SetHeight(nPopupFontHeight);
+ SetFont(maLabelFont);
+
+ SetText(OUString::createFromAscii("ScMenuFloatingWindow"));
+ SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) );
+}
+
+ScMenuFloatingWindow::~ScMenuFloatingWindow()
+{
+ EndPopupMode();
+}
+
+void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
+{
+ const Point& rPos = rMEvt.GetPosPixel();
+ size_t nSelectedMenu = getEnclosingMenuItem(rPos);
+ setSelectedMenuItem(nSelectedMenu, true, false);
+
+ Window::MouseMove(rMEvt);
+}
+
+void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ const Point& rPos = rMEvt.GetPosPixel();
+ mnClickedMenu = getEnclosingMenuItem(rPos);
+ Window::MouseButtonDown(rMEvt);
+}
+
+void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ executeMenuItem(mnClickedMenu);
+ mnClickedMenu = MENU_NOT_SELECTED;
+ Window::MouseButtonUp(rMEvt);
+}
+
+void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ bool bHandled = true;
+ size_t nSelectedMenu = mnSelectedMenu;
+ size_t nLastMenuPos = maMenuItems.size() - 1;
+ switch (rKeyCode.GetCode())
+ {
+ case KEY_UP:
+ if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
+ nSelectedMenu = nLastMenuPos;
+ else
+ --nSelectedMenu;
+ setSelectedMenuItem(nSelectedMenu, false, false);
+ break;
+ case KEY_DOWN:
+ if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
+ nSelectedMenu = 0;
+ else
+ ++nSelectedMenu;
+ setSelectedMenuItem(nSelectedMenu, false, false);
+ break;
+ case KEY_LEFT:
+ if (mpParentMenu)
+ mpParentMenu->endSubMenu(this);
+ break;
+ case KEY_RIGHT:
+ {
+ if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
+ break;
+
+ const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
+ if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
+ break;
+
+ maOpenTimer.mnMenuPos = mnSelectedMenu;
+ maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
+ launchSubMenu(true);
+ }
+ break;
+ case KEY_RETURN:
+ if (nSelectedMenu != MENU_NOT_SELECTED)
+ executeMenuItem(nSelectedMenu);
+ break;
+ default:
+ bHandled = false;
+ }
+
+ if (!bHandled)
+ Window::KeyInput(rKEvt);
+}
+
+void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
+{
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ Color aBackColor = rStyle.GetMenuColor();
+ Color aBorderColor = rStyle.GetShadowColor();
+
+ Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
+
+ // Window background
+ bool bNativeDrawn = true;
+ if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
+ {
+ SetClipRegion();
+ bNativeDrawn = DrawNativeControl(
+ CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
+ ImplControlValue(), OUString());
+ }
+ else
+ bNativeDrawn = false;
+
+ if (!bNativeDrawn)
+ {
+ SetFillColor(aBackColor);
+ SetLineColor(aBorderColor);
+ DrawRect(aCtrlRect);
+ }
+
+ // Menu items
+ SetTextColor(rStyle.GetMenuTextColor());
+ drawAllMenuItems();
+}
+
+Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
+{
+ if (!mxAccessible.is())
+ {
+ Reference<XAccessible> xAccParent = mpParentMenu ?
+ mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
+
+ mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc()));
+ ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
+ mxAccessible.get());
+
+ vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ size_t nPos = ::std::distance(itrBeg, itr);
+ p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
+ }
+ }
+
+ return mxAccessible;
+}
+
+void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
+{
+ MenuItemData aItem;
+ aItem.maText = rText;
+ aItem.mbEnabled = bEnabled;
+ aItem.mpAction.reset(pAction);
+ maMenuItems.push_back(aItem);
+}
+
+ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
+{
+ MenuItemData aItem;
+ aItem.maText = rText;
+ aItem.mbEnabled = bEnabled;
+ aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
+ aItem.mpSubMenuWin->setName(rText);
+ maMenuItems.push_back(aItem);
+ return aItem.mpSubMenuWin.get();
+}
+
+void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
+{
+ if (nPos >= maMenuItems.size())
+ return;
+
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nPos, aPos, aSize);
+
+ DecorationView aDecoView(this);
+ long nXOffset = 5;
+ long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
+ DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
+ maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
+
+ if (maMenuItems[nPos].mpSubMenuWin)
+ {
+ long nFontHeight = maLabelFont.GetHeight();
+ Point aMarkerPos = aPos;
+ aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
+ aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
+ Size aMarkerSize(nFontHeight/2, nFontHeight/2);
+ aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
+ SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
+ }
+}
+
+void ScMenuFloatingWindow::drawAllMenuItems()
+{
+ size_t n = maMenuItems.size();
+ for (size_t i = 0; i < n; ++i)
+ highlightMenuItem(i, i == mnSelectedMenu);
+}
+
+const Font& ScMenuFloatingWindow::getLabelFont() const
+{
+ return maLabelFont;
+}
+
+void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
+{
+ if (nPos >= maMenuItems.size())
+ return;
+
+ if (!maMenuItems[nPos].mpAction)
+ // no action is defined.
+ return;
+
+ maMenuItems[nPos].mpAction->execute();
+ terminateAllPopupMenus();
+}
+
+void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
+{
+ if (mnSelectedMenu == nPos)
+ // nothing to do.
+ return;
+
+ if (bEnsureSubMenu)
+ {
+ // Dismiss any child popup menu windows.
+ if (mnSelectedMenu < maMenuItems.size() &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
+ {
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
+ }
+
+ // The popup is not visible, yet a menu item is selected. The request
+ // most likely comes from the accessible object. Make sure this
+ // window, as well as all its parent windows are visible.
+ if (!IsVisible() && mpParentMenu)
+ mpParentMenu->ensureSubMenuVisible(this);
+ }
+
+ selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
+ selectMenuItem(nPos, true, bSubMenuTimer);
+ mnSelectedMenu = nPos;
+
+ fireMenuHighlightedEvent();
+}
+
+size_t ScMenuFloatingWindow::getSelectedMenuItem() const
+{
+ return mnSelectedMenu;
+}
+
+void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
+{
+ if (pTimer == &maOpenTimer)
+ {
+ // Close any open submenu immediately.
+ if (maCloseTimer.mpSubMenu)
+ {
+ maCloseTimer.mpSubMenu->EndPopupMode();
+ maCloseTimer.mpSubMenu = NULL;
+ maCloseTimer.maTimer.Stop();
+ }
+
+ launchSubMenu(false);
+ }
+ else if (pTimer == &maCloseTimer)
+ {
+ // end submenu.
+ if (maCloseTimer.mpSubMenu)
+ {
+ maOpenTimer.mpSubMenu = NULL;
+
+ maCloseTimer.mpSubMenu->EndPopupMode();
+ maCloseTimer.mpSubMenu = NULL;
+
+ highlightMenuItem(maOpenTimer.mnMenuPos, false);
+ maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
+ }
+ }
+}
+
+void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
+{
+ if (!pMenu)
+ return;
+
+ // Set the submenu on launch queue.
+ if (maOpenTimer.mpSubMenu)
+ {
+ if (maOpenTimer.mpSubMenu == pMenu)
+ {
+ if (pMenu == maCloseTimer.mpSubMenu)
+ maCloseTimer.reset();
+ return;
+ }
+
+ // new submenu is being requested.
+ queueCloseSubMenu();
+ }
+
+ maOpenTimer.mpSubMenu = pMenu;
+ maOpenTimer.mnMenuPos = nPos;
+ maOpenTimer.maTimer.Start();
+}
+
+void ScMenuFloatingWindow::queueCloseSubMenu()
+{
+ if (!maOpenTimer.mpSubMenu)
+ // There is no submenu to close.
+ return;
+
+ // Stop any submenu on queue for opening.
+ maOpenTimer.maTimer.Stop();
+
+ maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
+ maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
+ maCloseTimer.maTimer.Start();
+}
+
+void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
+{
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
+ ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
+
+ if (!pSubMenu)
+ return;
+
+ sal_uInt32 nOldFlags = GetPopupModeFlags();
+ SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
+ pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
+ pSubMenu->StartPopupMode(
+ Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
+ pSubMenu->AddPopupModeWindow(this);
+ if (bSetMenuPos)
+ pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
+ SetPopupModeFlags(nOldFlags);
+}
+
+void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
+{
+ if (!pSubMenu)
+ return;
+
+ pSubMenu->EndPopupMode();
+ maOpenTimer.reset();
+
+ size_t nMenuPos = getSubMenuPos(pSubMenu);
+ if (nMenuPos != MENU_NOT_SELECTED)
+ {
+ highlightMenuItem(nMenuPos, true);
+ mnSelectedMenu = nMenuPos;
+ fireMenuHighlightedEvent();
+ }
+}
+
+void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
+{
+ vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ size_t nPos = ::std::distance(itrBeg, itr);
+ pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
+ }
+}
+
+ScDocument* ScMenuFloatingWindow::getDoc()
+{
+ return mpDoc;
+}
+
+void ScMenuFloatingWindow::resizeToFitMenuItems()
+{
+ if (maMenuItems.empty())
+ return;
+
+ vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
+ long nTextWidth = 0;
+ for (; itr != itrEnd; ++itr)
+ nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
+
+ size_t nLastPos = maMenuItems.size()-1;
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nLastPos, aPos, aSize);
+ aPos.X() += nTextWidth + 15;
+ aPos.Y() += aSize.Height() + 5;
+ SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
+}
+
+void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
+{
+ if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
+ {
+ queueCloseSubMenu();
+ return;
+ }
+
+ if (!maMenuItems[nPos].mbEnabled)
+ {
+ queueCloseSubMenu();
+ return;
+ }
+
+ highlightMenuItem(nPos, bSelected);
+
+ if (bSelected)
+ {
+ if (mpParentMenu)
+ mpParentMenu->setSubMenuFocused(this);
+
+ if (bSubMenuTimer)
+ {
+ if (maMenuItems[nPos].mpSubMenuWin)
+ {
+ ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
+ queueLaunchSubMenu(nPos, pSubMenu);
+ }
+ else
+ queueCloseSubMenu();
+ }
+ }
+}
+
+void ScMenuFloatingWindow::clearSelectedMenuItem()
+{
+ selectMenuItem(mnSelectedMenu, false, false);
+ mnSelectedMenu = MENU_NOT_SELECTED;
+}
+
+ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
+{
+ if (maMenuItems.size() <= nPos)
+ return NULL;
+
+ return maMenuItems[nPos].mpSubMenuWin.get();
+}
+
+bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
+{
+ return nPos == mnSelectedMenu;
+}
+
+void ScMenuFloatingWindow::setName(const OUString& rName)
+{
+ maName = rName;
+}
+
+const OUString& ScMenuFloatingWindow::getName() const
+{
+ return maName;
+}
+
+void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
+{
+ if (nPos == MENU_NOT_SELECTED)
+ return;
+
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ Color aBackColor = rStyle.GetMenuColor();
+ SetFillColor(aBackColor);
+ SetLineColor(aBackColor);
+
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nPos, aPos, aSize);
+ Rectangle aRegion(aPos,aSize);
+
+ if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
+ {
+ Push(PUSH_CLIPREGION);
+ IntersectClipRegion(Rectangle(aPos, aSize));
+ Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
+ DrawNativeControl(
+ CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
+ ImplControlValue(), OUString());
+
+ Pop();
+ }
+
+ bool bNativeDrawn = true;
+ if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
+ {
+ ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
+ if (maMenuItems[nPos].mbEnabled)
+ nState |= CTRL_STATE_ENABLED;
+ bNativeDrawn = DrawNativeControl(
+ CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
+ }
+ else
+ bNativeDrawn = false;
+
+ if (!bNativeDrawn)
+ {
+ if (bSelected)
+ {
+ aBackColor = rStyle.GetMenuHighlightColor();
+ SetFillColor(aBackColor);
+ SetLineColor(aBackColor);
+ }
+ DrawRect(Rectangle(aPos,aSize));
+ }
+
+ Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
+ SetTextColor(aTextColor);
+ drawMenuItem(nPos);
+}
+
+void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
+{
+ const sal_uInt16 nLeftMargin = 5;
+ const sal_uInt16 nTopMargin = 5;
+ const sal_uInt16 nMenuItemHeight = static_cast< sal_uInt16 >( maLabelFont.GetHeight()*1.8 );
+
+ Size aWndSize = GetSizePixel();
+
+ Point aPos1(nLeftMargin, nTopMargin);
+ Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);
+
+ rPos = aPos1;
+ rPos.Y() += aSize1.Height()*nPos;
+ rSize = aSize1;
+}
+
+ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
+{
+ return mpParentMenu;
+}
+
+size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
+{
+ size_t n = maMenuItems.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(i, aPos, aSize);
+ Rectangle aRect(aPos, aSize);
+ if (aRect.IsInside(rPos))
+ return i;
+ }
+ return MENU_NOT_SELECTED;
+}
+
+size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
+{
+ size_t n = maMenuItems.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
+ return i;
+ }
+ return MENU_NOT_SELECTED;
+}
+
+void ScMenuFloatingWindow::fireMenuHighlightedEvent()
+{
+ if (mnSelectedMenu == MENU_NOT_SELECTED)
+ return;
+
+ if (!mxAccessible.is())
+ return;
+
+ Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
+ if (!xAccCxt.is())
+ return;
+
+ Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
+ if (!xAccMenu.is())
+ return;
+
+ VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
+ FireVclEvent(&aEvent);
+}
+
+void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
+{
+ maCloseTimer.reset();
+ size_t nMenuPos = getSubMenuPos(pSubMenu);
+ if (mnSelectedMenu != nMenuPos)
+ {
+ highlightMenuItem(nMenuPos, true);
+ mnSelectedMenu = nMenuPos;
+ }
+}
+
+void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
+{
+ if (mpParentMenu)
+ mpParentMenu->ensureSubMenuVisible(this);
+
+ if (pSubMenu->IsVisible())
+ return;
+
+ // Find the menu position of the submenu.
+ size_t nMenuPos = getSubMenuPos(pSubMenu);
+ if (nMenuPos != MENU_NOT_SELECTED)
+ {
+ setSelectedMenuItem(nMenuPos, false, false);
+
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nMenuPos, aPos, aSize);
+
+ sal_uInt32 nOldFlags = GetPopupModeFlags();
+ SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
+ pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
+ pSubMenu->StartPopupMode(
+ Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
+ pSubMenu->AddPopupModeWindow(this);
+ SetPopupModeFlags(nOldFlags);
+ }
+}
+
+void ScMenuFloatingWindow::ensureSubMenuNotVisible()
+{
+ if (mnSelectedMenu <= maMenuItems.size() &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
+ {
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
+ }
+
+ EndPopupMode();
+}
+
+void ScMenuFloatingWindow::terminateAllPopupMenus()
+{
+ EndPopupMode();
+ if (mpParentMenu)
+ mpParentMenu->terminateAllPopupMenus();
+}
+
+IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG )
+{
+ clearSelectedMenuItem();
+ return 0;
+}
+
+// ============================================================================
+
+ScDPFieldPopupWindow::Member::Member() :
+ mbVisible(true)
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
+ ::CancelButton(pParent), mpParent(pParent) {}
+
+void ScDPFieldPopupWindow::CancelButton::Click()
+{
+ mpParent->EndPopupMode();
+ ::CancelButton::Click();
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) :
+ ScMenuFloatingWindow(pParent, pDoc),
+ maChecks(this, 0),
+ maChkToggleAll(this, 0),
+ maBtnSelectSingle (this, 0),
+ maBtnUnselectSingle(this, 0),
+ maBtnOk(this),
+ maBtnCancel(this),
+ mnCurTabStop(0),
+ mpExtendedData(NULL),
+ mpOKAction(NULL),
+ maWndSize(240, 330),
+ mePrevToggleAllState(STATE_DONTKNOW)
+{
+ maTabStopCtrls.reserve(7);
+ maTabStopCtrls.push_back(this);
+ maTabStopCtrls.push_back(&maChecks);
+ maTabStopCtrls.push_back(&maChkToggleAll);
+ maTabStopCtrls.push_back(&maBtnSelectSingle);
+ maTabStopCtrls.push_back(&maBtnUnselectSingle);
+ maTabStopCtrls.push_back(&maBtnOk);
+ maTabStopCtrls.push_back(&maBtnCancel);
+
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+
+ Point aPos;
+ Size aSize;
+ getSectionPosSize(aPos, aSize, WHOLE);
+ SetOutputSizePixel(aSize);
+ Size aOutSize = GetOutputSizePixel();
+
+ getSectionPosSize(aPos, aSize, BTN_OK);
+ maBtnOk.SetPosSizePixel(aPos, aSize);
+ maBtnOk.SetFont(getLabelFont());
+ maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
+ maBtnOk.Show();
+
+ getSectionPosSize(aPos, aSize, BTN_CANCEL);
+ maBtnCancel.SetPosSizePixel(aPos, aSize);
+ maBtnCancel.SetFont(getLabelFont());
+ maBtnCancel.Show();
+
+ getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
+ maChecks.SetPosSizePixel(aPos, aSize);
+ maChecks.SetFont(getLabelFont());
+ maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) );
+ maChecks.Show();
+
+ getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
+ maChkToggleAll.SetPosSizePixel(aPos, aSize);
+ maChkToggleAll.SetFont(getLabelFont());
+ maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString());
+ maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
+ maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) );
+ maChkToggleAll.Show();
+
+ getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
+ maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
+ maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString());
+ maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL);
+ maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
+ maBtnSelectSingle.Show();
+
+ getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
+ maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
+ maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString());
+ maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL);
+ maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
+ maBtnUnselectSingle.Show();
+}
+
+ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
+{
+}
+
+void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
+{
+ // constant parameters.
+ const sal_uInt16 nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border.
+ const sal_uInt16 nListBoxInnerPadding = 5;
+ const sal_uInt16 nTopMargin = 5;
+ const sal_uInt16 nMenuHeight = 60;
+ const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
+ const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are.
+ const sal_uInt16 nBtnWidth = 90;
+ const sal_uInt16 nLabelHeight = static_cast< sal_uInt16 >( getLabelFont().GetHeight() );
+ const sal_uInt16 nBtnHeight = nLabelHeight*2;
+ const sal_uInt16 nBottomMargin = 10;
+ const sal_uInt16 nMenuListMargin = 20;
+
+ // parameters calculated from constants.
+ const sal_uInt16 nListBoxWidth = static_cast< sal_uInt16 >( maWndSize.Width() - nListBoxMargin*2 );
+ const sal_uInt16 nListBoxHeight = static_cast< sal_uInt16 >( maWndSize.Height() - nTopMargin - nMenuHeight -
+ nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight );
+
+ const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;
+
+ switch (eType)
+ {
+ case WHOLE:
+ {
+ rPos = Point(0, 0);
+ rSize = maWndSize;
+ }
+ break;
+ case LISTBOX_AREA_OUTER:
+ {
+ rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
+ rSize = Size(nListBoxWidth, nListBoxHeight);
+ }
+ break;
+ case LISTBOX_AREA_INNER:
+ {
+ rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
+ rPos.X() += nListBoxInnerPadding;
+ rPos.Y() += nListBoxInnerPadding;
+
+ rSize = Size(nListBoxWidth, nListBoxHeight);
+ rSize.Width() -= nListBoxInnerPadding*2;
+ rSize.Height() -= nListBoxInnerPadding*2;
+ }
+ break;
+ case SINGLE_BTN_AREA:
+ {
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
+ }
+ break;
+ case CHECK_TOGGLE_ALL:
+ {
+ long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height.
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rPos.X() += 5;
+ rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
+ rSize = Size(70, h);
+ }
+ break;
+ case BTN_SINGLE_SELECT:
+ {
+ long h = 26;
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rPos.X() += 150;
+ rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
+ rSize = Size(h, h);
+ }
+ break;
+ case BTN_SINGLE_UNSELECT:
+ {
+ long h = 26;
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rPos.X() += 150 + h + 10;
+ rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
+ rSize = Size(h, h);
+ }
+ break;
+ case BTN_OK:
+ {
+ long x = (maWndSize.Width() - nBtnWidth*2)/3;
+ long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
+ rPos = Point(x, y);
+ rSize = Size(nBtnWidth, nBtnHeight);
+ }
+ break;
+ case BTN_CANCEL:
+ {
+ long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
+ long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
+ rPos = Point(x, y);
+ rSize = Size(nBtnWidth, nBtnHeight);
+ }
+ break;
+ default:
+ ;
+ }
+}
+
+void ScDPFieldPopupWindow::setAllMemberState(bool bSet)
+{
+ size_t n = maMembers.size();
+ for (size_t i = 0; i < n; ++i)
+ maChecks.CheckEntryPos(static_cast< USHORT >( i ), bSet);
+}
+
+void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet)
+{
+ setAllMemberState(!bSet);
+ sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
+ maChecks.CheckEntryPos(nSelected, bSet);
+}
+
+void ScDPFieldPopupWindow::cycleFocus(bool bReverse)
+{
+ maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
+ maTabStopCtrls[mnCurTabStop]->LoseFocus();
+ if (mnCurTabStop == 0)
+ clearSelectedMenuItem();
+
+ if (bReverse)
+ {
+ if (mnCurTabStop > 0)
+ --mnCurTabStop;
+ else
+ mnCurTabStop = maTabStopCtrls.size() - 1;
+ }
+ else
+ {
+ ++mnCurTabStop;
+ if (mnCurTabStop >= maTabStopCtrls.size())
+ mnCurTabStop = 0;
+ }
+ maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
+ maTabStopCtrls[mnCurTabStop]->GrabFocus();
+}
+
+IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn )
+{
+ if (pBtn == &maBtnOk)
+ close(true);
+ else if (pBtn == &maBtnSelectSingle)
+ {
+ selectCurrentMemberOnly(true);
+ CheckHdl(&maChecks);
+ }
+ else if (pBtn == &maBtnUnselectSingle)
+ {
+ selectCurrentMemberOnly(false);
+ CheckHdl(&maChecks);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG )
+{
+ switch (mePrevToggleAllState)
+ {
+ case STATE_NOCHECK:
+ maChkToggleAll.SetState(STATE_CHECK);
+ setAllMemberState(true);
+ break;
+ case STATE_CHECK:
+ maChkToggleAll.SetState(STATE_NOCHECK);
+ setAllMemberState(false);
+ break;
+ case STATE_DONTKNOW:
+ default:
+ maChkToggleAll.SetState(STATE_CHECK);
+ setAllMemberState(true);
+ break;
+ }
+
+ mePrevToggleAllState = maChkToggleAll.GetState();
+ return 0;
+}
+
+IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks )
+{
+ if (pChecks != &maChecks)
+ return 0;
+
+ size_t nNumChecked = maChecks.GetCheckedEntryCount();
+ if (nNumChecked == maMembers.size())
+ // all members visible
+ maChkToggleAll.SetState(STATE_CHECK);
+ else if (nNumChecked == 0)
+ // no members visible
+ maChkToggleAll.SetState(STATE_NOCHECK);
+ else
+ maChkToggleAll.SetState(STATE_DONTKNOW);
+
+ mePrevToggleAllState = maChkToggleAll.GetState();
+ return 0;
+}
+
+void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
+{
+ ScMenuFloatingWindow::MouseMove(rMEvt);
+
+ size_t nSelectedMenu = getSelectedMenuItem();
+ if (nSelectedMenu == MENU_NOT_SELECTED)
+ queueCloseSubMenu();
+}
+
+long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt)
+{
+ switch (rNEvt.GetType())
+ {
+ case EVENT_KEYUP:
+ {
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rCode = pKeyEvent->GetKeyCode();
+ bool bShift = rCode.IsShift();
+ if (rCode.GetCode() == KEY_TAB)
+ {
+ cycleFocus(bShift);
+ return true;
+ }
+ }
+ break;
+ }
+ return ScMenuFloatingWindow::Notify(rNEvt);
+}
+
+void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
+{
+ ScMenuFloatingWindow::Paint(rRect);
+
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ Color aMemberBackColor = rStyle.GetFieldColor();
+ Color aBorderColor = rStyle.GetShadowColor();
+
+ Point aPos;
+ Size aSize;
+ getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
+
+ // Member list box background
+ SetFillColor(aMemberBackColor);
+ SetLineColor(aBorderColor);
+ DrawRect(Rectangle(aPos,aSize));
+
+ // Single-action button box
+ getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
+ SetFillColor(rStyle.GetMenuColor());
+ DrawRect(Rectangle(aPos,aSize));
+}
+
+Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow()
+{
+ return maTabStopCtrls[mnCurTabStop];
+}
+
+Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible()
+{
+ if (!mxAccessible.is())
+ {
+ mxAccessible.set(new ScAccessibleFilterTopWindow(
+ GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc()));
+ ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
+ fillMenuItemsToAccessible(pAccTop);
+
+ pAccTop->setAccessibleChild(
+ maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
+ pAccTop->setAccessibleChild(
+ maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
+ pAccTop->setAccessibleChild(
+ maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
+ pAccTop->setAccessibleChild(
+ maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
+ pAccTop->setAccessibleChild(
+ maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
+ pAccTop->setAccessibleChild(
+ maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
+ }
+
+ return mxAccessible;
+}
+
+void ScDPFieldPopupWindow::setMemberSize(size_t n)
+{
+ maMembers.reserve(n);
+}
+
+void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible)
+{
+ Member aMember;
+ aMember.maName = rName;
+ aMember.mbVisible = bVisible;
+ maMembers.push_back(aMember);
+}
+
+void ScDPFieldPopupWindow::initMembers()
+{
+ size_t n = maMembers.size();
+ size_t nVisMemCount = 0;
+ for (size_t i = 0; i < n; ++i)
+ {
+ maChecks.InsertEntry(maMembers[i].maName);
+ maChecks.CheckEntryPos(static_cast< USHORT >( i ), maMembers[i].mbVisible);
+ if (maMembers[i].mbVisible)
+ ++nVisMemCount;
+ }
+ if (nVisMemCount == n)
+ {
+ // all members visible
+ maChkToggleAll.SetState(STATE_CHECK);
+ mePrevToggleAllState = STATE_CHECK;
+ }
+ else if (nVisMemCount == 0)
+ {
+ // no members visible
+ maChkToggleAll.SetState(STATE_NOCHECK);
+ mePrevToggleAllState = STATE_NOCHECK;
+ }
+ else
+ {
+ maChkToggleAll.SetState(STATE_DONTKNOW);
+ mePrevToggleAllState = STATE_DONTKNOW;
+ }
+}
+
+const Size& ScDPFieldPopupWindow::getWindowSize() const
+{
+ return maWndSize;
+}
+
+void ScDPFieldPopupWindow::getResult(hash_map<OUString, bool, OUStringHash>& rResult)
+{
+ typedef hash_map<OUString, bool, OUStringHash> ResultMap;
+ ResultMap aResult;
+ size_t n = maMembers.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ bool bState = maChecks.IsChecked(static_cast< USHORT >( i ));
+ aResult.insert(ResultMap::value_type(maMembers[i].maName, bState));
+ }
+ rResult.swap(aResult);
+}
+
+void ScDPFieldPopupWindow::close(bool bOK)
+{
+ if (bOK && mpOKAction.get())
+ mpOKAction->execute();
+
+ EndPopupMode();
+}
+
+void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p)
+{
+ mpExtendedData.reset(p);
+}
+
+ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
+{
+ return mpExtendedData.get();
+}
+
+void ScDPFieldPopupWindow::setOKAction(Action* p)
+{
+ mpOKAction.reset(p);
+}
+
diff --git a/sc/source/ui/cctrl/dpcontrol.src b/sc/source/ui/cctrl/dpcontrol.src
new file mode 100644
index 000000000000..b38548369be5
--- /dev/null
+++ b/sc/source/ui/cctrl/dpcontrol.src
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dpcontrol.hrc"
+
+Resource RID_POPUP_FILTER
+{
+ String STR_MENU_SORT_ASC
+ {
+ Text [ en-US ] = "Sort Ascending" ;
+ };
+
+ String STR_MENU_SORT_DESC
+ {
+ Text [ en-US ] = "Sort Descending" ;
+ };
+
+ String STR_MENU_SORT_CUSTOM
+ {
+ Text [ en-US ] = "Custom Sort" ;
+ };
+
+ String STR_BTN_TOGGLE_ALL
+ {
+ Text [ en-US ] = "All" ;
+ };
+
+ String STR_BTN_SELECT_CURRENT
+ {
+ Text [ en-US ] = "Show only the current item." ;
+ };
+
+ String STR_BTN_UNSELECT_CURRENT
+ {
+ Text [ en-US ] = "Hide only the current item." ;
+ };
+};
+
+Image RID_IMG_SELECT_CURRENT
+{
+ ImageBitmap = Bitmap
+ {
+ File = "popup_select_current.png";
+ };
+ MaskColor = STD_MASKCOLOR;
+};
+
+Image RID_IMG_UNSELECT_CURRENT
+{
+ ImageBitmap = Bitmap
+ {
+ File = "popup_unselect_current.png";
+ };
+ MaskColor = STD_MASKCOLOR;
+};
diff --git a/sc/source/ui/cctrl/editfield.cxx b/sc/source/ui/cctrl/editfield.cxx
new file mode 100644
index 000000000000..4358694f6b04
--- /dev/null
+++ b/sc/source/ui/cctrl/editfield.cxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#ifdef SC_DLLIMPLEMENTATION
+#undef SC_DLLIMPLEMENTATION
+#endif
+#include "editfield.hxx"
+#include <rtl/math.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include "global.hxx"
+
+// ============================================================================
+
+namespace {
+
+sal_Unicode lclGetDecSep()
+{
+ return ScGlobal::GetpLocaleData()->getNumDecimalSep().GetChar( 0 );
+}
+
+sal_Unicode lclGetGroupSep()
+{
+ return ScGlobal::GetpLocaleData()->getNumThousandSep().GetChar( 0 );
+}
+
+} // namespace
+
+// ============================================================================
+
+ScDoubleField::ScDoubleField( Window* pParent, const ResId& rResId ) :
+ Edit( pParent, rResId )
+{
+}
+
+bool ScDoubleField::GetValue( double& rfValue ) const
+{
+ String aStr( GetText() );
+ aStr.EraseLeadingAndTrailingChars( ' ' );
+ bool bOk = aStr.Len() > 0;
+ if( bOk )
+ {
+ rtl_math_ConversionStatus eStatus;
+ sal_Int32 nEnd;
+ rfValue = rtl::math::stringToDouble( aStr, lclGetDecSep(), lclGetGroupSep(), &eStatus, &nEnd );
+ bOk = (eStatus == rtl_math_ConversionStatus_Ok) && (nEnd == static_cast< sal_Int32 >( aStr.Len() ));
+ }
+ return bOk;
+}
+
+void ScDoubleField::SetValue( double fValue, sal_Int32 nDecPlaces, bool bEraseTrailingDecZeros )
+{
+ SetText( ::rtl::math::doubleToUString( fValue, rtl_math_StringFormat_G,
+ nDecPlaces, lclGetDecSep(), bEraseTrailingDecZeros ) );
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/cctrl/makefile.mk b/sc/source/ui/cctrl/makefile.mk
new file mode 100644
index 000000000000..531013ea1c2e
--- /dev/null
+++ b/sc/source/ui/cctrl/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=cctrl
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+EXCEPTIONSFILES= \
+ $(SLO)$/tbinsert.obj \
+ $(SLO)$/tbzoomsliderctrl.obj \
+ $(SLO)$/dpcontrol.obj
+
+SLOFILES = \
+ $(SLO)$/popmenu.obj \
+ $(SLO)$/tbinsert.obj \
+ $(SLO)$/cbuttonw.obj \
+ $(SLO)$/dpcontrol.obj \
+ $(SLO)$/editfield.obj \
+ $(EXCEPTIONSFILES)
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ dpcontrol.src
+
+LIB1TARGET=$(SLB)$/$(TARGET).lib
+LIB1OBJFILES= \
+ $(SLO)$/popmenu.obj \
+ $(SLO)$/tbinsert.obj \
+ $(SLO)$/cbuttonw.obj \
+ $(SLO)$/dpcontrol.obj \
+ $(SLO)$/tbzoomsliderctrl.obj
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/sc/source/ui/cctrl/popmenu.cxx b/sc/source/ui/cctrl/popmenu.cxx
new file mode 100644
index 000000000000..6510fff87ead
--- /dev/null
+++ b/sc/source/ui/cctrl/popmenu.cxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "popmenu.hxx"
+
+//------------------------------------------------------------------
+
+void __EXPORT ScPopupMenu::Select()
+{
+ nSel = GetCurItemId();
+ bHit = TRUE;
+}
+
+
+
diff --git a/sc/source/ui/cctrl/tbinsert.cxx b/sc/source/ui/cctrl/tbinsert.cxx
new file mode 100644
index 000000000000..e27baecec115
--- /dev/null
+++ b/sc/source/ui/cctrl/tbinsert.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+#include <string> // HACK: prevent conflict between STLPORT and Workshop headers
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/shl.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/imagemgr.hxx>
+#include <vcl/toolbox.hxx>
+
+#include "tbinsert.hxx"
+#include "tbinsert.hrc"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+
+// -----------------------------------------------------------------------
+
+SFX_IMPL_TOOLBOX_CONTROL( ScTbxInsertCtrl, SfxUInt16Item);
+
+//------------------------------------------------------------------
+//
+// ToolBox - Controller
+//
+//------------------------------------------------------------------
+
+ScTbxInsertCtrl::ScTbxInsertCtrl( USHORT nSlotId, USHORT nId, ToolBox& rTbx ) :
+ SfxToolBoxControl( nSlotId, nId, rTbx ),
+ nLastSlotId(0)
+{
+ rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
+}
+
+__EXPORT ScTbxInsertCtrl::~ScTbxInsertCtrl()
+{
+}
+
+void __EXPORT ScTbxInsertCtrl::StateChanged( USHORT /* nSID */, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SFX_ITEM_DISABLED) );
+
+ if( eState == SFX_ITEM_AVAILABLE )
+ {
+
+ const SfxUInt16Item* pItem = PTR_CAST( SfxUInt16Item, pState );
+ if(pItem)
+ {
+ nLastSlotId = pItem->GetValue();
+ USHORT nImageId = nLastSlotId ? nLastSlotId : GetSlotId();
+ rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aSlotURL += rtl::OUString::valueOf( sal_Int32( nImageId ));
+ Image aImage = GetImage( m_xFrame,
+ aSlotURL,
+ hasBigImages(),
+ GetToolBox().GetSettings().GetStyleSettings().GetHighContrastMode() );
+ GetToolBox().SetItemImage(GetId(), aImage);
+ }
+ }
+}
+
+SfxPopupWindow* __EXPORT ScTbxInsertCtrl::CreatePopupWindow()
+{
+// USHORT nWinResId, nTbxResId;
+ USHORT nSlotId = GetSlotId();
+ if (nSlotId == SID_TBXCTL_INSERT)
+ {
+ rtl::OUString aInsertBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertbar" ));
+ createAndPositionSubToolBar( aInsertBarResStr );
+// nWinResId = RID_TBXCTL_INSERT;
+// nTbxResId = RID_TOOLBOX_INSERT;
+ }
+ else if (nSlotId == SID_TBXCTL_INSCELLS)
+ {
+ rtl::OUString aInsertCellsBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertcellsbar" ));
+ createAndPositionSubToolBar( aInsertCellsBarResStr );
+// nWinResId = RID_TBXCTL_INSCELLS;
+// nTbxResId = RID_TOOLBOX_INSCELLS;
+ }
+ else /* SID_TBXCTL_INSOBJ */
+ {
+ rtl::OUString aInsertObjectBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertobjectbar" ));
+ createAndPositionSubToolBar( aInsertObjectBarResStr );
+// nWinResId = RID_TBXCTL_INSOBJ;
+// nTbxResId = RID_TOOLBOX_INSOBJ;
+ }
+/*
+ WindowAlign eNewAlign = ( GetToolBox().IsHorizontal() ) ? WINDOWALIGN_LEFT : WINDOWALIGN_TOP;
+ ScTbxInsertPopup *pWin = new ScTbxInsertPopup( nSlotId, eNewAlign,
+ ScResId(nWinResId), ScResId(nTbxResId), GetBindings() );
+ pWin->StartPopupMode(&GetToolBox(), TRUE);
+ pWin->StartSelection();
+ pWin->Show();
+ return pWin;
+*/
+ return NULL;
+}
+
+SfxPopupWindowType __EXPORT ScTbxInsertCtrl::GetPopupWindowType() const
+{
+ return nLastSlotId ? SFX_POPUPWINDOW_ONTIMEOUT : SFX_POPUPWINDOW_ONCLICK;
+}
+
+void __EXPORT ScTbxInsertCtrl::Select( BOOL /* bMod1 */ )
+{
+ SfxViewShell* pCurSh( SfxViewShell::Current() );
+ SfxDispatcher* pDispatch( 0 );
+
+ if ( pCurSh )
+ {
+ SfxViewFrame* pViewFrame = pCurSh->GetViewFrame();
+ if ( pViewFrame )
+ pDispatch = pViewFrame->GetDispatcher();
+ }
+
+ if ( pDispatch )
+ pDispatch->Execute(nLastSlotId);
+}
+/*
+//------------------------------------------------------------------
+//
+// Popup - Window
+//
+//------------------------------------------------------------------
+
+ScTbxInsertPopup::ScTbxInsertPopup( USHORT nId, WindowAlign eNewAlign,
+ const ResId& rRIdWin, const ResId& rRIdTbx,
+ SfxBindings& rBindings ) :
+ SfxPopupWindow ( nId, rRIdWin, rBindings),
+ aTbx ( this, GetBindings(), rRIdTbx ),
+ aRIdWinTemp(rRIdWin),
+ aRIdTbxTemp(rRIdTbx)
+{
+ aTbx.UseDefault();
+ FreeResource();
+
+ aTbx.GetToolBox().SetAlign( eNewAlign );
+ if (eNewAlign == WINDOWALIGN_LEFT || eNewAlign == WINDOWALIGN_RIGHT)
+ SetText( EMPTY_STRING );
+
+ Size aSize = aTbx.CalcWindowSizePixel();
+ aTbx.SetPosSizePixel( Point(), aSize );
+ SetOutputSizePixel( aSize );
+ aTbx.GetToolBox().SetSelectHdl( LINK(this, ScTbxInsertPopup, TbxSelectHdl));
+ aTbxClickHdl = aTbx.GetToolBox().GetClickHdl();
+ aTbx.GetToolBox().SetClickHdl( LINK(this, ScTbxInsertPopup, TbxClickHdl));
+}
+
+ScTbxInsertPopup::~ScTbxInsertPopup()
+{
+}
+
+SfxPopupWindow* __EXPORT ScTbxInsertPopup::Clone() const
+{
+ return new ScTbxInsertPopup( GetId(), aTbx.GetToolBox().GetAlign(),
+ aRIdWinTemp, aRIdTbxTemp,
+ (SfxBindings&) GetBindings() );
+}
+
+void ScTbxInsertPopup::StartSelection()
+{
+ aTbx.GetToolBox().StartSelection();
+}
+
+IMPL_LINK(ScTbxInsertPopup, TbxSelectHdl, ToolBox*, pBox)
+{
+ EndPopupMode();
+
+ USHORT nLastSlotId = pBox->GetCurItemId();
+ SfxUInt16Item aItem( GetId(), nLastSlotId );
+ SfxDispatcher* pDisp = GetBindings().GetDispatcher();
+ pDisp->Execute( GetId(), SFX_CALLMODE_SYNCHRON, &aItem, 0L );
+ pDisp->Execute( nLastSlotId, SFX_CALLMODE_ASYNCHRON );
+ return 0;
+}
+
+IMPL_LINK(ScTbxInsertPopup, TbxClickHdl, ToolBox*, pBox)
+{
+ USHORT nLastSlotId = pBox->GetCurItemId();
+ SfxUInt16Item aItem( GetId(), nLastSlotId );
+ GetBindings().GetDispatcher()->Execute( GetId(), SFX_CALLMODE_SYNCHRON, &aItem, 0L );
+ if(aTbxClickHdl.IsSet())
+ aTbxClickHdl.Call(pBox);
+ return 0;
+}
+
+void __EXPORT ScTbxInsertPopup::PopupModeEnd()
+{
+ aTbx.GetToolBox().EndSelection();
+ SfxPopupWindow::PopupModeEnd();
+}
+*/
+
+
diff --git a/sc/source/ui/cctrl/tbzoomsliderctrl.cxx b/sc/source/ui/cctrl/tbzoomsliderctrl.cxx
new file mode 100644
index 000000000000..7d43b31e0b30
--- /dev/null
+++ b/sc/source/ui/cctrl/tbzoomsliderctrl.cxx
@@ -0,0 +1,540 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+#include "precompiled_sc.hxx"
+#ifndef _SC_ZOOMSLIDERTBCONTRL_HXX
+#include "tbzoomsliderctrl.hxx"
+#endif
+#ifndef _SV_IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+#ifndef _SV_TOOLBOX_HXX
+#include <vcl/toolbox.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _SV_GRADIENT_HXX
+#include <vcl/gradient.hxx>
+#endif
+#include <svl/itemset.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/dialogs.hrc>
+#include <set>
+#include "docsh.hxx"
+#include "stlpool.hxx"
+#include "scitems.hxx"
+#include "printfun.hxx"
+
+//========================================================================
+// class ScZoomSliderControl ---------------------------------------
+//========================================================================
+
+// -----------------------------------------------------------------------
+
+SFX_IMPL_TOOLBOX_CONTROL( ScZoomSliderControl, SvxZoomSliderItem );
+
+// -----------------------------------------------------------------------
+
+ScZoomSliderControl::ScZoomSliderControl(
+ USHORT nSlotId,
+ USHORT nId,
+ ToolBox& rTbx )
+ :SfxToolBoxControl( nSlotId, nId, rTbx )
+{
+ rTbx.Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScZoomSliderControl::~ScZoomSliderControl()
+{
+
+}
+
+// -----------------------------------------------------------------------
+
+void ScZoomSliderControl::StateChanged( USHORT /*nSID*/, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ USHORT nId = GetId();
+ ToolBox& rTbx = GetToolBox();
+ ScZoomSliderWnd* pBox = (ScZoomSliderWnd*)(rTbx.GetItemWindow( nId ));
+ DBG_ASSERT( pBox ,"Control not found!" );
+
+ if ( SFX_ITEM_AVAILABLE != eState || pState->ISA( SfxVoidItem ) )
+ {
+ SvxZoomSliderItem aZoomSliderItem( 100 );
+ pBox->Disable();
+ pBox->UpdateFromItem( &aZoomSliderItem );
+ }
+ else
+ {
+ pBox->Enable();
+ DBG_ASSERT( pState->ISA( SvxZoomSliderItem ), "invalid item type" );
+ const SvxZoomSliderItem* pZoomSliderItem = dynamic_cast< const SvxZoomSliderItem* >( pState );
+
+ DBG_ASSERT( pZoomSliderItem, "Sc::ScZoomSliderControl::StateChanged(), wrong item type!" );
+ if( pZoomSliderItem )
+ pBox->UpdateFromItem( pZoomSliderItem );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Window* ScZoomSliderControl::CreateItemWindow( Window *pParent )
+{
+ // #i98000# Don't try to get a value via SfxViewFrame::Current here.
+ // The view's value is always notified via StateChanged later.
+ ScZoomSliderWnd* pSlider = new ScZoomSliderWnd( pParent,
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >( m_xFrame->getController(),
+ ::com::sun::star::uno::UNO_QUERY ), m_xFrame, 100 );
+ return pSlider;
+}
+
+// -----------------------------------------------------------------------
+
+struct ScZoomSliderWnd::ScZoomSliderWnd_Impl
+{
+ USHORT mnCurrentZoom;
+ USHORT mnMinZoom;
+ USHORT mnMaxZoom;
+ USHORT mnSliderCenter;
+ std::vector< long > maSnappingPointOffsets;
+ std::vector< USHORT > maSnappingPointZooms;
+ Image maSliderButton;
+ Image maIncreaseButton;
+ Image maDecreaseButton;
+ bool mbValuesSet;
+ bool mbOmitPaint;
+
+ ScZoomSliderWnd_Impl( USHORT nCurrentZoom ) :
+ mnCurrentZoom( nCurrentZoom ),
+ mnMinZoom( 10 ),
+ mnMaxZoom( 400 ),
+ mnSliderCenter( 100 ),
+ maSnappingPointOffsets(),
+ maSnappingPointZooms(),
+ maSliderButton(),
+ maIncreaseButton(),
+ maDecreaseButton(),
+ mbValuesSet( true ),
+ mbOmitPaint( false )
+ {
+
+ }
+};
+
+// -----------------------------------------------------------------------
+
+const long nButtonWidth = 10;
+const long nButtonHeight = 10;
+const long nIncDecWidth = 11;
+const long nIncDecHeight = 11;
+const long nSliderHeight = 2; //
+const long nSliderWidth = 4; //
+const long nSnappingHeight = 4;
+const long nSliderXOffset = 20;
+const long nSnappingEpsilon = 5; // snapping epsilon in pixels
+const long nSnappingPointsMinDist = nSnappingEpsilon; // minimum distance of two adjacent snapping points
+
+
+// -----------------------------------------------------------------------
+
+USHORT ScZoomSliderWnd::Offset2Zoom( long nOffset ) const
+{
+ Size aSliderWindowSize = GetOutputSizePixel();
+ const long nControlWidth = aSliderWindowSize.Width();
+ USHORT nRet = 0;
+
+ if( nOffset < nSliderXOffset )
+ return mpImpl->mnMinZoom;
+ if( nOffset > nControlWidth - nSliderXOffset )
+ return mpImpl->mnMaxZoom;
+
+ // check for snapping points:
+ USHORT nCount = 0;
+ std::vector< long >::iterator aSnappingPointIter;
+ for ( aSnappingPointIter = mpImpl->maSnappingPointOffsets.begin();
+ aSnappingPointIter != mpImpl->maSnappingPointOffsets.end();
+ ++aSnappingPointIter )
+ {
+ const long nCurrent = *aSnappingPointIter;
+ if ( Abs(nCurrent - nOffset) < nSnappingEpsilon )
+ {
+ nOffset = nCurrent;
+ nRet = mpImpl->maSnappingPointZooms[ nCount ];
+ break;
+ }
+ ++nCount;
+ }
+
+ if( 0 == nRet )
+ {
+ if( nOffset < nControlWidth / 2 )
+ {
+ // first half of slider
+ const long nFirstHalfRange = mpImpl->mnSliderCenter - mpImpl->mnMinZoom;
+ const long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
+ const long nZoomPerSliderPixel = (1000 * nFirstHalfRange) / nHalfSliderWidth;
+ const long nOffsetToSliderLeft = nOffset - nSliderXOffset;
+ nRet = mpImpl->mnMinZoom + USHORT( nOffsetToSliderLeft * nZoomPerSliderPixel / 1000 );
+ }
+ else
+ {
+ // second half of slider
+ const long nSecondHalfRange = mpImpl->mnMaxZoom - mpImpl->mnSliderCenter;
+ const long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
+ const long nZoomPerSliderPixel = 1000 * nSecondHalfRange / nHalfSliderWidth;
+ const long nOffsetToSliderCenter = nOffset - nControlWidth/2;
+ nRet = mpImpl->mnSliderCenter + USHORT( nOffsetToSliderCenter * nZoomPerSliderPixel / 1000 );
+ }
+ }
+
+ if( nRet < mpImpl->mnMinZoom )
+ return mpImpl->mnMinZoom;
+
+ else if( nRet > mpImpl->mnMaxZoom )
+ return mpImpl->mnMaxZoom;
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long ScZoomSliderWnd::Zoom2Offset( USHORT nCurrentZoom ) const
+{
+ Size aSliderWindowSize = GetOutputSizePixel();
+ const long nControlWidth = aSliderWindowSize.Width();
+ long nRect = nSliderXOffset;
+
+ const long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
+ if( nCurrentZoom <= mpImpl->mnSliderCenter )
+ {
+ nCurrentZoom = nCurrentZoom - mpImpl->mnMinZoom;
+ const long nFirstHalfRange = mpImpl->mnSliderCenter - mpImpl->mnMinZoom;
+ const long nSliderPixelPerZoomPercent = 1000 * nHalfSliderWidth / nFirstHalfRange;
+ const long nOffset = (nSliderPixelPerZoomPercent * nCurrentZoom) / 1000;
+ nRect += nOffset;
+ }
+ else
+ {
+ nCurrentZoom = nCurrentZoom - mpImpl->mnSliderCenter;
+ const long nSecondHalfRange = mpImpl->mnMaxZoom - mpImpl->mnSliderCenter;
+ const long nSliderPixelPerZoomPercent = 1000 * nHalfSliderWidth / nSecondHalfRange;
+ const long nOffset = (nSliderPixelPerZoomPercent * nCurrentZoom) / 1000;
+ nRect += nHalfSliderWidth + nOffset;
+ }
+ return nRect;
+}
+
+// -----------------------------------------------------------------------
+
+
+ScZoomSliderWnd::ScZoomSliderWnd( Window* pParent, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& _xFrame , USHORT nCurrentZoom ):
+ Window( pParent ),
+ mpImpl( new ScZoomSliderWnd_Impl( nCurrentZoom ) ),
+ aLogicalSize( 115, 40 ),
+ m_xDispatchProvider( rDispatchProvider ),
+ m_xFrame( _xFrame )
+{
+ BOOL bIsHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+ mpImpl->maSliderButton = Image( SVX_RES( bIsHC ? RID_SVXBMP_SLIDERBUTTON_HC : RID_SVXBMP_SLIDERBUTTON ) );
+ mpImpl->maIncreaseButton = Image( SVX_RES( bIsHC ? RID_SVXBMP_SLIDERINCREASE_HC : RID_SVXBMP_SLIDERINCREASE ) );
+ mpImpl->maDecreaseButton = Image( SVX_RES( bIsHC ? RID_SVXBMP_SLIDERDECREASE_HC : RID_SVXBMP_SLIDERDECREASE ) );
+ Size aSliderSize = LogicToPixel( Size( aLogicalSize), MapMode( MAP_10TH_MM ) );
+ SetSizePixel( Size( aSliderSize.Width() * nSliderWidth-1, aSliderSize.Height() + nSliderHeight ) );
+}
+
+// -----------------------------------------------------------------------
+
+ScZoomSliderWnd::~ScZoomSliderWnd()
+{
+ delete mpImpl;
+}
+
+// -----------------------------------------------------------------------
+
+void ScZoomSliderWnd::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !mpImpl->mbValuesSet )
+ return ;
+ Size aSliderWindowSize = GetOutputSizePixel();
+
+ const Point aPoint = rMEvt.GetPosPixel();
+
+ const long nButtonLeftOffset = ( nSliderXOffset - nIncDecWidth )/2;
+ const long nButtonRightOffset = ( nSliderXOffset + nIncDecWidth )/2;
+
+ const long nOldZoom = mpImpl->mnCurrentZoom;
+
+ // click to - button
+ if ( aPoint.X() >= nButtonLeftOffset && aPoint.X() <= nButtonRightOffset )
+ {
+ mpImpl->mnCurrentZoom = mpImpl->mnCurrentZoom - 5;
+ }
+ // click to + button
+ else if ( aPoint.X() >= aSliderWindowSize.Width() - nSliderXOffset + nButtonLeftOffset &&
+ aPoint.X() <= aSliderWindowSize.Width() - nSliderXOffset + nButtonRightOffset )
+ {
+ mpImpl->mnCurrentZoom = mpImpl->mnCurrentZoom + 5;
+ }
+ else if( aPoint.X() >= nSliderXOffset && aPoint.X() <= aSliderWindowSize.Width() - nSliderXOffset )
+ {
+ mpImpl->mnCurrentZoom = Offset2Zoom( aPoint.X() );
+ }
+
+ if( mpImpl->mnCurrentZoom < mpImpl->mnMinZoom )
+ mpImpl->mnCurrentZoom = mpImpl->mnMinZoom;
+ else if( mpImpl->mnCurrentZoom > mpImpl->mnMaxZoom )
+ mpImpl->mnCurrentZoom = mpImpl->mnMaxZoom;
+
+ if( nOldZoom == mpImpl->mnCurrentZoom )
+ return ;
+
+ Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
+
+ Paint( aRect );
+ mpImpl->mbOmitPaint = true;
+
+ SvxZoomSliderItem aZoomSliderItem( mpImpl->mnCurrentZoom );
+
+ ::com::sun::star::uno::Any a;
+ aZoomSliderItem.QueryValue( a );
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScalingFactor" ));
+ aArgs[0].Value = a;
+
+ SfxToolBoxControl::Dispatch( m_xDispatchProvider, String::CreateFromAscii(".uno:ScalingFactor"), aArgs );
+
+ mpImpl->mbOmitPaint = false;
+}
+
+// -----------------------------------------------------------------------
+
+void ScZoomSliderWnd::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !mpImpl->mbValuesSet )
+ return ;
+
+ Size aSliderWindowSize = GetOutputSizePixel();
+ const long nControlWidth = aSliderWindowSize.Width();
+ const short nButtons = rMEvt.GetButtons();
+
+ // check mouse move with button pressed
+ if ( 1 == nButtons )
+ {
+ const Point aPoint = rMEvt.GetPosPixel();
+
+ if ( aPoint.X() >= nSliderXOffset && aPoint.X() <= nControlWidth - nSliderXOffset )
+ {
+ mpImpl->mnCurrentZoom = Offset2Zoom( aPoint.X() );
+
+ Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
+ Paint( aRect );
+
+ mpImpl->mbOmitPaint = true; // optimization: paint before executing command,
+
+ // commit state change
+ SvxZoomSliderItem aZoomSliderItem( mpImpl->mnCurrentZoom );
+
+ ::com::sun::star::uno::Any a;
+ aZoomSliderItem.QueryValue( a );
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScalingFactor" ));
+ aArgs[0].Value = a;
+
+ SfxToolBoxControl::Dispatch( m_xDispatchProvider, String::CreateFromAscii(".uno:ScalingFactor"), aArgs );
+
+ mpImpl->mbOmitPaint = false;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScZoomSliderWnd::UpdateFromItem( const SvxZoomSliderItem* pZoomSliderItem )
+{
+ if( pZoomSliderItem )
+ {
+ mpImpl->mnCurrentZoom = pZoomSliderItem->GetValue();
+ mpImpl->mnMinZoom = pZoomSliderItem->GetMinZoom();
+ mpImpl->mnMaxZoom = pZoomSliderItem->GetMaxZoom();
+
+ DBG_ASSERT( mpImpl->mnMinZoom <= mpImpl->mnCurrentZoom &&
+ mpImpl->mnMinZoom < mpImpl->mnSliderCenter &&
+ mpImpl->mnMaxZoom >= mpImpl->mnCurrentZoom &&
+ mpImpl->mnMaxZoom > mpImpl->mnSliderCenter,
+ "Looks like the zoom slider item is corrupted" );
+ const com::sun::star::uno::Sequence < sal_Int32 > rSnappingPoints = pZoomSliderItem->GetSnappingPoints();
+ mpImpl->maSnappingPointOffsets.clear();
+ mpImpl->maSnappingPointZooms.clear();
+
+ // get all snapping points:
+ std::set< USHORT > aTmpSnappingPoints;
+ for ( USHORT j = 0; j < rSnappingPoints.getLength(); ++j )
+ {
+ const sal_Int32 nSnappingPoint = rSnappingPoints[j];
+ aTmpSnappingPoints.insert( (USHORT)nSnappingPoint );
+ }
+
+ // remove snapping points that are to close to each other:
+ std::set< USHORT >::iterator aSnappingPointIter;
+ long nLastOffset = 0;
+
+ for ( aSnappingPointIter = aTmpSnappingPoints.begin(); aSnappingPointIter != aTmpSnappingPoints.end(); ++aSnappingPointIter )
+ {
+ const USHORT nCurrent = *aSnappingPointIter;
+ const long nCurrentOffset = Zoom2Offset( nCurrent );
+
+ if ( nCurrentOffset - nLastOffset >= nSnappingPointsMinDist )
+ {
+ mpImpl->maSnappingPointOffsets.push_back( nCurrentOffset );
+ mpImpl->maSnappingPointZooms.push_back( nCurrent );
+ nLastOffset = nCurrentOffset;
+ }
+ }
+ }
+
+ Size aSliderWindowSize = GetOutputSizePixel();
+ Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
+
+ if ( !mpImpl->mbOmitPaint )
+ Paint(aRect);
+}
+
+// -----------------------------------------------------------------------
+
+void ScZoomSliderWnd::Paint( const Rectangle& rRect )
+{
+ DoPaint( rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ScZoomSliderWnd::DoPaint( const Rectangle& /*rRect*/ )
+{
+ if( mpImpl->mbOmitPaint )
+ return;
+
+ Size aSliderWindowSize = GetOutputSizePixel();
+ Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
+
+ VirtualDevice* pVDev = new VirtualDevice( *this );
+ pVDev->SetOutputSizePixel( aSliderWindowSize );
+
+ Rectangle aSlider = aRect;
+
+ aSlider.Top() += ( aSliderWindowSize.Height() - nSliderHeight )/2 - 1;
+ aSlider.Bottom() = aSlider.Top() + nSliderHeight;
+ aSlider.Left() += nSliderXOffset;
+ aSlider.Right() -= nSliderXOffset;
+
+ Rectangle aFirstLine( aSlider );
+ aFirstLine.Bottom() = aFirstLine.Top();
+
+ Rectangle aSecondLine( aSlider );
+ aSecondLine.Top() = aSecondLine.Bottom();
+
+ Rectangle aLeft( aSlider );
+ aLeft.Right() = aLeft.Left();
+
+ Rectangle aRight( aSlider );
+ aRight.Left() = aRight.Right();
+
+ // draw VirtualDevice's background color
+ Color aStartColor,aEndColor;
+ aStartColor = GetSettings().GetStyleSettings().GetFaceColor();
+ aEndColor = GetSettings().GetStyleSettings().GetFaceColor();
+ if( aEndColor.IsDark() )
+ aStartColor = aEndColor;
+
+ Gradient g;
+ g.SetAngle( 0 );
+ g.SetStyle( GRADIENT_LINEAR );
+
+ g.SetStartColor( aStartColor );
+ g.SetEndColor( aEndColor );
+ pVDev->DrawGradient( aRect, g );
+
+ // draw slider
+ pVDev->SetLineColor( Color ( COL_WHITE ) );
+ pVDev->DrawRect( aSecondLine );
+ pVDev->DrawRect( aRight );
+
+ pVDev->SetLineColor( Color( COL_GRAY ) );
+ pVDev->DrawRect( aFirstLine );
+ pVDev->DrawRect( aLeft );
+
+ // draw snapping points:
+ std::vector< long >::iterator aSnappingPointIter;
+ for ( aSnappingPointIter = mpImpl->maSnappingPointOffsets.begin();
+ aSnappingPointIter != mpImpl->maSnappingPointOffsets.end();
+ ++aSnappingPointIter )
+ {
+ pVDev->SetLineColor( Color( COL_GRAY ) );
+ Rectangle aSnapping( aRect );
+ aSnapping.Bottom() = aSlider.Top();
+ aSnapping.Top() = aSnapping.Bottom() - nSnappingHeight;
+ aSnapping.Left() += *aSnappingPointIter;
+ aSnapping.Right() = aSnapping.Left();
+ pVDev->DrawRect( aSnapping );
+
+ aSnapping.Top() += nSnappingHeight + nSliderHeight;
+ aSnapping.Bottom() += nSnappingHeight + nSliderHeight;
+ pVDev->DrawRect( aSnapping );
+ }
+
+ // draw slider button
+ Point aImagePoint = aRect.TopLeft();
+ aImagePoint.X() += Zoom2Offset( mpImpl->mnCurrentZoom );
+ aImagePoint.X() -= nButtonWidth/2;
+ aImagePoint.Y() += ( aSliderWindowSize.Height() - nButtonHeight)/2;
+ pVDev->DrawImage( aImagePoint, mpImpl->maSliderButton );
+
+ // draw decrease button
+ aImagePoint = aRect.TopLeft();
+ aImagePoint.X() += (nSliderXOffset - nIncDecWidth)/2;
+ aImagePoint.Y() += ( aSliderWindowSize.Height() - nIncDecHeight)/2;
+ pVDev->DrawImage( aImagePoint, mpImpl->maDecreaseButton );
+
+ // draw increase button
+ aImagePoint.X() = aRect.TopLeft().X() + aSliderWindowSize.Width() - nIncDecWidth - (nSliderXOffset - nIncDecWidth)/2;
+ pVDev->DrawImage( aImagePoint, mpImpl->maIncreaseButton );
+
+ DrawOutDev( Point(0, 0), aSliderWindowSize, Point(0, 0), aSliderWindowSize, *pVDev );
+
+ delete pVDev;
+
+}
+
+// -----------------------------------------------------------------------
diff --git a/sc/source/ui/dbgui/asciiopt.cxx b/sc/source/ui/dbgui/asciiopt.cxx
new file mode 100644
index 000000000000..a22953ade25b
--- /dev/null
+++ b/sc/source/ui/dbgui/asciiopt.cxx
@@ -0,0 +1,480 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "global.hxx"
+#include "scresid.hxx"
+#include "impex.hxx"
+#include "asciiopt.hxx"
+#include "asciiopt.hrc"
+#include <tools/debug.hxx>
+#include <rtl/tencinfo.h>
+#include <unotools/transliterationwrapper.hxx>
+// ause
+#include "editutil.hxx"
+
+// ============================================================================
+
+static const sal_Char __FAR_DATA pStrFix[] = "FIX";
+static const sal_Char __FAR_DATA pStrMrg[] = "MRG";
+
+
+// ============================================================================
+
+ScAsciiOptions::ScAsciiOptions() :
+ bFixedLen ( FALSE ),
+ aFieldSeps ( ';' ),
+ bMergeFieldSeps ( FALSE ),
+ bQuotedFieldAsText(false),
+ bDetectSpecialNumber(false),
+ cTextSep ( cDefaultTextSep ),
+ eCharSet ( gsl_getSystemTextEncoding() ),
+ eLang ( LANGUAGE_SYSTEM ),
+ bCharSetSystem ( FALSE ),
+ nStartRow ( 1 ),
+ nInfoCount ( 0 ),
+ pColStart ( NULL ),
+ pColFormat ( NULL )
+{
+}
+
+
+ScAsciiOptions::ScAsciiOptions(const ScAsciiOptions& rOpt) :
+ bFixedLen ( rOpt.bFixedLen ),
+ aFieldSeps ( rOpt.aFieldSeps ),
+ bMergeFieldSeps ( rOpt.bMergeFieldSeps ),
+ bQuotedFieldAsText(rOpt.bQuotedFieldAsText),
+ bDetectSpecialNumber(rOpt.bDetectSpecialNumber),
+ cTextSep ( rOpt.cTextSep ),
+ eCharSet ( rOpt.eCharSet ),
+ eLang ( rOpt.eLang ),
+ bCharSetSystem ( rOpt.bCharSetSystem ),
+ nStartRow ( rOpt.nStartRow ),
+ nInfoCount ( rOpt.nInfoCount )
+{
+ if (nInfoCount)
+ {
+ pColStart = new xub_StrLen[nInfoCount];
+ pColFormat = new BYTE[nInfoCount];
+ for (USHORT i=0; i<nInfoCount; i++)
+ {
+ pColStart[i] = rOpt.pColStart[i];
+ pColFormat[i] = rOpt.pColFormat[i];
+ }
+ }
+ else
+ {
+ pColStart = NULL;
+ pColFormat = NULL;
+ }
+}
+
+
+ScAsciiOptions::~ScAsciiOptions()
+{
+ delete[] pColStart;
+ delete[] pColFormat;
+}
+
+
+void ScAsciiOptions::SetColInfo( USHORT nCount, const xub_StrLen* pStart, const BYTE* pFormat )
+{
+ delete[] pColStart;
+ delete[] pColFormat;
+
+ nInfoCount = nCount;
+
+ if (nInfoCount)
+ {
+ pColStart = new xub_StrLen[nInfoCount];
+ pColFormat = new BYTE[nInfoCount];
+ for (USHORT i=0; i<nInfoCount; i++)
+ {
+ pColStart[i] = pStart[i];
+ pColFormat[i] = pFormat[i];
+ }
+ }
+ else
+ {
+ pColStart = NULL;
+ pColFormat = NULL;
+ }
+}
+
+
+void ScAsciiOptions::SetColumnInfo( const ScCsvExpDataVec& rDataVec )
+{
+ delete[] pColStart;
+ pColStart = NULL;
+ delete[] pColFormat;
+ pColFormat = NULL;
+
+ nInfoCount = static_cast< sal_uInt16 >( rDataVec.size() );
+ if( nInfoCount )
+ {
+ pColStart = new xub_StrLen[ nInfoCount ];
+ pColFormat = new sal_uInt8[ nInfoCount ];
+ for( sal_uInt16 nIx = 0; nIx < nInfoCount; ++nIx )
+ {
+ pColStart[ nIx ] = rDataVec[ nIx ].mnIndex;
+ pColFormat[ nIx ] = rDataVec[ nIx ].mnType;
+ }
+ }
+}
+
+
+ScAsciiOptions& ScAsciiOptions::operator=( const ScAsciiOptions& rCpy )
+{
+ SetColInfo( rCpy.nInfoCount, rCpy.pColStart, rCpy.pColFormat );
+
+ bFixedLen = rCpy.bFixedLen;
+ aFieldSeps = rCpy.aFieldSeps;
+ bMergeFieldSeps = rCpy.bMergeFieldSeps;
+ bQuotedFieldAsText = rCpy.bQuotedFieldAsText;
+ cTextSep = rCpy.cTextSep;
+ eCharSet = rCpy.eCharSet;
+ bCharSetSystem = rCpy.bCharSetSystem;
+ nStartRow = rCpy.nStartRow;
+
+ return *this;
+}
+
+
+BOOL ScAsciiOptions::operator==( const ScAsciiOptions& rCmp ) const
+{
+ if ( bFixedLen == rCmp.bFixedLen &&
+ aFieldSeps == rCmp.aFieldSeps &&
+ bMergeFieldSeps == rCmp.bMergeFieldSeps &&
+ bQuotedFieldAsText == rCmp.bQuotedFieldAsText &&
+ cTextSep == rCmp.cTextSep &&
+ eCharSet == rCmp.eCharSet &&
+ bCharSetSystem == rCmp.bCharSetSystem &&
+ nStartRow == rCmp.nStartRow &&
+ nInfoCount == rCmp.nInfoCount )
+ {
+ DBG_ASSERT( !nInfoCount || (pColStart && pColFormat && rCmp.pColStart && rCmp.pColFormat),
+ "0-Zeiger in ScAsciiOptions" );
+ for (USHORT i=0; i<nInfoCount; i++)
+ if ( pColStart[i] != rCmp.pColStart[i] ||
+ pColFormat[i] != rCmp.pColFormat[i] )
+ return FALSE;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//
+// Der Options-String darf kein Semikolon mehr enthalten (wegen Pickliste)
+// darum ab Version 336 Komma stattdessen
+//
+
+
+void ScAsciiOptions::ReadFromString( const String& rString )
+{
+ xub_StrLen nCount = rString.GetTokenCount(',');
+ String aToken;
+ xub_StrLen nSub;
+ xub_StrLen i;
+
+ //
+ // Feld-Trenner
+ //
+
+ if ( nCount >= 1 )
+ {
+ bFixedLen = bMergeFieldSeps = FALSE;
+ aFieldSeps.Erase();
+
+ aToken = rString.GetToken(0,',');
+ if ( aToken.EqualsAscii(pStrFix) )
+ bFixedLen = TRUE;
+ nSub = aToken.GetTokenCount('/');
+ for ( i=0; i<nSub; i++ )
+ {
+ String aCode = aToken.GetToken( i, '/' );
+ if ( aCode.EqualsAscii(pStrMrg) )
+ bMergeFieldSeps = TRUE;
+ else
+ {
+ sal_Int32 nVal = aCode.ToInt32();
+ if ( nVal )
+ aFieldSeps += (sal_Unicode) nVal;
+ }
+ }
+ }
+
+ //
+ // Text-Trenner
+ //
+
+ if ( nCount >= 2 )
+ {
+ aToken = rString.GetToken(1,',');
+ sal_Int32 nVal = aToken.ToInt32();
+ cTextSep = (sal_Unicode) nVal;
+ }
+
+ //
+ // Zeichensatz
+ //
+
+ if ( nCount >= 3 )
+ {
+ aToken = rString.GetToken(2,',');
+ eCharSet = ScGlobal::GetCharsetValue( aToken );
+ }
+
+ //
+ // Startzeile
+ //
+
+ if ( nCount >= 4 )
+ {
+ aToken = rString.GetToken(3,',');
+ nStartRow = aToken.ToInt32();
+ }
+
+ //
+ // Spalten-Infos
+ //
+
+ if ( nCount >= 5 )
+ {
+ delete[] pColStart;
+ delete[] pColFormat;
+
+ aToken = rString.GetToken(4,',');
+ nSub = aToken.GetTokenCount('/');
+ nInfoCount = nSub / 2;
+ if (nInfoCount)
+ {
+ pColStart = new xub_StrLen[nInfoCount];
+ pColFormat = new BYTE[nInfoCount];
+ for (USHORT nInfo=0; nInfo<nInfoCount; nInfo++)
+ {
+ pColStart[nInfo] = (xub_StrLen) aToken.GetToken( 2*nInfo, '/' ).ToInt32();
+ pColFormat[nInfo] = (BYTE) aToken.GetToken( 2*nInfo+1, '/' ).ToInt32();
+ }
+ }
+ else
+ {
+ pColStart = NULL;
+ pColFormat = NULL;
+ }
+ }
+
+ // Language
+ if (nCount >= 6)
+ {
+ aToken = rString.GetToken(5, ',');
+ eLang = static_cast<LanguageType>(aToken.ToInt32());
+ }
+
+ // Import quoted field as text.
+ if (nCount >= 7)
+ {
+ aToken = rString.GetToken(6, ',');
+ bQuotedFieldAsText = aToken.EqualsAscii("true") ? true : false;
+ }
+
+ // Detect special nubmers.
+ if (nCount >= 8)
+ {
+ aToken = rString.GetToken(7, ',');
+ bDetectSpecialNumber = aToken.EqualsAscii("true") ? true : false;
+ }
+}
+
+
+String ScAsciiOptions::WriteToString() const
+{
+ String aOutStr;
+
+ //
+ // Feld-Trenner
+ //
+
+ if ( bFixedLen )
+ aOutStr.AppendAscii(pStrFix);
+ else if ( !aFieldSeps.Len() )
+ aOutStr += '0';
+ else
+ {
+ xub_StrLen nLen = aFieldSeps.Len();
+ for (xub_StrLen i=0; i<nLen; i++)
+ {
+ if (i)
+ aOutStr += '/';
+ aOutStr += String::CreateFromInt32(aFieldSeps.GetChar(i));
+ }
+ if ( bMergeFieldSeps )
+ {
+ aOutStr += '/';
+ aOutStr.AppendAscii(pStrMrg);
+ }
+ }
+
+ aOutStr += ','; // Token-Ende
+
+ //
+ // Text-Trenner
+ //
+
+ aOutStr += String::CreateFromInt32(cTextSep);
+ aOutStr += ','; // Token-Ende
+
+ //
+ // Zeichensatz
+ //
+
+ if ( bCharSetSystem ) // force "SYSTEM"
+ aOutStr += ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW );
+ else
+ aOutStr += ScGlobal::GetCharsetString( eCharSet );
+ aOutStr += ','; // Token-Ende
+
+ //
+ // Startzeile
+ //
+
+ aOutStr += String::CreateFromInt32(nStartRow);
+ aOutStr += ','; // Token-Ende
+
+ //
+ // Spalten-Infos
+ //
+
+ DBG_ASSERT( !nInfoCount || (pColStart && pColFormat), "0-Zeiger in ScAsciiOptions" );
+ for (USHORT nInfo=0; nInfo<nInfoCount; nInfo++)
+ {
+ if (nInfo)
+ aOutStr += '/';
+ aOutStr += String::CreateFromInt32(pColStart[nInfo]);
+ aOutStr += '/';
+ aOutStr += String::CreateFromInt32(pColFormat[nInfo]);
+ }
+
+ // #i112025# the options string is used in macros and linked sheets,
+ // so new options must be added at the end, to remain compatible
+
+ aOutStr += ',';
+
+ // Language
+ aOutStr += String::CreateFromInt32(eLang);
+ aOutStr += ',';
+
+ // Import quoted field as text.
+ aOutStr += String::CreateFromAscii(bQuotedFieldAsText ? "true" : "false");
+ aOutStr += ',';
+
+ // Detect special nubmers.
+ aOutStr += String::CreateFromAscii(bDetectSpecialNumber ? "true" : "false");
+
+ return aOutStr;
+}
+
+#if 0
+// Code, um die Spalten-Liste aus einem Excel-kompatiblen String zu erzeugen:
+// (im Moment nicht benutzt)
+
+void ScAsciiOptions::InterpretColumnList( const String& rString )
+{
+ // Eingabe ist 1-basiert, pColStart fuer FixedLen ist 0-basiert
+
+ // Kommas durch Semikolon ersetzen
+
+ String aSemiStr = rString;
+ USHORT nPos = 0;
+ do
+ nPos = aSemiStr.SearchAndReplace( ',', ';', nPos );
+ while ( nPos != STRING_NOTFOUND );
+
+ // Eintraege sortieren
+
+ USHORT nCount = aSemiStr.GetTokenCount();
+ USHORT* pTemp = new USHORT[nCount+1];
+ pTemp[0] = 1; // erste Spalte faengt immer bei 1 an
+ USHORT nFound = 1;
+ USHORT i,j;
+ for (i=0; i<nCount; i++)
+ {
+ USHORT nVal = (USHORT) aSemiStr.GetToken(i);
+ if (nVal)
+ {
+ BOOL bThere = FALSE;
+ nPos = 0;
+ for (j=0; j<nFound; j++)
+ {
+ if ( pTemp[j] == nVal )
+ bThere = TRUE;
+ else if ( pTemp[j] < nVal )
+ nPos = j+1;
+ }
+ if ( !bThere )
+ {
+ if ( nPos < nFound )
+ memmove( &pTemp[nPos+1], &pTemp[nPos], (nFound-nPos)*sizeof(USHORT) );
+ pTemp[nPos] = nVal;
+ ++nFound;
+ }
+ }
+ }
+
+ // Eintraege uebernehmen
+
+ delete[] pColStart;
+ delete[] pColFormat;
+ nInfoCount = nFound;
+ if (nInfoCount)
+ {
+ pColStart = new USHORT[nInfoCount];
+ pColFormat = new BYTE[nInfoCount];
+ for (i=0; i<nInfoCount; i++)
+ {
+ pColStart[i] = pTemp[i] - 1;
+ pColFormat[i] = SC_COL_STANDARD;
+ }
+ }
+ else
+ {
+ pColStart = NULL;
+ pColFormat = NULL;
+ }
+
+ bFixedLen = TRUE; // sonst macht's keinen Sinn
+
+ // aufraeumen
+
+ delete[] pTemp;
+}
+#endif
+
diff --git a/sc/source/ui/dbgui/asciiopt.hrc b/sc/source/ui/dbgui/asciiopt.hrc
new file mode 100644
index 000000000000..7bf6d42d6e2f
--- /dev/null
+++ b/sc/source/ui/dbgui/asciiopt.hrc
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc"
+//#define RID_SCDLG_ASCII 256
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define FL_FIELDOPT 4
+#define FT_CHARSET 5
+#define LB_CHARSET 6
+#define FT_CUSTOMLANG 7
+#define LB_CUSTOMLANG 8
+#define FT_AT_ROW 9
+#define NF_AT_ROW 10
+
+#define FL_SEPOPT 11
+#define RB_FIXED 12
+#define RB_SEPARATED 13
+#define CKB_TAB 14
+#define CKB_COMMA 15
+#define CKB_OTHER 16
+#define ED_OTHER 17
+#define CKB_SEMICOLON 18
+#define CKB_SPACE 19
+#define CB_ASONCE 20
+#define CB_TEXTSEP 21
+#define FT_TEXTSEP 22
+
+#define FL_OTHER_OPTIONS 23
+#define CB_QUOTED_AS_TEXT 24
+#define CB_DETECT_SPECIAL_NUMBER 25
+
+#define FL_WIDTH 26
+#define FT_TYPE 27
+#define LB_TYPE1 28
+#define CTR_TABLEBOX 29
+#define STR_TEXTTOCOLUMNS 30
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/dbgui/asciiopt.src b/sc/source/ui/dbgui/asciiopt.src
new file mode 100644
index 000000000000..9efbfe0f557f
--- /dev/null
+++ b/sc/source/ui/dbgui/asciiopt.src
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "asciiopt.hrc"
+
+ModalDialog RID_SCDLG_ASCII
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 320 , 305 ) ;
+ Text [ en-US ] = "Text Import" ;
+ Moveable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 264 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 264 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 264 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+
+ FixedLine FL_FIELDOPT
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 252 , 8 ) ;
+ Text [ en-US ] = "Import" ;
+ };
+
+ FixedText FT_CHARSET
+ {
+ Pos = MAP_APPFONT ( 12 , 16 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Ch~aracter set" ;
+ };
+
+ ListBox LB_CHARSET
+ {
+ Pos = MAP_APPFONT ( 76 , 14 ) ;
+ Size = MAP_APPFONT ( 130 , 61 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE;
+ };
+
+ FixedText FT_CUSTOMLANG
+ {
+ Pos = MAP_APPFONT ( 12 , 32 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Language" ;
+ };
+
+ ListBox LB_CUSTOMLANG
+ {
+ Pos = MAP_APPFONT ( 76 , 30 ) ;
+ Size = MAP_APPFONT ( 130 , 61 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE;
+ };
+
+ FixedText FT_AT_ROW
+ {
+ Pos = MAP_APPFONT ( 12 , 48 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "From ro~w" ;
+ };
+
+ NumericField NF_AT_ROW
+ {
+ Border = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 76 , 46 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ };
+
+ FixedLine FL_SEPOPT
+ {
+ Pos = MAP_APPFONT ( 6 , 63 ) ;
+ Size = MAP_APPFONT ( 252 , 8 ) ;
+ Text [ en-US ] = "Separator options" ;
+ };
+ RadioButton RB_FIXED
+ {
+ Pos = MAP_APPFONT ( 12 , 75 ) ;
+ Size = MAP_APPFONT ( 243 , 10 ) ;
+ Text [ en-US ] = "~Fixed width" ;
+ TabStop = TRUE ;
+ };
+ RadioButton RB_SEPARATED
+ {
+ Pos = MAP_APPFONT ( 12 , 89 ) ;
+ Size = MAP_APPFONT ( 243 , 10 ) ;
+ Text [ en-US ] = "~Separated by" ;
+ TabStop = TRUE ;
+ Check = TRUE ;
+ };
+
+ CheckBox CKB_TAB
+ {
+ Pos = MAP_APPFONT ( 20 , 102 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Tab" ;
+ };
+ CheckBox CKB_COMMA
+ {
+ Pos = MAP_APPFONT ( 92 , 102 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Comma" ;
+ };
+ CheckBox CKB_OTHER
+ {
+ Pos = MAP_APPFONT ( 164 , 102 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Other" ;
+ };
+ Edit ED_OTHER
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 218 , 100 ) ;
+ Size = MAP_APPFONT ( 37 , 12 ) ;
+ TabStop = TRUE ;
+ MaxTextLength = 10 ;
+ };
+
+ CheckBox CKB_SEMICOLON
+ {
+ Pos = MAP_APPFONT ( 20 , 115 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "S~emicolon" ;
+ };
+ CheckBox CKB_SPACE
+ {
+ Pos = MAP_APPFONT ( 92 , 115 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "S~pace" ;
+ };
+
+ CheckBox CB_ASONCE
+ {
+ Pos = MAP_APPFONT ( 20 , 130 ) ;
+ Size = MAP_APPFONT ( 130 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Merge ~delimiters" ;
+ };
+
+ ComboBox CB_TEXTSEP
+ {
+ Pos = MAP_APPFONT ( 218 , 128 ) ;
+ Size = MAP_APPFONT ( 37 , 94 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_TEXTSEP
+ {
+ Pos = MAP_APPFONT ( 156 , 130 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Te~xt delimiter" ;
+ };
+
+ FixedLine FL_OTHER_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 146 ) ;
+ Size = MAP_APPFONT ( 252 , 8 ) ;
+ Text [ en-US ] = "Other options" ;
+ };
+
+ CheckBox CB_QUOTED_AS_TEXT
+ {
+ Pos = MAP_APPFONT ( 12 , 158 ) ;
+ Size = MAP_APPFONT ( 130 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Quoted field as text" ;
+ };
+
+ CheckBox CB_DETECT_SPECIAL_NUMBER
+ {
+ Pos = MAP_APPFONT ( 12 , 171 ) ;
+ Size = MAP_APPFONT ( 130 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Detect special numbers" ;
+ };
+
+ FixedLine FL_WIDTH
+ {
+ Pos = MAP_APPFONT ( 6 , 187 ) ;
+ Size = MAP_APPFONT ( 252 , 8 ) ;
+ Text [ en-US ] = "Fields" ;
+ };
+ FixedText FT_TYPE
+ {
+ Pos = MAP_APPFONT ( 12 , 200 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Column t~ype";
+ };
+ ListBox LB_TYPE1
+ {
+ Pos = MAP_APPFONT ( 76 , 198 ) ;
+ Size = MAP_APPFONT ( 60 , 68 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ Control CTR_TABLEBOX
+ {
+ HelpId = HID_SC_ASCII_TABCTR ;
+ Border = TRUE ;
+ DialogControl = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 216 ) ;
+ Size = MAP_APPFONT ( 243 , 82 ) ;
+ };
+
+ String STR_TEXTTOCOLUMNS
+ {
+ Text [ en-US ] = "Text to Columns" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/dbgui/consdlg.cxx b/sc/source/ui/dbgui/consdlg.cxx
new file mode 100644
index 000000000000..e094149ab99b
--- /dev/null
+++ b/sc/source/ui/dbgui/consdlg.cxx
@@ -0,0 +1,655 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+#include <sfx2/dispatch.hxx>
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+
+#include "globstr.hrc"
+#include "consdlg.hrc"
+
+#define _CONSDLG_CXX
+#include "consdlg.hxx"
+#undef _CONSDLG_CXX
+#include <vcl/msgbox.hxx>
+
+#define INFOBOX(id) InfoBox(this, ScGlobal::GetRscString(id)).Execute()
+
+//============================================================================
+// class ScAreaData
+
+class ScAreaData
+{
+public:
+ ScAreaData() {}
+ ~ScAreaData() {}
+
+ void Set( const String& rName, const String& rArea, BOOL bDb )
+ {
+ aStrName = rName;
+ aStrArea = rArea;
+ bIsDbArea = bDb;
+ }
+
+ String aStrName;
+ String aStrArea;
+ BOOL bIsDbArea;
+};
+
+
+//============================================================================
+// class ScConsolidateDialog
+
+
+ScConsolidateDlg::ScConsolidateDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_CONSOLIDATE ),
+ //
+ aFtFunc ( this, ScResId( FT_FUNC ) ),
+ aLbFunc ( this, ScResId( LB_FUNC ) ),
+
+ aFtConsAreas ( this, ScResId( FT_CONSAREAS ) ),
+ aLbConsAreas ( this, ScResId( LB_CONSAREAS ) ),
+
+ aLbDataArea ( this, ScResId( LB_DATA_AREA ) ),
+ aFtDataArea ( this, ScResId( FT_DATA_AREA ) ),
+ aEdDataArea ( this, this, ScResId( ED_DATA_AREA ) ),
+ aRbDataArea ( this, ScResId( RB_DATA_AREA ), &aEdDataArea, this ),
+
+ aLbDestArea ( this, ScResId( LB_DEST_AREA ) ),
+ aFtDestArea ( this, ScResId( FT_DEST_AREA ) ),
+ aEdDestArea ( this, this, ScResId( ED_DEST_AREA ) ),
+ aRbDestArea ( this, ScResId( RB_DEST_AREA ), &aEdDestArea, this),
+
+ aFlConsBy ( this, ScResId( FL_CONSBY ) ),
+ aBtnByRow ( this, ScResId( BTN_BYROW ) ),
+ aBtnByCol ( this, ScResId( BTN_BYCOL) ),
+
+ aFlSep ( this, ScResId( FL_SEP ) ),
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ aBtnRefs ( this, ScResId( BTN_REFS ) ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnAdd ( this, ScResId( BTN_ADD ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
+ //
+ theConsData ( ((const ScConsolidateItem&)
+ rArgSet.Get( rArgSet.GetPool()->
+ GetWhich( SID_CONSOLIDATE ) )
+ ).GetData() ),
+ pViewData ( ((ScTabViewShell*)SfxViewShell::Current())->
+ GetViewData() ),
+ pDoc ( ((ScTabViewShell*)SfxViewShell::Current())->
+ GetViewData()->GetDocument() ),
+ pRangeUtil ( new ScRangeUtil ),
+ pAreaData ( NULL ),
+ nAreaDataCount ( 0 ),
+ nWhichCons ( rArgSet.GetPool()->GetWhich( SID_CONSOLIDATE ) ),
+
+ pRefInputEdit ( &aEdDataArea )
+{
+ Init();
+ FreeResource();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScConsolidateDlg::~ScConsolidateDlg()
+{
+ delete [] pAreaData;
+ delete pRangeUtil;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScConsolidateDlg::Init()
+{
+ DBG_ASSERT( pViewData && pDoc && pRangeUtil, "Error in Ctor" );
+
+ String aStr;
+ USHORT i=0;
+
+ aEdDataArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
+ aEdDestArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
+ aLbDataArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
+ aLbDestArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
+ aEdDataArea .SetModifyHdl ( LINK( this, ScConsolidateDlg, ModifyHdl ) );
+ aEdDestArea .SetModifyHdl ( LINK( this, ScConsolidateDlg, ModifyHdl ) );
+ aLbConsAreas.SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) );
+ aLbDataArea .SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) );
+ aLbDestArea .SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) );
+ aBtnOk .SetClickHdl ( LINK( this, ScConsolidateDlg, OkHdl ) );
+ aBtnCancel .SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) );
+ aBtnAdd .SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) );
+ aBtnRemove .SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) );
+
+ aBtnMore.AddWindow( &aFlConsBy );
+ aBtnMore.AddWindow( &aBtnByRow );
+ aBtnMore.AddWindow( &aBtnByCol );
+ aBtnMore.AddWindow( &aFlSep );
+ aBtnMore.AddWindow( &aFlOptions );
+ aBtnMore.AddWindow( &aBtnRefs );
+
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+
+ aBtnByRow.Check( theConsData.bByRow );
+ aBtnByCol.Check( theConsData.bByCol );
+ aBtnRefs .Check( theConsData.bReferenceData );
+
+ aLbFunc.SelectEntryPos( FuncToLbPos( theConsData.eFunction ) );
+
+ // Einlesen der Konsolidierungsbereiche
+ aLbConsAreas.Clear();
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ for ( i=0; i<theConsData.nDataAreaCount; i++ )
+ {
+ const ScArea& rArea = *(theConsData.ppDataAreas[i] );
+ if ( rArea.nTab < pDoc->GetTableCount() )
+ {
+ ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab,
+ rArea.nColEnd, rArea.nRowEnd, rArea.nTab ).Format( aStr,
+ SCR_ABS_3D, pDoc, eConv );
+ aLbConsAreas.InsertEntry( aStr );
+ }
+ }
+
+ if ( theConsData.nTab < pDoc->GetTableCount() )
+ {
+ ScAddress( theConsData.nCol, theConsData.nRow, theConsData.nTab
+ ).Format( aStr, SCA_ABS_3D, pDoc, eConv );
+ aEdDestArea.SetText( aStr );
+ }
+ else
+ aEdDestArea.SetText( EMPTY_STRING );
+
+ //----------------------------------------------------------
+
+ /*
+ * Aus den RangeNames und Datenbankbereichen werden sich
+ * in der Hilfsklasse ScAreaData die Bereichsnamen gemerkt,
+ * die in den ListBoxen erscheinen.
+ */
+
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ ScDBCollection* pDbNames = pDoc->GetDBCollection();
+ const USHORT nRangeCount = pRangeNames ? pRangeNames->GetCount() : 0;
+ const USHORT nDbCount = pDbNames ? pDbNames ->GetCount() : 0;
+
+ nAreaDataCount = nRangeCount+nDbCount;
+ pAreaData = NULL;
+
+ if ( nAreaDataCount > 0 )
+ {
+ pAreaData = new ScAreaData[nAreaDataCount];
+
+ String aStrName;
+ String aStrArea;
+ USHORT nAt = 0;
+ ScRange aRange;
+ ScAreaNameIterator aIter( pDoc );
+ while ( aIter.Next( aStrName, aRange ) )
+ {
+ aRange.Format( aStrArea, SCA_ABS_3D, pDoc, eConv );
+ pAreaData[nAt++].Set( aStrName, aStrArea, aIter.WasDBName() );
+ }
+ }
+
+ FillAreaLists();
+ ModifyHdl( &aEdDestArea );
+ aLbDataArea.SelectEntryPos( 0 );
+ aEdDataArea.SetText( EMPTY_STRING );
+ aEdDataArea.GrabFocus();
+
+ aFlSep.SetStyle( aFlSep.GetStyle() | WB_VERT );
+
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+}
+
+
+//----------------------------------------------------------------------------
+void ScConsolidateDlg::FillAreaLists()
+{
+ aLbDataArea.Clear();
+ aLbDestArea.Clear();
+ aLbDataArea.InsertEntry( aStrUndefined );
+ aLbDestArea.InsertEntry( aStrUndefined );
+
+ if ( pRangeUtil && pAreaData && (nAreaDataCount > 0) )
+ {
+ String aString;
+
+ for ( USHORT i=0;
+ (i<nAreaDataCount) && (pAreaData[i].aStrName.Len()>0);
+ i++ )
+ {
+ aLbDataArea.InsertEntry( pAreaData[i].aStrName, i+1 );
+
+// if ( !pAreaData[i].bIsDbArea )
+ aLbDestArea.InsertEntry( pAreaData[i].aStrName, i+1 );
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Fenster angezeigt wird.
+
+
+void ScConsolidateDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( pRefInputEdit )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( pRefInputEdit );
+
+ String aStr;
+ USHORT nFmt = SCR_ABS_3D; //!!! nCurTab fehlt noch
+ const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
+
+ if ( rRef.aStart.Tab() != rRef.aEnd.Tab() )
+ nFmt |= SCA_TAB2_3D;
+
+ if ( pRefInputEdit == &aEdDataArea)
+ rRef.Format( aStr, nFmt, pDocP, eConv );
+ else if ( pRefInputEdit == &aEdDestArea )
+ rRef.aStart.Format( aStr, nFmt, pDocP, eConv );
+
+ pRefInputEdit->SetRefString( aStr );
+ }
+
+ ModifyHdl( pRefInputEdit );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScConsolidateDlg::Close()
+{
+ return DoClose( ScConsolidateDlgWrapper::GetChildWindowId() );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScConsolidateDlg::SetActive()
+{
+ if ( bDlgLostFocus )
+ {
+ bDlgLostFocus = FALSE;
+
+ if ( pRefInputEdit )
+ {
+ pRefInputEdit->GrabFocus();
+ ModifyHdl( pRefInputEdit );
+ }
+ }
+ else
+ GrabFocus();
+
+ RefInputDone();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScConsolidateDlg::Deactivate()
+{
+ bDlgLostFocus = TRUE;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScConsolidateDlg::VerifyEdit( formula::RefEdit* pEd )
+{
+ if ( !pRangeUtil || !pDoc || !pViewData ||
+ ((pEd != &aEdDataArea) && (pEd != &aEdDestArea)) )
+ return FALSE;
+
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bEditOk = FALSE;
+ String theCompleteStr;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ if ( pEd == &aEdDataArea )
+ {
+ bEditOk = pRangeUtil->IsAbsArea( pEd->GetText(), pDoc,
+ nTab, &theCompleteStr, NULL, NULL, eConv );
+ }
+ else if ( pEd == &aEdDestArea )
+ {
+ String aPosStr;
+
+ pRangeUtil->CutPosString( pEd->GetText(), aPosStr );
+ bEditOk = pRangeUtil->IsAbsPos( aPosStr, pDoc,
+ nTab, &theCompleteStr, NULL, eConv );
+ }
+
+ if ( bEditOk )
+ pEd->SetText( theCompleteStr );
+
+ return bEditOk;
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+// ========
+
+IMPL_LINK( ScConsolidateDlg, GetFocusHdl, Control*, pCtr )
+{
+ if ( pCtr ==(Control*)&aEdDataArea ||
+ pCtr ==(Control*)&aEdDestArea)
+ {
+ pRefInputEdit = (formula::RefEdit*)pCtr;
+ }
+ else if(pCtr ==(Control*)&aLbDataArea )
+ {
+ pRefInputEdit = &aEdDataArea;
+ }
+ else if(pCtr ==(Control*)&aLbDestArea )
+ {
+ pRefInputEdit = &aEdDestArea;
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConsolidateDlg, OkHdl, void*, EMPTYARG )
+{
+ USHORT nDataAreaCount = aLbConsAreas.GetEntryCount();
+
+ if ( nDataAreaCount > 0 )
+ {
+ ScRefAddress aDestAddress;
+ SCTAB nTab = pViewData->GetTabNo();
+ String aDestPosStr( aEdDestArea.GetText() );
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ if ( pRangeUtil->IsAbsPos( aDestPosStr, pDoc, nTab, NULL, &aDestAddress, eConv ) )
+ {
+ ScConsolidateParam theOutParam( theConsData );
+ ScArea** ppDataAreas = new ScArea*[nDataAreaCount];
+ ScArea* pArea;
+ USHORT i=0;
+
+ for ( i=0; i<nDataAreaCount; i++ )
+ {
+ pArea = new ScArea;
+ pRangeUtil->MakeArea( aLbConsAreas.GetEntry( i ),
+ *pArea, pDoc, nTab, eConv );
+ ppDataAreas[i] = pArea;
+ }
+
+ theOutParam.nCol = aDestAddress.Col();
+ theOutParam.nRow = aDestAddress.Row();
+ theOutParam.nTab = aDestAddress.Tab();
+ theOutParam.eFunction = LbPosToFunc( aLbFunc.GetSelectEntryPos() );
+ theOutParam.bByCol = aBtnByCol.IsChecked();
+ theOutParam.bByRow = aBtnByRow.IsChecked();
+ theOutParam.bReferenceData = aBtnRefs.IsChecked();
+ theOutParam.SetAreas( ppDataAreas, nDataAreaCount );
+
+ for ( i=0; i<nDataAreaCount; i++ )
+ delete ppDataAreas[i];
+ delete [] ppDataAreas;
+
+ ScConsolidateItem aOutItem( nWhichCons, &theOutParam );
+
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( SID_CONSOLIDATE,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aOutItem, 0L, 0L );
+ Close();
+ }
+ else
+ {
+ INFOBOX( STR_INVALID_TABREF );
+ aEdDestArea.GrabFocus();
+ }
+ }
+ else
+ Close(); // keine Datenbereiche definiert -> Cancel
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConsolidateDlg, ClickHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &aBtnCancel )
+ Close();
+ else if ( pBtn == &aBtnAdd )
+ {
+ if ( aEdDataArea.GetText().Len() > 0 )
+ {
+ String aNewEntry( aEdDataArea.GetText() );
+ ScArea** ppAreas = NULL;
+ USHORT nAreaCount = 0;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ if ( pRangeUtil->IsAbsTabArea( aNewEntry, pDoc, &ppAreas, &nAreaCount, TRUE, eConv ) )
+ {
+ // IsAbsTabArea() legt ein Array von ScArea-Zeigern an,
+ // welche ebenfalls dynamisch erzeugt wurden.
+ // Diese Objekte muessen hier abgeraeumt werden.
+
+ for ( USHORT i=0; i<nAreaCount; i++ )
+ {
+ String aNewArea;
+
+ if ( ppAreas[i] )
+ {
+ const ScArea& rArea = *(ppAreas[i]);
+ ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab,
+ rArea.nColEnd, rArea.nRowEnd, rArea.nTab
+ ).Format( aNewArea, SCR_ABS_3D, pDoc, eConv );
+
+ if ( aLbConsAreas.GetEntryPos( aNewArea )
+ == LISTBOX_ENTRY_NOTFOUND )
+ {
+ aLbConsAreas.InsertEntry( aNewArea );
+ }
+ delete ppAreas[i];
+ }
+ }
+ delete [] ppAreas;
+ }
+ else if ( VerifyEdit( &aEdDataArea ) )
+ {
+ String aNewArea( aEdDataArea.GetText() );
+
+ if ( aLbConsAreas.GetEntryPos( aNewArea ) == LISTBOX_ENTRY_NOTFOUND )
+ aLbConsAreas.InsertEntry( aNewArea );
+ else
+ INFOBOX( STR_AREA_ALREADY_INSERTED );
+ }
+ else
+ {
+ INFOBOX( STR_INVALID_TABREF );
+ aEdDataArea.GrabFocus();
+ }
+ }
+ }
+ else if ( pBtn == &aBtnRemove )
+ {
+ while ( aLbConsAreas.GetSelectEntryCount() )
+ aLbConsAreas.RemoveEntry( aLbConsAreas.GetSelectEntryPos() );
+ aBtnRemove.Disable();
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConsolidateDlg, SelectHdl, ListBox*, pLb )
+{
+ if ( pLb == &aLbConsAreas )
+ {
+ if ( aLbConsAreas.GetSelectEntryCount() > 0 )
+ aBtnRemove.Enable();
+ else
+ aBtnRemove.Disable();
+ }
+ else if ( (pLb == &aLbDataArea) || (pLb == &aLbDestArea) )
+ {
+ Edit* pEd = (pLb == &aLbDataArea) ? &aEdDataArea : &aEdDestArea;
+ USHORT nSelPos = pLb->GetSelectEntryPos();
+
+ if ( pRangeUtil
+ && (nSelPos > 0)
+ && (nAreaDataCount > 0)
+ && (pAreaData != NULL) )
+ {
+ if ( nSelPos <= nAreaDataCount )
+ {
+ String aString( pAreaData[nSelPos-1].aStrArea );
+
+ if ( pLb == &aLbDestArea )
+ pRangeUtil->CutPosString( aString, aString );
+
+ pEd->SetText( aString );
+
+ if ( pEd == &aEdDataArea )
+ aBtnAdd.Enable();
+ }
+ }
+ else
+ {
+ pEd->SetText( EMPTY_STRING );
+ if ( pEd == &aEdDataArea )
+ aBtnAdd.Enable();
+ }
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScConsolidateDlg, ModifyHdl, formula::RefEdit*, pEd )
+{
+ if ( pEd == &aEdDataArea )
+ {
+ String aAreaStr( pEd->GetText() );
+ if ( aAreaStr.Len() > 0 )
+ {
+ aBtnAdd.Enable();
+ }
+ else
+ aBtnAdd.Disable();
+ }
+ else if ( pEd == &aEdDestArea )
+ {
+ aLbDestArea.SelectEntryPos(0);
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+// Verallgemeinern!!! :
+// Resource der ListBox und diese beiden Umrechnungsmethoden gibt es
+// auch noch in tpsubt bzw. ueberall, wo StarCalc-Funktionen
+// auswaehlbar sind.
+
+ScSubTotalFunc ScConsolidateDlg::LbPosToFunc( USHORT nPos )
+{
+ switch ( nPos )
+ {
+ case 2: return SUBTOTAL_FUNC_AVE;
+ case 6: return SUBTOTAL_FUNC_CNT;
+ case 1: return SUBTOTAL_FUNC_CNT2;
+ case 3: return SUBTOTAL_FUNC_MAX;
+ case 4: return SUBTOTAL_FUNC_MIN;
+ case 5: return SUBTOTAL_FUNC_PROD;
+ case 7: return SUBTOTAL_FUNC_STD;
+ case 8: return SUBTOTAL_FUNC_STDP;
+ case 9: return SUBTOTAL_FUNC_VAR;
+ case 10: return SUBTOTAL_FUNC_VARP;
+ case 0:
+ default:
+ return SUBTOTAL_FUNC_SUM;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+USHORT ScConsolidateDlg::FuncToLbPos( ScSubTotalFunc eFunc )
+{
+ switch ( eFunc )
+ {
+ case SUBTOTAL_FUNC_AVE: return 2;
+ case SUBTOTAL_FUNC_CNT: return 6;
+ case SUBTOTAL_FUNC_CNT2: return 1;
+ case SUBTOTAL_FUNC_MAX: return 3;
+ case SUBTOTAL_FUNC_MIN: return 4;
+ case SUBTOTAL_FUNC_PROD: return 5;
+ case SUBTOTAL_FUNC_STD: return 7;
+ case SUBTOTAL_FUNC_STDP: return 8;
+ case SUBTOTAL_FUNC_VAR: return 9;
+ case SUBTOTAL_FUNC_VARP: return 10;
+ case SUBTOTAL_FUNC_NONE:
+ case SUBTOTAL_FUNC_SUM:
+ default:
+ return 0;
+ }
+}
+
diff --git a/sc/source/ui/dbgui/consdlg.hrc b/sc/source/ui/dbgui/consdlg.hrc
new file mode 100644
index 000000000000..6f9f6708c388
--- /dev/null
+++ b/sc/source/ui/dbgui/consdlg.hrc
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+#define BTN_MORE 4
+
+#define BTN_ADD 5
+#define BTN_REMOVE 6
+
+#define FT_FUNC 11
+#define LB_FUNC 12
+
+#define FT_CONSAREAS 21
+#define LB_CONSAREAS 22
+
+#define FT_DATA_AREA 31
+#define LB_DATA_AREA 32
+#define ED_DATA_AREA 33
+#define RB_DATA_AREA 34
+
+#define FT_DEST_AREA 41
+#define LB_DEST_AREA 42
+#define ED_DEST_AREA 43
+#define RB_DEST_AREA 44
+
+#define FL_CONSBY 50
+#define BTN_BYROW 51
+#define BTN_BYCOL 52
+#define FL_SEP 59
+
+#define FL_OPTIONS 60
+#define BTN_REFS 61
+
diff --git a/sc/source/ui/dbgui/consdlg.src b/sc/source/ui/dbgui/consdlg.src
new file mode 100644
index 000000000000..5226c22629c6
--- /dev/null
+++ b/sc/source/ui/dbgui/consdlg.src
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "consdlg.hrc"
+ModelessDialog RID_SCDLG_CONSOLIDATE
+{
+ OutputSize = TRUE ;
+ HelpId = SID_OPENDLG_CONSOLIDATE ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 280 , 154 ) ;
+ Text [ en-US ] = "Consolidate" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ ListBox LB_FUNC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 17 ) ;
+ Size = MAP_APPFONT ( 212 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Sum" ; Default ; > ;
+ < "Count" ; Default ; > ;
+ < "Average" ; Default ; > ;
+ < "Max" ; Default ; > ;
+ < "Min" ; Default ; > ;
+ < "Product" ; Default ; > ;
+ < "Count (numbers only)" ; Default ; > ;
+ < "StDev (sample)" ; Default ; > ;
+ < "StDevP (population)" ; Default ; > ;
+ < "Var (sample)" ; Default ; > ;
+ < "VarP (population)" ; Default ; > ;
+ };
+ };
+ Edit ED_DATA_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 100 , 106 ) ;
+ Size = MAP_APPFONT ( 104 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ Edit ED_DEST_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 100 , 135 ) ;
+ Size = MAP_APPFONT ( 104 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_DATA_AREA
+ {
+ Pos = MAP_APPFONT ( 206 , 105 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ImageButton RB_DEST_AREA
+ {
+ Pos = MAP_APPFONT ( 206 , 134 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ListBox LB_DATA_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 106 ) ;
+ Size = MAP_APPFONT ( 90 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_DEST_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 135 ) ;
+ Size = MAP_APPFONT ( 90 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ MultiListBox LB_CONSAREAS
+ {
+ SimpleMode = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 46 ) ;
+ Size = MAP_APPFONT ( 212 , 43 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_FUNC
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 212 , 8 ) ;
+ Text [ en-US ] = "~Function" ;
+ };
+ FixedText FT_CONSAREAS
+ {
+ Pos = MAP_APPFONT ( 6 , 35 ) ;
+ Size = MAP_APPFONT ( 212 , 8 ) ;
+ Text [ en-US ] = "~Consolidation ranges" ;
+ };
+ FixedText FT_DATA_AREA
+ {
+ Pos = MAP_APPFONT ( 6 , 95 ) ;
+ Size = MAP_APPFONT ( 212 , 8 ) ;
+ Text [ en-US ] = "~Source data range" ;
+ };
+ FixedText FT_DEST_AREA
+ {
+ Pos = MAP_APPFONT ( 6 , 124 ) ;
+ Size = MAP_APPFONT ( 212 , 8 ) ;
+ Text [ en-US ] = "Copy results ~to" ;
+ };
+ CheckBox BTN_BYROW
+ {
+ Pos = MAP_APPFONT ( 12 , 165 ) ;
+ Size = MAP_APPFONT ( 94 , 10 ) ;
+ Text [ en-US ] = "~Row labels" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_BYCOL
+ {
+ Pos = MAP_APPFONT ( 12 , 179 ) ;
+ Size = MAP_APPFONT ( 94 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "C~olumn labels" ;
+ };
+ FixedLine FL_CONSBY
+ {
+ Pos = MAP_APPFONT ( 6 , 154 ) ;
+ Size = MAP_APPFONT ( 103 , 8 ) ;
+ Text [ en-US ] = "Consolidate by" ;
+ };
+ FixedLine FL_SEP
+ {
+ Pos = MAP_APPFONT ( 112 , 165 ) ;
+ Size = MAP_APPFONT ( 1 , 24 ) ;
+ };
+ FixedLine FL_OPTIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 115 , 154 ) ;
+ Size = MAP_APPFONT ( 103 , 8 ) ;
+ Text [ en-US ] = "Options" ;
+ };
+ CheckBox BTN_REFS
+ {
+ Pos = MAP_APPFONT ( 121 , 165 ) ;
+ Size = MAP_APPFONT ( 94 , 10 ) ;
+ Text [ en-US ] = "~Link to source data" ;
+ TabStop = TRUE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 224 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 224 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 224 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 224 , 134 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 41 ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 224 , 114 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Delete" ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 224 , 96 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Add" ;
+ TabStop = TRUE ;
+ };
+};
+
diff --git a/sc/source/ui/dbgui/csvcontrol.cxx b/sc/source/ui/dbgui/csvcontrol.cxx
new file mode 100644
index 000000000000..0dbc4e7dab39
--- /dev/null
+++ b/sc/source/ui/dbgui/csvcontrol.cxx
@@ -0,0 +1,337 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// ============================================================================
+#include "csvcontrol.hxx"
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include "AccessibleCsvControl.hxx"
+
+
+// ============================================================================
+
+ScCsvLayoutData::ScCsvLayoutData() :
+ mnPosCount( 1 ),
+ mnPosOffset( 0 ),
+ mnWinWidth( 1 ),
+ mnHdrWidth( 0 ),
+ mnCharWidth( 1 ),
+ mnLineCount( 1 ),
+ mnLineOffset( 0 ),
+ mnWinHeight( 1 ),
+ mnHdrHeight( 0 ),
+ mnLineHeight( 1 ),
+ mnPosCursor( CSV_POS_INVALID ),
+ mnColCursor( 0 ),
+ mnNoRepaint( 0 ),
+ mbAppRTL( !!Application::GetSettings().GetLayoutRTL() )
+{
+}
+
+ScCsvDiff ScCsvLayoutData::GetDiff( const ScCsvLayoutData& rData ) const
+{
+ ScCsvDiff nRet = CSV_DIFF_EQUAL;
+ if( mnPosCount != rData.mnPosCount ) nRet |= CSV_DIFF_POSCOUNT;
+ if( mnPosOffset != rData.mnPosOffset ) nRet |= CSV_DIFF_POSOFFSET;
+ if( mnHdrWidth != rData.mnHdrWidth ) nRet |= CSV_DIFF_HDRWIDTH;
+ if( mnCharWidth != rData.mnCharWidth ) nRet |= CSV_DIFF_CHARWIDTH;
+ if( mnLineCount != rData.mnLineCount ) nRet |= CSV_DIFF_LINECOUNT;
+ if( mnLineOffset != rData.mnLineOffset ) nRet |= CSV_DIFF_LINEOFFSET;
+ if( mnHdrHeight != rData.mnHdrHeight ) nRet |= CSV_DIFF_HDRHEIGHT;
+ if( mnLineHeight != rData.mnLineHeight ) nRet |= CSV_DIFF_LINEHEIGHT;
+ if( mnPosCursor != rData.mnPosCursor ) nRet |= CSV_DIFF_RULERCURSOR;
+ if( mnColCursor != rData.mnColCursor ) nRet |= CSV_DIFF_GRIDCURSOR;
+ return nRet;
+}
+
+
+// ============================================================================
+
+ScCsvControl::ScCsvControl( ScCsvControl& rParent ) :
+ Control( &rParent, WB_TABSTOP | WB_NODIALOGCONTROL ),
+ mrData( rParent.GetLayoutData() ),
+ mpAccessible( NULL ),
+ mbValidGfx( false )
+{
+}
+
+ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, WinBits nStyle ) :
+ Control( pParent, nStyle ),
+ mrData( rData ),
+ mpAccessible( NULL ),
+ mbValidGfx( false )
+{
+}
+
+ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, const ResId& rResId ) :
+ Control( pParent, rResId ),
+ mrData( rData ),
+ mpAccessible( NULL ),
+ mbValidGfx( false )
+{
+}
+
+ScCsvControl::~ScCsvControl()
+{
+ if( mpAccessible )
+ mpAccessible->dispose();
+}
+
+
+// event handling -------------------------------------------------------------
+
+void ScCsvControl::GetFocus()
+{
+ Control::GetFocus();
+ AccSendFocusEvent( true );
+}
+
+void ScCsvControl::LoseFocus()
+{
+ Control::LoseFocus();
+ AccSendFocusEvent( false );
+}
+
+void ScCsvControl::AccSendFocusEvent( bool bFocused )
+{
+ if( mpAccessible )
+ mpAccessible->SendFocusEvent( bFocused );
+}
+
+void ScCsvControl::AccSendCaretEvent()
+{
+ if( mpAccessible )
+ mpAccessible->SendCaretEvent();
+}
+
+void ScCsvControl::AccSendVisibleEvent()
+{
+ if( mpAccessible )
+ mpAccessible->SendVisibleEvent();
+}
+
+void ScCsvControl::AccSendSelectionEvent()
+{
+ if( mpAccessible )
+ mpAccessible->SendSelectionEvent();
+}
+
+void ScCsvControl::AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
+{
+ if( mpAccessible )
+ mpAccessible->SendTableUpdateEvent( nFirstColumn, nLastColumn, bAllRows );
+}
+
+void ScCsvControl::AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
+{
+ if( mpAccessible )
+ mpAccessible->SendInsertColumnEvent( nFirstColumn, nLastColumn );
+}
+
+void ScCsvControl::AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
+{
+ if( mpAccessible )
+ mpAccessible->SendRemoveColumnEvent( nFirstColumn, nLastColumn );
+}
+
+
+// repaint helpers ------------------------------------------------------------
+
+void ScCsvControl::Repaint( bool bInvalidate )
+{
+ if( bInvalidate )
+ InvalidateGfx();
+ if( !IsNoRepaint() )
+ Execute( CSVCMD_REPAINT );
+}
+
+void ScCsvControl::DisableRepaint()
+{
+ ++mrData.mnNoRepaint;
+}
+
+void ScCsvControl::EnableRepaint( bool bInvalidate )
+{
+ DBG_ASSERT( IsNoRepaint(), "ScCsvControl::EnableRepaint - invalid call" );
+ --mrData.mnNoRepaint;
+ Repaint( bInvalidate );
+}
+
+
+// command handling -----------------------------------------------------------
+
+void ScCsvControl::Execute( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 )
+{
+ maCmd.Set( eType, nParam1, nParam2 );
+ maCmdHdl.Call( this );
+}
+
+
+// layout helpers -------------------------------------------------------------
+
+sal_Int32 ScCsvControl::GetVisPosCount() const
+{
+ return (mrData.mnWinWidth - GetHdrWidth()) / GetCharWidth();
+}
+
+sal_Int32 ScCsvControl::GetMaxPosOffset() const
+{
+ return Max( GetPosCount() - GetVisPosCount() + 2L, 0L );
+}
+
+bool ScCsvControl::IsValidSplitPos( sal_Int32 nPos ) const
+{
+ return (0 < nPos) && (nPos < GetPosCount() );
+}
+
+bool ScCsvControl::IsVisibleSplitPos( sal_Int32 nPos ) const
+{
+ return IsValidSplitPos( nPos ) && (GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos());
+}
+
+sal_Int32 ScCsvControl::GetHdrX() const
+{
+ return IsRTL() ? (mrData.mnWinWidth - GetHdrWidth()) : 0;
+}
+
+sal_Int32 ScCsvControl::GetFirstX() const
+{
+ return IsRTL() ? 0 : GetHdrWidth();
+}
+
+sal_Int32 ScCsvControl::GetLastX() const
+{
+ return mrData.mnWinWidth - (IsRTL() ? GetHdrWidth() : 0) - 1;
+}
+
+sal_Int32 ScCsvControl::GetX( sal_Int32 nPos ) const
+{
+ return GetFirstX() + (nPos - GetFirstVisPos()) * GetCharWidth();
+}
+
+sal_Int32 ScCsvControl::GetPosFromX( sal_Int32 nX ) const
+{
+ return (nX - GetFirstX() + GetCharWidth() / 2) / GetCharWidth() + GetFirstVisPos();
+}
+
+sal_Int32 ScCsvControl::GetVisLineCount() const
+{
+ return (mrData.mnWinHeight - GetHdrHeight() - 2) / GetLineHeight() + 1;
+}
+
+sal_Int32 ScCsvControl::GetLastVisLine() const
+{
+ return Min( GetFirstVisLine() + GetVisLineCount(), GetLineCount() ) - 1;
+}
+
+sal_Int32 ScCsvControl::GetMaxLineOffset() const
+{
+ return Max( GetLineCount() - GetVisLineCount() + 1L, 0L );
+}
+
+bool ScCsvControl::IsValidLine( sal_Int32 nLine ) const
+{
+ return (0 <= nLine) && (nLine < GetLineCount());
+}
+
+bool ScCsvControl::IsVisibleLine( sal_Int32 nLine ) const
+{
+ return IsValidLine( nLine ) && (GetFirstVisLine() <= nLine) && (nLine <= GetLastVisLine());
+}
+
+sal_Int32 ScCsvControl::GetY( sal_Int32 nLine ) const
+{
+ return GetHdrHeight() + (nLine - GetFirstVisLine()) * GetLineHeight();
+}
+
+sal_Int32 ScCsvControl::GetLineFromY( sal_Int32 nY ) const
+{
+ return (nY - GetHdrHeight()) / GetLineHeight() + GetFirstVisLine();
+}
+
+
+// static helpers -------------------------------------------------------------
+
+void ScCsvControl::ImplInvertRect( OutputDevice& rOutDev, const Rectangle& rRect )
+{
+ rOutDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_RASTEROP );
+ rOutDev.SetLineColor( Color( COL_BLACK ) );
+ rOutDev.SetFillColor( Color( COL_BLACK ) );
+ rOutDev.SetRasterOp( ROP_INVERT );
+ rOutDev.DrawRect( rRect );
+ rOutDev.Pop();
+}
+
+ScMoveMode ScCsvControl::GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd )
+{
+ switch( nCode )
+ {
+ case KEY_LEFT: return MOVE_PREV;
+ case KEY_RIGHT: return MOVE_NEXT;
+ }
+ if( bHomeEnd ) switch( nCode )
+ {
+ case KEY_HOME: return MOVE_FIRST;
+ case KEY_END: return MOVE_LAST;
+ }
+ return MOVE_NONE;
+}
+
+ScMoveMode ScCsvControl::GetVertDirection( sal_uInt16 nCode, bool bHomeEnd )
+{
+ switch( nCode )
+ {
+ case KEY_UP: return MOVE_PREV;
+ case KEY_DOWN: return MOVE_NEXT;
+ case KEY_PAGEUP: return MOVE_PREVPAGE;
+ case KEY_PAGEDOWN: return MOVE_NEXTPAGE;
+ }
+ if( bHomeEnd ) switch( nCode )
+ {
+ case KEY_HOME: return MOVE_FIRST;
+ case KEY_END: return MOVE_LAST;
+ }
+ return MOVE_NONE;
+}
+
+
+// accessibility --------------------------------------------------------------
+
+ScCsvControl::XAccessibleRef ScCsvControl::CreateAccessible()
+{
+ mpAccessible = ImplCreateAccessible();
+ mxAccessible = mpAccessible;
+ return mxAccessible;
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/csvgrid.cxx b/sc/source/ui/dbgui/csvgrid.cxx
new file mode 100644
index 000000000000..d271022a987c
--- /dev/null
+++ b/sc/source/ui/dbgui/csvgrid.cxx
@@ -0,0 +1,1355 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "csvgrid.hxx"
+
+#include <algorithm>
+#include <svtools/colorcfg.hxx>
+#include <svl/smplhint.hxx>
+#include <tools/poly.hxx>
+#include "scmod.hxx"
+#include "asciiopt.hxx"
+#include "impex.hxx"
+#include "AccessibleCsvControl.hxx"
+
+// *** edit engine ***
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svl/itemset.hxx>
+#include "editutil.hxx"
+// *** edit engine ***
+
+
+// ============================================================================
+
+struct Func_SetType
+{
+ sal_Int32 mnType;
+ inline Func_SetType( sal_Int32 nType ) : mnType( nType ) {}
+ inline void operator()( ScCsvColState& rState ) { rState.mnType = mnType; }
+};
+
+struct Func_Select
+{
+ bool mbSelect;
+ inline Func_Select( bool bSelect ) : mbSelect( bSelect ) {}
+ inline void operator()( ScCsvColState& rState ) { rState.Select( mbSelect ); }
+};
+
+
+// ============================================================================
+
+ScCsvGrid::ScCsvGrid( ScCsvControl& rParent ) :
+ ScCsvControl( rParent ),
+ mrColorConfig( SC_MOD()->GetColorConfig() ),
+ mpEditEngine( new ScEditEngineDefaulter( EditEngine::CreatePool(), TRUE ) ),
+ maHeaderFont( GetFont() ),
+ maColStates( 1 ),
+ maTypeNames( 1 ),
+ mnFirstImpLine( 0 ),
+ mnRecentSelCol( CSV_COLUMN_INVALID )
+{
+ mpEditEngine->SetRefDevice( &maBackgrDev );
+ mpEditEngine->SetRefMapMode( MapMode( MAP_PIXEL ) );
+ maEdEngSize = mpEditEngine->GetPaperSize();
+
+ maPopup.SetMenuFlags( maPopup.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+
+ EnableRTL( false ); // #107812# RTL
+ InitColors();
+ InitFonts();
+ ImplClearSplits();
+ mrColorConfig.AddListener(this);
+}
+
+ScCsvGrid::~ScCsvGrid()
+{
+ mrColorConfig.RemoveListener(this);
+}
+
+
+// common grid handling -------------------------------------------------------
+
+void ScCsvGrid::UpdateLayoutData()
+{
+ DisableRepaint();
+ SetFont( maMonoFont );
+ Execute( CSVCMD_SETCHARWIDTH, GetTextWidth( String( 'X' ) ) );
+ Execute( CSVCMD_SETLINEHEIGHT, GetTextHeight() + 1 );
+ SetFont( maHeaderFont );
+ Execute( CSVCMD_SETHDRHEIGHT, GetTextHeight() + 1 );
+ UpdateOffsetX();
+ EnableRepaint();
+}
+
+void ScCsvGrid::UpdateOffsetX()
+{
+ sal_Int32 nLastLine = GetLastVisLine() + 1;
+ sal_Int32 nDigits = 2;
+ while( nLastLine /= 10 ) ++nDigits;
+ nDigits = Max( nDigits, sal_Int32( 3 ) );
+ Execute( CSVCMD_SETHDRWIDTH, GetTextWidth( String( '0' ) ) * nDigits );
+}
+
+void ScCsvGrid::ApplyLayout( const ScCsvLayoutData& rOldData )
+{
+ ScCsvDiff nDiff = GetLayoutData().GetDiff( rOldData );
+ if( nDiff == CSV_DIFF_EQUAL ) return;
+
+ DisableRepaint();
+
+ if( nDiff & CSV_DIFF_RULERCURSOR )
+ {
+ ImplInvertCursor( rOldData.mnPosCursor );
+ ImplInvertCursor( GetRulerCursorPos() );
+ }
+
+ if( nDiff & CSV_DIFF_POSCOUNT )
+ {
+ if( GetPosCount() < rOldData.mnPosCount )
+ {
+ SelectAll( false );
+ maSplits.RemoveRange( GetPosCount(), rOldData.mnPosCount );
+ }
+ else
+ maSplits.Remove( rOldData.mnPosCount );
+ maSplits.Insert( GetPosCount() );
+ maColStates.resize( maSplits.Count() - 1 );
+ }
+
+ if( nDiff & CSV_DIFF_LINEOFFSET )
+ {
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ UpdateOffsetX();
+ }
+
+ ScCsvDiff nHVDiff = nDiff & (CSV_DIFF_HORIZONTAL | CSV_DIFF_VERTICAL);
+ if( nHVDiff == CSV_DIFF_POSOFFSET )
+ ImplDrawHorzScrolled( rOldData.mnPosOffset );
+ else if( nHVDiff != CSV_DIFF_EQUAL )
+ InvalidateGfx();
+
+ EnableRepaint();
+
+ if( nDiff & (CSV_DIFF_POSOFFSET | CSV_DIFF_LINEOFFSET) )
+ AccSendVisibleEvent();
+}
+
+void ScCsvGrid::SetFirstImportedLine( sal_Int32 nLine )
+{
+ ImplDrawFirstLineSep( false );
+ mnFirstImpLine = nLine;
+ ImplDrawFirstLineSep( true );
+ ImplDrawGridDev();
+ Repaint();
+}
+
+sal_Int32 ScCsvGrid::GetNoScrollCol( sal_Int32 nPos ) const
+{
+ sal_Int32 nNewPos = nPos;
+ if( nNewPos != CSV_POS_INVALID )
+ {
+ if( nNewPos < GetFirstVisPos() + CSV_SCROLL_DIST )
+ {
+ sal_Int32 nScroll = (GetFirstVisPos() > 0) ? CSV_SCROLL_DIST : 0;
+ nNewPos = GetFirstVisPos() + nScroll;
+ }
+ else if( nNewPos > GetLastVisPos() - CSV_SCROLL_DIST - 1L )
+ {
+ sal_Int32 nScroll = (GetFirstVisPos() < GetMaxPosOffset()) ? CSV_SCROLL_DIST : 0;
+ nNewPos = GetLastVisPos() - nScroll - 1;
+ }
+ }
+ return nNewPos;
+}
+
+void ScCsvGrid::InitColors()
+{
+ maBackColor.SetColor( static_cast< sal_uInt32 >( mrColorConfig.GetColorValue( ::svtools::DOCCOLOR ).nColor ) );
+ maGridColor.SetColor( static_cast< sal_uInt32 >( mrColorConfig.GetColorValue( ::svtools::CALCGRID ).nColor ) );
+ maGridPBColor.SetColor( static_cast< sal_uInt32 >( mrColorConfig.GetColorValue( ::svtools::CALCPAGEBREAK ).nColor ) );
+ maAppBackColor.SetColor( static_cast< sal_uInt32 >( mrColorConfig.GetColorValue( ::svtools::APPBACKGROUND ).nColor ) );
+ maTextColor.SetColor( static_cast< sal_uInt32 >( mrColorConfig.GetColorValue( ::svtools::FONTCOLOR ).nColor ) );
+
+ const StyleSettings& rSett = GetSettings().GetStyleSettings();
+ maHeaderBackColor = rSett.GetFaceColor();
+ maHeaderGridColor = rSett.GetDarkShadowColor();
+ maHeaderTextColor = rSett.GetButtonTextColor();
+ maSelectColor = rSett.GetActiveColor();
+
+ InvalidateGfx();
+}
+
+void ScCsvGrid::InitFonts()
+{
+ maMonoFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US, 0 );
+ maMonoFont.SetSize( Size( maMonoFont.GetSize().Width(), maHeaderFont.GetSize().Height() ) );
+
+ /* *** Set edit engine defaults ***
+ maMonoFont for Latin script, smaller default font for Asian and Complex script. */
+
+ // get default fonts
+ SvxFontItem aLatinItem( EE_CHAR_FONTINFO );
+ SvxFontItem aAsianItem( EE_CHAR_FONTINFO_CJK );
+ SvxFontItem aComplexItem( EE_CHAR_FONTINFO_CTL );
+ ::GetDefaultFonts( aLatinItem, aAsianItem, aComplexItem );
+
+ // create item set for defaults
+ SfxItemSet aDefSet( mpEditEngine->GetEmptyItemSet() );
+ EditEngine::SetFontInfoInItemSet( aDefSet, maMonoFont );
+ aDefSet.Put( aAsianItem );
+ aDefSet.Put( aComplexItem );
+
+ // set Asian/Complex font size to height of character in Latin font
+ ULONG nFontHt = static_cast< ULONG >( maMonoFont.GetSize().Height() );
+ aDefSet.Put( SvxFontHeightItem( nFontHt, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ aDefSet.Put( SvxFontHeightItem( nFontHt, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+
+ // copy other items from default font
+ const SfxPoolItem& rWeightItem = aDefSet.Get( EE_CHAR_WEIGHT );
+ aDefSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
+ aDefSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
+ const SfxPoolItem& rItalicItem = aDefSet.Get( EE_CHAR_ITALIC );
+ aDefSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
+ aDefSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
+ const SfxPoolItem& rLangItem = aDefSet.Get( EE_CHAR_LANGUAGE );
+ aDefSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
+ aDefSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
+
+ mpEditEngine->SetDefaults( aDefSet );
+ InvalidateGfx();
+}
+
+void ScCsvGrid::InitSizeData()
+{
+ maWinSize = GetSizePixel();
+ maBackgrDev.SetOutputSizePixel( maWinSize );
+ maGridDev.SetOutputSizePixel( maWinSize );
+ InvalidateGfx();
+}
+
+
+// split handling -------------------------------------------------------------
+
+void ScCsvGrid::InsertSplit( sal_Int32 nPos )
+{
+ if( ImplInsertSplit( nPos ) )
+ {
+ DisableRepaint();
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ sal_uInt32 nColIx = GetColumnFromPos( nPos );
+ ImplDrawColumn( nColIx - 1 );
+ ImplDrawColumn( nColIx );
+ ValidateGfx(); // performance: do not redraw all columns
+ EnableRepaint();
+ }
+}
+
+void ScCsvGrid::RemoveSplit( sal_Int32 nPos )
+{
+ if( ImplRemoveSplit( nPos ) )
+ {
+ DisableRepaint();
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ ImplDrawColumn( GetColumnFromPos( nPos ) );
+ ValidateGfx(); // performance: do not redraw all columns
+ EnableRepaint();
+ }
+}
+
+void ScCsvGrid::MoveSplit( sal_Int32 nPos, sal_Int32 nNewPos )
+{
+ sal_uInt32 nColIx = GetColumnFromPos( nPos );
+ if( nColIx != CSV_COLUMN_INVALID )
+ {
+ DisableRepaint();
+ if( (GetColumnPos( nColIx - 1 ) < nNewPos) && (nNewPos < GetColumnPos( nColIx + 1 )) )
+ {
+ // move a split in the range between 2 others -> keep selection state of both columns
+ maSplits.Remove( nPos );
+ maSplits.Insert( nNewPos );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ ImplDrawColumn( nColIx - 1 );
+ ImplDrawColumn( nColIx );
+ ValidateGfx(); // performance: do not redraw all columns
+ AccSendTableUpdateEvent( nColIx - 1, nColIx );
+ }
+ else
+ {
+ ImplRemoveSplit( nPos );
+ ImplInsertSplit( nNewPos );
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ }
+ EnableRepaint();
+ }
+}
+
+void ScCsvGrid::RemoveAllSplits()
+{
+ DisableRepaint();
+ ImplClearSplits();
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ EnableRepaint();
+}
+
+void ScCsvGrid::SetSplits( const ScCsvSplits& rSplits )
+{
+ DisableRepaint();
+ ImplClearSplits();
+ sal_uInt32 nCount = rSplits.Count();
+ for( sal_uInt32 nIx = 0; nIx < nCount; ++nIx )
+ maSplits.Insert( rSplits[ nIx ] );
+ maColStates.clear();
+ maColStates.resize( maSplits.Count() - 1 );
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ EnableRepaint();
+}
+
+bool ScCsvGrid::ImplInsertSplit( sal_Int32 nPos )
+{
+ sal_uInt32 nColIx = GetColumnFromPos( nPos );
+ bool bRet = (nColIx < GetColumnCount()) && maSplits.Insert( nPos );
+ if( bRet )
+ {
+ ScCsvColState aState( GetColumnType( nColIx ) );
+ aState.Select( IsSelected( nColIx ) && IsSelected( nColIx + 1 ) );
+ maColStates.insert( maColStates.begin() + nColIx + 1, aState );
+ AccSendInsertColumnEvent( nColIx + 1, nColIx + 1 );
+ AccSendTableUpdateEvent( nColIx, nColIx );
+ }
+ return bRet;
+}
+
+bool ScCsvGrid::ImplRemoveSplit( sal_Int32 nPos )
+{
+ bool bRet = maSplits.Remove( nPos );
+ if( bRet )
+ {
+ sal_uInt32 nColIx = GetColumnFromPos( nPos );
+ bool bSel = IsSelected( nColIx ) || IsSelected( nColIx + 1 );
+ maColStates.erase( maColStates.begin() + nColIx + 1 );
+ maColStates[ nColIx ].Select( bSel );
+ AccSendRemoveColumnEvent( nColIx + 1, nColIx + 1 );
+ AccSendTableUpdateEvent( nColIx, nColIx );
+ }
+ return bRet;
+}
+
+void ScCsvGrid::ImplClearSplits()
+{
+ sal_uInt32 nColumns = GetColumnCount();
+ maSplits.Clear();
+ maSplits.Insert( 0 );
+ maSplits.Insert( GetPosCount() );
+ maColStates.resize( 1 );
+ InvalidateGfx();
+ AccSendRemoveColumnEvent( 1, nColumns - 1 );
+}
+
+// columns/column types -------------------------------------------------------
+
+sal_uInt32 ScCsvGrid::GetFirstVisColumn() const
+{
+ return GetColumnFromPos( GetFirstVisPos() );
+}
+
+sal_uInt32 ScCsvGrid::GetLastVisColumn() const
+{
+ return GetColumnFromPos( Min( GetLastVisPos(), GetPosCount() ) - 1 );
+}
+
+bool ScCsvGrid::IsValidColumn( sal_uInt32 nColIndex ) const
+{
+ return nColIndex < GetColumnCount();
+}
+
+bool ScCsvGrid::IsVisibleColumn( sal_uInt32 nColIndex ) const
+{
+ return IsValidColumn( nColIndex ) &&
+ (GetColumnPos( nColIndex ) < GetLastVisPos()) &&
+ (GetFirstVisPos() < GetColumnPos( nColIndex + 1 ));
+}
+
+sal_Int32 ScCsvGrid::GetColumnX( sal_uInt32 nColIndex ) const
+{
+ return GetX( GetColumnPos( nColIndex ) );
+}
+
+sal_uInt32 ScCsvGrid::GetColumnFromX( sal_Int32 nX ) const
+{
+ sal_Int32 nPos = (nX - GetFirstX()) / GetCharWidth() + GetFirstVisPos();
+ return ((GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos())) ?
+ GetColumnFromPos( nPos ) : CSV_COLUMN_INVALID;
+}
+
+sal_uInt32 ScCsvGrid::GetColumnFromPos( sal_Int32 nPos ) const
+{
+ return maSplits.UpperBound( nPos );
+}
+
+sal_Int32 ScCsvGrid::GetColumnWidth( sal_uInt32 nColIndex ) const
+{
+ return IsValidColumn( nColIndex ) ? (GetColumnPos( nColIndex + 1 ) - GetColumnPos( nColIndex )) : 0;
+}
+
+void ScCsvGrid::SetColumnStates( const ScCsvColStateVec& rStates )
+{
+ maColStates = rStates;
+ maColStates.resize( maSplits.Count() - 1 );
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ AccSendTableUpdateEvent( 0, GetColumnCount(), false );
+ AccSendSelectionEvent();
+}
+
+sal_Int32 ScCsvGrid::GetColumnType( sal_uInt32 nColIndex ) const
+{
+ return IsValidColumn( nColIndex ) ? maColStates[ nColIndex ].mnType : CSV_TYPE_NOSELECTION;
+}
+
+void ScCsvGrid::SetColumnType( sal_uInt32 nColIndex, sal_Int32 nColType )
+{
+ if( IsValidColumn( nColIndex ) )
+ {
+ maColStates[ nColIndex ].mnType = nColType;
+ AccSendTableUpdateEvent( nColIndex, nColIndex, false );
+ }
+}
+
+sal_Int32 ScCsvGrid::GetSelColumnType() const
+{
+ sal_uInt32 nColIx = GetFirstSelected();
+ if( nColIx == CSV_COLUMN_INVALID )
+ return CSV_TYPE_NOSELECTION;
+
+ sal_Int32 nType = GetColumnType( nColIx );
+ while( (nColIx != CSV_COLUMN_INVALID) && (nType != CSV_TYPE_MULTI) )
+ {
+ if( nType != GetColumnType( nColIx ) )
+ nType = CSV_TYPE_MULTI;
+ nColIx = GetNextSelected( nColIx );
+ }
+ return nType;
+}
+
+void ScCsvGrid::SetSelColumnType( sal_Int32 nType )
+{
+ if( (nType != CSV_TYPE_MULTI) && (nType != CSV_TYPE_NOSELECTION) )
+ {
+ for( sal_uInt32 nColIx = GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = GetNextSelected( nColIx ) )
+ SetColumnType( nColIx, nType );
+ Repaint( true );
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ }
+}
+
+void ScCsvGrid::SetTypeNames( const StringVec& rTypeNames )
+{
+ DBG_ASSERT( !rTypeNames.empty(), "ScCsvGrid::SetTypeNames - vector is empty" );
+ maTypeNames = rTypeNames;
+ Repaint( true );
+
+ maPopup.Clear();
+ sal_uInt32 nCount = maTypeNames.size();
+ sal_uInt32 nIx;
+ sal_uInt16 nItemId;
+ for( nIx = 0, nItemId = 1; nIx < nCount; ++nIx, ++nItemId )
+ maPopup.InsertItem( nItemId, maTypeNames[ nIx ] );
+
+ ::std::for_each( maColStates.begin(), maColStates.end(), Func_SetType( CSV_TYPE_DEFAULT ) );
+}
+
+const String& ScCsvGrid::GetColumnTypeName( sal_uInt32 nColIndex ) const
+{
+ sal_uInt32 nTypeIx = static_cast< sal_uInt32 >( GetColumnType( nColIndex ) );
+ return (nTypeIx < maTypeNames.size()) ? maTypeNames[ nTypeIx ] : EMPTY_STRING;
+}
+
+sal_uInt8 lcl_GetExtColumnType( sal_Int32 nIntType )
+{
+ static sal_uInt8 pExtTypes[] =
+ { SC_COL_STANDARD, SC_COL_TEXT, SC_COL_DMY, SC_COL_MDY, SC_COL_YMD, SC_COL_ENGLISH, SC_COL_SKIP };
+ static sal_Int32 nExtTypeCount = sizeof( pExtTypes ) / sizeof( *pExtTypes );
+ return pExtTypes[ ((0 <= nIntType) && (nIntType < nExtTypeCount)) ? nIntType : 0 ];
+}
+
+void ScCsvGrid::FillColumnDataSep( ScAsciiOptions& rOptions ) const
+{
+ sal_uInt32 nCount = GetColumnCount();
+ ScCsvExpDataVec aDataVec;
+
+ for( sal_uInt32 nColIx = 0; nColIx < nCount; ++nColIx )
+ {
+ if( GetColumnType( nColIx ) != CSV_TYPE_DEFAULT )
+ // 1-based column index
+ aDataVec.push_back( ScCsvExpData(
+ static_cast< xub_StrLen >( nColIx + 1 ),
+ lcl_GetExtColumnType( GetColumnType( nColIx ) ) ) );
+ }
+ rOptions.SetColumnInfo( aDataVec );
+}
+
+void ScCsvGrid::FillColumnDataFix( ScAsciiOptions& rOptions ) const
+{
+ sal_uInt32 nCount = Min( GetColumnCount(), static_cast<sal_uInt32>(MAXCOLCOUNT) );
+ ScCsvExpDataVec aDataVec( nCount + 1 );
+
+ for( sal_uInt32 nColIx = 0; nColIx < nCount; ++nColIx )
+ {
+ ScCsvExpData& rData = aDataVec[ nColIx ];
+ rData.mnIndex = static_cast< xub_StrLen >(
+ Min( static_cast< sal_Int32 >( STRING_MAXLEN ), GetColumnPos( nColIx ) ) );
+ rData.mnType = lcl_GetExtColumnType( GetColumnType( nColIx ) );
+ }
+ aDataVec[ nCount ].mnIndex = STRING_MAXLEN;
+ aDataVec[ nCount ].mnType = SC_COL_SKIP;
+ rOptions.SetColumnInfo( aDataVec );
+}
+
+void ScCsvGrid::ScrollVertRel( ScMoveMode eDir )
+{
+ sal_Int32 nLine = GetFirstVisLine();
+ switch( eDir )
+ {
+ case MOVE_PREV: --nLine; break;
+ case MOVE_NEXT: ++nLine; break;
+ case MOVE_FIRST: nLine = 0; break;
+ case MOVE_LAST: nLine = GetMaxLineOffset(); break;
+ case MOVE_PREVPAGE: nLine -= GetVisLineCount() - 2; break;
+ case MOVE_NEXTPAGE: nLine += GetVisLineCount() - 2; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ Execute( CSVCMD_SETLINEOFFSET, nLine );
+}
+
+void ScCsvGrid::ExecutePopup( const Point& rPos )
+{
+ sal_uInt16 nItemId = maPopup.Execute( this, rPos );
+ if( nItemId ) // 0 = cancelled
+ Execute( CSVCMD_SETCOLUMNTYPE, maPopup.GetItemPos( nItemId ) );
+}
+
+
+// selection handling ---------------------------------------------------------
+
+bool ScCsvGrid::IsSelected( sal_uInt32 nColIndex ) const
+{
+ return IsValidColumn( nColIndex ) && maColStates[ nColIndex ].IsSelected();
+}
+
+sal_uInt32 ScCsvGrid::GetFirstSelected() const
+{
+ return IsSelected( 0 ) ? 0 : GetNextSelected( 0 );
+}
+
+sal_uInt32 ScCsvGrid::GetNextSelected( sal_uInt32 nFromIndex ) const
+{
+ sal_uInt32 nColCount = GetColumnCount();
+ for( sal_uInt32 nColIx = nFromIndex + 1; nColIx < nColCount; ++nColIx )
+ if( IsSelected( nColIx ) )
+ return nColIx;
+ return CSV_COLUMN_INVALID;
+}
+
+void ScCsvGrid::Select( sal_uInt32 nColIndex, bool bSelect )
+{
+ if( IsValidColumn( nColIndex ) )
+ {
+ maColStates[ nColIndex ].Select( bSelect );
+ ImplDrawColumnSelection( nColIndex );
+ Repaint();
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ if( bSelect )
+ mnRecentSelCol = nColIndex;
+ AccSendSelectionEvent();
+ }
+}
+
+void ScCsvGrid::ToggleSelect( sal_uInt32 nColIndex )
+{
+ Select( nColIndex, !IsSelected( nColIndex ) );
+}
+
+void ScCsvGrid::SelectRange( sal_uInt32 nColIndex1, sal_uInt32 nColIndex2, bool bSelect )
+{
+ if( nColIndex1 == CSV_COLUMN_INVALID )
+ Select( nColIndex2 );
+ else if( nColIndex2 == CSV_COLUMN_INVALID )
+ Select( nColIndex1 );
+ else if( nColIndex1 > nColIndex2 )
+ {
+ SelectRange( nColIndex2, nColIndex1, bSelect );
+ if( bSelect )
+ mnRecentSelCol = nColIndex1;
+ }
+ else if( IsValidColumn( nColIndex1 ) && IsValidColumn( nColIndex2 ) )
+ {
+ for( sal_uInt32 nColIx = nColIndex1; nColIx <= nColIndex2; ++nColIx )
+ {
+ maColStates[ nColIx ].Select( bSelect );
+ ImplDrawColumnSelection( nColIx );
+ }
+ Repaint();
+ Execute( CSVCMD_EXPORTCOLUMNTYPE );
+ if( bSelect )
+ mnRecentSelCol = nColIndex1;
+ AccSendSelectionEvent();
+ }
+}
+
+void ScCsvGrid::SelectAll( bool bSelect )
+{
+ SelectRange( 0, GetColumnCount() - 1, bSelect );
+}
+
+void ScCsvGrid::MoveCursor( sal_uInt32 nColIndex )
+{
+ DisableRepaint();
+ if( IsValidColumn( nColIndex ) )
+ {
+ sal_Int32 nPosBeg = GetColumnPos( nColIndex );
+ sal_Int32 nPosEnd = GetColumnPos( nColIndex + 1 );
+ sal_Int32 nMinPos = Max( nPosBeg - CSV_SCROLL_DIST, sal_Int32( 0 ) );
+ sal_Int32 nMaxPos = Min( nPosEnd - GetVisPosCount() + CSV_SCROLL_DIST + sal_Int32( 1 ), nMinPos );
+ if( nPosBeg - CSV_SCROLL_DIST + 1 <= GetFirstVisPos() )
+ Execute( CSVCMD_SETPOSOFFSET, nMinPos );
+ else if( nPosEnd + CSV_SCROLL_DIST >= GetLastVisPos() )
+ Execute( CSVCMD_SETPOSOFFSET, nMaxPos );
+ }
+ Execute( CSVCMD_MOVEGRIDCURSOR, GetColumnPos( nColIndex ) );
+ EnableRepaint();
+}
+
+void ScCsvGrid::MoveCursorRel( ScMoveMode eDir )
+{
+ if( GetFocusColumn() != CSV_COLUMN_INVALID )
+ {
+ switch( eDir )
+ {
+ case MOVE_FIRST:
+ MoveCursor( 0 );
+ break;
+ case MOVE_LAST:
+ MoveCursor( GetColumnCount() - 1 );
+ break;
+ case MOVE_PREV:
+ if( GetFocusColumn() > 0 )
+ MoveCursor( GetFocusColumn() - 1 );
+ break;
+ case MOVE_NEXT:
+ if( GetFocusColumn() < GetColumnCount() - 1 )
+ MoveCursor( GetFocusColumn() + 1 );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+void ScCsvGrid::ImplClearSelection()
+{
+ ::std::for_each( maColStates.begin(), maColStates.end(), Func_Select( false ) );
+ ImplDrawGridDev();
+}
+
+void ScCsvGrid::DoSelectAction( sal_uInt32 nColIndex, sal_uInt16 nModifier )
+{
+ if( !(nModifier & KEY_MOD1) )
+ ImplClearSelection();
+ if( nModifier & KEY_SHIFT ) // SHIFT always expands
+ SelectRange( mnRecentSelCol, nColIndex );
+ else if( !(nModifier & KEY_MOD1) ) // no SHIFT/CTRL always selects 1 column
+ Select( nColIndex );
+ else if( IsTracking() ) // CTRL in tracking does not toggle
+ Select( nColIndex, mbMTSelecting );
+ else // CTRL only toggles
+ ToggleSelect( nColIndex );
+ Execute( CSVCMD_MOVEGRIDCURSOR, GetColumnPos( nColIndex ) );
+}
+
+
+// cell contents --------------------------------------------------------------
+
+void ScCsvGrid::ImplSetTextLineSep(
+ sal_Int32 nLine, const String& rTextLine,
+ const String& rSepChars, sal_Unicode cTextSep, bool bMergeSep )
+{
+ if( nLine < GetFirstVisLine() ) return;
+
+ sal_uInt32 nLineIx = nLine - GetFirstVisLine();
+ while( maTexts.size() <= nLineIx )
+ maTexts.push_back( StringVec() );
+ StringVec& rStrVec = maTexts[ nLineIx ];
+ rStrVec.clear();
+
+ // scan for separators
+ String aCellText;
+ const sal_Unicode* pSepChars = rSepChars.GetBuffer();
+ const sal_Unicode* pChar = rTextLine.GetBuffer();
+ sal_uInt32 nColIx = 0;
+
+ while( *pChar && (nColIx < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT)) )
+ {
+ // scan for next cell text
+ bool bIsQuoted = false;
+ pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText, cTextSep, pSepChars, bMergeSep, bIsQuoted );
+
+ // update column width
+ sal_Int32 nWidth = Max( CSV_MINCOLWIDTH, aCellText.Len() + sal_Int32( 1 ) );
+ if( IsValidColumn( nColIx ) )
+ {
+ // expand existing column
+ sal_Int32 nDiff = nWidth - GetColumnWidth( nColIx );
+ if( nDiff > 0 )
+ {
+ Execute( CSVCMD_SETPOSCOUNT, GetPosCount() + nDiff );
+ for( sal_uInt32 nSplitIx = GetColumnCount() - 1; nSplitIx > nColIx; --nSplitIx )
+ {
+ sal_Int32 nPos = maSplits[ nSplitIx ];
+ maSplits.Remove( nPos );
+ maSplits.Insert( nPos + nDiff );
+ }
+ }
+ }
+ else
+ {
+ // append new column
+ sal_Int32 nLastPos = GetPosCount();
+ Execute( CSVCMD_SETPOSCOUNT, nLastPos + nWidth );
+ ImplInsertSplit( nLastPos );
+ }
+
+ if( aCellText.Len() <= CSV_MAXSTRLEN )
+ rStrVec.push_back( aCellText );
+ else
+ rStrVec.push_back( aCellText.Copy( 0, CSV_MAXSTRLEN ) );
+ ++nColIx;
+ }
+ InvalidateGfx();
+}
+
+void ScCsvGrid::ImplSetTextLineFix( sal_Int32 nLine, const String& rTextLine )
+{
+ if( nLine < GetFirstVisLine() ) return;
+
+ sal_Int32 nChars = rTextLine.Len();
+ if( nChars > GetPosCount() )
+ Execute( CSVCMD_SETPOSCOUNT, nChars );
+
+ sal_uInt32 nLineIx = nLine - GetFirstVisLine();
+ while( maTexts.size() <= nLineIx )
+ maTexts.push_back( StringVec() );
+
+ StringVec& rStrVec = maTexts[ nLineIx ];
+ rStrVec.clear();
+ sal_uInt32 nColCount = GetColumnCount();
+ xub_StrLen nStrLen = rTextLine.Len();
+ xub_StrLen nStrIx = 0;
+ for( sal_uInt32 nColIx = 0; (nColIx < nColCount) && (nStrIx < nStrLen); ++nColIx )
+ {
+ xub_StrLen nColWidth = static_cast< xub_StrLen >( GetColumnWidth( nColIx ) );
+ rStrVec.push_back( rTextLine.Copy( nStrIx, Max( nColWidth, CSV_MAXSTRLEN ) ) );
+ nStrIx = sal::static_int_cast<xub_StrLen>( nStrIx + nColWidth );
+ }
+ InvalidateGfx();
+}
+
+const String& ScCsvGrid::GetCellText( sal_uInt32 nColIndex, sal_Int32 nLine ) const
+{
+ if( nLine < GetFirstVisLine() ) return EMPTY_STRING;
+
+ sal_uInt32 nLineIx = nLine - GetFirstVisLine();
+ if( nLineIx >= maTexts.size() ) return EMPTY_STRING;
+
+ const StringVec& rStrVec = maTexts[ nLineIx ];
+ if( nColIndex >= rStrVec.size() ) return EMPTY_STRING;
+
+ return rStrVec[ nColIndex ];
+}
+
+
+// event handling -------------------------------------------------------------
+
+void ScCsvGrid::Resize()
+{
+ ScCsvControl::Resize();
+ InitSizeData();
+ Execute( CSVCMD_UPDATECELLTEXTS );
+}
+
+void ScCsvGrid::GetFocus()
+{
+ ScCsvControl::GetFocus();
+ Execute( CSVCMD_MOVEGRIDCURSOR, GetNoScrollCol( GetGridCursorPos() ) );
+ Repaint();
+}
+
+void ScCsvGrid::LoseFocus()
+{
+ ScCsvControl::LoseFocus();
+ Repaint();
+}
+
+void ScCsvGrid::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ DisableRepaint();
+ if( !HasFocus() )
+ GrabFocus();
+
+ Point aPos( rMEvt.GetPosPixel() );
+ sal_uInt32 nColIx = GetColumnFromX( aPos.X() );
+
+ if( rMEvt.IsLeft() )
+ {
+ if( (GetFirstX() > aPos.X()) || (aPos.X() > GetLastX()) ) // in header column
+ {
+ if( aPos.Y() <= GetHdrHeight() )
+ SelectAll();
+ }
+ else if( IsValidColumn( nColIx ) )
+ {
+ DoSelectAction( nColIx, rMEvt.GetModifier() );
+ mnMTCurrCol = nColIx;
+ mbMTSelecting = IsSelected( nColIx );
+ StartTracking( STARTTRACK_BUTTONREPEAT );
+ }
+ }
+ EnableRepaint();
+}
+
+void ScCsvGrid::Tracking( const TrackingEvent& rTEvt )
+{
+ if( rTEvt.IsTrackingEnded() || rTEvt.IsTrackingRepeat() )
+ {
+ DisableRepaint();
+ const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
+
+ sal_Int32 nPos = (rMEvt.GetPosPixel().X() - GetFirstX()) / GetCharWidth() + GetFirstVisPos();
+ // on mouse tracking: keep position valid
+ nPos = Max( Min( nPos, GetPosCount() - sal_Int32( 1 ) ), sal_Int32( 0 ) );
+ Execute( CSVCMD_MAKEPOSVISIBLE, nPos );
+
+ sal_uInt32 nColIx = GetColumnFromPos( nPos );
+ if( mnMTCurrCol != nColIx )
+ {
+ DoSelectAction( nColIx, rMEvt.GetModifier() );
+ mnMTCurrCol = nColIx;
+ }
+ EnableRepaint();
+ }
+}
+
+void ScCsvGrid::KeyInput( const KeyEvent& rKEvt )
+{
+ const KeyCode& rKCode = rKEvt.GetKeyCode();
+ sal_uInt16 nCode = rKCode.GetCode();
+ bool bShift = rKCode.IsShift() == TRUE;
+ bool bMod1 = rKCode.IsMod1() == TRUE;
+
+ if( !rKCode.IsMod2() )
+ {
+ ScMoveMode eHDir = GetHorzDirection( nCode, !bMod1 );
+ ScMoveMode eVDir = GetVertDirection( nCode, bMod1 );
+
+ if( eHDir != MOVE_NONE )
+ {
+ DisableRepaint();
+ MoveCursorRel( eHDir );
+ if( !bMod1 )
+ ImplClearSelection();
+ if( bShift )
+ SelectRange( mnRecentSelCol, GetFocusColumn() );
+ else if( !bMod1 )
+ Select( GetFocusColumn() );
+ EnableRepaint();
+ }
+ else if( eVDir != MOVE_NONE )
+ ScrollVertRel( eVDir );
+ else if( nCode == KEY_SPACE )
+ {
+ if( !bMod1 )
+ ImplClearSelection();
+ if( bShift )
+ SelectRange( mnRecentSelCol, GetFocusColumn() );
+ else if( bMod1 )
+ ToggleSelect( GetFocusColumn() );
+ else
+ Select( GetFocusColumn() );
+ }
+ else if( !bShift && bMod1 )
+ {
+ if( nCode == KEY_A )
+ SelectAll();
+ else if( (KEY_1 <= nCode) && (nCode <= KEY_9) )
+ {
+ sal_uInt32 nType = nCode - KEY_1;
+ if( nType < maTypeNames.size() )
+ Execute( CSVCMD_SETCOLUMNTYPE, nType );
+ }
+ }
+ }
+
+ if( rKCode.GetGroup() != KEYGROUP_CURSOR )
+ ScCsvControl::KeyInput( rKEvt );
+}
+
+void ScCsvGrid::Command( const CommandEvent& rCEvt )
+{
+ switch( rCEvt.GetCommand() )
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ if( rCEvt.IsMouseEvent() )
+ {
+ Point aPos( rCEvt.GetMousePosPixel() );
+ sal_uInt32 nColIx = GetColumnFromX( aPos.X() );
+ if( IsValidColumn( nColIx ) && (GetFirstX() <= aPos.X()) && (aPos.X() <= GetLastX()) )
+ {
+ if( !IsSelected( nColIx ) )
+ DoSelectAction( nColIx, 0 ); // focus & select
+ ExecutePopup( aPos );
+ }
+ }
+ else
+ {
+ sal_uInt32 nColIx = GetFocusColumn();
+ if( !IsSelected( nColIx ) )
+ Select( nColIx );
+ sal_Int32 nX1 = Max( GetColumnX( nColIx ), GetFirstX() );
+ sal_Int32 nX2 = Min( GetColumnX( nColIx + 1 ), GetWidth() );
+ ExecutePopup( Point( (nX1 + nX2) / 2, GetHeight() / 2 ) );
+ }
+ }
+ break;
+ case COMMAND_WHEEL:
+ {
+ Point aPoint;
+ Rectangle aRect( aPoint, maWinSize );
+ if( aRect.IsInside( rCEvt.GetMousePosPixel() ) )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( pData && (pData->GetMode() == COMMAND_WHEEL_SCROLL) && !pData->IsHorz() )
+ Execute( CSVCMD_SETLINEOFFSET, GetFirstVisLine() - pData->GetNotchDelta() );
+ }
+ }
+ break;
+ default:
+ ScCsvControl::Command( rCEvt );
+ }
+}
+
+void ScCsvGrid::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ InitColors();
+ InitFonts();
+ UpdateLayoutData();
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ }
+ ScCsvControl::DataChanged( rDCEvt );
+}
+
+void ScCsvGrid::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
+{
+ InitColors();
+ Repaint();
+}
+
+
+// painting -------------------------------------------------------------------
+
+void ScCsvGrid::Paint( const Rectangle& )
+{
+ Repaint();
+}
+
+void ScCsvGrid::ImplRedraw()
+{
+ if( IsVisible() )
+ {
+ if( !IsValidGfx() )
+ {
+ ValidateGfx();
+ ImplDrawBackgrDev();
+ ImplDrawGridDev();
+ }
+ DrawOutDev( Point(), maWinSize, Point(), maWinSize, maGridDev );
+ ImplDrawTrackingRect( GetFocusColumn() );
+ }
+}
+
+EditEngine* ScCsvGrid::GetEditEngine()
+{
+ return mpEditEngine.get();
+}
+
+void ScCsvGrid::ImplSetColumnClipRegion( OutputDevice& rOutDev, sal_uInt32 nColIndex )
+{
+ rOutDev.SetClipRegion( Region( Rectangle(
+ Max( GetColumnX( nColIndex ), GetFirstX() ) + 1, 0,
+ Min( GetColumnX( nColIndex + 1 ), GetLastX() ), GetHeight() - 1 ) ) );
+}
+
+void ScCsvGrid::ImplDrawColumnHeader( OutputDevice& rOutDev, sal_uInt32 nColIndex, Color aFillColor )
+{
+ sal_Int32 nX1 = GetColumnX( nColIndex ) + 1;
+ sal_Int32 nX2 = GetColumnX( nColIndex + 1 );
+ sal_Int32 nHdrHt = GetHdrHeight();
+
+ rOutDev.SetLineColor();
+ rOutDev.SetFillColor( aFillColor );
+ rOutDev.DrawRect( Rectangle( nX1, 0, nX2, nHdrHt ) );
+
+ rOutDev.SetFont( maHeaderFont );
+ rOutDev.SetTextColor( maHeaderTextColor );
+ rOutDev.SetTextFillColor();
+ rOutDev.DrawText( Point( nX1 + 1, 0 ), GetColumnTypeName( nColIndex ) );
+
+ rOutDev.SetLineColor( maHeaderGridColor );
+ rOutDev.DrawLine( Point( nX1, nHdrHt ), Point( nX2, nHdrHt ) );
+ rOutDev.DrawLine( Point( nX2, 0 ), Point( nX2, nHdrHt ) );
+}
+
+void ScCsvGrid::ImplDrawCellText( const Point& rPos, const String& rText )
+{
+ String aPlainText( rText );
+ aPlainText.SearchAndReplaceAll( '\t', ' ' );
+ aPlainText.SearchAndReplaceAll( '\n', ' ' );
+ mpEditEngine->SetPaperSize( maEdEngSize );
+
+ /* #i60296# If string contains mixed script types, the space character
+ U+0020 may be drawn with a wrong width (from non-fixed-width Asian or
+ Complex font). Now we draw every non-space portion separately. */
+ xub_StrLen nTokenCount = aPlainText.GetTokenCount( ' ' );
+ xub_StrLen nCharIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCount; ++nToken )
+ {
+ xub_StrLen nBeginIx = nCharIx;
+ String aToken = aPlainText.GetToken( 0, ' ', nCharIx );
+ if( aToken.Len() > 0 )
+ {
+ sal_Int32 nX = rPos.X() + GetCharWidth() * nBeginIx;
+ mpEditEngine->SetText( aToken );
+ mpEditEngine->Draw( &maBackgrDev, Point( nX, rPos.Y() ) );
+ }
+ }
+
+ nCharIx = 0;
+ while( (nCharIx = rText.Search( '\t', nCharIx )) != STRING_NOTFOUND )
+ {
+ sal_Int32 nX1 = rPos.X() + GetCharWidth() * nCharIx;
+ sal_Int32 nX2 = nX1 + GetCharWidth() - 2;
+ sal_Int32 nY = rPos.Y() + GetLineHeight() / 2;
+ Color aColor( maTextColor );
+ maBackgrDev.SetLineColor( aColor );
+ maBackgrDev.DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
+ maBackgrDev.DrawLine( Point( nX2 - 2, nY - 2 ), Point( nX2, nY ) );
+ maBackgrDev.DrawLine( Point( nX2 - 2, nY + 2 ), Point( nX2, nY ) );
+ ++nCharIx;
+ }
+ nCharIx = 0;
+ while( (nCharIx = rText.Search( '\n', nCharIx )) != STRING_NOTFOUND )
+ {
+ sal_Int32 nX1 = rPos.X() + GetCharWidth() * nCharIx;
+ sal_Int32 nX2 = nX1 + GetCharWidth() - 2;
+ sal_Int32 nY = rPos.Y() + GetLineHeight() / 2;
+ Color aColor( maTextColor );
+ maBackgrDev.SetLineColor( aColor );
+ maBackgrDev.DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
+ maBackgrDev.DrawLine( Point( nX1 + 2, nY - 2 ), Point( nX1, nY ) );
+ maBackgrDev.DrawLine( Point( nX1 + 2, nY + 2 ), Point( nX1, nY ) );
+ maBackgrDev.DrawLine( Point( nX2, nY - 2 ), Point( nX2, nY ) );
+ ++nCharIx;
+ }
+}
+
+void ScCsvGrid::ImplDrawFirstLineSep( bool bSet )
+{
+ if( IsVisibleLine( mnFirstImpLine ) && (mnFirstImpLine != GetFirstVisLine() ) )
+ {
+ sal_Int32 nY = GetY( mnFirstImpLine );
+ sal_Int32 nX = Min( GetColumnX( GetLastVisColumn() + 1 ), GetLastX() );
+ maBackgrDev.SetLineColor( bSet ? maGridPBColor : maGridColor );
+ maBackgrDev.DrawLine( Point( GetFirstX() + 1, nY ), Point( nX, nY ) );
+ }
+}
+
+void ScCsvGrid::ImplDrawColumnBackgr( sal_uInt32 nColIndex )
+{
+ if( !IsVisibleColumn( nColIndex ) )
+ return;
+
+ ImplSetColumnClipRegion( maBackgrDev, nColIndex );
+
+ // grid
+ maBackgrDev.SetLineColor();
+ maBackgrDev.SetFillColor( maBackColor );
+ sal_Int32 nX1 = GetColumnX( nColIndex ) + 1;
+ sal_Int32 nX2 = GetColumnX( nColIndex + 1 );
+ sal_Int32 nY2 = GetY( GetLastVisLine() + 1 );
+ sal_Int32 nHdrHt = GetHdrHeight();
+ Rectangle aRect( nX1, nHdrHt, nX2, nY2 );
+ maBackgrDev.DrawRect( aRect );
+ maBackgrDev.SetLineColor( maGridColor );
+ maBackgrDev.DrawGrid( aRect, Size( 1, GetLineHeight() ), GRID_HORZLINES );
+ maBackgrDev.DrawLine( Point( nX2, nHdrHt ), Point( nX2, nY2 ) );
+ ImplDrawFirstLineSep( true );
+
+ // cell texts
+ mpEditEngine->SetDefaultItem( SvxColorItem( maTextColor, EE_CHAR_COLOR ) );
+ size_t nLineCount = ::std::min( static_cast< size_t >( GetLastVisLine() - GetFirstVisLine() + 1 ), maTexts.size() );
+ // #i67432# cut string to avoid edit engine performance problems with very large strings
+ sal_Int32 nFirstVisPos = ::std::max( GetColumnPos( nColIndex ), GetFirstVisPos() );
+ sal_Int32 nLastVisPos = ::std::min( GetColumnPos( nColIndex + 1 ), GetLastVisPos() );
+ xub_StrLen nStrPos = static_cast< xub_StrLen >( nFirstVisPos - GetColumnPos( nColIndex ) );
+ xub_StrLen nStrLen = static_cast< xub_StrLen >( nLastVisPos - nFirstVisPos + 1 );
+ sal_Int32 nStrX = GetX( nFirstVisPos );
+ for( size_t nLine = 0; nLine < nLineCount; ++nLine )
+ {
+ StringVec& rStrVec = maTexts[ nLine ];
+ if( (nColIndex < rStrVec.size()) && (rStrVec[ nColIndex ].Len() > nStrPos) )
+ {
+ String aText( rStrVec[ nColIndex ], nStrPos, nStrLen );
+ ImplDrawCellText( Point( nStrX, GetY( GetFirstVisLine() + nLine ) ), aText );
+ }
+ }
+
+ // header
+ ImplDrawColumnHeader( maBackgrDev, nColIndex, maHeaderBackColor );
+
+ maBackgrDev.SetClipRegion();
+}
+
+void ScCsvGrid::ImplDrawRowHeaders()
+{
+ maBackgrDev.SetLineColor();
+ maBackgrDev.SetFillColor( maAppBackColor );
+ Point aPoint( GetHdrX(), 0 );
+ Rectangle aRect( aPoint, Size( GetHdrWidth() + 1, GetHeight() ) );
+ maBackgrDev.DrawRect( aRect );
+
+ maBackgrDev.SetFillColor( maHeaderBackColor );
+ aRect.Bottom() = GetY( GetLastVisLine() + 1 );
+ maBackgrDev.DrawRect( aRect );
+
+ // line numbers
+ maBackgrDev.SetFont( maHeaderFont );
+ maBackgrDev.SetTextColor( maHeaderTextColor );
+ maBackgrDev.SetTextFillColor();
+ sal_Int32 nLastLine = GetLastVisLine();
+ for( sal_Int32 nLine = GetFirstVisLine(); nLine <= nLastLine; ++nLine )
+ {
+ String aText( String::CreateFromInt32( nLine + 1 ) );
+ sal_Int32 nX = GetHdrX() + (GetHdrWidth() - maBackgrDev.GetTextWidth( aText )) / 2;
+ maBackgrDev.DrawText( Point( nX, GetY( nLine ) ), aText );
+ }
+
+ // grid
+ maBackgrDev.SetLineColor( maHeaderGridColor );
+ if( IsRTL() )
+ {
+ maBackgrDev.DrawLine( Point( 0, 0 ), Point( 0, GetHeight() - 1 ) );
+ maBackgrDev.DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
+ }
+ else
+ maBackgrDev.DrawLine( aRect.TopRight(), aRect.BottomRight() );
+ aRect.Top() = GetHdrHeight();
+ maBackgrDev.DrawGrid( aRect, Size( 1, GetLineHeight() ), GRID_HORZLINES );
+}
+
+void ScCsvGrid::ImplDrawBackgrDev()
+{
+ maBackgrDev.SetLineColor();
+ maBackgrDev.SetFillColor( maAppBackColor );
+ maBackgrDev.DrawRect( Rectangle(
+ Point( GetFirstX() + 1, 0 ), Size( GetWidth() - GetHdrWidth(), GetHeight() ) ) );
+
+ sal_uInt32 nLastCol = GetLastVisColumn();
+ for( sal_uInt32 nColIx = GetFirstVisColumn(); nColIx <= nLastCol; ++nColIx )
+ ImplDrawColumnBackgr( nColIx );
+
+ ImplDrawRowHeaders();
+}
+
+void ScCsvGrid::ImplDrawColumnSelection( sal_uInt32 nColIndex )
+{
+ ImplInvertCursor( GetRulerCursorPos() );
+ ImplSetColumnClipRegion( maGridDev, nColIndex );
+ maGridDev.DrawOutDev( Point(), maWinSize, Point(), maWinSize, maBackgrDev );
+
+ if( IsSelected( nColIndex ) )
+ {
+ sal_Int32 nX1 = GetColumnX( nColIndex ) + 1;
+ sal_Int32 nX2 = GetColumnX( nColIndex + 1 );
+
+ // header
+ Rectangle aRect( nX1, 0, nX2, GetHdrHeight() );
+ maGridDev.SetLineColor();
+ if( maHeaderBackColor.IsDark() )
+ // redraw with light gray background in dark mode
+ ImplDrawColumnHeader( maGridDev, nColIndex, COL_LIGHTGRAY );
+ else
+ {
+ // use transparent active color
+ maGridDev.SetFillColor( maSelectColor );
+ maGridDev.DrawTransparent( PolyPolygon( Polygon( aRect ) ), CSV_HDR_TRANSPARENCY );
+ }
+
+ // column selection
+ aRect = Rectangle( nX1, GetHdrHeight() + 1, nX2, GetY( GetLastVisLine() + 1 ) - 1 );
+ ImplInvertRect( maGridDev, aRect );
+ }
+
+ maGridDev.SetClipRegion();
+ ImplInvertCursor( GetRulerCursorPos() );
+}
+
+void ScCsvGrid::ImplDrawGridDev()
+{
+ maGridDev.DrawOutDev( Point(), maWinSize, Point(), maWinSize, maBackgrDev );
+ sal_uInt32 nLastCol = GetLastVisColumn();
+ for( sal_uInt32 nColIx = GetFirstVisColumn(); nColIx <= nLastCol; ++nColIx )
+ ImplDrawColumnSelection( nColIx );
+}
+
+void ScCsvGrid::ImplDrawColumn( sal_uInt32 nColIndex )
+{
+ ImplDrawColumnBackgr( nColIndex );
+ ImplDrawColumnSelection( nColIndex );
+}
+
+void ScCsvGrid::ImplDrawHorzScrolled( sal_Int32 nOldPos )
+{
+ sal_Int32 nPos = GetFirstVisPos();
+ if( !IsValidGfx() || (nPos == nOldPos) )
+ return;
+ if( Abs( nPos - nOldPos ) > GetVisPosCount() / 2 )
+ {
+ ImplDrawBackgrDev();
+ ImplDrawGridDev();
+ return;
+ }
+
+ Point aSrc, aDest;
+ sal_uInt32 nFirstColIx, nLastColIx;
+ if( nPos < nOldPos )
+ {
+ aSrc = Point( GetFirstX() + 1, 0 );
+ aDest = Point( GetFirstX() + GetCharWidth() * (nOldPos - nPos) + 1, 0 );
+ nFirstColIx = GetColumnFromPos( nPos );
+ nLastColIx = GetColumnFromPos( nOldPos );
+ }
+ else
+ {
+ aSrc = Point( GetFirstX() + GetCharWidth() * (nPos - nOldPos) + 1, 0 );
+ aDest = Point( GetFirstX() + 1, 0 );
+ nFirstColIx = GetColumnFromPos( Min( nOldPos + GetVisPosCount(), GetPosCount() ) - 1 );
+ nLastColIx = GetColumnFromPos( Min( nPos + GetVisPosCount(), GetPosCount() ) - 1 );
+ }
+
+ ImplInvertCursor( GetRulerCursorPos() + (nPos - nOldPos) );
+ Rectangle aRectangle( GetFirstX(), 0, GetLastX(), GetHeight() - 1 );
+ Region aClipReg( aRectangle );
+ maBackgrDev.SetClipRegion( aClipReg );
+ maBackgrDev.CopyArea( aDest, aSrc, maWinSize );
+ maBackgrDev.SetClipRegion();
+ maGridDev.SetClipRegion( aClipReg );
+ maGridDev.CopyArea( aDest, aSrc, maWinSize );
+ maGridDev.SetClipRegion();
+ ImplInvertCursor( GetRulerCursorPos() );
+
+ for( sal_uInt32 nColIx = nFirstColIx; nColIx <= nLastColIx; ++nColIx )
+ ImplDrawColumn( nColIx );
+
+ sal_Int32 nLastX = GetX( GetPosCount() ) + 1;
+ if( nLastX <= GetLastX() )
+ {
+ Rectangle aRect( nLastX, 0, GetLastX(), GetHeight() - 1 );
+ maBackgrDev.SetLineColor();
+ maBackgrDev.SetFillColor( maAppBackColor );
+ maBackgrDev.DrawRect( aRect );
+ maGridDev.SetLineColor();
+ maGridDev.SetFillColor( maAppBackColor );
+ maGridDev.DrawRect( aRect );
+ }
+}
+
+void ScCsvGrid::ImplInvertCursor( sal_Int32 nPos )
+{
+ if( IsVisibleSplitPos( nPos ) )
+ {
+ sal_Int32 nX = GetX( nPos ) - 1;
+ Rectangle aRect( Point( nX, 0 ), Size( 3, GetHdrHeight() ) );
+ ImplInvertRect( maGridDev, aRect );
+ aRect.Top() = GetHdrHeight() + 1;
+ aRect.Bottom() = GetY( GetLastVisLine() + 1 );
+ ImplInvertRect( maGridDev, aRect );
+ }
+}
+
+void ScCsvGrid::ImplDrawTrackingRect( sal_uInt32 nColIndex )
+{
+ if( HasFocus() && IsVisibleColumn( nColIndex ) )
+ {
+ sal_Int32 nX1 = Max( GetColumnX( nColIndex ), GetFirstX() ) + 1;
+ sal_Int32 nX2 = Min( GetColumnX( nColIndex + 1 ) - sal_Int32( 1 ), GetLastX() );
+ sal_Int32 nY2 = Min( GetY( GetLastVisLine() + 1 ), GetHeight() ) - 1;
+ InvertTracking( Rectangle( nX1, 0, nX2, nY2 ), SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ }
+}
+
+
+// accessibility ==============================================================
+
+ScAccessibleCsvControl* ScCsvGrid::ImplCreateAccessible()
+{
+ return new ScAccessibleCsvGrid( *this );
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/csvruler.cxx b/sc/source/ui/dbgui/csvruler.cxx
new file mode 100644
index 000000000000..56aa2a50a835
--- /dev/null
+++ b/sc/source/ui/dbgui/csvruler.cxx
@@ -0,0 +1,682 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "csvruler.hxx"
+#include "AccessibleCsvControl.hxx"
+
+
+#include <optutil.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "miscuno.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+
+
+// ============================================================================
+#define SEP_PATH "Office.Calc/Dialogs/CSVImport"
+#define FIXED_WIDTH_LIST "FixedWidthList"
+
+
+// ============================================================================
+
+static void load_FixedWidthList(ScCsvSplits &aSplits)
+{
+ String sSplits;
+ OUString sFixedWidthLists;
+
+ Sequence<Any>aValues;
+ const Any *pProperties;
+ Sequence<OUString> aNames(1);
+ OUString* pNames = aNames.getArray();
+ ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) );
+
+ pNames[0] = OUString::createFromAscii( FIXED_WIDTH_LIST );
+ aValues = aItem.GetProperties( aNames );
+ pProperties = aValues.getConstArray();
+
+ if( pProperties[0].hasValue() )
+ {
+ aSplits.Clear();
+ pProperties[0] >>= sFixedWidthLists;
+
+ sSplits = String( sFixedWidthLists );
+
+ // String ends with a semi-colon so there is no 'int' after the last one.
+ xub_StrLen n = sSplits.GetTokenCount() - 1;
+ for (xub_StrLen i = 0; i < n; ++i)
+ aSplits.Insert( sSplits.GetToken(i).ToInt32() );
+ }
+}
+static void save_FixedWidthList(ScCsvSplits aSplits)
+{
+ String sSplits;
+ // Create a semi-colon separated string to save the splits
+ sal_uInt32 n = aSplits.Count();
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ sSplits.Append( String::CreateFromInt32( aSplits[i] ) );
+ sSplits.Append((char)';');
+ }
+
+ OUString sFixedWidthLists = OUString( sSplits );
+ Sequence<Any> aValues;
+ Any *pProperties;
+ Sequence<OUString> aNames(1);
+ OUString* pNames = aNames.getArray();
+ ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) );
+
+ pNames[0] = OUString::createFromAscii( FIXED_WIDTH_LIST );
+ aValues = aItem.GetProperties( aNames );
+ pProperties = aValues.getArray();
+ pProperties[0] <<= sFixedWidthLists;
+
+ aItem.PutProperties(aNames, aValues);
+}
+
+ScCsvRuler::ScCsvRuler( ScCsvControl& rParent ) :
+ ScCsvControl( rParent ),
+ mnPosCursorLast( 1 )
+{
+ EnableRTL( false ); // #107812# RTL
+ InitColors();
+ InitSizeData();
+ maBackgrDev.SetFont( GetFont() );
+ maRulerDev.SetFont( GetFont() );
+
+ load_FixedWidthList( maSplits );
+}
+
+ScCsvRuler::~ScCsvRuler()
+{
+ save_FixedWidthList( maSplits );
+}
+
+
+// common ruler handling ------------------------------------------------------
+
+void ScCsvRuler::SetPosSizePixel(
+ long nX, long nY, long nWidth, long nHeight, USHORT nFlags )
+{
+ if( nFlags & WINDOW_POSSIZE_HEIGHT )
+ nHeight = GetTextHeight() + mnSplitSize + 2;
+ ScCsvControl::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
+}
+
+void ScCsvRuler::ApplyLayout( const ScCsvLayoutData& rOldData )
+{
+ ScCsvDiff nDiff = GetLayoutData().GetDiff( rOldData ) & (CSV_DIFF_HORIZONTAL | CSV_DIFF_RULERCURSOR);
+ if( nDiff == CSV_DIFF_EQUAL ) return;
+
+ DisableRepaint();
+ if( nDiff & CSV_DIFF_HORIZONTAL )
+ {
+ InitSizeData();
+ if( GetRulerCursorPos() >= GetPosCount() )
+ MoveCursor( GetPosCount() - 1 );
+ }
+ if( nDiff & CSV_DIFF_RULERCURSOR )
+ {
+ ImplInvertCursor( rOldData.mnPosCursor );
+ ImplInvertCursor( GetRulerCursorPos() );
+ }
+ EnableRepaint();
+
+ if( nDiff & CSV_DIFF_POSOFFSET )
+ AccSendVisibleEvent();
+}
+
+void ScCsvRuler::InitColors()
+{
+ const StyleSettings& rSett = GetSettings().GetStyleSettings();
+ maBackColor = rSett.GetFaceColor();
+ maActiveColor = rSett.GetWindowColor();
+ maTextColor = rSett.GetLabelTextColor();
+ maSplitColor = maBackColor.IsDark() ? maTextColor : Color( COL_LIGHTRED );
+ InvalidateGfx();
+}
+
+void ScCsvRuler::InitSizeData()
+{
+ maWinSize = GetSizePixel();
+
+ mnSplitSize = (GetCharWidth() * 3 / 5) | 1; // make an odd number
+
+ sal_Int32 nActiveWidth = Min( GetWidth() - GetHdrWidth(), GetPosCount() * GetCharWidth() );
+ sal_Int32 nActiveHeight = GetTextHeight();
+
+ maActiveRect.SetPos( Point( GetFirstX(), (GetHeight() - nActiveHeight - 1) / 2 ) );
+ maActiveRect.SetSize( Size( nActiveWidth, nActiveHeight ) );
+
+ maBackgrDev.SetOutputSizePixel( maWinSize );
+ maRulerDev.SetOutputSizePixel( maWinSize );
+
+ InvalidateGfx();
+}
+
+void ScCsvRuler::MoveCursor( sal_Int32 nPos, bool bScroll )
+{
+ DisableRepaint();
+ if( bScroll )
+ Execute( CSVCMD_MAKEPOSVISIBLE, nPos );
+ Execute( CSVCMD_MOVERULERCURSOR, IsVisibleSplitPos( nPos ) ? nPos : CSV_POS_INVALID );
+ EnableRepaint();
+ AccSendCaretEvent();
+}
+
+void ScCsvRuler::MoveCursorRel( ScMoveMode eDir )
+{
+ if( GetRulerCursorPos() != CSV_POS_INVALID )
+ {
+ switch( eDir )
+ {
+ case MOVE_FIRST:
+ MoveCursor( 1 );
+ break;
+ case MOVE_LAST:
+ MoveCursor( GetPosCount() - 1 );
+ break;
+ case MOVE_PREV:
+ if( GetRulerCursorPos() > 1 )
+ MoveCursor( GetRulerCursorPos() - 1 );
+ break;
+ case MOVE_NEXT:
+ if( GetRulerCursorPos() < GetPosCount() - 1 )
+ MoveCursor( GetRulerCursorPos() + 1 );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+void ScCsvRuler::MoveCursorToSplit( ScMoveMode eDir )
+{
+ if( GetRulerCursorPos() != CSV_POS_INVALID )
+ {
+ sal_uInt32 nIndex = CSV_VEC_NOTFOUND;
+ switch( eDir )
+ {
+ case MOVE_FIRST: nIndex = maSplits.LowerBound( 0 ); break;
+ case MOVE_LAST: nIndex = maSplits.UpperBound( GetPosCount() ); break;
+ case MOVE_PREV: nIndex = maSplits.UpperBound( GetRulerCursorPos() - 1 ); break;
+ case MOVE_NEXT: nIndex = maSplits.LowerBound( GetRulerCursorPos() + 1 ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ sal_Int32 nPos = maSplits[ nIndex ];
+ if( nPos != CSV_POS_INVALID )
+ MoveCursor( nPos );
+ }
+}
+
+void ScCsvRuler::ScrollVertRel( ScMoveMode eDir )
+{
+ sal_Int32 nLine = GetFirstVisLine();
+ switch( eDir )
+ {
+ case MOVE_PREV: --nLine; break;
+ case MOVE_NEXT: ++nLine; break;
+ case MOVE_PREVPAGE: nLine -= GetVisLineCount() - 1; break;
+ case MOVE_NEXTPAGE: nLine += GetVisLineCount() - 1; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ Execute( CSVCMD_SETLINEOFFSET, nLine );
+}
+
+
+// split handling -------------------------------------------------------------
+
+sal_Int32 ScCsvRuler::GetNoScrollPos( sal_Int32 nPos ) const
+{
+ sal_Int32 nNewPos = nPos;
+ if( nNewPos != CSV_POS_INVALID )
+ {
+ if( nNewPos < GetFirstVisPos() + CSV_SCROLL_DIST )
+ {
+ sal_Int32 nScroll = (GetFirstVisPos() > 0) ? CSV_SCROLL_DIST : 0;
+ nNewPos = Max( nPos, GetFirstVisPos() + nScroll );
+ }
+ else if( nNewPos > GetLastVisPos() - CSV_SCROLL_DIST - 1L )
+ {
+ sal_Int32 nScroll = (GetFirstVisPos() < GetMaxPosOffset()) ? CSV_SCROLL_DIST : 0;
+ nNewPos = Min( nNewPos, GetLastVisPos() - nScroll - sal_Int32( 1 ) );
+ }
+ }
+ return nNewPos;
+}
+
+void ScCsvRuler::InsertSplit( sal_Int32 nPos )
+{
+ if( maSplits.Insert( nPos ) )
+ {
+ ImplDrawSplit( nPos );
+ Repaint();
+ }
+}
+
+void ScCsvRuler::RemoveSplit( sal_Int32 nPos )
+{
+ if( maSplits.Remove( nPos ) )
+ {
+ ImplEraseSplit( nPos );
+ Repaint();
+ }
+}
+
+void ScCsvRuler::MoveSplit( sal_Int32 nPos, sal_Int32 nNewPos )
+{
+ bool bRemove = maSplits.Remove( nPos );
+ bool bInsert = maSplits.Insert( nNewPos );
+ if( bRemove || bInsert )
+ {
+ ImplEraseSplit( nPos );
+ ImplDrawSplit( nNewPos );
+ Repaint();
+ }
+}
+
+void ScCsvRuler::RemoveAllSplits()
+{
+ maSplits.Clear();
+ Repaint( true );
+}
+
+sal_Int32 ScCsvRuler::FindEmptyPos( sal_Int32 nPos, ScMoveMode eDir ) const
+{
+ sal_Int32 nNewPos = nPos;
+ if( nNewPos != CSV_POS_INVALID )
+ {
+ switch( eDir )
+ {
+ case MOVE_FIRST:
+ nNewPos = Min( nPos, FindEmptyPos( 0, MOVE_NEXT ) );
+ break;
+ case MOVE_LAST:
+ nNewPos = Max( nPos, FindEmptyPos( GetPosCount(), MOVE_PREV ) );
+ break;
+ case MOVE_PREV:
+ while( HasSplit( --nNewPos ) ) ;
+ break;
+ case MOVE_NEXT:
+ while( HasSplit( ++nNewPos ) ) ;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ return IsValidSplitPos( nNewPos ) ? nNewPos : CSV_POS_INVALID;
+}
+
+void ScCsvRuler::MoveCurrSplit( sal_Int32 nNewPos )
+{
+ DisableRepaint();
+ Execute( CSVCMD_MOVESPLIT, GetRulerCursorPos(), nNewPos );
+ MoveCursor( nNewPos );
+ EnableRepaint();
+}
+
+void ScCsvRuler::MoveCurrSplitRel( ScMoveMode eDir )
+{
+ if( HasSplit( GetRulerCursorPos() ) )
+ {
+ sal_Int32 nNewPos = FindEmptyPos( GetRulerCursorPos(), eDir );
+ if( nNewPos != CSV_POS_INVALID )
+ MoveCurrSplit( nNewPos );
+ }
+}
+
+
+// event handling -------------------------------------------------------------
+
+void ScCsvRuler::Resize()
+{
+ ScCsvControl::Resize();
+ InitSizeData();
+ Repaint();
+}
+
+void ScCsvRuler::GetFocus()
+{
+ ScCsvControl::GetFocus();
+ DisableRepaint();
+ if( GetRulerCursorPos() == CSV_POS_INVALID )
+ MoveCursor( GetNoScrollPos( mnPosCursorLast ) );
+ EnableRepaint();
+}
+
+void ScCsvRuler::LoseFocus()
+{
+ ScCsvControl::LoseFocus();
+ mnPosCursorLast = GetRulerCursorPos();
+ MoveCursor( CSV_POS_INVALID );
+}
+
+void ScCsvRuler::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ InitColors();
+ Repaint();
+ }
+ ScCsvControl::DataChanged( rDCEvt );
+}
+
+void ScCsvRuler::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ DisableRepaint();
+ if( !HasFocus() )
+ GrabFocus();
+ if( rMEvt.IsLeft() )
+ {
+ sal_Int32 nPos = GetPosFromX( rMEvt.GetPosPixel().X() );
+ if( IsVisibleSplitPos( nPos ) )
+ StartMouseTracking( nPos );
+ ImplSetMousePointer( nPos );
+ }
+ EnableRepaint();
+}
+
+void ScCsvRuler::MouseMove( const MouseEvent& rMEvt )
+{
+ if( !rMEvt.IsModifierChanged() )
+ {
+ sal_Int32 nPos = GetPosFromX( rMEvt.GetPosPixel().X() );
+ if( IsTracking() )
+ {
+ // on mouse tracking: keep position valid
+ nPos = Max( Min( nPos, GetPosCount() - sal_Int32( 1 ) ), sal_Int32( 1 ) );
+ MoveMouseTracking( nPos );
+ }
+ else
+ {
+ Point aPoint;
+ Rectangle aRect( aPoint, maWinSize );
+ if( !IsVisibleSplitPos( nPos ) || !aRect.IsInside( rMEvt.GetPosPixel() ) )
+ // if focused, keep old cursor position for key input
+ nPos = HasFocus() ? GetRulerCursorPos() : CSV_POS_INVALID;
+ MoveCursor( nPos, false );
+ }
+ ImplSetMousePointer( nPos );
+ }
+}
+
+void ScCsvRuler::Tracking( const TrackingEvent& rTEvt )
+{
+ if( rTEvt.IsTrackingEnded() || rTEvt.IsTrackingRepeat() )
+ MouseMove( rTEvt.GetMouseEvent() );
+ if( rTEvt.IsTrackingEnded() )
+ EndMouseTracking( !rTEvt.IsTrackingCanceled() );
+}
+
+void ScCsvRuler::KeyInput( const KeyEvent& rKEvt )
+{
+ const KeyCode& rKCode = rKEvt.GetKeyCode();
+ sal_uInt16 nCode = rKCode.GetCode();
+ bool bNoMod = !rKCode.GetModifier();
+ bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
+ bool bJump = (rKCode.GetModifier() == KEY_MOD1);
+ bool bMove = (rKCode.GetModifier() == (KEY_MOD1 | KEY_SHIFT));
+
+ ScMoveMode eHDir = GetHorzDirection( nCode, true );
+ ScMoveMode eVDir = GetVertDirection( nCode, false );
+
+ if( bNoMod )
+ {
+ if( eHDir != MOVE_NONE )
+ MoveCursorRel( eHDir );
+ else if( eVDir != MOVE_NONE )
+ ScrollVertRel( eVDir );
+ else switch( nCode )
+ {
+ case KEY_SPACE: Execute( CSVCMD_TOGGLESPLIT, GetRulerCursorPos() ); break;
+ case KEY_INSERT: Execute( CSVCMD_INSERTSPLIT, GetRulerCursorPos() ); break;
+ case KEY_DELETE: Execute( CSVCMD_REMOVESPLIT, GetRulerCursorPos() ); break;
+ }
+ }
+ else if( bJump && (eHDir != MOVE_NONE) )
+ MoveCursorToSplit( eHDir );
+ else if( bMove && (eHDir != MOVE_NONE) )
+ MoveCurrSplitRel( eHDir );
+ else if( bShift && (nCode == KEY_DELETE) )
+ Execute( CSVCMD_REMOVEALLSPLITS );
+
+ if( rKCode.GetGroup() != KEYGROUP_CURSOR )
+ ScCsvControl::KeyInput( rKEvt );
+}
+
+void ScCsvRuler::StartMouseTracking( sal_Int32 nPos )
+{
+ mnPosMTStart = mnPosMTCurr = nPos;
+ mbPosMTMoved = false;
+ maOldSplits = maSplits;
+ Execute( CSVCMD_INSERTSPLIT, nPos );
+ if( HasSplit( nPos ) )
+ StartTracking( STARTTRACK_BUTTONREPEAT );
+}
+
+void ScCsvRuler::MoveMouseTracking( sal_Int32 nPos )
+{
+ if( mnPosMTCurr != nPos )
+ {
+ DisableRepaint();
+ MoveCursor( nPos );
+ if( (mnPosMTCurr != mnPosMTStart) && maOldSplits.HasSplit( mnPosMTCurr ) )
+ Execute( CSVCMD_INSERTSPLIT, nPos );
+ else
+ Execute( CSVCMD_MOVESPLIT, mnPosMTCurr, nPos );
+ mnPosMTCurr = nPos;
+ mbPosMTMoved = true;
+ EnableRepaint();
+ }
+}
+
+void ScCsvRuler::EndMouseTracking( bool bApply )
+{
+ if( bApply ) // tracking finished successfully
+ {
+ // remove on simple click on an existing split
+ if( (mnPosMTCurr == mnPosMTStart) && maOldSplits.HasSplit( mnPosMTCurr ) && !mbPosMTMoved )
+ Execute( CSVCMD_REMOVESPLIT, mnPosMTCurr );
+ }
+ else // tracking cancelled
+ {
+ MoveCursor( mnPosMTStart );
+ // move split to origin
+ if( maOldSplits.HasSplit( mnPosMTStart ) )
+ MoveMouseTracking( mnPosMTStart );
+ // remove temporarily inserted split
+ else if( !maOldSplits.HasSplit( mnPosMTCurr ) )
+ Execute( CSVCMD_REMOVESPLIT, mnPosMTCurr );
+ }
+ mnPosMTStart = CSV_POS_INVALID;
+}
+
+
+// painting -------------------------------------------------------------------
+
+void ScCsvRuler::Paint( const Rectangle& )
+{
+ Repaint();
+}
+
+void ScCsvRuler::ImplRedraw()
+{
+ if( IsVisible() )
+ {
+ if( !IsValidGfx() )
+ {
+ ValidateGfx();
+ ImplDrawBackgrDev();
+ ImplDrawRulerDev();
+ }
+ DrawOutDev( Point(), maWinSize, Point(), maWinSize, maRulerDev );
+ ImplDrawTrackingRect();
+ }
+}
+
+void ScCsvRuler::ImplDrawArea( sal_Int32 nPosX, sal_Int32 nWidth )
+{
+ maBackgrDev.SetLineColor();
+ Rectangle aRect( Point( nPosX, 0 ), Size( nWidth, GetHeight() ) );
+ maBackgrDev.SetFillColor( maBackColor );
+ maBackgrDev.DrawRect( aRect );
+
+ aRect = maActiveRect;
+ aRect.Left() = Max( GetFirstX(), nPosX );
+ aRect.Right() = Min( Min( GetX( GetPosCount() ), GetLastX() ), nPosX + nWidth - sal_Int32( 1 ) );
+ if( aRect.Left() <= aRect.Right() )
+ {
+ maBackgrDev.SetFillColor( maActiveColor );
+ maBackgrDev.DrawRect( aRect );
+ }
+
+ maBackgrDev.SetLineColor( maTextColor );
+ sal_Int32 nY = GetHeight() - 1;
+ maBackgrDev.DrawLine( Point( nPosX, nY ), Point( nPosX + nWidth - 1, nY ) );
+}
+
+void ScCsvRuler::ImplDrawBackgrDev()
+{
+ ImplDrawArea( 0, GetWidth() );
+
+ // scale
+ maBackgrDev.SetLineColor( maTextColor );
+ maBackgrDev.SetFillColor();
+ sal_Int32 nPos;
+
+ sal_Int32 nFirstPos = Max( GetPosFromX( 0 ) - (sal_Int32)(1L), (sal_Int32)(0L) );
+ sal_Int32 nLastPos = GetPosFromX( GetWidth() );
+ sal_Int32 nY = (maActiveRect.Top() + maActiveRect.Bottom()) / 2;
+ for( nPos = nFirstPos; nPos <= nLastPos; ++nPos )
+ {
+ sal_Int32 nX = GetX( nPos );
+ if( nPos % 5 )
+ maBackgrDev.DrawPixel( Point( nX, nY ) );
+ else
+ maBackgrDev.DrawLine( Point( nX, nY - 1 ), Point( nX, nY + 1 ) );
+ }
+
+ // texts
+ maBackgrDev.SetTextColor( maTextColor );
+ maBackgrDev.SetTextFillColor();
+ for( nPos = ((nFirstPos + 9) / 10) * 10; nPos <= nLastPos; nPos += 10 )
+ {
+ String aText( String::CreateFromInt32( nPos ) );
+ sal_Int32 nTextWidth = maBackgrDev.GetTextWidth( aText );
+ sal_Int32 nTextX = GetX( nPos ) - nTextWidth / 2;
+ ImplDrawArea( nTextX - 1, nTextWidth + 2 );
+ maBackgrDev.DrawText( Point( nTextX, maActiveRect.Top() ), aText );
+ }
+}
+
+void ScCsvRuler::ImplDrawSplit( sal_Int32 nPos )
+{
+ if( IsVisibleSplitPos( nPos ) )
+ {
+ Point aPos( GetX( nPos ) - mnSplitSize / 2, GetHeight() - mnSplitSize - 2 );
+ Size aSize( mnSplitSize, mnSplitSize );
+ maRulerDev.SetLineColor( maTextColor );
+ maRulerDev.SetFillColor( maSplitColor );
+ maRulerDev.DrawEllipse( Rectangle( aPos, aSize ) );
+ maRulerDev.DrawPixel( Point( GetX( nPos ), GetHeight() - 2 ) );
+ }
+}
+
+void ScCsvRuler::ImplEraseSplit( sal_Int32 nPos )
+{
+ if( IsVisibleSplitPos( nPos ) )
+ {
+ ImplInvertCursor( GetRulerCursorPos() );
+ Point aPos( GetX( nPos ) - mnSplitSize / 2, 0 );
+ Size aSize( mnSplitSize, GetHeight() );
+ maRulerDev.DrawOutDev( aPos, aSize, aPos, aSize, maBackgrDev );
+ ImplInvertCursor( GetRulerCursorPos() );
+ }
+}
+
+void ScCsvRuler::ImplDrawRulerDev()
+{
+ maRulerDev.DrawOutDev( Point(), maWinSize, Point(), maWinSize, maBackgrDev );
+ ImplInvertCursor( GetRulerCursorPos() );
+
+ sal_uInt32 nFirst = maSplits.LowerBound( GetFirstVisPos() );
+ sal_uInt32 nLast = maSplits.UpperBound( GetLastVisPos() );
+ if( (nFirst != CSV_VEC_NOTFOUND) && (nLast != CSV_VEC_NOTFOUND) )
+ for( sal_uInt32 nIndex = nFirst; nIndex <= nLast; ++nIndex )
+ ImplDrawSplit( GetSplitPos( nIndex ) );
+}
+
+void ScCsvRuler::ImplInvertCursor( sal_Int32 nPos )
+{
+ if( IsVisibleSplitPos( nPos ) )
+ {
+ ImplInvertRect( maRulerDev, Rectangle( Point( GetX( nPos ) - 1, 0 ), Size( 3, GetHeight() - 1 ) ) );
+ if( HasSplit( nPos ) )
+ ImplDrawSplit( nPos );
+ }
+}
+
+void ScCsvRuler::ImplDrawTrackingRect()
+{
+ if( HasFocus() )
+ InvertTracking( Rectangle( 0, 0, GetWidth() - 1, GetHeight() - 2 ),
+ SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+}
+
+void ScCsvRuler::ImplSetMousePointer( sal_Int32 nPos )
+{
+ SetPointer( Pointer( HasSplit( nPos ) ? POINTER_HSPLIT : POINTER_ARROW ) );
+}
+
+
+// accessibility ==============================================================
+
+ScAccessibleCsvControl* ScCsvRuler::ImplCreateAccessible()
+{
+ return new ScAccessibleCsvRuler( *this );
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/csvsplits.cxx b/sc/source/ui/dbgui/csvsplits.cxx
new file mode 100644
index 000000000000..b93bb09b5151
--- /dev/null
+++ b/sc/source/ui/dbgui/csvsplits.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "csvsplits.hxx"
+#include <tools/debug.hxx>
+
+#include <algorithm>
+
+
+// ============================================================================
+
+bool ScCsvSplits::Insert( sal_Int32 nPos )
+{
+ bool bValid = (nPos >= 0);
+ if( bValid )
+ {
+ iterator aIter = ::std::lower_bound( maVec.begin(), maVec.end(), nPos );
+ bValid = (aIter == maVec.end()) || (*aIter != nPos);
+ if( bValid )
+ aIter = maVec.insert( aIter, nPos );
+ }
+ return bValid;
+}
+
+bool ScCsvSplits::Remove( sal_Int32 nPos )
+{
+ sal_uInt32 nIndex = GetIndex( nPos );
+ bool bValid = (nIndex != CSV_VEC_NOTFOUND);
+ if( bValid )
+ maVec.erase( maVec.begin() + nIndex );
+ return bValid;
+}
+
+void ScCsvSplits::RemoveRange( sal_Int32 nPosStart, sal_Int32 nPosEnd )
+{
+ sal_uInt32 nStartIx = LowerBound( nPosStart );
+ sal_uInt32 nEndIx = UpperBound( nPosEnd );
+ if( (nStartIx != CSV_VEC_NOTFOUND) && (nEndIx != CSV_VEC_NOTFOUND) && (nStartIx <= nEndIx) )
+ maVec.erase( maVec.begin() + nStartIx, maVec.begin() + nEndIx + 1 );
+}
+
+void ScCsvSplits::Clear()
+{
+ maVec.clear();
+}
+
+bool ScCsvSplits::HasSplit( sal_Int32 nPos ) const
+{
+ return GetIndex( nPos ) != CSV_VEC_NOTFOUND;
+}
+
+
+// ----------------------------------------------------------------------------
+
+sal_uInt32 ScCsvSplits::GetIndex( sal_Int32 nPos ) const
+{
+ const_iterator aIter = ::std::lower_bound( maVec.begin(), maVec.end(), nPos );
+ return GetIterIndex( ((aIter != maVec.end()) && (*aIter == nPos)) ? aIter : maVec.end() );
+}
+
+sal_uInt32 ScCsvSplits::LowerBound( sal_Int32 nPos ) const
+{
+ return GetIterIndex( ::std::lower_bound( maVec.begin(), maVec.end(), nPos ) );
+}
+
+sal_uInt32 ScCsvSplits::UpperBound( sal_Int32 nPos ) const
+{
+ sal_uInt32 nIndex = LowerBound( nPos );
+ if( nIndex == CSV_VEC_NOTFOUND )
+ return Count() ? (Count() - 1) : CSV_VEC_NOTFOUND;
+ if( GetPos( nIndex ) == nPos )
+ return nIndex;
+ return nIndex ? (nIndex - 1) : CSV_VEC_NOTFOUND;
+}
+
+sal_Int32 ScCsvSplits::GetPos( sal_uInt32 nIndex ) const
+{
+ return (nIndex < Count()) ? maVec[ nIndex ] : CSV_POS_INVALID;
+}
+
+
+// ----------------------------------------------------------------------------
+
+sal_uInt32 ScCsvSplits::GetIterIndex( const_iterator aIter ) const
+{
+ return (aIter == maVec.end()) ? CSV_VEC_NOTFOUND : (aIter - maVec.begin());
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/csvtablebox.cxx b/sc/source/ui/dbgui/csvtablebox.cxx
new file mode 100644
index 000000000000..842f1cc81dea
--- /dev/null
+++ b/sc/source/ui/dbgui/csvtablebox.cxx
@@ -0,0 +1,464 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "csvtablebox.hxx"
+#include <tools/debug.hxx>
+#include <vcl/lstbox.hxx>
+
+// ause
+#include "editutil.hxx"
+
+// ============================================================================
+
+//UNUSED2009-05 ScCsvTableBox::ScCsvTableBox( Window* pParent ) :
+//UNUSED2009-05 ScCsvControl( pParent, maData, WB_BORDER | WB_TABSTOP | WB_DIALOGCONTROL ),
+//UNUSED2009-05 maRuler( *this ),
+//UNUSED2009-05 maGrid( *this ),
+//UNUSED2009-05 maHScroll( this, WB_HORZ | WB_DRAG ),
+//UNUSED2009-05 maVScroll( this, WB_VERT | WB_DRAG ),
+//UNUSED2009-05 maScrollBox( this )
+//UNUSED2009-05 {
+//UNUSED2009-05 Init();
+//UNUSED2009-05 }
+
+ScCsvTableBox::ScCsvTableBox( Window* pParent, const ResId& rResId ) :
+ ScCsvControl( pParent, maData, rResId ),
+ maRuler( *this ),
+ maGrid( *this ),
+ maHScroll( this, WB_HORZ | WB_DRAG ),
+ maVScroll( this, WB_VERT | WB_DRAG ),
+ maScrollBox( this )
+{
+ Init();
+}
+
+
+// common table box handling --------------------------------------------------
+
+void ScCsvTableBox::SetSeparatorsMode()
+{
+ if( mbFixedMode )
+ {
+ // rescue data for fixed width mode
+ mnFixedWidth = GetPosCount();
+ maFixColStates = maGrid.GetColumnStates();
+ // switch to separators mode
+ mbFixedMode = false;
+ // reset and reinitialize controls
+ DisableRepaint();
+ Execute( CSVCMD_SETLINEOFFSET, 0 );
+ Execute( CSVCMD_SETPOSCOUNT, 1 );
+ Execute( CSVCMD_NEWCELLTEXTS );
+ maGrid.SetColumnStates( maSepColStates );
+ InitControls();
+ EnableRepaint();
+ }
+}
+
+void ScCsvTableBox::SetFixedWidthMode()
+{
+ if( !mbFixedMode )
+ {
+ // rescue data for separators mode
+ maSepColStates = maGrid.GetColumnStates();
+ // switch to fixed width mode
+ mbFixedMode = true;
+ // reset and reinitialize controls
+ DisableRepaint();
+ Execute( CSVCMD_SETLINEOFFSET, 0 );
+ Execute( CSVCMD_SETPOSCOUNT, mnFixedWidth );
+ maGrid.SetSplits( maRuler.GetSplits() );
+ maGrid.SetColumnStates( maFixColStates );
+ InitControls();
+ EnableRepaint();
+ }
+}
+
+void ScCsvTableBox::Init()
+{
+ mbFixedMode = false;
+ mnFixedWidth = 1;
+
+ maHScroll.EnableRTL( false ); // #107812# RTL
+ maHScroll.SetLineSize( 1 );
+ maVScroll.SetLineSize( 1 );
+
+ Link aLink = LINK( this, ScCsvTableBox, CsvCmdHdl );
+ SetCmdHdl( aLink );
+ maRuler.SetCmdHdl( aLink );
+ maGrid.SetCmdHdl( aLink );
+
+ aLink = LINK( this, ScCsvTableBox, ScrollHdl );
+ maHScroll.SetScrollHdl( aLink );
+ maVScroll.SetScrollHdl( aLink );
+
+ aLink = LINK( this, ScCsvTableBox, ScrollEndHdl );
+ maHScroll.SetEndScrollHdl( aLink );
+ maVScroll.SetEndScrollHdl( aLink );
+
+ InitControls();
+}
+
+void ScCsvTableBox::InitControls()
+{
+ maGrid.UpdateLayoutData();
+
+ long nScrollBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ Size aWinSize = CalcOutputSize( GetSizePixel() );
+ long nDataWidth = aWinSize.Width() - nScrollBarSize;
+ long nDataHeight = aWinSize.Height() - nScrollBarSize;
+
+ maData.mnWinWidth = nDataWidth;
+ maData.mnWinHeight = nDataHeight;
+
+ if( mbFixedMode )
+ {
+ // ruler sets height internally
+ maRuler.SetPosSizePixel( 0, 0, nDataWidth, 0 );
+ sal_Int32 nY = maRuler.GetSizePixel().Height();
+ maData.mnWinHeight -= nY;
+ maGrid.SetPosSizePixel( 0, nY, nDataWidth, maData.mnWinHeight );
+ }
+ else
+ maGrid.SetPosSizePixel( 0, 0, nDataWidth, nDataHeight );
+ maGrid.Show();
+ maRuler.Show( mbFixedMode );
+
+ // scrollbars always visible
+ maHScroll.SetPosSizePixel( 0, nDataHeight, nDataWidth, nScrollBarSize );
+ InitHScrollBar();
+ maHScroll.Show();
+
+ // scrollbars always visible
+ maVScroll.SetPosSizePixel( nDataWidth, 0, nScrollBarSize, nDataHeight );
+ InitVScrollBar();
+ maVScroll.Show();
+
+ bool bScrBox = maHScroll.IsVisible() && maVScroll.IsVisible();
+ if( bScrBox )
+ maScrollBox.SetPosSizePixel( nDataWidth, nDataHeight, nScrollBarSize, nScrollBarSize );
+ maScrollBox.Show( bScrBox );
+
+ // let the controls self-adjust to visible area
+ Execute( CSVCMD_SETPOSOFFSET, GetFirstVisPos() );
+ Execute( CSVCMD_SETLINEOFFSET, GetFirstVisLine() );
+}
+
+void ScCsvTableBox::InitHScrollBar()
+{
+ maHScroll.SetRange( Range( 0, GetPosCount() + 2 ) );
+ maHScroll.SetVisibleSize( GetVisPosCount() );
+ maHScroll.SetPageSize( GetVisPosCount() * 3 / 4 );
+ maHScroll.SetThumbPos( GetFirstVisPos() );
+}
+
+void ScCsvTableBox::InitVScrollBar()
+{
+ maVScroll.SetRange( Range( 0, GetLineCount() + 1 ) );
+ maVScroll.SetVisibleSize( GetVisLineCount() );
+ maVScroll.SetPageSize( GetVisLineCount() - 2 );
+ maVScroll.SetThumbPos( GetFirstVisLine() );
+}
+
+void ScCsvTableBox::MakePosVisible( sal_Int32 nPos )
+{
+ if( (0 <= nPos) && (nPos < GetPosCount()) )
+ {
+ if( nPos - CSV_SCROLL_DIST + 1 <= GetFirstVisPos() )
+ Execute( CSVCMD_SETPOSOFFSET, nPos - CSV_SCROLL_DIST );
+ else if( nPos + CSV_SCROLL_DIST >= GetLastVisPos() )
+ Execute( CSVCMD_SETPOSOFFSET, nPos - GetVisPosCount() + CSV_SCROLL_DIST );
+ }
+}
+
+
+// cell contents --------------------------------------------------------------
+
+void ScCsvTableBox::SetUniStrings(
+ const String* pTextLines, const String& rSepChars,
+ sal_Unicode cTextSep, bool bMergeSep )
+{
+ // assuming that pTextLines is a string array with size CSV_PREVIEW_LINES
+ // -> will be dynamic sometime
+ DisableRepaint();
+ sal_Int32 nEndLine = GetFirstVisLine() + CSV_PREVIEW_LINES;
+ const String* pString = pTextLines;
+ for( sal_Int32 nLine = GetFirstVisLine(); nLine < nEndLine; ++nLine, ++pString )
+ {
+ if( mbFixedMode )
+ maGrid.ImplSetTextLineFix( nLine, *pString );
+ else
+ maGrid.ImplSetTextLineSep( nLine, *pString, rSepChars, cTextSep, bMergeSep );
+ }
+ EnableRepaint();
+}
+
+//UNUSED2009-05 void ScCsvTableBox::SetByteStrings(
+//UNUSED2009-05 const ByteString* pTextLines, CharSet eCharSet,
+//UNUSED2009-05 const String& rSepChars, sal_Unicode cTextSep, bool bMergeSep )
+//UNUSED2009-05 {
+//UNUSED2009-05 // assuming that pTextLines is a string array with size CSV_PREVIEW_LINES
+//UNUSED2009-05 // -> will be dynamic sometime
+//UNUSED2009-05 DisableRepaint();
+//UNUSED2009-05 sal_Int32 nEndLine = GetFirstVisLine() + CSV_PREVIEW_LINES;
+//UNUSED2009-05 const ByteString* pString = pTextLines;
+//UNUSED2009-05 for( sal_Int32 nLine = GetFirstVisLine(); nLine < nEndLine; ++nLine, ++pString )
+//UNUSED2009-05 {
+//UNUSED2009-05 if( mbFixedMode )
+//UNUSED2009-05 maGrid.ImplSetTextLineFix( nLine, String( *pString, eCharSet ) );
+//UNUSED2009-05 else
+//UNUSED2009-05 maGrid.ImplSetTextLineSep( nLine, String( *pString, eCharSet ), rSepChars, cTextSep, bMergeSep );
+//UNUSED2009-05 }
+//UNUSED2009-05 EnableRepaint();
+//UNUSED2009-05 }
+
+
+// column settings ------------------------------------------------------------
+
+void ScCsvTableBox::InitTypes( const ListBox& rListBox )
+{
+ sal_uInt16 nTypeCount = rListBox.GetEntryCount();
+ StringVec aTypeNames( nTypeCount );
+ for( sal_uInt16 nIndex = 0; nIndex < nTypeCount; ++nIndex )
+ aTypeNames[ nIndex ] = rListBox.GetEntry( nIndex );
+ maGrid.SetTypeNames( aTypeNames );
+}
+
+void ScCsvTableBox::FillColumnData( ScAsciiOptions& rOptions ) const
+{
+ if( mbFixedMode )
+ maGrid.FillColumnDataFix( rOptions );
+ else
+ maGrid.FillColumnDataSep( rOptions );
+}
+
+
+// event handling -------------------------------------------------------------
+
+void ScCsvTableBox::Resize()
+{
+ ScCsvControl::Resize();
+ InitControls();
+}
+
+void ScCsvTableBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ InitControls();
+ ScCsvControl::DataChanged( rDCEvt );
+}
+
+IMPL_LINK( ScCsvTableBox, CsvCmdHdl, ScCsvControl*, pCtrl )
+{
+ DBG_ASSERT( pCtrl, "ScCsvTableBox::CsvCmdHdl - missing sender" );
+
+ const ScCsvCmd& rCmd = pCtrl->GetCmd();
+ ScCsvCmdType eType = rCmd.GetType();
+ sal_Int32 nParam1 = rCmd.GetParam1();
+ sal_Int32 nParam2 = rCmd.GetParam2();
+
+ bool bFound = true;
+ switch( eType )
+ {
+ case CSVCMD_REPAINT:
+ if( !IsNoRepaint() )
+ {
+ maGrid.ImplRedraw();
+ maRuler.ImplRedraw();
+ InitHScrollBar();
+ InitVScrollBar();
+ }
+ break;
+ case CSVCMD_MAKEPOSVISIBLE:
+ MakePosVisible( nParam1 );
+ break;
+
+ case CSVCMD_NEWCELLTEXTS:
+ if( mbFixedMode )
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ else
+ {
+ DisableRepaint();
+ ScCsvColStateVec aStates( maGrid.GetColumnStates() );
+ sal_Int32 nPos = GetFirstVisPos();
+ Execute( CSVCMD_SETPOSCOUNT, 1 );
+ Execute( CSVCMD_UPDATECELLTEXTS );
+ Execute( CSVCMD_SETPOSOFFSET, nPos );
+ maGrid.SetColumnStates( aStates );
+ EnableRepaint();
+ }
+ break;
+ case CSVCMD_UPDATECELLTEXTS:
+ maUpdateTextHdl.Call( this );
+ break;
+ case CSVCMD_SETCOLUMNTYPE:
+ maGrid.SetSelColumnType( nParam1 );
+ break;
+ case CSVCMD_EXPORTCOLUMNTYPE:
+ maColTypeHdl.Call( this );
+ break;
+ case CSVCMD_SETFIRSTIMPORTLINE:
+ maGrid.SetFirstImportedLine( nParam1 );
+ break;
+
+ case CSVCMD_INSERTSPLIT:
+ DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::InsertSplit - invalid call" );
+ if( maRuler.GetSplitCount() + 1 < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT) )
+ {
+ maRuler.InsertSplit( nParam1 );
+ maGrid.InsertSplit( nParam1 );
+ }
+ break;
+ case CSVCMD_REMOVESPLIT:
+ DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveSplit - invalid call" );
+ maRuler.RemoveSplit( nParam1 );
+ maGrid.RemoveSplit( nParam1 );
+ break;
+ case CSVCMD_TOGGLESPLIT:
+ Execute( maRuler.HasSplit( nParam1 ) ? CSVCMD_REMOVESPLIT : CSVCMD_INSERTSPLIT, nParam1 );
+ break;
+ case CSVCMD_MOVESPLIT:
+ DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::MoveSplit - invalid call" );
+ maRuler.MoveSplit( nParam1, nParam2 );
+ maGrid.MoveSplit( nParam1, nParam2 );
+ break;
+ case CSVCMD_REMOVEALLSPLITS:
+ DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveAllSplits - invalid call" );
+ maRuler.RemoveAllSplits();
+ maGrid.RemoveAllSplits();
+ break;
+ default:
+ bFound = false;
+ }
+ if( bFound )
+ return 0;
+
+ const ScCsvLayoutData aOldData( maData );
+ switch( eType )
+ {
+ case CSVCMD_SETPOSCOUNT:
+ maData.mnPosCount = Max( nParam1, sal_Int32( 1 ) );
+ ImplSetPosOffset( GetFirstVisPos() );
+ break;
+ case CSVCMD_SETPOSOFFSET:
+ ImplSetPosOffset( nParam1 );
+ break;
+ case CSVCMD_SETHDRWIDTH:
+ maData.mnHdrWidth = Max( nParam1, sal_Int32( 0 ) );
+ ImplSetPosOffset( GetFirstVisPos() );
+ break;
+ case CSVCMD_SETCHARWIDTH:
+ maData.mnCharWidth = Max( nParam1, sal_Int32( 1 ) );
+ ImplSetPosOffset( GetFirstVisPos() );
+ break;
+ case CSVCMD_SETLINECOUNT:
+ maData.mnLineCount = Max( nParam1, sal_Int32( 1 ) );
+ ImplSetLineOffset( GetFirstVisLine() );
+ break;
+ case CSVCMD_SETLINEOFFSET:
+ ImplSetLineOffset( nParam1 );
+ break;
+ case CSVCMD_SETHDRHEIGHT:
+ maData.mnHdrHeight = Max( nParam1, sal_Int32( 0 ) );
+ ImplSetLineOffset( GetFirstVisLine() );
+ break;
+ case CSVCMD_SETLINEHEIGHT:
+ maData.mnLineHeight = Max( nParam1, sal_Int32( 1 ) );
+ ImplSetLineOffset( GetFirstVisLine() );
+ break;
+ case CSVCMD_MOVERULERCURSOR:
+ maData.mnPosCursor = IsVisibleSplitPos( nParam1 ) ? nParam1 : CSV_POS_INVALID;
+ break;
+ case CSVCMD_MOVEGRIDCURSOR:
+ maData.mnColCursor = ((0 <= nParam1) && (nParam1 < GetPosCount())) ? nParam1 : CSV_POS_INVALID;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if( maData != aOldData )
+ {
+ DisableRepaint();
+ maRuler.ApplyLayout( aOldData );
+ maGrid.ApplyLayout( aOldData );
+ EnableRepaint();
+ }
+
+ return 0;
+}
+
+IMPL_LINK( ScCsvTableBox, ScrollHdl, ScrollBar*, pScrollBar )
+{
+ DBG_ASSERT( pScrollBar, "ScCsvTableBox::ScrollHdl - missing sender" );
+
+ if( pScrollBar == &maHScroll )
+ Execute( CSVCMD_SETPOSOFFSET, pScrollBar->GetThumbPos() );
+ else if( pScrollBar == &maVScroll )
+ Execute( CSVCMD_SETLINEOFFSET, pScrollBar->GetThumbPos() );
+
+ return 0;
+}
+
+IMPL_LINK( ScCsvTableBox, ScrollEndHdl, ScrollBar*, pScrollBar )
+{
+ DBG_ASSERT( pScrollBar, "ScCsvTableBox::ScrollEndHdl - missing sender" );
+
+ if( pScrollBar == &maHScroll )
+ {
+ if( GetRulerCursorPos() != CSV_POS_INVALID )
+ Execute( CSVCMD_MOVERULERCURSOR, maRuler.GetNoScrollPos( GetRulerCursorPos() ) );
+ if( GetGridCursorPos() != CSV_POS_INVALID )
+ Execute( CSVCMD_MOVEGRIDCURSOR, maGrid.GetNoScrollCol( GetGridCursorPos() ) );
+ }
+
+ return 0;
+}
+
+
+// accessibility --------------------------------------------------------------
+
+ScCsvTableBox::XAccessibleRef ScCsvTableBox::CreateAccessible()
+{
+ // do not use the ScCsvControl mechanism, return default accessible object
+ return Control::CreateAccessible();
+}
+
+ScAccessibleCsvControl* ScCsvTableBox::ImplCreateAccessible()
+{
+ return NULL; // not used, see CreateAccessible()
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/dapidata.cxx b/sc/source/ui/dbgui/dapidata.cxx
new file mode 100644
index 000000000000..976e0ae23039
--- /dev/null
+++ b/sc/source/ui/dbgui/dapidata.cxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+#include <vcl/waitobj.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+
+using namespace com::sun::star;
+
+#include "dapidata.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "dapitype.hrc"
+#include "miscuno.hxx"
+#include "dpsdbtab.hxx" // ScImportSourceDesc
+
+//-------------------------------------------------------------------------
+
+#define DP_SERVICE_DBCONTEXT "com.sun.star.sdb.DatabaseContext"
+#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler"
+
+// entries in the "type" ListBox
+#define DP_TYPELIST_TABLE 0
+#define DP_TYPELIST_QUERY 1
+#define DP_TYPELIST_SQL 2
+#define DP_TYPELIST_SQLNAT 3
+
+//-------------------------------------------------------------------------
+
+ScDataPilotDatabaseDlg::ScDataPilotDatabaseDlg( Window* pParent ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DAPIDATA ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aFtDatabase ( this, ScResId( FT_DATABASE ) ),
+ aLbDatabase ( this, ScResId( LB_DATABASE ) ),
+ aFtObject ( this, ScResId( FT_OBJECT ) ),
+ aCbObject ( this, ScResId( CB_OBJECT ) ),
+ aFtType ( this, ScResId( FT_OBJTYPE ) ),
+ aLbType ( this, ScResId( LB_OBJTYPE ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ FreeResource();
+
+ WaitObject aWait( this ); // initializing the database service the first time takes a while
+
+ try
+ {
+ // get database names
+
+ uno::Reference<container::XNameAccess> xContext(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( DP_SERVICE_DBCONTEXT ) ),
+ uno::UNO_QUERY);
+ if (xContext.is())
+ {
+ uno::Sequence<rtl::OUString> aNames = xContext->getElementNames();
+ long nCount = aNames.getLength();
+ const rtl::OUString* pArray = aNames.getConstArray();
+ for (long nPos = 0; nPos < nCount; nPos++)
+ {
+ String aName = pArray[nPos];
+ aLbDatabase.InsertEntry( aName );
+ }
+ }
+ }
+ catch(uno::Exception&)
+ {
+ DBG_ERROR("exception in database");
+ }
+
+ aLbDatabase.SelectEntryPos( 0 );
+ aLbType.SelectEntryPos( 0 );
+
+ FillObjects();
+
+ aLbDatabase.SetSelectHdl( LINK( this, ScDataPilotDatabaseDlg, SelectHdl ) );
+ aLbType.SetSelectHdl( LINK( this, ScDataPilotDatabaseDlg, SelectHdl ) );
+}
+
+ScDataPilotDatabaseDlg::~ScDataPilotDatabaseDlg()
+{
+}
+
+void ScDataPilotDatabaseDlg::GetValues( ScImportSourceDesc& rDesc )
+{
+ USHORT nSelect = aLbType.GetSelectEntryPos();
+
+ rDesc.aDBName = aLbDatabase.GetSelectEntry();
+ rDesc.aObject = aCbObject.GetText();
+
+ if ( !rDesc.aDBName.Len() || !rDesc.aObject.Len() )
+ rDesc.nType = sheet::DataImportMode_NONE;
+ else if ( nSelect == DP_TYPELIST_TABLE )
+ rDesc.nType = sheet::DataImportMode_TABLE;
+ else if ( nSelect == DP_TYPELIST_QUERY )
+ rDesc.nType = sheet::DataImportMode_QUERY;
+ else
+ rDesc.nType = sheet::DataImportMode_SQL;
+
+ rDesc.bNative = ( nSelect == DP_TYPELIST_SQLNAT );
+}
+
+IMPL_LINK( ScDataPilotDatabaseDlg, SelectHdl, ListBox*, EMPTYARG )
+{
+ FillObjects();
+ return 0;
+}
+
+void ScDataPilotDatabaseDlg::FillObjects()
+{
+ aCbObject.Clear();
+
+ String aDatabaseName = aLbDatabase.GetSelectEntry();
+ if (!aDatabaseName.Len())
+ return;
+
+ USHORT nSelect = aLbType.GetSelectEntryPos();
+ if ( nSelect > DP_TYPELIST_QUERY )
+ return; // only tables and queries
+
+ try
+ {
+ // open connection (for tables or queries)
+
+ uno::Reference<container::XNameAccess> xContext(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( DP_SERVICE_DBCONTEXT ) ),
+ uno::UNO_QUERY);
+ if ( !xContext.is() ) return;
+
+ uno::Any aSourceAny = xContext->getByName( aDatabaseName );
+ uno::Reference<sdb::XCompletedConnection> xSource(
+ ScUnoHelpFunctions::AnyToInterface( aSourceAny ), uno::UNO_QUERY );
+ if ( !xSource.is() ) return;
+
+ uno::Reference<task::XInteractionHandler> xHandler(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
+ uno::UNO_QUERY);
+
+ uno::Reference<sdbc::XConnection> xConnection = xSource->connectWithCompletion( xHandler );
+
+ uno::Sequence<rtl::OUString> aNames;
+ if ( nSelect == DP_TYPELIST_TABLE )
+ {
+ // get all tables
+
+ uno::Reference<sdbcx::XTablesSupplier> xTablesSupp( xConnection, uno::UNO_QUERY );
+ if ( !xTablesSupp.is() ) return;
+
+ uno::Reference<container::XNameAccess> xTables = xTablesSupp->getTables();
+ if ( !xTables.is() ) return;
+
+ aNames = xTables->getElementNames();
+ }
+ else
+ {
+ // get all queries
+
+ uno::Reference<sdb::XQueriesSupplier> xQueriesSupp( xConnection, uno::UNO_QUERY );
+ if ( !xQueriesSupp.is() ) return;
+
+ uno::Reference<container::XNameAccess> xQueries = xQueriesSupp->getQueries();
+ if ( !xQueries.is() ) return;
+
+ aNames = xQueries->getElementNames();
+ }
+
+ // fill list
+
+ long nCount = aNames.getLength();
+ const rtl::OUString* pArray = aNames.getConstArray();
+ for( long nPos=0; nPos<nCount; nPos++ )
+ {
+ String aName = pArray[nPos];
+ aCbObject.InsertEntry( aName );
+ }
+ }
+ catch(uno::Exception&)
+ {
+ // #71604# this may happen if an invalid database is selected -> no DBG_ERROR
+ DBG_WARNING("exception in database");
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/dbgui/dapitype.cxx b/sc/source/ui/dbgui/dapitype.cxx
new file mode 100644
index 000000000000..31aafbcb13da
--- /dev/null
+++ b/sc/source/ui/dbgui/dapitype.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "dapitype.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "dapitype.hrc"
+
+using namespace com::sun::star;
+
+//-------------------------------------------------------------------------
+
+ScDataPilotSourceTypeDlg::ScDataPilotSourceTypeDlg( Window* pParent, BOOL bEnableExternal ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DAPITYPE ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnSelection ( this, ScResId( BTN_SELECTION ) ),
+ aBtnDatabase ( this, ScResId( BTN_DATABASE ) ),
+ aBtnExternal ( this, ScResId( BTN_EXTERNAL ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ if (!bEnableExternal)
+ aBtnExternal.Disable();
+
+ aBtnSelection.Check();
+
+ FreeResource();
+}
+
+ScDataPilotSourceTypeDlg::~ScDataPilotSourceTypeDlg()
+{
+}
+
+BOOL ScDataPilotSourceTypeDlg::IsDatabase() const
+{
+ return aBtnDatabase.IsChecked();
+}
+
+BOOL ScDataPilotSourceTypeDlg::IsExternal() const
+{
+ return aBtnExternal.IsChecked();
+}
+
+//-------------------------------------------------------------------------
+
+ScDataPilotServiceDlg::ScDataPilotServiceDlg( Window* pParent,
+ const uno::Sequence<rtl::OUString>& rServices ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DAPISERVICE ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aFtService ( this, ScResId( FT_SERVICE ) ),
+ aLbService ( this, ScResId( LB_SERVICE ) ),
+ aFtSource ( this, ScResId( FT_SOURCE ) ),
+ aEdSource ( this, ScResId( ED_SOURCE ) ),
+ aFtName ( this, ScResId( FT_NAME ) ),
+ aEdName ( this, ScResId( ED_NAME ) ),
+ aFtUser ( this, ScResId( FT_USER ) ),
+ aEdUser ( this, ScResId( ED_USER ) ),
+ aFtPasswd ( this, ScResId( FT_PASSWD ) ),
+ aEdPasswd ( this, ScResId( ED_PASSWD ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ long nCount = rServices.getLength();
+ const rtl::OUString* pArray = rServices.getConstArray();
+ for (long i=0; i<nCount; i++)
+ {
+ String aName = pArray[i];
+ aLbService.InsertEntry( aName );
+ }
+ aLbService.SelectEntryPos( 0 );
+
+ FreeResource();
+}
+
+ScDataPilotServiceDlg::~ScDataPilotServiceDlg()
+{
+}
+
+String ScDataPilotServiceDlg::GetServiceName() const
+{
+ return aLbService.GetSelectEntry();
+}
+
+String ScDataPilotServiceDlg::GetParSource() const
+{
+ return aEdSource.GetText();
+}
+
+String ScDataPilotServiceDlg::GetParName() const
+{
+ return aEdName.GetText();
+}
+
+String ScDataPilotServiceDlg::GetParUser() const
+{
+ return aEdUser.GetText();
+}
+
+String ScDataPilotServiceDlg::GetParPass() const
+{
+ return aEdPasswd.GetText();
+}
+
+
+
diff --git a/sc/source/ui/dbgui/dapitype.hrc b/sc/source/ui/dbgui/dapitype.hrc
new file mode 100644
index 000000000000..efbabe64fa04
--- /dev/null
+++ b/sc/source/ui/dbgui/dapitype.hrc
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+#define BTN_SELECTION 4
+#define BTN_DATABASE 5
+#define BTN_EXTERNAL 6
+#define FL_FRAME 7
+
+#define FT_SERVICE 8
+#define LB_SERVICE 9
+#define FT_SOURCE 10
+#define ED_SOURCE 11
+#define FT_NAME 12
+#define ED_NAME 13
+#define FT_USER 14
+#define ED_USER 15
+#define FT_PASSWD 16
+#define ED_PASSWD 17
+
+#define FT_DATABASE 18
+#define LB_DATABASE 19
+#define FT_OBJECT 20
+#define CB_OBJECT 21
+#define FT_OBJTYPE 22
+#define LB_OBJTYPE 23
+
diff --git a/sc/source/ui/dbgui/dapitype.src b/sc/source/ui/dbgui/dapitype.src
new file mode 100644
index 000000000000..5cf1dacad819
--- /dev/null
+++ b/sc/source/ui/dbgui/dapitype.src
@@ -0,0 +1,308 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+#include "dapitype.hrc"
+
+
+ModalDialog RID_SCDLG_DAPITYPE
+{
+ OutputSize = TRUE ;
+ HelpId = HID_DATAPILOT_TYPE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 241 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 185 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 185 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 185 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_SELECTION
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 164 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Current selection";
+ };
+ RadioButton BTN_DATABASE
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 164 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Data source registered in %PRODUCTNAME";
+ };
+ RadioButton BTN_EXTERNAL
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 164 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~External source/interface";
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 173 , 8 ) ;
+ Text [ en-US ] = "Selection";
+ };
+ Text [ en-US ] = "Select Source";
+};
+
+
+//------------------------------------------------------------------------
+
+
+ModalDialog RID_SCDLG_DAPISERVICE
+{
+ OutputSize = TRUE ;
+ HelpId = HID_DATAPILOT_SERVICE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 241 , 94 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 185 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 185 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 185 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_SERVICE
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "~Service";
+ };
+ ListBox LB_SERVICE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 56 , 12 ) ;
+ Size = MAP_APPFONT ( 120 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_SOURCE
+ {
+ Pos = MAP_APPFONT ( 12 , 30 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "So~urce";
+ };
+ Edit ED_SOURCE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 56 , 28 ) ;
+ Size = MAP_APPFONT ( 120 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_NAME
+ {
+ Pos = MAP_APPFONT ( 12 , 46 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "~Name";
+ };
+ Edit ED_NAME
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 56 , 44 ) ;
+ Size = MAP_APPFONT ( 120 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_USER
+ {
+ Pos = MAP_APPFONT ( 12 , 62 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "Us~er";
+ };
+ Edit ED_USER
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 56 , 60 ) ;
+ Size = MAP_APPFONT ( 120 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_PASSWD
+ {
+ Pos = MAP_APPFONT ( 12 , 78 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "~Password";
+ };
+ Edit ED_PASSWD
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 56 , 76 ) ;
+ Size = MAP_APPFONT ( 120 , 12 ) ;
+ TabStop = TRUE ;
+ PassWord = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 173 , 8 ) ;
+ Text [ en-US ] = "Selection";
+ };
+ Text [ en-US ] = "External Source";
+};
+
+
+//------------------------------------------------------------------------
+
+
+ModalDialog RID_SCDLG_DAPIDATA
+{
+ OutputSize = TRUE ;
+ HelpId = HID_DATAPILOT_DATABASE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 241 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 185 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 185 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 185 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+
+ FixedText FT_DATABASE
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 52 , 8 ) ;
+ Text [ en-US ] = "~Database";
+ };
+ ListBox LB_DATABASE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 66 , 12 ) ;
+ Size = MAP_APPFONT ( 110 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+
+ FixedText FT_OBJECT
+ {
+ Pos = MAP_APPFONT ( 12 , 30 ) ;
+ Size = MAP_APPFONT ( 52 , 8 ) ;
+ Text [ en-US ] = "Data so~urce";
+ };
+ ComboBox CB_OBJECT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 66 , 28 ) ;
+ Size = MAP_APPFONT ( 110 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+
+ FixedText FT_OBJTYPE
+ {
+ Pos = MAP_APPFONT ( 12 , 46 ) ;
+ Size = MAP_APPFONT ( 52 , 8 ) ;
+ Text [ en-US ] = "~Type";
+ };
+ ListBox LB_OBJTYPE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 66 , 44 ) ;
+ Size = MAP_APPFONT ( 110 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Sheet" ; Default ; > ;
+ < "Query" ; Default ; > ;
+ < "Sql" ; Default ; > ;
+ < "Sql [Native]" ; Default ; > ;
+ };
+ };
+
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 173 , 8 ) ;
+ Text [ en-US ] = "Selection";
+ };
+ Text [ en-US ] = "Select Data Source";
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/dbgui/dbnamdlg.cxx b/sc/source/ui/dbgui/dbnamdlg.cxx
new file mode 100644
index 000000000000..a2f4d61af537
--- /dev/null
+++ b/sc/source/ui/dbgui/dbnamdlg.cxx
@@ -0,0 +1,721 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+
+#include <vcl/msgbox.hxx>
+
+#include "reffact.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "dbnamdlg.hrc"
+#include "rangenam.hxx" // IsNameValid
+
+#define _DBNAMDLG_CXX
+#include "dbnamdlg.hxx"
+#undef _DBNAMDLG_CXX
+
+
+//============================================================================
+
+#define ABS_SREF SCA_VALID \
+ | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
+#define ABS_DREF ABS_SREF \
+ | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
+#define ABS_SREF3D ABS_SREF | SCA_TAB_3D
+#define ABS_DREF3D ABS_DREF | SCA_TAB_3D
+
+//----------------------------------------------------------------------------
+
+class DBSaveData;
+
+static DBSaveData* pSaveObj = NULL;
+
+#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute()
+#define QUERYBOX(m) QueryBox(this,WinBits(WB_YES_NO|WB_DEF_YES),m).Execute()
+
+//============================================================================
+// class DBSaveData
+
+class DBSaveData
+{
+public:
+ DBSaveData( Edit& rEd, CheckBox& rHdr, CheckBox& rSize, CheckBox& rFmt,
+ CheckBox& rStrip, ScRange& rArea )
+ : rEdAssign(rEd),
+ rBtnHeader(rHdr), rBtnSize(rSize), rBtnFormat(rFmt), rBtnStrip(rStrip),
+ rCurArea(rArea),
+ bHeader(FALSE), bSize(FALSE), bFormat(FALSE), bDirty(FALSE) {}
+ void Save();
+ void Restore();
+
+private:
+ Edit& rEdAssign;
+ CheckBox& rBtnHeader;
+ CheckBox& rBtnSize;
+ CheckBox& rBtnFormat;
+ CheckBox& rBtnStrip;
+ ScRange& rCurArea;
+ String aStr;
+ ScRange aArea;
+ BOOL bHeader:1;
+ BOOL bSize:1;
+ BOOL bFormat:1;
+ BOOL bStrip:1;
+ BOOL bDirty:1;
+};
+
+
+
+//----------------------------------------------------------------------------
+
+void DBSaveData::Save()
+{
+ aArea = rCurArea;
+ aStr = rEdAssign.GetText();
+ bHeader = rBtnHeader.IsChecked();
+ bSize = rBtnSize.IsChecked();
+ bFormat = rBtnFormat.IsChecked();
+ bStrip = rBtnStrip.IsChecked();
+ bDirty = TRUE;
+}
+
+
+//----------------------------------------------------------------------------
+
+void DBSaveData::Restore()
+{
+ if ( bDirty )
+ {
+ rCurArea = aArea;
+ rEdAssign.SetText( aStr );
+ rBtnHeader.Check ( bHeader );
+ rBtnSize.Check ( bSize );
+ rBtnFormat.Check ( bFormat );
+ rBtnStrip.Check ( bStrip );
+ bDirty = FALSE;
+ }
+}
+
+
+//============================================================================
+// class ScDbNameDlg
+
+//----------------------------------------------------------------------------
+
+ScDbNameDlg::ScDbNameDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_DBNAMES ),
+ //
+ aFlName ( this, ScResId( FL_NAME ) ),
+ aEdName ( this, ScResId( ED_NAME ) ),
+
+ aFlAssign ( this, ScResId( FL_ASSIGN ) ),
+ aEdAssign ( this, this, ScResId( ED_DBAREA ) ),
+ aRbAssign ( this, ScResId( RB_DBAREA ), &aEdAssign, this ),
+
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ aBtnHeader ( this, ScResId( BTN_HEADER ) ),
+ aBtnDoSize ( this, ScResId( BTN_SIZE ) ),
+ aBtnKeepFmt ( this, ScResId( BTN_FORMAT ) ),
+ aBtnStripData ( this, ScResId( BTN_STRIPDATA ) ),
+ aFTSource ( this, ScResId( FT_SOURCE ) ),
+ aFTOperations ( this, ScResId( FT_OPERATIONS ) ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnAdd ( this, ScResId( BTN_ADD ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+
+ aStrAdd ( ScResId( STR_ADD ) ),
+ aStrModify ( ScResId( STR_MODIFY ) ),
+ aStrNoName ( ScGlobal::GetRscString(STR_DB_NONAME) ),
+ aStrInvalid ( ScResId( STR_DB_INVALID ) ),
+ //
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData->GetDocument() ),
+ bRefInputMode ( FALSE ),
+ aAddrDetails ( pDoc->GetAddressConvention(), 0, 0 ),
+ aLocalDbCol ( *(pDoc->GetDBCollection()) )
+{
+ // WB_NOLABEL can't be set in resource...
+ aFTSource.SetStyle( aFTSource.GetStyle() | WB_NOLABEL );
+ aFTOperations.SetStyle( aFTOperations.GetStyle() | WB_NOLABEL );
+
+ // damit die Strings in der Resource bei den FixedTexten bleiben koennen:
+ aStrSource = aFTSource.GetText();
+ aStrOperations = aFTOperations.GetText();
+
+ pSaveObj = new DBSaveData( aEdAssign, aBtnHeader,
+ aBtnDoSize, aBtnKeepFmt, aBtnStripData, theCurArea );
+ Init();
+ FreeResource();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScDbNameDlg::~ScDbNameDlg()
+{
+ DELETEZ( pSaveObj );
+
+ ScRange* pEntry = (ScRange*)aRemoveList.First();
+ while ( pEntry )
+ {
+ aRemoveList.Remove( pEntry );
+ delete pEntry;
+ pEntry = (ScRange*)aRemoveList.Next();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDbNameDlg::Init()
+{
+ aBtnHeader.Check( TRUE ); // Default: mit Spaltenkoepfen
+
+ aBtnMore.AddWindow( &aFlOptions );
+ aBtnMore.AddWindow( &aBtnHeader );
+ aBtnMore.AddWindow( &aBtnDoSize );
+ aBtnMore.AddWindow( &aBtnKeepFmt );
+ aBtnMore.AddWindow( &aBtnStripData );
+ aBtnMore.AddWindow( &aFTSource );
+ aBtnMore.AddWindow( &aFTOperations );
+
+ String theAreaStr;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCTAB nStartTab = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ SCTAB nEndTab = 0;
+
+ aBtnOk.SetClickHdl ( LINK( this, ScDbNameDlg, OkBtnHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScDbNameDlg, CancelBtnHdl ) );
+ aBtnAdd.SetClickHdl ( LINK( this, ScDbNameDlg, AddBtnHdl ) );
+ aBtnRemove.SetClickHdl ( LINK( this, ScDbNameDlg, RemoveBtnHdl ) );
+ aEdName.SetModifyHdl ( LINK( this, ScDbNameDlg, NameModifyHdl ) );
+ aEdAssign.SetModifyHdl ( LINK( this, ScDbNameDlg, AssModifyHdl ) );
+ UpdateNames();
+
+ if ( pViewData && pDoc )
+ {
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ ScDBData* pDBData = NULL;
+
+ pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ theCurArea = ScRange( ScAddress( nStartCol, nStartRow, nStartTab ),
+ ScAddress( nEndCol, nEndRow, nEndTab ) );
+
+ theCurArea.Format( theAreaStr, ABS_DREF3D, pDoc, aAddrDetails );
+
+ if ( pDBColl )
+ {
+ // Feststellen, ob definierter DB-Bereich markiert wurde:
+ pDBData = pDBColl->GetDBAtCursor( nStartCol, nStartRow, nStartTab, TRUE );
+ if ( pDBData )
+ {
+ String theDbName;
+ ScAddress& rStart = theCurArea.aStart;
+ ScAddress& rEnd = theCurArea.aEnd;
+ SCCOL nCol1;
+ SCCOL nCol2;
+ SCROW nRow1;
+ SCROW nRow2;
+ SCTAB nTab;
+
+ pDBData->GetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
+
+ if ( (rStart.Tab() == nTab)
+ && (rStart.Col() == nCol1) && (rStart.Row() == nRow1)
+ && (rEnd.Col() == nCol2) && (rEnd.Row() == nRow2 ) )
+ {
+ pDBData->GetName( theDbName );
+ if ( theDbName != aStrNoName )
+ aEdName.SetText( theDbName );
+ else
+ aEdName.SetText( EMPTY_STRING );
+ aBtnHeader.Check( pDBData->HasHeader() );
+ aBtnDoSize.Check( pDBData->IsDoSize() );
+ aBtnKeepFmt.Check( pDBData->IsKeepFmt() );
+ aBtnStripData.Check( pDBData->IsStripData() );
+ SetInfoStrings( pDBData );
+ }
+ }
+ }
+ }
+
+ aEdAssign.SetText( theAreaStr );
+ aEdName.GrabFocus();
+ bSaved=TRUE;
+ pSaveObj->Save();
+ NameModifyHdl( 0 );
+}
+
+
+void ScDbNameDlg::SetInfoStrings( const ScDBData* pDBData )
+{
+ String aSource = aStrSource;
+ if (pDBData)
+ {
+ aSource += ' ';
+ aSource += pDBData->GetSourceString();
+ }
+ aFTSource.SetText( aSource );
+
+ String aOper = aStrOperations;
+ if (pDBData)
+ {
+ aOper += ' ';
+ aOper += pDBData->GetOperations();
+ }
+ aFTOperations.SetText( aOper );
+}
+
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Fenster angezeigt wird.
+
+void ScDbNameDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( aEdAssign.IsEnabled() )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( &aEdAssign );
+
+ theCurArea = rRef;
+
+ String aRefStr;
+ theCurArea.Format( aRefStr, ABS_DREF3D, pDocP, aAddrDetails );
+ aEdAssign.SetRefString( aRefStr );
+ aBtnHeader.Enable();
+ aBtnDoSize.Enable();
+ aBtnKeepFmt.Enable();
+ aBtnStripData.Enable();
+ aFTSource.Enable();
+ aFTOperations.Enable();
+ aBtnAdd.Enable();
+ bSaved=TRUE;
+ pSaveObj->Save();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScDbNameDlg::Close()
+{
+ return DoClose( ScDbNameDlgWrapper::GetChildWindowId() );
+}
+
+//------------------------------------------------------------------------
+
+void ScDbNameDlg::SetActive()
+{
+ aEdAssign.GrabFocus();
+
+ // kein NameModifyHdl, weil sonst Bereiche nicht geaendert werden koennen
+ // (nach dem Aufziehen der Referenz wuerde der alte Inhalt wieder angezeigt)
+ // (der ausgewaehlte DB-Name hat sich auch nicht veraendert)
+
+ RefInputDone();
+}
+
+//------------------------------------------------------------------------
+
+void ScDbNameDlg::UpdateNames()
+{
+ USHORT nNameCount = aLocalDbCol.GetCount();
+
+ aEdName.SetUpdateMode( FALSE );
+ //-----------------------------------------------------------
+ aEdName.Clear();
+ aEdAssign.SetText( EMPTY_STRING );
+
+ if ( nNameCount > 0 )
+ {
+ ScDBData* pDbData = NULL;
+ String aString;
+
+ for ( USHORT i=0; i<nNameCount; i++ )
+ {
+ pDbData = (ScDBData*)(aLocalDbCol.At( i ));
+ if ( pDbData )
+ {
+ pDbData->GetName( aString );
+ if ( aString != aStrNoName )
+ aEdName.InsertEntry( aString );
+ }
+ }
+ }
+ else
+ {
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ }
+ //-----------------------------------------------------------
+ aEdName.SetUpdateMode( TRUE );
+ aEdName.Invalidate();
+}
+
+//------------------------------------------------------------------------
+
+void ScDbNameDlg::UpdateDBData( const String& rStrName )
+{
+ String theArea;
+ USHORT nAt;
+ ScDBData* pData;
+
+ aLocalDbCol.SearchName( rStrName, nAt );
+ pData = (ScDBData*)(aLocalDbCol.At( nAt ));
+
+ if ( pData )
+ {
+ SCCOL nColStart = 0;
+ SCROW nRowStart = 0;
+ SCCOL nColEnd = 0;
+ SCROW nRowEnd = 0;
+ SCTAB nTab = 0;
+
+ pData->GetArea( nTab, nColStart, nRowStart, nColEnd, nRowEnd );
+ theCurArea = ScRange( ScAddress( nColStart, nRowStart, nTab ),
+ ScAddress( nColEnd, nRowEnd, nTab ) );
+ theCurArea.Format( theArea, ABS_DREF3D, pDoc, aAddrDetails );
+ aEdAssign.SetText( theArea );
+ aBtnAdd.SetText( aStrModify );
+ aBtnHeader.Check( pData->HasHeader() );
+ aBtnDoSize.Check( pData->IsDoSize() );
+ aBtnKeepFmt.Check( pData->IsKeepFmt() );
+ aBtnStripData.Check( pData->IsStripData() );
+ SetInfoStrings( pData );
+ }
+
+ aBtnAdd.SetText( aStrModify );
+ aBtnAdd.Enable();
+ aBtnRemove.Enable();
+ aBtnHeader.Enable();
+ aBtnDoSize.Enable();
+ aBtnKeepFmt.Enable();
+ aBtnStripData.Enable();
+ aFTSource.Enable();
+ aFTOperations.Enable();
+}
+
+//------------------------------------------------------------------------
+
+
+BOOL ScDbNameDlg::IsRefInputMode() const
+{
+ return bRefInputMode;
+}
+
+//------------------------------------------------------------------------
+// Handler:
+// ========
+
+IMPL_LINK( ScDbNameDlg, OkBtnHdl, void *, EMPTYARG )
+{
+ AddBtnHdl( 0 );
+
+ // Der View die Aenderungen und die Remove-Liste uebergeben:
+ // beide werden nur als Referenz uebergeben, so dass an dieser
+ // Stelle keine Speicherleichen entstehen koennen:
+ if ( pViewData )
+ pViewData->GetView()->
+ NotifyCloseDbNameDlg( aLocalDbCol, aRemoveList );
+
+ Close();
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScDbNameDlg, CancelBtnHdl, void *, EMPTYARG )
+{
+ Close();
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScDbNameDlg, CancelBtnHdl, void *, EMPTYARG )
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScDbNameDlg, AddBtnHdl, void *, EMPTYARG )
+{
+ String aNewName = aEdName.GetText();
+ String aNewArea = aEdAssign.GetText();
+
+ aNewName.EraseLeadingChars( ' ' );
+ aNewName.EraseTrailingChars( ' ' );
+
+ if ( aNewName.Len() > 0 && aNewArea.Len() > 0 )
+ {
+ if ( ScRangeData::IsNameValid( aNewName, pDoc ) )
+ {
+ // weil jetzt editiert werden kann, muss erst geparst werden
+ ScRange aTmpRange;
+ String aText = aEdAssign.GetText();
+ if ( aTmpRange.ParseAny( aText, pDoc, aAddrDetails ) & SCA_VALID )
+ {
+ theCurArea = aTmpRange;
+ ScAddress aStart = theCurArea.aStart;
+ ScAddress aEnd = theCurArea.aEnd;
+
+ ScDBData* pOldEntry = NULL;
+ USHORT nFoundAt = 0;
+ if ( aLocalDbCol.SearchName( aNewName, nFoundAt ) )
+ pOldEntry = aLocalDbCol[nFoundAt];
+ if (pOldEntry)
+ {
+ // Bereich veraendern
+
+ pOldEntry->MoveTo( aStart.Tab(), aStart.Col(), aStart.Row(),
+ aEnd.Col(), aEnd.Row() );
+ pOldEntry->SetByRow( TRUE );
+ pOldEntry->SetHeader( aBtnHeader.IsChecked() );
+ pOldEntry->SetDoSize( aBtnDoSize.IsChecked() );
+ pOldEntry->SetKeepFmt( aBtnKeepFmt.IsChecked() );
+ pOldEntry->SetStripData( aBtnStripData.IsChecked() );
+ }
+ else
+ {
+ // neuen Bereich einfuegen
+
+ ScDBData* pNewEntry = new ScDBData( aNewName, aStart.Tab(),
+ aStart.Col(), aStart.Row(),
+ aEnd.Col(), aEnd.Row(),
+ TRUE, aBtnHeader.IsChecked() );
+ pNewEntry->SetDoSize( aBtnDoSize.IsChecked() );
+ pNewEntry->SetKeepFmt( aBtnKeepFmt.IsChecked() );
+ pNewEntry->SetStripData( aBtnStripData.IsChecked() );
+
+ if ( !aLocalDbCol.Insert( pNewEntry ) )
+ delete pNewEntry;
+ }
+
+ UpdateNames();
+
+ aEdName.SetText( EMPTY_STRING );
+ aEdName.GrabFocus();
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ aEdAssign.SetText( EMPTY_STRING );
+ aBtnHeader.Check( TRUE ); // Default: mit Spaltenkoepfen
+ aBtnDoSize.Check( FALSE );
+ aBtnKeepFmt.Check( FALSE );
+ aBtnStripData.Check( FALSE );
+ SetInfoStrings( NULL ); // leer
+ theCurArea = ScRange();
+ bSaved=TRUE;
+ pSaveObj->Save();
+ NameModifyHdl( 0 );
+ }
+ else
+ {
+ ERRORBOX( aStrInvalid );
+ aEdAssign.SetSelection( Selection( 0, SELECTION_MAX ) );
+ aEdAssign.GrabFocus();
+ }
+ }
+ else
+ {
+ ERRORBOX( ScGlobal::GetRscString(STR_INVALIDNAME) );
+ aEdName.SetSelection( Selection( 0, SELECTION_MAX ) );
+ aEdName.GrabFocus();
+ }
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScDbNameDlg, RemoveBtnHdl, void *, EMPTYARG )
+{
+ USHORT nRemoveAt = 0;
+ const String aStrEntry = aEdName.GetText();
+
+ if ( aLocalDbCol.SearchName( aStrEntry, nRemoveAt ) )
+ {
+ String aStrDelMsg = ScGlobal::GetRscString( STR_QUERY_DELENTRY );
+ String aMsg = aStrDelMsg.GetToken( 0, '#' );
+
+ aMsg += aStrEntry;
+ aMsg += aStrDelMsg.GetToken( 1, '#' );
+
+ if ( RET_YES == QUERYBOX(aMsg) )
+ {
+ ScDBData* pEntry = (ScDBData*)aLocalDbCol.At(nRemoveAt);
+
+ if ( pEntry )
+ {
+ SCTAB nTab;
+ SCCOL nColStart, nColEnd;
+ SCROW nRowStart, nRowEnd;
+ pEntry->GetArea( nTab, nColStart, nRowStart, nColEnd, nRowEnd );
+ aRemoveList.Insert(
+ new ScRange( ScAddress( nColStart, nRowStart, nTab ),
+ ScAddress( nColEnd, nRowEnd, nTab ) ) );
+ }
+ aLocalDbCol.AtFree( nRemoveAt );
+
+ UpdateNames();
+
+ aEdName.SetText( EMPTY_STRING );
+ aEdName.GrabFocus();
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ aEdAssign.SetText( EMPTY_STRING );
+ theCurArea = ScRange();
+ aBtnHeader.Check( TRUE ); // Default: mit Spaltenkoepfen
+ aBtnDoSize.Check( FALSE );
+ aBtnKeepFmt.Check( FALSE );
+ aBtnStripData.Check( FALSE );
+ SetInfoStrings( NULL ); // leer
+ bSaved=FALSE;
+ pSaveObj->Restore();
+ NameModifyHdl( 0 );
+ }
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScDbNameDlg, NameModifyHdl, void *, EMPTYARG )
+{
+ String theName = aEdName.GetText();
+ BOOL bNameFound = (COMBOBOX_ENTRY_NOTFOUND
+ != aEdName.GetEntryPos( theName ));
+
+ if ( theName.Len() == 0 )
+ {
+ if ( aBtnAdd.GetText() != aStrAdd )
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd .Disable();
+ aBtnRemove .Disable();
+ aFlAssign .Disable();
+ aBtnHeader .Disable();
+ aBtnDoSize .Disable();
+ aBtnKeepFmt .Disable();
+ aBtnStripData.Disable();
+ aFTSource .Disable();
+ aFTOperations.Disable();
+ aEdAssign .Disable();
+ aRbAssign .Disable();
+ //bSaved=FALSE;
+ //pSaveObj->Restore();
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+ bRefInputMode = FALSE;
+ }
+ else
+ {
+ if ( bNameFound )
+ {
+ if ( aBtnAdd.GetText() != aStrModify )
+ aBtnAdd.SetText( aStrModify );
+
+ if(!bSaved)
+ {
+ bSaved=TRUE;
+ pSaveObj->Save();
+ }
+ UpdateDBData( theName );
+ }
+ else
+ {
+ if ( aBtnAdd.GetText() != aStrAdd )
+ aBtnAdd.SetText( aStrAdd );
+
+ bSaved=FALSE;
+ pSaveObj->Restore();
+
+ if ( aEdAssign.GetText().Len() > 0 )
+ {
+ aBtnAdd.Enable();
+ aBtnHeader.Enable();
+ aBtnDoSize.Enable();
+ aBtnKeepFmt.Enable();
+ aBtnStripData.Enable();
+ aFTSource.Enable();
+ aFTOperations.Enable();
+ }
+ else
+ {
+ aBtnAdd.Disable();
+ aBtnHeader.Disable();
+ aBtnDoSize.Disable();
+ aBtnKeepFmt.Disable();
+ aBtnStripData.Disable();
+ aFTSource.Disable();
+ aFTOperations.Disable();
+ }
+ aBtnRemove.Disable();
+ }
+
+ aFlAssign.Enable();
+ aEdAssign.Enable();
+ aRbAssign.Enable();
+
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+ bRefInputMode = TRUE;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScDbNameDlg, AssModifyHdl, void *, EMPTYARG )
+{
+ // hier parsen fuer Save() etc.
+
+ ScRange aTmpRange;
+ String aText = aEdAssign.GetText();
+ if ( aTmpRange.ParseAny( aText, pDoc, aAddrDetails ) & SCA_VALID )
+ theCurArea = aTmpRange;
+
+ return 0;
+}
+
+
diff --git a/sc/source/ui/dbgui/dpgroupdlg.cxx b/sc/source/ui/dbgui/dpgroupdlg.cxx
new file mode 100644
index 000000000000..4ac3fb8d68ad
--- /dev/null
+++ b/sc/source/ui/dbgui/dpgroupdlg.cxx
@@ -0,0 +1,360 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#ifdef SC_DLLIMPLEMENTATION
+#undef SC_DLLIMPLEMENTATION
+#endif
+
+
+#include "dpgroupdlg.hxx"
+#ifndef SC_DPGROUPDLG_HRC
+#include "dpgroupdlg.hrc"
+#endif
+#include <tools/resary.hxx>
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+// ============================================================================
+
+namespace {
+
+/** Date part flags in order of the list box entries. */
+static const sal_Int32 spnDateParts[] =
+{
+ com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS,
+ com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES,
+ com::sun::star::sheet::DataPilotFieldGroupBy::HOURS,
+ com::sun::star::sheet::DataPilotFieldGroupBy::DAYS,
+ com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS,
+ com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS,
+ com::sun::star::sheet::DataPilotFieldGroupBy::YEARS
+};
+
+} // namespace
+
+// ============================================================================
+
+ScDPGroupEditHelper::ScDPGroupEditHelper( RadioButton& rRbAuto, RadioButton& rRbMan, Edit& rEdValue ) :
+ mrRbAuto( rRbAuto ),
+ mrRbMan( rRbMan ),
+ mrEdValue( rEdValue )
+{
+ mrRbAuto.SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
+ mrRbMan.SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
+}
+
+bool ScDPGroupEditHelper::IsAuto() const
+{
+ return mrRbAuto.IsChecked();
+}
+
+double ScDPGroupEditHelper::GetValue() const
+{
+ double fValue;
+ if( !ImplGetValue( fValue ) )
+ fValue = 0.0;
+ return fValue;
+}
+
+void ScDPGroupEditHelper::SetValue( bool bAuto, double fValue )
+{
+ if( bAuto )
+ {
+ mrRbAuto.Check();
+ ClickHdl( &mrRbAuto );
+ }
+ else
+ {
+ mrRbMan.Check();
+ ClickHdl( &mrRbMan );
+ }
+ ImplSetValue( fValue );
+}
+
+IMPL_LINK( ScDPGroupEditHelper, ClickHdl, RadioButton*, pButton )
+{
+ if( pButton == &mrRbAuto )
+ {
+ // disable edit field on clicking "automatic" radio button
+ mrEdValue.Disable();
+ }
+ else if( pButton == &mrRbMan )
+ {
+ // enable and set focus to edit field on clicking "manual" radio button
+ mrEdValue.Enable();
+ mrEdValue.GrabFocus();
+ }
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPNumGroupEditHelper::ScDPNumGroupEditHelper(
+ RadioButton& rRbAuto, RadioButton& rRbMan, ScDoubleField& rEdValue ) :
+ ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ),
+ mrEdValue( rEdValue )
+{
+}
+
+bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const
+{
+ return mrEdValue.GetValue( rfValue );
+}
+
+void ScDPNumGroupEditHelper::ImplSetValue( double fValue )
+{
+ mrEdValue.SetValue( fValue );
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPDateGroupEditHelper::ScDPDateGroupEditHelper(
+ RadioButton& rRbAuto, RadioButton& rRbMan, DateField& rEdValue, const Date& rNullDate ) :
+ ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ),
+ mrEdValue( rEdValue ),
+ maNullDate( rNullDate )
+{
+}
+
+bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const
+{
+ rfValue = mrEdValue.GetDate() - maNullDate;
+ return true;
+}
+
+void ScDPDateGroupEditHelper::ImplSetValue( double fValue )
+{
+ Date aDate( maNullDate );
+ aDate += static_cast< sal_Int32 >( fValue );
+ mrEdValue.SetDate( aDate );
+}
+
+// ============================================================================
+// ============================================================================
+
+ScDPNumGroupDlg::ScDPNumGroupDlg( Window* pParent, const ScDPNumGroupInfo& rInfo ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DPNUMGROUP ) ),
+ maFlStart ( this, ScResId( FL_START ) ),
+ maRbAutoStart ( this, ScResId( RB_AUTOSTART ) ),
+ maRbManStart ( this, ScResId( RB_MANSTART ) ),
+ maEdStart ( this, ScResId( ED_START ) ),
+ maFlEnd ( this, ScResId( FL_END ) ),
+ maRbAutoEnd ( this, ScResId( RB_AUTOEND ) ),
+ maRbManEnd ( this, ScResId( RB_MANEND ) ),
+ maEdEnd ( this, ScResId( ED_END ) ),
+ maFlBy ( this, ScResId( FL_BY ) ),
+ maEdBy ( this, ScResId( ED_BY ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maStartHelper ( maRbAutoStart, maRbManStart, maEdStart ),
+ maEndHelper ( maRbAutoEnd, maRbManEnd, maEdEnd )
+{
+ FreeResource();
+
+ maStartHelper.SetValue( rInfo.AutoStart, rInfo.Start );
+ maEndHelper.SetValue( rInfo.AutoEnd, rInfo.End );
+ maEdBy.SetValue( (rInfo.Step <= 0.0) ? 1.0 : rInfo.Step );
+
+ /* Set the initial focus, currently it is somewhere after calling all the radio
+ button click handlers. Now the first enabled editable control is focused. */
+ if( maEdStart.IsEnabled() )
+ maEdStart.GrabFocus();
+ else if( maEdEnd.IsEnabled() )
+ maEdEnd.GrabFocus();
+ else
+ maEdBy.GrabFocus();
+}
+
+ScDPNumGroupInfo ScDPNumGroupDlg::GetGroupInfo() const
+{
+ ScDPNumGroupInfo aInfo;
+ aInfo.Enable = sal_True;
+ aInfo.DateValues = sal_False;
+ aInfo.AutoStart = maStartHelper.IsAuto();
+ aInfo.AutoEnd = maEndHelper.IsAuto();
+
+ // get values and silently auto-correct them, if they are not valid
+ // TODO: error messages in OK event?
+ aInfo.Start = maStartHelper.GetValue();
+ aInfo.End = maEndHelper.GetValue();
+ if( !maEdBy.GetValue( aInfo.Step ) || (aInfo.Step <= 0.0) )
+ aInfo.Step = 1.0;
+ if( aInfo.End <= aInfo.Start )
+ aInfo.End = aInfo.Start + aInfo.Step;
+
+ return aInfo;
+}
+
+// ============================================================================
+
+ScDPDateGroupDlg::ScDPDateGroupDlg( Window* pParent,
+ const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DPDATEGROUP ) ),
+ maFlStart ( this, ScResId( FL_START ) ),
+ maRbAutoStart ( this, ScResId( RB_AUTOSTART ) ),
+ maRbManStart ( this, ScResId( RB_MANSTART ) ),
+ maEdStart ( this, ScResId( ED_START ) ),
+ maFlEnd ( this, ScResId( FL_END ) ),
+ maRbAutoEnd ( this, ScResId( RB_AUTOEND ) ),
+ maRbManEnd ( this, ScResId( RB_MANEND ) ),
+ maEdEnd ( this, ScResId( ED_END ) ),
+ maFlBy ( this, ScResId( FL_BY ) ),
+ maRbNumDays ( this, ScResId( RB_NUMDAYS ) ),
+ maRbUnits ( this, ScResId( RB_UNITS ) ),
+ maEdNumDays ( this, ScResId( ED_NUMDAYS ) ),
+ maLbUnits ( this, ScResId( LB_UNITS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maStartHelper ( maRbAutoStart, maRbManStart, maEdStart, rNullDate ),
+ maEndHelper ( maRbAutoEnd, maRbManEnd, maEdEnd, rNullDate )
+{
+ maLbUnits.SetHelpId( HID_SC_DPDATEGROUP_LB );
+ ResStringArray aArr( ScResId( STR_UNITS ) );
+ for( USHORT nIdx = 0, nCount = sal::static_int_cast<USHORT>(aArr.Count()); nIdx < nCount; ++nIdx )
+ maLbUnits.InsertEntry( aArr.GetString( nIdx ) );
+
+ FreeResource();
+
+ maEdStart.SetShowDateCentury( TRUE );
+ maEdEnd.SetShowDateCentury( TRUE );
+
+ maStartHelper.SetValue( rInfo.AutoStart, rInfo.Start );
+ maEndHelper.SetValue( rInfo.AutoEnd, rInfo.End );
+
+ if( nDatePart == 0 )
+ nDatePart = com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS;
+ for( ULONG nIdx = 0, nCount = maLbUnits.GetEntryCount(); nIdx < nCount; ++nIdx )
+ maLbUnits.CheckEntryPos( static_cast< USHORT >( nIdx ), (nDatePart & spnDateParts[ nIdx ]) != 0 );
+
+ if( rInfo.DateValues )
+ {
+ maRbNumDays.Check();
+ ClickHdl( &maRbNumDays );
+
+ double fNumDays = rInfo.Step;
+ if( fNumDays < 1.0 )
+ fNumDays = 1.0;
+ else if( fNumDays > 32767.0 )
+ fNumDays = 32767.0;
+ maEdNumDays.SetValue( static_cast< long >( fNumDays ) );
+ }
+ else
+ {
+ maRbUnits.Check();
+ ClickHdl( &maRbUnits );
+ }
+
+ /* Set the initial focus, currently it is somewhere after calling all the radio
+ button click handlers. Now the first enabled editable control is focused. */
+ if( maEdStart.IsEnabled() )
+ maEdStart.GrabFocus();
+ else if( maEdEnd.IsEnabled() )
+ maEdEnd.GrabFocus();
+ else if( maEdNumDays.IsEnabled() )
+ maEdNumDays.GrabFocus();
+ else if( maLbUnits.IsEnabled() )
+ maLbUnits.GrabFocus();
+
+ maRbNumDays.SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
+ maRbUnits.SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
+ maLbUnits.SetCheckButtonHdl( LINK( this, ScDPDateGroupDlg, CheckHdl ) );
+}
+
+ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const
+{
+ ScDPNumGroupInfo aInfo;
+ aInfo.Enable = sal_True;
+ aInfo.DateValues = maRbNumDays.IsChecked();
+ aInfo.AutoStart = maStartHelper.IsAuto();
+ aInfo.AutoEnd = maEndHelper.IsAuto();
+
+ // get values and silently auto-correct them, if they are not valid
+ // TODO: error messages in OK event?
+ aInfo.Start = maStartHelper.GetValue();
+ aInfo.End = maEndHelper.GetValue();
+ sal_Int64 nNumDays = maEdNumDays.GetValue();
+ aInfo.Step = static_cast<double>( aInfo.DateValues ? nNumDays : 0L );
+ if( aInfo.End <= aInfo.Start )
+ aInfo.End = aInfo.Start + nNumDays;
+
+ return aInfo;
+}
+
+sal_Int32 ScDPDateGroupDlg::GetDatePart() const
+{
+ // return DAYS for special "number of days" mode
+ if( maRbNumDays.IsChecked() )
+ return com::sun::star::sheet::DataPilotFieldGroupBy::DAYS;
+
+ // return listbox contents for "units" mode
+ sal_Int32 nDatePart = 0;
+ for( ULONG nIdx = 0, nCount = maLbUnits.GetEntryCount(); nIdx < nCount; ++nIdx )
+ if( maLbUnits.IsChecked( static_cast< USHORT >( nIdx ) ) )
+ nDatePart |= spnDateParts[ nIdx ];
+ return nDatePart;
+}
+
+IMPL_LINK( ScDPDateGroupDlg, ClickHdl, RadioButton*, pButton )
+{
+ if( pButton == &maRbNumDays )
+ {
+ maLbUnits.Disable();
+ // enable and set focus to edit field on clicking "num of days" radio button
+ maEdNumDays.Enable();
+ maEdNumDays.GrabFocus();
+ maBtnOk.Enable();
+ }
+ else if( pButton == &maRbUnits )
+ {
+ maEdNumDays.Disable();
+ // enable and set focus to listbox on clicking "units" radio button
+ maLbUnits.Enable();
+ maLbUnits.GrabFocus();
+ // disable OK button if no date part selected
+ CheckHdl( &maLbUnits );
+ }
+ return 0;
+}
+
+IMPL_LINK( ScDPDateGroupDlg, CheckHdl, SvxCheckListBox*, pListBox )
+{
+ // enable/disable OK button on modifying check list box
+ if( pListBox == &maLbUnits )
+ maBtnOk.Enable( maLbUnits.GetCheckedEntryCount() > 0 );
+ return 0;
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/dpgroupdlg.hrc b/sc/source/ui/dbgui/dpgroupdlg.hrc
new file mode 100644
index 000000000000..5a4797489ddf
--- /dev/null
+++ b/sc/source/ui/dbgui/dpgroupdlg.hrc
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DPGROUPDLG_HRC
+#define SC_DPGROUPDLG_HRC
+
+#include "sc.hrc"
+
+// push buttons
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+// fixed lines
+#define FL_START 1
+#define FL_END 2
+#define FL_BY 3
+
+// radio buttons
+#define RB_AUTOSTART 1
+#define RB_MANSTART 2
+#define RB_AUTOEND 3
+#define RB_MANEND 4
+#define RB_NUMDAYS 5
+#define RB_UNITS 6
+
+// edit fields
+#define ED_START 1
+#define ED_END 2
+#define ED_BY 3
+#define ED_NUMDAYS 4
+
+// list boxes
+#define LB_UNITS 1
+
+// strings/string arrays
+#define STR_UNITS 1
+
+#endif
+
diff --git a/sc/source/ui/dbgui/dpgroupdlg.src b/sc/source/ui/dbgui/dpgroupdlg.src
new file mode 100644
index 000000000000..f9a5ac589af5
--- /dev/null
+++ b/sc/source/ui/dbgui/dpgroupdlg.src
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dpgroupdlg.hrc"
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_DPNUMGROUP
+{
+ Size = MAP_APPFONT ( 220 , 110 ) ;
+ HelpId = HID_SC_DPNUMGROUP ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Hide = TRUE ;
+ FixedLine FL_START
+ {
+ Pos = MAP_APPFONT ( 6, 3 ) ;
+ Size = MAP_APPFONT ( 152, 8 ) ;
+ Text [ en-US ] = "Start" ;
+ };
+ RadioButton RB_AUTOSTART
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Automatically" ;
+ };
+ RadioButton RB_MANSTART
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Manually at" ;
+ };
+ Edit ED_START
+ {
+ Pos = MAP_APPFONT ( 94 , 26 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ Border = TRUE ;
+ };
+ FixedLine FL_END
+ {
+ Pos = MAP_APPFONT ( 6 , 42 ) ;
+ Size = MAP_APPFONT ( 152 , 8 ) ;
+ Text [ en-US ] = "End" ;
+ };
+ RadioButton RB_AUTOEND
+ {
+ Pos = MAP_APPFONT ( 12 , 53 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "A~utomatically" ;
+ };
+ RadioButton RB_MANEND
+ {
+ Pos = MAP_APPFONT ( 12 , 67 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Ma~nually at" ;
+ };
+ Edit ED_END
+ {
+ Pos = MAP_APPFONT ( 94 , 65 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ Border = TRUE ;
+ };
+ FixedLine FL_BY
+ {
+ Pos = MAP_APPFONT ( 6 , 81 ) ;
+ Size = MAP_APPFONT ( 152 , 8 ) ;
+ Text [ en-US ] = "~Group by" ;
+ };
+ Edit ED_BY
+ {
+ Pos = MAP_APPFONT ( 94 , 92 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ Border = TRUE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 164 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 164 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 164 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Text [ en-US ] = "Grouping" ;
+} ;
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_DPDATEGROUP
+{
+ Size = MAP_APPFONT ( 220 , 180 ) ;
+ HelpId = HID_SC_DPDATEGROUP ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Hide = TRUE ;
+ FixedLine FL_START
+ {
+ Pos = MAP_APPFONT ( 6, 3 ) ;
+ Size = MAP_APPFONT ( 152, 8 ) ;
+ Text [ en-US ] = "Start" ;
+ };
+ RadioButton RB_AUTOSTART
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Automatically" ;
+ };
+ RadioButton RB_MANSTART
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Manually at" ;
+ };
+ DateField ED_START
+ {
+ Pos = MAP_APPFONT ( 94 , 26 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ Border = TRUE ;
+ };
+ FixedLine FL_END
+ {
+ Pos = MAP_APPFONT ( 6 , 42 ) ;
+ Size = MAP_APPFONT ( 152 , 8 ) ;
+ Text [ en-US ] = "End" ;
+ };
+ RadioButton RB_AUTOEND
+ {
+ Pos = MAP_APPFONT ( 12 , 53 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "A~utomatically" ;
+ };
+ RadioButton RB_MANEND
+ {
+ Pos = MAP_APPFONT ( 12 , 67 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Ma~nually at" ;
+ };
+ DateField ED_END
+ {
+ Pos = MAP_APPFONT ( 94 , 65 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ Border = TRUE ;
+ };
+ FixedLine FL_BY
+ {
+ Pos = MAP_APPFONT ( 6 , 81 ) ;
+ Size = MAP_APPFONT ( 152 , 8 ) ;
+ Text [ en-US ] = "Group by" ;
+ };
+ RadioButton RB_NUMDAYS
+ {
+ Pos = MAP_APPFONT ( 12 , 94 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Number of ~days" ;
+ };
+ RadioButton RB_UNITS
+ {
+ Pos = MAP_APPFONT ( 12 , 110 ) ;
+ Size = MAP_APPFONT ( 80 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Intervals" ;
+ };
+ NumericField ED_NUMDAYS
+ {
+ Pos = MAP_APPFONT ( 94, 92 ) ;
+ Size = MAP_APPFONT ( 35, 12 ) ;
+ TabStop = TRUE ;
+ Border = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ Maximum = 32767 ;
+ SpinSize = 1 ;
+ };
+ Control LB_UNITS
+ {
+ Pos = MAP_APPFONT( 94, 110 );
+ Size = MAP_APPFONT( 58, 64 );
+ TabStop = TRUE;
+ Border = TRUE;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 164 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 164 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 164 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ StringArray STR_UNITS
+ {
+ ItemList [ en-US ] =
+ {
+ < "Seconds" ; Default ; > ;
+ < "Minutes" ; Default ; > ;
+ < "Hours" ; Default ; > ;
+ < "Days" ; Default ; > ;
+ < "Months" ; Default ; > ;
+ < "Quarters" ; Default ; > ;
+ < "Years" ; Default ; > ;
+ } ;
+ } ;
+ Text [ en-US ] = "Grouping" ;
+} ;
+
+// ----------------------------------------------------------------------------
+
diff --git a/sc/source/ui/dbgui/expftext.cxx b/sc/source/ui/dbgui/expftext.cxx
new file mode 100644
index 000000000000..405a18fcc004
--- /dev/null
+++ b/sc/source/ui/dbgui/expftext.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "expftext.hxx"
+#include <vcl/help.hxx>
+
+/*************************************************************************
+#* Member: ScExpandedFixedText Datum:18.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: MD_Test
+#*
+#* Funktion: Konstruktor der Klasse SvxCtrDial
+#*
+#* Input: Parent- Window, Resource ID
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+ScExpandedFixedText::ScExpandedFixedText( Window* pParent,
+ const ResId& rResId) :
+ FixedText( pParent, rResId )
+{
+
+}
+
+/*************************************************************************
+#* Member: RequestHelp Datum:18.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScExpandedFixedText
+#*
+#* Funktion: Die Methode wird gerufen, um Hilfe fuer das Fenster
+#* anzuzeigen. Zeigt das Fenster einen gekuerzten Text
+#* an, so wird selbiger in voller Laenge angezeigt.
+#*
+#* Input: HelpEvent
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScExpandedFixedText::RequestHelp(const HelpEvent& rEvt)
+{
+ String aTxtStr = GetText();
+ long nTxtWidth = GetTextWidth(aTxtStr);
+ if ( ( rEvt.GetMode() & HELPMODE_QUICK ) == HELPMODE_QUICK &&
+ nTxtWidth > GetSizePixel().Width())
+ {
+ Point aShowPoint = OutputToScreenPixel(Point(0,0));
+ long nTxtHeight = GetTextHeight();
+
+ Help::ShowQuickHelp( this,
+ Rectangle( aShowPoint, Size(nTxtWidth,nTxtHeight) ), aTxtStr,
+ QUICKHELP_TOP|QUICKHELP_LEFT );
+ }
+ else
+ {
+ FixedText::RequestHelp( rEvt );
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/dbgui/fieldwnd.cxx b/sc/source/ui/dbgui/fieldwnd.cxx
new file mode 100644
index 000000000000..d4b477cd4b33
--- /dev/null
+++ b/sc/source/ui/dbgui/fieldwnd.cxx
@@ -0,0 +1,776 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/virdev.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/help.hxx>
+#include <tools/debug.hxx>
+
+#include "fieldwnd.hxx"
+#include "pvlaydlg.hxx"
+#include "pvglob.hxx"
+#include "AccessibleDataPilotControl.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+
+const size_t INVALID_INDEX = static_cast< size_t >( -1 );
+
+//===================================================================
+
+ScDPFieldWindow::ScDPFieldWindow(
+ ScDPLayoutDlg* pDialog,
+ const ResId& rResId,
+ ScDPFieldType eFieldType,
+ FixedText* pFtFieldCaption ) :
+ Control( pDialog, rResId ),
+ pDlg( pDialog ),
+ pFtCaption( pFtFieldCaption ),
+ eType( eFieldType ),
+ nFieldSelected( 0 ),
+ pAccessible( NULL )
+{
+ Init();
+ if (eType != TYPE_SELECT && pFtCaption)
+ aName = MnemonicGenerator::EraseAllMnemonicChars( pFtCaption->GetText() );
+}
+
+ScDPFieldWindow::ScDPFieldWindow(
+ ScDPLayoutDlg* pDialog,
+ const ResId& rResId,
+ ScDPFieldType eFieldType,
+ const String& rName ) :
+ Control( pDialog, rResId ),
+ aName(rName),
+ pDlg( pDialog ),
+ pFtCaption( NULL ),
+ eType( eFieldType ),
+ nFieldSelected( 0 ),
+ pAccessible( NULL )
+{
+ Init();
+}
+
+void ScDPFieldWindow::Init()
+{
+ aWndRect = Rectangle( GetPosPixel(), GetSizePixel() );
+ nFieldSize = (eType == TYPE_SELECT) ? PAGE_SIZE : ((eType == TYPE_PAGE) ? MAX_PAGEFIELDS : MAX_FIELDS);
+
+ if( pFtCaption )
+ {
+ Size aWinSize( aWndRect.GetSize() );
+ Size aTextSize( GetTextWidth( pFtCaption->GetText() ), GetTextHeight() );
+ aTextPos.X() = (aWinSize.Width() - aTextSize.Width()) / 2;
+ aTextPos.Y() = (aWinSize.Height() - aTextSize.Height()) / 2;
+ }
+
+ GetStyleSettings();
+}
+
+__EXPORT ScDPFieldWindow::~ScDPFieldWindow()
+{
+ if (pAccessible)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->dispose();
+ }
+}
+
+//-------------------------------------------------------------------
+
+void ScDPFieldWindow::GetStyleSettings()
+{
+ const StyleSettings& rStyleSet = GetSettings().GetStyleSettings();
+ aFaceColor = rStyleSet.GetFaceColor();
+ aWinColor = rStyleSet.GetWindowColor();
+ aTextColor = rStyleSet.GetButtonTextColor();
+ aWinTextColor = rStyleSet.GetWindowTextColor();
+}
+
+//-------------------------------------------------------------------
+
+Point ScDPFieldWindow::GetFieldPosition( size_t nIndex ) const
+{
+ Point aPos;
+ switch( eType )
+ {
+ case TYPE_PAGE:
+ aPos.X() = OWIDTH * (nIndex % (MAX_PAGEFIELDS / 2));
+ aPos.Y() = OHEIGHT * (nIndex / (MAX_PAGEFIELDS / 2));
+ break;
+ case TYPE_COL:
+ aPos.X() = OWIDTH * (nIndex % (MAX_FIELDS / 2));
+ aPos.Y() = OHEIGHT * (nIndex / (MAX_FIELDS / 2));
+ break;
+ case TYPE_ROW:
+ case TYPE_DATA:
+ aPos.X() = 0;
+ aPos.Y() = OHEIGHT * nIndex;
+ break;
+ case TYPE_SELECT:
+ aPos.X() = (OWIDTH + SSPACE) * (nIndex / LINE_SIZE);
+ aPos.Y() = (OHEIGHT + SSPACE) * (nIndex % LINE_SIZE);
+ break;
+ }
+ return aPos;
+}
+
+Size ScDPFieldWindow::GetFieldSize() const
+{
+ return Size( (eType == TYPE_DATA) ? GetSizePixel().Width() : OWIDTH, OHEIGHT );
+}
+
+Point ScDPFieldWindow::GetLastPosition() const
+{
+ return OutputToScreenPixel( GetFieldPosition( nFieldSize - 1 ) );
+}
+
+bool ScDPFieldWindow::GetFieldIndex( const Point& rPos, size_t& rnIndex ) const
+{
+ rnIndex = INVALID_INDEX;
+ if( (rPos.X() >= 0) && (rPos.Y() >= 0) )
+ {
+ switch( eType )
+ {
+ case TYPE_ROW:
+ case TYPE_DATA:
+ rnIndex = rPos.Y() / OHEIGHT;
+ break;
+ case TYPE_PAGE:
+ {
+ size_t nRow = rPos.Y() / OHEIGHT;
+ size_t nCol = rPos.X() / OWIDTH;
+ rnIndex = nRow * MAX_PAGEFIELDS / 2 + nCol;
+ }
+ break;
+ case TYPE_COL:
+ {
+ size_t nRow = rPos.Y() / OHEIGHT;
+ size_t nCol = rPos.X() / OWIDTH;
+ rnIndex = nRow * MAX_FIELDS / 2 + nCol;
+ }
+ break;
+ case TYPE_SELECT:
+ {
+ size_t nRow = rPos.Y() / (OHEIGHT + SSPACE);
+ size_t nCol = rPos.X() / (OWIDTH + SSPACE);
+ // is not between controls?
+ if( (rPos.Y() % (OHEIGHT + SSPACE) < OHEIGHT) && (rPos.X() % (OWIDTH + SSPACE) < OWIDTH) )
+ rnIndex = nCol * LINE_SIZE + nRow;
+ }
+ break;
+ }
+ }
+ return IsValidIndex( rnIndex );
+}
+
+//-------------------------------------------------------------------
+
+void ScDPFieldWindow::DrawBackground( OutputDevice& rDev )
+{
+ Point aPos0;
+ Size aSize( GetSizePixel() );
+
+ if ( eType == TYPE_SELECT )
+ {
+ rDev.SetLineColor();
+ rDev.SetFillColor( aFaceColor );
+ rDev.DrawRect( Rectangle( aPos0, aSize ) );
+ }
+ else
+ {
+ rDev.SetLineColor( aWinTextColor );
+ rDev.SetFillColor( aWinColor );
+ rDev.DrawRect( Rectangle( aPos0, aSize ) );
+
+ rDev.SetTextColor( aWinTextColor );
+
+ /* Draw the caption text. This needs some special handling, because we
+ support hard line breaks here. This part will draw each line of the
+ text for itself. */
+
+ xub_StrLen nTokenCnt = GetText().GetTokenCount( '\n' );
+ long nY = (aSize.Height() - nTokenCnt * rDev.GetTextHeight()) / 2;
+ for( xub_StrLen nToken = 0, nStringIx = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aLine( GetText().GetToken( 0, '\n', nStringIx ) );
+ Point aLinePos( (aSize.Width() - rDev.GetCtrlTextWidth( aLine )) / 2, nY );
+ rDev.DrawCtrlText( aLinePos, aLine );
+ nY += rDev.GetTextHeight();
+ }
+ }
+}
+
+void ScDPFieldWindow::DrawField(
+ OutputDevice& rDev, const Rectangle& rRect, FieldString& rText, bool bFocus )
+{
+ VirtualDevice aVirDev( rDev );
+ // #i97623# VirtualDevice is always LTR while other windows derive direction from parent
+ aVirDev.EnableRTL( IsRTLEnabled() );
+
+ String aText = rText.first;
+ Size aDevSize( rRect.GetSize() );
+ long nWidth = aDevSize.Width();
+ long nHeight = aDevSize.Height();
+ long nLabelWidth = rDev.GetTextWidth( aText );
+ long nLabelHeight = rDev.GetTextHeight();
+
+ // #i31600# if text is too long, cut and add ellipsis
+ rText.second = nLabelWidth + 6 <= nWidth;
+ if( !rText.second )
+ {
+ xub_StrLen nMinLen = 0;
+ xub_StrLen nMaxLen = aText.Len();
+ bool bFits = false;
+ do
+ {
+ xub_StrLen nCurrLen = (nMinLen + nMaxLen) / 2;
+ aText = String( rText.first, 0, nCurrLen ).AppendAscii( "..." );
+ nLabelWidth = rDev.GetTextWidth( aText );
+ bFits = nLabelWidth + 6 <= nWidth;
+ (bFits ? nMinLen : nMaxLen) = nCurrLen;
+ }
+ while( !bFits || (nMinLen + 1 < nMaxLen) );
+ }
+ Point aLabelPos( (nWidth - nLabelWidth) / 2, ::std::max< long >( (nHeight - nLabelHeight) / 2, 3 ) );
+
+ aVirDev.SetOutputSizePixel( aDevSize );
+ aVirDev.SetFont( rDev.GetFont() );
+ DecorationView aDecoView( &aVirDev );
+ aDecoView.DrawButton( Rectangle( Point( 0, 0 ), aDevSize ), bFocus ? BUTTON_DRAW_DEFAULT : 0 );
+ aVirDev.SetTextColor( aTextColor );
+ aVirDev.DrawText( aLabelPos, aText );
+ rDev.DrawBitmap( rRect.TopLeft(), aVirDev.GetBitmap( Point( 0, 0 ), aDevSize ) );
+}
+
+void ScDPFieldWindow::Redraw()
+{
+ VirtualDevice aVirDev;
+ // #i97623# VirtualDevice is always LTR while other windows derive direction from parent
+ aVirDev.EnableRTL( IsRTLEnabled() );
+ aVirDev.SetMapMode( MAP_PIXEL );
+
+ Point aPos0;
+ Size aSize( GetSizePixel() );
+ Font aFont( GetFont() ); // Font vom Window
+ aFont.SetTransparent( TRUE );
+ aVirDev.SetFont( aFont );
+ aVirDev.SetOutputSizePixel( aSize );
+
+ DrawBackground( aVirDev );
+
+ if( !aFieldArr.empty() && (nFieldSelected >= aFieldArr.size()) )
+ nFieldSelected = aFieldArr.size() - 1;
+ Rectangle aFieldRect( aPos0, GetFieldSize() );
+ for( size_t nIx = 0; nIx < aFieldArr.size(); ++nIx )
+ {
+ aFieldRect.SetPos( GetFieldPosition( nIx ) );
+ bool bFocus = HasFocus() && (nIx == nFieldSelected);
+ DrawField( aVirDev, aFieldRect, aFieldArr[ nIx ], bFocus );
+ }
+ DrawBitmap( aPos0, aVirDev.GetBitmap( aPos0, aSize ) );
+
+ if( HasFocus() && (nFieldSelected < aFieldArr.size()) )
+ {
+ long nFieldWidth = aFieldRect.GetWidth();
+ long nSelectionWidth = Min( GetTextWidth( aFieldArr[ nFieldSelected ].first ) + 4, nFieldWidth - 6 );
+ Rectangle aSelection(
+ GetFieldPosition( nFieldSelected ) + Point( (nFieldWidth - nSelectionWidth) / 2, 3 ),
+ Size( nSelectionWidth, aFieldRect.GetHeight() - 6 ) );
+ InvertTracking( aSelection, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ }
+
+ UpdateStyle();
+}
+
+void ScDPFieldWindow::UpdateStyle()
+{
+ WinBits nMask = ~(WB_TABSTOP | WB_NOTABSTOP);
+ SetStyle( (GetStyle() & nMask) | (IsEmpty() ? WB_NOTABSTOP : WB_TABSTOP) );
+}
+
+//-------------------------------------------------------------------
+
+bool ScDPFieldWindow::IsValidIndex( size_t nIndex ) const
+{
+ return nIndex < nFieldSize;
+}
+
+bool ScDPFieldWindow::IsExistingIndex( size_t nIndex ) const
+{
+ return nIndex < aFieldArr.size();
+}
+
+bool ScDPFieldWindow::IsShortenedText( size_t nIndex ) const
+{
+ return (nIndex < aFieldArr.size()) && !aFieldArr[ nIndex ].second;
+}
+
+size_t ScDPFieldWindow::CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const
+{
+ size_t nNewField = nFieldSelected;
+ switch( eType )
+ {
+ case TYPE_PAGE:
+ nNewField += static_cast<SCsCOLROW>(nDX) + nDY * MAX_PAGEFIELDS / 2;
+ break;
+ case TYPE_COL:
+ nNewField += static_cast<SCsCOLROW>(nDX) + nDY * MAX_FIELDS / 2;
+ break;
+ case TYPE_ROW:
+ case TYPE_DATA:
+ nNewField += nDY;
+ break;
+ case TYPE_SELECT:
+ nNewField += static_cast<SCsCOLROW>(nDX) * LINE_SIZE + nDY;
+ break;
+ }
+
+ return IsExistingIndex( nNewField ) ? nNewField : nFieldSelected;
+}
+
+void ScDPFieldWindow::SetSelection( size_t nIndex )
+{
+ if( !aFieldArr.empty() )
+ {
+ if( nFieldSelected >= aFieldArr.size() )
+ nFieldSelected = aFieldArr.size() - 1;
+ if( nFieldSelected != nIndex )
+ {
+ sal_Int32 nOldSelected(nFieldSelected);
+ nFieldSelected = nIndex;
+ Redraw();
+
+ if (pAccessible && HasFocus())
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->FieldFocusChange(nOldSelected, nFieldSelected);
+ else
+ pAccessible = NULL;
+ }
+ }
+ }
+}
+
+void ScDPFieldWindow::SetSelectionHome()
+{
+ if( !aFieldArr.empty() )
+ {
+ if( eType == TYPE_SELECT )
+ pDlg->NotifyMoveSlider( KEY_HOME );
+ SetSelection( 0 );
+ }
+}
+
+void ScDPFieldWindow::SetSelectionEnd()
+{
+ if( !aFieldArr.empty() )
+ {
+ if( eType == TYPE_SELECT )
+ pDlg->NotifyMoveSlider( KEY_END );
+ SetSelection( aFieldArr.size() - 1 );
+ }
+}
+
+void ScDPFieldWindow::MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY )
+{
+ size_t nNewIndex = CalcNewFieldIndex( nDX, nDY );
+ if( (eType == TYPE_SELECT) && (nNewIndex == nFieldSelected) )
+ {
+ if( pDlg->NotifyMoveSlider( nKeyCode ) )
+ {
+ switch( nKeyCode )
+ {
+ case KEY_UP: nNewIndex += (LINE_SIZE - 1); break;
+ case KEY_DOWN: nNewIndex -= (LINE_SIZE - 1); break;
+ }
+ }
+ }
+ SetSelection( nNewIndex );
+}
+
+void ScDPFieldWindow::ModifySelectionOffset( long nOffsetDiff )
+{
+ nFieldSelected -= nOffsetDiff;
+ Redraw();
+}
+
+void ScDPFieldWindow::SelectNext()
+{
+ if( eType == TYPE_SELECT )
+ MoveSelection( KEY_DOWN, 0, 1 );
+}
+
+void ScDPFieldWindow::GrabFocusWithSel( size_t nIndex )
+{
+ SetSelection( nIndex );
+ if( !HasFocus() )
+ GrabFocus();
+}
+
+void ScDPFieldWindow::MoveField( size_t nDestIndex )
+{
+ if( nDestIndex != nFieldSelected )
+ {
+ // "recycle" existing functionality
+ pDlg->NotifyMouseButtonDown( eType, nFieldSelected );
+ pDlg->NotifyMouseButtonUp( OutputToScreenPixel( GetFieldPosition( nDestIndex ) ) );
+ }
+}
+
+void ScDPFieldWindow::MoveFieldRel( SCsCOL nDX, SCsROW nDY )
+{
+ MoveField( CalcNewFieldIndex( nDX, nDY ) );
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScDPFieldWindow::Paint( const Rectangle& /* rRect */ )
+{
+ // #124828# hiding the caption is now done from StateChanged
+ Redraw();
+}
+
+void ScDPFieldWindow::UseMnemonic()
+{
+ // Now the FixedText has its mnemonic char. Grab the text and hide the
+ // FixedText to be able to handle tabstop and mnemonics separately.
+ if( pFtCaption )
+ {
+ SetText( pFtCaption->GetText() );
+ pFtCaption->Hide();
+ }
+
+ // after reading the mnemonics, tab stop style bits can be updated
+ UpdateStyle();
+}
+
+void __EXPORT ScDPFieldWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ GetStyleSettings();
+ Redraw();
+ }
+ Control::DataChanged( rDCEvt );
+}
+
+void __EXPORT ScDPFieldWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if( rMEvt.IsLeft() )
+ {
+ size_t nIndex = 0;
+ if( GetFieldIndex( rMEvt.GetPosPixel(), nIndex ) && IsExistingIndex( nIndex ) )
+ {
+ GrabFocusWithSel( nIndex );
+
+ if( rMEvt.GetClicks() == 1 )
+ {
+ PointerStyle ePtr = pDlg->NotifyMouseButtonDown( eType, nIndex );
+ CaptureMouse();
+ SetPointer( Pointer( ePtr ) );
+ }
+ else
+ pDlg->NotifyDoubleClick( eType, nIndex );
+ }
+ }
+}
+
+void __EXPORT ScDPFieldWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if( rMEvt.IsLeft() )
+ {
+ if( rMEvt.GetClicks() == 1 )
+ {
+ pDlg->NotifyMouseButtonUp( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
+ SetPointer( Pointer( POINTER_ARROW ) );
+ }
+
+ if( IsMouseCaptured() )
+ ReleaseMouse();
+ }
+}
+
+void __EXPORT ScDPFieldWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if( IsMouseCaptured() )
+ {
+ PointerStyle ePtr = pDlg->NotifyMouseMove( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
+ SetPointer( Pointer( ePtr ) );
+ }
+ size_t nIndex = 0;
+ if( GetFieldIndex( rMEvt.GetPosPixel(), nIndex ) && IsShortenedText( nIndex ) )
+ {
+ Point aPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
+ Rectangle aRect( aPos, GetSizePixel() );
+ String aHelpText = GetFieldText(nIndex);
+ Help::ShowQuickHelp( this, aRect, aHelpText );
+ }
+}
+
+void __EXPORT ScDPFieldWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ USHORT nCode = rKeyCode.GetCode();
+ BOOL bKeyEvaluated = FALSE;
+
+ if( rKeyCode.IsMod1() && (eType != TYPE_SELECT) )
+ {
+ bKeyEvaluated = TRUE;
+ switch( nCode )
+ {
+ case KEY_UP: MoveFieldRel( 0, -1 ); break;
+ case KEY_DOWN: MoveFieldRel( 0, 1 ); break;
+ case KEY_LEFT: MoveFieldRel( -1, 0 ); break;
+ case KEY_RIGHT: MoveFieldRel( 1, 0 ); break;
+ case KEY_HOME: MoveField( 0 ); break;
+ case KEY_END: MoveField( aFieldArr.size() - 1 ); break;
+ default: bKeyEvaluated = FALSE;
+ }
+ }
+ else
+ {
+ bKeyEvaluated = TRUE;
+ switch( nCode )
+ {
+ case KEY_UP: MoveSelection( nCode, 0, -1 ); break;
+ case KEY_DOWN: MoveSelection( nCode, 0, 1 ); break;
+ case KEY_LEFT: MoveSelection( nCode, -1, 0 ); break;
+ case KEY_RIGHT: MoveSelection( nCode, 1, 0 ); break;
+ case KEY_HOME: SetSelectionHome(); break;
+ case KEY_END: SetSelectionEnd(); break;
+ case KEY_DELETE:
+ pDlg->NotifyRemoveField( eType, nFieldSelected ); break;
+ default: bKeyEvaluated = FALSE;
+ }
+ }
+
+ if( !bKeyEvaluated )
+ Control::KeyInput( rKEvt );
+}
+
+void __EXPORT ScDPFieldWindow::GetFocus()
+{
+ Control::GetFocus();
+ Redraw();
+ if( GetGetFocusFlags() & GETFOCUS_MNEMONIC ) // move field on shortcut
+ pDlg->NotifyMoveField( eType );
+ else // else change focus
+ pDlg->NotifyFieldFocus( eType, TRUE );
+
+ if (pAccessible)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->GotFocus();
+ else
+ pAccessible = NULL;
+ }
+}
+
+void __EXPORT ScDPFieldWindow::LoseFocus()
+{
+ Control::LoseFocus();
+ Redraw();
+ pDlg->NotifyFieldFocus( eType, FALSE );
+
+ if (pAccessible)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->LostFocus();
+ else
+ pAccessible = NULL;
+ }
+}
+
+//-------------------------------------------------------------------
+
+void ScDPFieldWindow::AddField( const String& rText, size_t nNewIndex )
+{
+ DBG_ASSERT( nNewIndex == aFieldArr.size(), "ScDPFieldWindow::AddField - invalid index" );
+ if( IsValidIndex( nNewIndex ) )
+ {
+ aFieldArr.push_back( FieldString( rText, true ) );
+ if (pAccessible)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->AddField(nNewIndex);
+ else
+ pAccessible = NULL;
+ }
+ }
+}
+
+void ScDPFieldWindow::DelField( size_t nDelIndex )
+{
+ if( IsExistingIndex( nDelIndex ) )
+ {
+ if (pAccessible) // before decrement fieldcount
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->RemoveField(nDelIndex);
+ else
+ pAccessible = NULL;
+ }
+ aFieldArr.erase( aFieldArr.begin() + nDelIndex );
+ Redraw();
+ }
+}
+
+void ScDPFieldWindow::ClearFields()
+{
+ if( eType == TYPE_SELECT || eType == TYPE_PAGE || eType == TYPE_COL || eType == TYPE_ROW || eType == TYPE_DATA)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (!xTempAcc.is() && pAccessible)
+ pAccessible = NULL;
+ if (pAccessible)
+ for( size_t nIdx = aFieldArr.size(); nIdx > 0; --nIdx )
+ pAccessible->RemoveField( nIdx - 1 );
+
+ aFieldArr.clear();
+ }
+}
+
+void ScDPFieldWindow::SetFieldText( const String& rText, size_t nIndex )
+{
+ if( IsExistingIndex( nIndex ) )
+ {
+ aFieldArr[ nIndex ] = FieldString( rText, true );
+ Redraw();
+
+ if (pAccessible)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->FieldNameChange(nIndex);
+ else
+ pAccessible = NULL;
+ }
+ }
+}
+
+const String& ScDPFieldWindow::GetFieldText( size_t nIndex ) const
+{
+ if( IsExistingIndex( nIndex ) )
+ return aFieldArr[ nIndex ].first;
+ return EMPTY_STRING;
+}
+
+//-------------------------------------------------------------------
+
+bool ScDPFieldWindow::AddField( const String& rText, const Point& rPos, size_t& rnIndex )
+{
+ if ( aFieldArr.size() == nFieldSize )
+ return FALSE;
+
+ size_t nNewIndex = 0;
+ if( GetFieldIndex( rPos, nNewIndex ) )
+ {
+ if( nNewIndex > aFieldArr.size() )
+ nNewIndex = aFieldArr.size();
+
+ aFieldArr.insert( aFieldArr.begin() + nNewIndex, FieldString( rText, true ) );
+ nFieldSelected = nNewIndex;
+ Redraw();
+ rnIndex = nNewIndex;
+
+ if (pAccessible)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (xTempAcc.is())
+ pAccessible->AddField(nNewIndex);
+ else
+ pAccessible = NULL;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void ScDPFieldWindow::GetExistingIndex( const Point& rPos, size_t& rnIndex )
+{
+ if( !aFieldArr.empty() && (eType != TYPE_SELECT) && GetFieldIndex( rPos, rnIndex ) )
+ {
+ if( rnIndex >= aFieldArr.size() )
+ rnIndex = aFieldArr.size() - 1;
+ }
+ else
+ rnIndex = 0;
+}
+
+String ScDPFieldWindow::GetDescription() const
+{
+ String sDescription;
+ switch( eType )
+ {
+ case TYPE_COL:
+ sDescription = ScResId(STR_ACC_DATAPILOT_COL_DESCR);
+ break;
+ case TYPE_ROW:
+ sDescription = ScResId(STR_ACC_DATAPILOT_ROW_DESCR);
+ break;
+ case TYPE_DATA:
+ sDescription = ScResId(STR_ACC_DATAPILOT_DATA_DESCR);
+ break;
+ case TYPE_SELECT:
+ sDescription = ScResId(STR_ACC_DATAPILOT_SEL_DESCR);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return sDescription;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScDPFieldWindow::CreateAccessible()
+{
+ pAccessible =
+ new ScAccessibleDataPilotControl(GetAccessibleParentWindow()->GetAccessible(), this);
+
+ com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xReturn = pAccessible;
+
+ pAccessible->Init();
+ xAccessible = xReturn;
+
+ return xReturn;
+}
+
+//===================================================================
+
diff --git a/sc/source/ui/dbgui/filtdlg.cxx b/sc/source/ui/dbgui/filtdlg.cxx
new file mode 100644
index 000000000000..b5dd2f3242c2
--- /dev/null
+++ b/sc/source/ui/dbgui/filtdlg.cxx
@@ -0,0 +1,1186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+#include <rangelst.hxx>
+#include <sfx2/dispatch.hxx>
+#include <vcl/waitobj.hxx>
+
+#include "uiitems.hxx"
+#include "dbcolect.hxx"
+#include "reffact.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+
+#include "foptmgr.hxx"
+
+#include "globstr.hrc"
+#include "filter.hrc"
+
+#define _FILTDLG_CXX
+#include "filtdlg.hxx"
+#undef _FILTDLG_CXX
+#include <vcl/msgbox.hxx>
+
+// DEFINE --------------------------------------------------------------------
+
+#define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK), \
+ ScGlobal::GetRscString(rid) ).Execute()
+
+
+//============================================================================
+// class ScFilterDlg
+
+//----------------------------------------------------------------------------
+
+ScFilterDlg::ScFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_FILTER ),
+ //
+ aFlCriteria ( this, ScResId( FL_CRITERIA ) ),
+ aLbConnect1 ( this, ScResId( LB_OP1 ) ),
+ aLbField1 ( this, ScResId( LB_FIELD1 ) ),
+ aLbCond1 ( this, ScResId( LB_COND1 ) ),
+ aEdVal1 ( this, ScResId( ED_VAL1 ) ),
+ aLbConnect2 ( this, ScResId( LB_OP2 ) ),
+ aLbField2 ( this, ScResId( LB_FIELD2 ) ),
+ aLbCond2 ( this, ScResId( LB_COND2 ) ),
+ aEdVal2 ( this, ScResId( ED_VAL2 ) ),
+ aLbConnect3 ( this, ScResId( LB_OP3 ) ),
+ aLbField3 ( this, ScResId( LB_FIELD3 ) ),
+ aLbCond3 ( this, ScResId( LB_COND3 ) ),
+ aEdVal3 ( this, ScResId( ED_VAL3 ) ),
+ aLbConnect4 ( this, ScResId( LB_OP4 ) ),
+ aLbField4 ( this, ScResId( LB_FIELD4 ) ),
+ aLbCond4 ( this, ScResId( LB_COND4 ) ),
+ aEdVal4 ( this, ScResId( ED_VAL4 ) ),
+ aFtConnect ( this, ScResId( FT_OP ) ),
+ aFtField ( this, ScResId( FT_FIELD ) ),
+ aFtCond ( this, ScResId( FT_COND ) ),
+ aFtVal ( this, ScResId( FT_VAL ) ),
+ aFlSeparator ( this, ScResId( FL_SEPARATOR ) ),
+ aScrollBar ( this, ScResId( LB_SCROLL ) ),
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ _INIT_COMMON_FILTER_RSCOBJS
+ aStrEmpty ( ScResId( SCSTR_EMPTY ) ),
+ aStrNotEmpty ( ScResId( SCSTR_NOTEMPTY ) ),
+ aStrRow ( ScResId( SCSTR_ROW ) ),
+ aStrColumn ( ScResId( SCSTR_COLUMN ) ),
+ //
+ pOptionsMgr ( NULL ),
+ nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
+ theQueryData ( ((const ScQueryItem&)
+ rArgSet.Get( nWhichQuery )).GetQueryData() ),
+ pOutItem ( NULL ),
+ pViewData ( NULL ),
+ pDoc ( NULL ),
+ nSrcTab ( 0 ),
+ nFieldCount ( 0 ),
+ bRefInputMode ( FALSE ),
+ pTimer ( NULL )
+{
+ for (USHORT i=0; i<=MAXCOL; i++)
+ pEntryLists[i] = NULL;
+ for (SCSIZE i=0;i<MAXQUERY;i++)
+ {
+ bRefreshExceptQuery[i]=FALSE;
+ }
+ aBtnMore.SetMoreText( String(ScResId( SCSTR_MOREBTN_MOREOPTIONS )) );
+ aBtnMore.SetLessText( String(ScResId( SCSTR_MOREBTN_FEWEROPTIONS )) );
+ Init( rArgSet );
+ FreeResource();
+
+ // Hack: RefInput-Kontrolle
+ pTimer = new Timer;
+ pTimer->SetTimeout( 50 ); // 50ms warten
+ pTimer->SetTimeoutHdl( LINK( this, ScFilterDlg, TimeOutHdl ) );
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScFilterDlg::~ScFilterDlg()
+{
+ for (USHORT i=0; i<=MAXCOL; i++)
+ delete pEntryLists[i];
+
+ delete pOptionsMgr;
+ delete pOutItem;
+
+ // Hack: RefInput-Kontrolle
+ pTimer->Stop();
+ delete pTimer;
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScFilterDlg::Init( const SfxItemSet& rArgSet )
+{
+ const ScQueryItem& rQueryItem = (const ScQueryItem&)
+ rArgSet.Get( nWhichQuery );
+
+ aBtnOk.SetClickHdl ( LINK( this, ScFilterDlg, EndDlgHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScFilterDlg, EndDlgHdl ) );
+ aBtnMore.SetClickHdl ( LINK( this, ScFilterDlg, MoreClickHdl ) );
+ aBtnHeader.SetClickHdl ( LINK( this, ScFilterDlg, CheckBoxHdl ) );
+ aBtnCase.SetClickHdl ( LINK( this, ScFilterDlg, CheckBoxHdl ) );
+ //
+ aLbField1.SetSelectHdl ( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbField2.SetSelectHdl ( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbField3.SetSelectHdl ( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbField4.SetSelectHdl ( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbConnect1.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbConnect2.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbConnect3.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbConnect4.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+
+ aLbCond1.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbCond2.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbCond3.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+ aLbCond4.SetSelectHdl( LINK( this, ScFilterDlg, LbSelectHdl ) );
+
+ pViewData = rQueryItem.GetViewData();
+ pDoc = pViewData ? pViewData->GetDocument() : NULL;
+ nSrcTab = pViewData ? pViewData->GetTabNo() : static_cast<SCTAB>(0);
+
+ // fuer leichteren Zugriff:
+ aFieldLbArr [0] = &aLbField1;
+ aFieldLbArr [1] = &aLbField2;
+ aFieldLbArr [2] = &aLbField3;
+ aFieldLbArr [3] = &aLbField4;
+ aValueEdArr [0] = &aEdVal1;
+ aValueEdArr [1] = &aEdVal2;
+ aValueEdArr [2] = &aEdVal3;
+ aValueEdArr [3] = &aEdVal4;
+ aCondLbArr [0] = &aLbCond1;
+ aCondLbArr [1] = &aLbCond2;
+ aCondLbArr [2] = &aLbCond3;
+ aCondLbArr [3] = &aLbCond4;
+ aConnLbArr [0] = &aLbConnect1;
+ aConnLbArr [1] = &aLbConnect2;
+ aConnLbArr [2] = &aLbConnect3;
+ aConnLbArr [3] = &aLbConnect4;
+
+ // Optionen initialisieren lassen:
+
+ pOptionsMgr = new ScFilterOptionsMgr(
+ this,
+ pViewData,
+ theQueryData,
+ aBtnMore,
+ aBtnCase,
+ aBtnRegExp,
+ aBtnHeader,
+ aBtnUnique,
+ aBtnCopyResult,
+ aBtnDestPers,
+ aLbCopyArea,
+ aEdCopyArea,
+ aRbCopyArea,
+ aFtDbAreaLabel,
+ aFtDbArea,
+ aFlOptions,
+ aStrNoName,
+ aStrUndefined );
+
+ // Feldlisten einlesen und Eintraege selektieren:
+
+ FillFieldLists();
+
+ for ( SCSIZE i=0; i<4; i++ )
+ {
+ String aValStr;
+ USHORT nCondPos = 0;
+ USHORT nFieldSelPos = 0;
+
+ ScQueryEntry& rEntry = theQueryData.GetEntry(i);
+ if ( rEntry.bDoQuery )
+ {
+ nCondPos = (USHORT)rEntry.eOp;
+ nFieldSelPos = GetFieldSelPos( static_cast<SCCOL>(rEntry.nField) );
+ if ( rEntry.nVal == SC_EMPTYFIELDS && !rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING )
+ {
+ aValStr = aStrEmpty;
+ aCondLbArr[i]->Disable();
+ }
+ else if ( rEntry.nVal == SC_NONEMPTYFIELDS && !rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING )
+ {
+ aValStr = aStrNotEmpty;
+ aCondLbArr[i]->Disable();
+ }
+ else
+ aValStr = *rEntry.pStr;
+ }
+ else if ( i == 0 )
+ {
+ nFieldSelPos = GetFieldSelPos( pViewData->GetCurX() );
+ rEntry.nField = nFieldSelPos ? (theQueryData.nCol1 +
+ static_cast<SCCOL>(nFieldSelPos) - 1) : static_cast<SCCOL>(0);
+ rEntry.bDoQuery=TRUE;
+ bRefreshExceptQuery[i]=TRUE;
+
+ }
+ aFieldLbArr[i]->SelectEntryPos( nFieldSelPos );
+ aCondLbArr [i]->SelectEntryPos( nCondPos );
+ aValueEdArr[i]->SetText( aValStr );
+ aValueEdArr[i]->SetModifyHdl( LINK( this, ScFilterDlg, ValModifyHdl ) );
+ UpdateValueList( static_cast<USHORT>(i+1) );
+ }
+
+ aScrollBar.SetEndScrollHdl( LINK( this, ScFilterDlg, ScrollHdl ) );
+ aScrollBar.SetScrollHdl( LINK( this, ScFilterDlg, ScrollHdl ) );
+
+ aScrollBar.SetRange( Range( 0, 4 ) );
+ aScrollBar.SetLineSize( 1 );
+ aLbConnect1.Hide();
+ // Disable/Enable Logik:
+
+ (aLbField1.GetSelectEntryPos() != 0)
+ && (aLbField2.GetSelectEntryPos() != 0)
+ ? aLbConnect2.SelectEntryPos( (USHORT)theQueryData.GetEntry(1).eConnect )
+ : aLbConnect2.SetNoSelection();
+
+ (aLbField2.GetSelectEntryPos() != 0)
+ && (aLbField3.GetSelectEntryPos() != 0)
+ ? aLbConnect3.SelectEntryPos( (USHORT)theQueryData.GetEntry(2).eConnect )
+ : aLbConnect3.SetNoSelection();
+
+ (aLbField3.GetSelectEntryPos() != 0)
+ && (aLbField4.GetSelectEntryPos() != 0)
+ ? aLbConnect4.SelectEntryPos( (USHORT)theQueryData.GetEntry(3).eConnect )
+ : aLbConnect4.SetNoSelection();
+ if ( aLbField1.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect2.Disable();
+ aLbField2.Disable();
+ aLbCond2.Disable();
+ aEdVal2.Disable();
+ }
+ else if ( aLbConnect2.GetSelectEntryCount() == 0 )
+ {
+ aLbField2.Disable();
+ aLbCond2.Disable();
+ aEdVal2.Disable();
+ }
+
+ if ( aLbField2.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect3.Disable();
+ aLbField3.Disable();
+ aLbCond3.Disable();
+ aEdVal3.Disable();
+ }
+ else if ( aLbConnect3.GetSelectEntryCount() == 0 )
+ {
+ aLbField3.Disable();
+ aLbCond3.Disable();
+ aEdVal3.Disable();
+ }
+ if ( aLbField3.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect4.Disable();
+ aLbField4.Disable();
+ aLbCond4.Disable();
+ aEdVal4.Disable();
+ }
+ else if ( aLbConnect4.GetSelectEntryCount() == 0 )
+ {
+ aLbField4.Disable();
+ aLbCond4.Disable();
+ aEdVal4.Disable();
+ }
+
+ if(pDoc!=NULL &&
+ pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable();
+ // Modal-Modus einschalten
+// SetDispatcherLock( TRUE );
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+// SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScFilterDlg::Close()
+{
+ if (pViewData)
+ pViewData->GetDocShell()->CancelAutoDBRange();
+
+ return DoClose( ScFilterDlgWrapper::GetChildWindowId() );
+}
+
+
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Edit angezeigt wird.
+
+void ScFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( bRefInputMode ) // Nur moeglich, wenn im Referenz-Editmodus
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( &aEdCopyArea );
+ String aRefStr;
+ rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, pDocP->GetAddressConvention() );
+ aEdCopyArea.SetRefString( aRefStr );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScFilterDlg::SetActive()
+{
+ if ( bRefInputMode )
+ {
+ aEdCopyArea.GrabFocus();
+ if ( aEdCopyArea.GetModifyHdl().IsSet() )
+ ((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea );
+ }
+ else
+ GrabFocus();
+
+ RefInputDone();
+}
+
+//----------------------------------------------------------------------------
+
+void ScFilterDlg::FillFieldLists()
+{
+ aLbField1.Clear();
+ aLbField2.Clear();
+ aLbField3.Clear();
+ aLbField4.Clear();
+ aLbField1.InsertEntry( aStrNone, 0 );
+ aLbField2.InsertEntry( aStrNone, 0 );
+ aLbField3.InsertEntry( aStrNone, 0 );
+ aLbField4.InsertEntry( aStrNone, 0 );
+
+ if ( pDoc )
+ {
+ String aFieldName;
+ SCTAB nTab = nSrcTab;
+ SCCOL nFirstCol = theQueryData.nCol1;
+ SCROW nFirstRow = theQueryData.nRow1;
+ SCCOL nMaxCol = theQueryData.nCol2;
+ SCCOL col = 0;
+ USHORT i=1;
+
+ for ( col=nFirstCol; col<=nMaxCol; col++ )
+ {
+ pDoc->GetString( col, nFirstRow, nTab, aFieldName );
+ if ( !aBtnHeader.IsChecked() || (aFieldName.Len() == 0) )
+ {
+ aFieldName = aStrColumn;
+ aFieldName += ' ';
+ aFieldName += ScColToAlpha( col );
+ }
+ aLbField1.InsertEntry( aFieldName, i );
+ aLbField2.InsertEntry( aFieldName, i );
+ aLbField3.InsertEntry( aFieldName, i );
+ aLbField4.InsertEntry( aFieldName, i );
+ i++;
+ }
+ nFieldCount = i;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScFilterDlg::UpdateValueList( USHORT nList )
+{
+ if ( pDoc && nList>0 && nList<=4 )
+ {
+ ComboBox* pValList = aValueEdArr[nList-1];
+ USHORT nFieldSelPos = aFieldLbArr[nList-1]->GetSelectEntryPos();
+ USHORT nListPos = 0;
+ String aCurValue = pValList->GetText();
+
+ pValList->Clear();
+ pValList->InsertEntry( aStrNotEmpty, 0 );
+ pValList->InsertEntry( aStrEmpty, 1 );
+ nListPos = 2;
+
+ if ( nFieldSelPos )
+ {
+ WaitObject aWaiter( this ); // auch wenn nur die ListBox gefuellt wird
+
+ SCCOL nColumn = theQueryData.nCol1 + static_cast<SCCOL>(nFieldSelPos) - 1;
+ if (!pEntryLists[nColumn])
+ {
+ USHORT nOffset = GetSliderPos();
+ SCTAB nTab = nSrcTab;
+ SCROW nFirstRow = theQueryData.nRow1;
+ SCROW nLastRow = theQueryData.nRow2;
+ mbHasDates[nOffset+nList-1] = false;
+
+ // erstmal ohne die erste Zeile
+
+ pEntryLists[nColumn] = new TypedScStrCollection( 128, 128 );
+ pEntryLists[nColumn]->SetCaseSensitive( aBtnCase.IsChecked() );
+ pDoc->GetFilterEntriesArea( nColumn, nFirstRow+1, nLastRow,
+ nTab, *pEntryLists[nColumn], mbHasDates[nOffset+nList-1] );
+
+ // Eintrag fuer die erste Zeile
+ //! Eintrag (pHdrEntry) ohne Collection erzeugen?
+
+ nHeaderPos[nColumn] = USHRT_MAX;
+ TypedScStrCollection aHdrColl( 1, 1 );
+ bool bDummy = false;
+ pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nFirstRow,
+ nTab, aHdrColl, bDummy );
+ TypedStrData* pHdrEntry = aHdrColl[0];
+ if ( pHdrEntry )
+ {
+ TypedStrData* pNewEntry = new TypedStrData(*pHdrEntry);
+ if ( pEntryLists[nColumn]->Insert( pNewEntry ) )
+ {
+ nHeaderPos[nColumn] = pEntryLists[nColumn]->IndexOf( pNewEntry );
+ DBG_ASSERT( nHeaderPos[nColumn] != USHRT_MAX,
+ "Header-Eintrag nicht wiedergefunden" );
+ }
+ else
+ delete pNewEntry; // war schon drin
+ }
+ }
+
+ TypedScStrCollection* pColl = pEntryLists[nColumn];
+ USHORT nValueCount = pColl->GetCount();
+ if ( nValueCount > 0 )
+ {
+ for ( USHORT i=0; i<nValueCount; i++ )
+ {
+ pValList->InsertEntry( (*pColl)[i]->GetString(), nListPos );
+ nListPos++;
+ }
+ }
+ }
+ pValList->SetText( aCurValue );
+ }
+
+ UpdateHdrInValueList( nList );
+}
+
+void ScFilterDlg::UpdateHdrInValueList( USHORT nList )
+{
+ //! GetText / SetText ??
+
+ if ( pDoc && nList>0 && nList<=4 )
+ {
+ USHORT nFieldSelPos = aFieldLbArr[nList-1]->GetSelectEntryPos();
+ if ( nFieldSelPos )
+ {
+ SCCOL nColumn = theQueryData.nCol1 + static_cast<SCCOL>(nFieldSelPos) - 1;
+ if ( pEntryLists[nColumn] )
+ {
+ USHORT nPos = nHeaderPos[nColumn];
+ if ( nPos != USHRT_MAX )
+ {
+ ComboBox* pValList = aValueEdArr[nList-1];
+ USHORT nListPos = nPos + 2; // nach "leer" und "nicht leer"
+
+ TypedStrData* pHdrEntry = (*pEntryLists[nColumn])[nPos];
+ if ( pHdrEntry )
+ {
+ String aHdrStr = pHdrEntry->GetString();
+ BOOL bWasThere = ( pValList->GetEntry(nListPos) == aHdrStr );
+ BOOL bInclude = !aBtnHeader.IsChecked();
+
+ if (bInclude) // Eintrag aufnehmen
+ {
+ if (!bWasThere)
+ pValList->InsertEntry(aHdrStr, nListPos);
+ }
+ else // Eintrag weglassen
+ {
+ if (bWasThere)
+ pValList->RemoveEntry(nListPos);
+ }
+ }
+ else
+ {
+ DBG_ERROR("Eintag in Liste nicht gefunden");
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("Spalte noch nicht initialisiert");
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScFilterDlg::ClearValueList( USHORT nList )
+{
+ if ( nList>0 && nList<=4 )
+ {
+ ComboBox* pValList = aValueEdArr[nList-1];
+ pValList->Clear();
+ pValList->InsertEntry( aStrNotEmpty, 0 );
+ pValList->InsertEntry( aStrEmpty, 1 );
+ pValList->SetText( EMPTY_STRING );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+USHORT ScFilterDlg::GetFieldSelPos( SCCOL nField )
+{
+ if ( nField >= theQueryData.nCol1 && nField <= theQueryData.nCol2 )
+ return static_cast<USHORT>(nField - theQueryData.nCol1 + 1);
+ else
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+ScQueryItem* ScFilterDlg::GetOutputItem()
+{
+ ScAddress theCopyPos;
+ ScQueryParam theParam( theQueryData );
+ BOOL bCopyPosOk = FALSE;
+
+ if ( aBtnCopyResult.IsChecked() )
+ {
+ String theCopyStr( aEdCopyArea.GetText() );
+ xub_StrLen nColonPos = theCopyStr.Search( ':' );
+
+ if ( STRING_NOTFOUND != nColonPos )
+ theCopyStr.Erase( nColonPos );
+
+ USHORT nResult = theCopyPos.Parse( theCopyStr, pDoc, pDoc->GetAddressConvention() );
+ bCopyPosOk = ( SCA_VALID == (nResult & SCA_VALID) );
+ }
+
+ if ( aBtnCopyResult.IsChecked() && bCopyPosOk )
+ {
+ theParam.bInplace = FALSE;
+ theParam.nDestTab = theCopyPos.Tab();
+ theParam.nDestCol = theCopyPos.Col();
+ theParam.nDestRow = theCopyPos.Row();
+ }
+ else
+ {
+ theParam.bInplace = TRUE;
+ theParam.nDestTab = 0;
+ theParam.nDestCol = 0;
+ theParam.nDestRow = 0;
+ }
+
+ theParam.bHasHeader = aBtnHeader.IsChecked();
+ theParam.bByRow = TRUE;
+ theParam.bDuplicate = !aBtnUnique.IsChecked();
+ theParam.bCaseSens = aBtnCase.IsChecked();
+ theParam.bRegExp = aBtnRegExp.IsChecked();
+ theParam.bDestPers = aBtnDestPers.IsChecked();
+
+ // nur die drei eingestellten - alles andere zuruecksetzen
+
+ DELETEZ( pOutItem );
+ pOutItem = new ScQueryItem( nWhichQuery, &theParam );
+
+ return pOutItem;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScFilterDlg::IsRefInputMode() const
+{
+ return bRefInputMode;
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+// ========
+
+IMPL_LINK( ScFilterDlg, EndDlgHdl, Button*, pBtn )
+{
+ if ( pBtn == &aBtnOk )
+ {
+ BOOL bAreaInputOk = TRUE;
+
+ if ( aBtnCopyResult.IsChecked() )
+ {
+ if ( !pOptionsMgr->VerifyPosStr( aEdCopyArea.GetText() ) )
+ {
+ if ( !aBtnMore.GetState() )
+ aBtnMore.SetState( TRUE );
+
+ ERRORBOX( STR_INVALID_TABREF );
+ aEdCopyArea.GrabFocus();
+ bAreaInputOk = FALSE;
+ }
+ }
+
+ if ( bAreaInputOk )
+ {
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ GetOutputItem(), 0L, 0L );
+ Close();
+ }
+ }
+ else if ( pBtn == &aBtnCancel )
+ {
+ Close();
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterDlg, MoreClickHdl, MoreButton*, EMPTYARG )
+{
+ if ( aBtnMore.GetState() )
+ pTimer->Start();
+ else
+ {
+ pTimer->Stop();
+ bRefInputMode = FALSE;
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterDlg, TimeOutHdl, Timer*, _pTimer )
+{
+ // alle 50ms nachschauen, ob RefInputMode noch stimmt
+
+ if( _pTimer == pTimer && IsActive() )
+ bRefInputMode = (aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus());
+
+ if ( aBtnMore.GetState() )
+ pTimer->Start();
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterDlg, LbSelectHdl, ListBox*, pLb )
+{
+ /*
+ * Behandlung der Enable/Disable-Logik,
+ * abhaengig davon, welche ListBox angefasst wurde:
+ */
+ USHORT nOffset = GetSliderPos();
+
+ if ( pLb == &aLbConnect1 )
+ {
+ aLbField1.Enable();
+ aLbCond1.Enable();
+ aEdVal1.Enable();
+
+ USHORT nConnect1 = aLbConnect1.GetSelectEntryPos();
+ USHORT nQE = nOffset;
+ theQueryData.GetEntry(nQE).eConnect =(ScQueryConnect)nConnect1;
+ bRefreshExceptQuery[nQE]=TRUE;
+ }
+
+ else if ( pLb == &aLbConnect2 )
+ {
+ aLbField2.Enable();
+ aLbCond2.Enable();
+ aEdVal2.Enable();
+
+ USHORT nConnect2 = aLbConnect2.GetSelectEntryPos();
+ USHORT nQE = 1+nOffset;
+ theQueryData.GetEntry(nQE).eConnect =(ScQueryConnect)nConnect2;
+ bRefreshExceptQuery[nQE]=TRUE;
+ }
+ else if ( pLb == &aLbConnect3 )
+ {
+ aLbField3.Enable();
+ aLbCond3.Enable();
+ aEdVal3.Enable();
+
+ USHORT nConnect3 = aLbConnect3.GetSelectEntryPos();
+ USHORT nQE = 2+nOffset;
+ theQueryData.GetEntry(nQE).eConnect = (ScQueryConnect)nConnect3;
+ bRefreshExceptQuery[nQE]=TRUE;
+
+ }
+ else if ( pLb == &aLbConnect4 )
+ {
+ aLbField4.Enable();
+ aLbCond4.Enable();
+ aEdVal4.Enable();
+
+ USHORT nConnect4 = aLbConnect4.GetSelectEntryPos();
+ USHORT nQE = 3+nOffset;
+ theQueryData.GetEntry(nQE).eConnect = (ScQueryConnect)nConnect4;
+ bRefreshExceptQuery[nQE]=TRUE;
+
+ }
+ else if ( pLb == &aLbField1 )
+ {
+ if ( aLbField1.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect2.SetNoSelection();
+ aLbConnect3.SetNoSelection();
+ aLbConnect4.SetNoSelection();
+ aLbField2.SelectEntryPos( 0 );
+ aLbField3.SelectEntryPos( 0 );
+ aLbField4.SelectEntryPos( 0 );
+ aLbCond2.SelectEntryPos( 0 );
+ aLbCond3.SelectEntryPos( 0 );
+ aLbCond4.SelectEntryPos( 0 );
+ ClearValueList( 1 );
+ ClearValueList( 2 );
+ ClearValueList( 3 );
+ ClearValueList( 4 );
+
+ aLbConnect2.Disable();
+ aLbConnect3.Disable();
+ aLbConnect4.Disable();
+ aLbField2.Disable();
+ aLbField3.Disable();
+ aLbField4.Disable();
+ aLbCond2.Disable();
+ aLbCond3.Disable();
+ aLbCond4.Disable();
+ aEdVal2.Disable();
+ aEdVal3.Disable();
+ aEdVal4.Disable();
+ for (USHORT i= nOffset; i< MAXQUERY; i++)
+ {
+ theQueryData.GetEntry(i).bDoQuery = FALSE;
+ bRefreshExceptQuery[i]=FALSE;
+ theQueryData.GetEntry(i).nField = static_cast<SCCOL>(0);
+ }
+ bRefreshExceptQuery[nOffset] =TRUE;
+ }
+ else
+ {
+ UpdateValueList( 1 );
+ if ( !aLbConnect2.IsEnabled() )
+ {
+ aLbConnect2.Enable();
+ }
+ theQueryData.GetEntry(nOffset).bDoQuery = TRUE;
+ USHORT nField = pLb->GetSelectEntryPos();
+ theQueryData.GetEntry(nOffset).nField = theQueryData.nCol1 + static_cast<SCCOL>(nField) - 1 ;
+ }
+ }
+ else if ( pLb == &aLbField2 )
+ {
+ if ( aLbField2.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect3.SetNoSelection();
+ aLbConnect4.SetNoSelection();
+ aLbField3.SelectEntryPos( 0 );
+ aLbField4.SelectEntryPos( 0 );
+ aLbCond3.SelectEntryPos( 0 );
+ aLbCond4.SelectEntryPos( 0 );
+ ClearValueList( 2 );
+ ClearValueList( 3 );
+ ClearValueList( 4 );
+
+ aLbConnect3.Disable();
+ aLbConnect4.Disable();
+ aLbField3.Disable();
+ aLbField4.Disable();
+ aLbCond3.Disable();
+ aLbCond4.Disable();
+ aEdVal3.Disable();
+ aEdVal4.Disable();
+
+ USHORT nTemp=nOffset+1;
+ for (USHORT i= nTemp; i< MAXQUERY; i++)
+ {
+ theQueryData.GetEntry(i).bDoQuery = FALSE;
+ bRefreshExceptQuery[i]=FALSE;
+ theQueryData.GetEntry(i).nField = static_cast<SCCOL>(0);
+ }
+ bRefreshExceptQuery[nTemp]=TRUE;
+ }
+ else
+ {
+ UpdateValueList( 2 );
+ if ( !aLbConnect3.IsEnabled() )
+ {
+ aLbConnect3.Enable();
+ }
+ USHORT nField = pLb->GetSelectEntryPos();
+ USHORT nQ=1+nOffset;
+ theQueryData.GetEntry(nQ).bDoQuery = TRUE;
+ theQueryData.GetEntry(nQ).nField = theQueryData.nCol1 + static_cast<SCCOL>(nField) - 1 ;
+ }
+ }
+ else if ( pLb == &aLbField3 )
+ {
+ if ( aLbField3.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect4.SetNoSelection();
+ aLbField4.SelectEntryPos( 0 );
+ aLbCond4.SelectEntryPos( 0 );
+ ClearValueList( 3 );
+ ClearValueList( 4 );
+
+ aLbConnect4.Disable();
+ aLbField4.Disable();
+ aLbCond4.Disable();
+ aEdVal4.Disable();
+
+ USHORT nTemp=nOffset+2;
+ for (USHORT i= nTemp; i< MAXQUERY; i++)
+ {
+ theQueryData.GetEntry(i).bDoQuery = FALSE;
+ bRefreshExceptQuery[i]=FALSE;
+ theQueryData.GetEntry(i).nField = static_cast<SCCOL>(0);
+ }
+ bRefreshExceptQuery[nTemp]=TRUE;
+ }
+ else
+ {
+ UpdateValueList( 3 );
+ if ( !aLbConnect4.IsEnabled() )
+ {
+ aLbConnect4.Enable();
+ }
+
+ USHORT nField = pLb->GetSelectEntryPos();
+ USHORT nQ=2+nOffset;
+ theQueryData.GetEntry(nQ).bDoQuery = TRUE;
+ theQueryData.GetEntry(nQ).nField = theQueryData.nCol1 + static_cast<SCCOL>(nField) - 1 ;
+
+ }
+ }
+ else if ( pLb == &aLbField4 )
+ {
+ if ( aLbField4.GetSelectEntryPos() == 0 )
+ {
+ ClearValueList( 4 );
+ USHORT nTemp=nOffset+3;
+ for (USHORT i= nTemp; i< MAXQUERY; i++)
+ {
+ theQueryData.GetEntry(i).bDoQuery = FALSE;
+ bRefreshExceptQuery[i]=FALSE;
+ theQueryData.GetEntry(i).nField = static_cast<SCCOL>(0);
+ }
+ bRefreshExceptQuery[nTemp]=TRUE;
+ }
+ else
+ {
+ UpdateValueList( 4 );
+ USHORT nField = pLb->GetSelectEntryPos();
+ USHORT nQ=3+nOffset;
+ theQueryData.GetEntry(nQ).bDoQuery = TRUE;
+ theQueryData.GetEntry(nQ).nField = theQueryData.nCol1 + static_cast<SCCOL>(nField) - 1 ;
+ }
+
+ }
+ else if ( pLb == &aLbCond1)
+ {
+ theQueryData.GetEntry(nOffset).eOp=(ScQueryOp)pLb->GetSelectEntryPos();
+ }
+ else if ( pLb == &aLbCond2)
+ {
+ USHORT nQ=1+nOffset;
+ theQueryData.GetEntry(nQ).eOp=(ScQueryOp)pLb->GetSelectEntryPos();
+ }
+ else if ( pLb == &aLbCond3)
+ {
+ USHORT nQ=2+nOffset;
+ theQueryData.GetEntry(nQ).eOp=(ScQueryOp)pLb->GetSelectEntryPos();
+ }
+ else
+ {
+ USHORT nQ=3+nOffset;
+ theQueryData.GetEntry(nQ).eOp=(ScQueryOp)pLb->GetSelectEntryPos();
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterDlg, CheckBoxHdl, CheckBox*, pBox )
+{
+ // Spaltenkoepfe:
+ // FeldListen: Spaltexx <-> Spaltenkopf-String
+ // WertListen: Spaltenkopf-Wert entfaellt.
+ // Gross-/Kleinschreibung:
+ // WertListen: komplett neu
+
+ if ( pBox == &aBtnHeader ) // Feldlisten und Wertlisten
+ {
+ USHORT nCurSel1 = aLbField1.GetSelectEntryPos();
+ USHORT nCurSel2 = aLbField2.GetSelectEntryPos();
+ USHORT nCurSel3 = aLbField3.GetSelectEntryPos();
+ USHORT nCurSel4 = aLbField4.GetSelectEntryPos();
+ FillFieldLists();
+ aLbField1.SelectEntryPos( nCurSel1 );
+ aLbField2.SelectEntryPos( nCurSel2 );
+ aLbField3.SelectEntryPos( nCurSel3 );
+ aLbField4.SelectEntryPos( nCurSel4 );
+
+ UpdateHdrInValueList( 1 );
+ UpdateHdrInValueList( 2 );
+ UpdateHdrInValueList( 3 );
+ UpdateHdrInValueList( 4 );
+ }
+
+ if ( pBox == &aBtnCase ) // Wertlisten komplett
+ {
+ for (USHORT i=0; i<=MAXCOL; i++)
+ DELETEZ( pEntryLists[i] );
+
+ UpdateValueList( 1 ); // aktueller Text wird gemerkt
+ UpdateValueList( 2 );
+ UpdateValueList( 3 );
+ UpdateValueList( 4 );
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterDlg, ValModifyHdl, ComboBox*, pEd )
+{
+ USHORT nOffset = GetSliderPos();
+ USHORT i=0;
+ USHORT nQE =i + nOffset;
+ if ( pEd )
+ {
+ String aStrVal = pEd->GetText();
+ ListBox* pLbCond = &aLbCond1;
+ ListBox* pLbField = &aLbField1;
+ if ( pEd == &aEdVal2 )
+ {
+ pLbCond = &aLbCond2;
+ pLbField = &aLbField2;
+ i=1;
+ nQE=i+nOffset;
+ }
+ if ( pEd == &aEdVal3 )
+ {
+ pLbCond = &aLbCond3;
+ pLbField = &aLbField3;
+ i=2;
+ nQE=i+nOffset;
+ }
+ if ( pEd == &aEdVal4 )
+ {
+ pLbCond = &aLbCond4;
+ pLbField = &aLbField4;
+ i=3;
+ nQE=i+nOffset;
+ }
+
+ if ( aStrEmpty == aStrVal || aStrNotEmpty == aStrVal )
+ {
+ pLbCond->SelectEntry( '=' );
+ pLbCond->Disable();
+ }
+ else
+ pLbCond->Enable();
+
+ ScQueryEntry& rEntry = theQueryData.GetEntry( nQE );
+ BOOL bDoThis = (pLbField->GetSelectEntryPos() != 0);
+ rEntry.bDoQuery = bDoThis;
+
+ if ( rEntry.bDoQuery || bRefreshExceptQuery[nQE] )
+ {
+ if ( aStrVal == aStrEmpty )
+ {
+ rEntry.pStr->Erase();
+ rEntry.nVal = SC_EMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ }
+ else if ( aStrVal == aStrNotEmpty )
+ {
+ rEntry.pStr->Erase();
+ rEntry.nVal = SC_NONEMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ }
+ else
+ {
+ *rEntry.pStr = aStrVal;
+ rEntry.nVal = 0;
+ rEntry.bQueryByString = TRUE;
+ }
+
+ USHORT nField = pLbField->GetSelectEntryPos();
+ rEntry.nField = nField ? (theQueryData.nCol1 +
+ static_cast<SCCOL>(nField) - 1) : static_cast<SCCOL>(0);
+
+ ScQueryOp eOp = (ScQueryOp)pLbCond->GetSelectEntryPos();
+ rEntry.eOp = eOp;
+ rEntry.bQueryByDate = mbHasDates[nQE];
+
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+IMPL_LINK( ScFilterDlg, ScrollHdl, ScrollBar*, EMPTYARG )
+{
+ SliderMoved();
+ return 0;
+}
+
+void ScFilterDlg::SliderMoved()
+{
+ USHORT nOffset = GetSliderPos();
+ RefreshEditRow( nOffset);
+}
+USHORT ScFilterDlg::GetSliderPos()
+{
+ return (USHORT) aScrollBar.GetThumbPos();
+}
+void ScFilterDlg::RefreshEditRow( USHORT nOffset )
+{
+ if (nOffset==0)
+ aConnLbArr[0]->Hide();
+ else
+ aConnLbArr[0]->Show();
+
+ for ( USHORT i=0; i<4; i++ )
+ {
+ String aValStr;
+ USHORT nCondPos = 0;
+ USHORT nFieldSelPos = 0;
+ USHORT nQE = i+nOffset;
+
+ ScQueryEntry& rEntry = theQueryData.GetEntry( nQE);
+ if ( rEntry.bDoQuery || bRefreshExceptQuery[nQE] )
+ {
+ nCondPos = (USHORT)rEntry.eOp;
+ if(rEntry.bDoQuery)
+ nFieldSelPos = GetFieldSelPos( static_cast<SCCOL>(rEntry.nField) );
+
+ if ( rEntry.nVal == SC_EMPTYFIELDS && !rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING )
+ {
+ aValStr = aStrEmpty;
+ aCondLbArr[i]->Disable();
+ }
+ else if ( rEntry.nVal == SC_NONEMPTYFIELDS && !rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING )
+ {
+ aValStr = aStrNotEmpty;
+ aCondLbArr[i]->Disable();
+ }
+ else
+ {
+ aValStr = *rEntry.pStr;
+ aCondLbArr[i]->Enable();
+ }
+ aFieldLbArr[i]->Enable();
+ aValueEdArr[i]->Enable();
+
+ if (nOffset==0)
+ {
+ if (i<3)
+ {
+ if(rEntry.bDoQuery)
+ aConnLbArr[i+1]->Enable();
+ else
+ aConnLbArr[i+1]->Disable();
+ USHORT nQENext = nQE+1;
+ if(theQueryData.GetEntry(nQENext).bDoQuery || bRefreshExceptQuery[nQENext])
+ aConnLbArr[i+1]->SelectEntryPos( (USHORT) theQueryData.GetEntry(nQENext).eConnect );
+ else
+ aConnLbArr[i+1]->SetNoSelection();
+ }
+ }
+ else
+ {
+ if(theQueryData.GetEntry( nQE-1).bDoQuery)
+ aConnLbArr[i]->Enable();
+ else
+ aConnLbArr[i]->Disable();
+
+ if(rEntry.bDoQuery || bRefreshExceptQuery[nQE])
+ aConnLbArr[i]->SelectEntryPos( (USHORT) rEntry.eConnect );
+ else
+ aConnLbArr[i]->SetNoSelection();
+ }
+
+ }
+ else
+ {
+ if (nOffset==0)
+ {
+ if(i<3)
+ {
+ aConnLbArr[i+1]->SetNoSelection();
+ aConnLbArr[i+1]->Disable();
+ }
+ }
+ else
+ {
+ if(theQueryData.GetEntry( nQE-1).bDoQuery)
+ aConnLbArr[i]->Enable();
+ else
+ aConnLbArr[i]->Disable();
+ aConnLbArr[i]->SetNoSelection();
+ }
+ aFieldLbArr[i]->Disable();
+ aCondLbArr[i]->Disable();
+ aValueEdArr[i]->Disable();
+ }
+ aFieldLbArr[i]->SelectEntryPos( nFieldSelPos );
+ aCondLbArr [i]->SelectEntryPos( nCondPos );
+ aValueEdArr[i]->SetText( aValStr );
+ UpdateValueList( static_cast<USHORT>(i+1) );
+ }
+}
diff --git a/sc/source/ui/dbgui/foptmgr.cxx b/sc/source/ui/dbgui/foptmgr.cxx
new file mode 100644
index 000000000000..1e274690c31c
--- /dev/null
+++ b/sc/source/ui/dbgui/foptmgr.cxx
@@ -0,0 +1,337 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+
+#include <vcl/morebtn.hxx>
+#include <svtools/stdctrl.hxx>
+
+#include "anyrefdg.hxx"
+#include "rangeutl.hxx"
+#include "dbcolect.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "queryparam.hxx"
+
+#define _FOPTMGR_CXX
+#include "foptmgr.hxx"
+#undef _FOPTMGR_CXX
+
+//----------------------------------------------------------------------------
+
+ScFilterOptionsMgr::ScFilterOptionsMgr(
+ Dialog* ptrDlg,
+ ScViewData* ptrViewData,
+ const ScQueryParam& refQueryData,
+ MoreButton& refBtnMore,
+ CheckBox& refBtnCase,
+ CheckBox& refBtnRegExp,
+ CheckBox& refBtnHeader,
+ CheckBox& refBtnUnique,
+ CheckBox& refBtnCopyResult,
+ CheckBox& refBtnDestPers,
+ ListBox& refLbCopyArea,
+ Edit& refEdCopyArea,
+ formula::RefButton& refRbCopyArea,
+ FixedText& refFtDbAreaLabel,
+ FixedInfo& refFtDbArea,
+ FixedLine& refFlOptions,
+ const String& refStrNoName,
+ const String& refStrUndefined )
+
+ : pDlg ( ptrDlg ),
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData ? ptrViewData->GetDocument() : NULL ),
+ rBtnMore ( refBtnMore ),
+ rBtnCase ( refBtnCase ),
+ rBtnRegExp ( refBtnRegExp ),
+ rBtnHeader ( refBtnHeader ),
+ rBtnUnique ( refBtnUnique ),
+ rBtnCopyResult ( refBtnCopyResult ),
+ rBtnDestPers ( refBtnDestPers ),
+ rLbCopyPos ( refLbCopyArea ),
+ rEdCopyPos ( refEdCopyArea ),
+ rRbCopyPos ( refRbCopyArea ),
+ rFtDbAreaLabel ( refFtDbAreaLabel ),
+ rFtDbArea ( refFtDbArea ),
+ rFlOptions ( refFlOptions ),
+ rStrNoName ( refStrNoName ),
+ rStrUndefined ( refStrUndefined ),
+ rQueryData ( refQueryData )
+{
+ Init();
+}
+
+
+//----------------------------------------------------------------------------
+
+ScFilterOptionsMgr::~ScFilterOptionsMgr()
+{
+ USHORT nEntries = rLbCopyPos.GetEntryCount();
+ USHORT i;
+
+ for ( i=2; i<nEntries; i++ )
+ delete (String*)rLbCopyPos.GetEntryData( i );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScFilterOptionsMgr::Init()
+{
+ DBG_ASSERT( pViewData && pDoc, "Init failed :-/" );
+
+ rLbCopyPos.SetSelectHdl ( LINK( this, ScFilterOptionsMgr, LbPosSelHdl ) );
+ rEdCopyPos.SetModifyHdl ( LINK( this, ScFilterOptionsMgr, EdPosModifyHdl ) );
+ rBtnCopyResult.SetClickHdl( LINK( this, ScFilterOptionsMgr, BtnCopyResultHdl ) );
+
+ rBtnMore.AddWindow( &rBtnCase );
+ rBtnMore.AddWindow( &rBtnRegExp );
+ rBtnMore.AddWindow( &rBtnHeader );
+ rBtnMore.AddWindow( &rBtnUnique );
+ rBtnMore.AddWindow( &rBtnCopyResult );
+ rBtnMore.AddWindow( &rBtnDestPers );
+ rBtnMore.AddWindow( &rLbCopyPos );
+ rBtnMore.AddWindow( &rEdCopyPos );
+ rBtnMore.AddWindow( &rRbCopyPos );
+ rBtnMore.AddWindow( &rFtDbAreaLabel );
+ rBtnMore.AddWindow( &rFtDbArea );
+ rBtnMore.AddWindow( &rFlOptions );
+
+ rBtnCase .Check( rQueryData.bCaseSens );
+ rBtnHeader .Check( rQueryData.bHasHeader );
+ rBtnRegExp .Check( rQueryData.bRegExp );
+ rBtnUnique .Check( !rQueryData.bDuplicate );
+
+ if ( pViewData && pDoc )
+ {
+ String theAreaStr;
+ ScRange theCurArea ( ScAddress( rQueryData.nCol1,
+ rQueryData.nRow1,
+ pViewData->GetTabNo() ),
+ ScAddress( rQueryData.nCol2,
+ rQueryData.nRow2,
+ pViewData->GetTabNo() ) );
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ String theDbArea;
+ String theDbName = rStrNoName;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ theCurArea.Format( theAreaStr, SCR_ABS_3D, pDoc, eConv );
+
+ // Zielbereichsliste fuellen
+
+ rLbCopyPos.Clear();
+ rLbCopyPos.InsertEntry( rStrUndefined, 0 );
+
+ ScAreaNameIterator aIter( pDoc );
+ String aName;
+ ScRange aRange;
+ String aRefStr;
+ while ( aIter.Next( aName, aRange ) )
+ {
+ USHORT nInsert = rLbCopyPos.InsertEntry( aName );
+
+ aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, eConv );
+ rLbCopyPos.SetEntryData( nInsert, new String( aRefStr ) );
+ }
+
+ rBtnDestPers.Check( TRUE ); // beim Aufruf immer an
+ rLbCopyPos.SelectEntryPos( 0 );
+ rEdCopyPos.SetText( EMPTY_STRING );
+
+ /*
+ * Ueberpruefen, ob es sich bei dem uebergebenen
+ * Bereich um einen Datenbankbereich handelt:
+ */
+
+ theDbArea = theAreaStr;
+
+ if ( pDBColl )
+ {
+ ScAddress& rStart = theCurArea.aStart;
+ ScAddress& rEnd = theCurArea.aEnd;
+ ScDBData* pDBData = pDBColl->GetDBAtArea( rStart.Tab(),
+ rStart.Col(), rStart.Row(),
+ rEnd.Col(), rEnd.Row() );
+ if ( pDBData )
+ {
+ rBtnHeader.Check( pDBData->HasHeader() );
+ pDBData->GetName( theDbName );
+
+ if ( theDbName != rStrNoName )
+ {
+ rBtnHeader.Disable();
+ }
+ }
+ }
+
+ theDbArea.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" ("));
+ theDbArea += theDbName;
+ theDbArea += ')';
+ rFtDbArea.SetText( theDbArea );
+
+ //------------------------------------------------------
+ // Kopierposition:
+
+ if ( !rQueryData.bInplace )
+ {
+ String aString;
+
+ ScAddress( rQueryData.nDestCol,
+ rQueryData.nDestRow,
+ rQueryData.nDestTab
+ ).Format( aString, SCA_ABS_3D, pDoc, eConv );
+
+ rBtnCopyResult.Check( TRUE );
+ rEdCopyPos.SetText( aString );
+ EdPosModifyHdl( &rEdCopyPos );
+ rLbCopyPos.Enable();
+ rEdCopyPos.Enable();
+ rRbCopyPos.Enable();
+ rBtnDestPers.Enable();
+ }
+ else
+ {
+ rBtnCopyResult.Check( FALSE );
+ rEdCopyPos.SetText( EMPTY_STRING );
+ rLbCopyPos.Disable();
+ rEdCopyPos.Disable();
+ rRbCopyPos.Disable();
+ rBtnDestPers.Disable();
+ }
+ }
+ else
+ rEdCopyPos.SetText( EMPTY_STRING );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScFilterOptionsMgr::VerifyPosStr( const String& rPosStr ) const
+{
+ String aPosStr( rPosStr );
+ xub_StrLen nColonPos = aPosStr.Search( ':' );
+
+ if ( STRING_NOTFOUND != nColonPos )
+ aPosStr.Erase( nColonPos );
+
+ USHORT nResult = ScAddress().Parse( aPosStr, pDoc, pDoc->GetAddressConvention() );
+
+ return ( SCA_VALID == (nResult & SCA_VALID) );
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterOptionsMgr, LbPosSelHdl, ListBox*, pLb )
+{
+ if ( pLb == &rLbCopyPos )
+ {
+ String aString;
+ USHORT nSelPos = rLbCopyPos.GetSelectEntryPos();
+
+ if ( nSelPos > 0 )
+ aString = *(String*)rLbCopyPos.GetEntryData( nSelPos );
+
+ rEdCopyPos.SetText( aString );
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterOptionsMgr, EdPosModifyHdl, Edit*, pEd )
+{
+ if ( pEd == &rEdCopyPos )
+ {
+ String theCurPosStr = pEd->GetText();
+ USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
+
+ if ( SCA_VALID == (nResult & SCA_VALID) )
+ {
+ String* pStr = NULL;
+ BOOL bFound = FALSE;
+ USHORT i = 0;
+ USHORT nCount = rLbCopyPos.GetEntryCount();
+
+ for ( i=2; i<nCount && !bFound; i++ )
+ {
+ pStr = (String*)rLbCopyPos.GetEntryData( i );
+ bFound = (theCurPosStr == *pStr);
+ }
+
+ if ( bFound )
+ rLbCopyPos.SelectEntryPos( --i );
+ else
+ rLbCopyPos.SelectEntryPos( 0 );
+ }
+ else
+ rLbCopyPos.SelectEntryPos( 0 );
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFilterOptionsMgr, BtnCopyResultHdl, CheckBox*, pBox )
+{
+ if ( pBox == &rBtnCopyResult )
+ {
+ if ( pBox->IsChecked() )
+ {
+ rBtnDestPers.Enable();
+ rLbCopyPos.Enable();
+ rEdCopyPos.Enable();
+ rRbCopyPos.Enable();
+ rEdCopyPos.GrabFocus();
+ }
+ else
+ {
+ rBtnDestPers.Disable();
+ rLbCopyPos.Disable();
+ rEdCopyPos.Disable();
+ rRbCopyPos.Disable();
+ }
+ }
+
+ return 0;
+}
diff --git a/sc/source/ui/dbgui/imoptdlg.cxx b/sc/source/ui/dbgui/imoptdlg.cxx
new file mode 100644
index 000000000000..bd18008afd47
--- /dev/null
+++ b/sc/source/ui/dbgui/imoptdlg.cxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "imoptdlg.hxx"
+#include "scresid.hxx"
+#include "imoptdlg.hrc"
+#include <rtl/tencinfo.h>
+
+static const sal_Char pStrFix[] = "FIX";
+
+//------------------------------------------------------------------------
+// Der Options-String darf kein Semikolon mehr enthalten (wegen Pickliste)
+// darum ab Version 336 Komma stattdessen
+
+
+ScImportOptions::ScImportOptions( const String& rStr )
+{
+ bFixedWidth = FALSE;
+ nFieldSepCode = 0;
+ if ( rStr.GetTokenCount(',') >= 3 )
+ {
+ String aToken( rStr.GetToken( 0, ',' ) );
+ if( aToken.EqualsIgnoreCaseAscii( pStrFix ) )
+ bFixedWidth = TRUE;
+ else
+ nFieldSepCode = (sal_Unicode) aToken.ToInt32();
+ nTextSepCode = (sal_Unicode) rStr.GetToken(1,',').ToInt32();
+ aStrFont = rStr.GetToken(2,',');
+ eCharSet = ScGlobal::GetCharsetValue(aStrFont);
+ bSaveAsShown = (rStr.GetToken( 3, ',' ).ToInt32() ? TRUE : FALSE);
+ }
+}
+
+//------------------------------------------------------------------------
+
+String ScImportOptions::BuildString() const
+{
+ String aResult;
+
+ if( bFixedWidth )
+ aResult.AppendAscii( pStrFix );
+ else
+ aResult += String::CreateFromInt32(nFieldSepCode);
+ aResult += ',';
+ aResult += String::CreateFromInt32(nTextSepCode);
+ aResult += ',';
+ aResult += aStrFont;
+ aResult += ',';
+ aResult += String::CreateFromInt32( bSaveAsShown ? 1 : 0 );
+
+ return aResult;
+}
+
+//------------------------------------------------------------------------
+
+void ScImportOptions::SetTextEncoding( rtl_TextEncoding nEnc )
+{
+ eCharSet = (nEnc == RTL_TEXTENCODING_DONTKNOW ?
+ gsl_getSystemTextEncoding() : nEnc);
+ aStrFont = ScGlobal::GetCharsetString( nEnc );
+}
diff --git a/sc/source/ui/dbgui/imoptdlg.hrc b/sc/source/ui/dbgui/imoptdlg.hrc
new file mode 100644
index 000000000000..5fd9256e8009
--- /dev/null
+++ b/sc/source/ui/dbgui/imoptdlg.hrc
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 RID_SCDLG_IMPORTOPT 2256
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+#define FT_FIELDSEP 4
+#define ED_FIELDSEP 5
+#define FT_TEXTSEP 6
+#define ED_TEXTSEP 7
+#define FT_FONT 8
+#define DDLB_FONT 9
+#define LB_FONT 10
+#define FL_FIELDOPT 11
+#define CB_FIXEDWIDTH 12
+#define CB_SAVESHOWN 13
+
diff --git a/sc/source/ui/dbgui/imoptdlg.src b/sc/source/ui/dbgui/imoptdlg.src
new file mode 100644
index 000000000000..914f2d1fb027
--- /dev/null
+++ b/sc/source/ui/dbgui/imoptdlg.src
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include "imoptdlg.hrc"
+
+ModalDialog RID_SCDLG_IMPORTOPT
+{
+ HelpId = HID_SC_INPORTOPT ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 256 , 66 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Text [ en-US ] = "Import File" ;
+ FixedText FT_FIELDSEP
+ {
+ Pos = MAP_APPFONT ( 12 , 32 ) ;
+ Size = MAP_APPFONT ( 55 , 8 ) ;
+ Text [ en-US ] = "~Field delimiter" ;
+ };
+ ComboBox ED_FIELDSEP
+ {
+ Pos = MAP_APPFONT ( 70 , 30 ) ;
+ Size = MAP_APPFONT ( 121 , 60 ) ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_TEXTSEP
+ {
+ Pos = MAP_APPFONT ( 12 , 48 ) ;
+ Size = MAP_APPFONT ( 55 , 8 ) ;
+ Text [ en-US ] = "~Text delimiter" ;
+ };
+ ComboBox ED_TEXTSEP
+ {
+ Pos = MAP_APPFONT ( 70 , 46 ) ;
+ Size = MAP_APPFONT ( 121 , 60 ) ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_FONT
+ {
+ Pos = MAP_APPFONT ( 12 , 16 ) ;
+ Size = MAP_APPFONT ( 55 , 8 ) ;
+ Text [ en-US ] = "~Character set" ;
+ };
+ ListBox DDLB_FONT
+ {
+ Border = TRUE;
+ Sort = TRUE;
+ DropDown = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 14 ) ;
+ Size = MAP_APPFONT ( 121 , 52 ) ;
+ };
+ ListBox LB_FONT
+ {
+ Border = TRUE;
+ Sort = TRUE;
+ DropDown = FALSE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 179 , 50 ) ;
+ };
+ FixedLine FL_FIELDOPT
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 188 , 8 ) ;
+ Text [ en-US ] = "Field options" ;
+ };
+ CheckBox CB_FIXEDWIDTH
+ {
+ Pos = MAP_APPFONT( 12, 80 );
+ Size = MAP_APPFONT( 172, 10 );
+ Hide = TRUE;
+ Text [ en-US ] = "Fixed column ~width";
+ };
+ CheckBox CB_SAVESHOWN
+ {
+ Pos = MAP_APPFONT( 12, 66 );
+ Size = MAP_APPFONT( 172, 10 );
+ TabStop = TRUE;
+ Hide = TRUE;
+ Text [ en-US ] = "Save cell content as ~shown";
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 202 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 202 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 202 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/dbgui/makefile.mk b/sc/source/ui/dbgui/makefile.mk
new file mode 100644
index 000000000000..1e7000d0cb07
--- /dev/null
+++ b/sc/source/ui/dbgui/makefile.mk
@@ -0,0 +1,122 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=dbgui
+LIBTARGET=no
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/sortdlg.obj \
+ $(SLO)$/tpsort.obj \
+ $(SLO)$/filtdlg.obj \
+ $(SLO)$/sfiltdlg.obj \
+ $(SLO)$/foptmgr.obj \
+ $(SLO)$/pfiltdlg.obj \
+ $(SLO)$/dbnamdlg.obj \
+ $(SLO)$/expftext.obj \
+ $(SLO)$/textimportoptions.obj \
+ $(SLO)$/subtdlg.obj \
+ $(SLO)$/tpsubt.obj \
+ $(SLO)$/fieldwnd.obj \
+ $(SLO)$/pvlaydlg.obj \
+ $(SLO)$/pvfundlg.obj \
+ $(SLO)$/dpgroupdlg.obj \
+ $(SLO)$/dapitype.obj \
+ $(SLO)$/dapidata.obj \
+ $(SLO)$/consdlg.obj \
+ $(SLO)$/scendlg.obj \
+ $(SLO)$/imoptdlg.obj \
+ $(SLO)$/validate.obj \
+ $(SLO)$/csvsplits.obj \
+ $(SLO)$/csvcontrol.obj \
+ $(SLO)$/csvruler.obj \
+ $(SLO)$/csvgrid.obj \
+ $(SLO)$/csvtablebox.obj \
+ $(SLO)$/asciiopt.obj \
+ $(SLO)$/scuiasciiopt.obj \
+ $(SLO)$/scuiimoptdlg.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/csvgrid.obj \
+ $(SLO)$/csvruler.obj \
+ $(SLO)$/csvsplits.obj \
+ $(SLO)$/csvtablebox.obj \
+ $(SLO)$/fieldwnd.obj \
+ $(SLO)$/pvfundlg.obj \
+ $(SLO)$/pvlaydlg.obj \
+ $(SLO)$/dapidata.obj \
+ $(SLO)$/validate.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ textimportoptions.src \
+ pivot.src \
+ pvfundlg.src \
+ dpgroupdlg.src \
+ dapitype.src \
+ consdlg.src \
+ scendlg.src \
+ imoptdlg.src \
+ validate.src \
+ asciiopt.src \
+ outline.src
+
+LIB1TARGET = $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO)$/filtdlg.obj \
+ $(SLO)$/sfiltdlg.obj \
+ $(SLO)$/foptmgr.obj \
+ $(SLO)$/dbnamdlg.obj \
+ $(SLO)$/expftext.obj \
+ $(SLO)$/fieldwnd.obj \
+ $(SLO)$/pvlaydlg.obj \
+ $(SLO)$/consdlg.obj \
+ $(SLO)$/imoptdlg.obj \
+ $(SLO)$/csvsplits.obj \
+ $(SLO)$/csvcontrol.obj \
+ $(SLO)$/csvruler.obj \
+ $(SLO)$/csvgrid.obj \
+ $(SLO)$/csvtablebox.obj \
+ $(SLO)$/asciiopt.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/sc/source/ui/dbgui/outline.src b/sc/source/ui/dbgui/outline.src
new file mode 100644
index 000000000000..cd59bf3b099d
--- /dev/null
+++ b/sc/source/ui/dbgui/outline.src
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+
+// Imageliste hier, damit sie nicht in ui.src beim Zusammenbauen der
+// "echten" Imagelisten stoert
+
+#define OUTLINE_ID_LIST \
+ IdList = { 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; }; \
+ IdCount = { 12; };
+
+ImageList RID_OUTLINEBITMAPS
+{
+ Prefix = "ou";
+ MaskColor = STD_MASKCOLOR;
+ OUTLINE_ID_LIST
+};
+
+ImageList RID_OUTLINEBITMAPS_H
+{
+ Prefix = "ouh";
+ MaskColor = SC_HC_MASKCOLOR;
+ OUTLINE_ID_LIST
+};
+
diff --git a/sc/source/ui/dbgui/pfiltdlg.cxx b/sc/source/ui/dbgui/pfiltdlg.cxx
new file mode 100644
index 000000000000..d590ffb83457
--- /dev/null
+++ b/sc/source/ui/dbgui/pfiltdlg.cxx
@@ -0,0 +1,620 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#ifndef PCH
+#include <vcl/waitobj.hxx>
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "uiitems.hxx"
+#include "global.hxx"
+#include "dbcolect.hxx"
+#include "scresid.hxx"
+
+#include "sc.hrc"
+#include "filter.hrc"
+#include "globstr.hrc"
+
+#define _PFILTDLG_CXX
+#include "pfiltdlg.hxx"
+#undef _PFILTDLG_CXX
+#include <svl/zforlist.hxx>
+
+//==================================================================
+
+ScPivotFilterDlg::ScPivotFilterDlg( Window* pParent,
+ const SfxItemSet& rArgSet,
+ SCTAB nSourceTab )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_PIVOTFILTER ) ),
+ //
+ aFlCriteria ( this, ScResId( FL_CRITERIA ) ),
+ aLbField1 ( this, ScResId( LB_FIELD1 ) ),
+ aLbCond1 ( this, ScResId( LB_COND1 ) ),
+ aEdVal1 ( this, ScResId( ED_VAL1 ) ),
+ aLbConnect1 ( this, ScResId( LB_OP1 ) ),
+ aLbField2 ( this, ScResId( LB_FIELD2 ) ),
+ aLbCond2 ( this, ScResId( LB_COND2 ) ),
+ aEdVal2 ( this, ScResId( ED_VAL2 ) ),
+ aLbConnect2 ( this, ScResId( LB_OP2 ) ),
+ aLbField3 ( this, ScResId( LB_FIELD3 ) ),
+ aLbCond3 ( this, ScResId( LB_COND3 ) ),
+ aEdVal3 ( this, ScResId( ED_VAL3 ) ),
+ aFtConnect ( this, ScResId( FT_OP ) ),
+ aFtField ( this, ScResId( FT_FIELD ) ),
+ aFtCond ( this, ScResId( FT_COND ) ),
+ aFtVal ( this, ScResId( FT_VAL ) ),
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ aBtnCase ( this, ScResId( BTN_CASE ) ),
+ aBtnRegExp ( this, ScResId( BTN_REGEXP ) ),
+ aBtnUnique ( this, ScResId( BTN_UNIQUE ) ),
+ aFtDbAreaLabel ( this, ScResId( FT_DBAREA_LABEL ) ),
+ aFtDbArea ( this, ScResId( FT_DBAREA ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
+ aStrNoName ( ScGlobal::GetRscString(STR_DB_NONAME) ),
+ aStrNone ( ScResId( SCSTR_NONE ) ),
+ aStrEmpty ( ScResId( SCSTR_EMPTY ) ),
+ aStrNotEmpty ( ScResId( SCSTR_NOTEMPTY ) ),
+ aStrRow ( ScResId( SCSTR_ROW ) ),
+ aStrColumn ( ScResId( SCSTR_COLUMN ) ),
+ //
+ nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
+ theQueryData ( ((const ScQueryItem&)
+ rArgSet.Get( nWhichQuery )).GetQueryData() ),
+ pOutItem ( NULL ),
+ pViewData ( NULL ),
+ pDoc ( NULL ),
+ nSrcTab ( nSourceTab ), // ist nicht im QueryParam
+ nFieldCount ( 0 )
+{
+ for (USHORT i=0; i<=MAXCOL; i++)
+ pEntryLists[i] = NULL;
+
+ Init( rArgSet );
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScPivotFilterDlg::~ScPivotFilterDlg()
+{
+ for (USHORT i=0; i<=MAXCOL; i++)
+ delete pEntryLists[i];
+
+ if ( pOutItem )
+ delete pOutItem;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScPivotFilterDlg::Init( const SfxItemSet& rArgSet )
+{
+ const ScQueryItem& rQueryItem = (const ScQueryItem&)
+ rArgSet.Get( nWhichQuery );
+
+ aBtnCase.SetClickHdl ( LINK( this, ScPivotFilterDlg, CheckBoxHdl ) );
+
+ aLbField1.SetSelectHdl ( LINK( this, ScPivotFilterDlg, LbSelectHdl ) );
+ aLbField2.SetSelectHdl ( LINK( this, ScPivotFilterDlg, LbSelectHdl ) );
+ aLbField3.SetSelectHdl ( LINK( this, ScPivotFilterDlg, LbSelectHdl ) );
+ aLbConnect1.SetSelectHdl( LINK( this, ScPivotFilterDlg, LbSelectHdl ) );
+ aLbConnect2.SetSelectHdl( LINK( this, ScPivotFilterDlg, LbSelectHdl ) );
+
+ aBtnMore.AddWindow( &aBtnCase );
+ aBtnMore.AddWindow( &aBtnRegExp );
+ aBtnMore.AddWindow( &aBtnUnique );
+ aBtnMore.AddWindow( &aFtDbAreaLabel );
+ aBtnMore.AddWindow( &aFtDbArea );
+ aBtnMore.AddWindow( &aFlOptions );
+
+ aBtnCase .Check( theQueryData.bCaseSens );
+ aBtnRegExp .Check( theQueryData.bRegExp );
+ aBtnUnique .Check( !theQueryData.bDuplicate );
+
+ pViewData = rQueryItem.GetViewData();
+ pDoc = pViewData ? pViewData->GetDocument() : NULL;
+
+ // fuer leichteren Zugriff:
+ aFieldLbArr [0] = &aLbField1;
+ aFieldLbArr [1] = &aLbField2;
+ aFieldLbArr [2] = &aLbField3;
+ aValueEdArr [0] = &aEdVal1;
+ aValueEdArr [1] = &aEdVal2;
+ aValueEdArr [2] = &aEdVal3;
+ aCondLbArr [0] = &aLbCond1;
+ aCondLbArr [1] = &aLbCond2;
+ aCondLbArr [2] = &aLbCond3;
+
+ if ( pViewData && pDoc )
+ {
+ String theAreaStr;
+ ScRange theCurArea ( ScAddress( theQueryData.nCol1,
+ theQueryData.nRow1,
+ nSrcTab ),
+ ScAddress( theQueryData.nCol2,
+ theQueryData.nRow2,
+ nSrcTab ) );
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ String theDbArea;
+ String theDbName = aStrNoName;
+
+ /*
+ * Ueberpruefen, ob es sich bei dem uebergebenen
+ * Bereich um einen Datenbankbereich handelt:
+ */
+
+ theCurArea.Format( theAreaStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+
+ if ( pDBColl )
+ {
+ ScAddress& rStart = theCurArea.aStart;
+ ScAddress& rEnd = theCurArea.aEnd;
+ ScDBData* pDBData = pDBColl->GetDBAtArea( rStart.Tab(),
+ rStart.Col(), rStart.Row(),
+ rEnd.Col(), rEnd.Row() );
+ if ( pDBData )
+ pDBData->GetName( theDbName );
+ }
+
+ theDbArea.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" ("));
+ theDbArea += theDbName;
+ theDbArea += ')';
+ aFtDbArea.SetText( theDbArea );
+ }
+ else
+ {
+ aFtDbArea.SetText( EMPTY_STRING );
+ }
+
+ // Feldlisten einlesen und Eintraege selektieren:
+
+ FillFieldLists();
+
+ for ( SCSIZE i=0; i<3; i++ )
+ {
+ if ( theQueryData.GetEntry(i).bDoQuery )
+ {
+ ScQueryEntry& rEntry = theQueryData.GetEntry(i);
+
+ String aValStr = *rEntry.pStr;
+ if (!rEntry.bQueryByString && aValStr == EMPTY_STRING)
+ {
+ if (rEntry.nVal == SC_EMPTYFIELDS)
+ aValStr = aStrEmpty;
+ else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+ aValStr = aStrNotEmpty;
+ }
+ USHORT nCondPos = (USHORT)rEntry.eOp;
+ USHORT nFieldSelPos = GetFieldSelPos( static_cast<SCCOL>(rEntry.nField) );
+
+ aFieldLbArr[i]->SelectEntryPos( nFieldSelPos );
+ aCondLbArr [i]->SelectEntryPos( nCondPos );
+ UpdateValueList( static_cast<USHORT>(i+1) );
+ aValueEdArr[i]->SetText( aValStr );
+ if (aValStr == aStrEmpty || aValStr == aStrNotEmpty)
+ aCondLbArr[i]->Disable();
+ }
+ else
+ {
+ aFieldLbArr[i]->SelectEntryPos( 0 ); // "keiner" selektieren
+ aCondLbArr [i]->SelectEntryPos( 0 ); // "=" selektieren
+ UpdateValueList( static_cast<USHORT>(i) );
+ aValueEdArr[i]->SetText( EMPTY_STRING );
+ }
+ aValueEdArr[i]->SetModifyHdl( LINK( this, ScPivotFilterDlg, ValModifyHdl ) );
+ }
+
+ // Disable/Enable Logik:
+
+ (aLbField1.GetSelectEntryPos() != 0)
+ && (aLbField2.GetSelectEntryPos() != 0)
+ ? aLbConnect1.SelectEntryPos( (USHORT)theQueryData.GetEntry(1).eConnect )
+ : aLbConnect1.SetNoSelection();
+
+ (aLbField2.GetSelectEntryPos() != 0)
+ && (aLbField3.GetSelectEntryPos() != 0)
+ ? aLbConnect2.SelectEntryPos( (USHORT)theQueryData.GetEntry(2).eConnect )
+ : aLbConnect2.SetNoSelection();
+
+ if ( aLbField1.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect1.Disable();
+ aLbField2.Disable();
+ aLbCond2.Disable();
+ aEdVal2.Disable();
+ }
+ else if ( aLbConnect1.GetSelectEntryCount() == 0 )
+ {
+ aLbField2.Disable();
+ aLbCond2.Disable();
+ aEdVal2.Disable();
+ }
+
+ if ( aLbField2.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect2.Disable();
+ aLbField3.Disable();
+ aLbCond3.Disable();
+ aEdVal3.Disable();
+ }
+ else if ( aLbConnect2.GetSelectEntryCount() == 0 )
+ {
+ aLbField3.Disable();
+ aLbCond3.Disable();
+ aEdVal3.Disable();
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScPivotFilterDlg::FillFieldLists()
+{
+ aLbField1.Clear();
+ aLbField2.Clear();
+ aLbField3.Clear();
+ aLbField1.InsertEntry( aStrNone, 0 );
+ aLbField2.InsertEntry( aStrNone, 0 );
+ aLbField3.InsertEntry( aStrNone, 0 );
+
+ if ( pDoc )
+ {
+ String aFieldName;
+ SCTAB nTab = nSrcTab;
+ SCCOL nFirstCol = theQueryData.nCol1;
+ SCROW nFirstRow = theQueryData.nRow1;
+ SCCOL nMaxCol = theQueryData.nCol2;
+ SCCOL col = 0;
+ USHORT i=1;
+
+ for ( col=nFirstCol; col<=nMaxCol; col++ )
+ {
+ pDoc->GetString( col, nFirstRow, nTab, aFieldName );
+ if ( aFieldName.Len() == 0 )
+ {
+ aFieldName = aStrColumn;
+ aFieldName += ' ';
+ aFieldName += ScColToAlpha( col );
+ }
+ aLbField1.InsertEntry( aFieldName, i );
+ aLbField2.InsertEntry( aFieldName, i );
+ aLbField3.InsertEntry( aFieldName, i );
+ i++;
+ }
+ nFieldCount = i;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScPivotFilterDlg::UpdateValueList( USHORT nList )
+{
+ if ( pDoc && nList>0 && nList<=3 )
+ {
+ ComboBox* pValList = aValueEdArr[nList-1];
+ USHORT nFieldSelPos = aFieldLbArr[nList-1]->GetSelectEntryPos();
+ USHORT nListPos = 0;
+ String aCurValue = pValList->GetText();
+
+ pValList->Clear();
+ pValList->InsertEntry( aStrNotEmpty, 0 );
+ pValList->InsertEntry( aStrEmpty, 1 );
+ nListPos = 2;
+
+ if ( pDoc && nFieldSelPos )
+ {
+ SCCOL nColumn = theQueryData.nCol1 + static_cast<SCCOL>(nFieldSelPos) - 1;
+ if (!pEntryLists[nColumn])
+ {
+ WaitObject aWaiter( this );
+
+ SCTAB nTab = nSrcTab;
+ SCROW nFirstRow = theQueryData.nRow1;
+ SCROW nLastRow = theQueryData.nRow2;
+ nFirstRow++;
+ bool bHasDates = false;
+
+ pEntryLists[nColumn] = new TypedScStrCollection( 128, 128 );
+ pEntryLists[nColumn]->SetCaseSensitive( aBtnCase.IsChecked() );
+ pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nLastRow,
+ nTab, *pEntryLists[nColumn], bHasDates );
+ }
+
+ TypedScStrCollection* pColl = pEntryLists[nColumn];
+ USHORT nValueCount = pColl->GetCount();
+ if ( nValueCount > 0 )
+ {
+ for ( USHORT i=0; i<nValueCount; i++ )
+ {
+ pValList->InsertEntry( (*pColl)[i]->GetString(), nListPos );
+ nListPos++;
+ }
+ }
+ }
+ pValList->SetText( aCurValue );
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScPivotFilterDlg::ClearValueList( USHORT nList )
+{
+ if ( nList>0 && nList<=3 )
+ {
+ ComboBox* pValList = aValueEdArr[nList-1];
+ pValList->Clear();
+ pValList->InsertEntry( aStrNotEmpty, 0 );
+ pValList->InsertEntry( aStrEmpty, 1 );
+ pValList->SetText( EMPTY_STRING );
+ }
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScPivotFilterDlg::GetFieldSelPos( SCCOL nField )
+{
+ if ( nField >= theQueryData.nCol1 && nField <= theQueryData.nCol2 )
+ return static_cast<USHORT>(nField - theQueryData.nCol1 + 1);
+ else
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+const ScQueryItem& ScPivotFilterDlg::GetOutputItem()
+{
+ ScQueryParam theParam( theQueryData );
+ USHORT nConnect1 = aLbConnect1.GetSelectEntryPos();
+ USHORT nConnect2 = aLbConnect2.GetSelectEntryPos();
+
+ for ( SCSIZE i=0; i<3; i++ )
+ {
+ USHORT nField = aFieldLbArr[i]->GetSelectEntryPos();
+ ScQueryOp eOp = (ScQueryOp)aCondLbArr[i]->GetSelectEntryPos();
+
+ BOOL bDoThis = (aFieldLbArr[i]->GetSelectEntryPos() != 0);
+ theParam.GetEntry(i).bDoQuery = bDoThis;
+
+ if ( bDoThis )
+ {
+ ScQueryEntry& rEntry = theParam.GetEntry(i);
+
+ String aStrVal( aValueEdArr[i]->GetText() );
+
+ /*
+ * Dialog liefert die ausgezeichneten Feldwerte "leer"/"nicht leer"
+ * als Konstanten in nVal in Verbindung mit dem Schalter
+ * bQueryByString auf FALSE.
+ */
+ if ( aStrVal == aStrEmpty )
+ {
+ *rEntry.pStr = EMPTY_STRING;
+ rEntry.nVal = SC_EMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ }
+ else if ( aStrVal == aStrNotEmpty )
+ {
+ *rEntry.pStr = EMPTY_STRING;
+ rEntry.nVal = SC_NONEMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ }
+ else
+ {
+ *rEntry.pStr = aStrVal;
+ rEntry.nVal = 0;
+ rEntry.bQueryByString = TRUE;
+ }
+
+ rEntry.nField = nField ? (theQueryData.nCol1 +
+ static_cast<SCCOL>(nField) - 1) : static_cast<SCCOL>(0);
+ rEntry.eOp = eOp;
+ }
+ }
+
+ theParam.GetEntry(1).eConnect = (nConnect1 != LISTBOX_ENTRY_NOTFOUND)
+ ? (ScQueryConnect)nConnect1
+ : SC_AND;
+ theParam.GetEntry(2).eConnect = (nConnect2 != LISTBOX_ENTRY_NOTFOUND)
+ ? (ScQueryConnect)nConnect2
+ : SC_AND;
+
+ theParam.bInplace = FALSE;
+ theParam.nDestTab = 0; // Woher kommen diese Werte?
+ theParam.nDestCol = 0;
+ theParam.nDestRow = 0;
+
+ theParam.bDuplicate = !aBtnUnique.IsChecked();
+ theParam.bCaseSens = aBtnCase.IsChecked();
+ theParam.bRegExp = aBtnRegExp.IsChecked();
+
+ if ( pOutItem ) DELETEZ( pOutItem );
+ pOutItem = new ScQueryItem( nWhichQuery, &theParam );
+
+ return *pOutItem;
+}
+
+//------------------------------------------------------------------------
+// Handler:
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScPivotFilterDlg, LbSelectHdl, ListBox*, pLb )
+{
+ /*
+ * Behandlung der Enable/Disable-Logik,
+ * abhaengig davon, welche ListBox angefasst wurde:
+ */
+
+ if ( pLb == &aLbConnect1 )
+ {
+ if ( !aLbField2.IsEnabled() )
+ {
+ aLbField2.Enable();
+ aLbCond2.Enable();
+ aEdVal2.Enable();
+ }
+ }
+ else if ( pLb == &aLbConnect2 )
+ {
+ if ( !aLbField3.IsEnabled() )
+ {
+ aLbField3.Enable();
+ aLbCond3.Enable();
+ aEdVal3.Enable();
+ }
+ }
+ else if ( pLb == &aLbField1 )
+ {
+ if ( aLbField1.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect1.SetNoSelection();
+ aLbConnect2.SetNoSelection();
+ aLbField2.SelectEntryPos( 0 );
+ aLbField3.SelectEntryPos( 0 );
+ aLbCond2.SelectEntryPos( 0 );
+ aLbCond3.SelectEntryPos( 0 );
+ ClearValueList( 1 );
+ ClearValueList( 2 );
+ ClearValueList( 3 );
+
+ aLbConnect1.Disable();
+ aLbConnect2.Disable();
+ aLbField2.Disable();
+ aLbField3.Disable();
+ aLbCond2.Disable();
+ aLbCond3.Disable();
+ aEdVal2.Disable();
+ aEdVal3.Disable();
+ }
+ else
+ {
+ UpdateValueList( 1 );
+ if ( !aLbConnect1.IsEnabled() )
+ {
+ aLbConnect1.Enable();
+ }
+ }
+ }
+ else if ( pLb == &aLbField2 )
+ {
+ if ( aLbField2.GetSelectEntryPos() == 0 )
+ {
+ aLbConnect2.SetNoSelection();
+ aLbField3.SelectEntryPos( 0 );
+ aLbCond3.SelectEntryPos( 0 );
+ ClearValueList( 2 );
+ ClearValueList( 3 );
+
+ aLbConnect2.Disable();
+ aLbField3.Disable();
+ aLbCond3.Disable();
+ aEdVal3.Disable();
+ }
+ else
+ {
+ UpdateValueList( 2 );
+ if ( !aLbConnect2.IsEnabled() )
+ {
+ aLbConnect2.Enable();
+ }
+ }
+ }
+ else if ( pLb == &aLbField3 )
+ {
+ ( aLbField3.GetSelectEntryPos() == 0 )
+ ? ClearValueList( 3 )
+ : UpdateValueList( 3 );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScPivotFilterDlg, CheckBoxHdl, CheckBox*, pBox )
+{
+ // bei Gross-/Kleinschreibung die Werte-Listen aktualisieren
+
+ if ( pBox == &aBtnCase ) // Wertlisten
+ {
+ for (USHORT i=0; i<=MAXCOL; i++)
+ DELETEZ( pEntryLists[i] );
+
+ String aCurVal1 = aEdVal1.GetText();
+ String aCurVal2 = aEdVal2.GetText();
+ String aCurVal3 = aEdVal3.GetText();
+ UpdateValueList( 1 );
+ UpdateValueList( 2 );
+ UpdateValueList( 3 );
+ aEdVal1.SetText( aCurVal1 );
+ aEdVal2.SetText( aCurVal2 );
+ aEdVal3.SetText( aCurVal3 );
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScPivotFilterDlg, ValModifyHdl, ComboBox*, pEd )
+{
+ if ( pEd )
+ {
+ String aStrVal = pEd->GetText();
+ ListBox* pLb = &aLbCond1;
+
+ if ( pEd == &aEdVal2 ) pLb = &aLbCond2;
+ else if ( pEd == &aEdVal3 ) pLb = &aLbCond3;
+
+ // wenn einer der Sonderwerte leer/nicht-leer
+ // gewaehlt wird, so macht nur der =-Operator Sinn:
+
+ if ( aStrEmpty == aStrVal || aStrNotEmpty == aStrVal )
+ {
+ pLb->SelectEntry( '=' );
+ pLb->Disable();
+ }
+ else
+ pLb->Enable();
+ }
+
+ return 0;
+}
+
+
diff --git a/sc/source/ui/dbgui/pivot.hrc b/sc/source/ui/dbgui/pivot.hrc
new file mode 100644
index 000000000000..1a97d4c75b52
--- /dev/null
+++ b/sc/source/ui/dbgui/pivot.hrc
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc" // ->RID_SCDLG_PIVOT_LAYOUT
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+#define BTN_MORE 4
+#define BTN_REMOVE 5
+#define BTN_OPTIONS 6
+
+#define FL_LAYOUT 10
+#define WND_COL 11
+#define WND_ROW 12
+#define WND_DATA 13
+#define WND_SELECT 14
+#define WND_FIELD 15
+#define WND_FIELD_SPACE 16
+#define WND_HSCROLL 17
+#define WND_PAGE 18
+#define FT_COL 31
+#define FT_ROW 32
+#define FT_DATA 33
+#define STR_SELECT 34
+#define FT_PAGE 35
+
+#define PTR_FIELD 18
+#define FT_INFO 19
+
+#define FL_OUTPUT 20
+#define FT_OUTAREA 21
+#define LB_OUTAREA 22
+#define ED_OUTAREA 23
+#define RB_OUTAREA 24
+#define BTN_IGNEMPTYROWS 25
+#define BTN_DETECTCAT 26
+#define BTN_TOTALCOL 27
+#define BTN_TOTALROW 28
+#define BTN_FILTER 29
+#define BTN_DRILLDOWN 30
+
+#define FT_INAREA 40
+#define RB_INAREA 41
+#define ED_INAREA 42
+
+#define PIVOTSTR_SUM 1
+#define PIVOTSTR_COUNT 2
+#define PIVOTSTR_AVG 3
+#define PIVOTSTR_MAX 4
+#define PIVOTSTR_MIN 5
+#define PIVOTSTR_PROD 6
+#define PIVOTSTR_COUNT2 7
+#define PIVOTSTR_DEV 8
+#define PIVOTSTR_DEV2 9
+#define PIVOTSTR_VAR 10
+#define PIVOTSTR_VAR2 11
+
diff --git a/sc/source/ui/dbgui/pivot.src b/sc/source/ui/dbgui/pivot.src
new file mode 100644
index 000000000000..359c8a92d8e5
--- /dev/null
+++ b/sc/source/ui/dbgui/pivot.src
@@ -0,0 +1,328 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "pivot.hrc"
+
+ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+{
+ OutputSize = TRUE ;
+ HelpId = SID_OPENDLG_PIVOTTABLE ;
+ Size = MAP_APPFONT ( 336 , 190 ) ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Text [ en-US ] = "DataPilot" ;
+
+ FixedText FT_PAGE
+ {
+ Pos = MAP_APPFONT ( 194 , 168 ) ;
+ Size = MAP_APPFONT ( 37 , 8 ) ;
+ Text[ en-US ] = "Page Fields" ;
+ };
+ Control WND_PAGE
+ {
+ Pos = MAP_APPFONT ( 6 , 14 ) ;
+ Size = MAP_APPFONT ( 182 , 24 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_COL
+ {
+ Pos = MAP_APPFONT ( 231 , 168 ) ;
+ Size = MAP_APPFONT ( 37 , 8 ) ;
+ Text [ en-US ] = "Column Fields" ;
+ };
+ Control WND_COL
+ {
+ Pos = MAP_APPFONT ( 44 , 40 ) ;
+ Size = MAP_APPFONT ( 144 , 24 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_ROW
+ {
+ Pos = MAP_APPFONT ( 194 , 176 ) ;
+ Size = MAP_APPFONT ( 37 , 8 ) ;
+ Text [ en-US ] = "Row\nFields" ;
+ };
+ Control WND_ROW
+ {
+ Pos = MAP_APPFONT ( 6 , 66 ) ;
+ Size = MAP_APPFONT ( 36 , 96 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_DATA
+ {
+ Pos = MAP_APPFONT ( 231, 176 ) ;
+ Size = MAP_APPFONT ( 37 , 8 ) ;
+ Text [ en-US ] = "Data Fields" ;
+ };
+ Control WND_DATA
+ {
+ Pos = MAP_APPFONT ( 44 , 66 ) ;
+ Size = MAP_APPFONT ( 144 , 96 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_SELECT
+ {
+ Pos = MAP_APPFONT ( 194 , 14 ) ;
+ Size = MAP_APPFONT ( 70 , 126 ) ;
+ TabStop = TRUE ;
+ };
+ String STR_SELECT
+ {
+ Text [ en-US ] = "Selection area";
+ };
+ ScrollBar WND_HSCROLL
+ {
+ Pos = MAP_APPFONT ( 194 , 144 ) ;
+ Size = MAP_APPFONT ( 70 , 8 ) ;
+ HScroll = TRUE ;
+ TabStop = FALSE ;
+ };
+ FixedText FT_INFO
+ {
+ Pos = MAP_APPFONT ( 6 , 168 ) ;
+ Size = MAP_APPFONT ( 182 , 16 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "Drag the fields from the right into the desired position." ;
+ };
+ FixedLine FL_LAYOUT
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 268 , 8 ) ;
+ Text [ en-US ] = "Layout";
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 280 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 280 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 280 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 280 , 63 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Remove";
+ };
+ PushButton BTN_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 280 , 80 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Options...";
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 280 , 170 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 90 ;
+ };
+ Window WND_FIELD
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 36 , 12 ) ;
+ };
+ Window WND_FIELD_SPACE
+ {
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 2 , 2 ) ;
+ };
+ FixedLine FL_OUTPUT
+ {
+ Pos = MAP_APPFONT ( 6 , 190 ) ;
+ Size = MAP_APPFONT ( 268 , 8 ) ;
+ Text [ en-US ] = "Result" ;
+ Hide = TRUE ;
+ };
+
+ FixedText FT_INAREA
+ {
+ Pos = MAP_APPFONT ( 12 , 203 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Selection from" ;
+ };
+ Edit ED_INAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 73 , 201 ) ;
+ Size = MAP_APPFONT ( 100 , 12 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ };
+ ImageButton RB_INAREA
+ {
+ Pos = MAP_APPFONT ( 177 , 200 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+
+ FixedText FT_OUTAREA
+ {
+ Pos = MAP_APPFONT ( 12 , 221 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Results to" ;
+ };
+ ListBox LB_OUTAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 73 , 219 ) ;
+ Size = MAP_APPFONT ( 75 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Hide = TRUE ;
+ };
+ Edit ED_OUTAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 152 , 219 ) ;
+ Size = MAP_APPFONT ( 100 , 12 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ };
+ ImageButton RB_OUTAREA
+ {
+ Pos = MAP_APPFONT ( 256 , 218 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ CheckBox BTN_IGNEMPTYROWS
+ {
+ Pos = MAP_APPFONT ( 12 , 237 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Ignore ~empty rows" ;
+ };
+ CheckBox BTN_DETECTCAT
+ {
+ Pos = MAP_APPFONT ( 142 , 237 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "~Identify categories" ;
+ };
+ CheckBox BTN_TOTALCOL
+ {
+ Pos = MAP_APPFONT ( 12 , 251 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Total columns" ;
+ };
+ CheckBox BTN_TOTALROW
+ {
+ Pos = MAP_APPFONT ( 142 , 251 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "~Total rows" ;
+ };
+ CheckBox BTN_FILTER
+ {
+ Pos = MAP_APPFONT ( 12 , 265 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "~Add filter" ;
+ };
+ CheckBox BTN_DRILLDOWN
+ {
+ Pos = MAP_APPFONT ( 142 , 265 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Ena~ble drill to details" ;
+ };
+ String PIVOTSTR_SUM
+ {
+ Text [ en-US ] = "Sum - " ;
+ };
+ String PIVOTSTR_COUNT
+ {
+ Text [ en-US ] = "Count - " ;
+ };
+ String PIVOTSTR_AVG
+ {
+ Text [ en-US ] = "Mean - " ;
+ };
+ String PIVOTSTR_MAX
+ {
+ Text [ en-US ] = "Max - " ;
+ };
+ String PIVOTSTR_MIN
+ {
+ Text [ en-US ] = "Min - " ;
+ };
+ String PIVOTSTR_PROD
+ {
+ Text [ en-US ] = "Product - " ;
+ };
+ String PIVOTSTR_COUNT2
+ {
+ Text [ en-US ] = "Count - " ;
+ };
+ String PIVOTSTR_DEV
+ {
+ Text [ en-US ] = "StDev - " ;
+ };
+ String PIVOTSTR_DEV2
+ {
+ Text [ en-US ] = "StDevP - " ;
+ };
+ String PIVOTSTR_VAR
+ {
+ Text [ en-US ] = "Var - " ;
+ };
+ String PIVOTSTR_VAR2
+ {
+ Text [ en-US ] = "VarP - " ;
+ };
+};
+
diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx
new file mode 100644
index 000000000000..b5a19ef0ec9b
--- /dev/null
+++ b/sc/source/ui/dbgui/pvfundlg.cxx
@@ -0,0 +1,790 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+#include "pvfundlg.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+
+#include <tools/resary.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "scresid.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "pvfundlg.hrc"
+#include "globstr.hrc"
+
+#include <vector>
+
+// ============================================================================
+
+using namespace ::com::sun::star::sheet;
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::std::vector;
+
+// ============================================================================
+
+namespace {
+
+/** Appends all strings from the Sequence to the list box.
+
+ Empty strings are replaced by a localized "(empty)" entry and inserted at
+ the specified position.
+
+ @return true = The passed string list contains an empty string entry.
+ */
+template< typename ListBoxType >
+bool lclFillListBox( ListBoxType& rLBox, const Sequence< OUString >& rStrings, USHORT nEmptyPos = LISTBOX_APPEND )
+{
+ bool bEmpty = false;
+ if( const OUString* pStr = rStrings.getConstArray() )
+ {
+ for( const OUString* pEnd = pStr + rStrings.getLength(); pStr != pEnd; ++pStr )
+ {
+ if( pStr->getLength() )
+ rLBox.InsertEntry( *pStr );
+ else
+ {
+ rLBox.InsertEntry( ScGlobal::GetRscString( STR_EMPTYDATA ), nEmptyPos );
+ bEmpty = true;
+ }
+ }
+ }
+ return bEmpty;
+}
+
+template< typename ListBoxType >
+bool lclFillListBox( ListBoxType& rLBox, const vector<ScDPLabelData::Member>& rMembers, USHORT nEmptyPos = LISTBOX_APPEND )
+{
+ bool bEmpty = false;
+ vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ OUString aName = itr->getDisplayName();
+ if (aName.getLength())
+ rLBox.InsertEntry(aName);
+ else
+ {
+ rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos);
+ bEmpty = true;
+ }
+ }
+ return bEmpty;
+}
+
+/** Searches for a listbox entry, starts search at specified position. */
+USHORT lclFindListBoxEntry( const ListBox& rLBox, const String& rEntry, USHORT nStartPos )
+{
+ USHORT nPos = nStartPos;
+ while( (nPos < rLBox.GetEntryCount()) && (rLBox.GetEntry( nPos ) != rEntry) )
+ ++nPos;
+ return (nPos < rLBox.GetEntryCount()) ? nPos : LISTBOX_ENTRY_NOTFOUND;
+}
+
+/** This table represents the order of the strings in the resource string array. */
+static const USHORT spnFunctions[] =
+{
+ PIVOT_FUNC_SUM,
+ PIVOT_FUNC_COUNT,
+ PIVOT_FUNC_AVERAGE,
+ PIVOT_FUNC_MAX,
+ PIVOT_FUNC_MIN,
+ PIVOT_FUNC_PRODUCT,
+ PIVOT_FUNC_COUNT_NUM,
+ PIVOT_FUNC_STD_DEV,
+ PIVOT_FUNC_STD_DEVP,
+ PIVOT_FUNC_STD_VAR,
+ PIVOT_FUNC_STD_VARP
+};
+
+const USHORT SC_BASEITEM_PREV_POS = 0;
+const USHORT SC_BASEITEM_NEXT_POS = 1;
+const USHORT SC_BASEITEM_USER_POS = 2;
+
+const USHORT SC_SORTNAME_POS = 0;
+const USHORT SC_SORTDATA_POS = 1;
+
+const long SC_SHOW_DEFAULT = 10;
+
+static const ScDPListBoxWrapper::MapEntryType spRefTypeMap[] =
+{
+ { 0, DataPilotFieldReferenceType::NONE },
+ { 1, DataPilotFieldReferenceType::ITEM_DIFFERENCE },
+ { 2, DataPilotFieldReferenceType::ITEM_PERCENTAGE },
+ { 3, DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE },
+ { 4, DataPilotFieldReferenceType::RUNNING_TOTAL },
+ { 5, DataPilotFieldReferenceType::ROW_PERCENTAGE },
+ { 6, DataPilotFieldReferenceType::COLUMN_PERCENTAGE },
+ { 7, DataPilotFieldReferenceType::TOTAL_PERCENTAGE },
+ { 8, DataPilotFieldReferenceType::INDEX },
+ { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldReferenceType::NONE }
+};
+
+static const ScDPListBoxWrapper::MapEntryType spLayoutMap[] =
+{
+ { 0, DataPilotFieldLayoutMode::TABULAR_LAYOUT },
+ { 1, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP },
+ { 2, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM },
+ { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldLayoutMode::TABULAR_LAYOUT }
+};
+
+static const ScDPListBoxWrapper::MapEntryType spShowFromMap[] =
+{
+ { 0, DataPilotFieldShowItemsMode::FROM_TOP },
+ { 1, DataPilotFieldShowItemsMode::FROM_BOTTOM },
+ { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldShowItemsMode::FROM_TOP }
+};
+
+} // namespace
+
+// ============================================================================
+
+ScDPFunctionListBox::ScDPFunctionListBox( Window* pParent, const ResId& rResId ) :
+ MultiListBox( pParent, rResId )
+{
+ FillFunctionNames();
+}
+
+void ScDPFunctionListBox::SetSelection( USHORT nFuncMask )
+{
+ if( (nFuncMask == PIVOT_FUNC_NONE) || (nFuncMask == PIVOT_FUNC_AUTO) )
+ SetNoSelection();
+ else
+ for( USHORT nEntry = 0, nCount = GetEntryCount(); nEntry < nCount; ++nEntry )
+ SelectEntryPos( nEntry, (nFuncMask & spnFunctions[ nEntry ]) != 0 );
+}
+
+USHORT ScDPFunctionListBox::GetSelection() const
+{
+ USHORT nFuncMask = PIVOT_FUNC_NONE;
+ for( USHORT nSel = 0, nCount = GetSelectEntryCount(); nSel < nCount; ++nSel )
+ nFuncMask |= spnFunctions[ GetSelectEntryPos( nSel ) ];
+ return nFuncMask;
+}
+
+void ScDPFunctionListBox::FillFunctionNames()
+{
+ DBG_ASSERT( !GetEntryCount(), "ScDPFunctionListBox::FillFunctionNames - do not add texts to resource" );
+ Clear();
+ ResStringArray aArr( ScResId( SCSTR_DPFUNCLISTBOX ) );
+ for( USHORT nIndex = 0, nCount = sal::static_int_cast<USHORT>(aArr.Count()); nIndex < nCount; ++nIndex )
+ InsertEntry( aArr.GetString( nIndex ) );
+}
+
+// ============================================================================
+
+ScDPFunctionDlg::ScDPFunctionDlg(
+ Window* pParent, const ScDPLabelDataVec& rLabelVec,
+ const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DPDATAFIELD ) ),
+ maFlFunc ( this, ScResId( FL_FUNC ) ),
+ maLbFunc ( this, ScResId( LB_FUNC ) ),
+ maFtNameLabel ( this, ScResId( FT_NAMELABEL ) ),
+ maFtName ( this, ScResId( FT_NAME ) ),
+ maFlDisplay ( this, ScResId( FL_DISPLAY ) ),
+ maFtType ( this, ScResId( FT_TYPE ) ),
+ maLbType ( this, ScResId( LB_TYPE ) ),
+ maFtBaseField ( this, ScResId( FT_BASEFIELD ) ),
+ maLbBaseField ( this, ScResId( LB_BASEFIELD ) ),
+ maFtBaseItem ( this, ScResId( FT_BASEITEM ) ),
+ maLbBaseItem ( this, ScResId( LB_BASEITEM ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maBtnMore ( this, ScResId( BTN_MORE ) ),
+ maLbTypeWrp ( maLbType, spRefTypeMap ),
+ mrLabelVec ( rLabelVec ),
+ mbEmptyItem ( false )
+{
+ FreeResource();
+ Init( rLabelData, rFuncData );
+}
+
+USHORT ScDPFunctionDlg::GetFuncMask() const
+{
+ return maLbFunc.GetSelection();
+}
+
+DataPilotFieldReference ScDPFunctionDlg::GetFieldRef() const
+{
+ DataPilotFieldReference aRef;
+
+ aRef.ReferenceType = maLbTypeWrp.GetControlValue();
+ aRef.ReferenceField = maLbBaseField.GetSelectEntry();
+
+ USHORT nBaseItemPos = maLbBaseItem.GetSelectEntryPos();
+ switch( nBaseItemPos )
+ {
+ case SC_BASEITEM_PREV_POS:
+ aRef.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
+ break;
+ case SC_BASEITEM_NEXT_POS:
+ aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
+ break;
+ default:
+ {
+ aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
+ if( !mbEmptyItem || (nBaseItemPos > SC_BASEITEM_USER_POS) )
+ aRef.ReferenceItemName = maLbBaseItem.GetSelectEntry();
+ }
+ }
+
+ return aRef;
+}
+
+void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData )
+{
+ // list box
+ USHORT nFuncMask = (rFuncData.mnFuncMask == PIVOT_FUNC_NONE) ? PIVOT_FUNC_SUM : rFuncData.mnFuncMask;
+ maLbFunc.SetSelection( nFuncMask );
+
+ // field name
+ maFtName.SetText(rLabelData.getDisplayName());
+
+ // "More button" controls
+ maBtnMore.AddWindow( &maFlDisplay );
+ maBtnMore.AddWindow( &maFtType );
+ maBtnMore.AddWindow( &maLbType );
+ maBtnMore.AddWindow( &maFtBaseField );
+ maBtnMore.AddWindow( &maLbBaseField );
+ maBtnMore.AddWindow( &maFtBaseItem );
+ maBtnMore.AddWindow( &maLbBaseItem );
+
+ // handlers
+ maLbFunc.SetDoubleClickHdl( LINK( this, ScDPFunctionDlg, DblClickHdl ) );
+ maLbType.SetSelectHdl( LINK( this, ScDPFunctionDlg, SelectHdl ) );
+ maLbBaseField.SetSelectHdl( LINK( this, ScDPFunctionDlg, SelectHdl ) );
+
+ // base field list box
+ for( ScDPLabelDataVec::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt )
+ maLbBaseField.InsertEntry(aIt->getDisplayName());
+
+ // base item list box
+ maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 );
+
+ // select field reference type
+ maLbTypeWrp.SetControlValue( rFuncData.maFieldRef.ReferenceType );
+ SelectHdl( &maLbType ); // enables base field/item list boxes
+
+ // select base field
+ maLbBaseField.SelectEntry( rFuncData.maFieldRef.ReferenceField );
+ if( maLbBaseField.GetSelectEntryPos() >= maLbBaseField.GetEntryCount() )
+ maLbBaseField.SelectEntryPos( 0 );
+ SelectHdl( &maLbBaseField ); // fills base item list, selects base item
+
+ // select base item
+ switch( rFuncData.maFieldRef.ReferenceItemType )
+ {
+ case DataPilotFieldReferenceItemType::PREVIOUS:
+ maLbBaseItem.SelectEntryPos( SC_BASEITEM_PREV_POS );
+ break;
+ case DataPilotFieldReferenceItemType::NEXT:
+ maLbBaseItem.SelectEntryPos( SC_BASEITEM_NEXT_POS );
+ break;
+ default:
+ {
+ if( mbEmptyItem && !rFuncData.maFieldRef.ReferenceItemName.getLength() )
+ {
+ // select special "(empty)" entry added before other items
+ maLbBaseItem.SelectEntryPos( SC_BASEITEM_USER_POS );
+ }
+ else
+ {
+ USHORT nStartPos = mbEmptyItem ? (SC_BASEITEM_USER_POS + 1) : SC_BASEITEM_USER_POS;
+ USHORT nPos = lclFindListBoxEntry( maLbBaseItem, rFuncData.maFieldRef.ReferenceItemName, nStartPos );
+ if( nPos >= maLbBaseItem.GetEntryCount() )
+ nPos = (maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
+ maLbBaseItem.SelectEntryPos( nPos );
+ }
+ }
+ }
+}
+
+IMPL_LINK( ScDPFunctionDlg, SelectHdl, ListBox*, pLBox )
+{
+ if( pLBox == &maLbType )
+ {
+ bool bEnableField, bEnableItem;
+ switch( maLbTypeWrp.GetControlValue() )
+ {
+ case DataPilotFieldReferenceType::ITEM_DIFFERENCE:
+ case DataPilotFieldReferenceType::ITEM_PERCENTAGE:
+ case DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
+ bEnableField = bEnableItem = true;
+ break;
+
+ case DataPilotFieldReferenceType::RUNNING_TOTAL:
+ bEnableField = true;
+ bEnableItem = false;
+ break;
+
+ default:
+ bEnableField = bEnableItem = false;
+ }
+
+ bEnableField &= maLbBaseField.GetEntryCount() > 0;
+ maFtBaseField.Enable( bEnableField );
+ maLbBaseField.Enable( bEnableField );
+
+ bEnableItem &= bEnableField;
+ maFtBaseItem.Enable( bEnableItem );
+ maLbBaseItem.Enable( bEnableItem );
+ }
+ else if( pLBox == &maLbBaseField )
+ {
+ // keep "previous" and "next" entries
+ while( maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS )
+ maLbBaseItem.RemoveEntry( SC_BASEITEM_USER_POS );
+
+ // update item list for current base field
+ mbEmptyItem = false;
+ size_t nBasePos = maLbBaseField.GetSelectEntryPos();
+ if( nBasePos < mrLabelVec.size() )
+ mbEmptyItem = lclFillListBox( maLbBaseItem, mrLabelVec[ nBasePos ].maMembers, SC_BASEITEM_USER_POS );
+
+ // select base item
+ USHORT nItemPos = (maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
+ maLbBaseItem.SelectEntryPos( nItemPos );
+ }
+ return 0;
+}
+
+IMPL_LINK( ScDPFunctionDlg, DblClickHdl, MultiListBox*, EMPTYARG )
+{
+ maBtnOk.Click();
+ return 0;
+}
+
+// ============================================================================
+
+ScDPSubtotalDlg::ScDPSubtotalDlg( Window* pParent, ScDPObject& rDPObj,
+ const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData,
+ const ScDPNameVec& rDataFields, bool bEnableLayout ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_PIVOTSUBT ) ),
+ maFlSubt ( this, ScResId( FL_FUNC ) ),
+ maRbNone ( this, ScResId( RB_NONE ) ),
+ maRbAuto ( this, ScResId( RB_AUTO ) ),
+ maRbUser ( this, ScResId( RB_USER ) ),
+ maLbFunc ( this, ScResId( LB_FUNC ) ),
+ maFtNameLabel ( this, ScResId( FT_NAMELABEL ) ),
+ maFtName ( this, ScResId( FT_NAME ) ),
+ maCbShowAll ( this, ScResId( CB_SHOWALL ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maBtnOptions ( this, ScResId( BTN_OPTIONS ) ),
+ mrDPObj ( rDPObj ),
+ mrDataFields ( rDataFields ),
+ maLabelData ( rLabelData ),
+ mbEnableLayout ( bEnableLayout )
+{
+ FreeResource();
+ Init( rLabelData, rFuncData );
+}
+
+USHORT ScDPSubtotalDlg::GetFuncMask() const
+{
+ USHORT nFuncMask = PIVOT_FUNC_NONE;
+
+ if( maRbAuto.IsChecked() )
+ nFuncMask = PIVOT_FUNC_AUTO;
+ else if( maRbUser.IsChecked() )
+ nFuncMask = maLbFunc.GetSelection();
+
+ return nFuncMask;
+}
+
+void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
+{
+ rLabelData.mnFuncMask = GetFuncMask();
+ rLabelData.mnUsedHier = maLabelData.mnUsedHier;
+ rLabelData.mbShowAll = maCbShowAll.IsChecked();
+ rLabelData.maMembers = maLabelData.maMembers;
+ rLabelData.maSortInfo = maLabelData.maSortInfo;
+ rLabelData.maLayoutInfo = maLabelData.maLayoutInfo;
+ rLabelData.maShowInfo = maLabelData.maShowInfo;
+}
+
+void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData )
+{
+ // field name
+ maFtName.SetText(rLabelData.getDisplayName());
+
+ // radio buttons
+ maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
+ maRbAuto.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
+ maRbUser.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
+
+ RadioButton* pRBtn = 0;
+ switch( rFuncData.mnFuncMask )
+ {
+ case PIVOT_FUNC_NONE: pRBtn = &maRbNone; break;
+ case PIVOT_FUNC_AUTO: pRBtn = &maRbAuto; break;
+ default: pRBtn = &maRbUser;
+ }
+ pRBtn->Check();
+ RadioClickHdl( pRBtn );
+
+ // list box
+ maLbFunc.SetSelection( rFuncData.mnFuncMask );
+ maLbFunc.SetDoubleClickHdl( LINK( this, ScDPSubtotalDlg, DblClickHdl ) );
+
+ // show all
+ maCbShowAll.Check( rLabelData.mbShowAll );
+
+ // options
+ maBtnOptions.SetClickHdl( LINK( this, ScDPSubtotalDlg, ClickHdl ) );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPSubtotalDlg, RadioClickHdl, RadioButton*, pBtn )
+{
+ maLbFunc.Enable( pBtn == &maRbUser );
+ return 0;
+}
+
+IMPL_LINK( ScDPSubtotalDlg, DblClickHdl, MultiListBox*, EMPTYARG )
+{
+ maBtnOk.Click();
+ return 0;
+}
+
+IMPL_LINK( ScDPSubtotalDlg, ClickHdl, PushButton*, pBtn )
+{
+ if( pBtn == &maBtnOptions )
+ {
+ ScDPSubtotalOptDlg* pDlg = new ScDPSubtotalOptDlg( this, mrDPObj, maLabelData, mrDataFields, mbEnableLayout );
+ if( pDlg->Execute() == RET_OK )
+ pDlg->FillLabelData( maLabelData );
+ delete pDlg;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ScDPSubtotalOptDlg::ScDPSubtotalOptDlg( Window* pParent, ScDPObject& rDPObj,
+ const ScDPLabelData& rLabelData, const ScDPNameVec& rDataFields,
+ bool bEnableLayout ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DPSUBTOTAL_OPT ) ),
+ maFlSortBy ( this, ScResId( FL_SORT_BY ) ),
+ maLbSortBy ( this, ScResId( LB_SORT_BY ) ),
+ maRbSortAsc ( this, ScResId( RB_SORT_ASC ) ),
+ maRbSortDesc ( this, ScResId( RB_SORT_DESC ) ),
+ maRbSortMan ( this, ScResId( RB_SORT_MAN ) ),
+ maFlLayout ( this, ScResId( FL_LAYOUT ) ),
+ maFtLayout ( this, ScResId( FT_LAYOUT ) ),
+ maLbLayout ( this, ScResId( LB_LAYOUT ) ),
+ maCbLayoutEmpty ( this, ScResId( CB_LAYOUT_EMPTY ) ),
+ maFlAutoShow ( this, ScResId( FL_AUTOSHOW ) ),
+ maCbShow ( this, ScResId( CB_SHOW ) ),
+ maNfShow ( this, ScResId( NF_SHOW ) ),
+ maFtShow ( this, ScResId( FT_SHOW ) ),
+ maFtShowFrom ( this, ScResId( FT_SHOW_FROM ) ),
+ maLbShowFrom ( this, ScResId( LB_SHOW_FROM ) ),
+ maFtShowUsing ( this, ScResId( FT_SHOW_USING ) ),
+ maLbShowUsing ( this, ScResId( LB_SHOW_USING ) ),
+ maFlHide ( this, ScResId( FL_HIDE ) ),
+ maLbHide ( this, ScResId( CT_HIDE ) ),
+ maFtHierarchy ( this, ScResId( FT_HIERARCHY ) ),
+ maLbHierarchy ( this, ScResId( LB_HIERARCHY ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maLbLayoutWrp ( maLbLayout, spLayoutMap ),
+ maLbShowFromWrp ( maLbShowFrom, spShowFromMap ),
+ mrDPObj ( rDPObj ),
+ maLabelData ( rLabelData )
+{
+ FreeResource();
+ Init( rDataFields, bEnableLayout );
+}
+
+void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
+{
+ // *** SORTING ***
+
+ if( maRbSortMan.IsChecked() )
+ rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
+ else if( maLbSortBy.GetSelectEntryPos() == SC_SORTNAME_POS )
+ rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::NAME;
+ else
+ rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::DATA;
+
+ rLabelData.maSortInfo.Field = maLbSortBy.GetSelectEntry();
+ rLabelData.maSortInfo.IsAscending = maRbSortAsc.IsChecked();
+
+ // *** LAYOUT MODE ***
+
+ rLabelData.maLayoutInfo.LayoutMode = maLbLayoutWrp.GetControlValue();
+ rLabelData.maLayoutInfo.AddEmptyLines = maCbLayoutEmpty.IsChecked();
+
+ // *** AUTO SHOW ***
+
+ rLabelData.maShowInfo.IsEnabled = maCbShow.IsChecked();
+ rLabelData.maShowInfo.ShowItemsMode = maLbShowFromWrp.GetControlValue();
+ rLabelData.maShowInfo.ItemCount = sal::static_int_cast<sal_Int32>( maNfShow.GetValue() );
+ rLabelData.maShowInfo.DataField = maLbShowUsing.GetSelectEntry();
+
+ // *** HIDDEN ITEMS ***
+
+ rLabelData.maMembers = maLabelData.maMembers;
+ ULONG nVisCount = maLbHide.GetEntryCount();
+ for( USHORT nPos = 0; nPos < nVisCount; ++nPos )
+ rLabelData.maMembers[nPos].mbVisible = !maLbHide.IsChecked(nPos);
+
+ // *** HIERARCHY ***
+
+ rLabelData.mnUsedHier = maLbHierarchy.GetSelectEntryCount() ? maLbHierarchy.GetSelectEntryPos() : 0;
+}
+
+void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayout )
+{
+ // *** SORTING ***
+
+ sal_Int32 nSortMode = maLabelData.maSortInfo.Mode;
+
+ // sort fields list box
+ maLbSortBy.InsertEntry(maLabelData.getDisplayName());
+
+ for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt )
+ {
+ maLbSortBy.InsertEntry( *aIt );
+ maLbShowUsing.InsertEntry( *aIt ); // for AutoShow
+ }
+ if( maLbSortBy.GetEntryCount() > SC_SORTDATA_POS )
+ maLbSortBy.SetSeparatorPos( SC_SORTDATA_POS - 1 );
+
+ USHORT nSortPos = SC_SORTNAME_POS;
+ if( nSortMode == DataPilotFieldSortMode::DATA )
+ {
+ nSortPos = lclFindListBoxEntry( maLbSortBy, maLabelData.maSortInfo.Field, SC_SORTDATA_POS );
+ if( nSortPos >= maLbSortBy.GetEntryCount() )
+ {
+ nSortPos = SC_SORTNAME_POS;
+ nSortMode = DataPilotFieldSortMode::MANUAL;
+ }
+ }
+ maLbSortBy.SelectEntryPos( nSortPos );
+
+ // sorting mode
+ maRbSortAsc.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
+ maRbSortDesc.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
+ maRbSortMan.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
+
+ RadioButton* pRBtn = 0;
+ switch( nSortMode )
+ {
+ case DataPilotFieldSortMode::NONE:
+ case DataPilotFieldSortMode::MANUAL:
+ pRBtn = &maRbSortMan;
+ break;
+ default:
+ pRBtn = maLabelData.maSortInfo.IsAscending ? &maRbSortAsc : &maRbSortDesc;
+ }
+ pRBtn->Check();
+ RadioClickHdl( pRBtn );
+
+ // *** LAYOUT MODE ***
+
+ maFlLayout.Enable( bEnableLayout );
+ maFtLayout.Enable( bEnableLayout );
+ maLbLayout.Enable( bEnableLayout );
+ maCbLayoutEmpty.Enable( bEnableLayout );
+
+ maLbLayoutWrp.SetControlValue( maLabelData.maLayoutInfo.LayoutMode );
+ maCbLayoutEmpty.Check( maLabelData.maLayoutInfo.AddEmptyLines );
+
+ // *** AUTO SHOW ***
+
+ maCbShow.Check( maLabelData.maShowInfo.IsEnabled );
+ maCbShow.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, CheckHdl ) );
+
+ maLbShowFromWrp.SetControlValue( maLabelData.maShowInfo.ShowItemsMode );
+ long nCount = static_cast< long >( maLabelData.maShowInfo.ItemCount );
+ if( nCount < 1 )
+ nCount = SC_SHOW_DEFAULT;
+ maNfShow.SetValue( nCount );
+
+ // maLbShowUsing already filled above
+ maLbShowUsing.SelectEntry( maLabelData.maShowInfo.DataField );
+ if( maLbShowUsing.GetSelectEntryPos() >= maLbShowUsing.GetEntryCount() )
+ maLbShowUsing.SelectEntryPos( 0 );
+
+ CheckHdl( &maCbShow ); // enable/disable dependent controls
+
+ // *** HIDDEN ITEMS ***
+
+ maLbHide.SetHelpId( HID_SC_DPSUBT_HIDE );
+ InitHideListBox();
+
+ // *** HIERARCHY ***
+
+ if( maLabelData.maHiers.getLength() > 1 )
+ {
+ lclFillListBox( maLbHierarchy, maLabelData.maHiers );
+ sal_Int32 nHier = maLabelData.mnUsedHier;
+ if( (nHier < 0) || (nHier >= maLabelData.maHiers.getLength()) ) nHier = 0;
+ maLbHierarchy.SelectEntryPos( static_cast< USHORT >( nHier ) );
+ maLbHierarchy.SetSelectHdl( LINK( this, ScDPSubtotalOptDlg, SelectHdl ) );
+ }
+ else
+ {
+ maFtHierarchy.Disable();
+ maLbHierarchy.Disable();
+ }
+}
+
+void ScDPSubtotalOptDlg::InitHideListBox()
+{
+ maLbHide.Clear();
+ lclFillListBox( maLbHide, maLabelData.maMembers );
+ size_t n = maLabelData.maMembers.size();
+ for (size_t i = 0; i < n; ++i)
+ maLbHide.CheckEntryPos(static_cast<USHORT>(i), !maLabelData.maMembers[i].mbVisible);
+ bool bEnable = maLbHide.GetEntryCount() > 0;
+ maFlHide.Enable( bEnable );
+ maLbHide.Enable( bEnable );
+}
+
+IMPL_LINK( ScDPSubtotalOptDlg, RadioClickHdl, RadioButton*, pBtn )
+{
+ maLbSortBy.Enable( pBtn != &maRbSortMan );
+ return 0;
+}
+
+IMPL_LINK( ScDPSubtotalOptDlg, CheckHdl, CheckBox*, pCBox )
+{
+ if( pCBox == &maCbShow )
+ {
+ bool bEnable = maCbShow.IsChecked();
+ maNfShow.Enable( bEnable );
+ maFtShow.Enable( bEnable );
+ maFtShowFrom.Enable( bEnable );
+ maLbShowFrom.Enable( bEnable );
+
+ bool bEnableUsing = bEnable && (maLbShowUsing.GetEntryCount() > 0);
+ maFtShowUsing.Enable( bEnableUsing );
+ maLbShowUsing.Enable( bEnableUsing );
+ }
+ return 0;
+}
+
+IMPL_LINK( ScDPSubtotalOptDlg, SelectHdl, ListBox*, pLBox )
+{
+ if( pLBox == &maLbHierarchy )
+ {
+ mrDPObj.GetMembers(maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), maLabelData.maMembers);
+ InitHideListBox();
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHORT nOrient ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DPSHOWDETAIL ) ),
+ maFtDims ( this, ScResId( FT_DIMS ) ),
+ maLbDims ( this, ScResId( LB_DIMS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+
+ mrDPObj(rDPObj)
+{
+ FreeResource();
+
+ ScDPSaveData* pSaveData = rDPObj.GetSaveData();
+ long nDimCount = rDPObj.GetDimCount();
+ for (long nDim=0; nDim<nDimCount; nDim++)
+ {
+ BOOL bIsDataLayout;
+ sal_Int32 nDimFlags = 0;
+ String aName = rDPObj.GetDimName( nDim, bIsDataLayout, &nDimFlags );
+ if ( !bIsDataLayout && !rDPObj.IsDuplicated( nDim ) && ScDPObject::IsOrientationAllowed( nOrient, nDimFlags ) )
+ {
+ const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0;
+ if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
+ {
+ if (pDimension)
+ {
+ const OUString* pLayoutName = pDimension->GetLayoutName();
+ if (pLayoutName)
+ aName = *pLayoutName;
+ }
+ maLbDims.InsertEntry( aName );
+ maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
+ }
+ }
+ }
+ if( maLbDims.GetEntryCount() )
+ maLbDims.SelectEntryPos( 0 );
+
+ maLbDims.SetDoubleClickHdl( LINK( this, ScDPShowDetailDlg, DblClickHdl ) );
+}
+
+short ScDPShowDetailDlg::Execute()
+{
+ return maLbDims.GetEntryCount() ? ModalDialog::Execute() : RET_CANCEL;
+}
+
+String ScDPShowDetailDlg::GetDimensionName() const
+{
+ // Look up the internal dimension name which may be different from the
+ // displayed field name.
+ String aSelectedName = maLbDims.GetSelectEntry();
+ DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
+ if (itr == maNameIndexMap.end())
+ // This should never happen!
+ return aSelectedName;
+
+ long nDim = itr->second;
+ BOOL bIsDataLayout = false;
+ return mrDPObj.GetDimName(nDim, bIsDataLayout);
+}
+
+IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox )
+{
+ if( pLBox == &maLbDims )
+ maBtnOk.Click();
+ return 0;
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/dbgui/pvfundlg.hrc b/sc/source/ui/dbgui/pvfundlg.hrc
new file mode 100644
index 000000000000..c9b6f562a9e1
--- /dev/null
+++ b/sc/source/ui/dbgui/pvfundlg.hrc
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+// RID_SCDLG_DPDATAFIELD - DataPilot Data Field Function
+// RID_SCDLG_PIVOTSUBT - DataPilot Page/Row/Column Field Subtotals
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+#define BTN_MORE 4
+#define BTN_OPTIONS 5
+
+#define RB_NONE 1
+#define RB_AUTO 2
+#define RB_USER 3
+#define RB_SORT_ASC 4
+#define RB_SORT_DESC 5
+#define RB_SORT_MAN 6
+
+#define FL_FUNC 1
+#define FL_DISPLAY 2
+#define FL_SORT_BY 3
+#define FL_LAYOUT 4
+#define FL_AUTOSHOW 5
+#define FL_HIDE 6
+
+#define LB_FUNC 1
+#define LB_TYPE 2
+#define LB_BASEFIELD 3
+#define LB_BASEITEM 4
+#define LB_SORT_BY 5
+#define LB_LAYOUT 6
+#define LB_SHOW_FROM 7
+#define LB_SHOW_USING 8
+#define LB_HIERARCHY 9
+#define LB_DIMS 10
+
+#define FT_NAMELABEL 1
+#define FT_NAME 2
+#define FT_TYPE 3
+#define FT_BASEFIELD 4
+#define FT_BASEITEM 5
+#define FT_LAYOUT 6
+#define FT_SHOW 7
+#define FT_SHOW_FROM 8
+#define FT_SHOW_USING 9
+#define FT_HIERARCHY 10
+#define FT_DIMS 11
+
+#define CB_SHOWALL 1
+#define CB_LAYOUT_EMPTY 2
+#define CB_SHOW 3
+
+#define NF_SHOW 1
+
+#define CT_HIDE 1
+
diff --git a/sc/source/ui/dbgui/pvfundlg.src b/sc/source/ui/dbgui/pvfundlg.src
new file mode 100644
index 000000000000..ed00f6a65fa5
--- /dev/null
+++ b/sc/source/ui/dbgui/pvfundlg.src
@@ -0,0 +1,515 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "pvfundlg.hrc"
+
+StringArray SCSTR_DPFUNCLISTBOX
+{
+ ItemList [ en-US ] =
+ {
+ < "Sum" ; Default ; > ;
+ < "Count" ; Default ; > ;
+ < "Average" ; Default ; > ;
+ < "Max" ; Default ; > ;
+ < "Min" ; Default ; > ;
+ < "Product" ; Default ; > ;
+ < "Count (Numbers only)" ; Default ; > ;
+ < "StDev (Sample)" ; Default ; > ;
+ < "StDevP (Population)" ; Default ; > ;
+ < "Var (Sample)" ; Default ; > ;
+ < "VarP (Population)" ; Default ; > ;
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_DPDATAFIELD
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_DPDATAFIELD ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 220 , 99 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Hide = TRUE ;
+ FixedLine FL_FUNC
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 152 , 8 ) ;
+ Text [ en-US ] = "~Function" ;
+ };
+ MultiListBox LB_FUNC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 140 , 65 ) ;
+ TabStop = TRUE ;
+ AutoHScroll = TRUE ;
+ SimpleMode = TRUE ;
+ };
+ FixedText FT_NAMELABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 85 ) ;
+ Size = MAP_APPFONT ( 25 , 8 ) ;
+ Text [ en-US ] = "Name:" ;
+ };
+ FixedText FT_NAME
+ {
+ Pos = MAP_APPFONT ( 32 , 85 ) ;
+ Size = MAP_APPFONT ( 126 , 8 ) ;
+ };
+ FixedLine FL_DISPLAY
+ {
+ Pos = MAP_APPFONT( 6, 99 );
+ Size = MAP_APPFONT( 152, 8 );
+ Text [ en-US ] = "Displayed value";
+ };
+ FixedText FT_TYPE
+ {
+ Pos = MAP_APPFONT( 12, 112 );
+ Size = MAP_APPFONT( 60, 8 );
+ Text [ en-US ] = "~Type";
+ };
+ ListBox LB_TYPE
+ {
+ Pos = MAP_APPFONT( 75, 110 );
+ Size = MAP_APPFONT( 77, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ StringList [ en-US ] =
+ {
+ < "Normal"; Default; >;
+ < "Difference from"; Default; >;
+ < "% of"; Default; >;
+ < "% difference from"; Default; >;
+ < "Running total in"; Default; >;
+ < "% of row"; Default; >;
+ < "% of column"; Default; >;
+ < "% of total"; Default; >;
+ < "Index"; Default; >;
+ };
+ };
+ FixedText FT_BASEFIELD
+ {
+ Pos = MAP_APPFONT( 12, 128 );
+ Size = MAP_APPFONT( 60, 8 );
+ Text [ en-US ] = "~Base field";
+ };
+ ListBox LB_BASEFIELD
+ {
+ Pos = MAP_APPFONT( 75, 126 );
+ Size = MAP_APPFONT( 77, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ };
+ FixedText FT_BASEITEM
+ {
+ Pos = MAP_APPFONT( 12, 144 );
+ Size = MAP_APPFONT( 60, 8 );
+ Text [ en-US ] = "Ba~se item";
+ };
+ ListBox LB_BASEITEM
+ {
+ Pos = MAP_APPFONT( 75, 142 );
+ Size = MAP_APPFONT( 77, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ StringList [ en-US ] =
+ {
+ < "- previous item -"; Default; >;
+ < "- next item -"; Default; >;
+ };
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 164 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 164 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 164 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 164 , 79 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 61 ;
+ };
+ Text [ en-US ] = "Data Field" ;
+};
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_PIVOTSUBT
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_PIVOTSUBT ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 220 , 155 ) ;
+ Text [ en-US ] = "Data Field" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Hide = TRUE ;
+ RadioButton RB_NONE
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 140 , 10 ) ;
+ Text [ en-US ] = "~None" ;
+ TabStop = TRUE ;
+ };
+ RadioButton RB_AUTO
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 140 , 10 ) ;
+ Text [ en-US ] = "~Automatic" ;
+ TabStop = TRUE ;
+ };
+ RadioButton RB_USER
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 140 , 10 ) ;
+ Text [ en-US ] = "~User-defined" ;
+ TabStop = TRUE ;
+ };
+ MultiListBox LB_FUNC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 140 , 65 ) ;
+ TabStop = TRUE ;
+ AutoHScroll = TRUE ;
+ SimpleMode = TRUE ;
+ };
+ FixedLine FL_FUNC
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 152 , 8 ) ;
+ Text [ en-US ] = "Subtotals" ;
+ };
+ CheckBox CB_SHOWALL
+ {
+ Pos = MAP_APPFONT ( 6 , 127 ) ;
+ Size = MAP_APPFONT ( 152 , 10 ) ;
+ Text [ en-US ] = "Show it~ems without data";
+ TabStop = TRUE ;
+ };
+ FixedText FT_NAMELABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 141 ) ;
+ Size = MAP_APPFONT ( 25 , 8 ) ;
+ Text [ en-US ] = "Name:" ;
+ };
+ FixedText FT_NAME
+ {
+ Pos = MAP_APPFONT ( 32 , 141 ) ;
+ Size = MAP_APPFONT ( 126 , 8 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 164 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 164 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 164 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 164 , 135 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Options...";
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_DPSUBTOTAL_OPT
+{
+ OutputSize = TRUE;
+ HelpId = HID_SC_DPSUBT_OPT;
+ SVLook = TRUE;
+ Size = MAP_APPFONT( 266, 240 );
+ Moveable = TRUE;
+ Closeable = FALSE;
+ Hide = TRUE;
+ FixedLine FL_SORT_BY
+ {
+ Pos = MAP_APPFONT( 6, 3 );
+ Size = MAP_APPFONT( 198, 8 );
+ Text [ en-US ] = "Sort ~by";
+ };
+ ListBox LB_SORT_BY
+ {
+ Pos = MAP_APPFONT( 12, 26 );
+ Size = MAP_APPFONT( 96, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ };
+ RadioButton RB_SORT_ASC
+ {
+ Pos = MAP_APPFONT( 114, 14 );
+ Size = MAP_APPFONT( 84, 10 );
+ TabStop = TRUE;
+ Text [ en-US ] = "~Ascending";
+ };
+ RadioButton RB_SORT_DESC
+ {
+ Pos = MAP_APPFONT( 114, 28 );
+ Size = MAP_APPFONT( 84, 10 );
+ TabStop = TRUE;
+ Text [ en-US ] = "~Descending";
+ };
+ RadioButton RB_SORT_MAN
+ {
+ Pos = MAP_APPFONT( 114, 42 );
+ Size = MAP_APPFONT( 84, 10 );
+ TabStop = TRUE;
+ Text [ en-US ] = "~Manual";
+ };
+ FixedLine FL_LAYOUT
+ {
+ Pos = MAP_APPFONT( 6, 56 );
+ Size = MAP_APPFONT( 198, 8 );
+ Text [ en-US ] = "Display options";
+ };
+ FixedText FT_LAYOUT
+ {
+ Pos = MAP_APPFONT( 12, 69 );
+ Size = MAP_APPFONT( 70, 8 );
+ Text [ en-US ] = "~Layout";
+ };
+ ListBox LB_LAYOUT
+ {
+ Pos = MAP_APPFONT( 84, 67 );
+ Size = MAP_APPFONT( 114, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ StringList [ en-US ] =
+ {
+ < "Tabular layout"; Default; >;
+ < "Outline layout with subtotals at the top"; Default; >;
+ < "Outline layout with subtotals at the bottom"; Default; >;
+ };
+ };
+ CheckBox CB_LAYOUT_EMPTY
+ {
+ Pos = MAP_APPFONT( 12, 85 );
+ Size = MAP_APPFONT( 186, 10 );
+ TabStop = TRUE;
+ Text [ en-US ] = "~Empty line after each item";
+ };
+ FixedLine FL_AUTOSHOW
+ {
+ Pos = MAP_APPFONT( 6, 99 );
+ Size = MAP_APPFONT( 198, 8 );
+ Text [ en-US ] = "Show automatically";
+ };
+ CheckBox CB_SHOW
+ {
+ Pos = MAP_APPFONT( 12, 112 );
+ Size = MAP_APPFONT( 70, 10 );
+ TabStop = TRUE;
+ Text[ en-US ] = "~Show";
+ };
+ NumericField NF_SHOW
+ {
+ Pos = MAP_APPFONT( 84, 110 );
+ Size = MAP_APPFONT( 30, 12 );
+ TabStop = TRUE;
+ Border = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = 1;
+ Maximum = 999;
+ SpinSize = 1;
+ StrictFormat = TRUE;
+ };
+ FixedText FT_SHOW
+ {
+ Pos = MAP_APPFONT( 118, 112 );
+ Size = MAP_APPFONT( 80, 8 );
+ Text [ en-US ] = "items";
+ };
+ FixedText FT_SHOW_FROM
+ {
+ Pos = MAP_APPFONT( 22, 128 );
+ Size = MAP_APPFONT( 60, 8 );
+ Text [ en-US ] = "~From";
+ };
+ ListBox LB_SHOW_FROM
+ {
+ Pos = MAP_APPFONT( 84, 126 );
+ Size = MAP_APPFONT( 114, 50 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ StringList [ en-US ] =
+ {
+ < "Top"; Default; >;
+ < "Bottom"; Default; >;
+ };
+ };
+ FixedText FT_SHOW_USING
+ {
+ Pos = MAP_APPFONT( 22, 144 );
+ Size = MAP_APPFONT( 60, 8 );
+ Text [ en-US ] = "~Using field";
+ };
+ ListBox LB_SHOW_USING
+ {
+ Pos = MAP_APPFONT( 84, 142 );
+ Size = MAP_APPFONT( 114, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ };
+ FixedLine FL_HIDE
+ {
+ Pos = MAP_APPFONT( 6, 160 );
+ Size = MAP_APPFONT( 198, 8 );
+ Text [ en-US ] = "Hide i~tems";
+ };
+ Control CT_HIDE
+ {
+ Pos = MAP_APPFONT( 12, 171 );
+ Size = MAP_APPFONT( 186, 45 );
+ TabStop = TRUE;
+ Border = TRUE;
+ };
+ FixedText FT_HIERARCHY
+ {
+ Pos = MAP_APPFONT( 6, 224 );
+ Size = MAP_APPFONT( 76, 8 );
+ Text [ en-US ] = "Hierarch~y";
+ };
+ ListBox LB_HIERARCHY
+ {
+ Pos = MAP_APPFONT( 84, 222 );
+ Size = MAP_APPFONT( 114, 120 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = TRUE;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT( 210, 6 );
+ Size = MAP_APPFONT( 50, 14 );
+ TabStop = TRUE;
+ DefButton = TRUE;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT( 210, 23 );
+ Size = MAP_APPFONT( 50, 14 );
+ TabStop = TRUE;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT( 210, 43 );
+ Size = MAP_APPFONT( 50, 14 );
+ TabStop = TRUE;
+ };
+ Text [ en-US ] = "Data Field Options";
+};
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_DPSHOWDETAIL
+{
+ OutputSize = TRUE;
+ HelpId = HID_SC_DPSHOWDETAIL;
+ SVLook = TRUE;
+ Size = MAP_APPFONT( 200, 116 );
+ Moveable = TRUE;
+ Closeable = FALSE;
+ FixedText FT_DIMS
+ {
+ Pos = MAP_APPFONT( 6, 3 );
+ Size = MAP_APPFONT( 132, 24 );
+ WordBreak = TRUE;
+ Text [ en-US ] = "~Choose the field containing the detail you want to show";
+ };
+ ListBox LB_DIMS
+ {
+ Pos = MAP_APPFONT( 6, 30 );
+ Size = MAP_APPFONT( 132, 80 );
+ TabStop = TRUE;
+ Border = TRUE;
+ DropDown = FALSE;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT( 144, 6 );
+ Size = MAP_APPFONT( 50, 14 );
+ TabStop = TRUE;
+ DefButton = TRUE;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT( 144, 23 );
+ Size = MAP_APPFONT( 50, 14 );
+ TabStop = TRUE;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT( 144, 43 );
+ Size = MAP_APPFONT( 50, 14 );
+ TabStop = TRUE;
+ };
+ Text [ en-US ] = "Show Detail";
+};
+
+// ----------------------------------------------------------------------------
+
diff --git a/sc/source/ui/dbgui/pvglob.hxx b/sc/source/ui/dbgui/pvglob.hxx
new file mode 100644
index 000000000000..6b6526266035
--- /dev/null
+++ b/sc/source/ui/dbgui/pvglob.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PVGLOB_HXX
+#define SC_PVGLOB_HXX
+
+//-------------------------------------------------------------------
+
+class PivotGlobal
+{
+public:
+ static long nObjHeight;
+ static long nObjWidth;
+ static long nSelSpace;
+};
+
+
+#endif // SC_PVGLOB_HXX
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
new file mode 100644
index 000000000000..56d7e3550cda
--- /dev/null
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
@@ -0,0 +1,1823 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "pvlaydlg.hxx"
+#include "dbdocfun.hxx"
+
+#include <sfx2/dispatch.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+
+#include "uiitems.hxx"
+#include "rangeutl.hxx"
+#include "document.hxx"
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "reffact.hxx"
+#include "scresid.hxx"
+#include "pvglob.hxx"
+//CHINA001 #include "pvfundlg.hxx"
+#include "globstr.hrc"
+#include "pivot.hrc"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpshttab.hxx"
+#include "scmod.hxx"
+
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+using namespace com::sun::star;
+using ::rtl::OUString;
+using ::std::vector;
+
+//----------------------------------------------------------------------------
+
+#define FSTR(index) aFuncNameArr[index-1]
+#define STD_FORMAT SCA_VALID | SCA_TAB_3D \
+ | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
+
+long PivotGlobal::nObjHeight = 0; // initialized with resource data
+long PivotGlobal::nObjWidth = 0;
+long PivotGlobal::nSelSpace = 0;
+
+
+//============================================================================
+
+namespace {
+
+void lcl_FillToPivotField( PivotField& rPivotField, const ScDPFuncData& rFuncData )
+{
+ rPivotField.nCol = rFuncData.mnCol;
+ rPivotField.nFuncMask = rFuncData.mnFuncMask;
+ rPivotField.maFieldRef = rFuncData.maFieldRef;
+}
+
+PointerStyle lclGetPointerForField( ScDPFieldType eType )
+{
+ switch( eType )
+ {
+ case TYPE_PAGE: return POINTER_PIVOT_FIELD;
+ case TYPE_COL: return POINTER_PIVOT_COL;
+ case TYPE_ROW: return POINTER_PIVOT_ROW;
+ case TYPE_DATA: return POINTER_PIVOT_FIELD;
+ case TYPE_SELECT: return POINTER_PIVOT_FIELD;
+ }
+ return POINTER_ARROW;
+}
+
+} // namespace
+
+//============================================================================
+
+//----------------------------------------------------------------------------
+
+ScDPLayoutDlg::ScDPLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const ScDPObject& rDPObject )
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_PIVOT_LAYOUT ),
+ aFlLayout ( this, ScResId( FL_LAYOUT ) ),
+ aFtPage ( this, ScResId( FT_PAGE ) ),
+ aWndPage ( this, ScResId( WND_PAGE ), TYPE_PAGE, &aFtPage ),
+ aFtCol ( this, ScResId( FT_COL ) ),
+ aWndCol ( this, ScResId( WND_COL ), TYPE_COL, &aFtCol ),
+ aFtRow ( this, ScResId( FT_ROW ) ),
+ aWndRow ( this, ScResId( WND_ROW ), TYPE_ROW, &aFtRow ),
+ aFtData ( this, ScResId( FT_DATA ) ),
+ aWndData ( this, ScResId( WND_DATA ), TYPE_DATA, &aFtData ),
+ aWndSelect ( this, ScResId( WND_SELECT ), TYPE_SELECT, String(ScResId(STR_SELECT)) ),
+ aSlider ( this, ScResId( WND_HSCROLL ) ),
+ aFtInfo ( this, ScResId( FT_INFO ) ),
+
+ aFlAreas ( this, ScResId( FL_OUTPUT ) ),
+
+ aFtInArea ( this, ScResId( FT_INAREA) ),
+ aEdInPos ( this, ScResId( ED_INAREA) ),
+ aRbInPos ( this, ScResId( RB_INAREA ), &aEdInPos, this ),
+
+ aLbOutPos ( this, ScResId( LB_OUTAREA ) ),
+ aFtOutArea ( this, ScResId( FT_OUTAREA ) ),
+ aEdOutPos ( this, this, ScResId( ED_OUTAREA ) ),
+ aRbOutPos ( this, ScResId( RB_OUTAREA ), &aEdOutPos, this ),
+ aBtnIgnEmptyRows( this, ScResId( BTN_IGNEMPTYROWS ) ),
+ aBtnDetectCat ( this, ScResId( BTN_DETECTCAT ) ),
+ aBtnTotalCol ( this, ScResId( BTN_TOTALCOL ) ),
+ aBtnTotalRow ( this, ScResId( BTN_TOTALROW ) ),
+ aBtnFilter ( this, ScResId( BTN_FILTER ) ),
+ aBtnDrillDown ( this, ScResId( BTN_DRILLDOWN ) ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+ aBtnOptions ( this, ScResId( BTN_OPTIONS ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
+ aStrNewTable ( ScResId( SCSTR_NEWTABLE ) ),
+
+ bIsDrag ( FALSE ),
+
+ pEditActive ( NULL ),
+
+ eLastActiveType ( TYPE_SELECT ),
+ nOffset ( 0 ),
+ //
+ xDlgDPObject ( new ScDPObject( rDPObject ) ),
+ pViewData ( ((ScTabViewShell*)SfxViewShell::Current())->
+ GetViewData() ),
+ pDoc ( ((ScTabViewShell*)SfxViewShell::Current())->
+ GetViewData()->GetDocument() ),
+ bRefInputMode ( FALSE )
+{
+ xDlgDPObject->SetAlive( TRUE ); // needed to get structure information
+ xDlgDPObject->FillOldParam( thePivotData, FALSE );
+ xDlgDPObject->FillLabelData( thePivotData );
+
+ Init();
+ FreeResource();
+}
+
+
+//----------------------------------------------------------------------------
+
+ScDPLayoutDlg::~ScDPLayoutDlg()
+{
+ USHORT nEntries = aLbOutPos.GetEntryCount();
+ USHORT i;
+
+ for ( i=2; i<nEntries; i++ )
+ delete (String*)aLbOutPos.GetEntryData( i );
+}
+
+
+//----------------------------------------------------------------------------
+
+ScDPFieldWindow& ScDPLayoutDlg::GetFieldWindow( ScDPFieldType eType )
+{
+ switch( eType )
+ {
+ case TYPE_PAGE: return aWndPage;
+ case TYPE_ROW: return aWndRow;
+ case TYPE_COL: return aWndCol;
+ case TYPE_DATA: return aWndData;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return aWndSelect;
+}
+
+void __EXPORT ScDPLayoutDlg::Init()
+{
+ DBG_ASSERT( pViewData && pDoc,
+ "Ctor-Initialisierung fehlgeschlagen!" );
+
+ aBtnRemove.SetClickHdl( LINK( this, ScDPLayoutDlg, ClickHdl ) );
+ aBtnOptions.SetClickHdl( LINK( this, ScDPLayoutDlg, ClickHdl ) );
+
+ aFuncNameArr.reserve( FUNC_COUNT );
+ for ( USHORT i = 0; i < FUNC_COUNT; ++i )
+ aFuncNameArr.push_back( String( ScResId( i + 1 ) ) );
+
+ aBtnMore.AddWindow( &aFlAreas );
+ aBtnMore.AddWindow( &aFtInArea );
+ aBtnMore.AddWindow( &aEdInPos );
+ aBtnMore.AddWindow( &aRbInPos );
+ aBtnMore.AddWindow( &aFtOutArea );
+ aBtnMore.AddWindow( &aLbOutPos );
+ aBtnMore.AddWindow( &aEdOutPos );
+ aBtnMore.AddWindow( &aRbOutPos );
+ aBtnMore.AddWindow( &aBtnIgnEmptyRows );
+ aBtnMore.AddWindow( &aBtnDetectCat );
+ aBtnMore.AddWindow( &aBtnTotalCol );
+ aBtnMore.AddWindow( &aBtnTotalRow );
+ aBtnMore.AddWindow( &aBtnFilter );
+ aBtnMore.AddWindow( &aBtnDrillDown );
+ aBtnMore.SetClickHdl( LINK( this, ScDPLayoutDlg, MoreClickHdl ) );
+
+ {
+ Size aFieldSize( Window( this, ScResId( WND_FIELD ) ).GetSizePixel() );
+ OHEIGHT = aFieldSize.Height();
+ OWIDTH = aFieldSize.Width();
+ }
+ SSPACE = Window( this, ScResId( WND_FIELD_SPACE ) ).GetSizePixel().Width();
+
+ CalcWndSizes();
+
+ aSelectArr.resize( MAX_LABELS );
+ aPageArr.resize( MAX_PAGEFIELDS );
+ aColArr.resize( MAX_FIELDS );
+ aRowArr.resize( MAX_FIELDS );
+ aDataArr.resize( MAX_FIELDS );
+
+ ScRange inRange;
+ String inString;
+ if (xDlgDPObject->GetSheetDesc())
+ {
+ aEdInPos.Enable();
+ aRbInPos.Enable();
+ aOldRange = xDlgDPObject->GetSheetDesc()->aSourceRange;
+ aOldRange.Format( inString, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ aEdInPos.SetText(inString);
+ }
+ else
+ {
+ /* Data is not reachable, so could be a remote database */
+ aEdInPos.Disable();
+ aRbInPos.Disable();
+ }
+
+ InitFields();
+
+ aLbOutPos .SetSelectHdl( LINK( this, ScDPLayoutDlg, SelAreaHdl ) );
+ aEdOutPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdModifyHdl ) );
+ aEdInPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdInModifyHdl ) );
+ aBtnOk .SetClickHdl ( LINK( this, ScDPLayoutDlg, OkHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScDPLayoutDlg, CancelHdl ) );
+ Link aLink = LINK( this, ScDPLayoutDlg, GetFocusHdl );
+ if ( aEdInPos.IsEnabled() )
+ // Once disabled it will never get enabled, so no need to handle focus.
+ aEdInPos.SetGetFocusHdl( aLink );
+ aEdOutPos.SetGetFocusHdl( aLink );
+
+ if ( pViewData && pDoc )
+ {
+ /*
+ * Aus den RangeNames des Dokumentes werden nun die
+ * in einem Zeiger-Array gemerkt, bei denen es sich
+ * um sinnvolle Bereiche handelt
+ */
+
+ aLbOutPos.Clear();
+ aLbOutPos.InsertEntry( aStrUndefined, 0 );
+ aLbOutPos.InsertEntry( aStrNewTable, 1 );
+
+ ScAreaNameIterator aIter( pDoc );
+ String aName;
+ ScRange aRange;
+ String aRefStr;
+ while ( aIter.Next( aName, aRange ) )
+ {
+ if ( !aIter.WasDBName() ) // hier keine DB-Bereiche !
+ {
+ USHORT nInsert = aLbOutPos.InsertEntry( aName );
+
+ aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) );
+ }
+ }
+ }
+
+ if ( thePivotData.nTab != MAXTAB+1 )
+ {
+ String aStr;
+ ScAddress( thePivotData.nCol,
+ thePivotData.nRow,
+ thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() );
+ aEdOutPos.SetText( aStr );
+ EdModifyHdl(0);
+ }
+ else
+ {
+ aLbOutPos.SelectEntryPos( aLbOutPos.GetEntryCount()-1 );
+ SelAreaHdl(NULL);
+ }
+
+ aBtnIgnEmptyRows.Check( thePivotData.bIgnoreEmptyRows );
+ aBtnDetectCat .Check( thePivotData.bDetectCategories );
+ aBtnTotalCol .Check( thePivotData.bMakeTotalCol );
+ aBtnTotalRow .Check( thePivotData.bMakeTotalRow );
+
+ if( const ScDPSaveData* pSaveData = xDlgDPObject->GetSaveData() )
+ {
+ aBtnFilter.Check( pSaveData->GetFilterButton() );
+ aBtnDrillDown.Check( pSaveData->GetDrillDown() );
+ }
+ else
+ {
+ aBtnFilter.Check();
+ aBtnDrillDown.Check();
+ }
+
+ aWndPage.SetHelpId( HID_SC_DPLAY_PAGE );
+ aWndCol.SetHelpId( HID_SC_DPLAY_COLUMN );
+ aWndRow.SetHelpId( HID_SC_DPLAY_ROW );
+ aWndData.SetHelpId( HID_SC_DPLAY_DATA );
+ aWndSelect.SetHelpId( HID_SC_DPLAY_SELECT );
+
+ InitFocus();
+
+// SetDispatcherLock( TRUE ); // Modal-Modus einschalten
+
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScDPLayoutDlg::Close()
+{
+ return DoClose( ScPivotLayoutWrapper::GetChildWindowId() );
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::StateChanged( StateChangedType nStateChange )
+{
+ ScAnyRefDlg::StateChanged( nStateChange );
+
+ if ( nStateChange == STATE_CHANGE_INITSHOW )
+ {
+ // #124828# Hiding the FixedTexts and clearing the tab stop style bits
+ // has to be done after assigning the mnemonics, but Paint is too late,
+ // because the test tool may send key events to the dialog when it isn't visible.
+ // Mnemonics are assigned in the Dialog::StateChanged for STATE_CHANGE_INITSHOW,
+ // so this can be done immediately afterwards.
+
+ aWndPage.UseMnemonic();
+ aWndCol.UseMnemonic();
+ aWndRow.UseMnemonic();
+ aWndData.UseMnemonic();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::InitWndSelect( const vector<ScDPLabelDataRef>& rLabels )
+{
+ size_t nLabelCount = rLabels.size();
+ if (nLabelCount > MAX_LABELS)
+ nLabelCount = MAX_LABELS;
+ size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1);
+
+ aLabelDataArr.clear();
+ aLabelDataArr.reserve( nLabelCount );
+ for ( size_t i=0; i < nLabelCount; i++ )
+ {
+ aLabelDataArr.push_back(*rLabels[i]);
+
+ if ( i <= nLast )
+ {
+ aWndSelect.AddField(aLabelDataArr[i].getDisplayName(), i);
+ aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) );
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::InitWnd( PivotField* pArr, long nCount, ScDPFieldType eType )
+{
+ if ( pArr && (eType != TYPE_SELECT) )
+ {
+ ScDPFuncDataVec* pInitArr = NULL;
+ ScDPFieldWindow* pInitWnd = NULL;
+ BOOL bDataArr = FALSE;
+
+ switch ( eType )
+ {
+ case TYPE_PAGE:
+ pInitArr = &aPageArr;
+ pInitWnd = &aWndPage;
+ break;
+
+ case TYPE_COL:
+ pInitArr = &aColArr;
+ pInitWnd = &aWndCol;
+ break;
+
+ case TYPE_ROW:
+ pInitArr = &aRowArr;
+ pInitWnd = &aWndRow;
+ break;
+
+ case TYPE_DATA:
+ pInitArr = &aDataArr;
+ pInitWnd = &aWndData;
+ bDataArr = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ if ( pInitArr && pInitWnd )
+ {
+ long j=0;
+ for ( long i=0; (i<nCount); i++ )
+ {
+ SCCOL nCol = pArr[i].nCol;
+ USHORT nMask = pArr[i].nFuncMask;
+
+ if ( nCol != PIVOT_DATA_FIELD )
+ {
+ (*pInitArr)[j].reset( new ScDPFuncData( nCol, nMask, pArr[i].maFieldRef ) );
+
+ if ( !bDataArr )
+ {
+ pInitWnd->AddField( GetLabelString( nCol ), j );
+ }
+ else
+ {
+ ScDPLabelData* pData = GetLabelData( nCol );
+ DBG_ASSERT( pData, "ScDPLabelData not found" );
+ if (pData)
+ {
+ String aStr( GetFuncString( (*pInitArr)[j]->mnFuncMask,
+ pData->mbIsValue ) );
+
+ aStr += GetLabelString( nCol );
+ pInitWnd->AddField( aStr, j );
+
+ pData->mnFuncMask = nMask;
+ }
+ }
+ ++j;
+ }
+ }
+// Do not redraw here -> first the FixedText has to get its mnemonic char
+// pInitWnd->Redraw();
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::InitFocus()
+{
+ if( aWndSelect.IsEmpty() )
+ {
+ aBtnOk.GrabFocus();
+ NotifyFieldFocus( TYPE_SELECT, FALSE );
+ }
+ else
+ aWndSelect.GrabFocus();
+}
+
+void ScDPLayoutDlg::InitFields()
+{
+ InitWndSelect(thePivotData.maLabelArray);
+ InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE );
+ InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL );
+ InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW );
+ InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA );
+
+ size_t nLabels = thePivotData.maLabelArray.size();
+ aSlider.SetPageSize( PAGE_SIZE );
+ aSlider.SetVisibleSize( PAGE_SIZE );
+ aSlider.SetLineSize( LINE_SIZE );
+ aSlider.SetRange( Range( 0, static_cast<long>(((nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
+
+ if ( nLabels > PAGE_SIZE )
+ {
+ aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) );
+ aSlider.Show();
+ }
+ else
+ aSlider.Hide();
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos )
+{
+ ScDPFuncData fData( *(aSelectArr[nFromIndex]) );
+ size_t nAt = 0;
+ ScDPFieldWindow* toWnd = NULL;
+ ScDPFieldWindow* rmWnd1 = NULL;
+ ScDPFieldWindow* rmWnd2 = NULL;
+ ScDPFuncDataVec* toArr = NULL;
+ ScDPFuncDataVec* rmArr1 = NULL;
+ ScDPFuncDataVec* rmArr2 = NULL;
+ BOOL bDataArr = FALSE;
+
+ switch ( eToType )
+ {
+ case TYPE_PAGE:
+ toWnd = &aWndPage;
+ rmWnd1 = &aWndRow;
+ rmWnd2 = &aWndCol;
+ toArr = &aPageArr;
+ rmArr1 = &aRowArr;
+ rmArr2 = &aColArr;
+ break;
+
+ case TYPE_COL:
+ toWnd = &aWndCol;
+ rmWnd1 = &aWndPage;
+ rmWnd2 = &aWndRow;
+ toArr = &aColArr;
+ rmArr1 = &aPageArr;
+ rmArr2 = &aRowArr;
+ break;
+
+ case TYPE_ROW:
+ toWnd = &aWndRow;
+ rmWnd1 = &aWndPage;
+ rmWnd2 = &aWndCol;
+ toArr = &aRowArr;
+ rmArr1 = &aPageArr;
+ rmArr2 = &aColArr;
+ break;
+
+ case TYPE_DATA:
+ toWnd = &aWndData;
+ toArr = &aDataArr;
+ bDataArr = TRUE;
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType );
+ if ( bAllowed
+ && (toArr->back().get() == NULL)
+ && (!Contains( toArr, fData.mnCol, nAt )) )
+ {
+ // ggF. in anderem Fenster entfernen
+ if ( rmArr1 )
+ {
+ if ( Contains( rmArr1, fData.mnCol, nAt ) )
+ {
+ rmWnd1->DelField( nAt );
+ Remove( rmArr1, nAt );
+ }
+ }
+ if ( rmArr2 )
+ {
+ if ( Contains( rmArr2, fData.mnCol, nAt ) )
+ {
+ rmWnd2->DelField( nAt );
+ Remove( rmArr2, nAt );
+ }
+ }
+
+ ScDPLabelData& rData = aLabelDataArr[nFromIndex+nOffset];
+ size_t nAddedAt = 0;
+
+ if ( !bDataArr )
+ {
+ if ( toWnd->AddField( rData.getDisplayName(),
+ DlgPos2WndPos( rAtPos, *toWnd ),
+ nAddedAt ) )
+ {
+ Insert( toArr, fData, nAddedAt );
+ toWnd->GrabFocus();
+ }
+ }
+ else
+ {
+ USHORT nMask = fData.mnFuncMask;
+ OUString aStr = GetFuncString( nMask, rData.mbIsValue );
+
+ aStr += rData.getDisplayName();
+
+ if ( toWnd->AddField( aStr,
+ DlgPos2WndPos( rAtPos, *toWnd ),
+ nAddedAt ) )
+ {
+ fData.mnFuncMask = nMask;
+ Insert( toArr, fData, nAddedAt );
+ toWnd->GrabFocus();
+ }
+ }
+
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos )
+{
+ if ( eFromType == TYPE_SELECT )
+ AddField( nFromIndex, eToType, rAtPos );
+ else if ( eFromType != eToType )
+ {
+ ScDPFieldWindow* fromWnd = NULL;
+ ScDPFieldWindow* toWnd = NULL;
+ ScDPFieldWindow* rmWnd1 = NULL;
+ ScDPFieldWindow* rmWnd2 = NULL;
+ ScDPFuncDataVec* fromArr = NULL;
+ ScDPFuncDataVec* toArr = NULL;
+ ScDPFuncDataVec* rmArr1 = NULL;
+ ScDPFuncDataVec* rmArr2 = NULL;
+ size_t nAt = 0;
+ BOOL bDataArr = FALSE;
+
+ switch ( eFromType )
+ {
+ case TYPE_PAGE:
+ fromWnd = &aWndPage;
+ fromArr = &aPageArr;
+ break;
+
+ case TYPE_COL:
+ fromWnd = &aWndCol;
+ fromArr = &aColArr;
+ break;
+
+ case TYPE_ROW:
+ fromWnd = &aWndRow;
+ fromArr = &aRowArr;
+ break;
+
+ case TYPE_DATA:
+ fromWnd = &aWndData;
+ fromArr = &aDataArr;
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ switch ( eToType )
+ {
+ case TYPE_PAGE:
+ toWnd = &aWndPage;
+ toArr = &aPageArr;
+ rmWnd1 = &aWndCol;
+ rmWnd2 = &aWndRow;
+ rmArr1 = &aColArr;
+ rmArr2 = &aRowArr;
+ break;
+
+ case TYPE_COL:
+ toWnd = &aWndCol;
+ toArr = &aColArr;
+ rmWnd1 = &aWndPage;
+ rmWnd2 = &aWndRow;
+ rmArr1 = &aPageArr;
+ rmArr2 = &aRowArr;
+ break;
+
+ case TYPE_ROW:
+ toWnd = &aWndRow;
+ toArr = &aRowArr;
+ rmWnd1 = &aWndPage;
+ rmWnd2 = &aWndCol;
+ rmArr1 = &aPageArr;
+ rmArr2 = &aColArr;
+ break;
+
+ case TYPE_DATA:
+ toWnd = &aWndData;
+ toArr = &aDataArr;
+ bDataArr = TRUE;
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if ( fromArr && toArr && fromWnd && toWnd )
+ {
+ ScDPFuncData fData( *((*fromArr)[nFromIndex]) );
+
+ bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType );
+ if ( bAllowed && Contains( fromArr, fData.mnCol, nAt ) )
+ {
+ fromWnd->DelField( nAt );
+ Remove( fromArr, nAt );
+
+ if ( (toArr->back().get() == NULL)
+ && (!Contains( toArr, fData.mnCol, nAt )) )
+ {
+ size_t nAddedAt = 0;
+ if ( !bDataArr )
+ {
+ // ggF. in anderem Fenster entfernen
+ if ( rmArr1 )
+ {
+ if ( Contains( rmArr1, fData.mnCol, nAt ) )
+ {
+ rmWnd1->DelField( nAt );
+ Remove( rmArr1, nAt );
+ }
+ }
+ if ( rmArr2 )
+ {
+ if ( Contains( rmArr2, fData.mnCol, nAt ) )
+ {
+ rmWnd2->DelField( nAt );
+ Remove( rmArr2, nAt );
+ }
+ }
+
+ if ( toWnd->AddField( GetLabelString( fData.mnCol ),
+ DlgPos2WndPos( rAtPos, *toWnd ),
+ nAddedAt ) )
+ {
+ Insert( toArr, fData, nAddedAt );
+ toWnd->GrabFocus();
+ }
+ }
+ else
+ {
+ String aStr;
+ USHORT nMask = fData.mnFuncMask;
+ aStr = GetFuncString( nMask );
+ aStr += GetLabelString( fData.mnCol );
+
+ if ( toWnd->AddField( aStr,
+ DlgPos2WndPos( rAtPos, *toWnd ),
+ nAddedAt ) )
+ {
+ fData.mnFuncMask = nMask;
+ Insert( toArr, fData, nAddedAt );
+ toWnd->GrabFocus();
+ }
+ }
+ }
+ }
+ }
+ }
+ else // -> eFromType == eToType
+ {
+ ScDPFieldWindow* theWnd = NULL;
+ ScDPFuncDataVec* theArr = NULL;
+ size_t nAt = 0;
+ size_t nToIndex = 0;
+ Point aToPos;
+ BOOL bDataArr = FALSE;
+
+ switch ( eFromType )
+ {
+ case TYPE_PAGE:
+ theWnd = &aWndPage;
+ theArr = &aPageArr;
+ break;
+
+ case TYPE_COL:
+ theWnd = &aWndCol;
+ theArr = &aColArr;
+ break;
+
+ case TYPE_ROW:
+ theWnd = &aWndRow;
+ theArr = &aRowArr;
+ break;
+
+ case TYPE_DATA:
+ theWnd = &aWndData;
+ theArr = &aDataArr;
+ bDataArr = TRUE;
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ ScDPFuncData fData( *((*theArr)[nFromIndex]) );
+
+ if ( Contains( theArr, fData.mnCol, nAt ) )
+ {
+ aToPos = DlgPos2WndPos( rAtPos, *theWnd );
+ theWnd->GetExistingIndex( aToPos, nToIndex );
+
+ if ( nToIndex != nAt )
+ {
+ size_t nAddedAt = 0;
+
+ theWnd->DelField( nAt );
+ Remove( theArr, nAt );
+
+ if ( !bDataArr )
+ {
+ if ( theWnd->AddField( GetLabelString( fData.mnCol ),
+ aToPos,
+ nAddedAt ) )
+ {
+ Insert( theArr, fData, nAddedAt );
+ }
+ }
+ else
+ {
+ String aStr;
+ USHORT nMask = fData.mnFuncMask;
+ aStr = GetFuncString( nMask );
+ aStr += GetLabelString( fData.mnCol );
+
+ if ( theWnd->AddField( aStr,
+ DlgPos2WndPos( rAtPos, *theWnd ),
+ nAddedAt ) )
+ {
+ fData.mnFuncMask = nMask;
+ Insert( theArr, fData, nAddedAt );
+ }
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::RemoveField( ScDPFieldType eFromType, size_t nIndex )
+{
+ ScDPFuncDataVec* pArr = NULL;
+ switch( eFromType )
+ {
+ case TYPE_PAGE: pArr = &aPageArr; break;
+ case TYPE_COL: pArr = &aColArr; break;
+ case TYPE_ROW: pArr = &aRowArr; break;
+ case TYPE_DATA: pArr = &aDataArr; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if( pArr )
+ {
+ ScDPFieldWindow& rWnd = GetFieldWindow( eFromType );
+ rWnd.DelField( nIndex );
+ Remove( pArr, nIndex );
+ if( rWnd.IsEmpty() ) InitFocus();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::NotifyMouseButtonUp( const Point& rAt )
+{
+ if ( bIsDrag )
+ {
+ bIsDrag = FALSE;
+
+ ScDPFieldType eDnDToType = TYPE_SELECT;
+ Point aPos = ScreenToOutputPixel( rAt );
+ BOOL bDel = FALSE;
+
+ if ( aRectPage.IsInside( aPos ) )
+ {
+ eDnDToType = TYPE_PAGE;
+ bDel = FALSE;
+ }
+ else if ( aRectCol.IsInside( aPos ) )
+ {
+ eDnDToType = TYPE_COL;
+ bDel = FALSE;
+ }
+ else if ( aRectRow.IsInside( aPos ) )
+ {
+ eDnDToType = TYPE_ROW;
+ bDel = FALSE;
+ }
+ else if ( aRectData.IsInside( aPos ) )
+ {
+ eDnDToType = TYPE_DATA;
+ bDel = FALSE;
+ }
+ else if ( aRectSelect.IsInside( aPos ) )
+ {
+ eDnDToType = TYPE_SELECT;
+ bDel = TRUE;
+ }
+ else
+ bDel = TRUE;
+
+ if ( bDel )
+ RemoveField( eDnDFromType, nDnDFromIndex );
+ else
+ MoveField( eDnDFromType, nDnDFromIndex, eDnDToType, aPos );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+PointerStyle ScDPLayoutDlg::NotifyMouseMove( const Point& rAt )
+{
+ PointerStyle ePtr = POINTER_ARROW;
+
+ if ( bIsDrag )
+ {
+ Point aPos = ScreenToOutputPixel( rAt );
+ ScDPFieldType eCheckTarget = TYPE_SELECT;
+
+ if ( aRectPage.IsInside( aPos ) )
+ eCheckTarget = TYPE_PAGE;
+ else if ( aRectCol.IsInside( aPos ) )
+ eCheckTarget = TYPE_COL;
+ else if ( aRectRow.IsInside( aPos ) )
+ eCheckTarget = TYPE_ROW;
+ else if ( aRectData.IsInside( aPos ) )
+ eCheckTarget = TYPE_DATA;
+ else if ( eDnDFromType != TYPE_SELECT )
+ ePtr = POINTER_PIVOT_DELETE;
+ else if ( aRectSelect.IsInside( aPos ) )
+ ePtr = lclGetPointerForField( TYPE_SELECT );
+ else
+ ePtr = POINTER_NOTALLOWED;
+
+ if ( eCheckTarget != TYPE_SELECT )
+ {
+ // check if the target orientation is allowed for this field
+ ScDPFuncDataVec* fromArr = NULL;
+ switch ( eDnDFromType )
+ {
+ case TYPE_PAGE: fromArr = &aPageArr; break;
+ case TYPE_COL: fromArr = &aColArr; break;
+ case TYPE_ROW: fromArr = &aRowArr; break;
+ case TYPE_DATA: fromArr = &aDataArr; break;
+ case TYPE_SELECT: fromArr = &aSelectArr; break;
+ }
+ ScDPFuncData fData( *((*fromArr)[nDnDFromIndex]) );
+ if (IsOrientationAllowed( fData.mnCol, eCheckTarget ))
+ ePtr = lclGetPointerForField( eCheckTarget );
+ else
+ ePtr = POINTER_NOTALLOWED;
+ }
+ }
+
+ return ePtr;
+}
+
+
+//----------------------------------------------------------------------------
+
+PointerStyle ScDPLayoutDlg::NotifyMouseButtonDown( ScDPFieldType eType, size_t nFieldIndex )
+{
+ bIsDrag = TRUE;
+ eDnDFromType = eType;
+ nDnDFromIndex = nFieldIndex;
+ return lclGetPointerForField( eType );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::NotifyDoubleClick( ScDPFieldType eType, size_t nFieldIndex )
+{
+ ScDPFuncDataVec* pArr = NULL;
+ switch ( eType )
+ {
+ case TYPE_PAGE: pArr = &aPageArr; break;
+ case TYPE_COL: pArr = &aColArr; break;
+ case TYPE_ROW: pArr = &aRowArr; break;
+ case TYPE_DATA: pArr = &aDataArr; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if ( pArr )
+ {
+ if ( nFieldIndex >= pArr->size() )
+ {
+ DBG_ERROR("invalid selection");
+ return;
+ }
+
+ size_t nArrPos = 0;
+ if( ScDPLabelData* pData = GetLabelData( (*pArr)[nFieldIndex]->mnCol, &nArrPos ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ switch ( eType )
+ {
+ case TYPE_PAGE:
+ case TYPE_COL:
+ case TYPE_ROW:
+ {
+ // list of names of all data fields
+ std::vector< String > aDataFieldNames;
+ for( ScDPFuncDataVec::const_iterator aIt = aDataArr.begin(), aEnd = aDataArr.end();
+ (aIt != aEnd) && aIt->get(); ++aIt )
+ {
+ String aName( GetLabelString( (*aIt)->mnCol ) );
+ if( aName.Len() )
+ aDataFieldNames.push_back( aName );
+ }
+
+ bool bLayout = (eType == TYPE_ROW) &&
+ ((aDataFieldNames.size() > 1) || ((nFieldIndex + 1 < pArr->size()) && (*pArr)[nFieldIndex+1].get()));
+
+ AbstractScDPSubtotalDlg* pDlg = pFact->CreateScDPSubtotalDlg(
+ this, RID_SCDLG_PIVOTSUBT,
+ *xDlgDPObject, *pData, *(*pArr)[nFieldIndex], aDataFieldNames, bLayout );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ pDlg->FillLabelData( *pData );
+ (*pArr)[nFieldIndex]->mnFuncMask = pData->mnFuncMask;
+ }
+ delete pDlg;
+ }
+ break;
+
+ case TYPE_DATA:
+ {
+ AbstractScDPFunctionDlg* pDlg = pFact->CreateScDPFunctionDlg(
+ this, RID_SCDLG_DPDATAFIELD,
+ aLabelDataArr, *pData, *(*pArr)[nFieldIndex] );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ (*pArr)[nFieldIndex]->mnFuncMask = pData->mnFuncMask = pDlg->GetFuncMask();
+ (*pArr)[nFieldIndex]->maFieldRef = pDlg->GetFieldRef();
+
+ String aStr( GetFuncString ( aDataArr[nFieldIndex]->mnFuncMask ) );
+ aStr += GetLabelString( aDataArr[nFieldIndex]->mnCol );
+ aWndData.SetFieldText( aStr, nFieldIndex );
+ }
+ delete pDlg;
+ }
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::NotifyFieldFocus( ScDPFieldType eType, BOOL bGotFocus )
+{
+ /* Enable Remove/Options buttons on GetFocus in field window.
+ #107616# Enable them also, if dialog is deactivated (click into document).
+ The !IsActive() condition handles the case that a LoseFocus event of a
+ field window would follow the Deactivate event of this dialog. */
+ BOOL bEnable = (bGotFocus || !IsActive()) && (eType != TYPE_SELECT);
+
+ // #128113# The TestTool may set the focus into an empty field.
+ // Then the Remove/Options buttons must be disabled.
+ if ( bEnable && bGotFocus && GetFieldWindow( eType ).IsEmpty() )
+ bEnable = FALSE;
+
+ aBtnRemove.Enable( bEnable );
+ aBtnOptions.Enable( bEnable );
+ if( bGotFocus )
+ eLastActiveType = eType;
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::NotifyMoveField( ScDPFieldType eToType )
+{
+ ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType );
+ if( (eToType != TYPE_SELECT) && !rWnd.IsEmpty() )
+ {
+ MoveField( eLastActiveType, rWnd.GetSelectedField(), eToType, GetFieldWindow( eToType ).GetLastPosition() );
+ if( rWnd.IsEmpty() )
+ NotifyFieldFocus( eToType, TRUE );
+ else
+ rWnd.GrabFocus();
+ if( eLastActiveType == TYPE_SELECT )
+ aWndSelect.SelectNext();
+ }
+ else
+ InitFocus();
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::NotifyRemoveField( ScDPFieldType eType, size_t nFieldIndex )
+{
+ if( eType != TYPE_SELECT )
+ RemoveField( eType, nFieldIndex );
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScDPLayoutDlg::NotifyMoveSlider( USHORT nKeyCode )
+{
+ long nOldPos = aSlider.GetThumbPos();
+ switch( nKeyCode )
+ {
+ case KEY_HOME: aSlider.DoScroll( 0 ); break;
+ case KEY_END: aSlider.DoScroll( aSlider.GetRangeMax() ); break;
+ case KEY_UP:
+ case KEY_LEFT: aSlider.DoScrollAction( SCROLL_LINEUP ); break;
+ case KEY_DOWN:
+ case KEY_RIGHT: aSlider.DoScrollAction( SCROLL_LINEDOWN ); break;
+ }
+ return nOldPos != aSlider.GetThumbPos();
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::Deactivate()
+{
+ /* #107616# If the dialog has been deactivated (click into document), the LoseFocus
+ event from field window disables Remove/Options buttons. Re-enable them here by
+ simulating a GetFocus event. Event order of LoseFocus and Deactivate is not important.
+ The last event will enable the buttons in both cases (see NotifyFieldFocus). */
+ NotifyFieldFocus( eLastActiveType, TRUE );
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt )
+{
+ if ( !pArr )
+ return FALSE;
+
+ BOOL bFound = FALSE;
+ size_t i = 0;
+
+ while ( (i<pArr->size()) && ((*pArr)[i].get() != NULL) && !bFound )
+ {
+ bFound = ((*pArr)[i]->mnCol == nCol);
+ if ( bFound )
+ nAt = i;
+ i++;
+ }
+
+ return bFound;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::Remove( ScDPFuncDataVec* pArr, size_t nAt )
+{
+ if ( !pArr || (nAt>=pArr->size()) )
+ return;
+
+ pArr->erase( pArr->begin() + nAt );
+ pArr->push_back( ScDPFuncDataRef() );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::Insert( ScDPFuncDataVec* pArr, const ScDPFuncData& rFData, size_t nAt )
+{
+ if ( !pArr || (nAt>=pArr->size()) )
+ return;
+
+ if ( (*pArr)[nAt].get() == NULL )
+ {
+ (*pArr)[nAt].reset( new ScDPFuncData( rFData ) );
+ }
+ else
+ {
+ if ( pArr->back().get() == NULL ) // mind. ein Slot frei?
+ {
+ pArr->insert( pArr->begin() + nAt, ScDPFuncDataRef( new ScDPFuncData( rFData ) ) );
+ pArr->erase( pArr->end() - 1 );
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+ScDPLabelData* ScDPLayoutDlg::GetLabelData( SCsCOL nCol, size_t* pnPos )
+{
+ ScDPLabelData* pData = 0;
+ for( ScDPLabelDataVec::iterator aIt = aLabelDataArr.begin(), aEnd = aLabelDataArr.end(); !pData && (aIt != aEnd); ++aIt )
+ {
+ if( aIt->mnCol == nCol )
+ {
+ pData = &*aIt;
+ if( pnPos ) *pnPos = aIt - aLabelDataArr.begin();
+ }
+ }
+ return pData;
+}
+
+
+//----------------------------------------------------------------------------
+
+String ScDPLayoutDlg::GetLabelString( SCsCOL nCol )
+{
+ ScDPLabelData* pData = GetLabelData( nCol );
+ DBG_ASSERT( pData, "LabelData not found" );
+ if (pData)
+ return pData->getDisplayName();
+ return String();
+}
+
+//----------------------------------------------------------------------------
+
+bool ScDPLayoutDlg::IsOrientationAllowed( SCsCOL nCol, ScDPFieldType eType )
+{
+ bool bAllowed = true;
+ ScDPLabelData* pData = GetLabelData( nCol );
+ DBG_ASSERT( pData, "LabelData not found" );
+ if (pData)
+ {
+ sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ switch (eType)
+ {
+ case TYPE_PAGE: eOrient = sheet::DataPilotFieldOrientation_PAGE; break;
+ case TYPE_COL: eOrient = sheet::DataPilotFieldOrientation_COLUMN; break;
+ case TYPE_ROW: eOrient = sheet::DataPilotFieldOrientation_ROW; break;
+ case TYPE_DATA: eOrient = sheet::DataPilotFieldOrientation_DATA; break;
+ case TYPE_SELECT: eOrient = sheet::DataPilotFieldOrientation_HIDDEN; break;
+ }
+ bAllowed = ScDPObject::IsOrientationAllowed( (USHORT)eOrient, pData->mnFlags );
+ }
+ return bAllowed;
+}
+
+//----------------------------------------------------------------------------
+
+String ScDPLayoutDlg::GetFuncString( USHORT& rFuncMask, BOOL bIsValue )
+{
+ String aStr;
+
+ if ( rFuncMask == PIVOT_FUNC_NONE
+ || rFuncMask == PIVOT_FUNC_AUTO )
+ {
+ if ( bIsValue )
+ {
+ aStr = FSTR(PIVOTSTR_SUM);
+ rFuncMask = PIVOT_FUNC_SUM;
+ }
+ else
+ {
+ aStr = FSTR(PIVOTSTR_COUNT);
+ rFuncMask = PIVOT_FUNC_COUNT;
+ }
+ }
+ else if ( rFuncMask == PIVOT_FUNC_SUM ) aStr = FSTR(PIVOTSTR_SUM);
+ else if ( rFuncMask == PIVOT_FUNC_COUNT ) aStr = FSTR(PIVOTSTR_COUNT);
+ else if ( rFuncMask == PIVOT_FUNC_AVERAGE ) aStr = FSTR(PIVOTSTR_AVG);
+ else if ( rFuncMask == PIVOT_FUNC_MAX ) aStr = FSTR(PIVOTSTR_MAX);
+ else if ( rFuncMask == PIVOT_FUNC_MIN ) aStr = FSTR(PIVOTSTR_MIN);
+ else if ( rFuncMask == PIVOT_FUNC_PRODUCT ) aStr = FSTR(PIVOTSTR_PROD);
+ else if ( rFuncMask == PIVOT_FUNC_COUNT_NUM ) aStr = FSTR(PIVOTSTR_COUNT2);
+ else if ( rFuncMask == PIVOT_FUNC_STD_DEV ) aStr = FSTR(PIVOTSTR_DEV);
+ else if ( rFuncMask == PIVOT_FUNC_STD_DEVP ) aStr = FSTR(PIVOTSTR_DEV2);
+ else if ( rFuncMask == PIVOT_FUNC_STD_VAR ) aStr = FSTR(PIVOTSTR_VAR);
+ else if ( rFuncMask == PIVOT_FUNC_STD_VARP ) aStr = FSTR(PIVOTSTR_VAR2);
+ else
+ {
+ aStr = ScGlobal::GetRscString( STR_TABLE_ERGEBNIS );
+ aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
+ }
+
+ return aStr;
+}
+
+
+//----------------------------------------------------------------------------
+
+Point ScDPLayoutDlg::DlgPos2WndPos( const Point& rPt, Window& rWnd )
+{
+ Point aWndPt( rPt );
+ aWndPt.X() = rPt.X()-rWnd.GetPosPixel().X();
+ aWndPt.Y() = rPt.Y()-rWnd.GetPosPixel().Y();
+
+ return aWndPt;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::CalcWndSizes()
+{
+ // row/column/data area sizes
+ aWndPage.SetSizePixel( Size( MAX_PAGEFIELDS * OWIDTH / 2, 2 * OHEIGHT ) );
+ aWndRow.SetSizePixel( Size( OWIDTH, MAX_FIELDS * OHEIGHT ) );
+ aWndCol.SetSizePixel( Size( MAX_FIELDS * OWIDTH / 2, 2 * OHEIGHT ) );
+ aWndData.SetSizePixel( Size( MAX_FIELDS * OWIDTH / 2, MAX_FIELDS * OHEIGHT ) );
+
+ // #i29203# align right border of page window with data window
+ long nDataPosX = aWndData.GetPosPixel().X() + aWndData.GetSizePixel().Width();
+ aWndPage.SetPosPixel( Point( nDataPosX - aWndPage.GetSizePixel().Width(), aWndPage.GetPosPixel().Y() ) );
+
+ // selection area
+ aWndSelect.SetSizePixel( Size(
+ 2 * OWIDTH + SSPACE, LINE_SIZE * OHEIGHT + (LINE_SIZE - 1) * SSPACE ) );
+
+ // scroll bar
+ Point aSliderPos( aWndSelect.GetPosPixel() );
+ Size aSliderSize( aWndSelect.GetSizePixel() );
+ aSliderPos.Y() += aSliderSize.Height() + SSPACE;
+ aSliderSize.Height() = GetSettings().GetStyleSettings().GetScrollBarSize();
+ aSlider.SetPosSizePixel( aSliderPos, aSliderSize );
+
+ aRectPage = Rectangle( aWndPage.GetPosPixel(), aWndPage.GetSizePixel() );
+ aRectRow = Rectangle( aWndRow.GetPosPixel(), aWndRow.GetSizePixel() );
+ aRectCol = Rectangle( aWndCol.GetPosPixel(), aWndCol.GetSizePixel() );
+ aRectData = Rectangle( aWndData.GetPosPixel(), aWndData.GetSizePixel() );
+ aRectSelect = Rectangle( aWndSelect.GetPosPixel(), aWndSelect.GetSizePixel() );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScDPLayoutDlg::GetPivotArrays( PivotField* pPageArr,
+ PivotField* pColArr,
+ PivotField* pRowArr,
+ PivotField* pDataArr,
+ USHORT& rPageCount,
+ USHORT& rColCount,
+ USHORT& rRowCount,
+ USHORT& rDataCount )
+{
+ BOOL bFit = TRUE;
+ USHORT i=0;
+
+ for ( i=0; (i<aDataArr.size()) && (aDataArr[i].get() != NULL ); i++ )
+ lcl_FillToPivotField( pDataArr[i], *aDataArr[i] );
+ rDataCount = i;
+
+ for ( i=0; (i<aPageArr.size()) && (aPageArr[i].get() != NULL ); i++ )
+ lcl_FillToPivotField( pPageArr[i], *aPageArr[i] );
+ rPageCount = i;
+
+ for ( i=0; (i<aColArr.size()) && (aColArr[i].get() != NULL ); i++ )
+ lcl_FillToPivotField( pColArr[i], *aColArr[i] );
+ rColCount = i;
+
+ for ( i=0; (i<aRowArr.size()) && (aRowArr[i].get() != NULL ); i++ )
+ lcl_FillToPivotField( pRowArr[i], *aRowArr[i] );
+ rRowCount = i;
+
+ if ( rRowCount < aRowArr.size() )
+ pRowArr[rRowCount++].nCol = PIVOT_DATA_FIELD;
+ else if ( rColCount < aColArr.size() )
+ pColArr[rColCount++].nCol = PIVOT_DATA_FIELD;
+ else
+ bFit = FALSE; // kein Platz fuer Datenfeld
+
+ return bFit;
+}
+
+void ScDPLayoutDlg::UpdateSrcRange()
+{
+ String theCurPosStr = aEdInPos.GetText();
+ USHORT nResult = ScRange().Parse(theCurPosStr, pDoc, pDoc->GetAddressConvention());
+
+ if ( SCA_VALID != (nResult & SCA_VALID) )
+ // invalid source range.
+ return;
+
+ ScRefAddress start, end;
+ ConvertDoubleRef(pDoc, theCurPosStr, 1, start, end, pDoc->GetAddressConvention());
+ ScRange aNewRange(start.GetAddress(), end.GetAddress());
+ ScSheetSourceDesc inSheet = *xDlgDPObject->GetSheetDesc();
+
+ if (inSheet.aSourceRange == aNewRange)
+ // new range is identical to the current range. Nothing to do.
+ return;
+
+ ScTabViewShell * pTabViewShell = pViewData->GetViewShell();
+ inSheet.aSourceRange = aNewRange;
+ xDlgDPObject->SetSheetDesc(inSheet);
+ xDlgDPObject->FillOldParam( thePivotData, FALSE );
+ xDlgDPObject->FillLabelData(thePivotData);
+
+ pTabViewShell->SetDialogDPObject(xDlgDPObject.get());
+ aLabelDataArr.clear();
+ aWndSelect.ClearFields();
+ aWndData.ClearFields();
+ aWndRow.ClearFields();
+ aWndCol.ClearFields();
+ aWndPage.ClearFields();
+
+ for (size_t i = 0; i < MAX_LABELS; ++i)
+ aSelectArr[i].reset();
+
+ for (size_t i = 0; i < MAX_FIELDS; ++i)
+ {
+ aRowArr[i].reset();
+ aColArr[i].reset();
+ aDataArr[i].reset();
+ }
+
+ for (size_t i = 0; i < MAX_PAGEFIELDS; ++i)
+ aPageArr[i].reset();
+
+ InitFields();
+}
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( !bRefInputMode || !pEditActive )
+ return;
+
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( pEditActive );
+
+ if ( pEditActive == &aEdInPos )
+ {
+ String aRefStr;
+ rRef.Format( aRefStr, SCR_ABS_3D, pDocP, pDocP->GetAddressConvention() );
+ pEditActive->SetRefString( aRefStr );
+ }
+ else if ( pEditActive == &aEdOutPos )
+ {
+ String aRefStr;
+ rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP, pDocP->GetAddressConvention() );
+ pEditActive->SetRefString( aRefStr );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScDPLayoutDlg::SetActive()
+{
+ if ( bRefInputMode )
+ {
+ if ( pEditActive )
+ pEditActive->GrabFocus();
+
+ if ( pEditActive == &aEdInPos )
+ EdInModifyHdl( NULL );
+ else if ( pEditActive == &aEdOutPos )
+ EdModifyHdl( NULL );
+ }
+ else
+ {
+ GrabFocus();
+ }
+
+ RefInputDone();
+}
+
+//----------------------------------------------------------------------------
+// Handler:
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, ClickHdl, PushButton *, pBtn )
+{
+ if( pBtn == &aBtnRemove )
+ {
+ ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType );
+ RemoveField( eLastActiveType, rWnd.GetSelectedField() );
+ if( !rWnd.IsEmpty() ) rWnd.GrabFocus();
+ }
+ else if( pBtn == &aBtnOptions )
+ {
+ ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType );
+ NotifyDoubleClick( eLastActiveType, rWnd.GetSelectedField() );
+ rWnd.GrabFocus();
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
+{
+ String aOutPosStr( aEdOutPos.GetText() );
+ ScAddress aAdrDest;
+ BOOL bToNewTable = (aLbOutPos.GetSelectEntryPos() == 1);
+ USHORT nResult = !bToNewTable ? aAdrDest.Parse( aOutPosStr, pDoc, pDoc->GetAddressConvention() ) : 0;
+
+ if ( bToNewTable
+ || ( (aOutPosStr.Len() > 0) && (SCA_VALID == (nResult & SCA_VALID)) ) )
+ {
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+
+ ScPivotParam theOutParam;
+ PivotPageFieldArr aPageFieldArr;
+ PivotFieldArr aColFieldArr;
+ PivotFieldArr aRowFieldArr;
+ PivotFieldArr aDataFieldArr;
+ USHORT nPageCount;
+ USHORT nColCount;
+ USHORT nRowCount;
+ USHORT nDataCount;
+
+ BOOL bFit = GetPivotArrays( aPageFieldArr, aColFieldArr, aRowFieldArr, aDataFieldArr,
+ nPageCount, nColCount, nRowCount, nDataCount );
+ if ( bFit )
+ {
+ ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData();
+
+ ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately
+
+ ScDPSaveData aSaveData;
+ aSaveData.SetIgnoreEmptyRows( aBtnIgnEmptyRows.IsChecked() );
+ aSaveData.SetRepeatIfEmpty( aBtnDetectCat.IsChecked() );
+ aSaveData.SetColumnGrand( aBtnTotalCol.IsChecked() );
+ aSaveData.SetRowGrand( aBtnTotalRow.IsChecked() );
+ aSaveData.SetFilterButton( aBtnFilter.IsChecked() );
+ aSaveData.SetDrillDown( aBtnDrillDown.IsChecked() );
+
+ uno::Reference<sheet::XDimensionsSupplier> xSource = xDlgDPObject->GetSource();
+
+ ScDPObject::ConvertOrientation( aSaveData, aPageFieldArr, nPageCount,
+ sheet::DataPilotFieldOrientation_PAGE, NULL, 0, 0, xSource, FALSE );
+ ScDPObject::ConvertOrientation( aSaveData, aColFieldArr, nColCount,
+ sheet::DataPilotFieldOrientation_COLUMN, NULL, 0, 0, xSource, FALSE );
+ ScDPObject::ConvertOrientation( aSaveData, aRowFieldArr, nRowCount,
+ sheet::DataPilotFieldOrientation_ROW, NULL, 0, 0, xSource, FALSE );
+ ScDPObject::ConvertOrientation( aSaveData, aDataFieldArr, nDataCount,
+ sheet::DataPilotFieldOrientation_DATA, NULL, 0, 0, xSource, FALSE,
+ aColFieldArr, nColCount, aRowFieldArr, nRowCount, aPageFieldArr, nPageCount );
+
+ for( ScDPLabelDataVec::const_iterator aIt = aLabelDataArr.begin(), aEnd = aLabelDataArr.end(); aIt != aEnd; ++aIt )
+ {
+ if( ScDPSaveDimension* pDim = aSaveData.GetExistingDimensionByName( aIt->maName ) )
+ {
+ pDim->SetUsedHierarchy( aIt->mnUsedHier );
+ pDim->SetShowEmpty( aIt->mbShowAll );
+ pDim->SetSortInfo( &aIt->maSortInfo );
+ pDim->SetLayoutInfo( &aIt->maLayoutInfo );
+ pDim->SetAutoShowInfo( &aIt->maShowInfo );
+ ScDPSaveDimension* pOldDim = NULL;
+ if (pOldSaveData)
+ {
+ // Transfer the existing layout names to new dimension instance.
+ pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName);
+ if (pOldDim)
+ {
+ const OUString* pLayoutName = pOldDim->GetLayoutName();
+ if (pLayoutName)
+ pDim->SetLayoutName(*pLayoutName);
+
+ const OUString* pSubtotalName = pOldDim->GetSubtotalName();
+ if (pSubtotalName)
+ pDim->SetSubtotalName(*pSubtotalName);
+ }
+ }
+
+ bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL );
+
+ // visibility of members
+ for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName);
+
+ // #i40054# create/access members only if flags are not default
+ // (or in manual sorting mode - to keep the order)
+ if (bManualSort || !itr->mbVisible || !itr->mbShowDetails)
+ {
+ pMember->SetIsVisible(itr->mbVisible);
+ pMember->SetShowDetails(itr->mbShowDetails);
+ }
+ if (pOldDim)
+ {
+ // Transfer the existing layout name.
+ ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName);
+ if (pOldMember)
+ {
+ const OUString* pLayoutName = pOldMember->GetLayoutName();
+ if (pLayoutName)
+ pMember->SetLayoutName(*pLayoutName);
+ }
+ }
+ }
+ }
+ }
+ ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
+ if (pDim && pOldSaveData)
+ {
+ ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension();
+ if (pOldDim)
+ {
+ const OUString* pLayoutName = pOldDim->GetLayoutName();
+ if (pLayoutName)
+ pDim->SetLayoutName(*pLayoutName);
+ }
+ }
+
+ USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE );
+ ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable );
+
+ bRefInputMode = FALSE; // to allow deselecting when switching sheets
+
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+
+ // #95513# don't hide the dialog before executing the slot, instead it is used as
+ // parent for message boxes in ScTabViewShell::GetDialogParent
+
+ const SfxPoolItem* pRet = GetBindings().GetDispatcher()->Execute(
+ SID_PIVOT_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aOutItem, 0L, 0L );
+
+ bool bSuccess = true;
+ if (pRet)
+ {
+ const SfxBoolItem* pItem = dynamic_cast<const SfxBoolItem*>(pRet);
+ if (pItem)
+ bSuccess = pItem->GetValue();
+ }
+ if (bSuccess)
+ // Table successfully inserted.
+ Close();
+ else
+ {
+ // Table insertion failed. Keep the dialog open.
+ bRefInputMode = true;
+ SetDispatcherLock(true);
+ }
+ }
+ else
+ {
+ ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_PIVOT_ERROR )
+ ).Execute();
+ }
+ }
+ else
+ {
+ if ( !aBtnMore.GetState() )
+ aBtnMore.SetState( TRUE );
+
+ ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_INVALID_TABREF )
+ ).Execute();
+ aEdOutPos.GrabFocus();
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG )
+{
+ Close();
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, MoreClickHdl, MoreButton *, EMPTYARG )
+{
+ if ( aBtnMore.GetState() )
+ {
+ bRefInputMode = TRUE;
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+ if ( aEdInPos.IsEnabled() )
+ {
+ aEdInPos.Enable();
+ aEdInPos.GrabFocus();
+ aEdInPos.Enable();
+ }
+ else
+ {
+ aEdOutPos.Enable();
+ aEdOutPos.GrabFocus();
+ aEdOutPos.Enable();
+ }
+ }
+ else
+ {
+ bRefInputMode = FALSE;
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG )
+{
+ String theCurPosStr = aEdOutPos.GetText();
+ USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
+
+ if ( SCA_VALID == (nResult & SCA_VALID) )
+ {
+ String* pStr = NULL;
+ BOOL bFound = FALSE;
+ USHORT i = 0;
+ USHORT nCount = aLbOutPos.GetEntryCount();
+
+ for ( i=2; i<nCount && !bFound; i++ )
+ {
+ pStr = (String*)aLbOutPos.GetEntryData( i );
+ bFound = (theCurPosStr == *pStr);
+ }
+
+ if ( bFound )
+ aLbOutPos.SelectEntryPos( --i );
+ else
+ aLbOutPos.SelectEntryPos( 0 );
+ }
+ return 0;
+}
+
+
+IMPL_LINK( ScDPLayoutDlg, EdInModifyHdl, Edit *, EMPTYARG )
+{
+ UpdateSrcRange();
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG )
+{
+ String aString;
+ USHORT nSelPos = aLbOutPos.GetSelectEntryPos();
+
+ if ( nSelPos > 1 )
+ {
+ aString = *(String*)aLbOutPos.GetEntryData( nSelPos );
+ }
+ else if ( nSelPos == aLbOutPos.GetEntryCount()-1 ) // auf neue Tabelle?
+ {
+ aEdOutPos.Disable();
+ aRbOutPos.Disable();
+ }
+ else
+ {
+ aEdOutPos.Enable();
+ aRbOutPos.Enable();
+ }
+
+ aEdOutPos.SetText( aString );
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG )
+{
+ long nNewOffset = aSlider.GetThumbPos();
+ long nOffsetDiff = nNewOffset - nOffset;
+ nOffset = nNewOffset;
+
+ size_t nFields = std::min< size_t >( aLabelDataArr.size() - nOffset, PAGE_SIZE );
+
+ aWndSelect.ClearFields();
+
+ size_t i=0;
+ for ( i=0; i<nFields; i++ )
+ {
+ const ScDPLabelData& rData = aLabelDataArr[nOffset+i];
+ aWndSelect.AddField(rData.getDisplayName(), i);
+ aSelectArr[i].reset( new ScDPFuncData( rData.mnCol, rData.mnFuncMask ) );
+ }
+ for ( ; i<aSelectArr.size(); i++ )
+ aSelectArr[i].reset();
+
+ aWndSelect.ModifySelectionOffset( nOffsetDiff ); // adjusts selection & redraws
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScDPLayoutDlg, GetFocusHdl, Control*, pCtrl )
+{
+ pEditActive = NULL;
+ if ( pCtrl == &aEdInPos )
+ pEditActive = &aEdInPos;
+ else if ( pCtrl == &aEdOutPos )
+ pEditActive = &aEdOutPos;
+
+ return 0;
+}
+
diff --git a/sc/source/ui/dbgui/scendlg.cxx b/sc/source/ui/dbgui/scendlg.cxx
new file mode 100644
index 000000000000..96c9f120f5b1
--- /dev/null
+++ b/sc/source/ui/dbgui/scendlg.cxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "scitems.hxx"
+#include <svx/drawitem.hxx>
+#include <svx/xtable.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/useroptions.hxx>
+#include <vcl/msgbox.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "scendlg.hrc"
+#include "scendlg.hxx"
+
+//========================================================================
+
+ScNewScenarioDlg::ScNewScenarioDlg( Window* pParent, const String& rName, BOOL bEdit, BOOL bSheetProtected)
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_NEWSCENARIO ) ),
+ aFlName ( this, ScResId( FL_NAME )),
+ aEdName ( this, ScResId( ED_NAME ) ),
+ aFlComment ( this, ScResId( FL_COMMENT ) ),
+ aEdComment ( this, ScResId( ED_COMMENT ) ),
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ aCbShowFrame ( this, ScResId( CB_SHOWFRAME ) ),
+ aLbColor ( this, ScResId( LB_COLOR ) ),
+ //aCbPrintFrame ( this, ScResId( CB_PRINTFRAME ) ),
+ aCbTwoWay ( this, ScResId( CB_TWOWAY ) ),
+ //aCbAttrib ( this, ScResId( CB_ATTRIB ) ),
+ //aCbValue ( this, ScResId( CB_VALUE ) ),
+ aCbCopyAll ( this, ScResId( CB_COPYALL ) ),
+ aCbProtect ( this, ScResId( CB_PROTECT ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aDefScenarioName( rName ),
+ bIsEdit ( bEdit )
+{
+ if (bIsEdit)
+ SetText(String(ScResId(STR_EDIT)));
+
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
+ if ( pItem )
+ {
+ XColorTable* pColorTable = ((SvxColorTableItem*)pItem)->GetColorTable();
+ if (pColorTable)
+ {
+ aLbColor.SetUpdateMode( FALSE );
+ long nCount = pColorTable->Count();
+ for ( long n=0; n<nCount; n++ )
+ {
+ XColorEntry* pEntry = pColorTable->GetColor(n);
+ aLbColor.InsertEntry( pEntry->GetColor(), pEntry->GetName() );
+ }
+ aLbColor.SetUpdateMode( TRUE );
+ }
+ }
+ }
+
+ SvtUserOptions aUserOpt;
+
+ String aComment( ScResId( STR_CREATEDBY ) );
+
+ aComment += ' ';
+ aComment += (String)aUserOpt.GetFirstName();
+ aComment += ' ';
+ aComment += (String)aUserOpt.GetLastName();
+ aComment.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
+ aComment += String( ScResId( STR_ON ) );
+ aComment += ' ';
+ aComment += ScGlobal::GetpLocaleData()->getDate( Date() );//CHINA001 aComment += ScGlobal::pLocaleData->getDate( Date() );
+ aComment.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
+ aComment += ScGlobal::GetpLocaleData()->getTime( Time() );//CHINA001 aComment += ScGlobal::pLocaleData->getTime( Time() );
+
+ aEdComment .SetText( aComment );
+ aEdName .SetText( rName );
+ aBtnOk .SetClickHdl( LINK( this, ScNewScenarioDlg, OkHdl ) );
+ aCbShowFrame.SetClickHdl( LINK( this, ScNewScenarioDlg, EnableHdl ) );
+
+ FreeResource();
+
+ aLbColor.SelectEntry( Color( COL_LIGHTGRAY ) );
+ aCbShowFrame.Check(TRUE);
+ //aCbPrintFrame.Check(TRUE);
+ aCbTwoWay.Check(TRUE);
+ //aCbAttrib.Check(FALSE);
+ //aCbValue.Check(FALSE);
+ aCbCopyAll.Check(FALSE);
+ aCbProtect.Check(TRUE);
+
+ if (bIsEdit)
+ aCbCopyAll.Enable(FALSE);
+ // If the Sheet is protected then we disable the Scenario Protect input
+ // and default it to true above. Note we are in 'Add' mode here as: if
+ // Sheet && scenario protection are true, then we cannot edit this dialog.
+ if (bSheetProtected)
+ aCbProtect.Enable(FALSE);
+
+ //! die drei funktionieren noch nicht...
+ /*
+ aCbPrintFrame.Enable(FALSE);
+ aCbAttrib.Enable(FALSE);
+ aCbValue.Enable(FALSE);
+ */
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScNewScenarioDlg::~ScNewScenarioDlg()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScNewScenarioDlg::GetScenarioData( String& rName, String& rComment,
+ Color& rColor, USHORT& rFlags ) const
+{
+ rComment = aEdComment.GetText();
+ rName = aEdName.GetText();
+
+ if ( rName.Len() == 0 )
+ rName = aDefScenarioName;
+
+ rColor = aLbColor.GetSelectEntryColor();
+ USHORT nBits = 0;
+ if (aCbShowFrame.IsChecked())
+ nBits |= SC_SCENARIO_SHOWFRAME;
+ /*
+ if (aCbPrintFrame.IsChecked())
+ nBits |= SC_SCENARIO_PRINTFRAME;
+ */
+ if (aCbTwoWay.IsChecked())
+ nBits |= SC_SCENARIO_TWOWAY;
+ /*
+ if (aCbAttrib.IsChecked())
+ nBits |= SC_SCENARIO_ATTRIB;
+ if (aCbValue.IsChecked())
+ nBits |= SC_SCENARIO_VALUE;
+ */
+ if (aCbCopyAll.IsChecked())
+ nBits |= SC_SCENARIO_COPYALL;
+ if (aCbProtect.IsChecked())
+ nBits |= SC_SCENARIO_PROTECT;
+ rFlags = nBits;
+}
+
+void ScNewScenarioDlg::SetScenarioData( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags )
+{
+ aEdComment.SetText(rComment);
+ aEdName.SetText(rName);
+ aLbColor.SelectEntry(rColor);
+
+ aCbShowFrame.Check ( (nFlags & SC_SCENARIO_SHOWFRAME) != 0 );
+ EnableHdl( &aCbShowFrame );
+ //aCbPrintFrame.Check( (nFlags & SC_SCENARIO_PRINTFRAME) != 0 );
+ aCbTwoWay.Check ( (nFlags & SC_SCENARIO_TWOWAY) != 0 );
+ //aCbAttrib.Check ( (nFlags & SC_SCENARIO_ATTRIB) != 0 );
+ //aCbValue.Check ( (nFlags & SC_SCENARIO_VALUE) != 0 );
+ // CopyAll nicht
+ aCbProtect.Check ( (nFlags & SC_SCENARIO_PROTECT) != 0 );
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScNewScenarioDlg, OkHdl, OKButton *, EMPTYARG )
+{
+ String aName ( aEdName.GetText() );
+ ScDocument* pDoc = ((ScTabViewShell*)SfxViewShell::Current())->
+ GetViewData()->GetDocument();
+
+ aName.EraseLeadingChars( ' ' );
+ aName.EraseTrailingChars( ' ' );
+ aEdName.SetText( aName );
+
+ if ( !pDoc->ValidTabName( aName ) )
+ {
+ InfoBox( this, ScGlobal::GetRscString( STR_INVALIDTABNAME ) ).
+ Execute();
+ aEdName.GrabFocus();
+ }
+ else if ( !bIsEdit && !pDoc->ValidNewTabName( aName ) )
+ {
+ InfoBox( this, ScGlobal::GetRscString( STR_NEWTABNAMENOTUNIQUE ) ).
+ Execute();
+ aEdName.GrabFocus();
+ }
+ else
+ EndDialog( RET_OK );
+ return 0;
+
+ //! beim Editieren testen, ob eine andere Tabelle den Namen hat!
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScNewScenarioDlg, EnableHdl, CheckBox *, pBox )
+{
+ if( pBox == &aCbShowFrame )
+ aLbColor.Enable( aCbShowFrame.IsChecked() );
+ return 0;
+}
+
diff --git a/sc/source/ui/dbgui/scendlg.hrc b/sc/source/ui/dbgui/scendlg.hrc
new file mode 100644
index 000000000000..83818773bf5a
--- /dev/null
+++ b/sc/source/ui/dbgui/scendlg.hrc
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc"
+//#define RID_SCDLG_NEWSCENARIO 256
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define FL_NAME 10
+#define ED_NAME 11
+#define FL_COMMENT 12
+#define ED_COMMENT 13
+
+#define FL_OPTIONS 20
+#define CB_SHOWFRAME 21
+#define LB_COLOR 22
+#define CB_PRINTFRAME 23
+#define CB_TWOWAY 24
+#define CB_ATTRIB 25
+#define CB_VALUE 26
+#define CB_COPYALL 27
+#define CB_PROTECT 28
+
+#ifdef STR_ON
+#undef STR_ON
+#endif
+#ifdef STR_EDIT
+#undef STR_EDIT
+#endif
+
+#define STR_CREATEDBY 31
+#define STR_ON 32
+#define STR_EDIT 33
diff --git a/sc/source/ui/dbgui/scendlg.src b/sc/source/ui/dbgui/scendlg.src
new file mode 100644
index 000000000000..40cfeb01b8ff
--- /dev/null
+++ b/sc/source/ui/dbgui/scendlg.src
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include "scendlg.hrc"
+ModalDialog RID_SCDLG_NEWSCENARIO
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 165 ) ;
+ Text [ en-US ] = "Create Scenario" ;
+ Moveable = TRUE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 204 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 204 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 204 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MultiLineEdit ED_COMMENT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 43 ) ;
+ Size = MAP_APPFONT ( 183 , 46 ) ;
+ TabStop = TRUE ;
+ MaxTextLength = 512 ;
+ VScroll = TRUE ;
+ IgnoreTab = TRUE ;
+ };
+ Edit ED_NAME
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 183 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ CheckBox CB_SHOWFRAME
+ {
+ Pos = MAP_APPFONT ( 12 , 107 ) ;
+ Size = MAP_APPFONT ( 109 , 10 ) ;
+ Text [ en-US ] = "~Display border";
+ };
+ ListBox LB_COLOR
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 125 , 105 ) ;
+ Size = MAP_APPFONT ( 70 , 86 ) ;
+ DropDown = TRUE ;
+ DDExtraWidth = TRUE ;
+ };
+ CheckBox CB_PRINTFRAME
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 121 , 243 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Print border" ;
+ };
+ CheckBox CB_TWOWAY
+ {
+ Pos = MAP_APPFONT ( 12 , 121 ) ;
+ Size = MAP_APPFONT ( 183 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zurückkopieren : Zur³ckkopieren */
+ Text [ en-US ] = "Copy ~back" ;
+ };
+ CheckBox CB_ATTRIB
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 243 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Attributes" ;
+ };
+ CheckBox CB_VALUE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 230 , 243 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Copy values only" ;
+ };
+ CheckBox CB_COPYALL
+ {
+ Pos = MAP_APPFONT ( 12 , 135 ) ;
+ Size = MAP_APPFONT ( 183 , 10 ) ;
+ Text [ en-US ] = "Copy ~entire sheet" ;
+ };
+ CheckBox CB_PROTECT
+ {
+ Pos = MAP_APPFONT ( 12 , 149 ) ;
+ Size = MAP_APPFONT ( 183 , 10 ) ;
+ Text [ en-US ] = "~Prevent changes" ;
+ };
+ String STR_EDIT
+ {
+ Text [ en-US ] = "Edit Scenario" ;
+ };
+ String STR_CREATEDBY
+ {
+ Text [ en-US ] = "Created by" ;
+ };
+ String STR_ON
+ {
+ Text [ en-US ] = "on" ;
+ };
+ FixedLine FL_NAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 192 , 8 ) ;
+ Text [ en-US ] = "~Name of scenario";
+ };
+ FixedLine FL_COMMENT
+ {
+ Pos = MAP_APPFONT ( 6 , 32 ) ;
+ Size = MAP_APPFONT ( 192 , 8 ) ;
+ Text [ en-US ] = "~Comment";
+ };
+ FixedLine FL_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 95 ) ;
+ Size = MAP_APPFONT ( 192 , 8 ) ;
+ Text [ en-US ] = "Settings";
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/dbgui/scuiasciiopt.cxx b/sc/source/ui/dbgui/scuiasciiopt.cxx
new file mode 100644
index 000000000000..171daa0ca882
--- /dev/null
+++ b/sc/source/ui/dbgui/scuiasciiopt.cxx
@@ -0,0 +1,723 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+#include "global.hxx"
+#include "scresid.hxx"
+#include "impex.hxx"
+#include "scuiasciiopt.hxx"
+#include "asciiopt.hrc"
+#include <tools/debug.hxx>
+#include <rtl/tencinfo.h>
+#include <unotools/transliterationwrapper.hxx>
+// ause
+#include "editutil.hxx"
+
+#include <optutil.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "miscuno.hxx"
+
+
+//! TODO make dynamic
+#ifdef WIN
+const SCSIZE ASCIIDLG_MAXROWS = 10000;
+#else
+const SCSIZE ASCIIDLG_MAXROWS = MAXROWCOUNT;
+#endif
+
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+// Defines - CSV Import Preserve Options
+#define FIXED_WIDTH "FixedWidth"
+#define FROM_ROW "FromRow"
+#define CHAR_SET "CharSet"
+#define SEPARATORS "Separators"
+#define TEXT_SEPARATORS "TextSeparators"
+#define MERGE_DELIMITERS "MergeDelimiters"
+#define QUOTED_AS_TEXT "QuotedFieldAsText"
+#define DETECT_SPECIAL_NUM "DetectSpecialNumbers"
+#define LANGUAGE "Language"
+#define SEP_PATH "Office.Calc/Dialogs/CSVImport"
+
+// ============================================================================
+
+void lcl_FillCombo( ComboBox& rCombo, const String& rList, sal_Unicode cSelect )
+{
+ xub_StrLen i;
+ xub_StrLen nCount = rList.GetTokenCount('\t');
+ for ( i=0; i<nCount; i+=2 )
+ rCombo.InsertEntry( rList.GetToken(i,'\t') );
+
+ if ( cSelect )
+ {
+ String aStr;
+ for ( i=0; i<nCount; i+=2 )
+ if ( (sal_Unicode)rList.GetToken(i+1,'\t').ToInt32() == cSelect )
+ aStr = rList.GetToken(i,'\t');
+ if (!aStr.Len())
+ aStr = cSelect; // Ascii
+
+ rCombo.SetText(aStr);
+ }
+}
+
+sal_Unicode lcl_CharFromCombo( ComboBox& rCombo, const String& rList )
+{
+ sal_Unicode c = 0;
+ String aStr = rCombo.GetText();
+ if ( aStr.Len() )
+ {
+ xub_StrLen nCount = rList.GetTokenCount('\t');
+ for ( xub_StrLen i=0; i<nCount; i+=2 )
+ {
+ if ( ScGlobal::GetpTransliteration()->isEqual( aStr, rList.GetToken(i,'\t') ) )//CHINA001 if ( ScGlobal::GetpTransliteration()->isEqual( aStr, rList.GetToken(i,'\t') ) )
+ c = (sal_Unicode)rList.GetToken(i+1,'\t').ToInt32();
+ }
+ if (!c && aStr.Len())
+ {
+ sal_Unicode cFirst = aStr.GetChar( 0 );
+ // #i24235# first try the first character of the string directly
+ if( (aStr.Len() == 1) || (cFirst < '0') || (cFirst > '9') )
+ c = cFirst;
+ else // keep old behaviour for compatibility (i.e. "39" -> "'")
+ c = (sal_Unicode) aStr.ToInt32(); // Ascii
+ }
+ }
+ return c;
+}
+
+static void load_Separators( OUString &sFieldSeparators, OUString &sTextSeparators,
+ bool &bMergeDelimiters, bool& bQuotedAsText, bool& bDetectSpecialNum,
+ bool &bFixedWidth, sal_Int32 &nFromRow, sal_Int32 &nCharSet,
+ sal_Int32& nLanguage )
+{
+ Sequence<Any>aValues;
+ const Any *pProperties;
+ Sequence<OUString> aNames(9);
+ OUString* pNames = aNames.getArray();
+ ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) );
+
+ pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS );
+ pNames[1] = OUString::createFromAscii( SEPARATORS );
+ pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS );
+ pNames[3] = OUString::createFromAscii( FIXED_WIDTH );
+ pNames[4] = OUString::createFromAscii( FROM_ROW );
+ pNames[5] = OUString::createFromAscii( CHAR_SET );
+ pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT );
+ pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM );
+ pNames[8] = OUString::createFromAscii( LANGUAGE );
+ aValues = aItem.GetProperties( aNames );
+ pProperties = aValues.getConstArray();
+ if( pProperties[1].hasValue() )
+ pProperties[1] >>= sFieldSeparators;
+
+ if( pProperties[2].hasValue() )
+ pProperties[2] >>= sTextSeparators;
+
+ if( pProperties[0].hasValue() )
+ bMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[0] );
+
+ if( pProperties[3].hasValue() )
+ bFixedWidth = ScUnoHelpFunctions::GetBoolFromAny( pProperties[3] );
+
+ if( pProperties[4].hasValue() )
+ pProperties[4] >>= nFromRow;
+
+ if( pProperties[5].hasValue() )
+ pProperties[5] >>= nCharSet;
+
+ if ( pProperties[6].hasValue() )
+ pProperties[6] >>= bQuotedAsText;
+
+ if ( pProperties[7].hasValue() )
+ pProperties[7] >>= bDetectSpecialNum;
+
+ if ( pProperties[8].hasValue() )
+ pProperties[8] >>= nLanguage;
+}
+
+static void save_Separators(
+ String maSeparators, String maTxtSep, bool bMergeDelimiters, bool bQuotedAsText,
+ bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow, sal_Int32 nCharSet, sal_Int32 nLanguage )
+{
+ OUString sFieldSeparators = OUString( maSeparators );
+ OUString sTextSeparators = OUString( maTxtSep );
+ Sequence<Any> aValues;
+ Any *pProperties;
+ Sequence<OUString> aNames(9);
+ OUString* pNames = aNames.getArray();
+ ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) );
+
+ pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS );
+ pNames[1] = OUString::createFromAscii( SEPARATORS );
+ pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS );
+ pNames[3] = OUString::createFromAscii( FIXED_WIDTH );
+ pNames[4] = OUString::createFromAscii( FROM_ROW );
+ pNames[5] = OUString::createFromAscii( CHAR_SET );
+ pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT );
+ pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM );
+ pNames[8] = OUString::createFromAscii( LANGUAGE );
+ aValues = aItem.GetProperties( aNames );
+ pProperties = aValues.getArray();
+ pProperties[1] <<= sFieldSeparators;
+ pProperties[2] <<= sTextSeparators;
+ ScUnoHelpFunctions::SetBoolInAny( pProperties[0], bMergeDelimiters );
+ ScUnoHelpFunctions::SetBoolInAny( pProperties[3], bFixedWidth );
+ pProperties[4] <<= nFromRow;
+ pProperties[5] <<= nCharSet;
+ pProperties[6] <<= static_cast<sal_Bool>(bQuotedAsText);
+ pProperties[7] <<= static_cast<sal_Bool>(bDetectSpecialNum);
+ pProperties[8] <<= nLanguage;
+
+ aItem.PutProperties(aNames, aValues);
+}
+
+// ----------------------------------------------------------------------------
+
+ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName,
+ SvStream* pInStream, sal_Unicode /*cSep*/ ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_ASCII ) ),
+ mpDatStream ( pInStream ),
+ mnStreamPos( pInStream ? pInStream->Tell() : 0 ),
+
+ mpRowPosArray( NULL ),
+ mnRowPosCount(0),
+
+ aFlFieldOpt ( this, ScResId( FL_FIELDOPT ) ),
+ aFtCharSet ( this, ScResId( FT_CHARSET ) ),
+ aLbCharSet ( this, ScResId( LB_CHARSET ) ),
+ aFtCustomLang( this, ScResId( FT_CUSTOMLANG ) ),
+ aLbCustomLang( this, ScResId( LB_CUSTOMLANG ) ),
+
+ aFtRow ( this, ScResId( FT_AT_ROW ) ),
+ aNfRow ( this, ScResId( NF_AT_ROW ) ),
+
+ aFlSepOpt ( this, ScResId( FL_SEPOPT ) ),
+ aRbFixed ( this, ScResId( RB_FIXED ) ),
+ aRbSeparated( this, ScResId( RB_SEPARATED ) ),
+
+ aCkbTab ( this, ScResId( CKB_TAB ) ),
+ aCkbSemicolon(this, ScResId( CKB_SEMICOLON ) ),
+ aCkbComma ( this, ScResId( CKB_COMMA ) ),
+ aCkbSpace ( this, ScResId( CKB_SPACE ) ),
+ aCkbOther ( this, ScResId( CKB_OTHER ) ),
+ aEdOther ( this, ScResId( ED_OTHER ) ),
+ aCkbAsOnce ( this, ScResId( CB_ASONCE) ),
+ aFlOtherOpt ( this, ScResId( FL_OTHER_OPTIONS ) ),
+
+ aFtTextSep ( this, ScResId( FT_TEXTSEP ) ),
+ aCbTextSep ( this, ScResId( CB_TEXTSEP ) ),
+
+ aCkbQuotedAsText( this, ScResId(CB_QUOTED_AS_TEXT) ),
+ aCkbDetectNumber( this, ScResId(CB_DETECT_SPECIAL_NUMBER) ),
+
+ aFlWidth ( this, ScResId( FL_WIDTH ) ),
+ aFtType ( this, ScResId( FT_TYPE ) ),
+ aLbType ( this, ScResId( LB_TYPE1 ) ),
+
+ maTableBox ( this, ScResId( CTR_TABLEBOX ) ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+
+ aCharSetUser( ScResId( SCSTR_CHARSET_USER ) ),
+ aColumnUser ( ScResId( SCSTR_COLUMN_USER ) ),
+ aFldSepList ( ScResId( SCSTR_FIELDSEP ) ),
+ aTextSepList( ScResId( SCSTR_TEXTSEP ) ),
+ mcTextSep ( ScAsciiOptions::cDefaultTextSep ),
+ maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ),
+ mbFileImport(true)
+{
+ FreeResource();
+ mbFileImport = aDatName.Len() > 0;
+
+ String aName = GetText();
+ // aDatName is empty if invoked during paste from clipboard.
+ if (mbFileImport)
+ {
+ aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" - ["));
+ aName += aDatName;
+ aName += ']';
+ }
+ SetText( aName );
+
+
+ OUString sFieldSeparators;
+ OUString sTextSeparators;
+ bool bMergeDelimiters = false;
+ bool bFixedWidth = false;
+ bool bQuotedFieldAsText = true;
+ bool bDetectSpecialNum = false;
+ sal_Int32 nFromRow = 1;
+ sal_Int32 nCharSet = -1;
+ sal_Int32 nLanguage = 0;
+ if (mbFileImport)
+ // load separators only when importing csv files.
+ load_Separators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
+ bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow, nCharSet, nLanguage);
+ maFieldSeparators = String(sFieldSeparators);
+
+ if( bMergeDelimiters )
+ aCkbAsOnce.Check();
+ if (bQuotedFieldAsText)
+ aCkbQuotedAsText.Check();
+ if (bDetectSpecialNum)
+ aCkbDetectNumber.Check();
+ if( bFixedWidth )
+ aRbFixed.Check();
+ if( nFromRow != 1 )
+ aNfRow.SetValue( nFromRow );
+
+ ByteString bString(maFieldSeparators,RTL_TEXTENCODING_MS_1252);
+ const sal_Char *aSep = bString.GetBuffer();
+ int len = maFieldSeparators.Len();
+ for (int i = 0; i < len; ++i)
+ {
+ switch( aSep[i] )
+ {
+ case '\t': aCkbTab.Check(); break;
+ case ';': aCkbSemicolon.Check(); break;
+ case ',': aCkbComma.Check(); break;
+ case ' ': aCkbSpace.Check(); break;
+ default:
+ aCkbOther.Check();
+ aEdOther.SetText( aEdOther.GetText() + OUString( aSep[i] ) );
+ }
+ }
+
+ // Get Separators from the dialog
+ maFieldSeparators = GetSeparators();
+
+ // Clipboard is always Unicode, else detect.
+ bool bPreselectUnicode = !mbFileImport;
+ // Sniff for Unicode / not
+ if( !bPreselectUnicode && mpDatStream )
+ {
+ Seek( 0 );
+ mpDatStream->StartReadingUnicodeText();
+ ULONG nUniPos = mpDatStream->Tell();
+ if ( nUniPos > 0 )
+ bPreselectUnicode = TRUE; // read 0xfeff/0xfffe
+ else
+ {
+ UINT16 n;
+ *mpDatStream >> n;
+ // Assume that normal ASCII/ANSI/ISO/etc. text doesn't start with
+ // control characters except CR,LF,TAB
+ if ( (n & 0xff00) < 0x2000 )
+ {
+ switch ( n & 0xff00 )
+ {
+ case 0x0900 :
+ case 0x0a00 :
+ case 0x0d00 :
+ break;
+ default:
+ bPreselectUnicode = TRUE;
+ }
+ }
+ mpDatStream->Seek(0);
+ }
+ mnStreamPos = mpDatStream->Tell();
+ }
+
+ aNfRow.SetModifyHdl( LINK( this, ScImportAsciiDlg, FirstRowHdl ) );
+
+ // *** Separator characters ***
+ lcl_FillCombo( aCbTextSep, aTextSepList, mcTextSep );
+ aCbTextSep.SetText( sTextSeparators );
+
+ Link aSeparatorHdl =LINK( this, ScImportAsciiDlg, SeparatorHdl );
+ aCbTextSep.SetSelectHdl( aSeparatorHdl );
+ aCbTextSep.SetModifyHdl( aSeparatorHdl );
+ aCkbTab.SetClickHdl( aSeparatorHdl );
+ aCkbSemicolon.SetClickHdl( aSeparatorHdl );
+ aCkbComma.SetClickHdl( aSeparatorHdl );
+ aCkbAsOnce.SetClickHdl( aSeparatorHdl );
+ aCkbQuotedAsText.SetClickHdl( aSeparatorHdl );
+ aCkbDetectNumber.SetClickHdl( aSeparatorHdl );
+ aCkbSpace.SetClickHdl( aSeparatorHdl );
+ aCkbOther.SetClickHdl( aSeparatorHdl );
+ aEdOther.SetModifyHdl( aSeparatorHdl );
+
+ // *** text encoding ListBox ***
+ // all encodings allowed, including Unicode, but subsets are excluded
+ aLbCharSet.FillFromTextEncodingTable( TRUE );
+ // Insert one "SYSTEM" entry for compatibility in AsciiOptions and system
+ // independent document linkage.
+ aLbCharSet.InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, aCharSetUser );
+ aLbCharSet.SelectTextEncoding( bPreselectUnicode ?
+ RTL_TEXTENCODING_UNICODE : gsl_getSystemTextEncoding() );
+
+ if( nCharSet >= 0 )
+ aLbCharSet.SelectEntryPos( static_cast<USHORT>(nCharSet) );
+
+ SetSelectedCharSet();
+ aLbCharSet.SetSelectHdl( LINK( this, ScImportAsciiDlg, CharSetHdl ) );
+
+ aLbCustomLang.SetLanguageList(
+ LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false);
+ aLbCustomLang.InsertLanguage(LANGUAGE_SYSTEM);
+ aLbCustomLang.SelectLanguage(static_cast<LanguageType>(nLanguage), true);
+
+ // *** column type ListBox ***
+ xub_StrLen nCount = aColumnUser.GetTokenCount();
+ for (xub_StrLen i=0; i<nCount; i++)
+ aLbType.InsertEntry( aColumnUser.GetToken( i ) );
+
+ aLbType.SetSelectHdl( LINK( this, ScImportAsciiDlg, LbColTypeHdl ) );
+ aFtType.Disable();
+ aLbType.Disable();
+
+ // *** table box preview ***
+ maTableBox.SetUpdateTextHdl( LINK( this, ScImportAsciiDlg, UpdateTextHdl ) );
+ maTableBox.InitTypes( aLbType );
+ maTableBox.SetColTypeHdl( LINK( this, ScImportAsciiDlg, ColTypeHdl ) );
+
+ aRbSeparated.SetClickHdl( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
+ aRbFixed.SetClickHdl( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
+
+ SetupSeparatorCtrls();
+ RbSepFixHdl( &aRbFixed );
+
+ UpdateVertical();
+
+ maTableBox.Execute( CSVCMD_NEWCELLTEXTS );
+}
+
+
+ScImportAsciiDlg::~ScImportAsciiDlg()
+{
+ delete[] mpRowPosArray;
+}
+
+
+// ----------------------------------------------------------------------------
+
+bool ScImportAsciiDlg::GetLine( ULONG nLine, String &rText )
+{
+ if (nLine >= ASCIIDLG_MAXROWS || !mpDatStream)
+ return false;
+
+ bool bRet = true;
+ bool bFixed = aRbFixed.IsChecked();
+
+ if (!mpRowPosArray)
+ mpRowPosArray = new ULONG[ASCIIDLG_MAXROWS + 2];
+
+ if (!mnRowPosCount) // complete re-fresh
+ {
+ memset( mpRowPosArray, 0, sizeof(mpRowPosArray[0]) * (ASCIIDLG_MAXROWS+2));
+
+ Seek(0);
+ if ( mpDatStream->GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ mpDatStream->StartReadingUnicodeText();
+
+ mnStreamPos = mpDatStream->Tell();
+ mpRowPosArray[mnRowPosCount] = mnStreamPos;
+ }
+
+ if (nLine >= mnRowPosCount)
+ {
+ // need to work out some more line information
+ do
+ {
+ if (!Seek( mpRowPosArray[mnRowPosCount]) ||
+ mpDatStream->GetError() != ERRCODE_NONE ||
+ mpDatStream->IsEof())
+ {
+ bRet = false;
+ break;
+ }
+ mpDatStream->ReadCsvLine( rText, !bFixed, maFieldSeparators,
+ mcTextSep);
+ mnStreamPos = mpDatStream->Tell();
+ mpRowPosArray[++mnRowPosCount] = mnStreamPos;
+ } while (nLine >= mnRowPosCount &&
+ mpDatStream->GetError() == ERRCODE_NONE &&
+ !mpDatStream->IsEof());
+ if (mpDatStream->IsEof() &&
+ mnStreamPos == mpRowPosArray[mnRowPosCount-1])
+ {
+ // the very end, not even an empty line read
+ bRet = false;
+ --mnRowPosCount;
+ }
+ }
+ else
+ {
+ Seek( mpRowPosArray[nLine]);
+ mpDatStream->ReadCsvLine( rText, !bFixed, maFieldSeparators, mcTextSep);
+ mnStreamPos = mpDatStream->Tell();
+ }
+
+ // #107455# If the file content isn't unicode, ReadUniStringLine
+ // may try to seek beyond the file's end and cause a CANTSEEK error
+ // (depending on the stream type). The error code has to be cleared,
+ // or further read operations (including non-unicode) will fail.
+ if ( mpDatStream->GetError() == ERRCODE_IO_CANTSEEK )
+ mpDatStream->ResetError();
+
+ return bRet;
+}
+
+
+void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )
+{
+ rOpt.SetCharSet( meCharSet );
+ rOpt.SetCharSetSystem( mbCharSetSystem );
+ rOpt.SetLanguage(aLbCustomLang.GetSelectLanguage());
+ rOpt.SetFixedLen( aRbFixed.IsChecked() );
+ rOpt.SetStartRow( (long)aNfRow.GetValue() );
+ maTableBox.FillColumnData( rOpt );
+ if( aRbSeparated.IsChecked() )
+ {
+ rOpt.SetFieldSeps( GetSeparators() );
+ rOpt.SetMergeSeps( aCkbAsOnce.IsChecked() );
+ rOpt.SetTextSep( lcl_CharFromCombo( aCbTextSep, aTextSepList ) );
+ }
+
+ rOpt.SetQuotedAsText(aCkbQuotedAsText.IsChecked());
+ rOpt.SetDetectSpecialNumber(aCkbDetectNumber.IsChecked());
+}
+
+void ScImportAsciiDlg::SetTextToColumnsMode()
+{
+ SetText( maStrTextToColumns );
+ aFtCharSet.Disable();
+ aLbCharSet.Disable();
+ aFtCustomLang.Disable();
+ aLbCustomLang.SelectLanguage(LANGUAGE_SYSTEM);
+ aLbCustomLang.Disable();
+ aFtRow.Disable();
+ aNfRow.Disable();
+
+ // Quoted field as text option is not used for text-to-columns mode.
+ aCkbQuotedAsText.Check(false);
+ aCkbQuotedAsText.Disable();
+
+ // Always detect special numbers for text-to-columns mode.
+ aCkbDetectNumber.Check();
+ aCkbDetectNumber.Disable();
+}
+
+void ScImportAsciiDlg::SaveParameters()
+{
+ if (!mbFileImport)
+ // We save parameters only for file import.
+ return;
+
+ save_Separators( maFieldSeparators, aCbTextSep.GetText(), aCkbAsOnce.IsChecked(),
+ aCkbQuotedAsText.IsChecked(), aCkbDetectNumber.IsChecked(),
+ aRbFixed.IsChecked(),
+ static_cast<sal_Int32>(aNfRow.GetValue()),
+ static_cast<sal_Int32>(aLbCharSet.GetSelectEntryPos()),
+ static_cast<sal_Int32>(aLbCustomLang.GetSelectLanguage()) );
+}
+
+void ScImportAsciiDlg::SetSelectedCharSet()
+{
+ meCharSet = aLbCharSet.GetSelectTextEncoding();
+ mbCharSetSystem = (meCharSet == RTL_TEXTENCODING_DONTKNOW);
+ if( mbCharSetSystem )
+ meCharSet = gsl_getSystemTextEncoding();
+}
+
+String ScImportAsciiDlg::GetSeparators() const
+{
+ String aSepChars;
+ if( aCkbTab.IsChecked() )
+ aSepChars += '\t';
+ if( aCkbSemicolon.IsChecked() )
+ aSepChars += ';';
+ if( aCkbComma.IsChecked() )
+ aSepChars += ',';
+ if( aCkbSpace.IsChecked() )
+ aSepChars += ' ';
+ if( aCkbOther.IsChecked() )
+ aSepChars += aEdOther.GetText();
+ return aSepChars;
+}
+
+void ScImportAsciiDlg::SetupSeparatorCtrls()
+{
+ BOOL bEnable = aRbSeparated.IsChecked();
+ aCkbTab.Enable( bEnable );
+ aCkbSemicolon.Enable( bEnable );
+ aCkbComma.Enable( bEnable );
+ aCkbSpace.Enable( bEnable );
+ aCkbOther.Enable( bEnable );
+ aEdOther.Enable( bEnable );
+ aCkbAsOnce.Enable( bEnable );
+ aFtTextSep.Enable( bEnable );
+ aCbTextSep.Enable( bEnable );
+}
+
+void ScImportAsciiDlg::UpdateVertical()
+{
+ mnRowPosCount = 0;
+ if (mpDatStream)
+ mpDatStream->SetStreamCharSet(meCharSet);
+}
+
+
+// ----------------------------------------------------------------------------
+
+IMPL_LINK( ScImportAsciiDlg, RbSepFixHdl, RadioButton*, pButton )
+{
+ DBG_ASSERT( pButton, "ScImportAsciiDlg::RbSepFixHdl - missing sender" );
+
+ if( (pButton == &aRbFixed) || (pButton == &aRbSeparated) )
+ {
+ SetPointer( Pointer( POINTER_WAIT ) );
+ if( aRbFixed.IsChecked() )
+ maTableBox.SetFixedWidthMode();
+ else
+ maTableBox.SetSeparatorsMode();
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ SetupSeparatorCtrls();
+ }
+ return 0;
+}
+
+IMPL_LINK( ScImportAsciiDlg, SeparatorHdl, Control*, pCtrl )
+{
+ DBG_ASSERT( pCtrl, "ScImportAsciiDlg::SeparatorHdl - missing sender" );
+ DBG_ASSERT( !aRbFixed.IsChecked(), "ScImportAsciiDlg::SeparatorHdl - not allowed in fixed width" );
+
+ /* #i41550# First update state of the controls. The GetSeparators()
+ function needs final state of the check boxes. */
+ if( (pCtrl == &aCkbOther) && aCkbOther.IsChecked() )
+ aEdOther.GrabFocus();
+ else if( pCtrl == &aEdOther )
+ aCkbOther.Check( aEdOther.GetText().Len() > 0 );
+
+ String aOldFldSeps( maFieldSeparators);
+ maFieldSeparators = GetSeparators();
+ sal_Unicode cOldSep = mcTextSep;
+ mcTextSep = lcl_CharFromCombo( aCbTextSep, aTextSepList );
+ // Any separator changed may result in completely different lines due to
+ // embedded line breaks.
+ if (cOldSep != mcTextSep || aOldFldSeps != maFieldSeparators)
+ UpdateVertical();
+
+ maTableBox.Execute( CSVCMD_NEWCELLTEXTS );
+ return 0;
+}
+
+IMPL_LINK( ScImportAsciiDlg, CharSetHdl, SvxTextEncodingBox*, pCharSetBox )
+{
+ DBG_ASSERT( pCharSetBox, "ScImportAsciiDlg::CharSetHdl - missing sender" );
+
+ if( (pCharSetBox == &aLbCharSet) && (pCharSetBox->GetSelectEntryCount() == 1) )
+ {
+ SetPointer( Pointer( POINTER_WAIT ) );
+ CharSet eOldCharSet = meCharSet;
+ SetSelectedCharSet();
+ // switching char-set invalidates 8bit -> String conversions
+ if (eOldCharSet != meCharSet)
+ UpdateVertical();
+
+ maTableBox.Execute( CSVCMD_NEWCELLTEXTS );
+ SetPointer( Pointer( POINTER_ARROW ) );
+ }
+ return 0;
+}
+
+IMPL_LINK( ScImportAsciiDlg, FirstRowHdl, NumericField*, pNumField )
+{
+ DBG_ASSERT( pNumField, "ScImportAsciiDlg::FirstRowHdl - missing sender" );
+ maTableBox.Execute( CSVCMD_SETFIRSTIMPORTLINE, sal::static_int_cast<sal_Int32>( pNumField->GetValue() - 1 ) );
+ return 0;
+}
+
+IMPL_LINK( ScImportAsciiDlg, LbColTypeHdl, ListBox*, pListBox )
+{
+ DBG_ASSERT( pListBox, "ScImportAsciiDlg::LbColTypeHdl - missing sender" );
+ if( pListBox == &aLbType )
+ maTableBox.Execute( CSVCMD_SETCOLUMNTYPE, pListBox->GetSelectEntryPos() );
+ return 0;
+}
+
+IMPL_LINK( ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox*, EMPTYARG )
+{
+ sal_Int32 nBaseLine = maTableBox.GetFirstVisLine();
+ sal_Int32 nRead = maTableBox.GetVisLineCount();
+ // If mnRowPosCount==0, this is an initializing call, read ahead for row
+ // count and resulting scroll bar size and position to be able to scroll at
+ // all. When adding lines, read only the amount of next lines to be
+ // displayed.
+ if (!mnRowPosCount || nRead > CSV_PREVIEW_LINES)
+ nRead = CSV_PREVIEW_LINES;
+
+ sal_Int32 i;
+ for (i = 0; i < nRead; i++)
+ {
+ if (!GetLine( nBaseLine + i, maPreviewLine[i]))
+ break;
+ }
+ for (; i < CSV_PREVIEW_LINES; i++)
+ maPreviewLine[i].Erase();
+
+ maTableBox.Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
+ bool bMergeSep = (aCkbAsOnce.IsChecked() == TRUE);
+ maTableBox.SetUniStrings( maPreviewLine, maFieldSeparators, mcTextSep, bMergeSep);
+
+ return 0;
+}
+
+IMPL_LINK( ScImportAsciiDlg, ColTypeHdl, ScCsvTableBox*, pTableBox )
+{
+ DBG_ASSERT( pTableBox, "ScImportAsciiDlg::ColTypeHdl - missing sender" );
+
+ sal_Int32 nType = pTableBox->GetSelColumnType();
+ sal_Int32 nTypeCount = aLbType.GetEntryCount();
+ bool bEmpty = (nType == CSV_TYPE_MULTI);
+ bool bEnable = ((0 <= nType) && (nType < nTypeCount)) || bEmpty;
+
+ aFtType.Enable( bEnable );
+ aLbType.Enable( bEnable );
+
+ Link aSelHdl = aLbType.GetSelectHdl();
+ aLbType.SetSelectHdl( Link() );
+ if( bEmpty )
+ aLbType.SetNoSelection();
+ else if( bEnable )
+ aLbType.SelectEntryPos( static_cast< sal_uInt16 >( nType ) );
+ aLbType.SetSelectHdl( aSelHdl );
+
+ return 0;
+}
diff --git a/sc/source/ui/dbgui/scuiimoptdlg.cxx b/sc/source/ui/dbgui/scuiimoptdlg.cxx
new file mode 100644
index 000000000000..5440f515c86a
--- /dev/null
+++ b/sc/source/ui/dbgui/scuiimoptdlg.cxx
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "scuiimoptdlg.hxx"
+#include "scresid.hxx"
+#include "imoptdlg.hrc"
+#include <rtl/tencinfo.h>
+//========================================================================
+// ScDelimiterTable
+//========================================================================
+
+class ScDelimiterTable
+{
+public:
+ ScDelimiterTable( const String& rDelTab )
+ : theDelTab ( rDelTab ),
+ cSep ( '\t' ),
+ nCount ( rDelTab.GetTokenCount('\t') ),
+ nIter ( 0 )
+ {}
+
+ USHORT GetCode( const String& rDelimiter ) const;
+ String GetDelimiter( sal_Unicode nCode ) const;
+
+ String FirstDel() { nIter = 0; return theDelTab.GetToken( nIter, cSep ); }
+ String NextDel() { nIter +=2; return theDelTab.GetToken( nIter, cSep ); }
+
+private:
+ const String theDelTab;
+ const sal_Unicode cSep;
+ const xub_StrLen nCount;
+ xub_StrLen nIter;
+};
+
+//------------------------------------------------------------------------
+
+USHORT ScDelimiterTable::GetCode( const String& rDel ) const
+{
+ sal_Unicode nCode = 0;
+ xub_StrLen i = 0;
+
+ if ( nCount >= 2 )
+ {
+ while ( i<nCount )
+ {
+ if ( rDel == theDelTab.GetToken( i, cSep ) )
+ {
+ nCode = (sal_Unicode) theDelTab.GetToken( i+1, cSep ).ToInt32();
+ i = nCount;
+ }
+ else
+ i += 2;
+ }
+ }
+
+ return nCode;
+}
+
+//------------------------------------------------------------------------
+
+String ScDelimiterTable::GetDelimiter( sal_Unicode nCode ) const
+{
+ String aStrDel;
+ xub_StrLen i = 0;
+
+ if ( nCount >= 2 )
+ {
+ while ( i<nCount )
+ {
+ if ( nCode == (sal_Unicode) theDelTab.GetToken( i+1, cSep ).ToInt32() )
+ {
+ aStrDel = theDelTab.GetToken( i, cSep );
+ i = nCount;
+ }
+ else
+ i += 2;
+ }
+ }
+
+ return aStrDel;
+}
+
+//========================================================================
+// ScImportOptionsDlg
+//========================================================================
+
+ScImportOptionsDlg::ScImportOptionsDlg(
+ Window* pParent,
+ BOOL bAscii,
+ const ScImportOptions* pOptions,
+ const String* pStrTitle,
+ BOOL bMultiByte,
+ BOOL bOnlyDbtoolsEncodings,
+ BOOL bImport )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_IMPORTOPT ) ),
+ aFlFieldOpt ( this, ScResId( FL_FIELDOPT ) ),
+ aFtFont ( this, ScResId( FT_FONT ) ),
+ aLbFont ( this, ScResId( bAscii ? DDLB_FONT : LB_FONT ) ),
+ aFtFieldSep ( this, ScResId( FT_FIELDSEP ) ),
+ aEdFieldSep ( this, ScResId( ED_FIELDSEP ) ),
+ aFtTextSep ( this, ScResId( FT_TEXTSEP ) ),
+ aEdTextSep ( this, ScResId( ED_TEXTSEP ) ),
+ aCbFixed ( this, ScResId( CB_FIXEDWIDTH ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aCbShown ( this, ScResId( CB_SAVESHOWN ) )
+{
+ // im Ctor-Initializer nicht moeglich (MSC kann das nicht):
+ pFieldSepTab = new ScDelimiterTable( String(ScResId(SCSTR_FIELDSEP)) );
+ pTextSepTab = new ScDelimiterTable( String(ScResId(SCSTR_TEXTSEP)) );
+
+ String aStr = pFieldSepTab->FirstDel();
+ sal_Unicode nCode;
+
+ while ( aStr.Len() > 0 )
+ {
+ aEdFieldSep.InsertEntry( aStr );
+ aStr = pFieldSepTab->NextDel();
+ }
+
+ aStr = pTextSepTab->FirstDel();
+
+ while ( aStr.Len() > 0 )
+ {
+ aEdTextSep.InsertEntry( aStr );
+ aStr = pTextSepTab->NextDel();
+ }
+
+ aEdFieldSep.SetText( aEdFieldSep.GetEntry(0) );
+ aEdTextSep.SetText( aEdTextSep.GetEntry(0) );
+
+ if ( bOnlyDbtoolsEncodings )
+ {
+ // Even dBase export allows multibyte now
+ if ( bMultiByte )
+ aLbFont.FillFromDbTextEncodingMap( bImport );
+ else
+ aLbFont.FillFromDbTextEncodingMap( bImport, RTL_TEXTENCODING_INFO_MULTIBYTE );
+ }
+ else if ( !bAscii )
+ { //!TODO: Unicode would need work in each filter
+ if ( bMultiByte )
+ aLbFont.FillFromTextEncodingTable( bImport, RTL_TEXTENCODING_INFO_UNICODE );
+ else
+ aLbFont.FillFromTextEncodingTable( bImport, RTL_TEXTENCODING_INFO_UNICODE |
+ RTL_TEXTENCODING_INFO_MULTIBYTE );
+ }
+ else
+ {
+ if ( pOptions )
+ {
+ nCode = pOptions->nFieldSepCode;
+ aStr = pFieldSepTab->GetDelimiter( nCode );
+
+ if ( !aStr.Len() )
+ aEdFieldSep.SetText( String((sal_Unicode)nCode) );
+ else
+ aEdFieldSep.SetText( aStr );
+
+ nCode = pOptions->nTextSepCode;
+ aStr = pTextSepTab->GetDelimiter( nCode );
+
+ if ( !aStr.Len() )
+ aEdTextSep.SetText( String((sal_Unicode)nCode) );
+ else
+ aEdTextSep.SetText( aStr );
+ }
+ // all encodings allowed, even Unicode
+ aLbFont.FillFromTextEncodingTable( bImport );
+ }
+
+ if( bAscii )
+ {
+ Size aWinSize( GetSizePixel() );
+ aWinSize.Height() = aCbFixed.GetPosPixel().Y() + aCbFixed.GetSizePixel().Height();
+ Size aDiffSize( LogicToPixel( Size( 0, 6 ), MapMode( MAP_APPFONT ) ) );
+ aWinSize.Height() += aDiffSize.Height();
+ SetSizePixel( aWinSize );
+ aCbFixed.Show();
+ aCbFixed.SetClickHdl( LINK( this, ScImportOptionsDlg, FixedWidthHdl ) );
+ aCbFixed.Check( FALSE );
+ aCbShown.Show();
+ aCbShown.Check( TRUE );
+ }
+ else
+ {
+ aFlFieldOpt.SetText( aFtFont.GetText() );
+ aFtFieldSep.Hide();
+ aFtTextSep.Hide();
+ aFtFont.Hide();
+ aEdFieldSep.Hide();
+ aEdTextSep.Hide();
+ aCbFixed.Hide();
+ aCbShown.Hide();
+ aLbFont.GrabFocus();
+ aLbFont.SetDoubleClickHdl( LINK( this, ScImportOptionsDlg, DoubleClickHdl ) );
+ }
+
+ aLbFont.SelectTextEncoding( pOptions ? pOptions->eCharSet :
+ gsl_getSystemTextEncoding() );
+
+ // optionaler Titel:
+ if ( pStrTitle )
+ SetText( *pStrTitle );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScImportOptionsDlg::~ScImportOptionsDlg()
+{
+ delete pFieldSepTab;
+ delete pTextSepTab;
+}
+
+//------------------------------------------------------------------------
+
+void ScImportOptionsDlg::GetImportOptions( ScImportOptions& rOptions ) const
+{
+ rOptions.SetTextEncoding( aLbFont.GetSelectTextEncoding() );
+
+ if ( aCbFixed.IsVisible() )
+ {
+ rOptions.nFieldSepCode = GetCodeFromCombo( aEdFieldSep );
+ rOptions.nTextSepCode = GetCodeFromCombo( aEdTextSep );
+ rOptions.bFixedWidth = aCbFixed.IsChecked();
+ rOptions.bSaveAsShown = aCbShown.IsChecked();
+ }
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScImportOptionsDlg::GetCodeFromCombo( const ComboBox& rEd ) const
+{
+ ScDelimiterTable* pTab;
+ String aStr( rEd.GetText() );
+ USHORT nCode;
+
+ if ( &rEd == &aEdTextSep )
+ pTab = pTextSepTab;
+ else
+ pTab = pFieldSepTab;
+
+ if ( !aStr.Len() )
+ {
+ nCode = 0; // kein Trennzeichen
+ }
+ else
+ {
+ nCode = pTab->GetCode( aStr );
+
+ if ( nCode == 0 )
+ nCode = (USHORT)aStr.GetChar(0);
+ }
+
+ return nCode;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScImportOptionsDlg, FixedWidthHdl, CheckBox*, pCheckBox )
+{
+ if( pCheckBox == &aCbFixed )
+ {
+ BOOL bEnable = !aCbFixed.IsChecked();
+ aFtFieldSep.Enable( bEnable );
+ aEdFieldSep.Enable( bEnable );
+ aFtTextSep.Enable( bEnable );
+ aEdTextSep.Enable( bEnable );
+ aCbShown.Enable( bEnable );
+ }
+ return 0;
+}
+
+ IMPL_LINK( ScImportOptionsDlg, DoubleClickHdl, ListBox*, pLb )
+{
+ if ( pLb == &aLbFont )
+ {
+ aBtnOk.Click();
+ }
+ return 0;
+}
diff --git a/sc/source/ui/dbgui/sfiltdlg.cxx b/sc/source/ui/dbgui/sfiltdlg.cxx
new file mode 100644
index 000000000000..f70fbb094c92
--- /dev/null
+++ b/sc/source/ui/dbgui/sfiltdlg.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+#include <sfx2/dispatch.hxx>
+
+#include "uiitems.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "reffact.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+
+#include "foptmgr.hxx"
+
+#include "globstr.hrc"
+#include "filter.hrc"
+
+#define _SFILTDLG_CXX
+#include "filtdlg.hxx"
+#undef _SFILTDLG_CXX
+#include <vcl/msgbox.hxx>
+
+// DEFINE --------------------------------------------------------------------
+
+#define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
+ ScGlobal::GetRscString(rid) ).Execute()
+
+
+//============================================================================
+// class ScSpecialFilterDialog
+
+//----------------------------------------------------------------------------
+
+ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SPEC_FILTER ),
+ //
+ aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA ) ),
+ aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA ) ),
+ aEdFilterArea ( this, this, ScResId( ED_CRITERIA_AREA ) ),
+ aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA ), &aEdFilterArea, this ),
+ //
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ _INIT_COMMON_FILTER_RSCOBJS
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+ //
+ pOptionsMgr ( NULL ),
+ nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
+ theQueryData ( ((const ScQueryItem&)
+ rArgSet.Get( nWhichQuery )).GetQueryData() ),
+ pOutItem ( NULL ),
+ pViewData ( NULL ),
+ pDoc ( NULL ),
+ pRefInputEdit ( NULL ),
+ bRefInputMode ( FALSE ),
+ pTimer ( NULL )
+{
+ Init( rArgSet );
+ aEdFilterArea.GrabFocus();
+
+ FreeResource();
+
+ // Hack: RefInput-Kontrolle
+ pTimer = new Timer;
+ pTimer->SetTimeout( 50 ); // 50ms warten
+ pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
+ pTimer->Start();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScSpecialFilterDlg::~ScSpecialFilterDlg()
+{
+ USHORT nEntries = aLbFilterArea.GetEntryCount();
+ USHORT i;
+
+ for ( i=1; i<nEntries; i++ )
+ delete (String*)aLbFilterArea.GetEntryData( i );
+
+ delete pOptionsMgr;
+
+ if ( pOutItem )
+ delete pOutItem;
+
+ // Hack: RefInput-Kontrolle
+ pTimer->Stop();
+ delete pTimer;
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
+{
+ const ScQueryItem& rQueryItem = (const ScQueryItem&)
+ rArgSet.Get( nWhichQuery );
+
+ aBtnOk.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
+ aLbFilterArea.SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
+ aEdFilterArea.SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
+
+ pViewData = rQueryItem.GetViewData();
+ pDoc = pViewData ? pViewData->GetDocument() : NULL;
+
+ aEdFilterArea.SetText( EMPTY_STRING ); // may be overwritten below
+
+ if ( pViewData && pDoc )
+ {
+ if(pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable();
+
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ const USHORT nCount = pRangeNames ? pRangeNames->GetCount() : 0;
+
+ /*
+ * Aus den RangeNames des Dokumentes werden nun die
+ * gemerkt, bei denen es sich um Filter-Bereiche handelt
+ */
+
+ aLbFilterArea.Clear();
+ aLbFilterArea.InsertEntry( aStrUndefined, 0 );
+
+ if ( nCount > 0 )
+ {
+ String aString;
+ ScRangeData* pData = NULL;
+ USHORT nInsert = 0;
+
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ pData = (ScRangeData*)(pRangeNames->At( i ));
+ if ( pData )
+ {
+ if ( pData->HasType( RT_CRITERIA ) )
+ {
+ pData->GetName( aString );
+ nInsert = aLbFilterArea.InsertEntry( aString );
+ pData->GetSymbol( aString );
+ aLbFilterArea.SetEntryData( nInsert,
+ new String( aString ) );
+ }
+ }
+ }
+ }
+
+ // is there a stored source range?
+
+ ScRange aAdvSource;
+ if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
+ {
+ String aRefStr;
+ aAdvSource.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ aEdFilterArea.SetRefString( aRefStr );
+ }
+ }
+
+ aLbFilterArea.SelectEntryPos( 0 );
+
+ // Optionen initialisieren lassen:
+
+ pOptionsMgr = new ScFilterOptionsMgr(
+ this,
+ pViewData,
+ theQueryData,
+ aBtnMore,
+ aBtnCase,
+ aBtnRegExp,
+ aBtnHeader,
+ aBtnUnique,
+ aBtnCopyResult,
+ aBtnDestPers,
+ aLbCopyArea,
+ aEdCopyArea,
+ aRbCopyArea,
+ aFtDbAreaLabel,
+ aFtDbArea,
+ aFlOptions,
+ aStrNoName,
+ aStrUndefined );
+
+ // #35206# Spezialfilter braucht immer Spaltenkoepfe
+ aBtnHeader.Check(TRUE);
+ aBtnHeader.Disable();
+
+ // Modal-Modus einschalten
+// SetDispatcherLock( TRUE );
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScSpecialFilterDlg::Close()
+{
+ if (pViewData)
+ pViewData->GetDocShell()->CancelAutoDBRange();
+
+ return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
+}
+
+
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Edit angezeigt wird.
+
+void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( pRefInputEdit );
+
+ String aRefStr;
+ const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
+
+ if ( pRefInputEdit == &aEdCopyArea)
+ rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, eConv );
+ else if ( pRefInputEdit == &aEdFilterArea)
+ rRef.Format( aRefStr, SCR_ABS_3D, pDocP, eConv );
+
+ pRefInputEdit->SetRefString( aRefStr );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScSpecialFilterDlg::SetActive()
+{
+ if ( bRefInputMode )
+ {
+ if ( pRefInputEdit == &aEdCopyArea )
+ {
+ aEdCopyArea.GrabFocus();
+ if ( aEdCopyArea.GetModifyHdl().IsSet() )
+ ((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea );
+ }
+ else if ( pRefInputEdit == &aEdFilterArea )
+ {
+ aEdFilterArea.GrabFocus();
+ FilterAreaModHdl( &aEdFilterArea );
+ }
+ }
+ else
+ GrabFocus();
+
+ RefInputDone();
+}
+
+
+//----------------------------------------------------------------------------
+
+ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
+ const ScRange& rSource )
+{
+ if ( pOutItem ) DELETEZ( pOutItem );
+ pOutItem = new ScQueryItem( nWhichQuery, &rParam );
+ pOutItem->SetAdvancedQuerySource( &rSource );
+
+ return pOutItem;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScSpecialFilterDlg::IsRefInputMode() const
+{
+ return bRefInputMode;
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+// ========
+
+IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn )
+{
+ DBG_ASSERT( pDoc && pViewData, "Document or ViewData not found. :-/" );
+
+ if ( (pBtn == &aBtnOk) && pDoc && pViewData )
+ {
+ String theCopyStr( aEdCopyArea.GetText() );
+ String theAreaStr( aEdFilterArea.GetText() );
+ ScQueryParam theOutParam( theQueryData );
+ ScAddress theAdrCopy;
+ BOOL bEditInputOk = TRUE;
+ BOOL bQueryOk = FALSE;
+ ScRange theFilterArea;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ if ( aBtnCopyResult.IsChecked() )
+ {
+ xub_StrLen nColonPos = theCopyStr.Search( ':' );
+
+ if ( STRING_NOTFOUND != nColonPos )
+ theCopyStr.Erase( nColonPos );
+
+ USHORT nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );
+
+ if ( SCA_VALID != (nResult & SCA_VALID) )
+ {
+ if ( !aBtnMore.GetState() )
+ aBtnMore.SetState( TRUE );
+
+ ERRORBOX( STR_INVALID_TABREF );
+ aEdCopyArea.GrabFocus();
+ bEditInputOk = FALSE;
+ }
+ }
+
+ if ( bEditInputOk )
+ {
+ USHORT nResult = ScRange().Parse( theAreaStr, pDoc, eConv );
+
+ if ( SCA_VALID != (nResult & SCA_VALID) )
+ {
+ ERRORBOX( STR_INVALID_TABREF );
+ aEdFilterArea.GrabFocus();
+ bEditInputOk = FALSE;
+ }
+ }
+
+ if ( bEditInputOk )
+ {
+ /*
+ * Alle Edit-Felder enthalten gueltige Bereiche.
+ * Nun wird versucht aus dem Filterbereich
+ * ein ScQueryParam zu erzeugen:
+ */
+
+ USHORT nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );
+
+ if ( SCA_VALID == (nResult & SCA_VALID) )
+ {
+ ScAddress& rStart = theFilterArea.aStart;
+ ScAddress& rEnd = theFilterArea.aEnd;
+
+ if ( aBtnCopyResult.IsChecked() )
+ {
+ theOutParam.bInplace = FALSE;
+ theOutParam.nDestTab = theAdrCopy.Tab();
+ theOutParam.nDestCol = theAdrCopy.Col();
+ theOutParam.nDestRow = theAdrCopy.Row();
+ }
+ else
+ {
+ theOutParam.bInplace = TRUE;
+ theOutParam.nDestTab = 0;
+ theOutParam.nDestCol = 0;
+ theOutParam.nDestRow = 0;
+ }
+
+ theOutParam.bHasHeader = aBtnHeader.IsChecked();
+ theOutParam.bByRow = TRUE;
+ theOutParam.bCaseSens = aBtnCase.IsChecked();
+ theOutParam.bRegExp = aBtnRegExp.IsChecked();
+ theOutParam.bDuplicate = !aBtnUnique.IsChecked();
+ theOutParam.bDestPers = aBtnDestPers.IsChecked();
+
+ bQueryOk =
+ pDoc->CreateQueryParam( rStart.Col(),
+ rStart.Row(),
+ rEnd.Col(),
+ rEnd.Row(),
+ rStart.Tab(),
+ theOutParam );
+
+ // an der DB-Collection koennen nur MAXQUERY Filter-Eintraege
+ // gespeichert werden
+
+ if ( bQueryOk && theOutParam.GetEntryCount() > MAXQUERY &&
+ theOutParam.GetEntry(MAXQUERY).bDoQuery )
+ {
+ bQueryOk = FALSE; // zu viele
+ //! andere Fehlermeldung ??
+ }
+ }
+ }
+
+ if ( bQueryOk )
+ {
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ GetOutputItem( theOutParam, theFilterArea ), 0L, 0L );
+ Close();
+ }
+ else
+ {
+ ERRORBOX( STR_INVALID_QUERYAREA );
+ aEdFilterArea.GrabFocus();
+ }
+ }
+ else if ( pBtn == &aBtnCancel )
+ {
+ Close();
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer )
+{
+ // alle 50ms nachschauen, ob RefInputMode noch stimmt
+
+ if( (_pTimer == pTimer) && IsActive() )
+ {
+ if( aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus() )
+ {
+ pRefInputEdit = &aEdCopyArea;
+ bRefInputMode = TRUE;
+ }
+ else if( aEdFilterArea.HasFocus() || aRbFilterArea.HasFocus() )
+ {
+ pRefInputEdit = &aEdFilterArea;
+ bRefInputMode = TRUE;
+ }
+ else if( bRefInputMode )
+ {
+ pRefInputEdit = NULL;
+ bRefInputMode = FALSE;
+ }
+ }
+
+ pTimer->Start();
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb )
+{
+ if ( pLb == &aLbFilterArea )
+ {
+ String aString;
+ USHORT nSelPos = aLbFilterArea.GetSelectEntryPos();
+
+ if ( nSelPos > 0 )
+ aString = *(String*)aLbFilterArea.GetEntryData( nSelPos );
+
+ aEdFilterArea.SetText( aString );
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd )
+{
+ if ( pEd == &aEdFilterArea )
+ {
+ if ( pDoc && pViewData )
+ {
+ String theCurAreaStr = pEd->GetText();
+ USHORT nResult = ScRange().Parse( theCurAreaStr, pDoc );
+
+ if ( SCA_VALID == (nResult & SCA_VALID) )
+ {
+ String* pStr = NULL;
+ BOOL bFound = FALSE;
+ USHORT i = 0;
+ USHORT nCount = aLbFilterArea.GetEntryCount();
+
+ for ( i=1; i<nCount && !bFound; i++ )
+ {
+ pStr = (String*)aLbFilterArea.GetEntryData( i );
+ bFound = (theCurAreaStr == *pStr);
+ }
+
+ if ( bFound )
+ aLbFilterArea.SelectEntryPos( --i );
+ else
+ aLbFilterArea.SelectEntryPos( 0 );
+ }
+ }
+ else
+ aLbFilterArea.SelectEntryPos( 0 );
+ }
+
+ return 0;
+}
+
+
diff --git a/sc/source/ui/dbgui/sortdlg.cxx b/sc/source/ui/dbgui/sortdlg.cxx
new file mode 100644
index 000000000000..f2a733af3aa8
--- /dev/null
+++ b/sc/source/ui/dbgui/sortdlg.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+#include <vcl/msgbox.hxx>
+#include "tpsort.hxx"
+#include "sortdlg.hxx"
+#include "scresid.hxx"
+#include "sortdlg.hrc"
+
+#if !LAYOUT_SFX_TABDIALOG_BROKEN
+#include <layout/layout-pre.hxx>
+#endif
+
+ScSortDlg::ScSortDlg( Window* pParent,
+ const SfxItemSet* pArgSet ) :
+ SfxTabDialog( pParent,
+ ScResId( RID_SCDLG_SORT ),
+ pArgSet ),
+ bIsHeaders ( FALSE ),
+ bIsByRows ( FALSE )
+
+{
+#if LAYOUT_SFX_TABDIALOG_BROKEN
+ AddTabPage( TP_FIELDS, ScTabPageSortFields::Create, 0 );
+ AddTabPage( TP_OPTIONS, ScTabPageSortOptions::Create, 0 );
+#else
+ String fields = rtl::OUString::createFromAscii ("fields");
+ AddTabPage( TP_FIELDS, fields, ScTabPageSortFields::Create, 0, FALSE, TAB_APPEND);
+ String options = rtl::OUString::createFromAscii ("options");
+ AddTabPage( TP_OPTIONS, options, ScTabPageSortOptions::Create, 0, FALSE, TAB_APPEND);
+#endif
+ FreeResource();
+}
+
+__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/dbgui/subtdlg.cxx b/sc/source/ui/dbgui/subtdlg.cxx
new file mode 100644
index 000000000000..2c9cba31cd13
--- /dev/null
+++ b/sc/source/ui/dbgui/subtdlg.cxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "tpsubt.hxx"
+#include "scresid.hxx"
+#include "subtdlg.hxx"
+#include "subtdlg.hrc"
+
+
+//==================================================================
+
+ScSubTotalDlg::ScSubTotalDlg( Window* pParent,
+ const SfxItemSet* pArgSet ) :
+ SfxTabDialog( pParent,
+ ScResId( RID_SCDLG_SUBTOTALS ),
+ pArgSet ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) )
+{
+ AddTabPage( PAGE_GROUP1, ScTpSubTotalGroup1::Create, 0 );
+ AddTabPage( PAGE_GROUP2, ScTpSubTotalGroup2::Create, 0 );
+ AddTabPage( PAGE_GROUP3, ScTpSubTotalGroup3::Create, 0 );
+ AddTabPage( PAGE_OPTIONS, ScTpSubTotalOptions::Create, 0 );
+ aBtnRemove.SetClickHdl( LINK( this, ScSubTotalDlg, RemoveHdl ) );
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScSubTotalDlg, RemoveHdl, PushButton *, pBtn )
+{
+ if ( pBtn == &aBtnRemove )
+ {
+ EndDialog( SCRET_REMOVE );
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScSubTotalDlg, RemoveHdl, PushButton *, pBtn )
+
diff --git a/sc/source/ui/dbgui/textimportoptions.cxx b/sc/source/ui/dbgui/textimportoptions.cxx
new file mode 100644
index 000000000000..be918d2a0fbd
--- /dev/null
+++ b/sc/source/ui/dbgui/textimportoptions.cxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * 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: langbox.hxx,v $
+ * $Revision: 1.4.242.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"
+
+#undef SC_DLLIMPLEMENTATION
+
+//------------------------------------------------------------------------
+
+#include "textimportoptions.hxx"
+#include "textimportoptions.hrc"
+
+#include "scresid.hxx"
+#include "vcl/window.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/svapp.hxx"
+
+ScTextImportOptionsDlg::ScTextImportOptionsDlg(Window* pParent) :
+ ModalDialog(pParent, ScResId(RID_SCDLG_TEXT_IMPORT_OPTIONS)),
+
+ maBtnOk(this, ScResId(BTN_OK)),
+ maBtnCancel(this, ScResId(BTN_CANCEL)),
+ maBtnHelp(this, ScResId(BTN_HELP)),
+ maFlChooseLang(this, ScResId(FL_CHOOSE_LANG)),
+ maRbAutomatic(this, ScResId(RB_AUTOMATIC)),
+ maRbCustom(this, ScResId(RB_CUSTOM)),
+ maLbCustomLang(this, ScResId(LB_CUSTOM_LANG)),
+ maFlOption(this, ScResId(FL_OPTION)),
+ maBtnConvertDate(this, ScResId(BTN_CONVERT_DATE))
+{
+ FreeResource();
+ init();
+}
+
+ScTextImportOptionsDlg::~ScTextImportOptionsDlg()
+{
+}
+
+short ScTextImportOptionsDlg::Execute()
+{
+ return ModalDialog::Execute();
+}
+
+LanguageType ScTextImportOptionsDlg::getLanguageType() const
+{
+ if (maRbAutomatic.IsChecked())
+ return LANGUAGE_SYSTEM;
+
+ return maLbCustomLang.GetSelectLanguage();
+}
+
+bool ScTextImportOptionsDlg::isDateConversionSet() const
+{
+ return maBtnConvertDate.IsChecked();
+}
+
+void ScTextImportOptionsDlg::init()
+{
+ Link aLink = LINK( this, ScTextImportOptionsDlg, OKHdl );
+ maBtnOk.SetClickHdl(aLink);
+ aLink = LINK( this, ScTextImportOptionsDlg, RadioHdl );
+ maRbAutomatic.SetClickHdl(aLink);
+ maRbCustom.SetClickHdl(aLink);
+
+ maRbAutomatic.Check(true);
+
+ maLbCustomLang.SetLanguageList(
+ LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false);
+
+ LanguageType eLang = Application::GetSettings().GetLanguage();
+ maLbCustomLang.SelectLanguage(eLang);
+ maLbCustomLang.Disable();
+}
+
+IMPL_LINK( ScTextImportOptionsDlg, OKHdl, OKButton*, EMPTYARG )
+{
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK( ScTextImportOptionsDlg, RadioHdl, RadioButton*, pBtn )
+{
+ if (pBtn == &maRbAutomatic)
+ {
+ maLbCustomLang.Disable();
+ }
+ else if (pBtn == &maRbCustom)
+ {
+ maLbCustomLang.Enable();
+ }
+ return 0;
+}
+
diff --git a/sc/source/ui/dbgui/textimportoptions.src b/sc/source/ui/dbgui/textimportoptions.src
new file mode 100644
index 000000000000..69e2d69b3142
--- /dev/null
+++ b/sc/source/ui/dbgui/textimportoptions.src
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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 "textimportoptions.hrc"
+
+ModalDialog RID_SCDLG_TEXT_IMPORT_OPTIONS
+{
+ Text [ en-US ] = "Import Options" ;
+ Size = MAP_APPFONT ( 230 , 101 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ OutputSize = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 175, 6 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ DefButton = TRUE ;
+ };
+
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 175, 23 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 175, 43 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ FixedLine FL_CHOOSE_LANG
+ {
+ Pos = MAP_APPFONT( 6, 3 ) ;
+ Size = MAP_APPFONT( 165, 14 ) ;
+
+ Text [ en-US ] = "Select the language to use for import" ;
+ };
+
+ RadioButton RB_AUTOMATIC
+ {
+ Pos = MAP_APPFONT( 12, 20 ) ;
+ Size = MAP_APPFONT( 159, 10 ) ;
+ TabStop = TRUE ;
+
+ Text [ en-US ] = "Automatic" ;
+ };
+
+ RadioButton RB_CUSTOM
+ {
+ Pos = MAP_APPFONT( 12, 34 ) ;
+ Size = MAP_APPFONT( 159, 10 ) ;
+ TabStop = TRUE ;
+
+ Text [ en-US ] = "Custom" ;
+ };
+
+ ListBox LB_CUSTOM_LANG
+ {
+ Pos = MAP_APPFONT( 20, 50 ) ;
+ Size = MAP_APPFONT( 140, 120 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+
+ FixedLine FL_OPTION
+ {
+ Pos = MAP_APPFONT( 6, 70 );
+ Size = MAP_APPFONT( 165, 14 );
+ Text [ en-US ] = "Options" ;
+ };
+
+ CheckBox BTN_CONVERT_DATE
+ {
+ Pos = MAP_APPFONT( 12, 86 );
+ Size = MAP_APPFONT( 159, 10 );
+ TabStop = TRUE ;
+ Text [ en-US ] = "Detect special numbers (such as dates)." ;
+ };
+};
+
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
new file mode 100644
index 000000000000..18c1eb25664a
--- /dev/null
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -0,0 +1,1080 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include <vcl/msgbox.hxx>
+#include <i18npool/mslangid.hxx>
+#include <svtools/collatorres.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include "scitems.hxx"
+#include "uiitems.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "dbcolect.hxx"
+#include "userlist.hxx"
+#include "rangeutl.hxx"
+#include "scresid.hxx"
+#include "sc.hrc" // -> Slot IDs
+#include "globstr.hrc"
+
+#include "sortdlg.hxx"
+#include "sortdlg.hrc"
+
+#define _TPSORT_CXX
+#include "tpsort.hxx"
+#undef _TPSORT_CXX
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+static USHORT pSortRanges[] =
+{
+ SID_SORT,
+ SID_SORT,
+ 0
+};
+
+// -----------------------------------------------------------------------
+
+/*
+ * Da sich Einstellungen auf der zweiten TabPage (Optionen) auf
+ * die erste TabPage auswirken, muss es die Moeglichkeit geben,
+ * dies der jeweils anderen Seite mitzuteilen.
+ *
+ * Im Moment wird dieses Problem ueber zwei Datenmember des TabDialoges
+ * geloest. Wird eine Seite Aktiviert/Deaktiviert, so gleicht sie diese
+ * Datenmember mit dem eigenen Zustand ab (->Activate()/Deactivate()).
+ *
+ * 31.01.95:
+ * Die Klasse SfxTabPage bietet mittlerweile ein Verfahren an:
+ *
+ * virtual BOOL HasExchangeSupport() const; -> return TRUE;
+ * virtual void ActivatePage(const SfxItemSet &);
+ * virtual int DeactivatePage(SfxItemSet * = 0);
+ *
+ * muss noch geaendert werden!
+ */
+
+//========================================================================
+//========================================================================
+// Sortierkriterien-Tabpage:
+
+ScTabPageSortFields::ScTabPageSortFields( Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_SORT_FIELDS ),
+ rArgSet ),
+ //
+ aFlSort1 ( this, ScResId( FL_SORT1 ) ),
+ aLbSort1 ( this, ScResId( LB_SORT1 ) ),
+ aBtnUp1 ( this, ScResId( BTN_UP1 ) ),
+ aBtnDown1 ( this, ScResId( BTN_DOWN1 ) ),
+ //
+ aFlSort2 ( this, ScResId( FL_SORT2 ) ),
+ aLbSort2 ( this, ScResId( LB_SORT2 ) ),
+ aBtnUp2 ( this, ScResId( BTN_UP2 ) ),
+ aBtnDown2 ( this, ScResId( BTN_DOWN2 ) ),
+ //
+ aFlSort3 ( this, ScResId( FL_SORT3 ) ),
+ aLbSort3 ( this, ScResId( LB_SORT3 ) ),
+ aBtnUp3 ( this, ScResId( BTN_UP3 ) ),
+ aBtnDown3 ( this, ScResId( BTN_DOWN3 ) ),
+
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
+ aStrColumn ( ScResId( SCSTR_COLUMN ) ),
+ aStrRow ( ScResId( SCSTR_ROW ) ),
+ //
+ nWhichSort ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
+ pDlg ( (ScSortDlg*)(GetParent()->GetParent()) ),
+ pViewData ( NULL ),
+ rSortData ( ((const ScSortItem&)
+ rArgSet.Get( nWhichSort )).
+ GetSortData() ),
+ nFieldCount ( 0 ),
+ bHasHeader ( FALSE ),
+ bSortByRows ( FALSE )
+{
+ Init();
+ FreeResource();
+ SetExchangeSupport();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTabPageSortFields::~ScTabPageSortFields()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ScTabPageSortFields::Init()
+{
+ const ScSortItem& rSortItem = (const ScSortItem&)
+ GetItemSet().Get( nWhichSort );
+
+ pViewData = rSortItem.GetViewData();
+
+ DBG_ASSERT( pViewData, "ViewData not found!" );
+
+ nFieldArr[0] = 0;
+ nFirstCol = 0;
+ nFirstRow = 0;
+
+ aLbSort1.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
+ aLbSort2.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
+ aLbSort3.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
+ aLbSort1.Clear();
+ aLbSort2.Clear();
+ aLbSort3.Clear();
+
+ aSortLbArr[0] = &aLbSort1;
+ aSortLbArr[1] = &aLbSort2;
+ aSortLbArr[2] = &aLbSort3;
+ aDirBtnArr[0][0] = &aBtnUp1;
+ aDirBtnArr[0][1] = &aBtnDown1;
+ aDirBtnArr[1][0] = &aBtnUp2;
+ aDirBtnArr[1][1] = &aBtnDown2;
+ aDirBtnArr[2][0] = &aBtnUp3;
+ aDirBtnArr[2][1] = &aBtnDown3;
+ aFlArr[0] = &aFlSort1;
+ aFlArr[1] = &aFlSort2;
+ aFlArr[2] = &aFlSort3;
+}
+
+//------------------------------------------------------------------------
+
+USHORT* __EXPORT ScTabPageSortFields::GetRanges()
+{
+ return pSortRanges;
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTabPageSortFields::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+{
+ return ( new ScTabPageSortFields( pParent, rArgSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
+{
+ bSortByRows = rSortData.bByRow;
+ bHasHeader = rSortData.bHasHeader;
+
+ if ( aLbSort1.GetEntryCount() == 0 )
+ FillFieldLists();
+
+ // Selektieren der ListBoxen:
+
+ if ( rSortData.bDoSort[0] )
+ {
+ for ( USHORT i=0; i<3; i++ )
+ {
+ if ( rSortData.bDoSort[i] )
+ {
+ aSortLbArr[i]->SelectEntryPos(
+ GetFieldSelPos( rSortData.nField[i] ) );
+
+ (rSortData.bAscending[i])
+ ? aDirBtnArr[i][0]->Check() // Up
+ : aDirBtnArr[i][1]->Check(); // Down
+ }
+ else
+ {
+ aSortLbArr[i]->SelectEntryPos( 0 ); // "keiner" selektieren
+ aDirBtnArr[i][0]->Check(); // Up
+ }
+ }
+
+ EnableField( 1 );
+ EnableField( 2 );
+ EnableField( 3 );
+ if ( aLbSort1.GetSelectEntryPos() == 0 )
+ DisableField( 2 );
+ if ( aLbSort2.GetSelectEntryPos() == 0 )
+ DisableField( 3 );
+ }
+ else
+ {
+ SCCOL nCol = pViewData->GetCurX();
+
+ if( nCol < rSortData.nCol1 )
+ nCol = rSortData.nCol1;
+ else if( nCol > rSortData.nCol2 )
+ nCol = rSortData.nCol2;
+
+ USHORT nSort1Pos = nCol - rSortData.nCol1+1;
+ aLbSort1.SelectEntryPos( nSort1Pos );
+ aLbSort2.SelectEntryPos( 0 );
+ aLbSort3.SelectEntryPos( 0 );
+ aBtnUp1.Check();
+ aBtnUp2.Check();
+ aBtnUp3.Check();
+ EnableField ( 1 );
+ EnableField ( 2 );
+ DisableField( 3 );
+ }
+
+ if ( pDlg )
+ {
+ pDlg->SetByRows ( bSortByRows );
+ pDlg->SetHeaders( bHasHeader );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTabPageSortFields::FillItemSet( SfxItemSet& rArgSet )
+{
+ ScSortParam theSortData = rSortData;
+ if (pDlg)
+ {
+ const SfxItemSet* pExample = pDlg->GetExampleSet();
+ const SfxPoolItem* pItem;
+ if ( pExample && pExample->GetItemState( nWhichSort, TRUE, &pItem ) == SFX_ITEM_SET )
+ theSortData = ((const ScSortItem*)pItem)->GetSortData();
+ }
+
+ USHORT nSort1Pos = aLbSort1.GetSelectEntryPos();
+ USHORT nSort2Pos = aLbSort2.GetSelectEntryPos();
+ USHORT nSort3Pos = aLbSort3.GetSelectEntryPos();
+
+ DBG_ASSERT( (nSort1Pos <= SC_MAXFIELDS)
+ && (nSort2Pos <= SC_MAXFIELDS)
+ && (nSort3Pos <= SC_MAXFIELDS),
+ "Array-Range Fehler!" );
+
+ if ( nSort1Pos == LISTBOX_ENTRY_NOTFOUND ) nSort1Pos = 0;
+ if ( nSort2Pos == LISTBOX_ENTRY_NOTFOUND ) nSort2Pos = 0;
+ if ( nSort3Pos == LISTBOX_ENTRY_NOTFOUND ) nSort3Pos = 0;
+
+ if ( nSort1Pos > 0 )
+ {
+ theSortData.bDoSort[0] = (nSort1Pos > 0);
+ theSortData.bDoSort[1] = (nSort2Pos > 0);
+ theSortData.bDoSort[2] = (nSort3Pos > 0);
+
+ // wenn auf Optionen-Seite "OK" gewaehlt wurde und
+ // dabei die Sortierrichtung umgestellt wurde, so
+ // wird das erste Feld der jeweiligen Richtung als
+ // Sortierkriterium gewaehlt (steht in nFieldArr[0]):
+ if ( bSortByRows != pDlg->GetByRows() )
+ {
+ theSortData.nField[0] =
+ theSortData.nField[1] =
+ theSortData.nField[2] = ( bSortByRows ?
+ static_cast<SCCOLROW>(nFirstRow) :
+ static_cast<SCCOLROW>(nFirstCol) );
+ }
+ else
+ {
+ theSortData.nField[0] = nFieldArr[nSort1Pos];
+ theSortData.nField[1] = nFieldArr[nSort2Pos];
+ theSortData.nField[2] = nFieldArr[nSort3Pos];
+ }
+
+ theSortData.bAscending[0] = aBtnUp1.IsChecked();
+ theSortData.bAscending[1] = aBtnUp2.IsChecked();
+ theSortData.bAscending[2] = aBtnUp3.IsChecked();
+ // bHasHeader ist in ScTabPageSortOptions::FillItemSet, wo es hingehoert
+ }
+ else
+ {
+ theSortData.bDoSort[0] =
+ theSortData.bDoSort[1] =
+ theSortData.bDoSort[2] = FALSE;
+ }
+
+ rArgSet.Put( ScSortItem( SCITEM_SORTDATA, NULL, &theSortData ) );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+// fuer Datenaustausch ohne Dialog-Umweg: (! noch zu tun !)
+// void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
+
+void __EXPORT ScTabPageSortFields::ActivatePage()
+{
+ if ( pDlg )
+ {
+ if ( bHasHeader != pDlg->GetHeaders()
+ || bSortByRows != pDlg->GetByRows() )
+ {
+ USHORT nCurSel1 = aLbSort1.GetSelectEntryPos();
+ USHORT nCurSel2 = aLbSort2.GetSelectEntryPos();
+ USHORT nCurSel3 = aLbSort3.GetSelectEntryPos();
+
+ bHasHeader = pDlg->GetHeaders();
+ bSortByRows = pDlg->GetByRows();
+ FillFieldLists();
+ aLbSort1.SelectEntryPos( nCurSel1 );
+ aLbSort2.SelectEntryPos( nCurSel2 );
+ aLbSort3.SelectEntryPos( nCurSel3 );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int __EXPORT ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( pDlg )
+ {
+ if ( bHasHeader != pDlg->GetHeaders() )
+ pDlg->SetHeaders( bHasHeader );
+
+ if ( bSortByRows != pDlg->GetByRows() )
+ pDlg->SetByRows( bSortByRows );
+ }
+
+ if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return SfxTabPage::LEAVE_PAGE;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTabPageSortFields::DisableField( USHORT nField )
+{
+ nField--;
+
+ if ( nField<=2 )
+ {
+ aSortLbArr[nField] ->Disable();
+ aDirBtnArr[nField][0]->Disable();
+ aDirBtnArr[nField][1]->Disable();
+ aFlArr[nField] ->Disable();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScTabPageSortFields::EnableField( USHORT nField )
+{
+ nField--;
+
+ if ( nField<=2 )
+ {
+ aSortLbArr[nField] ->Enable();
+ aDirBtnArr[nField][0]->Enable();
+ aDirBtnArr[nField][1]->Enable();
+ aFlArr[nField] ->Enable();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScTabPageSortFields::FillFieldLists()
+{
+ if ( pViewData )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ if ( pDoc )
+ {
+ aLbSort1.Clear();
+ aLbSort2.Clear();
+ aLbSort3.Clear();
+ aLbSort1.InsertEntry( aStrUndefined, 0 );
+ aLbSort2.InsertEntry( aStrUndefined, 0 );
+ aLbSort3.InsertEntry( aStrUndefined, 0 );
+
+ SCCOL nFirstSortCol = rSortData.nCol1;
+ SCROW nFirstSortRow = rSortData.nRow1;
+ SCTAB nTab = pViewData->GetTabNo();
+ USHORT i = 1;
+
+ if ( bSortByRows )
+ {
+ String aFieldName;
+ SCCOL nMaxCol = rSortData.nCol2;
+ SCCOL col;
+
+ for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
+ {
+ pDoc->GetString( col, nFirstSortRow, nTab, aFieldName );
+ if ( !bHasHeader || (aFieldName.Len() == 0) )
+ {
+ aFieldName = aStrColumn;
+ aFieldName += ' ';
+ aFieldName += ScColToAlpha( col );
+ }
+ nFieldArr[i] = col;
+ aLbSort1.InsertEntry( aFieldName, i );
+ aLbSort2.InsertEntry( aFieldName, i );
+ aLbSort3.InsertEntry( aFieldName, i );
+ i++;
+ }
+ }
+ else
+ {
+ String aFieldName;
+ SCROW nMaxRow = rSortData.nRow2;
+ SCROW row;
+
+ for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS; row++ )
+ {
+ pDoc->GetString( nFirstSortCol, row, nTab, aFieldName );
+ if ( !bHasHeader || (aFieldName.Len() == 0) )
+ {
+ aFieldName = aStrRow;
+ aFieldName += ' ';
+ aFieldName += String::CreateFromInt32( row+1 );
+ }
+ nFieldArr[i] = row;
+ aLbSort1.InsertEntry( aFieldName, i );
+ aLbSort2.InsertEntry( aFieldName, i );
+ aLbSort3.InsertEntry( aFieldName, i );
+ i++;
+ }
+ }
+ nFieldCount = i;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
+{
+ USHORT nFieldPos = 0;
+ BOOL bFound = FALSE;
+
+ for ( USHORT n=1; n<nFieldCount && !bFound; n++ )
+ {
+ if ( nFieldArr[n] == nField )
+ {
+ nFieldPos = n;
+ bFound = TRUE;
+ }
+ }
+
+ return nFieldPos;
+}
+
+// -----------------------------------------------------------------------
+// Handler:
+//---------
+
+IMPL_LINK( ScTabPageSortFields, SelectHdl, ListBox *, pLb )
+{
+ String aSelEntry = pLb->GetSelectEntry();
+
+ if ( pLb == &aLbSort1 )
+ {
+ if ( aSelEntry == aStrUndefined )
+ {
+ aLbSort2.SelectEntryPos( 0 );
+ aLbSort3.SelectEntryPos( 0 );
+
+ if ( aFlSort2.IsEnabled() )
+ DisableField( 2 );
+
+ if ( aFlSort3.IsEnabled() )
+ DisableField( 3 );
+ }
+ else
+ {
+ if ( !aFlSort2.IsEnabled() )
+ EnableField( 2 );
+ }
+ }
+ else if ( pLb == &aLbSort2 )
+ {
+ if ( aSelEntry == aStrUndefined )
+ {
+ aLbSort3.SelectEntryPos( 0 );
+ if ( aFlSort3.IsEnabled() )
+ DisableField( 3 );
+ }
+ else
+ {
+ if ( !aFlSort3.IsEnabled() )
+ EnableField( 3 );
+ }
+ }
+ return 0;
+}
+
+//========================================================================
+// Sortieroptionen-Tabpage:
+//========================================================================
+
+#if ENABLE_LAYOUT_EXPERIMENTAL
+#include <layout/layout-pre.hxx>
+
+#if ENABLE_LAYOUT
+#undef ScResId
+#define ScResId(x) #x
+#undef SfxTabPage
+#define SfxTabPage( parent, id, args ) SfxTabPage( parent, "sort-options.xml", id, &args )
+#endif /* ENABLE_LAYOUT */
+
+#endif /* ENABLE_LAYOUT_EXPERIMENTAL */
+
+ScTabPageSortOptions::ScTabPageSortOptions( Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_SORT_OPTIONS ),
+ rArgSet ),
+ //
+ aBtnCase ( this, ScResId( BTN_CASESENSITIVE ) ),
+ aBtnHeader ( this, ScResId( BTN_LABEL ) ),
+ aBtnFormats ( this, ScResId( BTN_FORMATS ) ),
+ aBtnCopyResult ( this, ScResId( BTN_COPYRESULT ) ),
+ aLbOutPos ( this, ScResId( LB_OUTAREA ) ),
+ aEdOutPos ( this, ScResId( ED_OUTAREA ) ),
+ aBtnSortUser ( this, ScResId( BTN_SORT_USER ) ),
+ aLbSortUser ( this, ScResId( LB_SORT_USER ) ),
+ aFtLanguage ( this, ScResId( FT_LANGUAGE ) ),
+ aLbLanguage ( this, ScResId( LB_LANGUAGE ) ),
+ aFtAlgorithm ( this, ScResId( FT_ALGORITHM ) ),
+ aLbAlgorithm ( this, ScResId( LB_ALGORITHM ) ),
+ aLineDirection ( this, ScResId( FL_DIRECTION ) ),
+ aBtnTopDown ( this, ScResId( BTN_TOP_DOWN ) ),
+ aBtnLeftRight ( this, ScResId( BTN_LEFT_RIGHT ) ),
+ aFtAreaLabel ( this, ScResId( FT_AREA_LABEL ) ),
+// aFtArea ( this, ScResId( FT_AREA ) ),
+ //
+#if ENABLE_LAYOUT_EXPERIMENTAL
+#undef this
+#undef ScResId
+#define ScResId(x) this, #x
+#endif /* ENABLE_LAYOUT_EXPERIMENTAL */
+ aStrRowLabel ( ScResId( STR_ROW_LABEL ) ),
+ aStrColLabel ( ScResId( STR_COL_LABEL ) ),
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
+ aStrNoName ( ScGlobal::GetRscString(STR_DB_NONAME) ),
+ //
+ nWhichSort ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
+ rSortData ( ((const ScSortItem&)
+ rArgSet.Get( nWhichSort )).GetSortData() ),
+ pViewData ( NULL ),
+ pDoc ( NULL ),
+ pDlg ( (ScSortDlg*)(GetParent() ? GetParent()->GetParent() : 0 ) ),
+ pColRes ( NULL ),
+ pColWrap ( NULL )
+{
+ Init();
+ FreeResource();
+ SetExchangeSupport();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTabPageSortOptions::~ScTabPageSortOptions()
+{
+ USHORT nEntries = aLbOutPos.GetEntryCount();
+
+ for ( USHORT i=1; i<nEntries; i++ )
+ delete (String*)aLbOutPos.GetEntryData( i );
+
+ delete pColRes;
+ delete pColWrap; //! not if from document
+}
+
+// -----------------------------------------------------------------------
+
+void ScTabPageSortOptions::Init()
+{
+ aStrAreaLabel = aFtAreaLabel.GetText();
+ aStrAreaLabel.Append( (sal_Unicode) ' ' );
+
+ // CollatorRessource has user-visible names for sort algorithms
+ pColRes = new CollatorRessource();
+
+ //! use CollatorWrapper from document?
+ pColWrap = new CollatorWrapper( comphelper::getProcessServiceFactory() );
+
+ const ScSortItem& rSortItem = (const ScSortItem&)
+ GetItemSet().Get( nWhichSort );
+
+ aLbOutPos.SetSelectHdl ( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
+ aBtnCopyResult.SetClickHdl( LINK( this, ScTabPageSortOptions, EnableHdl ) );
+ aBtnSortUser.SetClickHdl ( LINK( this, ScTabPageSortOptions, EnableHdl ) );
+ aBtnTopDown.SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
+ aBtnLeftRight.SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
+ aLbLanguage.SetSelectHdl ( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
+
+ pViewData = rSortItem.GetViewData();
+ pDoc = pViewData ? pViewData->GetDocument() : NULL;
+
+ DBG_ASSERT( pViewData, "ViewData not found! :-/" );
+
+ if ( pViewData && pDoc )
+ {
+ String theArea;
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ String theDbArea;
+ String theDbName = aStrNoName;
+ const SCTAB nCurTab = pViewData->GetTabNo();
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ aLbOutPos.Clear();
+ aLbOutPos.InsertEntry( aStrUndefined, 0 );
+ aLbOutPos.Disable();
+
+ ScAreaNameIterator aIter( pDoc );
+ String aName;
+ ScRange aRange;
+ String aRefStr;
+ while ( aIter.Next( aName, aRange ) )
+ {
+ USHORT nInsert = aLbOutPos.InsertEntry( aName );
+
+ aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, eConv );
+ aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) );
+ }
+
+ aLbOutPos.SelectEntryPos( 0 );
+ aEdOutPos.SetText( EMPTY_STRING );
+
+ /*
+ * Ueberpruefen, ob es sich bei dem uebergebenen
+ * Bereich um einen Datenbankbereich handelt:
+ */
+
+ ScAddress aScAddress( rSortData.nCol1, rSortData.nRow1, nCurTab );
+ ScRange( aScAddress,
+ ScAddress( rSortData.nCol2, rSortData.nRow2, nCurTab )
+ ).Format( theArea, SCR_ABS, pDoc, eConv );
+
+ if ( pDBColl )
+ {
+ ScDBData* pDBData
+ = pDBColl->GetDBAtArea( nCurTab,
+ rSortData.nCol1, rSortData.nRow1,
+ rSortData.nCol2, rSortData.nRow2 );
+ if ( pDBData )
+ {
+ pDBData->GetName( theDbName );
+ aBtnHeader.Check( pDBData->HasHeader() );
+ }
+ }
+
+ theArea.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" ("));
+ theArea += theDbName;
+ theArea += ')';
+
+ //aFtArea.SetText( theArea );
+ theArea.Insert( aStrAreaLabel, 0 );
+ aFtAreaLabel.SetText( theArea );
+
+ aBtnHeader.SetText( aStrColLabel );
+ }
+
+ FillUserSortListBox();
+
+ // get available languages
+
+ aLbLanguage.SetLanguageList( LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, FALSE );
+ aLbLanguage.InsertLanguage( LANGUAGE_SYSTEM );
+}
+
+//------------------------------------------------------------------------
+
+USHORT* __EXPORT ScTabPageSortOptions::GetRanges()
+{
+ return pSortRanges;
+}
+
+// -----------------------------------------------------------------------
+
+#if ENABLE_LAYOUT_EXPERIMENTAL
+#undef SfxTabPage
+#endif /* ENABLE_LAYOUT_EXPERIMENTAL */
+SfxTabPage* __EXPORT ScTabPageSortOptions::Create(
+ Window* pParent,
+ const SfxItemSet& rArgSet )
+{
+ return ( new ScTabPageSortOptions( pParent, rArgSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTabPageSortOptions::Reset( const SfxItemSet& /* rArgSet */ )
+{
+ if ( rSortData.bUserDef )
+ {
+ aBtnSortUser.Check( TRUE );
+ aLbSortUser.Enable();
+ aLbSortUser.SelectEntryPos( rSortData.nUserIndex );
+ }
+ else
+ {
+ aBtnSortUser.Check( FALSE );
+ aLbSortUser.Disable();
+ aLbSortUser.SelectEntryPos( 0 );
+ }
+
+ aBtnCase.Check ( rSortData.bCaseSens );
+ aBtnFormats.Check ( rSortData.bIncludePattern );
+ aBtnHeader.Check ( rSortData.bHasHeader );
+
+ if ( rSortData.bByRow )
+ {
+ aBtnTopDown.Check();
+ aBtnHeader.SetText( aStrColLabel );
+ }
+ else
+ {
+ aBtnLeftRight.Check();
+ aBtnHeader.SetText( aStrRowLabel );
+ }
+
+ LanguageType eLang = MsLangId::convertLocaleToLanguage( rSortData.aCollatorLocale );
+ if ( eLang == LANGUAGE_DONTKNOW )
+ eLang = LANGUAGE_SYSTEM;
+ aLbLanguage.SelectLanguage( eLang );
+ FillAlgorHdl( &aLbLanguage ); // get algorithms, select default
+ if ( rSortData.aCollatorAlgorithm.Len() )
+ aLbAlgorithm.SelectEntry( pColRes->GetTranslation( rSortData.aCollatorAlgorithm ) );
+
+ if ( pDoc && !rSortData.bInplace )
+ {
+ String aStr;
+ USHORT nFormat = (rSortData.nDestTab != pViewData->GetTabNo())
+ ? SCR_ABS_3D
+ : SCR_ABS;
+
+ theOutPos.Set( rSortData.nDestCol,
+ rSortData.nDestRow,
+ rSortData.nDestTab );
+
+ theOutPos.Format( aStr, nFormat, pDoc, pDoc->GetAddressConvention() );
+ aBtnCopyResult.Check();
+ aLbOutPos.Enable();
+ aEdOutPos.Enable();
+ aEdOutPos.SetText( aStr );
+ EdOutPosModHdl( &aEdOutPos );
+ aEdOutPos.GrabFocus();
+ aEdOutPos.SetSelection( Selection( 0, SELECTION_MAX ) );
+ }
+ else
+ {
+ aBtnCopyResult.Check( FALSE );
+ aLbOutPos.Disable();
+ aEdOutPos.Disable();
+ aEdOutPos.SetText( EMPTY_STRING );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTabPageSortOptions::FillItemSet( SfxItemSet& rArgSet )
+{
+ ScSortParam theSortData = rSortData;
+ if (pDlg)
+ {
+ const SfxItemSet* pExample = pDlg->GetExampleSet();
+ const SfxPoolItem* pItem;
+ if ( pExample && pExample->GetItemState( nWhichSort, TRUE, &pItem ) == SFX_ITEM_SET )
+ theSortData = ((const ScSortItem*)pItem)->GetSortData();
+ }
+
+ theSortData.bByRow = aBtnTopDown.IsChecked();
+ theSortData.bHasHeader = aBtnHeader.IsChecked();
+ theSortData.bCaseSens = aBtnCase.IsChecked();
+ theSortData.bIncludePattern = aBtnFormats.IsChecked();
+ theSortData.bInplace = !aBtnCopyResult.IsChecked();
+ theSortData.nDestCol = theOutPos.Col();
+ theSortData.nDestRow = theOutPos.Row();
+ theSortData.nDestTab = theOutPos.Tab();
+ theSortData.bUserDef = aBtnSortUser.IsChecked();
+ theSortData.nUserIndex = (aBtnSortUser.IsChecked())
+ ? aLbSortUser.GetSelectEntryPos()
+ : 0;
+
+ // get locale
+ LanguageType eLang = aLbLanguage.GetSelectLanguage();
+ theSortData.aCollatorLocale = MsLangId::convertLanguageToLocale( eLang, false );
+
+ // get algorithm
+ String sAlg;
+ if ( eLang != LANGUAGE_SYSTEM )
+ {
+ uno::Sequence<rtl::OUString> aAlgos = pColWrap->listCollatorAlgorithms(
+ theSortData.aCollatorLocale );
+ USHORT nSel = aLbAlgorithm.GetSelectEntryPos();
+ if ( nSel < aAlgos.getLength() )
+ sAlg = aAlgos[nSel];
+ }
+ theSortData.aCollatorAlgorithm = sAlg;
+
+ rArgSet.Put( ScSortItem( SCITEM_SORTDATA, &theSortData ) );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+// fuer Datenaustausch ohne Dialog-Umweg: (! noch zu tun !)
+// void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
+void __EXPORT ScTabPageSortOptions::ActivatePage()
+{
+ if ( pDlg )
+ {
+ if ( aBtnHeader.IsChecked() != pDlg->GetHeaders() )
+ {
+ aBtnHeader.Check( pDlg->GetHeaders() );
+ }
+
+ if ( aBtnTopDown.IsChecked() != pDlg->GetByRows() )
+ {
+ aBtnTopDown.Check( pDlg->GetByRows() );
+ aBtnLeftRight.Check( !pDlg->GetByRows() );
+ }
+
+ aBtnHeader.SetText( (pDlg->GetByRows())
+ ? aStrColLabel
+ : aStrRowLabel );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int __EXPORT ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
+{
+ BOOL bPosInputOk = TRUE;
+
+ if ( aBtnCopyResult.IsChecked() )
+ {
+ String thePosStr = aEdOutPos.GetText();
+ ScAddress thePos;
+ xub_StrLen nColonPos = thePosStr.Search( ':' );
+
+ if ( STRING_NOTFOUND != nColonPos )
+ thePosStr.Erase( nColonPos );
+
+ if ( pViewData )
+ {
+ // visible table is default for input without table
+ // must be changed to GetRefTabNo when sorting has RefInput!
+ thePos.SetTab( pViewData->GetTabNo() );
+ }
+
+ USHORT nResult = thePos.Parse( thePosStr, pDoc, pDoc->GetAddressConvention() );
+
+ bPosInputOk = ( SCA_VALID == (nResult & SCA_VALID) );
+
+ if ( !bPosInputOk )
+ {
+#if !ENABLE_LAYOUT_EXPERIMENTAL
+ ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_INVALID_TABREF )
+ ).Execute();
+#endif /* ENABLE_LAYOUT_EXPERIMENTAL */
+ aEdOutPos.GrabFocus();
+ aEdOutPos.SetSelection( Selection( 0, SELECTION_MAX ) );
+ theOutPos.Set(0,0,0);
+ }
+ else
+ {
+ aEdOutPos.SetText( thePosStr );
+ theOutPos = thePos;
+ }
+ }
+
+ if ( pDlg && bPosInputOk )
+ {
+ pDlg->SetHeaders( aBtnHeader.IsChecked() );
+ pDlg->SetByRows ( aBtnTopDown.IsChecked() );
+ }
+
+ if ( pSetP && bPosInputOk )
+ FillItemSet( *pSetP );
+
+ return bPosInputOk ? SfxTabPage::LEAVE_PAGE : SfxTabPage::KEEP_PAGE;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTabPageSortOptions::FillUserSortListBox()
+{
+ ScUserList* pUserLists = ScGlobal::GetUserList();
+
+ aLbSortUser.Clear();
+ if ( pUserLists )
+ {
+ USHORT nCount = pUserLists->GetCount();
+ if ( nCount > 0 )
+ for ( USHORT i=0; i<nCount; i++ )
+ aLbSortUser.InsertEntry( (*pUserLists)[i]->GetString() );
+ }
+}
+
+// -----------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScTabPageSortOptions, EnableHdl, CheckBox *, pBox )
+{
+ if ( pBox == &aBtnCopyResult )
+ {
+ if ( pBox->IsChecked() )
+ {
+ aLbOutPos.Enable();
+ aEdOutPos.Enable();
+ aEdOutPos.GrabFocus();
+ }
+ else
+ {
+ aLbOutPos.Disable();
+ aEdOutPos.Disable();
+ }
+ }
+ else if ( pBox == &aBtnSortUser )
+ {
+ if ( pBox->IsChecked() )
+ {
+ aLbSortUser.Enable();
+ aLbSortUser.GrabFocus();
+ }
+ else
+ aLbSortUser.Disable();
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTabPageSortOptions, SelOutPosHdl, ListBox *, pLb )
+{
+ if ( pLb == &aLbOutPos )
+ {
+ String aString;
+ USHORT nSelPos = aLbOutPos.GetSelectEntryPos();
+
+ if ( nSelPos > 0 )
+ aString = *(String*)aLbOutPos.GetEntryData( nSelPos );
+
+ aEdOutPos.SetText( aString );
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTabPageSortOptions, SortDirHdl, RadioButton *, pBtn )
+{
+ if ( pBtn == &aBtnTopDown )
+ {
+ aBtnHeader.SetText( aStrColLabel );
+ }
+ else if ( pBtn == &aBtnLeftRight )
+ {
+ aBtnHeader.SetText( aStrRowLabel );
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTabPageSortOptions::EdOutPosModHdl( Edit* pEd )
+{
+ if ( pEd == &aEdOutPos )
+ {
+ String theCurPosStr = aEdOutPos.GetText();
+ USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
+
+ if ( SCA_VALID == (nResult & SCA_VALID) )
+ {
+ String* pStr = NULL;
+ BOOL bFound = FALSE;
+ USHORT i = 0;
+ USHORT nCount = aLbOutPos.GetEntryCount();
+
+ for ( i=2; i<nCount && !bFound; i++ )
+ {
+ pStr = (String*)aLbOutPos.GetEntryData( i );
+ bFound = (theCurPosStr == *pStr);
+ }
+
+ if ( bFound )
+ aLbOutPos.SelectEntryPos( --i );
+ else
+ aLbOutPos.SelectEntryPos( 0 );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTabPageSortOptions, FillAlgorHdl, void *, EMPTYARG )
+{
+ aLbAlgorithm.SetUpdateMode( FALSE );
+ aLbAlgorithm.Clear();
+
+ LanguageType eLang = aLbLanguage.GetSelectLanguage();
+ if ( eLang == LANGUAGE_SYSTEM )
+ {
+ // for LANGUAGE_SYSTEM no algorithm can be selected because
+ // it wouldn't necessarily exist for other languages
+ // -> leave list box empty if LANGUAGE_SYSTEM is selected
+ aFtAlgorithm.Enable( FALSE ); // nothing to select
+ aLbAlgorithm.Enable( FALSE ); // nothing to select
+ }
+ else
+ {
+ lang::Locale aLocale( MsLangId::convertLanguageToLocale( eLang ));
+ uno::Sequence<rtl::OUString> aAlgos = pColWrap->listCollatorAlgorithms( aLocale );
+
+ long nCount = aAlgos.getLength();
+ const rtl::OUString* pArray = aAlgos.getConstArray();
+ for (long i=0; i<nCount; i++)
+ {
+ String sAlg = pArray[i];
+ String sUser = pColRes->GetTranslation( sAlg );
+ aLbAlgorithm.InsertEntry( sUser, LISTBOX_APPEND );
+ }
+ aLbAlgorithm.SelectEntryPos( 0 ); // first entry is default
+ aFtAlgorithm.Enable( nCount > 1 ); // enable only if there is a choice
+ aLbAlgorithm.Enable( nCount > 1 ); // enable only if there is a choice
+ }
+
+ aLbAlgorithm.SetUpdateMode( TRUE );
+ return 0;
+}
+
+
diff --git a/sc/source/ui/dbgui/tpsubt.cxx b/sc/source/ui/dbgui/tpsubt.cxx
new file mode 100644
index 000000000000..fbada165b55d
--- /dev/null
+++ b/sc/source/ui/dbgui/tpsubt.cxx
@@ -0,0 +1,686 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "scitems.hxx"
+#include "uiitems.hxx"
+#include "global.hxx"
+#include "userlist.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "sc.hrc" // -> Slot IDs
+
+#include "subtdlg.hxx"
+#include "subtdlg.hrc"
+#include "tpsubt.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+static USHORT pSubTotalsRanges[] =
+{
+ SID_SUBTOTALS,
+ SID_SUBTOTALS,
+ 0
+};
+
+//========================================================================
+// Zwischenergebnisgruppen-Tabpage:
+
+ScTpSubTotalGroup::ScTpSubTotalGroup( Window* pParent, USHORT nResId,
+ const SfxItemSet& rArgSet )
+ : SfxTabPage ( pParent,
+ ScResId( nResId ),
+ rArgSet ),
+ //
+ aFtGroup ( this, ScResId( FT_GROUP ) ),
+ aLbGroup ( this, ScResId( LB_GROUP ) ),
+ aFtColumns ( this, ScResId( FT_COLUMNS ) ),
+ aLbColumns ( this, ScResId( WND_COLUMNS ) ),
+ aFtFunctions ( this, ScResId( FT_FUNCTIONS ) ),
+ aLbFunctions ( this, ScResId( LB_FUNCTIONS ) ),
+ aStrNone ( ScResId( SCSTR_NONE ) ),
+ aStrColumn ( ScResId( SCSTR_COLUMN ) ),
+ //
+ pViewData ( NULL ),
+ pDoc ( NULL ),
+ nWhichSubTotals ( rArgSet.GetPool()->GetWhich( SID_SUBTOTALS ) ),
+ rSubTotalData ( ((const ScSubTotalItem&)
+ rArgSet.Get( nWhichSubTotals )).
+ GetSubTotalData() ),
+ nFieldCount ( 0 )
+{
+ // Font is correctly initialized by SvTreeListBox ctor
+ aLbColumns.SetSelectionMode( SINGLE_SELECTION );
+ aLbColumns.SetDragDropMode( SV_DRAGDROP_NONE );
+ aLbColumns.SetSpaceBetweenEntries( 0 );
+ aLbColumns.Show();
+
+ Init ();
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTpSubTotalGroup::~ScTpSubTotalGroup()
+{
+ USHORT nCount = (USHORT)aLbColumns.GetEntryCount();
+
+ if ( nCount > 0 )
+ {
+ USHORT* pData = NULL;
+
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ pData = (USHORT*)(aLbColumns.GetEntryData( i ));
+ DBG_ASSERT( pData, "EntryData not found" );
+
+ delete pData;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpSubTotalGroup::Init()
+{
+ const ScSubTotalItem& rSubTotalItem = (const ScSubTotalItem&)
+ GetItemSet().Get( nWhichSubTotals );
+
+ pViewData = rSubTotalItem.GetViewData();
+ pDoc = ( pViewData ) ? pViewData->GetDocument() : NULL;
+
+ DBG_ASSERT( pViewData && pDoc, "ViewData or Document not found :-(" );
+
+ aLbGroup.SetSelectHdl ( LINK( this, ScTpSubTotalGroup, SelectHdl ) );
+ aLbColumns.SetSelectHdl ( LINK( this, ScTpSubTotalGroup, SelectHdl ) );
+ aLbColumns.SetCheckButtonHdl ( LINK( this, ScTpSubTotalGroup, CheckHdl ) );
+ aLbFunctions.SetSelectHdl ( LINK( this, ScTpSubTotalGroup, SelectHdl ) );
+
+ nFieldArr[0] = 0;
+ FillListBoxes();
+}
+
+//------------------------------------------------------------------------
+
+USHORT* __EXPORT ScTpSubTotalGroup::GetRanges()
+{
+ return pSubTotalsRanges;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScTpSubTotalGroup::DoReset( USHORT nGroupNo,
+ const SfxItemSet& rArgSet )
+{
+ USHORT nGroupIdx = 0;
+
+ DBG_ASSERT( (nGroupNo<=3) && (nGroupNo>0), "Invalid group" );
+
+ if ( (nGroupNo > 3) || (nGroupNo == 0) )
+ return FALSE;
+ else
+ nGroupIdx = nGroupNo-1;
+
+ //----------------------------------------------------------
+
+ // #79058# first we have to clear the listboxes...
+ for ( USHORT nLbEntry = 0; nLbEntry < aLbColumns.GetEntryCount(); ++nLbEntry )
+ {
+ aLbColumns.CheckEntryPos( nLbEntry, FALSE );
+ *((USHORT*)aLbColumns.GetEntryData( nLbEntry )) = 0;
+ }
+ aLbFunctions.SelectEntryPos( 0 );
+
+ ScSubTotalParam theSubTotalData( ((const ScSubTotalItem&)
+ rArgSet.Get( nWhichSubTotals )).
+ GetSubTotalData() );
+
+ if ( theSubTotalData.bGroupActive[nGroupIdx] )
+ {
+ SCCOL nField = theSubTotalData.nField[nGroupIdx];
+ SCCOL nSubTotals = theSubTotalData.nSubTotals[nGroupIdx];
+ SCCOL* pSubTotals = theSubTotalData.pSubTotals[nGroupIdx];
+ ScSubTotalFunc* pFunctions = theSubTotalData.pFunctions[nGroupIdx];
+
+ aLbGroup.SelectEntryPos( GetFieldSelPos( nField )+1 );
+
+ for ( USHORT i=0; i<nSubTotals; i++ )
+ {
+ USHORT nCheckPos = GetFieldSelPos( pSubTotals[i] );
+ USHORT* pFunction = (USHORT*)aLbColumns.GetEntryData( nCheckPos );
+
+ aLbColumns.CheckEntryPos( nCheckPos );
+ *pFunction = FuncToLbPos( pFunctions[i] );
+ }
+ aLbColumns.SelectEntryPos( 0 );
+ }
+ else
+ {
+ aLbGroup.SelectEntryPos( (nGroupNo == 1) ? 1 : 0 );
+ aLbColumns.SelectEntryPos( 0 );
+ aLbFunctions.SelectEntryPos( 0 );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScTpSubTotalGroup::DoFillItemSet( USHORT nGroupNo,
+ SfxItemSet& rArgSet )
+{
+ USHORT nGroupIdx = 0;
+
+ DBG_ASSERT( (nGroupNo<=3) && (nGroupNo>0), "Invalid group" );
+ DBG_ASSERT( (aLbGroup.GetEntryCount() > 0)
+ && (aLbColumns.GetEntryCount() > 0)
+ && (aLbFunctions.GetEntryCount() > 0),
+ "Non-initialized Lists" );
+
+
+ if ( (nGroupNo > 3) || (nGroupNo == 0)
+ || (aLbGroup.GetEntryCount() == 0)
+ || (aLbColumns.GetEntryCount() == 0)
+ || (aLbFunctions.GetEntryCount() == 0)
+ )
+ return FALSE;
+ else
+ nGroupIdx = nGroupNo-1;
+
+ //----------------------------------------------------------
+
+ ScSubTotalParam theSubTotalData; // auslesen, wenn schon teilweise gefuellt
+ SfxTabDialog* pDlg = GetTabDialog();
+ if ( pDlg )
+ {
+ const SfxItemSet* pExample = pDlg->GetExampleSet();
+ const SfxPoolItem* pItem;
+ if ( pExample && pExample->GetItemState( nWhichSubTotals, TRUE, &pItem ) == SFX_ITEM_SET )
+ theSubTotalData = ((const ScSubTotalItem*)pItem)->GetSubTotalData();
+ }
+
+ ScSubTotalFunc* pFunctions = NULL;
+ SCCOL* pSubTotals = NULL;
+ USHORT nGroup = aLbGroup.GetSelectEntryPos();
+ USHORT nEntryCount = (USHORT)aLbColumns.GetEntryCount();
+ USHORT nCheckCount = aLbColumns.GetCheckedEntryCount();
+
+ theSubTotalData.nCol1 = rSubTotalData.nCol1;
+ theSubTotalData.nRow1 = rSubTotalData.nRow1;
+ theSubTotalData.nCol2 = rSubTotalData.nCol2;
+ theSubTotalData.nRow2 = rSubTotalData.nRow2;
+ theSubTotalData.bGroupActive[nGroupIdx] = (nGroup != 0);
+ theSubTotalData.nField[nGroupIdx] = (nGroup != 0)
+ ? nFieldArr[nGroup-1]
+ : static_cast<SCCOL>(0);
+
+ if ( nEntryCount>0 && nCheckCount>0 && nGroup!=0 )
+ {
+ USHORT nFunction = 0;
+
+ pSubTotals = new SCCOL [nCheckCount];
+ pFunctions = new ScSubTotalFunc [nCheckCount];
+
+ for ( USHORT i=0, nCheck=0; i<nEntryCount; i++ )
+ {
+ if ( aLbColumns.IsChecked( i ) )
+ {
+ DBG_ASSERT( nCheck <= nCheckCount,
+ "Range error :-(" );
+ nFunction = *((USHORT*)aLbColumns.GetEntryData( i ));
+ pSubTotals[nCheck] = nFieldArr[i];
+ pFunctions[nCheck] = LbPosToFunc( nFunction );
+ nCheck++;
+ }
+ }
+ theSubTotalData.SetSubTotals( nGroupNo, // Gruppen-Nr.
+ pSubTotals,
+ pFunctions,
+ nCheckCount ); // Anzahl der Array-Elemente
+
+ }
+
+ rArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA, &theSubTotalData ) );
+
+ if ( pSubTotals ) delete [] pSubTotals;
+ if ( pFunctions ) delete [] pFunctions;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpSubTotalGroup::FillListBoxes()
+{
+ DBG_ASSERT( pViewData && pDoc, "ViewData or Document not found :-/" );
+
+ if ( pViewData && pDoc )
+ {
+ SCCOL nFirstCol = rSubTotalData.nCol1;
+ SCROW nFirstRow = rSubTotalData.nRow1;
+ SCTAB nTab = pViewData->GetTabNo();
+ SCCOL nMaxCol = rSubTotalData.nCol2;
+ SCCOL col;
+ USHORT i=0;
+ String aFieldName;
+
+ aLbGroup.Clear();
+ aLbColumns.Clear();
+ aLbGroup.InsertEntry( aStrNone, 0 );
+
+ i=0;
+ for ( col=nFirstCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
+ {
+ pDoc->GetString( col, nFirstRow, nTab, aFieldName );
+ if ( aFieldName.Len() == 0 )
+ {
+ aFieldName = aStrColumn;
+ aFieldName += ' ';
+ aFieldName += ::ScColToAlpha( col ); // from global.hxx
+ }
+ nFieldArr[i] = col;
+ aLbGroup.InsertEntry( aFieldName, i+1 );
+ aLbColumns.InsertEntry( aFieldName, i );
+ aLbColumns.SetEntryData( i, new USHORT(0) );
+ i++;
+ }
+ // Nachtraegliche "Konstanteninitialisierung":
+ (USHORT&)nFieldCount = i;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ScTpSubTotalGroup::GetFieldSelPos( SCCOL nField )
+{
+ USHORT nFieldPos = 0;
+ BOOL bFound = FALSE;
+
+ for ( USHORT n=0; n<nFieldCount && !bFound; n++ )
+ {
+ if ( nFieldArr[n] == nField )
+ {
+ nFieldPos = n;
+ bFound = TRUE;
+ }
+ }
+
+ return nFieldPos;
+}
+
+// -----------------------------------------------------------------------
+
+ScSubTotalFunc ScTpSubTotalGroup::LbPosToFunc( USHORT nPos )
+{
+ switch ( nPos )
+ {
+// case 0: return SUBTOTAL_FUNC_NONE;
+ case 2: return SUBTOTAL_FUNC_AVE;
+ case 6: return SUBTOTAL_FUNC_CNT;
+ case 1: return SUBTOTAL_FUNC_CNT2;
+ case 3: return SUBTOTAL_FUNC_MAX;
+ case 4: return SUBTOTAL_FUNC_MIN;
+ case 5: return SUBTOTAL_FUNC_PROD;
+ case 7: return SUBTOTAL_FUNC_STD;
+ case 8: return SUBTOTAL_FUNC_STDP;
+ case 0: return SUBTOTAL_FUNC_SUM;
+ case 9: return SUBTOTAL_FUNC_VAR;
+ case 10: return SUBTOTAL_FUNC_VARP;
+ default:
+ DBG_ERROR( "ScTpSubTotalGroup::LbPosToFunc" );
+ return SUBTOTAL_FUNC_NONE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ScTpSubTotalGroup::FuncToLbPos( ScSubTotalFunc eFunc )
+{
+ switch ( eFunc )
+ {
+// case SUBTOTAL_FUNC_NONE: return 0;
+ case SUBTOTAL_FUNC_AVE: return 2;
+ case SUBTOTAL_FUNC_CNT: return 6;
+ case SUBTOTAL_FUNC_CNT2: return 1;
+ case SUBTOTAL_FUNC_MAX: return 3;
+ case SUBTOTAL_FUNC_MIN: return 4;
+ case SUBTOTAL_FUNC_PROD: return 5;
+ case SUBTOTAL_FUNC_STD: return 7;
+ case SUBTOTAL_FUNC_STDP: return 8;
+ case SUBTOTAL_FUNC_SUM: return 0;
+ case SUBTOTAL_FUNC_VAR: return 9;
+ case SUBTOTAL_FUNC_VARP: return 10;
+ default:
+ DBG_ERROR( "ScTpSubTotalGroup::FuncToLbPos" );
+ return 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+// Handler:
+//---------
+
+IMPL_LINK( ScTpSubTotalGroup, SelectHdl, ListBox *, pLb )
+{
+ if ( (aLbColumns.GetEntryCount() > 0)
+ && (aLbColumns.GetSelectionCount() > 0) )
+ {
+ USHORT nFunction = aLbFunctions.GetSelectEntryPos();
+ USHORT nColumn = aLbColumns.GetSelectEntryPos();
+ USHORT* pFunction = (USHORT*)aLbColumns.GetEntryData( nColumn );
+
+ DBG_ASSERT( pFunction, "EntryData nicht gefunden!" );
+ if ( !pFunction )
+ return 0;
+
+ if ( ((SvxCheckListBox*)pLb) == &aLbColumns )
+ {
+ aLbFunctions.SelectEntryPos( *pFunction );
+ }
+ else if ( pLb == &aLbFunctions )
+ {
+ *pFunction = nFunction;
+// aLbColumns.CheckEntryPos( nColumn, (nFunction != 0) );//XXX
+ aLbColumns.CheckEntryPos( nColumn, TRUE );
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTpSubTotalGroup, CheckHdl, ListBox *, pLb )
+{
+ if ( ((SvxCheckListBox*)pLb) == &aLbColumns )
+ {
+ SvLBoxEntry* pEntry = aLbColumns.GetHdlEntry();
+
+ if ( pEntry )
+ {
+ aLbColumns.SelectEntryPos( (USHORT)aLbColumns.GetModel()->GetAbsPos( pEntry ) );
+ SelectHdl( pLb );
+ }
+ }
+ return 0;
+}
+
+//========================================================================
+// Abgeleitete Gruppen-TabPages:
+
+SfxTabPage* __EXPORT ScTpSubTotalGroup1::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+ { return ( new ScTpSubTotalGroup1( pParent, rArgSet ) ); }
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTpSubTotalGroup2::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+ { return ( new ScTpSubTotalGroup2( pParent, rArgSet ) ); }
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTpSubTotalGroup3::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+ { return ( new ScTpSubTotalGroup3( pParent, rArgSet ) ); }
+
+// -----------------------------------------------------------------------
+
+ScTpSubTotalGroup1::ScTpSubTotalGroup1( Window* pParent, const SfxItemSet& rArgSet ) :
+ ScTpSubTotalGroup( pParent, RID_SCPAGE_SUBT_GROUP1, rArgSet )
+{}
+
+ScTpSubTotalGroup2::ScTpSubTotalGroup2( Window* pParent, const SfxItemSet& rArgSet ) :
+ ScTpSubTotalGroup( pParent, RID_SCPAGE_SUBT_GROUP2, rArgSet )
+{}
+
+ScTpSubTotalGroup3::ScTpSubTotalGroup3( Window* pParent, const SfxItemSet& rArgSet ) :
+ ScTpSubTotalGroup( pParent, RID_SCPAGE_SUBT_GROUP3, rArgSet )
+{}
+
+// -----------------------------------------------------------------------
+
+
+#define RESET(i) (ScTpSubTotalGroup::DoReset( (i), rArgSet ))
+
+void __EXPORT ScTpSubTotalGroup1::Reset( const SfxItemSet& rArgSet ) { RESET(1); }
+
+void __EXPORT ScTpSubTotalGroup2::Reset( const SfxItemSet& rArgSet ) { RESET(2); }
+
+void __EXPORT ScTpSubTotalGroup3::Reset( const SfxItemSet& rArgSet ) { RESET(3); }
+
+#undef RESET
+
+// -----------------------------------------------------------------------
+
+#define FILLSET(i) (ScTpSubTotalGroup::DoFillItemSet( (i), rArgSet ))
+
+BOOL __EXPORT ScTpSubTotalGroup1::FillItemSet( SfxItemSet& rArgSet ) { return FILLSET(1); }
+
+BOOL __EXPORT ScTpSubTotalGroup2::FillItemSet( SfxItemSet& rArgSet ) { return FILLSET(2); }
+
+BOOL __EXPORT ScTpSubTotalGroup3::FillItemSet( SfxItemSet& rArgSet ) { return FILLSET(3); }
+
+#undef FILL
+
+//========================================================================
+// Optionen-Tabpage:
+
+ScTpSubTotalOptions::ScTpSubTotalOptions( Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_SUBT_OPTIONS ),
+ rArgSet ),
+ //
+ aFlGroup ( this, ScResId( FL_GROUP ) ),
+ aBtnPagebreak ( this, ScResId( BTN_PAGEBREAK ) ),
+ aBtnCase ( this, ScResId( BTN_CASE ) ),
+ aBtnSort ( this, ScResId( BTN_SORT ) ),
+ aFlSort ( this, ScResId( FL_SORT ) ),
+ aBtnAscending ( this, ScResId( BTN_ASCENDING ) ),
+ aBtnDescending ( this, ScResId( BTN_DESCENDING ) ),
+ aBtnFormats ( this, ScResId( BTN_FORMATS ) ),
+ aBtnUserDef ( this, ScResId( BTN_USERDEF ) ),
+ aLbUserDef ( this, ScResId( LB_USERDEF ) ),
+ //
+ pViewData ( NULL ),
+ pDoc ( NULL ),
+ nWhichSubTotals ( rArgSet.GetPool()->GetWhich( SID_SUBTOTALS ) ),
+ rSubTotalData ( ((const ScSubTotalItem&)
+ rArgSet.Get( nWhichSubTotals )).
+ GetSubTotalData() )
+{
+ Init();
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTpSubTotalOptions::~ScTpSubTotalOptions()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpSubTotalOptions::Init()
+{
+ const ScSubTotalItem& rSubTotalItem = (const ScSubTotalItem&)
+ GetItemSet().Get( nWhichSubTotals );
+
+ pViewData = rSubTotalItem.GetViewData();
+ pDoc = ( pViewData ) ? pViewData->GetDocument() : NULL;
+
+ DBG_ASSERT( pViewData && pDoc, "ViewData oder Document nicht gefunden!" );
+
+ aBtnSort.SetClickHdl ( LINK( this, ScTpSubTotalOptions, CheckHdl ) );
+ aBtnUserDef.SetClickHdl ( LINK( this, ScTpSubTotalOptions, CheckHdl ) );
+
+ FillUserSortListBox();
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTpSubTotalOptions::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+{
+ return ( new ScTpSubTotalOptions( pParent, rArgSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTpSubTotalOptions::Reset( const SfxItemSet& /* rArgSet */ )
+{
+ aBtnPagebreak.Check ( rSubTotalData.bPagebreak );
+ aBtnCase.Check ( rSubTotalData.bCaseSens );
+ aBtnFormats.Check ( rSubTotalData.bIncludePattern );
+ aBtnSort.Check ( rSubTotalData.bDoSort );
+ aBtnAscending.Check ( rSubTotalData.bAscending );
+ aBtnDescending.Check( !rSubTotalData.bAscending );
+
+ if ( rSubTotalData.bUserDef )
+ {
+ aBtnUserDef.Check( TRUE );
+ aLbUserDef.Enable();
+ aLbUserDef.SelectEntryPos( rSubTotalData.nUserIndex );
+ }
+ else
+ {
+ aBtnUserDef.Check( FALSE );
+ aLbUserDef.Disable();
+ aLbUserDef.SelectEntryPos( 0 );
+ }
+
+ CheckHdl( &aBtnSort );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTpSubTotalOptions::FillItemSet( SfxItemSet& rArgSet )
+{
+ ScSubTotalParam theSubTotalData; // auslesen, wenn schon teilweise gefuellt
+ SfxTabDialog* pDlg = GetTabDialog();
+ if ( pDlg )
+ {
+ const SfxItemSet* pExample = pDlg->GetExampleSet();
+ const SfxPoolItem* pItem;
+ if ( pExample && pExample->GetItemState( nWhichSubTotals, TRUE, &pItem ) == SFX_ITEM_SET )
+ theSubTotalData = ((const ScSubTotalItem*)pItem)->GetSubTotalData();
+ }
+
+ theSubTotalData.bPagebreak = aBtnPagebreak.IsChecked();
+ theSubTotalData.bReplace = TRUE;
+ theSubTotalData.bCaseSens = aBtnCase.IsChecked();
+ theSubTotalData.bIncludePattern = aBtnFormats.IsChecked();
+ theSubTotalData.bDoSort = aBtnSort.IsChecked();
+ theSubTotalData.bAscending = aBtnAscending.IsChecked();
+ theSubTotalData.bUserDef = aBtnUserDef.IsChecked();
+ theSubTotalData.nUserIndex = (aBtnUserDef.IsChecked())
+ ? aLbUserDef.GetSelectEntryPos()
+ : 0;
+
+ rArgSet.Put( ScSubTotalItem( nWhichSubTotals, &theSubTotalData ) );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpSubTotalOptions::FillUserSortListBox()
+{
+ ScUserList* pUserLists = ScGlobal::GetUserList();
+
+ aLbUserDef.Clear();
+ if ( pUserLists )
+ {
+ USHORT nCount = pUserLists->GetCount();
+ if ( nCount > 0 )
+ for ( USHORT i=0; i<nCount; i++ )
+ aLbUserDef.InsertEntry( (*pUserLists)[i]->GetString() );
+ }
+}
+
+// -----------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScTpSubTotalOptions, CheckHdl, CheckBox *, pBox )
+{
+ if ( pBox == &aBtnSort )
+ {
+ if ( aBtnSort.IsChecked() )
+ {
+ aFlSort .Enable();
+ aBtnFormats .Enable();
+ aBtnUserDef .Enable();
+ aBtnAscending .Enable();
+ aBtnDescending .Enable();
+
+ if ( aBtnUserDef.IsChecked() )
+ aLbUserDef.Enable();
+ }
+ else
+ {
+ aFlSort .Disable();
+ aBtnFormats .Disable();
+ aBtnUserDef .Disable();
+ aBtnAscending .Disable();
+ aBtnDescending .Disable();
+ aLbUserDef .Disable();
+ }
+ }
+ else if ( pBox == &aBtnUserDef )
+ {
+ if ( aBtnUserDef.IsChecked() )
+ {
+ aLbUserDef.Enable();
+ aLbUserDef.GrabFocus();
+ }
+ else
+ aLbUserDef.Disable();
+ }
+
+ return 0;
+}
+
+__EXPORT ScTpSubTotalGroup1::~ScTpSubTotalGroup1()
+{
+}
+
+__EXPORT ScTpSubTotalGroup2::~ScTpSubTotalGroup2()
+{
+}
+
+__EXPORT ScTpSubTotalGroup3::~ScTpSubTotalGroup3()
+{
+}
+
diff --git a/sc/source/ui/dbgui/validate.cxx b/sc/source/ui/dbgui/validate.cxx
new file mode 100644
index 000000000000..1ee02badefe1
--- /dev/null
+++ b/sc/source/ui/dbgui/validate.cxx
@@ -0,0 +1,1021 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#ifdef SC_DLLIMPLEMENTATION
+#undef SC_DLLIMPLEMENTATION
+#endif
+
+#include <vcl/svapp.hxx>
+#include <svl/aeitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbmod.hxx>
+#include <sfx2/app.hxx>
+
+#include "scresid.hxx"
+#include "sc.hrc" // -> Slot IDs
+
+#include "validat.hxx"
+#include "validate.hrc"
+#include "validate.hxx"
+#include "compiler.hxx"
+#include "formula/opcode.hxx" //CHINA001
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#include "tabvwsh.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/childwin.hxx>
+#include "reffact.hxx"
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+// ============================================================================
+
+static USHORT pValueRanges[] =
+{
+ FID_VALID_MODE, FID_VALID_ERRTEXT,
+ FID_VALID_LISTTYPE, FID_VALID_LISTTYPE,
+ 0
+};
+
+
+// ============================================================================
+
+//<!--Modified by PengYunQuan for Validity Cell Range Picker
+//ScValidationDlg::ScValidationDlg( Window* pParent, const SfxItemSet* pArgSet ) :
+// SfxTabDialog( pParent, ScResId( TAB_DLG_VALIDATION ), pArgSet )
+ScValidationDlg::ScValidationDlg( Window* pParent,
+ const SfxItemSet* pArgSet,
+ ScTabViewShell *pTabViewSh,
+ SfxBindings *pB /*= NULL*/
+ ) :
+ ScValidationDlgBase( pParent ? pParent : SFX_APP()->GetTopWindow(), TAB_DLG_VALIDATION, pArgSet, pB ),
+ m_bOwnRefHdlr( false ),
+ m_pTabVwSh( pTabViewSh ),
+ m_bRefInputting( false )
+//-->Modified by PengYunQuan for Validity Cell Range Picker
+{
+ AddTabPage( TP_VALIDATION_VALUES, ScTPValidationValue::Create, 0 );
+ AddTabPage( TP_VALIDATION_INPUTHELP, ScTPValidationHelp::Create, 0 );
+ AddTabPage( TP_VALIDATION_ERROR, ScTPValidationError::Create, 0 );
+ FreeResource();
+}
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+void ScTPValidationValue::SetReferenceHdl( const ScRange&rRange , ScDocument* pDoc )
+{
+ if ( rRange.aStart != rRange.aEnd )
+ if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
+ if( m_pRefEdit )
+ pValidationDlg/*->GetRefHandler()*/->RefInputStart( m_pRefEdit );
+
+ if ( m_pRefEdit )
+ {
+ String aStr;
+ rRange.Format( aStr, SCR_ABS_3D, pDoc );
+ m_pRefEdit->SetRefString( aStr );
+ //m_pRefEdit->SetRefString( rRange.aStart != rRange.aEnd ? aStr : String::CreateFromAscii("=").Append( aStr ) );
+ }
+}
+
+void ScTPValidationValue:: SetActiveHdl()
+{
+ if ( m_pRefEdit ) m_pRefEdit->GrabFocus();
+
+ if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
+ if( m_pRefEdit )
+ {
+ pValidationDlg/*->GetRefHandler()*/->RefInputDone();
+ }
+}
+
+void ScTPValidationValue::RefInputStartPreHdl( ScRefEdit* pEdit, ScRefButton* pButton )
+{
+ if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
+ {
+ if( pEdit == m_pRefEdit )
+ {
+ if( Window *pPreWnd = pEdit==&maEdMax?&maFtMax:(pEdit==&maEdMin?&maFtMin:NULL) )
+ {
+ pPreWnd->SetParent( pValidationDlg );
+ pPreWnd->Hide();
+ }
+
+ m_pRefEdit->SetParent( pValidationDlg );
+ }
+
+ if( pButton == &m_btnRef )m_btnRef.SetParent( pValidationDlg );
+ }
+}
+
+void ScTPValidationValue::RefInputDonePreHdl()
+{
+
+ if( m_pRefEdit && m_pRefEdit->GetParent()!= this )
+ {
+ if( Window *pPreWnd = m_pRefEdit==&maEdMax?&maFtMax:(m_pRefEdit==&maEdMin?&maFtMin:NULL) )
+ {
+ pPreWnd->SetParent( this );
+ pPreWnd->Show();
+ }
+
+ m_pRefEdit->SetParent( this );
+
+ m_btnRef.SetParent( m_pRefEdit ); //if Edit SetParent but button not, the tab order will be incorrect, need button to setparent to anthor window and restore parent later in order to restore the tab order
+// aExample1.SetParent( m_pRefEdit ); // the aExample1's child order will affect acc key
+ }
+
+ if( m_btnRef.GetParent()!=this ) m_btnRef.SetParent( this );
+// if( aExample1.GetParent()!=this ) aExample1.SetParent( this );
+}
+
+void ScTPValidationValue::RefInputDonePostHdl()
+{
+
+
+ if( m_pRefEdit && !m_pRefEdit->HasFocus() )
+ m_pRefEdit->GrabFocus();
+
+}
+
+
+BOOL ScValidationDlg::Close()
+{
+ if( m_bOwnRefHdlr )
+ if( SfxTabPage* pPage = GetTabPage( TP_VALIDATION_VALUES ) )
+ static_cast<ScTPValidationValue*>(pPage)->RemoveRefDlg();
+
+ return ScValidationDlgBase::Close();
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+ScValidationDlg::~ScValidationDlg()
+{
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ if( m_bOwnRefHdlr )
+ RemoveRefDlg( FALSE );
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+}
+
+
+// ============================================================================
+
+namespace {
+
+/** Converts the passed ScValidationMode to the position in the list box. */
+USHORT lclGetPosFromValMode( ScValidationMode eValMode )
+{
+ USHORT nLbPos = SC_VALIDDLG_ALLOW_ANY;
+ switch( eValMode )
+ {
+ case SC_VALID_ANY: nLbPos = SC_VALIDDLG_ALLOW_ANY; break;
+ case SC_VALID_WHOLE: nLbPos = SC_VALIDDLG_ALLOW_WHOLE; break;
+ case SC_VALID_DECIMAL: nLbPos = SC_VALIDDLG_ALLOW_DECIMAL; break;
+ case SC_VALID_DATE: nLbPos = SC_VALIDDLG_ALLOW_DATE; break;
+ case SC_VALID_TIME: nLbPos = SC_VALIDDLG_ALLOW_TIME; break;
+ case SC_VALID_TEXTLEN: nLbPos = SC_VALIDDLG_ALLOW_TEXTLEN; break;
+ case SC_VALID_LIST: nLbPos = SC_VALIDDLG_ALLOW_RANGE; break;
+ case SC_VALID_CUSTOM: nLbPos = SC_VALIDDLG_ALLOW_ANY; break; // not supported
+ default: DBG_ERRORFILE( "lclGetPosFromValMode - unknown validity mode" );
+ }
+ return nLbPos;
+}
+
+/** Converts the passed list box position to an ScValidationMode. */
+ScValidationMode lclGetValModeFromPos( USHORT nLbPos )
+{
+ ScValidationMode eValMode = SC_VALID_ANY;
+ switch( nLbPos )
+ {
+ case SC_VALIDDLG_ALLOW_ANY: eValMode = SC_VALID_ANY; break;
+ case SC_VALIDDLG_ALLOW_WHOLE: eValMode = SC_VALID_WHOLE; break;
+ case SC_VALIDDLG_ALLOW_DECIMAL: eValMode = SC_VALID_DECIMAL; break;
+ case SC_VALIDDLG_ALLOW_DATE: eValMode = SC_VALID_DATE; break;
+ case SC_VALIDDLG_ALLOW_TIME: eValMode = SC_VALID_TIME; break;
+ case SC_VALIDDLG_ALLOW_RANGE: eValMode = SC_VALID_LIST; break;
+ case SC_VALIDDLG_ALLOW_LIST: eValMode = SC_VALID_LIST; break;
+ case SC_VALIDDLG_ALLOW_TEXTLEN: eValMode = SC_VALID_TEXTLEN; break;
+ default: DBG_ERRORFILE( "lclGetValModeFromPos - invalid list box position" );
+ }
+ return eValMode;
+}
+
+/** Converts the passed ScConditionMode to the position in the list box. */
+USHORT lclGetPosFromCondMode( ScConditionMode eCondMode )
+{
+ USHORT nLbPos = SC_VALIDDLG_DATA_EQUAL;
+ switch( eCondMode )
+ {
+ case SC_COND_NONE: // #111771# may occur in old XML files after Excel import
+ case SC_COND_EQUAL: nLbPos = SC_VALIDDLG_DATA_EQUAL; break;
+ case SC_COND_LESS: nLbPos = SC_VALIDDLG_DATA_LESS; break;
+ case SC_COND_GREATER: nLbPos = SC_VALIDDLG_DATA_GREATER; break;
+ case SC_COND_EQLESS: nLbPos = SC_VALIDDLG_DATA_EQLESS; break;
+ case SC_COND_EQGREATER: nLbPos = SC_VALIDDLG_DATA_EQGREATER; break;
+ case SC_COND_NOTEQUAL: nLbPos = SC_VALIDDLG_DATA_NOTEQUAL; break;
+ case SC_COND_BETWEEN: nLbPos = SC_VALIDDLG_DATA_BETWEEN; break;
+ case SC_COND_NOTBETWEEN: nLbPos = SC_VALIDDLG_DATA_NOTBETWEEN; break;
+ default: DBG_ERRORFILE( "lclGetPosFromCondMode - unknown condition mode" );
+ }
+ return nLbPos;
+}
+
+/** Converts the passed list box position to an ScConditionMode. */
+ScConditionMode lclGetCondModeFromPos( USHORT nLbPos )
+{
+ ScConditionMode eCondMode = SC_COND_EQUAL;
+ switch( nLbPos )
+ {
+ case SC_VALIDDLG_DATA_EQUAL: eCondMode = SC_COND_EQUAL; break;
+ case SC_VALIDDLG_DATA_LESS: eCondMode = SC_COND_LESS; break;
+ case SC_VALIDDLG_DATA_GREATER: eCondMode = SC_COND_GREATER; break;
+ case SC_VALIDDLG_DATA_EQLESS: eCondMode = SC_COND_EQLESS; break;
+ case SC_VALIDDLG_DATA_EQGREATER: eCondMode = SC_COND_EQGREATER; break;
+ case SC_VALIDDLG_DATA_NOTEQUAL: eCondMode = SC_COND_NOTEQUAL; break;
+ case SC_VALIDDLG_DATA_BETWEEN: eCondMode = SC_COND_BETWEEN; break;
+ case SC_VALIDDLG_DATA_NOTBETWEEN: eCondMode = SC_COND_NOTBETWEEN; break;
+ default: DBG_ERRORFILE( "lclGetCondModeFromPos - invalid list box position" );
+ }
+ return eCondMode;
+}
+
+/** Converts line feed separated string to a formula with strings separated by semicolons.
+ @descr Keeps all empty strings.
+ Example: abc\ndef\n\nghi -> "abc";"def";"";"ghi".
+ @param rFmlaStr (out-param) The converted formula string. */
+void lclGetFormulaFromStringList( String& rFmlaStr, const String& rStringList, sal_Unicode cFmlaSep )
+{
+ rFmlaStr.Erase();
+ xub_StrLen nTokenCnt = rStringList.GetTokenCount( '\n' );
+ for( xub_StrLen nToken = 0, nStringIx = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( rStringList.GetToken( 0, '\n', nStringIx ) );
+ ScGlobal::AddQuotes( aToken, '"' );
+ ScGlobal::AddToken( rFmlaStr, aToken, cFmlaSep );
+ }
+ if( !rFmlaStr.Len() )
+ rFmlaStr.AssignAscii( "\"\"" );
+}
+
+
+/** Converts formula with strings separated by semicolons to line feed separated string.
+ @descr Keeps all empty strings. Ignores all empty tokens (multiple semicolons).
+ Example: "abc";;;"def";"";"ghi" -> abc\ndef\n\nghi.
+ @param rStringList (out-param) The converted line feed separated string list.
+ @return true = Conversion successful. */
+bool lclGetStringListFromFormula( String& rStringList, const String& rFmlaStr, sal_Unicode cFmlaSep )
+{
+ String aQuotes( RTL_CONSTASCII_USTRINGPARAM( "\"\"" ) );
+ xub_StrLen nTokenCnt = rFmlaStr.GetQuotedTokenCount( aQuotes, cFmlaSep );
+
+ rStringList.Erase();
+ bool bIsStringList = (nTokenCnt > 0);
+ bool bTokenAdded = false;
+
+ for( xub_StrLen nToken = 0, nStringIx = 0; bIsStringList && (nToken < nTokenCnt); ++nToken )
+ {
+ String aToken( rFmlaStr.GetQuotedToken( 0, aQuotes, cFmlaSep, nStringIx ) );
+ aToken.EraseLeadingAndTrailingChars();
+ if( aToken.Len() ) // ignore empty tokens, i.e. "a";;"b"
+ {
+ bIsStringList = ScGlobal::IsQuoted( aToken, '"' );
+ if( bIsStringList )
+ {
+ ScGlobal::EraseQuotes( aToken, '"' );
+ ScGlobal::AddToken( rStringList, aToken, '\n', 1, bTokenAdded );
+ bTokenAdded = true;
+ }
+ }
+ }
+
+ return bIsStringList;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ScTPValidationValue::ScTPValidationValue( Window* pParent, const SfxItemSet& rArgSet ) :
+ SfxTabPage( pParent, ScResId( TP_VALIDATION_VALUES ), rArgSet ),
+ maFtAllow ( this, ScResId( FT_ALLOW ) ),
+ maLbAllow ( this, ScResId( LB_ALLOW ) ),
+ maCbAllow ( this, ScResId( TSB_ALLOW_BLANKS ) ),
+ maCbShow ( this, ScResId( CB_SHOWLIST ) ),
+ maCbSort ( this, ScResId( CB_SORTLIST ) ),
+ maFtValue ( this, ScResId( FT_VALUE ) ),
+ maLbValue ( this, ScResId( LB_VALUE ) ),
+ maFtMin ( this, ScResId( FT_MIN ) ),
+ maEdMin ( this, ScResId( EDT_MIN ) ),
+ maEdList ( this, ScResId( EDT_LIST ) ),
+ maFtMax ( this, ScResId( FT_MAX ) ),
+ maEdMax ( this, ScResId( EDT_MAX ) ),
+ maFtHint ( this, ScResId( FT_SOURCEHINT ) ),
+ maStrMin ( ScResId( SCSTR_VALID_MINIMUM ) ),
+ maStrMax ( ScResId( SCSTR_VALID_MAXIMUM ) ),
+ maStrValue( ScResId( SCSTR_VALID_VALUE ) ),
+ maStrRange( ScResId( SCSTR_VALID_RANGE ) ),
+ maStrList ( ScResId( SCSTR_VALID_LIST ) ),
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+ m_btnRef( this, ScResId( RB_VALIDITY_REF ) )
+//-->Added by PengYunQuan for Validity Cell Range Picker
+{
+ Init();
+ FreeResource();
+
+ // list separator in formulas
+ //CHINA001 const String& rListSep = ScCompiler::pSymbolTableNative[ ocSep ];
+ String aListSep = ::GetScCompilerNativeSymbol( ocSep ); //CHINA001
+ DBG_ASSERT( aListSep.Len() == 1, "ScTPValidationValue::ScTPValidationValue - list separator error" );
+ mcFmlaSep = aListSep.Len() ? aListSep.GetChar( 0 ) : ';';
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ m_btnRef.Hide();
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+}
+
+ScTPValidationValue::~ScTPValidationValue()
+{
+}
+
+void ScTPValidationValue::Init()
+{
+ maLbAllow.SetSelectHdl( LINK( this, ScTPValidationValue, SelectHdl ) );
+ maLbValue.SetSelectHdl( LINK( this, ScTPValidationValue, SelectHdl ) );
+ maCbShow.SetClickHdl( LINK( this, ScTPValidationValue, CheckHdl ) );
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ maEdMin.SetGetFocusHdl( LINK( this, ScTPValidationValue, EditSetFocusHdl ) );
+ maEdMin.SetLoseFocusHdl( LINK( this, ScTPValidationValue, KillFocusHdl ) );
+ maEdMax.SetGetFocusHdl( LINK( this, ScTPValidationValue, EditSetFocusHdl ) );
+ m_btnRef.SetLoseFocusHdl( LINK( this, ScTPValidationValue, KillFocusHdl ) );
+ maEdMax.SetLoseFocusHdl( LINK( this, ScTPValidationValue, KillFocusHdl ) );
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+
+ maLbAllow.SelectEntryPos( SC_VALIDDLG_ALLOW_ANY );
+ maLbValue.SelectEntryPos( SC_VALIDDLG_DATA_EQUAL );
+
+ SelectHdl( NULL );
+ CheckHdl( NULL );
+}
+
+SfxTabPage* ScTPValidationValue::Create( Window* pParent, const SfxItemSet& rArgSet )
+{
+ return( new ScTPValidationValue( pParent, rArgSet ) );
+}
+
+USHORT* ScTPValidationValue::GetRanges()
+{
+ return pValueRanges;
+}
+
+void ScTPValidationValue::Reset( const SfxItemSet& rArgSet )
+{
+ const SfxPoolItem* pItem;
+
+ USHORT nLbPos = SC_VALIDDLG_ALLOW_ANY;
+ if( rArgSet.GetItemState( FID_VALID_MODE, TRUE, &pItem ) == SFX_ITEM_SET )
+ nLbPos = lclGetPosFromValMode( static_cast< ScValidationMode >(
+ static_cast< const SfxAllEnumItem* >( pItem )->GetValue() ) );
+ maLbAllow.SelectEntryPos( nLbPos );
+
+ nLbPos = SC_VALIDDLG_DATA_EQUAL;
+ if( rArgSet.GetItemState( FID_VALID_CONDMODE, TRUE, &pItem ) == SFX_ITEM_SET )
+ nLbPos = lclGetPosFromCondMode( static_cast< ScConditionMode >(
+ static_cast< const SfxAllEnumItem* >( pItem )->GetValue() ) );
+ maLbValue.SelectEntryPos( nLbPos );
+
+ // *** check boxes ***
+ BOOL bCheck = TRUE;
+ if( rArgSet.GetItemState( FID_VALID_BLANK, TRUE, &pItem ) == SFX_ITEM_SET )
+ bCheck = static_cast< const SfxBoolItem* >( pItem )->GetValue();
+ maCbAllow.Check( bCheck );
+
+ sal_Int32 nListType = ValidListType::UNSORTED;
+ if( rArgSet.GetItemState( FID_VALID_LISTTYPE, TRUE, &pItem ) == SFX_ITEM_SET )
+ nListType = static_cast< const SfxInt16Item* >( pItem )->GetValue();
+ maCbShow.Check( nListType != ValidListType::INVISIBLE );
+ maCbSort.Check( nListType == ValidListType::SORTEDASCENDING );
+
+ // *** formulas ***
+ String aFmlaStr;
+ if ( rArgSet.GetItemState( FID_VALID_VALUE1, TRUE, &pItem ) == SFX_ITEM_SET )
+ aFmlaStr = static_cast< const SfxStringItem* >( pItem )->GetValue();
+ SetFirstFormula( aFmlaStr );
+
+ aFmlaStr.Erase();
+ if ( rArgSet.GetItemState( FID_VALID_VALUE2, TRUE, &pItem ) == SFX_ITEM_SET )
+ aFmlaStr = static_cast< const SfxStringItem* >( pItem )->GetValue();
+ SetSecondFormula( aFmlaStr );
+
+ SelectHdl( NULL );
+ CheckHdl( NULL );
+}
+
+BOOL ScTPValidationValue::FillItemSet( SfxItemSet& rArgSet )
+{
+ sal_Int16 nListType = maCbShow.IsChecked() ?
+ (maCbSort.IsChecked() ? ValidListType::SORTEDASCENDING : ValidListType::UNSORTED) :
+ ValidListType::INVISIBLE;
+
+ rArgSet.Put( SfxAllEnumItem( FID_VALID_MODE, sal::static_int_cast<USHORT>(
+ lclGetValModeFromPos( maLbAllow.GetSelectEntryPos() ) ) ) );
+ rArgSet.Put( SfxAllEnumItem( FID_VALID_CONDMODE, sal::static_int_cast<USHORT>(
+ lclGetCondModeFromPos( maLbValue.GetSelectEntryPos() ) ) ) );
+ rArgSet.Put( SfxStringItem( FID_VALID_VALUE1, GetFirstFormula() ) );
+ rArgSet.Put( SfxStringItem( FID_VALID_VALUE2, GetSecondFormula() ) );
+ rArgSet.Put( SfxBoolItem( FID_VALID_BLANK, maCbAllow.IsChecked() ) );
+ rArgSet.Put( SfxInt16Item( FID_VALID_LISTTYPE, nListType ) );
+ return TRUE;
+}
+
+String ScTPValidationValue::GetFirstFormula() const
+{
+ String aFmlaStr;
+ if( maLbAllow.GetSelectEntryPos() == SC_VALIDDLG_ALLOW_LIST )
+ lclGetFormulaFromStringList( aFmlaStr, maEdList.GetText(), mcFmlaSep );
+ else
+ aFmlaStr = maEdMin.GetText();
+ return aFmlaStr;
+}
+
+String ScTPValidationValue::GetSecondFormula() const
+{
+ return maEdMax.GetText();
+}
+
+void ScTPValidationValue::SetFirstFormula( const String& rFmlaStr )
+{
+ // try if formula is a string list, validation mode must already be set
+ String aStringList;
+ if( (maLbAllow.GetSelectEntryPos() == SC_VALIDDLG_ALLOW_RANGE) &&
+ lclGetStringListFromFormula( aStringList, rFmlaStr, mcFmlaSep ) )
+ {
+ maEdList.SetText( aStringList );
+ maEdMin.SetText( EMPTY_STRING );
+ // change validation mode to string list
+ maLbAllow.SelectEntryPos( SC_VALIDDLG_ALLOW_LIST );
+ }
+ else
+ {
+ maEdMin.SetText( rFmlaStr );
+ maEdList.SetText( EMPTY_STRING );
+ }
+}
+
+void ScTPValidationValue::SetSecondFormula( const String& rFmlaStr )
+{
+ maEdMax.SetText( rFmlaStr );
+}
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+ScValidationDlg * ScTPValidationValue::GetValidationDlg()
+{
+ if( Window *pParent = GetParent() )
+ do{
+ if ( dynamic_cast<ScValidationDlg*>( pParent ) )
+ return static_cast< ScValidationDlg * >( pParent );
+ }while ( NULL != ( pParent = pParent->GetParent() ) );
+ return NULL;
+}
+void ScTPValidationValue::SetupRefDlg()
+{
+ if( ScValidationDlg *pValidationDlg = GetValidationDlg() )
+ if( pValidationDlg->SetupRefDlg() )
+ {
+ pValidationDlg->SetHandler( this );
+ pValidationDlg->SetSetRefHdl( (ScRefHandlerHelper::PFUNCSETREFHDLTYPE)( &ScTPValidationValue::SetReferenceHdl ) );
+ pValidationDlg->SetSetActHdl( (ScRefHandlerHelper::PCOMMONHDLTYPE)( &ScTPValidationValue::SetActiveHdl ) );
+ pValidationDlg->SetRefInputStartPreHdl( (ScRefHandlerHelper::PINPUTSTARTDLTYPE)( &ScTPValidationValue::RefInputStartPreHdl ) );
+ pValidationDlg->SetRefInputDonePreHdl( (ScRefHandlerHelper::PCOMMONHDLTYPE)( &ScTPValidationValue::RefInputDonePreHdl ) );
+ pValidationDlg->SetRefInputDonePostHdl( (ScRefHandlerHelper::PCOMMONHDLTYPE)( &ScTPValidationValue::RefInputDonePostHdl ) );
+
+ if ( maEdMax.IsVisible() ) { m_pRefEdit = &maEdMax; }
+ else if ( maEdMin.IsVisible() ) { m_pRefEdit = &maEdMin; }
+
+ if( m_pRefEdit && !m_pRefEdit->HasFocus() ) m_pRefEdit->GrabFocus();
+
+ if( m_pRefEdit ) m_pRefEdit->SetRefDialog( pValidationDlg );
+ m_btnRef.SetReferences( pValidationDlg, m_pRefEdit );
+ }
+}
+
+void ScTPValidationValue::RemoveRefDlg()
+{
+ if( ScValidationDlg *pValidationDlg = GetValidationDlg() )
+ if( pValidationDlg->RemoveRefDlg() )
+ {
+ pValidationDlg->SetHandler( NULL );
+ pValidationDlg->SetSetRefHdl( NULL );
+ pValidationDlg->SetSetActHdl( NULL );
+ pValidationDlg->SetRefInputStartPreHdl( NULL );
+ pValidationDlg->SetRefInputDonePreHdl( NULL );
+ pValidationDlg->SetRefInputDonePostHdl( NULL );
+
+ if( m_pRefEdit ) m_pRefEdit->SetRefDialog( NULL );
+ m_pRefEdit = NULL;
+
+ m_btnRef.SetReferences( NULL, NULL );
+
+#if ! defined( WNT ) && !defined( _MSC_VER )
+ TidyListBoxes();
+#endif
+ }
+}
+
+void ScTPValidationValue::TidyListBoxes()
+{
+ if ( Window *pWnd = GetChild( 0 ) )
+ {
+ bool bFindLst = false;
+ std::list<Window*> alstOrder;
+
+ do{
+ if( pWnd->GetParent() == this )
+ {
+ if ( !bFindLst )
+ {
+ try{
+ if( dynamic_cast<ListBox*>(pWnd)||dynamic_cast<ListBox*>(pWnd->GetWindow(WINDOW_CLIENT) ) )
+ bFindLst = true;
+ }
+ catch( ... )
+ {
+ if ( *(void**)pWnd == *(void**)&maLbValue )
+ bFindLst = true;
+ else if ( Window *pClient = pWnd->GetWindow( WINDOW_CLIENT ) )
+ if ( *(void**)pClient == *(void**)&maLbValue )
+ bFindLst = true;
+ }
+ }
+
+ if ( bFindLst )
+ alstOrder.push_back( pWnd->GetWindow( WINDOW_CLIENT ) );
+ }
+ }while( NULL != ( pWnd = pWnd->GetWindow( WINDOW_NEXT ) ) );
+
+ pWnd = GetChild(0);
+
+ while( std::find( alstOrder.begin(), alstOrder.end(), pWnd ) != alstOrder.end() && NULL != ( pWnd = pWnd->GetWindow( WINDOW_NEXT) ) ) ;
+
+ if ( pWnd )
+ {
+ for ( std::list<Window*>::iterator i = alstOrder.begin(); i!=alstOrder.end(); i++ )
+ {
+ Window *pParent = (*i)->GetParent();
+ (*i)->SetParent( pWnd );
+ (*i)->SetParent( pParent );
+ }
+ }
+ }
+}
+
+IMPL_LINK( ScTPValidationValue, EditSetFocusHdl, Edit *, /*pEdit*/ )
+{
+ USHORT nPos=maLbAllow.GetSelectEntryPos();
+
+ if ( nPos == SC_VALIDDLG_ALLOW_RANGE )
+ {
+ SetupRefDlg();
+ }
+
+ return 0;
+}
+
+IMPL_LINK( ScTPValidationValue, KillFocusHdl, Window *, pWnd )
+{
+ if( pWnd == m_pRefEdit || pWnd == &m_btnRef )
+ if( ScValidationDlg *pValidationDlg = GetValidationDlg() )
+ if ( (pValidationDlg->IsActive() || pValidationDlg->IsChildFocus() ) && !pValidationDlg->IsRefInputting() )
+ if( ( !m_pRefEdit || !m_pRefEdit->HasFocus()) && !m_btnRef.HasFocus() )
+ {
+ RemoveRefDlg();
+ }
+
+ return 0;
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+// ----------------------------------------------------------------------------
+
+IMPL_LINK( ScTPValidationValue, SelectHdl, ListBox*, EMPTYARG )
+{
+ USHORT nLbPos = maLbAllow.GetSelectEntryPos();
+ bool bEnable = (nLbPos != SC_VALIDDLG_ALLOW_ANY);
+ bool bRange = (nLbPos == SC_VALIDDLG_ALLOW_RANGE);
+ bool bList = (nLbPos == SC_VALIDDLG_ALLOW_LIST);
+
+ maCbAllow.Enable( bEnable ); // Leerzellen
+ maFtValue.Enable( bEnable );
+ maLbValue.Enable( bEnable );
+ maFtMin.Enable( bEnable );
+ maEdMin.Enable( bEnable );
+ maEdList.Enable( bEnable );
+ maFtMax.Enable( bEnable );
+ maEdMax.Enable( bEnable );
+
+ bool bShowMax = false;
+ if( bRange )
+ maFtMin.SetText( maStrRange );
+ else if( bList )
+ maFtMin.SetText( maStrList );
+ else
+ {
+ switch( maLbValue.GetSelectEntryPos() )
+ {
+ case SC_VALIDDLG_DATA_EQUAL:
+ case SC_VALIDDLG_DATA_NOTEQUAL: maFtMin.SetText( maStrValue ); break;
+
+ case SC_VALIDDLG_DATA_LESS:
+ case SC_VALIDDLG_DATA_EQLESS: maFtMin.SetText( maStrMax ); break;
+
+ case SC_VALIDDLG_DATA_BETWEEN:
+ case SC_VALIDDLG_DATA_NOTBETWEEN: bShowMax = true; // fall through
+ case SC_VALIDDLG_DATA_GREATER:
+ case SC_VALIDDLG_DATA_EQGREATER: maFtMin.SetText( maStrMin ); break;
+
+ default:
+ DBG_ERRORFILE( "ScTPValidationValue::SelectHdl - unknown condition mode" );
+ }
+ }
+
+ maCbShow.Show( bRange || bList );
+ maCbSort.Show( bRange || bList );
+ maFtValue.Show( !bRange && !bList );
+ maLbValue.Show( !bRange && !bList );
+ maEdMin.Show( !bList );
+ maEdList.Show( bList );
+ maFtMax.Show( bShowMax );
+ maEdMax.Show( bShowMax );
+ maFtHint.Show( bRange );
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ m_btnRef.Show( bRange );
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+ return 0;
+}
+
+IMPL_LINK( ScTPValidationValue, CheckHdl, CheckBox*, EMPTYARG )
+{
+ maCbSort.Enable( maCbShow.IsChecked() );
+ return 0;
+}
+
+
+//========================================================================
+//========================================================================
+// Input Help Page
+
+ScTPValidationHelp::ScTPValidationHelp( Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : SfxTabPage ( pParent,
+ ScResId( TP_VALIDATION_INPUTHELP ),
+ rArgSet ),
+ aTsbHelp ( this, ScResId( TSB_HELP ) ),
+ aFlContent ( this, ScResId( FL_CONTENT ) ),
+ aFtTitle ( this, ScResId( FT_TITLE ) ),
+ aEdtTitle ( this, ScResId( EDT_TITLE ) ),
+ aFtInputHelp ( this, ScResId( FT_INPUTHELP ) ),
+ aEdInputHelp ( this, ScResId( EDT_INPUTHELP ) ),
+
+ mrArgSet ( rArgSet )
+{
+ Init();
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTPValidationHelp::~ScTPValidationHelp()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ScTPValidationHelp::Init()
+{
+ //aLb.SetSelectHdl( LINK( this, ScTPValidationHelp, SelectHdl ) );
+
+ aTsbHelp.EnableTriState( FALSE );
+}
+
+//------------------------------------------------------------------------
+
+USHORT* __EXPORT ScTPValidationHelp::GetRanges()
+{
+ return pValueRanges;
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTPValidationHelp::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+{
+ return ( new ScTPValidationHelp( pParent, rArgSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTPValidationHelp::Reset( const SfxItemSet& rArgSet )
+{
+ const SfxPoolItem* pItem;
+
+ if ( rArgSet.GetItemState( FID_VALID_SHOWHELP, TRUE, &pItem ) == SFX_ITEM_SET )
+ aTsbHelp.SetState( ((const SfxBoolItem*)pItem)->GetValue() ? STATE_CHECK : STATE_NOCHECK );
+ else
+ aTsbHelp.SetState( STATE_NOCHECK );
+
+ if ( rArgSet.GetItemState( FID_VALID_HELPTITLE, TRUE, &pItem ) == SFX_ITEM_SET )
+ aEdtTitle.SetText( ((const SfxStringItem*)pItem)->GetValue() );
+ else
+ aEdtTitle.SetText( EMPTY_STRING );
+
+ if ( rArgSet.GetItemState( FID_VALID_HELPTEXT, TRUE, &pItem ) == SFX_ITEM_SET )
+ aEdInputHelp.SetText( ((const SfxStringItem*)pItem)->GetValue() );
+ else
+ aEdInputHelp.SetText( EMPTY_STRING );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTPValidationHelp::FillItemSet( SfxItemSet& rArgSet )
+{
+ rArgSet.Put( SfxBoolItem( FID_VALID_SHOWHELP, aTsbHelp.GetState() == STATE_CHECK ) );
+ rArgSet.Put( SfxStringItem( FID_VALID_HELPTITLE, aEdtTitle.GetText() ) );
+ rArgSet.Put( SfxStringItem( FID_VALID_HELPTEXT, aEdInputHelp.GetText() ) );
+
+ return TRUE;
+}
+
+//========================================================================
+//========================================================================
+// Error Alert Page
+
+ScTPValidationError::ScTPValidationError( Window* pParent,
+ const SfxItemSet& rArgSet )
+
+ : SfxTabPage ( pParent,
+ ScResId( TP_VALIDATION_ERROR ),
+ rArgSet ),
+ aTsbShow ( this, ScResId( TSB_SHOW ) ),
+ aFlContent ( this, ScResId( FL_CONTENT ) ),
+ aFtAction ( this, ScResId( FT_ACTION ) ),
+ aLbAction ( this, ScResId( LB_ACTION ) ),
+ aBtnSearch ( this, ScResId( BTN_SEARCH ) ),
+ aFtTitle ( this, ScResId( FT_TITLE ) ),
+ aEdtTitle ( this, ScResId( EDT_TITLE ) ),
+ aFtError ( this, ScResId( FT_ERROR ) ),
+ aEdError ( this, ScResId( EDT_ERROR ) ),
+
+ mrArgSet ( rArgSet )
+{
+ Init();
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTPValidationError::~ScTPValidationError()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ScTPValidationError::Init()
+{
+ aLbAction.SetSelectHdl( LINK( this, ScTPValidationError, SelectActionHdl ) );
+ aBtnSearch.SetClickHdl( LINK( this, ScTPValidationError, ClickSearchHdl ) );
+
+ aLbAction.SelectEntryPos( 0 );
+ aTsbShow.EnableTriState( FALSE );
+
+ SelectActionHdl( NULL );
+}
+
+//------------------------------------------------------------------------
+
+USHORT* __EXPORT ScTPValidationError::GetRanges()
+{
+ return pValueRanges;
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTPValidationError::Create( Window* pParent,
+ const SfxItemSet& rArgSet )
+{
+ return ( new ScTPValidationError( pParent, rArgSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTPValidationError::Reset( const SfxItemSet& rArgSet )
+{
+ const SfxPoolItem* pItem;
+
+ if ( rArgSet.GetItemState( FID_VALID_SHOWERR, TRUE, &pItem ) == SFX_ITEM_SET )
+ aTsbShow.SetState( ((const SfxBoolItem*)pItem)->GetValue() ? STATE_CHECK : STATE_NOCHECK );
+ else
+ aTsbShow.SetState( STATE_CHECK ); // #111720# check by default
+
+ if ( rArgSet.GetItemState( FID_VALID_ERRSTYLE, TRUE, &pItem ) == SFX_ITEM_SET )
+ aLbAction.SelectEntryPos( ((const SfxAllEnumItem*)pItem)->GetValue() );
+ else
+ aLbAction.SelectEntryPos( 0 );
+
+ if ( rArgSet.GetItemState( FID_VALID_ERRTITLE, TRUE, &pItem ) == SFX_ITEM_SET )
+ aEdtTitle.SetText( ((const SfxStringItem*)pItem)->GetValue() );
+ else
+ aEdtTitle.SetText( EMPTY_STRING );
+
+ if ( rArgSet.GetItemState( FID_VALID_ERRTEXT, TRUE, &pItem ) == SFX_ITEM_SET )
+ aEdError.SetText( ((const SfxStringItem*)pItem)->GetValue() );
+ else
+ aEdError.SetText( EMPTY_STRING );
+
+ SelectActionHdl( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTPValidationError::FillItemSet( SfxItemSet& rArgSet )
+{
+ rArgSet.Put( SfxBoolItem( FID_VALID_SHOWERR, aTsbShow.GetState() == STATE_CHECK ) );
+ rArgSet.Put( SfxAllEnumItem( FID_VALID_ERRSTYLE, aLbAction.GetSelectEntryPos() ) );
+ rArgSet.Put( SfxStringItem( FID_VALID_ERRTITLE, aEdtTitle.GetText() ) );
+ rArgSet.Put( SfxStringItem( FID_VALID_ERRTEXT, aEdError.GetText() ) );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTPValidationError, SelectActionHdl, ListBox*, EMPTYARG )
+{
+ ScValidErrorStyle eStyle = (ScValidErrorStyle) aLbAction.GetSelectEntryPos();
+ BOOL bMacro = ( eStyle == SC_VALERR_MACRO );
+
+ aBtnSearch.Enable( bMacro );
+ aFtError.Enable( !bMacro );
+ aEdError.Enable( !bMacro );
+
+ return( 0L );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTPValidationError, ClickSearchHdl, PushButton*, EMPTYARG )
+{
+ Window* pOld = Application::GetDefDialogParent();
+ Application::SetDefDialogParent( this );
+
+ // Use static SfxApplication method to bring up selector dialog for
+ // choosing a script
+ ::rtl::OUString aScriptURL = SfxApplication::ChooseScript();
+
+ Application::SetDefDialogParent( pOld );
+
+ if ( aScriptURL != NULL && aScriptURL.getLength() != 0 )
+ {
+ aEdtTitle.SetText( aScriptURL );
+ }
+
+ return( 0L );
+}
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+bool ScValidationDlg::EnterRefStatus()
+{
+ ScTabViewShell *pTabViewShell = GetTabViewShell();
+
+ if( !pTabViewShell ) return false;
+
+ USHORT nId = SLOTID;
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ if ( pWnd && pWnd->GetWindow()!= this ) pWnd = NULL;
+
+ SC_MOD()->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+
+ return true;
+}
+
+bool ScValidationDlg::LeaveRefStatus()
+{
+ ScTabViewShell *pTabViewShell = GetTabViewShell();
+
+ if( !pTabViewShell ) return false;
+
+ USHORT nId = SLOTID;
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ //SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+ if ( pViewFrm->GetChildWindow( nId ) )
+ {
+ DoClose( nId );
+ }
+ return true;
+}
+
+bool ScValidationDlg::SetupRefDlg()
+{
+ if ( m_bOwnRefHdlr ) return false;
+ if( EnterRefMode() )
+ {
+ SetModal( FALSE );
+ return /*SetChkShell( GetDocShell() ),*/ m_bOwnRefHdlr = true && EnterRefStatus();
+ }
+
+ return false;
+}
+
+bool ScValidationDlg::RemoveRefDlg( BOOL bRestoreModal /* = TRUE */ )
+{
+ bool bVisLock = false;
+ bool bFreeWindowLock = false;
+
+ ScTabViewShell *pTabVwSh = GetTabViewShell();
+
+ if( !pTabVwSh ) return false;
+
+ if ( SfxChildWindow* pWnd = pTabVwSh->GetViewFrame()->GetChildWindow( SID_VALIDITY_REFERENCE ) )
+ {
+ bVisLock = static_cast<ScValidityRefChildWin*>(pWnd)->LockVisible( true );
+ bFreeWindowLock = static_cast<ScValidityRefChildWin*>(pWnd)->LockFreeWindow( true );
+ }
+
+ if ( !m_bOwnRefHdlr ) return false;
+ if( LeaveRefStatus() && LeaveRefMode() )
+ {
+ m_bOwnRefHdlr = false;
+
+ if( bRestoreModal )
+ SetModal( TRUE );
+ }
+
+ if ( SfxChildWindow* pWnd = pTabVwSh->GetViewFrame()->GetChildWindow( SID_VALIDITY_REFERENCE ) )
+ {
+ static_cast<ScValidityRefChildWin*>(pWnd)->LockVisible( bVisLock );
+ static_cast<ScValidityRefChildWin*>(pWnd)->LockFreeWindow( bFreeWindowLock );
+ }
+
+ return true;
+}
+
+//TYPEINIT1( ScTPValidationValue, SfxTabPage )
+
+void ScTPValidationValue::ScRefButtonEx::Click()
+{
+ if( ScTPValidationValue *pParent = dynamic_cast< ScTPValidationValue*>( GetParent() ) )
+ pParent->OnClick( this );
+
+ ScRefButton::Click();
+}
+
+void ScTPValidationValue::OnClick( Button *pBtn )
+{
+ if( pBtn == &m_btnRef )
+ SetupRefDlg();
+}
+
+BOOL ScValidationDlg::IsChildFocus()
+{
+ if ( const Window *pWin = Application::GetFocusWindow() )
+ while( NULL != ( pWin = pWin->GetParent() ) )
+ if( pWin == this )
+ return TRUE;
+
+ return FALSE;
+}
+
+
+bool ScValidationDlg::IsAlive()
+{
+ return SC_MOD()->IsAliveRefDlg( SLOTID, this );
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
diff --git a/sc/source/ui/dbgui/validate.src b/sc/source/ui/dbgui/validate.src
new file mode 100644
index 000000000000..c861fbc200cb
--- /dev/null
+++ b/sc/source/ui/dbgui/validate.src
@@ -0,0 +1,407 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "validate.hrc"
+
+
+TabDialog TAB_DLG_VALIDATION
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 289 , 176 ) ;
+ Moveable = TRUE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = TP_VALIDATION_VALUES ;
+ PageResID = TP_VALIDATION_VALUES ;
+ Text [ en-US ] = "Criteria";
+ };
+ PageItem
+ {
+ Identifier = TP_VALIDATION_INPUTHELP ;
+ PageResID = TP_VALIDATION_INPUTHELP ;
+ Text [ en-US ] = "Input Help" ;
+ };
+ PageItem
+ {
+ Identifier = TP_VALIDATION_ERROR ;
+ PageResID = TP_VALIDATION_ERROR ;
+ Text [ en-US ] = "Error Alert" ;
+ };
+ };
+ };
+ Text [ en-US ] = "Validity" ;
+};
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#define OFFSET_X 30
+//-->Added by PengYunQuan for Validity Cell Range Picker
+TabPage TP_VALIDATION_VALUES
+{
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ Text [ en-US ] = "Values" ;
+ FixedText FT_ALLOW
+ {
+ Pos = MAP_APPFONT ( 6 , 16 ) ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Size = MAP_APPFONT ( 70 , 8 ) ;
+ Size = MAP_APPFONT ( 70 - OFFSET_X , 8 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Text [ en-US ] = "~Allow" ;
+ };
+ ListBox LB_ALLOW
+ {
+ Border = TRUE ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 14 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 14 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Size = MAP_APPFONT ( 90 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "All values" ; SC_VALIDDLG_ALLOW_ANY ; > ;
+ < "Whole Numbers" ; SC_VALIDDLG_ALLOW_WHOLE ; > ;
+ < "Decimal" ; SC_VALIDDLG_ALLOW_DECIMAL ; > ;
+ < "Date" ; SC_VALIDDLG_ALLOW_DATE ; > ;
+ < "Time" ; SC_VALIDDLG_ALLOW_TIME ; > ;
+ < "Cell range" ; SC_VALIDDLG_ALLOW_RANGE ; > ;
+ < "List" ; SC_VALIDDLG_ALLOW_LIST ; > ;
+ < "Text length" ; SC_VALIDDLG_ALLOW_TEXTLEN ; > ;
+ };
+ };
+ FixedText FT_VALUE
+ {
+ Pos = MAP_APPFONT ( 6 , 58 ) ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Size = MAP_APPFONT ( 70 , 8 ) ;
+ Size = MAP_APPFONT ( 70 - OFFSET_X , 8 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Text [ en-US ] = "~Data" ;
+ };
+ ListBox LB_VALUE
+ {
+ Border = TRUE ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 56 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 56 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Size = MAP_APPFONT ( 90 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ // Reihenfolge entspricht enum ScConditionMode
+ StringList [ en-US ] =
+ {
+ < "equal" ; SC_VALIDDLG_DATA_EQUAL ; > ;
+ < "less than" ; SC_VALIDDLG_DATA_LESS ; > ;
+ < "greater than" ; SC_VALIDDLG_DATA_GREATER ; > ;
+ < "less than or equal" ; SC_VALIDDLG_DATA_EQLESS ; > ;
+ < "greater than or equal to" ; SC_VALIDDLG_DATA_EQGREATER ; > ;
+ < "not equal" ; SC_VALIDDLG_DATA_NOTEQUAL ; > ;
+ < "between" ; SC_VALIDDLG_DATA_BETWEEN ; > ;
+ < "not between" ; SC_VALIDDLG_DATA_NOTBETWEEN ; > ;
+ };
+ };
+ FixedText FT_MIN
+ {
+ Pos = MAP_APPFONT ( 6 , 76 ) ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Size = MAP_APPFONT ( 70 , 8 ) ;
+ Size = MAP_APPFONT ( 70 - OFFSET_X , 8 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Text [ en-US ] = "~Minimum" ;
+ };
+ Edit EDT_MIN
+ {
+ Border = TRUE ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 74 ) ;
+ //Size = MAP_APPFONT ( 174 , 12 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 74 ) ;
+ Size = MAP_APPFONT ( 90 , 12 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ TabStop = TRUE ;
+ };
+ MultiLineEdit EDT_LIST
+ {
+ Border = TRUE ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 74 ) ;
+ //Size = MAP_APPFONT ( 174 , 105 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 74 ) ;
+ Size = MAP_APPFONT ( 174 + OFFSET_X , 105 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ VScroll = TRUE ;
+ IgnoreTab = TRUE ;
+ };
+ FixedText FT_MAX
+ {
+ Pos = MAP_APPFONT ( 6 , 92 ) ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Size = MAP_APPFONT ( 70 , 8 ) ;
+ Size = MAP_APPFONT ( 70 - OFFSET_X , 8 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Text [ en-US ] = "Ma~ximum" ;
+ };
+ Edit EDT_MAX
+ {
+ Border = TRUE ;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 90 ) ;
+ //Size = MAP_APPFONT ( 174 , 12 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 90 ) ;
+ Size = MAP_APPFONT ( 90 , 12 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ TabStop = TRUE ;
+ };
+ CheckBox TSB_ALLOW_BLANKS
+ {
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 30 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 30 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Size = MAP_APPFONT ( 174 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Allow ~blank cells" ;
+ };
+ CheckBox CB_SHOWLIST
+ {
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 80 , 44 ) ;
+ Pos = MAP_APPFONT ( 80 - OFFSET_X , 44 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Size = MAP_APPFONT ( 174 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Show selection ~list" ;
+ };
+ CheckBox CB_SORTLIST
+ {
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Pos = MAP_APPFONT ( 90 , 58 ) ;
+ Pos = MAP_APPFONT ( 90 - OFFSET_X , 58 ) ;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ Size = MAP_APPFONT ( 164 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Sor~t entries ascending" ;
+ };
+ FixedText FT_SOURCEHINT
+ {
+ Pos = MAP_APPFONT ( 80 , 90 ) ;
+ Size = MAP_APPFONT ( 174 , 64 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "A valid source can only consist of a contiguous selection of rows and columns, or a formula that results in an area or array.";
+ };
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ ImageButton RB_VALIDITY_REF
+ {
+ Pos = MAP_APPFONT ( 142 , 73 ) ;
+ Size = MAP_APPFONT ( 13 , 14 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+};
+
+TabPage TP_VALIDATION_INPUTHELP
+{
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ Text = "Eingabehilfe" ;
+ TriStateBox TSB_HELP
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 248 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Show input help when cell is selected" ;
+ };
+ FixedLine FL_CONTENT
+ {
+ Pos = MAP_APPFONT ( 6 , 22 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Contents" ;
+ };
+ FixedText FT_TITLE
+ {
+ Pos = MAP_APPFONT ( 12 , 35 ) ;
+ Size = MAP_APPFONT ( 64 , 8 ) ;
+ Text [ en-US ] = "~Title" ;
+ };
+ FixedText FT_INPUTHELP
+ {
+ Pos = MAP_APPFONT ( 12 , 53 ) ;
+ Size = MAP_APPFONT ( 64 , 8 ) ;
+ Text [ en-US ] = "~Input help" ;
+ };
+ Edit EDT_TITLE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 33 ) ;
+ Size = MAP_APPFONT ( 171 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ MultiLineEdit EDT_INPUTHELP
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 51 ) ;
+ Size = MAP_APPFONT ( 171 , 128 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ IgnoreTab = TRUE ;
+ };
+};
+
+TabPage TP_VALIDATION_ERROR
+{
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedLine FL_CONTENT
+ {
+ Pos = MAP_APPFONT ( 6 , 22 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Contents" ;
+ };
+ TriStateBox TSB_SHOW
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 248 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Show error ~message when invalid values are entered" ;
+ };
+ MultiLineEdit EDT_ERROR
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 69 ) ;
+ Size = MAP_APPFONT ( 171 , 110 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ IgnoreTab = TRUE ;
+ };
+ Edit EDT_TITLE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 51 ) ;
+ Size = MAP_APPFONT ( 171 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_ERROR
+ {
+ Pos = MAP_APPFONT ( 12 , 71 ) ;
+ Size = MAP_APPFONT ( 64 , 8 ) ;
+ Text [ en-US ] = "~Error message" ;
+ };
+ FixedText FT_TITLE
+ {
+ Pos = MAP_APPFONT ( 12 , 53 ) ;
+ Size = MAP_APPFONT ( 64 , 8 ) ;
+ Text [ en-US ] = "~Title" ;
+ };
+ FixedText FT_ACTION
+ {
+ Pos = MAP_APPFONT ( 12 , 35 ) ;
+ Size = MAP_APPFONT ( 64 , 8 ) ;
+ Text [ en-US ] = "~Action" ;
+ };
+ ListBox LB_ACTION
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 33 ) ;
+ Size = MAP_APPFONT ( 107 , 76 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ // Reihenfolge entspricht enum ScValidErrorStyle
+ StringList [ en-US ] =
+ {
+ < "Stop" ; Default ; > ;
+ < "Warning" ; Default ; > ;
+ < "Information" ; Default ; > ;
+ < "Macro" ; Default ; > ;
+ };
+ };
+ PushButton BTN_SEARCH
+ {
+ Pos = MAP_APPFONT ( 191 , 32 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Browse..." ;
+ };
+ Text [ en-US ] = "Error Alert" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/docshell/arealink.cxx b/sc/source/ui/docshell/arealink.cxx
new file mode 100644
index 000000000000..d819785c843b
--- /dev/null
+++ b/sc/source/ui/docshell/arealink.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/linkmgr.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "arealink.hxx"
+
+#include "tablink.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "undoblk.hxx"
+#include "globstr.hrc"
+#include "markdata.hxx"
+#include "hints.hxx"
+#include "filter.hxx"
+//CHINA001 #include "linkarea.hxx" // dialog
+
+#include "attrib.hxx" // raus, wenn ResetAttrib am Dokument
+#include "patattr.hxx" // raus, wenn ResetAttrib am Dokument
+#include "docpool.hxx" // raus, wenn ResetAttrib am Dokument
+
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "clipparam.hxx"
+
+struct AreaLink_Impl
+{
+ ScDocShell* m_pDocSh;
+ AbstractScLinkedAreaDlg* m_pDialog;
+
+ AreaLink_Impl() : m_pDocSh( NULL ), m_pDialog( NULL ) {}
+};
+
+TYPEINIT1(ScAreaLink,::sfx2::SvBaseLink);
+
+//------------------------------------------------------------------------
+
+ScAreaLink::ScAreaLink( SfxObjectShell* pShell, const String& rFile,
+ const String& rFilter, const String& rOpt,
+ const String& rArea, const ScRange& rDest,
+ ULONG nRefresh ) :
+ ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE),
+ ScRefreshTimer ( nRefresh ),
+ pImpl ( new AreaLink_Impl() ),
+ aFileName (rFile),
+ aFilterName (rFilter),
+ aOptions (rOpt),
+ aSourceArea (rArea),
+ aDestArea (rDest),
+ bAddUndo (TRUE),
+ bInCreate (FALSE),
+ bDoInsert (TRUE)
+{
+ DBG_ASSERT(pShell->ISA(ScDocShell), "ScAreaLink mit falscher ObjectShell");
+ pImpl->m_pDocSh = static_cast< ScDocShell* >( pShell );
+ SetRefreshHandler( LINK( this, ScAreaLink, RefreshHdl ) );
+ SetRefreshControl( pImpl->m_pDocSh->GetDocument()->GetRefreshTimerControlAddress() );
+}
+
+__EXPORT ScAreaLink::~ScAreaLink()
+{
+ StopRefreshTimer();
+ delete pImpl;
+}
+
+void __EXPORT ScAreaLink::Edit(Window* pParent, const Link& /* rEndEditHdl */ )
+{
+ // use own dialog instead of SvBaseLink::Edit...
+ // DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom
+ // ein Optionen-Dialog kommt...
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScLinkedAreaDlg* pDlg = pFact->CreateScLinkedAreaDlg( pParent, RID_SCDLG_LINKAREA);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->InitFromOldLink( aFileName, aFilterName, aOptions, aSourceArea, GetRefreshDelay() );
+ pImpl->m_pDialog = pDlg;
+ pDlg->StartExecuteModal( LINK( this, ScAreaLink, AreaEndEditHdl ) );
+}
+
+void __EXPORT ScAreaLink::DataChanged( const String&,
+ const ::com::sun::star::uno::Any& )
+{
+ // bei bInCreate nichts tun, damit Update gerufen werden kann, um den Status im
+ // LinkManager zu setzen, ohne die Daten im Dokument zu aendern
+
+ if (bInCreate)
+ return;
+
+ sfx2::LinkManager* pLinkManager=pImpl->m_pDocSh->GetDocument()->GetLinkManager();
+ if (pLinkManager!=NULL)
+ {
+ String aFile;
+ String aFilter;
+ String aArea;
+ pLinkManager->GetDisplayNames( this,0,&aFile,&aArea,&aFilter);
+
+ // the file dialog returns the filter name with the application prefix
+ // -> remove prefix
+ ScDocumentLoader::RemoveAppPrefix( aFilter );
+
+ // #81155# dialog doesn't set area, so keep old one
+ if ( !aArea.Len() )
+ {
+ aArea = aSourceArea;
+
+ // adjust in dialog:
+ String aNewLinkName;
+ sfx2::MakeLnkName( aNewLinkName, NULL, aFile, aArea, &aFilter );
+ SetName( aNewLinkName );
+ }
+
+ Refresh( aFile, aFilter, aArea, GetRefreshDelay() );
+ }
+}
+
+void __EXPORT ScAreaLink::Closed()
+{
+ // Verknuepfung loeschen: Undo
+
+ ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ if (bAddUndo && bUndo)
+ {
+ pImpl->m_pDocSh->GetUndoManager()->AddUndoAction( new ScUndoRemoveAreaLink( pImpl->m_pDocSh,
+ aFileName, aFilterName, aOptions,
+ aSourceArea, aDestArea, GetRefreshDelay() ) );
+
+ bAddUndo = FALSE; // nur einmal
+ }
+
+ SCTAB nDestTab = aDestArea.aStart.Tab();
+ if (pDoc->IsStreamValid(nDestTab))
+ pDoc->SetStreamValid(nDestTab, FALSE);
+
+ SvBaseLink::Closed();
+}
+
+void ScAreaLink::SetDestArea(const ScRange& rNew)
+{
+ aDestArea = rNew; // fuer Undo
+}
+
+void ScAreaLink::SetSource(const String& rDoc, const String& rFlt, const String& rOpt,
+ const String& rArea)
+{
+ aFileName = rDoc;
+ aFilterName = rFlt;
+ aOptions = rOpt;
+ aSourceArea = rArea;
+
+ // also update link name for dialog
+ String aNewLinkName;
+ sfx2::MakeLnkName( aNewLinkName, NULL, aFileName, aSourceArea, &aFilterName );
+ SetName( aNewLinkName );
+}
+
+BOOL ScAreaLink::IsEqual( const String& rFile, const String& rFilter, const String& rOpt,
+ const String& rSource, const ScRange& rDest ) const
+{
+ return aFileName == rFile && aFilterName == rFilter && aOptions == rOpt &&
+ aSourceArea == rSource && aDestArea.aStart == rDest.aStart;
+}
+
+// find a range with name >rAreaName< in >pSrcDoc<, return it in >rRange<
+BOOL ScAreaLink::FindExtRange( ScRange& rRange, ScDocument* pSrcDoc, const String& rAreaName )
+{
+ BOOL bFound = FALSE;
+ ScRangeName* pNames = pSrcDoc->GetRangeName();
+ USHORT nPos;
+ if (pNames) // benannte Bereiche
+ {
+ if (pNames->SearchName( rAreaName, nPos ))
+ if ( (*pNames)[nPos]->IsValidReference( rRange ) )
+ bFound = TRUE;
+ }
+ if (!bFound) // Datenbankbereiche
+ {
+ ScDBCollection* pDBColl = pSrcDoc->GetDBCollection();
+ if (pDBColl)
+ if (pDBColl->SearchName( rAreaName, nPos ))
+ {
+ SCTAB nTab;
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ (*pDBColl)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2);
+ rRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab );
+ bFound = TRUE;
+ }
+ }
+ if (!bFound) // direct reference (range or cell)
+ {
+ ScAddress::Details aDetails(pSrcDoc->GetAddressConvention(), 0, 0);
+ if ( rRange.ParseAny( rAreaName, pSrcDoc, aDetails ) & SCA_VALID )
+ bFound = TRUE;
+ }
+ return bFound;
+}
+
+// ausfuehren:
+
+BOOL ScAreaLink::Refresh( const String& rNewFile, const String& rNewFilter,
+ const String& rNewArea, ULONG nNewRefresh )
+{
+ // Dokument laden - wie TabLink
+
+ if (!rNewFile.Len() || !rNewFilter.Len())
+ return FALSE;
+
+ String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pImpl->m_pDocSh ) );
+ BOOL bNewUrlName = (aNewUrl != aFileName);
+
+ const SfxFilter* pFilter = pImpl->m_pDocSh->GetFactory().GetFilterContainer()->GetFilter4FilterName(rNewFilter);
+ if (!pFilter)
+ return FALSE;
+
+ ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
+
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ pDoc->SetInLinkUpdate( TRUE );
+
+ // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen
+ if ( rNewFilter != aFilterName )
+ aOptions.Erase();
+
+ // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann
+ SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+ if ( aOptions.Len() )
+ pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
+
+ SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, FALSE, pFilter);
+
+ ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL);
+//REMOVE SvEmbeddedObjectRef aRef = pSrcShell;
+ SfxObjectShellRef aRef = pSrcShell;
+ pSrcShell->DoLoad(pMed);
+
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+
+ // Optionen koennten gesetzt worden sein
+ String aNewOpt = ScDocumentLoader::GetOptions(*pMed);
+ if (!aNewOpt.Len())
+ aNewOpt = aOptions;
+
+ // correct source range name list for web query import
+ String aTempArea;
+
+ if( rNewFilter == ScDocShell::GetWebQueryFilterName() )
+ aTempArea = ScFormatFilter::Get().GetHTMLRangeNameList( pSrcDoc, rNewArea );
+ else
+ aTempArea = rNewArea;
+
+ // find total size of source area
+ SCCOL nWidth = 0;
+ SCROW nHeight = 0;
+ xub_StrLen nTokenCnt = aTempArea.GetTokenCount( ';' );
+ xub_StrLen nStringIx = 0;
+ xub_StrLen nToken;
+
+ for( nToken = 0; nToken < nTokenCnt; nToken++ )
+ {
+ String aToken( aTempArea.GetToken( 0, ';', nStringIx ) );
+ ScRange aTokenRange;
+ if( FindExtRange( aTokenRange, pSrcDoc, aToken ) )
+ {
+ // columns: find maximum
+ nWidth = Max( nWidth, (SCCOL)(aTokenRange.aEnd.Col() - aTokenRange.aStart.Col() + 1) );
+ // rows: add row range + 1 empty row
+ nHeight += aTokenRange.aEnd.Row() - aTokenRange.aStart.Row() + 2;
+ }
+ }
+ // remove the last empty row
+ if( nHeight > 0 )
+ nHeight--;
+
+ // alte Daten loeschen / neue kopieren
+
+ ScAddress aDestPos = aDestArea.aStart;
+ SCTAB nDestTab = aDestPos.Tab();
+ ScRange aOldRange = aDestArea;
+ ScRange aNewRange = aDestArea; // alter Bereich, wenn Datei nicht gefunden o.ae.
+ if (nWidth > 0 && nHeight > 0)
+ {
+ aNewRange.aEnd.SetCol( aNewRange.aStart.Col() + nWidth - 1 );
+ aNewRange.aEnd.SetRow( aNewRange.aStart.Row() + nHeight - 1 );
+ }
+
+ //! check CanFitBlock only if bDoInsert is set?
+ BOOL bCanDo = ValidColRow( aNewRange.aEnd.Col(), aNewRange.aEnd.Row() ) &&
+ pDoc->CanFitBlock( aOldRange, aNewRange );
+ if (bCanDo)
+ {
+ ScDocShellModificator aModificator( *pImpl->m_pDocSh );
+
+ SCCOL nOldEndX = aOldRange.aEnd.Col();
+ SCROW nOldEndY = aOldRange.aEnd.Row();
+ SCCOL nNewEndX = aNewRange.aEnd.Col();
+ SCROW nNewEndY = aNewRange.aEnd.Row();
+ ScRange aMaxRange( aDestPos,
+ ScAddress(Max(nOldEndX,nNewEndX), Max(nOldEndY,nNewEndY), nDestTab) );
+
+ // Undo initialisieren
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRedoDoc = NULL;
+ if ( bAddUndo && bUndo )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ if ( bDoInsert )
+ {
+ if ( nNewEndX != nOldEndX || nNewEndY != nOldEndY ) // Bereich veraendert?
+ {
+ pUndoDoc->InitUndo( pDoc, 0, pDoc->GetTableCount()-1 );
+ pDoc->CopyToDocument( 0,0,0,MAXCOL,MAXROW,MAXTAB,
+ IDF_FORMULA, FALSE, pUndoDoc ); // alle Formeln
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle
+ pDoc->CopyToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, FALSE, pUndoDoc );
+ }
+ else // ohne Einfuegen
+ {
+ pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle
+ pDoc->CopyToDocument( aMaxRange, IDF_ALL & ~IDF_NOTE, FALSE, pUndoDoc );
+ }
+ }
+
+ // Zellen einfuegen / loeschen
+ // DeleteAreaTab loescht auch MERGE_FLAG Attribute
+
+ if (bDoInsert)
+ pDoc->FitBlock( aOldRange, aNewRange ); // incl. loeschen
+ else
+ pDoc->DeleteAreaTab( aMaxRange, IDF_ALL & ~IDF_NOTE );
+
+ // Daten kopieren
+
+ if (nWidth > 0 && nHeight > 0)
+ {
+ ScDocument aClipDoc( SCDOCMODE_CLIP );
+ ScRange aNewTokenRange( aNewRange.aStart );
+ nStringIx = 0;
+ for( nToken = 0; nToken < nTokenCnt; nToken++ )
+ {
+ String aToken( aTempArea.GetToken( 0, ';', nStringIx ) );
+ ScRange aTokenRange;
+ if( FindExtRange( aTokenRange, pSrcDoc, aToken ) )
+ {
+ SCTAB nSrcTab = aTokenRange.aStart.Tab();
+ ScMarkData aSourceMark;
+ aSourceMark.SelectOneTable( nSrcTab ); // selektieren fuer CopyToClip
+ aSourceMark.SetMarkArea( aTokenRange );
+
+ ScClipParam aClipParam(aTokenRange, false);
+ pSrcDoc->CopyToClip(aClipParam, &aClipDoc, &aSourceMark);
+
+ if ( aClipDoc.HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ //! ResetAttrib am Dokument !!!
+
+ ScPatternAttr aPattern( pSrcDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults
+ aPattern.GetItemSet().Put( ScMergeFlagAttr() );
+ aClipDoc.ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern );
+ }
+
+ aNewTokenRange.aEnd.SetCol( aNewTokenRange.aStart.Col() + (aTokenRange.aEnd.Col() - aTokenRange.aStart.Col()) );
+ aNewTokenRange.aEnd.SetRow( aNewTokenRange.aStart.Row() + (aTokenRange.aEnd.Row() - aTokenRange.aStart.Row()) );
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nDestTab );
+ aDestMark.SetMarkArea( aNewTokenRange );
+ pDoc->CopyFromClip( aNewTokenRange, aDestMark, IDF_ALL, NULL, &aClipDoc, FALSE );
+ aNewTokenRange.aStart.SetRow( aNewTokenRange.aEnd.Row() + 2 );
+ }
+ }
+ }
+ else
+ {
+ String aErr = ScGlobal::GetRscString(STR_LINKERROR);
+ pDoc->SetString( aDestPos.Col(), aDestPos.Row(), aDestPos.Tab(), aErr );
+ }
+
+ // Undo eintragen
+
+ if ( bAddUndo && bUndo)
+ {
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nDestTab, nDestTab );
+ pDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, FALSE, pRedoDoc );
+
+ pImpl->m_pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoUpdateAreaLink( pImpl->m_pDocSh,
+ aFileName, aFilterName, aOptions,
+ aSourceArea, aOldRange, GetRefreshDelay(),
+ aNewUrl, rNewFilter, aNewOpt,
+ rNewArea, aNewRange, nNewRefresh,
+ pUndoDoc, pRedoDoc, bDoInsert ) );
+ }
+
+ // neue Einstellungen merken
+
+ if ( bNewUrlName )
+ aFileName = aNewUrl;
+ if ( rNewFilter != aFilterName )
+ aFilterName = rNewFilter;
+ if ( rNewArea != aSourceArea )
+ aSourceArea = rNewArea;
+ if ( aNewOpt != aOptions )
+ aOptions = aNewOpt;
+
+ if ( aNewRange != aDestArea )
+ aDestArea = aNewRange;
+
+ if ( nNewRefresh != GetRefreshDelay() )
+ SetRefreshDelay( nNewRefresh );
+
+ SCCOL nPaintEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() );
+ SCROW nPaintEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() );
+
+ if ( aOldRange.aEnd.Col() != aNewRange.aEnd.Col() )
+ nPaintEndX = MAXCOL;
+ if ( aOldRange.aEnd.Row() != aNewRange.aEnd.Row() )
+ nPaintEndY = MAXROW;
+
+ if ( !pImpl->m_pDocSh->AdjustRowHeight( aDestPos.Row(), nPaintEndY, nDestTab ) )
+ pImpl->m_pDocSh->PostPaint( aDestPos.Col(),aDestPos.Row(),nDestTab,
+ nPaintEndX,nPaintEndY,nDestTab, PAINT_GRID );
+ aModificator.SetDocumentModified();
+ }
+ else
+ {
+ // CanFitBlock FALSE -> Probleme mit zusammengefassten Zellen
+ // oder Tabellengrenze erreicht!
+ //! Zellschutz ???
+
+ //! Link-Dialog muss Default-Parent setzen
+ // "kann keine Zeilen einfuegen"
+ InfoBox aBox( Application::GetDefDialogParent(),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_2 ) );
+ aBox.Execute();
+ }
+
+ // aufraeumen
+
+ aRef->DoClose();
+
+ pDoc->SetInLinkUpdate( FALSE );
+
+ if (bCanDo)
+ {
+ // notify Uno objects (for XRefreshListener)
+ //! also notify Uno objects if file name was changed!
+ ScLinkRefreshedHint aHint;
+ aHint.SetAreaLink( aDestPos );
+ pDoc->BroadcastUno( aHint );
+ }
+
+ return bCanDo;
+}
+
+
+IMPL_LINK( ScAreaLink, RefreshHdl, ScAreaLink*, EMPTYARG )
+{
+ long nRes = Refresh( aFileName, aFilterName, aSourceArea,
+ GetRefreshDelay() ) != 0;
+ return nRes;
+}
+
+IMPL_LINK( ScAreaLink, AreaEndEditHdl, void*, EMPTYARG )
+{
+ // #i76514# can't use link argument to access the dialog,
+ // because it's the ScLinkedAreaDlg, not AbstractScLinkedAreaDlg
+
+ if ( pImpl->m_pDialog && pImpl->m_pDialog->GetResult() == RET_OK )
+ {
+ aOptions = pImpl->m_pDialog->GetOptions();
+ Refresh( pImpl->m_pDialog->GetURL(), pImpl->m_pDialog->GetFilter(),
+ pImpl->m_pDialog->GetSource(), pImpl->m_pDialog->GetRefresh() );
+
+ // copy source data from members (set in Refresh) into link name for dialog
+ String aNewLinkName;
+ sfx2::MakeLnkName( aNewLinkName, NULL, aFileName, aSourceArea, &aFilterName );
+ SetName( aNewLinkName );
+ }
+ pImpl->m_pDialog = NULL; // dialog is deleted with parent
+
+ return 0;
+}
+
diff --git a/sc/source/ui/docshell/autostyl.cxx b/sc/source/ui/docshell/autostyl.cxx
new file mode 100644
index 000000000000..61683e169f02
--- /dev/null
+++ b/sc/source/ui/docshell/autostyl.cxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <time.h>
+#include "autostyl.hxx"
+
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "sc.hrc"
+
+//==================================================================
+
+struct ScAutoStyleInitData
+{
+ ScRange aRange;
+ String aStyle1;
+ ULONG nTimeout;
+ String aStyle2;
+
+ ScAutoStyleInitData( const ScRange& rR, const String& rSt1, ULONG nT, const String& rSt2 ) :
+ aRange(rR), aStyle1(rSt1), nTimeout(nT), aStyle2(rSt2) {}
+};
+
+struct ScAutoStyleData
+{
+ ULONG nTimeout;
+ ScRange aRange;
+ String aStyle;
+
+ ScAutoStyleData( ULONG nT, const ScRange& rR, const String& rT ) :
+ nTimeout(nT), aRange(rR), aStyle(rT) {}
+};
+
+//==================================================================
+
+inline ULONG TimeNow() // Sekunden
+{
+ return (ULONG) time(0);
+}
+
+//==================================================================
+
+ScAutoStyleList::ScAutoStyleList(ScDocShell* pShell) :
+ pDocSh( pShell )
+{
+ aTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, TimerHdl ) );
+ aInitTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, InitHdl ) );
+ aInitTimer.SetTimeout( 0 );
+}
+
+ScAutoStyleList::~ScAutoStyleList()
+{
+ ULONG i;
+ ULONG nCount = aEntries.Count();
+ for (i=0; i<nCount; i++)
+ delete (ScAutoStyleData*) aEntries.GetObject(i);
+ nCount = aInitials.Count();
+ for (i=0; i<nCount; i++)
+ delete (ScAutoStyleInitData*) aInitials.GetObject(i);
+}
+
+//==================================================================
+
+// initial short delay (asynchronous call)
+
+void ScAutoStyleList::AddInitial( const ScRange& rRange, const String& rStyle1,
+ ULONG nTimeout, const String& rStyle2 )
+{
+ ScAutoStyleInitData* pNew =
+ new ScAutoStyleInitData( rRange, rStyle1, nTimeout, rStyle2 );
+ aInitials.Insert( pNew, aInitials.Count() );
+ aInitTimer.Start();
+}
+
+IMPL_LINK( ScAutoStyleList, InitHdl, Timer*, EMPTYARG )
+{
+ ULONG nCount = aInitials.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScAutoStyleInitData* pData = (ScAutoStyleInitData*) aInitials.GetObject(i);
+
+ // apply first style immediately
+ pDocSh->DoAutoStyle( pData->aRange, pData->aStyle1 );
+
+ // add second style to list
+ if ( pData->nTimeout )
+ AddEntry( pData->nTimeout, pData->aRange, pData->aStyle2 );
+
+ delete pData;
+ }
+ aInitials.Clear();
+
+ return 0;
+}
+
+//==================================================================
+
+void ScAutoStyleList::AddEntry( ULONG nTimeout, const ScRange& rRange, const String& rStyle )
+{
+ aTimer.Stop();
+ ULONG nNow = TimeNow();
+
+ // alten Eintrag loeschen
+
+ ULONG nCount = aEntries.Count();
+ ULONG i;
+ for (i=0; i<nCount; i++)
+ {
+ ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i);
+ if (pData->aRange == rRange)
+ {
+ delete pData;
+ aEntries.Remove(i);
+ --nCount;
+ break; // nicht weitersuchen - es kann nur einen geben
+ }
+ }
+
+ // Timeouts von allen Eintraegen anpassen
+
+ if (nCount && nNow != nTimerStart)
+ {
+ DBG_ASSERT(nNow>nTimerStart, "Zeit laeuft rueckwaerts?");
+ AdjustEntries((nNow-nTimerStart)*1000);
+ }
+
+ // Einfuege-Position suchen
+
+ ULONG nPos = LIST_APPEND;
+ for (i=0; i<nCount && nPos == LIST_APPEND; i++)
+ if (nTimeout <= ((ScAutoStyleData*) aEntries.GetObject(i))->nTimeout)
+ nPos = i;
+
+ ScAutoStyleData* pNew = new ScAutoStyleData( nTimeout, rRange, rStyle );
+ aEntries.Insert( pNew, nPos );
+
+ // abgelaufene ausfuehren, Timer neu starten
+
+ ExecuteEntries();
+ StartTimer(nNow);
+}
+
+void ScAutoStyleList::AdjustEntries( ULONG nDiff ) // Millisekunden
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i);
+ if ( pData->nTimeout <= nDiff )
+ pData->nTimeout = 0; // abgelaufen
+ else
+ pData->nTimeout -= nDiff; // weiterzaehlen
+ }
+}
+
+void ScAutoStyleList::ExecuteEntries()
+{
+ ScAutoStyleData* pData;
+ while ((pData = (ScAutoStyleData*) aEntries.GetObject(0)) != NULL && pData->nTimeout == 0)
+ {
+ pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ???
+
+ delete pData;
+ aEntries.Remove((ULONG)0);
+ }
+}
+
+void ScAutoStyleList::ExecuteAllNow()
+{
+ aTimer.Stop();
+
+ ULONG nCount = aEntries.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i);
+
+ pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ???
+
+ delete pData;
+ }
+ aEntries.Clear();
+}
+
+void ScAutoStyleList::StartTimer( ULONG nNow ) // Sekunden
+{
+ // ersten Eintrag mit Timeout != 0 suchen
+
+ ULONG nPos = 0;
+ ScAutoStyleData* pData;
+ while ( (pData = (ScAutoStyleData*) aEntries.GetObject(nPos)) != NULL && pData->nTimeout == 0 )
+ ++nPos;
+
+ if (pData)
+ {
+ aTimer.SetTimeout( pData->nTimeout );
+ aTimer.Start();
+ }
+ nTimerStart = nNow;
+}
+
+IMPL_LINK( ScAutoStyleList, TimerHdl, Timer*, EMPTYARG )
+{
+ ULONG nNow = TimeNow();
+ AdjustEntries(aTimer.GetTimeout()); // eingestellte Wartezeit
+ ExecuteEntries();
+ StartTimer(nNow);
+
+ return 0;
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
new file mode 100644
index 000000000000..cf149d258062
--- /dev/null
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -0,0 +1,1503 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/app.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/waitobj.hxx>
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include "dbdocfun.hxx"
+#include "sc.hrc"
+#include "dbcolect.hxx"
+#include "undodat.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "patattr.hxx"
+#include "rangenam.hxx"
+#include "olinetab.hxx"
+#include "dpobject.hxx"
+#include "dociter.hxx" // for lcl_EmptyExcept
+#include "cell.hxx" // for lcl_EmptyExcept
+#include "editable.hxx"
+#include "attrib.hxx"
+#include "drwlayer.hxx"
+#include "dpshttab.hxx"
+#include "hints.hxx"
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::AddDBRange( const String& rName, const ScRange& rRange, BOOL /* bApi */ )
+{
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScDBCollection* pDocColl = pDoc->GetDBCollection();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ ScDBCollection* pUndoColl = NULL;
+ if (bUndo)
+ pUndoColl = new ScDBCollection( *pDocColl );
+
+ ScDBData* pNew = new ScDBData( rName, rRange.aStart.Tab(),
+ rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row() );
+
+ // #i55926# While loading XML, formula cells only have a single string token,
+ // so CompileDBFormula would never find any name (index) tokens, and would
+ // unnecessarily loop through all cells.
+ BOOL bCompile = !pDoc->IsImportingXML();
+
+ if ( bCompile )
+ pDoc->CompileDBFormula( TRUE ); // CreateFormulaString
+ BOOL bOk = pDocColl->Insert( pNew );
+ if ( bCompile )
+ pDoc->CompileDBFormula( FALSE ); // CompileFormulaString
+
+ if (!bOk)
+ {
+ delete pNew;
+ delete pUndoColl;
+ return FALSE;
+ }
+
+ if (bUndo)
+ {
+ ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
+ }
+
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ return TRUE;
+}
+
+BOOL ScDBDocFunc::DeleteDBRange( const String& rName, BOOL /* bApi */ )
+{
+ BOOL bDone = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScDBCollection* pDocColl = pDoc->GetDBCollection();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ USHORT nPos = 0;
+ if (pDocColl->SearchName( rName, nPos ))
+ {
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDBCollection* pUndoColl = NULL;
+ if (bUndo)
+ pUndoColl = new ScDBCollection( *pDocColl );
+
+ pDoc->CompileDBFormula( TRUE ); // CreateFormulaString
+ pDocColl->AtFree( nPos );
+ pDoc->CompileDBFormula( FALSE ); // CompileFormulaString
+
+ if (bUndo)
+ {
+ ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
+ }
+
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ bDone = TRUE;
+ }
+
+ return bDone;
+}
+
+BOOL ScDBDocFunc::RenameDBRange( const String& rOld, const String& rNew, BOOL /* bApi */ )
+{
+ BOOL bDone = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScDBCollection* pDocColl = pDoc->GetDBCollection();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ USHORT nPos = 0;
+ USHORT nDummy = 0;
+ if ( pDocColl->SearchName( rOld, nPos ) &&
+ !pDocColl->SearchName( rNew, nDummy ) )
+ {
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDBData* pData = (*pDocColl)[nPos];
+ ScDBData* pNewData = new ScDBData(*pData);
+ pNewData->SetName(rNew);
+
+ ScDBCollection* pUndoColl = new ScDBCollection( *pDocColl );
+
+ pDoc->CompileDBFormula( TRUE ); // CreateFormulaString
+ pDocColl->AtFree( nPos );
+ BOOL bInserted = pDocColl->Insert( pNewData );
+ if (!bInserted) // Fehler -> alten Zustand wiederherstellen
+ {
+ delete pNewData;
+ pDoc->SetDBCollection( pUndoColl ); // gehoert dann dem Dokument
+ }
+ pDoc->CompileDBFormula( FALSE ); // CompileFormulaString
+
+ if (bInserted) // Einfuegen hat geklappt
+ {
+ if (bUndo)
+ {
+ ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
+ }
+ else
+ delete pUndoColl;
+
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ bDone = TRUE;
+ }
+ }
+
+ return bDone;
+}
+
+BOOL ScDBDocFunc::ModifyDBData( const ScDBData& rNewData, BOOL /* bApi */ )
+{
+ BOOL bDone = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScDBCollection* pDocColl = pDoc->GetDBCollection();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ USHORT nPos = 0;
+ if (pDocColl->SearchName( rNewData.GetName(), nPos ))
+ {
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDBData* pData = (*pDocColl)[nPos];
+
+ ScRange aOldRange, aNewRange;
+ pData->GetArea(aOldRange);
+ rNewData.GetArea(aNewRange);
+ BOOL bAreaChanged = ( aOldRange != aNewRange ); // dann muss neu compiliert werden
+
+ ScDBCollection* pUndoColl = NULL;
+ if (bUndo)
+ pUndoColl = new ScDBCollection( *pDocColl );
+
+ *pData = rNewData;
+ if (bAreaChanged)
+ pDoc->CompileDBFormula();
+
+ if (bUndo)
+ {
+ ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) );
+ }
+
+ aModificator.SetDocumentModified();
+ bDone = TRUE;
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::RepeatDB( const String& rDBName, BOOL bRecord, BOOL bApi )
+{
+ //! auch fuer ScDBFunc::RepeatDB benutzen!
+
+ BOOL bDone = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ USHORT nIndex;
+ if ( pColl && pColl->SearchName( rDBName, nIndex ) )
+ {
+ ScDBData* pDBData = (*pColl)[nIndex];
+
+ ScQueryParam aQueryParam;
+ pDBData->GetQueryParam( aQueryParam );
+ BOOL bQuery = aQueryParam.GetEntry(0).bDoQuery;
+
+ ScSortParam aSortParam;
+ pDBData->GetSortParam( aSortParam );
+ BOOL bSort = aSortParam.bDoSort[0];
+
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ BOOL bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly;
+
+ if ( bQuery || bSort || bSubTotal )
+ {
+ BOOL bQuerySize = FALSE;
+ ScRange aOldQuery;
+ ScRange aNewQuery;
+ if (bQuery && !aQueryParam.bInplace)
+ {
+ ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, TRUE );
+ if (pDest && pDest->IsDoSize())
+ {
+ pDest->GetArea( aOldQuery );
+ bQuerySize = TRUE;
+ }
+ }
+
+ SCTAB nTab;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDBData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+
+ //! Undo nur benoetigte Daten ?
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ ScRangeName* pUndoRange = NULL;
+ ScDBCollection* pUndoDB = NULL;
+
+ if (bRecord)
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ // column/row state
+ SCCOLROW nOutStartCol, nOutEndCol;
+ SCCOLROW nOutStartRow, nOutEndRow;
+ pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
+ pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0,
+ nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, static_cast<SCROW>(nOutStartRow),
+ nTab, MAXCOL, static_cast<SCROW>(nOutEndRow), nTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+
+ // Datenbereich sichern - incl. Filter-Ergebnis
+ pDoc->CopyToDocument( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab, IDF_ALL, FALSE, pUndoDoc );
+
+ // alle Formeln wegen Referenzen
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, IDF_FORMULA, FALSE, pUndoDoc );
+
+ // DB- und andere Bereiche
+ ScRangeName* pDocRange = pDoc->GetRangeName();
+ if (pDocRange->GetCount())
+ pUndoRange = new ScRangeName( *pDocRange );
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+ }
+
+ if (bSort && bSubTotal)
+ {
+ // Sortieren ohne SubTotals
+
+ aSubTotalParam.bRemoveOnly = TRUE; // wird unten wieder zurueckgesetzt
+ DoSubTotals( nTab, aSubTotalParam, NULL, FALSE, bApi );
+ }
+
+ if (bSort)
+ {
+ pDBData->GetSortParam( aSortParam ); // Bereich kann sich geaendert haben
+ Sort( nTab, aSortParam, FALSE, FALSE, bApi );
+ }
+ if (bQuery)
+ {
+ pDBData->GetQueryParam( aQueryParam ); // Bereich kann sich geaendert haben
+ ScRange aAdvSource;
+ if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ Query( nTab, aQueryParam, &aAdvSource, FALSE, bApi );
+ else
+ Query( nTab, aQueryParam, NULL, FALSE, bApi );
+
+ // bei nicht-inplace kann die Tabelle umgestellt worden sein
+// if ( !aQueryParam.bInplace && aQueryParam.nDestTab != nTab )
+// SetTabNo( nTab );
+ }
+ if (bSubTotal)
+ {
+ pDBData->GetSubTotalParam( aSubTotalParam ); // Bereich kann sich geaendert haben
+ aSubTotalParam.bRemoveOnly = FALSE;
+ DoSubTotals( nTab, aSubTotalParam, NULL, FALSE, bApi );
+ }
+
+ if (bRecord)
+ {
+ SCTAB nDummyTab;
+ SCCOL nDummyCol;
+ SCROW nDummyRow;
+ SCROW nNewEndRow;
+ pDBData->GetArea( nDummyTab, nDummyCol,nDummyRow, nDummyCol,nNewEndRow );
+
+ const ScRange* pOld = NULL;
+ const ScRange* pNew = NULL;
+ if (bQuerySize)
+ {
+ ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, TRUE );
+ if (pDest)
+ {
+ pDest->GetArea( aNewQuery );
+ pOld = &aOldQuery;
+ pNew = &aNewQuery;
+ }
+ }
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoRepeatDB( &rDocShell, nTab,
+ nStartCol, nStartRow, nEndCol, nEndRow,
+ nNewEndRow,
+ //nCurX, nCurY,
+ nStartCol, nStartRow,
+ pUndoDoc, pUndoTab,
+ pUndoRange, pUndoDB,
+ pOld, pNew ) );
+ }
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+ bDone = TRUE;
+ }
+ else if (!bApi) // "Keine Operationen auszufuehren"
+ rDocShell.ErrorMessage(STR_MSSG_REPEATDB_0);
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
+ BOOL bRecord, BOOL bPaint, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ SCTAB nSrcTab = nTab;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
+ rSortParam.nCol2, rSortParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "Sort: keine DBData" );
+ return FALSE;
+ }
+
+ ScDBData* pDestData = NULL;
+ ScRange aOldDest;
+ BOOL bCopy = !rSortParam.bInplace;
+ if ( bCopy && rSortParam.nDestCol == rSortParam.nCol1 &&
+ rSortParam.nDestRow == rSortParam.nRow1 && rSortParam.nDestTab == nTab )
+ bCopy = FALSE;
+ ScSortParam aLocalParam( rSortParam );
+ if ( bCopy )
+ {
+ aLocalParam.MoveToDest();
+ if ( !ValidColRow( aLocalParam.nCol2, aLocalParam.nRow2 ) )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PASTE_FULL);
+ return FALSE;
+ }
+
+ nTab = rSortParam.nDestTab;
+ pDestData = pDoc->GetDBAtCursor( rSortParam.nDestCol, rSortParam.nDestRow,
+ rSortParam.nDestTab, TRUE );
+ if (pDestData)
+ pDestData->GetArea(aOldDest);
+ }
+
+ ScEditableTester aTester( pDoc, nTab, aLocalParam.nCol1,aLocalParam.nRow1,
+ aLocalParam.nCol2,aLocalParam.nRow2 );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ if ( aLocalParam.bIncludePattern && pDoc->HasAttrib(
+ aLocalParam.nCol1, aLocalParam.nRow1, nTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ // Merge-Attribute wuerden beim Sortieren durcheinanderkommen
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_SORT_ERR_MERGED);
+ return FALSE;
+ }
+
+
+ // ausfuehren
+
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ BOOL bRepeatQuery = FALSE; // bestehenden Filter wiederholen?
+ ScQueryParam aQueryParam;
+ pDBData->GetQueryParam( aQueryParam );
+ if ( aQueryParam.GetEntry(0).bDoQuery )
+ bRepeatQuery = TRUE;
+
+ if (bRepeatQuery && bCopy)
+ {
+ if ( aQueryParam.bInplace ||
+ aQueryParam.nDestCol != rSortParam.nDestCol ||
+ aQueryParam.nDestRow != rSortParam.nDestRow ||
+ aQueryParam.nDestTab != rSortParam.nDestTab ) // Query auf selben Zielbereich?
+ bRepeatQuery = FALSE;
+ }
+
+ ScUndoSort* pUndoAction = 0;
+ if ( bRecord )
+ {
+ // Referenzen ausserhalb des Bereichs werden nicht veraendert !
+
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ // Zeilenhoehen immer (wegen automatischer Anpassung)
+ //! auf ScBlockUndo umstellen
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+
+ /* #i59745# Do not copy note captions to undo document. All existing
+ caption objects will be repositioned while sorting which is tracked
+ in drawing undo. When undo is executed, the old positions will be
+ restored, and the cells with the old notes (which still refer to the
+ existing captions) will be copied back into the source document. */
+ pDoc->CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nTab,
+ IDF_ALL|IDF_NOCAPTIONS, FALSE, pUndoDoc );
+
+ const ScRange* pR = 0;
+ if (pDestData)
+ {
+ /* #i59745# Do not copy note captions from destination range to
+ undo document. All existing caption objects will be removed
+ which is tracked in drawing undo. When undo is executed, the
+ caption objects are reinserted with drawing undo, and the cells
+ with the old notes (which still refer to the existing captions)
+ will be copied back into the source document. */
+ pDoc->CopyToDocument( aOldDest, IDF_ALL|IDF_NOCAPTIONS, FALSE, pUndoDoc );
+ pR = &aOldDest;
+ }
+
+ // Zeilenhoehen immer (wegen automatischer Anpassung)
+ //! auf ScBlockUndo umstellen
+// if (bRepeatQuery)
+ pDoc->CopyToDocument( 0, aLocalParam.nRow1, nTab, MAXCOL, aLocalParam.nRow2, nTab,
+ IDF_NONE, FALSE, pUndoDoc );
+
+ ScDBCollection* pUndoDB = NULL;
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+
+ pUndoAction = new ScUndoSort( &rDocShell, nTab, rSortParam, bRepeatQuery, pUndoDoc, pUndoDB, pR );
+ rDocShell.GetUndoManager()->AddUndoAction( pUndoAction );
+
+ // #i59745# collect all drawing undo actions affecting cell note captions
+ if( pDrawLayer )
+ pDrawLayer->BeginCalcUndo();
+ }
+
+ if ( bCopy )
+ {
+ if (pDestData)
+ pDoc->DeleteAreaTab(aOldDest, IDF_CONTENTS); // Zielbereich vorher loeschen
+
+ ScRange aSource( rSortParam.nCol1,rSortParam.nRow1,nSrcTab,
+ rSortParam.nCol2,rSortParam.nRow2,nSrcTab );
+ ScAddress aDest( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab );
+
+ rDocShell.GetDocFunc().MoveBlock( aSource, aDest, FALSE, FALSE, FALSE, TRUE );
+ }
+
+ // #105780# don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
+ if ( aLocalParam.bDoSort[0] )
+ pDoc->Sort( nTab, aLocalParam, bRepeatQuery );
+
+ BOOL bSave = TRUE;
+ if (bCopy)
+ {
+ ScSortParam aOldSortParam;
+ pDBData->GetSortParam( aOldSortParam );
+ if ( aOldSortParam.bDoSort[0] && aOldSortParam.bInplace ) // Inplace-Sortierung gemerkt?
+ {
+ bSave = FALSE;
+ aOldSortParam.nDestCol = rSortParam.nDestCol;
+ aOldSortParam.nDestRow = rSortParam.nDestRow;
+ aOldSortParam.nDestTab = rSortParam.nDestTab;
+ pDBData->SetSortParam( aOldSortParam ); // dann nur DestPos merken
+ }
+ }
+ if (bSave) // Parameter merken
+ {
+ pDBData->SetSortParam( rSortParam );
+ pDBData->SetHeader( rSortParam.bHasHeader ); //! ???
+ pDBData->SetByRow( rSortParam.bByRow ); //! ???
+ }
+
+ if (bCopy) // neuen DB-Bereich merken
+ {
+ // Tabelle umschalten von aussen (View)
+ //! SetCursor ??!?!
+
+ ScRange aDestPos( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nTab );
+ ScDBData* pNewData;
+ if (pDestData)
+ pNewData = pDestData; // Bereich vorhanden -> anpassen
+ else // Bereich ab Cursor/Markierung wird angelegt
+ pNewData = rDocShell.GetDBData(aDestPos, SC_DB_MAKE, SC_DBSEL_FORCE_MARK );
+ if (pNewData)
+ {
+ pNewData->SetArea( nTab,
+ aLocalParam.nCol1,aLocalParam.nRow1,
+ aLocalParam.nCol2,aLocalParam.nRow2 );
+ pNewData->SetSortParam( aLocalParam );
+ pNewData->SetHeader( aLocalParam.bHasHeader ); //! ???
+ pNewData->SetByRow( aLocalParam.bByRow );
+ }
+ else
+ {
+ DBG_ERROR("Zielbereich nicht da");
+ }
+ }
+
+ ScRange aDirtyRange( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nTab );
+ pDoc->SetDirty( aDirtyRange );
+
+ if (bPaint)
+ {
+ USHORT nPaint = PAINT_GRID;
+ SCCOL nStartX = aLocalParam.nCol1;
+ SCROW nStartY = aLocalParam.nRow1;
+ SCCOL nEndX = aLocalParam.nCol2;
+ SCROW nEndY = aLocalParam.nRow2;
+ if ( bRepeatQuery )
+ {
+ nPaint |= PAINT_LEFT;
+ nStartX = 0;
+ nEndX = MAXCOL;
+ }
+ if (pDestData)
+ {
+ if ( nEndX < aOldDest.aEnd.Col() )
+ nEndX = aOldDest.aEnd.Col();
+ if ( nEndY < aOldDest.aEnd.Row() )
+ nEndY = aOldDest.aEnd.Row();
+ }
+ rDocShell.PostPaint( nStartX, nStartY, nTab, nEndX, nEndY, nTab, nPaint );
+ }
+
+ // AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, bPaint );
+ rDocShell.AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, nTab );
+
+ // #i59745# set collected drawing undo actions at sorting undo action
+ if( pUndoAction && pDrawLayer )
+ pUndoAction->SetDrawUndoAction( pDrawLayer->GetCalcUndo() );
+
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam,
+ const ScRange* pAdvSource, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rQueryParam.nCol1, rQueryParam.nRow1,
+ rQueryParam.nCol2, rQueryParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "Query: keine DBData" );
+ return FALSE;
+ }
+
+ // Wechsel von Inplace auf nicht-Inplace, dann erst Inplace aufheben:
+ // (nur, wenn im Dialog "Persistent" ausgewaehlt ist)
+
+ if ( !rQueryParam.bInplace && pDBData->HasQueryParam() && rQueryParam.bDestPers )
+ {
+ ScQueryParam aOldQuery;
+ pDBData->GetQueryParam(aOldQuery);
+ if (aOldQuery.bInplace)
+ {
+ // alte Filterung aufheben
+
+ SCSIZE nEC = aOldQuery.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aOldQuery.GetEntry(i).bDoQuery = FALSE;
+ aOldQuery.bDuplicate = TRUE;
+ Query( nTab, aOldQuery, NULL, bRecord, bApi );
+ }
+ }
+
+ ScQueryParam aLocalParam( rQueryParam ); // fuer Paint / Zielbereich
+ BOOL bCopy = !rQueryParam.bInplace; // kopiert wird in Table::Query
+ ScDBData* pDestData = NULL; // Bereich, in den kopiert wird
+ BOOL bDoSize = FALSE; // Zielgroesse anpassen (einf./loeschen)
+ SCCOL nFormulaCols = 0; // nur bei bDoSize
+ BOOL bKeepFmt = FALSE;
+ ScRange aOldDest;
+ ScRange aDestTotal;
+ if ( bCopy && rQueryParam.nDestCol == rQueryParam.nCol1 &&
+ rQueryParam.nDestRow == rQueryParam.nRow1 && rQueryParam.nDestTab == nTab )
+ bCopy = FALSE;
+ SCTAB nDestTab = nTab;
+ if ( bCopy )
+ {
+ aLocalParam.MoveToDest();
+ nDestTab = rQueryParam.nDestTab;
+ if ( !ValidColRow( aLocalParam.nCol2, aLocalParam.nRow2 ) )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PASTE_FULL);
+ return FALSE;
+ }
+
+ ScEditableTester aTester( pDoc, nDestTab, aLocalParam.nCol1,aLocalParam.nRow1,
+ aLocalParam.nCol2,aLocalParam.nRow2);
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ pDestData = pDoc->GetDBAtCursor( rQueryParam.nDestCol, rQueryParam.nDestRow,
+ rQueryParam.nDestTab, TRUE );
+ if (pDestData)
+ {
+ pDestData->GetArea( aOldDest );
+ aDestTotal=ScRange( rQueryParam.nDestCol,
+ rQueryParam.nDestRow,
+ nDestTab,
+ rQueryParam.nDestCol + rQueryParam.nCol2 - rQueryParam.nCol1,
+ rQueryParam.nDestRow + rQueryParam.nRow2 - rQueryParam.nRow1,
+ nDestTab );
+
+ bDoSize = pDestData->IsDoSize();
+ // Test, ob Formeln aufgefuellt werden muessen (nFormulaCols):
+ if ( bDoSize && aOldDest.aEnd.Col() == aDestTotal.aEnd.Col() )
+ {
+ SCCOL nTestCol = aOldDest.aEnd.Col() + 1; // neben dem Bereich
+ SCROW nTestRow = rQueryParam.nDestRow +
+ ( aLocalParam.bHasHeader ? 1 : 0 );
+ while ( nTestCol <= MAXCOL &&
+ pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
+ ++nTestCol, ++nFormulaCols;
+ }
+
+ bKeepFmt = pDestData->IsKeepFmt();
+ if ( bDoSize && !pDoc->CanFitBlock( aOldDest, aDestTotal ) )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2); // kann keine Zeilen einfuegen
+ return FALSE;
+ }
+ }
+ }
+
+ // ausfuehren
+
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ BOOL bKeepSub = FALSE; // bestehende Teilergebnisse wiederholen?
+ ScSubTotalParam aSubTotalParam;
+ if (rQueryParam.GetEntry(0).bDoQuery) // nicht beim Aufheben
+ {
+ pDBData->GetSubTotalParam( aSubTotalParam ); // Teilergebnisse vorhanden?
+
+ if ( aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly )
+ bKeepSub = TRUE;
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ ScDBCollection* pUndoDB = NULL;
+ const ScRange* pOld = NULL;
+
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ if (bCopy)
+ {
+ pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab, FALSE, TRUE );
+ pDoc->CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nDestTab,
+ IDF_ALL, FALSE, pUndoDoc );
+ // Attribute sichern, falls beim Filtern mitkopiert
+
+ if (pDestData)
+ {
+ pDoc->CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc );
+ pOld = &aOldDest;
+ }
+ }
+ else
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+ pDoc->CopyToDocument( 0, rQueryParam.nRow1, nTab, MAXCOL, rQueryParam.nRow2, nTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ }
+
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+
+ pDoc->BeginDrawUndo();
+ }
+
+ ScDocument* pAttribDoc = NULL;
+ ScRange aAttribRange;
+ if (pDestData) // Zielbereich loeschen
+ {
+ if ( bKeepFmt )
+ {
+ // kleinere der End-Spalten, Header+1 Zeile
+ aAttribRange = aOldDest;
+ if ( aAttribRange.aEnd.Col() > aDestTotal.aEnd.Col() )
+ aAttribRange.aEnd.SetCol( aDestTotal.aEnd.Col() );
+ aAttribRange.aEnd.SetRow( aAttribRange.aStart.Row() +
+ ( aLocalParam.bHasHeader ? 1 : 0 ) );
+
+ // auch fuer aufgefuellte Formeln
+ aAttribRange.aEnd.SetCol( aAttribRange.aEnd.Col() + nFormulaCols );
+
+ pAttribDoc = new ScDocument( SCDOCMODE_UNDO );
+ pAttribDoc->InitUndo( pDoc, nDestTab, nDestTab, FALSE, TRUE );
+ pDoc->CopyToDocument( aAttribRange, IDF_ATTRIB, FALSE, pAttribDoc );
+ }
+
+ if ( bDoSize )
+ pDoc->FitBlock( aOldDest, aDestTotal );
+ else
+ pDoc->DeleteAreaTab(aOldDest, IDF_ALL); // einfach loeschen
+ }
+
+ // Filtern am Dokument ausfuehren
+ SCSIZE nCount = pDoc->Query( nTab, rQueryParam, bKeepSub );
+ if (bCopy)
+ {
+ aLocalParam.nRow2 = aLocalParam.nRow1 + nCount;
+ if (!aLocalParam.bHasHeader && nCount > 0)
+ --aLocalParam.nRow2;
+
+ if ( bDoSize )
+ {
+ // auf wirklichen Ergebnis-Bereich anpassen
+ // (das hier ist immer eine Verkleinerung)
+
+ ScRange aNewDest( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nDestTab );
+ pDoc->FitBlock( aDestTotal, aNewDest, FALSE ); // FALSE - nicht loeschen
+
+ if ( nFormulaCols > 0 )
+ {
+ // Formeln ausfuellen
+ //! Undo (Query und Repeat) !!!
+
+ ScRange aNewForm( aLocalParam.nCol2+1, aLocalParam.nRow1, nDestTab,
+ aLocalParam.nCol2+nFormulaCols, aLocalParam.nRow2, nDestTab );
+ ScRange aOldForm = aNewForm;
+ aOldForm.aEnd.SetRow( aOldDest.aEnd.Row() );
+ pDoc->FitBlock( aOldForm, aNewForm, FALSE );
+
+ ScMarkData aMark;
+ aMark.SelectOneTable(nDestTab);
+ SCROW nFStartY = aLocalParam.nRow1 + ( aLocalParam.bHasHeader ? 1 : 0 );
+ pDoc->Fill( aLocalParam.nCol2+1, nFStartY,
+ aLocalParam.nCol2+nFormulaCols, nFStartY, aMark,
+ aLocalParam.nRow2 - nFStartY,
+ FILL_TO_BOTTOM, FILL_SIMPLE );
+ }
+ }
+
+ if ( pAttribDoc ) // gemerkte Attribute zurueckkopieren
+ {
+ // Header
+ if (aLocalParam.bHasHeader)
+ {
+ ScRange aHdrRange = aAttribRange;
+ aHdrRange.aEnd.SetRow( aHdrRange.aStart.Row() );
+ pAttribDoc->CopyToDocument( aHdrRange, IDF_ATTRIB, FALSE, pDoc );
+ }
+
+ // Daten
+ SCCOL nAttrEndCol = aAttribRange.aEnd.Col();
+ SCROW nAttrRow = aAttribRange.aStart.Row() + ( aLocalParam.bHasHeader ? 1 : 0 );
+ for (SCCOL nCol = aAttribRange.aStart.Col(); nCol<=nAttrEndCol; nCol++)
+ {
+ const ScPatternAttr* pSrcPattern = pAttribDoc->GetPattern(
+ nCol, nAttrRow, nDestTab );
+ DBG_ASSERT(pSrcPattern,"Pattern ist 0");
+ if (pSrcPattern)
+ pDoc->ApplyPatternAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2,
+ nDestTab, *pSrcPattern );
+ const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
+ if (pStyle)
+ pDoc->ApplyStyleAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2,
+ nDestTab, *pStyle );
+ }
+
+ delete pAttribDoc;
+ }
+ }
+
+ // speichern: Inplace immer, sonst je nach Einstellung
+ // alter Inplace-Filter ist ggf. schon aufgehoben
+
+ BOOL bSave = rQueryParam.bInplace || rQueryParam.bDestPers;
+ if (bSave) // merken
+ {
+ pDBData->SetQueryParam( rQueryParam );
+ pDBData->SetHeader( rQueryParam.bHasHeader ); //! ???
+ pDBData->SetAdvancedQuerySource( pAdvSource ); // after SetQueryParam
+ }
+
+ if (bCopy) // neuen DB-Bereich merken
+ {
+ // selektieren wird hinterher von aussen (dbfunc)
+ // momentan ueber DB-Bereich an der Zielposition, darum muss dort
+ // auf jeden Fall ein Bereich angelegt werden.
+
+ ScDBData* pNewData;
+ if (pDestData)
+ pNewData = pDestData; // Bereich vorhanden -> anpassen (immer!)
+ else // Bereich anlegen
+ pNewData = rDocShell.GetDBData(
+ ScRange( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
+ aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ),
+ SC_DB_MAKE, SC_DBSEL_FORCE_MARK );
+
+ if (pNewData)
+ {
+ pNewData->SetArea( nDestTab, aLocalParam.nCol1, aLocalParam.nRow1,
+ aLocalParam.nCol2, aLocalParam.nRow2 );
+
+ // Query-Param wird am Ziel nicht mehr eingestellt, fuehrt nur zu Verwirrung
+ // und Verwechslung mit dem Query-Param am Quellbereich (#37187#)
+ }
+ else
+ {
+ DBG_ERROR("Zielbereich nicht da");
+ }
+ }
+
+ if (!bCopy)
+ {
+ pDoc->InvalidatePageBreaks(nTab);
+ pDoc->UpdatePageBreaks( nTab );
+ }
+
+ // #i23299# because of Subtotal functions, the whole rows must be set dirty
+ ScRange aDirtyRange( 0 , aLocalParam.nRow1, nDestTab,
+ MAXCOL, aLocalParam.nRow2, nDestTab );
+ pDoc->SetDirty( aDirtyRange );
+
+ if ( bRecord )
+ {
+ // create undo action after executing, because of drawing layer undo
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoQuery( &rDocShell, nTab, rQueryParam, pUndoDoc, pUndoDB,
+ pOld, bDoSize, pAdvSource ) );
+ }
+
+
+ if (bCopy)
+ {
+ SCCOL nEndX = aLocalParam.nCol2;
+ SCROW nEndY = aLocalParam.nRow2;
+ if (pDestData)
+ {
+ if ( aOldDest.aEnd.Col() > nEndX )
+ nEndX = aOldDest.aEnd.Col();
+ if ( aOldDest.aEnd.Row() > nEndY )
+ nEndY = aOldDest.aEnd.Row();
+ }
+ if (bDoSize)
+ nEndY = MAXROW;
+ rDocShell.PostPaint( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
+ nEndX, nEndY, nDestTab, PAINT_GRID );
+ }
+ else
+ rDocShell.PostPaint( 0, rQueryParam.nRow1, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::DoSubTotals( SCTAB nTab, const ScSubTotalParam& rParam,
+ const ScSortParam* pForceNewSort, BOOL bRecord, BOOL bApi )
+{
+ //! auch fuer ScDBFunc::DoSubTotals benutzen!
+ // dann bleibt aussen:
+ // - neuen Bereich (aus DBData) markieren
+ // - SelectionChanged (?)
+
+ BOOL bDo = !rParam.bRemoveOnly; // FALSE = nur loeschen
+ BOOL bRet = FALSE;
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
+ rParam.nCol2, rParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "SubTotals: keine DBData" );
+ return FALSE;
+ }
+
+ ScEditableTester aTester( pDoc, nTab, 0,rParam.nRow1+1, MAXCOL,MAXROW );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ if (pDoc->HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab,
+ rParam.nCol2, rParam.nRow2, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0); // nicht in zusammengefasste einfuegen
+ return FALSE;
+ }
+
+ BOOL bOk = TRUE;
+ BOOL bDelete = FALSE;
+ if (rParam.bReplace)
+ if (pDoc->TestRemoveSubTotals( nTab, rParam ))
+ {
+ bDelete = TRUE;
+ bOk = ( MessBox( rDocShell.GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ // "StarCalc" "Daten loeschen?"
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_1 ) ).Execute()
+ == RET_YES );
+ }
+
+ if (bOk)
+ {
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScSubTotalParam aNewParam( rParam ); // Bereichsende wird veraendert
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ ScRangeName* pUndoRange = NULL;
+ ScDBCollection* pUndoDB = NULL;
+ SCTAB nTabCount = 0; // fuer Referenz-Undo
+
+ if (bRecord) // alte Daten sichern
+ {
+ BOOL bOldFilter = bDo && rParam.bDoSort;
+
+ nTabCount = pDoc->GetTableCount();
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ // column/row state
+ SCCOLROW nOutStartCol, nOutEndCol;
+ SCCOLROW nOutStartRow, nOutEndRow;
+ pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
+ pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, bOldFilter );
+
+ // Datenbereich sichern - incl. Filter-Ergebnis
+ pDoc->CopyToDocument( 0,rParam.nRow1+1,nTab, MAXCOL,rParam.nRow2,nTab,
+ IDF_ALL, FALSE, pUndoDoc );
+
+ // alle Formeln wegen Referenzen
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
+ IDF_FORMULA, FALSE, pUndoDoc );
+
+ // DB- und andere Bereiche
+ ScRangeName* pDocRange = pDoc->GetRangeName();
+ if (pDocRange->GetCount())
+ pUndoRange = new ScRangeName( *pDocRange );
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+ }
+
+// pDoc->SetOutlineTable( nTab, NULL );
+ ScOutlineTable* pOut = pDoc->GetOutlineTable( nTab );
+ if (pOut)
+ pOut->GetRowArray()->RemoveAll(); // nur Zeilen-Outlines loeschen
+
+ if (rParam.bReplace)
+ pDoc->RemoveSubTotals( nTab, aNewParam );
+ BOOL bSuccess = TRUE;
+ if (bDo)
+ {
+ // Sortieren
+ if ( rParam.bDoSort || pForceNewSort )
+ {
+ pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+
+ // Teilergebnis-Felder vor die Sortierung setzen
+ // (doppelte werden weggelassen, kann darum auch wieder aufgerufen werden)
+
+ ScSortParam aOldSort;
+ pDBData->GetSortParam( aOldSort );
+ ScSortParam aSortParam( aNewParam, pForceNewSort ? *pForceNewSort : aOldSort );
+ Sort( nTab, aSortParam, FALSE, FALSE, bApi );
+ }
+
+ bSuccess = pDoc->DoSubTotals( nTab, aNewParam );
+ }
+ ScRange aDirtyRange( aNewParam.nCol1, aNewParam.nRow1, nTab,
+ aNewParam.nCol2, aNewParam.nRow2, nTab );
+ pDoc->SetDirty( aDirtyRange );
+
+ if (bRecord)
+ {
+// ScDBData* pUndoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoSubTotals( &rDocShell, nTab,
+ rParam, aNewParam.nRow2,
+ pUndoDoc, pUndoTab, // pUndoDBData,
+ pUndoRange, pUndoDB ) );
+ }
+
+ if (!bSuccess)
+ {
+ // "Kann keine Zeilen einfuegen"
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2);
+ }
+
+ // merken
+ pDBData->SetSubTotalParam( aNewParam );
+ pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+ pDoc->CompileDBFormula();
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+ aModificator.SetDocumentModified();
+
+ bRet = bSuccess;
+ }
+ return bRet;
+}
+
+//==================================================================
+
+BOOL lcl_EmptyExcept( ScDocument* pDoc, const ScRange& rRange, const ScRange& rExcept )
+{
+ ScCellIterator aIter( pDoc, rRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if ( !pCell->IsBlank() ) // real content?
+ {
+ if ( !rExcept.In( ScAddress( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ) ) )
+ return FALSE; // cell found
+ }
+ pCell = aIter.GetNext();
+ }
+
+ return TRUE; // nothing found - empty
+}
+
+BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj,
+ BOOL bRecord, BOOL bApi, BOOL bAllowMove )
+{
+ ScDocShellModificator aModificator( rDocShell );
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ BOOL bDone = FALSE;
+ BOOL bUndoSelf = FALSE;
+ USHORT nErrId = 0;
+
+ ScDocument* pOldUndoDoc = NULL;
+ ScDocument* pNewUndoDoc = NULL;
+ ScDPObject* pUndoDPObj = NULL;
+ if ( bRecord && pOldObj )
+ pUndoDPObj = new ScDPObject( *pOldObj ); // copy old settings for undo
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ if ( !rDocShell.IsEditable() || pDoc->GetChangeTrack() )
+ {
+ // not recorded -> disallow
+ //! different error messages?
+
+ nErrId = STR_PROTECTIONERR;
+ }
+ if ( pOldObj && !nErrId )
+ {
+ ScRange aOldOut = pOldObj->GetOutRange();
+ ScEditableTester aTester( pDoc, aOldOut );
+ if ( !aTester.IsEditable() )
+ nErrId = aTester.GetMessageId();
+ }
+ if ( pNewObj && !nErrId )
+ {
+ // at least one cell at the output position must be editable
+ // -> check in advance
+ // (start of output range in pNewObj is valid)
+
+ ScRange aNewStart( pNewObj->GetOutRange().aStart );
+ ScEditableTester aTester( pDoc, aNewStart );
+ if ( !aTester.IsEditable() )
+ nErrId = aTester.GetMessageId();
+ }
+
+ ScDPObject* pDestObj = NULL;
+ if ( !nErrId )
+ {
+ if ( pOldObj && !pNewObj )
+ {
+ // delete table
+
+ ScRange aRange = pOldObj->GetOutRange();
+ SCTAB nTab = aRange.aStart.Tab();
+
+ if ( bRecord )
+ {
+ pOldUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pOldUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pOldUndoDoc );
+ }
+
+ pDoc->DeleteAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ nTab, IDF_ALL );
+ pDoc->RemoveFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ nTab, SC_MF_AUTO );
+
+ pDoc->GetDPCollection()->FreeTable( pOldObj ); // object is deleted here
+
+ rDocShell.PostPaintGridAll(); //! only necessary parts
+ rDocShell.PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), nTab,
+ aRange.aEnd.Col(), aRange.aEnd.Row(), nTab,
+ PAINT_GRID );
+ bDone = TRUE;
+ }
+ else if ( pNewObj )
+ {
+ if ( pOldObj )
+ {
+ if ( bRecord )
+ {
+ ScRange aRange = pOldObj->GetOutRange();
+ SCTAB nTab = aRange.aStart.Tab();
+ pOldUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pOldUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pOldUndoDoc );
+ }
+
+ if ( pNewObj == pOldObj )
+ {
+ // refresh only - no settings modified
+ }
+ else
+ {
+ pNewObj->WriteSourceDataTo( *pOldObj ); // copy source data
+
+ ScDPSaveData* pData = pNewObj->GetSaveData();
+ DBG_ASSERT( pData, "no SaveData from living DPObject" );
+ if ( pData )
+ pOldObj->SetSaveData( *pData ); // copy SaveData
+ }
+
+ pDestObj = pOldObj;
+ pDestObj->SetAllowMove( bAllowMove );
+ }
+ else
+ {
+ // output range must be set at pNewObj
+
+ pDestObj = new ScDPObject( *pNewObj );
+
+ // #i94570# When changing the output position in the dialog, a new table is created
+ // with the settings from the old table, including the name.
+ // So we have to check for duplicate names here (before inserting).
+ if ( pDoc->GetDPCollection()->GetByName(pDestObj->GetName()) )
+ pDestObj->SetName( String() ); // ignore the invalid name, create a new name below
+
+ pDestObj->SetAlive(TRUE);
+ if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
+ {
+ DBG_ERROR("cannot insert DPObject");
+ DELETEZ( pDestObj );
+ }
+ }
+ if ( pDestObj )
+ {
+ // #78541# create new database connection for "refresh"
+ // (and re-read column entry collections)
+ // so all changes take effect
+ if ( pNewObj == pOldObj && pDestObj->IsImportData() )
+ pDestObj->InvalidateSource();
+
+ pDestObj->InvalidateData(); // before getting the new output area
+
+ // make sure the table has a name (not set by dialog)
+ if ( !pDestObj->GetName().Len() )
+ pDestObj->SetName( pDoc->GetDPCollection()->CreateNewName() );
+
+ 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
+ DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" );
+ bUndoSelf = TRUE;
+ nErrId = STR_PIVOT_ERROR;
+ }
+ else
+ {
+ ScEditableTester aTester( pDoc, aNewOut );
+ if ( !aTester.IsEditable() )
+ {
+ // destination area isn't editable
+ //! reverse everything done so far, don't proceed
+
+ // quick solution: proceed to end, use undo action
+ // to reverse everything:
+ DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" );
+ bUndoSelf = TRUE;
+ nErrId = aTester.GetMessageId();
+ }
+ }
+
+ // test if new output area is empty except for old area
+ if ( !bApi )
+ {
+ BOOL bEmpty;
+ if ( pOldObj ) // OutRange of pOldObj (pDestObj) is still old area
+ bEmpty = lcl_EmptyExcept( pDoc, aNewOut, pOldObj->GetOutRange() );
+ else
+ bEmpty = pDoc->IsBlockEmpty( aNewOut.aStart.Tab(),
+ aNewOut.aStart.Col(), aNewOut.aStart.Row(),
+ aNewOut.aEnd.Col(), aNewOut.aEnd.Row() );
+
+ if ( !bEmpty )
+ {
+ QueryBox aBox( rDocShell.GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_PIVOT_NOTEMPTY) );
+ if (aBox.Execute() == RET_NO)
+ {
+ //! like above (not editable), use undo to reverse everything
+ DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" );
+ bUndoSelf = TRUE;
+ }
+ }
+ }
+
+ if ( bRecord )
+ {
+ SCTAB nTab = aNewOut.aStart.Tab();
+ pNewUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pNewUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( aNewOut, IDF_ALL, FALSE, pNewUndoDoc );
+ }
+
+ pDestObj->Output( aNewOut.aStart );
+
+ rDocShell.PostPaintGridAll(); //! only necessary parts
+ bDone = TRUE;
+ }
+ }
+ // else nothing (no old, no new)
+ }
+
+ if ( bRecord && bDone )
+ {
+ SfxUndoAction* pAction = new ScUndoDataPilot( &rDocShell,
+ pOldUndoDoc, pNewUndoDoc, pUndoDPObj, pDestObj, bAllowMove );
+ pOldUndoDoc = NULL;
+ pNewUndoDoc = NULL; // pointers are used in undo action
+ // pUndoDPObj is copied
+
+ if (bUndoSelf)
+ {
+ // use undo action to restore original state
+ //! prevent setting the document modified? (ScDocShellModificator)
+
+ pAction->Undo();
+ delete pAction;
+ bDone = FALSE;
+ }
+ else
+ rDocShell.GetUndoManager()->AddUndoAction( pAction );
+ }
+
+ delete pOldUndoDoc; // if not used for undo
+ delete pNewUndoDoc;
+ delete pUndoDPObj;
+
+ if (bDone)
+ {
+ // notify API objects
+ if (pDestObj)
+ pDoc->BroadcastUno( ScDataPilotModifiedHint( pDestObj->GetName() ) );
+ aModificator.SetDocumentModified();
+ }
+
+ if ( nErrId && !bApi )
+ rDocShell.ErrorMessage( nErrId );
+
+ return bDone;
+}
+
+//==================================================================
+//
+// Datenbank-Import...
+
+void ScDBDocFunc::UpdateImport( const String& rTarget, const String& rDBName,
+ const String& rTableName, const String& rStatement, BOOL bNative,
+ BYTE nType, const ::com::sun::star::uno::Reference<
+ ::com::sun::star::sdbc::XResultSet >& xResultSet,
+ const SbaSelectionList* pSelection )
+{
+ // Target ist jetzt einfach der Bereichsname
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScDBCollection& rDBColl = *pDoc->GetDBCollection();
+ ScDBData* pData = NULL;
+ ScImportParam aImportParam;
+ BOOL bFound = FALSE;
+ USHORT nCount = rDBColl.GetCount();
+ for (USHORT i=0; i<nCount && !bFound; i++)
+ {
+ pData = rDBColl[i];
+ if (pData->GetName() == rTarget)
+ bFound = TRUE;
+ }
+ if (!bFound)
+ {
+ InfoBox aInfoBox(rDocShell.GetActiveDialogParent(),
+ ScGlobal::GetRscString( STR_TARGETNOTFOUND ) );
+ aInfoBox.Execute();
+ return;
+ }
+
+ SCTAB nTab;
+ SCCOL nDummyCol;
+ SCROW nDummyRow;
+ pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow );
+ pData->GetImportParam( aImportParam );
+
+ BOOL bSql = ( rStatement.Len() != 0 );
+
+ aImportParam.aDBName = rDBName;
+ aImportParam.bSql = bSql;
+ aImportParam.aStatement = bSql ? rStatement : rTableName;
+ aImportParam.bNative = bNative;
+ aImportParam.nType = nType;
+ aImportParam.bImport = TRUE;
+ BOOL bContinue = DoImport( nTab, aImportParam, xResultSet, pSelection, TRUE );
+
+ // DB-Operationen wiederholen
+
+ ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
+ if (pViewSh)
+ {
+ ScRange aRange;
+ pData->GetArea(aRange);
+ pViewSh->MarkRange(aRange); // selektieren
+
+ if ( bContinue ) // #41905# Fehler beim Import -> Abbruch
+ {
+ // interne Operationen, wenn welche gespeichert
+
+ if ( pData->HasQueryParam() || pData->HasSortParam() || pData->HasSubTotalParam() )
+ pViewSh->RepeatDB();
+
+ // Pivottabellen die den Bereich als Quelldaten haben
+
+ rDocShell.RefreshPivotTables(aRange);
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/dbdocimp.cxx b/sc/source/ui/docshell/dbdocimp.cxx
new file mode 100644
index 000000000000..a073e50d105c
--- /dev/null
+++ b/sc/source/ui/docshell/dbdocimp.cxx
@@ -0,0 +1,720 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <comphelper/processfactory.hxx>
+#include <comphelper/types.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/debug.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/XCompletedExecution.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+
+
+#include "dbdocfun.hxx"
+#include "docsh.hxx"
+#include "globstr.hrc"
+#include "scerrors.hxx"
+#include "dbcolect.hxx"
+#include "markdata.hxx"
+#include "undodat.hxx"
+#include "progress.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "dbdocutl.hxx"
+#include "editable.hxx"
+#include "hints.hxx"
+
+using namespace com::sun::star;
+
+#define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
+#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler"
+
+//! move to a header file?
+#define SC_DBPROP_DATASOURCENAME "DataSourceName"
+#define SC_DBPROP_COMMAND "Command"
+#define SC_DBPROP_COMMANDTYPE "CommandType"
+#define SC_DBPROP_SELECTION "Selection"
+#define SC_DBPROP_CURSOR "Cursor"
+
+// static
+void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFrame )
+{
+ // called after opening the database beamer
+
+ if ( !pFrame || !rParam.bImport )
+ return;
+
+ uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface();
+ uno::Reference<frame::XDispatchProvider> xDP(xFrame, uno::UNO_QUERY);
+
+ uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame(
+ rtl::OUString::createFromAscii("_beamer"),
+ frame::FrameSearchFlag::CHILDREN);
+ if (xBeamerFrame.is())
+ {
+ uno::Reference<frame::XController> xController = xBeamerFrame->getController();
+ uno::Reference<view::XSelectionSupplier> xControllerSelection(xController, uno::UNO_QUERY);
+ if (xControllerSelection.is())
+ {
+ sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
+ ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
+ sdb::CommandType::TABLE );
+
+ ::svx::ODataAccessDescriptor aSelection;
+ aSelection.setDataSource(rtl::OUString( rParam.aDBName ));
+ aSelection[svx::daCommand] <<= rtl::OUString( rParam.aStatement );
+ aSelection[svx::daCommandType] <<= nType;
+
+ xControllerSelection->select(uno::makeAny(aSelection.createPropertyValueSequence()));
+ }
+ else
+ {
+ DBG_ERROR("no selection supplier in the beamer!");
+ }
+ }
+}
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::DoImportUno( const ScAddress& rPos,
+ const uno::Sequence<beans::PropertyValue>& aArgs )
+{
+ BOOL bDone = FALSE;
+
+ ScImportParam aImParam;
+ aImParam.nCol1 = aImParam.nCol2 = rPos.Col();
+ aImParam.nRow1 = aImParam.nRow2 = rPos.Row();
+ aImParam.bImport = TRUE;
+
+ uno::Reference<sdbc::XResultSet> xResSet;
+ uno::Sequence<uno::Any> aSelection;
+
+ rtl::OUString aStrVal;
+ const beans::PropertyValue* pPropArray = aArgs.getConstArray();
+ long nPropCount = aArgs.getLength();
+ long i;
+ for (i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName = rProp.Name;
+
+ if ( aPropName.EqualsAscii( SC_DBPROP_DATASOURCENAME ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aImParam.aDBName = aStrVal;
+ }
+ else if ( aPropName.EqualsAscii( SC_DBPROP_COMMAND ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aImParam.aStatement = aStrVal;
+ }
+ else if ( aPropName.EqualsAscii( SC_DBPROP_COMMANDTYPE ))
+ {
+ sal_Int32 nType = 0;
+ if ( rProp.Value >>= nType )
+ {
+ aImParam.bSql = ( nType == sdb::CommandType::COMMAND );
+ aImParam.nType = sal::static_int_cast<BYTE>( ( nType == sdb::CommandType::QUERY ) ? ScDbQuery : ScDbTable );
+ // nType is ignored if bSql is set
+ }
+ }
+ else if ( aPropName.EqualsAscii( SC_DBPROP_SELECTION ))
+ {
+ rProp.Value >>= aSelection;
+ }
+ else if ( aPropName.EqualsAscii( SC_DBPROP_CURSOR ))
+ {
+ rProp.Value >>= xResSet;
+ }
+ }
+
+ SbaSelectionList aList;
+ long nSelLen = aSelection.getLength();
+ for (i = 0; i < nSelLen; i++)
+ {
+ sal_Int32 nEntry = 0;
+ if ( aSelection[i] >>= nEntry )
+ aList.Insert( (void*)nEntry, LIST_APPEND );
+ }
+
+ BOOL bAddrInsert = FALSE; //!???
+ if ( bAddrInsert )
+ {
+ bDone = DoImport( rPos.Tab(), aImParam, xResSet, &aList, TRUE, bAddrInsert );
+ }
+ else
+ {
+ // create database range
+ //! merge this with SID_SBA_IMPORT execute in docsh4.cxx
+
+ ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, SC_DBSEL_KEEP );
+ DBG_ASSERT(pDBData, "can't create DB data");
+ String sTarget = pDBData->GetName();
+
+ //! change UpdateImport to use only one of rTableName, rStatement
+
+ String aTableName, aStatement;
+ if ( aImParam.bSql )
+ aStatement = aImParam.aStatement;
+ else
+ aTableName = aImParam.aStatement;
+
+ UpdateImport( sTarget, aImParam.aDBName, aTableName, aStatement,
+ aImParam.bNative, aImParam.nType, xResSet, &aList );
+ bDone = TRUE;
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------
+
+BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+ const uno::Reference< sdbc::XResultSet >& xResultSet,
+ const SbaSelectionList* pSelection, BOOL bRecord, BOOL bAddrInsert )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDBData* pDBData = 0;
+ if ( !bAddrInsert )
+ {
+ pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
+ rParam.nCol2, rParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "DoImport: no DBData" );
+ return FALSE;
+ }
+ }
+
+ Window* pWaitWin = rDocShell.GetActiveDialogParent();
+ if (pWaitWin)
+ pWaitWin->EnterWait();
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ BOOL bApi = FALSE; //! pass as argument
+ BOOL bTruncated = FALSE; // for warning
+ USHORT nErrStringId = 0;
+ String aErrorMessage;
+
+ SCCOL nCol = rParam.nCol1;
+ SCROW nRow = rParam.nRow1;
+ SCCOL nEndCol = nCol; // end of resulting database area
+ SCROW nEndRow = nRow;
+ long i;
+
+ BOOL bDoSelection = FALSE;
+ BOOL bRealSelection = FALSE; // TRUE if not everything is selected
+ ULONG nListPos = 0;
+ ULONG nRowsRead = 0;
+ ULONG nListCount = 0;
+
+ // -1 is special
+ if ( pSelection && pSelection->Count() && (long)pSelection->GetObject(0) != -1L )
+ {
+ bDoSelection = TRUE;
+ nListCount = pSelection->Count();
+ }
+
+ // ImportDoc - also used for Redo
+ ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
+ pImportDoc->InitUndo( pDoc, nTab, nTab );
+ ScColumn::bDoubleAlloc = TRUE;
+
+ //
+ // get data from database into import document
+ //
+
+ try
+ {
+ // progress bar
+ // only text (title is still needed, for the cancel button)
+ ScProgress aProgress( &rDocShell, ScGlobal::GetRscString(STR_UNDO_IMPORTDATA), 0 );
+ USHORT nInserted = 0;
+
+ uno::Reference<sdbc::XRowSet> xRowSet = uno::Reference<sdbc::XRowSet>(
+ xResultSet, uno::UNO_QUERY );
+ sal_Bool bDispose = sal_False;
+ if ( !xRowSet.is() )
+ {
+ bDispose = sal_True;
+ xRowSet = uno::Reference<sdbc::XRowSet>(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
+ if ( xRowProp.is() )
+ {
+ //
+ // set source parameters
+ //
+
+ sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
+ ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
+ sdb::CommandType::TABLE );
+ uno::Any aAny;
+
+ aAny <<= rtl::OUString( rParam.aDBName );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny );
+
+ aAny <<= rtl::OUString( rParam.aStatement );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
+
+ aAny <<= nType;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
+
+ uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
+ if ( xExecute.is() )
+ {
+ uno::Reference<task::XInteractionHandler> xHandler(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
+ uno::UNO_QUERY);
+ xExecute->executeWithCompletion( xHandler );
+ }
+ else
+ xRowSet->execute();
+ }
+ }
+ if ( xRowSet.is() )
+ {
+ //
+ // get column descriptions
+ //
+
+ long nColCount = 0;
+ uno::Reference<sdbc::XResultSetMetaData> xMeta;
+ uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
+ if ( xMetaSupp.is() )
+ xMeta = xMetaSupp->getMetaData();
+ if ( xMeta.is() )
+ nColCount = xMeta->getColumnCount(); // this is the number of real columns
+
+ if ( rParam.nCol1 + nColCount - 1 > MAXCOL )
+ {
+ nColCount = 0;
+ //! error message
+ }
+
+ uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
+ if ( nColCount > 0 && xRow.is() )
+ {
+ nEndCol = (SCCOL)( rParam.nCol1 + nColCount - 1 );
+
+ uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types
+ uno::Sequence<sal_Bool> aColCurr( nColCount ); // currency flag is not in types
+ sal_Int32* pTypeArr = aColTypes.getArray();
+ sal_Bool* pCurrArr = aColCurr.getArray();
+ for (i=0; i<nColCount; i++)
+ {
+ pTypeArr[i] = xMeta->getColumnType( i+1 );
+ pCurrArr[i] = xMeta->isCurrency( i+1 );
+ }
+
+ if ( !bAddrInsert ) // read column names
+ {
+ nCol = rParam.nCol1;
+ for (i=0; i<nColCount; i++)
+ {
+ pImportDoc->SetString( nCol, nRow, nTab,
+ xMeta->getColumnLabel( i+1 ) );
+ ++nCol;
+ }
+ ++nRow;
+ }
+
+ BOOL bEnd = FALSE;
+ if ( !bDoSelection )
+ xRowSet->beforeFirst();
+ while ( !bEnd )
+ {
+ // skip rows that are not selected
+ if ( !bDoSelection )
+ {
+ if ( (bEnd = !xRowSet->next()) == FALSE )
+ ++nRowsRead;
+ }
+ else
+ {
+ if (nListPos < nListCount)
+ {
+ ULONG nNextRow = (ULONG) pSelection->GetObject(nListPos);
+ if ( nRowsRead+1 < nNextRow )
+ bRealSelection = TRUE;
+ bEnd = !xRowSet->absolute(nRowsRead = nNextRow);
+ ++nListPos;
+ }
+ else
+ {
+ bRealSelection = xRowSet->next();
+ bEnd = TRUE; // more data available but not used
+ }
+ }
+
+ if ( !bEnd )
+ {
+ if ( ValidRow(nRow) )
+ {
+ nCol = rParam.nCol1;
+ for (i=0; i<nColCount; i++)
+ {
+ ScDatabaseDocUtil::PutData( pImportDoc, nCol, nRow, nTab,
+ xRow, i+1, pTypeArr[i], pCurrArr[i] );
+ ++nCol;
+ }
+ nEndRow = nRow;
+ ++nRow;
+
+ // progress bar
+
+ ++nInserted;
+ if (!(nInserted & 15))
+ {
+ String aPict = ScGlobal::GetRscString( STR_PROGRESS_IMPORT );
+ String aText = aPict.GetToken(0,'#');
+ aText += String::CreateFromInt32( nInserted );
+ aText += aPict.GetToken(1,'#');
+
+ if (!aProgress.SetStateText( 0, aText )) // stopped by user?
+ {
+ bEnd = TRUE;
+ bSuccess = FALSE;
+ nErrStringId = STR_DATABASE_ABORTED;
+ }
+ }
+ }
+ else // past the end of the spreadsheet
+ {
+ bEnd = TRUE; // don't continue
+ bTruncated = TRUE; // warning flag
+ }
+ }
+ }
+
+ bSuccess = TRUE;
+ }
+
+ if ( bDispose )
+ ::comphelper::disposeComponent( xRowSet );
+ }
+ }
+ catch ( sdbc::SQLException& rError )
+ {
+ aErrorMessage = rError.Message;
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in database");
+ }
+
+ ScColumn::bDoubleAlloc = FALSE;
+ pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 );
+
+ //
+ // test for cell protection
+ //
+
+ BOOL bKeepFormat = !bAddrInsert && pDBData->IsKeepFmt();
+ BOOL bMoveCells = !bAddrInsert && pDBData->IsDoSize();
+ SCCOL nFormulaCols = 0; // columns to be filled with formulas
+ if (bMoveCells && nEndCol == rParam.nCol2)
+ {
+ // if column count changes, formulas would become invalid anyway
+ // -> only set nFormulaCols for unchanged column count
+
+ SCCOL nTestCol = rParam.nCol2 + 1; // right of the data
+ SCROW nTestRow = rParam.nRow1 + 1; // below the title row
+ while ( nTestCol <= MAXCOL &&
+ pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
+ ++nTestCol, ++nFormulaCols;
+ }
+
+ if (bSuccess)
+ {
+ // old and new range editable?
+ ScEditableTester aTester;
+ aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,rParam.nCol2,rParam.nRow2 );
+ aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,nEndCol,nEndRow );
+ if ( !aTester.IsEditable() )
+ {
+ nErrStringId = aTester.GetMessageId();
+ bSuccess = FALSE;
+ }
+ else if ( pDoc->GetChangeTrack() != NULL )
+ {
+ nErrStringId = STR_PROTECTIONERR;
+ bSuccess = FALSE;
+ }
+ }
+
+ if ( bSuccess && bMoveCells )
+ {
+ ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
+ rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
+ ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
+ nEndCol+nFormulaCols, nEndRow, nTab );
+ if (!pDoc->CanFitBlock( aOld, aNew ))
+ {
+ nErrStringId = STR_MSSG_DOSUBTOTALS_2; // can't insert cells
+ bSuccess = FALSE;
+ }
+ }
+
+ //
+ // copy data from import doc into real document
+ //
+
+ if ( bSuccess )
+ {
+ if (bKeepFormat)
+ {
+ // keep formatting of title and first data row from the document
+ // CopyToDocument also copies styles, Apply... needs separate calls
+
+ SCCOL nMinEndCol = Min( rParam.nCol2, nEndCol ); // not too much
+ nMinEndCol = sal::static_int_cast<SCCOL>( nMinEndCol + nFormulaCols ); // only if column count unchanged
+ pImportDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, nTab, IDF_ATTRIB );
+ pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
+ nMinEndCol, rParam.nRow1, nTab,
+ IDF_ATTRIB, FALSE, pImportDoc );
+
+ SCROW nDataStartRow = rParam.nRow1+1;
+ for (SCCOL nCopyCol=rParam.nCol1; nCopyCol<=nMinEndCol; nCopyCol++)
+ {
+ const ScPatternAttr* pSrcPattern = pDoc->GetPattern(
+ nCopyCol, nDataStartRow, nTab );
+ pImportDoc->ApplyPatternAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
+ nTab, *pSrcPattern );
+ const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
+ if (pStyle)
+ pImportDoc->ApplyStyleAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
+ nTab, *pStyle );
+ }
+ }
+
+ // don't set cell protection attribute if table is protected
+ if (pDoc->IsTabProtected(nTab))
+ {
+ ScPatternAttr aPattern(pImportDoc->GetPool());
+ aPattern.GetItemSet().Put( ScProtectionAttr( FALSE,FALSE,FALSE,FALSE ) );
+ pImportDoc->ApplyPatternAreaTab( 0,0,MAXCOL,MAXROW, nTab, aPattern );
+ }
+
+ //
+ // copy old data for undo
+ //
+
+ SCCOL nUndoEndCol = Max( nEndCol, rParam.nCol2 ); // rParam = old end
+ SCROW nUndoEndRow = Max( nEndRow, rParam.nRow2 );
+
+ ScDocument* pUndoDoc = NULL;
+ ScDBData* pUndoDBData = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( !bAddrInsert )
+ pUndoDBData = new ScDBData( *pDBData );
+ }
+
+ ScMarkData aNewMark;
+ aNewMark.SelectOneTable( nTab );
+
+ if (bRecord)
+ {
+ // do not touch notes (ScUndoImportData does not support drawing undo)
+ sal_uInt16 nCopyFlags = IDF_ALL & ~IDF_NOTE;
+
+ // nFormulaCols is set only if column count is unchanged
+ pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
+ nEndCol+nFormulaCols, nEndRow, nTab,
+ nCopyFlags, FALSE, pUndoDoc );
+ if ( rParam.nCol2 > nEndCol )
+ pDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab,
+ nUndoEndCol, nUndoEndRow, nTab,
+ nCopyFlags, FALSE, pUndoDoc );
+ if ( rParam.nRow2 > nEndRow )
+ pDoc->CopyToDocument( rParam.nCol1, nEndRow+1, nTab,
+ nUndoEndCol+nFormulaCols, nUndoEndRow, nTab,
+ nCopyFlags, FALSE, pUndoDoc );
+ }
+
+ //
+ // move new data
+ //
+
+ if (bMoveCells)
+ {
+ // clear only the range without the formulas,
+ // so the formula title and first row are preserved
+
+ ScRange aDelRange( rParam.nCol1, rParam.nRow1, nTab,
+ rParam.nCol2, rParam.nRow2, nTab );
+ pDoc->DeleteAreaTab( aDelRange, IDF_ALL & ~IDF_NOTE ); // ohne die Formeln
+
+ ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
+ rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
+ ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
+ nEndCol+nFormulaCols, nEndRow, nTab );
+ pDoc->FitBlock( aOld, aNew, FALSE ); // Formeln nicht loeschen
+ }
+ else if ( nEndCol < rParam.nCol2 ) // DeleteArea calls PutInOrder
+ pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
+ aNewMark, IDF_CONTENTS & ~IDF_NOTE );
+
+ // CopyToDocument doesn't remove contents
+ pDoc->DeleteAreaTab( rParam.nCol1, rParam.nRow1, nEndCol, nEndRow, nTab, IDF_CONTENTS & ~IDF_NOTE );
+
+ // #41216# remove each column from ImportDoc after copying to reduce memory usage
+ BOOL bOldAutoCalc = pDoc->GetAutoCalc();
+ pDoc->SetAutoCalc( FALSE ); // outside of the loop
+ for (SCCOL nCopyCol = rParam.nCol1; nCopyCol <= nEndCol; nCopyCol++)
+ {
+ pImportDoc->CopyToDocument( nCopyCol, rParam.nRow1, nTab, nCopyCol, nEndRow, nTab,
+ IDF_ALL, FALSE, pDoc );
+ pImportDoc->DeleteAreaTab( nCopyCol, rParam.nRow1, nCopyCol, nEndRow, nTab, IDF_CONTENTS );
+ pImportDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 );
+ }
+ pDoc->SetAutoCalc( bOldAutoCalc );
+
+ if (nFormulaCols > 0) // copy formulas
+ {
+ if (bKeepFormat) // formats for formulas
+ pImportDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab,
+ nEndCol+nFormulaCols, nEndRow, nTab,
+ IDF_ATTRIB, FALSE, pDoc );
+ // fill formulas
+ ScMarkData aMark;
+ aMark.SelectOneTable(nTab);
+ pDoc->Fill( nEndCol+1, rParam.nRow1+1, nEndCol+nFormulaCols, rParam.nRow1+1,
+ aMark, nEndRow-rParam.nRow1-1, FILL_TO_BOTTOM, FILL_SIMPLE );
+ }
+
+ // if new range is smaller, clear old contents
+
+ if (!bMoveCells) // move has happened above
+ {
+ if ( rParam.nCol2 > nEndCol )
+ pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
+ aNewMark, IDF_CONTENTS );
+ if ( rParam.nRow2 > nEndRow )
+ pDoc->DeleteArea( rParam.nCol1, nEndRow+1, rParam.nCol2, rParam.nRow2,
+ aNewMark, IDF_CONTENTS );
+ }
+
+ if( !bAddrInsert ) // update database range
+ {
+ pDBData->SetImportParam( rParam );
+ pDBData->SetHeader( TRUE );
+ pDBData->SetByRow( TRUE );
+ pDBData->SetArea( nTab, rParam.nCol1,rParam.nRow1, nEndCol,nEndRow );
+ pDBData->SetImportSelection( bRealSelection );
+ pDoc->CompileDBFormula();
+ }
+
+ if (bRecord)
+ {
+ ScDocument* pRedoDoc = pImportDoc;
+ pImportDoc = NULL;
+
+ if (nFormulaCols > 0) // include filled formulas for redo
+ pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
+ nEndCol+nFormulaCols, nEndRow, nTab,
+ IDF_ALL & ~IDF_NOTE, FALSE, pRedoDoc );
+
+ ScDBData* pRedoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoImportData( &rDocShell, nTab,
+ rParam, nUndoEndCol, nUndoEndRow,
+ nFormulaCols,
+ pUndoDoc, pRedoDoc, pUndoDBData, pRedoDBData ) );
+ }
+
+ pDoc->SetDirty();
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+ aModificator.SetDocumentModified();
+
+ ScDBRangeRefreshedHint aHint( rParam );
+ pDoc->BroadcastUno( aHint );
+
+ if (pWaitWin)
+ pWaitWin->LeaveWait();
+
+ if ( bTruncated && !bApi ) // show warning
+ ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW);
+ }
+ else if ( !bApi )
+ {
+ if (pWaitWin)
+ pWaitWin->LeaveWait();
+
+ if (!aErrorMessage.Len())
+ {
+ if (!nErrStringId)
+ nErrStringId = STR_MSSG_IMPORTDATA_0;
+ aErrorMessage = ScGlobal::GetRscString( nErrStringId );
+ }
+ InfoBox aInfoBox( rDocShell.GetActiveDialogParent(), aErrorMessage );
+ aInfoBox.Execute();
+ }
+
+ delete pImportDoc;
+
+ return bSuccess;
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
new file mode 100644
index 000000000000..36b6641d94a6
--- /dev/null
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -0,0 +1,4881 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <editeng/editobj.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svx/svdundo.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/printer.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/waitobj.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/PasswordHelper.hxx>
+
+#include <basic/sbstar.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+
+#include <list>
+
+#include "docfunc.hxx"
+
+#include "sc.hrc"
+
+#include "arealink.hxx"
+#include "attrib.hxx"
+#include "dociter.hxx"
+#include "autoform.hxx"
+#include "cell.hxx"
+#include "detdata.hxx"
+#include "detfunc.hxx"
+#include "docpool.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "editutil.hxx"
+#include "globstr.hrc"
+//CHINA001 #include "namecrea.hxx" // NAME_TOP etc.
+#include "olinetab.hxx"
+#include "patattr.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "refundo.hxx"
+#include "scresid.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "tablink.hxx"
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "undoblk.hxx"
+#include "undocell.hxx"
+#include "undodraw.hxx"
+#include "undotab.hxx"
+#include "waitoff.hxx"
+#include "sizedev.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "editable.hxx"
+#include "compiler.hxx"
+#include "scui_def.hxx" //CHINA001
+#include "tabprotection.hxx"
+#include "clipparam.hxx"
+#include "externalrefmgr.hxx"
+
+#include <memory>
+#include <basic/basmgr.hxx>
+#include <boost/scoped_ptr.hpp>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
+
+// STATIC DATA -----------------------------------------------------------
+
+//========================================================================
+
+IMPL_LINK( ScDocFunc, NotifyDrawUndo, SdrUndoAction*, pUndoAction )
+{
+ // #i101118# if drawing layer collects the undo actions, add it there
+ ScDrawLayer* pDrawLayer = rDocShell.GetDocument()->GetDrawLayer();
+ if( pDrawLayer && pDrawLayer->IsRecording() )
+ pDrawLayer->AddCalcUndo( pUndoAction );
+ else
+ rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) );
+ rDocShell.SetDrawModified();
+
+ // the affected sheet isn't known, so all stream positions are invalidated
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+// Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
+
+void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange )
+{
+ SCROW nRow = rRange.aStart.Row();
+ if ( nRow > 0 )
+ {
+ SCTAB nTab = rRange.aStart.Tab(); //! alle?
+ --nRow;
+ rDocShell.PostPaint( ScRange(0,nRow,nTab, MAXCOL,nRow,nTab), PAINT_GRID );
+ }
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::AdjustRowHeight( const ScRange& rRange, BOOL bPaint )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if ( pDoc->IsImportingXML() )
+ {
+ // for XML import, all row heights are updated together after importing
+ return FALSE;
+ }
+ if ( !pDoc->IsAdjustHeightEnabled() )
+ {
+ return FALSE;
+ }
+
+ SCTAB nTab = rRange.aStart.Tab();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCROW nEndRow = rRange.aEnd.Row();
+
+ ScSizeDeviceProvider aProv( &rDocShell );
+ Fraction aOne(1,1);
+
+ BOOL bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
+ aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, FALSE );
+
+ if ( bPaint && bChanged )
+ rDocShell.PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+
+ return bChanged;
+}
+
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::DetectiveAddPred(const ScAddress& rPos)
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ rDocShell.MakeDrawLayer();
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).ShowPred( nCol, nRow );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (bDone)
+ {
+ ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED );
+ pDoc->AddDetectiveOperation( aOperation );
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
+ }
+ aModificator.SetDocumentModified();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_REFRESH );
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveDelPred(const ScAddress& rPos)
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).DeletePred( nCol, nRow );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (bDone)
+ {
+ ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED );
+ pDoc->AddDetectiveOperation( aOperation );
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
+ }
+ aModificator.SetDocumentModified();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_REFRESH );
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveAddSucc(const ScAddress& rPos)
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ rDocShell.MakeDrawLayer();
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).ShowSucc( nCol, nRow );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (bDone)
+ {
+ ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC );
+ pDoc->AddDetectiveOperation( aOperation );
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
+ }
+ aModificator.SetDocumentModified();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_REFRESH );
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveDelSucc(const ScAddress& rPos)
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).DeleteSucc( nCol, nRow );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (bDone)
+ {
+ ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC );
+ pDoc->AddDetectiveOperation( aOperation );
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
+ }
+ aModificator.SetDocumentModified();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_REFRESH );
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveAddError(const ScAddress& rPos)
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ rDocShell.MakeDrawLayer();
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ SCCOL nCol = rPos.Col();
+ SCROW nRow = rPos.Row();
+ SCTAB nTab = rPos.Tab();
+
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).ShowError( nCol, nRow );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (bDone)
+ {
+ ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR );
+ pDoc->AddDetectiveOperation( aOperation );
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
+ }
+ aModificator.SetDocumentModified();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_REFRESH );
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveMarkInvalid(SCTAB nTab)
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ rDocShell.MakeDrawLayer();
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+
+ Window* pWaitWin = rDocShell.GetActiveDialogParent();
+ if (pWaitWin)
+ pWaitWin->EnterWait();
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bOverflow;
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).MarkInvalid( bOverflow );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (pWaitWin)
+ pWaitWin->LeaveWait();
+ if (bDone)
+ {
+ if (pUndo && bUndo)
+ {
+ pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID ) );
+ rDocShell.GetUndoManager()->AddUndoAction( pUndo );
+ }
+ aModificator.SetDocumentModified();
+ if ( bOverflow )
+ {
+ InfoBox( NULL,
+ ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW ) ).Execute();
+ }
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveDelAll(SCTAB nTab)
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return FALSE;
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ if (bUndo)
+ pModel->BeginCalcUndo();
+ BOOL bDone = ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_DETECTIVE );
+ SdrUndoGroup* pUndo = NULL;
+ if (bUndo)
+ pUndo = pModel->GetCalcUndo();
+ if (bDone)
+ {
+ ScDetOpList* pOldList = pDoc->GetDetOpList();
+ ScDetOpList* pUndoList = NULL;
+ if (bUndo)
+ pUndoList = pOldList ? new ScDetOpList(*pOldList) : NULL;
+
+ pDoc->ClearDetectiveOperations();
+
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDetective( &rDocShell, pUndo, NULL, pUndoList ) );
+ }
+ aModificator.SetDocumentModified();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DETECTIVE_REFRESH );
+ }
+ else
+ delete pUndo;
+
+ return bDone;
+}
+
+BOOL ScDocFunc::DetectiveRefresh( BOOL bAutomatic )
+{
+ BOOL bDone = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScDetOpList* pList = pDoc->GetDetOpList();
+ if ( pList && pList->Count() )
+ {
+ rDocShell.MakeDrawLayer();
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (bUndo)
+ pModel->BeginCalcUndo();
+
+ // Loeschen auf allen Tabellen
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_ARROWS ); // don't remove circles
+
+ // Wiederholen
+
+ USHORT nCount = pList->Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScDetOpData* pData = (*pList)[i];
+ if (pData)
+ {
+ ScAddress aPos = pData->GetPos();
+ ScDetectiveFunc aFunc( pDoc, aPos.Tab() );
+ SCCOL nCol = aPos.Col();
+ SCROW nRow = aPos.Row();
+ switch (pData->GetOperation())
+ {
+ case SCDETOP_ADDSUCC:
+ aFunc.ShowSucc( nCol, nRow );
+ break;
+ case SCDETOP_DELSUCC:
+ aFunc.DeleteSucc( nCol, nRow );
+ break;
+ case SCDETOP_ADDPRED:
+ aFunc.ShowPred( nCol, nRow );
+ break;
+ case SCDETOP_DELPRED:
+ aFunc.DeletePred( nCol, nRow );
+ break;
+ case SCDETOP_ADDERROR:
+ aFunc.ShowError( nCol, nRow );
+ break;
+ default:
+ DBG_ERROR("falsche Op bei DetectiveRefresh");
+ }
+ }
+ }
+
+ if (bUndo)
+ {
+ SdrUndoGroup* pUndo = pModel->GetCalcUndo();
+ if (pUndo)
+ {
+ pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH ) );
+ // wenn automatisch, an letzte Aktion anhaengen
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDraw( pUndo, &rDocShell ),
+ bAutomatic );
+ }
+ }
+ rDocShell.SetDrawModified();
+ bDone = TRUE;
+ }
+ return bDone;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::DeleteContents( const ScMarkData& rMark, USHORT nFlags,
+ BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ DBG_ERROR("ScDocFunc::DeleteContents ohne Markierung");
+ return FALSE;
+ }
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScEditableTester aTester( pDoc, rMark );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ ScRange aMarkRange;
+ BOOL bSimple = FALSE;
+
+ ScMarkData aMultiMark = rMark;
+ aMultiMark.SetMarking(FALSE); // fuer MarkToMulti
+
+ ScDocument* pUndoDoc = NULL;
+ BOOL bMulti = !bSimple && aMultiMark.IsMultiMarked();
+ if (!bSimple)
+ {
+ aMultiMark.MarkToMulti();
+ aMultiMark.GetMultiMarkArea( aMarkRange );
+ }
+ ScRange aExtendedRange(aMarkRange);
+ if (!bSimple)
+ {
+ if ( pDoc->ExtendMerge( aExtendedRange, TRUE ) )
+ bMulti = FALSE;
+ }
+
+ // keine Objekte auf geschuetzten Tabellen
+ BOOL bObjects = FALSE;
+ if ( nFlags & IDF_OBJECTS )
+ {
+ bObjects = TRUE;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aMultiMark.GetTableSelect(nTab) && pDoc->IsTabProtected(nTab))
+ bObjects = FALSE;
+ }
+
+ USHORT nExtFlags = 0; // extra flags are needed only if attributes are deleted
+ if ( nFlags & IDF_ATTRIB )
+ rDocShell.UpdatePaintExt( nExtFlags, aMarkRange );
+
+ // Reihenfolge:
+ // 1) BeginDrawUndo
+ // 2) Objekte loeschen (DrawUndo wird gefuellt)
+ // 3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
+ // 4) Inhalte loeschen
+
+ bool bDrawUndo = bObjects || (nFlags & IDF_NOTE);
+ if (bRecord && bDrawUndo)
+ pDoc->BeginDrawUndo();
+
+ if (bObjects)
+ {
+ if (bMulti)
+ pDoc->DeleteObjectsInSelection( aMultiMark );
+ else
+ pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
+ aMultiMark );
+ }
+
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, aMarkRange.aStart.Tab(), aMarkRange.aEnd.Tab() );
+
+ // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
+ // nur mit IDF_HARDATTR zu langsam ist:
+ USHORT nUndoDocFlags = nFlags;
+ if (nFlags & IDF_ATTRIB)
+ nUndoDocFlags |= IDF_ATTRIB;
+ if (nFlags & IDF_EDITATTR) // Edit-Engine-Attribute
+ nUndoDocFlags |= IDF_STRING; // -> Zellen werden geaendert
+ if (nFlags & IDF_NOTE)
+ nUndoDocFlags |= IDF_CONTENTS; // #68795# copy all cells with their notes
+ // note captions are handled in drawing undo
+ nUndoDocFlags |= IDF_NOCAPTIONS;
+ pDoc->CopyToDocument( aExtendedRange, nUndoDocFlags, bMulti, pUndoDoc, &aMultiMark );
+ }
+
+//! HideAllCursors(); // falls Zusammenfassung aufgehoben wird
+ if (bSimple)
+ pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
+ aMultiMark, nFlags );
+ else
+ {
+ pDoc->DeleteSelection( nFlags, aMultiMark );
+// aMultiMark.MarkToSimple();
+ }
+
+ // add undo action after drawing undo is complete (objects and note captions)
+ if( bRecord )
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteContents( &rDocShell, aMultiMark, aExtendedRange,
+ pUndoDoc, bMulti, nFlags, bDrawUndo ) );
+
+ if (!AdjustRowHeight( aExtendedRange ))
+ rDocShell.PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
+ else if (nExtFlags & SC_PF_LINES)
+ lcl_PaintAbove( rDocShell, aExtendedRange ); // fuer Linien ueber dem Bereich
+
+// rDocShell.UpdateOle(GetViewData()); //! an der View?
+ aModificator.SetDocumentModified();
+//! CellContentChanged();
+//! ShowAllCursors();
+
+#if 0
+ //! muss an der View bleiben !!!!
+ if ( nFlags & IDF_ATTRIB )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ ForgetFormatArea();
+ else
+ StartFormatArea(); // Attribute loeschen ist auch Attributierung
+ }
+#endif
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
+ BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScEditableTester aTester( pDoc, rMark );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ ScRange aMarkRange;
+ ScMarkData aMultiMark = rMark;
+ aMultiMark.SetMarking(FALSE); // for MarkToMulti
+ aMultiMark.MarkToMulti();
+ aMultiMark.GetMultiMarkArea( aMarkRange );
+
+ if (bRecord)
+ {
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ 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 );
+
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, TRUE, pUndoDoc, &aMultiMark );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTransliterate( &rDocShell, aMultiMark, pUndoDoc, nType ) );
+ }
+
+ pDoc->TransliterateText( aMultiMark, nType );
+
+ if (!AdjustRowHeight( aMarkRange ))
+ rDocShell.PostPaint( aMarkRange, PAINT_GRID );
+
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::SetNormalString( const ScAddress& rPos, const String& rText, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ SCTAB* pTabs = NULL;
+ ScBaseCell** ppOldCells = NULL;
+ BOOL* pHasFormat = NULL;
+ ULONG* pOldFormats = NULL;
+ ScBaseCell* pDocCell = pDoc->GetCell( rPos );
+ BOOL bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT);
+ if (bUndo)
+ {
+ pTabs = new SCTAB[1];
+ pTabs[0] = rPos.Tab();
+ ppOldCells = new ScBaseCell*[1];
+ ppOldCells[0] = pDocCell ? pDocCell->CloneWithoutNote( *pDoc ) : 0;
+
+ pHasFormat = new BOOL[1];
+ pOldFormats = new ULONG[1];
+ const SfxPoolItem* pItem;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() );
+ if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
+ ATTR_VALUE_FORMAT,FALSE,&pItem) )
+ {
+ pHasFormat[0] = TRUE;
+ pOldFormats[0] = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+ else
+ pHasFormat[0] = FALSE;
+ }
+
+ pDoc->SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText );
+
+ if (bUndo)
+ {
+ // wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
+ rDocShell.GetUndoManager()->AddUndoAction(new ScUndoEnterData( &rDocShell, rPos.Col(),rPos.Row(),rPos.Tab(), 1,pTabs,
+ ppOldCells, pHasFormat, pOldFormats, rText, NULL ) );
+ }
+
+ if ( bEditDeleted || pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) )
+ AdjustRowHeight( ScRange(rPos) );
+
+ rDocShell.PostPaintCell( rPos );
+ aModificator.SetDocumentModified();
+
+ // #107160# notify input handler here the same way as in PutCell
+ if (bApi)
+ NotifyInputHandler( rPos );
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ BOOL bXMLLoading(pDoc->IsImportingXML());
+
+ // #i925#; it is not neccessary to test whether the cell is editable on loading a XML document
+ if (!bXMLLoading)
+ {
+ ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ pNewCell->Delete();
+ return FALSE;
+ }
+ }
+
+ BOOL bEditCell = ( pNewCell->GetCellType() == CELLTYPE_EDIT );
+ ScBaseCell* pDocCell = pDoc->GetCell( rPos );
+ BOOL bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT);
+ BOOL bHeight = ( bEditDeleted || bEditCell ||
+ pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) );
+
+ ScBaseCell* pUndoCell = (bUndo && pDocCell) ? pDocCell->CloneWithoutNote( *pDoc, rPos ) : 0;
+ ScBaseCell* pRedoCell = (bUndo && pNewCell) ? pNewCell->CloneWithoutNote( *pDoc, rPos ) : 0;
+
+ pDoc->PutCell( rPos, pNewCell );
+
+ // wegen ChangeTracking darf UndoAction erst nach PutCell angelegt werden
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoPutCell( &rDocShell, rPos, pUndoCell, pRedoCell, bHeight ) );
+ }
+
+ if (bHeight)
+ AdjustRowHeight( ScRange(rPos) );
+
+ if (!bXMLLoading)
+ rDocShell.PostPaintCell( rPos );
+
+ aModificator.SetDocumentModified();
+
+ // #i925#; it is not neccessary to notify on loading a XML document
+ // #103934#; notify editline and cell in edit mode
+ if (bApi && !bXMLLoading)
+ NotifyInputHandler( rPos );
+
+ return TRUE;
+}
+
+void ScDocFunc::NotifyInputHandler( const ScAddress& /* rPos */ )
+{
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh && pViewSh->GetViewData()->GetDocShell() == &rDocShell )
+ {
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ {
+ sal_Bool bIsEditMode(pInputHdl->IsEditMode());
+
+ // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
+ // (the cell shows the same like the InputWindow)
+ if (bIsEditMode)
+ pInputHdl->SetModified();
+ pViewSh->UpdateInputHandler(FALSE, !bIsEditMode);
+ }
+ }
+}
+
+ struct ScMyRememberItem
+ {
+ USHORT nIndex;
+ SfxItemSet aItemSet;
+
+ ScMyRememberItem(const SfxItemSet& rItemSet, USHORT nTempIndex) :
+ nIndex(nTempIndex), aItemSet(rItemSet) {}
+ };
+
+ typedef ::std::list<ScMyRememberItem*> ScMyRememberItemList;
+
+BOOL ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, BOOL bInterpret, BOOL bApi )
+{
+ // PutData ruft PutCell oder SetNormalString
+
+ BOOL bRet = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScEditAttrTester aTester( &rEngine );
+ BOOL bEditCell = aTester.NeedsObject();
+ if ( bEditCell )
+ {
+ // #i61702# With bLoseContent set, the content of rEngine isn't restored
+ // (used in loading XML, where after the removeActionLock call the API obejct's
+ // EditEngine isn't accessed again.
+ sal_Bool bLoseContent = pDoc->IsImportingXML();
+
+ sal_Bool bUpdateMode(rEngine.GetUpdateMode());
+ if (bUpdateMode)
+ rEngine.SetUpdateMode(sal_False);
+
+ ScMyRememberItemList aRememberItems;
+ ScMyRememberItem* pRememberItem = NULL;
+
+ // All paragraph attributes must be removed before calling CreateTextObject,
+ // not only alignment, so the object doesn't contain the cell attributes as
+ // paragraph attributes. Before remove the attributes store they in a list to
+ // set they back to the EditEngine.
+ USHORT nCount = rEngine.GetParagraphCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ const SfxItemSet& rOld = rEngine.GetParaAttribs( i );
+ if ( rOld.Count() )
+ {
+ if ( !bLoseContent )
+ {
+ pRememberItem = new ScMyRememberItem(rEngine.GetParaAttribs(i), i);
+ aRememberItems.push_back(pRememberItem);
+ }
+ rEngine.SetParaAttribs( i, SfxItemSet( *rOld.GetPool(), rOld.GetRanges() ) );
+ }
+ }
+
+ EditTextObject* pNewData = rEngine.CreateTextObject();
+ bRet = PutCell( rPos,
+ new ScEditCell( pNewData, pDoc, rEngine.GetEditTextObjectPool() ),
+ bApi );
+ delete pNewData;
+
+ // Set the paragraph attributes back to the EditEngine.
+ if (!aRememberItems.empty())
+ {
+// ScMyRememberItem* pRememberItem = NULL;
+ ScMyRememberItemList::iterator aItr = aRememberItems.begin();
+ while (aItr != aRememberItems.end())
+ {
+ pRememberItem = *aItr;
+ rEngine.SetParaAttribs(pRememberItem->nIndex, pRememberItem->aItemSet);
+ delete pRememberItem;
+ aItr = aRememberItems.erase(aItr);
+ }
+ }
+
+ // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
+ if ( bUpdateMode && !bLoseContent )
+ rEngine.SetUpdateMode(sal_True);
+ }
+ else
+ {
+ String aText = rEngine.GetText();
+ if ( bInterpret || !aText.Len() )
+ bRet = SetNormalString( rPos, aText, bApi );
+ else
+ bRet = PutCell( rPos, new ScStringCell( aText ), bApi );
+ }
+
+ if ( bRet && aTester.NeedsCellAttr() )
+ {
+ const SfxItemSet& rEditAttr = aTester.GetAttribs();
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetFromEditItemSet( &rEditAttr );
+ aPattern.DeleteUnchanged( pDoc->GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) );
+ aPattern.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY ); // wasn't removed above if no edit object
+ if ( aPattern.GetItemSet().Count() > 0 )
+ {
+ ScMarkData aMark;
+ aMark.SelectTable( rPos.Tab(), TRUE );
+ aMark.SetMarkArea( ScRange( rPos ) );
+ ApplyAttributes( aMark, aPattern, TRUE, bApi );
+ }
+ }
+
+ return bRet;
+}
+
+
+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 String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScBaseCell* pNewCell = NULL;
+
+ if ( rText.Len() > 1 && rText.GetChar(0) == '=' )
+ {
+ ScTokenArray* pCode;
+ if ( pDoc->IsImportingXML() )
+ { // temporary formula string as string tokens
+ pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText, rFormulaNmsp, eGrammar );
+ pDoc->IncXMLImportedFormulaCount( rText.Len() );
+ }
+ else
+ {
+ ScCompiler aComp( pDoc, rPos );
+ aComp.SetGrammar(eGrammar);
+ pCode = aComp.CompileString( rText );
+ }
+ pNewCell = new ScFormulaCell( pDoc, rPos, pCode, eGrammar, MM_NONE );
+ delete pCode; // Zell-ctor hat das TokenArray kopiert
+ }
+ else if ( rText.Len() > 1 && rText.GetChar(0) == '\'' )
+ {
+ // for bEnglish, "'" at the beginning is always interpreted as text
+ // marker and stripped
+ pNewCell = ScBaseCell::CreateTextCell( rText.Copy( 1 ), pDoc );
+ }
+ else // (nur) auf englisches Zahlformat testen
+ {
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
+ double fVal;
+ if ( pFormatter->IsNumberFormat( rText, nEnglish, fVal ) )
+ pNewCell = new ScValueCell( fVal );
+ else if ( rText.Len() )
+ pNewCell = ScBaseCell::CreateTextCell( rText, pDoc );
+
+ // das (englische) Zahlformat wird nicht gesetzt
+ //! passendes lokales Format suchen und setzen???
+ }
+
+ return pNewCell;
+}
+
+
+BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
+ BOOL bInterpret, BOOL bEnglish, BOOL bApi,
+ const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
+{
+ // SetCellText ruft PutCell oder SetNormalString
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScBaseCell* pNewCell = NULL;
+ if ( bInterpret )
+ {
+ if ( bEnglish )
+ {
+ ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
+ if (bApi)
+ pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
+
+ // code moved to own method InterpretEnglishString because it is also used in
+ // ScCellRangeObj::setFormulaArray
+
+ 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 );
+ else
+ return SetNormalString( rPos, rText, bApi );
+}
+
+//------------------------------------------------------------------------
+
+bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
+{
+ ScDocument& rDoc = *rDocShell.GetDocument();
+ ScPostIt* pNote = rDoc.GetNote( rPos );
+ if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;
+
+ // move the caption to internal or hidden layer and create undo action
+ pNote->ShowCaption( rPos, bShow );
+ if( rDoc.IsUndoEnabled() )
+ rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
+
+ if (rDoc.IsStreamValid(rPos.Tab()))
+ rDoc.SetStreamValid(rPos.Tab(), FALSE);
+
+ rDocShell.SetDocumentModified();
+
+ return true;
+}
+
+//------------------------------------------------------------------------
+
+bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return false;
+ }
+
+ String aNewText = rText;
+ aNewText.ConvertLineEnd(); //! ist das noetig ???
+
+ if( ScPostIt* pNote = (aNewText.Len() > 0) ? pDoc->GetOrCreateNote( rPos ) : pDoc->GetNote( rPos ) )
+ pNote->SetText( rPos, aNewText );
+
+ //! Undo !!!
+
+ if (pDoc->IsStreamValid(rPos.Tab()))
+ pDoc->SetStreamValid(rPos.Tab(), FALSE);
+
+ rDocShell.PostPaintCell( rPos );
+ aModificator.SetDocumentModified();
+
+ return true;
+}
+
+//------------------------------------------------------------------------
+
+bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate, BOOL bApi )
+{
+ bool bDone = false;
+
+ ScDocShellModificator aModificator( rDocShell );
+ ScDocument& rDoc = *rDocShell.GetDocument();
+ ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
+ if (aTester.IsEditable())
+ {
+ ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+ SfxUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;
+
+ ScNoteData aOldData;
+ 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();
+ }
+
+ // 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, true ) )
+ {
+ if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
+ if( pDate ) pNewNote->SetDate( *pDate );
+ // rescue note data for undo
+ aNewData = pNewNote->GetNoteData();
+ }
+
+ // create the undo action
+ if( pUndoMgr && (aOldData.mpCaption || aNewData.mpCaption) )
+ pUndoMgr->AddUndoAction( new ScUndoReplaceNote( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo() ) );
+
+ // repaint cell (to make note marker visible)
+ rDocShell.PostPaintCell( rPos );
+
+ if (rDoc.IsStreamValid(rPos.Tab()))
+ rDoc.SetStreamValid(rPos.Tab(), FALSE);
+
+ aModificator.SetDocumentModified();
+ bDone = true;
+ }
+ else if (!bApi)
+ {
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ }
+
+ return bDone;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
+ BOOL bRecord, BOOL bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if ( bRecord && !pDoc->IsUndoEnabled() )
+ bRecord = FALSE;
+
+ BOOL bImportingXML = pDoc->IsImportingXML();
+ // Cell formats can still be set if the range isn't editable only because of matrix formulas.
+ // #i62483# When loading XML, the check can be skipped altogether.
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
+ && !bOnlyNotBecauseOfMatrix )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR);
+ return FALSE;
+ }
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ //! Umrandung
+
+ ScRange aMultiRange;
+ BOOL bMulti = rMark.IsMultiMarked();
+ if ( bMulti )
+ rMark.GetMultiMarkArea( aMultiRange );
+ else
+ rMark.GetMarkArea( aMultiRange );
+
+ if ( bRecord )
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() );
+ pDoc->CopyToDocument( aMultiRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionAttr(
+ &rDocShell, rMark,
+ aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(),
+ aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(),
+ pUndoDoc, bMulti, &rPattern ) );
+ }
+
+ // While loading XML it is not neccessary to ask HasAttrib. It needs too much time.
+ USHORT nExtFlags = 0;
+ if ( !bImportingXML )
+ rDocShell.UpdatePaintExt( nExtFlags, aMultiRange ); // content before the change
+ pDoc->ApplySelectionPattern( rPattern, rMark );
+ if ( !bImportingXML )
+ rDocShell.UpdatePaintExt( nExtFlags, aMultiRange ); // content after the change
+
+ if (!AdjustRowHeight( aMultiRange ))
+ rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
+ else if (nExtFlags & SC_PF_LINES)
+ lcl_PaintAbove( rDocShell, aMultiRange ); // fuer Linien ueber dem Bereich
+
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+
+BOOL ScDocFunc::ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
+ BOOL bRecord, BOOL bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if ( bRecord && !pDoc->IsUndoEnabled() )
+ bRecord = FALSE;
+
+ BOOL bImportingXML = pDoc->IsImportingXML();
+ // Cell formats can still be set if the range isn't editable only because of matrix formulas.
+ // #i62483# When loading XML, the check can be skipped altogether.
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
+ && !bOnlyNotBecauseOfMatrix )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR);
+ return FALSE;
+ }
+
+ ScStyleSheet* pStyleSheet = (ScStyleSheet*) pDoc->GetStyleSheetPool()->Find(
+ rStyleName, SFX_STYLE_FAMILY_PARA );
+ if (!pStyleSheet)
+ return FALSE;
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScRange aMultiRange;
+ BOOL bMulti = rMark.IsMultiMarked();
+ if ( bMulti )
+ rMark.GetMultiMarkArea( aMultiRange );
+ else
+ rMark.GetMarkArea( aMultiRange );
+
+ if ( bRecord )
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nStartTab = aMultiRange.aStart.Tab();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nStartTab && rMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange = aMultiRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionStyle(
+ &rDocShell, rMark, aMultiRange, rStyleName, pUndoDoc ) );
+
+ }
+
+// BOOL bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
+// pDoc->ApplySelectionPattern( rPattern, rMark );
+
+ pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, rMark );
+
+// if (!bPaintExt)
+// bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
+// USHORT nExtFlags = bPaintExt ? SC_PF_LINES : 0;
+ USHORT nExtFlags = 0;
+ if (!AdjustRowHeight( aMultiRange ))
+ rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
+ else if (nExtFlags & SC_PF_LINES)
+ lcl_PaintAbove( rDocShell, aMultiRange ); // fuer Linien ueber dem Bereich
+
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, InsCellCmd eCmd,
+ BOOL bRecord, BOOL bApi, BOOL bPartOfPaste )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
+ {
+ DBG_ERROR("invalid row in InsertCells");
+ return FALSE;
+ }
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCCOL nPaintStartX = nStartCol;
+ SCROW nPaintStartY = nStartRow;
+ SCCOL nPaintEndX = nEndCol;
+ SCROW nPaintEndY = nEndRow;
+ USHORT nPaintFlags = PAINT_GRID;
+ BOOL bSuccess;
+ SCTAB i;
+
+ ScTabViewShell* pViewSh = rDocShell.GetBestViewShell(); //preserve current cursor position
+ SCCOL nCursorCol = 0;
+ SCROW nCursorRow = 0;
+ if( pViewSh )
+ {
+ nCursorCol = pViewSh->GetViewData()->GetCurX();
+ nCursorRow = pViewSh->GetViewData()->GetCurY();
+ }
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ SCTAB nCount = 0;
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( !pDoc->IsScenario(i) )
+ {
+ nCount++;
+ if( nCount == nEndTab+1 )
+ {
+ aMark.SelectTable( i, TRUE );
+ break;
+ }
+ }
+ }
+ }
+
+ 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
+ // Test zusammengefasste
+
+ SCCOL nMergeTestStartX = nStartCol;
+ SCROW nMergeTestStartY = nStartRow;
+ SCCOL nMergeTestEndX = nEndCol;
+ SCROW nMergeTestEndY = nEndRow;
+
+ ScRange aExtendMergeRange( rRange );
+
+ if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
+ {
+ pDoc->ExtendMerge( aExtendMergeRange );
+ pDoc->ExtendOverlapped( aExtendMergeRange );
+ nMergeTestEndX = aExtendMergeRange.aEnd.Col();
+ nMergeTestEndY = aExtendMergeRange.aEnd.Row();
+ nPaintEndX = nMergeTestEndX;
+ nPaintEndY = nMergeTestEndY;
+ }
+
+ if ( eCmd == INS_INSROWS )
+ {
+ nMergeTestStartX = 0;
+ nMergeTestEndX = MAXCOL;
+ }
+ if ( eCmd == INS_INSCOLS )
+ {
+ nMergeTestStartY = 0;
+ nMergeTestEndY = MAXROW;
+ }
+ if ( eCmd == INS_CELLSDOWN )
+ nMergeTestEndY = MAXROW;
+ if ( eCmd == INS_CELLSRIGHT )
+ nMergeTestEndX = MAXCOL;
+
+ BOOL bNeedRefresh = FALSE;
+
+ SCCOL nEditTestEndX = (eCmd==INS_INSCOLS) ? MAXCOL : nMergeTestEndX;
+ SCROW nEditTestEndY = (eCmd==INS_INSROWS) ? MAXROW : nMergeTestEndY;
+ ScEditableTester aTester( pDoc, nMergeTestStartX, nMergeTestStartY, nEditTestEndX, nEditTestEndY, aMark );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ WaitObject aWait( rDocShell.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+
+ ScDocument* pRefUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if ( bRecord )
+ {
+ pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE );
+
+ // pRefUndoDoc is filled in InsertCol / InsertRow
+
+ pUndoData = new ScRefUndoData( pDoc );
+
+ pDoc->BeginDrawUndo();
+ }
+
+ // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
+ // the patch comes from mloiseleur and maoyg
+ BOOL bInsertMerge = FALSE;
+ std::vector<ScRange> qIncreaseRange;
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTCELLS );
+ if (bRecord)
+ rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect(i) )
+ {
+ if( pDoc->HasAttrib( nMergeTestStartX, nMergeTestStartY, i, nMergeTestEndX, nMergeTestEndY, i, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ if (eCmd==INS_CELLSRIGHT)
+ bNeedRefresh = TRUE;
+
+ SCCOL nMergeStartX = nMergeTestStartX;
+ SCROW nMergeStartY = nMergeTestStartY;
+ SCCOL nMergeEndX = nMergeTestEndX;
+ SCROW nMergeEndY = nMergeTestEndY;
+
+ 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 (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
+ rDocShell.GetUndoManager()->LeaveListAction();
+ return FALSE;
+ }
+
+ SCCOL nTestCol = -1;
+ SCROW nTestRow1 = -1;
+ SCROW nTestRow2 = -1;
+
+ ScDocAttrIterator aTestIter( pDoc, i, nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY );
+ ScRange aExtendRange( nMergeTestStartX, nMergeTestStartY, i, nMergeTestEndX, nMergeTestEndY, i );
+ const ScPatternAttr* pPattern = NULL;
+ const ScMergeAttr* pMergeFlag = NULL;
+ const ScMergeFlagAttr* pMergeFlagAttr = NULL;
+ while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
+ {
+ pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
+ pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ INT16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
+ if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
+ {
+ ScRange aRange( nTestCol, nTestRow1, i );
+ pDoc->ExtendOverlapped(aRange);
+ pDoc->ExtendMerge(aRange, TRUE, TRUE);
+
+ if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
+ {
+ for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
+ {
+ ScRange aTestRange( nTestCol, nTestRow, i );
+ pDoc->ExtendOverlapped( aTestRange );
+ pDoc->ExtendMerge( aTestRange, TRUE, TRUE);
+ ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
+ if( !aExtendRange.In( aMergeRange ) )
+ {
+ qIncreaseRange.push_back( aTestRange );
+ bInsertMerge = TRUE;
+ }
+ }
+ }
+ else
+ {
+ ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
+ if( !aExtendRange.In( aMergeRange ) )
+ {
+ qIncreaseRange.push_back( aRange );
+ }
+ bInsertMerge = TRUE;
+ }
+ }
+ }
+
+ if( bInsertMerge )
+ {
+ if( eCmd == INS_INSROWS || eCmd == INS_CELLSDOWN )
+ {
+ nStartRow = aExtendMergeRange.aStart.Row();
+ nEndRow = aExtendMergeRange.aEnd.Row();
+
+ if( eCmd == INS_CELLSDOWN )
+ nEndCol = nMergeTestEndX;
+ else
+ {
+ nStartCol = 0;
+ nEndCol = MAXCOL;
+ }
+ }
+ else if( eCmd == INS_CELLSRIGHT || eCmd == INS_INSCOLS )
+ {
+
+ nStartCol = aExtendMergeRange.aStart.Col();
+ nEndCol = aExtendMergeRange.aEnd.Col();
+ if( eCmd == INS_CELLSRIGHT )
+ {
+ nEndRow = nMergeTestEndY;
+ }
+ else
+ {
+ nStartRow = 0;
+ nEndRow = MAXROW;
+ }
+ }
+
+ if( !qIncreaseRange.empty() )
+ {
+ for( ::std::vector<ScRange>::const_iterator iIter( qIncreaseRange.begin()); iIter != qIncreaseRange.end(); iIter++ )
+ {
+ ScRange aRange( *iIter );
+ if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
+ {
+ UnmergeCells( aRange, TRUE, TRUE );
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
+ rDocShell.GetUndoManager()->LeaveListAction();
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ switch (eCmd)
+ {
+ case INS_CELLSDOWN:
+ bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
+ nPaintEndY = MAXROW;
+ break;
+ case INS_INSROWS:
+ 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 = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
+ nPaintEndX = MAXCOL;
+ break;
+ case INS_INSCOLS:
+ bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
+ nPaintStartY = 0;
+ nPaintEndY = MAXROW;
+ nPaintEndX = MAXCOL;
+ nPaintFlags |= PAINT_TOP;
+ break;
+ default:
+ DBG_ERROR("Falscher Code beim Einfuegen");
+ bSuccess = FALSE;
+ break;
+ }
+
+ if ( bSuccess )
+ {
+ SCTAB* pTabs = NULL;
+ SCTAB* pScenarios = NULL;
+ SCTAB nUndoPos = 0;
+
+ if ( bRecord )
+ {
+ pTabs = new SCTAB[nSelCount];
+ pScenarios = new SCTAB[nSelCount];
+ nUndoPos = 0;
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect( i ) )
+ {
+ SCTAB nCount = 0;
+ for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+ nCount ++;
+
+ pScenarios[nUndoPos] = nCount;
+ pTabs[nUndoPos] = i;
+ nUndoPos ++;
+ }
+ }
+
+ if( !bInsertMerge )
+ {
+ rDocShell.GetUndoManager()->LeaveListAction();
+ }
+
+ rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
+ &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
+ nUndoPos, pTabs, pScenarios, eCmd, pRefUndoDoc, pUndoData, bPartOfPaste ) );
+ }
+
+ // #i8302 : we remerge growing ranges, with the new part inserted
+
+ while( !qIncreaseRange.empty() )
+ {
+ ScRange aRange = qIncreaseRange.back();
+ if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
+ {
+ switch (eCmd)
+ {
+ case INS_CELLSDOWN:
+ case INS_INSROWS:
+ aRange.aEnd.IncRow(static_cast<SCsCOL>(nEndRow-nStartRow+1));
+ break;
+ case INS_CELLSRIGHT:
+ case INS_INSCOLS:
+ aRange.aEnd.IncCol(static_cast<SCsCOL>(nEndCol-nStartCol+1));
+ break;
+ default:
+ break;
+ }
+ MergeCells(aRange, FALSE, TRUE, TRUE);
+ }
+ qIncreaseRange.pop_back();
+ }
+
+ if( bInsertMerge )
+ rDocShell.GetUndoManager()->LeaveListAction();
+
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect( i ) )
+ {
+ if (bNeedRefresh)
+ pDoc->ExtendMerge( nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY, i, TRUE );
+ else
+ pDoc->RefreshAutoFilter( nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY, i );
+
+ if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
+ pDoc->UpdatePageBreaks( i );
+
+ USHORT nExtFlags = 0;
+ rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );
+
+ SCTAB nScenarioCount = 0;
+
+ for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+ nScenarioCount ++;
+
+ BOOL bAdjusted = ( eCmd == INS_INSROWS ) ? AdjustRowHeight(ScRange(0, nStartRow, i, MAXCOL, nEndRow, i+nScenarioCount )) :
+ AdjustRowHeight(ScRange(0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount ));
+ if (bAdjusted)
+ {
+ // paint only what is not done by AdjustRowHeight
+ if (nPaintFlags & PAINT_TOP)
+ rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
+ }
+ else
+ rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags, nExtFlags );
+ }
+ }
+ //aModificator.SetDocumentModified();
+ }
+ else
+ {
+ if( bInsertMerge )
+ {
+ while( !qIncreaseRange.empty() )
+ {
+ ScRange aRange = qIncreaseRange.back();
+ MergeCells(aRange, FALSE, TRUE, TRUE);
+ qIncreaseRange.pop_back();
+ }
+
+ if( pViewSh )
+ {
+ pViewSh->MarkRange( rRange, FALSE );
+ pViewSh->SetCursor( nCursorCol, nCursorRow );
+ }
+ }
+
+ rDocShell.GetUndoManager()->LeaveListAction();
+ SfxUndoManager* pMgr = rDocShell.GetUndoManager();
+ pMgr->RemoveLastUndoAction();
+
+ delete pRefUndoDoc;
+ delete pUndoData;
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_INSERT_FULL); // Spalte/Zeile voll
+ }
+
+ aModificator.SetDocumentModified();
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+ return bSuccess;
+}
+
+BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
+ BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
+ {
+ DBG_ERROR("invalid row in DeleteCells");
+ return FALSE;
+ }
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCCOL nPaintStartX = nStartCol;
+ SCROW nPaintStartY = nStartRow;
+ SCCOL nPaintEndX = nEndCol;
+ SCROW nPaintEndY = nEndRow;
+ USHORT nPaintFlags = PAINT_GRID;
+ SCTAB i;
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ SCTAB nCount = 0;
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( !pDoc->IsScenario(i) )
+ {
+ nCount++;
+ if( nCount == nEndTab+1 )
+ {
+ aMark.SelectTable( i, TRUE );
+ break;
+ }
+ }
+ }
+ }
+
+ 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;
+ SCROW nUndoStartY = nStartRow;
+ SCCOL nUndoEndX = nEndCol;
+ SCROW nUndoEndY = nEndRow;
+
+ ScRange aExtendMergeRange( rRange );
+
+ if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
+ {
+ pDoc->ExtendMerge( aExtendMergeRange );
+ pDoc->ExtendOverlapped( aExtendMergeRange );
+ nUndoEndX = aExtendMergeRange.aEnd.Col();
+ nUndoEndY = aExtendMergeRange.aEnd.Row();
+ nPaintEndX = nUndoEndX;
+ nPaintEndY = nUndoEndY;
+ }
+
+ if (eCmd==DEL_DELROWS)
+ {
+ nUndoStartX = 0;
+ nUndoEndX = MAXCOL;
+ }
+ if (eCmd==DEL_DELCOLS)
+ {
+ nUndoStartY = 0;
+ nUndoEndY = MAXROW;
+ }
+ // Test Zellschutz
+
+ SCCOL nEditTestEndX = nUndoEndX;
+ if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
+ nEditTestEndX = MAXCOL;
+ SCROW nEditTestEndY = nUndoEndY;
+ if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
+ nEditTestEndY = MAXROW;
+ ScEditableTester aTester( pDoc, nUndoStartX, nUndoStartY, nEditTestEndX, nEditTestEndY, aMark );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ // Test zusammengefasste
+
+ SCCOL nMergeTestEndX = (eCmd==DEL_CELLSLEFT) ? MAXCOL : nUndoEndX;
+ SCROW nMergeTestEndY = (eCmd==DEL_CELLSUP) ? MAXROW : nUndoEndY;
+ SCCOL nExtendStartCol = nUndoStartX;
+ SCROW nExtendStartRow = nUndoStartY;
+ BOOL bNeedRefresh = FALSE;
+
+ //Issue 8302 want to be able to insert into the middle of merged cells
+ //the patch comes from maoyg
+ ::std::vector<ScRange> qDecreaseRange;
+ BOOL bDeletingMerge = FALSE;
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_DELETECELLS );
+ if (bRecord)
+ rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect(i) )
+ {
+ if ( pDoc->HasAttrib( nUndoStartX, nUndoStartY, i, nMergeTestEndX, nMergeTestEndY, i, HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ SCCOL nMergeStartX = nUndoStartX;
+ SCROW nMergeStartY = nUndoStartY;
+ SCCOL nMergeEndX = nMergeTestEndX;
+ SCROW nMergeEndY = nMergeTestEndY;
+
+ pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
+ pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
+ if( ( eCmd == DEL_CELLSUP && ( nMergeStartX != nUndoStartX || nMergeEndX != nMergeTestEndX))||
+ ( eCmd == DEL_CELLSLEFT && ( nMergeStartY != nUndoStartY || nMergeEndY != nMergeTestEndY)))
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
+ rDocShell.GetUndoManager()->LeaveListAction();
+ return FALSE;
+ }
+
+ nExtendStartCol = nMergeStartX;
+ nExtendStartRow = nMergeStartY;
+ SCCOL nTestCol = -1;
+ SCROW nTestRow1 = -1;
+ SCROW nTestRow2 = -1;
+
+ ScDocAttrIterator aTestIter( pDoc, i, nUndoStartX, nUndoStartY, nMergeTestEndX, nMergeTestEndY );
+ ScRange aExtendRange( nUndoStartX, nUndoStartY, i, nMergeTestEndX, nMergeTestEndY, i );
+ const ScPatternAttr* pPattern = NULL;
+ const ScMergeAttr* pMergeFlag = NULL;
+ const ScMergeFlagAttr* pMergeFlagAttr = NULL;
+ while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
+ {
+ pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
+ pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG );
+ INT16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
+ if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
+ {
+ ScRange aRange( nTestCol, nTestRow1, i );
+ pDoc->ExtendOverlapped( aRange );
+ pDoc->ExtendMerge( aRange, TRUE, TRUE );
+
+ if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
+ {
+ for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
+ {
+ ScRange aTestRange( nTestCol, nTestRow, i );
+ pDoc->ExtendOverlapped( aTestRange );
+ pDoc->ExtendMerge( aTestRange, TRUE, TRUE);
+ ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
+ if( !aExtendRange.In( aMergeRange ) )
+ {
+ qDecreaseRange.push_back( aTestRange );
+ bDeletingMerge = TRUE;
+ }
+ }
+ }
+ else
+ {
+ ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
+ if( !aExtendRange.In( aMergeRange ) )
+ {
+ qDecreaseRange.push_back( aRange );
+ }
+ bDeletingMerge = TRUE;
+ }
+ }
+ }
+
+ if( bDeletingMerge )
+ {
+
+ if( eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP )
+ {
+ nStartRow = aExtendMergeRange.aStart.Row();
+ nEndRow = aExtendMergeRange.aEnd.Row();
+ bNeedRefresh = TRUE;
+
+ if( eCmd == DEL_CELLSUP )
+ {
+ nEndCol = aExtendMergeRange.aEnd.Col();
+ }
+ else
+ {
+ nStartCol = 0;
+ nEndCol = MAXCOL;
+ }
+ }
+ else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
+ {
+
+ nStartCol = aExtendMergeRange.aStart.Col();
+ nEndCol = aExtendMergeRange.aEnd.Col();
+ if( eCmd == DEL_CELLSLEFT )
+ {
+ nEndRow = aExtendMergeRange.aEnd.Row();
+ bNeedRefresh = TRUE;
+ }
+ else
+ {
+ nStartRow = 0;
+ nEndRow = MAXROW;
+ }
+ }
+
+ if( !qDecreaseRange.empty() )
+ {
+ for( ::std::vector<ScRange>::const_iterator iIter( qDecreaseRange.begin()); iIter != qDecreaseRange.end(); iIter++ )
+ {
+ ScRange aRange( *iIter );
+ if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
+ {
+ UnmergeCells( aRange, TRUE, TRUE );
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
+ rDocShell.GetUndoManager()->LeaveListAction();
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ //
+ // ausfuehren
+ //
+
+ WaitObject aWait( rDocShell.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRefUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if ( bRecord )
+ {
+ // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
+ // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, 0, nTabCount-1, (eCmd==DEL_DELCOLS), (eCmd==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->CopyToDocument( nUndoStartX, nUndoStartY, i, nUndoEndX, nUndoEndY, i+nScenarioCount,
+ IDF_ALL | IDF_NOCAPTIONS, FALSE, pUndoDoc );
+ }
+ }
+
+ pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE );
+
+ pUndoData = new ScRefUndoData( pDoc );
+
+ pDoc->BeginDrawUndo();
+ }
+
+ USHORT nExtFlags = 0;
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect( i ) )
+ rDocShell.UpdatePaintExt( nExtFlags, nStartCol, nStartRow, i, nEndCol, nEndRow, i );
+ }
+
+ BOOL bUndoOutline = FALSE;
+ switch (eCmd)
+ {
+ case DEL_CELLSUP:
+ pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
+ nPaintEndY = MAXROW;
+ break;
+ case DEL_DELROWS:
+ 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:
+ pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
+ nPaintEndX = MAXCOL;
+ break;
+ case DEL_DELCOLS:
+ pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
+ nPaintStartY = 0;
+ nPaintEndY = MAXROW;
+ nPaintEndX = MAXCOL;
+ nPaintFlags |= PAINT_TOP;
+ break;
+ default:
+ DBG_ERROR("Falscher Code beim Loeschen");
+ break;
+ }
+
+ //! Test, ob Outline in Groesse geaendert
+
+ if ( bRecord )
+ {
+ 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 );
+
+ // kopieren mit bColRowFlags=FALSE (#54194#)
+ pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,FALSE,pUndoDoc,NULL,FALSE);
+ delete pRefUndoDoc;
+
+ SCTAB* pTabs = new SCTAB[nSelCount];
+ SCTAB* pScenarios = new SCTAB[nSelCount];
+ SCTAB nUndoPos = 0;
+
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect( i ) )
+ {
+ SCTAB nCount = 0;
+ for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+ nCount ++;
+
+ pScenarios[nUndoPos] = nCount;
+ pTabs[nUndoPos] = i;
+ 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 ) );
+ }
+
+ // #i8302 want to be able to insert into the middle of merged cells
+ // the patch comes from maoyg
+
+ while( !qDecreaseRange.empty() )
+ {
+ ScRange aRange = qDecreaseRange.back();
+
+ long nDecreaseRowCount = 0;
+ long nDecreaseColCount = 0;
+ if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
+ {
+ if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
+ nDecreaseRowCount = nEndRow-nStartRow+1;
+ else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
+ nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
+ else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
+ nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
+ }
+ else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
+ {
+ if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
+ nDecreaseColCount = nEndCol-nStartCol+1;
+ else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
+ nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
+ else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
+ nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
+ }
+
+ switch (eCmd)
+ {
+ case DEL_CELLSUP:
+ case DEL_DELROWS:
+ aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
+ break;
+ case DEL_CELLSLEFT:
+ case DEL_DELCOLS:
+ aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
+ break;
+ default:
+ break;
+ }
+
+ if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
+ {
+ MergeCells( aRange, FALSE, TRUE, TRUE );
+ }
+ qDecreaseRange.pop_back();
+ }
+
+ if( bDeletingMerge )
+ rDocShell.GetUndoManager()->LeaveListAction();
+
+ if ( bNeedRefresh )
+ {
+ // #i51445# old merge flag attributes must be deleted also for single cells,
+ // not only for whole columns/rows
+
+ if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
+ nMergeTestEndX = MAXCOL;
+ if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
+ nMergeTestEndY = MAXROW;
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr() );
+
+ pDoc->ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndX, nMergeTestEndY, aMark, aPattern );
+
+ 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 ++;
+
+ ScRange aMergedRange( nExtendStartCol, nExtendStartRow, i, nMergeTestEndX, nMergeTestEndY, i+nScenarioCount );
+ pDoc->ExtendMerge( aMergedRange, TRUE );
+ }
+ }
+ }
+
+ for( i=0; i<nTabCount; i++ )
+ {
+ if( aMark.GetTableSelect( i ) )
+ {
+ if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
+ pDoc->UpdatePageBreaks( i );
+
+ rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );
+
+ SCTAB nScenarioCount = 0;
+
+ for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+ nScenarioCount ++;
+
+ // ganze Zeilen loeschen: nichts anpassen
+ if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount )) )
+ rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags, nExtFlags );
+ else
+ {
+ // paint only what is not done by AdjustRowHeight
+ if (nExtFlags & SC_PF_LINES)
+ lcl_PaintAbove( rDocShell, ScRange( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount) );
+ if (nPaintFlags & PAINT_TOP)
+ rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
+ }
+ }
+ }
+ aModificator.SetDocumentModified();
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
+ BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ SCCOL nStartCol = rSource.aStart.Col();
+ SCROW nStartRow = rSource.aStart.Row();
+ SCTAB nStartTab = rSource.aStart.Tab();
+ SCCOL nEndCol = rSource.aEnd.Col();
+ SCROW nEndRow = rSource.aEnd.Row();
+ SCTAB nEndTab = rSource.aEnd.Tab();
+ SCCOL nDestCol = rDestPos.Col();
+ SCROW nDestRow = rDestPos.Row();
+ SCTAB nDestTab = rDestPos.Tab();
+
+ if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) || !ValidRow(nDestRow) )
+ {
+ DBG_ERROR("invalid row in MoveBlock");
+ return FALSE;
+ }
+
+ // zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
+ BOOL bScenariosAdded = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nDestTab == nStartTab && !pDoc->IsScenario(nEndTab) )
+ while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) )
+ {
+ ++nEndTab;
+ bScenariosAdded = TRUE;
+ }
+
+ SCTAB nSrcTabCount = nEndTab-nStartTab+1;
+ SCTAB nDestEndTab = nDestTab+nSrcTabCount-1;
+ SCTAB nTab;
+
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+
+ ScMarkData aSourceMark;
+ for (nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aSourceMark.SelectTable( nTab, TRUE ); // Source selektieren
+ aSourceMark.SetMarkArea( rSource );
+
+ ScDocShellRef aDragShellRef;
+ if ( pDoc->HasOLEObjectsInArea( rSource ) )
+ {
+ aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
+ aDragShellRef->DoInitNew(NULL);
+ }
+ ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
+
+ ScClipParam aClipParam(ScRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0), bCut);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true);
+
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ SCCOL nOldEndCol = nEndCol;
+ SCROW nOldEndRow = nEndRow;
+ BOOL bClipOver = FALSE;
+ for (nTab=nStartTab; nTab<=nEndTab; nTab++)
+ {
+ SCCOL nTmpEndCol = nOldEndCol;
+ SCROW nTmpEndRow = nOldEndRow;
+ if (pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab ))
+ bClipOver = TRUE;
+ if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol;
+ if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow;
+ }
+
+ SCCOL nDestEndCol = nDestCol + ( nOldEndCol-nStartCol );
+ SCROW nDestEndRow = nDestRow + ( nOldEndRow-nStartRow );
+
+ SCCOL nUndoEndCol = nDestCol + ( nEndCol-nStartCol ); // erweitert im Zielblock
+ SCROW nUndoEndRow = nDestRow + ( nEndRow-nStartRow );
+
+ BOOL bIncludeFiltered = bCut;
+ if ( !bIncludeFiltered )
+ {
+ // adjust sizes to include only non-filtered rows
+
+ SCCOL nClipX;
+ SCROW nClipY;
+ pClipDoc->GetClipArea( nClipX, nClipY, FALSE );
+ SCROW nUndoAdd = nUndoEndRow - nDestEndRow;
+ nDestEndRow = nDestRow + nClipY;
+ nUndoEndRow = nDestEndRow + nUndoAdd;
+ }
+
+ if (!ValidCol(nUndoEndCol) || !ValidRow(nUndoEndRow))
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PASTE_FULL);
+ delete pClipDoc;
+ return FALSE;
+ }
+
+ // Test auf Zellschutz
+
+ ScEditableTester aTester;
+ for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
+ aTester.TestBlock( pDoc, nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow );
+ if (bCut)
+ for (nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aTester.TestBlock( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ delete pClipDoc;
+ return FALSE;
+ }
+
+ // Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
+
+ if (bClipOver && !bCut)
+ if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ { // "Zusammenfassen nicht verschachteln !"
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
+ delete pClipDoc;
+ return FALSE;
+ }
+
+ // Are there borders in the cells? (for painting)
+
+ USHORT nSourceExt = 0;
+ rDocShell.UpdatePaintExt( nSourceExt, nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab );
+ USHORT nDestExt = 0;
+ rDocShell.UpdatePaintExt( nDestExt, nDestCol,nDestRow,nDestTab, nDestEndCol,nDestEndRow,nDestEndTab );
+
+ //
+ // ausfuehren
+ //
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRefUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ BOOL bWholeCols = ( nStartRow == 0 && nEndRow == MAXROW );
+ BOOL bWholeRows = ( nStartCol == 0 && nEndCol == MAXCOL );
+ USHORT nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bWholeCols, bWholeRows );
+
+ if (bCut)
+ {
+ pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ nUndoFlags, FALSE, pUndoDoc );
+ pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE );
+ }
+
+ if ( nDestTab != nStartTab )
+ pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, bWholeCols, bWholeRows );
+ pDoc->CopyToDocument( nDestCol, nDestRow, nDestTab,
+ nDestEndCol, nDestEndRow, nDestEndTab,
+ nUndoFlags, FALSE, pUndoDoc );
+
+ pUndoData = new ScRefUndoData( pDoc );
+
+ pDoc->BeginDrawUndo();
+ }
+
+ BOOL bSourceHeight = FALSE; // Hoehen angepasst?
+ if (bCut)
+ {
+ ScMarkData aDelMark; // only for tables
+ for (nTab=nStartTab; nTab<=nEndTab; nTab++)
+ {
+ pDoc->DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, IDF_ALL );
+ aDelMark.SelectTable( nTab, TRUE );
+ }
+ pDoc->DeleteObjectsInArea( nStartCol,nStartRow, nOldEndCol,nOldEndRow, aDelMark );
+
+ // Test auf zusammengefasste
+
+ if (bClipOver)
+ if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab,
+ nUndoEndCol,nUndoEndRow,nDestEndTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ pDoc->CopyFromClip( rSource, aSourceMark, IDF_ALL, pRefUndoDoc, pClipDoc );
+ for (nTab=nStartTab; nTab<=nEndTab; nTab++)
+ {
+ SCCOL nTmpEndCol = nEndCol;
+ SCROW nTmpEndRow = nEndRow;
+ pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, TRUE );
+ }
+
+ // Fehlermeldung erst nach dem Wiederherstellen des Inhalts
+ if (!bApi) // "Zusammenfassen nicht verschachteln !"
+ rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
+
+ delete pUndoDoc;
+ delete pRefUndoDoc;
+ delete pUndoData;
+ delete pClipDoc;
+ return FALSE;
+ }
+
+ bSourceHeight = AdjustRowHeight( rSource, FALSE );
+ }
+
+ ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab );
+
+ ScMarkData aDestMark;
+ for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
+ aDestMark.SelectTable( nTab, TRUE ); // Destination selektieren
+ aDestMark.SetMarkArea( aPasteDest );
+
+ /* Do not copy cell notes and drawing objects here. While pasting, the
+ function ScDocument::UpdateReference() is called which calls
+ ScDrawLayer::MoveCells() which may move away inserted objects to wrong
+ positions (e.g. if source and destination range overlaps). Cell notes
+ and drawing objects are pasted below after doing all adjusting. */
+ pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS),
+ pRefUndoDoc, pClipDoc, TRUE, FALSE, bIncludeFiltered );
+
+ // skipped rows and merged cells don't mix
+ if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
+ UnmergeCells( aPasteDest, FALSE, TRUE );
+
+ VirtualDevice aVirtDev;
+ BOOL bDestHeight = AdjustRowHeight(
+ ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ),
+ FALSE );
+
+ /* 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.
+ #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_ADDNOTES | IDF_OBJECTS,
+ pRefUndoDoc, pClipDoc, TRUE, FALSE, bIncludeFiltered );
+
+ if (bRecord)
+ {
+ if (pRefUndoDoc)
+ {
+ // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
+ pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE );
+
+ pRefUndoDoc->DeleteArea( nDestCol, nDestRow, nDestEndCol, nDestEndRow, aSourceMark, IDF_ALL );
+ // kopieren mit bColRowFlags=FALSE (#54194#)
+ pRefUndoDoc->CopyToDocument( 0, 0, 0, MAXCOL, MAXROW, MAXTAB,
+ IDF_FORMULA, FALSE, pUndoDoc, NULL, FALSE );
+ delete pRefUndoDoc;
+ }
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDragDrop( &rDocShell, ScRange(
+ nStartCol, nStartRow, nStartTab,
+ nOldEndCol, nOldEndRow, nEndTab ),
+ ScAddress( nDestCol, nDestRow, nDestTab ),
+ bCut, pUndoDoc, pUndoData, bScenariosAdded ) );
+ }
+
+ SCCOL nDestPaintEndCol = nDestEndCol;
+ SCROW nDestPaintEndRow = nDestEndRow;
+ for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
+ {
+ SCCOL nTmpEndCol = nDestEndCol;
+ SCROW nTmpEndRow = nDestEndRow;
+ pDoc->ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, TRUE );
+ if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol;
+ if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow;
+ }
+
+ if (bCut)
+ for (nTab=nStartTab; nTab<=nEndTab; nTab++)
+ pDoc->RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+
+ if (bPaint)
+ {
+ // Zielbereich:
+
+ SCCOL nPaintStartX = nDestCol;
+ SCROW nPaintStartY = nDestRow;
+ SCCOL nPaintEndX = nDestPaintEndCol;
+ SCROW nPaintEndY = nDestPaintEndRow;
+ USHORT nFlags = PAINT_GRID;
+
+ if ( nStartRow==0 && nEndRow==MAXROW ) // Breiten mitkopiert?
+ {
+ nPaintEndX = MAXCOL;
+ nPaintStartY = 0;
+ nPaintEndY = MAXROW;
+ nFlags |= PAINT_TOP;
+ }
+ if ( bDestHeight || ( nStartCol == 0 && nEndCol == MAXCOL ) )
+ {
+ nPaintEndY = MAXROW;
+ nPaintStartX = 0;
+ nPaintEndX = MAXCOL;
+ nFlags |= PAINT_LEFT;
+ }
+ if ( bScenariosAdded )
+ {
+ nPaintStartX = 0;
+ nPaintStartY = 0;
+ nPaintEndX = MAXCOL;
+ nPaintEndY = MAXROW;
+ }
+
+ rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab,
+ nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nSourceExt | nDestExt );
+
+ if ( bCut )
+ {
+ // Quellbereich:
+
+ nPaintStartX = nStartCol;
+ nPaintStartY = nStartRow;
+ nPaintEndX = nEndCol;
+ nPaintEndY = nEndRow;
+ nFlags = PAINT_GRID;
+
+ if ( bSourceHeight )
+ {
+ nPaintEndY = MAXROW;
+ nPaintStartX = 0;
+ nPaintEndX = MAXCOL;
+ nFlags |= PAINT_LEFT;
+ }
+ if ( bScenariosAdded )
+ {
+ nPaintStartX = 0;
+ nPaintStartY = 0;
+ nPaintEndX = MAXCOL;
+ nPaintEndY = MAXROW;
+ }
+
+ rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab,
+ nPaintEndX,nPaintEndY,nEndTab, nFlags, nSourceExt );
+ }
+ }
+
+ aModificator.SetDocumentModified();
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+
+ delete pClipDoc;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, String& sCodeName )
+{
+ uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY);
+ uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
+ uno::Reference< uno::XInterface > xDocModuleApiObject;
+ if ( xSF.is() )
+ {
+ xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY );
+ xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY );
+ }
+ return xDocModuleApiObject;
+
+}
+
+script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule )
+{
+ script::ModuleInfo sModuleInfo;
+ sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
+ sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule );
+ return sModuleInfo;
+}
+
+void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sSource )
+{
+ SFX_APP()->EnterBasicCall();
+ SfxObjectShell& rDocSh = *rDoc.GetDocumentShell();
+ uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
+ DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+
+ uno::Reference< container::XNameContainer > xLib;
+ if( xLibContainer.is() )
+ {
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() )
+ aLibName = rDocSh.GetBasicManager()->GetName();
+ uno::Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+ if( xLib.is() )
+ {
+ // if the Module with codename exists then find a new name
+ sal_Int32 nNum = 0;
+ String genModuleName;
+ if ( sModuleName.Len() )
+ sModuleName = sModuleName;
+ else
+ {
+ genModuleName = String::CreateFromAscii( "Sheet1" );
+ nNum = 1;
+ }
+ while( xLib->hasByName( genModuleName ) )
+ genModuleName = rtl::OUString::createFromAscii( "Sheet" ) + rtl::OUString::valueOf( ++nNum );
+
+ uno::Any aSourceAny;
+ rtl::OUString sTmpSource = sSource;
+ if ( sTmpSource.getLength() == 0 )
+ sTmpSource = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" ));
+ aSourceAny <<= sTmpSource;
+ uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
+ if ( xVBAModuleInfo.is() )
+ {
+ String sCodeName( genModuleName );
+ rDoc.SetCodeName( nTab, sCodeName );
+ script::ModuleInfo sModuleInfo = lcl_InitModuleInfo( rDocSh, genModuleName );
+ xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo );
+ xLib->insertByName( genModuleName, aSourceAny );
+ }
+
+ }
+ SFX_APP()->LeaveBasicCall();
+}
+
+void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName )
+{
+ SFX_APP()->EnterBasicCall();
+ uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
+ DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+
+ uno::Reference< container::XNameContainer > xLib;
+ if( xLibContainer.is() )
+ {
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() )
+ aLibName = rDocSh.GetBasicManager()->GetName();
+ uno::Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+ if( xLib.is() )
+ {
+ uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
+ if( xLib->hasByName( sModuleName ) )
+ xLib->removeByName( sModuleName );
+ if ( xVBAModuleInfo.is() )
+ xVBAModuleInfo->removeModuleInfo( sModuleName );
+
+ }
+ SFX_APP()->LeaveBasicCall();
+}
+
+
+BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi )
+{
+ BOOL bSuccess = FALSE;
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+
+ // Strange loop, also basic is loaded too early ( InsertTable )
+ // is called via the xml import for sheets in described in odf
+ BOOL bInsertDocModule = false;
+
+ if( !rDocShell.GetDocument()->IsImportingXML() )
+ {
+ bInsertDocModule = pDoc ? pDoc->IsInVBAMode() : false;
+ }
+ if ( bInsertDocModule || ( bRecord && !pDoc->IsUndoEnabled() ) )
+ bRecord = FALSE;
+
+ if (bRecord)
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ BOOL bAppend = ( nTab >= nTabCount );
+ if ( bAppend )
+ nTab = nTabCount; // wichtig fuer Undo
+
+ if (pDoc->InsertTab( nTab, rName ))
+ {
+ String sCodeName;
+ if (bRecord)
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName));
+ // Views updaten:
+ // Only insert vba modules if vba mode ( and not currently importing XML )
+ if( bInsertDocModule )
+ {
+ String sSource;
+ VBA_InsertModule( *pDoc, nTab, sCodeName, sSource );
+ }
+ rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) );
+
+ rDocShell.PostPaintExtras();
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ bSuccess = TRUE;
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(STR_TABINSERT_ERROR);
+
+ return bSuccess;
+}
+
+BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ )
+{
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false;
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ if ( bVbaEnabled )
+ bRecord = FALSE;
+ BOOL bWasLinked = pDoc->IsLinked(nTab);
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nCount = pDoc->GetTableCount();
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); // nur nTab mit Flags
+ pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
+
+ pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pUndoDoc );
+ String aOldName;
+ pDoc->GetName( nTab, aOldName );
+ pUndoDoc->RenameTab( nTab, aOldName, FALSE );
+ if (bWasLinked)
+ pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
+ pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
+ pDoc->GetLinkTab(nTab),
+ pDoc->GetLinkRefreshDelay(nTab) );
+
+ if ( pDoc->IsScenario(nTab) )
+ {
+ pUndoDoc->SetScenario( nTab, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
+ pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
+ BOOL bActive = pDoc->IsActiveScenario( nTab );
+ pUndoDoc->SetActiveScenario( nTab, bActive );
+ }
+ pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
+ pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
+ pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
+
+ // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
+ pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+
+ String sCodeName;
+ BOOL bHasCodeName = pDoc->GetCodeName( nTab, sCodeName );
+ if (pDoc->DeleteTab( nTab, pUndoDoc ))
+ {
+ if (bRecord)
+ {
+ SvShorts theTabs;
+ theTabs.Insert(nTab,theTabs.Count());
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData ));
+ }
+ // Views updaten:
+ if( bVbaEnabled )
+ {
+ if( bHasCodeName )
+ {
+ VBA_DeleteModule( rDocShell, sCodeName );
+ }
+ }
+ rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) );
+
+ if (bWasLinked)
+ {
+ rDocShell.UpdateLinks(); // Link-Manager updaten
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate(SID_LINKS);
+ }
+
+ rDocShell.PostPaintExtras();
+ aModificator.SetDocumentModified();
+
+ SfxApplication* pSfxApp = SFX_APP(); // Navigator
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+
+ bSuccess = TRUE;
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pUndoData;
+ }
+ return bSuccess;
+}
+
+BOOL ScDocFunc::SetTableVisible( SCTAB nTab, BOOL bVisible, BOOL bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ if ( pDoc->IsVisible( nTab ) == bVisible )
+ return TRUE; // nichts zu tun - ok
+
+ if ( !pDoc->IsDocEditable() )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR);
+ return FALSE;
+ }
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ if ( !bVisible && !pDoc->IsImportingXML() ) // #i57869# allow hiding in any order for loading
+ {
+ // nicht alle Tabellen ausblenden
+
+ USHORT nVisCount = 0;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ if (pDoc->IsVisible(i))
+ ++nVisCount;
+
+ if (nVisCount <= 1)
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR); //! eigene Meldung?
+ return FALSE;
+ }
+ }
+
+ pDoc->SetVisible( nTab, bVisible );
+ if (bUndo)
+ rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell, nTab, bVisible ) );
+
+ // Views updaten:
+ if (!bVisible)
+ rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ rDocShell.PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL /* bApi */ )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ if ( pDoc->IsLayoutRTL( nTab ) == bRTL )
+ return TRUE; // nothing to do - ok
+
+ //! protection (sheet or document?)
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ pDoc->SetLayoutRTL( nTab, bRTL );
+
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell, nTab, bRTL ) );
+ }
+
+ rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_TAB_RTL );
+ pBindings->Invalidate( SID_ATTR_SIZE );
+ }
+
+ return TRUE;
+}
+
+//UNUSED2009-05 BOOL ScDocFunc::SetGrammar( formula::FormulaGrammar::Grammar eGrammar )
+//UNUSED2009-05 {
+//UNUSED2009-05 ScDocument* pDoc = rDocShell.GetDocument();
+//UNUSED2009-05
+//UNUSED2009-05 if ( pDoc->GetGrammar() == eGrammar )
+//UNUSED2009-05 return TRUE;
+//UNUSED2009-05
+//UNUSED2009-05 BOOL bUndo(pDoc->IsUndoEnabled());
+//UNUSED2009-05 ScDocShellModificator aModificator( rDocShell );
+//UNUSED2009-05
+//UNUSED2009-05 pDoc->SetGrammar( eGrammar );
+//UNUSED2009-05
+//UNUSED2009-05 if (bUndo)
+//UNUSED2009-05 {
+//UNUSED2009-05 rDocShell.GetUndoManager()->AddUndoAction( new ScUndoSetGrammar( &rDocShell, eGrammar ) );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
+//UNUSED2009-05
+//UNUSED2009-05 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+//UNUSED2009-05 if (NULL != pViewSh)
+//UNUSED2009-05 {
+//UNUSED2009-05 pViewSh->UpdateInputHandler( FALSE, FALSE );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 aModificator.SetDocumentModified();
+//UNUSED2009-05
+//UNUSED2009-05 SfxBindings* pBindings = rDocShell.GetViewBindings();
+//UNUSED2009-05 if (pBindings)
+//UNUSED2009-05 {
+//UNUSED2009-05 // erAck: 2006-09-07T22:19+0200 commented out in CWS scr1c1
+//UNUSED2009-05 //pBindings->Invalidate( FID_TAB_USE_R1C1 );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 return TRUE;
+//UNUSED2009-05 }
+
+BOOL ScDocFunc::RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ if ( !pDoc->IsDocEditable() )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR);
+ return FALSE;
+ }
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ String sOldName;
+ pDoc->GetName(nTab, sOldName);
+ if (pDoc->RenameTab( nTab, rName ))
+ {
+ if (bRecord)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoRenameTab( &rDocShell, nTab, sOldName, rName));
+ }
+ rDocShell.PostPaintExtras();
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+
+ bSuccess = TRUE;
+ }
+ return bSuccess;
+}
+
+bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi )
+{
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = false;
+ if ( !pDoc->IsDocEditable() || pDoc->IsTabProtected(nTab) )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is...
+ return false;
+ }
+
+ Color aOldTabBgColor;
+ aOldTabBgColor = pDoc->GetTabBgColor(nTab);
+
+ bool bSuccess = false;
+ pDoc->SetTabBgColor(nTab, rColor);
+ if ( pDoc->GetTabBgColor(nTab) == rColor)
+ bSuccess = true;
+ if (bSuccess)
+ {
+ if (bRecord)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor));
+ }
+ rDocShell.PostPaintExtras();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+
+ bSuccess = true;
+ }
+ return bSuccess;
+}
+
+bool ScDocFunc::SetTabBgColor(
+ ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = false;
+
+ if ( !pDoc->IsDocEditable() )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
+ return false;
+ }
+
+ USHORT nTab;
+ Color aNewTabBgColor;
+ bool bSuccess = true;
+ size_t nTabProtectCount = 0;
+ size_t nTabListCount = rUndoTabColorList.size();
+ for ( size_t i = 0; i < nTabListCount; ++i )
+ {
+ ScUndoTabColorInfo& rInfo = rUndoTabColorList[i];
+ nTab = rInfo.mnTabId;
+ if ( !pDoc->IsTabProtected(nTab) )
+ {
+ aNewTabBgColor = rInfo.maNewTabBgColor;
+ rInfo.maOldTabBgColor = pDoc->GetTabBgColor(nTab);
+ pDoc->SetTabBgColor(nTab, aNewTabBgColor);
+ if ( pDoc->GetTabBgColor(nTab) != aNewTabBgColor)
+ {
+ bSuccess = false;
+ break;
+ }
+ }
+ else
+ {
+ nTabProtectCount++;
+ }
+ }
+
+ if ( nTabProtectCount == nTabListCount )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
+ return false;
+ }
+
+ if (bSuccess)
+ {
+ if (bRecord)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabColor( &rDocShell, rUndoTabColorList));
+ }
+ rDocShell.PostPaintExtras();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+ }
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------
+
+//! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
+//! Probleme:
+//! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
+//! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
+
+USHORT lcl_GetOptimalColWidth( ScDocShell& rDocShell, SCCOL nCol, SCTAB nTab, BOOL bFormula )
+{
+ USHORT nTwips = 0;
+
+ ScSizeDeviceProvider aProv(&rDocShell);
+ OutputDevice* pDev = aProv.GetDevice(); // has pixel MapMode
+ double nPPTX = aProv.GetPPTX();
+ double nPPTY = aProv.GetPPTY();
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ Fraction aOne(1,1);
+ nTwips = pDoc->GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne,
+ bFormula, NULL );
+
+ return nTwips;
+}
+
+BOOL ScDocFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges, SCTAB nTab,
+ ScSizeMode eMode, USHORT nSizeTwips,
+ BOOL bRecord, BOOL bApi )
+{
+ if (!nRangeCnt)
+ return TRUE;
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if ( bRecord && !pDoc->IsUndoEnabled() )
+ bRecord = FALSE;
+
+ // import into read-only document is possible
+ if ( !pDoc->IsChangeReadOnlyEnabled() && !rDocShell.IsEditable() )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_PROTECTIONERR); //! eigene Meldung?
+ return FALSE;
+ }
+
+ BOOL bSuccess = FALSE;
+ SCCOLROW nStart = pRanges[0];
+ SCCOLROW nEnd = pRanges[2*nRangeCnt-1];
+
+ BOOL bFormula = FALSE;
+ if ( eMode == SC_SIZE_OPTIMAL )
+ {
+ //! Option "Formeln anzeigen" - woher nehmen?
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ SCCOLROW* pUndoRanges = NULL;
+
+ if ( bRecord )
+ {
+ pDoc->BeginDrawUndo(); // Drawing Updates
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ if (bWidth)
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab, static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+ else
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+ pDoc->CopyToDocument( 0, static_cast<SCROW>(nStart), nTab, MAXCOL, static_cast<SCROW>(nEnd), nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+
+ pUndoRanges = new SCCOLROW[ 2*nRangeCnt ];
+ memmove( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(SCCOLROW) );
+
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ pUndoTab = new ScOutlineTable( *pTable );
+ }
+
+ BOOL bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
+ BOOL bOutline = FALSE;
+
+ pDoc->IncSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln
+ for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nStartNo = *(pRanges++);
+ SCCOLROW nEndNo = *(pRanges++);
+
+ if ( !bWidth ) // Hoehen immer blockweise
+ {
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ {
+ BOOL bAll = ( eMode==SC_SIZE_OPTIMAL );
+ if (!bAll)
+ {
+ // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
+ // dann SetOptimalHeight mit bShrink = FALSE
+ for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++)
+ {
+ BYTE nOld = pDoc->GetRowFlags(nRow,nTab);
+ SCROW nLastRow = -1;
+ bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow);
+ if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
+ pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
+ }
+ }
+
+ ScSizeDeviceProvider aProv( &rDocShell );
+ Fraction aOne(1,1);
+ pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
+ aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, bAll );
+
+ if (bAll)
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, TRUE );
+
+ // Manual-Flag wird bei bAll=TRUE schon in SetOptimalHeight gesetzt
+ // (an bei Extra-Height, sonst aus).
+ }
+ else if ( eMode==SC_SIZE_DIRECT || eMode==SC_SIZE_ORIGINAL )
+ {
+ if (nSizeTwips)
+ {
+ pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
+ pDoc->SetManualHeight( nStartNo, nEndNo, nTab, TRUE ); // height was set manually
+ }
+ if ( eMode != SC_SIZE_ORIGINAL )
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
+ }
+ else if ( eMode==SC_SIZE_SHOW )
+ {
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, TRUE );
+ }
+ }
+ else // Spaltenbreiten
+ {
+ for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
+ {
+ SCCOL nLastCol = -1;
+ if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab, nLastCol) )
+ {
+ USHORT nThisSize = nSizeTwips;
+
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ nThisSize = nSizeTwips +
+ lcl_GetOptimalColWidth( rDocShell, nCol, nTab, bFormula );
+ if ( nThisSize )
+ pDoc->SetColWidth( nCol, nTab, nThisSize );
+
+ if ( eMode != SC_SIZE_ORIGINAL )
+ pDoc->ShowCol( nCol, nTab, bShow );
+ }
+ }
+ }
+
+ // adjust outlines
+
+ if ( eMode != SC_SIZE_ORIGINAL )
+ {
+ if (bWidth)
+ bOutline = bOutline || pDoc->UpdateOutlineCol(
+ static_cast<SCCOL>(nStartNo),
+ static_cast<SCCOL>(nEndNo), nTab, bShow );
+ else
+ bOutline = bOutline || pDoc->UpdateOutlineRow(
+ static_cast<SCROW>(nStartNo),
+ static_cast<SCROW>(nEndNo), nTab, bShow );
+ }
+ }
+ pDoc->DecSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln
+
+ if (!bOutline)
+ DELETEZ(pUndoTab);
+
+ if (bRecord)
+ {
+ ScMarkData aMark;
+ aMark.SelectOneTable( nTab );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoWidthOrHeight( &rDocShell, aMark,
+ nStart, nTab, nEnd, nTab,
+ pUndoDoc, nRangeCnt, pUndoRanges,
+ pUndoTab, eMode, nSizeTwips, bWidth ) );
+ }
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ rDocShell.PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_ALL);
+
+ return bSuccess;
+}
+
+
+BOOL ScDocFunc::InsertPageBreak( BOOL bColumn, const ScAddress& rPos,
+ BOOL bRecord, BOOL bSetModified, BOOL /* bApi */ )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ SCTAB nTab = rPos.Tab();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+
+ SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
+ static_cast<SCCOLROW>(rPos.Row());
+ if (nPos == 0)
+ return FALSE; // erste Spalte / Zeile
+
+ ScBreakType nBreak = bColumn ?
+ pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) :
+ pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
+ if (nBreak & BREAK_MANUAL)
+ return true;
+
+ if (bRecord)
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, TRUE ) );
+
+ if (bColumn)
+ pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
+ else
+ pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
+
+ pDoc->InvalidatePageBreaks(nTab);
+ pDoc->UpdatePageBreaks( nTab );
+
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ if (bColumn)
+ {
+ rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_INS_COLBRK );
+ pBindings->Invalidate( FID_DEL_COLBRK );
+ }
+ }
+ else
+ {
+ rDocShell.PostPaint( 0, static_cast<SCROW>(nPos)-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_INS_ROWBRK );
+ pBindings->Invalidate( FID_DEL_ROWBRK );
+ }
+ }
+ if (pBindings)
+ pBindings->Invalidate( FID_DEL_MANUALBREAKS );
+
+ if (bSetModified)
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
+ BOOL bRecord, BOOL bSetModified, BOOL /* bApi */ )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ SCTAB nTab = rPos.Tab();
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+
+ SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
+ static_cast<SCCOLROW>(rPos.Row());
+
+ ScBreakType nBreak;
+ if (bColumn)
+ nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab);
+ else
+ nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
+ if ((nBreak & BREAK_MANUAL) == 0)
+ // There is no manual break.
+ return false;
+
+ if (bRecord)
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, FALSE ) );
+
+ if (bColumn)
+ pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
+ else
+ pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ if (bColumn)
+ {
+ rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_INS_COLBRK );
+ pBindings->Invalidate( FID_DEL_COLBRK );
+ }
+ }
+ else
+ {
+ rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_INS_ROWBRK );
+ pBindings->Invalidate( FID_DEL_ROWBRK );
+ }
+ }
+ if (pBindings)
+ pBindings->Invalidate( FID_DEL_MANUALBREAKS );
+
+ if (bSetModified)
+ aModificator.SetDocumentModified();
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ pDoc->SetTabProtection(nTab, &rProtect);
+ 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.
+ }
+ }
+
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator(rDocShell);
+ aModificator.SetDocumentModified();
+}
+
+BOOL ScDocFunc::Protect( SCTAB nTab, const String& rPassword, BOOL /*bApi*/ )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (nTab == TABLEID_DOC)
+ {
+ // document protection
+ ScDocProtection aProtection;
+ aProtection.setProtected(true);
+ aProtection.setPassword(rPassword);
+ pDoc->SetDocProtection(&aProtection);
+ if (pDoc->IsUndoEnabled())
+ {
+ 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.
+ }
+ }
+ }
+ else
+ {
+ // sheet protection
+
+ 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.
+ }
+ }
+ }
+
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+
+ return true;
+}
+
+BOOL ScDocFunc::Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ 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))
+ {
+ if (!bApi)
+ {
+ InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ return false;
+ }
+
+ 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
+ {
+ // 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;
+ }
+
+ 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.
+ }
+ }
+
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+
+ return true;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::ClearItems( const ScMarkData& rMark, const USHORT* pWhich, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ ScEditableTester aTester( pDoc, rMark );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ // #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
+ // MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
+ // here.
+
+ ScRange aMarkRange;
+ ScMarkData aMultiMark = rMark;
+ aMultiMark.SetMarking(FALSE); // for MarkToMulti
+ aMultiMark.MarkToMulti();
+ aMultiMark.GetMultiMarkArea( aMarkRange );
+
+// if (bRecord)
+ if (bUndo)
+ {
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ pDoc->CopyToDocument( aMarkRange, IDF_ATTRIB, TRUE, pUndoDoc, (ScMarkData*)&aMultiMark );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoClearItems( &rDocShell, aMultiMark, pUndoDoc, pWhich ) );
+ }
+
+ pDoc->ClearSelectionItems( pWhich, aMultiMark );
+
+ rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+ aModificator.SetDocumentModified();
+
+ //! Bindings-Invalidate etc.?
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::ChangeIndent( const ScMarkData& rMark, BOOL bIncrement, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ ScEditableTester aTester( pDoc, rMark );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ ScRange aMarkRange;
+ rMark.GetMultiMarkArea( aMarkRange );
+
+// if (bRecord)
+ if (bUndo)
+ {
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ 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 );
+
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pUndoDoc, (ScMarkData*)&rMark );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoIndent( &rDocShell, rMark, pUndoDoc, bIncrement ) );
+ }
+
+ pDoc->ChangeSelectionIndent( bIncrement, rMark );
+
+ rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_ALIGNLEFT ); // ChangeIndent setzt auf links
+ pBindings->Invalidate( SID_ALIGNRIGHT );
+ pBindings->Invalidate( SID_ALIGNBLOCK );
+ pBindings->Invalidate( SID_ALIGNCENTERHOR );
+ // pseudo slots for Format menu
+ pBindings->Invalidate( SID_ALIGN_ANY_HDEFAULT );
+ pBindings->Invalidate( SID_ALIGN_ANY_LEFT );
+ pBindings->Invalidate( SID_ALIGN_ANY_HCENTER );
+ pBindings->Invalidate( SID_ALIGN_ANY_RIGHT );
+ pBindings->Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+ }
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
+ USHORT nFormatNo, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aMark.SelectTable( nTab, TRUE );
+ }
+
+ ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
+ ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
+ if ( pAutoFormat && nFormatNo < pAutoFormat->GetCount() && aTester.IsEditable() )
+ {
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ BOOL bSize = (*pAutoFormat)[nFormatNo]->GetIncludeWidthHeight();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab, bSize, bSize );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nStartTab && aMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i, bSize, bSize );
+
+ ScRange aCopyRange = rRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aStart.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, FALSE, pUndoDoc, &aMark );
+ if (bSize)
+ {
+ pDoc->CopyToDocument( nStartCol,0,0, nEndCol,MAXROW,nTabCount-1,
+ IDF_NONE, FALSE, pUndoDoc, &aMark );
+ pDoc->CopyToDocument( 0,nStartRow,0, MAXCOL,nEndRow,nTabCount-1,
+ IDF_NONE, FALSE, pUndoDoc, &aMark );
+ }
+ pDoc->BeginDrawUndo();
+ }
+
+ pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark );
+
+ if (bSize)
+ {
+/* SCCOL nCols[2];
+ nCols[0] = nStartCol;
+ nCols[1] = nEndCol;
+ SCROW nRows[2];
+ nRows[0] = nStartRow;
+ nRows[1] = nEndRow;
+*/
+ SCCOLROW nCols[2] = { nStartCol, nEndCol };
+ SCCOLROW nRows[2] = { nStartRow, nEndRow };
+
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aMark.GetTableSelect(nTab))
+ {
+ SetWidthOrHeight( TRUE, 1,nCols, nTab, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, FALSE, TRUE);
+ SetWidthOrHeight( FALSE,1,nRows, nTab, SC_SIZE_VISOPT, 0, FALSE, FALSE);
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP );
+ }
+ }
+ else
+ {
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aMark.GetTableSelect(nTab))
+ {
+ BOOL bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, nTab,
+ nEndCol, nEndRow, nTab), FALSE );
+ if (bAdj)
+ rDocShell.PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT );
+ else
+ rDocShell.PostPaint( nStartCol, nStartRow, nTab,
+ nEndCol, nEndRow, nTab, PAINT_GRID );
+ }
+ }
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFormat( &rDocShell, rRange, pUndoDoc, aMark, bSize, nFormatNo ) );
+ }
+
+ aModificator.SetDocumentModified();
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
+ const ScTokenArray* pTokenArray, const String& rString, BOOL bApi, BOOL bEnglish,
+ const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aMark.SelectTable( nTab, TRUE );
+ }
+
+ ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
+ if ( aTester.IsEditable() )
+ {
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ ScDocument* pUndoDoc = NULL;
+// if (bRecord) // immer
+ if (bUndo)
+ {
+ //! auch bei Undo selektierte Tabellen beruecksichtigen
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, FALSE, pUndoDoc );
+ }
+
+ // use TokenArray if given, string (and flags) otherwise
+ if ( pTokenArray )
+ {
+ pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
+ aMark, EMPTY_STRING, pTokenArray, eGrammar);
+ }
+ else if ( pDoc->IsImportingXML() )
+ {
+ ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
+ pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
+ aMark, EMPTY_STRING, pCode, eGrammar);
+ delete pCode;
+ pDoc->IncXMLImportedFormulaCount( rString.Len() );
+ }
+ else if (bEnglish)
+ {
+ ScCompiler aComp( pDoc, rRange.aStart);
+ aComp.SetGrammar(eGrammar);
+ ScTokenArray* pCode = aComp.CompileString( rString );
+ pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
+ aMark, EMPTY_STRING, pCode, eGrammar);
+ delete pCode;
+ }
+ else
+ pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
+ aMark, rString, NULL, eGrammar);
+
+// if (bRecord) // immer
+ if (bUndo)
+ {
+ //! auch bei Undo selektierte Tabellen beruecksichtigen
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoEnterMatrix( &rDocShell, rRange, pUndoDoc, rString ) );
+ }
+
+ // Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
+ rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PAINT_GRID );
+ aModificator.SetDocumentModified();
+
+ bSuccess = TRUE;
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
+ const ScTabOpParam& rParam, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aMark.SelectTable( nTab, TRUE );
+ }
+
+ ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
+ if ( aTester.IsEditable() )
+ {
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+ pDoc->SetDirty( rRange );
+ if ( bRecord )
+ {
+ //! auch bei Undo selektierte Tabellen beruecksichtigen
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, FALSE, pUndoDoc );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabOp( &rDocShell,
+ nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab, pUndoDoc,
+ rParam.aRefFormulaCell,
+ rParam.aRefFormulaEnd,
+ rParam.aRefRowCell,
+ rParam.aRefColCell,
+ rParam.nMode) );
+ }
+ pDoc->InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark);
+ rDocShell.PostPaintGridAll();
+ aModificator.SetDocumentModified();
+ bSuccess = TRUE;
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------
+
+inline ScDirection DirFromFillDir( FillDir eDir )
+{
+ if (eDir==FILL_TO_BOTTOM)
+ return DIR_BOTTOM;
+ else if (eDir==FILL_TO_RIGHT)
+ return DIR_RIGHT;
+ else if (eDir==FILL_TO_TOP)
+ return DIR_TOP;
+ else // if (eDir==FILL_TO_LEFT)
+ return DIR_LEFT;
+}
+
+BOOL ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
+ FillDir eDir, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aMark.SelectTable( nTab, TRUE );
+ }
+
+ ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
+ if ( aTester.IsEditable() )
+ {
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ ScRange aSourceArea = rRange;
+ ScRange aDestArea = rRange;
+
+ SCCOLROW nCount = 0;
+ switch (eDir)
+ {
+ case FILL_TO_BOTTOM:
+ nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
+ aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() );
+ break;
+ case FILL_TO_RIGHT:
+ nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
+ aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() );
+ break;
+ case FILL_TO_TOP:
+ nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
+ aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() );
+ break;
+ case FILL_TO_LEFT:
+ nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
+ aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() );
+ break;
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nDestStartTab = aDestArea.aStart.Tab();
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nDestStartTab && aMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange = aDestArea;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
+ }
+
+ pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
+ aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
+ nCount, eDir, FILL_SIMPLE );
+ AdjustRowHeight(rRange);
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
+ eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307,
+ pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
+ }
+
+ rDocShell.PostPaintGridAll();
+// rDocShell.PostPaintDataChanged();
+ aModificator.SetDocumentModified();
+
+ bSuccess = TRUE;
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+
+ return bSuccess;
+}
+
+BOOL ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
+ FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
+ double fStart, double fStep, double fMax,
+ BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aMark.SelectTable( nTab, TRUE );
+ }
+
+ ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
+ if ( aTester.IsEditable() )
+ {
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ ScRange aSourceArea = rRange;
+ ScRange aDestArea = rRange;
+
+ SCSIZE nCount = pDoc->GetEmptyLinesInBlock(
+ aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
+ aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
+ DirFromFillDir(eDir) );
+
+ // #27665# mindestens eine Zeile/Spalte als Quellbereich behalten:
+ SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
+ static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
+ static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
+ if ( nCount >= nTotLines )
+ nCount = nTotLines - 1;
+
+ switch (eDir)
+ {
+ case FILL_TO_BOTTOM:
+ aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
+ break;
+ case FILL_TO_RIGHT:
+ aSourceArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() - nCount ) );
+ break;
+ case FILL_TO_TOP:
+ aSourceArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() + nCount ) );
+ break;
+ case FILL_TO_LEFT:
+ aSourceArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() + nCount ) );
+ break;
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nDestStartTab = aDestArea.aStart.Tab();
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nDestStartTab && aMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ pDoc->CopyToDocument(
+ aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
+ aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
+ IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
+ }
+
+ if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
+ aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
+ {
+ if ( fStart != MAXDOUBLE )
+ {
+ SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
+ SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
+ SCTAB nTab = aDestArea.aStart.Tab();
+ pDoc->SetValue( nValX, nValY, nTab, fStart );
+ }
+ pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
+ aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
+ nCount, eDir, eCmd, eDateCmd, fStep, fMax );
+ AdjustRowHeight(rRange);
+
+ rDocShell.PostPaintGridAll();
+// rDocShell.PostPaintDataChanged();
+ aModificator.SetDocumentModified();
+ }
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
+ eDir, eCmd, eDateCmd, fStart, fStep, fMax,
+ pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
+ }
+
+ bSuccess = TRUE;
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+
+ return bSuccess;
+}
+
+BOOL ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
+ FillDir eDir, ULONG nCount, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScMarkData aMark;
+ if (pTabMark)
+ aMark = *pTabMark;
+ else
+ {
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ aMark.SelectTable( nTab, TRUE );
+ }
+
+ ScRange aSourceArea = rRange;
+ ScRange aDestArea = rRange;
+
+ FillCmd eCmd = FILL_AUTO;
+ FillDateCmd eDateCmd = FILL_DAY;
+ double fStep = 1.0;
+ double fMax = MAXDOUBLE;
+
+ switch (eDir)
+ {
+ case FILL_TO_BOTTOM:
+ aDestArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() + nCount ) );
+ break;
+ case FILL_TO_TOP:
+ if (nCount > sal::static_int_cast<ULONG>( aSourceArea.aStart.Row() ))
+ {
+ DBG_ERROR("FillAuto: Row < 0");
+ nCount = aSourceArea.aStart.Row();
+ }
+ aDestArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() - nCount ) );
+ break;
+ case FILL_TO_RIGHT:
+ aDestArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() + nCount ) );
+ break;
+ case FILL_TO_LEFT:
+ if (nCount > sal::static_int_cast<ULONG>( aSourceArea.aStart.Col() ))
+ {
+ DBG_ERROR("FillAuto: Col < 0");
+ nCount = aSourceArea.aStart.Col();
+ }
+ aDestArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() - nCount ) );
+ break;
+ default:
+ DBG_ERROR("Falsche Richtung bei FillAuto");
+ break;
+ }
+
+ // Zellschutz testen
+ //! Quellbereich darf geschuetzt sein !!!
+ //! aber kein Matrixfragment enthalten !!!
+
+ ScEditableTester aTester( pDoc, aDestArea );
+ if ( !aTester.IsEditable() )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ if ( pDoc->HasSelectedBlockMatrixFragment( nStartCol, nStartRow,
+ nEndCol, nEndRow, aMark ) )
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MATRIXFRAGMENTERR);
+ return FALSE;
+ }
+
+ WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nDestStartTab = aDestArea.aStart.Tab();
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nDestStartTab && aMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ // do not clone note captions in undo document
+ pDoc->CopyToDocument(
+ aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
+ aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
+ IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
+ }
+
+ pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
+ aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
+ nCount, eDir, eCmd, eDateCmd, fStep, fMax );
+
+ AdjustRowHeight(aDestArea);
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
+ eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax,
+ pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
+ }
+
+ rDocShell.PostPaintGridAll();
+// rDocShell.PostPaintDataChanged();
+ aModificator.SetDocumentModified();
+
+ rRange = aDestArea; // Zielbereich zurueckgeben (zum Markieren)
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::MergeCells( const ScRange& rRange, BOOL bContents, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ if (!aTester.IsEditable())
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ if ( nStartCol == nEndCol && nStartRow == nEndRow )
+ {
+ // nichts zu tun
+ return TRUE;
+ }
+
+ if ( pDoc->HasAttrib( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ // "Zusammenfassen nicht verschachteln !"
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
+ return FALSE;
+ }
+
+ BOOL bNeedContents = bContents &&
+ ( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
+ !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );
+
+ ScDocument* pUndoDoc = 0;
+ if (bRecord)
+ {
+ // test if the range contains other notes which also implies that we need an undo document
+ bool bHasNotes = false;
+ for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
+ for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
+ bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNote( aPos ) != 0);
+
+ if (bNeedContents || bHasNotes)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ // note captions are collected by drawing undo
+ pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+ IDF_ALL|IDF_NOCAPTIONS, FALSE, pUndoDoc );
+ }
+ if( bHasNotes )
+ pDoc->BeginDrawUndo();
+ }
+
+ if (bNeedContents)
+ pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+ pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+
+ if( bRecord )
+ {
+ SdrUndoGroup* pDrawUndo = pDoc->GetDrawLayer() ? pDoc->GetDrawLayer()->GetCalcUndo() : 0;
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoMerge( &rDocShell,
+ nStartCol, nStartRow, nTab,
+ nEndCol, nEndRow, nTab, bNeedContents, pUndoDoc, pDrawUndo ) );
+ }
+
+ if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
+ rDocShell.PostPaint( nStartCol, nStartRow, nTab,
+ nEndCol, nEndRow, nTab, PAINT_GRID );
+ if (bNeedContents)
+ pDoc->SetDirty( rRange );
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_MERGE_ON );
+ pBindings->Invalidate( FID_MERGE_OFF );
+ pBindings->Invalidate( FID_MERGE_TOGGLE );
+ }
+
+ return TRUE;
+}
+
+BOOL ScDocFunc::UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ if ( pDoc->HasAttrib( rRange, HASATTR_MERGED ) )
+ {
+ ScRange aExtended = rRange;
+ pDoc->ExtendMerge( aExtended );
+ ScRange aRefresh = aExtended;
+ pDoc->ExtendOverlapped( aRefresh );
+
+ if (bRecord)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( aExtended, IDF_ATTRIB, FALSE, pUndoDoc );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveMerge( &rDocShell, rRange, pUndoDoc ) );
+ }
+
+ const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( rDefAttr );
+ pDoc->ApplyPatternAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), nTab,
+ aPattern );
+
+ pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
+ aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
+ SC_MF_HOR | SC_MF_VER );
+
+ pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
+
+ if ( !AdjustRowHeight( aExtended ) )
+ rDocShell.PostPaint( aExtended, PAINT_GRID );
+ aModificator.SetDocumentModified();
+ }
+ else if (!bApi)
+ Sound::Beep(); //! FALSE zurueck???
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, BOOL bApi )
+{
+ return SetNewRangeNames( new ScRangeName( rNewRanges ), bApi );
+}
+
+BOOL ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, BOOL /* bApi */ ) // takes ownership of pNewRanges
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+ DBG_ASSERT( pNewRanges, "pNewRanges is 0" );
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if (bUndo)
+ {
+ ScRangeName* pOld = pDoc->GetRangeName();
+ ScRangeName* pUndoRanges = new ScRangeName(*pOld);
+ ScRangeName* pRedoRanges = new ScRangeName(*pNewRanges);
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoRangeNames( &rDocShell, pUndoRanges, pRedoRanges ) );
+ }
+
+ // #i55926# While loading XML, formula cells only have a single string token,
+ // so CompileNameFormula would never find any name (index) tokens, and would
+ // unnecessarily loop through all cells.
+ BOOL bCompile = ( !pDoc->IsImportingXML() && pDoc->GetNamedRangesLockCount() == 0 );
+
+ if ( bCompile )
+ pDoc->CompileNameFormula( TRUE ); // CreateFormulaString
+ pDoc->SetRangeName( pNewRanges ); // takes ownership
+ if ( bCompile )
+ pDoc->CompileNameFormula( FALSE ); // CompileFormulaString
+
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+void ScDocFunc::CreateOneName( ScRangeName& rList,
+ SCCOL nPosX, SCROW nPosY, SCTAB nTab,
+ SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ BOOL& rCancel, BOOL bApi )
+{
+ if (rCancel)
+ return;
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (!pDoc->HasValueData( nPosX, nPosY, nTab ))
+ {
+ String aName;
+ pDoc->GetString( nPosX, nPosY, nTab, aName );
+ ScRangeData::MakeValidName(aName);
+ if (aName.Len())
+ {
+ String aContent;
+ ScRange( nX1, nY1, nTab, nX2, nY2, nTab ).Format( aContent, SCR_ABS_3D, pDoc );
+
+ BOOL bInsert = FALSE;
+ USHORT nOldPos;
+ if (rList.SearchName( aName, nOldPos )) // vorhanden ?
+ {
+ ScRangeData* pOld = rList[nOldPos];
+ String aOldStr;
+ pOld->GetSymbol( aOldStr );
+ if (aOldStr != aContent)
+ {
+ if (bApi)
+ bInsert = TRUE; // per API nicht nachfragen
+ else
+ {
+ String aTemplate = ScGlobal::GetRscString( STR_CREATENAME_REPLACE );
+
+ String aMessage = aTemplate.GetToken( 0, '#' );
+ aMessage += aName;
+ aMessage += aTemplate.GetToken( 1, '#' );
+
+ short nResult = QueryBox( rDocShell.GetActiveDialogParent(),
+ WinBits(WB_YES_NO_CANCEL | WB_DEF_YES),
+ aMessage ).Execute();
+ if ( nResult == RET_YES )
+ {
+ rList.AtFree(nOldPos);
+ bInsert = TRUE;
+ }
+ else if ( nResult == RET_CANCEL )
+ rCancel = TRUE;
+ }
+ }
+ }
+ else
+ bInsert = TRUE;
+
+ if (bInsert)
+ {
+ ScRangeData* pData = new ScRangeData( pDoc, aName, aContent,
+ ScAddress( nPosX, nPosY, nTab));
+ if (!rList.Insert(pData))
+ {
+ DBG_ERROR("nanu?");
+ delete pData;
+ }
+ }
+ }
+ }
+}
+
+BOOL ScDocFunc::CreateNames( const ScRange& rRange, USHORT nFlags, BOOL bApi )
+{
+ if (!nFlags)
+ return FALSE; // war nix
+
+ ScDocShellModificator aModificator( rDocShell );
+
+ BOOL bDone = FALSE;
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+ DBG_ASSERT(rRange.aEnd.Tab() == nTab, "CreateNames: mehrere Tabellen geht nicht");
+
+ BOOL bValid = TRUE;
+ if ( nFlags & ( NAME_TOP | NAME_BOTTOM ) )
+ if ( nStartRow == nEndRow )
+ bValid = FALSE;
+ if ( nFlags & ( NAME_LEFT | NAME_RIGHT ) )
+ if ( nStartCol == nEndCol )
+ bValid = FALSE;
+
+ if (bValid)
+ {
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScRangeName* pNames = pDoc->GetRangeName();
+ if (!pNames)
+ return FALSE; // soll nicht sein
+ ScRangeName aNewRanges( *pNames );
+
+ BOOL bTop = ( ( nFlags & NAME_TOP ) != 0 );
+ BOOL bLeft = ( ( nFlags & NAME_LEFT ) != 0 );
+ BOOL bBottom = ( ( nFlags & NAME_BOTTOM ) != 0 );
+ BOOL bRight = ( ( nFlags & NAME_RIGHT ) != 0 );
+
+ SCCOL nContX1 = nStartCol;
+ SCROW nContY1 = nStartRow;
+ SCCOL nContX2 = nEndCol;
+ SCROW nContY2 = nEndRow;
+
+ if ( bTop )
+ ++nContY1;
+ if ( bLeft )
+ ++nContX1;
+ if ( bBottom )
+ --nContY2;
+ if ( bRight )
+ --nContX2;
+
+ BOOL bCancel = FALSE;
+ SCCOL i;
+ SCROW j;
+
+ if ( bTop )
+ for (i=nContX1; i<=nContX2; i++)
+ CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
+ if ( bLeft )
+ for (j=nContY1; j<=nContY2; j++)
+ CreateOneName( aNewRanges, nStartCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
+ if ( bBottom )
+ for (i=nContX1; i<=nContX2; i++)
+ CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
+ if ( bRight )
+ for (j=nContY1; j<=nContY2; j++)
+ CreateOneName( aNewRanges, nEndCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
+
+ if ( bTop && bLeft )
+ CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
+ if ( bTop && bRight )
+ CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
+ if ( bBottom && bLeft )
+ CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
+ if ( bBottom && bRight )
+ CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
+
+ bDone = ModifyRangeNames( aNewRanges, bApi );
+
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+ }
+
+ return bDone;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::InsertNameList( const ScAddress& rStartPos, BOOL bApi )
+{
+ ScDocShellModificator aModificator( rDocShell );
+
+
+ BOOL bDone = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+ const BOOL bRecord = pDoc->IsUndoEnabled();
+ SCTAB nTab = rStartPos.Tab();
+ ScDocument* pUndoDoc = NULL;
+
+ ScRangeName* pList = pDoc->GetRangeName();
+ USHORT nCount = pList->GetCount();
+ USHORT nValidCount = 0;
+ USHORT i;
+ for (i=0; i<nCount; i++)
+ {
+ ScRangeData* pData = (*pList)[i];
+ if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) )
+ ++nValidCount;
+ }
+
+ if (nValidCount)
+ {
+ SCCOL nStartCol = rStartPos.Col();
+ SCROW nStartRow = rStartPos.Row();
+ SCCOL nEndCol = nStartCol + 1;
+ SCROW nEndRow = nStartRow + static_cast<SCROW>(nValidCount) - 1;
+
+ ScEditableTester aTester( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+ if (aTester.IsEditable())
+ {
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+ IDF_ALL, FALSE, pUndoDoc );
+
+ pDoc->BeginDrawUndo(); // wegen Hoehenanpassung
+ }
+
+ ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
+ USHORT j = 0;
+ for (i=0; i<nCount; i++)
+ {
+ ScRangeData* pData = (*pList)[i];
+ if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) )
+ ppSortArray[j++] = pData;
+ }
+#ifndef ICC
+ qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
+ &ScRangeData_QsortNameCompare );
+#else
+ qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
+ ICCQsortNameCompare );
+#endif
+ String aName;
+ rtl::OUStringBuffer aContent;
+ String aFormula;
+ SCROW nOutRow = nStartRow;
+ for (j=0; j<nValidCount; j++)
+ {
+ ScRangeData* pData = ppSortArray[j];
+ pData->GetName(aName);
+ // relative Referenzen Excel-konform auf die linke Spalte anpassen:
+ pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab ));
+ aFormula = '=';
+ aFormula += aContent;
+ pDoc->PutCell( nStartCol,nOutRow,nTab, new ScStringCell( aName ) );
+ pDoc->PutCell( nEndCol ,nOutRow,nTab, new ScStringCell( aFormula ) );
+ ++nOutRow;
+ }
+
+ delete [] ppSortArray;
+
+ if (bRecord)
+ {
+ ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+ IDF_ALL, FALSE, pRedoDoc );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoListNames( &rDocShell,
+ ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ),
+ pUndoDoc, pRedoDoc ) );
+ }
+
+ if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,MAXCOL,nEndRow,nTab)))
+ rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PAINT_GRID );
+//! rDocShell.UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ bDone = TRUE;
+ }
+ else if (!bApi)
+ rDocShell.ErrorMessage(aTester.GetMessageId());
+ }
+ return bDone;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCCOL nStartCol = rOldRange.aStart.Col();
+ SCROW nStartRow = rOldRange.aStart.Row();
+ SCTAB nTab = rOldRange.aStart.Tab();
+
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ BOOL bRet = FALSE;
+
+ String aFormula;
+ pDoc->GetFormula( nStartCol, nStartRow, nTab, aFormula );
+ if ( aFormula.GetChar(0) == '{' && aFormula.GetChar(aFormula.Len()-1) == '}' )
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX );
+ if (bUndo)
+ rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ aFormula.Erase(0,1);
+ aFormula.Erase(aFormula.Len()-1,1);
+
+ ScMarkData aMark;
+ aMark.SetMarkArea( rOldRange );
+ aMark.SelectTable( nTab, TRUE );
+ ScRange aNewRange( rOldRange.aStart, rNewEnd );
+
+ if ( DeleteContents( aMark, IDF_CONTENTS, TRUE, bApi ) )
+ {
+ // GRAM_PODF_A1 for API compatibility.
+ 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, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
+ }
+ }
+
+ if (bUndo)
+ rDocShell.GetUndoManager()->LeaveListAction();
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScDocFunc::InsertAreaLink( const String& rFile, const String& rFilter,
+ const String& rOptions, const String& rSource,
+ const ScRange& rDestRange, ULONG nRefresh,
+ BOOL bFitBlock, BOOL bApi )
+{
+ //! auch fuer ScViewFunc::InsertAreaLink benutzen!
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ // #i52120# if other area links exist at the same start position,
+ // remove them first (file format specifies only one link definition
+ // for a cell)
+
+ USHORT nLinkCount = pLinkManager->GetLinks().Count();
+ USHORT nRemoved = 0;
+ USHORT nLinkPos = 0;
+ while (nLinkPos<nLinkCount)
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[nLinkPos];
+ if ( pBase->ISA(ScAreaLink) &&
+ static_cast<ScAreaLink*>(pBase)->GetDestArea().aStart == rDestRange.aStart )
+ {
+ if ( bUndo )
+ {
+ if ( !nRemoved )
+ {
+ // group all remove and the insert action
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
+ rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ ScAreaLink* pOldArea = static_cast<ScAreaLink*>(pBase);
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveAreaLink( &rDocShell,
+ pOldArea->GetFile(), pOldArea->GetFilter(), pOldArea->GetOptions(),
+ pOldArea->GetSource(), pOldArea->GetDestArea(), pOldArea->GetRefreshDelay() ) );
+ }
+ pLinkManager->Remove( pBase );
+ nLinkCount = pLinkManager->GetLinks().Count();
+ ++nRemoved;
+ }
+ else
+ ++nLinkPos;
+ }
+
+ String aFilterName = rFilter;
+ String aNewOptions = rOptions;
+ if (!aFilterName.Len())
+ ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions, TRUE, !bApi );
+
+ // remove application prefix from filter name here, so the filter options
+ // aren't reset when the filter name is changed in ScAreaLink::DataChanged
+ ScDocumentLoader::RemoveAppPrefix( aFilterName );
+
+ ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName,
+ aNewOptions, rSource, rDestRange, nRefresh );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rFile, &aFilterName, &rSource );
+
+ // Undo fuer den leeren Link
+
+ if (bUndo)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell,
+ rFile, aFilterName, aNewOptions,
+ rSource, rDestRange, nRefresh ) );
+ if ( nRemoved )
+ rDocShell.GetUndoManager()->LeaveListAction(); // undo for link update is still separate
+ }
+
+ // Update hat sein eigenes Undo
+
+ pLink->SetDoInsert(bFitBlock); // beim ersten Update ggf. nichts einfuegen
+ pLink->Update(); // kein SetInCreate -> Update ausfuehren
+ pLink->SetDoInsert(TRUE); // Default = TRUE
+
+ SfxBindings* pBindings = rDocShell.GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_LINKS );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+
+ return TRUE;
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
new file mode 100644
index 000000000000..d5d7f6e09292
--- /dev/null
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -0,0 +1,2948 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+// System - Includes -----------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/svxenum.hxx>
+#include <svx/algitem.hxx>
+
+#include <sot/clsids.hxx>
+#include <unotools/securityoptions.hxx>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/waitobj.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dinfdlg.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/evntconf.hxx>
+#include <sfx2/sfx.hrc>
+#include <sfx2/objface.hxx>
+#include <svl/srchitem.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <svl/documentlockfile.hxx>
+#include <svl/sharecontrolfile.hxx>
+#include <unotools/charclass.hxx>
+#include <vcl/virdev.hxx>
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include <sfx2/request.hxx>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <basic/sbstar.hxx>
+#include <basic/basmgr.hxx>
+#include <vbahelper/vbaaccesshelper.hxx>
+
+#include "scabstdlg.hxx" //CHINA001
+#include <sot/formats.hxx>
+#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "cell.hxx"
+#include "global.hxx"
+#include "filter.hxx"
+#include "scmod.hxx"
+#include "tabvwsh.hxx"
+#include "docfunc.hxx"
+#include "imoptdlg.hxx"
+#include "impex.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "scerrors.hxx"
+#include "brdcst.hxx"
+#include "stlpool.hxx"
+#include "autostyl.hxx"
+#include "attrib.hxx"
+#include "asciiopt.hxx"
+#include "waitoff.hxx"
+#include "docpool.hxx" // LoadCompleted
+#include "progress.hxx"
+#include "pntlock.hxx"
+#include "collect.hxx"
+#include "docuno.hxx"
+#include "appoptio.hxx"
+#include "detdata.hxx"
+#include "printfun.hxx"
+#include "dociter.hxx"
+#include "cellform.hxx"
+#include "chartlis.hxx"
+#include "hints.hxx"
+#include "xmlwrap.hxx"
+#include "drwlayer.hxx"
+#include "refreshtimer.hxx"
+#include "dbcolect.hxx"
+#include "scextopt.hxx"
+#include "compiler.hxx"
+#include "cfgids.hxx"
+#include "warnpassword.hxx"
+#include "optsolver.hxx"
+#include "sheetdata.hxx"
+#include "tabprotection.hxx"
+
+#include "docsh.hxx"
+#include "docshimp.hxx"
+#include <rtl/logfile.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include "uiitems.hxx"
+#include "cellsuno.hxx"
+
+using namespace com::sun::star;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// STATIC DATA -----------------------------------------------------------
+
+// Stream-Namen im Storage
+
+const sal_Char __FAR_DATA ScDocShell::pStarCalcDoc[] = STRING_SCSTREAM; // "StarCalcDocument"
+const sal_Char __FAR_DATA ScDocShell::pStyleName[] = "SfxStyleSheets";
+
+// Filter-Namen (wie in sclib.cxx)
+
+static const sal_Char __FAR_DATA pFilterSc50[] = "StarCalc 5.0";
+//static const sal_Char __FAR_DATA pFilterSc50Temp[] = "StarCalc 5.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterSc40[] = "StarCalc 4.0";
+//static const sal_Char __FAR_DATA pFilterSc40Temp[] = "StarCalc 4.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterSc30[] = "StarCalc 3.0";
+//static const sal_Char __FAR_DATA pFilterSc30Temp[] = "StarCalc 3.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterSc10[] = "StarCalc 1.0";
+static const sal_Char __FAR_DATA pFilterXML[] = "StarOffice XML (Calc)";
+static const sal_Char __FAR_DATA pFilterAscii[] = "Text - txt - csv (StarCalc)";
+static const sal_Char __FAR_DATA pFilterLotus[] = "Lotus";
+static const sal_Char __FAR_DATA pFilterQPro6[] = "Quattro Pro 6.0";
+static const sal_Char __FAR_DATA pFilterExcel4[] = "MS Excel 4.0";
+static const sal_Char __FAR_DATA pFilterEx4Temp[] = "MS Excel 4.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterExcel5[] = "MS Excel 5.0/95";
+static const sal_Char __FAR_DATA pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterExcel95[] = "MS Excel 95";
+static const sal_Char __FAR_DATA pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterExcel97[] = "MS Excel 97";
+static const sal_Char __FAR_DATA pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterEx07Xml[] = "MS Excel 2007 XML";
+static const sal_Char __FAR_DATA pFilterDBase[] = "dBase";
+static const sal_Char __FAR_DATA pFilterDif[] = "DIF";
+static const sal_Char __FAR_DATA pFilterSylk[] = "SYLK";
+static const sal_Char __FAR_DATA pFilterHtml[] = "HTML (StarCalc)";
+static const sal_Char __FAR_DATA pFilterHtmlWebQ[] = "calc_HTML_WebQuery";
+static const sal_Char __FAR_DATA pFilterRtf[] = "Rich Text Format (StarCalc)";
+
+//----------------------------------------------------------------------
+
+#define ScDocShell
+#include "scslots.hxx"
+
+
+SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL))
+{
+ SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
+}
+
+// GlobalName der aktuellen Version:
+SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "scalc" )
+
+TYPEINIT1( ScDocShell, SfxObjectShell ); // SfxInPlaceObject: kein Type-Info ?
+
+//------------------------------------------------------------------
+
+void __EXPORT ScDocShell::FillClass( SvGlobalName* pClassName,
+ sal_uInt32* pFormat,
+ String* /* pAppName */,
+ String* pFullTypeName,
+ String* pShortTypeName,
+ sal_Int32 nFileFormat,
+ sal_Bool bTemplate /* = sal_False */) const
+{
+ if ( nFileFormat == SOFFICE_FILEFORMAT_60 )
+ {
+ *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
+ *pFormat = SOT_FORMATSTR_ID_STARCALC_60;
+ *pFullTypeName = String( ScResId( SCSTR_LONG_SCDOC_NAME ) );
+ *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
+ }
+ else if ( nFileFormat == SOFFICE_FILEFORMAT_8 )
+ {
+ *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
+ *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE : SOT_FORMATSTR_ID_STARCALC_8;
+ *pFullTypeName = String( RTL_CONSTASCII_USTRINGPARAM("calc8") );
+ *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
+ }
+ else
+ {
+ DBG_ERROR("wat fuer ne Version?");
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::DoEnterHandler()
+{
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if (pViewSh)
+ if (pViewSh->GetViewData()->GetDocShell() == this)
+ SC_MOD()->InputEnterHandler();
+}
+
+//------------------------------------------------------------------
+
+SCTAB ScDocShell::GetSaveTab()
+{
+ SCTAB nTab = 0;
+ ScTabViewShell* pSh = GetBestViewShell();
+ if (pSh)
+ {
+ const ScMarkData& rMark = pSh->GetViewData()->GetMarkData();
+ for ( nTab = 0; nTab <= MAXTAB; nTab++ ) // erste markierte Tabelle
+ if ( rMark.GetTableSelect( nTab ) )
+ break;
+ }
+ return nTab;
+}
+
+sal_uInt16 ScDocShell::GetHiddenInformationState( sal_uInt16 nStates )
+{
+ // get global state like HIDDENINFORMATION_DOCUMENTVERSIONS
+ sal_uInt16 nState = SfxObjectShell::GetHiddenInformationState( nStates );
+
+ if ( nStates & HIDDENINFORMATION_RECORDEDCHANGES )
+ {
+ if ( aDocument.GetChangeTrack() && aDocument.GetChangeTrack()->GetFirst() )
+ nState |= HIDDENINFORMATION_RECORDEDCHANGES;
+ }
+ if ( nStates & HIDDENINFORMATION_NOTES )
+ {
+ SCTAB nTableCount = aDocument.GetTableCount();
+ SCTAB nTable = 0;
+ sal_Bool bFound(sal_False);
+ while ( nTable < nTableCount && !bFound )
+ {
+ ScCellIterator aCellIter( &aDocument, 0,0, nTable, MAXCOL,MAXROW, nTable );
+ for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bFound; pCell = aCellIter.GetNext() )
+ if (pCell->HasNote())
+ bFound = sal_True;
+ nTable++;
+ }
+
+ if (bFound)
+ nState |= HIDDENINFORMATION_NOTES;
+ }
+
+ return nState;
+}
+
+void ScDocShell::BeforeXMLLoading()
+{
+ aDocument.DisableIdle( TRUE );
+
+ // prevent unnecessary broadcasts and updates
+ DBG_ASSERT(pModificator == NULL, "The Modificator should not exist");
+ pModificator = new ScDocShellModificator( *this );
+
+ aDocument.SetImportingXML( TRUE );
+ aDocument.EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
+ aDocument.EnableUndo( FALSE );
+ // prevent unnecessary broadcasts and "half way listeners"
+ aDocument.SetInsertingFromOtherDoc( TRUE );
+
+ if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
+ ScColumn::bDoubleAlloc = sal_True;
+}
+
+void ScDocShell::AfterXMLLoading(sal_Bool bRet)
+{
+ if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
+ {
+ UpdateLinks();
+ // don't prevent establishing of listeners anymore
+ aDocument.SetInsertingFromOtherDoc( FALSE );
+ if ( bRet )
+ {
+ ScChartListenerCollection* pChartListener = aDocument.GetChartListenerCollection();
+ if (pChartListener)
+ pChartListener->UpdateDirtyCharts();
+
+ // #95582#; set the table names of linked tables to the new path
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ if (aDocument.IsLinked( i ))
+ {
+ String aName;
+ aDocument.GetName(i, aName);
+ String aLinkTabName = aDocument.GetLinkTab(i);
+ xub_StrLen nLinkTabNameLength = aLinkTabName.Len();
+ xub_StrLen nNameLength = aName.Len();
+ if (nLinkTabNameLength < nNameLength)
+ {
+
+ // remove the quottes on begin and end of the docname and restore the escaped quotes
+ const sal_Unicode* pNameBuffer = aName.GetBuffer();
+ if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos
+ ScGlobal::UnicodeStrChr( pNameBuffer, SC_COMPILER_FILE_TAB_SEP ) )
+ {
+ rtl::OUStringBuffer aDocURLBuffer;
+ BOOL bQuote = TRUE; // Dokumentenname ist immer quoted
+ ++pNameBuffer;
+ while ( bQuote && *pNameBuffer )
+ {
+ if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' )
+ bQuote = FALSE;
+ else if( !(*pNameBuffer == '\\' && *(pNameBuffer+1) == '\'') )
+ aDocURLBuffer.append(*pNameBuffer); // falls escaped Quote: nur Quote in den Namen
+ ++pNameBuffer;
+ }
+
+
+ if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP ) // after the last quote of the docname should be the # char
+ {
+ xub_StrLen nIndex = nNameLength - nLinkTabNameLength;
+ INetURLObject aINetURLObject(aDocURLBuffer.makeStringAndClear());
+ if( aName.Equals(aLinkTabName, nIndex, nLinkTabNameLength) &&
+ (aName.GetChar(nIndex - 1) == '#') && // before the table name should be the # char
+ !aINetURLObject.HasError()) // the docname should be a valid URL
+ {
+ aName = ScGlobal::GetDocTabName( aDocument.GetLinkDoc( i ), aDocument.GetLinkTab( i ) );
+ aDocument.RenameTab(i, aName, TRUE, TRUE);
+ }
+ // else; nothing has to happen, because it is a user given name
+ }
+ // else; nothing has to happen, because it is a user given name
+ }
+ // else; nothing has to happen, because it is a user given name
+ }
+ // else; nothing has to happen, because it is a user given name
+ }
+ }
+
+ // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API.
+ // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name.
+ ScDPCollection* pDPCollection = aDocument.GetDPCollection();
+ if ( pDPCollection )
+ {
+ USHORT nDPCount = pDPCollection->GetCount();
+ for (USHORT nDP=0; nDP<nDPCount; nDP++)
+ {
+ ScDPObject* pDPObj = (*pDPCollection)[nDP];
+ if ( !pDPObj->GetName().Len() )
+ pDPObj->SetName( pDPCollection->CreateNewName() );
+ }
+ }
+ }
+ ScColumn::bDoubleAlloc = sal_False;
+ }
+ else
+ aDocument.SetInsertingFromOtherDoc( FALSE );
+
+ aDocument.SetImportingXML( FALSE );
+ aDocument.EnableExecuteLink( true );
+ aDocument.EnableUndo( TRUE );
+ bIsEmpty = FALSE;
+
+ if (pModificator)
+ {
+ delete pModificator;
+ pModificator = NULL;
+ }
+ else
+ {
+ DBG_ERROR("The Modificator should exist");
+ }
+
+ aDocument.DisableIdle( FALSE );
+}
+
+BOOL ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::LoadXML" );
+
+ // MacroCallMode is no longer needed, state is kept in SfxObjectShell now
+
+ // no Seek(0) here - always loading from storage, GetInStream must not be called
+
+ BeforeXMLLoading();
+
+ // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked
+ // from an external component. The XMLFromWrapper flag is only set here, when called
+ // through ScDocShell.
+ aDocument.SetXMLFromWrapper( TRUE );
+
+ ScXMLImportWrapper aImport( aDocument, pLoadMedium, xStor );
+
+ sal_Bool bRet(sal_False);
+ ErrCode nError = ERRCODE_NONE;
+ if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
+ bRet = aImport.Import(sal_False, nError);
+ else
+ bRet = aImport.Import(sal_True, nError);
+
+ if ( nError )
+ pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ aDocument.SetXMLFromWrapper( FALSE );
+ AfterXMLLoading(bRet);
+
+ //! row heights...
+
+ return bRet;
+}
+
+BOOL ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::SaveXML" );
+
+ aDocument.DisableIdle( TRUE );
+
+ ScXMLImportWrapper aImport( aDocument, pSaveMedium, xStor );
+ sal_Bool bRet(sal_False);
+ if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
+ bRet = aImport.Export(sal_False);
+ else
+ bRet = aImport.Export(sal_True);
+
+ aDocument.DisableIdle( FALSE );
+
+ return bRet;
+}
+
+BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" );
+
+ ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
+
+ // only the latin script language is loaded
+ // -> initialize the others from options (before loading)
+ InitOptions(true);
+
+ GetUndoManager()->Clear();
+
+ BOOL bRet = SfxObjectShell::Load( rMedium );
+ if( bRet )
+ {
+ if (GetMedium())
+ {
+ SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
+ nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
+ }
+
+ {
+ // prepare a valid document for XML filter
+ // (for ConvertFrom, InitNew is called before)
+ aDocument.MakeTable(0);
+ aDocument.GetStyleSheetPool()->CreateStandardStyles();
+ aDocument.UpdStlShtPtrsFrmNms();
+
+ bRet = LoadXML( &rMedium, NULL );
+ }
+ }
+
+ if (!bRet && !rMedium.GetError())
+ rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ if (rMedium.GetError())
+ SetError( rMedium.GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ InitItems();
+ CalcOutputFactor();
+
+ // #73762# invalidate eventually temporary table areas
+ if ( bRet )
+ aDocument.InvalidateTableArea();
+
+ bIsEmpty = FALSE;
+ FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
+ return bRet;
+}
+
+void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor();
+ if ( xVbaEvents.is() ) try
+ {
+ using namespace ::com::sun::star::script::vba::VBAEventId;
+ if (rHint.ISA(ScTablesHint) )
+ {
+ const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint );
+ if (rScHint.GetId() == SC_TAB_INSERTED)
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[0] <<= rScHint.GetTab1();
+ xVbaEvents->processVbaEvent( WORKBOOK_NEWSHEET, aArgs );
+ }
+ }
+ else if ( rHint.ISA( SfxEventHint ) )
+ {
+ ULONG nEventId = static_cast< const SfxEventHint& >( rHint ).GetEventId();
+ switch ( nEventId )
+ {
+ case SFX_EVENT_ACTIVATEDOC:
+ {
+ uno::Sequence< uno::Any > aArgs;
+ xVbaEvents->processVbaEvent( WORKBOOK_ACTIVATE, aArgs );
+ }
+ break;
+ case SFX_EVENT_DEACTIVATEDOC:
+ {
+ uno::Sequence< uno::Any > aArgs;
+ xVbaEvents->processVbaEvent( WORKBOOK_DEACTIVATE, aArgs );
+ }
+ break;
+ case SFX_EVENT_OPENDOC:
+ {
+ uno::Sequence< uno::Any > aArgs;
+ xVbaEvents->processVbaEvent( WORKBOOK_OPEN, aArgs );
+ }
+ break;
+ case SFX_EVENT_SAVEDOCDONE:
+ case SFX_EVENT_SAVEASDOCDONE:
+ case SFX_EVENT_SAVETODOCDONE:
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= true;
+ xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs );
+ }
+ break;
+ case SFX_EVENT_SAVEASDOCFAILED:
+ case SFX_EVENT_SAVEDOCFAILED:
+ case SFX_EVENT_SAVETODOCFAILED:
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= false;
+ xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs );
+ }
+ break;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ if (rHint.ISA(SfxSimpleHint)) // ohne Parameter
+ {
+ ULONG nSlot = ((const SfxSimpleHint&)rHint).GetId();
+ switch ( nSlot )
+ {
+ case SFX_HINT_TITLECHANGED:
+ aDocument.SetName( SfxShell::GetName() );
+ // RegisterNewTargetNames gibts nicht mehr
+ SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED )); // Navigator
+ break;
+ }
+ }
+ else if (rHint.ISA(SfxStyleSheetHint)) // Vorlagen geaendert
+ NotifyStyle((const SfxStyleSheetHint&) rHint);
+ else if (rHint.ISA(ScAutoStyleHint))
+ {
+ //! direct call for AutoStyles
+
+ // this is called synchronously from ScInterpreter::ScStyle,
+ // modifying the document must be asynchronous
+ // (handled by AddInitial)
+
+ ScAutoStyleHint& rStlHint = (ScAutoStyleHint&)rHint;
+ ScRange aRange = rStlHint.GetRange();
+ String aName1 = rStlHint.GetStyle1();
+ String aName2 = rStlHint.GetStyle2();
+ UINT32 nTimeout = rStlHint.GetTimeout();
+
+ if (!pAutoStyleList)
+ pAutoStyleList = new ScAutoStyleList(this);
+ pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 );
+ }
+ else if ( rHint.ISA( SfxEventHint ) )
+ {
+ ULONG nEventId = ((SfxEventHint&)rHint).GetEventId();
+ switch ( nEventId )
+ {
+ case SFX_EVENT_LOADFINISHED:
+ {
+ // the readonly documents should not be opened in shared mode
+ if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
+ {
+ if ( SwitchToShared( sal_True, sal_False ) )
+ {
+ ScViewData* pViewData = GetViewData();
+ ScTabView* pTabView = ( pViewData ? dynamic_cast< ScTabView* >( pViewData->GetView() ) : NULL );
+ if ( pTabView )
+ {
+ pTabView->UpdateLayerLocks();
+ }
+ }
+ else
+ {
+ // switching to shared mode has failed, the document should be opened readonly
+ // TODO/LATER: And error message should be shown here probably
+ SetReadOnlyUI( sal_True );
+ }
+ }
+
+ // VBA specific initialization
+ if( aDocument.IsInVBAMode() ) try
+ {
+ uno::Reference< frame::XModel > xModel( GetModel(), uno::UNO_SET_THROW );
+
+ // create VBAGlobals object if not yet done (this also creates the "ThisExcelDoc" symbol)
+ uno::Reference< lang::XMultiServiceFactory > xFactory( xModel, uno::UNO_QUERY_THROW );
+ xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
+
+ // create the VBA document event processor
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= xModel;
+ xVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( this, "com.sun.star.script.vba.VBASpreadsheetEventProcessor" , aArgs ), uno::UNO_QUERY );
+ aDocument.SetVbaEventProcessor( xVbaEvents );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ break;
+ case SFX_EVENT_VIEWCREATED:
+ {
+ if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
+ {
+ ScAppOptions aAppOptions = SC_MOD()->GetAppOptions();
+ if ( aAppOptions.GetShowSharedDocumentWarning() )
+ {
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
+ ScGlobal::GetRscString( STR_SHARED_DOC_WARNING ) );
+ aBox.SetDefaultCheckBoxText();
+ aBox.Execute();
+ BOOL bChecked = aBox.GetCheckBoxState();
+ if ( bChecked )
+ {
+ aAppOptions.SetShowSharedDocumentWarning( !bChecked );
+ SC_MOD()->SetAppOptions( aAppOptions );
+ }
+ }
+ }
+
+ try
+ {
+ uno::Reference< uno::XComponentContext > xContext;
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+ uno::Reference< beans::XPropertySet > xProp( xServiceManager, uno::UNO_QUERY_THROW );
+ xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;
+ if ( xContext.is() )
+ {
+ uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocumentJob" ) ) );
+ if ( xEnum.is() )
+ {
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Any aAny = xEnum->nextElement();
+ uno::Reference< lang::XSingleComponentFactory > xFactory;
+ aAny >>= xFactory;
+ if ( xFactory.is() )
+ {
+ uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::NamedValue > aArgsForJob(1);
+ ScViewData* pViewData = GetViewData();
+ SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : NULL );
+ SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : NULL );
+ SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : NULL );
+ uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : 0 );
+ uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW );
+ aArgsForJob[0] = beans::NamedValue( ::rtl::OUString::createFromAscii( "SpreadsheetView" ),
+ uno::makeAny( xSpreadsheetView ) );
+ xJob->execute( aArgsForJob );
+ }
+ }
+ }
+ }
+ }
+ catch ( uno::Exception & )
+ {
+ }
+ }
+ break;
+ case SFX_EVENT_SAVEDOC:
+ {
+ if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
+ {
+ bool bSuccess = false;
+ bool bRetry = true;
+ while ( bRetry )
+ {
+ bRetry = false;
+ uno::Reference< frame::XModel > xModel;
+ try
+ {
+ // load shared file
+ xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
+
+ // check if shared flag is set in shared file
+ bool bShared = false;
+ ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
+ ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : NULL );
+ if ( pSharedDocShell )
+ {
+ bShared = pSharedDocShell->HasSharedXMLFlagSet();
+ }
+
+ // #i87870# check if shared status was disabled and enabled again
+ bool bOwnEntry = false;
+ bool bEntriesNotAccessible = false;
+ try
+ {
+ ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
+ bOwnEntry = aControlFile.HasOwnEntry();
+ }
+ catch ( uno::Exception& )
+ {
+ bEntriesNotAccessible = true;
+ }
+
+ if ( bShared && bOwnEntry )
+ {
+ uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
+
+ if ( xStorable->isReadonly() )
+ {
+ xCloseable->close( sal_True );
+
+ String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
+ bool bNoLockAccess = false;
+ try
+ {
+ ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
+ uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData();
+ if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID )
+ {
+ if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 )
+ {
+ aUserName = aData[LOCKFILE_OOOUSERNAME_ID];
+ }
+ else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 )
+ {
+ aUserName = aData[LOCKFILE_SYSUSERNAME_ID];
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ bNoLockAccess = true;
+ }
+
+ if ( bNoLockAccess )
+ {
+ // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
+ ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
+ }
+ else
+ {
+ String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER ) );
+ aMessage.SearchAndReplaceAscii( "%1", aUserName );
+
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL | WB_DEF_RETRY ), aMessage );
+ if ( aBox.Execute() == RET_RETRY )
+ {
+ bRetry = true;
+ }
+ }
+ }
+ else
+ {
+ // merge changes from shared file into temp file
+ bool bSaveToShared = false;
+ if ( pSharedDocShell )
+ {
+ bSaveToShared = MergeSharedDocument( pSharedDocShell );
+ }
+
+ // close shared file
+ xCloseable->close( sal_True );
+
+ // TODO: keep file lock on shared file
+
+ // store to shared file
+ if ( bSaveToShared )
+ {
+ bool bChangedViewSettings = false;
+ ScChangeViewSettings* pChangeViewSet = aDocument.GetChangeViewSettings();
+ if ( pChangeViewSet && pChangeViewSet->ShowChanges() )
+ {
+ pChangeViewSet->SetShowChanges( FALSE );
+ pChangeViewSet->SetShowAccepted( FALSE );
+ aDocument.SetChangeViewSettings( *pChangeViewSet );
+ bChangedViewSettings = true;
+ }
+
+ uno::Reference< frame::XStorable > xStor( GetModel(), uno::UNO_QUERY_THROW );
+ // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
+ uno::Sequence< beans::PropertyValue > aValues(1);
+ aValues[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
+ aValues[0].Value <<= ::rtl::OUString( GetMedium()->GetFilter()->GetFilterName() );
+
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
+ if ( pPasswordItem && pPasswordItem->GetValue().Len() )
+ {
+ aValues.realloc( 2 );
+ aValues[1].Name = ::rtl::OUString::createFromAscii( "Password" );
+ aValues[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() );
+ }
+
+ SC_MOD()->SetInSharedDocSaving( true );
+ xStor->storeToURL( GetSharedFileURL(), aValues );
+ SC_MOD()->SetInSharedDocSaving( false );
+
+ if ( bChangedViewSettings )
+ {
+ pChangeViewSet->SetShowChanges( TRUE );
+ pChangeViewSet->SetShowAccepted( TRUE );
+ aDocument.SetChangeViewSettings( *pChangeViewSet );
+ }
+ }
+
+ bSuccess = true;
+ GetUndoManager()->Clear();
+ }
+ }
+ else
+ {
+ xCloseable->close( sal_True );
+
+ if ( bEntriesNotAccessible )
+ {
+ // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
+ ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
+ }
+ else
+ {
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
+ ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
+ aBox.Execute();
+
+ SfxBindings* pBindings = GetViewBindings();
+ if ( pBindings )
+ {
+ pBindings->ExecuteSynchron( SID_SAVEASDOC );
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "SFX_EVENT_SAVEDOC: caught exception\n" );
+ SC_MOD()->SetInSharedDocSaving( false );
+
+ try
+ {
+ uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
+ xClose->close( sal_True );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ if ( !bSuccess )
+ 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
+ }
+ if (pSheetSaveData)
+ pSheetSaveData->SetInSupportedSave(true);
+ }
+ break;
+ case SFX_EVENT_SAVEASDOC:
+ case SFX_EVENT_SAVETODOC:
+ // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
+ // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
+ // if there is a SAVE/SAVEAS/SAVETO event first.
+ if (pSheetSaveData)
+ pSheetSaveData->SetInSupportedSave(true);
+ break;
+ case SFX_EVENT_SAVEDOCDONE:
+ {
+ if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
+ {
+ }
+ UseSheetSaveEntries(); // use positions from saved file for next saving
+ if (pSheetSaveData)
+ pSheetSaveData->SetInSupportedSave(false);
+ }
+ break;
+ case SFX_EVENT_SAVEASDOCDONE:
+ // new positions are used after "save" and "save as", but not "save to"
+ UseSheetSaveEntries(); // use positions from saved file for next saving
+ if (pSheetSaveData)
+ pSheetSaveData->SetInSupportedSave(false);
+ break;
+ case SFX_EVENT_SAVETODOCDONE:
+ // only reset the flag, don't use the new positions
+ if (pSheetSaveData)
+ pSheetSaveData->SetInSupportedSave(false);
+ break;
+ default:
+ {
+ }
+ break;
+ }
+ }
+}
+
+ // Inhalte fuer Organizer laden
+
+
+BOOL __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::LoadFrom" );
+
+ ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
+
+ WaitObject aWait( GetActiveDialogParent() );
+
+ BOOL bRet = FALSE;
+
+ if (GetMedium())
+ {
+ SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
+ nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
+ }
+
+ // until loading/saving only the styles in XML is implemented,
+ // load the whole file
+ bRet = LoadXML( &rMedium, NULL );
+ InitItems();
+
+ SfxObjectShell::LoadFrom( rMedium );
+
+ return bRet;
+}
+
+static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert)
+{
+ OUStringBuffer aBuf;
+ OUString aTokens[2];
+ sal_Int32 n = rOption.getLength();
+ const sal_Unicode* p = rOption.getStr();
+ sal_Int32 nTokenId = 0;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (c == sal_Unicode(' '))
+ {
+ if (aBuf.getLength())
+ aTokens[nTokenId++] = aBuf.makeStringAndClear();
+ }
+ else
+ aBuf.append(c);
+
+ if (nTokenId >= 2)
+ break;
+ }
+
+ if (aBuf.getLength())
+ aTokens[nTokenId] = aBuf.makeStringAndClear();
+
+ rLang = static_cast<LanguageType>(aTokens[0].toInt32());
+ rDateConvert = static_cast<bool>(aTokens[1].toInt32());
+}
+
+namespace {
+
+class LoadMediumGuard
+{
+public:
+ explicit LoadMediumGuard(ScDocument* pDoc) :
+ mpDoc(pDoc)
+ {
+ mpDoc->SetLoadingMedium(true);
+ }
+
+ ~LoadMediumGuard()
+ {
+ mpDoc->SetLoadingMedium(false);
+ }
+private:
+ ScDocument* mpDoc;
+};
+
+}
+
+BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" );
+
+ LoadMediumGuard aLoadGuard(&aDocument);
+
+ BOOL bRet = FALSE; // FALSE heisst Benutzerabbruch !!
+ // bei Fehler: Fehler am Stream setzen!!
+
+ ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
+
+ GetUndoManager()->Clear();
+
+ // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
+ BOOL bSetColWidths = FALSE;
+ BOOL bSetSimpleTextColWidths = FALSE;
+ BOOL bSimpleColWidth[MAXCOLCOUNT];
+ memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(BOOL) );
+ ScRange aColWidthRange;
+ // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
+ BOOL bSetRowHeights = FALSE;
+
+ aConvFilterName.Erase(); //@ #BugId 54198
+
+ // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
+ // darum vorher per CreateFileStream dafuer sorgen, dass die komplette
+ // Datei uebertragen wird.
+ rMedium.GetPhysicalName(); //! CreateFileStream direkt rufen, wenn verfuegbar
+
+ SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
+ nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
+
+ const SfxFilter* pFilter = rMedium.GetFilter();
+ if (pFilter)
+ {
+ String aFltName = pFilter->GetFilterName();
+
+ aConvFilterName=aFltName; //@ #BugId 54198
+
+ BOOL bCalc3 = ( aFltName.EqualsAscii(pFilterSc30) );
+ BOOL bCalc4 = ( aFltName.EqualsAscii(pFilterSc40) );
+ if (!bCalc3 && !bCalc4)
+ aDocument.SetInsertingFromOtherDoc( TRUE );
+
+ if (aFltName.EqualsAscii(pFilterXML))
+ bRet = LoadXML( &rMedium, NULL );
+ else if (aFltName.EqualsAscii(pFilterSc10))
+ {
+ SvStream* pStream = rMedium.GetInStream();
+ if (pStream)
+ {
+ FltError eError = ScFormatFilter::Get().ScImportStarCalc10( *pStream, &aDocument );
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ else
+ bRet = TRUE;
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterLotus))
+ {
+ String sItStr;
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ sItStr = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (sItStr.Len() == 0)
+ {
+ // default for lotus import (from API without options):
+ // IBM_437 encoding
+ sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 );
+ }
+
+ ScColumn::bDoubleAlloc = TRUE;
+ FltError eError = ScFormatFilter::Get().ScImportLotus123( rMedium, &aDocument,
+ ScGlobal::GetCharsetValue(sItStr));
+ ScColumn::bDoubleAlloc = FALSE;
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+
+ if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE;
+ bSetColWidths = TRUE;
+ bSetRowHeights = TRUE;
+ }
+ else if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterExcel5) ||
+ aFltName.EqualsAscii(pFilterExcel95) || aFltName.EqualsAscii(pFilterExcel97) ||
+ aFltName.EqualsAscii(pFilterEx4Temp) || aFltName.EqualsAscii(pFilterEx5Temp) ||
+ aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) )
+ {
+ EXCIMPFORMAT eFormat = EIF_AUTO;
+ if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterEx4Temp) )
+ eFormat = EIF_BIFF_LE4;
+ else if ( aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
+ aFltName.EqualsAscii(pFilterEx5Temp) || aFltName.EqualsAscii(pFilterEx95Temp) )
+ eFormat = EIF_BIFF5;
+ else if ( aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx97Temp) )
+ eFormat = EIF_BIFF8;
+
+ MakeDrawLayer(); //! im Filter
+ CalcOutputFactor(); // #93255# prepare update of row height
+ ScColumn::bDoubleAlloc = TRUE;
+ FltError eError = ScFormatFilter::Get().ScImportExcel( rMedium, &aDocument, eFormat );
+ ScColumn::bDoubleAlloc = FALSE;
+ aDocument.UpdateFontCharSet();
+ if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
+ aDocument.UpdateChartListenerCollection(); //! fuer alle Importe?
+
+ // #75299# all graphics objects must have names
+ aDocument.EnsureGraphicNames();
+
+ if (eError == SCWARN_IMPORT_RANGE_OVERFLOW)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ bRet = TRUE;
+ }
+ else if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ else
+ bRet = TRUE;
+
+ // #93255# update of row height done inside of Excel filter to speed up chart import
+// bSetRowHeights = TRUE; // #75357# optimal row heights must be updated
+ }
+ else if (aFltName.EqualsAscii(pFilterAscii))
+ {
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ const SfxPoolItem* pItem;
+ ScAsciiOptions aOptions;
+ BOOL bOptInit = FALSE;
+
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ aOptions.ReadFromString( ((const SfxStringItem*)pItem)->GetValue() );
+ bOptInit = TRUE;
+ }
+
+ if ( !bOptInit )
+ {
+ // default for ascii import (from API without options):
+ // ISO8859-1/MS_1252 encoding, comma, double quotes
+
+ aOptions.SetCharSet( RTL_TEXTENCODING_MS_1252 );
+ aOptions.SetFieldSeps( (sal_Unicode) ',' );
+ aOptions.SetTextSep( (sal_Unicode) '"' );
+ }
+
+ FltError eError = eERR_OK;
+ BOOL bOverflow = FALSE;
+
+ if( ! rMedium.IsStorage() )
+ {
+ ScImportExport aImpEx( &aDocument );
+ aImpEx.SetExtOptions( aOptions );
+
+ SvStream* pInStream = rMedium.GetInStream();
+ if (pInStream)
+ {
+ pInStream->SetStreamCharSet( aOptions.GetCharSet() );
+ pInStream->Seek( 0 );
+ bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL() );
+ eError = bRet ? eERR_OK : SCERR_IMPORT_CONNECT;
+ aDocument.StartAllListeners();
+ aDocument.SetDirty();
+ bOverflow = aImpEx.IsOverflow();
+ }
+ else
+ {
+ DBG_ERROR( "No Stream" );
+ }
+ }
+
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ else if ( bOverflow )
+ {
+ if (!GetError())
+ SetError(SCWARN_IMPORT_RANGE_OVERFLOW, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ bSetColWidths = TRUE;
+ bSetSimpleTextColWidths = TRUE;
+ }
+ else if (aFltName.EqualsAscii(pFilterDBase))
+ {
+ String sItStr;
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ sItStr = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (sItStr.Len() == 0)
+ {
+ // default for dBase import (from API without options):
+ // IBM_850 encoding
+
+ sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
+ }
+
+ ULONG eError = DBaseImport( rMedium.GetPhysicalName(),
+ ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );
+
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW );
+ }
+ else
+ bRet = TRUE;
+
+ aColWidthRange.aStart.SetRow( 1 ); // Spaltenheader nicht
+ bSetColWidths = TRUE;
+ bSetSimpleTextColWidths = TRUE;
+ // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
+ for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
+ {
+ if ( !bSimpleColWidth[nCol] )
+ bSetRowHeights = TRUE;
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterDif))
+ {
+ SvStream* pStream = rMedium.GetInStream();
+ if (pStream)
+ {
+ FltError eError;
+ String sItStr;
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ sItStr = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (sItStr.Len() == 0)
+ {
+ // default for DIF import (from API without options):
+ // ISO8859-1/MS_1252 encoding
+
+ sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
+ }
+
+ eError = ScFormatFilter::Get().ScImportDif( *pStream, &aDocument, ScAddress(0,0,0),
+ ScGlobal::GetCharsetValue(sItStr));
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+
+ if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE;
+ }
+ bSetColWidths = TRUE;
+ bSetSimpleTextColWidths = TRUE;
+ bSetRowHeights = TRUE;
+ }
+ else if (aFltName.EqualsAscii(pFilterSylk))
+ {
+ FltError eError = SCERR_IMPORT_UNKNOWN;
+ if( !rMedium.IsStorage() )
+ {
+ ScImportExport aImpEx( &aDocument );
+
+ SvStream* pInStream = rMedium.GetInStream();
+ if (pInStream)
+ {
+ pInStream->Seek( 0 );
+ bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SOT_FORMATSTR_ID_SYLK );
+ eError = bRet ? eERR_OK : SCERR_IMPORT_UNKNOWN;
+ aDocument.StartAllListeners();
+ aDocument.SetDirty();
+ }
+ else
+ {
+ DBG_ERROR( "No Stream" );
+ }
+ }
+
+ if ( eError != eERR_OK && !GetError() )
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ bSetColWidths = TRUE;
+ bSetSimpleTextColWidths = TRUE;
+ bSetRowHeights = TRUE;
+ }
+ else if (aFltName.EqualsAscii(pFilterQPro6))
+ {
+ ScColumn::bDoubleAlloc = TRUE;
+ FltError eError = ScFormatFilter::Get().ScImportQuattroPro( rMedium, &aDocument);
+ ScColumn::bDoubleAlloc = FALSE;
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE;
+ // TODO: Filter should set column widths. Not doing it here, it may
+ // result in very narrow or wide columns, depending on content.
+ // Setting row heights makes cells with font size attribution or
+ // wrapping enabled look nicer..
+ bSetRowHeights = TRUE;
+ }
+ else if (aFltName.EqualsAscii(pFilterRtf))
+ {
+ FltError eError = SCERR_IMPORT_UNKNOWN;
+ if( !rMedium.IsStorage() )
+ {
+ SvStream* pInStream = rMedium.GetInStream();
+ if (pInStream)
+ {
+ pInStream->Seek( 0 );
+ ScRange aRange;
+ eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange );
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+
+ if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE;
+ aDocument.StartAllListeners();
+ aDocument.SetDirty();
+ bSetColWidths = TRUE;
+ bSetRowHeights = TRUE;
+ }
+ else
+ {
+ DBG_ERROR( "No Stream" );
+ }
+ }
+
+ if ( eError != eERR_OK && !GetError() )
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ else if (aFltName.EqualsAscii(pFilterHtml) || aFltName.EqualsAscii(pFilterHtmlWebQ))
+ {
+ FltError eError = SCERR_IMPORT_UNKNOWN;
+ BOOL bWebQuery = aFltName.EqualsAscii(pFilterHtmlWebQ);
+ if( !rMedium.IsStorage() )
+ {
+ SvStream* pInStream = rMedium.GetInStream();
+ if (pInStream)
+ {
+ LanguageType eLang = LANGUAGE_SYSTEM;
+ bool bDateConvert = false;
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue();
+ lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert);
+ }
+
+ pInStream->Seek( 0 );
+ ScRange aRange;
+ // HTML macht eigenes ColWidth/RowHeight
+ CalcOutputFactor();
+ SvNumberFormatter aNumFormatter(aDocument.GetServiceManager(), eLang);
+ eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange,
+ GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert );
+ if (eError != eERR_OK)
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+
+ if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE;
+ aDocument.StartAllListeners();
+ aDocument.SetDirty();
+ }
+ else
+ {
+ DBG_ERROR( "No Stream" );
+ }
+ }
+
+ if ( eError != eERR_OK && !GetError() )
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ else
+ {
+ if (!GetError())
+ SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+
+ if (!bCalc3)
+ aDocument.SetInsertingFromOtherDoc( FALSE );
+ }
+ else
+ {
+ DBG_ERROR("Kein Filter bei ConvertFrom");
+ }
+
+ InitItems();
+ CalcOutputFactor();
+ if ( bRet && (bSetColWidths || bSetRowHeights) )
+ { // Spaltenbreiten/Zeilenhoehen anpassen, Basis 100% Zoom
+ Fraction aZoom( 1, 1 );
+ double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom
+ / GetOutputFactor(); // Faktor ist Drucker zu Bildschirm
+ double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom;
+ VirtualDevice aVirtDev;
+ // all sheets (for Excel import)
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aDocument.GetCellArea( nTab, nEndCol, nEndRow );
+ aColWidthRange.aEnd.SetCol( nEndCol );
+ aColWidthRange.aEnd.SetRow( nEndRow );
+ ScMarkData aMark;
+ aMark.SetMarkArea( aColWidthRange );
+ aMark.MarkToMulti();
+ // Reihenfolge erst Breite dann Hoehe ist wichtig (vergl. hund.rtf)
+ if ( bSetColWidths )
+ {
+ for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
+ {
+ USHORT nWidth = aDocument.GetOptimalColWidth(
+ nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, FALSE, &aMark,
+ (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
+ aDocument.SetColWidth( nCol, nTab,
+ nWidth + (USHORT)ScGlobal::nLastColWidthExtra );
+ }
+ }
+// if ( bSetRowHeights )
+// {
+// // nExtra must be 0
+// aDocument.SetOptimalHeight( 0, nEndRow, nTab, 0, &aVirtDev,
+// nPPTX, nPPTY, aZoom, aZoom, FALSE );
+// }
+ }
+ if ( bSetRowHeights )
+ UpdateAllRowHeights(); // with vdev or printer, depending on configuration
+ }
+ FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
+
+ // #73762# invalidate eventually temporary table areas
+ if ( bRet )
+ aDocument.InvalidateTableArea();
+
+ bIsEmpty = FALSE;
+
+ return bRet;
+}
+
+
+ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell )
+ : mrDocShell( rDocShell)
+{
+ // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
+
+ ScChartListenerCollection* pCharts = mrDocShell.aDocument.GetChartListenerCollection();
+ if (pCharts)
+ pCharts->UpdateDirtyCharts(); // Charts to be updated.
+ mrDocShell.aDocument.StopTemporaryChartLock();
+ if (mrDocShell.pAutoStyleList)
+ mrDocShell.pAutoStyleList->ExecuteAllNow(); // Execute template timeouts now.
+ if (mrDocShell.aDocument.HasExternalRefManager())
+ {
+ ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
+ if (pRefMgr && pRefMgr->hasExternalData())
+ {
+ pRefMgr->setAllCacheTableReferencedStati( false);
+ mrDocShell.aDocument.MarkUsedExternalReferences(); // Mark tables of external references to be written.
+ }
+ }
+ if (mrDocShell.GetCreateMode()== SFX_CREATE_MODE_STANDARD)
+ mrDocShell.SfxObjectShell::SetVisArea( Rectangle() ); // "Normally" worked on => no VisArea.
+}
+
+ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
+{
+ if (mrDocShell.aDocument.HasExternalRefManager())
+ {
+ ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
+ if (pRefMgr && pRefMgr->hasExternalData())
+ {
+ // Prevent accidental data loss due to lack of knowledge.
+ pRefMgr->setAllCacheTableReferencedStati( true);
+ }
+ }
+}
+
+
+BOOL __EXPORT ScDocShell::Save()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Save" );
+
+ ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
+
+ PrepareSaveGuard aPrepareGuard( *this);
+
+ // wait cursor is handled with progress bar
+ BOOL bRet = SfxObjectShell::Save();
+ if( bRet )
+ bRet = SaveXML( GetMedium(), NULL );
+ return bRet;
+}
+
+
+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);
+
+ // wait cursor is handled with progress bar
+ BOOL bRet = SfxObjectShell::SaveAs( rMedium );
+ if( bRet )
+ bRet = SaveXML( &rMedium, NULL );
+
+ return bRet;
+}
+
+
+BOOL __EXPORT ScDocShell::IsInformationLost()
+{
+/*
+ const SfxFilter *pFilt = GetMedium()->GetFilter();
+ BOOL bRet = pFilt && pFilt->IsAlienFormat() && bNoInformLost;
+ if (bNoInformLost) // nur einmal!!
+ bNoInformLost = FALSE;
+ return bRet;
+*/
+ //!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen
+
+ return SfxObjectShell::IsInformationLost();
+}
+
+
+// Xcl-like column width measured in characters of standard font.
+xub_StrLen lcl_ScDocShell_GetColWidthInChars( USHORT nWidth )
+{
+ // double fColScale = 1.0;
+ double f = nWidth;
+ f *= 1328.0 / 25.0;
+ f += 90.0;
+ f *= 1.0 / 23.0;
+ // f /= fColScale * 256.0;
+ f /= 256.0;
+
+ return xub_StrLen( f );
+}
+
+
+void lcl_ScDocShell_GetFixedWidthString( String& rStr, const ScDocument& rDoc,
+ SCTAB nTab, SCCOL nCol, BOOL bValue, SvxCellHorJustify eHorJust )
+{
+ xub_StrLen nLen = lcl_ScDocShell_GetColWidthInChars(
+ rDoc.GetColWidth( nCol, nTab ) );
+ if ( nLen < rStr.Len() )
+ {
+ if ( bValue )
+ rStr.AssignAscii( "###" );
+ rStr.Erase( nLen );
+ }
+ if ( nLen > rStr.Len() )
+ {
+ if ( bValue && eHorJust == SVX_HOR_JUSTIFY_STANDARD )
+ eHorJust = SVX_HOR_JUSTIFY_RIGHT;
+ switch ( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_RIGHT:
+ {
+ String aTmp;
+ aTmp.Fill( nLen - rStr.Len() );
+ rStr.Insert( aTmp, 0 );
+ }
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ {
+ xub_StrLen nLen2 = (nLen - rStr.Len()) / 2;
+ String aTmp;
+ aTmp.Fill( nLen2 );
+ rStr.Insert( aTmp, 0 );
+ rStr.Expand( nLen );
+ }
+ break;
+ default:
+ rStr.Expand( nLen );
+ }
+ }
+}
+
+
+void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream,
+ const ScDocument& rDoc, SCTAB nTab, SCCOL nCol )
+{
+ String aString;
+ lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, FALSE,
+ SVX_HOR_JUSTIFY_STANDARD );
+ rStream.WriteUnicodeOrByteText( aString );
+}
+
+
+void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt )
+{
+ sal_Unicode cDelim = rAsciiOpt.nFieldSepCode;
+ sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
+ CharSet eCharSet = rAsciiOpt.eCharSet;
+ BOOL bFixedWidth = rAsciiOpt.bFixedWidth;
+ BOOL bSaveAsShown = rAsciiOpt.bSaveAsShown;
+
+ CharSet eOldCharSet = rStream.GetStreamCharSet();
+ rStream.SetStreamCharSet( eCharSet );
+ USHORT nOldNumberFormatInt = rStream.GetNumberFormatInt();
+ ByteString aStrDelimEncoded; // only used if not Unicode
+ UniString aStrDelimDecoded; // only used if context encoding
+ BOOL bContextOrNotAsciiEncoding;
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ {
+ rStream.StartWritingUnicodeText();
+ bContextOrNotAsciiEncoding = FALSE;
+ }
+ else
+ {
+ aStrDelimEncoded = ByteString( cStrDelim, eCharSet );
+ rtl_TextEncodingInfo aInfo;
+ aInfo.StructSize = sizeof(aInfo);
+ if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
+ {
+ bContextOrNotAsciiEncoding =
+ (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
+ ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
+ if ( bContextOrNotAsciiEncoding )
+ aStrDelimDecoded = String( aStrDelimEncoded, eCharSet );
+ }
+ else
+ bContextOrNotAsciiEncoding = FALSE;
+ }
+
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCTAB nTab = GetSaveTab();
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aDocument.GetCellArea( nTab, nEndCol, nEndRow );
+
+ ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), nEndRow );
+
+ String aString;
+
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+ const ScViewOptions& rOpt = (pViewSh)
+ ? pViewSh->GetViewData()->GetOptions()
+ : aDocument.GetViewOptions();
+ BOOL bShowFormulas = rOpt.GetOption( VOPT_FORMULAS );
+ BOOL bTabProtect = aDocument.IsTabProtected( nTab );
+
+ SCCOL nCol;
+ SCROW nRow;
+ SCCOL nNextCol = nStartCol;
+ SCROW nNextRow = nStartRow;
+ SCCOL nEmptyCol;
+ SCROW nEmptyRow;
+ SvNumberFormatter& rFormatter = *aDocument.GetFormatTable();
+
+ ScHorizontalCellIterator aIter( &aDocument, nTab, nStartCol, nStartRow,
+ nEndCol, nEndRow );
+ ScBaseCell* pCell;
+ while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != NULL )
+ {
+ BOOL bProgress = FALSE; // only upon line change
+ if ( nNextRow < nRow )
+ { // empty rows or/and empty columns up to end of row
+ bProgress = TRUE;
+ for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
+ { // remaining columns of last row
+ if ( bFixedWidth )
+ lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
+ aDocument, nTab, nEmptyCol );
+ else if ( cDelim != 0 )
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ endlub( rStream );
+ nNextRow++;
+ for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ )
+ { // completely empty rows
+ for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
+ {
+ if ( bFixedWidth )
+ lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
+ aDocument, nTab, nEmptyCol );
+ else if ( cDelim != 0 )
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ endlub( rStream );
+ }
+ for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ )
+ { // empty columns at beginning of row
+ if ( bFixedWidth )
+ lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
+ aDocument, nTab, nEmptyCol );
+ else if ( cDelim != 0 )
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ nNextRow = nRow;
+ }
+ else if ( nNextCol < nCol )
+ { // empty columns in same row
+ for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ )
+ { // columns in between
+ if ( bFixedWidth )
+ lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
+ aDocument, nTab, nEmptyCol );
+ else if ( cDelim != 0 )
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ }
+ if ( nCol == nEndCol )
+ {
+ bProgress = TRUE;
+ nNextCol = nStartCol;
+ nNextRow = nRow + 1;
+ }
+ else
+ nNextCol = nCol + 1;
+
+ CellType eType = pCell->GetCellType();
+ if ( bTabProtect )
+ {
+ const ScProtectionAttr* pProtAttr =
+ (const ScProtectionAttr*) aDocument.GetAttr(
+ nCol, nRow, nTab, ATTR_PROTECTION );
+ if ( pProtAttr->GetHideCell() ||
+ ( eType == CELLTYPE_FORMULA && bShowFormulas &&
+ pProtAttr->GetHideFormula() ) )
+ eType = CELLTYPE_NONE; // hide
+ }
+ BOOL bString;
+ switch ( eType )
+ {
+ case CELLTYPE_NOTE:
+ case CELLTYPE_NONE:
+ aString.Erase();
+ bString = FALSE;
+ break;
+ case CELLTYPE_FORMULA :
+ {
+ USHORT nErrCode;
+ if ( bShowFormulas )
+ {
+ ((ScFormulaCell*)pCell)->GetFormula( aString );
+ bString = TRUE;
+ }
+ else if ( ( nErrCode = ((ScFormulaCell*)pCell)->GetErrCode() ) != 0 )
+ {
+ aString = ScGlobal::GetErrorString( nErrCode );
+ bString = TRUE;
+ }
+ else if ( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ sal_uInt32 nFormat;
+ aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
+ if ( bFixedWidth || bSaveAsShown )
+ {
+ Color* pDummy;
+ ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
+ bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
+ }
+ else
+ {
+ ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
+ bString = FALSE;
+ }
+ }
+ else
+ {
+ if ( bSaveAsShown )
+ {
+ sal_uInt32 nFormat;
+ aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
+ Color* pDummy;
+ ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
+ }
+ else
+ ((ScFormulaCell*)pCell)->GetString( aString );
+ bString = TRUE;
+ }
+ }
+ break;
+ case CELLTYPE_STRING :
+ if ( bSaveAsShown )
+ {
+ sal_uInt32 nFormat;
+ aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
+ Color* pDummy;
+ ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
+ }
+ else
+ ((ScStringCell*)pCell)->GetString( aString );
+ bString = TRUE;
+ break;
+ case CELLTYPE_EDIT :
+ {
+ const EditTextObject* pObj;
+ static_cast<const ScEditCell*>(pCell)->GetData( pObj);
+ EditEngine& rEngine = aDocument.GetEditEngine();
+ rEngine.SetText( *pObj);
+ aString = rEngine.GetText(); // including LF
+ bString = TRUE;
+ }
+ break;
+ case CELLTYPE_VALUE :
+ {
+ sal_uInt32 nFormat;
+ aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
+ if ( bFixedWidth || bSaveAsShown )
+ {
+ Color* pDummy;
+ ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
+ bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
+ }
+ else
+ {
+ ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
+ bString = FALSE;
+ }
+ }
+ break;
+ default:
+ DBG_ERROR( "ScDocShell::AsciiSave: unknown CellType" );
+ aString.Erase();
+ bString = FALSE;
+ }
+
+ if ( bFixedWidth )
+ {
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)
+ ((const SvxHorJustifyItem*) aDocument.GetAttr( nCol, nRow,
+ nTab, ATTR_HOR_JUSTIFY ))->GetValue();
+ lcl_ScDocShell_GetFixedWidthString( aString, aDocument, nTab, nCol,
+ !bString, eHorJust );
+ rStream.WriteUnicodeOrByteText( aString );
+ }
+ else
+ {
+ if (!bString && cStrDelim != 0 && aString.Len() > 0)
+ {
+ sal_Unicode c = aString.GetChar(0);
+ bString = (c == cStrDelim || c == ' ' ||
+ aString.GetChar( aString.Len()-1) == ' ' ||
+ aString.Search( cStrDelim) != STRING_NOTFOUND);
+ if (!bString && cDelim != 0)
+ bString = (aString.Search( cDelim) != STRING_NOTFOUND);
+ }
+ if ( bString )
+ {
+ if ( cStrDelim != 0 ) //@ BugId 55355
+ {
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ {
+ xub_StrLen nPos = aString.Search( cStrDelim );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aString.Insert( cStrDelim, nPos );
+ nPos = aString.Search( cStrDelim, nPos+2 );
+ }
+ rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
+ rStream.WriteUnicodeText( aString );
+ rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
+ }
+ else
+ {
+ // #105549# This is nasty. The Unicode to byte encoding
+ // may convert typographical quotation marks to ASCII
+ // quotation marks, which may interfer with the delimiter,
+ // so we have to escape delimiters after the string has
+ // been encoded. Since this may happen also with UTF-8
+ // encoded typographical quotation marks if such was
+ // specified as a delimiter we have to check for the full
+ // encoded delimiter string, not just one character.
+ // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
+ // dead encodings where one code point (and especially a
+ // low ASCII value) may represent different characters, we
+ // have to convert forth and back and forth again. Same for
+ // UTF-7 since it is a context sensitive encoding too.
+
+ if ( bContextOrNotAsciiEncoding )
+ {
+ // to byte encoding
+ ByteString aStrEnc( aString, eCharSet );
+ // back to Unicode
+ UniString aStrDec( aStrEnc, eCharSet );
+ // search on re-decoded string
+ xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aStrDec.Insert( aStrDelimDecoded, nPos );
+ nPos = aStrDec.Search( aStrDelimDecoded,
+ nPos+1+aStrDelimDecoded.Len() );
+ }
+ // write byte re-encoded
+ rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
+ rStream.WriteUnicodeOrByteText( aStrDec, eCharSet );
+ rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
+ }
+ else
+ {
+ ByteString aStrEnc( aString, eCharSet );
+ // search on encoded string
+ xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aStrEnc.Insert( aStrDelimEncoded, nPos );
+ nPos = aStrEnc.Search( aStrDelimEncoded,
+ nPos+1+aStrDelimEncoded.Len() );
+ }
+ // write byte encoded
+ rStream.Write( aStrDelimEncoded.GetBuffer(),
+ aStrDelimEncoded.Len() );
+ rStream.Write( aStrEnc.GetBuffer(), aStrEnc.Len() );
+ rStream.Write( aStrDelimEncoded.GetBuffer(),
+ aStrDelimEncoded.Len() );
+ }
+ }
+ }
+ else
+ rStream.WriteUnicodeOrByteText( aString );
+ }
+ else
+ rStream.WriteUnicodeOrByteText( aString );
+ }
+
+ if( nCol < nEndCol )
+ {
+ if(cDelim!=0) //@ BugId 55355
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ else
+ endlub( rStream );
+
+ if ( bProgress )
+ aProgress.SetStateOnPercent( nRow );
+ }
+
+ // write out empty if requested
+ if ( nNextRow <= nEndRow )
+ {
+ for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
+ { // remaining empty columns of last row
+ if ( bFixedWidth )
+ lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
+ aDocument, nTab, nEmptyCol );
+ else if ( cDelim != 0 )
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ endlub( rStream );
+ nNextRow++;
+ }
+ for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ )
+ { // entire empty rows
+ for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
+ {
+ if ( bFixedWidth )
+ lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
+ aDocument, nTab, nEmptyCol );
+ else if ( cDelim != 0 )
+ rStream.WriteUniOrByteChar( cDelim );
+ }
+ endlub( rStream );
+ }
+
+ rStream.SetStreamCharSet( eOldCharSet );
+ rStream.SetNumberFormatInt( nOldNumberFormatInt );
+}
+
+BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );
+
+ ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
+
+ // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
+ // it's already in ExecuteSave (as for Save and SaveAs)
+
+ if (pAutoStyleList)
+ pAutoStyleList->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren
+ if (GetCreateMode()== SFX_CREATE_MODE_STANDARD)
+ SfxObjectShell::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea
+
+ DBG_ASSERT( rMed.GetFilter(), "Filter == 0" );
+
+ BOOL bRet = FALSE;
+ String aFltName = rMed.GetFilter()->GetFilterName();
+
+/*
+ if (aFltName.EqualsAscii(pFilterLotus))
+ {
+ SvStream* pStream = rMed.GetOutStream();
+ if (pStream)
+ {
+ FltError eError = ScFormatFilter::Get().ScExportLotus123( *pStream, &aDocument, ExpWK1,
+ CHARSET_IBMPC_437 );
+ bRet = eError == eERR_OK;
+ }
+ }
+ else
+*/
+ if (aFltName.EqualsAscii(pFilterXML))
+ {
+ //TODO/LATER: this shouldn't happen!
+ DBG_ERROR("XML filter in ConvertFrom?!");
+ bRet = SaveXML( &rMed, NULL );
+ }
+ else if (aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
+ aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx5Temp) ||
+ aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) ||
+ aFltName.EqualsAscii(pFilterEx07Xml))
+ {
+ WaitObject aWait( GetActiveDialogParent() );
+
+ bool bDoSave = true;
+ if( ScTabViewShell* pViewShell = GetBestViewShell() )
+ {
+ ScExtDocOptions* pExtDocOpt = aDocument.GetExtDocOptions();
+ if( !pExtDocOpt )
+ aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
+ pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );
+
+ /* #115980# #i104990# If the imported document contains a medium
+ password, determine if we can save it, otherwise ask the users
+ whether they want to save without it. */
+ if( (rMed.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION) == 0 )
+ {
+ SfxItemSet* pItemSet = rMed.GetItemSet();
+ const SfxPoolItem* pItem = 0;
+ if( pItemSet && pItemSet->GetItemState( SID_PASSWORD, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ bDoSave = ScWarnPassword::WarningOnPassword( rMed );
+ // #i42858# remove password from medium (warn only one time)
+ if( bDoSave )
+ pItemSet->ClearItem( SID_PASSWORD );
+ }
+ }
+
+#if ENABLE_SHEET_PROTECTION
+ if( bDoSave )
+ {
+ bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen( aDocument, PASSHASH_XL );
+ bDoSave = !bNeedRetypePassDlg || pViewShell->ExecuteRetypePassDlg( PASSHASH_XL );
+ }
+#endif
+ }
+
+ if( bDoSave )
+ {
+ ExportFormatExcel eFormat = ExpBiff5;
+ if( aFltName.EqualsAscii( pFilterExcel97 ) || aFltName.EqualsAscii( pFilterEx97Temp ) )
+ eFormat = ExpBiff8;
+ if( aFltName.EqualsAscii( pFilterEx07Xml ) )
+ eFormat = Exp2007Xml;
+ FltError eError = ScFormatFilter::Get().ScExportExcel5( rMed, &aDocument, eFormat, RTL_TEXTENCODING_MS_1252 );
+
+ if( eError && !GetError() )
+ 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);
+ }
+ else
+ {
+ // export aborted, i.e. "Save without password" warning
+ SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterAscii))
+ {
+ SvStream* pStream = rMed.GetOutStream();
+ if (pStream)
+ {
+ String sItStr;
+ SfxItemSet* pSet = rMed.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ sItStr = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if ( sItStr.Len() == 0 )
+ {
+ // default for ascii export (from API without options):
+ // ISO8859-1/MS_1252 encoding, comma, double quotes
+
+ ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
+ sItStr = aDefOptions.BuildString();
+ }
+
+ WaitObject aWait( GetActiveDialogParent() );
+ ScImportOptions aOptions( sItStr );
+ AsciiSave( *pStream, aOptions );
+ bRet = TRUE;
+
+ if (aDocument.GetTableCount() > 1)
+ if (!rMed.GetError())
+ rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterDBase))
+ {
+ String sCharSet;
+ SfxItemSet* pSet = rMed.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ sCharSet = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (sCharSet.Len() == 0)
+ {
+ // default for dBase export (from API without options):
+ // IBM_850 encoding
+
+ sCharSet = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
+ }
+
+ WaitObject aWait( GetActiveDialogParent() );
+// HACK damit Sba geoffnetes TempFile ueberschreiben kann
+ rMed.CloseOutStream();
+ BOOL bHasMemo = FALSE;
+
+ ULONG eError = DBaseExport( rMed.GetPhysicalName(),
+ ScGlobal::GetCharsetValue(sCharSet), bHasMemo );
+
+ if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) )
+ {
+//! if ( !rMed.GetError() )
+//! 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, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ INetURLObject aTmpFile( rMed.GetPhysicalName(), INET_PROT_FILE );
+ if ( bHasMemo )
+ aTmpFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
+ if ( eError != eERR_OK )
+ {
+ if (!GetError())
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ if ( bHasMemo && IsDocument( aTmpFile ) )
+ KillFile( aTmpFile );
+ }
+ else
+ {
+ bRet = TRUE;
+ if ( bHasMemo )
+ {
+ SfxStringItem* pNameItem =
+ (SfxStringItem*) rMed.GetItemSet()->GetItem( SID_FILE_NAME );
+ INetURLObject aDbtFile( pNameItem->GetValue(), INET_PROT_FILE );
+ aDbtFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
+ if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) )
+ bRet = FALSE;
+ if ( bRet && !MoveFile( aTmpFile, aDbtFile ) )
+ bRet = FALSE;
+ if ( !bRet )
+ {
+ KillFile( aTmpFile );
+ if ( !GetError() )
+ SetError( SCERR_EXPORT_DATA, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterDif))
+ {
+ SvStream* pStream = rMed.GetOutStream();
+ if (pStream)
+ {
+ String sItStr;
+ SfxItemSet* pSet = rMed.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET ==
+ pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ {
+ sItStr = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (sItStr.Len() == 0)
+ {
+ // default for DIF export (from API without options):
+ // ISO8859-1/MS_1252 encoding
+
+ sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
+ }
+
+ WaitObject aWait( GetActiveDialogParent() );
+ ScFormatFilter::Get().ScExportDif( *pStream, &aDocument, ScAddress(0,0,0),
+ ScGlobal::GetCharsetValue(sItStr) );
+ bRet = TRUE;
+
+ if (aDocument.GetTableCount() > 1)
+ if (!rMed.GetError())
+ rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterSylk))
+ {
+ SvStream* pStream = rMed.GetOutStream();
+ if ( pStream )
+ {
+ WaitObject aWait( GetActiveDialogParent() );
+
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aDocument.GetCellArea( 0, nEndCol, nEndRow );
+ ScRange aRange( 0,0,0, nEndCol,nEndRow,0 );
+
+ ScImportExport aImExport( &aDocument, aRange );
+ aImExport.SetFormulas( TRUE );
+ bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK );
+ }
+ }
+ else if (aFltName.EqualsAscii(pFilterHtml))
+ {
+ SvStream* pStream = rMed.GetOutStream();
+ if ( pStream )
+ {
+ WaitObject aWait( GetActiveDialogParent() );
+ ScImportExport aImExport( &aDocument );
+ aImExport.SetStreamPath( rMed.GetName() );
+ bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_HTML );
+ if ( bRet && aImExport.GetNonConvertibleChars().Len() )
+ SetError( *new StringErrorInfo(
+ SCWARN_EXPORT_NONCONVERTIBLE_CHARS,
+ aImExport.GetNonConvertibleChars(),
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ else
+ {
+ if (GetError())
+ SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ return bRet;
+}
+
+
+BOOL __EXPORT ScDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor )
+{
+ return SfxObjectShell::SaveCompleted( xStor );
+}
+
+
+BOOL __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor )
+{
+ BOOL bRet = SfxObjectShell::DoSaveCompleted( pNewStor );
+
+ // SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write
+ Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) );
+ return bRet;
+}
+
+
+sal_Bool ScDocShell::QuerySlotExecutable( USHORT nSlotId )
+{
+ // #i112634# ask VBA event handlers whether to save or print the document
+
+ using namespace ::com::sun::star::script::vba;
+
+ sal_Int32 nVbaEventId = VBAEventId::NO_EVENT;
+ uno::Sequence< uno::Any > aArgs;
+ switch( nSlotId )
+ {
+ case SID_SAVEDOC:
+ case SID_SAVEASDOC:
+ nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE;
+ aArgs.realloc( 1 );
+ aArgs[ 0 ] <<= (nSlotId == SID_SAVEASDOC);
+ break;
+ case SID_PRINTDOC:
+ case SID_PRINTDOCDIRECT:
+ nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT;
+ break;
+ }
+
+ sal_Bool bSlotExecutable = sal_True;
+ if( nVbaEventId != VBAEventId::NO_EVENT ) try
+ {
+ uno::Reference< XVBAEventProcessor > xEventProcessor( aDocument.GetVbaEventProcessor(), uno::UNO_QUERY_THROW );
+ xEventProcessor->processVbaEvent( nVbaEventId, aArgs );
+ }
+ catch( util::VetoException& )
+ {
+ bSlotExecutable = sal_False;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return bSlotExecutable;
+}
+
+
+USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing )
+{
+ if(SC_MOD()->GetCurRefDlgId()>0)
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
+ if( pFrame )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
+ if(pViewSh!=NULL)
+ {
+ Window *pWin=pViewSh->GetWindow();
+ if(pWin!=NULL) pWin->GrabFocus();
+ }
+ }
+
+ return FALSE;
+ }
+ if ( aDocument.IsInLinkUpdate() || aDocument.IsInInterpreter() )
+ {
+ ErrorMessage(STR_CLOSE_ERROR_LINK);
+ return FALSE;
+ }
+
+ DoEnterHandler();
+
+ // start 'Workbook_BeforeClose' VBA event handler for possible veto
+ if( !IsInPrepareClose() )
+ {
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( aDocument.GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ uno::Sequence< uno::Any > aArgs;
+ xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs );
+ }
+ catch( util::VetoException& )
+ {
+ // if event processor throws VetoException, macro has vetoed close
+ return sal_False;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ // end handler code
+
+ USHORT nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing );
+ if (nRet == TRUE) // TRUE = schliessen
+ aDocument.DisableIdle(TRUE); // nicht mehr drin rumpfuschen !!!
+
+ return nRet;
+}
+
+void ScDocShell::PrepareReload()
+{
+ SfxObjectShell::PrepareReload(); // tut nichts?
+
+ // Das Disconnect von DDE-Links kann Reschedule ausloesen.
+ // Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload
+ // aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest
+ // werden. Dabei verklemmt sicht dann irgendwas.
+ // -> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten
+
+ aDocument.DisconnectDdeLinks();
+}
+
+
+String ScDocShell::GetOwnFilterName() // static
+{
+ return String::CreateFromAscii(pFilterSc50);
+}
+
+String ScDocShell::GetHtmlFilterName()
+{
+ return String::CreateFromAscii(pFilterHtml);
+}
+
+String ScDocShell::GetWebQueryFilterName() // static
+{
+ return String::CreateFromAscii(pFilterHtmlWebQ);
+}
+
+String ScDocShell::GetAsciiFilterName() // static
+{
+ return String::CreateFromAscii(pFilterAscii);
+}
+
+String ScDocShell::GetLotusFilterName() // static
+{
+ return String::CreateFromAscii(pFilterLotus);
+}
+
+String ScDocShell::GetDBaseFilterName() // static
+{
+ return String::CreateFromAscii(pFilterDBase);
+}
+
+String ScDocShell::GetDifFilterName() // static
+{
+ return String::CreateFromAscii(pFilterDif);
+}
+
+BOOL ScDocShell::HasAutomaticTableName( const String& rFilter ) // static
+{
+ // TRUE for those filters that keep the default table name
+ // (which is language specific)
+
+ return rFilter.EqualsAscii( pFilterAscii )
+ || rFilter.EqualsAscii( pFilterLotus )
+ || rFilter.EqualsAscii( pFilterExcel4 )
+ || rFilter.EqualsAscii( pFilterEx4Temp )
+ || rFilter.EqualsAscii( pFilterDBase )
+ || rFilter.EqualsAscii( pFilterDif )
+ || rFilter.EqualsAscii( pFilterSylk )
+ || rFilter.EqualsAscii( pFilterHtml )
+ || rFilter.EqualsAscii( pFilterRtf );
+}
+
+//==================================================================
+
+#define __SCDOCSHELL_INIT \
+ aDocument ( SCDOCMODE_DOCUMENT, this ), \
+ aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), \
+ nPrtToScreenFactor( 1.0 ), \
+ pImpl ( new DocShell_Impl ), \
+ bHeaderOn ( TRUE ), \
+ bFooterOn ( TRUE ), \
+ bNoInformLost ( TRUE ), \
+ bIsEmpty ( TRUE ), \
+ bIsInUndo ( FALSE ), \
+ bDocumentModifiedPending( FALSE ), \
+ nDocumentLock ( 0 ), \
+ nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG), \
+ bUpdateEnabled ( TRUE ), \
+ pOldAutoDBRange ( NULL ), \
+ pDocHelper ( NULL ), \
+ pAutoStyleList ( NULL ), \
+ pPaintLockData ( NULL ), \
+ pOldJobSetup ( NULL ), \
+ pSolverSaveData ( NULL ), \
+ pSheetSaveData ( NULL ), \
+ pModificator ( NULL )
+
+//------------------------------------------------------------------
+
+ScDocShell::ScDocShell( const ScDocShell& rShell )
+ : SvRefBase(),
+ SotObject(),
+ SfxObjectShell( rShell.GetCreateMode() ),
+ SfxListener(),
+ __SCDOCSHELL_INIT
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );
+
+ SetPool( &SC_MOD()->GetPool() );
+
+ bIsInplace = rShell.bIsInplace;
+
+ pDocFunc = new ScDocFunc(*this);
+
+ // SetBaseModel needs exception handling
+ ScModelObj::CreateAndSet( this );
+
+ StartListening(*this);
+ SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
+ if (pStlPool)
+ StartListening(*pStlPool);
+
+ GetPageOnFromPageStyleSet( NULL, 0, bHeaderOn, bFooterOn );
+ SetHelpId( HID_SCSHELL_DOCSH );
+
+ // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
+}
+
+//------------------------------------------------------------------
+
+ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags )
+ : SfxObjectShell( i_nSfxCreationFlags )
+ , __SCDOCSHELL_INIT
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );
+
+ SetPool( &SC_MOD()->GetPool() );
+
+ bIsInplace = (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
+ // wird zurueckgesetzt, wenn nicht inplace
+
+ pDocFunc = new ScDocFunc(*this);
+
+ // SetBaseModel needs exception handling
+ ScModelObj::CreateAndSet( this );
+
+ StartListening(*this);
+ SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
+ if (pStlPool)
+ StartListening(*pStlPool);
+ SetHelpId( HID_SCSHELL_DOCSH );
+
+ aDocument.GetDBCollection()->SetRefreshHandler(
+ LINK( this, ScDocShell, RefreshDBDataHdl ) );
+
+ // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
+}
+
+//------------------------------------------------------------------
+
+__EXPORT ScDocShell::~ScDocShell()
+{
+ ResetDrawObjectShell(); // #55570# falls der Drawing-Layer noch versucht, darauf zuzugreifen
+
+ SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
+ if (pStlPool)
+ EndListening(*pStlPool);
+ EndListening(*this);
+
+ delete pAutoStyleList;
+
+ SfxApplication *pSfxApp = SFX_APP();
+ if ( pSfxApp->GetDdeService() ) // DDE vor Dokument loeschen
+ pSfxApp->RemoveDdeTopic( this );
+
+ delete pDocFunc;
+ delete aDocument.mpUndoManager;
+ aDocument.mpUndoManager = 0;
+ delete pImpl;
+
+ delete pPaintLockData;
+
+ delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob()
+
+ delete pSolverSaveData;
+ delete pSheetSaveData;
+ delete pOldAutoDBRange;
+
+ if (pModificator)
+ {
+ DBG_ERROR("The Modificator should not exist");
+ delete pModificator;
+ }
+}
+
+//------------------------------------------------------------------
+
+SfxUndoManager* __EXPORT ScDocShell::GetUndoManager()
+{
+ return aDocument.GetUndoManager();
+}
+
+void ScDocShell::SetModified( BOOL bModified )
+{
+ if ( SfxObjectShell::IsEnableSetModified() )
+ {
+ SfxObjectShell::SetModified( bModified );
+ Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) );
+ }
+}
+
+
+void ScDocShell::SetDocumentModified( BOOL bIsModified /* = TRUE */ )
+{
+ // BroadcastUno muss auch mit pPaintLockData sofort passieren
+ //! auch bei SetDrawModified, wenn Drawing angebunden ist
+ //! dann eigener Hint???
+
+ if ( pPaintLockData && bIsModified )
+ {
+ //! BCA_BRDCST_ALWAYS etc. also needed here?
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
+ pPaintLockData->SetModified(); // spaeter...
+ return;
+ }
+
+ SetDrawModified( bIsModified );
+
+ if ( bIsModified )
+ {
+ if ( aDocument.IsAutoCalcShellDisabled() )
+ SetDocumentModifiedPending( TRUE );
+ else
+ {
+ SetDocumentModifiedPending( FALSE );
+ aDocument.InvalidateStyleSheetUsage();
+ aDocument.InvalidateTableArea();
+ aDocument.InvalidateLastTableOpParams();
+ aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
+ if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() )
+ aDocument.CalcFormulaTree( TRUE );
+ PostDataChanged();
+
+ // Detective AutoUpdate:
+ // Update if formulas were modified (DetectiveDirty) or the list contains
+ // "Trace Error" entries (#75362# - Trace Error can look completely different
+ // after changes to non-formula cells).
+
+ ScDetOpList* pList = aDocument.GetDetOpList();
+ if ( pList && ( aDocument.IsDetectiveDirty() || pList->HasAddError() ) &&
+ pList->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
+ {
+ GetDocFunc().DetectiveRefresh(TRUE); // TRUE = caused by automatic update
+ }
+ aDocument.SetDetectiveDirty(FALSE); // always reset, also if not refreshed
+ }
+
+ // #b6697848# notify UNO objects after BCA_BRDCST_ALWAYS etc.
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+ }
+}
+
+// SetDrawModified - ohne Formel-Update
+// (Drawing muss auch beim normalen SetDocumentModified upgedated werden,
+// z.B. bei Tabelle loeschen etc.)
+
+void ScDocShell::SetDrawModified( BOOL bIsModified /* = TRUE */ )
+{
+ BOOL bUpdate = ( bIsModified != IsModified() );
+
+ SetModified( bIsModified );
+
+ SfxBindings* pBindings = GetViewBindings();
+ if (bUpdate)
+ {
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_SAVEDOC );
+ pBindings->Invalidate( SID_DOC_MODIFIED );
+ }
+ }
+
+ if (bIsModified)
+ {
+ if (pBindings)
+ {
+ // #i105960# Undo etc used to be volatile.
+ // They always have to be invalidated, including drawing layer or row height changes
+ // (but not while pPaintLockData is set).
+ pBindings->Invalidate( SID_UNDO );
+ pBindings->Invalidate( SID_REDO );
+ pBindings->Invalidate( SID_REPEAT );
+ }
+
+ if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
+ {
+ aDocument.UpdateChartListenerCollection();
+ SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED )); // Navigator
+ }
+ SC_MOD()->AnythingChanged();
+ }
+}
+
+void ScDocShell::SetInUndo(BOOL bSet)
+{
+ bIsInUndo = bSet;
+}
+
+
+void ScDocShell::GetDocStat( ScDocStat& rDocStat )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+
+ aDocument.GetDocStat( rDocStat );
+ rDocStat.nPageCount = 0;
+
+ if ( pPrinter )
+ for ( SCTAB i=0; i<rDocStat.nTableCount; i++ )
+ rDocStat.nPageCount = sal::static_int_cast<USHORT>( rDocStat.nPageCount +
+ (USHORT) ScPrintFunc( this, pPrinter, i ).GetTotalPages() );
+}
+
+
+SfxDocumentInfoDialog* __EXPORT ScDocShell::CreateDocumentInfoDialog(
+ Window *pParent, const SfxItemSet &rSet )
+{
+ SfxDocumentInfoDialog* pDlg = new SfxDocumentInfoDialog( pParent, rSet );
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current());
+
+ //nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht
+ //aus dem Doc-Manager
+
+ if( pDocSh == this )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ ::CreateTabPage ScDocStatPageCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_STAT );
+ DBG_ASSERT(ScDocStatPageCreate, "Tabpage create fail!");//CHINA001
+ pDlg->AddTabPage( 42,
+ ScGlobal::GetRscString( STR_DOC_STAT ),
+ ScDocStatPageCreate,
+ NULL);
+//CHINA001 pDlg->AddTabPage( 42,
+//CHINA001 ScGlobal::GetRscString( STR_DOC_STAT ),
+//CHINA001 ScDocStatPage::Create,
+//CHINA001 NULL );
+ }
+ return pDlg;
+}
+
+Window* ScDocShell::GetActiveDialogParent()
+{
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ return pViewSh->GetDialogParent();
+ else
+ return Application::GetDefDialogParent();
+}
+
+void ScDocShell::SetSolverSaveData( const ScOptSolverSave& rData )
+{
+ delete pSolverSaveData;
+ pSolverSaveData = new ScOptSolverSave( rData );
+}
+
+ScSheetSaveData* ScDocShell::GetSheetSaveData()
+{
+ if (!pSheetSaveData)
+ pSheetSaveData = new ScSheetSaveData;
+
+ return pSheetSaveData;
+}
+
+void ScDocShell::UseSheetSaveEntries()
+{
+ if (pSheetSaveData)
+ {
+ pSheetSaveData->UseSaveEntries(); // use positions from saved file for next saving
+
+ bool bHasEntries = false;
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nTab;
+ for (nTab = 0; nTab < nTabCount; ++nTab)
+ if (pSheetSaveData->HasStreamPos(nTab))
+ bHasEntries = true;
+
+ if (!bHasEntries)
+ {
+ // if no positions were set (for example, export to other format),
+ // reset all "valid" flags
+
+ for (nTab = 0; nTab < nTabCount; ++nTab)
+ if (aDocument.IsStreamValid(nTab))
+ aDocument.SetStreamValid(nTab, FALSE);
+ }
+ }
+}
+
+// --- ScDocShellModificator ------------------------------------------
+
+ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS )
+ :
+ rDocShell( rDS ),
+ aProtector( rDS.GetDocument()->GetRefreshTimerControlAddress() )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ bAutoCalcShellDisabled = pDoc->IsAutoCalcShellDisabled();
+ bIdleDisabled = pDoc->IsIdleDisabled();
+ pDoc->SetAutoCalcShellDisabled( TRUE );
+ pDoc->DisableIdle( TRUE );
+}
+
+
+ScDocShellModificator::~ScDocShellModificator()
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
+ if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() )
+ rDocShell.SetDocumentModified(); // last one shuts off the lights
+ pDoc->DisableIdle( bIdleDisabled );
+}
+
+
+void ScDocShellModificator::SetDocumentModified()
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if ( !pDoc->IsImportingXML() )
+ {
+ // AutoCalcShellDisabled temporaer restaurieren
+ BOOL bDisabled = pDoc->IsAutoCalcShellDisabled();
+ pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
+ rDocShell.SetDocumentModified();
+ pDoc->SetAutoCalcShellDisabled( bDisabled );
+ }
+ else
+ {
+ // uno broadcast is necessary for api to work
+ // -> must also be done during xml import
+ pDoc->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+ }
+}
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+sal_Bool ScDocShell::AcceptStateUpdate() const
+{
+ if( SfxObjectShell::AcceptStateUpdate() )
+ return sal_True;
+
+ if( SC_MOD()->Find1RefWindow( SFX_APP()->GetTopWindow() ) )
+ return sal_True;
+
+ return sal_False;
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+
+bool ScDocShell::IsChangeRecording() const
+{
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ return pChangeTrack != NULL;
+}
+
+
+bool ScDocShell::HasChangeRecordProtection() const
+{
+ bool bRes = false;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if (pChangeTrack)
+ bRes = pChangeTrack->IsProtected();
+ return bRes;
+}
+
+
+void ScDocShell::SetChangeRecording( bool bActivate )
+{
+ bool bOldChangeRecording = IsChangeRecording();
+
+ if (bActivate)
+ {
+ aDocument.StartChangeTracking();
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ aDocument.SetChangeViewSettings(aChangeViewSet);
+ }
+ else
+ {
+ aDocument.EndChangeTracking();
+ PostPaintGridAll();
+ }
+
+ if (bOldChangeRecording != IsChangeRecording())
+ {
+ UpdateAcceptChangesDialog();
+ // Slots invalidieren
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ pBindings->InvalidateAll(FALSE);
+ }
+}
+
+
+bool ScDocShell::SetProtectionPassword( const String &rNewPassword )
+{
+ bool bRes = false;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if (pChangeTrack)
+ {
+ sal_Bool bProtected = pChangeTrack->IsProtected();
+
+ if (rNewPassword.Len())
+ {
+ // when password protection is applied change tracking must always be active
+ SetChangeRecording( true );
+
+ ::com::sun::star::uno::Sequence< sal_Int8 > aProtectionHash;
+ SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword );
+ pChangeTrack->SetProtection( aProtectionHash );
+ }
+ else
+ {
+ pChangeTrack->SetProtection( ::com::sun::star::uno::Sequence< sal_Int8 >() );
+ }
+ bRes = true;
+
+ if ( bProtected != pChangeTrack->IsProtected() )
+ {
+ UpdateAcceptChangesDialog();
+ SetDocumentModified();
+ }
+ }
+
+ return bRes;
+}
+
+
+bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash )
+{
+ bool bRes = false;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if (pChangeTrack && pChangeTrack->IsProtected())
+ {
+ rPasswordHash = pChangeTrack->GetProtection();
+ bRes = true;
+ }
+ return bRes;
+}
+
+
diff --git a/sc/source/ui/docshell/docsh2.cxx b/sc/source/ui/docshell/docsh2.cxx
new file mode 100644
index 000000000000..14ff7622818c
--- /dev/null
+++ b/sc/source/ui/docshell/docsh2.cxx
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <svx/svdpage.hxx>
+
+
+#include <svx/xtable.hxx>
+
+#include "scitems.hxx"
+#include <tools/gen.hxx>
+#include <svtools/ctrltool.hxx>
+#include <editeng/flstitem.hxx>
+#include <svx/drawitem.hxx>
+#include <sfx2/printer.hxx>
+#include <svl/smplhint.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoole2.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/asiancfg.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <editeng/unolingu.hxx>
+#include <rtl/logfile.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/basmgr.hxx>
+#include <sfx2/app.hxx>
+
+// INCLUDE ---------------------------------------------------------------
+/*
+#include <svdrwetc.hxx>
+#include <svdrwobx.hxx>
+#include <sostor.hxx>
+*/
+#include "drwlayer.hxx"
+#include "stlpool.hxx"
+#include "docsh.hxx"
+#include "docshimp.hxx"
+#include "docfunc.hxx"
+#include "sc.hrc"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xStor )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::InitNew" );
+
+ BOOL bRet = SfxObjectShell::InitNew( xStor );
+
+ aDocument.MakeTable(0);
+ // zusaetzliche Tabellen werden von der ersten View angelegt,
+ // wenn bIsEmpty dann noch TRUE ist
+
+ if( bRet )
+ {
+ Size aSize( (long) ( STD_COL_WIDTH * HMM_PER_TWIPS * OLE_STD_CELLS_X ),
+ (long) ( ScGlobal::nStdRowHeight * HMM_PER_TWIPS * OLE_STD_CELLS_Y ) );
+ // hier muss auch der Start angepasst werden
+ SetVisAreaOrSize( Rectangle( Point(), aSize ), TRUE );
+ }
+
+ aDocument.SetDrawDefaults(); // drawing layer defaults that are set only in InitNew
+
+ // InitOptions sets the document languages, must be called before CreateStandardStyles
+ InitOptions(false);
+
+ aDocument.GetStyleSheetPool()->CreateStandardStyles();
+ aDocument.UpdStlShtPtrsFrmNms();
+
+ // SetDocumentModified ist in Load/InitNew nicht mehr erlaubt!
+
+ InitItems();
+ CalcOutputFactor();
+#if 0
+ uno::Any aGlobs;
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[ 0 ] <<= GetModel();
+ aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs );
+ GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
+ // Fake ThisComponent being setup by Activate ( which is a view
+ // related thing ),
+ // a) if another document is opened then in theory ThisComponent
+ // will be reset as before,
+ // b) when this document is 'really' Activated then ThisComponent
+ // again will be set as before
+ // The only wrinkle seems if this document is loaded 'InVisible'
+ // but.. I don't see that this is possible from the vba API
+ // I could be wrong though
+ // There may be implications setting the current component
+ // too early :-/ so I will just manually set the Basic Variables
+ BasicManager* pAppMgr = SFX_APP()->GetBasicManager();
+ if ( pAppMgr )
+ pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] );
+#endif
+
+ return bRet;
+}
+
+//------------------------------------------------------------------
+
+BOOL ScDocShell::IsEmpty() const
+{
+ return bIsEmpty;
+}
+
+
+void ScDocShell::SetEmpty(BOOL bSet)
+{
+ bIsEmpty = bSet;
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::InitItems()
+{
+ // AllItemSet fuer Controller mit benoetigten Items fuellen:
+
+ // if ( pImpl->pFontList )
+ // delete pImpl->pFontList;
+
+ // Druck-Optionen werden beim Drucken und evtl. in GetPrinter gesetzt
+
+ // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
+ //PutItem( SvxFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST ) );
+ UpdateFontList();
+
+ ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
+ if (pDrawLayer)
+ {
+ PutItem( SvxColorTableItem ( pDrawLayer->GetColorTable(), SID_COLOR_TABLE ) );
+ PutItem( SvxGradientListItem( pDrawLayer->GetGradientList(), SID_GRADIENT_LIST ) );
+ PutItem( SvxHatchListItem ( pDrawLayer->GetHatchList(), SID_HATCH_LIST ) );
+ PutItem( SvxBitmapListItem ( pDrawLayer->GetBitmapList(), SID_BITMAP_LIST ) );
+ PutItem( SvxDashListItem ( pDrawLayer->GetDashList(), SID_DASH_LIST ) );
+ PutItem( SvxLineEndListItem ( pDrawLayer->GetLineEndList(), SID_LINEEND_LIST ) );
+
+ // andere Anpassungen nach dem Anlegen des DrawLayers
+
+ pDrawLayer->SetNotifyUndoActionHdl( LINK( pDocFunc, ScDocFunc, NotifyDrawUndo ) );
+
+ //if (SfxObjectShell::HasSbxObject())
+ pDrawLayer->UpdateBasic(); // DocShell-Basic in DrawPages setzen
+ }
+ else
+ {
+ // always use global color table instead of local copy
+ PutItem( SvxColorTableItem( XColorTable::GetStdColorTable(), SID_COLOR_TABLE ) );
+ }
+
+ if ( !aDocument.GetForbiddenCharacters().isValid() ||
+ !aDocument.IsValidAsianCompression() || !aDocument.IsValidAsianKerning() )
+ {
+ // get settings from SvxAsianConfig
+ SvxAsianConfig aAsian( sal_False );
+
+ if ( !aDocument.GetForbiddenCharacters().isValid() )
+ {
+ // set forbidden characters if necessary
+ uno::Sequence<lang::Locale> aLocales = aAsian.GetStartEndCharLocales();
+ if (aLocales.getLength())
+ {
+ vos::ORef<SvxForbiddenCharactersTable> xForbiddenTable =
+ new SvxForbiddenCharactersTable( aDocument.GetServiceManager() );
+
+ const lang::Locale* pLocales = aLocales.getConstArray();
+ for (sal_Int32 i = 0; i < aLocales.getLength(); i++)
+ {
+ i18n::ForbiddenCharacters aForbidden;
+ aAsian.GetStartEndChars( pLocales[i], aForbidden.beginLine, aForbidden.endLine );
+ LanguageType eLang = SvxLocaleToLanguage(pLocales[i]);
+ //pDoc->SetForbiddenCharacters( eLang, aForbidden );
+
+ xForbiddenTable->SetForbiddenCharacters( eLang, aForbidden );
+ }
+
+ aDocument.SetForbiddenCharacters( xForbiddenTable );
+ }
+ }
+
+ if ( !aDocument.IsValidAsianCompression() )
+ {
+ // set compression mode from configuration if not already set (e.g. XML import)
+ aDocument.SetAsianCompression( sal::static_int_cast<BYTE>( aAsian.GetCharDistanceCompression() ) );
+ }
+
+ if ( !aDocument.IsValidAsianKerning() )
+ {
+ // set asian punctuation kerning from configuration if not already set (e.g. XML import)
+ aDocument.SetAsianKerning( !aAsian.IsKerningWesternTextOnly() ); // reversed
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::ResetDrawObjectShell()
+{
+ ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
+ if (pDrawLayer)
+ pDrawLayer->SetObjectShell( NULL );
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScDocShell::Activate()
+{
+}
+
+
+void __EXPORT ScDocShell::Deactivate()
+{
+}
+
+//------------------------------------------------------------------
+
+
+ScDrawLayer* ScDocShell::MakeDrawLayer()
+{
+ ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
+ if (!pDrawLayer)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::MakeDrawLayer" );
+
+ aDocument.InitDrawLayer(this);
+ pDrawLayer = aDocument.GetDrawLayer();
+ InitItems(); // incl. Undo und Basic
+ Broadcast( SfxSimpleHint( SC_HINT_DRWLAYER_NEW ) );
+ if (nDocumentLock)
+ pDrawLayer->setLock(TRUE);
+ }
+ return pDrawLayer;
+}
diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx
new file mode 100644
index 000000000000..233843935bbd
--- /dev/null
+++ b/sc/source/ui/docshell/docsh3.cxx
@@ -0,0 +1,1409 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+#include "scitems.hxx"
+#include "rangelst.hxx"
+#include <editeng/flstitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <svx/postattr.hxx>
+#include <editeng/sizeitem.hxx>
+#include <unotools/misccfg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "docsh.hxx"
+#include "docshimp.hxx"
+#include "scmod.hxx"
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+#include "patattr.hxx"
+#include "uiitems.hxx"
+#include "hints.hxx"
+#include "docoptio.hxx"
+#include "viewopti.hxx"
+#include "pntlock.hxx"
+#include "chgtrack.hxx"
+#include "docfunc.hxx"
+#include "cell.hxx"
+#include "chgviset.hxx"
+#include "progress.hxx"
+#include "redcom.hxx"
+#include "sc.hrc"
+#include "inputopt.hxx"
+#include "drwlayer.hxx"
+#include "inputhdl.hxx"
+#include "conflictsdlg.hxx"
+#include "globstr.hrc"
+
+#if DEBUG_CHANGETRACK
+#include <stdio.h>
+#endif // DEBUG_CHANGETRACK
+
+
+//------------------------------------------------------------------
+
+//
+// Redraw - Benachrichtigungen
+//
+
+
+void ScDocShell::PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos )
+{
+// Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) );
+
+ // Test: nur aktive ViewShell
+
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if (pViewSh && pViewSh->GetViewData()->GetDocShell() == this)
+ {
+ ScEditViewHint aHint( pEditEngine, rCursorPos );
+ pViewSh->Notify( *this, aHint );
+ }
+}
+
+void ScDocShell::PostDataChanged()
+{
+ Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
+ aDocument.ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
+
+ SFX_APP()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED )); // Navigator
+ //! Navigator direkt benachrichtigen!
+}
+
+void ScDocShell::PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, USHORT nPart,
+ USHORT nExtFlags )
+{
+ if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+ if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+ if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+ if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+
+ if ( pPaintLockData )
+ {
+ // #i54081# PAINT_EXTRAS still has to be brodcast because it changes the
+ // current sheet if it's invalid. All other flags added to pPaintLockData.
+ USHORT nLockPart = nPart & ~PAINT_EXTRAS;
+ if ( nLockPart )
+ {
+ //! nExtFlags ???
+ pPaintLockData->AddRange( ScRange( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab ), nLockPart );
+ }
+
+ nPart &= PAINT_EXTRAS; // for broadcasting
+ if ( !nPart )
+ return;
+ }
+
+
+ if (nExtFlags & SC_PF_LINES) // Platz fuer Linien beruecksichtigen
+ {
+ //! Abfrage auf versteckte Spalten/Zeilen!
+ if (nStartCol>0) --nStartCol;
+ if (nEndCol<MAXCOL) ++nEndCol;
+ if (nStartRow>0) --nStartRow;
+ if (nEndRow<MAXROW) ++nEndRow;
+ }
+
+ // um zusammengefasste erweitern
+ if (nExtFlags & SC_PF_TESTMERGE)
+ aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nStartTab );
+
+ if ( nStartCol != 0 || nEndCol != MAXCOL )
+ {
+ // Extend to whole rows if SC_PF_WHOLEROWS is set, or rotated or non-left
+ // aligned cells are contained (see UpdatePaintExt).
+ // Special handling for RTL text (#i9731#) is unnecessary now with full
+ // support of right-aligned text.
+
+ if ( ( nExtFlags & SC_PF_WHOLEROWS ) ||
+ aDocument.HasAttrib( nStartCol,nStartRow,nStartTab,
+ MAXCOL,nEndRow,nEndTab, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
+ {
+ nStartCol = 0;
+ nEndCol = MAXCOL;
+ }
+ }
+
+ Broadcast( ScPaintHint( ScRange( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab ), nPart ) );
+
+ if ( nPart & PAINT_GRID )
+ aDocument.ResetChanged( ScRange(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) );
+}
+
+void ScDocShell::PostPaint( const ScRange& rRange, USHORT nPart, USHORT nExtFlags )
+{
+ PostPaint( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(),
+ nPart, nExtFlags );
+}
+
+void ScDocShell::PostPaintGridAll()
+{
+ PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+}
+
+void ScDocShell::PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, SC_PF_TESTMERGE );
+}
+
+void ScDocShell::PostPaintCell( const ScAddress& rPos )
+{
+ PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() );
+}
+
+void ScDocShell::PostPaintExtras()
+{
+ PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS );
+}
+
+void ScDocShell::UpdatePaintExt( USHORT& rExtFlags, const ScRange& rRange )
+{
+ if ( ( rExtFlags & SC_PF_LINES ) == 0 && aDocument.HasAttrib( rRange, HASATTR_PAINTEXT ) )
+ {
+ // If the range contains lines, shadow or conditional formats,
+ // set SC_PF_LINES to include one extra cell in all directions.
+
+ rExtFlags |= SC_PF_LINES;
+ }
+
+ if ( ( rExtFlags & SC_PF_WHOLEROWS ) == 0 &&
+ ( rRange.aStart.Col() != 0 || rRange.aEnd.Col() != MAXCOL ) &&
+ aDocument.HasAttrib( rRange, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
+ {
+ // If the range contains (logically) right- or center-aligned cells,
+ // or rotated cells, set SC_PF_WHOLEROWS to paint the whole rows.
+ // This test isn't needed after the cell changes, because it's also
+ // tested in PostPaint. UpdatePaintExt may later be changed to do this
+ // only if called before the changes.
+
+ rExtFlags |= SC_PF_WHOLEROWS;
+ }
+}
+
+void ScDocShell::UpdatePaintExt( USHORT& rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
+{
+ UpdatePaintExt( rExtFlags, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) );
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::LockPaint_Impl(BOOL bDoc)
+{
+ if ( !pPaintLockData )
+ pPaintLockData = new ScPaintLockData(0); //! Modus...
+ pPaintLockData->IncLevel(bDoc);
+}
+
+void ScDocShell::UnlockPaint_Impl(BOOL bDoc)
+{
+ if ( pPaintLockData )
+ {
+ if ( pPaintLockData->GetLevel(bDoc) )
+ pPaintLockData->DecLevel(bDoc);
+ if (!pPaintLockData->GetLevel(!bDoc) && !pPaintLockData->GetLevel(bDoc))
+ {
+ // Paint jetzt ausfuehren
+
+ ScPaintLockData* pPaint = pPaintLockData;
+ pPaintLockData = NULL; // nicht weitersammeln
+
+ ScRangeListRef xRangeList = pPaint->GetRangeList();
+ if (xRangeList)
+ {
+ USHORT nParts = pPaint->GetParts();
+ ULONG nCount = xRangeList->Count();
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ //! nExtFlags ???
+ ScRange aRange = *xRangeList->GetObject(i);
+ PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(),
+ nParts );
+ }
+ }
+
+ if ( pPaint->GetModified() )
+ SetDocumentModified();
+
+ delete pPaint;
+ }
+ }
+ else
+ {
+ DBG_ERROR("UnlockPaint ohne LockPaint");
+ }
+}
+
+void ScDocShell::LockDocument_Impl(USHORT nNew)
+{
+ if (!nDocumentLock)
+ {
+ ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
+ if (pDrawLayer)
+ pDrawLayer->setLock(TRUE);
+ }
+ nDocumentLock = nNew;
+}
+
+void ScDocShell::UnlockDocument_Impl(USHORT nNew)
+{
+ nDocumentLock = nNew;
+ if (!nDocumentLock)
+ {
+ ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
+ if (pDrawLayer)
+ pDrawLayer->setLock(FALSE);
+ }
+}
+
+USHORT ScDocShell::GetLockCount() const
+{
+ return nDocumentLock;
+}
+
+void ScDocShell::SetLockCount(USHORT nNew)
+{
+ if (nNew) // setzen
+ {
+ if ( !pPaintLockData )
+ pPaintLockData = new ScPaintLockData(0); //! Modus...
+ pPaintLockData->SetLevel(nNew-1, TRUE);
+ LockDocument_Impl(nNew);
+ }
+ else if (pPaintLockData) // loeschen
+ {
+ pPaintLockData->SetLevel(0, TRUE); // bei Unlock sofort ausfuehren
+ UnlockPaint_Impl(TRUE); // jetzt
+ UnlockDocument_Impl(0);
+ }
+}
+
+void ScDocShell::LockPaint()
+{
+ LockPaint_Impl(FALSE);
+}
+
+void ScDocShell::UnlockPaint()
+{
+ UnlockPaint_Impl(FALSE);
+}
+
+void ScDocShell::LockDocument()
+{
+ LockPaint_Impl(TRUE);
+ LockDocument_Impl(nDocumentLock + 1);
+}
+
+void ScDocShell::UnlockDocument()
+{
+ if (nDocumentLock)
+ {
+ UnlockPaint_Impl(TRUE);
+ UnlockDocument_Impl(nDocumentLock - 1);
+ }
+ else
+ {
+ DBG_ERROR("UnlockDocument without LockDocument");
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::SetInplace( BOOL bInplace )
+{
+ if (bIsInplace != bInplace)
+ {
+ bIsInplace = bInplace;
+ CalcOutputFactor();
+ }
+}
+
+void ScDocShell::CalcOutputFactor()
+{
+ if (bIsInplace)
+ {
+ nPrtToScreenFactor = 1.0; // passt sonst nicht zur inaktiven Darstellung
+ return;
+ }
+
+ BOOL bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
+ if (bTextWysiwyg)
+ {
+ nPrtToScreenFactor = 1.0;
+ return;
+ }
+
+ String aTestString = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789" ));
+ long nPrinterWidth = 0;
+ long nWindowWidth = 0;
+ const ScPatternAttr* pPattern = (const ScPatternAttr*)&aDocument.GetPool()->
+ GetDefaultItem(ATTR_PATTERN);
+
+ Font aDefFont;
+ OutputDevice* pRefDev = GetRefDevice();
+ MapMode aOldMode = pRefDev->GetMapMode();
+ Font aOldFont = pRefDev->GetFont();
+
+ pRefDev->SetMapMode(MAP_PIXEL);
+ pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, pRefDev); // font color doesn't matter here
+ pRefDev->SetFont(aDefFont);
+ nPrinterWidth = pRefDev->PixelToLogic( Size( pRefDev->GetTextWidth(aTestString), 0 ), MAP_100TH_MM ).Width();
+ pRefDev->SetFont(aOldFont);
+ pRefDev->SetMapMode(aOldMode);
+
+ VirtualDevice aVirtWindow( *Application::GetDefaultDevice() );
+ aVirtWindow.SetMapMode(MAP_PIXEL);
+ pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, &aVirtWindow); // font color doesn't matter here
+ aVirtWindow.SetFont(aDefFont);
+ nWindowWidth = aVirtWindow.GetTextWidth(aTestString);
+ nWindowWidth = (long) ( nWindowWidth / ScGlobal::nScreenPPTX * HMM_PER_TWIPS );
+
+ if (nPrinterWidth && nWindowWidth)
+ nPrtToScreenFactor = nPrinterWidth / (double) nWindowWidth;
+ else
+ {
+ DBG_ERROR("GetTextSize gibt 0 ??");
+ nPrtToScreenFactor = 1.0;
+ }
+}
+
+double ScDocShell::GetOutputFactor() const
+{
+ return nPrtToScreenFactor;
+}
+
+//---------------------------------------------------------------------
+
+void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load
+{
+ // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions
+
+ USHORT nDefLang, nCjkLang, nCtlLang;
+ BOOL bAutoSpell;
+ ScModule::GetSpellSettings( nDefLang, nCjkLang, nCtlLang, bAutoSpell );
+ ScModule* pScMod = SC_MOD();
+
+ ScDocOptions aDocOpt = pScMod->GetDocOptions();
+ ScViewOptions aViewOpt = pScMod->GetViewOptions();
+ aDocOpt.SetAutoSpell( bAutoSpell );
+
+ // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges
+ aDocOpt.SetYear2000( sal::static_int_cast<USHORT>( ::utl::MiscCfg().GetYear2000() ) );
+
+ if (bForLoading)
+ {
+ // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default,
+ // so it must not be taken from the global options.
+ // Calculation settings are handled separately in ScXMLBodyContext::EndElement.
+ aDocOpt.SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION );
+ }
+
+ aDocument.SetDocOptions( aDocOpt );
+ aDocument.SetViewOptions( aViewOpt );
+
+ // Druck-Optionen werden jetzt direkt vor dem Drucken gesetzt
+
+ aDocument.SetLanguage( (LanguageType) nDefLang, (LanguageType) nCjkLang, (LanguageType) nCtlLang );
+}
+
+//---------------------------------------------------------------------
+
+Printer* ScDocShell::GetDocumentPrinter() // fuer OLE
+{
+ return aDocument.GetPrinter();
+}
+
+SfxPrinter* ScDocShell::GetPrinter(BOOL bCreateIfNotExist)
+{
+ return aDocument.GetPrinter(bCreateIfNotExist);
+}
+
+void ScDocShell::UpdateFontList()
+{
+ delete pImpl->pFontList;
+ // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
+ pImpl->pFontList = new FontList( GetRefDevice(), NULL, FALSE ); // FALSE or TRUE???
+ SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
+ PutItem( aFontListItem );
+
+ CalcOutputFactor();
+}
+
+OutputDevice* ScDocShell::GetRefDevice()
+{
+ return aDocument.GetRefDevice();
+}
+
+USHORT ScDocShell::SetPrinter( SfxPrinter* pNewPrinter, USHORT nDiffFlags )
+{
+ SfxPrinter *pOld = aDocument.GetPrinter( FALSE );
+ if ( pOld && pOld->IsPrinting() )
+ return SFX_PRINTERROR_BUSY;
+
+ if (nDiffFlags & SFX_PRINTER_PRINTER)
+ {
+ if ( aDocument.GetPrinter() != pNewPrinter )
+ {
+ aDocument.SetPrinter( pNewPrinter );
+ aDocument.SetPrintOptions();
+
+ // MT: Use UpdateFontList: Will use Printer fonts only if needed!
+ /*
+ delete pImpl->pFontList;
+ pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
+ SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
+ PutItem( aFontListItem );
+
+ CalcOutputFactor();
+ */
+ if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
+ UpdateFontList();
+
+ ScModule* pScMod = SC_MOD();
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
+ while (pFrame)
+ {
+ SfxViewShell* pSh = pFrame->GetViewShell();
+ if (pSh && pSh->ISA(ScTabViewShell))
+ {
+ ScTabViewShell* pViewSh = (ScTabViewShell*)pSh;
+ ScInputHandler* pInputHdl = pScMod->GetInputHdl(pViewSh);
+ if (pInputHdl)
+ pInputHdl->UpdateRefDevice();
+ }
+ pFrame = SfxViewFrame::GetNext( *pFrame, this );
+ }
+ }
+ }
+ else if (nDiffFlags & SFX_PRINTER_JOBSETUP)
+ {
+ SfxPrinter* pOldPrinter = aDocument.GetPrinter();
+ if (pOldPrinter)
+ {
+ pOldPrinter->SetJobSetup( pNewPrinter->GetJobSetup() );
+
+ // #i6706# Call SetPrinter with the old printer again, so the drawing layer
+ // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
+ // because the JobSetup (printer device settings) may affect text layout.
+ aDocument.SetPrinter( pOldPrinter );
+ CalcOutputFactor(); // also with the new settings
+ }
+ }
+
+ if (nDiffFlags & SFX_PRINTER_OPTIONS)
+ {
+ aDocument.SetPrintOptions(); //! aus neuem Printer ???
+ }
+
+ if (nDiffFlags & (SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE))
+ {
+ String aStyle = aDocument.GetPageStyle( GetCurTab() );
+ ScStyleSheetPool* pStPl = aDocument.GetStyleSheetPool();
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)pStPl->Find(aStyle, SFX_STYLE_FAMILY_PAGE);
+ if (pStyleSheet)
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+
+ if (nDiffFlags & SFX_PRINTER_CHG_ORIENTATION)
+ {
+ const SvxPageItem& rOldItem = (const SvxPageItem&)rSet.Get(ATTR_PAGE);
+ BOOL bWasLand = rOldItem.IsLandscape();
+ BOOL bNewLand = ( pNewPrinter->GetOrientation() == ORIENTATION_LANDSCAPE );
+ if (bNewLand != bWasLand)
+ {
+ SvxPageItem aNewItem( rOldItem );
+ aNewItem.SetLandscape( bNewLand );
+ rSet.Put( aNewItem );
+
+ // Groesse umdrehen
+ Size aOldSize = ((const SvxSizeItem&)rSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ Size aNewSize(aOldSize.Height(),aOldSize.Width());
+ SvxSizeItem aNewSItem(ATTR_PAGE_SIZE,aNewSize);
+ rSet.Put( aNewSItem );
+ }
+ }
+ if (nDiffFlags & SFX_PRINTER_CHG_SIZE)
+ {
+ SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(pNewPrinter) );
+ rSet.Put( aPaperSizeItem );
+ }
+ }
+ }
+
+ PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_ALL);
+
+ return 0;
+}
+
+//---------------------------------------------------------------------
+
+ScChangeAction* ScDocShell::GetChangeAction( const ScAddress& rPos )
+{
+ ScChangeTrack* pTrack = GetDocument()->GetChangeTrack();
+ if (!pTrack)
+ return NULL;
+
+ SCTAB nTab = rPos.Tab();
+
+ const ScChangeAction* pFound = NULL;
+ const ScChangeAction* pFoundContent = NULL;
+ const ScChangeAction* pFoundMove = NULL;
+ long nModified = 0;
+ const ScChangeAction* pAction = pTrack->GetFirst();
+ while (pAction)
+ {
+ ScChangeActionType eType = pAction->GetType();
+ //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )...
+ if ( pAction->IsVisible() && eType != SC_CAT_DELETE_TABS )
+ {
+ const ScBigRange& rBig = pAction->GetBigRange();
+ if ( rBig.aStart.Tab() == nTab )
+ {
+ ScRange aRange = rBig.MakeRange();
+
+ if ( eType == SC_CAT_DELETE_ROWS )
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ else if ( eType == SC_CAT_DELETE_COLS )
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+
+ if ( aRange.In( rPos ) )
+ {
+ pFound = pAction; // der letzte gewinnt
+ switch ( pAction->GetType() )
+ {
+ case SC_CAT_CONTENT :
+ pFoundContent = pAction;
+ break;
+ case SC_CAT_MOVE :
+ pFoundMove = pAction;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ++nModified;
+ }
+ }
+ if ( pAction->GetType() == SC_CAT_MOVE )
+ {
+ ScRange aRange =
+ ((const ScChangeActionMove*)pAction)->
+ GetFromRange().MakeRange();
+ if ( aRange.In( rPos ) )
+ {
+ pFound = pAction;
+ ++nModified;
+ }
+ }
+ }
+ pAction = pAction->GetNext();
+ }
+
+ return (ScChangeAction*)pFound;
+}
+
+void ScDocShell::SetChangeComment( ScChangeAction* pAction, const String& rComment )
+{
+ if (pAction)
+ {
+ pAction->SetComment( rComment );
+ //! Undo ???
+ SetDocumentModified();
+
+ // Dialog-Notify
+ ScChangeTrack* pTrack = GetDocument()->GetChangeTrack();
+ if (pTrack)
+ {
+ ULONG nNumber = pAction->GetActionNumber();
+ pTrack->NotifyModified( SC_CTM_CHANGE, nNumber, nNumber );
+ }
+ }
+}
+
+void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction* pAction, Window* pParent,BOOL bPrevNext)
+{
+ if (!pAction) return; // ohne Aktion ist nichts..
+
+ String aComment = pAction->GetComment();
+ String aAuthor = pAction->GetUser();
+
+ DateTime aDT = pAction->GetDateTime();
+ String aDate = ScGlobal::pLocaleData->getDate( aDT );
+ aDate += ' ';
+ aDate += ScGlobal::pLocaleData->getTime( aDT, FALSE, FALSE );
+
+ SfxItemSet aSet( GetPool(),
+ SID_ATTR_POSTIT_AUTHOR, SID_ATTR_POSTIT_AUTHOR,
+ SID_ATTR_POSTIT_DATE, SID_ATTR_POSTIT_DATE,
+ SID_ATTR_POSTIT_TEXT, SID_ATTR_POSTIT_TEXT,
+ 0 );
+
+ aSet.Put( SvxPostItTextItem ( aComment, SID_ATTR_POSTIT_TEXT ) );
+ aSet.Put( SvxPostItAuthorItem( aAuthor, SID_ATTR_POSTIT_AUTHOR ) );
+ aSet.Put( SvxPostItDateItem ( aDate, SID_ATTR_POSTIT_DATE ) );
+
+ ScRedComDialog* pDlg = new ScRedComDialog( pParent, aSet,this,pAction,bPrevNext);
+
+ pDlg->Execute();
+
+ delete pDlg;
+}
+
+//---------------------------------------------------------------------
+
+void ScDocShell::CompareDocument( ScDocument& rOtherDoc )
+{
+ ScChangeTrack* pTrack = aDocument.GetChangeTrack();
+ if ( pTrack && pTrack->GetFirst() )
+ {
+ //! Changes vorhanden -> Nachfrage ob geloescht werden soll
+ }
+
+ aDocument.EndChangeTracking();
+ aDocument.StartChangeTracking();
+
+ String aOldUser;
+ pTrack = aDocument.GetChangeTrack();
+ if ( pTrack )
+ {
+ aOldUser = pTrack->GetUser();
+
+ // check if comparing to same document
+
+ String aThisFile;
+ const SfxMedium* pThisMed = GetMedium();
+ if (pThisMed)
+ aThisFile = pThisMed->GetName();
+ String aOtherFile;
+ SfxObjectShell* pOtherSh = rOtherDoc.GetDocumentShell();
+ if (pOtherSh)
+ {
+ const SfxMedium* pOtherMed = pOtherSh->GetMedium();
+ if (pOtherMed)
+ aOtherFile = pOtherMed->GetName();
+ }
+ BOOL bSameDoc = ( aThisFile == aOtherFile && aThisFile.Len() );
+ if ( !bSameDoc )
+ {
+ // create change actions from comparing with the name of the user
+ // who last saved the document
+ // (only if comparing different documents)
+
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xDPS->getDocumentProperties());
+ DBG_ASSERT(xDocProps.is(), "no DocumentProperties");
+ String aDocUser = xDocProps->getModifiedBy();
+
+ if ( aDocUser.Len() )
+ pTrack->SetUser( aDocUser );
+ }
+ }
+
+ aDocument.CompareDocument( rOtherDoc );
+
+ pTrack = aDocument.GetChangeTrack();
+ if ( pTrack )
+ pTrack->SetUser( aOldUser );
+
+ PostPaintGridAll();
+ SetDocumentModified();
+}
+
+//---------------------------------------------------------------------
+//
+// Merge (Aenderungen zusammenfuehren)
+//
+//---------------------------------------------------------------------
+
+inline BOOL lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, BOOL bIgnore100Sec )
+{
+ return pA && pB &&
+ pA->GetActionNumber() == pB->GetActionNumber() &&
+ pA->GetType() == pB->GetType() &&
+ pA->GetUser() == pB->GetUser() &&
+ (bIgnore100Sec ?
+ pA->GetDateTimeUTC().IsEqualIgnore100Sec( pB->GetDateTimeUTC() ) :
+ pA->GetDateTimeUTC() == pB->GetDateTimeUTC());
+ // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
+}
+
+bool lcl_FindAction( ScDocument* pDoc, const ScChangeAction* pAction, ScDocument* pSearchDoc, const ScChangeAction* pFirstSearchAction, const ScChangeAction* pLastSearchAction, BOOL bIgnore100Sec )
+{
+ if ( !pDoc || !pAction || !pSearchDoc || !pFirstSearchAction || !pLastSearchAction )
+ {
+ return false;
+ }
+
+ ULONG nLastSearchAction = pLastSearchAction->GetActionNumber();
+ const ScChangeAction* pA = pFirstSearchAction;
+ while ( pA && pA->GetActionNumber() <= nLastSearchAction )
+ {
+ if ( pAction->GetType() == pA->GetType() &&
+ pAction->GetUser() == pA->GetUser() &&
+ (bIgnore100Sec ?
+ pAction->GetDateTimeUTC().IsEqualIgnore100Sec( pA->GetDateTimeUTC() ) :
+ pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
+ pAction->GetBigRange() == pA->GetBigRange() )
+ {
+ String aActionDesc;
+ pAction->GetDescription( aActionDesc, pDoc, TRUE );
+ String aADesc;
+ pA->GetDescription( aADesc, pSearchDoc, TRUE );
+ if ( aActionDesc.Equals( aADesc ) )
+ {
+ DBG_ERROR( "lcl_FindAction(): found equal action!" );
+ return true;
+ }
+ }
+ pA = pA->GetNext();
+ }
+
+ return false;
+}
+
+void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, ULONG nOffset, ScChangeActionMergeMap* pMergeMap, bool bInverseMap )
+{
+ ScTabViewShell* pViewSh = GetBestViewShell( FALSE ); //! Funktionen an die DocShell
+ if (!pViewSh)
+ return;
+
+ ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack();
+ if (!pSourceTrack)
+ return; //! nichts zu tun - Fehlermeldung?
+
+ ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
+ if ( !pThisTrack )
+ { // anschalten
+ aDocument.StartChangeTracking();
+ pThisTrack = aDocument.GetChangeTrack();
+ DBG_ASSERT(pThisTrack,"ChangeTracking nicht angeschaltet?");
+ if ( !bShared )
+ {
+ // #51138# visuelles RedLining einschalten
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ aDocument.SetChangeViewSettings(aChangeViewSet);
+ }
+ }
+
+ // #97286# include 100th seconds in compare?
+ BOOL bIgnore100Sec = !pSourceTrack->IsTime100thSeconds() ||
+ !pThisTrack->IsTime100thSeconds();
+
+ // gemeinsame Ausgangsposition suchen
+ ULONG nFirstNewNumber = 0;
+ const ScChangeAction* pSourceAction = pSourceTrack->GetFirst();
+ const ScChangeAction* pThisAction = pThisTrack->GetFirst();
+ // skip identical actions
+ while ( lcl_Equal( pSourceAction, pThisAction, bIgnore100Sec ) )
+ {
+ nFirstNewNumber = pSourceAction->GetActionNumber() + 1;
+ pSourceAction = pSourceAction->GetNext();
+ pThisAction = pThisAction->GetNext();
+ }
+ // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen
+ // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht
+
+ //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!!
+
+
+ const ScChangeAction* pFirstMergeAction = pSourceAction;
+ const ScChangeAction* pFirstSearchAction = pThisAction;
+
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ const ScChangeAction* pLastSearchAction = pThisTrack->GetLast();
+
+ // MergeChangeData aus den folgenden Aktionen erzeugen
+ ULONG nNewActionCount = 0;
+ const ScChangeAction* pCount = pSourceAction;
+ while ( pCount )
+ {
+ if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
+ ++nNewActionCount;
+ pCount = pCount->GetNext();
+ }
+ if (!nNewActionCount)
+ return; //! nichts zu tun - Fehlermeldung?
+ // ab hier kein return mehr
+
+ ScProgress aProgress( this,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")),
+ nNewActionCount );
+
+ ULONG nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber();
+ // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand
+ pSourceTrack->MergePrepare( (ScChangeAction*) pFirstMergeAction, bShared );
+
+ // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen
+ // -> Referenzen gueltig fuer dieses Dokument
+ while ( pThisAction )
+ {
+ // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
+ if ( !bShared || !ScChangeTrack::MergeIgnore( *pThisAction, nFirstNewNumber ) )
+ {
+ ScChangeActionType eType = pThisAction->GetType();
+ switch ( eType )
+ {
+ case SC_CAT_INSERT_COLS :
+ case SC_CAT_INSERT_ROWS :
+ case SC_CAT_INSERT_TABS :
+ pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange() );
+ break;
+ case SC_CAT_DELETE_COLS :
+ case SC_CAT_DELETE_ROWS :
+ case SC_CAT_DELETE_TABS :
+ {
+ const ScChangeActionDel* pDel = (const ScChangeActionDel*) pThisAction;
+ if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
+ { // deleted Table enthaelt deleted Cols, die nicht
+ ULONG nStart, nEnd;
+ pSourceTrack->AppendDeleteRange(
+ pDel->GetOverAllRange().MakeRange(), NULL, nStart, nEnd );
+ }
+ }
+ break;
+ case SC_CAT_MOVE :
+ {
+ const ScChangeActionMove* pMove = (const ScChangeActionMove*) pThisAction;
+ pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange(),
+ pMove->GetBigRange().MakeRange(), NULL );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ pThisAction = pThisAction->GetNext();
+ }
+
+ LockPaint(); // #i73877# no repainting after each action
+
+ // MergeChangeData in das aktuelle Dokument uebernehmen
+ BOOL bHasRejected = FALSE;
+ String aOldUser = pThisTrack->GetUser();
+ pThisTrack->SetUseFixDateTime( TRUE );
+ ScMarkData& rMarkData = pViewSh->GetViewData()->GetMarkData();
+ ScMarkData aOldMarkData( rMarkData );
+ pSourceAction = pFirstMergeAction;
+ while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
+ {
+ bool bMergeAction = false;
+ if ( bShared )
+ {
+ if ( !bCheckDuplicates || !lcl_FindAction( &rOtherDoc, pSourceAction, &aDocument, pFirstSearchAction, pLastSearchAction, bIgnore100Sec ) )
+ {
+ bMergeAction = true;
+ }
+ }
+ else
+ {
+ if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
+ {
+ bMergeAction = true;
+ }
+ }
+
+ if ( bMergeAction )
+ {
+ ScChangeActionType eSourceType = pSourceAction->GetType();
+ if ( !bShared && pSourceAction->IsDeletedIn() )
+ {
+ //! muss hier noch festgestellt werden, ob wirklich in
+ //! _diesem_ Dokument geloescht?
+
+ // liegt in einem Bereich, der in diesem Dokument geloescht wurde
+ // -> wird weggelassen
+ //! ??? Loesch-Aktion rueckgaengig machen ???
+ //! ??? Aktion irgendwo anders speichern ???
+#ifdef DBG_UTIL
+ String aValue;
+ if ( eSourceType == SC_CAT_CONTENT )
+ ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue );
+ ByteString aError( aValue, gsl_getSystemTextEncoding() );
+ aError += " weggelassen";
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ }
+ else
+ {
+ //! Datum/Autor/Kommentar der Source-Aktion uebernehmen!
+
+ pThisTrack->SetUser( pSourceAction->GetUser() );
+ pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
+ ULONG nOldActionMax = pThisTrack->GetActionMax();
+
+ bool bExecute = true;
+ ULONG nReject = pSourceAction->GetRejectAction();
+ if ( nReject )
+ {
+ if ( bShared )
+ {
+ if ( nReject >= nFirstNewNumber )
+ {
+ nReject += nOffset;
+ }
+ ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
+ if ( pOldAction && pOldAction->IsVirgin() )
+ {
+ pThisTrack->Reject( pOldAction );
+ bHasRejected = TRUE;
+ bExecute = false;
+ }
+ }
+ else
+ {
+ // alte Aktion (aus den gemeinsamen) ablehnen
+ ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
+ if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
+ {
+ //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
+ //! Fehlermeldung oder was???
+ //! oder Reject-Aenderung normal ausfuehren
+
+ pThisTrack->Reject(pOldAction);
+ bHasRejected = TRUE; // fuer Paint
+ }
+ bExecute = false;
+ }
+ }
+
+ if ( bExecute )
+ {
+ // normal ausfuehren
+ ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange();
+ rMarkData.SelectOneTable( aSourceRange.aStart.Tab() );
+ switch ( eSourceType )
+ {
+ case SC_CAT_CONTENT:
+ {
+ //! Test, ob es ganz unten im Dokument war, dann automatisches
+ //! Zeilen-Einfuegen ???
+
+ DBG_ASSERT( aSourceRange.aStart == aSourceRange.aEnd, "huch?" );
+ ScAddress aPos = aSourceRange.aStart;
+ String aValue;
+ ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue );
+ BYTE eMatrix = MM_NONE;
+ const ScBaseCell* pCell = ((const ScChangeActionContent*)pSourceAction)->GetNewCell();
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ eMatrix = ((const ScFormulaCell*)pCell)->GetMatrixFlag();
+ switch ( eMatrix )
+ {
+ case MM_NONE :
+ pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
+ break;
+ case MM_FORMULA :
+ {
+ SCCOL nCols;
+ SCROW nRows;
+ ((const ScFormulaCell*)pCell)->GetMatColsRows( nCols, nRows );
+ aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 );
+ aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 );
+ aValue.Erase( 0, 1 );
+ aValue.Erase( aValue.Len()-1, 1 );
+ GetDocFunc().EnterMatrix( aSourceRange,
+ NULL, NULL, aValue, FALSE, FALSE,
+ EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
+ }
+ break;
+ case MM_REFERENCE : // do nothing
+ break;
+ case MM_FAKE :
+ DBG_WARNING( "MergeDocument: MatrixFlag MM_FAKE" );
+ pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
+ break;
+ default:
+ DBG_ERROR( "MergeDocument: unknown MatrixFlag" );
+ }
+ }
+ break;
+ case SC_CAT_INSERT_TABS :
+ {
+ String aName;
+ aDocument.CreateValidTabName( aName );
+ GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, TRUE, FALSE );
+ }
+ break;
+ case SC_CAT_INSERT_ROWS:
+ GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSROWS, TRUE, FALSE );
+ break;
+ case SC_CAT_INSERT_COLS:
+ GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSCOLS, TRUE, FALSE );
+ break;
+ case SC_CAT_DELETE_TABS :
+ GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), TRUE, FALSE );
+ break;
+ case SC_CAT_DELETE_ROWS:
+ {
+ const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction;
+ if ( pDel->IsTopDelete() )
+ {
+ aSourceRange = pDel->GetOverAllRange().MakeRange();
+ GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELROWS, TRUE, FALSE );
+
+ // #i101099# [Collaboration] Changes are not correctly shown
+ if ( bShared )
+ {
+ ScChangeAction* pAct = pThisTrack->GetLast();
+ if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() )
+ {
+ pAct->RemoveAllDeletedIn();
+ }
+ }
+ }
+ }
+ break;
+ case SC_CAT_DELETE_COLS:
+ {
+ const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction;
+ if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
+ { // deleted Table enthaelt deleted Cols, die nicht
+ aSourceRange = pDel->GetOverAllRange().MakeRange();
+ GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELCOLS, TRUE, FALSE );
+ }
+ }
+ break;
+ case SC_CAT_MOVE :
+ {
+ const ScChangeActionMove* pMove = (const ScChangeActionMove*) pSourceAction;
+ ScRange aFromRange( pMove->GetFromRange().MakeRange() );
+ GetDocFunc().MoveBlock( aFromRange,
+ aSourceRange.aStart, TRUE, TRUE, FALSE, FALSE );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ const String& rComment = pSourceAction->GetComment();
+ if ( rComment.Len() )
+ {
+ ScChangeAction* pAct = pThisTrack->GetLast();
+ if ( pAct && pAct->GetActionNumber() > nOldActionMax )
+ pAct->SetComment( rComment );
+#ifdef DBG_UTIL
+ else
+ DBG_ERROR( "MergeDocument: wohin mit dem Kommentar?!?" );
+#endif
+ }
+
+ // Referenzen anpassen
+ pSourceTrack->MergeOwn( (ScChangeAction*) pSourceAction, nFirstNewNumber, bShared );
+
+ // merge action state
+ if ( bShared && !pSourceAction->IsRejected() )
+ {
+ ScChangeAction* pAct = pThisTrack->GetLast();
+ if ( pAct && pAct->GetActionNumber() > nOldActionMax )
+ {
+ pThisTrack->MergeActionState( pAct, pSourceAction );
+ }
+ }
+
+ // fill merge map
+ if ( bShared && pMergeMap )
+ {
+ ScChangeAction* pAct = pThisTrack->GetLast();
+ if ( pAct && pAct->GetActionNumber() > nOldActionMax )
+ {
+ ULONG nActionMax = pAct->GetActionNumber();
+ ULONG nActionCount = nActionMax - nOldActionMax;
+ ULONG nAction = nActionMax - nActionCount + 1;
+ ULONG nSourceAction = pSourceAction->GetActionNumber() - nActionCount + 1;
+ while ( nAction <= nActionMax )
+ {
+ if ( bInverseMap )
+ {
+ (*pMergeMap)[ nAction++ ] = nSourceAction++;
+ }
+ else
+ {
+ (*pMergeMap)[ nSourceAction++ ] = nAction++;
+ }
+ }
+ }
+ }
+ }
+ aProgress.SetStateCountDown( --nNewActionCount );
+ }
+ pSourceAction = pSourceAction->GetNext();
+ }
+
+ rMarkData = aOldMarkData;
+ pThisTrack->SetUser(aOldUser);
+ pThisTrack->SetUseFixDateTime( FALSE );
+
+ pSourceTrack->Clear(); //! der ist jetzt verhunzt
+
+ if (bHasRejected)
+ PostPaintGridAll(); // Reject() paintet nicht selber
+
+ UnlockPaint();
+}
+
+bool ScDocShell::MergeSharedDocument( ScDocShell* pSharedDocShell )
+{
+ if ( !pSharedDocShell )
+ {
+ return false;
+ }
+
+ ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
+ if ( !pThisTrack )
+ {
+ return false;
+ }
+
+ ScDocument& rSharedDoc = *( pSharedDocShell->GetDocument() );
+ ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
+ if ( !pSharedTrack )
+ {
+ return false;
+ }
+
+#if DEBUG_CHANGETRACK
+ ::rtl::OUString aMessage = ::rtl::OUString::createFromAscii( "\nbefore merge:\n" );
+ aMessage += pThisTrack->ToString();
+ ::rtl::OString aMsg = ::rtl::OUStringToOString( aMessage, RTL_TEXTENCODING_UTF8 );
+ OSL_ENSURE( false, aMsg.getStr() );
+ //fprintf( stdout, "%s ", aMsg.getStr() );
+ //fflush( stdout );
+#endif // DEBUG_CHANGETRACK
+
+ // reset show changes
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges( FALSE );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+
+ // find first merge action in this document
+ BOOL bIgnore100Sec = !pThisTrack->IsTime100thSeconds() || !pSharedTrack->IsTime100thSeconds();
+ ScChangeAction* pThisAction = pThisTrack->GetFirst();
+ ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
+ while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
+ {
+ pThisAction = pThisAction->GetNext();
+ pSharedAction = pSharedAction->GetNext();
+ }
+
+ if ( pSharedAction )
+ {
+ if ( pThisAction )
+ {
+ // merge own changes into shared document
+ ULONG nActStartShared = pSharedAction->GetActionNumber();
+ ULONG nActEndShared = pSharedTrack->GetActionMax();
+ ScDocument* pTmpDoc = new ScDocument;
+ for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
+ {
+ String sTabName;
+ pTmpDoc->CreateValidTabName( sTabName );
+ pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
+ }
+ aDocument.GetChangeTrack()->Clone( pTmpDoc );
+ ScChangeActionMergeMap aOwnInverseMergeMap;
+ pSharedDocShell->MergeDocument( *pTmpDoc, true, true, 0, &aOwnInverseMergeMap, true );
+ delete pTmpDoc;
+ ULONG nActStartOwn = nActEndShared + 1;
+ ULONG nActEndOwn = pSharedTrack->GetActionMax();
+
+ // find conflicts
+ ScConflictsList aConflictsList;
+ ScConflictsFinder aFinder( pSharedTrack, nActStartShared, nActEndShared, nActStartOwn, nActEndOwn, aConflictsList );
+ if ( aFinder.Find() )
+ {
+ ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnInverseMergeMap );
+ bool bLoop = true;
+ while ( bLoop )
+ {
+ bLoop = false;
+ ScConflictsDlg aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc, aConflictsList );
+ if ( aDlg.Execute() == RET_CANCEL )
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED ) );
+ if ( aBox.Execute() == RET_YES )
+ {
+ return false;
+ }
+ else
+ {
+ bLoop = true;
+ }
+ }
+ }
+ }
+
+ // undo own changes in shared document
+ pSharedTrack->Undo( nActStartOwn, nActEndOwn );
+
+ // clone change track for merging into own document
+ pTmpDoc = new ScDocument;
+ for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
+ {
+ String sTabName;
+ pTmpDoc->CreateValidTabName( sTabName );
+ pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
+ }
+ pThisTrack->Clone( pTmpDoc );
+
+ // undo own changes since last save in own document
+ ULONG nStartShared = pThisAction->GetActionNumber();
+ ScChangeAction* pAction = pThisTrack->GetLast();
+ while ( pAction && pAction->GetActionNumber() >= nStartShared )
+ {
+ pThisTrack->Reject( pAction, true );
+ pAction = pAction->GetPrev();
+ }
+
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax(), true );
+
+ // merge shared changes into own document
+ ScChangeActionMergeMap aSharedMergeMap;
+ MergeDocument( rSharedDoc, true, true, 0, &aSharedMergeMap );
+ ULONG nEndShared = pThisTrack->GetActionMax();
+
+ // resolve conflicts for shared non-content actions
+ if ( !aConflictsList.empty() )
+ {
+ ScConflictsListHelper::TransformConflictsList( aConflictsList, &aSharedMergeMap, NULL );
+ ScConflictsResolver aResolver( pThisTrack, aConflictsList );
+ pAction = pThisTrack->GetAction( nEndShared );
+ while ( pAction && pAction->GetActionNumber() >= nStartShared )
+ {
+ aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
+ false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
+ pAction = pAction->GetPrev();
+ }
+ }
+ nEndShared = pThisTrack->GetActionMax();
+
+ // only show changes from shared document
+ aChangeViewSet.SetShowChanges( TRUE );
+ aChangeViewSet.SetShowAccepted( TRUE );
+ aChangeViewSet.SetHasActionRange( true );
+ aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+
+ // merge own changes back into own document
+ ULONG nStartOwn = nEndShared + 1;
+ ScChangeActionMergeMap aOwnMergeMap;
+ MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1, &aOwnMergeMap );
+ delete pTmpDoc;
+ ULONG nEndOwn = pThisTrack->GetActionMax();
+
+ // resolve conflicts for shared content actions and own actions
+ if ( !aConflictsList.empty() )
+ {
+ ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnMergeMap );
+ ScConflictsResolver aResolver( pThisTrack, aConflictsList );
+ pAction = pThisTrack->GetAction( nEndShared );
+ while ( pAction && pAction->GetActionNumber() >= nStartShared )
+ {
+ aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
+ true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
+ pAction = pAction->GetPrev();
+ }
+
+ pAction = pThisTrack->GetAction( nEndOwn );
+ while ( pAction && pAction->GetActionNumber() >= nStartOwn )
+ {
+ aResolver.HandleAction( pAction, false /*bIsSharedAction*/,
+ true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
+ pAction = pAction->GetPrev();
+ }
+ }
+ nEndOwn = pThisTrack->GetActionMax();
+ }
+ else
+ {
+ // merge shared changes into own document
+ ULONG nStartShared = pThisTrack->GetActionMax() + 1;
+ MergeDocument( rSharedDoc, true, true );
+ ULONG nEndShared = pThisTrack->GetActionMax();
+
+ // only show changes from shared document
+ aChangeViewSet.SetShowChanges( TRUE );
+ aChangeViewSet.SetShowAccepted( TRUE );
+ aChangeViewSet.SetHasActionRange( true );
+ aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+ }
+
+ // update view
+ PostPaintExtras();
+ PostPaintGridAll();
+
+ InfoBox aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED ) );
+ aInfoBox.Execute();
+ }
+
+#if DEBUG_CHANGETRACK
+ aMessage = ::rtl::OUString::createFromAscii( "\nafter merge:\n" );
+ aMessage += pThisTrack->ToString();
+ aMsg = ::rtl::OUStringToOString( aMessage, RTL_TEXTENCODING_UTF8 );
+ OSL_ENSURE( false, aMsg.getStr() );
+ //fprintf( stdout, "%s ", aMsg.getStr() );
+ //fflush( stdout );
+#endif // DEBUG_CHANGETRACK
+
+ return ( pThisAction != NULL );
+}
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
new file mode 100644
index 000000000000..d50ce6f21c9c
--- /dev/null
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -0,0 +1,2734 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+
+
+using namespace ::com::sun::star;
+
+// INCLUDE ---------------------------------------------------------------
+#if STLPORT_VERSION>=321
+#include <math.h> // prevent conflict between exception and std::exception
+#endif
+
+#include "scitems.hxx"
+#include <sfx2/fcontnr.hxx>
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <svtools/ehdl.hxx>
+#include <basic/sbxcore.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/request.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svx/ofaitem.hxx>
+#include <sot/formats.hxx>
+#include <svtools/printdlg.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/waitobj.hxx>
+#include <tools/multisel.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/fmview.hxx>
+#include <svx/pageitem.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/fmshell.hxx>
+#include <svtools/xwindowitem.hxx>
+#include <sfx2/passwd.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docinsert.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <svl/documentlockfile.hxx>
+#include <svl/sharecontrolfile.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include "docuno.hxx"
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include "docsh.hxx"
+#include "docshimp.hxx"
+#include "docfunc.hxx"
+#include "sc.hrc"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "appoptio.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+//CHINA001 #include "styledlg.hxx"
+//CHINA001 #include "hfedtdlg.hxx"
+#include "dbdocfun.hxx"
+#include "printfun.hxx" // DrawToDev
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "attrib.hxx"
+//CHINA001 #include "corodlg.hxx"
+#include "undodat.hxx"
+#include "autostyl.hxx"
+#include "undocell.hxx"
+#include "undotab.hxx"
+#include "inputhdl.hxx"
+#include "dbcolect.hxx"
+#include "servobj.hxx"
+#include "rangenam.hxx"
+#include "scmod.hxx"
+//CHINA001 #include "scendlg.hxx"
+#include "chgviset.hxx"
+#include "reffact.hxx"
+#include "chartlis.hxx"
+#include "waitoff.hxx"
+#include "tablink.hxx" // ScDocumentLoader statics
+#include "drwlayer.hxx"
+#include "docoptio.hxx"
+#include "undostyl.hxx"
+#include "rangeseq.hxx"
+#include "chgtrack.hxx"
+#include "printopt.hxx"
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include "scresid.hxx" //add by CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "externalrefmgr.hxx"
+#include "sharedocdlg.hxx"
+#include "conditio.hxx"
+#include "sheetevents.hxx"
+
+//------------------------------------------------------------------
+
+#define IS_SHARE_HEADER(set) \
+ ((SfxBoolItem&) \
+ ((SvxSetItem&)(set).Get(ATTR_PAGE_HEADERSET)).GetItemSet(). \
+ Get(ATTR_PAGE_SHARED)).GetValue()
+
+#define IS_SHARE_FOOTER(set) \
+ ((SfxBoolItem&) \
+ ((SvxSetItem&)(set).Get(ATTR_PAGE_FOOTERSET)).GetItemSet(). \
+ Get(ATTR_PAGE_SHARED)).GetValue()
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+#define SC_PREVIEW_SIZE_X 10000
+#define SC_PREVIEW_SIZE_Y 12400
+
+
+//------------------------------------------------------------------
+
+void ScDocShell::Execute( SfxRequest& rReq )
+{
+ // SID_SC_RANGE (Range),
+ // SID_SC_CELLTEXT (CellText),
+ // SID_SC_CELLS (Cells) - removed (old Basic)
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ SfxBindings* pBindings = GetViewBindings();
+ BOOL bUndo (aDocument.IsUndoEnabled());
+
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_SC_SETTEXT:
+ {
+ const SfxPoolItem* pColItem;
+ const SfxPoolItem* pRowItem;
+ const SfxPoolItem* pTabItem;
+ const SfxPoolItem* pTextItem;
+ if( pReqArgs && IS_AVAILABLE( FN_PARAM_1, &pColItem ) &&
+ IS_AVAILABLE( FN_PARAM_2, &pRowItem ) &&
+ IS_AVAILABLE( FN_PARAM_3, &pTabItem ) &&
+ IS_AVAILABLE( SID_SC_SETTEXT, &pTextItem ) )
+ {
+ // Parameter sind 1-based !!!
+ SCCOL nCol = ((SfxInt16Item*)pColItem)->GetValue() - 1;
+ SCROW nRow = ((SfxInt32Item*)pRowItem)->GetValue() - 1;
+ SCTAB nTab = ((SfxInt16Item*)pTabItem)->GetValue() - 1;
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ if ( ValidCol(nCol) && ValidRow(nRow) && ValidTab(nTab,nTabCount) )
+ {
+ if ( aDocument.IsBlockEditable( nTab, nCol,nRow, nCol, nRow ) )
+ {
+ String aVal = ((const SfxStringItem*)pTextItem)->GetValue();
+ aDocument.SetString( nCol, nRow, nTab, aVal );
+
+ PostPaintCell( nCol, nRow, nTab );
+ SetDocumentModified();
+
+ rReq.Done();
+ break;
+ }
+ else // geschuetzte Zelle
+ {
+ SbxBase::SetError( SbxERR_BAD_PARAMETER ); //! welchen Fehler ?
+ break;
+ }
+ }
+ }
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ }
+ break;
+
+
+ // SID_SBA_QRY_CHANGETARGET gibts nicht mehr - auch in idl raus
+
+ case SID_SBA_IMPORT:
+ {
+ if (pReqArgs)
+ {
+ const sal_Unicode cSbaSep = 11; // Trennzeichen
+
+ const SfxPoolItem* pItem;
+ String sSbaData, sTarget;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ sSbaData = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
+ sTarget = ((const SfxStringItem*)pItem)->GetValue();
+
+ BOOL bIsNewArea = TRUE; // Default TRUE (keine Nachfrage)
+ if ( pReqArgs->GetItemState( FN_PARAM_2, TRUE, &pItem ) == SFX_ITEM_SET )
+ bIsNewArea = ((const SfxBoolItem*)pItem)->GetValue();
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::sdbc::XResultSet > xResultSet;
+ if ( pReqArgs->GetItemState( FN_PARAM_3, FALSE, &pItem ) == SFX_ITEM_SET && pItem )
+ xResultSet.set(((const SfxUsrAnyItem*)pItem)->GetValue(),::com::sun::star::uno::UNO_QUERY);
+
+ String sDBName = sSbaData.GetToken(0,cSbaSep); // Datenbankname
+ String sDBTable = sSbaData.GetToken(1,cSbaSep); // Tabellen- oder Query-Name
+ String sTabFlag = sSbaData.GetToken(2,cSbaSep);
+ String sDBSql = sSbaData.GetToken(3,cSbaSep); // SQL im Klartext
+
+ BYTE nType = ScDbTable; // "0" oder "1"
+ if ( sTabFlag.EqualsAscii("0") ) // "0" = Query, "1" = Table (Default)
+ nType = ScDbQuery;
+
+ SbaSelectionListRef pSelectionList = new SbaSelectionList;
+ xub_StrLen nCount = sSbaData.GetTokenCount(cSbaSep);
+
+ for (xub_StrLen i = 4; i < nCount; i++)
+ {
+ String aSelItem = sSbaData.GetToken(i,cSbaSep);
+ if (aSelItem.Len())
+ {
+ void *pPtr = (void*)aSelItem.ToInt32();
+ pSelectionList->Insert( pPtr, LIST_APPEND );
+ }
+ }
+
+ // bei Bedarf neuen Datenbankbereich anlegen
+ BOOL bMakeArea = FALSE;
+ if (bIsNewArea)
+ {
+ ScDBCollection* pDBColl = aDocument.GetDBCollection();
+ USHORT nDummy;
+ if ( !pDBColl || !pDBColl->SearchName( sTarget, nDummy ) )
+ {
+ ScAddress aPos;
+ if ( aPos.Parse( sTarget, &aDocument, aDocument.GetAddressConvention() ) & SCA_VALID )
+ {
+ bMakeArea = TRUE;
+ if (bUndo)
+ {
+ String aStrImport = ScGlobal::GetRscString( STR_UNDO_IMPORTDATA );
+ GetUndoManager()->EnterListAction( aStrImport, aStrImport );
+ }
+
+ ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, SC_DBSEL_KEEP );
+ DBG_ASSERT(pDBData, "kann DB-Daten nicht anlegen");
+ sTarget = pDBData->GetName();
+ }
+ }
+ }
+
+ // nachfragen, bevor alter DB-Bereich ueberschrieben wird
+ BOOL bDo = TRUE;
+ if (!bIsNewArea)
+ {
+ String aTemplate = ScGlobal::GetRscString( STR_IMPORT_REPLACE );
+ String aMessage = aTemplate.GetToken( 0, '#' );
+ aMessage += sTarget;
+ aMessage += aTemplate.GetToken( 1, '#' );
+
+ QueryBox aBox( 0, WinBits(WB_YES_NO | WB_DEF_YES), aMessage );
+ bDo = ( aBox.Execute() == RET_YES );
+ }
+
+ if (bDo)
+ {
+ ScDBDocFunc(*this).UpdateImport( sTarget, sDBName,
+ sDBTable, sDBSql, TRUE, nType, xResultSet,
+ pSelectionList );
+ rReq.Done();
+
+ // UpdateImport aktualisiert auch die internen Operationen
+ }
+ else
+ rReq.Ignore();
+
+ if ( bMakeArea && bUndo)
+ GetUndoManager()->LeaveListAction();
+ }
+ else
+ {
+ DBG_ERROR( "arguments expected" );
+ }
+ }
+ break;
+
+ case SID_CHART_SOURCE:
+ case SID_CHART_ADDSOURCE:
+ if (pReqArgs)
+ {
+ ScDocument* pDoc = GetDocument();
+// BOOL bUndo (pDoc->IsUndoEnabled());
+ const SfxPoolItem* pItem;
+ String aChartName, aRangeName;
+
+ ScRange aSingleRange;
+ ScRangeListRef aRangeListRef;
+ BOOL bMultiRange = FALSE;
+
+ BOOL bColHeaders = TRUE;
+ BOOL bRowHeaders = TRUE;
+ BOOL bColInit = FALSE;
+ BOOL bRowInit = FALSE;
+ BOOL bAddRange = (nSlot == SID_CHART_ADDSOURCE);
+
+ if( IS_AVAILABLE( SID_CHART_NAME, &pItem ) )
+ aChartName = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( SID_CHART_SOURCE, &pItem ) )
+ aRangeName = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ {
+ bColHeaders = ((const SfxBoolItem*)pItem)->GetValue();
+ bColInit = TRUE;
+ }
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ {
+ bRowHeaders = ((const SfxBoolItem*)pItem)->GetValue();
+ bRowInit = TRUE;
+ }
+
+ ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
+ BOOL bValid = ( aSingleRange.ParseAny( aRangeName, pDoc, aDetails ) & SCA_VALID ) != 0;
+ if (!bValid)
+ {
+ aRangeListRef = new ScRangeList;
+ aRangeListRef->Parse( aRangeName, pDoc );
+ if ( aRangeListRef->Count() )
+ {
+ bMultiRange = TRUE;
+ aSingleRange = *aRangeListRef->GetObject(0); // fuer Header
+ bValid = TRUE;
+ }
+ else
+ aRangeListRef.Clear();
+ }
+
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if (pViewSh && bValid && aChartName.Len() != 0 )
+ {
+ Window* pParent = pViewSh->GetDialogParent();
+
+ SCCOL nCol1 = aSingleRange.aStart.Col();
+ SCROW nRow1 = aSingleRange.aStart.Row();
+ SCCOL nCol2 = aSingleRange.aEnd.Col();
+ SCROW nRow2 = aSingleRange.aEnd.Row();
+ SCTAB nTab = aSingleRange.aStart.Tab();
+
+ //! immer oder gar nicht begrenzen ???
+ if (!bMultiRange)
+ aDocument.LimitChartArea( nTab, nCol1,nRow1, nCol2,nRow2 );
+
+ // Dialog fuer Spalten/Zeilenkoepfe
+ BOOL bOk = TRUE;
+ if ( !bAddRange && ( !bColInit || !bRowInit ) )
+ {
+ // Spalten/Zeilenkoepfe testen wie in chartarr
+ if (!bColInit)
+ {
+ for (SCCOL i=nCol1; i<=nCol2 && bColHeaders; i++)
+ if (aDocument.HasValueData( i, nRow1, nTab ))
+ bColHeaders = FALSE;
+ }
+ if (!bRowInit)
+ {
+ for (SCROW i=nRow1; i<=nRow2 && bRowHeaders; i++)
+ if (aDocument.HasValueData( nCol1, i, nTab ))
+ bRowHeaders = FALSE;
+ }
+
+ //CHINA001 ScColRowLabelDlg aDlg( pParent, bRowHeaders, bColHeaders );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScColRowLabelDlg* pDlg = pFact->CreateScColRowLabelDlg( pParent, RID_SCDLG_CHARTCOLROW, bRowHeaders, bColHeaders);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK ) //CHINA001 if ( aDlg.Execute() == RET_OK )
+ {
+ bColHeaders = pDlg->IsRow(); //CHINA001 bColHeaders = aDlg.IsRow(); // Spaltenkoepfe = 1. Zeile
+ bRowHeaders = pDlg->IsCol(); //CHINA001 bRowHeaders = aDlg.IsCol();
+
+ rReq.AppendItem(SfxBoolItem(FN_PARAM_1, bColHeaders));
+ rReq.AppendItem(SfxBoolItem(FN_PARAM_2, bRowHeaders));
+ }
+ else
+ bOk = FALSE;
+ delete pDlg; //CHINA001
+ }
+
+ if (bOk) // ausfuehren
+ {
+ if (bMultiRange)
+ {
+ if (bUndo)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoChartData( this, aChartName, aRangeListRef,
+ bColHeaders, bRowHeaders, bAddRange ) );
+ }
+ aDocument.UpdateChartArea( aChartName, aRangeListRef,
+ bColHeaders, bRowHeaders, bAddRange );
+ }
+ else
+ {
+ ScRange aNewRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab );
+ if (bUndo)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoChartData( this, aChartName, aNewRange,
+ bColHeaders, bRowHeaders, bAddRange ) );
+ }
+ aDocument.UpdateChartArea( aChartName, aNewRange,
+ bColHeaders, bRowHeaders, bAddRange );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("UpdateChartArea: keine ViewShell oder falsche Daten");
+ }
+ rReq.Done();
+ }
+ else
+ {
+ DBG_ERROR("SID_CHART_SOURCE ohne Argumente");
+ }
+ break;
+
+ case FID_AUTO_CALC:
+ {
+ BOOL bNewVal;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( nSlot, TRUE, &pItem ) )
+ bNewVal = ((const SfxBoolItem*)pItem)->GetValue();
+ else
+ bNewVal = !aDocument.GetAutoCalc(); // Toggle fuer Menue
+ aDocument.SetAutoCalc( bNewVal );
+ SetDocumentModified();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_AUTO_CALC );
+// pBindings->Invalidate( FID_RECALC ); // jetzt immer enabled
+ }
+ rReq.AppendItem( SfxBoolItem( FID_AUTO_CALC, bNewVal ) );
+ rReq.Done();
+ }
+ break;
+ case FID_RECALC:
+ DoRecalc( rReq.IsAPI() );
+ rReq.Done();
+ break;
+ case FID_HARD_RECALC:
+ DoHardRecalc( rReq.IsAPI() );
+ rReq.Done();
+ break;
+ case SID_UPDATETABLINKS:
+ {
+ ScDocument* pDoc = GetDocument();
+
+ ScLkUpdMode nSet=pDoc->GetLinkMode();
+
+ USHORT nDlgRet=RET_NO;
+ if(nSet==LM_UNKNOWN)
+ {
+ ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
+ nSet=aAppOptions.GetLinkMode();
+ }
+
+ if (nCanUpdate == com::sun::star::document::UpdateDocMode::NO_UPDATE)
+ nSet = LM_NEVER;
+ else if (nCanUpdate == com::sun::star::document::UpdateDocMode::QUIET_UPDATE &&
+ nSet == LM_ON_DEMAND)
+ nSet = LM_NEVER;
+ else if (nCanUpdate == com::sun::star::document::UpdateDocMode::FULL_UPDATE)
+ nSet = LM_ALWAYS;
+
+ if(nSet==LM_ON_DEMAND)
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_RELOAD_TABLES) );
+
+ nDlgRet=aBox.Execute();
+ }
+
+ if (nDlgRet == RET_YES || nSet==LM_ALWAYS)
+ {
+ ReloadTabLinks();
+ aDocument.UpdateExternalRefLinks();
+ aDocument.UpdateDdeLinks();
+ aDocument.UpdateAreaLinks();
+
+ //! Test, ob Fehler
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_REIMPORT_AFTER_LOAD:
+ {
+ // wird nach dem Laden aufgerufen, wenn DB-Bereiche mit
+ // weggelassenen Daten enthalten sind
+
+ BOOL bDone = FALSE;
+ ScDBCollection* pDBColl = aDocument.GetDBCollection();
+
+ if ((nCanUpdate != com::sun::star::document::UpdateDocMode::NO_UPDATE) &&
+ (nCanUpdate != com::sun::star::document::UpdateDocMode::QUIET_UPDATE))
+ {
+ ScRange aRange;
+ ScTabViewShell* pViewSh = GetBestViewShell();
+ DBG_ASSERT(pViewSh,"SID_REIMPORT_AFTER_LOAD: keine View");
+ if (pViewSh && pDBColl)
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_REIMPORT_AFTER_LOAD) );
+ if (aBox.Execute() == RET_YES)
+ {
+ for (USHORT i=0; i<pDBColl->GetCount(); i++)
+ {
+ ScDBData* pDBData = (*pDBColl)[i];
+ if ( pDBData->IsStripData() &&
+ pDBData->HasImportParam() && !pDBData->HasImportSelection() )
+ {
+ pDBData->GetArea(aRange);
+ pViewSh->MarkRange(aRange);
+
+ // Import und interne Operationen wie SID_REFRESH_DBAREA
+ // (Abfrage auf Import hier nicht noetig)
+
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ BOOL bContinue = pViewSh->ImportData( aImportParam );
+ pDBData->SetImportParam( aImportParam );
+
+ // markieren (Groesse kann sich geaendert haben)
+ pDBData->GetArea(aRange);
+ pViewSh->MarkRange(aRange);
+
+ if ( bContinue ) // #41905# Fehler beim Import -> Abbruch
+ {
+ // interne Operationen, wenn welche gespeichert
+
+ if ( pDBData->HasQueryParam() || pDBData->HasSortParam() ||
+ pDBData->HasSubTotalParam() )
+ pViewSh->RepeatDB();
+
+ // Pivottabellen die den Bereich als Quelldaten haben
+
+ RefreshPivotTables(aRange);
+ }
+ }
+ }
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if ( !bDone && pDBColl )
+ {
+ // wenn nicht, dann aber die abhaengigen Formeln updaten
+ //! auch fuer einzelne Bereiche, die nicht aktualisiert werden koennen
+
+ aDocument.CalcAll(); //! nur die abhaengigen
+ PostDataChanged();
+ }
+
+ if (bDone)
+ rReq.Done();
+ else
+ rReq.Ignore();
+ }
+ break;
+
+
+ case SID_AUTO_STYLE:
+ DBG_ERROR("use ScAutoStyleHint instead of SID_AUTO_STYLE");
+ break;
+
+ case SID_GET_COLORTABLE:
+ {
+ // passende ColorTable ist per PutItem gesetzt worden
+ SvxColorTableItem* pColItem = (SvxColorTableItem*)GetItem(SID_COLOR_TABLE);
+ XColorTable* pTable = pColItem->GetColorTable();
+ rReq.SetReturnValue(OfaPtrItem(SID_GET_COLORTABLE, pTable));
+ }
+ break;
+
+ case FID_CHG_RECORD:
+ {
+ ScDocument* pDoc = GetDocument();
+ if(pDoc!=NULL)
+ {
+ // get argument (recorded macro)
+ SFX_REQUEST_ARG( rReq, pItem, SfxBoolItem, FID_CHG_RECORD, sal_False );
+ BOOL bDo = TRUE;
+
+ // xmlsec05/06:
+ // getting real parent window when called from Security-Options TP
+ Window* pParent = NULL;
+ const SfxPoolItem* pParentItem;
+ if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) )
+ pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr();
+
+ // desired state
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ BOOL bActivateTracking = (pChangeTrack == 0); // toggle
+ if ( pItem )
+ bActivateTracking = pItem->GetValue(); // from argument
+
+ if ( !bActivateTracking )
+ {
+ if ( !pItem )
+ {
+ // no dialog on playing the macro
+ WarningBox aBox( pParent ? pParent : GetActiveDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_END_REDLINING ) );
+ bDo = ( aBox.Execute() == RET_YES );
+ }
+
+ if ( bDo )
+ {
+ if ( pChangeTrack->IsProtected() )
+ bDo = ExecuteChangeProtectionDialog( NULL );
+ if ( bDo )
+ {
+ pDoc->EndChangeTracking();
+ PostPaintGridAll();
+ }
+ }
+ }
+ else
+ {
+ pDoc->StartChangeTracking();
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ pDoc->SetChangeViewSettings(aChangeViewSet);
+ }
+
+ if ( bDo )
+ {
+ UpdateAcceptChangesDialog();
+
+ // Slots invalidieren
+ if (pBindings)
+ pBindings->InvalidateAll(FALSE);
+ if ( !pItem )
+ rReq.AppendItem( SfxBoolItem( FID_CHG_RECORD, bActivateTracking ) );
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ }
+ break;
+
+ case SID_CHG_PROTECT :
+ {
+ Window* pParent = NULL;
+ const SfxPoolItem* pParentItem;
+ if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) )
+ pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr();
+ if ( ExecuteChangeProtectionDialog( pParent ) )
+ {
+ rReq.Done();
+ SetDocumentModified();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_DOCUMENT_MERGE:
+ case SID_DOCUMENT_COMPARE:
+ {
+ BOOL bDo = TRUE;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if ( pChangeTrack && !pImpl->bIgnoreLostRedliningWarning )
+ {
+ if ( nSlot == SID_DOCUMENT_COMPARE )
+ { //! old changes trace will be lost
+ WarningBox aBox( GetActiveDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_END_REDLINING ) );
+ if( aBox.Execute() == RET_YES )
+ bDo = ExecuteChangeProtectionDialog( NULL, TRUE );
+ else
+ bDo = FALSE;
+ }
+ else // merge might reject some actions
+ bDo = ExecuteChangeProtectionDialog( NULL, TRUE );
+ }
+ if ( !bDo )
+ {
+ rReq.Ignore();
+ break;
+ }
+ SfxApplication* pApp = SFX_APP();
+ const SfxPoolItem* pItem;
+ SfxMedium* pMed = NULL;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState( SID_FILE_NAME, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxStringItem) )
+ {
+ String aFileName = ((const SfxStringItem*)pItem)->GetValue();
+
+ String aFilterName;
+ if ( pReqArgs->GetItemState( SID_FILTER_NAME, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxStringItem) )
+ {
+ aFilterName = ((const SfxStringItem*)pItem)->GetValue();
+ }
+ String aOptions;
+ if ( pReqArgs->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxStringItem) )
+ {
+ aOptions = ((const SfxStringItem*)pItem)->GetValue();
+ }
+ short nVersion = 0;
+ if ( pReqArgs->GetItemState( SID_VERSION, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxInt16Item) )
+ {
+ nVersion = ((const SfxInt16Item*)pItem)->GetValue();
+ }
+
+ // kein Filter angegeben -> Detection
+ if ( !aFilterName.Len() )
+ ScDocumentLoader::GetFilterName( aFileName, aFilterName, aOptions, TRUE, FALSE );
+
+ // filter name from dialog contains application prefix,
+ // GetFilter needs name without the prefix.
+ ScDocumentLoader::RemoveAppPrefix( aFilterName );
+
+ const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
+ SfxItemSet* pSet = new SfxAllItemSet( pApp->GetPool() );
+ if ( aOptions.Len() )
+ pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
+ if ( nVersion != 0 )
+ pSet->Put( SfxInt16Item( SID_VERSION, nVersion ) );
+ pMed = new SfxMedium( aFileName, STREAM_STD_READ, FALSE, pFilter, pSet );
+ }
+ else
+ {
+ // start file dialog asynchronous
+ pImpl->bIgnoreLostRedliningWarning = true;
+ delete pImpl->pRequest;
+ pImpl->pRequest = new SfxRequest( rReq );
+ delete pImpl->pDocInserter;
+ pImpl->pDocInserter = new ::sfx2::DocumentInserter(
+ 0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ), 0 );
+ pImpl->pDocInserter->StartExecuteModal( LINK( this, ScDocShell, DialogClosedHdl ) );
+ return ;
+ }
+
+ if ( pMed ) // nun wirklich ausfuehren...
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
+
+ ScDocShell* pOtherDocSh = new ScDocShell;
+ SfxObjectShellRef aDocShTablesRef = pOtherDocSh;
+ pOtherDocSh->DoLoad( pMed );
+ ULONG nErr = pOtherDocSh->GetErrorCode();
+ if (nErr)
+ ErrorHandler::HandleError( nErr ); // auch Warnings
+
+ if ( !pOtherDocSh->GetError() ) // nur Errors
+ {
+ BOOL bHadTrack = ( aDocument.GetChangeTrack() != NULL );
+ ULONG nStart = 0;
+ if ( nSlot == SID_DOCUMENT_MERGE && pChangeTrack )
+ {
+ nStart = pChangeTrack->GetActionMax() + 1;
+ }
+
+ if ( nSlot == SID_DOCUMENT_COMPARE )
+ CompareDocument( *pOtherDocSh->GetDocument() );
+ else
+ MergeDocument( *pOtherDocSh->GetDocument() );
+
+ // show "accept changes" dialog
+ //! get view for this document!
+ if ( !IsDocShared() )
+ {
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm )
+ {
+ pViewFrm->ShowChildWindow( ScAcceptChgDlgWrapper::GetChildWindowId(), TRUE ); //@51669
+ }
+ if ( pBindings )
+ {
+ pBindings->Invalidate( FID_CHG_ACCEPT );
+ }
+ }
+
+ rReq.SetReturnValue( SfxInt32Item( nSlot, 0 ) ); //! ???????
+ rReq.Done();
+
+ if (!bHadTrack) // neu eingeschaltet -> auch anzeigen
+ {
+ ScChangeViewSettings* pOldSet = aDocument.GetChangeViewSettings();
+ if ( !pOldSet || !pOldSet->ShowChanges() )
+ {
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ aDocument.SetChangeViewSettings(aChangeViewSet);
+ }
+ }
+ else if ( nSlot == SID_DOCUMENT_MERGE && IsDocShared() && pChangeTrack )
+ {
+ ULONG nEnd = pChangeTrack->GetActionMax();
+ if ( nEnd >= nStart )
+ {
+ // only show changes from merged document
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges( TRUE );
+ aChangeViewSet.SetShowAccepted( TRUE );
+ aChangeViewSet.SetHasActionRange( true );
+ aChangeViewSet.SetTheActionRange( nStart, nEnd );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+
+ // update view
+ PostPaintExtras();
+ PostPaintGridAll();
+ }
+ }
+ }
+ pOtherDocSh->DoClose(); // delete passiert mit der Ref
+ }
+ }
+ break;
+
+ case SID_DELETE_SCENARIO:
+ if (pReqArgs)
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ if ( pItem->ISA(SfxStringItem) )
+ {
+ String aName = ((const SfxStringItem*)pItem)->GetValue();
+ SCTAB nTab;
+ if (aDocument.GetTable( aName, nTab ))
+ {
+ // DeleteTable von viewfunc nach docfunc verschieben!
+
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ //! SetTabNo in DeleteTable weglassen?
+ SCTAB nDispTab = pSh->GetViewData()->GetTabNo();
+ pSh->DeleteTable( nTab );
+ pSh->SetTabNo(nDispTab);
+ rReq.Done();
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_EDIT_SCENARIO:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ if ( pItem->ISA(SfxStringItem) )
+ {
+ String aName = ((const SfxStringItem*)pItem)->GetValue();
+ SCTAB nTab;
+ if (aDocument.GetTable( aName, nTab ))
+ {
+ if (aDocument.IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ aDocument.GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ // Determine if the Sheet that the Scenario was created on
+ // is protected. But first we need to find that Sheet.
+ // Rewind back to the actual sheet.
+ SCTAB nActualTab = nTab;
+ do
+ {
+ nActualTab--;
+ }
+ while(aDocument.IsScenario(nActualTab));
+ BOOL bSheetProtected = aDocument.IsTabProtected(nActualTab);
+
+ //! anderen Titel am Dialog setzen
+//CHINA001 ScNewScenarioDlg* pNewDlg =
+//CHINA001 new ScNewScenarioDlg( GetActiveDialogParent(), aName, TRUE, bSheetProtected);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNewScenarioDlg* pNewDlg = pFact->CreateScNewScenarioDlg( GetActiveDialogParent(), aName, RID_SCDLG_NEWSCENARIO, TRUE,bSheetProtected);
+ DBG_ASSERT(pNewDlg, "Dialog create fail!");//CHINA001
+ pNewDlg->SetScenarioData( aName, aComment, aColor, nFlags );
+ if ( pNewDlg->Execute() == RET_OK )
+ {
+ pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
+ ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ rReq.Done();
+ }
+ delete pNewDlg;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_ATTR_YEAR2000 :
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ if ( pItem->ISA(SfxUInt16Item) )
+ {
+ UINT16 nY2k = ((SfxUInt16Item*)pItem)->GetValue();
+ // immer an den DocOptions setzen, damit das auch fuer SO50
+ // gespeichert wird (und alle Abfragen bisher auch darauf laufen).
+ // SetDocOptions propagiert das an den NumberFormatter
+ ScDocOptions aDocOpt( aDocument.GetDocOptions() );
+ aDocOpt.SetYear2000( nY2k );
+ aDocument.SetDocOptions( aDocOpt );
+ // die FormShell soll es mitbekommen
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ FmFormShell* pFSh = pSh->GetFormShell();
+ if ( pFSh )
+ pFSh->SetY2KState( nY2k );
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_SHARE_DOC:
+ {
+ ScViewData* pViewData = GetViewData();
+ if ( !pViewData )
+ {
+ rReq.Ignore();
+ break;
+ }
+
+ ScShareDocumentDlg aDlg( GetActiveDialogParent(), pViewData );
+ if ( aDlg.Execute() == RET_OK )
+ {
+ bool bSetShared = aDlg.IsShareDocumentChecked();
+ if ( bSetShared != static_cast< bool >( IsDocShared() ) )
+ {
+ if ( bSetShared )
+ {
+ bool bContinue = true;
+ if ( HasName() )
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_DOC_WILLBESAVED ) );
+ if ( aBox.Execute() == RET_NO )
+ {
+ bContinue = false;
+ }
+ }
+ if ( bContinue )
+ {
+ EnableSharedSettings( true );
+
+ SC_MOD()->SetInSharedDocSaving( true );
+ if ( !SwitchToShared( sal_True, sal_True ) )
+ {
+ // TODO/LATER: what should be done in case the switch has failed?
+ // for example in case the user has cancelled the saveAs operation
+ }
+
+ SC_MOD()->SetInSharedDocSaving( false );
+
+ InvalidateName();
+ GetUndoManager()->Clear();
+
+ ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
+ if ( pTabView )
+ {
+ pTabView->UpdateLayerLocks();
+ }
+ }
+ }
+ else
+ {
+ uno::Reference< frame::XModel > xModel;
+ try
+ {
+ // load shared file
+ xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
+
+ // check if shared flag is set in shared file
+ bool bShared = false;
+ ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
+ if ( pDocObj )
+ {
+ ScDocShell* pDocShell = dynamic_cast< ScDocShell* >( pDocObj->GetEmbeddedObject() );
+ if ( pDocShell )
+ {
+ bShared = pDocShell->HasSharedXMLFlagSet();
+ }
+ }
+
+ // #i87870# check if shared status was disabled and enabled again
+ bool bOwnEntry = false;
+ try
+ {
+ ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
+ bOwnEntry = aControlFile.HasOwnEntry();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ if ( bShared && bOwnEntry )
+ {
+ uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
+ if ( xStorable->isReadonly() )
+ {
+ xCloseable->close( sal_True );
+
+ String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
+ try
+ {
+ ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
+ uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData();
+ if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID )
+ {
+ if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 )
+ {
+ aUserName = aData[LOCKFILE_OOOUSERNAME_ID];
+ }
+ else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 )
+ {
+ aUserName = aData[LOCKFILE_SYSUSERNAME_ID];
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_TRY_LATER ) );
+ aMessage.SearchAndReplaceAscii( "%1", aUserName );
+
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ), aMessage );
+ aBox.Execute();
+ }
+ else
+ {
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_DOC_DISABLESHARED ) );
+ if ( aBox.Execute() == RET_YES )
+ {
+ xCloseable->close( sal_True );
+
+ if ( !SwitchToShared( sal_False, sal_True ) )
+ {
+ // TODO/LATER: what should be done in case the switch has failed?
+ // for example in case the user has cancelled the saveAs operation
+ }
+
+ EnableSharedSettings( false );
+
+ if ( pBindings )
+ {
+ pBindings->ExecuteSynchron( SID_SAVEDOC );
+ }
+
+ ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
+ if ( pTabView )
+ {
+ pTabView->UpdateLayerLocks();
+ }
+ }
+ else
+ {
+ xCloseable->close( sal_True );
+ }
+ }
+ }
+ else
+ {
+ xCloseable->close( sal_True );
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
+ ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
+ aBox.Execute();
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "SID_SHARE_DOC: caught exception\n" );
+ SC_MOD()->SetInSharedDocSaving( false );
+
+ try
+ {
+ uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
+ xClose->close( sal_True );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ rReq.Done();
+ }
+ break;
+
+ default:
+ {
+ // kleiner (?) Hack -> forward der Slots an TabViewShell
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ pSh->Execute( rReq );
+ else
+ SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
+ }
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void UpdateAcceptChangesDialog()
+{
+ // update "accept changes" dialog
+ //! notify all views
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT );
+ if ( pChild )
+ ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg();
+ }
+}
+
+//------------------------------------------------------------------
+
+BOOL ScDocShell::ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQueryIfProtected )
+{
+ BOOL bDone = FALSE;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ BOOL bProtected = pChangeTrack->IsProtected();
+ if ( bJustQueryIfProtected && !bProtected )
+ return TRUE;
+
+ String aTitle( ScResId( bProtected ? SCSTR_CHG_UNPROTECT : SCSTR_CHG_PROTECT ) );
+ String aText( ScResId( SCSTR_PASSWORD ) );
+ String aPassword;
+
+ SfxPasswordDialog* pDlg = new SfxPasswordDialog(
+ _pParent ? _pParent : GetActiveDialogParent(), &aText );
+ pDlg->SetText( aTitle );
+ pDlg->SetMinLen( 1 );
+ pDlg->SetHelpId( SID_CHG_PROTECT );
+ pDlg->SetEditHelpId( HID_CHG_PROTECT );
+ if ( !bProtected )
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+ if ( pDlg->Execute() == RET_OK )
+ aPassword = pDlg->GetPassword();
+ delete pDlg;
+
+ if ( aPassword.Len() )
+ {
+ if ( bProtected )
+ {
+ if ( SvPasswordHelper::CompareHashPassword(pChangeTrack->GetProtection(), aPassword) )
+ {
+ if ( bJustQueryIfProtected )
+ bDone = TRUE;
+ else
+ pChangeTrack->SetProtection(
+ com::sun::star::uno::Sequence< sal_Int8 > (0) );
+ }
+ else
+ {
+ InfoBox aBox( GetActiveDialogParent(),
+ String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ }
+ else
+ {
+ com::sun::star::uno::Sequence< sal_Int8 > aPass;
+ SvPasswordHelper::GetHashPassword( aPass, aPassword );
+ pChangeTrack->SetProtection( aPass );
+ }
+ if ( bProtected != pChangeTrack->IsProtected() )
+ {
+ UpdateAcceptChangesDialog();
+ bDone = TRUE;
+ }
+ }
+ }
+ else if ( bJustQueryIfProtected )
+ bDone = TRUE;
+ return bDone;
+}
+
+
+//------------------------------------------------------------------
+
+void ScDocShell::DoRecalc( BOOL bApi )
+{
+ BOOL bDone = FALSE;
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(pSh);
+ if ( pHdl && pHdl->IsInputMode() && pHdl->IsFormulaMode() && !bApi )
+ {
+ pHdl->FormulaPreview(); // Teilergebnis als QuickHelp
+ bDone = TRUE;
+ }
+ else
+ {
+ pSh->UpdateInputLine(); // InputEnterHandler
+ pSh->UpdateInputHandler();
+ }
+ }
+ if (!bDone) // sonst Dokument neu berechnen
+ {
+ WaitObject aWaitObj( GetActiveDialogParent() );
+ aDocument.CalcFormulaTree();
+ if ( pSh )
+ pSh->UpdateCharts(TRUE);
+
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
+ // #47939# Wenn es Charts gibt, dann alles painten, damit nicht
+ // PostDataChanged und die Charts nacheinander kommen und Teile
+ // doppelt gepainted werden.
+
+ ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection();
+ if ( pCharts && pCharts->GetCount() )
+ PostPaintGridAll();
+ else
+ PostDataChanged();
+ }
+}
+
+void ScDocShell::DoHardRecalc( BOOL /* bApi */ )
+{
+ WaitObject aWaitObj( GetActiveDialogParent() );
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ pSh->UpdateInputLine(); // InputEnterHandler
+ pSh->UpdateInputHandler();
+ }
+ aDocument.CalcAll();
+ GetDocFunc().DetectiveRefresh(); // erzeugt eigenes Undo
+ if ( pSh )
+ pSh->UpdateCharts(TRUE);
+
+ // set notification flags for "calculate" event (used in SFX_HINT_DATACHANGED broadcast)
+ // (might check for the presence of any formulas on each sheet)
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nTab;
+ if (aDocument.HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true )) // search also for VBA hendler
+ for (nTab=0; nTab<nTabCount; nTab++)
+ aDocument.SetCalcNotification(nTab);
+
+ // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally
+ // in addition to SFX_HINT_DATACHANGED.
+ aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) );
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
+ // use hard recalc also to disable stream-copying of all sheets
+ // (somewhat consistent with charts)
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (aDocument.IsStreamValid(nTab))
+ aDocument.SetStreamValid(nTab, FALSE);
+
+ PostPaintGridAll();
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::DoAutoStyle( const ScRange& rRange, const String& rStyle )
+{
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ ScStyleSheet* pStyleSheet =
+ pStylePool->FindCaseIns( rStyle, SFX_STYLE_FAMILY_PARA );
+ if (!pStyleSheet)
+ pStyleSheet = (ScStyleSheet*)
+ pStylePool->Find( ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA );
+ if (pStyleSheet)
+ {
+ DBG_ASSERT(rRange.aStart.Tab() == rRange.aEnd.Tab(),
+ "DoAutoStyle mit mehreren Tabellen");
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ aDocument.ApplyStyleAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, *pStyleSheet );
+ aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+ PostPaint( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, PAINT_GRID );
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::NotifyStyle( const SfxStyleSheetHint& rHint )
+{
+ USHORT nId = rHint.GetHint();
+ const SfxStyleSheetBase* pStyle = rHint.GetStyleSheet();
+ if (!pStyle)
+ return;
+
+ if ( pStyle->GetFamily() == SFX_STYLE_FAMILY_PAGE )
+ {
+ if ( nId == SFX_STYLESHEET_MODIFIED )
+ {
+ ScDocShellModificator aModificator( *this );
+
+ String aNewName = pStyle->GetName();
+ String aOldName = aNewName;
+ BOOL bExtended = rHint.ISA(SfxStyleSheetHintExtended); // Name geaendert?
+ if (bExtended)
+ aOldName = ((SfxStyleSheetHintExtended&)rHint).GetOldName();
+
+ if ( aNewName != aOldName )
+ aDocument.RenamePageStyleInUse( aOldName, aNewName );
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aDocument.GetPageStyle(nTab) == aNewName) // schon auf neu angepasst
+ {
+ aDocument.PageStyleModified( nTab, aNewName );
+ ScPrintFunc aPrintFunc( this, GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ aModificator.SetDocumentModified();
+
+ if (bExtended)
+ {
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_STATUS_PAGESTYLE );
+ pBindings->Invalidate( SID_STYLE_FAMILY4 );
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+ }
+ }
+ }
+ else if ( pStyle->GetFamily() == SFX_STYLE_FAMILY_PARA )
+ {
+ if ( nId == SFX_STYLESHEET_MODIFIED)
+ {
+ String aNewName = pStyle->GetName();
+ String aOldName = aNewName;
+ BOOL bExtended = rHint.ISA(SfxStyleSheetHintExtended);
+ if (bExtended)
+ aOldName = ((SfxStyleSheetHintExtended&)rHint).GetOldName();
+ if ( aNewName != aOldName )
+ {
+ ScConditionalFormatList* pList = aDocument.GetCondFormList();
+ if (pList)
+ pList->RenameCellStyle( aOldName,aNewName );
+ }
+ }
+ }
+
+ // alles andere geht ueber Slots...
+}
+
+// wie in printfun.cxx
+#define ZOOM_MIN 10
+
+void ScDocShell::SetPrintZoom( SCTAB nTab, USHORT nScale, USHORT nPages )
+{
+ BOOL bUndo(aDocument.IsUndoEnabled());
+ String aStyleName = aDocument.GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ ScDocShellModificator aModificator( *this );
+
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if (bUndo)
+ {
+ USHORT nOldScale = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ USHORT nOldPages = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
+ GetUndoManager()->AddUndoAction( new ScUndoPrintZoom(
+ this, nTab, nOldScale, nOldPages, nScale, nPages ) );
+ }
+
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
+
+ ScPrintFunc aPrintFunc( this, GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ }
+}
+
+BOOL ScDocShell::AdjustPrintZoom( const ScRange& rRange )
+{
+ BOOL bChange = FALSE;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ String aStyleName = aDocument.GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ BOOL bHeaders = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_HEADERS)).GetValue();
+ USHORT nOldScale = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ USHORT nOldPages = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
+ const ScRange* pRepeatCol = aDocument.GetRepeatColRange( nTab );
+ const ScRange* pRepeatRow = aDocument.GetRepeatRowRange( nTab );
+
+ // benoetigte Skalierung fuer Selektion ausrechnen
+
+ USHORT nNewScale = nOldScale;
+
+ long nBlkTwipsX = 0;
+ if (bHeaders)
+ nBlkTwipsX += (long) PRINT_HEADER_WIDTH;
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ if ( pRepeatCol && nStartCol >= pRepeatCol->aStart.Col() )
+ {
+ for (SCCOL i=pRepeatCol->aStart.Col(); i<=pRepeatCol->aEnd.Col(); i++ )
+ nBlkTwipsX += aDocument.GetColWidth( i, nTab );
+ if ( nStartCol <= pRepeatCol->aEnd.Col() )
+ nStartCol = pRepeatCol->aEnd.Col() + 1;
+ }
+ // legacy compilers' own scope for i
+ {
+ for ( SCCOL i=nStartCol; i<=nEndCol; i++ )
+ nBlkTwipsX += aDocument.GetColWidth( i, nTab );
+ }
+
+ long nBlkTwipsY = 0;
+ if (bHeaders)
+ nBlkTwipsY += (long) PRINT_HEADER_HEIGHT;
+ SCROW nStartRow = rRange.aStart.Row();
+ SCROW nEndRow = rRange.aEnd.Row();
+ if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() )
+ {
+ nBlkTwipsY += aDocument.GetRowHeight( pRepeatRow->aStart.Row(),
+ pRepeatRow->aEnd.Row(), nTab );
+ if ( nStartRow <= pRepeatRow->aEnd.Row() )
+ nStartRow = pRepeatRow->aEnd.Row() + 1;
+ }
+ nBlkTwipsY += aDocument.GetRowHeight( nStartRow, nEndRow, nTab );
+
+ Size aPhysPage;
+ long nHdr, nFtr;
+ ScPrintFunc aOldPrFunc( this, GetPrinter(), nTab );
+ aOldPrFunc.GetScaleData( aPhysPage, nHdr, nFtr );
+ nBlkTwipsY += nHdr + nFtr;
+
+ if ( nBlkTwipsX == 0 ) // #100639# hidden columns/rows may lead to 0
+ nBlkTwipsX = 1;
+ if ( nBlkTwipsY == 0 )
+ nBlkTwipsY = 1;
+
+ long nNeeded = Min( aPhysPage.Width() * 100 / nBlkTwipsX,
+ aPhysPage.Height() * 100 / nBlkTwipsY );
+ if ( nNeeded < ZOOM_MIN )
+ nNeeded = ZOOM_MIN; // Begrenzung
+ if ( nNeeded < (long) nNewScale )
+ nNewScale = (USHORT) nNeeded;
+
+ bChange = ( nNewScale != nOldScale || nOldPages != 0 );
+ if ( bChange )
+ SetPrintZoom( nTab, nNewScale, 0 );
+ }
+ return bChange;
+}
+
+void ScDocShell::PageStyleModified( const String& rStyleName, BOOL bApi )
+{
+ ScDocShellModificator aModificator( *this );
+
+ BOOL bWarn = FALSE;
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nUseTab = MAXTAB+1;
+ for (SCTAB nTab=0; nTab<nTabCount && nUseTab>MAXTAB; nTab++)
+ if ( aDocument.GetPageStyle(nTab) == rStyleName &&
+ ( !bApi || aDocument.GetPageSize(nTab).Width() ) )
+ nUseTab = nTab;
+ // bei bApi nur, wenn Umbrueche schon angezeigt
+
+ if (ValidTab(nUseTab)) // nicht verwendet -> nichts zu tun
+ {
+ ScPrintFunc aPrintFunc( this, GetPrinter(), nUseTab ); //! ohne CountPages auskommen
+ if (!aPrintFunc.UpdatePages()) // setzt Umbrueche auf allen Tabs
+ bWarn = TRUE;
+
+ if (bWarn && !bApi)
+ {
+ ScWaitCursorOff aWaitOff( GetActiveDialogParent() );
+ InfoBox aInfoBox(GetActiveDialogParent(),
+ ScGlobal::GetRscString(STR_PRINT_INVALID_AREA));
+ aInfoBox.Execute();
+ }
+ }
+
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+}
+
+void ScDocShell::ExecutePageStyle( SfxViewShell& rCaller,
+ SfxRequest& rReq,
+ SCTAB nCurTab )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ switch ( rReq.GetSlot() )
+ {
+ case SID_STATUS_PAGESTYLE: // Click auf StatusBar-Control
+ case SID_FORMATPAGE:
+ {
+ if ( pReqArgs != NULL )
+ {
+ }
+ else if ( pReqArgs == NULL )
+ {
+ BOOL bUndo(aDocument.IsUndoEnabled());
+ String aOldName = aDocument.GetPageStyle( nCurTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet
+ = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ ScStyleSaveData aOldData;
+ if (bUndo)
+ aOldData.InitFromStyle( pStyleSheet );
+
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+//CHINA001 ScStyleDlg* pDlg = new ScStyleDlg( GetActiveDialogParent(),
+//CHINA001 *pStyleSheet,
+//CHINA001 RID_SCDLG_STYLES_PAGE );
+//CHINA001
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScStyleDlg( GetActiveDialogParent(), *pStyleSheet, RID_SCDLG_STYLES_PAGE, RID_SCDLG_STYLES_PAGE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ WaitObject aWait( GetActiveDialogParent() );
+
+ String aNewName = pStyleSheet->GetName();
+ if ( aNewName != aOldName &&
+ aDocument.RenamePageStyleInUse( aOldName, aNewName ) )
+ {
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_STATUS_PAGESTYLE );
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ }
+ }
+
+ if ( pOutSet )
+ aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet );
+
+ // merken fuer GetState():
+ GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, bHeaderOn, bFooterOn );
+ rCaller.GetViewFrame()->GetBindings().Invalidate( SID_HFEDIT );
+
+ ScStyleSaveData aNewData;
+ aNewData.InitFromStyle( pStyleSheet );
+ if (bUndo)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( this, SFX_STYLE_FAMILY_PAGE,
+ aOldData, aNewData ) );
+ }
+
+ PageStyleModified( aNewName, FALSE );
+ rReq.Done();
+ }
+ delete pDlg;
+
+ rStyleSet.ClearItem( ATTR_PAGE_PAPERTRAY );
+ }
+ }
+ }
+ break;
+
+ case SID_HFEDIT:
+ {
+ if ( pReqArgs != NULL )
+ {
+ }
+ else if ( pReqArgs == NULL )
+ {
+ String aStr( aDocument.GetPageStyle( nCurTab ) );
+
+ ScStyleSheetPool* pStylePool
+ = aDocument.GetStyleSheetPool();
+
+ SfxStyleSheetBase* pStyleSheet
+ = pStylePool->Find( aStr, SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ SvxPageUsage eUsage =
+ SvxPageUsage( ((const SvxPageItem&)
+ rStyleSet.Get( ATTR_PAGE )).
+ GetPageUsage() );
+ BOOL bShareHeader = IS_SHARE_HEADER(rStyleSet);
+ BOOL bShareFooter = IS_SHARE_FOOTER(rStyleSet);
+ USHORT nResId = 0;
+
+ switch ( eUsage )
+ {
+ case SVX_PAGE_LEFT:
+ case SVX_PAGE_RIGHT:
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT;
+ else if ( SVX_PAGE_RIGHT == eUsage )
+ {
+ if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
+ }
+ else
+ {
+ // #69193a# respect "shared" setting
+ if ( !bHeaderOn && bFooterOn )
+ nResId = bShareFooter ?
+ RID_SCDLG_HFEDIT_RIGHTFOOTER :
+ RID_SCDLG_HFEDIT_LEFTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = bShareHeader ?
+ RID_SCDLG_HFEDIT_RIGHTHEADER :
+ RID_SCDLG_HFEDIT_LEFTHEADER;
+ }
+ }
+ break;
+
+ case SVX_PAGE_MIRROR:
+ case SVX_PAGE_ALL:
+ default:
+ {
+ if ( !bShareHeader && !bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_ALL;
+ else if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_FOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_HEADER;
+ }
+ else if ( bShareHeader && bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT;
+ else
+ {
+ if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
+ }
+ }
+ else if ( !bShareHeader && bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_SFTR;
+ else if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_HEADER;
+ }
+ else if ( bShareHeader && !bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_SHDR;
+ else if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_FOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
+ }
+ }
+ }
+
+//CHINA001 ScHFEditDlg* pDlg
+//CHINA001 = new ScHFEditDlg( SFX_APP()->GetViewFrame(),
+//CHINA001 GetActiveDialogParent(),
+//CHINA001 rStyleSet,
+//CHINA001 aStr,
+//CHINA001 nResId );
+//CHINA001
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScHFEditDlg( SfxViewFrame::Current(),
+ GetActiveDialogParent(),
+ rStyleSet,
+ aStr,
+ RID_SCDLG_HFEDIT, nResId);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ if ( pOutSet )
+ aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet );
+
+ SetDocumentModified();
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ScDocShell::GetStatePageStyle( SfxViewShell& /* rCaller */,
+ SfxItemSet& rSet,
+ SCTAB nCurTab )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_STATUS_PAGESTYLE:
+ rSet.Put( SfxStringItem( nWhich, aDocument.GetPageStyle( nCurTab ) ) );
+ break;
+
+ case SID_HFEDIT:
+ {
+ String aStr = aDocument.GetPageStyle( nCurTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStr, SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, bHeaderOn, bFooterOn );
+
+ if ( !bHeaderOn && !bFooterOn )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void lcl_GetPrintData( ScDocShell* pDocShell /*in*/,
+ ScDocument* pDocument /*in*/, SfxPrinter* pPrinter /*in*/,
+ PrintDialog* pPrintDialog /*in*/, bool bForceSelected /*in*/,
+ ScMarkData* pMarkData /*inout*/, bool& rbHasOptions /*out*/,
+ ScPrintOptions& rOptions /*out*/, bool& rbAllTabs /*out*/,
+ long& rnTotalPages /*out*/, long aPageArr[] /*out*/,
+ MultiSelection& rPageRanges /*out*/, ScRange** ppMarkedRange /*out*/ )
+{
+ // get settings from print options sub-dialog
+ const SfxItemSet& rOptionSet = pPrinter->GetOptions();
+ const SfxPoolItem* pItem;
+ rbHasOptions = ( rOptionSet.GetItemState( SID_SCPRINTOPTIONS, FALSE, &pItem ) == SFX_ITEM_SET );
+ if ( rbHasOptions )
+ {
+ rOptions = ((const ScTpPrintItem*)pItem)->GetPrintOptions();
+ }
+ else
+ {
+ // use configuration
+ 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();
+ for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, pPrinter, nTab, 0, 0, NULL, &rOptions );
+ long nThisTab = aPrintFunc.GetTotalPages();
+ aPageArr[nTab] = nThisTab;
+ rnTotalPages += nThisTab;
+ }
+
+ rPageRanges.SetTotalRange( Range( 0, RANGE_MAX ) );
+ rPageRanges.Select( Range( 1, rnTotalPages ) );
+
+ rbAllTabs = ( pPrintDialog ? ( pPrintDialog->GetCheckedSheetRange() == PRINTSHEETS_ALL ) : SC_MOD()->GetPrintOptions().GetAllSheets() );
+ if ( bForceSelected )
+ {
+ rbAllTabs = false;
+ }
+
+ if ( ( pPrintDialog && pPrintDialog->GetCheckedSheetRange() == PRINTSHEETS_SELECTED_CELLS ) || bForceSelected )
+ {
+ if ( pMarkData && ( pMarkData->IsMarked() || pMarkData->IsMultiMarked() ) )
+ {
+ pMarkData->MarkToMulti();
+ *ppMarkedRange = new ScRange;
+ pMarkData->GetMultiMarkArea( **ppMarkedRange );
+ pMarkData->MarkToSimple();
+ }
+ }
+
+ PrintDialogRange eDlgOption = pPrintDialog ? pPrintDialog->GetCheckedRange() : PRINTDIALOG_ALL;
+ if ( eDlgOption == PRINTDIALOG_RANGE )
+ {
+ rPageRanges = MultiSelection( pPrintDialog->GetRangeText() );
+ }
+
+ // get number of total pages if selection
+ if ( !rbAllTabs )
+ {
+ rnTotalPages = 0;
+ for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ if ( *ppMarkedRange ) // selected range is used instead of print ranges -> page count is different
+ {
+ ScPrintFunc aPrintFunc( pDocShell, pPrinter, nTab, 0, 0, *ppMarkedRange, &rOptions );
+ aPageArr[nTab] = aPrintFunc.GetTotalPages();
+ }
+ if ( !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ rnTotalPages += aPageArr[nTab];
+ }
+ }
+ if ( eDlgOption == PRINTDIALOG_ALL || bForceSelected )
+ {
+ rPageRanges.Select( Range( 1, rnTotalPages ) );
+ }
+ }
+}
+
+bool ScDocShell::CheckPrint( PrintDialog* pPrintDialog, ScMarkData* pMarkData, bool bForceSelected, bool bIsAPI )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+ if ( !pPrinter )
+ {
+ return false;
+ }
+
+ bool bHasOptions = false;
+ ScPrintOptions aOptions;
+ bool bAllTabs = true;
+ long nTotalPages = 0;
+ long aPageArr[MAXTABCOUNT]; // pages per sheet
+ MultiSelection aPageRanges; // pages to print
+ ScRange* pMarkedRange = NULL;
+
+ lcl_GetPrintData( this, &aDocument, pPrinter, pPrintDialog, bForceSelected,
+ pMarkData, bHasOptions, aOptions, bAllTabs, nTotalPages,
+ aPageArr, aPageRanges, &pMarkedRange );
+
+ delete pMarkedRange;
+
+ if ( nTotalPages == 0 )
+ {
+ if ( !bIsAPI )
+ {
+ WarningBox aWarningBox( GetActiveDialogParent(), WinBits( WB_OK ),
+ String( ScResId( STR_PRINT_NOTHING ) ) );
+ aWarningBox.Execute();
+ }
+ return false;
+ }
+
+ return true;
+}
+
+void ScDocShell::PreparePrint( PrintDialog* pPrintDialog, ScMarkData* pMarkData )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+ if ( !pPrinter )
+ {
+ return;
+ }
+
+ delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob()
+ pOldJobSetup = new ScJobSetup( pPrinter ); // Einstellungen merken
+
+ // Einstellungen fuer die erste gedruckte Seite muessen hier (vor StartJob) gesetzt werden
+ //! Selection etc. mit Print() zusammenfassen !!!
+ //! Seiten nur einmal zaehlen
+
+ bool bHasOptions = false;
+ ScPrintOptions aOptions;
+ bool bAllTabs = true;
+ long nTotalPages = 0;
+ long aPageArr[MAXTABCOUNT]; // pages per sheet
+ MultiSelection aPageRanges; // pages to print
+ ScRange* pMarkedRange = NULL;
+
+ lcl_GetPrintData( this, &aDocument, pPrinter, pPrintDialog, false,
+ pMarkData, bHasOptions, aOptions, bAllTabs, nTotalPages,
+ aPageArr, aPageRanges, &pMarkedRange );
+
+ BOOL bFound = FALSE; // erste Seite gefunden
+ long nTabStart = 0;
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for ( SCTAB nTab=0; nTab<nTabCount && !bFound; nTab++ )
+ {
+ if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ long nNext = nTabStart + aPageArr[nTab];
+ BOOL bSelected = FALSE;
+ for (long nP=nTabStart+1; nP<=nNext; nP++) // 1-basiert
+ if (aPageRanges.IsSelected( nP )) // eine Seite von dieser Tabelle selektiert?
+ bSelected = TRUE;
+
+ if (bSelected)
+ {
+ ScPrintFunc aPrintFunc( this, pPrinter, nTab );
+
+ aPrintFunc.ApplyPrintSettings(); // dann Settings fuer diese Tabelle
+ bFound = TRUE;
+ }
+ nTabStart = nNext;
+ }
+ }
+
+ delete pMarkedRange;
+}
+
+BOOL lcl_HasTransparent( ScDocument* pDoc, SCTAB nTab, const ScRange* pRange )
+{
+ BOOL bFound = FALSE;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ Rectangle aMMRect;
+ if ( pRange )
+ aMMRect = pDoc->GetMMRect( pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row(), nTab );
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if (pObject->IsTransparent())
+ {
+ if ( pRange )
+ {
+ Rectangle aObjRect = pObject->GetLogicRect();
+ if ( aObjRect.IsOver( aMMRect ) )
+ bFound = TRUE;
+ }
+ else
+ bFound = TRUE;
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScDocShell::Print( SfxProgress& rProgress, PrintDialog* pPrintDialog,
+ ScMarkData* pMarkData, Window* pDialogParent, BOOL bForceSelected, BOOL bIsAPI )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+ if ( !pPrinter )
+ {
+ return;
+ }
+
+ bool bHasOptions = false;
+ ScPrintOptions aOptions;
+ bool bAllTabs = true;
+ long nTotalPages = 0;
+ long aPageArr[MAXTABCOUNT]; // pages per sheet
+ MultiSelection aPageRanges; // pages to print
+ ScRange* pMarkedRange = NULL;
+
+ lcl_GetPrintData( this, &aDocument, pPrinter, pPrintDialog, bForceSelected,
+ pMarkData, bHasOptions, aOptions, bAllTabs, nTotalPages,
+ aPageArr, aPageRanges, &pMarkedRange );
+
+ USHORT nCollateCopies = 1;
+ if ( pPrintDialog && pPrintDialog->IsCollateEnabled() && pPrintDialog->IsCollateChecked() )
+ nCollateCopies = pPrintDialog->GetCopyCount();
+
+ // test if printed range contains transparent objects
+
+ BOOL bHasTransp = FALSE;
+ BOOL bAnyPrintRanges = aDocument.HasPrintRange();
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for ( SCTAB nTab=0; nTab<nTabCount && !bHasTransp; nTab++ )
+ {
+ if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ aDocument.GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if ( ((const ScViewObjectModeItem&)rSet.Get(ATTR_PAGE_CHARTS)).GetValue() == VOBJ_MODE_SHOW ||
+ ((const ScViewObjectModeItem&)rSet.Get(ATTR_PAGE_OBJECTS)).GetValue() == VOBJ_MODE_SHOW ||
+ ((const ScViewObjectModeItem&)rSet.Get(ATTR_PAGE_DRAWINGS)).GetValue() == VOBJ_MODE_SHOW )
+ {
+ if ( pMarkedRange )
+ bHasTransp = bHasTransp || lcl_HasTransparent( &aDocument, nTab, pMarkedRange );
+ else if ( aDocument.GetPrintRangeCount(nTab) )
+ {
+ USHORT nRangeCount = aDocument.GetPrintRangeCount(nTab);
+ for (USHORT i=0; i<nRangeCount; i++)
+ bHasTransp = bHasTransp ||
+ lcl_HasTransparent( &aDocument, nTab, aDocument.GetPrintRange( nTab, i ) );
+ }
+ else if (!bAnyPrintRanges || aDocument.IsPrintEntireSheet(nTab))
+ bHasTransp = bHasTransp || lcl_HasTransparent( &aDocument, nTab, NULL );
+ }
+ }
+ }
+ }
+
+ BOOL bContinue = pPrinter->InitJob( pDialogParent, !bIsAPI && bHasTransp );
+
+ if ( bContinue )
+ {
+ for ( USHORT n=0; n<nCollateCopies; n++ )
+ {
+ long nTabStart = 0;
+ long nDisplayStart = 0;
+ long nAttrPage = 1;
+ long nPrinted = 0;
+
+ for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
+ {
+ if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ FmFormView* pDrawView = NULL;
+ Rectangle aFull( 0, 0, LONG_MAX, LONG_MAX );
+
+ // #114135#
+ ScDrawLayer* pModel = aDocument.GetDrawLayer(); // ist nicht NULL
+
+ if(pModel)
+ {
+ pDrawView = new FmFormView( pModel, pPrinter );
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ pDrawView->SetPrintPreview( TRUE );
+ }
+
+ ScPrintFunc aPrintFunc( this, pPrinter, nTab, nAttrPage, nTotalPages, pMarkedRange, &aOptions );
+ aPrintFunc.SetDrawView( pDrawView );
+ nPrinted += aPrintFunc.DoPrint( aPageRanges, nTabStart, nDisplayStart, TRUE, &rProgress, NULL );
+
+ nTabStart += aPageArr[nTab];
+ if ( aDocument.NeedPageResetAfterTab(nTab) )
+ nDisplayStart = 0;
+ else
+ nDisplayStart += aPageArr[nTab];
+ nAttrPage = aPrintFunc.GetFirstPageNo(); // behalten oder aus Vorlage
+
+ delete pDrawView;
+ }
+ }
+
+ if ( n+1 < nCollateCopies &&
+ (pPrinter->GetDuplexMode() == DUPLEX_SHORTEDGE || pPrinter->GetDuplexMode() == DUPLEX_LONGEDGE) &&
+ ( nPrinted % 2 ) == 1 )
+ {
+ // #105584# when several collated copies are printed in duplex mode, and there is
+ // an odd number of pages, print an empty page between copies, so the first page of
+ // the second copy isn't printed on the back of the last page of the first copy.
+ // (same as in Writer ViewShell::Prt)
+
+ // FIXME: needs to be adapted to XRenderable interface
+ #if 0
+ pPrinter->StartPage();
+ pPrinter->EndPage();
+ #endif
+ }
+ }
+ }
+
+ delete pMarkedRange;
+
+ if (pOldJobSetup)
+ {
+ pPrinter->SetOrientation( pOldJobSetup->eOrientation );
+ pPrinter->SetPaperBin ( pOldJobSetup->nPaperBin );
+ pPrinter->SetPaper ( pOldJobSetup->ePaper );
+
+ if ( PAPER_USER == pOldJobSetup->ePaper )
+ {
+ pPrinter->SetMapMode( pOldJobSetup->aUserMapMode );
+ pPrinter->SetPaperSizeUser( pOldJobSetup->aUserSize );
+ }
+
+ delete pOldJobSetup;
+ pOldJobSetup = NULL;
+ }
+
+ if ( bHasOptions )
+ {
+ // remove PrintOptions from printer ItemSet,
+ // so next time the options from the configuration are used
+
+ SfxItemSet aSet( pPrinter->GetOptions() );
+ aSet.ClearItem( SID_SCPRINTOPTIONS );
+ pPrinter->SetOptions( aSet );
+ }
+
+ PostPaintGridAll(); //! nur wenn geaendert
+}
+
+void ScDocShell::GetState( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case FID_AUTO_CALC:
+ if ( (BOOL) aDocument.GetHardRecalcState() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich, aDocument.GetAutoCalc() ) );
+ break;
+
+ case FID_CHG_RECORD:
+ if ( IsDocShared() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich,
+ aDocument.GetChangeTrack() != NULL ) );
+ break;
+
+ case SID_CHG_PROTECT:
+ {
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if ( pChangeTrack && !IsDocShared() )
+ rSet.Put( SfxBoolItem( nWhich,
+ pChangeTrack->IsProtected() ) );
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DOCUMENT_COMPARE:
+ {
+ if ( IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ // Wenn eine Formel editiert wird, muss FID_RECALC auf jeden Fall enabled sein.
+ // Recalc fuer das Doc war mal wegen #29898# disabled, wenn AutoCalc an war,
+ // ist jetzt wegen #41540# aber auch immer enabled.
+// case FID_RECALC:
+// if ( aDocument.GetAutoCalc() )
+// rSet.DisableItem( nWhich );
+// break;
+
+ case SID_TABLES_COUNT:
+ rSet.Put( SfxInt16Item( nWhich, aDocument.GetTableCount() ) );
+ break;
+
+ case SID_ATTR_YEAR2000 :
+ rSet.Put( SfxUInt16Item( nWhich,
+ aDocument.GetDocOptions().GetYear2000() ) );
+ break;
+
+ case SID_SHARE_DOC:
+ {
+ if ( IsReadOnly() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScDocShell::GetSbxState( SfxItemSet &rSet )
+{
+ // SID_SC_SELECTION (Selection),
+ // SID_SC_ACTIVECELL (ActiveCell),
+ // SID_SC_ACTIVETAB (ActiveTable),
+ // SID_TABLES_GET (Tables),
+ // SID_PIVOT_GET (DataPilotTables) - removed (old Basic)
+
+ //
+ // Wenn hier Slots von der View-Shell executed werden, muss auch der
+ // GetState weitergeleitet werden!
+ //
+
+ ScTabViewShell* pVisibleSh = GetBestViewShell(); // sichtbare View
+ if ( pVisibleSh )
+ pVisibleSh->GetState( rSet );
+}
+
+void __EXPORT ScDocShell::Draw( OutputDevice* pDev, const JobSetup & /* rSetup */, USHORT nAspect )
+{
+// bIsOle = TRUE; // jetzt ueber den CreateMode
+
+ SCTAB nVisTab = aDocument.GetVisibleTab();
+ if (!aDocument.HasTable(nVisTab))
+ return;
+
+ ULONG nOldLayoutMode = pDev->GetLayoutMode();
+ pDev->SetLayoutMode( TEXT_LAYOUT_DEFAULT ); // even if it's the same, to get the metafile action
+
+ if ( nAspect == ASPECT_THUMBNAIL )
+ {
+ Rectangle aBoundRect = GetVisArea( ASPECT_THUMBNAIL );
+ ScViewData aTmpData( this, NULL );
+ aTmpData.SetTabNo(nVisTab);
+ aDocument.SnapVisArea( aBoundRect );
+ aTmpData.SetScreen( aBoundRect );
+ ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, TRUE );
+ }
+ else
+ {
+ Rectangle aBoundRect = SfxObjectShell::GetVisArea();
+ ScViewData aTmpData( this, NULL );
+ aTmpData.SetTabNo(nVisTab);
+ aDocument.SnapVisArea( aBoundRect );
+ aTmpData.SetScreen( aBoundRect );
+ ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, TRUE );
+ }
+
+ pDev->SetLayoutMode( nOldLayoutMode );
+}
+
+Rectangle __EXPORT ScDocShell::GetVisArea( USHORT nAspect ) const
+{
+ SfxObjectCreateMode eShellMode = GetCreateMode();
+ if ( eShellMode == SFX_CREATE_MODE_ORGANIZER )
+ {
+ // ohne Inhalte wissen wir auch nicht, wie gross die Inhalte sind
+ // leeres Rechteck zurueckgeben, das wird dann nach dem Laden berechnet
+ return Rectangle();
+ }
+
+ if( nAspect == ASPECT_THUMBNAIL )
+ {
+// Rectangle aArea( 0,0, 3175,3175 ); // 120x120 Pixel in 1:1
+ Rectangle aArea( 0,0, SC_PREVIEW_SIZE_X,SC_PREVIEW_SIZE_Y );
+ BOOL bNegativePage = aDocument.IsNegativePage( aDocument.GetVisibleTab() );
+ if ( bNegativePage )
+ ScDrawLayer::MirrorRectRTL( aArea );
+ aDocument.SnapVisArea( aArea );
+ return aArea;
+ }
+ else if( nAspect == ASPECT_CONTENT && eShellMode != SFX_CREATE_MODE_EMBEDDED )
+ {
+ // Visarea holen wie nach Load
+
+ SCTAB nVisTab = aDocument.GetVisibleTab();
+ if (!aDocument.HasTable(nVisTab))
+ {
+ nVisTab = 0;
+ ((ScDocShell*)this)->aDocument.SetVisibleTab(nVisTab);
+ }
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ aDocument.GetDataStart( nVisTab, nStartCol, nStartRow );
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aDocument.GetPrintArea( nVisTab, nEndCol, nEndRow );
+ if (nStartCol>nEndCol)
+ nStartCol = nEndCol;
+ if (nStartRow>nEndRow)
+ nStartRow = nEndRow;
+ Rectangle aNewArea = ((ScDocument&)aDocument)
+ .GetMMRect( nStartCol,nStartRow, nEndCol,nEndRow, nVisTab );
+ //TODO/LATER: different methods for setting VisArea?!
+ ((ScDocShell*)this)->SfxObjectShell::SetVisArea( aNewArea );
+ return aNewArea;
+ }
+ else
+ return SfxObjectShell::GetVisArea( nAspect );
+}
+
+void ScDocShell::GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet,
+ SCTAB nCurTab,
+ BOOL& rbHeader,
+ BOOL& rbFooter )
+{
+ if ( !pStyleSet )
+ {
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->
+ Find( aDocument.GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ pStyleSet = &pStyleSheet->GetItemSet();
+ else
+ rbHeader = rbFooter = FALSE;
+ }
+
+ DBG_ASSERT( pStyleSet, "PageStyle-Set not found! :-(" );
+
+ //--------------------------------------------------------------------
+
+ const SvxSetItem* pSetItem = NULL;
+ const SfxItemSet* pSet = NULL;
+
+ pSetItem = (const SvxSetItem*) &pStyleSet->Get( ATTR_PAGE_HEADERSET );
+ pSet = &pSetItem->GetItemSet();
+ rbHeader = ((const SfxBoolItem&)pSet->Get(ATTR_PAGE_ON)).GetValue();
+
+ pSetItem = (const SvxSetItem*) &pStyleSet->Get( ATTR_PAGE_FOOTERSET );
+ pSet = &pSetItem->GetItemSet();
+ rbFooter = ((const SfxBoolItem&)pSet->Get(ATTR_PAGE_ON)).GetValue();
+}
+
+long __EXPORT ScDocShell::DdeGetData( const String& rItem,
+ const String& rMimeType,
+ ::com::sun::star::uno::Any & rValue )
+{
+ if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ) )
+ {
+ if( rItem.EqualsIgnoreCaseAscii( "Format" ) )
+ {
+ ByteString aFmtByte( aDdeTextFmt, gsl_getSystemTextEncoding() );
+ rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
+ (sal_Int8*)aFmtByte.GetBuffer(),
+ aFmtByte.Len() + 1 );
+ return 1;
+ }
+ ScImportExport aObj( &aDocument, rItem );
+ if ( !aObj.IsRef() )
+ return 0; // ungueltiger Bereich
+
+ if( aDdeTextFmt.GetChar(0) == 'F' )
+ aObj.SetFormulas( TRUE );
+ if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
+ aDdeTextFmt.EqualsAscii( "FSYLK" ) )
+ {
+ ByteString aData;
+ if( aObj.ExportByteString( aData, gsl_getSystemTextEncoding(),
+ SOT_FORMATSTR_ID_SYLK ) )
+ {
+ rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
+ (sal_Int8*)aData.GetBuffer(),
+ aData.Len() + 1 );
+ return 1;
+ }
+ else
+ return 0;
+ }
+ if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
+ aDdeTextFmt.EqualsAscii( "FCSV" ) )
+ aObj.SetSeparator( ',' );
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) );
+ return aObj.ExportData( rMimeType, rValue ) ? 1 : 0;
+ }
+
+ ScImportExport aObj( &aDocument, rItem );
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) );
+ if( aObj.IsRef() )
+ return aObj.ExportData( rMimeType, rValue ) ? 1 : 0;
+ return 0;
+}
+
+long __EXPORT ScDocShell::DdeSetData( const String& rItem,
+ const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue )
+{
+ if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ))
+ {
+ if( rItem.EqualsIgnoreCaseAscii( "Format" ) )
+ {
+ if ( ScByteSequenceToString::GetString( aDdeTextFmt, rValue, gsl_getSystemTextEncoding() ) )
+ {
+ aDdeTextFmt.ToUpperAscii();
+ return 1;
+ }
+ return 0;
+ }
+ ScImportExport aObj( &aDocument, rItem );
+ if( aDdeTextFmt.GetChar(0) == 'F' )
+ aObj.SetFormulas( TRUE );
+ if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
+ aDdeTextFmt.EqualsAscii( "FSYLK" ) )
+ {
+ String aData;
+ if ( ScByteSequenceToString::GetString( aData, rValue, gsl_getSystemTextEncoding() ) )
+ {
+ return aObj.ImportString( aData, SOT_FORMATSTR_ID_SYLK ) ? 1 : 0;
+ }
+ return 0;
+ }
+ if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
+ aDdeTextFmt.EqualsAscii( "FCSV" ) )
+ aObj.SetSeparator( ',' );
+ return aObj.ImportData( rMimeType, rValue ) ? 1 : 0;
+ }
+ ScImportExport aObj( &aDocument, rItem );
+ if( aObj.IsRef() )
+ return aObj.ImportData( rMimeType, rValue ) ? 1 : 0;
+ return 0;
+}
+
+::sfx2::SvLinkSource* __EXPORT ScDocShell::DdeCreateLinkSource( const String& rItem )
+{
+ // only check for valid item string - range is parsed again in ScServerObject ctor
+
+ // named range?
+ String aPos = rItem;
+ ScRangeName* pRange = aDocument.GetRangeName();
+ if( pRange )
+ {
+ USHORT nPos;
+ if( pRange->SearchName( aPos, nPos ) )
+ {
+ ScRangeData* pData = (*pRange)[ nPos ];
+ if( pData->HasType( RT_REFAREA )
+ || pData->HasType( RT_ABSAREA )
+ || pData->HasType( RT_ABSPOS ) )
+ 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;
+ 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 )
+ pObj = new ScServerObject( this, rItem );
+
+ // GetLinkManager()->InsertServer() is in the ScServerObject ctor
+
+ return pObj;
+}
+
+//------------------------------------------------------------------
+
+ScViewData* ScDocShell::GetViewData()
+{
+ SfxViewShell* pCur = SfxViewShell::Current();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,pCur);
+ return pViewSh ? pViewSh->GetViewData() : NULL;
+}
+
+//------------------------------------------------------------------
+
+SCTAB ScDocShell::GetCurTab()
+{
+ //! this must be made non-static and use a ViewShell from this document!
+
+ ScViewData* pViewData = GetViewData();
+
+ return pViewData ? pViewData->GetTabNo() : static_cast<SCTAB>(0);
+}
+
+ScTabViewShell* ScDocShell::GetBestViewShell( BOOL bOnlyVisible )
+{
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ // falsches Doc?
+ if( pViewSh && pViewSh->GetViewData()->GetDocShell() != this )
+ pViewSh = NULL;
+ if( !pViewSh )
+ {
+ // 1. ViewShell suchen
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible );
+ if( pFrame )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ pViewSh = PTR_CAST(ScTabViewShell,p);
+ }
+ }
+ return pViewSh;
+}
+
+SfxBindings* ScDocShell::GetViewBindings()
+{
+ // used to invalidate slots after changes to this document
+
+ SfxViewShell* pViewSh = GetBestViewShell();
+ if (pViewSh)
+ return &pViewSh->GetViewFrame()->GetBindings();
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------
+
+ScDocShell* ScDocShell::GetShellByNum( USHORT nDocNo ) // static
+{
+ ScDocShell* pFound = NULL;
+ SfxObjectShell* pShell = SfxObjectShell::GetFirst();
+ USHORT nShellCnt = 0;
+
+ while ( pShell && !pFound )
+ {
+ if ( pShell->Type() == TYPE(ScDocShell) )
+ {
+ if ( nShellCnt == nDocNo )
+ pFound = (ScDocShell*) pShell;
+ else
+ ++nShellCnt;
+ }
+ pShell = SfxObjectShell::GetNext( *pShell );
+ }
+
+ return pFound;
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScDocShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
+{
+ DBG_ASSERT( _pFileDlg, "ScDocShell::DialogClosedHdl(): no file dialog" );
+ DBG_ASSERT( pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" );
+
+ if ( ERRCODE_NONE == _pFileDlg->GetError() )
+ {
+ USHORT nSlot = pImpl->pRequest->GetSlot();
+ SfxMedium* pMed = pImpl->pDocInserter->CreateMedium();
+ // #i87094# If a .odt was selected pMed is NULL.
+ if (pMed)
+ {
+ pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_NAME, pMed->GetName() ) );
+ if ( SID_DOCUMENT_COMPARE == nSlot )
+ {
+ if ( pMed->GetFilter() )
+ pImpl->pRequest->AppendItem(
+ SfxStringItem( SID_FILTER_NAME, pMed->GetFilter()->GetFilterName() ) );
+ String sOptions = ScDocumentLoader::GetOptions( *pMed );
+ if ( sOptions.Len() > 0 )
+ pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, sOptions ) );
+ }
+ const SfxPoolItem* pItem = NULL;
+ SfxItemSet* pSet = pMed->GetItemSet();
+ if ( pSet &&
+ pSet->GetItemState( SID_VERSION, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SfxInt16Item ) )
+ {
+ pImpl->pRequest->AppendItem( *pItem );
+ }
+
+ Execute( *(pImpl->pRequest) );
+ }
+ }
+
+ pImpl->bIgnoreLostRedliningWarning = false;
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::EnableSharedSettings( bool bEnable )
+{
+ SetDocumentModified();
+
+ if ( bEnable )
+ {
+ aDocument.EndChangeTracking();
+ aDocument.StartChangeTracking();
+
+ // hide accept or reject changes dialog
+ USHORT nId = ScAcceptChgDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame && pViewFrame->HasChildWindow( nId ) )
+ {
+ pViewFrame->ToggleChildWindow( nId );
+ SfxBindings* pBindings = GetViewBindings();
+ if ( pBindings )
+ {
+ pBindings->Invalidate( FID_CHG_ACCEPT );
+ }
+ }
+ }
+ else
+ {
+ aDocument.EndChangeTracking();
+ }
+
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges( FALSE );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+}
+
+uno::Reference< frame::XModel > ScDocShell::LoadSharedDocument()
+{
+ uno::Reference< frame::XModel > xModel;
+ try
+ {
+ SC_MOD()->SetInSharedDocLoading( true );
+ uno::Reference< lang::XMultiServiceFactory > xFactory(
+ ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XComponentLoader > xLoader(
+ xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ),
+ uno::UNO_QUERY_THROW );
+ uno::Sequence < beans::PropertyValue > aArgs( 1 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii( "Hidden" );
+ aArgs[0].Value <<= sal_True;
+
+ if ( GetMedium() )
+ {
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
+ if ( pPasswordItem && pPasswordItem->GetValue().Len() )
+ {
+ aArgs.realloc( 2 );
+ aArgs[1].Name = ::rtl::OUString::createFromAscii( "Password" );
+ aArgs[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() );
+ }
+ }
+
+ xModel.set(
+ xLoader->loadComponentFromURL( GetSharedFileURL(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" ) ), 0, aArgs ),
+ uno::UNO_QUERY_THROW );
+ SC_MOD()->SetInSharedDocLoading( false );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "ScDocShell::LoadSharedDocument(): caught exception\n" );
+ SC_MOD()->SetInSharedDocLoading( false );
+ try
+ {
+ uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
+ xClose->close( sal_True );
+ return uno::Reference< frame::XModel >();
+ }
+ catch ( uno::Exception& )
+ {
+ return uno::Reference< frame::XModel >();
+ }
+ }
+ return xModel;
+}
diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
new file mode 100644
index 000000000000..84979e3dbcdf
--- /dev/null
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -0,0 +1,995 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+
+#include "scitems.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/waitobj.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/smplhint.hxx>
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "docsh.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "undodat.hxx"
+#include "undotab.hxx"
+#include "undoblk.hxx"
+//#include "pivot.hxx"
+#include "dpobject.hxx"
+#include "dpshttab.hxx"
+#include "dbdocfun.hxx"
+#include "consoli.hxx"
+#include "dbcolect.hxx"
+#include "olinetab.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "docpool.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "waitoff.hxx"
+#include "sizedev.hxx"
+#include <basic/sbstar.hxx>
+#include <basic/basmgr.hxx>
+
+// defined in docfunc.cxx
+void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource );
+
+// ---------------------------------------------------------------------------
+
+//
+// ehemalige viewfunc/dbfunc Methoden
+//
+
+void ScDocShell::ErrorMessage( USHORT nGlobStrId )
+{
+ //! StopMarking an der (aktiven) View?
+
+ Window* pParent = GetActiveDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ BOOL bFocus = pParent && pParent->HasFocus();
+
+ if(nGlobStrId==STR_PROTECTIONERR)
+ {
+ if(IsReadOnly())
+ {
+ nGlobStrId=STR_READONLYERR;
+ }
+ }
+
+ InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
+ aBox.Execute();
+ if (bFocus)
+ pParent->GrabFocus();
+}
+
+BOOL ScDocShell::IsEditable() const
+{
+ // import into read-only document is possible - must be extended if other filters use api
+ // #i108547# MSOOXML filter uses "IsChangeReadOnlyEnabled" property
+
+ return !IsReadOnly() || aDocument.IsImportingXML() || aDocument.IsChangeReadOnlyEnabled();
+}
+
+void ScDocShell::DBAreaDeleted( SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW /* nY2 */ )
+{
+ ScDocShellModificator aModificator( *this );
+ aDocument.RemoveFlagsTab( nX1, nY1, nX2, nY1, nTab, SC_MF_AUTO );
+ PostPaint( nX1, nY1, nTab, nX2, nY1, nTab, PAINT_GRID );
+ // No SetDocumentModified, as the unnamed database range might have to be restored later.
+ // The UNO hint is broadcast directly instead, to keep UNO objects in valid state.
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+}
+
+ScDBData* lcl_GetDBNearCursor( ScDBCollection* pColl, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ //! nach document/dbcolect verschieben
+
+ if (!pColl)
+ return NULL;
+
+ ScDBData* pNoNameData = NULL;
+ ScDBData* pNearData = NULL;
+ USHORT nCount = pColl->GetCount();
+ String aNoName = ScGlobal::GetRscString( STR_DB_NONAME );
+ SCTAB nAreaTab;
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ for (USHORT i = 0; i < nCount; i++)
+ {
+ ScDBData* pDB = (*pColl)[i];
+ pDB->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ if ( nTab == nAreaTab && nCol+1 >= nStartCol && nCol <= nEndCol+1 &&
+ nRow+1 >= nStartRow && nRow <= nEndRow+1 )
+ {
+ if ( pDB->GetName() == aNoName )
+ pNoNameData = pDB;
+ else if ( nCol < nStartCol || nCol > nEndCol || nRow < nStartRow || nRow > nEndRow )
+ {
+ if (!pNearData)
+ pNearData = pDB; // ersten angrenzenden Bereich merken
+ }
+ else
+ return pDB; // nicht "unbenannt" und Cursor steht wirklich drin
+ }
+ }
+ if (pNearData)
+ return pNearData; // angrenzender, wenn nichts direkt getroffen
+ return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden
+}
+
+ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGetDBSelection eSel )
+{
+ SCCOL nCol = rMarked.aStart.Col();
+ SCROW nRow = rMarked.aStart.Row();
+ SCTAB nTab = rMarked.aStart.Tab();
+
+ SCCOL nStartCol = nCol;
+ SCROW nStartRow = nRow;
+ SCTAB nStartTab = nTab;
+ SCCOL nEndCol = rMarked.aEnd.Col();
+ SCROW nEndRow = rMarked.aEnd.Row();
+ SCTAB nEndTab = rMarked.aEnd.Tab();
+
+ // Wegen #49655# nicht einfach GetDBAtCursor: Der zusammenhaengende Datenbereich
+ // fuer "unbenannt" (GetDataArea) kann neben dem Cursor legen, also muss auch ein
+ // benannter DB-Bereich dort gesucht werden.
+
+ ScDBData* pData = aDocument.GetDBAtArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ if (!pData)
+ pData = lcl_GetDBNearCursor( aDocument.GetDBCollection(), nCol, nRow, nTab );
+
+ BOOL bSelected = ( eSel == SC_DBSEL_FORCE_MARK ||
+ (rMarked.aStart != rMarked.aEnd && eSel != SC_DBSEL_ROW_DOWN) );
+ bool bOnlyDown = (!bSelected && eSel == SC_DBSEL_ROW_DOWN && rMarked.aStart.Row() == rMarked.aEnd.Row());
+
+ BOOL bUseThis = FALSE;
+ if (pData)
+ {
+ // Bereich nehmen, wenn nichts anderes markiert
+
+ SCTAB nDummy;
+ SCCOL nOldCol1;
+ SCROW nOldRow1;
+ SCCOL nOldCol2;
+ SCROW nOldRow2;
+ pData->GetArea( nDummy, nOldCol1,nOldRow1, nOldCol2,nOldRow2 );
+ BOOL bIsNoName = ( pData->GetName() == ScGlobal::GetRscString( STR_DB_NONAME ) );
+
+ if (!bSelected)
+ {
+ bUseThis = TRUE;
+ if ( bIsNoName && eMode == SC_DB_MAKE )
+ {
+ // If nothing marked or only one row marked, adapt
+ // "unbenannt"/"unnamed" to contiguous area.
+ nStartCol = nCol;
+ nStartRow = nRow;
+ if (bOnlyDown)
+ {
+ nEndCol = rMarked.aEnd.Col();
+ nEndRow = rMarked.aEnd.Row();
+ }
+ else
+ {
+ nEndCol = nStartCol;
+ nEndRow = nStartRow;
+ }
+ aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, bOnlyDown );
+ if ( nOldCol1 != nStartCol || nOldCol2 != nEndCol || nOldRow1 != nStartRow )
+ bUseThis = FALSE; // passt gar nicht
+ else if ( nOldRow2 != nEndRow )
+ {
+ // Bereich auf neue End-Zeile erweitern
+ pData->SetArea( nTab, nOldCol1,nOldRow1, nOldCol2,nEndRow );
+ }
+ }
+ }
+ else
+ {
+ if ( nOldCol1 == nStartCol && nOldRow1 == nStartRow &&
+ nOldCol2 == nEndCol && nOldRow2 == nEndRow ) // genau markiert?
+ bUseThis = TRUE;
+ else
+ bUseThis = FALSE; // immer Markierung nehmen (Bug 11964)
+ }
+
+ // fuer Import nie "unbenannt" nehmen
+
+ if ( bUseThis && eMode == SC_DB_IMPORT && bIsNoName )
+ bUseThis = FALSE;
+ }
+
+ if ( bUseThis )
+ {
+ pData->GetArea( nStartTab, nStartCol,nStartRow, nEndCol,nEndRow );
+ nEndTab = nStartTab;
+ }
+ else if ( eMode == SC_DB_OLD )
+ {
+ pData = NULL; // nichts gefunden
+ nStartCol = nEndCol = nCol;
+ nStartRow = nEndRow = nRow;
+ nStartTab = nEndTab = nTab;
+// bMark = FALSE; // nichts zu markieren
+ }
+ else
+ {
+ if ( bSelected )
+ {
+// bMark = FALSE;
+ }
+ else
+ { // zusammenhaengender Bereich
+ nStartCol = nCol;
+ nStartRow = nRow;
+ if (bOnlyDown)
+ {
+ nEndCol = rMarked.aEnd.Col();
+ nEndRow = rMarked.aEnd.Row();
+ }
+ else
+ {
+ nEndCol = nStartCol;
+ nEndRow = nStartRow;
+ }
+ aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, bOnlyDown );
+ }
+
+ BOOL bHasHeader = aDocument.HasColHeader( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
+
+ ScDBData* pNoNameData;
+ USHORT nNoNameIndex;
+ ScDBCollection* pColl = aDocument.GetDBCollection();
+ if ( eMode != SC_DB_IMPORT &&
+ pColl->SearchName( ScGlobal::GetRscString( STR_DB_NONAME ), nNoNameIndex ) )
+ {
+ pNoNameData = (*pColl)[nNoNameIndex];
+
+ if ( !pOldAutoDBRange )
+ {
+ // store the old unnamed database range with its settings for undo
+ // (store at the first change, get the state before all changes)
+ pOldAutoDBRange = new ScDBData( *pNoNameData );
+ }
+
+ SCCOL nOldX1; // alten Bereich sauber wegnehmen
+ SCROW nOldY1; //! (UNDO ???)
+ SCCOL nOldX2;
+ SCROW nOldY2;
+ SCTAB nOldTab;
+ pNoNameData->GetArea( nOldTab, nOldX1, nOldY1, nOldX2, nOldY2 );
+ DBAreaDeleted( nOldTab, nOldX1, nOldY1, nOldX2, nOldY2 );
+
+ pNoNameData->SetSortParam( ScSortParam() ); // Parameter zuruecksetzen
+ pNoNameData->SetQueryParam( ScQueryParam() );
+ pNoNameData->SetSubTotalParam( ScSubTotalParam() );
+
+ pNoNameData->SetArea( nTab, nStartCol,nStartRow, nEndCol,nEndRow ); // neu setzen
+ pNoNameData->SetByRow( TRUE );
+ pNoNameData->SetHeader( bHasHeader );
+ pNoNameData->SetAutoFilter( FALSE );
+ }
+ else
+ {
+ ScDBCollection* pUndoColl = NULL;
+
+ String aNewName;
+ if (eMode==SC_DB_IMPORT)
+ {
+ aDocument.CompileDBFormula( TRUE ); // CreateFormulaString
+ pUndoColl = new ScDBCollection( *pColl ); // Undo fuer Import1-Bereich
+
+ String aImport = ScGlobal::GetRscString( STR_DBNAME_IMPORT );
+ long nCount = 0;
+ USHORT nDummy;
+ do
+ {
+ ++nCount;
+ aNewName = aImport;
+ aNewName += String::CreateFromInt32( nCount );
+ }
+ while (pColl->SearchName( aNewName, nDummy ));
+ }
+ else
+ aNewName = ScGlobal::GetRscString( STR_DB_NONAME );
+ pNoNameData = new ScDBData( aNewName, nTab,
+ nStartCol,nStartRow, nEndCol,nEndRow,
+ TRUE, bHasHeader );
+ pColl->Insert( pNoNameData );
+
+ if ( pUndoColl )
+ {
+ aDocument.CompileDBFormula( FALSE ); // CompileFormulaString
+
+ ScDBCollection* pRedoColl = new ScDBCollection( *pColl );
+ GetUndoManager()->AddUndoAction( new ScUndoDBData( this, pUndoColl, pRedoColl ) );
+ }
+
+ // neuen Bereich am Sba anmelden nicht mehr noetig
+
+ // "Import1" etc am Navigator bekanntmachen
+ if (eMode==SC_DB_IMPORT)
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ }
+ pData = pNoNameData;
+ }
+
+// if (bMark)
+// MarkRange( ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ), FALSE );
+
+ return pData;
+}
+
+ScDBData* ScDocShell::GetOldAutoDBRange()
+{
+ ScDBData* pRet = pOldAutoDBRange;
+ pOldAutoDBRange = NULL;
+ return pRet; // has to be deleted by caller!
+}
+
+void ScDocShell::CancelAutoDBRange()
+{
+ // called when dialog is cancelled
+ if ( pOldAutoDBRange )
+ {
+ USHORT nNoNameIndex;
+ ScDBCollection* pColl = aDocument.GetDBCollection();
+ if ( pColl->SearchName( ScGlobal::GetRscString( STR_DB_NONAME ), nNoNameIndex ) )
+ {
+ ScDBData* pNoNameData = (*pColl)[nNoNameIndex];
+
+ SCCOL nRangeX1;
+ SCROW nRangeY1;
+ SCCOL nRangeX2;
+ SCROW nRangeY2;
+ SCTAB nRangeTab;
+ pNoNameData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+ DBAreaDeleted( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+
+ *pNoNameData = *pOldAutoDBRange; // restore old settings
+
+ if ( pOldAutoDBRange->HasAutoFilter() )
+ {
+ // restore AutoFilter buttons
+ pOldAutoDBRange->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+ aDocument.ApplyFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, SC_MF_AUTO );
+ PostPaint( nRangeX1, nRangeY1, nRangeTab, nRangeX2, nRangeY1, nRangeTab, PAINT_GRID );
+ }
+ }
+
+ delete pOldAutoDBRange;
+ pOldAutoDBRange = NULL;
+ }
+}
+
+
+ // Hoehen anpassen
+ //! mit docfunc zusammenfassen
+
+BOOL ScDocShell::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab )
+{
+ ScSizeDeviceProvider aProv(this);
+ Fraction aZoom(1,1);
+ BOOL bChange = aDocument.SetOptimalHeight( nStartRow,nEndRow, nTab, 0, aProv.GetDevice(),
+ aProv.GetPPTX(),aProv.GetPPTY(), aZoom,aZoom, FALSE );
+ if (bChange)
+ PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID|PAINT_LEFT );
+
+ return bChange;
+}
+
+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, pTabMark );
+}
+
+void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore )
+{
+ BOOL bIsUndoEnabled = aDocument.IsUndoEnabled();
+ aDocument.EnableUndo( FALSE );
+ aDocument.LockStreamValid( true ); // ignore draw page size (but not formula results)
+ 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.LockStreamValid( false );
+ aDocument.EnableUndo( bIsUndoEnabled );
+}
+
+void ScDocShell::RefreshPivotTables( const ScRange& rSource )
+{
+ //! rename to RefreshDataPilotTables?
+
+ ScDPCollection* pColl = aDocument.GetDPCollection();
+ if ( pColl )
+ {
+ // DataPilotUpdate doesn't modify the collection order like PivotUpdate did,
+ // so a simple loop can be used.
+
+ USHORT nCount = pColl->GetCount();
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ ScDPObject* pOld = (*pColl)[i];
+ if ( pOld )
+ {
+ const ScSheetSourceDesc* pSheetDesc = pOld->GetSheetDesc();
+ if ( pSheetDesc && pSheetDesc->aSourceRange.Intersects( rSource ) )
+ {
+ ScDPObject* pNew = new ScDPObject( *pOld );
+ ScDBDocFunc aFunc( *this );
+ aFunc.DataPilotUpdate( pOld, pNew, TRUE, FALSE );
+ delete pNew; // DataPilotUpdate copies settings from "new" object
+ }
+ }
+ }
+ }
+}
+
+String lcl_GetAreaName( ScDocument* pDoc, ScArea* pArea )
+{
+ String aName;
+ BOOL bOk = FALSE;
+ ScDBData* pData = pDoc->GetDBAtArea( pArea->nTab, pArea->nColStart, pArea->nRowStart,
+ pArea->nColEnd, pArea->nRowEnd );
+ if (pData)
+ {
+ pData->GetName( aName );
+ if ( aName != ScGlobal::GetRscString( STR_DB_NONAME ) )
+ bOk = TRUE;
+ }
+
+ if (!bOk)
+ pDoc->GetName( pArea->nTab, aName );
+
+ return aName;
+}
+
+void ScDocShell::DoConsolidate( const ScConsolidateParam& rParam, BOOL bRecord )
+{
+ ScConsData aData;
+
+ USHORT nPos;
+ SCCOL nColSize = 0;
+ SCROW nRowSize = 0;
+ BOOL bErr = FALSE;
+ for (nPos=0; nPos<rParam.nDataAreaCount; nPos++)
+ {
+ ScArea* pArea = rParam.ppDataAreas[nPos];
+ nColSize = Max( nColSize, SCCOL( pArea->nColEnd - pArea->nColStart + 1 ) );
+ nRowSize = Max( nRowSize, SCROW( pArea->nRowEnd - pArea->nRowStart + 1 ) );
+
+ // Test, ob Quelldaten verschoben wuerden
+ if (rParam.bReferenceData)
+ if (pArea->nTab == rParam.nTab && pArea->nRowEnd >= rParam.nRow)
+ bErr = TRUE;
+ }
+
+ if (bErr)
+ {
+ InfoBox aBox( GetActiveDialogParent(),
+ ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1 ) );
+ aBox.Execute();
+ return;
+ }
+
+ // ausfuehren
+
+ WaitObject aWait( GetActiveDialogParent() );
+ ScDocShellModificator aModificator( *this );
+
+ ScRange aOldDest;
+ ScDBData* pDestData = aDocument.GetDBAtCursor( rParam.nCol, rParam.nRow, rParam.nTab, TRUE );
+ if (pDestData)
+ pDestData->GetArea(aOldDest);
+
+ aData.SetSize( nColSize, nRowSize );
+ aData.SetFlags( rParam.eFunction, rParam.bByCol, rParam.bByRow, rParam.bReferenceData );
+ if ( rParam.bByCol || rParam.bByRow )
+ for (nPos=0; nPos<rParam.nDataAreaCount; nPos++)
+ {
+ ScArea* pArea = rParam.ppDataAreas[nPos];
+ aData.AddFields( &aDocument, pArea->nTab, pArea->nColStart, pArea->nRowStart,
+ pArea->nColEnd, pArea->nRowEnd );
+ }
+ aData.DoneFields();
+ for (nPos=0; nPos<rParam.nDataAreaCount; nPos++)
+ {
+ ScArea* pArea = rParam.ppDataAreas[nPos];
+ aData.AddData( &aDocument, pArea->nTab, pArea->nColStart, pArea->nRowStart,
+ pArea->nColEnd, pArea->nRowEnd );
+ aData.AddName( lcl_GetAreaName(&aDocument,pArea) );
+ }
+
+ aData.GetSize( nColSize, nRowSize );
+ if (bRecord && nColSize > 0 && nRowSize > 0)
+ {
+ ScDBData* pUndoData = pDestData ? new ScDBData(*pDestData) : NULL;
+
+ SCTAB nDestTab = rParam.nTab;
+ ScArea aDestArea( rParam.nTab, rParam.nCol, rParam.nRow,
+ rParam.nCol+nColSize-1, rParam.nRow+nRowSize-1 );
+ if (rParam.bByCol) ++aDestArea.nColEnd;
+ if (rParam.bByRow) ++aDestArea.nRowEnd;
+
+ if (rParam.bReferenceData)
+ {
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCROW nInsertCount = aData.GetInsertCount();
+
+ // alte Outlines
+ ScOutlineTable* pTable = aDocument.GetOutlineTable( nDestTab );
+ ScOutlineTable* pUndoTab = pTable ? new ScOutlineTable( *pTable ) : NULL;
+
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( &aDocument, 0, nTabCount-1, FALSE, TRUE );
+
+ // Zeilenstatus
+ aDocument.CopyToDocument( 0,0,nDestTab, MAXCOL,MAXROW,nDestTab,
+ IDF_NONE, FALSE, pUndoDoc );
+
+ // alle Formeln
+ aDocument.CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
+ IDF_FORMULA, FALSE, pUndoDoc );
+
+ // komplette Ausgangszeilen
+ aDocument.CopyToDocument( 0,aDestArea.nRowStart,nDestTab,
+ MAXCOL,aDestArea.nRowEnd,nDestTab,
+ IDF_ALL, FALSE, pUndoDoc );
+
+ // alten Ausgabebereich
+ if (pDestData)
+ aDocument.CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc );
+
+ GetUndoManager()->AddUndoAction(
+ new ScUndoConsolidate( this, aDestArea, rParam, pUndoDoc,
+ TRUE, nInsertCount, pUndoTab, pUndoData ) );
+ }
+ else
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( &aDocument, aDestArea.nTab, aDestArea.nTab );
+
+ aDocument.CopyToDocument( aDestArea.nColStart, aDestArea.nRowStart, aDestArea.nTab,
+ aDestArea.nColEnd, aDestArea.nRowEnd, aDestArea.nTab,
+ IDF_ALL, FALSE, pUndoDoc );
+
+ // alten Ausgabebereich
+ if (pDestData)
+ aDocument.CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc );
+
+ GetUndoManager()->AddUndoAction(
+ new ScUndoConsolidate( this, aDestArea, rParam, pUndoDoc,
+ FALSE, 0, NULL, pUndoData ) );
+ }
+ }
+
+ if (pDestData) // Zielbereich loeschen / anpassen
+ {
+ aDocument.DeleteAreaTab(aOldDest, IDF_CONTENTS);
+ pDestData->SetArea( rParam.nTab, rParam.nCol, rParam.nRow,
+ rParam.nCol + nColSize - 1, rParam.nRow + nRowSize - 1 );
+ pDestData->SetHeader( rParam.bByRow );
+ }
+
+ aData.OutputToDocument( &aDocument, rParam.nCol, rParam.nRow, rParam.nTab );
+
+ SCCOL nPaintStartCol = rParam.nCol;
+ SCROW nPaintStartRow = rParam.nRow;
+ SCCOL nPaintEndCol = nPaintStartCol + nColSize - 1;
+ SCROW nPaintEndRow = nPaintStartRow + nRowSize - 1;
+ USHORT nPaintFlags = PAINT_GRID;
+ if (rParam.bByCol)
+ ++nPaintEndRow;
+ if (rParam.bByRow)
+ ++nPaintEndCol;
+ if (rParam.bReferenceData)
+ {
+ nPaintStartCol = 0;
+ nPaintEndCol = MAXCOL;
+ nPaintEndRow = MAXROW;
+ nPaintFlags |= PAINT_LEFT | PAINT_SIZE;
+ }
+ if (pDestData)
+ {
+ if ( aOldDest.aEnd.Col() > nPaintEndCol )
+ nPaintEndCol = aOldDest.aEnd.Col();
+ if ( aOldDest.aEnd.Row() > nPaintEndRow )
+ nPaintEndRow = aOldDest.aEnd.Row();
+ }
+ PostPaint( nPaintStartCol, nPaintStartRow, rParam.nTab,
+ nPaintEndCol, nPaintEndRow, rParam.nTab, nPaintFlags );
+ aModificator.SetDocumentModified();
+}
+
+void ScDocShell::UseScenario( SCTAB nTab, const String& rName, BOOL bRecord )
+{
+ if (!aDocument.IsScenario(nTab))
+ {
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nSrcTab = SCTAB_MAX;
+ SCTAB nEndTab = nTab;
+ String aCompare;
+ while ( nEndTab+1 < nTabCount && aDocument.IsScenario(nEndTab+1) )
+ {
+ ++nEndTab;
+ if (nSrcTab > MAXTAB) // noch auf der Suche nach dem Szenario?
+ {
+ aDocument.GetName( nEndTab, aCompare );
+ if (aCompare == rName)
+ nSrcTab = nEndTab; // gefunden
+ }
+ }
+ if (ValidTab(nSrcTab))
+ {
+ if ( aDocument.TestCopyScenario( nSrcTab, nTab ) ) // Zellschutz testen
+ {
+ ScDocShellModificator aModificator( *this );
+ ScMarkData aScenMark;
+ aDocument.MarkScenario( nSrcTab, nTab, aScenMark );
+ ScRange aMultiRange;
+ aScenMark.GetMultiMarkArea( aMultiRange );
+ SCCOL nStartCol = aMultiRange.aStart.Col();
+ SCROW nStartRow = aMultiRange.aStart.Row();
+ SCCOL nEndCol = aMultiRange.aEnd.Col();
+ SCROW nEndRow = aMultiRange.aEnd.Row();
+
+ if (bRecord)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( &aDocument, nTab,nEndTab ); // auch alle Szenarien
+ // angezeigte Tabelle:
+ aDocument.CopyToDocument( nStartCol,nStartRow,nTab,
+ nEndCol,nEndRow,nTab, IDF_ALL,TRUE, pUndoDoc, &aScenMark );
+ // Szenarien
+ for (SCTAB i=nTab+1; i<=nEndTab; i++)
+ {
+ pUndoDoc->SetScenario( i, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ aDocument.GetScenarioData( i, aComment, aColor, nScenFlags );
+ pUndoDoc->SetScenarioData( i, aComment, aColor, nScenFlags );
+ BOOL bActive = aDocument.IsActiveScenario( i );
+ pUndoDoc->SetActiveScenario( i, bActive );
+ // Bei Zurueckkopier-Szenarios auch Inhalte
+ if ( nScenFlags & SC_SCENARIO_TWOWAY )
+ aDocument.CopyToDocument( 0,0,i, MAXCOL,MAXROW,i,
+ IDF_ALL,FALSE, pUndoDoc );
+ }
+
+ GetUndoManager()->AddUndoAction(
+ new ScUndoUseScenario( this, aScenMark,
+ ScArea( nTab,nStartCol,nStartRow,nEndCol,nEndRow ),
+ pUndoDoc, rName ) );
+ }
+
+ aDocument.CopyScenario( nSrcTab, nTab );
+ aDocument.SetDirty();
+
+ // alles painten, weil in anderen Bereichen das aktive Szenario
+ // geaendert sein kann
+ //! nur, wenn sichtbare Rahmen vorhanden?
+ PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+ aModificator.SetDocumentModified();
+ }
+ else
+ {
+ InfoBox aBox(GetActiveDialogParent(),
+ ScGlobal::GetRscString( STR_PROTECTIONERR ) );
+ aBox.Execute();
+ }
+ }
+ else
+ {
+ InfoBox aBox(GetActiveDialogParent(),
+ ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND ) );
+ aBox.Execute();
+ }
+ }
+ else
+ {
+ DBG_ERROR( "UseScenario auf Szenario-Blatt" );
+ }
+}
+
+void ScDocShell::ModifyScenario( SCTAB nTab, const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags )
+{
+ // Undo
+ String aOldName;
+ aDocument.GetName( nTab, aOldName );
+ String aOldComment;
+ Color aOldColor;
+ USHORT nOldFlags;
+ aDocument.GetScenarioData( nTab, aOldComment, aOldColor, nOldFlags );
+ GetUndoManager()->AddUndoAction(
+ new ScUndoScenarioFlags( this, nTab,
+ aOldName, rName, aOldComment, rComment,
+ aOldColor, rColor, nOldFlags, nFlags ) );
+
+ // ausfuehren
+ ScDocShellModificator aModificator( *this );
+ aDocument.RenameTab( nTab, rName );
+ aDocument.SetScenarioData( nTab, rComment, rColor, nFlags );
+ PostPaintGridAll();
+ aModificator.SetDocumentModified();
+
+ if ( rName != aOldName )
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_SELECT_SCENARIO );
+}
+
+SCTAB ScDocShell::MakeScenario( SCTAB nTab, const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags,
+ ScMarkData& rMark, BOOL bRecord )
+{
+ rMark.MarkToMulti();
+ if (rMark.IsMultiMarked())
+ {
+ SCTAB nNewTab = nTab + 1;
+ while (aDocument.IsScenario(nNewTab))
+ ++nNewTab;
+
+ BOOL bCopyAll = ( (nFlags & SC_SCENARIO_COPYALL) != 0 );
+ const ScMarkData* pCopyMark = NULL;
+ if (!bCopyAll)
+ pCopyMark = &rMark;
+
+ ScDocShellModificator aModificator( *this );
+
+ if (bRecord)
+ aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ if (aDocument.CopyTab( nTab, nNewTab, pCopyMark ))
+ {
+ if (bRecord)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoMakeScenario( this, nTab, nNewTab,
+ rName, rComment, rColor, nFlags, rMark ));
+ }
+
+ aDocument.RenameTab( nNewTab, rName, FALSE ); // ohne Formel-Update
+ aDocument.SetScenario( nNewTab, TRUE );
+ aDocument.SetScenarioData( nNewTab, rComment, rColor, nFlags );
+
+ ScMarkData aDestMark = rMark;
+ aDestMark.SelectOneTable( nNewTab );
+
+ //! auf Filter / Buttons / Merging testen !
+
+ ScPatternAttr aProtPattern( aDocument.GetPool() );
+ aProtPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
+ aDocument.ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nNewTab, aProtPattern );
+
+ ScPatternAttr aPattern( aDocument.GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
+ aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
+ aDocument.ApplySelectionPattern( aPattern, aDestMark );
+
+ if (!bCopyAll)
+ aDocument.SetVisible( nNewTab, FALSE );
+
+ // dies ist dann das aktive Szenario
+ aDocument.CopyScenario( nNewTab, nTab, TRUE ); // TRUE - nicht aus Szenario kopieren
+
+ if (nFlags & SC_SCENARIO_SHOWFRAME)
+ PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); // Rahmen painten
+ PostPaintExtras(); // Tabellenreiter
+ aModificator.SetDocumentModified();
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+
+ return nNewTab;
+ }
+ }
+ return nTab;
+}
+
+BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRecord )
+{
+ ScDocShellModificator aModificator( *this );
+
+ // #i92477# be consistent with ScDocFunc::InsertTable: any index past the last sheet means "append"
+ // #i101139# nDestTab must be the target position, not APPEND (for CopyTabProtection etc.)
+ if ( nDestTab >= aDocument.GetTableCount() )
+ nDestTab = aDocument.GetTableCount();
+
+ if (bCopy)
+ {
+ if (bRecord)
+ aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ String sSrcCodeName;
+ aDocument.GetCodeName( nSrcTab, sSrcCodeName );
+ if (!aDocument.CopyTab( nSrcTab, nDestTab ))
+ {
+ //! EndDrawUndo?
+ return FALSE;
+ }
+ else
+ {
+ SCTAB nAdjSource = nSrcTab;
+ if ( nDestTab <= nSrcTab )
+ ++nAdjSource; // new position of source table after CopyTab
+
+ if ( aDocument.IsTabProtected( nAdjSource ) )
+ aDocument.CopyTabProtection(nAdjSource, nDestTab);
+
+ if (bRecord)
+ {
+ SvShorts aSrcList;
+ SvShorts aDestList;
+ aSrcList.Insert(nSrcTab,0);
+ aDestList.Insert(nDestTab,0);
+ GetUndoManager()->AddUndoAction(
+ new ScUndoCopyTab( this, aSrcList, aDestList ) );
+ }
+
+ BOOL bVbaEnabled = aDocument.IsInVBAMode();
+ if ( bVbaEnabled )
+ {
+ StarBASIC* pStarBASIC = GetBasic();
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( GetBasicManager()->GetName().Len() > 0 )
+ {
+ aLibName = GetBasicManager()->GetName();
+ pStarBASIC = GetBasicManager()->GetLib( aLibName );
+ }
+ SCTAB nTabToUse = nDestTab;
+ if ( nDestTab == SC_TAB_APPEND )
+ nTabToUse = aDocument.GetMaxTableNumber() - 1;
+ String sCodeName;
+ String sSource;
+ com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibContainer = GetBasicContainer();
+ com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xLib;
+ if( xLibContainer.is() )
+ {
+ com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+ if( xLib.is() )
+ {
+ rtl::OUString sRTLSource;
+ xLib->getByName( sSrcCodeName ) >>= sRTLSource;
+ sSource = sRTLSource;
+ }
+ VBA_InsertModule( aDocument, nTabToUse, sCodeName, sSource );
+ }
+ }
+ Broadcast( ScTablesHint( SC_TAB_COPIED, nSrcTab, nDestTab ) );
+ }
+ else
+ {
+ if ( aDocument.GetChangeTrack() )
+ return FALSE;
+
+ if ( nSrcTab<nDestTab && nDestTab!=SC_TAB_APPEND )
+ nDestTab--;
+
+ if ( nSrcTab == nDestTab )
+ {
+ //! allow only for api calls?
+ return TRUE; // nothing to do, but valid
+ }
+
+ if (!aDocument.MoveTab( nSrcTab, nDestTab ))
+ return FALSE;
+ else if (bRecord)
+ {
+ SvShorts aSrcList;
+ SvShorts aDestList;
+ aSrcList.Insert(nSrcTab,0);
+ aDestList.Insert(nDestTab,0);
+ GetUndoManager()->AddUndoAction(
+ new ScUndoMoveTab( this, aSrcList, aDestList ) );
+ }
+
+ Broadcast( ScTablesHint( SC_TAB_MOVED, nSrcTab, nDestTab ) );
+ }
+
+ PostPaintGridAll();
+ PostPaintExtras();
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+
+ return TRUE;
+}
+
+
+IMPL_LINK( ScDocShell, RefreshDBDataHdl, ScRefreshTimer*, pRefreshTimer )
+{
+ ScDBDocFunc aFunc(*this);
+
+ BOOL bContinue = TRUE;
+ ScDBData* pDBData = static_cast<ScDBData*>(pRefreshTimer);
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ if (aImportParam.bImport && !pDBData->HasImportSelection())
+ {
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet> xResultSet;
+ bContinue = aFunc.DoImport( aRange.aStart.Tab(), aImportParam, xResultSet, NULL, TRUE, FALSE ); //! Api-Flag as parameter
+ // internal operations (sort, query, subtotal) only if no error
+ if (bContinue)
+ {
+ aFunc.RepeatDB( pDBData->GetName(), TRUE, TRUE );
+ RefreshPivotTables(aRange);
+ }
+ }
+
+ return bContinue != 0;
+}
+
diff --git a/sc/source/ui/docshell/docsh6.cxx b/sc/source/ui/docshell/docsh6.cxx
new file mode 100644
index 000000000000..fbb6dc8ead35
--- /dev/null
+++ b/sc/source/ui/docshell/docsh6.cxx
@@ -0,0 +1,469 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+#ifndef PCH
+#include "scitems.hxx"
+
+#include <svx/pageitem.hxx>
+#include <vcl/virdev.hxx>
+#include <sfx2/linkmgr.hxx>
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+//#include <svxlink.hxx>
+
+#include "docsh.hxx"
+
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "tablink.hxx"
+#include "collect.hxx"
+
+struct ScStylePair
+{
+ SfxStyleSheetBase *pSource;
+ SfxStyleSheetBase *pDest;
+};
+
+
+// STATIC DATA -----------------------------------------------------------
+
+//----------------------------------------------------------------------
+
+//
+// Ole
+//
+
+void __EXPORT ScDocShell::SetVisArea( const Rectangle & rVisArea )
+{
+ // with the SnapVisArea call in SetVisAreaOrSize, it's safe to always
+ // use both the size and position of the VisArea
+ SetVisAreaOrSize( rVisArea, TRUE );
+}
+
+void lcl_SetTopRight( Rectangle& rRect, const Point& rPos )
+{
+ Size aSize = rRect.GetSize();
+ rRect.Right() = rPos.X();
+ rRect.Left() = rPos.X() - aSize.Width() + 1;
+ rRect.Top() = rPos.Y();
+ rRect.Bottom() = rPos.Y() + aSize.Height() - 1;
+}
+
+void ScDocShell::SetVisAreaOrSize( const Rectangle& rVisArea, BOOL bModifyStart )
+{
+ BOOL bNegativePage = aDocument.IsNegativePage( aDocument.GetVisibleTab() );
+
+ Rectangle aArea = rVisArea;
+ if (bModifyStart)
+ {
+ // when loading, don't check for negative values, because the sheet orientation
+ // might be set later
+ if ( !aDocument.IsImportingXML() )
+ {
+ if ( ( bNegativePage ? (aArea.Right() > 0) : (aArea.Left() < 0) ) || aArea.Top() < 0 )
+ {
+ // VisArea start position can't be negative.
+ // Move the VisArea, otherwise only the upper left position would
+ // be changed in SnapVisArea, and the size would be wrong.
+
+ Point aNewPos( 0, Max( aArea.Top(), (long) 0 ) );
+ if ( bNegativePage )
+ {
+ aNewPos.X() = Min( aArea.Right(), (long) 0 );
+ lcl_SetTopRight( aArea, aNewPos );
+ }
+ else
+ {
+ aNewPos.X() = Max( aArea.Left(), (long) 0 );
+ aArea.SetPos( aNewPos );
+ }
+ }
+ }
+ }
+ else
+ {
+ Rectangle aOldVisArea = SfxObjectShell::GetVisArea();
+ if ( bNegativePage )
+ lcl_SetTopRight( aArea, aOldVisArea.TopRight() );
+ else
+ aArea.SetPos( aOldVisArea.TopLeft() );
+ }
+
+ // hier Position anpassen!
+
+ // #92248# when loading an ole object, the VisArea is set from the document's
+ // view settings and must be used as-is (document content may not be complete yet).
+ if ( !aDocument.IsImportingXML() )
+ aDocument.SnapVisArea( aArea );
+
+ //TODO/LATER: it's unclear which IPEnv is used here
+ /*
+ SvInPlaceEnvironment* pEnv = GetIPEnv();
+ if (pEnv)
+ {
+ Window* pWin = pEnv->GetEditWin();
+ pEnv->MakeScale( aArea.GetSize(), MAP_100TH_MM,
+ pWin->LogicToPixel( aArea.GetSize() ) );
+ } */
+
+ //TODO/LATER: formerly in SvInplaceObject
+ SfxObjectShell::SetVisArea( aArea );
+
+ if (bIsInplace) // Zoom in der InPlace View einstellen
+ {
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if (pViewSh)
+ {
+ if (pViewSh->GetViewData()->GetDocShell() == this)
+ pViewSh->UpdateOleZoom();
+ }
+ //else
+ // DataChanged( SvDataType() ); // fuer Zuppeln wenn nicht IP-aktiv
+ }
+
+ if (aDocument.IsEmbedded())
+ {
+ ScRange aOld;
+ aDocument.GetEmbedded( aOld);
+ aDocument.SetEmbedded( aArea );
+ ScRange aNew;
+ aDocument.GetEmbedded( aNew);
+ if (aOld != aNew)
+ PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_GRID);
+
+ //TODO/LATER: currently not implemented
+ //ViewChanged( ASPECT_CONTENT ); // auch im Container anzeigen
+ }
+}
+
+BOOL ScDocShell::IsOle()
+{
+ return (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
+}
+
+void ScDocShell::UpdateOle( const ScViewData* pViewData, BOOL bSnapSize )
+{
+ // wenn's gar nicht Ole ist, kann man sich die Berechnungen sparen
+ // (VisArea wird dann beim Save wieder zurueckgesetzt)
+
+ if (GetCreateMode() == SFX_CREATE_MODE_STANDARD)
+ return;
+
+ DBG_ASSERT(pViewData,"pViewData==0 bei ScDocShell::UpdateOle");
+
+ Rectangle aOldArea = SfxObjectShell::GetVisArea();
+ Rectangle aNewArea = aOldArea;
+
+ BOOL bChange = FALSE;
+ BOOL bEmbedded = aDocument.IsEmbedded();
+ if (bEmbedded)
+ aNewArea = aDocument.GetEmbeddedRect();
+ else
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( nTab != aDocument.GetVisibleTab() )
+ {
+ aDocument.SetVisibleTab( nTab );
+ bChange = TRUE;
+ }
+
+ BOOL bNegativePage = aDocument.IsNegativePage( nTab );
+ SCCOL nX = pViewData->GetPosX(SC_SPLIT_LEFT);
+ SCROW nY = pViewData->GetPosY(SC_SPLIT_BOTTOM);
+ Rectangle aMMRect = aDocument.GetMMRect( nX,nY, nX,nY, nTab );
+ if (bNegativePage)
+ lcl_SetTopRight( aNewArea, aMMRect.TopRight() );
+ else
+ aNewArea.SetPos( aMMRect.TopLeft() );
+ if (bSnapSize)
+ aDocument.SnapVisArea(aNewArea); // uses the new VisibleTab
+ }
+
+ if (aNewArea != aOldArea)
+ {
+ SetVisAreaOrSize( aNewArea, TRUE ); // hier muss auch der Start angepasst werden
+ bChange = TRUE;
+ }
+
+// if (bChange)
+// DataChanged( SvDataType() ); //! passiert auch bei SetModified
+}
+
+//
+// Style-Krempel fuer Organizer etc.
+//
+
+SfxStyleSheetBasePool* __EXPORT ScDocShell::GetStyleSheetPool()
+{
+ return (SfxStyleSheetBasePool*)aDocument.GetStyleSheetPool();
+}
+
+
+// nach dem Laden von Vorlagen aus einem anderen Dokment (LoadStyles, Insert)
+// muessen die SetItems (ATTR_PAGE_HEADERSET, ATTR_PAGE_FOOTERSET) auf den richtigen
+// Pool umgesetzt werden, bevor der Quell-Pool geloescht wird.
+
+void lcl_AdjustPool( SfxStyleSheetBasePool* pStylePool )
+{
+ pStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, 0xffff);
+ SfxStyleSheetBase *pStyle = pStylePool->First();
+ while ( pStyle )
+ {
+ SfxItemSet& rStyleSet = pStyle->GetItemSet();
+
+ const SfxPoolItem* pItem;
+ if (rStyleSet.GetItemState(ATTR_PAGE_HEADERSET,FALSE,&pItem) == SFX_ITEM_SET)
+ {
+ SfxItemSet& rSrcSet = ((SvxSetItem*)pItem)->GetItemSet();
+ SfxItemSet* pDestSet = new SfxItemSet(*rStyleSet.GetPool(),rSrcSet.GetRanges());
+ pDestSet->Put(rSrcSet);
+ rStyleSet.Put(SvxSetItem(ATTR_PAGE_HEADERSET,pDestSet));
+ }
+ if (rStyleSet.GetItemState(ATTR_PAGE_FOOTERSET,FALSE,&pItem) == SFX_ITEM_SET)
+ {
+ SfxItemSet& rSrcSet = ((SvxSetItem*)pItem)->GetItemSet();
+ SfxItemSet* pDestSet = new SfxItemSet(*rStyleSet.GetPool(),rSrcSet.GetRanges());
+ pDestSet->Put(rSrcSet);
+ rStyleSet.Put(SvxSetItem(ATTR_PAGE_FOOTERSET,pDestSet));
+ }
+
+ pStyle = pStylePool->Next();
+ }
+}
+
+void __EXPORT ScDocShell::LoadStyles( SfxObjectShell &rSource )
+{
+ aDocument.StylesToNames();
+
+ SfxObjectShell::LoadStyles(rSource);
+ lcl_AdjustPool( GetStyleSheetPool() ); // SetItems anpassen
+
+ aDocument.UpdStlShtPtrsFrmNms();
+
+ UpdateAllRowHeights();
+
+ // Paint
+
+ PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID | PAINT_LEFT );
+}
+
+void ScDocShell::LoadStylesArgs( ScDocShell& rSource, BOOL bReplace, BOOL bCellStyles, BOOL bPageStyles )
+{
+ // similar to LoadStyles, but with selectable behavior for XStyleLoader::loadStylesFromURL call
+
+ if ( !bCellStyles && !bPageStyles ) // nothing to do
+ return;
+
+ ScStyleSheetPool* pSourcePool = rSource.GetDocument()->GetStyleSheetPool();
+ ScStyleSheetPool* pDestPool = aDocument.GetStyleSheetPool();
+
+ SfxStyleFamily eFamily = bCellStyles ?
+ ( bPageStyles ? SFX_STYLE_FAMILY_ALL : SFX_STYLE_FAMILY_PARA ) :
+ SFX_STYLE_FAMILY_PAGE;
+ SfxStyleSheetIterator aIter( pSourcePool, eFamily );
+ USHORT nSourceCount = aIter.Count();
+ if ( nSourceCount == 0 )
+ return; // no source styles
+
+ ScStylePair* pStyles = new ScStylePair[ nSourceCount ];
+ USHORT nFound = 0;
+
+ // first create all new styles
+
+ SfxStyleSheetBase* pSourceStyle = aIter.First();
+ while (pSourceStyle)
+ {
+ String aName = pSourceStyle->GetName();
+ SfxStyleSheetBase* pDestStyle = pDestPool->Find( pSourceStyle->GetName(), pSourceStyle->GetFamily() );
+ if ( pDestStyle )
+ {
+ // touch existing styles only if replace flag is set
+ if ( bReplace )
+ {
+ pStyles[nFound].pSource = pSourceStyle;
+ pStyles[nFound].pDest = pDestStyle;
+ ++nFound;
+ }
+ }
+ else
+ {
+ pStyles[nFound].pSource = pSourceStyle;
+ pStyles[nFound].pDest = &pDestPool->Make( aName, pSourceStyle->GetFamily(), pSourceStyle->GetMask() );
+ ++nFound;
+ }
+
+ pSourceStyle = aIter.Next();
+ }
+
+ // then copy contents (after inserting all styles, for parent etc.)
+
+ for ( USHORT i = 0; i < nFound; ++i )
+ {
+ pStyles[i].pDest->GetItemSet().PutExtended(
+ pStyles[i].pSource->GetItemSet(), SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT);
+ if(pStyles[i].pSource->HasParentSupport())
+ pStyles[i].pDest->SetParent(pStyles[i].pSource->GetParent());
+ // follow is never used
+ }
+
+ lcl_AdjustPool( GetStyleSheetPool() ); // adjust SetItems
+ UpdateAllRowHeights();
+ PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID | PAINT_LEFT ); // Paint
+
+ delete[] pStyles;
+}
+
+
+BOOL __EXPORT ScDocShell::Insert( SfxObjectShell &rSource,
+ USHORT nSourceIdx1, USHORT nSourceIdx2, USHORT nSourceIdx3,
+ USHORT &nIdx1, USHORT &nIdx2, USHORT &nIdx3, USHORT &rIdxDeleted )
+{
+ BOOL bRet = SfxObjectShell::Insert( rSource, nSourceIdx1, nSourceIdx2, nSourceIdx3,
+ nIdx1, nIdx2, nIdx3, rIdxDeleted );
+ if (bRet)
+ lcl_AdjustPool( GetStyleSheetPool() ); // SetItems anpassen
+
+ return bRet;
+}
+
+void ScDocShell::UpdateLinks()
+{
+ sfx2::LinkManager* pLinkManager = aDocument.GetLinkManager();
+ ScStrCollection aNames;
+
+ // nicht mehr benutzte Links raus
+
+ USHORT nCount = pLinkManager->GetLinks().Count();
+ for (USHORT k=nCount; k>0; )
+ {
+ --k;
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[k];
+ if (pBase->ISA(ScTableLink))
+ {
+ ScTableLink* pTabLink = (ScTableLink*)pBase;
+ if (pTabLink->IsUsed())
+ {
+ StrData* pData = new StrData(pTabLink->GetFileName());
+ if (!aNames.Insert(pData))
+ delete pData;
+ }
+ else // nicht mehr benutzt -> loeschen
+ {
+ pTabLink->SetAddUndo(TRUE);
+ pLinkManager->Remove(k);
+ }
+ }
+ }
+
+
+ // neue Links eintragen
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (aDocument.IsLinked(i))
+ {
+ String aDocName = aDocument.GetLinkDoc(i);
+ String aFltName = aDocument.GetLinkFlt(i);
+ String aOptions = aDocument.GetLinkOpt(i);
+ ULONG nRefresh = aDocument.GetLinkRefreshDelay(i);
+ BOOL bThere = FALSE;
+ for (SCTAB j=0; j<i && !bThere; j++) // im Dokument mehrfach?
+ if (aDocument.IsLinked(j)
+ && aDocument.GetLinkDoc(j) == aDocName
+ && aDocument.GetLinkFlt(j) == aFltName
+ && aDocument.GetLinkOpt(j) == aOptions)
+ // Ignore refresh delay in compare, it should be the
+ // same for identical links and we don't want dupes
+ // if it ain't.
+ bThere = TRUE;
+
+ if (!bThere) // schon als Filter eingetragen?
+ {
+ StrData* pData = new StrData(aDocName);
+ if (!aNames.Insert(pData))
+ {
+ delete pData;
+ bThere = TRUE;
+ }
+ }
+ if (!bThere)
+ {
+ ScTableLink* pLink = new ScTableLink( this, aDocName, aFltName, aOptions, nRefresh );
+ pLink->SetInCreate( TRUE );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+ }
+ }
+}
+
+BOOL ScDocShell::ReloadTabLinks()
+{
+ sfx2::LinkManager* pLinkManager = aDocument.GetLinkManager();
+
+ BOOL bAny = FALSE;
+ USHORT nCount = pLinkManager->GetLinks().Count();
+ for (USHORT i=0; i<nCount; i++ )
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
+ if (pBase->ISA(ScTableLink))
+ {
+ ScTableLink* pTabLink = (ScTableLink*)pBase;
+// pTabLink->SetAddUndo(FALSE); //! Undo's zusammenfassen
+ pTabLink->SetPaint(FALSE); // Paint nur einmal am Ende
+ pTabLink->Update();
+ pTabLink->SetPaint(TRUE);
+// pTabLink->SetAddUndo(TRUE);
+ bAny = TRUE;
+ }
+ }
+
+ if ( bAny )
+ {
+ // Paint nur einmal
+ PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB),
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT );
+
+ SetDocumentModified();
+ }
+
+ return TRUE; //! Fehler erkennen
+}
+
+
diff --git a/sc/source/ui/docshell/docsh7.cxx b/sc/source/ui/docshell/docsh7.cxx
new file mode 100644
index 000000000000..89f082672b29
--- /dev/null
+++ b/sc/source/ui/docshell/docsh7.cxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "docsh.hxx"
+
+//------------------------------------------------------------------
+
+void ScDocShell::GetDrawObjState( SfxItemSet & /* rSet */ )
+{
+ // SID_SC_ACTIVEOBJECT (SelectedObject) - removed (old Basic)
+}
+
+
+
diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx
new file mode 100644
index 000000000000..cb9d625da70c
--- /dev/null
+++ b/sc/source/ui/docshell/docsh8.cxx
@@ -0,0 +1,1098 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <stdio.h>
+#include <tools/urlobj.hxx>
+#include <svl/converter.hxx>
+#include <svl/zforlist.hxx>
+#include <comphelper/types.hxx>
+#include <ucbhelper/content.hxx>
+#include <unotools/sharedunocomponent.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svx/txenctab.hxx>
+#include <svx/dbcharsethelper.hxx>
+
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDriver.hpp>
+#include <com/sun/star/sdbc/XDriverAccess.hpp>
+#include <com/sun/star/sdbc/XDriverManager.hpp>
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XRowUpdate.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbcx/XAppend.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
+#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+
+#include "scerrors.hxx"
+#include "docsh.hxx"
+#include "filter.hxx"
+#include "progress.hxx"
+#include "collect.hxx"
+#include "cell.hxx"
+#include "editutil.hxx"
+#include "cellform.hxx"
+#include "dbdocutl.hxx"
+#include "dociter.hxx"
+#include "globstr.hrc"
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
+#define SC_SERVICE_DRVMAN "com.sun.star.sdbc.DriverManager"
+
+//! move to a header file?
+//#define SC_DBPROP_DATASOURCENAME "DataSourceName"
+#define SC_DBPROP_ACTIVECONNECTION "ActiveConnection"
+#define SC_DBPROP_COMMAND "Command"
+#define SC_DBPROP_COMMANDTYPE "CommandType"
+
+#define SC_DBPROP_NAME "Name"
+#define SC_DBPROP_TYPE "Type"
+#define SC_DBPROP_PRECISION "Precision"
+#define SC_DBPROP_SCALE "Scale"
+
+#define SC_DBPROP_EXTENSION "Extension"
+#define SC_DBPROP_CHARSET "CharSet"
+
+#define SC_ROWCOUNT_ERROR (-1)
+
+namespace
+{
+ ULONG lcl_getDBaseConnection(uno::Reference<sdbc::XDriverManager>& _rDrvMgr,uno::Reference<sdbc::XConnection>& _rConnection,String& _rTabName,const String& rFullFileName,rtl_TextEncoding eCharSet)
+ {
+ INetURLObject aURL;
+ aURL.SetSmartProtocol( INET_PROT_FILE );
+ aURL.SetSmartURL( rFullFileName );
+ _rTabName = aURL.getBase( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_UNAMBIGUOUS );
+ String aExtension = aURL.getExtension();
+ aURL.removeSegment();
+ aURL.removeFinalSlash();
+ String aPath = aURL.GetMainURL(INetURLObject::NO_DECODE);
+ uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
+ if (!xFactory.is()) return SCERR_EXPORT_CONNECT;
+
+ _rDrvMgr.set( xFactory->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_DRVMAN ) ),
+ uno::UNO_QUERY);
+ DBG_ASSERT( _rDrvMgr.is(), "can't get DriverManager" );
+ if (!_rDrvMgr.is()) return SCERR_EXPORT_CONNECT;
+
+ // get connection
+
+ String aConnUrl = String::CreateFromAscii("sdbc:dbase:");
+ aConnUrl += aPath;
+
+ svxform::ODataAccessCharsetHelper aHelper;
+ ::std::vector< rtl_TextEncoding > aEncodings;
+ aHelper.getSupportedTextEncodings( aEncodings );
+ ::std::vector< rtl_TextEncoding >::iterator aIter = ::std::find(aEncodings.begin(),aEncodings.end(),(rtl_TextEncoding) eCharSet);
+ if ( aIter == aEncodings.end() )
+ {
+ DBG_ERRORFILE( "DBaseImport: dbtools::OCharsetMap doesn't know text encoding" );
+ return SCERR_IMPORT_CONNECT;
+ } // if ( aIter == aMap.end() )
+ rtl::OUString aCharSetStr;
+ if ( RTL_TEXTENCODING_DONTKNOW != *aIter )
+ { // it's not the virtual "system charset"
+ const char* pIanaName = rtl_getMimeCharsetFromTextEncoding( *aIter );
+ OSL_ENSURE( pIanaName, "invalid mime name!" );
+ if ( pIanaName )
+ aCharSetStr = ::rtl::OUString::createFromAscii( pIanaName );
+ }
+
+ uno::Sequence<beans::PropertyValue> aProps(2);
+ aProps[0].Name = rtl::OUString::createFromAscii(SC_DBPROP_EXTENSION);
+ aProps[0].Value <<= rtl::OUString( aExtension );
+ aProps[1].Name = rtl::OUString::createFromAscii(SC_DBPROP_CHARSET);
+ aProps[1].Value <<= aCharSetStr;
+
+ _rConnection = _rDrvMgr->getConnectionWithInfo( aConnUrl, aProps );
+ return 0L;
+ }
+}
+// -----------------------------------------------------------------------
+// MoveFile/KillFile/IsDocument: similar to SfxContentHelper
+
+// static
+BOOL ScDocShell::MoveFile( const INetURLObject& rSourceObj, const INetURLObject& rDestObj )
+{
+ sal_Bool bMoveData = sal_True;
+ sal_Bool bRet = sal_True, bKillSource = sal_False;
+ if ( rSourceObj.GetProtocol() != rDestObj.GetProtocol() )
+ {
+ bMoveData = sal_False;
+ bKillSource = sal_True;
+ }
+ String aName = rDestObj.getName();
+ INetURLObject aDestPathObj = rDestObj;
+ aDestPathObj.removeSegment();
+ aDestPathObj.setFinalSlash();
+
+ try
+ {
+ ::ucbhelper::Content aDestPath( aDestPathObj.GetMainURL(INetURLObject::NO_DECODE),
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands();
+ rtl::OUString aTransferName = rtl::OUString::createFromAscii( "transfer" );
+ if ( xInfo->hasCommandByName( aTransferName ) )
+ {
+ aDestPath.executeCommand( aTransferName, uno::makeAny(
+ ::com::sun::star::ucb::TransferInfo( bMoveData, rSourceObj.GetMainURL(INetURLObject::NO_DECODE), aName,
+ ::com::sun::star::ucb::NameClash::ERROR ) ) );
+ }
+ else
+ {
+ DBG_ERRORFILE( "transfer command not available" );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // ucb may throw different exceptions on failure now
+ bRet = sal_False;
+ }
+
+ if ( bKillSource )
+ KillFile( rSourceObj );
+
+ return bRet;
+}
+
+
+// static
+BOOL ScDocShell::KillFile( const INetURLObject& rURL )
+{
+ sal_Bool bRet = sal_True;
+ try
+ {
+ ::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE),
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ),
+ comphelper::makeBoolAny( sal_True ) );
+ }
+ catch( uno::Exception& )
+ {
+ // ucb may throw different exceptions on failure now
+ bRet = sal_False;
+ }
+
+ return bRet;
+}
+
+// static
+BOOL ScDocShell::IsDocument( const INetURLObject& rURL )
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ ::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE),
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ bRet = aCnt.isDocument();
+ }
+ catch( uno::Exception& )
+ {
+ // ucb may throw different exceptions on failure now - warning only
+ DBG_WARNING( "Any other exception" );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+ BOOL bSimpleColWidth[MAXCOLCOUNT] )
+{
+ ULONG nErr = eERR_OK;
+ long i;
+
+ try
+ {
+ String aTabName;
+ uno::Reference<sdbc::XDriverManager> xDrvMan;
+ uno::Reference<sdbc::XConnection> xConnection;
+ ULONG nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
+ if ( !xConnection.is() || !xDrvMan.is() )
+ return nRet;
+ ::utl::DisposableComponent aConnectionHelper(xConnection);
+
+ long nRowCount = 0;
+ if ( nRowCount < 0 )
+ {
+ DBG_ERROR("can't get row count");
+ nRowCount = 0;
+ }
+
+ ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), nRowCount );
+ uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
+ uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
+ uno::UNO_QUERY);
+ ::utl::DisposableComponent aRowSetHelper(xRowSet);
+ uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
+ if (!xRowProp.is()) return SCERR_IMPORT_CONNECT;
+
+ sal_Int32 nType = sdb::CommandType::TABLE;
+ uno::Any aAny;
+
+ aAny <<= xConnection;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny );
+
+ aAny <<= nType;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
+
+ aAny <<= rtl::OUString( aTabName );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
+
+ xRowSet->execute();
+
+ long nColCount = 0;
+ uno::Reference<sdbc::XResultSetMetaData> xMeta;
+ uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
+ if ( xMetaSupp.is() )
+ xMeta = xMetaSupp->getMetaData();
+ if ( xMeta.is() )
+ nColCount = xMeta->getColumnCount(); // this is the number of real columns
+
+ if ( nColCount > MAXCOL+1 )
+ {
+ nColCount = MAXCOL+1;
+ nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning
+ }
+
+ if ( nColCount > 0 )
+ aDocument.DoColResize( 0, 0, static_cast<SCCOL>(nColCount) - 1,
+ static_cast<SCSIZE>(nRowCount) + 1 );
+
+ uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRow.is(), "can't get Row" );
+ if (!xRow.is()) return SCERR_IMPORT_CONNECT;
+
+ // currency flag is not needed for dBase
+ uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types
+ sal_Int32* pTypeArr = aColTypes.getArray();
+ for (i=0; i<nColCount; i++)
+ pTypeArr[i] = xMeta->getColumnType( i+1 );
+
+ // read column names
+ //! add type descriptions
+
+ for (i=0; i<nColCount; i++)
+ {
+ String aHeader = xMeta->getColumnLabel( i+1 );
+
+ switch ( pTypeArr[i] )
+ {
+ case sdbc::DataType::BIT:
+ aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" ));
+ break;
+ case sdbc::DataType::DATE:
+ aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" ));
+ break;
+ case sdbc::DataType::LONGVARCHAR:
+ aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" ));
+ break;
+ case sdbc::DataType::VARCHAR:
+ aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," ));
+ aHeader += String::CreateFromInt32( xMeta->getColumnDisplaySize( i+1 ) );
+ break;
+ case sdbc::DataType::DECIMAL:
+ {
+ long nPrec = xMeta->getPrecision( i+1 );
+ long nScale = xMeta->getScale( i+1 );
+ aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," ));
+ aHeader += String::CreateFromInt32(
+ SvDbaseConverter::ConvertPrecisionToDbase(
+ nPrec, nScale ) );
+ aHeader += ',';
+ aHeader += String::CreateFromInt32( nScale );
+ }
+ break;
+ }
+
+ aDocument.SetString( static_cast<SCCOL>(i), 0, 0, aHeader );
+ }
+
+ SCROW nRow = 1; // 0 is column titles
+ BOOL bEnd = FALSE;
+ while ( !bEnd && xRowSet->next() )
+ {
+ if ( nRow <= MAXROW )
+ {
+ SCCOL nCol = 0;
+ for (i=0; i<nColCount; i++)
+ {
+ ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0,
+ xRow, i+1, pTypeArr[i], FALSE,
+ &bSimpleColWidth[nCol] );
+ ++nCol;
+ }
+ ++nRow;
+ }
+ else // past the end of the spreadsheet
+ {
+ bEnd = TRUE; // don't continue
+ nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning message
+ }
+
+ if ( nRowCount )
+ aProgress.SetStateOnPercent( nRow );
+ }
+ }
+ catch ( sdbc::SQLException& )
+ {
+ nErr = SCERR_IMPORT_CONNECT;
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in database");
+ nErr = ERRCODE_IO_GENERAL;
+ }
+
+ return nErr;
+}
+
+// -----------------------------------------------------------------------
+
+inline sal_Bool IsAsciiDigit( sal_Unicode c )
+{
+ return 0x30 <= c && c <= 0x39;
+}
+
+inline sal_Bool IsAsciiAlpha( sal_Unicode c )
+{
+ return (0x41 <= c && c <= 0x5a) || (0x61 <= c && c <= 0x7a);
+}
+
+void lcl_GetColumnTypes( ScDocShell& rDocShell,
+ const ScRange& rDataRange, BOOL bHasFieldNames,
+ rtl::OUString* pColNames, sal_Int32* pColTypes,
+ sal_Int32* pColLengths, sal_Int32* pColScales,
+ BOOL& bHasMemo, CharSet eCharSet )
+{
+ // updating of column titles didn't work in 5.2 and isn't always wanted
+ // (saving normally shouldn't modify the document)
+ //! read flag from configuration
+ BOOL bUpdateTitles = FALSE;
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SvNumberFormatter* pNumFmt = pDoc->GetFormatTable();
+
+ SCTAB nTab = rDataRange.aStart.Tab();
+ SCCOL nFirstCol = rDataRange.aStart.Col();
+ SCROW nFirstRow = rDataRange.aStart.Row();
+ SCCOL nLastCol = rDataRange.aEnd.Col();
+ SCROW nLastRow = rDataRange.aEnd.Row();
+
+ ScStrCollection aFieldNamesCollection;
+
+ long nField = 0;
+ SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
+ for ( SCCOL nCol = nFirstCol; nCol <= nLastCol; nCol++ )
+ {
+ BOOL bTypeDefined = FALSE;
+ BOOL bPrecDefined = FALSE;
+ sal_Int32 nFieldLen = 0;
+ sal_Int32 nPrecision = 0;
+ sal_Int32 nDbType = sdbc::DataType::SQLNULL;
+ String aFieldName, aString;
+
+ // Feldname[,Type[,Width[,Prec]]]
+ // Typ etc.: L; D; C[,W]; N[,W[,P]]
+ if ( bHasFieldNames )
+ {
+ pDoc->GetString( nCol, nFirstRow, nTab, aString );
+ aString.ToUpperAscii();
+ xub_StrLen nToken = aString.GetTokenCount( ',' );
+ if ( nToken > 1 )
+ {
+ aFieldName = aString.GetToken( 0, ',' );
+ aString.EraseAllChars( ' ' );
+ switch ( aString.GetToken( 1, ',' ).GetChar(0) )
+ {
+ case 'L' :
+ nDbType = sdbc::DataType::BIT;
+ nFieldLen = 1;
+ bTypeDefined = TRUE;
+ bPrecDefined = TRUE;
+ break;
+ case 'D' :
+ nDbType = sdbc::DataType::DATE;
+ nFieldLen = 8;
+ bTypeDefined = TRUE;
+ bPrecDefined = TRUE;
+ break;
+ case 'M' :
+ nDbType = sdbc::DataType::LONGVARCHAR;
+ nFieldLen = 10;
+ bTypeDefined = TRUE;
+ bPrecDefined = TRUE;
+ bHasMemo = TRUE;
+ break;
+ case 'C' :
+ nDbType = sdbc::DataType::VARCHAR;
+ bTypeDefined = TRUE;
+ bPrecDefined = TRUE;
+ break;
+ case 'N' :
+ nDbType = sdbc::DataType::DECIMAL;
+ bTypeDefined = TRUE;
+ break;
+ }
+ if ( bTypeDefined && !nFieldLen && nToken > 2 )
+ {
+ nFieldLen = aString.GetToken( 2, ',' ).ToInt32();
+ if ( !bPrecDefined && nToken > 3 )
+ {
+ String aTmp( aString.GetToken( 3, ',' ) );
+ if ( CharClass::isAsciiNumeric(aTmp) )
+ {
+ nPrecision = aTmp.ToInt32();
+ bPrecDefined = TRUE;
+ }
+ }
+ }
+ }
+ else
+ aFieldName = aString;
+
+ // Feldnamen pruefen und ggbf. gueltigen Feldnamen erzeugen.
+ // Erstes Zeichen muss Buchstabe sein,
+ // weitere nur alphanumerisch und Unterstrich erlaubt,
+ // "_DBASELOCK" ist reserviert (obsolet weil erstes Zeichen kein Buchstabe),
+ // keine doppelten Namen.
+ if ( !IsAsciiAlpha( aFieldName.GetChar(0) ) )
+ aFieldName.Insert( 'N', 0 );
+ String aTmpStr;
+ sal_Unicode c;
+ for ( const sal_Unicode* p = aFieldName.GetBuffer(); ( c = *p ) != 0; p++ )
+ {
+ if ( IsAsciiAlpha( c ) || IsAsciiDigit( c ) || c == '_' )
+ aTmpStr += c;
+ else
+ aTmpStr += '_';
+ }
+ aFieldName = aTmpStr;
+ if ( aFieldName.Len() > 10 )
+ aFieldName.Erase( 10 );
+ StrData* pStrData = new StrData( aFieldName );
+ if ( !aFieldNamesCollection.Insert( pStrData ) )
+ { // doppelter Feldname, numerisch erweitern
+ USHORT nSub = 1;
+ String aFixPart( aFieldName );
+ do
+ {
+ ++nSub;
+ String aVarPart = String::CreateFromInt32( nSub );
+ if ( aFixPart.Len() + aVarPart.Len() > 10 )
+ aFixPart.Erase( 10 - aVarPart.Len() );
+ aFieldName = aFixPart;
+ aFieldName += aVarPart;
+ pStrData->SetString( aFieldName );
+ } while ( !aFieldNamesCollection.Insert( pStrData ) );
+ }
+ }
+ else
+ {
+ aFieldName = 'N';
+ aFieldName += String::CreateFromInt32(nCol+1);
+ }
+
+ if ( !bTypeDefined )
+ { // Feldtyp
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nFirstDataRow, nTab, pCell );
+ if ( !pCell || pCell->HasStringData() )
+ nDbType = sdbc::DataType::VARCHAR;
+ else
+ {
+ sal_uInt32 nFormat;
+ pDoc->GetNumberFormat( nCol, nFirstDataRow, nTab, nFormat );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
+ && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) )
+ {
+ nFormat = ScGlobal::GetStandardFormat(
+ ((ScFormulaCell*)pCell)->GetValue(), *pNumFmt, nFormat,
+ ((ScFormulaCell*)pCell)->GetFormatType() );
+ }
+ switch ( pNumFmt->GetType( nFormat ) )
+ {
+ case NUMBERFORMAT_LOGICAL :
+ nDbType = sdbc::DataType::BIT;
+ nFieldLen = 1;
+ break;
+ case NUMBERFORMAT_DATE :
+ nDbType = sdbc::DataType::DATE;
+ nFieldLen = 8;
+ break;
+ case NUMBERFORMAT_TIME :
+ case NUMBERFORMAT_DATETIME :
+ nDbType = sdbc::DataType::VARCHAR;
+ break;
+ default:
+ nDbType = sdbc::DataType::DECIMAL;
+ }
+ }
+ }
+ BOOL bSdbLenAdjusted = FALSE;
+ BOOL bSdbLenBad = FALSE;
+ // Feldlaenge
+ if ( nDbType == sdbc::DataType::VARCHAR && !nFieldLen )
+ { // maximale Feldbreite bestimmen
+ nFieldLen = pDoc->GetMaxStringLen( nTab, nCol, nFirstDataRow,
+ nLastRow, eCharSet );
+ if ( nFieldLen == 0 )
+ nFieldLen = 1;
+ }
+ else if ( nDbType == sdbc::DataType::DECIMAL )
+ { // maximale Feldbreite und Nachkommastellen bestimmen
+ xub_StrLen nLen;
+ sal_uInt16 nPrec;
+ nLen = pDoc->GetMaxNumberStringLen( nPrec, nTab, nCol,
+ nFirstDataRow, nLastRow );
+ // dBaseIII Limit Nachkommastellen: 15
+ if ( nPrecision > 15 )
+ nPrecision = 15;
+ if ( nPrec > 15 )
+ nPrec = 15;
+ if ( bPrecDefined && nPrecision != nPrec )
+ { // Laenge auf vorgegebene Nachkommastellen anpassen
+ if ( nPrecision )
+ nLen = sal::static_int_cast<xub_StrLen>( nLen + ( nPrecision - nPrec ) );
+ else
+ nLen -= nPrec+1; // auch den . mit raus
+ }
+ if ( nLen > nFieldLen && !bTypeDefined )
+ nFieldLen = nLen;
+ if ( !bPrecDefined )
+ nPrecision = nPrec;
+ if ( nFieldLen == 0 )
+ nFieldLen = 1;
+ else if ( nFieldLen > 19 )
+ nFieldLen = 19; // dBaseIII Limit Feldlaenge numerisch: 19
+ if ( nPrecision && nFieldLen < nPrecision + 2 )
+ nFieldLen = nPrecision + 2; // 0. muss mit reinpassen
+ // 538 MUST: Sdb internal representation adds 2 to the field length!
+ // To give the user what he wants we must substract it here.
+ //! CAVEAT! There is no way to define a numeric field with a length
+ //! of 1 and no decimals!
+ if ( nFieldLen == 1 && nPrecision == 0 )
+ bSdbLenBad = TRUE;
+ nFieldLen = SvDbaseConverter::ConvertPrecisionToOdbc( nFieldLen, nPrecision );
+ bSdbLenAdjusted = TRUE;
+ }
+ if ( nFieldLen > 254 )
+ {
+ if ( nDbType == sdbc::DataType::VARCHAR )
+ { // zu lang fuer normales Textfeld => Memofeld
+ nDbType = sdbc::DataType::LONGVARCHAR;
+ nFieldLen = 10;
+ bHasMemo = TRUE;
+ }
+ else
+ nFieldLen = 254; // dumm gelaufen..
+ }
+
+ pColNames[nField] = aFieldName;
+ pColTypes[nField] = nDbType;
+ pColLengths[nField] = nFieldLen;
+ pColScales[nField] = nPrecision;
+
+ // undo change to field length, reflect reality
+ if ( bSdbLenAdjusted )
+ {
+ nFieldLen = SvDbaseConverter::ConvertPrecisionToDbase( nFieldLen, nPrecision );
+ if ( bSdbLenBad && nFieldLen == 1 )
+ nFieldLen = 2; // THIS is reality
+ }
+ if ( bUpdateTitles )
+ { // Angabe anpassen und ausgeben
+ String aOutString = aFieldName;
+ switch ( nDbType )
+ {
+ case sdbc::DataType::BIT :
+ aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" ));
+ break;
+ case sdbc::DataType::DATE :
+ aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" ));
+ break;
+ case sdbc::DataType::LONGVARCHAR :
+ aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" ));
+ break;
+ case sdbc::DataType::VARCHAR :
+ aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," ));
+ aOutString += String::CreateFromInt32( nFieldLen );
+ break;
+ case sdbc::DataType::DECIMAL :
+ aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," ));
+ aOutString += String::CreateFromInt32( nFieldLen );
+ aOutString += ',';
+ aOutString += String::CreateFromInt32( nPrecision );
+ break;
+ }
+ if ( !aOutString.EqualsIgnoreCaseAscii( aString ) )
+ {
+ pDoc->SetString( nCol, nFirstRow, nTab, aOutString );
+ rDocShell.PostPaint( nCol, nFirstRow, nTab, nCol, nFirstRow, nTab, PAINT_GRID );
+ }
+ }
+ ++nField;
+ }
+}
+
+
+inline void lcl_getLongVarCharEditString( String& rString,
+ const ScBaseCell* pCell, ScFieldEditEngine& rEditEngine )
+{
+ rEditEngine.SetText( *((const ScEditCell*)pCell)->GetData() );
+ rString = rEditEngine.GetText( LINEEND_CRLF );
+}
+
+inline void lcl_getLongVarCharString( String& rString, ScBaseCell* pCell,
+ ScDocument& rDocument, SCCOL nCol, SCROW nRow, SCTAB nTab,
+ SvNumberFormatter& rNumFmt )
+{
+ sal_uInt32 nFormat;
+ Color* pColor;
+ rDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
+ ScCellFormat::GetString( pCell, nFormat, rString, &pColor, rNumFmt );
+}
+
+
+ULONG ScDocShell::DBaseExport( const String& rFullFileName, CharSet eCharSet, BOOL& bHasMemo )
+{
+ // remove the file so the dBase driver doesn't find an invalid file
+ INetURLObject aDeleteObj( rFullFileName, INET_PROT_FILE );
+ KillFile( aDeleteObj );
+
+ ULONG nErr = eERR_OK;
+ uno::Any aAny;
+
+ SCCOL nFirstCol, nLastCol;
+ SCROW nFirstRow, nLastRow;
+ SCTAB nTab = GetSaveTab();
+ aDocument.GetDataStart( nTab, nFirstCol, nFirstRow );
+ aDocument.GetCellArea( nTab, nLastCol, nLastRow );
+ if ( nFirstCol > nLastCol )
+ nFirstCol = nLastCol;
+ if ( nFirstRow > nLastRow )
+ nFirstRow = nLastRow;
+ ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ),
+ nLastRow - nFirstRow );
+ SvNumberFormatter* pNumFmt = aDocument.GetFormatTable();
+
+ BOOL bHasFieldNames = TRUE;
+ for ( SCCOL nDocCol = nFirstCol; nDocCol <= nLastCol && bHasFieldNames; nDocCol++ )
+ { // nur Strings in erster Zeile => sind Feldnamen
+ if ( !aDocument.HasStringData( nDocCol, nFirstRow, nTab ) )
+ bHasFieldNames = FALSE;
+ }
+
+ long nColCount = nLastCol - nFirstCol + 1;
+ uno::Sequence<rtl::OUString> aColNames( nColCount );
+ uno::Sequence<sal_Int32> aColTypes( nColCount );
+ uno::Sequence<sal_Int32> aColLengths( nColCount );
+ uno::Sequence<sal_Int32> aColScales( nColCount );
+
+ ScRange aDataRange( nFirstCol, nFirstRow, nTab, nLastCol, nLastRow, nTab );
+ lcl_GetColumnTypes( *this, aDataRange, bHasFieldNames,
+ aColNames.getArray(), aColTypes.getArray(),
+ aColLengths.getArray(), aColScales.getArray(),
+ bHasMemo, eCharSet );
+ // also needed for exception catch
+ SCROW nDocRow = 0;
+ ScFieldEditEngine aEditEngine( aDocument.GetEditPool() );
+ String aString;
+ String aTabName;
+
+ try
+ {
+ uno::Reference<sdbc::XDriverManager> xDrvMan;
+ uno::Reference<sdbc::XConnection> xConnection;
+ ULONG nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
+ if ( !xConnection.is() || !xDrvMan.is() )
+ return nRet;
+ ::utl::DisposableComponent aConnectionHelper(xConnection);
+
+ // get dBase driver
+ uno::Reference< sdbc::XDriverAccess> xAccess(xDrvMan,uno::UNO_QUERY);
+ uno::Reference< sdbcx::XDataDefinitionSupplier > xDDSup( xAccess->getDriverByURL( xConnection->getMetaData()->getURL() ), uno::UNO_QUERY );
+ if ( !xDDSup.is() )
+ return SCERR_EXPORT_CONNECT;
+
+ // create table
+ uno::Reference<sdbcx::XTablesSupplier> xTablesSupp =xDDSup->getDataDefinitionByConnection( xConnection );
+ DBG_ASSERT( xTablesSupp.is(), "can't get Data Definition" );
+ if (!xTablesSupp.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<container::XNameAccess> xTables = xTablesSupp->getTables();
+ DBG_ASSERT( xTables.is(), "can't get Tables" );
+ if (!xTables.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<sdbcx::XDataDescriptorFactory> xTablesFact( xTables, uno::UNO_QUERY );
+ DBG_ASSERT( xTablesFact.is(), "can't get tables factory" );
+ if (!xTablesFact.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<sdbcx::XAppend> xTablesAppend( xTables, uno::UNO_QUERY );
+ DBG_ASSERT( xTablesAppend.is(), "can't get tables XAppend" );
+ if (!xTablesAppend.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<beans::XPropertySet> xTableDesc = xTablesFact->createDataDescriptor();
+ DBG_ASSERT( xTableDesc.is(), "can't get table descriptor" );
+ if (!xTableDesc.is()) return SCERR_EXPORT_CONNECT;
+
+ aAny <<= rtl::OUString( aTabName );
+ xTableDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny );
+
+ // create columns
+
+ uno::Reference<sdbcx::XColumnsSupplier> xColumnsSupp( xTableDesc, uno::UNO_QUERY );
+ DBG_ASSERT( xColumnsSupp.is(), "can't get columns supplier" );
+ if (!xColumnsSupp.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<container::XNameAccess> xColumns = xColumnsSupp->getColumns();
+ DBG_ASSERT( xColumns.is(), "can't get columns" );
+ if (!xColumns.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<sdbcx::XDataDescriptorFactory> xColumnsFact( xColumns, uno::UNO_QUERY );
+ DBG_ASSERT( xColumnsFact.is(), "can't get columns factory" );
+ if (!xColumnsFact.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<sdbcx::XAppend> xColumnsAppend( xColumns, uno::UNO_QUERY );
+ DBG_ASSERT( xColumnsAppend.is(), "can't get columns XAppend" );
+ if (!xColumnsAppend.is()) return SCERR_EXPORT_CONNECT;
+
+ const rtl::OUString* pColNames = aColNames.getConstArray();
+ const sal_Int32* pColTypes = aColTypes.getConstArray();
+ const sal_Int32* pColLengths = aColLengths.getConstArray();
+ const sal_Int32* pColScales = aColScales.getConstArray();
+ long nCol;
+
+ for (nCol=0; nCol<nColCount; nCol++)
+ {
+ uno::Reference<beans::XPropertySet> xColumnDesc = xColumnsFact->createDataDescriptor();
+ DBG_ASSERT( xColumnDesc.is(), "can't get column descriptor" );
+ if (!xColumnDesc.is()) return SCERR_EXPORT_CONNECT;
+
+ aAny <<= pColNames[nCol];
+ xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny );
+
+ aAny <<= pColTypes[nCol];
+ xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_TYPE), aAny );
+
+ aAny <<= pColLengths[nCol];
+ xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_PRECISION), aAny );
+
+ aAny <<= pColScales[nCol];
+ xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_SCALE), aAny );
+
+ xColumnsAppend->appendByDescriptor( xColumnDesc );
+ }
+
+ xTablesAppend->appendByDescriptor( xTableDesc );
+
+ // re-open connection
+// xConnection = xDrvMan->getConnectionWithInfo( aConnUrl, aProps );
+// DBG_ASSERT( xConnection.is(), "can't get Connection" );
+// if (!xConnection.is()) return SCERR_EXPORT_CONNECT;
+
+ // get row set for writing
+ uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
+ uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
+ uno::UNO_QUERY);
+ ::utl::DisposableComponent aRowSetHelper(xRowSet);
+ uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
+ if (!xRowProp.is()) return SCERR_EXPORT_CONNECT;
+
+ aAny <<= xConnection;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny );
+
+ aAny <<= (sal_Int32) sdb::CommandType::TABLE;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
+
+ aAny <<= rtl::OUString( aTabName );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
+
+ xRowSet->execute();
+
+ // write data rows
+
+ uno::Reference<sdbc::XResultSetUpdate> xResultUpdate( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xResultUpdate.is(), "can't get XResultSetUpdate" );
+ if (!xResultUpdate.is()) return SCERR_EXPORT_CONNECT;
+
+ uno::Reference<sdbc::XRowUpdate> xRowUpdate( xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRowUpdate.is(), "can't get XRowUpdate" );
+ if (!xRowUpdate.is()) return SCERR_EXPORT_CONNECT;
+
+ SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
+ double fVal;
+
+ for ( nDocRow = nFirstDataRow; nDocRow <= nLastRow; nDocRow++ )
+ {
+ xResultUpdate->moveToInsertRow();
+
+ for (nCol=0; nCol<nColCount; nCol++)
+ {
+ SCCOL nDocCol = sal::static_int_cast<SCCOL>( nFirstCol + nCol );
+
+ switch (pColTypes[nCol])
+ {
+ case sdbc::DataType::LONGVARCHAR:
+ {
+ ScBaseCell* pCell;
+ aDocument.GetCell( nDocCol, nDocRow, nTab, pCell );
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_EDIT )
+ { // #60761# Paragraphs erhalten
+ lcl_getLongVarCharEditString( aString,
+ pCell, aEditEngine);
+ }
+ else
+ {
+ lcl_getLongVarCharString( aString, pCell,
+ aDocument, nDocCol, nDocRow, nTab,
+ *pNumFmt);
+ }
+ xRowUpdate->updateString( nCol+1, aString );
+ }
+ else
+ xRowUpdate->updateNull( nCol+1 );
+ }
+ break;
+
+ case sdbc::DataType::VARCHAR:
+ aDocument.GetString( nDocCol, nDocRow, nTab, aString );
+ xRowUpdate->updateString( nCol+1, aString );
+ if ( nErr == eERR_OK && pColLengths[nCol] < aString.Len() )
+ nErr = SCWARN_EXPORT_DATALOST;
+ break;
+
+ case sdbc::DataType::DATE:
+ {
+ aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
+ // #39274# zwischen 0 Wert und 0 kein Wert unterscheiden
+ BOOL bIsNull = (fVal == 0.0);
+ if ( bIsNull )
+ bIsNull = !aDocument.HasValueData( nDocCol, nDocRow, nTab );
+ if ( bIsNull )
+ {
+ xRowUpdate->updateNull( nCol+1 );
+ if ( nErr == eERR_OK &&
+ aDocument.HasStringData( nDocCol, nDocRow, nTab ) )
+ nErr = SCWARN_EXPORT_DATALOST;
+ }
+ else
+ {
+ Date aDate = *(pNumFmt->GetNullDate()); // tools date
+ aDate += (long)fVal; //! approxfloor?
+ util::Date aUnoDate( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() );
+ xRowUpdate->updateDate( nCol+1, aUnoDate );
+ }
+ }
+ break;
+
+ case sdbc::DataType::DECIMAL:
+ case sdbc::DataType::BIT:
+ aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
+ if ( fVal == 0.0 && nErr == eERR_OK &&
+ aDocument.HasStringData( nDocCol, nDocRow, nTab ) )
+ nErr = SCWARN_EXPORT_DATALOST;
+ if ( pColTypes[nCol] == sdbc::DataType::BIT )
+ xRowUpdate->updateBoolean( nCol+1, ( fVal != 0.0 ) );
+ else
+ xRowUpdate->updateDouble( nCol+1, fVal );
+ break;
+
+ default:
+ DBG_ERROR( "ScDocShell::DBaseExport: unknown FieldType" );
+ if ( nErr == eERR_OK )
+ nErr = SCWARN_EXPORT_DATALOST;
+ aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
+ xRowUpdate->updateDouble( nCol+1, fVal );
+ }
+ }
+
+ xResultUpdate->insertRow();
+
+ //! error handling and recovery of old
+ //! ScDocShell::SbaSdbExport is still missing!
+
+ if ( !aProgress.SetStateOnPercent( nDocRow - nFirstRow ) )
+ { // UserBreak
+ nErr = SCERR_EXPORT_DATA;
+ break;
+ }
+ }
+
+ comphelper::disposeComponent( xRowSet );
+ comphelper::disposeComponent( xConnection );
+ }
+ catch ( sdbc::SQLException& aException )
+ {
+ sal_Int32 nError = aException.ErrorCode;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "ScDocShell::DBaseExport: SQLException ErrorCode: %d, SQLState: %s, Message: %s\n",
+ (int)nError, OUStringToOString( aException.SQLState,
+ RTL_TEXTENCODING_UTF8).getStr(), OUStringToOString(
+ aException.Message, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ if (nError == 22018 || nError == 22001)
+ {
+ // SQL error 22018: Character not in target encoding.
+ // SQL error 22001: String length exceeds field width (after encoding).
+ bool bEncErr = (nError == 22018);
+ bool bIsOctetTextEncoding = rtl_isOctetTextEncoding( eCharSet);
+ DBG_ASSERT( !bEncErr || bIsOctetTextEncoding, "ScDocShell::DBaseExport: encoding error and not an octect textencoding");
+ SCCOL nDocCol = nFirstCol;
+ const sal_Int32* pColTypes = aColTypes.getConstArray();
+ const sal_Int32* pColLengths = aColLengths.getConstArray();
+ ScHorizontalCellIterator aIter( &aDocument, nTab, nFirstCol,
+ nDocRow, nLastCol, nDocRow);
+ ScBaseCell* pCell = NULL;
+ bool bTest = true;
+ while (bTest && ((pCell = aIter.GetNext( nDocCol, nDocRow)) != NULL))
+ {
+ SCCOL nCol = nDocCol - nFirstCol;
+ switch (pColTypes[nCol])
+ {
+ case sdbc::DataType::LONGVARCHAR:
+ {
+ if ( pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_EDIT )
+ lcl_getLongVarCharEditString( aString,
+ pCell, aEditEngine);
+ else
+ lcl_getLongVarCharString( aString,
+ pCell, aDocument, nDocCol,
+ nDocRow, nTab, *pNumFmt);
+ }
+ }
+ break;
+
+ case sdbc::DataType::VARCHAR:
+ aDocument.GetString( nDocCol, nDocRow, nTab, aString);
+ break;
+
+ // NOTE: length of DECIMAL fields doesn't need to be
+ // checked here, the database driver adjusts the field
+ // width accordingly.
+
+ default:
+ bTest = false;
+ }
+ if (bTest)
+ {
+ sal_Int32 nLen;
+ if (bIsOctetTextEncoding)
+ {
+ rtl::OUString aOUString( aString);
+ rtl::OString aOString;
+ if (!aOUString.convertToString( &aOString, eCharSet,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ {
+ bTest = false;
+ bEncErr = true;
+ }
+ nLen = aOString.getLength();
+#if OSL_DEBUG_LEVEL > 1
+ if (!bTest)
+ fprintf( stderr, "ScDocShell::DBaseExport encoding error, string with default replacements: ``%s''\n",
+ OUStringToOString( aOUString, eCharSet).getStr());
+#endif
+ }
+ else
+ nLen = aString.Len() * sizeof(sal_Unicode);
+ if (!bEncErr &&
+ pColTypes[nCol] != sdbc::DataType::LONGVARCHAR &&
+ pColLengths[nCol] < nLen)
+ {
+ bTest = false;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "ScDocShell::DBaseExport: field width: %d, encoded length: %d\n",
+ (int)pColLengths[nCol], (int)nLen);
+#endif
+ }
+ }
+ else
+ bTest = true;
+ }
+ String sPosition( ScAddress( nDocCol, nDocRow, nTab).GetColRowString());
+ String sEncoding( SvxTextEncodingTable().GetTextString( eCharSet));
+ nErr = *new TwoStringErrorInfo( (bEncErr ? SCERR_EXPORT_ENCODING :
+ SCERR_EXPORT_FIELDWIDTH), sPosition, sEncoding,
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR);
+ }
+ else if ( aException.Message.getLength() )
+ nErr = *new StringErrorInfo( (SCERR_EXPORT_SQLEXCEPTION), aException.Message, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR);
+ else
+ nErr = SCERR_EXPORT_DATA;
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in database");
+ nErr = ERRCODE_IO_GENERAL;
+ }
+
+ return nErr;
+}
+
+
diff --git a/sc/source/ui/docshell/docshimp.hxx b/sc/source/ui/docshell/docshimp.hxx
new file mode 100644
index 000000000000..6532c46d0835
--- /dev/null
+++ b/sc/source/ui/docshell/docshimp.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_DOCSHELLIMP_HXX
+#define SC_DOCSHELLIMP_HXX
+
+#include <svtools/ctrltool.hxx>
+#include <sfx2/docinsert.hxx>
+#include <sfx2/request.hxx>
+
+struct DocShell_Impl
+{
+ bool bIgnoreLostRedliningWarning;
+ FontList* pFontList;
+ sfx2::DocumentInserter* pDocInserter;
+ SfxRequest* pRequest;
+
+ DocShell_Impl() :
+ bIgnoreLostRedliningWarning( false )
+ , pFontList( NULL )
+ , pDocInserter( NULL )
+ , pRequest( NULL )
+ {}
+
+ ~DocShell_Impl()
+ {
+ delete pFontList;
+ delete pDocInserter;
+ delete pRequest;
+ }
+};
+
+#endif
+
diff --git a/sc/source/ui/docshell/editable.cxx b/sc/source/ui/docshell/editable.cxx
new file mode 100644
index 000000000000..d381ff067a99
--- /dev/null
+++ b/sc/source/ui/docshell/editable.cxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "editable.hxx"
+#include "document.hxx"
+#include "viewfunc.hxx"
+#include "globstr.hrc"
+
+//------------------------------------------------------------------
+
+ScEditableTester::ScEditableTester() :
+ bIsEditable( TRUE ),
+ bOnlyMatrix( TRUE )
+{
+}
+
+ScEditableTester::ScEditableTester( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) :
+ bIsEditable( TRUE ),
+ bOnlyMatrix( TRUE )
+{
+ TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+ScEditableTester::ScEditableTester( ScDocument* pDoc,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark ) :
+ bIsEditable( TRUE ),
+ bOnlyMatrix( TRUE )
+{
+ TestSelectedBlock( pDoc, nStartCol, nStartRow, nEndCol, nEndRow, rMark );
+}
+
+ScEditableTester::ScEditableTester( ScDocument* pDoc, const ScRange& rRange ) :
+ bIsEditable( TRUE ),
+ bOnlyMatrix( TRUE )
+{
+ TestRange( pDoc, rRange );
+}
+
+ScEditableTester::ScEditableTester( ScDocument* pDoc, const ScMarkData& rMark ) :
+ bIsEditable( TRUE ),
+ bOnlyMatrix( TRUE )
+{
+ TestSelection( pDoc, rMark );
+}
+
+ScEditableTester::ScEditableTester( ScViewFunc* pView ) :
+ bIsEditable( TRUE ),
+ bOnlyMatrix( TRUE )
+{
+ TestView( pView );
+}
+
+//------------------------------------------------------------------
+
+void ScEditableTester::TestBlock( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ if ( bIsEditable || bOnlyMatrix )
+ {
+ BOOL bThisMatrix;
+ if ( !pDoc->IsBlockEditable( nTab, nStartCol, nStartRow, nEndCol, nEndRow, &bThisMatrix ) )
+ {
+ bIsEditable = FALSE;
+ if ( !bThisMatrix )
+ bOnlyMatrix = FALSE;
+ }
+ }
+}
+
+void ScEditableTester::TestSelectedBlock( ScDocument* pDoc,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark )
+{
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+void ScEditableTester::TestRange( ScDocument* pDoc, const ScRange& rRange )
+{
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCTAB nStartTab = rRange.aStart.Tab();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nEndTab = rRange.aEnd.Tab();
+ for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
+ TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+void ScEditableTester::TestSelection( ScDocument* pDoc, const ScMarkData& rMark )
+{
+ if ( bIsEditable || bOnlyMatrix )
+ {
+ BOOL bThisMatrix;
+ if ( !pDoc->IsSelectionEditable( rMark, &bThisMatrix ) )
+ {
+ bIsEditable = FALSE;
+ if ( !bThisMatrix )
+ bOnlyMatrix = FALSE;
+ }
+ }
+}
+
+void ScEditableTester::TestView( ScViewFunc* pView )
+{
+ if ( bIsEditable || bOnlyMatrix )
+ {
+ BOOL bThisMatrix;
+ if ( !pView->SelectionEditable( &bThisMatrix ) )
+ {
+ bIsEditable = FALSE;
+ if ( !bThisMatrix )
+ bOnlyMatrix = FALSE;
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+USHORT ScEditableTester::GetMessageId() const
+{
+ if (bIsEditable)
+ return 0;
+ else if (bOnlyMatrix)
+ return STR_MATRIXFRAGMENTERR;
+ else
+ return STR_PROTECTIONERR;
+}
+
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
new file mode 100644
index 000000000000..ba39316768b7
--- /dev/null
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -0,0 +1,2456 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "externalrefmgr.hxx"
+#include "document.hxx"
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "address.hxx"
+#include "tablink.hxx"
+#include "docsh.hxx"
+#include "scextopt.hxx"
+#include "rangenam.hxx"
+#include "cell.hxx"
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+
+#include "sfx2/app.hxx"
+#include "sfx2/docfilt.hxx"
+#include "sfx2/docfile.hxx"
+#include "sfx2/fcontnr.hxx"
+#include "sfx2/sfxsids.hrc"
+#include "sfx2/objsh.hxx"
+#include "svl/broadcast.hxx"
+#include "svl/smplhint.hxx"
+#include "svl/itemset.hxx"
+#include "svl/stritem.hxx"
+#include "svl/urihelper.hxx"
+#include "svl/zformat.hxx"
+#include "sfx2/linkmgr.hxx"
+#include "tools/urlobj.hxx"
+#include "unotools/ucbhelper.hxx"
+
+#include <memory>
+#include <algorithm>
+
+#include <boost/scoped_ptr.hpp>
+
+using ::std::auto_ptr;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::std::vector;
+using ::std::find;
+using ::std::find_if;
+using ::std::distance;
+using ::std::pair;
+using ::std::list;
+using ::std::unary_function;
+using namespace formula;
+
+#define SRCDOC_LIFE_SPAN 6000 // 1 minute (in 100th of a sec)
+#define SRCDOC_SCAN_INTERVAL 1000*5 // every 5 seconds (in msec)
+
+namespace {
+
+class TabNameSearchPredicate : public unary_function<bool, ScExternalRefCache::TableName>
+{
+public:
+ explicit TabNameSearchPredicate(const String& rSearchName) :
+ maSearchName(ScGlobal::pCharClass->upper(rSearchName))
+ {
+ }
+
+ bool operator()(const ScExternalRefCache::TableName& rTabNameSet) const
+ {
+ // Ok, I'm doing case insensitive search here.
+ return rTabNameSet.maUpperName.Equals(maSearchName);
+ }
+
+private:
+ String maSearchName;
+};
+
+class FindSrcFileByName : public unary_function<ScExternalRefManager::SrcFileData, bool>
+{
+public:
+ FindSrcFileByName(const String& rMatchName) :
+ mrMatchName(rMatchName)
+ {
+ }
+
+ bool operator()(const ScExternalRefManager::SrcFileData& rSrcData) const
+ {
+ return rSrcData.maFileName.Equals(mrMatchName);
+ }
+
+private:
+ const String& mrMatchName;
+};
+
+class NotifyLinkListener : public unary_function<ScExternalRefManager::LinkListener*, void>
+{
+public:
+ NotifyLinkListener(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType) :
+ mnFileId(nFileId), meType(eType) {}
+
+ NotifyLinkListener(const NotifyLinkListener& r) :
+ mnFileId(r.mnFileId), meType(r.meType) {}
+
+ void operator() (ScExternalRefManager::LinkListener* p) const
+ {
+ p->notify(mnFileId, meType);
+ }
+private:
+ sal_uInt16 mnFileId;
+ ScExternalRefManager::LinkUpdateType meType;
+};
+
+struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void>
+{
+ void operator() (ScFormulaCell* pCell) const
+ {
+ // Check to make sure the cell really contains ocExternalRef.
+ // External names, external cell and range references all have a
+ // ocExternalRef token.
+ const ScTokenArray* pCode = pCell->GetCode();
+ if (!pCode->HasOpCode( ocExternalRef))
+ return;
+
+ ScTokenArray* pArray = pCell->GetCode();
+ if (pArray)
+ // Clear the error code, or a cell with error won't get re-compiled.
+ pArray->SetCodeError(0);
+
+ pCell->SetCompile(true);
+ pCell->CompileTokenArray();
+ pCell->SetDirty();
+ }
+};
+
+class RemoveFormulaCell : public unary_function<pair<const sal_uInt16, ScExternalRefManager::RefCellSet>, void>
+{
+public:
+ explicit RemoveFormulaCell(ScFormulaCell* p) : mpCell(p) {}
+ void operator() (pair<const sal_uInt16, ScExternalRefManager::RefCellSet>& r) const
+ {
+ r.second.erase(mpCell);
+ }
+private:
+ ScFormulaCell* mpCell;
+};
+
+class ConvertFormulaToStatic : public unary_function<ScFormulaCell*, void>
+{
+public:
+ explicit ConvertFormulaToStatic(ScDocument* pDoc) : mpDoc(pDoc) {}
+ void operator() (ScFormulaCell* pCell) const
+ {
+ ScAddress aPos = pCell->aPos;
+
+ // We don't check for empty cells because empty external cells are
+ // treated as having a value of 0.
+
+ if (pCell->IsValue())
+ {
+ // Turn this into value cell.
+ double fVal = pCell->GetValue();
+ mpDoc->PutCell(aPos, new ScValueCell(fVal));
+ }
+ else
+ {
+ // string cell otherwise.
+ String aVal;
+ pCell->GetString(aVal);
+ mpDoc->PutCell(aPos, new ScStringCell(aVal));
+ }
+ }
+private:
+ ScDocument* mpDoc;
+};
+
+}
+
+// ============================================================================
+
+ScExternalRefCache::Table::Table()
+ : meReferenced( REFERENCED_MARKED )
+ // Prevent accidental data loss due to lack of knowledge.
+{
+}
+
+ScExternalRefCache::Table::~Table()
+{
+}
+
+void ScExternalRefCache::Table::setReferencedFlag( ScExternalRefCache::Table::ReferencedFlag eFlag )
+{
+ meReferenced = eFlag;
+}
+
+void ScExternalRefCache::Table::setReferenced( bool 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 meReferenced != UNREFERENCED;
+}
+
+void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex, bool bSetCacheRange)
+{
+ using ::std::pair;
+ RowsDataType::iterator itrRow = maRows.find(nRow);
+ if (itrRow == maRows.end())
+ {
+ // This row does not exist yet.
+ pair<RowsDataType::iterator, bool> res = maRows.insert(
+ RowsDataType::value_type(nRow, RowDataType()));
+
+ if (!res.second)
+ return;
+
+ itrRow = res.first;
+ }
+
+ // Insert this token into the specified column location. I don't need to
+ // check for existing data. Just overwrite it.
+ RowDataType& rRow = itrRow->second;
+ ScExternalRefCache::Cell aCell;
+ aCell.mxToken = pToken;
+ aCell.mnFmtIndex = nFmtIndex;
+ rRow.insert(RowDataType::value_type(nCol, aCell));
+ if (bSetCacheRange)
+ setCachedCell(nCol, nRow);
+}
+
+ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex) const
+{
+ RowsDataType::const_iterator itrTable = maRows.find(nRow);
+ if (itrTable == maRows.end())
+ {
+ // this table doesn't have the specified row.
+ return getEmptyOrNullToken(nCol, nRow);
+ }
+
+ const RowDataType& rRowData = itrTable->second;
+ RowDataType::const_iterator itrRow = rRowData.find(nCol);
+ if (itrRow == rRowData.end())
+ {
+ // this row doesn't have the specified column.
+ return getEmptyOrNullToken(nCol, nRow);
+ }
+
+ const Cell& rCell = itrRow->second;
+ if (pnFmtIndex)
+ *pnFmtIndex = rCell.mnFmtIndex;
+
+ return rCell.mxToken;
+}
+
+bool ScExternalRefCache::Table::hasRow( SCROW nRow ) const
+{
+ RowsDataType::const_iterator itrRow = maRows.find(nRow);
+ return itrRow != maRows.end();
+}
+
+void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows, SCROW nLow, SCROW nHigh) const
+{
+ vector<SCROW> aRows;
+ aRows.reserve(maRows.size());
+ RowsDataType::const_iterator itr = maRows.begin(), itrEnd = maRows.end();
+ for (; itr != itrEnd; ++itr)
+ if (nLow <= itr->first && itr->first <= nHigh)
+ aRows.push_back(itr->first);
+
+ // hash map is not ordered, so we need to explicitly sort it.
+ ::std::sort(aRows.begin(), aRows.end());
+ rRows.swap(aRows);
+}
+
+::std::pair< SCROW, SCROW > ScExternalRefCache::Table::getRowRange() const
+{
+ ::std::pair< SCROW, SCROW > aRange( 0, 0 );
+ if( !maRows.empty() )
+ {
+ // iterate over entire container (hash map is not sorted by key)
+ RowsDataType::const_iterator itr = maRows.begin(), itrEnd = maRows.end();
+ aRange.first = itr->first;
+ aRange.second = itr->first + 1;
+ while( ++itr != itrEnd )
+ {
+ if( itr->first < aRange.first )
+ aRange.first = itr->first;
+ else if( itr->first >= aRange.second )
+ aRange.second = itr->first + 1;
+ }
+ }
+ return aRange;
+}
+
+void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols, SCCOL nLow, SCCOL nHigh) const
+{
+ RowsDataType::const_iterator itrRow = maRows.find(nRow);
+ if (itrRow == maRows.end())
+ // this table doesn't have the specified row.
+ return;
+
+ const RowDataType& rRowData = itrRow->second;
+ vector<SCCOL> aCols;
+ aCols.reserve(rRowData.size());
+ RowDataType::const_iterator itrCol = rRowData.begin(), itrColEnd = rRowData.end();
+ for (; itrCol != itrColEnd; ++itrCol)
+ if (nLow <= itrCol->first && itrCol->first <= nHigh)
+ aCols.push_back(itrCol->first);
+
+ // hash map is not ordered, so we need to explicitly sort it.
+ ::std::sort(aCols.begin(), aCols.end());
+ rCols.swap(aCols);
+}
+
+::std::pair< SCCOL, SCCOL > ScExternalRefCache::Table::getColRange( SCROW nRow ) const
+{
+ ::std::pair< SCCOL, SCCOL > aRange( 0, 0 );
+
+ RowsDataType::const_iterator itrRow = maRows.find( nRow );
+ if (itrRow == maRows.end())
+ // this table doesn't have the specified row.
+ return aRange;
+
+ const RowDataType& rRowData = itrRow->second;
+ if( !rRowData.empty() )
+ {
+ // iterate over entire container (hash map is not sorted by key)
+ RowDataType::const_iterator itr = rRowData.begin(), itrEnd = rRowData.end();
+ aRange.first = itr->first;
+ aRange.second = itr->first + 1;
+ while( ++itr != itrEnd )
+ {
+ if( itr->first < aRange.first )
+ aRange.first = itr->first;
+ else if( itr->first >= aRange.second )
+ aRange.second = itr->first + 1;
+ }
+ }
+ return aRange;
+}
+
+void ScExternalRefCache::Table::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const
+{
+ RowsDataType::const_iterator itrRow = maRows.begin(), itrRowEnd = maRows.end();
+ for (; itrRow != itrRowEnd; ++itrRow)
+ {
+ const RowDataType& rRowData = itrRow->second;
+ RowDataType::const_iterator itrCol = rRowData.begin(), itrColEnd = rRowData.end();
+ for (; itrCol != itrColEnd; ++itrCol)
+ {
+ const Cell& rCell = itrCol->second;
+ rNumFmts.push_back(rCell.mnFmtIndex);
+ }
+ }
+}
+
+const ScRangeList& ScExternalRefCache::Table::getCachedRanges() const
+{
+ return maCachedRanges;
+}
+
+bool ScExternalRefCache::Table::isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
+{
+ return maCachedRanges.In(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0));
+}
+
+void ScExternalRefCache::Table::setCachedCell(SCCOL nCol, SCROW nRow)
+{
+ setCachedCellRange(nCol, nRow, nCol, nRow);
+}
+
+void ScExternalRefCache::Table::setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
+{
+ ScRange aRange(nCol1, nRow1, 0, nCol2, nRow2, 0);
+ if (!maCachedRanges.Count())
+ maCachedRanges.Append(aRange);
+ else
+ maCachedRanges.Join(aRange);
+
+ String aStr;
+ maCachedRanges.Format(aStr, SCA_VALID);
+}
+
+void ScExternalRefCache::Table::setWholeTableCached()
+{
+ setCachedCellRange(0, 0, MAXCOL, MAXROW);
+}
+
+bool ScExternalRefCache::Table::isInCachedRanges(SCCOL nCol, SCROW nRow) const
+{
+ return maCachedRanges.In(ScRange(nCol, nRow, 0, nCol, nRow, 0));
+}
+
+ScExternalRefCache::TokenRef ScExternalRefCache::Table::getEmptyOrNullToken(
+ SCCOL nCol, SCROW nRow) const
+{
+ if (isInCachedRanges(nCol, nRow))
+ {
+ TokenRef p(new ScEmptyCellToken(false, false));
+ return p;
+ }
+ return TokenRef();
+}
+
+// ----------------------------------------------------------------------------
+
+ScExternalRefCache::TableName::TableName(const String& rUpper, const String& rReal) :
+ maUpperName(rUpper), maRealName(rReal)
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScExternalRefCache::CellFormat::CellFormat() :
+ mbIsSet(false), mnType(NUMBERFORMAT_ALL), mnIndex(0)
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScExternalRefCache::ScExternalRefCache()
+{
+}
+ScExternalRefCache::~ScExternalRefCache()
+{
+}
+
+const String* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const String& rTabName) const
+{
+ DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
+ if (itrDoc == maDocs.end())
+ {
+ // specified document is not cached.
+ return NULL;
+ }
+
+ const DocItem& rDoc = itrDoc->second;
+ TableNameIndexMap::const_iterator itrTabId = rDoc.maTableNameIndex.find(
+ ScGlobal::pCharClass->upper(rTabName));
+ if (itrTabId == rDoc.maTableNameIndex.end())
+ {
+ // the specified table is not in cache.
+ return NULL;
+ }
+
+ return &rDoc.maTableNames[itrTabId->second].maRealName;
+}
+
+const String* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const
+{
+ DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
+ if (itrDoc == maDocs.end())
+ {
+ // specified document is not cached.
+ return NULL;
+ }
+
+ const DocItem& rDoc = itrDoc->second;
+ NamePairMap::const_iterator itr = rDoc.maRealRangeNameMap.find(
+ ScGlobal::pCharClass->upper(rRangeName));
+ if (itr == rDoc.maRealRangeNameMap.end())
+ // range name not found.
+ return NULL;
+
+ return &itr->second;
+}
+
+ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
+ sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex)
+{
+ DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
+ if (itrDoc == maDocs.end())
+ {
+ // specified document is not cached.
+ return TokenRef();
+ }
+
+ const DocItem& rDoc = itrDoc->second;
+ TableNameIndexMap::const_iterator itrTabId = rDoc.maTableNameIndex.find(
+ ScGlobal::pCharClass->upper(rTabName));
+ if (itrTabId == rDoc.maTableNameIndex.end())
+ {
+ // the specified table is not in cache.
+ return TokenRef();
+ }
+
+ const TableTypeRef& pTableData = rDoc.maTables[itrTabId->second];
+ if (!pTableData.get())
+ {
+ // the table data is not instantiated yet.
+ return TokenRef();
+ }
+
+ return pTableData->getCell(nCol, nRow, pnFmtIndex);
+}
+
+ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
+ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
+{
+ DocDataType::iterator itrDoc = maDocs.find(nFileId);
+ if (itrDoc == maDocs.end())
+ // specified document is not cached.
+ return TokenArrayRef();
+
+ DocItem& rDoc = itrDoc->second;
+
+ TableNameIndexMap::iterator itrTabId = rDoc.maTableNameIndex.find(
+ ScGlobal::pCharClass->upper(rTabName));
+ if (itrTabId == rDoc.maTableNameIndex.end())
+ // the specified table is not in cache.
+ return TokenArrayRef();
+
+ const ScAddress& s = rRange.aStart;
+ const ScAddress& e = rRange.aEnd;
+
+ SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
+ SCCOL nCol1 = s.Col(), nCol2 = e.Col();
+ SCROW nRow1 = s.Row(), nRow2 = e.Row();
+
+ // Make sure I have all the tables cached.
+ size_t nTabFirstId = itrTabId->second;
+ size_t nTabLastId = nTabFirstId + nTab2 - nTab1;
+ if (nTabLastId >= rDoc.maTables.size())
+ // not all tables are cached.
+ return TokenArrayRef();
+
+ ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId));
+
+ RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find( aCacheRange);
+ if (itrRange != rDoc.maRangeArrays.end())
+ // Cache hit!
+ return itrRange->second;
+
+ ::boost::scoped_ptr<ScRange> pNewRange;
+ TokenArrayRef pArray;
+ bool bFirstTab = true;
+ for (size_t nTab = nTabFirstId; nTab <= nTabLastId; ++nTab)
+ {
+ TableTypeRef pTab = rDoc.maTables[nTab];
+ if (!pTab.get())
+ return TokenArrayRef();
+
+ SCCOL nDataCol1 = nCol1, nDataCol2 = nCol2;
+ SCROW nDataRow1 = nRow1, nDataRow2 = nRow2;
+
+ if (!pTab->isRangeCached(nDataCol1, nDataRow1, nDataCol2, nDataRow2))
+ {
+ // specified range is not entirely within cached ranges.
+ return TokenArrayRef();
+ }
+
+ ScMatrixRef xMat = new ScMatrix(
+ static_cast<SCSIZE>(nDataCol2-nDataCol1+1), static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
+
+#if 0
+ // TODO: Switch to this code block once we have support for sparsely-filled
+ // matrices in ScMatrix.
+
+ // Only fill non-empty cells, for better performance.
+ vector<SCROW> aRows;
+ pTab->getAllRows(aRows, nDataRow1, nDataRow2);
+ for (vector<SCROW>::const_iterator itr = aRows.begin(), itrEnd = aRows.end(); itr != itrEnd; ++itr)
+ {
+ SCROW nRow = *itr;
+ vector<SCCOL> aCols;
+ pTab->getAllCols(nRow, aCols, nDataCol1, nDataCol2);
+ for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end(); itrCol != itrColEnd; ++itrCol)
+ {
+ SCCOL nCol = *itrCol;
+ TokenRef pToken = pTab->getCell(nCol, nRow);
+ if (!pToken)
+ // This should never happen!
+ return TokenArrayRef();
+
+ SCSIZE nC = nCol - nDataCol1, nR = nRow - nDataRow1;
+ switch (pToken->GetType())
+ {
+ case svDouble:
+ xMat->PutDouble(pToken->GetDouble(), nC, nR);
+ break;
+ case svString:
+ xMat->PutString(pToken->GetString(), nC, nR);
+ break;
+ default:
+ ;
+ }
+ }
+ }
+#else
+ vector<SCROW> aRows;
+ pTab->getAllRows(aRows, nDataRow1, nDataRow2);
+ if (aRows.empty())
+ // Cache is empty.
+ return TokenArrayRef();
+ else
+ // Trim the column below the last non-empty row.
+ nDataRow2 = aRows.back();
+
+ // Empty all matrix elements first, and fill only non-empty elements.
+ for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
+ {
+ for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
+ {
+ TokenRef pToken = pTab->getCell(nCol, nRow);
+ SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
+ if (!pToken)
+ return TokenArrayRef();
+
+ switch (pToken->GetType())
+ {
+ case svDouble:
+ xMat->PutDouble(pToken->GetDouble(), nC, nR);
+ break;
+ case svString:
+ xMat->PutString(pToken->GetString(), nC, nR);
+ break;
+ default:
+ xMat->PutEmpty(nC, nR);
+ }
+ }
+ }
+#endif
+
+ if (!bFirstTab)
+ pArray->AddOpCode(ocSep);
+
+ ScMatrix* pMat2 = xMat;
+ ScMatrixToken aToken(pMat2);
+ if (!pArray)
+ pArray.reset(new ScTokenArray);
+ pArray->AddToken(aToken);
+
+ bFirstTab = false;
+
+ if (!pNewRange)
+ pNewRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
+ else
+ pNewRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
+ }
+
+ if (pNewRange)
+ rDoc.maRangeArrays.insert( RangeArrayMap::value_type(*pNewRange, pArray));
+ return pArray;
+}
+
+ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const String& rName)
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return TokenArrayRef();
+
+ RangeNameMap& rMap = pDoc->maRangeNames;
+ RangeNameMap::const_iterator itr = rMap.find(
+ ScGlobal::pCharClass->upper(rName));
+ if (itr == rMap.end())
+ return TokenArrayRef();
+
+ return itr->second;
+}
+
+void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray)
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return;
+
+ String aUpperName = ScGlobal::pCharClass->upper(rName);
+ RangeNameMap& rMap = pDoc->maRangeNames;
+ rMap.insert(RangeNameMap::value_type(aUpperName, pArray));
+ pDoc->maRealRangeNameMap.insert(NamePairMap::value_type(aUpperName, rName));
+}
+
+void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
+ TokenRef pToken, sal_uInt32 nFmtIndex)
+{
+ if (!isDocInitialized(nFileId))
+ return;
+
+ using ::std::pair;
+ DocItem* pDocItem = getDocItem(nFileId);
+ if (!pDocItem)
+ return;
+
+ DocItem& rDoc = *pDocItem;
+
+ // See if the table by this name already exists.
+ TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(
+ ScGlobal::pCharClass->upper(rTabName));
+ if (itrTabName == rDoc.maTableNameIndex.end())
+ // Table not found. Maybe the table name or the file id is wrong ???
+ return;
+
+ TableTypeRef& pTableData = rDoc.maTables[itrTabName->second];
+ if (!pTableData.get())
+ pTableData.reset(new Table);
+
+ pTableData->setCell(nCol, nRow, pToken, nFmtIndex);
+ pTableData->setCachedCell(nCol, nRow);
+}
+
+void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const vector<SingleRangeData>& rData,
+ TokenArrayRef pArray)
+{
+ using ::std::pair;
+ if (rData.empty() || !isDocInitialized(nFileId))
+ // nothing to cache
+ return;
+
+ // First, get the document item for the given file ID.
+ DocItem* pDocItem = getDocItem(nFileId);
+ if (!pDocItem)
+ return;
+
+ DocItem& rDoc = *pDocItem;
+
+ // Now, find the table position of the first table to cache.
+ const String& rFirstTabName = rData.front().maTableName;
+ TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(
+ ScGlobal::pCharClass->upper(rFirstTabName));
+ if (itrTabName == rDoc.maTableNameIndex.end())
+ {
+ // table index not found.
+ return;
+ }
+
+ size_t nTabFirstId = itrTabName->second;
+ SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
+ SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
+ vector<SingleRangeData>::const_iterator itrDataBeg = rData.begin(), itrDataEnd = rData.end();
+ for (vector<SingleRangeData>::const_iterator itrData = itrDataBeg; itrData != itrDataEnd; ++itrData)
+ {
+ size_t i = nTabFirstId + ::std::distance(itrDataBeg, itrData);
+ TableTypeRef& pTabData = rDoc.maTables[i];
+ if (!pTabData.get())
+ pTabData.reset(new Table);
+
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ {
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ {
+ SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
+ TokenRef pToken;
+ const ScMatrixRef& pMat = itrData->mpRangeData;
+ if (pMat->IsEmpty(nC, nR))
+ // Don't cache empty cells.
+ continue;
+
+ if (pMat->IsValue(nC, nR))
+ pToken.reset(new formula::FormulaDoubleToken(pMat->GetDouble(nC, nR)));
+ else if (pMat->IsString(nC, nR))
+ pToken.reset(new formula::FormulaStringToken(pMat->GetString(nC, nR)));
+
+ if (pToken)
+ // Don't mark this cell 'cached' here, for better performance.
+ pTabData->setCell(nCol, nRow, pToken, 0, false);
+ }
+ }
+ // Mark the whole range 'cached'.
+ pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2);
+ }
+
+ size_t nTabLastId = nTabFirstId + rRange.aEnd.Tab() - rRange.aStart.Tab();
+ ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId));
+
+ rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray));
+}
+
+bool ScExternalRefCache::isDocInitialized(sal_uInt16 nFileId)
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return false;
+
+ return pDoc->mbInitFromSource;
+}
+
+static bool lcl_getTableDataIndex(const ScExternalRefCache::TableNameIndexMap& rMap, const String& rName, size_t& rIndex)
+{
+ ScExternalRefCache::TableNameIndexMap::const_iterator itr = rMap.find(rName);
+ if (itr == rMap.end())
+ return false;
+
+ rIndex = itr->second;
+ return true;
+}
+
+void ScExternalRefCache::initializeDoc(sal_uInt16 nFileId, const vector<String>& rTabNames)
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return;
+
+ size_t n = rTabNames.size();
+
+ // table name list - the list must include all table names in the source
+ // document and only to be populated when loading the source document, not
+ // when loading cached data from, say, Excel XCT/CRN records.
+ vector<TableName> aNewTabNames;
+ aNewTabNames.reserve(n);
+ for (vector<String>::const_iterator itr = rTabNames.begin(), itrEnd = rTabNames.end();
+ itr != itrEnd; ++itr)
+ {
+ TableName aNameItem(ScGlobal::pCharClass->upper(*itr), *itr);
+ aNewTabNames.push_back(aNameItem);
+ }
+ pDoc->maTableNames.swap(aNewTabNames);
+
+ // data tables - preserve any existing data that may have been set during
+ // file import.
+ vector<TableTypeRef> aNewTables(n);
+ for (size_t i = 0; i < n; ++i)
+ {
+ size_t nIndex;
+ if (lcl_getTableDataIndex(pDoc->maTableNameIndex, pDoc->maTableNames[i].maUpperName, nIndex))
+ {
+ aNewTables[i] = pDoc->maTables[nIndex];
+ }
+ }
+ pDoc->maTables.swap(aNewTables);
+
+ // name index map
+ TableNameIndexMap aNewNameIndex;
+ for (size_t i = 0; i < n; ++i)
+ aNewNameIndex.insert(TableNameIndexMap::value_type(pDoc->maTableNames[i].maUpperName, i));
+ pDoc->maTableNameIndex.swap(aNewNameIndex);
+
+ pDoc->mbInitFromSource = true;
+}
+
+String ScExternalRefCache::getTableName(sal_uInt16 nFileId, size_t nCacheId) const
+{
+ if( DocItem* pDoc = getDocItem( nFileId ) )
+ if( nCacheId < pDoc->maTableNames.size() )
+ return pDoc->maTableNames[ nCacheId ].maRealName;
+ return EMPTY_STRING;
+}
+
+void ScExternalRefCache::getAllTableNames(sal_uInt16 nFileId, vector<String>& rTabNames) const
+{
+ rTabNames.clear();
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return;
+
+ size_t n = pDoc->maTableNames.size();
+ rTabNames.reserve(n);
+ for (vector<TableName>::const_iterator itr = pDoc->maTableNames.begin(), itrEnd = pDoc->maTableNames.end();
+ itr != itrEnd; ++itr)
+ rTabNames.push_back(itr->maRealName);
+}
+
+SCsTAB ScExternalRefCache::getTabSpan( sal_uInt16 nFileId, const String& rStartTabName, const String& rEndTabName ) const
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return -1;
+
+ vector<TableName>::const_iterator itrBeg = pDoc->maTableNames.begin();
+ vector<TableName>::const_iterator itrEnd = pDoc->maTableNames.end();
+
+ vector<TableName>::const_iterator itrStartTab = ::std::find_if( itrBeg, itrEnd,
+ TabNameSearchPredicate( rStartTabName));
+ if (itrStartTab == itrEnd)
+ return -1;
+
+ vector<TableName>::const_iterator itrEndTab = ::std::find_if( itrBeg, itrEnd,
+ TabNameSearchPredicate( rEndTabName));
+ if (itrEndTab == itrEnd)
+ return 0;
+
+ size_t nStartDist = ::std::distance( itrBeg, itrStartTab);
+ size_t nEndDist = ::std::distance( itrBeg, itrEndTab);
+ return nStartDist <= nEndDist ? static_cast<SCsTAB>(nEndDist - nStartDist + 1) : -static_cast<SCsTAB>(nStartDist - nEndDist + 1);
+}
+
+void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const
+{
+ using ::std::sort;
+ using ::std::unique;
+
+ vector<sal_uInt32> aNumFmts;
+ for (DocDataType::const_iterator itrDoc = maDocs.begin(), itrDocEnd = maDocs.end();
+ itrDoc != itrDocEnd; ++itrDoc)
+ {
+ const vector<TableTypeRef>& rTables = itrDoc->second.maTables;
+ for (vector<TableTypeRef>::const_iterator itrTab = rTables.begin(), itrTabEnd = rTables.end();
+ itrTab != itrTabEnd; ++itrTab)
+ {
+ TableTypeRef pTab = *itrTab;
+ if (!pTab)
+ continue;
+
+ pTab->getAllNumberFormats(aNumFmts);
+ }
+ }
+
+ // remove duplicates.
+ sort(aNumFmts.begin(), aNumFmts.end());
+ aNumFmts.erase(unique(aNumFmts.begin(), aNumFmts.end()), aNumFmts.end());
+ rNumFmts.swap(aNumFmts);
+}
+
+bool ScExternalRefCache::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return false;
+
+ String aUpperName = ScGlobal::pCharClass->upper(rTabName);
+ vector<TableName>::const_iterator itrBeg = pDoc->maTableNames.begin(), itrEnd = pDoc->maTableNames.end();
+ vector<TableName>::const_iterator itr = ::std::find_if(
+ itrBeg, itrEnd, TabNameSearchPredicate(aUpperName));
+
+ return itr != itrEnd;
+}
+
+size_t ScExternalRefCache::getCacheTableCount(sal_uInt16 nFileId) const
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ return pDoc ? pDoc->maTables.size() : 0;
+}
+
+bool ScExternalRefCache::setCacheDocReferenced( sal_uInt16 nFileId )
+{
+ DocItem* pDocItem = getDocItem(nFileId);
+ if (!pDocItem)
+ return areAllCacheTablesReferenced();
+
+ for (::std::vector<TableTypeRef>::iterator itrTab = pDocItem->maTables.begin();
+ itrTab != pDocItem->maTables.end(); ++itrTab)
+ {
+ if ((*itrTab).get())
+ (*itrTab)->setReferenced( true);
+ }
+ addCacheDocToReferenced( nFileId);
+ return areAllCacheTablesReferenced();
+}
+
+bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets, bool bPermanent )
+{
+ 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())
+ {
+ 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)
+ {
+ maReferenced.reset(0);
+ for (DocDataType::iterator itrDoc = maDocs.begin(); itrDoc != maDocs.end(); ++itrDoc)
+ {
+ ScExternalRefCache::DocItem& rDocItem = (*itrDoc).second;
+ for (::std::vector<TableTypeRef>::iterator itrTab = rDocItem.maTables.begin();
+ itrTab != rDocItem.maTables.end(); ++itrTab)
+ {
+ if ((*itrTab).get())
+ (*itrTab)->setReferenced( true);
+ }
+ }
+ }
+ else
+ {
+ size_t nDocs = 0;
+ for (DocDataType::const_iterator itrDoc = maDocs.begin(); itrDoc != maDocs.end(); ++itrDoc)
+ {
+ if (nDocs <= (*itrDoc).first)
+ nDocs = (*itrDoc).first + 1;
+ }
+ maReferenced.reset( nDocs);
+
+ for (DocDataType::iterator itrDoc = maDocs.begin(); itrDoc != maDocs.end(); ++itrDoc)
+ {
+ ScExternalRefCache::DocItem& rDocItem = (*itrDoc).second;
+ sal_uInt16 nFileId = (*itrDoc).first;
+ size_t nTables = rDocItem.maTables.size();
+ ReferencedStatus::DocReferenced & rDocReferenced = maReferenced.maDocs[nFileId];
+ // All referenced => non-existing tables evaluate as completed.
+ rDocReferenced.maTables.resize( nTables, true);
+ for (size_t i=0; i < nTables; ++i)
+ {
+ TableTypeRef & xTab = rDocItem.maTables[i];
+ if (xTab.get())
+ {
+ 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;
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScExternalRefCache::addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex )
+{
+ if (nFileId >= maReferenced.maDocs.size())
+ return;
+
+ ::std::vector<bool> & rTables = maReferenced.maDocs[nFileId].maTables;
+ size_t nTables = rTables.size();
+ if (nIndex >= nTables)
+ return;
+
+ if (!rTables[nIndex])
+ {
+ rTables[nIndex] = true;
+ size_t i = 0;
+ while (i < nTables && rTables[i])
+ ++i;
+ if (i == nTables)
+ {
+ maReferenced.maDocs[nFileId].mbAllTablesReferenced = true;
+ maReferenced.checkAllDocs();
+ }
+ }
+}
+
+void ScExternalRefCache::addCacheDocToReferenced( sal_uInt16 nFileId )
+{
+ if (nFileId >= maReferenced.maDocs.size())
+ return;
+
+ if (!maReferenced.maDocs[nFileId].mbAllTablesReferenced)
+ {
+ ::std::vector<bool> & rTables = maReferenced.maDocs[nFileId].maTables;
+ size_t nSize = rTables.size();
+ for (size_t i=0; i < nSize; ++i)
+ rTables[i] = true;
+ maReferenced.maDocs[nFileId].mbAllTablesReferenced = true;
+ maReferenced.checkAllDocs();
+ }
+}
+
+bool ScExternalRefCache::areAllCacheTablesReferenced() const
+{
+ return maReferenced.mbAllReferenced;
+}
+
+ScExternalRefCache::ReferencedStatus::ReferencedStatus() :
+ mbAllReferenced(false)
+{
+ reset(0);
+}
+
+ScExternalRefCache::ReferencedStatus::ReferencedStatus( size_t nDocs ) :
+ mbAllReferenced(false)
+{
+ reset( nDocs);
+}
+
+void ScExternalRefCache::ReferencedStatus::reset( size_t nDocs )
+{
+ if (nDocs)
+ {
+ mbAllReferenced = false;
+ DocReferencedVec aRefs( nDocs);
+ maDocs.swap( aRefs);
+ }
+ else
+ {
+ mbAllReferenced = true;
+ DocReferencedVec aRefs;
+ maDocs.swap( aRefs);
+ }
+}
+
+void ScExternalRefCache::ReferencedStatus::checkAllDocs()
+{
+ for (DocReferencedVec::const_iterator itr = maDocs.begin(); itr != maDocs.end(); ++itr)
+ {
+ if (!(*itr).mbAllTablesReferenced)
+ return;
+ }
+ mbAllReferenced = true;
+}
+
+ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc || nTabIndex >= pDoc->maTables.size())
+ return TableTypeRef();
+
+ return pDoc->maTables[nTabIndex];
+}
+
+ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex)
+{
+ // In API, the index is transported as cached sheet ID of type sal_Int32 in
+ // sheet::SingleReference.Sheet or sheet::ComplexReference.Reference1.Sheet
+ // in a sheet::FormulaToken, choose a sensible value for N/A. Effectively
+ // being 0xffffffff
+ const size_t nNotAvailable = static_cast<size_t>( static_cast<sal_Int32>( -1));
+
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ {
+ if (pnIndex) *pnIndex = nNotAvailable;
+ return TableTypeRef();
+ }
+
+ DocItem& rDoc = *pDoc;
+
+ size_t nIndex;
+ String aTabNameUpper = ScGlobal::pCharClass->upper(rTabName);
+ if (lcl_getTableDataIndex(rDoc.maTableNameIndex, aTabNameUpper, nIndex))
+ {
+ // specified table found.
+ if( pnIndex ) *pnIndex = nIndex;
+ if (bCreateNew && !rDoc.maTables[nIndex])
+ rDoc.maTables[nIndex].reset(new Table);
+
+ return rDoc.maTables[nIndex];
+ }
+
+ if (!bCreateNew)
+ {
+ if (pnIndex) *pnIndex = nNotAvailable;
+ return TableTypeRef();
+ }
+
+ // Specified table doesn't exist yet. Create one.
+ nIndex = rDoc.maTables.size();
+ if( pnIndex ) *pnIndex = nIndex;
+ TableTypeRef pTab(new Table);
+ rDoc.maTables.push_back(pTab);
+ rDoc.maTableNames.push_back(TableName(aTabNameUpper, rTabName));
+ rDoc.maTableNameIndex.insert(
+ TableNameIndexMap::value_type(aTabNameUpper, nIndex));
+ return pTab;
+}
+
+void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
+{
+ maDocs.erase(nFileId);
+}
+
+ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const
+{
+ using ::std::pair;
+ DocDataType::iterator itrDoc = maDocs.find(nFileId);
+ if (itrDoc == maDocs.end())
+ {
+ // specified document is not cached.
+ pair<DocDataType::iterator, bool> res = maDocs.insert(
+ DocDataType::value_type(nFileId, DocItem()));
+
+ if (!res.second)
+ // insertion failed.
+ return NULL;
+
+ itrDoc = res.first;
+ }
+
+ return &itrDoc->second;
+}
+
+// ============================================================================
+
+ScExternalRefLink::ScExternalRefLink(ScDocument* pDoc, sal_uInt16 nFileId, const String& rFilter) :
+ ::sfx2::SvBaseLink(::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE),
+ mnFileId(nFileId),
+ maFilterName(rFilter),
+ mpDoc(pDoc),
+ mbDoRefresh(true)
+{
+}
+
+ScExternalRefLink::~ScExternalRefLink()
+{
+}
+
+void ScExternalRefLink::Closed()
+{
+ ScExternalRefManager* pMgr = mpDoc->GetExternalRefManager();
+ pMgr->breakLink(mnFileId);
+}
+
+void ScExternalRefLink::DataChanged(const String& /*rMimeType*/, const Any& /*rValue*/)
+{
+ if (!mbDoRefresh)
+ return;
+
+ String aFile, aFilter;
+ mpDoc->GetLinkManager()->GetDisplayNames(this, NULL, &aFile, NULL, &aFilter);
+ ScExternalRefManager* pMgr = mpDoc->GetExternalRefManager();
+ const String* pCurFile = pMgr->getExternalFileName(mnFileId);
+ if (!pCurFile)
+ return;
+
+ if (pCurFile->Equals(aFile))
+ {
+ // Refresh the current source document.
+ pMgr->refreshNames(mnFileId);
+ }
+ else
+ {
+ // The source document has changed.
+ ScDocShell* pDocShell = ScDocShell::GetViewData()->GetDocShell();
+ ScDocShellModificator aMod(*pDocShell);
+ pMgr->switchSrcFile(mnFileId, aFile, aFilter);
+ maFilterName = aFilter;
+ aMod.SetDocumentModified();
+ }
+}
+
+void ScExternalRefLink::Edit(Window* pParent, const Link& /*rEndEditHdl*/)
+{
+ SvBaseLink::Edit(pParent, LINK(this, ScExternalRefLink, ExternalRefEndEditHdl));
+}
+
+void ScExternalRefLink::SetDoReferesh(bool b)
+{
+ mbDoRefresh = b;
+}
+
+IMPL_LINK( ScExternalRefLink, ExternalRefEndEditHdl, ::sfx2::SvBaseLink*, EMPTYARG )
+{
+ return 0;
+}
+
+// ============================================================================
+
+static FormulaToken* lcl_convertToToken(ScBaseCell* pCell)
+{
+ if (!pCell || pCell->HasEmptyData())
+ {
+ bool bInherited = (pCell && pCell->GetCellType() == CELLTYPE_FORMULA);
+ return new ScEmptyCellToken( bInherited, false);
+ }
+
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_EDIT:
+ {
+ String aStr;
+ static_cast<ScEditCell*>(pCell)->GetString(aStr);
+ return new formula::FormulaStringToken(aStr);
+ }
+ //break;
+ case CELLTYPE_STRING:
+ {
+ String aStr;
+ static_cast<ScStringCell*>(pCell)->GetString(aStr);
+ return new formula::FormulaStringToken(aStr);
+ }
+ //break;
+ case CELLTYPE_VALUE:
+ {
+ double fVal = static_cast<ScValueCell*>(pCell)->GetValue();
+ return new formula::FormulaDoubleToken(fVal);
+ }
+ //break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ USHORT nError = pFCell->GetErrCode();
+ if (nError)
+ return new FormulaErrorToken( nError);
+ else if (pFCell->IsValue())
+ {
+ double fVal = pFCell->GetValue();
+ return new formula::FormulaDoubleToken(fVal);
+ }
+ else
+ {
+ String aStr;
+ pFCell->GetString(aStr);
+ return new formula::FormulaStringToken(aStr);
+ }
+ }
+ //break;
+ default:
+ DBG_ERROR("attempted to convert an unknown cell type.");
+ }
+
+ return NULL;
+}
+
+static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, ScRange& rRange,
+ vector<ScExternalRefCache::SingleRangeData>& rCacheData)
+{
+ ScAddress& s = rRange.aStart;
+ ScAddress& e = rRange.aEnd;
+
+ SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
+ SCCOL nCol1 = s.Col(), nCol2 = e.Col();
+ SCROW nRow1 = s.Row(), nRow2 = e.Row();
+
+ if (nTab2 != nTab1)
+ // For now, we don't support multi-sheet ranges intentionally because
+ // we don't have a way to express them in a single token. In the
+ // future we can introduce a new stack variable type svMatrixList with
+ // a new token type that can store a 3D matrix value and convert a 3D
+ // range to it.
+ return NULL;
+
+ ::boost::scoped_ptr<ScRange> pUsedRange;
+
+ auto_ptr<ScTokenArray> pArray(new ScTokenArray);
+ bool bFirstTab = true;
+ vector<ScExternalRefCache::SingleRangeData>::iterator
+ itrCache = rCacheData.begin(), itrCacheEnd = rCacheData.end();
+
+ for (SCTAB nTab = nTab1; nTab <= nTab2 && itrCache != itrCacheEnd; ++nTab, ++itrCache)
+ {
+ // Only loop within the data area.
+ SCCOL nDataCol1 = nCol1, nDataCol2 = nCol2;
+ SCROW nDataRow1 = nRow1, nDataRow2 = nRow2;
+ bool bShrunk;
+ if (!pSrcDoc->ShrinkToUsedDataArea( bShrunk, nTab, nDataCol1, nDataRow1, nDataCol2, nDataRow2, false))
+ // no data within specified range.
+ continue;
+
+ if (pUsedRange.get())
+ // Make sure the used area only grows, not shrinks.
+ pUsedRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
+ else
+ pUsedRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
+
+ ScMatrixRef xMat = new ScMatrix(
+ static_cast<SCSIZE>(nDataCol2-nDataCol1+1),
+ static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
+
+ for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
+ {
+ for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
+ {
+ SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
+ ScBaseCell* pCell;
+ pSrcDoc->GetCell(nCol, nRow, nTab, pCell);
+ if (!pCell || pCell->HasEmptyData())
+ xMat->PutEmpty(nC, nR);
+ else
+ {
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_EDIT:
+ {
+ String aStr;
+ static_cast<ScEditCell*>(pCell)->GetString(aStr);
+ xMat->PutString(aStr, nC, nR);
+ }
+ break;
+ case CELLTYPE_STRING:
+ {
+ String aStr;
+ static_cast<ScStringCell*>(pCell)->GetString(aStr);
+ xMat->PutString(aStr, nC, nR);
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ double fVal = static_cast<ScValueCell*>(pCell)->GetValue();
+ xMat->PutDouble(fVal, nC, nR);
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ USHORT nError = pFCell->GetErrCode();
+ if (nError)
+ xMat->PutDouble( CreateDoubleError( nError), nC, nR);
+ else if (pFCell->IsValue())
+ {
+ double fVal = pFCell->GetValue();
+ xMat->PutDouble(fVal, nC, nR);
+ }
+ else
+ {
+ String aStr;
+ pFCell->GetString(aStr);
+ xMat->PutString(aStr, nC, nR);
+ }
+ }
+ break;
+ default:
+ DBG_ERROR("attempted to convert an unknown cell type.");
+ }
+ }
+ }
+ }
+ if (!bFirstTab)
+ pArray->AddOpCode(ocSep);
+
+ ScMatrix* pMat2 = xMat;
+ ScMatrixToken aToken(pMat2);
+ pArray->AddToken(aToken);
+
+ itrCache->mpRangeData = xMat;
+
+ bFirstTab = false;
+ }
+
+ if (!pUsedRange.get())
+ return NULL;
+
+ s.SetCol(pUsedRange->aStart.Col());
+ s.SetRow(pUsedRange->aStart.Row());
+ e.SetCol(pUsedRange->aEnd.Col());
+ e.SetRow(pUsedRange->aEnd.Row());
+
+ return pArray.release();
+}
+
+static ScTokenArray* lcl_fillEmptyMatrix(const ScRange& rRange)
+{
+ SCSIZE nC = static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1);
+ SCSIZE nR = static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1);
+ ScMatrixRef xMat = new ScMatrix(nC, nR);
+ for (SCSIZE i = 0; i < nC; ++i)
+ for (SCSIZE j = 0; j < nR; ++j)
+ xMat->PutEmpty(i, j);
+
+ ScMatrix* pMat2 = xMat;
+ ScMatrixToken aToken(pMat2);
+ auto_ptr<ScTokenArray> pArray(new ScTokenArray);
+ pArray->AddToken(aToken);
+ return pArray.release();
+}
+
+ScExternalRefManager::ScExternalRefManager(ScDocument* pDoc) :
+ mpDoc(pDoc),
+ mbInReferenceMarking(false),
+ mbUserInteractionEnabled(true)
+{
+ maSrcDocTimer.SetTimeoutHdl( LINK(this, ScExternalRefManager, TimeOutHdl) );
+ maSrcDocTimer.SetTimeout(SRCDOC_SCAN_INTERVAL);
+}
+
+ScExternalRefManager::~ScExternalRefManager()
+{
+ clear();
+}
+
+String ScExternalRefManager::getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const
+{
+ return maRefCache.getTableName(nFileId, nTabIndex);
+}
+
+ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
+{
+ return maRefCache.getCacheTable(nFileId, nTabIndex);
+}
+
+ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex)
+{
+ return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew, pnIndex);
+}
+
+// ============================================================================
+
+ScExternalRefManager::LinkListener::LinkListener()
+{
+}
+
+ScExternalRefManager::LinkListener::~LinkListener()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScExternalRefManager::ApiGuard::ApiGuard(ScDocument* pDoc) :
+ mpMgr(pDoc->GetExternalRefManager()),
+ mbOldInteractionEnabled(mpMgr->mbUserInteractionEnabled)
+{
+ // We don't want user interaction handled in the API.
+ mpMgr->mbUserInteractionEnabled = false;
+}
+
+ScExternalRefManager::ApiGuard::~ApiGuard()
+{
+ // Restore old value.
+ mpMgr->mbUserInteractionEnabled = mbOldInteractionEnabled;
+}
+
+// ----------------------------------------------------------------------------
+
+void ScExternalRefManager::getAllCachedTableNames(sal_uInt16 nFileId, vector<String>& rTabNames) const
+{
+ maRefCache.getAllTableNames(nFileId, rTabNames);
+}
+
+SCsTAB ScExternalRefManager::getCachedTabSpan( sal_uInt16 nFileId, const String& rStartTabName, const String& rEndTabName ) const
+{
+ return maRefCache.getTabSpan( nFileId, rStartTabName, rEndTabName);
+}
+
+void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmts) const
+{
+ maRefCache.getAllNumberFormats(rNumFmts);
+}
+
+bool ScExternalRefManager::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const
+{
+ return maRefCache.hasCacheTable(nFileId, rTabName);
+}
+
+size_t ScExternalRefManager::getCacheTableCount(sal_uInt16 nFileId) const
+{
+ return maRefCache.getCacheTableCount(nFileId);
+}
+
+sal_uInt16 ScExternalRefManager::getExternalFileCount() const
+{
+ return static_cast< sal_uInt16 >( maSrcFiles.size() );
+}
+
+bool ScExternalRefManager::markUsedByLinkListeners()
+{
+ bool bAllMarked = false;
+ for (LinkListenerMap::const_iterator itr = maLinkListeners.begin();
+ itr != maLinkListeners.end() && !bAllMarked; ++itr)
+ {
+ if (!(*itr).second.empty())
+ bAllMarked = maRefCache.setCacheDocReferenced( (*itr).first);
+ /* TODO: LinkListeners should remember the table they're listening to.
+ * As is, listening to one table will mark all tables of the document
+ * being referenced. */
+ }
+ return bAllMarked;
+}
+
+bool ScExternalRefManager::markUsedExternalRefCells()
+{
+ RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ RefCellSet::iterator itrCell = itr->second.begin(), itrCellEnd = itr->second.end();
+ for (; itrCell != itrCellEnd; ++itrCell)
+ {
+ ScFormulaCell* pCell = *itrCell;
+ bool bUsed = pCell->MarkUsedExternalReferences();
+ if (bUsed)
+ // Return true when at least one cell references external docs.
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ScExternalRefManager::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets )
+{
+ 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 )
+{
+ mbInReferenceMarking = !bReferenced;
+ maRefCache.setAllCacheTableReferencedStati( bReferenced );
+}
+
+void ScExternalRefManager::storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray)
+{
+ ScExternalRefCache::TokenArrayRef pArray(rArray.Clone());
+ maRefCache.setRangeNameTokens(nFileId, rName, pArray);
+}
+
+ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
+ sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell,
+ const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt)
+{
+ if (pCurPos)
+ insertRefCell(nFileId, *pCurPos);
+
+ maybeLinkExternalFile(nFileId);
+
+ if (pTab)
+ *pTab = -1;
+
+ if (pFmt)
+ pFmt->mbIsSet = false;
+
+ // Check if the given table name and the cell position is cached.
+ sal_uInt32 nFmtIndex = 0;
+ ScExternalRefCache::TokenRef pToken = maRefCache.getCellData(
+ nFileId, rTabName, rCell.Col(), rCell.Row(), &nFmtIndex);
+ if (pToken)
+ {
+ // Cache hit !
+ if (pFmt)
+ {
+ short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex);
+ if (nFmtType != NUMBERFORMAT_UNDEFINED)
+ {
+ pFmt->mbIsSet = true;
+ pFmt->mnIndex = nFmtIndex;
+ pFmt->mnType = nFmtType;
+ }
+ }
+ return pToken;
+ }
+
+ // reference not cached. read from the source document.
+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
+ if (!pSrcDoc)
+ {
+ // Source document not reachable. Throw a reference error.
+ pToken.reset(new FormulaErrorToken(errNoRef));
+ return pToken;
+ }
+
+ ScBaseCell* pCell = NULL;
+ SCTAB nTab;
+ if (!pSrcDoc->GetTable(rTabName, nTab))
+ {
+ // specified table name doesn't exist in the source document.
+ pToken.reset(new FormulaErrorToken(errNoRef));
+ return pToken;
+ }
+
+ if (pTab)
+ *pTab = nTab;
+
+ SCCOL nDataCol1 = 0, nDataCol2 = MAXCOL;
+ SCROW nDataRow1 = 0, nDataRow2 = MAXROW;
+ bool bData = pSrcDoc->ShrinkToDataArea(nTab, nDataCol1, nDataRow1, nDataCol2, nDataRow2);
+ if (!bData || rCell.Col() < nDataCol1 || nDataCol2 < rCell.Col() || rCell.Row() < nDataRow1 || nDataRow2 < rCell.Row())
+ {
+ // requested cell is outside the data area. Don't even bother caching
+ // this data, but add it to the cached range to prevent accessing the
+ // source document time and time again.
+ ScExternalRefCache::TableTypeRef pCacheTab =
+ maRefCache.getCacheTable(nFileId, rTabName, true, NULL);
+ if (pCacheTab)
+ pCacheTab->setCachedCell(rCell.Col(), rCell.Row());
+
+ pToken.reset(new ScEmptyCellToken(false, false));
+ return pToken;
+ }
+
+ pSrcDoc->GetCell(rCell.Col(), rCell.Row(), nTab, pCell);
+ ScExternalRefCache::TokenRef pTok(lcl_convertToToken(pCell));
+
+ pSrcDoc->GetNumberFormat(rCell.Col(), rCell.Row(), nTab, nFmtIndex);
+ nFmtIndex = getMappedNumberFormat(nFileId, nFmtIndex, pSrcDoc);
+ if (pFmt)
+ {
+ short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex);
+ if (nFmtType != NUMBERFORMAT_UNDEFINED)
+ {
+ pFmt->mbIsSet = true;
+ pFmt->mnIndex = nFmtIndex;
+ pFmt->mnType = nFmtType;
+ }
+ }
+
+ if (!pTok.get())
+ {
+ // Generate an error for unresolvable cells.
+ pTok.reset( new FormulaErrorToken( errNoValue));
+ }
+
+ // Now, insert the token into cache table but don't cache empty cells.
+ if (pTok->GetType() != formula::svEmptyCell)
+ maRefCache.setCellData(nFileId, rTabName, rCell.Col(), rCell.Row(), pTok, nFmtIndex);
+
+ return pTok;
+}
+
+ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
+ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
+{
+ if (pCurPos)
+ insertRefCell(nFileId, *pCurPos);
+
+ maybeLinkExternalFile(nFileId);
+
+ // Check if the given table name and the cell position is cached.
+ ScExternalRefCache::TokenArrayRef pArray =
+ maRefCache.getCellRangeData(nFileId, rTabName, rRange);
+ if (pArray)
+ // Cache hit !
+ return pArray;
+
+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
+ if (!pSrcDoc)
+ {
+ // Source document is not reachable. Throw a reference error.
+ pArray.reset(new ScTokenArray);
+ pArray->AddToken(FormulaErrorToken(errNoRef));
+ return pArray;
+ }
+
+ SCTAB nTab1;
+ if (!pSrcDoc->GetTable(rTabName, nTab1))
+ {
+ // specified table name doesn't exist in the source document.
+ pArray.reset(new ScTokenArray);
+ pArray->AddToken(FormulaErrorToken(errNoRef));
+ return pArray;
+ }
+
+ ScRange aRange(rRange);
+ SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab();
+
+ vector<ScExternalRefCache::SingleRangeData> aCacheData;
+ aCacheData.reserve(nTabSpan+1);
+ aCacheData.push_back(ScExternalRefCache::SingleRangeData());
+ aCacheData.back().maTableName = ScGlobal::pCharClass->upper(rTabName);
+
+ for (SCTAB i = 1; i < nTabSpan + 1; ++i)
+ {
+ String aTabName;
+ if (!pSrcDoc->GetName(nTab1 + 1, aTabName))
+ // source document doesn't have any table by the specified name.
+ break;
+
+ aCacheData.push_back(ScExternalRefCache::SingleRangeData());
+ aCacheData.back().maTableName = ScGlobal::pCharClass->upper(aTabName);
+ }
+
+ aRange.aStart.SetTab(nTab1);
+ aRange.aEnd.SetTab(nTab1 + nTabSpan);
+
+ pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData));
+
+ if (pArray)
+ // Cache these values.
+ maRefCache.setCellRangeData(nFileId, aRange, aCacheData, pArray);
+ else
+ {
+ // Array is empty. Fill it with an empty matrix of the required size.
+ pArray.reset(lcl_fillEmptyMatrix(rRange));
+
+ // Make sure to set this range 'cached', to prevent unnecessarily
+ // accessing the src document time and time again.
+ ScExternalRefCache::TableTypeRef pCacheTab =
+ maRefCache.getCacheTable(nFileId, rTabName, true, NULL);
+ if (pCacheTab)
+ pCacheTab->setCachedCellRange(
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
+ }
+
+ return pArray;
+}
+
+ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos)
+{
+ if (pCurPos)
+ insertRefCell(nFileId, *pCurPos);
+
+ maybeLinkExternalFile(nFileId);
+
+ ScExternalRefCache::TokenArrayRef pArray = maRefCache.getRangeNameTokens(nFileId, rName);
+ if (pArray.get())
+ return pArray;
+
+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
+ if (!pSrcDoc)
+ return ScExternalRefCache::TokenArrayRef();
+
+ ScRangeName* pExtNames = pSrcDoc->GetRangeName();
+ String aUpperName = ScGlobal::pCharClass->upper(rName);
+ USHORT n;
+ bool bRes = pExtNames->SearchNameUpper(aUpperName, n);
+ if (!bRes)
+ return ScExternalRefCache::TokenArrayRef();
+
+ ScRangeData* pRangeData = (*pExtNames)[n];
+ if (!pRangeData)
+ return ScExternalRefCache::TokenArrayRef();
+
+ // Parse all tokens in this external range data, and replace each absolute
+ // reference token with an external reference token, and cache them. Also
+ // register the source document with the link manager if it's a new
+ // source.
+
+ ScExternalRefCache::TokenArrayRef pNew(new ScTokenArray);
+
+ ScTokenArray* pCode = pRangeData->GetCode();
+ for (FormulaToken* pToken = pCode->First(); pToken; pToken = pCode->Next())
+ {
+ bool bTokenAdded = false;
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ {
+ const ScSingleRefData& rRef = static_cast<ScToken*>(pToken)->GetSingleRef();
+ String aTabName;
+ pSrcDoc->GetName(rRef.nTab, aTabName);
+ ScExternalSingleRefToken aNewToken(nFileId, aTabName, static_cast<ScToken*>(pToken)->GetSingleRef());
+ pNew->AddToken(aNewToken);
+ bTokenAdded = true;
+ }
+ break;
+ case svDoubleRef:
+ {
+ const ScSingleRefData& rRef = static_cast<ScToken*>(pToken)->GetSingleRef();
+ String aTabName;
+ pSrcDoc->GetName(rRef.nTab, aTabName);
+ ScExternalDoubleRefToken aNewToken(nFileId, aTabName, static_cast<ScToken*>(pToken)->GetDoubleRef());
+ pNew->AddToken(aNewToken);
+ bTokenAdded = true;
+ }
+ break;
+ default:
+ ; // nothing
+ }
+
+ if (!bTokenAdded)
+ pNew->AddToken(*pToken);
+ }
+
+ // Make sure to pass the correctly-cased range name here.
+ maRefCache.setRangeNameTokens(nFileId, pRangeData->GetName(), pNew);
+ return pNew;
+}
+
+void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
+{
+ RefCellMap::iterator itrFile = maRefCells.find(nFileId);
+ if (itrFile == maRefCells.end())
+ return;
+
+ RefCellSet& rRefCells = itrFile->second;
+ for_each(rRefCells.begin(), rRefCells.end(), UpdateFormulaCell());
+
+ ScViewData* pViewData = ScDocShell::GetViewData();
+ if (!pViewData)
+ return;
+
+ ScTabViewShell* pVShell = pViewData->GetViewShell();
+ if (!pVShell)
+ return;
+
+ // Repainting the grid also repaints the texts, but is there a better way
+ // to refresh texts?
+ pVShell->Invalidate(FID_REPAINT);
+ pVShell->PaintGrid();
+}
+
+void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell)
+{
+ RefCellMap::iterator itr = maRefCells.find(nFileId);
+ if (itr == maRefCells.end())
+ {
+ RefCellSet aRefCells;
+ pair<RefCellMap::iterator, bool> r = maRefCells.insert(
+ RefCellMap::value_type(nFileId, aRefCells));
+ if (!r.second)
+ // insertion failed.
+ return;
+
+ itr = r.first;
+ }
+
+ ScBaseCell* pCell = mpDoc->GetCell(rCell);
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ itr->second.insert(static_cast<ScFormulaCell*>(pCell));
+}
+
+ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
+{
+ if (!mpDoc->IsExecuteLinkEnabled())
+ return NULL;
+
+ DocShellMap::iterator itrEnd = maDocShells.end();
+ DocShellMap::iterator itr = maDocShells.find(nFileId);
+
+ if (itr != itrEnd)
+ {
+ // document already loaded.
+
+ // TODO: Find out a way to access a document that's already open in
+ // memory and re-use that instance, instead of loading it from the
+ // disk again.
+
+ SfxObjectShell* p = itr->second.maShell;
+ itr->second.maLastAccess = Time();
+ return static_cast<ScDocShell*>(p)->GetDocument();
+ }
+
+ const String* pFile = getExternalFileName(nFileId);
+ if (!pFile)
+ // no file name associated with this ID.
+ return NULL;
+
+ String aFilter;
+ SrcShell aSrcDoc;
+ aSrcDoc.maShell = loadSrcDocument(nFileId, aFilter);
+ if (!aSrcDoc.maShell.Is())
+ {
+ // source document could not be loaded.
+ return NULL;
+ }
+
+ if (maDocShells.empty())
+ {
+ // If this is the first source document insertion, start up the timer.
+ maSrcDocTimer.Start();
+ }
+
+ maDocShells.insert(DocShellMap::value_type(nFileId, aSrcDoc));
+ SfxObjectShell* p = aSrcDoc.maShell;
+ ScDocument* pSrcDoc = static_cast<ScDocShell*>(p)->GetDocument();
+
+ SCTAB nTabCount = pSrcDoc->GetTableCount();
+ if (!maRefCache.isDocInitialized(nFileId) && nTabCount)
+ {
+ // Populate the cache with all table names in the source document.
+ vector<String> aTabNames;
+ aTabNames.reserve(nTabCount);
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ String aName;
+ pSrcDoc->GetName(i, aName);
+ aTabNames.push_back(aName);
+ }
+ maRefCache.initializeDoc(nFileId, aTabNames);
+ }
+ return pSrcDoc;
+}
+
+SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, String& rFilter)
+{
+ const SrcFileData* pFileData = getExternalFileData(nFileId);
+ if (!pFileData)
+ return NULL;
+
+ // Always load the document by using the path created from the relative
+ // path. If the referenced document is not there, simply exit. The
+ // original file name should be used only when the relative path is not
+ // given.
+ String aFile = pFileData->maFileName;
+ maybeCreateRealFileName(nFileId);
+ if (pFileData->maRealFileName.Len())
+ aFile = pFileData->maRealFileName;
+
+ if (!isFileLoadable(aFile))
+ return NULL;
+
+ String aOptions( pFileData->maFilterOptions );
+ ScDocumentLoader::GetFilterName(aFile, rFilter, aOptions, true, false);
+ const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName(rFilter);
+
+ if (!pFileData->maRelativeName.Len())
+ {
+ // Generate a relative file path.
+ INetURLObject aBaseURL(getOwnDocumentName());
+ aBaseURL.insertName(OUString::createFromAscii("content.xml"));
+
+ String aStr = URIHelper::simpleNormalizedMakeRelative(
+ aBaseURL.GetMainURL(INetURLObject::NO_DECODE), aFile);
+
+ setRelativeFileName(nFileId, aStr);
+ }
+
+ SfxItemSet* pSet = new SfxAllItemSet(SFX_APP()->GetPool());
+ if (aOptions.Len())
+ pSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, aOptions));
+
+ // make medium hidden to prevent assertion from progress bar
+ pSet->Put( SfxBoolItem( SID_HIDDEN, TRUE ) );
+
+ auto_ptr<SfxMedium> pMedium(new SfxMedium(aFile, STREAM_STD_READ, false, pFilter, pSet));
+ if (pMedium->GetError() != ERRCODE_NONE)
+ return NULL;
+
+ // To load encrypted documents with password, user interaction needs to be enabled.
+ pMedium->UseInteractionHandler(mbUserInteractionEnabled);
+
+ ScDocShell* pNewShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL);
+ SfxObjectShellRef aRef = pNewShell;
+
+ // increment the recursive link count of the source document.
+ ScExtDocOptions* pExtOpt = mpDoc->GetExtDocOptions();
+ sal_uInt32 nLinkCount = pExtOpt ? pExtOpt->GetDocSettings().mnLinkCnt : 0;
+ ScDocument* pSrcDoc = pNewShell->GetDocument();
+ pSrcDoc->EnableExecuteLink(false); // to prevent circular access of external references.
+ pSrcDoc->EnableUndo(false);
+ pSrcDoc->EnableAdjustHeight(false);
+
+ ScExtDocOptions* pExtOptNew = pSrcDoc->GetExtDocOptions();
+ if (!pExtOptNew)
+ {
+ pExtOptNew = new ScExtDocOptions;
+ pSrcDoc->SetExtDocOptions(pExtOptNew);
+ }
+ pExtOptNew->GetDocSettings().mnLinkCnt = nLinkCount + 1;
+
+ pNewShell->DoLoad(pMedium.release());
+
+ // with UseInteractionHandler, options may be set by dialog during DoLoad
+ String aNew = ScDocumentLoader::GetOptions(*pNewShell->GetMedium());
+ if (aNew.Len() && aNew != aOptions)
+ aOptions = aNew;
+ setFilterData(nFileId, rFilter, aOptions); // update the filter data, including the new options
+
+ return aRef;
+}
+
+bool ScExternalRefManager::isFileLoadable(const String& rFile) const
+{
+ if (!rFile.Len())
+ return false;
+
+ if (isOwnDocument(rFile))
+ return false;
+
+ if (utl::UCBContentHelper::IsFolder(rFile))
+ return false;
+
+ return utl::UCBContentHelper::Exists(rFile);
+}
+
+void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId)
+{
+ if (maLinkedDocs.count(nFileId))
+ // file alerady linked, or the link has been broken.
+ return;
+
+ // Source document not linked yet. Link it now.
+ const String* pFileName = getExternalFileName(nFileId);
+ if (!pFileName)
+ return;
+
+ String aFilter, aOptions;
+ ScDocumentLoader::GetFilterName(*pFileName, aFilter, aOptions, true, false);
+ sfx2::LinkManager* pLinkMgr = mpDoc->GetLinkManager();
+ ScExternalRefLink* pLink = new ScExternalRefLink(mpDoc, nFileId, aFilter);
+ DBG_ASSERT(pFileName, "ScExternalRefManager::insertExternalFileLink: file name pointer is NULL");
+ pLinkMgr->InsertFileLink(*pLink, OBJECT_CLIENT_FILE, *pFileName, &aFilter);
+
+ pLink->SetDoReferesh(false);
+ pLink->Update();
+ pLink->SetDoReferesh(true);
+
+ maLinkedDocs.insert(LinkedDocMap::value_type(nFileId, true));
+}
+
+void ScExternalRefManager::SrcFileData::maybeCreateRealFileName(const String& rOwnDocName)
+{
+ if (!maRelativeName.Len())
+ // No relative path given. Nothing to do.
+ return;
+
+ if (maRealFileName.Len())
+ // Real file name already created. Nothing to do.
+ return;
+
+ // Formulate the absolute file path from the relative path.
+ const String& rRelPath = maRelativeName;
+ INetURLObject aBaseURL(rOwnDocName);
+ aBaseURL.insertName(OUString::createFromAscii("content.xml"));
+ bool bWasAbs = false;
+ maRealFileName = aBaseURL.smartRel2Abs(rRelPath, bWasAbs).GetMainURL(INetURLObject::NO_DECODE);
+}
+
+void ScExternalRefManager::maybeCreateRealFileName(sal_uInt16 nFileId)
+{
+ if (nFileId >= maSrcFiles.size())
+ return;
+
+ maSrcFiles[nFileId].maybeCreateRealFileName(getOwnDocumentName());
+}
+
+const String& ScExternalRefManager::getOwnDocumentName() const
+{
+ SfxObjectShell* pShell = mpDoc->GetDocumentShell();
+ if (!pShell)
+ // This should not happen!
+ return EMPTY_STRING;
+
+ SfxMedium* pMed = pShell->GetMedium();
+ if (!pMed)
+ return EMPTY_STRING;
+
+ return pMed->GetName();
+}
+
+bool ScExternalRefManager::isOwnDocument(const String& rFile) const
+{
+ return getOwnDocumentName().Equals(rFile);
+}
+
+void ScExternalRefManager::convertToAbsName(String& rFile) const
+{
+ SfxObjectShell* pDocShell = mpDoc->GetDocumentShell();
+ rFile = ScGlobal::GetAbsDocName(rFile, pDocShell);
+}
+
+sal_uInt16 ScExternalRefManager::getExternalFileId(const String& rFile)
+{
+ vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
+ vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
+ if (itr != itrEnd)
+ {
+ size_t nId = distance(itrBeg, itr);
+ return static_cast<sal_uInt16>(nId);
+ }
+
+ SrcFileData aData;
+ aData.maFileName = rFile;
+ maSrcFiles.push_back(aData);
+ return static_cast<sal_uInt16>(maSrcFiles.size() - 1);
+}
+
+const String* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal)
+{
+ if (nFileId >= maSrcFiles.size())
+ return NULL;
+
+ if (bForceOriginal)
+ return &maSrcFiles[nFileId].maFileName;
+
+ maybeCreateRealFileName(nFileId);
+
+ if (maSrcFiles[nFileId].maRealFileName.Len())
+ return &maSrcFiles[nFileId].maRealFileName;
+ else
+ return &maSrcFiles[nFileId].maFileName;
+}
+
+bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const
+{
+ return nFileId < maSrcFiles.size();
+}
+
+bool ScExternalRefManager::hasExternalFile(const String& rFile) const
+{
+ vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
+ vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
+ return itr != itrEnd;
+}
+
+const ScExternalRefManager::SrcFileData* ScExternalRefManager::getExternalFileData(sal_uInt16 nFileId) const
+{
+ if (nFileId >= maSrcFiles.size())
+ return NULL;
+
+ return &maSrcFiles[nFileId];
+}
+
+const String* ScExternalRefManager::getRealTableName(sal_uInt16 nFileId, const String& rTabName) const
+{
+ return maRefCache.getRealTableName(nFileId, rTabName);
+}
+
+const String* ScExternalRefManager::getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const
+{
+ return maRefCache.getRealRangeName(nFileId, rRangeName);
+}
+
+template<typename MapContainer>
+void lcl_removeByFileId(sal_uInt16 nFileId, MapContainer& rMap)
+{
+ typename MapContainer::iterator itr = rMap.find(nFileId);
+ if (itr != rMap.end())
+ rMap.erase(itr);
+}
+
+void ScExternalRefManager::refreshNames(sal_uInt16 nFileId)
+{
+ maRefCache.clearCache(nFileId);
+ lcl_removeByFileId(nFileId, maDocShells);
+
+ if (maDocShells.empty())
+ maSrcDocTimer.Stop();
+
+ // Update all cells containing names from this source document.
+ refreshAllRefCells(nFileId);
+
+ notifyAllLinkListeners(nFileId, LINK_MODIFIED);
+}
+
+void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
+{
+ // Turn all formula cells referencing this external document into static
+ // cells.
+ RefCellMap::iterator itrRefs = maRefCells.find(nFileId);
+ if (itrRefs != maRefCells.end())
+ {
+ // Make a copy because removing the formula cells below will modify
+ // the original container.
+ RefCellSet aSet = itrRefs->second;
+ for_each(aSet.begin(), aSet.end(), ConvertFormulaToStatic(mpDoc));
+ maRefCells.erase(nFileId);
+ }
+
+ lcl_removeByFileId(nFileId, maDocShells);
+
+ if (maDocShells.empty())
+ maSrcDocTimer.Stop();
+
+ LinkedDocMap::iterator itr = maLinkedDocs.find(nFileId);
+ if (itr != maLinkedDocs.end())
+ itr->second = false;
+
+ notifyAllLinkListeners(nFileId, LINK_BROKEN);
+}
+
+void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const String& rNewFile, const String& rNewFilter)
+{
+ maSrcFiles[nFileId].maFileName = rNewFile;
+ maSrcFiles[nFileId].maRelativeName.Erase();
+ maSrcFiles[nFileId].maRealFileName.Erase();
+ if (!maSrcFiles[nFileId].maFilterName.Equals(rNewFilter))
+ {
+ // Filter type has changed.
+ maSrcFiles[nFileId].maFilterName = rNewFilter;
+ maSrcFiles[nFileId].maFilterOptions.Erase();
+ }
+ refreshNames(nFileId);
+}
+
+void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const String& rRelUrl)
+{
+ if (nFileId >= maSrcFiles.size())
+ return;
+ maSrcFiles[nFileId].maRelativeName = rRelUrl;
+}
+
+void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const String& rFilterName, const String& rOptions)
+{
+ if (nFileId >= maSrcFiles.size())
+ return;
+ maSrcFiles[nFileId].maFilterName = rFilterName;
+ maSrcFiles[nFileId].maFilterOptions = rOptions;
+}
+
+void ScExternalRefManager::clear()
+{
+ DocShellMap::iterator itrEnd = maDocShells.end();
+ for (DocShellMap::iterator itr = maDocShells.begin(); itr != itrEnd; ++itr)
+ itr->second.maShell->DoClose();
+
+ maDocShells.clear();
+ maSrcDocTimer.Stop();
+}
+
+bool ScExternalRefManager::hasExternalData() const
+{
+ return !maSrcFiles.empty();
+}
+
+void ScExternalRefManager::resetSrcFileData(const String& rBaseFileUrl)
+{
+ for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
+ itr != itrEnd; ++itr)
+ {
+ // Re-generate relative file name from the absolute file name.
+ String aAbsName = itr->maRealFileName;
+ if (!aAbsName.Len())
+ aAbsName = itr->maFileName;
+
+ itr->maRelativeName = URIHelper::simpleNormalizedMakeRelative(
+ rBaseFileUrl, aAbsName);
+ }
+}
+
+void ScExternalRefManager::removeRefCell(ScFormulaCell* pCell)
+{
+ for_each(maRefCells.begin(), maRefCells.end(), RemoveFormulaCell(pCell));
+}
+
+void ScExternalRefManager::addLinkListener(sal_uInt16 nFileId, LinkListener* pListener)
+{
+ LinkListenerMap::iterator itr = maLinkListeners.find(nFileId);
+ if (itr == maLinkListeners.end())
+ {
+ pair<LinkListenerMap::iterator, bool> r = maLinkListeners.insert(
+ LinkListenerMap::value_type(nFileId, LinkListeners()));
+ if (!r.second)
+ {
+ DBG_ERROR("insertion of new link listener list failed");
+ return;
+ }
+
+ itr = r.first;
+ }
+
+ LinkListeners& rList = itr->second;
+ rList.insert(pListener);
+}
+
+void ScExternalRefManager::removeLinkListener(sal_uInt16 nFileId, LinkListener* pListener)
+{
+ LinkListenerMap::iterator itr = maLinkListeners.find(nFileId);
+ if (itr == maLinkListeners.end())
+ // no listeners for a specified file.
+ return;
+
+ LinkListeners& rList = itr->second;
+ rList.erase(pListener);
+
+ if (rList.empty())
+ // No more listeners for this file. Remove its entry.
+ maLinkListeners.erase(itr);
+}
+
+void ScExternalRefManager::removeLinkListener(LinkListener* pListener)
+{
+ LinkListenerMap::iterator itr = maLinkListeners.begin(), itrEnd = maLinkListeners.end();
+ for (; itr != itrEnd; ++itr)
+ itr->second.erase(pListener);
+}
+
+void ScExternalRefManager::notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdateType eType)
+{
+ LinkListenerMap::iterator itr = maLinkListeners.find(nFileId);
+ if (itr == maLinkListeners.end())
+ // no listeners for a specified file.
+ return;
+
+ LinkListeners& rList = itr->second;
+ for_each(rList.begin(), rList.end(), NotifyLinkListener(nFileId, eType));
+}
+
+void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
+{
+ DocShellMap aNewDocShells;
+ DocShellMap::iterator itr = maDocShells.begin(), itrEnd = maDocShells.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ // in 100th of a second.
+ sal_Int32 nSinceLastAccess = (Time() - itr->second.maLastAccess).GetTime();
+ if (nSinceLastAccess < nTimeOut)
+ aNewDocShells.insert(*itr);
+ }
+ maDocShells.swap(aNewDocShells);
+
+ if (maDocShells.empty())
+ maSrcDocTimer.Stop();
+}
+
+sal_uInt32 ScExternalRefManager::getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, ScDocument* pSrcDoc)
+{
+ NumFmtMap::iterator itr = maNumFormatMap.find(nFileId);
+ if (itr == maNumFormatMap.end())
+ {
+ // Number formatter map is not initialized for this external document.
+ pair<NumFmtMap::iterator, bool> r = maNumFormatMap.insert(
+ NumFmtMap::value_type(nFileId, SvNumberFormatterMergeMap()));
+
+ if (!r.second)
+ // insertion failed.
+ return nNumFmt;
+
+ itr = r.first;
+ mpDoc->GetFormatTable()->MergeFormatter( *pSrcDoc->GetFormatTable());
+ SvNumberFormatterMergeMap aMap = mpDoc->GetFormatTable()->ConvertMergeTableToMap();
+ itr->second.swap(aMap);
+ }
+ const SvNumberFormatterMergeMap& rMap = itr->second;
+ SvNumberFormatterMergeMap::const_iterator itrNumFmt = rMap.find(nNumFmt);
+ if (itrNumFmt != rMap.end())
+ // mapped value found.
+ return itrNumFmt->second;
+
+ return nNumFmt;
+}
+
+IMPL_LINK(ScExternalRefManager, TimeOutHdl, AutoTimer*, pTimer)
+{
+ if (pTimer == &maSrcDocTimer)
+ purgeStaleSrcDocument(SRCDOC_LIFE_SPAN);
+
+ return 0;
+}
+
diff --git a/sc/source/ui/docshell/hiranges.cxx b/sc/source/ui/docshell/hiranges.cxx
new file mode 100644
index 000000000000..af1226216a06
--- /dev/null
+++ b/sc/source/ui/docshell/hiranges.cxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "hiranges.hxx"
+
+//==================================================================
+
+ScHighlightRanges::ScHighlightRanges()
+{
+}
+
+ScHighlightRanges::~ScHighlightRanges()
+{
+ void* pEntry = aEntries.First();
+ while ( pEntry )
+ {
+ delete (ScHighlightEntry*) aEntries.Remove( pEntry );
+ pEntry = aEntries.Next();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
new file mode 100644
index 000000000000..a17279f409a9
--- /dev/null
+++ b/sc/source/ui/docshell/impex.cxx
@@ -0,0 +1,2094 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+class StarBASIC;
+
+
+
+#ifndef PCH
+#include "sc.hrc"
+#define GLOBALOVERFLOW
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <osl/endian.h>
+#include <i18npool/mslangid.hxx>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+#include <rtl/math.hxx>
+#include <svtools/htmlout.hxx>
+#include <svl/zforlist.hxx>
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#include <sot/formats.hxx>
+#include <sfx2/mieclip.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/calendarwrapper.hxx>
+#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docsh.hxx"
+#include "undoblk.hxx"
+#include "rangenam.hxx"
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "filter.hxx"
+#include "asciiopt.hxx"
+#include "cell.hxx"
+#include "docoptio.hxx"
+#include "progress.hxx"
+#include "scitems.hxx"
+#include "editable.hxx"
+#include "compiler.hxx"
+#include "warnbox.hxx"
+
+#include "impex.hxx"
+
+// ause
+#include "editutil.hxx"
+
+#include "globstr.hrc"
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/module.hxx>
+
+//========================================================================
+
+namespace
+{
+ const String SYLK_LF = String::CreateFromAscii("\x1b :");
+ const String DOUBLE_SEMICOLON = String::CreateFromAscii(";;");
+ const String DOUBLE_DOUBLEQUOTE = String::CreateFromAscii("\"\"");
+}
+
+enum SylkVersion
+{
+ SYLK_SCALC3, // Wrote wrongly quoted strings and unescaped semicolons.
+ SYLK_OOO32, // Correct strings, plus multiline content.
+ SYLK_OWN, // Place our new versions, if any, before this value.
+ SYLK_OTHER // Assume that aliens wrote correct strings.
+};
+
+
+// Gesamtdokument ohne Undo
+
+
+ScImportExport::ScImportExport( ScDocument* p )
+ : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
+ nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
+ bFormulas( FALSE ), bIncludeFiltered( TRUE ),
+ bAll( TRUE ), bSingle( TRUE ), bUndo( FALSE ),
+ bOverflow( FALSE ), mbApi( true ), mExportTextOptions()
+{
+ pUndoDoc = NULL;
+ pExtOptions = NULL;
+}
+
+// Insert am Punkt ohne Bereichschecks
+
+
+ScImportExport::ScImportExport( ScDocument* p, const ScAddress& rPt )
+ : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
+ aRange( rPt ),
+ nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
+ bFormulas( FALSE ), bIncludeFiltered( TRUE ),
+ bAll( FALSE ), bSingle( TRUE ), bUndo( BOOL( pDocSh != NULL ) ),
+ bOverflow( FALSE ), mbApi( true ), mExportTextOptions()
+{
+ pUndoDoc = NULL;
+ pExtOptions = NULL;
+}
+
+
+// ctor with a range is only used for export
+//! ctor with a string (and bSingle=TRUE) is also used for DdeSetData
+
+ScImportExport::ScImportExport( ScDocument* p, const ScRange& r )
+ : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
+ aRange( r ),
+ nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
+ bFormulas( FALSE ), bIncludeFiltered( TRUE ),
+ bAll( FALSE ), bSingle( FALSE ), bUndo( BOOL( pDocSh != NULL ) ),
+ bOverflow( FALSE ), mbApi( true ), mExportTextOptions()
+{
+ pUndoDoc = NULL;
+ pExtOptions = NULL;
+ // Zur Zeit nur in einer Tabelle!
+ aRange.aEnd.SetTab( aRange.aStart.Tab() );
+}
+
+// String auswerten: Entweder Bereich, Punkt oder Gesamtdoc (bei Fehler)
+// Falls eine View existiert, wird die TabNo der View entnommen!
+
+
+ScImportExport::ScImportExport( ScDocument* p, const String& rPos )
+ : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
+ nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
+ bFormulas( FALSE ), bIncludeFiltered( TRUE ),
+ bAll( FALSE ), bSingle( TRUE ), bUndo( BOOL( pDocSh != NULL ) ),
+ bOverflow( FALSE ), mbApi( true ), mExportTextOptions()
+{
+ pUndoDoc = NULL;
+ pExtOptions = NULL;
+
+ SCTAB nTab = ScDocShell::GetCurTab();
+ aRange.aStart.SetTab( nTab );
+ String aPos( rPos );
+ // Benannter Bereich?
+ ScRangeName* pRange = pDoc->GetRangeName();
+ if( pRange )
+ {
+ USHORT nPos;
+ if( pRange->SearchName( aPos, nPos ) )
+ {
+ ScRangeData* pData = (*pRange)[ nPos ];
+ if( pData->HasType( RT_REFAREA )
+ || pData->HasType( RT_ABSAREA )
+ || pData->HasType( RT_ABSPOS ) )
+ pData->GetSymbol( aPos ); // mit dem Inhalt weitertesten
+ }
+ }
+ formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ // Bereich?
+ if( aRange.Parse( aPos, pDoc, eConv ) & SCA_VALID )
+ bSingle = FALSE;
+ // Zelle?
+ else if( aRange.aStart.Parse( aPos, pDoc, eConv ) & SCA_VALID )
+ aRange.aEnd = aRange.aStart;
+ else
+ bAll = TRUE;
+}
+
+
+ScImportExport::~ScImportExport()
+{
+ delete pUndoDoc;
+ delete pExtOptions;
+}
+
+
+void ScImportExport::SetExtOptions( const ScAsciiOptions& rOpt )
+{
+ if ( pExtOptions )
+ *pExtOptions = rOpt;
+ else
+ pExtOptions = new ScAsciiOptions( rOpt );
+
+ // "normale" Optionen uebernehmen
+
+ cSep = rOpt.GetFieldSeps().GetChar(0);
+ cStr = rOpt.GetTextSep();
+}
+
+
+BOOL ScImportExport::IsFormatSupported( ULONG nFormat )
+{
+ return BOOL( nFormat == FORMAT_STRING
+ || nFormat == SOT_FORMATSTR_ID_SYLK
+ || nFormat == SOT_FORMATSTR_ID_LINK
+ || nFormat == SOT_FORMATSTR_ID_HTML
+ || nFormat == SOT_FORMATSTR_ID_HTML_SIMPLE
+ || nFormat == SOT_FORMATSTR_ID_DIF );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Vorbereitung fuer Undo: Undo-Dokument erzeugen
+
+
+BOOL ScImportExport::StartPaste()
+{
+ if ( !bAll )
+ {
+ ScEditableTester aTester( pDoc, aRange );
+ if ( !aTester.IsEditable() )
+ {
+ InfoBox aInfoBox(Application::GetDefDialogParent(),
+ ScGlobal::GetRscString( aTester.GetMessageId() ) );
+ aInfoBox.Execute();
+ return FALSE;
+ }
+ }
+ if( bUndo && pDocSh && pDoc->IsUndoEnabled())
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
+ pDoc->CopyToDocument( aRange, IDF_ALL | IDF_NOCAPTIONS, FALSE, pUndoDoc );
+ }
+ return TRUE;
+}
+
+// Nachbereitung Insert: Undo/Redo-Aktionen erzeugen, Invalidate/Repaint
+
+
+void ScImportExport::EndPaste()
+{
+ BOOL bHeight = pDocSh && pDocSh->AdjustRowHeight(
+ aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab() );
+
+ if( pUndoDoc && pDoc->IsUndoEnabled() )
+ {
+ ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
+ pDoc->CopyToDocument( aRange, IDF_ALL | IDF_NOCAPTIONS, FALSE, pRedoDoc );
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( aRange.aStart.Tab() );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPaste( pDocSh,
+ aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), aDestMark,
+ pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) );
+ }
+ pUndoDoc = NULL;
+ if( pDocSh )
+ {
+ if (!bHeight)
+ pDocSh->PostPaint( aRange, PAINT_GRID ); // AdjustRowHeight paintet evtl. selber
+ pDocSh->SetDocumentModified();
+ }
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if ( pViewSh )
+ pViewSh->UpdateInputHandler();
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+#if 0
+BOOL ScImportExport::ImportData( SvData& rData )
+{
+ ULONG nFmt = rData.GetFormat();
+ if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE )
+ {
+ MSE40HTMLClipFormatObj aMSE40ClpObj;
+ if ( aMSE40ClpObj.GetData( rData ) )
+ {
+ SvStream* pStream = aMSE40ClpObj.GetStream();
+ return ImportStream( *pStream, nFmt );
+ }
+ return FALSE;
+ }
+ else
+ {
+ void* pMem;
+ ULONG nSize = rData.GetMinMemorySize();
+ rData.GetData( &pMem, TRANSFER_REFERENCE );
+ if( nFmt == FORMAT_STRING
+ || nFmt == FORMAT_RTF
+ || nFmt == SOT_FORMATSTR_ID_SYLK
+ || nFmt == SOT_FORMATSTR_ID_HTML
+ || nFmt == SOT_FORMATSTR_ID_DIF )
+ {
+ //! String? Unicode??
+
+ // Stringende ermitteln!
+ sal_Char* pBegin = (sal_Char*) pMem;
+ sal_Char* pEnd = (sal_Char*) pMem + nSize;
+
+ nSize = 0;
+ while( pBegin != pEnd && *pBegin != '\0' )
+ pBegin++, nSize++;
+ // #72909# MT says only STRING has to be zero-terminated
+ DBG_ASSERT( pBegin != pEnd || nFmt != FORMAT_STRING, "non zero-terminated String" )
+ }
+ SvMemoryStream aStrm( pMem, nSize, STREAM_READ );
+ return ImportStream( aStrm, nFmt );
+ }
+}
+
+#endif
+
+BOOL ScImportExport::ImportData( const String& /* rMimeType */,
+ const ::com::sun::star::uno::Any & /* rValue */ )
+{
+ DBG_ASSERT( !this, "Implementation is missing" );
+ return FALSE;
+}
+
+BOOL ScImportExport::ExportData( const String& rMimeType,
+ ::com::sun::star::uno::Any & rValue )
+{
+ SvMemoryStream aStrm;
+ // mba: no BaseURL for data exchange
+ if( ExportStream( aStrm, String(),
+ SotExchange::GetFormatIdFromMimeType( rMimeType ) ))
+ {
+ aStrm << (BYTE) 0;
+ rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
+ (sal_Int8*)aStrm.GetData(),
+ aStrm.Seek( STREAM_SEEK_TO_END ) );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL ScImportExport::ImportString( const ::rtl::OUString& rText, ULONG nFmt )
+{
+ switch ( nFmt )
+ {
+ // formats supporting unicode
+ case FORMAT_STRING :
+ {
+ ScImportStringStream aStrm( rText);
+ return ImportStream( aStrm, String(), nFmt );
+ // ImportStream must handle RTL_TEXTENCODING_UNICODE
+ }
+ //break;
+ default:
+ {
+ rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
+ ::rtl::OString aTmp( rText.getStr(), rText.getLength(), eEnc );
+ SvMemoryStream aStrm( (void*)aTmp.getStr(), aTmp.getLength() * sizeof(sal_Char), STREAM_READ );
+ aStrm.SetStreamCharSet( eEnc );
+ SetNoEndianSwap( aStrm ); //! no swapping in memory
+ return ImportStream( aStrm, String(), nFmt );
+ }
+ }
+}
+
+
+BOOL ScImportExport::ExportString( ::rtl::OUString& rText, ULONG nFmt )
+{
+ DBG_ASSERT( nFmt == FORMAT_STRING, "ScImportExport::ExportString: Unicode not supported for other formats than FORMAT_STRING" );
+ if ( nFmt != FORMAT_STRING )
+ {
+ rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
+ ByteString aTmp;
+ BOOL bOk = ExportByteString( aTmp, eEnc, nFmt );
+ rText = UniString( aTmp, eEnc );
+ return bOk;
+ }
+ // nSizeLimit not needed for OUString
+
+ SvMemoryStream aStrm;
+ aStrm.SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
+ SetNoEndianSwap( aStrm ); //! no swapping in memory
+ // mba: no BaseURL for data exc
+ if( ExportStream( aStrm, String(), nFmt ) )
+ {
+ aStrm << (sal_Unicode) 0;
+ aStrm.Seek( STREAM_SEEK_TO_END );
+
+ rText = rtl::OUString( (const sal_Unicode*) aStrm.GetData() );
+ return TRUE;
+ }
+ rText = rtl::OUString();
+ return FALSE;
+
+ // ExportStream must handle RTL_TEXTENCODING_UNICODE
+}
+
+
+BOOL ScImportExport::ExportByteString( ByteString& rText, rtl_TextEncoding eEnc, ULONG nFmt )
+{
+ DBG_ASSERT( eEnc != RTL_TEXTENCODING_UNICODE, "ScImportExport::ExportByteString: Unicode not supported" );
+ if ( eEnc == RTL_TEXTENCODING_UNICODE )
+ eEnc = gsl_getSystemTextEncoding();
+
+ if (!nSizeLimit)
+ nSizeLimit = STRING_MAXLEN;
+
+ SvMemoryStream aStrm;
+ aStrm.SetStreamCharSet( eEnc );
+ SetNoEndianSwap( aStrm ); //! no swapping in memory
+ // mba: no BaseURL for data exchange
+ if( ExportStream( aStrm, String(), nFmt ) )
+ {
+ aStrm << (sal_Char) 0;
+ aStrm.Seek( STREAM_SEEK_TO_END );
+ // Sicherheits-Check:
+ if( aStrm.Tell() <= (ULONG) STRING_MAXLEN )
+ {
+ rText = (const sal_Char*) aStrm.GetData();
+ return TRUE;
+ }
+ }
+ rText.Erase();
+ return FALSE;
+}
+
+
+BOOL ScImportExport::ImportStream( SvStream& rStrm, const String& rBaseURL, ULONG nFmt )
+{
+ if( nFmt == FORMAT_STRING )
+ {
+ if( ExtText2Doc( rStrm ) ) // pExtOptions auswerten
+ return TRUE;
+ }
+ if( nFmt == SOT_FORMATSTR_ID_SYLK )
+ {
+ if( Sylk2Doc( rStrm ) )
+ return TRUE;
+ }
+ if( nFmt == SOT_FORMATSTR_ID_DIF )
+ {
+ if( Dif2Doc( rStrm ) )
+ return TRUE;
+ }
+ if( nFmt == FORMAT_RTF )
+ {
+ if( RTF2Doc( rStrm, rBaseURL ) )
+ return TRUE;
+ }
+ if( nFmt == SOT_FORMATSTR_ID_LINK )
+ return TRUE; // Link-Import?
+ if ( nFmt == SOT_FORMATSTR_ID_HTML )
+ {
+ if( HTML2Doc( rStrm, rBaseURL ) )
+ return TRUE;
+ }
+ if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE )
+ {
+ MSE40HTMLClipFormatObj aMSE40ClpObj; // needed to skip the header data
+ SvStream* pHTML = aMSE40ClpObj.IsValid( rStrm );
+ if ( pHTML && HTML2Doc( *pHTML, rBaseURL ) )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL ScImportExport::ExportStream( SvStream& rStrm, const String& rBaseURL, ULONG nFmt )
+{
+ if( nFmt == FORMAT_STRING )
+ {
+ if( Doc2Text( rStrm ) )
+ return TRUE;
+ }
+ if( nFmt == SOT_FORMATSTR_ID_SYLK )
+ {
+ if( Doc2Sylk( rStrm ) )
+ return TRUE;
+ }
+ if( nFmt == SOT_FORMATSTR_ID_DIF )
+ {
+ if( Doc2Dif( rStrm ) )
+ return TRUE;
+ }
+ if( nFmt == SOT_FORMATSTR_ID_LINK && !bAll )
+ {
+ String aDocName;
+ if ( pDoc->IsClipboard() )
+ aDocName = ScGlobal::GetClipDocName();
+ else
+ {
+ SfxObjectShell* pShell = pDoc->GetDocumentShell();
+ if (pShell)
+ aDocName = pShell->GetTitle( SFX_TITLE_FULLNAME );
+ }
+
+ DBG_ASSERT( aDocName.Len(), "ClipBoard document has no name! :-/" );
+ if( aDocName.Len() )
+ {
+ String aRefName;
+ USHORT nFlags = SCA_VALID | SCA_TAB_3D;
+ if( bSingle )
+ aRange.aStart.Format( aRefName, nFlags, pDoc, pDoc->GetAddressConvention() );
+ else
+ {
+ if( aRange.aStart.Tab() != aRange.aEnd.Tab() )
+ nFlags |= SCA_TAB2_3D;
+ aRange.Format( aRefName, nFlags, pDoc );
+ }
+ String aAppName = Application::GetAppName();
+
+ WriteUnicodeOrByteString( rStrm, aAppName, TRUE );
+ WriteUnicodeOrByteString( rStrm, aDocName, TRUE );
+ WriteUnicodeOrByteString( rStrm, aRefName, TRUE );
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ rStrm << sal_Unicode(0);
+ else
+ rStrm << sal_Char(0);
+ return BOOL( rStrm.GetError() == SVSTREAM_OK );
+ }
+ }
+ if( nFmt == SOT_FORMATSTR_ID_HTML )
+ {
+ if( Doc2HTML( rStrm, rBaseURL ) )
+ return TRUE;
+ }
+ if( nFmt == FORMAT_RTF )
+ {
+ if( Doc2RTF( rStrm ) )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+//static
+void ScImportExport::WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, BOOL bZero )
+{
+ rtl_TextEncoding eEnc = rStrm.GetStreamCharSet();
+ if ( eEnc == RTL_TEXTENCODING_UNICODE )
+ {
+ if ( !IsEndianSwap( rStrm ) )
+ rStrm.Write( rString.GetBuffer(), rString.Len() * sizeof(sal_Unicode) );
+ else
+ {
+ const sal_Unicode* p = rString.GetBuffer();
+ const sal_Unicode* const pStop = p + rString.Len();
+ while ( p < pStop )
+ {
+ rStrm << *p;
+ }
+ }
+ if ( bZero )
+ rStrm << sal_Unicode(0);
+ }
+ else
+ {
+ ByteString aByteStr( rString, eEnc );
+ rStrm << aByteStr.GetBuffer();
+ if ( bZero )
+ rStrm << sal_Char(0);
+ }
+}
+
+
+// This function could be replaced by endlub()
+// static
+void ScImportExport::WriteUnicodeOrByteEndl( SvStream& rStrm )
+{
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ { // same as endl() but unicode
+ switch ( rStrm.GetLineDelimiter() )
+ {
+ case LINEEND_CR :
+ rStrm << sal_Unicode(_CR);
+ break;
+ case LINEEND_LF :
+ rStrm << sal_Unicode(_LF);
+ break;
+ default:
+ rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
+ }
+ }
+ else
+ endl( rStrm );
+}
+
+
+enum DoubledQuoteMode
+{
+ DQM_KEEP, // both are taken
+ DQM_ESCAPE, // escaped quote, one is taken, one ignored
+ DQM_CONCAT, // first is end, next is start, both ignored => strings combined
+ DQM_SEPARATE // end one string and begin next
+};
+
+static const sal_Unicode* lcl_ScanString( const sal_Unicode* p, String& rString,
+ sal_Unicode cStr, DoubledQuoteMode eMode )
+{
+ p++; //! jump over opening quote
+ BOOL bCont;
+ do
+ {
+ bCont = FALSE;
+ const sal_Unicode* p0 = p;
+ for( ;; )
+ {
+ if( !*p )
+ break;
+ if( *p == cStr )
+ {
+ if ( *++p != cStr )
+ break;
+ // doubled quote char
+ switch ( eMode )
+ {
+ case DQM_KEEP :
+ p++; // both for us (not breaking for-loop)
+ break;
+ case DQM_ESCAPE :
+ p++; // one for us (breaking for-loop)
+ bCont = TRUE; // and more
+ break;
+ case DQM_CONCAT :
+ if ( p0+1 < p )
+ rString.Append( p0, sal::static_int_cast<xub_StrLen>( (p-1) - p0 ) ); // first part
+ p0 = ++p; // text of next part starts here
+ break;
+ case DQM_SEPARATE :
+ // positioned on next opening quote
+ break;
+ }
+ if ( eMode == DQM_ESCAPE || eMode == DQM_SEPARATE )
+ break;
+ }
+ else
+ p++;
+ }
+ if ( p0 < p )
+ rString.Append( p0, sal::static_int_cast<xub_StrLen>( ((*p || *(p-1) == cStr) ? p-1 : p) - p0 ) );
+ } while ( bCont );
+ return p;
+}
+
+void lcl_UnescapeSylk( String & rString, SylkVersion eVersion )
+{
+ // Older versions didn't escape the semicolon.
+ // Older versions quoted the string and doubled embedded quotes, but not
+ // the semicolons, which was plain wrong.
+ if (eVersion >= SYLK_OOO32)
+ rString.SearchAndReplaceAll( DOUBLE_SEMICOLON, ';' );
+ else
+ rString.SearchAndReplaceAll( DOUBLE_DOUBLEQUOTE, '"' );
+
+ rString.SearchAndReplaceAll( SYLK_LF, _LF );
+}
+
+static const sal_Unicode* lcl_ScanSylkString( const sal_Unicode* p,
+ String& rString, SylkVersion eVersion )
+{
+ const sal_Unicode* pStartQuote = p;
+ const sal_Unicode* pEndQuote = 0;
+ while( *(++p) )
+ {
+ if( *p == '"' )
+ {
+ pEndQuote = p;
+ if (eVersion >= SYLK_OOO32)
+ {
+ if (*(p+1) == ';')
+ {
+ if (*(p+2) == ';')
+ {
+ p += 2; // escaped ';'
+ pEndQuote = 0;
+ }
+ else
+ break; // end field
+ }
+ }
+ else
+ {
+ if (*(p+1) == '"')
+ {
+ ++p; // escaped '"'
+ pEndQuote = 0;
+ }
+ else if (*(p+1) == ';')
+ break; // end field
+ }
+ }
+ }
+ if (!pEndQuote)
+ pEndQuote = p; // Take all data as string.
+ rString.Append( pStartQuote + 1, sal::static_int_cast<xub_StrLen>( pEndQuote - pStartQuote - 1 ) );
+ lcl_UnescapeSylk( rString, eVersion);
+ return p;
+}
+
+static const sal_Unicode* lcl_ScanSylkFormula( const sal_Unicode* p,
+ String& rString, SylkVersion eVersion )
+{
+ const sal_Unicode* pStart = p;
+ if (eVersion >= SYLK_OOO32)
+ {
+ while (*p)
+ {
+ if (*p == ';')
+ {
+ if (*(p+1) == ';')
+ ++p; // escaped ';'
+ else
+ break; // end field
+ }
+ ++p;
+ }
+ rString.Append( pStart, sal::static_int_cast<xub_StrLen>( p - pStart));
+ lcl_UnescapeSylk( rString, eVersion);
+ }
+ else
+ {
+ // Nasty. If in old versions the formula contained a semicolon, it was
+ // quoted and embedded quotes were doubled, but semicolons were not. If
+ // there was no semicolon, it could still contain quotes and doubled
+ // embedded quotes if it was something like ="a""b", which was saved as
+ // E"a""b" as is and has to be preserved, even if older versions
+ // couldn't even load it correctly. However, theoretically another
+ // field might follow and thus the line contain a semicolon again, such
+ // as ...;E"a""b";...
+ bool bQuoted = false;
+ if (*p == '"')
+ {
+ // May be a quoted expression or just a string constant expression
+ // with quotes.
+ while (*(++p))
+ {
+ if (*p == '"')
+ {
+ if (*(p+1) == '"')
+ ++p; // escaped '"'
+ else
+ break; // closing '"', had no ';' yet
+ }
+ else if (*p == ';')
+ {
+ bQuoted = true; // ';' within quoted expression
+ break;
+ }
+ }
+ p = pStart;
+ }
+ if (bQuoted)
+ p = lcl_ScanSylkString( p, rString, eVersion);
+ else
+ {
+ while (*p && *p != ';')
+ ++p;
+ rString.Append( pStart, sal::static_int_cast<xub_StrLen>( p - pStart));
+ }
+ }
+ return p;
+}
+
+static void lcl_DoubleEscapeChar( String& rString, sal_Unicode cStr )
+{
+ xub_StrLen n = 0;
+ while( ( n = rString.Search( cStr, n ) ) != STRING_NOTFOUND )
+ {
+ rString.Insert( cStr, n );
+ n += 2;
+ }
+}
+
+static void lcl_WriteString( SvStream& rStrm, String& rString, sal_Unicode cQuote, sal_Unicode cEsc )
+{
+ if (cEsc)
+ lcl_DoubleEscapeChar( rString, cEsc );
+
+ if (cQuote)
+ {
+ rString.Insert( cQuote, 0 );
+ rString.Append( cQuote );
+ }
+
+ ScImportExport::WriteUnicodeOrByteString( rStrm, rString );
+}
+
+inline void lcl_WriteSimpleString( SvStream& rStrm, const String& rString )
+{
+ ScImportExport::WriteUnicodeOrByteString( rStrm, rString );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+BOOL ScImportExport::Text2Doc( SvStream& rStrm )
+{
+ BOOL bOk = TRUE;
+
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ ULONG nOldPos = rStrm.Tell();
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ rStrm.StartReadingUnicodeText();
+ BOOL bData = BOOL( !bSingle );
+ if( !bSingle)
+ bOk = StartPaste();
+
+ while( bOk )
+ {
+ ByteString aByteLine;
+ String aLine, aCell;
+ SCROW nRow = nStartRow;
+ rStrm.Seek( nOldPos );
+ for( ;; )
+ {
+ rStrm.ReadUniOrByteStringLine( aLine );
+ if( rStrm.IsEof() )
+ break;
+ SCCOL nCol = nStartCol;
+ const sal_Unicode* p = aLine.GetBuffer();
+ while( *p )
+ {
+ aCell.Erase();
+ if( *p == cStr )
+ {
+ p = lcl_ScanString( p, aCell, cStr, DQM_KEEP );
+ while( *p && *p != cSep )
+ p++;
+ if( *p )
+ p++;
+ }
+ else
+ {
+ const sal_Unicode* q = p;
+ while( *p && *p != cSep )
+ p++;
+ aCell.Assign( q, sal::static_int_cast<xub_StrLen>( p - q ) );
+ if( *p )
+ p++;
+ }
+ if (ValidCol(nCol) && ValidRow(nRow) )
+ {
+ if( bSingle )
+ {
+ if (nCol>nEndCol) nEndCol = nCol;
+ if (nRow>nEndRow) nEndRow = nRow;
+ }
+ if( bData && nCol <= nEndCol && nRow <= nEndRow )
+ pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aCell );
+ }
+ else // zuviele Spalten/Zeilen
+ bOverflow = TRUE; // beim Import Warnung ausgeben
+ ++nCol;
+ }
+ ++nRow;
+ }
+
+ if( !bData )
+ {
+ aRange.aEnd.SetCol( nEndCol );
+ aRange.aEnd.SetRow( nEndRow );
+ bOk = StartPaste();
+ bData = TRUE;
+ }
+ else
+ break;
+ }
+
+ EndPaste();
+ return bOk;
+}
+
+ //
+ // erweiterter Ascii-Import
+ //
+
+
+static bool lcl_PutString(
+ ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rStr, BYTE nColFormat,
+ SvNumberFormatter* pFormatter, bool bDetectNumFormat,
+ ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar,
+ ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar )
+{
+ bool bMultiLine = false;
+ if ( nColFormat == SC_COL_SKIP || !rStr.Len() || !ValidCol(nCol) || !ValidRow(nRow) )
+ return bMultiLine;
+
+ if ( nColFormat == SC_COL_TEXT )
+ {
+ pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( rStr, pDoc ) );
+ return bMultiLine;
+ }
+
+ if ( nColFormat == SC_COL_ENGLISH )
+ {
+ //! SetString mit Extra-Flag ???
+
+ SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable();
+ sal_uInt32 nEnglish = pDocFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
+ double fVal;
+ if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) )
+ {
+ // Zahlformat wird nicht auf englisch gesetzt
+ pDoc->SetValue( nCol, nRow, nTab, fVal );
+ return bMultiLine;
+ }
+ // sonst weiter mit SetString
+ }
+ else if ( nColFormat != SC_COL_STANDARD ) // Datumsformate
+ {
+ const USHORT nMaxNumberParts = 7; // Y-M-D h:m:s.t
+ xub_StrLen nLen = rStr.Len();
+ xub_StrLen nStart[nMaxNumberParts];
+ xub_StrLen nEnd[nMaxNumberParts];
+
+ USHORT nDP, nMP, nYP;
+ switch ( nColFormat )
+ {
+ case SC_COL_YMD: nDP = 2; nMP = 1; nYP = 0; break;
+ case SC_COL_MDY: nDP = 1; nMP = 0; nYP = 2; break;
+ case SC_COL_DMY:
+ default: nDP = 0; nMP = 1; nYP = 2; break;
+ }
+
+ USHORT nFound = 0;
+ BOOL bInNum = FALSE;
+ for ( xub_StrLen nPos=0; nPos<nLen && (bInNum ||
+ nFound<nMaxNumberParts); nPos++ )
+ {
+ if (bInNum && nFound == 3 && nColFormat == SC_COL_YMD &&
+ nPos <= nStart[nFound]+2 && rStr.GetChar(nPos) == 'T')
+ bInNum = FALSE; // ISO-8601: YYYY-MM-DDThh:mm...
+ else if ((((!bInNum && nFound==nMP) || (bInNum && nFound==nMP+1))
+ && ScGlobal::pCharClass->isLetterNumeric( rStr, nPos))
+ || ScGlobal::pCharClass->isDigit( rStr, nPos))
+ {
+ if (!bInNum)
+ {
+ bInNum = TRUE;
+ nStart[nFound] = nPos;
+ ++nFound;
+ }
+ nEnd[nFound-1] = nPos;
+ }
+ else
+ bInNum = FALSE;
+ }
+
+ if ( nFound == 1 )
+ {
+ // try to break one number (without separators) into date fields
+
+ xub_StrLen nDateStart = nStart[0];
+ xub_StrLen nDateLen = nEnd[0] + 1 - nDateStart;
+
+ if ( nDateLen >= 5 && nDateLen <= 8 &&
+ ScGlobal::pCharClass->isNumeric( rStr.Copy( nDateStart, nDateLen ) ) )
+ {
+ // 6 digits: 2 each for day, month, year
+ // 8 digits: 4 for year, 2 each for day and month
+ // 5 or 7 digits: first field is shortened by 1
+
+ BOOL bLongYear = ( nDateLen >= 7 );
+ BOOL bShortFirst = ( nDateLen == 5 || nDateLen == 7 );
+
+ USHORT nFieldStart = nDateStart;
+ for (USHORT nPos=0; nPos<3; nPos++)
+ {
+ USHORT nFieldEnd = nFieldStart + 1; // default: 2 digits
+ if ( bLongYear && nPos == nYP )
+ nFieldEnd += 2; // 2 extra digits for long year
+ if ( bShortFirst && nPos == 0 )
+ --nFieldEnd; // first field shortened?
+
+ nStart[nPos] = nFieldStart;
+ nEnd[nPos] = nFieldEnd;
+ nFieldStart = nFieldEnd + 1;
+ }
+ nFound = 3;
+ }
+ }
+
+ if ( nFound >= 3 )
+ {
+ using namespace ::com::sun::star;
+ BOOL bSecondCal = FALSE;
+ USHORT nDay = (USHORT) rStr.Copy( nStart[nDP], nEnd[nDP]+1-nStart[nDP] ).ToInt32();
+ USHORT nYear = (USHORT) rStr.Copy( nStart[nYP], nEnd[nYP]+1-nStart[nYP] ).ToInt32();
+ String aMStr = rStr.Copy( nStart[nMP], nEnd[nMP]+1-nStart[nMP] );
+ sal_Int16 nMonth = (sal_Int16) aMStr.ToInt32();
+ if (!nMonth)
+ {
+ static const String aSeptCorrect( RTL_CONSTASCII_USTRINGPARAM( "SEPT" ) );
+ static const String aSepShortened( RTL_CONSTASCII_USTRINGPARAM( "SEP" ) );
+ uno::Sequence< i18n::CalendarItem > xMonths;
+ sal_Int32 i, nMonthCount;
+ // first test all month names from local international
+ xMonths = rCalendar.getMonths();
+ nMonthCount = xMonths.getLength();
+ for (i=0; i<nMonthCount && !nMonth; i++)
+ {
+ if ( rTransliteration.isEqual( aMStr, xMonths[i].FullName ) ||
+ rTransliteration.isEqual( aMStr, xMonths[i].AbbrevName ) )
+ nMonth = sal::static_int_cast<sal_Int16>( i+1 );
+ else if ( i == 8 && rTransliteration.isEqual( aSeptCorrect,
+ xMonths[i].AbbrevName ) &&
+ rTransliteration.isEqual( aMStr, aSepShortened ) )
+ { // #102136# correct English abbreviation is SEPT,
+ // but data mostly contains SEP only
+ nMonth = sal::static_int_cast<sal_Int16>( i+1 );
+ }
+ }
+ // if none found, then test english month names
+ if ( !nMonth && pSecondCalendar && pSecondTransliteration )
+ {
+ xMonths = pSecondCalendar->getMonths();
+ nMonthCount = xMonths.getLength();
+ for (i=0; i<nMonthCount && !nMonth; i++)
+ {
+ if ( pSecondTransliteration->isEqual( aMStr, xMonths[i].FullName ) ||
+ pSecondTransliteration->isEqual( aMStr, xMonths[i].AbbrevName ) )
+ {
+ nMonth = sal::static_int_cast<sal_Int16>( i+1 );
+ bSecondCal = TRUE;
+ }
+ else if ( i == 8 && pSecondTransliteration->isEqual(
+ aMStr, aSepShortened ) )
+ { // #102136# correct English abbreviation is SEPT,
+ // but data mostly contains SEP only
+ nMonth = sal::static_int_cast<sal_Int16>( i+1 );
+ bSecondCal = TRUE;
+ }
+ }
+ }
+ }
+
+ SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable();
+ if ( nYear < 100 )
+ nYear = pDocFormatter->ExpandTwoDigitYear( nYear );
+
+ CalendarWrapper* pCalendar = (bSecondCal ? pSecondCalendar : &rCalendar);
+ sal_Int16 nNumMonths = pCalendar->getNumberOfMonthsInYear();
+ if ( nDay && nMonth && nDay<=31 && nMonth<=nNumMonths )
+ {
+ --nMonth;
+ pCalendar->setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDay );
+ pCalendar->setValue( i18n::CalendarFieldIndex::MONTH, nMonth );
+ pCalendar->setValue( i18n::CalendarFieldIndex::YEAR, nYear );
+ sal_Int16 nHour, nMinute, nSecond, nMilli;
+ // #i14974# The imported value should have no fractional value, so set the
+ // time fields to zero (ICU calendar instance defaults to current date/time)
+ nHour = nMinute = nSecond = nMilli = 0;
+ if (nFound > 3)
+ nHour = (sal_Int16) rStr.Copy( nStart[3], nEnd[3]+1-nStart[3]).ToInt32();
+ if (nFound > 4)
+ nMinute = (sal_Int16) rStr.Copy( nStart[4], nEnd[4]+1-nStart[4]).ToInt32();
+ if (nFound > 5)
+ nSecond = (sal_Int16) rStr.Copy( nStart[5], nEnd[5]+1-nStart[5]).ToInt32();
+ if (nFound > 6)
+ {
+ sal_Unicode cDec = '.';
+ rtl::OUString aT( &cDec, 1);
+ aT += rStr.Copy( nStart[6], nEnd[6]+1-nStart[6]);
+ rtl_math_ConversionStatus eStatus;
+ double fV = rtl::math::stringToDouble( aT, cDec, 0, &eStatus, 0);
+ if (eStatus == rtl_math_ConversionStatus_Ok)
+ nMilli = (sal_Int16) (1000.0 * fV + 0.5);
+ }
+ pCalendar->setValue( i18n::CalendarFieldIndex::HOUR, nHour );
+ pCalendar->setValue( i18n::CalendarFieldIndex::MINUTE, nMinute );
+ pCalendar->setValue( i18n::CalendarFieldIndex::SECOND, nSecond );
+ pCalendar->setValue( i18n::CalendarFieldIndex::MILLISECOND, nMilli );
+ if ( pCalendar->isValid() )
+ {
+ double fDiff = DateTime(*pDocFormatter->GetNullDate()) -
+ pCalendar->getEpochStart();
+ // #i14974# must use getLocalDateTime to get the same
+ // date values as set above
+ double fDays = pCalendar->getLocalDateTime();
+ fDays -= fDiff;
+
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ LanguageType eDocLang = eLatin; //! which language for date formats?
+
+ short nType = (nFound > 3 ? NUMBERFORMAT_DATETIME : NUMBERFORMAT_DATE);
+ ULONG nFormat = pDocFormatter->GetStandardFormat( nType, eDocLang );
+ // maybe there is a special format including seconds or milliseconds
+ if (nFound > 5)
+ nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang);
+
+ pDoc->PutCell( nCol, nRow, nTab, new ScValueCell(fDays), nFormat, FALSE );
+
+ return bMultiLine; // success
+ }
+ }
+ }
+ }
+
+ // Standard or date not determined -> SetString / EditCell
+ if( rStr.Search( _LF ) == STRING_NOTFOUND )
+ pDoc->SetString( nCol, nRow, nTab, rStr, pFormatter, bDetectNumFormat );
+ else
+ {
+ bMultiLine = true;
+ pDoc->PutCell( nCol, nRow, nTab, new ScEditCell( rStr, pDoc ) );
+ }
+ return bMultiLine;
+}
+
+
+String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext, bool& rbIsQuoted )
+{
+ xub_StrLen nLen = rLine.Len();
+ if (nNext > nLen)
+ nNext = nLen;
+ if ( nNext <= nStart )
+ return EMPTY_STRING;
+
+ const sal_Unicode* pStr = rLine.GetBuffer();
+
+ xub_StrLen nSpace = nNext;
+ while ( nSpace > nStart && pStr[nSpace-1] == ' ' )
+ --nSpace;
+
+ rbIsQuoted = (pStr[nStart] == sal_Unicode('"') && pStr[nSpace-1] == sal_Unicode('"'));
+ if (rbIsQuoted)
+ return rLine.Copy(nStart+1, nSpace-nStart-2);
+ else
+ return rLine.Copy(nStart, nSpace-nStart);
+}
+
+BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+{
+ if (!pExtOptions)
+ return Text2Doc( rStrm );
+
+ ULONG nOldPos = rStrm.Tell();
+ rStrm.Seek( STREAM_SEEK_TO_END );
+ ::std::auto_ptr<ScProgress> xProgress( new ScProgress( pDocSh,
+ ScGlobal::GetRscString( STR_LOAD_DOC ), rStrm.Tell() - nOldPos ));
+ rStrm.Seek( nOldPos );
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ rStrm.StartReadingUnicodeText();
+
+ BOOL bOld = ScColumn::bDoubleAlloc;
+ ScColumn::bDoubleAlloc = TRUE;
+
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCTAB nTab = aRange.aStart.Tab();
+
+ BOOL bFixed = pExtOptions->IsFixedLen();
+ const String& rSeps = pExtOptions->GetFieldSeps();
+ const sal_Unicode* pSeps = rSeps.GetBuffer();
+ BOOL bMerge = pExtOptions->IsMergeSeps();
+ USHORT nInfoCount = pExtOptions->GetInfoCount();
+ const xub_StrLen* pColStart = pExtOptions->GetColStart();
+ const BYTE* pColFormat = pExtOptions->GetColFormat();
+ long nSkipLines = pExtOptions->GetStartRow();
+
+ LanguageType eDocLang = pExtOptions->GetLanguage();
+ SvNumberFormatter aNumFormatter(pDoc->GetServiceManager(), eDocLang);
+ bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber();
+
+ // For date recognition
+ ::utl::TransliterationWrapper aTransliteration(
+ pDoc->GetServiceManager(), SC_TRANSLITERATION_IGNORECASE );
+ aTransliteration.loadModuleIfNeeded( eDocLang );
+ CalendarWrapper aCalendar( pDoc->GetServiceManager() );
+ aCalendar.loadDefaultCalendar(
+ MsLangId::convertLanguageToLocale( eDocLang ) );
+ ::utl::TransliterationWrapper* pEnglishTransliteration = NULL;
+ CalendarWrapper* pEnglishCalendar = NULL;
+ if ( eDocLang != LANGUAGE_ENGLISH_US )
+ {
+ pEnglishTransliteration = new ::utl::TransliterationWrapper (
+ pDoc->GetServiceManager(), SC_TRANSLITERATION_IGNORECASE );
+ aTransliteration.loadModuleIfNeeded( LANGUAGE_ENGLISH_US );
+ pEnglishCalendar = new CalendarWrapper ( pDoc->GetServiceManager() );
+ pEnglishCalendar->loadDefaultCalendar(
+ MsLangId::convertLanguageToLocale( LANGUAGE_ENGLISH_US ) );
+ }
+
+ String aLine, aCell;
+ USHORT i;
+ SCROW nRow = nStartRow;
+
+ while(--nSkipLines>0)
+ {
+ rStrm.ReadCsvLine( aLine, !bFixed, rSeps, cStr); // content is ignored
+ if ( rStrm.IsEof() )
+ break;
+ }
+
+ // Determine range for Undo.
+ // TODO: we don't need this during import of a file to a new sheet or
+ // document, could set bDetermineRange=false then.
+ bool bDetermineRange = true;
+
+ // Row heights don't need to be adjusted on the fly if EndPaste() is called
+ // afterwards, which happens only if bDetermineRange. This variable also
+ // survives the toggle of bDetermineRange down at the end of the do{} loop.
+ bool bRangeIsDetermined = bDetermineRange;
+
+ bool bQuotedAsText = pExtOptions && pExtOptions->IsQuotedAsText();
+
+ ULONG nOriginalStreamPos = rStrm.Tell();
+
+ do
+ {
+ for( ;; )
+ {
+ rStrm.ReadCsvLine( aLine, !bFixed, rSeps, cStr);
+ if ( rStrm.IsEof() )
+ break;
+
+ xub_StrLen nLineLen = aLine.Len();
+ SCCOL nCol = nStartCol;
+ bool bMultiLine = false;
+ if ( bFixed ) // Feste Satzlaenge
+ {
+ // Yes, the check is nCol<=MAXCOL+1, +1 because it is only an
+ // overflow if there is really data following to be put behind
+ // the last column, which doesn't happen if info is
+ // SC_COL_SKIP.
+ for ( i=0; i<nInfoCount && nCol <= MAXCOL+1; i++ )
+ {
+ BYTE nFmt = pColFormat[i];
+ if (nFmt != SC_COL_SKIP) // sonst auch nCol nicht hochzaehlen
+ {
+ if (nCol > MAXCOL)
+ bOverflow = TRUE; // display warning on import
+ else if (!bDetermineRange)
+ {
+ xub_StrLen nStart = pColStart[i];
+ xub_StrLen nNext = ( i+1 < nInfoCount ) ? pColStart[i+1] : nLineLen;
+ bool bIsQuoted = false;
+ aCell = lcl_GetFixed( aLine, nStart, nNext, bIsQuoted );
+ if (bIsQuoted && bQuotedAsText)
+ nFmt = SC_COL_TEXT;
+
+ bMultiLine |= lcl_PutString(
+ pDoc, nCol, nRow, nTab, aCell, nFmt,
+ &aNumFormatter, bDetectNumFormat, aTransliteration, aCalendar,
+ pEnglishTransliteration, pEnglishCalendar);
+ }
+ ++nCol;
+ }
+ }
+ }
+ else // Nach Trennzeichen suchen
+ {
+ SCCOL nSourceCol = 0;
+ USHORT nInfoStart = 0;
+ const sal_Unicode* p = aLine.GetBuffer();
+ // Yes, the check is nCol<=MAXCOL+1, +1 because it is only an
+ // overflow if there is really data following to be put behind
+ // the last column, which doesn't happen if info is
+ // SC_COL_SKIP.
+ while (*p && nCol <= MAXCOL+1)
+ {
+ bool bIsQuoted = false;
+ p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge, bIsQuoted );
+
+ BYTE nFmt = SC_COL_STANDARD;
+ for ( i=nInfoStart; i<nInfoCount; i++ )
+ {
+ if ( pColStart[i] == nSourceCol + 1 ) // pColStart ist 1-basiert
+ {
+ nFmt = pColFormat[i];
+ nInfoStart = i + 1; // ColInfos sind in Reihenfolge
+ break; // for
+ }
+ }
+ if ( nFmt != SC_COL_SKIP )
+ {
+ if (nCol > MAXCOL)
+ bOverflow = TRUE; // display warning on import
+ else if (!bDetermineRange)
+ {
+ if (bIsQuoted && bQuotedAsText)
+ nFmt = SC_COL_TEXT;
+
+ bMultiLine |= lcl_PutString(
+ pDoc, nCol, nRow, nTab, aCell, nFmt,
+ &aNumFormatter, bDetectNumFormat, aTransliteration,
+ aCalendar, pEnglishTransliteration, pEnglishCalendar);
+ }
+ ++nCol;
+ }
+
+ ++nSourceCol;
+ }
+ }
+ if (nEndCol < nCol)
+ nEndCol = nCol; //! points to the next free or even MAXCOL+2
+
+ if (!bDetermineRange)
+ {
+ if (bMultiLine && !bRangeIsDetermined && pDocSh)
+ pDocSh->AdjustRowHeight( nRow, nRow, nTab);
+ xProgress->SetStateOnPercent( rStrm.Tell() - nOldPos );
+ }
+ ++nRow;
+ if ( nRow > MAXROW )
+ {
+ bOverflow = TRUE; // display warning on import
+ break; // for
+ }
+ }
+ // so far nRow/nEndCol pointed to the next free
+ if (nRow > nStartRow)
+ --nRow;
+ if (nEndCol > nStartCol)
+ nEndCol = ::std::min( static_cast<SCCOL>(nEndCol - 1), MAXCOL);
+
+ if (bDetermineRange)
+ {
+ aRange.aEnd.SetCol( nEndCol );
+ aRange.aEnd.SetRow( nRow );
+
+ if ( !mbApi && nStartCol != nEndCol &&
+ !pDoc->IsBlockEmpty( nTab, nStartCol + 1, nStartRow, nEndCol, nRow ) )
+ {
+ ScReplaceWarnBox aBox( pDocSh->GetActiveDialogParent() );
+ if ( aBox.Execute() != RET_YES )
+ {
+ delete pEnglishTransliteration;
+ delete pEnglishCalendar;
+ return FALSE;
+ }
+ }
+
+ rStrm.Seek( nOriginalStreamPos );
+ nRow = nStartRow;
+ if (!StartPaste())
+ {
+ EndPaste();
+ return FALSE;
+ }
+ }
+
+ bDetermineRange = !bDetermineRange; // toggle
+ } while (!bDetermineRange);
+
+ ScColumn::bDoubleAlloc = bOld;
+ pDoc->DoColResize( nTab, nStartCol, nEndCol, 0 );
+
+ delete pEnglishTransliteration;
+ delete pEnglishCalendar;
+
+ xProgress.reset(); // make room for AdjustRowHeight progress
+ if (bRangeIsDetermined)
+ EndPaste();
+
+ return TRUE;
+}
+
+
+// static
+const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p,
+ String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted )
+{
+ rbIsQuoted = false;
+ rField.Erase();
+ if ( *p == cStr ) // String in Anfuehrungszeichen
+ {
+ rbIsQuoted = true;
+ const sal_Unicode* p1;
+ p1 = p = lcl_ScanString( p, rField, cStr, DQM_ESCAPE );
+ while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
+ p++;
+ // Append remaining unquoted and undelimited data (dirty, dirty) to
+ // this field.
+ if (p > p1)
+ rField.Append( p1, sal::static_int_cast<xub_StrLen>( p - p1 ) );
+ if( *p )
+ p++;
+ }
+ else // bis zum Trennzeichen
+ {
+ const sal_Unicode* p0 = p;
+ while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
+ p++;
+ rField.Append( p0, sal::static_int_cast<xub_StrLen>( p - p0 ) );
+ if( *p )
+ p++;
+ }
+ if ( bMergeSeps ) // folgende Trennzeichen ueberspringen
+ {
+ while ( *p && ScGlobal::UnicodeStrChr( pSeps, *p ) )
+ p++;
+ }
+ return p;
+}
+
+ //
+ //
+ //
+
+
+BOOL ScImportExport::Doc2Text( SvStream& rStrm )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ String aCell;
+ bool bConvertLF = (GetSystemLineEnd() != LINEEND_LF);
+
+ for (nRow = nStartRow; nRow <= nEndRow; nRow++)
+ {
+ if (bIncludeFiltered || !pDoc->RowFiltered( nRow, aRange.aStart.Tab() ))
+ {
+ for (nCol = nStartCol; nCol <= nEndCol; nCol++)
+ {
+ CellType eType;
+ pDoc->GetCellType( nCol, nRow, aRange.aStart.Tab(), eType );
+ switch (eType)
+ {
+ case CELLTYPE_FORMULA:
+ {
+ if (bFormulas)
+ {
+ pDoc->GetFormula( nCol, nRow, aRange.aStart.Tab(), aCell, TRUE );
+ if( aCell.Search( cSep ) != STRING_NOTFOUND )
+ lcl_WriteString( rStrm, aCell, cStr, cStr );
+ else
+ lcl_WriteSimpleString( rStrm, aCell );
+ }
+ else
+ {
+ pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
+
+ bool bMultiLineText = ( aCell.Search( _LF ) != STRING_NOTFOUND );
+ if( bMultiLineText )
+ {
+ if( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSpace )
+ aCell.SearchAndReplaceAll( _LF, ' ' );
+ else if ( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSystem && bConvertLF )
+ aCell.ConvertLineEnd();
+ }
+
+ if( mExportTextOptions.mcSeparatorConvertTo && cSep )
+ aCell.SearchAndReplaceAll( cSep, mExportTextOptions.mcSeparatorConvertTo );
+
+ if( mExportTextOptions.mbAddQuotes && ( aCell.Search( cSep ) != STRING_NOTFOUND ) )
+ lcl_WriteString( rStrm, aCell, cStr, cStr );
+ else
+ lcl_WriteSimpleString( rStrm, aCell );
+ }
+ }
+ break;
+ case CELLTYPE_VALUE:
+ {
+ pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
+ lcl_WriteSimpleString( rStrm, aCell );
+ }
+ break;
+ case CELLTYPE_NOTE:
+ case CELLTYPE_NONE:
+ break;
+ default:
+ {
+ pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
+
+ bool bMultiLineText = ( aCell.Search( _LF ) != STRING_NOTFOUND );
+ if( bMultiLineText )
+ {
+ if( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSpace )
+ aCell.SearchAndReplaceAll( _LF, ' ' );
+ else if ( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSystem && bConvertLF )
+ aCell.ConvertLineEnd();
+ }
+
+ if( mExportTextOptions.mcSeparatorConvertTo && cSep )
+ aCell.SearchAndReplaceAll( cSep, mExportTextOptions.mcSeparatorConvertTo );
+
+ if( mExportTextOptions.mbAddQuotes && ( aCell.Search( cSep ) != STRING_NOTFOUND ) )
+ lcl_WriteString( rStrm, aCell, cStr, cStr );
+ else
+ lcl_WriteSimpleString( rStrm, aCell );
+ }
+ }
+ if( nCol < nEndCol )
+ lcl_WriteSimpleString( rStrm, String(cSep) );
+ }
+// if( nRow < nEndRow )
+ WriteUnicodeOrByteEndl( rStrm );
+ if( rStrm.GetError() != SVSTREAM_OK )
+ break;
+ if( nSizeLimit && rStrm.Tell() > nSizeLimit )
+ break;
+ }
+ }
+
+ return BOOL( rStrm.GetError() == SVSTREAM_OK );
+}
+
+
+BOOL ScImportExport::Sylk2Doc( SvStream& rStrm )
+{
+ BOOL bOk = TRUE;
+ BOOL bMyDoc = FALSE;
+ SylkVersion eVersion = SYLK_OTHER;
+
+ // US-English separators for StringToDouble
+ sal_Unicode cDecSep = '.';
+ sal_Unicode cGrpSep = ',';
+
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ ULONG nOldPos = rStrm.Tell();
+ BOOL bData = BOOL( !bSingle );
+ SvULongs aFormats;
+
+ if( !bSingle)
+ bOk = StartPaste();
+
+ while( bOk )
+ {
+ String aLine;
+ String aText;
+ ByteString aByteLine;
+ SCCOL nCol = nStartCol;
+ SCROW nRow = nStartRow;
+ SCCOL nRefCol = 1;
+ SCROW nRefRow = 1;
+ rStrm.Seek( nOldPos );
+ for( ;; )
+ {
+ //! allow unicode
+ rStrm.ReadLine( aByteLine );
+ aLine = String( aByteLine, rStrm.GetStreamCharSet() );
+ if( rStrm.IsEof() )
+ break;
+ const sal_Unicode* p = aLine.GetBuffer();
+ sal_Unicode cTag = *p++;
+ if( cTag == 'C' ) // Content
+ {
+ if( *p++ != ';' )
+ return FALSE;
+ while( *p )
+ {
+ sal_Unicode ch = *p++;
+ ch = ScGlobal::ToUpperAlpha( ch );
+ switch( ch )
+ {
+ case 'X':
+ nCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
+ break;
+ case 'Y':
+ nRow = String( p ).ToInt32() + nStartRow - 1;
+ break;
+ case 'C':
+ nRefCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
+ break;
+ case 'R':
+ nRefRow = String( p ).ToInt32() + nStartRow - 1;
+ break;
+ case 'K':
+ {
+ if( !bSingle &&
+ ( nCol < nStartCol || nCol > nEndCol
+ || nRow < nStartRow || nRow > nEndRow
+ || nCol > MAXCOL || nRow > MAXROW ) )
+ break;
+ if( !bData )
+ {
+ if( nRow > nEndRow )
+ nEndRow = nRow;
+ if( nCol > nEndCol )
+ nEndCol = nCol;
+ break;
+ }
+ BOOL bText;
+ if( *p == '"' )
+ {
+ bText = TRUE;
+ aText.Erase();
+ p = lcl_ScanSylkString( p, aText, eVersion);
+ }
+ else
+ bText = FALSE;
+ const sal_Unicode* q = p;
+ while( *q && *q != ';' )
+ q++;
+ if ( !(*q == ';' && *(q+1) == 'I') )
+ { // don't ignore value
+ if( bText )
+ {
+ pDoc->PutCell( nCol, nRow, aRange.aStart.Tab(),
+ ScBaseCell::CreateTextCell( aText, pDoc),
+ (BOOL) TRUE);
+ }
+ else
+ {
+ double fVal = rtl_math_uStringToDouble( p,
+ aLine.GetBuffer() + aLine.Len(),
+ cDecSep, cGrpSep, NULL, NULL );
+ pDoc->SetValue( nCol, nRow, aRange.aStart.Tab(), fVal );
+ }
+ }
+ }
+ break;
+ case 'E':
+ case 'M':
+ {
+ if ( ch == 'M' )
+ {
+ if ( nRefCol < nCol )
+ nRefCol = nCol;
+ if ( nRefRow < nRow )
+ nRefRow = nRow;
+ if ( !bData )
+ {
+ if( nRefRow > nEndRow )
+ nEndRow = nRefRow;
+ if( nRefCol > nEndCol )
+ nEndCol = nRefCol;
+ }
+ }
+ if( !bMyDoc || !bData )
+ break;
+ aText = '=';
+ p = lcl_ScanSylkFormula( p, aText, eVersion);
+ ScAddress aPos( nCol, nRow, aRange.aStart.Tab() );
+ /* FIXME: do we want GRAM_ODFF_A1 instead? At the
+ * end it probably should be GRAM_ODFF_R1C1, since
+ * R1C1 is what Excel writes in SYLK. */
+ const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
+ ScCompiler aComp( pDoc, aPos);
+ aComp.SetGrammar(eGrammar);
+ ScTokenArray* pCode = aComp.CompileString( aText );
+ if ( ch == 'M' )
+ {
+ ScMarkData aMark;
+ aMark.SelectTable( aPos.Tab(), TRUE );
+ pDoc->InsertMatrixFormula( nCol, nRow, nRefCol,
+ nRefRow, aMark, EMPTY_STRING, pCode );
+ }
+ else
+ {
+ ScFormulaCell* pFCell = new ScFormulaCell(
+ pDoc, aPos, pCode, eGrammar, MM_NONE);
+ pDoc->PutCell( aPos, pFCell );
+ }
+ delete pCode; // ctor/InsertMatrixFormula did copy TokenArray
+ }
+ break;
+ }
+ while( *p && *p != ';' )
+ p++;
+ if( *p )
+ p++;
+ }
+ }
+ else if( cTag == 'F' ) // Format
+ {
+ if( *p++ != ';' )
+ return FALSE;
+ sal_Int32 nFormat = -1;
+ while( *p )
+ {
+ sal_Unicode ch = *p++;
+ ch = ScGlobal::ToUpperAlpha( ch );
+ switch( ch )
+ {
+ case 'X':
+ nCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
+ break;
+ case 'Y':
+ nRow = String( p ).ToInt32() + nStartRow - 1;
+ break;
+ case 'P' :
+ if ( bData )
+ {
+ // F;P<n> sets format code of P;P<code> at
+ // current position, or at ;X;Y if specified.
+ // Note that ;X;Y may appear after ;P
+ const sal_Unicode* p0 = p;
+ while( *p && *p != ';' )
+ p++;
+ String aNumber( p0, sal::static_int_cast<xub_StrLen>( p - p0 ) );
+ nFormat = aNumber.ToInt32();
+ }
+ break;
+ }
+ while( *p && *p != ';' )
+ p++;
+ if( *p )
+ p++;
+ }
+ if ( !bData )
+ {
+ if( nRow > nEndRow )
+ nEndRow = nRow;
+ if( nCol > nEndCol )
+ nEndCol = nCol;
+ }
+ if ( 0 <= nFormat && nFormat < aFormats.Count() )
+ {
+ ULONG nKey = aFormats[(USHORT)nFormat];
+ pDoc->ApplyAttr( nCol, nRow, aRange.aStart.Tab(),
+ SfxUInt32Item( ATTR_VALUE_FORMAT, nKey ) );
+ }
+ }
+ else if( cTag == 'P' )
+ {
+ if ( bData && *p == ';' && *(p+1) == 'P' )
+ {
+ String aCode( p+2 );
+ // unescape doubled semicolons
+ xub_StrLen nPos = 0;
+ String aSemicolon( RTL_CONSTASCII_USTRINGPARAM(";;"));
+ while ( (nPos = aCode.Search( aSemicolon, nPos )) != STRING_NOTFOUND )
+ aCode.Erase( nPos++, 1 );
+ // get rid of Xcl escape characters
+ nPos = 0;
+ while ( (nPos = aCode.Search( sal_Unicode(0x1b), nPos )) != STRING_NOTFOUND )
+ aCode.Erase( nPos, 1 );
+ xub_StrLen nCheckPos;
+ short nType;
+ sal_uInt32 nKey;
+ pDoc->GetFormatTable()->PutandConvertEntry(
+ aCode, nCheckPos, nType, nKey, LANGUAGE_ENGLISH_US,
+ ScGlobal::eLnge );
+ if ( nCheckPos )
+ nKey = 0;
+ aFormats.Insert( nKey, aFormats.Count() );
+ }
+ }
+ else if( cTag == 'I' && *p == 'D' )
+ {
+ aLine.Erase( 0, 4 );
+ if (aLine.EqualsAscii( "CALCOOO32" ))
+ eVersion = SYLK_OOO32;
+ else if (aLine.EqualsAscii( "SCALC3" ))
+ eVersion = SYLK_SCALC3;
+ bMyDoc = (eVersion <= SYLK_OWN);
+ }
+ else if( cTag == 'E' ) // Ende
+ break;
+ }
+ if( !bData )
+ {
+ aRange.aEnd.SetCol( nEndCol );
+ aRange.aEnd.SetRow( nEndRow );
+ bOk = StartPaste();
+ bData = TRUE;
+ }
+ else
+ break;
+ }
+
+ EndPaste();
+ return bOk;
+}
+
+
+BOOL ScImportExport::Doc2Sylk( SvStream& rStrm )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ String aCellStr;
+ String aValStr;
+ lcl_WriteSimpleString( rStrm,
+ String( RTL_CONSTASCII_USTRINGPARAM( "ID;PCALCOOO32")));
+ WriteUnicodeOrByteEndl( rStrm );
+
+ for (nRow = nStartRow; nRow <= nEndRow; nRow++)
+ {
+ for (nCol = nStartCol; nCol <= nEndCol; nCol++)
+ {
+ String aBufStr;
+ double nVal;
+ BOOL bForm = FALSE;
+ SCROW r = nRow - nStartRow + 1;
+ SCCOL c = nCol - nStartCol + 1;
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, aRange.aStart.Tab(), pCell );
+ CellType eType = (pCell ? pCell->GetCellType() : CELLTYPE_NONE);
+ switch( eType )
+ {
+ case CELLTYPE_FORMULA:
+ bForm = bFormulas;
+ if( pDoc->HasValueData( nCol, nRow, aRange.aStart.Tab()) )
+ goto hasvalue;
+ else
+ goto hasstring;
+
+ case CELLTYPE_VALUE:
+ hasvalue:
+ pDoc->GetValue( nCol, nRow, aRange.aStart.Tab(), nVal );
+
+ aValStr = ::rtl::math::doubleToUString( nVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', TRUE );
+
+ aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" ));
+ aBufStr += String::CreateFromInt32( c );
+ aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" ));
+ aBufStr += String::CreateFromInt32( r );
+ aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" ));
+ aBufStr += aValStr;
+ lcl_WriteSimpleString( rStrm, aBufStr );
+ goto checkformula;
+
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ hasstring:
+ pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCellStr );
+ aCellStr.SearchAndReplaceAll( _LF, SYLK_LF );
+
+ aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" ));
+ aBufStr += String::CreateFromInt32( c );
+ aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" ));
+ aBufStr += String::CreateFromInt32( r );
+ aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" ));
+ lcl_WriteSimpleString( rStrm, aBufStr );
+ lcl_WriteString( rStrm, aCellStr, '"', ';' );
+
+ checkformula:
+ if( bForm )
+ {
+ const ScFormulaCell* pFCell =
+ static_cast<const ScFormulaCell*>(pCell);
+ switch ( pFCell->GetMatrixFlag() )
+ {
+ case MM_REFERENCE :
+ aCellStr.Erase();
+ break;
+ default:
+ pFCell->GetFormula( aCellStr,formula::FormulaGrammar::GRAM_PODF_A1);
+ /* FIXME: do we want GRAM_ODFF_A1 instead? At
+ * the end it probably should be
+ * GRAM_ODFF_R1C1, since R1C1 is what Excel
+ * writes in SYLK. */
+ }
+ if ( pFCell->GetMatrixFlag() != MM_NONE &&
+ aCellStr.Len() > 2 &&
+ aCellStr.GetChar(0) == '{' &&
+ aCellStr.GetChar(aCellStr.Len()-1) == '}' )
+ { // cut off matrix {} characters
+ aCellStr.Erase(aCellStr.Len()-1,1);
+ aCellStr.Erase(0,1);
+ }
+ if ( aCellStr.GetChar(0) == '=' )
+ aCellStr.Erase(0,1);
+ String aPrefix;
+ switch ( pFCell->GetMatrixFlag() )
+ {
+ case MM_FORMULA :
+ { // diff expression with 'M' M$-extension
+ SCCOL nC;
+ SCROW nR;
+ pFCell->GetMatColsRows( nC, nR );
+ nC += c - 1;
+ nR += r - 1;
+ aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";R" ) );
+ aPrefix += String::CreateFromInt32( nR );
+ aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";C" ) );
+ aPrefix += String::CreateFromInt32( nC );
+ aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";M" ) );
+ }
+ break;
+ case MM_REFERENCE :
+ { // diff expression with 'I' M$-extension
+ ScAddress aPos;
+ pFCell->GetMatrixOrigin( aPos );
+ aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";I;R" ) );
+ aPrefix += String::CreateFromInt32( aPos.Row() - nStartRow + 1 );
+ aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";C" ) );
+ aPrefix += String::CreateFromInt32( aPos.Col() - nStartCol + 1 );
+ }
+ break;
+ default:
+ // formula Expression
+ aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";E" ) );
+ }
+ lcl_WriteSimpleString( rStrm, aPrefix );
+ if ( aCellStr.Len() )
+ lcl_WriteString( rStrm, aCellStr, 0, ';' );
+ }
+ WriteUnicodeOrByteEndl( rStrm );
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ lcl_WriteSimpleString( rStrm, String( 'E' ) );
+ WriteUnicodeOrByteEndl( rStrm );
+ return BOOL( rStrm.GetError() == SVSTREAM_OK );
+}
+
+
+BOOL ScImportExport::Doc2HTML( SvStream& rStrm, const String& rBaseURL )
+{
+ // CharSet is ignored in ScExportHTML, read from Load/Save HTML options
+ ScFormatFilter::Get().ScExportHTML( rStrm, rBaseURL, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW, bAll,
+ aStreamPath, aNonConvertibleChars );
+ return BOOL( rStrm.GetError() == SVSTREAM_OK );
+}
+
+BOOL ScImportExport::Doc2RTF( SvStream& rStrm )
+{
+ // CharSet is ignored in ScExportRTF
+ ScFormatFilter::Get().ScExportRTF( rStrm, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW );
+ return BOOL( rStrm.GetError() == SVSTREAM_OK );
+}
+
+
+BOOL ScImportExport::Doc2Dif( SvStream& rStrm )
+{
+ // for DIF in the clipboard, IBM_850 is always used
+ ScFormatFilter::Get().ScExportDif( rStrm, pDoc, aRange, RTL_TEXTENCODING_IBM_850 );
+ return TRUE;
+}
+
+
+BOOL ScImportExport::Dif2Doc( SvStream& rStrm )
+{
+ SCTAB nTab = aRange.aStart.Tab();
+ ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
+ pImportDoc->InitUndo( pDoc, nTab, nTab );
+
+ // for DIF in the clipboard, IBM_850 is always used
+ ScFormatFilter::Get().ScImportDif( rStrm, pImportDoc, aRange.aStart, RTL_TEXTENCODING_IBM_850 );
+
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pImportDoc->GetCellArea( nTab, nEndCol, nEndRow );
+ // #131247# if there are no cells in the imported content, nEndCol/nEndRow may be before the start
+ if ( nEndCol < aRange.aStart.Col() )
+ nEndCol = aRange.aStart.Col();
+ if ( nEndRow < aRange.aStart.Row() )
+ nEndRow = aRange.aStart.Row();
+ aRange.aEnd = ScAddress( nEndCol, nEndRow, nTab );
+
+ BOOL bOk = StartPaste();
+ if (bOk)
+ {
+ USHORT nFlags = IDF_ALL & ~IDF_STYLES;
+ pDoc->DeleteAreaTab( aRange, nFlags );
+ pImportDoc->CopyToDocument( aRange, nFlags, FALSE, pDoc );
+ EndPaste();
+ }
+
+ delete pImportDoc;
+
+ return bOk;
+}
+
+
+BOOL ScImportExport::RTF2Doc( SvStream& rStrm, const String& rBaseURL )
+{
+ ScEEAbsImport *pImp = ScFormatFilter::Get().CreateRTFImport( pDoc, aRange );
+ if (!pImp)
+ return false;
+ pImp->Read( rStrm, rBaseURL );
+ aRange = pImp->GetRange();
+
+ BOOL bOk = StartPaste();
+ if (bOk)
+ {
+ USHORT nFlags = IDF_ALL & ~IDF_STYLES;
+ pDoc->DeleteAreaTab( aRange, nFlags );
+ pImp->WriteToDocument();
+ EndPaste();
+ }
+ delete pImp;
+ return bOk;
+}
+
+
+BOOL ScImportExport::HTML2Doc( SvStream& rStrm, const String& rBaseURL )
+{
+ ScEEAbsImport *pImp = ScFormatFilter::Get().CreateHTMLImport( pDoc, rBaseURL, aRange, TRUE);
+ if (!pImp)
+ return false;
+ pImp->Read( rStrm, rBaseURL );
+ aRange = pImp->GetRange();
+
+ BOOL bOk = StartPaste();
+ if (bOk)
+ {
+ // ScHTMLImport may call ScDocument::InitDrawLayer, resulting in
+ // a Draw Layer but no Draw View -> create Draw Layer and View here
+ if (pDocSh)
+ pDocSh->MakeDrawLayer();
+
+ USHORT nFlags = IDF_ALL & ~IDF_STYLES;
+ pDoc->DeleteAreaTab( aRange, nFlags );
+ pImp->WriteToDocument();
+ EndPaste();
+ }
+ delete pImp;
+ return bOk;
+}
+
+#define RETURN_ERROR { return eERR_INTERN; }
+class ScFormatFilterMissing : public ScFormatFilterPlugin {
+ public:
+ ScFormatFilterMissing()
+ {
+ OSL_ASSERT ("Missing file filters");
+ }
+ virtual FltError ScImportLotus123( SfxMedium&, ScDocument*, CharSet ) RETURN_ERROR
+ virtual FltError ScImportQuattroPro( SfxMedium &, ScDocument * ) RETURN_ERROR
+ virtual FltError ScImportExcel( SfxMedium&, ScDocument*, const EXCIMPFORMAT ) RETURN_ERROR
+ virtual FltError ScImportStarCalc10( SvStream&, ScDocument* ) RETURN_ERROR
+ virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress&,
+ const CharSet, UINT32 ) RETURN_ERROR
+ virtual FltError ScImportRTF( SvStream&, const String&, ScDocument*, ScRange& ) RETURN_ERROR
+ virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, BOOL, SvNumberFormatter*, bool ) RETURN_ERROR
+
+ virtual ScEEAbsImport *CreateRTFImport( ScDocument*, const ScRange& ) { return NULL; }
+ virtual ScEEAbsImport *CreateHTMLImport( ScDocument*, const String&, const ScRange&, BOOL ) { return NULL; }
+ virtual String GetHTMLRangeNameList( ScDocument*, const String& ) { return String(); }
+
+#if ENABLE_LOTUS123_EXPORT
+ virtual FltError ScExportLotus123( SvStream&, ScDocument*, ExportFormatLotus, CharSet ) RETURN_ERROR
+#endif
+ virtual FltError ScExportExcel5( SfxMedium&, ScDocument*, ExportFormatExcel, CharSet ) RETURN_ERROR
+ virtual FltError ScExportDif( SvStream&, ScDocument*, const ScAddress&, const CharSet, UINT32 ) RETURN_ERROR
+ virtual FltError ScExportDif( SvStream&, ScDocument*, const ScRange&, const CharSet, UINT32 ) RETURN_ERROR
+ virtual FltError ScExportHTML( SvStream&, const String&, ScDocument*, const ScRange&, const CharSet, BOOL,
+ const String&, String& ) RETURN_ERROR
+ virtual FltError ScExportRTF( SvStream&, ScDocument*, const ScRange&, const CharSet ) RETURN_ERROR
+};
+
+extern "C" { static void SAL_CALL thisModule() {} }
+typedef ScFormatFilterPlugin * (*FilterFn)(void);
+ScFormatFilterPlugin &ScFormatFilter::Get()
+{
+ static ScFormatFilterPlugin *plugin;
+
+ if (plugin != NULL)
+ return *plugin;
+
+ static ::osl::Module aModule;
+ if ( aModule.loadRelative( &thisModule,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SVLIBRARY( "scfilt" ) ) ) ) )
+ {
+ oslGenericFunction fn = aModule.getFunctionSymbol( ::rtl::OUString::createFromAscii( "ScFilterCreate" ) );
+ if (fn != NULL)
+ plugin = reinterpret_cast<FilterFn>(fn)();
+ }
+ if (plugin == NULL)
+ plugin = new ScFormatFilterMissing();
+
+ return *plugin;
+}
diff --git a/sc/source/ui/docshell/makefile.mk b/sc/source/ui/docshell/makefile.mk
new file mode 100644
index 000000000000..99a7495b6b49
--- /dev/null
+++ b/sc/source/ui/docshell/makefile.mk
@@ -0,0 +1,139 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=docshell
+LIBTARGET=no
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ docsh.cxx \
+ docsh2.cxx \
+ docsh3.cxx \
+ docsh4.cxx \
+ docsh5.cxx \
+ docsh6.cxx \
+ docsh7.cxx \
+ docsh8.cxx \
+ externalrefmgr.cxx \
+ tablink.cxx \
+ arealink.cxx \
+ dbdocfun.cxx \
+ dbdocimp.cxx \
+ impex.cxx \
+ docfunc.cxx \
+ olinefun.cxx \
+ servobj.cxx \
+ tpstat.cxx \
+ autostyl.cxx \
+ pagedata.cxx \
+ hiranges.cxx \
+ pntlock.cxx \
+ sizedev.cxx \
+ editable.cxx
+
+
+SLOFILES = \
+ $(SLO)$/docsh.obj \
+ $(SLO)$/docsh2.obj \
+ $(SLO)$/docsh3.obj \
+ $(SLO)$/docsh4.obj \
+ $(SLO)$/docsh5.obj \
+ $(SLO)$/docsh6.obj \
+ $(SLO)$/docsh7.obj \
+ $(SLO)$/docsh8.obj \
+ $(SLO)$/externalrefmgr.obj \
+ $(SLO)$/tablink.obj \
+ $(SLO)$/arealink.obj \
+ $(SLO)$/dbdocfun.obj \
+ $(SLO)$/dbdocimp.obj \
+ $(SLO)$/impex.obj \
+ $(SLO)$/docfunc.obj \
+ $(SLO)$/olinefun.obj \
+ $(SLO)$/servobj.obj \
+ $(SLO)$/tpstat.obj \
+ $(SLO)$/autostyl.obj \
+ $(SLO)$/pagedata.obj \
+ $(SLO)$/hiranges.obj \
+ $(SLO)$/pntlock.obj \
+ $(SLO)$/sizedev.obj \
+ $(SLO)$/editable.obj
+
+
+EXCEPTIONSFILES= \
+ $(SLO)$/docsh.obj \
+ $(SLO)$/docsh3.obj \
+ $(SLO)$/docsh4.obj \
+ $(SLO)$/docsh8.obj \
+ $(SLO)$/externalrefmgr.obj \
+ $(SLO)$/dbdocimp.obj \
+ $(SLO)$/docfunc.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES = tpstat.src
+
+LIB1TARGET = $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO)$/docsh.obj \
+ $(SLO)$/docsh2.obj \
+ $(SLO)$/docsh3.obj \
+ $(SLO)$/docsh4.obj \
+ $(SLO)$/docsh5.obj \
+ $(SLO)$/docsh6.obj \
+ $(SLO)$/docsh7.obj \
+ $(SLO)$/docsh8.obj \
+ $(SLO)$/externalrefmgr.obj \
+ $(SLO)$/tablink.obj \
+ $(SLO)$/arealink.obj \
+ $(SLO)$/dbdocfun.obj \
+ $(SLO)$/dbdocimp.obj \
+ $(SLO)$/impex.obj \
+ $(SLO)$/docfunc.obj \
+ $(SLO)$/olinefun.obj \
+ $(SLO)$/servobj.obj \
+ $(SLO)$/autostyl.obj \
+ $(SLO)$/pagedata.obj \
+ $(SLO)$/hiranges.obj \
+ $(SLO)$/pntlock.obj \
+ $(SLO)$/sizedev.obj \
+ $(SLO)$/editable.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/docshell/olinefun.cxx b/sc/source/ui/docshell/olinefun.cxx
new file mode 100644
index 000000000000..822c74800ab2
--- /dev/null
+++ b/sc/source/ui/docshell/olinefun.cxx
@@ -0,0 +1,790 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/sound.hxx>
+#include <sfx2/bindings.hxx>
+
+#include "olinefun.hxx"
+
+#include "docsh.hxx"
+#include "olinetab.hxx"
+#include "undodat.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+
+
+//========================================================================
+
+void lcl_InvalidateOutliner( SfxBindings* pBindings )
+{
+ if ( pBindings )
+ {
+ pBindings->Invalidate( SID_OUTLINE_SHOW );
+ pBindings->Invalidate( SID_OUTLINE_HIDE );
+ pBindings->Invalidate( SID_OUTLINE_REMOVE );
+
+ pBindings->Invalidate( SID_STATUS_SUM ); // wegen ein-/ausblenden
+ pBindings->Invalidate( SID_ATTR_SIZE );
+ }
+}
+
+//------------------------------------------------------------------------
+
+//! PaintWidthHeight zur DocShell verschieben?
+
+void lcl_PaintWidthHeight( ScDocShell& rDocShell, SCTAB nTab,
+ BOOL bColumns, SCCOLROW nStart, SCCOLROW nEnd )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ USHORT nParts = PAINT_GRID;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = MAXCOL; // fuer Test auf Merge
+ SCROW nEndRow = MAXROW;
+ if ( bColumns )
+ {
+ nParts |= PAINT_TOP;
+ nStartCol = static_cast<SCCOL>(nStart);
+ nEndCol = static_cast<SCCOL>(nEnd);
+ }
+ else
+ {
+ nParts |= PAINT_LEFT;
+ nStartRow = nStart;
+ nEndRow = nEnd;
+ }
+ if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ nStartCol = 0;
+ nStartRow = 0;
+ }
+ rDocShell.PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScOutlineDocFunc::MakeOutline( const ScRange& rRange, BOOL bColumns, BOOL bRecord, BOOL bApi )
+{
+ BOOL bSuccess = FALSE;
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab, TRUE );
+ ScOutlineTable* pUndoTab = NULL;
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ if (bRecord)
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
+
+ BOOL bRes;
+ BOOL bSize = FALSE;
+ if ( bColumns )
+ bRes = pArray->Insert( nStartCol, nEndCol, bSize );
+ else
+ bRes = pArray->Insert( nStartRow, nEndRow, bSize );
+
+ if ( bRes )
+ {
+ if (bRecord)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoMakeOutline( &rDocShell,
+ nStartCol,nStartRow,nTab,nEndCol,nEndRow,nTab,
+ pUndoTab, bColumns, TRUE ) );
+ }
+
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ USHORT nParts = 0; // Datenbereich nicht geaendert
+ if ( bColumns )
+ nParts |= PAINT_TOP;
+ else
+ nParts |= PAINT_LEFT;
+ if ( bSize )
+ nParts |= PAINT_SIZE;
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts );
+ rDocShell.SetDocumentModified();
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+ bSuccess = TRUE;
+ }
+ else
+ {
+ if (!bApi)
+ rDocShell.ErrorMessage(STR_MSSG_MAKEOUTLINE_0); // "Gruppierung nicht moeglich"
+ delete pUndoTab;
+ }
+
+ return bSuccess;
+}
+
+BOOL ScOutlineDocFunc::RemoveOutline( const ScRange& rRange, BOOL bColumns, BOOL bRecord, BOOL bApi )
+{
+ BOOL bDone = FALSE;
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ ScOutlineTable* pUndoTab = NULL;
+ if (bRecord)
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
+
+ BOOL bRes;
+ BOOL bSize = FALSE;
+ if ( bColumns )
+ bRes = pArray->Remove( nStartCol, nEndCol, bSize );
+ else
+ bRes = pArray->Remove( nStartRow, nEndRow, bSize );
+
+ if ( bRes )
+ {
+ if (bRecord)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoMakeOutline( &rDocShell,
+ nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+ pUndoTab, bColumns, FALSE ) );
+ }
+
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ USHORT nParts = 0; // Datenbereich nicht geaendert
+ if ( bColumns )
+ nParts |= PAINT_TOP;
+ else
+ nParts |= PAINT_LEFT;
+ if ( bSize )
+ nParts |= PAINT_SIZE;
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts );
+ rDocShell.SetDocumentModified();
+ bDone = TRUE;
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+
+ // es wird nicht wieder eingeblendet -> kein UpdatePageBreaks
+ }
+ else
+ delete pUndoTab;
+ }
+
+ if (!bDone && !bApi)
+ rDocShell.ErrorMessage(STR_MSSG_REMOVEOUTLINE_0); // "Aufheben nicht moeglich"
+
+ return bDone;
+}
+
+BOOL ScOutlineDocFunc::RemoveAllOutlines( SCTAB nTab, BOOL bRecord, BOOL bApi )
+{
+ BOOL bSuccess = FALSE;
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ if (bRecord)
+ {
+ SCCOLROW nCol1, nCol2, nRow1, nRow2;
+ pTable->GetColArray()->GetRange( nCol1, nCol2 );
+ pTable->GetRowArray()->GetRange( nRow1, nRow2 );
+ SCCOL nStartCol = static_cast<SCCOL>(nCol1);
+ SCROW nStartRow = nRow1;
+ SCCOL nEndCol = static_cast<SCCOL>(nCol2);
+ SCROW nEndRow = nRow2;
+
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+
+ ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveAllOutlines( &rDocShell,
+ nStartCol, nStartRow, nTab,
+ nEndCol, nEndRow, nTab,
+ pUndoDoc, pUndoTab ) );
+ }
+
+ SelectLevel( nTab, TRUE, pTable->GetColArray()->GetDepth(), FALSE, FALSE, bApi );
+ SelectLevel( nTab, FALSE, pTable->GetRowArray()->GetDepth(), FALSE, FALSE, bApi );
+ pDoc->SetOutlineTable( nTab, NULL );
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+ rDocShell.SetDocumentModified();
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+ bSuccess = TRUE;
+ }
+ else if (!bApi)
+ Sound::Beep();
+
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScOutlineDocFunc::AutoOutline( const ScRange& rRange, BOOL bRecord, BOOL bApi )
+{
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+
+ if ( pTable )
+ {
+ if ( bRecord )
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ SCCOLROW nCol1, nCol2, nRow1, nRow2;
+ pTable->GetColArray()->GetRange( nCol1, nCol2 );
+ pTable->GetRowArray()->GetRange( nRow1, nRow2 );
+ SCCOL nOutStartCol = static_cast<SCCOL>(nCol1);;
+ SCROW nOutStartRow = nRow1;
+ SCCOL nOutEndCol = static_cast<SCCOL>(nCol2);;
+ SCROW nOutEndRow = nRow2;
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( nOutStartCol, 0, nTab, nOutEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+
+ // einblenden
+ SelectLevel( nTab, TRUE, pTable->GetColArray()->GetDepth(), FALSE, FALSE, bApi );
+ SelectLevel( nTab, FALSE, pTable->GetRowArray()->GetDepth(), FALSE, FALSE, bApi );
+ pDoc->SetOutlineTable( nTab, NULL );
+ }
+
+ pDoc->DoAutoOutline( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
+
+ if (bRecord)
+ {
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoAutoOutline( &rDocShell,
+ nStartCol, nStartRow, nTab,
+ nEndCol, nEndRow, nTab,
+ pUndoDoc, pUndoTab ) );
+ }
+
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+ rDocShell.SetDocumentModified();
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScOutlineDocFunc::SelectLevel( SCTAB nTab, BOOL bColumns, USHORT nLevel,
+ BOOL bRecord, BOOL bPaint, BOOL /* bApi */ )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); // ist schon da
+ if (!pTable)
+ return FALSE;
+ ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
+ if (!pArray)
+ return FALSE;
+
+ SCCOLROW nStart, nEnd;
+ pArray->GetRange( nStart, nEnd );
+
+ if ( bRecord )
+ {
+ ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ if (bColumns)
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, FALSE,
+ pUndoDoc );
+ }
+ else
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+ pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoOutlineLevel( &rDocShell,
+ nStart, nEnd, nTab, //! start und end berechnen
+ pUndoDoc, pUndoTab,
+ bColumns, nLevel ) );
+ }
+
+ ScSubOutlineIterator aIter( pArray ); // alle Eintraege
+ ScOutlineEntry* pEntry;
+ while ((pEntry=aIter.GetNext()) != NULL)
+ {
+ USHORT nThisLevel = aIter.LastLevel();
+ BOOL bShow = (nThisLevel < nLevel);
+ if (bShow) // einblenden
+ {
+ pEntry->SetHidden( FALSE );
+ pEntry->SetVisible( TRUE );
+ }
+ else if ( nThisLevel == nLevel ) // ausblenden
+ {
+ pEntry->SetHidden( TRUE );
+ pEntry->SetVisible( TRUE );
+ }
+ else // verdeckt
+ {
+ pEntry->SetVisible( FALSE );
+ }
+
+ SCCOLROW nThisStart = pEntry->GetStart();
+ SCCOLROW nThisEnd = pEntry->GetEnd();
+ for (SCCOLROW i=nThisStart; i<=nThisEnd; i++)
+ {
+ if ( bColumns )
+ pDoc->ShowCol( static_cast<SCCOL>(i), nTab, bShow );
+ else
+ if ( !bShow || !pDoc->RowFiltered( i,nTab ) )
+ pDoc->ShowRow( i, nTab, bShow );
+ }
+ }
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ if (bPaint)
+ lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
+
+ rDocShell.SetDocumentModified();
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, BOOL bRecord, BOOL bApi )
+{
+ BOOL bDone = FALSE;
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+
+ if (pTable)
+ {
+ ScOutlineArray* pArray;
+ ScOutlineEntry* pEntry;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ SCCOLROW nMin;
+ SCCOLROW nMax;
+ SCCOLROW i;
+
+ if ( bRecord )
+ {
+ ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoOutlineBlock( &rDocShell,
+ nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+ pUndoDoc, pUndoTab, TRUE ) );
+ }
+
+ // Spalten
+
+ nMin=MAXCOL;
+ nMax=0;
+ pArray = pTable->GetColArray();
+ ScSubOutlineIterator aColIter( pArray );
+ while ((pEntry=aColIter.GetNext()) != NULL)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( nStart>=nStartCol && nEnd<=nEndCol )
+ {
+ pEntry->SetHidden( FALSE );
+ pEntry->SetVisible( TRUE );
+ if (nStart<nMin) nMin=nStart;
+ if (nEnd>nMax) nMax=nEnd;
+ }
+ }
+ for ( i=nMin; i<=nMax; i++ )
+ pDoc->ShowCol( static_cast<SCCOL>(i), nTab, TRUE );
+
+ // Zeilen
+
+ nMin=MAXROW;
+ nMax=0;
+ pArray = pTable->GetRowArray();
+ ScSubOutlineIterator aRowIter( pArray );
+ while ((pEntry=aRowIter.GetNext()) != NULL)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( nStart>=nStartRow && nEnd<=nEndRow )
+ {
+ pEntry->SetHidden( FALSE );
+ pEntry->SetVisible( TRUE );
+ if (nStart<nMin) nMin=nStart;
+ if (nEnd>nMax) nMax=nEnd;
+ }
+ }
+ for ( i=nMin; i<=nMax; i++ )
+ if ( !pDoc->RowFiltered( i,nTab ) ) // weggefilterte nicht einblenden
+ pDoc->ShowRow( i, nTab, TRUE );
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP );
+
+ rDocShell.SetDocumentModified();
+ bDone = TRUE;
+
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+ }
+
+ if (!bDone && !bApi)
+ Sound::Beep();
+
+ return bDone;
+}
+
+BOOL ScOutlineDocFunc::HideMarkedOutlines( const ScRange& rRange, BOOL bRecord, BOOL bApi )
+{
+ BOOL bDone = FALSE;
+
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+
+ if (pTable)
+ {
+ ScOutlineEntry* pEntry;
+ USHORT nColLevel;
+ USHORT nRowLevel;
+ USHORT nCount;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ USHORT i;
+
+ SCCOLROW nEffStartCol = nStartCol;
+ SCCOLROW nEffEndCol = nEndCol;
+ ScOutlineArray* pColArray = pTable->GetColArray();
+ pColArray->FindTouchedLevel( nStartCol, nEndCol, nColLevel );
+ pColArray->ExtendBlock( nColLevel, nEffStartCol, nEffEndCol );
+ SCCOLROW nEffStartRow = nStartRow;
+ SCCOLROW nEffEndRow = nEndRow;
+ ScOutlineArray* pRowArray = pTable->GetRowArray();
+ pRowArray->FindTouchedLevel( nStartRow, nEndRow, nRowLevel );
+ pRowArray->ExtendBlock( nRowLevel, nEffStartRow, nEffEndRow );
+
+ if ( bRecord )
+ {
+ ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nEffStartCol), 0, nTab,
+ static_cast<SCCOL>(nEffEndCol), MAXROW, nTab, IDF_NONE,
+ FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nEffStartRow, nTab, MAXCOL, nEffEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoOutlineBlock( &rDocShell,
+ nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+ pUndoDoc, pUndoTab, FALSE ) );
+ }
+
+ // Spalten
+
+ nCount = pColArray->GetCount(nColLevel);
+ for ( i=0; i<nCount; i++ )
+ {
+ pEntry = pColArray->GetEntry(nColLevel,i);
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+
+ if ( static_cast<SCCOLROW>(nStartCol)<=nEnd && static_cast<SCCOLROW>(nEndCol)>=nStart )
+ HideOutline( nTab, TRUE, nColLevel, i, FALSE, FALSE, bApi );
+ }
+
+ // Zeilen
+
+ nCount = pRowArray->GetCount(nRowLevel);
+ for ( i=0; i<nCount; i++ )
+ {
+ pEntry = pRowArray->GetEntry(nRowLevel,i);
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+
+ if ( nStartRow<=nEnd && nEndRow>=nStart )
+ HideOutline( nTab, FALSE, nRowLevel, i, FALSE, FALSE, bApi );
+ }
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP );
+
+ rDocShell.SetDocumentModified();
+ bDone = TRUE;
+
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+ }
+
+ if (!bDone && !bApi)
+ Sound::Beep();
+
+ return bDone;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScOutlineDocFunc::ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, USHORT nEntry,
+ BOOL bRecord, BOOL bPaint, BOOL /* bApi */ )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
+ ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry );
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( bRecord )
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ if (bColumns)
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, FALSE,
+ pUndoDoc );
+ }
+ else
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+ pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDoOutline( &rDocShell,
+ nStart, nEnd, nTab, pUndoDoc, //! start und end berechnen
+ bColumns, nLevel, nEntry, TRUE ) );
+ }
+
+//! HideCursor();
+
+ pEntry->SetHidden(FALSE);
+ SCCOLROW i;
+ for ( i = nStart; i <= nEnd; i++ )
+ {
+ if ( bColumns )
+ pDoc->ShowCol( static_cast<SCCOL>(i), nTab, TRUE );
+ else
+ if ( !pDoc->RowFiltered( i,nTab ) ) // weggefilterte nicht einblenden
+ pDoc->ShowRow( i, nTab, TRUE );
+ }
+
+ ScSubOutlineIterator aIter( pArray, nLevel, nEntry );
+ while ((pEntry=aIter.GetNext()) != NULL)
+ {
+ if ( pEntry->IsHidden() )
+ {
+ SCCOLROW nSubStart = pEntry->GetStart();
+ SCCOLROW nSubEnd = pEntry->GetEnd();
+ for ( i = nSubStart; i <= nSubEnd; i++ )
+ {
+ if ( bColumns )
+ pDoc->ShowCol( static_cast<SCCOL>(i), nTab, FALSE );
+ else
+ pDoc->ShowRow( i, nTab, FALSE );
+ }
+ }
+ }
+
+ pArray->SetVisibleBelow( nLevel, nEntry, TRUE, TRUE );
+
+ pDoc->InvalidatePageBreaks(nTab);
+ pDoc->UpdatePageBreaks( nTab );
+
+ if (bPaint)
+ lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
+
+//! ShowCursor();
+ rDocShell.SetDocumentModified();
+
+//! if (bPaint)
+//! UpdateScrollBars();
+
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+
+ return TRUE; //! immer ???
+}
+
+BOOL ScOutlineDocFunc::HideOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, USHORT nEntry,
+ BOOL bRecord, BOOL bPaint, BOOL /* bApi */ )
+{
+ ScDocument* pDoc = rDocShell.GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
+ ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry );
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( bRecord )
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ if (bColumns)
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, FALSE,
+ pUndoDoc );
+ }
+ else
+ {
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+ pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDoOutline( &rDocShell,
+ nStart, nEnd, nTab, pUndoDoc,
+ bColumns, nLevel, nEntry, FALSE ) );
+ }
+
+//! HideCursor();
+
+ pEntry->SetHidden(TRUE);
+ SCCOLROW i;
+ for ( i = nStart; i <= nEnd; i++ )
+ {
+ if ( bColumns )
+ pDoc->ShowCol( static_cast<SCCOL>(i), nTab, FALSE );
+ else
+ pDoc->ShowRow( i, nTab, FALSE );
+ }
+
+ pArray->SetVisibleBelow( nLevel, nEntry, FALSE );
+
+ pDoc->InvalidatePageBreaks(nTab);
+ pDoc->UpdatePageBreaks( nTab );
+
+ if (bPaint)
+ lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
+
+//! ShowCursor();
+ rDocShell.SetDocumentModified();
+
+//! if (bPaint)
+//! UpdateScrollBars();
+
+ lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+
+ return TRUE; //! immer ???
+}
+
+
+
+
+
diff --git a/sc/source/ui/docshell/pagedata.cxx b/sc/source/ui/docshell/pagedata.cxx
new file mode 100644
index 000000000000..db55c2364305
--- /dev/null
+++ b/sc/source/ui/docshell/pagedata.cxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <string.h>
+#include <tools/debug.hxx>
+
+
+#include "pagedata.hxx"
+
+//============================================================================
+
+ScPrintRangeData::ScPrintRangeData()
+{
+ nPagesX = nPagesY = 0;
+ pPageEndX = NULL;
+ pPageEndY = NULL;
+ bTopDown = bAutomatic = TRUE;
+ nFirstPage = 1;
+}
+
+ScPrintRangeData::~ScPrintRangeData()
+{
+ delete[] pPageEndX;
+ delete[] pPageEndY;
+}
+
+void ScPrintRangeData::SetPagesX( size_t nCount, const SCCOL* pData )
+{
+ delete[] pPageEndX;
+ if ( nCount )
+ {
+ pPageEndX = new SCCOL[nCount];
+ memcpy( pPageEndX, pData, nCount * sizeof(SCCOL) );
+ }
+ else
+ pPageEndX = NULL;
+ nPagesX = nCount;
+}
+
+void ScPrintRangeData::SetPagesY( size_t nCount, const SCROW* pData )
+{
+ delete[] pPageEndY;
+ if ( nCount )
+ {
+ pPageEndY = new SCROW[nCount];
+ memcpy( pPageEndY, pData, nCount * sizeof(SCROW) );
+ }
+ else
+ pPageEndY = NULL;
+ nPagesY = nCount;
+}
+
+//============================================================================
+
+ScPageBreakData::ScPageBreakData(size_t nMax)
+{
+ nUsed = 0;
+ if (nMax)
+ pData = new ScPrintRangeData[nMax];
+ else
+ pData = NULL;
+ nAlloc = nMax;
+}
+
+ScPageBreakData::~ScPageBreakData()
+{
+ delete[] pData;
+}
+
+ScPrintRangeData& ScPageBreakData::GetData(size_t nPos)
+{
+ DBG_ASSERT(nPos < nAlloc, "ScPageBreakData::GetData bumm");
+
+ if ( nPos >= nUsed )
+ {
+ DBG_ASSERT(nPos == nUsed, "ScPageBreakData::GetData falsche Reihenfolge");
+ nUsed = nPos+1;
+ }
+
+ return pData[nPos];
+}
+
+BOOL ScPageBreakData::IsEqual( const ScPageBreakData& rOther ) const
+{
+ if ( nUsed != rOther.nUsed )
+ return FALSE;
+
+ for (USHORT i=0; i<nUsed; i++)
+ if ( pData[i].GetPrintRange() != rOther.pData[i].GetPrintRange() )
+ return FALSE;
+
+ //! ScPrintRangeData komplett vergleichen ??
+
+ return TRUE;
+}
+
+void ScPageBreakData::AddPages()
+{
+ if ( nUsed > 1 )
+ {
+ long nPage = pData[0].GetFirstPage();
+ for (USHORT i=0; sal::static_int_cast<size_t>(i+1)<nUsed; i++)
+ {
+ nPage += ((long)pData[i].GetPagesX())*pData[i].GetPagesY();
+ pData[i+1].SetFirstPage( nPage );
+ }
+ }
+}
+
+
+
diff --git a/sc/source/ui/docshell/pntlock.cxx b/sc/source/ui/docshell/pntlock.cxx
new file mode 100644
index 000000000000..764d431f3af0
--- /dev/null
+++ b/sc/source/ui/docshell/pntlock.cxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "pntlock.hxx"
+
+//------------------------------------------------------------------------
+
+ScPaintLockData::ScPaintLockData(USHORT nNewMode) :
+ nMode( nNewMode ),
+ nLevel( 0 ),
+ nDocLevel( 0 ),
+ nParts( 0 ),
+ bModified( FALSE )
+{
+}
+
+ScPaintLockData::~ScPaintLockData()
+{
+}
+
+void ScPaintLockData::AddRange( const ScRange& rRange, USHORT nP )
+{
+ if (!xRangeList.Is())
+ xRangeList = new ScRangeList;
+
+ xRangeList->Join( rRange );
+ nParts |= nP;
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/servobj.cxx b/sc/source/ui/docshell/servobj.cxx
new file mode 100644
index 000000000000..dabe38fb8c1d
--- /dev/null
+++ b/sc/source/ui/docshell/servobj.cxx
@@ -0,0 +1,273 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// System - Includes -----------------------------------------------------
+
+
+
+#include <sot/formats.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/linkmgr.hxx>
+#include "servobj.hxx"
+#include "docsh.hxx"
+#include "impex.hxx"
+#include "brdcst.hxx"
+#include "rangenam.hxx"
+#include "sc.hrc" // SC_HINT_AREAS_CHANGED
+
+// -----------------------------------------------------------------------
+
+BOOL lcl_FillRangeFromName( ScRange& rRange, ScDocShell* pDocSh, const String& rName )
+{
+ if (pDocSh)
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScRangeName* pNames = pDoc->GetRangeName();
+ if (pNames)
+ {
+ USHORT nPos;
+ if( pNames->SearchName( rName, nPos ) )
+ {
+ ScRangeData* pData = (*pNames)[ nPos ];
+ if ( pData->IsValidReference( rRange ) )
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+ScServerObjectSvtListenerForwarder::ScServerObjectSvtListenerForwarder(
+ ScServerObject* pObjP)
+ : pObj(pObjP)
+{
+}
+
+ScServerObjectSvtListenerForwarder::~ScServerObjectSvtListenerForwarder()
+{
+ //! do NOT access pObj
+}
+
+void ScServerObjectSvtListenerForwarder::Notify( SvtBroadcaster& /* rBC */, const SfxHint& rHint)
+{
+ pObj->Notify( aBroadcaster, rHint);
+}
+
+ScServerObject::ScServerObject( ScDocShell* pShell, const String& rItem ) :
+ aForwarder( this ),
+ pDocSh( pShell ),
+ bRefreshListener( FALSE )
+{
+ // parse item string
+
+ if ( lcl_FillRangeFromName( aRange, pDocSh, rItem ) )
+ {
+ aItemStr = rItem; // must be parsed again on ref update
+ }
+ else
+ {
+ // parse ref
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pDocSh->GetCurTab();
+ aRange.aStart.SetTab( nTab );
+
+ if ( aRange.Parse( rItem, pDoc ) & SCA_VALID )
+ {
+ // area reference
+ }
+ else if ( aRange.aStart.Parse( rItem, pDoc, pDoc->GetAddressConvention() ) & SCA_VALID )
+ {
+ // cell reference
+ aRange.aEnd = aRange.aStart;
+ }
+ else
+ {
+ DBG_ERROR("ScServerObject: invalid item");
+ }
+ }
+
+ pDocSh->GetDocument()->GetLinkManager()->InsertServer( this );
+ pDocSh->GetDocument()->StartListeningArea( aRange, &aForwarder );
+
+ StartListening(*pDocSh); // um mitzubekommen, wenn die DocShell geloescht wird
+ StartListening(*SFX_APP()); // for SC_HINT_AREAS_CHANGED
+}
+
+__EXPORT ScServerObject::~ScServerObject()
+{
+ Clear();
+}
+
+void ScServerObject::Clear()
+{
+ if (pDocSh)
+ {
+ ScDocShell* pTemp = pDocSh;
+ pDocSh = NULL;
+
+ pTemp->GetDocument()->EndListeningArea( aRange, &aForwarder );
+ pTemp->GetDocument()->GetLinkManager()->RemoveServer( this );
+ EndListening(*pTemp);
+ EndListening(*SFX_APP());
+ }
+}
+
+void ScServerObject::EndListeningAll()
+{
+ aForwarder.EndListeningAll();
+ SfxListener::EndListeningAll();
+}
+
+BOOL __EXPORT ScServerObject::GetData(
+ ::com::sun::star::uno::Any & rData /*out param*/,
+ const String & rMimeType, BOOL /* bSynchron */ )
+{
+ if (!pDocSh)
+ return FALSE;
+
+ // named ranges may have changed -> update aRange
+ if ( aItemStr.Len() )
+ {
+ ScRange aNew;
+ if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange )
+ {
+ aRange = aNew;
+ bRefreshListener = TRUE;
+ }
+ }
+
+ if ( bRefreshListener )
+ {
+ // refresh the listeners now (this is called from a timer)
+
+ EndListeningAll();
+ pDocSh->GetDocument()->StartListeningArea( aRange, &aForwarder );
+ StartListening(*pDocSh);
+ StartListening(*SFX_APP());
+ bRefreshListener = FALSE;
+ }
+
+ String aDdeTextFmt = pDocSh->GetDdeTextFmt();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ))
+ {
+ ScImportExport aObj( pDoc, aRange );
+ if( aDdeTextFmt.GetChar(0) == 'F' )
+ aObj.SetFormulas( TRUE );
+ if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
+ aDdeTextFmt.EqualsAscii( "FSYLK" ) )
+ {
+ ByteString aByteData;
+ if( aObj.ExportByteString( aByteData, gsl_getSystemTextEncoding(), SOT_FORMATSTR_ID_SYLK ) )
+ {
+ rData <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
+ (sal_Int8*)aByteData.GetBuffer(),
+ aByteData.Len() + 1 );
+ return 1;
+ }
+ return 0;
+ }
+ if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
+ aDdeTextFmt.EqualsAscii( "FCSV" ) )
+ aObj.SetSeparator( ',' );
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
+ return aObj.ExportData( rMimeType, rData ) ? 1 : 0;
+ }
+
+ ScImportExport aObj( pDoc, aRange );
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
+ if( aObj.IsRef() )
+ return aObj.ExportData( rMimeType, rData ) ? 1 : 0;
+ return 0;
+}
+
+void __EXPORT ScServerObject::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ BOOL bDataChanged = FALSE;
+
+ // DocShell can't be tested via type info, because SFX_HINT_DYING comes from the dtor
+ if ( &rBC == pDocSh )
+ {
+ // from DocShell, only SFX_HINT_DYING is interesting
+ if ( rHint.ISA(SfxSimpleHint) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocSh = NULL;
+ EndListening(*SFX_APP());
+ // don't access DocShell anymore for EndListening etc.
+ }
+ }
+ else if (rBC.ISA(SfxApplication))
+ {
+ if ( aItemStr.Len() && rHint.ISA(SfxSimpleHint) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SC_HINT_AREAS_CHANGED )
+ {
+ // check if named range was modified
+ ScRange aNew;
+ if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange )
+ bDataChanged = TRUE;
+ }
+ }
+ else
+ {
+ // must be from Area broadcasters
+
+ const ScHint* pScHint = PTR_CAST( ScHint, &rHint );
+ if( pScHint && (pScHint->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)) )
+ bDataChanged = TRUE;
+ else if (rHint.ISA(ScAreaChangedHint)) // position of broadcaster changed
+ {
+ ScRange aNewRange = ((const ScAreaChangedHint&)rHint).GetRange();
+ if ( aRange != aNewRange )
+ {
+ bRefreshListener = TRUE;
+ bDataChanged = TRUE;
+ }
+ }
+ else if (rHint.ISA(SfxSimpleHint))
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if (nId == SFX_HINT_DYING)
+ {
+ // If the range is being deleted, listening must be restarted
+ // after the deletion is complete (done in GetData)
+ bRefreshListener = TRUE;
+ bDataChanged = TRUE;
+ }
+ }
+ }
+
+ if ( bDataChanged && HasDataLinks() )
+ SvLinkSource::NotifyDataChanged();
+}
+
+
+
+
+
diff --git a/sc/source/ui/docshell/sizedev.cxx b/sc/source/ui/docshell/sizedev.cxx
new file mode 100644
index 000000000000..d89009540156
--- /dev/null
+++ b/sc/source/ui/docshell/sizedev.cxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <sfx2/printer.hxx>
+#include <vcl/virdev.hxx>
+
+#include "sizedev.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "inputopt.hxx"
+
+//------------------------------------------------------------------
+
+ScSizeDeviceProvider::ScSizeDeviceProvider( ScDocShell* pDocSh )
+{
+ BOOL bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
+ if ( bTextWysiwyg )
+ {
+ pDevice = pDocSh->GetPrinter();
+ bOwner = FALSE;
+
+ aOldMapMode = pDevice->GetMapMode();
+ pDevice->SetMapMode( MAP_PIXEL ); // GetNeededSize needs pixel MapMode
+ // printer has right DigitLanguage already
+ }
+ else
+ {
+ pDevice = new VirtualDevice;
+ pDevice->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ bOwner = TRUE;
+ }
+
+ Point aLogic = pDevice->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ nPPTX = aLogic.X() / 1000.0;
+ nPPTY = aLogic.Y() / 1000.0;
+
+ if ( !bTextWysiwyg )
+ nPPTX /= pDocSh->GetOutputFactor();
+}
+
+ScSizeDeviceProvider::~ScSizeDeviceProvider()
+{
+ if (bOwner)
+ delete pDevice;
+ else
+ pDevice->SetMapMode( aOldMapMode );
+}
+
diff --git a/sc/source/ui/docshell/tablink.cxx b/sc/source/ui/docshell/tablink.cxx
new file mode 100644
index 000000000000..697b39052b9f
--- /dev/null
+++ b/sc/source/ui/docshell/tablink.cxx
@@ -0,0 +1,621 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+//------------------------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------
+
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/app.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/transliterationwrapper.hxx>
+
+#include "tablink.hxx"
+
+#include "scextopt.hxx"
+#include "table.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "globstr.hrc"
+#include "undoblk.hxx"
+#include "undotab.hxx"
+#include "global.hxx"
+#include "hints.hxx"
+#include "cell.hxx"
+#include "dociter.hxx"
+#include "formula/opcode.hxx"
+
+struct TableLink_Impl
+{
+ ScDocShell* m_pDocSh;
+ Window* m_pOldParent;
+ Link m_aEndEditLink;
+
+ TableLink_Impl() : m_pDocSh( NULL ), m_pOldParent( NULL ) {}
+};
+
+TYPEINIT1(ScTableLink, ::sfx2::SvBaseLink);
+
+//------------------------------------------------------------------------
+
+ScTableLink::ScTableLink(ScDocShell* pDocSh, const String& rFile,
+ const String& rFilter, const String& rOpt,
+ ULONG nRefresh ):
+ ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE),
+ ScRefreshTimer( nRefresh ),
+ pImpl( new TableLink_Impl ),
+ aFileName(rFile),
+ aFilterName(rFilter),
+ aOptions(rOpt),
+ bInCreate( FALSE ),
+ bInEdit( FALSE ),
+ bAddUndo( TRUE ),
+ bDoPaint( TRUE )
+{
+ pImpl->m_pDocSh = pDocSh;
+}
+
+ScTableLink::ScTableLink(SfxObjectShell* pShell, const String& rFile,
+ const String& rFilter, const String& rOpt,
+ ULONG nRefresh ):
+ ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE),
+ ScRefreshTimer( nRefresh ),
+ pImpl( new TableLink_Impl ),
+ aFileName(rFile),
+ aFilterName(rFilter),
+ aOptions(rOpt),
+ bInCreate( FALSE ),
+ bInEdit( FALSE ),
+ bAddUndo( TRUE ),
+ bDoPaint( TRUE )
+{
+ pImpl->m_pDocSh = static_cast< ScDocShell* >( pShell );
+ SetRefreshHandler( LINK( this, ScTableLink, RefreshHdl ) );
+ SetRefreshControl( pImpl->m_pDocSh->GetDocument()->GetRefreshTimerControlAddress() );
+}
+
+__EXPORT ScTableLink::~ScTableLink()
+{
+ // Verbindung aufheben
+
+ StopRefreshTimer();
+ String aEmpty;
+ ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nCount; nTab++)
+ if (pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab)==aFileName)
+ pDoc->SetLink( nTab, SC_LINK_NONE, aEmpty, aEmpty, aEmpty, aEmpty, 0 );
+ delete pImpl;
+}
+
+void __EXPORT ScTableLink::Edit( Window* pParent, const Link& rEndEditHdl )
+{
+ // DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom
+ // ein Optionen-Dialog kommt...
+
+ pImpl->m_aEndEditLink = rEndEditHdl;
+ pImpl->m_pOldParent = Application::GetDefDialogParent();
+ if (pParent)
+ Application::SetDefDialogParent(pParent);
+
+ bInEdit = TRUE;
+ SvBaseLink::Edit( pParent, LINK( this, ScTableLink, TableEndEditHdl ) );
+}
+
+void __EXPORT ScTableLink::DataChanged( const String&,
+ const ::com::sun::star::uno::Any& )
+{
+ sfx2::LinkManager* pLinkManager=pImpl->m_pDocSh->GetDocument()->GetLinkManager();
+ if (pLinkManager!=NULL)
+ {
+ String aFile;
+ String aFilter;
+ pLinkManager->GetDisplayNames( this,0,&aFile,NULL,&aFilter);
+
+ // the file dialog returns the filter name with the application prefix
+ // -> remove prefix
+ ScDocumentLoader::RemoveAppPrefix( aFilter );
+
+ if (!bInCreate)
+ Refresh( aFile, aFilter, NULL, GetRefreshDelay() ); // don't load twice
+ }
+}
+
+void __EXPORT ScTableLink::Closed()
+{
+ // Verknuepfung loeschen: Undo
+ ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ if (bAddUndo && bUndo)
+ {
+ pImpl->m_pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveLink( pImpl->m_pDocSh, aFileName ) );
+
+ bAddUndo = FALSE; // nur einmal
+ }
+
+ // Verbindung wird im dtor aufgehoben
+
+ SvBaseLink::Closed();
+}
+
+BOOL ScTableLink::IsUsed() const
+{
+ return pImpl->m_pDocSh->GetDocument()->HasLink( aFileName, aFilterName, aOptions );
+}
+
+BOOL ScTableLink::Refresh(const String& rNewFile, const String& rNewFilter,
+ const String* pNewOptions, ULONG nNewRefresh )
+{
+ // Dokument laden
+
+ if (!rNewFile.Len() || !rNewFilter.Len())
+ return FALSE;
+
+ String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pImpl->m_pDocSh ) );
+ BOOL bNewUrlName = (aNewUrl != aFileName);
+
+ const SfxFilter* pFilter = pImpl->m_pDocSh->GetFactory().GetFilterContainer()->GetFilter4FilterName(rNewFilter);
+ if (!pFilter)
+ return FALSE;
+
+ ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
+ pDoc->SetInLinkUpdate( TRUE );
+
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen
+ if ( rNewFilter != aFilterName )
+ aOptions.Erase();
+ if ( pNewOptions ) // Optionen hart angegeben?
+ aOptions = *pNewOptions;
+
+ // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann
+ SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+ if ( aOptions.Len() )
+ pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
+
+ SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, FALSE, pFilter, pSet);
+
+ if ( bInEdit ) // only if using the edit dialog,
+ pMed->UseInteractionHandler( TRUE ); // enable the filter options dialog
+
+ ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL);
+ SfxObjectShellRef aRef = pSrcShell;
+ pSrcShell->DoLoad(pMed);
+
+ // Optionen koennten gesetzt worden sein
+ String aNewOpt = ScDocumentLoader::GetOptions(*pMed);
+ if (!aNewOpt.Len())
+ aNewOpt = aOptions;
+
+ // Undo...
+
+ ScDocument* pUndoDoc = NULL;
+ BOOL bFirst = TRUE;
+ if (bAddUndo && bUndo)
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+
+ // Tabellen kopieren
+
+ ScDocShellModificator aModificator( *pImpl->m_pDocSh );
+
+ BOOL bNotFound = FALSE;
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+
+ // #74835# from text filters that don't set the table name,
+ // use the one table regardless of link table name
+ BOOL bAutoTab = (pSrcDoc->GetTableCount() == 1) &&
+ ScDocShell::HasAutomaticTableName( rNewFilter );
+
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nCount; nTab++)
+ {
+ BYTE nMode = pDoc->GetLinkMode(nTab);
+ if (nMode && pDoc->GetLinkDoc(nTab)==aFileName)
+ {
+ String aTabName = pDoc->GetLinkTab(nTab);
+
+ // Undo
+
+ if (bAddUndo && bUndo)
+ {
+ if (bFirst)
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ else
+ pUndoDoc->AddUndoTab( nTab, nTab, TRUE, TRUE );
+ bFirst = FALSE;
+ ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
+ pDoc->CopyToDocument(aRange, IDF_ALL, FALSE, pUndoDoc);
+ pUndoDoc->TransferDrawPage( pDoc, nTab, nTab );
+ pUndoDoc->SetLink( nTab, nMode, aFileName, aFilterName,
+ aOptions, aTabName, GetRefreshDelay() );
+ }
+
+ // Tabellenname einer ExtDocRef anpassen
+
+ if ( bNewUrlName && nMode == SC_LINK_VALUE )
+ {
+ String aName;
+ pDoc->GetName( nTab, aName );
+ if ( ScGlobal::GetpTransliteration()->isEqual(
+ ScGlobal::GetDocTabName( aFileName, aTabName ), aName ) )
+ {
+ pDoc->RenameTab( nTab,
+ ScGlobal::GetDocTabName( aNewUrl, aTabName ),
+ FALSE, TRUE ); // kein RefUpdate, kein ValidTabName
+ }
+ }
+
+ // kopieren
+
+ SCTAB nSrcTab = 0;
+ bool bFound = false;
+ /* #i71497# check if external document is loaded successfully,
+ otherwise we may find the empty default sheet "Sheet1" in
+ pSrcDoc, even if the document does not exist. */
+ if( pMed->GetError() == 0 )
+ {
+ // no sheet name -> use first sheet
+ if ( aTabName.Len() && !bAutoTab )
+ bFound = pSrcDoc->GetTable( aTabName, nSrcTab );
+ else
+ bFound = true;
+ }
+
+ if (bFound)
+ pDoc->TransferTab( pSrcDoc, nSrcTab, nTab, FALSE, // nicht neu einfuegen
+ (nMode == SC_LINK_VALUE) ); // nur Werte?
+ else
+ {
+ pDoc->DeleteAreaTab( 0,0,MAXCOL,MAXROW, nTab, IDF_ALL );
+
+ bool bShowError = true;
+ if ( nMode == SC_LINK_VALUE )
+ {
+ // #139464# Value link (used with external references in formulas):
+ // Look for formulas that reference the sheet, and put errors in the referenced cells.
+
+ ScRangeList aErrorCells; // cells on the linked sheets that need error values
+
+ ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB ); // all sheets
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+
+ ScDetectiveRefIter aRefIter( pFCell );
+ ScRange aRefRange;
+ while ( aRefIter.GetNextRef( aRefRange ) )
+ {
+ if ( aRefRange.aStart.Tab() <= nTab && aRefRange.aEnd.Tab() >= nTab )
+ {
+ // use first cell of range references (don't fill potentially large ranges)
+
+ aErrorCells.Join( ScRange( aRefRange.aStart ) );
+ }
+ }
+ }
+ pCell = aCellIter.GetNext();
+ }
+
+ ULONG nRanges = aErrorCells.Count();
+ if ( nRanges ) // found any?
+ {
+ ScTokenArray aTokenArr;
+ aTokenArr.AddOpCode( ocNotAvail );
+ aTokenArr.AddOpCode( ocOpen );
+ aTokenArr.AddOpCode( ocClose );
+ aTokenArr.AddOpCode( ocStop );
+
+ for (ULONG nPos=0; nPos<nRanges; nPos++)
+ {
+ const ScRange* pRange = aErrorCells.GetObject(nPos);
+ SCCOL nStartCol = pRange->aStart.Col();
+ SCROW nStartRow = pRange->aStart.Row();
+ SCCOL nEndCol = pRange->aEnd.Col();
+ SCROW nEndRow = pRange->aEnd.Row();
+ for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ ScAddress aDestPos( nCol, nRow, nTab );
+ ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aDestPos, &aTokenArr );
+ pDoc->PutCell( aDestPos, pNewCell );
+ }
+ }
+
+ bShowError = false;
+ }
+ // if no references were found, insert error message (don't leave the sheet empty)
+ }
+
+ if ( bShowError )
+ {
+ // Normal link or no references: put error message on sheet.
+
+ pDoc->SetString( 0,0,nTab, ScGlobal::GetRscString(STR_LINKERROR) );
+ pDoc->SetString( 0,1,nTab, ScGlobal::GetRscString(STR_LINKERRORFILE) );
+ pDoc->SetString( 1,1,nTab, aNewUrl );
+ pDoc->SetString( 0,2,nTab, ScGlobal::GetRscString(STR_LINKERRORTAB) );
+ pDoc->SetString( 1,2,nTab, aTabName );
+ }
+
+ bNotFound = TRUE;
+ }
+
+ if ( bNewUrlName || rNewFilter != aFilterName ||
+ aNewOpt != aOptions || pNewOptions ||
+ nNewRefresh != GetRefreshDelay() )
+ pDoc->SetLink( nTab, nMode, aNewUrl, rNewFilter, aNewOpt,
+ aTabName, nNewRefresh );
+ }
+ }
+
+ // neue Einstellungen merken
+
+ if ( bNewUrlName )
+ aFileName = aNewUrl;
+ if ( rNewFilter != aFilterName )
+ aFilterName = rNewFilter;
+ if ( aNewOpt != aOptions )
+ aOptions = aNewOpt;
+
+ // aufraeumen
+
+// pSrcShell->DoClose();
+ aRef->DoClose();
+
+ // Undo
+
+ if (bAddUndo && bUndo)
+ pImpl->m_pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRefreshLink( pImpl->m_pDocSh, pUndoDoc ) );
+
+ // Paint (koennen mehrere Tabellen sein)
+
+ if (bDoPaint)
+ {
+ pImpl->m_pDocSh->PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB),
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT );
+ aModificator.SetDocumentModified();
+ }
+
+ if (bNotFound)
+ {
+ //! Fehler ausgeben ?
+ }
+
+ pDoc->SetInLinkUpdate( FALSE );
+
+ // notify Uno objects (for XRefreshListener)
+ //! also notify Uno objects if file name was changed!
+ ScLinkRefreshedHint aHint;
+ aHint.SetSheetLink( aFileName );
+ pDoc->BroadcastUno( aHint );
+
+ return TRUE;
+}
+
+IMPL_LINK( ScTableLink, RefreshHdl, ScTableLink*, EMPTYARG )
+{
+ long nRes = Refresh( aFileName, aFilterName, NULL, GetRefreshDelay() ) != 0;
+ return nRes;
+}
+
+IMPL_LINK( ScTableLink, TableEndEditHdl, ::sfx2::SvBaseLink*, pLink )
+{
+ if ( pImpl->m_aEndEditLink.IsSet() )
+ pImpl->m_aEndEditLink.Call( pLink );
+ bInEdit = FALSE;
+ Application::SetDefDialogParent( pImpl->m_pOldParent );
+ return 0;
+}
+
+// === ScDocumentLoader ==================================================
+
+String ScDocumentLoader::GetOptions( SfxMedium& rMedium ) // static
+{
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ const SfxPoolItem* pItem;
+ if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
+ return ((const SfxStringItem*)pItem)->GetValue();
+
+ return EMPTY_STRING;
+}
+
+BOOL ScDocumentLoader::GetFilterName( const String& rFileName,
+ String& rFilter, String& rOptions,
+ BOOL bWithContent, BOOL bWithInteraction ) // static
+{
+ TypeId aScType = TYPE(ScDocShell);
+ SfxObjectShell* pDocSh = SfxObjectShell::GetFirst( &aScType );
+ while ( pDocSh )
+ {
+ if ( pDocSh->HasName() )
+ {
+ SfxMedium* pMed = pDocSh->GetMedium();
+ if ( rFileName == pMed->GetName() )
+ {
+ rFilter = pMed->GetFilter()->GetFilterName();
+ rOptions = GetOptions(*pMed);
+ return TRUE;
+ }
+ }
+ pDocSh = SfxObjectShell::GetNext( *pDocSh, &aScType );
+ }
+
+ INetURLObject aUrl( rFileName );
+ INetProtocol eProt = aUrl.GetProtocol();
+ if ( eProt == INET_PROT_NOT_VALID ) // invalid URL?
+ return FALSE; // abort without creating a medium
+
+ // Filter-Detection
+
+ const SfxFilter* pSfxFilter = NULL;
+ SfxMedium* pMedium = new SfxMedium( rFileName, STREAM_STD_READ, FALSE );
+ if ( pMedium->GetError() == ERRCODE_NONE )
+ {
+ if ( bWithInteraction )
+ pMedium->UseInteractionHandler(TRUE); // #i73992# no longer called from GuessFilter
+
+ SfxFilterMatcher aMatcher( String::CreateFromAscii("scalc") );
+ if( bWithContent )
+ aMatcher.GuessFilter( *pMedium, &pSfxFilter );
+ else
+ aMatcher.GuessFilterIgnoringContent( *pMedium, &pSfxFilter );
+ }
+
+ BOOL bOK = FALSE;
+ if ( pMedium->GetError() == ERRCODE_NONE )
+ {
+ if ( pSfxFilter )
+ rFilter = pSfxFilter->GetFilterName();
+ else
+ rFilter = ScDocShell::GetOwnFilterName(); // sonst Calc-Datei
+ bOK = (rFilter.Len()>0);
+ }
+
+ delete pMedium;
+ return bOK;
+}
+
+void ScDocumentLoader::RemoveAppPrefix( String& rFilterName ) // static
+{
+ String aAppPrefix = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP ));
+ aAppPrefix.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+ xub_StrLen nPreLen = aAppPrefix.Len();
+ if ( rFilterName.Copy(0,nPreLen) == aAppPrefix )
+ rFilterName.Erase(0,nPreLen);
+}
+
+ScDocumentLoader::ScDocumentLoader( const String& rFileName,
+ String& rFilterName, String& rOptions,
+ UINT32 nRekCnt, BOOL bWithInteraction ) :
+ pDocShell(0),
+ pMedium(0)
+{
+ if ( !rFilterName.Len() )
+ GetFilterName( rFileName, rFilterName, rOptions, TRUE, bWithInteraction );
+
+ const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( rFilterName );
+
+ // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann
+ SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+ if ( rOptions.Len() )
+ pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, rOptions ) );
+
+ pMedium = new SfxMedium( rFileName, STREAM_STD_READ, FALSE, pFilter, pSet );
+ if ( pMedium->GetError() != ERRCODE_NONE )
+ return ;
+
+ if ( bWithInteraction )
+ pMedium->UseInteractionHandler( TRUE ); // to enable the filter options dialog
+
+ pDocShell = new ScDocShell( SFX_CREATE_MODE_INTERNAL );
+ aRef = pDocShell;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if( pDoc )
+ {
+ ScExtDocOptions* pExtDocOpt = pDoc->GetExtDocOptions();
+ if( !pExtDocOpt )
+ {
+ pExtDocOpt = new ScExtDocOptions;
+ pDoc->SetExtDocOptions( pExtDocOpt );
+ }
+ pExtDocOpt->GetDocSettings().mnLinkCnt = nRekCnt;
+ }
+
+ pDocShell->DoLoad( pMedium );
+
+ String aNew = GetOptions(*pMedium); // Optionen werden beim Laden per Dialog gesetzt
+ if (aNew.Len() && aNew != rOptions)
+ rOptions = aNew;
+}
+
+ScDocumentLoader::~ScDocumentLoader()
+{
+/* if ( pDocShell )
+ pDocShell->DoClose();
+*/
+ if ( aRef.Is() )
+ aRef->DoClose();
+ else if ( pMedium )
+ delete pMedium;
+}
+
+void ScDocumentLoader::ReleaseDocRef()
+{
+ if ( aRef.Is() )
+ {
+ // release reference without calling DoClose - caller must
+ // have another reference to the doc and call DoClose later
+
+ pDocShell = NULL;
+ pMedium = NULL;
+ aRef.Clear();
+ }
+}
+
+ScDocument* ScDocumentLoader::GetDocument()
+{
+ return pDocShell ? pDocShell->GetDocument() : 0;
+}
+
+BOOL ScDocumentLoader::IsError() const
+{
+ if ( pDocShell && pMedium )
+ return pMedium->GetError() != ERRCODE_NONE;
+ else
+ return TRUE;
+}
+
+String ScDocumentLoader::GetTitle() const
+{
+ if ( pDocShell )
+ return pDocShell->GetTitle();
+ else
+ return EMPTY_STRING;
+}
+
diff --git a/sc/source/ui/docshell/tpstat.cxx b/sc/source/ui/docshell/tpstat.cxx
new file mode 100644
index 000000000000..1072af30c7a1
--- /dev/null
+++ b/sc/source/ui/docshell/tpstat.cxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+#include "tpstat.hrc"
+
+#include "tpstat.hxx"
+
+
+//========================================================================
+// Dokumentinfo-Tabpage:
+//========================================================================
+
+SfxTabPage* __EXPORT ScDocStatPage::Create( Window *pParent, const SfxItemSet& rSet )
+{
+ return new ScDocStatPage( pParent, rSet );
+}
+
+//------------------------------------------------------------------------
+
+ScDocStatPage::ScDocStatPage( Window *pParent, const SfxItemSet& rSet )
+ : SfxTabPage( pParent, ScResId(RID_SCPAGE_STAT), rSet ),
+ aFlInfo ( this, ScResId( FL_INFO ) ),
+ aFtTablesLbl ( this, ScResId( FT_TABLES_LBL ) ),
+ aFtTables ( this, ScResId( FT_TABLES ) ),
+ aFtCellsLbl ( this, ScResId( FT_CELLS_LBL ) ),
+ aFtCells ( this, ScResId( FT_CELLS ) ),
+ aFtPagesLbl ( this, ScResId( FT_PAGES_LBL ) ),
+ aFtPages ( this, ScResId( FT_PAGES ) )
+{
+ ScDocShell* pDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
+ ScDocStat aDocStat;
+
+ if ( pDocSh )
+ pDocSh->GetDocStat( aDocStat );
+
+ String aInfo = aFlInfo.GetText();
+ aInfo += aDocStat.aDocName;
+ aFlInfo .SetText( aInfo );
+ aFtTables .SetText( String::CreateFromInt32( aDocStat.nTableCount ) );
+ aFtCells .SetText( String::CreateFromInt32( aDocStat.nCellCount ) );
+ aFtPages .SetText( String::CreateFromInt32( aDocStat.nPageCount ) );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScDocStatPage::~ScDocStatPage()
+{
+}
+
+//------------------------------------------------------------------------
+
+BOOL __EXPORT ScDocStatPage::FillItemSet( SfxItemSet& /* rSet */ )
+{
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScDocStatPage::Reset( const SfxItemSet& /* rSet */ )
+{
+}
+
+
+
+
diff --git a/sc/source/ui/docshell/tpstat.hrc b/sc/source/ui/docshell/tpstat.hrc
new file mode 100644
index 000000000000..2b57d20f1a26
--- /dev/null
+++ b/sc/source/ui/docshell/tpstat.hrc
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc"
+
+#define FT_TABLES 1
+#define FT_TABLES_LBL 2
+#define FT_CELLS 3
+#define FT_CELLS_LBL 4
+#define FT_PAGES 5
+#define FT_PAGES_LBL 6
+
+#define FL_INFO 1
diff --git a/sc/source/ui/docshell/tpstat.src b/sc/source/ui/docshell/tpstat.src
new file mode 100644
index 000000000000..7226da4642c3
--- /dev/null
+++ b/sc/source/ui/docshell/tpstat.src
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "tpstat.hrc"
+TabPage RID_SCPAGE_STAT
+{
+ // HelpID = HID_DOC_STAT;
+ Hide = TRUE ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedText FT_TABLES_LBL
+ {
+ Pos = MAP_APPFONT ( 12 , 17 ) ;
+ Size = MAP_APPFONT ( 90 , 8 ) ;
+ Text [ en-US ] = "Number of sheets:" ;
+ Left = TRUE ;
+ };
+ FixedText FT_TABLES
+ {
+ Pos = MAP_APPFONT ( 108 , 17 ) ;
+ Size = MAP_APPFONT ( 27 , 8 ) ;
+ Left = TRUE ;
+ };
+ FixedText FT_CELLS_LBL
+ {
+ Pos = MAP_APPFONT ( 12 , 29 ) ;
+ Size = MAP_APPFONT ( 90 , 8 ) ;
+ Text [ en-US ] = "Number of cells:" ;
+ Left = TRUE ;
+ };
+ FixedText FT_CELLS
+ {
+ Pos = MAP_APPFONT ( 108 , 29 ) ;
+ Size = MAP_APPFONT ( 27 , 8 ) ;
+ Left = TRUE ;
+ };
+ FixedText FT_PAGES_LBL
+ {
+ Pos = MAP_APPFONT ( 12 , 41 ) ;
+ Size = MAP_APPFONT ( 90 , 8 ) ;
+ Text [ en-US ] = "Number of pages:" ;
+ Left = TRUE ;
+ };
+ FixedText FT_PAGES
+ {
+ Pos = MAP_APPFONT ( 108 , 41 ) ;
+ Size = MAP_APPFONT ( 27 , 8 ) ;
+ Left = TRUE ;
+ };
+ FixedLine FL_INFO
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Document: " ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/drawfunc/chartsh.cxx b/sc/source/ui/drawfunc/chartsh.cxx
new file mode 100644
index 000000000000..605611f2e309
--- /dev/null
+++ b/sc/source/ui/drawfunc/chartsh.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+#include <editeng/eeitem.hxx>
+#include <svx/fontwork.hxx>
+//CHINA001 #include <svx/labdlg.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/tabline.hxx>
+//CHINA001 #include <svx/transfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "chartsh.hxx"
+#include "drwlayer.hxx"
+#include "sc.hrc"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "drawview.hxx"
+#include "scresid.hxx"
+#include <svx/svdobj.hxx>
+
+#define ScChartShell
+#include "scslots.hxx"
+
+
+SFX_IMPL_INTERFACE(ScChartShell, ScDrawShell, ScResId(SCSTR_CHARTSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
+ ScResId(RID_DRAW_OBJECTBAR) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_CHART) );
+ //SFX_OBJECTMENU_REGISTRATION( SID_OBJECTMENU0, ScResId(RID_OBJECTMENU_DRAW) );
+}
+
+TYPEINIT1( ScChartShell, ScDrawShell );
+
+ScChartShell::ScChartShell(ScViewData* pData) :
+ ScDrawShell(pData)
+{
+ SetHelpId(HID_SCSHELL_CHARTSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ChartObject")));
+}
+
+ScChartShell::~ScChartShell()
+{
+}
+
+
+
diff --git a/sc/source/ui/drawfunc/drawsh.cxx b/sc/source/ui/drawfunc/drawsh.cxx
new file mode 100644
index 000000000000..e2f70432d679
--- /dev/null
+++ b/sc/source/ui/drawfunc/drawsh.cxx
@@ -0,0 +1,503 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+
+#include "scitems.hxx"
+
+#include <editeng/eeitem.hxx>
+#include <svx/fontwork.hxx>
+//#include <svx/labdlg.hxx> CHINA001
+#include <svl/srchitem.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/tabline.hxx>
+//CHINA001 #include <svx/transfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "drawsh.hxx"
+#include "drwlayer.hxx"
+#include "sc.hrc"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "drawview.hxx"
+#include "scresid.hxx"
+#include <svx/svdobj.hxx>
+//add header of cui CHINA001
+#include <svx/svxdlg.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/drawitem.hxx>
+#include <svx/xtable.hxx>
+
+#define ScDrawShell
+#include "scslots.hxx"
+
+#include "userdat.hxx"
+#include <sfx2/objsh.hxx>
+#include <svl/macitem.hxx>
+#include <sfx2/evntconf.hxx>
+#include <sfx2/viewsh.hxx>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+
+//------------------------------------------------------------------
+
+TYPEINIT1( ScDrawShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScDrawShell, SfxShell, ScResId(SCSTR_DRAWSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
+ ScResId(RID_DRAW_OBJECTBAR) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_DRAW) );
+ SFX_CHILDWINDOW_REGISTRATION( SvxFontWorkChildWindow::GetChildWindowId() );
+}
+
+
+// abschalten der nicht erwuenschten Acceleratoren:
+
+void ScDrawShell::StateDisableItems( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void lcl_setModified( SfxObjectShell* pShell )
+{
+ if ( pShell )
+ {
+ com::sun::star::uno::Reference< com::sun::star::util::XModifiable > xModif( pShell->GetModel(), com::sun::star::uno::UNO_QUERY );
+ if ( xModif.is() )
+ xModif->setModified( sal_True );
+ }
+}
+
+void ScDrawShell::ExecDrawAttr( SfxRequest& rReq )
+{
+ USHORT nSlot = rReq.GetSlot();
+ Window* pWin = pViewData->GetActiveWin();
+// SfxViewFrame* pViewFrame = SfxViewShell::Current()->GetViewFrame(); //!!! koennte knallen
+ ScDrawView* pView = pViewData->GetScDrawView();
+ SdrModel* pDoc = pViewData->GetDocument()->GetDrawLayer();
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+ SdrObject* pSingleSelectedObj = NULL;
+ if ( nMarkCount > 0 )
+ pSingleSelectedObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+
+ switch ( nSlot )
+ {
+ case SID_ASSIGNMACRO:
+ {
+ if ( pSingleSelectedObj )
+ ExecuteMacroAssign( pSingleSelectedObj, pWin );
+ }
+ break;
+
+ case SID_TEXT_STANDARD: // Harte Textattributierung loeschen
+ {
+ SfxItemSet aEmptyAttr(GetPool(), EE_ITEMS_START, EE_ITEMS_END);
+ pView->SetAttributes(aEmptyAttr, TRUE);
+ }
+ break;
+
+ case SID_ATTR_LINE_STYLE:
+ case SID_ATTR_LINEEND_STYLE:
+ case SID_ATTR_LINE_DASH:
+ case SID_ATTR_LINE_WIDTH:
+ case SID_ATTR_LINE_COLOR:
+ case SID_ATTR_FILL_STYLE:
+ case SID_ATTR_FILL_COLOR:
+ case SID_ATTR_FILL_GRADIENT:
+ case SID_ATTR_FILL_HATCH:
+ case SID_ATTR_FILL_BITMAP:
+
+ // #i25616#
+ case SID_ATTR_FILL_SHADOW:
+ {
+ // Wenn ToolBar vertikal :
+ if ( !rReq.GetArgs() )
+ {
+ switch ( nSlot )
+ {
+ case SID_ATTR_LINE_STYLE:
+ case SID_ATTR_LINE_DASH:
+ case SID_ATTR_LINE_WIDTH:
+ case SID_ATTR_LINE_COLOR:
+ ExecuteLineDlg( rReq );
+ break;
+
+ case SID_ATTR_FILL_STYLE:
+ case SID_ATTR_FILL_COLOR:
+ case SID_ATTR_FILL_GRADIENT:
+ case SID_ATTR_FILL_HATCH:
+ case SID_ATTR_FILL_BITMAP:
+
+ // #i25616#
+ case SID_ATTR_FILL_SHADOW:
+
+ ExecuteAreaDlg( rReq );
+ break;
+
+ default:
+ break;
+ }
+
+ //=====
+ return;
+ //=====
+ }
+
+ if( pView->AreObjectsMarked() )
+ pView->SetAttrToMarked( *rReq.GetArgs(), FALSE );
+ else
+ pView->SetDefaultAttr( *rReq.GetArgs(), FALSE);
+ pView->InvalidateAttribs();
+ }
+ break;
+
+ case SID_ATTRIBUTES_LINE:
+ ExecuteLineDlg( rReq );
+ break;
+
+ case SID_ATTRIBUTES_AREA:
+ ExecuteAreaDlg( rReq );
+ break;
+
+ case SID_DRAWTEXT_ATTR_DLG:
+ ExecuteTextAttrDlg( rReq );
+ break;
+
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ case SID_DRAW_HLINK_EDIT:
+ if ( pSingleSelectedObj )
+ pViewData->GetDispatcher().Execute( SID_HYPERLINK_DIALOG );
+ break;
+
+ case SID_DRAW_HLINK_DELETE:
+ if ( pSingleSelectedObj )
+ SetHlinkForObject( pSingleSelectedObj, rtl::OUString() );
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ if ( nMarkCount == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if ( pObj->IsGroupObject() )
+ {
+ SdrPageView* pPV = 0;
+ SdrObject* pHit = 0;
+ if ( pView->PickObj( pWin->PixelToLogic( pViewData->GetMousePosPixel() ), pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
+ pObj = pHit;
+ }
+
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
+ if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
+ ScGlobal::OpenURL( pInfo->GetHlink(), String::EmptyString() );
+ }
+ break;
+#endif
+
+ case SID_ATTR_TRANSFORM:
+ {
+ if ( pView->AreObjectsMarked() )
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ if( !pArgs )
+ {
+ // const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( rMarkList.GetMark(0) != 0 )
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if( pObj->GetObjIdentifier() == OBJ_CAPTION )
+ {
+ // --------- Itemset fuer Caption --------
+ SfxItemSet aNewAttr(pDoc->GetItemPool());
+ pView->GetAttributes(aNewAttr);
+ // --------- Itemset fuer Groesse und Position --------
+ SfxItemSet aNewGeoAttr(pView->GetGeoAttrFromMarked());
+
+ //SvxCaptionTabDialog* pDlg = new SvxCaptionTabDialog(pWin, pView);
+ //change for cui CHINA001
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if ( pFact )
+ {
+ SfxAbstractTabDialog *pDlg = pFact->CreateCaptionDialog( pWin, pView );
+
+ const USHORT* pRange = pDlg->GetInputRanges( *aNewAttr.GetPool() );
+ SfxItemSet aCombSet( *aNewAttr.GetPool(), pRange );
+ aCombSet.Put( aNewAttr );
+ aCombSet.Put( aNewGeoAttr );
+ pDlg->SetInputSet( &aCombSet );
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ rReq.Done(*(pDlg->GetOutputItemSet()));
+ pView->SetAttributes(*pDlg->GetOutputItemSet());
+ pView->SetGeoAttrToMarked(*pDlg->GetOutputItemSet());
+ }
+
+ delete pDlg;
+ }// change for cui
+ }
+ else
+ {
+ SfxItemSet aNewAttr(pView->GetGeoAttrFromMarked());
+ //CHINA001 SvxTransformTabDialog* pDlg = new SvxTransformTabDialog(pWin, &aNewAttr, pView);
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ SfxAbstractTabDialog* pDlg = pFact->CreateSvxTransformTabDialog( pWin, &aNewAttr,pView );
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ if (pDlg->Execute() == RET_OK)
+ {
+ rReq.Done(*(pDlg->GetOutputItemSet()));
+ pView->SetGeoAttrToMarked(*pDlg->GetOutputItemSet());
+ }
+ delete pDlg;
+ }
+ }
+ }
+
+
+ }
+ else
+ pView->SetGeoAttrToMarked( *pArgs );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ScDrawShell::ExecuteMacroAssign( SdrObject* pObj, Window* pWin )
+{
+ SvxMacroItem aItem ( SFX_APP()->GetPool().GetWhich( SID_ATTR_MACROITEM ) );
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj, TRUE );
+ if ( pInfo->GetMacro().getLength() > 0 )
+ {
+ SvxMacroTableDtor aTab;
+ String sMacro( pInfo->GetMacro() );
+ aTab.Insert( SFX_EVENT_MOUSECLICK_OBJECT, new SvxMacro( sMacro, String() ) );
+ aItem.SetMacroTable( aTab );
+ }
+
+ // create empty itemset for macro-dlg
+ SfxItemSet* pItemSet = new SfxItemSet(SFX_APP()->GetPool(), SID_ATTR_MACROITEM, SID_ATTR_MACROITEM, SID_EVENTCONFIG, SID_EVENTCONFIG, 0 );
+ pItemSet->Put ( aItem, SID_ATTR_MACROITEM );
+
+ SfxEventNamesItem aNamesItem(SID_EVENTCONFIG);
+ aNamesItem.AddEvent( ScResId(RID_SCSTR_ONCLICK), String(), SFX_EVENT_MOUSECLICK_OBJECT );
+ pItemSet->Put( aNamesItem, SID_EVENTCONFIG );
+
+ com::sun::star::uno::Reference < com::sun::star::frame::XFrame > xFrame;
+ if (GetViewShell())
+ xFrame = GetViewShell()->GetViewFrame()->GetFrame().GetFrameInterface();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractDialog* pMacroDlg = pFact->CreateSfxDialog( pWin, *pItemSet, xFrame, SID_EVENTCONFIG );
+ if ( pMacroDlg && pMacroDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pMacroDlg->GetOutputItemSet();
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pOutSet->GetItemState( SID_ATTR_MACROITEM, FALSE, &pItem ))
+ {
+ rtl::OUString sMacro;
+ SvxMacro* pMacro = ((SvxMacroItem*)pItem)->GetMacroTable().Get( SFX_EVENT_MOUSECLICK_OBJECT );
+ if ( pMacro )
+ sMacro = pMacro->GetMacName();
+
+ if ( pObj->IsGroupObject() )
+ {
+ SdrObjList* pOL = pObj->GetSubList();
+ ULONG nObj = pOL->GetObjCount();
+ for ( ULONG index=0; index<nObj; ++index )
+ {
+ pInfo = ScDrawLayer::GetMacroInfo( pOL->GetObj(index), TRUE );
+ pInfo->SetMacro( sMacro );
+ }
+ }
+ else
+ pInfo->SetMacro( sMacro );
+ lcl_setModified( GetObjectShell() );
+ }
+ }
+
+ delete pMacroDlg;
+ delete pItemSet;
+}
+
+void ScDrawShell::ExecuteLineDlg( SfxRequest& rReq, USHORT nTabPage )
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+ BOOL bHasMarked = pView->AreObjectsMarked();
+ const SdrObject* pObj = NULL;
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if( rMarkList.GetMarkCount() == 1 )
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ SfxItemSet aNewAttr( pView->GetDefaultAttr() );
+ if( bHasMarked )
+ pView->MergeAttrFromMarked( aNewAttr, FALSE );
+
+//CHINA001 SvxLineTabDialog* pDlg
+//CHINA001 = new SvxLineTabDialog( pViewData->GetDialogParent(),
+//CHINA001 &aNewAttr,
+//CHINA001 pViewData->GetDocument()->GetDrawLayer(),
+//CHINA001 pObj,
+//CHINA001 bHasMarked );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "Dialogdiet Factory fail!");//CHINA001
+ SfxAbstractTabDialog * pDlg = pFact->CreateSvxLineTabDialog( pViewData->GetDialogParent(),
+ &aNewAttr,
+ pViewData->GetDocument()->GetDrawLayer(),
+ pObj,
+ bHasMarked);
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ if ( nTabPage != 0xffff )
+ pDlg->SetCurPageId( nTabPage );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ if( bHasMarked )
+ pView->SetAttrToMarked( *pDlg->GetOutputItemSet(), FALSE );
+ else
+ pView->SetDefaultAttr( *pDlg->GetOutputItemSet(), FALSE );
+
+ pView->InvalidateAttribs();
+ rReq.Done();
+ }
+
+ delete pDlg;
+}
+
+void ScDrawShell::ExecuteAreaDlg( SfxRequest& rReq, USHORT nTabPage )
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+ BOOL bHasMarked = pView->AreObjectsMarked();
+
+ SfxItemSet aNewAttr( pView->GetDefaultAttr() );
+ if( bHasMarked )
+ pView->MergeAttrFromMarked( aNewAttr, FALSE );
+
+ //CHINA001 SvxAreaTabDialog* pDlg
+ //CHINA001 = new SvxAreaTabDialog( pViewData->GetDialogParent(),
+//CHINA001 &aNewAttr,
+//CHINA001 pViewData->GetDocument()->GetDrawLayer(),
+//CHINA001 pView );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "Dialogdiet Factory fail!");//CHINA001
+ AbstractSvxAreaTabDialog * pDlg = pFact->CreateSvxAreaTabDialog( pViewData->GetDialogParent(),
+ &aNewAttr,
+ pViewData->GetDocument()->GetDrawLayer(),
+ pView);
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+
+ // #i74099# by default, the dialog deletes the current color table if a different one is loaded
+ // (see SwDrawShell::ExecDrawDlg)
+ const SvxColorTableItem* pColorItem =
+ static_cast<const SvxColorTableItem*>( pViewData->GetSfxDocShell()->GetItem(SID_COLOR_TABLE) );
+ if (pColorItem->GetColorTable() == XColorTable::GetStdColorTable())
+ pDlg->DontDeleteColorTable();
+
+ if ( nTabPage != 0xffff )
+ pDlg->SetCurPageId( nTabPage );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ if( bHasMarked )
+ pView->SetAttrToMarked( *pDlg->GetOutputItemSet(), FALSE );
+ else
+ pView->SetDefaultAttr( *pDlg->GetOutputItemSet(), FALSE );
+
+ pView->InvalidateAttribs();
+ rReq.Done();
+ }
+
+ delete pDlg;
+}
+
+void ScDrawShell::ExecuteTextAttrDlg( SfxRequest& rReq, USHORT /* nTabPage */ )
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+ BOOL bHasMarked = pView->AreObjectsMarked();
+ SfxItemSet aNewAttr ( pView->GetDefaultAttr() );
+
+ if( bHasMarked )
+ pView->MergeAttrFromMarked( aNewAttr, FALSE );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractTabDialog *pDlg = pFact->CreateTextTabDialog( pViewData->GetDialogParent(), &aNewAttr, pView );
+
+ USHORT nResult = pDlg->Execute();
+
+ if ( RET_OK == nResult )
+ {
+ if ( bHasMarked )
+ pView->SetAttributes( *pDlg->GetOutputItemSet() );
+ else
+ pView->SetDefaultAttr( *pDlg->GetOutputItemSet(), FALSE );
+
+ pView->InvalidateAttribs();
+ rReq.Done();
+ }
+ delete( pDlg );
+}
+
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+void ScDrawShell::SetHlinkForObject( SdrObject* pObj, const rtl::OUString& rHlnk )
+{
+ if ( pObj )
+ {
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj, TRUE );
+ pInfo->SetHlink( rHlnk );
+ lcl_setModified( GetObjectShell() );
+ }
+}
+#endif
+
diff --git a/sc/source/ui/drawfunc/drawsh2.cxx b/sc/source/ui/drawfunc/drawsh2.cxx
new file mode 100644
index 000000000000..7da571fc05a7
--- /dev/null
+++ b/sc/source/ui/drawfunc/drawsh2.cxx
@@ -0,0 +1,399 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------
+#include <com/sun/star/embed/EmbedMisc.hpp>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/xdef.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/whiter.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+
+#include "drawsh.hxx"
+#include "drawview.hxx"
+#include "viewdata.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include <svx/svdoole2.hxx>
+#include <svx/svdocapt.hxx>
+
+USHORT ScGetFontWorkId(); // in drtxtob
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+ScDrawShell::ScDrawShell( ScViewData* pData ) :
+ SfxShell(pData->GetViewShell()),
+ pViewData( pData )
+{
+ SetPool( &pViewData->GetScDrawView()->GetModel()->GetItemPool() );
+ SfxUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_DRAWSH );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Drawing")));
+}
+
+ScDrawShell::~ScDrawShell()
+{
+}
+
+void ScDrawShell::GetState( SfxItemSet& rSet ) // Zustaende / Toggles
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+ SdrDragMode eMode = pView->GetDragMode();
+
+ rSet.Put( SfxBoolItem( SID_OBJECT_ROTATE, eMode == SDRDRAG_ROTATE ) );
+ rSet.Put( SfxBoolItem( SID_OBJECT_MIRROR, eMode == SDRDRAG_MIRROR ) );
+ rSet.Put( SfxBoolItem( SID_BEZIER_EDIT, !pView->IsFrameDragSingles() ) );
+
+ USHORT nFWId = ScGetFontWorkId();
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ rSet.Put(SfxBoolItem(SID_FONTWORK, pViewFrm->HasChildWindow(nFWId)));
+
+ // Notes always default to Page anchor.
+ bool bDisableAnchor = false;
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+ if ( nMarkCount == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( ScDrawLayer::IsNoteCaption( pObj ) )
+ {
+ bDisableAnchor = true;
+ rSet.DisableItem( SID_ANCHOR_PAGE );
+ rSet.DisableItem( SID_ANCHOR_CELL );
+ }
+ }
+
+ if ( !bDisableAnchor )
+ {
+ switch( pView->GetAnchor() )
+ {
+ case SCA_PAGE:
+ rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, TRUE ) );
+ rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, FALSE ) );
+ break;
+
+ case SCA_CELL:
+ rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, FALSE ) );
+ rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, TRUE ) );
+ break;
+
+ default:
+ rSet.Put( SfxBoolItem( SID_ANCHOR_PAGE, FALSE ) );
+ rSet.Put( SfxBoolItem( SID_ANCHOR_CELL, FALSE ) );
+ break;
+ }
+ }
+}
+
+void ScDrawShell::GetDrawFuncState( SfxItemSet& rSet ) // Funktionen disablen
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+
+ // #111711# call IsMirrorAllowed first to make sure ForcePossibilities (and thus CheckMarked)
+ // is called before GetMarkCount, so the nMarkCount value is valid for the rest of this method.
+ if (!pView->IsMirrorAllowed(TRUE,TRUE))
+ {
+ rSet.DisableItem( SID_MIRROR_HORIZONTAL );
+ rSet.DisableItem( SID_MIRROR_VERTICAL );
+ }
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+
+ if ( nMarkCount <= 1 || !pView->IsGroupPossible() )
+ rSet.DisableItem( SID_GROUP );
+ if ( nMarkCount == 0 || !pView->IsUnGroupPossible() )
+ rSet.DisableItem( SID_UNGROUP );
+ if ( nMarkCount != 1 || !pView->IsGroupEnterPossible() )
+ rSet.DisableItem( SID_ENTER_GROUP );
+ if ( !pView->IsGroupEntered() )
+ rSet.DisableItem( SID_LEAVE_GROUP );
+
+ if ( nMarkCount <= 1 ) // nichts oder nur ein Objekt selektiert
+ {
+ // Ausrichtung
+ rSet.DisableItem( SID_OBJECT_ALIGN_LEFT ); // keine Ausrichtung an der Seite
+ rSet.DisableItem( SID_OBJECT_ALIGN_CENTER );
+ rSet.DisableItem( SID_OBJECT_ALIGN_RIGHT );
+ rSet.DisableItem( SID_OBJECT_ALIGN_UP );
+ rSet.DisableItem( SID_OBJECT_ALIGN_MIDDLE );
+ rSet.DisableItem( SID_OBJECT_ALIGN_DOWN );
+
+ // pseudo slots for Format menu
+ rSet.DisableItem( SID_ALIGN_ANY_LEFT );
+ rSet.DisableItem( SID_ALIGN_ANY_HCENTER );
+ rSet.DisableItem( SID_ALIGN_ANY_RIGHT );
+ rSet.DisableItem( SID_ALIGN_ANY_TOP );
+ rSet.DisableItem( SID_ALIGN_ANY_VCENTER );
+ rSet.DisableItem( SID_ALIGN_ANY_BOTTOM );
+ }
+
+ // do not change layer of form controls
+ // #158385# #i83729# do not change layer of cell notes (on internal layer)
+ if ( !nMarkCount || pView->HasMarkedControl() || pView->HasMarkedInternal() )
+ {
+ rSet.DisableItem( SID_OBJECT_HEAVEN );
+ rSet.DisableItem( SID_OBJECT_HELL );
+ }
+ else
+ {
+ if(AreAllObjectsOnLayer(SC_LAYER_FRONT,rMarkList))
+ {
+ rSet.DisableItem( SID_OBJECT_HEAVEN );
+ }
+ else if(AreAllObjectsOnLayer(SC_LAYER_BACK,rMarkList))
+ {
+ rSet.DisableItem( SID_OBJECT_HELL );
+ }
+ }
+
+ BOOL bCanRename = FALSE;
+ if ( nMarkCount > 1 )
+ {
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ // no hypelink options for a selected group
+ rSet.DisableItem( SID_DRAW_HLINK_EDIT );
+ rSet.DisableItem( SID_DRAW_HLINK_DELETE );
+ rSet.DisableItem( SID_OPEN_HYPERLINK );
+#endif
+ }
+ else if ( nMarkCount == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
+ if ( !pInfo || (pInfo->GetHlink().getLength() == 0) )
+ {
+ rSet.DisableItem( SID_DRAW_HLINK_DELETE );
+ rSet.DisableItem( SID_OPEN_HYPERLINK );
+ }
+#endif
+ SdrLayerID nLayerID = pObj->GetLayer();
+ if ( nLayerID != SC_LAYER_INTERN )
+ bCanRename = TRUE; // #i51351# anything except internal objects can be renamed
+
+ // #91929#; don't show original size entry if not possible
+ UINT16 nObjType = pObj->GetObjIdentifier();
+ if ( nObjType == OBJ_OLE2 )
+ {
+ SdrOle2Obj* pOleObj = static_cast<SdrOle2Obj*>(rMarkList.GetMark( 0 )->GetMarkedSdrObj());
+ if (pOleObj->GetObjRef().is() &&
+ ((pOleObj->GetObjRef()->getStatus( pOleObj->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) ) )
+ //TODO/LATER: why different slots in Draw and Calc?
+ rSet.DisableItem(SID_ORIGINALSIZE);
+ }
+ else if ( nObjType == OBJ_CAPTION )
+ {
+ if ( nLayerID == SC_LAYER_INTERN )
+ {
+ // SdrCaptionObj() Notes cannot be cut/copy in isolation from
+ // their cells.
+ rSet.DisableItem( SID_CUT );
+ rSet.DisableItem( SID_COPY );
+ // Notes always default to Page anchor.
+ rSet.DisableItem( SID_ANCHOR_TOGGLE );
+ }
+ }
+ }
+ if ( !bCanRename )
+ {
+ // #i68101#
+ rSet.DisableItem( SID_RENAME_OBJECT );
+ rSet.DisableItem( SID_TITLE_DESCRIPTION_OBJECT );
+ }
+
+ if ( !nMarkCount ) // nichts selektiert
+ {
+ // Anordnung
+ rSet.DisableItem( SID_FRAME_UP );
+ rSet.DisableItem( SID_FRAME_DOWN );
+ rSet.DisableItem( SID_FRAME_TO_TOP );
+ rSet.DisableItem( SID_FRAME_TO_BOTTOM );
+ // Clipboard / loeschen
+ rSet.DisableItem( SID_DELETE );
+ rSet.DisableItem( SID_DELETE_CONTENTS );
+ rSet.DisableItem( SID_CUT );
+ rSet.DisableItem( SID_COPY );
+ // sonstiges
+ rSet.DisableItem( SID_ANCHOR_TOGGLE );
+ rSet.DisableItem( SID_ORIGINALSIZE );
+ rSet.DisableItem( SID_ATTR_TRANSFORM );
+ }
+
+ if ( rSet.GetItemState( SID_ENABLE_HYPHENATION ) != SFX_ITEM_UNKNOWN )
+ {
+ SfxItemSet aAttrs( pView->GetModel()->GetItemPool() );
+ pView->GetAttributes( aAttrs );
+ if( aAttrs.GetItemState( EE_PARA_HYPHENATE ) >= SFX_ITEM_AVAILABLE )
+ {
+ BOOL bValue = ( (const SfxBoolItem&) aAttrs.Get( EE_PARA_HYPHENATE ) ).GetValue();
+ rSet.Put( SfxBoolItem( SID_ENABLE_HYPHENATION, bValue ) );
+ }
+ }
+
+ svx::ExtrusionBar::getState( pView, rSet );
+ svx::FontworkBar::getState( pView, rSet );
+}
+
+//
+// Attribute fuer Drawing-Objekte
+//
+
+void ScDrawShell::GetDrawAttrState( SfxItemSet& rSet )
+{
+ Point aMousePos = pViewData->GetMousePosPixel();
+ Window* pWindow = pViewData->GetActiveWin();
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ Point aPos = pWindow->PixelToLogic(aMousePos);
+ BOOL bHasMarked = pDrView->AreObjectsMarked();
+
+ if( bHasMarked )
+ {
+ rSet.Put( pDrView->GetAttrFromMarked(FALSE) );
+
+ // Wenn die View selektierte Objekte besitzt, muessen entspr. Items
+ // von SFX_ITEM_DEFAULT (_ON) auf SFX_ITEM_DISABLED geaendert werden
+
+ SfxWhichIter aIter( rSet, XATTR_LINE_FIRST, XATTR_FILL_LAST );
+ USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ if( SFX_ITEM_DEFAULT == rSet.GetItemState( nWhich ) )
+ rSet.DisableItem( nWhich );
+
+ nWhich = aIter.NextWhich();
+ }
+ }
+ else
+ rSet.Put( pDrView->GetDefaultAttr() );
+
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ if ( pPV )
+ {
+ // #i52073# when a sheet with an active OLE object is deleted,
+ // the slot state is queried without an active page view
+
+ // Items for position and size (see ScGridWindow::UpdateStatusPosSize, #108137#)
+
+ // #i34458# The SvxSizeItem in SID_TABLE_CELL is no longer needed by
+ // SvxPosSizeStatusBarControl, it's enough to have it in SID_ATTR_SIZE.
+
+ BOOL bActionItem = FALSE;
+ if ( pDrView->IsAction() ) // action rectangle
+ {
+ Rectangle aRect;
+ pDrView->TakeActionRect( aRect );
+ if ( !aRect.IsEmpty() )
+ {
+ pPV->LogicToPagePos(aRect);
+ rSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
+ Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
+ rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize ) );
+ bActionItem = TRUE;
+ }
+ }
+ if ( !bActionItem )
+ {
+ if ( pDrView->AreObjectsMarked() ) // selected objects
+ {
+ Rectangle aRect = pDrView->GetAllMarkedRect();
+ pPV->LogicToPagePos(aRect);
+ rSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
+ Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
+ rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize ) );
+ }
+ else // mouse position
+ {
+ // aPos is initialized above
+ pPV->LogicToPagePos(aPos);
+ rSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos ) );
+ rSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
+ }
+ }
+ }
+}
+
+void ScDrawShell::GetAttrFuncState(SfxItemSet &rSet)
+{
+ // Dialoge fuer Draw-Attribute disablen, wenn noetig
+
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ SfxItemSet aViewSet = pDrView->GetAttrFromMarked(FALSE);
+
+ if ( aViewSet.GetItemState( XATTR_LINESTYLE ) == SFX_ITEM_DEFAULT )
+ {
+ rSet.DisableItem( SID_ATTRIBUTES_LINE );
+ rSet.DisableItem( SID_ATTR_LINEEND_STYLE ); // Tbx-Controller
+ }
+
+ if ( aViewSet.GetItemState( XATTR_FILLSTYLE ) == SFX_ITEM_DEFAULT )
+ rSet.DisableItem( SID_ATTRIBUTES_AREA );
+}
+
+BOOL ScDrawShell::AreAllObjectsOnLayer(USHORT nLayerNo,const SdrMarkList& rMark)
+{
+ BOOL bResult=TRUE;
+ ULONG nCount = rMark.GetMarkCount();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
+ if ( !pObj->ISA(SdrUnoObj) )
+ {
+ if(nLayerNo!=pObj->GetLayer())
+ {
+ bResult=FALSE;
+ break;
+ }
+ }
+ }
+ return bResult;
+}
+
+
diff --git a/sc/source/ui/drawfunc/drawsh4.cxx b/sc/source/ui/drawfunc/drawsh4.cxx
new file mode 100644
index 000000000000..45b26584f29a
--- /dev/null
+++ b/sc/source/ui/drawfunc/drawsh4.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/drawitem.hxx>
+#include <svx/fontwork.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/xdef.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "drawsh.hxx"
+#include "drawview.hxx"
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+
+
+//------------------------------------------------------------------
+
+void ScDrawShell::GetFormTextState(SfxItemSet& rSet)
+{
+ const SdrObject* pObj = NULL;
+ SvxFontWorkDialog* pDlg = NULL;
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ USHORT nId = SvxFontWorkChildWindow::GetChildWindowId();
+
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ if ( pViewFrm->HasChildWindow(nId) )
+ pDlg = (SvxFontWorkDialog*)(pViewFrm->GetChildWindow(nId)->GetWindow());
+
+ if ( rMarkList.GetMarkCount() == 1 )
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ if ( pObj == NULL || !pObj->ISA(SdrTextObj) ||
+ !((SdrTextObj*) pObj)->HasText() )
+ {
+ if ( pDlg )
+ pDlg->SetActive(FALSE);
+
+ rSet.DisableItem(XATTR_FORMTXTSTYLE);
+ rSet.DisableItem(XATTR_FORMTXTADJUST);
+ rSet.DisableItem(XATTR_FORMTXTDISTANCE);
+ rSet.DisableItem(XATTR_FORMTXTSTART);
+ rSet.DisableItem(XATTR_FORMTXTMIRROR);
+ rSet.DisableItem(XATTR_FORMTXTSTDFORM);
+ rSet.DisableItem(XATTR_FORMTXTHIDEFORM);
+ rSet.DisableItem(XATTR_FORMTXTOUTLINE);
+ rSet.DisableItem(XATTR_FORMTXTSHADOW);
+ rSet.DisableItem(XATTR_FORMTXTSHDWCOLOR);
+ rSet.DisableItem(XATTR_FORMTXTSHDWXVAL);
+ rSet.DisableItem(XATTR_FORMTXTSHDWYVAL);
+ }
+ else
+ {
+ if ( pDlg )
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
+ XColorTable* pColorTable = NULL;
+
+ if ( pItem )
+ pColorTable = ((SvxColorTableItem*)pItem)->GetColorTable();
+
+ pDlg->SetActive();
+
+ if ( pColorTable )
+ pDlg->SetColorTable( pColorTable );
+ else
+ { DBG_ERROR( "ColorList not found :-/" ); }
+ }
+ }
+ SfxItemSet aViewAttr(pDrView->GetModel()->GetItemPool());
+ pDrView->GetAttributes(aViewAttr);
+ rSet.Set(aViewAttr);
+ }
+}
+
+
+
diff --git a/sc/source/ui/drawfunc/drawsh5.cxx b/sc/source/ui/drawfunc/drawsh5.cxx
new file mode 100644
index 000000000000..e79097ef8874
--- /dev/null
+++ b/sc/source/ui/drawfunc/drawsh5.cxx
@@ -0,0 +1,760 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/eeitem.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/bindings.hxx>
+#include <tools/urlobj.hxx>
+//CHINA001 #include <svx/dlgname.hxx>
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+#include <svx/fmglob.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svx/fontwork.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/xdef.hxx>
+#include <svx/xftsfit.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <sfx2/docfile.hxx>
+
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+
+#include "drawsh.hxx"
+#include "drawview.hxx"
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+//CHINA001 #include "strindlg.hxx"
+#include "scresid.hxx"
+#include "undotab.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "postit.hxx"
+
+#include "sc.hrc"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+void ScDrawShell::GetHLinkState( SfxItemSet& rSet ) // Hyperlink
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+
+ // Hyperlink
+
+ SvxHyperlinkItem aHLinkItem;
+
+ if ( nMarkCount == 1 ) // URL-Button markiert ?
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
+ if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
+ {
+ aHLinkItem.SetURL( pInfo->GetHlink() );
+ aHLinkItem.SetInsertMode(HLINK_FIELD);
+ }
+#endif
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObj);
+ if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
+ {
+ uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
+ DBG_ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
+
+ rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" );
+ rtl::OUString sPropTargetURL = rtl::OUString::createFromAscii( "TargetURL" );
+ rtl::OUString sPropTargetFrame = rtl::OUString::createFromAscii( "TargetFrame" );
+ rtl::OUString sPropLabel = rtl::OUString::createFromAscii( "Label" );
+
+ if(xInfo->hasPropertyByName( sPropButtonType ))
+ {
+ uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
+ form::FormButtonType eTmp;
+ if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
+ {
+ rtl::OUString sTmp;
+ // Label
+ if(xInfo->hasPropertyByName( sPropLabel ))
+ {
+ aAny = xPropSet->getPropertyValue( sPropLabel );
+ if ( (aAny >>= sTmp) && sTmp.getLength() )
+ {
+ aHLinkItem.SetName(sTmp);
+ }
+ }
+ // URL
+ if(xInfo->hasPropertyByName( sPropTargetURL ))
+ {
+ aAny = xPropSet->getPropertyValue( sPropTargetURL );
+ if ( (aAny >>= sTmp) && sTmp.getLength() )
+ {
+ aHLinkItem.SetURL(sTmp);
+ }
+ }
+ // Target
+ if(xInfo->hasPropertyByName( sPropTargetFrame ))
+ {
+ aAny = xPropSet->getPropertyValue( sPropTargetFrame );
+ if ( (aAny >>= sTmp) && sTmp.getLength() )
+ {
+ aHLinkItem.SetTargetFrame(sTmp);
+ }
+ }
+ aHLinkItem.SetInsertMode(HLINK_BUTTON);
+ }
+ }
+ }
+ }
+
+ rSet.Put(aHLinkItem);
+}
+
+void ScDrawShell::ExecuteHLink( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem;
+ const String& rName = pHyper->GetName();
+ const String& rURL = pHyper->GetURL();
+ const String& rTarget = pHyper->GetTargetFrame();
+ SvxLinkInsertMode eMode = pHyper->GetInsertMode();
+
+ BOOL bDone = FALSE;
+ if ( eMode == HLINK_FIELD || eMode == HLINK_BUTTON )
+ {
+ ScDrawView* pView = pViewData->GetScDrawView();
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if ( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObj );
+ if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
+ {
+ uno::Reference<awt::XControlModel> xControlModel =
+ pUnoCtrl->GetUnoControlModel();
+ DBG_ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
+
+ rtl::OUString sPropTargetURL =
+ rtl::OUString::createFromAscii( "TargetURL" );
+
+ // Darf man eine URL an dem Objekt setzen?
+ if (xInfo->hasPropertyByName( sPropTargetURL ))
+ {
+ // Ja!
+
+ rtl::OUString sPropButtonType =
+ rtl::OUString::createFromAscii( "ButtonType" );
+ rtl::OUString sPropTargetFrame =
+ rtl::OUString::createFromAscii( "TargetFrame" );
+ rtl::OUString sPropLabel =
+ rtl::OUString::createFromAscii( "Label" );
+
+ uno::Any aAny;
+ if ( xInfo->hasPropertyByName( sPropLabel ) )
+ {
+ aAny <<= rtl::OUString(rName);
+ xPropSet->setPropertyValue( sPropLabel, aAny );
+ }
+
+ ::rtl::OUString aTmp = INetURLObject::GetAbsURL( pViewData->GetDocShell()->GetMedium()->GetBaseURL(), rURL );
+ aAny <<= aTmp;
+ xPropSet->setPropertyValue( sPropTargetURL, aAny );
+
+ if( rTarget.Len() && xInfo->hasPropertyByName( sPropTargetFrame ) )
+ {
+ aAny <<= rtl::OUString(rTarget);
+ xPropSet->setPropertyValue( sPropTargetFrame, aAny );
+ }
+
+ if ( xInfo->hasPropertyByName( sPropButtonType ) )
+ {
+ form::FormButtonType eButtonType = form::FormButtonType_URL;
+ aAny <<= eButtonType;
+ xPropSet->setPropertyValue( sPropButtonType, aAny );
+ }
+
+ //! Undo ???
+ pViewData->GetDocShell()->SetDocumentModified();
+ bDone = TRUE;
+ }
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ else
+ {
+ SetHlinkForObject( pObj, rURL );
+ bDone = TRUE;
+ }
+#endif
+ }
+ }
+
+ if (!bDone)
+ pViewData->GetViewShell()->
+ InsertURL( rName, rURL, rTarget, (USHORT) eMode );
+
+ // InsertURL an der ViewShell schaltet bei "Text" die DrawShell ab !!!
+ }
+ }
+ break;
+ default:
+ DBG_ERROR("falscher Slot");
+ }
+}
+
+USHORT ScGetFontWorkId(); // wegen CLOOKs - in drtxtob2
+
+//------------------------------------------------------------------
+
+//
+// Funktionen auf Drawing-Objekten
+//
+
+void ScDrawShell::ExecDrawFunc( SfxRequest& rReq )
+{
+ SfxBindings& rBindings = pViewData->GetBindings();
+ ScTabView* pTabView = pViewData->GetView();
+ ScDrawView* pView = pTabView->GetScDrawView();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ USHORT nSlotId = rReq.GetSlot();
+
+ //!!!
+ // wer weiss, wie lange das funktioniert? (->vom Abreisscontrol funktioniert es)
+ //
+ if (nSlotId == SID_OBJECT_ALIGN && pArgs)
+ nSlotId = SID_OBJECT_ALIGN + ((SfxEnumItem&)pArgs->Get(SID_OBJECT_ALIGN)).GetValue() + 1;
+
+ switch (nSlotId)
+ {
+ case SID_OBJECT_HEAVEN:
+ pView->SetMarkedToLayer( SC_LAYER_FRONT );
+ rBindings.Invalidate(SID_OBJECT_HEAVEN);
+ rBindings.Invalidate(SID_OBJECT_HELL);
+ break;
+ case SID_OBJECT_HELL:
+ pView->SetMarkedToLayer( SC_LAYER_BACK );
+ rBindings.Invalidate(SID_OBJECT_HEAVEN);
+ rBindings.Invalidate(SID_OBJECT_HELL);
+ // leave draw shell if nothing selected (layer may be locked)
+ if ( pView->GetMarkedObjectList().GetMarkCount() == 0 )
+ pViewData->GetViewShell()->SetDrawShell( FALSE );
+ break;
+
+ case SID_FRAME_TO_TOP:
+ pView->PutMarkedToTop();
+ break;
+ case SID_FRAME_TO_BOTTOM:
+ pView->PutMarkedToBtm();
+ break;
+ case SID_FRAME_UP:
+ pView->MovMarkedToTop();
+ break;
+ case SID_FRAME_DOWN:
+ pView->MovMarkedToBtm();
+ break;
+
+ case SID_GROUP:
+ pView->GroupMarked();
+ break;
+ case SID_UNGROUP:
+ pView->UnGroupMarked();
+ break;
+ case SID_ENTER_GROUP:
+ pView->EnterMarkedGroup();
+ break;
+ case SID_LEAVE_GROUP:
+ pView->LeaveOneGroup();
+ break;
+
+ case SID_MIRROR_HORIZONTAL:
+ pView->MirrorAllMarkedHorizontal();
+ break;
+ case SID_MIRROR_VERTICAL:
+ pView->MirrorAllMarkedVertical();
+ break;
+
+ case SID_OBJECT_ALIGN_LEFT:
+ case SID_ALIGN_ANY_LEFT:
+ if (pView->IsAlignPossible())
+ pView->AlignMarkedObjects(SDRHALIGN_LEFT, SDRVALIGN_NONE);
+ break;
+ case SID_OBJECT_ALIGN_CENTER:
+ case SID_ALIGN_ANY_HCENTER:
+ if (pView->IsAlignPossible())
+ pView->AlignMarkedObjects(SDRHALIGN_CENTER, SDRVALIGN_NONE);
+ break;
+ case SID_OBJECT_ALIGN_RIGHT:
+ case SID_ALIGN_ANY_RIGHT:
+ if (pView->IsAlignPossible())
+ pView->AlignMarkedObjects(SDRHALIGN_RIGHT, SDRVALIGN_NONE);
+ break;
+ case SID_OBJECT_ALIGN_UP:
+ case SID_ALIGN_ANY_TOP:
+ if (pView->IsAlignPossible())
+ pView->AlignMarkedObjects(SDRHALIGN_NONE, SDRVALIGN_TOP);
+ break;
+ case SID_OBJECT_ALIGN_MIDDLE:
+ case SID_ALIGN_ANY_VCENTER:
+ if (pView->IsAlignPossible())
+ pView->AlignMarkedObjects(SDRHALIGN_NONE, SDRVALIGN_CENTER);
+ break;
+ case SID_OBJECT_ALIGN_DOWN:
+ case SID_ALIGN_ANY_BOTTOM:
+ if (pView->IsAlignPossible())
+ pView->AlignMarkedObjects(SDRHALIGN_NONE, SDRVALIGN_BOTTOM);
+ break;
+
+ case SID_DELETE:
+ case SID_DELETE_CONTENTS:
+ pView->DeleteMarked();
+ if (!pTabView->IsDrawSelMode())
+ pViewData->GetViewShell()->SetDrawShell( FALSE );
+ break;
+
+ case SID_CUT:
+ pView->DoCut();
+ if (!pTabView->IsDrawSelMode())
+ pViewData->GetViewShell()->SetDrawShell( FALSE );
+ break;
+
+ case SID_COPY:
+ pView->DoCopy();
+ break;
+
+ case SID_PASTE:
+ DBG_ERROR( "SdrView::PasteClipboard not supported anymore" );
+ // pView->PasteClipboard( pWin );
+ break;
+
+ case SID_SELECTALL:
+ pView->MarkAll();
+ break;
+
+ case SID_ANCHOR_PAGE:
+ pView->SetAnchor( SCA_PAGE );
+ rBindings.Invalidate( SID_ANCHOR_PAGE );
+ rBindings.Invalidate( SID_ANCHOR_CELL );
+ break;
+
+ case SID_ANCHOR_CELL:
+ pView->SetAnchor( SCA_CELL );
+ rBindings.Invalidate( SID_ANCHOR_PAGE );
+ rBindings.Invalidate( SID_ANCHOR_CELL );
+ break;
+
+ case SID_ANCHOR_TOGGLE:
+ {
+ switch( pView->GetAnchor() )
+ {
+ case SCA_CELL:
+ pView->SetAnchor( SCA_PAGE );
+ break;
+ default:
+ pView->SetAnchor( SCA_CELL );
+ break;
+ }
+ }
+ rBindings.Invalidate( SID_ANCHOR_PAGE );
+ rBindings.Invalidate( SID_ANCHOR_CELL );
+ break;
+
+ case SID_OBJECT_ROTATE:
+ {
+ SdrDragMode eMode;
+ if (pView->GetDragMode() == SDRDRAG_ROTATE)
+ eMode = SDRDRAG_MOVE;
+ else
+ eMode = SDRDRAG_ROTATE;
+ pView->SetDragMode( eMode );
+ rBindings.Invalidate( SID_OBJECT_ROTATE );
+ rBindings.Invalidate( SID_OBJECT_MIRROR );
+ if (eMode == SDRDRAG_ROTATE && !pView->IsFrameDragSingles())
+ {
+ pView->SetFrameDragSingles( TRUE );
+ rBindings.Invalidate( SID_BEZIER_EDIT );
+ }
+ }
+ break;
+ case SID_OBJECT_MIRROR:
+ {
+ SdrDragMode eMode;
+ if (pView->GetDragMode() == SDRDRAG_MIRROR)
+ eMode = SDRDRAG_MOVE;
+ else
+ eMode = SDRDRAG_MIRROR;
+ pView->SetDragMode( eMode );
+ rBindings.Invalidate( SID_OBJECT_ROTATE );
+ rBindings.Invalidate( SID_OBJECT_MIRROR );
+ if (eMode == SDRDRAG_MIRROR && !pView->IsFrameDragSingles())
+ {
+ pView->SetFrameDragSingles( TRUE );
+ rBindings.Invalidate( SID_BEZIER_EDIT );
+ }
+ }
+ break;
+ case SID_BEZIER_EDIT:
+ {
+ BOOL bOld = pView->IsFrameDragSingles();
+ pView->SetFrameDragSingles( !bOld );
+ rBindings.Invalidate( SID_BEZIER_EDIT );
+ if (bOld && pView->GetDragMode() != SDRDRAG_MOVE)
+ {
+ pView->SetDragMode( SDRDRAG_MOVE );
+ rBindings.Invalidate( SID_OBJECT_ROTATE );
+ rBindings.Invalidate( SID_OBJECT_MIRROR );
+ }
+ }
+ break;
+
+ case SID_FONTWORK:
+ {
+ USHORT nId = ScGetFontWorkId();
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+
+ if ( rReq.GetArgs() )
+ pViewFrm->SetChildWindow( nId,
+ ((const SfxBoolItem&)
+ (rReq.GetArgs()->Get(SID_FONTWORK))).
+ GetValue() );
+ else
+ pViewFrm->ToggleChildWindow( nId );
+
+ rBindings.Invalidate( SID_FONTWORK );
+ rReq.Done();
+ }
+ break;
+
+ case SID_ORIGINALSIZE:
+ pView->SetMarkedOriginalSize();
+ break;
+
+ case SID_ENABLE_HYPHENATION:
+ {
+ SFX_REQUEST_ARG( rReq, pItem, SfxBoolItem, SID_ENABLE_HYPHENATION, FALSE);
+ if( pItem )
+ {
+ SfxItemSet aSet( GetPool(), EE_PARA_HYPHENATE, EE_PARA_HYPHENATE );
+ BOOL bValue = ( (const SfxBoolItem*) pItem)->GetValue();
+ aSet.Put( SfxBoolItem( EE_PARA_HYPHENATE, bValue ) );
+ pView->SetAttributes( aSet );
+ }
+ rReq.Done();
+ }
+ break;
+
+ case SID_RENAME_OBJECT:
+ {
+ if(1L == pView->GetMarkedObjectCount())
+ {
+ // #i68101#
+ SdrObject* pSelected = pView->GetMarkedObjectByIndex(0L);
+ OSL_ENSURE(pSelected, "ScDrawShell::ExecDrawFunc: nMarkCount, but no object (!)");
+
+ if(SC_LAYER_INTERN != pSelected->GetLayer())
+ {
+ String aName(pSelected->GetName());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ OSL_ENSURE(pFact, "Dialogdiet fail!");
+ AbstractSvxObjectNameDialog* pDlg = pFact->CreateSvxObjectNameDialog(NULL, aName);
+ OSL_ENSURE(pDlg, "Dialogdiet fail!");
+
+ pDlg->SetCheckNameHdl(LINK(this, ScDrawShell, NameObjectHdl));
+
+ if(RET_OK == pDlg->Execute())
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ pDlg->GetName(aName);
+
+ if(aName != pSelected->GetName())
+ {
+ // handle name change
+ const sal_uInt16 nObjType(pSelected->GetObjIdentifier());
+
+ if(OBJ_GRAF == nObjType && 0L == aName.Len())
+ {
+ // graphics objects must have names
+ // (all graphics are supposed to be in the navigator)
+ ScDrawLayer* pModel = pViewData->GetDocument()->GetDrawLayer();
+
+ if(pModel)
+ {
+ aName = pModel->GetNewGraphicName();
+ }
+ }
+
+ // An undo action for renaming is missing in svdraw (99363).
+ // For OLE objects (which can be identified using the persist name),
+ // ScUndoRenameObject can be used until there is a common action for all objects.
+ if(OBJ_OLE2 == nObjType)
+ {
+ const String aPersistName = static_cast<SdrOle2Obj*>(pSelected)->GetPersistName();
+
+ if(aPersistName.Len())
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRenameObject(pDocSh, aPersistName, pSelected->GetName(), aName));
+ }
+ }
+
+ // set new name
+ pSelected->SetName(aName);
+ }
+
+ // ChartListenerCollectionNeedsUpdate is needed for Navigator update
+ pDocSh->GetDocument()->SetChartListenerCollectionNeedsUpdate( TRUE );
+ pDocSh->SetDrawModified();
+ }
+
+ delete pDlg;
+ }
+ }
+ break;
+ }
+
+ // #i68101#
+ case SID_TITLE_DESCRIPTION_OBJECT:
+ {
+ if(1L == pView->GetMarkedObjectCount())
+ {
+ SdrObject* pSelected = pView->GetMarkedObjectByIndex(0L);
+ OSL_ENSURE(pSelected, "ScDrawShell::ExecDrawFunc: nMarkCount, but no object (!)");
+
+ if(SC_LAYER_INTERN != pSelected->GetLayer())
+ {
+ String aTitle(pSelected->GetTitle());
+ String aDescription(pSelected->GetDescription());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ OSL_ENSURE(pFact, "Dialogdiet fail!");
+ AbstractSvxObjectTitleDescDialog* pDlg = pFact->CreateSvxObjectTitleDescDialog(NULL, aTitle, aDescription);
+ OSL_ENSURE(pDlg, "Dialogdiet fail!");
+
+ if(RET_OK == pDlg->Execute())
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ // handle Title and Description
+ pDlg->GetTitle(aTitle);
+ pDlg->GetDescription(aDescription);
+ pSelected->SetTitle(aTitle);
+ pSelected->SetDescription(aDescription);
+
+ // ChartListenerCollectionNeedsUpdate is needed for Navigator update
+ pDocSh->GetDocument()->SetChartListenerCollectionNeedsUpdate( TRUE );
+ pDocSh->SetDrawModified();
+ }
+
+ delete pDlg;
+ }
+ }
+ break;
+ }
+
+ case SID_EXTRUSION_TOOGLE:
+ case SID_EXTRUSION_TILT_DOWN:
+ case SID_EXTRUSION_TILT_UP:
+ case SID_EXTRUSION_TILT_LEFT:
+ case SID_EXTRUSION_TILT_RIGHT:
+ case SID_EXTRUSION_3D_COLOR:
+ case SID_EXTRUSION_DEPTH:
+ case SID_EXTRUSION_DIRECTION:
+ case SID_EXTRUSION_PROJECTION:
+ case SID_EXTRUSION_LIGHTING_DIRECTION:
+ case SID_EXTRUSION_LIGHTING_INTENSITY:
+ case SID_EXTRUSION_SURFACE:
+ case SID_EXTRUSION_DEPTH_FLOATER:
+ case SID_EXTRUSION_DIRECTION_FLOATER:
+ case SID_EXTRUSION_LIGHTING_FLOATER:
+ case SID_EXTRUSION_SURFACE_FLOATER:
+ case SID_EXTRUSION_DEPTH_DIALOG:
+ svx::ExtrusionBar::execute( pView, rReq, rBindings );
+ rReq.Ignore ();
+ break;
+
+ case SID_FONTWORK_SHAPE:
+ case SID_FONTWORK_SHAPE_TYPE:
+ case SID_FONTWORK_ALIGNMENT:
+ case SID_FONTWORK_SAME_LETTER_HEIGHTS:
+ case SID_FONTWORK_CHARACTER_SPACING:
+ case SID_FONTWORK_KERN_CHARACTER_PAIRS:
+ case SID_FONTWORK_CHARACTER_SPACING_FLOATER:
+ case SID_FONTWORK_ALIGNMENT_FLOATER:
+ case SID_FONTWORK_CHARACTER_SPACING_DIALOG:
+ svx::FontworkBar::execute( pView, rReq, rBindings );
+ rReq.Ignore ();
+ break;
+
+ default:
+ break;
+ }
+}
+
+IMPL_LINK( ScDrawShell, NameObjectHdl, AbstractSvxNameDialog*, pDialog )
+{
+ String aName;
+
+ if( pDialog )
+ pDialog->GetName( aName );
+
+ ScDrawLayer* pModel = pViewData->GetDocument()->GetDrawLayer();
+ if ( aName.Len() && pModel )
+ {
+ SCTAB nDummyTab;
+ if ( pModel->GetNamedObject( aName, 0, nDummyTab ) )
+ {
+ // existing object found -> name invalid
+ return 0;
+ }
+ }
+
+ return 1; // name is valid
+}
+
+//------------------------------------------------------------------
+
+void ScDrawShell::ExecFormText(SfxRequest& rReq)
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+
+ if ( rMarkList.GetMarkCount() == 1 && rReq.GetArgs() )
+ {
+ const SfxItemSet& rSet = *rReq.GetArgs();
+ const SfxPoolItem* pItem;
+
+ if ( pDrView->IsTextEdit() )
+ pDrView->ScEndTextEdit();
+
+ if ( SFX_ITEM_SET ==
+ rSet.GetItemState(XATTR_FORMTXTSTDFORM, TRUE, &pItem)
+ && XFTFORM_NONE !=
+ ((const XFormTextStdFormItem*) pItem)->GetValue() )
+ {
+
+ USHORT nId = SvxFontWorkChildWindow::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ SvxFontWorkDialog* pDlg = (SvxFontWorkDialog*)
+ (pViewFrm->
+ GetChildWindow(nId)->GetWindow());
+
+ pDlg->CreateStdFormObj(*pDrView, *pDrView->GetSdrPageView(),
+ rSet, *rMarkList.GetMark(0)->GetMarkedSdrObj(),
+ ((const XFormTextStdFormItem*) pItem)->
+ GetValue());
+ }
+ else
+ pDrView->SetAttributes(rSet);
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScDrawShell::ExecFormatPaintbrush( SfxRequest& rReq )
+{
+ ScViewFunc* pView = pViewData->GetView();
+ if ( pView->HasPaintBrush() )
+ {
+ // cancel paintbrush mode
+ pView->ResetBrushDocument();
+ }
+ else
+ {
+ BOOL bLock = FALSE;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ if( pArgs && pArgs->Count() >= 1 )
+ bLock = static_cast<const SfxBoolItem&>(pArgs->Get(SID_FORMATPAINTBRUSH)).GetValue();
+
+ ScDrawView* pDrawView = pViewData->GetScDrawView();
+ if ( pDrawView && pDrawView->AreObjectsMarked() )
+ {
+ BOOL bOnlyHardAttr = TRUE;
+ SfxItemSet* pItemSet = new SfxItemSet( pDrawView->GetAttrFromMarked(bOnlyHardAttr) );
+ pView->SetDrawBrushSet( pItemSet, bLock );
+ }
+ }
+}
+
+void ScDrawShell::StateFormatPaintbrush( SfxItemSet& rSet )
+{
+ ScDrawView* pDrawView = pViewData->GetScDrawView();
+ BOOL bSelection = pDrawView && pDrawView->AreObjectsMarked();
+ BOOL bHasPaintBrush = pViewData->GetView()->HasPaintBrush();
+
+ if ( !bHasPaintBrush && !bSelection )
+ rSet.DisableItem( SID_FORMATPAINTBRUSH );
+ else
+ rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, bHasPaintBrush ) );
+}
+
+ScDrawView* ScDrawShell::GetDrawView()
+{
+ return pViewData->GetView()->GetScDrawView();
+}
+
+
+
+
diff --git a/sc/source/ui/drawfunc/drformsh.cxx b/sc/source/ui/drawfunc/drformsh.cxx
new file mode 100644
index 000000000000..44b88738430a
--- /dev/null
+++ b/sc/source/ui/drawfunc/drformsh.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+#include <svx/fontwork.hxx>
+//CHINA001 #include <svx/labdlg.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/tabline.hxx>
+//CHINA001 #include <svx/transfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "drformsh.hxx"
+#include "drwlayer.hxx"
+#include "sc.hrc"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "drawview.hxx"
+#include "scresid.hxx"
+#include <svx/svdobj.hxx>
+
+#define ScDrawFormShell
+#include "scslots.hxx"
+
+
+SFX_IMPL_INTERFACE(ScDrawFormShell, ScDrawShell, ScResId(SCSTR_DRAWFORMSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_FORMAT) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_DRAWFORM) );
+}
+
+TYPEINIT1( ScDrawFormShell, ScDrawShell );
+
+ScDrawFormShell::ScDrawFormShell(ScViewData* pData) :
+ ScDrawShell(pData)
+{
+ SetHelpId(HID_SCSHELL_DRAWFORMSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DrawForm")));
+}
+
+ScDrawFormShell::~ScDrawFormShell()
+{
+}
+
+
+
diff --git a/sc/source/ui/drawfunc/drformsh.src b/sc/source/ui/drawfunc/drformsh.src
new file mode 100644
index 000000000000..65e98eea7b2c
--- /dev/null
+++ b/sc/source/ui/drawfunc/drformsh.src
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+#include "submenu.hrc"
+#include <svx/globlmn.hrc>
+ //
+ // Defines -------------------------------------------------------------------------------
+ //
+#define MN_LAYER\
+ ToolBoxItem\
+ {\
+ Identifier = SID_FRAME_TO_TOP ; \
+ HelpID = SID_FRAME_TO_TOP ; \
+ };\
+ ToolBoxItem\
+ {\
+ Identifier = SID_FRAME_TO_BOTTOM ; \
+ HelpID = SID_FRAME_TO_BOTTOM ; \
+ };
+
+#define MN_RENAME_OBJECT \
+ MenuItem\
+ {\
+ Identifier = SID_RENAME_OBJECT ; \
+ HelpId = SID_RENAME_OBJECT ; \
+ Text [ en-US ] = "Name...";\
+ };
+
+// #i68101#
+#define MN_TITLE_DESCRIPTION_OBJECT \
+ MenuItem\
+ {\
+ Identifier = SID_TITLE_DESCRIPTION_OBJECT; \
+ HelpId = SID_TITLE_DESCRIPTION_OBJECT; \
+ Text [ en-US ] = "Description...";\
+ };
+
+#define MN_ARRANGESUB \
+ MenuItem\
+ {\
+ Identifier = SUBMENU_OBJARRANGE ; \
+ HelpID = HID_SCMENU_OBJARRANGE ; \
+ Text [ en-US ] = "~Arrange" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ ITEM_FORMAT_FRAME_TO_TOP\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_FRAME_UP ; \
+ HelpId = SID_FRAME_UP ; \
+ /* ### ACHTUNG: Neuer Text in Resource? W~eiter nach vorn : Weiter nach vorn */\
+ Text [ en-US ] = "Bring ~Forward" ; \
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_FRAME_DOWN ; \
+ HelpId = SID_FRAME_DOWN ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Weiter ~nach hinten : Weiter nach hinten */\
+ Text [ en-US ] = "Send Back~ward" ; \
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_FRAME_TO_BOTTOM\
+ };\
+ MenuItem { Separator = TRUE ; }; \
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_HEAVEN\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_HELL\
+ };\
+ };\
+ };\
+ };
+
+#define MN_ANCHORSUB \
+ MenuItem\
+ {\
+ Identifier = SUBMENU_ANCHOR ; \
+ HelpID = HID_SCMENU_ANCHOR ; \
+ Text [ en-US ] = "An~chor" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ RadioCheck = TRUE ; \
+ Identifier = SID_ANCHOR_PAGE ; \
+ HelpId = SID_ANCHOR_PAGE ; \
+ Text [ en-US ] = "To P~age" ; \
+ };\
+ MenuItem\
+ {\
+ RadioCheck = TRUE ; \
+ Identifier = SID_ANCHOR_CELL ; \
+ HelpId = SID_ANCHOR_CELL ; \
+ Text [ en-US ] = "To ~Cell" ; \
+ };\
+ };\
+ };\
+ };
+
+#define MN_ALIGNSUB \
+ MenuItem\
+ {\
+ Identifier = SID_OBJECT_ALIGN ; \
+ HelpId = SID_OBJECT_ALIGN ; \
+ Text [ en-US ] = "A~lignment" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_LEFT\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_CENTER\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_RIGHT\
+ };\
+ MenuItem\
+ {\
+ Separator = TRUE ; \
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_UP\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_MIDDLE\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_DOWN\
+ };\
+ };\
+ };\
+ };
+
+
+ // Popup-Menues ---------------------------------------------------------------------
+ //
+String RID_POPUP_DRAWFORM
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Popup-Menü für Zeichenobjekte : Popup-Men³ f³r Zeichenobjekte */
+ Text [ en-US ] = "Popup menu for form objects";
+};
+ //
+ // Popup-Menue fuer (Uno-) Controls
+ //
+Menu RID_POPUP_DRAWFORM
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem { ITEM_FORM_CONTROL_PROPERTIES };
+ MenuItem { ITEM_FORM_PROPERTIES };
+ MenuItem { ITEM_REPLACE_CONTROL };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/drawfunc/drtxtob.cxx b/sc/source/ui/drawfunc/drtxtob.cxx
new file mode 100644
index 000000000000..a5159d8a8043
--- /dev/null
+++ b/sc/source/ui/drawfunc/drtxtob.cxx
@@ -0,0 +1,1095 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//-------------------------------------------------------------------------
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include "scitems.hxx"
+
+#include <editeng/adjitem.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <svx/svdoutl.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <svl/srchitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svtools/cliplistener.hxx>
+#include <svtools/transfer.hxx>
+#include <svl/whiter.hxx>
+#include <svl/languageoptions.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <svx/svxdlg.hxx>
+#include <svx/dialogs.hrc>
+
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "drtxtob.hxx"
+#include "fudraw.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "drawview.hxx"
+#include "viewutil.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+
+#define ScDrawTextObjectBar
+#include "scslots.hxx"
+
+
+using namespace ::com::sun::star;
+
+
+SFX_IMPL_INTERFACE( ScDrawTextObjectBar, SfxShell, ScResId(SCSTR_DRAWTEXTSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
+ ScResId(RID_TEXT_TOOLBOX) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_DRAWTEXT) );
+ SFX_CHILDWINDOW_REGISTRATION( ScGetFontWorkId() );
+}
+
+TYPEINIT1( ScDrawTextObjectBar, SfxShell );
+
+
+
+// abschalten der nicht erwuenschten Acceleratoren:
+
+void ScDrawTextObjectBar::StateDisableItems( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+ScDrawTextObjectBar::ScDrawTextObjectBar(ScViewData* pData) :
+ SfxShell(pData->GetViewShell()),
+ pViewData(pData),
+ pClipEvtLstnr(NULL),
+ bPastePossible(FALSE)
+{
+ SetPool( pViewData->GetScDrawView()->GetDefaultAttr().GetPool() );
+
+ // UndoManager wird beim Umschalten in den Edit-Modus umgesetzt...
+ SfxUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+
+ SetHelpId( HID_SCSHELL_DRTXTOB );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DrawText")));
+}
+
+__EXPORT ScDrawTextObjectBar::~ScDrawTextObjectBar()
+{
+ if ( pClipEvtLstnr )
+ {
+ pClipEvtLstnr->AddRemoveListener( pViewData->GetActiveWin(), FALSE );
+
+ // #122057# The listener may just now be waiting for the SolarMutex and call the link
+ // afterwards, in spite of RemoveListener. So the link has to be reset, too.
+ pClipEvtLstnr->ClearCallbackLink();
+
+ pClipEvtLstnr->release();
+ }
+}
+
+//========================================================================
+//
+// Funktionen
+//
+//========================================================================
+
+void __EXPORT ScDrawTextObjectBar::Execute( SfxRequest &rReq )
+{
+ ScDrawView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ Outliner* pOutliner = pView->GetTextEditOutliner();
+
+ if (!pOutView || !pOutliner)
+ {
+ ExecuteGlobal( rReq ); // auf ganze Objekte
+ return;
+ }
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_COPY:
+ pOutView->Copy();
+ break;
+
+ case SID_CUT:
+ pOutView->Cut();
+ break;
+
+ case SID_PASTE:
+ pOutView->PasteSpecial();
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ ULONG nFormat = 0;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+
+ if ( nFormat )
+ {
+ if (nFormat == SOT_FORMAT_STRING)
+ pOutView->Paste();
+ else
+ pOutView->PasteSpecial();
+ }
+ }
+ break;
+
+ case SID_PASTE_SPECIAL:
+ ExecutePasteContents( rReq );
+ break;
+
+ case SID_SELECTALL:
+ {
+ ULONG nCount = pOutliner->GetParagraphCount();
+ ESelection aSel( 0,0,(USHORT)nCount,0 );
+ pOutView->SetSelection( aSel );
+ }
+ break;
+
+ case SID_CHARMAP:
+ {
+ const SvxFontItem& rItem = (const SvxFontItem&)
+ pOutView->GetAttribs().Get(EE_CHAR_FONTINFO);
+
+ String aString;
+ SvxFontItem aNewItem( EE_CHAR_FONTINFO );
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = 0;
+ if( pArgs )
+ pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), FALSE, &pItem);
+
+ if ( pItem )
+ {
+ aString = ((const SfxStringItem*)pItem)->GetValue();
+ const SfxPoolItem* pFtItem = NULL;
+ pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), FALSE, &pFtItem);
+ const SfxStringItem* pFontItem = PTR_CAST( SfxStringItem, pFtItem );
+ if ( pFontItem )
+ {
+ String aFontName(pFontItem->GetValue());
+ Font aFont(aFontName, Size(1,1)); // Size nur wg. CTOR
+ aNewItem = SvxFontItem( aFont.GetFamily(), aFont.GetName(),
+ aFont.GetStyleName(), aFont.GetPitch(),
+ aFont.GetCharSet(), ATTR_FONT );
+ }
+ else
+ aNewItem = rItem;
+ }
+ else
+ ScViewUtil::ExecuteCharMap( rItem, *pViewData->GetViewShell()->GetViewFrame(), aNewItem, aString );
+
+ if ( aString.Len() )
+ {
+ SfxItemSet aSet( pOutliner->GetEmptyItemSet() );
+ aSet.Put( aNewItem );
+ // SetAttribs an der View selektiert ein Wort, wenn nichts selektiert ist
+ pOutView->GetOutliner()->QuickSetAttribs( aSet, pOutView->GetSelection() );
+ pOutView->InsertText(aString);
+ }
+
+ Invalidate( SID_ATTR_CHAR_FONT );
+ }
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem;
+ const String& rName = pHyper->GetName();
+ const String& rURL = pHyper->GetURL();
+ const String& rTarget = pHyper->GetTargetFrame();
+ SvxLinkInsertMode eMode = pHyper->GetInsertMode();
+
+ BOOL bDone = FALSE;
+ if ( pOutView && ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD ) )
+ {
+ const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection();
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ // altes Feld selektieren
+
+ ESelection aSel = pOutView->GetSelection();
+ aSel.Adjust();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pOutView->SetSelection( aSel );
+ }
+ }
+
+ // neues Feld einfuegen
+
+ SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR );
+ aURLField.SetTargetFrame( rTarget );
+ SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
+ pOutView->InsertField( aURLItem );
+
+ // select new field
+
+ ESelection aSel = pOutView->GetSelection();
+ if ( aSel.nStartPos == aSel.nEndPos && aSel.nStartPos > 0 )
+ {
+ // Cursor is behind the inserted field -> extend selection to the left
+
+ --aSel.nStartPos;
+ pOutView->SetSelection( aSel );
+ }
+
+ bDone = TRUE;
+ }
+
+ if (!bDone)
+ ExecuteGlobal( rReq ); // normal an der View
+
+ // InsertURL an der ViewShell schaltet bei "Text" die DrawShell ab !!!
+ }
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ {
+ if ( pOutView )
+ {
+ const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection();
+ if ( pFieldItem )
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if( pField && pField->ISA( SvxURLField ) )
+ {
+ const SvxURLField* pURLField = static_cast< const SvxURLField* >( pField );
+ ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_ENABLE_HYPHENATION:
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+#if 0 // DR
+ if (IsNoteEdit())
+ {
+ pView->CaptionTextDirection( rReq.GetSlot()); // process Notes before we end the text edit.
+ ExecuteGlobal( rReq );
+ pViewData->GetDispatcher().Execute(pViewData->GetView()->GetDrawFuncPtr()->GetSlotID(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ else
+#endif
+ {
+ pView->ScEndTextEdit(); // end text edit before switching direction
+ ExecuteGlobal( rReq );
+ // restore consistent state between shells and functions:
+ pViewData->GetDispatcher().Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ break;
+
+#if 0
+ // Hyphenation is handled above - text edit is ended
+ case SID_ENABLE_HYPHENATION:
+ // force loading of hyphenator (object is skipped in repaint)
+ ((ScDrawLayer*)pView->GetModel())->UseHyphenator();
+ pOutliner->SetHyphenator( LinguMgr::GetHyphenator() );
+ ExecuteGlobal( rReq );
+ break;
+#endif
+
+ case SID_THES:
+ {
+ String aReplaceText;
+ SFX_REQUEST_ARG( rReq, pItem2, SfxStringItem, SID_THES, sal_False );
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (aReplaceText.Len() > 0)
+ ReplaceTextWithSynonym( pOutView->GetEditView(), aReplaceText );
+ }
+ break;
+
+ case SID_THESAURUS:
+ {
+ pOutView->StartThesaurus();
+ }
+ break;
+
+ }
+}
+
+void __EXPORT ScDrawTextObjectBar::GetState( SfxItemSet& rSet )
+{
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ BOOL bHasFontWork = pViewFrm->HasChildWindow(SID_FONTWORK);
+ BOOL bDisableFontWork = FALSE;
+
+ if (IsNoteEdit())
+ {
+ // #i21255# notes now support rich text formatting (#i74140# but not fontwork)
+ bDisableFontWork = TRUE;
+ }
+
+ if ( bDisableFontWork )
+ rSet.DisableItem( SID_FONTWORK );
+ else
+ rSet.Put(SfxBoolItem(SID_FONTWORK, bHasFontWork));
+
+ if ( rSet.GetItemState( SID_HYPERLINK_GETLINK ) != SFX_ITEM_UNKNOWN )
+ {
+ SvxHyperlinkItem aHLinkItem;
+ SdrView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if ( pOutView )
+ {
+ BOOL bField = FALSE;
+ const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection();
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ const SvxURLField* pURLField = (const SvxURLField*) pField;
+ aHLinkItem.SetName( pURLField->GetRepresentation() );
+ aHLinkItem.SetURL( pURLField->GetURL() );
+ aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() );
+ bField = TRUE;
+ }
+ }
+ if (!bField)
+ {
+ // use selected text as name for urls
+ String sReturn = pOutView->GetSelected();
+ sReturn.Erase(255);
+ sReturn.EraseTrailingChars();
+ aHLinkItem.SetName(sReturn);
+ }
+ }
+ rSet.Put(aHLinkItem);
+ }
+
+ if ( rSet.GetItemState( SID_OPEN_HYPERLINK ) != SFX_ITEM_UNKNOWN )
+ {
+ SdrView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ bool bEnable = false;
+ if ( pOutView )
+ {
+ const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection();
+ if ( pFieldItem )
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ bEnable = pField && pField->ISA( SvxURLField );
+ }
+ }
+ if( !bEnable )
+ rSet.DisableItem( SID_OPEN_HYPERLINK );
+ }
+
+ if( rSet.GetItemState( SID_TRANSLITERATE_HALFWIDTH ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_HALFWIDTH );
+ if( rSet.GetItemState( SID_TRANSLITERATE_FULLWIDTH ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_FULLWIDTH );
+ if( rSet.GetItemState( SID_TRANSLITERATE_HIRAGANA ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_HIRAGANA );
+ if( rSet.GetItemState( SID_TRANSLITERATE_KATAGANA ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_KATAGANA );
+
+ if ( rSet.GetItemState( SID_ENABLE_HYPHENATION ) != SFX_ITEM_UNKNOWN )
+ {
+ SdrView* pView = pViewData->GetScDrawView();
+ SfxItemSet aAttrs( pView->GetModel()->GetItemPool() );
+ pView->GetAttributes( aAttrs );
+ if( aAttrs.GetItemState( EE_PARA_HYPHENATE ) >= SFX_ITEM_AVAILABLE )
+ {
+ BOOL bValue = ( (const SfxBoolItem&) aAttrs.Get( EE_PARA_HYPHENATE ) ).GetValue();
+ rSet.Put( SfxBoolItem( SID_ENABLE_HYPHENATION, bValue ) );
+ }
+ }
+
+ if ( rSet.GetItemState( SID_THES ) != SFX_ITEM_UNKNOWN ||
+ rSet.GetItemState( SID_THESAURUS ) != SFX_ITEM_UNKNOWN )
+ {
+ SdrView * pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+
+ String aStatusVal;
+ LanguageType nLang = LANGUAGE_NONE;
+ bool bIsLookUpWord = false;
+ if ( pOutView )
+ {
+ EditView& rEditView = pOutView->GetEditView();
+ bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, rEditView );
+ }
+ rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
+
+ // disable thesaurus main menu and context menu entry if there is nothing to look up
+ BOOL bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang );
+ if (!bIsLookUpWord || !bCanDoThesaurus)
+ rSet.DisableItem( SID_THES );
+ if (!bCanDoThesaurus)
+ rSet.DisableItem( SID_THESAURUS );
+ }
+}
+
+IMPL_LINK( ScDrawTextObjectBar, ClipboardChanged, TransferableDataHelper*, pDataHelper )
+{
+ if ( pDataHelper )
+ {
+ bPastePossible = ( pDataHelper->HasFormat( SOT_FORMAT_STRING ) || pDataHelper->HasFormat( SOT_FORMAT_RTF ) );
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+ rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ return 0;
+}
+
+void __EXPORT ScDrawTextObjectBar::GetClipState( SfxItemSet& rSet )
+{
+ SdrView* pView = pViewData->GetScDrawView();
+ if ( !pView->GetTextEditOutlinerView() )
+ {
+ GetGlobalClipState( rSet );
+ return;
+ }
+
+ if ( !pClipEvtLstnr )
+ {
+ // create listener
+ pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScDrawTextObjectBar, ClipboardChanged ) );
+ pClipEvtLstnr->acquire();
+ Window* pWin = pViewData->GetActiveWin();
+ pClipEvtLstnr->AddRemoveListener( pWin, TRUE );
+
+ // get initial state
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+ bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PASTE:
+ case SID_PASTE_SPECIAL:
+ if( !bPastePossible )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ if ( bPastePossible )
+ {
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+
+ if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ aFormats.AddClipbrdFormat( SOT_FORMAT_STRING );
+ if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ aFormats.AddClipbrdFormat( SOT_FORMAT_RTF );
+
+ rSet.Put( aFormats );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//========================================================================
+//
+// Attribute
+//
+//========================================================================
+
+void __EXPORT ScDrawTextObjectBar::ExecuteToggle( SfxRequest &rReq )
+{
+ // Unterstreichung
+
+ SdrView* pView = pViewData->GetScDrawView();
+
+ USHORT nSlot = rReq.GetSlot();
+
+ SfxItemSet aSet( pView->GetDefaultAttr() );
+
+ SfxItemSet aViewAttr(pView->GetModel()->GetItemPool());
+ pView->GetAttributes(aViewAttr);
+
+ // Unterstreichung
+ FontUnderline eOld = ((const SvxUnderlineItem&) aViewAttr.
+ Get(EE_CHAR_UNDERLINE)).GetLineStyle();
+ FontUnderline eNew = eOld;
+ switch (nSlot)
+ {
+ case SID_ULINE_VAL_NONE:
+ eNew = UNDERLINE_NONE;
+ break;
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == UNDERLINE_SINGLE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == UNDERLINE_DOUBLE ) ? UNDERLINE_NONE : UNDERLINE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == UNDERLINE_DOTTED ) ? UNDERLINE_NONE : UNDERLINE_DOTTED;
+ break;
+ default:
+ break;
+ }
+ aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) );
+
+ pView->SetAttributes( aSet );
+ rReq.Done();
+ pViewData->GetScDrawView()->InvalidateDrawTextAttrs();
+}
+
+void lcl_RemoveFields( OutlinerView& rOutView )
+{
+ //! Outliner should have RemoveFields with a selection
+
+ Outliner* pOutliner = rOutView.GetOutliner();
+ if (!pOutliner) return;
+
+ ESelection aOldSel = rOutView.GetSelection();
+ ESelection aSel = aOldSel;
+ aSel.Adjust();
+ xub_StrLen nNewEnd = aSel.nEndPos;
+
+ BOOL bUpdate = pOutliner->GetUpdateMode();
+ BOOL bChanged = FALSE;
+
+ //! GetPortions and GetAttribs should be const!
+ EditEngine& rEditEng = (EditEngine&)pOutliner->GetEditEngine();
+
+ ULONG nParCount = pOutliner->GetParagraphCount();
+ for (ULONG nPar=0; nPar<nParCount; nPar++)
+ if ( nPar >= aSel.nStartPara && nPar <= aSel.nEndPara )
+ {
+ SvUShorts aPortions;
+ rEditEng.GetPortions( (USHORT)nPar, aPortions );
+ //! GetPortions should use xub_StrLen instead of USHORT
+
+ for ( USHORT nPos = aPortions.Count(); nPos; )
+ {
+ --nPos;
+ USHORT nEnd = aPortions.GetObject( nPos );
+ USHORT nStart = nPos ? aPortions.GetObject( nPos - 1 ) : 0;
+ // fields are single characters
+ if ( nEnd == nStart+1 &&
+ ( nPar > aSel.nStartPara || nStart >= aSel.nStartPos ) &&
+ ( nPar < aSel.nEndPara || nEnd <= aSel.nEndPos ) )
+ {
+ ESelection aFieldSel( (USHORT)nPar, nStart, (USHORT)nPar, nEnd );
+ SfxItemSet aSet = rEditEng.GetAttribs( aFieldSel );
+ if ( aSet.GetItemState( EE_FEATURE_FIELD ) == SFX_ITEM_ON )
+ {
+ if (!bChanged)
+ {
+ if (bUpdate)
+ pOutliner->SetUpdateMode( FALSE );
+ String aName = ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
+ pOutliner->GetUndoManager().EnterListAction( aName, aName );
+ bChanged = TRUE;
+ }
+
+ String aFieldText = rEditEng.GetText( aFieldSel );
+ pOutliner->QuickInsertText( aFieldText, aFieldSel );
+ if ( nPar == aSel.nEndPara )
+ {
+ nNewEnd = sal::static_int_cast<xub_StrLen>( nNewEnd + aFieldText.Len() );
+ --nNewEnd;
+ }
+ }
+ }
+ }
+ }
+
+ if (bUpdate && bChanged)
+ {
+ pOutliner->GetUndoManager().LeaveListAction();
+ pOutliner->SetUpdateMode( TRUE );
+ }
+
+ if ( aOldSel.IsEqual( aSel ) ) // aSel is adjusted
+ aOldSel.nEndPos = nNewEnd;
+ else
+ aOldSel.nStartPos = nNewEnd; // if aOldSel is backwards
+ rOutView.SetSelection( aOldSel );
+}
+
+void __EXPORT ScDrawTextObjectBar::ExecuteAttr( SfxRequest &rReq )
+{
+ SdrView* pView = pViewData->GetScDrawView();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ BOOL bArgsInReq = ( pArgs != NULL );
+ if ( !bArgsInReq )
+ {
+ SfxItemSet aEditAttr(pView->GetModel()->GetItemPool());
+ pView->GetAttributes(aEditAttr);
+ SfxItemSet aNewAttr( *aEditAttr.GetPool(), aEditAttr.GetRanges() );
+ BOOL bDone = TRUE;
+
+ switch ( nSlot )
+ {
+ case SID_TEXT_STANDARD: // Harte Textattributierung loeschen
+ {
+ OutlinerView* pOutView = pView->IsTextEdit() ?
+ pView->GetTextEditOutlinerView() : NULL;
+ if ( pOutView )
+ pOutView->Paint( Rectangle() );
+
+ SfxItemSet aEmptyAttr( *aEditAttr.GetPool(), EE_ITEMS_START, EE_ITEMS_END );
+ pView->SetAttributes( aEmptyAttr, TRUE );
+
+ if ( pOutView )
+ {
+ lcl_RemoveFields( *pOutView );
+ pOutView->ShowCursor();
+ }
+
+ rReq.Done( aEmptyAttr );
+ pViewData->GetScDrawView()->InvalidateDrawTextAttrs();
+ bDone = FALSE; // bereits hier passiert
+ }
+ break;
+
+ case SID_CHAR_DLG: // Dialog-Button
+ case SID_ATTR_CHAR_FONT: // Controller nicht angezeigt
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ bDone = ExecuteCharDlg( aEditAttr, aNewAttr );
+ break;
+
+ case SID_PARA_DLG:
+ bDone = ExecuteParaDlg( aEditAttr, aNewAttr );
+ break;
+
+ case SID_ATTR_CHAR_WEIGHT:
+ aNewAttr.Put( (const SvxWeightItem&)aEditAttr.Get( EE_CHAR_WEIGHT ) );
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ aNewAttr.Put( (const SvxPostureItem&)aEditAttr.Get( EE_CHAR_ITALIC ) );
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ aNewAttr.Put( (const SvxUnderlineItem&)aEditAttr.Get( EE_CHAR_UNDERLINE ) );
+ break;
+
+ case SID_ATTR_CHAR_OVERLINE:
+ aNewAttr.Put( (const SvxOverlineItem&)aEditAttr.Get( EE_CHAR_OVERLINE ) );
+ break;
+
+ case SID_ATTR_CHAR_CONTOUR:
+ aNewAttr.Put( (const SvxContourItem&)aEditAttr.Get( EE_CHAR_OUTLINE ) );
+ break;
+
+ case SID_ATTR_CHAR_SHADOWED:
+ aNewAttr.Put( (const SvxShadowedItem&)aEditAttr.Get( EE_CHAR_SHADOW ) );
+ break;
+
+ case SID_ATTR_CHAR_STRIKEOUT:
+ aNewAttr.Put( (const SvxCrossedOutItem&)aEditAttr.Get( EE_CHAR_STRIKEOUT ) );
+ break;
+
+ case SID_ALIGNLEFT:
+ case SID_ALIGN_ANY_LEFT:
+ aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+ break;
+
+ case SID_ALIGNCENTERHOR:
+ case SID_ALIGN_ANY_HCENTER:
+ aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+ break;
+
+ case SID_ALIGNRIGHT:
+ case SID_ALIGN_ANY_RIGHT:
+ aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+ break;
+
+ case SID_ALIGNBLOCK:
+ case SID_ALIGN_ANY_JUSTIFIED:
+ aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_BLOCK, EE_PARA_JUST ) );
+ break;
+
+ case SID_ATTR_PARA_LINESPACE_10:
+ {
+ SvxLineSpacingItem aItem( SVX_LINESPACE_ONE_LINE, EE_PARA_SBL );
+ aItem.SetPropLineSpace( 100 );
+ aNewAttr.Put( aItem );
+ }
+ break;
+
+ case SID_ATTR_PARA_LINESPACE_15:
+ {
+ SvxLineSpacingItem aItem( SVX_LINESPACE_ONE_POINT_FIVE_LINES, EE_PARA_SBL );
+ aItem.SetPropLineSpace( 150 );
+ aNewAttr.Put( aItem );
+ }
+ break;
+
+ case SID_ATTR_PARA_LINESPACE_20:
+ {
+ SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
+ aItem.SetPropLineSpace( 200 );
+ aNewAttr.Put( aItem );
+ }
+ break;
+
+ case SID_SET_SUPER_SCRIPT:
+ {
+ SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
+ SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&)
+ aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue();
+
+ if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT )
+ aItem.SetEscapement( SVX_ESCAPEMENT_OFF );
+ else
+ aItem.SetEscapement( SVX_ESCAPEMENT_SUPERSCRIPT );
+ aNewAttr.Put( aItem );
+ }
+ break;
+ case SID_SET_SUB_SCRIPT:
+ {
+ SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
+ SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&)
+ aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue();
+
+ if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT )
+ aItem.SetEscapement( SVX_ESCAPEMENT_OFF );
+ else
+ aItem.SetEscapement( SVX_ESCAPEMENT_SUBSCRIPT );
+ aNewAttr.Put( aItem );
+ }
+ break;
+
+ case SID_DRAWTEXT_ATTR_DLG:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractTabDialog *pDlg = pFact->CreateTextTabDialog( pViewData->GetDialogParent(), &aEditAttr, pView );
+
+ bDone = ( RET_OK == pDlg->Execute() );
+
+ if ( bDone )
+ aNewAttr.Put( *pDlg->GetOutputItemSet() );
+
+ delete pDlg;
+ }
+ break;
+ }
+
+ if ( bDone ) // wurden Attribute geaendert?
+ {
+ rReq.Done( aNewAttr );
+ pArgs = rReq.GetArgs();
+ }
+ }
+
+ if ( pArgs )
+ {
+ if ( bArgsInReq &&
+ ( nSlot == SID_ATTR_CHAR_FONT || nSlot == SID_ATTR_CHAR_FONTHEIGHT ||
+ nSlot == SID_ATTR_CHAR_WEIGHT || nSlot == SID_ATTR_CHAR_POSTURE ) )
+ {
+ // font items from toolbox controller have to be applied for the right script type
+
+ // #i78017 establish the same behaviour as in Writer
+ USHORT nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ nScript = pView->GetScriptType();
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ USHORT nWhich = rPool.GetWhich( nSlot );
+ aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
+
+ pView->SetAttributes( aSetItem.GetItemSet() );
+ }
+ else
+ {
+ // use args directly
+
+ pView->SetAttributes( *pArgs );
+ }
+ pViewData->GetScDrawView()->InvalidateDrawTextAttrs();
+ }
+}
+
+void __EXPORT ScDrawTextObjectBar::GetAttrState( SfxItemSet& rDestSet )
+{
+ if ( IsNoteEdit() )
+ {
+ // issue 21255 - Notes now support rich text formatting.
+ }
+
+ SvtLanguageOptions aLangOpt;
+ BOOL bDisableCTLFont = !aLangOpt.IsCTLFontEnabled();
+ BOOL bDisableVerticalText = !aLangOpt.IsVerticalTextEnabled();
+
+ SdrView* pView = pViewData->GetScDrawView();
+ SfxItemSet aAttrSet(pView->GetModel()->GetItemPool());
+ pView->GetAttributes(aAttrSet);
+
+ // direkte Attribute
+
+ rDestSet.Put( aAttrSet );
+
+ // choose font info according to selection script type
+
+ USHORT nScript = pView->GetScriptType();
+
+ // #i55929# input-language-dependent script type (depends on input language if nothing selected)
+ USHORT nInputScript = nScript;
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if (pOutView && !pOutView->GetSelection().HasRange())
+ {
+ LanguageType nInputLang = pViewData->GetActiveWin()->GetInputLanguage();
+ if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ }
+
+ // #i55929# according to spec, nInputScript is used for font and font height only
+ if ( rDestSet.GetItemState( EE_CHAR_FONTINFO ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_FONTINFO, nInputScript );
+ if ( rDestSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_FONTHEIGHT, nInputScript );
+ if ( rDestSet.GetItemState( EE_CHAR_WEIGHT ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_WEIGHT, nScript );
+ if ( rDestSet.GetItemState( EE_CHAR_ITALIC ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_ITALIC, nScript );
+
+ // Ausrichtung
+
+ SvxAdjust eAdj = ((const SvxAdjustItem&)aAttrSet.Get(EE_PARA_JUST)).GetAdjust();
+ switch( eAdj )
+ {
+ case SVX_ADJUST_LEFT:
+ rDestSet.Put( SfxBoolItem( SID_ALIGNLEFT, TRUE ) );
+ break;
+ case SVX_ADJUST_CENTER:
+ rDestSet.Put( SfxBoolItem( SID_ALIGNCENTERHOR, TRUE ) );
+ break;
+ case SVX_ADJUST_RIGHT:
+ rDestSet.Put( SfxBoolItem( SID_ALIGNRIGHT, TRUE ) );
+ break;
+ case SVX_ADJUST_BLOCK:
+ rDestSet.Put( SfxBoolItem( SID_ALIGNBLOCK, TRUE ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ // pseudo slots for Format menu
+ rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_LEFT, eAdj == SVX_ADJUST_LEFT ) );
+ rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_HCENTER, eAdj == SVX_ADJUST_CENTER ) );
+ rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_RIGHT, eAdj == SVX_ADJUST_RIGHT ) );
+ rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_JUSTIFIED, eAdj == SVX_ADJUST_BLOCK ) );
+
+ // Zeilenabstand
+
+ USHORT nLineSpace = (USHORT)
+ ((const SvxLineSpacingItem&)aAttrSet.
+ Get( EE_PARA_SBL )).GetPropLineSpace();
+ switch( nLineSpace )
+ {
+ case 100:
+ rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_10, TRUE ) );
+ break;
+ case 150:
+ rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_15, TRUE ) );
+ break;
+ case 200:
+ rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_20, TRUE ) );
+ break;
+ }
+
+ // hoch-/tiefgestellt
+
+ SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&)
+ aAttrSet.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue();
+ if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT )
+ rDestSet.Put( SfxBoolItem( SID_SET_SUPER_SCRIPT, TRUE ) );
+ else if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT )
+ rDestSet.Put( SfxBoolItem( SID_SET_SUB_SCRIPT, TRUE ) );
+
+ // Unterstreichung
+
+ SfxItemState eState = aAttrSet.GetItemState( EE_CHAR_UNDERLINE, TRUE );
+ if ( eState == SFX_ITEM_DONTCARE )
+ {
+ rDestSet.InvalidateItem( SID_ULINE_VAL_NONE );
+ rDestSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
+ rDestSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
+ rDestSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
+ }
+ else
+ {
+ FontUnderline eUnderline = ((const SvxUnderlineItem&)
+ aAttrSet.Get(EE_CHAR_UNDERLINE)).GetLineStyle();
+ USHORT nId = SID_ULINE_VAL_NONE;
+ switch (eUnderline)
+ {
+ case UNDERLINE_SINGLE: nId = SID_ULINE_VAL_SINGLE; break;
+ case UNDERLINE_DOUBLE: nId = SID_ULINE_VAL_DOUBLE; break;
+ case UNDERLINE_DOTTED: nId = SID_ULINE_VAL_DOTTED; break;
+ default:
+ break;
+ }
+ rDestSet.Put( SfxBoolItem( nId, TRUE ) );
+ }
+
+ // horizontal / vertical
+
+ BOOL bLeftToRight = TRUE;
+
+ SdrOutliner* pOutl = pView->GetTextEditOutliner();
+ if( pOutl )
+ {
+ if( pOutl->IsVertical() )
+ bLeftToRight = FALSE;
+ }
+ else
+ bLeftToRight = ( (const SvxWritingModeItem&) aAttrSet.Get( SDRATTR_TEXTDIRECTION ) ).GetValue() == com::sun::star::text::WritingMode_LR_TB;
+
+ if ( bDisableVerticalText )
+ {
+ rDestSet.DisableItem( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
+ rDestSet.DisableItem( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
+ }
+ else
+ {
+ rDestSet.Put( SfxBoolItem( SID_TEXTDIRECTION_LEFT_TO_RIGHT, bLeftToRight ) );
+ rDestSet.Put( SfxBoolItem( SID_TEXTDIRECTION_TOP_TO_BOTTOM, !bLeftToRight ) );
+ }
+
+ // left-to-right or right-to-left
+
+ if ( !bLeftToRight || bDisableCTLFont )
+ {
+ // disabled if vertical
+ rDestSet.DisableItem( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rDestSet.DisableItem( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+ else if ( aAttrSet.GetItemState( EE_PARA_WRITINGDIR ) == SFX_ITEM_DONTCARE )
+ {
+ rDestSet.InvalidateItem( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rDestSet.InvalidateItem( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+ else
+ {
+ SvxFrameDirection eAttrDir = (SvxFrameDirection)((const SvxFrameDirectionItem&)
+ aAttrSet.Get( EE_PARA_WRITINGDIR )).GetValue();
+ if ( eAttrDir == FRMDIR_ENVIRONMENT )
+ {
+ // get "environment" direction from page style
+ if ( pViewData->GetDocument()->GetEditTextDirection( pViewData->GetTabNo() ) == EE_HTEXTDIR_R2L )
+ eAttrDir = FRMDIR_HORI_RIGHT_TOP;
+ else
+ eAttrDir = FRMDIR_HORI_LEFT_TOP;
+ }
+ rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LEFT_TO_RIGHT, ( eAttrDir == FRMDIR_HORI_LEFT_TOP ) ) );
+ rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_RIGHT_TO_LEFT, ( eAttrDir == FRMDIR_HORI_RIGHT_TOP ) ) );
+ }
+}
+
+void ScDrawTextObjectBar::ExecuteTrans( SfxRequest& rReq )
+{
+ sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
+ if ( nType )
+ {
+ ScDrawView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if ( pOutView )
+ {
+ // change selected text in object
+ pOutView->TransliterateText( nType );
+ }
+ else
+ {
+ //! apply to whole objects?
+ }
+ }
+}
+
diff --git a/sc/source/ui/drawfunc/drtxtob1.cxx b/sc/source/ui/drawfunc/drtxtob1.cxx
new file mode 100644
index 000000000000..61fbf3d0f96e
--- /dev/null
+++ b/sc/source/ui/drawfunc/drtxtob1.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/svxdlg.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <sot/exchange.hxx>
+#include <vcl/msgbox.hxx>
+#include <svtools/transfer.hxx>
+
+#include "sc.hrc"
+#include "drtxtob.hxx"
+#include "drawview.hxx"
+#include "viewdata.hxx"
+//CHINA001 #include "textdlgs.hxx"
+#include "scresid.hxx"
+
+#include "scabstdlg.hxx" //CHINA00
+//------------------------------------------------------------------------
+
+BOOL ScDrawTextObjectBar::ExecuteCharDlg( const SfxItemSet& rArgs,
+ SfxItemSet& rOutSet )
+{
+//CHINA001 ScCharDlg* pDlg = new ScCharDlg( pViewData->GetDialogParent(),
+//CHINA001 &rArgs,
+//CHINA001 pViewData->GetSfxDocShell() );
+//CHINA001
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScCharDlg( pViewData->GetDialogParent(), &rArgs,
+ pViewData->GetSfxDocShell(),RID_SCDLG_CHAR );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ BOOL bRet = ( pDlg->Execute() == RET_OK );
+
+ if ( bRet )
+ {
+ const SfxItemSet* pNewAttrs = pDlg->GetOutputItemSet();
+ if ( pNewAttrs )
+ rOutSet.Put( *pNewAttrs );
+ }
+ delete pDlg;
+
+ return bRet;
+}
+
+BOOL ScDrawTextObjectBar::ExecuteParaDlg( const SfxItemSet& rArgs,
+ SfxItemSet& rOutSet )
+{
+ SfxItemPool* pArgPool = rArgs.GetPool();
+ SfxItemSet aNewAttr( *pArgPool,
+ EE_ITEMS_START, EE_ITEMS_END,
+ SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_HYPHENZONE,
+ SID_ATTR_PARA_PAGEBREAK, SID_ATTR_PARA_PAGEBREAK,
+ SID_ATTR_PARA_SPLIT, SID_ATTR_PARA_SPLIT,
+ SID_ATTR_PARA_WIDOWS, SID_ATTR_PARA_WIDOWS,
+ SID_ATTR_PARA_ORPHANS, SID_ATTR_PARA_ORPHANS,
+ 0 );
+ aNewAttr.Put( rArgs );
+
+ // Die Werte sind erst einmal uebernommen worden, um den Dialog anzuzeigen.
+ // Muss natuerlich noch geaendert werden
+ // aNewAttr.Put( SvxParaDlgLimitsItem( 567 * 50, 5670) );
+
+ aNewAttr.Put( SvxHyphenZoneItem( sal_False, SID_ATTR_PARA_HYPHENZONE ) );
+ aNewAttr.Put( SvxFmtBreakItem( SVX_BREAK_NONE, SID_ATTR_PARA_PAGEBREAK ) );
+ aNewAttr.Put( SvxFmtSplitItem( sal_True, SID_ATTR_PARA_SPLIT) );
+ aNewAttr.Put( SvxWidowsItem( 0, SID_ATTR_PARA_WIDOWS) );
+ aNewAttr.Put( SvxOrphansItem( 0, SID_ATTR_PARA_ORPHANS) );
+
+//CHINA001 ScParagraphDlg* pDlg = new ScParagraphDlg( pViewData->GetDialogParent(),
+//CHINA001 &aNewAttr );
+//CHINA001
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScParagraphDlg( pViewData->GetDialogParent(), &aNewAttr, RID_SCDLG_PARAGRAPH);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ BOOL bRet = ( pDlg->Execute() == RET_OK );
+
+ if ( bRet )
+ {
+ const SfxItemSet* pNewAttrs = pDlg->GetOutputItemSet();
+ if ( pNewAttrs )
+ rOutSet.Put( *pNewAttrs );
+ }
+ delete pDlg;
+
+ return bRet;
+}
+
+void ScDrawTextObjectBar::ExecutePasteContents( SfxRequest & /* rReq */ )
+{
+ SdrView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( pViewData->GetDialogParent() );
+
+ pDlg->Insert( SOT_FORMAT_STRING, EMPTY_STRING );
+ pDlg->Insert( SOT_FORMAT_RTF, EMPTY_STRING );
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+
+ ULONG nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+
+ //! test if outliner view is still valid
+
+ if (nFormat > 0)
+ {
+ if (nFormat == SOT_FORMAT_STRING)
+ pOutView->Paste();
+ else
+ pOutView->PasteSpecial();
+ }
+ delete pDlg;
+}
+
+
diff --git a/sc/source/ui/drawfunc/drtxtob2.cxx b/sc/source/ui/drawfunc/drtxtob2.cxx
new file mode 100644
index 000000000000..27f1a3dbb77f
--- /dev/null
+++ b/sc/source/ui/drawfunc/drtxtob2.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/adjitem.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/fontwork.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/xtextit.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sot/formats.hxx>
+#include <svl/whiter.hxx>
+
+#include "sc.hrc"
+#include "drtxtob.hxx"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "docsh.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "drwlayer.hxx"
+
+//------------------------------------------------------------------------
+
+USHORT ScGetFontWorkId()
+{
+ return SvxFontWorkChildWindow::GetChildWindowId();
+}
+
+BOOL ScDrawTextObjectBar::IsNoteEdit()
+{
+ return ScDrawLayer::IsNoteCaption( pViewData->GetView()->GetSdrView()->GetTextEditObject() );
+}
+
+// wenn kein Text editiert wird, Funktionen wie in drawsh
+
+void __EXPORT ScDrawTextObjectBar::ExecuteGlobal( SfxRequest &rReq )
+{
+ ScTabView* pTabView = pViewData->GetView();
+ ScDrawView* pView = pTabView->GetScDrawView();
+
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_COPY:
+ pView->DoCopy();
+ break;
+
+ case SID_CUT:
+ pView->DoCut();
+ if (!pTabView->IsDrawSelMode())
+ pViewData->GetViewShell()->SetDrawShell( FALSE );
+ break;
+
+ case SID_PASTE:
+ case SID_PASTE_SPECIAL:
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ case SID_HYPERLINK_SETLINK:
+ {
+ // cell methods are at cell shell, which is not available if
+ // ScDrawTextObjectBar is active
+ //! move paste etc. to view shell?
+ }
+ break;
+
+ case SID_SELECTALL:
+ pView->MarkAll();
+ break;
+
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ {
+ SfxItemSet aAttr( pView->GetModel()->GetItemPool(), SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, 0 );
+ aAttr.Put( SvxWritingModeItem(
+ nSlot == SID_TEXTDIRECTION_LEFT_TO_RIGHT ?
+ com::sun::star::text::WritingMode_LR_TB : com::sun::star::text::WritingMode_TB_RL,
+ SDRATTR_TEXTDIRECTION ) );
+ pView->SetAttributes( aAttr );
+ pViewData->GetScDrawView()->InvalidateDrawTextAttrs(); // Bidi slots may be disabled
+ rReq.Done( aAttr );
+ }
+ break;
+
+ case SID_ENABLE_HYPHENATION:
+ {
+ SFX_REQUEST_ARG( rReq, pItem, SfxBoolItem, SID_ENABLE_HYPHENATION, FALSE);
+ if( pItem )
+ {
+ SfxItemSet aSet( GetPool(), EE_PARA_HYPHENATE, EE_PARA_HYPHENATE );
+ BOOL bValue = ( (const SfxBoolItem*) pItem)->GetValue();
+ aSet.Put( SfxBoolItem( EE_PARA_HYPHENATE, bValue ) );
+ pView->SetAttributes( aSet );
+ }
+ rReq.Done();
+ }
+ break;
+ }
+}
+
+void ScDrawTextObjectBar::GetGlobalClipState( SfxItemSet& rSet )
+{
+ // cell methods are at cell shell, which is not available if
+ // ScDrawTextObjectBar is active -> disable everything
+ //! move paste etc. to view shell?
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void __EXPORT ScDrawTextObjectBar::ExecuteExtra( SfxRequest &rReq )
+{
+ ScTabView* pTabView = pViewData->GetView();
+ ScDrawView* pView = pTabView->GetScDrawView();
+
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_FONTWORK:
+ {
+ USHORT nId = SvxFontWorkChildWindow::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+
+ if ( rReq.GetArgs() )
+ pViewFrm->SetChildWindow( nId,
+ ((const SfxBoolItem&)
+ (rReq.GetArgs()->Get(SID_FONTWORK))).
+ GetValue() );
+ else
+ pViewFrm->ToggleChildWindow( nId );
+
+ pViewFrm->GetBindings().Invalidate( SID_FONTWORK );
+ rReq.Done();
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ SfxItemSet aAttr( pView->GetModel()->GetItemPool(),
+ EE_PARA_WRITINGDIR, EE_PARA_WRITINGDIR,
+ EE_PARA_JUST, EE_PARA_JUST,
+ 0 );
+ BOOL bLeft = ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT );
+ aAttr.Put( SvxFrameDirectionItem(
+ bLeft ? FRMDIR_HORI_LEFT_TOP : FRMDIR_HORI_RIGHT_TOP,
+ EE_PARA_WRITINGDIR ) );
+ aAttr.Put( SvxAdjustItem(
+ bLeft ? SVX_ADJUST_LEFT : SVX_ADJUST_RIGHT,
+ EE_PARA_JUST ) );
+ pView->SetAttributes( aAttr );
+ pViewData->GetScDrawView()->InvalidateDrawTextAttrs();
+ rReq.Done(); //! Done(aAttr) ?
+
+ }
+ break;
+ }
+}
+
+void ScDrawTextObjectBar::ExecFormText(SfxRequest& rReq)
+{
+ ScTabView* pTabView = pViewData->GetView();
+ ScDrawView* pDrView = pTabView->GetScDrawView();
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+
+ if ( rMarkList.GetMarkCount() == 1 && rReq.GetArgs() )
+ {
+ const SfxItemSet& rSet = *rReq.GetArgs();
+ const SfxPoolItem* pItem;
+
+ if ( pDrView->IsTextEdit() )
+ pDrView->ScEndTextEdit();
+
+ if ( SFX_ITEM_SET ==
+ rSet.GetItemState(XATTR_FORMTXTSTDFORM, TRUE, &pItem)
+ && XFTFORM_NONE !=
+ ((const XFormTextStdFormItem*) pItem)->GetValue() )
+ {
+
+ USHORT nId = SvxFontWorkChildWindow::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ SvxFontWorkDialog* pDlg = (SvxFontWorkDialog*)
+ (pViewFrm->
+ GetChildWindow(nId)->GetWindow());
+
+ pDlg->CreateStdFormObj(*pDrView, *pDrView->GetSdrPageView(),
+ rSet, *rMarkList.GetMark(0)->GetMarkedSdrObj(),
+ ((const XFormTextStdFormItem*) pItem)->
+ GetValue());
+ }
+ else
+ pDrView->SetAttributes(rSet);
+ }
+}
+
+void ScDrawTextObjectBar::GetFormTextState(SfxItemSet& rSet)
+{
+ const SdrObject* pObj = NULL;
+ SvxFontWorkDialog* pDlg = NULL;
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ USHORT nId = SvxFontWorkChildWindow::GetChildWindowId();
+
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ if ( pViewFrm->HasChildWindow(nId) )
+ pDlg = (SvxFontWorkDialog*)(pViewFrm->GetChildWindow(nId)->GetWindow());
+
+ if ( rMarkList.GetMarkCount() == 1 )
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ if ( pObj == NULL || !pObj->ISA(SdrTextObj) ||
+ !((SdrTextObj*) pObj)->HasText() )
+ {
+ if ( pDlg )
+ pDlg->SetActive(FALSE);
+
+ rSet.DisableItem(XATTR_FORMTXTSTYLE);
+ rSet.DisableItem(XATTR_FORMTXTADJUST);
+ rSet.DisableItem(XATTR_FORMTXTDISTANCE);
+ rSet.DisableItem(XATTR_FORMTXTSTART);
+ rSet.DisableItem(XATTR_FORMTXTMIRROR);
+ rSet.DisableItem(XATTR_FORMTXTSTDFORM);
+ rSet.DisableItem(XATTR_FORMTXTHIDEFORM);
+ rSet.DisableItem(XATTR_FORMTXTOUTLINE);
+ rSet.DisableItem(XATTR_FORMTXTSHADOW);
+ rSet.DisableItem(XATTR_FORMTXTSHDWCOLOR);
+ rSet.DisableItem(XATTR_FORMTXTSHDWXVAL);
+ rSet.DisableItem(XATTR_FORMTXTSHDWYVAL);
+ }
+ else
+ {
+ if ( pDlg )
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
+ XColorTable* pColorTable = NULL;
+
+ if ( pItem )
+ pColorTable = ((SvxColorTableItem*)pItem)->GetColorTable();
+
+ pDlg->SetActive();
+
+ if ( pColorTable )
+ pDlg->SetColorTable( pColorTable );
+ else
+ { DBG_ERROR( "ColorList not found :-/" ); }
+ }
+ }
+ SfxItemSet aViewAttr(pDrView->GetModel()->GetItemPool());
+ pDrView->GetAttributes(aViewAttr);
+ rSet.Set(aViewAttr);
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/drawfunc/fuconarc.cxx b/sc/source/ui/drawfunc/fuconarc.cxx
new file mode 100644
index 000000000000..20daacffac0e
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuconarc.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "fuconarc.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "drawview.hxx"
+
+// #98185# Create default drawing objects via keyboard
+#include <svx/svdocirc.hxx>
+#include <svx/sxciaitm.hxx>
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuConstArc::FuConstArc( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq )
+ : FuConstruct( pViewSh, pWin, pViewP, pDoc, rReq )
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuConstArc::~FuConstArc()
+{
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstArc::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuConstruct::MouseButtonDown( rMEvt );
+
+ if ( rMEvt.IsLeft() && !pView->IsAction() )
+ {
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pWindow->CaptureMouse();
+ pView->BegCreateObj( aPnt );
+ bReturn = TRUE;
+ }
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstArc::MouseMove( const MouseEvent& rMEvt )
+{
+ return FuConstruct::MouseMove(rMEvt);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstArc::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FALSE;
+
+ if ( pView->IsCreateObj() && rMEvt.IsLeft() )
+ {
+ // Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pView->EndCreateObj( SDRCREATE_NEXTPOINT );
+ bReturn = TRUE;
+ }
+/*
+ else if ( pView->IsCreateObj() && rMEvt.IsRight() )
+ {
+ // Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pView->EndCreateObj( SDRCREATE_FORCEEND );
+ bReturn = TRUE;
+ }
+*/
+ return (FuConstruct::MouseButtonUp(rMEvt) || bReturn);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstArc::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FuConstruct::KeyInput(rKEvt);
+ return(bReturn);
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuConstArc::Activate()
+{
+ SdrObjKind aObjKind;
+
+ switch (aSfxRequest.GetSlot() )
+ {
+ case SID_DRAW_ARC:
+ aNewPointer = Pointer( POINTER_DRAW_ARC );
+ aObjKind = OBJ_CARC;
+ break;
+
+ case SID_DRAW_PIE:
+ aNewPointer = Pointer( POINTER_DRAW_PIE );
+ aObjKind = OBJ_SECT;
+ break;
+
+ case SID_DRAW_CIRCLECUT:
+ aNewPointer = Pointer( POINTER_DRAW_CIRCLECUT );
+ aObjKind = OBJ_CCUT;
+ break;
+
+ default:
+ aNewPointer = Pointer( POINTER_CROSS );
+ aObjKind = OBJ_CARC;
+ break;
+ }
+
+ pView->SetCurrentObj( sal::static_int_cast<UINT16>( aObjKind ) );
+
+ aOldPointer = pWindow->GetPointer();
+ pViewShell->SetActivePointer( aNewPointer );
+
+ FuDraw::Activate();
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuConstArc::Deactivate()
+{
+ FuDraw::Deactivate();
+ pViewShell->SetActivePointer( aOldPointer );
+}
+
+// #98185# Create default drawing objects via keyboard
+SdrObject* FuConstArc::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
+{
+ // case SID_DRAW_ARC:
+ // case SID_DRAW_PIE:
+ // case SID_DRAW_CIRCLECUT:
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
+ 0L, pDrDoc);
+
+ if(pObj)
+ {
+ if(pObj->ISA(SdrCircObj))
+ {
+ Rectangle aRect(rRectangle);
+
+ if(SID_DRAW_ARC == nID || SID_DRAW_CIRCLECUT == nID)
+ {
+ // force quadratic
+ ImpForceQuadratic(aRect);
+ }
+
+ pObj->SetLogicRect(aRect);
+
+ SfxItemSet aAttr(pDrDoc->GetItemPool());
+ aAttr.Put(SdrCircStartAngleItem(9000));
+ aAttr.Put(SdrCircEndAngleItem(0));
+
+ pObj->SetMergedItemSet(aAttr);
+ }
+ else
+ {
+ DBG_ERROR("Object is NO circle object");
+ }
+ }
+
+ return pObj;
+}
+
+
diff --git a/sc/source/ui/drawfunc/fuconcustomshape.cxx b/sc/source/ui/drawfunc/fuconcustomshape.cxx
new file mode 100644
index 000000000000..69a47f0584d0
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuconcustomshape.cxx
@@ -0,0 +1,288 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "fuconcustomshape.hxx"
+#include <editeng/svxenum.hxx>
+#include <svx/gallery.hxx>
+#include <sfx2/request.hxx>
+#include <svx/fmmodel.hxx>
+#include <svl/itempool.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdoashp.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/sdtagitm.hxx>
+#include "fuconuno.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "drawview.hxx"
+#include <editeng/adjitem.hxx>
+
+#include <math.h>
+
+//------------------------------------------------------------------------
+
+FuConstCustomShape::FuConstCustomShape( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP, SdrModel* pDoc, SfxRequest& rReq )
+ : FuConstruct( pViewSh, pWin, pViewP, pDoc, rReq )
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ const SfxStringItem& rItm = (const SfxStringItem&)pArgs->Get( rReq.GetSlot() );
+ aCustomShape = rItm.GetValue();
+ }
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuConstCustomShape::~FuConstCustomShape()
+{
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstCustomShape::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuConstruct::MouseButtonDown(rMEvt);
+ if ( rMEvt.IsLeft() && !pView->IsAction() )
+ {
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pWindow->CaptureMouse();
+ pView->BegCreateObj(aPnt);
+
+ SdrObject* pObj = pView->GetCreateObj();
+ if ( pObj )
+ {
+ SetAttributes( pObj );
+ sal_Bool bForceFillStyle = sal_True;
+ sal_Bool bForceNoFillStyle = sal_False;
+ if ( ((SdrObjCustomShape*)pObj)->UseNoFillStyle() )
+ {
+ bForceFillStyle = sal_False;
+ bForceNoFillStyle = sal_True;
+ }
+ if ( bForceNoFillStyle )
+ pObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) );
+ }
+
+ bReturn = TRUE;
+ }
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstCustomShape::MouseMove(const MouseEvent& rMEvt)
+{
+ return FuConstruct::MouseMove(rMEvt);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstCustomShape::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FALSE;
+
+ if ( pView->IsCreateObj() && rMEvt.IsLeft() )
+ {
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pView->EndCreateObj(SDRCREATE_FORCEEND);
+ bReturn = TRUE;
+ }
+ return (FuConstruct::MouseButtonUp(rMEvt) || bReturn);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstCustomShape::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FuConstruct::KeyInput(rKEvt);
+ return(bReturn);
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuConstCustomShape::Activate()
+{
+ pView->SetCurrentObj( OBJ_CUSTOMSHAPE, SdrInventor );
+
+ aNewPointer = Pointer( POINTER_DRAW_RECT );
+ aOldPointer = pWindow->GetPointer();
+ pViewShell->SetActivePointer( aNewPointer );
+
+ SdrLayer* pLayer = pView->GetModel()->GetLayerAdmin().GetLayerPerID(SC_LAYER_CONTROLS);
+ if (pLayer)
+ pView->SetActiveLayer( pLayer->GetName() );
+
+ FuConstruct::Activate();
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuConstCustomShape::Deactivate()
+{
+ FuConstruct::Deactivate();
+
+ SdrLayer* pLayer = pView->GetModel()->GetLayerAdmin().GetLayerPerID(SC_LAYER_FRONT);
+ if (pLayer)
+ pView->SetActiveLayer( pLayer->GetName() );
+
+ pViewShell->SetActivePointer( aOldPointer );
+}
+
+// #98185# Create default drawing objects via keyboard
+SdrObject* FuConstCustomShape::CreateDefaultObject(const sal_uInt16 /* nID */, const Rectangle& rRectangle)
+{
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
+ 0L, pDrDoc);
+ if( pObj )
+ {
+ Rectangle aRectangle( rRectangle );
+ SetAttributes( pObj );
+ if ( SdrObjCustomShape::doConstructOrthogonal( aCustomShape ) )
+ ImpForceQuadratic( aRectangle );
+ pObj->SetLogicRect( aRectangle );
+ }
+ return pObj;
+}
+
+/*************************************************************************
+|*
+|* applying attributes
+|*
+\************************************************************************/
+
+void FuConstCustomShape::SetAttributes( SdrObject* pObj )
+{
+ sal_Bool bAttributesAppliedFromGallery = sal_False;
+
+ if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) )
+ {
+ std::vector< rtl::OUString > aObjList;
+ if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) )
+ {
+ sal_uInt16 i;
+ for ( i = 0; i < aObjList.size(); i++ )
+ {
+ if ( aObjList[ i ].equalsIgnoreAsciiCase( aCustomShape ) )
+ {
+ FmFormModel aFormModel;
+ SfxItemPool& rPool = aFormModel.GetItemPool();
+ rPool.FreezeIdRanges();
+ if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aFormModel ) )
+ {
+ const SdrObject* pSourceObj = aFormModel.GetPage( 0 )->GetObj( 0 );
+ if( pSourceObj )
+ {
+ const SfxItemSet& rSource = pSourceObj->GetMergedItemSet();
+ SfxItemSet aDest( pObj->GetModel()->GetItemPool(), // ranges from SdrAttrObj
+ SDRATTR_START, SDRATTR_SHADOW_LAST,
+ SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
+ SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
+ // Graphic Attributes
+ SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST,
+ // 3d Properties
+ SDRATTR_3D_FIRST, SDRATTR_3D_LAST,
+ // CustomShape properties
+ SDRATTR_CUSTOMSHAPE_FIRST, SDRATTR_CUSTOMSHAPE_LAST,
+ // range from SdrTextObj
+ EE_ITEMS_START, EE_ITEMS_END,
+ // end
+ 0, 0);
+ aDest.Set( rSource );
+ pObj->SetMergedItemSet( aDest );
+ sal_Int32 nAngle = pSourceObj->GetRotateAngle();
+ if ( nAngle )
+ {
+ double a = nAngle * F_PI18000;
+ pObj->NbcRotate( pObj->GetSnapRect().Center(), nAngle, sin( a ), cos( a ) );
+ }
+ bAttributesAppliedFromGallery = sal_True;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ if ( !bAttributesAppliedFromGallery )
+ {
+ pObj->SetMergedItem( SvxAdjustItem( SVX_ADJUST_CENTER, 0 ) );
+ pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) );
+ pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) );
+ pObj->SetMergedItem( SdrTextAutoGrowHeightItem( sal_False ) );
+ ((SdrObjCustomShape*)pObj)->MergeDefaultAttributes( &aCustomShape );
+ }
+}
+
+// #i33136#
+bool FuConstCustomShape::doConstructOrthogonal() const
+{
+ return SdrObjCustomShape::doConstructOrthogonal(aCustomShape);
+}
+
+// eof
diff --git a/sc/source/ui/drawfunc/fuconpol.cxx b/sc/source/ui/drawfunc/fuconpol.cxx
new file mode 100644
index 000000000000..440f49f41326
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuconpol.cxx
@@ -0,0 +1,355 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "fuconpol.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "drawview.hxx"
+
+// #98185# Create default drawing objects via keyboard
+#include <svx/svdopath.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+
+// Pixelabstand zum Schliessen von Freihand-Zeichnungen
+#ifndef CLOSE_PIXDIST
+#define CLOSE_PIXDIST 5
+#endif
+
+//------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuConstPolygon::FuConstPolygon(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq)
+ : FuConstruct(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuConstPolygon::~FuConstPolygon()
+{
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstPolygon::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuConstruct::MouseButtonDown(rMEvt);
+
+ SdrViewEvent aVEvt;
+ (void)pView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
+ if (aVEvt.eEvent == SDREVENT_BEGTEXTEDIT)
+ {
+ // Texteingabe hier nicht zulassen
+ aVEvt.eEvent = SDREVENT_BEGDRAGOBJ;
+ pView->EnableExtendedMouseEventDispatcher(FALSE);
+ }
+ else
+ {
+ pView->EnableExtendedMouseEventDispatcher(TRUE);
+ }
+
+ if ( pView->MouseButtonDown(rMEvt, pWindow) )
+ bReturn = TRUE;
+
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstPolygon::MouseMove(const MouseEvent& rMEvt)
+{
+ pView->MouseMove(rMEvt, pWindow);
+ BOOL bReturn = FuConstruct::MouseMove(rMEvt);
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstPolygon::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FALSE;
+ BOOL bSimple = FALSE;
+
+ SdrViewEvent aVEvt;
+ (void)pView->PickAnything(rMEvt, SDRMOUSEBUTTONUP, aVEvt);
+
+ pView->MouseButtonUp(rMEvt, pWindow);
+
+ if (aVEvt.eEvent == SDREVENT_ENDCREATE)
+ {
+ bReturn = TRUE;
+ bSimple = TRUE; // Doppelklick nicht weiterreichen
+ }
+
+ BOOL bParent;
+ if (bSimple)
+ bParent = FuConstruct::SimpleMouseButtonUp(rMEvt);
+ else
+ bParent = FuConstruct::MouseButtonUp(rMEvt);
+
+ return (bParent || bReturn);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstPolygon::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FuConstruct::KeyInput(rKEvt);
+
+ return(bReturn);
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuConstPolygon::Activate()
+{
+ pView->EnableExtendedMouseEventDispatcher(TRUE);
+
+ SdrObjKind eKind;
+
+ switch (GetSlotID())
+ {
+ case SID_DRAW_POLYGON_NOFILL:
+ case SID_DRAW_XPOLYGON_NOFILL:
+ {
+ eKind = OBJ_PLIN;
+ }
+ break;
+
+ case SID_DRAW_POLYGON:
+ case SID_DRAW_XPOLYGON:
+ {
+ eKind = OBJ_POLY;
+ }
+ break;
+
+ case SID_DRAW_BEZIER_NOFILL:
+ {
+ eKind = OBJ_PATHLINE;
+ }
+ break;
+
+ case SID_DRAW_BEZIER_FILL:
+ {
+ eKind = OBJ_PATHFILL;
+ }
+ break;
+
+ case SID_DRAW_FREELINE_NOFILL:
+ {
+ eKind = OBJ_FREELINE;
+ }
+ break;
+
+ case SID_DRAW_FREELINE:
+ {
+ eKind = OBJ_FREEFILL;
+ }
+ break;
+
+ default:
+ {
+ eKind = OBJ_PATHLINE;
+ }
+ break;
+ }
+
+ pView->SetCurrentObj(sal::static_int_cast<UINT16>(eKind));
+
+ pView->SetEditMode(SDREDITMODE_CREATE);
+
+ FuConstruct::Activate();
+
+ aNewPointer = Pointer( POINTER_DRAW_POLYGON );
+ aOldPointer = pWindow->GetPointer();
+ pViewShell->SetActivePointer( aNewPointer );
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuConstPolygon::Deactivate()
+{
+ pView->SetEditMode(SDREDITMODE_EDIT);
+
+ pView->EnableExtendedMouseEventDispatcher(FALSE);
+
+ FuConstruct::Deactivate();
+
+ pViewShell->SetActivePointer( aOldPointer );
+}
+
+// #98185# Create default drawing objects via keyboard
+SdrObject* FuConstPolygon::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
+{
+ // case SID_DRAW_POLYGON:
+ // case SID_DRAW_POLYGON_NOFILL:
+ // case SID_DRAW_BEZIER_NOFILL:
+ // case SID_DRAW_FREELINE_NOFILL:
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
+ 0L, pDrDoc);
+
+ if(pObj)
+ {
+ if(pObj->ISA(SdrPathObj))
+ {
+ basegfx::B2DPolyPolygon aPoly;
+
+ switch(nID)
+ {
+ case SID_DRAW_BEZIER_NOFILL:
+ {
+ basegfx::B2DPolygon aInnerPoly;
+
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
+
+ const basegfx::B2DPoint aCenterBottom(rRectangle.Center().X(), rRectangle.Bottom());
+ aInnerPoly.appendBezierSegment(
+ aCenterBottom,
+ aCenterBottom,
+ basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
+
+ const basegfx::B2DPoint aCenterTop(rRectangle.Center().X(), rRectangle.Top());
+ aInnerPoly.appendBezierSegment(
+ aCenterTop,
+ aCenterTop,
+ basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
+
+ aPoly.append(aInnerPoly);
+ break;
+ }
+ case SID_DRAW_FREELINE_NOFILL:
+ {
+ basegfx::B2DPolygon aInnerPoly;
+
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
+
+ aInnerPoly.appendBezierSegment(
+ basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()),
+ basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()),
+ basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
+
+ aInnerPoly.appendBezierSegment(
+ basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()),
+ basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()),
+ basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
+
+ aPoly.append(aInnerPoly);
+ break;
+ }
+ case SID_DRAW_POLYGON:
+ case SID_DRAW_POLYGON_NOFILL:
+ {
+ basegfx::B2DPolygon aInnerPoly;
+ const sal_Int32 nWdt(rRectangle.GetWidth());
+ const sal_Int32 nHgt(rRectangle.GetHeight());
+
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 30) / 100, rRectangle.Top() + (nHgt * 70) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top() + (nHgt * 15) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 65) / 100, rRectangle.Top()));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + nWdt, rRectangle.Top() + (nHgt * 30) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 50) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 75) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Bottom(), rRectangle.Right()));
+
+ if(SID_DRAW_POLYGON_NOFILL == nID)
+ {
+ aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
+ }
+ else
+ {
+ aInnerPoly.setClosed(true);
+ }
+
+ aPoly.append(aInnerPoly);
+ break;
+ }
+ }
+
+ ((SdrPathObj*)pObj)->SetPathPoly(aPoly);
+ }
+ else
+ {
+ DBG_ERROR("Object is NO path object");
+ }
+
+ pObj->SetLogicRect(rRectangle);
+ }
+
+ return pObj;
+}
+
+// eof
diff --git a/sc/source/ui/drawfunc/fuconrec.cxx b/sc/source/ui/drawfunc/fuconrec.cxx
new file mode 100644
index 000000000000..733c6fe08b45
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuconrec.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "fuconrec.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "drawview.hxx"
+
+#include <editeng/outlobj.hxx>
+// #98185# Create default drawing objects via keyboard
+#include <svx/svdopath.hxx>
+#include <svx/svdocapt.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+
+#include "scresid.hxx"
+
+//------------------------------------------------------------------------
+
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuConstRectangle::FuConstRectangle(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq)
+ : FuConstruct(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuConstRectangle::~FuConstRectangle()
+{
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstRectangle::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuConstruct::MouseButtonDown(rMEvt);
+
+ if ( rMEvt.IsLeft() && !pView->IsAction() )
+ {
+ Point aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ pWindow->CaptureMouse();
+
+ if ( pView->GetCurrentObjIdentifier() == OBJ_CAPTION )
+ {
+ Size aCaptionSize ( 2268, 1134 ); // 4x2cm
+
+ bReturn = pView->BegCreateCaptionObj( aPos, aCaptionSize );
+
+ // wie stellt man den Font ein, mit dem geschrieben wird
+ }
+ else
+ bReturn = pView->BegCreateObj(aPos);
+ }
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstRectangle::MouseMove(const MouseEvent& rMEvt)
+{
+ return FuConstruct::MouseMove(rMEvt);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstRectangle::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FALSE;
+
+ if ( pView->IsCreateObj() && rMEvt.IsLeft() )
+ {
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pView->EndCreateObj(SDRCREATE_FORCEEND);
+
+ if (aSfxRequest.GetSlot() == SID_DRAW_CAPTION_VERTICAL)
+ {
+ // set vertical flag for caption object
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMark(0))
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ // create OutlinerParaObject now so it can be set to vertical
+ if ( pObj->ISA(SdrTextObj) )
+ ((SdrTextObj*)pObj)->ForceOutlinerParaObject();
+ OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
+ if( pOPO && !pOPO->IsVertical() )
+ pOPO->SetVertical( TRUE );
+ }
+ }
+
+ bReturn = TRUE;
+ }
+ return (FuConstruct::MouseButtonUp(rMEvt) || bReturn);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstRectangle::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FuConstruct::KeyInput(rKEvt);
+ return(bReturn);
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuConstRectangle::Activate()
+{
+ SdrObjKind aObjKind;
+
+ switch (aSfxRequest.GetSlot() )
+ {
+ case SID_DRAW_LINE:
+ aNewPointer = Pointer( POINTER_DRAW_LINE );
+ aObjKind = OBJ_LINE;
+ break;
+
+ case SID_DRAW_RECT:
+ aNewPointer = Pointer( POINTER_DRAW_RECT );
+ aObjKind = OBJ_RECT;
+ break;
+
+ case SID_DRAW_ELLIPSE:
+ aNewPointer = Pointer( POINTER_DRAW_ELLIPSE );
+ aObjKind = OBJ_CIRC;
+ break;
+
+ case SID_DRAW_CAPTION:
+ case SID_DRAW_CAPTION_VERTICAL:
+ aNewPointer = Pointer( POINTER_DRAW_CAPTION );
+ aObjKind = OBJ_CAPTION;
+ break;
+
+ default:
+ aNewPointer = Pointer( POINTER_CROSS );
+ aObjKind = OBJ_RECT;
+ break;
+ }
+
+ pView->SetCurrentObj(sal::static_int_cast<UINT16>(aObjKind));
+
+ aOldPointer = pWindow->GetPointer();
+ pViewShell->SetActivePointer( aNewPointer );
+
+ FuConstruct::Activate();
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuConstRectangle::Deactivate()
+{
+ FuConstruct::Deactivate();
+ pViewShell->SetActivePointer( aOldPointer );
+}
+
+// #98185# Create default drawing objects via keyboard
+SdrObject* FuConstRectangle::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
+{
+ // case SID_DRAW_LINE:
+ // case SID_DRAW_RECT:
+ // case SID_DRAW_ELLIPSE:
+ // case SID_DRAW_CAPTION:
+ // case SID_DRAW_CAPTION_VERTICAL:
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
+ 0L, pDrDoc);
+
+ if(pObj)
+ {
+ Rectangle aRect(rRectangle);
+ Point aStart = aRect.TopLeft();
+ Point aEnd = aRect.BottomRight();
+
+ switch(nID)
+ {
+ case SID_DRAW_LINE:
+ {
+ if(pObj->ISA(SdrPathObj))
+ {
+ sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
+ basegfx::B2DPolygon aPoly;
+ aPoly.append(basegfx::B2DPoint(aStart.X(), nYMiddle));
+ aPoly.append(basegfx::B2DPoint(aEnd.X(), nYMiddle));
+ ((SdrPathObj*)pObj)->SetPathPoly(basegfx::B2DPolyPolygon(aPoly));
+ }
+ else
+ {
+ DBG_ERROR("Object is NO line object");
+ }
+
+ break;
+ }
+ case SID_DRAW_CAPTION:
+ case SID_DRAW_CAPTION_VERTICAL:
+ {
+ if(pObj->ISA(SdrCaptionObj))
+ {
+ sal_Bool bIsVertical(SID_DRAW_CAPTION_VERTICAL == nID);
+
+ ((SdrTextObj*)pObj)->SetVerticalWriting(bIsVertical);
+
+ if(bIsVertical)
+ {
+ SfxItemSet aSet(pObj->GetMergedItemSet());
+ aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER));
+ aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
+ pObj->SetMergedItemSet(aSet);
+ }
+
+ // #105815# don't set default text, start edit mode instead
+ // (Edit mode is started in ScTabViewShell::ExecDraw, because
+ // it must be handled by FuText)
+ // String aText(ScResId(STR_CAPTION_DEFAULT_TEXT));
+ // ((SdrCaptionObj*)pObj)->SetText(aText);
+
+ ((SdrCaptionObj*)pObj)->SetLogicRect(aRect);
+ ((SdrCaptionObj*)pObj)->SetTailPos(
+ aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2));
+ }
+ else
+ {
+ DBG_ERROR("Object is NO caption object");
+ }
+
+ break;
+ }
+
+ default:
+ {
+ pObj->SetLogicRect(aRect);
+
+ break;
+ }
+ }
+
+ SfxItemSet aAttr(pDrDoc->GetItemPool());
+ pObj->SetMergedItemSet(aAttr);
+ }
+
+ return pObj;
+}
+
diff --git a/sc/source/ui/drawfunc/fuconstr.cxx b/sc/source/ui/drawfunc/fuconstr.cxx
new file mode 100644
index 000000000000..bb918e9005ae
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuconstr.cxx
@@ -0,0 +1,335 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/outliner.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdouno.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include "fuconstr.hxx"
+#include "fudraw.hxx"
+#include "tabvwsh.hxx"
+#include "futext.hxx"
+#include "sc.hrc"
+#include "drawview.hxx"
+
+// Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
+//! fusel,fuconstr,futext - zusammenfassen!
+#define SC_MAXDRAGMOVE 3
+
+//------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuConstruct::FuConstruct(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq) :
+ FuDraw(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuConstruct::~FuConstruct()
+{
+}
+
+BYTE FuConstruct::Command(const CommandEvent& rCEvt)
+{
+ // special code for non-VCL OS2/UNX removed
+
+ return FuDraw::Command( rCEvt );
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstruct::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuDraw::MouseButtonDown(rMEvt);
+
+ if ( pView->IsAction() )
+ {
+ if ( rMEvt.IsRight() )
+ pView->BckAction();
+ return TRUE;
+ }
+
+ aDragTimer.Start();
+
+ aMDPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ pWindow->CaptureMouse();
+
+ SdrHdl* pHdl = pView->PickHandle(aMDPos);
+
+ if ( pHdl != NULL || pView->IsMarkedHit(aMDPos) )
+ {
+ pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, 1);
+ bReturn = TRUE;
+ }
+ else if ( pView->AreObjectsMarked() )
+ {
+ pView->UnmarkAll();
+ bReturn = TRUE;
+ }
+ }
+
+ bIsInDragMode = FALSE;
+
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstruct::MouseMove(const MouseEvent& rMEvt)
+{
+ FuDraw::MouseMove(rMEvt);
+
+ if (aDragTimer.IsActive() )
+ {
+ Point aOldPixel = pWindow->LogicToPixel( aMDPos );
+ Point aNewPixel = rMEvt.GetPosPixel();
+ if ( Abs( aOldPixel.X() - aNewPixel.X() ) > SC_MAXDRAGMOVE ||
+ Abs( aOldPixel.Y() - aNewPixel.Y() ) > SC_MAXDRAGMOVE )
+ aDragTimer.Stop();
+ }
+
+ Point aPix(rMEvt.GetPosPixel());
+ Point aPnt( pWindow->PixelToLogic(aPix) );
+
+ if ( pView->IsAction() )
+ {
+ ForceScroll(aPix);
+ pView->MovAction(aPnt);
+ }
+ else
+ {
+ SdrHdl* pHdl=pView->PickHandle(aPnt);
+
+ if ( pHdl != NULL )
+ {
+ pViewShell->SetActivePointer(pHdl->GetPointer());
+ }
+ else if ( pView->IsMarkedHit(aPnt) )
+ {
+ pViewShell->SetActivePointer(Pointer(POINTER_MOVE));
+ }
+ else
+ {
+ pViewShell->SetActivePointer( aNewPointer );
+ }
+ }
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstruct::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = SimpleMouseButtonUp( rMEvt );
+
+ // Doppelklick auf Textobjekt? (->fusel)
+
+ USHORT nClicks = rMEvt.GetClicks();
+ if ( nClicks == 2 && rMEvt.IsLeft() )
+ {
+ if ( pView->AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ // #49458# bei Uno-Controls nicht in Textmodus
+ if ( pObj->ISA(SdrTextObj) && !pObj->ISA(SdrUnoObj) )
+ {
+ OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
+ BOOL bVertical = ( pOPO && pOPO->IsVertical() );
+ USHORT nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
+
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(nTextSlotId, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+
+ // jetzt den erzeugten FuText holen und in den EditModus setzen
+ FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
+ if ( pPoor && pPoor->GetSlotID() == nTextSlotId ) // hat keine RTTI
+ {
+ FuText* pText = (FuText*)pPoor;
+ Point aMousePixel = rMEvt.GetPosPixel();
+ pText->SetInEditMode( pObj, &aMousePixel );
+ }
+ bReturn = TRUE;
+ }
+ }
+ }
+ }
+
+ FuDraw::MouseButtonUp(rMEvt);
+
+ return bReturn;
+}
+
+// SimpleMouseButtonUp - ohne Test auf Doppelklick
+
+BOOL FuConstruct::SimpleMouseButtonUp(const MouseEvent& rMEvt)
+{
+ BOOL bReturn = TRUE;
+
+ if (aDragTimer.IsActive() )
+ {
+ aDragTimer.Stop();
+ }
+
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ if ( pView->IsDragObj() )
+ pView->EndDragObj( rMEvt.IsMod1() );
+
+ else if ( pView->IsMarkObj() )
+ pView->EndMarkObj();
+
+ else bReturn = FALSE;
+
+ if ( !pView->IsAction() )
+ {
+ pWindow->ReleaseMouse();
+
+ if ( !pView->AreObjectsMarked() && rMEvt.GetClicks() < 2 )
+ {
+ pView->MarkObj(aPnt, -2, FALSE, rMEvt.IsMod1());
+
+ SfxDispatcher& rDisp = pViewShell->GetViewData()->GetDispatcher();
+ if ( pView->AreObjectsMarked() )
+ rDisp.Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ else
+ rDisp.Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ }
+
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstruct::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FALSE;
+
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_ESCAPE:
+ if ( pView->IsAction() )
+ {
+ pView->BrkAction();
+ pWindow->ReleaseMouse();
+ bReturn = TRUE;
+ }
+ else // Zeichenmodus beenden
+ {
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ break;
+
+ case KEY_DELETE:
+ pView->DeleteMarked();
+ bReturn = TRUE;
+ break;
+ }
+
+ if ( !bReturn )
+ {
+ bReturn = FuDraw::KeyInput(rKEvt);
+ }
+
+ return(bReturn);
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuConstruct::Activate()
+{
+ FuDraw::Activate();
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuConstruct::Deactivate()
+{
+ FuDraw::Deactivate();
+}
+
+
+
+
diff --git a/sc/source/ui/drawfunc/fuconuno.cxx b/sc/source/ui/drawfunc/fuconuno.cxx
new file mode 100644
index 000000000000..c1212d4d9699
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuconuno.cxx
@@ -0,0 +1,190 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "fuconuno.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "drawview.hxx"
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuConstUnoControl::FuConstUnoControl(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq)
+ : FuConstruct(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+ SFX_REQUEST_ARG( rReq, pInventorItem, SfxUInt32Item, SID_FM_CONTROL_INVENTOR, FALSE );
+ SFX_REQUEST_ARG( rReq, pIdentifierItem, SfxUInt16Item, SID_FM_CONTROL_IDENTIFIER, FALSE );
+ if( pInventorItem )
+ nInventor = pInventorItem->GetValue();
+ if( pIdentifierItem )
+ nIdentifier = pIdentifierItem->GetValue();
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuConstUnoControl::~FuConstUnoControl()
+{
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstUnoControl::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuConstruct::MouseButtonDown(rMEvt);
+
+ if ( rMEvt.IsLeft() && !pView->IsAction() )
+ {
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pWindow->CaptureMouse();
+ pView->BegCreateObj(aPnt);
+ bReturn = TRUE;
+ }
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstUnoControl::MouseMove(const MouseEvent& rMEvt)
+{
+ return FuConstruct::MouseMove(rMEvt);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstUnoControl::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FALSE;
+
+ if ( pView->IsCreateObj() && rMEvt.IsLeft() )
+ {
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pView->EndCreateObj(SDRCREATE_FORCEEND);
+ bReturn = TRUE;
+ }
+ return (FuConstruct::MouseButtonUp(rMEvt) || bReturn);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuConstUnoControl::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FuConstruct::KeyInput(rKEvt);
+ return(bReturn);
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuConstUnoControl::Activate()
+{
+ pView->SetCurrentObj( nIdentifier, nInventor );
+
+ aNewPointer = Pointer( POINTER_DRAW_RECT );
+ aOldPointer = pWindow->GetPointer();
+ pViewShell->SetActivePointer( aNewPointer );
+
+ SdrLayer* pLayer = pView->GetModel()->GetLayerAdmin().GetLayerPerID(SC_LAYER_CONTROLS);
+ if (pLayer)
+ pView->SetActiveLayer( pLayer->GetName() );
+
+ FuConstruct::Activate();
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuConstUnoControl::Deactivate()
+{
+ FuConstruct::Deactivate();
+
+ SdrLayer* pLayer = pView->GetModel()->GetLayerAdmin().GetLayerPerID(SC_LAYER_FRONT);
+ if (pLayer)
+ pView->SetActiveLayer( pLayer->GetName() );
+
+ pViewShell->SetActivePointer( aOldPointer );
+}
+
+// #98185# Create default drawing objects via keyboard
+SdrObject* FuConstUnoControl::CreateDefaultObject(const sal_uInt16 /* nID */, const Rectangle& rRectangle)
+{
+ // case SID_FM_CREATE_CONTROL:
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
+ 0L, pDrDoc);
+
+ if(pObj)
+ {
+ pObj->SetLogicRect(rRectangle);
+ }
+
+ return pObj;
+}
+
+
diff --git a/sc/source/ui/drawfunc/fudraw.cxx b/sc/source/ui/drawfunc/fudraw.cxx
new file mode 100644
index 000000000000..bad23bf26ed1
--- /dev/null
+++ b/sc/source/ui/drawfunc/fudraw.cxx
@@ -0,0 +1,863 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/editeng.hxx> // EditEngine::IsSimpleCharInput
+#include <editeng/outlobj.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdundo.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "sc.hrc"
+#include "fudraw.hxx"
+#include "futext.hxx"
+#include "tabvwsh.hxx"
+#include "drwlayer.hxx"
+#include "scresid.hxx"
+#include "userdat.hxx"
+#include "docsh.hxx"
+#include "postit.hxx"
+#include "globstr.hrc"
+#include "drawview.hxx"
+
+/*************************************************************************
+|*
+|* Basisklasse fuer alle Drawmodul-spezifischen Funktionen
+|*
+\************************************************************************/
+
+FuDraw::FuDraw(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq) :
+ FuPoor (pViewSh, pWin, pViewP, pDoc, rReq),
+ aNewPointer ( POINTER_ARROW ),
+ aOldPointer ( POINTER_ARROW )
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuDraw::~FuDraw()
+{
+}
+
+/*************************************************************************
+|*
+|* Modifier-Tasten auswerten
+|*
+\************************************************************************/
+
+void FuDraw::DoModifiers(const MouseEvent& rMEvt)
+{
+ // Shift = Ortho und AngleSnap
+ // Control = Snap (Toggle)
+ // Alt = zentrisch
+
+ BOOL bShift = rMEvt.IsShift();
+// BOOL bCtrl = rMEvt.IsMod1();
+ BOOL bAlt = rMEvt.IsMod2();
+
+// ScViewData* pViewData = pViewShell->GetViewData();
+// const ScViewOptions& rOpt = pViewData->GetOptions();
+// const ScGridOptions& rGrid = rOpt.GetGridOptions();
+// BOOL bGridOpt = rGrid.GetUseGridSnap();
+
+ BOOL bOrtho = bShift;
+ BOOL bAngleSnap = bShift;
+// BOOL bGridSnap = ( bGridOpt != bCtrl ); // andere Snap's nicht unterstuetzt
+ BOOL bCenter = bAlt;
+
+ // #i33136#
+ if(doConstructOrthogonal())
+ {
+ bOrtho = !bShift;
+ }
+
+ if (pView->IsOrtho() != bOrtho)
+ pView->SetOrtho(bOrtho);
+ if (pView->IsAngleSnapEnabled() != bAngleSnap)
+ pView->SetAngleSnapEnabled(bAngleSnap);
+
+/* Control fuer Snap beisst sich beim Verschieben mit "kopieren" !!!
+
+ if (pView->IsGridSnap() != bGridSnap)
+ pView->SetGridSnap(bGridSnap);
+ if (pView->IsSnapEnabled() != bGridSnap)
+ pView->SetSnapEnabled(bGridSnap);
+*/
+ if (pView->IsCreate1stPointAsCenter() != bCenter)
+ pView->SetCreate1stPointAsCenter(bCenter);
+ if (pView->IsResizeAtCenter() != bCenter)
+ pView->SetResizeAtCenter(bCenter);
+
+}
+
+void FuDraw::ResetModifiers()
+{
+ ScViewData* pViewData = pViewShell->GetViewData();
+ const ScViewOptions& rOpt = pViewData->GetOptions();
+ const ScGridOptions& rGrid = rOpt.GetGridOptions();
+ BOOL bGridOpt = rGrid.GetUseGridSnap();
+
+ if (pView->IsOrtho())
+ pView->SetOrtho(FALSE);
+ if (pView->IsAngleSnapEnabled())
+ pView->SetAngleSnapEnabled(FALSE);
+
+ if (pView->IsGridSnap() != bGridOpt)
+ pView->SetGridSnap(bGridOpt);
+ if (pView->IsSnapEnabled() != bGridOpt)
+ pView->SetSnapEnabled(bGridOpt);
+
+ if (pView->IsCreate1stPointAsCenter())
+ pView->SetCreate1stPointAsCenter(FALSE);
+ if (pView->IsResizeAtCenter())
+ pView->SetResizeAtCenter(FALSE);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuDraw::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ DoModifiers( rMEvt );
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuDraw::MouseMove(const MouseEvent& rMEvt)
+{
+ // #106438# evaluate modifiers only if in a drawing layer action
+ // (don't interfere with keyboard shortcut handling)
+ if (pView->IsAction())
+ DoModifiers( rMEvt );
+
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuDraw::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ ResetModifiers();
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL lcl_KeyEditMode( SdrObject* pObj, ScTabViewShell* pViewShell, const KeyEvent* pInitialKey )
+{
+ BOOL bReturn = FALSE;
+ if ( pObj && pObj->ISA(SdrTextObj) && !pObj->ISA(SdrUnoObj) )
+ {
+ // start text edit - like FuSelection::MouseButtonUp,
+ // but with bCursorToEnd instead of mouse position
+
+ OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
+ BOOL bVertical = ( pOPO && pOPO->IsVertical() );
+ USHORT nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
+
+ // don't switch shells if text shell is already active
+ FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
+ if ( !pPoor || pPoor->GetSlotID() != nTextSlotId )
+ {
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(nTextSlotId, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
+ }
+
+ // get the resulting FuText and set in edit mode
+ pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
+ if ( pPoor && pPoor->GetSlotID() == nTextSlotId ) // no RTTI
+ {
+ FuText* pText = (FuText*)pPoor;
+ pText->SetInEditMode( pObj, NULL, TRUE, pInitialKey );
+ //! set cursor to end of text
+ }
+ bReturn = TRUE;
+ }
+ return bReturn;
+}
+
+BOOL __EXPORT FuDraw::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FALSE;
+ ScViewData& rViewData = *pViewShell->GetViewData();
+
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_ESCAPE:
+
+ /* 18.12.95: TextShell beibehalten nicht mehr gewuenscht...
+ *
+ * if ( pView->IsAction() )
+ * {
+ * pView->BrkAction();
+ * pWindow->ReleaseMouse();
+ * bReturn = TRUE;
+ * }
+ * else if ( pView->IsTextEdit() )
+ * {
+ * pView->EndTextEdit();
+ * pView->SetCreateMode();
+ * pViewShell->GetScDrawView()->InvalidateDrawTextAttrs();
+ * bReturn = TRUE;
+ * }
+ * else
+ */
+
+ if ( pViewShell->IsDrawTextShell() || aSfxRequest.GetSlot() == SID_DRAW_NOTEEDIT )
+ {
+ // in normale Draw-Shell, wenn Objekt selektiert, sonst Zeichnen aus
+ rViewData.GetDispatcher().Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ bReturn = TRUE;
+ }
+ else if ( pViewShell->IsDrawSelMode() )
+ {
+ pView->UnmarkAll();
+ rViewData.GetDispatcher().Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ bReturn = TRUE;
+ }
+ else if ( pView->AreObjectsMarked() )
+ {
+ // #97016# III
+ SdrHdlList& rHdlList = const_cast< SdrHdlList& >( pView->GetHdlList() );
+ if( rHdlList.GetFocusHdl() )
+ rHdlList.ResetFocusHdl();
+ else
+ pView->UnmarkAll();
+
+ // Beim Bezier-Editieren ist jetzt wieder das Objekt selektiert
+ if (!pView->AreObjectsMarked())
+ pViewShell->SetDrawShell( FALSE );
+
+ bReturn = TRUE;
+ }
+ break;
+
+ case KEY_DELETE: //! ueber Accelerator
+ pView->DeleteMarked();
+ bReturn = TRUE;
+ break;
+
+ case KEY_RETURN:
+ {
+ if( rKEvt.GetKeyCode().GetModifier() == 0 )
+ {
+ // #98256# activate OLE object on RETURN for selected object
+ // #98198# put selected text object in edit mode
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
+ {
+ BOOL bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace();
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( pObj && pObj->ISA( SdrOle2Obj ) && !bOle )
+ {
+ //HMHpView->HideMarkHdl();
+ pViewShell->ActivateObject( static_cast< SdrOle2Obj* >( pObj ), 0 );
+
+ // consumed
+ bReturn = TRUE;
+ }
+ else if ( lcl_KeyEditMode( pObj, pViewShell, NULL ) ) // start text edit for suitable object
+ bReturn = TRUE;
+ }
+ }
+ }
+ break;
+
+ case KEY_F2:
+ {
+ if( rKEvt.GetKeyCode().GetModifier() == 0 )
+ {
+ // #98198# put selected text object in edit mode
+ // (this is not SID_SETINPUTMODE, but F2 hardcoded, like in Writer)
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if ( lcl_KeyEditMode( pObj, pViewShell, NULL ) ) // start text edit for suitable object
+ bReturn = TRUE;
+ }
+ }
+ }
+ break;
+
+ // #97016#
+ case KEY_TAB:
+ {
+ // in calc do NOT start draw object selection using TAB/SHIFT-TAB when
+ // there is not yet a object selected
+ if(pView->AreObjectsMarked())
+ {
+ KeyCode aCode = rKEvt.GetKeyCode();
+
+ if ( !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ // changeover to the next object
+ if(!pView->MarkNextObj( !aCode.IsShift() ))
+ {
+ // #97016# No next object: go over open end and
+ // get first from the other side
+ pView->UnmarkAllObj();
+ pView->MarkNextObj(!aCode.IsShift());
+ }
+
+ // #97016# II
+ if(pView->AreObjectsMarked())
+ pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
+
+ bReturn = TRUE;
+ }
+
+ // #98994# handle Mod1 and Mod2 to get travelling running on different systems
+ if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
+ {
+ // #97016# II do something with a selected handle?
+ const SdrHdlList& rHdlList = pView->GetHdlList();
+ sal_Bool bForward(!rKEvt.GetKeyCode().IsShift());
+
+ ((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
+
+ // guarantee visibility of focused handle
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+
+ if(pHdl)
+ {
+ Point aHdlPosition(pHdl->GetPos());
+ Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
+ pView->MakeVisible(aVisRect, *pWindow);
+ }
+
+ // consumed
+ bReturn = TRUE;
+ }
+ }
+ }
+ break;
+
+ // #97016#
+ case KEY_END:
+ {
+ // in calc do NOT select the last draw object when
+ // there is not yet a object selected
+ if(pView->AreObjectsMarked())
+ {
+ KeyCode aCode = rKEvt.GetKeyCode();
+
+ if ( aCode.IsMod1() )
+ {
+ // #97016# mark last object
+ pView->UnmarkAllObj();
+ pView->MarkNextObj(FALSE);
+
+ // #97016# II
+ if(pView->AreObjectsMarked())
+ pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
+
+ bReturn = TRUE;
+ }
+ }
+ }
+ break;
+
+ // #97016#
+ case KEY_HOME:
+ {
+ // in calc do NOT select the first draw object when
+ // there is not yet a object selected
+ if(pView->AreObjectsMarked())
+ {
+ KeyCode aCode = rKEvt.GetKeyCode();
+
+ if ( aCode.IsMod1() )
+ {
+ // #97016# mark first object
+ pView->UnmarkAllObj();
+ pView->MarkNextObj(TRUE);
+
+ // #97016# II
+ if(pView->AreObjectsMarked())
+ pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
+
+ bReturn = TRUE;
+ }
+ }
+ }
+ break;
+
+ // #97016#
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ {
+ // in calc do cursor travelling of draw objects only when
+ // there is a object selected yet
+ if(pView->AreObjectsMarked())
+ {
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if(rMarkList.GetMarkCount() == 1)
+ {
+ // disable cursor travelling on note objects as the tail connector position
+ // must not move.
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( ScDrawLayer::IsNoteCaption( pObj ) )
+ break;
+ }
+
+ long nX = 0;
+ long nY = 0;
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+
+ if (nCode == KEY_UP)
+ {
+ // Scroll nach oben
+ nX = 0;
+ nY =-1;
+ }
+ else if (nCode == KEY_DOWN)
+ {
+ // Scroll nach unten
+ nX = 0;
+ nY = 1;
+ }
+ else if (nCode == KEY_LEFT)
+ {
+ // Scroll nach links
+ nX =-1;
+ nY = 0;
+ }
+ else if (nCode == KEY_RIGHT)
+ {
+ // Scroll nach rechts
+ nX = 1;
+ nY = 0;
+ }
+
+ BOOL bReadOnly = rViewData.GetDocShell()->IsReadOnly();
+
+ if(!rKEvt.GetKeyCode().IsMod1() && !bReadOnly)
+ {
+ if(rKEvt.GetKeyCode().IsMod2())
+ {
+ // #97016# move in 1 pixel distance
+ Size aLogicSizeOnePixel = (pWindow) ? pWindow->PixelToLogic(Size(1,1)) : Size(100, 100);
+ nX *= aLogicSizeOnePixel.Width();
+ nY *= aLogicSizeOnePixel.Height();
+ }
+ else
+ {
+ // old, fixed move distance
+ nX *= 100;
+ nY *= 100;
+ }
+
+ // is there a movement to do?
+ if(0 != nX || 0 != nY)
+ {
+ // #97016# II
+ const SdrHdlList& rHdlList = pView->GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+
+ if(0L == pHdl)
+ {
+ // #107086# only take action when move is allowed
+ if(pView->IsMoveAllowed())
+ {
+ // #90129# restrict movement to WorkArea
+ const Rectangle& rWorkArea = pView->GetWorkArea();
+
+ if(!rWorkArea.IsEmpty())
+ {
+ Rectangle aMarkRect(pView->GetMarkedObjRect());
+ aMarkRect.Move(nX, nY);
+
+ if(!aMarkRect.IsInside(rWorkArea))
+ {
+ if(aMarkRect.Left() < rWorkArea.Left())
+ {
+ nX += rWorkArea.Left() - aMarkRect.Left();
+ }
+
+ if(aMarkRect.Right() > rWorkArea.Right())
+ {
+ nX -= aMarkRect.Right() - rWorkArea.Right();
+ }
+
+ if(aMarkRect.Top() < rWorkArea.Top())
+ {
+ nY += rWorkArea.Top() - aMarkRect.Top();
+ }
+
+ if(aMarkRect.Bottom() > rWorkArea.Bottom())
+ {
+ nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
+ }
+ }
+ }
+
+ // now move the selected draw objects
+ pView->MoveAllMarked(Size(nX, nY));
+
+ // #97016# II
+ pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
+
+ bReturn = TRUE;
+ }
+ }
+ else
+ {
+ // move handle with index nHandleIndex
+ if(pHdl && (nX || nY))
+ {
+ // now move the Handle (nX, nY)
+ Point aStartPoint(pHdl->GetPos());
+ Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
+ const SdrDragStat& rDragStat = pView->GetDragStat();
+
+ // start dragging
+ pView->BegDragObj(aStartPoint, 0, pHdl, 0);
+
+ if(pView->IsDragObj())
+ {
+ FASTBOOL bWasNoSnap = rDragStat.IsNoSnap();
+ BOOL bWasSnapEnabled = pView->IsSnapEnabled();
+
+ // switch snapping off
+ if(!bWasNoSnap)
+ ((SdrDragStat&)rDragStat).SetNoSnap(TRUE);
+ if(bWasSnapEnabled)
+ pView->SetSnapEnabled(FALSE);
+
+ pView->MovAction(aEndPoint);
+ pView->EndDragObj();
+
+ // restore snap
+ if(!bWasNoSnap)
+ ((SdrDragStat&)rDragStat).SetNoSnap(bWasNoSnap);
+ if(bWasSnapEnabled)
+ pView->SetSnapEnabled(bWasSnapEnabled);
+ }
+
+ // make moved handle visible
+ Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
+ pView->MakeVisible(aVisRect, *pWindow);
+
+ bReturn = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ // #97016#
+ case KEY_SPACE:
+ {
+ // in calc do only something when draw objects are selected
+ if(pView->AreObjectsMarked())
+ {
+ const SdrHdlList& rHdlList = pView->GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+
+ if(pHdl)
+ {
+ if(pHdl->GetKind() == HDL_POLY)
+ {
+ // rescue ID of point with focus
+ sal_uInt32 nPol(pHdl->GetPolyNum());
+ sal_uInt32 nPnt(pHdl->GetPointNum());
+
+ if(pView->IsPointMarked(*pHdl))
+ {
+ if(rKEvt.GetKeyCode().IsShift())
+ {
+ pView->UnmarkPoint(*pHdl);
+ }
+ }
+ else
+ {
+ if(!rKEvt.GetKeyCode().IsShift())
+ {
+ pView->UnmarkAllPoints();
+ }
+
+ pView->MarkPoint(*pHdl);
+ }
+
+ if(0L == rHdlList.GetFocusHdl())
+ {
+ // restore point with focus
+ SdrHdl* pNewOne = 0L;
+
+ for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
+ {
+ SdrHdl* pAct = rHdlList.GetHdl(a);
+
+ if(pAct
+ && pAct->GetKind() == HDL_POLY
+ && pAct->GetPolyNum() == nPol
+ && pAct->GetPointNum() == nPnt)
+ {
+ pNewOne = pAct;
+ }
+ }
+
+ if(pNewOne)
+ {
+ ((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
+ }
+ }
+
+ bReturn = TRUE;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ if (!bReturn)
+ {
+ bReturn = FuPoor::KeyInput(rKEvt);
+ }
+
+ if (!bReturn)
+ {
+ // #98198# allow direct typing into a selected text object
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() && EditEngine::IsSimpleCharInput(rKEvt) )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+
+ // start text edit for suitable object, pass key event to OutlinerView
+ if ( lcl_KeyEditMode( pObj, pViewShell, &rKEvt ) )
+ bReturn = TRUE;
+ }
+ }
+
+ return (bReturn);
+}
+
+// #97016# II
+void FuDraw::SelectionHasChanged()
+{
+ const SdrHdlList& rHdlList = pView->GetHdlList();
+ ((SdrHdlList&)rHdlList).ResetFocusHdl();
+}
+
+/*************************************************************************
+|*
+|* Vor dem Scrollen Selektionsdarstellung ausblenden
+|*
+\************************************************************************/
+
+void FuDraw::ScrollStart()
+{
+// HideShownXor in Gridwin
+}
+
+/*************************************************************************
+|*
+|* Nach dem Scrollen Selektionsdarstellung wieder anzeigen
+|*
+\************************************************************************/
+
+void FuDraw::ScrollEnd()
+{
+// ShowShownXor in Gridwin
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuDraw::Activate()
+{
+ FuPoor::Activate();
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuDraw::Deactivate()
+{
+ FuPoor::Deactivate();
+}
+
+/*************************************************************************
+|*
+|* Maus-Pointer umschalten
+|*
+\************************************************************************/
+
+BOOL lcl_UrlHit( SdrView* pView, const Point& rPosPixel, Window* pWindow )
+{
+ SdrViewEvent aVEvt;
+ MouseEvent aMEvt( rPosPixel, 1, 0, MOUSE_LEFT );
+ SdrHitKind eHit = pView->PickAnything( aMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
+
+ if ( eHit != SDRHIT_NONE && aVEvt.pObj != NULL )
+ {
+ if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) && ScDrawLayer::GetHitIMapObject(
+ aVEvt.pObj, pWindow->PixelToLogic(rPosPixel), *pWindow ) )
+ return TRUE;
+
+ if ( aVEvt.eEvent == SDREVENT_EXECUTEURL )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void FuDraw::ForcePointer(const MouseEvent* pMEvt)
+{
+ if ( !pView->IsAction() )
+ {
+ Point aPosPixel = pWindow->GetPointerPosPixel();
+ BOOL bAlt = pMEvt && pMEvt->IsMod2();
+ Point aPnt = pWindow->PixelToLogic( aPosPixel );
+ SdrHdl* pHdl = pView->PickHandle(aPnt);
+ SdrObject* pObj;
+ SdrPageView* pPV;
+
+ ScMacroInfo* pInfo = 0;
+ if ( pView->PickObj(aPnt, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
+ {
+ if ( pObj->IsGroupObject() )
+ {
+ SdrObject* pHit = 0;
+ if ( pView->PickObj(aMDPos, pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
+ pObj = pHit;
+ }
+ pInfo = ScDrawLayer::GetMacroInfo( pObj );
+ }
+
+ if ( pView->IsTextEdit() )
+ {
+ pViewShell->SetActivePointer(Pointer(POINTER_TEXT)); // kann nicht sein ?
+ }
+ else if ( pHdl )
+ {
+ pViewShell->SetActivePointer(
+ pView->GetPreferedPointer( aPnt, pWindow ) );
+ }
+ else if ( pView->IsMarkedHit(aPnt) )
+ {
+ pViewShell->SetActivePointer( Pointer(POINTER_MOVE) );
+ }
+ else if ( !bAlt && ( !pMEvt || !pMEvt->GetButtons() )
+ && lcl_UrlHit( pView, aPosPixel, pWindow ) )
+ {
+ // kann mit ALT unterdrueckt werden
+ pWindow->SetPointer( Pointer( POINTER_REFHAND ) ); // Text-URL / ImageMap
+ }
+ 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 ????
+ pViewShell->SetActivePointer( pObj->GetMacroPointer(aHitRec) );
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ else if ( !bAlt && pInfo && ((pInfo->GetMacro().getLength() > 0) || (pInfo->GetHlink().getLength() > 0)) )
+#else
+ else if ( !bAlt && pInfo && (pInfo->GetMacro().getLength() > 0) )
+#endif
+ pWindow->SetPointer( Pointer( POINTER_REFHAND ) );
+ else if ( IsDetectiveHit( aPnt ) )
+ pViewShell->SetActivePointer( Pointer( POINTER_DETECTIVE ) );
+ else
+ pViewShell->SetActivePointer( aNewPointer ); //! in Gridwin?
+ }
+}
+
+BOOL FuDraw::IsSizingOrMovingNote( const MouseEvent& rMEvt ) const
+{
+ BOOL bIsSizingOrMoving = FALSE;
+ if ( rMEvt.IsLeft() )
+ {
+ const SdrMarkList& rNoteMarkList = pView->GetMarkedObjectList();
+ if(rNoteMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rNoteMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if ( ScDrawLayer::IsNoteCaption( pObj ) )
+ {
+ Point aMPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
+ bIsSizingOrMoving =
+ pView->PickHandle( aMPos ) || // handles to resize the note
+ pView->IsTextEditFrameHit( aMPos ); // frame for moving the note
+ }
+ }
+ }
+ return bIsSizingOrMoving;
+}
diff --git a/sc/source/ui/drawfunc/fuins1.cxx b/sc/source/ui/drawfunc/fuins1.cxx
new file mode 100644
index 000000000000..53a44f058dda
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuins1.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/opengrf.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdomedia.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <svtools/filter.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/urlobj.hxx>
+#include <avmedia/mediawindow.hxx>
+#include <vcl/svapp.hxx>
+
+#include "fuinsert.hxx"
+#include "tabvwsh.hxx"
+#include "drwlayer.hxx"
+#include "drawview.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "progress.hxx"
+#include "sc.hrc"
+
+
+
+////========================================================================
+//// class ImportProgress
+////
+//// Bemerkung:
+//// Diese Klasse stellt lediglich den Handler fuer den ImportProgress des
+//// Grafikfilters bereit.
+////========================================================================
+//
+//class ImportProgress
+//{
+//public:
+// ImportProgress( GraphicFilter& rFilter );
+// ~ImportProgress();
+//
+// DECL_LINK( Update, GraphicFilter* );
+//
+//private:
+// ScProgress aProgress;
+//};
+//
+////------------------------------------------------------------------------
+//
+//ImportProgress::ImportProgress( GraphicFilter& rFilter )
+// : aProgress( NULL, // SfxViewFrame*, NULL == alle Docs locken
+// String( ScResId(STR_INSERTGRAPHIC) ),
+// 100 )
+//{
+// rFilter.SetUpdatePercentHdl( LINK( this, ImportProgress, Update) );
+//}
+//
+////------------------------------------------------------------------------
+//
+//__EXPORT ImportProgress::~ImportProgress()
+//{
+// aProgress.SetState( 100 );
+//}
+//
+////------------------------------------------------------------------------
+//
+//IMPL_LINK( ImportProgress, Update, GraphicFilter*, pGraphicFilter )
+//{
+// aProgress.SetState( pGraphicFilter->GetPercent() );
+// return 0;
+//}
+
+
+//------------------------------------------------------------------------
+
+void SC_DLLPUBLIC ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage )
+{
+ if ( !rPage.Width() || !rPage.Height() )
+ return;
+
+ Size aPageSize = rPage;
+ BOOL bNegative = aPageSize.Width() < 0;
+ if ( bNegative )
+ {
+ // make everything positive temporarily
+ aPageSize.Width() = -aPageSize.Width();
+ rPos.X() = -rPos.X() - rSize.Width();
+ }
+
+ if ( rSize.Width() > aPageSize.Width() || rSize.Height() > aPageSize.Height() )
+ {
+ double fX = aPageSize.Width() / (double) rSize.Width();
+ double fY = aPageSize.Height() / (double) rSize.Height();
+
+ if ( fX < fY )
+ {
+ rSize.Width() = aPageSize.Width();
+ rSize.Height() = (long) ( rSize.Height() * fX );
+ }
+ else
+ {
+ rSize.Height() = aPageSize.Height();
+ rSize.Width() = (long) ( rSize.Width() * fY );
+ }
+
+ if (!rSize.Width())
+ rSize.Width() = 1;
+ if (!rSize.Height())
+ rSize.Height() = 1;
+ }
+
+ if ( rPos.X() + rSize.Width() > aPageSize.Width() )
+ rPos.X() = aPageSize.Width() - rSize.Width();
+ if ( rPos.Y() + rSize.Height() > aPageSize.Height() )
+ rPos.Y() = aPageSize.Height() - rSize.Height();
+
+ if ( bNegative )
+ rPos.X() = -rPos.X() - rSize.Width(); // back to real position
+}
+
+//------------------------------------------------------------------------
+
+void lcl_InsertGraphic( const Graphic& rGraphic,
+ const String& rFileName, const String& rFilterName, BOOL bAsLink, BOOL bApi,
+ ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView )
+{
+ // #74778# set the size so the graphic has its original pixel size
+ // at 100% view scale (as in SetMarkedOriginalSize),
+ // instead of respecting the current view scale
+
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ MapMode aSourceMap = rGraphic.GetPrefMapMode();
+ MapMode aDestMap( MAP_100TH_MM );
+ if ( aSourceMap.GetMapUnit() == MAP_PIXEL && pDrawView )
+ {
+ Fraction aScaleX, aScaleY;
+ pDrawView->CalcNormScale( aScaleX, aScaleY );
+ aDestMap.SetScaleX(aScaleX);
+ aDestMap.SetScaleY(aScaleY);
+ }
+ Size aLogicSize = pWindow->LogicToLogic(
+ rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
+
+ // Limit size
+
+ SdrPageView* pPV = pView->GetSdrPageView();
+ SdrPage* pPage = pPV->GetPage();
+ Point aInsertPos = pViewSh->GetInsertPos();
+
+ ScViewData* pData = pViewSh->GetViewData();
+ if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
+ aInsertPos.X() -= aLogicSize.Width(); // move position to left edge
+
+ ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
+
+ Rectangle aRect ( aInsertPos, aLogicSize );
+
+ SdrGrafObj* pObj = new SdrGrafObj( rGraphic, aRect );
+
+ // #118522# calling SetGraphicLink here doesn't work
+
+ // #49961# Path is no longer used as name for the graphics object
+
+ ScDrawLayer* pLayer = (ScDrawLayer*) pView->GetModel();
+ String aName = pLayer->GetNewGraphicName(); // "Grafik x"
+ pObj->SetName(aName);
+
+ // don't select if from (dispatch) API, to allow subsequent cell operations
+ ULONG nInsOptions = bApi ? SDRINSERT_DONTMARK : 0;
+ pView->InsertObjectAtView( pObj, *pPV, nInsOptions );
+
+ // #118522# SetGraphicLink has to be used after inserting the object,
+ // otherwise an empty graphic is swapped in and the contact stuff crashes.
+ // See #i37444#.
+ if ( bAsLink )
+ pObj->SetGraphicLink( rFileName, rFilterName );
+}
+
+//------------------------------------------------------------------------
+
+void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi,
+ ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView,
+ const Size& rPrefSize )
+{
+ SdrPageView* pPV = pView->GetSdrPageView();
+ SdrPage* pPage = pPV->GetPage();
+ ScViewData* pData = pViewSh->GetViewData();
+ Point aInsertPos( pViewSh->GetInsertPos() );
+ Size aSize;
+
+ if( rPrefSize.Width() && rPrefSize.Height() )
+ {
+ if( pWindow )
+ aSize = pWindow->PixelToLogic( rPrefSize, MAP_100TH_MM );
+ else
+ aSize = Application::GetDefaultDevice()->PixelToLogic( rPrefSize, MAP_100TH_MM );
+ }
+ else
+ aSize = Size( 5000, 5000 );
+
+ ScLimitSizeOnDrawPage( aSize, aInsertPos, pPage->GetSize() );
+
+ if( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
+ aInsertPos.X() -= aSize.Width();
+
+ SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aInsertPos, aSize ) );
+
+ pObj->setURL( rMediaURL );
+ pView->InsertObjectAtView( pObj, *pPV, bApi ? SDRINSERT_DONTMARK : 0 );
+}
+
+/*************************************************************************
+|*
+|* FuInsertGraphic::Konstruktor
+|*
+\************************************************************************/
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+FuInsertGraphic::FuInsertGraphic( ScTabViewShell* pViewSh,
+ Window* pWin,
+ ScDrawView* pViewP,
+ SdrModel* pDoc,
+ SfxRequest& rReq )
+ : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState( SID_INSERT_GRAPHIC, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ String aFileName = ((const SfxStringItem*)pItem)->GetValue();
+
+ String aFilterName;
+ if ( pReqArgs->GetItemState( FN_PARAM_FILTER, TRUE, &pItem ) == SFX_ITEM_SET )
+ aFilterName = ((const SfxStringItem*)pItem)->GetValue();
+
+ BOOL bAsLink = FALSE;
+ if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
+ bAsLink = ((const SfxBoolItem*)pItem)->GetValue();
+
+ Graphic aGraphic;
+ int nError = GraphicFilter::LoadGraphic( aFileName, aFilterName, aGraphic, GraphicFilter::GetGraphicFilter() );
+ if ( nError == GRFILTER_OK )
+ {
+ lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, TRUE, pViewSh, pWindow, pView );
+ }
+ }
+ else
+ {
+ SvxOpenGraphicDialog aDlg(ScResId(STR_INSERTGRAPHIC));
+
+ if( aDlg.Execute() == GRFILTER_OK )
+ {
+ Graphic aGraphic;
+ int nError = aDlg.GetGraphic(aGraphic);
+ if( nError == GRFILTER_OK )
+ {
+ String aFileName = aDlg.GetPath();
+ String aFilterName = aDlg.GetCurrentFilter();
+ BOOL bAsLink = aDlg.IsAsLink();
+
+ lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, FALSE, pViewSh, pWindow, pView );
+
+ // append items for recording
+ rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
+ rReq.Done();
+ }
+ else
+ {
+ // error is handled in SvxOpenGraphicDialog::GetGraphic
+
+#if 0
+ USHORT nRes = 0;
+ switch ( nError )
+ {
+ case GRFILTER_OPENERROR: nRes = SCSTR_GRFILTER_OPENERROR; break;
+ case GRFILTER_IOERROR: nRes = SCSTR_GRFILTER_IOERROR; break;
+ case GRFILTER_FORMATERROR: nRes = SCSTR_GRFILTER_FORMATERROR; break;
+ case GRFILTER_VERSIONERROR: nRes = SCSTR_GRFILTER_VERSIONERROR; break;
+ case GRFILTER_FILTERERROR: nRes = SCSTR_GRFILTER_FILTERERROR; break;
+ case GRFILTER_TOOBIG: nRes = SCSTR_GRFILTER_TOOBIG; break;
+ }
+ if ( nRes )
+ {
+ InfoBox aInfoBox( pWindow, String(ScResId(nRes)) );
+ aInfoBox.Execute();
+ }
+ else
+ {
+ ULONG nStreamError = GetGrfFilter()->GetLastError().nStreamError;
+ if( ERRCODE_NONE != nStreamError )
+ ErrorHandler::HandleError( nStreamError );
+ }
+#endif
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* FuInsertGraphic::Destruktor
+|*
+\************************************************************************/
+
+FuInsertGraphic::~FuInsertGraphic()
+{
+}
+
+/*************************************************************************
+|*
+|* FuInsertGraphic::Function aktivieren
+|*
+\************************************************************************/
+
+void FuInsertGraphic::Activate()
+{
+ FuPoor::Activate();
+}
+
+/*************************************************************************
+|*
+|* FuInsertGraphic::Function deaktivieren
+|*
+\************************************************************************/
+
+void FuInsertGraphic::Deactivate()
+{
+ FuPoor::Deactivate();
+}
+
+/*************************************************************************
+|*
+|* FuInsertMedia::Konstruktor
+|*
+\************************************************************************/
+
+FuInsertMedia::FuInsertMedia( ScTabViewShell* pViewSh,
+ Window* pWin,
+ ScDrawView* pViewP,
+ SdrModel* pDoc,
+ SfxRequest& rReq ) :
+ FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+ ::rtl::OUString aURL;
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ bool bAPI = false;
+
+ if( pReqArgs )
+ {
+ const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, &pReqArgs->Get( rReq.GetSlot() ) );
+
+ if( pStringItem )
+ {
+ aURL = pStringItem->GetValue();
+ bAPI = aURL.getLength();
+ }
+ }
+
+ if( bAPI || ::avmedia::MediaWindow::executeMediaURLDialog( pWindow, aURL ) )
+ {
+ Size aPrefSize;
+
+ if( pWin )
+ pWin->EnterWait();
+
+ if( !::avmedia::MediaWindow::isMediaURL( aURL, true, &aPrefSize ) )
+ {
+ if( pWin )
+ pWin->LeaveWait();
+
+ if( !bAPI )
+ ::avmedia::MediaWindow::executeFormatErrorBox( pWindow );
+ }
+ else
+ {
+ lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize );
+
+ if( pWin )
+ pWin->LeaveWait();
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* FuInsertMedia::Destruktor
+|*
+\************************************************************************/
+
+FuInsertMedia::~FuInsertMedia()
+{
+}
+
+/*************************************************************************
+|*
+|* FuInsertMedia::Function aktivieren
+|*
+\************************************************************************/
+
+void FuInsertMedia::Activate()
+{
+ FuPoor::Activate();
+}
+
+/*************************************************************************
+|*
+|* FuInsertMedia::Function deaktivieren
+|*
+\************************************************************************/
+
+void FuInsertMedia::Deactivate()
+{
+ FuPoor::Deactivate();
+}
diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx
new file mode 100644
index 000000000000..f648a1484e8e
--- /dev/null
+++ b/sc/source/ui/drawfunc/fuins2.cxx
@@ -0,0 +1,849 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//------------------------------------------------------------------------
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <sot/exchange.hxx>
+#include <svl/globalnameitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/stritem.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/pfiledlg.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/urihelper.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svtools/insdlg.hxx>
+#include <svtools/soerr.hxx>
+#include <svx/svxdlg.hxx>
+#include <sot/clsids.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+
+
+// BM/IHA --
+#include <cppuhelper/component_context.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <cppuhelper/bootstrap.hxx>
+
+using namespace ::com::sun::star;
+// BM/IHA --
+
+// erAck
+#include "chart2uno.hxx"
+// erAck
+
+#include "fuinsert.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "chartarr.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "undotab.hxx"
+#include "chartlis.hxx"
+#include "uiitems.hxx"
+#include "globstr.hrc"
+#include "drawview.hxx"
+
+extern SdrObject* pSkipPaintObj; // output.cxx - dieses Objekt nicht zeichnen
+
+//------------------------------------------------------------------------
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScViewData* pViewData,
+ const rtl::OUString& rRangeParam )
+{
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ ScDocument* pScDoc = pDocShell->GetDocument();
+
+ rtl::OUString aRangeString( rRangeParam );
+ if ( !aRangeString.getLength() )
+ {
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ SCCOL nCol2 = 0;
+ SCROW nRow2 = 0;
+ SCTAB nTab2 = 0;
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if ( !rMark.IsMarked() )
+ pViewData->GetView()->MarkDataArea( TRUE );
+
+ if ( pViewData->GetSimpleArea( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 ) == SC_MARK_SIMPLE )
+ {
+ PutInOrder( nCol1, nCol2 );
+ PutInOrder( nRow1, nRow2 );
+ if ( nCol2>nCol1 || nRow2>nRow1 )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ pDoc->LimitChartArea( nTab1, nCol1,nRow1, nCol2,nRow2 );
+
+ String aStr;
+ ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ aRange.Format( aStr, SCR_ABS_3D, pScDoc );
+ aRangeString = aStr;
+ }
+ }
+ }
+
+ if ( aRangeString.getLength() )
+ {
+ // connect to Calc data (if no range string, leave chart alone, with its own data)
+
+ uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
+ uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
+ if( xCompSupp.is())
+ xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
+ OSL_ASSERT( xReceiver.is());
+ if( xReceiver.is() )
+ {
+ uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( pScDoc );
+ xReceiver->attachDataProvider( xDataProvider );
+
+ uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
+ xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
+
+ // Same behavior as with old chart: Always assume data series in columns
+ chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
+ bool bHasCategories = false;
+ bool bFirstCellAsLabel = false;
+
+ // use ScChartPositioner to auto-detect column/row headers (like ScChartArray in old version)
+ ScRangeListRef aRangeListRef( new ScRangeList );
+ aRangeListRef->Parse( aRangeString, pScDoc );
+ 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() );
+ aRangeString = aTmpStr;
+
+ ScChartPositioner aChartPositioner( pScDoc, aRangeListRef );
+ const ScChartPositionMap* pPositionMap( aChartPositioner.GetPositionMap() );
+ if( pPositionMap )
+ {
+ SCSIZE nRowCount = pPositionMap->GetRowCount();
+ if( 1==nRowCount )
+ eDataRowSource = chart::ChartDataRowSource_ROWS;
+ }
+ if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
+ {
+ bHasCategories = aChartPositioner.HasRowHeaders();
+ bFirstCellAsLabel = aChartPositioner.HasColHeaders();
+ }
+ else // in case the default is changed
+ {
+ bHasCategories = aChartPositioner.HasColHeaders();
+ bFirstCellAsLabel = aChartPositioner.HasRowHeaders();
+ }
+ }
+
+ uno::Sequence< beans::PropertyValue > aArgs( 4 );
+ aArgs[0] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
+ uno::makeAny( aRangeString ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[1] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("HasCategories"), -1,
+ uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[2] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
+ uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[3] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("DataRowSource"), -1,
+ uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
+ xReceiver->setArguments( aArgs );
+
+ // don't create chart listener here (range may be modified in chart dialog)
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* FuInsertOLE::Konstruktor
+|*
+\************************************************************************/
+
+FuInsertOLE::FuInsertOLE(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq)
+ : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+
+ //! hier DLL's initalisieren, damit die Factories existieren?
+
+ uno::Reference < embed::XEmbeddedObject > xObj;
+ uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
+ BOOL bIsFromFile = FALSE;
+ ::rtl::OUString aName;
+
+ sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
+ ::rtl::OUString aIconMediaType;
+ uno::Reference< io::XInputStream > xIconMetaFile;
+
+
+ USHORT nSlot = rReq.GetSlot();
+ SFX_REQUEST_ARG( rReq, pNameItem, SfxGlobalNameItem, SID_INSERT_OBJECT, sal_False );
+ if ( nSlot == SID_INSERT_OBJECT && pNameItem )
+ {
+ SvGlobalName aClassName = pNameItem->GetValue();
+ xObj = pViewShell->GetViewFrame()->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( aClassName.GetByteSequence(), aName );
+ }
+ else if ( nSlot == SID_INSERT_SMATH )
+ {
+ if ( SvtModuleOptions().IsMath() )
+ {
+ nSlot = SID_INSERT_OBJECT;
+ xObj = pViewShell->GetViewFrame()->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SM_CLASSID_60 ).GetByteSequence(), aName );
+ rReq.AppendItem( SfxGlobalNameItem( SID_INSERT_OBJECT, SvGlobalName( SO3_SM_CLASSID_60 ) ) );
+ }
+ }
+ else
+ {
+ SvObjectServerList aServerLst;
+ switch ( nSlot )
+ {
+ case SID_INSERT_OBJECT :
+ aServerLst.FillInsertObjects();
+ aServerLst.Remove( ScDocShell::Factory().GetClassId() ); // Starcalc nicht anzeigen
+ //TODO/LATER: currently no inserting of ClassId into SfxRequest!
+ case SID_INSERT_PLUGIN :
+ case SID_INSERT_APPLET :
+ case SID_INSERT_FLOATINGFRAME :
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractInsertObjectDialog* pDlg =
+ pFact->CreateInsertObjectDialog( pViewShell->GetWindow(), nSlot,
+ xStorage, &aServerLst );
+ if ( pDlg )
+ {
+ pDlg->Execute();
+ xObj = pDlg->GetObject();
+
+ xIconMetaFile = pDlg->GetIconIfIconified( &aIconMediaType );
+ if ( xIconMetaFile.is() )
+ nAspect = embed::Aspects::MSOLE_ICON;
+
+ if ( xObj.is() )
+ pViewSh->GetObjectShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
+ // damit DrawShell eingeschaltet wird (Objekt aktivieren ist unnoetig):
+ bIsFromFile = !pDlg->IsCreateNew();
+ DELETEZ( pDlg );
+ }
+
+ break;
+ }
+ case SID_INSERT_SOUND :
+ case SID_INSERT_VIDEO :
+ {
+ // create special filedialog for plugins
+ SvxPluginFileDlg aPluginFileDialog(pWin, nSlot);
+
+ // open filedlg
+ if ( ERRCODE_NONE == aPluginFileDialog.Execute() )
+ {
+ // get URL
+ INetURLObject aURL;
+ aURL.SetSmartProtocol( INET_PROT_FILE );
+ if ( aURL.SetURL( aPluginFileDialog.GetPath() ) )
+ {
+ // create a plugin object
+ ::rtl::OUString aObjName;
+ SvGlobalName aClassId( SO3_PLUGIN_CLASSID );
+ comphelper::EmbeddedObjectContainer aCnt( xStorage );
+ xObj = aCnt.CreateEmbeddedObject( aClassId.GetByteSequence(), aObjName );
+ if ( xObj.is() && svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+ {
+ // set properties from dialog
+ uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("PluginURL"),
+ uno::makeAny( ::rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("Invalid URL!");
+ //! error message
+ //! can this happen???
+ }
+ }
+ }
+ }
+ }
+
+ // SvInsertObjectDialog (alles in einem Dialog) wird nicht mehr benutzt
+ if (xObj.is())
+ {
+ pView->UnmarkAll();
+
+ try
+ {
+ ::svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
+ Size aSize;
+ MapMode aMap100( MAP_100TH_MM );
+ MapUnit aMapUnit = MAP_100TH_MM;
+
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ {
+ aObjRef.SetGraphicStream( xIconMetaFile, aIconMediaType );
+ aSize = aObjRef.GetSize( &aMap100 );
+ }
+ else
+ {
+ awt::Size aSz;
+ try
+ {
+ aSz = xObj->getVisualAreaSize( nAspect );
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {
+ // the default size will be set later
+ }
+
+ aSize = Size( aSz.Width, aSz.Height );
+
+ aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+ if (aSize.Height() == 0 || aSize.Width() == 0)
+ {
+ // Rechteck mit ausgewogenem Kantenverhaeltnis
+ aSize.Width() = 5000;
+ aSize.Height() = 5000;
+ Size aTmp = OutputDevice::LogicToLogic( aSize, MAP_100TH_MM, aMapUnit );
+ aSz.Width = aTmp.Width();
+ aSz.Height = aTmp.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+
+ // re-convert aSize to 1/100th mm to avoid rounding errors in comparison below
+ aSize = Window::LogicToLogic( aTmp,
+ MapMode( aMapUnit ), aMap100 );
+ }
+ else
+ aSize = Window::LogicToLogic( aSize,
+ MapMode( aMapUnit ), aMap100 );
+ }
+
+ // Chart initialisieren ?
+ if ( SvtModuleOptions().IsChart() && SotExchange::IsChart( SvGlobalName( xObj->getClassID() ) ) )
+ lcl_ChartInit( xObj, pViewSh->GetViewData(), rtl::OUString() );
+
+ ScViewData* pData = pViewSh->GetViewData();
+
+ Point aPnt = pViewSh->GetInsertPos();
+ if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
+ aPnt.X() -= aSize.Width(); // move position to left edge
+ Rectangle aRect (aPnt, aSize);
+ SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect);
+
+ // Dieses Objekt nicht vor dem Aktivieren zeichnen
+ // (in MarkListHasChanged kommt ein Update)
+ if (!bIsFromFile)
+ pSkipPaintObj = pObj;
+
+ SdrPageView* pPV = pView->GetSdrPageView();
+ pView->InsertObjectAtView(pObj, *pPV);
+
+ if ( nAspect != embed::Aspects::MSOLE_ICON )
+ {
+ // #73279# Math objects change their object size during InsertObject.
+ // New size must be set in SdrObject, or a wrong scale will be set at
+ // ActivateObject.
+
+ try
+ {
+ awt::Size aSz = xObj->getVisualAreaSize( nAspect );
+
+ Size aNewSize( aSz.Width, aSz.Height );
+ aNewSize = OutputDevice::LogicToLogic( aNewSize, aMapUnit, MAP_100TH_MM );
+
+ if ( aNewSize != aSize )
+ {
+ aRect.SetSize( aNewSize );
+ pObj->SetLogicRect( aRect );
+ }
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {}
+ }
+
+ if ( !rReq.IsAPI() )
+ {
+ // XXX Activate aus Makro ist toedlich !!! ???
+ if (bIsFromFile)
+ {
+ // #45012# Objekt ist selektiert, also Draw-Shell aktivieren
+ pViewShell->SetDrawShell( TRUE );
+ }
+ else
+ {
+ pViewShell->ActivateObject( (SdrOle2Obj*) pObj, SVVERB_SHOW );
+ pSkipPaintObj = NULL;
+ }
+ }
+
+ rReq.Done();
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ASSERT( "May need error handling here!\n" );
+ }
+ }
+ else
+ rReq.Ignore();
+}
+
+/*************************************************************************
+|*
+|* FuInsertOLE::Destruktor
+|*
+\************************************************************************/
+
+FuInsertOLE::~FuInsertOLE()
+{
+}
+
+/*************************************************************************
+|*
+|* FuInsertOLE::Function aktivieren
+|*
+\************************************************************************/
+
+void FuInsertOLE::Activate()
+{
+ FuPoor::Activate();
+}
+
+/*************************************************************************
+|*
+|* FuInsertOLE::Function deaktivieren
+|*
+\************************************************************************/
+
+void FuInsertOLE::Deactivate()
+{
+ FuPoor::Deactivate();
+}
+
+/*************************************************************************
+|*
+|* FuInsertChart::Konstruktor
+|*
+\************************************************************************/
+
+FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq)
+ : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+
+ if( SvtModuleOptions().IsChart() )
+ {
+ // ----------------------------------------
+ // BM/IHA --
+
+ // get range
+ ::rtl::OUString aRangeString;
+ ScRange aPositionRange; // cell range for chart positioning
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_5, &pItem ) )
+ aRangeString = ::rtl::OUString( ((const SfxStringItem*)pItem)->GetValue());
+
+ aPositionRange = pViewSh->GetViewData()->GetCurPos();
+ }
+ else
+ {
+ ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
+ bool bAutomaticMark = false;
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ pViewSh->GetViewData()->GetView()->MarkDataArea( TRUE );
+ bAutomaticMark = true;
+ }
+
+ ScMarkData aMultiMark( rMark );
+ aMultiMark.MarkToMulti();
+
+ ScRangeList aRanges;
+ aMultiMark.FillRangeListWithMarks( &aRanges, FALSE );
+ String aStr;
+ ScDocument* pDocument = pViewSh->GetViewData()->GetDocument();
+ aRanges.Format( aStr, SCR_ABS_3D, pDocument, pDocument->GetAddressConvention() );
+ aRangeString = aStr;
+
+ // get "total" range for positioning
+ ULONG nCount = aRanges.Count();
+ if ( nCount > 0 )
+ {
+ aPositionRange = *aRanges.GetObject(0);
+ for (ULONG i=1; i<nCount; i++)
+ aPositionRange.ExtendTo( *aRanges.GetObject(i) );
+ }
+
+ if(bAutomaticMark)
+ pViewSh->GetViewData()->GetView()->Unmark();
+ }
+
+ // ----------------------------------------
+ // adapted old code
+ pView->UnmarkAll();
+
+ ::rtl::OUString aName;
+ const sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
+
+ uno::Reference < embed::XEmbeddedObject > xObj =
+ pViewShell->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID_60 ).GetByteSequence(), aName );
+
+ uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
+ uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
+ if( xCompSupp.is())
+ xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
+
+ // lock the model to suppress any internal updates
+ uno::Reference< frame::XModel > xChartModel( xReceiver, uno::UNO_QUERY );
+ if( xChartModel.is() )
+ xChartModel->lockControllers();
+
+ ScRangeListRef aDummy;
+ Rectangle aMarkDest;
+ SCTAB nMarkTab;
+ BOOL bDrawRect = pViewShell->GetChartArea( aDummy, aMarkDest, nMarkTab );
+
+ // Objekt-Groesse
+ awt::Size aSz = xObj->getVisualAreaSize( nAspect );
+ Size aSize( aSz.Width, aSz.Height );
+
+ MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+
+ BOOL bSizeCh = FALSE;
+ if (bDrawRect && !aMarkDest.IsEmpty())
+ {
+ aSize = aMarkDest.GetSize();
+ bSizeCh = TRUE;
+ }
+ if (aSize.Height() <= 0 || aSize.Width() <= 0)
+ {
+ aSize.Width() = 5000;
+ aSize.Height() = 5000;
+ bSizeCh = TRUE;
+ }
+ if (bSizeCh)
+ {
+ aSize = Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) );
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+ }
+
+ ScViewData* pData = pViewSh->GetViewData();
+ ScDocShell* pScDocSh = pData->GetDocShell();
+ ScDocument* pScDoc = pScDocSh->GetDocument();
+ BOOL bUndo (pScDoc->IsUndoEnabled());
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ UINT16 nToTable = 0;
+
+ if( IS_AVAILABLE( FN_PARAM_4, &pItem ) )
+ {
+ if ( pItem->ISA( SfxUInt16Item ) )
+ nToTable = ((const SfxUInt16Item*)pItem)->GetValue();
+ else if ( pItem->ISA( SfxBoolItem ) )
+ {
+ // #46033# in der idl fuer Basic steht FN_PARAM_4 als SfxBoolItem
+ // -> wenn gesetzt, neue Tabelle, sonst aktuelle Tabelle
+
+ if ( ((const SfxBoolItem*)pItem)->GetValue() )
+ nToTable = static_cast<UINT16>(pScDoc->GetTableCount());
+ else
+ nToTable = static_cast<UINT16>(pData->GetTabNo());
+ }
+ }
+ else
+ {
+ if (bDrawRect)
+ nToTable = static_cast<UINT16>(nMarkTab);
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_4, nToTable ) );
+ }
+
+ // auf neue Tabelle ausgeben?
+ if ( nToTable == pScDoc->GetTableCount() )
+ {
+ // dann los...
+ String aTabName;
+ SCTAB nNewTab = pScDoc->GetTableCount();
+
+ pScDoc->CreateValidTabName( aTabName );
+
+ if ( pScDoc->InsertTab( nNewTab, aTabName ) )
+ {
+ BOOL bAppend = TRUE;
+
+ if (bUndo)
+ {
+ pScDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pScDocSh, nNewTab,
+ bAppend, aTabName ) );
+ }
+
+ pScDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nNewTab ) );
+ pViewSh->SetTabNo( nNewTab, TRUE );
+ pScDocSh->PostPaintExtras(); //! erst hinterher ???
+ }
+ else
+ {
+ DBG_ERROR( "Could not create new table :-/" );
+ }
+ }
+ else if ( nToTable != pData->GetTabNo() )
+ {
+ pViewSh->SetTabNo( nToTable, TRUE );
+ }
+ }
+
+ lcl_ChartInit( xObj, pData, aRangeString ); // set source range, auto-detect column/row headers
+
+ // Objekt-Position
+
+ Point aStart;
+ if ( bDrawRect )
+ aStart = aMarkDest.TopLeft(); // marked by hand
+ else
+ {
+ // get chart position (from window size and data range)
+ aStart = pViewSh->GetChartInsertPos( aSize, aPositionRange );
+ }
+
+ Rectangle aRect (aStart, aSize);
+ SdrOle2Obj* pObj = new SdrOle2Obj( svt::EmbeddedObjectRef( xObj, nAspect ), aName, aRect);
+
+ // Dieses Objekt nicht vor dem Aktivieren zeichnen
+ // (in MarkListHasChanged kommt ein Update)
+ pSkipPaintObj = pObj;
+
+ SdrPageView* pPV = pView->GetSdrPageView();
+
+// pView->InsertObjectAtView(pObj, *pPV);//this call leads to an immidiate redraw and asks the chart for a visual representation
+
+ // use the page instead of the view to insert, so no undo action is created yet
+ SdrPage* pInsPage = pPV->GetPage();
+ pInsPage->InsertObject( pObj );
+ pView->UnmarkAllObj();
+ pView->MarkObj( pObj, pPV );
+ bool bAddUndo = true; // add undo action later, unless the dialog is canceled
+
+ if (rReq.IsAPI())
+ {
+ if( xChartModel.is() )
+ xChartModel->unlockControllers();
+ }
+ else
+ {
+ //the controller will be unlocked by the dialog when the dialog is told to do so
+
+ // only activate object if not called via API (e.g. macro)
+ pViewShell->ActivateObject( (SdrOle2Obj*) pObj, SVVERB_SHOW );
+
+ //open wizard
+ //@todo get context from calc if that has one
+ uno::Reference< uno::XComponentContext > xContext(
+ ::cppu::defaultBootstrap_InitialComponentContext() );
+ if(xContext.is())
+ {
+ uno::Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
+ if(xMCF.is())
+ {
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ xMCF->createInstanceWithContext(
+ rtl::OUString::createFromAscii("com.sun.star.comp.chart2.WizardDialog")
+ , xContext), uno::UNO_QUERY);
+ uno::Reference< lang::XInitialization > xInit( xDialog, uno::UNO_QUERY );
+ if( xChartModel.is() && xInit.is() )
+ {
+ uno::Reference< awt::XWindow > xDialogParentWindow(0);
+ // initialize dialog
+ uno::Sequence<uno::Any> aSeq(2);
+ uno::Any* pArray = aSeq.getArray();
+ beans::PropertyValue aParam1;
+ aParam1.Name = rtl::OUString::createFromAscii("ParentWindow");
+ aParam1.Value <<= uno::makeAny(xDialogParentWindow);
+ beans::PropertyValue aParam2;
+ aParam2.Name = rtl::OUString::createFromAscii("ChartModel");
+ aParam2.Value <<= uno::makeAny(xChartModel);
+ pArray[0] <<= uno::makeAny(aParam1);
+ pArray[1] <<= uno::makeAny(aParam2);
+ xInit->initialize( aSeq );
+
+ // try to set the dialog's position so it doesn't hide the chart
+ uno::Reference < beans::XPropertySet > xDialogProps( xDialog, uno::UNO_QUERY );
+ if ( xDialogProps.is() )
+ {
+ try
+ {
+ //get dialog size:
+ awt::Size aDialogAWTSize;
+ if( xDialogProps->getPropertyValue( ::rtl::OUString::createFromAscii("Size") )
+ >>= aDialogAWTSize )
+ {
+ Size aDialogSize( aDialogAWTSize.Width, aDialogAWTSize.Height );
+ if ( aDialogSize.Width() > 0 && aDialogSize.Height() > 0 )
+ {
+ //calculate and set new position
+ Point aDialogPos = pViewShell->GetChartDialogPos( aDialogSize, aRect );
+ xDialogProps->setPropertyValue( ::rtl::OUString::createFromAscii("Position"),
+ uno::makeAny( awt::Point(aDialogPos.getX(),aDialogPos.getY()) ) );
+ }
+ }
+ //tell the dialog to unlock controller
+ xDialogProps->setPropertyValue( ::rtl::OUString::createFromAscii("UnlockControllersOnExecute"),
+ uno::makeAny( sal_True ) );
+
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ASSERT( "Chart wizard couldn't be positioned automatically\n" );
+ }
+ }
+
+ sal_Int16 nDialogRet = xDialog->execute();
+ if( nDialogRet == ui::dialogs::ExecutableDialogResults::CANCEL )
+ {
+ // leave OLE inplace mode and unmark
+ OSL_ASSERT( pViewShell );
+ OSL_ASSERT( pView );
+ pViewShell->DeactivateOle();
+ pView->UnmarkAll();
+
+ // old page view pointer is invalid after switching sheets
+ pPV = pView->GetSdrPageView();
+
+ // remove the chart
+ OSL_ASSERT( pPV );
+ SdrPage * pPage( pPV->GetPage());
+ OSL_ASSERT( pPage );
+ OSL_ASSERT( pObj );
+ if( pPage )
+ pPage->RemoveObject( pObj->GetOrdNum());
+
+ bAddUndo = false; // don't create the undo action for inserting
+
+ // leave the draw shell
+ pViewShell->SetDrawShell( FALSE );
+ }
+ else
+ {
+ OSL_ASSERT( nDialogRet == ui::dialogs::ExecutableDialogResults::OK );
+ //@todo maybe move chart to different table
+ }
+ }
+ uno::Reference< lang::XComponent > xComponent( xDialog, uno::UNO_QUERY );
+ if( xComponent.is())
+ xComponent->dispose();
+ }
+ }
+ }
+
+ if ( bAddUndo )
+ {
+ // add undo action the same way as in SdrEditView::InsertObjectAtView
+ // (using UndoActionHdl etc.)
+ pView->AddUndo(pDoc->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
+ }
+
+ // BM/IHA --
+ }
+}
+
+/*************************************************************************
+|*
+|* FuInsertChart::Destruktor
+|*
+\************************************************************************/
+
+FuInsertChart::~FuInsertChart()
+{
+}
+
+/*************************************************************************
+|*
+|* FuInsertChart::Function aktivieren
+|*
+\************************************************************************/
+
+void FuInsertChart::Activate()
+{
+ FuPoor::Activate();
+}
+
+/*************************************************************************
+|*
+|* FuInsertChart::Function deaktivieren
+|*
+\************************************************************************/
+
+void FuInsertChart::Deactivate()
+{
+ FuPoor::Deactivate();
+}
+
+
diff --git a/sc/source/ui/drawfunc/fumark.cxx b/sc/source/ui/drawfunc/fumark.cxx
new file mode 100644
index 000000000000..02554c495729
--- /dev/null
+++ b/sc/source/ui/drawfunc/fumark.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "fumark.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "scmod.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "drawview.hxx"
+
+//------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* Funktion zum Aufziehen eines Rechtecks
+|*
+\************************************************************************/
+
+FuMarkRect::FuMarkRect(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq) :
+ FuPoor(pViewSh, pWin, pViewP, pDoc, rReq),
+ bVisible(FALSE),
+ bStartDrag(FALSE)
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuMarkRect::~FuMarkRect()
+{
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL FuMarkRect::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ pWindow->CaptureMouse();
+ pView->UnmarkAll(); // der Einheitlichkeit halber und wegen #50558#
+ bStartDrag = TRUE;
+
+ aBeginPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
+ aZoomRect = Rectangle( aBeginPos, Size() );
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL FuMarkRect::MouseMove(const MouseEvent& rMEvt)
+{
+ if ( bStartDrag )
+ {
+ if ( bVisible )
+ pViewShell->DrawMarkRect(aZoomRect);
+ Point aPixPos= rMEvt.GetPosPixel();
+ ForceScroll(aPixPos);
+
+ Point aEndPos = pWindow->PixelToLogic(aPixPos);
+ Rectangle aRect(aBeginPos, aEndPos);
+ aZoomRect = aRect;
+ aZoomRect.Justify();
+ pViewShell->DrawMarkRect(aZoomRect);
+ bVisible = TRUE;
+ }
+
+ ForcePointer(&rMEvt);
+
+ return bStartDrag;
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL FuMarkRect::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ if ( bVisible )
+ {
+ // Hide ZoomRect
+ pViewShell->DrawMarkRect(aZoomRect);
+ bVisible = FALSE;
+ }
+
+ Size aZoomSizePixel = pWindow->LogicToPixel(aZoomRect).GetSize();
+
+ USHORT nMinMove = pView->GetMinMoveDistancePixel();
+ if ( aZoomSizePixel.Width() < nMinMove || aZoomSizePixel.Height() < nMinMove )
+ {
+ // Klick auf der Stelle
+
+ aZoomRect.SetSize(Size()); // dann ganz leer
+ }
+
+ bStartDrag = FALSE;
+ pWindow->ReleaseMouse();
+
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
+
+ // Daten an der View merken
+
+ pViewShell->SetChartArea( aSourceRange, aZoomRect );
+
+ // Chart-Dialog starten:
+
+// USHORT nId = ScChartDlgWrapper::GetChildWindowId();
+// SfxChildWindow* pWnd = pViewShell->GetViewFrame()->GetChildWindow( nId );
+// SC_MOD()->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* Command-event
+|*
+\************************************************************************/
+
+BYTE FuMarkRect::Command(const CommandEvent& rCEvt)
+{
+ if ( COMMAND_STARTDRAG == rCEvt.GetCommand() )
+ {
+ // #29877# nicht anfangen, auf der Tabelle rumzudraggen,
+ // aber Maus-Status nicht zuruecksetzen
+ return SC_CMD_IGNORE;
+ }
+ else
+ return FuPoor::Command(rCEvt);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL FuMarkRect::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FALSE;
+
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_ESCAPE:
+ // beenden
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ bReturn = TRUE;
+ break;
+ }
+
+ if (!bReturn)
+ {
+ bReturn = FuPoor::KeyInput(rKEvt);
+ }
+
+ return (bReturn);
+}
+
+/*************************************************************************
+|*
+|* Vor dem Scrollen Selektionsdarstellung ausblenden
+|*
+\************************************************************************/
+
+void FuMarkRect::ScrollStart()
+{
+}
+
+/*************************************************************************
+|*
+|* Nach dem Scrollen Selektionsdarstellung wieder anzeigen
+|*
+\************************************************************************/
+
+void FuMarkRect::ScrollEnd()
+{
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuMarkRect::Activate()
+{
+ FuPoor::Activate();
+
+ // Markierung merken, bevor evtl. Tabelle umgeschaltet wird
+
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ if ( !rMark.IsMultiMarked() && !rMark.IsMarked() )
+ pViewShell->MarkDataArea( TRUE );
+
+ pViewData->GetMultiArea( aSourceRange ); // Mehrfachselektion erlaubt
+
+// pViewShell->Unmark();
+
+ ForcePointer(NULL);
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuMarkRect::Deactivate()
+{
+ FuPoor::Deactivate();
+
+ if (bVisible)
+ {
+ // Hide ZoomRect
+ pViewShell->DrawMarkRect(aZoomRect);
+ bVisible = FALSE;
+ bStartDrag = FALSE;
+ }
+}
+
+/*************************************************************************
+|*
+|* Maus-Pointer umschalten
+|*
+\************************************************************************/
+
+void FuMarkRect::ForcePointer(const MouseEvent* /* pMEvt */)
+{
+ pViewShell->SetActivePointer( Pointer( POINTER_CHART ) );
+}
+
+
+
+
diff --git a/sc/source/ui/drawfunc/fupoor.cxx b/sc/source/ui/drawfunc/fupoor.cxx
new file mode 100644
index 000000000000..0bffdfe7ef84
--- /dev/null
+++ b/sc/source/ui/drawfunc/fupoor.cxx
@@ -0,0 +1,385 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/outliner.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+
+#include "fupoor.hxx"
+#include "tabvwsh.hxx"
+#include "drawview.hxx"
+#include "detfunc.hxx"
+#include "document.hxx"
+#include <vcl/svapp.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuPoor::FuPoor(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq) :
+ pView(pViewP),
+ pViewShell(pViewSh),
+ pWindow(pWin),
+ pDrDoc(pDoc),
+ aSfxRequest(rReq),
+ pDialog(NULL),
+ bIsInDragMode(FALSE),
+ // #95491# remember MouseButton state
+ mnCode(0)
+{
+ aScrollTimer.SetTimeoutHdl( LINK(this, FuPoor, ScrollHdl) );
+ aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
+
+ aDragTimer.SetTimeoutHdl( LINK(this, FuPoor, DragTimerHdl) );
+ aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuPoor::~FuPoor()
+{
+ aDragTimer.Stop();
+ aScrollTimer.Stop();
+
+ if (pDialog)
+ delete pDialog;
+}
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuPoor::Activate()
+{
+ if (pDialog)
+ {
+ pDialog->Show();
+ }
+}
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuPoor::Deactivate()
+{
+ aDragTimer.Stop();
+ aScrollTimer.Stop();
+
+ if (pDialog)
+ {
+ pDialog->Hide();
+ }
+}
+
+/*************************************************************************
+|*
+|* Scrollen bei Erreichen des Fensterrandes; wird von
+|* MouseMove aufgerufen
+|*
+\************************************************************************/
+
+void FuPoor::ForceScroll(const Point& aPixPos)
+{
+ aScrollTimer.Stop();
+
+ Size aSize = pWindow->GetSizePixel();
+ SCsCOL dx = 0;
+ SCsROW dy = 0;
+
+ if ( aPixPos.X() <= 0 ) dx = -1;
+ if ( aPixPos.X() >= aSize.Width() ) dx = 1;
+ if ( aPixPos.Y() <= 0 ) dy = -1;
+ if ( aPixPos.Y() >= aSize.Height() ) dy = 1;
+
+ ScViewData* pViewData = pViewShell->GetViewData();
+ if ( pViewData->GetDocument()->IsNegativePage( pViewData->GetTabNo() ) )
+ dx = -dx;
+
+ ScSplitPos eWhich = pViewData->GetActivePart();
+ if ( dx > 0 && pViewData->GetHSplitMode() == SC_SPLIT_FIX && WhichH(eWhich) == SC_SPLIT_LEFT )
+ {
+ pViewShell->ActivatePart( ( eWhich == SC_SPLIT_TOPLEFT ) ?
+ SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
+ dx = 0;
+ }
+ if ( dy > 0 && pViewData->GetVSplitMode() == SC_SPLIT_FIX && WhichV(eWhich) == SC_SPLIT_TOP )
+ {
+ pViewShell->ActivatePart( ( eWhich == SC_SPLIT_TOPLEFT ) ?
+ SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
+ dy = 0;
+ }
+
+ if ( dx != 0 || dy != 0 )
+ {
+ ScrollStart(); // Scrollaktion in abgeleiteter Klasse
+ pViewShell->ScrollLines(2*dx, 4*dy);
+ ScrollEnd();
+ aScrollTimer.Start();
+ }
+}
+
+/*************************************************************************
+|*
+|* Timer-Handler fuer Fensterscrolling
+|*
+\************************************************************************/
+
+IMPL_LINK_INLINE_START( FuPoor, ScrollHdl, Timer *, EMPTYARG )
+{
+ Point aPosPixel = pWindow->GetPointerPosPixel();
+
+ // #95491# use remembered MouseButton state to create correct
+ // MouseEvents for this artifical MouseMove.
+ MouseMove(MouseEvent(aPosPixel, 1, 0, GetMouseButtonCode()));
+
+ return 0;
+}
+IMPL_LINK_INLINE_END( FuPoor, ScrollHdl, Timer *, pTimer )
+
+// #95491# moved from inline to *.cxx
+BOOL FuPoor::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ return FALSE;
+}
+
+// #95491# moved from inline to *.cxx
+BOOL FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* String in Applikations-Statuszeile ausgeben
+|*
+\************************************************************************/
+
+// WriteStatus gibt's nicht mehr
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL FuPoor::KeyInput(const KeyEvent& /* rKEvt */)
+{
+ BOOL bReturn = FALSE;
+
+ return(bReturn);
+}
+
+BYTE FuPoor::Command(const CommandEvent& rCEvt)
+{
+ if ( COMMAND_STARTDRAG == rCEvt.GetCommand() )
+ {
+ //!!! sollte Joe eigentlich machen:
+ // nur, wenn im Outliner was selektiert ist, darf
+ // Command TRUE zurueckliefern:
+
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+
+ if ( pOutView )
+ return pOutView->HasSelection() ? pView->Command(rCEvt,pWindow) : SC_CMD_NONE;
+ else
+ return pView->Command(rCEvt,pWindow);
+ }
+ else
+ return pView->Command(rCEvt,pWindow);
+}
+
+/*************************************************************************
+|*
+|* Cut object to clipboard
+|*
+\************************************************************************/
+
+void FuPoor::DoCut()
+{
+ if (pView)
+ {
+//! pView->DoCut(pWindow);
+ }
+}
+
+/*************************************************************************
+|*
+|* Copy object to clipboard
+|*
+\************************************************************************/
+
+void FuPoor::DoCopy()
+{
+ if (pView)
+ {
+//! pView->DoCopy(pWindow);
+ }
+}
+
+/*************************************************************************
+|*
+|* Paste object from clipboard
+|*
+\************************************************************************/
+
+void FuPoor::DoPaste()
+{
+ if (pView)
+ {
+//! pView->DoPaste(pWindow);
+ }
+}
+
+/*************************************************************************
+|*
+|* Timer-Handler fuer Drag&Drop
+|*
+\************************************************************************/
+
+IMPL_LINK( FuPoor, DragTimerHdl, Timer *, EMPTYARG )
+{
+ // ExecuteDrag (und das damit verbundene Reschedule) direkt aus dem Timer
+ // aufzurufen, bringt die VCL-Timer-Verwaltung durcheinander, wenn dabei
+ // (z.B. im Drop) wieder ein Timer gestartet wird (z.B. ComeBack-Timer der
+ // DrawView fuer Solid Handles / ModelHasChanged) - der neue Timer laeuft
+ // dann um die Dauer des Drag&Drop zu spaet ab.
+ // Darum Drag&Drop aus eigenem Event:
+
+ Application::PostUserEvent( LINK( this, FuPoor, DragHdl ) );
+ return 0;
+}
+
+IMPL_LINK( FuPoor, DragHdl, void *, EMPTYARG )
+{
+ SdrHdl* pHdl = pView->PickHandle(aMDPos);
+
+ if ( pHdl==NULL && pView->IsMarkedHit(aMDPos) )
+ {
+ pWindow->ReleaseMouse();
+ bIsInDragMode = TRUE;
+
+// pView->BeginDrag(pWindow, aMDPos);
+ pViewShell->GetScDrawView()->BeginDrag(pWindow, aMDPos);
+ }
+ return 0;
+}
+
+// Detektiv-Linie
+
+BOOL FuPoor::IsDetectiveHit( const Point& rLogicPos )
+{
+ SdrPageView* pPV = pView->GetSdrPageView();
+ if (!pPV)
+ return FALSE;
+
+ BOOL bFound = FALSE;
+ SdrObjListIter aIter( *pPV->GetObjList(), IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
+ {
+ USHORT nHitLog = (USHORT) pWindow->PixelToLogic(
+ Size(pView->GetHitTolerancePixel(),0)).Width();
+ if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, 0, false))
+ {
+ bFound = TRUE;
+ }
+ }
+
+ pObject = aIter.Next();
+ }
+ return bFound;
+}
+
+void FuPoor::StopDragTimer()
+{
+ if (aDragTimer.IsActive() )
+ aDragTimer.Stop();
+}
+
+/*************************************************************************
+|*
+|* #98185# Create default drawing objects via keyboard
+|*
+\************************************************************************/
+
+SdrObject* FuPoor::CreateDefaultObject(const sal_uInt16 /* nID */, const Rectangle& /* rRectangle */)
+{
+ // empty base implementation
+ return 0L;
+}
+
+void FuPoor::ImpForceQuadratic(Rectangle& rRect)
+{
+ if(rRect.GetWidth() > rRect.GetHeight())
+ {
+ rRect = Rectangle(
+ Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
+ Size(rRect.GetHeight(), rRect.GetHeight()));
+ }
+ else
+ {
+ rRect = Rectangle(
+ Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
+ Size(rRect.GetWidth(), rRect.GetWidth()));
+ }
+}
+
+// #i33136#
+bool FuPoor::doConstructOrthogonal() const
+{
+ return false;
+}
+
+// eof
diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx
new file mode 100644
index 000000000000..4a456522003c
--- /dev/null
+++ b/sc/source/ui/drawfunc/fusel.cxx
@@ -0,0 +1,649 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/embed/EmbedStates.hpp>
+
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdotext.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svtools/imapobj.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdomedia.hxx>
+#include <svx/svdpagv.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/app.hxx>
+
+#include "fusel.hxx"
+#include "sc.hrc"
+#include "fudraw.hxx"
+#include "futext.hxx"
+#include "drawview.hxx"
+#include "tabvwsh.hxx"
+#include "drawpage.hxx"
+#include "globstr.hrc"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "scmod.hxx"
+
+// -----------------------------------------------------------------------
+
+// Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
+//! fusel,fuconstr,futext - zusammenfassen!
+#define SC_MAXDRAGMOVE 3
+
+// -----------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+using namespace com::sun::star;
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+FuSelection::FuSelection(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq ) :
+ FuDraw(pViewSh, pWin, pViewP, pDoc, rReq),
+ bVCAction(FALSE)
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuSelection::~FuSelection()
+{
+}
+
+BYTE FuSelection::Command(const CommandEvent& rCEvt)
+{
+ // special code for non-VCL OS2/UNX removed
+
+ return FuDraw::Command( rCEvt );
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+ const bool bSelectionOnly = rMEvt.IsRight();
+ if ( pView->IsAction() )
+ {
+ if ( bSelectionOnly )
+ pView->BckAction();
+ return TRUE;
+ }
+
+ bVCAction = FALSE;
+ bIsInDragMode = FALSE; // irgendwo muss es ja zurueckgesetzt werden (#50033#)
+
+ BOOL bReturn = FuDraw::MouseButtonDown(rMEvt);
+
+ aMDPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ SdrHdl* pHdl = pView->PickHandle(aMDPos);
+ SdrObject* pObj;
+ SdrPageView* pPV;
+
+ if ( pHdl!=NULL || pView->IsMarkedHit(aMDPos) )
+ {
+ // Determine if this is the tail of a SdrCaptionObj i.e.
+ // we need to disable the drag option on the tail of a note
+ // object. Also, disable the ability to use the circular
+ // drag of a note object.
+ bool bDrag = false;
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pMarkedObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( ScDrawLayer::IsNoteCaption( pMarkedObj ) )
+ {
+ // move using the valid caption handles for note text box.
+ if(pHdl && (pHdl->GetKind() != HDL_POLY && pHdl->GetKind() != HDL_CIRC))
+ bDrag = true;
+ // move the complete note box.
+ else if(!pHdl)
+ bDrag = true;
+ }
+ else
+ bDrag = true; // different object
+ }
+ else
+ bDrag = true; // several objects
+
+ if ( bDrag )
+ {
+ aDragTimer.Start();
+ pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl);
+ bReturn = TRUE;
+ }
+ }
+ else
+ {
+ BOOL bAlt = rMEvt.IsMod2();
+ if ( !bAlt && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
+ {
+ pView->BegMacroObj(aMDPos, pObj, pPV, pWindow);
+ bReturn = TRUE;
+ }
+ else
+ {
+ String sURL, sTarget;
+ if ( !bAlt && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER))
+ {
+ // Support for imported Excel docs
+ // Excel is of course not consistent and allows
+ // a hyperlink to be assigned for an object group
+ // and even though the hyperlink is exported in the Escher layer
+ // its never used, when dealing with a group object the link
+ // associated with the clicked object is used only
+
+ // additionally you can also select a macro in Excel for a grouped
+ // objects and this results in the macro being set for the elements
+ // in the group and no macro is exported for the group
+
+ // if a macro and hlink are defined favour the hlink
+
+ // If a group object has no hyperlink use the hyperlink of the
+ // object clicked
+
+ if ( pObj->IsGroupObject() )
+ {
+ SdrObject* pHit = NULL;
+ if ( pView->PickObj(aMDPos, pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
+ pObj = pHit;
+ }
+
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj, TRUE );
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ // For interoperability favour links over macros if both are defined
+ if ( pInfo->GetHlink().getLength() > 0 )
+ {
+ OSL_TRACE("** Got URL");
+ sURL = pInfo->GetHlink();
+ }
+ else if ( pInfo->GetMacro().getLength() > 0 )
+#else
+ if ( pInfo->GetMacro().getLength() > 0 )
+#endif
+ {
+ SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ if ( pObjSh && SfxApplication::IsXScriptURL( pInfo->GetMacro() ) )
+ {
+ uno::Any aRet;
+ uno::Sequence< sal_Int16 > aOutArgsIndex;
+ uno::Sequence< uno::Any > aOutArgs;
+ uno::Sequence< uno::Any >* pInArgs =
+ new uno::Sequence< uno::Any >(0);
+ pObjSh->CallXScript( pInfo->GetMacro(),
+ *pInArgs, aRet, aOutArgsIndex, aOutArgs);
+ pViewShell->FakeButtonUp( pViewShell->GetViewData()->GetActivePart() );
+ return TRUE; // kein CaptureMouse etc.
+ }
+ }
+ }
+
+ // URL / ImageMap
+
+ SdrViewEvent aVEvt;
+ if ( !bAlt &&
+ pView->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt ) != SDRHIT_NONE &&
+ aVEvt.pObj != NULL )
+ {
+ if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) ) // ImageMap
+ {
+ const IMapObject* pIMapObj =
+ ScDrawLayer::GetHitIMapObject( aVEvt.pObj, aMDPos, *pWindow );
+ if ( pIMapObj && pIMapObj->GetURL().Len() )
+ {
+ sURL = pIMapObj->GetURL();
+ sTarget = pIMapObj->GetTarget();
+ }
+ }
+ if ( aVEvt.eEvent == SDREVENT_EXECUTEURL && aVEvt.pURLField ) // URL
+ {
+ sURL = aVEvt.pURLField->GetURL();
+ sTarget = aVEvt.pURLField->GetTargetFrame();
+ }
+ }
+
+ // open hyperlink, if found at object or in object's text
+ if ( sURL.Len() > 0 )
+ {
+ ScGlobal::OpenURL( sURL, sTarget );
+ pViewShell->FakeButtonUp( pViewShell->GetViewData()->GetActivePart() );
+ return TRUE; // kein CaptureMouse etc.
+ }
+
+ // Is another object being edited in this view?
+ // (Editing is ended in MarkListHasChanged - test before UnmarkAll)
+ SfxInPlaceClient* pClient = pViewShell->GetIPClient();
+ BOOL bWasOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
+
+ // Markieren
+
+ // do not allow multiselection with note caption
+ bool bCaptionClicked = IsNoteCaptionClicked( aMDPos );
+ if ( !rMEvt.IsShift() || bCaptionClicked || IsNoteCaptionMarked() )
+ pView->UnmarkAll();
+
+ /* Unlock internal layer, if a note caption is clicked. The
+ layer will be relocked in ScDrawView::MarkListHasChanged(). */
+ if( bCaptionClicked )
+ pView->UnlockInternalLayer();
+
+ // try to select the clicked object
+ if ( pView->MarkObj( aMDPos, -2, FALSE, rMEvt.IsMod1() ) )
+ {
+ //*********************************************************
+ //Objekt verschieben
+ //********************************************************
+ if (pView->IsMarkedHit(aMDPos))
+ {
+ // #95834# Don't start drag timer if inplace editing of an OLE object
+ // was just ended with this mouse click - the view will be moved
+ // (different tool bars) and the object that was clicked on would
+ // be moved unintentionally.
+ if ( !bWasOleActive )
+ aDragTimer.Start();
+
+ pHdl=pView->PickHandle(aMDPos);
+ pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl);
+ bReturn = TRUE;
+ }
+ else // Objekt am Rand getroffen
+ if (pViewShell->IsDrawSelMode())
+ bReturn = TRUE;
+ }
+ else
+ {
+ // nichts getroffen
+
+ if (pViewShell->IsDrawSelMode())
+ {
+ //*********************************************************
+ //Objekt selektieren
+ //********************************************************
+ pView->BegMarkObj(aMDPos);
+ bReturn = TRUE;
+ }
+ }
+ }
+ }
+
+ }
+
+ if (!bIsInDragMode)
+ {
+ if (!bVCAction) // VC rufen selber CaptureMouse
+ pWindow->CaptureMouse();
+ ForcePointer(&rMEvt);
+ }
+
+ return bReturn;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuSelection::MouseMove(const MouseEvent& rMEvt)
+{
+ BOOL bReturn = FuDraw::MouseMove(rMEvt);
+
+ if (aDragTimer.IsActive() )
+ {
+ Point aOldPixel = pWindow->LogicToPixel( aMDPos );
+ Point aNewPixel = rMEvt.GetPosPixel();
+ if ( Abs( aOldPixel.X() - aNewPixel.X() ) > SC_MAXDRAGMOVE ||
+ Abs( aOldPixel.Y() - aNewPixel.Y() ) > SC_MAXDRAGMOVE )
+ aDragTimer.Stop();
+ }
+
+ if ( pView->IsAction() )
+ {
+ Point aPix(rMEvt.GetPosPixel());
+ Point aPnt(pWindow->PixelToLogic(aPix));
+
+ ForceScroll(aPix);
+ pView->MovAction(aPnt);
+ bReturn = TRUE;
+ }
+
+ // Ein VCControl ist aktiv
+ // Event an den Manager weiterleiten
+ if( bVCAction )
+ {
+ // GetSbxForm gibts nicht mehr - Basic-Controls sind tot
+ //SdrPageView* pPgView = pView->GetPageViewByIndex(0);
+ //ScDrawPage* pPage = (ScDrawPage*)pPgView->GetPage();
+ //VCSbxForm* pForm = (VCSbxForm*)(SbxObject*)(pPage->GetSbxForm());
+ //((VCManager*)(pForm->GetVCContainer()))->
+ // MouseMove( pWindow, rMEvt );
+ bReturn = TRUE;
+ }
+
+ ForcePointer(&rMEvt);
+
+ return (bReturn);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuSelection::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FuDraw::MouseButtonUp(rMEvt);
+// BOOL bOle = pViewShell->GetViewData()->IsOle();
+ BOOL bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace();
+
+ if (aDragTimer.IsActive() )
+ {
+ aDragTimer.Stop();
+ }
+
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ if ( rMEvt.IsLeft() )
+ {
+ if ( pView->IsDragObj() )
+ {
+ /******************************************************************
+ * Objekt wurde verschoben
+ ******************************************************************/
+ pView->EndDragObj( rMEvt.IsMod1() );
+ pView->ForceMarkedToAnotherPage();
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
+ FuText* pText = static_cast<FuText*>(pPoor);
+ pText->StopDragMode(pObj );
+ }
+ bReturn = TRUE;
+ }
+ else if (pView->IsAction() )
+ {
+ // unlock internal layer to include note captions
+ pView->UnlockInternalLayer();
+ pView->EndAction();
+ if ( pView->AreObjectsMarked() )
+ {
+ bReturn = TRUE;
+
+ /* if multi-selection contains a note caption object, remove
+ all other objects from selection. */
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ ULONG nCount = rMarkList.GetMarkCount();
+ if( nCount > 1 )
+ {
+ bool bFound = false;
+ for( ULONG nIdx = 0; !bFound && (nIdx < nCount); ++nIdx )
+ {
+ SdrObject* pObj = rMarkList.GetMark( nIdx )->GetMarkedSdrObj();
+ bFound = ScDrawLayer::IsNoteCaption( pObj );
+ if( bFound )
+ {
+ pView->UnMarkAll();
+ pView->MarkObj( pObj, pView->GetSdrPageView() );
+ }
+ }
+ }
+ }
+ }
+ }
+
+/*
+ if ( pView->IsObjEdit() )
+ {
+ BOOL bShowCursor = TRUE;
+//! pOutlinerView = pView->GetOutlinerView(pWindow, bShowCursor);
+ bReturn = TRUE;
+ }
+*/
+ /**************************************************************************
+ * Ggf. OLE-Objekt beruecksichtigen
+ **************************************************************************/
+ SfxInPlaceClient* pIPClient = pViewShell->GetIPClient();
+
+ if (pIPClient)
+ {
+ ScModule* pScMod = SC_MOD();
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ if ( pIPClient->IsObjectInPlaceActive() && !bUnoRefDialog )
+ pIPClient->DeactivateObject();
+ }
+
+ USHORT nClicks = rMEvt.GetClicks();
+ if ( nClicks == 2 && rMEvt.IsLeft() )
+ {
+ if ( pView->AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ // #43984# aktivieren nur, wenn die Maus auch (noch) ueber dem
+ // selektierten Objekt steht
+
+ SdrViewEvent aVEvt;
+ SdrHitKind eHit = pView->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
+ if ( eHit != SDRHIT_NONE && aVEvt.pObj == pObj )
+ {
+ UINT16 nSdrObjKind = pObj->GetObjIdentifier();
+
+ //
+ // OLE: aktivieren
+ //
+
+ if (nSdrObjKind == OBJ_OLE2)
+ {
+ if (!bOle)
+ {
+ if (((SdrOle2Obj*) pObj)->GetObjRef().is())
+ {
+ //HMHpView->HideMarkHdl();
+ pViewShell->ActivateObject( (SdrOle2Obj*) pObj, 0 );
+ }
+ }
+ }
+
+ //
+ // Edit text
+ // #49458# not in UNO controls
+ // #i32352# not in media objects
+ //
+ else if ( pObj->ISA(SdrTextObj) && !pObj->ISA(SdrUnoObj) && !pObj->ISA(SdrMediaObj) )
+ {
+ OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
+ BOOL bVertical = ( pOPO && pOPO->IsVertical() );
+ USHORT nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
+
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(nTextSlotId, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
+
+ // jetzt den erzeugten FuText holen und in den EditModus setzen
+ FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
+ if ( pPoor && pPoor->GetSlotID() == nTextSlotId ) // hat keine RTTI
+ {
+ FuText* pText = (FuText*)pPoor;
+ Point aMousePixel = rMEvt.GetPosPixel();
+ pText->SetInEditMode( pObj, &aMousePixel );
+ }
+ bReturn = TRUE;
+ }
+ }
+ }
+ }
+ else if ( TestDetective( pView->GetSdrPageView(), aPnt ) )
+ bReturn = TRUE;
+ }
+
+ // Ein VCControl ist aktiv
+ // Event an den Manager weiterleiten
+ if( bVCAction )
+ {
+ // GetSbxForm gibts nicht mehr - Basic-Controls sind tot
+ //SdrPageView* pPgView = pView->GetPageViewByIndex(0);
+ //ScDrawPage* pPage = (ScDrawPage*)pPgView->GetPage();
+ //VCSbxForm* pForm = (VCSbxForm*)(SbxObject*)(pPage->GetSbxForm());
+ //((VCManager*)(pForm->GetVCContainer()))->
+ // MouseButtonUp( pWindow, rMEvt );
+ //HMHpView->ShowMarkHdl();
+ bVCAction = FALSE;
+ bReturn = TRUE;
+ }
+
+ ForcePointer(&rMEvt);
+
+ pWindow->ReleaseMouse();
+
+ // Command-Handler fuer Kontext-Menue kommt erst nach MouseButtonUp,
+ // darum hier die harte IsLeft-Abfrage
+ if ( !bReturn && rMEvt.IsLeft() )
+ if (pViewShell->IsDrawSelMode())
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+
+ return (bReturn);
+}
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL FuSelection::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FALSE;
+
+ if (!bReturn)
+ {
+ bReturn = FuDraw::KeyInput(rKEvt);
+ }
+
+ return(bReturn);
+}
+
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuSelection::Activate()
+{
+/*
+ SdrDragMode eMode;
+ switch (aSfxRequest.GetSlot() )
+ {
+ case SID_OBJECT_SELECT:
+ eMode = SDRDRAG_MOVE;
+ break;
+ case SID_OBJECT_ROTATE:
+ eMode = SDRDRAG_ROTATE;
+ break;
+ case SID_OBJECT_MIRROR:
+ eMode = SDRDRAG_MIRROR;
+ break;
+ }
+ pView->SetDragMode(eMode);
+*/
+ FuDraw::Activate();
+}
+
+
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuSelection::Deactivate()
+{
+ /**************************************************************************
+ * Hide Cursor
+ **************************************************************************/
+// BOOL bShowCursor = FALSE;
+//! pOutlinerView = pView->GetOutlinerView(pWindow, bShowCursor);
+
+// pView->SetDragMode(SDRDRAG_MOVE);
+ FuDraw::Deactivate();
+}
+
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+
+
+
+
diff --git a/sc/source/ui/drawfunc/fusel2.cxx b/sc/source/ui/drawfunc/fusel2.cxx
new file mode 100644
index 000000000000..402143ac0a8c
--- /dev/null
+++ b/sc/source/ui/drawfunc/fusel2.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpagv.hxx>
+#include <sfx2/dispatch.hxx>
+#include <editeng/outliner.hxx>
+
+#include "fusel.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "detfunc.hxx"
+#include "futext.hxx"
+#include "sc.hrc"
+#include "attrib.hxx"
+#include "scitems.hxx"
+#include "userdat.hxx"
+#include "drwlayer.hxx"
+#include "docsh.hxx"
+#include "drawview.hxx"
+#include <svx/sdrhittesthelper.hxx>
+
+// -----------------------------------------------------------------------
+
+inline long Diff( const Point& rP1, const Point& rP2 )
+{
+ long nX = rP1.X() - rP2.X();
+ if (nX<0) nX = -nX;
+ long nY = rP1.Y() - rP2.Y();
+ if (nY<0) nY = -nY;
+ return nX+nY;
+}
+
+BOOL FuSelection::TestDetective( SdrPageView* pPV, const Point& rPos )
+{
+ if (!pPV)
+ return FALSE;
+
+ BOOL bFound = FALSE;
+ SdrObjListIter aIter( *pPV->GetObjList(), IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
+ {
+ USHORT nHitLog = (USHORT) pWindow->PixelToLogic(
+ Size(pView->GetHitTolerancePixel(),0)).Width();
+ if (SdrObjectPrimitiveHit(*pObject, rPos, nHitLog, *pPV, 0, false))
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScSplitPos ePos = pViewShell->FindWindow( pWindow );
+ Point aLineStart = pObject->GetPoint(0);
+ Point aLineEnd = pObject->GetPoint(1);
+ Point aPixel = pWindow->LogicToPixel( aLineStart );
+ SCsCOL nStartCol;
+ SCsROW nStartRow;
+ pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), ePos, nStartCol, nStartRow );
+ aPixel = pWindow->LogicToPixel( aLineEnd );
+ SCsCOL nEndCol;
+ SCsROW nEndRow;
+ pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), ePos, nEndCol, nEndRow );
+ SCsCOL nCurX = (SCsCOL) pViewData->GetCurX();
+ SCsROW nCurY = (SCsROW) pViewData->GetCurY();
+ BOOL bStart = ( Diff( rPos,aLineStart ) > Diff( rPos,aLineEnd ) );
+ if ( nCurX == nStartCol && nCurY == nStartRow )
+ bStart = FALSE;
+ else if ( nCurX == nEndCol && nCurY == nEndRow )
+ bStart = TRUE;
+
+ SCsCOL nDifX;
+ SCsROW nDifY;
+ if ( bStart )
+ {
+ nDifX = nStartCol - nCurX;
+ nDifY = nStartRow - nCurY;
+ }
+ else
+ {
+ nDifX = nEndCol - nCurX;
+ nDifY = nEndRow - nCurY;
+ }
+ pViewShell->MoveCursorRel( nDifX, nDifY, SC_FOLLOW_JUMP, FALSE );
+
+ bFound = TRUE;
+ }
+ }
+
+ pObject = aIter.Next();
+ }
+ return bFound;
+}
+
+bool FuSelection::IsNoteCaptionMarked() const
+{
+ if( pView )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ return ScDrawLayer::IsNoteCaption( pObj );
+ }
+ }
+ return false;
+}
+
+bool FuSelection::IsNoteCaptionClicked( const Point& rPos ) const
+{
+ SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
+ if( pPageView )
+ {
+ const ScViewData& rViewData = *pViewShell->GetViewData();
+ ScDocument& rDoc = *rViewData.GetDocument();
+ SCTAB nTab = rViewData.GetTabNo();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ bool bProtectDoc = rDoc.IsTabProtected( nTab ) || (pDocSh && pDocSh->IsReadOnly());
+
+ // search the last object (on top) in the object list
+ SdrObjListIter aIter( *pPageView->GetObjList(), IM_DEEPNOGROUPS, TRUE );
+ for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
+ {
+ if( pObj->GetLogicRect().IsInside( rPos ) )
+ {
+ if( const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab ) )
+ {
+ const ScAddress& rNotePos = pCaptData->maStart;
+ // skip caption objects of notes in protected cells
+ const ScProtectionAttr* pProtAttr = static_cast< const ScProtectionAttr* >( rDoc.GetAttr( rNotePos.Col(), rNotePos.Row(), nTab, ATTR_PROTECTION ) );
+ bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell();
+ if( !bProtectAttr || !bProtectDoc )
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void FuSelection::ActivateNoteHandles(SdrObject* pObject)
+{
+ if( pView && ScDrawLayer::IsNoteCaption( pObject ) )
+ {
+ // Leave the internal layer unlocked - relock in ScDrawView::MarkListHasChanged()
+ pView->UnlockInternalLayer();
+ pView->MarkObj( pObject, pView->GetSdrPageView() );
+ }
+}
+
+//==================================================================
+
+
+
+
diff --git a/sc/source/ui/drawfunc/futext.cxx b/sc/source/ui/drawfunc/futext.cxx
new file mode 100644
index 000000000000..a13cfc61d1c6
--- /dev/null
+++ b/sc/source/ui/drawfunc/futext.cxx
@@ -0,0 +1,882 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svddef.hxx>
+#include <svx/svdoutl.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/sdtaaitm.hxx>
+#include <svx/sdtacitm.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/unolingu.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/eeitem.hxx>
+#include <svl/itemset.hxx>
+
+#include "futext.hxx"
+#include "drwlayer.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "drawview.hxx"
+
+// #98185# Create default drawing objects via keyboard
+#include "scresid.hxx"
+
+// Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
+//! fusel,fuconstr,futext - zusammenfassen!
+#define SC_MAXDRAGMOVE 3
+
+//------------------------------------------------------------------
+
+void lcl_InvalidateAttribs( SfxBindings& rBindings )
+{
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+ rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_10 );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_15 );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_20 );
+ rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
+ rBindings.Invalidate( SID_SET_SUB_SCRIPT );
+ rBindings.Invalidate( SID_HYPERLINK_GETLINK );
+ rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
+ rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+}
+
+void lcl_UpdateHyphenator( Outliner& rOutliner, SdrObject* pObj )
+{
+ // use hyphenator only if hyphenation attribute is set
+ if ( pObj && ((const SfxBoolItem&)pObj->GetMergedItem(EE_PARA_HYPHENATE)).GetValue() ) {
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xHyphenator( LinguMgr::GetHyphenator() );
+ rOutliner.SetHyphenator( xHyphenator );
+ }
+}
+
+/*************************************************************************
+|*
+|* Basisklasse fuer Textfunktionen
+|*
+\************************************************************************/
+
+FuText::FuText(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
+ SdrModel* pDoc, SfxRequest& rReq) :
+ FuConstruct(pViewSh, pWin, pViewP, pDoc, rReq),
+ pTextObj(NULL)
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+FuText::~FuText()
+{
+// StopEditMode(); // in Deactivate !
+}
+
+/*************************************************************************
+|*
+|* MouseButtonDown-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuText::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ if ( pView->MouseButtonDown(rMEvt, pWindow) )
+ return (TRUE); // Event von der SdrView ausgewertet
+
+ if ( pView->IsTextEdit() )
+ {
+ if( !IsSizingOrMovingNote(rMEvt) )
+ StopEditMode(); // Danebengeklickt, Ende mit Edit
+ pView->SetCreateMode();
+ }
+
+ aMDPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ SdrHdl* pHdl = pView->PickHandle(aMDPos);
+
+ ULONG nHdlNum = pView->GetHdlNum(pHdl);
+
+ if (pHdl != NULL)
+ {
+ if (pView->HasMarkablePoints() && pView->IsPointMarkable(*pHdl))
+ {
+ BOOL bPointMarked=pView->IsPointMarked(*pHdl);
+
+ if ( rMEvt.IsShift() )
+ {
+ if (!bPointMarked)
+ {
+ pView->MarkPoint(*pHdl);
+ }
+ else
+ {
+ pView->UnmarkPoint(*pHdl);
+ }
+ }
+ else
+ {
+ if (!bPointMarked)
+ {
+ pView->UnmarkAllPoints();
+ pView->MarkPoint(*pHdl);
+ }
+ }
+ pHdl=pView->GetHdl(nHdlNum);
+ }
+ }
+
+ SdrObject* pObj;
+ SdrPageView* pPV;
+
+ if ( pHdl != NULL || pView->IsMarkedHit(aMDPos) )
+ {
+ if (pHdl == NULL &&
+// pView->TakeTextEditObject(aMDPos, pObj, pPV) )
+ pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKTEXTEDIT) )
+ {
+ SdrOutliner* pO = MakeOutliner();
+ lcl_UpdateHyphenator( *pO, pObj );
+
+ // vertical flag:
+ // deduced from slot ids only if text object has no content
+
+ USHORT nSlotID = aSfxRequest.GetSlot();
+ BOOL bVertical = ( nSlotID == SID_DRAW_TEXT_VERTICAL );
+ OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
+ if ( pOPO )
+ bVertical = pOPO->IsVertical(); // content wins
+ pO->SetVertical( bVertical );
+
+ //!?? ohne uebergebenen Outliner stimmen die Defaults nicht ???!?
+ if ( pView->SdrBeginTextEdit(pObj, pPV, pWindow, sal_True, pO) )
+ {
+ // EditEngine-UndoManager anmelden
+ pViewShell->SetDrawTextUndo( &pO->GetUndoManager() );
+
+ OutlinerView* pOLV = pView->GetTextEditOutlinerView();
+ if ( pOLV->MouseButtonDown(rMEvt) )
+ return (TRUE); // Event an den Outliner
+ }
+ }
+ else
+ {
+ // disable tail & circular move for caption objects.
+ bool bDrag = false;
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pMarkedObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( ScDrawLayer::IsNoteCaption( pMarkedObj ) )
+ {
+ if(pHdl->GetKind() != HDL_POLY && pHdl->GetKind() != HDL_CIRC)
+ bDrag = true;
+ }
+ else
+ bDrag = true; // different object
+ }
+ else
+ bDrag = true; // several objects
+
+ if ( bDrag )
+ {
+ aDragTimer.Start();
+ pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl);
+ }
+ }
+ }
+ else
+ {
+ BOOL bMacro = FALSE;
+
+// if (bMacro && pView->TakeMacroObject(aMDPos,pObj,pPV))
+ if (bMacro && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
+
+ {
+ pView->BegMacroObj(aMDPos,pObj,pPV,pWindow);
+ }
+ else
+ {
+ if (pView->IsEditMode())
+ {
+ BOOL bPointMode=pView->HasMarkablePoints();
+
+ if (!rMEvt.IsShift())
+ {
+ if (bPointMode)
+ {
+ pView->UnmarkAllPoints();
+ }
+ else
+ {
+ pView->UnmarkAll();
+ }
+
+ pView->SetDragMode(SDRDRAG_MOVE);
+ SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
+ rBindings.Invalidate( SID_OBJECT_ROTATE );
+ rBindings.Invalidate( SID_OBJECT_MIRROR );
+ pHdl=pView->GetHdl(nHdlNum);
+ }
+
+ if ( pView->MarkObj(aMDPos, -2, FALSE, rMEvt.IsMod1()) )
+ {
+ aDragTimer.Start();
+
+ pHdl=pView->PickHandle(aMDPos);
+
+ if (pHdl!=NULL)
+ {
+ pView->MarkPoint(*pHdl);
+ pHdl=pView->GetHdl(nHdlNum);
+ }
+
+ pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl);
+ }
+ else
+ {
+ if (bPointMode)
+ {
+ pView->BegMarkPoints(aMDPos);
+ }
+ else
+ {
+ pView->BegMarkObj(aMDPos);
+ }
+ }
+ }
+ else if (aSfxRequest.GetSlot() == SID_DRAW_NOTEEDIT )
+ {
+ // Notizen editieren -> keine neuen Textobjekte erzeugen,
+ // stattdessen Textmodus verlassen
+
+ pViewShell->GetViewData()->GetDispatcher().
+ Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ else
+ {
+ /**********************************************************
+ * Objekt erzeugen
+ **********************************************************/
+ pView->BegCreateObj(aMDPos, (OutputDevice*) NULL);
+ }
+ }
+ }
+ }
+
+
+ if (!bIsInDragMode)
+ {
+ pWindow->CaptureMouse();
+// ForcePointer(&rMEvt);
+ lcl_InvalidateAttribs( pViewShell->GetViewFrame()->GetBindings() );
+ }
+
+ pViewShell->SetActivePointer(pView->GetPreferedPointer(
+ pWindow->PixelToLogic(rMEvt.GetPosPixel()), pWindow ));
+
+// return (bReturn);
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* MouseMove-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuText::MouseMove(const MouseEvent& rMEvt)
+{
+ BOOL bReturn = FALSE;
+
+// pViewShell->SetActivePointer(aNewPointer);
+
+ pViewShell->SetActivePointer(pView->GetPreferedPointer(
+ pWindow->PixelToLogic(rMEvt.GetPosPixel()), pWindow ));
+
+ if (aDragTimer.IsActive() )
+ {
+ Point aOldPixel = pWindow->LogicToPixel( aMDPos );
+ Point aNewPixel = rMEvt.GetPosPixel();
+ if ( Abs( aOldPixel.X() - aNewPixel.X() ) > SC_MAXDRAGMOVE ||
+ Abs( aOldPixel.Y() - aNewPixel.Y() ) > SC_MAXDRAGMOVE )
+ aDragTimer.Stop();
+ }
+
+ if ( pView->MouseMove(rMEvt, pWindow) )
+ return (TRUE); // Event von der SdrView ausgewertet
+
+ if ( pView->IsAction() )
+ {
+/* aNewPointer = Pointer(POINTER_TEXT);
+ pViewShell->SetActivePointer(aNewPointer);
+*/
+ Point aPix(rMEvt.GetPosPixel());
+ Point aPnt(pWindow->PixelToLogic(aPix));
+
+ ForceScroll(aPix);
+ pView->MovAction(aPnt);
+ }
+
+// ForcePointer(&rMEvt);
+
+ return (bReturn);
+}
+
+/*************************************************************************
+|*
+|* MouseButtonUp-event
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuText::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode(rMEvt.GetButtons());
+
+ BOOL bReturn = FALSE;
+
+ if (aDragTimer.IsActive() )
+ {
+ aDragTimer.Stop();
+ }
+
+ lcl_InvalidateAttribs( pViewShell->GetViewFrame()->GetBindings() );
+
+ Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ if ( pView->MouseButtonUp(rMEvt, pWindow) )
+ return (TRUE); // Event von der SdrView ausgewertet
+
+ if ( pView->IsDragObj() )
+ {
+ pView->EndDragObj( rMEvt.IsShift() );
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
+ FuText* pText = static_cast<FuText*>(pPoor);
+ pText->StopDragMode(pObj );
+ }
+ pView->ForceMarkedToAnotherPage();
+ }
+ else if ( pView->IsCreateObj() )
+ {
+ if (rMEvt.IsLeft())
+ {
+ pView->EndCreateObj(SDRCREATE_FORCEEND);
+ if (aSfxRequest.GetSlot() == SID_DRAW_TEXT_MARQUEE)
+ {
+ // Lauftext-Objekt erzeugen?
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMark(0))
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ // die fuer das Scrollen benoetigten Attribute setzen
+ SfxItemSet aItemSet( pDrDoc->GetItemPool(),
+ SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST);
+
+ aItemSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ aItemSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
+ aItemSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) );
+ aItemSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) );
+ aItemSet.Put( SdrTextAniCountItem( 1 ) );
+ aItemSet.Put( SdrTextAniAmountItem(
+ (INT16)pWindow->PixelToLogic(Size(2,1)).Width()) );
+ pObj->SetMergedItemSetAndBroadcast(aItemSet);
+ }
+ }
+
+ // #93382# init object different when vertical writing
+ sal_uInt16 nSlotID(aSfxRequest.GetSlot());
+ BOOL bVertical = (SID_DRAW_TEXT_VERTICAL == nSlotID);
+ if(bVertical)
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if(rMarkList.GetMark(0))
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if(pObj && pObj->ISA(SdrTextObj))
+ {
+ SdrTextObj* pText = (SdrTextObj*)pObj;
+ SfxItemSet aSet(pDrDoc->GetItemPool());
+
+ pText->SetVerticalWriting(TRUE);
+
+ aSet.Put(SdrTextAutoGrowWidthItem(TRUE));
+ aSet.Put(SdrTextAutoGrowHeightItem(FALSE));
+ aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
+ aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
+
+ pText->SetMergedItemSet(aSet);
+ }
+ }
+ }
+
+ SetInEditMode();
+
+ // Modus verlassen bei einzelnem Klick
+ // (-> fuconstr)
+
+ if ( !pView->AreObjectsMarked() )
+ {
+ pView->MarkObj(aPnt, -2, FALSE, rMEvt.IsMod1());
+
+ SfxDispatcher& rDisp = pViewShell->GetViewData()->GetDispatcher();
+ if ( pView->AreObjectsMarked() )
+ rDisp.Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ else
+ rDisp.Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ }
+ }
+ else if ( pView->IsAction() )
+ {
+ pView->EndAction();
+ }
+ else if( !pView->IsAction() )
+ {
+ pWindow->ReleaseMouse();
+
+ if ( !pView->AreObjectsMarked() && rMEvt.GetClicks() < 2 )
+ {
+ pView->MarkObj(aPnt, -2, FALSE, rMEvt.IsMod1());
+
+ SfxDispatcher& rDisp = pViewShell->GetViewData()->GetDispatcher();
+ if ( pView->AreObjectsMarked() )
+ rDisp.Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ else
+ rDisp.Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+ }
+ }
+
+ return (bReturn);
+}
+
+/*************************************************************************
+|*
+|* Maus-Pointer umschalten
+|*
+\************************************************************************/
+
+void FuText::ForcePointer(const MouseEvent* /* pMEvt */)
+{
+ pViewShell->SetActivePointer( aNewPointer );
+
+/*
+ if ( !pView->IsAction() )
+ {
+ Point aPnt(pWindow->PixelToLogic( pWindow->ScreenToOutputPixel(
+ Pointer::GetPosPixel() ) ) );
+ SdrHdl* pHdl=pView->HitHandle(aPnt, *pWindow);
+
+ if (pHdl!=NULL)
+ {
+ pViewShell->SetActivePointer(pHdl->GetPointer() );
+ }
+ else
+ {
+ SdrObject* pObj;
+ SdrPageView* pPV;
+
+ if ( pView->IsMarkedHit(aPnt) )
+ {
+ if ( pView->TakeTextEditObject(aPnt, pObj, pPV) )
+ {
+ pViewShell->SetActivePointer(Pointer(POINTER_TEXT));
+ }
+ else
+ {
+ pViewShell->SetActivePointer(Pointer(POINTER_MOVE));
+ }
+ }
+ else
+ {
+// if ( pView->TakeMacroObject(aPnt, pObj, pPV) )
+ if ( pView->PickObj(aPnt, pObj, pPV, SDRSEARCH_PICKMACRO) )
+ {
+ pViewShell->SetActivePointer( pObj->GetMacroPointer() );
+ }
+ else
+ {
+ pViewShell->SetActivePointer( aNewPointer );
+ }
+ }
+ }
+ }
+*/
+}
+
+
+
+/*************************************************************************
+|*
+|* Tastaturereignisse bearbeiten
+|*
+|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
+|* FALSE.
+|*
+\************************************************************************/
+
+BOOL __EXPORT FuText::KeyInput(const KeyEvent& rKEvt)
+{
+ BOOL bReturn = FALSE;
+
+ if ( pView->KeyInput(rKEvt, pWindow) )
+ {
+ bReturn = TRUE;
+ lcl_InvalidateAttribs( pViewShell->GetViewFrame()->GetBindings() );
+ }
+ else
+ {
+ bReturn = FuDraw::KeyInput(rKEvt);
+ }
+
+ return (bReturn);
+}
+
+
+
+/*************************************************************************
+|*
+|* Function aktivieren
+|*
+\************************************************************************/
+
+void FuText::Activate()
+{
+ pView->SetDragMode(SDRDRAG_MOVE);
+ SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
+ rBindings.Invalidate( SID_OBJECT_ROTATE );
+ rBindings.Invalidate( SID_OBJECT_MIRROR );
+
+// Sofort in den Edit Mode setzen
+// SetInEditMode();
+
+// if (!pTextObj)
+ {
+ /**********************************************************************
+ * Kein Textobjekt im EditMode, daher CreateMode setzen
+ **********************************************************************/
+ USHORT nObj = OBJ_TEXT;
+
+/* UINT16 nIdent;
+ UINT32 nInvent;
+ pView->TakeCurrentObj(nIdent, nInvent);
+*/
+ pView->SetCurrentObj(nObj);
+
+ pView->SetCreateMode();
+ }
+
+ aNewPointer = Pointer(POINTER_TEXT);
+// aNewPointer = Pointer(POINTER_CROSS); //! ???
+
+ aOldPointer = pWindow->GetPointer();
+ pViewShell->SetActivePointer( aNewPointer );
+
+ FuConstruct::Activate();
+}
+
+
+/*************************************************************************
+|*
+|* Function deaktivieren
+|*
+\************************************************************************/
+
+void FuText::Deactivate()
+{
+ FuConstruct::Deactivate();
+ pViewShell->SetActivePointer( aOldPointer );
+ StopEditMode();
+}
+
+
+/*************************************************************************
+|*
+|* Selektion hat sich geaendert
+|*
+\************************************************************************/
+
+void FuText::SelectionHasChanged()
+{
+ pView->SetDragMode(SDRDRAG_MOVE);
+ SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
+ rBindings.Invalidate( SID_OBJECT_ROTATE );
+ rBindings.Invalidate( SID_OBJECT_MIRROR );
+
+ pTextObj = NULL;
+
+ if ( pView->AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ UINT16 nSdrObjKind = pObj->GetObjIdentifier();
+
+ if (nSdrObjKind == OBJ_TEXT ||
+ nSdrObjKind == OBJ_TITLETEXT ||
+ nSdrObjKind == OBJ_OUTLINETEXT /* ||
+ pObj->ISA(SdrTextObj) */ )
+ {
+ pTextObj = (SdrTextObj*) pObj;
+ }
+ }
+ }
+
+ if (!pTextObj)
+ {
+ /**********************************************************************
+ * Kein Textobjekt im EditMode, daher CreateMode setzen
+ **********************************************************************/
+ USHORT nObj = OBJ_TEXT;
+ UINT16 nIdent;
+ UINT32 nInvent;
+ pView->TakeCurrentObj(nIdent, nInvent);
+
+// if (! pView->IsEditMode() )
+// {
+// if (nIdent == OBJ_TEXT)
+// {
+// nObj = OBJ_TEXT;
+// }
+// else if (nIdent == OBJ_OUTLINETEXT)
+// {
+// nObj = OBJ_OUTLINETEXT;
+// }
+// else if (nIdent == OBJ_TITLETEXT)
+// {
+// nObj = OBJ_TITLETEXT;
+// }
+// }
+
+ pView->SetCurrentObj(nObj);
+
+ pView->SetCreateMode();
+ }
+}
+
+/*************************************************************************
+|*
+|* Objekt in Edit-Mode setzen
+|*
+\************************************************************************/
+
+void FuText::SetInEditMode(SdrObject* pObj, const Point* pMousePixel,
+ BOOL bCursorToEnd, const KeyEvent* pInitialKey)
+{
+ /* It is possible to pass a special (unselected) object in pObj, e.g. the
+ caption object of a cell note. If pObj is 0, then the selected object
+ is used. The layer will be relocked in FuText::StopEditMode(). */
+ if ( pObj && (pObj->GetLayer() == SC_LAYER_INTERN) )
+ pView->UnlockInternalLayer();
+
+ if ( !pObj && pView->AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ pObj = pMark->GetMarkedSdrObj();
+ }
+ }
+
+ pTextObj = NULL;
+
+ if ( pObj )
+ {
+ UINT16 nSdrObjKind = pObj->GetObjIdentifier();
+
+ if (nSdrObjKind == OBJ_TEXT ||
+ nSdrObjKind == OBJ_TITLETEXT ||
+ nSdrObjKind == OBJ_OUTLINETEXT ||
+ pObj->ISA(SdrTextObj))
+ {
+ SdrPageView* pPV = pView->GetSdrPageView();
+ Rectangle aRect = pObj->GetLogicRect();
+ Point aPnt = aRect.Center();
+
+ if ( pObj->HasTextEdit() )
+ {
+ SdrOutliner* pO = MakeOutliner();
+ lcl_UpdateHyphenator( *pO, pObj );
+
+ // vertical flag:
+ // deduced from slot ids only if text object has no content
+
+ USHORT nSlotID = aSfxRequest.GetSlot();
+ BOOL bVertical = ( nSlotID == SID_DRAW_TEXT_VERTICAL );
+ OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
+ if ( pOPO )
+ bVertical = pOPO->IsVertical(); // content wins
+ pO->SetVertical( bVertical );
+
+ //!?? ohne uebergebenen Outliner stimmen die Defaults nicht ???!?
+ if ( pView->SdrBeginTextEdit(pObj, pPV, pWindow, sal_True, pO) )
+ {
+ // EditEngine-UndoManager anmelden
+ pViewShell->SetDrawTextUndo( &pO->GetUndoManager() );
+
+ pTextObj = (SdrTextObj*) pObj;
+ pView->SetEditMode();
+
+ // set text cursor to click position or to end,
+ // pass initial key event to outliner view
+ if ( pMousePixel || bCursorToEnd || pInitialKey )
+ {
+ OutlinerView* pOLV = pView->GetTextEditOutlinerView();
+ if (pOLV)
+ {
+ if ( pMousePixel )
+ {
+ MouseEvent aEditEvt( *pMousePixel, 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
+ pOLV->MouseButtonDown(aEditEvt);
+ pOLV->MouseButtonUp(aEditEvt);
+ }
+ else if ( bCursorToEnd )
+ {
+ ESelection aNewSelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
+ pOLV->SetSelection(aNewSelection);
+ }
+
+ if ( pInitialKey )
+ pOLV->PostKeyEvent( *pInitialKey );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// #98185# Create default drawing objects via keyboard
+SdrObject* FuText::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
+{
+ // case SID_DRAW_TEXT:
+ // case SID_DRAW_TEXT_VERTICAL:
+ // case SID_DRAW_TEXT_MARQUEE:
+ // case SID_DRAW_NOTEEDIT:
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
+ 0L, pDrDoc);
+
+ if(pObj)
+ {
+ if(pObj->ISA(SdrTextObj))
+ {
+ SdrTextObj* pText = (SdrTextObj*)pObj;
+ pText->SetLogicRect(rRectangle);
+
+ // #105815# don't set default text, start edit mode instead
+ // String aText(ScResId(STR_CAPTION_DEFAULT_TEXT));
+ // pText->SetText(aText);
+
+ sal_Bool bVertical = (SID_DRAW_TEXT_VERTICAL == nID);
+ sal_Bool bMarquee = (SID_DRAW_TEXT_MARQUEE == nID);
+
+ pText->SetVerticalWriting(bVertical);
+
+ if(bVertical)
+ {
+ SfxItemSet aSet(pDrDoc->GetItemPool());
+
+ aSet.Put(SdrTextAutoGrowWidthItem(TRUE));
+ aSet.Put(SdrTextAutoGrowHeightItem(FALSE));
+ aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
+ aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
+
+ pText->SetMergedItemSet(aSet);
+ }
+
+ if(bMarquee)
+ {
+ SfxItemSet aSet(pDrDoc->GetItemPool(), SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST);
+
+ aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
+ aSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) );
+ aSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) );
+ aSet.Put( SdrTextAniCountItem( 1 ) );
+ aSet.Put( SdrTextAniAmountItem( (INT16)pWindow->PixelToLogic(Size(2,1)).Width()) );
+
+ pObj->SetMergedItemSetAndBroadcast(aSet);
+ }
+
+ SetInEditMode( pObj ); // #105815# start edit mode
+ }
+ else
+ {
+ DBG_ERROR("Object is NO text object");
+ }
+ }
+
+ return pObj;
+}
+
diff --git a/sc/source/ui/drawfunc/futext2.cxx b/sc/source/ui/drawfunc/futext2.cxx
new file mode 100644
index 000000000000..340e71faa71c
--- /dev/null
+++ b/sc/source/ui/drawfunc/futext2.cxx
@@ -0,0 +1,307 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+// TOOLS
+#define _BIGINT_HXX
+#define _SFXMULTISEL_HXX
+#define _STACK_HXX
+#define _QUEUE_HXX
+#define _DYNARR_HXX
+#define _TREELIST_HXX
+#define _CACHESTR_HXX
+#define _NEW_HXX
+//#define _SHL_HXX
+//#define _LINK_HXX
+//#define _ERRCODE_HXX
+//#define _GEN_HXX
+//#define _FRACT_HXX
+//#define _STRING_HXX
+//#define _MTF_HXX
+//#define _CONTNR_HXX
+//#define _LIST_HXX
+//#define _TABLE_HXX
+#define _DYNARY_HXX
+//#define _UNQIDX_HXX
+#define _SVMEMPOOL_HXX
+//#define _UNQID_HXX
+//#define _DEBUG_HXX
+//#define _DATE_HXX
+//#define _TIME_HXX
+//#define _DATETIME_HXX
+//#define _INTN_HXX
+//#define _WLDCRD_HXX
+//#define _FSYS_HXX
+//#define _STREAM_HXX
+#define _CACHESTR_HXX
+#define _SV_MULTISEL_HXX
+
+//SV
+//#define _CLIP_HXX ***
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _FONTDLG_HXX
+#define _PRVWIN_HXX
+//#define _COLOR_HXX
+//#define _PAL_HXX
+//#define _BITMAP_HXX
+//#define _GDIOBJ_HXX
+//#define _POINTR_HXX
+//#define _ICON_HXX
+//#define _IMAGE_HXX
+//#define _KEYCOD_HXX
+//#define _EVENT_HXX
+#define _HELP_HXX
+//#define _APP_HXX
+//#define _MDIAPP_HXX
+//#define _TIMER_HXX
+//#define _METRIC_HXX
+//#define _REGION_HXX
+//#define _OUTDEV_HXX
+//#define _SYSTEM_HXX
+//#define _VIRDEV_HXX
+//#define _JOBSET_HXX
+//#define _PRINT_HXX
+//#define _WINDOW_HXX
+//#define _SYSWIN_HXX
+//#define _WRKWIN_HXX
+#define _MDIWIN_HXX
+//#define _FLOATWIN_HXX
+//#define _DOCKWIN_HXX
+//#define _CTRL_HXX
+//#define _SCRBAR_HXX
+//#define _BUTTON_HXX
+//#define _IMAGEBTN_HXX
+//#define _FIXED_HXX
+//#define _GROUP_HXX
+//#define _EDIT_HXX
+//#define _COMBOBOX_HXX
+//#define _LSTBOX_HXX
+//#define _SELENG_HXX ***
+//#define _SPLIT_HXX
+#define _SPIN_HXX
+//#define _FIELD_HXX
+//#define _MOREBTN_HXX ***
+//#define _TOOLBOX_HXX
+#define _STATUS_HXX
+#define _SVTCTRL3_HXX
+//#define _DIALOG_HXX
+//#define _MSGBOX_HXX
+//#define _SYSDLG_HXX
+//#define _FILDLG_HXX ***
+//#define _PRNDLG_HXX
+#define _COLDLG_HXX
+//#define _TABDLG_HXX
+//#define _MENU_HXX ***
+//#define _GDIMTF_HXX
+//#define _POLY_HXX
+//#define _ACCEL_HXX
+//#define _GRAPH_HXX
+#define _SOUND_HXX
+
+#if defined WIN
+#define _MENUBTN_HXX
+#endif
+
+//svtools
+#define _SCRWIN_HXX
+#define _RULER_HXX
+//#define _TABBAR_HXX
+//#define _VALUESET_HXX
+#define _STDMENU_HXX
+//#define _STDCTRL_HXX
+//#define _CTRLBOX_HXX
+#define _CTRLTOOL_HXX
+#define _EXTATTR_HXX
+#define _FRM3D_HXX
+#define _EXTATTR_HXX
+
+//SVTOOLS
+//#define _SVTREELIST_HXX
+#define _FILTER_HXX
+//#define _SVLBOXITM_HXX
+//#define _SVTREEBOX_HXX
+#define _SVICNVW_HXX
+#define _SVTABBX_HXX
+
+//sfxcore.hxx
+//#define _SFXINIMGR_HXX
+//#define _SFXCFGITEM_HXX
+//#define _SFX_PRINTER_HXX
+#define _SFXGENLINK_HXX
+#define _SFXHINTPOST_HXX
+#define _SFXDOCINF_HXX
+#define _SFXLINKHDL_HXX
+//#define _SFX_PROGRESS_HXX
+
+//sfxsh.hxx
+//#define _SFX_SHELL_HXX
+//#define _SFXAPP_HXX
+//#define _SFXDISPATCH_HXX
+//#define _SFXMSG_HXX
+//#define _SFXOBJFACE_HXX
+//#define _SFXREQUEST_HXX
+#define _SFXMACRO_HXX
+
+// SFX
+//#define _SFXAPPWIN_HXX
+#define _SFX_SAVEOPT_HXX
+//#define _SFX_CHILDWIN_HXX
+//#define _SFXCTRLITEM_HXX
+#define _SFXPRNMON_HXX
+#define _INTRO_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXFILEDLG_HXX
+#define _PASSWD_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXSTBMGR_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXEVENT_HXX
+
+//sfxdoc.hxx
+//#define _SFX_OBJSH_HXX
+//#define _SFX_CLIENTSH_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFX_OBJFAC_HXX
+#define _SFX_DOCFILT_HXX
+//#define _SFXDOCFILE_HXX
+//define _VIEWFAC_HXX
+//#define _SFXVIEWFRM_HXX
+//#define _SFXVIEWSH_HXX
+//#define _MDIFRM_HXX
+#define _SFX_IPFRM_HXX
+//#define _SFX_INTERNO_HXX
+
+//sfxdlg.hxx
+//#define _SFXTABDLG_HXX
+//#define _BASEDLGS_HXX
+#define _SFX_DINFDLG_HXX
+#define _SFXDINFEDT_HXX
+#define _SFX_MGETEMPL_HXX
+#define _SFX_TPLPITEM_HXX
+//#define _SFX_STYLEDLG_HXX
+#define _NEWSTYLE_HXX
+//#define _SFXDOCTEMPL_HXX
+//#define _SFXDOCTDLG_HXX
+//#define _SFX_TEMPLDLG_HXX
+//#define _SFXNEW_HXX
+#define _SFXDOCMAN_HXX
+//#define _SFXDOCKWIN_HXX **
+
+//sfxitems.hxx
+#define _SFX_WHMAP_HXX
+//#define _ARGS_HXX ***
+//#define _SFXPOOLITEM_HXX
+//#define _SFXINTITEM_HXX
+//#define _SFXENUMITEM_HXX
+#define _SFXFLAGITEM_HXX
+//#define _SFXSTRITEM_HXX
+#define _SFXPTITEM_HXX
+#define _SFXRECTITEM_HXX
+//#define _SFXITEMPOOL_HXX
+//#define _SFXITEMSET_HXX
+#define _SFXITEMITER_HXX
+#define _SFX_WHITER_HXX
+#define _SFXPOOLCACH_HXX
+//#define _AEITEM_HXX
+#define _SFXRNGITEM_HXX
+//#define _SFXSLSTITM_HXX
+//#define _SFXSTYLE_HXX
+
+//xout.hxx
+//#define _XENUM_HXX
+//#define _XPOLY_HXX
+//#define _XATTR_HXX
+//#define _XOUTX_HXX
+//#define _XPOOL_HXX
+//#define _XTABLE_HXX
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+//#define _SDR_NOOBJECTS
+//#define _SDR_NOVIEWS
+
+//#define SI_NOITEMS
+//#define SI_NODRW
+#define _SI_NOSBXCONTROLS
+#define _VCATTR_HXX
+#define _VCONT_HXX
+//#define _VCSBX_HXX ***
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+//#define _VCDRWOBJ_HXX ***
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+#define _SIDLL_HXX
+
+//------------------------------------------------------------------------
+
+#include <svx/svdmodel.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdetc.hxx>
+
+#include "futext.hxx"
+#include "tabvwsh.hxx"
+
+//------------------------------------------------------------------------
+
+SdrOutliner* FuText::MakeOutliner()
+{
+ ScViewData* pViewData = pViewShell->GetViewData();
+ SdrOutliner* pOutl = SdrMakeOutliner(OUTLINERMODE_OUTLINEOBJECT, pDrDoc);
+
+ pViewData->UpdateOutlinerFlags(*pOutl);
+
+ // Die EditEngine benutzt beim RTF Export (Clipboard / Drag&Drop)
+ // den MapMode des RefDevices, um die Fontgroesse zu setzen
+
+ // #i10426# The ref device isn't set to the EditEngine before SdrBeginTextEdit now,
+ // so the device must be taken from the model here.
+ OutputDevice* pRef = pDrDoc->GetRefDevice();
+ if (pRef && pRef != pWindow)
+ pRef->SetMapMode( MapMode(MAP_100TH_MM) );
+
+ return pOutl;
+}
+
+
+
diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx
new file mode 100644
index 000000000000..534e68705fa8
--- /dev/null
+++ b/sc/source/ui/drawfunc/futext3.cxx
@@ -0,0 +1,249 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/editeng.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdview.hxx>
+#include <editeng/editobj.hxx>
+#include <vcl/cursor.hxx>
+#include <sfx2/objsh.hxx>
+#include <editeng/writingmodeitem.hxx>
+
+#include "global.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "tabvwsh.hxx" // oder GetDocument irgendwo
+#include "document.hxx"
+#include "editutil.hxx"
+#include "futext.hxx"
+#include "docsh.hxx"
+#include "postit.hxx"
+#include "globstr.hrc"
+#include "attrib.hxx"
+#include "scitems.hxx"
+#include "drawview.hxx"
+#include "undocell.hxx"
+
+// ------------------------------------------------------------------------------------
+// Editieren von Notiz-Legendenobjekten muss immer ueber StopEditMode beendet werden,
+// damit die Aenderungen ins Dokument uebernommen werden!
+// (Fontwork-Execute in drawsh und drtxtob passiert nicht fuer Legendenobjekte)
+// bTextDirection=TRUE means that this function is called from SID_TEXTDIRECTION_XXX(drtxtob.cxx).
+// ------------------------------------------------------------------------------------
+
+void FuText::StopEditMode(BOOL /*bTextDirection*/)
+{
+ SdrObject* pObject = pView->GetTextEditObject();
+ if( !pObject ) return;
+
+ // relock the internal layer that has been unlocked in FuText::SetInEditMode()
+ if ( pObject->GetLayer() == SC_LAYER_INTERN )
+ pView->LockInternalLayer();
+
+ ScViewData& rViewData = *pViewShell->GetViewData();
+ ScDocument& rDoc = *rViewData.GetDocument();
+ ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+ DBG_ASSERT( pDrawLayer && (pDrawLayer == pDrDoc), "FuText::StopEditMode - missing or different drawing layers" );
+
+ ScAddress aNotePos;
+ ScPostIt* pNote = 0;
+ if( const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, rViewData.GetTabNo() ) )
+ {
+ aNotePos = pCaptData->maStart;
+ pNote = rDoc.GetNote( aNotePos );
+ DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "FuText::StopEditMode - missing or invalid cell note" );
+ }
+
+ ScDocShell* pDocShell = rViewData.GetDocShell();
+ SfxUndoManager* pUndoMgr = rDoc.IsUndoEnabled() ? pDocShell->GetUndoManager() : 0;
+ bool bNewNote = false;
+ if( pNote && pUndoMgr )
+ {
+ /* Put all undo actions already collected (e.g. create caption object)
+ and all following undo actions (text changed) together into a ListAction. */
+ String aUndoStr = ScGlobal::GetRscString( STR_UNDO_EDITNOTE );
+ pUndoMgr->EnterListAction( aUndoStr, aUndoStr );
+ if( SdrUndoGroup* pCalcUndo = pDrawLayer->GetCalcUndo() )
+ {
+ /* Note has been created before editing, if first undo action is
+ an insert action. Needed below to decide whether to drop the
+ undo if editing a new note has been cancelled. */
+ bNewNote = (pCalcUndo->GetActionCount() > 0) && pCalcUndo->GetAction( 0 )->ISA( SdrUndoNewObj );
+ // create a "insert note" undo action if needed
+ if( bNewNote )
+ pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, pNote->GetNoteData(), true, pCalcUndo ) );
+ else
+ pUndoMgr->AddUndoAction( pCalcUndo );
+ }
+ }
+
+ if( pNote )
+ rDoc.LockStreamValid(true); // only the affected sheet is invalidated below
+
+ /* SdrObjEditView::SdrEndTextEdit() may try to delete the entire drawing
+ object, if it does not contain text and has invisible border and fill.
+ This must not happen for note caption objects. They will be removed
+ below together with the cell note if the text is empty (independent of
+ border and area formatting). It is possible to prevent automatic
+ deletion by passing sal_True to this function. The return value changes
+ from SDRENDTEXTEDIT_DELETED to SDRENDTEXTEDIT_SHOULDBEDELETED in this
+ case. */
+ /*SdrEndTextEditKind eResult =*/ pView->SdrEndTextEdit( pNote != 0 );
+
+ // or ScEndTextEdit (with drawview.hxx)
+ pViewShell->SetDrawTextUndo( 0 );
+
+ Cursor* pCur = pWindow->GetCursor();
+ if( pCur && pCur->IsVisible() )
+ pCur->Hide();
+
+ if( pNote )
+ {
+ // hide the caption object if it is in hidden state
+ pNote->ShowCaptionTemp( aNotePos, false );
+
+ // update author and date
+ pNote->AutoStamp();
+
+ /* If the entire text has been cleared, the cell note and its caption
+ object have to be removed. */
+ SdrTextObj* pTextObject = dynamic_cast< SdrTextObj* >( pObject );
+ bool bDeleteNote = !pTextObject || !pTextObject->HasText();
+ if( bDeleteNote )
+ {
+ if( pUndoMgr )
+ {
+ // collect the "remove object" drawing undo action created by DeleteNote()
+ pDrawLayer->BeginCalcUndo();
+ // rescue note data before deletion
+ ScNoteData aNoteData( pNote->GetNoteData() );
+ // delete note from document (removes caption, but does not delete it)
+ rDoc.DeleteNote( aNotePos );
+ // create undo action for removed note
+ pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
+ }
+ else
+ {
+ rDoc.DeleteNote( aNotePos );
+ }
+ // ScDocument::DeleteNote has deleted the note that pNote points to
+ pNote = 0;
+ }
+
+ // finalize the undo list action
+ if( pUndoMgr )
+ {
+ pUndoMgr->LeaveListAction();
+
+ /* #i94039# Update the default name "Edit Note" of the undo action
+ if the note has been created before editing or is deleted due
+ to deleted text. If the note has been created *and* is deleted,
+ the last undo action can be removed completely. Note: The
+ function LeaveListAction() removes the last action by itself,
+ if it is empty (when result is SDRENDTEXTEDIT_UNCHANGED). */
+ if( bNewNote && bDeleteNote )
+ {
+ pUndoMgr->RemoveLastUndoAction();
+ }
+ else if( bNewNote || bDeleteNote )
+ {
+ SfxListUndoAction* pAction = dynamic_cast< SfxListUndoAction* >( pUndoMgr->GetUndoAction() );
+ DBG_ASSERT( pAction, "FuText::StopEditMode - list undo action expected" );
+ if( pAction )
+ pAction->SetComment( ScGlobal::GetRscString( bNewNote ? STR_UNDO_INSERTNOTE : STR_UNDO_DELETENOTE ) );
+ }
+ }
+
+ // invalidate stream positions only for the affected sheet
+ rDoc.LockStreamValid(false);
+ if (rDoc.IsStreamValid(aNotePos.Tab()))
+ rDoc.SetStreamValid(aNotePos.Tab(), FALSE);
+ }
+}
+
+// Called following an EndDragObj() to update the new note rectangle position
+void FuText::StopDragMode(SdrObject* /*pObject*/)
+{
+#if 0 // DR
+ ScViewData& rViewData = *pViewShell->GetViewData();
+ if( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, rViewData.GetTabNo() ) )
+ {
+ ScDocument& rDoc = *rViewData.GetDocument();
+ const ScAddress& rPos = pData->maStart;
+ ScPostIt* pNote = rDoc.GetNote( rPos );
+ DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "FuText::StopDragMode - missing or invalid cell note" );
+ if( pNote )
+ {
+ Rectangle aOldRect = pNote->CalcRectangle( rDoc, rPos );
+ Rectangle aNewRect = pObject->GetLogicRect();
+ if( aOldRect != aNewRect )
+ {
+ pNote->UpdateFromRectangle( rDoc, rPos, aNewRect );
+ OutlinerParaObject* pPObj = pCaption->GetOutlinerParaObject();
+ bool bVertical = (pPObj && pPObj->IsVertical());
+ // The new height/width is honoured if property item is reset.
+ if(!bVertical && aNewRect.Bottom() - aNewRect.Top() > aOldRect.Bottom() - aOldRect.Top())
+ {
+ if(pCaption->IsAutoGrowHeight() && !bVertical)
+ {
+ pCaption->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
+ aNote.SetItemSet( *pDoc, pCaption->GetMergedItemSet() );
+ }
+ }
+ else if(bVertical && aNewRect.Right() - aNewRect.Left() > aOldRect.Right() - aOldRect.Left())
+ {
+ if(pCaption->IsAutoGrowWidth() && bVertical)
+ {
+ pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( false ) );
+ aNote.SetItemSet( *pDoc, pCaption->GetMergedItemSet() );
+ }
+ }
+ pViewShell->SetNote( aTabPos.Col(), aTabPos.Row(), aTabPos.Tab(), aNote );
+
+ // This repaint should not be necessary but it cleans
+ // up the 'marks' left behind by the note handles
+ // now that notes can simultaineously have handles and edit active.
+ ScRange aDrawRange = rDoc.GetRange( rPos.Tab(), aOldRect );
+ // Set Start/End Row to previous/next row to allow for handles.
+ if( aDrawRange.aStart.Row() > 0 )
+ aDrawRange.aStart.IncRow( -1 );
+ if( aDrawRange.aEnd.Row() < MAXROW )
+ aDrawRange.aEnd.IncRow( 1 );
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ pDocSh->PostPaint( aDrawRange, PAINT_GRID| PAINT_EXTRAS);
+ }
+ }
+ }
+#endif
+}
+
diff --git a/sc/source/ui/drawfunc/graphsh.cxx b/sc/source/ui/drawfunc/graphsh.cxx
new file mode 100644
index 000000000000..25cda28aaa9d
--- /dev/null
+++ b/sc/source/ui/drawfunc/graphsh.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/grfflt.hxx>
+#include <svx/grafctrl.hxx>
+
+#include "graphsh.hxx"
+#include "sc.hrc"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "scresid.hxx"
+
+#define ScGraphicShell
+#include "scslots.hxx"
+
+#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
+
+
+SFX_IMPL_INTERFACE(ScGraphicShell, ScDrawShell, ScResId(SCSTR_GRAPHICSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
+ ScResId(RID_GRAPHIC_OBJECTBAR) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_GRAPHIC) );
+}
+
+TYPEINIT1( ScGraphicShell, ScDrawShell );
+
+ScGraphicShell::ScGraphicShell(ScViewData* pData) :
+ ScDrawShell(pData)
+{
+ SetHelpId(HID_SCSHELL_GRAPHIC);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GraphicObject")));
+}
+
+ScGraphicShell::~ScGraphicShell()
+{
+}
+
+void ScGraphicShell::GetAttrState( SfxItemSet& rSet )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+
+ if( pView )
+ SvxGrafAttrHelper::GetGrafAttrState( rSet, *pView );
+}
+
+void ScGraphicShell::Execute( SfxRequest& rReq )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+
+ if( pView )
+ {
+ SvxGrafAttrHelper::ExecuteGrafAttr( rReq, *pView );
+ Invalidate();
+ }
+}
+
+void ScGraphicShell::GetFilterState( SfxItemSet& rSet )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ BOOL bEnable = FALSE;
+
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+
+ if( pObj && pObj->ISA( SdrGrafObj ) && ( ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP ) )
+ bEnable = TRUE;
+ }
+
+ if( !bEnable )
+ SvxGraphicFilter::DisableGraphicFilterSlots( rSet );
+}
+
+void ScGraphicShell::ExecuteFilter( SfxRequest& rReq )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+
+ if( pObj && pObj->ISA( SdrGrafObj ) && ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP )
+ {
+ GraphicObject aFilterObj( ( (SdrGrafObj*) pObj )->GetGraphicObject() );
+
+ if( SVX_GRAPHICFILTER_ERRCODE_NONE ==
+ SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj ) )
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if( pPageView )
+ {
+ SdrGrafObj* pFilteredObj = (SdrGrafObj*) pObj->Clone();
+ String aStr( pView->GetDescriptionOfMarkedObjects() );
+
+ aStr.Append( sal_Unicode(' ') );
+ aStr.Append( String( ScResId( SCSTR_UNDO_GRAFFILTER ) ) );
+ pView->BegUndo( aStr );
+ pFilteredObj->SetGraphicObject( aFilterObj );
+ pView->ReplaceObjectAtView( pObj, *pPageView, pFilteredObj );
+ pView->EndUndo();
+ }
+ }
+ }
+ }
+
+ Invalidate();
+}
+
diff --git a/sc/source/ui/drawfunc/makefile.mk b/sc/source/ui/drawfunc/makefile.mk
new file mode 100644
index 000000000000..a50c450ab373
--- /dev/null
+++ b/sc/source/ui/drawfunc/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=drawfunc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ objdraw.src\
+ drformsh.src
+
+SLOFILES = \
+ $(SLO)$/fupoor.obj \
+ $(SLO)$/fumark.obj \
+ $(SLO)$/fudraw.obj \
+ $(SLO)$/fusel.obj \
+ $(SLO)$/fusel2.obj \
+ $(SLO)$/fuconstr.obj \
+ $(SLO)$/fuconrec.obj \
+ $(SLO)$/fuconarc.obj \
+ $(SLO)$/fuconuno.obj \
+ $(SLO)$/fuconpol.obj \
+ $(SLO)$/fuconcustomshape.obj \
+ $(SLO)$/fuins1.obj \
+ $(SLO)$/fuins2.obj \
+ $(SLO)$/futext.obj \
+ $(SLO)$/futext2.obj \
+ $(SLO)$/futext3.obj \
+ $(SLO)$/drawsh.obj \
+ $(SLO)$/drawsh2.obj \
+ $(SLO)$/drawsh4.obj \
+ $(SLO)$/drawsh5.obj \
+ $(SLO)$/drtxtob.obj \
+ $(SLO)$/drtxtob1.obj \
+ $(SLO)$/drtxtob2.obj \
+ $(SLO)$/drformsh.obj \
+ $(SLO)$/oleobjsh.obj \
+ $(SLO)$/chartsh.obj \
+ $(SLO)$/graphsh.obj \
+ $(SLO)$/mediash.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/fuins2.obj \
+ $(SLO)$/graphsh.obj \
+ $(SLO)$/mediash.obj
+
+NOOPTFILES=\
+ $(SLO)$/fusel.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/drawfunc/mediash.cxx b/sc/source/ui/drawfunc/mediash.cxx
new file mode 100644
index 000000000000..78948550aea6
--- /dev/null
+++ b/sc/source/ui/drawfunc/mediash.cxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <avmedia/mediaitem.hxx>
+#include <svl/whiter.hxx>
+#include <svx/svdomedia.hxx>
+#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx>
+
+#include "mediash.hxx"
+#include "sc.hrc"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "scresid.hxx"
+
+#define ScMediaShell
+#include "scslots.hxx"
+
+#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
+
+
+SFX_IMPL_INTERFACE(ScMediaShell, ScDrawShell, ScResId(SCSTR_GRAPHICSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT, ScResId(RID_MEDIA_OBJECTBAR) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_MEDIA) );
+}
+
+TYPEINIT1( ScMediaShell, ScDrawShell );
+
+ScMediaShell::ScMediaShell(ScViewData* pData) :
+ ScDrawShell(pData)
+{
+ SetHelpId(HID_SCSHELL_MEDIA);
+ SetName( String( ScResId( SCSTR_MEDIASHELL ) ) );
+}
+
+ScMediaShell::~ScMediaShell()
+{
+}
+
+void ScMediaShell::GetMediaState( SfxItemSet& rSet )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+
+ if( pView )
+ {
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+
+ while( nWhich )
+ {
+ if( SID_AVMEDIA_TOOLBOX == nWhich )
+ {
+ SdrMarkList* pMarkList = new SdrMarkList( pView->GetMarkedObjectList() );
+ bool bDisable = true;
+
+ if( 1 == pMarkList->GetMarkCount() )
+ {
+ SdrObject* pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
+
+ if( pObj && pObj->ISA( SdrMediaObj ) )
+ {
+ ::avmedia::MediaItem aItem( SID_AVMEDIA_TOOLBOX );
+
+ static_cast< sdr::contact::ViewContactOfSdrMediaObj& >( pObj->GetViewContact() ).updateMediaItem( aItem );
+ rSet.Put( aItem );
+ bDisable = false;
+ }
+ }
+
+ if( bDisable )
+ rSet.DisableItem( SID_AVMEDIA_TOOLBOX );
+
+ delete pMarkList;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+ }
+}
+
+void ScMediaShell::ExecuteMedia( SfxRequest& rReq )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+
+ if( pView && SID_AVMEDIA_TOOLBOX == rReq.GetSlot() )
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+
+ if( !pArgs || ( SFX_ITEM_SET != pArgs->GetItemState( SID_AVMEDIA_TOOLBOX, FALSE, &pItem ) ) )
+ pItem = NULL;
+
+ if( pItem )
+ {
+ SdrMarkList* pMarkList = new SdrMarkList( pView->GetMarkedObjectList() );
+
+ if( 1 == pMarkList->GetMarkCount() )
+ {
+ SdrObject* pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
+
+ if( pObj && pObj->ISA( SdrMediaObj ) )
+ {
+ static_cast< sdr::contact::ViewContactOfSdrMediaObj& >( pObj->GetViewContact() ).executeMediaItem(
+ static_cast< const ::avmedia::MediaItem& >( *pItem ) );
+ }
+
+ delete pMarkList;
+ }
+ }
+ }
+
+ Invalidate();
+}
diff --git a/sc/source/ui/drawfunc/objdraw.src b/sc/source/ui/drawfunc/objdraw.src
new file mode 100644
index 000000000000..82649044b38c
--- /dev/null
+++ b/sc/source/ui/drawfunc/objdraw.src
@@ -0,0 +1,1547 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+#include "submenu.hrc"
+#include <svx/globlmn.hrc>
+ //
+ // Defines -------------------------------------------------------------------------------
+ //
+#define MN_RESET\
+ MenuItem\
+ {\
+ Identifier = SID_TEXT_STANDARD ; \
+ HelpID = SID_TEXT_STANDARD ; \
+ Text [ en-US ] = "~Default" ; \
+ Text [ x-comment ] = " ";\
+ };
+
+ // Font (SID_ATTR_CHAR_FONT) und Groesse (SID_ATTR_CHAR_FONTHEIGHT) duerfen nicht im
+ // Formatmenue auftauchen, weil die Controller im ExeEnv sonst im Container angelegt werden
+#define MN_TEXT_ATTR\
+ MenuItem\
+ {\
+ Identifier = RID_MN_FORMAT_STYLE ; \
+ HelpID = RID_MN_FORMAT_STYLE ; \
+ Text [ en-US ] = "~Style" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_WEIGHT\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_POSTURE\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_OVERLINE\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_UNDERLINE\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_STRIKEOUT\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_SHADOWED\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_ATTR_CHAR_CONTOUR\
+ };\
+ MenuItem\
+ {\
+ Separator = TRUE ; \
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_SET_SUPER_SCRIPT ; \
+ HelpID = SID_SET_SUPER_SCRIPT ; \
+ Text [ en-US ] = "~Superscript" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_SET_SUB_SCRIPT ; \
+ HelpID = SID_SET_SUB_SCRIPT ; \
+ Text [ en-US ] = "S~ubscript" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ Identifier = RID_MN_FORMAT_ALGN ; \
+ HelpID = RID_MN_FORMAT_ALGN ; \
+ Text [ en-US ] = "~Alignment" ; \
+ RadioCheck = TRUE ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ Identifier = SID_ALIGNLEFT ; \
+ HelpID = SID_ATTR_PARA_ADJUST_LEFT ; \
+ RadioCheck = TRUE ; \
+ Text [ en-US ] = "~Left" ;\
+ Text [ x-comment ] = " "; \
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_ALIGNRIGHT ; \
+ HelpID = SID_ATTR_PARA_ADJUST_RIGHT ; \
+ RadioCheck = TRUE ; \
+ Text [ en-US ] = "~Right" ;\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_ALIGNCENTERHOR ; \
+ HelpID = SID_ATTR_PARA_ADJUST_CENTER ; \
+ RadioCheck = TRUE ; \
+ Text [ en-US ] = "~Centered" ;\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_ALIGNBLOCK ; \
+ HelpID = SID_ATTR_PARA_ADJUST_BLOCK ; \
+ RadioCheck = TRUE ; \
+ Text [ en-US ] = "~Justified" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ Identifier = RID_MN_FORMAT_LINESPACE ; \
+ HelpID = RID_MN_FORMAT_LINESPACE ; \
+ Text [ en-US ] = "~Line Spacing" ; \
+ _MenuItemFlags = MIB_RADIOCHECK ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ ITEM_FORMAT_PARA_LINESPACE_10\
+ RadioCheck = TRUE ; \
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_PARA_LINESPACE_15\
+ RadioCheck = TRUE ; \
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_PARA_LINESPACE_20\
+ RadioCheck = TRUE ; \
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_DRWTXT \
+ MenuItem\
+ {\
+ ITEM_FORMAT_CHAR_DLG\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_PARA_DLG\
+ };
+
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+#define MN_EDITLNK \
+ MenuItem\
+ {\
+ Identifier = SID_DRAW_HLINK_EDIT ; \
+ HelpID = SID_DRAW_HLINK_EDIT ; \
+ Text [ en-US ] = "~Hyperlink..." ; \
+ };
+
+#define MN_DELLNK \
+ MenuItem\
+ {\
+ Identifier = SID_DRAW_HLINK_DELETE ; \
+ HelpID = SID_DRAW_HLINK_DELETE ; \
+ Text [ en-US ] = "~Remove Hyperlink" ; \
+ };
+#endif
+
+#define MN_DRWTXTATTR \
+ MenuItem\
+ {\
+ Identifier = SID_DRAWTEXT_ATTR_DLG ; \
+ HelpID = SID_DRAWTEXT_ATTR_DLG ; \
+ Text [ en-US ] = "Te~xt..." ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Textattribute für die selektierten Textobjekte festlegen : Textattribute f³r die selektierten Textobjekte festlegen */\
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_ASSIGNMACRO \
+ MenuItem\
+ {\
+ Identifier = SID_ASSIGNMACRO ; \
+ HelpID = SID_ASSIGNMACRO ; \
+ Text [ en-US ] = "Assig~n Macro..." ; \
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_ORIGINALSIZE \
+ MenuItem\
+ {\
+ Identifier = SID_ORIGINALSIZE ; \
+ HelpId = SID_ORIGINALSIZE ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Originalgröße : Originalgr÷˜e */\
+ Text [ en-US ] = "~Original Size" ; \
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_RENAME_OBJECT \
+ MenuItem\
+ {\
+ Identifier = SID_RENAME_OBJECT ; \
+ HelpId = SID_RENAME_OBJECT ; \
+ Text [ en-US ] = "Name...";\
+ };
+
+// #i68101#
+#define MN_TITLE_DESCRIPTION_OBJECT \
+ MenuItem\
+ {\
+ Identifier = SID_TITLE_DESCRIPTION_OBJECT; \
+ HelpId = SID_TITLE_DESCRIPTION_OBJECT; \
+ Text [ en-US ] = "Description...";\
+ };
+
+#define MN_MIRRORSUB \
+ MenuItem\
+ {\
+ Identifier = SUBMENU_OBJMIRROR ; \
+ HelpID = HID_SCMENU_OBJMIRROR ; \
+ Text [ en-US ] = "~Flip" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ Identifier = SID_MIRROR_VERTICAL ; \
+ HelpId = SID_MIRROR_VERTICAL ; \
+ Text [ en-US ] = "~Vertically" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_MIRROR_HORIZONTAL ; \
+ HelpId = SID_MIRROR_HORIZONTAL ; \
+ Text [ en-US ] = "~Horizontal" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_ARRANGESUB \
+ MenuItem\
+ {\
+ Identifier = SUBMENU_OBJARRANGE ; \
+ HelpID = HID_SCMENU_OBJARRANGE ; \
+ Text [ en-US ] = "~Arrange" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ ITEM_FORMAT_FRAME_TO_TOP\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_FRAME_UP ; \
+ HelpId = SID_FRAME_UP ; \
+ /* ### ACHTUNG: Neuer Text in Resource? W~eiter nach vorn : Weiter nach vorn */\
+ Text [ en-US ] = "Bring ~Forward" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_FRAME_DOWN ; \
+ HelpId = SID_FRAME_DOWN ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Weiter ~nach hinten : Weiter nach hinten */\
+ Text [ en-US ] = "Send Back~ward" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_FRAME_TO_BOTTOM\
+ };\
+ MenuItem { Separator = TRUE ; }; \
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_HEAVEN\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_HELL\
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_ANCHORSUB \
+ MenuItem\
+ {\
+ Identifier = SUBMENU_ANCHOR ; \
+ HelpID = HID_SCMENU_ANCHOR ; \
+ Text [ en-US ] = "An~chor" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ RadioCheck = TRUE ; \
+ Identifier = SID_ANCHOR_PAGE ; \
+ HelpId = SID_ANCHOR_PAGE ; \
+ Text [ en-US ] = "To P~age" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ MenuItem\
+ {\
+ RadioCheck = TRUE ; \
+ Identifier = SID_ANCHOR_CELL ; \
+ HelpId = SID_ANCHOR_CELL ; \
+ Text [ en-US ] = "To ~Cell" ; \
+ Text [ x-comment ] = " ";\
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };
+
+#define MN_ALIGNSUB \
+ MenuItem\
+ {\
+ Identifier = SID_OBJECT_ALIGN ; \
+ HelpId = SID_OBJECT_ALIGN ; \
+ Text [ en-US ] = "A~lignment" ; \
+ SubMenu = Menu\
+ {\
+ ItemList = \
+ {\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_LEFT\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_CENTER\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_RIGHT\
+ };\
+ MenuItem\
+ {\
+ Separator = TRUE ; \
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_UP\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_MIDDLE\
+ };\
+ MenuItem\
+ {\
+ ITEM_FORMAT_OBJECT_ALIGN_DOWN\
+ };\
+ };\
+ };\
+ Text [ x-comment ] = " ";\
+ };
+
+ //
+ // ------------------------------------------------------------------------------
+ //
+ //
+ // Objekt-Leisten
+ //
+String RID_DRAW_OBJECTBAR
+{
+ Text [ en-US ] = "Drawing Object Bar" ;
+ Text [ x-comment ] = " ";
+};
+ToolBox RID_DRAW_OBJECTBAR
+{
+ HelpId = HID_SC_TOOLBOX_DRAW ;
+ Dockable = TRUE ;
+ Moveable = TRUE ;
+ Sizeable = TRUE ;
+ Closeable = TRUE ;
+ Zoomable = TRUE ;
+ Customize = TRUE ;
+ HideWhenDeactivate = TRUE ;
+ LineSpacing = TRUE ;
+ Border = TRUE ;
+ SVLook = TRUE ;
+ MenuStrings = TRUE ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_BEZIER_EDIT ;
+ HelpID = SID_BEZIER_EDIT ;
+
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ // Linien
+ ToolBoxItem
+ {
+ Identifier = SID_ATTRIBUTES_LINE ;
+ HelpId = SID_ATTRIBUTES_LINE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_LINEEND_STYLE ;
+ HelpID = SID_ATTR_LINEEND_STYLE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_LINE_STYLE ;
+ HelpId = SID_ATTR_LINE_STYLE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_LINE_WIDTH ;
+ HelpId = SID_ATTR_LINE_WIDTH ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_LINE_COLOR ;
+ HelpId = SID_ATTR_LINE_COLOR ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTRIBUTES_AREA ;
+ HelpId = SID_ATTRIBUTES_AREA ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_FILL_STYLE ;
+ HelpId = SID_ATTR_FILL_STYLE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ // Rest
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_ROTATE ;
+ HelpId = SID_OBJECT_ROTATE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ANCHOR_TOGGLE ;
+ HelpId = SID_ANCHOR_TOGGLE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_FRAME_TO_TOP ;
+ HelpId = SID_FRAME_TO_TOP ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_FRAME_TO_BOTTOM ;
+ HelpId = SID_FRAME_TO_BOTTOM ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_HEAVEN ;
+ HelpID = SID_OBJECT_HEAVEN ;
+
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_HELL ;
+ HelpID = SID_OBJECT_HELL ;
+
+ };
+
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+
+ ToolBoxItem
+ {
+ Identifier = SID_GRID_VISIBLE;
+ HelpID = SID_GRID_VISIBLE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_GRID_USE;
+ HelpID = SID_GRID_USE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_HELPLINES_MOVE;
+ HelpID = SID_HELPLINES_MOVE;
+ Hide = TRUE;
+ };
+
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_ALIGN ;
+ HelpId = SID_OBJECT_ALIGN ;
+ };
+ };
+ Scroll = TRUE ;
+};
+ //
+ // Text-Toolbox
+ //
+String RID_TEXT_TOOLBOX
+{
+ Text [ en-US ] = "Text Object Bar" ;
+ Text [ x-comment ] = " ";
+};
+ToolBox RID_TEXT_TOOLBOX
+{
+ HelpId = HID_SC_TOOLBOX_DRTEXT ;
+ LineSpacing = TRUE ;
+ Dockable = TRUE ;
+ Moveable = TRUE ;
+ Sizeable = TRUE ;
+ Closeable = TRUE ;
+ Zoomable = TRUE ;
+ Scroll = TRUE ;
+ Customize = TRUE ;
+ HideWhenDeactivate = TRUE ;
+ Border = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 0 , 0 ) ;
+ Align = BOXALIGN_TOP ;
+ MenuStrings = TRUE ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_FONT ;
+ HelpId = SID_ATTR_CHAR_FONT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_FONTHEIGHT ;
+ HelpId = SID_ATTR_CHAR_FONTHEIGHT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_WEIGHT ;
+ HelpId = SID_ATTR_CHAR_WEIGHT ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_POSTURE ;
+ HelpId = SID_ATTR_CHAR_POSTURE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_UNDERLINE ;
+ HelpId = SID_ATTR_CHAR_UNDERLINE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ULINE_VAL_DOUBLE;
+ HelpId = SID_ULINE_VAL_DOUBLE;
+ AutoCheck = TRUE ;
+ Hide=TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_COLOR ;
+ HelpId = SID_ATTR_CHAR_COLOR ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_10 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_10 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_15 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_15 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_20 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_20 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNLEFT ;
+ HelpId = SID_ATTR_PARA_ADJUST_LEFT ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNCENTERHOR ;
+ HelpId = SID_ATTR_PARA_ADJUST_CENTER ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNRIGHT ;
+ HelpId = SID_ATTR_PARA_ADJUST_RIGHT ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNBLOCK ;
+ HelpId = SID_ATTR_PARA_ADJUST_BLOCK ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ HelpID = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ RadioCheck = TRUE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ HelpID = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ RadioCheck = TRUE;
+ Hide = TRUE;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_SET_SUPER_SCRIPT ;
+ HelpID = SID_SET_SUPER_SCRIPT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_SET_SUB_SCRIPT ;
+ HelpID = SID_SET_SUB_SCRIPT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_TEXTDIRECTION_LEFT_TO_RIGHT ;
+ HelpID = SID_TEXTDIRECTION_LEFT_TO_RIGHT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_TEXTDIRECTION_TOP_TO_BOTTOM ;
+ HelpID = SID_TEXTDIRECTION_TOP_TO_BOTTOM ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_CHAR_DLG ;
+ HelpID = SID_CHAR_DLG ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_PARA_DLG ;
+ HelpID = SID_PARA_DLG ;
+ };
+ };
+ ItemList[ ar ] =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_FONT ;
+ HelpId = SID_ATTR_CHAR_FONT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_FONTHEIGHT ;
+ HelpId = SID_ATTR_CHAR_FONTHEIGHT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_WEIGHT ;
+ HelpId = SID_ATTR_CHAR_WEIGHT ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_POSTURE ;
+ HelpId = SID_ATTR_CHAR_POSTURE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_UNDERLINE ;
+ HelpId = SID_ATTR_CHAR_UNDERLINE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ULINE_VAL_DOUBLE;
+ HelpId = SID_ULINE_VAL_DOUBLE;
+ AutoCheck = TRUE ;
+ Hide=TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_COLOR ;
+ HelpId = SID_ATTR_CHAR_COLOR ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_10 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_10 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_15 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_15 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_20 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_20 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNRIGHT ;
+ HelpId = SID_ATTR_PARA_ADJUST_RIGHT ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNCENTERHOR ;
+ HelpId = SID_ATTR_PARA_ADJUST_CENTER ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNLEFT ;
+ HelpId = SID_ATTR_PARA_ADJUST_LEFT ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNBLOCK ;
+ HelpId = SID_ATTR_PARA_ADJUST_BLOCK ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ HelpID = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ RadioCheck = TRUE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ HelpID = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ RadioCheck = TRUE;
+ Hide = TRUE;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_SET_SUPER_SCRIPT ;
+ HelpID = SID_SET_SUPER_SCRIPT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_SET_SUB_SCRIPT ;
+ HelpID = SID_SET_SUB_SCRIPT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_TEXTDIRECTION_LEFT_TO_RIGHT ;
+ HelpID = SID_TEXTDIRECTION_LEFT_TO_RIGHT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_TEXTDIRECTION_TOP_TO_BOTTOM ;
+ HelpID = SID_TEXTDIRECTION_TOP_TO_BOTTOM ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_CHAR_DLG ;
+ HelpID = SID_CHAR_DLG ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_PARA_DLG ;
+ HelpID = SID_PARA_DLG ;
+ };
+ };
+ ItemList[ he ] =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_FONT ;
+ HelpId = SID_ATTR_CHAR_FONT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_FONTHEIGHT ;
+ HelpId = SID_ATTR_CHAR_FONTHEIGHT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_WEIGHT ;
+ HelpId = SID_ATTR_CHAR_WEIGHT ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_POSTURE ;
+ HelpId = SID_ATTR_CHAR_POSTURE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_UNDERLINE ;
+ HelpId = SID_ATTR_CHAR_UNDERLINE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ULINE_VAL_DOUBLE;
+ HelpId = SID_ULINE_VAL_DOUBLE;
+ AutoCheck = TRUE ;
+ Hide=TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_CHAR_COLOR ;
+ HelpId = SID_ATTR_CHAR_COLOR ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_10 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_10 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_15 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_15 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LINESPACE_20 ;
+ HelpId = SID_ATTR_PARA_LINESPACE_20 ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNRIGHT ;
+ HelpId = SID_ATTR_PARA_ADJUST_RIGHT ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNCENTERHOR ;
+ HelpId = SID_ATTR_PARA_ADJUST_CENTER ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNLEFT ;
+ HelpId = SID_ATTR_PARA_ADJUST_LEFT ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ALIGNBLOCK ;
+ HelpId = SID_ATTR_PARA_ADJUST_BLOCK ;
+ RadioCheck = TRUE ;
+ AutoCheck = TRUE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ HelpID = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ RadioCheck = TRUE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ HelpID = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ RadioCheck = TRUE;
+ Hide = TRUE;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_SET_SUPER_SCRIPT ;
+ HelpID = SID_SET_SUPER_SCRIPT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_SET_SUB_SCRIPT ;
+ HelpID = SID_SET_SUB_SCRIPT ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_TEXTDIRECTION_LEFT_TO_RIGHT ;
+ HelpID = SID_TEXTDIRECTION_LEFT_TO_RIGHT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_TEXTDIRECTION_TOP_TO_BOTTOM ;
+ HelpID = SID_TEXTDIRECTION_TOP_TO_BOTTOM ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_CHAR_DLG ;
+ HelpID = SID_CHAR_DLG ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_PARA_DLG ;
+ HelpID = SID_PARA_DLG ;
+ };
+ };
+};
+ //
+ // Graphics toolbox
+ //
+String RID_GRAPHIC_OBJECTBAR
+{
+ Text [ en-US ] = "Graphics Object Bar";
+};
+ToolBox RID_GRAPHIC_OBJECTBAR
+{
+ HelpId = HID_SC_TOOLBOX_GRAPHIC ;
+ LineSpacing = TRUE ;
+ Dockable = TRUE ;
+ Moveable = TRUE ;
+ Sizeable = TRUE ;
+ Closeable = TRUE ;
+ Zoomable = TRUE ;
+ Scroll = TRUE ;
+ Customize = TRUE ;
+ HideWhenDeactivate = TRUE ;
+ Border = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 0 , 0 ) ;
+ Align = BOXALIGN_TOP ;
+ MenuStrings = TRUE ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_GRFFILTER;
+ HelpID = SID_GRFFILTER;
+ DropDown = TRUE ;
+ Checkable = FALSE ;
+ RadioCheck = FALSE ;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_MODE;
+ HelpID = SID_ATTR_GRAF_MODE;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_RED;
+ HelpID = SID_ATTR_GRAF_RED;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_GREEN;
+ HelpID = SID_ATTR_GRAF_GREEN;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_BLUE;
+ HelpID = SID_ATTR_GRAF_BLUE;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_LUMINANCE;
+ HelpID = SID_ATTR_GRAF_LUMINANCE;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_CONTRAST;
+ HelpID = SID_ATTR_GRAF_CONTRAST;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_GAMMA;
+ HelpID = SID_ATTR_GRAF_GAMMA;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_TRANSPARENCE;
+ HelpID = SID_ATTR_GRAF_TRANSPARENCE;
+ };
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+
+ // #i25616#
+ ToolBoxItem
+ {
+ Identifier = SID_ATTRIBUTES_LINE;
+ HelpID = SID_ATTRIBUTES_LINE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTRIBUTES_AREA;
+ HelpID = SID_ATTRIBUTES_AREA;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_FILL_SHADOW;
+ HelpID = SID_ATTR_FILL_SHADOW;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SEPARATOR ;
+ };
+
+ ToolBoxItem
+ {
+ Identifier = SID_ATTR_GRAF_CROP;
+ HelpID = SID_ATTR_GRAF_CROP;
+ };
+
+ // copied from the "normal" drawing toolbar:
+
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_ANCHOR_TOGGLE ;
+ HelpId = SID_ANCHOR_TOGGLE ;
+ };
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_FRAME_TO_TOP ;
+ HelpId = SID_FRAME_TO_TOP ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_FRAME_TO_BOTTOM ;
+ HelpId = SID_FRAME_TO_BOTTOM ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_HEAVEN ;
+ HelpID = SID_OBJECT_HEAVEN ;
+
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_HELL ;
+ HelpID = SID_OBJECT_HELL ;
+
+ };
+
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+
+ ToolBoxItem
+ {
+ Identifier = SID_GRID_VISIBLE;
+ HelpID = SID_GRID_VISIBLE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_GRID_USE;
+ HelpID = SID_GRID_USE;
+ Hide = TRUE;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_HELPLINES_MOVE;
+ HelpID = SID_HELPLINES_MOVE;
+ Hide = TRUE;
+ };
+
+ //---------------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR ; };
+ //---------------------------------------------
+ ToolBoxItem
+ {
+ Identifier = SID_OBJECT_ALIGN ;
+ HelpId = SID_OBJECT_ALIGN ;
+ };
+ };
+};
+ //
+ // Popup-Menues ---------------------------------------------------------------------
+ //
+String RID_POPUP_DRAW
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Popup-Menü für Zeichenobjekte : Popup-Men³ f³r Zeichenobjekte */
+ Text [ en-US ] = "Pop-up menu for drawing objects" ;
+ Text [ x-comment ] = " ";
+};
+ //
+ // Popup-Menue fuer (allgemeine) Zeichenobjekte
+ //
+Menu RID_POPUP_DRAW
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTRIBUTES_LINE };
+ MenuItem { ITEM_FORMAT_ATTRIBUTES_AREA };
+ MN_DRWTXTATTR // Text...
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_MIRRORSUB
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ MN_ASSIGNMACRO
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ ITEM_FORMAT_BEZIER_EDIT
+ RadioCheck = FALSE ;
+ AutoCheck = TRUE ;
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_FONTWORK
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_EDITLNK
+ MN_DELLNK
+ MenuItem { ITEM_OPEN_HYPERLINK };
+#endif
+ };
+};
+
+ //
+ // Popup-Menue fuer (Uno-) Controls
+ //
+
+Menu RID_POPUP_CONTROL
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem { ITEM_FORM_CONTROL_PROPERTIES };
+ MenuItem { ITEM_FORM_PROPERTIES };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+ };
+};
+
+ //
+ // Grafik
+ //
+
+Menu RID_POPUP_GRAPHIC
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTRIBUTES_LINE }; // #i25616#
+ MenuItem { ITEM_FORMAT_ATTRIBUTES_AREA }; // #i25616#
+ MN_DRWTXTATTR
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+ MN_ORIGINALSIZE
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_MIRRORSUB
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ MN_ASSIGNMACRO
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_EDITLNK
+ MN_DELLNK
+ MenuItem { ITEM_OPEN_HYPERLINK };
+#endif
+ };
+};
+
+ //
+ // Media
+ //
+
+Menu RID_POPUP_MEDIA
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_MIRRORSUB
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+ };
+};
+
+ToolBox RID_MEDIA_OBJECTBAR
+{
+ //HelpId = HID_SC_TOOLBOX_MEDIA ;
+ LineSpacing = TRUE ;
+ Dockable = TRUE ;
+ Moveable = TRUE ;
+ Sizeable = TRUE ;
+ Closeable = TRUE ;
+ Zoomable = TRUE ;
+ Scroll = TRUE ;
+ Customize = TRUE ;
+ HideWhenDeactivate = TRUE ;
+ Border = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 0 , 0 ) ;
+ Align = BOXALIGN_TOP ;
+ MenuStrings = TRUE ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_AVMEDIA_TOOLBOX;
+ HelpID = SID_AVMEDIA_TOOLBOX;
+ DropDown = FALSE ;
+ Checkable = FALSE ;
+ RadioCheck = FALSE ;
+ };
+ };
+};
+
+ //
+ // Ole-Objekt
+ //
+
+Menu RID_POPUP_OLE
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+ MN_ORIGINALSIZE
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+ };
+};
+
+ //
+ // Charts
+ //
+
+Menu RID_POPUP_CHART
+{
+ ItemList =
+ {
+ MenuItem { ITEM_FORMAT_ATTR_TRANSFORM };
+ MN_ORIGINALSIZE
+
+ //-#i68101#----------------------
+ MenuItem { Separator = TRUE ; };
+ MN_TITLE_DESCRIPTION_OBJECT
+ MN_RENAME_OBJECT
+ //-#i68101#----------------------
+
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MN_ARRANGESUB
+ MN_ALIGNSUB
+ MN_ANCHORSUB
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ ITEM_GROUP_MENU
+ };
+};
+
+ //
+ // PopUpDraw Text
+ //
+
+String RID_POPUP_DRAWTEXT
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Popup-Menü für Text-Objekte : Popup-Men³ f³r Text-Objekte */
+ Text [ en-US ] = "Pop-up menu for text objects" ;
+ Text [ x-comment ] = " ";
+};
+
+Menu RID_POPUP_DRAWTEXT
+{
+ ItemList =
+ {
+ MN_RESET
+ MenuItem { Separator = TRUE ; };
+ MN_DRWTXTATTR
+ MenuItem { Separator = TRUE ; };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_FONT
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_FONTHEIGHT
+ };
+ // Stil, Ausrichtung, Zeilenabstand
+ MN_TEXT_ATTR
+ MenuItem { Separator = TRUE ; };
+ // Zeichen, Absatz
+ MN_DRWTXT
+ MenuItem { Separator = TRUE ; };
+ MenuItem
+ {
+ ITEM_OPEN_HYPERLINK
+ };
+ };
+};
+
diff --git a/sc/source/ui/drawfunc/oleobjsh.cxx b/sc/source/ui/drawfunc/oleobjsh.cxx
new file mode 100644
index 000000000000..f9346dd8da88
--- /dev/null
+++ b/sc/source/ui/drawfunc/oleobjsh.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+#include <svx/fontwork.hxx>
+//CHINA001 #include <svx/labdlg.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/tabline.hxx>
+//CHINA001 #include <svx/transfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "oleobjsh.hxx"
+#include "drwlayer.hxx"
+#include "sc.hrc"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "drawview.hxx"
+#include "scresid.hxx"
+#include <svx/svdobj.hxx>
+
+#define ScOleObjectShell
+#include "scslots.hxx"
+
+
+SFX_IMPL_INTERFACE(ScOleObjectShell, ScDrawShell, ScResId(SCSTR_OLEOBJECTSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
+ ScResId(RID_DRAW_OBJECTBAR) );
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_OLE) );
+}
+
+TYPEINIT1( ScOleObjectShell, ScDrawShell );
+
+ScOleObjectShell::ScOleObjectShell(ScViewData* pData) :
+ ScDrawShell(pData)
+{
+ SetHelpId(HID_SCSHELL_OLEOBEJCTSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("OleObject")));
+}
+
+ScOleObjectShell::~ScOleObjectShell()
+{
+}
+
+
+
diff --git a/sc/source/ui/formdlg/dwfunctr.cxx b/sc/source/ui/formdlg/dwfunctr.cxx
new file mode 100644
index 000000000000..1d522fb3211e
--- /dev/null
+++ b/sc/source/ui/formdlg/dwfunctr.cxx
@@ -0,0 +1,1182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/editview.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+
+#include "sc.hrc"
+#include "global.hxx" // ScAddress
+#include "scresid.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "tabvwsh.hxx"
+#include "appoptio.hxx"
+#include "compiler.hxx"
+
+#include "dwfunctr.hrc"
+#include "dwfunctr.hxx"
+
+// -----------------------------------------------------------------------
+
+#define ARG_SEPERATOR String("; ")
+SFX_IMPL_DOCKINGWINDOW( ScFunctionChildWindow, FID_FUNCTION_BOX )
+
+/*************************************************************************
+#* Member: ScFunctionChildWindow Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionChildWindow
+#*
+#* Funktion: Konstruktor der Klasse ScFunctionChildWindow
+#* Ableitung vom SfxChildWindow als "Behaelter" fuer
+#* Funktions- Fenster in Clac
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+__EXPORT ScFunctionChildWindow::ScFunctionChildWindow( Window* pParentP,
+ USHORT nId,
+ SfxBindings* pBindings,
+ SfxChildWinInfo* pInfo ) :
+ SfxChildWindow( pParentP, nId )
+{
+ ScFunctionDockWin* pWin = new ScFunctionDockWin( pBindings, this,
+ pParentP, ScResId( FID_FUNCTION_BOX ) );
+ pWindow = pWin;
+
+ eChildAlignment = SFX_ALIGN_RIGHT;
+
+ pWin->Initialize( pInfo );
+}
+
+/*************************************************************************
+#* Member: ScFunctionDockWin Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Konstruktor der Klasse ScFunctionDockWin
+#*
+#* Input: Sfx- Verknuepfungen, Fenster, Resource
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+ScFunctionDockWin::ScFunctionDockWin( SfxBindings* pBindingsP,
+ SfxChildWindow *pCW, Window* pParent, const ResId& rResId ) :
+
+ SfxDockingWindow( pBindingsP, pCW, pParent, rResId ),
+ aPrivatSplit ( this, ResId( FT_SPLIT, *rResId.GetResMgr() ),SC_SPLIT_VERT),
+ aCatBox ( this, ResId( CB_CAT, *rResId.GetResMgr() ) ),
+ aFuncList ( this, ResId( LB_FUNC, *rResId.GetResMgr() ) ),
+ aDDFuncList ( this, ResId( DDLB_FUNC, *rResId.GetResMgr() ) ),
+ aInsertButton ( this, ResId( IMB_INSERT, *rResId.GetResMgr() ) ),
+ aFiFuncDesc ( this, ResId( FI_FUNCDESC, *rResId.GetResMgr() ) ),
+ aOldSize (0,0)
+{
+ FreeResource();
+ InitLRUList();
+ SetStyle(GetStyle()|WB_CLIPCHILDREN);
+
+ aTimer.SetTimeout(200);
+ aTimer.SetTimeoutHdl(LINK( this, ScFunctionDockWin, TimerHdl));
+
+ eSfxNewAlignment=GetAlignment();
+ eSfxOldAlignment=eSfxNewAlignment;
+ aFiFuncDesc.SetUpdateMode(TRUE);
+ pAllFuncList=&aFuncList;
+ aDDFuncList.Disable();
+ aDDFuncList.Hide();
+ nArgs=0;
+ nDockMode=0;
+ bSizeFlag=FALSE;
+ aCatBox.SetDropDownLineCount(9);
+ Font aFont=aFiFuncDesc.GetFont();
+ aFont.SetColor(Color(COL_BLACK));
+ aFiFuncDesc.SetFont(aFont);
+ aFiFuncDesc.SetBackground( GetBackground() ); //! never transparent?
+//? SetBackground();
+
+ Link aLink=LINK( this, ScFunctionDockWin, SelHdl);
+ aCatBox.SetSelectHdl(aLink);
+ aFuncList.SetSelectHdl(aLink);
+ aDDFuncList.SetSelectHdl(aLink);
+
+ Link a2Link=LINK( this, ScFunctionDockWin, SetSelectionHdl);
+ aFuncList.SetDoubleClickHdl(a2Link);
+ aDDFuncList.SetSelectHdl(aLink);
+ aInsertButton.SetClickHdl(a2Link);
+
+ Link a3Link=LINK( this, ScFunctionDockWin, SetSplitHdl);
+ aPrivatSplit.SetCtrModifiedHdl(a3Link);
+ StartListening( *pBindingsP, TRUE );
+
+ Point aTopLeft=aCatBox.GetPosPixel();
+ //String aString=aCatBox.GetEntry( 0)+String("www");
+ String aString=String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ww"));
+ Size aTxtSize( aFiFuncDesc.GetTextWidth(aString), aFiFuncDesc.GetTextHeight() );
+ nMinWidth=aTxtSize.Width()+aTopLeft.X()
+ +2*aFuncList.GetPosPixel().X();
+ nMinHeight=19*aTxtSize.Height();
+ aCatBox.SelectEntryPos(0);
+
+ Range aYRange(3*aTxtSize.Height()+aFuncList.GetPosPixel().Y(),
+ GetOutputSizePixel().Height()-2*aTxtSize.Height());
+ aPrivatSplit.SetYRange(aYRange);
+ SelHdl(&aCatBox);
+ bInit=TRUE;
+}
+
+/*************************************************************************
+#* Member: ScFunctionDockWin Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Destruktor der Klasse ScFunctionDockWin
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+__EXPORT ScFunctionDockWin::~ScFunctionDockWin()
+{
+ EndListening( GetBindings() );
+}
+
+/*************************************************************************
+#* Member: UpdateFunctionList Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Aktualisiert die Liste der Funktionen ab-
+#* haengig von der eingestellten Kategorie.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::InitLRUList()
+{
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+ USHORT nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (USHORT)LRU_MAX );
+ USHORT* pLRUListIds = rAppOpt.GetLRUFuncList();
+
+ USHORT i;
+ for ( i=0; i<LRU_MAX; i++ )
+ aLRUList[i] = NULL;
+
+ if ( pLRUListIds )
+ {
+ ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+ for ( i=0; i<nLRUFuncCount; i++ )
+ aLRUList[i] = pFuncMgr->Get( pLRUListIds[i] );
+ }
+
+ USHORT nSelPos = aCatBox.GetSelectEntryPos();
+
+ if(nSelPos == 0)
+ UpdateFunctionList();
+}
+
+/*************************************************************************
+#* Member: UpdateFunctionList Datum:10.12.99
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Aktualisiert die Liste der zuletzt verwendeten Funktionen.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::UpdateLRUList()
+{
+ if (pFuncDesc && pFuncDesc->nFIndex!=0)
+ {
+ ScModule* pScMod = SC_MOD();
+ pScMod->InsertEntryToLRUList(pFuncDesc->nFIndex);
+ }
+}
+
+
+/*************************************************************************
+#* Member: SetSize Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Groesse fuer die einzelnen Controls einzustellen.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetSize()
+{
+ USHORT nSelEntry=0;
+ SfxChildAlignment aChildAlign=eSfxOldAlignment;//GetAlignment();
+ short nNewDockMode;
+ switch(aChildAlign)
+ {
+ case SFX_ALIGN_HIGHESTTOP:
+ case SFX_ALIGN_TOP:
+ case SFX_ALIGN_LOWESTTOP:
+ case SFX_ALIGN_LOWESTBOTTOM:
+ case SFX_ALIGN_BOTTOM:
+ case SFX_ALIGN_TOOLBOXTOP:
+ case SFX_ALIGN_TOOLBOXBOTTOM:
+
+
+ nNewDockMode=1;
+ if(nDockMode!=nNewDockMode)
+ {
+ nDockMode=nNewDockMode;
+ nSelEntry=aFuncList.GetSelectEntryPos();
+ aFuncList.Clear();
+ aFiFuncDesc.SetPosPixel(aFuncList.GetPosPixel());
+ aDDFuncList.Enable();
+ aDDFuncList.Show();
+ aPrivatSplit.Disable();
+ aPrivatSplit.Hide();
+ aFuncList.Disable();
+ aFuncList.Hide();
+ pAllFuncList=&aDDFuncList;
+ SelHdl(&aCatBox);
+ aDDFuncList.SelectEntryPos(nSelEntry);
+ }
+ break;
+
+ default: nNewDockMode=0;
+ if(nDockMode!=nNewDockMode)
+ {
+ nDockMode=nNewDockMode;
+ nSelEntry=aDDFuncList.GetSelectEntryPos();
+ aDDFuncList.Clear();
+ aDDFuncList.Disable();
+ aDDFuncList.Hide();
+ aPrivatSplit.Enable();
+ aPrivatSplit.Show();
+ aFuncList.Enable();
+ aFuncList.Show();
+ pAllFuncList=&aFuncList;
+ SelHdl(&aCatBox);
+ aFuncList.SelectEntryPos(nSelEntry);
+ }
+ break;
+ }
+
+ if(nDockMode==0)
+ {
+ SetLeftRightSize();
+ }
+ else
+ {
+ SetTopBottonSize();
+ }
+}
+/*************************************************************************
+#* Member: SetLeftRightSize Datum:15.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Groesse fuer die einzelnen Controls einstellen,
+#* wenn Links oder Rechts angedockt wird.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetLeftRightSize()
+{
+ if(bSizeFlag==FALSE)
+ {
+ bSizeFlag=TRUE;
+
+ Size aDiffSize=GetSizePixel();
+ Size aNewSize=GetOutputSizePixel();
+ aDiffSize.Width()-=aNewSize.Width();
+ aDiffSize.Height()-=aNewSize.Height();
+
+ //@ SetUpdateMode( FALSE);
+
+ String aString = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ww"));
+
+ Size aTxtSize( aFuncList.GetTextWidth(aString), aFuncList.GetTextHeight() );
+
+ Range aYRange(3*aTxtSize.Height()+aFuncList.GetPosPixel().Y(),
+ GetOutputSizePixel().Height()-2*aTxtSize.Height());
+ aPrivatSplit.SetYRange(aYRange);
+
+
+ if(aOldSize.Width()!=aNewSize.Width())
+ SetMyWidthLeRi(aNewSize);
+
+ if(aOldSize.Height()!=aNewSize.Height())
+ SetMyHeightLeRi(aNewSize);
+
+ aOldSize=aNewSize;
+ aNewSize.Width()+=aDiffSize.Width();
+ aNewSize.Height()+=aDiffSize.Height();
+ //SetSizePixel(aNewSize);
+ //@ SetUpdateMode( TRUE);
+ bSizeFlag=FALSE;
+ }
+
+}
+/*************************************************************************
+#* Member: SetTopBottonSize Datum:15.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Groesse fuer die einzelnen Controls einzustellen.
+#* wenn oben oder unten angedockt wird.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetTopBottonSize()
+{
+ if(bSizeFlag==FALSE)
+ {
+ bSizeFlag=TRUE;
+ Size aDiffSize=GetSizePixel();
+ Size aNewSize=GetOutputSizePixel();
+ aDiffSize.Width()-=aNewSize.Width();
+ aDiffSize.Height()-=aNewSize.Height();
+
+ SetMyWidthToBo(aNewSize);
+ SetMyHeightToBo(aNewSize);
+
+ aNewSize.Width()+=aDiffSize.Width();
+ aNewSize.Height()+=aDiffSize.Height();
+ //SetSizePixel(aNewSize);
+ //@ SetUpdateMode( TRUE);
+ bSizeFlag=FALSE;
+ }
+}
+
+/*************************************************************************
+#* Member: SetMyWidthLeRi Datum:15.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Breite fuer die einzelnen Controls und
+#* das Fenster einstellen,wenn Li oder Re
+#*
+#* Input: neue Fenstergroesse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetMyWidthLeRi(Size &aNewSize)
+{
+ if((ULONG)aNewSize.Width()<nMinWidth) aNewSize.Width()=nMinWidth;
+
+ Size aCDSize=aCatBox.GetSizePixel();
+ Size aFLSize=aFuncList.GetSizePixel();
+ Size aSplitterSize=aPrivatSplit.GetSizePixel();
+ Size aFDSize=aFiFuncDesc.GetSizePixel();
+
+ Point aCDTopLeft=aCatBox.GetPosPixel();
+ Point aFLTopLeft=aFuncList.GetPosPixel();
+ Point aSplitterTopLeft=aPrivatSplit.GetPosPixel();
+ Point aFDTopLeft=aFiFuncDesc.GetPosPixel();
+
+ aCDSize.Width()=aNewSize.Width()-aCDTopLeft.X()-aFLTopLeft.X();
+ aFLSize.Width()=aNewSize.Width()-2*aFLTopLeft.X();
+ aFDSize.Width()=aFLSize.Width();
+ aSplitterSize.Width()=aFLSize.Width();
+
+ aCatBox.SetSizePixel(aCDSize);
+ aFuncList.SetSizePixel(aFLSize);
+ aPrivatSplit.SetSizePixel(aSplitterSize);
+ aFiFuncDesc.SetSizePixel(aFDSize);
+}
+
+/*************************************************************************
+#* Member: SetHeight Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Hoehe fuer die einzelnen Controls und
+#* das Fenster einstellen bei Li oder Re
+#*
+#* Input: neue Fenstergroesse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetMyHeightLeRi(Size &aNewSize)
+{
+ if((ULONG)aNewSize.Height()<nMinHeight) aNewSize.Height()=nMinHeight;
+
+ Size aFLSize=aFuncList.GetSizePixel();
+ Size aSplitterSize=aPrivatSplit.GetSizePixel();
+ Size aFDSize=aFiFuncDesc.GetSizePixel();
+
+ Point aFLTopLeft=aFuncList.GetPosPixel();
+ Point aSplitterTopLeft=aPrivatSplit.GetPosPixel();
+ Point aFDTopLeft=aFiFuncDesc.GetPosPixel();
+
+ long nTxtHeight = aFuncList.GetTextHeight();
+
+ short nY=(short)(3*nTxtHeight+
+ aFuncList.GetPosPixel().Y()+aSplitterSize.Height());
+
+ aFDTopLeft.Y()=aNewSize.Height()-aFDSize.Height()-4;
+ if(nY>aFDTopLeft.Y())
+ {
+ aFDSize.Height()-=nY-aFDTopLeft.Y();
+ aFDTopLeft.Y()=nY;
+ }
+ aSplitterTopLeft.Y()=aFDTopLeft.Y()-aSplitterSize.Height()-1;
+ aFLSize.Height()=aSplitterTopLeft.Y()-aFLTopLeft.Y()-1;
+
+ aFuncList.SetSizePixel(aFLSize);
+ aPrivatSplit.SetPosPixel(aSplitterTopLeft);
+ aFiFuncDesc.SetPosPixel(aFDTopLeft);
+ aFiFuncDesc.SetSizePixel(aFDSize);
+
+}
+
+/*************************************************************************
+#* Member: SetMyWidthToBo Datum:16.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Breite fuer die einzelnen Controls und
+#* das Fenster einstellen, wenn oben oder
+#* unten angedockt werden soll.
+#*
+#* Input: neue Fenstergroesse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetMyWidthToBo(Size &aNewSize)
+{
+ if((ULONG)aNewSize.Width()<nMinWidth) aNewSize.Width()=nMinWidth;
+
+ Size aCDSize=aCatBox.GetSizePixel();
+ Size aDdFLSize=aDDFuncList.GetSizePixel();
+ Size aFDSize=aFiFuncDesc.GetSizePixel();
+
+ Point aCDTopLeft=aCatBox.GetPosPixel();
+ Point aDdFLTopLeft=aDDFuncList.GetPosPixel();
+ Point aFDTopLeft=aFiFuncDesc.GetPosPixel();
+
+ aCDSize.Width()=aDdFLTopLeft.X()-aFDTopLeft.X()-aCDTopLeft.X();
+ aDdFLTopLeft.X()=aCDSize.Width()+aCDTopLeft.X()+aFDTopLeft.X();
+
+ aDdFLSize.Width()=aNewSize.Width()-aDdFLTopLeft.X()-aFDTopLeft.X();
+
+ aFDSize.Width()=aNewSize.Width()-2*aFDTopLeft.X();
+
+ aDDFuncList.SetPosPixel(aDdFLTopLeft);
+ aDDFuncList.SetSizePixel(aDdFLSize);
+ aCatBox.SetSizePixel(aCDSize);
+ aFiFuncDesc.SetSizePixel(aFDSize);
+}
+
+/*************************************************************************
+#* Member: SetHeight Datum:16.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Hoehe fuer die einzelnen Controls und
+#* das Fenster einstellen, wenn oben oder
+#* unten angedockt werden soll.
+#*
+#* Input: neue Fenstergroesse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetMyHeightToBo(Size &aNewSize)
+{
+ if((ULONG)aNewSize.Height()<nMinHeight) aNewSize.Height()=nMinHeight;
+
+ Size aFDSize=aFiFuncDesc.GetSizePixel();
+
+ Point aFDTopLeft=aFiFuncDesc.GetPosPixel();
+ Point aCBTopLeft=aCatBox.GetPosPixel();
+ aFDSize.Height()=aNewSize.Height()-aFDTopLeft.Y()-aCBTopLeft.Y();
+ aFiFuncDesc.SetSizePixel(aFDSize);
+
+}
+
+/*************************************************************************
+#* Member: SetDescription Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Erklaerungstext fuer die Funktion einstellen.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::SetDescription()
+{
+ aFiFuncDesc.SetText( EMPTY_STRING );
+ const ScFuncDesc* pDesc =
+ (const ScFuncDesc*)pAllFuncList->GetEntryData(
+ pAllFuncList->GetSelectEntryPos() );
+ if (pDesc)
+ {
+ pDesc->initArgumentInfo(); // full argument info is needed
+
+ String aString=pAllFuncList->GetSelectEntry();
+ if(nDockMode==0)
+ {
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ":\n\n" ));
+ }
+ else
+ {
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+ }
+
+ aString+=pDesc->GetParamList();
+
+ if(nDockMode==0)
+ {
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n\n" ));
+ }
+ else
+ {
+ aString += '\n';
+ }
+
+ aString+=*(pDesc->pFuncDesc);
+
+ aFiFuncDesc.SetText(aString);
+ aFiFuncDesc.StateChanged(STATE_CHANGE_TEXT);
+ aFiFuncDesc.Invalidate();
+ aFiFuncDesc.Update();
+
+ }
+ }
+
+/*************************************************************************
+#* Member: Resizing Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Ueberladene Funktion um die Groesse der
+#* einzelnen Controls einzustellen.
+#*
+#* Input: neue Groesse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void __EXPORT ScFunctionDockWin::Resizing( Size& rNewSize )
+{
+ if((ULONG)rNewSize.Width()<nMinWidth) rNewSize.Width()=nMinWidth;
+ if((ULONG)rNewSize.Height()<nMinHeight) rNewSize.Height()=nMinHeight;
+
+}
+
+/*************************************************************************
+#* Member: Close Datum:07.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Schliessen des Fensters
+#*
+#* Input: ---
+#*
+#* Output: TRUE
+#*
+#************************************************************************/
+
+BOOL __EXPORT ScFunctionDockWin::Close()
+{
+ SfxBoolItem aItem( FID_FUNCTION_BOX, FALSE );
+
+ GetBindings().GetDispatcher()->Execute( FID_FUNCTION_BOX,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ &aItem, 0L );
+
+ SfxDockingWindow::Close();
+
+ return( TRUE );
+}
+
+
+/*************************************************************************
+#* Member: CheckAlignment Datum:16.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Ueberprueft den Andockmodus und stellt die
+#* Groessen dementsprechend ein.
+#*
+#* Input: Das neue Alignment
+#*
+#* Output: Das uebergebene Alignment
+#*
+#************************************************************************/
+SfxChildAlignment __EXPORT ScFunctionDockWin::CheckAlignment(SfxChildAlignment /* abla */,
+ SfxChildAlignment aChildAlign)
+{
+ String aString = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ww"));
+ Size aTxtSize( aFiFuncDesc.GetTextWidth(aString), aFiFuncDesc.GetTextHeight() );
+ if(!bInit)
+ {
+ eSfxOldAlignment=eSfxNewAlignment;
+ eSfxNewAlignment=aChildAlign;
+ }
+ else
+ {
+ bInit=FALSE;
+ eSfxOldAlignment=aChildAlign;
+ eSfxNewAlignment=aChildAlign;
+ }
+
+ switch(eSfxOldAlignment)
+ {
+ case SFX_ALIGN_HIGHESTTOP:
+ case SFX_ALIGN_TOP:
+ case SFX_ALIGN_LOWESTTOP:
+ case SFX_ALIGN_LOWESTBOTTOM:
+ case SFX_ALIGN_BOTTOM:
+ case SFX_ALIGN_TOOLBOXTOP:
+ case SFX_ALIGN_TOOLBOXBOTTOM:
+
+ nMinWidth= 0;/*aDDFuncList.GetPosPixel().X()+
+ 10*aTxtSize.Width()+
+ aFuncList.GetPosPixel().X();*/
+ nMinHeight=0;
+
+ break;
+
+ case SFX_ALIGN_NOALIGNMENT:
+
+ aString = aCatBox.GetEntry(0);
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM("www"));
+ aTxtSize = Size( aFiFuncDesc.GetTextWidth(aString),
+ aFiFuncDesc.GetTextHeight() );
+
+ default: Point aTopLeft=aCatBox.GetPosPixel();
+ nMinWidth=aTxtSize.Width()+aTopLeft.X()
+ +2*aFuncList.GetPosPixel().X();
+ nMinHeight=19*aTxtSize.Height();
+ //aCatBox.SelectEntryPos(0);
+
+ break;
+ }
+
+ return aChildAlign;
+}
+/*************************************************************************
+#* Member: Close Datum:07.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Aenderungen erkennen
+#*
+#* Input: ---
+#*
+#* Output: TRUE
+#*
+#************************************************************************/
+void ScFunctionDockWin::Notify( SfxBroadcaster&, const SfxHint& /* rHint */ )
+{
+// const SfxPoolItemHint *pPoolItemHint = PTR_CAST(SfxPoolItemHint, &rHint);
+ /*
+ if ( pPoolItemHint
+ && ( pPoolItemHint->GetObject()->ISA( SvxColorTableItem ) ) )
+ {
+ // Die Liste der Farben hat sich geaendert
+ pColorTable = ( (SvxColorTableItem*) pPoolItemHint->GetObject() )->GetColorTable();
+ FillValueSet();
+ }
+ */
+}
+
+
+/*************************************************************************
+#* Member: Resize Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Ueberladene Funktion um die Groesse der
+#* einzelnen Controls einzustellen.
+#*
+#* Input: neue Groesse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void __EXPORT ScFunctionDockWin::Resize()
+{
+ if ( !IsFloatingMode() ||
+ !GetFloatingWindow()->IsRollUp() )
+ {
+ Size aQSize=GetOutputSizePixel();
+ Resizing( aQSize);
+ SetSize();
+ }
+ SfxDockingWindow::Resize();
+}
+
+/*************************************************************************
+#* Member: UpdateFunctionList Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Aktualisiert die Liste der Funktionen ab-
+#* haengig von der eingestellten Kategorie.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::UpdateFunctionList()
+{
+ USHORT nSelPos = aCatBox.GetSelectEntryPos();
+ USHORT nCategory = ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
+ ? (nSelPos-1) : 0;
+
+ pAllFuncList->Clear();
+ pAllFuncList->SetUpdateMode( FALSE );
+
+ if ( nSelPos > 0 )
+ {
+ ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+
+ const ScFuncDesc* pDesc = pFuncMgr->First( nCategory );
+ while ( pDesc )
+ {
+ pAllFuncList->SetEntryData(
+ pAllFuncList->InsertEntry( *(pDesc->pFuncName) ),
+ (void*)pDesc );
+ pDesc = pFuncMgr->Next();
+ }
+ }
+ else // LRU-Liste
+ {
+ for ( USHORT i=0; i<LRU_MAX && aLRUList[i]; i++ )
+ {
+ const ScFuncDesc* pDesc = aLRUList[i];
+ pAllFuncList->SetEntryData(
+ pAllFuncList->InsertEntry( *(pDesc->pFuncName) ),
+ (void*)pDesc );
+ }
+ }
+
+
+ //------------------------------------------------------
+ pAllFuncList->SetUpdateMode( TRUE );
+
+ if ( pAllFuncList->GetEntryCount() > 0 )
+ {
+ pAllFuncList->Enable();
+ pAllFuncList->SelectEntryPos( 0 );
+ }
+ else
+ {
+ pAllFuncList->Disable();
+ }
+}
+
+/*************************************************************************
+#* Member: DoEnter Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Eingabe ins Dokument uebernehmen. Wird aufgerufen
+#* nach betaetigen der Uebernehmen- Schaltflaeche
+#* oder einem Doppelklick in die Funktionsliste.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScFunctionDockWin::DoEnter(BOOL /* bOk */) //@@ ???
+{
+ String aFirstArgStr;
+ String aParaStr;
+ String aArgStr;
+ String aString=pAllFuncList->GetSelectEntry();
+ SfxViewShell* pCurSh = SfxViewShell::Current();
+ nArgs=0;
+
+ if(aString.Len()>0)
+ {
+
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pCurSh);
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
+ if(!pScMod->IsEditMode())
+ {
+ pScMod->SetInputMode(SC_INPUT_TABLE);
+ aString = '=';
+ aString += pAllFuncList->GetSelectEntry();
+ if (pHdl)
+ pHdl->ClearText();
+ }
+ const ScFuncDesc* pDesc =
+ (const ScFuncDesc*)pAllFuncList->GetEntryData(
+ pAllFuncList->GetSelectEntryPos() );
+ if (pDesc)
+ {
+ pFuncDesc=pDesc;
+ UpdateLRUList();
+ nArgs = pDesc->nArgCount;
+ if(nArgs>0)
+ {
+ // NOTE: Theoretically the first parameter could have the
+ // suppress flag as well, but practically it doesn't.
+ aFirstArgStr = *(pDesc->ppDefArgNames[0]);
+ aFirstArgStr.EraseLeadingAndTrailingChars();
+ aFirstArgStr.SearchAndReplaceAll(' ', '_');
+ aArgStr = aFirstArgStr;
+ if ( nArgs != VAR_ARGS )
+ { // no VarArgs or Fix plus VarArgs, but not VarArgs only
+ String aArgSep = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "; " ));
+ USHORT nFix = ( nArgs < VAR_ARGS ? nArgs : nArgs - VAR_ARGS + 1 );
+ for ( USHORT nArg = 1;
+ nArg < nFix && !pDesc->pDefArgFlags[nArg].bOptional; nArg++ )
+ {
+ if (!pDesc->pDefArgFlags[nArg].bSuppress)
+ {
+ aArgStr += aArgSep;
+ String sTmp(*(pDesc->ppDefArgNames[nArg]));
+ sTmp.EraseLeadingAndTrailingChars();
+ sTmp.SearchAndReplaceAll(' ', '_');
+ aArgStr += sTmp;
+ }
+ }
+ }
+ }
+ }
+ if (pHdl)
+ {
+ if(pHdl->GetEditString().Len()==0)
+ {
+ aString = '=';
+ aString += pAllFuncList->GetSelectEntry();
+ }
+ EditView *pEdView=pHdl->GetActiveView();
+ if(pEdView!=NULL) // @ Wegen Absturz bei Namen festlegen
+ {
+ if(nArgs>0)
+ {
+ pHdl->InsertFunction(aString);
+ pEdView->InsertText(aArgStr,TRUE);
+ ESelection aESel=pEdView->GetSelection();
+ aESel.nEndPos=aESel.nStartPos+aFirstArgStr.Len();
+ pEdView->SetSelection(aESel);
+ pHdl->DataChanged();
+ }
+ else
+ {
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
+ pEdView->InsertText(aString,FALSE);
+ pHdl->DataChanged();
+ }
+ }
+ }
+ InitLRUList();
+ }
+ if ( pCurSh )
+ {
+ Window* pShellWnd = pCurSh->GetWindow();
+
+ if ( pShellWnd )
+ pShellWnd->GrabFocus();
+ }
+
+
+}
+
+
+
+/*************************************************************************
+#* Handle: SelHdl Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Bei einer Aenderung der Kategorie wird die
+#* die Liste der Funktionen aktualisiert.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScFunctionDockWin, SelHdl, ListBox*, pLb )
+{
+ if ( pLb == &aCatBox)
+ {
+ UpdateFunctionList();
+ SetDescription();
+ }
+
+ if ( pLb == &aFuncList||pLb == &aDDFuncList)
+ {
+ SetDescription();
+ }
+
+
+ //SetSize();
+ return 0;
+}
+
+/*************************************************************************
+#* Handle: SelHdl Datum:06.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Bei einer Aenderung der Kategorie wird die
+#* die Liste der Funktionen aktualisiert.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScFunctionDockWin, SetSelectionHdl, void*, pCtrl )
+{
+ if ((ImageButton *)pCtrl == &aInsertButton ||
+ (ListBox *)pCtrl == &aFuncList)
+ {
+ DoEnter(TRUE); // Uebernimmt die Eingabe
+ }
+ //...
+
+ return 0;
+}
+
+/*************************************************************************
+#* Handle: SetSplitHdl Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScFunctionDockWin
+#*
+#* Funktion: Bei einer Aenderung des Split- Controls werden die
+#* einzelnen Controls an die neue Groesse angepasst.
+#*
+#* Input: Zeiger auf Control
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScFunctionDockWin, SetSplitHdl, ScPrivatSplit*, pCtrl )
+{
+ if (pCtrl == &aPrivatSplit)
+ {
+ short nDeltaY=aPrivatSplit.GetDeltaY();
+ Size aFLSize=aFuncList.GetSizePixel();
+ Size aFDSize=aFiFuncDesc.GetSizePixel();
+ Point aFDTopLeft=aFiFuncDesc.GetPosPixel();
+
+ aFLSize.Height()+=nDeltaY;
+ aFDSize.Height()-=nDeltaY;
+ aFDTopLeft.Y()+=nDeltaY;
+ aFuncList.SetSizePixel(aFLSize);
+ aFiFuncDesc.SetPosPixel(aFDTopLeft);
+ aFiFuncDesc.SetSizePixel(aFDSize);
+ /*
+ aFuncList.Invalidate();
+ aFuncList.Update();
+ aFiFuncDesc.Invalidate();
+ aFiFuncDesc.Update();
+ */
+ }
+ //...
+
+ return 0;
+}
+
+void ScFunctionDockWin::ToggleFloatingMode()
+{
+ aSplitterInitPos = Point();
+ SfxDockingWindow::ToggleFloatingMode();
+
+ eSfxNewAlignment=GetAlignment();
+ eSfxOldAlignment=eSfxNewAlignment;
+
+ aOldSize.Height()=0;
+ aOldSize.Width()=0;
+ aTimer.Start();
+}
+
+IMPL_LINK( ScFunctionDockWin, TimerHdl, Timer*, EMPTYARG )
+{
+ CheckAlignment(eSfxOldAlignment,eSfxNewAlignment);
+ SetSize();
+ return 0;
+}
+
+void ScFunctionDockWin::Initialize(SfxChildWinInfo *pInfo)
+{
+ String aStr;
+ if(pInfo!=NULL)
+ {
+ if ( pInfo->aExtraString.Len() )
+ {
+ xub_StrLen nPos = pInfo->aExtraString.Search(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScFuncList:")));
+
+ // Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
+ // er nicht vorhanden ist, liegt eine "altere Version vor
+ if ( nPos != STRING_NOTFOUND )
+ {
+ xub_StrLen n1 = pInfo->aExtraString.Search('(', nPos);
+ if ( n1 != STRING_NOTFOUND )
+ {
+ xub_StrLen n2 = pInfo->aExtraString.Search(')', n1);
+ if ( n2 != STRING_NOTFOUND )
+ {
+ // Alignment-String herausschneiden
+ aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1);
+ pInfo->aExtraString.Erase(nPos, n2 - nPos + 1);
+ aStr.Erase(0, n1-nPos+1);
+ }
+ }
+ }
+ }
+ }
+ SfxDockingWindow::Initialize(pInfo);
+
+ if ( aStr.Len())
+ {
+ aSplitterInitPos=aPrivatSplit.GetPosPixel();
+ aSplitterInitPos.Y()=(USHORT) aStr.ToInt32();
+ xub_StrLen n1 = aStr.Search(';');
+ aStr.Erase(0, n1+1);
+ USHORT nSelPos=sal::static_int_cast<USHORT>( aStr.ToInt32() );
+ aCatBox.SelectEntryPos(nSelPos);
+ SelHdl(&aCatBox);
+
+ // if the window has already been shown (from SfxDockingWindow::Initialize if docked),
+ // set the splitter position now, otherwise it is set in StateChanged with type INITSHOW
+
+ UseSplitterInitPos();
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void ScFunctionDockWin::FillInfo(SfxChildWinInfo& rInfo) const
+{
+ SfxDockingWindow::FillInfo(rInfo);
+ Point aPoint=aPrivatSplit.GetPosPixel();
+ rInfo.aExtraString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "ScFuncList:(" ));
+ rInfo.aExtraString += String::CreateFromInt32(aPoint.Y());
+ rInfo.aExtraString += ';';
+ rInfo.aExtraString += String::CreateFromInt32(aCatBox.GetSelectEntryPos());
+ rInfo.aExtraString += ')';
+}
+
+void ScFunctionDockWin::UseSplitterInitPos()
+{
+ if ( IsVisible() && aPrivatSplit.IsEnabled() && aSplitterInitPos != Point() )
+ {
+ aPrivatSplit.MoveSplitTo(aSplitterInitPos);
+ aSplitterInitPos = Point(); // use only once
+ }
+}
+
+void ScFunctionDockWin::StateChanged( StateChangedType nStateChange )
+{
+ SfxDockingWindow::StateChanged( nStateChange );
+
+ if (nStateChange == STATE_CHANGE_INITSHOW)
+ {
+ UseSplitterInitPos(); // set initial splitter position if necessary
+ }
+}
+
+
diff --git a/sc/source/ui/formdlg/dwfunctr.hrc b/sc/source/ui/formdlg/dwfunctr.hrc
new file mode 100644
index 000000000000..388fea28b7ca
--- /dev/null
+++ b/sc/source/ui/formdlg/dwfunctr.hrc
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define CB_CAT 1
+#define LB_FUNC 2
+#define DDLB_FUNC 3
+#define IMB_INSERT 1
+#define FI_FUNCDESC 1
+#define FT_SPLIT 2
+
+
+// ********************************************************************** EOF
+
diff --git a/sc/source/ui/formdlg/dwfunctr.src b/sc/source/ui/formdlg/dwfunctr.src
new file mode 100644
index 000000000000..6f8a054dd6ff
--- /dev/null
+++ b/sc/source/ui/formdlg/dwfunctr.src
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+ // include ---------------------------------------------------------------
+#include "sc.hrc"
+#include "dwfunctr.hrc"
+ // pragma ----------------------------------------------------------------
+
+ // RID_SVXDLG_CALCFUNC --------------------------------------------------
+DockingWindow FID_FUNCTION_BOX
+{
+ Border = TRUE ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Sizeable = TRUE ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Zoomable = TRUE ;
+ Dockable = TRUE ;
+ EnableResizing = TRUE ;
+ Size = MAP_APPFONT ( 130 , 160 ) ;
+ HelpId = HID_FUNCTION_BOX ;
+ ListBox CB_CAT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 4 ) ;
+ Size = MAP_APPFONT ( 56 , 80 ) ;
+ DropDown = TRUE ;
+ AutoSize = TRUE ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ AutoHScroll = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Last Used" ; Default ; > ;
+ < "All" ; Default ; > ;
+ < "Database" ; Default ; > ;
+ < "Date&Time" ; Default ; > ;
+ < "Financial" ; Default ; > ;
+ < "Information" ; Default ; > ;
+ < "Logical" ; Default ; > ;
+ < "Mathematical" ; Default ; > ;
+ < "Array" ; Default ; > ;
+ < "Statistical" ; Default ; > ;
+ < "Spreadsheet" ; Default ; > ;
+ < "Text" ; Default ; > ;
+ < "Add-in" ; Default ; > ;
+ };
+ };
+ ListBox DDLB_FUNC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 103 , 4 ) ;
+ Size = MAP_APPFONT ( 56 , 80 ) ;
+ Hide = TRUE ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ AutoHScroll = TRUE ;
+ };
+ ListBox LB_FUNC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 19 ) ;
+ Size = MAP_APPFONT ( 72 , 90 ) ;
+ TabStop = TRUE ;
+ AutoHScroll = TRUE ;
+ };
+ FixedText FI_FUNCDESC
+ {
+ WordBreak = TRUE ;
+ Border = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 115 ) ;
+ Size = MAP_APPFONT ( 72 , 40 ) ;
+ };
+ Control FT_SPLIT
+ {
+ Pos = MAP_APPFONT ( 3 , 110 ) ;
+ Size = MAP_APPFONT ( 72 , 3 ) ;
+ };
+ ImageButton IMB_INSERT
+ {
+ Pos = MAP_APPFONT ( 3 , 4 ) ;
+ Size = MAP_APPFONT ( 13 , 13 ) ;
+ TabStop = TRUE ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap
+ {
+ File = "fx.bmp" ;
+ };
+ MaskColor = STD_MASKCOLOR;
+ };
+ DefButton = TRUE ;
+ QuickHelpText [ en-US ] = "Insert Function into calculation sheet" ;
+ };
+ Text [ en-US ] = "Functions" ;
+};
+ // ********************************************************************** EOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/formdlg/formdata.cxx b/sc/source/ui/formdlg/formdata.cxx
new file mode 100644
index 000000000000..e493e3f7b00f
--- /dev/null
+++ b/sc/source/ui/formdlg/formdata.cxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <tools/debug.hxx>
+
+#include "formdata.hxx"
+
+//============================================================================
+
+ScFormEditData::ScFormEditData() : formula::FormEditData()
+{
+ Reset();
+}
+
+ScFormEditData::~ScFormEditData()
+{
+}
+
+ScFormEditData::ScFormEditData( const ScFormEditData& r ) : formula::FormEditData(r)
+{
+ *this = r;
+}
+// -----------------------------------------------------------------------------
+void ScFormEditData::SaveValues()
+{
+ ScFormEditData* pTemp = new ScFormEditData(*this);
+
+ Reset();
+ pParent = pTemp;
+}
+
+
+
diff --git a/sc/source/ui/formdlg/formdlgs.src b/sc/source/ui/formdlg/formdlgs.src
new file mode 100644
index 000000000000..e3550030c74e
--- /dev/null
+++ b/sc/source/ui/formdlg/formdlgs.src
@@ -0,0 +1,29 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+ //---------------------------------------------------------------------------
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
new file mode 100644
index 000000000000..2d9cdef1b54e
--- /dev/null
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -0,0 +1,667 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//----------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/svtreebx.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <unotools/charclass.hxx>
+#include <tools/urlobj.hxx>
+#include <formula/formulahelper.hxx>
+#include <formula/IFunctionDescription.hxx>
+
+#include "tokenuno.hxx"
+#include "formula.hxx"
+#include "formdata.hxx"
+#include "globstr.hrc"
+#include "scresid.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "tabvwsh.hxx"
+#include "appoptio.hxx"
+#include "docsh.hxx"
+#include "funcdesc.hxx"
+#include "formula/token.hxx"
+#include "tokenarray.hxx"
+#include "sc.hrc"
+#include "servuno.hxx"
+#include "unonames.hxx"
+#include "externalrefmgr.hxx"
+
+#include <com/sun/star/table/CellAddress.hpp>
+
+//============================================================================
+using namespace formula;
+using namespace com::sun::star;
+
+ScDocument* ScFormulaDlg::pDoc = NULL;
+ScAddress ScFormulaDlg::aCursorPos;
+
+
+
+// --------------------------------------------------------------------------
+// Initialisierung / gemeinsame Funktionen fuer Dialog
+// --------------------------------------------------------------------------
+
+ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
+ Window* pParent, ScViewData* pViewData,formula::IFunctionManager* _pFunctionMgr )
+ : formula::FormulaDlg( pB, pCW, pParent, true,true,true,this, _pFunctionMgr,this)
+ , m_aHelper(this,pB)
+{
+ m_aHelper.SetWindow(this);
+ ScModule* pScMod = SC_MOD();
+ pScMod->InputEnterHandler();
+ ScTabViewShell* pScViewShell = NULL;
+
+ // title has to be from the view that opened the dialog,
+ // even if it's not the current view
+
+ SfxObjectShell* pParentDoc = NULL;
+ if ( pB )
+ {
+ SfxDispatcher* pMyDisp = pB->GetDispatcher();
+ if (pMyDisp)
+ {
+ SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
+ if (pMyViewFrm)
+ {
+ pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
+ if( pScViewShell )
+ pScViewShell->UpdateInputHandler(TRUE);
+ pParentDoc = pMyViewFrm->GetObjectShell();
+ }
+ }
+ }
+ //if ( !pParentDoc && pScViewShell ) // use current only if above fails
+ // pParentDoc = pScViewShell->GetObjectShell();
+ //if ( pParentDoc )
+ // aDocName = pParentDoc->GetTitle();
+
+ if ( pDoc == NULL )
+ pDoc = pViewData->GetDocument();
+ 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));
+
+ m_xOpCodeMapper.set(ScServiceProvider::MakeInstance(SC_SERVICE_OPCODEMAPPER,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
+
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
+
+ DBG_ASSERT( pInputHdl, "Missing input handler :-/" );
+
+ if ( pInputHdl )
+ pInputHdl->NotifyChange( NULL );
+
+ m_aHelper.enableInput( FALSE );
+ m_aHelper.EnableSpreadsheets();
+ m_aHelper.Init();
+ m_aHelper.SetDispatcherLock( TRUE );
+
+ notifyChange();
+ fill();
+
+ ScFormEditData* pData = pScMod->GetFormEditData();
+ if (!pData)
+ {
+ //Nun wird es Zeit den Inputhandler festzulegen
+ pScMod->SetRefInputHdl(pScMod->GetInputHdl());
+
+ pDoc = pViewData->GetDocument();
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aCursorPos = ScAddress( nCol, nRow, nTab );
+
+ pScMod->InitFormEditData(); // neu anlegen
+ pData = pScMod->GetFormEditData();
+ pData->SetInputHandler(pScMod->GetInputHdl());
+ pData->SetDocShell(pViewData->GetDocShell());
+
+ DBG_ASSERT(pData,"FormEditData ist nicht da");
+
+ formula::FormulaDlgMode eMode = FORMULA_FORMDLG_FORMULA; // Default...
+
+ // Formel vorhanden? Dann editieren
+
+ String aFormula;
+ pDoc->GetFormula( nCol, nRow, nTab, aFormula );
+ BOOL bEdit = ( aFormula.Len() > 1 );
+ BOOL bMatrix = FALSE;
+ if ( bEdit )
+ {
+ bMatrix = CheckMatrix(aFormula);
+
+ xub_StrLen nFStart = 0;
+ xub_StrLen nFEnd = 0;
+ if ( GetFormulaHelper().GetNextFunc( aFormula, FALSE, nFStart, &nFEnd) )
+ {
+ pScMod->InputReplaceSelection( aFormula );
+ pScMod->InputSetSelection( nFStart, nFEnd );
+ xub_StrLen PrivStart, PrivEnd;
+ pScMod->InputGetSelection( PrivStart, PrivEnd);
+
+ eMode = SetMeText(pScMod->InputGetFormulaStr(),PrivStart, PrivEnd,bMatrix,TRUE,TRUE);
+ pData->SetFStart( nFStart );
+ }
+ else
+ bEdit = FALSE;
+ }
+
+ if ( !bEdit )
+ {
+ String aNewFormula = '=';
+ if ( aFormula.Len() > 0 && aFormula.GetChar(0) == '=' )
+ aNewFormula=aFormula;
+
+ pScMod->InputReplaceSelection( aNewFormula );
+ pScMod->InputSetSelection( 1, aNewFormula.Len()+1 );
+ xub_StrLen PrivStart, PrivEnd;
+ pScMod->InputGetSelection( PrivStart, PrivEnd);
+ SetMeText(pScMod->InputGetFormulaStr(),PrivStart, PrivEnd,bMatrix,FALSE,FALSE);
+
+ pData->SetFStart( 1 ); // hinter dem "="
+ }
+
+ pData->SetMode( (USHORT) eMode );
+ String rStrExp = GetMeText();
+
+ pCell = new ScFormulaCell( pDoc, aCursorPos, rStrExp );
+
+ Update(rStrExp);
+ } // if (!pData)
+
+}
+
+void ScFormulaDlg::notifyChange()
+{
+ ScModule* pScMod = SC_MOD();
+
+ ScInputHandler* pInputHdl = pScMod->GetInputHdl();
+ if ( pInputHdl )
+ pInputHdl->NotifyChange( NULL );
+}
+// -----------------------------------------------------------------------------
+void ScFormulaDlg::fill()
+{
+ ScModule* pScMod = SC_MOD();
+ ScFormEditData* pData = pScMod->GetFormEditData();
+ notifyChange();
+ String rStrExp;
+ if (pData)
+ {
+ // Daten schon vorhanden -> Zustand wiederherstellen (nach Umschalten)
+ // pDoc und aCursorPos nicht neu initialisieren
+ //pDoc = pViewData->GetDocument();
+ if(IsInputHdl(pData->GetInputHandler()))
+ {
+ pScMod->SetRefInputHdl(pData->GetInputHandler());
+ }
+ else
+ {
+ PtrTabViewShell pTabViewShell;
+ ScInputHandler* pInputHdl = GetNextInputHandler(pData->GetDocShell(),&pTabViewShell);
+
+ if ( pInputHdl == NULL ) //DocShell hat keinen InputHandler mehr,
+ { //hat der Anwender halt Pech gehabt.
+ disableOk();
+ pInputHdl = pScMod->GetInputHdl();
+ }
+ else
+ {
+ pInputHdl->SetRefViewShell(pTabViewShell);
+ }
+ pScMod->SetRefInputHdl(pInputHdl);
+ pData->SetInputHandler(pInputHdl);
+ }
+
+ String aOldFormulaTmp(pScMod->InputGetFormulaStr());
+ pScMod->InputSetSelection( 0, aOldFormulaTmp.Len());
+
+ rStrExp=pData->GetUndoStr();
+ pScMod->InputReplaceSelection(rStrExp);
+
+ SetMeText(rStrExp);
+
+ pCell = new ScFormulaCell( pDoc, aCursorPos, rStrExp );
+
+ Update();
+ // Jetzt nochmals zurueckschalten, da evtl. neues Doc geoeffnet wurde!
+ pScMod->SetRefInputHdl(NULL);
+ }
+}
+
+__EXPORT ScFormulaDlg::~ScFormulaDlg()
+{
+ ScModule* pScMod = SC_MOD();
+ ScFormEditData* pData = pScMod->GetFormEditData();
+
+ if (pData) // wird nicht ueber Close zerstoert;
+ {
+ //Referenz Inputhandler zuruecksetzen
+ pScMod->SetRefInputHdl(NULL);
+ } // if (pData) // wird nicht ueber Close zerstoert;
+
+ delete pCell;
+}
+
+BOOL ScFormulaDlg::IsInputHdl(ScInputHandler* pHdl)
+{
+ BOOL bAlive = FALSE;
+
+ // gehoert der InputHandler zu irgendeiner ViewShell ?
+
+ TypeId aScType = TYPE(ScTabViewShell);
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh && !bAlive )
+ {
+ if (((ScTabViewShell*)pSh)->GetInputHandler() == pHdl)
+ bAlive = TRUE;
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+
+ return bAlive;
+
+}
+
+ScInputHandler* ScFormulaDlg::GetNextInputHandler(ScDocShell* pDocShell,PtrTabViewShell* ppViewSh)
+{
+ ScInputHandler* pHdl=NULL;
+
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ while( pFrame && pHdl==NULL)
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
+ if(pViewSh!=NULL)
+ {
+ pHdl=pViewSh->GetInputHandler();
+ if(ppViewSh!=NULL) *ppViewSh=pViewSh;
+ }
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
+ }
+
+
+ return pHdl;
+}
+
+
+BOOL __EXPORT ScFormulaDlg::Close()
+{
+ DoEnter(FALSE);
+ return TRUE;
+}
+
+// --------------------------------------------------------------------------
+// Funktionen fuer rechte Seite
+// --------------------------------------------------------------------------
+bool ScFormulaDlg::calculateValue( const String& rStrExp, String& rStrResult )
+{
+ BOOL bResult = TRUE;
+
+ ::std::auto_ptr<ScFormulaCell> pFCell( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
+
+ // #35521# HACK! um bei ColRowNames kein #REF! zu bekommen,
+ // wenn ein Name eigentlich als Bereich in die Gesamt-Formel
+ // eingefuegt wird, bei der Einzeldarstellung aber als
+ // single-Zellbezug interpretiert wird
+ BOOL bColRowName = pCell->HasColRowName();
+ if ( bColRowName )
+ {
+ // ColRowName im RPN-Code?
+ if ( pCell->GetCode()->GetCodeLen() <= 1 )
+ { // ==1: einzelner ist als Parameter immer Bereich
+ // ==0: es waere vielleicht einer, wenn..
+ String aBraced( '(' );
+ aBraced += rStrExp;
+ aBraced += ')';
+ pFCell.reset( new ScFormulaCell( pDoc, aCursorPos, aBraced ) );
+ }
+ else
+ bColRowName = FALSE;
+ }
+
+ USHORT nErrCode = pFCell->GetErrCode();
+ if ( nErrCode == 0 )
+ {
+ SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable());
+ Color* pColor;
+ if ( pFCell->IsValue() )
+ {
+ double n = pFCell->GetValue();
+ ULONG nFormat = aFormatter.GetStandardFormat( n, 0,
+ pFCell->GetFormatType(), ScGlobal::eLnge );
+ aFormatter.GetOutputString( n, nFormat,
+ rStrResult, &pColor );
+ }
+ else
+ {
+ String aStr;
+
+ pFCell->GetString( aStr );
+ ULONG nFormat = aFormatter.GetStandardFormat(
+ pFCell->GetFormatType(), ScGlobal::eLnge);
+ aFormatter.GetOutputString( aStr, nFormat,
+ rStrResult, &pColor );
+ }
+
+ ScRange aTestRange;
+ if ( bColRowName || (aTestRange.Parse(rStrExp) & SCA_VALID) )
+ rStrResult.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." ));
+ // Bereich
+ }
+ else
+ rStrResult += ScGlobal::GetErrorString(nErrCode);
+
+ if(!isUserMatrix() && pFCell->GetMatrixFlag())
+ {
+ CheckMatrix();
+ }
+
+ return bResult;
+}
+
+
+
+// virtuelle Methoden von ScAnyRefDlg:
+void ScFormulaDlg::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ ::std::pair<formula::RefButton*,formula::RefEdit*> aPair = RefInputStartBefore( pEdit, pButton );
+ m_aHelper.RefInputStart( aPair.second, aPair.first);
+ RefInputStartAfter( aPair.second, aPair.first );
+}
+void ScFormulaDlg::RefInputDone( BOOL bForced )
+{
+ m_aHelper.RefInputDone( bForced );
+ RefInputDoneAfter( bForced );
+}
+
+void ScFormulaDlg::SetReference( const ScRange& rRef, ScDocument* pRefDoc )
+{
+ const IFunctionDescription* pFunc = getCurrentFunctionDescription();
+ if ( pFunc && pFunc->getSuppressedArgumentCount() > 0 )
+ {
+ Selection theSel;
+ BOOL bRefNull = UpdateParaWin(theSel);
+
+ if ( rRef.aStart != rRef.aEnd && bRefNull )
+ {
+ RefInputStart(GetActiveEdit());
+ }
+
+ String aRefStr;
+ BOOL bOtherDoc = ( pRefDoc != pDoc && pRefDoc->GetDocumentShell()->HasName() );
+ if ( bOtherDoc )
+ {
+ // Referenz auf anderes Dokument - wie inputhdl.cxx
+
+ DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");
+
+ String aTmp;
+ rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pRefDoc ); // immer 3d
+
+ SfxObjectShell* pObjSh = pRefDoc->GetDocumentShell();
+
+ // #i75893# convert escaped URL of the document to something user friendly
+// String aFileName = pObjSh->GetMedium()->GetName();
+ String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+
+ aRefStr = '\'';
+ aRefStr += aFileName;
+ aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" ));
+ aRefStr += aTmp;
+ }
+ else
+ {
+ USHORT nFmt = ( rRef.aStart.Tab() == aCursorPos.Tab() )
+ ? SCA_VALID
+ : SCA_VALID | SCA_TAB_3D;
+ rRef.Format( aRefStr, nFmt, pRefDoc, pRefDoc->GetAddressConvention() );
+ }
+
+ UpdateParaWin(theSel,aRefStr);
+ }
+}
+
+BOOL ScFormulaDlg::IsRefInputMode() const
+{
+ const IFunctionDescription* pDesc = getCurrentFunctionDescription();
+ BOOL bRef = (pDesc && (pDesc->getSuppressedArgumentCount() > 0)) && (pDoc!=NULL);
+ return bRef;
+}
+
+BOOL ScFormulaDlg::IsDocAllowed(SfxObjectShell* pDocSh) const
+{
+ // not allowed: different from this doc, and no name
+ // pDocSh is always a ScDocShell
+ if ( pDocSh && ((ScDocShell*)pDocSh)->GetDocument() != pDoc && !pDocSh->HasName() )
+ return FALSE;
+
+ return TRUE; // everything else is allowed
+}
+
+void ScFormulaDlg::SetActive()
+{
+ const IFunctionDescription* pFunc = getCurrentFunctionDescription();
+ if ( pFunc && pFunc->getSuppressedArgumentCount() > 0 )
+ {
+ RefInputDone();
+ SetEdSelection();
+ }
+}
+
+void ScFormulaDlg::SaveLRUEntry(const ScFuncDesc* pFuncDescP)
+{
+ if (pFuncDescP && pFuncDescP->nFIndex!=0)
+ {
+ ScModule* pScMod = SC_MOD();
+ pScMod->InsertEntryToLRUList(pFuncDescP->nFIndex);
+ }
+}
+
+void ScFormulaDlg::doClose(BOOL /*_bOk*/)
+{
+ m_aHelper.DoClose( ScFormulaDlgWrapper::GetChildWindowId() );
+}
+void ScFormulaDlg::insertEntryToLRUList(const formula::IFunctionDescription* _pDesc)
+{
+ const ScFuncDesc* pDesc = dynamic_cast<const ScFuncDesc*>(_pDesc);
+ SaveLRUEntry(pDesc);
+}
+void ScFormulaDlg::showReference(const String& _sFormula)
+{
+ ShowReference(_sFormula);
+}
+void ScFormulaDlg::ShowReference(const String& _sFormula)
+{
+ m_aHelper.ShowReference(_sFormula);
+}
+void ScFormulaDlg::HideReference( BOOL bDoneRefMode )
+{
+ m_aHelper.HideReference(bDoneRefMode);
+}
+void ScFormulaDlg::ViewShellChanged( ScTabViewShell* pScViewShell )
+{
+ m_aHelper.ViewShellChanged( pScViewShell );
+}
+void ScFormulaDlg::AddRefEntry( )
+{
+
+}
+BOOL ScFormulaDlg::IsTableLocked( ) const
+{
+ // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
+ return FALSE;
+}
+void ScFormulaDlg::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton)
+{
+ m_aHelper.ToggleCollapsed(pEdit,pButton);
+}
+void ScFormulaDlg::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton)
+{
+ m_aHelper.ReleaseFocus(pEdit,pButton);
+}
+void ScFormulaDlg::dispatch(BOOL _bOK,BOOL _bMartixChecked)
+{
+ SfxBoolItem aRetItem( SID_DLG_RETOK, _bOK );
+ SfxBoolItem aMatItem( SID_DLG_MATRIX, _bMartixChecked );
+ SfxStringItem aStrItem( SCITEM_STRING, getCurrentFormula() );
+
+ // Wenn durch Dokument-Umschalterei die Eingabezeile weg war/ist,
+ // ist der String leer. Dann nicht die alte Formel loeschen.
+ if ( !aStrItem.GetValue().Len() )
+ aRetItem.SetValue( FALSE ); // FALSE = Cancel
+
+ m_aHelper.SetDispatcherLock( FALSE ); // Modal-Modus ausschalten
+
+ clear();
+
+ GetBindings().GetDispatcher()->Execute( SID_INS_FUNCTION,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ &aRetItem, &aStrItem, &aMatItem, 0L );
+}
+void ScFormulaDlg::setDispatcherLock( BOOL bLock )
+{
+ m_aHelper.SetDispatcherLock( bLock );
+}
+void ScFormulaDlg::setReferenceInput(const formula::FormEditData* _pData)
+{
+ ScModule* pScMod = SC_MOD();
+ ScFormEditData* pData = const_cast<ScFormEditData*>(dynamic_cast<const ScFormEditData*>(_pData));
+ pScMod->SetRefInputHdl(pData->GetInputHandler());
+}
+void ScFormulaDlg::deleteFormData()
+{
+ ScModule* pScMod = SC_MOD();
+ pScMod->ClearFormEditData(); // pData wird ungueltig!
+}
+void ScFormulaDlg::clear()
+{
+ pDoc = NULL;
+
+ //Referenz Inputhandler zuruecksetzen
+ ScModule* pScMod = SC_MOD();
+ pScMod->SetRefInputHdl(NULL);
+
+ // Enable() der Eingabezeile erzwingen:
+ ScTabViewShell* pScViewShell = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+ if ( pScViewShell )
+ pScViewShell->UpdateInputHandler();
+}
+void ScFormulaDlg::switchBack()
+{
+ ScModule* pScMod = SC_MOD();
+ // auf das Dokument zurueckschalten
+ // (noetig, weil ein fremdes oben sein kann - #34222#)
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if ( pHdl )
+ {
+ pHdl->ViewShellGone(NULL); // -> aktive View neu holen
+ pHdl->ShowRefFrame();
+ }
+
+ // aktuelle Tabelle ggF. restaurieren (wg. Maus-RefInput)
+ ScTabViewShell* pScViewShell = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+ if ( pScViewShell )
+ {
+ ScViewData* pVD=pScViewShell->GetViewData();
+ SCTAB nExecTab = aCursorPos.Tab();
+ if ( nExecTab != pVD->GetTabNo() )
+ pScViewShell->SetTabNo( nExecTab );
+
+ SCROW nRow=aCursorPos.Row();
+ SCCOL nCol=aCursorPos.Col();
+
+ if(pVD->GetCurX()!=nCol || pVD->GetCurY()!=nRow)
+ pScViewShell->SetCursor(nCol,nRow);
+ }
+}
+formula::FormEditData* ScFormulaDlg::getFormEditData() const
+{
+ ScModule* pScMod = SC_MOD();
+ return pScMod->GetFormEditData();
+}
+void ScFormulaDlg::setCurrentFormula(const String& _sReplacement)
+{
+ ScModule* pScMod = SC_MOD();
+ pScMod->InputReplaceSelection(_sReplacement);
+}
+void ScFormulaDlg::setSelection(xub_StrLen _nStart,xub_StrLen _nEnd)
+{
+ ScModule* pScMod = SC_MOD();
+ pScMod->InputSetSelection( _nStart, _nEnd );
+}
+void ScFormulaDlg::getSelection(xub_StrLen& _nStart,xub_StrLen& _nEnd) const
+{
+ ScModule* pScMod = SC_MOD();
+ pScMod->InputGetSelection( _nStart, _nEnd );
+}
+String ScFormulaDlg::getCurrentFormula() const
+{
+ ScModule* pScMod = SC_MOD();
+ return pScMod->InputGetFormulaStr();
+}
+formula::IFunctionManager* ScFormulaDlg::getFunctionManager()
+{
+ return ScGlobal::GetStarCalcFunctionMgr();
+}
+uno::Reference< sheet::XFormulaParser> ScFormulaDlg::getFormulaParser() const
+{
+ return m_xParser;
+}
+uno::Reference< sheet::XFormulaOpCodeMapper> ScFormulaDlg::getFormulaOpCodeMapper() const
+{
+ 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());
+ pArray->Fill( _aTokenList, pDoc->GetExternalRefManager());
+ return pArray;
+}
+
diff --git a/sc/source/ui/formdlg/makefile.mk b/sc/source/ui/formdlg/makefile.mk
new file mode 100644
index 000000000000..339e8fa4d581
--- /dev/null
+++ b/sc/source/ui/formdlg/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=formdlgs
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/formula.obj \
+ $(SLO)$/formdata.obj \
+ $(SLO)$/privsplt.obj \
+ $(SLO)$/dwfunctr.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ dwfunctr.src
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/formdlg/privsplt.cxx b/sc/source/ui/formdlg/privsplt.cxx
new file mode 100644
index 000000000000..a3b27ba21b1d
--- /dev/null
+++ b/sc/source/ui/formdlg/privsplt.cxx
@@ -0,0 +1,422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "privsplt.hxx"
+
+/*************************************************************************
+#* Member: ScPrivatSplit Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: MD_Test
+#*
+#* Funktion: Konstruktor der Klasse ScPrivatSplit
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+ScPrivatSplit::ScPrivatSplit( Window* pParent, const ResId& rResId,
+ SC_SPLIT_DIRECTION eSplit):
+ Control( pParent, rResId )
+{
+ Point aPos=GetPosPixel();
+ nOldX=(short)aPos.X();
+ nOldY=(short)aPos.Y();
+ nNewX=(short)aPos.X();
+ nNewY=(short)aPos.Y();
+ eScSplit=eSplit;
+ aXMovingRange.Min()=nNewX;
+ aXMovingRange.Max()=nNewX;
+ aYMovingRange.Min()=nNewY;
+ aYMovingRange.Max()=nNewY;
+
+ aWinPointer=GetPointer();
+
+ aMovingFlag=FALSE;
+ if(eScSplit==SC_SPLIT_HORZ)
+ {
+ aWinPointer=Pointer(POINTER_HSPLIT);
+ }
+ else
+ {
+ aWinPointer=Pointer(POINTER_VSPLIT);
+ }
+ SetPointer(aWinPointer);
+}
+
+
+/*************************************************************************
+#* Member: MouseButtonDown Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Reagiert auf einen einzelnen Mouse-Event. Nach Aufruf
+#* werden alle Mauseingaben an dieses Control weitergeleitet.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScPrivatSplit::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ Point aPos=LogicToPixel(rMEvt.GetPosPixel());
+
+ nOldX=(short)aPos.X();
+ nOldY=(short)aPos.Y();
+
+ CaptureMouse();
+}
+
+/*************************************************************************
+#* Member: MouseButtonUp Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Ende einer Benutzeraktion mit der Maus. Es werden
+#* die aktuelle Maus- Koordinaten ermittelt und fuer
+#* die Verschiebung des Fensters verwendet.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScPrivatSplit::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ ReleaseMouse();
+
+ Point aPos=LogicToPixel(rMEvt.GetPosPixel());
+ Point a2Pos=GetPosPixel();
+ Point a3Pos=a2Pos;
+
+ if(eScSplit==SC_SPLIT_HORZ)
+ {
+ nNewX=(short)aPos.X();
+ nDeltaX=nNewX-nOldX;
+ a2Pos.X()+=nDeltaX;
+ if(a2Pos.X()<aXMovingRange.Min())
+ {
+ nDeltaX=(short)(aXMovingRange.Min()-a3Pos.X());
+ a2Pos.X()=aXMovingRange.Min();
+ }
+ else if(a2Pos.X()>aXMovingRange.Max())
+ {
+ nDeltaX=(short)(aXMovingRange.Max()-a3Pos.X());
+ a2Pos.X()=aXMovingRange.Max();
+ }
+ }
+ else
+ {
+ nNewY=(short)aPos.Y();
+ nDeltaY=nNewY-nOldY;
+ a2Pos.Y()+=nDeltaY;
+ if(a2Pos.Y()<aYMovingRange.Min())
+ {
+ nDeltaY=(short)(aYMovingRange.Min()-a3Pos.Y());
+ a2Pos.Y()=aYMovingRange.Min();
+ }
+ else if(a2Pos.Y()>aYMovingRange.Max())
+ {
+ nDeltaY=(short)(aYMovingRange.Max()-a3Pos.Y());
+ a2Pos.Y()=aYMovingRange.Max();
+ }
+ }
+ SetPosPixel(a2Pos);
+ Invalidate();
+ Update();
+ CtrModified();
+}
+
+/*************************************************************************
+#* Member: MouseMove Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Reagiert kontinuierlich auf Mausbewegungen. Es werden
+#* die aktuelle Maus- Koordinaten ermittelt und fuer
+#* die Verschiebung des Fensters verwendet.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScPrivatSplit::MouseMove( const MouseEvent& rMEvt )
+{
+ Point aPos=LogicToPixel(rMEvt.GetPosPixel());
+ Point a2Pos=GetPosPixel();
+ Point a3Pos=a2Pos;
+ if(rMEvt.IsLeft())
+ {
+ if(eScSplit==SC_SPLIT_HORZ)
+ {
+ nNewX=(short)aPos.X();
+ nDeltaX=nNewX-nOldX;
+ a2Pos.X()+=nDeltaX;
+
+ if(a2Pos.X()<aXMovingRange.Min())
+ {
+ nDeltaX=(short)(aXMovingRange.Min()-a3Pos.X());
+ a2Pos.X()=aXMovingRange.Min();
+ }
+ else if(a2Pos.X()>aXMovingRange.Max())
+ {
+ nDeltaX=(short)(aXMovingRange.Max()-a3Pos.X());
+ a2Pos.X()=aXMovingRange.Max();
+ }
+ }
+ else
+ {
+ nNewY=(short)aPos.Y();
+ nDeltaY=nNewY-nOldY;
+ a2Pos.Y()+=nDeltaY;
+ if(a2Pos.Y()<aYMovingRange.Min())
+ {
+ nDeltaY=(short)(aYMovingRange.Min()-a3Pos.Y());
+ a2Pos.Y()=aYMovingRange.Min();
+ }
+ else if(a2Pos.Y()>aYMovingRange.Max())
+ {
+ nDeltaY=(short)(aYMovingRange.Max()-a3Pos.Y());
+ a2Pos.Y()=aYMovingRange.Max();
+ }
+ }
+
+ SetPosPixel(a2Pos);
+
+ CtrModified();
+ Invalidate();
+ Update();
+ }
+}
+
+/*************************************************************************
+#* Member: SetYRange Datum:14.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Setzt den Range fuer die Y- Verschiebung
+#*
+#* Input: neuer Bereich
+#*
+#* Output: ---
+#*
+#************************************************************************/
+void ScPrivatSplit::SetYRange(Range cRgeY)
+{
+ aYMovingRange=cRgeY;
+}
+
+
+
+/*************************************************************************
+#* Member: GetDeltaY Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Liefert die relative x-Verschiebung zurueck
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+short ScPrivatSplit::GetDeltaX()
+{
+ return nDeltaX;
+}
+
+/*************************************************************************
+#* Member: GetDeltaY Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Liefert die relative y-Verschiebung zurueck
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+short ScPrivatSplit::GetDeltaY()
+{
+ return nDeltaY;
+}
+
+/*************************************************************************
+#* Member: CtrModified Datum:13.10.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScPrivatSplit
+#*
+#* Funktion: Teilt einem installierten Handler mit, dass
+#* eine Veraenderung eingetreten ist.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+void ScPrivatSplit::CtrModified()
+{
+ aCtrModifiedLink.Call( this );
+}
+
+void ScPrivatSplit::MoveSplitTo(Point aPos)
+{
+ Point a2Pos=GetPosPixel();
+ nOldX=(short)a2Pos.X();
+ nOldY=(short)a2Pos.Y();
+ Point a3Pos=a2Pos;
+
+ if(eScSplit==SC_SPLIT_HORZ)
+ {
+ nNewX=(short)aPos.X();
+ nDeltaX=nNewX-nOldX;
+ a2Pos.X()+=nDeltaX;
+ if(a2Pos.X()<aXMovingRange.Min())
+ {
+ nDeltaX=(short)(aXMovingRange.Min()-a3Pos.X());
+ a2Pos.X()=aXMovingRange.Min();
+ }
+ else if(a2Pos.X()>aXMovingRange.Max())
+ {
+ nDeltaX=(short)(aXMovingRange.Max()-a3Pos.X());
+ a2Pos.X()=aXMovingRange.Max();
+ }
+ }
+ else
+ {
+ nNewY=(short)aPos.Y();
+ nDeltaY=nNewY-nOldY;
+ a2Pos.Y()+=nDeltaY;
+ if(a2Pos.Y()<aYMovingRange.Min())
+ {
+ nDeltaY=(short)(aYMovingRange.Min()-a3Pos.Y());
+ a2Pos.Y()=aYMovingRange.Min();
+ }
+ else if(a2Pos.Y()>aYMovingRange.Max())
+ {
+ nDeltaY=(short)(aYMovingRange.Max()-a3Pos.Y());
+ a2Pos.Y()=aYMovingRange.Max();
+ }
+ }
+ SetPosPixel(a2Pos);
+ Invalidate();
+ Update();
+ CtrModified();
+}
+
+
+void ScPrivatSplit::ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetFont( aFont );
+ }
+
+ if ( bFont || bForeground )
+ {
+ Color aTextColor = rStyleSettings.GetButtonTextColor();
+ if ( IsControlForeground() )
+ aTextColor = GetControlForeground();
+ SetTextColor( aTextColor );
+ }
+
+ if ( bBackground )
+ {
+ SetBackground( rStyleSettings.GetFaceColor());
+ }
+ if ( IsBackground() )
+ {
+ SetFillColor( GetBackground().GetColor() );
+ SetBackground();
+ }
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ScPrivatSplit::StateChanged( StateChangedType nType )
+{
+ if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+
+ Control::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void ScPrivatSplit::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+ else
+ Window::DataChanged( rDCEvt );
+}
+
+
diff --git a/sc/source/ui/inc/AccessibilityHints.hxx b/sc/source/ui/inc/AccessibilityHints.hxx
new file mode 100644
index 000000000000..8d966a78fa7f
--- /dev/null
+++ b/sc/source/ui/inc/AccessibilityHints.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ACCESSIBILITYHINTS_HXX
+#define SC_ACCESSIBILITYHINTS_HXX
+
+#include "viewdata.hxx"
+#include <com/sun/star/uno/XInterface.hpp>
+#include <svl/smplhint.hxx>
+#include <svl/hint.hxx>
+
+#define SC_HINT_ACC_SIMPLE_START SFX_HINT_USER00
+#define SC_HINT_ACC_TABLECHANGED SC_HINT_ACC_SIMPLE_START + 1
+#define SC_HINT_ACC_CURSORCHANGED SC_HINT_ACC_SIMPLE_START + 2
+#define SC_HINT_ACC_VISAREACHANGED SC_HINT_ACC_SIMPLE_START + 3
+#define SC_HINT_ACC_ENTEREDITMODE SC_HINT_ACC_SIMPLE_START + 4
+#define SC_HINT_ACC_LEAVEEDITMODE SC_HINT_ACC_SIMPLE_START + 5
+#define SC_HINT_ACC_MAKEDRAWLAYER SC_HINT_ACC_SIMPLE_START + 6
+#define SC_HINT_ACC_WINDOWRESIZED SC_HINT_ACC_SIMPLE_START + 7
+
+class ScAccWinFocusLostHint : public SfxHint
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ xOldAccessible;
+public:
+ TYPEINFO();
+ ScAccWinFocusLostHint(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xOld );
+ ~ScAccWinFocusLostHint();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ GetOldAccessible() const { return xOldAccessible; }
+};
+
+class ScAccWinFocusGotHint : public SfxHint
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ xNewAccessible;
+public:
+ TYPEINFO();
+ ScAccWinFocusGotHint(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xNew );
+ ~ScAccWinFocusGotHint();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ GetNewAccessible() const { return xNewAccessible; }
+};
+
+class ScAccGridWinFocusLostHint : public ScAccWinFocusLostHint
+{
+ ScSplitPos eOldGridWin;
+public:
+ TYPEINFO();
+ ScAccGridWinFocusLostHint( ScSplitPos eOldGridWin,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xOld );
+ ~ScAccGridWinFocusLostHint();
+
+ ScSplitPos GetOldGridWin() const { return eOldGridWin; }
+};
+
+class ScAccGridWinFocusGotHint : public ScAccWinFocusGotHint
+{
+ ScSplitPos eNewGridWin;
+public:
+ TYPEINFO();
+ ScAccGridWinFocusGotHint( ScSplitPos eNewGridWin,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xNew );
+ ~ScAccGridWinFocusGotHint();
+
+ ScSplitPos GetNewGridWin() const { return eNewGridWin; }
+};
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleCell.hxx b/sc/source/ui/inc/AccessibleCell.hxx
new file mode 100644
index 000000000000..38dfdc483886
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleCell.hxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLECELL_HXX
+#define _SC_ACCESSIBLECELL_HXX
+
+#include "AccessibleCellBase.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <editeng/AccessibleStaticTextBase.hxx>
+#include <comphelper/uno3.hxx>
+
+class ScTabViewShell;
+class ScAccessibleDocument;
+
+/** @descr
+ This base class provides an implementation of the
+ <code>AccessibleCell</code> service.
+*/
+class ScAccessibleCell
+ : public ScAccessibleCellBase,
+ public accessibility::AccessibleStaticTextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleCell(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScTabViewShell* pViewShell,
+ ScAddress& rCellAddress,
+ sal_Int32 nIndex,
+ ScSplitPos eSplitPos,
+ ScAccessibleDocument* pAccDoc);
+
+ virtual void Init();
+
+ using ScAccessibleCellBase::disposing;
+ virtual void SAL_CALL disposing();
+
+protected:
+ virtual ~ScAccessibleCell();
+
+ using ScAccessibleCellBase::IsDefunc;
+
+public:
+ ///===== XInterface =====================================================
+
+ DECLARE_XINTERFACE()
+
+ ///===== XTypeProvider ===================================================
+
+ DECLARE_XTYPEPROVIDER()
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ // is overloaded to calculate this on demand
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ // is overloaded to calculate this on demand
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleRelationSet> SAL_CALL
+ getAccessibleRelationSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a list of all supported services.
+ */
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScTabViewShell* mpViewShell;
+ ScAccessibleDocument* mpAccDoc;
+
+ ScSplitPos meSplitPos;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ virtual sal_Bool IsEditable(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ sal_Bool IsOpaque(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ sal_Bool IsSelected();
+
+ ScDocument* GetDocument(ScTabViewShell* mpViewShell);
+
+ ::std::auto_ptr< SvxEditSource > CreateEditSource(ScTabViewShell* pViewShell, ScAddress aCell, ScSplitPos eSplitPos);
+
+ void FillDependends(utl::AccessibleRelationSetHelper* pRelationSet);
+ void FillPrecedents(utl::AccessibleRelationSetHelper* pRelationSet);
+ void AddRelation(const ScAddress& rCell,
+ const sal_uInt16 aRelationType,
+ ::utl::AccessibleRelationSetHelper* pRelationSet);
+ void AddRelation(const ScRange& rRange,
+ const sal_uInt16 aRelationType,
+ ::utl::AccessibleRelationSetHelper* pRelationSet);
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleCellBase.hxx b/sc/source/ui/inc/AccessibleCellBase.hxx
new file mode 100644
index 000000000000..2bcef463480d
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleCellBase.hxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLECELLBASE_HXX
+#define _SC_ACCESSIBLECELLBASE_HXX
+
+#include "AccessibleContextBase.hxx"
+#include "global.hxx"
+#include "address.hxx"
+#include <com/sun/star/accessibility/XAccessibleValue.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class ScTabViewShell;
+
+typedef cppu::ImplHelper1< ::com::sun::star::accessibility::XAccessibleValue>
+ ScAccessibleCellBaseImpl;
+
+class ScAccessibleCellBase
+ : public ScAccessibleContextBase,
+ public ScAccessibleCellBaseImpl
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleCellBase(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDocument* pDoc,
+ const ScAddress& rCellAddress,
+ sal_Int32 nIndex);
+protected:
+ virtual ~ScAccessibleCellBase();
+public:
+
+ ///===== XInterface =====================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual sal_Bool SAL_CALL isVisible( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return this objects index among the parents children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleIndexInParent(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ ///===== XAccessibleValue ================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL
+ getCurrentValue( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ setCurrentValue( const ::com::sun::star::uno::Any& aNumber )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL
+ getMaximumValue( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL
+ getMinimumValue( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /// returns the possible types
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ ScAddress maCellAddress;
+
+ ScDocument* mpDoc;
+
+ sal_Int32 mnIndex;
+
+private:
+ virtual sal_Bool IsEditable(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleContextBase.hxx b/sc/source/ui/inc/AccessibleContextBase.hxx
new file mode 100644
index 000000000000..ecfeff96af39
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleContextBase.hxx
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLECONTEXTBASE_HXX
+#define _SC_ACCESSIBLECONTEXTBASE_HXX
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_IllegalAccessibleComponentStateException_HPP_
+#include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
+#endif
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <vos/mutex.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+
+#include <svl/lstner.hxx>
+#include <cppuhelper/compbase5.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/broadcasthelper.hxx>
+
+class Rectangle;
+
+/** @descr
+ This base class provides an implementation of the
+ <code>AccessibleContext</code> service.
+*/
+
+typedef cppu::WeakAggComponentImplHelper5<
+ ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::lang::XServiceInfo
+ > ScAccessibleContextBaseWeakImpl;
+
+typedef cppu::ImplHelper1<
+ ::com::sun::star::accessibility::XAccessibleEventListener
+ > ScAccessibleContextBaseImplEvent;
+
+class ScAccessibleContextBase
+ : public comphelper::OBaseMutex,
+ public ScAccessibleContextBaseWeakImpl,
+ public ScAccessibleContextBaseImplEvent,
+ public SfxListener
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleContextBase(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ const sal_Int16 aRole);
+
+ virtual void Init();
+ virtual void SAL_CALL disposing();
+protected:
+ virtual ~ScAccessibleContextBase(void);
+public:
+ using WeakAggComponentImplHelperBase::addEventListener;
+ using WeakAggComponentImplHelperBase::removeEventListener;
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XInterface =====================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
+ ///===== XAccessible =====================================================
+
+ /// Return the XAccessibleContext.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext> SAL_CALL
+ getAccessibleContext(void) throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual sal_Bool SAL_CALL containsPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isShowing( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVisible( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void) throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return a reference to the parent.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleParent(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return this objects index among the parents children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleIndexInParent(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return this object's role.
+ virtual sal_Int16 SAL_CALL
+ getAccessibleRole(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ getAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ getAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return NULL to indicate that an empty relation set.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleRelationSet> SAL_CALL
+ getAccessibleRelationSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Return the parents locale or throw exception if this object has no
+ parent yet/anymore.
+ */
+ virtual ::com::sun::star::lang::Locale SAL_CALL
+ getLocale(void)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::accessibility::IllegalAccessibleComponentStateException);
+
+ ///===== XAccessibleEventBroadcaster =====================================
+
+ /** Add listener that is informed of future changes of name,
+ description and so on events.
+ */
+ virtual void SAL_CALL
+ addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ // Remove an existing event listener.
+ virtual void SAL_CALL
+ removeEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleEventListener ========================================
+
+ virtual void SAL_CALL
+ disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ notifyEvent(
+ const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Return whether the specified service is supported by this class.
+ */
+ virtual sal_Bool SAL_CALL
+ supportsService(const ::rtl::OUString& sServiceName)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a list of all supported services. In this case that is just
+ the AccessibleContext and Accessible service.
+ */
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /// returns the possible types
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ /// Calls all Listener to tell they the change.
+ void
+ CommitChange(const com::sun::star::accessibility::AccessibleEventObject& rEvent) const;
+
+ /// change the name and call the listener to tell they the change
+ void
+ ChangeName();
+
+protected:
+ /// Calls all FocusListener to tell they that the focus is gained.
+ void CommitFocusGained() const;
+
+ /// Calls all FocusListener to tell they that the focus is lost.
+ void CommitFocusLost() const;
+
+ sal_Bool IsDefunc() const { return rBHelper.bDisposed; }
+
+ virtual void IsObjectValid() const
+ throw (::com::sun::star::lang::DisposedException);
+
+ /// Use this method to set initial Name without notification
+ void SetName(const rtl::OUString& rName) { msName = rName; }
+ /// Use this method to set initial Description without notification
+ void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; }
+
+ /// Reference to the parent object.
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> mxParent;
+
+private:
+ /** Description of this object. This is not a constant because it can
+ be set from the outside. Furthermore, it changes according the the
+ draw page's display mode.
+ */
+ ::rtl::OUString msDescription;
+
+ /** Name of this object. It changes according the the draw page's
+ display mode.
+ */
+ ::rtl::OUString msName;
+
+ /// client id in the AccessibleEventNotifier queue
+ sal_uInt32 mnClientId;
+
+ /** This is the role of this object.
+ */
+ sal_Int16 maRole;
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleCsvControl.hxx b/sc/source/ui/inc/AccessibleCsvControl.hxx
new file mode 100644
index 000000000000..14f48b51efc1
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleCsvControl.hxx
@@ -0,0 +1,666 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLECSVCONTROL_HXX
+#define _SC_ACCESSIBLECSVCONTROL_HXX
+
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <tools/gen.hxx>
+#include <tools/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <editeng/AccessibleStaticTextBase.hxx>
+#include <comphelper/uno3.hxx>
+#include "AccessibleContextBase.hxx"
+
+
+// ============================================================================
+
+class ScCsvControl;
+namespace utl { class AccessibleStateSetHelper; }
+
+/** Accessible base class used for CSV controls. */
+class ScAccessibleCsvControl : public ScAccessibleContextBase
+{
+protected:
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > XAccessibleRef;
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleRelationSet > XAccessibleRelationSetRef;
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet > XAccessibleStateSetRef;
+
+ typedef ::com::sun::star::awt::Point AwtPoint;
+ typedef ::com::sun::star::awt::Size AwtSize;
+ typedef ::com::sun::star::awt::Rectangle AwtRectangle;
+
+private:
+ ScCsvControl* mpControl; /// Pointer to the VCL control.
+
+public:
+ explicit ScAccessibleCsvControl(
+ const XAccessibleRef& rxParent,
+ ScCsvControl& rControl,
+ sal_uInt16 nRole );
+ virtual ~ScAccessibleCsvControl();
+
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ // XAccessibleComponent ---------------------------------------------------
+
+ /** Returns the child at the specified point (cell returns NULL). */
+ virtual XAccessibleRef SAL_CALL getAccessibleAtPoint( const AwtPoint& rPoint )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns true, if the control is visible. */
+ virtual sal_Bool SAL_CALL isVisible() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Sets the focus to this control. */
+ virtual void SAL_CALL grabFocus() throw( ::com::sun::star::uno::RuntimeException );
+
+ // events -----------------------------------------------------------------
+public:
+ /** Sends a GetFocus or LoseFocus event to all listeners. */
+ virtual void SendFocusEvent( bool bFocused );
+ /** Sends a caret changed event to all listeners. */
+ virtual void SendCaretEvent();
+ /** Sends a visible area changed event to all listeners. */
+ virtual void SendVisibleEvent();
+ /** Sends a selection changed event to all listeners. */
+ virtual void SendSelectionEvent();
+ /** Sends a table model changed event for changed cell contents to all listeners. */
+ virtual void SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows );
+ /** Sends a table model changed event for an inserted column to all listeners. */
+ virtual void SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn );
+ /** Sends a table model changed event for a removed column to all listeners. */
+ virtual void SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn );
+
+ // helpers ----------------------------------------------------------------
+protected:
+ /** Returns this object's current bounding box relative to the desktop. */
+ virtual Rectangle GetBoundingBoxOnScreen() const throw( ::com::sun::star::uno::RuntimeException );
+ /** Returns this object's current bounding box relative to the parent object. */
+ virtual Rectangle GetBoundingBox() const throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Creates a new UUID in rSeq, if it is empty. Locks mutex internally. */
+ void getUuid( ::com::sun::star::uno::Sequence< sal_Int8 >& rSeq );
+
+ /** Returns whether the object is alive. Must be called with locked mutex. */
+ inline bool implIsAlive() const { return !rBHelper.bDisposed && !rBHelper.bInDispose && mpControl; }
+ /** Throws an exception, if the object is disposed/disposing or any pointer
+ is missing. Should be used with locked mutex! */
+ void ensureAlive() const throw( ::com::sun::star::lang::DisposedException );
+
+ /** Returns the VCL control. Assumes a living object. */
+ ScCsvControl& implGetControl() const;
+
+ /** Returns the first child of rxParentObj, which has the role nRole. */
+ XAccessibleRef implGetChildByRole( const XAccessibleRef& rxParentObj, sal_uInt16 nRole )
+ throw( ::com::sun::star::uno::RuntimeException );
+ /** Creates a StateSetHelper and fills it with DEFUNC, OPAQUE, ENABLED, SHOWING and VISIBLE. */
+ ::utl::AccessibleStateSetHelper* implCreateStateSet();
+
+ /** Disposes the object. This is a helper called from destructors only. */
+ void implDispose();
+
+ /** Converts the control-relative position to an absolute screen position. */
+ Point implGetAbsPos( const Point& rPos ) const;
+};
+
+
+// ============================================================================
+
+class ScCsvRuler;
+
+typedef ::cppu::ImplHelper1<
+ ::com::sun::star::accessibility::XAccessibleText >
+ ScAccessibleCsvRulerImpl;
+
+/** Accessible class representing the CSV ruler control. */
+class ScAccessibleCsvRuler : public ScAccessibleCsvControl, public ScAccessibleCsvRulerImpl
+{
+protected:
+ typedef ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue > PropertyValueSeq;
+
+private:
+ ::rtl::OUStringBuffer maBuffer; /// Contains the text representation of the ruler.
+
+public:
+ explicit ScAccessibleCsvRuler( ScCsvRuler& rRuler );
+ virtual ~ScAccessibleCsvRuler();
+
+ // XAccessibleComponent -----------------------------------------------------
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext -----------------------------------------------------
+
+ /** Returns the child count (the ruler does not have children). */
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Throws an exception (the ruler does not have childern). */
+ virtual XAccessibleRef SAL_CALL getAccessibleChild( sal_Int32 nIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the relation to the grid control. */
+ virtual XAccessibleRelationSetRef SAL_CALL getAccessibleRelationSet()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the current set of states. */
+ virtual XAccessibleStateSetRef SAL_CALL getAccessibleStateSet()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XAccessibleText --------------------------------------------------------
+
+ /** Return the position of the caret. */
+ virtual sal_Int32 SAL_CALL getCaretPosition() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Sets the position of the caret. */
+ virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the specified character. */
+ virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the attributes of the specified character. */
+ virtual PropertyValueSeq SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the screen coordinates of the specified character. */
+ virtual AwtRectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the count of characters. */
+ virtual sal_Int32 SAL_CALL getCharacterCount() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the character index at the specified coordinate (object's coordinate system). */
+ virtual sal_Int32 SAL_CALL getIndexAtPoint( const AwtPoint& rPoint )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the selected text (ruler returns empty string). */
+ virtual ::rtl::OUString SAL_CALL getSelectedText() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the start index of the selection (ruler returns -1). */
+ virtual sal_Int32 SAL_CALL getSelectionStart() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the end index of the selection (ruler returns -1). */
+ virtual sal_Int32 SAL_CALL getSelectionEnd() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Selects a part of the text (ruler does nothing). */
+ virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the entire text. */
+ virtual ::rtl::OUString SAL_CALL getText() throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the specified range [Start,End) of the text. */
+ virtual ::rtl::OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the specified text portion. */
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ /** Copies the specified text range into the clipboard (ruler does nothing). */
+ virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ // XInterface -------------------------------------------------------------
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL acquire() throw();
+
+ virtual void SAL_CALL release() throw();
+
+ // XServiceInfo -----------------------------------------------------------
+
+ /** Returns an identifier for the implementation of this object. */
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XTypeProvider ----------------------------------------------------------
+
+ /** Returns a sequence with all supported interface types. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns an implementation ID. */
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // events -----------------------------------------------------------------
+public:
+ /** Sends a caret changed event to all listeners. */
+ virtual void SendCaretEvent();
+
+ // helpers ----------------------------------------------------------------
+private:
+ /** Returns this object's name. */
+ virtual ::rtl::OUString SAL_CALL createAccessibleName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ /** Returns this object's description. */
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Throws an exception, if the specified character position is invalid (outside 0..len-1). */
+ void ensureValidIndex( sal_Int32 nIndex ) const
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException );
+ /** Throws an exception, if the specified character position is invalid (outside 0..len). */
+ void ensureValidIndexWithEnd( sal_Int32 nIndex ) const
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException );
+ /** Throws an exception, if the specified character range [Start,End) is invalid.
+ @descr If Start>End, swaps Start and End before checking. */
+ void ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException );
+
+ /** Returns the VCL ruler control. Assumes a living object. */
+ ScCsvRuler& implGetRuler() const;
+
+ /** Builds the entire string buffer. */
+ void constructStringBuffer() throw( ::com::sun::star::uno::RuntimeException );
+ /** Returns the character count of the text. */
+ sal_Int32 implGetTextLength() const;
+
+ /** Returns true, if the character at the specified index has a split. */
+ bool implHasSplit( sal_Int32 nApiPos );
+
+ /** Returns the first character index with equal formatting as at nApiPos. */
+ sal_Int32 implGetFirstEqualFormatted( sal_Int32 nApiPos );
+ /** Returns the last character index with equal formatting as at nApiPos. */
+ sal_Int32 implGetLastEqualFormatted( sal_Int32 nApiPos );
+};
+
+
+// ============================================================================
+
+class ScCsvGrid;
+
+typedef ::cppu::ImplHelper2<
+ ::com::sun::star::accessibility::XAccessibleTable,
+ ::com::sun::star::accessibility::XAccessibleSelection >
+ ScAccessibleCsvGridImpl;
+
+/** Accessible class representing the CSV grid control. */
+class ScAccessibleCsvGrid : public ScAccessibleCsvControl, public ScAccessibleCsvGridImpl
+{
+protected:
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleTable > XAccessibleTableRef;
+
+public:
+ explicit ScAccessibleCsvGrid( ScCsvGrid& rGrid );
+ virtual ~ScAccessibleCsvGrid();
+
+ // XAccessibleComponent ---------------------------------------------------
+
+ /** Returns the cell at the specified point. */
+ virtual XAccessibleRef SAL_CALL getAccessibleAtPoint( const AwtPoint& rPoint )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext -----------------------------------------------------
+
+ /** Returns the child count (count of cells in the table). */
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the specified child cell. */
+ virtual XAccessibleRef SAL_CALL getAccessibleChild( sal_Int32 nIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the relation to the ruler control. */
+ virtual XAccessibleRelationSetRef SAL_CALL getAccessibleRelationSet()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the current set of states. */
+ virtual XAccessibleStateSetRef SAL_CALL getAccessibleStateSet()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XAccessibleTable -------------------------------------------------------
+
+ /** Returns the number of rows in the table. */
+ virtual sal_Int32 SAL_CALL getAccessibleRowCount()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the number of columns in the table. */
+ virtual sal_Int32 SAL_CALL getAccessibleColumnCount()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the description of the specified row in the table. */
+ virtual ::rtl::OUString SAL_CALL getAccessibleRowDescription( sal_Int32 nRow )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the description text of the specified column in the table. */
+ virtual ::rtl::OUString SAL_CALL getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the number of rows occupied at a specified row and column.
+ @descr Returns always 1 (Merged cells not supported). */
+ virtual sal_Int32 SAL_CALL getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the number of rows occupied at a specified row and column.
+ @descr Returns always 1 (Merged cells not supported). */
+ virtual sal_Int32 SAL_CALL getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the row headers as an AccessibleTable. */
+ virtual XAccessibleTableRef SAL_CALL getAccessibleRowHeaders()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the column headers as an AccessibleTable. */
+ virtual XAccessibleTableRef SAL_CALL getAccessibleColumnHeaders()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the selected rows as a sequence. */
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL getSelectedAccessibleRows()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the selected columns as a sequence. */
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL getSelectedAccessibleColumns()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns true, if the specified row is selected. */
+ virtual sal_Bool SAL_CALL isAccessibleRowSelected( sal_Int32 nRow )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns true, if the specified column is selected. */
+ virtual sal_Bool SAL_CALL isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the accessible cell object at the specified position. */
+ virtual XAccessibleRef SAL_CALL getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the caption object of the table. */
+ virtual XAccessibleRef SAL_CALL getAccessibleCaption()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the summary description object of the table. */
+ virtual XAccessibleRef SAL_CALL getAccessibleSummary()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns true, if the cell at a specified position is selected. */
+ virtual sal_Bool SAL_CALL isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the child index of the cell at the specified position. */
+ virtual sal_Int32 SAL_CALL getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the row index of the specified child. */
+ virtual sal_Int32 SAL_CALL getAccessibleRow( sal_Int32 nChildIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the column index of the specified child. */
+ virtual sal_Int32 SAL_CALL getAccessibleColumn( sal_Int32 nChildIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ // XAccessibleSelection ---------------------------------------------------
+
+ /** Selects the specified child (selects the entire column or the entire table). */
+ virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns true, if the specified child is selected. */
+ virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Deselects all cells. */
+ virtual void SAL_CALL clearAccessibleSelection()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Selects all cells. */
+ virtual void SAL_CALL selectAllAccessibleChildren()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the count of selected children. */
+ virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the child with the specified index in all selected children. */
+ virtual XAccessibleRef SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Deselects the child with the specified index in all selected children. */
+ virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ // XInterface -------------------------------------------------------------
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL acquire() throw();
+
+ virtual void SAL_CALL release() throw();
+
+ // XServiceInfo -----------------------------------------------------------
+
+ /** Returns an identifier for the implementation of this object. */
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XTypeProvider ----------------------------------------------------------
+
+ /** Returns a sequence with all supported interface types. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns an implementation ID. */
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // events -----------------------------------------------------------------
+public:
+ /** Sends a GetFocus or LoseFocus event to all listeners. */
+ virtual void SendFocusEvent( bool bFocused );
+ /** Sends a table model changed event for changed cell contents to all listeners. */
+ virtual void SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows );
+ /** Sends a table model changed event for an inserted column to all listeners. */
+ virtual void SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn );
+ /** Sends a table model changed event for a removed column to all listeners. */
+ virtual void SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn );
+
+ // helpers ----------------------------------------------------------------
+private:
+ /** Returns this object's name. */
+ virtual ::rtl::OUString SAL_CALL createAccessibleName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ /** Returns this object's description. */
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Throws an exception, if nIndex is not a valid child index. */
+ void ensureValidIndex( sal_Int32 nIndex ) const
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException );
+ /** Throws an exception, if the specified position is invalid. */
+ void ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException );
+
+ /** Returns the VCL grid control. Assumes a living object. */
+ ScCsvGrid& implGetGrid() const;
+
+ /** Returns true, if the specified column (including header) is selected. */
+ bool implIsColumnSelected( sal_Int32 nColumn ) const;
+ /** Selects the specified column (including header). */
+ void implSelectColumn( sal_Int32 nColumn, bool bSelect );
+
+ /** Returns the count of visible rows in the table (including header). */
+ sal_Int32 implGetRowCount() const;
+ /** Returns the total column count in the table (including header). */
+ sal_Int32 implGetColumnCount() const;
+ /** Returns the count of selected columns in the table. */
+ sal_Int32 implGetSelColumnCount() const;
+ /** Returns the total cell count in the table (including header). */
+ inline sal_Int32 implGetCellCount() const { return implGetRowCount() * implGetColumnCount(); }
+
+ /** Returns the row index from cell index (including header). */
+ inline sal_Int32 implGetRow( sal_Int32 nIndex ) const { return nIndex / implGetColumnCount(); }
+ /** Returns the column index from cell index (including header). */
+ inline sal_Int32 implGetColumn( sal_Int32 nIndex ) const { return nIndex % implGetColumnCount(); }
+ /** Returns the absolute column index of the nSelColumn-th selected column. */
+ sal_Int32 implGetSelColumn( sal_Int32 nSelColumn ) const;
+ /** Returns the child index from cell position (including header). */
+ inline sal_Int32 implGetIndex( sal_Int32 nRow, sal_Int32 nColumn ) const { return nRow * implGetColumnCount() + nColumn; }
+
+ /** Returns the contents of the specified cell (including header). Indexes must be valid. */
+ String implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const;
+ /** Creates a new accessible object of the specified cell. Indexes must be valid. */
+ ScAccessibleCsvControl* implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const;
+};
+
+
+// ============================================================================
+
+/** Accessible class representing a cell of the CSV grid control. */
+class ScAccessibleCsvCell : public ScAccessibleCsvControl, public accessibility::AccessibleStaticTextBase
+{
+protected:
+ typedef ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue > PropertyValueSeq;
+ typedef ::std::auto_ptr< SvxEditSource > SvxEditSourcePtr;
+
+private:
+ String maCellText; /// The text contents of this cell.
+ sal_Int32 mnLine; /// The grid line index (core index).
+ sal_uInt32 mnColumn; /// The grid column index (core index).
+ sal_Int32 mnIndex; /// The index of the cell in the table.
+
+public:
+ explicit ScAccessibleCsvCell(
+ ScCsvGrid& rGrid,
+ const String& rCellText,
+ sal_Int32 nRow, sal_Int32 nColumn );
+ virtual ~ScAccessibleCsvCell();
+
+ using ScAccessibleCsvControl::disposing;
+ virtual void SAL_CALL disposing();
+
+ // XAccessibleComponent ---------------------------------------------------
+
+ /** Sets the focus to the column of this cell. */
+ virtual void SAL_CALL grabFocus() throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext -----------------------------------------------------
+
+ /** Returns the child count. */
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the specified child. */
+ virtual XAccessibleRef SAL_CALL getAccessibleChild( sal_Int32 nIndex )
+ throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the index of this cell in the table. */
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the relation to the ruler control. */
+ virtual XAccessibleRelationSetRef SAL_CALL getAccessibleRelationSet()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the current set of states. */
+ virtual XAccessibleStateSetRef SAL_CALL getAccessibleStateSet()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XInterface -------------------------------------------------------------
+
+ DECLARE_XINTERFACE()
+
+ // XTypeProvider ----------------------------------------------------------
+
+ DECLARE_XTYPEPROVIDER()
+
+ // XServiceInfo -----------------------------------------------------------
+
+ /** Returns an identifier for the implementation of this object. */
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // helpers ----------------------------------------------------------------
+protected:
+ /** Returns this object's current bounding box relative to the desktop. */
+ virtual Rectangle GetBoundingBoxOnScreen() const throw( ::com::sun::star::uno::RuntimeException );
+ /** Returns this object's current bounding box relative to the parent object. */
+ virtual Rectangle GetBoundingBox() const throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ /** Returns this object's name. */
+ virtual ::rtl::OUString SAL_CALL createAccessibleName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ /** Returns this object's description. */
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Returns the VCL grid control. Assumes a living object. */
+ ScCsvGrid& implGetGrid() const;
+ /** Returns the pixel position of the cell (rel. to parent), regardless of visibility. */
+ Point implGetRealPos() const;
+ /** Returns the width of the character count */
+ sal_uInt32 implCalcPixelWidth(sal_uInt32 nChars) const;
+ /** Returns the pixel size of the cell, regardless of visibility. */
+ Size implGetRealSize() const;
+ /** Returns the bounding box of the cell relative in the table. */
+ Rectangle implGetBoundingBox() const;
+
+ /** Creates the edit source the text helper needs. */
+ ::std::auto_ptr< SvxEditSource > implCreateEditSource();
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/AccessibleDataPilotControl.hxx b/sc/source/ui/inc/AccessibleDataPilotControl.hxx
new file mode 100644
index 000000000000..c86d598b6e9c
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleDataPilotControl.hxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLEDATAPILOTCONTROL_HXX
+#define _SC_ACCESSIBLEDATAPILOTCONTROL_HXX
+
+#include "AccessibleContextBase.hxx"
+
+class ScDPFieldWindow;
+class ScAccessibleDataPilotButton;
+
+class ScAccessibleDataPilotControl
+ : public ScAccessibleContextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleDataPilotControl(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow);
+
+ virtual void Init();
+
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ void AddField(sal_Int32 nNewIndex);
+ void RemoveField(sal_Int32 nOldIndex);
+ void FieldFocusChange(sal_Int32 nOldIndex, sal_Int32 nNewIndex);
+ void FieldNameChange(sal_Int32 nIndex);
+ void GotFocus();
+ void LostFocus();
+protected:
+ virtual ~ScAccessibleDataPilotControl(void);
+public:
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVisible( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void) throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScDPFieldWindow* mpDPFieldWindow;
+ struct AccessibleWeak
+ {
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xWeakAcc;
+ ScAccessibleDataPilotButton* pAcc;
+ AccessibleWeak() : pAcc(NULL) {}
+ };
+ ::std::vector< AccessibleWeak > maChildren;
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleDocument.hxx b/sc/source/ui/inc/AccessibleDocument.hxx
new file mode 100644
index 000000000000..2ec612e0865b
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleDocument.hxx
@@ -0,0 +1,328 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLEDOCUMENT_HXX
+#define _SC_ACCESSIBLEDOCUMENT_HXX
+
+#include "AccessibleDocumentBase.hxx"
+#include "viewdata.hxx"
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/view/XSelectionChangeListener.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <svx/IAccessibleViewForwarder.hxx>
+
+class ScTabViewShell;
+class ScAccessibleSpreadsheet;
+class ScChildrenShapes;
+class ScAccessibleEditObject;
+
+namespace accessibility
+{
+ class AccessibleShape;
+}
+namespace utl
+{
+ class AccessibleRelationSetHelper;
+}
+
+/** @descr
+ This base class provides an implementation of the
+ <code>AccessibleContext</code> service.
+*/
+
+typedef cppu::ImplHelper2< ::com::sun::star::accessibility::XAccessibleSelection,
+ ::com::sun::star::view::XSelectionChangeListener >
+ ScAccessibleDocumentImpl;
+
+class ScAccessibleDocument
+ : public ScAccessibleDocumentBase,
+ public ScAccessibleDocumentImpl,
+ public accessibility::IAccessibleViewForwarder
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleDocument(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScTabViewShell* pViewShell,
+ ScSplitPos eSplitPos);
+
+ virtual void Init();
+
+
+ DECL_LINK( WindowChildEventListener, VclSimpleEvent* );
+protected:
+ virtual ~ScAccessibleDocument(void);
+
+ using ScAccessibleDocumentBase::IsDefunc;
+
+public:
+
+ virtual void SAL_CALL disposing();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XInterface =====================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleSelection ===========================================
+
+ virtual void SAL_CALL
+ selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ clearAccessibleSelection( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ selectAllAccessibleChildren( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ getSelectedAccessibleChildCount( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ ///===== XSelectionListener =============================================
+
+ virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ===================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a list of all supported services.
+ */
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /// returns the possible types
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== IAccessibleViewForwarder ========================================
+
+ /** This method informs you about the state of the forwarder. Do not
+ use it when the returned value is <false/>.
+
+ @return
+ Return <true/> if the view forwarder is valid and <false/> else.
+ */
+ virtual sal_Bool IsValid (void) const;
+
+ /** Returns the area of the underlying document that is visible in the
+ * corresponding window.
+
+ @return
+ The rectangle of the visible part of the document. The values
+ are, contrary to the base class, in internal coordinates.
+ */
+ virtual Rectangle GetVisibleArea() const;
+
+ /** Transform the specified point from internal coordinates to an
+ absolute screen position.
+
+ @param rPoint
+ Point in internal coordinates.
+
+ @return
+ The same point but in screen coordinates relative to the upper
+ left corner of the (current) screen.
+ */
+ virtual Point LogicToPixel (const Point& rPoint) const;
+
+ /** Transform the specified size from internal coordinates to a screen
+ * oriented pixel size.
+
+ @param rSize
+ Size in internal coordinates.
+
+ @return
+ The same size but in screen coordinates.
+ */
+ virtual Size LogicToPixel (const Size& rSize) const;
+
+ /** Transform the specified point from absolute screen coordinates to
+ internal coordinates.
+
+ @param rPoint
+ Point in screen coordinates relative to the upper left corner of
+ the (current) screen.
+
+ @return
+ The same point but in internal coordinates.
+ */
+ virtual Point PixelToLogic (const Point& rPoint) const;
+
+ /** Transform the specified size from screen coordinates to internal
+ coordinates.
+
+ @param rSize
+ Size in screen coordinates.
+
+ @return
+ The same size but in internal coordinates.
+ */
+ virtual Size PixelToLogic (const Size& rSize) const;
+
+ ///======== internal =====================================================
+
+ utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;
+
+ ::com::sun::star::uno::Reference
+ < ::com::sun::star::accessibility::XAccessible >
+ GetAccessibleSpreadsheet();
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScTabViewShell* mpViewShell;
+ ScSplitPos meSplitPos;
+ ScAccessibleSpreadsheet* mpAccessibleSpreadsheet;
+ ScChildrenShapes* mpChildrenShapes;
+ ScAccessibleEditObject* mpTempAccEdit;
+ com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> mxTempAcc;
+ Rectangle maVisArea;
+ sal_Bool mbCompleteSheetSelected;
+
+public:
+ SCTAB getVisibleTable() const; // use it in ScChildrenShapes
+
+private:
+ void FreeAccessibleSpreadsheet();
+
+ sal_Bool IsTableSelected() const;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ sal_Bool IsEditable(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ void AddChild(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>& xAcc, sal_Bool bFireEvent);
+ void RemoveChild(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>& xAcc, sal_Bool bFireEvent);
+
+ rtl::OUString GetCurrentCellName() const;
+ rtl::OUString GetCurrentCellDescription() const;
+
+ Rectangle GetVisibleArea_Impl() const;
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleDocumentBase.hxx b/sc/source/ui/inc/AccessibleDocumentBase.hxx
new file mode 100644
index 000000000000..fc76a8d771cf
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleDocumentBase.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEDOCUMENTBASE_HXX
+#define _SC_ACCESSIBLEDOCUMENTBASE_HXX
+
+#ifndef _SC_ACCESSIBLE_CONTEXT_BASE_HXX
+#include "AccessibleContextBase.hxx"
+#endif
+
+class ScAccessibleDocumentBase
+ : public ScAccessibleContextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleDocumentBase(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent);
+protected:
+ virtual ~ScAccessibleDocumentBase (void);
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/AccessibleDocumentPagePreview.hxx b/sc/source/ui/inc/AccessibleDocumentPagePreview.hxx
new file mode 100644
index 000000000000..8ce9050c6094
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleDocumentPagePreview.hxx
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEDOCUMENTPAGEPREVIEW_HXX
+#define _SC_ACCESSIBLEDOCUMENTPAGEPREVIEW_HXX
+
+#include "AccessibleDocumentBase.hxx"
+
+class ScPreviewShell;
+class ScNotesChilds;
+class ScShapeChilds;
+class ScAccessiblePreviewTable;
+class ScAccessiblePageHeader;
+
+class ScAccessibleDocumentPagePreview
+ : public ScAccessibleDocumentBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleDocumentPagePreview(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell );
+protected:
+ virtual ~ScAccessibleDocumentPagePreview(void);
+
+ using ScAccessibleDocumentBase::IsDefunc;
+
+public:
+ using ScAccessibleContextBase::disposing;
+
+ virtual void SAL_CALL disposing();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a list of all supported services.
+ */
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== internal ========================================================
+
+//UNUSED2009-05 com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible >
+//UNUSED2009-05 GetCurrentAccessibleTable();
+
+//UNUSED2009-05 void ChildCountChanged();
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+public: // needed in ScShapeChilds
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScPreviewShell* mpViewShell;
+ ScNotesChilds* mpNotesChilds;
+ ScShapeChilds* mpShapeChilds;
+ ScAccessiblePreviewTable* mpTable;
+ ScAccessiblePageHeader* mpHeader;
+ ScAccessiblePageHeader* mpFooter;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ ScNotesChilds* GetNotesChilds();
+ ScShapeChilds* GetShapeChilds();
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleEditObject.hxx b/sc/source/ui/inc/AccessibleEditObject.hxx
new file mode 100644
index 000000000000..55bb92f13424
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleEditObject.hxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEEDITOBJECT_HXX
+#define _SC_ACCESSIBLEEDITOBJECT_HXX
+
+#include "AccessibleContextBase.hxx"
+
+namespace accessibility
+{
+ class AccessibleTextHelper;
+}
+class EditView;
+class Window;
+
+enum EditObjectType
+{
+ CellInEditMode,
+ EditLine,
+ EditControl
+};
+
+/** @descr
+ This base class provides an implementation of the
+ <code>AccessibleCell</code> service.
+*/
+class ScAccessibleEditObject
+ : public ScAccessibleContextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleEditObject(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ EditView* pEditView, Window* pWin, const rtl::OUString& rName,
+ const rtl::OUString& rDescription, EditObjectType eObjectType);
+
+protected:
+ virtual ~ScAccessibleEditObject();
+
+ using ScAccessibleContextBase::IsDefunc;
+
+public:
+ using ScAccessibleContextBase::addEventListener;
+ using ScAccessibleContextBase::removeEventListener;
+ using ScAccessibleContextBase::disposing;
+
+ virtual void SAL_CALL disposing();
+
+ virtual void LostFocus();
+
+ virtual void GotFocus();
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ // is overloaded to calculate this on demand
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ // is overloaded to calculate this on demand
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ ///===== XAccessibleEventBroadcaster =====================================
+
+ /** Add listener that is informed of future changes of name,
+ description and so on events.
+ */
+ virtual void SAL_CALL
+ addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ // Remove an existing event listener.
+ virtual void SAL_CALL
+ removeEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ accessibility::AccessibleTextHelper* mpTextHelper;
+ EditView* mpEditView;
+ Window* mpWindow;
+ EditObjectType meObjectType;
+ sal_Bool mbHasFocus;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ void CreateTextHelper();
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessiblePageHeader.hxx b/sc/source/ui/inc/AccessiblePageHeader.hxx
new file mode 100644
index 000000000000..1e28670419a4
--- /dev/null
+++ b/sc/source/ui/inc/AccessiblePageHeader.hxx
@@ -0,0 +1,111 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEPAGEHEADER_HXX
+#define _SC_ACCESSIBLEPAGEHEADER_HXX
+
+#include "AccessibleContextBase.hxx"
+#include <editeng/svxenum.hxx>
+
+class ScPreviewShell;
+class EditTextObject;
+class ScAccessiblePageHeaderArea;
+class ScPreviewShell;
+
+class ScAccessiblePageHeader : public ScAccessibleContextBase
+{
+public:
+ ScAccessiblePageHeader( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, sal_Bool bHeader, sal_Int32 nIndex );
+
+protected:
+ virtual ~ScAccessiblePageHeader();
+
+ using ScAccessibleContextBase::IsDefunc;
+
+public:
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ //===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ //===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XAccessibleContext ==============================================
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleChild( sal_Int32 i )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
+ getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XServiceInfo ====================================================
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ //===== internal ========================================================
+ void SetCurrentIndexInParent(sal_Int32 nNew) { mnIndex = nNew; }
+
+protected:
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL createAccessibleName(void) throw (::com::sun::star::uno::RuntimeException);
+
+ virtual Rectangle GetBoundingBoxOnScreen(void) const throw(::com::sun::star::uno::RuntimeException);
+ virtual Rectangle GetBoundingBox(void) const throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScPreviewShell* mpViewShell;
+ sal_Int32 mnIndex;
+ sal_Bool mbHeader;
+ typedef std::vector< ScAccessiblePageHeaderArea* > ScHFAreas;
+ ScHFAreas maAreas;
+ sal_Int32 mnChildCount;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ void AddChild(const EditTextObject* pArea, sal_uInt32 nIndex, SvxAdjust eAdjust);
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessiblePageHeaderArea.hxx b/sc/source/ui/inc/AccessiblePageHeaderArea.hxx
new file mode 100644
index 000000000000..dbf7c126b617
--- /dev/null
+++ b/sc/source/ui/inc/AccessiblePageHeaderArea.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEPAGEHEADERAREA_HXX
+#define _SC_ACCESSIBLEPAGEHEADERAREA_HXX
+
+#ifndef _SC_ACCESSIBLE_CONTEXT_BASE_HXX
+#include "AccessibleContextBase.hxx"
+#endif
+#include <editeng/svxenum.hxx>
+
+class EditTextObject;
+namespace accessibility
+{
+ class AccessibleTextHelper;
+}
+class ScPreviewShell;
+
+class ScAccessiblePageHeaderArea
+ : public ScAccessibleContextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessiblePageHeaderArea(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell,
+ const EditTextObject* pEditObj,
+ sal_Bool bHeader,
+ SvxAdjust eAdjust);
+protected:
+ virtual ~ScAccessiblePageHeaderArea (void);
+public:
+ const EditTextObject* GetEditTextObject() const { return mpEditObj; }
+
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ // is overloaded to calculate this on demand
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ // is overloaded to calculate this on demand
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a list of all supported services. In this case that is just
+ the AccessibleContext and Accessible service.
+ */
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL createAccessibleName(void) throw (::com::sun::star::uno::RuntimeException);
+
+ virtual Rectangle GetBoundingBoxOnScreen(void) const throw(::com::sun::star::uno::RuntimeException);
+ virtual Rectangle GetBoundingBox(void) const throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ EditTextObject* mpEditObj;
+ accessibility::AccessibleTextHelper* mpTextHelper;
+ ScPreviewShell* mpViewShell;
+ sal_Bool mbHeader;
+ SvxAdjust meAdjust;
+
+ void CreateTextHelper();
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/AccessiblePreviewCell.hxx b/sc/source/ui/inc/AccessiblePreviewCell.hxx
new file mode 100644
index 000000000000..47a2be3b6713
--- /dev/null
+++ b/sc/source/ui/inc/AccessiblePreviewCell.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEPREVIEWCELL_HXX
+#define _SC_ACCESSIBLEPREVIEWCELL_HXX
+
+#include "AccessibleCellBase.hxx"
+
+class ScPreviewShell;
+
+namespace accessibility
+{
+ class AccessibleTextHelper;
+}
+
+class ScAccessiblePreviewCell : public ScAccessibleCellBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessiblePreviewCell(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, /* const */ ScAddress& rCellAddress, sal_Int32 nIndex );
+
+protected:
+ virtual ~ScAccessiblePreviewCell();
+
+ using ScAccessibleCellBase::IsDefunc;
+
+public:
+ using ScAccessibleCellBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ //===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XAccessibleContext ==============================================
+
+ // overloaded to calculate this on demand
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleChild( sal_Int32 i )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
+ getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XServiceInfo ====================================================
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ virtual Rectangle GetBoundingBoxOnScreen(void) const throw(::com::sun::star::uno::RuntimeException);
+ virtual Rectangle GetBoundingBox(void) const throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScPreviewShell* mpViewShell;
+
+ accessibility::AccessibleTextHelper* mpTextHelper;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ virtual sal_Bool IsEditable(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ sal_Bool IsOpaque(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ void CreateTextHelper();
+
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/AccessiblePreviewHeaderCell.hxx b/sc/source/ui/inc/AccessiblePreviewHeaderCell.hxx
new file mode 100644
index 000000000000..520abe7c53c3
--- /dev/null
+++ b/sc/source/ui/inc/AccessiblePreviewHeaderCell.hxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLEPREVIEWHEADERCELL_HXX
+#define _SC_ACCESSIBLEPREVIEWHEADERCELL_HXX
+
+#include "AccessibleContextBase.hxx"
+#include <com/sun/star/accessibility/XAccessibleValue.hpp>
+#include <tools/gen.hxx>
+#include "global.hxx"
+#include "address.hxx"
+#include <cppuhelper/implbase1.hxx>
+
+class ScPreviewShell;
+class ScPreviewTableInfo;
+namespace accessibility {
+ class AccessibleTextHelper;
+}
+
+typedef cppu::ImplHelper1< ::com::sun::star::accessibility::XAccessibleValue>
+ ScAccessiblePreviewHeaderCellImpl;
+
+class ScAccessiblePreviewHeaderCell :
+ public ScAccessibleContextBase,
+ public ScAccessiblePreviewHeaderCellImpl
+{
+public:
+ ScAccessiblePreviewHeaderCell( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell,
+ const ScAddress& rCellPos, sal_Bool bIsColHdr, sal_Bool bIsRowHdr,
+ sal_Int32 nIndex );
+
+protected:
+ virtual ~ScAccessiblePreviewHeaderCell();
+
+ using ScAccessibleContextBase::IsDefunc;
+
+public:
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ //===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XInterface =====================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
+ //===== XAccessibleValue ================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setCurrentValue( const ::com::sun::star::uno::Any& aNumber )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getMaximumValue() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getMinimumValue() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XAccessibleContext ==============================================
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleChild( sal_Int32 i )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
+ getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XServiceInfo ====================================================
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL createAccessibleName(void) throw (::com::sun::star::uno::RuntimeException);
+
+ virtual Rectangle GetBoundingBoxOnScreen(void) const throw(::com::sun::star::uno::RuntimeException);
+ virtual Rectangle GetBoundingBox(void) const throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScPreviewShell* mpViewShell;
+ accessibility::AccessibleTextHelper* mpTextHelper;
+ sal_Int32 mnIndex;
+ ScAddress maCellPos;
+ sal_Bool mbColumnHeader;
+ sal_Bool mbRowHeader;
+ mutable ScPreviewTableInfo* mpTableInfo;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ void CreateTextHelper();
+ void FillTableInfo() const;
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessiblePreviewTable.hxx b/sc/source/ui/inc/AccessiblePreviewTable.hxx
new file mode 100644
index 000000000000..6d9ae3c3025f
--- /dev/null
+++ b/sc/source/ui/inc/AccessiblePreviewTable.hxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLEPREVIEWTABLE_HXX
+#define _SC_ACCESSIBLEPREVIEWTABLE_HXX
+
+#include "AccessibleContextBase.hxx"
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class ScPreviewShell;
+class ScPreviewTableInfo;
+
+typedef cppu::ImplHelper1< ::com::sun::star::accessibility::XAccessibleTable>
+ ScAccessiblePreviewTableImpl;
+
+class ScAccessiblePreviewTable :
+ public ScAccessibleContextBase,
+ public ScAccessiblePreviewTableImpl
+{
+public:
+ ScAccessiblePreviewTable( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, sal_Int32 nIndex );
+
+protected:
+ virtual ~ScAccessiblePreviewTable();
+
+ using ScAccessibleContextBase::IsDefunc;
+
+public:
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ //===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XInterface =====================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
+ //===== XAccessibleTable ================================================
+
+ virtual sal_Int32 SAL_CALL getAccessibleRowCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleColumnCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleRowDescription( sal_Int32 nRow )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleTable > SAL_CALL
+ getAccessibleRowHeaders() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleTable > SAL_CALL
+ getAccessibleColumnHeaders() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL getSelectedAccessibleRows()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL getSelectedAccessibleColumns()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isAccessibleRowSelected( sal_Int32 nRow )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleCaption() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleSummary() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleRow( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleColumn( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ //===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XAccessibleContext ==============================================
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleChild( sal_Int32 i )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
+ getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException);
+
+ //===== XServiceInfo ====================================================
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ //===== XTypeProvider ===================================================
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ //===== internal ========================================================
+ void SetCurrentIndexInParent(sal_Int32 nNew) { mnIndex = nNew; }
+
+protected:
+ virtual ::rtl::OUString SAL_CALL createAccessibleDescription(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL createAccessibleName(void) throw (::com::sun::star::uno::RuntimeException);
+
+ virtual Rectangle GetBoundingBoxOnScreen(void) const throw(::com::sun::star::uno::RuntimeException);
+ virtual Rectangle GetBoundingBox(void) const throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScPreviewShell* mpViewShell;
+ sal_Int32 mnIndex;
+ mutable ScPreviewTableInfo* mpTableInfo;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+
+ void FillTableInfo() const;
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleSpreadsheet.hxx b/sc/source/ui/inc/AccessibleSpreadsheet.hxx
new file mode 100644
index 000000000000..87447285dea2
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleSpreadsheet.hxx
@@ -0,0 +1,289 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLESPREADSHEET_HXX
+#define _SC_ACCESSIBLESPREADSHEET_HXX
+
+#include "AccessibleTableBase.hxx"
+#include "viewdata.hxx"
+
+#include <vector>
+
+class ScMyAddress : public ScAddress
+{
+public:
+ ScMyAddress() : ScAddress() {}
+ ScMyAddress(SCCOL nColP, SCROW nRowP, SCTAB nTabP) : ScAddress(nColP, nRowP, nTabP) {}
+ ScMyAddress(const ScAddress& rAddress) : ScAddress(rAddress) {}
+
+ sal_Bool operator< ( const ScMyAddress& rAddress ) const
+ {
+ if( Row() != rAddress.Row() )
+ return (Row() < rAddress.Row());
+ else
+ return (Col() < rAddress.Col());
+ }
+};
+
+class ScTabViewShell;
+class ScAccessibleDocument;
+class ScAccessibleCell;
+
+/** @descr
+ This base class provides an implementation of the
+ <code>AccessibleTable</code> service.
+*/
+class ScAccessibleSpreadsheet
+ : public ScAccessibleTableBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleSpreadsheet(
+ ScAccessibleDocument* pAccDoc,
+ ScTabViewShell* pViewShell,
+ SCTAB nTab,
+ ScSplitPos eSplitPos);
+protected:
+ ScAccessibleSpreadsheet(
+ ScAccessibleSpreadsheet& rParent,
+ const ScRange& rRange );
+
+ virtual ~ScAccessibleSpreadsheet();
+
+ void ConstructScAccessibleSpreadsheet(
+ ScAccessibleDocument* pAccDoc,
+ ScTabViewShell* pViewShell,
+ SCTAB nTab,
+ ScSplitPos eSplitPos);
+
+ using ScAccessibleTableBase::IsDefunc;
+
+public:
+ using ScAccessibleTableBase::addEventListener;
+ using ScAccessibleTableBase::disposing;
+
+ virtual void SAL_CALL disposing();
+
+ void CompleteSelectionChanged(sal_Bool bNewState);
+
+ virtual void LostFocus();
+
+ virtual void GotFocus();
+
+ void BoundingBoxChanged();
+
+ void VisAreaChanged();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== XAccessibleTable ================================================
+
+ /// Returns the row headers as an AccessibleTable.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleTable > SAL_CALL
+ getAccessibleRowHeaders( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the column headers as an AccessibleTable.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleTable > SAL_CALL
+ getAccessibleColumnHeaders( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the selected rows in a table.
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
+ getSelectedAccessibleRows( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the selected columns in a table.
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
+ getSelectedAccessibleColumns( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns a boolean value indicating whether the specified row is selected.
+ virtual sal_Bool SAL_CALL
+ isAccessibleRowSelected( sal_Int32 nRow )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns a boolean value indicating whether the specified column is selected.
+ virtual sal_Bool SAL_CALL
+ isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the Accessible at a specified row and column in the table.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ ScAccessibleCell* GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn);
+
+ /// Returns a boolean value indicating whether the accessible at a specified row and column is selected.
+ virtual sal_Bool SAL_CALL
+ isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return NULL to indicate that an empty relation set.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleRelationSet> SAL_CALL
+ getAccessibleRelationSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleSelection ===========================================
+
+ virtual void SAL_CALL
+ selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ clearAccessibleSelection( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ selectAllAccessibleChildren( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ getSelectedAccessibleChildCount( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a list of all supported services.
+ */
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleEventBroadcaster =====================================
+
+ /** Add listener that is informed of future changes of name,
+ description and so on events.
+ */
+ virtual void SAL_CALL
+ addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+private:
+ ScTabViewShell* mpViewShell;
+ ScRangeList* mpMarkedRanges;
+ std::vector<ScMyAddress>* mpSortedMarkedCells;
+ ScAccessibleDocument* mpAccDoc;
+ ScAccessibleCell* mpAccCell;
+ Rectangle maVisCells;
+ ScSplitPos meSplitPos;
+ ScAddress maActiveCell;
+ SCTAB mnTab;
+ sal_Bool mbIsSpreadsheet;
+ sal_Bool mbHasSelection;
+ sal_Bool mbDelIns;
+ sal_Bool mbIsFocusSend;
+
+ sal_Bool IsDefunc(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ sal_Bool IsEditable(
+ const com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
+ sal_Bool IsFocused();
+ sal_Bool IsCompleteSheetSelected();
+
+ void SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect);
+ void CreateSortedMarkedCells();
+ void AddMarkedRange(const ScRange& rRange);
+
+ ScDocument* GetDocument(ScTabViewShell* pViewShell);
+ Rectangle GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
+ Rectangle GetVisCells(const Rectangle& rVisArea);
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleTableBase.hxx b/sc/source/ui/inc/AccessibleTableBase.hxx
new file mode 100644
index 000000000000..017ef4dfca3f
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleTableBase.hxx
@@ -0,0 +1,298 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SC_ACCESSIBLETABLEBASE_HXX
+#define _SC_ACCESSIBLETABLEBASE_HXX
+
+#include "AccessibleContextBase.hxx"
+#include "global.hxx"
+#include "address.hxx"
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+class ScTabViewShell;
+
+/** @descr
+ This base class provides an implementation of the
+ <code>AccessibleTable</code> service.
+*/
+
+typedef cppu::ImplHelper2< ::com::sun::star::accessibility::XAccessibleTable,
+ ::com::sun::star::accessibility::XAccessibleSelection>
+ ScAccessibleTableBaseImpl;
+
+class ScAccessibleTableBase :
+ public ScAccessibleContextBase,
+ public ScAccessibleTableBaseImpl
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleTableBase(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDocument* pDoc,
+ const ScRange& rRange);
+protected:
+ virtual ~ScAccessibleTableBase();
+public:
+
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ ///===== XInterface =====================================================
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
+ ///===== XAccessibleTable ================================================
+
+ /// Returns the number of rows in the table.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleRowCount( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the number of columns in the table.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleColumnCount( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the description of the specified row in the table.
+ virtual ::rtl::OUString SAL_CALL
+ getAccessibleRowDescription( sal_Int32 nRow )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the description text of the specified column in the table.
+ virtual ::rtl::OUString SAL_CALL
+ getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /** Returns the number of rows occupied by the Accessible at a specified row and column in the table.
+ Returns 1 if it is only a cell and the number of rows the cell is merged if the cell is a merged cell.
+ */
+ virtual sal_Int32 SAL_CALL
+ getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /** Returns the number of columns occupied by the Accessible at a specified row and column in the table.
+ Returns 1 if it is only a cell and the number of columns the cell is merged if the cell is a merged cell.
+ */
+ virtual sal_Int32 SAL_CALL
+ getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the row headers as an AccessibleTable.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleTable > SAL_CALL
+ getAccessibleRowHeaders( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the column headers as an AccessibleTable.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleTable > SAL_CALL
+ getAccessibleColumnHeaders( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the selected rows in a table.
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
+ getSelectedAccessibleRows( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the selected columns in a table.
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL
+ getSelectedAccessibleColumns( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns a boolean value indicating whether the specified row is selected.
+ virtual sal_Bool SAL_CALL
+ isAccessibleRowSelected( sal_Int32 nRow )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns a boolean value indicating whether the specified column is selected.
+ virtual sal_Bool SAL_CALL
+ isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the Accessible at a specified row and column in the table.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the caption for the table.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleCaption( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns the summary description of the table.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleSummary( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Returns a boolean value indicating whether the accessible at a specified row and column is selected.
+ virtual sal_Bool SAL_CALL
+ isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ ///===== XAccessibleExtendedTable ========================================
+
+ /// Returns the index of the cell on the given position.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the row number of an index in the table.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleRow( sal_Int32 nChildIndex )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Returns the column number of an index in the table.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleColumn( sal_Int32 nChildIndex )
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ //===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ // is overloaded to calculate this on demand
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ // is overloaded to calculate this on demand
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ /// Return NULL to indicate that an empty relation set.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleRelationSet> SAL_CALL
+ getAccessibleRelationSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the set of current states.
+ // perhaps sometimes to be implemented
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleSelection ===========================================
+
+ virtual void SAL_CALL
+ selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ clearAccessibleSelection( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ selectAllAccessibleChildren( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ getSelectedAccessibleChildCount( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ===================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /// returns the possible types
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// contains the range of the table, because it could be a subrange of the complete table
+ ScRange maRange;
+
+ ScDocument* mpDoc;
+
+ void CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId);
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/AccessibleText.hxx b/sc/source/ui/inc/AccessibleText.hxx
new file mode 100644
index 000000000000..0a61280a574a
--- /dev/null
+++ b/sc/source/ui/inc/AccessibleText.hxx
@@ -0,0 +1,359 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ACCESSIBLETEXT_HXX
+#define _SC_ACCESSIBLETEXT_HXX
+
+#include "textuno.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+#include <editeng/svxenum.hxx>
+
+#include <memory>
+
+class ScDocShell;
+class ScViewForwarder;
+class ScEditObjectViewForwarder;
+class ScPreviewViewForwarder;
+class ScEditViewForwarder;
+class ScPreviewShell;
+class EditTextObject;
+class ScCsvViewForwarder;
+class ScAccessibleCell;
+
+
+// ============================================================================
+
+class ScAccessibleTextData : public SfxListener
+{
+public:
+ ScAccessibleTextData() {}
+ virtual ~ScAccessibleTextData() {}
+
+ virtual ScAccessibleTextData* Clone() const = 0;
+
+ virtual void Notify( SfxBroadcaster& /* rBC */, const SfxHint& /* rHint */ ) {}
+
+ virtual SvxTextForwarder* GetTextForwarder() = 0;
+ virtual SvxViewForwarder* GetViewForwarder() = 0;
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate ) = 0;
+ virtual SfxBroadcaster& GetBroadcaster() const { return maBroadcaster; }
+
+ virtual void UpdateData() = 0;
+ virtual void SetDoUpdate(sal_Bool bValue) = 0;
+ virtual sal_Bool IsDirty() const = 0;
+
+private:
+ mutable SfxBroadcaster maBroadcaster;
+
+ // prevent the using of this method of the base class
+ ScSharedCellEditSource* GetOriginalSource() { return NULL; }
+};
+
+
+// ============================================================================
+
+class ScAccessibleCellBaseTextData : public ScAccessibleTextData,
+ public ScCellTextData
+{
+public:
+ ScAccessibleCellBaseTextData(ScDocShell* pDocShellP,
+ const ScAddress& rP)
+ : ScCellTextData(pDocShellP, rP) {}
+ virtual ~ScAccessibleCellBaseTextData() {}
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { ScCellTextData::Notify(rBC, rHint); }
+
+ virtual void UpdateData() { ScCellTextData::UpdateData(); }
+ virtual void SetDoUpdate(sal_Bool bValue) { ScCellTextData::SetDoUpdate(bValue); }
+ virtual sal_Bool IsDirty() const { return ScCellTextData::IsDirty(); }
+};
+
+
+// ============================================================================
+
+// ScAccessibleCellTextData: shared data between sub objects of a accessible cell text object
+
+class ScAccessibleCellTextData : public ScAccessibleCellBaseTextData
+{
+public:
+ ScAccessibleCellTextData(ScTabViewShell* pViewShell,
+ const ScAddress& rP, ScSplitPos eSplitPos, ScAccessibleCell* pAccCell);
+ virtual ~ScAccessibleCellTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate );
+
+ DECL_LINK( NotifyHdl, EENotify* );
+protected:
+ virtual void GetCellText(const ScAddress& rCellPos, String& rText);
+private:
+ ScViewForwarder* mpViewForwarder;
+ ScEditViewForwarder* mpEditViewForwarder;
+ ScTabViewShell* mpViewShell;
+ ScSplitPos meSplitPos;
+ sal_Bool mbViewEditEngine;
+ ScAccessibleCell* mpAccessibleCell;
+
+ // prevent the using of this method of the base class
+ ScSharedCellEditSource* GetOriginalSource() { return NULL; }
+
+ using ScAccessibleCellBaseTextData::GetDocShell;
+ ScDocShell* GetDocShell(ScTabViewShell* pViewShell);
+};
+
+
+// ============================================================================
+
+class ScAccessibleEditObjectTextData : public ScAccessibleTextData
+{
+public:
+ ScAccessibleEditObjectTextData(EditView* pEditView, Window* pWin);
+ virtual ~ScAccessibleEditObjectTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate );
+
+ virtual void UpdateData() { }
+ virtual void SetDoUpdate(sal_Bool /* bValue */) { }
+ virtual sal_Bool IsDirty() const { return sal_False; }
+
+ DECL_LINK( NotifyHdl, EENotify* );
+protected:
+ ScEditObjectViewForwarder* mpViewForwarder;
+ ScEditViewForwarder* mpEditViewForwarder;
+ EditView* mpEditView;
+ EditEngine* mpEditEngine;
+ SvxEditEngineForwarder* mpForwarder;
+ Window* mpWindow;
+};
+
+
+// ============================================================================
+
+class ScAccessibleEditLineTextData : public ScAccessibleEditObjectTextData
+{
+public:
+ ScAccessibleEditLineTextData(EditView* pEditView, Window* pWin);
+ virtual ~ScAccessibleEditLineTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate );
+
+ void Dispose();
+ void TextChanged();
+ void StartEdit();
+ void EndEdit();
+private:
+ void ResetEditMode();
+
+ sal_Bool mbEditEngineCreated;
+};
+
+
+// ============================================================================
+
+class ScAccessiblePreviewCellTextData : public ScAccessibleCellBaseTextData
+{
+public:
+ ScAccessiblePreviewCellTextData(ScPreviewShell* pViewShell,
+ const ScAddress& rP);
+ virtual ~ScAccessiblePreviewCellTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool /* bCreate */ ) { return NULL; }
+
+//UNUSED2008-05 DECL_LINK( NotifyHdl, EENotify* );
+private:
+ ScPreviewViewForwarder* mpViewForwarder;
+ ScPreviewShell* mpViewShell;
+
+ // prevent the using of this method of the base class
+ ScSharedCellEditSource* GetOriginalSource() { return NULL; }
+
+ using ScAccessibleCellBaseTextData::GetDocShell;
+ ScDocShell* GetDocShell(ScPreviewShell* pViewShell);
+};
+
+
+// ============================================================================
+
+class ScAccessiblePreviewHeaderCellTextData : public ScAccessibleCellBaseTextData
+{
+public:
+ ScAccessiblePreviewHeaderCellTextData(ScPreviewShell* pViewShell,
+ const String& rText, const ScAddress& rP, sal_Bool bColHeader, sal_Bool bRowHeader);
+ virtual ~ScAccessiblePreviewHeaderCellTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool /* bCreate */ ) { return NULL; }
+
+//UNUSED2008-05 DECL_LINK( NotifyHdl, EENotify* );
+private:
+ ScPreviewViewForwarder* mpViewForwarder;
+ ScPreviewShell* mpViewShell;
+ String maText;
+ sal_Bool mbColHeader;
+ sal_Bool mbRowHeader;
+
+ // prevent the using of this method of the base class
+ ScSharedCellEditSource* GetOriginalSource() { return NULL; }
+
+ using ScAccessibleCellBaseTextData::GetDocShell;
+ ScDocShell* GetDocShell(ScPreviewShell* pViewShell);
+};
+
+
+// ============================================================================
+
+class ScAccessibleHeaderTextData : public ScAccessibleTextData
+{
+public:
+ ScAccessibleHeaderTextData(ScPreviewShell* pViewShell,
+ const EditTextObject* pEditObj, sal_Bool bHeader, SvxAdjust eAdjust);
+ virtual ~ScAccessibleHeaderTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool /* bCreate */ ) { return NULL; }
+
+ virtual void UpdateData() { }
+ virtual void SetDoUpdate(sal_Bool /* bValue */) { }
+ virtual sal_Bool IsDirty() const { return sal_False; }
+private:
+ ScPreviewViewForwarder* mpViewForwarder;
+ ScPreviewShell* mpViewShell;
+ ScEditEngineDefaulter* mpEditEngine;
+ SvxEditEngineForwarder* mpForwarder;
+ ScDocShell* mpDocSh;
+ const EditTextObject* mpEditObj;
+ sal_Bool mbHeader;
+ sal_Bool mbDataValid;
+ SvxAdjust meAdjust;
+};
+
+
+// ============================================================================
+
+class ScAccessibleNoteTextData : public ScAccessibleTextData
+{
+public:
+ ScAccessibleNoteTextData(ScPreviewShell* pViewShell,
+ const String& sText, const ScAddress& aCellPos, sal_Bool bMarkNote);
+ virtual ~ScAccessibleNoteTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool /* bCreate */ ) { return NULL; }
+
+ virtual void UpdateData() { }
+ virtual void SetDoUpdate(sal_Bool /* bValue */) { }
+ virtual sal_Bool IsDirty() const { return sal_False; }
+private:
+ ScPreviewViewForwarder* mpViewForwarder;
+ ScPreviewShell* mpViewShell;
+ ScEditEngineDefaulter* mpEditEngine;
+ SvxEditEngineForwarder* mpForwarder;
+ ScDocShell* mpDocSh;
+ String msText;
+ ScAddress maCellPos;
+ sal_Bool mbMarkNote;
+ sal_Bool mbDataValid;
+};
+
+
+// ============================================================================
+
+class ScAccessibleCsvTextData : public ScAccessibleTextData
+{
+private:
+ typedef ::std::auto_ptr< SvxTextForwarder > TextForwarderPtr;
+ typedef ::std::auto_ptr< ScCsvViewForwarder > ViewForwarderPtr;
+
+ Window* mpWindow;
+ EditEngine* mpEditEngine;
+ TextForwarderPtr mpTextForwarder;
+ ViewForwarderPtr mpViewForwarder;
+ String maCellText;
+ Rectangle maBoundBox;
+ Size maCellSize;
+
+public:
+ explicit ScAccessibleCsvTextData(
+ Window* pWindow,
+ EditEngine* pEditEngine,
+ const String& rCellText,
+ const Rectangle& rBoundBox,
+ const Size& rCellSize );
+ virtual ~ScAccessibleCsvTextData();
+
+ virtual ScAccessibleTextData* Clone() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate );
+
+ virtual void UpdateData() {}
+ virtual void SetDoUpdate( sal_Bool /* bValue */ ) {}
+ virtual sal_Bool IsDirty() const { return sal_False; }
+};
+
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/ui/inc/ChartRangeSelectionListener.hxx b/sc/source/ui/inc/ChartRangeSelectionListener.hxx
new file mode 100644
index 000000000000..65c725da5675
--- /dev/null
+++ b/sc/source/ui/inc/ChartRangeSelectionListener.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_CHARTRANGESELECTIONLISTENER_HXX
+#define SC_CHARTRANGESELECTIONLISTENER_HXX
+
+#include <cppuhelper/compbase2.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <com/sun/star/view/XSelectionChangeListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+class ScTabViewShell;
+
+typedef ::cppu::WeakComponentImplHelper2<
+ ::com::sun::star::view::XSelectionChangeListener,
+ ::com::sun::star::lang::XServiceInfo >
+ ScChartRangeSelectionListener_Base;
+
+class ScChartRangeSelectionListener :
+ public comphelper::OBaseMutex,
+ public ScChartRangeSelectionListener_Base
+{
+public:
+ explicit ScChartRangeSelectionListener( ScTabViewShell * pViewShell );
+ virtual ~ScChartRangeSelectionListener();
+
+protected:
+ // ____ XSelectionChangeListener ____
+ virtual void SAL_CALL selectionChanged(
+ const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XEventListener (base of XSelectionChangeListener) ____
+ virtual void SAL_CALL disposing(
+ const ::com::sun::star::lang::EventObject& Source )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ WeakComponentImplHelperBase ____
+ // is called when dispose() is called at this component
+ virtual void SAL_CALL disposing();
+
+ // ____ XServiceInfo ____
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService(
+ const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScTabViewShell * m_pViewShell;
+};
+
+// SC_CHARTRANGESELECTIONLISTENER_HXX
+#endif
diff --git a/sc/source/ui/inc/DrawModelBroadcaster.hxx b/sc/source/ui/inc/DrawModelBroadcaster.hxx
new file mode 100644
index 000000000000..045e9bc86f41
--- /dev/null
+++ b/sc/source/ui/inc/DrawModelBroadcaster.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SC_DRAWMODELBROADCASTER_HXX
+#define _SC_DRAWMODELBROADCASTER_HXX
+
+
+#include <svl/lstner.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+
+class SdrModel;
+
+class ScDrawModelBroadcaster : public SfxListener,
+ public ::cppu::WeakImplHelper1< com::sun::star::document::XEventBroadcaster >
+{
+ mutable ::osl::Mutex maListenerMutex;
+ ::cppu::OInterfaceContainerHelper maEventListeners;
+ SdrModel *mpDrawModel;
+
+public:
+
+ ScDrawModelBroadcaster( SdrModel *pDrawModel );
+ virtual ~ScDrawModelBroadcaster();
+
+ virtual void SAL_CALL addEventListener( const com::sun::star::uno::Reference< com::sun::star::document::XEventListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const com::sun::star::uno::Reference< com::sun::star::document::XEventListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+};
+
+#endif
diff --git a/sc/source/ui/inc/IAnyRefDialog.hxx b/sc/source/ui/inc/IAnyRefDialog.hxx
new file mode 100644
index 000000000000..70731ac8a1f7
--- /dev/null
+++ b/sc/source/ui/inc/IAnyRefDialog.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_IANYREFDIALOG_HXX_INCLUDED
+#define SC_IANYREFDIALOG_HXX_INCLUDED
+
+#include <formula/IControlReferenceHandler.hxx>
+
+class ScRange;
+class ScDocument;
+class ScTabViewShell;
+class SfxObjectShell;
+namespace formula
+{
+ class RefEdit;
+ class RefButton;
+}
+class SAL_NO_VTABLE IAnyRefDialog : public formula::IControlReferenceHandler
+{
+public:
+ virtual ~IAnyRefDialog(){}
+
+ //virtual void ShowReference(const String& _sRef) = 0;
+ //virtual void HideReference( BOOL bDoneRefMode = TRUE ) = 0;
+ //virtual void ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL ) = 0;
+ //virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL ) = 0;
+
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc ) = 0;
+ virtual void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL ) = 0;
+ virtual void RefInputDone( BOOL bForced = FALSE ) = 0;
+ virtual BOOL IsTableLocked() const = 0;
+ virtual BOOL IsRefInputMode() const = 0;
+
+ virtual BOOL IsDocAllowed( SfxObjectShell* pDocSh ) const = 0;
+ virtual void AddRefEntry() = 0;
+ virtual void SetActive() = 0;
+ virtual void ViewShellChanged( ScTabViewShell* pScViewShell ) = 0;
+};
+
+#endif // SC_IANYREFDIALOG_HXX_INCLUDED
diff --git a/sc/source/ui/inc/ScDevChart.hxx b/sc/source/ui/inc/ScDevChart.hxx
new file mode 100644
index 000000000000..a08a89da0570
--- /dev/null
+++ b/sc/source/ui/inc/ScDevChart.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef INCLUDED_DEVCHARTCONFIG_HXX
+#define INCLUDED_DEVCHARTCONFIG_HXX
+
+#include <unotools/configitem.hxx>
+
+namespace ScDevChart
+{
+
+class DevChartConfigItem : public ::utl::ConfigItem
+{
+public:
+ DevChartConfigItem() :
+ ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Internal" )),
+ CONFIG_MODE_IMMEDIATE_UPDATE )
+ {}
+
+ bool UseDevelopmentChart();
+};
+
+bool DevChartConfigItem::UseDevelopmentChart()
+{
+ bool bResult = false;
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > aNames( 1 );
+ aNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DevelopmentChart" ));
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aResult( GetProperties( aNames ));
+
+ OSL_ASSERT( aResult.getLength());
+ aResult[0] >>= bResult;
+
+ return bResult;
+}
+
+/** States whether the new chart implementation or the old one should be used.
+ If <TRUE/> is returned the newly developed chart (chart2) should be used.
+ If <FALSE/> is returned, the old chart (sch) should be used.
+
+ Config-Item: Office.Common/Internal:DevelopmentChart
+
+ This function (the complete header) is only for a transitional period. It
+ will be deprecated after the new chart is definitely integrated into the
+ product.
+ */
+bool UseDevChart()
+{
+// static DevChartConfigItem aCfgItem;
+// return aCfgItem.UseDevelopmentChart();
+
+ // ignore configuration
+ //@todo: get rid of this class
+ return true;
+}
+
+} // namespace ScDevChart
+
+// INCLUDED_DEVCHARTCONFIG_HXX
+#endif
diff --git a/sc/source/ui/inc/acredlin.hrc b/sc/source/ui/inc/acredlin.hrc
new file mode 100644
index 000000000000..b21676ee6ae9
--- /dev/null
+++ b/sc/source/ui/inc/acredlin.hrc
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> RID_SCDLG_CHANGES
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 5
+//
+#define CTR_REDLINING 10
+#define TP_FILTER 11
+#define TP_VIEW 12
+
+
+#define FT_ASSIGN 14
+#define ED_ASSIGN 15
+#define RB_ASSIGN 16
+
+
+#define STR_INSERT_COLS 20
+#define STR_INSERT_ROWS 21
+#define STR_INSERT_TABS 22
+#define STR_DELETE_COLS 23
+#define STR_DELETE_ROWS 24
+#define STR_DELETE_TABS 25
+#define STR_MOVE 26
+#define STR_CONTENT 27
+#define STR_REJECT 28
+#define STR_ACCEPTED 29
+#define STR_REJECTED 30
+#define STR_NO_ENTRY 31
+#define STR_CONTENT_WITH_CHILD 32
+#define STR_CHILD_CONTENT 33
+#define STR_CHILD_ORGCONTENT 34
+#define STR_EMPTY 35
+// Bitmaps
+#define BMP_STR_CLOSE 41
+#define BMP_STR_OPEN 42
+#define BMP_STR_END 43
+#define BMP_STR_ERROR 44
+
+#define SC_CHANGES_COMMENT 49
+#define SC_SUB_SORT 50
+#define SC_SORT_ACTION 51
+#define SC_SORT_POSITION 52
+#define SC_SORT_AUTHOR 53
+#define SC_SORT_DATE 54
+#define SC_SORT_COMMENT 55
+
+//
+
diff --git a/sc/source/ui/inc/acredlin.hxx b/sc/source/ui/inc/acredlin.hxx
new file mode 100644
index 000000000000..a077129c374c
--- /dev/null
+++ b/sc/source/ui/inc/acredlin.hxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ACREDLIN_HXX
+#define SC_ACREDLIN_HXX
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#include <svtools/headbar.hxx>
+#include <svtools/svtabbx.hxx>
+
+
+#include "rangenam.hxx"
+#include "anyrefdg.hxx"
+#include <vcl/lstbox.hxx>
+
+#ifndef _SVX_ACREDLIN_HXX
+#include <svx/ctredlin.hxx>
+#endif
+#include <svx/simptabl.hxx>
+
+#ifndef _SVARRAY_HXX
+#define _SVARRAY_HXX
+#include <svl/svarray.hxx>
+#endif
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include <vcl/timer.hxx>
+
+class ScViewData;
+class ScDocument;
+
+#define FLT_DATE_BEFORE 0
+#define FLT_DATE_SINCE 1
+#define FLT_DATE_EQUAL 2
+#define FLT_DATE_NOTEQUAL 3
+#define FLT_DATE_BETWEEN 4
+#define FLT_DATE_SAVE 5
+
+
+class ScViewEntryPtr
+{
+private:
+ String* pAction;
+ String* pPos;
+ String* pAuthor;
+ String* pDate;
+ String* pComment;
+ void* pData;
+
+public:
+
+ String* GetpAction() {return pAction; }
+ String* GetpPos() {return pPos; }
+ String* GetpAuthor() {return pAuthor; }
+ String* GetpDate() {return pDate; }
+ String* GetpComment() {return pComment;}
+ void* GetpData() {return pData; }
+
+ void SetpAction (String* pString) {pAction= pString;}
+ void SetpPos (String* pString) {pPos = pString;}
+ void SetpAuthor (String* pString) {pAuthor= pString;}
+ void SetpDate (String* pString) {pDate = pString;}
+ void SetpComment(String* pString) {pComment=pString;}
+ void SetpData (void* pdata) {pData =pdata;}
+};
+
+class ScViewEntryPtrList
+{
+ ScViewEntryPtrList* pNext;
+ ScViewEntryPtrList* pLast;
+
+ ScViewEntryPtr* pData;
+};
+
+
+class ScRedlinData : public RedlinData
+{
+public:
+
+ ScRedlinData();
+ ~ScRedlinData();
+ SCTAB nTable;
+ SCCOL nCol;
+ SCROW nRow;
+ ULONG nActionNo;
+ ULONG nInfo;
+ BOOL bIsRejectable;
+ BOOL bIsAcceptable;
+};
+
+typedef long LExpNum;
+
+//@ Expand-Entrys nicht eindeutig, daher gestrichen
+//DECLARE_TABLE( ScChgTrackExps, LExpNum)
+//==================================================================
+
+class ScAcceptChgDlg : public SfxModelessDialog
+{
+private:
+
+ Timer aSelectionTimer;
+ Timer aReOpenTimer;
+ SvxAcceptChgCtr aAcceptChgCtr;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ ScRangeName aLocalRangeName;
+ Selection theCurSel;
+ SvxTPFilter* pTPFilter;
+ SvxTPView* pTPView;
+ SvxRedlinTable* pTheView; // PB 2006/02/02 #i48648 now SvHeaderTabListBox
+ Size MinSize;
+ ScRangeList aRangeList;
+ ScChangeViewSettings aChangeViewSet;
+ String aStrInsertCols;
+ String aStrInsertRows;
+ String aStrInsertTabs;
+ String aStrDeleteCols;
+ String aStrDeleteRows;
+ String aStrDeleteTabs;
+ String aStrMove;
+ String aStrContent;
+ String aStrReject;
+ String aUnknown;
+ String aStrAllAccepted;
+ String aStrAllRejected;
+ String aStrNoEntry;
+ String aStrContentWithChild;
+ String aStrChildContent;
+ String aStrChildOrgContent;
+ String aStrEmpty;
+ ULONG nAcceptCount;
+ ULONG nRejectCount;
+ BOOL bAcceptEnableFlag;
+ BOOL bRejectEnableFlag;
+ BOOL bNeedsUpdate;
+ BOOL bIgnoreMsg;
+ BOOL bNoSelection;
+ BOOL bHasFilterEntry;
+ BOOL bUseColor;
+ //ScChgTrackExps aExpandArray;
+
+ void Init();
+ void InitFilter();
+//UNUSED2008-05 void SetMyStaticData();
+
+ DECL_LINK( FilterHandle, SvxTPFilter* );
+ DECL_LINK( RefHandle, SvxTPFilter* );
+ DECL_LINK( FilterModified, SvxTPFilter* );
+ DECL_LINK( MinSizeHandle, SvxAcceptChgCtr*);
+ DECL_LINK( RejectHandle, SvxTPView*);
+ DECL_LINK( AcceptHandle, SvxTPView*);
+ DECL_LINK( RejectAllHandle, SvxTPView*);
+ DECL_LINK( AcceptAllHandle, SvxTPView*);
+ DECL_LINK( ExpandingHandle, SvxRedlinTable*);
+ DECL_LINK( SelectHandle, SvxRedlinTable*);
+ DECL_LINK( RefInfoHandle, String*);
+
+ DECL_LINK( UpdateSelectionHdl, Timer*);
+ DECL_LINK( ChgTrackModHdl, ScChangeTrack*);
+ DECL_LINK( CommandHdl, Control*);
+ DECL_LINK( ReOpenTimerHdl, Timer*);
+ DECL_LINK( ColCompareHdl, SvSortData*);
+
+
+
+protected:
+
+ virtual void Resize();
+ virtual BOOL Close();
+
+ void RejectFiltered();
+ void AcceptFiltered();
+
+ BOOL IsValidAction(const ScChangeAction* pScChangeAction);
+
+ String* MakeTypeString(ScChangeActionType eType);
+
+ SvLBoxEntry* InsertChangeAction(const ScChangeAction* pScChangeAction,ScChangeActionState eState,
+ SvLBoxEntry* pParent=NULL,BOOL bDelMaster=FALSE,
+ BOOL bDisabled=FALSE,ULONG nPos=LIST_APPEND);
+
+ SvLBoxEntry* InsertFilteredAction(const ScChangeAction* pScChangeAction,ScChangeActionState eState,
+ SvLBoxEntry* pParent=NULL,BOOL bDelMaster=FALSE,
+ BOOL bDisabled=FALSE,ULONG nPos=LIST_APPEND);
+
+
+ SvLBoxEntry* InsertChangeActionContent(const ScChangeActionContent* pScChangeAction,
+ SvLBoxEntry* pParent,ULONG nSpecial);
+
+ void GetDependents( const ScChangeAction* pScChangeAction,
+ ScChangeActionTable& aActionTable,
+ SvLBoxEntry* pEntry);
+
+ BOOL InsertContentChilds(ScChangeActionTable* pActionTable,SvLBoxEntry* pParent);
+
+ BOOL InsertAcceptedORejected(SvLBoxEntry* pParent);
+
+ BOOL InsertDeletedChilds(const ScChangeAction *pChangeAction, ScChangeActionTable* pActionTable,
+ SvLBoxEntry* pParent);
+
+ BOOL InsertChilds(ScChangeActionTable* pActionTable,SvLBoxEntry* pParent);
+
+ void AppendChanges(ScChangeTrack* pChanges,ULONG nStartAction, ULONG nEndAction,
+ ULONG nPos=LIST_APPEND);
+
+ void RemoveEntrys(ULONG nStartAction,ULONG nEndAction);
+ void UpdateEntrys(ScChangeTrack* pChgTrack, ULONG nStartAction,ULONG nEndAction);
+
+ void UpdateView();
+ void ClearView();
+
+ BOOL Expand(ScChangeTrack* pChanges,const ScChangeAction* pScChangeAction,
+ SvLBoxEntry* pEntry, BOOL bFilter=FALSE);
+
+public:
+ ScAcceptChgDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData);
+
+ ~ScAcceptChgDlg();
+
+ void ReInit(ScViewData* ptrViewData);
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ void Initialize (SfxChildWinInfo* pInfo);
+ virtual void FillInfo(SfxChildWinInfo&) const;
+
+};
+
+
+#endif // SC_NAMEDLG_HXX
+
diff --git a/sc/source/ui/inc/anyrefdg.hxx b/sc/source/ui/inc/anyrefdg.hxx
new file mode 100644
index 000000000000..0e7560fe0c50
--- /dev/null
+++ b/sc/source/ui/inc/anyrefdg.hxx
@@ -0,0 +1,281 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ANYREFDG_HXX
+#define SC_ANYREFDG_HXX
+
+#ifndef _IMAGEBTN_HXX
+#include <vcl/imagebtn.hxx>
+#endif
+#ifndef _EDIT_HXX
+#include <vcl/edit.hxx>
+#endif
+#ifndef _ACCEL_HXX
+#include <vcl/accel.hxx>
+#endif
+#include <sfx2/basedlgs.hxx>
+#include "address.hxx"
+#include "cell.hxx"
+#include "compiler.hxx"
+#include "formula/funcutl.hxx"
+#include "IAnyRefDialog.hxx"
+#include "scresid.hxx"
+#include <memory>
+
+class SfxObjectShell;
+class ScRange;
+class ScDocument;
+class ScTabViewShell;
+//The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
+//class ScAnyRefDlg;
+class ScRefHandler;
+class ScRangeList;
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+class SfxShell;
+#include "scmod.hxx"
+
+typedef formula::RefButton ScRefButton;
+typedef formula::RefEdit ScRefEdit;
+//-->Added by PengYunQuan for Validity Cell Range Picker
+class ScFormulaReferenceHelper
+{
+ IAnyRefDialog* m_pDlg;
+ ::std::auto_ptr<ScFormulaCell> pRefCell;
+ ::std::auto_ptr<ScCompiler> pRefComp;
+ formula::RefEdit* pRefEdit; // aktives Eingabefeld
+ formula::RefButton* pRefBtn; // Button dazu
+ Window* m_pWindow;
+ SfxBindings* m_pBindings;
+ ::std::auto_ptr<Accelerator>
+ pAccel; // fuer Enter/Escape
+ BOOL* pHiddenMarks; // Merkfeld fuer versteckte Controls
+ SCTAB nRefTab; // used for ShowReference
+
+ String sOldDialogText; // Originaltitel des Dialogfensters
+ Size aOldDialogSize; // Originalgroesse Dialogfenster
+ Point aOldEditPos; // Originalposition des Eingabefeldes
+ Size aOldEditSize; // Originalgroesse des Eingabefeldes
+ Point aOldButtonPos; // Originalpositiuon des Buttons
+
+ BOOL bEnableColorRef;
+ BOOL bHighLightRef;
+ BOOL bAccInserted;
+
+ DECL_LINK( AccelSelectHdl, Accelerator* );
+
+public:
+ ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings);
+ ~ScFormulaReferenceHelper();
+
+ void ShowSimpleReference( const XubString& rStr );
+ void ShowFormulaReference( const XubString& rStr );
+ bool ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc );
+ void Init();
+
+ void ShowReference( const XubString& rStr );
+ void ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ void HideReference( BOOL bDoneRefMode = TRUE );
+ void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ void RefInputDone( BOOL bForced = FALSE );
+ void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+
+ inline void SetWindow(Window* _pWindow) { m_pWindow = _pWindow; }
+ BOOL DoClose( USHORT nId );
+ void SetDispatcherLock( BOOL bLock );
+ void EnableSpreadsheets( BOOL bFlag = TRUE, BOOL bChilds = TRUE );
+ void ViewShellChanged( ScTabViewShell* pScViewShell );
+
+ static void enableInput(BOOL _bInput);
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+protected:
+ Window * GetWindow(){ return m_pWindow; }
+public:
+ bool CanInputStart( const ScRefEdit *pEdit ){ return !!pEdit; }
+ bool CanInputDone( BOOL bForced ){ return pRefEdit && (bForced || !pRefBtn); }
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+};
+//============================================================================
+
+//The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
+class SC_DLLPUBLIC ScRefHandler : //public SfxModelessDialog,
+ public IAnyRefDialog
+{
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+ Window & m_rWindow;
+ bool m_bInRefMode;
+public:
+ operator Window *(){ return &m_rWindow; }
+ Window * operator ->() { return static_cast<Window *>(*this); }
+ template<class,bool> friend class ScRefHdlrImplBase;
+//-->Added by PengYunQuan for Validity Cell Range Picker
+ friend class formula::RefButton;
+ friend class formula::RefEdit;
+
+private:
+ ScFormulaReferenceHelper
+ m_aHelper;
+ SfxBindings* pMyBindings;
+
+ Window* pActiveWin;
+ Timer aTimer;
+ String aDocName; // document on which the dialog was opened
+
+ DECL_LINK( UpdateFocusHdl, Timer* );
+
+
+protected:
+ virtual BOOL DoClose( USHORT nId );
+
+ void SetDispatcherLock( BOOL bLock );
+
+ //Overwrite TWindow will implemented by ScRefHdlrImplBase
+ //virtual long PreNotify( NotifyEvent& rNEvt );
+
+ virtual void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ virtual void RefInputDone( BOOL bForced = FALSE );
+ void ShowSimpleReference( const XubString& rStr );
+ void ShowFormulaReference( const XubString& rStr );
+
+ bool ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc );
+
+public:
+ ScRefHandler( Window &rWindow, SfxBindings* pB/*, SfxChildWindow* pCW,
+ Window* pParent, USHORT nResId*/, bool bBindRef );
+ virtual ~ScRefHandler();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc ) = 0;
+ virtual void AddRefEntry();
+
+ virtual BOOL IsRefInputMode() const;
+ virtual BOOL IsTableLocked() const;
+ virtual BOOL IsDocAllowed( SfxObjectShell* pDocSh ) const;
+
+ virtual void ShowReference( const XubString& rStr );
+ virtual void HideReference( BOOL bDoneRefMode = TRUE );
+
+ virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ virtual void ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+
+ virtual void ViewShellChanged( ScTabViewShell* pScViewShell );
+ void SwitchToDocument();
+ //SfxBindings& GetBindings();
+
+ virtual void SetActive() = 0;
+// virtual BOOL Close();
+ //Overwrite TWindow will implemented by ScRefHdlrImplBase
+ //virtual void StateChanged( StateChangedType nStateChange );
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+public:
+ bool EnterRefMode();
+ bool LeaveRefMode();
+ inline bool CanInputStart( const ScRefEdit *pEdit );
+ inline bool CanInputDone( BOOL bForced );
+//-->Added by PengYunQuan for Validity Cell Range Picker
+};
+
+
+//============================================================================
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+template< class TWindow, bool bBindRef = true >
+class ScRefHdlrImplBase:public TWindow, public ScRefHandler
+{
+public:
+ //Overwrite TWindow
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void StateChanged( StateChangedType nStateChange );
+
+private:
+ template<class TBindings, class TChildWindow, class TParentWindow, class TResId>
+ ScRefHdlrImplBase( TBindings* pB, TChildWindow* pCW,
+ TParentWindow* pParent, TResId nResId);
+
+ template<class TParentWindow, class TResId, class TArg>
+ ScRefHdlrImplBase( TParentWindow* pParent, TResId nResId, const TArg &rArg, SfxBindings *pB = NULL );
+
+ ~ScRefHdlrImplBase();
+
+ template<class, class, bool> friend struct ScRefHdlrImpl;
+};
+
+template<class TWindow, bool bBindRef>
+template<class TBindings, class TChildWindow, class TParentWindow, class TResId>
+ScRefHdlrImplBase<TWindow, bBindRef>::ScRefHdlrImplBase( TBindings* pB, TChildWindow* pCW,
+ TParentWindow* pParent, TResId nResId):TWindow(pB, pCW, pParent, ScResId(static_cast<USHORT>( nResId ) ) ), ScRefHandler( *static_cast<TWindow*>(this), pB, bBindRef ){}
+
+template<class TWindow, bool bBindRef >
+template<class TParentWindow, class TResId, class TArg>
+ScRefHdlrImplBase<TWindow,bBindRef>::ScRefHdlrImplBase( TParentWindow* pParent, TResId nResIdP, const TArg &rArg, SfxBindings *pB /*= NULL*/ )
+:TWindow( pParent, ScResId(static_cast<USHORT>( nResIdP )), rArg ), ScRefHandler( *static_cast<TWindow*>(this), pB, bBindRef ){}
+
+template<class TWindow, bool bBindRef >
+ScRefHdlrImplBase<TWindow,bBindRef>::~ScRefHdlrImplBase(){}
+
+//============================================================================
+template<class TDerived, class TBase, bool bBindRef = true>
+struct ScRefHdlrImpl: ScRefHdlrImplBase<TBase, bBindRef >
+{
+ enum { UNKNOWN_SLOTID = 0U, SLOTID = UNKNOWN_SLOTID };
+
+ template<class T1, class T2, class T3, class T4>
+ ScRefHdlrImpl( const T1 & rt1, const T2 & rt2, const T3 & rt3, const T4 & rt4 ):ScRefHdlrImplBase<TBase, bBindRef >(rt1, rt2, rt3, rt4 )
+ {
+ SC_MOD()->RegisterRefWindow( static_cast<USHORT>( static_cast<TDerived*>(this)->SLOTID ), this );
+ }
+
+ ~ScRefHdlrImpl()
+ {
+ SC_MOD()->UnregisterRefWindow( static_cast<USHORT>( static_cast<TDerived*>(this)->SLOTID ), this );
+ }
+};
+//============================================================================
+struct ScAnyRefDlg : ::ScRefHdlrImpl< ScAnyRefDlg, SfxModelessDialog>
+{
+ template<class T1, class T2, class T3, class T4>
+ ScAnyRefDlg( const T1 & rt1, const T2 & rt2, const T3 & rt3, const T4 & rt4 ):ScRefHdlrImpl< ScAnyRefDlg, SfxModelessDialog>(rt1, rt2, rt3, rt4){}
+};
+//============================================================================
+
+inline bool ScRefHandler::CanInputStart( const ScRefEdit *pEdit )
+{
+ return m_aHelper.CanInputStart( pEdit );
+}
+
+inline bool ScRefHandler::CanInputDone( BOOL bForced )
+{
+ return m_aHelper.CanInputDone( bForced );
+}
+
+template <> SC_DLLPUBLIC void ScRefHdlrImplBase<SfxModelessDialog,true>::StateChanged( StateChangedType nStateChange );
+template <> SC_DLLPUBLIC long ScRefHdlrImplBase<SfxModelessDialog,true>::PreNotify( NotifyEvent& rNEvt );
+#include <sfx2/tabdlg.hxx>
+template <> SC_DLLPUBLIC void ScRefHdlrImplBase<SfxTabDialog,false>::StateChanged( StateChangedType nStateChange );
+template <> SC_DLLPUBLIC long ScRefHdlrImplBase<SfxTabDialog,false>::PreNotify( NotifyEvent& rNEvt );
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#endif // SC_ANYREFDG_HXX
+
diff --git a/sc/source/ui/inc/areasave.hxx b/sc/source/ui/inc/areasave.hxx
new file mode 100644
index 000000000000..608f95a3bb51
--- /dev/null
+++ b/sc/source/ui/inc/areasave.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_AREASAVE_HXX
+#define SC_AREASAVE_HXX
+
+#include "collect.hxx"
+#include "global.hxx"
+#include "address.hxx"
+
+class ScDocument;
+class ScAreaLink;
+
+
+class ScAreaLinkSaver : public ScDataObject
+{
+private:
+ String aFileName;
+ String aFilterName;
+ String aOptions;
+ String aSourceArea;
+ ScRange aDestArea;
+ ULONG nRefresh;
+
+public:
+ ScAreaLinkSaver( const ScAreaLink& rSource );
+ ScAreaLinkSaver( const ScAreaLinkSaver& rCopy );
+ virtual ~ScAreaLinkSaver();
+
+ virtual ScDataObject* Clone() const;
+
+ BOOL IsEqual( const ScAreaLink& rCompare ) const;
+ BOOL IsEqualSource( const ScAreaLink& rCompare ) const;
+
+ void WriteToLink( ScAreaLink& rLink ) const;
+ void InsertNewLink( ScDocument* pDoc ) const;
+};
+
+
+class ScAreaLinkSaveCollection : public ScCollection
+{
+public:
+ ScAreaLinkSaveCollection();
+ ScAreaLinkSaveCollection( const ScAreaLinkSaveCollection& rCopy );
+ virtual ~ScAreaLinkSaveCollection();
+
+ virtual ScDataObject* Clone() const;
+
+ ScAreaLinkSaver* operator[](USHORT nIndex) const {return (ScAreaLinkSaver*)At(nIndex);}
+
+ BOOL IsEqual( const ScDocument* pDoc ) const;
+ void Restore( ScDocument* pDoc ) const;
+
+ // returns NULL if empty
+ static ScAreaLinkSaveCollection* CreateFromDoc( const ScDocument* pDoc );
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/areasdlg.hxx b/sc/source/ui/inc/areasdlg.hxx
new file mode 100644
index 000000000000..08c6e3cf0a91
--- /dev/null
+++ b/sc/source/ui/inc/areasdlg.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_AREASDLG_HXX
+#define SC_AREASDLG_HXX
+
+#include "address.hxx"
+
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#include <anyrefdg.hxx>
+
+class ScDocument;
+class ScViewData;
+class ScRangeUtil;
+class ScRangeItem;
+
+
+//============================================================================
+
+class ScPrintAreasDlg : public ScAnyRefDlg
+{
+public:
+ ScPrintAreasDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent );
+ ~ScPrintAreasDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual void AddRefEntry();
+
+ virtual BOOL IsTableLocked() const;
+
+ virtual void SetActive();
+ virtual void Deactivate();
+ virtual BOOL Close();
+
+private:
+ ListBox aLbPrintArea;
+ FixedLine aFlPrintArea;
+ formula::RefEdit aEdPrintArea;
+ formula::RefButton aRbPrintArea;
+
+ ListBox aLbRepeatRow;
+ FixedLine aFlRepeatRow;
+ formula::RefEdit aEdRepeatRow;
+ formula::RefButton aRbRepeatRow;
+
+ ListBox aLbRepeatCol;
+ FixedLine aFlRepeatCol;
+ formula::RefEdit aEdRepeatCol;
+ formula::RefButton aRbRepeatCol;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ BOOL bDlgLostFocus;
+ formula::RefEdit* pRefInputEdit;
+ ScDocument* pDoc;
+ ScViewData* pViewData;
+ SCTAB nCurTab;
+
+#ifdef _AREASDLG_CXX
+private:
+ void Impl_Reset();
+ BOOL Impl_CheckRefStrings();
+ void Impl_FillLists();
+ BOOL Impl_GetItem( Edit* pEd, SfxStringItem& rItem );
+
+ // Handler:
+ DECL_LINK( Impl_SelectHdl, ListBox* );
+ DECL_LINK( Impl_ModifyHdl, formula::RefEdit* );
+ DECL_LINK( Impl_BtnHdl, PushButton* );
+ DECL_LINK( Impl_GetFocusHdl, Control* );
+#endif
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/asciiopt.hxx b/sc/source/ui/inc/asciiopt.hxx
new file mode 100644
index 000000000000..a5c7a2b554b4
--- /dev/null
+++ b/sc/source/ui/inc/asciiopt.hxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_ASCIIOPT_HXX
+#define SC_ASCIIOPT_HXX
+
+#include <tools/string.hxx>
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#ifndef _FIELD_HXX //autogen
+#include <vcl/field.hxx>
+#endif
+#include <tools/stream.hxx>
+#include <svx/txencbox.hxx>
+#include "csvtablebox.hxx"
+#include "i18npool/lang.h"
+
+// ============================================================================
+
+class ScAsciiOptions
+{
+private:
+ BOOL bFixedLen;
+ String aFieldSeps;
+ BOOL bMergeFieldSeps;
+ bool bQuotedFieldAsText;
+ bool bDetectSpecialNumber;
+ sal_Unicode cTextSep;
+ CharSet eCharSet;
+ LanguageType eLang;
+ BOOL bCharSetSystem;
+ long nStartRow;
+ USHORT nInfoCount;
+ xub_StrLen* pColStart; //! TODO replace with vector
+ BYTE* pColFormat; //! TODO replace with vector
+
+public:
+ ScAsciiOptions();
+ ScAsciiOptions(const ScAsciiOptions& rOpt);
+ ~ScAsciiOptions();
+
+ static const sal_Unicode cDefaultTextSep = '"';
+
+ ScAsciiOptions& operator=( const ScAsciiOptions& rCpy );
+
+ BOOL operator==( const ScAsciiOptions& rCmp ) const;
+
+ void ReadFromString( const String& rString );
+ String WriteToString() const;
+
+ void InterpretColumnList( const String& rString );
+
+ CharSet GetCharSet() const { return eCharSet; }
+ BOOL GetCharSetSystem() const { return bCharSetSystem; }
+ const String& GetFieldSeps() const { return aFieldSeps; }
+ BOOL IsMergeSeps() const { return bMergeFieldSeps; }
+ bool IsQuotedAsText() const { return bQuotedFieldAsText; }
+ bool IsDetectSpecialNumber() const { return bDetectSpecialNumber; }
+ sal_Unicode GetTextSep() const { return cTextSep; }
+ BOOL IsFixedLen() const { return bFixedLen; }
+ USHORT GetInfoCount() const { return nInfoCount; }
+ const xub_StrLen* GetColStart() const { return pColStart; }
+ const BYTE* GetColFormat() const { return pColFormat; }
+ long GetStartRow() const { return nStartRow; }
+ LanguageType GetLanguage() const { return eLang; }
+
+ void SetCharSet( CharSet eNew ) { eCharSet = eNew; }
+ void SetCharSetSystem( BOOL bSet ) { bCharSetSystem = bSet; }
+ void SetFixedLen( BOOL bSet ) { bFixedLen = bSet; }
+ void SetFieldSeps( const String& rStr ) { aFieldSeps = rStr; }
+ void SetMergeSeps( BOOL bSet ) { bMergeFieldSeps = bSet; }
+ void SetQuotedAsText(bool bSet) { bQuotedFieldAsText = bSet; }
+ void SetDetectSpecialNumber(bool bSet) { bDetectSpecialNumber = bSet; }
+ void SetTextSep( sal_Unicode c ) { cTextSep = c; }
+ void SetStartRow( long nRow) { nStartRow= nRow; }
+ void SetLanguage(LanguageType e) { eLang = e; }
+
+ void SetColInfo( USHORT nCount, const xub_StrLen* pStart, const BYTE* pFormat );
+ void SetColumnInfo( const ScCsvExpDataVec& rDataVec );
+};
+
+
+//CHINA001 // ============================================================================
+//CHINA001
+//CHINA001 class ScImportAsciiDlg : public ModalDialog
+//CHINA001 {
+//CHINA001 SvStream* pDatStream;
+//CHINA001 ULONG* pRowPosArray;
+//CHINA001 ULONG* pRowPosArrayUnicode;
+//CHINA001 USHORT nArrayEndPos;
+//CHINA001 USHORT nArrayEndPosUnicode;
+//CHINA001 ULONG nStreamPos;
+//CHINA001 ULONG nStreamPosUnicode;
+//CHINA001 BOOL bVFlag;
+//CHINA001
+//CHINA001 FixedLine aFlFieldOpt;
+//CHINA001 FixedText aFtCharSet;
+//CHINA001 SvxTextEncodingBox aLbCharSet;
+//CHINA001
+//CHINA001 FixedText aFtRow;
+//CHINA001 NumericField aNfRow;
+//CHINA001
+//CHINA001 FixedLine aFlSepOpt;
+//CHINA001 RadioButton aRbFixed;
+//CHINA001 RadioButton aRbSeparated;
+//CHINA001
+//CHINA001 CheckBox aCkbTab;
+//CHINA001 CheckBox aCkbSemicolon;
+//CHINA001 CheckBox aCkbComma;
+//CHINA001 CheckBox aCkbSpace;
+//CHINA001 CheckBox aCkbOther;
+//CHINA001 Edit aEdOther;
+//CHINA001 CheckBox aCkbAsOnce;
+//CHINA001 FixedText aFtTextSep;
+//CHINA001 ComboBox aCbTextSep;
+//CHINA001
+//CHINA001 FixedLine aFlWidth;
+//CHINA001 FixedText aFtType;
+//CHINA001 ListBox aLbType;
+//CHINA001
+//CHINA001 ScCsvTableBox maTableBox;
+//CHINA001
+//CHINA001 OKButton aBtnOk;
+//CHINA001 CancelButton aBtnCancel;
+//CHINA001 HelpButton aBtnHelp;
+//CHINA001
+//CHINA001 String aCharSetUser;
+//CHINA001 String aColumnUser;
+//CHINA001 String aFldSepList;
+//CHINA001 String aTextSepList;
+//CHINA001
+//CHINA001 // aPreviewLine contains the byte string as read from the file
+//CHINA001 ByteString aPreviewLine[ CSV_PREVIEW_LINES ];
+//CHINA001 // same for Unicode
+//CHINA001 String aPreviewLineUnicode[ CSV_PREVIEW_LINES ];
+//CHINA001
+//CHINA001 CharSet meCharSet; /// Selected char set.
+//CHINA001 bool mbCharSetSystem; /// Is System char set selected?
+//CHINA001
+//CHINA001 public:
+//CHINA001 ScImportAsciiDlg(
+//CHINA001 Window* pParent, String aDatName,
+//CHINA001 SvStream* pInStream, sal_Unicode cSep = '\t' );
+//CHINA001 ~ScImportAsciiDlg();
+//CHINA001
+//CHINA001 void GetOptions( ScAsciiOptions& rOpt );
+//CHINA001
+//CHINA001 private:
+//CHINA001 /** Sets the selected char set data to meCharSet and mbCharSetSystem. */
+//CHINA001 void SetSelectedCharSet();
+//CHINA001 /** Returns all separator characters in a string. */
+//CHINA001 String GetSeparators() const;
+//CHINA001
+//CHINA001 /** Enables or disables all separator checkboxes and edit fields. */
+//CHINA001 void SetupSeparatorCtrls();
+//CHINA001
+//CHINA001 void UpdateVertical( bool bSwitchToFromUnicode = false );
+//CHINA001
+//CHINA001 DECL_LINK( CharSetHdl, SvxTextEncodingBox* );
+//CHINA001 DECL_LINK( FirstRowHdl, NumericField* );
+//CHINA001 DECL_LINK( RbSepFixHdl, RadioButton* );
+//CHINA001 DECL_LINK( SeparatorHdl, Control* );
+//CHINA001 DECL_LINK( LbColTypeHdl, ListBox* );
+//CHINA001 DECL_LINK( UpdateTextHdl, ScCsvTableBox* );
+//CHINA001 DECL_LINK( ColTypeHdl, ScCsvTableBox* );
+//CHINA001 };
+//CHINA001
+//CHINA001
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/attrdlg.hrc b/sc/source/ui/inc/attrdlg.hrc
new file mode 100644
index 000000000000..f43c1cb30b86
--- /dev/null
+++ b/sc/source/ui/inc/attrdlg.hrc
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> SC_DLG_ATTR
+
+#define TP_NUMBER 1
+#define TP_FONT 2
+#define TP_ALIGNMENT 3
+#define TP_BORDER 4
+#define TP_BACKGROUND 5
+#define TP_PROTECTION 6
+#define TP_FONTEFF 7
+#define TP_ASIAN 8
+
+//================================================
+// Zellschutz-TabPage:
+
+#define BTN_PROTECTED 1
+#define BTN_HIDE_FORMULAR 2
+#define BTN_HIDE_ALL 3
+#define FT_HINT 4
+#define FL_PROTECTION 5
+#define BTN_HIDE_PRINT 6
+#define FT_HINT2 7
+#define FL_PRINT 8
+
+
diff --git a/sc/source/ui/inc/attrdlg.hxx b/sc/source/ui/inc/attrdlg.hxx
new file mode 100644
index 000000000000..752ee01ddd62
--- /dev/null
+++ b/sc/source/ui/inc/attrdlg.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ATTRDLG_HXX
+#define SC_ATTRDLG_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+class Window;
+class SfxViewFrame;
+class SfxItemSet;
+
+#ifndef LAYOUT_SFX_TABDIALOG_BROKEN
+#define LAYOUT_SFX_TABDIALOG_BROKEN 1
+#endif /* !LAYOUT_SFX_TABDIALOG_BROKEN */
+
+#if !LAYOUT_SFX_TABDIALOG_BROKEN
+#include <sfx2/layout.hxx>
+#include <layout/layout-pre.hxx>
+#endif
+
+//==================================================================
+
+class ScAttrDlg : public SfxTabDialog
+{
+public:
+ ScAttrDlg( SfxViewFrame* pFrame,
+ Window* pParent,
+ const SfxItemSet* pCellAttrs );
+ ~ScAttrDlg();
+
+protected:
+ virtual void PageCreated( USHORT nPageId, SfxTabPage& rTabPage );
+
+private:
+ DECL_LINK( OkHandler, void* ); // fuer DoppelClick-Beenden in TabPages
+};
+
+#if !LAYOUT_SFX_TABDIALOG_BROKEN
+#include <layout/layout-post.hxx>
+#endif
+
+#endif // SC_ATTRDLG_HXX
+
+
diff --git a/sc/source/ui/inc/auditsh.hxx b/sc/source/ui/inc/auditsh.hxx
new file mode 100644
index 000000000000..75059f4f88cc
--- /dev/null
+++ b/sc/source/ui/inc/auditsh.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_AUDITSH_HXX
+#define SC_AUDITSH_HXX
+
+#include <sfx2/shell.hxx>
+#include <sfx2/module.hxx>
+
+#include "shellids.hxx"
+
+class ScViewData;
+
+class ScAuditingShell : public SfxShell
+{
+private:
+ ScViewData* pViewData;
+ USHORT nFunction;
+
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_AUDITING_SHELL)
+
+ ScAuditingShell(ScViewData* pData);
+ ~ScAuditingShell();
+
+ void Execute(SfxRequest& rReq);
+ void GetState(SfxItemSet& rSet);
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/autofmt.hxx b/sc/source/ui/inc/autofmt.hxx
new file mode 100644
index 000000000000..52a033c202b2
--- /dev/null
+++ b/sc/source/ui/inc/autofmt.hxx
@@ -0,0 +1,210 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_AUTOFMT_HXX
+#define SC_AUTOFMT_HXX
+
+#ifndef _VIRDEV_HXX //autogen
+#include <vcl/virdev.hxx>
+#endif
+#ifndef SV_FIXED_HXX
+#include <vcl/fixed.hxx>
+#endif
+#ifndef SV_LSTBOX_HXX
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#ifndef SV_MOREBTN_HXX
+#include <vcl/morebtn.hxx>
+#endif
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#include <svtools/scriptedtext.hxx>
+#include <svx/framelinkarray.hxx>
+#include "scdllapi.h"
+
+//------------------------------------------------------------------------
+
+class ScAutoFormat;
+class ScAutoFormatData;
+class SvxBoxItem;
+class SvxLineItem;
+class ScAutoFmtPreview; // s.u.
+class SvNumberFormatter;
+class ScDocument;
+
+//------------------------------------------------------------------------
+
+enum AutoFmtLine { TOP_LINE, BOTTOM_LINE, LEFT_LINE, RIGHT_LINE };
+
+//========================================================================
+
+//CHINA001 class ScAutoFormatDlg : public ModalDialog
+//CHINA001 {
+//CHINA001 public:
+//CHINA001 ScAutoFormatDlg( Window* pParent,
+//CHINA001 ScAutoFormat* pAutoFormat,
+//CHINA001 const ScAutoFormatData* pSelFormatData,
+//CHINA001 ScDocument* pDoc );
+//CHINA001 ~ScAutoFormatDlg();
+//CHINA001
+//CHINA001 USHORT GetIndex() const { return nIndex; }
+//CHINA001 String GetCurrFormatName();
+//CHINA001
+//CHINA001 private:
+//CHINA001 FixedLine aFlFormat;
+//CHINA001 ListBox aLbFormat;
+//CHINA001 ScAutoFmtPreview* pWndPreview;
+//CHINA001 OKButton aBtnOk;
+//CHINA001 CancelButton aBtnCancel;
+//CHINA001 HelpButton aBtnHelp;
+//CHINA001 PushButton aBtnAdd;
+//CHINA001 PushButton aBtnRemove;
+//CHINA001 MoreButton aBtnMore;
+//CHINA001 FixedLine aFlFormatting;
+//CHINA001 CheckBox aBtnNumFormat;
+//CHINA001 CheckBox aBtnBorder;
+//CHINA001 CheckBox aBtnFont;
+//CHINA001 CheckBox aBtnPattern;
+//CHINA001 CheckBox aBtnAlignment;
+//CHINA001 CheckBox aBtnAdjust;
+//CHINA001 PushButton aBtnRename;
+//CHINA001 String aStrTitle;
+//CHINA001 String aStrLabel;
+//CHINA001 String aStrClose;
+//CHINA001 String aStrDelTitle;
+//CHINA001 String aStrDelMsg;
+//CHINA001 String aStrRename;
+//CHINA001
+//CHINA001 //------------------------
+//CHINA001 ScAutoFormat* pFormat;
+//CHINA001 const ScAutoFormatData* pSelFmtData;
+//CHINA001 USHORT nIndex;
+//CHINA001 BOOL bCoreDataChanged;
+//CHINA001 BOOL bFmtInserted;
+//CHINA001
+//CHINA001 void Init ();
+//CHINA001 void UpdateChecks ();
+//CHINA001 //------------------------
+//CHINA001 DECL_LINK( CheckHdl, Button * );
+//CHINA001 DECL_LINK( AddHdl, void * );
+//CHINA001 DECL_LINK( RemoveHdl, void * );
+//CHINA001 DECL_LINK( SelFmtHdl, void * );
+//CHINA001 DECL_LINK( CloseHdl, PushButton * );
+//CHINA001 DECL_LINK( DblClkHdl, void * );
+//CHINA001 DECL_LINK( RenameHdl, void *);
+//CHINA001
+//CHINA001 };
+//CHINA001
+//========================================================================
+
+class SC_DLLPUBLIC ScAutoFmtPreview : public Window
+{
+public:
+ ScAutoFmtPreview( Window* pParent, const ResId& rRes, ScDocument* pDoc );
+ ~ScAutoFmtPreview();
+
+ void NotifyChange( ScAutoFormatData* pNewData );
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+
+private:
+ ScAutoFormatData* pCurData;
+ VirtualDevice aVD;
+ SvtScriptedTextHelper aScriptedText;
+ ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xBreakIter;
+ BOOL bFitWidth;
+ svx::frame::Array maArray; /// Implementation to draw the frame borders.
+ bool mbRTL;
+ Size aPrvSize;
+ long mnLabelColWidth;
+ long mnDataColWidth1;
+ long mnDataColWidth2;
+ long mnRowHeight;
+ const String aStrJan;
+ const String aStrFeb;
+ const String aStrMar;
+ const String aStrNorth;
+ const String aStrMid;
+ const String aStrSouth;
+ const String aStrSum;
+ SvNumberFormatter* pNumFmt;
+ //-------------------------------------------
+ SC_DLLPRIVATE void Init ();
+ SC_DLLPRIVATE void DoPaint ( const Rectangle& rRect );
+ SC_DLLPRIVATE void CalcCellArray ( BOOL bFitWidth );
+ SC_DLLPRIVATE void CalcLineMap ();
+ SC_DLLPRIVATE void PaintCells ();
+
+/* Usage of type size_t instead of SCCOL/SCROW is correct here - used in
+ conjunction with class svx::frame::Array (svx/framelinkarray.hxx), which
+ expects size_t coordinates. */
+
+ SC_DLLPRIVATE USHORT GetFormatIndex( size_t nCol, size_t nRow ) const;
+ SC_DLLPRIVATE const SvxBoxItem& GetBoxItem( size_t nCol, size_t nRow ) const;
+ SC_DLLPRIVATE const SvxLineItem& GetDiagItem( size_t nCol, size_t nRow, bool bTLBR ) const;
+
+ SC_DLLPRIVATE void DrawString( size_t nCol, size_t nRow );
+ SC_DLLPRIVATE void DrawStrings();
+ SC_DLLPRIVATE void DrawBackground();
+
+ SC_DLLPRIVATE void MakeFonts ( USHORT nIndex,
+ Font& rFont,
+ Font& rCJKFont,
+ Font& rCTLFont );
+
+ SC_DLLPRIVATE String MakeNumberString( String cellString, BOOL bAddDec );
+ SC_DLLPRIVATE void DrawFrameLine ( const SvxBorderLine& rLineD,
+ Point from,
+ Point to,
+ BOOL bHorizontal,
+ const SvxBorderLine& rLineLT,
+ const SvxBorderLine& rLineL,
+ const SvxBorderLine& rLineLB,
+ const SvxBorderLine& rLineRT,
+ const SvxBorderLine& rLineR,
+ const SvxBorderLine& rLineRB );
+ SC_DLLPRIVATE void CheckPriority ( USHORT nCurLine,
+ AutoFmtLine eLine,
+ SvxBorderLine& rLine );
+ SC_DLLPRIVATE void GetLines ( USHORT nIndex, AutoFmtLine eLine,
+ SvxBorderLine& rLineD,
+ SvxBorderLine& rLineLT,
+ SvxBorderLine& rLineL,
+ SvxBorderLine& rLineLB,
+ SvxBorderLine& rLineRT,
+ SvxBorderLine& rLineR,
+ SvxBorderLine& rLineRB );
+};
+
+#endif // SC_AUTOFMT_HXX
+
+
diff --git a/sc/source/ui/inc/autostyl.hxx b/sc/source/ui/inc/autostyl.hxx
new file mode 100644
index 000000000000..5540ecf87aac
--- /dev/null
+++ b/sc/source/ui/inc/autostyl.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_AUTOSTYL_HXX
+#define SC_AUTOSTYL_HXX
+
+#include <vcl/timer.hxx>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+
+class ScDocShell;
+class ScRange;
+
+class ScAutoStyleList
+{
+private:
+ ScDocShell* pDocSh;
+ Timer aTimer;
+ Timer aInitTimer;
+ ULONG nTimerStart;
+ List aEntries;
+ List aInitials;
+
+ void ExecuteEntries();
+ void AdjustEntries(ULONG nDiff);
+ void StartTimer(ULONG nNow);
+ DECL_LINK( TimerHdl, Timer* );
+ DECL_LINK( InitHdl, Timer* );
+
+public:
+ ScAutoStyleList(ScDocShell* pShell);
+ ~ScAutoStyleList();
+
+ void AddInitial( const ScRange& rRange, const String& rStyle1,
+ ULONG nTimeout, const String& rStyle2 );
+ void AddEntry( ULONG nTimeout, const ScRange& rRange, const String& rStyle );
+
+ void ExecuteAllNow();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/cbutton.hxx b/sc/source/ui/inc/cbutton.hxx
new file mode 100644
index 000000000000..8de5dafe7768
--- /dev/null
+++ b/sc/source/ui/inc/cbutton.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//------------------------------------------------------------------
+
+#ifndef SC_CBUTTON_HXX
+#define SC_CBUTTON_HXX
+
+#include <tools/gen.hxx>
+#include <tools/color.hxx>
+
+class OutputDevice;
+
+
+//==================================================================
+
+class ScDDComboBoxButton
+{
+public:
+ ScDDComboBoxButton( OutputDevice* pOutputDevice );
+ ~ScDDComboBoxButton();
+
+ void SetOutputDevice( OutputDevice* pOutputDevice );
+
+ void Draw( const Point& rAt,
+ const Size& rSize,
+ BOOL bState,
+ BOOL bBtnIn = FALSE );
+
+ void Draw( const Point& rAt,
+ BOOL bState,
+ BOOL bBtnIn = FALSE )
+ { Draw( rAt, aBtnSize, bState, bBtnIn ); }
+
+ void Draw( BOOL bState,
+ BOOL bBtnIn = FALSE )
+ { Draw( aBtnPos, aBtnSize, bState, bBtnIn ); }
+
+ void SetOptSizePixel();
+
+ void SetPosPixel( const Point& rNewPos ) { aBtnPos = rNewPos; }
+ Point GetPosPixel() const { return aBtnPos; }
+
+ void SetSizePixel( const Size& rNewSize ) { aBtnSize = rNewSize; }
+ Size GetSizePixel() const { return aBtnSize; }
+
+private:
+ void ImpDrawArrow( const Rectangle& rRect,
+ BOOL bState );
+
+protected:
+ OutputDevice* pOut;
+ Point aBtnPos;
+ Size aBtnSize;
+};
+
+
+#endif // SC_CBUTTON_HXX
+
+
diff --git a/sc/source/ui/inc/cellsh.hxx b/sc/source/ui/inc/cellsh.hxx
new file mode 100644
index 000000000000..563e18d96656
--- /dev/null
+++ b/sc/source/ui/inc/cellsh.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CELLSH_HXX
+#define SC_CELLSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+#include <tools/link.hxx>
+#include "formatsh.hxx"
+
+class SvxClipboardFmtItem;
+class TransferableDataHelper;
+class TransferableClipboardListener;
+class AbstractScLinkedAreaDlg;
+class ScTabViewShell;
+
+struct CellShell_Impl
+{
+ TransferableClipboardListener* m_pClipEvtLstnr;
+ AbstractScLinkedAreaDlg* m_pLinkedDlg;
+ SfxRequest* m_pRequest;
+
+ CellShell_Impl() :
+ m_pClipEvtLstnr( NULL ),
+ m_pLinkedDlg( NULL ),
+ m_pRequest( NULL ) {}
+};
+
+class ScCellShell: public ScFormatShell
+{
+private:
+ CellShell_Impl* pImpl;
+ BOOL bPastePossible;
+
+ void GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats );
+ void ExecuteExternalSource(
+ const String& _rFile, const String& _rFilter, const String& _rOptions,
+ const String& _rSource, ULONG _nRefresh, SfxRequest& _rRequest );
+
+ DECL_LINK( ClipboardChanged, TransferableDataHelper* );
+ DECL_LINK( DialogClosed, AbstractScLinkedAreaDlg* );
+
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_CELL_SHELL)
+
+ ScCellShell(ScViewData* pData);
+ virtual ~ScCellShell();
+
+ void Execute(SfxRequest &);
+ void GetState(SfxItemSet &);
+
+ void ExecuteEdit( SfxRequest& rReq );
+ void ExecuteTrans( SfxRequest& rReq );
+
+ void GetBlockState( SfxItemSet& rSet );
+ void GetCellState( SfxItemSet& rSet );
+
+ void ExecuteDB( SfxRequest& rReq );
+ void GetDBState( SfxItemSet& rSet );
+
+ void ExecImageMap(SfxRequest& rReq); // ImageMap
+ void GetImageMapState(SfxItemSet& rSet);
+
+ void GetClipState( SfxItemSet& rSet );
+ void GetHLinkState( SfxItemSet& rSet );
+
+ void ExecuteCursor( SfxRequest& rReq );
+ void ExecuteCursorSel( SfxRequest& rReq );
+ void ExecutePage( SfxRequest& rReq );
+ void ExecutePageSel( SfxRequest& rReq );
+ void ExecuteMove( SfxRequest& rReq );
+ void GetStateCursor( SfxItemSet& rSet );
+
+ static void PasteFromClipboard( ScViewData* pViewData, ScTabViewShell* pTabViewShell, bool bShowDialog );
+};
+
+#endif
diff --git a/sc/source/ui/inc/chartsh.hxx b/sc/source/ui/inc/chartsh.hxx
new file mode 100644
index 000000000000..95efd03f3b76
--- /dev/null
+++ b/sc/source/ui/inc/chartsh.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CHARTSH_HXX
+#define CHARTSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+
+class ScViewData;
+
+#include "drawsh.hxx"
+
+class ScChartShell: public ScDrawShell
+{
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_CHART_SHELL)
+
+ ScChartShell(ScViewData* pData);
+ virtual ~ScChartShell();
+
+};
+
+#endif
diff --git a/sc/source/ui/inc/client.hxx b/sc/source/ui/inc/client.hxx
new file mode 100644
index 000000000000..1b13ee224d77
--- /dev/null
+++ b/sc/source/ui/inc/client.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CLIENT_HXX
+#define SC_CLIENT_HXX
+
+#ifndef _SFX_CLIENTSH_HXX //autogen
+#include <sfx2/ipclient.hxx>
+#endif
+
+class ScDocument;
+class ScTabViewShell;
+class SdrOle2Obj;
+class SdrGrafObj;
+class SdrModel;
+
+class ScClient : public SfxInPlaceClient
+{
+private:
+ SdrModel* pModel;
+ SdrGrafObj* pGrafEdit;
+
+ virtual void ObjectAreaChanged();
+ virtual void RequestNewObjectArea( Rectangle& );
+ virtual void ViewChanged();
+ virtual void MakeVisible();
+
+public:
+ ScClient( ScTabViewShell* pViewShell, Window* pDraw, SdrModel* pSdrModel, SdrOle2Obj* pObj );
+ virtual ~ScClient();
+
+ SdrGrafObj* GetGrafEdit() const { return pGrafEdit; }
+ void SetGrafEdit(SdrGrafObj* pNew) { pGrafEdit = pNew; }
+ SdrOle2Obj* GetDrawObj();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/colrowba.hxx b/sc/source/ui/inc/colrowba.hxx
new file mode 100644
index 000000000000..587412defea2
--- /dev/null
+++ b/sc/source/ui/inc/colrowba.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_COLROWBAR_HXX
+#define SC_COLROWBAR_HXX
+
+#include "hdrcont.hxx"
+#include "viewdata.hxx"
+
+class ScHeaderFunctionSet;
+class ScHeaderSelectionEngine;
+
+// ---------------------------------------------------------------------------
+
+
+class ScColBar : public ScHeaderControl
+{
+ ScViewData* pViewData;
+ ScHSplitPos eWhich;
+ ScHeaderFunctionSet* pFuncSet;
+ ScHeaderSelectionEngine* pSelEngine;
+
+public:
+ ScColBar( Window* pParent, ScViewData* pData, ScHSplitPos eWhichPos,
+ ScHeaderFunctionSet* pFunc, ScHeaderSelectionEngine* pEng );
+ ~ScColBar();
+
+ virtual SCCOLROW GetPos();
+ virtual USHORT GetEntrySize( SCCOLROW nEntryNo );
+ virtual String GetEntryText( SCCOLROW nEntryNo );
+
+ virtual BOOL IsLayoutRTL(); // only for columns
+
+ virtual void SetEntrySize( SCCOLROW nPos, USHORT nNewSize );
+ virtual void HideEntries( SCCOLROW nStart, SCCOLROW nEnd );
+
+ virtual void SetMarking( BOOL bSet );
+ virtual void SelectWindow();
+ virtual BOOL IsDisabled();
+ virtual BOOL ResizeAllowed();
+
+ virtual void DrawInvert( long nDragPos );
+
+ virtual String GetDragHelp( long nVal );
+
+ BOOL UseNumericHeader() const;
+};
+
+
+class ScRowBar : public ScHeaderControl
+{
+ ScViewData* pViewData;
+ ScVSplitPos eWhich;
+ ScHeaderFunctionSet* pFuncSet;
+ ScHeaderSelectionEngine* pSelEngine;
+
+public:
+ ScRowBar( Window* pParent, ScViewData* pData, ScVSplitPos eWhichPos,
+ ScHeaderFunctionSet* pFunc, ScHeaderSelectionEngine* pEng );
+ ~ScRowBar();
+
+ virtual SCCOLROW GetPos();
+ virtual USHORT GetEntrySize( SCCOLROW nEntryNo );
+ virtual String GetEntryText( SCCOLROW nEntryNo );
+
+ virtual BOOL IsMirrored(); // only for columns
+ virtual SCROW GetHiddenCount( SCROW nEntryNo ); // only for columns
+
+ virtual void SetEntrySize( SCCOLROW nPos, USHORT nNewSize );
+ virtual void HideEntries( SCCOLROW nStart, SCCOLROW nEnd );
+
+ virtual void SetMarking( BOOL bSet );
+ virtual void SelectWindow();
+ virtual BOOL IsDisabled();
+ virtual BOOL ResizeAllowed();
+
+ virtual void DrawInvert( long nDragPos );
+
+ virtual String GetDragHelp( long nVal );
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/condfrmt.hrc b/sc/source/ui/inc/condfrmt.hrc
new file mode 100644
index 000000000000..099d82b2fa85
--- /dev/null
+++ b/sc/source/ui/inc/condfrmt.hrc
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // ->RID_SCDLG_SOLVER
+
+#define CBX_COND1 1
+#define LB_COND1_1 2
+#define LB_COND1_2 3
+#define EDT_COND1_1 4
+#define RB_COND1_1 5
+#define FT_COND1_AND 6
+#define EDT_COND1_2 7
+#define RB_COND1_2 8
+#define FT_COND1_TEMPLATE 9
+#define LB_COND1_TEMPLATE 10
+
+#define CBX_COND2 11
+#define LB_COND2_1 12
+#define LB_COND2_2 13
+#define EDT_COND2_1 14
+#define RB_COND2_1 15
+#define FT_COND2_AND 16
+#define EDT_COND2_2 17
+#define RB_COND2_2 18
+#define FT_COND2_TEMPLATE 19
+#define LB_COND2_TEMPLATE 20
+
+#define CBX_COND3 21
+#define LB_COND3_1 22
+#define LB_COND3_2 23
+#define EDT_COND3_1 24
+#define RB_COND3_1 25
+#define FT_COND3_AND 26
+#define EDT_COND3_2 27
+#define RB_COND3_2 28
+#define FT_COND3_TEMPLATE 29
+#define LB_COND3_TEMPLATE 30
+
+#define FL_SEP1 41
+#define FL_SEP2 42
+
+#define BTN_OK 31
+#define BTN_CANCEL 32
+#define BTN_HELP 33
+
+#define BTN_COND1_NEW 34
+#define BTN_COND2_NEW 35
+#define BTN_COND3_NEW 36
+
diff --git a/sc/source/ui/inc/condfrmt.hxx b/sc/source/ui/inc/condfrmt.hxx
new file mode 100644
index 000000000000..ecd4c529d57a
--- /dev/null
+++ b/sc/source/ui/inc/condfrmt.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_CONDFRMT_HXX_
+#define SC_CONDFRMT_HXX_
+
+#include "anyrefdg.hxx"
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+
+
+class ScDocument;
+class ScConditionalFormat;
+
+
+//============================================================================
+// class ScConditionalFormat
+//
+// Dialog zum Festlegen von bedingten Formaten
+
+class ScConditionalFormatDlg : public ScAnyRefDlg
+{
+public:
+ ScConditionalFormatDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocument* pCurDoc,
+ const ScConditionalFormat* pCurrentFormat );
+ ~ScConditionalFormatDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual void AddRefEntry();
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+ virtual BOOL Close();
+
+private:
+ CheckBox aCbxCond1;
+ ListBox aLbCond11;
+ ListBox aLbCond12;
+ formula::RefEdit aEdtCond11;
+ formula::RefButton aRbCond11;
+ FixedText aFtCond1And;
+ formula::RefEdit aEdtCond12;
+ formula::RefButton aRbCond12;
+ FixedText aFtCond1Template;
+ ListBox aLbCond1Template;
+ PushButton aBtnNew1;
+ FixedLine aFlSep1;
+
+ CheckBox aCbxCond2;
+ ListBox aLbCond21;
+ ListBox aLbCond22;
+ formula::RefEdit aEdtCond21;
+ formula::RefButton aRbCond21;
+ FixedText aFtCond2And;
+ formula::RefEdit aEdtCond22;
+ formula::RefButton aRbCond22;
+ FixedText aFtCond2Template;
+ ListBox aLbCond2Template;
+ PushButton aBtnNew2;
+ FixedLine aFlSep2;
+
+ CheckBox aCbxCond3;
+ ListBox aLbCond31;
+ ListBox aLbCond32;
+ formula::RefEdit aEdtCond31;
+ formula::RefButton aRbCond31;
+ FixedText aFtCond3And;
+ formula::RefEdit aEdtCond32;
+ formula::RefButton aRbCond32;
+ FixedText aFtCond3Template;
+ ListBox aLbCond3Template;
+ PushButton aBtnNew3;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ Point aCond1Pos1;
+ Point aCond1Pos2;
+ Point aRBtn1Pos1;
+ Point aRBtn1Pos2;
+ Size aCond1Size1;
+ Size aCond1Size2;
+ Size aCond1Size3;
+
+ Point aCond2Pos1;
+ Point aCond2Pos2;
+ Point aRBtn2Pos1;
+ Point aRBtn2Pos2;
+ Size aCond2Size1;
+ Size aCond2Size2;
+ Size aCond2Size3;
+
+ Point aCond3Pos1;
+ Point aCond3Pos2;
+ Point aRBtn3Pos1;
+ Point aRBtn3Pos2;
+ Size aCond3Size1;
+ Size aCond3Size2;
+ Size aCond3Size3;
+
+ formula::RefEdit* pEdActive;
+ BOOL bDlgLostFocus;
+ ScDocument* pDoc;
+
+#ifdef _CONDFRMT_CXX
+ void GetConditionalFormat( ScConditionalFormat& rCndFmt );
+
+ DECL_LINK( ClickCond1Hdl, void * );
+ DECL_LINK( ChangeCond11Hdl, void * );
+ DECL_LINK( ChangeCond12Hdl, void * );
+
+ DECL_LINK( ClickCond2Hdl, void * );
+ DECL_LINK( ChangeCond21Hdl, void * );
+ DECL_LINK( ChangeCond22Hdl, void * );
+
+ DECL_LINK( ClickCond3Hdl, void * );
+ DECL_LINK( ChangeCond31Hdl, void * );
+ DECL_LINK( ChangeCond32Hdl, void * );
+
+ DECL_LINK( GetFocusHdl, Control* );
+ DECL_LINK( LoseFocusHdl, Control* );
+ DECL_LINK( BtnHdl, PushButton* );
+ DECL_LINK( NewBtnHdl, PushButton* );
+#endif // _CONDFRMT_CXX
+};
+
+#endif // SC_CONDFRMT_HXX_
+
+
diff --git a/sc/source/ui/inc/conflictsdlg.hrc b/sc/source/ui/inc/conflictsdlg.hrc
new file mode 100644
index 000000000000..7935a6ee21d7
--- /dev/null
+++ b/sc/source/ui/inc/conflictsdlg.hrc
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 FT_CONFLICTS 1
+#define LB_CONFLICTS 2
+#define BTN_KEEPMINE 3
+#define BTN_KEEPOTHER 4
+#define FL_CONFLICTS 5
+#define BTN_KEEPALLMINE 6
+#define BTN_KEEPALLOTHERS 7
+#define BTN_CANCEL 8
+#define BTN_HELP 9
+
+#define STR_TITLE_CONFLICT 1
+#define STR_TITLE_AUTHOR 2
+#define STR_TITLE_DATE 3
+#define STR_UNKNOWN_USER 4
diff --git a/sc/source/ui/inc/conflictsdlg.hxx b/sc/source/ui/inc/conflictsdlg.hxx
new file mode 100644
index 000000000000..faeecb370c78
--- /dev/null
+++ b/sc/source/ui/inc/conflictsdlg.hxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CONFLICTSDLG_HXX
+#define SC_CONFLICTSDLG_HXX
+
+#include <vcl/button.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <svx/ctredlin.hxx>
+
+#include "chgtrack.hxx"
+#include "docsh.hxx"
+
+class ScViewData;
+
+
+//=============================================================================
+
+enum ScConflictAction
+{
+ SC_CONFLICT_ACTION_NONE,
+ SC_CONFLICT_ACTION_KEEP_MINE,
+ SC_CONFLICT_ACTION_KEEP_OTHER
+};
+
+typedef ::std::vector< ULONG > ScChangeActionList;
+
+
+//=============================================================================
+// struct ScConflictsListEntry
+//=============================================================================
+
+struct ScConflictsListEntry
+{
+ ScConflictAction meConflictAction;
+ ScChangeActionList maSharedActions;
+ ScChangeActionList maOwnActions;
+
+ bool HasSharedAction( ULONG nSharedAction ) const;
+ bool HasOwnAction( ULONG nOwnAction ) const;
+};
+
+
+//=============================================================================
+
+typedef ::std::vector< ScConflictsListEntry > ScConflictsList;
+
+
+//=============================================================================
+// class ScConflictsListHelper
+//=============================================================================
+
+class ScConflictsListHelper
+{
+private:
+ static void Transform_Impl( ScChangeActionList& rActionList, ScChangeActionMergeMap* pMergeMap );
+
+public:
+//UNUSED2008-05 static bool HasSharedAction( ScConflictsList& rConflictsList, ULONG nSharedAction );
+ static bool HasOwnAction( ScConflictsList& rConflictsList, ULONG nOwnAction );
+
+ static ScConflictsListEntry* GetSharedActionEntry( ScConflictsList& rConflictsList, ULONG nSharedAction );
+ static ScConflictsListEntry* GetOwnActionEntry( ScConflictsList& rConflictsList, ULONG nOwnAction );
+
+ static void TransformConflictsList( ScConflictsList& rConflictsList,
+ ScChangeActionMergeMap* pSharedMap, ScChangeActionMergeMap* pOwnMap );
+};
+
+
+//=============================================================================
+// class ScConflictsFinder
+//=============================================================================
+
+class ScConflictsFinder
+{
+private:
+ ScChangeTrack* mpTrack;
+ ULONG mnStartShared;
+ ULONG mnEndShared;
+ ULONG mnStartOwn;
+ ULONG mnEndOwn;
+ ScConflictsList& mrConflictsList;
+
+ static bool DoActionsIntersect( const ScChangeAction* pAction1, const ScChangeAction* pAction2 );
+ ScConflictsListEntry* GetIntersectingEntry( const ScChangeAction* pAction ) const;
+ ScConflictsListEntry* GetEntry( ULONG nSharedAction, const ScChangeActionList& rOwnActions );
+
+public:
+ ScConflictsFinder( ScChangeTrack* pTrack, ULONG nStartShared, ULONG nEndShared,
+ ULONG nStartOwn, ULONG nEndOwn, ScConflictsList& rConflictsList );
+ virtual ~ScConflictsFinder();
+
+ bool Find();
+};
+
+
+//=============================================================================
+// class ScConflictsResolver
+//=============================================================================
+
+class ScConflictsResolver
+{
+private:
+ ScChangeTrack* mpTrack;
+ ScConflictsList& mrConflictsList;
+
+public:
+ ScConflictsResolver( ScChangeTrack* pTrack, ScConflictsList& rConflictsList );
+ virtual ~ScConflictsResolver();
+
+ void HandleAction( ScChangeAction* pAction, bool bIsSharedAction,
+ bool bHandleContentAction, bool bHandleNonContentAction );
+};
+
+
+//=============================================================================
+// class ScConflictsListBox
+//=============================================================================
+
+class ScConflictsListBox: public SvxRedlinTable
+{
+private:
+
+public:
+//UNUSED2008-05 ScConflictsListBox( Window* pParent, WinBits nBits = WB_BORDER );
+ ScConflictsListBox( Window* pParent, const ResId& rResId );
+ ~ScConflictsListBox();
+
+//UNUSED2008-05 ULONG GetRootEntryPos( const SvLBoxEntry* pRootEntry ) const;
+};
+
+//=============================================================================
+// class ScConflictsDlg
+//=============================================================================
+
+class ScConflictsDlg : public ModalDialog
+{
+private:
+ FixedText maFtConflicts;
+ ScConflictsListBox maLbConflicts;
+ PushButton maBtnKeepMine;
+ PushButton maBtnKeepOther;
+ FixedLine maFlConflicts;
+ PushButton maBtnKeepAllMine;
+ PushButton maBtnKeepAllOthers;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ String maStrTitleConflict;
+ String maStrTitleAuthor;
+ String maStrTitleDate;
+ String maStrUnknownUser;
+
+ ScViewData* mpViewData;
+ ScDocument* mpOwnDoc;
+ ScChangeTrack* mpOwnTrack;
+ ScDocument* mpSharedDoc;
+ ScChangeTrack* mpSharedTrack;
+ ScConflictsList& mrConflictsList;
+ Size maDialogSize;
+
+ Timer maSelectionTimer;
+ bool mbInSelectHdl;
+ bool mbInDeselectHdl;
+
+ String GetConflictString( const ScConflictsListEntry& rConflictEntry );
+ String GetActionString( const ScChangeAction* pAction, ScDocument* pDoc );
+ void HandleListBoxSelection( bool bSelectHandle );
+
+ void SetConflictAction( SvLBoxEntry* pRootEntry, ScConflictAction eConflictAction );
+ void KeepHandler( bool bMine );
+ void KeepAllHandler( bool bMine );
+
+ DECL_LINK( SelectHandle, SvxRedlinTable* );
+ DECL_LINK( DeselectHandle, SvxRedlinTable* );
+ DECL_LINK( UpdateSelectionHdl, Timer* );
+ DECL_LINK( KeepMineHandle, void* );
+ DECL_LINK( KeepOtherHandle, void* );
+ DECL_LINK( KeepAllMineHandle, void* );
+ DECL_LINK( KeepAllOthersHandle, void* );
+
+public:
+ ScConflictsDlg( Window* pParent, ScViewData* pViewData, ScDocument* pSharedDoc, ScConflictsList& rConflictsList );
+ ~ScConflictsDlg();
+
+ virtual void Resize();
+ void UpdateView();
+};
+
+#endif
diff --git a/sc/source/ui/inc/consdlg.hxx b/sc/source/ui/inc/consdlg.hxx
new file mode 100644
index 000000000000..e82e2619cce0
--- /dev/null
+++ b/sc/source/ui/inc/consdlg.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CONSDLG_HXX
+#define SC_CONSDLG_HXX
+
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#include "global.hxx"
+#include "anyrefdg.hxx"
+
+class ScViewData;
+class ScDocument;
+class ScRangeUtil;
+class ScAreaData;
+
+
+//============================================================================
+
+class ScConsolidateDlg : public ScAnyRefDlg
+{
+public:
+ ScConsolidateDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScConsolidateDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+
+ virtual BOOL IsRefInputMode() const { return TRUE; }
+ virtual void SetActive();
+
+ virtual BOOL Close();
+
+protected:
+ virtual void Deactivate();
+
+private:
+ FixedText aFtFunc;
+ ListBox aLbFunc;
+
+ FixedText aFtConsAreas;
+ MultiListBox aLbConsAreas;
+
+ ListBox aLbDataArea;
+ FixedText aFtDataArea;
+ formula::RefEdit aEdDataArea;
+ formula::RefButton aRbDataArea;
+
+ ListBox aLbDestArea;
+ FixedText aFtDestArea;
+ formula::RefEdit aEdDestArea;
+ formula::RefButton aRbDestArea;
+
+ FixedLine aFlConsBy;
+ CheckBox aBtnByRow;
+ CheckBox aBtnByCol;
+
+ FixedLine aFlSep;
+ FixedLine aFlOptions;
+ CheckBox aBtnRefs;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ PushButton aBtnAdd;
+ PushButton aBtnRemove;
+ MoreButton aBtnMore;
+
+ String aStrUndefined;
+
+ ScConsolidateParam theConsData;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ ScRangeUtil* pRangeUtil;
+ ScAreaData* pAreaData;
+ USHORT nAreaDataCount;
+ USHORT nWhichCons;
+
+ formula::RefEdit* pRefInputEdit;
+ BOOL bDlgLostFocus;
+
+#ifdef _CONSDLG_CXX
+private:
+ void Init ();
+ void FillAreaLists ();
+ BOOL VerifyEdit ( formula::RefEdit* pEd );
+
+ DECL_LINK( OkHdl, void* );
+ DECL_LINK( ClickHdl, PushButton* );
+ DECL_LINK( GetFocusHdl, Control* );
+ DECL_LINK( ModifyHdl, formula::RefEdit* );
+ DECL_LINK( SelectHdl, ListBox* );
+
+ ScSubTotalFunc LbPosToFunc( USHORT nPos );
+ USHORT FuncToLbPos( ScSubTotalFunc eFunc );
+#endif // _CONSDLG_CXX
+};
+
+
+
+#endif // SC_CONSDLG_HXX
+
diff --git a/sc/source/ui/inc/content.hxx b/sc/source/ui/inc/content.hxx
new file mode 100644
index 000000000000..b7d4d292c406
--- /dev/null
+++ b/sc/source/ui/inc/content.hxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CONTENT_HXX
+#define SC_CONTENT_HXX
+
+#include <svtools/svtreebx.hxx>
+#include "global.hxx"
+#include "address.hxx"
+#include <tools/solar.h>
+
+class ScNavigatorDlg;
+class ScNavigatorSettings;
+class ScDocument;
+class ScDocShell;
+class ScAreaLink;
+
+#define SC_CONTENT_ROOT 0
+#define SC_CONTENT_TABLE 1
+#define SC_CONTENT_RANGENAME 2
+#define SC_CONTENT_DBAREA 3
+#define SC_CONTENT_GRAPHIC 4
+#define SC_CONTENT_OLEOBJECT 5
+#define SC_CONTENT_NOTE 6
+#define SC_CONTENT_AREALINK 7
+#define SC_CONTENT_DRAWING 8
+#define SC_CONTENT_COUNT 9
+
+const ULONG SC_CONTENT_NOCHILD = ~0UL;
+
+//
+// TreeListBox fuer Inhalte
+//
+
+class ScContentTree : public SvTreeListBox
+{
+ ScNavigatorDlg* pParentWindow;
+ ImageList aEntryImages;
+ ImageList aHCEntryImages;
+ SvLBoxEntry* pRootNodes[SC_CONTENT_COUNT];
+ USHORT nRootType; // als Root eingestellt
+ String aManualDoc; // im Navigator umgeschaltet (Title)
+ BOOL bHiddenDoc; // verstecktes aktiv?
+ String aHiddenName; // URL zum Laden
+ String aHiddenTitle; // fuer Anzeige
+ ScDocument* pHiddenDocument; // temporaer
+
+ USHORT pPosList[SC_CONTENT_COUNT]; // fuer die Reihenfolge
+
+ static BOOL bIsInDrag; // static, falls der Navigator im ExecuteDrag geloescht wird
+
+ ScDocShell* GetManualOrCurrent();
+
+ void InitRoot(USHORT nType);
+ void ClearType(USHORT nType);
+ void ClearAll();
+ void InsertContent( USHORT nType, const String& rValue );
+ void GetDrawNames( USHORT nType );
+
+ void GetTableNames();
+ void GetAreaNames();
+ void GetDbNames();
+ void GetLinkNames();
+ void GetGraphicNames();
+ void GetOleNames();
+ void GetDrawingNames();
+ void GetNoteStrings();
+
+ static bool IsPartOfType( USHORT nContentType, USHORT nObjIdentifier );
+
+ BOOL DrawNamesChanged( USHORT nType );
+ BOOL NoteStringsChanged();
+
+ ScAddress GetNotePos( ULONG nIndex );
+ const ScAreaLink* GetLink( ULONG nIndex );
+
+ /** Returns the indexes of the specified listbox entry.
+ @param rnRootIndex Root index of specified entry is returned.
+ @param rnChildIndex Index of the entry inside its root is returned (or SC_CONTENT_NOCHILD if entry is root).
+ @param pEntry The entry to examine. */
+ void GetEntryIndexes( USHORT& rnRootIndex, ULONG& rnChildIndex, SvLBoxEntry* pEntry ) const;
+
+ /** Returns the child index of the specified listbox entry.
+ @param pEntry The entry to examine or NULL for the selected entry.
+ @return Index of the entry inside its root or SC_CONTENT_NOCHILD if entry is root. */
+ ULONG GetChildIndex( SvLBoxEntry* pEntry ) const;
+
+ void DoDrag();
+//UNUSED2008-05 void AdjustTitle();
+
+ ScDocument* GetSourceDocument();
+
+ DECL_LINK( ContentDoubleClickHdl, ScContentTree* );
+ DECL_STATIC_LINK( ScContentTree, ExecDragHdl, void* );
+
+protected:
+// virtual BOOL Drop( const DropEvent& rEvt );
+// virtual BOOL QueryDrop( DropEvent& rEvt );
+
+ using SvTreeListBox::ExecuteDrop;
+
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel );
+ virtual void DragFinished( sal_Int8 nAction );
+
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void RequestHelp( const HelpEvent& rHEvt );
+
+public:
+ ScContentTree( Window* pParent, const ResId& rResId );
+ ~ScContentTree();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+
+ void InitWindowBits( BOOL bButtons );
+
+ void Refresh( USHORT nType = 0 );
+
+ void ToggleRoot();
+ void SetRootType( USHORT nNew );
+ USHORT GetRootType() const { return nRootType; }
+
+ void ActiveDocChanged();
+ void ResetManualDoc();
+ void SetManualDoc(const String& rName);
+ BOOL LoadFile(const String& rUrl);
+ void SelectDoc(const String& rName);
+
+ const String& GetHiddenTitle() const { return aHiddenTitle; }
+
+ /** Applies the navigator settings to the listbox. */
+ void ApplySettings();
+ /** Stores the current listbox state in the navigator settings. */
+ void StoreSettings() const;
+
+ static BOOL IsInDrag() { return bIsInDrag; }
+};
+
+
+
+
+#endif // SC_NAVIPI_HXX
+
diff --git a/sc/source/ui/inc/corodlg.hxx b/sc/source/ui/inc/corodlg.hxx
new file mode 100644
index 000000000000..424326565619
--- /dev/null
+++ b/sc/source/ui/inc/corodlg.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CORODLG_HXX
+#define SC_CORODLG_HXX
+
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+
+#include "sc.hrc"
+#include "scresid.hxx"
+
+//------------------------------------------------------------------------
+
+class ScColRowLabelDlg : public ModalDialog
+{
+public:
+ ScColRowLabelDlg( Window* pParent,
+ BOOL bCol = FALSE,
+ BOOL bRow = FALSE )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_CHARTCOLROW ) ),
+ aFlColRow ( this, ScResId(6) ),
+ aBtnRow ( this, ScResId(2) ),
+ aBtnCol ( this, ScResId(1) ),
+ aBtnOk ( this, ScResId(3) ),
+ aBtnCancel ( this, ScResId(4) ),
+ aBtnHelp ( this, ScResId(5) )
+ {
+ FreeResource();
+ aBtnCol.Check( bCol );
+ aBtnRow.Check( bRow );
+ }
+
+ BOOL IsCol() { return aBtnCol.IsChecked(); }
+ BOOL IsRow() { return aBtnRow.IsChecked(); }
+
+private:
+ FixedLine aFlColRow;
+ CheckBox aBtnRow;
+ CheckBox aBtnCol;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+};
+
+
+#endif
+
+
+
diff --git a/sc/source/ui/inc/crdlg.hxx b/sc/source/ui/inc/crdlg.hxx
new file mode 100644
index 000000000000..20dd79f359ad
--- /dev/null
+++ b/sc/source/ui/inc/crdlg.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CRDLG_HXX
+#define SC_CRDLG_HXX
+
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+#include "scui_def.hxx" //CHINA001
+
+//CHINA001 #define SCRET_COLS 0x42
+//CHINA001 #define SCRET_ROWS 0x43
+
+//------------------------------------------------------------------------
+
+class ScColOrRowDlg : public ModalDialog
+{
+public:
+ ScColOrRowDlg( Window* pParent,
+ const String& rStrTitle,
+ const String& rStrLabel,
+ BOOL bColDefault = TRUE );
+ ~ScColOrRowDlg();
+
+private:
+ FixedLine aFlFrame;
+ RadioButton aBtnRows;
+ RadioButton aBtnCols;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ DECL_LINK( OkHdl, OKButton * );
+};
+
+
+#endif
+
+
+
diff --git a/sc/source/ui/inc/crnrdlg.hrc b/sc/source/ui/inc/crnrdlg.hrc
new file mode 100644
index 000000000000..1d27531f9bc1
--- /dev/null
+++ b/sc/source/ui/inc/crnrdlg.hrc
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> RID_SCDLG_COLROWNAMERANGES
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_ADD 3
+#define BTN_REMOVE 4
+#define BTN_HELP 5
+//
+#define LB_RANGE 11
+//
+#define FL_ASSIGN 12
+#define ED_AREA 13
+#define RB_AREA 14
+#define BTN_COLHEAD 15
+#define BTN_ROWHEAD 16
+#define ED_DATA 17
+#define RB_DATA 18
+#define FT_DATA_LABEL 19
+//
diff --git a/sc/source/ui/inc/crnrdlg.hxx b/sc/source/ui/inc/crnrdlg.hxx
new file mode 100644
index 000000000000..e45ff4403633
--- /dev/null
+++ b/sc/source/ui/inc/crnrdlg.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CRNRDLG_HXX
+#define SC_CRNRDLG_HXX
+
+#include "anyrefdg.hxx"
+#include "rangelst.hxx"
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+
+#include <hash_map>
+
+class ScViewData;
+class ScDocument;
+
+
+//============================================================================
+
+class ScColRowNameRangesDlg : public ScAnyRefDlg
+{
+public:
+ ScColRowNameRangesDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData );
+ ~ScColRowNameRangesDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+ virtual BOOL Close();
+
+private:
+ FixedLine aFlAssign;
+ ListBox aLbRange;
+
+ formula::RefEdit aEdAssign;
+ formula::RefButton aRbAssign;
+ RadioButton aBtnColHead;
+ RadioButton aBtnRowHead;
+ FixedText aFtAssign2;
+ formula::RefEdit aEdAssign2;
+ formula::RefButton aRbAssign2;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ PushButton aBtnAdd;
+ PushButton aBtnRemove;
+
+ ScRange theCurArea;
+ ScRange theCurData;
+
+ ScRangePairListRef xColNameRanges;
+ ScRangePairListRef xRowNameRanges;
+
+ typedef ::std::hash_map< String, ScRange, ScStringHashCode, ::std::equal_to<String> > NameRangeMap;
+ NameRangeMap aRangeMap;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ formula::RefEdit* pEdActive;
+ BOOL bDlgLostFocus;
+
+#ifdef _CRNRDLG_CXX
+private:
+ void Init ();
+ void UpdateNames ();
+ void UpdateRangeData ( const ScRange& rRange, BOOL bColName );
+ void SetColRowData( const ScRange& rLabelRange,BOOL bRef=FALSE);
+ void AdjustColRowData( const ScRange& rDataRange,BOOL bRef=FALSE);
+ DECL_LINK( CancelBtnHdl, void * );
+ DECL_LINK( OkBtnHdl, void * );
+ DECL_LINK( AddBtnHdl, void * );
+ DECL_LINK( RemoveBtnHdl, void * );
+ DECL_LINK( Range1SelectHdl, void * );
+ DECL_LINK( Range1DataModifyHdl, void * );
+ DECL_LINK( ColClickHdl, void * );
+ DECL_LINK( RowClickHdl, void * );
+ DECL_LINK( Range2DataModifyHdl, void * );
+ DECL_LINK( GetFocusHdl, Control* );
+ DECL_LINK( LoseFocusHdl, Control* );
+#endif
+};
+
+
+
+#endif // SC_CRNRDLG_HXX
+
diff --git a/sc/source/ui/inc/csvcontrol.hxx b/sc/source/ui/inc/csvcontrol.hxx
new file mode 100644
index 000000000000..c38abfb83598
--- /dev/null
+++ b/sc/source/ui/inc/csvcontrol.hxx
@@ -0,0 +1,432 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_CSVCONTROL_HXX
+#define _SC_CSVCONTROL_HXX
+
+#include <vcl/ctrl.hxx>
+#include "scdllapi.h"
+#include "global.hxx"
+#include "address.hxx"
+#include "csvsplits.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+
+
+class ScAccessibleCsvControl;
+namespace com { namespace sun { namespace star { namespace accessibility {
+ class XAccessible;
+} } } }
+
+
+// ============================================================================
+
+/** Minimum character count for a column in separators mode. */
+const sal_Int32 CSV_MINCOLWIDTH = 8;
+/** Maximum length of a cell string. */
+const xub_StrLen CSV_MAXSTRLEN = 0x7FFF;
+/** Transparency for header color of selected columns. */
+const sal_uInt16 CSV_HDR_TRANSPARENCY = 85;
+/** Minimum distance to border for auto scroll. */
+const sal_Int32 CSV_SCROLL_DIST = 3;
+
+//! TODO make string array dynamic
+const sal_Int32 CSV_PREVIEW_LINES = 32; // maximum count of preview lines
+/** Maximum count of columns. */
+const sal_Int32 CSV_MAXCOLCOUNT = MAXCOLCOUNT;
+
+/** Default column data type. */
+const sal_Int32 CSV_TYPE_DEFAULT = 0;
+/** Multi selection with different types. */
+const sal_Int32 CSV_TYPE_MULTI = -1;
+/** No column selected. */
+const sal_Int32 CSV_TYPE_NOSELECTION = -2;
+
+// External used column types.
+const sal_uInt8 SC_COL_STANDARD = 1;
+const sal_uInt8 SC_COL_TEXT = 2;
+const sal_uInt8 SC_COL_MDY = 3;
+const sal_uInt8 SC_COL_DMY = 4;
+const sal_uInt8 SC_COL_YMD = 5;
+const sal_uInt8 SC_COL_SKIP = 9;
+const sal_uInt8 SC_COL_ENGLISH = 10;
+
+
+// ============================================================================
+
+/** Exported data of a column (data used in the dialog). */
+struct ScCsvExpData
+{
+ xub_StrLen mnIndex; /// Index of a column.
+ sal_uInt8 mnType; /// External type of the column.
+
+ inline ScCsvExpData() : mnIndex( 0 ), mnType( SC_COL_STANDARD ) {}
+ inline ScCsvExpData( xub_StrLen nIndex, sal_uInt8 nType ) :
+ mnIndex( nIndex ), mnType( nType ) {}
+};
+
+typedef ::std::vector< ScCsvExpData > ScCsvExpDataVec;
+
+
+// ============================================================================
+
+/** Specifies which element should be used to perform an action. */
+enum ScMoveMode
+{
+ MOVE_NONE, /// No action.
+ MOVE_FIRST, /// First element in current context.
+ MOVE_LAST, /// Last element in current context.
+ MOVE_PREV, /// Predecessor of current element in current context.
+ MOVE_NEXT, /// Successor of current element in current context.
+ MOVE_PREVPAGE, /// Previous page relative to current context.
+ MOVE_NEXTPAGE /// Next page relative to current context.
+};
+
+
+// ============================================================================
+
+/** Flags for comparison of old and new control layout data. */
+typedef sal_uInt32 ScCsvDiff;
+
+const ScCsvDiff CSV_DIFF_EQUAL = 0x00000000;
+const ScCsvDiff CSV_DIFF_POSCOUNT = 0x00000001;
+const ScCsvDiff CSV_DIFF_POSOFFSET = 0x00000002;
+const ScCsvDiff CSV_DIFF_HDRWIDTH = 0x00000004;
+const ScCsvDiff CSV_DIFF_CHARWIDTH = 0x00000008;
+const ScCsvDiff CSV_DIFF_LINECOUNT = 0x00000010;
+const ScCsvDiff CSV_DIFF_LINEOFFSET = 0x00000020;
+const ScCsvDiff CSV_DIFF_HDRHEIGHT = 0x00000040;
+const ScCsvDiff CSV_DIFF_LINEHEIGHT = 0x00000080;
+const ScCsvDiff CSV_DIFF_RULERCURSOR = 0x00000100;
+const ScCsvDiff CSV_DIFF_GRIDCURSOR = 0x00000200;
+
+const ScCsvDiff CSV_DIFF_HORIZONTAL = CSV_DIFF_POSCOUNT | CSV_DIFF_POSOFFSET | CSV_DIFF_HDRWIDTH | CSV_DIFF_CHARWIDTH;
+const ScCsvDiff CSV_DIFF_VERTICAL = CSV_DIFF_LINECOUNT | CSV_DIFF_LINEOFFSET | CSV_DIFF_HDRHEIGHT | CSV_DIFF_LINEHEIGHT;
+const ScCsvDiff CSV_DIFF_CURSOR = CSV_DIFF_RULERCURSOR | CSV_DIFF_GRIDCURSOR;
+
+
+// ----------------------------------------------------------------------------
+
+/** A structure containing all layout data valid for both ruler and data grid
+ (i.e. scroll position or column width). */
+struct ScCsvLayoutData
+{
+ // horizontal settings
+ sal_Int32 mnPosCount; /// Number of positions.
+ sal_Int32 mnPosOffset; /// Horizontal scroll offset.
+
+ sal_Int32 mnWinWidth; /// Width of ruler and data grid.
+ sal_Int32 mnHdrWidth; /// Width of the header column.
+ sal_Int32 mnCharWidth; /// Pixel width of one character.
+
+ // vertical settings
+ sal_Int32 mnLineCount; /// Number of data lines.
+ sal_Int32 mnLineOffset; /// Index of first visible line (0-based).
+
+ sal_Int32 mnWinHeight; /// Height of entire data grid (incl. header).
+ sal_Int32 mnHdrHeight; /// Height of the header line.
+ sal_Int32 mnLineHeight; /// Height of a data line.
+
+ // cursor settings
+ sal_Int32 mnPosCursor; /// Position of ruler cursor.
+ sal_Int32 mnColCursor; /// Position of grid column cursor.
+
+ mutable sal_Int32 mnNoRepaint; /// >0 = no repaint.
+ bool mbAppRTL; /// true = application in RTL mode.
+
+ explicit ScCsvLayoutData();
+
+ /** Returns differences to rData.
+ @descr For each difference the appropriate bit is set in the returned value. */
+ ScCsvDiff GetDiff( const ScCsvLayoutData& rData ) const;
+};
+
+inline bool operator==( const ScCsvLayoutData& rData1, const ScCsvLayoutData& rData2 )
+{
+ return rData1.GetDiff( rData2 ) == CSV_DIFF_EQUAL;
+}
+
+inline bool operator!=( const ScCsvLayoutData& rData1, const ScCsvLayoutData& rData2 )
+{
+ return !(rData1 == rData2);
+}
+
+
+// ============================================================================
+
+/** Enumeration of possible commands to change any settings of the CSV controls.
+ @descr Controls have to send commands instead of changing their settings directly.
+ This helps to keep the different controls consistent to each other.
+ A command can contain 0 to 2 sal_Int32 parameters. In the description of each
+ command the required parameters are swown in brackets. [-] means no parameter. */
+enum ScCsvCmdType
+{
+ // misc
+ CSVCMD_NONE, /// No command. [-]
+ CSVCMD_REPAINT, /// Repaint all controls. [-]
+
+ // modify horizontal dimensions
+ CSVCMD_SETPOSCOUNT, /// Change position/column count. [character count]
+ CSVCMD_SETPOSOFFSET, /// Change position offset (scroll pos). [position]
+ CSVCMD_SETHDRWIDTH, /// Change width of the header column. [width in pixel]
+ CSVCMD_SETCHARWIDTH, /// Change character pixel width. [width in pixel]
+
+ // modify vertical dimensions
+ CSVCMD_SETLINECOUNT, /// Change number of data lines. [line count]
+ CSVCMD_SETLINEOFFSET, /// Change first visible line. [line index]
+ CSVCMD_SETHDRHEIGHT, /// Change height of top header line. [height in pixel]
+ CSVCMD_SETLINEHEIGHT, /// Change data line pixel height. [height in pixel}
+
+ // cursors/positions
+ CSVCMD_MOVERULERCURSOR, /// Move ruler cursor to new position. [position]
+ CSVCMD_MOVEGRIDCURSOR, /// Move data grid cursor to new column. [position]
+ CSVCMD_MAKEPOSVISIBLE, /// Move to make passed position visible (for mouse tracking). [position]
+
+ // table contents
+ CSVCMD_NEWCELLTEXTS, /// Recalculate splits and cell texts. [-]
+ CSVCMD_UPDATECELLTEXTS, /// Update cell texts with current split settings. [-]
+ CSVCMD_SETCOLUMNTYPE, /// Change data type of selected columns. [column type]
+ CSVCMD_EXPORTCOLUMNTYPE, /// Send selected column type to external controls. [-]
+ CSVCMD_SETFIRSTIMPORTLINE, /// Set number of first imported line. [line index]
+
+ // splits
+ CSVCMD_INSERTSPLIT, /// Insert a split. [position]
+ CSVCMD_REMOVESPLIT, /// Remove a split. [position]
+ CSVCMD_TOGGLESPLIT, /// Inserts or removes a split. [position]
+ CSVCMD_MOVESPLIT, /// Move a split. [old position, new position]
+ CSVCMD_REMOVEALLSPLITS /// Remove all splits. [-]
+};
+
+
+// ----------------------------------------------------------------------------
+
+/** Data for a CSV control command. The stored position data is aways character based,
+ it's never a column index (required for internal consistency). */
+class ScCsvCmd
+{
+private:
+ ScCsvCmdType meType; /// The command.
+ sal_Int32 mnParam1; /// First parameter.
+ sal_Int32 mnParam2; /// Second parameter.
+
+public:
+ inline explicit ScCsvCmd() : meType( CSVCMD_NONE ),
+ mnParam1( CSV_POS_INVALID ), mnParam2( CSV_POS_INVALID ) {}
+
+ inline void Set( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 );
+
+ inline ScCsvCmdType GetType() const { return meType; }
+ inline sal_Int32 GetParam1() const { return mnParam1; }
+ inline sal_Int32 GetParam2() const { return mnParam2; }
+};
+
+inline void ScCsvCmd::Set( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 )
+{
+ meType = eType; mnParam1 = nParam1; mnParam2 = nParam2;
+}
+
+
+// ============================================================================
+
+/** Base class for the CSV ruler and the data grid control. Implements command handling. */
+class SC_DLLPUBLIC ScCsvControl : public Control
+{
+protected:
+ typedef ::std::vector< String > StringVec;
+ typedef ::std::vector< StringVec > StringVecVec;
+
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > XAccessibleRef;
+
+private:
+ Link maCmdHdl; /// External command handler.
+ ScCsvCmd maCmd; /// Data of last command.
+ const ScCsvLayoutData& mrData; /// Shared layout data.
+
+ XAccessibleRef mxAccessible; /// The accessible object of the control.
+ ScAccessibleCsvControl* mpAccessible; /// Pointer to the accessible implementation object.
+ bool mbValidGfx; /// Content of virtual devices valid?
+
+ // ------------------------------------------------------------------------
+public:
+ explicit ScCsvControl( ScCsvControl& rParent );
+ explicit ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, WinBits nStyle = 0 );
+ explicit ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, const ResId& rResId );
+ virtual ~ScCsvControl();
+
+ // event handling ---------------------------------------------------------
+
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ /** Sends a GetFocus or LoseFocus event to the accessibility object. */
+ void AccSendFocusEvent( bool bFocused );
+ /** Sends a caret changed event to the accessibility object. */
+ void AccSendCaretEvent();
+ /** Sends a visible area changed event to the accessibility object. */
+ void AccSendVisibleEvent();
+ /** Sends a selection changed event to the accessibility object. */
+ void AccSendSelectionEvent();
+ /** Sends a table model changed event for changed cell contents to the accessibility object. */
+ void AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows = true );
+ /** Sends a table model changed event for an inserted column to the accessibility object. */
+ void AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn );
+ /** Sends a table model changed event for a removed column to the accessibility object. */
+ void AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn );
+
+ // repaint helpers --------------------------------------------------------
+
+ /** Sets the graphic invalid (next Redraw() will not use cached graphic). */
+ inline void InvalidateGfx() { mbValidGfx = false; }
+ /** Sets the graphic valid (next Redraw() will use cached graphic). */
+ inline void ValidateGfx() { mbValidGfx = true; }
+ /** Returns true, if cached graphic is valid. */
+ inline bool IsValidGfx() const { return mbValidGfx; }
+
+ /** Repaints all controls.
+ @param bInvalidate true = invalidates graphics of this control (not all). */
+ void Repaint( bool bInvalidate = false );
+ /** Increases no-repaint counter (controls do not repaint until the last EnableRepaint()). */
+ void DisableRepaint();
+ /** Decreases no-repaint counter and repaints if counter reaches 0.
+ @param bInvalidate true = invalidates graphics of this control (not all). */
+ void EnableRepaint( bool bInvalidate = false );
+ /** Returns true, if controls will not repaint. */
+ inline bool IsNoRepaint() const { return mrData.mnNoRepaint > 0; }
+
+ // command handling -------------------------------------------------------
+
+ /** Sets a new command handler. */
+ inline void SetCmdHdl( const Link& rHdl ) { maCmdHdl = rHdl; }
+ /** Returns the current command handler. */
+ inline const Link& GetCmdHdl() const { return maCmdHdl; }
+ /** Returns data of the last command. */
+ inline const ScCsvCmd& GetCmd() const { return maCmd; }
+
+ /** Executes a command by calling command handler. */
+ void Execute(
+ ScCsvCmdType eType,
+ sal_Int32 nParam1 = CSV_POS_INVALID,
+ sal_Int32 nParam2 = CSV_POS_INVALID );
+
+ // layout helpers ---------------------------------------------------------
+
+ /** Returns a reference to the current layout data. */
+ inline const ScCsvLayoutData& GetLayoutData() const { return mrData; }
+ /** Returns true, if the Right-to-Left layout mode is active. */
+ inline bool IsRTL() const { return mrData.mbAppRTL; }
+
+ /** Returns the number of available positions. */
+ inline sal_Int32 GetPosCount() const { return mrData.mnPosCount; }
+ /** Returns the number of visible positions. */
+ sal_Int32 GetVisPosCount() const;
+ /** Returns the first visible position. */
+ inline sal_Int32 GetFirstVisPos() const { return mrData.mnPosOffset; }
+ /** Returns the last visible position. */
+ inline sal_Int32 GetLastVisPos() const { return GetFirstVisPos() + GetVisPosCount(); }
+ /** Returns highest possible position for first visible character. */
+ sal_Int32 GetMaxPosOffset() const;
+
+ /** Returns true, if it is allowed to set a split at nPos. */
+ bool IsValidSplitPos( sal_Int32 nPos ) const;
+ /** Returns true, if nPos is an allowed AND visible split position. */
+ bool IsVisibleSplitPos( sal_Int32 nPos ) const;
+
+ /** Returns the width of the header column. */
+ inline sal_Int32 GetHdrWidth() const { return mrData.mnHdrWidth; }
+ /** Returns the width of one character column. */
+ inline sal_Int32 GetCharWidth() const { return mrData.mnCharWidth; }
+ /** Returns the start position of the header column. */
+ sal_Int32 GetHdrX() const;
+ /** Returns the X position of the first pixel of the data area. */
+ sal_Int32 GetFirstX() const;
+ /** Returns the X position of the last pixel of the data area. */
+ sal_Int32 GetLastX() const;
+ /** Returns output X coordinate of the specified position. */
+ sal_Int32 GetX( sal_Int32 nPos ) const;
+ /** Returns position from output coordinate. */
+ sal_Int32 GetPosFromX( sal_Int32 nX ) const;
+
+ /** Returns the number of data lines. */
+ inline sal_Int32 GetLineCount() const { return mrData.mnLineCount; }
+ /** Returns the number of visible lines (including partly visible bottom line). */
+ sal_Int32 GetVisLineCount() const;
+ /** Returns index of first visible line. */
+ inline sal_Int32 GetFirstVisLine() const { return mrData.mnLineOffset; }
+ /** Returns index of last visible line. */
+ sal_Int32 GetLastVisLine() const;
+ /** Returns highest possible index for first line. */
+ sal_Int32 GetMaxLineOffset() const;
+
+ /** Returns true, if nLine is a valid line index. */
+ bool IsValidLine( sal_Int32 nLine ) const;
+ /** Returns true, if nLine is a valid and visible line index. */
+ bool IsVisibleLine( sal_Int32 nLine ) const;
+
+ /** Returns the height of the header line. */
+ inline sal_Int32 GetHdrHeight() const { return mrData.mnHdrHeight; }
+ /** Returns the height of one line. */
+ inline sal_Int32 GetLineHeight() const { return mrData.mnLineHeight; }
+ /** Returns output Y coordinate of the specified line. */
+ sal_Int32 GetY( sal_Int32 nLine ) const;
+ /** Returns line index from output coordinate. */
+ sal_Int32 GetLineFromY( sal_Int32 nY ) const;
+
+ /** Returns the ruler cursor position. */
+ inline sal_Int32 GetRulerCursorPos() const { return mrData.mnPosCursor; }
+ /** Returns the data grid cursor position (not column index!). */
+ inline sal_Int32 GetGridCursorPos() const { return mrData.mnColCursor; }
+
+ // static helpers ---------------------------------------------------------
+
+ /** Inverts a rectangle in the specified output device. */
+ static void ImplInvertRect( OutputDevice& rOutDev, const Rectangle& rRect );
+
+ /** Returns direction code for the keys LEFT, RIGHT, HOME, END.
+ @param bHomeEnd false = ignore HOME and END key. */
+ static ScMoveMode GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd );
+ /** Returns direction code for the keys UP, DOWN, HOME, END, PAGE UP, PAGE DOWN.
+ @param bHomeEnd false = ignore HOME and END key. */
+ static ScMoveMode GetVertDirection( sal_uInt16 nCode, bool bHomeEnd );
+
+ // accessibility ----------------------------------------------------------
+public:
+ /** Creates and returns the accessible object of this control. Do not overwrite in
+ derived classes, use ImplCreateAccessible() instead. */
+ virtual XAccessibleRef CreateAccessible();
+
+protected:
+ /** Derived classes create a new accessible object here. */
+ virtual ScAccessibleCsvControl* ImplCreateAccessible() = 0;
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/csvgrid.hxx b/sc/source/ui/inc/csvgrid.hxx
new file mode 100644
index 000000000000..fb6d687533e6
--- /dev/null
+++ b/sc/source/ui/inc/csvgrid.hxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_CSVGRID_HXX
+#define _SC_CSVGRID_HXX
+
+#include <vcl/virdev.hxx>
+#include <vcl/menu.hxx>
+#include <unotools/options.hxx>
+
+#include <vector>
+#include <memory>
+#include "scdllapi.h"
+#include "csvcontrol.hxx"
+#include "csvsplits.hxx"
+
+
+// ----------------------------------------------------------------------------
+
+namespace svtools { class ColorConfig; }
+class EditEngine;
+class ScEditEngineDefaulter;
+class ScAsciiOptions;
+class ScAccessibleCsvControl;
+
+
+// ============================================================================
+
+const sal_uInt8 CSV_COLFLAG_NONE = 0x00; /// Nothing set.
+const sal_uInt8 CSV_COLFLAG_SELECT = 0x01; /// Column is selected.
+
+const sal_uInt32 CSV_COLUMN_INVALID = CSV_VEC_NOTFOUND;
+
+
+// ----------------------------------------------------------------------------
+
+/** This struct contains the state of one table column. */
+struct ScCsvColState
+{
+ sal_Int32 mnType; /// Data type.
+ sal_uInt8 mnFlags; /// Flags (i.e. selection state).
+
+ inline explicit ScCsvColState(
+ sal_Int32 nType = CSV_TYPE_DEFAULT,
+ sal_uInt8 nFlags = CSV_COLFLAG_NONE ) :
+ mnType( nType ), mnFlags( nFlags ) {}
+
+ inline bool IsSelected() const;
+ inline void Select( bool bSel );
+};
+
+inline bool ScCsvColState::IsSelected() const
+{
+ return (mnFlags & CSV_COLFLAG_SELECT) != 0;
+}
+
+inline void ScCsvColState::Select( bool bSel )
+{
+ if( bSel ) mnFlags |= CSV_COLFLAG_SELECT; else mnFlags &= ~CSV_COLFLAG_SELECT;
+}
+
+
+// ----------------------------------------------------------------------------
+
+typedef ::std::vector< ScCsvColState > ScCsvColStateVec;
+
+
+// ============================================================================
+
+/** A data grid control for the CSV import dialog. The design of this control
+ simulates a Calc spreadsheet with row and column headers. */
+class SC_DLLPUBLIC ScCsvGrid : public ScCsvControl, public utl::ConfigurationListener
+{
+private:
+ typedef ::std::auto_ptr< ScEditEngineDefaulter > ScEditEnginePtr;
+
+ VirtualDevice maBackgrDev; /// Grid background, headers, cell texts.
+ VirtualDevice maGridDev; /// Data grid with selection and cursor.
+ PopupMenu maPopup; /// Popup menu for column types.
+
+ ::svtools::ColorConfig& mrColorConfig; /// Application color configuration.
+ Color maBackColor; /// Cell background color.
+ Color maGridColor; /// Table grid color.
+ Color maGridPBColor; /// Grid color for "first imported line" delimiter.
+ Color maAppBackColor; /// Background color for unused area.
+ Color maTextColor; /// Text color for data area.
+ Color maHeaderBackColor; /// Background color for headers.
+ Color maHeaderGridColor; /// Grid color for headers.
+ Color maHeaderTextColor; /// Text color for headers.
+ Color maSelectColor; /// Header color of selected columns.
+
+ ScEditEnginePtr mpEditEngine; /// For drawing cell texts.
+ Font maHeaderFont; /// Font for column and row headers.
+ Font maMonoFont; /// Monospace font for data cells.
+ Size maWinSize; /// Size of the control.
+ Size maEdEngSize; /// Paper size for edit engine.
+
+ ScCsvSplits maSplits; /// Vector with split positions.
+ ScCsvColStateVec maColStates; /// State of each column.
+ StringVec maTypeNames; /// UI names of data types.
+ StringVecVec maTexts; /// 2D-vector for cell texts.
+
+ sal_Int32 mnFirstImpLine; /// First imported line (0-based).
+ sal_uInt32 mnRecentSelCol; /// Index of most recently selected column.
+ sal_uInt32 mnMTCurrCol; /// Current column of mouse tracking.
+ bool mbMTSelecting; /// Mouse tracking: true = select, false = deselect.
+
+ // ------------------------------------------------------------------------
+public:
+ explicit ScCsvGrid( ScCsvControl& rParent );
+ virtual ~ScCsvGrid();
+
+ // common grid handling ---------------------------------------------------
+public:
+ /** Updates layout data dependent from the control's state. */
+ void UpdateLayoutData();
+ /** Updates X coordinate of first visible position dependent from line numbers. */
+ void UpdateOffsetX();
+ /** Apply current layout data to the grid control. */
+ void ApplyLayout( const ScCsvLayoutData& rOldData );
+ /** Sets the number of the first imported line (for visual feedback). nLine is 0-based! */
+ void SetFirstImportedLine( sal_Int32 nLine );
+
+ /** Finds a column position nearest to nPos which does not cause scrolling the visible area. */
+ sal_Int32 GetNoScrollCol( sal_Int32 nPos ) const;
+
+private:
+ /** Reads colors from system settings. */
+ SC_DLLPRIVATE void InitColors();
+ /** Initializes all font settings. */
+ SC_DLLPRIVATE void InitFonts();
+ /** Initializes all data dependent from the control's size. */
+ SC_DLLPRIVATE void InitSizeData();
+
+ // split handling ---------------------------------------------------------
+public:
+ /** Inserts a split. */
+ void InsertSplit( sal_Int32 nPos );
+ /** Removes a split. */
+ void RemoveSplit( sal_Int32 nPos );
+ /** Inserts a new or removes an existing split. */
+ void MoveSplit( sal_Int32 nPos, sal_Int32 nNewPos );
+ /** Removes all splits. */
+ void RemoveAllSplits();
+ /** Removes all splits and inserts the splits from rSplits. */
+ void SetSplits( const ScCsvSplits& rSplits );
+
+private:
+ /** Inserts a split and adjusts column data. */
+ SC_DLLPRIVATE bool ImplInsertSplit( sal_Int32 nPos );
+ /** Removes a split and adjusts column data. */
+ SC_DLLPRIVATE bool ImplRemoveSplit( sal_Int32 nPos );
+ /** Clears the split array and re-inserts boundary splits. */
+ SC_DLLPRIVATE void ImplClearSplits();
+
+ // columns/column types ---------------------------------------------------
+public:
+ /** Returns the number of columns. */
+ inline sal_uInt32 GetColumnCount() const { return maColStates.size(); }
+ /** Returns the index of the first visible column. */
+ sal_uInt32 GetFirstVisColumn() const;
+ /** Returns the index of the last visible column. */
+ sal_uInt32 GetLastVisColumn() const;
+
+ /** Returns true, if nColIndex points to an existing column. */
+ bool IsValidColumn( sal_uInt32 nColIndex ) const;
+ /** Returns true, if column with index nColIndex is (at least partly) visible. */
+ bool IsVisibleColumn( sal_uInt32 nColIndex ) const;
+
+ /** Returns X coordinate of the specified column. */
+ sal_Int32 GetColumnX( sal_uInt32 nColIndex ) const;
+ /** Returns column index from output coordinate. */
+ sal_uInt32 GetColumnFromX( sal_Int32 nX ) const;
+
+ /** Returns start position of the column with the specified index. */
+ inline sal_Int32 GetColumnPos( sal_uInt32 nColIndex ) const { return maSplits[ nColIndex ]; }
+ /** Returns column index from position. A split counts to its following column. */
+ sal_uInt32 GetColumnFromPos( sal_Int32 nPos ) const;
+ /** Returns the character width of the column with the specified index. */
+ sal_Int32 GetColumnWidth( sal_uInt32 nColIndex ) const;
+
+ /** Returns the vector with the states of all columns. */
+ inline const ScCsvColStateVec& GetColumnStates() const { return maColStates; }
+ /** Sets all column states to the values in the passed vector. */
+ void SetColumnStates( const ScCsvColStateVec& rColStates );
+ /** Returns the data type of the selected columns. */
+ sal_Int32 GetSelColumnType() const;
+ /** Changes the data type of all selected columns. */
+ void SetSelColumnType( sal_Int32 nType );
+ /** Sets new UI data type names. */
+ void SetTypeNames( const StringVec& rTypeNames );
+ /** Returns the UI type name of the specified column. */
+ const String& GetColumnTypeName( sal_uInt32 nColIndex ) const;
+
+ /** Fills the options object with column data for separators mode. */
+ void FillColumnDataSep( ScAsciiOptions& rOptions ) const;
+ /** Fills the options object with column data for fixed width mode. */
+ void FillColumnDataFix( ScAsciiOptions& rOptions ) const;
+
+private:
+ /** Returns the data type of the specified column. */
+ SC_DLLPRIVATE sal_Int32 GetColumnType( sal_uInt32 nColIndex ) const;
+ /** Returns the data type of the specified column. */
+ SC_DLLPRIVATE void SetColumnType( sal_uInt32 nColIndex, sal_Int32 nColType );
+
+ /** Scrolls data grid vertically. */
+ SC_DLLPRIVATE void ScrollVertRel( ScMoveMode eDir );
+ /** Executes the data type popup menu. */
+ SC_DLLPRIVATE void ExecutePopup( const Point& rPos );
+
+ // selection handling -----------------------------------------------------
+public:
+ /** Returns true, if the specified column is selected. */
+ bool IsSelected( sal_uInt32 nColIndex ) const;
+ /** Returns index of the first selected column. */
+ sal_uInt32 GetFirstSelected() const;
+ /** Returns index of the first selected column really after nFromIndex. */
+ sal_uInt32 GetNextSelected( sal_uInt32 nFromIndex ) const;
+ /** Returns true, if at least one column is selected. */
+ inline bool HasSelection() const { return GetFirstSelected() != CSV_COLUMN_INVALID; }
+
+ /** Selects or deselects the specified column. */
+ void Select( sal_uInt32 nColIndex, bool bSelect = true );
+ /** Toggles selection of the specified column. */
+ void ToggleSelect( sal_uInt32 nColIndex );
+ /** Selects or deselects the specified column range. */
+ void SelectRange( sal_uInt32 nColIndex1, sal_uInt32 nColIndex2, bool bSelect = true );
+ /** Selects or deselects all columns. */
+ void SelectAll( bool bSelect = true );
+
+ /** Returns index of the focused column. */
+ inline sal_uInt32 GetFocusColumn() const { return GetColumnFromPos( GetGridCursorPos() ); }
+
+private:
+ /** Moves column cursor to a new position. */
+ SC_DLLPRIVATE void MoveCursor( sal_uInt32 nColIndex );
+ /** Moves column cursor to the given direction. */
+ SC_DLLPRIVATE void MoveCursorRel( ScMoveMode eDir );
+
+ /** Clears the entire selection without notify. */
+ SC_DLLPRIVATE void ImplClearSelection();
+
+ /** Executes selection action for a specific column. */
+ SC_DLLPRIVATE void DoSelectAction( sal_uInt32 nColIndex, sal_uInt16 nModifier );
+
+ // cell contents ----------------------------------------------------------
+public:
+ /** Fills all cells of a line with the passed text (separators mode). */
+ void ImplSetTextLineSep(
+ sal_Int32 nLine, const String& rTextLine,
+ const String& rSepChars, sal_Unicode cTextSep, bool bMergeSep );
+ /** Fills all cells of a line with the passed text (fixed width mode). */
+ void ImplSetTextLineFix( sal_Int32 nLine, const String& rTextLine );
+
+ /** Returns the text of the specified cell. */
+ const String& GetCellText( sal_uInt32 nColIndex, sal_Int32 nLine ) const;
+
+ // event handling ---------------------------------------------------------
+protected:
+ virtual void Resize();
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual void Command( const CommandEvent& rCEvt );
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ virtual void ConfigurationChanged( ::utl::ConfigurationBroadcaster*, sal_uInt32 );
+
+ // painting ---------------------------------------------------------------
+protected:
+ virtual void Paint( const Rectangle& );
+
+public:
+ /** Redraws the entire data grid. */
+ void ImplRedraw();
+ /** Returns a pointer to the used edit engine. */
+ EditEngine* GetEditEngine();
+
+private:
+ /** Returns the width of the control. */
+ inline sal_Int32 GetWidth() const { return maWinSize.Width(); }
+ /** Returns the height of the control. */
+ inline sal_Int32 GetHeight() const { return maWinSize.Height(); }
+
+ /** Sets a clip region in the specified output device for the specified column. */
+ SC_DLLPRIVATE void ImplSetColumnClipRegion( OutputDevice& rOutDev, sal_uInt32 nColIndex );
+ /** Draws the header of the specified column to the specified output device. */
+ SC_DLLPRIVATE void ImplDrawColumnHeader( OutputDevice& rOutDev, sal_uInt32 nColIndex, Color aFillColor );
+
+ /** Draws the text at the specified position to maBackgrDev. */
+ SC_DLLPRIVATE void ImplDrawCellText( const Point& rPos, const String& rText );
+ /** Draws the "first imported line" separator to maBackgrDev (or erases, if bSet is false). */
+ SC_DLLPRIVATE void ImplDrawFirstLineSep( bool bSet );
+ /** Draws the column with index nColIndex to maBackgrDev. */
+ SC_DLLPRIVATE void ImplDrawColumnBackgr( sal_uInt32 nColIndex );
+ /** Draws the row headers column to maBackgrDev. */
+ SC_DLLPRIVATE void ImplDrawRowHeaders();
+ /** Draws all columns and the row headers column to maBackgrDev. */
+ SC_DLLPRIVATE void ImplDrawBackgrDev();
+
+ /** Draws the column with index nColIndex with its selection state to maGridDev. */
+ SC_DLLPRIVATE void ImplDrawColumnSelection( sal_uInt32 nColIndex );
+ /** Draws all columns with selection and cursor to maGridDev. */
+ SC_DLLPRIVATE void ImplDrawGridDev();
+
+ /** Redraws the entire column (background and selection). */
+ SC_DLLPRIVATE void ImplDrawColumn( sal_uInt32 nColIndex );
+
+ /** Optimized drawing: Scrolls horizontally and redraws only missing parts. */
+ SC_DLLPRIVATE void ImplDrawHorzScrolled( sal_Int32 nOldPos );
+
+ /** Inverts the cursor bar at the specified position in maGridDev. */
+ SC_DLLPRIVATE void ImplInvertCursor( sal_Int32 nPos );
+
+ /** Draws directly tracking rectangle to the column with the specified index. */
+ SC_DLLPRIVATE void ImplDrawTrackingRect( sal_uInt32 nColIndex );
+
+ // accessibility ----------------------------------------------------------
+protected:
+ /** Creates a new accessible object. */
+ virtual ScAccessibleCsvControl* ImplCreateAccessible();
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/csvruler.hxx b/sc/source/ui/inc/csvruler.hxx
new file mode 100644
index 000000000000..52be4b4ebd8c
--- /dev/null
+++ b/sc/source/ui/inc/csvruler.hxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef _SC_CSVRULER_HXX
+#define _SC_CSVRULER_HXX
+
+#include <vcl/virdev.hxx>
+#include "csvcontrol.hxx"
+#include "csvsplits.hxx"
+#include "scdllapi.h"
+
+class ScAccessibleCsvControl;
+
+
+// ============================================================================
+
+/** A ruler control for the CSV import dialog. Supports setting and moving
+ splits (which divide lines of data into several columns). */
+class SC_DLLPUBLIC ScCsvRuler : public ScCsvControl
+{
+private:
+ VirtualDevice maBackgrDev; /// Ruler background, scaling.
+ VirtualDevice maRulerDev; /// Ruler with splits and cursor.
+
+ Color maBackColor; /// Background color.
+ Color maActiveColor; /// Color for active part of ruler.
+ Color maTextColor; /// Text and scale color.
+ Color maSplitColor; /// Split area color.
+
+ ScCsvSplits maSplits; /// Vector with split positions.
+ ScCsvSplits maOldSplits; /// Old state for cancellation.
+
+ sal_Int32 mnPosCursorLast; /// Last valid position of cursor.
+ sal_Int32 mnPosMTStart; /// Start position of mouse tracking.
+ sal_Int32 mnPosMTCurr; /// Current position of mouse tracking.
+ bool mbPosMTMoved; /// Tracking: Anytime moved to another position?
+
+ Size maWinSize; /// Size of the control.
+ Rectangle maActiveRect; /// The active area of the ruler.
+ sal_Int32 mnSplitSize; /// Size of a split circle.
+
+ // ------------------------------------------------------------------------
+public:
+ explicit ScCsvRuler( ScCsvControl& rParent );
+ ~ScCsvRuler();
+
+ // common ruler handling --------------------------------------------------
+public:
+ using Window::SetPosSizePixel;
+ /** Sets position and size of the ruler. The height is calculated internally. */
+ virtual void SetPosSizePixel(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ USHORT nFlags = WINDOW_POSSIZE_ALL );
+
+ /** Apply current layout data to the ruler. */
+ void ApplyLayout( const ScCsvLayoutData& rOldData );
+
+private:
+ /** Reads colors from system settings. */
+ SC_DLLPRIVATE void InitColors();
+ /** Initializes all data dependent from the control's size. */
+ SC_DLLPRIVATE void InitSizeData();
+
+ /** Moves cursor to a new position.
+ @param bScroll TRUE = The method may scroll the ruler. */
+ SC_DLLPRIVATE void MoveCursor( sal_Int32 nPos, bool bScroll = true );
+ /** Moves cursor to the given direction. */
+ SC_DLLPRIVATE void MoveCursorRel( ScMoveMode eDir );
+ /** Sets cursor to an existing split, according to eDir. */
+ SC_DLLPRIVATE void MoveCursorToSplit( ScMoveMode eDir );
+ /** Scrolls data grid vertically. */
+ SC_DLLPRIVATE void ScrollVertRel( ScMoveMode eDir );
+
+ // split handling ---------------------------------------------------------
+public:
+ /** Returns the split array. */
+ inline const ScCsvSplits& GetSplits() const { return maSplits; }
+ /** Returns the number of splits. */
+ inline sal_uInt32 GetSplitCount() const
+ { return maSplits.Count(); }
+ /** Returns the position of the specified split. */
+ inline sal_Int32 GetSplitPos( sal_uInt32 nIndex ) const
+ { return maSplits[ nIndex ]; }
+ /** Finds a position nearest to nPos which does not cause scrolling the visible area. */
+ sal_Int32 GetNoScrollPos( sal_Int32 nPos ) const;
+
+ /** Returns true if at position nPos is a split. */
+ inline bool HasSplit( sal_Int32 nPos ) const { return maSplits.HasSplit( nPos ); }
+ /** Inserts a split. */
+ void InsertSplit( sal_Int32 nPos );
+ /** Removes a split. */
+ void RemoveSplit( sal_Int32 nPos );
+ /** Moves a split from nPos to nNewPos. */
+ void MoveSplit( sal_Int32 nPos, sal_Int32 nNewPos );
+ /** Removes all splits of the ruler. */
+ void RemoveAllSplits();
+
+private:
+ /** Finds next position without a split. */
+ SC_DLLPRIVATE sal_Int32 FindEmptyPos( sal_Int32 nPos, ScMoveMode eDir ) const;
+
+ /** Moves split and cursor to nNewPos and commits event. */
+ SC_DLLPRIVATE void MoveCurrSplit( sal_Int32 nNewPos );
+ /** Moves split and cursor to the given direction and commits event. */
+ SC_DLLPRIVATE void MoveCurrSplitRel( ScMoveMode eDir );
+
+ // event handling ---------------------------------------------------------
+protected:
+ virtual void Resize();
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+
+ virtual void KeyInput( const KeyEvent& rKEvt );
+
+private:
+ /** Starts tracking at the specified position. */
+ SC_DLLPRIVATE void StartMouseTracking( sal_Int32 nPos );
+ /** Moves tracking to a new position. */
+ SC_DLLPRIVATE void MoveMouseTracking( sal_Int32 nPos );
+ /** Applies tracking action for the current tracking position.
+ @param bApply TRUE = apply action, FALSE = cancel action. */
+ SC_DLLPRIVATE void EndMouseTracking( bool bApply );
+
+ // painting ---------------------------------------------------------------
+protected:
+ virtual void Paint( const Rectangle& );
+
+public:
+ /** Redraws the entire ruler. */
+ void ImplRedraw();
+
+private:
+ /** Returns the width of the control. */
+ inline sal_Int32 GetWidth() const { return maWinSize.Width(); }
+ /** Returns the height of the control. */
+ inline sal_Int32 GetHeight() const { return maWinSize.Height(); }
+
+ /** Draws the background and active area to maBackgrDev (only the given X range). */
+ SC_DLLPRIVATE void ImplDrawArea( sal_Int32 nPosX, sal_Int32 nWidth );
+ /** Draws the entire ruler background with scaling to maBackgrDev. */
+ SC_DLLPRIVATE void ImplDrawBackgrDev();
+
+ /** Draws a split to maRulerDev. */
+ SC_DLLPRIVATE void ImplDrawSplit( sal_Int32 nPos );
+ /** Erases a split from maRulerDev. */
+ SC_DLLPRIVATE void ImplEraseSplit( sal_Int32 nPos );
+ /** Draws the ruler background, all splits and the cursor to maRulerDev. */
+ SC_DLLPRIVATE void ImplDrawRulerDev();
+
+ /** Inverts the cursor bar at the specified position in maRulerDev. */
+ SC_DLLPRIVATE void ImplInvertCursor( sal_Int32 nPos );
+ /** Draws directly tracking rectangle to the column with the specified index. */
+ SC_DLLPRIVATE void ImplDrawTrackingRect();
+
+ /** Sets arrow or horizontal split pointer. */
+ SC_DLLPRIVATE void ImplSetMousePointer( sal_Int32 nPos );
+
+ // accessibility ----------------------------------------------------------
+protected:
+ /** Creates a new accessible object. */
+ virtual ScAccessibleCsvControl* ImplCreateAccessible();
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/csvsplits.hxx b/sc/source/ui/inc/csvsplits.hxx
new file mode 100644
index 000000000000..4685269936d5
--- /dev/null
+++ b/sc/source/ui/inc/csvsplits.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef _SC_CSVSPLITS_HXX
+#define _SC_CSVSPLITS_HXX
+
+#include <sal/types.h>
+
+#include <vector>
+
+
+// ============================================================================
+
+/** Constant for an invalid vector index. */
+const sal_uInt32 CSV_VEC_NOTFOUND = SAL_MAX_UINT32;
+/** Constant for an invalid ruler position. */
+const sal_Int32 CSV_POS_INVALID = -1;
+
+
+// ----------------------------------------------------------------------------
+
+/** A vector of column splits that supports inserting, removing and moving splits. */
+class ScCsvSplits
+{
+private:
+ typedef ::std::vector< sal_Int32 > ScSplitVector;
+ typedef ScSplitVector::iterator iterator;
+ typedef ScSplitVector::const_iterator const_iterator;
+
+ ScSplitVector maVec; /// The split containter.
+
+public:
+ // *** access by position *** ---------------------------------------------
+
+ /** Inserts a new split at position nPos into the vector.
+ @return true = split inserted (nPos was valid and empty). */
+ bool Insert( sal_Int32 nPos );
+ /** Removes a split by position.
+ @return true = split found and removed. */
+ bool Remove( sal_Int32 nPos );
+ /** Removes a range of splits in the given position range. */
+ void RemoveRange( sal_Int32 nPosStart, sal_Int32 nPosEnd );
+ /** Removes all elements from the vector. */
+ void Clear();
+
+ /** Returns true if at position nPos is a split. */
+ bool HasSplit( sal_Int32 nPos ) const;
+
+ // *** access by index *** ------------------------------------------------
+
+ /** Searches for a split at position nPos.
+ @return the vector index of the split. */
+ sal_uInt32 GetIndex( sal_Int32 nPos ) const;
+ /** Returns index of the first split greater than or equal to nPos. */
+ sal_uInt32 LowerBound( sal_Int32 nPos ) const;
+ /** Returns index of the last split less than or equal to nPos. */
+ sal_uInt32 UpperBound( sal_Int32 nPos ) const;
+
+ /** Returns the number of splits. */
+ inline sal_uInt32 Count() const
+ { return maVec.size(); }
+ /** Returns the position of the specified split. */
+ sal_Int32 GetPos( sal_uInt32 nIndex ) const;
+ /** Returns the position of the specified split. */
+ inline sal_Int32 operator[]( sal_uInt32 nIndex ) const
+ { return GetPos( nIndex ); }
+
+private:
+ /** Returns the vector index of an iterator. */
+ sal_uInt32 GetIterIndex( const_iterator aIter ) const;
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/csvtablebox.hxx b/sc/source/ui/inc/csvtablebox.hxx
new file mode 100644
index 000000000000..205e8b50cad1
--- /dev/null
+++ b/sc/source/ui/inc/csvtablebox.hxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef _SC_CSVTABLEBOX_HXX
+#define _SC_CSVTABLEBOX_HXX
+
+#include <vcl/ctrl.hxx>
+#include <vcl/scrbar.hxx>
+#include "scdllapi.h"
+#include "csvcontrol.hxx"
+#include "csvruler.hxx"
+#include "csvgrid.hxx"
+
+
+class ListBox;
+class ScAsciiOptions;
+
+
+/* ============================================================================
+Position: Positions between the characters (the dots in the ruler).
+Character: The characters (the range from one position to the next).
+Split: Positions which contain a split to divide characters into groups (columns).
+Column: The range between two splits.
+============================================================================ */
+
+/** The control in the CSV import dialog that contains a ruler and a data grid
+ to visualize and modify the current import settings. */
+class SC_DLLPUBLIC ScCsvTableBox : public ScCsvControl
+{
+private:
+ ScCsvLayoutData maData; /// Current layout data of the controls.
+
+ ScCsvRuler maRuler; /// The ruler for fixed width mode.
+ ScCsvGrid maGrid; /// Calc-like data table for fixed width mode.
+ ScrollBar maHScroll; /// Horizontal scroll bar.
+ ScrollBar maVScroll; /// Vertical scroll bar.
+ ScrollBarBox maScrollBox; /// For the bottom right edge.
+
+ Link maUpdateTextHdl; /// Updates all cell texts.
+ Link maColTypeHdl; /// Handler for exporting the column type.
+
+ ScCsvColStateVec maFixColStates; /// Column states in fixed width mode.
+ ScCsvColStateVec maSepColStates; /// Column states in separators mode.
+
+ sal_Int32 mnFixedWidth; /// Cached total width for fixed width mode.
+
+ bool mbFixedMode; /// false = Separators, true = Fixed width.
+
+ // ------------------------------------------------------------------------
+public:
+//UNUSED2009-05 explicit ScCsvTableBox( Window* pParent );
+ explicit ScCsvTableBox( Window* pParent, const ResId& rResId );
+
+ // common table box handling ----------------------------------------------
+public:
+ /** Sets the control to separators mode. */
+ void SetSeparatorsMode();
+ /** Sets the control to fixed width mode. */
+ void SetFixedWidthMode();
+
+private:
+ /** Initialisation on construction. */
+ SC_DLLPRIVATE void Init();
+ /** Initializes the children controls (pos/size, scroll bars, ...). */
+ SC_DLLPRIVATE void InitControls();
+ /** Initializes size and position data of horizontal scrollbar. */
+ SC_DLLPRIVATE void InitHScrollBar();
+ /** Initializes size and position data of vertical scrollbar. */
+ SC_DLLPRIVATE void InitVScrollBar();
+
+ /** Calculates and sets valid position offset nearest to nPos. */
+ SC_DLLPRIVATE inline void ImplSetPosOffset( sal_Int32 nPos )
+ { maData.mnPosOffset = Max( Min( nPos, GetMaxPosOffset() ), sal_Int32( 0 ) ); }
+ /** Calculates and sets valid line offset nearest to nLine. */
+ SC_DLLPRIVATE inline void ImplSetLineOffset( sal_Int32 nLine )
+ { maData.mnLineOffset = Max( Min( nLine, GetMaxLineOffset() ), sal_Int32( 0 ) ); }
+ /** Moves controls (not cursors!) so that nPos becomes visible. */
+ SC_DLLPRIVATE void MakePosVisible( sal_Int32 nPos );
+
+ // cell contents ----------------------------------------------------------
+public:
+ /** Fills all cells of all lines with the passed texts (Unicode strings). */
+ void SetUniStrings(
+ const String* pTextLines, const String& rSepChars,
+ sal_Unicode cTextSep, bool bMergeSep );
+//UNUSED2009-05 /** Fills all cells of all lines with the passed texts (ByteStrings). */
+//UNUSED2009-05 void SetByteStrings(
+//UNUSED2009-05 const ByteString* pLineTexts, CharSet eCharSet,
+//UNUSED2009-05 const String& rSepChars, sal_Unicode cTextSep, bool bMergeSep );
+
+ // column settings --------------------------------------------------------
+public:
+ /** Reads UI strings for data types from the list box. */
+ void InitTypes( const ListBox& rListBox );
+ /** Returns the data type of the selected columns. */
+ inline sal_Int32 GetSelColumnType() const { return maGrid.GetSelColumnType(); }
+
+ /** Fills the options object with current column data. */
+ void FillColumnData( ScAsciiOptions& rOptions ) const;
+
+ // event handling ---------------------------------------------------------
+public:
+ /** Sets a new handler for "update cell texts" requests. */
+ inline void SetUpdateTextHdl( const Link& rHdl ) { maUpdateTextHdl = rHdl; }
+ /** Returns the handler for "update cell texts" requests. */
+ inline const Link& GetUpdateTextHdl() const { return maUpdateTextHdl; }
+ /** Sets a new handler for "column selection changed" events. */
+ inline void SetColTypeHdl( const Link& rHdl ) { maColTypeHdl = rHdl; }
+ /** Returns the handler for "column selection changed" events. */
+ inline const Link& GetColTypeHdl() const { return maColTypeHdl; }
+
+protected:
+ virtual void Resize();
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+private:
+ SC_DLLPRIVATE DECL_LINK( CsvCmdHdl, ScCsvControl* );
+ SC_DLLPRIVATE DECL_LINK( ScrollHdl, ScrollBar* );
+ SC_DLLPRIVATE DECL_LINK( ScrollEndHdl, ScrollBar* );
+
+ // accessibility ----------------------------------------------------------
+public:
+ /** Creates and returns the accessible object of this control. */
+ virtual XAccessibleRef CreateAccessible();
+
+protected:
+ /** Creates a new accessible object. */
+ virtual ScAccessibleCsvControl* ImplCreateAccessible();
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/dapidata.hxx b/sc/source/ui/inc/dapidata.hxx
new file mode 100644
index 000000000000..13d7e91bdceb
--- /dev/null
+++ b/sc/source/ui/inc/dapidata.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DAPIDATA_HXX
+#define SC_DAPIDATA_HXX
+
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/combobox.hxx>
+
+//------------------------------------------------------------------------
+
+struct ScImportSourceDesc;
+
+
+class ScDataPilotDatabaseDlg : public ModalDialog
+{
+private:
+ FixedLine aFlFrame;
+ FixedText aFtDatabase;
+ ListBox aLbDatabase;
+ FixedText aFtObject;
+ ComboBox aCbObject;
+ FixedText aFtType;
+ ListBox aLbType;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ void FillObjects();
+
+ DECL_LINK( SelectHdl, ListBox* );
+
+public:
+ ScDataPilotDatabaseDlg( Window* pParent );
+ ~ScDataPilotDatabaseDlg();
+
+ void GetValues( ScImportSourceDesc& rDesc );
+};
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/dapitype.hxx b/sc/source/ui/inc/dapitype.hxx
new file mode 100644
index 000000000000..07659b1dbc59
--- /dev/null
+++ b/sc/source/ui/inc/dapitype.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DAPITYPE_HXX
+#define SC_DAPITYPE_HXX
+
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/dialog.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+//------------------------------------------------------------------------
+
+class ScDataPilotSourceTypeDlg : public ModalDialog
+{
+private:
+ FixedLine aFlFrame;
+ RadioButton aBtnSelection;
+ RadioButton aBtnDatabase;
+ RadioButton aBtnExternal;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+public:
+ ScDataPilotSourceTypeDlg( Window* pParent, BOOL bEnableExternal );
+ ~ScDataPilotSourceTypeDlg();
+
+ BOOL IsDatabase() const;
+ BOOL IsExternal() const;
+};
+
+
+class ScDataPilotServiceDlg : public ModalDialog
+{
+private:
+ FixedLine aFlFrame;
+ FixedText aFtService;
+ ListBox aLbService;
+ FixedText aFtSource;
+ Edit aEdSource;
+ FixedText aFtName;
+ Edit aEdName;
+ FixedText aFtUser;
+ Edit aEdUser;
+ FixedText aFtPasswd;
+ Edit aEdPasswd;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+public:
+ ScDataPilotServiceDlg( Window* pParent,
+ const com::sun::star::uno::Sequence<rtl::OUString>& rServices );
+ ~ScDataPilotServiceDlg();
+
+ String GetServiceName() const;
+ String GetParSource() const;
+ String GetParName() const;
+ String GetParUser() const;
+ String GetParPass() const;
+};
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx
new file mode 100644
index 000000000000..efdd29b44738
--- /dev/null
+++ b/sc/source/ui/inc/dbdocfun.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DBDOCFUN_HXX
+#define SC_DBDOCFUN_HXX
+
+#include "address.hxx"
+#include <tools/solar.h>
+#include <com/sun/star/uno/Sequence.hxx>
+
+class String;
+
+struct ScImportParam;
+struct ScQueryParam;
+struct ScSortParam;
+struct ScSubTotalParam;
+
+class SfxViewFrame;
+class SbaSelectionList;
+class ScDBData;
+class ScDocShell;
+class ScAddress;
+class ScRange;
+class ScDPObject;
+
+namespace com { namespace sun { namespace star {
+ namespace beans {
+ struct PropertyValue;
+ }
+ namespace sdbc {
+ class XResultSet;
+ }
+} } }
+
+// ---------------------------------------------------------------------------
+// -----------------------------------------------------------------
+class SbaSelectionList: public List , public SvRefBase
+{
+public:
+ SbaSelectionList():
+ List(CONTAINER_MAXBLOCKSIZE,100,100){}
+};
+
+SV_DECL_IMPL_REF(SbaSelectionList)
+
+
+class ScDBDocFunc
+{
+friend class ScDBFunc;
+
+private:
+ ScDocShell& rDocShell;
+
+public:
+ ScDBDocFunc( ScDocShell& rDocSh ): rDocShell(rDocSh) {}
+ ~ScDBDocFunc() {}
+
+ void UpdateImport( const String& rTarget, const String& rDBName,
+ const String& rTableName, const String& rStatement,
+ BOOL bNative, BYTE nType,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::sdbc::XResultSet >& xResultSet,
+ const SbaSelectionList* pSelection );
+
+ BOOL DoImport( SCTAB nTab, const ScImportParam& rParam,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::sdbc::XResultSet >& xResultSet,
+ const SbaSelectionList* pSelection, BOOL bRecord,
+ BOOL bAddrInsert = FALSE );
+
+ BOOL DoImportUno( const ScAddress& rPos,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyValue>& aArgs );
+
+ static void ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFrame );
+
+ BOOL Sort( SCTAB nTab, const ScSortParam& rSortParam,
+ BOOL bRecord, BOOL bPaint, BOOL bApi );
+
+ SC_DLLPUBLIC BOOL Query( SCTAB nTab, const ScQueryParam& rQueryParam,
+ const ScRange* pAdvSource, BOOL bRecord, BOOL bApi );
+
+ BOOL DoSubTotals( SCTAB nTab, const ScSubTotalParam& rParam,
+ const ScSortParam* pForceNewSort,
+ BOOL bRecord, BOOL bApi );
+
+ BOOL AddDBRange( const String& rName, const ScRange& rRange, BOOL bApi );
+ BOOL DeleteDBRange( const String& rName, BOOL bApi );
+ BOOL RenameDBRange( const String& rOld, const String& rNew, BOOL bApi );
+ BOOL ModifyDBData( const ScDBData& rNewData, BOOL bApi ); // Name unveraendert
+
+ BOOL RepeatDB( const String& rDBName, BOOL bRecord, BOOL bApi );
+
+ BOOL DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj,
+ BOOL bRecord, BOOL bApi, BOOL bAllowMove = FALSE );
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx
new file mode 100644
index 000000000000..baadae0a64dc
--- /dev/null
+++ b/sc/source/ui/inc/dbfunc.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DBFUNC_HXX
+#define SC_DBFUNC_HXX
+
+#include "viewfunc.hxx"
+
+namespace com { namespace sun { namespace star { namespace sheet {
+ struct DataPilotFieldFilter;
+}}}}
+
+struct ScSortParam;
+struct ScQueryParam;
+class ScDBData;
+class ScDBCollection;
+class ScDPObject;
+class ScDPSaveData;
+class ScStrCollection;
+struct ScDPNumGroupInfo;
+
+// ---------------------------------------------------------------------------
+
+class ScDBFunc : public ScViewFunc
+{
+private:
+ void GetSelectedMemberList( ScStrCollection& rEntries, long& rDimension );
+
+public:
+ ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
+//UNUSED2008-05 ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell );
+ virtual ~ScDBFunc();
+
+ // nur UISort wiederholt bei Bedarf die Teilergebnisse
+
+ void UISort( const ScSortParam& rSortParam,
+ BOOL bRecord = TRUE );
+
+ void Sort( const ScSortParam& rSortParam,
+ BOOL bRecord = TRUE, BOOL bPaint = TRUE );
+ SC_DLLPUBLIC void Query( const ScQueryParam& rQueryParam,
+ const ScRange* pAdvSource, BOOL bRecord );
+ void DoSubTotals( const ScSubTotalParam& rParam, BOOL bRecord = TRUE,
+ const ScSortParam* pForceNewSort = NULL );
+
+ void ToggleAutoFilter();
+ void HideAutoFilter();
+
+ void RepeatDB( BOOL bRecord = TRUE );
+
+ BOOL ImportData( const ScImportParam& rParam, BOOL bRecord = TRUE );
+
+ void GotoDBArea( const String& rDBName );
+
+ // DB-Bereich vom Cursor
+ ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE, ScGetDBSelection eSel = SC_DBSEL_KEEP );
+
+ void NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList );
+
+ void Consolidate( const ScConsolidateParam& rParam, BOOL bRecord = TRUE );
+
+ bool MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable,
+ const ScDPObject& rSource, BOOL bApi = FALSE );
+ void DeletePivotTable();
+ // Wang Xu Ming -- 2009-6-17
+ // DataPilot Migration
+ ULONG RecalcPivotTable();
+ // End Comments
+ BOOL HasSelectionForDateGroup( ScDPNumGroupInfo& rOldInfo, sal_Int32& rParts );
+ BOOL HasSelectionForNumGroup( ScDPNumGroupInfo& rOldInfo );
+ void GroupDataPilot();
+ void DateGroupDataPilot( const ScDPNumGroupInfo& rInfo, sal_Int32 nParts );
+ void NumGroupDataPilot( const ScDPNumGroupInfo& rInfo );
+ void UngroupDataPilot();
+ void DataPilotInput( const ScAddress& rPos, const String& rString );
+
+ bool DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId = NULL );
+ BOOL DataPilotMove( const ScRange& rSource, const ScAddress& rDest );
+
+ BOOL HasSelectionForDrillDown( USHORT& rOrientation );
+ void SetDataPilotDetails( BOOL bShow, const String* pNewDimensionName = NULL );
+
+ void ShowDataPilotSourceData( ScDPObject& rDPObj,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters );
+
+ void MakeOutline( BOOL bColumns, BOOL bRecord = TRUE );
+ void RemoveOutline( BOOL bColumns, BOOL bRecord = TRUE );
+ void RemoveAllOutlines( BOOL bRecord = TRUE );
+ void TestRemoveOutline( BOOL& rCol, BOOL& rRow );
+
+ void AutoOutline( BOOL bRecord = TRUE );
+
+ void SelectLevel( BOOL bColumns, USHORT nLevel,
+ BOOL bRecord = TRUE, BOOL bPaint = TRUE );
+ void ShowOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry,
+ BOOL bRecord = TRUE, BOOL bPaint = TRUE );
+ void HideOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry,
+ BOOL bRecord = TRUE, BOOL bPaint = TRUE );
+
+ void ShowMarkedOutlines( BOOL bRecord = TRUE );
+ void HideMarkedOutlines( BOOL bRecord = TRUE );
+ BOOL OutlinePossible(BOOL bHide);
+
+ void UpdateCharts(BOOL bAllCharts = FALSE); // Default: am Cursor
+
+ static USHORT DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, BOOL bAllCharts );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/dbnamdlg.hrc b/sc/source/ui/inc/dbnamdlg.hrc
new file mode 100644
index 000000000000..fd0205e3bbed
--- /dev/null
+++ b/sc/source/ui/inc/dbnamdlg.hrc
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> RID_SCDLG_DBNAMES
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_ADD 3
+#define BTN_REMOVE 4
+#define BTN_HELP 5
+#define FL_NAME 10
+#define ED_NAME 11
+#define FL_ASSIGN 12
+#define ED_DBAREA 13
+#define RB_DBAREA 14
+#define FL_OPTIONS 20
+#define BTN_HEADER 21
+#define BTN_SIZE 22
+#define BTN_FORMAT 23
+#define BTN_STRIPDATA 24
+#define FT_SOURCE 25
+#define FT_OPERATIONS 26
+#define STR_ADD 30
+#define STR_MODIFY 31
+#define STR_DB_INVALID 32
+#define BTN_MORE 33
+
diff --git a/sc/source/ui/inc/dbnamdlg.hxx b/sc/source/ui/inc/dbnamdlg.hxx
new file mode 100644
index 000000000000..cd878c651d6c
--- /dev/null
+++ b/sc/source/ui/inc/dbnamdlg.hxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DBNAMDLG_HXX
+#define SC_DBNAMDLG_HXX
+
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#include "anyrefdg.hxx"
+#include "dbcolect.hxx"
+#include "expftext.hxx"
+
+class ScViewData;
+class ScDocument;
+
+
+//============================================================================
+
+class ScDbNameDlg : public ScAnyRefDlg
+{
+public:
+ ScDbNameDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData );
+ ~ScDbNameDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+ virtual BOOL Close();
+
+private:
+ FixedLine aFlName;
+ ComboBox aEdName;
+
+ FixedLine aFlAssign;
+ formula::RefEdit aEdAssign;
+ formula::RefButton aRbAssign;
+
+ FixedLine aFlOptions;
+ CheckBox aBtnHeader;
+ CheckBox aBtnDoSize;
+ CheckBox aBtnKeepFmt;
+ CheckBox aBtnStripData;
+ ScExpandedFixedText aFTSource; //@18.09.97 erweiterter FixedText
+ FixedText aFTOperations;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ PushButton aBtnAdd;
+ PushButton aBtnRemove;
+ MoreButton aBtnMore;
+
+ BOOL bSaved;
+
+
+ const String aStrAdd; // "Hinzufuegen"
+ const String aStrModify; // "Aendern"
+ const String aStrNoName; // "unbenannt"
+ const String aStrInvalid;
+
+ String aStrSource;
+ String aStrOperations;
+
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ BOOL bRefInputMode;
+ ScAddress::Details aAddrDetails;
+
+ ScDBCollection aLocalDbCol;
+ ScRange theCurArea;
+ List aRemoveList;
+
+#ifdef _DBNAMDLG_CXX
+private:
+ void Init();
+ void UpdateNames();
+ void UpdateDBData( const String& rStrName );
+ void SetInfoStrings( const ScDBData* pDBData );
+
+ DECL_LINK( CancelBtnHdl, void * );
+ DECL_LINK( OkBtnHdl, void * );
+ DECL_LINK( AddBtnHdl, void * );
+ DECL_LINK( RemoveBtnHdl, void * );
+ DECL_LINK( NameModifyHdl, void * );
+ DECL_LINK( AssModifyHdl, void * );
+#endif
+};
+
+
+
+#endif // SC_DBNAMDLG_HXX
+
diff --git a/sc/source/ui/inc/delcldlg.hxx b/sc/source/ui/inc/delcldlg.hxx
new file mode 100644
index 000000000000..e1a816e78c0f
--- /dev/null
+++ b/sc/source/ui/inc/delcldlg.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DELCLDLG_HXX
+#define SC_DELCLDLG_HXX
+
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+
+
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+
+class ScDeleteCellDlg : public ModalDialog
+{
+private:
+ FixedLine aFlFrame;
+ RadioButton aBtnCellsUp;
+ RadioButton aBtnCellsLeft;
+ RadioButton aBtnDelRows;
+ RadioButton aBtnDelCols;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+
+public:
+ ScDeleteCellDlg( Window* pParent, BOOL bDisallowCellMove = FALSE );
+ ~ScDeleteCellDlg();
+
+ DelCellCmd GetDelCellCmd() const;
+};
+
+
+#endif // SC_DELCLDLG_HXX
+
+
diff --git a/sc/source/ui/inc/delcodlg.hxx b/sc/source/ui/inc/delcodlg.hxx
new file mode 100644
index 000000000000..8773b9c78f3a
--- /dev/null
+++ b/sc/source/ui/inc/delcodlg.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DELCODLG_HXX
+#define SC_DELCODLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/imagebtn.hxx>
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+
+class ScDeleteContentsDlg : public ModalDialog
+{
+private:
+ FixedLine aFlFrame;
+ CheckBox aBtnDelAll;
+ CheckBox aBtnDelStrings;
+ CheckBox aBtnDelNumbers;
+ CheckBox aBtnDelDateTime;
+ CheckBox aBtnDelFormulas;
+ CheckBox aBtnDelNotes;
+ CheckBox aBtnDelAttrs;
+ CheckBox aBtnDelObjects;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ BOOL bObjectsDisabled;
+
+ static BOOL bPreviousAllCheck;
+ static USHORT nPreviousChecks;
+
+ void DisableChecks( BOOL bDelAllChecked = TRUE );
+ DECL_LINK( DelAllHdl, void * );
+
+public:
+ ScDeleteContentsDlg( Window* pParent,
+ USHORT nCheckDefaults = 0 );
+ ~ScDeleteContentsDlg();
+ void DisableObjects();
+
+ USHORT GetDelContentsCmdBits() const;
+};
+
+
+#endif // SC_DELCODLG_HXX
+
+
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
new file mode 100644
index 000000000000..c92cc082986d
--- /dev/null
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DOCFUNC_HXX
+#define SC_DOCFUNC_HXX
+
+#include <tools/link.hxx>
+#include "global.hxx"
+#include "formula/grammar.hxx"
+#include "tabbgcolor.hxx"
+
+class ScEditEngineDefaulter;
+class SdrUndoAction;
+class ScAddress;
+class ScDocShell;
+class ScMarkData;
+class ScPatternAttr;
+class ScRange;
+class ScRangeName;
+class ScBaseCell;
+class ScTokenArray;
+struct ScTabOpParam;
+class ScTableProtection;
+
+// ---------------------------------------------------------------------------
+
+class ScDocFunc
+{
+private:
+ ScDocShell& rDocShell;
+
+ BOOL AdjustRowHeight( const ScRange& rRange, BOOL bPaint = TRUE );
+ void CreateOneName( ScRangeName& rList,
+ SCCOL nPosX, SCROW nPosY, SCTAB nTab,
+ SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ BOOL& rCancel, BOOL bApi );
+ void NotifyInputHandler( const ScAddress& rPos );
+
+public:
+ ScDocFunc( ScDocShell& rDocSh ): rDocShell(rDocSh) {}
+ ~ScDocFunc() {}
+
+ DECL_LINK( NotifyDrawUndo, SdrUndoAction* );
+
+ BOOL DetectiveAddPred(const ScAddress& rPos);
+ BOOL DetectiveDelPred(const ScAddress& rPos);
+ BOOL DetectiveAddSucc(const ScAddress& rPos);
+ BOOL DetectiveDelSucc(const ScAddress& rPos);
+ BOOL DetectiveAddError(const ScAddress& rPos);
+ BOOL DetectiveMarkInvalid(SCTAB nTab);
+ BOOL DetectiveDelAll(SCTAB nTab);
+ BOOL DetectiveRefresh(BOOL bAutomatic = FALSE);
+
+ BOOL DeleteContents( const ScMarkData& rMark, USHORT nFlags,
+ BOOL bRecord, BOOL bApi );
+
+ BOOL TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
+ BOOL bRecord, BOOL bApi );
+
+ BOOL SetNormalString( const ScAddress& rPos, const String& rText, BOOL bApi );
+ BOOL PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi );
+ BOOL PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
+ 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 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 ); }
+
+ bool SetNoteText( const ScAddress& rPos, const String& rNoteText, BOOL bApi );
+ bool ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate, BOOL bApi );
+
+ BOOL ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
+ BOOL bRecord, BOOL bApi );
+ BOOL ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
+ BOOL bRecord, BOOL bApi );
+
+ BOOL InsertCells( const ScRange& rRange,const ScMarkData* pTabMark,
+ InsCellCmd eCmd, BOOL bRecord, BOOL bApi,
+ BOOL bPartOfPaste = FALSE );
+ BOOL DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
+ DelCellCmd eCmd, BOOL bRecord, BOOL bApi );
+
+ BOOL MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
+ BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi );
+
+ BOOL InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi );
+ BOOL RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi );
+ BOOL DeleteTable( SCTAB nTab, BOOL bRecord, BOOL bApi );
+
+ bool SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi );
+ bool SetTabBgColor( ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi );
+
+ BOOL SetTableVisible( SCTAB nTab, BOOL bVisible, BOOL bApi );
+
+ BOOL SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL bApi );
+
+//UNUSED2009-05 BOOL SetGrammar( formula::FormulaGrammar::Grammar eGrammar );
+
+ SC_DLLPUBLIC BOOL SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
+ SCTAB nTab, ScSizeMode eMode, USHORT nSizeTwips,
+ BOOL bRecord, BOOL bApi );
+
+ BOOL InsertPageBreak( BOOL bColumn, const ScAddress& rPos,
+ BOOL bRecord, BOOL bSetModified, BOOL bApi );
+ 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 );
+
+ BOOL ClearItems( const ScMarkData& rMark, const USHORT* pWhich, BOOL bApi );
+ BOOL ChangeIndent( const ScMarkData& rMark, BOOL bIncrement, BOOL bApi );
+ BOOL AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
+ USHORT nFormatNo, BOOL bRecord, BOOL bApi );
+
+ 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,
+ const ScTabOpParam& rParam, BOOL bRecord, BOOL bApi );
+
+ BOOL FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
+ FillDir eDir, BOOL bRecord, BOOL bApi );
+ BOOL FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
+ FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
+ double fStart, double fStep, double fMax,
+ BOOL bRecord, BOOL bApi );
+ // FillAuto: rRange wird von Source-Range auf Dest-Range angepasst
+ BOOL FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
+ FillDir eDir, ULONG nCount, BOOL bRecord, BOOL bApi );
+
+ BOOL ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi );
+
+ BOOL MergeCells( const ScRange& rRange, BOOL bContents,
+ BOOL bRecord, BOOL bApi );
+ BOOL UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi );
+
+ BOOL SetNewRangeNames( ScRangeName* pNewRanges, BOOL bApi ); // takes ownership of pNewRanges
+ BOOL ModifyRangeNames( const ScRangeName& rNewRanges, BOOL bApi );
+
+ BOOL CreateNames( const ScRange& rRange, USHORT nFlags, BOOL bApi );
+ BOOL InsertNameList( const ScAddress& rStartPos, BOOL bApi );
+
+ BOOL InsertAreaLink( const String& rFile, const String& rFilter,
+ const String& rOptions, const String& rSource,
+ const ScRange& rDestRange, ULONG nRefresh,
+ BOOL bFitBlock, BOOL bApi );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
new file mode 100644
index 000000000000..19147cfaf61f
--- /dev/null
+++ b/sc/source/ui/inc/docsh.hxx
@@ -0,0 +1,468 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_DOCSHELL_HXX
+#define SC_DOCSHELL_HXX
+
+
+#include <sfx2/objsh.hxx>
+
+#include <sfx2/docfac.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+#include <sfx2/viewsh.hxx>
+
+#include "scdllapi.h"
+#include "scdll.hxx"
+#include "document.hxx"
+#include "shellids.hxx"
+#include "refreshtimer.hxx"
+
+#include <hash_map>
+
+class ScEditEngineDefaulter;
+class FontList;
+class PrintDialog;
+class SfxStyleSheetBasePool;
+class SfxStyleSheetHint;
+struct ChartSelectionInfo;
+class INetURLObject;
+
+class ScPaintItem;
+class ScViewData;
+class ScDocFunc;
+class ScDrawLayer;
+class ScTabViewShell;
+class ScSbxDocHelper;
+class ScAutoStyleList;
+class ScRange;
+class ScMarkData;
+class ScPaintLockData;
+class ScJobSetup;
+class ScChangeAction;
+class VirtualDevice;
+class ScImportOptions;
+class ScDocShellModificator;
+class ScOptSolverSave;
+class ScSheetSaveData;
+
+namespace sfx2 { class FileDialogHelper; }
+struct DocShell_Impl;
+
+typedef ::std::hash_map< ULONG, ULONG > ScChangeActionMergeMap;
+
+//==================================================================
+
+//enum ScDBFormat { SC_FORMAT_SDF, SC_FORMAT_DBF };
+
+ // Extra-Flags fuer Repaint
+#define SC_PF_LINES 1
+#define SC_PF_TESTMERGE 2
+#define SC_PF_WHOLEROWS 4
+
+class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
+{
+ static const sal_Char __FAR_DATA pStarCalcDoc[];
+ static const sal_Char __FAR_DATA pStyleName[];
+
+ ScDocument aDocument;
+
+ String aDdeTextFmt;
+ String aConvFilterName; //@ #BugId 54198
+
+ double nPrtToScreenFactor;
+//! FontList* pFontList;
+ DocShell_Impl* pImpl;
+ ScDocFunc* pDocFunc;
+
+ //SfxObjectCreateMode eShellMode;
+
+ BOOL bIsInplace; // wird von der View gesetzt
+ BOOL bHeaderOn;
+ BOOL bFooterOn;
+ BOOL bNoInformLost;
+ BOOL bIsEmpty;
+ BOOL bIsInUndo;
+ BOOL bDocumentModifiedPending;
+ USHORT nDocumentLock;
+ sal_Int16 nCanUpdate; // stores the UpdateDocMode from loading a document till update links
+ BOOL bUpdateEnabled;
+
+ ScDBData* pOldAutoDBRange;
+
+ ScSbxDocHelper* pDocHelper;
+
+ ScAutoStyleList* pAutoStyleList;
+ ScPaintLockData* pPaintLockData;
+ ScJobSetup* pOldJobSetup;
+ ScOptSolverSave* pSolverSaveData;
+ ScSheetSaveData* pSheetSaveData;
+
+ ScDocShellModificator* pModificator; // #109979#; is used to load XML (created in BeforeXMLLoading and destroyed in AfterXMLLoading)
+
+ SC_DLLPRIVATE void InitItems();
+ SC_DLLPRIVATE void DoEnterHandler();
+ SC_DLLPRIVATE void InitOptions(bool bForLoading);
+ SC_DLLPRIVATE void ResetDrawObjectShell();
+
+ // SUNWS needs a forward declared friend, otherwise types and members
+ // of the outer class are not accessible.
+ class PrepareSaveGuard;
+ friend class ScDocShell::PrepareSaveGuard;
+ /** Do things that need to be done before saving to our own format and
+ necessary clean ups in dtor. */
+ class PrepareSaveGuard
+ {
+ public:
+ explicit PrepareSaveGuard( ScDocShell & rDocShell );
+ ~PrepareSaveGuard();
+ private:
+ ScDocShell & mrDocShell;
+ };
+
+ SC_DLLPRIVATE BOOL LoadXML( SfxMedium* pMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& );
+ SC_DLLPRIVATE BOOL SaveXML( SfxMedium* pMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& );
+ SC_DLLPRIVATE SCTAB GetSaveTab();
+
+ SC_DLLPRIVATE ULONG DBaseImport( const String& rFullFileName, CharSet eCharSet,
+ BOOL bSimpleColWidth[MAXCOLCOUNT] );
+ SC_DLLPRIVATE ULONG DBaseExport( const String& rFullFileName, CharSet eCharSet,
+ BOOL& bHasMemo );
+
+ SC_DLLPRIVATE static BOOL MoveFile( const INetURLObject& rSource, const INetURLObject& rDest );
+ SC_DLLPRIVATE static BOOL KillFile( const INetURLObject& rURL );
+ SC_DLLPRIVATE static BOOL IsDocument( const INetURLObject& rURL );
+
+ SC_DLLPRIVATE void LockPaint_Impl(BOOL bDoc);
+ SC_DLLPRIVATE void UnlockPaint_Impl(BOOL bDoc);
+ SC_DLLPRIVATE void LockDocument_Impl(USHORT nNew);
+ SC_DLLPRIVATE void UnlockDocument_Impl(USHORT nNew);
+
+ SC_DLLPRIVATE void EnableSharedSettings( bool bEnable );
+ SC_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > LoadSharedDocument();
+
+ SC_DLLPRIVATE void UseSheetSaveEntries();
+
+protected:
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+public:
+ TYPEINFO();
+
+ SFX_DECL_INTERFACE(SCID_DOC_SHELL)
+ SFX_DECL_OBJECTFACTORY();
+
+ ScDocShell( const ScDocShell& rDocShell );
+ ScDocShell( const sal_uInt64 i_nSfxCreationFlags = SFXMODEL_EMBEDDED_OBJECT );
+ ~ScDocShell();
+
+ using SotObject::GetInterface;
+ using SfxShell::Activate; // with BOOL bMDI
+ using SfxShell::Deactivate; // with BOOL bMDI
+ using SfxObjectShell::Print; // print styles
+
+ virtual void Activate();
+ virtual void Deactivate();
+
+ virtual SfxUndoManager* GetUndoManager();
+
+ virtual void FillClass( SvGlobalName * pClassName,
+ sal_uInt32 * pFormat,
+ String * pAppName,
+ String * pFullTypeName,
+ String * pShortTypeName,
+ sal_Int32 nFileFormat,
+ sal_Bool bTemplate = sal_False ) const;
+
+ virtual BOOL InitNew( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& );
+ virtual BOOL Load( SfxMedium& rMedium );
+ virtual BOOL LoadFrom( SfxMedium& rMedium );
+ virtual BOOL ConvertFrom( SfxMedium &rMedium );
+ virtual BOOL Save();
+ virtual BOOL SaveAs( SfxMedium& rMedium );
+ virtual BOOL ConvertTo( SfxMedium &rMedium );
+ virtual USHORT PrepareClose( BOOL bUI = TRUE, BOOL bForBrowsing = FALSE );
+ virtual void PrepareReload();
+ virtual BOOL IsInformationLost();
+ virtual void LoadStyles( SfxObjectShell &rSource );
+ virtual BOOL Insert( SfxObjectShell &rSource,
+ USHORT nSourceIdx1, USHORT nSourceIdx2, USHORT nSourceIdx3,
+ USHORT &nIdx1, USHORT &nIdx2, USHORT &nIdx3, USHORT &rIdxDeleted );
+
+ virtual BOOL SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& ); // SfxInPlaceObject
+ virtual BOOL DoSaveCompleted( SfxMedium * pNewStor); // SfxObjectShell
+ virtual sal_Bool QuerySlotExecutable( USHORT nSlotId );
+
+ virtual void Draw( OutputDevice *, const JobSetup & rSetup,
+ USHORT nAspect = ASPECT_CONTENT );
+
+ virtual void SetVisArea( const Rectangle & rVisArea );
+
+ using SfxObjectShell::GetVisArea;
+ virtual Rectangle GetVisArea( USHORT nAspect ) const;
+
+ virtual Printer* GetDocumentPrinter();
+
+ virtual void SetModified( BOOL = TRUE );
+
+ void SetVisAreaOrSize( const Rectangle& rVisArea, BOOL bModifyStart );
+
+ virtual SfxDocumentInfoDialog* CreateDocumentInfoDialog( Window *pParent,
+ const SfxItemSet &rSet );
+
+ void GetDocStat( ScDocStat& rDocStat );
+
+ ScDocument* GetDocument() { return &aDocument; }
+ ScDocFunc& GetDocFunc() { return *pDocFunc; }
+
+ SfxPrinter* GetPrinter( BOOL bCreateIfNotExist = TRUE );
+ USHORT SetPrinter( SfxPrinter* pNewPrinter, USHORT nDiffFlags = SFX_PRINTER_ALL );
+
+ void UpdateFontList();
+
+ String CreateObjectName( const String& rPrefix );
+
+ ScDrawLayer* MakeDrawLayer();
+
+ void AsciiSave( SvStream& rStream, const ScImportOptions& rOpt );
+
+ void GetSbxState( SfxItemSet &rSet );
+ void GetDrawObjState( SfxItemSet &rSet );
+
+ void Execute( SfxRequest& rReq );
+ void GetState( SfxItemSet &rSet );
+ void ExecutePageStyle ( SfxViewShell& rCaller, SfxRequest& rReq, SCTAB nCurTab );
+ void GetStatePageStyle( SfxViewShell& rCaller, SfxItemSet& rSet, SCTAB nCurTab );
+
+ void CompareDocument( ScDocument& rOtherDoc );
+ void MergeDocument( ScDocument& rOtherDoc, bool bShared = false, bool bCheckDuplicates = false, ULONG nOffset = 0, ScChangeActionMergeMap* pMergeMap = NULL, bool bInverseMap = false );
+ bool MergeSharedDocument( ScDocShell* pSharedDocShell );
+
+ ScChangeAction* GetChangeAction( const ScAddress& rPos );
+ void SetChangeComment( ScChangeAction* pAction, const String& rComment );
+ void ExecuteChangeCommentDialog( ScChangeAction* pAction, Window* pParent,BOOL bPrevNext=TRUE );
+ /// Protect/unprotect ChangeTrack and return <TRUE/> if
+ /// protection was successfully changed.
+ /// If bJustQueryIfProtected==TRUE protection is not
+ /// changed and <TRUE/> is returned if not protected or
+ /// password was entered correctly.
+ BOOL ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQueryIfProtected = FALSE );
+
+ void SetPrintZoom( SCTAB nTab, USHORT nScale, USHORT nPages );
+ BOOL AdjustPrintZoom( const ScRange& rRange );
+
+ void LoadStylesArgs( ScDocShell& rSource, BOOL bReplace, BOOL bCellStyles, BOOL bPageStyles );
+
+ void PageStyleModified( const String& rStyleName, BOOL bApi );
+
+ void NotifyStyle( const SfxStyleSheetHint& rHint );
+ void DoAutoStyle( const ScRange& rRange, const String& rStyle );
+
+ Window* GetActiveDialogParent();
+ void ErrorMessage( USHORT nGlobStrId );
+ BOOL IsEditable() const;
+
+ BOOL AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab );
+ void UpdateAllRowHeights( const ScMarkData* pTabMark = NULL );
+ void UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore = false );
+
+ void RefreshPivotTables( const ScRange& rSource );
+ void DoConsolidate( const ScConsolidateParam& rParam, BOOL bRecord = TRUE );
+ void UseScenario( SCTAB nTab, const String& rName, BOOL bRecord = TRUE );
+ SCTAB MakeScenario( SCTAB nTab, const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags,
+ ScMarkData& rMark, BOOL bRecord = TRUE );
+ void ModifyScenario( SCTAB nTab, const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags );
+ BOOL MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRecord );
+
+ void DoRecalc( BOOL bApi );
+ void DoHardRecalc( BOOL bApi );
+
+ bool CheckPrint( PrintDialog* pPrintDialog, ScMarkData* pMarkData,
+ bool bForceSelected, bool bIsAPI );
+ void PreparePrint( PrintDialog* pPrintDialog, ScMarkData* pMarkData );
+ void Print( SfxProgress& rProgress, PrintDialog* pPrintDialog,
+ ScMarkData* pMarkData, Window* pDialogParent,
+ BOOL bForceSelected, BOOL bIsAPI );
+
+ void UpdateOle( const ScViewData* pViewData, BOOL bSnapSize = FALSE );
+ BOOL IsOle();
+
+ void DBAreaDeleted( SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 );
+ ScDBData* GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGetDBSelection eSel );
+ ScDBData* GetOldAutoDBRange(); // has to be deleted by caller!
+ void CancelAutoDBRange(); // called when dialog is cancelled
+
+ void UpdateLinks(); // Link-Eintraege aktuallisieren
+ BOOL ReloadTabLinks(); // Links ausfuehren (Inhalt aktualisieren)
+
+ void PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos );
+
+ void PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, USHORT nPart,
+ USHORT nExtFlags = 0 );
+ void PostPaint( const ScRange& rRange, USHORT nPart, USHORT nExtFlags = 0 );
+
+ void PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
+ void PostPaintCell( const ScAddress& rPos );
+ void PostPaintGridAll();
+ void PostPaintExtras();
+
+ void PostDataChanged();
+
+ void UpdatePaintExt( USHORT& rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab );
+ void UpdatePaintExt( USHORT& rExtFlags, const ScRange& rRange );
+
+ void SetDocumentModified( BOOL bIsModified = TRUE );
+ void SetDrawModified( BOOL bIsModified = TRUE );
+
+ void LockPaint();
+ void UnlockPaint();
+ USHORT GetLockCount() const;
+ void SetLockCount(USHORT nNew);
+
+ void LockDocument();
+ void UnlockDocument();
+
+ DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper* );
+
+ virtual SfxStyleSheetBasePool* GetStyleSheetPool();
+
+ void SetInplace( BOOL bInplace );
+ BOOL IsEmpty() const;
+ void SetEmpty(BOOL bSet);
+
+ BOOL IsInUndo() const { return bIsInUndo; }
+ void SetInUndo(BOOL bSet);
+
+ void CalcOutputFactor();
+ double GetOutputFactor() const;
+ void GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet,
+ SCTAB nCurTab,
+ BOOL& rbHeader,
+ BOOL& rbFooter );
+
+ virtual long DdeGetData( const String& rItem, const String& rMimeType,
+ ::com::sun::star::uno::Any & rValue );
+ virtual long DdeSetData( const String& rItem, const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue );
+ virtual ::sfx2::SvLinkSource* DdeCreateLinkSource( const String& rItem );
+
+ const String& GetDdeTextFmt() const { return aDdeTextFmt; }
+
+ SfxBindings* GetViewBindings();
+
+ ScTabViewShell* GetBestViewShell( BOOL bOnlyVisible = TRUE );
+ ScSbxDocHelper* GetDocHelperObject() { return pDocHelper; }
+
+ void SetDocumentModifiedPending( BOOL bVal )
+ { bDocumentModifiedPending = bVal; }
+ BOOL IsDocumentModifiedPending() const
+ { return bDocumentModifiedPending; }
+
+ BOOL IsUpdateEnabled() const
+ { return bUpdateEnabled; }
+ void SetUpdateEnabled(BOOL bValue)
+ { bUpdateEnabled = bValue; }
+
+ OutputDevice* GetRefDevice(); // WYSIWYG: Printer, otherwise VirtualDevice...
+
+ static ScViewData* GetViewData();
+ static SCTAB GetCurTab();
+
+ static ScDocShell* GetShellByNum( USHORT nDocNo );
+ static String GetOwnFilterName();
+ static String GetHtmlFilterName();
+ static String GetWebQueryFilterName();
+ static String GetAsciiFilterName();
+ static String GetLotusFilterName();
+ static String GetDBaseFilterName();
+ static String GetDifFilterName();
+ static BOOL HasAutomaticTableName( const String& rFilter );
+
+ DECL_LINK( RefreshDBDataHdl, ScRefreshTimer* );
+
+ void BeforeXMLLoading();
+ void AfterXMLLoading(sal_Bool bRet);
+
+ virtual sal_uInt16 GetHiddenInformationState( sal_uInt16 nStates );
+
+ const ScOptSolverSave* GetSolverSaveData() const { return pSolverSaveData; } // may be null
+ void SetSolverSaveData( const ScOptSolverSave& rData );
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ sal_Bool AcceptStateUpdate() const;
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+ ScSheetSaveData* GetSheetSaveData();
+
+ // passwword protection for Calc (derived from SfxObjectShell)
+ // see also: FID_CHG_RECORD, SID_CHG_PROTECT
+ virtual bool IsChangeRecording() const;
+ virtual bool HasChangeRecordProtection() const;
+ virtual void SetChangeRecording( bool bActivate );
+ virtual bool SetProtectionPassword( const String &rPassword );
+ virtual bool GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash );
+};
+
+
+void UpdateAcceptChangesDialog();
+
+
+SO2_DECL_REF(ScDocShell)
+SO2_IMPL_REF(ScDocShell)
+
+
+// Vor Modifizierungen des Dokuments anlegen und danach zerstoeren.
+// Merkt sich im Ctor AutoCalcShellDisabled und IdleDisabled, schaltet sie ab
+// und stellt sie im Dtor wieder her, AutoCalcShellDisabled ggbf. auch vor
+// einem ScDocShell SetDocumentModified.
+// SetDocumentModified hierdran aufrufen statt an der ScDocShell.
+// Im Dtor wird wenn ScDocShell bDocumentModifiedPending gesetzt ist und
+// bAutoCalcShellDisabled nicht gesetzt ist ein SetDocumentModified gerufen.
+class SC_DLLPUBLIC ScDocShellModificator
+{
+ ScDocShell& rDocShell;
+ ScRefreshTimerProtector aProtector;
+ BOOL bAutoCalcShellDisabled;
+ BOOL bIdleDisabled;
+
+ // not implemented
+ ScDocShellModificator( const ScDocShellModificator& );
+ ScDocShellModificator& operator=( const ScDocShellModificator& );
+
+public:
+ ScDocShellModificator( ScDocShell& );
+ ~ScDocShellModificator();
+ void SetDocumentModified();
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/dpcontrol.hrc b/sc/source/ui/inc/dpcontrol.hrc
new file mode 100644
index 000000000000..687f999970ad
--- /dev/null
+++ b/sc/source/ui/inc/dpcontrol.hrc
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __DPCONTROL_HRC__
+#define __DPCONTROL_HRC__
+
+#include <sc.hrc>
+
+#define STR_MENU_SORT_ASC 1
+#define STR_MENU_SORT_DESC 2
+#define STR_MENU_SORT_CUSTOM 3
+#define STR_BTN_TOGGLE_ALL 4
+#define STR_BTN_SELECT_CURRENT 5
+#define STR_BTN_UNSELECT_CURRENT 6
+
+#endif
diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx
new file mode 100644
index 000000000000..25cb3e05acac
--- /dev/null
+++ b/sc/source/ui/inc/dpcontrol.hxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DPCONTROL_HXX
+#define SC_DPCONTROL_HXX
+
+#include "rtl/ustring.hxx"
+#include "tools/gen.hxx"
+#include "tools/fract.hxx"
+#include "vcl/popupmenuwindow.hxx"
+#include "vcl/button.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/timer.hxx"
+#include "svx/checklbx.hxx"
+
+#include <boost/shared_ptr.hpp>
+#include <memory>
+#include <hash_map>
+
+namespace com { namespace sun { namespace star {
+
+ namespace accessibility {
+ class XAccessible;
+ }
+
+}}}
+
+class OutputDevice;
+class Point;
+class Size;
+class StyleSettings;
+class Window;
+class ScDocument;
+class ScAccessibleFilterMenu;
+
+/**
+ * This class takes care of physically drawing field button controls inside
+ * data pilot tables.
+ */
+class ScDPFieldButton
+{
+public:
+ ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX = NULL, const Fraction* pZoomY = NULL,
+ ScDocument* pDoc = NULL);
+ ~ScDPFieldButton();
+
+ void setText(const ::rtl::OUString& rText);
+ void setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL);
+ void setDrawBaseButton(bool b);
+ void setDrawPopupButton(bool b);
+ void setHasHiddenMember(bool b);
+ void setPopupPressed(bool b);
+ void setPopupLeft(bool b);
+ void draw();
+
+ void getPopupBoundingBox(Point& rPos, Size& rSize) const;
+
+private:
+ void drawPopupButton();
+
+private:
+ Point maPos;
+ Size maSize;
+ ::rtl::OUString maText;
+ Fraction maZoomX;
+ Fraction maZoomY;
+ ScDocument* mpDoc;
+ OutputDevice* mpOutDev;
+ const StyleSettings* mpStyle;
+ bool mbBaseButton;
+ bool mbPopupButton;
+ bool mbHasHiddenMember;
+ bool mbPopupPressed;
+ bool mbPopupLeft;
+};
+
+// ============================================================================
+
+class ScMenuFloatingWindow : public PopupMenuFloatingWindow
+{
+public:
+ static size_t MENU_NOT_SELECTED;
+ /**
+ * Action to perform when an event takes place. Create a sub-class of
+ * this to implement the desired action.
+ */
+ class Action
+ {
+ public:
+ virtual void execute() = 0;
+ };
+
+ explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel = 0);
+ virtual ~ScMenuFloatingWindow();
+
+ virtual void MouseMove(const MouseEvent& rMEvt);
+ virtual void MouseButtonDown(const MouseEvent& rMEvt);
+ virtual void MouseButtonUp(const MouseEvent& rMEvt);
+ virtual void KeyInput(const KeyEvent& rKEvt);
+ virtual void Paint(const Rectangle& rRect);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction);
+ ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled);
+ void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
+ void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
+ void clearSelectedMenuItem();
+ ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
+ bool isMenuItemSelected(size_t nPos) const;
+ size_t getSelectedMenuItem() const;
+
+ void setName(const ::rtl::OUString& rName);
+ const ::rtl::OUString& getName() const;
+
+ void executeMenuItem(size_t nPos);
+ void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
+ ScMenuFloatingWindow* getParentMenuWindow() const;
+
+protected:
+
+ void drawMenuItem(size_t nPos);
+ void drawAllMenuItems();
+ const Font& getLabelFont() const;
+
+ void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
+ void queueCloseSubMenu();
+ void launchSubMenu(bool bSetMenuPos);
+ void endSubMenu(ScMenuFloatingWindow* pSubMenu);
+
+ void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
+
+ ScDocument* getDoc();
+
+protected:
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > mxAccessible;
+
+private:
+ struct SubMenuItemData;
+ void handleMenuTimeout(SubMenuItemData* pTimer);
+
+ void resizeToFitMenuItems();
+ void highlightMenuItem(size_t nPos, bool bSelected);
+
+ size_t getEnclosingMenuItem(const Point& rPos) const;
+ size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu);
+
+ /**
+ * Fire a menu highlight event since the accessibility framework needs
+ * this to track focus on menu items.
+ */
+ void fireMenuHighlightedEvent();
+
+ /**
+ * Make sure that the specified submenu is permanently up, the submenu
+ * close timer is not active, and the correct menu item associated with
+ * the submenu is highlighted.
+ */
+ void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu);
+
+ /**
+ * When a menu item of an invisible submenu is selected, we need to make
+ * sure that all its parent menu(s) are visible, with the right menu item
+ * highlighted in each of the parents. Calling this method ensures it.
+ */
+ void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
+
+ /**
+ * Dismiss any visible child submenus when a menu item of a parent menu is
+ * selected.
+ */
+ void ensureSubMenuNotVisible();
+
+ /**
+ * Dismiss all visible popup menus and set focus back to the application
+ * window. This method is called e.g. when a menu action is fired.
+ */
+ void terminateAllPopupMenus();
+
+ DECL_LINK( PopupEndHdl, void* );
+
+private:
+
+ struct MenuItemData
+ {
+ ::rtl::OUString maText;
+ bool mbEnabled;
+
+ ::boost::shared_ptr<Action> mpAction;
+ ::boost::shared_ptr<ScMenuFloatingWindow> mpSubMenuWin;
+
+ MenuItemData();
+ };
+
+ ::std::vector<MenuItemData> maMenuItems;
+
+ struct SubMenuItemData
+ {
+ Timer maTimer;
+ ScMenuFloatingWindow* mpSubMenu;
+ size_t mnMenuPos;
+
+ DECL_LINK( TimeoutHdl, void* );
+
+ SubMenuItemData(ScMenuFloatingWindow* pParent);
+ void reset();
+
+ private:
+ ScMenuFloatingWindow* mpParent;
+ };
+ SubMenuItemData maOpenTimer;
+ SubMenuItemData maCloseTimer;
+
+ Font maLabelFont;
+
+ // Name of this menu window, taken from the menu item of the parent window
+ // that launches it (if this is a sub menu). If this is a top-level menu
+ // window, then this name can be anything.
+ ::rtl::OUString maName;
+
+ size_t mnSelectedMenu;
+ size_t mnClickedMenu;
+
+ ScDocument* mpDoc;
+
+ ScMenuFloatingWindow* mpParentMenu;
+ ScMenuFloatingWindow* mpActiveSubMenu;
+};
+
+// ============================================================================
+
+/**
+ * This class implements a popup window for field button, for quick access
+ * of hide-item list, and possibly more stuff related to field options.
+ */
+class ScDPFieldPopupWindow : public ScMenuFloatingWindow
+{
+public:
+ /**
+ * Extended data that the client code may need to store. Create a
+ * sub-class of this and store data there.
+ */
+ struct ExtendedData {};
+
+ explicit ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc);
+ virtual ~ScDPFieldPopupWindow();
+
+ virtual void MouseMove(const MouseEvent& rMEvt);
+ virtual long Notify(NotifyEvent& rNEvt);
+ virtual void Paint(const Rectangle& rRect);
+ virtual Window* GetPreferredKeyInputWindow();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ void setMemberSize(size_t n);
+ void addMember(const ::rtl::OUString& rName, bool bVisible);
+ void initMembers();
+
+ const Size& getWindowSize() const;
+
+ void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult);
+ void close(bool bOK);
+
+ /**
+ * Set auxiliary data that the client code might need. Note that this
+ * popup window class manages its life time; no explicit deletion of the
+ * instance is needed in the client code.
+ */
+ void setExtendedData(ExtendedData* p);
+
+ /**
+ * Get the store auxiliary data, or NULL if no such data is stored.
+ */
+ ExtendedData* getExtendedData();
+
+ void setOKAction(Action* p);
+
+private:
+ struct Member
+ {
+ ::rtl::OUString maName;
+ bool mbVisible;
+
+ Member();
+ };
+
+ class CancelButton : public ::CancelButton
+ {
+ public:
+ CancelButton(ScDPFieldPopupWindow* pParent);
+
+ virtual void Click();
+
+ private:
+ ScDPFieldPopupWindow* mpParent;
+ };
+
+ enum SectionType {
+ WHOLE, // entire window
+ LISTBOX_AREA_OUTER, // box enclosing the check box items.
+ LISTBOX_AREA_INNER, // box enclosing the check box items.
+ SINGLE_BTN_AREA, // box enclosing the single-action buttons.
+ CHECK_TOGGLE_ALL, // check box for toggling all items.
+ BTN_SINGLE_SELECT,
+ BTN_SINGLE_UNSELECT,
+ BTN_OK, // OK button
+ BTN_CANCEL, // Cancel button
+ };
+ void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
+
+ void setAllMemberState(bool bSet);
+ void selectCurrentMemberOnly(bool bSet);
+ void cycleFocus(bool bReverse = false);
+
+ DECL_LINK( ButtonHdl, Button* );
+ DECL_LINK( TriStateHdl, TriStateBox* );
+ DECL_LINK( CheckHdl, SvTreeListBox* );
+
+private:
+ SvxCheckListBox maChecks;
+
+ TriStateBox maChkToggleAll;
+ ImageButton maBtnSelectSingle;
+ ImageButton maBtnUnselectSingle;
+
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+
+ ::std::vector<Window*> maTabStopCtrls;
+ size_t mnCurTabStop;
+
+ ::std::vector<Member> maMembers;
+ ::std::auto_ptr<ExtendedData> mpExtendedData;
+ ::std::auto_ptr<Action> mpOKAction;
+
+ const Size maWndSize; /// hard-coded window size.
+ TriState mePrevToggleAllState;
+};
+
+#endif
diff --git a/sc/source/ui/inc/dpgroupdlg.hxx b/sc/source/ui/inc/dpgroupdlg.hxx
new file mode 100644
index 000000000000..52f2e7c8f592
--- /dev/null
+++ b/sc/source/ui/inc/dpgroupdlg.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DPGROUPDLG_HXX
+#define SC_DPGROUPDLG_HXX
+
+#ifndef _FIXED_HXX
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _DIALOG_HXX
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/field.hxx>
+#include <svx/checklbx.hxx>
+#include "editfield.hxx"
+#include "dpgroup.hxx"
+
+// ============================================================================
+
+class ScDPGroupEditHelper
+{
+public:
+ explicit ScDPGroupEditHelper(
+ RadioButton& rRbAuto, RadioButton& rRbMan,
+ Edit& rEdValue );
+
+ bool IsAuto() const;
+ double GetValue() const;
+ void SetValue( bool bAuto, double fValue );
+
+private:
+ virtual bool ImplGetValue( double& rfValue ) const = 0;
+ virtual void ImplSetValue( double fValue ) = 0;
+
+ DECL_LINK( ClickHdl, RadioButton* );
+
+private:
+ RadioButton& mrRbAuto;
+ RadioButton& mrRbMan;
+ Edit& mrEdValue;
+};
+
+// ----------------------------------------------------------------------------
+
+class ScDPNumGroupEditHelper : public ScDPGroupEditHelper
+{
+public:
+ explicit ScDPNumGroupEditHelper(
+ RadioButton& rRbAuto, RadioButton& rRbMan,
+ ScDoubleField& rEdValue );
+
+private:
+ virtual bool ImplGetValue( double& rfValue ) const;
+ virtual void ImplSetValue( double fValue );
+
+private:
+ ScDoubleField& mrEdValue;
+};
+
+// ----------------------------------------------------------------------------
+
+class ScDPDateGroupEditHelper : public ScDPGroupEditHelper
+{
+public:
+ explicit ScDPDateGroupEditHelper(
+ RadioButton& rRbAuto, RadioButton& rRbMan,
+ DateField& rEdValue, const Date& rNullDate );
+
+private:
+ virtual bool ImplGetValue( double& rfValue ) const;
+ virtual void ImplSetValue( double fValue );
+
+private:
+ DateField& mrEdValue;
+ Date maNullDate;
+};
+
+// ============================================================================
+// ============================================================================
+
+class ScDPNumGroupDlg : public ModalDialog
+{
+public:
+ explicit ScDPNumGroupDlg( Window* pParent, const ScDPNumGroupInfo& rInfo );
+
+ ScDPNumGroupInfo GetGroupInfo() const;
+
+private:
+ FixedLine maFlStart;
+ RadioButton maRbAutoStart;
+ RadioButton maRbManStart;
+ ScDoubleField maEdStart;
+ FixedLine maFlEnd;
+ RadioButton maRbAutoEnd;
+ RadioButton maRbManEnd;
+ ScDoubleField maEdEnd;
+ FixedLine maFlBy;
+ ScDoubleField maEdBy;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+ ScDPNumGroupEditHelper maStartHelper;
+ ScDPNumGroupEditHelper maEndHelper;
+};
+
+// ============================================================================
+
+class ScDPDateGroupDlg : public ModalDialog
+{
+public:
+ explicit ScDPDateGroupDlg( Window* pParent, const ScDPNumGroupInfo& rInfo,
+ sal_Int32 nDatePart, const Date& rNullDate );
+
+ ScDPNumGroupInfo GetGroupInfo() const;
+ sal_Int32 GetDatePart() const;
+
+private:
+ DECL_LINK( ClickHdl, RadioButton* );
+ DECL_LINK( CheckHdl, SvxCheckListBox* );
+
+private:
+ FixedLine maFlStart;
+ RadioButton maRbAutoStart;
+ RadioButton maRbManStart;
+ DateField maEdStart;
+ FixedLine maFlEnd;
+ RadioButton maRbAutoEnd;
+ RadioButton maRbManEnd;
+ DateField maEdEnd;
+ FixedLine maFlBy;
+ RadioButton maRbNumDays;
+ RadioButton maRbUnits;
+ NumericField maEdNumDays;
+ SvxCheckListBox maLbUnits;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+ ScDPDateGroupEditHelper maStartHelper;
+ ScDPDateGroupEditHelper maEndHelper;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/drawsh.hxx b/sc/source/ui/inc/drawsh.hxx
new file mode 100644
index 000000000000..d417d1427dda
--- /dev/null
+++ b/sc/source/ui/inc/drawsh.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DRAWSH_HXX
+#define SC_DRAWSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+#include <tools/link.hxx>
+
+class AbstractSvxNameDialog; //CHINA001 class SvxNameDialog;
+class ScViewData;
+class ScDrawView;
+
+class ScDrawShell : public SfxShell
+{
+ ScViewData* pViewData;
+
+ DECL_LINK( NameObjectHdl, AbstractSvxNameDialog* );
+
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ void SetHlinkForObject( SdrObject* pObj, const rtl::OUString& rHlnk );
+#endif
+
+protected:
+ ScViewData* GetViewData() { return pViewData; }
+
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_DRAW_SHELL)
+
+ ScDrawShell(ScViewData* pData);
+ ~ScDrawShell();
+
+ void StateDisableItems( SfxItemSet &rSet );
+
+ void ExecDrawAttr(SfxRequest& rReq);
+ void GetDrawAttrState(SfxItemSet &rSet);
+ void GetAttrFuncState(SfxItemSet &rSet);
+
+ void ExecDrawFunc(SfxRequest& rReq);
+ void GetDrawFuncState(SfxItemSet &rSet);
+ void GetState(SfxItemSet &rSet);
+
+ void ExecFormText(SfxRequest& rReq); // StarFontWork
+ void GetFormTextState(SfxItemSet& rSet);
+
+ void ExecuteHLink(SfxRequest& rReq); // Hyperlink
+ void GetHLinkState(SfxItemSet& rSet);
+
+ void ExecFormatPaintbrush(SfxRequest& rReq);
+ void StateFormatPaintbrush(SfxItemSet& rSet);
+
+ void ExecuteMacroAssign( SdrObject* pObj, Window* pWin );
+ void ExecuteLineDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
+ void ExecuteAreaDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
+ void ExecuteTextAttrDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
+
+ ScDrawView* GetDrawView();
+
+ BOOL AreAllObjectsOnLayer(USHORT nLayerNo,const SdrMarkList& rMark);
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/drawutil.hxx b/sc/source/ui/inc/drawutil.hxx
new file mode 100644
index 000000000000..67e1c0ba836f
--- /dev/null
+++ b/sc/source/ui/inc/drawutil.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DRAWUTIL_HXX
+#define SC_DRAWUTIL_HXX
+
+#include "address.hxx"
+#include <tools/solar.h>
+
+class Fraction;
+class OutputDevice;
+class ScDocument;
+
+class ScDrawUtil
+{
+public:
+ static void CalcScale( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ OutputDevice* pDev, const Fraction& rZoomX, const Fraction& rZoomY,
+ double nPPTX, double nPPTY,
+ Fraction& rScaleX, Fraction& rScaleY );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/drawview.hxx b/sc/source/ui/inc/drawview.hxx
new file mode 100644
index 000000000000..fa6b03638551
--- /dev/null
+++ b/sc/source/ui/inc/drawview.hxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DRAWVIEW_HXX
+#define SC_DRAWVIEW_HXX
+
+#include <svx/fmview.hxx>
+
+#include "global.hxx"
+
+namespace com { namespace sun { namespace star { namespace datatransfer { class XTransferable; } } } }
+
+class ScDocument;
+class ScViewData;
+class ScDrawObjData;
+
+class ScDrawView: public FmFormView
+{
+ ScViewData* pViewData;
+ OutputDevice* pDev; //! noetig ?
+ ScDocument* pDoc;
+ SCTAB nTab;
+ Fraction aScaleX; // Faktor fuer Drawing-MapMode
+ Fraction aScaleY;
+ SdrDropMarkerOverlay* pDropMarker;
+ SdrObject* pDropMarkObj;
+ BOOL bInConstruct;
+ //HMHBOOL bDisableHdl;
+
+ void Construct();
+ void UpdateBrowser();
+
+protected:
+ virtual void ModelHasChanged();
+
+ // add custom handles (used by other apps, e.g. AnchorPos)
+ virtual void AddCustomHdl();
+
+ void ImplClearCalcDropMarker();
+
+public:
+ ScDrawView( OutputDevice* pOut, ScViewData* pData );
+ virtual ~ScDrawView();
+
+ virtual void MarkListHasChanged();
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual void DoConnect(SdrOle2Obj* pOleObj);
+
+ virtual void MakeVisible( const Rectangle& rRect, Window& rWin );
+
+ virtual void DeleteMarked();
+
+ void DrawMarks( OutputDevice* pOut ) const;
+
+ void MarkDropObj( SdrObject* pObj );
+
+ //HMHBOOL IsDisableHdl() const { return bDisableHdl; }
+
+ void SetMarkedToLayer( BYTE nLayerNo );
+
+ void InvalidateAttribs();
+ void InvalidateDrawTextAttrs();
+
+ BOOL BeginDrag( Window* pWindow, const Point& rStartPos );
+ void DoCut();
+ void DoCopy();
+
+ void GetScale( Fraction& rFractX, Fraction& rFractY ) const;
+ void RecalcScale();
+ void UpdateWorkArea();
+ SCTAB GetTab() const { return nTab; }
+
+ void CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const;
+
+ void SetAnchor( ScAnchorType );
+ ScAnchorType GetAnchor() const;
+
+ void VCAddWin( Window* pWin );
+ void VCRemoveWin( Window* pWin );
+
+ void UpdateIMap( SdrObject* pObj );
+
+ USHORT GetPopupMenuId();
+ void UpdateUserViewOptions();
+
+ void SetMarkedOriginalSize();
+
+ BOOL SelectObject( const String& rName );
+//UNUSED2008-05 String GetSelectedChartName() const;
+ bool HasMarkedControl() const;
+ bool HasMarkedInternal() const;
+
+ FASTBOOL InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, ULONG nOptions=0);
+
+ /** Returns the selected object, if it is the caption object of a cell note.
+ @param ppCaptData (out-param) If not null, returns the pointer to the caption object data. */
+ SdrObject* GetMarkedNoteCaption( ScDrawObjData** ppCaptData = 0 );
+
+ /** Locks/unlocks the specified layer in the draw page.
+ Unlocked layer is required to be able to edit the contained objects. */
+ void LockCalcLayer( SdrLayerID nLayer, bool bLock = true );
+ /** Unlocks the specified layer in the draw page. */
+ inline void UnlockCalcLayer( SdrLayerID nLayer ) { LockCalcLayer( nLayer, false ); }
+
+ /** Locks/unlocks the background layer that contains background objects.
+ Unlocked layer is required to be able to edit the objects. */
+ inline void LockBackgroundLayer( bool bLock = true ) { LockCalcLayer( SC_LAYER_BACK, bLock ); }
+ /** Unlocks the background layer that contains background objects. */
+ inline void UnlockBackgroundLayer() { LockBackgroundLayer( false ); }
+
+ /** Locks/unlocks the internal layer that contains caption objects of cell notes.
+ Unlocked layer is required to be able to edit the contained objects. */
+ inline void LockInternalLayer( bool bLock = true ) { LockCalcLayer( SC_LAYER_INTERN, bLock ); }
+ /** Unlocks the internal layer that contains caption objects of cell notes. */
+ inline void UnlockInternalLayer() { LockInternalLayer( false ); }
+
+ SdrEndTextEditKind ScEndTextEdit(); // ruft SetDrawTextUndo(0)
+//UNUSED2009-05 void CaptionTextDirection(USHORT nSlot);
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > CopyToTransferable();
+};
+
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/drformsh.hxx b/sc/source/ui/inc/drformsh.hxx
new file mode 100644
index 000000000000..7f7473eb7519
--- /dev/null
+++ b/sc/source/ui/inc/drformsh.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef DRFORMSH_HXX
+#define DRFORMSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+
+class ScViewData;
+
+
+#include "drawsh.hxx"
+
+class ScDrawFormShell: public ScDrawShell
+{
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_FORM_SHELL)
+
+ ScDrawFormShell(ScViewData* pData);
+ virtual ~ScDrawFormShell();
+
+// void Execute(SfxRequest &);
+// void GetState(SfxItemSet &);
+};
+
+#endif
diff --git a/sc/source/ui/inc/drtxtob.hxx b/sc/source/ui/inc/drtxtob.hxx
new file mode 100644
index 000000000000..5c493df2f769
--- /dev/null
+++ b/sc/source/ui/inc/drtxtob.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DRTXTOB_HXX
+#define SC_DRTXTOB_HXX
+
+#ifndef _SFX_HXX
+#endif
+
+#include <sfx2/shell.hxx>
+#include <sfx2/module.hxx>
+#include <tools/link.hxx>
+
+#include "shellids.hxx"
+
+USHORT ScGetFontWorkId(); // statt SvxFontWorkChildWindow::GetChildWindowId()
+
+class ScViewData;
+class TransferableDataHelper;
+class TransferableClipboardListener;
+
+class ScDrawTextObjectBar : public SfxShell
+{
+ ScViewData* pViewData;
+ TransferableClipboardListener* pClipEvtLstnr;
+ BOOL bPastePossible;
+
+ DECL_LINK( ClipboardChanged, TransferableDataHelper* );
+
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_DRAW_TEXT_SHELL)
+
+ ScDrawTextObjectBar(ScViewData* pData);
+ ~ScDrawTextObjectBar();
+
+ void StateDisableItems( SfxItemSet &rSet );
+
+ void Execute( SfxRequest &rReq );
+ void ExecuteTrans( SfxRequest& rReq );
+ void GetState( SfxItemSet& rSet );
+ void GetClipState( SfxItemSet& rSet );
+
+ void ExecuteAttr( SfxRequest &rReq );
+ void GetAttrState( SfxItemSet& rSet );
+ void ExecuteToggle( SfxRequest &rReq );
+
+ BOOL ExecuteCharDlg( const SfxItemSet& rArgs, SfxItemSet& rOutSet );
+ BOOL ExecuteParaDlg( const SfxItemSet& rArgs, SfxItemSet& rOutSet );
+
+ void ExecuteExtra( SfxRequest &rReq );
+ void ExecFormText(SfxRequest& rReq); // StarFontWork
+ void GetFormTextState(SfxItemSet& rSet);
+
+private:
+ void ExecuteGlobal( SfxRequest &rReq ); // von Execute gerufen fuer ganze Objekte
+ void GetGlobalClipState( SfxItemSet& rSet );
+ void ExecutePasteContents( SfxRequest &rReq );
+ BOOL IsNoteEdit();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/drwtrans.hxx b/sc/source/ui/inc/drwtrans.hxx
new file mode 100644
index 000000000000..9a1175d3310d
--- /dev/null
+++ b/sc/source/ui/inc/drwtrans.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DRWTRANS_HXX
+#define SC_DRWTRANS_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <svtools/transfer.hxx>
+
+#include <sfx2/objsh.hxx>
+#include "global.hxx"
+
+
+class SdrModel;
+class ScDocShell;
+class INetBookmark;
+class SdrObject;
+class SdrView;
+class ScDrawView;
+class SdrOle2Obj;
+
+class ScDrawTransferObj : public TransferableHelper
+{
+private:
+ SdrModel* pModel;
+ TransferableDataHelper aOleData;
+ TransferableObjectDescriptor aObjDesc;
+//REMOVE SvEmbeddedObjectRef aDocShellRef;
+//REMOVE SvEmbeddedObjectRef aDrawPersistRef;
+ SfxObjectShellRef aDocShellRef;
+ SfxObjectShellRef aDrawPersistRef;
+
+ // extracted from model in ctor:
+ Size aSrcSize;
+ INetBookmark* pBookmark;
+ BOOL bGraphic;
+ BOOL bGrIsBit;
+ BOOL bOleObj;
+ // source information for drag&drop:
+ // (view is needed to handle drawing obejcts)
+ SdrView* pDragSourceView;
+ USHORT nDragSourceFlags;
+ BOOL bDragWasInternal;
+
+ sal_uInt32 nSourceDocID;
+
+
+ void InitDocShell();
+//REMOVE SvInPlaceObjectRef GetSingleObject();
+ SdrOle2Obj* GetSingleObject();
+
+public:
+ ScDrawTransferObj( SdrModel* pClipModel, ScDocShell* pContainerShell,
+ const TransferableObjectDescriptor& rDesc );
+ virtual ~ScDrawTransferObj();
+
+ virtual void AddSupportedFormats();
+ virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ virtual sal_Bool WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
+ const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ virtual void ObjectReleased();
+ virtual void DragFinished( sal_Int8 nDropAction );
+
+ SdrModel* GetModel() { return pModel; }
+
+ void SetDrawPersist( const SfxObjectShellRef& rRef );
+ void SetDragSource( ScDrawView* pView );
+ void SetDragSourceObj( SdrObject* pObj, SCTAB nTab );
+ void SetDragSourceFlags( USHORT nFlags );
+ void SetDragWasInternal();
+
+ SdrView* GetDragSourceView() { return pDragSourceView; }
+ USHORT GetDragSourceFlags() const { return nDragSourceFlags; }
+
+ void SetSourceDocID( sal_uInt32 nVal )
+ { nSourceDocID = nVal; }
+ sal_uInt32 GetSourceDocID() const { return nSourceDocID; }
+
+ static ScDrawTransferObj* GetOwnClipboard( Window* pUIWin );
+ virtual sal_Int64 SAL_CALL getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException );
+ static const com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/dwfunctr.hxx b/sc/source/ui/inc/dwfunctr.hxx
new file mode 100644
index 000000000000..800696970fbd
--- /dev/null
+++ b/sc/source/ui/inc/dwfunctr.hxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SC_DWFUNCTR_HXX
+#define _SC_DWFUNCTR_HXX
+
+#include <sfx2/childwin.hxx>
+#include <sfx2/dockwin.hxx>
+#include <svl/lstner.hxx>
+#include <svtools/stdctrl.hxx>
+
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+
+#ifndef _IMAGEBTN_HXX //autogen
+#include <vcl/imagebtn.hxx>
+#endif
+
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#include "anyrefdg.hxx"
+#include "global.hxx" // ScAddress
+#include "privsplt.hxx"
+#include "funcdesc.hxx"
+
+#ifndef LRU_MAX
+#define LRU_MAX 10
+#endif
+/*************************************************************************
+|*
+|* Ableitung vom SfxChildWindow als "Behaelter" fuer Controller
+|*
+\************************************************************************/
+
+class ScFunctionChildWindow : public SfxChildWindow
+{
+ public:
+ ScFunctionChildWindow( Window*, USHORT, SfxBindings*,
+ SfxChildWinInfo* );
+
+ SFX_DECL_CHILDWINDOW(ScFunctionChildWindow);
+};
+
+/*************************************************************************
+|*
+|* ScFuncDockWin
+|*
+\************************************************************************/
+
+class ScFunctionDockWin : public SfxDockingWindow, public SfxListener
+{
+
+private:
+ Timer aTimer;
+ ScPrivatSplit aPrivatSplit;
+ ListBox aCatBox;
+ ListBox aFuncList;
+ ListBox aDDFuncList;
+ ListBox* pAllFuncList;
+
+ SfxChildAlignment eSfxNewAlignment;
+ SfxChildAlignment eSfxOldAlignment;
+ ImageButton aInsertButton;
+ FixedText aFiFuncDesc;
+ USHORT nLeftSlot;
+ USHORT nRightSlot;
+ ULONG nMinWidth;
+ ULONG nMinHeight;
+ Size aOldSize;
+ BOOL bSizeFlag;
+ BOOL bInit;
+ short nDockMode;
+ Point aSplitterInitPos;
+ const ScFuncDesc* pFuncDesc;
+ USHORT nArgs;
+ String** pArgArr;
+
+
+ const ScFuncDesc* aLRUList[LRU_MAX];
+
+ void UpdateFunctionList();
+ void UpdateLRUList();
+ void DoEnter(BOOL bOk); //@@ ???
+ void SetDescription();
+ void SetLeftRightSize();
+ void SetTopBottonSize();
+ void SetMyWidthLeRi(Size &aNewSize);
+ void SetMyHeightLeRi(Size &aNewSize);
+ void SetMyWidthToBo(Size &aNewSize);
+ void SetMyHeightToBo(Size &aNewSize);
+ void UseSplitterInitPos();
+
+ DECL_LINK( SetSelectionHdl, void* );
+ DECL_LINK( SelHdl, ListBox* );
+ DECL_LINK(SetSplitHdl,ScPrivatSplit*);
+ DECL_LINK( TimerHdl, Timer*);
+
+protected:
+
+ virtual BOOL Close();
+ virtual void Resize();
+ virtual void Resizing( Size& rSize );
+ virtual void SetSize();
+ virtual void ToggleFloatingMode();
+ virtual void StateChanged( StateChangedType nStateChange );
+
+
+ virtual SfxChildAlignment CheckAlignment(SfxChildAlignment,
+ SfxChildAlignment eAlign);
+
+public:
+ ScFunctionDockWin( SfxBindings* pBindings,
+ SfxChildWindow *pCW,
+ Window* pParent,
+ const ResId& rResId );
+
+ ~ScFunctionDockWin();
+
+ using SfxDockingWindow::Notify;
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ void SetSlotIDs( USHORT nLeft, USHORT nRight )
+ { nLeftSlot = nLeft; nRightSlot = nRight; }
+
+ void InitLRUList();
+
+ void Initialize (SfxChildWinInfo* pInfo);
+ virtual void FillInfo(SfxChildWinInfo&) const;
+};
+
+#endif
+
+
diff --git a/sc/source/ui/inc/editable.hxx b/sc/source/ui/inc/editable.hxx
new file mode 100644
index 000000000000..4b6e8d0596bc
--- /dev/null
+++ b/sc/source/ui/inc/editable.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EDITABLE_HXX
+#define SC_EDITABLE_HXX
+
+#include "address.hxx"
+#include <tools/solar.h>
+
+class ScDocument;
+class ScViewFunc;
+class ScMarkData;
+class ScRange;
+
+
+class ScEditableTester
+{
+ BOOL bIsEditable;
+ BOOL bOnlyMatrix;
+
+public:
+ // no test in ctor
+ ScEditableTester();
+
+ // calls TestBlock
+ ScEditableTester( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
+
+ // calls TestSelectedBlock
+ ScEditableTester( ScDocument* pDoc,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark );
+
+ // calls TestRange
+ ScEditableTester( ScDocument* pDoc, const ScRange& rRange );
+
+ // calls TestSelection
+ ScEditableTester( ScDocument* pDoc, const ScMarkData& rMark );
+
+ // calls TestView
+ ScEditableTester( ScViewFunc* pView );
+
+ ~ScEditableTester() {}
+
+ // Several calls to the Test... methods check if *all* of the ranges
+ // are editable. For several independent checks, Reset() has to be used.
+ void TestBlock( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
+ void TestSelectedBlock( ScDocument* pDoc,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ const ScMarkData& rMark );
+ void TestRange( ScDocument* pDoc, const ScRange& rRange );
+ void TestSelection( ScDocument* pDoc, const ScMarkData& rMark );
+ void TestView( ScViewFunc* pView );
+
+ BOOL IsEditable() const { return bIsEditable; }
+ BOOL IsFormatEditable() const { return bIsEditable || bOnlyMatrix; }
+ USHORT GetMessageId() const;
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/editfield.hxx b/sc/source/ui/inc/editfield.hxx
new file mode 100644
index 000000000000..9836e94aa215
--- /dev/null
+++ b/sc/source/ui/inc/editfield.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EDITFIELD_HXX
+#define SC_EDITFIELD_HXX
+
+#include <vcl/field.hxx>
+
+// ============================================================================
+
+/** An edit control that contains a double precision floating-point value. */
+class ScDoubleField : public Edit
+{
+public:
+ explicit ScDoubleField( Window* pParent, const ResId& rResId );
+
+ bool GetValue( double& rfValue ) const;
+ void SetValue( double fValue,
+ sal_Int32 nDecPlaces = 12,
+ bool bEraseTrailingDecZeros = true );
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/editsh.hxx b/sc/source/ui/inc/editsh.hxx
new file mode 100644
index 000000000000..ebada82a32fb
--- /dev/null
+++ b/sc/source/ui/inc/editsh.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EDITSH_HXX
+#define SC_EDITSH_HXX
+
+#include <sfx2/shell.hxx>
+#include <sfx2/module.hxx>
+#include <tools/link.hxx>
+
+#include "shellids.hxx"
+#include <editeng/editview.hxx>
+
+class EditView;
+class ScViewData;
+class ScInputHandler;
+class SvxURLField;
+class TransferableDataHelper;
+class TransferableClipboardListener;
+
+class ScEditShell : public SfxShell
+{
+private:
+ EditView* pEditView;
+ ScViewData* pViewData;
+ TransferableClipboardListener* pClipEvtLstnr;
+ BOOL bPastePossible;
+ BOOL bIsInsertMode;
+
+ const SvxURLField* GetURLField();
+ ScInputHandler* GetMyInputHdl();
+
+ DECL_LINK( ClipboardChanged, TransferableDataHelper* );
+
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_EDIT_SHELL)
+
+ ScEditShell(EditView* pView, ScViewData* pData);
+ ~ScEditShell();
+
+ void SetEditView(EditView* pView);
+ EditView* GetEditView() {return pEditView;}
+
+ void Execute(SfxRequest& rReq);
+ void ExecuteTrans(SfxRequest& rReq);
+ void GetState(SfxItemSet &rSet);
+ void GetClipState(SfxItemSet& rSet);
+
+ void ExecuteAttr(SfxRequest& rReq);
+ void GetAttrState(SfxItemSet &rSet);
+
+ void ExecuteUndo(SfxRequest& rReq);
+ void GetUndoState(SfxItemSet &rSet);
+
+ String GetSelectionText( BOOL bWholeWord );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/expftext.hxx b/sc/source/ui/inc/expftext.hxx
new file mode 100644
index 000000000000..170deba5b403
--- /dev/null
+++ b/sc/source/ui/inc/expftext.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_EXPFTEXT_HXX
+#define _SC_EXPFTEXT_HXX
+
+#include <vcl/fixed.hxx>
+#include "scdllapi.h"
+
+class SC_DLLPUBLIC ScExpandedFixedText: public FixedText
+{
+ protected:
+
+ void RequestHelp( const HelpEvent& rHEvt );
+
+ public:
+ ScExpandedFixedText( Window* pWindow, const ResId& rResId);
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/fieldwnd.hxx b/sc/source/ui/inc/fieldwnd.hxx
new file mode 100755
index 000000000000..539dbe54e275
--- /dev/null
+++ b/sc/source/ui/inc/fieldwnd.hxx
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_FIELDWND_HXX
+#define SC_FIELDWND_HXX
+
+#include <vector>
+#include "address.hxx"
+#include <vcl/ctrl.hxx>
+#include <vcl/fixed.hxx>
+#include <cppuhelper/weakref.hxx>
+
+#define PAGE_SIZE 16 // count of visible fields for scrollbar
+#define LINE_SIZE 8 // count of fields per column for scrollbar
+#define MAX_FIELDS 8 // maximum count of fields for row/col/data area
+#define MAX_PAGEFIELDS 10 // maximum count of fields for page area
+
+#define OWIDTH PivotGlobal::nObjWidth
+#define OHEIGHT PivotGlobal::nObjHeight
+#define SSPACE PivotGlobal::nSelSpace
+
+class ScDPLayoutDlg;
+class ScAccessibleDataPilotControl;
+
+//===================================================================
+
+/** Type of content area. */
+enum ScDPFieldType
+{
+ TYPE_PAGE, /// Area for all page fields.
+ TYPE_ROW, /// Area for all row fields.
+ TYPE_COL, /// Area for all column fields.
+ TYPE_DATA, /// Area for all data fields.
+ TYPE_SELECT /// Selection area with all fields.
+};
+
+//-------------------------------------------------------------------
+
+/** Represents a field area in the DataPilot layout dialog. */
+class ScDPFieldWindow : public Control
+{
+private:
+ typedef ::std::pair< String, bool > FieldString; // true = text fits into button
+
+ String aName; /// name of the control, used in Accessibility
+ ScDPLayoutDlg* pDlg; /// Parent dialog.
+ Rectangle aWndRect; /// Area rectangle in pixels.
+ FixedText* pFtCaption; /// FixedText containing the name of the control.
+ Point aTextPos; /// Position of the caption text.
+ std::vector< FieldString > aFieldArr; /// String array of the field names and flags, if text fits into button.
+ ScDPFieldType eType; /// Type of this area.
+ Color aFaceColor; /// Color for dialog background.
+ Color aWinColor; /// Color for window background.
+ Color aTextColor; /// Color for text in buttons.
+ Color aWinTextColor; /// Color for text in field windows.
+ size_t nFieldSize; /// Maximum count of fields.
+ size_t nFieldSelected; /// Currently selected field.
+
+ com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAccessible;
+ ScAccessibleDataPilotControl* pAccessible;
+
+ /** Initilize the object. */
+ void Init();
+
+ /** Reads all needed style settings. */
+ void GetStyleSettings();
+
+ /** Draws the background. */
+ void DrawBackground( OutputDevice& rDev );
+ /** Draws a field into the specified rectangle. */
+ void DrawField(
+ OutputDevice& rDev,
+ const Rectangle& rRect,
+ FieldString& rText,
+ bool bFocus );
+
+ /** @return TRUE, if the field index is inside of the control area. */
+ bool IsValidIndex( size_t nIndex ) const;
+ /** @return TRUE, if the field with the given index exists. */
+ bool IsExistingIndex( size_t nIndex ) const;
+ /** @return TRUE, if the field with the given index exists and the text is
+ too long for the button control. */
+ bool IsShortenedText( size_t nIndex ) const;
+ /** @return The new selection index after moving to the given direction. */
+ size_t CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const;
+
+ /** Sets selection to the field with index nIndex. */
+ void SetSelection( size_t nIndex );
+ /** Sets selection to first field. */
+ void SetSelectionHome();
+ /** Sets selection to last field. */
+ void SetSelectionEnd();
+ /** Sets selection to new position relative to current. */
+ void MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY );
+
+ /** Moves the selected field to nDestIndex. */
+ void MoveField( size_t nDestIndex );
+ /** Moves the selected field to the given direction. */
+ void MoveFieldRel( SCsCOL nDX, SCsROW nDY );
+
+ /** Updates the tab stop style bits. */
+ void UpdateStyle();
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+public:
+ ScDPFieldWindow(
+ ScDPLayoutDlg* pDialog,
+ const ResId& rResId,
+ ScDPFieldType eFieldType,
+ FixedText* pFtFieldCaption );
+ ScDPFieldWindow(
+ ScDPLayoutDlg* pDialog,
+ const ResId& rResId,
+ ScDPFieldType eFieldType,
+ const String& aName );
+ virtual ~ScDPFieldWindow();
+
+ /** Reads the FixedText's text with mnemonic and hides the FixedText. */
+ void UseMnemonic();
+
+ /** Draws the complete control. */
+ void Redraw();
+
+ /** @return The pixel position of a field (without bound check). */
+ Point GetFieldPosition( size_t nIndex ) const;
+ /** @return The pixel size of a field. */
+ Size GetFieldSize() const;
+
+ /** @return The index of the selected field. */
+ inline bool IsEmpty() const { return aFieldArr.empty(); }
+ /** @return The index of the selected field. */
+ inline size_t GetSelectedField() const { return nFieldSelected; }
+ /** @return The pixel position of the last possible field. */
+ Point GetLastPosition() const;
+
+ /** @return The count of existing fields. */
+ inline size_t GetFieldCount() const { return aFieldArr.size(); }
+ /** Inserts a field to the specified index. */
+ void AddField( const String& rText, size_t nNewIndex );
+ /** Removes a field from the specified index. */
+ void DelField( size_t nDelIndex );
+ /** Removes all fields. */
+ void ClearFields();
+ /** Changes the text on an existing field. */
+ void SetFieldText( const String& rText, size_t nIndex );
+ /** Returns the text of an existing field. */
+ const String& GetFieldText( size_t nIndex ) const;
+
+ /** Inserts a field using the specified pixel position.
+ @param rPos The coordinates to insert the field.
+ @param rnIndex The new index of the field is returned here.
+ @return TRUE, if the field has been created. */
+ bool AddField( const String& rText, const Point& rPos, size_t& rnIndex );
+ /** Calculates the field index at a specific pixel position.
+ @param rnIndex The index of the field is returned here.
+ @return TRUE, if the index value is valid. */
+ bool GetFieldIndex( const Point& rPos, size_t& rnIndex ) const;
+ /** Calculates a field index at a specific pixel position. Returns in every
+ case the index of an existing field.
+ @param rnIndex The index of the field is returned here.
+ @return TRUE, if the index value is valid. */
+ void GetExistingIndex( const Point& rPos, size_t& rnIndex );
+
+ /** Notifies this control that the offset of the first field has been changed.
+ The control has to adjust the selection to keep the same field selected
+ on scrolling with scrollbar. */
+ void ModifySelectionOffset( long nOffsetDiff );
+ /** Selects the next field. Called i.e. after moving a field from SELECT area. */
+ void SelectNext();
+
+ /** @return The name of the control without shortcut. */
+ inline String GetName() const { return aName; }
+
+ /** @return The description of the control which is used for the accessibility objects. */
+ String GetDescription() const;
+
+ /** Grabs focus and sets new selection. */
+ void GrabFocusWithSel( size_t nIndex );
+
+ /** @return The type of the FieldWindow. */
+ inline ScDPFieldType GetType() const { return eType; }
+};
+
+//===================================================================
+
+#endif // SC_FIELDWND_HXX
diff --git a/sc/source/ui/inc/filldlg.hxx b/sc/source/ui/inc/filldlg.hxx
new file mode 100644
index 000000000000..7f2fb046093c
--- /dev/null
+++ b/sc/source/ui/inc/filldlg.hxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FILLDLG_HXX
+#define SC_FILLDLG_HXX
+
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _EDIT_HXX //autogen
+#include <vcl/edit.hxx>
+#endif
+#include "global.hxx"
+
+class ScDocument;
+
+//----------------------------------------------------------------------------
+
+//CHINA001 #define FDS_OPT_NONE 0
+//CHINA001 #define FDS_OPT_HORZ 1
+//CHINA001 #define FDS_OPT_VERT 2
+//CHINA001
+#include "scui_def.hxx" //CHINA001
+//============================================================================
+
+class ScFillSeriesDlg : public ModalDialog
+{
+public:
+ ScFillSeriesDlg( Window* pParent,
+ ScDocument& rDocument,
+ FillDir eFillDir,
+ FillCmd eFillCmd,
+ FillDateCmd eFillDateCmd,
+ String aStartStr,
+ double fStep,
+ double fMax,
+ USHORT nPossDir );
+ ~ScFillSeriesDlg();
+
+ FillDir GetFillDir() const { return theFillDir; }
+ FillCmd GetFillCmd() const { return theFillCmd; }
+ FillDateCmd GetFillDateCmd() const { return theFillDateCmd; }
+ double GetStart() const { return fStartVal; }
+ double GetStep() const { return fIncrement; }
+ double GetMax() const { return fEndVal; }
+
+ String GetStartStr() const { return aEdStartVal.GetText(); }
+
+ void SetEdStartValEnabled(BOOL bFlag=FALSE);
+
+private:
+ FixedLine aFlDirection;
+ RadioButton aBtnDown;
+ RadioButton aBtnRight;
+ RadioButton aBtnUp;
+ RadioButton aBtnLeft;
+
+ FixedLine aFlSep1;
+ FixedLine aFlType;
+ RadioButton aBtnArithmetic;
+ RadioButton aBtnGeometric;
+ RadioButton aBtnDate;
+ RadioButton aBtnAutoFill;
+
+ FixedLine aFlSep2;
+ FixedLine aFlTimeUnit;
+ RadioButton aBtnDay;
+ RadioButton aBtnDayOfWeek;
+ RadioButton aBtnMonth;
+ RadioButton aBtnYear;
+
+ BOOL bStartValFlag;
+ FixedText aFtStartVal;
+ Edit aEdStartVal;
+ String aStartStrVal;
+
+ FixedText aFtEndVal;
+ Edit aEdEndVal;
+
+ FixedText aFtIncrement;
+ Edit aEdIncrement;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ const String errMsgInvalidVal;
+
+ //----------------------------------------------------------
+
+ ScDocument& rDoc;
+ FillDir theFillDir;
+ FillCmd theFillCmd;
+ FillDateCmd theFillDateCmd;
+ double fStartVal;
+ double fIncrement;
+ double fEndVal;
+
+#ifdef _FILLDLG_CXX
+private:
+ void Init( USHORT nPossDir );
+ BOOL CheckStartVal();
+ BOOL CheckIncrementVal();
+ BOOL CheckEndVal();
+
+ DECL_LINK( OKHdl, void * );
+ DECL_LINK( DisableHdl, Button * );
+#endif
+};
+
+
+
+#endif // SC_FILLDLG_HXX
+
diff --git a/sc/source/ui/inc/filtdlg.hxx b/sc/source/ui/inc/filtdlg.hxx
new file mode 100644
index 000000000000..31e0e3a5d4b1
--- /dev/null
+++ b/sc/source/ui/inc/filtdlg.hxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_FILTDLG_HXX
+#define SC_FILTDLG_HXX
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#include <svtools/stdctrl.hxx>
+#include "global.hxx" // -> ScQueryParam
+#include "address.hxx"
+#include "anyrefdg.hxx"
+
+
+//----------------------------------------------------------------------------
+
+class ScFilterOptionsMgr;
+class ScRangeData;
+class ScViewData;
+class ScDocument;
+class ScQueryItem;
+class TypedScStrCollection;
+
+//==================================================================
+// Gemeinsame Resource-Objekte:
+
+#define _COMMON_FILTER_RSCOBJS \
+ CheckBox aBtnCase; \
+ CheckBox aBtnRegExp; \
+ CheckBox aBtnHeader; \
+ CheckBox aBtnUnique; \
+ CheckBox aBtnCopyResult; \
+ ListBox aLbCopyArea; \
+ formula::RefEdit aEdCopyArea; \
+ formula::RefButton aRbCopyArea; \
+ CheckBox aBtnDestPers; \
+ FixedText aFtDbAreaLabel; \
+ FixedInfo aFtDbArea; \
+ const String aStrUndefined; \
+ const String aStrNoName; \
+ const String aStrNone;
+
+
+#define _INIT_COMMON_FILTER_RSCOBJS \
+ aBtnCase ( this, ScResId( BTN_CASE ) ), \
+ aBtnRegExp ( this, ScResId( BTN_REGEXP ) ), \
+ aBtnHeader ( this, ScResId( BTN_HEADER ) ), \
+ aBtnUnique ( this, ScResId( BTN_UNIQUE ) ), \
+ aBtnCopyResult ( this, ScResId( BTN_COPY_RESULT ) ), \
+ aLbCopyArea ( this, ScResId( LB_COPY_AREA ) ), \
+ aEdCopyArea ( this, this, ScResId( ED_COPY_AREA ) ), \
+ aRbCopyArea ( this, ScResId( RB_COPY_AREA ), &aEdCopyArea, this ), \
+ aBtnDestPers ( this, ScResId( BTN_DEST_PERS ) ), \
+ aFtDbAreaLabel ( this, ScResId( FT_DBAREA_LABEL ) ), \
+ aFtDbArea ( this, ScResId( FT_DBAREA ) ), \
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ), \
+ aStrNoName ( ScGlobal::GetRscString(STR_DB_NONAME) ), \
+ aStrNone ( ScResId( SCSTR_NONE ) ),
+
+
+//============================================================================
+class ScFilterDlg : public ScAnyRefDlg
+{
+public:
+ ScFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScFilterDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+
+ virtual BOOL Close();
+ void SliderMoved();
+ USHORT GetSliderPos();
+ void RefreshEditRow( USHORT nOffset );
+
+private:
+ FixedLine aFlCriteria;
+ //----------------------------
+ ListBox aLbConnect1;
+ ListBox aLbField1;
+ ListBox aLbCond1;
+ ComboBox aEdVal1;
+ //----------------------------
+ ListBox aLbConnect2;
+ ListBox aLbField2;
+ ListBox aLbCond2;
+ ComboBox aEdVal2;
+ //----------------------------
+ ListBox aLbConnect3;
+ ListBox aLbField3;
+ ListBox aLbCond3;
+ ComboBox aEdVal3;
+ //----------------------------
+ ListBox aLbConnect4;
+ ListBox aLbField4;
+ ListBox aLbCond4;
+ ComboBox aEdVal4;
+ //----------------------------
+ FixedText aFtConnect;
+ FixedText aFtField;
+ FixedText aFtCond;
+ FixedText aFtVal;
+ FixedLine aFlSeparator;
+
+ ScrollBar aScrollBar;
+
+ FixedLine aFlOptions;
+ MoreButton aBtnMore;
+ HelpButton aBtnHelp;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+
+ _COMMON_FILTER_RSCOBJS
+
+ const String aStrEmpty;
+ const String aStrNotEmpty;
+ const String aStrRow;
+ const String aStrColumn;
+
+ ScFilterOptionsMgr* pOptionsMgr;
+
+ const USHORT nWhichQuery;
+ const ScQueryParam theQueryData;
+ ScQueryItem* pOutItem;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ SCTAB nSrcTab;
+
+ ComboBox* aValueEdArr[4];
+ ListBox* aFieldLbArr[4];
+ ListBox* aCondLbArr[4];
+ ListBox* aConnLbArr[4];
+ bool mbHasDates[MAXQUERY];
+ BOOL bRefreshExceptQuery[MAXQUERY];
+ USHORT nFieldCount;
+ BOOL bRefInputMode;
+
+ TypedScStrCollection* pEntryLists[MAXCOLCOUNT];
+ USHORT nHeaderPos[MAXCOLCOUNT];
+
+ // Hack: RefInput-Kontrolle
+ Timer* pTimer;
+
+#ifdef _FILTDLG_CXX
+private:
+ void Init ( const SfxItemSet& rArgSet );
+ void FillFieldLists ();
+ void FillAreaList ();
+ void UpdateValueList ( USHORT nList );
+ void UpdateHdrInValueList( USHORT nList );
+ void ClearValueList ( USHORT nList );
+ USHORT GetFieldSelPos ( SCCOL nField );
+ ScQueryItem* GetOutputItem ();
+
+ // Handler:
+ DECL_LINK( LbSelectHdl, ListBox* );
+ DECL_LINK( ValModifyHdl, ComboBox* );
+ DECL_LINK( CheckBoxHdl, CheckBox* );
+ DECL_LINK( EndDlgHdl, Button* );
+ DECL_LINK( MoreClickHdl, MoreButton* );
+ DECL_LINK( ScrollHdl, ScrollBar* );
+
+ // Hack: RefInput-Kontrolle
+ DECL_LINK( TimeOutHdl, Timer* );
+#endif
+};
+
+
+//============================================================================
+class ScSpecialFilterDlg : public ScAnyRefDlg
+{
+public:
+ ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScSpecialFilterDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+
+ virtual BOOL Close();
+
+private:
+ ListBox aLbFilterArea;
+ FixedText aFtFilterArea;
+ formula::RefEdit aEdFilterArea;
+ formula::RefButton aRbFilterArea;
+
+ FixedLine aFlOptions;
+
+ _COMMON_FILTER_RSCOBJS
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ MoreButton aBtnMore;
+
+ ScFilterOptionsMgr* pOptionsMgr;
+
+ const USHORT nWhichQuery;
+ const ScQueryParam theQueryData;
+ ScQueryItem* pOutItem;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+
+ formula::RefEdit* pRefInputEdit;
+ BOOL bRefInputMode;
+
+ // Hack: RefInput-Kontrolle
+ Timer* pTimer;
+
+#ifdef _SFILTDLG_CXX
+private:
+ void Init( const SfxItemSet& rArgSet );
+ ScQueryItem* GetOutputItem( const ScQueryParam& rParam,
+ const ScRange& rSource );
+
+ // Handler
+ DECL_LINK( FilterAreaSelHdl, ListBox* );
+ DECL_LINK( FilterAreaModHdl, formula::RefEdit* );
+ DECL_LINK( EndDlgHdl, Button* );
+ DECL_LINK( ScrollHdl, ScrollBar* );
+
+ // Hack: RefInput-Kontrolle
+ DECL_LINK( TimeOutHdl, Timer* );
+#endif
+};
+
+
+
+#endif // SC_FILTDLG_HXX
+
diff --git a/sc/source/ui/inc/filter.hrc b/sc/source/ui/inc/filter.hrc
new file mode 100644
index 000000000000..508c5af9aab5
--- /dev/null
+++ b/sc/source/ui/inc/filter.hrc
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc" // -> RID_SCDLG_FILTER
+ // -> RID_SCDLG_SPEC_FILTER
+ // -> RID_SCDLG_PIVOTFILTER
+
+// allgemein
+
+#define BTN_OK 1
+#define BTN_CANCEL 1
+#define BTN_HELP 1
+#define BTN_MORE 1
+
+#define BTN_UNIQUE 1
+#define BTN_CASE 2
+#define BTN_REGEXP 3
+#define BTN_HEADER 4
+#define BTN_COPY_RESULT 5
+#define LB_COPY_AREA 6
+#define ED_COPY_AREA 7
+#define RB_COPY_AREA 8
+#define FL_OPTIONS 9
+#define FT_DBAREA_LABEL 10
+#define FT_DBAREA 11
+#define BTN_DEST_PERS 12
+
+// Filter:
+#define FT_OP 20
+#define FT_FIELD 21
+#define FT_COND 22
+#define FT_VAL 23
+#define LB_FIELD1 24
+#define LB_FIELD2 25
+#define LB_FIELD3 26
+#define LB_OP1 27
+#define LB_OP2 28
+#define LB_COND1 29
+#define LB_COND2 30
+#define LB_COND3 31
+#define ED_VAL1 32
+#define ED_VAL2 33
+#define ED_VAL3 34
+#define FL_CRITERIA 35
+#define FL_SEPARATOR 36
+#define LB_OP3 37
+#define LB_FIELD4 38
+#define LB_COND4 39
+#define ED_VAL4 40
+#define LB_SCROLL 41
+#define LB_OP4 42
+
+// Spezialfilter
+
+#define FT_CRITERIA_AREA 50
+#define LB_CRITERIA_AREA 51
+#define ED_CRITERIA_AREA 52
+#define RB_CRITERIA_AREA 53
+
diff --git a/sc/source/ui/inc/foptmgr.hxx b/sc/source/ui/inc/foptmgr.hxx
new file mode 100644
index 000000000000..92e3833dff7d
--- /dev/null
+++ b/sc/source/ui/inc/foptmgr.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FOPTMGR_HXX
+#define SC_FOPTMGR_HXX
+
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _EDIT_HXX //autogen
+#include <vcl/edit.hxx>
+#endif
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+
+//----------------------------------------------------------------------------
+
+class FixedInfo;
+namespace formula
+{
+ class RefButton;
+}
+class MoreButton;
+class Dialog;
+struct ScQueryParam;
+class ScDocument;
+class ScViewData;
+
+//----------------------------------------------------------------------------
+
+class ScFilterOptionsMgr
+{
+public:
+ ScFilterOptionsMgr( Dialog* ptrDlg,
+ ScViewData* ptrViewData,
+ const ScQueryParam& refQueryData,
+ MoreButton& refBtnMore,
+ CheckBox& refBtnCase,
+ CheckBox& refBtnRegExp,
+ CheckBox& refBtnHeader,
+ CheckBox& refBtnUnique,
+ CheckBox& refBtnCopyResult,
+ CheckBox& refBtnDestPers,
+ ListBox& refLbCopyArea,
+ Edit& refEdCopyArea,
+ formula::RefButton& refRbCopyArea,
+ FixedText& refFtDbAreaLabel,
+ FixedInfo& refFtDbArea,
+ FixedLine& refFlOptions,
+ const String& refStrNoName,
+ const String& refStrUndefined );
+ ~ScFilterOptionsMgr();
+
+ BOOL VerifyPosStr ( const String& rPosStr ) const;
+
+private:
+ Dialog* pDlg;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+
+ MoreButton& rBtnMore;
+ CheckBox& rBtnCase;
+ CheckBox& rBtnRegExp;
+ CheckBox& rBtnHeader;
+ CheckBox& rBtnUnique;
+ CheckBox& rBtnCopyResult;
+ CheckBox& rBtnDestPers;
+ ListBox& rLbCopyPos;
+ Edit& rEdCopyPos;
+ formula::RefButton& rRbCopyPos;
+ FixedText& rFtDbAreaLabel;
+ FixedInfo& rFtDbArea;
+ FixedLine& rFlOptions;
+
+ const String& rStrNoName;
+ const String& rStrUndefined;
+
+ const ScQueryParam& rQueryData;
+
+#ifdef _FOPTMGR_CXX
+private:
+ void Init();
+
+ // Handler:
+ DECL_LINK( EdPosModifyHdl, Edit* );
+ DECL_LINK( LbPosSelHdl, ListBox* );
+ DECL_LINK( BtnCopyResultHdl, CheckBox* );
+#endif
+};
+
+
+
+#endif // SC_FOPTMGR_HXX
diff --git a/sc/source/ui/inc/formatsh.hxx b/sc/source/ui/inc/formatsh.hxx
new file mode 100644
index 000000000000..e45fb99c54ef
--- /dev/null
+++ b/sc/source/ui/inc/formatsh.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMATSH_HXX
+#define SC_FORMATSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+
+class ScViewData;
+
+class ScFormatShell: public SfxShell
+{
+ ScViewData* pViewData;
+
+protected:
+
+ ScViewData* GetViewData(){return pViewData;}
+ const ScViewData* GetViewData() const {return pViewData;}
+
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_FORMAT_SHELL)
+
+ ScFormatShell(ScViewData* pData);
+ virtual ~ScFormatShell();
+
+ void ExecuteNumFormat( SfxRequest& rReq );
+ void GetNumFormatState( SfxItemSet& rSet );
+
+ void ExecuteAttr( SfxRequest& rReq );
+ void GetAttrState( SfxItemSet& rSet );
+
+ void ExecuteAlignment( SfxRequest& rReq );
+
+ void ExecuteTextAttr( SfxRequest& rReq );
+ void GetTextAttrState( SfxItemSet& rSet );
+
+ void GetAlignState( SfxItemSet& rSet );
+ void GetBorderState( SfxItemSet& rSet );
+
+ void ExecuteStyle( SfxRequest& rReq );
+ void GetStyleState( SfxItemSet& rSet );
+
+ void ExecuteTextDirection( SfxRequest& rReq );
+ void GetTextDirectionState( SfxItemSet& rSet );
+
+ void ExecFormatPaintbrush( SfxRequest& rReq );
+ void StateFormatPaintbrush( SfxItemSet& rSet );
+};
+
+#endif
diff --git a/sc/source/ui/inc/formdata.hxx b/sc/source/ui/inc/formdata.hxx
new file mode 100644
index 000000000000..72c7862a007b
--- /dev/null
+++ b/sc/source/ui/inc/formdata.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMDATA_HXX
+#define SC_FORMDATA_HXX
+
+#include <tools/string.hxx>
+#include <tools/gen.hxx>
+#include <formula/formdata.hxx>
+class ScInputHandler;
+class ScDocShell;
+
+//============================================================================
+
+class ScFormEditData : public formula::FormEditData
+{
+public:
+ ScFormEditData();
+ virtual ~ScFormEditData();
+
+ ScInputHandler* GetInputHandler() { return pInputHandler;}
+ ScDocShell* GetDocShell() { return pScDocShell;}
+
+ void SetInputHandler(ScInputHandler* pHdl) { pInputHandler=pHdl;}
+ void SetDocShell(ScDocShell* pSds) { pScDocShell=pSds;}
+
+
+ virtual void SaveValues();
+
+private:
+ ScFormEditData( const ScFormEditData& );
+// const ScFormEditData& operator=( const ScFormEditData& r );
+
+
+ ScInputHandler* pInputHandler;
+ ScDocShell* pScDocShell;
+};
+
+
+
+#endif // SC_CRNRDLG_HXX
+
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
new file mode 100644
index 000000000000..f863662f7cd0
--- /dev/null
+++ b/sc/source/ui/inc/formula.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMULA_HXX
+#define SC_FORMULA_HXX
+
+#include "anyrefdg.hxx"
+#include "global.hxx" // ScAddress
+#include <svtools/stdctrl.hxx>
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#include <vcl/group.hxx>
+#include <svtools/svmedit.hxx>
+#include <vcl/tabpage.hxx>
+
+#ifndef _SVSTDARR_STRINGS
+
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+
+#endif
+#include "compiler.hxx"
+#include "cell.hxx"
+
+#include "formula/formula.hxx"
+#include "IAnyRefDialog.hxx"
+#include "anyrefdg.hxx"
+#include <formula/IFunctionDescription.hxx>
+
+class ScViewData;
+class ScDocument;
+class ScFuncDesc;
+class ScInputHandler;
+class ScDocShell;
+class SvLBoxEntry;
+
+//============================================================================
+typedef ScTabViewShell* PtrTabViewShell;
+//============================================================================
+
+class ScFormulaDlg : public formula::FormulaDlg,
+ public IAnyRefDialog,
+ public formula::IFormulaEditorHelper
+{
+ ScFormulaReferenceHelper m_aHelper;
+ ScFormulaCell* pCell;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser> m_xParser;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaOpCodeMapper> m_xOpCodeMapper;
+
+ static ScDocument* pDoc;
+ static ScAddress aCursorPos;
+public:
+ ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
+ Window* pParent, ScViewData* pViewData ,formula::IFunctionManager* _pFunctionMgr);
+ ~ScFormulaDlg();
+
+ // IFormulaEditorHelper
+ virtual void notifyChange();
+ virtual void fill();
+ virtual bool calculateValue(const String& _sExpression,String& _rResult);
+ virtual void doClose(BOOL _bOk);
+ virtual void insertEntryToLRUList(const formula::IFunctionDescription* pDesc);
+ virtual void showReference(const String& _sFormula);
+ virtual void dispatch(BOOL _bOK,BOOL _bMartixChecked);
+ virtual void setDispatcherLock( BOOL bLock );
+ virtual void setReferenceInput(const formula::FormEditData* _pData);
+ virtual void deleteFormData();
+ virtual void clear();
+ virtual void switchBack();
+ virtual formula::FormEditData* getFormEditData() const;
+ virtual void setCurrentFormula(const String& _sReplacement);
+ virtual void setSelection(xub_StrLen _nStart,xub_StrLen _nEnd);
+ virtual void getSelection(xub_StrLen& _nStart,xub_StrLen& _nEnd) const;
+ virtual String getCurrentFormula() const;
+
+ virtual formula::IFunctionManager* getFunctionManager();
+ 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();
+
+ // sc::IAnyRefDialog
+ virtual void ShowReference(const String& _sRef);
+ virtual void HideReference( BOOL bDoneRefMode = TRUE );
+ virtual void SetReference( const ScRange& rRef, ScDocument* pD );
+
+ virtual void ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ virtual void RefInputDone( BOOL bForced = FALSE );
+ virtual BOOL IsTableLocked() const;
+ virtual BOOL IsRefInputMode() const;
+
+ virtual BOOL IsDocAllowed( SfxObjectShell* pDocSh ) const;
+ virtual void AddRefEntry();
+ virtual void SetActive();
+ virtual void ViewShellChanged( ScTabViewShell* pScViewShell );
+protected:
+
+ virtual void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = NULL );
+ ULONG FindFocusWin(Window *pWin);
+ void SaveLRUEntry(const ScFuncDesc* pFuncDesc);
+ void HighlightFunctionParas(const String& aFormula);
+
+ BOOL IsInputHdl(ScInputHandler* pHdl);
+ ScInputHandler* GetNextInputHandler(ScDocShell* pDocShell,PtrTabViewShell* ppViewSh);
+};
+
+
+
+#endif // SC_CRNRDLG_HXX
+
diff --git a/sc/source/ui/inc/fuconarc.hxx b/sc/source/ui/inc/fuconarc.hxx
new file mode 100644
index 000000000000..686f2a00ae5b
--- /dev/null
+++ b/sc/source/ui/inc/fuconarc.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUCONARC_HXX
+#define SC_FUCONARC_HXX
+
+#include "fuconstr.hxx"
+
+/*************************************************************************
+|*
+|* Rechteck zeichnen
+|*
+\************************************************************************/
+
+class FuConstArc : public FuConstruct
+{
+ public:
+ FuConstArc( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuConstArc();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle);
+};
+
+
+
+#endif // _SD_FUCONARC_HXX
+
diff --git a/sc/source/ui/inc/fuconcustomshape.hxx b/sc/source/ui/inc/fuconcustomshape.hxx
new file mode 100644
index 000000000000..e6ecbfb2e2c3
--- /dev/null
+++ b/sc/source/ui/inc/fuconcustomshape.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUCONCUSTOMSHAPE_HXX
+#define SC_FUCONCUSTOMSHAPE_HXX
+
+#include "fuconstr.hxx"
+
+class FuConstCustomShape : public FuConstruct
+{
+ rtl::OUString aCustomShape;
+
+ void SetAttributes( SdrObject* pObj );
+
+public:
+ FuConstCustomShape(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuConstCustomShape();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject( const sal_uInt16 nID, const Rectangle& rRectangle );
+
+ // #i33136#
+ virtual bool doConstructOrthogonal() const;
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/fuconpol.hxx b/sc/source/ui/inc/fuconpol.hxx
new file mode 100644
index 000000000000..3a27ffcc2f69
--- /dev/null
+++ b/sc/source/ui/inc/fuconpol.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUCONPOL_HXX
+#define SC_FUCONPOL_HXX
+
+#include "fuconstr.hxx"
+
+/*************************************************************************
+|*
+|* Basisklasse fuer alle Funktionen
+|*
+\************************************************************************/
+
+class FuConstPolygon : public FuConstruct
+{
+ Point aLastPos;
+
+ public:
+ FuConstPolygon(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuConstPolygon();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle);
+};
+
+
+#endif // _FUCONPOL_HXX
+
diff --git a/sc/source/ui/inc/fuconrec.hxx b/sc/source/ui/inc/fuconrec.hxx
new file mode 100644
index 000000000000..fb609e4a7681
--- /dev/null
+++ b/sc/source/ui/inc/fuconrec.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUCONREC_HXX
+#define SC_FUCONREC_HXX
+
+#include "fuconstr.hxx"
+
+/*************************************************************************
+|*
+|* Rechteck zeichnen
+|*
+\************************************************************************/
+
+class FuConstRectangle : public FuConstruct
+{
+ public:
+ FuConstRectangle(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuConstRectangle();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle);
+};
+
+
+
+#endif // _SD_FUCONREC_HXX
+
diff --git a/sc/source/ui/inc/fuconstr.hxx b/sc/source/ui/inc/fuconstr.hxx
new file mode 100644
index 000000000000..28b20c7a94df
--- /dev/null
+++ b/sc/source/ui/inc/fuconstr.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUCONSTR_HXX
+#define SC_FUCONSTR_HXX
+
+#include "fudraw.hxx"
+
+
+/************************************************************************/
+
+#define MIN_FREEHAND_DISTANCE 10
+
+
+/*************************************************************************
+|*
+|* Rechteck zeichnen
+|*
+\************************************************************************/
+
+class FuConstruct : public FuDraw
+{
+ public:
+ FuConstruct(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuConstruct();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+ virtual BYTE Command(const CommandEvent& rCEvt);
+
+ BOOL SimpleMouseButtonUp(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+};
+
+
+
+#endif // _SD_FUCONSTR_HXX
diff --git a/sc/source/ui/inc/fuconuno.hxx b/sc/source/ui/inc/fuconuno.hxx
new file mode 100644
index 000000000000..ffe2c1e9722b
--- /dev/null
+++ b/sc/source/ui/inc/fuconuno.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUCONUNO_HXX
+#define SC_FUCONUNO_HXX
+
+#include "fuconstr.hxx"
+
+
+/*************************************************************************
+|*
+|* Control zeichnen
+|*
+\************************************************************************/
+
+class FuConstUnoControl : public FuConstruct
+{
+protected:
+ UINT32 nInventor;
+ UINT16 nIdentifier;
+
+public:
+ FuConstUnoControl(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuConstUnoControl();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle);
+};
+
+
+
+#endif // _SD_FUCONCTL_HXX
+
diff --git a/sc/source/ui/inc/fudraw.hxx b/sc/source/ui/inc/fudraw.hxx
new file mode 100644
index 000000000000..2344ca629c2f
--- /dev/null
+++ b/sc/source/ui/inc/fudraw.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUDRAW_HXX
+#define SC_FUDRAW_HXX
+
+#include "fupoor.hxx"
+#include <vcl/pointr.hxx>
+
+/*************************************************************************
+|*
+|* Basisklasse fuer alle Drawmodul-spezifischen Funktionen
+|*
+\************************************************************************/
+
+class FuDraw : public FuPoor
+{
+ protected:
+ Pointer aNewPointer;
+ Pointer aOldPointer;
+
+ public:
+ FuDraw(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuDraw();
+
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+
+ virtual void ScrollStart();
+ virtual void ScrollEnd();
+
+ virtual void Activate();
+ virtual void Deactivate();
+
+ virtual void ForcePointer(const MouseEvent* pMEvt);
+
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ // #97016# II
+ virtual void SelectionHasChanged();
+
+ BOOL IsSizingOrMovingNote( const MouseEvent& rMEvt ) const;
+
+ private:
+ void DoModifiers(const MouseEvent& rMEvt);
+ void ResetModifiers();
+};
+
+
+
+#endif // _SD_FUDRAW_HXX
diff --git a/sc/source/ui/inc/fuedipo.hxx b/sc/source/ui/inc/fuedipo.hxx
new file mode 100644
index 000000000000..5138a134cc2e
--- /dev/null
+++ b/sc/source/ui/inc/fuedipo.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUEDIPO_HXX
+#define SC_FUEDIPO_HXX
+
+#include "fudraw.hxx"
+
+
+/*************************************************************************
+|*
+|* Basisklasse fuer alle Funktionen
+|*
+\************************************************************************/
+
+class FuEditPoints : public FuDraw
+{
+ public:
+ FuEditPoints(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuEditPoints();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+};
+
+
+
+#endif // _SD_FUEDIPO_HXX
+
diff --git a/sc/source/ui/inc/fuinsert.hxx b/sc/source/ui/inc/fuinsert.hxx
new file mode 100644
index 000000000000..4dda7cb2b5ba
--- /dev/null
+++ b/sc/source/ui/inc/fuinsert.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_FUINSERT_HXX
+#define SC_FUINSERT_HXX
+
+#include "fupoor.hxx"
+
+class FuInsertGraphic : public FuPoor
+{
+ public:
+ FuInsertGraphic( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuInsertGraphic();
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+};
+
+/************************************************************************/
+
+class FuInsertOLE : public FuPoor
+{
+ public:
+ FuInsertOLE( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuInsertOLE();
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+};
+
+/************************************************************************/
+
+class FuInsertChart : public FuPoor
+{
+ public:
+ FuInsertChart( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuInsertChart();
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+};
+
+/************************************************************************/
+
+class FuInsertMedia : public FuPoor
+{
+ public:
+ FuInsertMedia( ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuInsertMedia();
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+};
+
+#endif // _SD_FUINSERT_HXX
+
diff --git a/sc/source/ui/inc/fumark.hxx b/sc/source/ui/inc/fumark.hxx
new file mode 100644
index 000000000000..fcadc54768e8
--- /dev/null
+++ b/sc/source/ui/inc/fumark.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUMARK_HXX
+#define SC_FUMARK_HXX
+
+#include "fupoor.hxx"
+#include "rangelst.hxx" // ScRangeListRef
+
+
+/*************************************************************************
+|*
+|* Funktion zum Aufziehen eines Rechtecks
+|*
+\************************************************************************/
+
+class FuMarkRect : public FuPoor
+{
+ protected:
+ Point aBeginPos;
+ Rectangle aZoomRect;
+ BOOL bVisible;
+ BOOL bStartDrag;
+ ScRangeListRef aSourceRange;
+
+ public:
+ FuMarkRect(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuMarkRect();
+
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+
+ virtual void ScrollStart();
+ virtual void ScrollEnd();
+
+ virtual void Activate();
+ virtual void Deactivate();
+
+ virtual void ForcePointer(const MouseEvent* pMEvt);
+
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+ virtual BYTE Command(const CommandEvent& rCEvt);
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/funcpage.hxx b/sc/source/ui/inc/funcpage.hxx
new file mode 100644
index 000000000000..d8b5c7796971
--- /dev/null
+++ b/sc/source/ui/inc/funcpage.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_FUNCPAGE_HXX
+#define SC_FUNCPAGE_HXX
+
+#include "funcutl.hxx"
+#include "global.hxx" // ScAddress
+#include <svtools/stdctrl.hxx>
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#include <vcl/group.hxx>
+#include <svtools/svmedit.hxx>
+#include <vcl/tabpage.hxx>
+
+#ifndef _SVSTDARR_STRINGS
+
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+
+#endif
+#include <vcl/tabctrl.hxx>
+#include "parawin.hxx"
+#include <svtools/svtreebx.hxx>
+#include "compiler.hxx"
+#include "cell.hxx"
+
+
+class ScViewData;
+class ScFuncName_Impl;
+class ScDocument;
+class ScFuncDesc;
+
+//============================================================================
+
+#define LRU_MAX 10
+
+//============================================================================
+class ScListBox : public ListBox
+{
+protected:
+
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+public:
+ ScListBox( Window* pParent, const ResId& rResId );
+};
+
+
+
+
+//============================================================================
+class ScFuncPage : public TabPage
+{
+private:
+
+ Link aDoubleClickLink;
+ Link aSelectionLink;
+ FixedText aFtCategory;
+ ListBox aLbCategory;
+ FixedText aFtFunction;
+ ScListBox aLbFunction;
+ ImageButton aIBFunction;
+
+ const ScFuncDesc* aLRUList[LRU_MAX];
+
+
+ DECL_LINK( SelHdl, ListBox* );
+ DECL_LINK( DblClkHdl, ListBox* );
+
+protected:
+
+ void UpdateFunctionList();
+ void InitLRUList();
+
+
+public:
+
+ ScFuncPage( Window* pParent);
+
+ void SetCategory(USHORT nCat);
+ void SetFunction(USHORT nFunc);
+ void SetFocus();
+ USHORT GetCategory();
+ USHORT GetFunction();
+ USHORT GetFunctionEntryCount();
+
+ USHORT GetFuncPos(const ScFuncDesc*);
+ const ScFuncDesc* GetFuncDesc( USHORT nPos ) const;
+ String GetSelFunctionName() const;
+
+ void SetDoubleClickHdl( const Link& rLink ) { aDoubleClickLink = rLink; }
+ const Link& GetDoubleClickHdl() const { return aDoubleClickLink; }
+
+ void SetSelectHdl( const Link& rLink ) { aSelectionLink = rLink; }
+ const Link& GetSelectHdl() const { return aSelectionLink; }
+
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/funcutl.hxx b/sc/source/ui/inc/funcutl.hxx
new file mode 100644
index 000000000000..715c9d36a101
--- /dev/null
+++ b/sc/source/ui/inc/funcutl.hxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUNCUTL_HXX
+#define SC_FUNCUTL_HXX
+
+#ifndef _SCRBAR_HXX //autogen
+#include <vcl/scrbar.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#include <svtools/svmedit.hxx>
+#include "anyrefdg.hxx" // formula::RefButton
+
+
+//============================================================================
+// class ValWnd
+
+class ValWnd : public Window
+{
+public:
+ ValWnd( Window* pParent, const ResId& rId );
+
+ void SetValue( const String& rStrVal );
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+
+private:
+ String aStrValue;
+ Rectangle aRectOut;
+};
+
+
+//============================================================================
+// class ScEditBox
+
+class ScEditBox : public Control
+{
+private:
+
+ MultiLineEdit* pMEdit;
+ Link aSelChangedLink;
+ Selection aOldSel;
+ BOOL bMouseFlag;
+ DECL_LINK( ChangedHdl, ScEditBox* );
+
+protected:
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void SelectionChanged();
+ virtual void Resize();
+ virtual void GetFocus();
+
+
+public:
+ ScEditBox( Window* pParent, const ResId& rResId );
+
+ ~ScEditBox();
+
+ MultiLineEdit* GetEdit() {return pMEdit;}
+
+ void SetSelChangedHdl( const Link& rLink ) { aSelChangedLink = rLink; }
+ const Link& GetSelChangedHdl() const { return aSelChangedLink; }
+
+ void UpdateOldSel();
+};
+
+
+
+//============================================================================
+// class ArgEdit
+
+class ArgEdit : public formula::RefEdit
+{
+public:
+ ArgEdit( Window* pParent, const ResId& rResId );
+
+ void Init( ArgEdit* pPrevEdit, ArgEdit* pNextEdit,
+ ScrollBar& rArgSlider, USHORT nArgCount );
+
+protected:
+ virtual void KeyInput( const KeyEvent& rKEvt );
+
+private:
+ ArgEdit* pEdPrev;
+ ArgEdit* pEdNext;
+ ScrollBar* pSlider;
+ USHORT nArgs;
+};
+
+
+//============================================================================
+// class ArgInput
+
+class ArgInput
+{
+private:
+
+ Link aFxClickLink;
+ Link aRefClickLink;
+ Link aFxFocusLink;
+ Link aRefFocusLink;
+ Link aEdFocusLink;
+ Link aEdModifyLink;
+
+ FixedText* pFtArg;
+ ImageButton* pBtnFx;
+ ArgEdit* pEdArg;
+ formula::RefButton* pRefBtn;
+
+ DECL_LINK( FxBtnClickHdl, ImageButton* );
+ DECL_LINK( RefBtnClickHdl,formula::RefButton* );
+ DECL_LINK( FxBtnFocusHdl, ImageButton* );
+ DECL_LINK( RefBtnFocusHdl,formula::RefButton* );
+ DECL_LINK( EdFocusHdl, ArgEdit* );
+ DECL_LINK( EdModifyHdl,ArgEdit* );
+
+protected:
+
+ virtual void FxClick();
+ virtual void RefClick();
+ virtual void FxFocus();
+ virtual void RefFocus();
+ virtual void EdFocus();
+ virtual void EdModify();
+
+public:
+
+ ArgInput();
+
+ void InitArgInput ( FixedText* pftArg,
+ ImageButton* pbtnFx,
+ ArgEdit* pedArg,
+ formula::RefButton* prefBtn);
+
+ void SetArgName(const String &aArg);
+ String GetArgName();
+ void SetArgNameFont(const Font&);
+
+ void SetArgVal(const String &aVal);
+ String GetArgVal();
+
+ void SetArgSelection (const Selection& rSel );
+
+ ArgEdit* GetArgEdPtr() {return pEdArg;}
+
+
+ void SetFxClickHdl( const Link& rLink ) { aFxClickLink = rLink; }
+ const Link& GetFxClickHdl() const { return aFxClickLink; }
+
+ void SetRefClickHdl( const Link& rLink ) { aRefClickLink = rLink; }
+ const Link& GetRefClickHdl() const { return aRefClickLink; }
+
+ void SetFxFocusHdl( const Link& rLink ) { aFxFocusLink = rLink; }
+ const Link& GetFxFocusHdl() const { return aFxFocusLink; }
+
+ void SetRefFocusHdl( const Link& rLink ) { aRefFocusLink = rLink; }
+ const Link& GetRefFocusHdl() const { return aRefFocusLink; }
+
+ void SetEdFocusHdl( const Link& rLink ) { aEdFocusLink = rLink; }
+ const Link& GetEdFocusHdl() const { return aEdFocusLink; }
+
+ void SetEdModifyHdl( const Link& rLink ) { aEdModifyLink = rLink; }
+ const Link& GetEdModifyHdl() const { return aEdModifyLink; }
+
+ void Hide();
+ void Show();
+
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/fupoor.hxx b/sc/source/ui/inc/fupoor.hxx
new file mode 100644
index 000000000000..6d9b7ae2af5a
--- /dev/null
+++ b/sc/source/ui/inc/fupoor.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SC_FUPOOR_HXX
+#define _SC_FUPOOR_HXX
+
+#include <vcl/event.hxx>
+#include <vcl/timer.hxx>
+#include <sfx2/request.hxx>
+
+class ScDrawView;
+class ScTabViewShell;
+class Window;
+class SdrModel;
+class Dialog;
+
+// #98185# Create default drawing objects via keyboard
+class SdrObject;
+
+// Return-Werte fuer Command
+#define SC_CMD_NONE 0
+#define SC_CMD_USED 1
+#define SC_CMD_IGNORE 2
+
+/*************************************************************************
+|*
+|* Basisklasse fuer alle Funktionen
+|*
+\************************************************************************/
+
+class FuPoor
+{
+protected:
+ ScDrawView* pView;
+ ScTabViewShell* pViewShell;
+ Window* pWindow;
+ SdrModel* pDrDoc;
+
+ SfxRequest aSfxRequest;
+ Dialog* pDialog;
+
+ Timer aScrollTimer; // fuer Autoscrolling
+ DECL_LINK( ScrollHdl, Timer * );
+ void ForceScroll(const Point& aPixPos);
+
+ Timer aDragTimer; // fuer Drag&Drop
+ DECL_LINK( DragTimerHdl, Timer * );
+ DECL_LINK( DragHdl, void * );
+ BOOL bIsInDragMode;
+ Point aMDPos; // Position von MouseButtonDown
+
+ // #95491# member to hold state of the mouse buttons for creation
+ // of own MouseEvents (like in ScrollHdl)
+private:
+ sal_uInt16 mnCode;
+
+public:
+ FuPoor(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+ virtual ~FuPoor();
+
+ // #95491# see member
+ void SetMouseButtonCode(sal_uInt16 nNew) { if(nNew != mnCode) mnCode = nNew; }
+ sal_uInt16 GetMouseButtonCode() const { return mnCode; }
+
+ virtual void Paint(const Rectangle&, Window*) {}
+
+ virtual void DoCut();
+ virtual void DoCopy();
+ virtual void DoPaste();
+
+ // Mouse- & Key-Events; Returnwert=TRUE: Event wurde bearbeitet
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent&) { return FALSE; }
+
+ // #95491# moved from inline to *.cxx
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt); // { return FALSE; }
+
+ // #95491# moved from inline to *.cxx
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt); // { return FALSE; }
+
+ virtual BYTE Command(const CommandEvent& rCEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ virtual void ScrollStart() {} // diese Funktionen werden von
+ virtual void ScrollEnd() {} // ForceScroll aufgerufen
+
+ void SetWindow(Window* pWin) { pWindow = pWin; }
+
+ USHORT GetSlotID() const { return( aSfxRequest.GetSlot() ); }
+
+ BOOL IsDetectiveHit( const Point& rLogicPos );
+
+ void StopDragTimer();
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle);
+
+protected:
+ void ImpForceQuadratic(Rectangle& rRect);
+
+public:
+ // #i33136#
+ virtual bool doConstructOrthogonal() const;
+};
+
+
+
+#endif // _SD_FUPOOR_HXX
+
diff --git a/sc/source/ui/inc/fusel.hxx b/sc/source/ui/inc/fusel.hxx
new file mode 100644
index 000000000000..c12b5739d61c
--- /dev/null
+++ b/sc/source/ui/inc/fusel.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUSEL_HXX
+#define SC_FUSEL_HXX
+
+#ifndef _SV_HXX
+#endif
+
+#include "fudraw.hxx"
+
+//class Outliner;
+//class OutlinerView;
+class SdrPageView;
+
+
+/*************************************************************************
+|*
+|* Basisklasse fuer alle Funktionen
+|*
+\************************************************************************/
+
+class FuSelection : public FuDraw
+{
+public:
+ FuSelection(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq );
+
+ virtual ~FuSelection();
+ // Mouse- & Key-Events
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+ virtual BYTE Command(const CommandEvent& rCEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ void ActivateNoteHandles(SdrObject* pObj);
+
+protected:
+// Outliner* pOutliner;
+// OutlinerView* pOutlinerView;
+ BOOL bVCAction;
+
+private:
+ BOOL TestDetective( SdrPageView* pPV, const Point& rPos ); // -> fusel2
+
+ bool IsNoteCaptionMarked() const;
+ bool IsNoteCaptionClicked( const Point& rPos ) const;
+};
+
+
+
+#endif // _SD_FUSEL_HXX
+
diff --git a/sc/source/ui/inc/futext.hxx b/sc/source/ui/inc/futext.hxx
new file mode 100644
index 000000000000..41a41b054554
--- /dev/null
+++ b/sc/source/ui/inc/futext.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUTEXT_HXX
+#define SC_FUTEXT_HXX
+
+#include "fuconstr.hxx"
+
+class SdrObject;
+class SdrTextObj;
+class SdrOutliner;
+
+/*************************************************************************
+|*
+|* Basisklasse fuer Textfunktionen
+|*
+\************************************************************************/
+class FuText : public FuConstruct
+{
+protected:
+// USHORT nOldObjectBar;
+ SdrTextObj* pTextObj;
+
+public:
+ FuText(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pView,
+ SdrModel* pDoc, SfxRequest& rReq);
+
+ virtual ~FuText();
+
+ virtual BOOL KeyInput(const KeyEvent& rKEvt);
+ virtual BOOL MouseMove(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
+ virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);
+
+ virtual void Activate(); // Function aktivieren
+ virtual void Deactivate(); // Function deaktivieren
+
+ virtual void ForcePointer(const MouseEvent* pMEvt);
+
+ virtual void SelectionHasChanged();
+
+ void SetInEditMode( SdrObject* pObj = NULL, const Point* pMousePixel = NULL,
+ BOOL bCursorToEnd = FALSE, const KeyEvent* pInitialKey = NULL );
+ void StopEditMode(BOOL bTextDirection = FALSE);
+ void StopDragMode(SdrObject* pObject);
+
+ // #98185# Create default drawing objects via keyboard
+ virtual SdrObject* CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle);
+
+private:
+ SdrOutliner* MakeOutliner();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/graphsh.hxx b/sc/source/ui/inc/graphsh.hxx
new file mode 100644
index 000000000000..db9d04096142
--- /dev/null
+++ b/sc/source/ui/inc/graphsh.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GRAPHSH_HXX
+#define GRAPHSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+
+class ScViewData;
+
+#include "drawsh.hxx"
+
+class ScGraphicShell: public ScDrawShell
+{
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_GRAPHIC_SHELL)
+
+ ScGraphicShell(ScViewData* pData);
+ virtual ~ScGraphicShell();
+
+ void Execute(SfxRequest& rReq);
+ void GetAttrState(SfxItemSet &rSet);
+
+ void ExecuteFilter(SfxRequest& rReq);
+ void GetFilterState(SfxItemSet &rSet);
+};
+
+#endif
diff --git a/sc/source/ui/inc/gridmerg.hxx b/sc/source/ui/inc/gridmerg.hxx
new file mode 100644
index 000000000000..dd656b948a6b
--- /dev/null
+++ b/sc/source/ui/inc/gridmerg.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_GRIDMERG_HXX
+#define SC_GRIDMERG_HXX
+
+#include <tools/solar.h>
+
+class OutputDevice;
+
+class ScGridMerger
+{
+private:
+ OutputDevice* pDev;
+ long nOneX;
+ long nOneY;
+ long nFixStart;
+ long nFixEnd;
+ long nVarStart;
+ long nVarDiff;
+ long nCount;
+ BOOL bVertical;
+ BOOL bOptimize;
+
+ void AddLine( long nStart, long nEnd, long nPos );
+
+public:
+ ScGridMerger( OutputDevice* pOutDev, long nOnePixelX, long nOnePixelY );
+ ~ScGridMerger();
+
+ void AddHorLine( long nX1, long nX2, long nY );
+ void AddVerLine( long nX, long nY1, long nY2 );
+ void Flush();
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
new file mode 100644
index 000000000000..a2283bf2b7de
--- /dev/null
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -0,0 +1,426 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_GRIDWIN_HXX
+#define SC_GRIDWIN_HXX
+
+#include <tools/string.hxx>
+#include <svtools/transfer.hxx>
+#include "viewutil.hxx"
+#include "viewdata.hxx"
+#include "cbutton.hxx"
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+#include <vector>
+#include <memory>
+#include <boost/shared_ptr.hpp>
+
+// ---------------------------------------------------------------------------
+
+struct ScTableInfo;
+class ScViewSelectionEngine;
+class ScDPObject;
+class ScDPFieldPopupWindow;
+class ScDPFieldButton;
+class ScOutputData;
+class ScFilterListBox;
+class AutoFilterPopup;
+class SdrObject;
+class SdrEditView;
+class ScNoteMarker;
+class FloatingWindow;
+class SdrHdlList;
+class ScTransferObj;
+struct SpellCallbackInfo;
+
+ // Maus-Status (nMouseStatus)
+
+#define SC_GM_NONE 0
+#define SC_GM_TABDOWN 1
+#define SC_GM_DBLDOWN 2
+#define SC_GM_FILTER 3
+#define SC_GM_IGNORE 4
+#define SC_GM_WATERUNDO 5
+#define SC_GM_URLDOWN 6
+
+ // Page-Drag-Modus
+
+#define SC_PD_NONE 0
+#define SC_PD_RANGE_L 1
+#define SC_PD_RANGE_R 2
+#define SC_PD_RANGE_T 4
+#define SC_PD_RANGE_B 8
+#define SC_PD_RANGE_TL (SC_PD_RANGE_T|SC_PD_RANGE_L)
+#define SC_PD_RANGE_TR (SC_PD_RANGE_T|SC_PD_RANGE_R)
+#define SC_PD_RANGE_BL (SC_PD_RANGE_B|SC_PD_RANGE_L)
+#define SC_PD_RANGE_BR (SC_PD_RANGE_B|SC_PD_RANGE_R)
+#define SC_PD_BREAK_H 16
+#define SC_PD_BREAK_V 32
+
+
+class ScHideTextCursor
+{
+private:
+ ScViewData* pViewData;
+ ScSplitPos eWhich;
+
+public:
+ ScHideTextCursor( ScViewData* pData, ScSplitPos eW );
+ ~ScHideTextCursor();
+};
+
+// ---------------------------------------------------------------------------
+// predefines
+namespace sdr { namespace overlay { class OverlayObjectList; }}
+
+class ScGridWindow : public Window, public DropTargetHelper, public DragSourceHelper
+{
+ // ScFilterListBox wird immer fuer Auswahlliste benutzt
+ friend class ScFilterListBox;
+
+private:
+ // #114409#
+ ::sdr::overlay::OverlayObjectList* mpOOCursors;
+ ::sdr::overlay::OverlayObjectList* mpOOSelection;
+ ::sdr::overlay::OverlayObjectList* mpOOAutoFill;
+ ::sdr::overlay::OverlayObjectList* mpOODragRect;
+ ::sdr::overlay::OverlayObjectList* mpOOHeader;
+ ::sdr::overlay::OverlayObjectList* mpOOShrink;
+
+ ::boost::shared_ptr<Rectangle> mpAutoFillRect;
+
+ /**
+ * Stores current visible column and row ranges, used to avoid expensive
+ * operations on objects that are outside visible area.
+ */
+ struct VisibleRange
+ {
+ SCCOL mnCol1;
+ SCCOL mnCol2;
+ SCROW mnRow1;
+ SCROW mnRow2;
+
+ VisibleRange();
+
+ bool isInside(SCCOL nCol, SCROW nRow) const;
+ };
+ VisibleRange maVisibleRange;
+
+private:
+ ScViewData* pViewData;
+ ScSplitPos eWhich;
+ ScHSplitPos eHWhich;
+ ScVSplitPos eVWhich;
+
+ ScNoteMarker* pNoteMarker;
+
+ ScFilterListBox* pFilterBox;
+ FloatingWindow* pFilterFloat;
+ ::std::auto_ptr<ScDPFieldPopupWindow> mpDPFieldPopup;
+ ::std::auto_ptr<ScDPFieldButton> mpFilterButton;
+
+ USHORT nCursorHideCount;
+
+ BOOL bMarking;
+
+ USHORT nButtonDown;
+ BOOL bEEMouse; // Edit-Engine hat Maus
+ BYTE nMouseStatus;
+ BYTE nNestedButtonState; // track nested button up/down calls
+
+ BOOL bDPMouse; // DataPilot-D&D (neue Pivottabellen)
+ long nDPField;
+ ScDPObject* pDragDPObj; //! name?
+
+ BOOL bRFMouse; // RangeFinder-Drag
+ BOOL bRFSize;
+ USHORT nRFIndex;
+ SCsCOL nRFAddX;
+ SCsROW nRFAddY;
+
+ USHORT nPagebreakMouse; // Pagebreak-Modus Drag
+ SCCOLROW nPagebreakBreak;
+ SCCOLROW nPagebreakPrev;
+ ScRange aPagebreakSource;
+ ScRange aPagebreakDrag;
+ BOOL bPagebreakDrawn;
+
+ BYTE nPageScript;
+
+ long nLastClickX;
+ long nLastClickY;
+
+ BOOL bDragRect;
+ SCCOL nDragStartX;
+ SCROW nDragStartY;
+ SCCOL nDragEndX;
+ SCROW nDragEndY;
+ InsCellCmd meDragInsertMode;
+
+ USHORT nCurrentPointer;
+
+ BOOL bIsInScroll;
+ BOOL bIsInPaint;
+
+ ScDDComboBoxButton aComboButton;
+
+ Point aCurMousePos;
+
+ USHORT nPaintCount;
+ Rectangle aRepaintPixel;
+ BOOL bNeedsRepaint;
+
+ BOOL bAutoMarkVisible;
+ ScAddress aAutoMarkPos;
+
+ BOOL bListValButton;
+ ScAddress aListValPos;
+
+ Rectangle aInvertRect;
+
+ DECL_LINK( PopupModeEndHdl, FloatingWindow* );
+ DECL_LINK( PopupSpellingHdl, SpellCallbackInfo* );
+
+ BOOL TestMouse( const MouseEvent& rMEvt, BOOL bAction );
+
+ BOOL DoPageFieldSelection( SCCOL nCol, SCROW nRow );
+ bool DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
+ void DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
+
+ void DPMouseMove( const MouseEvent& rMEvt );
+ void DPMouseButtonUp( const MouseEvent& rMEvt );
+ void DPTestMouse( const MouseEvent& rMEvt, BOOL bMove );
+
+ /**
+ * Check if the mouse click is on a field popup button.
+ *
+ * @return bool true if the field popup menu has been launched and no
+ * further mouse event handling is necessary, false otherwise.
+ */
+ bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj);
+ void DPLaunchFieldPopupMenu(
+ const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj);
+
+ void RFMouseMove( const MouseEvent& rMEvt, BOOL bUp );
+
+ void PagebreakMove( const MouseEvent& rMEvt, BOOL bUp );
+
+ void UpdateDragRect( BOOL bShowRange, const Rectangle& rPosRect );
+
+ BOOL IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab );
+ void ExecFilter( ULONG nSel, SCCOL nCol, SCROW nRow,
+ const String& aValue, bool bCheckForDates );
+ void FilterSelect( ULONG nSel );
+
+ void ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr );
+
+ void ExecPageFieldSelect( SCCOL nCol, SCROW nRow, BOOL bHasSelection, const String& rStr );
+
+ BOOL HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange );
+
+ BOOL DropScroll( const Point& rMousePos );
+
+ sal_Int8 AcceptPrivateDrop( const AcceptDropEvent& rEvt );
+ sal_Int8 ExecutePrivateDrop( const ExecuteDropEvent& rEvt );
+ sal_Int8 DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
+ const Point& rLogicPos, sal_Int8 nDndAction );
+
+ void HandleMouseButtonDown( const MouseEvent& rMEvt );
+
+ BOOL DrawMouseButtonDown(const MouseEvent& rMEvt);
+ BOOL DrawMouseButtonUp(const MouseEvent& rMEvt);
+ BOOL DrawMouseMove(const MouseEvent& rMEvt);
+ BOOL DrawKeyInput(const KeyEvent& rKEvt);
+ BOOL DrawCommand(const CommandEvent& rCEvt);
+ BOOL DrawHasMarkedObj();
+ void DrawEndAction();
+ void DrawMarkDropObj( SdrObject* pObj );
+ SdrObject* GetEditObject();
+ BOOL IsMyModel(SdrEditView* pSdrView);
+ //void DrawStartTimer();
+
+ void DrawRedraw( ScOutputData& rOutputData, ScUpdateMode eMode, ULONG nLayer );
+ void DrawSdrGrid( const Rectangle& rDrawingRect, OutputDevice* pContentDev );
+ //BOOL DrawBeforeScroll();
+ void DrawAfterScroll(/*BOOL bVal*/);
+ //void DrawMarks();
+ //BOOL NeedDrawMarks();
+ void DrawComboButton( const Point& rCellPos,
+ long nCellSizeX,
+ long nCellSizeY,
+ BOOL bArrowState,
+ BOOL bBtnIn = FALSE );
+ Rectangle GetListValButtonRect( const ScAddress& rButtonPos );
+
+ void DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, OutputDevice* pContentDev );
+
+ BOOL GetEditUrl( const Point& rPos,
+ String* pName=0, String* pUrl=0, String* pTarget=0 );
+ BOOL GetEditUrlOrError( BOOL bSpellErr, const Point& rPos,
+ String* pName=0, String* pUrl=0, String* pTarget=0 );
+
+ BOOL HitRangeFinder( const Point& rMouse, BOOL& rCorner, USHORT* pIndex = NULL,
+ SCsCOL* pAddX = NULL, SCsROW* pAddY = NULL );
+
+ USHORT HitPageBreak( const Point& rMouse, ScRange* pSource = NULL,
+ SCCOLROW* pBreak = NULL, SCCOLROW* pPrev = NULL );
+
+ void PasteSelection( const Point& rPosPixel );
+
+ void SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY );
+
+ void GetSelectionRects( ::std::vector< Rectangle >& rPixelRects );
+
+protected:
+ using Window::Resize;
+ virtual void Resize( const Size& rSize );
+ virtual void PrePaint();
+ virtual void Paint( const Rectangle& rRect );
+ virtual void KeyInput(const KeyEvent& rKEvt);
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ virtual void RequestHelp( const HelpEvent& rEvt );
+ virtual void Command( const CommandEvent& rCEvt );
+
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel );
+
+public:
+ ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos );
+ ~ScGridWindow();
+
+ // #i70788# flush and get overlay
+ ::sdr::overlay::OverlayManager* getOverlayManager();
+ void flushOverlayManager();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ void FakeButtonUp();
+
+ Point GetMousePosPixel() const;
+ void UpdateStatusPosSize();
+
+ void ClickExtern();
+
+ void SetPointer( const Pointer& rPointer );
+
+ void MoveMouseStatus( ScGridWindow &rDestWin );
+
+ void ScrollPixel( long nDifX, long nDifY );
+ void UpdateEditViewPos();
+
+ void UpdateFormulas();
+
+ void DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect );
+ void DoScenarioMenue( const ScRange& rScenRange );
+
+ void LaunchPageFieldMenu( SCCOL nCol, SCROW nRow );
+ void LaunchDPFieldMenu( SCCOL nCol, SCROW nRow );
+
+ ::com::sun::star::sheet::DataPilotFieldOrientation GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const;
+
+ void DrawButtons( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ ScTableInfo& rTabInfo, OutputDevice* pContentDev );
+
+ using Window::Draw;
+ void Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ ScUpdateMode eMode = SC_UPDATE_ALL );
+
+ void InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ BOOL bTestMerge = FALSE, BOOL bRepeat = FALSE );
+
+//UNUSED2008-05 void DrawDragRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 );
+
+ void CreateAnchorHandle(SdrHdlList& rHdl, const ScAddress& rAddress);
+
+ void HideCursor();
+ void ShowCursor();
+ void DrawCursor();
+ void DrawAutoFillMark();
+ void UpdateAutoFillMark(BOOL bMarked, const ScRange& rMarkRange);
+
+ void UpdateListValPos( BOOL bVisible, const ScAddress& rPos );
+
+ BOOL ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, BOOL bKeyboard );
+ void HideNoteMarker();
+
+ MapMode GetDrawMapMode( BOOL bForce = FALSE );
+
+ void ContinueDrag();
+
+ void StopMarking();
+ void UpdateInputContext();
+
+ void CheckInverted() { if (nPaintCount) bNeedsRepaint = TRUE; }
+
+ void DoInvertRect( const Rectangle& rPixel );
+
+ void CheckNeedsRepaint();
+
+ void UpdateDPFromFieldPopupMenu();
+
+ // #114409#
+ void CursorChanged();
+ void DrawLayerCreated();
+
+ void DeleteCursorOverlay();
+ void UpdateCursorOverlay();
+ void DeleteSelectionOverlay();
+ void UpdateSelectionOverlay();
+ void DeleteAutoFillOverlay();
+ void UpdateAutoFillOverlay();
+ void DeleteDragRectOverlay();
+ void UpdateDragRectOverlay();
+ void DeleteHeaderOverlay();
+ void UpdateHeaderOverlay();
+ void DeleteShrinkOverlay();
+ void UpdateShrinkOverlay();
+ void UpdateAllOverlays();
+
+protected:
+ // #114409#
+ void ImpCreateOverlayObjects();
+ void ImpDestroyOverlayObjects();
+
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/groupdlg.hxx b/sc/source/ui/inc/groupdlg.hxx
new file mode 100644
index 000000000000..38b96f21e90e
--- /dev/null
+++ b/sc/source/ui/inc/groupdlg.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_GROUPDLG_HXX
+#define SC_GROUPDLG_HXX
+
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+
+//------------------------------------------------------------------------
+
+class ScGroupDlg : public ModalDialog
+{
+public:
+ ScGroupDlg( Window* pParent,
+ USHORT nResId,
+ BOOL bUnGroup = FALSE,
+ BOOL bRows = TRUE );
+ ~ScGroupDlg();
+
+ BOOL GetColsChecked() const;
+
+private:
+ FixedLine aFlFrame;
+ RadioButton aBtnRows;
+ RadioButton aBtnCols;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+};
+
+
+#endif // SC_STRINDLG_HXX
+
+
diff --git a/sc/source/ui/inc/hdrcont.hxx b/sc/source/ui/inc/hdrcont.hxx
new file mode 100644
index 000000000000..ec4dd49705d1
--- /dev/null
+++ b/sc/source/ui/inc/hdrcont.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HDRCONT_HXX
+#define SC_HDRCONT_HXX
+
+#include <vcl/window.hxx>
+#ifndef _SELENG_HXX //autogen
+#include <vcl/seleng.hxx>
+#endif
+#include "address.hxx"
+
+// ---------------------------------------------------------------------------
+
+
+#define HDR_HORIZONTAL 0
+#define HDR_VERTICAL 1
+
+#define HDR_SIZE_OPTIMUM 0xFFFF
+
+
+ // Groesse des Sliders
+#define HDR_SLIDERSIZE 2
+
+class ScHeaderControl : public Window
+{
+private:
+ SelectionEngine* pSelEngine;
+ Font aNormFont;
+ Font aBoldFont;
+ BOOL bBoldSet;
+
+ USHORT nFlags;
+ BOOL bVertical; // Vertikal = Zeilenheader
+
+ long nWidth;
+ long nSmallWidth;
+ long nBigWidth;
+
+ SCCOLROW nSize;
+
+ SCCOLROW nMarkStart;
+ SCCOLROW nMarkEnd;
+ BOOL bMarkRange;
+
+ BOOL bDragging; // Groessen aendern
+ SCCOLROW nDragNo;
+ long nDragStart;
+ long nDragPos;
+ BOOL bDragMoved;
+
+ BOOL bIgnoreMove;
+
+ long GetScrPos( SCCOLROW nEntryNo );
+ SCCOLROW GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder );
+ bool IsSelectionAllowed(SCCOLROW nPos) const;
+ void ShowDragHelp();
+
+ void DoPaint( SCCOLROW nStart, SCCOLROW nEnd );
+
+ void DrawShadedRect( long nStart, long nEnd, const Color& rBaseColor );
+
+protected:
+ // von Window ueberladen
+
+ virtual void Paint( const Rectangle& rRect );
+
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+
+ virtual void RequestHelp( const HelpEvent& rHEvt );
+
+ // neue Methoden
+
+ virtual SCCOLROW GetPos() = 0; // aktuelle Position (Scrolling)
+ virtual USHORT GetEntrySize( SCCOLROW nEntryNo ) = 0; // Breite / Hoehe (Pixel)
+ virtual String GetEntryText( SCCOLROW nEntryNo ) = 0;
+
+ virtual SCCOLROW GetHiddenCount( SCCOLROW nEntryNo );
+ virtual BOOL IsLayoutRTL();
+ virtual BOOL IsMirrored();
+
+ virtual void SetEntrySize( SCCOLROW nPos, USHORT nNewWidth ) = 0;
+ virtual void HideEntries( SCCOLROW nStart, SCCOLROW nEnd ) = 0;
+
+ virtual void SetMarking( BOOL bSet );
+ virtual void SelectWindow();
+ virtual BOOL IsDisabled();
+ virtual BOOL ResizeAllowed();
+ virtual String GetDragHelp( long nVal );
+
+ virtual void DrawInvert( long nDragPos );
+ virtual void Command( const CommandEvent& rCEvt );
+
+public:
+ ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
+ SCCOLROW nNewSize, USHORT nNewFlags );
+ ~ScHeaderControl();
+
+ void SetIgnoreMove(BOOL bSet) { bIgnoreMove = bSet; }
+
+ void StopMarking();
+
+ void SetMark( BOOL bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd );
+
+ long GetWidth() const { return nWidth; }
+ long GetSmallWidth() const { return nSmallWidth; }
+ long GetBigWidth() const { return nBigWidth; }
+ void SetWidth( long nNew );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/hfedtdlg.hxx b/sc/source/ui/inc/hfedtdlg.hxx
new file mode 100644
index 000000000000..1f1ea7242b17
--- /dev/null
+++ b/sc/source/ui/inc/hfedtdlg.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HFEDTDLG_HXX
+#define SC_HFEDTDLG_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/pageitem.hxx>
+
+
+#include "sc.hrc"
+
+
+//==================================================================
+
+class ScHFEditDlg : public SfxTabDialog
+{
+ SvxNumType eNumType;
+public:
+ ScHFEditDlg( SfxViewFrame* pFrame,
+ Window* pParent,
+ const SfxItemSet& rCoreSet,
+ const String& rPageStyle,
+ USHORT nResId = RID_SCDLG_HFEDIT );
+
+ ~ScHFEditDlg();
+
+ virtual void PageCreated( USHORT nId, SfxTabPage& rPage );
+};
+
+
+#endif // SC_HFEDTDLG_HXX
diff --git a/sc/source/ui/inc/highred.hrc b/sc/source/ui/inc/highred.hrc
new file mode 100644
index 000000000000..426c9ba29ee2
--- /dev/null
+++ b/sc/source/ui/inc/highred.hrc
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> RID_SCDLG_CHANGES
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 5
+
+#define CB_HIGHLIGHT_ACCEPT 6
+#define CB_HIGHLIGHT_REJECT 7
+
+//
+#define FL_FILTER 10
+#define TP_FILTER 11
+#define TP_VIEW 12
+#define CB_HIGHLIGHT 13
+
+#define FT_ASSIGN 14
+#define ED_ASSIGN 15
+#define RB_ASSIGN 16
+
+
+
+
+
+
+
+#define STR_INSERT_COLS 20
+#define STR_INSERT_ROWS 21
+#define STR_INSERT_TABS 22
+#define STR_DELETE_COLS 23
+#define STR_DELETE_ROWS 24
+#define STR_DELETE_TABS 25
+#define STR_MOVE 26
+#define STR_CONTENT 27
+#define STR_REJECT 28
+
+// Bitmaps
+#define BMP_STR_CLOSE 31
+#define BMP_STR_OPEN 32
+#define BMP_STR_END 33
+#define BMP_STR_ERROR 34
+
+
+//
+
diff --git a/sc/source/ui/inc/highred.hxx b/sc/source/ui/inc/highred.hxx
new file mode 100644
index 000000000000..b500473b2071
--- /dev/null
+++ b/sc/source/ui/inc/highred.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HIGHRED_HXX
+#define SC_HIGHRED_HXX
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#include <svtools/headbar.hxx>
+#include <svtools/svtabbx.hxx>
+
+
+#include "rangenam.hxx"
+#include "anyrefdg.hxx"
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#include <vcl/lstbox.hxx>
+
+#ifndef _SVX_ACREDLIN_HXX
+#include <svx/ctredlin.hxx>
+#endif
+#include <svx/simptabl.hxx>
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+
+class ScViewData;
+class ScDocument;
+
+#ifndef FLT_DATE_BEFORE
+#define FLT_DATE_BEFORE 0
+#define FLT_DATE_SINCE 1
+#define FLT_DATE_EQUAL 2
+#define FLT_DATE_NOTEQUAL 3
+#define FLT_DATE_BETWEEN 4
+#define FLT_DATE_SAVE 5
+#endif
+
+//==================================================================
+
+class ScHighlightChgDlg : public ScAnyRefDlg
+{
+private:
+
+ CheckBox aHighlightBox;
+ FixedLine aFlFilter;
+ SvxTPFilter aFilterCtr;
+ CheckBox aCbAccept;
+ CheckBox aCbReject;
+
+ OKButton aOkButton;
+ CancelButton aCancelButton;
+ HelpButton aHelpButton;
+
+ formula::RefEdit aEdAssign;
+ formula::RefButton aRbAssign;
+
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ ScRangeName aLocalRangeName;
+ Selection theCurSel;
+ Size MinSize;
+ ScRangeList aRangeList;
+ ScChangeViewSettings aChangeViewSet;
+
+ void Init();
+
+ DECL_LINK( RefHandle, SvxTPFilter* );
+ DECL_LINK(HighLightHandle, CheckBox*);
+ DECL_LINK(OKBtnHdl, PushButton*);
+
+
+protected:
+
+ virtual void RefInputDone( BOOL bForced = FALSE );
+
+public:
+ ScHighlightChgDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData);
+
+ ~ScHighlightChgDlg();
+
+ virtual void SetActive();
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual BOOL Close();
+ virtual BOOL IsRefInputMode() const;
+
+};
+
+
+#endif // SC_NAMEDLG_HXX
+
diff --git a/sc/source/ui/inc/hintwin.hxx b/sc/source/ui/inc/hintwin.hxx
new file mode 100644
index 000000000000..2fd9e7897ab6
--- /dev/null
+++ b/sc/source/ui/inc/hintwin.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HINTWIN_HXX
+#define SC_HINTWIN_HXX
+
+#include <vcl/window.hxx>
+
+class ScHintWindow : public Window
+{
+private:
+ String aTitle;
+ String aMessage;
+ Point aTextStart;
+ long nTextHeight;
+ Font aTextFont;
+ Font aHeadFont;
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+
+public:
+ ScHintWindow( Window* pParent, const String& rTit, const String& rMsg );
+ ~ScHintWindow();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/hiranges.hxx b/sc/source/ui/inc/hiranges.hxx
new file mode 100644
index 000000000000..6182d30dc96e
--- /dev/null
+++ b/sc/source/ui/inc/hiranges.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HIRANGES_HXX
+#define SC_HIRANGES_HXX
+
+#include <tools/color.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+//==================================================================
+
+struct ScHighlightEntry
+{
+ ScRange aRef;
+ Color aColor;
+
+ ScHighlightEntry( const ScRange& rR, const Color& rC ) :
+ aRef(rR), aColor(rC) {}
+};
+
+class ScHighlightRanges
+{
+ List aEntries;
+
+public:
+ ScHighlightRanges();
+ ~ScHighlightRanges();
+
+ ULONG Count() const { return aEntries.Count(); }
+ void Insert( ScHighlightEntry* pNew ) { aEntries.Insert(pNew, LIST_APPEND); }
+ ScHighlightEntry* GetObject( ULONG nIndex ) const
+ { return (ScHighlightEntry*)aEntries.GetObject(nIndex); }
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/imoptdlg.hxx b/sc/source/ui/inc/imoptdlg.hxx
new file mode 100644
index 000000000000..01e10f9a3983
--- /dev/null
+++ b/sc/source/ui/inc/imoptdlg.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_IMOPTDLG_HXX
+#define SC_IMOPTDLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/imagebtn.hxx>
+#include <svx/txencbox.hxx>
+#include "scdllapi.h"
+#include "global.hxx"
+
+//===================================================================
+
+class SC_DLLPUBLIC ScImportOptions
+{
+public:
+ ScImportOptions()
+ : nFieldSepCode(0), nTextSepCode(0),
+ eCharSet(RTL_TEXTENCODING_DONTKNOW), bFixedWidth(FALSE),
+ bSaveAsShown(FALSE)
+ {}
+ ScImportOptions( const String& rStr );
+
+ ScImportOptions( sal_Unicode nFieldSep, sal_Unicode nTextSep, const String& rStr )
+ : nFieldSepCode(nFieldSep), nTextSepCode(nTextSep), aStrFont(rStr),
+ bFixedWidth(FALSE), bSaveAsShown(FALSE)
+ { eCharSet = ScGlobal::GetCharsetValue(aStrFont); }
+
+ ScImportOptions( sal_Unicode nFieldSep, sal_Unicode nTextSep, rtl_TextEncoding nEnc )
+ : nFieldSepCode(nFieldSep), nTextSepCode(nTextSep),
+ bFixedWidth(FALSE), bSaveAsShown(FALSE)
+ { SetTextEncoding( nEnc ); }
+
+ ScImportOptions( const ScImportOptions& rCpy )
+ : nFieldSepCode (rCpy.nFieldSepCode),
+ nTextSepCode (rCpy.nTextSepCode),
+ aStrFont (rCpy.aStrFont),
+ eCharSet (rCpy.eCharSet),
+ bFixedWidth (rCpy.bFixedWidth),
+ bSaveAsShown (rCpy.bSaveAsShown)
+ {}
+
+ ScImportOptions& operator=( const ScImportOptions& rCpy )
+ {
+ nFieldSepCode = rCpy.nFieldSepCode;
+ nTextSepCode = rCpy.nTextSepCode;
+ aStrFont = rCpy.aStrFont;
+ eCharSet = rCpy.eCharSet;
+ bFixedWidth = rCpy.bFixedWidth;
+ bSaveAsShown = rCpy.bSaveAsShown;
+ return *this;
+ }
+
+ BOOL operator==( const ScImportOptions& rCmp )
+ {
+ return
+ nFieldSepCode == rCmp.nFieldSepCode
+ && nTextSepCode == rCmp.nTextSepCode
+ && eCharSet == rCmp.eCharSet
+ && aStrFont == rCmp.aStrFont
+ && bFixedWidth == rCmp.bFixedWidth
+ && bSaveAsShown == rCmp.bSaveAsShown;
+ }
+ String BuildString() const;
+
+ void SetTextEncoding( rtl_TextEncoding nEnc );
+
+ sal_Unicode nFieldSepCode;
+ sal_Unicode nTextSepCode;
+ String aStrFont;
+ CharSet eCharSet;
+ BOOL bFixedWidth;
+ BOOL bSaveAsShown;
+};
+
+
+#endif // SC_IMOPTDLG_HXX
+
+
+
diff --git a/sc/source/ui/inc/impex.hxx b/sc/source/ui/inc/impex.hxx
new file mode 100644
index 000000000000..86a91216edcc
--- /dev/null
+++ b/sc/source/ui/inc/impex.hxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_IMPEX_HXX
+#define SC_IMPEX_HXX
+
+#include <osl/endian.h>
+#include <sot/exchange.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+class ScDocShell;
+class ScDocument;
+class SvStream;
+class SfxMedium;
+class ScAsciiOptions;
+
+struct ScExportTextOptions
+{
+ enum NewlineConversion { ToSystem, ToSpace, None };
+ ScExportTextOptions( NewlineConversion eNewlineConversion = ToSystem, sal_Unicode cSeparatorConvertTo = 0, bool bAddQuotes = false ) :
+ meNewlineConversion( eNewlineConversion ), mcSeparatorConvertTo( cSeparatorConvertTo ), mbAddQuotes( bAddQuotes ) {}
+
+ NewlineConversion meNewlineConversion;
+ sal_Unicode mcSeparatorConvertTo; // Convert separator to this character
+ bool mbAddQuotes;
+};
+
+class ScImportExport
+{
+ ScDocShell* pDocSh;
+ ScDocument* pDoc;
+ ScDocument* pUndoDoc;
+ ScRange aRange;
+ String aStreamPath;
+ String aNonConvertibleChars;
+ ULONG nSizeLimit;
+ sal_Unicode cSep; // Separator
+ sal_Unicode cStr; // String Delimiter
+ BOOL bFormulas; // Formeln im Text?
+ BOOL bIncludeFiltered; // include filtered rows? (default true)
+ BOOL bAll; // keine Selektion
+ BOOL bSingle; // Einfachselektion
+ BOOL bUndo; // Mit Undo?
+ BOOL bOverflow; // zuviele Zeilen/Spalten
+ bool mbApi;
+ ScExportTextOptions mExportTextOptions;
+
+ ScAsciiOptions* pExtOptions; // erweiterte Optionen
+
+ BOOL StartPaste(); // Protect-Check, Undo einrichten
+ void EndPaste(); // Undo/Redo-Aktionen, Repaint
+ BOOL Doc2Text( SvStream& );
+ BOOL Text2Doc( SvStream& );
+ BOOL Doc2Sylk( SvStream& );
+ BOOL Sylk2Doc( SvStream& );
+ BOOL Doc2HTML( SvStream&, const String& );
+ BOOL Doc2RTF( SvStream& );
+ BOOL Doc2Dif( SvStream& );
+ BOOL Dif2Doc( SvStream& );
+ BOOL ExtText2Doc( SvStream& ); // mit pExtOptions
+ BOOL RTF2Doc( SvStream&, const String& rBaseURL );
+ BOOL HTML2Doc( SvStream&, const String& rBaseURL );
+
+public:
+ ScImportExport( ScDocument* ); // Gesamtdokument
+ ScImportExport( ScDocument*, const String& ); // Bereichs/Zellangabe
+ ScImportExport( ScDocument*, const ScAddress& );
+ ScImportExport( ScDocument*, const ScRange& );
+ ~ScImportExport();
+
+ void SetExtOptions( const ScAsciiOptions& rOpt );
+
+ BOOL IsDoubleRef() const { return BOOL( !( bAll || bSingle ) ); }
+ BOOL IsSingleRef() const { return bSingle; }
+ BOOL IsNoRef() const { return bAll; }
+ BOOL IsRef() const { return BOOL( !bAll ); }
+
+ const ScRange& GetRange() const { return aRange; }
+
+ BOOL IsUndo() const { return bUndo; }
+ void SetUndo( BOOL b ) { bUndo = b; }
+
+ static BOOL IsFormatSupported( ULONG nFormat );
+ static const sal_Unicode* ScanNextFieldFromString( const sal_Unicode* p,
+ String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted );
+ static void WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, BOOL bZero = FALSE );
+ static void WriteUnicodeOrByteEndl( SvStream& rStrm );
+ static inline BOOL IsEndianSwap( const SvStream& rStrm );
+
+ //! only if stream is only used in own (!) memory
+ static inline void SetNoEndianSwap( SvStream& rStrm );
+
+ sal_Unicode GetSeparator() const { return cSep; }
+ void SetSeparator( sal_Unicode c ) { cSep = c; }
+ sal_Unicode GetDelimiter() const { return cStr; }
+ void SetDelimiter( sal_Unicode c ) { cStr = c; }
+ BOOL IsFormulas() const { return bFormulas; }
+ void SetFormulas( BOOL b ) { bFormulas = b; }
+ BOOL IsIncludeFiltered() const { return bIncludeFiltered; }
+ void SetIncludeFiltered( BOOL b ) { bIncludeFiltered = b; }
+
+ void SetSizeLimit( ULONG nNew ) { nSizeLimit = nNew; } // momentan nur fuer Ascii
+
+ void SetStreamPath( const String& rPath ) { aStreamPath = rPath; }
+ const String& GetStreamPath() const { return aStreamPath; }
+
+ BOOL ImportString( const ::rtl::OUString&, ULONG=FORMAT_STRING );
+ BOOL ExportString( ::rtl::OUString&, ULONG=FORMAT_STRING );
+ BOOL ExportByteString( ByteString&, rtl_TextEncoding, ULONG=FORMAT_STRING );
+
+ BOOL ImportStream( SvStream&, const String& rBaseURL, ULONG=FORMAT_STRING );
+ BOOL ExportStream( SvStream&, const String& rBaseURL, ULONG=FORMAT_STRING );
+
+ BOOL ImportData( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue );
+ BOOL ExportData( const String& rMimeType,
+ ::com::sun::star::uno::Any & rValue );
+
+ BOOL IsOverflow() const { return bOverflow; } // nach dem Importieren
+
+ const String& GetNonConvertibleChars() const { return aNonConvertibleChars; }
+
+ bool IsApi() const { return mbApi; }
+ void SetApi( bool bApi ) { mbApi = bApi; }
+ const ScExportTextOptions& GetExportTextOptions() { return mExportTextOptions; }
+ void SetExportTextOptions( const ScExportTextOptions& options ) { mExportTextOptions = options; }
+};
+
+
+// static
+inline BOOL ScImportExport::IsEndianSwap( const SvStream& rStrm )
+{
+#ifdef OSL_BIGENDIAN
+ return rStrm.GetNumberFormatInt() != NUMBERFORMAT_INT_BIGENDIAN;
+#else
+ return rStrm.GetNumberFormatInt() != NUMBERFORMAT_INT_LITTLEENDIAN;
+#endif
+}
+
+// static
+inline void ScImportExport::SetNoEndianSwap( SvStream& rStrm )
+{
+#ifdef OSL_BIGENDIAN
+ rStrm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+#else
+ rStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+#endif
+}
+
+
+// Helper class for importing clipboard strings as streams.
+class ScImportStringStream : public SvMemoryStream
+{
+public:
+ ScImportStringStream( const ::rtl::OUString rStr )
+ : SvMemoryStream( (void*)rStr.getStr(),
+ rStr.getLength() * sizeof(sal_Unicode), STREAM_READ)
+ {
+ SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
+ SetEndianSwap( FALSE );
+ }
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
new file mode 100644
index 000000000000..61974cf7464d
--- /dev/null
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -0,0 +1,296 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_INPUTHDL_HXX
+#define SC_INPUTHDL_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include <tools/fract.hxx>
+#include <tools/gen.hxx>
+#include <editeng/svxenum.hxx>
+
+class ScDocument;
+class ScTabView;
+class ScTabViewShell;
+class ScInputWindow;
+class ScPatternAttr;
+class EditEngine;
+class ScEditEngineDefaulter;
+class EditView;
+class EditTextObject;
+class ScInputHdlState;
+class TypedScStrCollection;
+class ScRangeFindList;
+class Timer;
+class KeyEvent;
+class CommandEvent;
+
+struct ESelection;
+
+//========================================================================
+// ScInputHandler
+//========================================================================
+
+class ScInputHandler
+{
+private:
+ ScInputWindow* pInputWin;
+
+ ScEditEngineDefaulter* pEngine; // editierte Daten in der Tabelle
+ EditView* pTableView; // aktive EditView dazu
+ EditView* pTopView; // EditView in der Eingabezeile
+
+ TypedScStrCollection* pColumnData;
+ TypedScStrCollection* pFormulaData;
+ TypedScStrCollection* pFormulaDataPara;
+ Window* pTipVisibleParent;
+ ULONG nTipVisible;
+ Window* pTipVisibleSecParent;
+ ULONG nTipVisibleSec;
+ String aManualTip;
+ String aAutoSearch;
+ USHORT nAutoPos;
+ BOOL bUseTab; // Blaettern moeglich
+
+ BOOL bTextValid; // Text noch nicht in Edit-Engine
+ String aCurrentText;
+
+ String aFormText; // fuer Funktions-Autopilot
+ xub_StrLen nFormSelStart; // Selektion fuer Funktions-Autopilot
+ xub_StrLen nFormSelEnd;
+
+ USHORT nAutoPar; // autom.parentheses than can be overwritten
+
+ ScAddress aCursorPos;
+ ScInputMode eMode;
+ BOOL bModified;
+ BOOL bSelIsRef;
+ BOOL bFormulaMode;
+ BOOL bInRangeUpdate;
+ BOOL bParenthesisShown;
+ BOOL bCreatingFuncView;
+ BOOL bInEnterHandler;
+ BOOL bCommandErrorShown;
+ BOOL bInOwnChange;
+
+ BOOL bProtected;
+ BOOL bCellHasPercentFormat;
+ ULONG nValidation;
+ SvxCellHorJustify eAttrAdjust;
+
+ Fraction aScaleX; // fuer Ref-MapMode
+ Fraction aScaleY;
+
+ ScTabViewShell* pRefViewSh;
+ ScTabViewShell* pActiveViewSh;
+
+ const ScPatternAttr* pLastPattern;
+ SfxItemSet* pEditDefaults;
+ BOOL bLastIsSymbol;
+
+ ScInputHdlState* pLastState;
+ Timer* pDelayTimer;
+
+ ScRangeFindList* pRangeFindList;
+
+ static BOOL bAutoComplete; // aus App-Optionen
+ static BOOL bOptLoaded;
+
+#ifdef _INPUTHDL_CXX
+private:
+ void UpdateActiveView();
+ void SyncViews( EditView* pSourceView = NULL );
+ BOOL StartTable( sal_Unicode cTyped, BOOL bFromCommand );
+ void RemoveSelection();
+ void UpdateFormulaMode();
+ void InvalidateAttribs();
+ void ImplCreateEditEngine();
+ DECL_LINK( DelayTimer, Timer* );
+ void GetColData();
+ void UseColData();
+ void NextAutoEntry( BOOL bBack );
+ void UpdateAdjust( sal_Unicode cTyped );
+ void GetFormulaData();
+ void UseFormulaData();
+ void NextFormulaEntry( BOOL bBack );
+ void PasteFunctionData();
+ void PasteManualTip();
+ EditView* GetFuncEditView();
+ void RemoveAdjust();
+ void RemoveRangeFinder();
+ void DeleteRangeFinder();
+ void UpdateParenthesis();
+ void UpdateAutoCorrFlag();
+ void ResetAutoPar();
+ void AutoParAdded();
+ BOOL CursorAtClosingPar();
+ void SkipClosingPar();
+ DECL_LINK( ModifyHdl, void* );
+ DECL_LINK( ShowHideTipVisibleParentListener, VclWindowEvent* );
+ DECL_LINK( ShowHideTipVisibleSecParentListener, VclWindowEvent* );
+#endif
+
+public:
+ ScInputHandler();
+ virtual ~ScInputHandler();
+
+ void SetMode( ScInputMode eNewMode );
+ BOOL IsInputMode() const { return (eMode != SC_INPUT_NONE); }
+ BOOL IsEditMode() const { return (eMode != SC_INPUT_NONE &&
+ eMode != SC_INPUT_TYPE); }
+ BOOL IsTopMode() const { return (eMode == SC_INPUT_TOP); }
+
+ const String& GetEditString();
+ const String& GetFormString() const { return aFormText; }
+
+ BOOL GetTextAndFields( ScEditEngineDefaulter& rDestEngine );
+
+ BOOL KeyInput( const KeyEvent& rKEvt, BOOL bStartEdit = FALSE );
+ void EnterHandler( BYTE nBlockMode = 0 );
+ void CancelHandler();
+ void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ void AddRefEntry();
+
+ BOOL InputCommand( const CommandEvent& rCEvt, BOOL bForce );
+
+ void InsertFunction( const String& rFuncName, BOOL bAddPar = TRUE );
+ void ClearText();
+
+ void InputSelection( EditView* pView );
+ void InputChanged( EditView* pView, BOOL bFromNotify = FALSE );
+
+ void ViewShellGone(ScTabViewShell* pViewSh);
+ void SetRefViewShell(ScTabViewShell* pRefVsh) {pRefViewSh=pRefVsh;}
+
+
+ void NotifyChange( const ScInputHdlState* pState, BOOL bForce = FALSE,
+ ScTabViewShell* pSourceSh = NULL,
+ BOOL bStopEditing = TRUE);
+ void UpdateCellAdjust( SvxCellHorJustify eJust );
+
+ void ResetDelayTimer(); //BugId 54702
+
+ void HideTip();
+ void HideTipBelow();
+ void ShowTipCursor();
+ void ShowTip( const String& rText ); // am Cursor
+ void ShowTipBelow( const String& rText );
+
+ void SetRefScale( const Fraction& rX, const Fraction& rY );
+ void UpdateRefDevice();
+
+ EditView* GetActiveView();
+ EditView* GetTableView() { return pTableView; }
+ EditView* GetTopView() { return pTopView; }
+
+ BOOL DataChanging( sal_Unicode cTyped = 0, BOOL bFromCommand = FALSE );
+ void DataChanged( BOOL bFromTopNotify = FALSE );
+
+ BOOL TakesReturn() const { return ( nTipVisible != 0 ); }
+
+ void SetModified() { bModified = TRUE; }
+
+ BOOL GetSelIsRef() const { return bSelIsRef; }
+ void SetSelIsRef(BOOL bSet) { bSelIsRef = bSet; }
+
+ void ShowRefFrame();
+
+ ScRangeFindList* GetRangeFindList() { return pRangeFindList; }
+
+ void UpdateRange( USHORT nIndex, const ScRange& rNew );
+
+ // Kommunikation mit Funktionsautopilot
+ void InputGetSelection ( xub_StrLen& rStart, xub_StrLen& rEnd );
+ void InputSetSelection ( xub_StrLen nStart, xub_StrLen nEnd );
+ void InputReplaceSelection ( const String& rStr );
+ String InputGetFormulaStr ();
+
+ BOOL IsFormulaMode() const { return bFormulaMode; }
+ ScInputWindow* GetInputWindow() { return pInputWin; }
+ void SetInputWindow( ScInputWindow* pNew ) { pInputWin = pNew; }
+ void StopInputWinEngine( BOOL bAll );
+
+ BOOL IsInEnterHandler() const { return bInEnterHandler; }
+ BOOL IsInOwnChange() const { return bInOwnChange; }
+
+ BOOL IsModalMode( SfxObjectShell* pDocSh );
+
+ void ForgetLastPattern();
+
+ void UpdateSpellSettings( BOOL bFromStartTab = FALSE );
+
+ void FormulaPreview();
+
+ Size GetTextSize(); // in 1/100mm
+
+ // eigentlich private, fuer SID_INPUT_SUM public
+ void InitRangeFinder( const String& rFormula );
+
+ static void SetAutoComplete(BOOL bSet) { bAutoComplete = bSet; }
+};
+
+//========================================================================
+// ScInputHdlState
+//========================================================================
+class ScInputHdlState
+{
+ friend class ScInputHandler;
+
+public:
+ ScInputHdlState( const ScAddress& rCurPos,
+ const ScAddress& rStartPos,
+ const ScAddress& rEndPos,
+ const String& rString,
+ const EditTextObject* pData );
+ ScInputHdlState( const ScInputHdlState& rCpy );
+ ~ScInputHdlState();
+
+ ScInputHdlState& operator= ( const ScInputHdlState& r );
+ int operator==( const ScInputHdlState& r ) const;
+ int operator!=( const ScInputHdlState& r ) const
+ { return !operator==( r ); }
+
+ const ScAddress& GetPos() const { return aCursorPos; }
+ const ScAddress& GetStartPos() const { return aStartPos; }
+ const ScAddress& GetEndPos() const { return aEndPos; }
+ const String& GetString() const { return aString; }
+ const EditTextObject* GetEditData() const { return pEditData; }
+
+private:
+ ScAddress aCursorPos;
+ ScAddress aStartPos;
+ ScAddress aEndPos;
+ String aString;
+ EditTextObject* pEditData;
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/inputwin.hxx b/sc/source/ui/inc/inputwin.hxx
new file mode 100644
index 000000000000..236d34a8254f
--- /dev/null
+++ b/sc/source/ui/inc/inputwin.hxx
@@ -0,0 +1,228 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_INPUTWIN_HXX
+#define SC_INPUTWIN_HXX
+
+#include <vector>
+#include <vcl/toolbox.hxx>
+#include <sfx2/childwin.hxx>
+#include <svl/lstner.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/window.hxx>
+#include <svtools/transfer.hxx>
+
+class ScEditEngineDefaulter;
+class EditView;
+struct ESelection;
+class ScInputHandler;
+class ScAccessibleEditLineTextData;
+struct EENotify;
+class ScRangeList;
+
+//========================================================================
+
+class ScTextWnd : public Window, public DragSourceHelper // edit window
+{
+public:
+ ScTextWnd( Window* pParent );
+ virtual ~ScTextWnd();
+
+ void SetTextString( const String& rString );
+ const String& GetTextString() const;
+
+ BOOL IsInputActive();
+ EditView* GetEditView();
+
+ // fuer FunktionsAutopiloten
+ void MakeDialogEditView();
+
+ void StartEditEngine();
+ void StopEditEngine( BOOL bAll );
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ void SetFormulaMode( BOOL bSet );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ void InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData );
+ void RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData );
+
+ DECL_LINK( NotifyHdl, EENotify* );
+
+protected:
+ virtual void Paint( const Rectangle& rRec );
+ virtual void Resize();
+
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void KeyInput(const KeyEvent& rKEvt);
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel );
+
+ virtual String GetText() const;
+
+private:
+ void ImplInitSettings();
+ void UpdateAutoCorrFlag();
+
+private:
+ typedef ::std::vector< ScAccessibleEditLineTextData* > AccTextDataVector;
+
+ String aString;
+ Font aTextFont;
+ ScEditEngineDefaulter* pEditEngine; // erst bei Bedarf angelegt
+ EditView* pEditView;
+ AccTextDataVector maAccTextDatas; // #i105267# text datas may be cloned, remember all copies
+ BOOL bIsRTL;
+ BOOL bIsInsertMode;
+ BOOL bFormulaMode;
+
+ // #102710#; this flag should be true if a key input or a command is handled
+ // it prevents the call of InputChanged in the ModifyHandler of the EditEngine
+ BOOL bInputMode;
+};
+
+//========================================================================
+
+class ScPosWnd : public ComboBox, public SfxListener // Positionsanzeige
+{
+private:
+ String aPosStr;
+ Accelerator* pAccel;
+ ULONG nTipVisible;
+ BOOL bFormulaMode;
+ BOOL bTopHadFocus;
+
+public:
+ ScPosWnd( Window* pParent );
+ virtual ~ScPosWnd();
+
+ void SetPos( const String& rPosStr ); // angezeigter Text
+ void SetFormulaMode( BOOL bSet );
+
+protected:
+ virtual void Select();
+ virtual void Modify();
+
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+private:
+ void FillRangeNames();
+ void FillFunctions();
+ void DoEnter();
+ void HideTip();
+
+ void ReleaseFocus_Impl();
+};
+
+//========================================================================
+
+class ScInputWindow : public ToolBox // Parent-Toolbox
+{
+public:
+ ScInputWindow( Window* pParent, SfxBindings* pBind );
+ virtual ~ScInputWindow();
+
+ virtual void Resize();
+ virtual void Select();
+
+ void SetFuncString( const String& rString, BOOL bDoEdit = TRUE );
+ void SetPosString( const String& rStr );
+ void SetTextString( const String& rString );
+
+ void SetOkCancelMode();
+ void SetSumAssignMode();
+ void EnableButtons( BOOL bEnable = TRUE );
+
+ void SetFormulaMode( BOOL bSet );
+
+ BOOL IsInputActive();
+ EditView* GetEditView();
+//UNUSED2008-05 EditView* ActivateEdit( const String& rText,
+//UNUSED2008-05 const ESelection& rSel );
+
+ void TextGrabFocus();
+ void TextInvalidate();
+ void SwitchToTextWin();
+
+ void PosGrabFocus();
+
+ // Fuer FunktionsAutopiloten
+ void MakeDialogEditView();
+
+ void StopEditEngine( BOOL bAll );
+
+ void SetInputHandler( ScInputHandler* pNew );
+
+ ScInputHandler* GetInputHandler(){ return pInputHdl;}
+
+ void StateChanged( StateChangedType nType );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+
+protected:
+ virtual void SetText( const String& rString );
+ virtual String GetText() const;
+
+ sal_Bool UseSubTotal( ScRangeList* pRangeList ) const;
+
+private:
+ ScPosWnd aWndPos;
+ ScTextWnd aTextWindow;
+ ScInputHandler* pInputHdl;
+ SfxBindings* pBindings;
+ String aTextOk;
+ String aTextCancel;
+ String aTextSum;
+ String aTextEqual;
+ BOOL bIsOkCancelMode;
+};
+
+//==================================================================
+
+class ScInputWindowWrapper : public SfxChildWindow
+{
+public:
+ ScInputWindowWrapper( Window* pParent,
+ USHORT nId,
+ SfxBindings* pBindings,
+ SfxChildWinInfo* pInfo );
+
+ SFX_DECL_CHILDWINDOW(ScInputWindowWrapper);
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/inscldlg.hxx b/sc/source/ui/inc/inscldlg.hxx
new file mode 100644
index 000000000000..fd8c090cfd33
--- /dev/null
+++ b/sc/source/ui/inc/inscldlg.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_INSCLDLG_HXX
+#define SC_INSCLDLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+
+
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+
+class ScInsertCellDlg : public ModalDialog
+{
+private:
+ FixedLine aFlFrame;
+ RadioButton aBtnCellsDown;
+ RadioButton aBtnCellsRight;
+ RadioButton aBtnInsRows;
+ RadioButton aBtnInsCols;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+public:
+ ScInsertCellDlg( Window* pParent,BOOL bDisallowCellMove = FALSE );
+ ~ScInsertCellDlg();
+
+ InsCellCmd GetInsCellCmd() const;
+};
+
+
+#endif // SC_INSCLDLG_HXX
+
+
diff --git a/sc/source/ui/inc/inscodlg.hxx b/sc/source/ui/inc/inscodlg.hxx
new file mode 100644
index 000000000000..ffdccaba6a10
--- /dev/null
+++ b/sc/source/ui/inc/inscodlg.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_INSCODLG_HXX
+#define SC_INSCODLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+//CHINA001 #define INS_CONT_NOEMPTY 0x0100
+//CHINA001 #define INS_CONT_TRANS 0x0200
+//CHINA001 #define INS_CONT_LINK 0x0400
+//CHINA001
+//CHINA001 #define SC_CELL_SHIFT_DISABLE_DOWN 0x01
+//CHINA001 #define SC_CELL_SHIFT_DISABLE_RIGHT 0x02
+#include "scui_def.hxx"
+
+class ScInsertContentsDlg : public ModalDialog
+{
+public:
+ ScInsertContentsDlg( Window* pParent,
+ USHORT nCheckDefaults = 0,
+ const String* pStrTitle = NULL );
+ ~ScInsertContentsDlg();
+
+ USHORT GetInsContentsCmdBits() const;
+ USHORT GetFormulaCmdBits() const;
+ BOOL IsSkipEmptyCells() const {return aBtnSkipEmptyCells.IsChecked();}
+ BOOL IsTranspose() const {return aBtnTranspose.IsChecked();}
+ BOOL IsLink() const {return aBtnLink.IsChecked();}
+ InsCellCmd GetMoveMode();
+
+ void SetOtherDoc( BOOL bSet );
+ void SetFillMode( BOOL bSet );
+ void SetChangeTrack( BOOL bSet );
+ void SetCellShiftDisabled( int nDisable );
+
+private:
+ FixedLine aFlFrame;
+ CheckBox aBtnInsAll;
+ CheckBox aBtnInsStrings;
+ CheckBox aBtnInsNumbers;
+ CheckBox aBtnInsDateTime;
+ CheckBox aBtnInsFormulas;
+ CheckBox aBtnInsNotes;
+ CheckBox aBtnInsAttrs;
+ CheckBox aBtnInsObjects;
+
+ FixedLine aFlSep1;
+ FixedLine aFlOptions;
+ CheckBox aBtnSkipEmptyCells;
+ CheckBox aBtnTranspose;
+ CheckBox aBtnLink;
+
+ FixedLine aFlOperation;
+ RadioButton aRbNoOp;
+ RadioButton aRbAdd;
+ RadioButton aRbSub;
+ RadioButton aRbMul;
+ RadioButton aRbDiv;
+
+ FixedLine aFlSep2;
+ FixedLine aFlMove;
+ RadioButton aRbMoveNone;
+ RadioButton aRbMoveDown;
+ RadioButton aRbMoveRight;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ BOOL bOtherDoc;
+ BOOL bFillMode;
+ BOOL bChangeTrack;
+ BOOL bMoveDownDisabled;
+ BOOL bMoveRightDisabled;
+
+ static BOOL bPreviousAllCheck;
+ static USHORT nPreviousChecks;
+ static USHORT nPreviousChecks2;
+ static USHORT nPreviousFormulaChecks;
+ static USHORT nPreviousMoveMode; // enum InsCellCmd
+
+ void DisableChecks( BOOL bInsAllChecked = TRUE );
+ void TestModes();
+
+ // Handler
+ DECL_LINK( InsAllHdl, void* );
+ DECL_LINK( LinkBtnHdl, void* );
+};
+
+
+#endif // SC_INSCODLG_HXX
+
+
diff --git a/sc/source/ui/inc/instbdlg.hrc b/sc/source/ui/inc/instbdlg.hrc
new file mode 100644
index 000000000000..08bff85388dd
--- /dev/null
+++ b/sc/source/ui/inc/instbdlg.hrc
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sc.hrc> // -> RID_SCDLG_INSERT_TABLE
+
+//#define RID_SCDLG_INSERT_TABLE 300
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define FL_POSITION 10
+#define RB_BEFORE 11
+#define RB_BEHIND 12
+
+#define FL_TABLE 20
+#define RB_NEW 21
+#define FT_COUNT 22
+#define NF_COUNT 23
+#define FT_NAME 24
+#define ED_TABNAME 25
+#define RB_FROMFILE 26
+#define LB_TABLES 27
+#define BTN_BROWSE 28
+#define CB_LINK 29
+#define FT_PATH 30
+
+
diff --git a/sc/source/ui/inc/instbdlg.hxx b/sc/source/ui/inc/instbdlg.hxx
new file mode 100644
index 000000000000..660d16b62cca
--- /dev/null
+++ b/sc/source/ui/inc/instbdlg.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_INSTBDLG_HXX
+#define SC_INSTBDLG_HXX
+
+#include "address.hxx"
+
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _EDIT_HXX //autogen
+#include <vcl/edit.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+
+#include <sfx2/objsh.hxx>
+#include <vcl/field.hxx>
+#include "expftext.hxx"
+
+#include <layout/layout.hxx>
+#include <layout/layout-pre.hxx>
+
+class ScViewData;
+class ScDocument;
+class ScDocShell;
+
+namespace sfx2 { class DocumentInserter; }
+namespace sfx2 { class FileDialogHelper; }
+
+//------------------------------------------------------------------------
+
+class ScInsertTableDlg : public ModalDialog
+{
+public:
+ ScInsertTableDlg( Window* pParent, ScViewData& rViewData, SCTAB nTabCount, bool bFromFile );
+ ~ScInsertTableDlg();
+
+ virtual short Execute(); // ueberladen, um Dialog-Parent zu setzen
+
+ BOOL GetTablesFromFile() { return aBtnFromFile.IsChecked(); }
+ BOOL GetTablesAsLink() { return aBtnLink.IsChecked(); }
+
+ const String* GetFirstTable( USHORT* pN = NULL );
+ const String* GetNextTable( USHORT* pN = NULL );
+ ScDocShell* GetDocShellTables() { return pDocShTables; }
+ BOOL IsTableBefore() { return aBtnBefore.IsChecked(); }
+ SCTAB GetTableCount() { return nTableCount;}
+
+private:
+ RadioButton aBtnBefore;
+ RadioButton aBtnBehind;
+ FixedLine aFlPos;
+ RadioButton aBtnNew;
+ RadioButton aBtnFromFile;
+ FixedText aFtCount;
+ NumericField aNfCount;
+ FixedText aFtName;
+ Edit aEdName;
+ MultiListBox aLbTables;
+ ScExpandedFixedText aFtPath;
+ PushButton aBtnBrowse;
+ CheckBox aBtnLink;
+ FixedLine aFlTable;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ Timer aBrowseTimer;
+ ScViewData& rViewData;
+ ScDocument& rDoc;
+ ScDocShell* pDocShTables;
+ sfx2::DocumentInserter* pDocInserter;
+ SfxObjectShellRef aDocShTablesRef;
+
+ bool bMustClose;
+ USHORT nSelTabIndex; // fuer GetFirstTable() / GetNextTable()
+ String aStrCurSelTable;
+ SCTAB nTableCount;
+
+#ifdef SC_INSTBDLG_CXX
+ void Init_Impl( bool bFromFile );
+ void SetNewTable_Impl();
+ void SetFromTo_Impl();
+ void FillTables_Impl( ScDocument* pSrcDoc );
+ void DoEnable_Impl();
+
+ DECL_LINK( BrowseHdl_Impl, PushButton* );
+ DECL_LINK( ChoiceHdl_Impl, RadioButton* );
+ DECL_LINK( SelectHdl_Impl, MultiListBox* );
+ DECL_LINK( CountHdl_Impl, NumericField* );
+ DECL_LINK( DoEnterHdl, PushButton* );
+ DECL_LINK( BrowseTimeoutHdl, Timer* );
+ DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper* );
+#endif
+};
+
+#include <layout/layout-post.hxx>
+
+#endif // SC_INSTBDLG_HXX
+
diff --git a/sc/source/ui/inc/invmerge.hxx b/sc/source/ui/inc/invmerge.hxx
new file mode 100644
index 000000000000..49dfbc730fee
--- /dev/null
+++ b/sc/source/ui/inc/invmerge.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_INVMERGE_HXX
+#define SC_INVMERGE_HXX
+
+#include <tools/gen.hxx>
+
+#include <vector>
+
+class Window;
+
+class ScInvertMerger
+{
+private:
+ Window* pWin;
+ ::std::vector< Rectangle >* pRects;
+ Rectangle aTotalRect;
+ Rectangle aLineRect;
+
+ void FlushLine();
+ void FlushTotal();
+
+public:
+ ScInvertMerger( Window* pWindow );
+ ScInvertMerger( ::std::vector< Rectangle >* pRectangles );
+ ~ScInvertMerger();
+
+ void AddRect( const Rectangle& rRect );
+ void Flush();
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/lbseldlg.hxx b/sc/source/ui/inc/lbseldlg.hxx
new file mode 100644
index 000000000000..fa288c609070
--- /dev/null
+++ b/sc/source/ui/inc/lbseldlg.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LBSELDLG_HXX
+#define SC_LBSELDLG_HXX
+
+
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+
+#ifndef _SV_BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+
+
+#include <vcl/dialog.hxx>
+
+//------------------------------------------------------------------------
+
+class ScSelEntryDlg : public ModalDialog
+{
+private:
+ FixedLine aFlLbTitle;
+ ListBox aLb;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ DECL_LINK( DblClkHdl, void * );
+
+public:
+ ScSelEntryDlg( Window* pParent,
+ USHORT nResId,
+ const String& aTitle,
+ const String& aLbTitle,
+ List& aEntryList );
+ ~ScSelEntryDlg();
+
+ String GetSelectEntry() const;
+//UNUSED2008-05 USHORT GetSelectEntryPos() const;
+};
+
+
+#endif // SC_LBSELDLG_HXX
+
+
diff --git a/sc/source/ui/inc/linkarea.hrc b/sc/source/ui/inc/linkarea.hrc
new file mode 100644
index 000000000000..bc906fdb14ad
--- /dev/null
+++ b/sc/source/ui/inc/linkarea.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 FL_LOCATION 4
+#define CB_URL 5
+#define BTN_BROWSE 6
+#define FT_HINT 7
+#define FT_RANGES 8
+#define LB_RANGES 9
+#define BTN_RELOAD 10
+#define NF_DELAY 11
+#define FT_SECONDS 12
+
diff --git a/sc/source/ui/inc/linkarea.hxx b/sc/source/ui/inc/linkarea.hxx
new file mode 100644
index 000000000000..c90e1ea47e94
--- /dev/null
+++ b/sc/source/ui/inc/linkarea.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LINKAREA_HXX
+#define SC_LINKAREA_HXX
+
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <vcl/dialog.hxx>
+
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#include <vcl/field.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svtools/inettbc.hxx>
+
+//REMOVE #ifndef SO2_DECL_SVEMBEDDEDOBJECT_DEFINED
+//REMOVE #define SO2_DECL_SVEMBEDDEDOBJECT_DEFINED
+//REMOVE SO2_DECL_REF(SvEmbeddedObject)
+//REMOVE #endif
+
+namespace sfx2 { class DocumentInserter; }
+namespace sfx2 { class FileDialogHelper; }
+
+class ScDocShell;
+
+//------------------------------------------------------------------------
+
+class ScLinkedAreaDlg : public ModalDialog
+{
+private:
+ FixedLine aFlLocation;
+ SvtURLBox aCbUrl;
+ PushButton aBtnBrowse;
+ FixedInfo aTxtHint;
+ FixedText aFtRanges;
+ MultiListBox aLbRanges;
+ CheckBox aBtnReload;
+ NumericField aNfDelay;
+ FixedText aFtSeconds;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ ScDocShell* pSourceShell;
+ sfx2::DocumentInserter* pDocInserter;
+
+ SfxObjectShellRef aSourceRef;
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XEmbeddedObject > xSourceObject;
+
+ DECL_LINK( FileHdl, ComboBox* );
+ DECL_LINK( BrowseHdl, PushButton* );
+ DECL_LINK( RangeHdl, MultiListBox* );
+ DECL_LINK( ReloadHdl, CheckBox* );
+ DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper* );
+
+ void UpdateSourceRanges();
+ void UpdateEnable();
+ void LoadDocument( const String& rFile, const String& rFilter,
+ const String& rOptions );
+
+public:
+ ScLinkedAreaDlg( Window* pParent );
+ ~ScLinkedAreaDlg();
+
+ void InitFromOldLink( const String& rFile, const String& rFilter,
+ const String& rOptions, const String& rSource,
+ ULONG nRefresh );
+
+ virtual short Execute(); // overwritten to set dialog parent
+
+ String GetURL();
+ String GetFilter(); // may be empty
+ String GetOptions(); // filter options
+ String GetSource(); // separated by ";"
+ ULONG GetRefresh(); // 0 if disabled
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/lnktrans.hxx b/sc/source/ui/inc/lnktrans.hxx
new file mode 100644
index 000000000000..7e37c6cce554
--- /dev/null
+++ b/sc/source/ui/inc/lnktrans.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LNKTRANS_HXX
+#define SC_LNKTRANS_HXX
+
+#include <svtools/transfer.hxx>
+
+
+class ScLinkTransferObj : public TransferableHelper
+{
+private:
+ String aLinkURL;
+ String aLinkText;
+
+public:
+ ScLinkTransferObj();
+ virtual ~ScLinkTransferObj();
+
+ void SetLinkURL( const String& rURL, const String& rText );
+
+ virtual void AddSupportedFormats();
+ virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ virtual void ObjectReleased();
+ virtual void DragFinished( sal_Int8 nDropAction );
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/makefile.mk b/sc/source/ui/inc/makefile.mk
new file mode 100644
index 000000000000..1b35ca49549d
--- /dev/null
+++ b/sc/source/ui/inc/makefile.mk
@@ -0,0 +1,26 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
diff --git a/sc/source/ui/inc/mediash.hxx b/sc/source/ui/inc/mediash.hxx
new file mode 100644
index 000000000000..e297dc11777a
--- /dev/null
+++ b/sc/source/ui/inc/mediash.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef MEDIASH_HXX
+#define MEDIASH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+
+class ScViewData;
+
+#include "drawsh.hxx"
+
+class ScMediaShell: public ScDrawShell
+{
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_MEDIA_SHELL)
+
+ ScMediaShell(ScViewData* pData);
+ virtual ~ScMediaShell();
+
+ void ExecuteMedia(SfxRequest& rReq);
+ void GetMediaState(SfxItemSet &rSet);
+};
+
+#endif
diff --git a/sc/source/ui/inc/miscdlgs.hrc b/sc/source/ui/inc/miscdlgs.hrc
new file mode 100644
index 000000000000..00b1658849d6
--- /dev/null
+++ b/sc/source/ui/inc/miscdlgs.hrc
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> RID_SCDLG_DELCELL
+ // -> RID_SCDLG_INSCELL
+ // -> RID_SCDLG_DELCONT
+ // -> RID_SCDLG_INSCONT
+ // -> RID_SCDLG_MOVETAB
+ // -> RID_SCDLG_STRINPUT
+ // -> RID_SCDLG_MTRINPUT
+ // -> RID_SCDLG_SELENTRY
+ // -> RID_SCDLG_FILLSERIES
+ // -> RID_SCDLG_AUTOFORMAT
+
+// Fuer den DesignEditor:
+/*
+#define RID_SCDLG_DELCELL 1256
+#define RID_SCDLG_INSCELL 1257
+#define RID_SCDLG_DELCONT 1258
+#define RID_SCDLG_INSCONT 1259
+#define RID_SCDLG_MOVETAB 1260
+#define RID_SCDLG_STRINPUT 1261
+#define RID_SCDLG_MTRINPUT 1262
+#define RID_SCDLG_SELENTRY 1263
+#define RID_SCDLG_FILLSERIES 1264
+#define RID_SCDLG_AUTOFORMAT 1255
+*/
+
+// allgemein
+#define BTN_OK 100
+#define BTN_CANCEL 102
+#define BTN_HELP 103
+#define BTN_MORE 104
+#define BTN_ADD 105
+#define BTN_REMOVE 106
+#define FT_LABEL 110
+#define FL_FRAME 112
+#define STR_BTN_CLOSE 200
+
+// Zellen loeschen/einfuegen Dialog
+#define BTN_CELLSUP 10
+#define BTN_CELLSDOWN 11
+#define BTN_CELLSRIGHT 12
+#define BTN_CELLSLEFT 13
+#define BTN_DELROWS 14
+#define BTN_DELCOLS 15
+#define BTN_INSROWS 16
+#define BTN_INSCOLS 17
+
+// Inhalte loeschen/einfuegen Dialog
+#define BTN_DELALL 10
+#define BTN_DELSTRINGS 11
+#define BTN_DELNUMBERS 12
+#define BTN_DELDATETIME 13
+#define BTN_DELFORMULAS 14
+#define BTN_DELATTRS 15
+#define BTN_DELNOTES 16
+#define BTN_DELOBJECTS 17
+#define BTN_INSALL 20
+#define BTN_INSSTRINGS 21
+#define BTN_INSNUMBERS 22
+#define BTN_INSDATETIME 23
+#define BTN_INSFORMULAS 24
+#define BTN_INSATTRS 25
+#define BTN_INSNOTES 26
+#define BTN_OP_NOOP 27
+#define BTN_OP_ADD 28
+#define BTN_OP_SUB 29
+#define BTN_OP_MUL 30
+#define BTN_OP_DIV 31
+#define FL_OPERATION 32
+#define BTN_SKIP_EMPTY 33
+#define BTN_TRANSPOSE 34
+#define BTN_LINK 35
+#define FL_OPTIONS 36
+#define BTN_MV_NONE 37
+#define BTN_MV_DOWN 38
+#define BTN_MV_RIGHT 39
+#define FL_MOVE 40
+#define BTN_INSOBJECTS 41
+#define FL_SEP1 51
+#define FL_SEP2 52
+
+// Tabelle einfuegen/loeschen
+#define FT_DEST 1
+#define LB_DEST 2
+#define FT_INSERT 3
+#define LB_INSERT 4
+#define BTN_COPY 5
+#define STR_NEWDOC 6
+
+// Eingabe eines Strings
+#define ED_INPUT 10
+
+// Eingabe einer Metrik
+#define ED_VALUE 1
+#define BTN_DEFVAL 1
+
+// Auswahl aus einer (String-)ListBox
+#define FL_ENTRYLIST 10
+#define LB_ENTRYLIST 11
+
+// Reihen fuellen
+#define FL_DIRECTION 1
+#define BTN_LEFT 2
+#define BTN_RIGHT 3
+#define BTN_TOP 4
+#define BTN_BOTTOM 5
+#define FL_SEP11 10
+#define FL_TYPE 11
+#define BTN_ARITHMETIC 12
+#define BTN_GEOMETRIC 13
+#define BTN_DATE 14
+#define BTN_AUTOFILL 15
+#define FL_SEP12 20
+#define FL_TIME_UNIT 21
+#define BTN_DAY 22
+#define BTN_DAY_OF_WEEK 23
+#define BTN_MONTH 24
+#define BTN_YEAR 25
+#define FT_INCREMENT 30
+#define ED_INCREMENT 39
+#define FT_END_VALUE 40
+#define ED_END_VALUES 49
+#define STR_VALERR 50
+#define FT_START_VALUE 51
+#define ED_START_VALUES 52
+
+// Autoformat
+#define LB_FORMAT 1
+#define FL_FORMAT 9
+#define WND_PREVIEW 19
+#define BTN_NUMFORMAT 20
+#define BTN_BORDER 21
+#define BTN_FONT 23
+#define BTN_PATTERN 24
+#define BTN_ALIGNMENT 25
+#define BTN_ADJUST 26
+#define BTN_RENAME 27
+#define FL_FORMATTING 29
+#define STR_ADD_TITLE 100
+#define STR_ADD_LABEL 101
+#define STR_DEL_TITLE 102
+#define STR_DEL_MSG 103
+#define STR_RENAME_TITLE 104
+ // Autoformat-Preview:
+#define STR_JAN 121
+#define STR_FEB 122
+#define STR_MAR 123
+#define STR_NORTH 124
+#define STR_MID 125
+#define STR_SOUTH 126
+#define STR_SUM 127
+
+// Gruppierung setzen/aufheben:
+#define BTN_GROUP_COLS 1
+#define BTN_GROUP_ROWS 3
+#define STR_GROUP 1
+#define STR_UNGROUP 2
+
+// Tab Bg Color
+#define TAB_BG_COLOR_CT_BORDER 1
+#define TAB_BG_COLOR_SET_BGDCOLOR 2
+
diff --git a/sc/source/ui/inc/msgpool.hxx b/sc/source/ui/inc/msgpool.hxx
new file mode 100644
index 000000000000..7bc33b3af96b
--- /dev/null
+++ b/sc/source/ui/inc/msgpool.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_MSGPOOL_HXX
+#define SC_MSGPOOL_HXX
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+
+
+#include <svl/itempool.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+
+//#include <dbitems.hxx>
+#include "uiitems.hxx"
+
+
+//------------------------------------------------------------------------
+
+class ScDocumentPool;
+
+//------------------------------------------------------------------------
+
+class ScMessagePool: public SfxItemPool
+{
+ SfxStringItem aGlobalStringItem;
+ SvxSearchItem aGlobalSearchItem;
+ ScSortItem aGlobalSortItem;
+ ScQueryItem aGlobalQueryItem;
+ ScSubTotalItem aGlobalSubTotalItem;
+ ScConsolidateItem aGlobalConsolidateItem;
+ ScPivotItem aGlobalPivotItem;
+ ScSolveItem aGlobalSolveItem;
+ ScUserListItem aGlobalUserListItem;
+
+ SfxBoolItem aPrintWarnItem;
+
+ SfxPoolItem** ppPoolDefaults;
+ ScDocumentPool* pDocPool;
+
+public:
+ ScMessagePool();
+protected:
+ virtual ~ScMessagePool();
+public:
+
+ virtual SfxMapUnit GetMetric( USHORT nWhich ) const;
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/mtrindlg.hxx b/sc/source/ui/inc/mtrindlg.hxx
new file mode 100644
index 000000000000..f88f57a74e58
--- /dev/null
+++ b/sc/source/ui/inc/mtrindlg.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_MTRINDLG_HXX
+#define SC_MTRINDLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/field.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+
+
+//------------------------------------------------------------------------
+
+class ScMetricInputDlg : public ModalDialog
+{
+public:
+ ScMetricInputDlg( Window* pParent,
+ USHORT nResId, // Ableitung fuer jeden Dialog!
+ long nCurrent,
+ long nDefault,
+ FieldUnit eFUnit = FUNIT_MM,
+ USHORT nDecimals = 2,
+ long nMaximum = 1000,
+ long nMinimum = 0,
+ long nFirst = 1,
+ long nLast = 100 );
+ ~ScMetricInputDlg();
+
+ long GetInputValue( FieldUnit eUnit = FUNIT_TWIP ) const;
+
+private:
+ FixedText aFtEditTitle;
+ MetricField aEdValue;
+ CheckBox aBtnDefVal;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ long nDefaultValue;
+ long nCurrentValue;
+
+ void CalcPositions();
+ DECL_LINK( SetDefValHdl, CheckBox * );
+ DECL_LINK( ModifyHdl, MetricField * );
+};
+
+#endif // SC_MTRINDLG_HXX
+
+
+
+
+
diff --git a/sc/source/ui/inc/mvtabdlg.hxx b/sc/source/ui/inc/mvtabdlg.hxx
new file mode 100644
index 000000000000..d5ce7726243f
--- /dev/null
+++ b/sc/source/ui/inc/mvtabdlg.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_MVTABDLG_HXX
+#define SC_MVTABDLG_HXX
+
+
+#include "address.hxx"
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/fixed.hxx>
+
+#include <layout/layout.hxx>
+#include <layout/layout-pre.hxx>
+
+//------------------------------------------------------------------------
+
+class ScMoveTableDlg : public ModalDialog
+{
+public:
+ ScMoveTableDlg( Window* pParent );
+ ~ScMoveTableDlg();
+
+ USHORT GetSelectedDocument () const;
+ SCTAB GetSelectedTable () const;
+ BOOL GetCopyTable () const;
+ void SetCopyTable (BOOL bFlag=TRUE);
+ void EnableCopyTable (BOOL bFlag=TRUE);
+
+private:
+ FixedText aFtDoc;
+ ListBox aLbDoc;
+ FixedText aFtTable;
+ ListBox aLbTable;
+ CheckBox aBtnCopy;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ USHORT nDocument;
+ SCTAB nTable;
+ BOOL bCopyTable;
+ //--------------------------------------
+ void Init ();
+ void InitDocListBox ();
+ DECL_LINK( OkHdl, void * );
+ DECL_LINK( SelHdl, ListBox * );
+};
+
+#include <layout/layout-post.hxx>
+
+#endif // SC_MVTABDLG_HXX
+
+
diff --git a/sc/source/ui/inc/namecrea.hxx b/sc/source/ui/inc/namecrea.hxx
new file mode 100644
index 000000000000..e4e053fe0bcf
--- /dev/null
+++ b/sc/source/ui/inc/namecrea.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAMECREA_HXX
+#define SC_NAMECREA_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+#include "scui_def.hxx" //CHINA001
+
+//CHINA001 #define NAME_TOP 1
+//CHINA001 #define NAME_LEFT 2
+//CHINA001 #define NAME_BOTTOM 4
+//CHINA001 #define NAME_RIGHT 8
+
+class ScNameCreateDlg : public ModalDialog
+{
+protected:
+ FixedLine aFixedLine;
+ CheckBox aTopBox;
+ CheckBox aLeftBox;
+ CheckBox aBottomBox;
+ CheckBox aRightBox;
+ OKButton aOKButton;
+ CancelButton aCancelButton;
+ HelpButton aHelpButton;
+public:
+ ScNameCreateDlg( Window * pParent, USHORT nFlags );
+
+ USHORT GetFlags() const;
+};
+
+
+#endif //SC_NAMECREA_HXX
diff --git a/sc/source/ui/inc/namedlg.hrc b/sc/source/ui/inc/namedlg.hrc
new file mode 100644
index 000000000000..b2eec6879ec3
--- /dev/null
+++ b/sc/source/ui/inc/namedlg.hrc
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> RID_SCDLG_NAMES
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_ADD 3
+#define BTN_REMOVE 4
+#define BTN_HELP 5
+#define BTN_MORE 6
+//
+#define FL_NAME 11
+#define ED_NAME 12
+#define FL_ASSIGN 13
+#define ED_ASSIGN 15
+#define RB_ASSIGN 16
+//
+#define STR_ADD 21
+#define STR_MODIFY 22
+#define STR_INVALIDSYMBOL 23
+//
+#define BTN_CRITERIA 31
+#define BTN_PRINTAREA 32
+#define BTN_COLHEADER 33
+#define BTN_ROWHEADER 34
+#define FL_TYPE 35
+
diff --git a/sc/source/ui/inc/namedlg.hxx b/sc/source/ui/inc/namedlg.hxx
new file mode 100644
index 000000000000..b122c57a19fd
--- /dev/null
+++ b/sc/source/ui/inc/namedlg.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAMEDLG_HXX
+#define SC_NAMEDLG_HXX
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#include <vcl/fixed.hxx>
+#include "rangenam.hxx"
+#include "anyrefdg.hxx"
+
+class ScViewData;
+class ScDocument;
+
+
+//==================================================================
+
+class ScNameDlg : public ScAnyRefDlg
+{
+private:
+ FixedLine aFlName;
+ ComboBox aEdName;
+
+ FixedLine aFlAssign;
+ formula::RefEdit aEdAssign;
+ formula::RefButton aRbAssign;
+
+ FixedLine aFlType;
+ CheckBox aBtnPrintArea;
+ CheckBox aBtnColHeader;
+ CheckBox aBtnCriteria;
+ CheckBox aBtnRowHeader;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ PushButton aBtnAdd;
+ PushButton aBtnRemove;
+ MoreButton aBtnMore;
+ BOOL bSaved;
+
+ const String aStrAdd; // "Hinzufuegen"
+ const String aStrModify; // "Aendern"
+ const String errMsgInvalidSym;
+
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ ScRangeName aLocalRangeName;
+ const ScAddress theCursorPos;
+ Selection theCurSel;
+
+#ifdef _NAMEDLG_CXX
+private:
+ void Init();
+ void UpdateChecks();
+ void UpdateNames();
+ void CalcCurTableAssign( String& aAssign, USHORT nPos );
+
+ // Handler:
+ DECL_LINK( OkBtnHdl, void * );
+ DECL_LINK( CancelBtnHdl, void * );
+ DECL_LINK( AddBtnHdl, void * );
+ DECL_LINK( RemoveBtnHdl, void * );
+ DECL_LINK( EdModifyHdl, Edit * );
+ DECL_LINK( NameSelectHdl, void * );
+ DECL_LINK( AssignGetFocusHdl, void * );
+#endif
+
+protected:
+
+ virtual void RefInputDone( BOOL bForced = FALSE );
+
+
+public:
+ ScNameDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData,
+ const ScAddress& aCursorPos );
+ ~ScNameDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual BOOL IsRefInputMode() const;
+
+ virtual void SetActive();
+ virtual BOOL Close();
+
+};
+
+
+
+#endif // SC_NAMEDLG_HXX
+
diff --git a/sc/source/ui/inc/namepast.hxx b/sc/source/ui/inc/namepast.hxx
new file mode 100644
index 000000000000..3286af7b81bc
--- /dev/null
+++ b/sc/source/ui/inc/namepast.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAMEPAST_HXX
+#define SC_NAMEPAST_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+
+#include "scui_def.hxx" //CHINA001
+//CHINA001 #define BTN_PASTE_NAME 100
+//CHINA001 #define BTN_PASTE_LIST 101
+//CHINA001
+class ScRangeName;
+
+class ScNamePasteDlg : public ModalDialog
+{
+ DECL_LINK( ButtonHdl, Button * );
+ DECL_LINK( ListSelHdl, ListBox * );
+ DECL_LINK( ListDblClickHdl, ListBox * );
+
+protected:
+ FixedText aLabelText;
+ ListBox aNameList;
+ OKButton aOKButton;
+ CancelButton aCancelButton;
+ HelpButton aHelpButton;
+ PushButton aInsListButton;
+public:
+ ScNamePasteDlg( Window * pParent, const ScRangeName* pList, BOOL bInsList=TRUE );
+
+ String GetSelectedName() const;
+};
+
+
+#endif //SC_NAMEPAST_HXX
diff --git a/sc/source/ui/inc/navcitem.hxx b/sc/source/ui/inc/navcitem.hxx
new file mode 100644
index 000000000000..b464bd6cc9ad
--- /dev/null
+++ b/sc/source/ui/inc/navcitem.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAVCITEM_HXX
+#define SC_NAVCITEM_HXX
+
+
+#include <sfx2/ctrlitem.hxx>
+
+
+//==================================================================
+
+class ScNavigatorDlg;
+
+class ScNavigatorControllerItem : public SfxControllerItem
+{
+public:
+ ScNavigatorControllerItem( USHORT nId,
+ ScNavigatorDlg& rDlg,
+ SfxBindings& rBindings );
+protected:
+ virtual void StateChanged( USHORT nSID, SfxItemState eState,
+ const SfxPoolItem* pItem );
+
+private:
+ ScNavigatorDlg& rNavigatorDlg;
+};
+
+
+#endif // SC_NAVCITEM_HXX
+
diff --git a/sc/source/ui/inc/navipi.hxx b/sc/source/ui/inc/navipi.hxx
new file mode 100644
index 000000000000..8d53742b6f1e
--- /dev/null
+++ b/sc/source/ui/inc/navipi.hxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAVIPI_HXX
+#define SC_NAVIPI_HXX
+
+#include <vector>
+#include <vcl/toolbox.hxx>
+#include <vcl/field.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svl/poolitem.hxx>
+#include <svl/lstner.hxx>
+#include <sfx2/childwin.hxx>
+#include "content.hxx"
+#include <svtools/svmedit.hxx>
+
+
+class ScTabViewShell;
+class ScViewData;
+class ScArea;
+class ScScenarioWindow;
+class ScNavigatorControllerItem;
+class ScNavigatorDialogWrapper;
+class ScNavigatorDlg;
+class ScNavigatorSettings;
+class ScRange;
+
+//========================================================================
+
+#define SC_DROPMODE_URL 0
+#define SC_DROPMODE_LINK 1
+#define SC_DROPMODE_COPY 2
+
+enum NavListMode { NAV_LMODE_NONE = 0x4000,
+ NAV_LMODE_AREAS = 0x2000,
+ NAV_LMODE_DBAREAS = 0x1000,
+ NAV_LMODE_DOCS = 0x800,
+ NAV_LMODE_SCENARIOS = 0x400 };
+
+//========================================================================
+// class ScScenarioListBox -----------------------------------------------
+//========================================================================
+
+class ScScenarioListBox : public ListBox
+{
+public:
+ explicit ScScenarioListBox( ScScenarioWindow& rParent );
+ virtual ~ScScenarioListBox();
+
+ void UpdateEntries( List* pNewEntryList );
+
+protected:
+ virtual void Select();
+ virtual void DoubleClick();
+ virtual long Notify( NotifyEvent& rNEvt );
+
+private:
+ struct ScenarioEntry
+ {
+ String maName;
+ String maComment;
+ bool mbProtected;
+
+ inline explicit ScenarioEntry() : mbProtected( false ) {}
+ };
+ typedef ::std::vector< ScenarioEntry > ScenarioList;
+
+private:
+ const ScenarioEntry* GetSelectedEntry() const;
+
+ void ExecuteScenarioSlot( USHORT nSlotId );
+ void SelectScenario();
+ void EditScenario();
+ void DeleteScenario( bool bQueryBox );
+
+private:
+ ScScenarioWindow& mrParent;
+ ScenarioList maEntries;
+};
+
+//========================================================================
+// class ScScenarioWindow ------------------------------------------------
+//========================================================================
+class ScScenarioWindow : public Window
+{
+public:
+ ScScenarioWindow( Window* pParent,const String& aQH_List,const String& aQH_Comment);
+ ~ScScenarioWindow();
+
+ void NotifyState( const SfxPoolItem* pState );
+ void SetComment( const String& rComment )
+ { aEdComment.SetText( rComment ); }
+
+ void SetSizePixel( const Size& rNewSize );
+
+protected:
+
+ virtual void Paint( const Rectangle& rRec );
+
+private:
+ ScScenarioListBox aLbScenario;
+ MultiLineEdit aEdComment;
+};
+
+//==================================================================
+// class ColumnEdit
+//==================================================================
+class ColumnEdit : public SpinField
+{
+public:
+ ColumnEdit( ScNavigatorDlg* pParent, const ResId& rResId );
+ ~ColumnEdit();
+
+ SCCOL GetCol() { return nCol; }
+ void SetCol( SCCOL nColNo );
+
+protected:
+ virtual long Notify( NotifyEvent& rNEvt );
+ virtual void LoseFocus();
+ virtual void Up();
+ virtual void Down();
+ virtual void First();
+ virtual void Last();
+
+private:
+ ScNavigatorDlg& rDlg;
+ SCCOL nCol;
+ USHORT nKeyGroup;
+
+ void EvalText ();
+ void ExecuteCol ();
+ SCCOL AlphaToNum ( String& rStr );
+ SCCOL NumStrToAlpha ( String& rStr );
+ SCCOL NumToAlpha ( SCCOL nColNo, String& rStr );
+};
+
+
+//==================================================================
+// class RowEdit
+//==================================================================
+class RowEdit : public NumericField
+{
+public:
+ RowEdit( ScNavigatorDlg* pParent, const ResId& rResId );
+ ~RowEdit();
+
+ SCROW GetRow() { return (SCROW)GetValue(); }
+ void SetRow( SCROW nRow ){ SetValue( nRow ); }
+
+protected:
+ virtual long Notify( NotifyEvent& rNEvt );
+ virtual void LoseFocus();
+
+private:
+ ScNavigatorDlg& rDlg;
+
+ void ExecuteRow();
+};
+
+
+//==================================================================
+// class ScDocListBox
+//==================================================================
+class ScDocListBox : public ListBox
+{
+public:
+ ScDocListBox( ScNavigatorDlg* pParent, const ResId& rResId );
+ ~ScDocListBox();
+
+protected:
+ virtual void Select();
+
+private:
+ ScNavigatorDlg& rDlg;
+};
+
+
+//==================================================================
+// class CommandToolBox
+//==================================================================
+class CommandToolBox : public ToolBox
+{
+public:
+ CommandToolBox( ScNavigatorDlg* pParent, const ResId& rResId );
+ ~CommandToolBox();
+
+ void Select( USHORT nId );
+ void UpdateButtons();
+ void InitImageList();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ DECL_LINK( ToolBoxDropdownClickHdl, ToolBox* );
+
+protected:
+ virtual void Select();
+ virtual void Click();
+
+private:
+ ScNavigatorDlg& rDlg;
+};
+
+//==================================================================
+// class ScNavigatorDlg
+//==================================================================
+
+class ScNavigatorDlg : public Window, public SfxListener
+{
+friend class ScNavigatorControllerItem;
+friend class ScNavigatorDialogWrapper;
+friend class ColumnEdit;
+friend class RowEdit;
+friend class ScDocListBox;
+friend class CommandToolBox;
+friend class ScContentTree;
+
+private:
+ SfxBindings& rBindings; // must be first member
+
+ ImageList aCmdImageList; // must be before aTbxCmd
+ ImageList aCmdImageListH;
+ FixedInfo aFtCol;
+ ColumnEdit aEdCol;
+ FixedInfo aFtRow;
+ RowEdit aEdRow;
+ CommandToolBox aTbxCmd;
+ ScContentTree aLbEntries;
+ ScScenarioWindow aWndScenarios;
+ ScDocListBox aLbDocuments;
+
+ Timer aContentTimer;
+
+ String aTitleBase;
+ String aStrDragMode;
+ String aStrDisplay;
+ String aStrActive;
+ String aStrNotActive;
+ String aStrHidden;
+ String aStrActiveWin;
+
+ SfxChildWindowContext* pContextWin;
+ Size aInitSize;
+ ScArea* pMarkArea;
+ ScViewData* pViewData;
+
+ long nBorderOffset;
+ long nListModeHeight;
+ long nInitListHeight;
+ NavListMode eListMode;
+ USHORT nDropMode;
+ SCCOL nCurCol;
+ SCROW nCurRow;
+ SCTAB nCurTab;
+ BOOL bFirstBig;
+
+ ScNavigatorControllerItem** ppBoundItems;
+
+ DECL_LINK( TimeHdl, Timer* );
+
+ void DoResize();
+
+ SfxBindings& GetBindings()
+ { return rBindings; }
+
+ void SetCurrentCell( SCCOL nCol, SCROW Row );
+ void SetCurrentCellStr( const String rName );
+ void SetCurrentTable( SCTAB nTab );
+ void SetCurrentTableStr( const String rName );
+ void SetCurrentObject( const String rName );
+ void SetCurrentDoc( const String& rDocName );
+
+ ScTabViewShell* GetTabViewShell() const;
+ ScNavigatorSettings* GetNavigatorSettings();
+ BOOL GetViewData();
+
+ void UpdateColumn ( const SCCOL* pCol = NULL );
+ void UpdateRow ( const SCROW* pRow = NULL );
+ void UpdateTable ( const SCTAB* pTab = NULL );
+ void UpdateAll ();
+
+ void GetDocNames(const String* pSelEntry = NULL);
+
+ void SetListMode ( NavListMode eMode, BOOL bSetSize = TRUE );
+ void ShowList ( BOOL bShow, BOOL bSetSize );
+ void ShowScenarios ( BOOL bShow, BOOL bSetSize );
+
+ void SetDropMode(USHORT nNew);
+ USHORT GetDropMode() const { return nDropMode; }
+
+ const String& GetStrDragMode() const { return aStrDragMode; }
+ const String& GetStrDisplay() const { return aStrDisplay; }
+
+ void CheckDataArea ();
+ void MarkDataArea ();
+ void UnmarkDataArea ();
+ void StartOfDataArea ();
+ void EndOfDataArea ();
+
+ static void ReleaseFocus();
+
+protected:
+ virtual void Resize();
+ virtual void Paint( const Rectangle& rRec );
+ virtual void Resizing( Size& rSize );
+
+public:
+ ScNavigatorDlg( SfxBindings* pB, SfxChildWindowContext* pCW, Window* pParent );
+ ~ScNavigatorDlg();
+
+ using Window::Notify;
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ void CursorPosChanged();
+
+ virtual SfxChildAlignment
+ CheckAlignment(SfxChildAlignment,SfxChildAlignment);
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+};
+
+//==================================================================
+
+class ScNavigatorDialogWrapper: public SfxChildWindowContext
+{
+public:
+ ScNavigatorDialogWrapper( Window* pParent,
+ USHORT nId,
+ SfxBindings* pBindings,
+ SfxChildWinInfo* pInfo );
+
+ SFX_DECL_CHILDWINDOWCONTEXT(ScNavigatorDialogWrapper)
+
+ virtual void Resizing( Size& rSize );
+
+private:
+ ScNavigatorDlg* pNavigator;
+};
+
+
+
+#endif // SC_NAVIPI_HXX
+
diff --git a/sc/source/ui/inc/navsett.hxx b/sc/source/ui/inc/navsett.hxx
new file mode 100644
index 000000000000..896c64606646
--- /dev/null
+++ b/sc/source/ui/inc/navsett.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAVSETT_HXX
+#define SC_NAVSETT_HXX
+
+#include <tools/solar.h>
+
+#include <vector>
+
+/** Contains settings of the navigator listbox. This includes the expand state
+ of each listbox entry and the index of the selected entry and sub entry. */
+class ScNavigatorSettings
+{
+private:
+ ::std::vector< BOOL > maExpandedVec; /// Array of Booleans for expand state.
+ USHORT mnRootSelected; /// Index of selected root entry.
+ ULONG mnChildSelected; /// Index of selected child entry.
+
+public:
+ ScNavigatorSettings();
+
+ inline void SetExpanded( USHORT nIndex, BOOL bExpand ) { maExpandedVec[ nIndex ] = bExpand; }
+ inline BOOL IsExpanded( USHORT nIndex ) const { return maExpandedVec[ nIndex ]; }
+
+ inline void SetRootSelected( USHORT nIndex ) { mnRootSelected = nIndex; }
+ inline USHORT GetRootSelected() const { return mnRootSelected; }
+
+ inline void SetChildSelected( ULONG nIndex ) { mnChildSelected = nIndex; }
+ inline ULONG GetChildSelected() const { return mnChildSelected; }
+};
+
+
+#endif // SC_NAVSETT_HXX
+
diff --git a/sc/source/ui/inc/notemark.hxx b/sc/source/ui/inc/notemark.hxx
new file mode 100644
index 000000000000..65e36565ceb8
--- /dev/null
+++ b/sc/source/ui/inc/notemark.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NOTEMARK_HXX
+#define SC_NOTEMARK_HXX
+
+#ifndef _MAPMOD_HXX //autogen
+#include <vcl/mapmod.hxx>
+#endif
+#include <vcl/timer.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+class SdrModel;
+class SdrObject;
+
+class ScNoteMarker
+{
+private:
+ Window* pWindow;
+ Window* pRightWin;
+ Window* pBottomWin;
+ Window* pDiagWin;
+ ScDocument* pDoc;
+ ScAddress aDocPos;
+ String aUserText;
+ Rectangle aVisRect;
+ Timer aTimer;
+ MapMode aMapMode;
+ BOOL bLeft;
+ BOOL bByKeyboard;
+
+ Rectangle aRect;
+ SdrModel* pModel;
+ SdrObject* pObject;
+ BOOL bVisible;
+
+ DECL_LINK( TimeHdl, Timer* );
+
+public:
+ ScNoteMarker( Window* pWin, Window* pRight, Window* pBottom, Window* pDiagonal,
+ ScDocument* pD, ScAddress aPos, const String& rUser,
+ const MapMode& rMap, BOOL bLeftEdge, BOOL bForce, BOOL bKeyboard );
+ ~ScNoteMarker();
+
+ void Draw();
+ void InvalidateWin();
+
+ ScAddress GetDocPos() const { return aDocPos; }
+ BOOL IsByKeyboard() const { return bByKeyboard; }
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/oleobjsh.hxx b/sc/source/ui/inc/oleobjsh.hxx
new file mode 100644
index 000000000000..fa4f71729c97
--- /dev/null
+++ b/sc/source/ui/inc/oleobjsh.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OLEOBJSH_HXX
+#define OLEOBJSH_HXX
+
+#include <sfx2/shell.hxx>
+#include "shellids.hxx"
+#include <sfx2/module.hxx>
+#include <svx/svdmark.hxx>
+
+class ScViewData;
+
+#include "drawsh.hxx"
+
+class ScOleObjectShell: public ScDrawShell
+{
+public:
+
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_OLEOBJECT_SHELL)
+
+ ScOleObjectShell(ScViewData* pData);
+ virtual ~ScOleObjectShell();
+
+};
+
+#endif
diff --git a/sc/source/ui/inc/olinefun.hxx b/sc/source/ui/inc/olinefun.hxx
new file mode 100644
index 000000000000..444774ed2068
--- /dev/null
+++ b/sc/source/ui/inc/olinefun.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OLINEFUN_HXX
+#define SC_OLINEFUN_HXX
+
+#include "global.hxx"
+
+class ScDocShell;
+class ScRange;
+
+
+// ---------------------------------------------------------------------------
+
+class ScOutlineDocFunc
+{
+private:
+ ScDocShell& rDocShell;
+
+public:
+ ScOutlineDocFunc( ScDocShell& rDocSh ): rDocShell(rDocSh) {}
+ ~ScOutlineDocFunc() {}
+
+ BOOL MakeOutline( const ScRange& rRange, BOOL bColumns, BOOL bRecord, BOOL bApi );
+ BOOL RemoveOutline( const ScRange& rRange, BOOL bColumns, BOOL bRecord, BOOL bApi );
+ BOOL RemoveAllOutlines( SCTAB nTab, BOOL bRecord, BOOL bApi );
+ BOOL AutoOutline( const ScRange& rRange, BOOL bRecord, BOOL bApi );
+
+ BOOL SelectLevel( SCTAB nTab, BOOL bColumns, USHORT nLevel,
+ BOOL bRecord, BOOL bPaint, BOOL bApi );
+
+ BOOL ShowMarkedOutlines( const ScRange& rRange, BOOL bRecord, BOOL bApi );
+ BOOL HideMarkedOutlines( const ScRange& rRange, BOOL bRecord, BOOL bApi );
+
+ BOOL ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, USHORT nEntry,
+ BOOL bRecord, BOOL bPaint, BOOL bApi );
+ BOOL HideOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, USHORT nEntry,
+ BOOL bRecord, BOOL bPaint, BOOL bApi );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/olinewin.hxx b/sc/source/ui/inc/olinewin.hxx
new file mode 100644
index 000000000000..104f9e8f11da
--- /dev/null
+++ b/sc/source/ui/inc/olinewin.hxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_OLINEWIN_HXX
+#define SC_OLINEWIN_HXX
+
+#include "viewdata.hxx"
+
+class ScOutlineEntry;
+class ScOutlineArray;
+class ScOutlineTable;
+
+
+// ============================================================================
+
+enum ScOutlineMode { SC_OUTLINE_HOR, SC_OUTLINE_VER };
+
+
+// ----------------------------------------------------------------------------
+
+/** The window left of or above the spreadsheet containing the outline groups
+ and controls to expand/collapse them. */
+class ScOutlineWindow : public Window
+{
+private:
+ ScViewData& mrViewData; /// View data containing the document.
+ ScSplitPos meWhich; /// Which area in split window.
+ bool mbHoriz; /// true = Horizontal orientation.
+ bool mbMirrorEntries; /// true = mirror the order of entries (including header)
+ bool mbMirrorLevels; /// true = mirror the order of levels, including the border
+
+ ImageList* mpSymbols; /// Symbols for buttons.
+ Color maLineColor; /// Line color for expanded groups.
+ long mnHeaderSize; /// Size of the header area in entry direction.
+ long mnHeaderPos; /// Position of the header area in entry direction.
+ long mnMainFirstPos; /// First position of main area in entry direction.
+ long mnMainLastPos; /// Last position of main area in entry direction.
+
+ size_t mnMTLevel; /// Mouse tracking: Level of active button.
+ size_t mnMTEntry; /// Mouse tracking: Entry index of active button.
+ bool mbMTActive; /// Mouse tracking active?
+ bool mbMTPressed; /// Mouse tracking: Button currently drawed pressed?
+
+ Rectangle maFocusRect; /// Focus rectangle on screen.
+ size_t mnFocusLevel; /// Level of focused button.
+ size_t mnFocusEntry; /// Entry index of focused button.
+ bool mbDontDrawFocus; /// Do not redraw focus in next Paint().
+
+public:
+ ScOutlineWindow(
+ Window* pParent,
+ ScOutlineMode eMode,
+ ScViewData* pViewData,
+ ScSplitPos eWhich );
+ virtual ~ScOutlineWindow();
+
+ /** Sets the size of the header area (width/height dep. on window type). */
+ void SetHeaderSize( long nNewSize );
+ /** Returns the width/height the window needs to show all levels. */
+ long GetDepthSize() const;
+
+ /** Scrolls the window content by the specified amount of pixels. */
+ void ScrollPixel( long nDiff );
+
+ using Window::ShowFocus;
+
+private:
+ /** Initializes color and image settings. */
+ void InitSettings();
+
+ /** Returns the calc document. */
+ inline ScDocument& GetDoc() const { return *mrViewData.GetDocument(); }
+ /** Returns the current sheet index. */
+ inline SCTAB GetTab() const { return mrViewData.GetTabNo(); }
+ /** Returns the outline array of the corresponding document. */
+ const ScOutlineArray* GetOutlineArray() const;
+ /** Returns the specified outline entry. */
+ const ScOutlineEntry* GetOutlineEntry( size_t nLevel, size_t nEntry ) const;
+
+ /** Returns true, if the column/row is hidden. */
+ bool IsHidden( SCCOLROW nColRowIndex ) const;
+ /** Returns true, if the column/row is filtered. */
+ bool IsFiltered( SCCOLROW nColRowIndex ) const;
+ /** Returns true, if all columns/rows before nColRowIndex are hidden. */
+ bool IsFirstVisible( SCCOLROW nColRowIndex ) const;
+ /** Returns the currently visible column/row range. */
+ void GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const;
+
+ /** Returns the point in the window of the specified position. */
+ Point GetPoint( long nLevelPos, long nEntryPos ) const;
+ /** Returns the rectangle in the window of the specified position. */
+ Rectangle GetRectangle(
+ long nLevelStart, long nEntryStart,
+ long nLevelEnd, long nEntryEnd ) const;
+
+ /** Returns the window size for the level coordinate. */
+ long GetOutputSizeLevel() const;
+ /** Returns the window size for the entry coordinate. */
+ long GetOutputSizeEntry() const;
+
+ /** Returns the count of levels of the outline array. 0 means no outlines. */
+ size_t GetLevelCount() const;
+ /** Returns the pixel position of the specified level. */
+ long GetLevelPos( size_t nLevel ) const;
+ /** Returns the level of the passed pixel position. */
+ size_t GetLevelFromPos( long nLevelPos ) const;
+
+ /** Returns the start coordinate of the specified column/row in the window. */
+ long GetColRowPos( SCCOLROW nColRowIndex ) const;
+ /** Returns the entry position of header images. */
+ long GetHeaderEntryPos() const;
+ /** Calculates the coordinates the outline entry takes in the window.
+ @return false = no part of the group is visible (outside window or collapsed by parent group). */
+ bool GetEntryPos(
+ size_t nLevel, size_t nEntry,
+ long& rnStartPos, long& rnEndPos, long& rnImagePos ) const;
+ /** Calculates the absolute position of the image of the specified outline entry.
+ @param nLevel The level of the entry.
+ @param nEntry The entry index or SC_OL_HEADERENTRY for the header image.
+ @return false = image is not visible. */
+ bool GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const;
+ /** Returns true, if the button of the specified entry is visible in the window. */
+ bool IsButtonVisible( size_t nLevel, size_t nEntry ) const;
+
+ /** Returns true, if rPos is inside of a button or over the line of an expanded
+ group. The outline entry data is stored in the passed variables. */
+ bool ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const;
+ /** Returns true, if rPos is inside of a button.
+ The button data is stored in the passed variables. */
+ bool ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const;
+ /** Returns true, if rPos is over the line of an expanded group.
+ The outline entry data is stored in the passed variables. */
+ bool LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const;
+
+ /** Performs an action with the specified item.
+ @param nLevel The level of the entry.
+ @param nEntry The entry index or SC_OL_HEADERENTRY for the header entry. */
+ void DoFunction( size_t nLevel, size_t nEntry ) const;
+ /** Expands the specified entry (does nothing with header entries). */
+ void DoExpand( size_t nLevel, size_t nEntry ) const;
+ /** Collapses the specified entry (does nothing with header entries). */
+ void DoCollapse( size_t nLevel, size_t nEntry ) const;
+
+ /** Returns true, if the focused button is visible in the window. */
+ bool IsFocusButtonVisible() const;
+
+ /** Calculates index of next/previous focus button in the current level (no paint).
+ @param bFindVisible true = repeats until a visible button has been found.
+ @return true = focus wrapped from end to start or vice versa. */
+ bool ImplMoveFocusByEntry( bool bForward, bool bFindVisible );
+ /** Calculates position of focus button in next/previous level (no paint).
+ @return true = focus wrapped from end to start or vice versa. */
+ bool ImplMoveFocusByLevel( bool bForward );
+ /** Calculates position of focus button in tab order.
+ @param bFindVisible true = repeats until a visible button has been found.
+ @return true = focus wrapped from end to start or vice versa. */
+ bool ImplMoveFocusByTabOrder( bool bForward, bool bFindVisible );
+
+ /** If the focused entry is invisible, tries to move to visible position. */
+ void ImplMoveFocusToVisible( bool bForward );
+
+ /** Focuses next/previous button in the current level. */
+ void MoveFocusByEntry( bool bForward );
+ /** Focuses button in next/previous level. */
+ void MoveFocusByLevel( bool bForward );
+ /** Focuses next/previous button in tab order. */
+ void MoveFocusByTabOrder( bool bForward );
+
+ /** Starts mouse tracking after click on a button. */
+ void StartMouseTracking( size_t nLevel, size_t nEntry );
+ /** Returns whether mouse tracking mode is active. */
+ inline bool IsMouseTracking() const { return mbMTActive; }
+ /** Ends mouse tracking. */
+ void EndMouseTracking();
+
+ /** Sets a clip region for the window area without header. */
+ void SetEntryAreaClipRegion();
+ /** Converts coordinates to real window points and draws the line. */
+ void DrawLineRel(
+ long nLevelStart, long nEntryStart,
+ long nLevelEnd, long nEntryEnd );
+ /** Converts coordinates to real window points and draws the rectangle. */
+ void DrawRectRel(
+ long nLevelStart, long nEntryStart,
+ long nLevelEnd, long nEntryEnd );
+ /** Draws the specified image unpressed. */
+ void DrawImageRel( long nLevelPos, long nEntryPos, USHORT nId );
+ /** Draws a pressed or unpressed border. */
+ void DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed );
+
+ /** Draws the focus rectangle into the focused button. */
+ void ShowFocus();
+ /** Erases the focus rectangle from the focused button. */
+ void HideFocus();
+
+ /** Scrolls the specified range of the window in entry-relative direction. */
+ void ScrollRel( long nEntryDiff, long nEntryStart, long nEntryEnd );
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+
+ virtual void Resize();
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+
+ virtual void KeyInput( const KeyEvent& rKEvt );
+
+public:
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/opredlin.hrc b/sc/source/ui/inc/opredlin.hrc
new file mode 100644
index 000000000000..2b52d8b46118
--- /dev/null
+++ b/sc/source/ui/inc/opredlin.hrc
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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" // -> RID_SCPAGE_OPREDLINE
+
+#define FT_CONTENT 1
+#define FT_REMOVE 2
+#define FT_INSERT 3
+#define FT_MOVE 4
+#define GB_COLORCHGS 1
+#define CLB_CONTENT 1
+#define CLB_REMOVE 2
+#define CLB_INSERT 3
+#define CLB_MOVE 4
+#define STR_AUTHOR 1
diff --git a/sc/source/ui/inc/opredlin.hxx b/sc/source/ui/inc/opredlin.hxx
new file mode 100644
index 000000000000..0573ecb86f1e
--- /dev/null
+++ b/sc/source/ui/inc/opredlin.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SC_OPREDLIN_HXX
+#define _SC_OPREDLIN_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+
+#ifndef _FIELD_HXX //autogen
+#include <vcl/field.hxx>
+#endif
+
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#include <svtools/ctrlbox.hxx>
+#include <svx/fntctrl.hxx>
+#include <svx/strarray.hxx>
+
+/*-----------------------------------------------------------------------
+ Beschreibung: Redlining-Optionen
+ -----------------------------------------------------------------------*/
+
+class ScRedlineOptionsTabPage : public SfxTabPage
+{
+ FixedText aContentFT;
+ ColorListBox aContentColorLB;
+ FixedText aRemoveFT;
+ ColorListBox aRemoveColorLB;
+ FixedText aInsertFT;
+ ColorListBox aInsertColorLB;
+ FixedText aMoveFT;
+ ColorListBox aMoveColorLB;
+ FixedLine aChangedGB;
+ String aAuthorStr;
+ DECL_LINK( ColorHdl, ColorListBox *pColorLB );
+
+
+public:
+
+ ScRedlineOptionsTabPage( Window* pParent, const SfxItemSet& rSet );
+ ~ScRedlineOptionsTabPage();
+
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rAttrSet );
+
+ virtual BOOL FillItemSet( SfxItemSet& rSet );
+ virtual void Reset( const SfxItemSet& rSet );
+};
+#endif
+
+
diff --git a/sc/source/ui/inc/optdlg.hrc b/sc/source/ui/inc/optdlg.hrc
new file mode 100644
index 000000000000..27b8976e3541
--- /dev/null
+++ b/sc/source/ui/inc/optdlg.hrc
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 RID_SCDLG_OPTIONS 256
+#define RID_SCPAGE_VIEW 256
+#define RID_SCPAGE_USERLISTS 257
+#define RID_SCPAGE_CALC 258
+#define RID_SCPAGE_PRINT 259
+*/
+
+#define TP_GENERAL 1
+#define TP_SAVE 2
+#define TP_PATH 3
+#define TP_SPELL 4
+#define TP_VIEW 5
+#define TP_CALC 6
+#define TP_USERLISTS 7
+#define TP_PRINT 8
+#define TP_COLORS 9
+#define TP_GRID 10
+#define TP_CONTENT 11
+#define TP_LAYOUT 12
+#define TP_INPUT 13
+#define TP_CHANGES 14
+
+// TP_CALC:
+#define BTN_ITERATE 1
+#define FT_STEPS 2
+#define FT_EPS 3
+#define ED_STEPS 4
+#define ED_EPS 5
+#define GB_ZREFS 6
+#define ED_PREC 7
+#define FT_PREC 8
+#define BTN_DATESTD 9
+#define BTN_DATESC10 10
+#define BTN_DATE1904 11
+#define FT_VALUE 13
+#define GB_DATE 14
+#define BTN_CASE 15
+#define FT_CASE 16
+#define BTN_CALC 17
+#define BTN_MATCH 18
+#define BTN_LOOKUP 19
+#define BTN_REGEX 20
+#define BTN_GENERAL_PREC 21
+
+// TP_VIEW:
+#define BTN_VSCROLL 1
+#define BTN_HSCROLL 2
+#define BTN_REGISTER 3
+#define BTN_OUTLINER 4
+#define BTN_HEADERFOOTER 5
+#define BTN_GRID 6
+#define BTN_SYNTAX 7
+#define LB_GRIDCOLOR 9
+#define GB_ELEMENTS 10
+#define BTN_HELPLINES 11
+
+#define BTN_FORMULAS 20
+#define BTN_NULLVALS 21
+#define BTN_NOTES 22
+#define GB_CONTENTS 23
+
+//#define FT_OLE 31
+//#define FT_CHARTS 32
+//#define FT_DRAWINGS 33
+//#define LB_OLE 34
+//#define LB_CHARTS 35
+//#define LB_DRAWINGS 36
+//#define GB_OBJECTS 37
+
+
+// TP_USERLISTS:
+#define FT_LISTS 1
+#define LB_LISTS 1
+#define FT_ENTRIES 2
+#define ED_ENTRIES 2
+#define FT_COPYFROM 3
+#define ED_COPYFROM 3
+#define BTN_NEW 1
+#define BTN_ADD 2
+#define BTN_REMOVE 3
+#define BTN_COPY 4
+#define STR_QUERYREMOVE 5
+#define STR_DISMISS 6
+#define STR_COPYLIST 7
+#define STR_COPYFROM 8
+#define STR_COPYERR 9
+
+// TP_PRINT:
+#define FL_PAGES 1
+#define BTN_SKIPEMPTYPAGES 2
+#define FL_SHEETS 2
+#define BTN_SELECTEDSHEETS 4
+
+// TP_LCONTENT
+
+#define GB_DISPLAY 20
+#define CB_FORMULA 21
+#define CB_NIL 22
+#define CB_ANNOT 23
+#define CB_VALUE 24
+#define CB_ANCHOR 25
+#define GB_OBJECT 26
+#define FT_OBJGRF 27
+#define LB_OBJGRF 28
+#define FT_DIAGRAM 29
+#define LB_DIAGRAM 30
+#define FT_DRAW 31
+#define LB_DRAW 32
+#define CB_CLIP 33
+#define GB_ZOOM 34
+#define CB_SYNCZOOM 35
+
+// TP_LAYOUT
+#define GB_LINK 1
+#define RB_ALWAYS 2
+#define RB_REQUEST 3
+#define RB_NEVER 4
+#define CB_DOCONLY 5
+#define CB_MERGE_PARA_DIST 6
+#define GB_COMPAT 7
+#define CB_AUTO_UPDATE_FIELDS 8
+#define CB_AUTO_UPDATE_CHARTS 9
+#define FT_UPDATE_LINKS 10
+
+#define GB_WINDOW 50
+#define CB_ROWCOLHEADER 51
+#define CB_HSCROLL 52
+#define CB_VSCROLL 53
+#define CB_TBLREG 54
+#define CB_OUTLINE 55
+#define GB_LINES 56
+#define CB_GRID 57
+#define FT_COLOR 58
+#define LB_COLOR 59
+#define CB_GUIDELINE 60
+#define GB_UNIT 61
+#define LB_UNIT 62
+#define ST_UNIT 63
+#define GB_TAB 64
+#define MF_TAB 65
+#define CB_PAGEBREAKS 66
+#define CB_HANDLES 67
+#define CB_BIGHANDLES 68
+#define FT_TAB 69
+#define FT_UNIT 70
+#define FL_SEPARATOR1 71
+#define FL_SEPARATOR2 72
+#define FL_SEPARATOR 73
+#define FL_H_SEPARATOR 74
+// TP_INPUT
+
+#define GB_OPTIONS 70
+#define CB_ALIGN 71
+#define LB_ALIGN 72
+#define CB_EDITMODE 73
+#define CB_FORMAT 74
+#define CB_RFIND 75
+#define CB_EXPREF 76
+#define CB_MARKHDR 77
+#define CB_TEXTFMT 78
+#define CB_REPLWARN 79
+
diff --git a/sc/source/ui/inc/optload.hrc b/sc/source/ui/inc/optload.hrc
new file mode 100644
index 000000000000..992bb8c737e4
--- /dev/null
+++ b/sc/source/ui/inc/optload.hrc
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc" // -> RID_SCPAGE_OPREDLINE
+
+#define GB_LINK 1
+#define RB_ALWAYS 2
+#define RB_REQUEST 3
+#define RB_NEVER 4
+#define CB_DOCONLY 5
+#define CB_MERGE_PARA_DIST 6
+#define GB_COMPAT 7
+#define CB_AUTO_UPDATE_FIELDS 8
+#define CB_AUTO_UPDATE_CHARTS 9
+#define FT_UPDATE_LINKS 10
+
+
diff --git a/sc/source/ui/inc/optload.hxx b/sc/source/ui/inc/optload.hxx
new file mode 100644
index 000000000000..93d5fefa8358
--- /dev/null
+++ b/sc/source/ui/inc/optload.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _OPTLOAD_HXX
+#define _OPTLOAD_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#include <vcl/fixed.hxx>
+
+class ScDocument;
+
+class ScLoadOptPage : public SfxTabPage
+{
+private:
+ FixedText aLinkFT;
+ RadioButton aAlwaysRB;
+ RadioButton aRequestRB;
+ RadioButton aNeverRB;
+ CheckBox aDocOnlyCB;
+ GroupBox aLinkGB;
+ ScDocument *pDoc;
+
+ DECL_LINK( UpdateHdl, CheckBox* );
+
+public:
+ ScLoadOptPage( Window* pParent,
+ const SfxItemSet& rSet );
+ ~ScLoadOptPage();
+
+ static SfxTabPage* Create( Window* pParent,
+ const SfxItemSet& rAttrSet);
+
+ void SetDocument(ScDocument*);
+
+ virtual BOOL FillItemSet( SfxItemSet& rSet );
+ virtual void Reset( const SfxItemSet& rSet );
+};
+
+#endif
+
+
diff --git a/sc/source/ui/inc/optsolver.hrc b/sc/source/ui/inc/optsolver.hrc
new file mode 100644
index 000000000000..9df8eea1d7f4
--- /dev/null
+++ b/sc/source/ui/inc/optsolver.hrc
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+#define ED_OBJECTIVECELL 1
+#define ED_TARGET 2
+#define ED_VARIABLECELLS 3
+#define ED_LEFT1 4
+#define ED_LEFT2 5
+#define ED_LEFT3 6
+#define ED_LEFT4 7
+#define ED_RIGHT1 8
+#define ED_RIGHT2 9
+#define ED_RIGHT3 10
+#define ED_RIGHT4 11
+
+#define FT_OBJECTIVECELL 1
+#define FT_DIRECTION 2
+#define FT_VARIABLECELLS 3
+#define FT_CELLREF 4
+#define FT_OPERATOR 5
+#define FT_CONSTRAINT 6
+
+#define FT_PROGRESS 7
+#define FT_TIMELIMIT 8
+#define FT_NOSOLUTION 9
+#define FT_ERRORTEXT 10
+#define FT_SUCCESS 11
+#define FT_RESULT 12
+#define FT_QUESTION 13
+
+#define FL_CONDITIONS 1
+#define FL_BUTTONS 2
+
+#define IB_OBJECTIVECELL 1
+#define IB_TARGET 2
+#define IB_VARIABLECELLS 3
+#define IB_LEFT1 4
+#define IB_LEFT2 5
+#define IB_LEFT3 6
+#define IB_LEFT4 7
+#define IB_RIGHT1 8
+#define IB_RIGHT2 9
+#define IB_RIGHT3 10
+#define IB_RIGHT4 11
+#define IB_DELETE1 12
+#define IB_DELETE2 13
+#define IB_DELETE3 14
+#define IB_DELETE4 15
+
+#define LB_OP1 1
+#define LB_OP2 2
+#define LB_OP3 3
+#define LB_OP4 4
+
+#define RB_MAX 1
+#define RB_MIN 2
+#define RB_VALUE 3
+
+#define SB_SCROLL 1
+
+#define BTN_OPTIONS 1
+#define BTN_HELP 2
+#define BTN_CLOSE 3
+#define BTN_SOLVE 4
+#define BTN_OK 5
+#define BTN_CANCEL 6
+
+#define IMG_DEL_H 1
+
+#define STR_INVALIDINPUT 1
+#define STR_INVALIDCONDITION 2
+
diff --git a/sc/source/ui/inc/optsolver.hxx b/sc/source/ui/inc/optsolver.hxx
new file mode 100644
index 000000000000..bbd98f1d1818
--- /dev/null
+++ b/sc/source/ui/inc/optsolver.hxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OPTSOLVER_HXX
+#define SC_OPTSOLVER_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include "anyrefdg.hxx"
+#include <vcl/fixed.hxx>
+#include <vcl/group.hxx>
+#include <vcl/lstbox.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <vector>
+
+namespace com { namespace sun { namespace star {
+ namespace beans { struct PropertyValue; }
+} } }
+
+//============================================================================
+
+class ScCursorRefEdit : public formula::RefEdit
+{
+ Link maCursorUpLink;
+ Link maCursorDownLink;
+
+public:
+ ScCursorRefEdit( ScAnyRefDlg* pParent, const ResId& rResId );
+ void SetCursorLinks( const Link& rUp, const Link& rDown );
+
+protected:
+ virtual void KeyInput( const KeyEvent& rKEvt );
+};
+
+
+/// The dialog's content for a row, not yet parsed
+struct ScOptConditionRow
+{
+ String aLeftStr;
+ USHORT nOperator;
+ String aRightStr;
+
+ ScOptConditionRow() : nOperator(0) {}
+ bool IsDefault() const { return aLeftStr.Len() == 0 && aRightStr.Len() == 0 && nOperator == 0; }
+};
+
+/// All settings from the dialog, saved with the DocShell for the next call
+class ScOptSolverSave
+{
+ String maObjective;
+ BOOL mbMax;
+ BOOL mbMin;
+ BOOL mbValue;
+ String maTarget;
+ String maVariable;
+ std::vector<ScOptConditionRow> maConditions;
+ String maEngine;
+ com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> maProperties;
+
+public:
+ ScOptSolverSave( const String& rObjective, BOOL bMax, BOOL bMin, BOOL bValue,
+ const String& rTarget, const String& rVariable,
+ const std::vector<ScOptConditionRow>& rConditions,
+ const String& rEngine,
+ const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProperties );
+
+ const String& GetObjective() const { return maObjective; }
+ BOOL GetMax() const { return mbMax; }
+ BOOL GetMin() const { return mbMin; }
+ BOOL GetValue() const { return mbValue; }
+ const String& GetTarget() const { return maTarget; }
+ const String& GetVariable() const { return maVariable; }
+ const std::vector<ScOptConditionRow>& GetConditions() const { return maConditions; }
+ const String& GetEngine() const { return maEngine; }
+ const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& GetProperties() const
+ { return maProperties; }
+};
+
+class ScOptSolverDlg : public ScAnyRefDlg
+{
+public:
+ ScOptSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocShell* pDocSh, ScAddress aCursorPos );
+ ~ScOptSolverDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+ virtual BOOL Close();
+
+private:
+ FixedText maFtObjectiveCell;
+ formula::RefEdit maEdObjectiveCell;
+ formula::RefButton maRBObjectiveCell;
+
+ FixedText maFtDirection;
+ RadioButton maRbMax;
+ RadioButton maRbMin;
+ RadioButton maRbValue;
+ formula::RefEdit maEdTargetValue;
+ formula::RefButton maRBTargetValue;
+
+ FixedText maFtVariableCells;
+ formula::RefEdit maEdVariableCells;
+ formula::RefButton maRBVariableCells;
+
+ FixedLine maFlConditions;
+
+ FixedText maFtCellRef; // labels are together with controls for the first row
+ ScCursorRefEdit maEdLeft1;
+ formula::RefButton maRBLeft1;
+ FixedText maFtOperator;
+ ListBox maLbOp1;
+ FixedText maFtConstraint;
+ ScCursorRefEdit maEdRight1;
+ formula::RefButton maRBRight1;
+ ImageButton maBtnDel1;
+
+ ScCursorRefEdit maEdLeft2;
+ formula::RefButton maRBLeft2;
+ ListBox maLbOp2;
+ ScCursorRefEdit maEdRight2;
+ formula::RefButton maRBRight2;
+ ImageButton maBtnDel2;
+
+ ScCursorRefEdit maEdLeft3;
+ formula::RefButton maRBLeft3;
+ ListBox maLbOp3;
+ ScCursorRefEdit maEdRight3;
+ formula::RefButton maRBRight3;
+ ImageButton maBtnDel3;
+
+ ScCursorRefEdit maEdLeft4;
+ formula::RefButton maRBLeft4;
+ ListBox maLbOp4;
+ ScCursorRefEdit maEdRight4;
+ formula::RefButton maRBRight4;
+ ImageButton maBtnDel4;
+
+ ScrollBar maScrollBar;
+
+ FixedLine maFlButtons;
+
+ PushButton maBtnOpt;
+ HelpButton maBtnHelp;
+ CancelButton maBtnCancel;
+ PushButton maBtnSolve;
+
+ String maInputError;
+ String maConditionError;
+
+ ScDocShell* mpDocShell;
+ ScDocument* mpDoc;
+ const SCTAB mnCurTab;
+ formula::RefEdit* mpEdActive;
+ bool mbDlgLostFocus;
+
+ static const sal_uInt16 EDIT_ROW_COUNT = 4;
+ ScCursorRefEdit* mpLeftEdit[EDIT_ROW_COUNT];
+ formula::RefButton* mpLeftButton[EDIT_ROW_COUNT];
+ ScCursorRefEdit* mpRightEdit[EDIT_ROW_COUNT];
+ formula::RefButton* mpRightButton[EDIT_ROW_COUNT];
+ ListBox* mpOperator[EDIT_ROW_COUNT];
+ ImageButton* mpDelButton[EDIT_ROW_COUNT];
+
+ std::vector<ScOptConditionRow> maConditions;
+ long nScrollPos;
+
+ com::sun::star::uno::Sequence<rtl::OUString> maImplNames;
+ com::sun::star::uno::Sequence<rtl::OUString> maDescriptions;
+ String maEngine;
+ com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> maProperties;
+
+ void Init(const ScAddress& rCursorPos);
+ bool CallSolver();
+ void ReadConditions();
+ void ShowConditions();
+ void EnableButtons();
+ bool ParseRef( ScRange& rRange, const String& rInput, bool bAllowRange );
+ bool FindTimeout( sal_Int32& rTimeout );
+ void ShowError( bool bCondition, formula::RefEdit* pFocus );
+
+ DECL_LINK( BtnHdl, PushButton* );
+ DECL_LINK( DelBtnHdl, PushButton* );
+ DECL_LINK( GetFocusHdl, Control* );
+ DECL_LINK( LoseFocusHdl, Control* );
+ DECL_LINK( ScrollHdl, ScrollBar* );
+ DECL_LINK( CursorUpHdl, ScCursorRefEdit* );
+ DECL_LINK( CursorDownHdl, ScCursorRefEdit* );
+ DECL_LINK( CondModifyHdl, Edit* );
+ DECL_LINK( TargetModifyHdl, Edit* );
+ DECL_LINK( SelectHdl, ListBox* );
+};
+
+
+class ScSolverProgressDialog : public ModelessDialog
+{
+ FixedText maFtProgress;
+ FixedText maFtTime;
+ FixedLine maFlButtons;
+ OKButton maBtnOk;
+
+public:
+ ScSolverProgressDialog( Window* pParent );
+ ~ScSolverProgressDialog();
+
+ void HideTimeLimit();
+ void SetTimeLimit( sal_Int32 nSeconds );
+};
+
+class ScSolverNoSolutionDialog : public ModalDialog
+{
+ FixedText maFtNoSolution;
+ FixedText maFtErrorText;
+ FixedLine maFlButtons;
+ OKButton maBtnOk;
+
+public:
+ ScSolverNoSolutionDialog( Window* pParent, const String& rErrorText );
+ ~ScSolverNoSolutionDialog();
+};
+
+class ScSolverSuccessDialog : public ModalDialog
+{
+ FixedText maFtSuccess;
+ FixedText maFtResult;
+ FixedText maFtQuestion;
+ FixedLine maFlButtons;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+
+public:
+ ScSolverSuccessDialog( Window* pParent, const String& rSolution );
+ ~ScSolverSuccessDialog();
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
new file mode 100644
index 000000000000..42844513af92
--- /dev/null
+++ b/sc/source/ui/inc/output.hxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OUTPUT_HXX
+#define SC_OUTPUT_HXX
+
+#include "address.hxx"
+#include <tools/list.hxx>
+#include <tools/color.hxx>
+#include <tools/fract.hxx>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+
+class Rectangle;
+class Font;
+class OutputDevice;
+class Window;
+class EditEngine;
+class ScDocument;
+class ScBaseCell;
+class ScPatternAttr;
+class SvxMarginItem;
+class SdrObject;
+class SdrOle2Obj;
+struct RowInfo;
+struct ScTableInfo;
+class ScTabViewShell;
+class ScPageBreakData;
+class FmFormView;
+
+// #i74769# SdrPaintWindow predefine
+class SdrPaintWindow;
+
+// ---------------------------------------------------------------------------
+
+#define SC_SCENARIO_HSPACE 60
+#define SC_SCENARIO_VSPACE 50
+
+// ---------------------------------------------------------------------------
+
+#define SC_OBJECTS_NONE 0
+#define SC_OBJECTS_DRAWING 1
+#define SC_OBJECTS_OLE 2
+#define SC_OBJECTS_CHARTS 4
+#define SC_OBJECTS_ALL ( SC_OBJECTS_DRAWING | SC_OBJECTS_OLE | SC_OBJECTS_CHARTS )
+
+enum ScOutputType { OUTTYPE_WINDOW, OUTTYPE_PRINTER };
+
+class ScOutputData
+{
+friend class ScDrawStringsVars;
+private:
+ struct OutputAreaParam
+ {
+ Rectangle maAlignRect;
+ Rectangle maClipRect;
+ long mnColWidth;
+ bool mbLeftClip;
+ bool mbRightClip;
+ };
+
+ OutputDevice* pDev; // Device
+ OutputDevice* pRefDevice; // printer if used for preview
+ OutputDevice* pFmtDevice; // reference for text formatting
+ ScTableInfo& mrTabInfo;
+ RowInfo* pRowInfo; // Info-Block
+ SCSIZE nArrCount; // belegte Zeilen im Info-Block
+ ScDocument* pDoc; // Dokument
+ SCTAB nTab; // Tabelle
+ long nScrX; // Ausgabe Startpos. (Pixel)
+ long nScrY;
+ long nScrW; // Ausgabe Groesse (Pixel)
+ long nScrH;
+ long nMirrorW; // Visible output width for mirroring (default: nScrW)
+ SCCOL nX1; // Start-/Endkoordinaten
+ SCROW nY1; // ( incl. versteckte )
+ SCCOL nX2;
+ SCROW nY2;
+ SCCOL nVisX1; // Start-/Endkoordinaten
+ SCROW nVisY1; // ( sichtbarer Bereich )
+ SCCOL nVisX2;
+ SCROW nVisY2;
+ ScOutputType eType; // Bildschirm/Drucker ...
+ double nPPTX; // Pixel per Twips
+ double nPPTY;
+// USHORT nZoom; // Zoom-Faktor (Prozent) - fuer GetFont
+ Fraction aZoomX;
+ Fraction aZoomY;
+
+ SdrObject* pEditObj; // beim Painten auslassen
+
+ ScTabViewShell* pViewShell; // zum Connecten von sichtbaren Plug-Ins
+
+ // #114135#
+ FmFormView* pDrawView; // SdrView to paint to
+
+ BOOL bEditMode; // InPlace editierte Zelle - nicht ausgeben
+ SCCOL nEditCol;
+ SCROW nEditRow;
+
+ BOOL bMetaFile; // Ausgabe auf Metafile (nicht in Pixeln!)
+ BOOL bSingleGrid; // beim Gitter bChanged auswerten
+
+ BOOL bPagebreakMode; // Seitenumbruch-Vorschau
+ BOOL bSolidBackground; // weiss statt transparent
+
+ BOOL bUseStyleColor;
+ BOOL bForceAutoColor;
+
+ BOOL bSyntaxMode; // Syntax-Highlighting
+ Color* pValueColor;
+ Color* pTextColor;
+ Color* pFormulaColor;
+
+ Color aGridColor;
+
+ BOOL bShowNullValues;
+ BOOL bShowFormulas;
+ BOOL bShowSpellErrors; // Spell-Errors in EditObjekten anzeigen
+ BOOL bMarkClipped;
+
+ BOOL bSnapPixel;
+
+ BOOL bAnyRotated; // intern
+ BOOL bAnyClipped; // intern
+ BOOL bTabProtected;
+ BYTE nTabTextDirection; // EEHorizontalTextDirection values
+ BOOL bLayoutRTL;
+
+ // #i74769# use SdrPaintWindow direct, remember it during BeginDrawLayers/EndDrawLayers
+ SdrPaintWindow* mpTargetPaintWindow;
+
+ // private methods
+
+ BOOL GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
+ SCCOL& rOverX, SCROW& rOverY, BOOL bVisRowChanged );
+ BOOL IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY );
+ void GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell*& rpCell );
+
+ BOOL IsAvailable( SCCOL nX, SCROW nY );
+
+ void GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
+ SCCOL nCellX, SCROW nCellY, long nNeeded,
+ const ScPatternAttr& rPattern,
+ USHORT nHorJustify, bool bCellIsValue,
+ bool bBreak, bool bOverwrite,
+ OutputAreaParam& rParam );
+
+ void ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect,
+ long nLeftM, long nTopM, long nRightM, long nBottomM,
+ BOOL bWidth, USHORT nOrient, long nAttrRotate, BOOL bPixelToLogic,
+ long& rEngineWidth, long& rEngineHeight, long& rNeededPixel,
+ bool& rLeftClip, bool& rRightClip );
+
+ void SetSyntaxColor( Font* pFont, ScBaseCell* pCell );
+ void SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell );
+
+ double GetStretch();
+
+ void DrawRotatedFrame( const Color* pForceColor ); // pixel
+
+public:
+ ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
+ ScTableInfo& rTabInfo, ScDocument* pNewDoc,
+ SCTAB nNewTab, long nNewScrX, long nNewScrY,
+ SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2,
+ double nPixelPerTwipsX, double nPixelPerTwipsY,
+ const Fraction* pZoomX = NULL,
+ const Fraction* pZoomY = NULL );
+
+ ~ScOutputData();
+
+ void SetContentDevice( OutputDevice* pContentDev );
+
+ void SetRefDevice( OutputDevice* pRDev ) { pRefDevice = pFmtDevice = pRDev; }
+ void SetFmtDevice( OutputDevice* pRDev ) { pFmtDevice = pRDev; }
+ void SetEditObject( SdrObject* pObj ) { pEditObj = pObj; }
+ void SetViewShell( ScTabViewShell* pSh ) { pViewShell = pSh; }
+
+ // #114135#
+ void SetDrawView( FmFormView* pNew ) { pDrawView = pNew; }
+
+ void SetSolidBackground( BOOL bSet ) { bSolidBackground = bSet; }
+ void SetUseStyleColor( BOOL bSet ) { bUseStyleColor = bSet; }
+
+ void SetEditCell( SCCOL nCol, SCROW nRow );
+ void SetSyntaxMode( BOOL bNewMode );
+ void SetMetaFileMode( BOOL bNewMode );
+ void SetSingleGrid( BOOL bNewMode );
+ void SetGridColor( const Color& rColor );
+ void SetMarkClipped( BOOL bSet );
+ void SetShowNullValues ( BOOL bSet = TRUE );
+ void SetShowFormulas ( BOOL bSet = TRUE );
+ void SetShowSpellErrors( BOOL bSet = TRUE );
+ void SetMirrorWidth( long nNew );
+ long GetScrW() const { return nScrW; }
+ long GetScrH() const { return nScrH; }
+
+ void SetSnapPixel( BOOL bSet = TRUE );
+
+ void DrawGrid( BOOL bGrid, BOOL bPage );
+ void DrawStrings( BOOL bPixelToLogic = FALSE );
+ void DrawBackground();
+ void DrawShadow();
+ void DrawExtraShadow(BOOL bLeft, BOOL bTop, BOOL bRight, BOOL bBottom);
+ void DrawFrame();
+
+ // with logic MapMode set!
+ void DrawEdit(BOOL bPixelToLogic);
+
+ void FindRotated();
+ void DrawRotated(BOOL bPixelToLogic); // logisch
+
+ void DrawClear();
+
+ // #i72502# printer only command set
+ Point PrePrintDrawingLayer(long nLogStX, long nLogStY );
+ void PostPrintDrawingLayer(const Point& rMMOffset); // #i74768# need offset for FormLayer
+ void PrintDrawingLayer(const sal_uInt16 nLayer, const Point& rMMOffset);
+
+ // nur Bildschirm:
+ void DrawingSingle(const sal_uInt16 nLayer);
+ void DrawSelectiveObjects(const sal_uInt16 nLayer);
+
+ BOOL SetChangedClip(); // FALSE = nix
+ PolyPolygon GetChangedArea();
+
+ void FindChanged();
+ void SetPagebreakMode( ScPageBreakData* pPageData );
+#ifdef OLD_SELECTION_PAINT
+ void DrawMark( Window* pWin );
+#endif
+ void DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
+ SCCOL nRefEndX, SCROW nRefEndY,
+ const Color& rColor, BOOL bHandle );
+ void DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
+ SCCOL nRefEndX, SCROW nRefEndY,
+ const Color& rColor, USHORT nType );
+ void DrawChangeTrack();
+ void DrawClipMarks();
+
+ void DrawNoteMarks();
+ void AddPDFNotes();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/pagedata.hxx b/sc/source/ui/inc/pagedata.hxx
new file mode 100644
index 000000000000..bcd85c8f5a96
--- /dev/null
+++ b/sc/source/ui/inc/pagedata.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PAGEDATA_HXX
+#define SC_PAGEDATA_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+
+class ScDocShell;
+
+//============================================================================
+
+class ScPrintRangeData
+{
+private:
+ ScRange aPrintRange;
+ size_t nPagesX;
+ SCCOL* pPageEndX;
+ size_t nPagesY;
+ SCROW* pPageEndY;
+ long nFirstPage;
+ BOOL bTopDown;
+ BOOL bAutomatic;
+
+public:
+ ScPrintRangeData();
+ ~ScPrintRangeData();
+
+ void SetPrintRange( const ScRange& rNew ) { aPrintRange = rNew; }
+ const ScRange& GetPrintRange() const { return aPrintRange; }
+
+ void SetPagesX( size_t nCount, const SCCOL* pEnd );
+ void SetPagesY( size_t nCount, const SCROW* pEnd );
+
+ size_t GetPagesX() const { return nPagesX; }
+ const SCCOL* GetPageEndX() const { return pPageEndX; }
+ size_t GetPagesY() const { return nPagesY; }
+ const SCROW* GetPageEndY() const { return pPageEndY; }
+
+ void SetFirstPage( long nNew ) { nFirstPage = nNew; }
+ long GetFirstPage() const { return nFirstPage; }
+ void SetTopDown( BOOL bSet ) { bTopDown = bSet; }
+ BOOL IsTopDown() const { return bTopDown; }
+ void SetAutomatic( BOOL bSet ) { bAutomatic = bSet; }
+ BOOL IsAutomatic() const { return bAutomatic; }
+};
+
+class ScPageBreakData
+{
+private:
+ size_t nAlloc;
+ size_t nUsed;
+ ScPrintRangeData* pData; // Array
+
+public:
+ ScPageBreakData(size_t nMax);
+ ~ScPageBreakData();
+
+ size_t GetCount() const { return nUsed; }
+ ScPrintRangeData& GetData(size_t i);
+
+ BOOL IsEqual( const ScPageBreakData& rOther ) const;
+
+ void AddPages();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/parawin.hxx b/sc/source/ui/inc/parawin.hxx
new file mode 100644
index 000000000000..ae02fdb38114
--- /dev/null
+++ b/sc/source/ui/inc/parawin.hxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PARAWIN_HXX
+#define SC_PARAWIN_HXX
+
+#include "funcutl.hxx"
+#include "global.hxx" // ScAddress
+#include <svtools/stdctrl.hxx>
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#include <vcl/group.hxx>
+#include <svtools/svmedit.hxx>
+#include <vcl/tabpage.hxx>
+
+#ifndef _SVSTDARR_STRINGS
+
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+
+#endif
+#include <vcl/tabctrl.hxx>
+
+#include <vector>
+
+class ScFuncDesc;
+
+//============================================================================
+#define NOT_FOUND 0xffff
+//============================================================================
+
+class ScParaWin : public TabPage
+{
+private:
+
+ Link aScrollLink;
+ Link aFxLink;
+ Link aArgModifiedLink;
+
+ ::std::vector<USHORT> aVisibleArgMapping;
+ const ScFuncDesc* pFuncDesc;
+ ScAnyRefDlg* pMyParent;
+ USHORT nArgs; // unsuppressed arguments
+ Font aFntBold;
+ Font aFntLight;
+
+ FixedInfo aFtEditDesc;
+ FixedText aFtArgName;
+ FixedInfo aFtArgDesc;
+
+ ImageButton aBtnFx1;
+ FixedText aFtArg1;
+ ArgEdit aEdArg1;
+ formula::RefButton aRefBtn1;
+ ImageButton aBtnFx2;
+ FixedText aFtArg2;
+ ArgEdit aEdArg2;
+ formula::RefButton aRefBtn2;
+ ImageButton aBtnFx3;
+ FixedText aFtArg3;
+ ArgEdit aEdArg3;
+ formula::RefButton aRefBtn3;
+ ImageButton aBtnFx4;
+ FixedText aFtArg4;
+ ArgEdit aEdArg4;
+ formula::RefButton aRefBtn4;
+ ScrollBar aSlider;
+ BOOL bRefMode;
+
+ USHORT nEdFocus;
+ USHORT nActiveLine;
+
+ ArgInput aArgInput[4];
+ String aDefaultString;
+ SvStrings aParaArray;
+ DECL_LINK( ScrollHdl, ScrollBar* );
+ DECL_LINK( ModifyHdl, ArgInput* );
+ DECL_LINK( GetEdFocusHdl, ArgInput* );
+ DECL_LINK( GetFxFocusHdl, ArgInput* );
+ DECL_LINK( GetFxHdl, ArgInput* );
+
+protected:
+
+ virtual void SliderMoved();
+ virtual void ArgumentModified();
+ virtual void FxClick();
+
+ void InitArgInput( USHORT nPos, FixedText& rFtArg, ImageButton& rBtnFx,
+ ArgEdit& rEdArg, formula::RefButton& rRefBtn);
+
+ void DelParaArray();
+ void SetArgumentDesc(const String& aText);
+ void SetArgumentText(const String& aText);
+
+
+ void SetArgName (USHORT no,const String &aArg);
+ void SetArgNameFont (USHORT no,const Font&);
+ void SetArgVal (USHORT no,const String &aArg);
+
+ void HideParaLine(USHORT no);
+ void ShowParaLine(USHORT no);
+ void UpdateArgDesc( USHORT nArg );
+ void UpdateArgInput( USHORT nOffset, USHORT i );
+
+public:
+ ScParaWin(ScAnyRefDlg* pParent,Point aPos);
+ ~ScParaWin();
+
+ void SetFunctionDesc(const ScFuncDesc* pFDesc);
+ void SetArgumentOffset(USHORT nOffset);
+ void SetEditDesc(const String& aText);
+ void UpdateParas();
+ void ClearAll();
+
+ BOOL IsRefMode() {return bRefMode;}
+ void SetRefMode(BOOL bFlag) {bRefMode=bFlag;}
+
+ USHORT GetActiveLine();
+ void SetActiveLine(USHORT no);
+ formula::RefEdit* GetActiveEdit();
+ String GetActiveArgName();
+
+ String GetArgument(USHORT no);
+ void SetArgument(USHORT no, const String& aString);
+ void SetArgumentFonts(const Font&aBoldFont,const Font&aLightFont);
+
+ void SetEdFocus(USHORT nEditLine); //Sichtbare Editzeilen
+ USHORT GetSliderPos();
+ void SetSliderPos(USHORT nSliderPos);
+
+ void SetScrollHdl( const Link& rLink ) { aScrollLink = rLink; }
+ const Link& GetScrollHdl() const { return aScrollLink; }
+
+ void SetArgModifiedHdl( const Link& rLink ) { aArgModifiedLink = rLink; }
+ const Link& GetArgModifiedHdl() const { return aArgModifiedLink; }
+
+ void SetFxHdl( const Link& rLink ) { aFxLink = rLink; }
+ const Link& GetFxHdl() const { return aFxLink; }
+};
+
+
+
+
+
+#endif // SC_PARAWIN_HXX
+
diff --git a/sc/source/ui/inc/pfiltdlg.hxx b/sc/source/ui/inc/pfiltdlg.hxx
new file mode 100644
index 000000000000..426f95399b33
--- /dev/null
+++ b/sc/source/ui/inc/pfiltdlg.hxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PFILTDLG_HXX
+#define SC_PFILTDLG_HXX
+
+#ifndef _SV_HXX
+#endif
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#include <svtools/stdctrl.hxx>
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+#include "address.hxx"
+#include "queryparam.hxx"
+
+//------------------------------------------------------------------
+
+class ScViewData;
+class ScDocument;
+class ScQueryItem;
+class TypedScStrCollection;
+
+//==================================================================
+
+class ScPivotFilterDlg : public ModalDialog
+{
+public:
+ ScPivotFilterDlg( Window* pParent,
+ const SfxItemSet& rArgSet, SCTAB nSourceTab );
+ ~ScPivotFilterDlg();
+
+ const ScQueryItem& GetOutputItem();
+
+private:
+ FixedLine aFlCriteria;
+ //----------------------------
+ ListBox aLbField1;
+ ListBox aLbCond1;
+ ComboBox aEdVal1;
+ //----------------------------
+ ListBox aLbConnect1;
+ ListBox aLbField2;
+ ListBox aLbCond2;
+ ComboBox aEdVal2;
+ //----------------------------
+ ListBox aLbConnect2;
+ ListBox aLbField3;
+ ListBox aLbCond3;
+ ComboBox aEdVal3;
+ //----------------------------
+ FixedText aFtConnect;
+ FixedText aFtField;
+ FixedText aFtCond;
+ FixedText aFtVal;
+
+ FixedLine aFlOptions;
+ CheckBox aBtnCase;
+ CheckBox aBtnRegExp;
+ CheckBox aBtnUnique;
+ FixedText aFtDbAreaLabel;
+ FixedInfo aFtDbArea;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ MoreButton aBtnMore;
+ const String aStrUndefined;
+ const String aStrNoName;
+ const String aStrNone;
+ const String aStrEmpty;
+ const String aStrNotEmpty;
+ const String aStrRow;
+ const String aStrColumn;
+
+ const USHORT nWhichQuery;
+ const ScQueryParam theQueryData;
+ ScQueryItem* pOutItem;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ SCTAB nSrcTab;
+
+ USHORT nFieldCount;
+ ComboBox* aValueEdArr[3];
+ ListBox* aFieldLbArr[3];
+ ListBox* aCondLbArr[3];
+
+ TypedScStrCollection* pEntryLists[MAXCOLCOUNT];
+
+#ifdef _PFILTDLG_CXX
+private:
+ void Init ( const SfxItemSet& rArgSet );
+ void FillFieldLists ();
+ void UpdateValueList ( USHORT nList );
+ void ClearValueList ( USHORT nList );
+ USHORT GetFieldSelPos ( SCCOL nField );
+
+ // Handler:
+ DECL_LINK( LbSelectHdl, ListBox* );
+ DECL_LINK( ValModifyHdl, ComboBox* );
+ DECL_LINK( CheckBoxHdl, CheckBox* );
+#endif
+};
+
+
+#endif // SC_PFILTDLG_HXX
+
diff --git a/sc/source/ui/inc/pfuncache.hxx b/sc/source/ui/inc/pfuncache.hxx
new file mode 100644
index 000000000000..365df0acc38b
--- /dev/null
+++ b/sc/source/ui/inc/pfuncache.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PFUNCACHE_HXX
+#define SC_PFUNCACHE_HXX
+
+#include <vector>
+#include <tools/gen.hxx>
+#include "rangelst.hxx"
+#include "printopt.hxx"
+
+class ScDocShell;
+class ScMarkData;
+
+
+/** Possible types of selection for print functions */
+
+enum ScPrintSelectionMode
+{
+ SC_PRINTSEL_INVALID,
+ SC_PRINTSEL_DOCUMENT,
+ SC_PRINTSEL_CURSOR,
+ SC_PRINTSEL_RANGE,
+ SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS
+};
+
+
+/** Stores the selection in the ScPrintFuncCache so it is only used
+ for the same selection again. */
+
+class ScPrintSelectionStatus
+{
+ ScPrintSelectionMode eMode;
+ ScRangeList aRanges;
+ ScPrintOptions aOptions;
+
+public:
+ ScPrintSelectionStatus() : eMode(SC_PRINTSEL_INVALID) {}
+ ~ScPrintSelectionStatus() {}
+
+ void SetMode(ScPrintSelectionMode eNew) { eMode = eNew; }
+ void SetRanges(const ScRangeList& rNew) { aRanges = rNew; }
+ void SetOptions(const ScPrintOptions& rNew) { aOptions = rNew; }
+
+ BOOL operator==(const ScPrintSelectionStatus& rOther) const
+ { return eMode == rOther.eMode && aRanges == rOther.aRanges && aOptions == rOther.aOptions; }
+
+ ScPrintSelectionMode GetMode() const { return eMode; }
+ const ScPrintOptions& GetOptions() const { return aOptions; }
+};
+
+
+/** The range that is printed on a page (excluding repeated columns/rows),
+ and its position on the page, used to find hyperlink targets. */
+
+struct ScPrintPageLocation
+{
+ long nPage;
+ ScRange aCellRange;
+ Rectangle aRectangle; // pixels
+
+ ScPrintPageLocation() :
+ nPage(-1) {} // default: invalid
+
+ ScPrintPageLocation( long nP, const ScRange& rRange, const Rectangle& rRect ) :
+ nPage(nP), aCellRange(rRange), aRectangle(rRect) {}
+};
+
+
+/** Stores the data for printing that is needed from several sheets,
+ so it doesn't have to be calculated for rendering each page. */
+
+class ScPrintFuncCache
+{
+ ScPrintSelectionStatus aSelection;
+ ScDocShell* pDocSh;
+ long nTotalPages;
+ long nPages[MAXTABCOUNT];
+ long nFirstAttr[MAXTABCOUNT];
+ std::vector<ScPrintPageLocation> aLocations;
+ bool bLocInitialized;
+
+public:
+ ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark,
+ const ScPrintSelectionStatus& rStatus );
+ ~ScPrintFuncCache();
+
+ BOOL IsSameSelection( const ScPrintSelectionStatus& rStatus ) const;
+
+ void InitLocations( const ScMarkData& rMark, OutputDevice* pDev );
+ bool FindLocation( const ScAddress& rCell, ScPrintPageLocation& rLocation ) const;
+
+ long GetPageCount() const { return nTotalPages; }
+ long GetFirstAttr( SCTAB nTab ) const { return nFirstAttr[nTab]; }
+ SCTAB GetTabForPage( long nPage ) const;
+ long GetTabStart( SCTAB nTab ) const;
+ long GetDisplayStart( SCTAB nTab ) const;
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/pgbrksh.hxx b/sc/source/ui/inc/pgbrksh.hxx
new file mode 100644
index 000000000000..f367b4cc4f1f
--- /dev/null
+++ b/sc/source/ui/inc/pgbrksh.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PGBRKSH_HXX
+#define SC_PGBRKSH_HXX
+
+#include <sfx2/module.hxx>
+#include <sfx2/shell.hxx>
+
+#include "shellids.hxx"
+
+class ScTabViewShell;
+
+class ScPageBreakShell : public SfxShell
+{
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_PAGEBREAK_SHELL)
+
+ ScPageBreakShell( ScTabViewShell* pView );
+ ~ScPageBreakShell();
+
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/pivotsh.hxx b/sc/source/ui/inc/pivotsh.hxx
new file mode 100644
index 000000000000..2d3a21fa9756
--- /dev/null
+++ b/sc/source/ui/inc/pivotsh.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PIVOTSH_HXX
+#define SC_PIVOTSH_HXX
+
+#include <sfx2/module.hxx>
+#include <sfx2/shell.hxx>
+
+#include "shellids.hxx"
+
+class ScTabViewShell;
+class ScDPObject;
+
+class ScPivotShell : public SfxShell
+{
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_PIVOT_SHELL)
+
+ ScPivotShell( ScTabViewShell* pView );
+ ~ScPivotShell();
+
+ void Execute ( SfxRequest& rReq );
+ void GetState( SfxItemSet& rSet );
+
+private:
+ ScTabViewShell* pViewShell;
+
+ ScDPObject* GetCurrDPObject();
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/pntlock.hxx b/sc/source/ui/inc/pntlock.hxx
new file mode 100644
index 000000000000..60a7502c9734
--- /dev/null
+++ b/sc/source/ui/inc/pntlock.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PNTLOCK_HXX
+#define SC_PNTLOCK_HXX
+
+#include "rangelst.hxx"
+
+class ScPaintLockData
+{
+private:
+ ScRangeListRef xRangeList;
+ USHORT nMode;
+ USHORT nLevel;
+ USHORT nDocLevel;
+ USHORT nParts;
+ BOOL bModified;
+
+public:
+ ScPaintLockData(USHORT nNewMode);
+ ~ScPaintLockData();
+
+ void AddRange( const ScRange& rRange, USHORT nP );
+
+ void SetModified() { bModified = TRUE; }
+ void IncLevel(sal_Bool bDoc)
+ { if (bDoc) ++nDocLevel; else ++nLevel; }
+ void DecLevel(sal_Bool bDoc)
+ { if (bDoc) --nDocLevel; else --nLevel; }
+
+ const ScRangeListRef& GetRangeList() const { return xRangeList; }
+ USHORT GetParts() const { return nParts; }
+ USHORT GetLevel(sal_Bool bDoc) const
+ { return bDoc ? nDocLevel : nLevel; }
+ BOOL GetModified() const { return bModified; }
+
+ // fuer Wiederherstellen nach Reset
+ void SetLevel(USHORT nNew, sal_Bool bDoc)
+ { if (bDoc) nDocLevel = nNew; else nLevel = nNew; }
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/popmenu.hxx b/sc/source/ui/inc/popmenu.hxx
new file mode 100644
index 000000000000..8ac0fba4e80d
--- /dev/null
+++ b/sc/source/ui/inc/popmenu.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_POPMENU_HXX
+#define SC_POPMENU_HXX
+
+#ifndef _MENU_HXX //autogen
+#include <vcl/menu.hxx>
+#endif
+#include "scdllapi.h"
+
+class SC_DLLPUBLIC ScPopupMenu : public PopupMenu
+{
+private:
+ USHORT nSel;
+ BOOL bHit;
+protected:
+ virtual void Select();
+public:
+ ScPopupMenu() : nSel(0),bHit(FALSE) {}
+ ScPopupMenu(const ResId& rRes) : PopupMenu(rRes),nSel(0),bHit(FALSE) {}
+ USHORT GetSelected() const { return nSel; }
+ BOOL WasHit() const { return bHit; }
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/preview.hxx b/sc/source/ui/inc/preview.hxx
new file mode 100644
index 000000000000..87d15dcdaf86
--- /dev/null
+++ b/sc/source/ui/inc/preview.hxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_PREVIEW_HXX
+#define SC_PREVIEW_HXX
+
+
+#include <vcl/window.hxx>
+#include "printfun.hxx" // ScPrintState
+
+class ScDocShell;
+class ScPreviewShell;
+class FmFormView;
+
+class ScPreview : public Window
+{
+private:
+ // eingestellt:
+ long nPageNo; // Seite im Dokument
+ USHORT nZoom; // eingestellter Zoom
+ Point aOffset; // positiv
+
+ // berechnet:
+ BOOL bValid; // folgende Werte gueltig
+ SCTAB nTabCount;
+ SCTAB nTabsTested; // fuer wieviele Tabellen ist nPages gueltig?
+ long nPages[MAXTABCOUNT];
+ long nFirstAttr[MAXTABCOUNT];
+ SCTAB nTab; // Tabelle
+ long nTabPage; // Seite von Tabelle
+ long nTabStart; // erste Seite der Tabelle (wirklich)
+ long nDisplayStart; // dito, relativ zum Anfang der Zaehlung
+ Date aDate;
+ Time aTime;
+ long nTotalPages;
+ Size aPageSize; // fuer GetOptimalZoom
+ BOOL bStateValid;
+ BOOL bLocationValid;
+ ScPrintState aState;
+ ScPreviewLocationData* pLocationData; // stores table layout for accessibility API
+ FmFormView* pDrawView;
+
+ // intern:
+ BOOL bInPaint;
+ BOOL bInGetState;
+ ScDocShell* pDocShell;
+ ScPreviewShell* pViewShell;
+
+ BOOL bLeftRulerMove;
+ BOOL bRightRulerMove;
+ BOOL bTopRulerMove;
+ BOOL bBottomRulerMove;
+ BOOL bHeaderRulerMove;
+ BOOL bFooterRulerMove;
+
+ BOOL bLeftRulerChange;
+ BOOL bRightRulerChange;
+ BOOL bTopRulerChange;
+ BOOL bBottomRulerChange;
+ BOOL bHeaderRulerChange;
+ BOOL bFooterRulerChange;
+ BOOL bPageMargin;
+ BOOL bColRulerMove;
+ ScRange aPageArea;
+ long nRight[ MAXCOL+1 ];
+ long nLeftPosition;
+ long mnScale;
+ SCCOL nColNumberButttonDown;
+ Point aButtonDownChangePoint;
+ Point aButtonDownPt;
+ Point aButtonUpPt;
+ long nHeaderHeight;
+ long nFooterHeight;
+
+ void TestLastPage();
+ void CalcPages( SCTAB nToWhichTab );
+ void RecalcPages();
+ void UpdateDrawView();
+ void DoPrint( ScPreviewLocationData* pFillLocation );
+
+ void InvalidateLocationData( ULONG nId );
+
+ using Window::SetZoom;
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+public:
+ ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh );
+ ~ScPreview();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ void DataChanged(BOOL bNewTime = FALSE); // statt Invalidate rufen
+ void DoInvalidate();
+
+ void SetXOffset( long nX );
+ void SetYOffset( long nY );
+ void SetZoom(USHORT nNewZoom);
+ void SetPageNo( long nPage );
+
+ BOOL GetPageMargins()const { return bPageMargin; }
+ void SetPageMargins( BOOL bVal ) { bPageMargin = bVal; }
+ void DrawInvert( long nDragPos, USHORT nFlags );
+ void DragMove( long nDragMovePos, USHORT nFlags );
+
+
+ const ScPreviewLocationData& GetLocationData();
+
+ String GetPosString();
+
+ long GetPageNo() const { return nPageNo; }
+ USHORT GetZoom() const { return nZoom; }
+ Point GetOffset() const { return aOffset; }
+
+ SCTAB GetTab() { if (!bValid) { CalcPages(0); RecalcPages(); } return nTab; }
+ long GetTotalPages() { if (!bValid) { CalcPages(0); RecalcPages(); } return nTotalPages; }
+
+ BOOL AllTested() const { return bValid && nTabsTested >= nTabCount; }
+
+ USHORT GetOptimalZoom(BOOL bWidthOnly);
+ long GetFirstPage(SCTAB nTab);
+
+ void CalcAll() { CalcPages(MAXTAB); }
+ void SetInGetState(BOOL bSet) { bInGetState = bSet; }
+
+ DECL_STATIC_LINK( ScPreview, InvalidateHdl, void* );
+ static void StaticInvalidate();
+
+ FmFormView* GetDrawView() { return pDrawView; }
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/prevloc.hxx b/sc/source/ui/inc/prevloc.hxx
new file mode 100644
index 000000000000..15b477abad3c
--- /dev/null
+++ b/sc/source/ui/inc/prevloc.hxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PREVLOC_HXX
+#define SC_PREVLOC_HXX
+
+#include "address.hxx"
+#include <tools/list.hxx>
+#include <vcl/mapmod.hxx>
+#include <sal/types.h>
+
+
+#define SC_PREVIEW_MAXRANGES 4
+#define SC_PREVIEW_RANGE_EDGE 0
+#define SC_PREVIEW_RANGE_REPCOL 1
+#define SC_PREVIEW_RANGE_REPROW 2
+#define SC_PREVIEW_RANGE_TAB 3
+
+class OutputDevice;
+class String;
+class Point;
+class Rectangle;
+class ScAddress;
+class ScRange;
+class ScDocument;
+
+struct ScPreviewColRowInfo
+{
+ BOOL bIsHeader;
+ SCCOLROW nDocIndex;
+ long nPixelStart;
+ long nPixelEnd;
+
+ void Set( BOOL bHeader, SCCOLROW nIndex, long nStart, long nEnd )
+ {
+ bIsHeader = bHeader;
+ nDocIndex = nIndex;
+ nPixelStart = nStart;
+ nPixelEnd = nEnd;
+ }
+};
+
+class ScPreviewTableInfo
+{
+ SCTAB nTab;
+ SCCOL nCols;
+ SCROW nRows;
+ ScPreviewColRowInfo* pColInfo;
+ ScPreviewColRowInfo* pRowInfo;
+
+public:
+ ScPreviewTableInfo();
+ ~ScPreviewTableInfo();
+
+ SCTAB GetTab() const { return nTab; }
+ SCCOL GetCols() const { return nCols; }
+ SCROW GetRows() const { return nRows; }
+ const ScPreviewColRowInfo* GetColInfo() const { return pColInfo; }
+ const ScPreviewColRowInfo* GetRowInfo() const { return pRowInfo; }
+
+ void SetTab( SCTAB nNewTab );
+ void SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo );
+ void SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo );
+ void LimitToArea( const Rectangle& rPixelArea );
+};
+
+
+class ScPreviewLocationData
+{
+ OutputDevice* pWindow;
+ ScDocument* pDoc;
+ MapMode aCellMapMode;
+ MapMode aDrawMapMode[SC_PREVIEW_MAXRANGES];
+ Rectangle aDrawRectangle[SC_PREVIEW_MAXRANGES];
+ sal_uInt8 aDrawRangeId[SC_PREVIEW_MAXRANGES];
+ USHORT nDrawRanges;
+ SCTAB nPrintTab;
+ List aEntries;
+
+//UNUSED2008-05 ScAddress GetCellFromRange( const Size& rOffsetPixel, const ScRange& rRange ) const;
+ Rectangle GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const;
+
+public:
+ ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin );
+ ~ScPreviewLocationData();
+
+ void SetCellMapMode( const MapMode& rMapMode );
+ void SetPrintTab( SCTAB nNew );
+ void Clear();
+ void AddCellRange( const Rectangle& rRect, const ScRange& rRange, BOOL bRepCol, BOOL bRepRow,
+ const MapMode& rDrawMap );
+ void AddColHeaders( const Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, BOOL bRepCol );
+ void AddRowHeaders( const Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, BOOL bRepRow );
+ void AddHeaderFooter( const Rectangle& rRect, BOOL bHeader, BOOL bLeft );
+ void AddNoteMark( const Rectangle& rRect, const ScAddress& rPos );
+ void AddNoteText( const Rectangle& rRect, const ScAddress& rPos );
+
+ SCTAB GetPrintTab() const { return nPrintTab; }
+
+ // Get info on visible columns/rows in the visible area
+ void GetTableInfo( const Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const;
+
+ USHORT GetDrawRanges() const { return nDrawRanges; }
+ void GetDrawRange( USHORT nPos, Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const;
+
+ BOOL GetHeaderPosition( Rectangle& rHeaderRect ) const;
+ BOOL GetFooterPosition( Rectangle& rFooterRect ) const;
+ BOOL IsHeaderLeft() const;
+ BOOL IsFooterLeft() const;
+
+ long GetNoteCountInRange( const Rectangle& rVisiblePixel, BOOL bNoteMarks ) const;
+ BOOL GetNoteInRange( const Rectangle& rVisiblePixel, long nIndex, BOOL bNoteMarks,
+ ScAddress& rCellPos, Rectangle& rNoteRect ) const;
+ Rectangle GetNoteInRangeOutputRect(const Rectangle& rVisiblePixel, BOOL bNoteMarks,
+ const ScAddress& aCellPos) const;
+
+ // Check if any cells (including column/row headers) are in the visible area
+ BOOL HasCellsInRange( const Rectangle& rVisiblePixel ) const;
+
+ BOOL GetCellPosition( const ScAddress& rCellPos, Rectangle& rCellRect ) const;
+
+ // returns the rectangle where the EditEngine draws the text of a Header Cell
+ // if bColHeader is true it returns the rectangle of the header of the column in rCellPos
+ // otherwise of the header of the row in rCellPos
+ Rectangle GetHeaderCellOutputRect(const Rectangle& rVisRect, const ScAddress& rCellPos, sal_Bool bColHeader) const;
+ Rectangle GetCellOutputRect(const ScAddress& rCellPos) const;
+
+ // Query the range and rectangle of the main (non-repeat) cell range.
+ // Returns FALSE if not contained.
+ BOOL GetMainCellRange( ScRange& rRange, Rectangle& rPixRect ) const;
+};
+
+#endif
diff --git a/sc/source/ui/inc/prevwsh.hxx b/sc/source/ui/inc/prevwsh.hxx
new file mode 100644
index 000000000000..7ff97f8d0152
--- /dev/null
+++ b/sc/source/ui/inc/prevwsh.hxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PREVWSH_HXX
+#define SC_PREVWSH_HXX
+
+class ScrollBar;
+
+#include "address.hxx"
+#include <sfx2/viewfac.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svx/zoomitem.hxx>
+
+#include "shellids.hxx"
+
+class ScDocument;
+class ScDocShell;
+class ScPreview;
+struct ScHeaderFieldData;
+class ScPreviewLocationData;
+class CommandEvent;
+
+//==================================================================
+
+
+class ScPreviewShell: public SfxViewShell
+{
+ ScDocShell* pDocShell;
+
+ ScPreview* pPreview; // Ausgabe-Fenster
+ ScrollBar* pHorScroll;
+ ScrollBar* pVerScroll;
+ Window* pCorner;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aSourceData; // ViewData
+ BYTE nSourceDesignMode; // form design mode from TabView
+ SvxZoomType eZoom;
+ long nMaxVertPos;
+
+ SfxBroadcaster* pAccessibilityBroadcaster;
+
+private:
+ void Construct( Window* pParent );
+ DECL_LINK(ScrollHandler, ScrollBar* );
+ void DoScroll( USHORT nMode );
+
+protected:
+ virtual void Activate(BOOL bMDI);
+ virtual void Deactivate(BOOL bMDI);
+
+ virtual void AdjustPosSizePixel( const Point &rPos, const Size &rSize );
+
+ virtual void InnerResizePixel( const Point &rOfs, const Size &rSize );
+ virtual void OuterResizePixel( const Point &rOfs, const Size &rSize );
+
+ virtual Size GetOptimalSizePixel() const;
+
+ virtual String GetDescription() const;
+
+ virtual void WriteUserData(String &, BOOL bBrowse = FALSE);
+ virtual void ReadUserData(const String &, BOOL bBrowse = FALSE);
+
+ virtual void WriteUserDataSequence (::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, sal_Bool bBrowse = sal_False );
+ virtual void ReadUserDataSequence (const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, sal_Bool bBrowse = sal_False );
+
+public:
+ TYPEINFO();
+
+ SFX_DECL_INTERFACE(SCID_PREVIEW_SHELL)
+ SFX_DECL_VIEWFACTORY(ScPreviewShell);
+
+ ScPreviewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh );
+
+ virtual ~ScPreviewShell();
+
+ void InitStartTable(SCTAB nTab);
+
+ void UpdateScrollBars();
+ BOOL ScrollCommand( const CommandEvent& rCEvt );
+
+ void Execute( SfxRequest& rReq );
+ void GetState( SfxItemSet& rSet );
+
+ void FillFieldData( ScHeaderFieldData& rData );
+
+ ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >
+ GetSourceData() const { return aSourceData; }
+ BYTE GetSourceDesignMode() const { return nSourceDesignMode; }
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ virtual SfxPrinter* GetPrinter( BOOL bCreate = FALSE );
+ virtual USHORT SetPrinter( SfxPrinter* pNewPrinter, USHORT nDiffFlags = SFX_PRINTER_ALL, bool bIsAPI=false );
+ virtual PrintDialog* CreatePrintDialog( Window* pParent );
+ virtual SfxTabPage* CreatePrintOptionsPage( Window *pParent, const SfxItemSet &rOptions );
+ virtual void PreparePrint( PrintDialog* pPrintDialog = NULL );
+ virtual ErrCode DoPrint( SfxPrinter *pPrinter, PrintDialog *pPrintDialog, BOOL bSilent, BOOL bIsAPI );
+ virtual USHORT Print( SfxProgress& rProgress, BOOL bIsAPI, PrintDialog* pPrintDialog = NULL );
+
+ void AddAccessibilityObject( SfxListener& rObject );
+ void RemoveAccessibilityObject( SfxListener& rObject );
+ void BroadcastAccessibility( const SfxHint &rHint );
+ BOOL HasAccessibilityObjects();
+
+ const ScPreviewLocationData& GetLocationData();
+ ScDocument* GetDocument();
+ ScPreview* GetPreview() { return pPreview; }
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/printfun.hxx b/sc/source/ui/inc/printfun.hxx
new file mode 100644
index 000000000000..e3966bdc3d37
--- /dev/null
+++ b/sc/source/ui/inc/printfun.hxx
@@ -0,0 +1,368 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PRINTFUN_HXX
+#define SC_PRINTFUN_HXX
+
+
+#include "pagepar.hxx"
+#include "editutil.hxx"
+
+#ifndef _PRINT_HXX //autogen
+#include <vcl/print.hxx>
+#endif
+
+class SfxPrinter;
+class SfxProgress;
+class ScDocShell;
+class ScDocument;
+class ScViewData;
+class SfxItemSet;
+class ScPageHFItem;
+class EditTextObject;
+class MultiSelection;
+class ScHeaderEditEngine;
+class ScPageBreakData;
+class ScPreviewLocationData;
+class ScPrintOptions;
+class SvxBoxItem;
+class SvxBrushItem;
+class SvxShadowItem;
+class FmFormView;
+
+#define RANGENO_NORANGE USHRT_MAX
+
+#define PRINT_HEADER_WIDTH (1.0 * TWIPS_PER_CM)
+#define PRINT_HEADER_HEIGHT (12.8 * TWIPS_PER_POINT)
+#define PRINT_HEADER_FONTHEIGHT 200
+
+
+ // Einstellungen fuer Kopf-/Fusszeilen
+struct ScPrintHFParam
+{
+ BOOL bEnable;
+ BOOL bDynamic;
+ BOOL bShared;
+ long nHeight; // insgesamt (Hoehe+Abstand+Rahmen)
+ long nManHeight; // eingestellte Groesse (Min. bei dynamisch)
+ USHORT nDistance;
+ USHORT nLeft; // Raender
+ USHORT nRight;
+ const ScPageHFItem* pLeft;
+ const ScPageHFItem* pRight;
+ const SvxBoxItem* pBorder;
+ const SvxBrushItem* pBack;
+ const SvxShadowItem* pShadow;
+};
+
+
+// "Ersatz" fuer SV-JobSetup:
+
+class ScJobSetup
+{
+public:
+ ScJobSetup( SfxPrinter* pPrinter );
+
+ Size aUserSize;
+ MapMode aUserMapMode;
+ Paper ePaper;
+ Orientation eOrientation;
+ USHORT nPaperBin;
+};
+
+struct ScPrintState // Variablen aus ScPrintFunc retten
+{
+ SCTAB nPrintTab;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ USHORT nZoom;
+ size_t nPagesX;
+ size_t nPagesY;
+ long nTabPages;
+ long nTotalPages;
+ long nPageStart;
+ long nDocPages;
+};
+
+class ScPageRowEntry
+{
+private:
+ SCROW nStartRow;
+ SCROW nEndRow;
+ size_t nPagesX;
+ BOOL* pHidden;
+ //! Anzahl wirklich sichtbarer cachen???
+
+public:
+ ScPageRowEntry() { nStartRow = nEndRow = 0; nPagesX = 0; pHidden = NULL; }
+ ~ScPageRowEntry() { delete[] pHidden; }
+
+ ScPageRowEntry(const ScPageRowEntry& r);
+ const ScPageRowEntry& operator=(const ScPageRowEntry& r);
+
+ SCROW GetStartRow() const { return nStartRow; }
+ SCROW GetEndRow() const { return nEndRow; }
+ size_t GetPagesX() const { return nPagesX; }
+ void SetStartRow(SCROW n) { nStartRow = n; }
+ void SetEndRow(SCROW n) { nEndRow = n; }
+
+ void SetPagesX(size_t nNew);
+ void SetHidden(size_t nX);
+ BOOL IsHidden(size_t nX) const;
+
+ size_t CountVisible() const;
+};
+
+class ScPrintFunc
+{
+private:
+ ScDocShell* pDocShell;
+ ScDocument* pDoc;
+ SfxPrinter* pPrinter;
+ OutputDevice* pDev;
+ FmFormView* pDrawView;
+
+ MapMode aOldPrinterMode; // MapMode vor dem Aufruf
+
+ Point aSrcOffset; // Papier-1/100 mm
+ Point aOffset; // mit Faktor aus Seitenformat skaliert
+ USHORT nManualZoom; // Zoom in Preview (Prozent)
+ BOOL bClearWin; // Ausgabe vorher loeschen
+ BOOL bUseStyleColor;
+ BOOL bIsRender;
+
+ SCTAB nPrintTab;
+ long nPageStart; // Offset fuer erste Seite
+ long nDocPages; // Seiten im Dokument
+
+ const ScRange* pUserArea; // Selektion, wenn im Dialog eingestellt
+
+ const SfxItemSet* pParamSet; // eingestellte Vorlage
+ BOOL bState; // aus State-struct erzeugt
+
+ // Parameter aus Vorlage:
+ USHORT nLeftMargin;
+ USHORT nTopMargin;
+ USHORT nRightMargin;
+ USHORT nBottomMargin;
+ BOOL bCenterHor;
+ BOOL bCenterVer;
+ BOOL bLandscape;
+ BOOL bSourceRangeValid;
+
+ USHORT nPageUsage;
+ Size aPageSize; // Drucker-Twips
+ const SvxBoxItem* pBorderItem;
+ const SvxBrushItem* pBackgroundItem;
+ const SvxShadowItem* pShadowItem;
+
+ ScRange aLastSourceRange;
+ ScPrintHFParam aHdr;
+ ScPrintHFParam aFtr;
+ ScPageTableParam aTableParam;
+ ScPageAreaParam aAreaParam;
+
+ // berechnete Werte:
+ USHORT nZoom;
+ BOOL bPrintCurrentTable;
+ BOOL bMultiArea;
+ long nTabPages;
+ long nTotalPages;
+
+ Rectangle aPageRect; // Dokument-Twips
+
+ MapMode aLogicMode; // in DoPrint gesetzt
+ MapMode aOffsetMode;
+ MapMode aTwipMode;
+ double nScaleX;
+ double nScaleY;
+
+ SCCOL nRepeatStartCol;
+ SCCOL nRepeatEndCol;
+ SCROW nRepeatStartRow;
+ SCROW nRepeatEndRow;
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+
+ SCCOL* pPageEndX; // Seitenaufteilung
+ SCROW* pPageEndY;
+ ScPageRowEntry* pPageRows;
+ size_t nPagesX;
+ size_t nPagesY;
+ size_t nTotalY;
+
+ ScHeaderEditEngine* pEditEngine;
+ SfxItemSet* pEditDefaults;
+
+ ScHeaderFieldData aFieldData;
+
+ List aNotePosList; // Reihenfolge der Notizen
+
+ ScPageBreakData* pPageData; // zum Eintragen der Umbrueche etc.
+
+public:
+ ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
+ long nPage = 0, long nDocP = 0,
+ const ScRange* pArea = NULL,
+ const ScPrintOptions* pOptions = NULL,
+ ScPageBreakData* pData = NULL );
+
+ // ctors for device other than printer - for preview and pdf:
+
+ ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
+ long nPage = 0, long nDocP = 0,
+ const ScRange* pArea = NULL,
+ const ScPrintOptions* pOptions = NULL );
+
+ ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
+ const ScPrintState& rState,
+ const ScPrintOptions* pOptions );
+
+ ScPrintFunc( ScDocShell* pShell, Window* pWindow, SCTAB nTab,
+ long nPage = 0, long nDocP = 0,
+ const ScRange* pArea = NULL,
+ const ScPrintOptions* pOptions = NULL );
+
+ ScPrintFunc( ScDocShell* pShell, Window* pWindow,
+ const ScPrintState& rState,
+ const ScPrintOptions* pOptions );
+ ~ScPrintFunc();
+
+ static void DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double nPrintFactor,
+ const Rectangle& rBound, ScViewData* pViewData, BOOL bMetaFile );
+
+ void SetDrawView( FmFormView* pNew );
+
+ void SetOffset( const Point& rOfs );
+ void SetManualZoom( USHORT nNewZoom );
+ void SetDateTime( const Date& rDate, const Time& rTime );
+
+ void SetClearFlag( BOOL bFlag );
+ void SetUseStyleColor( BOOL bFlag );
+ void SetRenderFlag( BOOL bFlag );
+
+ void SetExclusivelyDrawOleAndDrawObjects();//for printing selected objects without surrounding cell contents
+
+ BOOL UpdatePages();
+
+ void ApplyPrintSettings(); // aus DoPrint() schon gerufen
+ long DoPrint( const MultiSelection& rPageRanges,
+ /*long nStartPage, long nDisplayStart, BOOL bDoPrint,
+ SfxProgress* pProgress, ScPreviewLocationData* pLocationData );*/
+ long nStartPage, long nDisplayStart, BOOL bDoPrint = TRUE,
+ SfxProgress* pProgress = NULL, ScPreviewLocationData* pLocationData = NULL);
+
+ // Werte abfragen - sofort
+
+ Size GetPageSize() const { return aPageSize; }
+ Size GetDataSize() const;
+ void GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr );
+ long GetFirstPageNo() const { return aTableParam.nFirstPageNo; }
+
+ // letzte Werte abfragen - nach DoPrint !!!
+
+ double GetScaleX() const { return nScaleX; }
+ double GetScaleY() const { return nScaleY; }
+ long GetTotalPages() const { return nTotalPages; }
+ USHORT GetZoom() const { return nZoom; }
+
+ void ResetBreaks( SCTAB nTab );
+
+ void GetPrintState( ScPrintState& rState );
+ BOOL GetLastSourceRange( ScRange& rRange ) const;
+ USHORT GetLeftMargin() const{return nLeftMargin;}
+ USHORT GetRightMargin() const{return nRightMargin;}
+ USHORT GetTopMargin() const{return nTopMargin;}
+ USHORT GetBottomMargin() const{return nBottomMargin;}
+ void SetLeftMargin(USHORT nRulerLeftDistance){ nLeftMargin = nRulerLeftDistance; }
+ void SetRightMargin(USHORT nRulerRightDistance){ nRightMargin = nRulerRightDistance; }
+ void SetTopMargin(USHORT nRulerTopDistance){ nTopMargin = nRulerTopDistance; }
+ void SetBottomMargin(USHORT nRulerBottomDistance){ nBottomMargin = nRulerBottomDistance; }
+ ScPrintHFParam GetHeader(){return aHdr;}
+ ScPrintHFParam GetFooter(){return aFtr;}
+
+private:
+ void Construct( const ScPrintOptions* pOptions );
+ void InitParam( const ScPrintOptions* pOptions );
+ void CalcZoom( USHORT nRangeNo );
+ void CalcPages();
+ long CountPages();
+ long CountNotePages();
+
+ BOOL AdjustPrintArea( BOOL bNew );
+
+ Size GetDocPageSize();
+
+ long TextHeight( const EditTextObject* pObject );
+ void MakeEditEngine();
+ void UpdateHFHeight( ScPrintHFParam& rParam );
+
+ void InitModes();
+
+ BOOL IsLeft( long nPageNo );
+ BOOL IsMirror( long nPageNo );
+ void ReplaceFields( long nPageNo ); // aendert Text in pEditEngine
+ void MakeTableString(); // setzt aTableStr
+
+ void PrintPage( long nPageNo,
+ SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ BOOL bDoPrint, ScPreviewLocationData* pLocationData );
+ void PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ long nScrX, long nScrY,
+ BOOL bShLeft, BOOL bShTop, BOOL bShRight, BOOL bShBottom );
+ void LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ long nScrX, long nScrY, BOOL bRepCol, BOOL bRepRow,
+ ScPreviewLocationData& rLocationData );
+ void PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY );
+ void PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY );
+ void LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
+ BOOL bRepCol, ScPreviewLocationData& rLocationData );
+ void LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
+ BOOL bRepRow, ScPreviewLocationData& rLocationData );
+ void PrintHF( long nPageNo, BOOL bHeader, long nStartY,
+ BOOL bDoPrint, ScPreviewLocationData* pLocationData );
+
+ long PrintNotes( long nPageNo, long nNoteStart, BOOL bDoPrint, ScPreviewLocationData* pLocationData );
+ long DoNotes( long nNoteStart, BOOL bDoPrint, ScPreviewLocationData* pLocationData );
+
+ void DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
+ const SvxBoxItem* pBorderData,
+ const SvxBrushItem* pBackground,
+ const SvxShadowItem* pShadow );
+
+ void FillPageData();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/privsplt.hxx b/sc/source/ui/inc/privsplt.hxx
new file mode 100644
index 000000000000..6194a4342849
--- /dev/null
+++ b/sc/source/ui/inc/privsplt.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PRIVSPLT_HXX
+#define SC_PRIVSPLT_HXX
+
+#include <vcl/ctrl.hxx>
+
+enum SC_SPLIT_DIRECTION {SC_SPLIT_HORZ,SC_SPLIT_VERT };
+
+class ScPrivatSplit : public Control
+{
+ private:
+
+ Link aCtrModifiedLink;
+ BOOL aMovingFlag;
+ Pointer aWinPointer;
+ SC_SPLIT_DIRECTION eScSplit;
+ short nOldX;
+ short nOldY;
+ short nNewX;
+ short nNewY;
+ short nMinPos;
+ short nMaxPos;
+ Range aXMovingRange;
+ Range aYMovingRange;
+ short nDeltaX;
+ short nDeltaY;
+
+ using Control::ImplInitSettings;
+ void ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground );
+
+
+
+ protected:
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt);
+
+ public:
+
+ ScPrivatSplit( Window* pWindow, const ResId& rResId,
+ SC_SPLIT_DIRECTION eScSplit);
+
+ virtual short GetDeltaX();
+ virtual short GetDeltaY();
+
+ virtual void CtrModified();
+
+ void SetYRange(Range cRgeY);
+
+ void MoveSplitTo(Point aPos);
+
+ virtual void StateChanged( StateChangedType nType );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+ void SetCtrModifiedHdl( const Link& rLink ) { aCtrModifiedLink = rLink; }
+ const Link& GetCtrModifiedHdl() const { return aCtrModifiedLink; }
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/protectiondlg.hrc b/sc/source/ui/inc/protectiondlg.hrc
new file mode 100644
index 000000000000..52e57040922c
--- /dev/null
+++ b/sc/source/ui/inc/protectiondlg.hrc
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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..d7d555ff5ac5
--- /dev/null
+++ b/sc/source/ui/inc/protectiondlg.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef 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/pvfundlg.hxx b/sc/source/ui/inc/pvfundlg.hxx
new file mode 100644
index 000000000000..ef245ebf26cf
--- /dev/null
+++ b/sc/source/ui/inc/pvfundlg.hxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_PVFUNDLG_HXX
+#define SC_PVFUNDLG_HXX
+
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+
+#ifndef _FIXED_HXX
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _LSTBOX_HXX
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _DIALOG_HXX
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#ifndef _MOREBTN_HXX
+#include <vcl/morebtn.hxx>
+#endif
+#include <vcl/field.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svx/checklbx.hxx>
+#include <sfx2/itemconnect.hxx>
+#include "pivot.hxx"
+
+#include <hash_map>
+
+// ============================================================================
+
+typedef sfx::ListBoxWrapper< sal_Int32 > ScDPListBoxWrapper;
+
+class ScDPObject;
+
+// ============================================================================
+
+class ScDPFunctionListBox : public MultiListBox
+{
+public:
+ explicit ScDPFunctionListBox( Window* pParent, const ResId& rResId );
+
+ void SetSelection( USHORT nFuncMask );
+ USHORT GetSelection() const;
+
+private:
+ void FillFunctionNames();
+};
+
+// ============================================================================
+
+class ScDPFunctionDlg : public ModalDialog
+{
+public:
+ explicit ScDPFunctionDlg( Window* pParent, const ScDPLabelDataVec& rLabelVec,
+ const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData );
+
+ USHORT GetFuncMask() const;
+ ::com::sun::star::sheet::DataPilotFieldReference GetFieldRef() const;
+
+private:
+ void Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData );
+
+ DECL_LINK( SelectHdl, ListBox* );
+ DECL_LINK( DblClickHdl, MultiListBox* );
+
+private:
+ FixedLine maFlFunc;
+ ScDPFunctionListBox maLbFunc;
+ FixedText maFtNameLabel;
+ FixedInfo maFtName;
+ FixedLine maFlDisplay;
+ FixedText maFtType;
+ ListBox maLbType;
+ FixedText maFtBaseField;
+ ListBox maLbBaseField;
+ FixedText maFtBaseItem;
+ ListBox maLbBaseItem;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+ MoreButton maBtnMore;
+
+ ScDPListBoxWrapper maLbTypeWrp; /// Wrapper for direct usage of API constants.
+
+ const ScDPLabelDataVec& mrLabelVec; /// Data of all labels.
+ bool mbEmptyItem; /// true = Empty base item in listbox.
+};
+
+// ============================================================================
+
+class ScDPSubtotalDlg : public ModalDialog
+{
+public:
+ explicit ScDPSubtotalDlg( Window* pParent, ScDPObject& rDPObj,
+ const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData,
+ const ScDPNameVec& rDataFields, bool bEnableLayout );
+
+ USHORT GetFuncMask() const;
+
+ void FillLabelData( ScDPLabelData& rLabelData ) const;
+
+private:
+ void Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData );
+
+ DECL_LINK( DblClickHdl, MultiListBox* );
+ DECL_LINK( RadioClickHdl, RadioButton* );
+ DECL_LINK( ClickHdl, PushButton* );
+
+private:
+ FixedLine maFlSubt;
+ RadioButton maRbNone;
+ RadioButton maRbAuto;
+ RadioButton maRbUser;
+ ScDPFunctionListBox maLbFunc;
+ FixedText maFtNameLabel;
+ FixedInfo maFtName;
+ CheckBox maCbShowAll;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+ PushButton maBtnOptions;
+
+ ScDPObject& mrDPObj; /// The DataPilot object (for member names).
+ const ScDPNameVec& mrDataFields; /// The list of all data field names.
+
+ ScDPLabelData maLabelData; /// Cache for sub dialog.
+ bool mbEnableLayout; /// true = Enable Layout mode controls.
+};
+
+// ============================================================================
+
+class ScDPSubtotalOptDlg : public ModalDialog
+{
+public:
+ explicit ScDPSubtotalOptDlg( Window* pParent, ScDPObject& rDPObj,
+ const ScDPLabelData& rLabelData, const ScDPNameVec& rDataFields,
+ bool bEnableLayout );
+
+ void FillLabelData( ScDPLabelData& rLabelData ) const;
+
+private:
+ void Init( const ScDPNameVec& rDataFields, bool bEnableLayout );
+ void InitHideListBox();
+
+ DECL_LINK( RadioClickHdl, RadioButton* );
+ DECL_LINK( CheckHdl, CheckBox* );
+ DECL_LINK( SelectHdl, ListBox* );
+
+private:
+ FixedLine maFlSortBy;
+ ListBox maLbSortBy;
+ RadioButton maRbSortAsc;
+ RadioButton maRbSortDesc;
+ RadioButton maRbSortMan;
+ FixedLine maFlLayout;
+ FixedText maFtLayout;
+ ListBox maLbLayout;
+ CheckBox maCbLayoutEmpty;
+ FixedLine maFlAutoShow;
+ CheckBox maCbShow;
+ NumericField maNfShow;
+ FixedText maFtShow;
+ FixedText maFtShowFrom;
+ ListBox maLbShowFrom;
+ FixedText maFtShowUsing;
+ ListBox maLbShowUsing;
+ FixedLine maFlHide;
+ SvxCheckListBox maLbHide;
+ FixedText maFtHierarchy;
+ ListBox maLbHierarchy;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ ScDPListBoxWrapper maLbLayoutWrp; /// Wrapper for direct usage of API constants.
+ ScDPListBoxWrapper maLbShowFromWrp; /// Wrapper for direct usage of API constants.
+
+ ScDPObject& mrDPObj; /// The DataPilot object (for member names).
+ ScDPLabelData maLabelData; /// Cache for members data.
+};
+
+// ============================================================================
+
+class ScDPShowDetailDlg : public ModalDialog
+{
+public:
+ explicit ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHORT nOrient );
+
+ virtual short Execute();
+
+ /**
+ * @return String internal name of the selected field. Note that this may
+ * be different from the name displayed in the dialog if the field
+ * has a layout name.
+ */
+ String GetDimensionName() const;
+
+private:
+ DECL_LINK( DblClickHdl, ListBox* );
+
+private:
+ FixedText maFtDims;
+ ListBox maLbDims;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ typedef ::std::hash_map<String, long, ScStringHashCode> DimNameIndexMap;
+ DimNameIndexMap maNameIndexMap;
+ ScDPObject& mrDPObj;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/pvlaydlg.hxx b/sc/source/ui/inc/pvlaydlg.hxx
new file mode 100644
index 000000000000..e16c3266510e
--- /dev/null
+++ b/sc/source/ui/inc/pvlaydlg.hxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_PVLAYDLG_HXX
+#define SC_PVLAYDLG_HXX
+
+#include <vector>
+#include <memory>
+#include <boost/shared_ptr.hpp>
+
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#ifndef _SCRBAR_HXX //autogen
+#include <vcl/scrbar.hxx>
+#endif
+#include <svtools/stdctrl.hxx>
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#include "pivot.hxx"
+#include "anyrefdg.hxx"
+#include "fieldwnd.hxx"
+#include "formula/funcutl.hxx"
+
+/*==========================================================================*\
+
+ Eine Instanz der Klasse ScPivotLayoutDlg ist ein (semi-)modaler
+ Dialog, in dem mit der Maus Felder mit Spaltenueberschriften den
+ drei Pivot-Kategorien "Spalte", "Zeile" und "Daten" zugeordnet
+ werden koennen.
+
+ Der Dialog erhaelt in der Struktur LabelData Informationen ueber
+ diese Ueberschriften (Name, Art (Zahl/String) und Funktionsmaske).
+ Weiterhin werden drei PivotFeld-Arrays uebergeben, mit denen die
+ drei Kategorie-Fenster initialisiert werden. Ein Kategorie-Fenster
+ wird durch eine Instanz der Klasse FieldWindow dargestellt. Ein
+ solches Fenster ist fuer die Darstellung der Datenstrukturen am
+ Schirm zustaendig. Es meldet Mausaktionen an den Dialog weiter und
+ bietet entsprechende Methoden zur Veraenderung der Darstellung.
+ Der Dialog sorgt fuer den Abgleich der interenen Datenstrukturen mit
+ der Bildschirmdarstellung. Ein weiteres FieldWindow (Select) bietet
+ alle Tabellenueberschriften zur Auswahl an, ist also "read-only".
+
+\*==========================================================================*/
+
+//============================================================================
+
+class ScViewData;
+class ScDocument;
+class ScRangeData;
+struct ScDPFuncData;
+class ScDPObject;
+
+//============================================================================
+
+#define FUNC_COUNT 11
+
+class ScDPLayoutDlg : public ScAnyRefDlg
+{
+public:
+ ScDPLayoutDlg(
+ SfxBindings* pB,
+ SfxChildWindow* pCW,
+ Window* pParent,
+ const ScDPObject& rDPObject );
+ virtual ~ScDPLayoutDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual BOOL IsRefInputMode() const { return bRefInputMode; }
+ virtual void SetActive();
+ virtual BOOL Close();
+ virtual void StateChanged( StateChangedType nStateChange );
+
+ void NotifyDoubleClick ( ScDPFieldType eType, size_t nFieldIndex );
+ PointerStyle NotifyMouseButtonDown( ScDPFieldType eType, size_t nFieldIndex );
+ void NotifyMouseButtonUp ( const Point& rAt );
+ PointerStyle NotifyMouseMove ( const Point& rAt );
+ void NotifyFieldFocus ( ScDPFieldType eType, BOOL bGotFocus );
+ void NotifyMoveField ( ScDPFieldType eToType );
+ void NotifyRemoveField ( ScDPFieldType eType, size_t nFieldIndex );
+ BOOL NotifyMoveSlider ( USHORT nKeyCode ); // return TRUE, if position changed
+
+protected:
+ virtual void Deactivate();
+
+private:
+ typedef boost::shared_ptr< ScDPFuncData > ScDPFuncDataRef;
+ typedef std::vector< ScDPFuncDataRef > ScDPFuncDataVec;
+ typedef std::auto_ptr< ScDPObject > ScDPObjectPtr;
+
+ FixedLine aFlLayout;
+ FixedText aFtPage;
+ ScDPFieldWindow aWndPage;
+ FixedText aFtCol;
+ ScDPFieldWindow aWndCol;
+ FixedText aFtRow;
+ ScDPFieldWindow aWndRow;
+ FixedText aFtData;
+ ScDPFieldWindow aWndData;
+ ScDPFieldWindow aWndSelect;
+ ScrollBar aSlider;
+ FixedInfo aFtInfo;
+
+ FixedLine aFlAreas;
+
+ // DP source selection
+ FixedText aFtInArea;
+ ::formula::RefEdit aEdInPos;
+ ::formula::RefButton aRbInPos;
+
+ // DP output location
+ ListBox aLbOutPos;
+ FixedText aFtOutArea;
+ formula::RefEdit aEdOutPos;
+ formula::RefButton aRbOutPos;
+
+ CheckBox aBtnIgnEmptyRows;
+ CheckBox aBtnDetectCat;
+ CheckBox aBtnTotalCol;
+ CheckBox aBtnTotalRow;
+ CheckBox aBtnFilter;
+ CheckBox aBtnDrillDown;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ PushButton aBtnRemove;
+ PushButton aBtnOptions;
+ MoreButton aBtnMore;
+
+ const String aStrUndefined;
+ const String aStrNewTable;
+ std::vector< String > aFuncNameArr;
+
+ ScDPFieldType eDnDFromType;
+ size_t nDnDFromIndex;
+ BOOL bIsDrag;
+
+ ::formula::RefEdit* pEditActive;
+
+ Rectangle aRectPage;
+ Rectangle aRectRow;
+ Rectangle aRectCol;
+ Rectangle aRectData;
+ Rectangle aRectSelect;
+
+ ScDPLabelDataVec aLabelDataArr; // (nCol, Feldname, Zahl/Text)
+
+ ScDPFieldType eLastActiveType; /// Type of last active area.
+ size_t nOffset; /// Offset of first field in TYPE_SELECT area.
+
+ ScDPFuncDataVec aSelectArr;
+ ScDPFuncDataVec aPageArr;
+ ScDPFuncDataVec aColArr;
+ ScDPFuncDataVec aRowArr;
+ ScDPFuncDataVec aDataArr;
+
+ ScDPObjectPtr xDlgDPObject;
+ ScRange aOldRange;
+ ScPivotParam thePivotData;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ BOOL bRefInputMode;
+
+private:
+ ScDPFieldWindow& GetFieldWindow ( ScDPFieldType eType );
+ void Init ();
+ void InitWndSelect ( const ::std::vector<ScDPLabelDataRef>& rLabels );
+ void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType );
+ void InitFocus ();
+ void InitFields ();
+ void CalcWndSizes ();
+ Point DlgPos2WndPos ( const Point& rPt, Window& rWnd );
+ ScDPLabelData* GetLabelData ( SCsCOL nCol, size_t* pPos = NULL );
+ String GetLabelString ( SCsCOL nCol );
+ bool IsOrientationAllowed( SCsCOL nCol, ScDPFieldType eType );
+ String GetFuncString ( USHORT& rFuncMask, BOOL bIsValue = TRUE );
+ BOOL Contains ( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt );
+ void Remove ( ScDPFuncDataVec* pArr, size_t nAt );
+ void Insert ( ScDPFuncDataVec* pArr, const ScDPFuncData& rFData, size_t nAt );
+
+ void AddField ( size_t nFromIndex,
+ ScDPFieldType eToType, const Point& rAtPos );
+ void MoveField ( ScDPFieldType eFromType, size_t nFromIndex,
+ ScDPFieldType eToType, const Point& rAtPos );
+ void RemoveField ( ScDPFieldType eRemType, size_t nRemIndex );
+
+ BOOL GetPivotArrays ( PivotField* pPageArr,
+ PivotField* pColArr,
+ PivotField* pRowArr,
+ PivotField* pDataArr,
+ USHORT& rPageCount,
+ USHORT& rColCount,
+ USHORT& rRowCount,
+ USHORT& rDataCount );
+
+ void UpdateSrcRange();
+
+ // Handler
+ DECL_LINK( ClickHdl, PushButton * );
+ DECL_LINK( ScrollHdl, ScrollBar * );
+ DECL_LINK( SelAreaHdl, ListBox * );
+ DECL_LINK( MoreClickHdl, MoreButton * );
+ DECL_LINK( EdModifyHdl, Edit * );
+ DECL_LINK( EdInModifyHdl, Edit * );
+ DECL_LINK( OkHdl, OKButton * );
+ DECL_LINK( CancelHdl, CancelButton * );
+ DECL_LINK( GetFocusHdl, Control* );
+};
+
+
+
+#endif // SC_PVLAYDLG_HXX
+
diff --git a/sc/source/ui/inc/redcom.hxx b/sc/source/ui/inc/redcom.hxx
new file mode 100644
index 000000000000..e7e064359349
--- /dev/null
+++ b/sc/source/ui/inc/redcom.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_REDCOM_HXX
+#define SC_REDCOM_HXX
+
+//CHINA001 #ifndef _SVX_POSTDLG_HXX //autogen
+//CHINA001 #include <svx/postdlg.hxx>
+//CHINA001 #endif
+
+#include "chgtrack.hxx"
+
+class ScDocShell;
+class AbstractSvxPostItDialog; //CHINA001
+
+class ScRedComDialog
+{
+private:
+
+ ScChangeAction *pChangeAction;
+ ScDocShell *pDocShell;
+ String aComment;
+ AbstractSvxPostItDialog* pDlg;
+
+ DECL_LINK( PrevHdl, AbstractSvxPostItDialog* );
+ DECL_LINK( NextHdl, AbstractSvxPostItDialog* );
+
+protected:
+
+ void ReInit(ScChangeAction *);
+ void SelectCell();
+
+ ScChangeAction *FindPrev(ScChangeAction *pAction);
+ ScChangeAction *FindNext(ScChangeAction *pAction);
+
+public:
+
+ ScRedComDialog( Window* pParent, const SfxItemSet& rCoreSet,
+ ScDocShell *,ScChangeAction *,BOOL bPrevNext = FALSE);
+ ~ScRedComDialog();
+
+ short Execute();
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/reffact.hxx b/sc/source/ui/inc/reffact.hxx
new file mode 100644
index 000000000000..617d7c0a669a
--- /dev/null
+++ b/sc/source/ui/inc/reffact.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_REFFACT_HXX
+#define SC_REFFACT_HXX
+
+#include <sfx2/childwin.hxx>
+
+#include "dbfunc.hxx"
+
+#define DECL_WRAPPER(Class) \
+ class Class : public SfxChildWindow \
+ { \
+ public: \
+ Class( Window*, USHORT, SfxBindings*, SfxChildWinInfo* ); \
+ SFX_DECL_CHILDWINDOW(Class); \
+ };
+
+
+//==================================================================
+
+DECL_WRAPPER(ScNameDlgWrapper)
+DECL_WRAPPER(ScSolverDlgWrapper)
+DECL_WRAPPER(ScOptSolverDlgWrapper)
+DECL_WRAPPER(ScPivotLayoutWrapper)
+DECL_WRAPPER(ScTabOpDlgWrapper)
+DECL_WRAPPER(ScFilterDlgWrapper)
+DECL_WRAPPER(ScSpecialFilterDlgWrapper)
+DECL_WRAPPER(ScDbNameDlgWrapper)
+DECL_WRAPPER(ScConsolidateDlgWrapper)
+DECL_WRAPPER(ScPrintAreasDlgWrapper)
+DECL_WRAPPER(ScCondFormatDlgWrapper)
+DECL_WRAPPER(ScColRowNameRangesDlgWrapper)
+DECL_WRAPPER(ScFormulaDlgWrapper)
+DECL_WRAPPER(ScHighlightChgDlgWrapper)
+
+/*!!! dafuer muss der Funktionsautopilot noch umgebaut werden
+DECL_WRAPPER(ScFunctionDlgWrapper)
+DECL_WRAPPER(ScEditFunctionDlgWrapper)
+DECL_WRAPPER(ScArgumentDlgWrapper)
+*/
+
+class ScAcceptChgDlgWrapper: public SfxChildWindow
+{
+ public:
+ ScAcceptChgDlgWrapper( Window*,
+ USHORT,
+ SfxBindings*,
+ SfxChildWinInfo* );
+
+ SFX_DECL_CHILDWINDOW(Class);
+
+ virtual void ReInitDlg();
+};
+
+class ScSimpleRefDlgWrapper: public SfxChildWindow
+{
+ public:
+ ScSimpleRefDlgWrapper( Window*,
+ USHORT,
+ SfxBindings*,
+ SfxChildWinInfo* );
+
+ SFX_DECL_CHILDWINDOW(Class);
+
+ static void SetDefaultPosSize(Point aPos, Size aSize, BOOL bSet=TRUE);
+ virtual String GetRefString();
+ virtual void SetRefString(const String& rStr);
+ void SetCloseHdl( const Link& rLink );
+ void SetUnoLinks( const Link& rDone, const Link& rAbort,
+ const Link& rChange );
+ void SetFlags( BOOL bCloseOnButtonUp, BOOL bSingleCell, BOOL bMultiSelection );
+ static void SetAutoReOpen(BOOL bFlag);
+
+ void StartRefInput();
+};
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+class SC_DLLPUBLIC ScValidityRefChildWin : public SfxChildWindow
+{
+ bool m_bVisibleLock:1;
+ bool m_bFreeWindowLock:1;
+ Window * m_pSavedWndParent;
+public:
+ ScValidityRefChildWin( Window*, USHORT, SfxBindings*, SfxChildWinInfo* );
+ SFX_DECL_CHILDWINDOW(ScValidityRefChildWin);
+ ~ScValidityRefChildWin();
+ bool LockVisible( bool bLock ){ bool bVis = m_bVisibleLock; m_bVisibleLock = bLock; return bVis; }
+ bool LockFreeWindow( bool bLock ){ bool bFreeWindow = m_bFreeWindowLock; m_bFreeWindowLock = bLock; return bFreeWindow; }
+ void Hide(){ if( !m_bVisibleLock) SfxChildWindow::Hide(); }
+ void Show( USHORT nFlags ){ if( !m_bVisibleLock ) SfxChildWindow::Show( nFlags ); }
+};
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+//==================================================================
+
+
+#endif // SC_REFFACT_HXX
diff --git a/sc/source/ui/inc/refundo.hxx b/sc/source/ui/inc/refundo.hxx
new file mode 100644
index 000000000000..87b5330e0f96
--- /dev/null
+++ b/sc/source/ui/inc/refundo.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_REFUNDO_HXX
+#define SC_REFUNDO_HXX
+
+#include <tools/solar.h>
+
+class ScDocument;
+class ScDBCollection;
+class ScRangeName;
+class ScPrintRangeSaver;
+class ScDPCollection;
+class ScChartCollection;
+class ScConditionalFormatList;
+class ScDetOpList;
+class ScChartListenerCollection;
+class ScAreaLinkSaveCollection;
+class ScUnoRefList;
+
+class ScRefUndoData
+{
+private:
+ ScDBCollection* pDBCollection;
+ ScRangeName* pRangeName;
+ ScPrintRangeSaver* pPrintRanges;
+ ScDPCollection* pDPCollection;
+ ScConditionalFormatList* pCondFormList;
+ ScDetOpList* pDetOpList;
+ ScChartListenerCollection* pChartListenerCollection;
+ ScAreaLinkSaveCollection* pAreaLinks;
+ ScUnoRefList* pUnoRefs;
+
+public:
+ ScRefUndoData( const ScDocument* pDoc );
+ ~ScRefUndoData();
+
+ void DeleteUnchanged( const ScDocument* pDoc );
+ void DoUndo( ScDocument* pDoc, BOOL bUndoRefFirst );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/retypepassdlg.hrc b/sc/source/ui/inc/retypepassdlg.hrc
new file mode 100644
index 000000000000..f027b6bc7ded
--- /dev/null
+++ b/sc/source/ui/inc/retypepassdlg.hrc
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <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..59753d8d386b
--- /dev/null
+++ b/sc/source/ui/inc/retypepassdlg.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/rfindlst.hxx b/sc/source/ui/inc/rfindlst.hxx
new file mode 100644
index 000000000000..225fd01451df
--- /dev/null
+++ b/sc/source/ui/inc/rfindlst.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RFINDLST_HXX
+#define SC_RFINDLST_HXX
+
+#include <tools/color.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+//==================================================================
+
+struct ScRangeFindData
+{
+ ScRange aRef;
+ USHORT nFlags;
+ xub_StrLen nSelStart;
+ xub_StrLen nSelEnd;
+
+ ScRangeFindData( const ScRange& rR, USHORT nF, xub_StrLen nS, xub_StrLen nE ) :
+ aRef(rR), nFlags(nF), nSelStart(nS), nSelEnd(nE) {}
+};
+
+class ScRangeFindList
+{
+ List aEntries;
+ String aDocName;
+ BOOL bHidden;
+
+public:
+ ScRangeFindList(const String& rName);
+ ~ScRangeFindList();
+
+ ULONG Count() const { return aEntries.Count(); }
+ void Insert( ScRangeFindData* pNew ) { aEntries.Insert(pNew, LIST_APPEND); }
+ ScRangeFindData* GetObject( ULONG nIndex ) const
+ { return (ScRangeFindData*)aEntries.GetObject(nIndex); }
+
+ void SetHidden( BOOL bSet ) { bHidden = bSet; }
+
+ const String& GetDocName() const { return aDocName; }
+ BOOL IsHidden() const { return bHidden; }
+
+ static ColorData GetColorName( USHORT nIndex );
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/scendlg.hxx b/sc/source/ui/inc/scendlg.hxx
new file mode 100644
index 000000000000..6281bb58b02c
--- /dev/null
+++ b/sc/source/ui/inc/scendlg.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCENDLG_HXX
+#define SC_SCENDLG_HXX
+
+
+#include <vcl/dialog.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/imagebtn.hxx>
+#include <svtools/svmedit.hxx>
+#include <svtools/ctrlbox.hxx>
+
+//===================================================================
+
+class ScNewScenarioDlg : public ModalDialog
+{
+public:
+ ScNewScenarioDlg( Window* pParent, const String& rName, BOOL bEdit = FALSE, BOOL bSheetProtected = FALSE );
+ ~ScNewScenarioDlg();
+
+ void SetScenarioData( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags );
+
+ void GetScenarioData( String& rName, String& rComment,
+ Color& rColor, USHORT& rFlags ) const;
+
+private:
+ FixedLine aFlName;
+ Edit aEdName;
+ FixedLine aFlComment;
+ MultiLineEdit aEdComment;
+ FixedLine aFlOptions;
+ CheckBox aCbShowFrame;
+ ColorListBox aLbColor;
+ //CheckBox aCbPrintFrame;
+ CheckBox aCbTwoWay;
+ //CheckBox aCbAttrib;
+ //CheckBox aCbValue;
+ CheckBox aCbCopyAll;
+ CheckBox aCbProtect;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ const String aDefScenarioName;
+ BOOL bIsEdit;
+
+ DECL_LINK( OkHdl, OKButton * );
+ DECL_LINK( EnableHdl, CheckBox * );
+};
+
+
+#endif // SC_SCENDLG_HXX
+
+
diff --git a/sc/source/ui/inc/scui_def.hxx b/sc/source/ui/inc/scui_def.hxx
new file mode 100644
index 000000000000..ca34ab0775b2
--- /dev/null
+++ b/sc/source/ui/inc/scui_def.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SCUI_DEF_HXX
+#define SCUI_DEF_HXX
+
+#define SCRET_COLS 0x42
+#define SCRET_ROWS 0x43
+
+#define FDS_OPT_NONE 0 // from filldlg.hxx
+#define FDS_OPT_HORZ 1 // from filldlg.hxx
+#define FDS_OPT_VERT 2 // from filldlg.hxx
+
+#define INS_CONT_NOEMPTY 0x0100 //from inscodlg.hxx
+#define INS_CONT_TRANS 0x0200 //from inscodlg.hxx
+#define INS_CONT_LINK 0x0400 //from inscodlg.hxx
+
+#define SC_CELL_SHIFT_DISABLE_DOWN 0x01 //from inscodlg.hxx
+#define SC_CELL_SHIFT_DISABLE_RIGHT 0x02 //from inscodlg.hxx
+
+#define NAME_TOP 1 //from namecrea.hxx
+#define NAME_LEFT 2 //from namecrea.hxx
+#define NAME_BOTTOM 4 //from namecrea.hxx
+#define NAME_RIGHT 8 //from namecrea.hxx
+
+#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/scuiasciiopt.hxx b/sc/source/ui/inc/scuiasciiopt.hxx
new file mode 100644
index 000000000000..3e1a7db38fb2
--- /dev/null
+++ b/sc/source/ui/inc/scuiasciiopt.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef SCUI_ASCIIOPT_HXX
+#define SCUI_ASCIIOPT_HXX
+
+
+#include "asciiopt.hxx"
+#include "svx/langbox.hxx"
+
+// ============================================================================
+
+class ScImportAsciiDlg : public ModalDialog
+{
+ SvStream* mpDatStream;
+ ULONG mnStreamPos;
+ ULONG* mpRowPosArray;
+ ULONG mnRowPosCount;
+
+ String maPreviewLine[ CSV_PREVIEW_LINES ];
+
+ FixedLine aFlFieldOpt;
+ FixedText aFtCharSet;
+ SvxTextEncodingBox aLbCharSet;
+ FixedText aFtCustomLang;
+ SvxLanguageBox aLbCustomLang;
+
+ FixedText aFtRow;
+ NumericField aNfRow;
+
+ FixedLine aFlSepOpt;
+ RadioButton aRbFixed;
+ RadioButton aRbSeparated;
+
+ CheckBox aCkbTab;
+ CheckBox aCkbSemicolon;
+ CheckBox aCkbComma;
+ CheckBox aCkbSpace;
+ CheckBox aCkbOther;
+ Edit aEdOther;
+ CheckBox aCkbAsOnce;
+
+ FixedLine aFlOtherOpt;
+
+ FixedText aFtTextSep;
+ ComboBox aCbTextSep;
+
+ CheckBox aCkbQuotedAsText;
+ CheckBox aCkbDetectNumber;
+
+ FixedLine aFlWidth;
+ FixedText aFtType;
+ ListBox aLbType;
+
+ ScCsvTableBox maTableBox;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ String aCharSetUser;
+ String aColumnUser;
+ String aFldSepList;
+ String aTextSepList;
+ String maFieldSeparators; // selected field separators
+ sal_Unicode mcTextSep;
+ String maStrTextToColumns;
+
+ CharSet meCharSet; /// Selected char set.
+ bool mbCharSetSystem; /// Is System char set selected?
+ bool mbFileImport; /// Is this dialog involked for csv file import ?
+
+public:
+ ScImportAsciiDlg(
+ Window* pParent, String aDatName,
+ SvStream* pInStream, sal_Unicode cSep = '\t' );
+ ~ScImportAsciiDlg();
+
+ void GetOptions( ScAsciiOptions& rOpt );
+ void SetTextToColumnsMode();
+ void SaveParameters();
+
+private:
+ /** Sets the selected char set data to meCharSet and mbCharSetSystem. */
+ void SetSelectedCharSet();
+ /** Returns all separator characters in a string. */
+ String GetSeparators() const;
+
+ /** Enables or disables all separator checkboxes and edit fields. */
+ void SetupSeparatorCtrls();
+
+
+ bool GetLine( ULONG nLine, String &rText );
+ void UpdateVertical();
+ inline bool Seek( ULONG nPos ); // synced to and from mnStreamPos
+
+ DECL_LINK( CharSetHdl, SvxTextEncodingBox* );
+ DECL_LINK( FirstRowHdl, NumericField* );
+ DECL_LINK( RbSepFixHdl, RadioButton* );
+ DECL_LINK( SeparatorHdl, Control* );
+ DECL_LINK( LbColTypeHdl, ListBox* );
+ DECL_LINK( UpdateTextHdl, ScCsvTableBox* );
+ DECL_LINK( ColTypeHdl, ScCsvTableBox* );
+};
+
+
+inline bool ScImportAsciiDlg::Seek(ULONG nPos)
+{
+ bool bSuccess = true;
+ if (nPos != mnStreamPos && mpDatStream)
+ {
+ if (mpDatStream->Seek( nPos ) != nPos)
+ bSuccess = false;
+ else
+ mnStreamPos = nPos;
+ }
+ return bSuccess;
+}
+
+#endif
+
diff --git a/sc/source/ui/inc/scuiautofmt.hxx b/sc/source/ui/inc/scuiautofmt.hxx
new file mode 100644
index 000000000000..84a408267b20
--- /dev/null
+++ b/sc/source/ui/inc/scuiautofmt.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SCUI_AUTOFMT_HXX
+#define SCUI_AUTOFMT_HXX
+#include "autofmt.hxx"
+
+class ScAutoFormatDlg : public ModalDialog
+{
+public:
+ ScAutoFormatDlg( Window* pParent,
+ ScAutoFormat* pAutoFormat,
+ const ScAutoFormatData* pSelFormatData,
+ ScDocument* pDoc );
+ ~ScAutoFormatDlg();
+
+ USHORT GetIndex() const { return nIndex; }
+ String GetCurrFormatName();
+
+private:
+ FixedLine aFlFormat;
+ ListBox aLbFormat;
+ ScAutoFmtPreview* pWndPreview;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ PushButton aBtnAdd;
+ PushButton aBtnRemove;
+ MoreButton aBtnMore;
+ FixedLine aFlFormatting;
+ CheckBox aBtnNumFormat;
+ CheckBox aBtnBorder;
+ CheckBox aBtnFont;
+ CheckBox aBtnPattern;
+ CheckBox aBtnAlignment;
+ CheckBox aBtnAdjust;
+ PushButton aBtnRename;
+ String aStrTitle;
+ String aStrLabel;
+ String aStrClose;
+ String aStrDelTitle;
+ String aStrDelMsg;
+ String aStrRename;
+
+ //------------------------
+ ScAutoFormat* pFormat;
+ const ScAutoFormatData* pSelFmtData;
+ USHORT nIndex;
+ BOOL bCoreDataChanged;
+ BOOL bFmtInserted;
+
+ void Init ();
+ void UpdateChecks ();
+ //------------------------
+ DECL_LINK( CheckHdl, Button * );
+ DECL_LINK( AddHdl, void * );
+ DECL_LINK( RemoveHdl, void * );
+ DECL_LINK( SelFmtHdl, void * );
+ DECL_LINK( CloseHdl, PushButton * );
+ DECL_LINK( DblClkHdl, void * );
+ DECL_LINK( RenameHdl, void *);
+
+};
+#endif
+
diff --git a/sc/source/ui/inc/scuiimoptdlg.hxx b/sc/source/ui/inc/scuiimoptdlg.hxx
new file mode 100644
index 000000000000..957d174a3deb
--- /dev/null
+++ b/sc/source/ui/inc/scuiimoptdlg.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SCUI_IMOPTDLG_HXX
+#define SCUI_IMOPTDLG_HXX
+
+#include "imoptdlg.hxx"
+
+//===================================================================
+
+
+class ScDelimiterTable;
+
+class ScImportOptionsDlg : public ModalDialog
+{
+public:
+ ScImportOptionsDlg( Window* pParent,
+ BOOL bAscii = TRUE,
+ const ScImportOptions* pOptions = NULL,
+ const String* pStrTitle = NULL,
+ BOOL bMultiByte = FALSE,
+ BOOL bOnlyDbtoolsEncodings = FALSE,
+ BOOL bImport = TRUE );
+
+ ~ScImportOptionsDlg();
+
+ void GetImportOptions( ScImportOptions& rOptions ) const;
+
+private:
+ FixedLine aFlFieldOpt;
+ FixedText aFtFont;
+ SvxTextEncodingBox aLbFont;
+ FixedText aFtFieldSep;
+ ComboBox aEdFieldSep;
+ FixedText aFtTextSep;
+ ComboBox aEdTextSep;
+ CheckBox aCbFixed;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ CheckBox aCbShown;
+
+ ScDelimiterTable* pFieldSepTab;
+ ScDelimiterTable* pTextSepTab;
+
+private:
+ USHORT GetCodeFromCombo( const ComboBox& rEd ) const;
+
+ DECL_LINK( FixedWidthHdl, CheckBox* );
+ DECL_LINK( DoubleClickHdl, ListBox* );
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/scuitphfedit.hxx b/sc/source/ui/inc/scuitphfedit.hxx
new file mode 100644
index 000000000000..99bd6c2a805a
--- /dev/null
+++ b/sc/source/ui/inc/scuitphfedit.hxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SCUI_TPHFEDIT_HXX
+#define SCUI_TPHFEDIT_HXX
+
+#include "tphfedit.hxx"
+
+//===================================================================
+enum ScHFEntryId
+{
+ eNoneEntry ,
+ ePageEntry ,
+ ePagesEntry ,
+ eSheetEntry ,
+ eConfidentialEntry ,
+ eFileNamePageEntry ,
+ eExtFileNameEntry ,
+ ePageSheetEntry ,
+ ePageFileNameEntry ,
+ ePageExtFileNameEntry ,
+ eUserNameEntry ,
+ eCreatedByEntry ,
+ eEntryCount
+};
+
+class ScHeaderEditEngine;
+class ScPatternAttr;
+class EditView;
+class EditTextObject;
+class SvxFieldItem;
+class ScAccessibleEditObject;
+
+
+class ScHFEditPage : public SfxTabPage
+{
+public:
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreSet );
+ virtual void Reset ( const SfxItemSet& rCoreSet );
+
+ void SetNumType(SvxNumType eNumType);
+ void ClearTextAreas();
+
+protected:
+ ScHFEditPage( Window* pParent,
+ USHORT nResId,
+ const SfxItemSet& rCoreSet,
+ USHORT nWhich, bool bHeader );
+ virtual ~ScHFEditPage();
+
+private:
+ FixedText aFtLeft;
+ ScEditWindow aWndLeft;
+ FixedText aFtCenter;
+ ScEditWindow aWndCenter;
+ FixedText aFtRight;
+ ScEditWindow aWndRight;
+ FixedText maFtDefinedHF;
+ ListBox maLbDefined;
+ FixedText maFtCustomHF;
+ ImageButton aBtnText;
+ ScExtIButton aBtnFile;
+ ImageButton aBtnTable;
+ ImageButton aBtnPage;
+ ImageButton aBtnLastPage;
+ ImageButton aBtnDate;
+ ImageButton aBtnTime;
+ FixedLine aFlInfo;
+ FixedInfo aFtInfo;
+ ScPopupMenu aPopUpFile;
+
+ USHORT nWhich;
+ String aCmdArr[6];
+
+private:
+#ifdef _TPHFEDIT_CXX
+ void FillCmdArr();
+ void InitPreDefinedList();
+ void ProcessDefinedListSel(ScHFEntryId eSel, bool bTravelling = false);
+ void InsertToDefinedList();
+ void RemoveFromDefinedList();
+ void SetSelectDefinedList();
+ bool IsPageEntry(EditEngine*pEngine, EditTextObject* pTextObj);
+ bool IsDateEntry(EditTextObject* pTextObj);
+ bool IsExtFileNameEntry(EditTextObject* pTextObj);
+ DECL_LINK( ListHdl_Impl, ListBox* );
+ DECL_LINK( ClickHdl, ImageButton* );
+ DECL_LINK( MenuHdl, ScExtIButton* );
+#endif
+};
+
+//===================================================================
+
+class ScRightHeaderEditPage : public ScHFEditPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges();
+
+private:
+ ScRightHeaderEditPage( Window* pParent, const SfxItemSet& rSet );
+};
+
+//===================================================================
+
+class ScLeftHeaderEditPage : public ScHFEditPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges();
+
+private:
+ ScLeftHeaderEditPage( Window* pParent, const SfxItemSet& rSet );
+};
+
+//===================================================================
+
+class ScRightFooterEditPage : public ScHFEditPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges();
+
+private:
+ ScRightFooterEditPage( Window* pParent, const SfxItemSet& rSet );
+};
+
+//===================================================================
+
+class ScLeftFooterEditPage : public ScHFEditPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges();
+
+private:
+ ScLeftFooterEditPage( Window* pParent, const SfxItemSet& rSet );
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/select.hxx b/sc/source/ui/inc/select.hxx
new file mode 100644
index 000000000000..ad12d9c743ad
--- /dev/null
+++ b/sc/source/ui/inc/select.hxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SELECT_HXX
+#define SC_SELECT_HXX
+
+#ifndef _SELENG_HXX //autogen
+#include <vcl/seleng.hxx>
+#endif
+
+#include "viewdata.hxx" // ScSplitPos
+
+// ---------------------------------------------------------------------------
+
+class ScTabView;
+class ScViewData;
+
+
+class ScViewSelectionEngine : public SelectionEngine
+{
+private:
+ ScSplitPos eWhich;
+public:
+ ScViewSelectionEngine( Window* pWindow, ScTabView* pView,
+ ScSplitPos eSplitPos );
+
+ ScSplitPos GetWhich() const { return eWhich; }
+ void SetWhich(ScSplitPos eNew) { eWhich = eNew; }
+};
+
+
+class ScViewFunctionSet : public FunctionSet // View (Gridwin / Tastatur)
+{
+private:
+ ScViewData* pViewData;
+ ScViewSelectionEngine* pEngine;
+
+ BOOL bAnchor;
+ BOOL bStarted;
+ ScAddress aAnchorPos;
+
+ ScSplitPos GetWhich();
+
+public:
+ ScViewFunctionSet( ScViewData* pNewViewData );
+
+ void SetSelectionEngine( ScViewSelectionEngine* pSelEngine );
+
+ void SetAnchor( SCCOL nPosX, SCROW nPosY );
+ void SetAnchorFlag( BOOL bSet );
+
+ virtual void BeginDrag();
+ virtual void CreateAnchor();
+ virtual void DestroyAnchor();
+ virtual BOOL SetCursorAtPoint( const Point& rPointPixel, BOOL bDontSelectAtCursor = FALSE );
+ virtual BOOL IsSelectionAtPoint( const Point& rPointPixel );
+ virtual void DeselectAtPoint( const Point& rPointPixel );
+ virtual void DeselectAll();
+
+ BOOL SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScroll );
+};
+
+
+// ---------------------------------------------------------------------------
+
+
+class ScHeaderFunctionSet : public FunctionSet // Spalten- / Zeilenkoepfe
+{
+private:
+ ScViewData* pViewData;
+ BOOL bColumn; // Col- / Rowbar
+ ScSplitPos eWhich;
+
+ BOOL bAnchor;
+ SCCOLROW nCursorPos;
+
+public:
+ ScHeaderFunctionSet( ScViewData* pNewViewData );
+
+ void SetColumn( BOOL bSet );
+ void SetWhich( ScSplitPos eNew );
+
+ virtual void BeginDrag();
+ virtual void CreateAnchor();
+ virtual void DestroyAnchor();
+ virtual BOOL SetCursorAtPoint( const Point& rPointPixel, BOOL bDontSelectAtCursor = FALSE );
+ virtual BOOL IsSelectionAtPoint( const Point& rPointPixel );
+ virtual void DeselectAtPoint( const Point& rPointPixel );
+ virtual void DeselectAll();
+
+ void SetAnchorFlag(BOOL bSet) { bAnchor = bSet; }
+};
+
+
+class ScHeaderSelectionEngine : public SelectionEngine
+{
+public:
+ ScHeaderSelectionEngine( Window* pWindow, ScHeaderFunctionSet* pFuncSet );
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/selectionstate.hxx b/sc/source/ui/inc/selectionstate.hxx
new file mode 100644
index 000000000000..cbdc6b1faff7
--- /dev/null
+++ b/sc/source/ui/inc/selectionstate.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SELECTIONSTATE_HXX
+#define SC_SELECTIONSTATE_HXX
+
+#include <editeng/editdata.hxx>
+#include "rangelst.hxx"
+
+// ============================================================================
+
+/** Enumerates all possible types of selections in a Calc document. */
+enum ScSelectionType
+{
+ SC_SELECTTYPE_NONE, /// No selection, simple cell cursor.
+ SC_SELECTTYPE_SHEET, /// Single cell, cell range, or multi range selection.
+ SC_SELECTTYPE_EDITCELL, /// Cell in edit mode (with or without selection).
+ SC_SELECTTYPE_DRAWING, /// One or more drawing objects.
+ SC_SELECTTYPE_EDITDRAW /// Edit mode in drawing object (with or without selection).
+};
+
+// ----------------------------------------------------------------------------
+
+class ScViewData;
+
+/** Contains all available data about any possible selection in a Calc document. */
+class ScSelectionState
+{
+public:
+ explicit ScSelectionState( ScViewData& rViewData );
+
+ /** Returns the type of the selection this object contains. */
+ inline ScSelectionType GetSelectionType() const { return meType; }
+
+ /** Returns the position of the cell cursor. */
+ inline const ScAddress& GetCellCursor() const { return maCursor; }
+ /** Returns a range list containing all selected cell ranges. */
+ inline const ScRangeList& GetSheetSelection() const { return maSheetSel; }
+ /** Returns the edit engine selection. */
+ inline const ESelection& GetEditSelection() const { return maEditSel; }
+
+private:
+ ScSelectionType meType; /// Type of the selection.
+ ScAddress maCursor; /// Cell cursor position.
+ ScRangeList maSheetSel; /// Sheet selection.
+ ESelection maEditSel; /// Selection in edit mode.
+};
+
+bool operator==( const ScSelectionState& rL, const ScSelectionState& rR );
+inline bool operator!=( const ScSelectionState& rL, const ScSelectionState& rR ) { return !(rL == rR); }
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/seltrans.hxx b/sc/source/ui/inc/seltrans.hxx
new file mode 100644
index 000000000000..c695c918dad0
--- /dev/null
+++ b/sc/source/ui/inc/seltrans.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SELTRANS_HXX
+#define SC_SELTRANS_HXX
+
+#include <svtools/transfer.hxx>
+
+class ScTabView;
+class ScTransferObj;
+class ScDrawTransferObj;
+
+enum ScSelectionTransferMode
+{
+ SC_SELTRANS_INVALID,
+ SC_SELTRANS_CELL,
+ SC_SELTRANS_CELLS,
+ SC_SELTRANS_DRAW_BITMAP,
+ SC_SELTRANS_DRAW_GRAPHIC,
+ SC_SELTRANS_DRAW_BOOKMARK,
+ SC_SELTRANS_DRAW_OLE,
+ SC_SELTRANS_DRAW_OTHER
+};
+
+class ScSelectionTransferObj : public TransferableHelper
+{
+private:
+ ScTabView* pView;
+ ScSelectionTransferMode eMode;
+ ScTransferObj* pCellData;
+ ScDrawTransferObj* pDrawData;
+
+ ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode );
+ void CreateCellData();
+ void CreateDrawData();
+
+public:
+ // creates an object if the view has a valid selection,
+ // returns NULL otherwise
+ static ScSelectionTransferObj* CreateFromView( ScTabView* pSource );
+
+ virtual ~ScSelectionTransferObj();
+
+ void ForgetView();
+ BOOL StillValid();
+ ScTabView* GetView() const { return pView; }
+
+ ScTransferObj* GetCellData();
+ ScDrawTransferObj* GetDrawData();
+
+ virtual void AddSupportedFormats();
+ virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ virtual void ObjectReleased();
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/servobj.hxx b/sc/source/ui/inc/servobj.hxx
new file mode 100644
index 000000000000..68e807461cad
--- /dev/null
+++ b/sc/source/ui/inc/servobj.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SERVOBJ_HXX
+#define SC_SERVOBJ_HXX
+
+#include <svl/lstner.hxx>
+#include <svl/listener.hxx>
+#include <sfx2/linksrc.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+class ScDocShell;
+class ScServerObject;
+
+class ScServerObjectSvtListenerForwarder : public SvtListener
+{
+ ScServerObject* pObj;
+ SfxBroadcaster aBroadcaster;
+public:
+ ScServerObjectSvtListenerForwarder( ScServerObject* pObjP);
+ virtual ~ScServerObjectSvtListenerForwarder();
+ virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
+};
+
+class ScServerObject : public ::sfx2::SvLinkSource, public SfxListener
+{
+private:
+ ScServerObjectSvtListenerForwarder aForwarder;
+ ScDocShell* pDocSh;
+ ScRange aRange;
+ String aItemStr;
+ BOOL bRefreshListener;
+
+ void Clear();
+
+public:
+ ScServerObject( ScDocShell* pShell, const String& rItem );
+ virtual ~ScServerObject();
+
+ virtual BOOL GetData( ::com::sun::star::uno::Any & rData /*out param*/,
+ const String & rMimeType,
+ BOOL bSynchron = FALSE );
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+ void EndListeningAll();
+};
+
+//SO2_DECL_REF( ScServerObject )
+
+
+#endif
diff --git a/sc/source/ui/inc/sharedocdlg.hrc b/sc/source/ui/inc/sharedocdlg.hrc
new file mode 100644
index 000000000000..cc38e81bbddb
--- /dev/null
+++ b/sc/source/ui/inc/sharedocdlg.hrc
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 CB_SHARE 1
+#define FT_WARNING 2
+#define FL_USERS 3
+#define FT_USERS 4
+#define LB_USERS 5
+#define FL_END 6
+#define BTN_HELP 7
+#define BTN_OK 8
+#define BTN_CANCEL 9
+
+#define STR_TITLE_NAME 1
+#define STR_TITLE_ACCESSED 2
+#define STR_NO_USER_DATA 3
+#define STR_UNKNOWN_USER 4
+#define STR_EXCLUSIVE_ACCESS 5
diff --git a/sc/source/ui/inc/sharedocdlg.hxx b/sc/source/ui/inc/sharedocdlg.hxx
new file mode 100644
index 000000000000..52c2f393b19a
--- /dev/null
+++ b/sc/source/ui/inc/sharedocdlg.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SHAREDOCDLG_HXX
+#define SC_SHAREDOCDLG_HXX
+
+#include <vcl/button.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <svx/simptabl.hxx>
+
+class ScViewData;
+class ScDocShell;
+
+
+//=============================================================================
+// class ScShareDocumentDlg
+//=============================================================================
+
+class ScShareDocumentDlg : public ModalDialog
+{
+private:
+ CheckBox maCbShare;
+ FixedText maFtWarning;
+ FixedLine maFlUsers;
+ FixedText maFtUsers;
+ SvxSimpleTable maLbUsers;
+ FixedLine maFlEnd;
+ HelpButton maBtnHelp;
+ OKButton maBtnOK;
+ CancelButton maBtnCancel;
+
+ String maStrTitleName;
+ String maStrTitleAccessed;
+ String maStrNoUserData;
+ String maStrUnkownUser;
+ String maStrExclusiveAccess;
+
+ ScViewData* mpViewData;
+ ScDocShell* mpDocShell;
+
+ DECL_LINK( ToggleHandle, void* );
+
+public:
+ ScShareDocumentDlg( Window* pParent, ScViewData* pViewData );
+ ~ScShareDocumentDlg();
+
+ bool IsShareDocumentChecked() const;
+ void UpdateView();
+};
+
+#endif
diff --git a/sc/source/ui/inc/shtabdlg.hxx b/sc/source/ui/inc/shtabdlg.hxx
new file mode 100644
index 000000000000..6c89c43b3a51
--- /dev/null
+++ b/sc/source/ui/inc/shtabdlg.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SHTABDLG_HXX
+#define SC_SHTABDLG_HXX
+
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#include <svtools/tooltiplbox.hxx>
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+
+//------------------------------------------------------------------------
+
+class ScShowTabDlg : public ModalDialog
+{
+private:
+ ::svtools::ToolTipMultiListBox aLb;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ FixedText aFtLbTitle;
+
+ DECL_LINK( DblClkHdl, void * );
+
+public:
+ ScShowTabDlg( Window* pParent );
+ ~ScShowTabDlg();
+
+ /** Sets dialog title, fixed text for listbox and help IDs. */
+ void SetDescription(
+ const String& rTitle, const String& rFixedText,
+ ULONG nDlgHelpId, ULONG nLbHelpId );
+
+ /** Inserts a string into the ListBox. */
+ void Insert( const String& rString, BOOL bSelected );
+
+ USHORT GetSelectEntryCount() const;
+ String GetSelectEntry(USHORT nPos) const;
+ USHORT GetSelectEntryPos(USHORT nPos) const;
+};
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/simpref.hrc b/sc/source/ui/inc/simpref.hrc
new file mode 100644
index 000000000000..d6fb6d4412eb
--- /dev/null
+++ b/sc/source/ui/inc/simpref.hrc
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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" // -> RID_SCDLG_SIMPLEREF
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_ADD 3
+#define BTN_HELP 4
+#define FT_ASSIGN 10
+#define ED_ASSIGN 11
+#define RB_ASSIGN 12
+
diff --git a/sc/source/ui/inc/simpref.hxx b/sc/source/ui/inc/simpref.hxx
new file mode 100644
index 000000000000..ba5b8ca287c3
--- /dev/null
+++ b/sc/source/ui/inc/simpref.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SIMPREF_HXX
+#define SC_SIMPREF_HXX
+
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+
+#ifndef _COMBOBOX_HXX //autogen
+#include <vcl/combobox.hxx>
+#endif
+
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+
+#ifndef _MOREBTN_HXX //autogen
+#include <vcl/morebtn.hxx>
+#endif
+#include "anyrefdg.hxx"
+#include "dbcolect.hxx"
+#include "expftext.hxx"
+
+class ScViewData;
+class ScDocument;
+
+
+//============================================================================
+
+class ScSimpleRefDlg: public ScAnyRefDlg
+{
+private:
+ Link aCloseHdl;
+ Link aDoneHdl;
+ Link aAbortedHdl;
+ Link aChangeHdl;
+
+ FixedText aFtAssign;
+ formula::RefEdit aEdAssign;
+ formula::RefButton aRbAssign;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ BOOL bRefInputMode;
+
+ ScRange theCurArea;
+ BOOL bCloseFlag;
+ BOOL bAutoReOpen;
+ BOOL bCloseOnButtonUp;
+ BOOL bSingleCell;
+ BOOL bMultiSelection;
+
+ void Init();
+
+ DECL_LINK( CancelBtnHdl, void * );
+ DECL_LINK( OkBtnHdl, void * );
+
+
+protected:
+
+ virtual void RefInputDone( BOOL bForced = FALSE );
+
+public:
+ ScSimpleRefDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData );
+ ~ScSimpleRefDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+ virtual BOOL Close();
+
+ void StartRefInput();
+
+ virtual String GetRefString() const;
+ virtual void SetRefString(const String &rStr);
+ virtual void FillInfo(SfxChildWinInfo&) const;
+
+ void SetCloseHdl( const Link& rLink );
+ void SetUnoLinks( const Link& rDone, const Link& rAbort,
+ const Link& rChange );
+
+ void SetFlags( BOOL bSetCloseOnButtonUp, BOOL bSetSingleCell, BOOL bSetMultiSelection );
+
+ void SetAutoReOpen(BOOL bFlag) {bAutoReOpen=bFlag;}
+};
+
+
+
+#endif // SC_DBNAMDLG_HXX
+
diff --git a/sc/source/ui/inc/sizedev.hxx b/sc/source/ui/inc/sizedev.hxx
new file mode 100644
index 000000000000..615755be0240
--- /dev/null
+++ b/sc/source/ui/inc/sizedev.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SIZEDEV_HXX
+#define SC_SIZEDEV_HXX
+
+#include <vcl/mapmod.hxx>
+
+class OutputDevice;
+class ScDocShell;
+
+class ScSizeDeviceProvider
+{
+ OutputDevice* pDevice;
+ BOOL bOwner;
+ double nPPTX;
+ double nPPTY;
+ MapMode aOldMapMode;
+
+public:
+ ScSizeDeviceProvider( ScDocShell* pDocSh );
+ ~ScSizeDeviceProvider();
+
+ OutputDevice* GetDevice() const { return pDevice; }
+ double GetPPTX() const { return nPPTX; }
+ double GetPPTY() const { return nPPTY; }
+ BOOL IsPrinter() const { return !bOwner; }
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/solveroptions.hrc b/sc/source/ui/inc/solveroptions.hrc
new file mode 100644
index 000000000000..e3be150ccd1b
--- /dev/null
+++ b/sc/source/ui/inc/solveroptions.hrc
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+#define FT_ENGINE 1
+#define FT_SETTINGS 2
+#define FT_OPTIONNAME 3
+
+#define LB_ENGINE 1
+#define LB_SETTINGS 2
+
+#define FL_BUTTONS 1
+
+#define BTN_EDIT 1
+#define BTN_HELP 2
+#define BTN_OK 3
+#define BTN_CANCEL 4
+
+#define NF_VALUE 1
+
+#define ED_VALUE 1
+
diff --git a/sc/source/ui/inc/solveroptions.hxx b/sc/source/ui/inc/solveroptions.hxx
new file mode 100644
index 000000000000..fc0714558be4
--- /dev/null
+++ b/sc/source/ui/inc/solveroptions.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SOLVEROPTIONS_HXX
+#define SC_SOLVEROPTIONS_HXX
+
+#include <vcl/dialog.hxx>
+
+#ifndef _SV_BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/field.hxx>
+#include <svx/checklbx.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace beans { struct PropertyValue; }
+} } }
+
+
+
+class ScSolverOptionsDialog : public ModalDialog
+{
+ FixedText maFtEngine;
+ ListBox maLbEngine;
+ FixedText maFtSettings;
+ SvxCheckListBox maLbSettings;
+ PushButton maBtnEdit;
+ FixedLine maFlButtons;
+ HelpButton maBtnHelp;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+
+ SvLBoxButtonData* mpCheckButtonData;
+ com::sun::star::uno::Sequence<rtl::OUString> maImplNames;
+ com::sun::star::uno::Sequence<rtl::OUString> maDescriptions;
+ String maEngine;
+ com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> maProperties;
+
+ DECL_LINK( EngineSelectHdl, ListBox* );
+ DECL_LINK( SettingsSelHdl, SvxCheckListBox* );
+ DECL_LINK( SettingsDoubleClickHdl, SvTreeListBox* );
+ DECL_LINK( ButtonHdl, PushButton* );
+
+ void ReadFromComponent();
+ void FillListBox();
+ void EditOption();
+
+public:
+ ScSolverOptionsDialog( Window* pParent,
+ const com::sun::star::uno::Sequence<rtl::OUString>& rImplNames,
+ const com::sun::star::uno::Sequence<rtl::OUString>& rDescriptions,
+ const String& rEngine,
+ const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProperties );
+ ~ScSolverOptionsDialog();
+
+ const String& GetEngine() const;
+ const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& GetProperties();
+};
+
+
+class ScSolverIntegerDialog : public ModalDialog
+{
+ FixedText maFtName;
+ NumericField maNfValue;
+ FixedLine maFlButtons;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+
+public:
+ ScSolverIntegerDialog( Window * pParent );
+ ~ScSolverIntegerDialog();
+
+ void SetOptionName( const String& rName );
+ void SetValue( sal_Int32 nValue );
+ sal_Int32 GetValue() const;
+};
+
+class ScSolverValueDialog : public ModalDialog
+{
+ FixedText maFtName;
+ Edit maEdValue;
+ FixedLine maFlButtons;
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+
+public:
+ ScSolverValueDialog( Window * pParent );
+ ~ScSolverValueDialog();
+
+ void SetOptionName( const String& rName );
+ void SetValue( double fValue );
+ double GetValue() const;
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/solverutil.hxx b/sc/source/ui/inc/solverutil.hxx
new file mode 100644
index 000000000000..89997e03c1a3
--- /dev/null
+++ b/sc/source/ui/inc/solverutil.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SOLVERUTIL_HXX
+#define SC_SOLVERUTIL_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace beans { struct PropertyValue; }
+ namespace sheet { class XSolver; }
+} } }
+
+
+class ScSolverUtil
+{
+public:
+ static void GetImplementations( com::sun::star::uno::Sequence<rtl::OUString>& rImplNames,
+ com::sun::star::uno::Sequence<rtl::OUString>& rDescriptions );
+ static com::sun::star::uno::Reference<com::sun::star::sheet::XSolver> GetSolver( const rtl::OUString& rImplName );
+ static com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> GetDefaults( const rtl::OUString& rImplName );
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/solvrdlg.hrc b/sc/source/ui/inc/solvrdlg.hrc
new file mode 100644
index 000000000000..7139abd2a5f6
--- /dev/null
+++ b/sc/source/ui/inc/solvrdlg.hrc
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // ->RID_SCDLG_SOLVER
+
+#define ED_FORMULACELL 1
+#define ED_TARGETVAL 2
+#define ED_VARCELL 3
+#define FT_FORMULACELL 1
+#define FT_TARGETVAL 2
+#define FT_VARCELL 3
+#define RB_FORMULACELL 1
+#define RB_VARCELL 2
+#define FL_VARIABLES 1
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 1
+#define STR_INVALIDVAL 1
+#define STR_INVALIDVAR 2
+#define STR_INVALIDFORM 3
+#define STR_NOFORMULA 4
+
diff --git a/sc/source/ui/inc/solvrdlg.hxx b/sc/source/ui/inc/solvrdlg.hxx
new file mode 100644
index 000000000000..fa1b9eb6341c
--- /dev/null
+++ b/sc/source/ui/inc/solvrdlg.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SOLVRDLG_HXX
+#define SC_SOLVRDLG_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include "anyrefdg.hxx"
+
+
+#include <vcl/fixed.hxx>
+#include <vcl/group.hxx>
+
+//----------------------------------------------------------------------------
+
+enum ScSolverErr
+ {
+ SOLVERR_NOFORMULA,
+ SOLVERR_INVALID_FORMULA,
+ SOLVERR_INVALID_VARIABLE,
+ SOLVERR_INVALID_TARGETVALUE
+ };
+
+
+//============================================================================
+
+class ScSolverDlg : public ScAnyRefDlg
+{
+public:
+ ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocument* pDocument,
+ ScAddress aCursorPos );
+ ~ScSolverDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual BOOL IsRefInputMode() const;
+ virtual void SetActive();
+ virtual BOOL Close();
+
+private:
+ FixedLine aFlVariables;
+ FixedText aFtFormulaCell;
+ formula::RefEdit aEdFormulaCell;
+ formula::RefButton aRBFormulaCell;
+
+ FixedText aFtTargetVal;
+ Edit aEdTargetVal;
+
+ FixedText aFtVariableCell;
+ formula::RefEdit aEdVariableCell;
+ formula::RefButton aRBVariableCell;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ ScAddress theFormulaCell;
+ ScAddress theVariableCell;
+ String theTargetValStr;
+
+ ScDocument* pDoc;
+ const SCTAB nCurTab;
+ formula::RefEdit* pEdActive;
+ BOOL bDlgLostFocus;
+ const String errMsgInvalidVar;
+ const String errMsgInvalidForm;
+ const String errMsgNoFormula;
+ const String errMsgInvalidVal;
+
+
+#ifdef _SOLVRDLG_CXX
+ void Init();
+ BOOL CheckTargetValue( String& rStrVal );
+ void RaiseError( ScSolverErr eError );
+
+ DECL_LINK( BtnHdl, PushButton* );
+ DECL_LINK( GetFocusHdl, Control* );
+ DECL_LINK( LoseFocusHdl, Control* );
+#endif // _SOLVERDLG_CXX
+};
+
+#endif // SC_SOLVRDLG_HXX
+
+
diff --git a/sc/source/ui/inc/sortdlg.hrc b/sc/source/ui/inc/sortdlg.hrc
new file mode 100644
index 000000000000..387690531cfd
--- /dev/null
+++ b/sc/source/ui/inc/sortdlg.hrc
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include "sc.hrc" // -> RID_SCDLG_SORT
+ // -> RID_SCPAGE_SORT_FIELDS
+ // -> RID_SCPAGE_SORT_OPTIONS
+ // -> RID_SCDLG_SORT_WARNING
+ // -> SCSTR_NONAME
+ // -> SCSTR_UNDEFINED
+ // -> SCSTR_FIELD
+
+/*
+#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
+#define TP_OPTIONS 2
+
+// TP_SORT_FIELDS:
+#define FL_SORT1 1
+#define FL_SORT2 2
+#define FL_SORT3 3
+#define LB_SORT1 4
+#define LB_SORT2 5
+#define LB_SORT3 6
+#define BTN_UP1 7
+#define BTN_UP2 8
+#define BTN_UP3 9
+#define BTN_DOWN1 10
+#define BTN_DOWN2 11
+#define BTN_DOWN3 12
+
+// TP_SORT_OPTIONS:
+#define FL_DIRECTION 1
+#define LB_SORT_USER 2
+#define LB_OUTAREA 3
+#define ED_OUTAREA 4
+#define FT_AREA_LABEL 5
+//#define FT_AREA 6
+#define BTN_SORT_USER 7
+#define BTN_CASESENSITIVE 8
+#define BTN_LABEL 9
+#define BTN_FORMATS 10
+#define BTN_COPYRESULT 11
+#define BTN_TOP_DOWN 12
+#define BTN_LEFT_RIGHT 13
+#define STR_COL_LABEL 14
+#define STR_ROW_LABEL 15
+#define FT_LANGUAGE 16
+#define LB_LANGUAGE 17
+#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
new file mode 100644
index 000000000000..e6f9ab1bf0c8
--- /dev/null
+++ b/sc/source/ui/inc/sortdlg.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SORTDLG_HXX
+#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
+#endif /* !LAYOUT_SFX_TABDIALOG_BROKEN */
+
+#if !LAYOUT_SFX_TABDIALOG_BROKEN
+#include <sfx2/layout.hxx>
+#include <layout/layout-pre.hxx>
+#endif
+
+class ScSortDlg : public SfxTabDialog
+{
+public:
+ ScSortDlg( Window* pParent,
+ const SfxItemSet* pArgSet );
+ ~ScSortDlg();
+
+ void SetHeaders( BOOL bHeaders );
+ void SetByRows ( BOOL bByRows );
+ BOOL GetHeaders() const;
+ BOOL GetByRows () const;
+
+
+private:
+ BOOL bIsHeaders;
+ BOOL bIsByRows;
+};
+
+inline void ScSortDlg::SetHeaders( BOOL bHeaders ) { bIsHeaders = bHeaders; }
+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
+
+#endif // SC_SORTDLG_HXX
diff --git a/sc/source/ui/inc/spelldialog.hxx b/sc/source/ui/inc/spelldialog.hxx
new file mode 100644
index 000000000000..eef0d170c2c8
--- /dev/null
+++ b/sc/source/ui/inc/spelldialog.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SPELLDIALOG_HXX
+#define SC_SPELLDIALOG_HXX
+
+#include <memory>
+#include <svx/SpellDialogChildWindow.hxx>
+
+// ============================================================================
+
+class ScConversionEngineBase;
+class ScSelectionState;
+class ScTabViewShell;
+class ScViewData;
+class ScDocShell;
+class ScDocument;
+
+/** Specialized spell check dialog child window for Calc.
+
+ This derivation of the ::svx::SpellDialogChildWindow base class provides
+ Calc specific implementations of the virtual functions GetNextWrongSentence()
+ and ApplyChangedSentence().
+ */
+class ScSpellDialogChildWindow : public ::svx::SpellDialogChildWindow
+{
+public:
+ SFX_DECL_CHILDWINDOW( ScSpellDialogChildWindow );
+
+ explicit ScSpellDialogChildWindow( Window* pParent, USHORT nId,
+ SfxBindings* pBindings, SfxChildWinInfo* pInfo );
+ virtual ~ScSpellDialogChildWindow();
+
+ /** This method makes the one from the base class public so that
+ it can be called from the view shell when one is created.
+ */
+ virtual void InvalidateSpellDialog();
+
+protected:
+ /** Iterate over the sentences in all text shapes and stop at the
+ next sentence with spelling errors. While doing so the view
+ mode may be changed and text shapes are set into edit mode.
+ */
+ virtual ::svx::SpellPortions GetNextWrongSentence( bool bRecheck );
+
+ /** This method is responsible for merging corrections made in the
+ spelling dialog back into the document.
+ */
+ virtual void ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck );
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+private:
+ void Reset();
+ void Init();
+
+ bool IsSelectionChanged();
+
+private:
+ typedef ::std::auto_ptr< ScConversionEngineBase > ScConvEnginePtr;
+ typedef ::std::auto_ptr< ScDocument > ScDocumentPtr;
+ typedef ::std::auto_ptr< ScSelectionState > ScSelectionStatePtr;
+
+ ScConvEnginePtr mxEngine;
+ ScDocumentPtr mxUndoDoc;
+ ScDocumentPtr mxRedoDoc;
+ ScSelectionStatePtr mxOldSel; /// Old selection state for comparison.
+ ScTabViewShell* mpViewShell;
+ ScViewData* mpViewData;
+ ScDocShell* mpDocShell;
+ ScDocument* mpDoc;
+ bool mbNeedNextObj;
+ bool mbOldIdleDisabled;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/spelleng.hxx b/sc/source/ui/inc/spelleng.hxx
new file mode 100644
index 000000000000..f44d4a8f7094
--- /dev/null
+++ b/sc/source/ui/inc/spelleng.hxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_SPELLENG_HXX
+#define SC_SPELLENG_HXX
+
+#include "editutil.hxx"
+#include "selectionstate.hxx"
+#include "spellparam.hxx"
+
+class ScViewData;
+class ScDocShell;
+class ScDocument;
+class SfxItemPool;
+
+// ============================================================================
+
+/** Base class for special type of edit engines, i.e. for spell checker and text conversion. */
+class ScConversionEngineBase : public ScEditEngineDefaulter
+{
+public:
+ explicit ScConversionEngineBase(
+ SfxItemPool* pEnginePool, ScViewData& rViewData,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc );
+
+ virtual ~ScConversionEngineBase();
+
+ /** Derived classes implement to convert all cells in the selection or sheet. */
+ virtual void ConvertAll( EditView& rEditView ) = 0;
+
+ /** Returns true, if at least one cell has been modified. */
+ inline bool IsAnyModified() const { return mbIsAnyModified; }
+ /** Returns true, if the entire document/selection has been finished. */
+ inline bool IsFinished() const { return mbFinished; }
+
+protected:
+ /** Implementation of cell iteration. Finds a cell that needs conversion.
+ @return true = Current cell needs conversion (i.e. spelling error found). */
+ bool FindNextConversionCell();
+ /** Restores the initial cursor position. */
+ void RestoreCursorPos();
+
+ /** Derived classes return, if the current text needs conversion (i.e. spelling error found).
+ @return true = Current edit text needs conversion. */
+ virtual bool NeedsConversion() = 0;
+
+ /** Derived classes may show a query box that asks whether to restart at top of the sheet.
+ @descr Default here is no dialog and restart always.
+ @return true = Restart at top, false = Stop the conversion. */
+ virtual bool ShowTableWrapDialog();
+ /** Derived classes may show a message box stating that the conversion is finished.
+ @descr Default here is no dialog. */
+ virtual void ShowFinishDialog();
+
+private:
+ /** Fills the edit engine from a document cell. */
+ void FillFromCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
+
+protected: // for usage in derived classes
+ ScViewData& mrViewData;
+ ScDocShell& mrDocShell;
+ ScDocument& mrDoc;
+
+private:
+ ScSelectionState maSelState; /// Selection data of the document.
+ ScDocument* mpUndoDoc; /// Document stores all old cells for UNDO action.
+ ScDocument* mpRedoDoc; /// Document stores all new cells for REDO action.
+ LanguageType meCurrLang; /// Current cell language.
+ SCCOL mnStartCol; /// Initial column index.
+ SCROW mnStartRow; /// Initial row index.
+ SCTAB mnStartTab; /// Initial sheet index.
+ SCCOL mnCurrCol; /// Current column index.
+ SCROW mnCurrRow; /// Current row index.
+ bool mbIsAnyModified; /// true = At least one cell has been changed.
+ bool mbInitialState; /// true = Not searched for a cell yet.
+ bool mbWrappedInTable; /// true = Already restarted at top of the sheet.
+ bool mbFinished; /// true = Entire document/selection finished.
+};
+
+// ============================================================================
+
+/** Edit engine for spell checking. */
+class ScSpellingEngine : public ScConversionEngineBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XSpellChecker1 > XSpellCheckerRef;
+
+ explicit ScSpellingEngine(
+ SfxItemPool* pEnginePool,
+ ScViewData& rViewData,
+ ScDocument* pUndoDoc,
+ ScDocument* pRedoDoc,
+ XSpellCheckerRef xSpeller );
+
+ /** Checks spelling of all cells in the selection or sheet. */
+ virtual void ConvertAll( EditView& rEditView );
+
+protected:
+ /** Callback from edit engine to check the next cell. */
+ virtual BOOL SpellNextDocument();
+
+ /** Returns true, if the current text contains a spelling error. */
+ virtual bool NeedsConversion();
+
+ /** Show a query box that asks whether to restart at top of the sheet.
+ @return true = Restart at top, false = Stop the conversion. */
+ virtual bool ShowTableWrapDialog();
+ /** Show a message box stating that spell checking is finished. */
+ virtual void ShowFinishDialog();
+
+private:
+ /** Returns the spelling dialog if it is open. */
+ Window* GetDialogParent();
+};
+
+// ============================================================================
+
+/** Edit engine for text conversion. */
+class ScTextConversionEngine : public ScConversionEngineBase
+{
+public:
+ explicit ScTextConversionEngine(
+ SfxItemPool* pEnginePool,
+ ScViewData& rViewData,
+ const ScConversionParam& rConvParam,
+ ScDocument* pUndoDoc,
+ ScDocument* pRedoDoc );
+
+ /** Converts all cells in the selection or sheet according to set language. */
+ virtual void ConvertAll( EditView& rEditView );
+
+protected:
+ /** Callback from edit engine to convert the next cell. */
+ virtual BOOL ConvertNextDocument();
+
+ /** Returns true, if the current text contains text to convert. */
+ virtual bool NeedsConversion();
+
+private:
+ ScConversionParam maConvParam; /// Conversion parameters.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/spellparam.hxx b/sc/source/ui/inc/spellparam.hxx
new file mode 100644
index 000000000000..ecc66d7ccdcb
--- /dev/null
+++ b/sc/source/ui/inc/spellparam.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_SPELLPARAM_HXX
+#define SC_SPELLPARAM_HXX
+
+#include <vcl/font.hxx>
+
+// ============================================================================
+
+/** Specifiers for sheet conversion (functions iterating over the sheet and modifying cells). */
+enum ScConversionType
+{
+ SC_CONVERSION_SPELLCHECK, /// Spell checker.
+ SC_CONVERSION_HANGULHANJA, /// Hangul-Hanja converter.
+ SC_CONVERSION_CHINESE_TRANSL /// Chinese simplified/traditional converter.
+};
+
+// ---------------------------------------------------------------------------
+
+/** Parameters for conversion. */
+class ScConversionParam
+{
+public:
+ /** Constructs an empty parameter struct with the passed conversion type. */
+ explicit ScConversionParam( ScConversionType eConvType );
+
+ /** Constructs parameter struct for text conversion without changing the language. */
+ explicit ScConversionParam(
+ ScConversionType eConvType,
+ LanguageType eLang,
+ sal_Int32 nOptions,
+ bool bIsInteractive );
+
+ /** Constructs parameter struct for text conversion with language change. */
+ explicit ScConversionParam(
+ ScConversionType eConvType,
+ LanguageType eSourceLang,
+ LanguageType eTargetLang,
+ const Font& rTargetFont,
+ sal_Int32 nOptions,
+ bool bIsInteractive );
+
+ inline ScConversionType GetType() const { return meConvType; }
+ inline LanguageType GetSourceLang() const { return meSourceLang; }
+ inline LanguageType GetTargetLang() const { return meTargetLang; }
+ inline const Font* GetTargetFont() const { return mbUseTargetFont ? &maTargetFont : 0; }
+ inline sal_Int32 GetOptions() const { return mnOptions; }
+ inline bool IsInteractive() const { return mbIsInteractive; }
+
+private:
+ ScConversionType meConvType; /// Type of the conversion.
+ LanguageType meSourceLang; /// Source language for conversion.
+ LanguageType meTargetLang; /// Target language for conversion.
+ Font maTargetFont; /// Target font to be used if language has to be changed.
+ sal_Int32 mnOptions; /// Conversion options.
+ bool mbUseTargetFont; /// True = Use maTargetFont to change font during conversion.
+ bool mbIsInteractive; /// True = Text conversion has (specific) dialog that may be raised.
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/inc/strindlg.hxx b/sc/source/ui/inc/strindlg.hxx
new file mode 100644
index 000000000000..f84d8e4e2b51
--- /dev/null
+++ b/sc/source/ui/inc/strindlg.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_STRINDLG_HXX
+#define SC_STRINDLG_HXX
+
+
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/imagebtn.hxx>
+#include <vcl/edit.hxx>
+
+#include <layout/layout.hxx>
+#include <layout/layout-pre.hxx>
+
+//------------------------------------------------------------------------
+
+class ScStringInputDlg : public ModalDialog
+{
+public:
+ ScStringInputDlg( Window* pParent,
+ const String& rTitle,
+ const String& rEditTitle,
+ const String& rDefault,
+ ULONG nHelpId );
+ ~ScStringInputDlg();
+
+ void GetInputString( String& rString ) const;
+
+private:
+ FixedText aFtEditTitle;
+ Edit aEdInput;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+};
+
+#include <layout/layout-post.hxx>
+
+#endif // SC_STRINDLG_HXX
+
+
diff --git a/sc/source/ui/inc/styledlg.hrc b/sc/source/ui/inc/styledlg.hrc
new file mode 100644
index 000000000000..4a954bb3afc1
--- /dev/null
+++ b/sc/source/ui/inc/styledlg.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define TP_NUMBER 2
+#define TP_FONT 3
+#define TP_ALIGNMENT 4
+#define TP_BORDER 5
+#define TP_BACKGROUND 6
+#define TP_PROTECTION 7
+#define TP_PAGE_STD 8
+#define TP_PAGE_HEADER 9
+#define TP_PAGE_FOOTER 10
+#define TP_TABLE 11
+#define TP_FONTEFF 12
+#define TP_ASIAN 13
+
diff --git a/sc/source/ui/inc/styledlg.hxx b/sc/source/ui/inc/styledlg.hxx
new file mode 100644
index 000000000000..63e37becf188
--- /dev/null
+++ b/sc/source/ui/inc/styledlg.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_STYLEDLG_HXX
+#define SC_STYLEDLG_HXX
+
+#ifndef _SFX_HXX
+#endif
+
+#include <sfx2/styledlg.hxx>
+
+//==================================================================
+
+class SfxStyleSheetBase;
+
+class ScStyleDlg : public SfxStyleDialog
+{
+public:
+ ScStyleDlg( Window* pParent,
+ SfxStyleSheetBase& rStyleBase,
+ USHORT nRscId );
+ ~ScStyleDlg();
+
+protected:
+ virtual void PageCreated( USHORT nPageId, SfxTabPage& rTabPage );
+ virtual const SfxItemSet* GetRefreshedSet();
+
+private:
+ USHORT nDlgRsc;
+};
+
+
+#endif // SC_STYLEDLG_HXX
+
+
diff --git a/sc/source/ui/inc/submenu.hrc b/sc/source/ui/inc/submenu.hrc
new file mode 100644
index 000000000000..4e5ad6d28d9e
--- /dev/null
+++ b/sc/source/ui/inc/submenu.hrc
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// IDs fuer Untermenues
+
+// 1 ist nicht erlaubt ????
+#define SUBMENU_EDIT 2
+#define SUBMENU_FILL 3
+#define SUBMENU_DELBREAK 4
+#define SUBMENU_VIEW 5
+#define SUBMENU_INSERT 6
+#define SUBMENU_INSBREAK 7
+#define SUBMENU_NAME 8
+#define SUBMENU_INSOBJ 9
+#define SUBMENU_DATA 10
+#define SUBMENU_FILTER 11
+#define SUBMENU_OUTLINE 12
+#define SUBMENU_PIVOT 13
+#define SUBMENU_EXTRA 14
+#define SUBMENU_AUDIT 15
+#define SUBMENU_PROTECT 16
+#define SUBMENU_ROW 17
+#define SUBMENU_COL 18
+#define SUBMENU_TAB 19
+#define SUBMENU_MERGE 20
+#define SUBMENU_AREA 21
+#define SUBMENU_MIRROR 22
+#define SUBMENU_OBJARRANGE 23
+#define SUBMENU_ANCHOR 24
+#define SUBMENU_POPARRANGE 25
+#define SUBMENU_OLEARRANGE 26
+#define SUBMENU_MAIL 27
+#define SUBMENU_OPTIONS 28
+#define SUBMENU_TOOLBARS 29
+#define SUBMENU_GRAPHIC 30
+#define SUBMENU_SPELLING 31
+#define SUBMENU_CELLCONT 32
+#define SUBMENU_OBJMIRROR 33
+#define SUBMENU_OBJALIGN 34
+#define SUBMENU_OBJANCHOR 35
+#define SUBMENU_SENDTO 36
+#define SUBMENU_CHANGES 37
+#define SUBMENU_EDIT_TABLE 38
+#define MN_TEMPLATES 39
diff --git a/sc/source/ui/inc/subtdlg.hrc b/sc/source/ui/inc/subtdlg.hrc
new file mode 100644
index 000000000000..66c63df48953
--- /dev/null
+++ b/sc/source/ui/inc/subtdlg.hrc
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+/*
+#define RID_SCDLG_SUBTOTALS 256
+#define RID_SCPAGE_SUBT_GROUP 256
+#define RID_SCPAGE_SUBT_OPTIONS 257
+*/
+
+// TabDialog
+#define BTN_REMOVE 1
+#define PAGE_GROUP1 2
+#define PAGE_GROUP2 3
+#define PAGE_GROUP3 4
+#define PAGE_OPTIONS 5
+
+// Gruppen TabPages
+#define FT_GROUP 10
+#define LB_GROUP 11
+#define FT_COLUMNS 12
+#define WND_COLUMNS 13
+#define LB_FUNCTIONS 14
+#define FT_FUNCTIONS 15
+
+// Optionen TabPage
+#define FL_GROUP 20
+#define BTN_PAGEBREAK 21
+#define BTN_CASE 22
+#define BTN_SORT 23
+
+#define FL_SORT 30
+#define BTN_ASCENDING 31
+#define BTN_DESCENDING 32
+#define BTN_FORMATS 33
+#define BTN_USERDEF 34
+#define LB_USERDEF 35
+
+
diff --git a/sc/source/ui/inc/subtdlg.hxx b/sc/source/ui/inc/subtdlg.hxx
new file mode 100644
index 000000000000..ec68d0e1fba1
--- /dev/null
+++ b/sc/source/ui/inc/subtdlg.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SUBTDLG_HXX
+#define SC_SUBTDLG_HXX
+
+#ifndef _SFX_HXX
+#endif
+
+#include <sfx2/tabdlg.hxx>
+
+#include "scui_def.hxx" //CHINA001
+//------------------------------------------------------------------------
+
+//CHINA001 #define SCRET_REMOVE 0x42
+
+//==================================================================
+
+class ScSubTotalDlg : public SfxTabDialog
+{
+public:
+ ScSubTotalDlg( Window* pParent,
+ const SfxItemSet* pArgSet );
+private:
+ PushButton aBtnRemove;
+ DECL_LINK( RemoveHdl, PushButton * );
+};
+
+
+#endif // SC_SUBTDLG_HXX
+
+
diff --git a/sc/source/ui/inc/tabbgcolordlg.hxx b/sc/source/ui/inc/tabbgcolordlg.hxx
new file mode 100644
index 000000000000..338609ae0e4d
--- /dev/null
+++ b/sc/source/ui/inc/tabbgcolordlg.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * 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: tabbgcolordlg.hxx,v $
+ * $Revision: 1.0 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_TABBGCOLORDLG_HXX
+#define SC_TABBGCOLORDLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/imagebtn.hxx>
+#include <svtools/valueset.hxx>
+
+//------------------------------------------------------------------------
+
+class ScTabBgColorDlg : public ModalDialog
+{
+public:
+ ScTabBgColorDlg( Window* pParent,
+ const String& rTitle,
+ const String& rTabBgColorNoColorText,
+ const Color& rDefaultColor,
+ ULONG nHelpId );
+ ~ScTabBgColorDlg();
+
+ void GetSelectedColor( Color& rColor ) const;
+
+private:
+ class ScTabBgColorValueSet : public ValueSet
+ {
+ public:
+ ScTabBgColorValueSet(Control* pParent, const ResId& rResId, ScTabBgColorDlg* pTabBgColorDlg);
+
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ private:
+ ScTabBgColorDlg* aTabBgColorDlg;
+ };
+
+ Control aBorderWin;
+ ScTabBgColorValueSet aTabBgColorSet;
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+ Color aTabBgColor;
+ const String aTabBgColorNoColorText;
+ ULONG mnHelpId;
+
+ void FillColorValueSets_Impl();
+
+ DECL_LINK( TabBgColorDblClickHdl_Impl, ValueSet* );
+ DECL_LINK( TabBgColorOKHdl_Impl, OKButton* pBtn );
+};
+
+#endif // SC_TABBGCOLORDLG_HXX
diff --git a/sc/source/ui/inc/tabcont.hxx b/sc/source/ui/inc/tabcont.hxx
new file mode 100644
index 000000000000..d77ee812fdb3
--- /dev/null
+++ b/sc/source/ui/inc/tabcont.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TABCONT_HXX
+#define SC_TABCONT_HXX
+
+#include "address.hxx"
+#include <svtools/tabbar.hxx>
+#include <svtools/transfer.hxx>
+
+
+class ScViewData;
+
+// ---------------------------------------------------------------------------
+
+// initial size
+#define SC_TABBAR_DEFWIDTH 270
+
+
+class ScTabControl : public TabBar, public DropTargetHelper, public DragSourceHelper
+{
+private:
+ ScViewData* pViewData;
+ USHORT nMouseClickPageId; /// Last page ID after mouse button down/up
+ USHORT nSelPageIdByMouse; /// Selected page ID, if selected with mouse
+ BOOL bErrorShown;
+
+ void DoDrag( const Region& rRegion );
+
+ USHORT GetMaxId() const;
+ SCTAB GetPrivatDropPos(const Point& rPos );
+
+protected:
+ virtual void Select();
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );
+
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel );
+
+ virtual long StartRenaming();
+ virtual long AllowRenaming();
+ virtual void EndRenaming();
+ virtual void Mirror();
+
+public:
+ ScTabControl( Window* pParent, ScViewData* pData );
+ ~ScTabControl();
+
+ using TabBar::StartDrag;
+
+ void UpdateStatus();
+ void ActivateView(BOOL bActivate);
+
+ void SetSheetLayoutRTL( BOOL bSheetRTL );
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/tabopdlg.hrc b/sc/source/ui/inc/tabopdlg.hrc
new file mode 100644
index 000000000000..5ae127b63e73
--- /dev/null
+++ b/sc/source/ui/inc/tabopdlg.hrc
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // ->RID_SCDLG_TABOP
+
+#define ED_FORMULARANGE 1
+#define ED_ROWCELL 2
+#define ED_COLCELL 3
+#define FT_FORMULARANGE 1
+#define FT_ROWCELL 2
+#define FT_COLCELL 3
+#define RB_FORMULARANGE 1
+#define RB_ROWCELL 2
+#define RB_COLCELL 3
+#define FL_VARIABLES 1
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 1
+#define STR_NOFORMULA 1
+#define STR_NOCOLROW 2
+#define STR_WRONGFORMULA 3
+#define STR_WRONGROWCOL 4
+#define STR_NOCOLFORMULA 5
+#define STR_NOROWFORMULA 6
+
+
diff --git a/sc/source/ui/inc/tabopdlg.hxx b/sc/source/ui/inc/tabopdlg.hxx
new file mode 100644
index 000000000000..e9286ca5ee96
--- /dev/null
+++ b/sc/source/ui/inc/tabopdlg.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TABOPDLG_HXX
+#define SC_TABOPDLG_HXX
+
+#include <vcl/fixed.hxx>
+#include <vcl/group.hxx>
+#include "global.hxx"
+#include "address.hxx"
+#include "anyrefdg.hxx"
+
+
+//------------------------------------------------------------------------
+
+enum ScTabOpErr
+{
+ TABOPERR_NOFORMULA = 1,
+ TABOPERR_NOCOLROW,
+ TABOPERR_WRONGFORMULA,
+ TABOPERR_WRONGROW,
+ TABOPERR_NOCOLFORMULA,
+ TABOPERR_WRONGCOL,
+ TABOPERR_NOROWFORMULA
+};
+
+//========================================================================
+
+class ScTabOpDlg : public ScAnyRefDlg
+{
+public:
+ ScTabOpDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocument* pDocument,
+ const ScRefAddress& rCursorPos );
+ ~ScTabOpDlg();
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc );
+ virtual BOOL IsRefInputMode() const { return TRUE; }
+ virtual void SetActive();
+
+ virtual BOOL Close();
+
+private:
+ FixedLine aFlVariables;
+ FixedText aFtFormulaRange;
+ formula::RefEdit aEdFormulaRange;
+ formula::RefButton aRBFormulaRange;
+
+ FixedText aFtRowCell;
+ formula::RefEdit aEdRowCell;
+ formula::RefButton aRBRowCell;
+
+ FixedText aFtColCell;
+ formula::RefEdit aEdColCell;
+ formula::RefButton aRBColCell;
+
+ OKButton aBtnOk;
+ CancelButton aBtnCancel;
+ HelpButton aBtnHelp;
+
+ ScRefAddress theFormulaCell;
+ ScRefAddress theFormulaEnd;
+ ScRefAddress theRowCell;
+ ScRefAddress theColCell;
+
+ ScDocument* pDoc;
+ const SCTAB nCurTab;
+ formula::RefEdit* pEdActive;
+ BOOL bDlgLostFocus;
+ const String errMsgNoFormula;
+ const String errMsgNoColRow;
+ const String errMsgWrongFormula;
+ const String errMsgWrongRowCol;
+ const String errMsgNoColFormula;
+ const String errMsgNoRowFormula;
+
+#ifdef _TABOPDLG_CXX
+ void Init();
+ void RaiseError( ScTabOpErr eError );
+
+ DECL_LINK( BtnHdl, PushButton* );
+ DECL_LINK( GetFocusHdl, Control* );
+ DECL_LINK( LoseFocusHdl, Control* );
+#endif // _TABOPDLG_CXX
+};
+
+#endif // SC_TABOPDLG_HXX
+
+
+
diff --git a/sc/source/ui/inc/tabpages.hxx b/sc/source/ui/inc/tabpages.hxx
new file mode 100644
index 000000000000..71d62f964fef
--- /dev/null
+++ b/sc/source/ui/inc/tabpages.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TABPAGES_HXX
+#define SC_TABPAGES_HXX
+
+#ifndef _GROUP_HXX //autogen
+#include <vcl/group.hxx>
+#endif
+#include <svtools/stdctrl.hxx>
+#include <sfx2/tabdlg.hxx>
+
+//========================================================================
+
+class ScTabPageProtection : public SfxTabPage
+{
+public:
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rAttrSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreAttrs );
+ virtual void Reset ( const SfxItemSet& );
+
+protected:
+ using SfxTabPage::DeactivatePage;
+ virtual int DeactivatePage ( SfxItemSet* pSet = NULL );
+
+private:
+ ScTabPageProtection( Window* pParent,
+ const SfxItemSet& rCoreAttrs );
+ ~ScTabPageProtection();
+
+private:
+ FixedLine aFlProtect;
+ TriStateBox aBtnHideCell;
+ TriStateBox aBtnProtect;
+ TriStateBox aBtnHideFormula;
+ FixedInfo aTxtHint;
+
+ FixedLine aFlPrint;
+ TriStateBox aBtnHidePrint;
+ FixedInfo aTxtHint2;
+
+ // aktueller Status:
+ BOOL bTriEnabled; // wenn vorher Dont-Care
+ BOOL bDontCare; // alles auf TriState
+ BOOL bProtect; // einzelne Einstellungen ueber TriState sichern
+ BOOL bHideForm;
+ BOOL bHideCell;
+ BOOL bHidePrint;
+
+ // Handler:
+ DECL_LINK( ButtonClickHdl, TriStateBox* pBox );
+ void UpdateButtons();
+};
+
+
+
+#endif // SC_TABPAGES_HXX
diff --git a/sc/source/ui/inc/tabpopsh.hxx b/sc/source/ui/inc/tabpopsh.hxx
new file mode 100644
index 000000000000..177e3d75136f
--- /dev/null
+++ b/sc/source/ui/inc/tabpopsh.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TABPOPSH_HXX
+#define SC_TABPOPSH_HXX
+
+#include <sfx2/module.hxx>
+#include <sfx2/shell.hxx>
+
+#include "shellids.hxx"
+
+class ScTabPopShell : public SfxShell
+{
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SCID_TABPOP_SHELL);
+
+ ScTabPopShell(SfxItemPool& rItemPool);
+ ~ScTabPopShell();
+
+ void DummyExec( SfxRequest& rReq );
+ void DummyState( SfxItemSet& rSet );
+};
+
+
+
+#endif
+
+
diff --git a/sc/source/ui/inc/tabsplit.hxx b/sc/source/ui/inc/tabsplit.hxx
new file mode 100644
index 000000000000..a06664c7c4ee
--- /dev/null
+++ b/sc/source/ui/inc/tabsplit.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TABSPLIT_HXX
+#define SC_TABSPLIT_HXX
+
+
+#include <vcl/split.hxx>
+
+class ScViewData;
+
+class ScTabSplitter : public Splitter
+{
+private:
+ ScViewData* pViewData;
+ BOOL bFixed;
+
+protected:
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+
+ virtual void Splitting( Point& rSplitPos );
+
+public:
+ ScTabSplitter( Window* pParent, WinBits nWinStyle,
+ ScViewData* pData );
+ ~ScTabSplitter();
+
+ void SetFixed(BOOL bSet);
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
new file mode 100644
index 000000000000..a6e99613f2ea
--- /dev/null
+++ b/sc/source/ui/inc/tabview.hxx
@@ -0,0 +1,533 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_TABVIEW_HXX
+#define SC_TABVIEW_HXX
+
+#include <vcl/scrbar.hxx>
+
+//REMOVE #ifndef SO2_DECL_SVINPLACECLIENT_DEFINED
+//REMOVE #define SO2_DECL_SVINPLACECLIENT_DEFINED
+//REMOVE SO2_DECL_REF(SvInPlaceClient)
+//REMOVE #endif
+
+#include <sfx2/ipclient.hxx>
+
+#include "viewutil.hxx"
+#include "select.hxx"
+
+class ScEditEngineDefaulter;
+class ScGridWindow;
+class ScOutlineWindow;
+class ScRowBar;
+class ScColBar;
+class ScTabControl;
+class ScTabViewShell;
+class SfxPrinter;
+class ScDrawView;
+class SvBorder;
+class FuPoor;
+class Splitter;
+class ScTabSplitter;
+class SdrView;
+class SdrObject;
+class ScHintWindow;
+class ScPageBreakData;
+class ScHighlightRanges;
+struct ChartSelectionInfo;
+class SdrHdlList;
+
+namespace com { namespace sun { namespace star {
+namespace chart2 { namespace data {
+ struct HighlightedRange;
+}}}}}
+
+#define SPLIT_HANDLE_SIZE 3
+#define SC_FORCEMODE_NONE 0xff
+
+// ---------------------------------------------------------------------------
+// Hilfs - Fenster
+
+class ScCornerButton : public Window
+{
+private:
+ ScViewData* pViewData;
+ BOOL bAdd;
+
+protected:
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Resize();
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+public:
+ ScCornerButton( Window* pParent, ScViewData* pData, BOOL bAdditional );
+ ~ScCornerButton();
+
+ virtual void StateChanged( StateChangedType nType );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+};
+
+
+// ---------------------------------------------------------------------------
+
+class ScTabView
+{
+private:
+ Window* pFrameWin; // als erstes !!!
+ ScViewData aViewData; // muss ganz vorne stehen !
+
+ ScViewSelectionEngine* pSelEngine;
+ ScViewFunctionSet aFunctionSet;
+
+ ScHeaderSelectionEngine* pHdrSelEng;
+ ScHeaderFunctionSet aHdrFunc;
+
+ SfxInPlaceClient* pIPClient;
+
+ ScDrawView* pDrawView;
+
+ Size aFrameSize; // wie bei DoResize uebergeben
+ Point aBorderPos;
+
+ BOOL bDrawSelMode; // nur Zeichenobjekte selektieren ?
+
+ FuPoor* pDrawActual;
+ FuPoor* pDrawOld;
+
+ ScGridWindow* pGridWin[4];
+ ScColBar* pColBar[2];
+ ScRowBar* pRowBar[2];
+ ScOutlineWindow* pColOutline[2];
+ ScOutlineWindow* pRowOutline[2];
+ ScTabSplitter* pHSplitter;
+ ScTabSplitter* pVSplitter;
+ ScTabControl* pTabControl;
+ ScrollBar aVScrollTop;
+ ScrollBar aVScrollBottom; // anfangs sichtbar
+ ScrollBar aHScrollLeft; // anfangs sichtbar
+ ScrollBar aHScrollRight;
+ ScCornerButton aCornerButton;
+ ScCornerButton aTopButton;
+ ScrollBarBox aScrollBarBox;
+
+ ScHintWindow* pInputHintWindow; // Eingabemeldung bei Gueltigkeit
+
+ ScPageBreakData* pPageBreakData; // fuer Seitenumbruch-Modus
+ ScHighlightRanges* pHighlightRanges;
+
+ ScDocument* pBrushDocument; // cell formats for format paint brush
+ SfxItemSet* pDrawBrushSet; // drawing object attributes for paint brush
+ BOOL bLockPaintBrush; // keep for more than one use?
+
+ Timer aScrollTimer;
+ ScGridWindow* pTimerWindow;
+ MouseEvent aTimerMEvt;
+
+ ULONG nTipVisible;
+
+ BOOL bDragging; // fuer Scrollbars
+ long nPrevDragPos;
+
+ BOOL bIsBlockMode; // Block markieren
+ BOOL bBlockNeg; // wird Markierung aufgehoben?
+ BOOL bBlockCols; // werden ganze Spalten markiert?
+ BOOL bBlockRows; // werden ganze Zeilen markiert?
+
+ SCCOL nBlockStartX;
+ SCCOL nBlockStartXOrig;
+ SCCOL nBlockEndX;
+
+ SCROW nBlockStartY;
+ SCROW nBlockStartYOrig;
+ SCROW nBlockEndY;
+
+ SCTAB nBlockStartZ;
+ SCTAB nBlockEndZ;
+
+ SCCOL nOldCurX;
+ SCROW nOldCurY;
+
+ double mfPendingTabBarWidth; // Tab bar width relative to frame window width.
+
+ BOOL bMinimized;
+ BOOL bInUpdateHeader;
+ BOOL bInActivatePart;
+ BOOL bInZoomUpdate;
+ BOOL bMoveIsShift;
+ BOOL bNewStartIfMarking;
+
+ void Init();
+
+ void DoAddWin( ScGridWindow* pWin );
+
+ void InitScrollBar( ScrollBar& rScrollBar, long nMaxVal );
+ DECL_LINK( ScrollHdl, ScrollBar* );
+ DECL_LINK( EndScrollHdl, ScrollBar* );
+
+ DECL_LINK( SplitHdl, Splitter* );
+ void DoHSplit(long nSplitPos);
+ void DoVSplit(long nSplitPos);
+
+ DECL_LINK( TimerHdl, Timer* );
+
+ void UpdateVarZoom();
+
+ static void SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, BOOL bLayoutRTL );
+ static long GetScrollBarPos( ScrollBar& rScroll, BOOL bLayoutRTL );
+
+protected:
+ void UpdateHeaderWidth( const ScVSplitPos* pWhich = NULL,
+ const SCROW* pPosY = NULL );
+
+ void HideTip();
+ void ShowRefTip();
+
+ void ZoomChanged();
+ void UpdateShow();
+ void GetBorderSize( SvBorder& rBorder, const Size& rSize );
+
+ void ResetDrawDragMode();
+ BOOL IsDrawTextEdit() const;
+ void DrawEnableAnim(BOOL bSet);
+ //HMHvoid DrawShowMarkHdl(BOOL bShow);
+
+ void MakeDrawView( BYTE nForceDesignMode = SC_FORCEMODE_NONE );
+
+ void HideNoteMarker();
+
+ void UpdateIMap( SdrObject* pObj );
+
+public:
+ ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
+//UNUSED2009-05 ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell );
+ ~ScTabView();
+
+ void MakeDrawLayer();
+
+ void HideListBox();
+
+ BOOL HasHintWindow() const { return pInputHintWindow != NULL; }
+ void RemoveHintWindow();
+ void TestHintWindow();
+
+
+ DECL_LINK( TabBarResize, void* );
+ /** Sets an absolute tab bar width (in pixels). */
+ void SetTabBarWidth( long nNewWidth );
+ /** Sets a relative tab bar width.
+ @param fRelTabBarWidth Tab bar width relative to frame window width (0.0 ... 1.0). */
+ void SetRelTabBarWidth( double fRelTabBarWidth );
+ /** Sets a relative tab bar width. Tab bar is resized again in next DoResize().
+ @param fRelTabBarWidth Tab bar width relative to frame window width (0.0 ... 1.0). */
+ void SetPendingRelTabBarWidth( double fRelTabBarWidth );
+ /** Returns the current tab bar width in pixels. */
+ long GetTabBarWidth() const;
+ /** Returns the current tab bar width relative to the frame window width (0.0 ... 1.0). */
+ double GetRelTabBarWidth() const;
+ /** Returns the pending tab bar width relative to the frame window width (0.0 ... 1.0). */
+ double GetPendingRelTabBarWidth() const;
+
+ void DoResize( const Point& rOffset, const Size& rSize, BOOL bInner = FALSE );
+ void RepeatResize( BOOL bUpdateFix = TRUE );
+ void UpdateFixPos();
+ Point GetGridOffset() const;
+
+ BOOL IsDrawSelMode() const { return bDrawSelMode; }
+ void SetDrawSelMode(BOOL bNew) { bDrawSelMode = bNew; }
+
+ void SetDrawFuncPtr(FuPoor* pFuncPtr) { pDrawActual = pFuncPtr; }
+ void SetDrawFuncOldPtr(FuPoor* pFuncPtr) { pDrawOld = pFuncPtr; }
+ FuPoor* GetDrawFuncPtr() { return pDrawActual; }
+ FuPoor* GetDrawFuncOldPtr() { return pDrawOld; }
+
+ void DrawDeselectAll();
+ void DrawMarkListHasChanged();
+ void UpdateAnchorHandles();
+//UNUSED2008-05 String GetSelectedChartName() const;
+
+ ScPageBreakData* GetPageBreakData() { return pPageBreakData; }
+ ScHighlightRanges* GetHighlightRanges() { return pHighlightRanges; }
+
+ void UpdatePageBreakData( BOOL bForcePaint = FALSE );
+
+ void DrawMarkRect( const Rectangle& rRect );
+
+ ScViewData* GetViewData() { return &aViewData; }
+ const ScViewData* GetViewData() const { return &aViewData; }
+
+ ScViewFunctionSet* GetFunctionSet() { return &aFunctionSet; }
+ ScViewSelectionEngine* GetSelEngine() { return pSelEngine; }
+
+ BOOL SelMouseButtonDown( const MouseEvent& rMEvt );
+
+ ScDrawView* GetScDrawView() { return pDrawView; }
+ SdrView* GetSdrView(); // gegen CLOKs
+
+ BOOL IsMinimized() const { return bMinimized; }
+
+ void TabChanged();
+ void SetZoom( const Fraction& rNewX, const Fraction& rNewY, BOOL bAll );
+ SC_DLLPUBLIC void RefreshZoom();
+ void SetPagebreakMode( BOOL bSet );
+
+ void UpdateLayerLocks();
+
+ void UpdateDrawTextOutliner();
+ void DigitLanguageChanged();
+
+ void UpdateInputLine();
+
+ void InitRefMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScRefType eType,
+ BOOL bPaint = TRUE );
+ void DoneRefMode( BOOL bContinue = FALSE );
+ void UpdateRef( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ );
+ void StopRefMode();
+
+//UNUSED2008-05 void EndSelection();
+ void StopMarking();
+ void FakeButtonUp( ScSplitPos eWhich );
+
+ Window* GetActiveWin();
+ Window* GetWindowByPos( ScSplitPos ePos );
+
+ ScSplitPos FindWindow( Window* pWindow ) const;
+
+ void SetActivePointer( const Pointer& rPointer );
+//UNUSED2008-05 void SetActivePointer( const ResId& rId );
+
+ void ActiveGrabFocus();
+//UNUSED2008-05 void ActiveCaptureMouse();
+//UNUSED2008-05 void ActiveReleaseMouse();
+//UNUSED2008-05 Point ActivePixelToLogic( const Point& rDevicePoint );
+
+ void ClickCursor( SCCOL nPosX, SCROW nPosY, BOOL bControl );
+
+ SC_DLLPUBLIC void SetCursor( SCCOL nPosX, SCROW nPosY, BOOL bNew = FALSE );
+
+ SC_DLLPUBLIC void CellContentChanged();
+ void SelectionChanged();
+ void CursorPosChanged();
+ void UpdateInputContext();
+
+ void CheckSelectionTransfer();
+
+ void InvertHorizontal( ScVSplitPos eWhich, long nDragPos );
+ void InvertVertical( ScHSplitPos eWhich, long nDragPos );
+
+ Point GetInsertPos();
+
+ Point GetChartInsertPos( const Size& rSize, const ScRange& rCellRange );
+ Point GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart );
+
+ void UpdateAutoFillMark();
+
+ void HideCursor(); // nur aktiver Teil
+ void ShowCursor();
+ void HideAllCursors();
+ void ShowAllCursors();
+
+ void AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
+ const ScSplitPos* pWhich = NULL );
+
+ SvxZoomType GetZoomType() const;
+ void SetZoomType( SvxZoomType eNew, BOOL bAll );
+ USHORT CalcZoom( SvxZoomType eType, USHORT nOldZoom );
+
+// void CalcZoom( SvxZoomType eType, USHORT& rZoom, SCCOL& rCol, SCROW& rRow );
+
+ sal_Bool HasPageFieldDataAtCursor() const;
+ void StartDataSelect();
+
+ // MoveCursorAbs - absolut
+ // MoveCursorRel - einzelne Zellen
+ // MoveCursorPage - Bildschirmseite
+ // MoveCursorArea - Datenblock
+ // MoveCursorEnd - links oben / benutzter Bereich
+
+ SC_DLLPUBLIC void MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
+ BOOL bShift, BOOL bControl,
+ BOOL bKeepOld = FALSE, BOOL bKeepSel = FALSE );
+ void MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+ BOOL bShift, BOOL bKeepSel = FALSE );
+ void MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+ BOOL bShift, BOOL bKeepSel = FALSE );
+ void MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+ BOOL bShift, BOOL bKeepSel = FALSE );
+ void MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+ BOOL bShift, BOOL bKeepSel = FALSE );
+ void MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift );
+
+ void MoveCursorEnter( BOOL bShift ); // Shift fuer Richtung (kein Markieren)
+
+ BOOL MoveCursorKeyInput( const KeyEvent& rKeyEvent );
+
+ void FindNextUnprot( BOOL bShift, BOOL bInSelection = TRUE );
+
+ void SetNewStartIfMarking();
+
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ //void SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE );
+ SC_DLLPUBLIC void SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE );
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+ void SelectNextTab( short nDir, BOOL bExtendSelection = FALSE );
+
+ void ActivateView( BOOL bActivate, BOOL bFirst );
+ void ActivatePart( ScSplitPos eWhich );
+ BOOL IsInActivatePart() const { return bInActivatePart; }
+
+ void SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt );
+ void ResetTimer();
+
+ void ScrollX( long nDeltaX, ScHSplitPos eWhich, BOOL bUpdBars = TRUE );
+ void ScrollY( long nDeltaY, ScVSplitPos eWhich, BOOL bUpdBars = TRUE );
+ SC_DLLPUBLIC void ScrollLines( long nDeltaX, long nDeltaY ); // aktives
+
+ BOOL ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos );
+
+ void ScrollToObject( SdrObject* pDrawObj );
+ void MakeVisible( const Rectangle& rHMMRect );
+
+ // Zeichnen
+
+ void InvertBlockMark(SCCOL nBlockStartX, SCROW nBlockStartY,
+ SCCOL nBlockEndX, SCROW nBlockEndY);
+
+//UNUSED2008-05 void DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
+//UNUSED2008-05 ScSplitPos ePos );
+//UNUSED2008-05 void PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
+//UNUSED2008-05 void PaintLeftRow( SCROW nRow );
+//UNUSED2008-05 void PaintTopCol( SCCOL nCol );
+
+ void PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ ScUpdateMode eMode = SC_UPDATE_ALL );
+
+ void PaintGrid();
+
+ void PaintTopArea( SCCOL nStartCol, SCCOL nEndCol );
+ void PaintTop();
+
+ void PaintLeftArea( SCROW nStartRow, SCROW nEndRow );
+ void PaintLeft();
+
+ BOOL PaintExtras();
+
+ void RecalcPPT();
+
+ void CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress);
+
+ void UpdateSelectionOverlay();
+ void UpdateShrinkOverlay();
+ void UpdateAllOverlays();
+
+ void UpdateFormulas();
+ void InterpretVisible();
+ void CheckNeedsRepaint();
+
+ void PaintRangeFinder( long nNumber = -1 );
+ void AddHighlightRange( const ScRange& rRange, const Color& rColor );
+ void ClearHighlightRanges();
+
+ void DoChartSelection( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::chart2::data::HighlightedRange > & rHilightRanges );
+
+ long GetGridWidth( ScHSplitPos eWhich );
+ long GetGridHeight( ScVSplitPos eWhich );
+
+ void UpdateScrollBars();
+ void SetNewVisArea();
+
+ void InvalidateAttribs();
+
+ void MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow );
+ void KillEditView( BOOL bNoPaint );
+ void UpdateEditView();
+
+
+ // Bloecke
+
+ void SelectAll( BOOL bContinue = FALSE );
+ void SelectAllTables();
+ void DeselectAllTables();
+
+ void MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ BOOL bCols = FALSE, BOOL bRows = FALSE, BOOL bCellSelection = FALSE );
+ void InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ BOOL bTestNeg = FALSE,
+ BOOL bCols = FALSE, BOOL bRows = FALSE );
+ void InitOwnBlockMode();
+ void DoneBlockMode( BOOL bContinue = FALSE );
+
+ BOOL IsBlockMode() const { return bIsBlockMode; }
+
+ void MarkColumns();
+ void MarkRows();
+ void MarkDataArea( BOOL bIncludeCursor = TRUE );
+ void MarkMatrixFormula();
+ void Unmark();
+
+ void MarkRange( const ScRange& rRange, BOOL bSetCursor = TRUE, BOOL bContinue = FALSE );
+
+ BOOL IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
+
+ void PaintMarks( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
+ void PaintBlock( BOOL bReset = FALSE );
+
+ void SetMarkData( const ScMarkData& rNew );
+ void MarkDataChanged();
+
+ void LockModifiers( USHORT nModifiers );
+ USHORT GetLockedModifiers() const;
+ void ViewOptionsHasChanged( BOOL bHScrollChanged,
+ BOOL bGraphicsChanged = FALSE);
+
+ Point GetMousePosPixel();
+
+ void SnapSplitPos( Point& rScreenPosPixel );
+ void FreezeSplitters( BOOL bFreeze );
+ void RemoveSplit();
+ void SplitAtCursor();
+ void SplitAtPixel( const Point& rPixel, BOOL bHor, BOOL bVer );
+ void InvalidateSplit();
+
+ void ErrorMessage( USHORT nGlobStrId );
+ Window* GetParentOrChild( USHORT nChildId );
+
+ void EnableRefInput(BOOL bFlag=TRUE);
+
+ Window* GetFrameWin() const { return pFrameWin; }
+
+ BOOL HasPaintBrush() const { return pBrushDocument || pDrawBrushSet; }
+ ScDocument* GetBrushDocument() const { return pBrushDocument; }
+ SfxItemSet* GetDrawBrushSet() const { return pDrawBrushSet; }
+ BOOL IsPaintBrushLocked() const { return bLockPaintBrush; }
+ void SetBrushDocument( ScDocument* pNew, BOOL bLock );
+ void SetDrawBrushSet( SfxItemSet* pNew, BOOL bLock );
+ void ResetBrushDocument();
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
new file mode 100644
index 000000000000..28cc2a823928
--- /dev/null
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_TABVWSH_HXX
+#define SC_TABVWSH_HXX
+
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/viewfac.hxx>
+#include <editeng/svxenum.hxx>
+#include "scdllapi.h"
+#include "dbfunc.hxx" // -> tabview
+#include "target.hxx"
+#include "rangelst.hxx" // ScRangeListRef
+#include "shellids.hxx"
+#include "tabprotection.hxx" // for ScPasswordHash
+
+class FmFormShell;
+class SbxObject;
+class SdrOle2Obj;
+class SfxBindings;
+class SfxChildWindow;
+class SfxModelessDialog;
+class SvxBorderLine;
+class SvxBoxObjectRef;
+class SvxNumberInfoItem;
+struct SfxChildWinInfo;
+
+class ScArea;
+class ScAuditingShell;
+class ScDrawShell;
+class ScDrawTextObjectBar;
+class ScEditShell;
+class ScInputHandler;
+class ScPivotShell;
+class ScDrawFormShell;
+class ScCellShell;
+class ScOleObjectShell;
+class ScGraphicShell;
+class ScMediaShell;
+class ScChartShell;
+class ScPageBreakShell;
+class ScDPObject;
+class ScNavigatorSettings;
+
+struct ScHeaderFieldData;
+
+namespace com { namespace sun { namespace star { namespace frame {
+ class XDispatchProviderInterceptor;
+} } } }
+
+namespace svx {
+ class ExtrusionBar;
+ class FontworkBar;
+}
+
+enum ObjectSelectionType
+{
+ OST_NONE,
+ OST_Cell,
+ OST_Editing,
+ OST_DrawText,
+ OST_Drawing,
+ OST_DrawForm,
+ OST_Pivot,
+ OST_Auditing,
+ OST_OleObject,
+ OST_Chart,
+ OST_Graphic,
+ OST_Media
+};
+
+//==================================================================
+
+
+class ScTabViewShell: public SfxViewShell, public ScDBFunc
+{
+private:
+ static USHORT nInsertCtrlState;
+ static USHORT nInsCellsCtrlState;
+ static USHORT nInsObjCtrlState;
+
+ SvxHtmlOptions aHTMLOpt;
+ ObjectSelectionType eCurOST;
+ USHORT nDrawSfxId;
+ USHORT nCtrlSfxId;
+ USHORT nFormSfxId;
+ String sDrawCustom; // current custom shape type
+ ScDrawShell* pDrawShell;
+ ScDrawTextObjectBar* pDrawTextShell;
+ ScEditShell* pEditShell;
+ ScPivotShell* pPivotShell;
+ ScAuditingShell* pAuditingShell;
+ ScDrawFormShell* pDrawFormShell;
+ ScCellShell* pCellShell;
+ ScOleObjectShell* pOleObjectShell;
+ ScChartShell* pChartShell;
+ ScGraphicShell* pGraphicShell;
+ ScMediaShell* pMediaShell;
+ ScPageBreakShell* pPageBreakShell;
+ svx::ExtrusionBar* pExtrusionBarShell;
+ svx::FontworkBar* pFontworkBarShell;
+
+ FmFormShell* pFormShell;
+
+ ScInputHandler* pInputHandler; // fuer OLE-Eingabezeile
+
+ SvxBorderLine* pCurFrameLine;
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatchProviderInterceptor >
+ xDisProvInterceptor;
+
+ Point aWinPos;
+
+ ScTabViewTarget aTarget;
+ ScArea* pPivotSource;
+ ScDPObject* pDialogDPObject;
+
+ ScNavigatorSettings* pNavSettings;
+
+ // used in first Activate
+ BOOL bFirstActivate;
+
+ BOOL bActiveDrawSh;
+ BOOL bActiveDrawTextSh;
+ BOOL bActivePivotSh;
+ BOOL bActiveAuditingSh;
+ BOOL bActiveDrawFormSh;
+ BOOL bActiveOleObjectSh;
+ BOOL bActiveChartSh;
+ BOOL bActiveGraphicSh;
+ BOOL bActiveMediaSh;
+ BOOL bActiveEditSh;
+
+ BOOL bFormShellAtTop; // does the FormShell need to be on top?
+
+
+ BOOL bDontSwitch; // EditShell nicht abschalten
+ BOOL bInFormatDialog; // fuer GetSelectionText
+ BOOL bPrintSelected; // for result of SvxPrtQryBox
+
+ BOOL bReadOnly; // um Status-Aenderungen zu erkennen
+
+ SbxObject* pScSbxObject;
+
+//UNUSED2008-05 BOOL bChartDlgIsEdit; // Datenbereich aendern
+ BOOL bChartAreaValid; // wenn Chart aufgezogen wird
+ String aEditChartName;
+ ScRangeListRef aChartSource;
+ Rectangle aChartPos;
+ SCTAB nChartDestTab;
+ USHORT nCurRefDlgId;
+
+ SfxBroadcaster* pAccessibilityBroadcaster;
+
+ static const int MASTERENUMCOMMANDS = 6;
+ String aCurrShapeEnumCommand[ MASTERENUMCOMMANDS ];
+
+private:
+ void Construct( BYTE nForceDesignMode = SC_FORCEMODE_NONE );
+
+//UNUSED2008-05 void SetMySubShell( SfxShell* pShell );
+ SfxShell* GetMySubShell() const;
+
+ void DoReadUserData( const String& rData );
+ void DoReadUserDataSequence( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rSettings );
+
+ DECL_LINK( SimpleRefClose, String* );
+ DECL_LINK( SimpleRefDone, String* );
+ DECL_LINK( SimpleRefAborted, String* );
+ DECL_LINK( SimpleRefChange, String* );
+ DECL_LINK( FormControlActivated, FmFormShell* );
+ DECL_LINK( HtmlOptionsHdl, void * );
+
+protected:
+ virtual void Activate(BOOL bMDI);
+ virtual void Deactivate(BOOL bMDI);
+ virtual USHORT PrepareClose( BOOL bUI = TRUE, BOOL bForBrowsing = FALSE );
+
+ virtual void ShowCursor(FASTBOOL bOn);
+
+ virtual void Move(); // Benachrichtigung
+
+ virtual void AdjustPosSizePixel( const Point &rPos, const Size &rSize ); // alt
+
+ virtual void InnerResizePixel( const Point &rOfs, const Size &rSize ); // neu
+ virtual void OuterResizePixel( const Point &rOfs, const Size &rSize );
+ virtual void SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY );
+
+ virtual void QueryObjAreaPixel( Rectangle& rRect ) const;
+
+ virtual Size GetOptimalSizePixel() const;
+
+ virtual String GetSelectionText( BOOL bWholeWord );
+ virtual BOOL HasSelection( BOOL bText ) const;
+ virtual String GetDescription() const;
+
+ virtual void WriteUserData(String &, BOOL bBrowse = FALSE);
+ virtual void ReadUserData(const String &, BOOL bBrowse = FALSE);
+ virtual void WriteUserDataSequence (::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, sal_Bool bBrowse = sal_False );
+ virtual void ReadUserDataSequence (const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, sal_Bool bBrowse = sal_False );
+
+ virtual void UIDeactivated( SfxInPlaceClient* pClient );
+
+ virtual FASTBOOL KeyInput( const KeyEvent &rKeyEvent );
+ virtual SdrView* GetDrawView() const;
+
+public:
+ TYPEINFO_VISIBILITY(SC_DLLPUBLIC);
+
+ SFX_DECL_INTERFACE(SCID_TABVIEW_SHELL)
+ SFX_DECL_VIEWFACTORY(ScTabViewShell);
+
+
+ // -> Clone-Methode fuer Factory
+
+//UNUSED2008-05 ScTabViewShell( SfxViewFrame* pViewFrame,
+//UNUSED2008-05 const ScTabViewShell& rWin );
+
+ // aus einer allgemeinen Shell konstruieren und
+ // soviel wie moeglich uebernehmen (SliderPos etc.):
+
+ ScTabViewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh );
+
+ virtual ~ScTabViewShell();
+
+ Window* GetDialogParent();
+
+ bool IsRefInputMode() const;
+ void ExecuteInputDirect();
+
+ ScInputHandler* GetInputHandler() const;
+ void UpdateInputHandler( BOOL bForce = FALSE, BOOL bStopEditing = TRUE );
+ void UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust );
+ BOOL TabKeyInput(const KeyEvent& rKEvt);
+ BOOL SfxKeyInput(const KeyEvent& rKEvt);
+
+ void SetActive();
+
+ SvxBorderLine* GetDefaultFrameLine() const { return pCurFrameLine; }
+ void SetDefaultFrameLine(const SvxBorderLine* pLine );
+
+//UNUSED2008-05 void ExecuteShowNIY( SfxRequest& rReq );
+//UNUSED2008-05 void StateDisabled( SfxItemSet& rSet );
+
+ SC_DLLPUBLIC void Execute( SfxRequest& rReq );
+ SC_DLLPUBLIC void GetState( SfxItemSet& rSet );
+
+ void ExecuteTable( SfxRequest& rReq );
+ void GetStateTable( SfxItemSet& rSet );
+
+ void WindowChanged();
+ void ExecDraw(SfxRequest&);
+ void ExecDrawIns(SfxRequest& rReq);
+ void GetDrawState(SfxItemSet &rSet);
+ void GetDrawInsState(SfxItemSet &rSet);
+ void ExecGallery(SfxRequest& rReq); // StarGallery
+ void GetGalleryState(SfxItemSet& rSet);
+
+ void ExecChildWin(SfxRequest& rReq);
+ void GetChildWinState( SfxItemSet& rSet );
+
+ void ExecImageMap( SfxRequest& rReq );
+ void GetImageMapState( SfxItemSet& rSet );
+
+ void ExecTbx( SfxRequest& rReq );
+ void GetTbxState( SfxItemSet& rSet );
+
+ void ExecuteSave( SfxRequest& rReq );
+ void GetSaveState( SfxItemSet& rSet );
+ void ExecSearch( SfxRequest& rReq );
+
+ void ExecuteUndo(SfxRequest& rReq);
+ void GetUndoState(SfxItemSet &rSet);
+
+ void ExecuteSbx( SfxRequest& rReq );
+ void GetSbxState( SfxItemSet& rSet );
+
+ void ExecuteObject(SfxRequest& rReq);
+ void GetObjectState(SfxItemSet &rSet);
+
+ void ExecDrawOpt(SfxRequest& rReq);
+ void GetDrawOptState(SfxItemSet &rSet);
+
+
+ void SetDrawShell( BOOL bActive );
+ void SetDrawTextShell( BOOL bActive );
+
+ void SetPivotShell( BOOL bActive );
+ ScArea* GetPivotSource(){return pPivotSource;}
+ void SetPivotSource(ScArea* pSrc){pPivotSource=pSrc;}
+ void SetDialogDPObject( const ScDPObject* pObj );
+ const ScDPObject* GetDialogDPObject() const { return pDialogDPObject; }
+
+ BOOL GetDontSwitch(){return bDontSwitch;}
+ void SetDontSwitch(BOOL bFlag){bDontSwitch=bFlag;}
+
+
+ void SetAuditShell( BOOL bActive );
+ void SetDrawFormShell( BOOL bActive );
+ void SetEditShell(EditView* pView, BOOL bActive );
+ void SetOleObjectShell( BOOL bActive );
+ void SetChartShell( BOOL bActive );
+ void SetGraphicShell( BOOL bActive );
+ void SetMediaShell( BOOL bActive );
+
+
+ void SetDrawShellOrSub();
+ void SetCurSubShell( ObjectSelectionType eOST, BOOL bForce = FALSE );
+
+ void SetFormShellAtTop( BOOL bSet );
+
+ ObjectSelectionType GetCurObjectSelectionType();
+
+ virtual ErrCode DoVerb(long nVerb);
+
+
+ void StopEditShell();
+ BOOL IsDrawTextShell() const;
+ BOOL IsAuditShell() const;
+
+ void SetDrawTextUndo( SfxUndoManager* pUndoMgr );
+
+ void FillFieldData( ScHeaderFieldData& rData );
+
+//UNUSED2008-05 void ResetChartArea();
+ void SetChartArea( const ScRangeListRef& rSource, const Rectangle& rDest );
+ BOOL GetChartArea( ScRangeListRef& rSource, Rectangle& rDest, SCTAB& rTab ) const;
+
+//UNUSED2008-05 BOOL IsChartDlgEdit() const;
+//UNUSED2008-05 void SetChartDlgEdit(BOOL bFlag){bChartDlgIsEdit=bFlag;}
+
+ void SetEditChartName(const String& aStr){aEditChartName=aStr;}
+//UNUSED2008-05 const String& GetEditChartName() const;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ScNavigatorSettings* GetNavigatorSettings();
+
+ // Drucken:
+ virtual SfxPrinter* GetPrinter( BOOL bCreate = FALSE );
+ virtual USHORT SetPrinter( SfxPrinter* pNewPrinter,
+ USHORT nDiffFlags = SFX_PRINTER_ALL, bool bIsApi=false );
+
+ virtual PrintDialog* CreatePrintDialog( Window* pParent );
+ virtual SfxTabPage* CreatePrintOptionsPage( Window *pParent, const SfxItemSet &rOptions );
+ virtual void PreparePrint( PrintDialog* pPrintDialog = NULL );
+ virtual ErrCode DoPrint( SfxPrinter *pPrinter,
+ PrintDialog *pPrintDialog,
+ BOOL bSilent, BOOL bIsAPI );
+ virtual USHORT Print( SfxProgress& rProgress, BOOL bIsAPI, PrintDialog* pPrintDialog = NULL );
+
+ void ConnectObject( SdrOle2Obj* pObj );
+ BOOL ActivateObject( SdrOle2Obj* pObj, long nVerb );
+
+ void DeactivateOle();
+
+ SC_DLLPUBLIC static ScTabViewShell* GetActiveViewShell();
+ SfxModelessDialog* CreateRefDialog( SfxBindings* pB, SfxChildWindow* pCW,
+ SfxChildWinInfo* pInfo,
+ Window* pParent, USHORT nSlotId );
+
+ void UpdateOleZoom();
+ inline SbxObject* GetScSbxObject() const
+ { return pScSbxObject; }
+ inline void SetScSbxObject( SbxObject* pOb )
+ { pScSbxObject = pOb; }
+
+ FmFormShell* GetFormShell() const { return pFormShell; }
+
+ void InsertURL( const String& rName, const String& rURL, const String& rTarget,
+ USHORT nMode );
+ void InsertURLButton( const String& rName, const String& rURL, const String& rTarget,
+ const Point* pInsPos = NULL );
+ void InsertURLField( const String& rName, const String& rURL, const String& rTarget );
+
+ BOOL SelectObject( const String& rName );
+
+ void SetInFormatDialog(BOOL bFlag) {bInFormatDialog=bFlag;}
+ BOOL IsInFormatDialog() {return bInFormatDialog;}
+
+ void ForceMove() { Move(); }
+
+ void MakeNumberInfoItem ( ScDocument* pDoc,
+ ScViewData* pViewData,
+ SvxNumberInfoItem** ppItem );
+
+ void UpdateNumberFormatter ( ScDocument* pDoc,
+ const SvxNumberInfoItem& rInfoItem );
+
+ void ExecuteCellFormatDlg ( SfxRequest& rReq, USHORT nTabPage = 0xffff );
+
+ BOOL GetFunction( String& rFuncStr, sal_uInt16 nErrCode = 0 );
+
+ void StartSimpleRefDialog( const String& rTitle, const String& rInitVal,
+ BOOL bCloseOnButtonUp, BOOL bSingleCell, BOOL bMultiSelection );
+ void StopSimpleRefDialog();
+
+ void SetCurRefDlgId( USHORT nNew );
+
+ void AddAccessibilityObject( SfxListener& rObject );
+ void RemoveAccessibilityObject( SfxListener& rObject );
+ void BroadcastAccessibility( const SfxHint &rHint );
+ BOOL HasAccessibilityObjects();
+
+ bool ExecuteRetypePassDlg(ScPasswordHash eDesiredHash);
+
+ using ScTabView::ShowCursor;
+};
+
+//==================================================================
+
+
+#endif
+
diff --git a/sc/source/ui/inc/target.hxx b/sc/source/ui/inc/target.hxx
new file mode 100644
index 000000000000..6fc62ffaa8cf
--- /dev/null
+++ b/sc/source/ui/inc/target.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TARGET_HXX
+#define SC_TARGET_HXX
+
+#include <svl/undo.hxx>
+
+class ScTabViewShell;
+
+class ScTabViewTarget : public SfxRepeatTarget
+{
+private:
+ ScTabViewShell* pViewShell;
+
+public:
+ TYPEINFO();
+
+ ScTabViewTarget( ScTabViewShell* pShell ) : pViewShell( pShell ) {}
+ virtual ~ScTabViewTarget();
+
+ ScTabViewShell* GetViewShell() const { return pViewShell; }
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/tbinsert.hrc b/sc/source/ui/inc/tbinsert.hrc
new file mode 100644
index 000000000000..44c0d295cfc6
--- /dev/null
+++ b/sc/source/ui/inc/tbinsert.hrc
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define RID_TOOLBOX_INSERT 1
+#define RID_TOOLBOX_INSCELLS 2
+#define RID_TOOLBOX_INSOBJ 3
+
+
diff --git a/sc/source/ui/inc/tbinsert.hxx b/sc/source/ui/inc/tbinsert.hxx
new file mode 100644
index 000000000000..a056da0a982c
--- /dev/null
+++ b/sc/source/ui/inc/tbinsert.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TBINSERT_HXX
+#define SC_TBINSERT_HXX
+
+#include <sfx2/tbxctrl.hxx>
+
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+
+class ScTbxInsertCtrl : public SfxToolBoxControl
+{
+ USHORT nLastSlotId;
+
+ using SfxToolBoxControl::Select;
+ virtual void Select( BOOL bMod1 = FALSE );
+
+public:
+ SFX_DECL_TOOLBOX_CONTROL();
+
+ ScTbxInsertCtrl( USHORT nSlotId, USHORT nId, ToolBox& rBox );
+ ~ScTbxInsertCtrl();
+
+ virtual SfxPopupWindowType GetPopupWindowType() const;
+ virtual SfxPopupWindow* CreatePopupWindow();
+ virtual void StateChanged( USHORT nSID,
+ SfxItemState eState,
+ const SfxPoolItem* pState );
+};
+
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+/*
+class ScTbxInsertPopup : public SfxPopupWindow
+{
+ SfxToolBoxManager aTbx;
+ ResId aRIdWinTemp;
+ ResId aRIdTbxTemp;
+
+ Link aTbxClickHdl;
+
+ DECL_LINK( TbxSelectHdl, ToolBox* );
+ DECL_LINK( TbxClickHdl, ToolBox* );
+
+protected:
+ virtual void PopupModeEnd();
+
+public:
+ ScTbxInsertPopup( USHORT nId, WindowAlign eAlign,
+ const ResId& rRIdWin, const ResId& rRIdTbx,
+ SfxBindings& rBindings );
+ ~ScTbxInsertPopup();
+
+ virtual SfxPopupWindow* Clone() const;
+ void StartSelection();
+};
+*/
+
+
+#endif
+
diff --git a/sc/source/ui/inc/tbzoomsliderctrl.hxx b/sc/source/ui/inc/tbzoomsliderctrl.hxx
new file mode 100644
index 000000000000..6ea4f6e169ed
--- /dev/null
+++ b/sc/source/ui/inc/tbzoomsliderctrl.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+#ifndef _SC_ZOOMSLIDERTBCONTRL_HXX
+#define _SC_ZOOMSLIDERTBCONTRL_HXX
+
+#ifndef _WINDOW_HXX //autogen
+#include <vcl/window.hxx>
+#endif
+#ifndef _SFXPOOLITEM_HXX //autogen
+#include <svl/poolitem.hxx>
+#endif
+#ifndef _SFXTBXCTRL_HXX //autogen
+#include <sfx2/tbxctrl.hxx>
+#endif
+#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#endif
+#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
+#include <com/sun/star/frame/XFrame.hpp>
+#endif
+#include <svx/zoomslideritem.hxx>
+
+
+//class ScZoomSliderControl define
+class ScZoomSliderControl: public SfxToolBoxControl
+{
+public:
+ SFX_DECL_TOOLBOX_CONTROL();
+ ScZoomSliderControl( USHORT nSlotId, USHORT nId, ToolBox& rTbx );
+ ~ScZoomSliderControl();
+
+ virtual void StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState );
+ virtual Window* CreateItemWindow( Window *pParent );
+};
+
+//========================================================================
+// class ScZoomSliderWnd define---------------------------------------
+//========================================================================
+class ScZoomSliderWnd: public Window
+{
+private:
+ struct ScZoomSliderWnd_Impl;
+ ScZoomSliderWnd_Impl* mpImpl;
+ Size aLogicalSize;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > m_xDispatchProvider;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > m_xFrame;
+
+ USHORT Offset2Zoom( long nOffset ) const;
+ long Zoom2Offset( USHORT nZoom ) const;
+ void DoPaint( const Rectangle& rRect );
+
+public:
+ ScZoomSliderWnd( Window* pParent, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& _xFrame , USHORT nCurrentZoom );
+ ~ScZoomSliderWnd();
+ void UpdateFromItem( const SvxZoomSliderItem* pZoomSliderItem );
+
+protected:
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void Paint( const Rectangle& rRect );
+};
+#endif
diff --git a/sc/source/ui/inc/textdlgs.hxx b/sc/source/ui/inc/textdlgs.hxx
new file mode 100644
index 000000000000..302b5de5ffd2
--- /dev/null
+++ b/sc/source/ui/inc/textdlgs.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TEXTDLGS_HXX
+#define SC_TEXTDLGS_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+class SfxObjectShell;
+
+//
+// Zeichen-Tab-Dialog
+//
+
+class ScCharDlg : public SfxTabDialog
+{
+private:
+ const SfxItemSet& rOutAttrs;
+ const SfxObjectShell& rDocShell;
+
+ virtual void PageCreated( USHORT nId, SfxTabPage &rPage );
+
+public:
+ ScCharDlg( Window* pParent, const SfxItemSet* pAttr,
+ const SfxObjectShell* pDocShell );
+ ~ScCharDlg() {}
+};
+
+//
+// Absatz-Tab-Dialog
+//
+
+class ScParagraphDlg : public SfxTabDialog
+{
+private:
+ const SfxItemSet& rOutAttrs;
+
+ virtual void PageCreated( USHORT nId, SfxTabPage &rPage );
+
+public:
+ ScParagraphDlg( Window* pParent, const SfxItemSet* pAttr );
+ ~ScParagraphDlg() {}
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/textimportoptions.hrc b/sc/source/ui/inc/textimportoptions.hrc
new file mode 100644
index 000000000000..93c554ef5c45
--- /dev/null
+++ b/sc/source/ui/inc/textimportoptions.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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 <sc.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define FL_CHOOSE_LANG 4
+#define RB_AUTOMATIC 5
+#define RB_CUSTOM 6
+#define LB_CUSTOM_LANG 7
+#define FL_OPTION 8
+#define BTN_CONVERT_DATE 9
diff --git a/sc/source/ui/inc/textimportoptions.hxx b/sc/source/ui/inc/textimportoptions.hxx
new file mode 100644
index 000000000000..bbb2bf6ebf09
--- /dev/null
+++ b/sc/source/ui/inc/textimportoptions.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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: langbox.hxx,v $
+ * $Revision: 1.4.242.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_UI_IMPORTOPTIONS_HXX
+#define SC_UI_IMPORTOPTIONS_HXX
+
+#include "vcl/dialog.hxx"
+#include "vcl/button.hxx"
+#include "vcl/fixed.hxx"
+#include "i18npool/lang.h"
+#include "svx/langbox.hxx"
+
+class ScTextImportOptionsDlg : public ModalDialog
+{
+public:
+ ScTextImportOptionsDlg(Window* pParent);
+ virtual ~ScTextImportOptionsDlg();
+
+ virtual short Execute();
+
+ LanguageType getLanguageType() const;
+ bool isDateConversionSet() const;
+
+private:
+ void init();
+
+private:
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ FixedLine maFlChooseLang;
+
+ RadioButton maRbAutomatic;
+ RadioButton maRbCustom;
+
+ SvxLanguageBox maLbCustomLang;
+
+ FixedLine maFlOption;
+
+ CheckBox maBtnConvertDate;
+
+ DECL_LINK( OKHdl, OKButton* );
+
+ DECL_LINK( RadioHdl, RadioButton* );
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/tpcalc.hxx b/sc/source/ui/inc/tpcalc.hxx
new file mode 100644
index 000000000000..31f2c9458c83
--- /dev/null
+++ b/sc/source/ui/inc/tpcalc.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPCALC_HXX
+#define SC_TPCALC_HXX
+
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/field.hxx>
+#include <vcl/group.hxx>
+#include <svtools/stdctrl.hxx>
+#include "editfield.hxx"
+
+//===================================================================
+
+class ScDocOptions;
+
+class ScTpCalcOptions : public SfxTabPage
+{
+public:
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreSet );
+ virtual void Reset ( const SfxItemSet& rCoreSet );
+ using SfxTabPage::DeactivatePage;
+ virtual int DeactivatePage ( SfxItemSet* pSet = NULL );
+
+private:
+ ScTpCalcOptions( Window* pParent,
+ const SfxItemSet& rCoreSet );
+ ~ScTpCalcOptions();
+
+private:
+ FixedLine aGbZRefs;
+ CheckBox aBtnIterate;
+ FixedText aFtSteps;
+ NumericField aEdSteps;
+ FixedText aFtEps;
+ ScDoubleField aEdEps;
+
+ FixedLine aSeparatorFL;
+ FixedLine aGbDate;
+ RadioButton aBtnDateStd;
+ RadioButton aBtnDateSc10;
+ RadioButton aBtnDate1904;
+
+ FixedLine aHSeparatorFL;
+ CheckBox aBtnCase;
+ CheckBox aBtnCalc;
+ CheckBox aBtnMatch;
+ CheckBox aBtnRegex;
+ CheckBox aBtnLookUp;
+ CheckBox aBtnGeneralPrec;
+
+ FixedText aFtPrec;
+ NumericField aEdPrec;
+
+ ScDocOptions* pOldOptions;
+ ScDocOptions* pLocalOptions;
+ USHORT nWhichCalc;
+
+#ifdef _TPCALC_CXX
+private:
+ void Init();
+
+ //------------------------------------
+ // Handler:
+ DECL_LINK( RadioClickHdl, RadioButton* );
+ DECL_LINK( CheckClickHdl, CheckBox* );
+
+#endif
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/tphf.hxx b/sc/source/ui/inc/tphf.hxx
new file mode 100644
index 000000000000..dcf730712a40
--- /dev/null
+++ b/sc/source/ui/inc/tphf.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPHF_HXX
+#define SC_TPHF_HXX
+
+
+#include <svx/hdft2.hxx>
+
+class ScStyleDlg;
+
+//========================================================================
+
+class ScHFPage : public SvxHFPage
+{
+public:
+ virtual ~ScHFPage();
+
+ virtual void Reset( const SfxItemSet& rSet );
+ virtual BOOL FillItemSet( SfxItemSet& rOutSet );
+
+ void SetPageStyle( const String& rName ) { aStrPageStyle = rName; }
+ void SetStyleDlg ( const ScStyleDlg* pDlg ) { pStyleDlg = pDlg; }
+
+protected:
+ ScHFPage( Window* pParent,
+ USHORT nResId,
+ const SfxItemSet& rSet,
+ USHORT nSetId );
+
+// using SvxHFPage::ActivatePage;
+// using SvxHFPage::DeactivatePage;
+ virtual void ActivatePage();
+ virtual void DeactivatePage();
+ virtual void ActivatePage( const SfxItemSet& rSet );
+ virtual int DeactivatePage( SfxItemSet* pSet = 0 );
+
+private:
+ PushButton aBtnEdit;
+ SfxItemSet aDataSet;
+ String aStrPageStyle;
+ USHORT nPageUsage;
+ const ScStyleDlg* pStyleDlg;
+
+#ifdef _TPHF_CXX
+private:
+ DECL_LINK( BtnHdl, PushButton* );
+ DECL_LINK( HFEditHdl, void* );
+ DECL_LINK( TurnOnHdl, CheckBox* );
+#endif
+};
+
+//========================================================================
+
+class ScHeaderPage : public ScHFPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rSet );
+ static USHORT* GetRanges();
+
+private:
+ ScHeaderPage( Window* pParent, const SfxItemSet& rSet );
+};
+
+//========================================================================
+
+class ScFooterPage : public ScHFPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rSet );
+ static USHORT* GetRanges();
+
+private:
+ ScFooterPage( Window* pParent, const SfxItemSet& rSet );
+};
+
+
+#endif // SC_TPHF_HXX
+
diff --git a/sc/source/ui/inc/tphfedit.hxx b/sc/source/ui/inc/tphfedit.hxx
new file mode 100644
index 000000000000..d9d26d2111cd
--- /dev/null
+++ b/sc/source/ui/inc/tphfedit.hxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPHFEDIT_HXX
+#define SC_TPHFEDIT_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/pageitem.hxx>
+#include <svtools/stdctrl.hxx>
+#include <vcl/group.hxx>
+#ifndef _LSTBOX_HXX //autogen
+#include <vcl/lstbox.hxx>
+#endif
+#include <vcl/timer.hxx>
+#include <vcl/virdev.hxx>
+#include "scdllapi.h"
+#include "scitems.hxx" // wegen enum SvxNumType
+#include "popmenu.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <cppuhelper/weakref.hxx>
+
+//===================================================================
+
+class ScHeaderEditEngine;
+class ScPatternAttr;
+class EditView;
+class EditTextObject;
+class SvxFieldItem;
+class ScAccessibleEditObject;
+class ScEditWindow;
+
+SC_DLLPUBLIC ScEditWindow* GetScEditWindow (); //CHINA001
+
+enum ScEditWindowLocation
+{
+ Left,
+ Center,
+ Right
+};
+
+class SC_DLLPUBLIC ScEditWindow : public Control
+{
+public:
+ ScEditWindow( Window* pParent, const ResId& rResId, ScEditWindowLocation eLoc );
+ ~ScEditWindow();
+
+ using Control::SetFont;
+ void SetFont( const ScPatternAttr& rPattern );
+ using Control::SetText;
+ void SetText( const EditTextObject& rTextObject );
+ EditTextObject* CreateTextObject();
+ void SetCharAttriutes();
+
+ void InsertField( const SvxFieldItem& rFld );
+
+ void SetNumType(SvxNumType eNumType);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ inline ScHeaderEditEngine* GetEditEngine() const {return pEdEngine;}
+protected:
+ virtual void Paint( const Rectangle& rRec );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void KeyInput( const KeyEvent& rKEvt );
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+private:
+ ScHeaderEditEngine* pEdEngine;
+ EditView* pEdView;
+ ScEditWindowLocation eLocation;
+ bool mbRTL;
+
+ com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAcc;
+ ScAccessibleEditObject* pAcc;
+};
+
+//===================================================================
+class SC_DLLPUBLIC ScExtIButton : public ImageButton
+{
+private:
+
+ Timer aTimer;
+ ScPopupMenu* pPopupMenu;
+ Link aMLink;
+ USHORT nSelected;
+
+ SC_DLLPRIVATE DECL_LINK( TimerHdl, Timer*);
+
+// void DrawArrow();
+
+protected:
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt);
+ virtual void Click();
+
+ virtual void StartPopup();
+
+public:
+
+ ScExtIButton(Window* pParent, const ResId& rResId );
+
+ void SetPopupMenu(ScPopupMenu* pPopUp);
+
+ USHORT GetSelected();
+
+ void SetMenuHdl( const Link& rLink ) { aMLink = rLink; }
+ const Link& GetMenuHdl() const { return aMLink; }
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+};
+
+
+//===================================================================
+//CHINA001
+//CHINA001 class ScHFEditPage : public SfxTabPage
+//CHINA001 {
+//CHINA001 public:
+//CHINA001 virtual BOOL FillItemSet ( SfxItemSet& rCoreSet );
+//CHINA001 virtual void Reset ( const SfxItemSet& rCoreSet );
+//CHINA001
+//CHINA001 void SetNumType(SvxNumType eNumType);
+//CHINA001
+//CHINA001 protected:
+//CHINA001 ScHFEditPage( Window* pParent,
+//CHINA001 USHORT nResId,
+//CHINA001 const SfxItemSet& rCoreSet,
+//CHINA001 USHORT nWhich );
+//CHINA001 virtual ~ScHFEditPage();
+//CHINA001
+//CHINA001 private:
+//CHINA001 FixedText aFtLeft;
+//CHINA001 ScEditWindow aWndLeft;
+//CHINA001 FixedText aFtCenter;
+//CHINA001 ScEditWindow aWndCenter;
+//CHINA001 FixedText aFtRight;
+//CHINA001 ScEditWindow aWndRight;
+//CHINA001 ImageButton aBtnText;
+//CHINA001 ScExtIButton aBtnFile;
+//CHINA001 ImageButton aBtnTable;
+//CHINA001 ImageButton aBtnPage;
+//CHINA001 ImageButton aBtnLastPage;
+//CHINA001 ImageButton aBtnDate;
+//CHINA001 ImageButton aBtnTime;
+//CHINA001 FixedLine aFlInfo;
+//CHINA001 FixedInfo aFtInfo;
+//CHINA001 ScPopupMenu aPopUpFile;
+//CHINA001
+//CHINA001 USHORT nWhich;
+//CHINA001 String aCmdArr[6];
+//CHINA001
+//CHINA001 private:
+//CHINA001 #ifdef _TPHFEDIT_CXX
+//CHINA001 void FillCmdArr();
+//CHINA001 DECL_LINK( ClickHdl, ImageButton* );
+//CHINA001 DECL_LINK( MenuHdl, ScExtIButton* );
+//CHINA001 #endif
+//CHINA001 };
+//CHINA001
+//CHINA001 //===================================================================
+//CHINA001
+//CHINA001 class ScRightHeaderEditPage : public ScHFEditPage
+//CHINA001 {
+//CHINA001 public:
+//CHINA001 static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+//CHINA001 static USHORT* GetRanges();
+//CHINA001
+//CHINA001 private:
+//CHINA001 ScRightHeaderEditPage( Window* pParent, const SfxItemSet& rSet );
+//CHINA001 };
+//CHINA001
+//CHINA001 //===================================================================
+//CHINA001
+//CHINA001 class ScLeftHeaderEditPage : public ScHFEditPage
+//CHINA001 {
+//CHINA001 public:
+//CHINA001 static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+//CHINA001 static USHORT* GetRanges();
+//CHINA001
+//CHINA001 private:
+//CHINA001 ScLeftHeaderEditPage( Window* pParent, const SfxItemSet& rSet );
+//CHINA001 };
+//CHINA001
+//CHINA001 //===================================================================
+//CHINA001
+//CHINA001 class ScRightFooterEditPage : public ScHFEditPage
+//CHINA001 {
+//CHINA001 public:
+//CHINA001 static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+//CHINA001 static USHORT* GetRanges();
+//CHINA001
+//CHINA001 private:
+//CHINA001 ScRightFooterEditPage( Window* pParent, const SfxItemSet& rSet );
+//CHINA001 };
+//CHINA001
+//CHINA001 //===================================================================
+//CHINA001
+//CHINA001 class ScLeftFooterEditPage : public ScHFEditPage
+//CHINA001 {
+//CHINA001 public:
+//CHINA001 static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+//CHINA001 static USHORT* GetRanges();
+//CHINA001
+//CHINA001 private:
+//CHINA001 ScLeftFooterEditPage( Window* pParent, const SfxItemSet& rSet );
+//CHINA001 };
+
+
+
+#endif // SC_TPHFEDIT_HXX
+
diff --git a/sc/source/ui/inc/tpprint.hxx b/sc/source/ui/inc/tpprint.hxx
new file mode 100644
index 000000000000..358c29f83d97
--- /dev/null
+++ b/sc/source/ui/inc/tpprint.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPPRINT_HXX
+#define SC_TPPRINT_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/fixed.hxx>
+
+//===================================================================
+
+class ScTpPrintOptions : public SfxTabPage
+{
+ FixedLine aPagesFL;
+ CheckBox aSkipEmptyPagesCB;
+ FixedLine aSheetsFL;
+ CheckBox aSelectedSheetsCB;
+
+ ScTpPrintOptions( Window* pParent, const SfxItemSet& rCoreSet );
+ ~ScTpPrintOptions();
+
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges();
+ virtual BOOL FillItemSet( SfxItemSet& rCoreSet );
+ virtual void Reset( const SfxItemSet& rCoreSet );
+ using SfxTabPage::DeactivatePage;
+ virtual int DeactivatePage( SfxItemSet* pSet = NULL );
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/tpsort.hxx b/sc/source/ui/inc/tpsort.hxx
new file mode 100644
index 000000000000..d1ba772a8ca2
--- /dev/null
+++ b/sc/source/ui/inc/tpsort.hxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPSORT_HXX
+#define SC_TPSORT_HXX
+
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svx/langbox.hxx>
+
+
+#include "global.hxx"
+#include "address.hxx"
+
+//------------------------------------------------------------------------
+
+// +1 because one field is reserved for the "- undefined -" entry
+#define SC_MAXFIELDS MAXCOLCOUNT+1
+
+class ScViewData;
+class ScSortDlg;
+struct ScSortParam;
+
+//========================================================================
+// Kriterien
+
+class ScTabPageSortFields : public SfxTabPage
+{
+public:
+ ScTabPageSortFields( Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScTabPageSortFields();
+
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rArgSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+
+protected:
+// fuer Datenaustausch (sollte noch umgestellt werden!)
+// virtual void ActivatePage ( const SfxItemSet& rSet );
+ using SfxTabPage::ActivatePage;
+ using SfxTabPage::DeactivatePage;
+ virtual void ActivatePage ();
+ virtual int DeactivatePage ( SfxItemSet* pSet = 0);
+
+private:
+ FixedLine aFlSort1;
+ ListBox aLbSort1;
+ RadioButton aBtnUp1;
+ RadioButton aBtnDown1;
+
+ FixedLine aFlSort2;
+ ListBox aLbSort2;
+ RadioButton aBtnUp2;
+ RadioButton aBtnDown2;
+
+ FixedLine aFlSort3;
+ ListBox aLbSort3;
+ RadioButton aBtnUp3;
+ RadioButton aBtnDown3;
+
+ String aStrUndefined;
+ String aStrColumn;
+ String aStrRow;
+
+ const USHORT nWhichSort;
+ ScSortDlg* pDlg;
+ ScViewData* pViewData;
+ const ScSortParam& rSortData;
+ SCCOLROW nFieldArr[SC_MAXFIELDS];
+ USHORT nFieldCount;
+ SCCOL nFirstCol;
+ SCROW nFirstRow;
+ BOOL bHasHeader;
+ BOOL bSortByRows;
+
+ ListBox* aSortLbArr[3];
+ RadioButton* aDirBtnArr[3][2];
+ FixedLine* aFlArr[3];
+
+#ifdef _TPSORT_CXX
+private:
+ void Init ();
+ void DisableField ( USHORT nField );
+ void EnableField ( USHORT nField );
+ void FillFieldLists ();
+ USHORT GetFieldSelPos ( SCCOLROW nField );
+
+ // Handler ------------------------
+ DECL_LINK( SelectHdl, ListBox * );
+#endif
+};
+
+//========================================================================
+// Sortieroptionen:
+
+class ScDocument;
+class ScRangeData;
+class CollatorRessource;
+class CollatorWrapper;
+
+#if ENABLE_LAYOUT_EXPERIMENTAL
+#include <sfx2/layout.hxx>
+#include <layout/layout-pre.hxx>
+#else /* !ENABLE_LAYOUT_EXPERIMENTAL */
+#define LocalizedString String
+#endif /* !ENABLE_LAYOUT_EXPERIMENTAL */
+
+class ScTabPageSortOptions : public SfxTabPage
+{
+public:
+ ScTabPageSortOptions( Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScTabPageSortOptions();
+
+#undef SfxTabPage
+#define SfxTabPage ::SfxTabPage
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rArgSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+
+protected:
+// fuer Datenaustausch (sollte noch umgestellt werden!)
+// virtual void ActivatePage ( const SfxItemSet& rSet );
+ using SfxTabPage::ActivatePage;
+ using SfxTabPage::DeactivatePage;
+ virtual void ActivatePage ();
+ virtual int DeactivatePage ( SfxItemSet* pSet = 0);
+
+private:
+
+ CheckBox aBtnCase;
+ CheckBox aBtnHeader;
+ CheckBox aBtnFormats;
+
+ CheckBox aBtnCopyResult;
+ ListBox aLbOutPos;
+ Edit aEdOutPos;
+
+ CheckBox aBtnSortUser;
+ ListBox aLbSortUser;
+
+ FixedText aFtLanguage;
+ SvxLanguageBox aLbLanguage;
+ FixedText aFtAlgorithm;
+ ListBox aLbAlgorithm;
+
+ FixedLine aLineDirection;
+ RadioButton aBtnTopDown;
+ RadioButton aBtnLeftRight;
+
+ FixedText aFtAreaLabel;
+// FixedInfo aFtArea;
+ LocalizedString aStrRowLabel;
+ LocalizedString aStrColLabel;
+ LocalizedString aStrUndefined;
+ String aStrNoName;
+ String aStrAreaLabel;
+
+ const USHORT nWhichSort;
+ const ScSortParam& rSortData;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ ScSortDlg* pDlg;
+ ScAddress theOutPos;
+
+ CollatorRessource* pColRes;
+ CollatorWrapper* pColWrap;
+
+#ifdef _TPSORT_CXX
+private:
+ void Init ();
+ void FillUserSortListBox ();
+ void FillOutPosList ();
+
+ // Handler ------------------------
+ DECL_LINK( EnableHdl, CheckBox * );
+ DECL_LINK( SelOutPosHdl, ListBox * );
+ void EdOutPosModHdl ( Edit* pEd );
+ DECL_LINK( SortDirHdl, RadioButton * );
+ DECL_LINK( FillAlgorHdl, void * );
+#endif
+};
+
+#if ENABLE_LAYOUT_EXPERIMENTAL
+#include <layout/layout-post.hxx>
+#endif /* ENABLE_LAYOUT_EXPERIMENTAL */
+
+#endif // SC_TPSORT_HXX
+
diff --git a/sc/source/ui/inc/tpstat.hxx b/sc/source/ui/inc/tpstat.hxx
new file mode 100644
index 000000000000..1c928ff2ef13
--- /dev/null
+++ b/sc/source/ui/inc/tpstat.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPSTAT_HXX
+#define SC_TPSTAT_HXX
+
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/fixed.hxx>
+#include <svtools/stdctrl.hxx>
+
+
+
+//========================================================================
+
+class ScDocStatPage: public SfxTabPage
+{
+public:
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rSet );
+
+private:
+ ScDocStatPage( Window *pParent, const SfxItemSet& rSet );
+ ~ScDocStatPage();
+
+protected:
+ virtual BOOL FillItemSet( SfxItemSet& rSet );
+ virtual void Reset ( const SfxItemSet& rSet );
+
+private:
+ FixedLine aFlInfo;
+ FixedText aFtTablesLbl;
+ FixedInfo aFtTables;
+ FixedText aFtCellsLbl;
+ FixedInfo aFtCells;
+ FixedText aFtPagesLbl;
+ FixedInfo aFtPages;
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/tpsubt.hxx b/sc/source/ui/inc/tpsubt.hxx
new file mode 100644
index 000000000000..6dd640e7925e
--- /dev/null
+++ b/sc/source/ui/inc/tpsubt.hxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPSUBT_HXX
+#define SC_TPSUBT_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/checklbx.hxx>
+#include <vcl/fixed.hxx>
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+
+// +1 because one field is reserved for the "- none -" entry
+#define SC_MAXFIELDS MAXCOLCOUNT+1
+
+class ScViewData;
+class ScDocument;
+
+//========================================================================
+// Gruppenseiten: Basisklasse
+
+class ScTpSubTotalGroup : public SfxTabPage
+{
+protected:
+ ScTpSubTotalGroup( Window* pParent, USHORT nResId,
+ const SfxItemSet& rArgSet );
+
+public:
+ virtual ~ScTpSubTotalGroup();
+
+ static USHORT* GetRanges ();
+ BOOL DoReset ( USHORT nGroupNo,
+ const SfxItemSet& rArgSet );
+ BOOL DoFillItemSet ( USHORT nGroupNo,
+ SfxItemSet& rArgSet );
+protected:
+ FixedText aFtGroup;
+ ListBox aLbGroup;
+ FixedText aFtColumns;
+ SvxCheckListBox aLbColumns;
+ FixedText aFtFunctions;
+ ListBox aLbFunctions;
+ const String aStrNone;
+ const String aStrColumn;
+
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+
+ const USHORT nWhichSubTotals;
+ const ScSubTotalParam& rSubTotalData;
+ SCCOL nFieldArr[SC_MAXFIELDS];
+ const USHORT nFieldCount;
+
+private:
+ void Init ();
+ void FillListBoxes ();
+ ScSubTotalFunc LbPosToFunc ( USHORT nPos );
+ USHORT FuncToLbPos ( ScSubTotalFunc eFunc );
+ USHORT GetFieldSelPos ( SCCOL nField );
+
+ // Handler ------------------------
+ DECL_LINK( SelectHdl, ListBox * );
+ DECL_LINK( CheckHdl, ListBox * );
+};
+
+//------------------------------------------------------------------------
+
+class ScTpSubTotalGroup1 : public ScTpSubTotalGroup
+{
+protected:
+ ScTpSubTotalGroup1( Window* pParent,
+ const SfxItemSet& rArgSet );
+
+public:
+ virtual ~ScTpSubTotalGroup1();
+
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rArgSet );
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+};
+
+//------------------------------------------------------------------------
+
+class ScTpSubTotalGroup2 : public ScTpSubTotalGroup
+{
+protected:
+ ScTpSubTotalGroup2( Window* pParent,
+ const SfxItemSet& rArgSet );
+
+public:
+ virtual ~ScTpSubTotalGroup2();
+
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rArgSet );
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+};
+
+//------------------------------------------------------------------------
+
+class ScTpSubTotalGroup3 : public ScTpSubTotalGroup
+{
+protected:
+ ScTpSubTotalGroup3( Window* pParent,
+ const SfxItemSet& rArgSet );
+
+public:
+ virtual ~ScTpSubTotalGroup3();
+
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rArgSet );
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+};
+
+//========================================================================
+// Optionen:
+
+class ScTpSubTotalOptions : public SfxTabPage
+{
+protected:
+ ScTpSubTotalOptions( Window* pParent,
+ const SfxItemSet& rArgSet );
+
+public:
+ virtual ~ScTpSubTotalOptions();
+
+ static USHORT* GetRanges ();
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rArgSet );
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+
+private:
+ FixedLine aFlGroup;
+ CheckBox aBtnPagebreak;
+ CheckBox aBtnCase;
+ CheckBox aBtnSort;
+ FixedLine aFlSort;
+ RadioButton aBtnAscending;
+ RadioButton aBtnDescending;
+ CheckBox aBtnFormats;
+ CheckBox aBtnUserDef;
+ ListBox aLbUserDef;
+
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+ const USHORT nWhichSubTotals;
+ const ScSubTotalParam& rSubTotalData;
+
+private:
+ void Init ();
+ void FillUserSortListBox ();
+
+ // Handler ------------------------
+ DECL_LINK( CheckHdl, CheckBox * );
+};
+
+
+
+#endif // SC_TPSORT_HXX
+
diff --git a/sc/source/ui/inc/tptable.hxx b/sc/source/ui/inc/tptable.hxx
new file mode 100644
index 000000000000..980a574dc61d
--- /dev/null
+++ b/sc/source/ui/inc/tptable.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPTABLE_HXX
+#define SC_TPTABLE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/field.hxx>
+
+//===================================================================
+
+/** A vcl/NumericField that additionally supports empty text.
+ @descr Value 0 is set as empty text, and empty text is returned as 0. */
+class EmptyNumericField : public NumericField
+{
+public:
+ inline explicit EmptyNumericField( Window* pParent, WinBits nWinStyle ) :
+ NumericField( pParent, nWinStyle ) {}
+ inline explicit EmptyNumericField( Window* pParent, const ResId& rResId ) :
+ NumericField( pParent, rResId ) {}
+
+ virtual void Modify();
+ virtual void SetValue( sal_Int64 nValue );
+ virtual sal_Int64 GetValue() const;
+};
+
+//===================================================================
+
+class ScTablePage : public SfxTabPage
+{
+public:
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rCoreSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreSet );
+ virtual void Reset ( const SfxItemSet& rCoreSet );
+ using SfxTabPage::DeactivatePage;
+ virtual int DeactivatePage ( SfxItemSet* pSet = NULL );
+ virtual void DataChanged ( const DataChangedEvent& rDCEvt );
+
+private:
+ ScTablePage( Window* pParent, const SfxItemSet& rCoreSet );
+ virtual ~ScTablePage();
+
+ void ShowImage();
+
+private:
+ FixedLine aFlPageDir;
+ RadioButton aBtnTopDown;
+ RadioButton aBtnLeftRight;
+ FixedImage aBmpPageDir;
+ Image aImgLeftRight;
+ Image aImgTopDown;
+ Image aImgLeftRightHC;
+ Image aImgTopDownHC;
+ CheckBox aBtnPageNo;
+ NumericField aEdPageNo;
+
+ FixedLine aFlPrint;
+ CheckBox aBtnHeaders;
+ CheckBox aBtnGrid;
+ CheckBox aBtnNotes;
+ CheckBox aBtnObjects;
+ CheckBox aBtnCharts;
+ CheckBox aBtnDrawings;
+ CheckBox aBtnFormulas;
+ CheckBox aBtnNullVals;
+
+ FixedLine aFlScale;
+ FixedText aFtScaleMode;
+ ListBox aLbScaleMode;
+ FixedText aFtScaleAll;
+ MetricField aEdScaleAll;
+ FixedText aFtScalePageWidth;
+ EmptyNumericField aEdScalePageWidth;
+ FixedText aFtScalePageHeight;
+ EmptyNumericField aEdScalePageHeight;
+ FixedText aFtScalePageNum;
+ NumericField aEdScalePageNum;
+
+private:
+ //------------------------------------
+ // Handler:
+ DECL_LINK( PageDirHdl, RadioButton* );
+ DECL_LINK( PageNoHdl, CheckBox* );
+ DECL_LINK( ScaleHdl, ListBox* );
+};
+
+#endif // SC_TPTABLE_HXX
diff --git a/sc/source/ui/inc/tpusrlst.hxx b/sc/source/ui/inc/tpusrlst.hxx
new file mode 100644
index 000000000000..f26e48889f1d
--- /dev/null
+++ b/sc/source/ui/inc/tpusrlst.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPUSRLST_HXX
+#define SC_TPUSRLST_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/svmedit.hxx>
+
+//========================================================================
+// Benutzerdefinierte Listen:
+
+class ScUserList;
+class ScDocument;
+class ScViewData;
+class ScRangeUtil;
+
+class ScTpUserLists : public SfxTabPage
+{
+public:
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rAttrSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreAttrs );
+ virtual void Reset ( const SfxItemSet& rCoreAttrs );
+ using SfxTabPage::DeactivatePage;
+ virtual int DeactivatePage ( SfxItemSet* pSet = NULL );
+
+private:
+ ScTpUserLists( Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScTpUserLists();
+
+private:
+ FixedText aFtLists;
+ ListBox aLbLists;
+ FixedText aFtEntries;
+ MultiLineEdit aEdEntries;
+ FixedText aFtCopyFrom;
+ Edit aEdCopyFrom;
+ PushButton aBtnNew;
+ PushButton aBtnAdd;
+ PushButton aBtnRemove;
+ PushButton aBtnCopy;
+
+ const String aStrQueryRemove;
+ const String aStrNew;
+ const String aStrCancel;
+ const String aStrAdd;
+ const String aStrModify;
+ const String aStrCopyList;
+ const String aStrCopyFrom;
+ const String aStrCopyErr;
+
+ const USHORT nWhichUserLists;
+ ScUserList* pUserLists;
+
+ ScDocument* pDoc;
+ ScViewData* pViewData;
+ ScRangeUtil* pRangeUtil;
+ String aStrSelectedArea;
+
+ BOOL bModifyMode;
+ BOOL bCancelMode;
+ BOOL bCopyDone;
+ USHORT nCancelPos;
+
+#ifdef _TPUSRLST_CXX
+private:
+ void Init ();
+ USHORT UpdateUserListBox ();
+ void UpdateEntries ( USHORT nList );
+ void MakeListStr ( String& rListStr );
+ void AddNewList ( const String& rEntriesStr );
+ void RemoveList ( USHORT nList );
+ void ModifyList ( USHORT nSelList,
+ const String& rEntriesStr );
+ void CopyListFromArea ( const ScRefAddress& rStartPos,
+ const ScRefAddress& rEndPos );
+
+ // Handler:
+ DECL_LINK( LbSelectHdl, ListBox* );
+ DECL_LINK( BtnClickHdl, PushButton* );
+ DECL_LINK( EdEntriesModHdl, MultiLineEdit* );
+#endif
+};
+
+
+
+#endif // SC_TPUSRLST_HXX
+
diff --git a/sc/source/ui/inc/tpview.hxx b/sc/source/ui/inc/tpview.hxx
new file mode 100644
index 000000000000..81760eb66c67
--- /dev/null
+++ b/sc/source/ui/inc/tpview.hxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TPVIEW_HXX
+#define SC_TPVIEW_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/field.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/group.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <svx/strarray.hxx>
+
+//========================================================================
+// View-Optionen:
+
+class ScViewOptions;
+
+//========================================================================
+// TabPage Inhalte
+
+class ScTpContentOptions : public SfxTabPage
+{
+ FixedLine aLinesGB;
+ CheckBox aGridCB;
+ FixedText aColorFT;
+ ColorListBox aColorLB;
+ CheckBox aBreakCB;
+ CheckBox aGuideLineCB;
+ CheckBox aHandleCB;
+ CheckBox aBigHandleCB;
+
+ FixedLine aSeparator1FL;
+
+ FixedLine aDisplayGB;
+ CheckBox aFormulaCB;
+ CheckBox aNilCB;
+ CheckBox aAnnotCB;
+ CheckBox aValueCB;
+ CheckBox aAnchorCB;
+ CheckBox aClipMarkCB;
+ CheckBox aRangeFindCB;
+
+ FixedLine aObjectGB;
+ FixedText aObjGrfFT;
+ ListBox aObjGrfLB;
+ FixedText aDiagramFT;
+ ListBox aDiagramLB;
+ FixedText aDrawFT;
+ ListBox aDrawLB;
+
+ FixedLine aZoomGB;
+ CheckBox aSyncZoomCB;
+
+ FixedLine aSeparator2FL;
+
+ FixedLine aWindowGB;
+ CheckBox aRowColHeaderCB;
+ CheckBox aHScrollCB;
+ CheckBox aVScrollCB;
+ CheckBox aTblRegCB;
+ CheckBox aOutlineCB;
+
+ ScViewOptions* pLocalOptions;
+
+ void InitGridOpt();
+ DECL_LINK( GridHdl, CheckBox* );
+ DECL_LINK( SelLbObjHdl, ListBox* );
+ DECL_LINK( CBHdl, CheckBox* );
+
+ ScTpContentOptions( Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScTpContentOptions();
+
+public:
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rCoreSet );
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreSet );
+ virtual void Reset ( const SfxItemSet& rCoreSet );
+ using SfxTabPage::ActivatePage;
+ using SfxTabPage::DeactivatePage;
+ virtual void ActivatePage( const SfxItemSet& );
+ virtual int DeactivatePage( SfxItemSet* pSet = 0 );
+
+
+};
+
+//========================================================================
+// TabPage Layout
+class ScDocument;
+class ScTpLayoutOptions : public SfxTabPage
+{
+ FixedLine aUnitGB;
+ FixedText aUnitFT;
+ ListBox aUnitLB;
+ FixedText aTabFT;
+ MetricField aTabMF;
+
+ FixedLine aSeparatorFL;
+ FixedLine aLinkGB;
+ FixedText aLinkFT;
+ RadioButton aAlwaysRB;
+ RadioButton aRequestRB;
+ RadioButton aNeverRB;
+
+ FixedLine aOptionsGB;
+ CheckBox aAlignCB;
+ ListBox aAlignLB;
+ CheckBox aEditModeCB;
+ CheckBox aFormatCB;
+ CheckBox aExpRefCB;
+ CheckBox aMarkHdrCB;
+ CheckBox aTextFmtCB;
+ CheckBox aReplWarnCB;
+
+ SvxStringArray aUnitArr;
+
+ DECL_LINK( CBHdl, CheckBox* );
+
+ DECL_LINK(MetricHdl, ListBox*);
+ DECL_LINK( AlignHdl, CheckBox* );
+
+ ScDocument *pDoc;
+
+ DECL_LINK( UpdateHdl, CheckBox* );
+
+ ScTpLayoutOptions( Window* pParent,
+ const SfxItemSet& rArgSet );
+ ~ScTpLayoutOptions();
+
+public:
+ static SfxTabPage* Create ( Window* pParent,
+ const SfxItemSet& rCoreSet );
+ virtual BOOL FillItemSet ( SfxItemSet& rCoreSet );
+ virtual void Reset ( const SfxItemSet& rCoreSet );
+ using SfxTabPage::ActivatePage;
+ using SfxTabPage::DeactivatePage;
+ virtual void ActivatePage( const SfxItemSet& );
+ virtual int DeactivatePage( SfxItemSet* pSet = 0 );
+
+ void SetDocument(ScDocument* pPtr){pDoc = pPtr;}
+
+};
+//========================================================================
+
+#endif // SC_TPUSRLST_HXX
+
diff --git a/sc/source/ui/inc/transobj.hxx b/sc/source/ui/inc/transobj.hxx
new file mode 100644
index 000000000000..e2dbad485812
--- /dev/null
+++ b/sc/source/ui/inc/transobj.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TRANSOBJ_HXX
+#define SC_TRANSOBJ_HXX
+
+#include <svtools/transfer.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+class ScDocShell;
+class ScMarkData;
+class SfxObjectShell;
+
+namespace com { namespace sun { namespace star {
+ namespace sheet {
+ class XSheetCellRanges;
+ }
+}}}
+
+#include <sfx2/objsh.hxx>
+
+class ScTransferObj : public TransferableHelper
+{
+private:
+ ScDocument* pDoc;
+ ScRange aBlock;
+ SCROW nNonFiltered; // non-filtered rows
+ TransferableDataHelper aOleData;
+ TransferableObjectDescriptor aObjDesc;
+//REMOVE SvEmbeddedObjectRef aDocShellRef;
+//REMOVE SvEmbeddedObjectRef aDrawPersistRef;
+ SfxObjectShellRef aDocShellRef;
+ SfxObjectShellRef aDrawPersistRef;
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSheetCellRanges> xDragSourceRanges;
+ SCCOL nDragHandleX;
+ SCROW nDragHandleY;
+ SCTAB nVisibleTab;
+ USHORT nDragSourceFlags;
+ BOOL bDragWasInternal;
+ BOOL bUsedForLink;
+ bool bHasFiltered; // if has filtered rows
+
+ void InitDocShell();
+ static void StripRefs( ScDocument* pDoc, SCCOL nStartX, SCROW nStartY,
+ SCCOL nEndX, SCROW nEndY,
+ ScDocument* pDestDoc=0,
+ SCCOL nSubX=0, SCROW nSubY=0 );
+ static void PaintToDev( OutputDevice* pDev, ScDocument* pDoc, double nPrintFactor,
+ const ScRange& rBlock, BOOL bMetaFile );
+ static void GetAreaSize( ScDocument* pDoc, SCTAB nTab1, SCTAB nTab2, SCROW& nRow, SCCOL& nCol );
+
+public:
+ ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDescriptor& rDesc );
+ virtual ~ScTransferObj();
+
+ virtual void AddSupportedFormats();
+ virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ virtual sal_Bool WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
+ const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ virtual void ObjectReleased();
+ virtual void DragFinished( sal_Int8 nDropAction );
+
+ ScDocument* GetDocument() { return pDoc; } // owned by ScTransferObj
+ const ScRange& GetRange() const { return aBlock; }
+ SCROW GetNonFilteredRows() const { return nNonFiltered; }
+ SCCOL GetDragHandleX() const { return nDragHandleX; }
+ SCROW GetDragHandleY() const { return nDragHandleY; }
+ SCTAB GetVisibleTab() const { return nVisibleTab; }
+ USHORT GetDragSourceFlags() const { return nDragSourceFlags; }
+ bool HasFilteredRows() const { return bHasFiltered; }
+ ScDocShell* GetSourceDocShell();
+ ScDocument* GetSourceDocument();
+ ScMarkData GetSourceMarkData();
+
+ void SetDrawPersist( const SfxObjectShellRef& rRef );
+ void SetDragHandlePos( SCCOL nX, SCROW nY );
+ void SetVisibleTab( SCTAB nNew );
+ void SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark );
+ void SetDragSourceFlags( USHORT nFlags );
+ void SetDragWasInternal();
+
+ static SC_DLLPUBLIC ScTransferObj* GetOwnClipboard( Window* pUIWin );
+
+ static SfxObjectShell* SetDrawClipDoc( BOOL bAnyOle ); // update ScGlobal::pDrawClipDocShellRef
+ virtual sal_Int64 SAL_CALL getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException );
+ static const com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
+};
+
+#endif
+
diff --git a/sc/source/ui/inc/ui_pch.hxx b/sc/source/ui/inc/ui_pch.hxx
new file mode 100644
index 000000000000..1ef2f02d405b
--- /dev/null
+++ b/sc/source/ui/inc/ui_pch.hxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ItemID-Defines etc. muessen immer ganz vorne stehen
+
+#include "scitems.hxx"
+
+#define _ZFORLIST_DECLARE_TABLE
+
+#define _PRINTFUN_CXX
+#define _INPUTHDL_CXX
+
+// ab hier automatisch per makepch generiert
+// folgende duerfen nicht aufgenommen werden:
+// scslots.hxx
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+#include <svl/solar.hrc>
+#include <tools/rtti.hxx>
+#include <string.h>
+#include <tools/contnr.hxx>
+#include <vcl/sv.h>
+#include <tools/ref.hxx>
+#include <tools/list.hxx>
+#include <tools/link.hxx>
+#include <i18npool/lang.h>
+#include <sfx2/sfx.hrc>
+#include <svl/memberid.hrc>
+#include <sfx2/sfxsids.hrc>
+#include <svl/cntwids.hrc>
+#include <tools/resid.hxx>
+#include <tools/rc.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/gen.hxx>
+#include <tools/fract.hxx>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/keycodes.hxx>
+#include <tools/globname.hxx>
+#include <tools/color.hxx>
+#include <vcl/region.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/bitmap.hxx>
+#include <sot/sotref.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/vclenum.hxx>
+#include <sot/object.hxx>
+#include <sot/sotdata.hxx>
+#include <sot/factory.hxx>
+#include <tools/ownlist.hxx>
+#include <vcl/font.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/accel.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/pointr.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/wintypes.hxx>
+#include <vcl/event.hxx>
+#include <limits.h>
+#include <tools/errinf.hxx>
+#include <tools/errcode.hxx>
+#include <tools/stream.hxx>
+#include <vcl/color.hxx>
+#include <vcl/window.hxx>
+#include <global.hxx>
+#include <vcl/syswin.hxx>
+#include <tools/debug.hxx>
+#include <svl/svarray.hxx>
+#include <vcl/ctrl.hxx>
+#include <svl/hint.hxx>
+#include <svl/poolitem.hxx>
+#include <vcl/image.hxx>
+#include <vcl/timer.hxx>
+#include <tools/unqidx.hxx>
+#include <vcl/symbol.hxx>
+#include <vcl/fixed.hxx>
+#include <svl/brdcst.hxx>
+#include <vcl/timer.hxx>
+#include <sc.hrc>
+#include <stdarg.h>
+#include <svx/dialogs.hrc>
+#include <basic/sbxdef.hxx>
+#include <svl/lstner.hxx>
+#include <sfx2/shell.hxx>
+#include <vcl/window.hxx>
+#include <vcl/group.hxx>
+#include <tools/unqid.hxx>
+#include <tools/table.hxx>
+#include <svl/itemset.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <rangelst.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/combobox.h>
+#include <tools/shl.hxx>
+#include <vcl/field.hxx>
+#include <vcl/spinfld.hxx>
+#include <vcl/combobox.hxx>
+#include <tools/pstm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/itempool.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/tabdlg.hxx>
+#include <vcl/tabpage.hxx>
+#include <vcl/tabctrl.hxx>
+#include <shellids.hxx>
+#include <vcl/event.hxx>
+#include <svl/intitem.hxx>
+#include <svtools/confitem.hxx>
+#include <markdata.hxx>
+#include <svx/optgrid.hxx>
+#include <vcl/apptypes.hxx>
+#include <viewopti.hxx>
+#include <viewdata.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/clientsh.hxx>
+#include <document.hxx>
+#include <vcl/prntypes.hxx>
+#include <table.hxx>
+#include <column.hxx>
+#include <markarr.hxx>
+#include <vcl/mapmod.hxx>
+#include <svl/undo.hxx>
+#include <vcl/seleng.hxx>
+#include <rsc/rscsfx.hxx>
+#include <svx/zoomitem.hxx>
+#include <vcl/scrbar.hxx>
+#include <viewutil.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/datetime.hxx>
+#include <tabview.hxx>
+#include <select.hxx>
+#include <sfx2/imgdef.hxx>
+#include <viewfunc.hxx>
+#include <sfx2/module.hxx>
+#include <dbfunc.hxx>
+#include <vcl/accel.hxx>
+#include <svl/smplhint.hxx>
+#include <sfx2/viewfac.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/objsh.hxx>
+#include <target.hxx>
+#include <tabvwsh.hxx>
+#include <svl/inethist.hxx>
+#include <svl/inetdef.hxx>
+#include <sfx2/sfxdefs.hxx>
+#include <svtools/compat.hxx>
+#include <svl/inetmsg.hxx>
+#include <sfx2/app.hxx>
+#include <tools/urlobj.hxx>
+#include <scdll.hxx>
+#include <sfx2/msg.hxx>
+#include <svl/ownlist.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/frame.hxx>
+#include <scresid.hxx>
+#include <sfx2/ipfrm.hxx>
+#include <docsh.hxx>
+//REMOVE #include <sfx2/interno.hxx>
+#include <vcl/wintypes.hxx>
+#include <sfx2/docfac.hxx>
+#include <scitems.hxx>
+#include <vcl/virdev.hxx>
+#include <globstr.hrc>
+#include <tcov.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/lstbox.h>
+#include <sfx2/minarray.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/pointr.hxx>
+#include <vcl/prntypes.hxx>
+#include <vcl/jobset.hxx>
+#include <svx/svdtypes.hxx>
+#include <vcl/btndlg.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/svstdarr.hxx>
+#include <vcl/edit.hxx>
+#include <svl/stritem.hxx>
+#include <collect.hxx>
+#include <svx/svdsob.hxx>
+#include <vcl/imagebtn.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdglue.hxx>
+#include <svx/svdlayer.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svdsnpv.hxx>
+#include <svx/svdpntv.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdhlpln.hxx>
+#include <scmod.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/field.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdcrtv.hxx>
+#include <vcl/print.hxx>
+#include <vcl/floatwin.hxx>
+#include <vcl/wrkwin.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/chalign.hxx>
+#include <sfx2/dispatch.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/animate.hxx>
+#include <vcl/graph.h>
+#include <editeng/editdata.hxx>
+#include <svtools/stdctrl.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <conditio.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/print.hxx>
+#include <uiitems.hxx>
+#include <svx/svdmodel.hxx>
+#include <vcl/gdiobj.hxx>
+#include <editeng/editeng.hxx>
+#include <svx/pageitem.hxx>
+#include <anyrefdg.hxx>
+#include <basic/sbxcore.hxx>
+#include <vcl/ctrl.hxx>
+#include <svx/xenum.hxx>
+#include <dbcolect.hxx>
+#include <sot/exchange.hxx>
+#include <math.h>
+#include <vcl/wrkwin.hxx>
+#include <basic/sbxvar.hxx>
+#include <vcl/image.hxx>
+#include <svx/xdef.hxx>
+#include <drwlayer.hxx>
+#include <editutil.hxx>
+#include <svx/xit.hxx>
+#include <svx/xcolit.hxx>
+#include <attrib.hxx>
+#include <patattr.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xflasit.hxx>
+#include <svx/xlnasit.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/sdangitm.hxx>
+#include <svx/sderitm.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/svddef.hxx>
+#include <svx/sdooitm.hxx>
+#include <svx/sdprcitm.hxx>
+#include <svx/sdshcitm.hxx>
+#include <svx/sdshitm.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/sdsxyitm.hxx>
+#include <svx/sdtaaitm.hxx>
+#include <svx/sdtacitm.hxx>
+#include <svx/sdtaditm.hxx>
+#include <svx/sdtagitm.hxx>
+#include <svx/sdtaiitm.hxx>
+#include <svx/sdynitm.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/sdtakitm.hxx>
+#include <svx/sdtayitm.hxx>
+#include <svx/sdtcfitm.hxx>
+#include <svx/sdtditm.hxx>
+#include <svx/sdtfsitm.hxx>
+#include <svx/sdtmfitm.hxx>
+#include <tools/poly.hxx>
+#include <vcl/gdimtf.hxx>
+#include <cell.hxx>
+#include <stddef.h>
+#include <tools/mempool.hxx>
+#include <svl/style.hrc>
+#include <drawview.hxx>
+#include <svx/view3d.hxx>
+#include <svx/def3d.hxx>
+#include <vcl/floatwin.hxx>
+#include <basic/sbxobj.hxx>
+#include <editeng/svxenum.hxx>
+#include <svx/xtextit0.hxx>
+#include <svx/svdtrans.hxx>
+#include <svl/style.hxx>
+#include <reffact.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdoattr.hxx>
+#include <tools/wldcrd.hxx>
+#include <rangenam.hxx>
+#include <undobase.hxx>
+#include <vcl/dockwin.hxx>
+#include <vcl/virdev.hxx>
+#include <rangeutl.hxx>
+#include <vcl/toolbox.hxx>
+#include <fupoor.hxx>
+#include <docpool.hxx>
+#include <vcl/button.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/svdorect.hxx>
+#include <svl/whiter.hxx>
+#include <stlpool.hxx>
+#include <editeng/eeitem.hxx>
+#include <inputhdl.hxx>
+#include <svx/svdpage.hxx>
+
+
+
+
diff --git a/sc/source/ui/inc/uiitems.hxx b/sc/source/ui/inc/uiitems.hxx
new file mode 100644
index 000000000000..770411b63e1b
--- /dev/null
+++ b/sc/source/ui/inc/uiitems.hxx
@@ -0,0 +1,378 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_UIITEMS_HXX
+#define SC_UIITEMS_HXX
+
+#include "scdllapi.h"
+#include "conditio.hxx"
+#include "sortparam.hxx"
+#include "queryparam.hxx"
+#include "paramisc.hxx"
+#include <svl/poolitem.hxx>
+
+class ScEditEngineDefaulter;
+class EditTextObject;
+class ScViewData;
+class ScDPSaveData;
+
+// ---------------------------------------------------------------------------
+
+// Items
+
+class ScInputStatusItem : public SfxPoolItem
+{
+ ScAddress aCursorPos;
+ ScAddress aStartPos;
+ ScAddress aEndPos;
+ String aString;
+ EditTextObject* pEditData;
+
+public:
+ TYPEINFO();
+//UNUSED2008-05 ScInputStatusItem( USHORT nWhich,
+//UNUSED2008-05 SCTAB nTab,
+//UNUSED2008-05 SCCOL nCol, SCROW nRow,
+//UNUSED2008-05 SCCOL nStartCol, SCROW nStartRow,
+//UNUSED2008-05 SCCOL nEndCol, SCROW nSEndRow,
+//UNUSED2008-05 const String& rString,
+//UNUSED2008-05 const EditTextObject* pData );
+
+ ScInputStatusItem( USHORT nWhich,
+ const ScAddress& rCurPos,
+ const ScAddress& rStartPos,
+ const ScAddress& rEndPos,
+ const String& rString,
+ const EditTextObject* pData );
+ ScInputStatusItem( const ScInputStatusItem& rItem );
+ ~ScInputStatusItem();
+
+ virtual String GetValueText() const;
+
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ const ScAddress& GetPos() const { return aCursorPos; }
+ const ScAddress& GetStartPos() const { return aStartPos; }
+ const ScAddress& GetEndPos() const { return aEndPos; }
+ SCTAB GetTab() const { return aCursorPos.Tab(); }
+ SCCOL GetCol() const { return aCursorPos.Col(); }
+ SCROW GetRow() const { return aCursorPos.Row(); }
+ SCCOL GetStartCol() const { return aStartPos.Col(); }
+ SCROW GetStartRow() const { return aStartPos.Row(); }
+ SCCOL GetEndCol() const { return aEndPos.Col(); }
+ SCROW GetEndRow() const { return aEndPos.Row(); }
+
+ const String& GetString() const { return aString; }
+ const EditTextObject* GetEditData() const { return pEditData; }
+};
+
+
+#define SC_TAB_INSERTED 1
+#define SC_TAB_DELETED 2
+#define SC_TAB_MOVED 3
+#define SC_TAB_COPIED 4
+#define SC_TAB_HIDDEN 5
+
+class ScTablesHint : public SfxHint
+{
+ USHORT nId;
+ SCTAB nTab1;
+ SCTAB nTab2;
+
+public:
+ TYPEINFO();
+ ScTablesHint(USHORT nNewId, SCTAB nTable1, SCTAB nTable2=0);
+ ~ScTablesHint();
+
+ USHORT GetId() const { return nId; }
+ SCTAB GetTab1() const { return nTab1; }
+ SCTAB GetTab2() const { return nTab2; }
+};
+
+class ScEditViewHint : public SfxHint
+{
+ ScEditEngineDefaulter* pEditEngine;
+ ScAddress aCursorPos;
+
+public:
+ TYPEINFO();
+ ScEditViewHint( ScEditEngineDefaulter* pEngine, const ScAddress& rCurPos );
+ ~ScEditViewHint();
+
+ SCCOL GetCol() const { return aCursorPos.Col(); }
+ SCROW GetRow() const { return aCursorPos.Row(); }
+ SCTAB GetTab() const { return aCursorPos.Tab(); }
+ ScEditEngineDefaulter* GetEngine() const { return pEditEngine; }
+
+private:
+ ScEditViewHint(); // disabled
+};
+
+class ScIndexHint : public SfxHint
+{
+ USHORT nId;
+ USHORT nIndex;
+
+public:
+ TYPEINFO();
+ ScIndexHint(USHORT nNewId, USHORT nIdx);
+ ~ScIndexHint();
+
+ USHORT GetId() const { return nId; }
+ USHORT GetIndex() const { return nIndex; }
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Sortierdialog:
+
+class SC_DLLPUBLIC ScSortItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScSortItem( USHORT nWhich,
+ ScViewData* ptrViewData,
+ const ScSortParam* pSortData );
+ ScSortItem( USHORT nWhich,
+ const ScSortParam* pSortData );
+ ScSortItem( const ScSortItem& rItem );
+ ~ScSortItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+ virtual sal_Bool QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberUd ) const;
+
+ ScViewData* GetViewData () const { return pViewData; }
+ const ScSortParam& GetSortData () const { return theSortData; }
+
+private:
+ ScViewData* pViewData;
+ ScSortParam theSortData;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Filterdialog:
+
+class SC_DLLPUBLIC ScQueryItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScQueryItem( USHORT nWhich,
+ ScViewData* ptrViewData,
+ const ScQueryParam* pQueryData );
+ ScQueryItem( USHORT nWhich,
+ const ScQueryParam* pQueryData );
+ ScQueryItem( const ScQueryItem& rItem );
+ ~ScQueryItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ ScViewData* GetViewData () const { return pViewData; }
+ const ScQueryParam& GetQueryData() const { return theQueryData; }
+
+ BOOL GetAdvancedQuerySource(ScRange& rSource) const;
+ void SetAdvancedQuerySource(const ScRange* pSource);
+
+private:
+ ScViewData* pViewData;
+ ScQueryParam theQueryData;
+ BOOL bIsAdvanced;
+ ScRange aAdvSource;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Zwischenergebnisdialog:
+
+class SC_DLLPUBLIC ScSubTotalItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScSubTotalItem( USHORT nWhich,
+ ScViewData* ptrViewData,
+ const ScSubTotalParam* pSubTotalData );
+ ScSubTotalItem( USHORT nWhich,
+ const ScSubTotalParam* pSubTotalData );
+ ScSubTotalItem( const ScSubTotalItem& rItem );
+ ~ScSubTotalItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+ virtual sal_Bool QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberUd ) const;
+
+ ScViewData* GetViewData () const { return pViewData; }
+ const ScSubTotalParam& GetSubTotalData() const { return theSubTotalData; }
+
+private:
+ ScViewData* pViewData;
+ ScSubTotalParam theSubTotalData;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer die Benutzerlisten-TabPage:
+
+class SC_DLLPUBLIC ScUserListItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScUserListItem( USHORT nWhich );
+ ScUserListItem( const ScUserListItem& rItem );
+ ~ScUserListItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ void SetUserList ( const ScUserList& rUserList );
+ ScUserList* GetUserList () const { return pUserList; }
+
+private:
+ ScUserList* pUserList;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer die Konsolidieren-Dialog
+
+class ScConsolidateItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScConsolidateItem( USHORT nWhich,
+ const ScConsolidateParam* pParam );
+ ScConsolidateItem( const ScConsolidateItem& rItem );
+ ~ScConsolidateItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ const ScConsolidateParam& GetData() const { return theConsData; }
+
+private:
+ ScConsolidateParam theConsData;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Pivot-Dialog
+
+class ScPivotItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScPivotItem( USHORT nWhich, const ScDPSaveData* pData,
+ const ScRange* pRange, BOOL bNew );
+ ScPivotItem( const ScPivotItem& rItem );
+ ~ScPivotItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ const ScDPSaveData& GetData() const { return *pSaveData; }
+ const ScRange& GetDestRange() const { return aDestRange; }
+ BOOL IsNewSheet() const { return bNewSheet; }
+
+private:
+ ScDPSaveData* pSaveData;
+ ScRange aDestRange;
+ BOOL bNewSheet;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Solver-Dialog
+
+class ScSolveItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScSolveItem( USHORT nWhich,
+ const ScSolveParam* pParam );
+ ScSolveItem( const ScSolveItem& rItem );
+ ~ScSolveItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ const ScSolveParam& GetData() const { return theSolveData; }
+
+private:
+ ScSolveParam theSolveData;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Mehrfachoperationen-Dialog
+
+class ScTabOpItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScTabOpItem( USHORT nWhich,
+ const ScTabOpParam* pParam );
+ ScTabOpItem( const ScTabOpItem& rItem );
+ ~ScTabOpItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ const ScTabOpParam& GetData() const { return theTabOpData; }
+
+private:
+ ScTabOpParam theTabOpData;
+};
+
+//----------------------------------------------------------------------------
+// Parameter-Item fuer den Dialog bedingte Formatierung
+
+class ScCondFrmtItem : public SfxPoolItem
+{
+public:
+ TYPEINFO();
+ ScCondFrmtItem( USHORT nWhich,
+//! const ScConditionalFormat* pCondFrmt );
+ const ScConditionalFormat& rCondFrmt );
+ ScCondFrmtItem( const ScCondFrmtItem& rItem );
+ ~ScCondFrmtItem();
+
+ virtual String GetValueText() const;
+ virtual int operator==( const SfxPoolItem& ) const;
+ virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const;
+
+ const ScConditionalFormat& GetData() const { return theCondFrmtData; }
+
+private:
+ ScConditionalFormat theCondFrmtData;
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undobase.hxx b/sc/source/ui/inc/undobase.hxx
new file mode 100644
index 000000000000..6f2bb3572832
--- /dev/null
+++ b/sc/source/ui/inc/undobase.hxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UNDOBASE_HXX
+#define SC_UNDOBASE_HXX
+
+#include <svl/undo.hxx>
+#include "global.hxx"
+#include "address.hxx"
+
+class ScDocument;
+class ScDocShell;
+class SdrUndoAction;
+class ScRefUndoData;
+class ScDBData;
+
+//----------------------------------------------------------------------------
+
+class ScSimpleUndo: public SfxUndoAction
+{
+public:
+ TYPEINFO();
+ ScSimpleUndo( ScDocShell* pDocSh );
+ virtual ~ScSimpleUndo();
+
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+
+protected:
+ ScDocShell* pDocShell;
+ SfxUndoAction* pDetectiveUndo;
+
+ void BeginUndo();
+ void EndUndo();
+ void BeginRedo();
+ void EndRedo();
+
+ static void ShowTable( SCTAB nTab );
+ static void ShowTable( const ScRange& rRange );
+};
+
+//----------------------------------------------------------------------------
+
+enum ScBlockUndoMode { SC_UNDO_SIMPLE, SC_UNDO_MANUALHEIGHT, SC_UNDO_AUTOHEIGHT };
+
+class ScBlockUndo: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScBlockUndo( ScDocShell* pDocSh, const ScRange& rRange,
+ ScBlockUndoMode eBlockMode );
+ virtual ~ScBlockUndo();
+
+protected:
+ ScRange aBlockRange;
+ SdrUndoAction* pDrawUndo;
+ ScBlockUndoMode eMode;
+
+ void BeginUndo();
+ void EndUndo();
+// void BeginRedo();
+ void EndRedo();
+
+ BOOL AdjustHeight();
+ void ShowBlock();
+};
+
+//----------------------------------------------------------------------------
+
+// for functions that act on a database range - takes care of the unnamed database range
+// (collected separately, before the undo action, for showing dialogs etc.)
+
+class ScDBFuncUndo: public ScSimpleUndo
+{
+ ScDBData* pAutoDBRange;
+ ScRange aOriginalRange;
+ SdrUndoAction* mpDrawUndo;
+
+public:
+ TYPEINFO();
+ ScDBFuncUndo( ScDocShell* pDocSh, const ScRange& rOriginal, SdrUndoAction* pDrawUndo = 0 );
+ virtual ~ScDBFuncUndo();
+
+ void SetDrawUndoAction( SdrUndoAction* pDrawUndo );
+
+ void BeginUndo();
+ void EndUndo();
+ void BeginRedo();
+ void EndRedo();
+};
+
+//----------------------------------------------------------------------------
+
+enum ScMoveUndoMode { SC_UNDO_REFFIRST, SC_UNDO_REFLAST };
+
+class ScMoveUndo: public ScSimpleUndo // mit Referenzen
+{
+public:
+ TYPEINFO();
+ ScMoveUndo( ScDocShell* pDocSh,
+ ScDocument* pRefDoc, ScRefUndoData* pRefData,
+ ScMoveUndoMode eRefMode );
+ virtual ~ScMoveUndo();
+
+protected:
+ SdrUndoAction* pDrawUndo;
+ ScDocument* pRefUndoDoc;
+ ScRefUndoData* pRefUndoData;
+ ScMoveUndoMode eMode;
+
+ void BeginUndo();
+ void EndUndo();
+// void BeginRedo();
+// void EndRedo();
+
+private:
+ void UndoRef();
+};
+
+//----------------------------------------------------------------------------
+
+class ScUndoWrapper: public SfxUndoAction // for manual merging of actions
+{
+ SfxUndoAction* pWrappedUndo;
+
+public:
+ TYPEINFO();
+ ScUndoWrapper( SfxUndoAction* pUndo );
+ virtual ~ScUndoWrapper();
+
+ SfxUndoAction* GetWrappedUndo() { return pWrappedUndo; }
+ void ForgetWrappedUndo();
+
+ virtual BOOL IsLinked();
+ virtual void SetLinked( BOOL bIsLinked );
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+ virtual String GetComment() const;
+ virtual String GetRepeatComment(SfxRepeatTarget&) const;
+ virtual USHORT GetId() const;
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
new file mode 100644
index 000000000000..574926ecbf52
--- /dev/null
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -0,0 +1,988 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_UNDOBLK_HXX
+#define SC_UNDOBLK_HXX
+
+#include "undobase.hxx"
+#include "markdata.hxx"
+#include "viewutil.hxx"
+#include "spellparam.hxx"
+
+class ScDocShell;
+class ScBaseCell;
+class ScDocument;
+class ScOutlineTable;
+class ScRangeName;
+class ScRangeList;
+class ScDBCollection;
+class ScPatternAttr;
+class SvxBoxItem;
+class SvxBoxInfoItem;
+class SvxSearchItem;
+class SdrUndoAction;
+
+//----------------------------------------------------------------------------
+
+class ScUndoInsertCells: public ScMoveUndo
+{
+public:
+ TYPEINFO();
+ ScUndoInsertCells( ScDocShell* pNewDocShell,
+ const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
+ InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
+ BOOL bNewPartOfPaste );
+ virtual ~ScUndoInsertCells();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat( SfxRepeatTarget& rTarget );
+ virtual BOOL CanRepeat( SfxRepeatTarget& rTarget ) const;
+
+ virtual String GetComment() const;
+
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+
+private:
+ ScRange aEffRange;
+ SCTAB nCount;
+ SCTAB* pTabs;
+ SCTAB* pScenarios;
+ ULONG nEndChangeAction;
+ InsCellCmd eCmd;
+ BOOL bPartOfPaste;
+ SfxUndoAction* pPasteUndo;
+
+ void DoChange ( const BOOL bUndo );
+ void SetChangeTrack();
+};
+
+
+class ScUndoDeleteCells: public ScMoveUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDeleteCells( ScDocShell* pNewDocShell,
+ const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
+ DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData );
+ virtual ~ScUndoDeleteCells();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange aEffRange;
+ SCTAB nCount;
+ SCTAB* pTabs;
+ SCTAB* pScenarios;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ DelCellCmd eCmd;
+
+ void DoChange ( const BOOL bUndo );
+ void SetChangeTrack();
+};
+
+
+class ScUndoDeleteMulti: public ScMoveUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDeleteMulti( ScDocShell* pNewDocShell,
+ BOOL bNewRows, BOOL bNeedsRefresh, SCTAB nNewTab,
+ const SCCOLROW* pRng, SCCOLROW nRngCnt,
+ ScDocument* pUndoDocument, ScRefUndoData* pRefData );
+ virtual ~ScUndoDeleteMulti();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ BOOL bRows;
+ BOOL bRefresh;
+ SCTAB nTab;
+ SCCOLROW* pRanges;
+ SCCOLROW nRangeCnt;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+
+ void DoChange() const;
+ void SetChangeTrack();
+};
+
+
+class ScUndoCut: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoCut( ScDocShell* pNewDocShell,
+ ScRange aRange, // adjusted for merged cells
+ ScAddress aOldEnd, // end position without adjustment
+ const ScMarkData& rMark, // selected sheets
+ ScDocument* pNewUndoDoc );
+ virtual ~ScUndoCut();
+
+ 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;
+ ScRange aExtendedRange;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+
+ void DoChange( const BOOL bUndo );
+ void SetChangeTrack();
+};
+
+
+struct ScUndoPasteOptions
+{
+ USHORT nFunction;
+ BOOL bSkipEmpty;
+ BOOL bTranspose;
+ BOOL bAsLink;
+ InsCellCmd eMoveMode;
+
+ ScUndoPasteOptions() :
+ nFunction( PASTE_NOFUNC ),
+ bSkipEmpty( FALSE ),
+ bTranspose( FALSE ),
+ bAsLink( FALSE ),
+ eMoveMode( INS_NONE )
+ {}
+};
+
+class ScUndoPaste: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoPaste( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
+ USHORT nNewFlags,
+ ScRefUndoData* pRefData, void* pFill1, void* pFill2, void* pFill3,
+ BOOL bRedoIsFilled = TRUE,
+ const ScUndoPasteOptions* pOptions = NULL );
+ virtual ~ScUndoPaste();
+
+ 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;
+ USHORT nFlags;
+ ScRefUndoData* pRefUndoData;
+ ScRefUndoData* pRefRedoData;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ BOOL bRedoFilled;
+ ScUndoPasteOptions aPasteOptions;
+
+ void DoChange( const BOOL bUndo );
+ void SetChangeTrack();
+};
+
+
+class ScUndoDragDrop: public ScMoveUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDragDrop( ScDocShell* pNewDocShell,
+ const ScRange& rRange, ScAddress aNewDestPos, BOOL bNewCut,
+ ScDocument* pUndoDocument, ScRefUndoData* pRefData,
+ BOOL bScenario );
+ virtual ~ScUndoDragDrop();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange aSrcRange;
+ ScRange aDestRange;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ BOOL bCut;
+ BOOL bKeepScenarioFlags;
+
+ void PaintArea( ScRange aRange, USHORT nExtFlags ) const;
+ void DoUndo( ScRange aRange ) const;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoDeleteContents: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDeleteContents( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ const ScRange& rRange,
+ ScDocument* pNewUndoDoc, BOOL bNewMulti,
+ USHORT nNewFlags, BOOL bObjects );
+ virtual ~ScUndoDeleteContents();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange aRange;
+ ScMarkData aMarkData;
+ ScDocument* pUndoDoc; // Blockmarkierung und geloeschte Daten
+ SdrUndoAction* pDrawUndo; // geloeschte Objekte
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ USHORT nFlags;
+ BOOL bMulti; // Mehrfachselektion
+
+ void DoChange( const BOOL bUndo );
+ void SetChangeTrack();
+};
+
+
+class ScUndoFillTable: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoFillTable( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, BOOL bNewMulti, SCTAB nSrc,
+ USHORT nFlg, USHORT nFunc, BOOL bSkip, BOOL bLink );
+ virtual ~ScUndoFillTable();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange aRange;
+ ScMarkData aMarkData;
+ ScDocument* pUndoDoc; // Blockmarkierung und geloeschte Daten
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ USHORT nFlags;
+ USHORT nFunction;
+ SCTAB nSrcTab;
+ BOOL bMulti; // Mehrfachselektion
+ BOOL bSkipEmpty;
+ BOOL bAsLink;
+
+ void DoChange( const BOOL bUndo );
+ void SetChangeTrack();
+};
+
+
+class ScUndoSelectionAttr: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoSelectionAttr( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, BOOL bNewMulti,
+ const ScPatternAttr* pNewApply,
+ const SvxBoxItem* pNewOuter = NULL,
+ const SvxBoxInfoItem* pNewInner = NULL );
+ virtual ~ScUndoSelectionAttr();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScMarkData aMarkData;
+ ScRange aRange;
+ ScDocument* pUndoDoc;
+ BOOL bMulti;
+ ScPatternAttr* pApplyPattern;
+ SvxBoxItem* pLineOuter;
+ SvxBoxInfoItem* pLineInner;
+
+ void DoChange( const BOOL bUndo );
+};
+
+
+class ScUndoWidthOrHeight: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoWidthOrHeight( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOLROW nNewStart, SCTAB nNewStartTab,
+ SCCOLROW nNewEnd, SCTAB nNewEndTab,
+ ScDocument* pNewUndoDoc,
+ SCCOLROW nNewCnt, SCCOLROW* pNewRanges,
+ ScOutlineTable* pNewUndoTab,
+ ScSizeMode eNewMode, USHORT nNewSizeTwips,
+ BOOL bNewWidth );
+ virtual ~ScUndoWidthOrHeight();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScMarkData aMarkData;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ SCTAB nStartTab;
+ SCTAB nEndTab;
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTab;
+ SCCOLROW nRangeCnt;
+ SCCOLROW* pRanges;
+ USHORT nNewSize;
+ BOOL bWidth;
+ ScSizeMode eMode;
+ SdrUndoAction* pDrawUndo;
+};
+
+
+class ScUndoAutoFill: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoAutoFill( ScDocShell* pNewDocShell,
+ const ScRange& rRange, const ScRange& rSourceArea,
+ ScDocument* pNewUndoDoc, const ScMarkData& rMark,
+ FillDir eNewFillDir,
+ FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
+ double fNewStartValue, double fNewStepValue, double fNewMaxValue,
+ USHORT nMaxShIndex );
+ virtual ~ScUndoAutoFill();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange aSource;
+ ScMarkData aMarkData;
+ ScDocument* pUndoDoc;
+ FillDir eFillDir;
+ FillCmd eFillCmd;
+ FillDateCmd eFillDateCmd;
+ double fStartValue;
+ double fStepValue;
+ double fMaxValue;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ USHORT nMaxSharedIndex;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoMerge: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoMerge( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo );
+ virtual ~ScUndoMerge();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange maRange;
+ bool mbMergeContents; // Merge contents in Redo().
+ ScDocument* mpUndoDoc; // wenn Daten zusammengefasst
+ SdrUndoAction* mpDrawUndo;
+
+ void DoChange( bool bUndo ) const;
+};
+
+
+class ScUndoAutoFormat: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoAutoFormat( ScDocShell* pNewDocShell,
+ const ScRange& rRange, ScDocument* pNewUndoDoc,
+ const ScMarkData& rMark,
+ BOOL bNewSize, USHORT nNewFormatNo );
+ virtual ~ScUndoAutoFormat();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc; // geloeschte Daten
+ ScMarkData aMarkData;
+ BOOL bSize;
+ USHORT nFormatNo;
+};
+
+
+class ScUndoReplace: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoReplace( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ const String& rNewUndoStr, ScDocument* pNewUndoDoc,
+ const SvxSearchItem* pItem );
+ virtual ~ScUndoReplace();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aCursorPos;
+ ScMarkData aMarkData;
+ String aUndoStr; // Daten bei Einfachmarkierung
+ ScDocument* pUndoDoc; // Blockmarkierung und geloeschte Daten
+ SvxSearchItem* pSearchItem;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoTabOp: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoTabOp( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc,
+ const ScRefAddress& rFormulaCell,
+ const ScRefAddress& rFormulaEnd,
+ const ScRefAddress& rRowCell,
+ const ScRefAddress& rColCell,
+ BYTE nMode );
+ virtual ~ScUndoTabOp();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRange aRange;
+ ScDocument* pUndoDoc; // geloeschte Daten
+ ScRefAddress theFormulaCell;
+ ScRefAddress theFormulaEnd;
+ ScRefAddress theRowCell;
+ ScRefAddress theColCell;
+ BYTE nMode;
+};
+
+
+class ScUndoConversion : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+
+ ScUndoConversion(
+ ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScDocument* pNewUndoDoc,
+ SCCOL nNewX, SCROW nNewY, SCTAB nNewZ, ScDocument* pNewRedoDoc,
+ const ScConversionParam& rConvParam );
+ virtual ~ScUndoConversion();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScMarkData aMarkData;
+ ScAddress aCursorPos;
+ ScDocument* pUndoDoc; // Blockmarkierung und geloeschte Daten
+ ScAddress aNewCursorPos;
+ ScDocument* pRedoDoc; // Blockmarkierung und neue Daten
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ ScConversionParam maConvParam; /// Conversion type and parameters.
+
+ void DoChange( ScDocument* pRefDoc, const ScAddress& rCursorPos );
+ 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
+{
+public:
+ TYPEINFO();
+ ScUndoListNames( ScDocShell* pNewDocShell,
+ const ScRange& rRange,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc );
+ virtual ~ScUndoListNames();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc;
+ ScDocument* pRedoDoc;
+
+ void DoChange( ScDocument* pSrcDoc ) const;
+};
+
+
+class ScUndoUseScenario: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoUseScenario( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ const ScArea& rDestArea, ScDocument* pNewUndoDoc,
+ const String& rNewName );
+ virtual ~ScUndoUseScenario();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc;
+ ScRange aRange;
+ ScMarkData aMarkData;
+ String aName;
+};
+
+
+class ScUndoSelectionStyle: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoSelectionStyle( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ const ScRange& rRange,
+ const String& rName,
+ ScDocument* pNewUndoDoc );
+ virtual ~ScUndoSelectionStyle();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+ virtual USHORT GetId() const;
+
+private:
+ ScMarkData aMarkData;
+ ScDocument* pUndoDoc;
+ String aStyleName;
+ ScRange aRange;
+
+ void DoChange( const BOOL bUndo );
+};
+
+
+class ScUndoRefreshLink: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRefreshLink( ScDocShell* pNewDocShell,
+ ScDocument* pNewUndoDoc );
+ virtual ~ScUndoRefreshLink();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc;
+ ScDocument* pRedoDoc;
+};
+
+
+class ScUndoEnterMatrix: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoEnterMatrix( ScDocShell* pNewDocShell,
+ const ScRange& rArea,
+ ScDocument* pNewUndoDoc,
+ const String& rForm );
+ virtual ~ScUndoEnterMatrix();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc;
+ String aFormula;
+ formula::FormulaGrammar::AddressConvention eConv;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoInsertAreaLink : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoInsertAreaLink( ScDocShell* pShell,
+ const String& rDoc,
+ const String& rFlt, const String& rOpt,
+ const String& rArea, const ScRange& rDestRange,
+ ULONG nRefreshDelay );
+ virtual ~ScUndoInsertAreaLink();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aDocName;
+ String aFltName;
+ String aOptions;
+ String aAreaName;
+ ScRange aRange;
+ ULONG nRefreshDelay;
+};
+
+
+class ScUndoRemoveAreaLink : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRemoveAreaLink( ScDocShell* pShell,
+ const String& rDoc,
+ const String& rFlt, const String& rOpt,
+ const String& rArea, const ScRange& rDestRange,
+ ULONG nRefreshDelay );
+ virtual ~ScUndoRemoveAreaLink();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aDocName;
+ String aFltName;
+ String aOptions;
+ String aAreaName;
+ ScRange aRange;
+ ULONG nRefreshDelay;
+};
+
+
+class ScUndoUpdateAreaLink : public ScSimpleUndo //! auch BlockUndo umstellen?
+{
+public:
+ TYPEINFO();
+ ScUndoUpdateAreaLink( ScDocShell* pShell,
+ const String& rOldD,
+ const String& rOldF, const String& rOldO,
+ const String& rOldA, const ScRange& rOldR,
+ ULONG nOldRD,
+ const String& rNewD,
+ const String& rNewF, const String& rNewO,
+ const String& rNewA, const ScRange& rNewR,
+ ULONG nNewRD,
+ ScDocument* pUndo, ScDocument* pRedo,
+ BOOL bDoInsert );
+ virtual ~ScUndoUpdateAreaLink();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aOldDoc;
+ String aOldFlt;
+ String aOldOpt;
+ String aOldArea;
+ ScRange aOldRange;
+ String aNewDoc;
+ String aNewFlt;
+ String aNewOpt;
+ String aNewArea;
+ ScRange aNewRange;
+ ScDocument* pUndoDoc;
+ ScDocument* pRedoDoc;
+ ULONG nOldRefresh;
+ ULONG nNewRefresh;
+ BOOL bWithInsert;
+
+ void DoChange( const BOOL bUndo ) const;
+};
+
+
+class ScUndoIndent: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, BOOL bIncrement );
+ virtual ~ScUndoIndent();
+
+ 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;
+ BOOL bIsIncrement;
+};
+
+
+class ScUndoTransliterate: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, sal_Int32 nType );
+ virtual ~ScUndoTransliterate();
+
+ 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;
+ sal_Int32 nTransliterationType;
+};
+
+
+class ScUndoClearItems: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, const USHORT* pW );
+ virtual ~ScUndoClearItems();
+
+ 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;
+ USHORT* pWhich;
+};
+
+
+class ScUndoRemoveBreaks: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
+ SCTAB nNewTab, ScDocument* pNewUndoDoc );
+ virtual ~ScUndoRemoveBreaks();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ ScDocument* pUndoDoc;
+};
+
+
+class ScUndoRemoveMerge: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRemoveMerge( ScDocShell* pNewDocShell,
+ const ScRange& rArea,
+ ScDocument* pNewUndoDoc );
+ virtual ~ScUndoRemoveMerge();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc;
+};
+
+
+class ScUndoBorder: public ScBlockUndo
+{
+public:
+ TYPEINFO();
+ ScUndoBorder( ScDocShell* pNewDocShell,
+ const ScRangeList& rRangeList,
+ ScDocument* pNewUndoDoc,
+ const SvxBoxItem& rNewOuter,
+ const SvxBoxInfoItem& rNewInner );
+ virtual ~ScUndoBorder();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pUndoDoc;
+ ScRangeList* pRanges;
+ SvxBoxItem* pOuter;
+ SvxBoxInfoItem* pInner;
+};
+
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undocell.hxx b/sc/source/ui/inc/undocell.hxx
new file mode 100644
index 000000000000..53f129166d10
--- /dev/null
+++ b/sc/source/ui/inc/undocell.hxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UNDOCELL_HXX
+#define SC_UNDOCELL_HXX
+
+#include "undobase.hxx"
+#include "postit.hxx"
+
+class ScDocShell;
+class ScBaseCell;
+class ScPatternAttr;
+class EditTextObject;
+class SdrUndoAction;
+class ScDetOpList;
+class ScDetOpData;
+class ScRangeName;
+
+//----------------------------------------------------------------------------
+
+class ScUndoCursorAttr: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoCursorAttr( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ const ScPatternAttr* pOldPat, const ScPatternAttr* pNewPat,
+ const ScPatternAttr* pApplyPat, BOOL bAutomatic );
+ virtual ~ScUndoCursorAttr();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ ScPatternAttr* pOldPattern;
+ ScPatternAttr* pNewPattern;
+ ScPatternAttr* pApplyPattern;
+ BOOL bIsAutomatic;
+
+ void DoChange( const ScPatternAttr* pWhichPattern ) const;
+};
+
+
+class ScUndoEnterData: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoEnterData( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ SCTAB nNewCount, SCTAB* pNewTabs,
+ ScBaseCell** ppOldData, BOOL* pHasForm, ULONG* pOldForm,
+ const String& rNewStr, EditTextObject* pObj = NULL );
+ virtual ~ScUndoEnterData();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aNewString;
+ SCTAB* pTabs;
+ ScBaseCell** ppOldCells;
+ BOOL* pHasFormat;
+ ULONG* pOldFormats;
+ EditTextObject* pNewEditData;
+ ULONG nEndChangeAction;
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ SCTAB nCount; // markierte Tabellen
+
+ void DoChange() const;
+ void SetChangeTrack();
+};
+
+
+class ScUndoEnterValue: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoEnterValue( ScDocShell* pNewDocShell,
+ const ScAddress& rNewPos,
+ ScBaseCell* pUndoCell, double nVal, BOOL bHeight );
+ virtual ~ScUndoEnterValue();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aPos;
+ ScBaseCell* pOldCell;
+ double nValue;
+ ULONG nEndChangeAction;
+ BOOL bNeedHeight;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoPutCell: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoPutCell( ScDocShell* pNewDocShell,
+ const ScAddress& rNewPos,
+ ScBaseCell* pUndoCell, ScBaseCell* pRedoCell, BOOL bHeight );
+ virtual ~ScUndoPutCell();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aPos;
+ ScBaseCell* pOldCell;
+ ScBaseCell* pEnteredCell;
+ ULONG nEndChangeAction;
+ BOOL bNeedHeight;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoPageBreak: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoPageBreak( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ BOOL bNewColumn, BOOL bNewInsert );
+ virtual ~ScUndoPageBreak();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ BOOL bColumn; // Spalten- oder Zeilenumbruch
+ BOOL bInsert; // Einfuegen oder Loeschen
+
+ void DoChange( BOOL bInsert ) const;
+};
+
+class ScUndoPrintZoom: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoPrintZoom( ScDocShell* pNewDocShell, SCTAB nT,
+ USHORT nOS, USHORT nOP, USHORT nNS, USHORT nNP );
+ virtual ~ScUndoPrintZoom();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ USHORT nOldScale;
+ USHORT nOldPages;
+ USHORT nNewScale;
+ USHORT nNewPages;
+
+ void DoChange( BOOL bUndo );
+};
+
+class ScUndoThesaurus: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoThesaurus( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ const String& rNewUndoStr, const EditTextObject* pUndoTObj,
+ const String& rNewRedoStr, const EditTextObject* pRedoTObj);
+ virtual ~ScUndoThesaurus();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ String aUndoStr; // Daten bei StringZelle
+ EditTextObject* pUndoTObject; // bei EditZelle
+ String aRedoStr;
+ EditTextObject* pRedoTObject;
+ ULONG nEndChangeAction;
+
+ void DoChange( BOOL bUndo, const String& rStr,
+ const EditTextObject* pTObj );
+ void SetChangeTrack( ScBaseCell* pOldCell );
+};
+
+// ============================================================================
+
+/** Undo action for inserting, removing, and replacing a cell note. */
+class ScUndoReplaceNote : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+
+ /** Constructs an undo action for inserting or removing a cell note. */
+ ScUndoReplaceNote(
+ ScDocShell& rDocShell,
+ const ScAddress& rPos,
+ const ScNoteData& rNoteData,
+ bool bInsert,
+ SdrUndoAction* pDrawUndo );
+
+ /** Constructs an undo action for replacing a cell note with another. */
+ ScUndoReplaceNote(
+ ScDocShell& rDocShell,
+ const ScAddress& rPos,
+ const ScNoteData& rOldData,
+ const ScNoteData& rNewData,
+ SdrUndoAction* pDrawUndo );
+
+ virtual ~ScUndoReplaceNote();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat( SfxRepeatTarget& rTarget );
+ virtual BOOL CanRepeat( SfxRepeatTarget& rTarget ) const;
+
+ virtual String GetComment() const;
+
+private:
+ void DoInsertNote( const ScNoteData& rNoteData );
+ void DoRemoveNote( const ScNoteData& rNoteData );
+
+private:
+ ScAddress maPos;
+ ScNoteData maOldData;
+ ScNoteData maNewData;
+ SdrUndoAction* mpDrawUndo;
+};
+
+// ============================================================================
+
+/** Undo action for showing or hiding a cell note caption. */
+class ScUndoShowHideNote : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoShowHideNote( ScDocShell& rDocShell, const ScAddress& rPos, bool bShow );
+ virtual ~ScUndoShowHideNote();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat( SfxRepeatTarget& rTarget );
+ virtual BOOL CanRepeat( SfxRepeatTarget& rTarget ) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress maPos;
+ bool mbShown;
+};
+
+// ============================================================================
+
+class ScUndoDetective: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDetective( ScDocShell* pNewDocShell,
+ SdrUndoAction* pDraw, const ScDetOpData* pOperation,
+ ScDetOpList* pUndoList = NULL );
+ virtual ~ScUndoDetective();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ BOOL bIsDelete;
+ ScDetOpList* pOldList;
+ USHORT nAction;
+ ScAddress aPos;
+ SdrUndoAction* pDrawUndo;
+};
+
+
+class ScUndoRangeNames: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRangeNames( ScDocShell* pNewDocShell,
+ ScRangeName* pOld, ScRangeName* pNew );
+ virtual ~ScUndoRangeNames();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScRangeName* pOldRanges;
+ ScRangeName* pNewRanges;
+
+ void DoChange( BOOL bUndo );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undodat.hxx b/sc/source/ui/inc/undodat.hxx
new file mode 100644
index 000000000000..a2fcd392e9b4
--- /dev/null
+++ b/sc/source/ui/inc/undodat.hxx
@@ -0,0 +1,535 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_UNDODAT_HXX
+#define SC_UNDODAT_HXX
+
+#include "undobase.hxx"
+#include "rangeutl.hxx" // ScArea
+#include "rangelst.hxx" // ScRangeListRef
+#include "markdata.hxx"
+#include "sortparam.hxx"
+#include "queryparam.hxx"
+#include "pivot.hxx"
+
+class ScDocShell;
+class ScDocument;
+class ScOutlineTable;
+class ScRangeName;
+class ScDBData;
+class ScDBCollection;
+class ScDPObject;
+class SdrUndoAction;
+
+//----------------------------------------------------------------------------
+
+class ScUndoDoOutline: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDoOutline( ScDocShell* pNewDocShell,
+ SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
+ ScDocument* pNewUndoDoc, BOOL bNewColumns,
+ USHORT nNewLevel, USHORT nNewEntry, BOOL bNewShow );
+ virtual ~ScUndoDoOutline();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ SCTAB nTab;
+ ScDocument* pUndoDoc;
+ BOOL bColumns;
+ USHORT nLevel;
+ USHORT nEntry;
+ BOOL bShow;
+};
+
+
+class ScUndoMakeOutline: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoMakeOutline( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScOutlineTable* pNewUndoTab,
+ BOOL bNewColumns, BOOL bNewMake );
+ virtual ~ScUndoMakeOutline();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aBlockStart;
+ ScAddress aBlockEnd;
+ ScOutlineTable* pUndoTable;
+ BOOL bColumns;
+ BOOL bMake;
+};
+
+
+class ScUndoOutlineLevel: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoOutlineLevel( ScDocShell* pNewDocShell,
+ SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+ BOOL bNewColumns, USHORT nNewLevel );
+ virtual ~ScUndoOutlineLevel();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ SCTAB nTab;
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTable;
+ BOOL bColumns;
+ USHORT nLevel;
+};
+
+
+class ScUndoOutlineBlock: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoOutlineBlock( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+ BOOL bNewShow );
+ virtual ~ScUndoOutlineBlock();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aBlockStart;
+ ScAddress aBlockEnd;
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTable;
+ BOOL bShow;
+};
+
+
+class ScUndoRemoveAllOutlines: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRemoveAllOutlines( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab );
+ virtual ~ScUndoRemoveAllOutlines();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aBlockStart;
+ ScAddress aBlockEnd;
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTable;
+};
+
+
+class ScUndoAutoOutline: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoAutoOutline( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab );
+ virtual ~ScUndoAutoOutline();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aBlockStart;
+ ScAddress aBlockEnd;
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTable;
+};
+
+
+class ScUndoSubTotals: public ScDBFuncUndo
+{
+public:
+ TYPEINFO();
+ ScUndoSubTotals( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ const ScSubTotalParam& rNewParam, SCROW nNewEndY,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+// ScDBData* pNewData,
+ ScRangeName* pNewUndoRange, ScDBCollection* pNewUndoDB );
+ virtual ~ScUndoSubTotals();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ ScSubTotalParam aParam; // Original uebergebener Parameter
+ SCROW nNewEndRow; // Ergebnis-Groesse
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTable;
+// ScDBData* pUndoDBData;
+ ScRangeName* pUndoRange;
+ ScDBCollection* pUndoDB;
+};
+
+
+class ScUndoSort: public ScDBFuncUndo
+{
+public:
+ TYPEINFO();
+ ScUndoSort( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ const ScSortParam& rParam,
+ BOOL bQuery, ScDocument* pNewUndoDoc,
+ ScDBCollection* pNewUndoDB, const ScRange* pDest = NULL );
+ virtual ~ScUndoSort();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ ScSortParam aSortParam;
+ BOOL bRepeatQuery;
+ ScDocument* pUndoDoc;
+ ScDBCollection* pUndoDB; // wegen Quell- und Zielbereich
+ BOOL bDestArea;
+ ScRange aDestRange;
+};
+
+
+class ScUndoQuery: public ScDBFuncUndo
+{
+public:
+ TYPEINFO();
+ ScUndoQuery( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ const ScQueryParam& rParam, ScDocument* pNewUndoDoc,
+ ScDBCollection* pNewUndoDB, const ScRange* pOld,
+ BOOL bSize, const ScRange* pAdvSrc );
+ virtual ~ScUndoQuery();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SdrUndoAction* pDrawUndo;
+ SCTAB nTab;
+ ScQueryParam aQueryParam;
+ ScDocument* pUndoDoc;
+ ScDBCollection* pUndoDB; // wegen Quell- und Zielbereich
+ ScRange aOldDest;
+ ScRange aAdvSource;
+ BOOL bIsAdvanced;
+ BOOL bDestArea;
+ BOOL bDoSize;
+};
+
+
+class ScUndoAutoFilter: public ScDBFuncUndo
+{
+private:
+ String aDBName;
+ BOOL bFilterSet;
+
+ void DoChange( BOOL bUndo );
+
+public:
+ TYPEINFO();
+ ScUndoAutoFilter( ScDocShell* pNewDocShell, const ScRange& rRange,
+ const String& rName, BOOL bSet );
+ virtual ~ScUndoAutoFilter();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+};
+
+
+class ScUndoDBData: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDBData( ScDocShell* pNewDocShell,
+ ScDBCollection* pNewUndoColl, ScDBCollection* pNewRedoColl );
+ virtual ~ScUndoDBData();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDBCollection* pUndoColl;
+ ScDBCollection* pRedoColl;
+};
+
+
+class ScUndoImportData: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoImportData( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ const ScImportParam& rParam, SCCOL nNewEndX, SCROW nNewEndY,
+ SCCOL nNewFormula,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
+ ScDBData* pNewUndoData, ScDBData* pNewRedoData );
+ virtual ~ScUndoImportData();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ ScImportParam aImportParam;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ ScDocument* pUndoDoc;
+ ScDocument* pRedoDoc;
+ ScDBData* pUndoDBData;
+ ScDBData* pRedoDBData;
+ SCCOL nFormulaCols;
+ BOOL bRedoFilled;
+};
+
+
+class ScUndoRepeatDB: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRepeatDB( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
+ SCROW nResultEndRow, SCCOL nCurX, SCROW nCurY,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+ ScRangeName* pNewUndoRange, ScDBCollection* pNewUndoDB,
+ const ScRange* pOldQ, const ScRange* pNewQ );
+ virtual ~ScUndoRepeatDB();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScAddress aBlockStart;
+ ScAddress aBlockEnd;
+ SCROW nNewEndRow;
+ ScAddress aCursorPos;
+ ScDocument* pUndoDoc;
+ ScOutlineTable* pUndoTable;
+ ScRangeName* pUndoRange;
+ ScDBCollection* pUndoDB;
+ ScRange aOldQuery;
+ ScRange aNewQuery;
+ BOOL bQuerySize;
+};
+
+//UNUSED2008-05 class ScUndoPivot: public ScSimpleUndo
+//UNUSED2008-05 {
+//UNUSED2008-05 public:
+//UNUSED2008-05 TYPEINFO();
+//UNUSED2008-05 ScUndoPivot( ScDocShell* pNewDocShell,
+//UNUSED2008-05 const ScArea& rOld, const ScArea& rNew,
+//UNUSED2008-05 ScDocument* pOldDoc, ScDocument* pNewDoc,
+//UNUSED2008-05 const ScPivot* pOldPivot, const ScPivot* pNewPivot );
+//UNUSED2008-05 virtual ~ScUndoPivot();
+//UNUSED2008-05
+//UNUSED2008-05 virtual void Undo();
+//UNUSED2008-05 virtual void Redo();
+//UNUSED2008-05 virtual void Repeat(SfxRepeatTarget& rTarget);
+//UNUSED2008-05 virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+//UNUSED2008-05
+//UNUSED2008-05 virtual String GetComment() const;
+//UNUSED2008-05
+//UNUSED2008-05 private:
+//UNUSED2008-05 ScArea aOldArea;
+//UNUSED2008-05 ScArea aNewArea;
+//UNUSED2008-05 ScDocument* pOldUndoDoc;
+//UNUSED2008-05 ScDocument* pNewUndoDoc;
+//UNUSED2008-05 ScPivotParam aOldParam; // fuer Redo
+//UNUSED2008-05 ScQueryParam aOldQuery;
+//UNUSED2008-05 ScArea aOldSrc;
+//UNUSED2008-05 ScPivotParam aNewParam; // fuer Undo in Collection
+//UNUSED2008-05 ScQueryParam aNewQuery;
+//UNUSED2008-05 ScArea aNewSrc;
+//UNUSED2008-05 String aOldName;
+//UNUSED2008-05 String aOldTag;
+//UNUSED2008-05 String aNewName;
+//UNUSED2008-05 String aNewTag;
+//UNUSED2008-05 };
+
+class ScUndoDataPilot: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoDataPilot( ScDocShell* pNewDocShell,
+ ScDocument* pOldDoc, ScDocument* pNewDoc,
+ const ScDPObject* pOldObj, const ScDPObject* pNewObj,
+ BOOL bMove );
+ virtual ~ScUndoDataPilot();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScDocument* pOldUndoDoc;
+ ScDocument* pNewUndoDoc;
+ ScDPObject* pOldDPObject;
+ ScDPObject* pNewDPObject;
+ BOOL bAllowMove;
+};
+
+
+class ScUndoConsolidate: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoConsolidate( ScDocShell* pNewDocShell,
+ const ScArea& rArea, const ScConsolidateParam& rPar,
+ ScDocument* pNewUndoDoc, BOOL bReference,
+ SCROW nInsCount, ScOutlineTable* pTab,
+ ScDBData* pData );
+ virtual ~ScUndoConsolidate();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScArea aDestArea;
+ ScDocument* pUndoDoc;
+ ScConsolidateParam aParam;
+ BOOL bInsRef;
+ SCSIZE nInsertCount;
+ ScOutlineTable* pUndoTab;
+ ScDBData* pUndoData;
+};
+
+
+class ScUndoChartData: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoChartData( ScDocShell* pNewDocShell,
+ const String& rName, const ScRange& rNew,
+ BOOL bColHdr, BOOL bRowHdr, BOOL bAdd );
+ ScUndoChartData( ScDocShell* pNewDocShell,
+ const String& rName, const ScRangeListRef& rNew,
+ BOOL bColHdr, BOOL bRowHdr, BOOL bAdd );
+ virtual ~ScUndoChartData();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aChartName;
+ ScRangeListRef aOldRangeListRef;
+ BOOL bOldColHeaders;
+ BOOL bOldRowHeaders;
+// ScRange aNewRange;
+ ScRangeListRef aNewRangeListRef;
+ BOOL bNewColHeaders;
+ BOOL bNewRowHeaders;
+ BOOL bAddRange;
+
+ void Init();
+};
+
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undodraw.hxx b/sc/source/ui/inc/undodraw.hxx
new file mode 100644
index 000000000000..a2647985af9f
--- /dev/null
+++ b/sc/source/ui/inc/undodraw.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UNDODRAW_HXX
+#define SC_UNDODRAW_HXX
+
+#include <svl/undo.hxx>
+
+class ScDocShell;
+
+class ScUndoDraw: public SfxUndoAction
+{
+ SfxUndoAction* pDrawUndo;
+ ScDocShell* pDocShell;
+
+public:
+ TYPEINFO();
+ ScUndoDraw( SfxUndoAction* pUndo, ScDocShell* pDocSh );
+ virtual ~ScUndoDraw();
+
+ SfxUndoAction* GetDrawUndo() { return pDrawUndo; }
+ void ForgetDrawUndo();
+
+ virtual BOOL IsLinked();
+ virtual void SetLinked( BOOL bIsLinked );
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+ virtual String GetComment() const;
+ virtual String GetRepeatComment(SfxRepeatTarget&) const;
+ virtual USHORT GetId() const;
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undoolk.hxx b/sc/source/ui/inc/undoolk.hxx
new file mode 100644
index 000000000000..527c973b6705
--- /dev/null
+++ b/sc/source/ui/inc/undoolk.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_UNDOOLK_HXX
+#define SC_UNDOOLK_HXX
+
+#include <tools/solar.h>
+
+class SdrUndoAction;
+class ScDocument;
+
+SdrUndoAction* GetSdrUndoAction ( ScDocument* pDoc );
+void DoSdrUndoAction ( SdrUndoAction* pUndoAction, ScDocument* pDoc );
+void RedoSdrUndoAction ( SdrUndoAction* pUndoAction );
+void DeleteSdrUndoAction ( SdrUndoAction* pUndoAction );
+void EnableDrawAdjust ( ScDocument* pDoc, BOOL bEnable );
+
+
+
+#endif
diff --git a/sc/source/ui/inc/undostyl.hxx b/sc/source/ui/inc/undostyl.hxx
new file mode 100644
index 000000000000..5e7b86449722
--- /dev/null
+++ b/sc/source/ui/inc/undostyl.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UNDOSTYL_HXX
+#define SC_UNDOSTYL_HXX
+
+#include <rsc/rscsfx.hxx>
+#include "undobase.hxx"
+
+class ScDocShell;
+class SfxStyleSheetBase;
+
+//----------------------------------------------------------------------------
+
+class ScStyleSaveData
+{
+private:
+ String aName;
+ String aParent;
+ SfxItemSet* pItems;
+
+public:
+ ScStyleSaveData();
+ ScStyleSaveData( const ScStyleSaveData& rOther );
+ ~ScStyleSaveData();
+ ScStyleSaveData& operator=( const ScStyleSaveData& rOther );
+
+ void InitFromStyle( const SfxStyleSheetBase* pSource );
+
+ const String& GetName() const { return aName; }
+ const String& GetParent() const { return aParent; }
+ const SfxItemSet* GetItems() const { return pItems; }
+};
+
+class ScUndoModifyStyle: public ScSimpleUndo
+{
+private:
+ SfxStyleFamily eFamily;
+ ScStyleSaveData aOldData;
+ ScStyleSaveData aNewData;
+
+ static void DoChange( ScDocShell* pDocSh,
+ const String& rName, SfxStyleFamily eStyleFamily,
+ const ScStyleSaveData& rData );
+
+public:
+ TYPEINFO();
+ ScUndoModifyStyle( ScDocShell* pDocSh,
+ SfxStyleFamily eFam,
+ const ScStyleSaveData& rOld,
+ const ScStyleSaveData& rNew );
+ virtual ~ScUndoModifyStyle();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+};
+
+class ScUndoApplyPageStyle: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoApplyPageStyle( ScDocShell* pDocSh, const String& rNewStyle );
+ virtual ~ScUndoApplyPageStyle();
+
+ void AddSheetAction( SCTAB nTab, const String& rOld );
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ struct ApplyStyleEntry
+ {
+ SCTAB mnTab;
+ String maOldStyle;
+ explicit ApplyStyleEntry( SCTAB nTab, const String& rOldStyle );
+ };
+ typedef ::std::vector< ApplyStyleEntry > ApplyStyleVec;
+
+ ApplyStyleVec maEntries;
+ String maNewStyle;
+};
+
+
+#endif
+
diff --git a/sc/source/ui/inc/undotab.hxx b/sc/source/ui/inc/undotab.hxx
new file mode 100644
index 000000000000..c8d135070ab1
--- /dev/null
+++ b/sc/source/ui/inc/undotab.hxx
@@ -0,0 +1,543 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_UNDOTAB_HXX
+#define SC_UNDOTAB_HXX
+
+#include "undobase.hxx"
+#include "markdata.hxx"
+#include "formula/grammar.hxx"
+#include <tools/color.hxx>
+#include "tabbgcolor.hxx"
+
+#ifndef _SVSTDARR_SHORTS
+
+#define _SVSTDARR_SHORTS
+#include <svl/svstdarr.hxx>
+
+#endif
+
+#ifndef _SVSTDARR_STRINGS
+
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+
+#endif
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <memory>
+
+class ScDocShell;
+class ScDocument;
+class SdrUndoAction;
+class ScPrintRangeSaver;
+class SdrObject;
+class ScDocProtection;
+class ScTableProtection;
+
+//----------------------------------------------------------------------------
+
+class ScUndoInsertTab : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoInsertTab(
+ ScDocShell* pNewDocShell,
+ SCTAB nTabNum,
+ BOOL bApp,
+ const String& rNewName);
+ virtual ~ScUndoInsertTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String sNewName;
+ SdrUndoAction* pDrawUndo;
+ ULONG nEndChangeAction;
+ SCTAB nTab;
+ BOOL bAppend;
+
+ void SetChangeTrack();
+};
+
+class ScUndoInsertTables : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoInsertTables(
+ ScDocShell* pNewDocShell,
+ SCTAB nTabNum,
+ BOOL bApp,
+ SvStrings *pNewNameList);
+ virtual ~ScUndoInsertTables();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+
+ SdrUndoAction* pDrawUndo;
+ SvStrings* pNameList;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+ SCTAB nTab;
+ BOOL bAppend;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoDeleteTab: public ScMoveUndo // Draw vom Move fuer geloeschte Tabelle
+{
+public:
+ TYPEINFO();
+ ScUndoDeleteTab(
+ ScDocShell* pNewDocShell,
+ const SvShorts &theTabs, //SCTAB nNewTab,
+ ScDocument* pUndoDocument,
+ ScRefUndoData* pRefData );
+ virtual ~ScUndoDeleteTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SvShorts theTabs;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+
+ void SetChangeTrack();
+};
+
+
+class ScUndoRenameTab: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRenameTab(
+ ScDocShell* pNewDocShell,
+ SCTAB nT,
+ const String& rOldName,
+ const String& rNewName);
+ virtual ~ScUndoRenameTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ String sOldName;
+ String sNewName;
+
+ void DoChange( SCTAB nTab, const String& rName ) const;
+};
+
+
+class ScUndoMoveTab: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoMoveTab( ScDocShell* pNewDocShell,
+ const SvShorts &aOldTab,
+ const SvShorts &aNewTab);
+ virtual ~ScUndoMoveTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SvShorts theOldTabs;
+ SvShorts theNewTabs;
+
+ void DoChange( BOOL bUndo ) const;
+};
+
+
+class ScUndoCopyTab: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoCopyTab(ScDocShell* pNewDocShell,
+ const SvShorts &aOldTab,
+ const SvShorts &aNewTab);
+
+ virtual ~ScUndoCopyTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SdrUndoAction* pDrawUndo;
+ SvShorts theOldTabs;
+ SvShorts theNewTabs;
+
+ void DoChange() const;
+};
+
+class ScUndoTabColor: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoTabColor(
+ ScDocShell* pNewDocShell,
+ SCTAB nT,
+ const Color& aOTabBgColor,
+ const Color& aNTabBgColor);
+ ScUndoTabColor(
+ ScDocShell* pNewDocShell,
+ const ScUndoTabColorInfo::List& rUndoTabColorList);
+ virtual ~ScUndoTabColor();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+virtual String GetComment() const;
+
+private:
+ ScUndoTabColorInfo::List aTabColorList;
+ bool bIsMultipleUndo;
+
+ void DoChange(bool bUndoType) const;
+};
+
+class ScUndoMakeScenario: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoMakeScenario(
+ ScDocShell* pNewDocShell,
+ SCTAB nSrc, SCTAB nDest,
+ const String& rN, const String& rC,
+ const Color& rCol, USHORT nF,
+ const ScMarkData& rMark );
+ virtual ~ScUndoMakeScenario();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nSrcTab;
+ SCTAB nDestTab;
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ ScMarkData aMarkData;
+ SdrUndoAction* pDrawUndo;
+};
+
+
+class ScUndoImportTab : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoImportTab(
+ ScDocShell* pShell,
+ SCTAB nNewTab, SCTAB nNewCount,
+ BOOL bNewLink );
+ virtual ~ScUndoImportTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ SCTAB nCount;
+ BOOL bLink;
+ ScDocument* pRedoDoc;
+ SdrUndoAction* pDrawUndo;
+
+ void DoChange() const;
+};
+
+
+class ScUndoRemoveLink : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRemoveLink( // vor dem Loeschen aufrufen!
+ ScDocShell* pShell,
+ const String& rDoc );
+ virtual ~ScUndoRemoveLink();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aDocName;
+ String aFltName;
+ String aOptions;
+ ULONG nRefreshDelay;
+ USHORT nCount;
+ SCTAB* pTabs;
+ BYTE* pModes;
+ String* pTabNames;
+
+ void DoChange( BOOL bLink ) const;
+};
+
+
+class ScUndoShowHideTab : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoShowHideTab(
+ ScDocShell* pShell,
+ SCTAB nNewTab, BOOL bNewShow );
+ virtual ~ScUndoShowHideTab();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ BOOL bShow;
+
+ void DoChange( BOOL bShow ) const;
+};
+
+// ============================================================================
+
+/** This class implements undo & redo of document protect & unprotect
+ operations. */
+class ScUndoDocProtect : public ScSimpleUndo
+{
+public:
+ ScUndoDocProtect(ScDocShell* pShell, ::std::auto_ptr<ScDocProtection> pProtectSettings);
+ virtual ~ScUndoDocProtect();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ::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 bProtect);
+};
+
+
+class ScUndoPrintRange : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoPrintRange( ScDocShell* pShell, SCTAB nNewTab,
+ ScPrintRangeSaver* pOld, ScPrintRangeSaver* pNew );
+ virtual ~ScUndoPrintRange();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ ScPrintRangeSaver* pOldRanges;
+ ScPrintRangeSaver* pNewRanges;
+
+ void DoChange( BOOL bUndo );
+};
+
+
+class ScUndoScenarioFlags: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoScenarioFlags(
+ ScDocShell* pNewDocShell, SCTAB nT,
+ const String& rON, const String& rNN,
+ const String& rOC, const String& rNC,
+ const Color& rOCol, const Color& rNCol,
+ USHORT nOF, USHORT nNF );
+
+ virtual ~ScUndoScenarioFlags();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ String aOldName;
+ String aNewName;
+ String aOldComment;
+ String aNewComment;
+ Color aOldColor;
+ Color aNewColor;
+ USHORT nOldFlags;
+ USHORT nNewFlags;
+};
+
+
+class ScUndoRenameObject: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRenameObject(
+ ScDocShell* pNewDocShell, const String& rPN,
+ const String& rON, const String& rNN );
+
+ virtual ~ScUndoRenameObject();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ String aPersistName; // to find object (works only for OLE objects)
+ String aOldName;
+ String aNewName;
+
+ SdrObject* GetObject();
+};
+
+
+class ScUndoLayoutRTL : public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoLayoutRTL( ScDocShell* pShell, SCTAB nNewTab, BOOL bNewRTL );
+ virtual ~ScUndoLayoutRTL();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB nTab;
+ BOOL bRTL;
+
+ void DoChange( BOOL bNew );
+};
+
+
+//UNUSED2009-05 class ScUndoSetGrammar : public ScSimpleUndo
+//UNUSED2009-05 {
+//UNUSED2009-05 public:
+//UNUSED2009-05 TYPEINFO();
+//UNUSED2009-05 ScUndoSetGrammar( ScDocShell* pShell,
+//UNUSED2009-05 formula::FormulaGrammar::Grammar eGrammar );
+//UNUSED2009-05 virtual ~ScUndoSetGrammar();
+//UNUSED2009-05
+//UNUSED2009-05 virtual void Undo();
+//UNUSED2009-05 virtual void Redo();
+//UNUSED2009-05 virtual void Repeat(SfxRepeatTarget& rTarget);
+//UNUSED2009-05 virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+//UNUSED2009-05
+//UNUSED2009-05 virtual String GetComment() const;
+//UNUSED2009-05
+//UNUSED2009-05 private:
+//UNUSED2009-05 formula::FormulaGrammar::Grammar meNewGrammar, meOldGrammar;
+//UNUSED2009-05
+//UNUSED2009-05 void DoChange( formula::FormulaGrammar::Grammar eGrammar );
+//UNUSED2009-05 };
+
+#endif
+
diff --git a/sc/source/ui/inc/undoutil.hxx b/sc/source/ui/inc/undoutil.hxx
new file mode 100644
index 000000000000..38302096b1fa
--- /dev/null
+++ b/sc/source/ui/inc/undoutil.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UNDOUTIL_HXX
+#define SC_UNDOUTIL_HXX
+
+#include "address.hxx"
+#include <tools/solar.h>
+
+class ScRange;
+class ScDocShell;
+class ScDBData;
+class ScDocument;
+
+//----------------------------------------------------------------------------
+
+class ScUndoUtil
+{
+public:
+ // Block markieren (unsichtbar, muss repainted werden)
+ static void MarkSimpleBlock( ScDocShell* pDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ );
+ static void MarkSimpleBlock( ScDocShell* pDocShell,
+ const ScAddress& rBlockStart,
+ const ScAddress& rBlockEnd );
+ static void MarkSimpleBlock( ScDocShell* pDocShell,
+ const ScRange& rRange );
+
+ // Bereich +1 painten
+ static void PaintMore( ScDocShell* pDocShell,
+ const ScRange& rRange );
+
+ // DB-Bereich im Dokument suchen ("unbenannt" oder nach Bereich)
+ // legt neu an, wenn nicht gefunden
+ static ScDBData* GetOldDBData( ScDBData* pUndoData, ScDocument* pDoc, SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+};
+
+
+
+#endif
diff --git a/sc/source/ui/inc/validate.hrc b/sc/source/ui/inc/validate.hrc
new file mode 100644
index 000000000000..45e5dda39c2d
--- /dev/null
+++ b/sc/source/ui/inc/validate.hrc
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define TP_VALIDATION_VALUES 696
+#define TP_VALIDATION_INPUTHELP 697
+#define TP_VALIDATION_ERROR 698
+#define TAB_DLG_VALIDATION 699
+
+#define FT_ALLOW 1
+#define LB_ALLOW 2
+#define TSB_ALLOW_BLANKS 3
+#define FT_VALUE 4
+#define LB_VALUE 5
+#define FT_MIN 6
+#define EDT_MIN 7
+#define FT_MAX 8
+#define EDT_MAX 9
+
+#define FL_CONTENT 10
+
+#define TSB_HELP 11
+#define FT_TITLE 12
+#define EDT_TITLE 13
+#define FT_INPUTHELP 14
+#define EDT_INPUTHELP 15
+
+#define TSB_SHOW 21
+#define FT_ACTION 22
+#define FT_ERROR 23
+#define LB_ACTION 24
+#define EDT_ERROR 25
+#define BTN_SEARCH 26
+
+#define CB_SHOWLIST 27
+#define CB_SORTLIST 28
+#define EDT_LIST 29
+#define FT_SOURCEHINT 30
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#define RB_VALIDITY_REF 88
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+/* Position indexes for "Allow" list box.
+ They do not map directly to ScValidationMode and can safely be modified to
+ change the order of the list box entries. */
+#define SC_VALIDDLG_ALLOW_ANY 0
+#define SC_VALIDDLG_ALLOW_WHOLE 1
+#define SC_VALIDDLG_ALLOW_DECIMAL 2
+#define SC_VALIDDLG_ALLOW_DATE 3
+#define SC_VALIDDLG_ALLOW_TIME 4
+#define SC_VALIDDLG_ALLOW_RANGE 5
+#define SC_VALIDDLG_ALLOW_LIST 6
+#define SC_VALIDDLG_ALLOW_TEXTLEN 7
+
+/* Position indexes for "Data" list box.
+ They do not map directly to ScConditionMode and can safely be modified to
+ change the order of the list box entries. */
+#define SC_VALIDDLG_DATA_EQUAL 0
+#define SC_VALIDDLG_DATA_LESS 1
+#define SC_VALIDDLG_DATA_GREATER 2
+#define SC_VALIDDLG_DATA_EQLESS 3
+#define SC_VALIDDLG_DATA_EQGREATER 4
+#define SC_VALIDDLG_DATA_NOTEQUAL 5
+#define SC_VALIDDLG_DATA_BETWEEN 6
+#define SC_VALIDDLG_DATA_NOTBETWEEN 7
+
diff --git a/sc/source/ui/inc/validate.hxx b/sc/source/ui/inc/validate.hxx
new file mode 100644
index 000000000000..f7cb9af23b63
--- /dev/null
+++ b/sc/source/ui/inc/validate.hxx
@@ -0,0 +1,347 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_VALIDATE_HXX
+#define SC_VALIDATE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/svmedit.hxx>
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#include "anyrefdg.hxx"
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+// ============================================================================
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+struct ScRefHandlerCaller{
+ virtual ~ScRefHandlerCaller(){}
+};
+class ScRefHandlerHelper
+{
+protected:
+ ScRefHandlerCaller *m_pHandler;
+ void (ScRefHandlerCaller::*m_pSetReferenceHdl)( const ScRange& , ScDocument* );
+ void (ScRefHandlerCaller::*m_pSetActiveHdl)();
+ void (ScRefHandlerCaller::*m_pRefInputStartPreHdl)( ScRefEdit* pEdit, ScRefButton* pButton );
+ void (ScRefHandlerCaller::*m_pRefInputStartPostHdl)( ScRefEdit* pEdit, ScRefButton* pButton );
+ void (ScRefHandlerCaller::*m_pRefInputDonePreHdl)();
+ void (ScRefHandlerCaller::*m_pRefInputDonePostHdl)();
+
+public:
+ typedef void (ScRefHandlerCaller::*PFUNCSETREFHDLTYPE)( const ScRange& , ScDocument* );
+ typedef void (ScRefHandlerCaller::*PCOMMONHDLTYPE)();
+ typedef void (ScRefHandlerCaller::*PINPUTSTARTDLTYPE)( ScRefEdit* pEdit, ScRefButton* pButton );
+
+ PFUNCSETREFHDLTYPE SetSetRefHdl( PFUNCSETREFHDLTYPE pNewHdl )
+ {
+ PFUNCSETREFHDLTYPE pOldHdl = m_pSetReferenceHdl;
+ m_pSetReferenceHdl = pNewHdl;
+ return pOldHdl;
+ }
+
+ PCOMMONHDLTYPE SetSetActHdl( PCOMMONHDLTYPE pNewHdl )
+ {
+ PCOMMONHDLTYPE pOldHdl = m_pSetActiveHdl;
+ m_pSetActiveHdl = pNewHdl;
+ return pOldHdl;
+ }
+
+ ScRefHandlerCaller *SetHandler( ScRefHandlerCaller *pNewHandler )
+ {
+ ScRefHandlerCaller *pOldHandler = m_pHandler;
+ m_pHandler = pNewHandler;
+ return pOldHandler;
+ }
+ void SetRefInputStartPreHdl( PINPUTSTARTDLTYPE pNewHdl ){ m_pRefInputStartPreHdl = pNewHdl; }
+ void SetRefInputDonePostHdl( void (ScRefHandlerCaller::*pNewHdl)() ){ m_pRefInputDonePostHdl = pNewHdl; }
+ void SetRefInputStartPostHdl( PINPUTSTARTDLTYPE pNewHdl ){ m_pRefInputStartPostHdl = pNewHdl; }
+ void SetRefInputDonePreHdl( void (ScRefHandlerCaller::*pNewHdl)() ){ m_pRefInputDonePreHdl = pNewHdl; }
+
+ ScRefHandlerHelper():m_pHandler(NULL), m_pSetReferenceHdl( NULL ), m_pSetActiveHdl(NULL), m_pRefInputStartPreHdl( NULL ), m_pRefInputStartPostHdl( NULL ), m_pRefInputDonePreHdl( NULL ), m_pRefInputDonePostHdl( NULL ){}
+};
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+/** The "Validity" tab dialog. */
+//<!--Modified by PengYunQuan for Validity Cell Range Picker
+//class ScValidationDlg : public SfxTabDialog
+class ScValidationDlg :public ScRefHdlrImpl<ScValidationDlg, SfxTabDialog, false>, public ScRefHandlerHelper
+//-->Modified by PengYunQuan for Validity Cell Range Picker
+{
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ typedef ScRefHdlrImpl<ScValidationDlg, SfxTabDialog, false> ScValidationDlgBase;
+
+ //Start_Moddify by liliang 03/26/2008 SODC_13677_2
+ DECL_LINK( OkHdl, Button * );
+ //End_Moddify by liliang 03/26/2008 SODC_13677_2
+ bool m_bOwnRefHdlr:1;
+
+ ScTabViewShell *m_pTabVwSh;
+ bool m_bRefInputting:1;
+ bool EnterRefStatus();
+ bool LeaveRefStatus();
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+public:
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //explicit ScValidationDlg( Window* pParent, const SfxItemSet* pArgSet );
+ explicit ScValidationDlg( Window* pParent, const SfxItemSet* pArgSet, ScTabViewShell * pTabViewSh, SfxBindings *pB = NULL );
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ virtual ~ScValidationDlg();
+ inline static ScValidationDlg * Find1AliveObject( Window *pAncestor );
+ bool IsAlive();
+ inline ScTabViewShell * GetTabViewShell();
+
+ bool SetupRefDlg();
+ bool RemoveRefDlg( BOOL bRestoreModal = TRUE );
+
+ virtual void SetModal( BOOL bModal ){ ScValidationDlgBase::SetModalInputMode( bModal ); }
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc )
+ {
+ if ( m_pHandler && m_pSetReferenceHdl )
+ (m_pHandler->*m_pSetReferenceHdl)( rRef, pDoc );
+ }
+
+ virtual void SetActive()
+ {
+ if ( m_pHandler && m_pSetActiveHdl )
+ (m_pHandler->*m_pSetActiveHdl)();
+ }
+
+ void CloseRefDialog()
+ {
+ DBG_ASSERT( false, "should not execute here!!!when the edit kill focus, should remove refhandler.\r\n" );
+
+ if ( IsInExecute() )
+ EndDialog( FALSE );
+ else if ( GetStyle() & WB_CLOSEABLE )
+ Close();
+ }
+
+ bool IsRefInputting(){ return m_bRefInputting; }
+
+ virtual void RefInputStart( ScRefEdit* pEdit, ScRefButton* pButton = NULL )
+ {
+ if( !CanInputStart( pEdit ) )
+ return;
+
+ if ( m_pHandler && m_pRefInputStartPreHdl )
+ (m_pHandler->*m_pRefInputStartPreHdl)( pEdit, pButton );
+ m_bRefInputting = true;
+ ScValidationDlgBase::RefInputStart( pEdit, pButton );
+ if ( m_pHandler && m_pRefInputStartPostHdl )
+ (m_pHandler->*m_pRefInputStartPostHdl)( pEdit, pButton );
+ }
+
+ virtual void RefInputDone( BOOL bForced = FALSE )
+ {
+ if( !CanInputDone( bForced ) )
+ return;
+
+ if ( m_pHandler && m_pRefInputDonePreHdl )
+ (m_pHandler->*m_pRefInputDonePreHdl)();
+
+ ScValidationDlgBase::RefInputDone( bForced );
+ m_bRefInputting = false;
+
+ if ( m_pHandler && m_pRefInputDonePostHdl )
+ (m_pHandler->*m_pRefInputDonePostHdl)();
+ }
+
+ BOOL IsChildFocus();
+
+ enum { SLOTID = SID_VALIDITY_REFERENCE };
+
+ BOOL Close();
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+};
+
+
+// ============================================================================
+
+/** The tab page "Criteria" from the Validation dialog. */
+//<!--Modified by PengYunQuan for Validity Cell Range Picker
+//class ScTPValidationValue : public SfxTabPage
+class ScTPValidationValue : public ScRefHandlerCaller, public SfxTabPage
+//-->Modified by PengYunQuan for Validity Cell Range Picker
+{
+public:
+ explicit ScTPValidationValue( Window* pParent, const SfxItemSet& rArgSet );
+ virtual ~ScTPValidationValue();
+
+ static SfxTabPage* Create( Window* pParent, const SfxItemSet& rArgSet );
+ static USHORT* GetRanges();
+
+ virtual BOOL FillItemSet( SfxItemSet& rArgSet );
+ virtual void Reset( const SfxItemSet& rArgSet );
+
+private:
+ void Init();
+
+ String GetFirstFormula() const;
+ String GetSecondFormula() const;
+
+ void SetFirstFormula( const String& rFmlaStr );
+ void SetSecondFormula( const String& rFmlaStr );
+
+ DECL_LINK( SelectHdl, ListBox* );
+ DECL_LINK( CheckHdl, CheckBox* );
+
+ FixedText maFtAllow;
+ ListBox maLbAllow;
+ CheckBox maCbAllow; /// Allow blank cells.
+ CheckBox maCbShow; /// Show selection list in cell.
+ CheckBox maCbSort; /// Sort selection list in cell.
+ FixedText maFtValue;
+ ListBox maLbValue;
+ FixedText maFtMin;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Edit maEdMin;
+ ScRefEdit maEdMin;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ MultiLineEdit maEdList; /// Entries for explicit list
+ FixedText maFtMax;
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //Edit maEdMax;
+ ScRefEdit maEdMax;
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ FixedText maFtHint; /// Hint text for cell range validity.
+
+ String maStrMin;
+ String maStrMax;
+ String maStrValue;
+ String maStrRange;
+ String maStrList;
+ sal_Unicode mcFmlaSep; /// List separator in formulas.
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ DECL_LINK( EditSetFocusHdl, Edit *);
+ DECL_LINK( KillFocusHdl, Window *);
+ void OnClick( Button *pBtn );
+ ScRefEdit *m_pRefEdit;
+ class ScRefButtonEx:public ::ScRefButton
+ {
+ void Click();
+ public:
+ ScRefButtonEx( Window* pParent, const ResId& rResId, ScRefEdit* pEdit = NULL, ScRefHandler *pRefHdlr = NULL ): ::ScRefButton( pParent, rResId, pEdit, pRefHdlr ){}
+ }m_btnRef;
+ friend class ScRefButtonEx;
+ void SetReferenceHdl( const ScRange& , ScDocument* );
+ void SetActiveHdl();
+ void RefInputStartPreHdl( ScRefEdit* pEdit, ScRefButton* pButton );
+ void RefInputDonePreHdl();
+ void RefInputDonePostHdl();
+ ScValidationDlg * GetValidationDlg();
+
+ //TYPEINFO();
+ void TidyListBoxes();
+public:
+ USHORT GetAllowEntryPos();
+ String GetMinText();
+ void SetupRefDlg();
+ void RemoveRefDlg();
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+};
+
+
+//==================================================================
+
+class ScTPValidationHelp : public SfxTabPage
+{
+private:
+ TriStateBox aTsbHelp;
+ FixedLine aFlContent;
+ FixedText aFtTitle;
+ Edit aEdtTitle;
+ FixedText aFtInputHelp;
+ MultiLineEdit aEdInputHelp;
+
+ const SfxItemSet& mrArgSet;
+
+ void Init();
+
+ // Handler ------------------------
+ // DECL_LINK( SelectHdl, ListBox * );
+
+public:
+ ScTPValidationHelp( Window* pParent, const SfxItemSet& rArgSet );
+ ~ScTPValidationHelp();
+
+ static SfxTabPage* Create ( Window* pParent, const SfxItemSet& rArgSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+};
+
+//==================================================================
+
+class ScTPValidationError : public SfxTabPage
+{
+private:
+ TriStateBox aTsbShow;
+ FixedLine aFlContent;
+ FixedText aFtAction;
+ ListBox aLbAction;
+ PushButton aBtnSearch;
+ FixedText aFtTitle;
+ Edit aEdtTitle;
+ FixedText aFtError;
+ MultiLineEdit aEdError;
+
+ const SfxItemSet& mrArgSet;
+
+ void Init();
+
+ // Handler ------------------------
+ DECL_LINK( SelectActionHdl, ListBox * );
+ DECL_LINK( ClickSearchHdl, PushButton * );
+
+public:
+ ScTPValidationError( Window* pParent, const SfxItemSet& rArgSet );
+ ~ScTPValidationError();
+
+ static SfxTabPage* Create ( Window* pParent, const SfxItemSet& rArgSet );
+ static USHORT* GetRanges ();
+ virtual BOOL FillItemSet ( SfxItemSet& rArgSet );
+ virtual void Reset ( const SfxItemSet& rArgSet );
+};
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+inline ScTabViewShell *ScValidationDlg::GetTabViewShell()
+{
+ return m_pTabVwSh;
+}
+
+inline ScValidationDlg * ScValidationDlg::Find1AliveObject( Window *pAncestor )
+{
+ return static_cast<ScValidationDlg *>( SC_MOD()->Find1RefWindow( SLOTID, pAncestor ) );
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
+#endif // SC_VALIDATE_HXX
+
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
new file mode 100644
index 000000000000..fb9c674a4488
--- /dev/null
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -0,0 +1,557 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_VIEWDATA_HXX
+#define SC_VIEWDATA_HXX
+
+#include <svx/zoomitem.hxx>
+#include "scdllapi.h"
+#include "viewopti.hxx"
+#include "markdata.hxx"
+
+
+// ---------------------------------------------------------------------------
+
+#define SC_SLIDER_SIZE 2
+#define SC_SMALL3DSHADOW COL_BLACK
+#define SC_SIZE_NONE 65535
+const SCCOL SC_TABSTART_NONE = SCCOL_MAX;
+
+#define SC_FILL_NONE 0
+#define SC_FILL_FILL 1
+#define SC_FILL_EMBED_LT 2
+#define SC_FILL_EMBED_RB 3
+#define SC_FILL_MATRIX 4
+
+enum ScSplitMode { SC_SPLIT_NONE = 0, SC_SPLIT_NORMAL, SC_SPLIT_FIX };
+
+enum ScSplitPos { SC_SPLIT_TOPLEFT, SC_SPLIT_TOPRIGHT, SC_SPLIT_BOTTOMLEFT, SC_SPLIT_BOTTOMRIGHT };
+enum ScHSplitPos { SC_SPLIT_LEFT, SC_SPLIT_RIGHT };
+enum ScVSplitPos { SC_SPLIT_TOP, SC_SPLIT_BOTTOM };
+
+inline ScHSplitPos WhichH( ScSplitPos ePos );
+inline ScVSplitPos WhichV( ScSplitPos ePos );
+inline ScSplitPos Which( ScHSplitPos eHPos );
+inline ScSplitPos Which( ScVSplitPos eVPos );
+
+// Bildschirmverhalten bei Cursorbewegungen:
+enum ScFollowMode { SC_FOLLOW_NONE, SC_FOLLOW_LINE, SC_FOLLOW_FIX, SC_FOLLOW_JUMP };
+
+// Mausmodi um Bereiche zu selektieren
+enum ScRefType { SC_REFTYPE_NONE, SC_REFTYPE_REF, SC_REFTYPE_FILL,
+ SC_REFTYPE_EMBED_LT, SC_REFTYPE_EMBED_RB };
+
+/** States GetSimpleArea() returns for the underlying selection marks, so the
+ caller can react if the result is not of type SC_MARK_SIMPLE. */
+enum ScMarkType
+{
+ SC_MARK_NONE = 0, // Not returned by GetSimpleArea(), used internally.
+ // Nothing marked always results in the
+ // current cursor position being selected and a simple mark.
+ SC_MARK_SIMPLE = 1, // Simple rectangular area marked, no filtered rows.
+ SC_MARK_FILTERED = 2, // At least one mark contains filtered rows.
+ SC_MARK_SIMPLE_FILTERED = // Simple rectangular area marked containing filtered rows.
+ SC_MARK_SIMPLE |
+ SC_MARK_FILTERED, // 3
+ SC_MARK_MULTI = 4 // Multiple selection marks.
+ /* TODO: if filtered multi-selection was implemented, this would be the value to use. */
+#if 0
+ ,
+ SC_MARK_MULTI_FILTERED = // Multiple selection marks containing filtered rows.
+ SC_MARK_MULTI |
+ SC_MARK_FILTERED // 6
+#endif
+};
+
+class ScDocShell;
+class ScDocument;
+class ScDBFunc;
+class ScTabViewShell;
+class ScDrawView;
+class ScEditEngineDefaulter;
+class EditView;
+class EditStatus;
+class Outliner;
+class Window;
+class SfxObjectShell;
+class SfxBindings;
+class SfxDispatcher;
+class ScPatternAttr;
+class ScRangeListRef;
+class ScExtDocOptions;
+class ScViewData;
+
+//--------------------------------------------------------------------------
+
+class ScViewDataTable // Daten pro Tabelle
+{
+friend class ScViewData;
+private:
+ SvxZoomType eZoomType; // selected zoom type (normal view)
+ Fraction aZoomX; // selected zoom X
+ Fraction aZoomY; // selected zoom Y (displayed)
+ Fraction aPageZoomX; // zoom in page break preview mode
+ Fraction aPageZoomY;
+
+ long nTPosX[2]; // MapMode - Offset (Twips)
+ long nTPosY[2];
+ long nMPosX[2]; // MapMode - Offset (1/100 mm)
+ long nMPosY[2];
+ long nPixPosX[2]; // Offset in Pixeln
+ long nPixPosY[2];
+ long nHSplitPos;
+ long nVSplitPos;
+
+ ScSplitMode eHSplitMode;
+ ScSplitMode eVSplitMode;
+ ScSplitPos eWhichActive;
+
+ SCCOL nFixPosX; // Zellposition des Splitters beim Fixieren
+ SCROW nFixPosY;
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ SCCOL nOldCurX;
+ SCROW nOldCurY;
+ SCCOL nPosX[2];
+ SCROW nPosY[2];
+
+ BOOL bOldCurValid; // "virtuelle" Cursorpos. bei zusammengefassten
+
+ ScViewDataTable();
+ ~ScViewDataTable();
+
+ void WriteUserDataSequence(
+ com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& rSettings,
+ const ScViewData& rViewData, SCTAB nTab );
+
+ void ReadUserDataSequence(
+ const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& rSettings,
+ ScViewData& rViewData, SCTAB nTab, bool& rHasZoom);
+};
+
+// ---------------------------------------------------------------------------
+
+class SC_DLLPUBLIC ScViewData
+{
+private:
+ double nPPTX, nPPTY; // Scaling-Faktoren
+
+ ScViewDataTable* pTabData[MAXTABCOUNT];
+ ScViewDataTable* pThisTab; // Daten der angezeigten Tabelle
+ ScDocShell* pDocShell;
+ ScDocument* pDoc;
+ ScDBFunc* pView;
+ ScTabViewShell* pViewShell;
+ EditView* pEditView[4]; // gehoert dem Fenster
+ ScViewOptions* pOptions;
+ EditView* pSpellingView;
+
+ ScMarkData aMarkData;
+
+ long nEditMargin;
+
+ Size aScenButSize; // Groesse eines Szenario-Buttons
+
+ Size aScrSize;
+ MapMode aLogicMode; // skalierter 1/100mm-MapMode
+
+ SvxZoomType eDefZoomType; // default zoom and type for missing TabData
+ Fraction aDefZoomX;
+ Fraction aDefZoomY;
+ Fraction aDefPageZoomX; // zoom in page break preview mode
+ Fraction aDefPageZoomY;
+
+ ScRefType eRefType;
+
+ SCTAB nTabNo; // angezeigte Tabelle
+ SCTAB nRefTabNo; // Tabelle auf die sich RefInput bezieht
+ SCCOL nRefStartX;
+ SCROW nRefStartY;
+ SCTAB nRefStartZ;
+ SCCOL nRefEndX;
+ SCROW nRefEndY;
+ SCTAB nRefEndZ;
+ SCCOL nFillStartX; // Fill-Cursor
+ SCROW nFillStartY;
+ SCCOL nFillEndX;
+ SCROW nFillEndY;
+ SCCOL nEditCol; // Position dazu
+ SCROW nEditRow;
+ SCCOL nEditStartCol;
+ SCCOL nEditEndCol; // Ende der Edit-View
+ SCROW nEditEndRow;
+ SCCOL nTabStartCol; // fuer Enter nach Tab
+ ScRange aDelRange; // fuer AutoFill-Loeschen
+
+ ScSplitPos eEditActivePart; // the part that was active when edit mode was started
+ BOOL bEditActive[4]; // aktiv?
+ BOOL bActive; // aktives Fenster ?
+ BOOL bIsRefMode; // Referenzeingabe
+ BOOL bDelMarkValid; // nur gueltig bei SC_REFTYPE_FILL
+ BYTE nFillMode; // Modus
+ BOOL bPagebreak; // Seitenumbruch-Vorschaumodus
+
+ BOOL bSelCtrlMouseClick; // special selection handling for ctrl-mouse-click
+
+ SC_DLLPRIVATE DECL_LINK (EmptyEditHdl, EditStatus*);
+ SC_DLLPRIVATE DECL_LINK (EditEngineHdl, EditStatus*);
+
+ SC_DLLPRIVATE void CalcPPT();
+ SC_DLLPRIVATE void CreateTabData( SCTAB nNewTab );
+ SC_DLLPRIVATE void CreateTabData( std::vector< SCTAB >& rvTabs );
+ SC_DLLPRIVATE void CreateSelectedTabData();
+
+public:
+ ScViewData( ScDocShell* pDocSh, ScTabViewShell* pViewSh );
+ ScViewData( const ScViewData& rViewData );
+ ~ScViewData();
+
+ void InitData( ScDocument* pDocument );
+//UNUSED2008-05 void InitFrom( const ScViewData* pRef );
+//UNUSED2008-05 void SetDocShell( ScDocShell* pShell );
+
+
+ ScDocShell* GetDocShell() const { return pDocShell; }
+ ScDBFunc* GetView() const { return pView; }
+ ScTabViewShell* GetViewShell() const { return pViewShell; }
+
+ SfxObjectShell* GetSfxDocShell() const;
+ SfxBindings& GetBindings(); // from ViewShell's ViewFrame
+ SfxDispatcher& GetDispatcher(); // from ViewShell's ViewFrame
+
+ ScMarkData& GetMarkData() { return aMarkData; }
+ const ScMarkData& GetMarkData() const { return aMarkData; }
+
+ Window* GetDialogParent(); // von tabvwsh weitergeleitet
+ Window* GetActiveWin(); // von View
+ ScDrawView* GetScDrawView(); // von View
+ BOOL IsMinimized(); // von View
+
+ void UpdateInputHandler( BOOL bForce = FALSE, BOOL bStopEditing = TRUE );
+
+ void WriteUserData(String& rData);
+ void ReadUserData(const String& rData);
+ void WriteExtOptions( ScExtDocOptions& rOpt ) const;
+ void ReadExtOptions( const ScExtDocOptions& rOpt );
+ void WriteUserDataSequence(com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& rSettings);
+ void ReadUserDataSequence(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& rSettings);
+
+ ScDocument* GetDocument() const;
+
+ void SetViewShell( ScTabViewShell* pViewSh );
+
+ BOOL IsActive() const { return bActive; }
+ void Activate(BOOL bActivate) { bActive = bActivate; }
+
+ void UpdateThis();
+
+ void InsertTab( SCTAB nTab );
+ void DeleteTab( SCTAB nTab );
+ void CopyTab( SCTAB nSrcTab, SCTAB nDestTab );
+ void MoveTab( SCTAB nSrcTab, SCTAB nDestTab );
+
+ SCTAB GetRefTabNo() const { return nRefTabNo; }
+ void SetRefTabNo( SCTAB nNewTab ) { nRefTabNo = nNewTab; }
+
+ SCTAB GetTabNo() const { return nTabNo; }
+ ScSplitPos GetActivePart() const { return pThisTab->eWhichActive; }
+ SCCOL GetPosX( ScHSplitPos eWhich ) const { return pThisTab->nPosX[eWhich]; }
+ SCROW GetPosY( ScVSplitPos eWhich ) const { return pThisTab->nPosY[eWhich]; }
+ SCCOL GetCurX() const { return pThisTab->nCurX; }
+ SCROW GetCurY() const { return pThisTab->nCurY; }
+ BOOL HasOldCursor() const { return pThisTab->bOldCurValid; }
+ SCCOL GetOldCurX() const;
+ SCROW GetOldCurY() const;
+ ScSplitMode GetHSplitMode() const { return pThisTab->eHSplitMode; }
+ ScSplitMode GetVSplitMode() const { return pThisTab->eVSplitMode; }
+ long GetHSplitPos() const { return pThisTab->nHSplitPos; }
+ long GetVSplitPos() const { return pThisTab->nVSplitPos; }
+ SCCOL GetFixPosX() const { return pThisTab->nFixPosX; }
+ SCROW GetFixPosY() const { return pThisTab->nFixPosY; }
+ BOOL IsPagebreakMode() const { return bPagebreak; }
+
+ void SetPosX( ScHSplitPos eWhich, SCCOL nNewPosX );
+ void SetPosY( ScVSplitPos eWhich, SCROW nNewPosY );
+ void SetCurX( SCCOL nNewCurX ) { pThisTab->nCurX = nNewCurX; }
+ void SetCurY( SCROW nNewCurY ) { pThisTab->nCurY = nNewCurY; }
+ void SetOldCursor( SCCOL nNewX, SCROW nNewY );
+ void ResetOldCursor();
+ void SetHSplitMode( ScSplitMode eMode ) { pThisTab->eHSplitMode = eMode; }
+ void SetVSplitMode( ScSplitMode eMode ) { pThisTab->eVSplitMode = eMode; }
+ void SetHSplitPos( long nPos ) { pThisTab->nHSplitPos = nPos; }
+ void SetVSplitPos( long nPos ) { pThisTab->nVSplitPos = nPos; }
+ void SetFixPosX( SCCOL nPos ) { pThisTab->nFixPosX = nPos; }
+ void SetFixPosY( SCROW nPos ) { pThisTab->nFixPosY = nPos; }
+ void SetPagebreakMode( BOOL bSet );
+
+ void SetZoomType( SvxZoomType eNew, BOOL bAll );
+ void SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs );
+ void SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs );
+ void SetZoom( const Fraction& rNewX, const Fraction& rNewY, BOOL bAll );
+ void RefreshZoom();
+
+ void SetSelCtrlMouseClick( BOOL bTmp ) { bSelCtrlMouseClick = bTmp; }
+
+ SvxZoomType GetZoomType() const { return pThisTab->eZoomType; }
+ const Fraction& GetZoomX() const { return bPagebreak ? pThisTab->aPageZoomX : pThisTab->aZoomX; }
+ const Fraction& GetZoomY() const { return bPagebreak ? pThisTab->aPageZoomY : pThisTab->aZoomY; }
+
+ const MapMode& GetLogicMode( ScSplitPos eWhich );
+ const MapMode& GetLogicMode(); // Offset 0
+
+ long GetTPosX( ScHSplitPos eWhich ) const { return pThisTab->nTPosX[eWhich]; }
+ long GetTPosY( ScVSplitPos eWhich ) const { return pThisTab->nTPosY[eWhich]; }
+
+ double GetPPTX() const { return nPPTX; }
+ double GetPPTY() const { return nPPTY; }
+
+ ScMarkType GetSimpleArea( SCCOL& rStartCol, SCROW& rStartRow, SCTAB& rStartTab,
+ SCCOL& rEndCol, SCROW& rEndRow, SCTAB& rEndTab ) const;
+ ScMarkType GetSimpleArea( ScRange& rRange ) const;
+ /// May modify rNewMark using MarkToSimple().
+ ScMarkType GetSimpleArea( ScRange & rRange, ScMarkData & rNewMark ) const;
+ void GetMultiArea( ScRangeListRef& rRange ) const;
+
+ BOOL SimpleColMarked();
+ BOOL SimpleRowMarked();
+
+ BOOL IsMultiMarked();
+
+ void SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
+ void SetDragMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ BYTE nMode );
+ void GetFillData( SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow );
+ void ResetFillMode();
+ BOOL IsAnyFillMode() { return nFillMode != SC_FILL_NONE; }
+ BOOL IsFillMode() { return nFillMode == SC_FILL_FILL; }
+ BYTE GetFillMode() { return nFillMode; }
+
+ // TRUE: Zelle ist zusammengefasst
+ BOOL GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix );
+ BOOL GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
+ SCsCOL& rPosX, SCsROW& rPosY,
+ BOOL bTestMerge = TRUE, BOOL bRepair = FALSE,
+ BOOL bNextIfLarge = TRUE );
+ void GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
+ SCsCOL nPosX, SCsROW nPosY, BOOL& rLeft, BOOL& rTop );
+
+ BOOL IsRefMode() const { return bIsRefMode; }
+ ScRefType GetRefType() const { return eRefType; }
+ SCCOL GetRefStartX() const { return nRefStartX; }
+ SCROW GetRefStartY() const { return nRefStartY; }
+ SCTAB GetRefStartZ() const { return nRefStartZ; }
+ SCCOL GetRefEndX() const { return nRefEndX; }
+ SCROW GetRefEndY() const { return nRefEndY; }
+ SCTAB GetRefEndZ() const { return nRefEndZ; }
+
+ void SetRefMode( BOOL bNewMode, ScRefType eNewType )
+ { bIsRefMode = bNewMode; eRefType = eNewType; }
+
+ void SetRefStart( SCCOL nNewX, SCROW nNewY, SCTAB nNewZ )
+ { nRefStartX = nNewX; nRefStartY = nNewY; nRefStartZ = nNewZ; }
+ void SetRefEnd( SCCOL nNewX, SCROW nNewY, SCTAB nNewZ )
+ { nRefEndX = nNewX; nRefEndY = nNewY; nRefEndZ = nNewZ; }
+
+ void ResetDelMark() { bDelMarkValid = FALSE; }
+ void SetDelMark( const ScRange& rRange )
+ { aDelRange = rRange; bDelMarkValid = TRUE; }
+
+ BOOL GetDelMark( ScRange& rRange ) const
+ { rRange = aDelRange; return bDelMarkValid; }
+
+ inline void GetMoveCursor( SCCOL& rCurX, SCROW& rCurY );
+
+ const ScViewOptions& GetOptions() const { return *pOptions; }
+ void SetOptions( const ScViewOptions& rOpt );
+
+ BOOL IsGridMode () const { return pOptions->GetOption( VOPT_GRID ); }
+ void SetGridMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_GRID, bNewMode ); }
+ BOOL IsSyntaxMode () const { return pOptions->GetOption( VOPT_SYNTAX ); }
+ void SetSyntaxMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_SYNTAX, bNewMode ); }
+ BOOL IsHeaderMode () const { return pOptions->GetOption( VOPT_HEADER ); }
+ void SetHeaderMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_HEADER, bNewMode ); }
+ BOOL IsTabMode () const { return pOptions->GetOption( VOPT_TABCONTROLS ); }
+ void SetTabMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_TABCONTROLS, bNewMode ); }
+ BOOL IsVScrollMode () const { return pOptions->GetOption( VOPT_VSCROLL ); }
+ void SetVScrollMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_VSCROLL, bNewMode ); }
+ BOOL IsHScrollMode () const { return pOptions->GetOption( VOPT_HSCROLL ); }
+ void SetHScrollMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_HSCROLL, bNewMode ); }
+ BOOL IsOutlineMode () const { return pOptions->GetOption( VOPT_OUTLINER ); }
+ void SetOutlineMode ( BOOL bNewMode ) { pOptions->SetOption( VOPT_OUTLINER, bNewMode ); }
+
+ void KillEditView();
+ void ResetEditView();
+ void SetEditEngine( ScSplitPos eWhich,
+ ScEditEngineDefaulter* pNewEngine,
+ Window* pWin, SCCOL nNewX, SCROW nNewY );
+ void GetEditView( ScSplitPos eWhich, EditView*& rViewPtr, SCCOL& rCol, SCROW& rRow );
+ BOOL HasEditView( ScSplitPos eWhich ) const
+ { return pEditView[eWhich] && bEditActive[eWhich]; }
+ EditView* GetEditView( ScSplitPos eWhich ) const
+ { return pEditView[eWhich]; }
+
+ void EditGrowX();
+ void EditGrowY( BOOL bInitial = FALSE );
+
+ ScSplitPos GetEditActivePart() const { return eEditActivePart; }
+ SCCOL GetEditViewCol() const { return nEditCol; }
+ SCROW GetEditViewRow() const { return nEditRow; }
+ SCCOL GetEditStartCol() const { return nEditStartCol; }
+ SCROW GetEditStartRow() const { return nEditRow; } // never editing above the cell
+ SCCOL GetEditEndCol() const { return nEditEndCol; }
+ SCROW GetEditEndRow() const { return nEditEndRow; }
+
+ Rectangle GetEditArea( ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY, Window* pWin,
+ const ScPatternAttr* pPattern, BOOL bForceToTop );
+
+ void SetTabNo( SCTAB nNewTab );
+ void SetActivePart( ScSplitPos eNewActive );
+
+ Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
+ BOOL bAllowNeg = FALSE ) const;
+ Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const;
+ Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const;
+
+ SCCOL CellsAtX( SCsCOL nPosX, SCsCOL nDir, ScHSplitPos eWhichX, USHORT nScrSizeY = SC_SIZE_NONE ) const;
+ SCROW CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHORT nScrSizeX = SC_SIZE_NONE ) const;
+
+ SCCOL VisibleCellsX( ScHSplitPos eWhichX ) const; // angezeigte komplette Zellen
+ SCROW VisibleCellsY( ScVSplitPos eWhichY ) const;
+ SCCOL PrevCellsX( ScHSplitPos eWhichX ) const; // Zellen auf der vorgehenden Seite
+ SCROW PrevCellsY( ScVSplitPos eWhichY ) const;
+//UNUSED2008-05 SCCOL LastCellsX( ScHSplitPos eWhichX ) const; // Zellen auf der letzten Seite
+//UNUSED2008-05 SCROW LastCellsY( ScVSplitPos eWhichY ) const;
+
+ BOOL IsOle();
+//UNUSED2008-05 void UpdateOle( ScSplitPos eWhich );
+ void SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+ void SetScreen( const Rectangle& rVisArea );
+ void SetScreenPos( const Point& rVisAreaStart );
+
+ void UpdateScreenZoom( const Fraction& rNewX, const Fraction& rNewY );
+
+ Size GetScrSize() const { return aScrSize; }
+
+ void RecalcPixPos();
+ Point GetPixPos( ScSplitPos eWhich ) const
+ { return Point( pThisTab->nPixPosX[WhichH(eWhich)],
+ pThisTab->nPixPosY[WhichV(eWhich)] ); }
+ void SetSpellingView( EditView* pSpView) { pSpellingView = pSpView; }
+ EditView* GetSpellingView() const { return pSpellingView; }
+
+ void UpdateOutlinerFlags( Outliner& rOutl ) const;
+
+ Point GetMousePosPixel();
+
+ BOOL UpdateFixX(SCTAB nTab = MAXTAB+1);
+ BOOL UpdateFixY(SCTAB nTab = MAXTAB+1);
+
+ SCCOL GetTabStartCol() const { return nTabStartCol; }
+ void SetTabStartCol(SCCOL nNew) { nTabStartCol = nNew; }
+
+ ScAddress GetCurPos() const;
+
+ const Size& GetScenButSize() const { return aScenButSize; }
+ void SetScenButSize(const Size& rNew) { aScenButSize = rNew; }
+
+ BOOL IsSelCtrlMouseClick() { return bSelCtrlMouseClick; }
+
+ static inline long ToPixel( USHORT nTwips, double nFactor );
+
+ /** while (rScrY <= nEndPixels && rPosY <= nEndRow) add pixels of row
+ heights converted with nPPTY to rScrY, optimized for row height
+ segments. Upon return rPosY is the last row evaluated <= nEndRow, rScrY
+ may be > nEndPixels!
+ */
+ static void AddPixelsWhile( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nEndRow, double nPPTY,
+ const ScDocument * pDoc, SCTAB nTabNo );
+
+ /** while (rScrY <= nEndPixels && rPosY >= nStartRow) add pixels of row
+ heights converted with nPPTY to rScrY, optimized for row height
+ segments. Upon return rPosY is the last row evaluated >= nStartRow,
+ rScrY may be > nEndPixels!
+ */
+ static void AddPixelsWhileBackward( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nStartRow, double nPPTY,
+ const ScDocument * pDoc, SCTAB nTabNo );
+};
+
+
+// ---------------------------------------------------------------------------
+
+inline long ScViewData::ToPixel( USHORT nTwips, double nFactor )
+{
+ long nRet = (long)( nTwips * nFactor );
+ if ( !nRet && nTwips )
+ nRet = 1;
+ return nRet;
+}
+
+inline void ScViewData::GetMoveCursor( SCCOL& rCurX, SCROW& rCurY )
+{
+ if ( bIsRefMode )
+ {
+ rCurX = nRefEndX;
+ rCurY = nRefEndY;
+ }
+ else
+ {
+ rCurX = GetCurX();
+ rCurY = GetCurY();
+ }
+}
+
+inline ScHSplitPos WhichH( ScSplitPos ePos )
+{
+ return (ePos==SC_SPLIT_TOPLEFT || ePos==SC_SPLIT_BOTTOMLEFT) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+}
+
+inline ScVSplitPos WhichV( ScSplitPos ePos )
+{
+ return (ePos==SC_SPLIT_TOPLEFT || ePos==SC_SPLIT_TOPRIGHT) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+}
+
+inline ScSplitPos Which( ScHSplitPos eHPos )
+{
+ return (eHPos==SC_SPLIT_LEFT) ?
+ SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+}
+
+inline ScSplitPos Which( ScVSplitPos eVPos )
+{
+ return (eVPos==SC_SPLIT_TOP) ?
+ SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+}
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
new file mode 100644
index 000000000000..59da2966cc60
--- /dev/null
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_VIEWFUNC_HXX
+#define SC_VIEWFUNC_HXX
+
+#include "tabview.hxx"
+
+#include "tabbgcolor.hxx"
+
+#ifndef _SVSTDARR_SHORTS
+#define _SVSTDARR_SHORTS
+#include <svl/svstdarr.hxx>
+
+#endif
+
+#ifndef _SVSTDARR_STRINGS
+
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+
+#endif
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+
+class ScPatternAttr;
+class ScAutoFormatData;
+class SvxSearchItem;
+class SfxItemSet;
+class SvxBorderLine;
+class SvxBoxItem;
+class SvxBoxInfoItem;
+class SfxStyleSheet;
+class SfxPoolItem;
+class EditTextObject;
+struct ScSolveParam;
+struct ScTabOpParam;
+class ScPostIt;
+class ScConditionalFormat;
+class ScValidationData;
+class ScConversionParam;
+class SdrModel;
+class Graphic;
+class Exchange;
+class ScRangeList;
+class SvxHyperlinkItem;
+class ScTransferObj;
+class ScTableProtection;
+
+namespace com { namespace sun { namespace star { namespace datatransfer { class XTransferable; } } } }
+
+//==================================================================
+
+class ScViewFunc : public ScTabView
+{
+private:
+ ScAddress aFormatSource; // fuer automatisches Erweitern von Formatierung
+ ScRange aFormatArea;
+ BOOL bFormatValid;
+
+public:
+ ScViewFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
+//UNUSED2008-05 ScViewFunc( Window* pParent, const ScViewFunc& rViewFunc, ScTabViewShell* pViewShell );
+ ~ScViewFunc();
+
+ const ScPatternAttr* GetSelectionPattern ();
+ void GetSelectionFrame ( SvxBoxItem& rLineOuter,
+ SvxBoxInfoItem& rLineInner );
+
+ BYTE GetSelectionScriptType();
+
+ BOOL GetAutoSumArea(ScRangeList& rRangeList);
+ void EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal);
+ bool AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue );
+ String GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal );
+
+ void EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
+ BOOL bRecord = TRUE, const EditTextObject* pData = NULL );
+ void EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue );
+ void EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextObject* pData,
+ BOOL bRecord = TRUE, BOOL bTestSimple = FALSE );
+
+ void EnterMatrix( const String& rString );
+ void EnterBlock( const String& rString, const EditTextObject* pData );
+
+ void EnterDataAtCursor( const String& rString ); //! nicht benutzt ?
+
+ SC_DLLPUBLIC void CutToClip( ScDocument* pClipDoc = NULL, BOOL bIncludeObjects = FALSE );
+ SC_DLLPUBLIC BOOL CopyToClip( ScDocument* pClipDoc = NULL, BOOL bCut = FALSE, BOOL bApi = FALSE,
+ BOOL bIncludeObjects = FALSE, BOOL bStopEdit = TRUE );
+ ScTransferObj* CopyToTransferable();
+ SC_DLLPUBLIC BOOL PasteFromClip( USHORT nFlags, ScDocument* pClipDoc,
+ USHORT nFunction = PASTE_NOFUNC, BOOL bSkipEmpty = FALSE,
+ BOOL bTranspose = FALSE, BOOL bAsLink = FALSE,
+ InsCellCmd eMoveMode = INS_NONE,
+ USHORT nUndoExtraFlags = IDF_NONE,
+ BOOL bAllowDialogs = FALSE );
+
+ void FillTab( USHORT nFlags, USHORT nFunction, BOOL bSkipEmpty, BOOL bAsLink );
+
+ SC_DLLPUBLIC void PasteFromSystem();
+ SC_DLLPUBLIC BOOL PasteFromSystem( ULONG nFormatId, BOOL bApi = FALSE );
+ void PasteFromTransferable( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable );
+
+ void PasteDraw();
+ void PasteDraw( const Point& rLogicPos, SdrModel* pModel,
+ BOOL bGroup = FALSE, BOOL bSameDocClipboard = FALSE );
+
+ BOOL PasteOnDrawObject( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
+ SdrObject* pHitObj, BOOL bLink );
+
+ BOOL PasteDataFormat( ULONG nFormatId,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
+ SCCOL nPosX, SCROW nPosY, Point* pLogicPos = NULL,
+ BOOL bLink = FALSE, BOOL bAllowDialogs = FALSE );
+
+ BOOL PasteFile( const Point&, const String&, BOOL bLink=FALSE );
+ BOOL PasteObject( const Point&, const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >&, const Size* = NULL, const Graphic* = NULL, const ::rtl::OUString& = ::rtl::OUString(), sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT );
+ BOOL PasteBitmap( const Point&, const Bitmap& );
+ BOOL PasteMetaFile( const Point&, const GDIMetaFile& );
+ BOOL PasteGraphic( const Point& rPos, const Graphic& rGraphic,
+ const String& rFile, const String& rFilter );
+ BOOL PasteBookmark( ULONG nFormatId,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
+ SCCOL nPosX, SCROW nPosY );
+ BOOL PasteDDE( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable );
+
+ BOOL ApplyGraphicToObject( SdrObject* pObject, const Graphic& rGraphic );
+
+ void InsertBookmark( const String& rDescription, const String& rURL,
+ SCCOL nPosX, SCROW nPosY, const String* pTarget = NULL,
+ BOOL bTryReplace = FALSE );
+ BOOL HasBookmarkAtCursor( SvxHyperlinkItem* pContent );
+
+ long DropRequestHdl( Exchange* pExchange );
+ BOOL MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
+ BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi );
+
+ BOOL LinkBlock( const ScRange& rSource, const ScAddress& rDestPos, BOOL bApi );
+
+ void CreateNames( USHORT nFlags );
+ USHORT GetCreateNameFlags();
+ void InsertNameList();
+ BOOL InsertName( const String& rName, const String& rSymbol,
+ const String& rType );
+
+ void ApplyAttributes( const SfxItemSet* pDialogSet, const SfxItemSet* pOldSet,
+ BOOL bRecord = TRUE );
+ void ApplyAttr( const SfxPoolItem& rAttrItem );
+ void ApplySelectionPattern( const ScPatternAttr& rAttr,
+ BOOL bRecord = TRUE,
+ BOOL bCursorOnly = FALSE );
+ void ApplyPatternLines( const ScPatternAttr& rAttr,
+ const SvxBoxItem* pNewOuter,
+ const SvxBoxInfoItem* pNewInner, BOOL bRecord = TRUE );
+
+ void ApplyUserItemSet( const SfxItemSet& rItemSet );
+
+ const SfxStyleSheet* GetStyleSheetFromMarked();
+ void SetStyleSheetToMarked( SfxStyleSheet* pStyleSheet,
+ BOOL bRecord = TRUE );
+ void RemoveStyleSheetInUse( SfxStyleSheet* pStyleSheet );
+ void UpdateStyleSheetInUse( SfxStyleSheet* pStyleSheet );
+
+ void SetNumberFormat( short nFormatType, ULONG nAdd = 0 );
+ void SetNumFmtByStr( const String& rCode );
+ void ChangeNumFmtDecimals( BOOL bIncrement );
+
+ void SetConditionalFormat( const ScConditionalFormat& rNew );
+ void SetValidation( const ScValidationData& rNew );
+
+ 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 );
+
+ void DeleteCells( DelCellCmd eCmd, BOOL bRecord = TRUE );
+ BOOL InsertCells( InsCellCmd eCmd, BOOL bRecord = TRUE, BOOL bPartOfPaste = FALSE );
+ void DeleteMulti( BOOL bRows, BOOL bRecord = TRUE );
+
+ void DeleteContents( USHORT nFlags, BOOL bRecord = TRUE );
+
+ void SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
+ ScSizeMode eMode, USHORT nSizeTwips,
+ BOOL bRecord = TRUE, BOOL bPaint = TRUE,
+ ScMarkData* pMarkData = NULL );
+ void SetMarkedWidthOrHeight( BOOL bWidth, ScSizeMode eMode, USHORT nSizeTwips,
+ BOOL bRecord = TRUE, BOOL bPaint = TRUE );
+ void ShowMarkedColumns( BOOL bShow, BOOL bRecord = TRUE );
+ void ShowMarkedRows( BOOL bShow, BOOL bRecord = TRUE );
+
+ BOOL AdjustBlockHeight( BOOL bPaint = TRUE, ScMarkData* pMarkData = NULL );
+ BOOL AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, BOOL bPaint = TRUE );
+
+ void ModifyCellSize( ScDirection eDir, BOOL bOptimal );
+
+ SC_DLLPUBLIC void InsertPageBreak( BOOL bColumn, BOOL bRecord = TRUE,
+ const ScAddress* pPos = NULL,
+ BOOL bSetModified = TRUE );
+ SC_DLLPUBLIC void DeletePageBreak( BOOL bColumn, BOOL bRecord = TRUE,
+ const ScAddress* pPos = NULL,
+ BOOL bSetModified = TRUE );
+
+ void RemoveManualBreaks();
+
+ void SetPrintZoom(USHORT nScale, USHORT nPages);
+ void AdjustPrintZoom();
+
+ BOOL TestMergeCells();
+ BOOL TestRemoveMerge();
+
+ BOOL MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord = TRUE );
+ BOOL RemoveMerge( BOOL bRecord = TRUE );
+
+ void FillSimple( FillDir eDir, BOOL bRecord = TRUE );
+ void FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
+ double fStart, double fStep, double fMax, BOOL bRecord = TRUE );
+ void FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, ULONG nCount, BOOL bRecord = TRUE );
+ void FillCrossDblClick();
+
+ void TransliterateText( sal_Int32 nType );
+
+ ScAutoFormatData* CreateAutoFormatData();
+ void AutoFormat( USHORT nFormatNo, BOOL bRecord = TRUE );
+
+ void SearchAndReplace( const SvxSearchItem* pSearchItem,
+ BOOL bAddUndo, BOOL bIsApi );
+
+ void Solve( const ScSolveParam& rParam );
+ void TabOp( const ScTabOpParam& rParam, BOOL bRecord = TRUE );
+
+ BOOL InsertTable( const String& rName, SCTAB nTabNr, BOOL bRecord = TRUE );
+ BOOL InsertTables(SvStrings *pNames, SCTAB nTab, SCTAB nCount, BOOL bRecord = TRUE);
+
+
+ BOOL AppendTable( const String& rName, BOOL bRecord = TRUE );
+
+ BOOL DeleteTable( SCTAB nTabNr, BOOL bRecord = TRUE );
+ BOOL DeleteTables(const SvShorts &TheTabs, BOOL bRecord = TRUE );
+
+ BOOL RenameTable( const String& rName, SCTAB nTabNr );
+ void MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy );
+ void ImportTables( ScDocShell* pSrcShell,
+ SCTAB nCount, const SCTAB* pSrcTabs,
+ BOOL bLink,SCTAB nTab);
+
+ bool SetTabBgColor( const Color& rColor, SCTAB nTabNr );
+ bool SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList );
+
+ void InsertTableLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rTabName );
+ void InsertAreaLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rSource, ULONG nRefresh );
+
+ void ShowTable( const String& rName );
+ void HideTable( SCTAB nTabNr );
+
+ void MakeScenario( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags );
+ void ExtendScenario();
+ void UseScenario( const String& rName );
+
+ void InsertSpecialChar( const String& rStr, const Font& rFont );
+
+ void InsertDummyObject();
+ void InsertOleObject();
+
+ void InsertDraw();
+
+ void SetSelectionFrameLines( const SvxBorderLine* pLine,
+ BOOL bColorOnly );
+
+ 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 );
+ void DoThesaurus( BOOL bRecord = TRUE );
+//UNUSED2008-05 DECL_LINK( SpellError, void * );
+
+ /** Generic implementation of sheet conversion functions. */
+ void DoSheetConversion( const ScConversionParam& rParam, BOOL bRecord = TRUE );
+
+ void SetPrintRanges( BOOL bEntireSheet,
+ const String* pPrint,
+ const String* pRepCol, const String* pRepRow,
+ BOOL bAddPrint );
+
+ void DetectiveAddPred();
+ void DetectiveDelPred();
+ void DetectiveAddSucc();
+ void DetectiveDelSucc();
+ void DetectiveAddError();
+ void DetectiveMarkInvalid();
+ void DetectiveDelAll();
+ void DetectiveRefresh();
+
+ void ShowNote( bool bShow = true );
+ inline void HideNote() { ShowNote( false ); }
+ void EditNote();
+
+ void ForgetFormatArea() { bFormatValid = FALSE; }
+ BOOL SelectionEditable( BOOL* pOnlyNotBecauseOfMatrix = NULL );
+
+ // interne Hilfsfunktionen
+protected:
+ void UpdateLineAttrs( SvxBorderLine& rLine,
+ const SvxBorderLine* pDestLine,
+ const SvxBorderLine* pSrcLine,
+ BOOL bColor );
+
+//UNUSED2008-05 void PaintWidthHeight( BOOL bColumns, SCCOLROW nStart, SCCOLROW nEnd );
+
+
+private:
+ void PasteRTF( SCCOL nCol, SCROW nStartRow,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable );
+ bool PasteMultiRangesFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
+ bool bSkipEmpty, bool bTranspos, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, sal_uInt16 nCondFlags, sal_uInt16 nUndoFlags );
+ void PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark);
+
+ USHORT GetOptimalColWidth( SCCOL nCol, SCTAB nTab, BOOL bFormula );
+
+ void StartFormatArea();
+ BOOL TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bAttrChanged );
+ void DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ BOOL bAttrChanged, BOOL bAddUndo );
+};
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/viewutil.hxx b/sc/source/ui/inc/viewutil.hxx
new file mode 100644
index 000000000000..eb1c6df2f902
--- /dev/null
+++ b/sc/source/ui/inc/viewutil.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VIEWUTIL_HXX
+#define SC_VIEWUTIL_HXX
+
+#include "address.hxx"
+#include <tools/solar.h>
+#include <sal/types.h>
+
+class String;
+class SfxItemSet;
+class SfxBindings;
+class SvxFontItem;
+class SfxViewShell;
+class SfxViewFrame;
+
+class ScChangeAction;
+class ScChangeViewSettings;
+class ScDocument;
+class ScAddress;
+class ScRange;
+class ScMarkData;
+
+enum ScUpdateMode { SC_UPDATE_ALL, SC_UPDATE_CHANGED, SC_UPDATE_MARKS };
+
+// ---------------------------------------------------------------------------
+
+class ScViewUtil // static Methoden
+{
+public:
+ static BOOL ExecuteCharMap( const SvxFontItem& rOldFont,
+ SfxViewFrame& rFrame,
+ SvxFontItem& rNewFont,
+ String& rString );
+
+ static BOOL IsActionShown( const ScChangeAction& rAction,
+ const ScChangeViewSettings& rSettings,
+ ScDocument& rDocument );
+
+ static void PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet,
+ USHORT nWhichId, USHORT nScript );
+
+ static USHORT GetEffLanguage( ScDocument* pDoc, const ScAddress& rPos );
+
+ static sal_Int32 GetTransliterationType( USHORT nSlotID );
+
+ static bool HasFiltered( const ScRange& rRange, ScDocument* pDoc );
+ /** Fit a range to cover nRows number of unfiltered rows.
+ @return <TRUE/> if the resulting range covers nRows unfiltered rows. */
+ static bool FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows );
+ static void UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc );
+
+ static void HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, USHORT nSlotId );
+
+ /** Returns true, if the passed view shell is in full screen mode. */
+ static bool IsFullScreen( SfxViewShell& rViewShell );
+ /** Enters or leaves full screen mode at the passed view shell. */
+ static void SetFullScreen( SfxViewShell& rViewShell, bool bSet );
+};
+
+// ---------------------------------------------------------------------------
+
+class ScUpdateRect
+{
+private:
+ SCCOL nOldStartX;
+ SCROW nOldStartY;
+ SCCOL nOldEndX;
+ SCROW nOldEndY;
+ SCCOL nNewStartX;
+ SCROW nNewStartY;
+ SCCOL nNewEndX;
+ SCROW nNewEndY;
+ SCCOL nContX1;
+ SCROW nContY1;
+ SCCOL nContX2;
+ SCROW nContY2;
+public:
+ ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 );
+ void SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 );
+ BOOL GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
+#ifdef OLD_SELECTION_PAINT
+ BOOL GetXorDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, BOOL& rCont );
+ void GetContDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
+#endif
+};
+
+
+
+
+#endif
+
diff --git a/sc/source/ui/inc/warnbox.hxx b/sc/source/ui/inc/warnbox.hxx
new file mode 100644
index 000000000000..3b06c98c9e3e
--- /dev/null
+++ b/sc/source/ui/inc/warnbox.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_WARNBOX_HXX
+#define SC_WARNBOX_HXX
+
+#include <vcl/msgbox.hxx>
+
+
+// ============================================================================
+
+/** Message box with warning image and "Do not show again" checkbox. */
+class ScCbWarningBox : public WarningBox
+{
+public:
+ /** @param rMsgStr Resource ID for the message text.
+ @param bDefYes true = "Yes" focused, false = "No" focused. */
+ ScCbWarningBox( Window* pParent, const String& rMsgStr, bool bDefYes = true );
+
+ /** Opens dialog if IsDialogEnabled() returns true.
+ @descr If after executing the dialog the checkbox "Do not show again" is set,
+ the method DisableDialog() will be called. */
+ virtual sal_Int16 Execute();
+
+ /** Called before executing the dialog. If this method returns false, the dialog will not be opened. */
+ virtual bool IsDialogEnabled();
+ /** Called, when dialog is exited and the option "Do not show again" is set. */
+ virtual void DisableDialog();
+};
+
+
+// ----------------------------------------------------------------------------
+
+/** Warning box for "Replace cell contents?". */
+class ScReplaceWarnBox : public ScCbWarningBox
+{
+public:
+ ScReplaceWarnBox( Window* pParent );
+
+ /** Reads the configuration key "ReplaceCellsWarning". */
+ virtual bool IsDialogEnabled();
+ /** Sets the configuration key "ReplaceCellsWarning" to false. */
+ virtual void DisableDialog();
+};
+
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/source/ui/miscdlgs/acredlin.cxx b/sc/source/ui/miscdlgs/acredlin.cxx
new file mode 100644
index 000000000000..6f59b64c52fc
--- /dev/null
+++ b/sc/source/ui/miscdlgs/acredlin.cxx
@@ -0,0 +1,2139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+#include <svl/undo.hxx>
+#include <unotools/textsearch.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "acredlin.hxx"
+#include "global.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "acredlin.hrc"
+#include "simpref.hxx"
+#include "scmod.hxx"
+#include "popmenu.hxx"
+#include "tabvwsh.hxx"
+
+// defines -------------------------------------------------------------------
+
+#define ABS_SREF SCA_VALID \
+ | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
+#define ABS_DREF ABS_SREF \
+ | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
+#define ABS_SREF3D ABS_SREF | SCA_TAB_3D
+#define ABS_DREF3D ABS_DREF | SCA_TAB_3D
+
+
+
+#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute();
+
+inline void EnableDisable( Window& rWin, BOOL bEnable )
+{
+ if (bEnable)
+ rWin.Enable();
+ else
+ rWin.Disable();
+}
+
+#define RD_SPECIAL_NONE 0
+#define RD_SPECIAL_CONTENT 1
+#define RD_SPECIAL_VISCONTENT 2
+
+//============================================================================
+// class ScRedlinData
+//----------------------------------------------------------------------------
+
+ScRedlinData::ScRedlinData()
+ :RedlinData()
+{
+ nInfo=RD_SPECIAL_NONE;
+ nActionNo=0;
+ pData=NULL;
+ bDisabled=FALSE;
+ bIsRejectable=FALSE;
+ bIsAcceptable=FALSE;
+ nTable=SCTAB_MAX;
+ nCol=SCCOL_MAX;
+ nRow=SCROW_MAX;
+}
+
+ScRedlinData::~ScRedlinData()
+{
+ nInfo=RD_SPECIAL_NONE;
+ nActionNo=0;
+ pData=NULL;
+ bDisabled=FALSE;
+ bIsRejectable=FALSE;
+ bIsAcceptable=FALSE;
+}
+
+
+//============================================================================
+// class ScAcceptChgDlg
+//----------------------------------------------------------------------------
+ScAcceptChgDlg::ScAcceptChgDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData)
+
+ : SfxModelessDialog( pB, pCW, pParent, ScResId(RID_SCDLG_CHANGES) ),
+ //
+ aAcceptChgCtr ( this, ScResId( CTR_REDLINING ) ),
+ //
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData->GetDocument() ),
+ aLocalRangeName ( *(pDoc->GetRangeName()) ),
+ //
+ aStrInsertCols ( ScResId( STR_INSERT_COLS)),
+ aStrInsertRows ( ScResId( STR_INSERT_ROWS)),
+ aStrInsertTabs ( ScResId( STR_INSERT_TABS)),
+ aStrDeleteCols ( ScResId( STR_DELETE_COLS)),
+ aStrDeleteRows ( ScResId( STR_DELETE_ROWS)),
+ aStrDeleteTabs ( ScResId( STR_DELETE_TABS)),
+ aStrMove ( ScResId( STR_MOVE )),
+ aStrContent ( ScResId( STR_CONTENT )),
+ aStrReject ( ScResId( STR_REJECT )),
+ aStrAllAccepted ( ScResId( STR_ACCEPTED )),
+ aStrAllRejected ( ScResId( STR_REJECTED )),
+ aStrNoEntry ( ScResId( STR_NO_ENTRY )),
+ aStrContentWithChild ( ScResId( STR_CONTENT_WITH_CHILD)),
+ aStrChildContent ( ScResId( STR_CHILD_CONTENT)),
+ aStrChildOrgContent ( ScResId( STR_CHILD_ORGCONTENT)),
+ aStrEmpty ( ScResId( STR_EMPTY ))
+{
+ FreeResource();
+// bScAcceptChgDlgIsDead=FALSE;
+ bNoSelection=FALSE;
+ bNeedsUpdate=FALSE;
+ bIgnoreMsg=FALSE;
+ nAcceptCount=0;
+ nRejectCount=0;
+ bAcceptEnableFlag=TRUE;
+ bRejectEnableFlag=TRUE;
+ bHasFilterEntry=FALSE;
+ bUseColor=FALSE;
+ aReOpenTimer.SetTimeout(50);
+ aReOpenTimer.SetTimeoutHdl(LINK( this, ScAcceptChgDlg, ReOpenTimerHdl ));
+
+ // dialog is now only hidden, not deleted, on switching views,
+ // so there's no need to restore settings when reopening
+
+ MinSize=aAcceptChgCtr.GetMinSizePixel();
+ MinSize.Height()+=2;
+ MinSize.Width()+=2;
+ SetMinOutputSizePixel(MinSize);
+ aUnknown.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Unknown"));
+
+ pTPFilter=aAcceptChgCtr.GetFilterPage();
+ pTPView=aAcceptChgCtr.GetViewPage();
+ pTheView=pTPView->GetTableControl();
+ aSelectionTimer.SetTimeout(100);
+ aSelectionTimer.SetTimeoutHdl(LINK( this, ScAcceptChgDlg, UpdateSelectionHdl ));
+
+ pTPFilter->SetReadyHdl(LINK( this, ScAcceptChgDlg, FilterHandle ));
+ pTPFilter->SetRefHdl(LINK( this, ScAcceptChgDlg, RefHandle ));
+ pTPFilter->SetModifyHdl(LINK( this, ScAcceptChgDlg, FilterModified));
+ pTPFilter->HideRange(FALSE);
+ pTPView->InsertCalcHeader();
+ pTPView->SetRejectClickHdl( LINK( this, ScAcceptChgDlg,RejectHandle));
+ pTPView->SetAcceptClickHdl( LINK(this, ScAcceptChgDlg, AcceptHandle));
+ pTPView->SetRejectAllClickHdl( LINK( this, ScAcceptChgDlg,RejectAllHandle));
+ pTPView->SetAcceptAllClickHdl( LINK(this, ScAcceptChgDlg, AcceptAllHandle));
+ pTheView->SetCalcView();
+ pTheView->SetWindowBits(WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
+ pTheView->SetExpandingHdl( LINK(this, ScAcceptChgDlg, ExpandingHandle));
+ pTheView->SetSelectHdl( LINK(this, ScAcceptChgDlg, SelectHandle));
+ pTheView->SetDeselectHdl( LINK(this, ScAcceptChgDlg, SelectHandle));
+ pTheView->SetCommandHdl( LINK(this, ScAcceptChgDlg, CommandHdl));
+ pTheView->SetColCompareHdl( LINK(this, ScAcceptChgDlg,ColCompareHdl));
+ pTheView->SetSelectionMode(MULTIPLE_SELECTION);
+ pTheView->SetHighlightRange(1);
+
+ Init();
+
+ aAcceptChgCtr.SetMinSizeHdl( LINK( this, ScAcceptChgDlg, MinSizeHandle ));
+
+ UpdateView();
+ SvLBoxEntry* pEntry=pTheView->First();
+ if(pEntry!=NULL)
+ {
+ pTheView->Select(pEntry);
+ }
+}
+ScAcceptChgDlg::~ScAcceptChgDlg()
+{
+// bScAcceptChgDlgIsDead=TRUE;
+ ClearView();
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pChanges!=NULL)
+ {
+ Link aLink;
+ pChanges->SetModifiedLink(aLink);
+ }
+}
+
+void ScAcceptChgDlg::ReInit(ScViewData* ptrViewData)
+{
+ pViewData=ptrViewData;
+ if(pViewData!=NULL)
+ {
+ pDoc=ptrViewData->GetDocument();
+ }
+ else
+ {
+ pDoc=NULL;
+ }
+
+ bNoSelection=FALSE;
+ bNeedsUpdate=FALSE;
+ bIgnoreMsg=FALSE;
+ nAcceptCount=0;
+ nRejectCount=0;
+ bAcceptEnableFlag=TRUE;
+ bRejectEnableFlag=TRUE;
+
+ // #91781# don't call Init here (switching between views), just set link below
+ // (dialog is just hidden, not deleted anymore, when switching views)
+ ClearView();
+ UpdateView();
+
+ if ( pDoc )
+ {
+ ScChangeTrack* pChanges = pDoc->GetChangeTrack();
+ if ( pChanges )
+ pChanges->SetModifiedLink( LINK( this, ScAcceptChgDlg, ChgTrackModHdl ) );
+ }
+}
+
+void __EXPORT ScAcceptChgDlg::Init()
+{
+ String aAreaStr;
+ ScRange aRange;
+
+ DBG_ASSERT( pViewData && pDoc, "ViewData oder Document nicht gefunden!" );
+
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pChanges!=NULL)
+ {
+ pChanges->SetModifiedLink( LINK( this, ScAcceptChgDlg,ChgTrackModHdl));
+ aChangeViewSet.SetTheAuthorToShow(pChanges->GetUser());
+ pTPFilter->ClearAuthors();
+ ScStrCollection aUserColl=pChanges->GetUserCollection();
+ for(USHORT i=0;i<aUserColl.GetCount();i++)
+ pTPFilter->InsertAuthor(aUserColl[i]->GetString());
+ }
+
+ ScChangeViewSettings* pViewSettings=pDoc->GetChangeViewSettings();
+ if ( pViewSettings!=NULL )
+ aChangeViewSet = *pViewSettings;
+ // adjust TimeField for filter tabpage
+ aChangeViewSet.AdjustDateMode( *pDoc );
+
+ pTPFilter->CheckDate(aChangeViewSet.HasDate());
+ pTPFilter->SetFirstDate(aChangeViewSet.GetTheFirstDateTime());
+ pTPFilter->SetFirstTime(aChangeViewSet.GetTheFirstDateTime());
+ pTPFilter->SetLastDate(aChangeViewSet.GetTheLastDateTime());
+ pTPFilter->SetLastTime(aChangeViewSet.GetTheLastDateTime());
+ pTPFilter->SetDateMode((USHORT)aChangeViewSet.GetTheDateMode());
+ pTPFilter->CheckComment(aChangeViewSet.HasComment());
+ pTPFilter->SetComment(aChangeViewSet.GetTheComment());
+
+ pTPFilter->CheckAuthor(aChangeViewSet.HasAuthor());
+ String aString=aChangeViewSet.GetTheAuthorToShow();
+ if(aString.Len()!=0)
+ {
+ pTPFilter->SelectAuthor(aString);
+ if(pTPFilter->GetSelectedAuthor()!=aString)
+ {
+ pTPFilter->InsertAuthor(aString);
+ pTPFilter->SelectAuthor(aString);
+ }
+ }
+ else
+ {
+ pTPFilter->SelectedAuthorPos(0);
+ }
+
+ pTPFilter->CheckRange(aChangeViewSet.HasRange());
+
+ ScRange* pRangeEntry=aChangeViewSet.GetTheRangeList().GetObject(0);
+ aRangeList=aChangeViewSet.GetTheRangeList();
+
+ if(pRangeEntry!=NULL)
+ {
+ String aRefStr;
+ pRangeEntry->Format( aRefStr, ABS_DREF3D, pDoc );
+ pTPFilter->SetRange(aRefStr);
+ }
+
+ Point aPoint(1,1);
+ aAcceptChgCtr.SetPosPixel(aPoint);
+ InitFilter();
+}
+
+
+
+void ScAcceptChgDlg::ClearView()
+{
+ nAcceptCount=0;
+ nRejectCount=0;
+ pTheView->SetUpdateMode(FALSE);
+
+ pTheView->Clear();
+ pTheView->SetUpdateMode(TRUE);
+}
+
+String* ScAcceptChgDlg::MakeTypeString(ScChangeActionType eType)
+{
+ String* pStr;
+
+ switch(eType)
+ {
+
+ case SC_CAT_INSERT_COLS: pStr=&aStrInsertCols;break;
+
+ case SC_CAT_INSERT_ROWS: pStr=&aStrInsertRows;break;
+
+ case SC_CAT_INSERT_TABS: pStr=&aStrInsertTabs;break;
+
+ case SC_CAT_DELETE_COLS: pStr=&aStrDeleteCols;break;
+
+ case SC_CAT_DELETE_ROWS: pStr=&aStrDeleteRows;break;
+
+ case SC_CAT_DELETE_TABS: pStr=&aStrDeleteTabs;break;
+
+ case SC_CAT_MOVE: pStr=&aStrMove;break;
+
+ case SC_CAT_CONTENT: pStr=&aStrContent;break;
+
+ case SC_CAT_REJECT: pStr=&aStrReject;break;
+
+ default: pStr=&aUnknown;break;
+ }
+ return pStr;
+}
+
+
+BOOL ScAcceptChgDlg::IsValidAction(const ScChangeAction* pScChangeAction)
+{
+ if(pScChangeAction==NULL) return FALSE;
+
+ BOOL bFlag=FALSE;
+
+ ScRange aRef=pScChangeAction->GetBigRange().MakeRange();
+ String aUser=pScChangeAction->GetUser();
+ DateTime aDateTime=pScChangeAction->GetDateTime();
+
+ ScChangeActionType eType=pScChangeAction->GetType();
+ String aString;
+ String aDesc;
+
+ String aComment=pScChangeAction->GetComment();
+ aComment.EraseAllChars('\n');
+
+ if(eType==SC_CAT_CONTENT)
+ {
+ if(!pScChangeAction->IsDialogParent())
+ {
+ pScChangeAction->GetDescription( aDesc, pDoc, TRUE);
+ }
+ }
+ else
+ {
+ pScChangeAction->GetDescription( aDesc, pDoc,!pScChangeAction->IsMasterDelete());
+ }
+
+ if(aDesc.Len()>0)
+ {
+ aComment.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aComment+=aDesc;
+ aComment+=')';
+ }
+
+ if(pTheView->IsValidEntry(&aUser,&aDateTime,&aComment))
+ {
+ if(pTPFilter->IsRange())
+ {
+ ScRange* pRangeEntry=aRangeList.First();
+
+ while(pRangeEntry!=NULL)
+ {
+ if(pRangeEntry->Intersects(aRef)) break;
+ pRangeEntry=aRangeList.Next();
+ }
+
+ if(pRangeEntry!=NULL)
+ {
+ bFlag=TRUE;
+ }
+ }
+ else
+ {
+ bFlag=TRUE;
+ }
+ }
+
+ return bFlag;
+}
+
+SvLBoxEntry* ScAcceptChgDlg::InsertChangeAction(const ScChangeAction* pScChangeAction,
+ ScChangeActionState /* eState */, SvLBoxEntry* pParent,
+ BOOL bDelMaster,BOOL bDisabled,ULONG nPos)
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pScChangeAction==NULL || pChanges==NULL) return NULL;
+
+ SvLBoxEntry* pEntry=NULL;
+
+ BOOL bFlag=FALSE;
+
+ ScRange aRef=pScChangeAction->GetBigRange().MakeRange();
+ String aUser=pScChangeAction->GetUser();
+ DateTime aDateTime=pScChangeAction->GetDateTime();
+
+ String aRefStr;
+ ScChangeActionType eType=pScChangeAction->GetType();
+ String aString;
+ String aDesc;
+
+ ScRedlinData* pNewData=new ScRedlinData;
+ pNewData->pData=(void *)pScChangeAction;
+ pNewData->nActionNo=pScChangeAction->GetActionNumber();
+ pNewData->bIsAcceptable=pScChangeAction->IsClickable();
+ pNewData->bIsRejectable=pScChangeAction->IsRejectable();
+ pNewData->bDisabled=!pNewData->bIsAcceptable | bDisabled;
+ pNewData->aDateTime=aDateTime;
+ pNewData->nRow = aRef.aStart.Row();
+ pNewData->nCol = aRef.aStart.Col();
+ pNewData->nTable= aRef.aStart.Tab();
+
+ if(eType==SC_CAT_CONTENT)
+ {
+ if(pScChangeAction->IsDialogParent())
+ {
+ aString=aStrContentWithChild;
+ pNewData->nInfo=RD_SPECIAL_VISCONTENT;
+ pNewData->bIsRejectable=FALSE;
+ pNewData->bIsAcceptable=FALSE;
+ }
+ else
+ {
+ aString=*MakeTypeString(eType);
+ pScChangeAction->GetDescription( aDesc, pDoc, TRUE);
+ }
+ }
+ else
+ {
+ aString=*MakeTypeString(eType);
+
+ if(bDelMaster)
+ {
+ pScChangeAction->GetDescription( aDesc, pDoc,TRUE);
+ pNewData->bDisabled=TRUE;
+ pNewData->bIsRejectable=FALSE;
+ }
+ else
+ pScChangeAction->GetDescription( aDesc, pDoc,!pScChangeAction->IsMasterDelete());
+
+ }
+
+ aString+='\t';
+ pScChangeAction->GetRefString(aRefStr, pDoc, TRUE);
+ aString+=aRefStr;
+ aString+='\t';
+
+ BOOL bIsGenerated;
+
+ if(!pChanges->IsGenerated(pScChangeAction->GetActionNumber()))
+ {
+ aString+=aUser;
+ aString+='\t';
+
+ aString+=ScGlobal::pLocaleData->getDate(aDateTime);
+ aString+=' ';
+ aString+=ScGlobal::pLocaleData->getTime(aDateTime);
+ aString+='\t';
+ bIsGenerated=FALSE;
+ }
+ else
+ {
+ aString+='\t';
+ aString+='\t';
+ bIsGenerated=TRUE;
+ }
+
+ String aComment=pScChangeAction->GetComment();
+ aComment.EraseAllChars('\n');
+ if(aDesc.Len()>0)
+ {
+ aComment.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aComment+=aDesc;
+ aComment+=')';
+ }
+
+ aString+=aComment;
+
+ if(pTheView->IsValidEntry(&aUser,&aDateTime)|| bIsGenerated)
+ {
+ if(pTheView->IsValidComment(&aComment))
+ {
+ if(pTPFilter->IsRange())
+ {
+ ScRange* pRangeEntry=aRangeList.First();
+
+ while(pRangeEntry!=NULL)
+ {
+ if(pRangeEntry->Intersects(aRef)) break;
+ pRangeEntry=aRangeList.Next();
+ }
+ //SC_CAS_VIRGIN,SC_CAS_ACCEPTED,SC_CAS_REJECTED
+ if(pRangeEntry!=NULL)
+ {
+ bHasFilterEntry=TRUE;
+ bFlag=TRUE;
+ }
+ }
+ else if(!bIsGenerated)
+ {
+ bHasFilterEntry=TRUE;
+ bFlag=TRUE;
+ }
+ }
+ }
+
+ if(!bFlag&& bUseColor&& pParent==NULL)
+ {
+ pEntry=pTheView->InsertEntry(aString,pNewData,Color(COL_LIGHTBLUE),pParent,nPos);
+ }
+ else if(bFlag&& bUseColor&& pParent!=NULL)
+ {
+ pEntry=pTheView->InsertEntry(aString,pNewData,Color(COL_GREEN),pParent,nPos);
+ SvLBoxEntry* pExpEntry=pParent;
+
+ while(pExpEntry!=NULL && !pTheView->IsExpanded(pExpEntry))
+ {
+ SvLBoxEntry* pTmpEntry=pTheView->GetParent(pExpEntry);
+
+ if(pTmpEntry!=NULL) pTheView->Expand(pExpEntry);
+
+ pExpEntry=pTmpEntry;
+ }
+ }
+ else
+ {
+ pEntry=pTheView->InsertEntry(aString,pNewData,pParent,nPos);
+ }
+ return pEntry;
+}
+
+SvLBoxEntry* ScAcceptChgDlg::InsertFilteredAction(const ScChangeAction* pScChangeAction,
+ ScChangeActionState eState,SvLBoxEntry* pParent,
+ BOOL bDelMaster,BOOL bDisabled,ULONG nPos)
+{
+
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pScChangeAction==NULL || pChanges==NULL) return NULL;
+
+ BOOL bIsGenerated=pChanges->IsGenerated(pScChangeAction->GetActionNumber());
+
+ SvLBoxEntry* pEntry=NULL;
+
+ int bFlag=FALSE;
+
+ ScRange aRef=pScChangeAction->GetBigRange().MakeRange();
+ String aUser=pScChangeAction->GetUser();
+ DateTime aDateTime=pScChangeAction->GetDateTime();
+
+ if(pTheView->IsValidEntry(&aUser,&aDateTime)||bIsGenerated)
+ {
+ if(pTPFilter->IsRange())
+ {
+ ScRange* pRangeEntry=aRangeList.First();
+
+ while(pRangeEntry!=NULL)
+ {
+ if(pRangeEntry->Intersects(aRef)) break;
+ pRangeEntry=aRangeList.Next();
+ }
+ //SC_CAS_VIRGIN,SC_CAS_ACCEPTED,SC_CAS_REJECTED
+ if(pRangeEntry!=NULL &&
+ pScChangeAction->GetState()==eState)
+ {
+ bFlag=TRUE;
+ }
+ }
+ else if(pScChangeAction->GetState()==eState && !bIsGenerated)
+ {
+ bFlag=TRUE;
+ }
+ }
+
+ if(bFlag)
+ {
+
+ String aRefStr;
+ ScChangeActionType eType=pScChangeAction->GetType();
+ String aString;
+ String aDesc;
+
+
+ ScRedlinData* pNewData=new ScRedlinData;
+ pNewData->pData=(void *)pScChangeAction;
+ pNewData->nActionNo=pScChangeAction->GetActionNumber();
+ pNewData->bIsAcceptable=pScChangeAction->IsClickable();
+ pNewData->bIsRejectable=pScChangeAction->IsRejectable();
+ pNewData->bDisabled=!pNewData->bIsAcceptable | bDisabled;
+ pNewData->aDateTime=aDateTime;
+ pNewData->nRow = aRef.aStart.Row();
+ pNewData->nCol = aRef.aStart.Col();
+ pNewData->nTable= aRef.aStart.Tab();
+
+ if(eType==SC_CAT_CONTENT)
+ {
+ if(pScChangeAction->IsDialogParent())
+ {
+ aString=aStrContentWithChild;
+ pNewData->nInfo=RD_SPECIAL_VISCONTENT;
+ pNewData->bIsRejectable=FALSE;
+ pNewData->bIsAcceptable=FALSE;
+ }
+ else
+ {
+ aString=*MakeTypeString(eType);
+ pScChangeAction->GetDescription( aDesc, pDoc, TRUE);
+ }
+ }
+ else
+ {
+ aString=*MakeTypeString(eType);
+
+ if(bDelMaster)
+ {
+ pScChangeAction->GetDescription( aDesc, pDoc,TRUE);
+ pNewData->bDisabled=TRUE;
+ pNewData->bIsRejectable=FALSE;
+ }
+ else
+ pScChangeAction->GetDescription( aDesc, pDoc,!pScChangeAction->IsMasterDelete());
+
+ }
+
+ aString+='\t';
+ pScChangeAction->GetRefString(aRefStr, pDoc, TRUE);
+ aString+=aRefStr;
+ aString+='\t';
+
+ if(!bIsGenerated)
+ {
+ aString+=aUser;
+ aString+='\t';
+ aString+=ScGlobal::pLocaleData->getDate(aDateTime);
+ aString+=' ';
+ aString+=ScGlobal::pLocaleData->getTime(aDateTime);
+ aString+='\t';
+ }
+ else
+ {
+ aString+='\t';
+ aString+='\t';
+ }
+
+ String aComment=pScChangeAction->GetComment();
+ aComment.EraseAllChars('\n');
+ if(aDesc.Len()>0)
+ {
+ aComment.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aComment+=aDesc;
+ aComment+=')';
+ }
+ if(pTheView->IsValidComment(&aComment))
+ {
+ aString+=aComment;
+ pEntry=pTheView->InsertEntry(aString,pNewData,pParent,nPos);
+ }
+ else
+ delete pNewData;
+ }
+ return pEntry;
+}
+
+SvLBoxEntry* ScAcceptChgDlg::InsertChangeActionContent(const ScChangeActionContent* pScChangeAction,
+ SvLBoxEntry* pParent, ULONG nSpecial)
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ SvLBoxEntry* pEntry=NULL;
+
+ if(pScChangeAction==NULL || pChanges==NULL) return NULL;
+
+ BOOL bIsGenerated=pChanges->IsGenerated(pScChangeAction->GetActionNumber());
+
+ BOOL bFlag=FALSE;
+
+ ScRange aRef=pScChangeAction->GetBigRange().MakeRange();
+ String aUser=pScChangeAction->GetUser();
+ DateTime aDateTime=pScChangeAction->GetDateTime();
+
+ if(pTheView->IsValidEntry(&aUser,&aDateTime)||bIsGenerated)
+ {
+ if(pTPFilter->IsRange())
+ {
+ ScRange* pRangeEntry=aRangeList.First();
+
+ while(pRangeEntry!=NULL)
+ {
+ if(pRangeEntry->Intersects(aRef)) break;
+ pRangeEntry=aRangeList.Next();
+ }
+ //SC_CAS_VIRGIN,SC_CAS_ACCEPTED,SC_CAS_REJECTED
+ if(pRangeEntry!=NULL)
+ {
+ bFlag=TRUE;
+ }
+ }
+ else if(!bIsGenerated)
+ bFlag=TRUE;
+ }
+
+ String aRefStr;
+ String aString;
+ String a2String;
+ String aDesc;
+
+ if(nSpecial==RD_SPECIAL_CONTENT)
+ {
+ pScChangeAction->GetOldString(a2String);
+ if(a2String.Len()==0) a2String=aStrEmpty;
+
+ //aString+="\'";
+ aString+=a2String;
+ //aString+="\'";
+
+ aDesc=aStrChildOrgContent;
+ aDesc.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+ }
+ else
+ {
+ pScChangeAction->GetNewString(a2String);
+ if(a2String.Len()==0)
+ {
+ a2String=aStrEmpty;
+ aString+=a2String;
+ }
+ else
+ {
+ aString+='\'';
+ aString+=a2String;
+ aString+='\'';
+ a2String=aString;
+ }
+ aDesc=aStrChildContent;
+
+ }
+
+ aDesc+=a2String;
+ aString+='\t';
+ pScChangeAction->GetRefString(aRefStr, pDoc, TRUE);
+ aString+=aRefStr;
+ aString+='\t';
+
+ if(!bIsGenerated)
+ {
+ aString+=aUser;
+ aString+='\t';
+
+ aString+=ScGlobal::pLocaleData->getDate(aDateTime);
+ aString+=' ';
+ aString+=ScGlobal::pLocaleData->getTime(aDateTime);
+ aString+='\t';
+ }
+ else
+ {
+ aString+='\t';
+ aString+='\t';
+ }
+ String aComment=pScChangeAction->GetComment();
+ aComment.EraseAllChars('\n');
+
+ if(aDesc.Len()>0)
+ {
+ aComment.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aComment+=aDesc;
+ aComment+=')';
+ }
+
+ aString+=aComment;
+
+ ScRedlinData* pNewData=new ScRedlinData;
+ pNewData->nInfo=nSpecial;
+ pNewData->pData=(void *)pScChangeAction;
+ pNewData->nActionNo=pScChangeAction->GetActionNumber();
+ pNewData->bIsAcceptable=pScChangeAction->IsClickable();
+ pNewData->bIsRejectable=FALSE;
+ pNewData->bDisabled=!pNewData->bIsAcceptable;
+ pNewData->aDateTime=aDateTime;
+ pNewData->nRow = aRef.aStart.Row();
+ pNewData->nCol = aRef.aStart.Col();
+ pNewData->nTable= aRef.aStart.Tab();
+
+ if(pTheView->IsValidComment(&aComment) && bFlag)
+ {
+ bHasFilterEntry=TRUE;
+ pEntry=pTheView->InsertEntry(aString,pNewData,pParent);
+ }
+ else
+ pEntry=pTheView->InsertEntry(aString,pNewData,Color(COL_LIGHTBLUE),pParent);
+ return pEntry;
+}
+
+long ScAcceptChgDlg::PreNotify( NotifyEvent& rNEvt )
+{
+ if(rNEvt.GetType()==EVENT_GETFOCUS && bNeedsUpdate)
+ {
+ ClearView();
+ UpdateView();
+ bNoSelection=FALSE;
+ }
+
+ return SfxModelessDialog::PreNotify(rNEvt);
+}
+
+
+void ScAcceptChgDlg::UpdateView()
+{
+ bNeedsUpdate=FALSE;
+ DateTime aDateTime;
+ SvLBoxEntry* pParent=NULL;
+ ScChangeTrack* pChanges=NULL;
+ const ScChangeAction* pScChangeAction=NULL;
+ bAcceptEnableFlag=TRUE;
+ bRejectEnableFlag=TRUE;
+ SetPointer(Pointer(POINTER_WAIT));
+ pTheView->SetUpdateMode(FALSE);
+ BOOL bFilterFlag=pTPFilter->IsDate()||pTPFilter->IsRange()||
+ pTPFilter->IsAuthor()||pTPFilter->IsComment();
+
+ bUseColor=bFilterFlag;
+
+ if(pDoc!=NULL)
+ {
+ pChanges=pDoc->GetChangeTrack();
+ if(pChanges!=NULL)
+ {
+ pScChangeAction=pChanges->GetFirst();
+ }
+ }
+ ScChangeActionTable ActionTable;
+ BOOL bTheFlag=FALSE;
+
+ while(pScChangeAction!=NULL)
+ {
+ bHasFilterEntry=FALSE;
+ switch(pScChangeAction->GetState())
+ {
+ case SC_CAS_VIRGIN:
+
+ if(pScChangeAction->IsDialogRoot())
+ {
+ if(pScChangeAction->IsDialogParent())
+ pParent=InsertChangeAction(pScChangeAction,SC_CAS_VIRGIN);
+ else
+ pParent=InsertFilteredAction(pScChangeAction,SC_CAS_VIRGIN);
+ }
+ else
+ pParent=NULL;
+
+ bTheFlag=TRUE;
+ break;
+
+ case SC_CAS_ACCEPTED:
+ pParent=NULL;
+ nAcceptCount++;
+ break;
+
+ case SC_CAS_REJECTED:
+ pParent=NULL;
+ nRejectCount++;
+ break;
+ }
+
+ if(pParent!=NULL && pScChangeAction->IsDialogParent())
+ {
+ if(!bFilterFlag)
+ {
+ pParent->EnableChildsOnDemand(TRUE);
+ }
+ else
+ {
+ BOOL bTestFlag=bHasFilterEntry;
+ bHasFilterEntry=FALSE;
+ if(Expand(pChanges,pScChangeAction,pParent,!bTestFlag)&&!bTestFlag)
+ pTheView->RemoveEntry(pParent);
+ }
+ }
+
+ pScChangeAction=pScChangeAction->GetNext();
+ }
+
+ if( bTheFlag && (!pDoc->IsDocEditable() || pChanges->IsProtected()) )
+ bTheFlag=FALSE;
+
+ pTPView->EnableAccept(bTheFlag);
+ pTPView->EnableAcceptAll(bTheFlag);
+ pTPView->EnableReject(bTheFlag);
+ pTPView->EnableRejectAll(bTheFlag);
+
+ if(nAcceptCount>0)
+ {
+ pParent=pTheView->InsertEntry(
+ aStrAllAccepted, static_cast< RedlinData * >(NULL),
+ static_cast< SvLBoxEntry * >(NULL));
+ pParent->EnableChildsOnDemand(TRUE);
+ }
+ if(nRejectCount>0)
+ {
+ pParent=pTheView->InsertEntry(
+ aStrAllRejected, static_cast< RedlinData * >(NULL),
+ static_cast< SvLBoxEntry * >(NULL));
+ pParent->EnableChildsOnDemand(TRUE);
+ }
+ pTheView->SetUpdateMode(TRUE);
+ SetPointer(Pointer(POINTER_ARROW));
+ SvLBoxEntry* pEntry=pTheView->First();
+ if(pEntry!=NULL)
+ {
+ pTheView->Select(pEntry);
+ }
+}
+
+//----------------------------------------------------------------------------
+BOOL ScAcceptChgDlg::Close()
+{
+ return SfxModelessDialog::Close();
+}
+
+void ScAcceptChgDlg::Resize()
+{
+ SfxModelessDialog::Resize();
+ Size aOutSize=GetOutputSizePixel();
+ aAcceptChgCtr.SetSizePixel(aOutSize);
+}
+
+IMPL_LINK( ScAcceptChgDlg, MinSizeHandle, SvxAcceptChgCtr*, pCtr )
+{
+ if(pCtr==&aAcceptChgCtr)
+ {
+ if(!IsRollUp())
+ SetOutputSizePixel(MinSize);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, RefHandle, SvxTPFilter*, EMPTYARG )
+{
+ USHORT nId =ScSimpleRefDlgWrapper::GetChildWindowId();
+
+ ScSimpleRefDlgWrapper::SetDefaultPosSize(GetPosPixel(),GetSizePixel(),TRUE);
+
+ SC_MOD()->SetRefDialog( nId, TRUE );
+
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ ScSimpleRefDlgWrapper* pWnd =(ScSimpleRefDlgWrapper*)pViewFrm->GetChildWindow( nId );
+
+ if(pWnd!=NULL)
+ {
+// bSimpleRefDlgStarted=TRUE;
+ USHORT nAcceptId=ScAcceptChgDlgWrapper::GetChildWindowId();
+ pViewFrm->ShowChildWindow(nAcceptId,FALSE);
+ pWnd->SetCloseHdl(LINK( this, ScAcceptChgDlg,RefInfoHandle));
+ pWnd->SetRefString(pTPFilter->GetRange());
+ pWnd->SetAutoReOpen(FALSE);
+ Window* pWin=pWnd->GetWindow();
+ pWin->SetPosSizePixel(GetPosPixel(),GetSizePixel());
+ Hide();
+ pWin->SetText(GetText());
+ pWnd->StartRefInput();
+ }
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, RefInfoHandle, String*, pResult)
+{
+ USHORT nId;
+
+// bSimpleRefDlgStarted=FALSE;
+ ScSimpleRefDlgWrapper::SetAutoReOpen(TRUE);
+
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ if(pResult!=NULL)
+ {
+ pTPFilter->SetRange(*pResult);
+ FilterHandle(pTPFilter);
+
+ nId = ScSimpleRefDlgWrapper::GetChildWindowId();
+ ScSimpleRefDlgWrapper* pWnd = (ScSimpleRefDlgWrapper*)pViewFrm->GetChildWindow( nId );
+
+ if(pWnd!=NULL)
+ {
+ Window* pWin=pWnd->GetWindow();
+ Size aWinSize=pWin->GetSizePixel();
+ aWinSize.Width()=GetSizePixel().Width();
+ SetPosSizePixel(pWin->GetPosPixel(),aWinSize);
+ Invalidate();
+ }
+ nId = ScAcceptChgDlgWrapper::GetChildWindowId();
+ pViewFrm->ShowChildWindow( nId, TRUE );
+ }
+ else
+ {
+ nId = ScAcceptChgDlgWrapper::GetChildWindowId();
+ pViewFrm->SetChildWindow( nId, FALSE );
+ }
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, FilterHandle, SvxTPFilter*, pRef )
+{
+ if(pRef!=NULL)
+ {
+ ClearView();
+ aRangeList.Clear();
+ aRangeList.Parse(pTPFilter->GetRange(),pDoc);
+ UpdateView();
+ }
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, RejectHandle, SvxTPView*, pRef )
+{
+ SetPointer(Pointer(POINTER_WAIT));
+
+ bIgnoreMsg=TRUE;
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pRef!=NULL)
+ {
+ SvLBoxEntry* pEntry=pTheView->FirstSelected();
+ while(pEntry!=NULL)
+ {
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ ScChangeAction* pScChangeAction=
+ (ScChangeAction*) pEntryData->pData;
+
+ if(pScChangeAction->GetType()==SC_CAT_INSERT_TABS)
+ {
+ pViewData->SetTabNo(0);
+ }
+ pChanges->Reject(pScChangeAction);
+ }
+ pEntry = pTheView->NextSelected(pEntry);
+ }
+ ScDocShell* pDocSh=pViewData->GetDocShell();
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->GetUndoManager()->Clear();
+ pDocSh->SetDocumentModified();
+ ClearView();
+ UpdateView();
+ }
+ SetPointer(Pointer(POINTER_ARROW));
+
+ bIgnoreMsg=FALSE;
+ return 0;
+}
+IMPL_LINK( ScAcceptChgDlg, AcceptHandle, SvxTPView*, pRef )
+{
+ SetPointer(Pointer(POINTER_WAIT));
+
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ bIgnoreMsg=TRUE;
+ if(pRef!=NULL)
+ {
+ SvLBoxEntry* pEntry=pTheView->FirstSelected();
+ while(pEntry!=NULL)
+ {
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ ScChangeAction* pScChangeAction=
+ (ScChangeAction*) pEntryData->pData;
+ if(pScChangeAction->GetType()==SC_CAT_CONTENT)
+ {
+ if(pEntryData->nInfo==RD_SPECIAL_CONTENT)
+ {
+ pChanges->SelectContent(pScChangeAction,TRUE);
+ }
+ else
+ {
+ pChanges->SelectContent(pScChangeAction);
+ }
+ }
+ else
+ pChanges->Accept(pScChangeAction);
+ }
+ pEntry = pTheView->NextSelected(pEntry);
+ }
+ ScDocShell* pDocSh=pViewData->GetDocShell();
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+ ClearView();
+ UpdateView();
+ }
+ bIgnoreMsg=FALSE;
+
+ return 0;
+}
+
+void ScAcceptChgDlg::RejectFiltered()
+{
+ if(pDoc==NULL) return;
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ const ScChangeAction* pScChangeAction=NULL;
+
+ if(pChanges!=NULL)
+ {
+ pScChangeAction=pChanges->GetLast();
+ }
+
+ while(pScChangeAction!=NULL)
+ {
+ if(pScChangeAction->IsDialogRoot())
+ {
+ if(IsValidAction(pScChangeAction))
+ {
+ pChanges->Reject((ScChangeAction*)pScChangeAction);
+ }
+ }
+ pScChangeAction=pScChangeAction->GetPrev();
+ }
+}
+void ScAcceptChgDlg::AcceptFiltered()
+{
+ if(pDoc==NULL) return;
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ const ScChangeAction* pScChangeAction=NULL;
+
+ if(pChanges!=NULL)
+ {
+ pScChangeAction=pChanges->GetLast();
+ }
+
+ while(pScChangeAction!=NULL)
+ {
+ if(pScChangeAction->IsDialogRoot())
+ {
+ if(IsValidAction(pScChangeAction))
+ {
+ pChanges->Accept((ScChangeAction*)pScChangeAction);
+ }
+ }
+ pScChangeAction=pScChangeAction->GetPrev();
+ }
+}
+
+IMPL_LINK( ScAcceptChgDlg, RejectAllHandle, SvxTPView*, EMPTYARG )
+{
+ SetPointer(Pointer(POINTER_WAIT));
+ bIgnoreMsg=TRUE;
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ if(pChanges!=NULL)
+ {
+ if(pTPFilter->IsDate()||pTPFilter->IsAuthor()||pTPFilter->IsRange()||pTPFilter->IsComment())
+ {
+ RejectFiltered();
+ }
+ else
+ {
+ pChanges->RejectAll();
+ }
+ pViewData->SetTabNo(0);
+
+ ScDocShell* pDocSh=pViewData->GetDocShell();
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->GetUndoManager()->Clear();
+ pDocSh->SetDocumentModified();
+ ClearView();
+ UpdateView();
+ }
+ SetPointer(Pointer(POINTER_ARROW));
+
+ bIgnoreMsg=FALSE;
+
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, AcceptAllHandle, SvxTPView*, EMPTYARG )
+{
+ SetPointer(Pointer(POINTER_WAIT));
+
+ bIgnoreMsg=TRUE;
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ if(pChanges!=NULL)
+ {
+ if(pTPFilter->IsDate()||pTPFilter->IsAuthor()||pTPFilter->IsRange()||pTPFilter->IsComment())
+ {
+ AcceptFiltered();
+ }
+ else
+ {
+ pChanges->AcceptAll();
+ }
+ ScDocShell* pDocSh=pViewData->GetDocShell();
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+ ClearView();
+ UpdateView();
+ }
+ bIgnoreMsg=FALSE;
+ SetPointer(Pointer(POINTER_ARROW));
+
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, SelectHandle, SvxRedlinTable*, EMPTYARG )
+{
+ if(!bNoSelection)
+ {
+ aSelectionTimer.Start();
+ }
+ bNoSelection=FALSE;
+ return 0;
+}
+
+void ScAcceptChgDlg::GetDependents( const ScChangeAction* pScChangeAction,
+ ScChangeActionTable& aActionTable,
+ SvLBoxEntry* pEntry)
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ SvLBoxEntry* pParent=pTheView->GetParent(pEntry);
+ if(pParent!=NULL)
+ {
+ ScRedlinData *pParentData=(ScRedlinData *)(pParent->GetUserData());
+ ScChangeAction* pParentAction=(ScChangeAction*) pParentData->pData;
+ if(pParentAction!=pScChangeAction)
+ {
+ pChanges->GetDependents((ScChangeAction*) pScChangeAction,
+ aActionTable,pScChangeAction->IsMasterDelete());
+ }
+ else
+ {
+ pChanges->GetDependents((ScChangeAction*) pScChangeAction,
+ aActionTable);
+ }
+ }
+ else
+ {
+ pChanges->GetDependents((ScChangeAction*) pScChangeAction,
+ aActionTable,pScChangeAction->IsMasterDelete());
+ }
+}
+
+BOOL ScAcceptChgDlg::InsertContentChilds(ScChangeActionTable* pActionTable,SvLBoxEntry* pParent)
+{
+ BOOL bTheTestFlag=TRUE;
+ ScRedlinData *pEntryData=(ScRedlinData *)(pParent->GetUserData());
+ const ScChangeAction* pScChangeAction = (ScChangeAction*) pEntryData->pData;
+ BOOL bParentInserted = FALSE;
+ // If the parent is a MatrixOrigin then place it in the right order before
+ // the MatrixReferences. Also if it is the first content change at this
+ // position don't insert the first dependent MatrixReference as the special
+ // content (original value) but insert the predecessor of the MatrixOrigin
+ // itself instead.
+ if ( pScChangeAction->GetType() == SC_CAT_CONTENT &&
+ ((const ScChangeActionContent*)pScChangeAction)->IsMatrixOrigin() )
+ {
+ pActionTable->Insert( pScChangeAction->GetActionNumber(),
+ (ScChangeAction*) pScChangeAction );
+ bParentInserted = TRUE;
+ }
+ SvLBoxEntry* pEntry=NULL;
+
+ const ScChangeActionContent* pCChild=(const ScChangeActionContent*)pActionTable->First();
+ while(pCChild!=NULL)
+ {
+ if( pCChild->GetState()==SC_CAS_VIRGIN )
+ break;
+ pCChild=(const ScChangeActionContent*)pActionTable->Next();
+ }
+
+ if(pCChild==NULL) return TRUE;
+
+ SvLBoxEntry* pOriginal=InsertChangeActionContent(pCChild,pParent,RD_SPECIAL_CONTENT);
+ if(pOriginal!=NULL)
+ {
+ bTheTestFlag=FALSE;
+ ScRedlinData *pParentData=(ScRedlinData *)(pOriginal->GetUserData());
+ pParentData->pData=(void *)pScChangeAction;
+ pParentData->nActionNo=pScChangeAction->GetActionNumber();
+ pParentData->bIsAcceptable=pScChangeAction->IsRejectable(); // select old value
+ pParentData->bIsRejectable=FALSE;
+ pParentData->bDisabled=FALSE;
+ }
+ while(pCChild!=NULL)
+ {
+ if(pCChild->GetState()==SC_CAS_VIRGIN)
+ {
+ pEntry=InsertChangeActionContent(pCChild,pParent,RD_SPECIAL_NONE);
+
+ if(pEntry!=NULL)
+ bTheTestFlag=FALSE;
+ }
+ pCChild=(const ScChangeActionContent*)pActionTable->Next();
+ }
+
+ if ( !bParentInserted )
+ {
+ pEntry=InsertChangeActionContent((const ScChangeActionContent*)
+ pScChangeAction,pParent,RD_SPECIAL_NONE);
+
+ if(pEntry!=NULL)
+ {
+ bTheTestFlag=FALSE;
+ ScRedlinData *pParentData=(ScRedlinData *)(pEntry->GetUserData());
+ pParentData->pData=(void *)pScChangeAction;
+ pParentData->nActionNo=pScChangeAction->GetActionNumber();
+ pParentData->bIsAcceptable=pScChangeAction->IsClickable();
+ pParentData->bIsRejectable=FALSE;
+ pParentData->bDisabled=FALSE;
+ }
+ }
+
+ return bTheTestFlag;
+
+}
+
+BOOL ScAcceptChgDlg::InsertAcceptedORejected(SvLBoxEntry* pParent)
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ BOOL bTheTestFlag=TRUE;
+
+ ScChangeActionState eState = SC_CAS_VIRGIN;
+ String aString=pTheView->GetEntryText( pParent);
+ String a2String=aString.Copy(0,aStrAllAccepted.Len());
+ if(a2String==aStrAllAccepted)
+ {
+ eState=SC_CAS_ACCEPTED;
+ }
+ else
+ {
+ a2String=aString.Copy(0,aStrAllRejected.Len());
+ if(a2String==aStrAllRejected)
+ {
+ eState=SC_CAS_REJECTED;
+ }
+ }
+
+ ScChangeAction* pScChangeAction=pChanges->GetFirst();
+ while(pScChangeAction!=NULL)
+ {
+ if(pScChangeAction->GetState()==eState &&
+ InsertFilteredAction(pScChangeAction,eState,pParent)!=NULL)
+ bTheTestFlag=FALSE;
+ pScChangeAction=pScChangeAction->GetNext();
+ }
+ return bTheTestFlag;
+}
+
+BOOL ScAcceptChgDlg::InsertChilds(ScChangeActionTable* pActionTable,SvLBoxEntry* pParent)
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ BOOL bTheTestFlag=TRUE;
+ SvLBoxEntry* pEntry=NULL;
+ const ScChangeAction* pChild=(const ScChangeAction*)pActionTable->First();
+ while(pChild!=NULL)
+ {
+ pEntry=InsertChangeAction(pChild,SC_CAS_VIRGIN,pParent,FALSE,TRUE);
+
+ if(pEntry!=NULL)
+ {
+ bTheTestFlag=FALSE;
+
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ pEntryData->bIsRejectable=FALSE;
+ pEntryData->bIsAcceptable=FALSE;
+ pEntryData->bDisabled=TRUE;
+
+ if(pChild->IsDialogParent())
+ {
+
+ //pEntry->EnableChildsOnDemand(TRUE);
+ Expand(pChanges,pChild,pEntry);
+ }
+ }
+ pChild=pActionTable->Next();
+ }
+ return bTheTestFlag;
+}
+BOOL ScAcceptChgDlg::InsertDeletedChilds(const ScChangeAction* pScChangeAction,
+ ScChangeActionTable* pActionTable,SvLBoxEntry* pParent)
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ BOOL bTheTestFlag=TRUE;
+ SvLBoxEntry* pEntry=NULL;
+ ScChangeActionTable aDelActionTable;
+ const ScChangeAction* pChild=(const ScChangeAction*)pActionTable->First();
+
+ while(pChild!=NULL)
+ {
+
+ if(pScChangeAction!=pChild)
+ pEntry=InsertChangeAction(pChild,SC_CAS_VIRGIN,pParent,FALSE,TRUE);
+ else
+ pEntry=InsertChangeAction(pChild,SC_CAS_VIRGIN,pParent,TRUE,TRUE);
+
+ if(pEntry!=NULL)
+ {
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ pEntryData->bIsRejectable=FALSE;
+ pEntryData->bIsAcceptable=FALSE;
+ pEntryData->bDisabled=TRUE;
+
+ bTheTestFlag=FALSE;
+ if ( pChild->IsDialogParent() )
+ {
+ Expand(pChanges,pChild,pEntry);
+ /*
+ pChanges->GetDependents((ScChangeAction*) pChild,aDelActionTable);
+ if(aDelActionTable.First()!=NULL)
+ {
+ pEntry->EnableChildsOnDemand(TRUE);
+ }
+ aDelActionTable.Clear();
+ */
+ }
+ }
+ pChild=pActionTable->Next();
+ }
+ return bTheTestFlag;
+}
+
+BOOL ScAcceptChgDlg::Expand(ScChangeTrack* pChanges,const ScChangeAction* pScChangeAction,
+ SvLBoxEntry* pEntry,BOOL bFilter)
+{
+ BOOL bTheTestFlag=TRUE;
+
+ if(pChanges!=NULL &&pEntry!=NULL &&pScChangeAction!=NULL)
+ {
+ ScChangeActionTable aActionTable;
+
+ GetDependents( pScChangeAction,aActionTable,pEntry);
+
+ switch(pScChangeAction->GetType())
+ {
+ case SC_CAT_CONTENT:
+ {
+ InsertContentChilds(&aActionTable,pEntry);
+ bTheTestFlag=!bHasFilterEntry;
+ break;
+ }
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ InsertDeletedChilds(pScChangeAction,&aActionTable,pEntry);
+ bTheTestFlag=!bHasFilterEntry;
+ break;
+ }
+ default:
+ {
+ if(!bFilter)
+ bTheTestFlag=InsertChilds(&aActionTable,pEntry);
+ break;
+ }
+ }
+ aActionTable.Clear();
+ }
+ return bTheTestFlag;
+}
+
+IMPL_LINK( ScAcceptChgDlg, ExpandingHandle, SvxRedlinTable*, pTable )
+{
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ ScChangeAction* pScChangeAction=NULL;
+ SetPointer(Pointer(POINTER_WAIT));
+ if(pTable!=NULL && pChanges!=NULL)
+ {
+ ScChangeActionTable aActionTable;
+ SvLBoxEntry* pEntry=pTheView->GetHdlEntry();
+ if(pEntry!=NULL)
+ {
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ pScChangeAction=(ScChangeAction*) pEntryData->pData;
+ }
+
+ if(pEntry->HasChildsOnDemand())
+ {
+ BOOL bTheTestFlag=TRUE;
+ pEntry->EnableChildsOnDemand(FALSE);
+ pTheView->RemoveEntry(pTheView->FirstChild(pEntry));
+
+ if(pEntryData!=NULL)
+ {
+ pScChangeAction=(ScChangeAction*) pEntryData->pData;
+
+ GetDependents( pScChangeAction,aActionTable,pEntry);
+
+ switch(pScChangeAction->GetType())
+ {
+ case SC_CAT_CONTENT:
+ {
+ bTheTestFlag=InsertContentChilds(&aActionTable,pEntry);
+ break;
+ }
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ bTheTestFlag=InsertDeletedChilds(pScChangeAction,&aActionTable,pEntry);
+ break;
+ }
+ default:
+ {
+ bTheTestFlag=InsertChilds(&aActionTable,pEntry);
+ break;
+ }
+ }
+ aActionTable.Clear();
+
+ }
+ else
+ {
+ bTheTestFlag=InsertAcceptedORejected(pEntry);
+ }
+ if(bTheTestFlag) pTheView->InsertEntry(aStrNoEntry,NULL,Color(COL_GRAY),pEntry);
+ }
+
+ }
+ }
+ SetPointer(Pointer(POINTER_ARROW));
+ return (ULONG) TRUE;
+}
+
+
+void ScAcceptChgDlg::AppendChanges(ScChangeTrack* pChanges,ULONG nStartAction,
+ ULONG nEndAction, ULONG /* nPos */)
+{
+ if(pChanges!=NULL)
+ {
+ DateTime aDateTime;
+ SvLBoxEntry* pParent=NULL;
+ const ScChangeAction* pScChangeAction=NULL;
+ bAcceptEnableFlag=TRUE;
+ bRejectEnableFlag=TRUE;
+ SetPointer(Pointer(POINTER_WAIT));
+ pTheView->SetUpdateMode(FALSE);
+
+ ScChangeActionTable ActionTable;
+ BOOL bTheFlag=FALSE;
+
+ BOOL bFilterFlag=pTPFilter->IsDate()||pTPFilter->IsRange()||
+ pTPFilter->IsAuthor()||pTPFilter->IsComment();
+
+ bUseColor=bFilterFlag;
+
+ for(ULONG i=nStartAction;i<=nEndAction;i++)
+ {
+ pScChangeAction=pChanges->GetAction(i);
+ if(pScChangeAction==NULL) continue;
+
+
+ switch(pScChangeAction->GetState())
+ {
+ case SC_CAS_VIRGIN:
+
+ if(pScChangeAction->IsDialogRoot())
+ {
+ if(pScChangeAction->IsDialogParent())
+ pParent=InsertChangeAction(pScChangeAction,SC_CAS_VIRGIN);
+ else
+ pParent=InsertFilteredAction(pScChangeAction,SC_CAS_VIRGIN);
+ }
+ else
+ pParent=NULL;
+
+ bTheFlag=TRUE;
+ break;
+
+ case SC_CAS_ACCEPTED:
+ pParent=NULL;
+ nAcceptCount++;
+ break;
+
+ case SC_CAS_REJECTED:
+ pParent=NULL;
+ nRejectCount++;
+ break;
+ }
+
+ if(pParent!=NULL && pScChangeAction->IsDialogParent())
+ {
+ if(!bFilterFlag)
+ {
+ pParent->EnableChildsOnDemand(TRUE);
+ }
+ else
+ {
+ BOOL bTestFlag=bHasFilterEntry;
+ bHasFilterEntry=FALSE;
+ if(Expand(pChanges,pScChangeAction,pParent,!bTestFlag)&&!bTestFlag)
+ pTheView->RemoveEntry(pParent);
+ }
+ }
+
+ pScChangeAction=pScChangeAction->GetNext();
+ }
+
+ if( bTheFlag && (!pDoc->IsDocEditable() || pChanges->IsProtected()) )
+ bTheFlag=FALSE;
+
+ pTPView->EnableAccept(bTheFlag);
+ pTPView->EnableAcceptAll(bTheFlag);
+ pTPView->EnableReject(bTheFlag);
+ pTPView->EnableRejectAll(bTheFlag);
+
+ pTheView->SetUpdateMode(TRUE);
+ SetPointer(Pointer(POINTER_ARROW));
+ }
+}
+
+void ScAcceptChgDlg::RemoveEntrys(ULONG nStartAction,ULONG nEndAction)
+{
+
+ pTheView->SetUpdateMode(FALSE);
+
+ SvLBoxEntry* pEntry=pTheView->GetCurEntry();
+
+ ScRedlinData *pEntryData=NULL;
+
+ if(pEntry!=NULL)
+ pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+
+ ULONG nAction=0;
+ if(pEntryData!=NULL)
+ {
+ nAction=pEntryData->nActionNo;
+ }
+
+ if(nAction>=nStartAction && nAction<=nEndAction)
+ {
+ pTheView->SetCurEntry(pTheView->GetModel()->GetEntry(0));
+ }
+
+ BOOL bRemove=FALSE;
+
+ // MUST do it backwards, don't delete parents before children and GPF
+ pEntry=pTheView->Last();
+ while(pEntry!=NULL)
+ {
+ bRemove=FALSE;
+ pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ nAction=pEntryData->nActionNo;
+
+ if(nStartAction<=nAction && nAction<=nEndAction) bRemove=TRUE;
+
+
+ }
+ SvLBoxEntry* pPrevEntry = pTheView->Prev(pEntry);
+
+ if(bRemove)
+ {
+ //delete pEntryData;
+ pTheView->RemoveEntry(pEntry);
+ }
+ pEntry=pPrevEntry;
+ }
+ pTheView->SetUpdateMode(TRUE);
+
+}
+
+void ScAcceptChgDlg::UpdateEntrys(ScChangeTrack* pChgTrack, ULONG nStartAction,ULONG nEndAction)
+{
+ pTheView->SetUpdateMode(FALSE);
+
+ ULONG nPos=LIST_APPEND;
+
+ BOOL bRemove=FALSE;
+
+ SvLBoxEntry* pEntry=pTheView->First();
+ SvLBoxEntry* pNextEntry = (pEntry ? pTheView->NextSibling(pEntry) : NULL);
+ SvLBoxEntry* pLastEntry=NULL;
+ while(pEntry!=NULL)
+ {
+ bRemove=FALSE;
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ ScChangeAction* pScChangeAction=
+ (ScChangeAction*) pEntryData->pData;
+
+ ULONG nAction=pScChangeAction->GetActionNumber();
+
+ if(nStartAction<=nAction && nAction<=nEndAction) bRemove=TRUE;
+ }
+
+ if(bRemove)
+ {
+ nPos=pEntry->GetChildListPos();
+ pTheView->RemoveEntry(pEntry);
+
+ if(pLastEntry==NULL) pLastEntry=pTheView->First();
+ if(pLastEntry!=NULL)
+ {
+ pNextEntry=pTheView->Next(pLastEntry);
+
+ if(pNextEntry==NULL)
+ {
+ pNextEntry=pLastEntry;
+ pLastEntry=NULL;
+ }
+ }
+ else
+ pNextEntry=NULL;
+
+ }
+ else
+ {
+ pLastEntry = pEntry;
+ pNextEntry = pTheView->Next(pEntry);
+ }
+ pEntry=pNextEntry;
+ }
+
+ if(nStartAction==nEndAction)
+ AppendChanges(pChgTrack,nStartAction,nEndAction,nPos);
+ else
+ AppendChanges(pChgTrack,nStartAction,nEndAction);
+
+ pTheView->SetUpdateMode(TRUE);
+
+}
+
+IMPL_LINK( ScAcceptChgDlg, ChgTrackModHdl, ScChangeTrack*, pChgTrack)
+{
+// if(bScAcceptChgDlgIsDead) return 0;
+
+ ScChangeTrackMsgQueue& aMsgQueue= pChgTrack->GetMsgQueue();
+
+ ScChangeTrackMsgInfo* pTrackInfo=aMsgQueue.Get();
+ ULONG nStartAction;
+ ULONG nEndAction;
+
+ while(pTrackInfo!=NULL)
+ {
+ nStartAction=pTrackInfo->nStartAction;
+ nEndAction=pTrackInfo->nEndAction;
+
+ if(!bIgnoreMsg)
+ {
+ bNoSelection=TRUE;
+
+ switch(pTrackInfo->eMsgType)
+ {
+ case SC_CTM_APPEND: AppendChanges(pChgTrack,nStartAction,nEndAction);
+ break;
+ case SC_CTM_REMOVE: RemoveEntrys(nStartAction,nEndAction);
+ break;
+ case SC_CTM_PARENT:
+ case SC_CTM_CHANGE: //bNeedsUpdate=TRUE;
+ UpdateEntrys(pChgTrack,nStartAction,nEndAction);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ delete pTrackInfo;
+ pTrackInfo=aMsgQueue.Get();
+ }
+
+ return 0;
+}
+IMPL_LINK( ScAcceptChgDlg, ReOpenTimerHdl, Timer*, EMPTYARG )
+{
+ ScSimpleRefDlgWrapper::SetAutoReOpen(TRUE);
+ aAcceptChgCtr.ShowFilterPage();
+ RefHandle(NULL);
+
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, UpdateSelectionHdl, Timer*, EMPTYARG )
+{
+ ScTabView* pTabView = pViewData->GetView();
+
+ BOOL bAcceptFlag = TRUE;
+ BOOL bRejectFlag = TRUE;
+ BOOL bContMark = FALSE;
+
+ pTabView->DoneBlockMode(); // clears old marking
+ SvLBoxEntry* pEntry = pTheView->FirstSelected();
+ while( pEntry )
+ {
+ ScRedlinData* pEntryData = (ScRedlinData*) pEntry->GetUserData();
+ if( pEntryData )
+ {
+ bRejectFlag &= pEntryData->bIsRejectable;
+ bAcceptFlag &= pEntryData->bIsAcceptable;
+
+ const ScChangeAction* pScChangeAction = (ScChangeAction*) pEntryData->pData;
+ if( pScChangeAction && (pScChangeAction->GetType() != SC_CAT_DELETE_TABS) &&
+ (!pEntryData->bDisabled || pScChangeAction->IsVisible()) )
+ {
+ const ScBigRange& rBigRange = pScChangeAction->GetBigRange();
+ if( rBigRange.IsValid( pDoc ) && IsActive() )
+ {
+ BOOL bSetCursor = !pTheView->NextSelected( pEntry );
+ pTabView->MarkRange( rBigRange.MakeRange(), bSetCursor, bContMark );
+ bContMark = TRUE;
+ }
+ }
+ }
+ else
+ {
+ bAcceptFlag = FALSE;
+ bRejectFlag = FALSE;
+ }
+ bAcceptEnableFlag = bAcceptFlag;
+ bRejectEnableFlag = bRejectFlag;
+
+ pEntry = pTheView->NextSelected( pEntry );
+ }
+
+ ScChangeTrack* pChanges = pDoc->GetChangeTrack();
+ BOOL bEnable = pDoc->IsDocEditable() && pChanges && !pChanges->IsProtected();
+ pTPView->EnableAccept( bAcceptFlag && bEnable );
+ pTPView->EnableReject( bRejectFlag && bEnable );
+
+ return 0;
+}
+
+IMPL_LINK( ScAcceptChgDlg, CommandHdl, Control*, EMPTYARG )
+{
+
+ const CommandEvent aCEvt(pTheView->GetCommandEvent());
+
+ if(aCEvt.GetCommand()==COMMAND_CONTEXTMENU)
+ {
+ ScPopupMenu aPopup(ScResId(RID_POPUP_CHANGES));
+
+ aPopup.SetMenuFlags(MENU_FLAG_HIDEDISABLEDENTRIES);
+
+ SvLBoxEntry* pEntry=pTheView->GetCurEntry();
+ if(pEntry!=NULL)
+ {
+ pTheView->Select(pEntry);
+ }
+ else
+ {
+ aPopup.Deactivate();
+ }
+
+ USHORT nSortedCol= pTheView->GetSortedCol();
+
+ if(nSortedCol!=0xFFFF)
+ {
+ USHORT nItemId=nSortedCol+SC_SUB_SORT+1;
+
+ aPopup.CheckItem(nItemId);
+
+ PopupMenu *pSubMenu = aPopup.GetPopupMenu(SC_SUB_SORT);
+ if (pSubMenu)
+ {
+ pSubMenu->CheckItem(nItemId);
+ }
+ }
+
+ aPopup.EnableItem(SC_CHANGES_COMMENT,FALSE);
+
+ if(pDoc->IsDocEditable() && pEntry!=NULL)
+ {
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ ScChangeAction* pScChangeAction=
+ (ScChangeAction*) pEntryData->pData;
+ if(pScChangeAction!=NULL && !pTheView->GetParent(pEntry))
+ aPopup.EnableItem(SC_CHANGES_COMMENT);
+ }
+ }
+
+ USHORT nCommand=aPopup.Execute( this, GetPointerPosPixel() );
+
+
+ if(nCommand)
+ {
+ if(nCommand==SC_CHANGES_COMMENT)
+ {
+ if(pEntry!=NULL)
+ {
+ ScRedlinData *pEntryData=(ScRedlinData *)(pEntry->GetUserData());
+ if(pEntryData!=NULL)
+ {
+ ScChangeAction* pScChangeAction=
+ (ScChangeAction*) pEntryData->pData;
+
+ pViewData->GetDocShell()->ExecuteChangeCommentDialog( pScChangeAction, this,FALSE);
+ }
+ }
+ }
+ else
+ {
+ BOOL bSortDir=pTheView->GetSortDirection();
+ USHORT nDialogCol=nCommand-SC_SUB_SORT-1;
+ if(nSortedCol==nDialogCol) bSortDir=!bSortDir;
+ pTheView->SortByCol(nDialogCol,bSortDir);
+ /*
+ SC_SUB_SORT
+ SC_SORT_ACTION
+ SC_SORT_POSITION
+ SC_SORT_AUTHOR
+ SC_SORT_DATE
+ SC_SORT_COMMENT
+ */
+ }
+ }
+ }
+ return 0;
+}
+
+void ScAcceptChgDlg::Initialize(SfxChildWinInfo *pInfo)
+{
+ String aStr;
+ if(pInfo!=NULL)
+ {
+ if ( pInfo->aExtraString.Len() )
+ {
+ xub_StrLen nPos = pInfo->aExtraString.Search(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("AcceptChgDat:")));
+
+ // Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
+ // er nicht vorhanden ist, liegt eine "altere Version vor
+ if ( nPos != STRING_NOTFOUND )
+ {
+ xub_StrLen n1 = pInfo->aExtraString.Search('(', nPos);
+ if ( n1 != STRING_NOTFOUND )
+ {
+ xub_StrLen n2 = pInfo->aExtraString.Search(')', n1);
+ if ( n2 != STRING_NOTFOUND )
+ {
+ // Alignment-String herausschneiden
+ aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1);
+ pInfo->aExtraString.Erase(nPos, n2 - nPos + 1);
+ aStr.Erase(0, n1-nPos+1);
+ }
+ }
+ }
+ }
+ }
+ SfxModelessDialog::Initialize(pInfo);
+
+ if ( aStr.Len())
+ {
+ USHORT nCount=(USHORT)aStr.ToInt32();
+
+ for(USHORT i=0;i<nCount;i++)
+ {
+ xub_StrLen n1 = aStr.Search(';');
+ aStr.Erase(0, n1+1);
+ pTheView->SetTab(i,(USHORT)aStr.ToInt32(),MAP_PIXEL);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void ScAcceptChgDlg::FillInfo(SfxChildWinInfo& rInfo) const
+{
+ SfxModelessDialog::FillInfo(rInfo);
+ rInfo.aExtraString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "AcceptChgDat:(" ));
+
+ USHORT nCount=pTheView->TabCount();
+
+ rInfo.aExtraString += String::CreateFromInt32(nCount);
+ rInfo.aExtraString += ';';
+ for(USHORT i=0;i<nCount;i++)
+ {
+ rInfo.aExtraString += String::CreateFromInt32(pTheView->GetTab(i));
+ rInfo.aExtraString += ';';
+ }
+ rInfo.aExtraString += ')';
+}
+
+void ScAcceptChgDlg::InitFilter()
+{
+ if(pTPFilter->IsDate()||pTPFilter->IsRange()||
+ pTPFilter->IsAuthor()||pTPFilter->IsComment())
+ {
+ pTheView->SetFilterDate(pTPFilter->IsDate());
+ pTheView->SetDateTimeMode(pTPFilter->GetDateMode());
+ pTheView->SetFirstDate(pTPFilter->GetFirstDate());
+ pTheView->SetLastDate(pTPFilter->GetLastDate());
+ pTheView->SetFirstTime(pTPFilter->GetFirstTime());
+ pTheView->SetLastTime(pTPFilter->GetLastTime());
+ pTheView->SetFilterAuthor(pTPFilter->IsAuthor());
+ pTheView->SetAuthor(pTPFilter->GetSelectedAuthor());
+
+ pTheView->SetFilterComment(pTPFilter->IsComment());
+
+ utl::SearchParam aSearchParam( pTPFilter->GetComment(),
+ utl::SearchParam::SRCH_REGEXP,FALSE,FALSE,FALSE );
+
+ pTheView->SetCommentParams(&aSearchParam);
+
+ pTheView->UpdateFilterTest();
+ }
+}
+
+//UNUSED2008-05 void ScAcceptChgDlg::SetMyStaticData()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+IMPL_LINK( ScAcceptChgDlg, FilterModified, SvxTPFilter*, EMPTYARG )
+{
+ return 0;
+}
+
+#define CALC_DATE 3
+#define CALC_POS 1
+
+IMPL_LINK( ScAcceptChgDlg, ColCompareHdl, SvSortData*, pSortData )
+{
+ StringCompare eCompare=COMPARE_EQUAL;
+ SCCOL nSortCol= static_cast<SCCOL>(pTheView->GetSortedCol());
+
+ if(pSortData)
+ {
+ SvLBoxEntry* pLeft = (SvLBoxEntry*)(pSortData->pLeft );
+ SvLBoxEntry* pRight = (SvLBoxEntry*)(pSortData->pRight );
+
+ if(CALC_DATE==nSortCol)
+ {
+ RedlinData *pLeftData=(RedlinData *)(pLeft->GetUserData());
+ RedlinData *pRightData=(RedlinData *)(pRight->GetUserData());
+
+ if(pLeftData!=NULL && pRightData!=NULL)
+ {
+ if(pLeftData->aDateTime < pRightData->aDateTime)
+ {
+ eCompare=COMPARE_LESS;
+ }
+ else if(pLeftData->aDateTime > pRightData->aDateTime)
+ {
+ eCompare=COMPARE_GREATER;
+ }
+ return eCompare;
+ }
+ }
+ else if(CALC_POS==nSortCol)
+ {
+ ScRedlinData *pLeftData=(ScRedlinData *)(pLeft->GetUserData());
+ ScRedlinData *pRightData=(ScRedlinData *)(pRight->GetUserData());
+
+ if(pLeftData!=NULL && pRightData!=NULL)
+ {
+ eCompare=COMPARE_GREATER;
+
+ if(pLeftData->nTable < pRightData->nTable)
+ {
+ eCompare=COMPARE_LESS;
+ }
+ else if(pLeftData->nTable == pRightData->nTable)
+ {
+ if(pLeftData->nRow < pRightData->nRow)
+ {
+ eCompare=COMPARE_LESS;
+ }
+ else if(pLeftData->nRow == pRightData->nRow)
+ {
+ if(pLeftData->nCol < pRightData->nCol)
+ {
+ eCompare=COMPARE_LESS;
+ }
+ else if(pLeftData->nCol == pRightData->nCol)
+ {
+ eCompare=COMPARE_EQUAL;
+ }
+ }
+ }
+
+ return eCompare;
+ }
+ }
+
+ SvLBoxItem* pLeftItem = pTheView->GetEntryAtPos( pLeft, static_cast<sal_uInt16>(nSortCol));
+ SvLBoxItem* pRightItem = pTheView->GetEntryAtPos( pRight, static_cast<sal_uInt16>(nSortCol));
+
+ if(pLeftItem != NULL && pRightItem != NULL)
+ {
+ USHORT nLeftKind=pLeftItem->IsA();
+ USHORT nRightKind=pRightItem->IsA();
+
+ if(nRightKind == SV_ITEM_ID_LBOXSTRING &&
+ nLeftKind == SV_ITEM_ID_LBOXSTRING )
+ {
+ eCompare= (StringCompare) ScGlobal::GetCaseCollator()->compareString(
+ ((SvLBoxString*)pLeftItem)->GetText(),
+ ((SvLBoxString*)pRightItem)->GetText());
+
+ if(eCompare==COMPARE_EQUAL) eCompare=COMPARE_LESS;
+ }
+ }
+
+
+ }
+ return eCompare;
+}
+
diff --git a/sc/source/ui/miscdlgs/acredlin.src b/sc/source/ui/miscdlgs/acredlin.src
new file mode 100644
index 000000000000..4baa9f3d388c
--- /dev/null
+++ b/sc/source/ui/miscdlgs/acredlin.src
@@ -0,0 +1,258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "acredlin.hrc"
+ModelessDialog RID_SCDLG_CHANGES
+{
+ OutputSize = TRUE ;
+ HelpId = FID_CHG_ACCEPT ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 282 , 142 ) ;
+ Moveable = TRUE ;
+ Sizeable = TRUE ;
+ Closeable = TRUE ;
+ // Dieser Dialog hat einen Cancel-Button !
+ Control CTR_REDLINING
+ {
+ HelpId = HID_SC_REDLIN_CTR ;
+ Pos = MAP_APPFONT ( 2 , 2 ) ;
+ Size = MAP_APPFONT ( 270 , 105 ) ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 271 , 105 ) ;
+ Size = MAP_APPFONT ( 1 , 1 ) ;
+ TabStop = FALSE ;
+ };
+ FixedText FT_ASSIGN
+ {
+ Hide = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 105 ) ;
+ Size = MAP_APPFONT ( 128 , 12 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Range" ;
+ };
+ Edit ED_ASSIGN
+ {
+ Hide = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 119 ) ;
+ Size = MAP_APPFONT ( 128 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_ASSIGN
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 118 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Minimize/Maximize" ;
+ };
+ String STR_INSERT_COLS
+ {
+ Text [ en-US ] = "Column inserted" ;
+ };
+ String STR_INSERT_ROWS
+ {
+ Text [ en-US ] = "Row inserted " ;
+ };
+ String STR_INSERT_TABS
+ {
+ Text [ en-US ] = "Sheet inserted " ;
+ };
+ String STR_DELETE_COLS
+ {
+ Text [ en-US ] = "Column deleted" ;
+ };
+ String STR_DELETE_ROWS
+ {
+ Text [ en-US ] = "Row deleted" ;
+ };
+ String STR_DELETE_TABS
+ {
+ Text [ en-US ] = "Sheet deleted" ;
+ };
+ String STR_MOVE
+ {
+ Text [ en-US ] = "Range moved" ;
+ };
+ String STR_CONTENT
+ {
+ Text [ en-US ] = "Changed contents" ;
+ };
+ String STR_CONTENT_WITH_CHILD
+ {
+ Text [ en-US ] = "Changed contents" ;
+ };
+ String STR_CHILD_CONTENT
+ {
+ Text [ en-US ] = "Changed to " ;
+ };
+ String STR_CHILD_ORGCONTENT
+ {
+ Text [ en-US ] = "Original" ;
+ };
+ String STR_REJECT
+ {
+ Text [ en-US ] = "Changes rejected" ;
+ };
+ String STR_ACCEPTED
+ {
+ Text [ en-US ] = "Accepted" ;
+ };
+ String STR_REJECTED
+ {
+ Text [ en-US ] = "Rejected" ;
+ };
+ String STR_NO_ENTRY
+ {
+ Text [ en-US ] = "No Entry" ;
+ };
+ String STR_EMPTY
+ {
+ Text [ en-US ] = "<empty>" ;
+ };
+ Bitmap BMP_STR_CLOSE
+ {
+ File = "dir-clos.bmp" ;
+ };
+ Bitmap BMP_STR_OPEN
+ {
+ File = "dir-open.bmp" ;
+ };
+ Bitmap BMP_STR_END
+ {
+ File = "basobj2.bmp" ;
+ };
+ Bitmap BMP_STR_ERROR
+ {
+ File = "basbrk.bmp" ;
+ };
+ Text [ en-US ] = "Accept or Reject Changes" ;
+};
+Menu RID_POPUP_CHANGES
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SC_CHANGES_COMMENT ;
+ HelpId = HID_SC_CHANGES_COMMENT ;
+ Text [ en-US ] = "Edit Comment..." ;
+
+ };
+ MenuItem
+ {
+ Identifier = SC_SUB_SORT ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SC_SORT_ACTION ;
+ HelpID = HID_SC_SORT_ACTION ;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "Action" ;
+ };
+ MenuItem
+ {
+ Identifier = SC_SORT_POSITION ;
+ HelpID = HID_SORT_POSITION ;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "Position" ;
+ };
+ MenuItem
+ {
+ Identifier = SC_SORT_AUTHOR ;
+ HelpID = HID_SC_SORT_AUTHOR ;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "Author" ;
+ };
+ MenuItem
+ {
+ Identifier = SC_SORT_DATE ;
+ HelpID = HID_SC_SORT_DATE ;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "Date" ;
+ };
+ MenuItem
+ {
+ Identifier = SC_SORT_COMMENT ;
+ HelpID = HID_SC_SORT_COMMENT ;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "Description" ;
+ };
+ };
+ };
+ Text [ en-US ] = "Sorting" ;
+ };
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx
new file mode 100644
index 000000000000..32b3376da9a7
--- /dev/null
+++ b/sc/source/ui/miscdlgs/anyrefdg.cxx
@@ -0,0 +1,1011 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "rangelst.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/viewsh.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/mnemonic.hxx>
+#include <tools/shl.hxx>
+#include <svtools/taskbar.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+
+
+#define ANYREFDG_CXX
+#include "anyrefdg.hxx"
+#undef ANYREFDG_CXX
+
+#include "sc.hrc"
+#include "inputhdl.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "inputwin.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "rfindlst.hxx"
+#include "compiler.hxx"
+#include "cell.hxx"
+#include "global.hxx"
+#include "inputopt.hxx"
+#include "rangeutl.hxx"
+
+
+ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings)
+ : m_pDlg(_pDlg)
+ , pRefEdit (NULL)
+ , m_pWindow(NULL)
+ , m_pBindings(_pBindings)
+ , pAccel( NULL )
+ , pHiddenMarks(NULL)
+ , nRefTab(0)
+ , bHighLightRef( FALSE )
+ , bAccInserted( FALSE )
+{
+ ScInputOptions aInputOption=SC_MOD()->GetInputOptions();
+ bEnableColorRef=aInputOption.GetRangeFinder();
+}
+// -----------------------------------------------------------------------------
+ScFormulaReferenceHelper::~ScFormulaReferenceHelper()
+{
+ if (bAccInserted)
+ Application::RemoveAccel( pAccel.get() );
+
+ // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here
+
+ HideReference();
+ enableInput( TRUE );
+
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ pInputHdl->ResetDelayTimer(); // stop the timer for disabling the input line
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::enableInput( BOOL bEnable )
+{
+ TypeId aType(TYPE(ScDocShell));
+ ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
+ while( pDocShell )
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ while( pFrame )
+ {
+ // #71577# enable everything except InPlace, including bean frames
+ if ( !pFrame->GetFrame().IsInPlace() )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
+ if(pViewSh!=NULL)
+ {
+ Window *pWin=pViewSh->GetWindow();
+ if(pWin)
+ {
+ Window *pParent=pWin->GetParent();
+ if(pParent)
+ {
+ pParent->EnableInput(bEnable,TRUE /* FALSE */);
+ if(TRUE /*bChilds*/)
+ pViewSh->EnableRefInput(bEnable);
+ }
+ }
+ }
+ }
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
+ }
+
+ pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr )
+{
+ if( /*!pRefEdit &&*/ bEnableColorRef )
+ {
+ bHighLightRef=TRUE;
+ ScViewData* pViewData=ScDocShell::GetViewData();
+ if ( pViewData )
+ {
+ ScDocument* pDoc=pViewData->GetDocument();
+ ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
+
+ ScRangeList aRangeList;
+
+ pTabViewShell->DoneRefMode( FALSE );
+ pTabViewShell->ClearHighlightRanges();
+
+ if( ParseWithNames( aRangeList, rStr, pDoc ) )
+ {
+ ScRange* pRangeEntry = aRangeList.First();
+
+ USHORT nIndex=0;
+ while(pRangeEntry != NULL)
+ {
+ ColorData aColName = ScRangeFindList::GetColorName(nIndex++);
+ pTabViewShell->AddHighlightRange(*pRangeEntry, aColName);
+
+ pRangeEntry = aRangeList.Next();
+ }
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
+{
+ bool bError = false;
+ rRanges.RemoveAll();
+
+ ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
+ ScRangeUtil aRangeUtil;
+ xub_StrLen nTokenCnt = rStr.GetTokenCount();
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ ScRange aRange;
+ String aRangeStr( rStr.GetToken( nToken ) );
+
+ USHORT nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails );
+ if ( nFlags & SCA_VALID )
+ {
+ if ( (nFlags & SCA_TAB_3D) == 0 )
+ aRange.aStart.SetTab( nRefTab );
+ if ( (nFlags & SCA_TAB2_3D) == 0 )
+ aRange.aEnd.SetTab( aRange.aStart.Tab() );
+ rRanges.Append( aRange );
+ }
+ else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) )
+ rRanges.Append( aRange );
+ else
+ bError = true;
+ }
+
+ return !bError;
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr )
+{
+ if( /*!pRefEdit &&*/ bEnableColorRef)
+ {
+ bHighLightRef=TRUE;
+ ScViewData* pViewData=ScDocShell::GetViewData();
+ if ( pViewData && pRefComp.get() )
+ {
+ ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScAddress aPos( nCol, nRow, nTab );
+
+ ScTokenArray* pScTokA=pRefComp->CompileString(rStr);
+ //pRefComp->CompileTokenArray();
+
+ if(pTabViewShell!=NULL && pScTokA!=NULL)
+ {
+ pTabViewShell->DoneRefMode( FALSE );
+ pTabViewShell->ClearHighlightRanges();
+
+ pScTokA->Reset();
+ const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
+
+ USHORT nIndex=0;
+
+ while(pToken!=NULL)
+ {
+ BOOL bDoubleRef=(pToken->GetType()==formula::svDoubleRef);
+
+
+ if(pToken->GetType()==formula::svSingleRef || bDoubleRef)
+ {
+ ScRange aRange;
+ if(bDoubleRef)
+ {
+ ScComplexRefData aRef( pToken->GetDoubleRef() );
+ aRef.CalcAbsIfRel( aPos );
+ aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab );
+ aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab );
+ }
+ else
+ {
+ ScSingleRefData aRef( pToken->GetSingleRef() );
+ aRef.CalcAbsIfRel( aPos );
+ aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab );
+ aRange.aEnd = aRange.aStart;
+ }
+ ColorData aColName=ScRangeFindList::GetColorName(nIndex++);
+ pTabViewShell->AddHighlightRange(aRange, aColName);
+ }
+
+ pToken = static_cast<const ScToken*>(pScTokA->GetNextReference());
+ }
+ }
+ if(pScTokA!=NULL) delete pScTokA;
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::HideReference( BOOL bDoneRefMode )
+{
+ ScViewData* pViewData=ScDocShell::GetViewData();
+
+ if( pViewData && /*!pRefEdit &&*/ bHighLightRef && bEnableColorRef)
+ {
+ ScTabViewShell* pTabViewShell=pViewData->GetViewShell();
+
+ if(pTabViewShell!=NULL)
+ {
+ // bDoneRefMode is FALSE when called from before SetReference.
+ // In that case, RefMode was just started and must not be ended now.
+
+ if ( bDoneRefMode )
+ pTabViewShell->DoneRefMode( FALSE );
+ pTabViewShell->ClearHighlightRanges();
+ }
+ bHighLightRef=FALSE;
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::ShowReference( const XubString& rStr )
+{
+ if( /*!pRefEdit &&*/ bEnableColorRef )
+ {
+ if( rStr.Search('(')!=STRING_NOTFOUND ||
+ rStr.Search('+')!=STRING_NOTFOUND ||
+ rStr.Search('*')!=STRING_NOTFOUND ||
+ rStr.Search('-')!=STRING_NOTFOUND ||
+ rStr.Search('/')!=STRING_NOTFOUND ||
+ rStr.Search('&')!=STRING_NOTFOUND ||
+ rStr.Search('<')!=STRING_NOTFOUND ||
+ rStr.Search('>')!=STRING_NOTFOUND ||
+ rStr.Search('=')!=STRING_NOTFOUND ||
+ rStr.Search('^')!=STRING_NOTFOUND)
+ {
+ ShowFormulaReference(rStr);
+ }
+ else
+ {
+ ShowSimpleReference(rStr);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ if( !pRefEdit && pEdit )
+ {
+ m_pDlg->RefInputStart( pEdit, pButton );
+// if( pRefEdit )
+// pRefEdit->SilentGrabFocus();
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if( pViewShell )
+ {
+ pViewShell->ActiveGrabFocus();
+ if( pRefEdit )
+ {
+ const ScViewData* pViewData = pViewShell->GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScRangeList aRangeList;
+ if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) )
+ {
+ const ScRange* pRange = aRangeList.GetObject( 0 );
+ if( pRange )
+ {
+ pViewShell->SetTabNo( pRange->aStart.Tab() );
+ pViewShell->MoveCursorAbs( pRange->aStart.Col(),
+ pRange->aStart.Row(), SC_FOLLOW_JUMP, FALSE, FALSE );
+ pViewShell->MoveCursorAbs( pRange->aEnd.Col(),
+ pRange->aEnd.Row(), SC_FOLLOW_JUMP, TRUE, FALSE );
+ m_pDlg->SetReference( *pRange, pDoc );
+ }
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::Init()
+{
+ ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell?
+ if ( pViewData )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScAddress aCursorPos( nCol, nRow, nTab );
+
+ String rStrExp;
+ pRefCell.reset( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
+ pRefComp.reset( new ScCompiler( pDoc, aCursorPos) );
+ pRefComp->SetGrammar( pDoc->GetGrammar() );
+ pRefComp->SetCompileForFAP(TRUE);
+
+ nRefTab = nTab;
+ } // if ( pViewData )
+}
+// -----------------------------------------------------------------------------
+IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator *, pSelAccel )
+{
+ if ( !pSelAccel )
+ return 0;
+
+ switch ( pSelAccel->GetCurKeyCode().GetCode() )
+ {
+ case KEY_RETURN:
+ case KEY_ESCAPE:
+ if( pRefEdit )
+ pRefEdit->GrabFocus();
+ m_pDlg->RefInputDone( TRUE );
+ break;
+ }
+ return TRUE;
+}
+//----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::RefInputDone( BOOL bForced )
+{
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //if (pRefEdit && (bForced || !pRefBtn))
+ if ( CanInputDone( bForced ) )//if (pRefEdit && (bForced || !pRefBtn))
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ {
+ if (bAccInserted) // Accelerator wieder abschalten
+ {
+ Application::RemoveAccel( pAccel.get() );
+ bAccInserted = FALSE;
+ }
+
+ // Fenstertitel anpassen
+ m_pWindow->SetText(sOldDialogText);
+
+ // Fenster wieder gross
+ m_pWindow->SetOutputSizePixel(aOldDialogSize);
+
+ // pEditCell an alte Position
+ pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize);
+
+ // set button position and image
+ if( pRefBtn )
+ {
+ pRefBtn->SetPosPixel( aOldButtonPos );
+ pRefBtn->SetStartImage();
+ }
+
+ // Alle anderen: Show();
+ USHORT nChildren = m_pWindow->GetChildCount();
+ for ( USHORT i = 0; i < nChildren; i++ )
+ if (pHiddenMarks[i])
+ {
+ m_pWindow->GetChild(i)->GetWindow( WINDOW_CLIENT )->Show();
+ }
+ delete [] pHiddenMarks;
+
+ pRefEdit = NULL;
+ pRefBtn = NULL;
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ if (!pRefEdit)
+ {
+ pRefEdit = pEdit;
+ pRefBtn = pButton;
+
+ // Neuen Fenstertitel basteln
+ String sNewDialogText;
+ sOldDialogText = m_pWindow->GetText();
+ sNewDialogText = sOldDialogText;
+ sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+
+ // Alle Elemente ausser EditCell und Button verstecken
+ USHORT nChildren = m_pWindow->GetChildCount();
+ pHiddenMarks = new BOOL [nChildren];
+ for (USHORT i = 0; i < nChildren; i++)
+ {
+ pHiddenMarks[i] = FALSE;
+ Window* pWin = m_pWindow->GetChild(i);
+ pWin = pWin->GetWindow( WINDOW_CLIENT );
+ if (pWin == (Window*)pRefEdit)
+ {
+ sNewDialogText += m_pWindow->GetChild(i-1)->GetWindow( WINDOW_CLIENT )->GetText();
+ }
+ else if (pWin == (Window*)pRefBtn)
+ ; // do nothing
+ else if (pWin->IsVisible())
+ {
+ pHiddenMarks[i] = TRUE;
+ pWin->Hide();
+ }
+ }
+
+ // Alte Daten merken
+ aOldDialogSize = m_pWindow->GetOutputSizePixel();
+ aOldEditPos = pRefEdit->GetPosPixel();
+ aOldEditSize = pRefEdit->GetSizePixel();
+ if (pRefBtn)
+ aOldButtonPos = pRefBtn->GetPosPixel();
+
+ // Edit-Feld verschieben und anpassen
+ Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height());
+ Size aNewEditSize(aNewDlgSize);
+ long nOffset = 0;
+ if (pRefBtn)
+ {
+ aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width();
+ aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width());
+
+ long nHeight = pRefBtn->GetSizePixel().Height();
+ if ( nHeight > aOldEditSize.Height() )
+ {
+ aNewDlgSize.Height() = nHeight;
+ nOffset = (nHeight-aOldEditSize.Height()) / 2;
+ }
+ aNewEditSize.Width() -= nOffset;
+ }
+ pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize);
+
+ // set button position and image
+ if( pRefBtn )
+ {
+ pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) );
+ pRefBtn->SetEndImage();
+ }
+
+ // Fenster verkleinern
+ m_pWindow->SetOutputSizePixel(aNewDlgSize);
+
+ // Fenstertitel anpassen
+ m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) );
+
+// if ( pButton ) // ueber den Button: Enter und Escape abfangen
+// {
+ if (!pAccel.get())
+ {
+ pAccel.reset( new Accelerator );
+ pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) );
+ pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) );
+ pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) );
+ }
+ Application::InsertAccel( pAccel.get() );
+ bAccInserted = TRUE;
+// }
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ if( pEdit )
+ {
+ if( pRefEdit == pEdit ) // is this the active ref edit field?
+ {
+ pRefEdit->GrabFocus(); // before RefInputDone()
+ m_pDlg->RefInputDone( TRUE ); // finish ref input
+ }
+ else
+ {
+ m_pDlg->RefInputDone( TRUE ); // another active ref edit?
+ m_pDlg->RefInputStart( pEdit, pButton ); // start ref input
+ // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
+ if( pRefEdit )
+ pRefEdit->GrabFocus();
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+BOOL ScFormulaReferenceHelper::DoClose( USHORT nId )
+{
+ SfxApplication* pSfxApp = SFX_APP();
+
+ SetDispatcherLock( FALSE ); //! here and in dtor ?
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) )
+ {
+ // Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch
+ // per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow),
+ // damit die Buttons auch wieder enabled gezeichnet werden.
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS);
+ if (pChild)
+ {
+ ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
+ pWin->Enable();
+ }
+ }
+
+ // find parent view frame to close dialog
+ SfxViewFrame* pMyViewFrm = NULL;
+ if ( m_pBindings )
+ {
+ SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher();
+ if (pMyDisp)
+ pMyViewFrm = pMyDisp->GetFrame();
+ }
+ SC_MOD()->SetRefDialog( nId, FALSE, pMyViewFrm );
+
+ pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
+
+ ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
+ if ( pScViewShell )
+ pScViewShell->UpdateInputHandler(TRUE);
+
+ return TRUE;
+}
+void ScFormulaReferenceHelper::SetDispatcherLock( BOOL bLock )
+{
+ // lock / unlock only the dispatchers of Calc documents
+
+ TypeId aType(TYPE(ScDocShell));
+ ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
+ while( pDocShell )
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ while( pFrame )
+ {
+ SfxDispatcher* pDisp = pFrame->GetDispatcher();
+ if (pDisp)
+ pDisp->Lock( bLock );
+
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
+ }
+ pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
+ }
+
+ // if a new view is created while the dialog is open,
+ // that view's dispatcher is locked when trying to create the dialog
+ // for that view (ScTabViewShell::CreateRefDialog)
+}
+// -----------------------------------------------------------------------------
+void ScFormulaReferenceHelper::ViewShellChanged(ScTabViewShell* /* pScViewShell */)
+{
+ enableInput( FALSE );
+
+ EnableSpreadsheets();
+}
+void ScFormulaReferenceHelper::EnableSpreadsheets(BOOL bFlag, BOOL bChilds)
+{
+ TypeId aType(TYPE(ScDocShell));
+ ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
+ while( pDocShell )
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ while( pFrame )
+ {
+ // #71577# enable everything except InPlace, including bean frames
+ if ( !pFrame->GetFrame().IsInPlace() )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
+ if(pViewSh!=NULL)
+ {
+ Window *pWin=pViewSh->GetWindow();
+ if(pWin)
+ {
+ Window *pParent=pWin->GetParent();
+ if(pParent)
+ {
+ pParent->EnableInput(bFlag,FALSE);
+ if(bChilds)
+ pViewSh->EnableRefInput(bFlag);
+ }
+ }
+ }
+ }
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
+ }
+
+ pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+
+
+void lcl_InvalidateWindows()
+{
+ TypeId aType(TYPE(ScDocShell));
+ ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
+ while( pDocShell )
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ while( pFrame )
+ {
+ // #71577# enable everything except InPlace, including bean frames
+ if ( !pFrame->GetFrame().IsInPlace() )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
+ if(pViewSh!=NULL)
+ {
+ Window *pWin=pViewSh->GetWindow();
+ if(pWin)
+ {
+ Window *pParent=pWin->GetParent();
+ if(pParent)
+ pParent->Invalidate();
+ }
+ }
+ }
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
+ }
+
+ pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType);
+ }
+}
+//----------------------------------------------------------------------------
+
+void lcl_HideAllReferences()
+{
+ TypeId aScType = TYPE(ScTabViewShell);
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh )
+ {
+ ((ScTabViewShell*)pSh)->ClearHighlightRanges();
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+}
+
+//============================================================================
+//The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
+// class ScRefHandler
+//----------------------------------------------------------------------------
+
+ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB/*, SfxChildWindow* pCW,
+ Window* pParent, USHORT nResId*/, bool bBindRef )
+ : //SfxModelessDialog ( pB, pCW, pParent, ScResId( nResId ) ),
+ m_rWindow( rWindow ),
+ m_bInRefMode( false ),
+ m_aHelper(this,pB),
+ pMyBindings( pB ),
+ pActiveWin(NULL)
+{
+ m_aHelper.SetWindow(/*this*/&m_rWindow);
+ if(m_rWindow.GetHelpId()==0) //Hack, da im SfxModelessDialog die HelpId
+ m_rWindow.SetHelpId(m_rWindow.GetUniqueId()); //fuer einen ModelessDialog entfernt und
+ //in eine UniqueId gewandelt wird, machen
+ //wir das an dieser Stelle rueckgaengig.
+ aTimer.SetTimeout(200);
+ aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl));
+
+ if( bBindRef ) EnterRefMode();
+}
+
+bool ScRefHandler::EnterRefMode()
+{
+ if( m_bInRefMode ) return false;
+
+ SC_MOD()->InputEnterHandler();
+// ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
+
+ ScTabViewShell* pScViewShell = NULL;
+
+ // title has to be from the view that opened the dialog,
+ // even if it's not the current view
+
+ SfxObjectShell* pParentDoc = NULL;
+ if ( pMyBindings )
+ {
+ SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher();
+ if (pMyDisp)
+ {
+ SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
+ if (pMyViewFrm)
+ {
+ pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
+ if( pScViewShell )
+ pScViewShell->UpdateInputHandler(TRUE);
+ pParentDoc = pMyViewFrm->GetObjectShell();
+ }
+ }
+ }
+ if ( !pParentDoc && pScViewShell ) // use current only if above fails
+ pParentDoc = pScViewShell->GetObjectShell();
+ if ( pParentDoc )
+ aDocName = pParentDoc->GetTitle();
+
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
+
+ DBG_ASSERT( pInputHdl, "Missing input handler :-/" );
+
+ if ( pInputHdl )
+ pInputHdl->NotifyChange( NULL );
+
+ m_aHelper.enableInput( FALSE );
+
+ m_aHelper.EnableSpreadsheets();
+
+ m_aHelper.Init();
+
+ m_aHelper.SetDispatcherLock( TRUE );
+ //@Test
+ //SFX_APPWINDOW->Disable(TRUE); //@BugID 54702
+
+ return m_bInRefMode = true;
+}
+
+//----------------------------------------------------------------------------
+
+ScRefHandler::~ScRefHandler()
+{
+ LeaveRefMode();
+}
+
+bool ScRefHandler::LeaveRefMode()
+{
+ if( !m_bInRefMode ) return false;
+
+ lcl_HideAllReferences();
+
+ if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) )
+ pDlg->SetModalInputMode(FALSE);
+ SetDispatcherLock( FALSE ); //! here and in DoClose ?
+
+ ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
+ if( pScViewShell )
+ pScViewShell->UpdateInputHandler(TRUE);
+
+ //SFX_APPWINDOW->Enable(TRUE,TRUE);
+ lcl_InvalidateWindows();
+
+ m_bInRefMode = false;
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+//SfxBindings& ScRefHandler::GetBindings()
+//{
+// //! SfxModelessDialog should allow access to pBindings pointer
+//
+// return *pMyBindings;
+//}
+
+//----------------------------------------------------------------------------
+
+void ScRefHandler::SwitchToDocument()
+{
+ ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell();
+ if (pCurrent)
+ {
+ SfxObjectShell* pObjSh = pCurrent->GetObjectShell();
+ if ( pObjSh && pObjSh->GetTitle() == aDocName )
+ {
+ // right document already visible -> nothing to do
+ return;
+ }
+ }
+
+ TypeId aScType = TYPE(ScTabViewShell);
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh )
+ {
+ SfxObjectShell* pObjSh = pSh->GetObjectShell();
+ if ( pObjSh && pObjSh->GetTitle() == aDocName )
+ {
+ // switch to first TabViewShell for document
+ ((ScTabViewShell*)pSh)->SetActive();
+ return;
+ }
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be 0
+{
+ // default: allow only same document (overridden in function dialog)
+ String aCmpName;
+ if ( pDocSh )
+ aCmpName = pDocSh->GetTitle();
+
+ // if aDocName isn't initialized, allow
+ return ( aDocName.Len() == 0 || aDocName == aCmpName );
+}
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScRefHandler::IsRefInputMode() const
+{
+ return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen
+}
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScRefHandler::DoClose( USHORT nId )
+{
+ m_aHelper.DoClose(nId);
+ return TRUE;
+}
+
+void ScRefHandler::SetDispatcherLock( BOOL bLock )
+{
+ m_aHelper.SetDispatcherLock( bLock );
+}
+
+//----------------------------------------------------------------------------
+
+void ScRefHandler::ViewShellChanged(ScTabViewShell* pScViewShell )
+{
+ m_aHelper.ViewShellChanged(pScViewShell);
+}
+
+//----------------------------------------------------------------------------
+
+void ScRefHandler::AddRefEntry()
+{
+ // wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen
+}
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScRefHandler::IsTableLocked() const
+{
+ // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
+
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------
+//
+// RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld
+// (per Button oder Bewegung)
+//
+//----------------------------------------------------------------------------
+
+void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ m_aHelper.RefInputStart( pEdit, pButton );
+}
+
+
+void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ m_aHelper.ToggleCollapsed( pEdit, pButton );
+}
+
+//The two following function is commentted out by PengYunQuan for Validity Cell Range Picker
+//long ScAnyRefDlg::PreNotify( NotifyEvent& rNEvt )
+//{
+// USHORT nSwitch=rNEvt.GetType();
+// if(nSwitch==EVENT_GETFOCUS)
+// {
+// pActiveWin=rNEvt.GetWindow();
+// }
+// return SfxModelessDialog::PreNotify(rNEvt);
+//}
+//
+//void ScAnyRefDlg::StateChanged( StateChangedType nStateChange )
+//{
+// SfxModelessDialog::StateChanged( nStateChange );
+//
+// if(nStateChange == STATE_CHANGE_VISIBLE)
+// {
+// if(IsVisible())
+// {
+// m_aHelper.enableInput( FALSE );
+// m_aHelper.EnableSpreadsheets();
+// m_aHelper.SetDispatcherLock( TRUE );
+// aTimer.Start();
+// }
+// else
+// {
+// m_aHelper.enableInput( TRUE );
+// m_aHelper.SetDispatcherLock( FALSE ); //! here and in DoClose ?
+// }
+// }
+//}
+
+#if defined( _MSC_VER )
+#define INTRODUCE_TEMPLATE
+#else
+#define INTRODUCE_TEMPLATE template <>
+#endif
+
+#define IMPL_TWINDOW_PRENOTIFY( TWindow,bBindRef ) \
+INTRODUCE_TEMPLATE long ScRefHdlrImplBase<TWindow,bBindRef>::PreNotify( NotifyEvent& rNEvt )\
+{\
+ if( bBindRef || m_bInRefMode )\
+ {\
+ USHORT nSwitch=rNEvt.GetType();\
+ if(nSwitch==EVENT_GETFOCUS)\
+ {\
+ pActiveWin=rNEvt.GetWindow();\
+ }\
+ }\
+ return TWindow::PreNotify(rNEvt);\
+}
+
+#define IMPL_TWINDOW_STATECHANGED( TWindow,bBindRef ) \
+INTRODUCE_TEMPLATE void ScRefHdlrImplBase<TWindow,bBindRef>::StateChanged( StateChangedType nStateChange )\
+{\
+ TWindow::StateChanged( nStateChange );\
+\
+ if( !bBindRef && !m_bInRefMode ) return;\
+ \
+ if(nStateChange == STATE_CHANGE_VISIBLE)\
+ {\
+ if(m_rWindow.IsVisible())\
+ {\
+ m_aHelper.enableInput( FALSE );\
+ m_aHelper.EnableSpreadsheets();\
+ m_aHelper.SetDispatcherLock( TRUE );\
+ aTimer.Start();\
+ }\
+ else\
+ {\
+ m_aHelper.enableInput( TRUE );\
+ m_aHelper.SetDispatcherLock( FALSE ); /*//! here and in DoClose ?*/\
+ }\
+ }\
+}
+
+IMPL_TWINDOW_PRENOTIFY( SfxModelessDialog, true )
+IMPL_TWINDOW_PRENOTIFY( SfxTabDialog, false )
+IMPL_TWINDOW_STATECHANGED( SfxModelessDialog, true )
+IMPL_TWINDOW_STATECHANGED( SfxTabDialog, false )
+
+IMPL_LINK( ScRefHandler, UpdateFocusHdl, Timer*, EMPTYARG )
+{
+ if (pActiveWin)
+ {
+ pActiveWin->GrabFocus();
+ }
+ return 0;
+}
+// -----------------------------------------------------------------------------
+bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc )
+{
+ return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
+}
+// -----------------------------------------------------------------------------
+void ScRefHandler::HideReference( BOOL bDoneRefMode )
+{
+ m_aHelper.HideReference( bDoneRefMode );
+}
+// -----------------------------------------------------------------------------
+void ScRefHandler::ShowReference( const XubString& rStr )
+{
+ m_aHelper.ShowReference( rStr );
+}
+// -----------------------------------------------------------------------------
+void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton )
+{
+ m_aHelper.ReleaseFocus( pEdit,pButton );
+}
+//----------------------------------------------------------------------------
+void ScRefHandler::RefInputDone( BOOL bForced )
+{
+ m_aHelper.RefInputDone( bForced );
+}
+
diff --git a/sc/source/ui/miscdlgs/autofmt.cxx b/sc/source/ui/miscdlgs/autofmt.cxx
new file mode 100644
index 000000000000..6ce65ab914be
--- /dev/null
+++ b/sc/source/ui/miscdlgs/autofmt.cxx
@@ -0,0 +1,979 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "attrib.hxx"
+#include "zforauto.hxx"
+#include "scitems.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "autoform.hxx"
+//CHINA001 #include "strindlg.hxx"
+#include "miscdlgs.hrc"
+#include "autofmt.hxx"
+#include "scresid.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+
+#define FRAME_OFFSET 4
+
+
+//CHINA001 //========================================================================
+//CHINA001 // AutoFormat-Dialog:
+//CHINA001
+//CHINA001 ScAutoFormatDlg::ScAutoFormatDlg( Window* pParent,
+//CHINA001 ScAutoFormat* pAutoFormat,
+//CHINA001 const ScAutoFormatData* pSelFormatData,
+//CHINA001 ScDocument* pDoc ) :
+//CHINA001
+//CHINA001 ModalDialog ( pParent, ScResId( RID_SCDLG_AUTOFORMAT ) ),
+//CHINA001 //
+//CHINA001 aLbFormat ( this, ScResId( LB_FORMAT ) ),
+//CHINA001 aFlFormat ( this, ScResId( FL_FORMAT ) ),
+//CHINA001 pWndPreview ( new ScAutoFmtPreview( this, ScResId( WND_PREVIEW ), pDoc ) ),
+//CHINA001 aBtnNumFormat ( this, ScResId( BTN_NUMFORMAT ) ),
+//CHINA001 aBtnBorder ( this, ScResId( BTN_BORDER ) ),
+//CHINA001 aBtnFont ( this, ScResId( BTN_FONT ) ),
+//CHINA001 aBtnPattern ( this, ScResId( BTN_PATTERN ) ),
+//CHINA001 aBtnAlignment ( this, ScResId( BTN_ALIGNMENT ) ),
+//CHINA001 aBtnAdjust ( this, ScResId( BTN_ADJUST ) ),
+//CHINA001 aFlFormatting ( this, ScResId( FL_FORMATTING ) ),
+//CHINA001 aBtnOk ( this, ScResId( BTN_OK ) ),
+//CHINA001 aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+//CHINA001 aBtnHelp ( this, ScResId( BTN_HELP ) ),
+//CHINA001 aBtnAdd ( this, ScResId( BTN_ADD ) ),
+//CHINA001 aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+//CHINA001 aBtnMore ( this, ScResId( BTN_MORE ) ),
+//CHINA001 aBtnRename ( this, ScResId( BTN_RENAME ) ),
+//CHINA001 aStrTitle ( ScResId( STR_ADD_TITLE ) ),
+//CHINA001 aStrLabel ( ScResId( STR_ADD_LABEL ) ),
+//CHINA001 aStrRename ( ScResId( STR_RENAME_TITLE ) ),
+//CHINA001 aStrClose ( ScResId( STR_BTN_CLOSE ) ),
+//CHINA001 aStrDelTitle ( ScResId( STR_DEL_TITLE ) ),
+//CHINA001 aStrDelMsg ( ScResId( STR_DEL_MSG ) ) ,
+//CHINA001 //
+//CHINA001 nIndex ( 0 ),
+//CHINA001 bFmtInserted ( FALSE ),
+//CHINA001 bCoreDataChanged( FALSE ),
+//CHINA001 pFormat ( pAutoFormat ),
+//CHINA001 pSelFmtData ( pSelFormatData )
+//CHINA001 {
+//CHINA001 Init();
+//CHINA001 pWndPreview->NotifyChange( (*pFormat)[0] );
+//CHINA001 FreeResource();
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 ScAutoFormatDlg::~ScAutoFormatDlg()
+//CHINA001 {
+//CHINA001 delete pWndPreview;
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 void ScAutoFormatDlg::Init()
+//CHINA001 {
+//CHINA001 USHORT nCount;
+//CHINA001 String aEntry;
+//CHINA001
+//CHINA001 aLbFormat .SetSelectHdl( LINK( this, ScAutoFormatDlg, SelFmtHdl ) );
+//CHINA001 aBtnNumFormat.SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+//CHINA001 aBtnBorder .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+//CHINA001 aBtnFont .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+//CHINA001 aBtnPattern .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+//CHINA001 aBtnAlignment.SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+//CHINA001 aBtnAdjust .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+//CHINA001 aBtnAdd .SetClickHdl ( LINK( this, ScAutoFormatDlg, AddHdl ) );
+//CHINA001 aBtnRemove .SetClickHdl ( LINK( this, ScAutoFormatDlg, RemoveHdl ) );
+//CHINA001 aBtnOk .SetClickHdl ( LINK( this, ScAutoFormatDlg, CloseHdl ) );
+//CHINA001 aBtnCancel .SetClickHdl ( LINK( this, ScAutoFormatDlg, CloseHdl ) );
+//CHINA001 aBtnRename .SetClickHdl ( LINK( this, ScAutoFormatDlg, RenameHdl ) );
+//CHINA001 aLbFormat .SetDoubleClickHdl( LINK( this, ScAutoFormatDlg, DblClkHdl ) );
+//CHINA001
+//CHINA001 aBtnMore.AddWindow( &aBtnRename );
+//CHINA001 aBtnMore.AddWindow( &aBtnNumFormat );
+//CHINA001 aBtnMore.AddWindow( &aBtnBorder );
+//CHINA001 aBtnMore.AddWindow( &aBtnFont );
+//CHINA001 aBtnMore.AddWindow( &aBtnPattern );
+//CHINA001 aBtnMore.AddWindow( &aBtnAlignment );
+//CHINA001 aBtnMore.AddWindow( &aBtnAdjust );
+//CHINA001 aBtnMore.AddWindow( &aFlFormatting );
+//CHINA001
+//CHINA001 nCount = pFormat->GetCount();
+//CHINA001
+//CHINA001 for ( USHORT i = 0; i < nCount; i++ )
+//CHINA001 {
+//CHINA001 ((*pFormat)[i])->GetName( aEntry );
+//CHINA001 aLbFormat.InsertEntry( aEntry );
+//CHINA001 }
+//CHINA001
+//CHINA001 if ( nCount == 1 )
+//CHINA001 aBtnRemove.Disable();
+//CHINA001
+//CHINA001 aLbFormat.SelectEntryPos( 0 );
+//CHINA001 aBtnRename.Disable();
+//CHINA001 aBtnRemove.Disable();
+//CHINA001
+//CHINA001 nIndex = 0;
+//CHINA001 UpdateChecks();
+//CHINA001
+//CHINA001 if ( !pSelFmtData )
+//CHINA001 {
+//CHINA001 aBtnAdd.Disable();
+//CHINA001 aBtnRemove.Disable();
+//CHINA001 bFmtInserted = TRUE;
+//CHINA001 }
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 void ScAutoFormatDlg::UpdateChecks()
+//CHINA001 {
+//CHINA001 ScAutoFormatData* pData = (*pFormat)[nIndex];
+//CHINA001
+//CHINA001 aBtnNumFormat.Check( pData->GetIncludeValueFormat() );
+//CHINA001 aBtnBorder .Check( pData->GetIncludeFrame() );
+//CHINA001 aBtnFont .Check( pData->GetIncludeFont() );
+//CHINA001 aBtnPattern .Check( pData->GetIncludeBackground() );
+//CHINA001 aBtnAlignment.Check( pData->GetIncludeJustify() );
+//CHINA001 aBtnAdjust .Check( pData->GetIncludeWidthHeight() );
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001 // Handler:
+//CHINA001 //---------
+//CHINA001
+//CHINA001 IMPL_LINK( ScAutoFormatDlg, CloseHdl, PushButton *, pBtn )
+//CHINA001 {
+//CHINA001 if ( pBtn == &aBtnOk || pBtn == &aBtnCancel )
+//CHINA001 {
+//CHINA001 if ( bCoreDataChanged )
+//CHINA001 ScGlobal::GetAutoFormat()->Save();
+//CHINA001
+//CHINA001 EndDialog( (pBtn == &aBtnOk) ? RET_OK : RET_CANCEL );
+//CHINA001 }
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 IMPL_LINK_INLINE_START( ScAutoFormatDlg, DblClkHdl, void *, EMPTYARG )
+//CHINA001 {
+//CHINA001 if ( bCoreDataChanged )
+//CHINA001 ScGlobal::GetAutoFormat()->Save();
+//CHINA001
+//CHINA001 EndDialog( RET_OK );
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001 IMPL_LINK_INLINE_END( ScAutoFormatDlg, DblClkHdl, void *, EMPTYARG )
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 IMPL_LINK( ScAutoFormatDlg, CheckHdl, Button *, pBtn )
+//CHINA001 {
+//CHINA001 ScAutoFormatData* pData = (*pFormat)[nIndex];
+//CHINA001 BOOL bCheck = ((CheckBox*)pBtn)->IsChecked();
+//CHINA001
+//CHINA001 if ( pBtn == &aBtnNumFormat )
+//CHINA001 pData->SetIncludeValueFormat( bCheck );
+//CHINA001 else if ( pBtn == &aBtnBorder )
+//CHINA001 pData->SetIncludeFrame( bCheck );
+//CHINA001 else if ( pBtn == &aBtnFont )
+//CHINA001 pData->SetIncludeFont( bCheck );
+//CHINA001 else if ( pBtn == &aBtnPattern )
+//CHINA001 pData->SetIncludeBackground( bCheck );
+//CHINA001 else if ( pBtn == &aBtnAlignment )
+//CHINA001 pData->SetIncludeJustify( bCheck );
+//CHINA001 else if ( pBtn == &aBtnAdjust )
+//CHINA001 pData->SetIncludeWidthHeight( bCheck );
+//CHINA001
+//CHINA001 if ( !bCoreDataChanged )
+//CHINA001 {
+//CHINA001 aBtnCancel.SetText( aStrClose );
+//CHINA001 bCoreDataChanged = TRUE;
+//CHINA001 }
+//CHINA001
+//CHINA001 pWndPreview->NotifyChange( pData );
+//CHINA001
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 IMPL_LINK( ScAutoFormatDlg, AddHdl, void *, EMPTYARG )
+//CHINA001 {
+//CHINA001 if ( !bFmtInserted && pSelFmtData )
+//CHINA001 {
+//CHINA001 String aStrStandard( ScResId(STR_STANDARD) );
+//CHINA001 String aFormatName;
+//CHINA001 ScStringInputDlg* pDlg;
+//CHINA001 BOOL bOk = FALSE;
+//CHINA001
+//CHINA001 while ( !bOk )
+//CHINA001 {
+//CHINA001 pDlg = new ScStringInputDlg( this,
+//CHINA001 aStrTitle,
+//CHINA001 aStrLabel,
+//CHINA001 aFormatName,
+//CHINA001 HID_SC_ADD_AUTOFMT );
+//CHINA001
+//CHINA001 if ( pDlg->Execute() == RET_OK )
+//CHINA001 {
+//CHINA001 pDlg->GetInputString( aFormatName );
+//CHINA001
+//CHINA001 if ( (aFormatName.Len() > 0) && (aFormatName != aStrStandard) )
+//CHINA001 {
+//CHINA001 ScAutoFormatData* pNewData
+//CHINA001 = new ScAutoFormatData( *pSelFmtData );
+//CHINA001
+//CHINA001 pNewData->SetName( aFormatName );
+//CHINA001 bFmtInserted = pFormat->Insert( pNewData );
+//CHINA001
+//CHINA001 if ( bFmtInserted )
+//CHINA001 {
+//CHINA001 USHORT nAt = pFormat->IndexOf( pNewData );
+//CHINA001
+//CHINA001 aLbFormat.InsertEntry( aFormatName, nAt );
+//CHINA001 aLbFormat.SelectEntry( aFormatName );
+//CHINA001 aBtnAdd.Disable();
+//CHINA001
+//CHINA001 if ( !bCoreDataChanged )
+//CHINA001 {
+//CHINA001 aBtnCancel.SetText( aStrClose );
+//CHINA001 bCoreDataChanged = TRUE;
+//CHINA001 }
+//CHINA001
+//CHINA001 SelFmtHdl( 0 );
+//CHINA001 bOk = TRUE;
+//CHINA001 }
+//CHINA001 else
+//CHINA001 delete pNewData;
+//CHINA001
+//CHINA001 }
+//CHINA001
+//CHINA001 if ( !bFmtInserted )
+//CHINA001 {
+//CHINA001 USHORT nRet = ErrorBox( this,
+//CHINA001 WinBits( WB_OK_CANCEL | WB_DEF_OK),
+//CHINA001 ScGlobal::GetRscString(STR_INVALID_AFNAME)
+//CHINA001 ).Execute();
+//CHINA001
+//CHINA001 bOk = ( nRet == RET_CANCEL );
+//CHINA001 }
+//CHINA001 }
+//CHINA001 else
+//CHINA001 bOk = TRUE;
+//CHINA001
+//CHINA001 delete pDlg;
+//CHINA001 }
+//CHINA001 }
+//CHINA001
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 IMPL_LINK( ScAutoFormatDlg, RemoveHdl, void *, EMPTYARG )
+//CHINA001 {
+//CHINA001 if ( (nIndex > 0) && (aLbFormat.GetEntryCount() > 0) )
+//CHINA001 {
+//CHINA001 String aMsg( aStrDelMsg.GetToken( 0, '#' ) );
+//CHINA001
+//CHINA001 aMsg += aLbFormat.GetSelectEntry();
+//CHINA001 aMsg += aStrDelMsg.GetToken( 1, '#' );
+//CHINA001
+//CHINA001 if ( RET_YES ==
+//CHINA001 QueryBox( this, WinBits( WB_YES_NO | WB_DEF_YES ), aMsg ).Execute() )
+//CHINA001 {
+//CHINA001 aLbFormat.RemoveEntry( nIndex );
+//CHINA001 aLbFormat.SelectEntryPos( nIndex-1 );
+//CHINA001
+//CHINA001 if ( nIndex-1 == 0 )
+//CHINA001 aBtnRemove.Disable();
+//CHINA001
+//CHINA001 if ( !bCoreDataChanged )
+//CHINA001 {
+//CHINA001 aBtnCancel.SetText( aStrClose );
+//CHINA001 bCoreDataChanged = TRUE;
+//CHINA001 }
+//CHINA001
+//CHINA001 pFormat->AtFree( nIndex ); // in der Core loeschen
+//CHINA001 nIndex--;
+//CHINA001
+//CHINA001 SelFmtHdl( 0 );
+//CHINA001 }
+//CHINA001 }
+//CHINA001
+//CHINA001 SelFmtHdl( 0 );
+//CHINA001
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 IMPL_LINK( ScAutoFormatDlg, RenameHdl, void *, pBtn)
+//CHINA001 {
+//CHINA001 BOOL bOk = FALSE;
+//CHINA001 while( !bOk )
+//CHINA001 {
+//CHINA001
+//CHINA001 String aFormatName=aLbFormat.GetSelectEntry();
+//CHINA001 String aEntry;
+//CHINA001
+//CHINA001 ScStringInputDlg* pDlg = new ScStringInputDlg( this,
+//CHINA001 aStrRename,
+//CHINA001 aStrLabel,
+//CHINA001 aFormatName,
+//CHINA001 HID_SC_RENAME_AUTOFMT );
+//CHINA001 if( pDlg->Execute() == RET_OK )
+//CHINA001 {
+//CHINA001 BOOL bFmtRenamed = FALSE;
+//CHINA001 pDlg->GetInputString( aFormatName );
+//CHINA001 USHORT n;
+//CHINA001
+//CHINA001 if ( aFormatName.Len() > 0 )
+//CHINA001 {
+//CHINA001 for( n = 0; n < pFormat->GetCount(); ++n )
+//CHINA001 {
+//CHINA001 (*pFormat)[n]->GetName(aEntry);
+//CHINA001 if ( aEntry== aFormatName)
+//CHINA001 break;
+//CHINA001 }
+//CHINA001 if( n >= pFormat->GetCount() )
+//CHINA001 {
+//CHINA001 // Format mit dem Namen noch nicht vorhanden, also
+//CHINA001 // umbenennen
+//CHINA001
+//CHINA001 aLbFormat.RemoveEntry(nIndex );
+//CHINA001 ScAutoFormatData* p=(*pFormat)[ nIndex ];
+//CHINA001 ScAutoFormatData* pNewData
+//CHINA001 = new ScAutoFormatData(*p);
+//CHINA001
+//CHINA001 pFormat->AtFree( nIndex );
+//CHINA001
+//CHINA001 pNewData->SetName( aFormatName );
+//CHINA001
+//CHINA001 pFormat->Insert( pNewData);
+//CHINA001
+//CHINA001 USHORT nCount = pFormat->GetCount();
+//CHINA001
+//CHINA001 aLbFormat.SetUpdateMode(FALSE);
+//CHINA001 aLbFormat.Clear();
+//CHINA001 for ( USHORT i = 0; i < nCount; i++ )
+//CHINA001 {
+//CHINA001 ((*pFormat)[i])->GetName( aEntry );
+//CHINA001 aLbFormat.InsertEntry( aEntry );
+//CHINA001 }
+//CHINA001
+//CHINA001 aLbFormat.SetUpdateMode( TRUE);
+//CHINA001 aLbFormat.SelectEntry( aFormatName);
+//CHINA001
+//CHINA001 if ( !bCoreDataChanged )
+//CHINA001 {
+//CHINA001 aBtnCancel.SetText( aStrClose );
+//CHINA001 bCoreDataChanged = TRUE;
+//CHINA001 }
+//CHINA001
+//CHINA001
+//CHINA001 SelFmtHdl( 0 );
+//CHINA001 bOk = TRUE;
+//CHINA001 bFmtRenamed = TRUE;
+//CHINA001 }
+//CHINA001 }
+//CHINA001 if( !bFmtRenamed )
+//CHINA001 {
+//CHINA001 bOk = RET_CANCEL == ErrorBox( this,
+//CHINA001 WinBits( WB_OK_CANCEL | WB_DEF_OK),
+//CHINA001 ScGlobal::GetRscString(STR_INVALID_AFNAME)
+//CHINA001 ).Execute();
+//CHINA001 }
+//CHINA001 }
+//CHINA001 else
+//CHINA001 bOk = TRUE;
+//CHINA001 delete pDlg;
+//CHINA001 }
+//CHINA001
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 IMPL_LINK( ScAutoFormatDlg, SelFmtHdl, void *, EMPTYARG )
+//CHINA001 {
+//CHINA001 nIndex = aLbFormat.GetSelectEntryPos();
+//CHINA001 UpdateChecks();
+//CHINA001
+//CHINA001 if ( nIndex == 0 )
+//CHINA001 {
+//CHINA001 aBtnRename.Disable();
+//CHINA001 aBtnRemove.Disable();
+//CHINA001 }
+//CHINA001 else
+//CHINA001 {
+//CHINA001 aBtnRename.Enable();
+//CHINA001 aBtnRemove.Enable();
+//CHINA001 }
+//CHINA001
+//CHINA001 pWndPreview->NotifyChange( (*pFormat)[nIndex] );
+//CHINA001
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 //------------------------------------------------------------------------
+//CHINA001
+//CHINA001 String ScAutoFormatDlg::GetCurrFormatName()
+//CHINA001 {
+//CHINA001 String aResult;
+//CHINA001
+//CHINA001 ((*pFormat)[nIndex])->GetName( aResult );
+//CHINA001
+//CHINA001 return aResult;
+//CHINA001 }
+//CHINA001
+//========================================================================
+// ScAutoFmtPreview
+
+ScAutoFmtPreview::ScAutoFmtPreview( Window* pParent, const ResId& rRes, ScDocument* pDoc ) :
+ Window ( pParent, rRes ),
+ pCurData ( NULL ),
+ aVD ( *this ),
+ aScriptedText ( aVD ),
+ xBreakIter ( pDoc->GetBreakIterator() ),
+ bFitWidth ( FALSE ),
+ mbRTL ( false ),
+ aPrvSize ( GetSizePixel().Width() - 6, GetSizePixel().Height() - 30 ),
+ mnLabelColWidth ( (aPrvSize.Width() - 4) / 4 - 12 ),
+ mnDataColWidth1 ( (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 3 ),
+ mnDataColWidth2 ( (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 4 ),
+ mnRowHeight ( (aPrvSize.Height() - 4) / 5 ),
+ aStrJan ( ScResId( STR_JAN ) ),
+ aStrFeb ( ScResId( STR_FEB ) ),
+ aStrMar ( ScResId( STR_MAR ) ),
+ aStrNorth ( ScResId( STR_NORTH ) ),
+ aStrMid ( ScResId( STR_MID ) ),
+ aStrSouth ( ScResId( STR_SOUTH ) ),
+ aStrSum ( ScResId( STR_SUM ) ),
+ pNumFmt ( new SvNumberFormatter( ::comphelper::getProcessServiceFactory(), ScGlobal::eLnge ) )
+{
+ Init();
+}
+
+//------------------------------------------------------------------------
+
+ScAutoFmtPreview::~ScAutoFmtPreview()
+{
+ delete pNumFmt;
+}
+
+//------------------------------------------------------------------------
+
+void lcl_SetFontProperties(
+ Font& rFont,
+ const SvxFontItem& rFontItem,
+ const SvxWeightItem& rWeightItem,
+ const SvxPostureItem& rPostureItem )
+{
+ rFont.SetFamily ( rFontItem.GetFamily() );
+ rFont.SetName ( rFontItem.GetFamilyName() );
+ rFont.SetStyleName ( rFontItem.GetStyleName() );
+ rFont.SetCharSet ( rFontItem.GetCharSet() );
+ rFont.SetPitch ( rFontItem.GetPitch() );
+ rFont.SetWeight ( (FontWeight)rWeightItem.GetValue() );
+ rFont.SetItalic ( (FontItalic)rPostureItem.GetValue() );
+}
+
+void ScAutoFmtPreview::MakeFonts( USHORT nIndex, Font& rFont, Font& rCJKFont, Font& rCTLFont )
+{
+ if ( pCurData )
+ {
+ rFont = rCJKFont = rCTLFont = GetFont();
+ Size aFontSize( rFont.GetSize().Width(), 10 );
+
+ const SvxFontItem* pFontItem = (const SvxFontItem*) pCurData->GetItem( nIndex, ATTR_FONT );
+ const SvxWeightItem* pWeightItem = (const SvxWeightItem*) pCurData->GetItem( nIndex, ATTR_FONT_WEIGHT );
+ const SvxPostureItem* pPostureItem = (const SvxPostureItem*) pCurData->GetItem( nIndex, ATTR_FONT_POSTURE );
+ const SvxFontItem* pCJKFontItem = (const SvxFontItem*) pCurData->GetItem( nIndex, ATTR_CJK_FONT );
+ const SvxWeightItem* pCJKWeightItem = (const SvxWeightItem*) pCurData->GetItem( nIndex, ATTR_CJK_FONT_WEIGHT );
+ const SvxPostureItem* pCJKPostureItem = (const SvxPostureItem*) pCurData->GetItem( nIndex, ATTR_CJK_FONT_POSTURE );
+ const SvxFontItem* pCTLFontItem = (const SvxFontItem*) pCurData->GetItem( nIndex, ATTR_CTL_FONT );
+ const SvxWeightItem* pCTLWeightItem = (const SvxWeightItem*) pCurData->GetItem( nIndex, ATTR_CTL_FONT_WEIGHT );
+ const SvxPostureItem* pCTLPostureItem = (const SvxPostureItem*) pCurData->GetItem( nIndex, ATTR_CTL_FONT_POSTURE );
+ const SvxUnderlineItem* pUnderlineItem = (const SvxUnderlineItem*) pCurData->GetItem( nIndex, ATTR_FONT_UNDERLINE );
+ const SvxOverlineItem* pOverlineItem = (const SvxOverlineItem*) pCurData->GetItem( nIndex, ATTR_FONT_OVERLINE );
+ const SvxCrossedOutItem* pCrossedOutItem = (const SvxCrossedOutItem*)pCurData->GetItem( nIndex, ATTR_FONT_CROSSEDOUT );
+ const SvxContourItem* pContourItem = (const SvxContourItem*) pCurData->GetItem( nIndex, ATTR_FONT_CONTOUR );
+ const SvxShadowedItem* pShadowedItem = (const SvxShadowedItem*) pCurData->GetItem( nIndex, ATTR_FONT_SHADOWED );
+ const SvxColorItem* pColorItem = (const SvxColorItem*) pCurData->GetItem( nIndex, ATTR_FONT_COLOR );
+
+ lcl_SetFontProperties( rFont, *pFontItem, *pWeightItem, *pPostureItem );
+ lcl_SetFontProperties( rCJKFont, *pCJKFontItem, *pCJKWeightItem, *pCJKPostureItem );
+ lcl_SetFontProperties( rCTLFont, *pCTLFontItem, *pCTLWeightItem, *pCTLPostureItem );
+
+ Color aColor( pColorItem->GetValue() );
+ if( aColor.GetColor() == COL_TRANSPARENT )
+ aColor = GetSettings().GetStyleSettings().GetWindowTextColor();
+
+#define SETONALLFONTS( MethodName, Value ) \
+rFont.MethodName( Value ); rCJKFont.MethodName( Value ); rCTLFont.MethodName( Value );
+
+ SETONALLFONTS( SetUnderline, (FontUnderline)pUnderlineItem->GetValue() )
+ SETONALLFONTS( SetOverline, (FontUnderline)pOverlineItem->GetValue() )
+ SETONALLFONTS( SetStrikeout, (FontStrikeout)pCrossedOutItem->GetValue() )
+ SETONALLFONTS( SetOutline, pContourItem->GetValue() )
+ SETONALLFONTS( SetShadow, pShadowedItem->GetValue() )
+ SETONALLFONTS( SetColor, aColor )
+ SETONALLFONTS( SetSize, aFontSize )
+ SETONALLFONTS( SetTransparent, TRUE )
+
+#undef SETONALLFONTS
+ }
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScAutoFmtPreview::GetFormatIndex( size_t nCol, size_t nRow ) const
+{
+ static const USHORT pnFmtMap[] =
+ {
+ 0, 1, 2, 1, 3,
+ 4, 5, 6, 5, 7,
+ 8, 9, 10, 9, 11,
+ 4, 5, 6, 5, 7,
+ 12, 13, 14, 13, 15
+ };
+ return pnFmtMap[ maArray.GetCellIndex( nCol, nRow, mbRTL ) ];
+}
+
+const SvxBoxItem& ScAutoFmtPreview::GetBoxItem( size_t nCol, size_t nRow ) const
+{
+ DBG_ASSERT( pCurData, "ScAutoFmtPreview::GetBoxItem - no format data found" );
+ return *static_cast< const SvxBoxItem* >( pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BORDER ) );
+}
+
+const SvxLineItem& ScAutoFmtPreview::GetDiagItem( size_t nCol, size_t nRow, bool bTLBR ) const
+{
+ DBG_ASSERT( pCurData, "ScAutoFmtPreview::GetDiagItem - no format data found" );
+ return *static_cast< const SvxLineItem* >( pCurData->GetItem( GetFormatIndex( nCol, nRow ), bTLBR ? ATTR_BORDER_TLBR : ATTR_BORDER_BLTR ) );
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::DrawString( size_t nCol, size_t nRow )
+{
+ if ( pCurData )
+ {
+ //------------------------
+ // Ausgabe des Zelltextes:
+ //------------------------
+
+ String cellString;
+ BOOL bNumFormat = pCurData->GetIncludeValueFormat();
+ ULONG nNum;
+ double nVal;
+ Color* pDummy = NULL;
+ USHORT nIndex = static_cast< USHORT >( maArray.GetCellIndex( nCol, nRow, mbRTL ) );
+
+ switch( nIndex )
+ {
+ case 1: cellString = aStrJan; break;
+ case 2: cellString = aStrFeb; break;
+ case 3: cellString = aStrMar; break;
+ case 5: cellString = aStrNorth; break;
+ case 10: cellString = aStrMid; break;
+ case 15: cellString = aStrSouth; break;
+ case 4:
+ case 20: cellString = aStrSum; break;
+
+ case 6:
+ case 8:
+ case 16:
+ case 18: nVal = nIndex;
+ nNum = 5;
+ goto mknum;
+ case 17:
+ case 7: nVal = nIndex;
+ nNum = 6;
+ goto mknum;
+ case 11:
+ case 12:
+ case 13: nVal = nIndex;
+ nNum = 12 == nIndex ? 10 : 9;
+ goto mknum;
+
+ case 9: nVal = 21; nNum = 7; goto mknum;
+ case 14: nVal = 36; nNum = 11; goto mknum;
+ case 19: nVal = 51; nNum = 7; goto mknum;
+ case 21: nVal = 33; nNum = 13; goto mknum;
+ case 22: nVal = 36; nNum = 14; goto mknum;
+ case 23: nVal = 39; nNum = 13; goto mknum;
+ case 24: nVal = 108; nNum = 15;
+ mknum:
+ if( bNumFormat )
+ {
+ ScNumFormatAbbrev& rNumFormat = (ScNumFormatAbbrev&)pCurData->GetNumFormat( (USHORT) nNum );
+ nNum = rNumFormat.GetFormatIndex( *pNumFmt );
+ }
+ else
+ nNum = 0;
+ pNumFmt->GetOutputString( nVal, nNum, cellString, &pDummy );
+ break;
+ }
+
+ if ( cellString.Len() > 0 )
+ {
+ Size aStrSize;
+ USHORT nFmtIndex = GetFormatIndex( nCol, nRow );
+ Rectangle cellRect = maArray.GetCellRect( nCol, nRow );
+ Point aPos = cellRect.TopLeft();
+ USHORT nRightX = 0;
+ BOOL bJustify = pCurData->GetIncludeJustify();
+ SvxHorJustifyItem aHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY );
+ SvxCellHorJustify eJustification;
+
+ //-------------
+ // Ausrichtung:
+ //-------------
+ eJustification = mbRTL ? SVX_HOR_JUSTIFY_RIGHT : bJustify ?
+ (SvxCellHorJustify)(((const SvxHorJustifyItem*)pCurData->GetItem( nFmtIndex, ATTR_HOR_JUSTIFY ))->GetValue()) :
+ SVX_HOR_JUSTIFY_STANDARD;
+
+ if ( pCurData->GetIncludeFont() )
+ {
+ Font aFont, aCJKFont, aCTLFont;
+ Size theMaxStrSize;
+
+ MakeFonts( nFmtIndex, aFont, aCJKFont, aCTLFont );
+
+ theMaxStrSize = cellRect.GetSize();
+ theMaxStrSize.Width() -= FRAME_OFFSET;
+ theMaxStrSize.Height() -= FRAME_OFFSET;
+
+ aScriptedText.SetFonts( &aFont, &aCJKFont, &aCTLFont );
+ aScriptedText.SetText( cellString, xBreakIter );
+ aStrSize = aScriptedText.GetTextSize();
+
+ if ( theMaxStrSize.Height() < aStrSize.Height() )
+ {
+ // wenn der String in diesem Font nicht
+ // in die Zelle passt, wird wieder der
+ // Standard-Font genommen:
+ aScriptedText.SetDefaultFont();
+ aStrSize = aScriptedText.GetTextSize();
+ }
+ while ( ( theMaxStrSize.Width() <= aStrSize.Width() )
+ && ( cellString.Len() > 1 ) )
+ {
+ if( eJustification == SVX_HOR_JUSTIFY_RIGHT )
+ cellString.Erase( 0, 1 );
+ else
+ cellString.Erase( cellString.Len() - 1 );
+
+ aScriptedText.SetText( cellString, xBreakIter );
+ aStrSize = aScriptedText.GetTextSize();
+ }
+ }
+ else
+ {
+ aScriptedText.SetDefaultFont();
+ aScriptedText.SetText( cellString, xBreakIter );
+ aStrSize = aScriptedText.GetTextSize();
+ }
+
+ nRightX = (USHORT)( cellRect.GetWidth()
+ - aStrSize.Width()
+ - FRAME_OFFSET );
+
+ //-----------------------------
+ // vertikal (immer zentrieren):
+ //-----------------------------
+ aPos.Y() += (mnRowHeight - (USHORT)aStrSize.Height()) / 2;
+
+ //-----------
+ // horizontal
+ //-----------
+ if ( eJustification != SVX_HOR_JUSTIFY_STANDARD )
+ {
+ USHORT nHorPos = (USHORT)
+ ((cellRect.GetWidth()-aStrSize.Width())/2);
+
+ switch ( eJustification )
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ aPos.X() += FRAME_OFFSET;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ aPos.X() += nRightX;
+ break;
+ case SVX_HOR_JUSTIFY_BLOCK:
+ case SVX_HOR_JUSTIFY_REPEAT:
+ case SVX_HOR_JUSTIFY_CENTER:
+ aPos.X() += nHorPos;
+ break;
+ case SVX_HOR_JUSTIFY_STANDARD:
+ default:
+ // Standard wird hier nicht behandelt
+ break;
+ }
+ }
+ else
+ {
+ //---------------------
+ // Standardausrichtung:
+ //---------------------
+ if ( (nCol == 0) || (nRow == 0) )
+ {
+ // Text-Label links oder Summe linksbuendig
+ aPos.X() += FRAME_OFFSET;
+ }
+ else
+ {
+ // Zahlen/Datum rechtsbuendig
+ aPos.X() += nRightX;
+ }
+ }
+
+ //-------------------------------
+ aScriptedText.DrawText( aPos );
+ //-------------------------------
+ }
+ }
+}
+
+#undef FRAME_OFFSET
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::DrawStrings()
+{
+ for( size_t nRow = 0; nRow < 5; ++nRow )
+ for( size_t nCol = 0; nCol < 5; ++nCol )
+ DrawString( nCol, nRow );
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::DrawBackground()
+{
+ if( pCurData )
+ {
+ for( size_t nRow = 0; nRow < 5; ++nRow )
+ {
+ for( size_t nCol = 0; nCol < 5; ++nCol )
+ {
+ const SvxBrushItem* pItem = static_cast< const SvxBrushItem* >(
+ pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BACKGROUND ) );
+
+ aVD.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ aVD.SetLineColor();
+ aVD.SetFillColor( pItem->GetColor() );
+ aVD.DrawRect( maArray.GetCellRect( nCol, nRow ) );
+ aVD.Pop();
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::PaintCells()
+{
+ if ( pCurData )
+ {
+ // 1) background
+ if ( pCurData->GetIncludeBackground() )
+ DrawBackground();
+
+ // 2) values
+ DrawStrings();
+
+ // 3) border
+ if ( pCurData->GetIncludeFrame() )
+ maArray.DrawArray( aVD );
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::Init()
+{
+ SetBorderStyle( WINDOW_BORDER_MONO );
+ maArray.Initialize( 5, 5 );
+ maArray.SetUseDiagDoubleClipping( false );
+ CalcCellArray( FALSE );
+ CalcLineMap();
+
+ TypeId aType(TYPE(ScDocShell));
+ ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
+ SfxViewShell* p = pFrame->GetViewShell();
+ ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell* >( p );
+ ScViewData* pViewData = pViewSh->GetViewData();
+ SCTAB nCurrentTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+ mbRTL = pDoc->IsLayoutRTL( nCurrentTab );
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::CalcCellArray( BOOL bFitWidthP )
+{
+ maArray.SetXOffset( 2 );
+ maArray.SetAllColWidths( bFitWidthP ? mnDataColWidth2 : mnDataColWidth1 );
+ maArray.SetColWidth( 0, mnLabelColWidth );
+ maArray.SetColWidth( 4, mnLabelColWidth );
+
+ maArray.SetYOffset( 2 );
+ maArray.SetAllRowHeights( mnRowHeight );
+
+ aPrvSize.Width() = maArray.GetWidth() + 4;
+ aPrvSize.Height() = maArray.GetHeight() + 4;
+}
+
+//------------------------------------------------------------------------
+
+inline void lclSetStyleFromBorder( svx::frame::Style& rStyle, const SvxBorderLine* pBorder )
+{
+ rStyle.Set( pBorder, 1.0 / TWIPS_PER_POINT, 5 );
+}
+
+void ScAutoFmtPreview::CalcLineMap()
+{
+ if ( pCurData )
+ {
+ for( size_t nRow = 0; nRow < 5; ++nRow )
+ {
+ for( size_t nCol = 0; nCol < 5; ++nCol )
+ {
+ svx::frame::Style aStyle;
+
+ const SvxBoxItem& rItem = GetBoxItem( nCol, nRow );
+ lclSetStyleFromBorder( aStyle, rItem.GetLeft() );
+ maArray.SetCellStyleLeft( nCol, nRow, aStyle );
+ lclSetStyleFromBorder( aStyle, rItem.GetRight() );
+ maArray.SetCellStyleRight( nCol, nRow, aStyle );
+ lclSetStyleFromBorder( aStyle, rItem.GetTop() );
+ maArray.SetCellStyleTop( nCol, nRow, aStyle );
+ lclSetStyleFromBorder( aStyle, rItem.GetBottom() );
+ maArray.SetCellStyleBottom( nCol, nRow, aStyle );
+
+ lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
+ maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
+ lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
+ maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::NotifyChange( ScAutoFormatData* pNewData )
+{
+ if ( pNewData != pCurData )
+ {
+ pCurData = pNewData;
+ bFitWidth = pNewData->GetIncludeWidthHeight();
+ CalcCellArray( bFitWidth );
+ CalcLineMap();
+ }
+ else if ( bFitWidth != pNewData->GetIncludeWidthHeight() )
+ {
+ bFitWidth = !bFitWidth;
+ CalcCellArray( bFitWidth );
+ }
+
+ DoPaint( Rectangle( Point(0,0), GetSizePixel() ) );
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::DoPaint( const Rectangle& /* rRect */ )
+{
+ sal_uInt32 nOldDrawMode = aVD.GetDrawMode();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ if( GetSettings().GetStyleSettings().GetHighContrastMode() )
+ aVD.SetDrawMode( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
+
+ Size aWndSize( GetSizePixel() );
+ Font aFont( aVD.GetFont() );
+ Color aBackCol( GetSettings().GetStyleSettings().GetWindowColor() );
+ Point aTmpPoint;
+ Rectangle aRect( aTmpPoint, aWndSize );
+
+ aFont.SetTransparent( TRUE );
+ aVD.SetFont( aFont );
+ aVD.SetLineColor();
+ aVD.SetFillColor( aBackCol );
+ aVD.SetOutputSize( aWndSize );
+ aVD.DrawRect( aRect );
+
+ PaintCells();
+ SetLineColor();
+ SetFillColor( aBackCol );
+ DrawRect( aRect );
+
+ Point aPos( (aWndSize.Width() - aPrvSize.Width()) / 2, (aWndSize.Height() - aPrvSize.Height()) / 2 );
+ if (Application::GetSettings().GetLayoutRTL())
+ aPos.X() = -aPos.X();
+ DrawOutDev( aPos, aWndSize, Point(), aWndSize, aVD );
+
+ aVD.SetDrawMode( nOldDrawMode );
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFmtPreview::Paint( const Rectangle& rRect )
+{
+ DoPaint( rRect );
+}
+
diff --git a/sc/source/ui/miscdlgs/conflictsdlg.cxx b/sc/source/ui/miscdlgs/conflictsdlg.cxx
new file mode 100644
index 000000000000..89f818e21928
--- /dev/null
+++ b/sc/source/ui/miscdlgs/conflictsdlg.cxx
@@ -0,0 +1,894 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/msgbox.hxx>
+
+#include "conflictsdlg.hxx"
+#include "conflictsdlg.hrc"
+#include "scresid.hxx"
+#include "viewdata.hxx"
+#include "dbfunc.hxx"
+
+
+//=============================================================================
+// struct ScConflictsListEntry
+//=============================================================================
+
+bool ScConflictsListEntry::HasSharedAction( ULONG nSharedAction ) const
+{
+ ScChangeActionList::const_iterator aEnd = maSharedActions.end();
+ for ( ScChangeActionList::const_iterator aItr = maSharedActions.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( *aItr == nSharedAction )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ScConflictsListEntry::HasOwnAction( ULONG nOwnAction ) const
+{
+ ScChangeActionList::const_iterator aEnd = maOwnActions.end();
+ for ( ScChangeActionList::const_iterator aItr = maOwnActions.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( *aItr == nOwnAction )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+//=============================================================================
+// class ScConflictsListHelper
+//=============================================================================
+
+//UNUSED2008-05 bool ScConflictsListHelper::HasSharedAction( ScConflictsList& rConflictsList, ULONG nSharedAction )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScConflictsList::const_iterator aEnd = rConflictsList.end();
+//UNUSED2008-05 for ( ScConflictsList::const_iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aItr->HasSharedAction( nSharedAction ) )
+//UNUSED2008-05 {
+//UNUSED2008-05 return true;
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return false;
+//UNUSED2008-05 }
+
+bool ScConflictsListHelper::HasOwnAction( ScConflictsList& rConflictsList, ULONG nOwnAction )
+{
+ ScConflictsList::const_iterator aEnd = rConflictsList.end();
+ for ( ScConflictsList::const_iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( aItr->HasOwnAction( nOwnAction ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+ScConflictsListEntry* ScConflictsListHelper::GetSharedActionEntry( ScConflictsList& rConflictsList, ULONG nSharedAction )
+{
+ ScConflictsList::iterator aEnd = rConflictsList.end();
+ for ( ScConflictsList::iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( aItr->HasSharedAction( nSharedAction ) )
+ {
+ return &(*aItr);
+ }
+ }
+
+ return NULL;
+}
+
+ScConflictsListEntry* ScConflictsListHelper::GetOwnActionEntry( ScConflictsList& rConflictsList, ULONG nOwnAction )
+{
+ ScConflictsList::iterator aEnd = rConflictsList.end();
+ for ( ScConflictsList::iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( aItr->HasOwnAction( nOwnAction ) )
+ {
+ return &(*aItr);
+ }
+ }
+
+ return NULL;
+}
+
+void ScConflictsListHelper::Transform_Impl( ScChangeActionList& rActionList, ScChangeActionMergeMap* pMergeMap )
+{
+ if ( !pMergeMap )
+ {
+ return;
+ }
+
+ for ( ScChangeActionList::iterator aItr = rActionList.begin(); aItr != rActionList.end(); )
+ {
+ ScChangeActionMergeMap::iterator aItrMap = pMergeMap->find( *aItr );
+ if ( aItrMap != pMergeMap->end() )
+ {
+ *aItr = aItrMap->second;
+ aItr++;
+ }
+ else
+ {
+ aItr = rActionList.erase( aItr );
+ DBG_ERROR( "ScConflictsListHelper::Transform_Impl: erased action from conflicts list!" );
+ }
+ }
+}
+
+void ScConflictsListHelper::TransformConflictsList( ScConflictsList& rConflictsList,
+ ScChangeActionMergeMap* pSharedMap, ScChangeActionMergeMap* pOwnMap )
+{
+ ScConflictsList::iterator aEnd = rConflictsList.end();
+ for ( ScConflictsList::iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( pSharedMap )
+ {
+ ScConflictsListHelper::Transform_Impl( aItr->maSharedActions, pSharedMap );
+ }
+
+ if ( pOwnMap )
+ {
+ ScConflictsListHelper::Transform_Impl( aItr->maOwnActions, pOwnMap );
+ }
+ }
+}
+
+
+//=============================================================================
+// class ScConflictsFinder
+//=============================================================================
+
+ScConflictsFinder::ScConflictsFinder( ScChangeTrack* pTrack, ULONG nStartShared, ULONG nEndShared,
+ ULONG nStartOwn, ULONG nEndOwn, ScConflictsList& rConflictsList )
+ :mpTrack( pTrack )
+ ,mnStartShared( nStartShared )
+ ,mnEndShared( nEndShared )
+ ,mnStartOwn( nStartOwn )
+ ,mnEndOwn( nEndOwn )
+ ,mrConflictsList( rConflictsList )
+{
+}
+
+ScConflictsFinder::~ScConflictsFinder()
+{
+}
+
+bool ScConflictsFinder::DoActionsIntersect( const ScChangeAction* pAction1, const ScChangeAction* pAction2 )
+{
+ if ( pAction1 && pAction2 && pAction1->GetBigRange().Intersects( pAction2->GetBigRange() ) )
+ {
+ return true;
+ }
+ return false;
+}
+
+ScConflictsListEntry* ScConflictsFinder::GetIntersectingEntry( const ScChangeAction* pAction ) const
+{
+ ScConflictsList::iterator aEnd = mrConflictsList.end();
+ for ( ScConflictsList::iterator aItr = mrConflictsList.begin(); aItr != aEnd; ++aItr )
+ {
+ ScChangeActionList::const_iterator aEndShared = aItr->maSharedActions.end();
+ for ( ScChangeActionList::const_iterator aItrShared = aItr->maSharedActions.begin(); aItrShared != aEndShared; ++aItrShared )
+ {
+ if ( DoActionsIntersect( mpTrack->GetAction( *aItrShared ), pAction ) )
+ {
+ return &(*aItr);
+ }
+ }
+
+ ScChangeActionList::const_iterator aEndOwn = aItr->maOwnActions.end();
+ for ( ScChangeActionList::const_iterator aItrOwn = aItr->maOwnActions.begin(); aItrOwn != aEndOwn; ++aItrOwn )
+ {
+ if ( DoActionsIntersect( mpTrack->GetAction( *aItrOwn ), pAction ) )
+ {
+ return &(*aItr);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+ScConflictsListEntry* ScConflictsFinder::GetEntry( ULONG nSharedAction, const ScChangeActionList& rOwnActions )
+{
+ // try to get a list entry which already contains the shared action
+ ScConflictsListEntry* pEntry = ScConflictsListHelper::GetSharedActionEntry( mrConflictsList, nSharedAction );
+ if ( pEntry )
+ {
+ return pEntry;
+ }
+
+ // try to get a list entry for which the shared action intersects with any
+ // other action of this entry
+ pEntry = GetIntersectingEntry( mpTrack->GetAction( nSharedAction ) );
+ if ( pEntry )
+ {
+ pEntry->maSharedActions.push_back( nSharedAction );
+ return pEntry;
+ }
+
+ // try to get a list entry for which any of the own actions intersects with
+ // any other action of this entry
+ ScChangeActionList::const_iterator aEnd = rOwnActions.end();
+ for ( ScChangeActionList::const_iterator aItr = rOwnActions.begin(); aItr != aEnd; ++aItr )
+ {
+ pEntry = GetIntersectingEntry( mpTrack->GetAction( *aItr ) );
+ if ( pEntry )
+ {
+ pEntry->maSharedActions.push_back( nSharedAction );
+ return pEntry;
+ }
+ }
+
+ // if no entry was found, create a new one
+ ScConflictsListEntry aEntry;
+ aEntry.meConflictAction = SC_CONFLICT_ACTION_NONE;
+ aEntry.maSharedActions.push_back( nSharedAction );
+ mrConflictsList.push_back( aEntry );
+ return &(mrConflictsList.back());
+}
+
+bool ScConflictsFinder::Find()
+{
+ if ( !mpTrack )
+ {
+ return false;
+ }
+
+ bool bReturn = false;
+ ScChangeAction* pSharedAction = mpTrack->GetAction( mnStartShared );
+ while ( pSharedAction && pSharedAction->GetActionNumber() <= mnEndShared )
+ {
+ ScChangeActionList aOwnActions;
+ ScChangeAction* pOwnAction = mpTrack->GetAction( mnStartOwn );
+ while ( pOwnAction && pOwnAction->GetActionNumber() <= mnEndOwn )
+ {
+ if ( DoActionsIntersect( pSharedAction, pOwnAction ) )
+ {
+ aOwnActions.push_back( pOwnAction->GetActionNumber() );
+ }
+ pOwnAction = pOwnAction->GetNext();
+ }
+
+ if ( aOwnActions.size() )
+ {
+ ScConflictsListEntry* pEntry = GetEntry( pSharedAction->GetActionNumber(), aOwnActions );;
+ ScChangeActionList::iterator aEnd = aOwnActions.end();
+ for ( ScChangeActionList::iterator aItr = aOwnActions.begin(); aItr != aEnd; ++aItr )
+ {
+ if ( pEntry && !ScConflictsListHelper::HasOwnAction( mrConflictsList, *aItr ) )
+ {
+ pEntry->maOwnActions.push_back( *aItr );
+ }
+ }
+ bReturn = true;
+ }
+
+ pSharedAction = pSharedAction->GetNext();
+ }
+
+ return bReturn;
+}
+
+//=============================================================================
+// class ScConflictsResolver
+//=============================================================================
+
+ScConflictsResolver::ScConflictsResolver( ScChangeTrack* pTrack, ScConflictsList& rConflictsList )
+ :mpTrack ( pTrack )
+ ,mrConflictsList ( rConflictsList )
+{
+ DBG_ASSERT( mpTrack, "ScConflictsResolver CTOR: mpTrack is null!" );
+}
+
+ScConflictsResolver::~ScConflictsResolver()
+{
+}
+
+void ScConflictsResolver::HandleAction( ScChangeAction* pAction, bool bIsSharedAction,
+ bool bHandleContentAction, bool bHandleNonContentAction )
+{
+ if ( !mpTrack || !pAction )
+ {
+ return;
+ }
+
+ if ( bIsSharedAction )
+ {
+ ScConflictsListEntry* pConflictEntry = ScConflictsListHelper::GetSharedActionEntry(
+ mrConflictsList, pAction->GetActionNumber() );
+ if ( pConflictEntry )
+ {
+ ScConflictAction eConflictAction = pConflictEntry->meConflictAction;
+ if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_MINE )
+ {
+ if ( pAction->GetType() == SC_CAT_CONTENT )
+ {
+ if ( bHandleContentAction )
+ {
+ mpTrack->Reject( pAction );
+ }
+ }
+ else
+ {
+ if ( bHandleNonContentAction )
+ {
+ mpTrack->Reject( pAction );
+ }
+ }
+ }
+ else if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_OTHER )
+ {
+ if ( pAction->GetType() == SC_CAT_CONTENT )
+ {
+ if ( bHandleContentAction )
+ {
+ // do nothing
+ //mpTrack->SelectContent( pAction );
+ }
+ }
+ else
+ {
+ if ( bHandleNonContentAction )
+ {
+ // do nothing
+ //mpTrack->Accept( pAction );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ScConflictsListEntry* pConflictEntry = ScConflictsListHelper::GetOwnActionEntry(
+ mrConflictsList, pAction->GetActionNumber() );
+ if ( pConflictEntry )
+ {
+ ScConflictAction eConflictAction = pConflictEntry->meConflictAction;
+ if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_MINE )
+ {
+ if ( pAction->GetType() == SC_CAT_CONTENT )
+ {
+ if ( bHandleContentAction )
+ {
+ // do nothing
+ //mpTrack->SelectContent( pAction );
+ }
+ }
+ else
+ {
+ if ( bHandleNonContentAction )
+ {
+ // do nothing
+ //mpTrack->Accept( pAction );
+ }
+ }
+ }
+ else if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_OTHER )
+ {
+ if ( pAction->GetType() == SC_CAT_CONTENT )
+ {
+ if ( bHandleContentAction )
+ {
+ mpTrack->Reject( pAction );
+ }
+ }
+ else
+ {
+ if ( bHandleNonContentAction )
+ {
+ mpTrack->Reject( pAction );
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//=============================================================================
+// class ScConflictsListBox
+//=============================================================================
+
+//UNUSED2008-05 ScConflictsListBox::ScConflictsListBox( Window* pParent, WinBits nBits )
+//UNUSED2008-05 :SvxRedlinTable( pParent, nBits )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScConflictsListBox::ScConflictsListBox( Window* pParent, const ResId& rResId )
+ :SvxRedlinTable( pParent, rResId )
+{
+}
+
+ScConflictsListBox::~ScConflictsListBox()
+{
+}
+
+//UNUSED2008-05 ULONG ScConflictsListBox::GetRootEntryPos( const SvLBoxEntry* pRootEntry ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 ULONG nPos = 0;
+//UNUSED2008-05 SvLBoxEntry* pEntry = GetRootLevelParent( First() );
+//UNUSED2008-05 while ( pEntry )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( pEntry == pRootEntry )
+//UNUSED2008-05 {
+//UNUSED2008-05 return nPos;
+//UNUSED2008-05 }
+//UNUSED2008-05 pEntry = NextSibling( pEntry );
+//UNUSED2008-05 ++nPos;
+//UNUSED2008-05 }
+//UNUSED2008-05 return 0xffffffff;
+//UNUSED2008-05 }
+
+
+//=============================================================================
+// class ScConflictsDlg
+//=============================================================================
+
+ScConflictsDlg::ScConflictsDlg( Window* pParent, ScViewData* pViewData, ScDocument* pSharedDoc, ScConflictsList& rConflictsList )
+ :ModalDialog( pParent, ScResId( RID_SCDLG_CONFLICTS ) )
+ ,maFtConflicts ( this, ScResId( FT_CONFLICTS ) )
+ ,maLbConflicts ( this, ScResId( LB_CONFLICTS ) )
+ ,maBtnKeepMine ( this, ScResId( BTN_KEEPMINE ) )
+ ,maBtnKeepOther ( this, ScResId( BTN_KEEPOTHER ) )
+ ,maFlConflicts ( this, ScResId( FL_CONFLICTS ) )
+ ,maBtnKeepAllMine ( this, ScResId( BTN_KEEPALLMINE ) )
+ ,maBtnKeepAllOthers ( this, ScResId( BTN_KEEPALLOTHERS ) )
+ ,maBtnCancel ( this, ScResId( BTN_CANCEL ) )
+ ,maBtnHelp ( this, ScResId( BTN_HELP ) )
+ ,maStrTitleConflict ( ScResId( STR_TITLE_CONFLICT ) )
+ ,maStrTitleAuthor ( ScResId( STR_TITLE_AUTHOR ) )
+ ,maStrTitleDate ( ScResId( STR_TITLE_DATE ) )
+ ,maStrUnknownUser ( ScResId( STR_UNKNOWN_USER ) )
+ ,mpViewData ( pViewData )
+ ,mpOwnDoc ( NULL )
+ ,mpOwnTrack ( NULL )
+ ,mpSharedDoc ( pSharedDoc )
+ ,mpSharedTrack ( NULL )
+ ,mrConflictsList ( rConflictsList )
+ ,maDialogSize ( GetSizePixel() )
+ ,mbInSelectHdl ( false )
+ ,mbInDeselectHdl ( false )
+{
+ DBG_ASSERT( mpViewData, "ScConflictsDlg CTOR: mpViewData is null!" );
+ mpOwnDoc = ( mpViewData ? mpViewData->GetDocument() : NULL );
+ DBG_ASSERT( mpOwnDoc, "ScConflictsDlg CTOR: mpOwnDoc is null!" );
+ mpOwnTrack = ( mpOwnDoc ? mpOwnDoc->GetChangeTrack() : NULL );
+ DBG_ASSERT( mpOwnTrack, "ScConflictsDlg CTOR: mpOwnTrack is null!" );
+ DBG_ASSERT( mpSharedDoc, "ScConflictsDlg CTOR: mpSharedDoc is null!" );
+ mpSharedTrack = ( mpSharedDoc ? mpSharedDoc->GetChangeTrack() : NULL );
+ DBG_ASSERT( mpSharedTrack, "ScConflictsDlg CTOR: mpSharedTrack is null!" );
+
+ FreeResource();
+
+ SetMinOutputSizePixel( maDialogSize );
+
+ long nTabs[] = { 3, 10, 216, 266 };
+ maLbConflicts.SetTabs( nTabs );
+
+ String aTab( sal_Unicode( '\t' ) );
+ String aHeader( maStrTitleConflict );
+ aHeader += aTab;
+ aHeader += maStrTitleAuthor;
+ aHeader += aTab;
+ aHeader += maStrTitleDate;
+ maLbConflicts.InsertHeaderEntry( aHeader, HEADERBAR_APPEND, HIB_LEFT | HIB_LEFTIMAGE | HIB_VCENTER );
+
+ maLbConflicts.SetWindowBits( WB_HASLINES | WB_CLIPCHILDREN | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL );
+ maLbConflicts.SetSelectionMode( MULTIPLE_SELECTION );
+ maLbConflicts.SetHighlightRange();
+
+ maSelectionTimer.SetTimeout( 100 );
+ maSelectionTimer.SetTimeoutHdl( LINK( this, ScConflictsDlg, UpdateSelectionHdl ) );
+
+ maLbConflicts.SetSelectHdl( LINK( this, ScConflictsDlg, SelectHandle ) );
+ maLbConflicts.SetDeselectHdl( LINK( this, ScConflictsDlg, DeselectHandle ) );
+
+ maBtnKeepMine.SetClickHdl( LINK( this, ScConflictsDlg, KeepMineHandle ) );
+ maBtnKeepOther.SetClickHdl( LINK( this, ScConflictsDlg, KeepOtherHandle ) );
+ maBtnKeepAllMine.SetClickHdl( LINK( this, ScConflictsDlg, KeepAllMineHandle ) );
+ maBtnKeepAllOthers.SetClickHdl( LINK( this, ScConflictsDlg, KeepAllOthersHandle ) );
+
+ UpdateView();
+
+ SvLBoxEntry* pEntry = maLbConflicts.First();
+ if ( pEntry != NULL )
+ {
+ maLbConflicts.Select( pEntry );
+ }
+}
+
+ScConflictsDlg::~ScConflictsDlg()
+{
+}
+
+String ScConflictsDlg::GetConflictString( const ScConflictsListEntry& rConflictEntry )
+{
+ String aString;
+ if ( mpOwnTrack )
+ {
+ const ScChangeAction* pAction = mpOwnTrack->GetAction( rConflictEntry.maOwnActions[ 0 ] );
+ if ( pAction && mpOwnDoc )
+ {
+ SCTAB nTab = pAction->GetBigRange().MakeRange().aStart.Tab();
+ mpOwnDoc->GetName( nTab, aString );
+ }
+ }
+ return aString;
+}
+
+String ScConflictsDlg::GetActionString( const ScChangeAction* pAction, ScDocument* pDoc )
+{
+ String aString;
+
+ DBG_ASSERT( pAction, "ScConflictsDlg::GetActionString(): pAction is null!" );
+ DBG_ASSERT( pDoc, "ScConflictsDlg::GetActionString(): pDoc is null!" );
+ if ( pAction && pDoc )
+ {
+ String aDesc;
+ pAction->GetDescription( aDesc, pDoc, TRUE, false );
+ aString += aDesc;
+ aString += '\t';
+
+ String aUser = pAction->GetUser();
+ aUser.EraseLeadingAndTrailingChars();
+ if ( aUser.Len() == 0 )
+ {
+ aUser = maStrUnknownUser;
+ }
+ aString += aUser;
+ aString += '\t';
+
+ DateTime aDateTime = pAction->GetDateTime();
+ aString += ScGlobal::pLocaleData->getDate( aDateTime );
+ aString += ' ';
+ aString += ScGlobal::pLocaleData->getTime( aDateTime, FALSE );
+ aString += '\t';
+ }
+
+ return aString;
+}
+
+void ScConflictsDlg::HandleListBoxSelection( bool bSelectHandle )
+{
+ SvLBoxEntry* pSelEntry = maLbConflicts.GetCurEntry();
+ if ( !pSelEntry )
+ {
+ pSelEntry = maLbConflicts.FirstSelected();
+ }
+ if ( !pSelEntry )
+ {
+ return;
+ }
+
+ SvLBoxEntry* pRootEntry = maLbConflicts.GetRootLevelParent( pSelEntry );
+ if ( pRootEntry )
+ {
+ if ( bSelectHandle )
+ {
+ maLbConflicts.SelectAll( FALSE );
+ }
+ if ( !maLbConflicts.IsSelected( pRootEntry ) )
+ {
+ maLbConflicts.Select( pRootEntry );
+ }
+ SvLBoxEntry* pEntry = maLbConflicts.FirstChild( pRootEntry );
+ while ( pEntry )
+ {
+ if ( !maLbConflicts.IsSelected( pEntry ) )
+ {
+ maLbConflicts.Select( pEntry );
+ }
+ pEntry = maLbConflicts.NextSibling( pEntry );
+ }
+ }
+}
+
+IMPL_LINK( ScConflictsDlg, SelectHandle, SvxRedlinTable*, EMPTYARG )
+{
+ if ( mbInSelectHdl || mbInDeselectHdl )
+ {
+ return 0;
+ }
+
+ mbInSelectHdl = true;
+ HandleListBoxSelection( true );
+ maSelectionTimer.Start();
+ mbInSelectHdl = false;
+
+ return 0;
+}
+
+IMPL_LINK( ScConflictsDlg, DeselectHandle, SvxRedlinTable*, EMPTYARG )
+{
+ if ( mbInDeselectHdl || mbInSelectHdl )
+ {
+ return 0;
+ }
+
+ mbInDeselectHdl = true;
+ HandleListBoxSelection( false );
+ mbInDeselectHdl = false;
+
+ return 0;
+}
+
+IMPL_LINK( ScConflictsDlg, UpdateSelectionHdl, Timer*, EMPTYARG )
+{
+ if ( !mpViewData || !mpOwnDoc )
+ {
+ return 0;
+ }
+
+ ScTabView* pTabView = mpViewData->GetView();
+ pTabView->DoneBlockMode();
+ BOOL bContMark = FALSE;
+ SvLBoxEntry* pEntry = maLbConflicts.FirstSelected();
+ while ( pEntry )
+ {
+ if ( pEntry != maLbConflicts.GetRootLevelParent( pEntry ) )
+ {
+ RedlinData* pUserData = static_cast< RedlinData* >( pEntry->GetUserData() );
+ if ( pUserData )
+ {
+ ScChangeAction* pAction = static_cast< ScChangeAction* >( pUserData->pData );
+ if ( pAction && ( pAction->GetType() != SC_CAT_DELETE_TABS ) &&
+ ( pAction->IsClickable() || pAction->IsVisible() ) )
+ {
+ const ScBigRange& rBigRange = ( static_cast< const ScChangeAction* >( pAction ) )->GetBigRange();
+ if ( rBigRange.IsValid( mpOwnDoc ) )
+ {
+ BOOL bSetCursor = !maLbConflicts.NextSelected( pEntry );
+ pTabView->MarkRange( rBigRange.MakeRange(), bSetCursor, bContMark );
+ bContMark = TRUE;
+ }
+ }
+ }
+ }
+ pEntry = maLbConflicts.NextSelected( pEntry );
+ }
+
+ return 0;
+}
+
+void ScConflictsDlg::SetConflictAction( SvLBoxEntry* pRootEntry, ScConflictAction eConflictAction )
+{
+ RedlinData* pUserData = static_cast< RedlinData* >( pRootEntry ? pRootEntry->GetUserData() : NULL );
+ ScConflictsListEntry* pConflictEntry = static_cast< ScConflictsListEntry* >( pUserData ? pUserData->pData : NULL );
+ if ( pConflictEntry )
+ {
+ pConflictEntry->meConflictAction = eConflictAction;
+ }
+}
+
+void ScConflictsDlg::KeepHandler( bool bMine )
+{
+ SvLBoxEntry* pEntry = maLbConflicts.FirstSelected();
+ SvLBoxEntry* pRootEntry = ( pEntry ? maLbConflicts.GetRootLevelParent( pEntry ) : NULL );
+ if ( !pRootEntry )
+ {
+ return;
+ }
+ SetPointer( Pointer( POINTER_WAIT ) );
+ ScConflictAction eConflictAction = ( bMine ? SC_CONFLICT_ACTION_KEEP_MINE : SC_CONFLICT_ACTION_KEEP_OTHER );
+ SetConflictAction( pRootEntry, eConflictAction );
+ maLbConflicts.RemoveEntry( pRootEntry );
+ SetPointer( Pointer( POINTER_ARROW ) );
+ if ( maLbConflicts.GetEntryCount() == 0 )
+ {
+ EndDialog( RET_OK );
+ }
+}
+
+void ScConflictsDlg::KeepAllHandler( bool bMine )
+{
+ SvLBoxEntry* pEntry = maLbConflicts.First();
+ SvLBoxEntry* pRootEntry = ( pEntry ? maLbConflicts.GetRootLevelParent( pEntry ) : NULL );
+ if ( !pRootEntry )
+ {
+ return;
+ }
+ SetPointer( Pointer( POINTER_WAIT ) );
+ ScConflictAction eConflictAction = ( bMine ? SC_CONFLICT_ACTION_KEEP_MINE : SC_CONFLICT_ACTION_KEEP_OTHER );
+ while ( pRootEntry )
+ {
+ SetConflictAction( pRootEntry, eConflictAction );
+ pRootEntry = maLbConflicts.NextSibling( pRootEntry );
+ }
+ maLbConflicts.SetUpdateMode( FALSE );
+ maLbConflicts.Clear();
+ maLbConflicts.SetUpdateMode( TRUE );
+ SetPointer( Pointer( POINTER_ARROW ) );
+ EndDialog( RET_OK );
+}
+
+IMPL_LINK( ScConflictsDlg, KeepMineHandle, void*, EMPTYARG )
+{
+ KeepHandler( true );
+
+ return 0;
+}
+
+IMPL_LINK( ScConflictsDlg, KeepOtherHandle, void*, EMPTYARG )
+{
+ KeepHandler( false );
+
+ return 0;
+}
+
+IMPL_LINK( ScConflictsDlg, KeepAllMineHandle, void*, EMPTYARG )
+{
+ KeepAllHandler( true );
+
+ return 0;
+}
+
+IMPL_LINK( ScConflictsDlg, KeepAllOthersHandle, void*, EMPTYARG )
+{
+ KeepAllHandler( false );
+
+ return 0;
+}
+
+void lcl_MoveControlX( Window& rWindow, long nDelta )
+{
+ Point aPos( rWindow.GetPosPixel() );
+ aPos.X() += nDelta;
+ rWindow.SetPosPixel( aPos );
+}
+
+void lcl_MoveControlY( Window& rWindow, long nDelta )
+{
+ Point aPos( rWindow.GetPosPixel() );
+ aPos.Y() += nDelta;
+ rWindow.SetPosPixel( aPos );
+}
+
+void lcl_ChangeControlWidth( Window& rWindow, long nDelta )
+{
+ Size aSize( rWindow.GetSizePixel() );
+ aSize.Width() += nDelta;
+ rWindow.SetSizePixel( aSize );
+}
+
+void lcl_ChangeControlHeight( Window& rWindow, long nDelta )
+{
+ Size aSize( rWindow.GetSizePixel() );
+ aSize.Height() += nDelta;
+ rWindow.SetSizePixel( aSize );
+}
+
+void ScConflictsDlg::Resize()
+{
+ Size aSize( GetSizePixel() );
+ long nDeltaWidth = aSize.Width() - maDialogSize.Width();
+ long nDeltaHeight = aSize.Height() - maDialogSize.Height();
+ maDialogSize = aSize;
+
+ lcl_ChangeControlWidth( maFtConflicts, nDeltaWidth );
+
+ lcl_ChangeControlWidth( maLbConflicts, nDeltaWidth );
+ lcl_ChangeControlHeight( maLbConflicts, nDeltaHeight );
+
+ lcl_MoveControlX( maBtnKeepMine, nDeltaWidth / 2 );
+ lcl_MoveControlY( maBtnKeepMine, nDeltaHeight );
+
+ lcl_MoveControlX( maBtnKeepOther, nDeltaWidth / 2 );
+ lcl_MoveControlY( maBtnKeepOther, nDeltaHeight );
+
+ lcl_MoveControlY( maFlConflicts, nDeltaHeight );
+ lcl_ChangeControlWidth( maFlConflicts, nDeltaWidth );
+
+ lcl_MoveControlX( maBtnKeepAllMine, nDeltaWidth );
+ lcl_MoveControlY( maBtnKeepAllMine, nDeltaHeight );
+
+ lcl_MoveControlX( maBtnKeepAllOthers, nDeltaWidth );
+ lcl_MoveControlY( maBtnKeepAllOthers, nDeltaHeight );
+
+ lcl_MoveControlX( maBtnCancel, nDeltaWidth );
+ lcl_MoveControlY( maBtnCancel, nDeltaHeight );
+
+ lcl_MoveControlX( maBtnHelp, nDeltaWidth );
+ lcl_MoveControlY( maBtnHelp, nDeltaHeight );
+}
+
+void ScConflictsDlg::UpdateView()
+{
+ ScConflictsList::iterator aEndItr = mrConflictsList.end();
+ for ( ScConflictsList::iterator aItr = mrConflictsList.begin(); aItr != aEndItr; ++aItr )
+ {
+ ScConflictsListEntry* pConflictEntry = &(*aItr);
+ if ( pConflictEntry && pConflictEntry->meConflictAction == SC_CONFLICT_ACTION_NONE )
+ {
+ RedlinData* pRootUserData = new RedlinData();
+ pRootUserData->pData = static_cast< void* >( pConflictEntry );
+ SvLBoxEntry* pRootEntry = maLbConflicts.InsertEntry( GetConflictString( *aItr ), pRootUserData );
+
+ ScChangeActionList::const_iterator aEndShared = aItr->maSharedActions.end();
+ for ( ScChangeActionList::const_iterator aItrShared = aItr->maSharedActions.begin(); aItrShared != aEndShared; ++aItrShared )
+ {
+ ScChangeAction* pAction = mpSharedTrack->GetAction( *aItrShared );
+ if ( pAction )
+ {
+ // only display shared top content entries
+ if ( pAction->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContent* pNextContent = ( dynamic_cast< ScChangeActionContent* >( pAction ) )->GetNextContent();
+ if ( pNextContent && aItr->HasSharedAction( pNextContent->GetActionNumber() ) )
+ {
+ continue;
+ }
+ }
+
+ String aString( GetActionString( pAction, mpSharedDoc ) );
+ maLbConflicts.InsertEntry( aString, static_cast< RedlinData* >( NULL ), pRootEntry );
+ }
+ }
+
+ ScChangeActionList::const_iterator aEndOwn = aItr->maOwnActions.end();
+ for ( ScChangeActionList::const_iterator aItrOwn = aItr->maOwnActions.begin(); aItrOwn != aEndOwn; ++aItrOwn )
+ {
+ ScChangeAction* pAction = mpOwnTrack->GetAction( *aItrOwn );
+ if ( pAction )
+ {
+ // only display own top content entries
+ if ( pAction->GetType() == SC_CAT_CONTENT )
+ {
+ ScChangeActionContent* pNextContent = ( dynamic_cast< ScChangeActionContent* >( pAction ) )->GetNextContent();
+ if ( pNextContent && aItr->HasOwnAction( pNextContent->GetActionNumber() ) )
+ {
+ continue;
+ }
+ }
+
+ String aString( GetActionString( pAction, mpOwnDoc ) );
+ RedlinData* pUserData = new RedlinData();
+ pUserData->pData = static_cast< void* >( pAction );
+ maLbConflicts.InsertEntry( aString, pUserData, pRootEntry );
+ }
+ }
+
+ maLbConflicts.Expand( pRootEntry );
+ }
+ }
+}
diff --git a/sc/source/ui/miscdlgs/conflictsdlg.src b/sc/source/ui/miscdlgs/conflictsdlg.src
new file mode 100644
index 000000000000..1facf85da95b
--- /dev/null
+++ b/sc/source/ui/miscdlgs/conflictsdlg.src
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "conflictsdlg.hrc"
+
+ModalDialog RID_SCDLG_CONFLICTS
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SCDLG_CONFLICTS ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 338 , 192 ) ;
+ Text [ en-US ] = "Resolve Conflicts" ;
+ Moveable = TRUE ;
+ Sizeable = TRUE ;
+ Closeable = TRUE ;
+ FixedText FT_CONFLICTS
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 326 , 26 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "There are conflicting changes in this shared spreadsheet. Conflicts must be resolved before saving the spreadsheet. Keep either own or other changes." ;
+ };
+ Control LB_CONFLICTS
+ {
+ Pos = MAP_APPFONT ( 6 , 34 ) ;
+ Size = MAP_APPFONT ( 326 , 104 ) ;
+ Border = TRUE ;
+ };
+ PushButton BTN_KEEPMINE
+ {
+ Pos = MAP_APPFONT ( 72 , 145 ) ;
+ Size = MAP_APPFONT ( 76 , 14 ) ;
+ Text [ en-US ] = "Keep ~Mine" ;
+ };
+ PushButton BTN_KEEPOTHER
+ {
+ Pos = MAP_APPFONT ( 190 , 145 ) ;
+ Size = MAP_APPFONT ( 76 , 14 ) ;
+ Text [ en-US ] = "Keep ~Other" ;
+ };
+ FixedLine FL_CONFLICTS
+ {
+ Pos = MAP_APPFONT ( 1 , 162 ) ;
+ Size = MAP_APPFONT ( 338 , 8 ) ;
+ };
+ PushButton BTN_KEEPALLMINE
+ {
+ Pos = MAP_APPFONT ( 6 , 172 ) ;
+ Size = MAP_APPFONT ( 104 , 14 ) ;
+ Text [ en-US ] = "~Keep All Mine" ;
+ };
+ PushButton BTN_KEEPALLOTHERS
+ {
+ Pos = MAP_APPFONT ( 116 , 172 ) ;
+ Size = MAP_APPFONT ( 104 , 14 ) ;
+ Text [ en-US ] = "Keep ~All Others" ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 226 , 172 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 282 , 172 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ String STR_TITLE_CONFLICT
+ {
+ Text [ en-US ] = "Conflict" ;
+ };
+ String STR_TITLE_AUTHOR
+ {
+ Text [ en-US ] = "Author" ;
+ };
+ String STR_TITLE_DATE
+ {
+ Text [ en-US ] = "Date" ;
+ };
+ String STR_UNKNOWN_USER
+ {
+ Text [ en-US ] = "Unknown User" ;
+ };
+};
+
diff --git a/sc/source/ui/miscdlgs/crdlg.cxx b/sc/source/ui/miscdlgs/crdlg.cxx
new file mode 100644
index 000000000000..074d54a5c912
--- /dev/null
+++ b/sc/source/ui/miscdlgs/crdlg.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "crdlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+ScColOrRowDlg::ScColOrRowDlg( Window* pParent,
+ const String& rStrTitle,
+ const String& rStrLabel,
+ BOOL bColDefault )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_COLORROW ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnRows ( this, ScResId( BTN_GROUP_ROWS ) ),
+ aBtnCols ( this, ScResId( BTN_GROUP_COLS ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ SetText( rStrTitle );
+ aFlFrame.SetText( rStrLabel );
+
+ if ( bColDefault )
+ aBtnCols.Check();
+ else
+ aBtnRows.Check();
+
+ aBtnOk.SetClickHdl( LINK( this, ScColOrRowDlg, OkHdl ) );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScColOrRowDlg::~ScColOrRowDlg()
+{
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScColOrRowDlg, OkHdl, OKButton *, EMPTYARG )
+{
+ EndDialog( aBtnCols.IsChecked() ? SCRET_COLS : SCRET_ROWS );
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScColOrRowDlg, OkHdl, OKButton *, EMPTYARG )
+
+
+
diff --git a/sc/source/ui/miscdlgs/crnrdlg.cxx b/sc/source/ui/miscdlgs/crnrdlg.cxx
new file mode 100644
index 000000000000..0ad2a2e80ca4
--- /dev/null
+++ b/sc/source/ui/miscdlgs/crnrdlg.cxx
@@ -0,0 +1,1172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "reffact.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "crnrdlg.hrc"
+#include "docsh.hxx"
+
+#define _CRNRDLG_CXX
+#include "crnrdlg.hxx"
+#undef _CRNRDLG_CXX
+#include <vcl/msgbox.hxx>
+
+
+//============================================================================
+
+#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute()
+#define QUERYBOX(m) QueryBox(this,WinBits(WB_YES_NO|WB_DEF_YES),m).Execute()
+
+const ULONG nEntryDataCol = 0;
+const ULONG nEntryDataRow = 1;
+const ULONG nEntryDataDelim = 2;
+
+
+//============================================================================
+// class ScColRowNameRangesDlg
+
+
+/*************************************************************************
+#* Member: ScColRowNameRangesDlg Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Konstruktor der Klasse ScColRowNameRangesDlg.
+#* Initialisieren der Klassen- Mitglieder,
+#* Uebernahme der Range- Angaben und Aufruf
+#* der eigentlichen Initialisierungsroutine
+#*
+#* Input: Sfx- Verknuepfungen
+#* Parent- Window
+#* SCViewData
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+ScColRowNameRangesDlg::ScColRowNameRangesDlg( SfxBindings* pB,
+ SfxChildWindow* pCW,
+ Window* pParent,
+ ScViewData* ptrViewData )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_COLROWNAMERANGES ),
+ //
+ aFlAssign ( this, ScResId( FL_ASSIGN ) ),
+ aLbRange ( this, ScResId( LB_RANGE ) ),
+
+ aEdAssign ( this, this, ScResId( ED_AREA ) ),
+ aRbAssign ( this, ScResId( RB_AREA ), &aEdAssign, this ),
+ aBtnColHead ( this, ScResId( BTN_COLHEAD ) ),
+ aBtnRowHead ( this, ScResId( BTN_ROWHEAD ) ),
+ aFtAssign2 ( this, ScResId( FT_DATA_LABEL ) ),
+ aEdAssign2 ( this, this, ScResId( ED_DATA ) ),
+ aRbAssign2 ( this, ScResId( RB_DATA ), &aEdAssign2, this ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnAdd ( this, ScResId( BTN_ADD ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData->GetDocument() ),
+
+ pEdActive ( NULL ),
+ bDlgLostFocus ( FALSE )
+{
+ xColNameRanges = pDoc->GetColNameRanges()->Clone();
+ xRowNameRanges = pDoc->GetRowNameRanges()->Clone();
+ Init();
+ FreeResource();
+}
+
+
+/*************************************************************************
+#* Member: ~ScColRowNameRangesDlg Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Destruktor der Klasse
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+__EXPORT ScColRowNameRangesDlg::~ScColRowNameRangesDlg()
+{
+}
+
+
+/*************************************************************************
+#* Member: Init Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Initialisierungs- Routine:
+#* Umlenken der Event- Handler und einstellen der
+#* Startparameter.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::Init()
+{
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCTAB nStartTab = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ SCTAB nEndTab = 0;
+
+ aBtnOk.SetClickHdl ( LINK( this, ScColRowNameRangesDlg, OkBtnHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScColRowNameRangesDlg, CancelBtnHdl ) );
+ aBtnAdd.SetClickHdl ( LINK( this, ScColRowNameRangesDlg, AddBtnHdl ) );
+ aBtnRemove.SetClickHdl ( LINK( this, ScColRowNameRangesDlg, RemoveBtnHdl ) );
+ aLbRange.SetSelectHdl ( LINK( this, ScColRowNameRangesDlg, Range1SelectHdl ) );
+ aEdAssign.SetModifyHdl ( LINK( this, ScColRowNameRangesDlg, Range1DataModifyHdl ) );
+ aBtnColHead.SetClickHdl ( LINK( this, ScColRowNameRangesDlg, ColClickHdl ) );
+ aBtnRowHead.SetClickHdl ( LINK( this, ScColRowNameRangesDlg, RowClickHdl ) );
+ aEdAssign2.SetModifyHdl ( LINK( this, ScColRowNameRangesDlg, Range2DataModifyHdl ) );
+
+ Link aLink = LINK( this, ScColRowNameRangesDlg, GetFocusHdl );
+ aEdAssign.SetGetFocusHdl( aLink );
+ aRbAssign.SetGetFocusHdl( aLink );
+ aEdAssign2.SetGetFocusHdl( aLink );
+ aRbAssign2.SetGetFocusHdl( aLink );
+
+ aLink = LINK( this, ScColRowNameRangesDlg, LoseFocusHdl );
+ aEdAssign.SetLoseFocusHdl( aLink );
+ aRbAssign.SetLoseFocusHdl( aLink );
+ aEdAssign2.SetLoseFocusHdl( aLink );
+ aRbAssign2.SetLoseFocusHdl( aLink );
+
+ pEdActive = &aEdAssign;
+
+ UpdateNames();
+
+ if ( pViewData && pDoc )
+ {
+ pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+ SetColRowData( ScRange( ScAddress( nStartCol, nStartRow, nStartTab ),
+ ScAddress( nEndCol, nEndRow, nEndTab ) ) );
+ }
+ else
+ {
+ aBtnColHead.Check( TRUE );
+ aBtnRowHead.Check( FALSE );
+ aEdAssign.SetText( EMPTY_STRING );
+ aEdAssign2.SetText( EMPTY_STRING );
+ }
+
+ aLbRange.SetBorderStyle( WINDOW_BORDER_MONO );
+ aBtnColHead.Enable();
+ aBtnRowHead.Enable();
+ aEdAssign.Enable();
+ aEdAssign.GrabFocus();
+ aRbAssign.Enable();
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable(); // Ref-Feld hat Focus
+
+ Range1SelectHdl( 0 );
+}
+
+
+/*************************************************************************
+#* Member: SetColRowData Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: zugehoerigen Datenbereich eines Beschriftungsbereiches
+#* auf default Werte setzen und beide Referenz-Edit-Felder
+#* fuellen.
+#*
+#* Input: Einstellbereich fuer Labels
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::SetColRowData( const ScRange& rLabelRange,BOOL bRef)
+{
+ theCurData = theCurArea = rLabelRange;
+ BOOL bValid = TRUE;
+ SCCOL nCol1 = theCurArea.aStart.Col();
+ SCCOL nCol2 = theCurArea.aEnd.Col();
+ SCROW nRow1 = theCurArea.aStart.Row();
+ SCROW nRow2 = theCurArea.aEnd.Row();
+ if ( (static_cast<SCCOLROW>(nCol2 - nCol1) >= nRow2 - nRow1) || (nCol1 == 0 && nCol2 == MAXCOL) )
+ { // Spaltenkoepfe und Grenzfall gesamte Tabelle
+ aBtnColHead.Check( TRUE );
+ aBtnRowHead.Check( FALSE );
+ if ( nRow2 == MAXROW )
+ {
+ if ( nRow1 == 0 )
+ bValid = FALSE; // Grenzfall gesamte Tabelle
+ else
+ { // Head unten, Data oben
+ theCurData.aStart.SetRow( 0 );
+ theCurData.aEnd.SetRow( nRow1 - 1 );
+ }
+ }
+ else
+ { // Head oben, Data unten
+ theCurData.aStart.SetRow( nRow2 + 1 );
+ theCurData.aEnd.SetRow( MAXROW );
+ }
+ }
+ else
+ { // Zeilenkoepfe
+ aBtnRowHead.Check( TRUE );
+ aBtnColHead.Check( FALSE );
+ if ( nCol2 == MAXCOL )
+ { // Head rechts, Data links
+ theCurData.aStart.SetCol( 0 );
+ theCurData.aEnd.SetCol( nCol2 - 1 );
+ }
+ else
+ { // Head links, Data rechts
+ theCurData.aStart.SetCol( nCol2 + 1 );
+ theCurData.aEnd.SetCol( MAXCOL );
+ }
+ }
+ if ( bValid )
+ {
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ String aStr;
+ theCurArea.Format( aStr, SCR_ABS_3D, pDoc, eConv );
+
+ if(bRef)
+ aEdAssign.SetRefString( aStr );
+ else
+ aEdAssign.SetText( aStr );
+
+ aEdAssign.SetSelection( Selection( SELECTION_MAX, SELECTION_MAX ) );
+ theCurData.Format( aStr, SCR_ABS_3D, pDoc, eConv );
+
+ if(bRef)
+ aEdAssign2.SetRefString( aStr );
+ else
+ aEdAssign2.SetText( aStr );
+ }
+ else
+ {
+ theCurData = theCurArea = ScRange();
+
+ if(bRef)
+ {
+ aEdAssign.SetRefString( EMPTY_STRING );
+ aEdAssign2.SetRefString( EMPTY_STRING );
+ }
+ else
+ {
+ aEdAssign.SetText( EMPTY_STRING );
+ aEdAssign2.SetText( EMPTY_STRING );
+ }
+
+ aBtnColHead.Disable();
+ aBtnRowHead.Disable();
+ aEdAssign2.Disable();
+ aRbAssign2.Disable();
+ }
+}
+
+
+/*************************************************************************
+#* Member: AdjustColRowData Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: zugehoerigen Datenbereich eines Beschriftungsbereiches
+#* anpassen und Data-Referenz-Edit-Feld fuellen.
+#*
+#* Input: Bereich fuer Labels
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::AdjustColRowData( const ScRange& rDataRange,BOOL bRef)
+{
+ theCurData = rDataRange;
+ if ( aBtnColHead.IsChecked() )
+ { // Datenbereich gleiche Spalten wie Koepfe
+ theCurData.aStart.SetCol( theCurArea.aStart.Col() );
+ theCurData.aEnd.SetCol( theCurArea.aEnd.Col() );
+ if ( theCurData.Intersects( theCurArea ) )
+ {
+ SCROW nRow1 = theCurArea.aStart.Row();
+ SCROW nRow2 = theCurArea.aEnd.Row();
+ if ( nRow1 > 0
+ && (theCurData.aEnd.Row() < nRow2 || nRow2 == MAXROW) )
+ { // Data oben
+ theCurData.aEnd.SetRow( nRow1 - 1 );
+ if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
+ theCurData.aStart.SetRow( theCurData.aEnd.Row() );
+ }
+ else
+ { // Data unten
+ theCurData.aStart.SetRow( nRow2 + 1 );
+ if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
+ theCurData.aEnd.SetRow( theCurData.aStart.Row() );
+ }
+ }
+ }
+ else
+ { // Datenbereich gleiche Zeilen wie Koepfe
+ theCurData.aStart.SetRow( theCurArea.aStart.Row() );
+ theCurData.aEnd.SetRow( theCurArea.aEnd.Row() );
+ if ( theCurData.Intersects( theCurArea ) )
+ {
+ SCCOL nCol1 = theCurArea.aStart.Col();
+ SCCOL nCol2 = theCurArea.aEnd.Col();
+ if ( nCol1 > 0
+ && (theCurData.aEnd.Col() < nCol2 || nCol2 == MAXCOL) )
+ { // Data links
+ theCurData.aEnd.SetCol( nCol1 - 1 );
+ if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
+ theCurData.aStart.SetCol( theCurData.aEnd.Col() );
+ }
+ else
+ { // Data rechts
+ theCurData.aStart.SetCol( nCol2 + 1 );
+ if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
+ theCurData.aEnd.SetCol( theCurData.aStart.Col() );
+ }
+ }
+ }
+ String aStr;
+ theCurData.Format( aStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+
+ if(bRef)
+ aEdAssign2.SetRefString( aStr );
+ else
+ aEdAssign2.SetText( aStr );
+
+ aEdAssign2.SetSelection( Selection( SELECTION_MAX, SELECTION_MAX ) );
+}
+
+
+/*************************************************************************
+#* Member: SetReference Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Uebergabe eines mit der Maus selektierten Tabellen-
+#* bereiches, der dann als neue Selektion im Referenz-
+#* Fenster angezeigt wird.
+#*
+#* Input: Bereich fuer Labels
+#* Dokumentklasse
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::SetReference( const ScRange& rRef, ScDocument* /* pDoc */ )
+{
+ if ( pEdActive )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( pEdActive );
+
+ String aRefStr;
+ if ( pEdActive == &aEdAssign )
+ SetColRowData( rRef, TRUE );
+ else
+ AdjustColRowData( rRef, TRUE );
+ aBtnColHead.Enable();
+ aBtnRowHead.Enable();
+ aBtnAdd.Enable();
+ aBtnRemove.Disable();
+ }
+}
+
+
+/*************************************************************************
+#* Member: Close Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Schliessen des Fensters
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+BOOL __EXPORT ScColRowNameRangesDlg::Close()
+{
+ return DoClose( ScColRowNameRangesDlgWrapper::GetChildWindowId() );
+}
+
+
+/*************************************************************************
+#* Member: SetActive Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Aktivieren des Fensters
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::SetActive()
+{
+ if ( bDlgLostFocus )
+ {
+ bDlgLostFocus = FALSE;
+ if( pEdActive )
+ pEdActive->GrabFocus();
+ }
+ else
+ GrabFocus();
+
+ if( pEdActive == &aEdAssign )
+ Range1DataModifyHdl( 0 );
+ else if( pEdActive == &aEdAssign2 )
+ Range2DataModifyHdl( 0 );
+
+ RefInputDone();
+}
+
+
+/*************************************************************************
+#* Member: UpdateNames Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Aktualisieren der Namen
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::UpdateNames()
+{
+ aLbRange.SetUpdateMode( FALSE );
+ //-----------------------------------------------------------
+ aLbRange.Clear();
+ aRangeMap.clear();
+ aEdAssign.SetText( EMPTY_STRING );
+
+ ULONG nCount, j;
+ USHORT nPos; //@008 Hilfsvariable q eingefuegt
+
+ SCCOL nCol1; //@008 04.09.97
+ SCROW nRow1; //Erweiterung fuer Bereichsnamen
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ String rString;
+ String strShow;
+ const ScAddress::Details aDetails(pDoc->GetAddressConvention());
+
+ String aString;
+ String strDelim = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( " --- " ));
+ aString = strDelim;
+ aString += ScGlobal::GetRscString( STR_COLUMN );
+ aString += strDelim;
+ nPos = aLbRange.InsertEntry( aString );
+ aLbRange.SetEntryData( nPos, (void*)nEntryDataDelim );
+ if ( (nCount = xColNameRanges->Count()) > 0 )
+ {
+ ScRangePair** ppSortArray = xColNameRanges->CreateNameSortedArray(
+ nCount, pDoc );
+ for ( j=0; j < nCount; j++ )
+ {
+ const ScRange aRange(ppSortArray[j]->GetRange(0));
+ aRange.Format( aString, SCR_ABS_3D, pDoc, aDetails );
+
+ //@008 Hole Bereichsparameter aus Dok
+ ppSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
+ nCol2, nRow2, nTab2 );
+ SCCOL q=nCol1+3;
+ if(q>nCol2) q=nCol2;
+ //@008 Baue String zusammen
+ strShow.AssignAscii(RTL_CONSTASCII_STRINGPARAM(" ["));
+ if(pDoc!=NULL)
+ {
+ pDoc->GetString(nCol1, nRow1, nTab1,rString);
+ strShow +=rString;
+ for(SCCOL i=nCol1+1;i<=q;i++)
+ {
+ strShow.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ pDoc->GetString(i, nRow1, nTab1,rString);
+ strShow += rString;
+ }
+ }
+ if(q<nCol2) // Zu lang? Ergaenzen um ",..."
+ {
+ strShow.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ..."));
+ }
+ strShow += ']';
+
+ //@008 String einfuegen in Listbox
+ String aInsStr = aString;
+ aInsStr += strShow;
+ nPos = aLbRange.InsertEntry( aInsStr );
+ aRangeMap.insert( NameRangeMap::value_type(aInsStr, aRange) );
+ aLbRange.SetEntryData( nPos, (void*)nEntryDataCol );
+ }
+ delete [] ppSortArray;
+ }
+ aString = strDelim;
+ aString += ScGlobal::GetRscString( STR_ROW );
+ aString += strDelim;
+ nPos = aLbRange.InsertEntry( aString );
+ aLbRange.SetEntryData( nPos, (void*)nEntryDataDelim );
+ if ( (nCount = xRowNameRanges->Count()) > 0 )
+ {
+ ScRangePair** ppSortArray = xRowNameRanges->CreateNameSortedArray(
+ nCount, pDoc );
+ for ( j=0; j < nCount; j++ )
+ {
+ const ScRange aRange(ppSortArray[j]->GetRange(0));
+ aRange.Format( aString, SCR_ABS_3D, pDoc, aDetails );
+
+ //@008 Ab hier baue String fuer Zeilen
+ ppSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
+ nCol2, nRow2, nTab2 );
+ SCROW q=nRow1+3;
+ if(q>nRow2) q=nRow2;
+ strShow.AssignAscii(RTL_CONSTASCII_STRINGPARAM(" ["));
+ if(pDoc!=NULL)
+ {
+ pDoc->GetString(nCol1, nRow1, nTab1,rString);
+ strShow += rString;
+ for(SCROW i=nRow1+1;i<=q;i++)
+ {
+ strShow.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ pDoc->GetString(nCol1, i, nTab1,rString);
+ strShow += rString;
+ }
+ }
+ if(q<nRow2)
+ {
+ strShow.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ..."));
+ }
+ strShow += ']';
+
+ String aInsStr = aString;
+ aInsStr += strShow;
+ nPos = aLbRange.InsertEntry( aInsStr );
+ aRangeMap.insert( NameRangeMap::value_type(aInsStr, aRange) );
+ aLbRange.SetEntryData( nPos, (void*)nEntryDataRow );
+ }
+ delete [] ppSortArray;
+ }
+ //-----------------------------------------------------------
+ aLbRange.SetUpdateMode( TRUE );
+ aLbRange.Invalidate();
+}
+
+
+/*************************************************************************
+#* Member: UpdateRangeData Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Aktualisieren der Bereichsdaten
+#*
+#* Input: Bereichs-String
+#* Flag fuer Spalten
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+void ScColRowNameRangesDlg::UpdateRangeData( const ScRange& rRange, BOOL bColName )
+{
+ ScRangePair* pPair = NULL;
+ BOOL bFound = FALSE;
+ if ( bColName && (pPair = xColNameRanges->Find( rRange )) != NULL )
+ bFound = TRUE;
+ else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != NULL )
+ bFound = TRUE;
+
+ if ( bFound )
+ {
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ String aStr;
+ theCurArea = rRange;
+ theCurArea.Format( aStr, SCR_ABS_3D, pDoc, eConv );
+ aEdAssign.SetText( aStr );
+ aBtnAdd.Disable();
+ aBtnRemove.Enable();
+ aBtnColHead.Check( bColName );
+ aBtnRowHead.Check( !bColName );
+ theCurData = pPair->GetRange(1);
+ theCurData.Format( aStr, SCR_ABS_3D, pDoc, eConv );
+ aEdAssign2.SetText( aStr );
+ }
+ else
+ {
+ aBtnAdd.Enable();
+ aBtnRemove.Disable();
+ }
+ aBtnColHead.Enable();
+ aBtnRowHead.Enable();
+ aEdAssign2.Enable();
+ aRbAssign2.Enable();
+}
+
+
+/*************************************************************************
+#* Member: IsRefInputMode Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Abfragefunktion fuer Referenz- Input- Mode.
+#*
+#* Input: Bereichs-String
+#* Flag fuer Spalten
+#*
+#* Output: true, wenn Referenz- Input- Mode
+#*
+#************************************************************************/
+
+BOOL ScColRowNameRangesDlg::IsRefInputMode() const
+{
+ return (pEdActive != NULL);
+}
+
+//------------------------------------------------------------------------
+// Handler:
+// ========
+
+/*************************************************************************
+#* Handler: OkBtnHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Wird ausgeloest, wenn der OK- Button gedrueckt wurde.
+#* Hinzufuegen- Button ausloesen, und die neu einge-
+#* stellten Bereiche ans Dokument uebergeben.
+#* Fensterschliessen- Anweisung ausloesen.
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, OkBtnHdl, void *, EMPTYARG )
+{
+ AddBtnHdl( 0 );
+
+ // die RangeLists den Refs am Doc zuweisen
+ pDoc->GetColNameRangesRef() = xColNameRanges;
+ pDoc->GetRowNameRangesRef() = xRowNameRanges;
+ // geaenderte Datenbereiche muessen sich auswirken
+ pDoc->CompileColRowNameFormula();
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ pDocShell->SetDocumentModified();
+
+ Close();
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: CancelBtnHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Fensterschliessen- Anweisung ausloesen.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK_INLINE_START( ScColRowNameRangesDlg, CancelBtnHdl, void *, EMPTYARG )
+{
+ Close();
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScColRowNameRangesDlg, CancelBtnHdl, void *, EMPTYARG )
+
+
+/*************************************************************************
+#* Handler: AddBtnHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Nach betaetigen des Hinzufuegen- Buttons, werden
+#* die Bereichsangaben eingestellt und in der
+#* Listbox dargestellt.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, AddBtnHdl, void *, EMPTYARG )
+{
+ String aNewArea( aEdAssign.GetText() );
+ String aNewData( aEdAssign2.GetText() );
+
+ if ( aNewArea.Len() > 0 && aNewData.Len() > 0 )
+ {
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ ScRange aRange1, aRange2;
+ BOOL bOk1;
+ if ( (bOk1 = ((aRange1.ParseAny( aNewArea, pDoc, eConv ) & SCA_VALID) == SCA_VALID)) != FALSE
+ && ((aRange2.ParseAny( aNewData, pDoc, eConv ) & SCA_VALID) == SCA_VALID) )
+ {
+ theCurArea = aRange1;
+ AdjustColRowData( aRange2 );
+ ScRangePair* pPair;
+ if ( ( pPair = xColNameRanges->Find( theCurArea ) ) != NULL )
+ {
+ xColNameRanges->Remove( pPair );
+ delete pPair;
+ }
+ if ( ( pPair = xRowNameRanges->Find( theCurArea ) ) != NULL )
+ {
+ xRowNameRanges->Remove( pPair );
+ delete pPair;
+ }
+ if ( aBtnColHead.IsChecked() )
+ xColNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
+ else
+ xRowNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
+
+ UpdateNames();
+
+ aEdAssign.GrabFocus();
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ aEdAssign.SetText( EMPTY_STRING );
+ aBtnColHead.Check( TRUE );
+ aBtnRowHead.Check( FALSE );
+ aEdAssign2.SetText( EMPTY_STRING );
+ theCurArea = ScRange();
+ theCurData = theCurArea;
+ Range1SelectHdl( 0 );
+ }
+ else
+ {
+ ERRORBOX( ScGlobal::GetRscString(STR_INVALIDTABNAME) );
+ if ( !bOk1 )
+ aEdAssign.GrabFocus();
+ else
+ aEdAssign2.GrabFocus();
+ }
+ }
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: RemoveBtnHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Nach betaetigen des Loeschen- Buttons, wird
+#* die markierte Bereichsangabe geloescht.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, RemoveBtnHdl, void *, EMPTYARG )
+{
+ String aRangeStr = aLbRange.GetSelectEntry();
+ USHORT nSelectPos = aLbRange.GetSelectEntryPos();
+ BOOL bColName =
+ ((ULONG)aLbRange.GetEntryData( nSelectPos ) == nEntryDataCol);
+ NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
+ if (itr == aRangeMap.end())
+ return 0;
+ const ScRange& rRange = itr->second;
+
+ ScRangePair* pPair = NULL;
+ BOOL bFound = FALSE;
+ if ( bColName && (pPair = xColNameRanges->Find( rRange )) != NULL )
+ bFound = TRUE;
+ else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != NULL )
+ bFound = TRUE;
+ if ( bFound )
+ {
+ String aStrDelMsg = ScGlobal::GetRscString( STR_QUERY_DELENTRY );
+ String aMsg = aStrDelMsg.GetToken( 0, '#' );
+
+ aMsg += aRangeStr;
+ aMsg += aStrDelMsg.GetToken( 1, '#' );
+
+ if ( RET_YES == QUERYBOX(aMsg) )
+ {
+ if ( bColName )
+ xColNameRanges->Remove( pPair );
+ else
+ xRowNameRanges->Remove( pPair );
+ delete pPair;
+
+ UpdateNames();
+ USHORT nCnt = aLbRange.GetEntryCount();
+ if ( nSelectPos >= nCnt )
+ {
+ if ( nCnt )
+ nSelectPos = nCnt - 1;
+ else
+ nSelectPos = 0;
+ }
+ aLbRange.SelectEntryPos( nSelectPos );
+ if ( nSelectPos &&
+ (ULONG)aLbRange.GetEntryData( nSelectPos ) == nEntryDataDelim )
+ aLbRange.SelectEntryPos( --nSelectPos ); // ---Zeile---
+
+ aLbRange.GrabFocus();
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ aEdAssign.SetText( EMPTY_STRING );
+ theCurArea = theCurData = ScRange();
+ aBtnColHead.Check( TRUE );
+ aBtnRowHead.Check( FALSE );
+ aEdAssign2.SetText( EMPTY_STRING );
+ Range1SelectHdl( 0 );
+ }
+ }
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: Range1SelectHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Wenn Zeile in Listbox ausgewaehlt wird,
+#* werden die Eingabefelder entsprechend
+#* eingestellt.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, Range1SelectHdl, void *, EMPTYARG )
+{
+ USHORT nSelectPos = aLbRange.GetSelectEntryPos();
+ USHORT nCnt = aLbRange.GetEntryCount();
+ USHORT nMoves = 0;
+ while ( nSelectPos < nCnt
+ && (ULONG)aLbRange.GetEntryData( nSelectPos ) == nEntryDataDelim )
+ { // skip Delimiter
+ ++nMoves;
+ aLbRange.SelectEntryPos( ++nSelectPos );
+ }
+ String aRangeStr = aLbRange.GetSelectEntry();
+ if ( nMoves )
+ {
+ if ( nSelectPos > 1 && nSelectPos >= nCnt )
+ { // am Ende nicht auf dem " --- Zeile --- " Delimiter stehenbleiben
+ // wenn davor Eintraege existieren
+ nSelectPos = nCnt - 2;
+ aLbRange.SelectEntryPos( nSelectPos );
+ aRangeStr = aLbRange.GetSelectEntry();
+ }
+ else if ( nSelectPos > 2 && nSelectPos < nCnt && aRangeStr.Len()
+ && aRangeStr == aEdAssign.GetText() )
+ { // nach oben wandern statt nach unten auf die vorherige Position
+ nSelectPos -= 2;
+ aLbRange.SelectEntryPos( nSelectPos );
+ aRangeStr = aLbRange.GetSelectEntry();
+ }
+ }
+ NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
+ if ( itr != aRangeMap.end() )
+ {
+ BOOL bColName =
+ ((ULONG)aLbRange.GetEntryData( nSelectPos ) == nEntryDataCol);
+ UpdateRangeData( itr->second, bColName );
+ aBtnAdd.Disable();
+ aBtnRemove.Enable();
+ }
+ else
+ {
+ if ( aEdAssign.GetText().Len() > 0 )
+ {
+ if ( aEdAssign2.GetText().Len() > 0 )
+ aBtnAdd.Enable();
+ else
+ aBtnAdd.Disable();
+ aBtnColHead.Enable();
+ aBtnRowHead.Enable();
+ aEdAssign2.Enable();
+ aRbAssign2.Enable();
+ }
+ else
+ {
+ aBtnAdd.Disable();
+ aBtnColHead.Disable();
+ aBtnRowHead.Disable();
+ aEdAssign2.Disable();
+ aRbAssign2.Disable();
+ }
+ aBtnRemove.Disable();
+ aEdAssign.GrabFocus();
+ }
+
+ aEdAssign.Enable();
+ aRbAssign.Enable();
+
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: Range1DataModifyHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Wird ausgeloest, wenn in der Tabelle, der Label-
+#* Bereich geaendert wurde.
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, Range1DataModifyHdl, void *, EMPTYARG )
+{
+ String aNewArea( aEdAssign.GetText() );
+ BOOL bValid = FALSE;
+ if ( aNewArea.Len() > 0 )
+ {
+ ScRange aRange;
+ if ( (aRange.ParseAny( aNewArea, pDoc, pDoc->GetAddressConvention() ) & SCA_VALID) == SCA_VALID )
+ {
+ SetColRowData( aRange );
+ bValid = TRUE;
+ }
+ }
+ if ( bValid )
+ {
+ aBtnAdd.Enable();
+ aBtnColHead.Enable();
+ aBtnRowHead.Enable();
+ aEdAssign2.Enable();
+ aRbAssign2.Enable();
+ }
+ else
+ {
+ aBtnAdd.Disable();
+ aBtnColHead.Disable();
+ aBtnRowHead.Disable();
+ aEdAssign2.Disable();
+ aRbAssign2.Disable();
+ }
+ aBtnRemove.Disable();
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: Range2DataModifyHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Wird ausgeloest, wenn in der Tabelle, der Daten-
+#* Bereich geaendert wurde
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, Range2DataModifyHdl, void *, EMPTYARG )
+{
+ String aNewData( aEdAssign2.GetText() );
+ if ( aNewData.Len() > 0 )
+ {
+ ScRange aRange;
+ if ( (aRange.ParseAny( aNewData, pDoc, pDoc->GetAddressConvention() ) & SCA_VALID) == SCA_VALID )
+ {
+ AdjustColRowData( aRange );
+ aBtnAdd.Enable();
+ }
+ else
+ aBtnAdd.Disable();
+ }
+ else
+ {
+ aBtnAdd.Disable();
+ }
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: ColClickHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Radiobutton fuer Spalten wurde betaetigt,
+#* die entsprechenden Einstellungen werden
+#* vorgenommen
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, ColClickHdl, void *, EMPTYARG )
+{
+ if ( !aBtnColHead.GetSavedValue() )
+ {
+ aBtnColHead.Check( TRUE );
+ aBtnRowHead.Check( FALSE );
+ if ( theCurArea.aStart.Row() == 0 && theCurArea.aEnd.Row() == MAXROW )
+ {
+ theCurArea.aEnd.SetRow( MAXROW - 1 );
+ String aStr;
+ theCurArea.Format( aStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ aEdAssign.SetText( aStr );
+ }
+ ScRange aRange( theCurData );
+ aRange.aStart.SetRow( Min( (long)(theCurArea.aEnd.Row() + 1), (long)MAXROW ) );
+ aRange.aEnd.SetRow( MAXROW );
+ AdjustColRowData( aRange );
+ }
+ return 0;
+}
+
+
+/*************************************************************************
+#* Handler: RowClickHdl Datum:04.09.97
+#*------------------------------------------------------------------------
+#*
+#* Klasse: ScColRowNameRangesDlg
+#*
+#* Funktion: Radiobutton fuer Zeilen wurde betaetigt,
+#* die entsprechenden Einstellungen werden
+#* vorgenommen
+#*
+#* Input: ---
+#*
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( ScColRowNameRangesDlg, RowClickHdl, void *, EMPTYARG )
+{
+ if ( !aBtnRowHead.GetSavedValue() )
+ {
+ aBtnRowHead.Check( TRUE );
+ aBtnColHead.Check( FALSE );
+ if ( theCurArea.aStart.Col() == 0 && theCurArea.aEnd.Col() == MAXCOL )
+ {
+ theCurArea.aEnd.SetCol( MAXCOL - 1 );
+ String aStr;
+ theCurArea.Format( aStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ aEdAssign.SetText( aStr );
+ }
+ ScRange aRange( theCurData );
+ aRange.aStart.SetCol( static_cast<SCCOL>(Min( (long)(theCurArea.aEnd.Col() + 1), (long)MAXCOL )) );
+ aRange.aEnd.SetCol( MAXCOL );
+ AdjustColRowData( aRange );
+ }
+ return 0;
+}
+
+
+IMPL_LINK( ScColRowNameRangesDlg, GetFocusHdl, Control*, pCtrl )
+{
+ if( (pCtrl == (Control*)&aEdAssign) || (pCtrl == (Control*)&aRbAssign) )
+ pEdActive = &aEdAssign;
+ else if( (pCtrl == (Control*)&aEdAssign2) || (pCtrl == (Control*)&aRbAssign2) )
+ pEdActive = &aEdAssign2;
+ else
+ pEdActive = NULL;
+
+ if( pEdActive )
+ pEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
+
+ return 0;
+}
+
+
+IMPL_LINK( ScColRowNameRangesDlg, LoseFocusHdl, Control*, EMPTYARG )
+{
+ bDlgLostFocus = !IsActive();
+ return 0;
+}
diff --git a/sc/source/ui/miscdlgs/delcldlg.cxx b/sc/source/ui/miscdlgs/delcldlg.cxx
new file mode 100644
index 000000000000..fd206ac537ba
--- /dev/null
+++ b/sc/source/ui/miscdlgs/delcldlg.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "delcldlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+static BYTE nDelItemChecked=0;
+
+//==================================================================
+
+ScDeleteCellDlg::ScDeleteCellDlg( Window* pParent, BOOL bDisallowCellMove ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DELCELL ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnCellsUp ( this, ScResId( BTN_CELLSUP ) ),
+ aBtnCellsLeft ( this, ScResId( BTN_CELLSLEFT ) ),
+ aBtnDelRows ( this, ScResId( BTN_DELROWS ) ),
+ aBtnDelCols ( this, ScResId( BTN_DELCOLS ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+
+ if (bDisallowCellMove)
+ {
+ aBtnCellsUp.Disable();
+ aBtnCellsLeft.Disable();
+
+ switch(nDelItemChecked)
+ {
+ case 2: aBtnDelRows.Check();break;
+ case 3: aBtnDelCols.Check();break;
+ default:aBtnDelRows.Check();break;
+ }
+ }
+ else
+ {
+ switch(nDelItemChecked)
+ {
+ case 0: aBtnCellsUp.Check();break;
+ case 1: aBtnCellsLeft.Check();break;
+ case 2: aBtnDelRows.Check();break;
+ case 3: aBtnDelCols.Check();break;
+ }
+ }
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+DelCellCmd ScDeleteCellDlg::GetDelCellCmd() const
+{
+ DelCellCmd nReturn = DEL_NONE;
+
+ if ( aBtnCellsUp.IsChecked() )
+ {
+ nDelItemChecked=0;
+ nReturn = DEL_CELLSUP;
+ }
+ else if ( aBtnCellsLeft.IsChecked() )
+ {
+ nDelItemChecked=1;
+ nReturn = DEL_CELLSLEFT;
+ }
+ else if ( aBtnDelRows.IsChecked() )
+ {
+ nDelItemChecked=2;
+ nReturn = DEL_DELROWS;
+ }
+ else if ( aBtnDelCols.IsChecked() )
+ {
+ nDelItemChecked=3;
+ nReturn = DEL_DELCOLS;
+ }
+
+ return nReturn;
+}
+
+__EXPORT ScDeleteCellDlg::~ScDeleteCellDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/delcodlg.cxx b/sc/source/ui/miscdlgs/delcodlg.cxx
new file mode 100644
index 000000000000..7be4c7a0bf3f
--- /dev/null
+++ b/sc/source/ui/miscdlgs/delcodlg.cxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "delcodlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+BOOL ScDeleteContentsDlg::bPreviousAllCheck = FALSE;
+USHORT ScDeleteContentsDlg::nPreviousChecks = (IDF_DATETIME | IDF_STRING |
+ IDF_NOTE | IDF_FORMULA |
+ IDF_VALUE);
+
+//-----------------------------------------------------------------------
+
+ScDeleteContentsDlg::ScDeleteContentsDlg( Window* pParent,
+ USHORT nCheckDefaults ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_DELCONT ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnDelAll ( this, ScResId( BTN_DELALL ) ),
+ aBtnDelStrings ( this, ScResId( BTN_DELSTRINGS ) ),
+ aBtnDelNumbers ( this, ScResId( BTN_DELNUMBERS ) ),
+ aBtnDelDateTime ( this, ScResId( BTN_DELDATETIME ) ),
+ aBtnDelFormulas ( this, ScResId( BTN_DELFORMULAS ) ),
+ aBtnDelNotes ( this, ScResId( BTN_DELNOTES ) ),
+ aBtnDelAttrs ( this, ScResId( BTN_DELATTRS ) ),
+ aBtnDelObjects ( this, ScResId( BTN_DELOBJECTS ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ bObjectsDisabled( FALSE )
+{
+ if ( nCheckDefaults != 0 )
+ {
+ ScDeleteContentsDlg::nPreviousChecks = nCheckDefaults;
+ ScDeleteContentsDlg::bPreviousAllCheck = FALSE;
+ }
+
+ aBtnDelAll.Check ( ScDeleteContentsDlg::bPreviousAllCheck );
+ aBtnDelStrings.Check ( IS_SET( IDF_STRING,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+ aBtnDelNumbers.Check ( IS_SET( IDF_VALUE,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+ aBtnDelDateTime.Check( IS_SET( IDF_DATETIME,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+ aBtnDelFormulas.Check( IS_SET( IDF_FORMULA,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+ aBtnDelNotes.Check ( IS_SET( IDF_NOTE,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+ aBtnDelAttrs.Check ( IS_SET( IDF_ATTRIB,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+ aBtnDelObjects.Check ( IS_SET( IDF_OBJECTS,
+ ScDeleteContentsDlg::nPreviousChecks ) );
+
+ DisableChecks( aBtnDelAll.IsChecked() );
+
+ aBtnDelAll.SetClickHdl( LINK( this, ScDeleteContentsDlg, DelAllHdl ) );
+
+ //-------------
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScDeleteContentsDlg::GetDelContentsCmdBits() const
+{
+ ScDeleteContentsDlg::nPreviousChecks = 0;
+
+ if ( aBtnDelStrings.IsChecked() )
+ ScDeleteContentsDlg::nPreviousChecks = IDF_STRING;
+ if ( aBtnDelNumbers.IsChecked() )
+ ScDeleteContentsDlg::nPreviousChecks |= IDF_VALUE;
+ if ( aBtnDelDateTime.IsChecked())
+ ScDeleteContentsDlg::nPreviousChecks |= IDF_DATETIME;
+ if ( aBtnDelFormulas.IsChecked())
+ ScDeleteContentsDlg::nPreviousChecks |= IDF_FORMULA;
+ if ( aBtnDelNotes.IsChecked() )
+ ScDeleteContentsDlg::nPreviousChecks |= IDF_NOTE;
+ if ( aBtnDelAttrs.IsChecked() )
+ ScDeleteContentsDlg::nPreviousChecks |= IDF_ATTRIB;
+ if ( aBtnDelObjects.IsChecked() )
+ ScDeleteContentsDlg::nPreviousChecks |= IDF_OBJECTS;
+
+ ScDeleteContentsDlg::bPreviousAllCheck = aBtnDelAll.IsChecked();
+
+ return ( (ScDeleteContentsDlg::bPreviousAllCheck)
+ ? IDF_ALL
+ : ScDeleteContentsDlg::nPreviousChecks );
+}
+
+//------------------------------------------------------------------------
+
+void ScDeleteContentsDlg::DisableChecks( BOOL bDelAllChecked )
+{
+ if ( bDelAllChecked )
+ {
+ aBtnDelStrings.Disable();
+ aBtnDelNumbers.Disable();
+ aBtnDelDateTime.Disable();
+ aBtnDelFormulas.Disable();
+ aBtnDelNotes.Disable();
+ aBtnDelAttrs.Disable();
+ aBtnDelObjects.Disable();
+ }
+ else
+ {
+ aBtnDelStrings.Enable();
+ aBtnDelNumbers.Enable();
+ aBtnDelDateTime.Enable();
+ aBtnDelFormulas.Enable();
+ aBtnDelNotes.Enable();
+ aBtnDelAttrs.Enable();
+ if (bObjectsDisabled)
+ aBtnDelObjects.Disable();
+ else
+ aBtnDelObjects.Enable();
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScDeleteContentsDlg::DisableObjects()
+{
+ bObjectsDisabled = TRUE;
+ aBtnDelObjects.Check(FALSE);
+ aBtnDelObjects.Disable();
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScDeleteContentsDlg, DelAllHdl, void *, EMPTYARG )
+{
+ DisableChecks( aBtnDelAll.IsChecked() );
+
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScDeleteContentsDlg, DelAllHdl, void *, EMPTYARG )
+
+__EXPORT ScDeleteContentsDlg::~ScDeleteContentsDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/filldlg.cxx b/sc/source/ui/miscdlgs/filldlg.cxx
new file mode 100644
index 000000000000..2b247f0f9a07
--- /dev/null
+++ b/sc/source/ui/miscdlgs/filldlg.cxx
@@ -0,0 +1,375 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//----------------------------------------------------------------------------
+
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <limits.h>
+
+#include "scresid.hxx"
+#include "document.hxx"
+#include "miscdlgs.hrc"
+
+#define _FILLDLG_CXX
+#include "filldlg.hxx"
+#undef _FILLDLG_CXX
+
+
+
+//============================================================================
+// class ScFillSeriesDlg
+
+//----------------------------------------------------------------------------
+
+ScFillSeriesDlg::ScFillSeriesDlg( Window* pParent,
+ ScDocument& rDocument,
+ FillDir eFillDir,
+ FillCmd eFillCmd,
+ FillDateCmd eFillDateCmd,
+ String aStartStr,
+ double fStep,
+ double fMax,
+ USHORT nPossDir )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_FILLSERIES ) ),
+
+ aFlDirection ( this, ScResId( FL_DIRECTION ) ),
+ aBtnDown ( this, ScResId( BTN_BOTTOM ) ),
+ aBtnRight ( this, ScResId( BTN_RIGHT ) ),
+ aBtnUp ( this, ScResId( BTN_TOP ) ),
+ aBtnLeft ( this, ScResId( BTN_LEFT ) ),
+ aFlSep1 ( this, ScResId( FL_SEP1 ) ),
+ aFlType ( this, ScResId( FL_TYPE ) ),
+ aBtnArithmetic ( this, ScResId( BTN_ARITHMETIC ) ),
+ aBtnGeometric ( this, ScResId( BTN_GEOMETRIC ) ),
+ aBtnDate ( this, ScResId( BTN_DATE ) ),
+ aBtnAutoFill ( this, ScResId( BTN_AUTOFILL ) ),
+ aFlSep2 ( this, ScResId( FL_SEP2 ) ),
+ aFlTimeUnit ( this, ScResId( FL_TIME_UNIT ) ),
+ aBtnDay ( this, ScResId( BTN_DAY ) ),
+ aBtnDayOfWeek ( this, ScResId( BTN_DAY_OF_WEEK ) ),
+ aBtnMonth ( this, ScResId( BTN_MONTH ) ),
+ aBtnYear ( this, ScResId( BTN_YEAR ) ),
+
+ aFtStartVal ( this, ScResId( FT_START_VALUE ) ),
+ aEdStartVal ( this, ScResId( ED_START_VALUES ) ),
+ aStartStrVal ( aStartStr),
+ aFtEndVal ( this, ScResId( FT_END_VALUE ) ),
+ aEdEndVal ( this, ScResId( ED_END_VALUES ) ),
+ aFtIncrement ( this, ScResId( FT_INCREMENT ) ),
+ aEdIncrement ( this, ScResId( ED_INCREMENT ) ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ errMsgInvalidVal( ScResId( STR_VALERR ) ),
+ rDoc ( rDocument ),
+ theFillDir ( eFillDir ),
+ theFillCmd ( eFillCmd ),
+ theFillDateCmd ( eFillDateCmd ),
+ fIncrement ( fStep ),
+ fEndVal ( fMax )
+{
+ Init( nPossDir );
+ FreeResource();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScFillSeriesDlg::~ScFillSeriesDlg()
+{
+}
+
+//----------------------------------------------------------------------------
+
+void ScFillSeriesDlg::SetEdStartValEnabled(BOOL bFlag)
+{
+ bStartValFlag=bFlag;
+ if(bFlag)
+ {
+ aFtStartVal.Enable();
+ aEdStartVal.Enable();
+ }
+ else
+ {
+ aFtStartVal.Disable();
+ aEdStartVal.Disable();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScFillSeriesDlg::Init( USHORT nPossDir )
+{
+ aBtnOk.SetClickHdl ( LINK( this, ScFillSeriesDlg, OKHdl ) );
+ aBtnArithmetic.SetClickHdl ( LINK( this, ScFillSeriesDlg, DisableHdl ) );
+ aBtnGeometric.SetClickHdl ( LINK( this, ScFillSeriesDlg, DisableHdl ) );
+ aBtnDate.SetClickHdl ( LINK( this, ScFillSeriesDlg, DisableHdl ) );
+ aBtnAutoFill.SetClickHdl ( LINK( this, ScFillSeriesDlg, DisableHdl ) );
+
+ if( nPossDir == FDS_OPT_NONE )
+ {
+ aBtnLeft.Disable();
+ aBtnRight.Disable();
+ aBtnDown.Disable();
+ aBtnUp.Disable();
+ }
+
+ if( nPossDir == FDS_OPT_HORZ )
+ {
+ aBtnDown.Disable();
+ aBtnUp.Disable();
+ }
+
+ if( nPossDir == FDS_OPT_VERT )
+ {
+ aBtnLeft.Disable();
+ aBtnRight.Disable();
+ }
+
+ switch ( theFillDir )
+ {
+ case FILL_TO_LEFT: aBtnLeft.Check(); break;
+ case FILL_TO_RIGHT: aBtnRight.Check(); break;
+ case FILL_TO_BOTTOM: aBtnDown.Check(); break;
+ case FILL_TO_TOP: aBtnUp.Check(); break;
+ default:
+ break;
+ }
+
+ switch ( theFillCmd )
+ {
+ case FILL_LINEAR:
+ aBtnArithmetic.Check();
+ DisableHdl( &aBtnArithmetic );
+ break;
+ case FILL_GROWTH:
+ aBtnGeometric.Check();
+ DisableHdl( &aBtnGeometric );
+ break;
+ case FILL_DATE:
+ aBtnDate.Check();
+ DisableHdl( &aBtnDate );
+ break;
+ case FILL_AUTO:
+ aBtnAutoFill.Check();
+ DisableHdl( &aBtnAutoFill );
+ break;
+ default:
+ break;
+ }
+
+ switch ( theFillDateCmd )
+ {
+ case FILL_DAY: aBtnDay.Check(); break;
+ case FILL_WEEKDAY: aBtnDayOfWeek.Check(); break;
+ case FILL_MONTH: aBtnMonth.Check(); break;
+ case FILL_YEAR: aBtnYear.Check(); break;
+ default:
+ break;
+ }
+
+ fStartVal = MAXDOUBLE;
+ /*
+ String aStartTxt;
+ if ( fStartVal != MAXDOUBLE )
+ rDoc.GetFormatTable()->GetInputLineString( fStartVal, 0, aStartTxt );
+ aEdStartVal.SetText( aStartTxt );
+ */
+
+ aEdStartVal.SetText( aStartStrVal);
+
+ String aIncrTxt;
+ rDoc.GetFormatTable()->GetInputLineString( fIncrement, 0, aIncrTxt );
+ aEdIncrement.SetText( aIncrTxt );
+
+ String aEndTxt;
+ if ( fEndVal != MAXDOUBLE )
+ rDoc.GetFormatTable()->GetInputLineString( fEndVal, 0, aEndTxt );
+ aEdEndVal.SetText( aEndTxt );
+
+ bStartValFlag=FALSE;
+
+ aFlSep1.SetStyle( aFlSep1.GetStyle() | WB_VERT );
+ aFlSep2.SetStyle( aFlSep2.GetStyle() | WB_VERT );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScFillSeriesDlg::CheckStartVal()
+{
+ BOOL bValOk = FALSE;
+ sal_uInt32 nKey = 0;
+ String aStr( aEdStartVal.GetText() );
+
+ if ( aStr.Len() == 0 || aBtnAutoFill.IsChecked())
+ {
+ fStartVal = MAXDOUBLE;
+ bValOk = TRUE;
+ }
+ else
+ bValOk = rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fStartVal );
+
+ return bValOk;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScFillSeriesDlg::CheckIncrementVal()
+{
+ sal_uInt32 nKey = 0;
+ String aStr( aEdIncrement.GetText() );
+
+ return rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fIncrement );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScFillSeriesDlg::CheckEndVal()
+{
+ BOOL bValOk = FALSE;
+ sal_uInt32 nKey = 0;
+ String aStr( aEdEndVal.GetText() );
+
+ if ( aStr.Len() == 0 )
+ {
+ fEndVal = (fIncrement < 0) ? -MAXDOUBLE : MAXDOUBLE;
+ bValOk = TRUE;
+ }
+ else
+ bValOk = rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fEndVal );
+
+ return bValOk;
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFillSeriesDlg, DisableHdl, Button *, pBtn )
+{
+ if ( pBtn == &aBtnDate )
+ {
+ aBtnDay.Enable();
+ aBtnDayOfWeek.Enable();
+ aBtnMonth.Enable();
+ aBtnYear.Enable();
+ aFlTimeUnit.Enable();
+ }
+ else
+ {
+ aBtnDay.Disable();
+ aBtnDayOfWeek.Disable();
+ aBtnMonth.Disable();
+ aBtnYear.Disable();
+ aFlTimeUnit.Disable();
+ }
+
+ if ( pBtn != &aBtnAutoFill )
+ {
+ aFtIncrement.Enable();
+ aEdIncrement.Enable();
+ aFtEndVal.Enable();
+ aEdEndVal.Enable();
+ }
+ else
+ {
+ aFtIncrement.Disable();
+ aEdIncrement.Disable();
+ aFtEndVal.Disable();
+ aEdEndVal.Disable();
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScFillSeriesDlg, OKHdl, void *, EMPTYARG )
+{
+ if ( aBtnLeft.IsChecked() ) theFillDir = FILL_TO_LEFT;
+ else if ( aBtnRight.IsChecked() ) theFillDir = FILL_TO_RIGHT;
+ else if ( aBtnDown.IsChecked() ) theFillDir = FILL_TO_BOTTOM;
+ else if ( aBtnUp.IsChecked() ) theFillDir = FILL_TO_TOP;
+
+ if ( aBtnArithmetic.IsChecked() ) theFillCmd = FILL_LINEAR;
+ else if ( aBtnGeometric.IsChecked() ) theFillCmd = FILL_GROWTH;
+ else if ( aBtnDate.IsChecked() ) theFillCmd = FILL_DATE;
+ else if ( aBtnAutoFill.IsChecked() ) theFillCmd = FILL_AUTO;
+
+ if ( aBtnDay.IsChecked() ) theFillDateCmd = FILL_DAY;
+ else if ( aBtnDayOfWeek.IsChecked() ) theFillDateCmd = FILL_WEEKDAY;
+ else if ( aBtnMonth.IsChecked() ) theFillDateCmd = FILL_MONTH;
+ else if ( aBtnYear.IsChecked() ) theFillDateCmd = FILL_YEAR;
+
+ BOOL bAllOk = TRUE;
+ Edit* pEdWrong = NULL;
+ if ( !CheckStartVal() )
+ {
+ bAllOk = FALSE;
+ pEdWrong = &aEdStartVal;
+ }
+ else if ( !CheckIncrementVal() )
+ {
+ bAllOk = FALSE;
+ pEdWrong = &aEdIncrement;
+ }
+ else if ( !CheckEndVal() )
+ {
+ bAllOk = FALSE;
+ pEdWrong = &aEdEndVal;
+ }
+ if ( bAllOk )
+ EndDialog( RET_OK );
+ else
+ {
+ ErrorBox( this,
+ WinBits( WB_OK | WB_DEF_OK ),
+ errMsgInvalidVal
+ ).Execute();
+ pEdWrong->GrabFocus();
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/groupdlg.cxx b/sc/source/ui/miscdlgs/groupdlg.cxx
new file mode 100644
index 000000000000..d6eb1865b184
--- /dev/null
+++ b/sc/source/ui/miscdlgs/groupdlg.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "groupdlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+ScGroupDlg::ScGroupDlg( Window* pParent,
+ USHORT nResId,
+ BOOL bUngroup,
+ BOOL bRows ) :
+ ModalDialog ( pParent, ScResId( nResId ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnRows ( this, ScResId( BTN_GROUP_ROWS ) ),
+ aBtnCols ( this, ScResId( BTN_GROUP_COLS ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ aFlFrame.SetText( String( ScResId(bUngroup ? STR_UNGROUP : STR_GROUP) ) );
+
+ if ( bRows )
+ aBtnRows.Check();
+ else
+ aBtnCols.Check();
+
+ //-------------
+ FreeResource();
+ aBtnRows.GrabFocus();
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScGroupDlg::GetColsChecked() const
+{
+ return aBtnCols.IsChecked();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScGroupDlg::~ScGroupDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/highred.cxx b/sc/source/ui/miscdlgs/highred.cxx
new file mode 100644
index 000000000000..dce755c10db3
--- /dev/null
+++ b/sc/source/ui/miscdlgs/highred.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "global.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "highred.hrc"
+
+#include "highred.hxx"
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+
+// defines -------------------------------------------------------------------
+
+#define ABS_SREF SCA_VALID \
+ | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
+#define ABS_DREF ABS_SREF \
+ | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
+#define ABS_SREF3D ABS_SREF | SCA_TAB_3D
+#define ABS_DREF3D ABS_DREF | SCA_TAB_3D
+
+
+
+#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute();
+
+inline void EnableDisable( Window& rWin, BOOL bEnable )
+{
+ if (bEnable)
+ rWin.Enable();
+ else
+ rWin.Disable();
+}
+
+//============================================================================
+// class ScHighlightChgDlg
+
+//----------------------------------------------------------------------------
+ScHighlightChgDlg::ScHighlightChgDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData)
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_HIGHLIGHT_CHANGES ),
+ //
+ aHighlightBox ( this, ScResId( CB_HIGHLIGHT)),
+ aFlFilter ( this, ScResId( FL_FILTER)),
+ aFilterCtr ( this),
+ aCbAccept ( this, ScResId( CB_HIGHLIGHT_ACCEPT)),
+ aCbReject ( this, ScResId( CB_HIGHLIGHT_REJECT)),
+ aOkButton ( this, ScResId( BTN_OK ) ),
+ aCancelButton ( this, ScResId( BTN_CANCEL ) ),
+ aHelpButton ( this, ScResId( BTN_HELP ) ),
+ aEdAssign ( this, this, ScResId( ED_ASSIGN ) ),
+ aRbAssign ( this, ScResId( RB_ASSIGN ), &aEdAssign, this ),
+ //
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData->GetDocument() ),
+ aLocalRangeName ( *(pDoc->GetRangeName()) )
+{
+ FreeResource();
+
+ Point aFlFilterPt( aFlFilter.GetPosPixel() );
+ aFlFilterPt.Y() += aFlFilter.GetSizePixel().Height();
+ aFilterCtr.SetPosPixel( aFlFilterPt );
+ MinSize=aFilterCtr.GetSizePixel();
+ MinSize.Height()+=2;
+ MinSize.Width()+=2;
+ aOkButton.SetClickHdl(LINK( this, ScHighlightChgDlg, OKBtnHdl));
+ aHighlightBox.SetClickHdl(LINK( this, ScHighlightChgDlg, HighLightHandle ));
+ aFilterCtr.SetRefHdl(LINK( this, ScHighlightChgDlg, RefHandle ));
+ aFilterCtr.HideRange(FALSE);
+ aFilterCtr.Show();
+ SetDispatcherLock( TRUE );
+ //SFX_APPWINDOW->Disable(FALSE);
+
+ Init();
+
+}
+ScHighlightChgDlg::~ScHighlightChgDlg()
+{
+ SetDispatcherLock( FALSE );
+ //SFX_APPWINDOW->Enable();
+}
+
+void __EXPORT ScHighlightChgDlg::Init()
+{
+ String aAreaStr;
+ ScRange aRange;
+
+ DBG_ASSERT( pViewData && pDoc, "ViewData oder Document nicht gefunden!" );
+
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+ if(pChanges!=NULL)
+ {
+ aChangeViewSet.SetTheAuthorToShow(pChanges->GetUser());
+ aFilterCtr.ClearAuthors();
+ ScStrCollection aUserColl=pChanges->GetUserCollection();
+ for(USHORT i=0;i<aUserColl.GetCount();i++)
+ aFilterCtr.InsertAuthor(aUserColl[i]->GetString());
+ }
+
+
+ ScChangeViewSettings* pViewSettings=pDoc->GetChangeViewSettings();
+
+ if(pViewSettings!=NULL)
+ aChangeViewSet=*pViewSettings;
+ aHighlightBox.Check(aChangeViewSet.ShowChanges());
+ aFilterCtr.CheckDate(aChangeViewSet.HasDate());
+ aFilterCtr.SetFirstDate(aChangeViewSet.GetTheFirstDateTime());
+ aFilterCtr.SetFirstTime(aChangeViewSet.GetTheFirstDateTime());
+ aFilterCtr.SetLastDate(aChangeViewSet.GetTheLastDateTime());
+ aFilterCtr.SetLastTime(aChangeViewSet.GetTheLastDateTime());
+ aFilterCtr.SetDateMode((USHORT)aChangeViewSet.GetTheDateMode());
+ aFilterCtr.CheckAuthor(aChangeViewSet.HasAuthor());
+ aFilterCtr.CheckComment(aChangeViewSet.HasComment());
+ aFilterCtr.SetComment(aChangeViewSet.GetTheComment());
+
+ aCbAccept.Check(aChangeViewSet.IsShowAccepted());
+ aCbReject.Check(aChangeViewSet.IsShowRejected());
+
+ String aString=aChangeViewSet.GetTheAuthorToShow();
+ if(aString.Len()!=0)
+ {
+ aFilterCtr.SelectAuthor(aString);
+ }
+ else
+ {
+ aFilterCtr.SelectedAuthorPos(0);
+ }
+
+ aFilterCtr.CheckRange(aChangeViewSet.HasRange());
+ ScRange* pRangeEntry=aChangeViewSet.GetTheRangeList().GetObject(0);
+
+
+ if(pRangeEntry!=NULL)
+ {
+ String aRefStr;
+ pRangeEntry->Format( aRefStr, ABS_DREF3D, pDoc );
+ aFilterCtr.SetRange(aRefStr);
+ }
+ aFilterCtr.Enable(TRUE,TRUE);
+ HighLightHandle(&aHighlightBox);
+}
+
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Edit angezeigt wird.
+
+void ScHighlightChgDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( aEdAssign.IsVisible() )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart(&aEdAssign);
+ String aRefStr;
+ rRef.Format( aRefStr, ABS_DREF3D, pDocP, pDocP->GetAddressConvention() );
+ aEdAssign.SetRefString( aRefStr );
+ aFilterCtr.SetRange(aRefStr);
+ }
+}
+
+//----------------------------------------------------------------------------
+BOOL __EXPORT ScHighlightChgDlg::Close()
+{
+ return DoClose( ScHighlightChgDlgWrapper::GetChildWindowId() );
+}
+
+void ScHighlightChgDlg::RefInputDone( BOOL bForced)
+{
+ ScAnyRefDlg::RefInputDone(bForced);
+ if(bForced || !aRbAssign.IsVisible())
+ {
+ aFilterCtr.SetRange(aEdAssign.GetText());
+ aFilterCtr.SetFocusToRange();
+ aEdAssign.Hide();
+ aRbAssign.Hide();
+ }
+}
+
+void ScHighlightChgDlg::SetActive()
+{
+ /*
+ if(pTPFilter!=NULL)
+ {
+ aAcceptChgCtr.GetFilterPage()->SetFocusToRange();
+ aEdAssign.Hide();
+ aRbAssign.Hide();
+ SFX_APPWINDOW->Enable();
+ SetDispatcherLock( FALSE );
+ }
+ //RefInputDone();
+ */
+}
+
+BOOL ScHighlightChgDlg::IsRefInputMode() const
+{
+ return aEdAssign.IsVisible();
+}
+
+IMPL_LINK( ScHighlightChgDlg, HighLightHandle, CheckBox*, pCb )
+{
+ if(pCb!=NULL)
+ {
+ if(aHighlightBox.IsChecked())
+ {
+ aFilterCtr.Enable(TRUE,TRUE);
+ aCbAccept.Enable();
+ aCbReject.Enable();
+ }
+ else
+ {
+ aFilterCtr.Disable(TRUE);
+ aCbAccept.Disable();
+ aCbReject.Disable();
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( ScHighlightChgDlg, RefHandle, SvxTPFilter*, pRef )
+{
+ if(pRef!=NULL)
+ {
+ SetDispatcherLock( TRUE );
+ //SFX_APPWINDOW->Disable(FALSE);
+ aEdAssign.Show();
+ aRbAssign.Show();
+ aEdAssign.SetText(aFilterCtr.GetRange());
+ ScAnyRefDlg::RefInputStart(&aEdAssign,&aRbAssign);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScHighlightChgDlg, OKBtnHdl, PushButton*, pOKBtn )
+{
+ if ( pOKBtn == &aOkButton)
+ {
+ aChangeViewSet.SetShowChanges(aHighlightBox.IsChecked());
+ aChangeViewSet.SetHasDate(aFilterCtr.IsDate());
+ ScChgsDateMode eMode = (ScChgsDateMode) aFilterCtr.GetDateMode();
+ aChangeViewSet.SetTheDateMode( eMode );
+ Date aFirstDate( aFilterCtr.GetFirstDate() );
+ Time aFirstTime( aFilterCtr.GetFirstTime() );
+ Date aLastDate( aFilterCtr.GetLastDate() );
+ Time aLastTime( aFilterCtr.GetLastTime() );
+ aChangeViewSet.SetTheFirstDateTime( DateTime( aFirstDate, aFirstTime ) );
+ aChangeViewSet.SetTheLastDateTime( DateTime( aLastDate, aLastTime ) );
+ aChangeViewSet.SetHasAuthor(aFilterCtr.IsAuthor());
+ aChangeViewSet.SetTheAuthorToShow(aFilterCtr.GetSelectedAuthor());
+ aChangeViewSet.SetHasRange(aFilterCtr.IsRange());
+ aChangeViewSet.SetShowAccepted(aCbAccept.IsChecked());
+ aChangeViewSet.SetShowRejected(aCbReject.IsChecked());
+ aChangeViewSet.SetHasComment(aFilterCtr.IsComment());
+ aChangeViewSet.SetTheComment(aFilterCtr.GetComment());
+ ScRangeList aLocalRangeList;
+ aLocalRangeList.Parse(aFilterCtr.GetRange(), pDoc);
+ aChangeViewSet.SetTheRangeList(aLocalRangeList);
+ aChangeViewSet.AdjustDateMode( *pDoc );
+ pDoc->SetChangeViewSettings(aChangeViewSet);
+ pViewData->GetDocShell()->PostPaintGridAll();
+ Close();
+ }
+ return 0;
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/highred.src b/sc/source/ui/miscdlgs/highred.src
new file mode 100644
index 000000000000..a244a3e2a44e
--- /dev/null
+++ b/sc/source/ui/miscdlgs/highred.src
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "highred.hrc"
+ModelessDialog RID_SCDLG_HIGHLIGHT_CHANGES
+{
+ OutputSize = TRUE ;
+ HelpId = FID_CHG_ACCEPT ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 318 , 148 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ // Dieser Dialog hat einen Cancel-Button !
+ CheckBox CB_HIGHLIGHT
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 150 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Show changes in spreadsheet" ;
+ };
+ FixedLine FL_FILTER
+ {
+ Pos = MAP_APPFONT ( 6 , 22 ) ;
+ Size = MAP_APPFONT ( 255 , 8 ) ;
+ Text [ en-US ] = "Filter settings";
+ };
+ CheckBox CB_HIGHLIGHT_ACCEPT
+ {
+ Pos = MAP_APPFONT ( 12 , 118 ) ;
+ Size = MAP_APPFONT ( 246 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Show ~accepted changes" ;
+ };
+ CheckBox CB_HIGHLIGHT_REJECT
+ {
+ Pos = MAP_APPFONT ( 12 , 132 ) ;
+ Size = MAP_APPFONT ( 246 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Show ~rejected changes" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 267 , 6 ) ;
+ Size = MAP_APPFONT ( 45 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 267 , 23 ) ;
+ Size = MAP_APPFONT ( 45 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 267 , 43 ) ;
+ Size = MAP_APPFONT ( 45 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Edit ED_ASSIGN
+ {
+ Hide = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 119 ) ;
+ Size = MAP_APPFONT ( 128 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_ASSIGN
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 118 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Minimize/Maximize" ;
+ };
+ Text [ en-US ] = "Show Changes" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/inscldlg.cxx b/sc/source/ui/miscdlgs/inscldlg.cxx
new file mode 100644
index 000000000000..2a3489088489
--- /dev/null
+++ b/sc/source/ui/miscdlgs/inscldlg.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "inscldlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+static BYTE nInsItemChecked=0;
+
+//==================================================================
+
+ScInsertCellDlg::ScInsertCellDlg( Window* pParent,BOOL bDisallowCellMove) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_INSCELL ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnCellsDown ( this, ScResId( BTN_CELLSDOWN ) ),
+ aBtnCellsRight ( this, ScResId( BTN_CELLSRIGHT ) ),
+ aBtnInsRows ( this, ScResId( BTN_INSROWS ) ),
+ aBtnInsCols ( this, ScResId( BTN_INSCOLS ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ if (bDisallowCellMove)
+ {
+ aBtnCellsDown.Disable();
+ aBtnCellsRight.Disable();
+ aBtnInsRows.Check();
+
+ switch(nInsItemChecked)
+ {
+ case 2: aBtnInsRows .Check();break;
+ case 3: aBtnInsCols .Check();break;
+ default:aBtnInsRows .Check();break;
+ }
+ }
+ else
+ {
+ switch(nInsItemChecked)
+ {
+ case 0: aBtnCellsDown .Check();break;
+ case 1: aBtnCellsRight.Check();break;
+ case 2: aBtnInsRows .Check();break;
+ case 3: aBtnInsCols .Check();break;
+ }
+ }
+ //-------------
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+InsCellCmd ScInsertCellDlg::GetInsCellCmd() const
+{
+ InsCellCmd nReturn = INS_NONE;
+
+ if ( aBtnCellsDown.IsChecked() )
+ {
+ nInsItemChecked=0;
+ nReturn = INS_CELLSDOWN;
+ }
+ else if ( aBtnCellsRight.IsChecked())
+ {
+ nInsItemChecked=1;
+ nReturn = INS_CELLSRIGHT;
+ }
+ else if ( aBtnInsRows.IsChecked() )
+ {
+ nInsItemChecked=2;
+ nReturn = INS_INSROWS;
+ }
+ else if ( aBtnInsCols.IsChecked() )
+ {
+ nInsItemChecked=3;
+ nReturn = INS_INSCOLS;
+ }
+
+ return nReturn;
+}
+
+__EXPORT ScInsertCellDlg::~ScInsertCellDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/inscodlg.cxx b/sc/source/ui/miscdlgs/inscodlg.cxx
new file mode 100644
index 000000000000..b1c8e31ef373
--- /dev/null
+++ b/sc/source/ui/miscdlgs/inscodlg.cxx
@@ -0,0 +1,372 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "inscodlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+BOOL ScInsertContentsDlg::bPreviousAllCheck = TRUE;
+USHORT ScInsertContentsDlg::nPreviousChecks = (IDF_DATETIME | IDF_STRING |
+ IDF_NOTE | IDF_FORMULA |
+ IDF_ATTRIB | IDF_OBJECTS);
+USHORT ScInsertContentsDlg::nPreviousFormulaChecks = PASTE_NOFUNC;
+USHORT ScInsertContentsDlg::nPreviousChecks2 = 0;
+USHORT ScInsertContentsDlg::nPreviousMoveMode = INS_NONE; // enum InsCellCmd
+
+//-----------------------------------------------------------------------
+
+ScInsertContentsDlg::ScInsertContentsDlg( Window* pParent,
+ USHORT nCheckDefaults,
+ const String* pStrTitle )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_INSCONT ) ),
+ //
+ aFlFrame ( this, ScResId( FL_FRAME ) ),
+ aBtnInsAll ( this, ScResId( BTN_INSALL ) ),
+ aBtnInsStrings ( this, ScResId( BTN_INSSTRINGS ) ),
+ aBtnInsNumbers ( this, ScResId( BTN_INSNUMBERS ) ),
+ aBtnInsDateTime ( this, ScResId( BTN_INSDATETIME ) ),
+ aBtnInsFormulas ( this, ScResId( BTN_INSFORMULAS ) ),
+ aBtnInsNotes ( this, ScResId( BTN_INSNOTES ) ),
+ aBtnInsAttrs ( this, ScResId( BTN_INSATTRS ) ),
+ aBtnInsObjects ( this, ScResId( BTN_INSOBJECTS ) ),
+ aFlSep1 ( this, ScResId( FL_SEP1 ) ),
+ aFlOptions ( this, ScResId( FL_OPTIONS ) ),
+ aBtnSkipEmptyCells( this, ScResId(BTN_SKIP_EMPTY ) ),
+ aBtnTranspose ( this, ScResId( BTN_TRANSPOSE ) ),
+ aBtnLink ( this, ScResId( BTN_LINK ) ),
+ aFlOperation ( this, ScResId( FL_OPERATION ) ),
+ aRbNoOp ( this, ScResId( BTN_OP_NOOP ) ),
+ aRbAdd ( this, ScResId( BTN_OP_ADD ) ),
+ aRbSub ( this, ScResId( BTN_OP_SUB ) ),
+ aRbMul ( this, ScResId( BTN_OP_MUL ) ),
+ aRbDiv ( this, ScResId( BTN_OP_DIV ) ),
+ aFlSep2 ( this, ScResId( FL_SEP2 ) ),
+ aFlMove ( this, ScResId( FL_MOVE ) ),
+ aRbMoveNone ( this, ScResId( BTN_MV_NONE ) ),
+ aRbMoveDown ( this, ScResId( BTN_MV_DOWN ) ),
+ aRbMoveRight ( this, ScResId( BTN_MV_RIGHT ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ bOtherDoc ( FALSE ),
+ bFillMode ( FALSE ),
+ bChangeTrack ( FALSE ),
+ bMoveDownDisabled( FALSE ),
+ bMoveRightDisabled( FALSE )
+{
+ if ( pStrTitle )
+ SetText( *pStrTitle );
+
+ if ( nCheckDefaults != 0 )
+ {
+ ScInsertContentsDlg::nPreviousChecks = nCheckDefaults;
+ ScInsertContentsDlg::bPreviousAllCheck = FALSE;
+ ScInsertContentsDlg::nPreviousChecks2 = 0;
+ }
+
+ aBtnInsAll.Check ( ScInsertContentsDlg::bPreviousAllCheck );
+ aBtnInsStrings.Check ( IS_SET( IDF_STRING,
+ ScInsertContentsDlg::nPreviousChecks ) );
+ aBtnInsNumbers.Check ( IS_SET( IDF_VALUE,
+ ScInsertContentsDlg::nPreviousChecks ) );
+ aBtnInsDateTime.Check( IS_SET( IDF_DATETIME,
+ ScInsertContentsDlg::nPreviousChecks ) );
+ aBtnInsFormulas.Check( IS_SET( IDF_FORMULA,
+ ScInsertContentsDlg::nPreviousChecks ) );
+ aBtnInsNotes.Check ( IS_SET( IDF_NOTE,
+ ScInsertContentsDlg::nPreviousChecks ) );
+ aBtnInsAttrs.Check ( IS_SET( IDF_ATTRIB,
+ ScInsertContentsDlg::nPreviousChecks ) );
+ aBtnInsObjects.Check ( IS_SET( IDF_OBJECTS,
+ ScInsertContentsDlg::nPreviousChecks ) );
+
+ switch( ScInsertContentsDlg::nPreviousFormulaChecks )
+ {
+ case PASTE_NOFUNC: aRbNoOp.Check(TRUE); break;
+ case PASTE_ADD: aRbAdd.Check(TRUE); break;
+ case PASTE_SUB: aRbSub.Check(TRUE); break;
+ case PASTE_MUL: aRbMul.Check(TRUE); break;
+ case PASTE_DIV: aRbDiv.Check(TRUE); break;
+ }
+
+ switch( ScInsertContentsDlg::nPreviousMoveMode )
+ {
+ case INS_NONE: aRbMoveNone.Check(TRUE); break;
+ case INS_CELLSDOWN: aRbMoveDown.Check(TRUE); break;
+ case INS_CELLSRIGHT: aRbMoveRight.Check(TRUE); break;
+ }
+
+ aBtnSkipEmptyCells.Check( ( ScInsertContentsDlg::nPreviousChecks2 & INS_CONT_NOEMPTY ) != 0);
+ aBtnTranspose.Check( ( ScInsertContentsDlg::nPreviousChecks2 & INS_CONT_TRANS ) != 0);
+ aBtnLink.Check( ( ScInsertContentsDlg::nPreviousChecks2 & INS_CONT_LINK ) != 0);
+
+ DisableChecks( aBtnInsAll.IsChecked() );
+
+ aFlSep1.SetStyle( aFlSep1.GetStyle() | WB_VERT );
+ aFlSep2.SetStyle( aFlSep2.GetStyle() | WB_VERT );
+
+ aBtnInsAll.SetClickHdl( LINK( this, ScInsertContentsDlg, InsAllHdl ) );
+ aBtnLink.SetClickHdl( LINK( this, ScInsertContentsDlg, LinkBtnHdl ) );
+
+ //-------------
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScInsertContentsDlg::GetInsContentsCmdBits() const
+{
+ ScInsertContentsDlg::nPreviousChecks = 0;
+
+ if ( aBtnInsStrings.IsChecked() )
+ ScInsertContentsDlg::nPreviousChecks = IDF_STRING;
+ if ( aBtnInsNumbers.IsChecked() )
+ ScInsertContentsDlg::nPreviousChecks |= IDF_VALUE;
+ if ( aBtnInsDateTime.IsChecked())
+ ScInsertContentsDlg::nPreviousChecks |= IDF_DATETIME;
+ if ( aBtnInsFormulas.IsChecked())
+ ScInsertContentsDlg::nPreviousChecks |= IDF_FORMULA;
+ if ( aBtnInsNotes.IsChecked() )
+ ScInsertContentsDlg::nPreviousChecks |= IDF_NOTE;
+ if ( aBtnInsAttrs.IsChecked() )
+ ScInsertContentsDlg::nPreviousChecks |= IDF_ATTRIB;
+ if ( aBtnInsObjects.IsChecked() )
+ ScInsertContentsDlg::nPreviousChecks |= IDF_OBJECTS;
+
+ ScInsertContentsDlg::bPreviousAllCheck = aBtnInsAll.IsChecked();
+
+ return ( (ScInsertContentsDlg::bPreviousAllCheck)
+ ? IDF_ALL
+ : ScInsertContentsDlg::nPreviousChecks );
+}
+
+//------------------------------------------------------------------------
+
+InsCellCmd ScInsertContentsDlg::GetMoveMode()
+{
+ if ( aRbMoveDown.IsChecked() )
+ return INS_CELLSDOWN;
+ if ( aRbMoveRight.IsChecked() )
+ return INS_CELLSRIGHT;
+
+ return INS_NONE;
+}
+
+//------------------------------------------------------------------------
+
+void ScInsertContentsDlg::DisableChecks( BOOL bInsAllChecked )
+{
+ if ( bInsAllChecked )
+ {
+ aBtnInsStrings.Disable();
+ aBtnInsNumbers.Disable();
+ aBtnInsDateTime.Disable();
+ aBtnInsFormulas.Disable();
+ aBtnInsNotes.Disable();
+ aBtnInsAttrs.Disable();
+ aBtnInsObjects.Disable();
+ }
+ else
+ {
+ aBtnInsStrings.Enable();
+ aBtnInsNumbers.Enable();
+ aBtnInsDateTime.Enable();
+ aBtnInsFormulas.Enable();
+ aBtnInsNotes.Enable();
+ aBtnInsAttrs.Enable();
+
+ // "Objects" is disabled for "Fill Tables"
+ if ( bFillMode )
+ aBtnInsObjects.Disable();
+ else
+ aBtnInsObjects.Enable();
+ }
+}
+
+// Link in anderes Dokument -> alles andere disabled
+
+void ScInsertContentsDlg::TestModes()
+{
+ if ( bOtherDoc && aBtnLink.IsChecked() )
+ {
+ aBtnSkipEmptyCells.Disable();
+ aBtnTranspose.Disable();
+ aRbNoOp.Disable();
+ aRbAdd.Disable();
+ aRbSub.Disable();
+ aRbMul.Disable();
+ aRbDiv.Disable();
+ aFlOperation.Disable();
+
+ aRbMoveNone.Disable();
+ aRbMoveDown.Disable();
+ aRbMoveRight.Disable();
+ aFlMove.Disable();
+
+ aFlFrame.Disable();
+ aBtnInsAll.Disable();
+ DisableChecks(TRUE);
+ }
+ else
+ {
+ aBtnSkipEmptyCells.Enable();
+ aBtnTranspose.Enable(!bFillMode);
+ aRbNoOp.Enable();
+ aRbAdd.Enable();
+ aRbSub.Enable();
+ aRbMul.Enable();
+ aRbDiv.Enable();
+ aFlOperation.Enable();
+
+ aRbMoveNone.Enable(!bFillMode && !bChangeTrack && !(bMoveDownDisabled && bMoveRightDisabled));
+ aRbMoveDown.Enable(!bFillMode && !bChangeTrack && !bMoveDownDisabled);
+ aRbMoveRight.Enable(!bFillMode && !bChangeTrack && !bMoveRightDisabled);
+ aFlMove.Enable(!bFillMode && !bChangeTrack && !(bMoveDownDisabled && bMoveRightDisabled));
+
+ aFlFrame.Enable();
+ aBtnInsAll.Enable();
+ DisableChecks( aBtnInsAll.IsChecked() );
+ }
+}
+
+void ScInsertContentsDlg::SetOtherDoc( BOOL bSet )
+{
+ if ( bSet != bOtherDoc )
+ {
+ bOtherDoc = bSet;
+ TestModes();
+ if ( bSet )
+ aRbMoveNone.Check(TRUE);
+ }
+}
+
+void ScInsertContentsDlg::SetFillMode( BOOL bSet )
+{
+ if ( bSet != bFillMode )
+ {
+ bFillMode = bSet;
+ TestModes();
+ if ( bSet )
+ aRbMoveNone.Check(TRUE);
+ }
+}
+
+void ScInsertContentsDlg::SetChangeTrack( BOOL bSet )
+{
+ if ( bSet != bChangeTrack )
+ {
+ bChangeTrack = bSet;
+ TestModes();
+ if ( bSet )
+ aRbMoveNone.Check(TRUE);
+ }
+}
+
+void ScInsertContentsDlg::SetCellShiftDisabled( int nDisable )
+{
+ BOOL bDown = ((nDisable & SC_CELL_SHIFT_DISABLE_DOWN) != 0);
+ BOOL bRight = ((nDisable & SC_CELL_SHIFT_DISABLE_RIGHT) != 0);
+ if ( bDown != bMoveDownDisabled || bRight != bMoveRightDisabled )
+ {
+ bMoveDownDisabled = bDown;
+ bMoveRightDisabled = bRight;
+ TestModes();
+ if ( bMoveDownDisabled && aRbMoveDown.IsChecked() )
+ aRbMoveNone.Check(TRUE);
+ if ( bMoveRightDisabled && aRbMoveRight.IsChecked() )
+ aRbMoveNone.Check(TRUE);
+ }
+}
+
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScInsertContentsDlg, InsAllHdl, void*, EMPTYARG )
+{
+ DisableChecks( aBtnInsAll.IsChecked() );
+
+ return 0;
+}
+
+IMPL_LINK( ScInsertContentsDlg, LinkBtnHdl, void*, EMPTYARG )
+{
+ TestModes();
+
+ return 0;
+}
+
+__EXPORT ScInsertContentsDlg::~ScInsertContentsDlg()
+{
+ ScInsertContentsDlg::nPreviousChecks2 = 0;
+ if(aBtnSkipEmptyCells.IsChecked())
+ ScInsertContentsDlg::nPreviousChecks2 |= INS_CONT_NOEMPTY;
+ if( aBtnTranspose.IsChecked())
+ ScInsertContentsDlg::nPreviousChecks2 |= INS_CONT_TRANS;
+ if( aBtnLink.IsChecked() )
+ ScInsertContentsDlg::nPreviousChecks2 |= INS_CONT_LINK;
+
+ if (!bFillMode) // im FillMode ist None gecheckt und alle 3 disabled
+ {
+ if ( aRbMoveNone.IsChecked() )
+ ScInsertContentsDlg::nPreviousMoveMode = INS_NONE;
+ else if ( aRbMoveDown.IsChecked() )
+ ScInsertContentsDlg::nPreviousMoveMode = INS_CELLSDOWN;
+ else if ( aRbMoveRight.IsChecked() )
+ ScInsertContentsDlg::nPreviousMoveMode = INS_CELLSRIGHT;
+ }
+}
+
+USHORT ScInsertContentsDlg::GetFormulaCmdBits() const
+{
+ ScInsertContentsDlg::nPreviousFormulaChecks = PASTE_NOFUNC;
+ if(aRbAdd.IsChecked())
+ ScInsertContentsDlg::nPreviousFormulaChecks = PASTE_ADD;
+ else if(aRbSub.IsChecked())
+ ScInsertContentsDlg::nPreviousFormulaChecks = PASTE_SUB;
+ else if(aRbMul.IsChecked())
+ ScInsertContentsDlg::nPreviousFormulaChecks = PASTE_MUL;
+ else if(aRbDiv.IsChecked())
+ ScInsertContentsDlg::nPreviousFormulaChecks = PASTE_DIV;
+ // Bits fuer Checkboxen ausblenden
+ return ScInsertContentsDlg::nPreviousFormulaChecks;
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/instbdlg.cxx b/sc/source/ui/miscdlgs/instbdlg.cxx
new file mode 100644
index 000000000000..06d4f23389c0
--- /dev/null
+++ b/sc/source/ui/miscdlgs/instbdlg.cxx
@@ -0,0 +1,433 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docinsert.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "global.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+#include "scresid.hxx"
+#include "instbdlg.hrc"
+#include "globstr.hrc"
+
+#define SC_INSTBDLG_CXX
+#include "instbdlg.hxx"
+
+#include <layout/layout-pre.hxx>
+
+#if ENABLE_LAYOUT
+#undef ScResId
+#define ScResId(x) #x
+#undef ModalDialog
+#define ModalDialog( parent, id ) Dialog( parent, "insert-sheet.xml", id )
+#undef ErrorBox
+#define ErrorBox( this, bits, message ) ErrorBox (LAYOUT_THIS_WINDOW (this), bits, message)
+#endif /* ENABLE_LAYOUT */
+
+//==================================================================
+
+ScInsertTableDlg::ScInsertTableDlg( Window* pParent, ScViewData& rData, SCTAB nTabCount, bool bFromFile )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_INSERT_TABLE ) ),
+ //
+ aBtnBefore ( this, ScResId( RB_BEFORE ) ),
+ aBtnBehind ( this, ScResId( RB_BEHIND ) ),
+ aFlPos ( this, ScResId( FL_POSITION ) ),
+ aBtnNew ( this, ScResId( RB_NEW ) ),
+ aBtnFromFile ( this, ScResId( RB_FROMFILE ) ),
+ aFtCount ( this, ScResId( FT_COUNT ) ),
+ aNfCount ( this, ScResId( NF_COUNT ) ),
+ aFtName ( this, ScResId( FT_NAME ) ),
+ aEdName ( this, ScResId( ED_TABNAME ) ),
+ aLbTables ( this, ScResId( LB_TABLES ) ),
+ aFtPath ( this, ScResId( FT_PATH ) ),
+ aBtnBrowse ( this, ScResId( BTN_BROWSE ) ),
+ aBtnLink ( this, ScResId( CB_LINK ) ),
+ aFlTable ( this, ScResId( FL_TABLE ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ rViewData ( rData ),
+ rDoc ( *rData.GetDocument() ),
+ pDocShTables ( NULL ),
+ pDocInserter ( NULL ),
+ bMustClose ( false ),
+ nSelTabIndex ( 0 ),
+ nTableCount (nTabCount)
+{
+#if ENABLE_LAYOUT
+ SetHelpId (SID_INSERT_TABLE);
+ aFtPath.SetText (EMPTY_STRING);
+#endif /* ENABLE_LAYOUT */
+ Init_Impl( bFromFile );
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScInsertTableDlg::~ScInsertTableDlg()
+{
+ if (pDocShTables)
+ pDocShTables->DoClose();
+ delete pDocInserter;
+}
+
+//------------------------------------------------------------------------
+
+void ScInsertTableDlg::Init_Impl( bool bFromFile )
+{
+ aBtnBrowse .SetClickHdl( LINK( this, ScInsertTableDlg, BrowseHdl_Impl ) );
+ aBtnNew .SetClickHdl( LINK( this, ScInsertTableDlg, ChoiceHdl_Impl ) );
+ aBtnFromFile .SetClickHdl( LINK( this, ScInsertTableDlg, ChoiceHdl_Impl ) );
+ aLbTables .SetSelectHdl( LINK( this, ScInsertTableDlg, SelectHdl_Impl ) );
+ aNfCount .SetModifyHdl( LINK( this, ScInsertTableDlg, CountHdl_Impl));
+ aBtnOk .SetClickHdl( LINK( this, ScInsertTableDlg, DoEnterHdl ));
+ aBtnBefore.Check();
+
+ aNfCount.SetText( String::CreateFromInt32(nTableCount) );
+ aNfCount.SetMax( MAXTAB - rDoc.GetTableCount() + 1 );
+
+ if(nTableCount==1)
+ {
+ String aName;
+ rDoc.CreateValidTabName( aName );
+ aEdName.SetText( aName );
+ }
+ else
+ {
+ String aName=aFlTable.GetText();
+ aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
+ aEdName.SetText( aName );
+ aFtName.Disable();
+ aEdName.Disable();
+ }
+
+ bool bShared = ( rViewData.GetDocShell() ? rViewData.GetDocShell()->IsDocShared() : false );
+
+ if ( !bFromFile || bShared )
+ {
+ aBtnNew.Check();
+ SetNewTable_Impl();
+ if ( bShared )
+ {
+ aBtnFromFile.Disable();
+ }
+ }
+ else
+ {
+ aBtnFromFile.Check();
+ SetFromTo_Impl();
+
+ aBrowseTimer.SetTimeoutHdl( LINK( this, ScInsertTableDlg, BrowseTimeoutHdl ) );
+ aBrowseTimer.SetTimeout( 200 );
+ }
+}
+
+//------------------------------------------------------------------------
+
+#if ENABLE_LAYOUT
+#undef ModalDialog
+#define ModalDialog Dialog
+#endif /* ENABLE_LAYOUT */
+
+short __EXPORT ScInsertTableDlg::Execute()
+{
+ // set Parent of DocumentInserter and Doc-Manager
+ Window* pOldDefParent = Application::GetDefDialogParent();
+ Application::SetDefDialogParent( LAYOUT_THIS_WINDOW (this) );
+
+ if ( aBtnFromFile.IsChecked() )
+ aBrowseTimer.Start();
+
+ short nRet = ModalDialog::Execute();
+ Application::SetDefDialogParent( pOldDefParent );
+ return nRet;
+}
+
+//------------------------------------------------------------------------
+
+void ScInsertTableDlg::SetNewTable_Impl()
+{
+ if (aBtnNew.IsChecked() )
+ {
+ aNfCount .Enable();
+ aFtCount .Enable();
+ aLbTables .Disable();
+ aFtPath .Disable();
+ aBtnBrowse .Disable();
+ aBtnLink .Disable();
+
+ if(nTableCount==1)
+ {
+ aEdName.Enable();
+ aFtName.Enable();
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScInsertTableDlg::SetFromTo_Impl()
+{
+ if (aBtnFromFile.IsChecked() )
+ {
+ aEdName .Disable();
+ aFtName .Disable();
+ aFtCount .Disable();
+ aNfCount .Disable();
+ aLbTables .Enable();
+ aFtPath .Enable();
+ aBtnBrowse .Enable();
+ aBtnLink .Enable();
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScInsertTableDlg::FillTables_Impl( ScDocument* pSrcDoc )
+{
+ aLbTables.SetUpdateMode( FALSE );
+ aLbTables.Clear();
+
+ if ( pSrcDoc )
+ {
+ SCTAB nCount = pSrcDoc->GetTableCount();
+ String aName;
+
+ for ( SCTAB i=0; i<nCount; i++ )
+ {
+ pSrcDoc->GetName( i, aName );
+ aLbTables.InsertEntry( aName );
+ }
+ }
+
+ aLbTables.SetUpdateMode( TRUE );
+
+ if(aLbTables.GetEntryCount()==1)
+ aLbTables.SelectEntryPos(0);
+}
+
+//------------------------------------------------------------------------
+
+const String* ScInsertTableDlg::GetFirstTable( USHORT* pN )
+{
+ const String* pStr = NULL;
+
+ if ( aBtnNew.IsChecked() )
+ {
+ aStrCurSelTable = aEdName.GetText();
+ pStr = &aStrCurSelTable;
+ }
+ else if ( nSelTabIndex < aLbTables.GetSelectEntryCount() )
+ {
+ aStrCurSelTable = aLbTables.GetSelectEntry( 0 );
+ pStr = &aStrCurSelTable;
+ if ( pN )
+ *pN = aLbTables.GetSelectEntryPos( 0 );
+ nSelTabIndex = 1;
+ }
+
+ return pStr;
+}
+
+//------------------------------------------------------------------------
+
+const String* ScInsertTableDlg::GetNextTable( USHORT* pN )
+{
+ const String* pStr = NULL;
+
+ if ( !aBtnNew.IsChecked() && nSelTabIndex < aLbTables.GetSelectEntryCount() )
+ {
+ aStrCurSelTable = aLbTables.GetSelectEntry( nSelTabIndex );
+ pStr = &aStrCurSelTable;
+ if ( pN )
+ *pN = aLbTables.GetSelectEntryPos( nSelTabIndex );
+ nSelTabIndex++;
+ }
+
+ return pStr;
+}
+
+
+//------------------------------------------------------------------------
+// Handler:
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScInsertTableDlg, CountHdl_Impl, NumericField*, EMPTYARG )
+{
+ nTableCount = static_cast<SCTAB>(aNfCount.GetValue());
+ if ( nTableCount==1)
+ {
+ String aName;
+ rDoc.CreateValidTabName( aName );
+ aEdName.SetText( aName );
+ aFtName.Enable();
+ aEdName.Enable();
+ }
+ else
+ {
+ String aName=aFlTable.GetText();
+ aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
+ aEdName.SetText( aName );
+ aFtName.Disable();
+ aEdName.Disable();
+ }
+
+ DoEnable_Impl();
+ return 0;
+}
+
+//------------------------------------------------------------------------
+IMPL_LINK( ScInsertTableDlg, ChoiceHdl_Impl, RadioButton*, EMPTYARG )
+{
+ if ( aBtnNew.IsChecked() )
+ SetNewTable_Impl();
+ else
+ SetFromTo_Impl();
+
+ DoEnable_Impl();
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScInsertTableDlg, BrowseHdl_Impl, PushButton*, EMPTYARG )
+{
+ if ( pDocInserter )
+ delete pDocInserter;
+ pDocInserter = new ::sfx2::DocumentInserter(
+ 0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ) );
+ pDocInserter->StartExecuteModal( LINK( this, ScInsertTableDlg, DialogClosedHdl ) );
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScInsertTableDlg, SelectHdl_Impl, MultiListBox*, EMPTYARG )
+{
+ DoEnable_Impl();
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+void ScInsertTableDlg::DoEnable_Impl()
+{
+ if ( aBtnNew.IsChecked() || ( pDocShTables && aLbTables.GetSelectEntryCount() ) )
+ aBtnOk.Enable();
+ else
+ aBtnOk.Disable();
+}
+
+IMPL_LINK( ScInsertTableDlg, DoEnterHdl, PushButton*, EMPTYARG )
+{
+ if(nTableCount > 1 || rDoc.ValidTabName(aEdName.GetText()))
+ {
+ EndDialog(RET_OK);
+ }
+ else
+ {
+ String aErrMsg ( ScGlobal::GetRscString( STR_INVALIDTABNAME ) );
+ (void)ErrorBox( this,WinBits( WB_OK | WB_DEF_OK ),aErrMsg).Execute();
+ }
+ return 0;
+}
+
+IMPL_LINK( ScInsertTableDlg, BrowseTimeoutHdl, Timer*, EMPTYARG )
+{
+ bMustClose = true;
+ BrowseHdl_Impl( &aBtnBrowse );
+ return 0;
+}
+
+IMPL_LINK( ScInsertTableDlg, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
+{
+ if ( ERRCODE_NONE == _pFileDlg->GetError() )
+ {
+ SfxMedium* pMed = pDocInserter->CreateMedium();
+ if ( pMed )
+ {
+ // ERRCTX_SFX_OPENDOC -> "Fehler beim Laden des Dokumentes"
+ SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
+
+ if ( pDocShTables )
+ pDocShTables->DoClose(); // delete passiert beim Zuweisen auf die Ref
+
+ pMed->UseInteractionHandler( TRUE ); // to enable the filter options dialog
+
+ pDocShTables = new ScDocShell;
+ aDocShTablesRef = pDocShTables;
+
+ Pointer aOldPtr( GetPointer() );
+ SetPointer( Pointer( POINTER_WAIT ) );
+ pDocShTables->DoLoad( pMed );
+ SetPointer( aOldPtr );
+
+ ULONG nErr = pDocShTables->GetErrorCode();
+ if ( nErr )
+ ErrorHandler::HandleError( nErr ); // auch Warnings
+
+ if ( !pDocShTables->GetError() ) // nur Errors
+ {
+ FillTables_Impl( pDocShTables->GetDocument() );
+ aFtPath.SetText( pDocShTables->GetTitle( SFX_TITLE_FULLNAME ) );
+ }
+ else
+ {
+ pDocShTables->DoClose();
+ aDocShTablesRef.Clear();
+ pDocShTables = NULL;
+
+ FillTables_Impl( NULL );
+ aFtPath.SetText( EMPTY_STRING );
+ }
+ }
+
+ DoEnable_Impl();
+ }
+ else if ( bMustClose )
+ // execute slot FID_INS_TABLE_EXT and cancel file dialog
+ EndDialog( RET_CANCEL );
+
+ return 0;
+}
+
diff --git a/sc/source/ui/miscdlgs/instbdlg.src b/sc/source/ui/miscdlgs/instbdlg.src
new file mode 100644
index 000000000000..6f64c0de1d62
--- /dev/null
+++ b/sc/source/ui/miscdlgs/instbdlg.src
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "instbdlg.hrc"
+ModalDialog RID_SCDLG_INSERT_TABLE
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 274 , 190 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Tabelle einfügen : Tabelle einf³gen */
+ Text [ en-US ] = "Insert Sheet" ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 218 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 218 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 218 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ FixedLine FL_POSITION
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 206 , 8 ) ;
+ Text [ en-US ] = "Position" ;
+ };
+ RadioButton RB_BEFORE
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 197 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "B~efore current sheet" ;
+ };
+ RadioButton RB_BEHIND
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 197 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~After current sheet" ;
+ };
+ FixedLine FL_TABLE
+ {
+ Pos = MAP_APPFONT ( 6 , 44 ) ;
+ Size = MAP_APPFONT ( 206 , 8 ) ;
+ Text [ en-US ] = "Sheet" ;
+ };
+ RadioButton RB_NEW
+ {
+ Pos = MAP_APPFONT ( 12 , 55 ) ;
+ Size = MAP_APPFONT ( 197 , 10 ) ;
+ Text [ en-US ] = "~New sheet" ;
+ };
+ FixedText FT_COUNT
+ {
+ Pos = MAP_APPFONT ( 20 , 68 ) ;
+ Size = MAP_APPFONT ( 52 , 8 ) ;
+ Text [ en-US ] = "N~o. of sheets" ;
+ };
+ NumericField NF_COUNT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 72 , 66 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ Maximum = 256 ;
+ };
+ FixedText FT_NAME
+ {
+ Pos = MAP_APPFONT ( 20 , 84 ) ;
+ Size = MAP_APPFONT ( 50 , 8 ) ;
+ Text [ en-US ] = "Na~me";
+ };
+ Edit ED_TABNAME
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 72 , 82 ) ;
+ Size = MAP_APPFONT ( 137 , 12 ) ;
+ };
+ RadioButton RB_FROMFILE
+ {
+ Pos = MAP_APPFONT ( 12 , 100 ) ;
+ Size = MAP_APPFONT ( 197 , 10 ) ;
+ Text [ en-US ] = "~From file" ;
+ };
+ MultiListBox LB_TABLES
+ {
+ SimpleMode = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 113 ) ;
+ Size = MAP_APPFONT ( 123 , 59 ) ;
+ AutoHScroll = TRUE ;
+ };
+ PushButton BTN_BROWSE
+ {
+ Pos = MAP_APPFONT ( 149 , 113 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ Text [ en-US ] = "~Browse..." ;
+ };
+ CheckBox CB_LINK
+ {
+ Pos = MAP_APPFONT ( 149 , 131 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ver~knüpfen : Ver~kn³pfen */
+ Text [ en-US ] = "Lin~k" ;
+ };
+ FixedText FT_PATH
+ {
+ Pos = MAP_APPFONT ( 20 , 176 ) ;
+ Size = MAP_APPFONT ( 192 , 8 ) ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/lbseldlg.cxx b/sc/source/ui/miscdlgs/lbseldlg.cxx
new file mode 100644
index 000000000000..79dcfe3b7ad8
--- /dev/null
+++ b/sc/source/ui/miscdlgs/lbseldlg.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <vcl/msgbox.hxx>
+
+#include "lbseldlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+ScSelEntryDlg::ScSelEntryDlg( Window* pParent,
+ USHORT nResId,
+ const String& aTitle,
+ const String& aLbTitle,
+ List& aEntryList ) :
+ ModalDialog ( pParent, ScResId( nResId ) ),
+ //
+ aFlLbTitle ( this, ScResId( FL_ENTRYLIST ) ),
+ aLb ( this, ScResId( LB_ENTRYLIST ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ SetText( aTitle );
+ aFlLbTitle.SetText( aLbTitle );
+ aLb.Clear();
+ aLb.SetDoubleClickHdl( LINK( this, ScSelEntryDlg, DblClkHdl ) );
+
+ void* pListEntry = aEntryList.First();
+ while ( pListEntry )
+ {
+ aLb.InsertEntry( *((String*)pListEntry ) );
+ pListEntry = aEntryList.Next();
+ }
+
+ if ( aLb.GetEntryCount() > 0 )
+ aLb.SelectEntryPos( 0 );
+
+ //-------------
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+String ScSelEntryDlg::GetSelectEntry() const
+{
+ return aLb.GetSelectEntry();
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 USHORT ScSelEntryDlg::GetSelectEntryPos() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return aLb.GetSelectEntryPos();
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScSelEntryDlg, DblClkHdl, void *, EMPTYARG )
+{
+ EndDialog( RET_OK );
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScSelEntryDlg, DblClkHdl, void *, EMPTYARG )
+
+//------------------------------------------------------------------------
+
+__EXPORT ScSelEntryDlg::~ScSelEntryDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/linkarea.cxx b/sc/source/ui/miscdlgs/linkarea.cxx
new file mode 100644
index 000000000000..48e33622e99f
--- /dev/null
+++ b/sc/source/ui/miscdlgs/linkarea.cxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docinsert.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <vcl/waitobj.hxx>
+
+#include "linkarea.hxx"
+#include "linkarea.hrc"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "rangeutl.hxx"
+#include "docsh.hxx"
+#include "tablink.hxx"
+
+//==================================================================
+
+ScLinkedAreaDlg::ScLinkedAreaDlg( Window* pParent ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_LINKAREA ) ),
+ //
+ aFlLocation ( this, ScResId( FL_LOCATION ) ),
+ aCbUrl ( this, ScResId( CB_URL ) ),
+ aBtnBrowse ( this, ScResId( BTN_BROWSE ) ),
+ aTxtHint ( this, ScResId( FT_HINT ) ),
+ aFtRanges ( this, ScResId( FT_RANGES ) ),
+ aLbRanges ( this, ScResId( LB_RANGES ) ),
+ aBtnReload ( this, ScResId( BTN_RELOAD ) ),
+ aNfDelay ( this, ScResId( NF_DELAY ) ),
+ aFtSeconds ( this, ScResId( FT_SECONDS ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ //
+ pSourceShell( NULL ),
+ pDocInserter( NULL )
+
+{
+ FreeResource();
+
+ aCbUrl.SetHelpId( HID_SCDLG_LINKAREAURL ); // SvtURLBox ctor always sets SID_OPENURL
+ aCbUrl.SetSelectHdl( LINK( this, ScLinkedAreaDlg, FileHdl ) );
+ aBtnBrowse.SetClickHdl( LINK( this, ScLinkedAreaDlg, BrowseHdl ) );
+ aLbRanges.SetSelectHdl( LINK( this, ScLinkedAreaDlg, RangeHdl ) );
+ aBtnReload.SetClickHdl( LINK( this, ScLinkedAreaDlg, ReloadHdl ) );
+ UpdateEnable();
+}
+
+ScLinkedAreaDlg::~ScLinkedAreaDlg()
+{
+ // pSourceShell is deleted by aSourceRef
+}
+
+short ScLinkedAreaDlg::Execute()
+{
+ // set parent for file dialog or filter options
+
+ Window* pOldDefParent = Application::GetDefDialogParent();
+ Application::SetDefDialogParent( this );
+
+ short nRet = ModalDialog::Execute();
+
+ Application::SetDefDialogParent( pOldDefParent );
+
+ return nRet;
+}
+
+#define FILTERNAME_HTML "HTML (StarCalc)"
+#define FILTERNAME_QUERY "calc_HTML_WebQuery"
+
+IMPL_LINK( ScLinkedAreaDlg, BrowseHdl, PushButton*, EMPTYARG )
+{
+ if ( !pDocInserter )
+ pDocInserter = new sfx2::DocumentInserter(
+ 0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ) );
+ pDocInserter->StartExecuteModal( LINK( this, ScLinkedAreaDlg, DialogClosedHdl ) );
+ return 0;
+}
+
+IMPL_LINK( ScLinkedAreaDlg, FileHdl, ComboBox*, EMPTYARG )
+{
+ String aEntered = aCbUrl.GetURL();
+ if (pSourceShell)
+ {
+ SfxMedium* pMed = pSourceShell->GetMedium();
+ if ( pMed->GetName() == aEntered )
+ {
+ // already loaded - nothing to do
+ return 0;
+ }
+ }
+
+ String aFilter;
+ String aOptions;
+ // get filter name by looking at the file content (bWithContent = TRUE)
+ // Break operation if any error occured inside.
+ if (!ScDocumentLoader::GetFilterName( aEntered, aFilter, aOptions, TRUE, TRUE ))
+ return 0;
+
+ // #i53241# replace HTML filter with DataQuery filter
+ if( aFilter.EqualsAscii( FILTERNAME_HTML ) )
+ aFilter.AssignAscii( FILTERNAME_QUERY );
+
+ LoadDocument( aEntered, aFilter, aOptions );
+
+ UpdateSourceRanges();
+ UpdateEnable();
+ return 0;
+}
+
+void ScLinkedAreaDlg::LoadDocument( const String& rFile, const String& rFilter, const String& rOptions )
+{
+ if ( pSourceShell )
+ {
+ // unload old document
+ pSourceShell->DoClose();
+ pSourceShell = NULL;
+ aSourceRef.Clear();
+ }
+
+ if ( rFile.Len() )
+ {
+ WaitObject aWait( this );
+
+ String aNewFilter = rFilter;
+ String aNewOptions = rOptions;
+
+ SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, rFile );
+
+ ScDocumentLoader aLoader( rFile, aNewFilter, aNewOptions, 0, TRUE ); // with interaction
+ pSourceShell = aLoader.GetDocShell();
+ if ( pSourceShell )
+ {
+ ULONG nErr = pSourceShell->GetErrorCode();
+ if (nErr)
+ ErrorHandler::HandleError( nErr ); // including warnings
+
+ aSourceRef = pSourceShell;
+ aLoader.ReleaseDocRef(); // don't call DoClose in DocLoader dtor
+ }
+ }
+}
+
+void ScLinkedAreaDlg::InitFromOldLink( const String& rFile, const String& rFilter,
+ const String& rOptions, const String& rSource,
+ ULONG nRefresh )
+{
+ LoadDocument( rFile, rFilter, rOptions );
+ if (pSourceShell)
+ {
+ SfxMedium* pMed = pSourceShell->GetMedium();
+ aCbUrl.SetText( pMed->GetName() );
+ }
+ else
+ aCbUrl.SetText( EMPTY_STRING );
+
+ UpdateSourceRanges();
+
+ xub_StrLen nRangeCount = rSource.GetTokenCount();
+ for ( xub_StrLen i=0; i<nRangeCount; i++ )
+ {
+ String aRange = rSource.GetToken(i);
+ aLbRanges.SelectEntry( aRange );
+ }
+
+ BOOL bDoRefresh = ( nRefresh != 0 );
+ aBtnReload.Check( bDoRefresh );
+ if (bDoRefresh)
+ aNfDelay.SetValue( nRefresh );
+
+ UpdateEnable();
+}
+
+IMPL_LINK( ScLinkedAreaDlg, RangeHdl, MultiListBox*, EMPTYARG )
+{
+ UpdateEnable();
+ return 0;
+}
+
+IMPL_LINK( ScLinkedAreaDlg, ReloadHdl, CheckBox*, EMPTYARG )
+{
+ UpdateEnable();
+ return 0;
+}
+
+IMPL_LINK( ScLinkedAreaDlg, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
+{
+ if ( _pFileDlg->GetError() != ERRCODE_NONE )
+ return 0;
+
+ SfxMedium* pMed = pDocInserter->CreateMedium();
+ if ( pMed )
+ {
+ WaitObject aWait( this );
+
+ // #92296# replace HTML filter with DataQuery filter
+ const String aHTMLFilterName( RTL_CONSTASCII_USTRINGPARAM( FILTERNAME_HTML ) );
+ const String aWebQFilterName( RTL_CONSTASCII_USTRINGPARAM( FILTERNAME_QUERY ) );
+
+ const SfxFilter* pFilter = pMed->GetFilter();
+ if( pFilter && (pFilter->GetFilterName() == aHTMLFilterName) )
+ {
+ const SfxFilter* pNewFilter =
+ ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aWebQFilterName );
+ if( pNewFilter )
+ pMed->SetFilter( pNewFilter );
+ }
+
+ // ERRCTX_SFX_OPENDOC -> "Fehler beim Laden des Dokumentes"
+ SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
+
+ if (pSourceShell)
+ pSourceShell->DoClose(); // deleted when assigning aSourceRef
+
+ pMed->UseInteractionHandler( TRUE ); // to enable the filter options dialog
+
+ pSourceShell = new ScDocShell;
+ aSourceRef = pSourceShell;
+ pSourceShell->DoLoad( pMed );
+
+ ULONG nErr = pSourceShell->GetErrorCode();
+ if (nErr)
+ ErrorHandler::HandleError( nErr ); // including warnings
+
+ if ( !pSourceShell->GetError() ) // only errors
+ {
+ //aCbUrl.SetText( pSourceShell->GetTitle( SFX_TITLE_FULLNAME ) );
+ aCbUrl.SetText( pMed->GetName() );
+ }
+ else
+ {
+ pSourceShell->DoClose();
+ pSourceShell = NULL;
+ aSourceRef.Clear();
+
+ aCbUrl.SetText( EMPTY_STRING );
+ }
+ }
+
+ UpdateSourceRanges();
+ UpdateEnable();
+ return 0;
+}
+
+#undef FILTERNAME_HTML
+#undef FILTERNAME_QUERY
+
+void ScLinkedAreaDlg::UpdateSourceRanges()
+{
+ aLbRanges.SetUpdateMode( FALSE );
+
+ aLbRanges.Clear();
+ if ( pSourceShell )
+ {
+ ScAreaNameIterator aIter( pSourceShell->GetDocument() );
+ ScRange aDummy;
+ String aName;
+ while ( aIter.Next( aName, aDummy ) )
+ aLbRanges.InsertEntry( aName );
+ }
+
+ aLbRanges.SetUpdateMode( TRUE );
+
+ if ( aLbRanges.GetEntryCount() == 1 )
+ aLbRanges.SelectEntryPos(0);
+}
+
+void ScLinkedAreaDlg::UpdateEnable()
+{
+ BOOL bEnable = ( pSourceShell && aLbRanges.GetSelectEntryCount() );
+ aBtnOk.Enable( bEnable );
+
+ BOOL bReload = aBtnReload.IsChecked();
+ aNfDelay.Enable( bReload );
+ aFtSeconds.Enable( bReload );
+}
+
+String ScLinkedAreaDlg::GetURL()
+{
+ if (pSourceShell)
+ {
+ SfxMedium* pMed = pSourceShell->GetMedium();
+ return pMed->GetName();
+ }
+ return EMPTY_STRING;
+}
+
+String ScLinkedAreaDlg::GetFilter()
+{
+ if (pSourceShell)
+ {
+ SfxMedium* pMed = pSourceShell->GetMedium();
+ return pMed->GetFilter()->GetFilterName();
+ }
+ return EMPTY_STRING;
+}
+
+String ScLinkedAreaDlg::GetOptions()
+{
+ if (pSourceShell)
+ {
+ SfxMedium* pMed = pSourceShell->GetMedium();
+ return ScDocumentLoader::GetOptions( *pMed );
+ }
+ return EMPTY_STRING;
+}
+
+String ScLinkedAreaDlg::GetSource()
+{
+ String aSource;
+ USHORT nCount = aLbRanges.GetSelectEntryCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ if (i > 0)
+ aSource.Append( (sal_Unicode) ';' );
+ aSource.Append( aLbRanges.GetSelectEntry( i ) );
+ }
+ return aSource;
+}
+
+ULONG ScLinkedAreaDlg::GetRefresh()
+{
+ if ( aBtnReload.IsChecked() )
+ return sal::static_int_cast<ULONG>( aNfDelay.GetValue() );
+ else
+ return 0; // disabled
+}
+
diff --git a/sc/source/ui/miscdlgs/linkarea.src b/sc/source/ui/miscdlgs/linkarea.src
new file mode 100644
index 000000000000..715d3fd20766
--- /dev/null
+++ b/sc/source/ui/miscdlgs/linkarea.src
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "linkarea.hrc"
+
+ModalDialog RID_SCDLG_LINKAREA
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Size = MAP_APPFONT ( 274 , 190 ) ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 218 , 8 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 218 , 25 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 218 , 49 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ FixedLine FL_LOCATION
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 204 , 8 ) ;
+ Text [ en-US ] = "URL of ~external data source";
+ };
+ ComboBox CB_URL
+ {
+ Pos = MAP_APPFONT ( 12 , 15 ) ;
+ Size = MAP_APPFONT ( 174 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ PushButton BTN_BROWSE
+ {
+ Pos = MAP_APPFONT ( 190 , 14 ) ;
+ Size = MAP_APPFONT ( 14 , 14 ) ;
+ Text = "~..." ;
+ };
+ FixedText FT_HINT
+ {
+ Pos = MAP_APPFONT ( 12 , 31 ) ;
+ Size = MAP_APPFONT ( 192 , 26 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "(Enter the URL of the source document in the local file system or Internet here.)";
+ };
+ FixedText FT_RANGES
+ {
+ Pos = MAP_APPFONT ( 6 , 62 ) ;
+ Size = MAP_APPFONT ( 198 , 8 ) ;
+ Text [ en-US ] = "~Available tables/ranges";
+ };
+ MultiListBox LB_RANGES
+ {
+ SimpleMode = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 74 ) ;
+ Size = MAP_APPFONT ( 192 , 80 ) ;
+ AutoHScroll = TRUE ;
+ };
+ CheckBox BTN_RELOAD
+ {
+ Pos = MAP_APPFONT ( 12 , 168 ) ;
+ Size = MAP_APPFONT ( 100 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Update every";
+ };
+ NumericField NF_DELAY
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 113 , 166 ) ;
+ Size = MAP_APPFONT ( 32 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ Maximum = 99999 ;
+ Value = 60 ;
+ };
+ FixedText FT_SECONDS
+ {
+ Pos = MAP_APPFONT ( 149 , 168 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Text [ en-US ] = "seconds";
+ };
+ Text [ en-US ] = "External Data";
+};
+
diff --git a/sc/source/ui/miscdlgs/makefile.mk b/sc/source/ui/miscdlgs/makefile.mk
new file mode 100644
index 000000000000..d34994341ade
--- /dev/null
+++ b/sc/source/ui/miscdlgs/makefile.mk
@@ -0,0 +1,127 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=miscdlgs
+LIBTARGET=no
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/delcldlg.obj \
+ $(SLO)$/inscldlg.obj \
+ $(SLO)$/delcodlg.obj \
+ $(SLO)$/inscodlg.obj \
+ $(SLO)$/strindlg.obj \
+ $(SLO)$/tabbgcolordlg.obj \
+ $(SLO)$/mtrindlg.obj \
+ $(SLO)$/lbseldlg.obj \
+ $(SLO)$/filldlg.obj \
+ $(SLO)$/autofmt.obj \
+ $(SLO)$/solvrdlg.obj \
+ $(SLO)$/optsolver.obj \
+ $(SLO)$/solveroptions.obj \
+ $(SLO)$/solverutil.obj \
+ $(SLO)$/mvtabdlg.obj \
+ $(SLO)$/groupdlg.obj \
+ $(SLO)$/tabopdlg.obj \
+ $(SLO)$/crdlg.obj \
+ $(SLO)$/namecrea.obj \
+ $(SLO)$/namepast.obj \
+ $(SLO)$/textdlgs.obj \
+ $(SLO)$/anyrefdg.obj \
+ $(SLO)$/crnrdlg.obj \
+ $(SLO)$/shtabdlg.obj \
+ $(SLO)$/instbdlg.obj \
+ $(SLO)$/acredlin.obj \
+ $(SLO)$/highred.obj \
+ $(SLO)$/simpref.obj \
+ $(SLO)$/redcom.obj \
+ $(SLO)$/linkarea.obj \
+ $(SLO)$/warnbox.obj \
+ $(SLO)$/scuiautofmt.obj \
+ $(SLO)$/conflictsdlg.obj \
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
+
+EXCEPTIONSFILES = \
+ $(SLO)$/acredlin.obj \
+ $(SLO)$/conflictsdlg.obj \
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/optsolver.obj \
+ $(SLO)$/solveroptions.obj \
+ $(SLO)$/crnrdlg.obj \
+ $(SLO)$/solverutil.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ instbdlg.src \
+ acredlin.src \
+ highred.src \
+ linkarea.src \
+ conflictsdlg.src \
+ sharedocdlg.src \
+ protectiondlg.src \
+ retypepassdlg.src
+
+LIB1TARGET = $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO)$/autofmt.obj \
+ $(SLO)$/solvrdlg.obj \
+ $(SLO)$/optsolver.obj \
+ $(SLO)$/solveroptions.obj \
+ $(SLO)$/solverutil.obj \
+ $(SLO)$/tabopdlg.obj \
+ $(SLO)$/anyrefdg.obj \
+ $(SLO)$/crnrdlg.obj \
+ $(SLO)$/acredlin.obj \
+ $(SLO)$/highred.obj \
+ $(SLO)$/simpref.obj \
+ $(SLO)$/redcom.obj \
+ $(SLO)$/warnbox.obj \
+ $(SLO)$/conflictsdlg.obj \
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/miscdlgs/mtrindlg.cxx b/sc/source/ui/miscdlgs/mtrindlg.cxx
new file mode 100644
index 000000000000..02bc77f8f89e
--- /dev/null
+++ b/sc/source/ui/miscdlgs/mtrindlg.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "mtrindlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+ScMetricInputDlg::ScMetricInputDlg( Window* pParent,
+ USHORT nResId,
+ long nCurrent,
+ long nDefault,
+ FieldUnit eFUnit,
+ USHORT nDecimals,
+ long nMaximum,
+ long nMinimum,
+ long nFirst,
+ long nLast )
+
+ : ModalDialog ( pParent, ScResId( nResId ) ),
+ //
+ aFtEditTitle ( this, ScResId( FT_LABEL ) ),
+ aEdValue ( this, ScResId( ED_VALUE ) ),
+ aBtnDefVal ( this, ScResId( BTN_DEFVAL ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ //SetText( rTitle );
+ //
+ //aFtEditTitle.SetText( rEditTitle );
+ CalcPositions();
+ aBtnDefVal.SetClickHdl ( LINK( this, ScMetricInputDlg, SetDefValHdl ) );
+ aEdValue. SetModifyHdl( LINK( this, ScMetricInputDlg, ModifyHdl ) );
+
+ aEdValue.SetUnit ( eFUnit );
+ aEdValue.SetDecimalDigits ( nDecimals );
+ aEdValue.SetMax ( aEdValue.Normalize( nMaximum ), FUNIT_TWIP );
+ aEdValue.SetMin ( aEdValue.Normalize( nMinimum ), FUNIT_TWIP );
+ aEdValue.SetLast ( aEdValue.Normalize( nLast ), FUNIT_TWIP );
+ aEdValue.SetFirst ( aEdValue.Normalize( nFirst ), FUNIT_TWIP );
+ aEdValue.SetSpinSize ( aEdValue.Normalize( 1 ) / 10 );
+ aEdValue.SetValue ( aEdValue.Normalize( nDefault ), FUNIT_TWIP );
+ nDefaultValue = sal::static_int_cast<long>( aEdValue.GetValue() );
+ aEdValue.SetValue ( aEdValue.Normalize( nCurrent ), FUNIT_TWIP );
+ nCurrentValue = sal::static_int_cast<long>( aEdValue.GetValue() );
+ aBtnDefVal.Check( nCurrentValue == nDefaultValue );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScMetricInputDlg::~ScMetricInputDlg()
+{
+}
+
+//------------------------------------------------------------------------
+
+long ScMetricInputDlg::GetInputValue( FieldUnit eUnit ) const
+{
+/*
+ mit Nachkommastellen:
+
+ double nVal = aEdValue.GetValue( eUnit );
+ USHORT nDecs = aEdValue.GetDecimalDigits();
+ double nFactor = 0.0;
+
+ // static long ImpPower10( USHORT nDecs )
+ {
+ nFactor = 1.0;
+
+ for ( USHORT i=0; i < nDecs; i++ )
+ nFactor *= 10.0;
+ }
+
+ return nVal / nFactor;
+*/
+ // erstmal Nachkommastellen abschneiden - nich so doll...
+
+ return sal::static_int_cast<long>( aEdValue.Denormalize( aEdValue.GetValue( eUnit ) ) );
+}
+
+//------------------------------------------------------------------------
+
+void ScMetricInputDlg::CalcPositions()
+{
+ MapMode oldMode = GetMapMode();
+ SetMapMode( MAP_APPFONT );
+
+ Size aDlgSize = GetOutputSizePixel();
+ Size aFtSize = aFtEditTitle.GetSizePixel();
+ Point aNewPos;
+
+ aFtSize.Width() = aFtEditTitle.GetTextWidth(aFtEditTitle.GetText());
+ // #95990# add mnemonic char width to fixed text width
+ aFtSize.Width() += aFtEditTitle.GetTextWidth(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("(W)")));
+ aFtEditTitle.SetSizePixel( aFtSize );
+
+ aNewPos.Y() = aEdValue.GetPosPixel().Y();
+ aNewPos.X() = aFtEditTitle.GetPosPixel().X();
+ aNewPos.X() += aFtEditTitle.GetSizePixel().Width();
+ aNewPos.X() += LogicToPixel( Point(3,0) ).X();
+ aEdValue.SetPosPixel( aNewPos );
+
+ aNewPos.Y() = aBtnDefVal.GetPosPixel().Y();
+ aBtnDefVal.SetPosPixel( aNewPos );
+
+ aNewPos.Y() = aBtnOk.GetPosPixel().Y();
+ aNewPos.X() += aEdValue.GetSizePixel().Width();
+ aNewPos.X() += LogicToPixel( Point(6,0) ).X();
+ aBtnOk.SetPosPixel( aNewPos );
+ aNewPos.Y() = aBtnCancel.GetPosPixel().Y();
+ aBtnCancel.SetPosPixel( aNewPos );
+ aNewPos.Y() = aBtnHelp.GetPosPixel().Y();
+ aBtnHelp.SetPosPixel( aNewPos );
+
+ aNewPos.X() += aBtnOk.GetSizePixel().Width();
+ aNewPos.X() += LogicToPixel( Point(6,0) ).X();
+ aDlgSize.Width() = aNewPos.X();
+ SetOutputSizePixel( aDlgSize );
+
+ SetMapMode( oldMode );
+}
+
+//------------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScMetricInputDlg, SetDefValHdl, CheckBox *, EMPTYARG )
+{
+ if ( aBtnDefVal.IsChecked() )
+ {
+ nCurrentValue = sal::static_int_cast<long>( aEdValue.GetValue() );
+ aEdValue.SetValue( nDefaultValue );
+ }
+ else
+ aEdValue.SetValue( nCurrentValue );
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScMetricInputDlg, ModifyHdl, MetricField *, EMPTYARG )
+{
+ aBtnDefVal.Check( nDefaultValue == aEdValue.GetValue() );
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScMetricInputDlg, ModifyHdl, MetricField *, EMPTYARG )
+
+
+
diff --git a/sc/source/ui/miscdlgs/mvtabdlg.cxx b/sc/source/ui/miscdlgs/mvtabdlg.cxx
new file mode 100644
index 000000000000..296cf8a8637f
--- /dev/null
+++ b/sc/source/ui/miscdlgs/mvtabdlg.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <vcl/msgbox.hxx>
+
+#include "mvtabdlg.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "miscdlgs.hrc"
+#include "global.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+
+#include <layout/layout-pre.hxx>
+
+#if ENABLE_LAYOUT
+#undef ScResId
+#define ScResId(x) #x
+#undef ModalDialog
+#define ModalDialog( parent, id ) Dialog( parent, "move-copy-sheet.xml", id )
+#endif /* ENABLE_LAYOUT */
+
+//==================================================================
+
+ScMoveTableDlg::ScMoveTableDlg( Window* pParent )
+
+ : ModalDialog ( pParent, ScResId( RID_SCDLG_MOVETAB ) ),
+ //
+ aFtDoc ( this, ScResId( FT_DEST ) ),
+ aLbDoc ( this, ScResId( LB_DEST ) ),
+ aFtTable ( this, ScResId( FT_INSERT ) ),
+ aLbTable ( this, ScResId( LB_INSERT ) ),
+ aBtnCopy ( this, ScResId( BTN_COPY ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ //
+ nDocument ( 0 ),
+ nTable ( 0 ),
+ bCopyTable ( FALSE )
+{
+#if ENABLE_LAYOUT
+#undef ScResId
+ SetHelpId (FID_TAB_MOVE);
+#endif /* ENABLE_LAYOUT */
+ Init();
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScMoveTableDlg::~ScMoveTableDlg()
+{
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScMoveTableDlg::GetSelectedDocument () const { return nDocument; }
+
+SCTAB ScMoveTableDlg::GetSelectedTable () const { return nTable; }
+
+BOOL ScMoveTableDlg::GetCopyTable () const { return bCopyTable; }
+
+void ScMoveTableDlg::SetCopyTable(BOOL bFlag)
+{
+ aBtnCopy.Check(bFlag);
+}
+void ScMoveTableDlg::EnableCopyTable(BOOL bFlag)
+{
+ if(bFlag)
+ aBtnCopy.Enable();
+ else
+ aBtnCopy.Disable();
+}
+
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScMoveTableDlg::Init()
+{
+ aBtnOk.SetClickHdl ( LINK( this, ScMoveTableDlg, OkHdl ) );
+ aLbDoc.SetSelectHdl ( LINK( this, ScMoveTableDlg, SelHdl ) );
+ aBtnCopy.Check( FALSE );
+ InitDocListBox();
+ SelHdl( &aLbDoc );
+}
+
+//------------------------------------------------------------------------
+
+void ScMoveTableDlg::InitDocListBox()
+{
+ SfxObjectShell* pSh = SfxObjectShell::GetFirst();
+ ScDocShell* pScSh = NULL;
+ USHORT nSelPos = 0;
+ USHORT i = 0;
+
+ aLbDoc.Clear();
+ aLbDoc.SetUpdateMode( FALSE );
+
+ while ( pSh )
+ {
+ pScSh = PTR_CAST( ScDocShell, pSh );
+
+ if ( pScSh )
+ {
+ if ( pScSh == SfxObjectShell::Current() )
+ nSelPos = i;
+
+ aLbDoc.InsertEntry( pScSh->GetTitle(), i );
+ aLbDoc.SetEntryData( i, (void*)pScSh->GetDocument() );
+
+ i++;
+ }
+ pSh = SfxObjectShell::GetNext( *pSh );
+ }
+
+ aLbDoc.SetUpdateMode( TRUE );
+ aLbDoc.InsertEntry( String( ScResId( STR_NEWDOC ) ) );
+ aLbDoc.SelectEntryPos( nSelPos );
+}
+
+
+//------------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScMoveTableDlg, OkHdl, void *, EMPTYARG )
+{
+ USHORT nDocSel = aLbDoc.GetSelectEntryPos();
+ USHORT nDocLast = aLbDoc.GetEntryCount()-1;
+ USHORT nTabSel = aLbTable.GetSelectEntryPos();
+ USHORT nTabLast = aLbTable.GetEntryCount()-1;
+
+ nDocument = (nDocSel != nDocLast) ? nDocSel : SC_DOC_NEW;
+ nTable = (nTabSel != nTabLast) ? static_cast<SCTAB>(nTabSel) : SC_TAB_APPEND;
+ bCopyTable = aBtnCopy.IsChecked();
+ EndDialog( RET_OK );
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScMoveTableDlg, SelHdl, ListBox *, pLb )
+{
+ if ( pLb == &aLbDoc )
+ {
+ ScDocument* pDoc = (ScDocument*)
+ aLbDoc.GetEntryData( aLbDoc.GetSelectEntryPos() );
+ SCTAB nLast = 0;
+ String aName;
+
+ aLbTable.Clear();
+ aLbTable.SetUpdateMode( FALSE );
+ if ( pDoc )
+ {
+ nLast = pDoc->GetTableCount()-1;
+ for ( SCTAB i=0; i<=nLast; i++ )
+ {
+ pDoc->GetName( i, aName );
+ aLbTable.InsertEntry( aName, static_cast<sal_uInt16>(i) );
+ }
+ }
+ aLbTable.InsertEntry( ScGlobal::GetRscString(STR_MOVE_TO_END) );
+ aLbTable.SetUpdateMode( TRUE );
+ aLbTable.SelectEntryPos( 0 );
+ }
+
+ return 0;
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/namecrea.cxx b/sc/source/ui/miscdlgs/namecrea.cxx
new file mode 100644
index 000000000000..1714fddd3b3d
--- /dev/null
+++ b/sc/source/ui/miscdlgs/namecrea.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "namecrea.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+ScNameCreateDlg::ScNameCreateDlg( Window * pParent, USHORT nFlags )
+ : ModalDialog( pParent, ScResId(RID_SCDLG_NAMES_CREATE) ),
+ aFixedLine ( this, ScResId( FL_FRAME ) ),
+ aTopBox ( this, ScResId( BTN_TOP ) ),
+ aLeftBox ( this, ScResId( BTN_LEFT ) ),
+ aBottomBox ( this, ScResId( BTN_BOTTOM ) ),
+ aRightBox ( this, ScResId( BTN_RIGHT ) ),
+ aOKButton ( this, ScResId( BTN_OK ) ),
+ aCancelButton ( this, ScResId( BTN_CANCEL ) ),
+ aHelpButton ( this, ScResId( BTN_HELP ) )
+{
+ aTopBox.Check ( (nFlags & NAME_TOP) ? TRUE : FALSE );
+ aLeftBox.Check ( (nFlags & NAME_LEFT) ? TRUE : FALSE );
+ aBottomBox.Check( (nFlags & NAME_BOTTOM)? TRUE : FALSE );
+ aRightBox.Check ( (nFlags & NAME_RIGHT) ? TRUE : FALSE );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------
+
+USHORT ScNameCreateDlg::GetFlags() const
+{
+ USHORT nResult = 0;
+
+ nResult |= aTopBox.IsChecked() ? NAME_TOP: 0 ;
+ nResult |= aLeftBox.IsChecked() ? NAME_LEFT: 0 ;
+ nResult |= aBottomBox.IsChecked() ? NAME_BOTTOM: 0 ;
+ nResult |= aRightBox.IsChecked() ? NAME_RIGHT: 0 ;
+
+ return nResult;
+}
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/namepast.cxx b/sc/source/ui/miscdlgs/namepast.cxx
new file mode 100644
index 000000000000..c621f14b431c
--- /dev/null
+++ b/sc/source/ui/miscdlgs/namepast.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "namepast.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+#include "rangenam.hxx"
+
+
+//==================================================================
+
+ScNamePasteDlg::ScNamePasteDlg( Window * pParent, const ScRangeName* pList, BOOL bInsList )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_NAMES_PASTE ) ),
+ aLabelText ( this, ScResId( FT_LABEL ) ),
+ aNameList ( this, ScResId( LB_ENTRYLIST ) ),
+ aOKButton ( this, ScResId( BTN_OK ) ),
+ aCancelButton ( this, ScResId( BTN_CANCEL ) ),
+ aHelpButton ( this, ScResId( BTN_HELP ) ),
+ aInsListButton ( this, ScResId( BTN_ADD ) )
+{
+ if( ! bInsList )
+ aInsListButton.Disable();
+
+ aInsListButton.SetClickHdl( LINK( this,ScNamePasteDlg,ButtonHdl) );
+ aOKButton.SetClickHdl( LINK( this,ScNamePasteDlg,ButtonHdl) );
+ aNameList.SetSelectHdl( LINK( this,ScNamePasteDlg,ListSelHdl) );
+ aNameList.SetDoubleClickHdl( LINK( this,ScNamePasteDlg,ListDblClickHdl) );
+
+ USHORT nCnt = pList->GetCount();
+ String aText;
+
+ for( USHORT i=0 ; i<nCnt ; i++ )
+ {
+ ScRangeData* pData = (*pList)[ i ];
+
+ if( pData )
+ {
+ if ( !pData->HasType( RT_DATABASE )
+ && !pData->HasType( RT_SHARED ) )
+ {
+ pData->GetName( aText );
+ aNameList.InsertEntry( aText );
+ }
+ }
+ }
+
+ ListSelHdl( &aNameList );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScNamePasteDlg, ButtonHdl, Button *, pButton )
+{
+ if( pButton == &aInsListButton )
+ {
+ EndDialog( BTN_PASTE_LIST );
+ }
+ else if( pButton == &aOKButton )
+ {
+ EndDialog( BTN_PASTE_NAME );
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScNamePasteDlg, ListSelHdl, ListBox *, pListBox )
+{
+ if( pListBox == &aNameList )
+ {
+ if( aNameList.GetSelectEntryCount() )
+ aOKButton.Enable();
+ else
+ aOKButton.Disable();
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScNamePasteDlg, ListDblClickHdl, ListBox *, pListBox )
+{
+ if( pListBox == &aNameList )
+ {
+ ButtonHdl( &aOKButton );
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScNamePasteDlg, ListDblClickHdl, ListBox *, pListBox )
+
+//------------------------------------------------------------------
+
+String ScNamePasteDlg::GetSelectedName() const
+{
+ return aNameList.GetSelectEntry();
+}
+
+
diff --git a/sc/source/ui/miscdlgs/optsolver.cxx b/sc/source/ui/miscdlgs/optsolver.cxx
new file mode 100644
index 000000000000..37759aef81b5
--- /dev/null
+++ b/sc/source/ui/miscdlgs/optsolver.cxx
@@ -0,0 +1,1066 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "rangelst.hxx"
+#include "scitems.hxx"
+#include <sfx2/bindings.hxx>
+#include <sfx2/imagemgr.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "uiitems.hxx"
+#include "reffact.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "cell.hxx"
+#include "rangeutl.hxx"
+#include "scresid.hxx"
+#include "convuno.hxx"
+#include "unonames.hxx"
+#include "solveroptions.hxx"
+#include "solverutil.hxx"
+#include "optsolver.hrc"
+
+#include "optsolver.hxx"
+
+#include <com/sun/star/sheet/Solver.hpp>
+#include <com/sun/star/sheet/XSolverDescription.hpp>
+
+using namespace com::sun::star;
+
+//----------------------------------------------------------------------------
+
+ScSolverProgressDialog::ScSolverProgressDialog( Window* pParent )
+ : ModelessDialog( pParent, ScResId( RID_SCDLG_SOLVER_PROGRESS ) ),
+ maFtProgress ( this, ScResId( FT_PROGRESS ) ),
+ maFtTime ( this, ScResId( FT_TIMELIMIT ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) )
+{
+ maBtnOk.Enable(FALSE);
+ FreeResource();
+}
+
+ScSolverProgressDialog::~ScSolverProgressDialog()
+{
+}
+
+void ScSolverProgressDialog::HideTimeLimit()
+{
+ maFtTime.Hide();
+}
+
+void ScSolverProgressDialog::SetTimeLimit( sal_Int32 nSeconds )
+{
+ String aOld = maFtTime.GetText();
+ String aNew = aOld.GetToken(0,'#');
+ aNew += String::CreateFromInt32( nSeconds );
+ aNew += aOld.GetToken(1,'#');
+ maFtTime.SetText( aNew );
+}
+
+//----------------------------------------------------------------------------
+
+ScSolverNoSolutionDialog::ScSolverNoSolutionDialog( Window* pParent, const String& rErrorText )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_NOSOLUTION ) ),
+ maFtNoSolution ( this, ScResId( FT_NOSOLUTION ) ),
+ maFtErrorText ( this, ScResId( FT_ERRORTEXT ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) )
+{
+ maFtErrorText.SetText( rErrorText );
+ FreeResource();
+}
+
+ScSolverNoSolutionDialog::~ScSolverNoSolutionDialog()
+{
+}
+
+//----------------------------------------------------------------------------
+
+ScSolverSuccessDialog::ScSolverSuccessDialog( Window* pParent, const String& rSolution )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_SUCCESS ) ),
+ maFtSuccess ( this, ScResId( FT_SUCCESS ) ),
+ maFtResult ( this, ScResId( FT_RESULT ) ),
+ maFtQuestion ( this, ScResId( FT_QUESTION ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) )
+{
+ String aMessage = maFtResult.GetText();
+ aMessage.Append( (sal_Char) ' ' );
+ aMessage.Append( rSolution );
+ maFtResult.SetText( aMessage );
+ FreeResource();
+}
+
+ScSolverSuccessDialog::~ScSolverSuccessDialog()
+{
+}
+
+//----------------------------------------------------------------------------
+
+ScCursorRefEdit::ScCursorRefEdit( ScAnyRefDlg* pParent, const ResId& rResId ) :
+ formula::RefEdit( pParent, pParent, rResId )
+{
+}
+
+void ScCursorRefEdit::SetCursorLinks( const Link& rUp, const Link& rDown )
+{
+ maCursorUpLink = rUp;
+ maCursorDownLink = rDown;
+}
+
+void ScCursorRefEdit::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aCode = rKEvt.GetKeyCode();
+ bool bUp = (aCode.GetCode() == KEY_UP);
+ bool bDown = (aCode.GetCode() == KEY_DOWN);
+ if ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() && ( bUp || bDown ) )
+ {
+ if ( bUp )
+ maCursorUpLink.Call( this );
+ else
+ maCursorDownLink.Call( this );
+ }
+ else
+ formula::RefEdit::KeyInput( rKEvt );
+}
+
+//----------------------------------------------------------------------------
+
+ScOptSolverSave::ScOptSolverSave( const String& rObjective, BOOL bMax, BOOL bMin, BOOL bValue,
+ const String& rTarget, const String& rVariable,
+ const std::vector<ScOptConditionRow>& rConditions,
+ const String& rEngine,
+ const uno::Sequence<beans::PropertyValue>& rProperties ) :
+ maObjective( rObjective ),
+ mbMax( bMax ),
+ mbMin( bMin ),
+ mbValue( bValue ),
+ maTarget( rTarget ),
+ maVariable( rVariable ),
+ maConditions( rConditions ),
+ maEngine( rEngine ),
+ maProperties( rProperties )
+{
+}
+
+//============================================================================
+// class ScOptSolverDlg
+//----------------------------------------------------------------------------
+
+ScOptSolverDlg::ScOptSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocShell* pDocSh, ScAddress aCursorPos )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_OPTSOLVER ),
+ //
+ maFtObjectiveCell ( this, ScResId( FT_OBJECTIVECELL ) ),
+ maEdObjectiveCell ( this, this, ScResId( ED_OBJECTIVECELL ) ),
+ maRBObjectiveCell ( this, ScResId( IB_OBJECTIVECELL ), &maEdObjectiveCell, this ),
+ maFtDirection ( this, ScResId( FT_DIRECTION ) ),
+ maRbMax ( this, ScResId( RB_MAX ) ),
+ maRbMin ( this, ScResId( RB_MIN ) ),
+ maRbValue ( this, ScResId( RB_VALUE ) ),
+ maEdTargetValue ( this, this, ScResId( ED_TARGET ) ),
+ maRBTargetValue ( this, ScResId( IB_TARGET ), &maEdTargetValue, this ),
+ maFtVariableCells ( this, ScResId( FT_VARIABLECELLS ) ),
+ maEdVariableCells ( this, this, ScResId( ED_VARIABLECELLS ) ),
+ maRBVariableCells ( this, ScResId( IB_VARIABLECELLS ), &maEdVariableCells, this),
+ maFlConditions ( this, ScResId( FL_CONDITIONS ) ),
+ maFtCellRef ( this, ScResId( FT_CELLREF ) ),
+ maEdLeft1 ( this, ScResId( ED_LEFT1 ) ),
+ maRBLeft1 ( this, ScResId( IB_LEFT1 ), &maEdLeft1, this ),
+ maFtOperator ( this, ScResId( FT_OPERATOR ) ),
+ maLbOp1 ( this, ScResId( LB_OP1 ) ),
+ maFtConstraint ( this, ScResId( FT_CONSTRAINT ) ),
+ maEdRight1 ( this, ScResId( ED_RIGHT1 ) ),
+ maRBRight1 ( this, ScResId( IB_RIGHT1 ), &maEdRight1, this ),
+ maBtnDel1 ( this, ScResId( IB_DELETE1 ) ),
+ maEdLeft2 ( this, ScResId( ED_LEFT2 ) ),
+ maRBLeft2 ( this, ScResId( IB_LEFT2 ), &maEdLeft2, this ),
+ maLbOp2 ( this, ScResId( LB_OP2 ) ),
+ maEdRight2 ( this, ScResId( ED_RIGHT2 ) ),
+ maRBRight2 ( this, ScResId( IB_RIGHT2 ), &maEdRight2, this ),
+ maBtnDel2 ( this, ScResId( IB_DELETE2 ) ),
+ maEdLeft3 ( this, ScResId( ED_LEFT3 ) ),
+ maRBLeft3 ( this, ScResId( IB_LEFT3 ), &maEdLeft3, this ),
+ maLbOp3 ( this, ScResId( LB_OP3 ) ),
+ maEdRight3 ( this, ScResId( ED_RIGHT3 ) ),
+ maRBRight3 ( this, ScResId( IB_RIGHT3 ), &maEdRight3, this ),
+ maBtnDel3 ( this, ScResId( IB_DELETE3 ) ),
+ maEdLeft4 ( this, ScResId( ED_LEFT4 ) ),
+ maRBLeft4 ( this, ScResId( IB_LEFT4 ), &maEdLeft4, this ),
+ maLbOp4 ( this, ScResId( LB_OP4 ) ),
+ maEdRight4 ( this, ScResId( ED_RIGHT4 ) ),
+ maRBRight4 ( this, ScResId( IB_RIGHT4 ), &maEdRight4, this ),
+ maBtnDel4 ( this, ScResId( IB_DELETE4 ) ),
+ maScrollBar ( this, ScResId( SB_SCROLL ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnOpt ( this, ScResId( BTN_OPTIONS ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maBtnCancel ( this, ScResId( BTN_CLOSE ) ),
+ maBtnSolve ( this, ScResId( BTN_SOLVE ) ),
+ maInputError ( ScResId( STR_INVALIDINPUT ) ),
+ maConditionError ( ScResId( STR_INVALIDCONDITION ) ),
+ //
+ mpDocShell ( pDocSh ),
+ mpDoc ( pDocSh->GetDocument() ),
+ mnCurTab ( aCursorPos.Tab() ),
+ mpEdActive ( NULL ),
+ mbDlgLostFocus ( false ),
+ nScrollPos ( 0 )
+{
+ mpLeftEdit[0] = &maEdLeft1;
+ mpLeftButton[0] = &maRBLeft1;
+ mpRightEdit[0] = &maEdRight1;
+ mpRightButton[0] = &maRBRight1;
+ mpOperator[0] = &maLbOp1;
+ mpDelButton[0] = &maBtnDel1;
+
+ mpLeftEdit[1] = &maEdLeft2;
+ mpLeftButton[1] = &maRBLeft2;
+ mpRightEdit[1] = &maEdRight2;
+ mpRightButton[1] = &maRBRight2;
+ mpOperator[1] = &maLbOp2;
+ mpDelButton[1] = &maBtnDel2;
+
+ mpLeftEdit[2] = &maEdLeft3;
+ mpLeftButton[2] = &maRBLeft3;
+ mpRightEdit[2] = &maEdRight3;
+ mpRightButton[2] = &maRBRight3;
+ mpOperator[2] = &maLbOp3;
+ mpDelButton[2] = &maBtnDel3;
+
+ mpLeftEdit[3] = &maEdLeft4;
+ mpLeftButton[3] = &maRBLeft4;
+ mpRightEdit[3] = &maEdRight4;
+ mpRightButton[3] = &maRBRight4;
+ mpOperator[3] = &maLbOp4;
+ mpDelButton[3] = &maBtnDel4;
+
+ Init( aCursorPos );
+ FreeResource();
+}
+
+//----------------------------------------------------------------------------
+
+ScOptSolverDlg::~ScOptSolverDlg()
+{
+}
+
+//----------------------------------------------------------------------------
+
+void ScOptSolverDlg::Init(const ScAddress& rCursorPos)
+{
+ // Get the "Delete Rows" commandimagelist images from sfx instead of
+ // adding a second copy to sc (see ScTbxInsertCtrl::StateChanged)
+
+ rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aSlotURL += rtl::OUString::valueOf( sal_Int32( SID_DEL_ROWS ) );
+ uno::Reference<frame::XFrame> xFrame = GetBindings().GetActiveFrame();
+ Image aDelNm = ::GetImage( xFrame, aSlotURL, FALSE, FALSE );
+ Image aDelHC = ::GetImage( xFrame, aSlotURL, FALSE, TRUE ); // high contrast
+
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ mpDelButton[nRow]->SetModeImage( aDelNm, BMP_COLOR_NORMAL );
+ mpDelButton[nRow]->SetModeImage( aDelHC, BMP_COLOR_HIGHCONTRAST );
+ }
+
+ maBtnOpt.SetClickHdl( LINK( this, ScOptSolverDlg, BtnHdl ) );
+ maBtnCancel.SetClickHdl( LINK( this, ScOptSolverDlg, BtnHdl ) );
+ maBtnSolve.SetClickHdl( LINK( this, ScOptSolverDlg, BtnHdl ) );
+
+ Link aLink = LINK( this, ScOptSolverDlg, GetFocusHdl );
+ maEdObjectiveCell.SetGetFocusHdl( aLink );
+ maRBObjectiveCell.SetGetFocusHdl( aLink );
+ maEdTargetValue.SetGetFocusHdl( aLink );
+ maRBTargetValue.SetGetFocusHdl( aLink );
+ maEdVariableCells.SetGetFocusHdl( aLink );
+ maRBVariableCells.SetGetFocusHdl( aLink );
+ maRbValue.SetGetFocusHdl( aLink );
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ mpLeftEdit[nRow]->SetGetFocusHdl( aLink );
+ mpLeftButton[nRow]->SetGetFocusHdl( aLink );
+ mpRightEdit[nRow]->SetGetFocusHdl( aLink );
+ mpRightButton[nRow]->SetGetFocusHdl( aLink );
+ mpOperator[nRow]->SetGetFocusHdl( aLink );
+ }
+
+ aLink = LINK( this, ScOptSolverDlg, LoseFocusHdl );
+ maEdObjectiveCell.SetLoseFocusHdl( aLink );
+ maRBObjectiveCell.SetLoseFocusHdl( aLink );
+ maEdTargetValue. SetLoseFocusHdl( aLink );
+ maRBTargetValue. SetLoseFocusHdl( aLink );
+ maEdVariableCells.SetLoseFocusHdl( aLink );
+ maRBVariableCells.SetLoseFocusHdl( aLink );
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ mpLeftEdit[nRow]->SetLoseFocusHdl( aLink );
+ mpLeftButton[nRow]->SetLoseFocusHdl( aLink );
+ mpRightEdit[nRow]->SetLoseFocusHdl( aLink );
+ mpRightButton[nRow]->SetLoseFocusHdl( aLink );
+ }
+
+ Link aCursorUp = LINK( this, ScOptSolverDlg, CursorUpHdl );
+ Link aCursorDown = LINK( this, ScOptSolverDlg, CursorDownHdl );
+ Link aCondModify = LINK( this, ScOptSolverDlg, CondModifyHdl );
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ mpLeftEdit[nRow]->SetCursorLinks( aCursorUp, aCursorDown );
+ mpRightEdit[nRow]->SetCursorLinks( aCursorUp, aCursorDown );
+ mpLeftEdit[nRow]->SetModifyHdl( aCondModify );
+ mpRightEdit[nRow]->SetModifyHdl( aCondModify );
+ mpDelButton[nRow]->SetClickHdl( LINK( this, ScOptSolverDlg, DelBtnHdl ) );
+ mpOperator[nRow]->SetSelectHdl( LINK( this, ScOptSolverDlg, SelectHdl ) );
+ }
+ maEdTargetValue.SetModifyHdl( LINK( this, ScOptSolverDlg, TargetModifyHdl ) );
+
+ maScrollBar.SetEndScrollHdl( LINK( this, ScOptSolverDlg, ScrollHdl ) );
+ maScrollBar.SetScrollHdl( LINK( this, ScOptSolverDlg, ScrollHdl ) );
+
+ maScrollBar.SetPageSize( EDIT_ROW_COUNT );
+ maScrollBar.SetVisibleSize( EDIT_ROW_COUNT );
+ maScrollBar.SetLineSize( 1 );
+ // Range is set in ShowConditions
+
+ // get available solver implementations
+ //! sort by descriptions?
+ ScSolverUtil::GetImplementations( maImplNames, maDescriptions );
+ sal_Int32 nImplCount = maImplNames.getLength();
+
+ const ScOptSolverSave* pOldData = mpDocShell->GetSolverSaveData();
+ if ( pOldData )
+ {
+ maEdObjectiveCell.SetRefString( pOldData->GetObjective() );
+ maRbMax.Check( pOldData->GetMax() );
+ maRbMin.Check( pOldData->GetMin() );
+ maRbValue.Check( pOldData->GetValue() );
+ maEdTargetValue.SetRefString( pOldData->GetTarget() );
+ maEdVariableCells.SetRefString( pOldData->GetVariable() );
+ maConditions = pOldData->GetConditions();
+ maEngine = pOldData->GetEngine();
+ maProperties = pOldData->GetProperties();
+ }
+ else
+ {
+ maRbMax.Check();
+ String aCursorStr;
+ if ( !mpDoc->GetRangeAtBlock( ScRange(rCursorPos), &aCursorStr ) )
+ rCursorPos.Format( aCursorStr, SCA_ABS, NULL, mpDoc->GetAddressConvention() );
+ maEdObjectiveCell.SetRefString( aCursorStr );
+ if ( nImplCount > 0 )
+ maEngine = maImplNames[0]; // use first implementation
+ }
+ ShowConditions();
+
+ maEdObjectiveCell.GrabFocus();
+ mpEdActive = &maEdObjectiveCell;
+}
+
+//----------------------------------------------------------------------------
+
+void ScOptSolverDlg::ReadConditions()
+{
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ ScOptConditionRow aRowEntry;
+ aRowEntry.aLeftStr = mpLeftEdit[nRow]->GetText();
+ aRowEntry.aRightStr = mpRightEdit[nRow]->GetText();
+ aRowEntry.nOperator = mpOperator[nRow]->GetSelectEntryPos();
+
+ long nVecPos = nScrollPos + nRow;
+ if ( nVecPos >= (long)maConditions.size() && !aRowEntry.IsDefault() )
+ maConditions.resize( nVecPos + 1 );
+
+ if ( nVecPos < (long)maConditions.size() )
+ maConditions[nVecPos] = aRowEntry;
+
+ // remove default entries at the end
+ size_t nSize = maConditions.size();
+ while ( nSize > 0 && maConditions[ nSize-1 ].IsDefault() )
+ --nSize;
+ maConditions.resize( nSize );
+ }
+}
+
+void ScOptSolverDlg::ShowConditions()
+{
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ ScOptConditionRow aRowEntry;
+
+ long nVecPos = nScrollPos + nRow;
+ if ( nVecPos < (long)maConditions.size() )
+ aRowEntry = maConditions[nVecPos];
+
+ mpLeftEdit[nRow]->SetRefString( aRowEntry.aLeftStr );
+ mpRightEdit[nRow]->SetRefString( aRowEntry.aRightStr );
+ mpOperator[nRow]->SelectEntryPos( aRowEntry.nOperator );
+ }
+
+ // allow to scroll one page behind the visible or stored rows
+ long nVisible = nScrollPos + EDIT_ROW_COUNT;
+ long nMax = std::max( nVisible, (long) maConditions.size() );
+ maScrollBar.SetRange( Range( 0, nMax + EDIT_ROW_COUNT ) );
+ maScrollBar.SetThumbPos( nScrollPos );
+
+ EnableButtons();
+}
+
+void ScOptSolverDlg::EnableButtons()
+{
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ long nVecPos = nScrollPos + nRow;
+ mpDelButton[nRow]->Enable( nVecPos < (long)maConditions.size() );
+ }
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScOptSolverDlg::Close()
+{
+ return DoClose( ScOptSolverDlgWrapper::GetChildWindowId() );
+}
+
+//----------------------------------------------------------------------------
+
+void ScOptSolverDlg::SetActive()
+{
+ if ( mbDlgLostFocus )
+ {
+ mbDlgLostFocus = false;
+ if( mpEdActive )
+ mpEdActive->GrabFocus();
+ }
+ else
+ {
+ GrabFocus();
+ }
+ RefInputDone();
+}
+
+//----------------------------------------------------------------------------
+
+void ScOptSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if( mpEdActive )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart(mpEdActive);
+
+ // "target"/"value": single cell
+ bool bSingle = ( mpEdActive == &maEdObjectiveCell || mpEdActive == &maEdTargetValue );
+
+ String aStr;
+ ScAddress aAdr = rRef.aStart;
+ ScRange aNewRef( rRef );
+ if ( bSingle )
+ aNewRef.aEnd = aAdr;
+
+ String aName;
+ if ( pDocP->GetRangeAtBlock( aNewRef, &aName ) ) // named range: show name
+ aStr = aName;
+ else // format cell/range reference
+ {
+ USHORT nFmt = ( aAdr.Tab() == mnCurTab ) ? SCA_ABS : SCA_ABS_3D;
+ if ( bSingle )
+ aAdr.Format( aStr, nFmt, pDocP, pDocP->GetAddressConvention() );
+ else
+ rRef.Format( aStr, nFmt | SCR_ABS, pDocP, pDocP->GetAddressConvention() );
+ }
+
+ // variable cells can be several ranges, so only the selection is replaced
+ if ( mpEdActive == &maEdVariableCells )
+ {
+ String aVal = mpEdActive->GetText();
+ Selection aSel = mpEdActive->GetSelection();
+ aSel.Justify();
+ aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ aVal.Insert( aStr, (xub_StrLen)aSel.Min() );
+ Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() );
+ mpEdActive->SetRefString( aVal );
+ mpEdActive->SetSelection( aNewSel );
+ }
+ else
+ mpEdActive->SetRefString( aStr );
+
+ ReadConditions();
+ EnableButtons();
+
+ // select "Value of" if a ref is input into "target" edit
+ if ( mpEdActive == &maEdTargetValue )
+ maRbValue.Check();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScOptSolverDlg::IsRefInputMode() const
+{
+ return mpEdActive != NULL;
+}
+
+//----------------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScOptSolverDlg, BtnHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &maBtnSolve || pBtn == &maBtnCancel )
+ {
+ bool bSolve = ( pBtn == &maBtnSolve );
+
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+
+ bool bClose = true;
+ if ( bSolve )
+ bClose = CallSolver();
+
+ if ( bClose )
+ {
+ // Close: write dialog settings to DocShell for subsequent calls
+ ReadConditions();
+ ScOptSolverSave aSave(
+ maEdObjectiveCell.GetText(), maRbMax.IsChecked(), maRbMin.IsChecked(), maRbValue.IsChecked(),
+ maEdTargetValue.GetText(), maEdVariableCells.GetText(), maConditions, maEngine, maProperties );
+ mpDocShell->SetSolverSaveData( aSave );
+ Close();
+ }
+ else
+ {
+ // no solution -> dialog is kept open
+ SetDispatcherLock( TRUE );
+ }
+ }
+ else if ( pBtn == &maBtnOpt )
+ {
+ //! move options dialog to UI lib?
+ ScSolverOptionsDialog* pOptDlg =
+ new ScSolverOptionsDialog( this, maImplNames, maDescriptions, maEngine, maProperties );
+ if ( pOptDlg->Execute() == RET_OK )
+ {
+ maEngine = pOptDlg->GetEngine();
+ maProperties = pOptDlg->GetProperties();
+ }
+ delete pOptDlg;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScOptSolverDlg, GetFocusHdl, Control*, pCtrl )
+{
+ Edit* pEdit = NULL;
+ mpEdActive = NULL;
+
+ if( pCtrl == &maEdObjectiveCell || pCtrl == &maRBObjectiveCell )
+ pEdit = mpEdActive = &maEdObjectiveCell;
+ else if( pCtrl == &maEdTargetValue || pCtrl == &maRBTargetValue )
+ pEdit = mpEdActive = &maEdTargetValue;
+ else if( pCtrl == &maEdVariableCells || pCtrl == &maRBVariableCells )
+ pEdit = mpEdActive = &maEdVariableCells;
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ {
+ if( pCtrl == mpLeftEdit[nRow] || pCtrl == mpLeftButton[nRow] )
+ pEdit = mpEdActive = mpLeftEdit[nRow];
+ else if( pCtrl == mpRightEdit[nRow] || pCtrl == mpRightButton[nRow] )
+ pEdit = mpEdActive = mpRightEdit[nRow];
+ else if( pCtrl == mpOperator[nRow] ) // focus on "operator" list box
+ mpEdActive = mpRightEdit[nRow]; // use right edit for ref input, but don't change selection
+ }
+ if( pCtrl == &maRbValue ) // focus on "Value of" radio button
+ mpEdActive = &maEdTargetValue; // use value edit for ref input, but don't change selection
+
+ if( pEdit )
+ pEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScOptSolverDlg, LoseFocusHdl, Control*, EMPTYARG )
+{
+ mbDlgLostFocus = !IsActive();
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScOptSolverDlg, DelBtnHdl, PushButton*, pBtn )
+{
+ for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow )
+ if( pBtn == mpDelButton[nRow] )
+ {
+ BOOL bHadFocus = pBtn->HasFocus();
+
+ ReadConditions();
+ long nVecPos = nScrollPos + nRow;
+ if ( nVecPos < (long)maConditions.size() )
+ {
+ maConditions.erase( maConditions.begin() + nVecPos );
+ ShowConditions();
+
+ if ( bHadFocus && !pBtn->IsEnabled() )
+ {
+ // If the button is disabled, focus would normally move to the next control,
+ // (left edit of the next row). Move it to left edit of this row instead.
+
+ mpEdActive = mpLeftEdit[nRow];
+ mpEdActive->GrabFocus();
+ }
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScOptSolverDlg, TargetModifyHdl, Edit*, EMPTYARG )
+{
+ // modify handler for the target edit:
+ // select "Value of" if something is input into the edit
+ if ( maEdTargetValue.GetText().Len() )
+ maRbValue.Check();
+ return 0;
+}
+
+IMPL_LINK( ScOptSolverDlg, CondModifyHdl, Edit*, EMPTYARG )
+{
+ // modify handler for the condition edits, just to enable/disable "delete" buttons
+ ReadConditions();
+ EnableButtons();
+ return 0;
+}
+
+IMPL_LINK( ScOptSolverDlg, SelectHdl, ListBox*, EMPTYARG )
+{
+ // select handler for operator list boxes, just to enable/disable "delete" buttons
+ ReadConditions();
+ EnableButtons();
+ return 0;
+}
+
+IMPL_LINK( ScOptSolverDlg, ScrollHdl, ScrollBar*, EMPTYARG )
+{
+ ReadConditions();
+ nScrollPos = maScrollBar.GetThumbPos();
+ ShowConditions();
+ if( mpEdActive )
+ mpEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
+ return 0;
+}
+
+IMPL_LINK( ScOptSolverDlg, CursorUpHdl, ScCursorRefEdit*, pEdit )
+{
+ if ( pEdit == mpLeftEdit[0] || pEdit == mpRightEdit[0] )
+ {
+ if ( nScrollPos > 0 )
+ {
+ ReadConditions();
+ --nScrollPos;
+ ShowConditions();
+ if( mpEdActive )
+ mpEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
+ }
+ }
+ else
+ {
+ formula::RefEdit* pFocus = NULL;
+ for ( sal_uInt16 nRow = 1; nRow < EDIT_ROW_COUNT; ++nRow ) // second row or below: move focus
+ {
+ if ( pEdit == mpLeftEdit[nRow] )
+ pFocus = mpLeftEdit[nRow-1];
+ else if ( pEdit == mpRightEdit[nRow] )
+ pFocus = mpRightEdit[nRow-1];
+ }
+ if (pFocus)
+ {
+ mpEdActive = pFocus;
+ pFocus->GrabFocus();
+ }
+ }
+
+ return 0;
+}
+
+IMPL_LINK( ScOptSolverDlg, CursorDownHdl, ScCursorRefEdit*, pEdit )
+{
+ if ( pEdit == mpLeftEdit[EDIT_ROW_COUNT-1] || pEdit == mpRightEdit[EDIT_ROW_COUNT-1] )
+ {
+ //! limit scroll position?
+ ReadConditions();
+ ++nScrollPos;
+ ShowConditions();
+ if( mpEdActive )
+ mpEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
+ }
+ else
+ {
+ formula::RefEdit* pFocus = NULL;
+ for ( sal_uInt16 nRow = 0; nRow+1 < EDIT_ROW_COUNT; ++nRow ) // before last row: move focus
+ {
+ if ( pEdit == mpLeftEdit[nRow] )
+ pFocus = mpLeftEdit[nRow+1];
+ else if ( pEdit == mpRightEdit[nRow] )
+ pFocus = mpRightEdit[nRow+1];
+ }
+ if (pFocus)
+ {
+ mpEdActive = pFocus;
+ pFocus->GrabFocus();
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+void ScOptSolverDlg::ShowError( bool bCondition, formula::RefEdit* pFocus )
+{
+ String aMessage = bCondition ? maConditionError : maInputError;
+ ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ), aMessage ).Execute();
+ if (pFocus)
+ {
+ mpEdActive = pFocus;
+ pFocus->GrabFocus();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+bool ScOptSolverDlg::ParseRef( ScRange& rRange, const String& rInput, bool bAllowRange )
+{
+ ScRangeUtil aRangeUtil;
+ ScAddress::Details aDetails(mpDoc->GetAddressConvention(), 0, 0);
+ USHORT nFlags = rRange.ParseAny( rInput, mpDoc, aDetails );
+ if ( nFlags & SCA_VALID )
+ {
+ if ( (nFlags & SCA_TAB_3D) == 0 )
+ rRange.aStart.SetTab( mnCurTab );
+ if ( (nFlags & SCA_TAB2_3D) == 0 )
+ rRange.aEnd.SetTab( rRange.aStart.Tab() );
+ return ( bAllowRange || rRange.aStart == rRange.aEnd );
+ }
+ else if ( aRangeUtil.MakeRangeFromName( rInput, mpDoc, mnCurTab, rRange, RUTL_NAMES, aDetails ) )
+ return ( bAllowRange || rRange.aStart == rRange.aEnd );
+
+ return false; // not recognized
+}
+
+bool ScOptSolverDlg::FindTimeout( sal_Int32& rTimeout )
+{
+ bool bFound = false;
+
+ if ( !maProperties.getLength() )
+ maProperties = ScSolverUtil::GetDefaults( maEngine ); // get property defaults from component
+
+ sal_Int32 nPropCount = maProperties.getLength();
+ for (sal_Int32 nProp=0; nProp<nPropCount && !bFound; ++nProp)
+ {
+ const beans::PropertyValue& rValue = maProperties[nProp];
+ if ( rValue.Name.equalsAscii( SC_UNONAME_TIMEOUT ) )
+ bFound = ( rValue.Value >>= rTimeout );
+ }
+ return bFound;
+}
+
+bool ScOptSolverDlg::CallSolver() // return true -> close dialog after calling
+{
+ // show progress dialog
+
+ ScSolverProgressDialog aProgress( this );
+ sal_Int32 nTimeout = 0;
+ if ( FindTimeout( nTimeout ) )
+ aProgress.SetTimeLimit( nTimeout );
+ else
+ aProgress.HideTimeLimit();
+ aProgress.Show();
+ aProgress.Update();
+ aProgress.Sync();
+ // try to make sure the progress dialog is painted before continuing
+ Application::Reschedule(true);
+
+ // collect solver parameters
+
+ ReadConditions();
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDocument( mpDocShell->GetModel(), uno::UNO_QUERY );
+
+ ScRange aObjRange;
+ if ( !ParseRef( aObjRange, maEdObjectiveCell.GetText(), false ) )
+ {
+ ShowError( false, &maEdObjectiveCell );
+ return false;
+ }
+ table::CellAddress aObjective( aObjRange.aStart.Tab(), aObjRange.aStart.Col(), aObjRange.aStart.Row() );
+
+ // "changing cells" can be several ranges
+ ScRangeList aVarRanges;
+ if ( !ParseWithNames( aVarRanges, maEdVariableCells.GetText(), mpDoc ) )
+ {
+ ShowError( false, &maEdVariableCells );
+ return false;
+ }
+ uno::Sequence<table::CellAddress> aVariables;
+ sal_Int32 nVarPos = 0;
+ ULONG nRangeCount = aVarRanges.Count();
+ for (ULONG nRangePos=0; nRangePos<nRangeCount; ++nRangePos)
+ {
+ ScRange aRange(*aVarRanges.GetObject(nRangePos));
+ aRange.Justify();
+ SCTAB nTab = aRange.aStart.Tab();
+
+ // resolve into single cells
+
+ sal_Int32 nAdd = ( aRange.aEnd.Col() - aRange.aStart.Col() + 1 ) *
+ ( aRange.aEnd.Row() - aRange.aStart.Row() + 1 );
+ aVariables.realloc( nVarPos + nAdd );
+
+ for (SCROW nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow)
+ for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
+ aVariables[nVarPos++] = table::CellAddress( nTab, nCol, nRow );
+ }
+
+ uno::Sequence<sheet::SolverConstraint> aConstraints;
+ sal_Int32 nConstrPos = 0;
+ for ( std::vector<ScOptConditionRow>::const_iterator aConstrIter = maConditions.begin();
+ aConstrIter != maConditions.end(); ++aConstrIter )
+ {
+ if ( aConstrIter->aLeftStr.Len() )
+ {
+ sheet::SolverConstraint aConstraint;
+ // order of list box entries must match enum values
+ aConstraint.Operator = static_cast<sheet::SolverConstraintOperator>(aConstrIter->nOperator);
+
+ ScRange aLeftRange;
+ if ( !ParseRef( aLeftRange, aConstrIter->aLeftStr, true ) )
+ {
+ ShowError( true, NULL );
+ return false;
+ }
+
+ bool bIsRange = false;
+ ScRange aRightRange;
+ if ( ParseRef( aRightRange, aConstrIter->aRightStr, true ) )
+ {
+ if ( aRightRange.aStart == aRightRange.aEnd )
+ aConstraint.Right <<= table::CellAddress( aRightRange.aStart.Tab(),
+ aRightRange.aStart.Col(), aRightRange.aStart.Row() );
+ else if ( aRightRange.aEnd.Col()-aRightRange.aStart.Col() == aLeftRange.aEnd.Col()-aLeftRange.aStart.Col() &&
+ aRightRange.aEnd.Row()-aRightRange.aStart.Row() == aLeftRange.aEnd.Row()-aLeftRange.aStart.Row() )
+ bIsRange = true; // same size as "left" range, resolve into single cells
+ else
+ {
+ ShowError( true, NULL );
+ return false;
+ }
+ }
+ else
+ {
+ sal_uInt32 nFormat = 0; //! explicit language?
+ double fValue = 0.0;
+ if ( mpDoc->GetFormatTable()->IsNumberFormat( aConstrIter->aRightStr, nFormat, fValue ) )
+ aConstraint.Right <<= fValue;
+ else if ( aConstraint.Operator != sheet::SolverConstraintOperator_INTEGER &&
+ aConstraint.Operator != sheet::SolverConstraintOperator_BINARY )
+ {
+ ShowError( true, NULL );
+ return false;
+ }
+ }
+
+ // resolve into single cells
+
+ sal_Int32 nAdd = ( aLeftRange.aEnd.Col() - aLeftRange.aStart.Col() + 1 ) *
+ ( aLeftRange.aEnd.Row() - aLeftRange.aStart.Row() + 1 );
+ aConstraints.realloc( nConstrPos + nAdd );
+
+ for (SCROW nRow = aLeftRange.aStart.Row(); nRow <= aLeftRange.aEnd.Row(); ++nRow)
+ for (SCCOL nCol = aLeftRange.aStart.Col(); nCol <= aLeftRange.aEnd.Col(); ++nCol)
+ {
+ aConstraint.Left = table::CellAddress( aLeftRange.aStart.Tab(), nCol, nRow );
+ if ( bIsRange )
+ aConstraint.Right <<= table::CellAddress( aRightRange.aStart.Tab(),
+ aRightRange.aStart.Col() + ( nCol - aLeftRange.aStart.Col() ),
+ aRightRange.aStart.Row() + ( nRow - aLeftRange.aStart.Row() ) );
+
+ aConstraints[nConstrPos++] = aConstraint;
+ }
+ }
+ }
+
+ sal_Bool bMaximize = maRbMax.IsChecked();
+ if ( maRbValue.IsChecked() )
+ {
+ // handle "value of" with an additional constraint (and then minimize)
+
+ sheet::SolverConstraint aConstraint;
+ aConstraint.Left = aObjective;
+ aConstraint.Operator = sheet::SolverConstraintOperator_EQUAL;
+
+ String aValStr = maEdTargetValue.GetText();
+ ScRange aRightRange;
+ if ( ParseRef( aRightRange, aValStr, false ) )
+ aConstraint.Right <<= table::CellAddress( aRightRange.aStart.Tab(),
+ aRightRange.aStart.Col(), aRightRange.aStart.Row() );
+ else
+ {
+ sal_uInt32 nFormat = 0; //! explicit language?
+ double fValue = 0.0;
+ if ( mpDoc->GetFormatTable()->IsNumberFormat( aValStr, nFormat, fValue ) )
+ aConstraint.Right <<= fValue;
+ else
+ {
+ ShowError( false, &maEdTargetValue );
+ return false;
+ }
+ }
+
+ aConstraints.realloc( nConstrPos + 1 );
+ aConstraints[nConstrPos++] = aConstraint;
+ }
+
+ // copy old document values
+
+ sal_Int32 nVarCount = aVariables.getLength();
+ uno::Sequence<double> aOldValues;
+ aOldValues.realloc( nVarCount );
+ for (nVarPos=0; nVarPos<nVarCount; ++nVarPos)
+ {
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress( aCellPos, aVariables[nVarPos] );
+ aOldValues[nVarPos] = mpDoc->GetValue( aCellPos );
+ }
+
+ // create and initialize solver
+
+ uno::Reference<sheet::XSolver> xSolver = ScSolverUtil::GetSolver( maEngine );
+ DBG_ASSERT( xSolver.is(), "can't get solver component" );
+ if ( !xSolver.is() )
+ return false;
+
+ xSolver->setDocument( xDocument );
+ xSolver->setObjective( aObjective );
+ xSolver->setVariables( aVariables );
+ xSolver->setConstraints( aConstraints );
+ xSolver->setMaximize( bMaximize );
+
+ // set options
+ uno::Reference<beans::XPropertySet> xOptProp(xSolver, uno::UNO_QUERY);
+ if ( xOptProp.is() )
+ {
+ sal_Int32 nPropCount = maProperties.getLength();
+ for (sal_Int32 nProp=0; nProp<nPropCount; ++nProp)
+ {
+ const beans::PropertyValue& rValue = maProperties[nProp];
+ try
+ {
+ xOptProp->setPropertyValue( rValue.Name, rValue.Value );
+ }
+ catch ( uno::Exception & )
+ {
+ DBG_ERRORFILE("Exception in solver option property");
+ }
+ }
+ }
+
+ xSolver->solve();
+ sal_Bool bSuccess = xSolver->getSuccess();
+
+ aProgress.Hide();
+ bool bClose = false;
+ bool bRestore = true; // restore old values unless a solution is accepted
+ if ( bSuccess )
+ {
+ // put solution into document so it is visible when asking
+ uno::Sequence<double> aSolution = xSolver->getSolution();
+ if ( aSolution.getLength() == nVarCount )
+ {
+ mpDocShell->LockPaint();
+ ScDocFunc aFunc(*mpDocShell);
+ for (nVarPos=0; nVarPos<nVarCount; ++nVarPos)
+ {
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress( aCellPos, aVariables[nVarPos] );
+ aFunc.PutCell( aCellPos, new ScValueCell( aSolution[nVarPos] ), TRUE );
+ }
+ mpDocShell->UnlockPaint();
+ }
+ //! else error?
+
+ // take formatted result from document (result value from component is ignored)
+ String aResultStr;
+ mpDoc->GetString( (SCCOL)aObjective.Column, (SCROW)aObjective.Row, (SCTAB)aObjective.Sheet, aResultStr );
+ ScSolverSuccessDialog aDialog( this, aResultStr );
+ if ( aDialog.Execute() == RET_OK )
+ {
+ // keep results and close dialog
+ bRestore = false;
+ bClose = true;
+ }
+ }
+ else
+ {
+ rtl::OUString aError;
+ uno::Reference<sheet::XSolverDescription> xDesc( xSolver, uno::UNO_QUERY );
+ if ( xDesc.is() )
+ aError = xDesc->getStatusDescription(); // error description from component
+ ScSolverNoSolutionDialog aDialog( this, aError );
+ aDialog.Execute();
+ }
+
+ if ( bRestore ) // restore old values
+ {
+ mpDocShell->LockPaint();
+ ScDocFunc aFunc(*mpDocShell);
+ for (nVarPos=0; nVarPos<nVarCount; ++nVarPos)
+ {
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress( aCellPos, aVariables[nVarPos] );
+ aFunc.PutCell( aCellPos, new ScValueCell( aOldValues[nVarPos] ), TRUE );
+ }
+ mpDocShell->UnlockPaint();
+ }
+
+ return bClose;
+}
+
diff --git a/sc/source/ui/miscdlgs/protectiondlg.cxx b/sc/source/ui/miscdlgs/protectiondlg.cxx
new file mode 100644
index 000000000000..c10620bc8c4a
--- /dev/null
+++ b/sc/source/ui/miscdlgs/protectiondlg.cxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// 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..6b62efb4c784
--- /dev/null
+++ b/sc/source/ui/miscdlgs/protectiondlg.src
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "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/redcom.cxx b/sc/source/ui/miscdlgs/redcom.cxx
new file mode 100644
index 000000000000..7046009f63b2
--- /dev/null
+++ b/sc/source/ui/miscdlgs/redcom.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <vcl/msgbox.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "redcom.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+//------------------------------------------------------------------------
+
+ScRedComDialog::ScRedComDialog( Window* pParent, const SfxItemSet& rCoreSet,
+ ScDocShell *pShell,ScChangeAction *pAction,BOOL bPrevNext)
+{
+ //CHINA001 pDlg = new SvxPostItDialog(pParent,rCoreSet,bPrevNext,TRUE);
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ pDlg = pFact->CreateSvxPostItDialog( pParent, rCoreSet, bPrevNext, TRUE );
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ pDocShell=pShell;
+ pDlg->DontChangeAuthor();
+ pDlg->HideAuthor();
+
+ pDlg->SetPrevHdl(LINK( this, ScRedComDialog, PrevHdl));
+ pDlg->SetNextHdl(LINK( this, ScRedComDialog, NextHdl));
+
+ ReInit(pAction);
+ }
+}
+
+ScRedComDialog::~ScRedComDialog()
+{
+ delete pDlg;
+}
+
+ScChangeAction *ScRedComDialog::FindPrev(ScChangeAction *pAction)
+{
+ if(pAction!=NULL && pDocShell !=NULL)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
+
+ pAction=pAction->GetPrev();
+
+ while(pAction!=NULL)
+ {
+ if( pAction->GetState()==SC_CAS_VIRGIN &&
+ pAction->IsDialogRoot() &&
+ ScViewUtil::IsActionShown(*pAction,*pSettings,*pDoc)) break;
+
+ pAction=pAction->GetPrev();
+ }
+ }
+ return pAction;
+}
+
+ScChangeAction *ScRedComDialog::FindNext(ScChangeAction *pAction)
+{
+ if(pAction!=NULL && pDocShell !=NULL)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
+
+ pAction=pAction->GetNext();
+
+ while(pAction!=NULL)
+ {
+ if( pAction->GetState()==SC_CAS_VIRGIN &&
+ pAction->IsDialogRoot() &&
+ ScViewUtil::IsActionShown(*pAction,*pSettings,*pDoc)) break;
+
+ pAction=pAction->GetNext();
+ }
+ }
+ return pAction;
+}
+
+void ScRedComDialog::ReInit(ScChangeAction *pAction)
+{
+ pChangeAction=pAction;
+ if(pChangeAction!=NULL && pDocShell !=NULL)
+ {
+ String aTitle;
+ pChangeAction->GetDescription( aTitle, pDocShell->GetDocument());
+ pDlg->SetText(aTitle);
+ aComment=pChangeAction->GetComment();
+
+ BOOL bNext=FindNext(pChangeAction)!=NULL;
+ BOOL bPrev=FindPrev(pChangeAction)!=NULL;
+ pDlg->EnableTravel(bNext,bPrev);
+
+ String aAuthor = pChangeAction->GetUser();
+
+ DateTime aDT = pChangeAction->GetDateTime();
+ String aDate = ScGlobal::pLocaleData->getDate( aDT );
+ aDate += ' ';
+ aDate += ScGlobal::pLocaleData->getTime( aDT, FALSE, FALSE );
+
+ pDlg->ShowLastAuthor(aAuthor, aDate);
+ pDlg->SetNote(aComment);
+ }
+}
+
+short ScRedComDialog::Execute()
+{
+ short nRet=pDlg->Execute();
+
+ if(nRet== RET_OK )
+ {
+ if ( pDocShell!=NULL && pDlg->GetNote() != aComment )
+ pDocShell->SetChangeComment( pChangeAction, pDlg->GetNote());
+ }
+
+ return nRet;
+}
+
+void ScRedComDialog::SelectCell()
+{
+ if(pChangeAction!=NULL)
+ {
+ const ScChangeAction* pAction=pChangeAction;
+ const ScBigRange& rRange = pAction->GetBigRange();
+
+ if(rRange.IsValid(pDocShell->GetDocument()))
+ {
+ ScViewData* pViewData=pDocShell->GetViewData();
+ ScRange aRef=rRange.MakeRange();
+ ScTabView* pTabView=pViewData->GetView();
+ pTabView->MarkRange(aRef);
+ }
+ }
+}
+
+IMPL_LINK(ScRedComDialog, PrevHdl, AbstractSvxPostItDialog*, pDlgP )
+{
+ if (pDocShell!=NULL && pDlgP->GetNote() != aComment )
+ pDocShell->SetChangeComment( pChangeAction, pDlgP->GetNote());
+
+ ReInit(FindPrev(pChangeAction));
+ SelectCell();
+
+ return 0;
+}
+
+IMPL_LINK(ScRedComDialog, NextHdl, AbstractSvxPostItDialog*, pDlgP )
+{
+ if ( pDocShell!=NULL && pDlgP->GetNote() != aComment )
+ pDocShell->SetChangeComment( pChangeAction, pDlgP->GetNote());
+
+ ReInit(FindNext(pChangeAction));
+ SelectCell();
+
+ return 0;
+}
+
diff --git a/sc/source/ui/miscdlgs/retypepassdlg.cxx b/sc/source/ui/miscdlgs/retypepassdlg.cxx
new file mode 100644
index 000000000000..24e5dc409c83
--- /dev/null
+++ b/sc/source/ui/miscdlgs/retypepassdlg.cxx
@@ -0,0 +1,544 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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..794af9d43ebd
--- /dev/null
+++ b/sc/source/ui/miscdlgs/retypepassdlg.src
@@ -0,0 +1,313 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "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/miscdlgs/scuiautofmt.cxx b/sc/source/ui/miscdlgs/scuiautofmt.cxx
new file mode 100644
index 000000000000..b2f837db4cb4
--- /dev/null
+++ b/sc/source/ui/miscdlgs/scuiautofmt.cxx
@@ -0,0 +1,476 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "attrib.hxx"
+#include "zforauto.hxx"
+#include "scitems.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "autoform.hxx"
+#include "strindlg.hxx"
+#include "miscdlgs.hrc"
+#include "scuiautofmt.hxx"
+#include "scresid.hxx"
+#include "document.hxx"
+
+//========================================================================
+// AutoFormat-Dialog:
+
+ScAutoFormatDlg::ScAutoFormatDlg( Window* pParent,
+ ScAutoFormat* pAutoFormat,
+ const ScAutoFormatData* pSelFormatData,
+ ScDocument* pDoc ) :
+
+ ModalDialog ( pParent, ScResId( RID_SCDLG_AUTOFORMAT ) ),
+ //
+ aFlFormat ( this, ScResId( FL_FORMAT ) ),
+ aLbFormat ( this, ScResId( LB_FORMAT ) ),
+ pWndPreview ( new ScAutoFmtPreview( this, ScResId( WND_PREVIEW ), pDoc ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnAdd ( this, ScResId( BTN_ADD ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+ aFlFormatting ( this, ScResId( FL_FORMATTING ) ),
+ aBtnNumFormat ( this, ScResId( BTN_NUMFORMAT ) ),
+ aBtnBorder ( this, ScResId( BTN_BORDER ) ),
+ aBtnFont ( this, ScResId( BTN_FONT ) ),
+ aBtnPattern ( this, ScResId( BTN_PATTERN ) ),
+ aBtnAlignment ( this, ScResId( BTN_ALIGNMENT ) ),
+ aBtnAdjust ( this, ScResId( BTN_ADJUST ) ),
+ aBtnRename ( this, ScResId( BTN_RENAME ) ),
+ aStrTitle ( ScResId( STR_ADD_TITLE ) ),
+ aStrLabel ( ScResId( STR_ADD_LABEL ) ),
+ aStrClose ( ScResId( STR_BTN_CLOSE ) ),
+ aStrDelTitle ( ScResId( STR_DEL_TITLE ) ),
+ aStrDelMsg ( ScResId( STR_DEL_MSG ) ) ,
+ aStrRename ( ScResId( STR_RENAME_TITLE ) ),
+ //
+ pFormat ( pAutoFormat ),
+ pSelFmtData ( pSelFormatData ),
+ nIndex ( 0 ),
+ bCoreDataChanged( FALSE ),
+ bFmtInserted ( FALSE )
+{
+ Init();
+ pWndPreview->NotifyChange( (*pFormat)[0] );
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScAutoFormatDlg::~ScAutoFormatDlg()
+{
+ delete pWndPreview;
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFormatDlg::Init()
+{
+ USHORT nCount;
+ String aEntry;
+
+ aLbFormat .SetSelectHdl( LINK( this, ScAutoFormatDlg, SelFmtHdl ) );
+ aBtnNumFormat.SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+ aBtnBorder .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+ aBtnFont .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+ aBtnPattern .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+ aBtnAlignment.SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+ aBtnAdjust .SetClickHdl ( LINK( this, ScAutoFormatDlg, CheckHdl ) );
+ aBtnAdd .SetClickHdl ( LINK( this, ScAutoFormatDlg, AddHdl ) );
+ aBtnRemove .SetClickHdl ( LINK( this, ScAutoFormatDlg, RemoveHdl ) );
+ aBtnOk .SetClickHdl ( LINK( this, ScAutoFormatDlg, CloseHdl ) );
+ aBtnCancel .SetClickHdl ( LINK( this, ScAutoFormatDlg, CloseHdl ) );
+ aBtnRename .SetClickHdl ( LINK( this, ScAutoFormatDlg, RenameHdl ) );
+ aLbFormat .SetDoubleClickHdl( LINK( this, ScAutoFormatDlg, DblClkHdl ) );
+
+ aBtnMore.AddWindow( &aBtnRename );
+ aBtnMore.AddWindow( &aBtnNumFormat );
+ aBtnMore.AddWindow( &aBtnBorder );
+ aBtnMore.AddWindow( &aBtnFont );
+ aBtnMore.AddWindow( &aBtnPattern );
+ aBtnMore.AddWindow( &aBtnAlignment );
+ aBtnMore.AddWindow( &aBtnAdjust );
+ aBtnMore.AddWindow( &aFlFormatting );
+
+ nCount = pFormat->GetCount();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ ((*pFormat)[i])->GetName( aEntry );
+ aLbFormat.InsertEntry( aEntry );
+ }
+
+ if ( nCount == 1 )
+ aBtnRemove.Disable();
+
+ aLbFormat.SelectEntryPos( 0 );
+ aBtnRename.Disable();
+ aBtnRemove.Disable();
+
+ nIndex = 0;
+ UpdateChecks();
+
+ if ( !pSelFmtData )
+ {
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ bFmtInserted = TRUE;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScAutoFormatDlg::UpdateChecks()
+{
+ ScAutoFormatData* pData = (*pFormat)[nIndex];
+
+ aBtnNumFormat.Check( pData->GetIncludeValueFormat() );
+ aBtnBorder .Check( pData->GetIncludeFrame() );
+ aBtnFont .Check( pData->GetIncludeFont() );
+ aBtnPattern .Check( pData->GetIncludeBackground() );
+ aBtnAlignment.Check( pData->GetIncludeJustify() );
+ aBtnAdjust .Check( pData->GetIncludeWidthHeight() );
+}
+
+//------------------------------------------------------------------------
+// Handler:
+//---------
+
+IMPL_LINK( ScAutoFormatDlg, CloseHdl, PushButton *, pBtn )
+{
+ if ( pBtn == &aBtnOk || pBtn == &aBtnCancel )
+ {
+ if ( bCoreDataChanged )
+ ScGlobal::GetAutoFormat()->Save();
+
+ EndDialog( (pBtn == &aBtnOk) ? RET_OK : RET_CANCEL );
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScAutoFormatDlg, DblClkHdl, void *, EMPTYARG )
+{
+ if ( bCoreDataChanged )
+ ScGlobal::GetAutoFormat()->Save();
+
+ EndDialog( RET_OK );
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScAutoFormatDlg, DblClkHdl, void *, EMPTYARG )
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScAutoFormatDlg, CheckHdl, Button *, pBtn )
+{
+ ScAutoFormatData* pData = (*pFormat)[nIndex];
+ BOOL bCheck = ((CheckBox*)pBtn)->IsChecked();
+
+ if ( pBtn == &aBtnNumFormat )
+ pData->SetIncludeValueFormat( bCheck );
+ else if ( pBtn == &aBtnBorder )
+ pData->SetIncludeFrame( bCheck );
+ else if ( pBtn == &aBtnFont )
+ pData->SetIncludeFont( bCheck );
+ else if ( pBtn == &aBtnPattern )
+ pData->SetIncludeBackground( bCheck );
+ else if ( pBtn == &aBtnAlignment )
+ pData->SetIncludeJustify( bCheck );
+ else if ( pBtn == &aBtnAdjust )
+ pData->SetIncludeWidthHeight( bCheck );
+
+ if ( !bCoreDataChanged )
+ {
+ aBtnCancel.SetText( aStrClose );
+ bCoreDataChanged = TRUE;
+ }
+
+ pWndPreview->NotifyChange( pData );
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScAutoFormatDlg, AddHdl, void *, EMPTYARG )
+{
+ if ( !bFmtInserted && pSelFmtData )
+ {
+ String aStrStandard( ScResId(STR_STANDARD) );
+ String aFormatName;
+ ScStringInputDlg* pDlg;
+ BOOL bOk = FALSE;
+
+ while ( !bOk )
+ {
+ pDlg = new ScStringInputDlg( this,
+ aStrTitle,
+ aStrLabel,
+ aFormatName,
+ HID_SC_ADD_AUTOFMT );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetInputString( aFormatName );
+
+ if ( (aFormatName.Len() > 0) && (aFormatName != aStrStandard) )
+ {
+ ScAutoFormatData* pNewData
+ = new ScAutoFormatData( *pSelFmtData );
+
+ pNewData->SetName( aFormatName );
+ bFmtInserted = pFormat->Insert( pNewData );
+
+ if ( bFmtInserted )
+ {
+ USHORT nAt = pFormat->IndexOf( pNewData );
+
+ aLbFormat.InsertEntry( aFormatName, nAt );
+ aLbFormat.SelectEntry( aFormatName );
+ aBtnAdd.Disable();
+
+ if ( !bCoreDataChanged )
+ {
+ aBtnCancel.SetText( aStrClose );
+ bCoreDataChanged = TRUE;
+ }
+
+ SelFmtHdl( 0 );
+ bOk = TRUE;
+ }
+ else
+ delete pNewData;
+
+ }
+
+ if ( !bFmtInserted )
+ {
+ USHORT nRet = ErrorBox( this,
+ WinBits( WB_OK_CANCEL | WB_DEF_OK),
+ ScGlobal::GetRscString(STR_INVALID_AFNAME)
+ ).Execute();
+
+ bOk = ( nRet == RET_CANCEL );
+ }
+ }
+ else
+ bOk = TRUE;
+
+ delete pDlg;
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScAutoFormatDlg, RemoveHdl, void *, EMPTYARG )
+{
+ if ( (nIndex > 0) && (aLbFormat.GetEntryCount() > 0) )
+ {
+ String aMsg( aStrDelMsg.GetToken( 0, '#' ) );
+
+ aMsg += aLbFormat.GetSelectEntry();
+ aMsg += aStrDelMsg.GetToken( 1, '#' );
+
+ if ( RET_YES ==
+ QueryBox( this, WinBits( WB_YES_NO | WB_DEF_YES ), aMsg ).Execute() )
+ {
+ aLbFormat.RemoveEntry( nIndex );
+ aLbFormat.SelectEntryPos( nIndex-1 );
+
+ if ( nIndex-1 == 0 )
+ aBtnRemove.Disable();
+
+ if ( !bCoreDataChanged )
+ {
+ aBtnCancel.SetText( aStrClose );
+ bCoreDataChanged = TRUE;
+ }
+
+ pFormat->AtFree( nIndex ); // in der Core loeschen
+ nIndex--;
+
+ SelFmtHdl( 0 );
+ }
+ }
+
+ SelFmtHdl( 0 );
+
+ return 0;
+}
+
+IMPL_LINK( ScAutoFormatDlg, RenameHdl, void *, EMPTYARG )
+{
+ BOOL bOk = FALSE;
+ while( !bOk )
+ {
+
+ String aFormatName=aLbFormat.GetSelectEntry();
+ String aEntry;
+
+ ScStringInputDlg* pDlg = new ScStringInputDlg( this,
+ aStrRename,
+ aStrLabel,
+ aFormatName,
+ HID_SC_REN_AFMT_DLG );
+ if( pDlg->Execute() == RET_OK )
+ {
+ BOOL bFmtRenamed = FALSE;
+ pDlg->GetInputString( aFormatName );
+ USHORT n;
+
+ if ( aFormatName.Len() > 0 )
+ {
+ for( n = 0; n < pFormat->GetCount(); ++n )
+ {
+ (*pFormat)[n]->GetName(aEntry);
+ if ( aEntry== aFormatName)
+ break;
+ }
+ if( n >= pFormat->GetCount() )
+ {
+ // Format mit dem Namen noch nicht vorhanden, also
+ // umbenennen
+
+ aLbFormat.RemoveEntry(nIndex );
+ ScAutoFormatData* p=(*pFormat)[ nIndex ];
+ ScAutoFormatData* pNewData
+ = new ScAutoFormatData(*p);
+
+ pFormat->AtFree( nIndex );
+
+ pNewData->SetName( aFormatName );
+
+ pFormat->Insert( pNewData);
+
+ USHORT nCount = pFormat->GetCount();
+
+ aLbFormat.SetUpdateMode(FALSE);
+ aLbFormat.Clear();
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ ((*pFormat)[i])->GetName( aEntry );
+ aLbFormat.InsertEntry( aEntry );
+ }
+
+ aLbFormat.SetUpdateMode( TRUE);
+ aLbFormat.SelectEntry( aFormatName);
+
+ if ( !bCoreDataChanged )
+ {
+ aBtnCancel.SetText( aStrClose );
+ bCoreDataChanged = TRUE;
+ }
+
+
+ SelFmtHdl( 0 );
+ bOk = TRUE;
+ bFmtRenamed = TRUE;
+ }
+ }
+ if( !bFmtRenamed )
+ {
+ bOk = RET_CANCEL == ErrorBox( this,
+ WinBits( WB_OK_CANCEL | WB_DEF_OK),
+ ScGlobal::GetRscString(STR_INVALID_AFNAME)
+ ).Execute();
+ }
+ }
+ else
+ bOk = TRUE;
+ delete pDlg;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScAutoFormatDlg, SelFmtHdl, void *, EMPTYARG )
+{
+ nIndex = aLbFormat.GetSelectEntryPos();
+ UpdateChecks();
+
+ if ( nIndex == 0 )
+ {
+ aBtnRename.Disable();
+ aBtnRemove.Disable();
+ }
+ else
+ {
+ aBtnRename.Enable();
+ aBtnRemove.Enable();
+ }
+
+ pWndPreview->NotifyChange( (*pFormat)[nIndex] );
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT ScAutoFormatDlg::GetCurrFormatName()
+{
+ String aResult;
+
+ ((*pFormat)[nIndex])->GetName( aResult );
+
+ return aResult;
+}
diff --git a/sc/source/ui/miscdlgs/sharedocdlg.cxx b/sc/source/ui/miscdlgs/sharedocdlg.cxx
new file mode 100644
index 000000000000..4a5b7cc2149b
--- /dev/null
+++ b/sc/source/ui/miscdlgs/sharedocdlg.cxx
@@ -0,0 +1,235 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <osl/security.hxx>
+#include <svl/sharecontrolfile.hxx>
+#include <unotools/useroptions.hxx>
+
+#include <docsh.hxx>
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+
+#include "sharedocdlg.hxx"
+#include "sharedocdlg.hrc"
+#include "scresid.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+
+
+using namespace ::com::sun::star;
+
+
+//=============================================================================
+// class ScShareDocumentDlg
+//=============================================================================
+
+ScShareDocumentDlg::ScShareDocumentDlg( Window* pParent, ScViewData* pViewData )
+ :ModalDialog( pParent, ScResId( RID_SCDLG_SHAREDOCUMENT ) )
+ ,maCbShare ( this, ScResId( CB_SHARE ) )
+ ,maFtWarning ( this, ScResId( FT_WARNING ) )
+ ,maFlUsers ( this, ScResId( FL_USERS ) )
+ ,maFtUsers ( this, ScResId( FT_USERS ) )
+ ,maLbUsers ( this, ScResId( LB_USERS ) )
+ ,maFlEnd ( this, ScResId( FL_END ) )
+ ,maBtnHelp ( this, ScResId( BTN_HELP ) )
+ ,maBtnOK ( this, ScResId( BTN_OK ) )
+ ,maBtnCancel ( this, ScResId( BTN_CANCEL ) )
+ ,maStrTitleName ( ScResId( STR_TITLE_NAME ) )
+ ,maStrTitleAccessed ( ScResId( STR_TITLE_ACCESSED ) )
+ ,maStrNoUserData ( ScResId( STR_NO_USER_DATA ) )
+ ,maStrUnkownUser ( ScResId( STR_UNKNOWN_USER ) )
+ ,maStrExclusiveAccess ( ScResId( STR_EXCLUSIVE_ACCESS ) )
+ ,mpViewData ( pViewData )
+ ,mpDocShell ( NULL )
+{
+ DBG_ASSERT( mpViewData, "ScShareDocumentDlg CTOR: mpViewData is null!" );
+ mpDocShell = ( mpViewData ? mpViewData->GetDocShell() : NULL );
+ DBG_ASSERT( mpDocShell, "ScShareDocumentDlg CTOR: mpDocShell is null!" );
+
+ FreeResource();
+
+ bool bIsDocShared = ( mpDocShell ? mpDocShell->IsDocShared() : false );
+ maCbShare.Check( bIsDocShared );
+ maCbShare.SetToggleHdl( LINK( this, ScShareDocumentDlg, ToggleHandle ) );
+ maFtWarning.Enable( bIsDocShared );
+
+ long nTabs[] = { 2, 10, 128 };
+ maLbUsers.SetTabs( nTabs );
+
+ String aHeader( maStrTitleName );
+ aHeader += '\t';
+ aHeader += maStrTitleAccessed;
+ maLbUsers.InsertHeaderEntry( aHeader, HEADERBAR_APPEND, HIB_LEFT | HIB_LEFTIMAGE | HIB_VCENTER );
+ maLbUsers.SetSelectionMode( NO_SELECTION );
+
+ UpdateView();
+}
+
+ScShareDocumentDlg::~ScShareDocumentDlg()
+{
+}
+
+IMPL_LINK( ScShareDocumentDlg, ToggleHandle, void*, EMPTYARG )
+{
+ maFtWarning.Enable( maCbShare.IsChecked() );
+
+ return 0;
+}
+
+bool ScShareDocumentDlg::IsShareDocumentChecked() const
+{
+ return maCbShare.IsChecked();
+}
+
+void ScShareDocumentDlg::UpdateView()
+{
+ if ( !mpDocShell )
+ {
+ return;
+ }
+
+ if ( mpDocShell->IsDocShared() )
+ {
+ try
+ {
+ ::svt::ShareControlFile aControlFile( mpDocShell->GetSharedFileURL() );
+ uno::Sequence< uno::Sequence< ::rtl::OUString > > aUsersData = aControlFile.GetUsersData();
+ const uno::Sequence< ::rtl::OUString >* pUsersData = aUsersData.getConstArray();
+ sal_Int32 nLength = aUsersData.getLength();
+
+ if ( nLength > 0 )
+ {
+ sal_Int32 nUnknownUser = 1;
+
+ for ( sal_Int32 i = 0; i < nLength; ++i )
+ {
+ if ( pUsersData[i].getLength() > SHARED_EDITTIME_ID )
+ {
+ String aUser;
+ if ( pUsersData[i][SHARED_OOOUSERNAME_ID].getLength() )
+ {
+ aUser = pUsersData[i][SHARED_OOOUSERNAME_ID];
+ }
+ else if ( pUsersData[i][SHARED_SYSUSERNAME_ID].getLength() )
+ {
+ aUser = pUsersData[i][SHARED_SYSUSERNAME_ID];
+ }
+ else
+ {
+ aUser = maStrUnkownUser;
+ aUser += ' ';
+ aUser += String::CreateFromInt32( nUnknownUser++ );
+ }
+
+ // parse the edit time string of the format "DD.MM.YYYY hh:mm"
+ ::rtl::OUString aDateTimeStr = pUsersData[i][SHARED_EDITTIME_ID];
+ sal_Int32 nIndex = 0;
+ ::rtl::OUString aDateStr = aDateTimeStr.getToken( 0, ' ', nIndex );
+ ::rtl::OUString aTimeStr = aDateTimeStr.getToken( 0, ' ', nIndex );
+ nIndex = 0;
+ USHORT nDay = sal::static_int_cast< USHORT >( aDateStr.getToken( 0, '.', nIndex ).toInt32() );
+ USHORT nMonth = sal::static_int_cast< USHORT >( aDateStr.getToken( 0, '.', nIndex ).toInt32() );
+ USHORT nYear = sal::static_int_cast< USHORT >( aDateStr.getToken( 0, '.', nIndex ).toInt32() );
+ nIndex = 0;
+ USHORT nHours = sal::static_int_cast< USHORT >( aTimeStr.getToken( 0, ':', nIndex ).toInt32() );
+ USHORT nMinutes = sal::static_int_cast< USHORT >( aTimeStr.getToken( 0, ':', nIndex ).toInt32() );
+ Date aDate( nDay, nMonth, nYear );
+ Time aTime( nHours, nMinutes );
+ DateTime aDateTime( aDate, aTime );
+
+ String aString( aUser );
+ aString += '\t';
+ aString += ScGlobal::pLocaleData->getDate( aDateTime );
+ aString += ' ';
+ aString += ScGlobal::pLocaleData->getTime( aDateTime, FALSE );
+
+ maLbUsers.InsertEntry( aString, NULL );
+ }
+ }
+ }
+ else
+ {
+ maLbUsers.InsertEntry( maStrNoUserData, NULL );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "ScShareDocumentDlg::UpdateView(): caught exception\n" );
+ maLbUsers.Clear();
+ maLbUsers.InsertEntry( maStrNoUserData, NULL );
+ }
+ }
+ else
+ {
+ // get OOO user name
+ SvtUserOptions aUserOpt;
+ String aUser = aUserOpt.GetFirstName();
+ if ( aUser.Len() > 0 )
+ {
+ aUser += ' ';
+ }
+ aUser += String(aUserOpt.GetLastName());
+ if ( aUser.Len() == 0 )
+ {
+ // get sys user name
+ ::rtl::OUString aUserName;
+ ::osl::Security aSecurity;
+ aSecurity.getUserName( aUserName );
+ aUser = aUserName;
+ }
+ if ( aUser.Len() == 0 )
+ {
+ // unknown user name
+ aUser = maStrUnkownUser;
+ }
+ aUser += ' ';
+ aUser += maStrExclusiveAccess;
+ String aString( aUser );
+ aString += '\t';
+
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
+
+ util::DateTime uDT(xDocProps->getModificationDate());
+ Date d(uDT.Day, uDT.Month, uDT.Year);
+ Time t(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
+ DateTime aDateTime(d,t);
+
+ aString += ScGlobal::pLocaleData->getDate( aDateTime );
+ aString += ' ';
+ aString += ScGlobal::pLocaleData->getTime( aDateTime, FALSE );
+
+ maLbUsers.InsertEntry( aString, NULL );
+ }
+}
diff --git a/sc/source/ui/miscdlgs/sharedocdlg.src b/sc/source/ui/miscdlgs/sharedocdlg.src
new file mode 100644
index 000000000000..fe55ee58c8e4
--- /dev/null
+++ b/sc/source/ui/miscdlgs/sharedocdlg.src
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sharedocdlg.hrc"
+
+ModalDialog RID_SCDLG_SHAREDOCUMENT
+{
+ OutputSize = TRUE ;
+ HelpId = SID_SHARE_DOC ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 204 , 186 ) ;
+ Text [ en-US ] = "Share Document" ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ CheckBox CB_SHARE
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 192 , 8 ) ;
+ Text [ en-US ] = "Share this spreadsheet with other users" ;
+ };
+ FixedText FT_WARNING
+ {
+ Pos = MAP_APPFONT ( 15 , 18 ) ;
+ Size = MAP_APPFONT ( 183 , 48 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "Note: Changes to formatting attributes like fonts, colors, and number formats will not be saved and some functionalities like editing charts and drawing objects are not available in shared mode. Turn off shared mode to get exclusive access needed for those changes and functionalities." ;
+ };
+ FixedLine FL_USERS
+ {
+ Pos = MAP_APPFONT ( 6 , 66 ) ;
+ Size = MAP_APPFONT ( 192 , 4 ) ;
+ };
+ FixedText FT_USERS
+ {
+ Pos = MAP_APPFONT ( 6 , 72 ) ;
+ Size = MAP_APPFONT ( 192 , 8 ) ;
+ Text [ en-US ] = "Users currently accessing this spreadsheet" ;
+ };
+ Control LB_USERS
+ {
+ Pos = MAP_APPFONT ( 6 , 82 ) ;
+ Size = MAP_APPFONT ( 192 , 72 ) ;
+ Border = TRUE ;
+ };
+ FixedLine FL_END
+ {
+ Pos = MAP_APPFONT ( 1 , 156 ) ;
+ Size = MAP_APPFONT ( 204 , 8 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 6 , 166 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 92 , 166 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 148 , 166 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ String STR_TITLE_NAME
+ {
+ Text [ en-US ] = "Name" ;
+ };
+ String STR_TITLE_ACCESSED
+ {
+ Text [ en-US ] = "Accessed" ;
+ };
+ String STR_NO_USER_DATA
+ {
+ Text [ en-US ] = "No user data available." ;
+ };
+ String STR_UNKNOWN_USER
+ {
+ Text [ en-US ] = "Unknown User" ;
+ };
+ String STR_EXCLUSIVE_ACCESS
+ {
+ Text [ en-US ] = "(exclusive access)" ;
+ };
+};
diff --git a/sc/source/ui/miscdlgs/shtabdlg.cxx b/sc/source/ui/miscdlgs/shtabdlg.cxx
new file mode 100644
index 000000000000..7e57ebbe5d60
--- /dev/null
+++ b/sc/source/ui/miscdlgs/shtabdlg.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <vcl/msgbox.hxx>
+
+#include "shtabdlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+
+//==================================================================
+
+ScShowTabDlg::ScShowTabDlg( Window* pParent ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_SHOW_TAB ) ),
+ aLb ( this, ScResId( LB_ENTRYLIST ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aFtLbTitle ( this, ScResId( FT_LABEL ) )
+{
+ aLb.Clear();
+ aLb.SetDoubleClickHdl( LINK( this, ScShowTabDlg, DblClkHdl ) );
+
+ //-------------
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+void ScShowTabDlg::SetDescription(
+ const String& rTitle, const String& rFixedText,
+ ULONG nDlgHelpId, ULONG nLbHelpId )
+{
+ SetText( rTitle );
+ aFtLbTitle.SetText( rFixedText );
+ SetHelpId( nDlgHelpId );
+ aLb.SetHelpId( nLbHelpId );
+}
+
+void ScShowTabDlg::Insert( const String& rString, BOOL bSelected )
+{
+ aLb.InsertEntry( rString );
+ if( bSelected )
+ aLb.SelectEntryPos( aLb.GetEntryCount() - 1 );
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScShowTabDlg::GetSelectEntryCount() const
+{
+ return aLb.GetSelectEntryCount();
+}
+
+String ScShowTabDlg::GetSelectEntry(USHORT nPos) const
+{
+ return aLb.GetSelectEntry(nPos);
+}
+
+USHORT ScShowTabDlg::GetSelectEntryPos(USHORT nPos) const
+{
+ return aLb.GetSelectEntryPos(nPos);
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScShowTabDlg, DblClkHdl, void *, EMPTYARG )
+{
+ EndDialog( RET_OK );
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScShowTabDlg, DblClkHdl, void *, EMPTYARG )
+
+__EXPORT ScShowTabDlg::~ScShowTabDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/simpref.cxx b/sc/source/ui/miscdlgs/simpref.cxx
new file mode 100644
index 000000000000..097016836ee5
--- /dev/null
+++ b/sc/source/ui/miscdlgs/simpref.cxx
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+
+#include "reffact.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "simpref.hrc"
+#include "rangenam.hxx" // IsNameValid
+#include "simpref.hxx"
+#include "scmod.hxx"
+
+//============================================================================
+
+#define ABS_SREF SCA_VALID \
+ | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
+#define ABS_DREF ABS_SREF \
+ | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
+#define ABS_SREF3D ABS_SREF | SCA_TAB_3D
+#define ABS_DREF3D ABS_DREF | SCA_TAB_3D
+
+//----------------------------------------------------------------------------
+
+#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute()
+#define QUERYBOX(m) QueryBox(this,WinBits(WB_YES_NO|WB_DEF_YES),m).Execute()
+
+//============================================================================
+// class ScSimpleRefDlg
+
+//----------------------------------------------------------------------------
+ScSimpleRefDlg::ScSimpleRefDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SIMPLEREF ),
+ //
+ aFtAssign ( this, ScResId( FT_ASSIGN ) ),
+ aEdAssign ( this, this, ScResId( ED_ASSIGN ) ),
+ aRbAssign ( this, ScResId( RB_ASSIGN ), &aEdAssign, this ),
+
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+
+ //
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData->GetDocument() ),
+ bRefInputMode ( FALSE ),
+ bAutoReOpen ( TRUE ),
+ bCloseOnButtonUp( FALSE ),
+ bSingleCell ( FALSE ),
+ bMultiSelection ( FALSE )
+{
+ // damit die Strings in der Resource bei den FixedTexten bleiben koennen:
+ Init();
+ FreeResource();
+ SetDispatcherLock( TRUE ); // Modal-Modus einschalten
+}
+
+//----------------------------------------------------------------------------
+__EXPORT ScSimpleRefDlg::~ScSimpleRefDlg()
+{
+ SetDispatcherLock( FALSE ); // Modal-Modus einschalten
+}
+
+//----------------------------------------------------------------------------
+void ScSimpleRefDlg::FillInfo(SfxChildWinInfo& rWinInfo) const
+{
+ ScAnyRefDlg::FillInfo(rWinInfo);
+ rWinInfo.bVisible=bAutoReOpen;
+}
+
+//----------------------------------------------------------------------------
+void ScSimpleRefDlg::SetRefString(const String &rStr)
+{
+ aEdAssign.SetText(rStr);
+}
+
+//----------------------------------------------------------------------------
+void ScSimpleRefDlg::Init()
+{
+ aBtnOk.SetClickHdl ( LINK( this, ScSimpleRefDlg, OkBtnHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScSimpleRefDlg, CancelBtnHdl ) );
+ bCloseFlag=FALSE;
+}
+
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Fenster angezeigt wird.
+void ScSimpleRefDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( aEdAssign.IsEnabled() )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( &aEdAssign );
+
+ theCurArea = rRef;
+ String aRefStr;
+ if ( bSingleCell )
+ {
+ ScAddress aAdr = rRef.aStart;
+ aAdr.Format( aRefStr, SCA_ABS_3D, pDocP, pDocP->GetAddressConvention() );
+ }
+ else
+ theCurArea.Format( aRefStr, ABS_DREF3D, pDocP, pDocP->GetAddressConvention() );
+
+ if ( bMultiSelection )
+ {
+ String aVal = aEdAssign.GetText();
+ Selection aSel = aEdAssign.GetSelection();
+ aSel.Justify();
+ aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ aVal.Insert( aRefStr, (xub_StrLen)aSel.Min() );
+ Selection aNewSel( aSel.Min(), aSel.Min()+aRefStr.Len() );
+ aEdAssign.SetRefString( aVal );
+ aEdAssign.SetSelection( aNewSel );
+ }
+ else
+ aEdAssign.SetRefString( aRefStr );
+
+ aChangeHdl.Call( &aRefStr );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+BOOL __EXPORT ScSimpleRefDlg::Close()
+{
+ CancelBtnHdl(&aBtnCancel);
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+void ScSimpleRefDlg::SetActive()
+{
+ aEdAssign.GrabFocus();
+
+ // kein NameModifyHdl, weil sonst Bereiche nicht geaendert werden koennen
+ // (nach dem Aufziehen der Referenz wuerde der alte Inhalt wieder angezeigt)
+ // (der ausgewaehlte DB-Name hat sich auch nicht veraendert)
+
+ RefInputDone();
+}
+//------------------------------------------------------------------------
+BOOL ScSimpleRefDlg::IsRefInputMode() const
+{
+ return TRUE;
+}
+
+String ScSimpleRefDlg::GetRefString() const
+{
+ return aEdAssign.GetText();
+}
+
+void ScSimpleRefDlg::SetCloseHdl( const Link& rLink )
+{
+ aCloseHdl=rLink;
+}
+
+void ScSimpleRefDlg::SetUnoLinks( const Link& rDone, const Link& rAbort,
+ const Link& rChange )
+{
+ aDoneHdl = rDone;
+ aAbortedHdl = rAbort;
+ aChangeHdl = rChange;
+}
+
+void ScSimpleRefDlg::SetFlags( BOOL bSetCloseOnButtonUp, BOOL bSetSingleCell, BOOL bSetMultiSelection )
+{
+ bCloseOnButtonUp = bSetCloseOnButtonUp;
+ bSingleCell = bSetSingleCell;
+ bMultiSelection = bSetMultiSelection;
+}
+
+void ScSimpleRefDlg::StartRefInput()
+{
+ if ( bMultiSelection )
+ {
+ // initially select the whole string, so it gets replaced by default
+ aEdAssign.SetSelection( Selection( 0, aEdAssign.GetText().Len() ) );
+ }
+
+ aRbAssign.DoRef();
+ bCloseFlag=TRUE;
+}
+
+void ScSimpleRefDlg::RefInputDone( BOOL bForced)
+{
+ ScAnyRefDlg::RefInputDone(bForced);
+ if ( (bForced || bCloseOnButtonUp) && bCloseFlag )
+ OkBtnHdl(&aBtnOk);
+}
+//------------------------------------------------------------------------
+// Handler:
+// ========
+IMPL_LINK( ScSimpleRefDlg, OkBtnHdl, void *, EMPTYARG )
+{
+ bAutoReOpen=FALSE;
+ String aResult=aEdAssign.GetText();
+ aCloseHdl.Call(&aResult);
+ Link aUnoLink = aDoneHdl; // stack var because this is deleted in DoClose
+ DoClose( ScSimpleRefDlgWrapper::GetChildWindowId() );
+ aUnoLink.Call( &aResult );
+ return 0;
+}
+
+//------------------------------------------------------------------------
+IMPL_LINK( ScSimpleRefDlg, CancelBtnHdl, void *, EMPTYARG )
+{
+ bAutoReOpen=FALSE;
+ String aResult=aEdAssign.GetText();
+ aCloseHdl.Call(NULL);
+ Link aUnoLink = aAbortedHdl; // stack var because this is deleted in DoClose
+ DoClose( ScSimpleRefDlgWrapper::GetChildWindowId() );
+ aUnoLink.Call( &aResult );
+ return 0;
+}
+
+
+
+//------------------------------------------------------------------------
+
diff --git a/sc/source/ui/miscdlgs/solveroptions.cxx b/sc/source/ui/miscdlgs/solveroptions.cxx
new file mode 100644
index 000000000000..418a88b3cbea
--- /dev/null
+++ b/sc/source/ui/miscdlgs/solveroptions.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "solveroptions.hxx"
+#include "solveroptions.hrc"
+#include "scresid.hxx"
+#include "global.hxx"
+#include "miscuno.hxx"
+#include "solverutil.hxx"
+
+#include <rtl/math.hxx>
+#include <vcl/msgbox.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include <algorithm>
+
+#include <com/sun/star/sheet/Solver.hpp>
+#include <com/sun/star/sheet/XSolverDescription.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace com::sun::star;
+
+//==================================================================
+
+/// Helper for sorting properties
+struct ScSolverOptionsEntry
+{
+ sal_Int32 nPosition;
+ rtl::OUString aDescription;
+
+ ScSolverOptionsEntry() : nPosition(0) {}
+
+ bool operator< (const ScSolverOptionsEntry& rOther) const
+ {
+ return ( ScGlobal::GetCollator()->compareString( aDescription, rOther.aDescription ) == COMPARE_LESS );
+ }
+};
+
+//------------------------------------------------------------------
+
+class ScSolverOptionsString : public SvLBoxString
+{
+ bool mbIsDouble;
+ double mfDoubleValue;
+ sal_Int32 mnIntValue;
+
+public:
+ ScSolverOptionsString( SvLBoxEntry* pEntry, USHORT nFlags, const String& rStr ) :
+ SvLBoxString( pEntry, nFlags, rStr ),
+ mbIsDouble( false ),
+ mfDoubleValue( 0.0 ),
+ mnIntValue( 0 ) {}
+
+ bool IsDouble() const { return mbIsDouble; }
+ double GetDoubleValue() const { return mfDoubleValue; }
+ sal_Int32 GetIntValue() const { return mnIntValue; }
+
+ void SetDoubleValue( double fNew ) { mbIsDouble = true; mfDoubleValue = fNew; }
+ void SetIntValue( sal_Int32 nNew ) { mbIsDouble = false; mnIntValue = nNew; }
+
+ virtual void Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags, SvLBoxEntry* pEntry );
+};
+
+void ScSolverOptionsString::Paint( const Point& rPos, SvLBox& rDev, USHORT, SvLBoxEntry* /* pEntry */ )
+{
+ //! move position? (SvxLinguTabPage: aPos.X() += 20)
+ String aNormalStr( GetText() );
+ aNormalStr.Append( (sal_Unicode) ':' );
+ rDev.DrawText( rPos, aNormalStr );
+
+ Point aNewPos( rPos );
+ aNewPos.X() += rDev.GetTextWidth( aNormalStr );
+ Font aOldFont( rDev.GetFont() );
+ Font aFont( aOldFont );
+ aFont.SetWeight( WEIGHT_BOLD );
+
+ String sTxt( ' ' );
+ if ( mbIsDouble )
+ sTxt += (String)rtl::math::doubleToUString( mfDoubleValue,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::GetpLocaleData()->getNumDecimalSep().GetChar(0), true );
+ else
+ sTxt += String::CreateFromInt32( mnIntValue );
+ rDev.SetFont( aFont );
+ rDev.DrawText( aNewPos, sTxt );
+
+ rDev.SetFont( aOldFont );
+}
+
+//------------------------------------------------------------------
+
+ScSolverOptionsDialog::ScSolverOptionsDialog( Window* pParent,
+ const uno::Sequence<rtl::OUString>& rImplNames,
+ const uno::Sequence<rtl::OUString>& rDescriptions,
+ const String& rEngine,
+ const uno::Sequence<beans::PropertyValue>& rProperties )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVEROPTIONS ) ),
+ maFtEngine ( this, ScResId( FT_ENGINE ) ),
+ maLbEngine ( this, ScResId( LB_ENGINE ) ),
+ maFtSettings ( this, ScResId( FT_SETTINGS ) ),
+ maLbSettings ( this, ScResId( LB_SETTINGS ) ),
+ maBtnEdit ( this, ScResId( BTN_EDIT ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ mpCheckButtonData( NULL ),
+ maImplNames( rImplNames ),
+ maDescriptions( rDescriptions ),
+ maEngine( rEngine ),
+ maProperties( rProperties )
+{
+ maLbEngine.SetSelectHdl( LINK( this, ScSolverOptionsDialog, EngineSelectHdl ) );
+
+ maBtnEdit.SetClickHdl( LINK( this, ScSolverOptionsDialog, ButtonHdl ) );
+
+ maLbSettings.SetWindowBits( WB_CLIPCHILDREN|WB_FORCE_MAKEVISIBLE );
+ maLbSettings.SetHelpId( HID_SC_SOLVEROPTIONS_LB );
+ maLbSettings.SetHighlightRange();
+
+ maLbSettings.SetSelectHdl( LINK( this, ScSolverOptionsDialog, SettingsSelHdl ) );
+ maLbSettings.SetDoubleClickHdl( LINK( this, ScSolverOptionsDialog, SettingsDoubleClickHdl ) );
+
+ sal_Int32 nSelect = -1;
+ sal_Int32 nImplCount = maImplNames.getLength();
+ for (sal_Int32 nImpl=0; nImpl<nImplCount; ++nImpl)
+ {
+ String aImplName( maImplNames[nImpl] );
+ String aDescription( maDescriptions[nImpl] ); // user-visible descriptions in list box
+ maLbEngine.InsertEntry( aDescription );
+ if ( aImplName == maEngine )
+ nSelect = nImpl;
+ }
+ if ( nSelect < 0 ) // no (valid) engine given
+ {
+ if ( nImplCount > 0 )
+ {
+ maEngine = maImplNames[0]; // use first implementation
+ nSelect = 0;
+ }
+ else
+ maEngine.Erase();
+ maProperties.realloc(0); // don't use options from different engine
+ }
+ if ( nSelect >= 0 ) // select in list box
+ maLbEngine.SelectEntryPos( static_cast<USHORT>(nSelect) );
+
+ if ( !maProperties.getLength() )
+ ReadFromComponent(); // fill maProperties from component (using maEngine)
+ FillListBox(); // using maProperties
+
+ FreeResource();
+}
+
+ScSolverOptionsDialog::~ScSolverOptionsDialog()
+{
+ delete mpCheckButtonData;
+}
+
+const String& ScSolverOptionsDialog::GetEngine() const
+{
+ return maEngine; // already updated in selection handler
+}
+
+const uno::Sequence<beans::PropertyValue>& ScSolverOptionsDialog::GetProperties()
+{
+ // update maProperties from list box content
+ // order of entries in list box and maProperties is the same
+ sal_Int32 nEntryCount = maProperties.getLength();
+ SvLBoxTreeList* pModel = maLbSettings.GetModel();
+ if ( nEntryCount == (sal_Int32)pModel->GetEntryCount() )
+ {
+ for (sal_Int32 nEntryPos=0; nEntryPos<nEntryCount; ++nEntryPos)
+ {
+ uno::Any& rValue = maProperties[nEntryPos].Value;
+ SvLBoxEntry* pEntry = pModel->GetEntry(nEntryPos);
+
+ bool bHasData = false;
+ USHORT nItemCount = pEntry->ItemCount();
+ for (USHORT nItemPos=0; nItemPos<nItemCount && !bHasData; ++nItemPos)
+ {
+ SvLBoxItem* pItem = pEntry->GetItem( nItemPos );
+ ScSolverOptionsString* pStringItem = dynamic_cast<ScSolverOptionsString*>(pItem);
+ if ( pStringItem )
+ {
+ if ( pStringItem->IsDouble() )
+ rValue <<= pStringItem->GetDoubleValue();
+ else
+ rValue <<= pStringItem->GetIntValue();
+ bHasData = true;
+ }
+ }
+ if ( !bHasData )
+ ScUnoHelpFunctions::SetBoolInAny( rValue,
+ maLbSettings.GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "wrong count" );
+ }
+
+ return maProperties;
+}
+
+void ScSolverOptionsDialog::FillListBox()
+{
+ // get property descriptions, sort by them
+
+ uno::Reference<sheet::XSolverDescription> xDesc( ScSolverUtil::GetSolver( maEngine ), uno::UNO_QUERY );
+ sal_Int32 nCount = maProperties.getLength();
+ std::vector<ScSolverOptionsEntry> aDescriptions( nCount );
+ for (sal_Int32 nPos=0; nPos<nCount; nPos++)
+ {
+ rtl::OUString aPropName( maProperties[nPos].Name );
+ rtl::OUString aVisName;
+ if ( xDesc.is() )
+ aVisName = xDesc->getPropertyDescription( aPropName );
+ if ( !aVisName.getLength() )
+ aVisName = aPropName;
+ aDescriptions[nPos].nPosition = nPos;
+ aDescriptions[nPos].aDescription = aVisName;
+ }
+ std::sort( aDescriptions.begin(), aDescriptions.end() );
+
+ // also update maProperties to the order of descriptions
+
+ uno::Sequence<beans::PropertyValue> aNewSeq;
+ aNewSeq.realloc( nCount );
+ for (sal_Int32 nPos=0; nPos<nCount; nPos++)
+ aNewSeq[nPos] = maProperties[ aDescriptions[nPos].nPosition ];
+ maProperties = aNewSeq;
+
+ // fill the list box
+
+ maLbSettings.SetUpdateMode(FALSE);
+ maLbSettings.Clear();
+
+ String sEmpty;
+ if (!mpCheckButtonData)
+ mpCheckButtonData = new SvLBoxButtonData( &maLbSettings );
+
+ SvLBoxTreeList* pModel = maLbSettings.GetModel();
+ SvLBoxEntry* pEntry = NULL;
+
+ for (sal_Int32 nPos=0; nPos<nCount; nPos++)
+ {
+ rtl::OUString aVisName = aDescriptions[nPos].aDescription;
+
+ uno::Any aValue = maProperties[nPos].Value;
+ uno::TypeClass eClass = aValue.getValueTypeClass();
+ if ( eClass == uno::TypeClass_BOOLEAN )
+ {
+ // check box entry
+ pEntry = new SvLBoxEntry;
+ SvLBoxButton* pButton = new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, mpCheckButtonData );
+ if ( ScUnoHelpFunctions::GetBoolFromAny( aValue ) )
+ pButton->SetStateChecked();
+ else
+ pButton->SetStateUnchecked();
+ pEntry->AddItem( pButton );
+ pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0 ) );
+ pEntry->AddItem( new SvLBoxString( pEntry, 0, aVisName ) );
+ }
+ else
+ {
+ // value entry
+ pEntry = new SvLBoxEntry;
+ pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty ) ); // empty column
+ pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0 ) );
+ ScSolverOptionsString* pItem = new ScSolverOptionsString( pEntry, 0, aVisName );
+ if ( eClass == uno::TypeClass_DOUBLE )
+ {
+ double fDoubleValue = 0.0;
+ if ( aValue >>= fDoubleValue )
+ pItem->SetDoubleValue( fDoubleValue );
+ }
+ else
+ {
+ sal_Int32 nIntValue = 0;
+ if ( aValue >>= nIntValue )
+ pItem->SetIntValue( nIntValue );
+ }
+ pEntry->AddItem( pItem );
+ }
+ pModel->Insert( pEntry );
+ }
+
+ maLbSettings.SetUpdateMode(TRUE);
+}
+
+void ScSolverOptionsDialog::ReadFromComponent()
+{
+ maProperties = ScSolverUtil::GetDefaults( maEngine );
+}
+
+void ScSolverOptionsDialog::EditOption()
+{
+ SvLBoxEntry* pEntry = maLbSettings.GetCurEntry();
+ if (pEntry)
+ {
+ USHORT nItemCount = pEntry->ItemCount();
+ for (USHORT nPos=0; nPos<nItemCount; ++nPos)
+ {
+ SvLBoxItem* pItem = pEntry->GetItem( nPos );
+ ScSolverOptionsString* pStringItem = dynamic_cast<ScSolverOptionsString*>(pItem);
+ if ( pStringItem )
+ {
+ if ( pStringItem->IsDouble() )
+ {
+ ScSolverValueDialog aValDialog( this );
+ aValDialog.SetOptionName( pStringItem->GetText() );
+ aValDialog.SetValue( pStringItem->GetDoubleValue() );
+ if ( aValDialog.Execute() == RET_OK )
+ {
+ pStringItem->SetDoubleValue( aValDialog.GetValue() );
+ maLbSettings.InvalidateEntry( pEntry );
+ }
+ }
+ else
+ {
+ ScSolverIntegerDialog aIntDialog( this );
+ aIntDialog.SetOptionName( pStringItem->GetText() );
+ aIntDialog.SetValue( pStringItem->GetIntValue() );
+ if ( aIntDialog.Execute() == RET_OK )
+ {
+ pStringItem->SetIntValue( aIntDialog.GetValue() );
+ maLbSettings.InvalidateEntry( pEntry );
+ }
+ }
+ }
+ }
+ }
+}
+
+IMPL_LINK( ScSolverOptionsDialog, ButtonHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &maBtnEdit )
+ EditOption();
+
+ return 0;
+}
+
+IMPL_LINK( ScSolverOptionsDialog, SettingsDoubleClickHdl, SvTreeListBox*, EMPTYARG )
+{
+ EditOption();
+ return 0;
+}
+
+IMPL_LINK( ScSolverOptionsDialog, EngineSelectHdl, ListBox*, EMPTYARG )
+{
+ USHORT nSelectPos = maLbEngine.GetSelectEntryPos();
+ if ( nSelectPos < maImplNames.getLength() )
+ {
+ String aNewEngine( maImplNames[nSelectPos] );
+ if ( aNewEngine != maEngine )
+ {
+ maEngine = aNewEngine;
+ ReadFromComponent(); // fill maProperties from component (using maEngine)
+ FillListBox(); // using maProperties
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( ScSolverOptionsDialog, SettingsSelHdl, SvxCheckListBox*, EMPTYARG )
+{
+ BOOL bCheckbox = FALSE;
+
+ SvLBoxEntry* pEntry = maLbSettings.GetCurEntry();
+ if (pEntry)
+ {
+ SvLBoxItem* pItem = pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON);
+ if ( pItem && pItem->IsA() == SV_ITEM_ID_LBOXBUTTON )
+ bCheckbox = TRUE;
+ }
+
+ maBtnEdit.Enable( !bCheckbox );
+
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+ScSolverIntegerDialog::ScSolverIntegerDialog( Window * pParent )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_INTEGER ) ),
+ maFtName ( this, ScResId( FT_OPTIONNAME ) ),
+ maNfValue ( this, ScResId( NF_VALUE ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) )
+{
+ FreeResource();
+}
+
+ScSolverIntegerDialog::~ScSolverIntegerDialog()
+{
+}
+
+void ScSolverIntegerDialog::SetOptionName( const String& rName )
+{
+ maFtName.SetText( rName );
+}
+
+void ScSolverIntegerDialog::SetValue( sal_Int32 nValue )
+{
+ maNfValue.SetValue( nValue );
+}
+
+sal_Int32 ScSolverIntegerDialog::GetValue() const
+{
+ sal_Int64 nValue = maNfValue.GetValue();
+ if ( nValue < SAL_MIN_INT32 )
+ return SAL_MIN_INT32;
+ if ( nValue > SAL_MAX_INT32 )
+ return SAL_MAX_INT32;
+ return (sal_Int32) nValue;
+}
+
+//------------------------------------------------------------------
+
+ScSolverValueDialog::ScSolverValueDialog( Window * pParent )
+ : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_DOUBLE ) ),
+ maFtName ( this, ScResId( FT_OPTIONNAME ) ),
+ maEdValue ( this, ScResId( ED_VALUE ) ),
+ maFlButtons ( this, ScResId( FL_BUTTONS ) ),
+ maBtnOk ( this, ScResId( BTN_OK ) ),
+ maBtnCancel ( this, ScResId( BTN_CANCEL ) )
+{
+ FreeResource();
+}
+
+ScSolverValueDialog::~ScSolverValueDialog()
+{
+}
+
+void ScSolverValueDialog::SetOptionName( const String& rName )
+{
+ maFtName.SetText( rName );
+}
+
+void ScSolverValueDialog::SetValue( double fValue )
+{
+ maEdValue.SetText( rtl::math::doubleToUString( fValue,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::GetpLocaleData()->getNumDecimalSep().GetChar(0), true ) );
+}
+
+double ScSolverValueDialog::GetValue() const
+{
+ String aInput = maEdValue.GetText();
+
+ const LocaleDataWrapper* pLocaleData = ScGlobal::GetpLocaleData();
+ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
+ double fValue = rtl::math::stringToDouble( aInput,
+ pLocaleData->getNumDecimalSep().GetChar(0),
+ pLocaleData->getNumThousandSep().GetChar(0),
+ &eStatus, NULL );
+ return fValue;
+}
+
diff --git a/sc/source/ui/miscdlgs/solverutil.cxx b/sc/source/ui/miscdlgs/solverutil.cxx
new file mode 100644
index 000000000000..ae080f2525c7
--- /dev/null
+++ b/sc/source/ui/miscdlgs/solverutil.cxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------
+
+#include "solverutil.hxx"
+
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/XSolver.hpp>
+#include <com/sun/star/sheet/XSolverDescription.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+#define SCSOLVER_SERVICE "com.sun.star.sheet.Solver"
+
+uno::Reference<sheet::XSolver> lcl_CreateSolver( const uno::Reference<uno::XInterface>& xIntFac,
+ const uno::Reference<uno::XComponentContext>& xCtx )
+{
+ uno::Reference<sheet::XSolver> xSolver;
+
+ uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
+ uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
+ if ( xCFac.is() )
+ {
+ try
+ {
+ uno::Reference<uno::XInterface> xInterface = xCFac->createInstanceWithContext(xCtx);
+ xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY );
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ if ( !xSolver.is() && xFac.is() )
+ {
+ try
+ {
+ uno::Reference<uno::XInterface> xInterface = xFac->createInstance();
+ xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY );
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+
+ return xSolver;
+}
+
+// static
+void ScSolverUtil::GetImplementations( uno::Sequence<rtl::OUString>& rImplNames,
+ uno::Sequence<rtl::OUString>& rDescriptions )
+{
+ rImplNames.realloc(0); // clear
+ rDescriptions.realloc(0);
+ sal_Int32 nCount = 0;
+
+ uno::Reference<uno::XComponentContext> xCtx;
+ uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory();
+ uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY);
+ try
+ {
+ xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx;
+ }
+ catch ( uno::Exception & )
+ {
+ }
+
+ uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY );
+ if ( xCtx.is() && xEnAc.is() )
+ {
+ uno::Reference<container::XEnumeration> xEnum =
+ xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) );
+ if ( xEnum.is() )
+ {
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Any aAny = xEnum->nextElement();
+ uno::Reference<uno::XInterface> xIntFac;
+ aAny >>= xIntFac;
+ if ( xIntFac.is() )
+ {
+ uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
+ if ( xInfo.is() )
+ {
+ rtl::OUString sName = xInfo->getImplementationName();
+ rtl::OUString sDescription;
+
+ uno::Reference<sheet::XSolver> xSolver = lcl_CreateSolver( xIntFac, xCtx );
+ uno::Reference<sheet::XSolverDescription> xDesc( xSolver, uno::UNO_QUERY );
+ if ( xDesc.is() )
+ sDescription = xDesc->getComponentDescription();
+
+ if ( !sDescription.getLength() )
+ sDescription = sName; // use implementation name if no description available
+
+ rImplNames.realloc( nCount+1 );
+ rImplNames[nCount] = sName;
+ rDescriptions.realloc( nCount+1 );
+ rDescriptions[nCount] = sDescription;
+ ++nCount;
+ }
+ }
+ }
+ }
+ }
+}
+
+// static
+uno::Reference<sheet::XSolver> ScSolverUtil::GetSolver( const rtl::OUString& rImplName )
+{
+ uno::Reference<sheet::XSolver> xSolver;
+
+ uno::Reference<uno::XComponentContext> xCtx;
+ uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory();
+ uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY);
+ try
+ {
+ xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx;
+ }
+ catch ( uno::Exception & )
+ {
+ }
+
+ uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY );
+ if ( xCtx.is() && xEnAc.is() )
+ {
+ uno::Reference<container::XEnumeration> xEnum =
+ xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) );
+ if ( xEnum.is() )
+ {
+ while ( xEnum->hasMoreElements() && !xSolver.is() )
+ {
+ uno::Any aAny = xEnum->nextElement();
+ uno::Reference<uno::XInterface> xIntFac;
+ aAny >>= xIntFac;
+ if ( xIntFac.is() )
+ {
+ uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
+ if ( xInfo.is() )
+ {
+ rtl::OUString sName = xInfo->getImplementationName();
+ if ( sName == rImplName )
+ xSolver = lcl_CreateSolver( xIntFac, xCtx );
+ }
+ }
+ }
+ }
+ }
+
+ OSL_ENSURE( xSolver.is(), "can't get solver" );
+ return xSolver;
+}
+
+// static
+uno::Sequence<beans::PropertyValue> ScSolverUtil::GetDefaults( const rtl::OUString& rImplName )
+{
+ uno::Sequence<beans::PropertyValue> aDefaults;
+
+ uno::Reference<sheet::XSolver> xSolver = GetSolver( rImplName );
+ uno::Reference<beans::XPropertySet> xPropSet( xSolver, uno::UNO_QUERY );
+ if ( !xPropSet.is() )
+ {
+ // no XPropertySet - no options
+ return aDefaults;
+ }
+
+ // fill maProperties
+
+ uno::Reference<beans::XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo();
+ OSL_ENSURE( xInfo.is(), "can't get property set info" );
+ if ( !xInfo.is() )
+ return aDefaults;
+
+ uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
+ const sal_Int32 nSize = aPropSeq.getLength();
+ aDefaults.realloc(nSize);
+ sal_Int32 nValid = 0;
+ for (sal_Int32 nPos=0; nPos<nSize; ++nPos)
+ {
+ const beans::Property& rProp = aPropSeq[nPos];
+ uno::Any aValue = xPropSet->getPropertyValue( rProp.Name );
+ uno::TypeClass eClass = aValue.getValueTypeClass();
+ // only use properties of supported types
+ if ( eClass == uno::TypeClass_BOOLEAN || eClass == uno::TypeClass_LONG || eClass == uno::TypeClass_DOUBLE )
+ aDefaults[nValid++] = beans::PropertyValue( rProp.Name, -1, aValue, beans::PropertyState_DIRECT_VALUE );
+ }
+ aDefaults.realloc(nValid);
+
+ //! get user-visible names, sort by them
+
+ return aDefaults;
+}
+
diff --git a/sc/source/ui/miscdlgs/solvrdlg.cxx b/sc/source/ui/miscdlgs/solvrdlg.cxx
new file mode 100644
index 000000000000..5b41592e8457
--- /dev/null
+++ b/sc/source/ui/miscdlgs/solvrdlg.cxx
@@ -0,0 +1,313 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//----------------------------------------------------------------------------
+
+#include "rangelst.hxx"
+#include "scitems.hxx"
+#include <sfx2/dispatch.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "uiitems.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "solvrdlg.hrc"
+
+#define _SOLVRDLG_CXX
+#include "solvrdlg.hxx"
+#undef _SOLVERDLG_CXX
+
+
+#define ERRORBOX(s) ErrorBox( this, WinBits( WB_OK | WB_DEF_OK), s ).Execute()
+
+
+//============================================================================
+// class ScSolverDlg
+//----------------------------------------------------------------------------
+
+ScSolverDlg::ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocument* pDocument,
+ ScAddress aCursorPos )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SOLVER ),
+ //
+ aFlVariables ( this, ScResId( FL_VARIABLES ) ),
+ aFtFormulaCell ( this, ScResId( FT_FORMULACELL ) ),
+ aEdFormulaCell ( this, this, ScResId( ED_FORMULACELL ) ),
+ aRBFormulaCell ( this, ScResId( RB_FORMULACELL ), &aEdFormulaCell, this ),
+ aFtTargetVal ( this, ScResId( FT_TARGETVAL ) ),
+ aEdTargetVal ( this, ScResId( ED_TARGETVAL ) ),
+ aFtVariableCell ( this, ScResId( FT_VARCELL ) ),
+ aEdVariableCell ( this, this, ScResId( ED_VARCELL ) ),
+ aRBVariableCell ( this, ScResId( RB_VARCELL ), &aEdVariableCell, this ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ //
+ theFormulaCell ( aCursorPos ),
+ theVariableCell ( aCursorPos ),
+ pDoc ( pDocument ),
+ nCurTab ( aCursorPos.Tab() ),
+ pEdActive ( NULL ),
+ bDlgLostFocus ( FALSE ),
+ errMsgInvalidVar ( ScResId( STR_INVALIDVAR ) ),
+ errMsgInvalidForm ( ScResId( STR_INVALIDFORM ) ),
+ errMsgNoFormula ( ScResId( STR_NOFORMULA ) ),
+ errMsgInvalidVal ( ScResId( STR_INVALIDVAL ) )
+{
+ Init();
+ FreeResource();
+}
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScSolverDlg::~ScSolverDlg()
+{
+}
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScSolverDlg::Init()
+{
+ String aStr;
+
+ aBtnOk. SetClickHdl ( LINK( this, ScSolverDlg, BtnHdl ) );
+ aBtnCancel. SetClickHdl ( LINK( this, ScSolverDlg, BtnHdl ) );
+
+ Link aLink = LINK( this, ScSolverDlg, GetFocusHdl );
+ aEdFormulaCell. SetGetFocusHdl ( aLink );
+ aRBFormulaCell. SetGetFocusHdl ( aLink );
+ aEdVariableCell.SetGetFocusHdl ( aLink );
+ aRBVariableCell.SetGetFocusHdl ( aLink );
+ aEdTargetVal. SetGetFocusHdl ( aLink );
+
+ aLink = LINK( this, ScSolverDlg, LoseFocusHdl );
+ aEdFormulaCell. SetLoseFocusHdl ( aLink );
+ aRBFormulaCell. SetLoseFocusHdl ( aLink );
+ aEdVariableCell.SetLoseFocusHdl ( aLink );
+ aRBVariableCell.SetLoseFocusHdl ( aLink );
+
+ theFormulaCell.Format( aStr, SCA_ABS, NULL, pDoc->GetAddressConvention() );
+
+ aEdFormulaCell.SetText( aStr );
+ aEdFormulaCell.GrabFocus();
+ pEdActive = &aEdFormulaCell;
+}
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScSolverDlg::Close()
+{
+ return DoClose( ScSolverDlgWrapper::GetChildWindowId() );
+}
+
+//----------------------------------------------------------------------------
+
+void ScSolverDlg::SetActive()
+{
+ if ( bDlgLostFocus )
+ {
+ bDlgLostFocus = FALSE;
+ if( pEdActive )
+ pEdActive->GrabFocus();
+ }
+ else
+ {
+ GrabFocus();
+ }
+ RefInputDone();
+}
+
+//----------------------------------------------------------------------------
+
+void ScSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if( pEdActive )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart(pEdActive);
+
+ String aStr;
+ ScAddress aAdr = rRef.aStart;
+ USHORT nFmt = ( aAdr.Tab() == nCurTab )
+ ? SCA_ABS
+ : SCA_ABS_3D;
+
+ aAdr.Format( aStr, nFmt, pDocP, pDocP->GetAddressConvention() );
+ pEdActive->SetRefString( aStr );
+
+ if ( pEdActive == &aEdFormulaCell )
+ theFormulaCell = aAdr;
+ else if ( pEdActive == &aEdVariableCell )
+ theVariableCell = aAdr;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScSolverDlg::RaiseError( ScSolverErr eError )
+{
+ switch ( eError )
+ {
+ case SOLVERR_NOFORMULA:
+ ERRORBOX( errMsgNoFormula );
+ aEdFormulaCell.GrabFocus();
+ break;
+
+ case SOLVERR_INVALID_FORMULA:
+ ERRORBOX( errMsgInvalidForm );
+ aEdFormulaCell.GrabFocus();
+ break;
+
+ case SOLVERR_INVALID_VARIABLE:
+ ERRORBOX( errMsgInvalidVar );
+ aEdVariableCell.GrabFocus();
+ break;
+
+ case SOLVERR_INVALID_TARGETVALUE:
+ ERRORBOX( errMsgInvalidVal );
+ aEdTargetVal.GrabFocus();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScSolverDlg::IsRefInputMode() const
+{
+ return pEdActive != NULL;
+}
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScSolverDlg::CheckTargetValue( String& rStrVal )
+{
+ sal_uInt32 n1 = 0;
+ double n2;
+
+ return pDoc->GetFormatTable()->IsNumberFormat( rStrVal, n1, n2 );
+}
+
+//----------------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScSolverDlg, BtnHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &aBtnOk )
+ {
+ theTargetValStr = aEdTargetVal.GetText();
+
+ // Zu ueberpruefen:
+ // 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen?
+ // 2. verweist die Formel-Koordinate wirklich auf eine Formelzelle?
+ // 3. wurde ein korrekter Zielwert eingegeben
+
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ USHORT nRes1 = theFormulaCell .Parse( aEdFormulaCell.GetText(), pDoc, eConv );
+ USHORT nRes2 = theVariableCell.Parse( aEdVariableCell.GetText(), pDoc, eConv );
+
+ if ( SCA_VALID == ( nRes1 & SCA_VALID ) )
+ {
+ if ( SCA_VALID == ( nRes2 & SCA_VALID ) )
+ {
+ if ( CheckTargetValue( theTargetValStr ) )
+ {
+ CellType eType;
+ pDoc->GetCellType( theFormulaCell.Col(),
+ theFormulaCell.Row(),
+ theFormulaCell.Tab(),
+ eType );
+
+ if ( CELLTYPE_FORMULA == eType )
+ {
+ ScSolveParam aOutParam( theFormulaCell,
+ theVariableCell,
+ theTargetValStr );
+ ScSolveItem aOutItem( SCITEM_SOLVEDATA, &aOutParam );
+
+ SetDispatcherLock( FALSE );
+
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( SID_SOLVE,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aOutItem, 0L, 0L );
+ Close();
+ }
+ else RaiseError( SOLVERR_NOFORMULA );
+ }
+ else RaiseError( SOLVERR_INVALID_TARGETVALUE );
+ }
+ else RaiseError( SOLVERR_INVALID_VARIABLE );
+ }
+ else RaiseError( SOLVERR_INVALID_FORMULA );
+ }
+ else if ( pBtn == &aBtnCancel )
+ {
+ Close();
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScSolverDlg, GetFocusHdl, Control*, pCtrl )
+{
+ Edit* pEdit = NULL;
+ pEdActive = NULL;
+
+ if( (pCtrl == (Control*)&aEdFormulaCell) || (pCtrl == (Control*)&aRBFormulaCell) )
+ pEdit = pEdActive = &aEdFormulaCell;
+ else if( (pCtrl == (Control*)&aEdVariableCell) || (pCtrl == (Control*)&aRBVariableCell) )
+ pEdit = pEdActive = &aEdVariableCell;
+ else if( pCtrl == (Control*)&aEdTargetVal )
+ pEdit = &aEdTargetVal;
+
+ if( pEdit )
+ pEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScSolverDlg, LoseFocusHdl, Control*, EMPTYARG )
+{
+ bDlgLostFocus = !IsActive();
+ return 0;
+}
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/strindlg.cxx b/sc/source/ui/miscdlgs/strindlg.cxx
new file mode 100644
index 000000000000..b8dc2e13538e
--- /dev/null
+++ b/sc/source/ui/miscdlgs/strindlg.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "strindlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+#include <layout/layout-pre.hxx>
+
+#if ENABLE_LAYOUT
+#undef ScResId
+#define ScResId(x) #x
+#undef ModalDialog
+#define ModalDialog( parent, id ) Dialog( parent, "string-input.xml", id )
+#endif /* ENABLE_LAYOUT */
+
+//==================================================================
+
+ScStringInputDlg::ScStringInputDlg( Window* pParent,
+ const String& rTitle,
+ const String& rEditTitle,
+ const String& rDefault,
+ ULONG nHelpId ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_STRINPUT ) ),
+ //
+ aFtEditTitle ( this, ScResId( FT_LABEL ) ),
+ aEdInput ( this, ScResId( ED_INPUT ) ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) )
+{
+ SetHelpId( nHelpId );
+ SetText( rTitle );
+ aFtEditTitle.SetText( rEditTitle );
+ aEdInput.SetText( rDefault );
+ aEdInput.SetSelection(Selection(SELECTION_MIN, SELECTION_MAX));
+
+ // HelpId for Edit different for different uses
+
+ if ( nHelpId == FID_TAB_APPEND )
+ aEdInput.SetHelpId( HID_SC_APPEND_NAME );
+ else if ( nHelpId == FID_TAB_RENAME )
+ aEdInput.SetHelpId( HID_SC_RENAME_NAME );
+ else if ( nHelpId == HID_SC_ADD_AUTOFMT )
+ aEdInput.SetHelpId( HID_SC_AUTOFMT_NAME );
+ else if ( nHelpId == HID_SC_REN_AFMT_DLG )
+ aEdInput.SetHelpId( HID_SC_REN_AFMT_NAME );
+ else if ( nHelpId == SID_RENAME_OBJECT )
+ aEdInput.SetHelpId( HID_SC_RENAME_OBJECT );
+ // #i68101#
+ else if ( nHelpId == SID_TITLE_DESCRIPTION_OBJECT )
+ aEdInput.SetHelpId( HID_SC_TITLE_DESCRIPTION_OBJECT );
+ else
+ DBG_ERRORFILE( "unknown ID" );
+
+ //-------------
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+void ScStringInputDlg::GetInputString( String& rString ) const
+{
+ rString = aEdInput.GetText();
+}
+
+__EXPORT ScStringInputDlg::~ScStringInputDlg()
+{
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/tabbgcolordlg.cxx b/sc/source/ui/miscdlgs/tabbgcolordlg.cxx
new file mode 100644
index 000000000000..463c06d76712
--- /dev/null
+++ b/sc/source/ui/miscdlgs/tabbgcolordlg.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * 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: tabbgcolordlg.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+//------------------------------------------------------------------
+
+#include "tabbgcolordlg.hxx"
+#include "scresid.hxx"
+#include "miscdlgs.hrc"
+
+#include <tools/debug.hxx>
+#include <tools/color.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/resid.hxx>
+#include <editeng/editrids.hrc>
+#include <editeng/eerdll.hxx>
+
+#include <boost/scoped_ptr.hpp>
+
+//==================================================================
+
+#define HDL(hdl) LINK(this,ScTabBgColorDlg,hdl)
+
+ScTabBgColorDlg::ScTabBgColorDlg( Window* pParent,
+ const String& rTitle,
+ const String& rTabBgColorNoColorText,
+ const Color& rDefaultColor,
+ ULONG nHelpId ) :
+ ModalDialog ( pParent, ScResId( RID_SCDLG_TAB_BG_COLOR ) ),
+ aBorderWin ( this, ScResId( TAB_BG_COLOR_CT_BORDER ) ),
+ aTabBgColorSet ( &aBorderWin, ScResId( TAB_BG_COLOR_SET_BGDCOLOR ), this ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aTabBgColor ( rDefaultColor ),
+ aTabBgColorNoColorText ( rTabBgColorNoColorText ),
+ mnHelpId ( nHelpId )
+
+{
+ SetHelpId( nHelpId );
+ this->SetText( rTitle );
+ this->SetStyle(GetStyle() | WB_BORDER | WB_STDFLOATWIN | WB_3DLOOK | WB_DIALOGCONTROL | WB_SYSTEMWINDOW | WB_STANDALONE | WB_HIDE);
+
+ FillColorValueSets_Impl();
+ aTabBgColorSet.SetDoubleClickHdl( HDL(TabBgColorDblClickHdl_Impl) );
+ aBtnOk.SetClickHdl( HDL(TabBgColorOKHdl_Impl) );
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+void ScTabBgColorDlg::GetSelectedColor( Color& rColor ) const
+{
+ rColor = this->aTabBgColor;
+}
+
+ScTabBgColorDlg::~ScTabBgColorDlg()
+{
+}
+
+void ScTabBgColorDlg::FillColorValueSets_Impl()
+{
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ const SfxPoolItem* pItem = NULL;
+ XColorTable* pColorTable = NULL;
+ ::boost::scoped_ptr<XColorTable> pOwnColorTable; // locally instantiated in case the doc shell doesn't have one.
+
+ const Size aSize15x15 = Size( 15, 15 );
+ const Size aSize10x10 = Size( 10, 10 );
+ const Size aSize5x5 = Size( 5, 5 );
+ USHORT nSelectedItem = 0;
+
+ DBG_ASSERT( pDocSh, "DocShell not found!" );
+
+ if ( pDocSh && ( 0 != ( pItem = pDocSh->GetItem(SID_COLOR_TABLE) ) ) )
+ pColorTable = ( (SvxColorTableItem*)pItem )->GetColorTable();
+ if ( !pColorTable )
+ {
+ pOwnColorTable.reset(new XColorTable(SvtPathOptions().GetPalettePath()));
+ pColorTable = pOwnColorTable.get();
+ }
+ if ( pColorTable )
+ {
+ sal_uInt16 i = 0;
+ long nCount = pColorTable->Count();
+ XColorEntry* pEntry = NULL;
+ Color aColWhite( COL_WHITE );
+ String aStrWhite( EditResId( RID_SVXITEMS_COLOR_WHITE ) );
+ WinBits nBits = ( aTabBgColorSet.GetStyle() | WB_NAMEFIELD | WB_ITEMBORDER | WB_NONEFIELD | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_NOPOINTERFOCUS);
+ aTabBgColorSet.SetText( aTabBgColorNoColorText );
+ aTabBgColorSet.SetStyle( nBits );
+ for ( i = 0; i < nCount; i++ )
+ {
+ pEntry = pColorTable->GetColor(i);
+ aTabBgColorSet.InsertItem( i + 1, pEntry->GetColor(), pEntry->GetName() );
+ if (pEntry->GetColor() == aTabBgColor)
+ nSelectedItem = (i + 1);
+ }
+
+ while ( i < 80 )
+ {
+ aTabBgColorSet.InsertItem( i + 1, aColWhite, aStrWhite );
+ i++;
+ }
+
+ if ( nCount > 80 )
+ {
+ aTabBgColorSet.SetStyle( nBits | WB_VSCROLL );
+ }
+ }
+ aTabBgColorSet.SetColCount( 10 );
+ aTabBgColorSet.SetLineCount( 10 );
+ aTabBgColorSet.CalcWindowSizePixel( aSize15x15 );
+ aTabBgColorSet.Format();
+ aTabBgColorSet.SelectItem(nSelectedItem);
+ aTabBgColorSet.Resize();
+}
+
+IMPL_LINK( ScTabBgColorDlg, TabBgColorDblClickHdl_Impl, ValueSet*, EMPTYARG )
+/*
+ Handler, called when color selection is changed
+*/
+{
+ USHORT nItemId = aTabBgColorSet.GetSelectItemId();
+ Color aColor = nItemId ? ( aTabBgColorSet.GetItemColor( nItemId ) ) : Color( COL_AUTO );
+ aTabBgColor = aColor;
+ EndDialog( TRUE );
+ return 0;
+}
+
+IMPL_LINK( ScTabBgColorDlg, TabBgColorOKHdl_Impl, OKButton*, EMPTYARG )
+{
+
+// Handler, called when the OK button is pushed
+
+ USHORT nItemId = aTabBgColorSet.GetSelectItemId();
+ Color aColor = nItemId ? ( aTabBgColorSet.GetItemColor( nItemId ) ) : Color( COL_AUTO );
+ aTabBgColor = aColor;
+ EndDialog( TRUE );
+ return 0;
+}
+
+ScTabBgColorDlg::ScTabBgColorValueSet::ScTabBgColorValueSet( Control* pParent, const ResId& rResId, ScTabBgColorDlg* pTabBgColorDlg ) :
+ ValueSet(pParent, rResId)
+{
+ aTabBgColorDlg = pTabBgColorDlg;
+}
+
+void ScTabBgColorDlg::ScTabBgColorValueSet::KeyInput( const KeyEvent& rKEvt )
+{
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_SPACE:
+ case KEY_RETURN:
+ {
+ USHORT nItemId = GetSelectItemId();
+ const Color& aColor = nItemId ? ( GetItemColor( nItemId ) ) : Color( COL_AUTO );
+ aTabBgColorDlg->aTabBgColor = aColor;
+ aTabBgColorDlg->EndDialog(TRUE);
+ }
+ break;
+ }
+ ValueSet::KeyInput(rKEvt);
+}
diff --git a/sc/source/ui/miscdlgs/tabopdlg.cxx b/sc/source/ui/miscdlgs/tabopdlg.cxx
new file mode 100644
index 000000000000..38ae6bddaebd
--- /dev/null
+++ b/sc/source/ui/miscdlgs/tabopdlg.cxx
@@ -0,0 +1,371 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//----------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/dispatch.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "uiitems.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "reffact.hxx"
+#include "tabopdlg.hrc"
+
+#define _TABOPDLG_CXX
+#include "tabopdlg.hxx"
+
+
+//============================================================================
+// class ScTabOpDlg
+//----------------------------------------------------------------------------
+
+ScTabOpDlg::ScTabOpDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScDocument* pDocument,
+ const ScRefAddress& rCursorPos )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_TABOP ),
+ //
+ aFlVariables ( this, ScResId( FL_VARIABLES ) ),
+ aFtFormulaRange ( this, ScResId( FT_FORMULARANGE ) ),
+ aEdFormulaRange ( this, this, ScResId( ED_FORMULARANGE ) ),
+ aRBFormulaRange ( this, ScResId( RB_FORMULARANGE ), &aEdFormulaRange, this ),
+ aFtRowCell ( this, ScResId( FT_ROWCELL ) ),
+ aEdRowCell ( this, this, ScResId( ED_ROWCELL ) ),
+ aRBRowCell ( this, ScResId( RB_ROWCELL ), &aEdRowCell, this ),
+ aFtColCell ( this, ScResId( FT_COLCELL ) ),
+ aEdColCell ( this, this, ScResId( ED_COLCELL ) ),
+ aRBColCell ( this, ScResId( RB_COLCELL ), &aEdColCell, this ),
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ //
+ theFormulaCell ( rCursorPos ),
+ pDoc ( pDocument ),
+ nCurTab ( theFormulaCell.Tab() ),
+ pEdActive ( NULL ),
+ bDlgLostFocus ( FALSE ),
+ errMsgNoFormula ( ScResId( STR_NOFORMULA ) ),
+ errMsgNoColRow ( ScResId( STR_NOCOLROW ) ),
+ errMsgWrongFormula ( ScResId( STR_WRONGFORMULA ) ),
+ errMsgWrongRowCol ( ScResId( STR_WRONGROWCOL ) ),
+ errMsgNoColFormula ( ScResId( STR_NOCOLFORMULA ) ),
+ errMsgNoRowFormula ( ScResId( STR_NOROWFORMULA ) )
+{
+ Init();
+ FreeResource();
+}
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScTabOpDlg::~ScTabOpDlg()
+{
+ Hide();
+}
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScTabOpDlg::Init()
+{
+ aBtnOk. SetClickHdl ( LINK( this, ScTabOpDlg, BtnHdl ) );
+ aBtnCancel. SetClickHdl ( LINK( this, ScTabOpDlg, BtnHdl ) );
+
+ Link aLink = LINK( this, ScTabOpDlg, GetFocusHdl );
+ aEdFormulaRange.SetGetFocusHdl( aLink );
+ aRBFormulaRange.SetGetFocusHdl( aLink );
+ aEdRowCell. SetGetFocusHdl( aLink );
+ aRBRowCell. SetGetFocusHdl( aLink );
+ aEdColCell. SetGetFocusHdl( aLink );
+ aRBColCell. SetGetFocusHdl( aLink );
+
+ aLink = LINK( this, ScTabOpDlg, LoseFocusHdl );
+ aEdFormulaRange.SetLoseFocusHdl( aLink );
+ aRBFormulaRange.SetLoseFocusHdl( aLink );
+ aEdRowCell. SetLoseFocusHdl( aLink );
+ aRBRowCell. SetLoseFocusHdl( aLink );
+ aEdColCell. SetLoseFocusHdl( aLink );
+ aRBColCell. SetLoseFocusHdl( aLink );
+
+ aEdFormulaRange.GrabFocus();
+ pEdActive = &aEdFormulaRange;
+
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+}
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScTabOpDlg::Close()
+{
+ return DoClose( ScTabOpDlgWrapper::GetChildWindowId() );
+}
+
+//----------------------------------------------------------------------------
+
+void ScTabOpDlg::SetActive()
+{
+ if ( bDlgLostFocus )
+ {
+ bDlgLostFocus = FALSE;
+ if( pEdActive )
+ pEdActive->GrabFocus();
+ }
+ else
+ GrabFocus();
+
+ RefInputDone();
+}
+
+//----------------------------------------------------------------------------
+
+void ScTabOpDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( pEdActive )
+ {
+ ScAddress::Details aDetails(pDocP->GetAddressConvention(), 0, 0);
+
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart(pEdActive);
+
+ String aStr;
+ USHORT nFmt = ( rRef.aStart.Tab() == nCurTab )
+ ? SCR_ABS
+ : SCR_ABS_3D;
+
+ if ( pEdActive == &aEdFormulaRange )
+ {
+ theFormulaCell.Set( rRef.aStart, false, false, false);
+ theFormulaEnd.Set( rRef.aEnd, false, false, false);
+ rRef.Format( aStr, nFmt, pDocP, aDetails );
+ }
+ else if ( pEdActive == &aEdRowCell )
+ {
+ theRowCell.Set( rRef.aStart, false, false, false);
+ rRef.aStart.Format( aStr, nFmt, pDocP, aDetails );
+ }
+ else if ( pEdActive == &aEdColCell )
+ {
+ theColCell.Set( rRef.aStart, false, false, false);
+ rRef.aStart.Format( aStr, nFmt, pDocP, aDetails );
+ }
+
+ pEdActive->SetRefString( aStr );
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScTabOpDlg::RaiseError( ScTabOpErr eError )
+{
+ const String* pMsg = &errMsgNoFormula;
+ Edit* pEd = &aEdFormulaRange;
+
+ switch ( eError )
+ {
+ case TABOPERR_NOFORMULA:
+ pMsg = &errMsgNoFormula;
+ pEd = &aEdFormulaRange;
+ break;
+
+ case TABOPERR_NOCOLROW:
+ pMsg = &errMsgNoColRow;
+ pEd = &aEdRowCell;
+ break;
+
+ case TABOPERR_WRONGFORMULA:
+ pMsg = &errMsgWrongFormula;
+ pEd = &aEdFormulaRange;
+ break;
+
+ case TABOPERR_WRONGROW:
+ pMsg = &errMsgWrongRowCol;
+ pEd = &aEdRowCell;
+ break;
+
+ case TABOPERR_NOCOLFORMULA:
+ pMsg = &errMsgNoColFormula;
+ pEd = &aEdFormulaRange;
+ break;
+
+ case TABOPERR_WRONGCOL:
+ pMsg = &errMsgWrongRowCol;
+ pEd = &aEdColCell;
+ break;
+
+ case TABOPERR_NOROWFORMULA:
+ pMsg = &errMsgNoRowFormula;
+ pEd = &aEdFormulaRange;
+ break;
+ }
+
+ ErrorBox( this, WinBits( WB_OK_CANCEL | WB_DEF_OK), *pMsg ).Execute();
+ pEd->GrabFocus();
+}
+
+//----------------------------------------------------------------------------
+
+BOOL lcl_Parse( const String& rString, ScDocument* pDoc, SCTAB nCurTab,
+ ScRefAddress& rStart, ScRefAddress& rEnd )
+{
+ BOOL bRet = FALSE;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ if ( rString.Search(':') != STRING_NOTFOUND )
+ bRet = ConvertDoubleRef( pDoc, rString, nCurTab, rStart, rEnd, eConv );
+ else
+ {
+ bRet = ConvertSingleRef( pDoc, rString, nCurTab, rStart, eConv );
+ rEnd = rStart;
+ }
+ return bRet;
+}
+
+//----------------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScTabOpDlg, BtnHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &aBtnOk )
+ {
+ BYTE nMode = 3;
+ USHORT nError = 0;
+
+ // Zu ueberpruefen:
+ // 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen?
+ // 2. IstFormelRang Zeile bei leerer Zeile bzw. Spalte bei leerer Spalte
+ // bzw. Einfachreferenz bei beidem?
+ // 3. Ist mindestens Zeile oder Spalte und Formel voll?
+
+ if (aEdFormulaRange.GetText().Len() == 0)
+ nError = TABOPERR_NOFORMULA;
+ else if (aEdRowCell.GetText().Len() == 0 &&
+ aEdColCell.GetText().Len() == 0)
+ nError = TABOPERR_NOCOLROW;
+ else if ( !lcl_Parse( aEdFormulaRange.GetText(), pDoc, nCurTab,
+ theFormulaCell, theFormulaEnd ) )
+ nError = TABOPERR_WRONGFORMULA;
+ else
+ {
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ if (aEdRowCell.GetText().Len() > 0)
+ {
+ if (!ConvertSingleRef( pDoc, aEdRowCell.GetText(), nCurTab,
+ theRowCell, eConv ))
+ nError = TABOPERR_WRONGROW;
+ else
+ {
+ if (aEdColCell.GetText().Len() == 0 &&
+ theFormulaCell.Col() != theFormulaEnd.Col())
+ nError = TABOPERR_NOCOLFORMULA;
+ else
+ nMode = 1;
+ }
+ }
+ if (aEdColCell.GetText().Len() > 0)
+ {
+ if (!ConvertSingleRef( pDoc, aEdColCell.GetText(), nCurTab,
+ theColCell, eConv ))
+ nError = TABOPERR_WRONGCOL;
+ else
+ {
+ if (nMode == 1) // beides
+ {
+ nMode = 2;
+ ConvertSingleRef( pDoc, aEdFormulaRange.GetText(), nCurTab,
+ theFormulaCell, eConv );
+ }
+ else if (theFormulaCell.Row() != theFormulaEnd.Row())
+ nError = TABOPERR_NOROWFORMULA;
+ else
+ nMode = 0;
+ }
+ }
+ }
+
+ if (nError)
+ RaiseError( (ScTabOpErr) nError );
+ else
+ {
+ ScTabOpParam aOutParam( theFormulaCell,
+ theFormulaEnd,
+ theRowCell,
+ theColCell,
+ nMode );
+ ScTabOpItem aOutItem( SID_TABOP, &aOutParam );
+
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( SID_TABOP,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aOutItem, 0L, 0L );
+ Close();
+ }
+ }
+ else if ( pBtn == &aBtnCancel )
+ Close();
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScTabOpDlg, GetFocusHdl, Control*, pCtrl )
+{
+ if( (pCtrl == (Control*)&aEdFormulaRange) || (pCtrl == (Control*)&aRBFormulaRange) )
+ pEdActive = &aEdFormulaRange;
+ else if( (pCtrl == (Control*)&aEdRowCell) || (pCtrl == (Control*)&aRBRowCell) )
+ pEdActive = &aEdRowCell;
+ else if( (pCtrl == (Control*)&aEdColCell) || (pCtrl == (Control*)&aRBColCell) )
+ pEdActive = &aEdColCell;
+ else
+ pEdActive = NULL;
+
+ if( pEdActive )
+ pEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScTabOpDlg, LoseFocusHdl, Control*, EMPTYARG )
+{
+ bDlgLostFocus = !IsActive();
+ return 0;
+}
+
+
+
+
+
diff --git a/sc/source/ui/miscdlgs/textdlgs.cxx b/sc/source/ui/miscdlgs/textdlgs.cxx
new file mode 100644
index 000000000000..9f8b2474fc3e
--- /dev/null
+++ b/sc/source/ui/miscdlgs/textdlgs.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+// ohne precompiled Headers uebersetzen !!!
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svxids.hrc>
+
+//CHINA001 #include <svx/chardlg.hxx>
+#include <editeng/flstitem.hxx>
+//CHINA001 #include <svx/paragrph.hxx>
+//CHINA001 #include <svx/tabstpge.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/cjkoptions.hxx>
+
+#include "textdlgs.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include <svx/svxids.hrc> //add CHINA001
+#include <svl/intitem.hxx> //add CHINA001
+#include <svx/flagsdef.hxx> //CHINA001
+// -----------------------------------------------------------------------
+
+ScCharDlg::ScCharDlg( Window* pParent, const SfxItemSet* pAttr,
+ const SfxObjectShell* pDocShell ) :
+ SfxTabDialog ( pParent, ScResId( RID_SCDLG_CHAR ), pAttr ),
+ rOutAttrs ( *pAttr ),
+ rDocShell ( *pDocShell )
+{
+ FreeResource();
+
+ AddTabPage( RID_SVXPAGE_CHAR_NAME ); //CHINA001 AddTabPage( RID_SVXPAGE_CHAR_NAME, SvxCharNamePage::Create, 0);
+ AddTabPage( RID_SVXPAGE_CHAR_EFFECTS ); //CHINA001 AddTabPage( RID_SVXPAGE_CHAR_EFFECTS, SvxCharEffectsPage::Create, 0);
+ AddTabPage( RID_SVXPAGE_CHAR_POSITION ); //CHINA001 AddTabPage( RID_SVXPAGE_CHAR_POSITION, SvxCharPositionPage::Create, 0);
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScCharDlg::PageCreated( USHORT nId, SfxTabPage &rPage )
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); //CHINA001
+ switch( nId )
+ {
+ case RID_SVXPAGE_CHAR_NAME:
+ {
+ SvxFontListItem aItem(*( (const SvxFontListItem*)
+ ( rDocShell.GetItem( SID_ATTR_CHAR_FONTLIST) ) ) );
+
+ //CHINA001 ( (SvxCharNamePage&) rPage ).SetFontList( aItem );
+ aSet.Put (SvxFontListItem( aItem.GetFontList(), SID_ATTR_CHAR_FONTLIST));
+ rPage.PageCreated(aSet);
+ }
+ break;
+
+ case RID_SVXPAGE_CHAR_EFFECTS:
+ //CHINA001 ( (SvxCharEffectsPage&) rPage ).DisableControls(
+ //CHINA001 DISABLE_CASEMAP);
+ aSet.Put (SfxUInt16Item(SID_DISABLE_CTL,DISABLE_CASEMAP)); //CHINA001
+ rPage.PageCreated(aSet);
+ break;
+
+ default:
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScParagraphDlg::ScParagraphDlg( Window* pParent, const SfxItemSet* pAttr ) :
+ SfxTabDialog ( pParent, ScResId( RID_SCDLG_PARAGRAPH ), pAttr ),
+ rOutAttrs ( *pAttr )
+{
+ FreeResource();
+
+ SvtCJKOptions aCJKOptions;
+
+ AddTabPage( RID_SVXPAGE_STD_PARAGRAPH );//CHINA001 AddTabPage( RID_SVXPAGE_STD_PARAGRAPH, SvxStdParagraphTabPage::Create, 0);
+ AddTabPage( RID_SVXPAGE_ALIGN_PARAGRAPH );//CHINA001 AddTabPage( RID_SVXPAGE_ALIGN_PARAGRAPH, SvxParaAlignTabPage::Create, 0);
+ //AddTabPage( RID_SVXPAGE_EXT_PARAGRAPH, SvxExtParagraphTabPage::Create, 0);
+ if ( aCJKOptions.IsAsianTypographyEnabled() )
+ AddTabPage( RID_SVXPAGE_PARA_ASIAN);//CHINA001 AddTabPage( RID_SVXPAGE_PARA_ASIAN, SvxAsianTabPage::Create,0);
+ else
+ RemoveTabPage( RID_SVXPAGE_PARA_ASIAN );
+ AddTabPage( RID_SVXPAGE_TABULATOR );//CHINA001 AddTabPage( RID_SVXPAGE_TABULATOR, SvxTabulatorTabPage::Create, 0);
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScParagraphDlg::PageCreated( USHORT nId, SfxTabPage &rPage )
+{
+ switch( nId )
+ {
+ case RID_SVXPAGE_TABULATOR:
+ {
+ //CHINA001 ( (SvxTabulatorTabPage&) rPage ).
+ //CHINA001 DisableControls( TABTYPE_ALL &~TABTYPE_LEFT |
+ //CHINA001 TABFILL_ALL &~TABFILL_NONE );
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));//add CHINA001
+ aSet.Put(SfxUInt16Item(SID_SVXTABULATORTABPAGE_CONTROLFLAGS,(TABTYPE_ALL &~TABTYPE_LEFT) |
+ (TABFILL_ALL &~TABFILL_NONE) ));
+ rPage.PageCreated(aSet);//add CHINA001
+ }
+ break;
+ }
+}
+
+
+
diff --git a/sc/source/ui/miscdlgs/warnbox.cxx b/sc/source/ui/miscdlgs/warnbox.cxx
new file mode 100644
index 000000000000..24b2e62a1c78
--- /dev/null
+++ b/sc/source/ui/miscdlgs/warnbox.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "warnbox.hxx"
+
+#include "scmod.hxx"
+#include "inputopt.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+
+
+// ============================================================================
+
+ScCbWarningBox::ScCbWarningBox( Window* pParent, const String& rMsgStr, bool bDefYes ) :
+ WarningBox( pParent, WB_YES_NO | (bDefYes ? WB_DEF_YES : WB_DEF_NO), rMsgStr )
+{
+ SetDefaultCheckBoxText();
+}
+
+sal_Int16 ScCbWarningBox::Execute()
+{
+ sal_Int16 nRet = (GetStyle() & WB_DEF_YES) ? RET_YES : RET_NO;
+ if( IsDialogEnabled() )
+ {
+ nRet = WarningBox::Execute();
+ if( GetCheckBoxState() )
+ DisableDialog();
+ }
+ return nRet;
+}
+
+bool ScCbWarningBox::IsDialogEnabled()
+{
+ return true;
+}
+
+void ScCbWarningBox::DisableDialog()
+{
+}
+
+
+// ----------------------------------------------------------------------------
+
+ScReplaceWarnBox::ScReplaceWarnBox( Window* pParent ) :
+ ScCbWarningBox( pParent, String( ScResId( STR_REPLCELLSWARN ) ), true )
+{
+ SetHelpId( HID_SC_REPLCELLSWARN );
+}
+
+bool ScReplaceWarnBox::IsDialogEnabled()
+{
+ return SC_MOD()->GetInputOptions().GetReplaceCellsWarn() == TRUE;
+}
+
+void ScReplaceWarnBox::DisableDialog()
+{
+ ScModule* pScMod = SC_MOD();
+ ScInputOptions aInputOpt( pScMod->GetInputOptions() );
+ aInputOpt.SetReplaceCellsWarn( FALSE );
+ pScMod->SetInputOptions( aInputOpt );
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/namedlg/makefile.mk b/sc/source/ui/namedlg/makefile.mk
new file mode 100644
index 000000000000..7c1151b8340b
--- /dev/null
+++ b/sc/source/ui/namedlg/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=namedlg
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ namedlg.cxx
+
+SLOFILES = \
+ $(SLO)$/namedlg.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/namedlg/namedlg.cxx b/sc/source/ui/namedlg/namedlg.cxx
new file mode 100644
index 000000000000..bc79fa7c65e7
--- /dev/null
+++ b/sc/source/ui/namedlg/namedlg.cxx
@@ -0,0 +1,649 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes ---------------------------------------------------------
+
+
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "global.hxx"
+#include "reffact.hxx"
+#include "document.hxx"
+#include "docfunc.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "namedlg.hrc"
+
+#define _NAMEDLG_CXX
+#include "namedlg.hxx"
+#undef _NAMEDLG_CXX
+#include <vcl/msgbox.hxx>
+
+
+
+// defines -------------------------------------------------------------------
+
+#define ABS_SREF SCA_VALID \
+ | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
+#define ABS_DREF ABS_SREF \
+ | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
+#define ABS_SREF3D ABS_SREF | SCA_TAB_3D
+#define ABS_DREF3D ABS_DREF | SCA_TAB_3D
+
+
+//============================================================================
+// Hilfsklasse: Merken der aktuellen Bereichsoptionen,
+// wenn ein Name in der ComboBox gefunden wird.
+
+struct SaveData
+{
+ SaveData()
+ : bCriteria(FALSE),bPrintArea(FALSE),
+ bColHeader(FALSE),bRowHeader(FALSE),
+ bDirty(FALSE) {}
+
+ void Clear()
+ {
+ aStrSymbol.Erase();
+ bCriteria = bPrintArea =
+ bColHeader = bRowHeader = FALSE;
+ bDirty = TRUE;
+ }
+
+ String aStrSymbol;
+ BOOL bCriteria:1;
+ BOOL bPrintArea:1;
+ BOOL bColHeader:1;
+ BOOL bRowHeader:1;
+ BOOL bDirty:1;
+};
+
+static SaveData* pSaveObj = NULL;
+
+#define SAVE_DATA() \
+ pSaveObj->aStrSymbol = aEdAssign.GetText(); \
+ pSaveObj->bCriteria = aBtnCriteria.IsChecked(); \
+ pSaveObj->bPrintArea = aBtnPrintArea.IsChecked(); \
+ pSaveObj->bColHeader = aBtnColHeader.IsChecked(); \
+ pSaveObj->bRowHeader = aBtnRowHeader.IsChecked(); \
+ pSaveObj->bDirty = TRUE;
+
+#define RESTORE_DATA() \
+ if ( pSaveObj->bDirty ) \
+ { \
+ aEdAssign.SetText( pSaveObj->aStrSymbol ); \
+ aBtnCriteria.Check( pSaveObj->bCriteria ); \
+ aBtnPrintArea.Check( pSaveObj->bPrintArea ); \
+ aBtnColHeader.Check( pSaveObj->bColHeader ); \
+ aBtnRowHeader.Check( pSaveObj->bRowHeader ); \
+ pSaveObj->bDirty = FALSE; \
+ }
+
+#define ERRORBOX(s) ErrorBox(this,WinBits(WB_OK|WB_DEF_OK),s).Execute();
+
+
+//============================================================================
+// class ScNameDlg
+
+//----------------------------------------------------------------------------
+
+ScNameDlg::ScNameDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
+ ScViewData* ptrViewData,
+ const ScAddress& aCursorPos )
+
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_NAMES ),
+ //
+ aFlName ( this, ScResId( FL_NAME ) ),
+ aEdName ( this, ScResId( ED_NAME ) ),
+ //
+ aFlAssign ( this, ScResId( FL_ASSIGN ) ),
+ aEdAssign ( this, this, ScResId( ED_ASSIGN ) ),
+ aRbAssign ( this, ScResId( RB_ASSIGN ), &aEdAssign, this ),
+ //
+ aFlType ( this, ScResId( FL_TYPE ) ),
+ aBtnPrintArea ( this, ScResId( BTN_PRINTAREA ) ),
+ aBtnColHeader ( this, ScResId( BTN_COLHEADER ) ),
+ aBtnCriteria ( this, ScResId( BTN_CRITERIA ) ),
+ aBtnRowHeader ( this, ScResId( BTN_ROWHEADER ) ),
+ //
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ aBtnAdd ( this, ScResId( BTN_ADD ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+ aBtnMore ( this, ScResId( BTN_MORE ) ),
+ //
+ bSaved (FALSE),
+ aStrAdd ( ScResId( STR_ADD ) ),
+ aStrModify ( ScResId( STR_MODIFY ) ),
+ errMsgInvalidSym( ScResId( STR_INVALIDSYMBOL ) ),
+ //
+ pViewData ( ptrViewData ),
+ pDoc ( ptrViewData->GetDocument() ),
+ aLocalRangeName ( *(pDoc->GetRangeName()) ),
+ theCursorPos ( aCursorPos ) // zum Berechnen der Referenzen
+{
+ pSaveObj = new SaveData;
+ Init();
+ FreeResource();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScNameDlg::~ScNameDlg()
+{
+ DELETEZ( pSaveObj );
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScNameDlg::Init()
+{
+ String aAreaStr;
+ ScRange aRange;
+
+ DBG_ASSERT( pViewData && pDoc, "ViewData oder Document nicht gefunden!" );
+
+ aBtnOk.SetClickHdl ( LINK( this, ScNameDlg, OkBtnHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScNameDlg, CancelBtnHdl ) );
+ aBtnAdd.SetClickHdl ( LINK( this, ScNameDlg, AddBtnHdl ) );
+ aBtnRemove.SetClickHdl ( LINK( this, ScNameDlg, RemoveBtnHdl ) );
+ aEdAssign.SetGetFocusHdl( LINK( this, ScNameDlg, AssignGetFocusHdl ) );
+ aEdAssign.SetModifyHdl ( LINK( this, ScNameDlg, EdModifyHdl ) );
+ aEdName.SetModifyHdl ( LINK( this, ScNameDlg, EdModifyHdl ) );
+ aEdName.SetSelectHdl ( LINK( this, ScNameDlg, NameSelectHdl ) );
+
+ aBtnCriteria .Hide();
+ aBtnPrintArea.Hide();
+ aBtnColHeader.Hide();
+ aBtnRowHeader.Hide();
+
+ aBtnMore.AddWindow( &aFlType );
+ aBtnMore.AddWindow( &aBtnCriteria );
+ aBtnMore.AddWindow( &aBtnPrintArea );
+ aBtnMore.AddWindow( &aBtnColHeader );
+ aBtnMore.AddWindow( &aBtnRowHeader );
+
+ UpdateNames();
+
+ pViewData->GetSimpleArea( aRange );
+ aRange.Format( aAreaStr, ABS_DREF3D, pDoc,
+ ScAddress::Details(pDoc->GetAddressConvention(), 0, 0) );
+
+ theCurSel = Selection( 0, SELECTION_MAX );
+ aEdAssign.GrabFocus();
+ aEdAssign.SetText( aAreaStr );
+ aEdAssign.SetSelection( theCurSel );
+ aEdName.GrabFocus();
+
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ if ( aEdName.GetEntryCount() > 0 )
+ aBtnAdd.SetText( aStrAdd );
+ UpdateChecks();
+ EdModifyHdl( 0 );
+
+ bSaved=TRUE;
+ SAVE_DATA()
+
+ //@BugID 54702
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+}
+
+//----------------------------------------------------------------------------
+BOOL ScNameDlg::IsRefInputMode() const
+{
+ return aEdAssign.IsEnabled();
+}
+
+void ScNameDlg::RefInputDone( BOOL bForced)
+{
+ ScAnyRefDlg::RefInputDone(bForced);
+ EdModifyHdl(&aEdAssign);
+}
+//----------------------------------------------------------------------------
+// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
+// neue Selektion im Referenz-Edit angezeigt wird.
+
+
+void ScNameDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+{
+ if ( aEdAssign.IsEnabled() )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart(&aEdAssign);
+ String aRefStr;
+ rRef.Format( aRefStr, ABS_DREF3D, pDocP,
+ ScAddress::Details(pDocP->GetAddressConvention(), 0, 0) );
+ aEdAssign.SetRefString( aRefStr );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+BOOL __EXPORT ScNameDlg::Close()
+{
+ return DoClose( ScNameDlgWrapper::GetChildWindowId() );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScNameDlg::SetActive()
+{
+ aEdAssign.GrabFocus();
+ RefInputDone();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScNameDlg::UpdateChecks()
+{
+ USHORT nCurPos=0;
+
+ if(aLocalRangeName.SearchName( aEdName.GetText(), nCurPos))
+ {
+ ScRangeData* pData=(ScRangeData*)(aLocalRangeName.At( nCurPos ));
+ aBtnCriteria .Check( pData->HasType( RT_CRITERIA ) );
+ aBtnPrintArea.Check( pData->HasType( RT_PRINTAREA ) );
+ aBtnColHeader.Check( pData->HasType( RT_COLHEADER ) );
+ aBtnRowHeader.Check( pData->HasType( RT_ROWHEADER ) );
+ }
+
+ // Falls Edit-Feld leer ist: Typ-CheckBoxen deaktivieren:
+
+ if ( aEdName.GetText().Len() != 0 )
+ {
+ if ( !aFlType.IsEnabled() )
+ {
+ aFlType .Enable();
+ aBtnCriteria .Enable();
+ aBtnPrintArea.Enable();
+ aBtnColHeader.Enable();
+ aBtnRowHeader.Enable();
+ aFlAssign .Enable();
+ aEdAssign .Enable();
+ aRbAssign .Enable();
+ }
+ }
+ else if ( aFlType.IsEnabled() )
+ {
+ aFlType .Disable();
+ aBtnCriteria .Disable();
+ aBtnPrintArea.Disable();
+ aBtnColHeader.Disable();
+ aBtnRowHeader.Disable();
+ aFlAssign .Disable();
+ aEdAssign .Disable();
+ aRbAssign .Disable();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScNameDlg::UpdateNames()
+{
+ USHORT nRangeCount = aLocalRangeName.GetCount();
+
+ aEdName.SetUpdateMode( FALSE );
+ //-----------------------------------------------------------
+ USHORT nNamePos = aEdName.GetTopEntry();
+ aEdName.Clear();
+
+ aEdAssign.SetText( EMPTY_STRING );
+
+ if ( nRangeCount > 0 )
+ {
+ ScRangeData* pRangeData = NULL;
+ String aString;
+
+ for ( USHORT i=0; i<nRangeCount; i++ )
+ {
+ pRangeData = (ScRangeData*)(aLocalRangeName.At( i ));
+ if ( pRangeData )
+ {
+ if ( !pRangeData->HasType( RT_DATABASE )
+ && !pRangeData->HasType( RT_SHARED ) )
+ {
+ pRangeData->GetName( aString );
+ aEdName.InsertEntry( aString );
+ }
+ }
+ }
+ }
+ else
+ {
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ }
+ //-----------------------------------------------------------
+ aEdName.SetUpdateMode( TRUE );
+ aEdName.SetTopEntry(nNamePos);
+ aEdName.Invalidate();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScNameDlg::CalcCurTableAssign( String& aAssign, USHORT nCurPos )
+{
+ ScRangeData* pRangeData = (ScRangeData*)(aLocalRangeName.At( nCurPos ));
+
+ if ( pRangeData )
+ {
+ rtl::OUStringBuffer sBuffer;
+ pRangeData->UpdateSymbol( sBuffer, theCursorPos );
+ aAssign = sBuffer;
+ }
+ else
+ {
+ aAssign.Erase();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+// ========
+
+IMPL_LINK( ScNameDlg, OkBtnHdl, void *, EMPTYARG )
+{
+ if ( aBtnAdd.IsEnabled() )
+ AddBtnHdl( 0 );
+
+ if ( !aBtnAdd.IsEnabled() && !aBtnRemove.IsEnabled() )
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.ModifyRangeNames( aLocalRangeName, FALSE );
+ Close();
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScNameDlg, CancelBtnHdl, void *, EMPTYARG )
+{
+ Close();
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScNameDlg, CancelBtnHdl, void *, EMPTYARG )
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScNameDlg, AddBtnHdl, void *, EMPTYARG )
+{
+ BOOL bAdded = FALSE;
+ String aNewEntry = aEdName.GetText();
+ USHORT nNamePos = aEdName.GetTopEntry();
+ aNewEntry.EraseLeadingChars( ' ' );
+ aNewEntry.EraseTrailingChars( ' ' );
+
+ if ( aNewEntry.Len() > 0 )
+ {
+ if ( ScRangeData::IsNameValid( aNewEntry, pDoc ) )
+ {
+ if ( pDoc )
+ {
+ ScRangeData* pNewEntry = NULL;
+ RangeType nType = RT_NAME;
+ USHORT nFoundAt = 0;
+ String theSymbol = aEdAssign.GetText();
+ String aStrPos;
+ String aStrArea;
+
+ pNewEntry = new ScRangeData( pDoc,
+ aNewEntry,
+ theSymbol,
+ theCursorPos,
+ nType );
+ if (pNewEntry)
+ {
+ nType = nType
+ | (aBtnRowHeader .IsChecked() ? RT_ROWHEADER : RangeType(0))
+ | (aBtnColHeader .IsChecked() ? RT_COLHEADER : RangeType(0))
+ | (aBtnPrintArea .IsChecked() ? RT_PRINTAREA : RangeType(0))
+ | (aBtnCriteria .IsChecked() ? RT_CRITERIA : RangeType(0));
+ pNewEntry->AddType(nType);
+ }
+
+ // theSymbol gueltig?
+ // (= konnte theSymbol im ScRangeData-Ctor
+ // in ein Token-Array uebersetzt werden?)
+ if ( 0 == pNewEntry->GetErrCode() )
+ {
+ // Eintrag bereits vorhanden? Dann vorher entfernen (=Aendern)
+ if ( aLocalRangeName.SearchName( aNewEntry, nFoundAt ) )
+ { // alten Index uebernehmen
+ pNewEntry->SetIndex(
+ ((ScRangeData*)(aLocalRangeName.At(nFoundAt)))->GetIndex() );
+ aLocalRangeName.AtFree( nFoundAt );
+ }
+ else
+ pSaveObj->Clear();
+
+ if ( !aLocalRangeName.Insert( pNewEntry ) )
+ delete pNewEntry;
+
+ UpdateNames();
+ bSaved=FALSE;
+ RESTORE_DATA()
+ aEdName.SetText(EMPTY_STRING);
+ aEdName.GrabFocus();
+ UpdateChecks();
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+
+ //@BugID 54702 raus mit dem Sch.
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+
+ bAdded = TRUE;
+ }
+ else // theSymbol ungueltig
+ {
+ delete pNewEntry;
+ ERRORBOX( errMsgInvalidSym );
+ theCurSel = Selection( 0, SELECTION_MAX );
+ aEdAssign.GrabFocus();
+ }
+ }
+ }
+ else
+ {
+ ERRORBOX( ScGlobal::GetRscString(STR_INVALIDNAME) );
+ aEdName.SetSelection( Selection( 0, SELECTION_MAX ) );
+ aEdName.GrabFocus();
+ }
+ }
+
+ aEdName.SetTopEntry(nNamePos);
+ return bAdded;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScNameDlg, RemoveBtnHdl, void *, EMPTYARG )
+{
+ USHORT nRemoveAt = 0;
+ const String aStrEntry = aEdName.GetText();
+
+ if ( aLocalRangeName.SearchName( aStrEntry, nRemoveAt ) )
+ {
+ String aStrDelMsg = ScGlobal::GetRscString( STR_QUERY_DELENTRY );
+ String aMsg = aStrDelMsg.GetToken( 0, '#' );
+
+ aMsg += aStrEntry;
+ aMsg += aStrDelMsg.GetToken( 1, '#' );
+
+ if ( RET_YES ==
+ QueryBox( this, WinBits( WB_YES_NO | WB_DEF_YES ), aMsg ).Execute() )
+ {
+ aLocalRangeName.AtFree( nRemoveAt );
+ UpdateNames();
+ UpdateChecks();
+ bSaved=FALSE;
+ RESTORE_DATA()
+ theCurSel = Selection( 0, SELECTION_MAX );
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ }
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScNameDlg, NameSelectHdl, void *, EMPTYARG )
+{
+ USHORT nAtPos;
+
+ if ( aLocalRangeName.SearchName( aEdName.GetText(), nAtPos ) )
+ {
+ String aSymbol;
+ ScRangeData* pData = (ScRangeData*)(aLocalRangeName.At( nAtPos ));
+
+ if ( pData )
+ {
+ pData->GetSymbol( aSymbol );
+ CalcCurTableAssign( aSymbol, nAtPos );
+ aEdAssign.SetText( aSymbol );
+ aBtnAdd.SetText( aStrModify );
+ theCurSel = Selection( 0, SELECTION_MAX );
+ }
+ }
+ UpdateChecks();
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScNameDlg, EdModifyHdl, Edit *, pEd )
+{
+ String theName = aEdName.GetText();
+ String theSymbol = aEdAssign.GetText();
+ BOOL bNameFound = (COMBOBOX_ENTRY_NOTFOUND
+ != aEdName.GetEntryPos( theName ));
+
+ if ( pEd == &aEdName )
+ {
+ if ( theName.Len() == 0 )
+ {
+ if ( aBtnAdd.GetText() != aStrAdd )
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ aFlAssign.Disable();
+ aEdAssign.Disable();
+ aRbAssign.Disable();
+ //@BugID 54702 raus mit dem Sch.
+ //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
+ }
+ else
+ {
+ if ( bNameFound )
+ {
+ if ( aBtnAdd.GetText() != aStrModify )
+ aBtnAdd.SetText( aStrModify );
+
+ aBtnRemove.Enable();
+
+ if(!bSaved)
+ {
+ bSaved=TRUE;
+ SAVE_DATA()
+ }
+ NameSelectHdl( 0 );
+ }
+ else
+ {
+ if ( aBtnAdd.GetText() != aStrAdd )
+ aBtnAdd.SetText( aStrAdd );
+ aBtnRemove.Disable();
+
+ bSaved=FALSE;
+ RESTORE_DATA()
+ }
+ theSymbol = aEdAssign.GetText();
+
+ if ( theSymbol.Len() > 0 )
+ aBtnAdd.Enable();
+ else
+ aBtnAdd.Disable();
+
+ aFlAssign.Enable();
+ aEdAssign.Enable();
+ aRbAssign.Enable();
+ //@BugID 54702 raus mit dem Sch.
+ //SFX_APPWINDOW->Enable();
+ }
+ UpdateChecks();
+ theCurSel = Selection( 0, SELECTION_MAX );
+ }
+ else if ( pEd == &aEdAssign )
+ {
+ if ( (theName.Len()>0) && (theSymbol.Len()>0) )
+ {
+ aBtnAdd.Enable();
+ if ( bNameFound )
+ aBtnRemove.Enable();
+ }
+ else
+ {
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ }
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( ScNameDlg, AssignGetFocusHdl, void *, EMPTYARG )
+{
+ EdModifyHdl( &aEdAssign );
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScNameDlg, AssignGetFocusHdl, void *, EMPTYARG )
+
+
diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx
new file mode 100644
index 000000000000..a417621bb303
--- /dev/null
+++ b/sc/source/ui/navipi/content.cxx
@@ -0,0 +1,1526 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdxcgv.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/help.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/urlbmk.hxx>
+#include <stdlib.h>
+
+#include "content.hxx"
+#include "navipi.hxx"
+#include "global.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "tablink.hxx" // fuer Loader
+#include "popmenu.hxx"
+#include "drwlayer.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "lnktrans.hxx"
+#include "cell.hxx"
+#include "dociter.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "navipi.hrc"
+#include "arealink.hxx"
+#include "navicfg.hxx"
+#include "navsett.hxx"
+#include "postit.hxx"
+#include "clipparam.hxx"
+
+using namespace com::sun::star;
+
+// Reihenfolge der Kategorien im Navigator -------------------------------------
+
+static USHORT pTypeList[SC_CONTENT_COUNT] =
+{
+ SC_CONTENT_ROOT, // ROOT (0) muss vorne stehen
+ SC_CONTENT_TABLE,
+ SC_CONTENT_RANGENAME,
+ SC_CONTENT_DBAREA,
+ SC_CONTENT_AREALINK,
+ SC_CONTENT_GRAPHIC,
+ SC_CONTENT_OLEOBJECT,
+ SC_CONTENT_NOTE,
+ SC_CONTENT_DRAWING
+};
+
+BOOL ScContentTree::bIsInDrag = FALSE;
+
+
+ScDocShell* ScContentTree::GetManualOrCurrent()
+{
+ ScDocShell* pSh = NULL;
+ if ( aManualDoc.Len() )
+ {
+ TypeId aScType = TYPE(ScDocShell);
+ SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( &aScType );
+ while ( pObjSh && !pSh )
+ {
+ if ( pObjSh->GetTitle() == aManualDoc )
+ pSh = PTR_CAST( ScDocShell, pObjSh );
+ pObjSh = SfxObjectShell::GetNext( *pObjSh, &aScType );
+ }
+ }
+ else
+ {
+ // Current nur, wenn keine manuell eingestellt ist
+ // (damit erkannt wird, wenn das Dokument nicht mehr existiert)
+
+ SfxViewShell* pViewSh = SfxViewShell::Current();
+ if ( pViewSh )
+ {
+ SfxObjectShell* pObjSh = pViewSh->GetViewFrame()->GetObjectShell();
+ pSh = PTR_CAST( ScDocShell, pObjSh );
+ }
+ }
+
+ return pSh;
+}
+
+//
+// ScContentTree
+//
+
+ScContentTree::ScContentTree( Window* pParent, const ResId& rResId ) :
+ SvTreeListBox ( pParent, rResId ),
+ aEntryImages ( ScResId( RID_IMAGELIST_NAVCONT ) ),
+ aHCEntryImages ( ScResId( RID_IMAGELIST_H_NAVCONT ) ),
+ nRootType ( SC_CONTENT_ROOT ),
+ bHiddenDoc ( FALSE ),
+ pHiddenDocument ( NULL )
+{
+ USHORT i;
+ for (i=0; i<SC_CONTENT_COUNT; i++)
+ pPosList[pTypeList[i]] = i; // invers zum suchen
+
+ pParentWindow = (ScNavigatorDlg*)pParent;
+
+ pRootNodes[0] = NULL;
+ for (i=1; i<SC_CONTENT_COUNT; i++)
+ InitRoot(i);
+
+ SetNodeDefaultImages();
+
+ SetDoubleClickHdl( LINK( this, ScContentTree, ContentDoubleClickHdl ) );
+}
+
+ScContentTree::~ScContentTree()
+{
+}
+
+void ScContentTree::InitRoot( USHORT nType )
+{
+ if ( !nType )
+ return;
+
+ if ( nRootType && nRootType != nType ) // ausgeblendet ?
+ {
+ pRootNodes[nType] = NULL;
+ return;
+ }
+
+ const Image& rImage = aEntryImages.GetImage( nType );
+ String aName( ScResId( SCSTR_CONTENT_ROOT + nType ) );
+ // wieder an die richtige Position:
+ USHORT nPos = nRootType ? 0 : pPosList[nType]-1;
+ SvLBoxEntry* pNew = InsertEntry( aName, rImage, rImage, NULL, FALSE, nPos );
+
+ const Image& rHCImage = aHCEntryImages.GetImage( nType );
+ SetExpandedEntryBmp( pNew, rHCImage, BMP_COLOR_HIGHCONTRAST );
+ SetCollapsedEntryBmp( pNew, rHCImage, BMP_COLOR_HIGHCONTRAST );
+
+ pRootNodes[nType] = pNew;
+}
+
+void ScContentTree::ClearAll()
+{
+ Clear();
+ for (USHORT i=1; i<SC_CONTENT_COUNT; i++)
+ InitRoot(i);
+}
+
+void ScContentTree::ClearType(USHORT nType)
+{
+ if (!nType)
+ ClearAll();
+ else
+ {
+ SvLBoxEntry* pParent = pRootNodes[nType];
+ if ( !pParent || GetChildCount(pParent) ) // nicht, wenn ohne Children schon da
+ {
+ if (pParent)
+ GetModel()->Remove( pParent ); // mit allen Children
+ InitRoot( nType ); // ggf. neu eintragen
+ }
+ }
+}
+
+void ScContentTree::InsertContent( USHORT nType, const String& rValue )
+{
+ if (nType >= SC_CONTENT_COUNT)
+ {
+ DBG_ERROR("ScContentTree::InsertContent mit falschem Typ");
+ return;
+ }
+
+ SvLBoxEntry* pParent = pRootNodes[nType];
+ if (pParent)
+ InsertEntry( rValue, pParent );
+ else
+ {
+ DBG_ERROR("InsertContent ohne Parent");
+ }
+}
+
+void ScContentTree::GetEntryIndexes( USHORT& rnRootIndex, ULONG& rnChildIndex, SvLBoxEntry* pEntry ) const
+{
+ rnRootIndex = SC_CONTENT_ROOT;
+ rnChildIndex = SC_CONTENT_NOCHILD;
+
+ if( !pEntry )
+ return;
+
+ SvLBoxEntry* pParent = GetParent( pEntry );
+ bool bFound = false;
+ for( USHORT nRoot = 1; !bFound && (nRoot < SC_CONTENT_COUNT); ++nRoot )
+ {
+ if( pEntry == pRootNodes[ nRoot ] )
+ {
+ rnRootIndex = nRoot;
+ rnChildIndex = ~0UL;
+ bFound = true;
+ }
+ else if( pParent && (pParent == pRootNodes[ nRoot ]) )
+ {
+ rnRootIndex = nRoot;
+
+ // search the entry in all child entries of the parent
+ ULONG nEntry = 0;
+ SvLBoxEntry* pIterEntry = FirstChild( pParent );
+ while( !bFound && pIterEntry )
+ {
+ if ( pEntry == pIterEntry )
+ {
+ rnChildIndex = nEntry;
+ bFound = true; // exit the while loop
+ }
+ pIterEntry = NextSibling( pIterEntry );
+ ++nEntry;
+ }
+
+ bFound = true; // exit the for loop
+ }
+ }
+}
+
+ULONG ScContentTree::GetChildIndex( SvLBoxEntry* pEntry ) const
+{
+ USHORT nRoot;
+ ULONG nChild;
+ GetEntryIndexes( nRoot, nChild, pEntry );
+ return nChild;
+}
+
+String lcl_GetDBAreaRange( ScDocument* pDoc, const String& rDBName )
+{
+ String aRet;
+ if (pDoc)
+ {
+ ScDBCollection* pDbNames = pDoc->GetDBCollection();
+ USHORT nCount = pDbNames->GetCount();
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ ScDBData* pData = (*pDbNames)[i];
+ if ( pData->GetName() == rDBName )
+ {
+ ScRange aRange;
+ pData->GetArea(aRange);
+ aRange.Format( aRet, SCR_ABS_3D, pDoc );
+ break;
+ }
+ }
+ }
+ return aRet;
+}
+
+IMPL_LINK( ScContentTree, ContentDoubleClickHdl, ScContentTree *, EMPTYARG )
+{
+ USHORT nType;
+ ULONG nChild;
+ SvLBoxEntry* pEntry = GetCurEntry();
+ GetEntryIndexes( nType, nChild, pEntry );
+
+ if( pEntry && (nType != SC_CONTENT_ROOT) && (nChild != SC_CONTENT_NOCHILD) )
+ {
+ if ( bHiddenDoc )
+ return 0; //! spaeter...
+
+ String aText( GetEntryText( pEntry ) );
+
+ if ( aManualDoc.Len() )
+ pParentWindow->SetCurrentDoc( aManualDoc );
+
+ switch( nType )
+ {
+ case SC_CONTENT_TABLE:
+ pParentWindow->SetCurrentTableStr( aText );
+ break;
+
+ case SC_CONTENT_RANGENAME:
+ pParentWindow->SetCurrentCellStr( aText );
+ break;
+
+ case SC_CONTENT_DBAREA:
+ {
+ // #47905# Wenn gleiche Bereichs- und DB-Namen existieren, wird
+ // bei SID_CURRENTCELL der Bereichsname genommen.
+ // DB-Bereiche darum direkt ueber die Adresse anspringen.
+
+ String aRangeStr = lcl_GetDBAreaRange( GetSourceDocument(), aText );
+ if (aRangeStr.Len())
+ pParentWindow->SetCurrentCellStr( aRangeStr );
+ }
+ break;
+
+ case SC_CONTENT_OLEOBJECT:
+ case SC_CONTENT_GRAPHIC:
+ case SC_CONTENT_DRAWING:
+ pParentWindow->SetCurrentObject( aText );
+ break;
+
+ case SC_CONTENT_NOTE:
+ {
+ ScAddress aPos = GetNotePos( nChild );
+ pParentWindow->SetCurrentTable( aPos.Tab() );
+ pParentWindow->SetCurrentCell( aPos.Col(), aPos.Row() );
+ }
+ break;
+
+ case SC_CONTENT_AREALINK:
+ {
+ const ScAreaLink* pLink = GetLink( nChild );
+ if( pLink )
+ {
+ ScRange aRange = pLink->GetDestArea();
+ String aRangeStr;
+ ScDocument* pSrcDoc = GetSourceDocument();
+ aRange.Format( aRangeStr, SCR_ABS_3D, pSrcDoc, pSrcDoc->GetAddressConvention() );
+ pParentWindow->SetCurrentCellStr( aRangeStr );
+ }
+ }
+ break;
+ }
+
+ ScNavigatorDlg::ReleaseFocus(); // set focus into document
+ }
+
+ return 0;
+}
+
+void ScContentTree::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ SvTreeListBox::MouseButtonDown( rMEvt );
+ StoreSettings();
+}
+
+void ScContentTree::KeyInput( const KeyEvent& rKEvt )
+{
+ BOOL bUsed = FALSE;
+
+ const KeyCode aCode = rKEvt.GetKeyCode();
+ if (aCode.GetCode() == KEY_RETURN)
+ {
+ switch (aCode.GetModifier())
+ {
+ case KEY_MOD1:
+ ToggleRoot(); // toggle root mode (as in Writer)
+ bUsed = TRUE;
+ break;
+ case 0:
+ {
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if( pEntry )
+ {
+ USHORT nType;
+ ULONG nChild;
+ GetEntryIndexes( nType, nChild, pEntry );
+
+ if( (nType != SC_CONTENT_ROOT) && (nChild == SC_CONTENT_NOCHILD) )
+ {
+ String aText( GetEntryText( pEntry ) );
+ if ( IsExpanded( pEntry ) )
+ Collapse( pEntry );
+ else
+ Expand( pEntry );
+ }
+ else
+ ContentDoubleClickHdl(0); // select content as if double clicked
+ }
+
+ bUsed = TRUE;
+ }
+ break;
+ }
+ }
+ StoreSettings();
+
+ if( !bUsed )
+ SvTreeListBox::KeyInput(rKEvt);
+}
+
+//BOOL __EXPORT ScContentTree::Drop( const DropEvent& rEvt )
+//{
+// return pParentWindow->Drop(rEvt); // Drop auf Navigator
+//}
+
+//BOOL __EXPORT ScContentTree::QueryDrop( DropEvent& rEvt )
+//{
+// return pParentWindow->QueryDrop(rEvt); // Drop auf Navigator
+//}
+
+sal_Int8 ScContentTree::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
+{
+ return DND_ACTION_NONE;
+}
+
+sal_Int8 ScContentTree::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ )
+{
+ return DND_ACTION_NONE;
+}
+
+void ScContentTree::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ )
+{
+ DoDrag();
+}
+
+void ScContentTree::DragFinished( sal_Int8 /* nAction */ )
+{
+}
+
+void __EXPORT ScContentTree::Command( const CommandEvent& rCEvt )
+{
+ BOOL bDone = FALSE;
+
+ switch ( rCEvt.GetCommand() )
+ {
+ case COMMAND_STARTDRAG:
+ // Aus dem ExecuteDrag heraus kann der Navigator geloescht werden
+ // (beim Umschalten auf einen anderen Dokument-Typ), das wuerde aber
+ // den StarView MouseMove-Handler, der Command() aufruft, umbringen.
+ // Deshalb Drag&Drop asynchron:
+
+// DoDrag();
+
+ Application::PostUserEvent( STATIC_LINK( this, ScContentTree, ExecDragHdl ) );
+
+ bDone = TRUE;
+ break;
+
+ case COMMAND_CONTEXTMENU:
+ {
+ // Drag-Drop Modus
+
+ PopupMenu aPop;
+ ScPopupMenu aDropMenu( ScResId( RID_POPUP_DROPMODE ) );
+ aDropMenu.CheckItem( RID_DROPMODE_URL + pParentWindow->GetDropMode() );
+ aPop.InsertItem( 1, pParentWindow->GetStrDragMode() );
+ aPop.SetPopupMenu( 1, &aDropMenu );
+
+ // angezeigtes Dokument
+
+ ScPopupMenu aDocMenu;
+ aDocMenu.SetMenuFlags( aDocMenu.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+ USHORT i=0;
+ USHORT nPos=0;
+ // geladene Dokumente
+ ScDocShell* pCurrentSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
+ SfxObjectShell* pSh = SfxObjectShell::GetFirst();
+ while ( pSh )
+ {
+ if ( pSh->ISA(ScDocShell) )
+ {
+ String aName = pSh->GetTitle();
+ String aEntry = aName;
+ if ( pSh == pCurrentSh )
+ aEntry += pParentWindow->aStrActive;
+ else
+ aEntry += pParentWindow->aStrNotActive;
+ aDocMenu.InsertItem( ++i, aEntry );
+ if ( !bHiddenDoc && aName == aManualDoc )
+ nPos = i;
+ }
+ pSh = SfxObjectShell::GetNext( *pSh );
+ }
+ // "aktives Fenster"
+ aDocMenu.InsertItem( ++i, pParentWindow->aStrActiveWin );
+ if (!bHiddenDoc && !aManualDoc.Len())
+ nPos = i;
+ // verstecktes Dokument
+ if ( aHiddenTitle.Len() )
+ {
+ String aEntry = aHiddenTitle;
+ aEntry += pParentWindow->aStrHidden;
+ aDocMenu.InsertItem( ++i, aEntry );
+ if (bHiddenDoc)
+ nPos = i;
+ }
+ aDocMenu.CheckItem( nPos );
+ aPop.InsertItem( 2, pParentWindow->GetStrDisplay() );
+ aPop.SetPopupMenu( 2, &aDocMenu );
+
+ // ausfuehren
+
+ aPop.Execute( this, rCEvt.GetMousePosPixel() );
+
+ if ( aDropMenu.WasHit() ) // Drag-Drop Modus
+ {
+ USHORT nId = aDropMenu.GetSelected();
+ if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY )
+ pParentWindow->SetDropMode( nId - RID_DROPMODE_URL );
+ }
+ else if ( aDocMenu.WasHit() ) // angezeigtes Dokument
+ {
+ USHORT nId = aDocMenu.GetSelected();
+ String aName = aDocMenu.GetItemText(nId);
+ SelectDoc( aName );
+ }
+ }
+ break;
+ }
+
+ if (!bDone)
+ SvTreeListBox::Command(rCEvt);
+}
+
+void __EXPORT ScContentTree::RequestHelp( const HelpEvent& rHEvt )
+{
+ BOOL bDone = FALSE;
+ if( rHEvt.GetMode() & HELPMODE_QUICK )
+ {
+ Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
+ SvLBoxEntry* pEntry = GetEntry( aPos );
+ if ( pEntry )
+ {
+ BOOL bRet = FALSE;
+ String aHelpText;
+ SvLBoxEntry* pParent = GetParent(pEntry);
+ if ( !pParent ) // Top-Level ?
+ {
+ aHelpText = String::CreateFromInt32( GetChildCount(pEntry) );
+ aHelpText += ' ';
+ aHelpText += GetEntryText(pEntry);
+ bRet = TRUE;
+ }
+ else if ( pParent == pRootNodes[SC_CONTENT_NOTE] )
+ {
+ aHelpText = GetEntryText(pEntry); // Notizen als Help-Text
+ bRet = TRUE;
+ }
+ else if ( pParent == pRootNodes[SC_CONTENT_AREALINK] )
+ {
+ ULONG nIndex = GetChildIndex(pEntry);
+ if( nIndex != SC_CONTENT_NOCHILD )
+ {
+ const ScAreaLink* pLink = GetLink(nIndex);
+ if (pLink)
+ {
+ aHelpText = pLink->GetFile(); // Source-Datei als Help-Text
+ bRet = TRUE;
+ }
+ }
+ }
+
+ if (bRet)
+ {
+ SvLBoxTab* pTab;
+ SvLBoxString* pItem = (SvLBoxString*)(GetItem( pEntry, aPos.X(), &pTab ));
+ if( pItem )
+ {
+ aPos = GetEntryPosition( pEntry );
+ aPos.X() = GetTabPos( pEntry, pTab );
+ aPos = OutputToScreenPixel(aPos);
+ Size aSize( pItem->GetSize( this, pEntry ) );
+
+ Rectangle aItemRect( aPos, aSize );
+ Help::ShowQuickHelp( this, aItemRect, aHelpText );
+ bDone = TRUE;
+ }
+ }
+ }
+ }
+ if (!bDone)
+ Window::RequestHelp( rHEvt );
+}
+
+ScDocument* ScContentTree::GetSourceDocument()
+{
+ if (bHiddenDoc)
+ return pHiddenDocument;
+ else
+ {
+ ScDocShell* pSh = GetManualOrCurrent();
+ if (pSh)
+ return pSh->GetDocument();
+
+ }
+ return NULL;
+}
+
+void ScContentTree::Refresh( USHORT nType )
+{
+ if ( bHiddenDoc && !pHiddenDocument )
+ return; // anderes Dokument angezeigt
+
+ // wenn sich nichts geaendert hat, gleich abbrechen (gegen Geflacker)
+
+ if ( nType == SC_CONTENT_NOTE )
+ if (!NoteStringsChanged())
+ return;
+ if ( nType == SC_CONTENT_GRAPHIC )
+ if (!DrawNamesChanged(SC_CONTENT_GRAPHIC))
+ return;
+ if ( nType == SC_CONTENT_OLEOBJECT )
+ if (!DrawNamesChanged(SC_CONTENT_OLEOBJECT))
+ return;
+ if ( nType == SC_CONTENT_DRAWING )
+ if (!DrawNamesChanged(SC_CONTENT_DRAWING))
+ return;
+
+ SetUpdateMode(FALSE);
+
+ ClearType( nType );
+
+ if ( !nType || nType == SC_CONTENT_TABLE )
+ GetTableNames();
+ if ( !nType || nType == SC_CONTENT_RANGENAME )
+ GetAreaNames();
+ if ( !nType || nType == SC_CONTENT_DBAREA )
+ GetDbNames();
+ if ( !nType || nType == SC_CONTENT_GRAPHIC )
+ GetGraphicNames();
+ if ( !nType || nType == SC_CONTENT_OLEOBJECT )
+ GetOleNames();
+ if ( !nType || nType == SC_CONTENT_DRAWING )
+ GetDrawingNames();
+ if ( !nType || nType == SC_CONTENT_NOTE )
+ GetNoteStrings();
+ if ( !nType || nType == SC_CONTENT_AREALINK )
+ GetLinkNames();
+
+ ApplySettings();
+ SetUpdateMode(TRUE);
+}
+
+void ScContentTree::GetTableNames()
+{
+ if ( nRootType && nRootType != SC_CONTENT_TABLE ) // ausgeblendet ?
+ return;
+
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return;
+
+ String aName;
+ SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ {
+ pDoc->GetName( i, aName );
+ InsertContent( SC_CONTENT_TABLE, aName );
+ }
+}
+
+void ScContentTree::GetAreaNames()
+{
+ if ( nRootType && nRootType != SC_CONTENT_RANGENAME ) // ausgeblendet ?
+ return;
+
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return;
+
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ USHORT nCount = pRangeNames->GetCount();
+ if ( nCount > 0 )
+ {
+ USHORT nValidCount = 0;
+ ScRange aDummy;
+ USHORT i;
+ for ( i=0; i<nCount; i++ )
+ {
+ ScRangeData* pData = (*pRangeNames)[i];
+ if (pData->IsValidReference(aDummy))
+ nValidCount++;
+ }
+ if ( nValidCount )
+ {
+ ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
+ USHORT j;
+ for ( i=0, j=0; i<nCount; i++ )
+ {
+ ScRangeData* pData = (*pRangeNames)[i];
+ if (pData->IsValidReference(aDummy))
+ ppSortArray[j++] = pData;
+ }
+#ifndef ICC
+ qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
+ &ScRangeData_QsortNameCompare );
+#else
+ qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
+ ICCQsortNameCompare );
+#endif
+ for ( j=0; j<nValidCount; j++ )
+ InsertContent( SC_CONTENT_RANGENAME, ppSortArray[j]->GetName() );
+ delete [] ppSortArray;
+ }
+ }
+}
+
+void ScContentTree::GetDbNames()
+{
+ if ( nRootType && nRootType != SC_CONTENT_DBAREA ) // ausgeblendet ?
+ return;
+
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return;
+
+ ScDBCollection* pDbNames = pDoc->GetDBCollection();
+ USHORT nCount = pDbNames->GetCount();
+ if ( nCount > 0 )
+ {
+ String aStrNoName( ScGlobal::GetRscString(STR_DB_NONAME) );
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ ScDBData* pData = (*pDbNames)[i];
+ String aStrName = pData->GetName();
+ if ( aStrName != aStrNoName )
+ InsertContent( SC_CONTENT_DBAREA, aStrName );
+ }
+ }
+}
+
+bool ScContentTree::IsPartOfType( USHORT nContentType, USHORT nObjIdentifier ) // static
+{
+ bool bRet = false;
+ switch ( nContentType )
+ {
+ case SC_CONTENT_GRAPHIC:
+ bRet = ( nObjIdentifier == OBJ_GRAF );
+ break;
+ case SC_CONTENT_OLEOBJECT:
+ bRet = ( nObjIdentifier == OBJ_OLE2 );
+ break;
+ case SC_CONTENT_DRAWING:
+ bRet = ( nObjIdentifier != OBJ_GRAF && nObjIdentifier != OBJ_OLE2 ); // everything else
+ break;
+ default:
+ DBG_ERROR("unknown content type");
+ }
+ return bRet;
+}
+
+void ScContentTree::GetDrawNames( USHORT nType )
+{
+ if ( nRootType && nRootType != nType ) // ausgeblendet ?
+ return;
+
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return;
+
+ // iterate in flat mode for groups
+ SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
+
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ SfxObjectShell* pShell = pDoc->GetDocumentShell();
+ if (pDrawLayer && pShell)
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, eIter );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
+ {
+ String aName = ScDrawLayer::GetVisibleName( pObject );
+ if (aName.Len())
+ InsertContent( nType, aName );
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+}
+
+void ScContentTree::GetGraphicNames()
+{
+ GetDrawNames( SC_CONTENT_GRAPHIC );
+}
+
+void ScContentTree::GetOleNames()
+{
+ GetDrawNames( SC_CONTENT_OLEOBJECT );
+}
+
+void ScContentTree::GetDrawingNames()
+{
+ GetDrawNames( SC_CONTENT_DRAWING );
+}
+
+void ScContentTree::GetLinkNames()
+{
+ if ( nRootType && nRootType != SC_CONTENT_AREALINK ) // ausgeblendet ?
+ return;
+
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return;
+
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?");
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ InsertContent( SC_CONTENT_AREALINK, ((ScAreaLink*)pBase)->GetSource() );
+
+ // in der Liste die Namen der Quellbereiche
+ }
+}
+
+const ScAreaLink* ScContentTree::GetLink( ULONG nIndex )
+{
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return NULL;
+
+ ULONG nFound = 0;
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?");
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = rLinks.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ {
+ if (nFound == nIndex)
+ return (const ScAreaLink*) pBase;
+ ++nFound;
+ }
+ }
+
+ DBG_ERROR("Link nicht gefunden");
+ return NULL;
+}
+
+String lcl_NoteString( const ScPostIt& rNote )
+{
+ String aText = rNote.GetText();
+ xub_StrLen nAt;
+ while ( (nAt = aText.Search( '\n' )) != STRING_NOTFOUND )
+ aText.SetChar( nAt, ' ' );
+ return aText;
+}
+
+void ScContentTree::GetNoteStrings()
+{
+ if ( nRootType && nRootType != SC_CONTENT_NOTE ) // ausgeblendet ?
+ return;
+
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return;
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
+ for( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
+ if( const ScPostIt* pNote = pCell->GetNote() )
+ InsertContent( SC_CONTENT_NOTE, lcl_NoteString( *pNote ) );
+ }
+}
+
+ScAddress ScContentTree::GetNotePos( ULONG nIndex )
+{
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return ScAddress();
+
+ ULONG nFound = 0;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if( pCell->HasNote() )
+ {
+ if (nFound == nIndex)
+ return ScAddress( aIter.GetCol(), aIter.GetRow(), nTab ); // gefunden
+ ++nFound;
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+
+ DBG_ERROR("Notiz nicht gefunden");
+ return ScAddress();
+}
+
+BOOL ScContentTree::NoteStringsChanged()
+{
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return FALSE;
+
+ SvLBoxEntry* pParent = pRootNodes[SC_CONTENT_NOTE];
+ if (!pParent)
+ return FALSE;
+
+ SvLBoxEntry* pEntry = FirstChild( pParent );
+
+ BOOL bEqual = TRUE;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++)
+ {
+ ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell && bEqual)
+ {
+ if( const ScPostIt* pNote = pCell->GetNote() )
+ {
+ if ( !pEntry )
+ bEqual = FALSE;
+ else
+ {
+ if ( lcl_NoteString( *pNote ) != GetEntryText(pEntry) )
+ bEqual = FALSE;
+
+ pEntry = NextSibling( pEntry );
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+
+ if ( pEntry )
+ bEqual = FALSE; // kommt noch was
+
+ return !bEqual;
+}
+
+BOOL ScContentTree::DrawNamesChanged( USHORT nType )
+{
+ ScDocument* pDoc = GetSourceDocument();
+ if (!pDoc)
+ return FALSE;
+
+ SvLBoxEntry* pParent = pRootNodes[nType];
+ if (!pParent)
+ return FALSE;
+
+ SvLBoxEntry* pEntry = FirstChild( pParent );
+
+ // iterate in flat mode for groups
+ SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
+
+ BOOL bEqual = TRUE;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ SfxObjectShell* pShell = pDoc->GetDocumentShell();
+ if (pDrawLayer && pShell)
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, eIter );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && bEqual)
+ {
+ if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
+ {
+ if ( !pEntry )
+ bEqual = FALSE;
+ else
+ {
+ if ( ScDrawLayer::GetVisibleName( pObject ) != GetEntryText(pEntry) )
+ bEqual = FALSE;
+
+ pEntry = NextSibling( pEntry );
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+
+ if ( pEntry )
+ bEqual = FALSE; // kommt noch was
+
+ return !bEqual;
+}
+
+BOOL lcl_GetRange( ScDocument* pDoc, USHORT nType, const String& rName, ScRange& rRange )
+{
+ BOOL bFound = FALSE;
+ USHORT nPos;
+
+ if ( nType == SC_CONTENT_RANGENAME )
+ {
+ ScRangeName* pList = pDoc->GetRangeName();
+ if (pList)
+ if (pList->SearchName( rName, nPos ))
+ if ( (*pList)[nPos]->IsValidReference( rRange ) )
+ bFound = TRUE;
+ }
+ else if ( nType == SC_CONTENT_DBAREA )
+ {
+ ScDBCollection* pList = pDoc->GetDBCollection();
+ if (pList)
+ if (pList->SearchName( rName, nPos ))
+ {
+ SCTAB nTab;
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ (*pList)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2);
+ rRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab );
+ bFound = TRUE;
+ }
+ }
+
+ return bFound;
+}
+
+void lcl_DoDragObject( ScDocShell* pSrcShell, const String& rName, USHORT nType, Window* pWin )
+{
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+ ScDrawLayer* pModel = pSrcDoc->GetDrawLayer();
+ if (pModel)
+ {
+ BOOL bOle = ( nType == SC_CONTENT_OLEOBJECT );
+ BOOL bGraf = ( nType == SC_CONTENT_GRAPHIC );
+ USHORT nDrawId = sal::static_int_cast<USHORT>( bOle ? OBJ_OLE2 : ( bGraf ? OBJ_GRAF : OBJ_GRUP ) );
+ SCTAB nTab = 0;
+ SdrObject* pObject = pModel->GetNamedObject( rName, nDrawId, nTab );
+ if (pObject)
+ {
+ SdrView aEditView( pModel );
+ aEditView.ShowSdrPage(aEditView.GetModel()->GetPage(nTab));
+ SdrPageView* pPV = aEditView.GetSdrPageView();
+ aEditView.MarkObj(pObject, pPV);
+
+ SdrModel* pDragModel = aEditView.GetAllMarkedModel();
+
+ TransferableObjectDescriptor aObjDesc;
+ pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pDragModel, pSrcShell, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ pTransferObj->SetDragSourceObj( pObject, nTab );
+ pTransferObj->SetDragSourceFlags( SC_DROP_NAVIGATOR );
+
+ SC_MOD()->SetDragObject( NULL, pTransferObj );
+ pWin->ReleaseMouse();
+ pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+ }
+ }
+}
+
+void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, USHORT nFlags, Window* pWin )
+{
+ ScMarkData aMark;
+ aMark.SelectTable( rRange.aStart.Tab(), TRUE );
+ aMark.SetMarkArea( rRange );
+
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+ if ( !pSrcDoc->HasSelectedBlockMatrixFragment( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(),
+ aMark ) )
+ {
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ ScClipParam aClipParam(rRange, false);
+ pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aMark);
+ // pClipDoc->ExtendMerge( rRange, TRUE );
+
+ TransferableObjectDescriptor aObjDesc;
+ pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ pTransferObj->SetDragSource( pSrcShell, aMark );
+ pTransferObj->SetDragSourceFlags( nFlags );
+
+ SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D
+ pWin->ReleaseMouse();
+ pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+ }
+}
+
+void ScContentTree::DoDrag()
+{
+ ScDocumentLoader* pDocLoader = NULL;
+ bIsInDrag = TRUE;
+
+ ScModule* pScMod = SC_MOD();
+
+ USHORT nType;
+ ULONG nChild;
+ SvLBoxEntry* pEntry = GetCurEntry();
+ GetEntryIndexes( nType, nChild, pEntry );
+
+ if( pEntry &&
+ (nChild != SC_CONTENT_NOCHILD) &&
+ (nType != SC_CONTENT_ROOT) &&
+ (nType != SC_CONTENT_NOTE) &&
+ (nType != SC_CONTENT_AREALINK) )
+ {
+ String aText( GetEntryText( pEntry ) );
+
+ ScDocument* pLocalDoc = NULL; // fuer URL-Drop
+ String aDocName;
+ if (bHiddenDoc)
+ aDocName = aHiddenName;
+ else
+ {
+ ScDocShell* pDocSh = GetManualOrCurrent();
+ if (pDocSh)
+ {
+ if (pDocSh->HasName())
+ aDocName = pDocSh->GetMedium()->GetName();
+ else
+ pLocalDoc = pDocSh->GetDocument(); // Drop nur in dieses Dokument
+ }
+ }
+
+ BOOL bDoLinkTrans = FALSE; // use ScLinkTransferObj
+ String aLinkURL; // for ScLinkTransferObj
+ String aLinkText;
+
+ USHORT nDropMode = pParentWindow->GetDropMode();
+ switch ( nDropMode )
+ {
+ case SC_DROPMODE_URL:
+ {
+ String aUrl = aDocName;
+ aUrl += '#';
+ aUrl += aText;
+
+ pScMod->SetDragJump( pLocalDoc, aUrl, aText );
+
+ if (aDocName.Len())
+ {
+ // provide URL to outside only if the document has a name
+ // (without name, only internal D&D via SetDragJump)
+
+ aLinkURL = aUrl;
+ aLinkText = aText;
+ }
+ bDoLinkTrans = TRUE;
+ }
+ break;
+ case SC_DROPMODE_LINK:
+ {
+ if ( aDocName.Len() ) // link only to named documents
+ {
+ // for internal D&D, set flag to insert a link
+
+ switch ( nType )
+ {
+ case SC_CONTENT_TABLE:
+ pScMod->SetDragLink( aDocName, aText, EMPTY_STRING );
+ bDoLinkTrans = TRUE;
+ break;
+ case SC_CONTENT_RANGENAME:
+ case SC_CONTENT_DBAREA:
+ pScMod->SetDragLink( aDocName, EMPTY_STRING, aText );
+ bDoLinkTrans = TRUE;
+ break;
+
+ // other types cannot be linked
+ }
+ }
+ }
+ break;
+ case SC_DROPMODE_COPY:
+ {
+ ScDocShell* pSrcShell = NULL;
+ if ( bHiddenDoc )
+ {
+ String aFilter, aOptions;
+ pDocLoader = new ScDocumentLoader( aHiddenName, aFilter, aOptions );
+ if (!pDocLoader->IsError())
+ pSrcShell = pDocLoader->GetDocShell();
+ }
+ else
+ pSrcShell = GetManualOrCurrent();
+
+ if ( pSrcShell )
+ {
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+ if ( nType == SC_CONTENT_RANGENAME || nType == SC_CONTENT_DBAREA )
+ {
+ ScRange aRange;
+ if ( lcl_GetRange( pSrcDoc, nType, aText, aRange ) )
+ {
+ lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR, this );
+ }
+ }
+ else if ( nType == SC_CONTENT_TABLE )
+ {
+ SCTAB nTab;
+ if ( pSrcDoc->GetTable( aText, nTab ) )
+ {
+ ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab );
+ lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR | SC_DROP_TABLE, this );
+ }
+ }
+ else if ( nType == SC_CONTENT_GRAPHIC || nType == SC_CONTENT_OLEOBJECT ||
+ nType == SC_CONTENT_DRAWING )
+ {
+ lcl_DoDragObject( pSrcShell, aText, nType, this );
+
+ // in ExecuteDrag kann der Navigator geloescht worden sein
+ // -> nicht mehr auf Member zugreifen !!!
+ }
+ }
+ }
+ break;
+ }
+
+ if (bDoLinkTrans)
+ {
+ ScLinkTransferObj* pTransferObj = new ScLinkTransferObj;
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( aLinkURL.Len() )
+ pTransferObj->SetLinkURL( aLinkURL, aLinkText );
+
+ // SetDragJump / SetDragLink has been done above
+
+ ReleaseMouse();
+ pTransferObj->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+ }
+ }
+
+ bIsInDrag = FALSE; // static Member
+
+ delete pDocLoader; // falls Dokument zum Draggen geladen wurde
+}
+
+IMPL_STATIC_LINK(ScContentTree, ExecDragHdl, void*, EMPTYARG)
+{
+ // als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch der
+ // Navigator geloescht werden darf
+
+ pThis->DoDrag();
+ return 0;
+}
+
+//UNUSED2008-05 void ScContentTree::AdjustTitle()
+//UNUSED2008-05 {
+//UNUSED2008-05 String aTitle = pParentWindow->aTitleBase;
+//UNUSED2008-05 if (bHiddenDoc)
+//UNUSED2008-05 {
+//UNUSED2008-05 aTitle.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
+//UNUSED2008-05 aTitle += aHiddenTitle;
+//UNUSED2008-05 }
+//UNUSED2008-05 pParentWindow->SetText(aTitle);
+//UNUSED2008-05 }
+
+BOOL ScContentTree::LoadFile( const String& rUrl )
+{
+ String aDocName = rUrl;
+ xub_StrLen nPos = aDocName.Search('#');
+ if ( nPos != STRING_NOTFOUND )
+ aDocName.Erase(nPos); // nur der Name, ohne #...
+
+ BOOL bReturn = FALSE;
+ String aFilter, aOptions;
+ ScDocumentLoader aLoader( aDocName, aFilter, aOptions );
+ if ( !aLoader.IsError() )
+ {
+ bHiddenDoc = TRUE;
+ aHiddenName = aDocName;
+ aHiddenTitle = aLoader.GetTitle();
+ pHiddenDocument = aLoader.GetDocument();
+
+ Refresh(); // Inhalte aus geladenem Dokument holen
+
+ pHiddenDocument = NULL;
+// AdjustTitle();
+
+ pParentWindow->GetDocNames( &aHiddenTitle ); // Liste fuellen
+ }
+ else
+ Sound::Beep(); // Fehler beim Laden
+
+ // Dokument wird im dtor von ScDocumentLoader wieder geschlossen
+
+ return bReturn;
+}
+
+void ScContentTree::InitWindowBits( BOOL bButtons )
+{
+ WinBits nFlags = WB_CLIPCHILDREN|WB_HSCROLL;
+ if (bButtons)
+ nFlags |= WB_HASBUTTONS|WB_HASBUTTONSATROOT;
+
+ SetWindowBits( nFlags );
+}
+
+void ScContentTree::SetRootType( USHORT nNew )
+{
+ if ( nNew != nRootType )
+ {
+ nRootType = nNew;
+ InitWindowBits( nNew == 0 );
+ Refresh();
+
+ ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
+ rCfg.SetRootType( nRootType );
+ }
+}
+
+void ScContentTree::ToggleRoot() // nach Selektion
+{
+ USHORT nNew = SC_CONTENT_ROOT;
+ if ( nRootType == SC_CONTENT_ROOT )
+ {
+ SvLBoxEntry* pEntry = GetCurEntry();
+ if (pEntry)
+ {
+ SvLBoxEntry* pParent = GetParent(pEntry);
+ for (USHORT i=1; i<SC_CONTENT_COUNT; i++)
+ if ( pEntry == pRootNodes[i] || pParent == pRootNodes[i] )
+ nNew = i;
+ }
+ }
+
+ SetRootType( nNew );
+}
+
+void ScContentTree::ResetManualDoc()
+{
+ aManualDoc.Erase();
+ bHiddenDoc = FALSE;
+
+ ActiveDocChanged();
+}
+
+void ScContentTree::ActiveDocChanged()
+{
+ if ( !bHiddenDoc && !aManualDoc.Len() )
+ Refresh(); // Inhalte nur wenn automatisch
+
+ // Listbox muss immer geupdated werden, wegen aktiv-Flag
+
+ String aCurrent;
+ if ( bHiddenDoc )
+ aCurrent = aHiddenTitle;
+ else
+ {
+ ScDocShell* pSh = GetManualOrCurrent();
+ if (pSh)
+ aCurrent = pSh->GetTitle();
+ else
+ {
+ // eingestelltes Dokument existiert nicht mehr
+
+ aManualDoc.Erase(); // wieder automatisch
+ Refresh();
+ pSh = GetManualOrCurrent(); // sollte jetzt aktives sein
+ if (pSh)
+ aCurrent = pSh->GetTitle();
+ }
+ }
+ pParentWindow->GetDocNames( &aCurrent ); // selektieren
+}
+
+void ScContentTree::SetManualDoc(const String& rName)
+{
+ aManualDoc = rName;
+ if (!bHiddenDoc)
+ {
+ Refresh();
+ pParentWindow->GetDocNames( &aManualDoc ); // selektieren
+ }
+}
+
+void ScContentTree::SelectDoc(const String& rName) // rName wie im Menue/Listbox angezeigt
+{
+ if ( rName == pParentWindow->aStrActiveWin )
+ {
+ ResetManualDoc();
+ return;
+ }
+
+ // "aktiv" oder "inaktiv" weglassen
+
+ String aRealName = rName;
+ xub_StrLen nLen = rName.Len();
+ xub_StrLen nActiveStart = nLen - pParentWindow->aStrActive.Len();
+ if ( rName.Copy( nActiveStart ) == pParentWindow->aStrActive )
+ aRealName = rName.Copy( 0, nActiveStart );
+ xub_StrLen nNotActiveStart = nLen - pParentWindow->aStrNotActive.Len();
+ if ( rName.Copy( nNotActiveStart ) == pParentWindow->aStrNotActive )
+ aRealName = rName.Copy( 0, nNotActiveStart );
+
+ //
+
+ BOOL bLoaded = FALSE;
+
+ // ist es ein normal geladenes Doc ?
+
+ SfxObjectShell* pSh = SfxObjectShell::GetFirst();
+ while ( pSh && !bLoaded )
+ {
+ if ( pSh->ISA(ScDocShell) )
+ if ( pSh->GetTitle() == aRealName )
+ bLoaded = TRUE;
+ pSh = SfxObjectShell::GetNext( *pSh );
+ }
+
+ if (bLoaded)
+ {
+ bHiddenDoc = FALSE;
+ SetManualDoc(aRealName);
+ }
+ else if (aHiddenTitle.Len()) // verstecktes ausgewaehlt
+ {
+ if (!bHiddenDoc)
+ LoadFile(aHiddenName);
+ }
+ else
+ {
+ DBG_ERROR("SelectDoc: nicht gefunden");
+ }
+}
+
+void ScContentTree::ApplySettings()
+{
+ const ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings();
+ if( pSettings )
+ {
+ USHORT nRootSel = pSettings->GetRootSelected();
+ ULONG nChildSel = pSettings->GetChildSelected();
+
+ for( USHORT nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry )
+ {
+ if( pRootNodes[ nEntry ] )
+ {
+ // expand
+ BOOL bExp = pSettings->IsExpanded( nEntry );
+ if( bExp != IsExpanded( pRootNodes[ nEntry ] ) )
+ {
+ if( bExp )
+ Expand( pRootNodes[ nEntry ] );
+ else
+ Collapse( pRootNodes[ nEntry ] );
+ }
+
+ // select
+ if( nRootSel == nEntry )
+ {
+ SvLBoxEntry* pEntry = NULL;
+ if( bExp && (nChildSel != SC_CONTENT_NOCHILD) )
+ pEntry = GetEntry( pRootNodes[ nEntry ], nChildSel );
+ Select( pEntry ? pEntry : pRootNodes[ nEntry ] );
+ }
+ }
+ }
+ }
+}
+
+void ScContentTree::StoreSettings() const
+{
+ ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings();
+ if( pSettings )
+ {
+ for( USHORT nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry )
+ {
+ BOOL bExp = pRootNodes[ nEntry ] && IsExpanded( pRootNodes[ nEntry ] );
+ pSettings->SetExpanded( nEntry, bExp );
+ }
+ USHORT nRoot;
+ ULONG nChild;
+ GetEntryIndexes( nRoot, nChild, GetCurEntry() );
+ pSettings->SetRootSelected( nRoot );
+ pSettings->SetChildSelected( nChild );
+ }
+}
+
+
+//
+//------------------------------------------------------------------------
+//
+
+
+
+
+
diff --git a/sc/source/ui/navipi/makefile.mk b/sc/source/ui/navipi/makefile.mk
new file mode 100644
index 000000000000..9c0de073dd8c
--- /dev/null
+++ b/sc/source/ui/navipi/makefile.mk
@@ -0,0 +1,57 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=navipi
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/navipi.obj \
+ $(SLO)$/navcitem.obj \
+ $(SLO)$/scenwnd.obj \
+ $(SLO)$/content.obj
+
+EXCEPTIONSFILES = \
+ $(SLO)$/scenwnd.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES = navipi.src
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/navipi/navcitem.cxx b/sc/source/ui/navipi/navcitem.cxx
new file mode 100644
index 000000000000..e5002c44c60e
--- /dev/null
+++ b/sc/source/ui/navipi/navcitem.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+
+#include "navcitem.hxx"
+#include "global.hxx"
+#include "navipi.hxx"
+#include "sc.hrc" // -> Item-IDs
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//------------------------------------------------------------------------
+
+ScNavigatorControllerItem::ScNavigatorControllerItem( USHORT nIdP,
+ ScNavigatorDlg& rDlg,
+ SfxBindings& rBindings )
+ : SfxControllerItem ( nIdP, rBindings ),
+ rNavigatorDlg ( rDlg )
+{
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScNavigatorControllerItem::StateChanged( USHORT /* nSID */, SfxItemState /* eState */,
+ const SfxPoolItem* pItem )
+{
+ switch( GetId() )
+ {
+ case SID_CURRENTCELL:
+ if ( pItem )
+ {
+// const SfxPointItem* pCellPosItem = PTR_CAST(SfxPointItem, pItem);
+ const SfxStringItem* pCellPosItem = PTR_CAST(SfxStringItem, pItem);
+
+ DBG_ASSERT( pCellPosItem, "SfxStringItem expected!" );
+
+ if ( pCellPosItem )
+ {
+ String aAddress( pCellPosItem->GetValue() );
+ ScAddress aScAddress;
+ aScAddress.Parse( aAddress );
+
+ SCCOL nCol = aScAddress.Col()+1;
+ SCROW nRow = aScAddress.Row()+1;
+
+// SCCOL nCol = (USHORT)pCellPosItem->GetValue().X()+1;
+// SCROW nRow = (USHORT)pCellPosItem->GetValue().Y()+1;
+
+ rNavigatorDlg.UpdateColumn( &nCol );
+ rNavigatorDlg.UpdateRow ( &nRow );
+ rNavigatorDlg.CursorPosChanged();
+ }
+ }
+ break;
+
+ case SID_CURRENTTAB:
+ if ( pItem )
+ {
+ const SfxUInt16Item* pTabItem = PTR_CAST(SfxUInt16Item, pItem);
+
+ DBG_ASSERT( pTabItem, "SfxUInt16Item expected!" );
+
+ // Tabelle fuer Basic ist 1-basiert
+ if ( pTabItem && pTabItem->GetValue() )
+ {
+ SCTAB nTab = pTabItem->GetValue() - 1;
+
+ rNavigatorDlg.UpdateTable( &nTab );
+ rNavigatorDlg.UpdateColumn();
+ rNavigatorDlg.UpdateRow();
+ rNavigatorDlg.CursorPosChanged();
+ }
+ }
+ break;
+
+ case SID_CURRENTDOC:
+ //
+ // gar nix mehr, wird ueber SFX_HINT_DOCCHANGED erledigt
+ //
+ break;
+
+
+ case SID_SELECT_SCENARIO:
+ rNavigatorDlg.aWndScenarios.NotifyState( pItem );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
diff --git a/sc/source/ui/navipi/navipi.cxx b/sc/source/ui/navipi/navipi.cxx
new file mode 100644
index 000000000000..846e2ce53310
--- /dev/null
+++ b/sc/source/ui/navipi/navipi.cxx
@@ -0,0 +1,1565 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------
+
+// #include <math.h>
+#include <rangelst.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/imgmgr.hxx>
+#include <sfx2/navigat.hxx>
+#include <svl/stritem.hxx>
+#include <svl/urlbmk.hxx>
+#include <vcl/sound.hxx>
+#include <unotools/charclass.hxx>
+#include <stdlib.h>
+
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "popmenu.hxx"
+#include "scresid.hxx"
+#include "scmod.hxx"
+#include "navicfg.hxx"
+#include "navcitem.hxx"
+#include "navipi.hrc"
+#include "navipi.hxx"
+#include "navsett.hxx"
+
+// Timeout, um Notizen zu suchen
+#define SC_CONTENT_TIMEOUT 1000
+
+// Toleranz, wieviel ueber der eingeklappten Groesse noch klein ist
+#define SCNAV_MINTOL 5
+
+// maximum values for UI
+#define SCNAV_MAXCOL (MAXCOLCOUNT)
+// macro is sufficient since only used in ctor
+#define SCNAV_COLDIGITS (static_cast<xub_StrLen>( floor( log10( static_cast<double>(SCNAV_MAXCOL)))) + 1) // 1...256...18278
+// precomputed constant because it is used in every change of spin button field
+static const xub_StrLen SCNAV_COLLETTERS = ::ScColToAlpha(SCNAV_MAXCOL).Len(); // A...IV...ZZZ
+
+#define SCNAV_MAXROW (MAXROWCOUNT)
+
+//------------------------------------------------------------------------
+
+// static
+void ScNavigatorDlg::ReleaseFocus()
+{
+ SfxViewShell* pCurSh = SfxViewShell::Current();
+
+ if ( pCurSh )
+ {
+ Window* pShellWnd = pCurSh->GetWindow();
+ if ( pShellWnd )
+ pShellWnd->GrabFocus();
+ }
+}
+
+//==================================================================
+// class ColumnEdit
+//==================================================================
+
+ColumnEdit::ColumnEdit( ScNavigatorDlg* pParent, const ResId& rResId )
+ : SpinField ( pParent, rResId ),
+ rDlg ( *pParent ),
+ nCol ( 0 ),
+ nKeyGroup ( KEYGROUP_ALPHA )
+{
+ SetMaxTextLen( SCNAV_COLDIGITS ); // 1...256...18278 or A...IV...ZZZ
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ColumnEdit::~ColumnEdit()
+{
+}
+
+//------------------------------------------------------------------------
+
+long __EXPORT ColumnEdit::Notify( NotifyEvent& rNEvt )
+{
+ long nHandled = SpinField::Notify( rNEvt );
+
+ USHORT nType = rNEvt.GetType();
+ if ( nType == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aCode = pKEvt->GetKeyCode();
+
+ if ( !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ //! Eingabeueberpruefung (nur Zahlen oder nur Buchstaben, max 2 bzw 3 Stellen)
+ //! war vor VCL per nicht weitergeleitetem KeyInput
+ //! dafuer was neues ausdenken!!!
+
+ if ( aCode.GetCode() == KEY_RETURN )
+ {
+ ScNavigatorDlg::ReleaseFocus();
+ ExecuteCol();
+ nHandled = 1;
+ }
+ }
+ }
+ else if ( nType == EVENT_LOSEFOCUS ) // LoseFocus wird bei VCL nicht gerufen
+ EvalText(); // nCol setzen
+
+ return nHandled;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ColumnEdit::LoseFocus()
+{
+ EvalText();
+}
+
+
+//------------------------------------------------------------------------
+
+void __EXPORT ColumnEdit::Up()
+{
+ nCol++;
+
+#ifdef OS2
+ if ( nCol > SCNAV_MAXCOL )
+ nCol = 1;
+#endif
+
+ if ( nCol <= SCNAV_MAXCOL )
+ SetCol( nCol );
+ else
+ nCol--;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ColumnEdit::Down()
+{
+ if ( nCol>1 )
+ SetCol( nCol-1 );
+#ifdef OS2
+ else
+ SetCol( SCNAV_MAXCOL );
+#endif
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ColumnEdit::First()
+{
+ nCol = 1;
+ SetText( 'A' );
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ColumnEdit::Last()
+{
+ String aStr;
+ nCol = NumToAlpha( SCNAV_MAXCOL, aStr );
+ SetText( aStr );
+}
+
+
+//------------------------------------------------------------------------
+
+void ColumnEdit::EvalText()
+{
+ String aStrCol = GetText();
+
+ if ( aStrCol.Len() > 0 )
+ {
+ // nKeyGroup wird bei VCL mangels KeyInput nicht mehr gesetzt
+
+ if ( CharClass::isAsciiNumeric(aStrCol) )
+ nCol = NumStrToAlpha( aStrCol );
+ else
+ nCol = AlphaToNum( aStrCol );
+ }
+ else
+ nCol = 0;
+
+ SetText( aStrCol );
+ nKeyGroup = KEYGROUP_ALPHA;
+}
+
+//------------------------------------------------------------------------
+
+void ColumnEdit::ExecuteCol()
+{
+ SCROW nRow = rDlg.aEdRow.GetRow();
+
+ EvalText(); // setzt nCol
+
+ if ( (nCol > 0) && (nRow > 0) )
+ rDlg.SetCurrentCell( nCol-1, nRow-1 );
+}
+
+//------------------------------------------------------------------------
+
+void ColumnEdit::SetCol( SCCOL nColNo )
+{
+ String aStr;
+
+ if ( nColNo == 0 )
+ {
+ nCol = 0;
+ SetText( aStr );
+ }
+ else
+ {
+ nColNo = NumToAlpha( nColNo, aStr );
+ nCol = nColNo;
+ SetText( aStr );
+ }
+}
+
+//------------------------------------------------------------------------
+
+SCCOL ColumnEdit::AlphaToNum( String& rStr )
+{
+ SCCOL nColumn = 0;
+
+ if ( CharClass::isAsciiAlpha( rStr) )
+ {
+ rStr.ToUpperAscii();
+
+ if (::AlphaToCol( nColumn, rStr))
+ ++nColumn;
+
+ if ( (rStr.Len() > SCNAV_COLLETTERS) || (nColumn > SCNAV_MAXCOL) )
+ {
+ nColumn = SCNAV_MAXCOL;
+ NumToAlpha( nColumn, rStr );
+ }
+ }
+ else
+ rStr.Erase();
+
+ return nColumn;
+}
+
+//------------------------------------------------------------------------
+
+SCCOL ColumnEdit::NumStrToAlpha( String& rStr )
+{
+ SCCOL nColumn = 0;
+
+ if ( CharClass::isAsciiNumeric(rStr) )
+ nColumn = NumToAlpha( (SCCOL)rStr.ToInt32(), rStr );
+ else
+ rStr.Erase();
+
+ return nColumn;
+}
+
+//------------------------------------------------------------------------
+
+SCCOL ColumnEdit::NumToAlpha( SCCOL nColNo, String& rStr )
+{
+ if ( nColNo > SCNAV_MAXCOL )
+ nColNo = SCNAV_MAXCOL;
+ else if ( nColNo < 1 )
+ nColNo = 1;
+
+ ::ScColToAlpha( rStr, nColNo - 1);
+
+ return nColNo;
+}
+
+//==================================================================
+// class RowEdit
+//==================================================================
+
+RowEdit::RowEdit( ScNavigatorDlg* pParent, const ResId& rResId )
+ : NumericField( pParent, rResId ),
+ rDlg ( *pParent )
+{
+ SetMax( SCNAV_MAXROW);
+ SetLast( SCNAV_MAXROW);
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT RowEdit::~RowEdit()
+{
+}
+
+//------------------------------------------------------------------------
+
+long __EXPORT RowEdit::Notify( NotifyEvent& rNEvt )
+{
+ long nHandled = NumericField::Notify( rNEvt );
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aCode = pKEvt->GetKeyCode();
+ if ( aCode.GetCode() == KEY_RETURN && !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ ScNavigatorDlg::ReleaseFocus();
+ ExecuteRow();
+ nHandled = 1;
+ }
+ }
+
+ return nHandled;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT RowEdit::LoseFocus()
+{
+}
+
+//------------------------------------------------------------------------
+
+void RowEdit::ExecuteRow()
+{
+ SCCOL nCol = rDlg.aEdCol.GetCol();
+ SCROW nRow = (SCROW)GetValue();
+
+ if ( (nCol > 0) && (nRow > 0) )
+ rDlg.SetCurrentCell( nCol-1, nRow-1 );
+}
+
+//==================================================================
+// class ScDocListBox
+//==================================================================
+
+ScDocListBox::ScDocListBox( ScNavigatorDlg* pParent, const ResId& rResId )
+ : ListBox ( pParent, rResId ),
+ rDlg ( *pParent )
+{
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScDocListBox::~ScDocListBox()
+{
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScDocListBox::Select()
+{
+ ScNavigatorDlg::ReleaseFocus();
+
+ String aDocName = GetSelectEntry();
+ rDlg.aLbEntries.SelectDoc( aDocName );
+}
+
+//==================================================================
+// class CommandToolBox
+//==================================================================
+
+CommandToolBox::CommandToolBox( ScNavigatorDlg* pParent, const ResId& rResId )
+ : ToolBox ( pParent, rResId ),
+ rDlg ( *pParent )
+{
+ InitImageList(); // ImageList members of ScNavigatorDlg must be initialized before!
+
+ SetSizePixel( CalcWindowSizePixel() );
+ SetDropdownClickHdl( LINK(this, CommandToolBox, ToolBoxDropdownClickHdl) );
+ SetItemBits( IID_DROPMODE, GetItemBits( IID_DROPMODE ) | TIB_DROPDOWNONLY );
+// EnableItem( IID_UP, FALSE );
+// EnableItem( IID_DOWN, FALSE );
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT CommandToolBox::~CommandToolBox()
+{
+}
+
+//------------------------------------------------------------------------
+
+void CommandToolBox::Select( USHORT nSelId )
+{
+ // Modus umschalten ?
+
+ if ( nSelId == IID_ZOOMOUT || nSelId == IID_SCENARIOS )
+ {
+ NavListMode eOldMode = rDlg.eListMode;
+ NavListMode eNewMode = eOldMode;
+
+ if ( nSelId == IID_SCENARIOS ) // auf Szenario
+ {
+ if ( eOldMode == NAV_LMODE_SCENARIOS )
+ eNewMode = NAV_LMODE_AREAS;
+ else
+ eNewMode = NAV_LMODE_SCENARIOS;
+ }
+ else // ein/aus
+ {
+ if ( eOldMode == NAV_LMODE_NONE )
+ eNewMode = NAV_LMODE_AREAS;
+ else
+ eNewMode = NAV_LMODE_NONE;
+ }
+ rDlg.SetListMode( eNewMode );
+ UpdateButtons();
+ }
+ else
+ switch ( nSelId )
+ {
+ case IID_DATA:
+ rDlg.MarkDataArea();
+ break;
+ case IID_UP:
+ rDlg.StartOfDataArea();
+ break;
+ case IID_DOWN:
+ rDlg.EndOfDataArea();
+ break;
+ // IID_DROPMODE ist in Click
+ case IID_CHANGEROOT:
+ rDlg.aLbEntries.ToggleRoot();
+ UpdateButtons();
+ break;
+ }
+}
+
+void __EXPORT CommandToolBox::Select()
+{
+ Select( GetCurItemId() );
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT CommandToolBox::Click()
+{
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( CommandToolBox, ToolBoxDropdownClickHdl, ToolBox*, EMPTYARG )
+{
+ // Das Popupmenue fuer den Dropmodus muss im Click (Button Down)
+ // statt im Select (Button Up) aufgerufen werden.
+
+ if ( GetCurItemId() == IID_DROPMODE )
+ {
+ ScPopupMenu aPop( ScResId( RID_POPUP_DROPMODE ) );
+ aPop.CheckItem( RID_DROPMODE_URL + rDlg.GetDropMode() );
+ aPop.Execute( this, GetItemRect(IID_DROPMODE), POPUPMENU_EXECUTE_DOWN );
+ USHORT nId = aPop.GetSelected();
+
+ EndSelection(); // vor SetDropMode (SetDropMode ruft SetItemImage)
+
+ if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY )
+ rDlg.SetDropMode( nId - RID_DROPMODE_URL );
+
+ // #49956# den gehighlighteten Button aufheben
+ Point aPoint;
+ MouseEvent aLeave( aPoint, 0, MOUSE_LEAVEWINDOW | MOUSE_SYNTHETIC );
+ MouseMove( aLeave );
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------
+
+void CommandToolBox::UpdateButtons()
+{
+ NavListMode eMode = rDlg.eListMode;
+ CheckItem( IID_SCENARIOS, eMode == NAV_LMODE_SCENARIOS );
+ CheckItem( IID_ZOOMOUT, eMode != NAV_LMODE_NONE );
+
+ // Umschalten-Button:
+ if ( eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE )
+ {
+ EnableItem( IID_CHANGEROOT, FALSE );
+ CheckItem( IID_CHANGEROOT, FALSE );
+ }
+ else
+ {
+ EnableItem( IID_CHANGEROOT, TRUE );
+ BOOL bRootSet = rDlg.aLbEntries.GetRootType() != SC_CONTENT_ROOT;
+ CheckItem( IID_CHANGEROOT, bRootSet );
+ }
+
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ USHORT nImageId = 0;
+ switch ( rDlg.nDropMode )
+ {
+ case SC_DROPMODE_URL: nImageId = bHC ? RID_IMG_H_DROP_URL : RID_IMG_DROP_URL; break;
+ case SC_DROPMODE_LINK: nImageId = bHC ? RID_IMG_H_DROP_LINK : RID_IMG_DROP_LINK; break;
+ case SC_DROPMODE_COPY: nImageId = bHC ? RID_IMG_H_DROP_COPY : RID_IMG_DROP_COPY; break;
+ }
+ SetItemImage( IID_DROPMODE, Image(ScResId(nImageId)) );
+}
+
+void CommandToolBox::InitImageList()
+{
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ ImageList& rImgLst = bHC ? rDlg.aCmdImageListH : rDlg.aCmdImageList;
+
+ USHORT nCount = GetItemCount();
+ for (USHORT i = 0; i < nCount; i++)
+ {
+ USHORT nId = GetItemId(i);
+ SetItemImage( nId, rImgLst.GetImage( nId ) );
+ }
+}
+
+void CommandToolBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ // update item images
+
+ InitImageList();
+ UpdateButtons(); // drop mode
+ }
+
+ ToolBox::DataChanged( rDCEvt );
+}
+
+//==================================================================
+// class ScNavigatorSettings
+//==================================================================
+
+ScNavigatorSettings::ScNavigatorSettings() :
+ maExpandedVec( SC_CONTENT_COUNT, FALSE ),
+ mnRootSelected( SC_CONTENT_ROOT ),
+ mnChildSelected( SC_CONTENT_NOCHILD )
+{
+}
+
+//==================================================================
+// class ScNavigatorDlgWrapper
+//==================================================================
+
+SFX_IMPL_CHILDWINDOWCONTEXT( ScNavigatorDialogWrapper, SID_NAVIGATOR )
+
+#define IS_MODE(bit)(((nFlags)&(bit))==(bit))
+
+ScNavigatorDialogWrapper::ScNavigatorDialogWrapper(
+ Window* pParent,
+ USHORT nId,
+ SfxBindings* pBind,
+ SfxChildWinInfo* /* pInfo */ ) :
+ SfxChildWindowContext( nId )
+{
+ pNavigator = new ScNavigatorDlg( pBind, this, pParent );
+ SetWindow( pNavigator );
+
+ // Einstellungen muessen anderswo gemerkt werden,
+ // pInfo geht uns (ausser der Groesse) nichts mehr an
+
+ Size aInfoSize = pParent->GetOutputSizePixel(); // von aussen vorgegebene Groesse
+ Size aNavSize = pNavigator->GetOutputSizePixel(); // Default-Groesse
+
+ aNavSize.Width() = Max( aInfoSize.Width(), aNavSize.Width() );
+ aNavSize.Height() = Max( aInfoSize.Height(), aNavSize.Height() );
+ pNavigator->nListModeHeight = Max( aNavSize.Height(), pNavigator->nListModeHeight );
+
+ // Die Groesse kann in einem anderen Modul geaendert worden sein,
+ // deshalb muessen in Abhaengigkeit von der momentanen Groesse die
+ // Inhalte eingeblendet werden oder nicht
+
+ BOOL bSmall = ( aInfoSize.Height() <= pNavigator->aInitSize.Height() + SCNAV_MINTOL );
+ NavListMode eNavMode = NAV_LMODE_NONE;
+ if (!bSmall)
+ {
+ // wenn Szenario aktiv war, wieder einschalten
+
+ ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
+ NavListMode eLastMode = (NavListMode) rCfg.GetListMode();
+ if ( eLastMode == NAV_LMODE_SCENARIOS )
+ eNavMode = NAV_LMODE_SCENARIOS;
+ else
+ eNavMode = NAV_LMODE_AREAS;
+ }
+
+ // Die Groesse des Floats nicht neu setzen (FALSE bei SetListMode), damit der
+ // Navigator nicht aufgeklappt wird, wenn er minimiert war (#38872#).
+
+ pNavigator->SetListMode( eNavMode, FALSE ); // FALSE: Groesse des Float nicht setzen
+
+ USHORT nCmdId;
+ switch (eNavMode)
+ {
+ case NAV_LMODE_DOCS: nCmdId = IID_DOCS; break;
+ case NAV_LMODE_AREAS: nCmdId = IID_AREAS; break;
+ case NAV_LMODE_DBAREAS: nCmdId = IID_DBAREAS; break;
+ case NAV_LMODE_SCENARIOS: nCmdId = IID_SCENARIOS; break;
+ default: nCmdId = 0;
+ }
+ if (nCmdId)
+ {
+ pNavigator->aTbxCmd.CheckItem( nCmdId );
+ pNavigator->DoResize();
+ }
+
+ pNavigator->bFirstBig = ( nCmdId == 0 ); // dann spaeter
+
+/*???
+ FloatingWindow* pFloat = GetFloatingWindow();
+ if ( pFloat )
+ pFloat->SetMinOutputSizePixel( pNavigator->GetMinOutputSizePixel() );
+*/
+
+//!? pNavigator->Show();
+}
+
+void __EXPORT ScNavigatorDialogWrapper::Resizing( Size& rSize )
+{
+ ((ScNavigatorDlg*)GetWindow())->Resizing(rSize);
+}
+
+//========================================================================
+// class ScNavigatorPI
+//========================================================================
+
+#define CTRL_ITEMS 4
+
+#define REGISTER_SLOT(i,id) \
+ ppBoundItems[i]=new ScNavigatorControllerItem(id,*this,rBindings);
+
+ScNavigatorDlg::ScNavigatorDlg( SfxBindings* pB, SfxChildWindowContext* pCW, Window* pParent ) :
+ Window( pParent, ScResId(RID_SCDLG_NAVIGATOR) ),
+ rBindings ( *pB ), // is used in CommandToolBox ctor
+ aCmdImageList( ScResId( IL_CMD ) ),
+ aCmdImageListH( ScResId( ILH_CMD ) ),
+ aFtCol ( this, ScResId( FT_COL ) ),
+ aEdCol ( this, ScResId( ED_COL ) ),
+ aFtRow ( this, ScResId( FT_ROW ) ),
+ aEdRow ( this, ScResId( ED_ROW ) ),
+ aTbxCmd ( this, ScResId( TBX_CMD ) ),
+ aLbEntries ( this, ScResId( LB_ENTRIES ) ),
+ aWndScenarios( this,ScResId( STR_QHLP_SCEN_LISTBOX), ScResId(STR_QHLP_SCEN_COMMENT)),
+ aLbDocuments( this, ScResId( LB_DOCUMENTS ) ),
+ aStrDragMode ( ScResId( STR_DRAGMODE ) ),
+ aStrDisplay ( ScResId( STR_DISPLAY ) ),
+ aStrActiveWin( ScResId( STR_ACTIVEWIN ) ),
+ pContextWin ( pCW ),
+ pMarkArea ( NULL ),
+ pViewData ( NULL ),
+ nListModeHeight( 0 ),
+ nInitListHeight( 0 ),
+ eListMode ( NAV_LMODE_NONE ),
+ nDropMode ( SC_DROPMODE_URL ),
+ nCurCol ( 0 ),
+ nCurRow ( 0 ),
+ nCurTab ( 0 ),
+ bFirstBig ( FALSE )
+{
+ ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
+ nDropMode = rCfg.GetDragMode();
+ // eListMode wird von aussen gesetzt, Root weiter unten
+
+ aLbDocuments.SetDropDownLineCount(9);
+ String aOpen = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aStrActive = aOpen;
+ aStrActive += String( ScResId( STR_ACTIVE ) );
+ aStrActive += ')'; // " (aktiv)"
+ aStrNotActive = aOpen;
+ aStrNotActive += String( ScResId( STR_NOTACTIVE ) );
+ aStrNotActive += ')'; // " (inaktiv)"
+ aStrHidden = aOpen;
+ aStrHidden += String( ScResId( STR_HIDDEN ) );
+ aStrHidden += ')'; // " (versteckt)"
+
+ aTitleBase = GetText();
+
+ long nListboxYPos = aTbxCmd.GetPosPixel().Y() + aTbxCmd.GetSizePixel().Height() + 4;
+ aLbEntries.SetPosSizePixel( 0, nListboxYPos, 0, 0, WINDOW_POSSIZE_Y);
+
+ nBorderOffset = aLbEntries.GetPosPixel().X();
+
+ aInitSize.Width() = aTbxCmd.GetPosPixel().X()
+ + aTbxCmd.GetSizePixel().Width()
+ + nBorderOffset;
+ aInitSize.Height() = aLbEntries.GetPosPixel().Y();
+
+ nInitListHeight = aLbEntries.GetSizePixel().Height();
+ nListModeHeight = aInitSize.Height()
+ + nInitListHeight;
+
+ // kein Resize, eh der ganze Kontext-Kram initialisiert ist!
+// SetOutputSizePixel( aInitSize ); //???
+/*! FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
+ if ( pFloat)
+ pFloat->SetMinOutputSizePixel( aInitSize );
+*/
+ ppBoundItems = new ScNavigatorControllerItem* [CTRL_ITEMS];
+
+ rBindings.ENTERREGISTRATIONS();
+ //-----------------------------
+ REGISTER_SLOT( 0, SID_CURRENTCELL );
+ REGISTER_SLOT( 1, SID_CURRENTTAB );
+ REGISTER_SLOT( 2, SID_CURRENTDOC );
+ REGISTER_SLOT( 3, SID_SELECT_SCENARIO );
+ //-----------------------------
+ rBindings.LEAVEREGISTRATIONS();
+
+ StartListening( *(SFX_APP()) );
+ StartListening( rBindings );
+
+ aLbDocuments.Hide(); // bei NAV_LMODE_NONE gibts die nicht
+
+ aLbEntries.InitWindowBits(TRUE);
+
+ aLbEntries.SetSpaceBetweenEntries(0);
+ aLbEntries.SetSelectionMode( SINGLE_SELECTION );
+ aLbEntries.SetDragDropMode( SV_DRAGDROP_CTRL_MOVE |
+ SV_DRAGDROP_CTRL_COPY |
+ SV_DRAGDROP_ENABLE_TOP );
+
+ // war eine Kategorie als Root ausgewaehlt?
+ USHORT nLastRoot = rCfg.GetRootType();
+ if ( nLastRoot )
+ aLbEntries.SetRootType( nLastRoot );
+
+ aLbEntries.Refresh();
+ GetDocNames();
+
+ aTbxCmd.UpdateButtons();
+
+ UpdateColumn();
+ UpdateRow();
+ UpdateTable();
+ aLbEntries.Hide();
+ aWndScenarios.Hide();
+ aWndScenarios.SetPosPixel( aLbEntries.GetPosPixel() );
+
+ aContentTimer.SetTimeoutHdl( LINK( this, ScNavigatorDlg, TimeHdl ) );
+ aContentTimer.SetTimeout( SC_CONTENT_TIMEOUT );
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+__EXPORT ScNavigatorDlg::~ScNavigatorDlg()
+{
+ aContentTimer.Stop();
+
+ USHORT i;
+ for ( i=0; i<CTRL_ITEMS; i++ )
+ delete ppBoundItems[i];
+
+ delete [] ppBoundItems;
+ delete pMarkArea;
+
+ EndListening( *(SFX_APP()) );
+ EndListening( rBindings );
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScNavigatorDlg::Resizing( Size& rNewSize ) // Size = Outputsize?
+{
+ FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
+ if ( pFloat )
+ {
+ Size aMinOut = pFloat->GetMinOutputSizePixel();
+
+ if ( rNewSize.Width() < aMinOut.Width() )
+ rNewSize.Width() = aMinOut.Width();
+
+ if ( eListMode == NAV_LMODE_NONE )
+ rNewSize.Height() = aInitSize.Height();
+ else
+ {
+ if ( rNewSize.Height() < aMinOut.Height() )
+ rNewSize.Height() = aMinOut.Height();
+ }
+ }
+// else
+// SfxDockingWindow::Resizing(rNewSize);
+}
+
+
+
+void ScNavigatorDlg::Paint( const Rectangle& rRec )
+{
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aBgColor = rStyleSettings.GetFaceColor();
+ Wallpaper aBack( aBgColor );
+
+ SetBackground( aBack );
+ aFtCol.SetBackground( aBack );
+ aFtRow.SetBackground( aBack );
+
+ Window::Paint( rRec );
+}
+
+void ScNavigatorDlg::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ // toolbox images are exchanged in CommandToolBox::DataChanged
+ Invalidate();
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScNavigatorDlg::Resize()
+{
+ DoResize();
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::DoResize()
+{
+ Size aNewSize = GetOutputSizePixel();
+ long nTotalHeight = aNewSize.Height();
+
+ // #41403# bei angedocktem Navigator wird das Fenster evtl. erst klein erzeugt,
+ // dann kommt ein Resize auf die wirkliche Groesse -> dann Inhalte einschalten
+
+ BOOL bSmall = ( nTotalHeight <= aInitSize.Height() + SCNAV_MINTOL );
+ if ( !bSmall && bFirstBig )
+ {
+ // Inhalte laut Config wieder einschalten
+
+ bFirstBig = FALSE;
+ NavListMode eNavMode = NAV_LMODE_AREAS;
+ ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
+ NavListMode eLastMode = (NavListMode) rCfg.GetListMode();
+ if ( eLastMode == NAV_LMODE_SCENARIOS )
+ eNavMode = NAV_LMODE_SCENARIOS;
+ SetListMode( eNavMode, FALSE ); // FALSE: Groesse des Float nicht setzen
+ }
+
+ // auch wenn die Inhalte nicht sichtbar sind, die Groessen anpassen,
+ // damit die Breite stimmt
+
+ //@@ 03.11.97 changes begin
+ Point aEntryPos = aLbEntries.GetPosPixel();
+ Point aListPos = aLbDocuments.GetPosPixel();
+ aNewSize.Width() -= 2*nBorderOffset;
+ Size aDocSize = aLbDocuments.GetSizePixel();
+ aDocSize.Width() = aNewSize.Width();
+
+ if(!bSmall)
+ {
+
+ long nListHeight = aLbDocuments.GetSizePixel().Height();
+ aNewSize.Height() -= ( aEntryPos.Y() + nListHeight + 2*nBorderOffset );
+ if(aNewSize.Height()<0) aNewSize.Height()=0;
+
+ aListPos.Y() = aEntryPos.Y() + aNewSize.Height() + nBorderOffset;
+
+ if(aListPos.Y() > aLbEntries.GetPosPixel().Y())
+ aLbDocuments.SetPosPixel( aListPos );
+
+ }
+ aLbEntries.SetSizePixel( aNewSize );
+ aWndScenarios.SetSizePixel( aNewSize );
+ aLbDocuments.SetSizePixel( aDocSize );
+
+ //@@ 03.11.97 end
+
+ BOOL bListMode = (eListMode != NAV_LMODE_NONE);
+ FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
+ if ( pFloat && bListMode )
+ nListModeHeight = nTotalHeight;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA(SfxSimpleHint) )
+ {
+ ULONG nHintId = ((SfxSimpleHint&)rHint).GetId();
+
+ if ( nHintId == SC_HINT_DOCNAME_CHANGED )
+ {
+ aLbEntries.ActiveDocChanged();
+ }
+ else if ( NAV_LMODE_NONE == eListMode )
+ {
+ // Tabellen hier nicht mehr
+ }
+ else
+ {
+ switch ( nHintId )
+ {
+ case SC_HINT_TABLES_CHANGED:
+ aLbEntries.Refresh( SC_CONTENT_TABLE );
+ break;
+
+ case SC_HINT_DBAREAS_CHANGED:
+ aLbEntries.Refresh( SC_CONTENT_DBAREA );
+ break;
+
+ case SC_HINT_AREAS_CHANGED:
+ aLbEntries.Refresh( SC_CONTENT_RANGENAME );
+ break;
+
+ case SC_HINT_DRAW_CHANGED:
+ aLbEntries.Refresh( SC_CONTENT_GRAPHIC );
+ aLbEntries.Refresh( SC_CONTENT_OLEOBJECT );
+ aLbEntries.Refresh( SC_CONTENT_DRAWING );
+ break;
+
+ case SC_HINT_AREALINKS_CHANGED:
+ aLbEntries.Refresh( SC_CONTENT_AREALINK );
+ break;
+
+ // SFX_HINT_DOCCHANGED kommt nicht nur bei Dokument-Wechsel
+
+ case SC_HINT_NAVIGATOR_UPDATEALL:
+ UpdateAll();
+ break;
+
+ case FID_DATACHANGED:
+ case FID_ANYDATACHANGED:
+ aContentTimer.Start(); // Notizen nicht sofort suchen
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ else if ( rHint.ISA(SfxEventHint) )
+ {
+ ULONG nEventId = ((SfxEventHint&)rHint).GetEventId();
+ if ( nEventId == SFX_EVENT_ACTIVATEDOC )
+ {
+ aLbEntries.ActiveDocChanged();
+ UpdateAll();
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScNavigatorDlg, TimeHdl, Timer*, pTimer )
+{
+ if ( pTimer != &aContentTimer )
+ return 0;
+
+ aLbEntries.Refresh( SC_CONTENT_NOTE );
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::SetDropMode(USHORT nNew)
+{
+ nDropMode = nNew;
+ aTbxCmd.UpdateButtons();
+
+ ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
+ rCfg.SetDragMode(nDropMode);
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::CursorPosChanged()
+{
+ //! Eintraege selektieren ???
+
+// if ( GetDBAtCursor( aStrDbName ) )
+// if ( GetAreaAtCursor( aStrAreaName ) )
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::SetCurrentCell( SCCOL nColNo, SCROW nRowNo )
+{
+ if ( (nColNo+1 != nCurCol) || (nRowNo+1 != nCurRow) )
+ {
+ // SID_CURRENTCELL == Item #0 Cache leeren, damit das Setzen der
+ // aktuellen Zelle auch in zusammengefassten Bereichen funktioniert.
+ ppBoundItems[0]->ClearCache();
+
+ ScAddress aScAddress( nColNo, nRowNo, 0 );
+ String aAddr;
+ aScAddress.Format( aAddr, SCA_ABS );
+
+ BOOL bUnmark = FALSE;
+ if ( GetViewData() )
+ bUnmark = !pViewData->GetMarkData().IsCellMarked( nColNo, nRowNo );
+
+ SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
+ SfxBoolItem aUnmarkItem( FN_PARAM_1, bUnmark ); // ggf. Selektion aufheben
+
+ rBindings.GetDispatcher()->Execute( SID_CURRENTCELL,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
+ &aPosItem, &aUnmarkItem, 0L );
+ }
+}
+
+void ScNavigatorDlg::SetCurrentCellStr( const String rName )
+{
+ ppBoundItems[0]->ClearCache();
+ SfxStringItem aNameItem( SID_CURRENTCELL, rName );
+
+ rBindings.GetDispatcher()->Execute( SID_CURRENTCELL,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
+ &aNameItem, 0L );
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::SetCurrentTable( SCTAB nTabNo )
+{
+ if ( nTabNo != nCurTab )
+ {
+ // Tabelle fuer Basic ist 1-basiert
+ SfxUInt16Item aTabItem( SID_CURRENTTAB, static_cast<sal_uInt16>(nTabNo) + 1 );
+ rBindings.GetDispatcher()->Execute( SID_CURRENTTAB,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
+ &aTabItem, 0L );
+ }
+}
+
+void ScNavigatorDlg::SetCurrentTableStr( const String rName )
+{
+ if (!GetViewData()) return;
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nCount = pDoc->GetTableCount();
+ String aTabName;
+
+ for ( SCTAB i=0; i<nCount; i++ )
+ {
+ pDoc->GetName( i, aTabName );
+ if ( aTabName == rName )
+ {
+ SetCurrentTable( i );
+ return;
+ }
+ }
+
+ Sound::Beep(); // Tabelle nicht gefunden
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::SetCurrentObject( const String rName )
+{
+ SfxStringItem aNameItem( SID_CURRENTOBJECT, rName );
+ rBindings.GetDispatcher()->Execute( SID_CURRENTOBJECT,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
+ &aNameItem, 0L );
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::SetCurrentDoc( const String& rDocName ) // aktivieren
+{
+ SfxStringItem aDocItem( SID_CURRENTDOC, rDocName );
+ rBindings.GetDispatcher()->Execute( SID_CURRENTDOC,
+ SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
+ &aDocItem, 0L );
+}
+
+//------------------------------------------------------------------------
+
+ScTabViewShell* ScNavigatorDlg::GetTabViewShell() const
+{
+ return PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+}
+
+//------------------------------------------------------------------------
+
+ScNavigatorSettings* ScNavigatorDlg::GetNavigatorSettings()
+{
+ // #95791# Don't store the settings pointer here, because the settings belong to
+ // the view, and the view may be closed while the navigator is open (reload).
+ // If the pointer is cached here again later for performance reasons, it has to
+ // be forgotten when the view is closed.
+
+ ScTabViewShell* pViewSh = GetTabViewShell();
+ return pViewSh ? pViewSh->GetNavigatorSettings() : NULL;
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScNavigatorDlg::GetViewData()
+{
+ ScTabViewShell* pViewSh = GetTabViewShell();
+ pViewData = pViewSh ? pViewSh->GetViewData() : NULL;
+
+ return ( pViewData != NULL );
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::UpdateColumn( const SCCOL* pCol )
+{
+ if ( pCol )
+ nCurCol = *pCol;
+ else if ( GetViewData() )
+ nCurCol = pViewData->GetCurX() + 1;
+
+ aEdCol.SetCol( nCurCol );
+ CheckDataArea();
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
+{
+ if ( pRow )
+ nCurRow = *pRow;
+ else if ( GetViewData() )
+ nCurRow = pViewData->GetCurY() + 1;
+
+ aEdRow.SetRow( nCurRow );
+ CheckDataArea();
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::UpdateTable( const SCTAB* pTab )
+{
+ if ( pTab )
+ nCurTab = *pTab;
+ else if ( GetViewData() )
+ nCurTab = pViewData->GetTabNo();
+
+// aLbTables.SetTab( nCurTab );
+ CheckDataArea();
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::UpdateAll()
+{
+ switch ( eListMode )
+ {
+ case NAV_LMODE_DOCS:
+ case NAV_LMODE_DBAREAS:
+ case NAV_LMODE_AREAS:
+ aLbEntries.Refresh();
+ break;
+
+ case NAV_LMODE_NONE:
+ //! ???
+ break;
+
+ default:
+ break;
+ }
+
+ aContentTimer.Stop(); // dann nicht nochmal
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::SetListMode( NavListMode eMode, BOOL bSetSize )
+{
+ if ( eMode != eListMode )
+ {
+ if ( eMode != NAV_LMODE_NONE )
+ bFirstBig = FALSE; // nicht mehr automatisch umschalten
+
+ eListMode = eMode;
+
+ switch ( eMode )
+ {
+ case NAV_LMODE_NONE:
+ ShowList( FALSE, bSetSize );
+ break;
+
+ case NAV_LMODE_AREAS:
+ case NAV_LMODE_DBAREAS:
+ case NAV_LMODE_DOCS:
+ aLbEntries.Refresh();
+ ShowList( TRUE, bSetSize );
+ break;
+
+ case NAV_LMODE_SCENARIOS:
+ ShowScenarios( TRUE, bSetSize );
+ break;
+ }
+
+ aTbxCmd.UpdateButtons();
+
+ if ( eMode != NAV_LMODE_NONE )
+ {
+ ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
+ rCfg.SetListMode( (USHORT) eMode );
+ }
+ }
+
+ if ( pMarkArea )
+ UnmarkDataArea();
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::ShowList( BOOL bShow, BOOL bSetSize )
+{
+ FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
+ Size aSize = GetParent()->GetOutputSizePixel();
+
+ if ( bShow )
+ {
+ Size aMinSize = aInitSize;
+
+ aMinSize.Height() += nInitListHeight;
+ if ( pFloat )
+ pFloat->SetMinOutputSizePixel( aMinSize );
+ aSize.Height() = nListModeHeight;
+ aLbEntries.Show();
+ aLbDocuments.Show();
+ }
+ else
+ {
+ if ( pFloat )
+ {
+ pFloat->SetMinOutputSizePixel( aInitSize );
+ nListModeHeight = aSize.Height();
+ }
+ aSize.Height() = aInitSize.Height();
+ aLbEntries.Hide();
+ aLbDocuments.Hide();
+ }
+ aWndScenarios.Hide();
+
+ if ( pFloat )
+ {
+ if ( bSetSize )
+ pFloat->SetOutputSizePixel( aSize );
+ }
+ else
+ {
+ SfxNavigator* pNav = (SfxNavigator*)GetParent();
+ Size aFloating = pNav->GetFloatingSize();
+ aFloating.Height() = aSize.Height();
+ pNav->SetFloatingSize( aFloating );
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::ShowScenarios( BOOL bShow, BOOL bSetSize )
+{
+ FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
+ Size aSize = GetParent()->GetOutputSizePixel();
+
+ if ( bShow )
+ {
+ Size aMinSize = aInitSize;
+ aMinSize.Height() += nInitListHeight;
+ if ( pFloat )
+ pFloat->SetMinOutputSizePixel( aMinSize );
+ aSize.Height() = nListModeHeight;
+
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Update( SID_SELECT_SCENARIO );
+
+ aWndScenarios.Show();
+ aLbDocuments.Show();
+ }
+ else
+ {
+ if ( pFloat )
+ {
+ pFloat->SetMinOutputSizePixel( aInitSize );
+ nListModeHeight = aSize.Height();
+ }
+ aSize.Height() = aInitSize.Height();
+ aWndScenarios.Hide();
+ aLbDocuments.Hide();
+ }
+ aLbEntries.Hide();
+
+ if ( pFloat )
+ {
+ if ( bSetSize )
+ pFloat->SetOutputSizePixel( aSize );
+ }
+ else
+ {
+ SfxNavigator* pNav = (SfxNavigator*)GetParent();
+ Size aFloating = pNav->GetFloatingSize();
+ aFloating.Height() = aSize.Height();
+ pNav->SetFloatingSize( aFloating );
+ }
+}
+
+
+//------------------------------------------------------------------------
+//
+// Dokumente fuer Dropdown-Listbox
+//
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::GetDocNames( const String* pManualSel )
+{
+ aLbDocuments.Clear();
+ aLbDocuments.SetUpdateMode( FALSE );
+
+ ScDocShell* pCurrentSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
+
+ String aSelEntry;
+ SfxObjectShell* pSh = SfxObjectShell::GetFirst();
+ while ( pSh )
+ {
+ if ( pSh->ISA(ScDocShell) )
+ {
+ String aName = pSh->GetTitle();
+ String aEntry = aName;
+ if (pSh == pCurrentSh)
+ aEntry += aStrActive;
+ else
+ aEntry += aStrNotActive;
+ aLbDocuments.InsertEntry( aEntry );
+
+ if ( pManualSel ? ( aName == *pManualSel )
+ : ( pSh == pCurrentSh ) )
+ aSelEntry = aEntry; // kompletter Eintrag zum Selektieren
+ }
+
+ pSh = SfxObjectShell::GetNext( *pSh );
+ }
+
+ aLbDocuments.InsertEntry( aStrActiveWin );
+
+ String aHidden = aLbEntries.GetHiddenTitle();
+ if (aHidden.Len())
+ {
+ String aEntry = aHidden;
+ aEntry += aStrHidden;
+ aLbDocuments.InsertEntry( aEntry );
+
+ if ( pManualSel && aHidden == *pManualSel )
+ aSelEntry = aEntry;
+ }
+
+ aLbDocuments.SetUpdateMode( TRUE );
+
+ aLbDocuments.SelectEntry( aSelEntry );
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::MarkDataArea()
+{
+ ScTabViewShell* pViewSh = GetTabViewShell();
+
+ if ( pViewSh )
+ {
+ if ( !pMarkArea )
+ pMarkArea = new ScArea;
+
+ pViewSh->MarkDataArea();
+ ScRange aMarkRange;
+ pViewSh->GetViewData()->GetMarkData().GetMarkArea(aMarkRange);
+ pMarkArea->nColStart = aMarkRange.aStart.Col();
+ pMarkArea->nRowStart = aMarkRange.aStart.Row();
+ pMarkArea->nColEnd = aMarkRange.aEnd.Col();
+ pMarkArea->nRowEnd = aMarkRange.aEnd.Row();
+ pMarkArea->nTab = aMarkRange.aStart.Tab();
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::UnmarkDataArea()
+{
+ ScTabViewShell* pViewSh = GetTabViewShell();
+
+ if ( pViewSh )
+ {
+ pViewSh->Unmark();
+ DELETEZ( pMarkArea );
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::CheckDataArea()
+{
+ if ( aTbxCmd.IsItemChecked( IID_DATA ) && pMarkArea )
+ {
+ if ( nCurTab != pMarkArea->nTab
+ || nCurCol < pMarkArea->nColStart+1
+ || nCurCol > pMarkArea->nColEnd+1
+ || nCurRow < pMarkArea->nRowStart+1
+ || nCurRow > pMarkArea->nRowEnd+1 )
+ {
+ aTbxCmd.SetItemState( IID_DATA, TriState(STATE_CHECK) );
+ aTbxCmd.Select( IID_DATA );
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::StartOfDataArea()
+{
+ // pMarkArea auswerten ???
+
+ if ( GetViewData() )
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+
+ SCCOL nCol = aMarkRange.aStart.Col();
+ SCROW nRow = aMarkRange.aStart.Row();
+
+ if ( (nCol+1 != aEdCol.GetCol()) || (nRow+1 != aEdRow.GetRow()) )
+ SetCurrentCell( nCol, nRow );
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScNavigatorDlg::EndOfDataArea()
+{
+ // pMarkArea auswerten ???
+
+ if ( GetViewData() )
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+
+ SCCOL nCol = aMarkRange.aEnd.Col();
+ SCROW nRow = aMarkRange.aEnd.Row();
+
+ if ( (nCol+1 != aEdCol.GetCol()) || (nRow+1 != aEdRow.GetRow()) )
+ SetCurrentCell( nCol, nRow );
+ }
+}
+
+//------------------------------------------------------------------------
+
+SfxChildAlignment __EXPORT ScNavigatorDlg::CheckAlignment(
+ SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
+{
+ SfxChildAlignment eRetAlign;
+
+ //! kein Andocken, wenn Listbox nicht da ???
+
+ switch (eAlign)
+ {
+ case SFX_ALIGN_TOP:
+ case SFX_ALIGN_HIGHESTTOP:
+ case SFX_ALIGN_LOWESTTOP:
+ case SFX_ALIGN_BOTTOM:
+ case SFX_ALIGN_LOWESTBOTTOM:
+ case SFX_ALIGN_HIGHESTBOTTOM:
+ eRetAlign = eActAlign; // nicht erlaubt
+ break;
+
+ case SFX_ALIGN_LEFT:
+ case SFX_ALIGN_RIGHT:
+ case SFX_ALIGN_FIRSTLEFT:
+ case SFX_ALIGN_LASTLEFT:
+ case SFX_ALIGN_FIRSTRIGHT:
+ case SFX_ALIGN_LASTRIGHT:
+ eRetAlign = eAlign; // erlaubt
+ break;
+
+ default:
+ eRetAlign = eAlign;
+ break;
+ }
+ return eRetAlign;
+}
+
+//------------------------------------------------------------------------
+//
+// Drop auf den Navigator - andere Datei laden (File oder Bookmark)
+//
+//------------------------------------------------------------------------
+
+#if 0
+BOOL __EXPORT ScNavigatorDlg::Drop( const DropEvent& rEvt )
+{
+ BOOL bReturn = FALSE;
+
+ if ( !aLbEntries.IsInDrag() ) // kein Verschieben innerhalb der TreeListBox
+ {
+ String aFileName;
+
+ SvScDataObjectRef pObject = SvScDataObject::PasteDragServer(rEvt);
+
+ ULONG nFormat = INetBookmark::HasFormat(*pObject);
+ INetBookmark aBookmark;
+ if (aBookmark.Paste(*pObject,nFormat))
+ aFileName = aBookmark.GetURL();
+ else
+ {
+ // FORMAT_FILE direkt aus DragServer
+
+ USHORT nCount = DragServer::GetItemCount();
+ for ( USHORT i = 0; i < nCount && !aFileName.Len(); ++i )
+ if (DragServer::HasFormat( i, FORMAT_FILE ))
+ aFileName = DragServer::PasteFile( i );
+ }
+
+ if ( aFileName.Len() )
+ bReturn = aLbEntries.LoadFile( aFileName );
+ }
+ return bReturn;
+}
+
+BOOL __EXPORT ScNavigatorDlg::QueryDrop( DropEvent& rEvt )
+{
+ BOOL bReturn = FALSE;
+
+ if ( !aLbEntries.IsInDrag() ) // kein Verschieben innerhalb der TreeListBox
+ {
+ SvScDataObjectRef pObject = SvScDataObject::PasteDragServer(rEvt);
+ if ( pObject->HasFormat(FORMAT_FILE)
+ || INetBookmark::HasFormat(*pObject) )
+ {
+ rEvt.SetAction(DROP_COPY); // Kopier-Cursor anzeigen
+ bReturn = TRUE;
+ }
+ }
+
+ return bReturn;
+}
+#endif
+
+
+
diff --git a/sc/source/ui/navipi/navipi.hrc b/sc/source/ui/navipi/navipi.hrc
new file mode 100644
index 000000000000..0adb65a5a042
--- /dev/null
+++ b/sc/source/ui/navipi/navipi.hrc
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc"
+
+//#define RID_SCDLG_NAVIGATOR 256
+
+#define FT_ROW 1
+#define ED_ROW 2
+#define FT_COL 3
+#define ED_COL 4
+#define LB_DOCUMENTS 5
+#define LB_ENTRIES 6
+#define TBX_CMD 7
+#define STR_DRAGMODE 8
+#define STR_DISPLAY 9
+#define STR_ACTIVE 10
+#define STR_NOTACTIVE 11
+#define STR_HIDDEN 12
+#define STR_ACTIVEWIN 13
+//#define IMG_ENTRIES 14
+#define STR_QHLP_SCEN_LISTBOX 15
+#define STR_QHLP_SCEN_COMMENT 16
+#define IL_CMD 17
+#define ILH_CMD 18
+
+
+
+#define IID_AREAS 1
+#define IID_DBAREAS 2
+#define IID_DATA 3
+#define IID_DOCS 4
+#define IID_UP 5
+#define IID_DOWN 6
+#define IID_SCENARIOS 7
+#define IID_DROPMODE 9
+#define IID_CHANGEROOT 10
+#define IID_ZOOMOUT 11
+
+
diff --git a/sc/source/ui/navipi/navipi.src b/sc/source/ui/navipi/navipi.src
new file mode 100644
index 000000000000..c2e9ecb6a4e6
--- /dev/null
+++ b/sc/source/ui/navipi/navipi.src
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "navipi.hrc"
+
+#define SC_NAVI_CMD_IDLIST \
+ IdList = \
+ { \
+ IID_DATA ; \
+ IID_UP ; \
+ IID_DOWN ; \
+ IID_SCENARIOS ; \
+ IID_DROPMODE ; \
+ IID_CHANGEROOT ; \
+ IID_ZOOMOUT ; \
+ }; \
+ IdCount = { 8 ; };
+
+// SC_CONTENT_...
+#define SC_NAVI_CONT_IDLIST \
+ IdList = \
+ { \
+ 1 ; \
+ 2 ; \
+ 3 ; \
+ 4 ; \
+ 5 ; \
+ 6 ; \
+ 7 ; \
+ 8 ; \
+ }; \
+ IdCount = { 8 ; };
+
+Window RID_SCDLG_NAVIGATOR
+{
+ SVLook = TRUE ;
+ HelpId = HID_SC_NAVIGATOR ;
+ //? Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT ( 115 , 116 ) ;
+ OutputSize = TRUE ;
+ DialogControl = TRUE ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Navigator" ;
+ // Closeable = TRUE ;
+ // Moveable = TRUE ;
+ // Zoomable = TRUE ;
+ // Sizeable = TRUE ;
+ // EnableResizing = TRUE ;
+ // HideWhenDeactivate = TRUE ;
+ // Border = TRUE ;
+ // Dockable = TRUE ;
+ FixedText FT_ROW
+ {
+ // Pos = MAP_APPFONT( 2, 20 );
+ Pos = MAP_APPFONT ( 2 , 19 ) ;
+ // an kleinere Toolbox-Bitmaps angepasst
+ Size = MAP_APPFONT ( 19 , 10 ) ;
+ Text [ en-US ] = "Row" ;
+ };
+ NumericField ED_ROW
+ {
+ HelpId = HID_SC_NAVIPI_ROW ;
+ Border = TRUE ;
+ // Pos = MAP_APPFONT( 31, 19 );
+ Pos = MAP_APPFONT ( 31 , 18 ) ;
+ // an kleinere Toolbox-Bitmaps angepasst
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ Right = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Minimum = 1 ;
+ First = 1 ;
+ QuickHelpText [ en-US ] = "Row" ;
+ };
+ FixedText FT_COL
+ {
+ Pos = MAP_APPFONT ( 2 , 5 ) ;
+ Size = MAP_APPFONT ( 23 , 10 ) ;
+ Text [ en-US ] = "Column" ;
+ };
+ SpinField ED_COL
+ {
+ HelpId = HID_SC_NAVIPI_COL ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 31 , 4 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ Right = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ QuickHelpText [ en-US ] = "Column" ;
+ };
+ Control LB_ENTRIES
+ {
+ // "Control" braucht immer eigene HelpId
+ HelpId = HID_SC_NAVIPI_ENTRIES ;
+ Border = TRUE ;
+ // Pos = MAP_APPFONT( 2, 52 );
+ Pos = MAP_APPFONT ( 2 , 35 ) ;
+ Size = MAP_APPFONT ( 110 , 100 ) ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_DOCUMENTS
+ {
+ HelpId = HID_SC_NAVIPI_DOC ;
+ Border = TRUE ;
+ // Pos = MAP_APPFONT( 2, 35 );
+ Pos = MAP_APPFONT ( 2 , 89 ) ;
+ Size = MAP_APPFONT ( 82 , 50 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ QuickHelpText [ en-US ] = "Document" ;
+ };
+ ImageList IL_CMD
+ {
+ Prefix = "na";
+ MaskColor = STD_MASKCOLOR ;
+ SC_NAVI_CMD_IDLIST
+ };
+ ImageList ILH_CMD
+ {
+ Prefix = "nah";
+ MaskColor = SC_HC_MASKCOLOR ;
+ SC_NAVI_CMD_IDLIST
+ };
+ ToolBox TBX_CMD
+ {
+ Pos = MAP_APPFONT ( 66 , 3 ) ;
+ HelpId = HID_SC_NAVIPI_TOOLBOX ;
+ SVLook = TRUE ;
+ Border = FALSE ;
+ LineCount = 2 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = IID_DATA ;
+ HelpId = HID_SC_NAVIPI_DATA ;
+ Text [ en-US ] = "Data Range" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = IID_UP ;
+ HelpId = HID_SC_NAVIPI_UP ;
+ Text [ en-US ] = "Start" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = IID_DOWN ;
+ HelpId = HID_SC_NAVIPI_DOWN ;
+ Text [ en-US ] = "End" ;
+ };
+ //--------------------------------------------
+ // ToolBoxItem { Type = TOOLBOXITEM_SEPARATOR; };
+ //--------------------------------------------
+ //----------------------------------------
+ ToolBoxItem { Type = TOOLBOXITEM_BREAK ; };
+ //----------------------------------------
+ ToolBoxItem
+ {
+ Identifier = IID_ZOOMOUT ;
+ HelpId = HID_SC_NAVIPI_ZOOM ;
+ Text [ en-US ] = "Contents" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = IID_CHANGEROOT ;
+ HelpId = HID_SC_NAVIPI_ROOT ;
+ Text [ en-US ] = "Toggle" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = IID_SCENARIOS ;
+ HelpId = HID_SC_NAVIPI_SCEN ;
+ Text [ en-US ] = "Scenarios" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = IID_DROPMODE ;
+ HelpId = HID_SC_NAVIPI_DROP ;
+ DropDown = TRUE ;
+ Text [ en-US ] = "Drag Mode" ;
+ };
+ };
+ };
+ String STR_DRAGMODE
+ {
+ Text [ en-US ] = "Drag Mode" ;
+ };
+ String STR_DISPLAY
+ {
+ Text [ en-US ] = "Display" ;
+ };
+ String STR_ACTIVE
+ {
+ Text [ en-US ] = "active" ;
+ };
+ String STR_NOTACTIVE
+ {
+ Text [ en-US ] = "inactive" ;
+ };
+ String STR_HIDDEN
+ {
+ Text [ en-US ] = "hidden" ;
+ };
+ String STR_ACTIVEWIN
+ {
+ Text [ en-US ] = "Active Window" ;
+ };
+
+ String STR_QHLP_SCEN_LISTBOX
+ {
+ Text [ en-US ] = "Scenario Name";
+ };
+
+ String STR_QHLP_SCEN_COMMENT
+ {
+ Text [ en-US ] = "Comment";
+ };
+
+};
+
+
+ImageList RID_IMAGELIST_NAVCONT
+{
+ Prefix = "nc";
+ MaskColor = STD_MASKCOLOR ;
+ SC_NAVI_CONT_IDLIST
+};
+ImageList RID_IMAGELIST_H_NAVCONT
+{
+ Prefix = "nch";
+ MaskColor = SC_HC_MASKCOLOR ;
+ SC_NAVI_CONT_IDLIST
+};
+
+Image RID_IMG_DROP_URL
+{
+ ImageBitmap = Bitmap { File = "dropurl.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+};
+Image RID_IMG_DROP_LINK
+{
+ ImageBitmap = Bitmap { File = "droplink.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+};
+Image RID_IMG_DROP_COPY
+{
+ ImageBitmap = Bitmap { File = "dropcopy.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+};
+Image RID_IMG_H_DROP_URL
+{
+ ImageBitmap = Bitmap { File = "dropurl_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR ;
+};
+Image RID_IMG_H_DROP_LINK
+{
+ ImageBitmap = Bitmap { File = "droplink_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR ;
+};
+Image RID_IMG_H_DROP_COPY
+{
+ ImageBitmap = Bitmap { File = "dropcopy_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR ;
+};
+
+// content description strings are also used in ScLinkTargetsObj
+
+String SCSTR_CONTENT_ROOT
+{
+ Text [ en-US ] = "Contents" ;
+};
+String SCSTR_CONTENT_TABLE
+{
+ Text [ en-US ] = "Sheets" ;
+};
+String SCSTR_CONTENT_RANGENAME
+{
+ Text [ en-US ] = "Range names" ;
+};
+String SCSTR_CONTENT_DBAREA
+{
+ Text [ en-US ] = "Database Ranges" ;
+};
+String SCSTR_CONTENT_GRAPHIC
+{
+ Text [ en-US ] = "Graphics" ;
+};
+String SCSTR_CONTENT_OLEOBJECT
+{
+ Text [ en-US ] = "OLE objects" ;
+};
+String SCSTR_CONTENT_NOTE
+{
+ Text [ en-US ] = "Comments" ;
+};
+String SCSTR_CONTENT_AREALINK
+{
+ Text [ en-US ] = "Linked areas" ;
+};
+String SCSTR_CONTENT_DRAWING
+{
+ Text [ en-US ] = "Drawing objects";
+};
+ // PopupMenu -------------------------------------------------------------
+Menu RID_POPUP_DROPMODE
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_DROPMODE_URL ;
+ HelpId = HID_SC_DROPMODE_URL ;
+ Text [ en-US ] = "Insert as Hyperlink" ;
+ };
+ MenuItem
+ {
+ Identifier = RID_DROPMODE_LINK ;
+ HelpId = HID_SC_DROPMODE_LINK ;
+ Text [ en-US ] = "Insert as Link" ;
+ };
+ MenuItem
+ {
+ Identifier = RID_DROPMODE_COPY ;
+ HelpId = HID_SC_DROPMODE_COPY ;
+ Text [ en-US ] = "Insert as Copy" ;
+ };
+ };
+};
+Menu RID_POPUP_NAVIPI_SCENARIO
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_NAVIPI_SCENARIO_DELETE ;
+ HelpId = HID_SC_SCENARIO_DELETE ;
+ Text [ en-US ] = "Delete" ;
+ };
+ MenuItem
+ {
+ Identifier = RID_NAVIPI_SCENARIO_EDIT ;
+ HelpId = HID_SC_SCENARIO_EDIT ;
+ Text [ en-US ] = "Properties..." ;
+ };
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/navipi/scenwnd.cxx b/sc/source/ui/navipi/scenwnd.cxx
new file mode 100644
index 000000000000..e7dff0bf37c7
--- /dev/null
+++ b/sc/source/ui/navipi/scenwnd.cxx
@@ -0,0 +1,309 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include "navipi.hxx"
+#include "popmenu.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+
+//========================================================================
+// class ScScenarioWindow ------------------------------------------------
+//========================================================================
+
+ScScenarioListBox::ScScenarioListBox( ScScenarioWindow& rParent ) :
+ ListBox( &rParent, WB_BORDER | WB_TABSTOP ),
+ mrParent( rParent )
+{
+ Font aFont( GetFont() );
+ aFont.SetTransparent( TRUE );
+ aFont.SetWeight( WEIGHT_LIGHT );
+ SetFont( aFont );
+}
+
+ScScenarioListBox::~ScScenarioListBox()
+{
+}
+
+void ScScenarioListBox::UpdateEntries( List* pNewEntryList )
+{
+ Clear();
+ maEntries.clear();
+
+ if( !pNewEntryList )
+ return;
+
+ switch( pNewEntryList->Count() )
+ {
+ case 0:
+ // no scenarios in current sheet
+ mrParent.SetComment( EMPTY_STRING );
+ break;
+
+ case 1:
+ // sheet is a scenario container, comment only
+ mrParent.SetComment( *static_cast< String* >( pNewEntryList->First() ) );
+ break;
+
+ default:
+ {
+ // sheet contains scenarios
+ DBG_ASSERT( pNewEntryList->Count() % 3 == 0, "ScScenarioListBox::UpdateEntries - wrong list size" );
+ SetUpdateMode( FALSE );
+ String* pEntry = static_cast< String* >( pNewEntryList->First() );
+ while( pEntry )
+ {
+ ScenarioEntry aEntry;
+
+ // first entry of a triple is the scenario name
+ aEntry.maName = *pEntry;
+ // second entry of a triple is the scenario comment
+ if( (pEntry = static_cast< String* >( pNewEntryList->Next() )) != 0 )
+ aEntry.maComment = *pEntry;
+ // third entry of a triple is the protection ("0" = not protected, "1" = protected)
+ if( (pEntry = static_cast< String* >( pNewEntryList->Next() )) != 0 )
+ aEntry.mbProtected = (pEntry->Len() > 0) && (pEntry->GetChar( 0 ) != '0');
+
+ maEntries.push_back( aEntry );
+ InsertEntry( aEntry.maName, LISTBOX_APPEND );
+ pEntry = static_cast< String* >( pNewEntryList->Next() );
+ }
+ SetUpdateMode( TRUE );
+ SetNoSelection();
+ mrParent.SetComment( EMPTY_STRING );
+ }
+ }
+}
+
+void ScScenarioListBox::Select()
+{
+ if( const ScenarioEntry* pEntry = GetSelectedEntry() )
+ mrParent.SetComment( pEntry->maComment );
+}
+
+void ScScenarioListBox::DoubleClick()
+{
+ SelectScenario();
+}
+
+long ScScenarioListBox::Notify( NotifyEvent& rNEvt )
+{
+ bool bHandled = false;
+
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ KeyCode aCode = rNEvt.GetKeyEvent()->GetKeyCode();
+ switch( aCode.GetCode() )
+ {
+ case KEY_RETURN:
+ SelectScenario();
+ bHandled = true;
+ break;
+ case KEY_DELETE:
+ DeleteScenario( true );
+ bHandled = true;
+ break;
+ }
+ }
+ else if ( rNEvt.GetType() == EVENT_COMMAND && GetSelectEntryCount() )
+ {
+ const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
+ if ( pCEvt && pCEvt->GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ if( const ScenarioEntry* pEntry = GetSelectedEntry() )
+ {
+ if( !pEntry->mbProtected )
+ {
+ ScPopupMenu aPopup( ScResId( RID_POPUP_NAVIPI_SCENARIO ) );
+ aPopup.Execute( this, pCEvt->GetMousePosPixel() );
+ if (aPopup.WasHit())
+ {
+ switch( aPopup.GetSelected() )
+ {
+ case RID_NAVIPI_SCENARIO_DELETE:
+ DeleteScenario( true );
+ break;
+ case RID_NAVIPI_SCENARIO_EDIT:
+ EditScenario();
+ break;
+ }
+ }
+ }
+ }
+ bHandled = true;
+ }
+ }
+
+ return bHandled ? 1 : ListBox::Notify( rNEvt );
+}
+
+const ScScenarioListBox::ScenarioEntry* ScScenarioListBox::GetSelectedEntry() const
+{
+ size_t nPos = GetSelectEntryPos();
+ return (nPos < maEntries.size()) ? &maEntries[ nPos ] : 0;
+}
+
+void ScScenarioListBox::ExecuteScenarioSlot( USHORT nSlotId )
+{
+ if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() )
+ {
+ SfxStringItem aStringItem( nSlotId, GetSelectEntry() );
+ pViewFrm->GetDispatcher()->Execute( nSlotId, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aStringItem, 0L, 0L );
+ }
+}
+
+void ScScenarioListBox::SelectScenario()
+{
+ if( GetSelectEntryCount() > 0 )
+ ExecuteScenarioSlot( SID_SELECT_SCENARIO );
+}
+
+void ScScenarioListBox::EditScenario()
+{
+ if( GetSelectEntryCount() > 0 )
+ ExecuteScenarioSlot( SID_EDIT_SCENARIO );
+}
+
+void ScScenarioListBox::DeleteScenario( bool bQueryBox )
+{
+ if( GetSelectEntryCount() > 0 )
+ if( !bQueryBox || (::QueryBox( 0, WinBits( WB_YES_NO | WB_DEF_YES ), ScGlobal::GetRscString( STR_QUERY_DELSCENARIO ) ).Execute() == RET_YES) )
+ ExecuteScenarioSlot( SID_DELETE_SCENARIO );
+}
+
+//========================================================================
+// class ScScenarioWindow ------------------------------------------------
+//========================================================================
+
+ScScenarioWindow::ScScenarioWindow( Window* pParent,const String& aQH_List,
+ const String& aQH_Comment)
+ : Window ( pParent, WB_TABSTOP | WB_DIALOGCONTROL ),
+ aLbScenario ( *this ),
+ aEdComment ( this, WB_BORDER | WB_LEFT | WB_READONLY | WB_VSCROLL | WB_TABSTOP )
+{
+ Font aFont( GetFont() );
+ aFont.SetTransparent( TRUE );
+ aFont.SetWeight( WEIGHT_LIGHT );
+ aEdComment.SetFont( aFont );
+ aEdComment.SetMaxTextLen( 512 );
+ aLbScenario.SetPosPixel( Point(0,0) );
+ aLbScenario.SetHelpId(HID_SC_SCENWIN_TOP);
+ aEdComment.SetHelpId(HID_SC_SCENWIN_BOTTOM);
+ aLbScenario.Show();
+ aEdComment.Show();
+
+ aLbScenario.SetQuickHelpText(aQH_List);
+ aEdComment.SetQuickHelpText(aQH_Comment);
+ aEdComment.SetBackground( Color( COL_LIGHTGRAY ) );
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (pViewFrm)
+ {
+ SfxBindings& rBindings = pViewFrm->GetBindings();
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Update( SID_SELECT_SCENARIO );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScScenarioWindow::~ScScenarioWindow()
+{
+}
+
+void ScScenarioWindow::Paint( const Rectangle& rRec )
+{
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aBgColor = rStyleSettings.GetFaceColor();
+
+ SetBackground( aBgColor );
+
+ Window::Paint( rRec );
+}
+
+// -----------------------------------------------------------------------
+
+void ScScenarioWindow::NotifyState( const SfxPoolItem* pState )
+{
+ if( pState )
+ {
+ aLbScenario.Enable();
+
+ if ( pState->ISA(SfxStringItem) )
+ {
+ String aNewEntry( ((const SfxStringItem*)pState)->GetValue() );
+
+ if ( aNewEntry.Len() > 0 )
+ aLbScenario.SelectEntry( aNewEntry );
+ else
+ aLbScenario.SetNoSelection();
+ }
+ else if ( pState->ISA(SfxStringListItem) )
+ {
+ aLbScenario.UpdateEntries( ((SfxStringListItem*)pState)->GetList() );
+ }
+ }
+ else
+ {
+ aLbScenario.Disable();
+ aLbScenario.SetNoSelection();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScScenarioWindow::SetSizePixel( const Size& rNewSize )
+{
+ Size aSize( rNewSize );
+ long nHeight = aSize.Height() / 2;
+
+ Window::SetSizePixel( aSize );
+
+ aSize.Height() = nHeight;
+ aLbScenario.SetSizePixel( aSize );
+
+ aSize.Height() -= 4;
+ aEdComment.SetPosSizePixel( Point( 0, nHeight+4 ), aSize );
+}
+
+
+
+
diff --git a/sc/source/ui/optdlg/makefile.mk b/sc/source/ui/optdlg/makefile.mk
new file mode 100644
index 000000000000..52df7072ecf8
--- /dev/null
+++ b/sc/source/ui/optdlg/makefile.mk
@@ -0,0 +1,59 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=optdlg
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ tpusrlst.cxx \
+ tpview.cxx \
+ tpcalc.cxx \
+ tpprint.cxx \
+ opredlin.cxx
+
+SLOFILES = \
+ $(SLO)$/tpusrlst.obj \
+ $(SLO)$/tpview.obj \
+ $(SLO)$/tpcalc.obj \
+ $(SLO)$/tpprint.obj \
+ $(SLO)$/opredlin.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/optdlg/opredlin.cxx b/sc/source/ui/optdlg/opredlin.cxx
new file mode 100644
index 000000000000..1a45ab715dee
--- /dev/null
+++ b/sc/source/ui/optdlg/opredlin.cxx
@@ -0,0 +1,289 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <svx/dlgutil.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xtable.hxx>
+
+#include "appoptio.hxx"
+#include "scmod.hxx"
+#include "scitems.hxx"
+#include "tpview.hxx"
+#include "global.hxx"
+#include "viewopti.hxx"
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "scresid.hxx"
+#include "docsh.hxx"
+#include "sc.hrc" // -> Slot-IDs
+#include "optdlg.hrc"
+#include "globstr.hrc"
+
+#include "opredlin.hxx"
+#include "opredlin.hrc"
+
+//------------------------------------------------------------------
+
+ScRedlineOptionsTabPage::ScRedlineOptionsTabPage( Window* pParent,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pParent, ScResId(RID_SCPAGE_OPREDLINE), rSet),
+ aContentFT ( this, ScResId(FT_CONTENT )),
+ aContentColorLB ( this, ScResId(CLB_CONTENT )),
+ aRemoveFT ( this, ScResId(FT_REMOVE )),
+ aRemoveColorLB ( this, ScResId(CLB_REMOVE )),
+ aInsertFT ( this, ScResId(FT_INSERT )),
+ aInsertColorLB ( this, ScResId(CLB_INSERT )),
+ aMoveFT ( this, ScResId(FT_MOVE )),
+ aMoveColorLB ( this, ScResId(CLB_MOVE )),
+ aChangedGB ( this, ScResId(GB_COLORCHGS)),
+ aAuthorStr (ScResId(STR_AUTHOR))
+{
+ FreeResource();
+
+ Link aLk = LINK(this, ScRedlineOptionsTabPage, ColorHdl);
+ aContentColorLB.SetSelectHdl( aLk );
+ aMoveColorLB.SetSelectHdl( aLk );
+ aInsertColorLB.SetSelectHdl( aLk );
+ aRemoveColorLB.SetSelectHdl( aLk );
+}
+
+/*-----------------------------------------------------------------------
+ Beschreibung:
+ -----------------------------------------------------------------------*/
+
+__EXPORT ScRedlineOptionsTabPage::~ScRedlineOptionsTabPage()
+{
+}
+
+/*-----------------------------------------------------------------------
+ Beschreibung:
+ -----------------------------------------------------------------------*/
+
+SfxTabPage* __EXPORT ScRedlineOptionsTabPage::Create( Window* pParent, const SfxItemSet& rSet )
+{
+ return new ScRedlineOptionsTabPage( pParent, rSet );
+}
+
+/*-----------------------------------------------------------------------
+ Beschreibung:
+ -----------------------------------------------------------------------*/
+
+BOOL __EXPORT ScRedlineOptionsTabPage::FillItemSet( SfxItemSet& /* rSet */ )
+{
+ ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
+
+ ULONG nNew=0;
+ USHORT nPos=0;
+
+ nPos = aContentColorLB.GetSelectEntryPos();
+ if (nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ nPos = aContentColorLB.GetSelectEntryPos();
+ if (nPos!=0)
+ nNew= aContentColorLB.GetEntryColor(nPos).GetColor();
+ else
+ nNew= COL_TRANSPARENT;
+
+ aAppOptions.SetTrackContentColor(nNew);
+
+ }
+ nPos = aMoveColorLB.GetSelectEntryPos();
+ if (nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ nPos = aMoveColorLB.GetSelectEntryPos();
+ if (nPos!=0)
+ nNew= aMoveColorLB.GetEntryColor(nPos).GetColor();
+ else
+ nNew= COL_TRANSPARENT;
+
+ aAppOptions.SetTrackMoveColor(nNew);
+
+ }
+ nPos = aInsertColorLB.GetSelectEntryPos();
+ if (nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ nPos = aInsertColorLB.GetSelectEntryPos();
+ if (nPos!=0)
+ nNew= aInsertColorLB.GetEntryColor(nPos).GetColor();
+ else
+ nNew= COL_TRANSPARENT;
+
+ aAppOptions.SetTrackInsertColor(nNew);
+
+ }
+ nPos = aRemoveColorLB.GetSelectEntryPos();
+ if (nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ nPos = aRemoveColorLB.GetSelectEntryPos();
+ if (nPos!=0)
+ nNew= aRemoveColorLB.GetEntryColor(nPos).GetColor();
+ else
+ nNew= COL_TRANSPARENT;
+
+ aAppOptions.SetTrackDeleteColor(nNew);
+
+ }
+
+ SC_MOD()->SetAppOptions(aAppOptions);
+
+ // Repaint (wenn alles ueber Items laufen wuerde, wie es sich gehoert,
+ // waere das nicht noetig...)
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current());
+ if (pDocSh)
+ pDocSh->PostPaintGridAll();
+
+ return FALSE;
+}
+
+/*-----------------------------------------------------------------------
+ Beschreibung:
+ -----------------------------------------------------------------------*/
+
+void __EXPORT ScRedlineOptionsTabPage::Reset( const SfxItemSet& /* rSet */ )
+{
+
+ XColorTable* pColorTbl = XColorTable::GetStdColorTable();
+ aContentColorLB.InsertEntry(aAuthorStr);
+ aMoveColorLB.InsertEntry(aAuthorStr);
+ aInsertColorLB.InsertEntry(aAuthorStr);
+ aRemoveColorLB.InsertEntry(aAuthorStr);
+
+ aContentColorLB.SetUpdateMode( FALSE);
+ aMoveColorLB.SetUpdateMode( FALSE);
+ aInsertColorLB.SetUpdateMode( FALSE);
+ aRemoveColorLB.SetUpdateMode( FALSE);
+
+ for( USHORT i = 0; i < pColorTbl->Count(); ++i )
+ {
+ XColorEntry* pEntry = pColorTbl->GetColor( i );
+ Color aColor = pEntry->GetColor();
+ String sName = pEntry->GetName();
+
+ aContentColorLB.InsertEntry( aColor, sName );
+ aMoveColorLB.InsertEntry( aColor, sName );
+ aInsertColorLB.InsertEntry( aColor, sName );
+ aRemoveColorLB.InsertEntry( aColor, sName );
+ }
+ aContentColorLB.SetUpdateMode( TRUE );
+ aMoveColorLB.SetUpdateMode( TRUE );
+ aInsertColorLB.SetUpdateMode( TRUE );
+ aRemoveColorLB.SetUpdateMode( TRUE );
+
+
+ ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
+
+ ULONG nColor = aAppOptions.GetTrackContentColor();
+ if (nColor == COL_TRANSPARENT)
+ aContentColorLB.SelectEntryPos(0);
+ else
+ aContentColorLB.SelectEntry(Color(nColor));
+
+ nColor = aAppOptions.GetTrackMoveColor();
+ if (nColor == COL_TRANSPARENT)
+ aMoveColorLB.SelectEntryPos(0);
+ else
+ aMoveColorLB.SelectEntry(Color(nColor));
+
+
+ nColor = aAppOptions.GetTrackInsertColor();
+ if (nColor == COL_TRANSPARENT)
+ aInsertColorLB.SelectEntryPos(0);
+ else
+ aInsertColorLB.SelectEntry(Color(nColor));
+
+
+ nColor = aAppOptions.GetTrackDeleteColor();
+ if (nColor == COL_TRANSPARENT)
+ aRemoveColorLB.SelectEntryPos(0);
+ else
+ aRemoveColorLB.SelectEntry(Color(nColor));
+
+}
+
+
+IMPL_LINK( ScRedlineOptionsTabPage, ColorHdl, ColorListBox *, EMPTYARG )
+{
+/*
+ SvxFontPrevWindow *pPrev;
+ ListBox *pLB;
+
+ if (pColorLB == &aInsertColorLB)
+ {
+ pPrev = &aInsertPreviewWN;
+ pLB = &aInsertLB;
+ }
+ else
+ {
+ pPrev = &aDeletedPreviewWN;
+ pLB = &aDeletedLB;
+ }
+
+ SvxFont& rFont = pPrev->GetFont();
+ USHORT nPos = pLB->GetSelectEntryPos();
+ if (nPos == LISTBOX_ENTRY_NOTFOUND)
+ nPos = 0;
+
+ CharAttr *pAttr = (CharAttr *)pLB->GetEntryData(nPos);
+
+ if (pAttr->nItemId == SID_ATTR_BRUSH)
+ {
+ rFont.SetColor(Color(COL_BLACK));
+ nPos = pColorLB->GetSelectEntryPos();
+ if (nPos && nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ Brush aBrush(Color(pColorLB->GetSelectEntryColor()));
+ pPrev->SetBrush(aBrush);
+ }
+ else
+ {
+ Brush aBrush(Color(COL_LIGHTGRAY));
+ pPrev->SetBrush(aBrush);
+ }
+ }
+ else
+ {
+ nPos = pColorLB->GetSelectEntryPos();
+ if (nPos && nPos != LISTBOX_ENTRY_NOTFOUND)
+ rFont.SetColor(pColorLB->GetEntryColor(nPos));
+ else
+ rFont.SetColor(Color(COL_RED));
+ }
+
+ pPrev->Invalidate();
+*/
+ return 0;
+}
+
diff --git a/sc/source/ui/optdlg/tpcalc.cxx b/sc/source/ui/optdlg/tpcalc.cxx
new file mode 100644
index 000000000000..5b5920e904fc
--- /dev/null
+++ b/sc/source/ui/optdlg/tpcalc.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <vcl/msgbox.hxx>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "uiitems.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "docoptio.hxx"
+#include "scresid.hxx"
+#include "sc.hrc" // -> Slot-IDs
+#include "optdlg.hrc"
+
+#define _TPCALC_CXX
+#include "tpcalc.hxx"
+#undef _TPCALC_CXX
+
+#include <math.h>
+
+// STATIC DATA -----------------------------------------------------------
+
+static USHORT pCalcOptRanges[] =
+{
+ SID_SCDOCOPTIONS,
+ SID_SCDOCOPTIONS,
+ 0
+};
+
+//========================================================================
+
+ScTpCalcOptions::ScTpCalcOptions( Window* pParent,
+ const SfxItemSet& rCoreAttrs )
+
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_CALC ),
+ rCoreAttrs ),
+
+ aGbZRefs ( this, ScResId( GB_ZREFS ) ),
+ aBtnIterate ( this, ScResId( BTN_ITERATE ) ),
+ aFtSteps ( this, ScResId( FT_STEPS ) ),
+ aEdSteps ( this, ScResId( ED_STEPS ) ),
+ aFtEps ( this, ScResId( FT_EPS ) ),
+ aEdEps ( this, ScResId( ED_EPS ) ),
+ aSeparatorFL ( this, ScResId( FL_SEPARATOR ) ),
+ aGbDate ( this, ScResId( GB_DATE ) ),
+ aBtnDateStd ( this, ScResId( BTN_DATESTD ) ),
+ aBtnDateSc10 ( this, ScResId( BTN_DATESC10 ) ),
+ aBtnDate1904 ( this, ScResId( BTN_DATE1904 ) ),
+ aHSeparatorFL ( this, ScResId( FL_H_SEPARATOR ) ),
+ aBtnCase ( this, ScResId( BTN_CASE ) ),
+ aBtnCalc ( this, ScResId( BTN_CALC ) ),
+ aBtnMatch ( this, ScResId( BTN_MATCH ) ),
+ aBtnRegex ( this, ScResId( BTN_REGEX ) ),
+ aBtnLookUp ( this, ScResId( BTN_LOOKUP ) ),
+ aBtnGeneralPrec ( this, ScResId( BTN_GENERAL_PREC ) ),
+ aFtPrec ( this, ScResId( FT_PREC ) ),
+ aEdPrec ( this, ScResId( ED_PREC ) ),
+ pOldOptions ( new ScDocOptions(
+ ((const ScTpCalcItem&)rCoreAttrs.Get(
+ GetWhich( SID_SCDOCOPTIONS ))).
+ GetDocOptions() ) ),
+ pLocalOptions ( new ScDocOptions ),
+ nWhichCalc ( GetWhich( SID_SCDOCOPTIONS ) )
+{
+ aSeparatorFL.SetStyle( aSeparatorFL.GetStyle() | WB_VERT );
+ Init();
+ FreeResource();
+ SetExchangeSupport();
+}
+
+//-----------------------------------------------------------------------
+
+__EXPORT ScTpCalcOptions::~ScTpCalcOptions()
+{
+ delete pOldOptions;
+ delete pLocalOptions;
+}
+
+//-----------------------------------------------------------------------
+
+void ScTpCalcOptions::Init()
+{
+ aBtnIterate .SetClickHdl( LINK( this, ScTpCalcOptions, CheckClickHdl ) );
+ aBtnGeneralPrec.SetClickHdl( LINK(this, ScTpCalcOptions, CheckClickHdl) );
+ aBtnDateStd .SetClickHdl( LINK( this, ScTpCalcOptions, RadioClickHdl ) );
+ aBtnDateSc10.SetClickHdl( LINK( this, ScTpCalcOptions, RadioClickHdl ) );
+ aBtnDate1904.SetClickHdl( LINK( this, ScTpCalcOptions, RadioClickHdl ) );
+}
+
+//-----------------------------------------------------------------------
+
+USHORT* __EXPORT ScTpCalcOptions::GetRanges()
+{
+ return pCalcOptRanges;
+}
+
+//-----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTpCalcOptions::Create( Window* pParent, const SfxItemSet& rAttrSet )
+{
+ return ( new ScTpCalcOptions( pParent, rAttrSet ) );
+}
+
+//-----------------------------------------------------------------------
+
+void __EXPORT ScTpCalcOptions::Reset( const SfxItemSet& /* rCoreAttrs */ )
+{
+ USHORT d,m,y;
+
+ *pLocalOptions = *pOldOptions;
+
+ aBtnCase .Check( !pLocalOptions->IsIgnoreCase() );
+ aBtnCalc .Check( pLocalOptions->IsCalcAsShown() );
+ aBtnMatch .Check( pLocalOptions->IsMatchWholeCell() );
+ aBtnRegex .Check( pLocalOptions->IsFormulaRegexEnabled() );
+ aBtnLookUp .Check( pLocalOptions->IsLookUpColRowNames() );
+ aBtnIterate.Check( pLocalOptions->IsIter() );
+ aEdSteps .SetValue( pLocalOptions->GetIterCount() );
+ aEdEps .SetValue( pLocalOptions->GetIterEps(), 6 );
+
+ pLocalOptions->GetDate( d, m, y );
+
+ switch ( y )
+ {
+ case 1899:
+ aBtnDateStd.Check();
+ break;
+ case 1900:
+ aBtnDateSc10.Check();
+ break;
+ case 1904:
+ aBtnDate1904.Check();
+ break;
+ }
+
+ sal_uInt16 nPrec = pLocalOptions->GetStdPrecision();
+ if (nPrec == SvNumberFormatter::UNLIMITED_PRECISION)
+ {
+ aFtPrec.Disable();
+ aEdPrec.Disable();
+ aBtnGeneralPrec.Check(false);
+ }
+ else
+ {
+ aBtnGeneralPrec.Check();
+ aFtPrec.Enable();
+ aEdPrec.Enable();
+ aEdPrec.SetValue(nPrec);
+ }
+
+ CheckClickHdl( &aBtnIterate );
+}
+
+
+//-----------------------------------------------------------------------
+
+BOOL __EXPORT ScTpCalcOptions::FillItemSet( SfxItemSet& rCoreAttrs )
+{
+ // alle weiteren Optionen werden in den Handlern aktualisiert
+ pLocalOptions->SetIterCount( (USHORT)aEdSteps.GetValue() );
+ pLocalOptions->SetIgnoreCase( !aBtnCase.IsChecked() );
+ pLocalOptions->SetCalcAsShown( aBtnCalc.IsChecked() );
+ pLocalOptions->SetMatchWholeCell( aBtnMatch.IsChecked() );
+ pLocalOptions->SetFormulaRegexEnabled( aBtnRegex.IsChecked() );
+ pLocalOptions->SetLookUpColRowNames( aBtnLookUp.IsChecked() );
+
+ if (aBtnGeneralPrec.IsChecked())
+ pLocalOptions->SetStdPrecision(
+ static_cast<sal_uInt16>(aEdPrec.GetValue()) );
+ else
+ pLocalOptions->SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION );
+
+ if ( *pLocalOptions != *pOldOptions )
+ {
+ rCoreAttrs.Put( ScTpCalcItem( nWhichCalc, *pLocalOptions ) );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+int __EXPORT ScTpCalcOptions::DeactivatePage( SfxItemSet* pSetP )
+{
+ int nReturn = KEEP_PAGE;
+
+ double fEps;
+ if( aEdEps.GetValue( fEps ) && (fEps > 0.0) )
+ {
+ pLocalOptions->SetIterEps( fEps );
+ nReturn = LEAVE_PAGE;
+ }
+
+ if ( nReturn == KEEP_PAGE )
+ {
+ ErrorBox( this,
+ WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_INVALID_EPS )
+ ).Execute();
+
+ aEdEps.GrabFocus();
+ }
+ else if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return nReturn;
+}
+
+//-----------------------------------------------------------------------
+// Handler:
+
+IMPL_LINK( ScTpCalcOptions, RadioClickHdl, RadioButton*, pBtn )
+{
+ if ( pBtn == &aBtnDateStd )
+ {
+ pLocalOptions->SetDate( 30, 12, 1899 );
+ }
+ else if ( pBtn == &aBtnDateSc10 )
+ {
+ pLocalOptions->SetDate( 1, 1, 1900 );
+ }
+ else if ( pBtn == &aBtnDate1904 )
+ {
+ pLocalOptions->SetDate( 1, 1, 1904 );
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------
+
+IMPL_LINK( ScTpCalcOptions, CheckClickHdl, CheckBox*, pBtn )
+{
+ if (pBtn == &aBtnGeneralPrec)
+ {
+ if (pBtn->IsChecked())
+ {
+ aEdPrec.Enable();
+ aFtPrec.Enable();
+ }
+ else
+ {
+ aEdPrec.Disable();
+ aFtPrec.Disable();
+ }
+ }
+ else if (pBtn == &aBtnIterate)
+ {
+ if ( pBtn->IsChecked() )
+ {
+ pLocalOptions->SetIter( TRUE );
+ aFtSteps.Enable(); aEdSteps.Enable();
+ aFtEps .Enable(); aEdEps .Enable();
+ }
+ else
+ {
+ pLocalOptions->SetIter( FALSE );
+ aFtSteps.Disable(); aEdSteps.Disable();
+ aFtEps .Disable(); aEdEps .Disable();
+ }
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/sc/source/ui/optdlg/tpprint.cxx b/sc/source/ui/optdlg/tpprint.cxx
new file mode 100644
index 000000000000..d14b79bd739a
--- /dev/null
+++ b/sc/source/ui/optdlg/tpprint.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+#include <svl/eitem.hxx>
+
+#include "tpprint.hxx"
+#include "printopt.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "optdlg.hrc"
+
+// -----------------------------------------------------------------------
+
+static USHORT pPrintOptRanges[] =
+{
+ SID_SCPRINTOPTIONS,
+ SID_SCPRINTOPTIONS,
+ 0
+};
+
+// -----------------------------------------------------------------------
+
+ScTpPrintOptions::ScTpPrintOptions( Window* pParent,
+ const SfxItemSet& rCoreAttrs )
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_PRINT ),
+ rCoreAttrs ),
+ aPagesFL ( this, ScResId( FL_PAGES ) ),
+ aSkipEmptyPagesCB( this, ScResId( BTN_SKIPEMPTYPAGES ) ),
+ aSheetsFL ( this, ScResId( FL_SHEETS ) ),
+ aSelectedSheetsCB( this, ScResId( BTN_SELECTEDSHEETS ) )
+{
+ FreeResource();
+}
+
+ScTpPrintOptions::~ScTpPrintOptions()
+{
+}
+
+USHORT* ScTpPrintOptions::GetRanges()
+{
+ return pPrintOptRanges;
+}
+
+SfxTabPage* ScTpPrintOptions::Create( Window* pParent, const SfxItemSet& rAttrSet )
+{
+ return new ScTpPrintOptions( pParent, rAttrSet );
+}
+
+int ScTpPrintOptions::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return LEAVE_PAGE;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpPrintOptions::Reset( const SfxItemSet& rCoreSet )
+{
+ ScPrintOptions aOptions;
+
+ const SfxPoolItem* pItem;
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SCPRINTOPTIONS, FALSE , &pItem))
+ aOptions = ((const ScTpPrintItem*)pItem)->GetPrintOptions();
+ else
+ {
+ // when called from print dialog and no options set, use configuration
+ aOptions = SC_MOD()->GetPrintOptions();
+ }
+
+ if ( SFX_ITEM_SET == rCoreSet.GetItemState( SID_PRINT_SELECTEDSHEET, FALSE , &pItem ) )
+ {
+ BOOL bChecked = ( (const SfxBoolItem*)pItem )->GetValue();
+ aSelectedSheetsCB.Check( bChecked );
+ }
+ else
+ {
+ aSelectedSheetsCB.Check( !aOptions.GetAllSheets() );
+ }
+
+ aSkipEmptyPagesCB.Check( aOptions.GetSkipEmpty() );
+ aSkipEmptyPagesCB.SaveValue();
+ aSelectedSheetsCB.SaveValue();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScTpPrintOptions::FillItemSet( SfxItemSet& rCoreAttrs )
+{
+ rCoreAttrs.ClearItem( SID_PRINT_SELECTEDSHEET );
+
+ bool bSkipEmptyChanged = ( aSkipEmptyPagesCB.GetSavedValue() != aSkipEmptyPagesCB.IsChecked() );
+ bool bSelectedSheetsChanged = ( aSelectedSheetsCB.GetSavedValue() != aSelectedSheetsCB.IsChecked() );
+
+ if ( bSkipEmptyChanged || bSelectedSheetsChanged )
+ {
+ ScPrintOptions aOpt;
+ aOpt.SetSkipEmpty( aSkipEmptyPagesCB.IsChecked() );
+ aOpt.SetAllSheets( !aSelectedSheetsCB.IsChecked() );
+ rCoreAttrs.Put( ScTpPrintItem( SID_SCPRINTOPTIONS, aOpt ) );
+ if ( bSelectedSheetsChanged )
+ {
+ rCoreAttrs.Put( SfxBoolItem( SID_PRINT_SELECTEDSHEET, aSelectedSheetsCB.IsChecked() ) );
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
diff --git a/sc/source/ui/optdlg/tpusrlst.cxx b/sc/source/ui/optdlg/tpusrlst.cxx
new file mode 100644
index 000000000000..eb7c8a6635eb
--- /dev/null
+++ b/sc/source/ui/optdlg/tpusrlst.cxx
@@ -0,0 +1,839 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include <vcl/msgbox.hxx>
+
+#include "global.hxx"
+#include "document.hxx"
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+#include "uiitems.hxx"
+#include "userlist.hxx"
+#include "rangeutl.hxx"
+#include "crdlg.hxx"
+#include "scresid.hxx"
+#include "sc.hrc" // -> Slot-IDs
+#include "optdlg.hrc"
+#include "globstr.hrc"
+
+#define _TPUSRLST_CXX
+#include "tpusrlst.hxx"
+#undef _TPUSRLST_CXX
+
+//CHINA001 #include "scui_def.hxx" //CHINA001
+//CHINA001 #include "scresid.hxx" //add by CHINA001
+//CHINA001 #include "miscdlgs.hrc" //add by CHINA001
+//CHINA001
+//CHINA001 #include "scabstdlg.hxx" //CHINA001
+// STATIC DATA -----------------------------------------------------------
+
+#define CR (sal_Unicode)13
+#define LF (sal_Unicode)10
+
+static USHORT pUserListsRanges[] =
+{
+ SID_SCUSERLISTS,
+ SID_SCUSERLISTS,
+ 0
+};
+
+static const sal_Unicode cDelimiter = ',';
+
+
+//========================================================================
+// Benutzerdefinierte Listen:
+
+
+ScTpUserLists::ScTpUserLists( Window* pParent,
+ const SfxItemSet& rCoreAttrs )
+
+ : SfxTabPage ( pParent,
+ ScResId( RID_SCPAGE_USERLISTS ),
+ rCoreAttrs ),
+ aFtLists ( this, ScResId( FT_LISTS ) ),
+ aLbLists ( this, ScResId( LB_LISTS ) ),
+ aFtEntries ( this, ScResId( FT_ENTRIES ) ),
+ aEdEntries ( this, ScResId( ED_ENTRIES ) ),
+ aFtCopyFrom ( this, ScResId( FT_COPYFROM ) ),
+ aEdCopyFrom ( this, ScResId( ED_COPYFROM ) ),
+ aBtnNew ( this, ScResId( BTN_NEW ) ),
+ aBtnAdd ( this, ScResId( BTN_ADD ) ),
+ aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
+ aBtnCopy ( this, ScResId( BTN_COPY ) ),
+ aStrQueryRemove ( ScResId( STR_QUERYREMOVE ) ),
+ aStrNew ( aBtnNew.GetText() ),
+ aStrCancel ( ScResId( STR_DISMISS ) ),
+ aStrAdd ( ScResId( SCSTR_ADD ) ),
+ aStrModify ( ScResId( SCSTR_MODIFY ) ),
+ aStrCopyList ( ScResId( STR_COPYLIST ) ),
+ aStrCopyFrom ( ScResId( STR_COPYFROM ) ),
+ aStrCopyErr ( ScResId( STR_COPYERR ) ),
+ //
+ nWhichUserLists ( GetWhich( SID_SCUSERLISTS ) ),
+ pUserLists ( NULL ),
+ pDoc ( NULL ),
+ pViewData ( NULL ),
+ pRangeUtil ( new ScRangeUtil ),
+ bModifyMode ( FALSE ),
+ bCancelMode ( FALSE ),
+ bCopyDone ( FALSE ),
+ nCancelPos ( 0 )
+{
+ SetExchangeSupport();
+ Init();
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScTpUserLists::~ScTpUserLists()
+{
+ delete pUserLists;
+ delete pRangeUtil;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::Init()
+{
+ SfxViewShell* pSh = SfxViewShell::Current();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, pSh);
+
+ aLbLists.SetSelectHdl ( LINK( this, ScTpUserLists, LbSelectHdl ) );
+ aBtnNew.SetClickHdl ( LINK( this, ScTpUserLists, BtnClickHdl ) );
+ aBtnNew.SetClickHdl ( LINK( this, ScTpUserLists, BtnClickHdl ) );
+ aBtnAdd.SetClickHdl ( LINK( this, ScTpUserLists, BtnClickHdl ) );
+ aBtnRemove.SetClickHdl ( LINK( this, ScTpUserLists, BtnClickHdl ) );
+ aEdEntries.SetModifyHdl ( LINK( this, ScTpUserLists, EdEntriesModHdl ) );
+
+
+ if ( pViewSh )
+ {
+ SCTAB nStartTab = 0;
+ SCTAB nEndTab = 0;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+
+ pViewData = pViewSh->GetViewData();
+ pDoc = pViewData->GetDocument();
+
+ pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+
+ ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab
+ ).Format( aStrSelectedArea, SCR_ABS_3D, pDoc );
+
+ aBtnCopy.SetClickHdl ( LINK( this, ScTpUserLists, BtnClickHdl ) );
+ aBtnCopy.Enable();
+ }
+ else
+ {
+ aBtnCopy.Disable();
+ aFtCopyFrom.Disable();
+ aEdCopyFrom.Disable();
+ }
+
+// aLbLists.GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT* __EXPORT ScTpUserLists::GetRanges()
+{
+ return pUserListsRanges;
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScTpUserLists::Create( Window* pParent, const SfxItemSet& rAttrSet )
+{
+ return ( new ScTpUserLists( pParent, rAttrSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTpUserLists::Reset( const SfxItemSet& rCoreAttrs )
+{
+ const ScUserListItem& rUserListItem = (const ScUserListItem&)
+ rCoreAttrs.Get( nWhichUserLists );
+ const ScUserList* pCoreList = rUserListItem.GetUserList();
+
+ DBG_ASSERT( pCoreList, "UserList not found :-/" );
+
+ if ( pCoreList )
+ {
+ if ( !pUserLists )
+ pUserLists = new ScUserList( *pCoreList );
+ else
+ *pUserLists = *pCoreList;
+
+ if ( UpdateUserListBox() > 0 )
+ {
+ aLbLists.SelectEntryPos( 0 );
+ UpdateEntries( 0 );
+ }
+ }
+ else if ( !pUserLists )
+ pUserLists = new ScUserList;
+
+ aEdCopyFrom.SetText( aStrSelectedArea );
+
+ if ( aLbLists.GetEntryCount() == 0 )
+ {
+ aFtLists .Disable();
+ aLbLists .Disable();
+ aFtEntries .Disable();
+ aEdEntries .Disable();
+ aBtnRemove .Disable();
+ }
+
+ aBtnNew.SetText( aStrNew );
+ aBtnAdd.SetText( aStrAdd );
+ aBtnAdd.Disable();
+
+ if ( !bCopyDone && pViewData )
+ {
+ aFtCopyFrom .Enable();
+ aEdCopyFrom .Enable();
+ aBtnCopy .Enable();
+ }
+
+// aLbLists.GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScTpUserLists::FillItemSet( SfxItemSet& rCoreAttrs )
+{
+ // Modifikationen noch nicht uebernommen?
+ // -> Click auf Add-Button simulieren
+
+ if ( bModifyMode || bCancelMode )
+ BtnClickHdl( &aBtnAdd );
+
+ const ScUserListItem& rUserListItem = (const ScUserListItem&)
+ GetItemSet().Get( nWhichUserLists );
+
+ ScUserList* pCoreList = rUserListItem.GetUserList();
+ BOOL bDataModified = FALSE;
+
+ if ( (pUserLists == NULL) && (pCoreList == NULL) )
+ {
+ bDataModified = FALSE;
+ }
+ else if ( pUserLists != NULL )
+ {
+ if ( pCoreList != NULL )
+ bDataModified = (*pUserLists != *pCoreList);
+ else
+ bDataModified = TRUE;
+ }
+
+ if ( bDataModified )
+ {
+ ScUserListItem aULItem( nWhichUserLists );
+
+ if ( pUserLists )
+ aULItem.SetUserList( *pUserLists );
+
+ rCoreAttrs.Put( aULItem );
+ }
+
+ return bDataModified;
+}
+
+// -----------------------------------------------------------------------
+
+int __EXPORT ScTpUserLists::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return LEAVE_PAGE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ScTpUserLists::UpdateUserListBox()
+{
+ aLbLists.Clear();
+
+ if ( !pUserLists ) return 0;
+
+ //----------------------------------------------------------
+
+ USHORT nCount = pUserLists->GetCount();
+ String aEntry;
+
+ if ( nCount > 0 )
+ {
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ aEntry = (*pUserLists)[i]->GetString();
+ DBG_ASSERT( aEntry.Len() > 0, "Empty UserList-entry :-/" );
+ aLbLists.InsertEntry( aEntry );
+ }
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::UpdateEntries( USHORT nList )
+{
+ if ( !pUserLists ) return;
+
+ //----------------------------------------------------------
+
+ if ( nList < pUserLists->GetCount() )
+ {
+ ScUserListData* pList = (*pUserLists)[nList];
+ USHORT nSubCount = pList->GetSubCount();
+ String aEntryListStr;
+
+ for ( USHORT i=0; i<nSubCount; i++ )
+ {
+ if ( i!=0 )
+ aEntryListStr += CR;
+ aEntryListStr += pList->GetSubStr( i );
+ }
+
+ aEntryListStr.ConvertLineEnd();
+ aEdEntries.SetText( aEntryListStr );
+ }
+ else
+ {
+ DBG_ERROR( "Invalid ListIndex :-/" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::MakeListStr( String& rListStr )
+{
+ String aInputStr(rListStr);
+ String aStr;
+
+ xub_StrLen nLen = aStr.Len();
+ xub_StrLen c = 0;
+
+ aInputStr.ConvertLineEnd( LINEEND_LF );
+ //aStr.EraseAllChars( ' ' );
+
+ xub_StrLen nToken=rListStr.GetTokenCount(LF);
+
+ for(xub_StrLen i=0;i<nToken;i++)
+ {
+ String aString=rListStr.GetToken(i,LF);
+ aString.EraseLeadingChars(' ');
+ aString.EraseTrailingChars(' ');
+ aStr+=aString;
+ aStr+=cDelimiter;
+ }
+
+ /*
+ // '\n' durch cDelimiter ersetzen:
+ for ( c=0;
+ (c < nLen) && (nFound != STRING_NOTFOUND);
+ c++ )
+ {
+ nFound = aStr.Search( LF, nFound );
+ if ( nFound != STRING_NOTFOUND )
+ aStr[nFound] = cDelimiter;
+ }
+ */
+
+ aStr.EraseLeadingChars( cDelimiter );
+ aStr.EraseTrailingChars( cDelimiter );
+ nLen = aStr.Len();
+
+ rListStr.Erase();
+
+ // Alle Doppelten cDelimiter entfernen:
+ c=0;
+ while ( c < nLen )
+ {
+ rListStr += aStr.GetChar(c);
+ c++;
+
+ if ( aStr.GetChar(c) == cDelimiter )
+ {
+ rListStr += aStr.GetChar(c);
+
+ while ( (aStr.GetChar(c) == cDelimiter) && (c < nLen) )
+ c++;
+ }
+ }
+
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::AddNewList( const String& rEntriesStr )
+{
+ String theEntriesStr( rEntriesStr );
+
+ if ( !pUserLists )
+ pUserLists = new ScUserList;
+
+ MakeListStr( theEntriesStr );
+
+ if ( !pUserLists->Insert( new ScUserListData( theEntriesStr ) ) )
+ {
+ DBG_ERROR( "Entry could not be inserted :-/" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::CopyListFromArea( const ScRefAddress& rStartPos,
+ const ScRefAddress& rEndPos )
+{
+ if ( bCopyDone ) return;
+
+ //----------------------------------------------------------
+
+ SCTAB nTab = rStartPos.Tab();
+ SCCOL nStartCol = rStartPos.Col();
+ SCROW nStartRow = rStartPos.Row();
+ SCCOL nEndCol = rEndPos.Col();
+ SCROW nEndRow = rEndPos.Row();
+ USHORT nCellDir = SCRET_COLS;
+ BOOL bValueIgnored = FALSE;
+
+ if ( (nStartCol != nEndCol) && (nStartRow != nEndRow) )
+ {
+ nCellDir = ScColOrRowDlg( this, aStrCopyList, aStrCopyFrom ).Execute();
+//CHINA001 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+//CHINA001 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+//CHINA001
+//CHINA001 VclAbstractDialog* pDlg = pFact->CreateScColOrRowDlg( this, aStrCopyList, aStrCopyFrom,ResId(RID_SCDLG_COLORROW) );
+//CHINA001 DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+//CHINA001 nCellDir = pDlg->Execute();
+//CHINA001 delete pDlg; //CHINA001
+ }
+ else if ( nStartCol != nEndCol )
+ nCellDir = SCRET_ROWS;
+ else
+ nCellDir = SCRET_COLS;
+
+ if ( nCellDir != RET_CANCEL )
+ {
+ String aStrList;
+ String aStrField;
+
+ if ( nCellDir == SCRET_COLS )
+ {
+ for ( SCCOL col=nStartCol; col<=nEndCol; col++ )
+ {
+ for ( SCROW row=nStartRow; row<=nEndRow; row++ )
+ {
+ if ( pDoc->HasStringData( col, row, nTab ) )
+ {
+ pDoc->GetString( col, row, nTab, aStrField );
+
+ if ( aStrField.Len() > 0 )
+ {
+ aStrList += aStrField;
+ aStrList += '\n';
+ }
+ }
+ else
+ bValueIgnored = TRUE;
+ }
+ if ( aStrList.Len() > 0 )
+ AddNewList( aStrList );
+ aStrList.Erase();
+ }
+ }
+ else
+ {
+ for ( SCROW row=nStartRow; row<=nEndRow; row++ )
+ {
+ for ( SCCOL col=nStartCol; col<=nEndCol; col++ )
+ {
+ if ( pDoc->HasStringData( col, row, nTab ) )
+ {
+ pDoc->GetString( col, row, nTab, aStrField );
+
+ if ( aStrField.Len() > 0 )
+ {
+ aStrList += aStrField;
+ aStrList += '\n';
+ }
+ }
+ else
+ bValueIgnored = TRUE;
+ }
+ if ( aStrList.Len() > 0 )
+ AddNewList( aStrList );
+ aStrList.Erase();
+ }
+ }
+
+ if ( bValueIgnored )
+ {
+ InfoBox( this, aStrCopyErr ).Execute();
+ }
+ }
+
+ //----------------------------------------------------------
+
+ bCopyDone = TRUE;
+
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::ModifyList( USHORT nSelList,
+ const String& rEntriesStr )
+{
+ if ( !pUserLists ) return;
+
+ //----------------------------------------------------------
+
+ String theEntriesStr( rEntriesStr );
+
+ MakeListStr( theEntriesStr );
+
+ (*pUserLists)[nSelList]->SetString( theEntriesStr );
+}
+
+// -----------------------------------------------------------------------
+
+void ScTpUserLists::RemoveList( USHORT nList )
+{
+ if ( pUserLists ) pUserLists->AtFree( nList );
+}
+
+//-----------------------------------------------------------------------
+// Handler:
+//---------
+
+IMPL_LINK( ScTpUserLists, LbSelectHdl, ListBox*, pLb )
+{
+ if ( pLb == &aLbLists )
+ {
+ USHORT nSelPos = aLbLists.GetSelectEntryPos();
+ if ( nSelPos != LISTBOX_ENTRY_NOTFOUND )
+ {
+ if ( !aFtEntries.IsEnabled() ) aFtEntries.Enable();
+ if ( !aEdEntries.IsEnabled() ) aEdEntries.Enable();
+ if ( !aBtnRemove.IsEnabled() ) aBtnRemove.Enable();
+ if ( aBtnAdd.IsEnabled() ) aBtnAdd.Disable();
+
+ UpdateEntries( nSelPos );
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTpUserLists, BtnClickHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &aBtnNew )
+ {
+ if ( !bCancelMode )
+ {
+ nCancelPos = ( aLbLists.GetEntryCount() > 0 )
+ ? aLbLists.GetSelectEntryPos()
+ : 0;
+ aLbLists.SetNoSelection();
+ aFtLists.Disable();
+ aLbLists.Disable();
+ aFtEntries.Enable();
+ aEdEntries.Enable();
+ aEdEntries.SetText( EMPTY_STRING );
+ aEdEntries.GrabFocus();
+ aBtnAdd.Disable();
+ aBtnRemove.Disable();
+ //-----------------------------
+ if ( aBtnCopy.IsEnabled() )
+ {
+ aBtnCopy.Disable();
+ aFtCopyFrom.Disable();
+ aEdCopyFrom.Disable();
+ }
+ aBtnNew.SetText( aStrCancel );
+ bCancelMode = TRUE;
+ }
+ else // if ( bCancelMode )
+ {
+ if ( aLbLists.GetEntryCount() > 0 )
+ {
+ aLbLists.SelectEntryPos( nCancelPos );
+ LbSelectHdl( &aLbLists );
+ aFtLists.Enable();
+ aLbLists.Enable();
+ }
+ else
+ {
+ aFtEntries.Disable();
+ aEdEntries.Disable();
+ aEdEntries.SetText( EMPTY_STRING );
+ aBtnRemove.Disable();
+ }
+ aBtnAdd.Disable();
+ //-----------------------------
+ if ( pViewData && !bCopyDone )
+ {
+ aBtnCopy.Enable();
+ aFtCopyFrom.Enable();
+ aEdCopyFrom.Enable();
+ }
+ aBtnNew.SetText( aStrNew );
+ bCancelMode = FALSE;
+ bModifyMode = FALSE;
+ }
+ }
+ else if ( pBtn == &aBtnAdd )
+ {
+ String theEntriesStr( aEdEntries.GetText() );
+
+ if ( !bModifyMode )
+ {
+ if ( theEntriesStr.Len() > 0 )
+ {
+ AddNewList( theEntriesStr );
+ UpdateUserListBox();
+ aLbLists.SelectEntryPos( aLbLists.GetEntryCount()-1 );
+ LbSelectHdl( &aLbLists );
+ aFtLists.Enable();
+ aLbLists.Enable();
+ }
+ else
+ {
+ if ( aLbLists.GetEntryCount() > 0 )
+ {
+ aLbLists.SelectEntryPos( nCancelPos );
+ LbSelectHdl( &aLbLists );
+ aLbLists.Enable();
+ aLbLists.Enable();
+ }
+ }
+
+ aBtnAdd.Disable();
+ aBtnRemove.Enable();
+ aBtnNew.SetText( aStrNew );
+ bCancelMode = FALSE;
+ }
+ else // if ( bModifyMode )
+ {
+ USHORT nSelList = aLbLists.GetSelectEntryPos();
+
+ DBG_ASSERT( nSelList != LISTBOX_ENTRY_NOTFOUND, "Modify without List :-/" );
+
+ if ( theEntriesStr.Len() > 0 )
+ {
+ ModifyList( nSelList, theEntriesStr );
+ UpdateUserListBox();
+ aLbLists.SelectEntryPos( nSelList );
+ }
+ else
+ {
+ aLbLists.SelectEntryPos( 0 );
+ LbSelectHdl( &aLbLists );
+ }
+
+ aBtnNew.SetText( aStrNew ); bCancelMode = FALSE;
+ aBtnAdd.SetText( aStrAdd ); bModifyMode = FALSE;
+ aBtnAdd.Disable();
+ aBtnRemove.Enable();
+ aFtLists.Enable();
+ aLbLists.Enable();
+ }
+
+ if ( pViewData && !bCopyDone )
+ {
+ aBtnCopy.Enable();
+ aFtCopyFrom.Enable();
+ aEdCopyFrom.Enable();
+ }
+ }
+ else if ( pBtn == &aBtnRemove )
+ {
+ if ( aLbLists.GetEntryCount() > 0 )
+ {
+ USHORT nRemovePos = aLbLists.GetSelectEntryPos();
+ String aMsg ( aStrQueryRemove.GetToken( 0, '#' ) );
+
+ aMsg += aLbLists.GetEntry( nRemovePos );
+ aMsg += aStrQueryRemove.GetToken( 1, '#' );
+
+
+ if ( RET_YES == QueryBox( this,
+ WinBits( WB_YES_NO | WB_DEF_YES ),
+ aMsg
+ ).Execute() )
+ {
+ RemoveList( nRemovePos );
+ UpdateUserListBox();
+
+ if ( aLbLists.GetEntryCount() > 0 )
+ {
+ aLbLists.SelectEntryPos(
+ ( nRemovePos >= aLbLists.GetEntryCount() )
+ ? aLbLists.GetEntryCount()-1
+ : nRemovePos );
+ LbSelectHdl( &aLbLists );
+ }
+ else
+ {
+ aFtLists.Disable();
+ aLbLists.Disable();
+ aFtEntries.Disable();
+ aEdEntries.Disable();
+ aEdEntries.SetText( EMPTY_STRING );
+ aBtnRemove.Disable();
+ }
+ }
+
+ if ( pViewData && !bCopyDone && !aBtnCopy.IsEnabled() )
+ {
+ aBtnCopy.Enable();
+ aFtCopyFrom.Enable();
+ aEdCopyFrom.Enable();
+ }
+ }
+ }
+ else if ( pViewData && (pBtn == &aBtnCopy) )
+ {
+ if ( bCopyDone )
+ return 0;
+
+ //-----------------------------------------------------------
+
+ ScRefAddress theStartPos;
+ ScRefAddress theEndPos;
+ String theAreaStr( aEdCopyFrom.GetText() );
+ BOOL bAreaOk = FALSE;
+
+ if ( theAreaStr.Len() > 0 )
+ {
+ bAreaOk = pRangeUtil->IsAbsArea( theAreaStr,
+ pDoc,
+ pViewData->GetTabNo(),
+ &theAreaStr,
+ &theStartPos,
+ &theEndPos,
+ pDoc->GetAddressConvention() );
+ if ( !bAreaOk )
+ {
+ bAreaOk = pRangeUtil->IsAbsPos( theAreaStr,
+ pDoc,
+ pViewData->GetTabNo(),
+ &theAreaStr,
+ &theStartPos,
+ pDoc->GetAddressConvention() );
+ theEndPos = theStartPos;
+ }
+ }
+
+ if ( bAreaOk )
+ {
+ CopyListFromArea( theStartPos, theEndPos );
+ UpdateUserListBox();
+ aLbLists.SelectEntryPos( aLbLists.GetEntryCount()-1 );
+ LbSelectHdl( &aLbLists );
+ aEdCopyFrom .SetText( theAreaStr );
+ aEdCopyFrom .Disable();
+ aBtnCopy .Disable();
+ aFtCopyFrom .Disable();
+ }
+ else
+ {
+ ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_INVALID_TABREF )
+ ).Execute();
+ aEdCopyFrom.GrabFocus();
+ aEdCopyFrom.SetSelection( Selection( 0, SELECTION_MAX ) );
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScTpUserLists, EdEntriesModHdl, MultiLineEdit*, pEd )
+{
+ if ( pEd != &aEdEntries )
+ return 0;
+
+ //-----------------------------------------------------------
+
+ if ( aBtnCopy.IsEnabled() )
+ {
+ aBtnCopy .Disable();
+ aFtCopyFrom .Disable();
+ aEdCopyFrom .Disable();
+ }
+
+ if ( aEdEntries.GetText().Len() > 0 )
+ {
+ if ( !bCancelMode && !bModifyMode )
+ {
+ aBtnNew.SetText( aStrCancel ); bCancelMode = TRUE;
+ aBtnAdd.SetText( aStrModify ); bModifyMode = TRUE;
+ aBtnAdd.Enable();
+ aBtnRemove.Disable();
+ aFtLists.Disable();
+ aLbLists.Disable();
+ }
+ else // if ( bCancelMode || bModifyMode )
+ {
+ if ( !aBtnAdd.IsEnabled() ) aBtnAdd.Enable();
+ }
+ }
+ else
+ {
+ if ( aBtnAdd.IsEnabled() ) aBtnAdd.Disable();
+ }
+
+ return 0;
+}
+
+
+
diff --git a/sc/source/ui/optdlg/tpview.cxx b/sc/source/ui/optdlg/tpview.cxx
new file mode 100644
index 000000000000..5c2e8dd52c9f
--- /dev/null
+++ b/sc/source/ui/optdlg/tpview.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include "tpview.hxx"
+#include "global.hxx"
+#include "viewopti.hxx"
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "scresid.hxx"
+#include "docsh.hxx"
+#include "sc.hrc" // -> Slot-IDs
+#include "optdlg.hrc"
+#include "globstr.hrc"
+#include <appoptio.hxx>
+#include <scmod.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xtable.hxx>
+
+
+// STATIC DATA -----------------------------------------------------------
+
+
+
+/*-----------------11.01.97 10.52-------------------
+ Optionen Inhalte
+--------------------------------------------------*/
+
+ScTpContentOptions::ScTpContentOptions( Window* pParent,
+ const SfxItemSet& rArgSet ) :
+ SfxTabPage(pParent, ScResId( RID_SCPAGE_CONTENT ), rArgSet),
+
+ aLinesGB( this, ScResId(GB_LINES )),
+ aGridCB( this, ScResId(CB_GRID )),
+ aColorFT( this, ScResId(FT_COLOR )),
+ aColorLB( this, ScResId(LB_COLOR )),
+ aBreakCB( this, ScResId(CB_PAGEBREAKS )),
+ aGuideLineCB( this, ScResId(CB_GUIDELINE )),
+ aHandleCB( this, ScResId(CB_HANDLES )),
+ aBigHandleCB( this, ScResId(CB_BIGHANDLES )),
+
+ aSeparator1FL (this, ScResId(FL_SEPARATOR1 )),
+ aDisplayGB( this, ScResId(GB_DISPLAY)),
+ aFormulaCB( this, ScResId(CB_FORMULA)),
+ aNilCB( this, ScResId(CB_NIL )),
+ aAnnotCB( this, ScResId(CB_ANNOT )),
+ aValueCB( this, ScResId(CB_VALUE )),
+ aAnchorCB( this, ScResId(CB_ANCHOR )),
+ aClipMarkCB( this, ScResId(CB_CLIP )),
+ aRangeFindCB( this, ScResId( CB_RFIND )),
+
+ aObjectGB( this, ScResId(GB_OBJECT )),
+ aObjGrfFT( this, ScResId(FT_OBJGRF )),
+ aObjGrfLB( this, ScResId(LB_OBJGRF )),
+ aDiagramFT( this, ScResId(FT_DIAGRAM)),
+ aDiagramLB( this, ScResId(LB_DIAGRAM)),
+ aDrawFT( this, ScResId(FT_DRAW )),
+ aDrawLB( this, ScResId(LB_DRAW )),
+
+ aZoomGB( this, ScResId(GB_ZOOM) ),
+ aSyncZoomCB( this, ScResId(CB_SYNCZOOM) ),
+
+ aSeparator2FL (this, ScResId(FL_SEPARATOR2)),
+ aWindowGB( this, ScResId(GB_WINDOW )),
+ aRowColHeaderCB(this, ScResId(CB_ROWCOLHEADER )),
+ aHScrollCB( this, ScResId(CB_HSCROLL )),
+ aVScrollCB( this, ScResId(CB_VSCROLL )),
+ aTblRegCB( this, ScResId(CB_TBLREG )),
+ aOutlineCB( this, ScResId(CB_OUTLINE )),
+ pLocalOptions(0)
+{
+ FreeResource();
+ aSeparator1FL.SetStyle( aSeparator1FL.GetStyle() | WB_VERT );
+ aSeparator2FL.SetStyle( aSeparator2FL.GetStyle() | WB_VERT );
+ SetExchangeSupport();
+ Link aSelObjHdl(LINK( this, ScTpContentOptions, SelLbObjHdl ) );
+ aObjGrfLB. SetSelectHdl(aSelObjHdl);
+ aDiagramLB. SetSelectHdl(aSelObjHdl);
+ aDrawLB. SetSelectHdl(aSelObjHdl);
+
+ Link aCBHdl(LINK( this, ScTpContentOptions, CBHdl ) );
+ aFormulaCB .SetClickHdl(aCBHdl);
+ aNilCB .SetClickHdl(aCBHdl);
+ aAnnotCB .SetClickHdl(aCBHdl);
+ aValueCB .SetClickHdl(aCBHdl);
+ aAnchorCB .SetClickHdl(aCBHdl);
+ aClipMarkCB .SetClickHdl(aCBHdl);
+
+ aVScrollCB .SetClickHdl(aCBHdl);
+ aHScrollCB .SetClickHdl(aCBHdl);
+ aTblRegCB .SetClickHdl(aCBHdl);
+ aOutlineCB .SetClickHdl(aCBHdl);
+ aBreakCB .SetClickHdl(aCBHdl);
+ aGuideLineCB.SetClickHdl(aCBHdl);
+ aHandleCB .SetClickHdl(aCBHdl);
+ aBigHandleCB.SetClickHdl(aCBHdl);
+ aRowColHeaderCB.SetClickHdl(aCBHdl);
+
+ aGridCB .SetClickHdl( LINK( this, ScTpContentOptions, GridHdl ) );
+}
+/*-----------------11.01.97 10.52-------------------
+
+--------------------------------------------------*/
+
+ScTpContentOptions::~ScTpContentOptions()
+{
+ delete pLocalOptions;
+}
+/*-----------------11.01.97 10.52-------------------
+
+--------------------------------------------------*/
+
+SfxTabPage* ScTpContentOptions::Create( Window* pParent,
+ const SfxItemSet& rCoreSet )
+{
+ return new ScTpContentOptions(pParent, rCoreSet);
+}
+/*-----------------11.01.97 10.52-------------------
+
+--------------------------------------------------*/
+BOOL ScTpContentOptions::FillItemSet( SfxItemSet& rCoreSet )
+{
+ BOOL bRet = FALSE;
+ if( aFormulaCB .GetSavedValue() != aFormulaCB .IsChecked() ||
+ aNilCB .GetSavedValue() != aNilCB .IsChecked() ||
+ aAnnotCB .GetSavedValue() != aAnnotCB .IsChecked() ||
+ aValueCB .GetSavedValue() != aValueCB .IsChecked() ||
+ aAnchorCB .GetSavedValue() != aAnchorCB .IsChecked() ||
+ aClipMarkCB .GetSavedValue() != aClipMarkCB .IsChecked() ||
+ aObjGrfLB .GetSavedValue() != aObjGrfLB .GetSelectEntryPos() ||
+ aDiagramLB .GetSavedValue() != aDiagramLB .GetSelectEntryPos() ||
+ aDrawLB .GetSavedValue() != aDrawLB .GetSelectEntryPos() ||
+ aGridCB .GetSavedValue() != aGridCB.IsChecked() ||
+ aRowColHeaderCB .GetSavedValue() != aRowColHeaderCB.IsChecked() ||
+ aHScrollCB .GetSavedValue() != aHScrollCB .IsChecked() ||
+ aVScrollCB .GetSavedValue() != aVScrollCB .IsChecked() ||
+ aTblRegCB .GetSavedValue() != aTblRegCB .IsChecked() ||
+ aOutlineCB .GetSavedValue() != aOutlineCB .IsChecked() ||
+ aColorLB .GetSavedValue() != aColorLB .GetSelectEntryPos() ||
+ aBreakCB .GetSavedValue() != aBreakCB .IsChecked() ||
+ aGuideLineCB .GetSavedValue() != aGuideLineCB .IsChecked() ||
+ aHandleCB .GetSavedValue() != aHandleCB .IsChecked() ||
+ aBigHandleCB .GetSavedValue() != aBigHandleCB .IsChecked())
+ {
+ pLocalOptions->SetGridColor( aColorLB.GetSelectEntryColor(),
+ aColorLB.GetSelectEntry() );
+ rCoreSet.Put(ScTpViewItem(SID_SCVIEWOPTIONS, *pLocalOptions));
+ bRet = TRUE;
+ }
+ if(aRangeFindCB.GetSavedValue() != aRangeFindCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_RANGEFINDER, aRangeFindCB.IsChecked()));
+ bRet = TRUE;
+ }
+ if(aSyncZoomCB.GetSavedValue() != aSyncZoomCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_OPT_SYNCZOOM, aSyncZoomCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+
+ return bRet;
+}
+/*-----------------11.01.97 10.53-------------------
+
+--------------------------------------------------*/
+
+void ScTpContentOptions::Reset( const SfxItemSet& rCoreSet )
+{
+ const SfxPoolItem* pItem;
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SCVIEWOPTIONS, FALSE , &pItem))
+ pLocalOptions = new ScViewOptions(
+ ((const ScTpViewItem*)pItem)->GetViewOptions() );
+ else
+ pLocalOptions = new ScViewOptions;
+ aFormulaCB .Check(pLocalOptions->GetOption(VOPT_FORMULAS));
+ aNilCB .Check(pLocalOptions->GetOption(VOPT_NULLVALS));
+ aAnnotCB .Check(pLocalOptions->GetOption(VOPT_NOTES));
+ aValueCB .Check(pLocalOptions->GetOption(VOPT_SYNTAX));
+ aAnchorCB .Check(pLocalOptions->GetOption(VOPT_ANCHOR));
+ aClipMarkCB .Check(pLocalOptions->GetOption(VOPT_CLIPMARKS));
+
+ aObjGrfLB .SelectEntryPos( (USHORT)pLocalOptions->GetObjMode(VOBJ_TYPE_OLE) );
+ aDiagramLB .SelectEntryPos( (USHORT)pLocalOptions->GetObjMode(VOBJ_TYPE_CHART) );
+ aDrawLB .SelectEntryPos( (USHORT)pLocalOptions->GetObjMode(VOBJ_TYPE_DRAW) );
+
+ aRowColHeaderCB.Check( pLocalOptions->GetOption(VOPT_HEADER) );
+ aHScrollCB .Check( pLocalOptions->GetOption(VOPT_HSCROLL) );
+ aVScrollCB .Check( pLocalOptions->GetOption(VOPT_VSCROLL) );
+ aTblRegCB .Check( pLocalOptions->GetOption(VOPT_TABCONTROLS) );
+ aOutlineCB .Check( pLocalOptions->GetOption(VOPT_OUTLINER) );
+
+ InitGridOpt();
+
+ aBreakCB.Check( pLocalOptions->GetOption(VOPT_PAGEBREAKS) );
+ aGuideLineCB.Check( pLocalOptions->GetOption(VOPT_HELPLINES) );
+ aHandleCB.Check( !pLocalOptions->GetOption(VOPT_SOLIDHANDLES) ); // inverted
+ aBigHandleCB.Check( pLocalOptions->GetOption(VOPT_BIGHANDLES) );
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_RANGEFINDER, FALSE, &pItem))
+ aRangeFindCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_OPT_SYNCZOOM, FALSE, &pItem))
+ aSyncZoomCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+ aRangeFindCB.SaveValue();
+ aSyncZoomCB.SaveValue();
+
+ aFormulaCB .SaveValue();
+ aNilCB .SaveValue();
+ aAnnotCB .SaveValue();
+ aValueCB .SaveValue();
+ aAnchorCB .SaveValue();
+ aClipMarkCB .SaveValue();
+ aObjGrfLB .SaveValue();
+ aDiagramLB .SaveValue();
+ aDrawLB .SaveValue();
+ aRowColHeaderCB .SaveValue();
+ aHScrollCB .SaveValue();
+ aVScrollCB .SaveValue();
+ aTblRegCB .SaveValue();
+ aOutlineCB .SaveValue();
+ aGridCB .SaveValue();
+ aColorLB .SaveValue();
+ aBreakCB .SaveValue();
+ aGuideLineCB .SaveValue();
+ aHandleCB .SaveValue();
+ aBigHandleCB .SaveValue();
+}
+/*-----------------11.01.97 12.45-------------------
+
+--------------------------------------------------*/
+
+void ScTpContentOptions::ActivatePage( const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ if(SFX_ITEM_SET == rSet.GetItemState(SID_SCVIEWOPTIONS, FALSE , &pItem))
+ *pLocalOptions = ((const ScTpViewItem*)pItem)->GetViewOptions();
+}
+/*-----------------11.01.97 12.45-------------------
+
+--------------------------------------------------*/
+
+int ScTpContentOptions::DeactivatePage( SfxItemSet* pSetP )
+{
+ if(pSetP)
+ FillItemSet(*pSetP);
+ return SfxTabPage::LEAVE_PAGE;
+}
+/*-----------------11.01.97 13.43-------------------
+
+--------------------------------------------------*/
+
+IMPL_LINK( ScTpContentOptions, SelLbObjHdl, ListBox*, pLb )
+{
+ USHORT nSelPos = pLb->GetSelectEntryPos();
+ ScVObjMode eMode = ScVObjMode(nSelPos);
+ ScVObjType eType = VOBJ_TYPE_OLE;
+
+ if ( pLb == &aDiagramLB )
+ eType = VOBJ_TYPE_CHART;
+ else if ( pLb == &aDrawLB )
+ eType = VOBJ_TYPE_DRAW;
+
+ pLocalOptions->SetObjMode( eType, eMode );
+
+ return 0;
+}
+
+/*-----------------11.01.97 14.25-------------------
+
+--------------------------------------------------*/
+
+IMPL_LINK( ScTpContentOptions, CBHdl, CheckBox*, pBtn )
+{
+ ScViewOption eOption = VOPT_FORMULAS;
+ BOOL bChecked = pBtn->IsChecked();
+
+ if ( &aFormulaCB == pBtn ) eOption = VOPT_FORMULAS;
+ else if ( &aNilCB == pBtn ) eOption = VOPT_NULLVALS;
+ else if ( &aAnnotCB == pBtn ) eOption = VOPT_NOTES;
+ else if ( &aValueCB == pBtn ) eOption = VOPT_SYNTAX;
+ else if ( &aAnchorCB == pBtn ) eOption = VOPT_ANCHOR;
+ else if ( &aClipMarkCB == pBtn ) eOption = VOPT_CLIPMARKS;
+ else if ( &aVScrollCB == pBtn ) eOption = VOPT_VSCROLL;
+ else if ( &aHScrollCB == pBtn ) eOption = VOPT_HSCROLL;
+ else if ( &aTblRegCB == pBtn ) eOption = VOPT_TABCONTROLS;
+ else if ( &aOutlineCB == pBtn ) eOption = VOPT_OUTLINER;
+ else if ( &aBreakCB == pBtn ) eOption = VOPT_PAGEBREAKS;
+ else if ( &aGuideLineCB == pBtn ) eOption = VOPT_HELPLINES;
+ else if ( &aHandleCB == pBtn ) eOption = VOPT_SOLIDHANDLES;
+ else if ( &aBigHandleCB == pBtn ) eOption = VOPT_BIGHANDLES;
+ else if ( &aRowColHeaderCB == pBtn ) eOption = VOPT_HEADER;
+
+ // VOPT_SOLIDHANDLES is inverted (CheckBox is "simple handles")
+ if ( eOption == VOPT_SOLIDHANDLES )
+ pLocalOptions->SetOption( eOption, !bChecked );
+ else
+ pLocalOptions->SetOption( eOption, bChecked );
+
+
+ return 0;
+}
+/*-----------------11.01.97 13.13-------------------
+
+--------------------------------------------------*/
+
+void ScTpContentOptions::InitGridOpt()
+{
+ BOOL bGrid = pLocalOptions->GetOption( VOPT_GRID );
+
+ aGridCB.Check( bGrid );
+
+ if ( bGrid )
+ aColorFT.Enable(), aColorLB.Enable();
+ else
+ aColorFT.Disable(), aColorLB.Disable();
+
+ if ( aColorLB.GetEntryCount() == 0 )
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ // hier koennte auch eine andere DocShell kommen!
+ pDocSh = PTR_CAST(ScDocShell, pDocSh);
+
+ XColorTable* pColorTable = NULL;
+
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
+
+ if ( pItem )
+ pColorTable = ((SvxColorTableItem*)pItem)->GetColorTable();
+ }
+ else
+ pColorTable = XColorTable::GetStdColorTable();
+
+ if ( !pColorTable )
+ return;
+
+ //------------------------------------------------------
+
+ aColorLB.SetUpdateMode( FALSE );
+
+ // Eintraege aus der Colortable
+
+ long nCount = pColorTable->Count();
+ for ( long n=0; n<nCount; n++ )
+ {
+ XColorEntry* pEntry = pColorTable->GetColor(n);
+ aColorLB.InsertEntry( pEntry->GetColor(), pEntry->GetName() );
+ }
+
+ // Standard-Gitterfarbe
+
+ Color aStdCol( SC_STD_GRIDCOLOR ); // wie Default in ScViewOptions
+ if ( LISTBOX_ENTRY_NOTFOUND ==
+ aColorLB.GetEntryPos( aStdCol ) )
+ aColorLB.InsertEntry( aStdCol, ScGlobal::GetRscString( STR_GRIDCOLOR ) );
+
+ aColorLB.SetUpdateMode( TRUE );
+
+ Invalidate();
+ }
+
+ // #79720# also select grid color entry on subsequent calls
+
+ String aName;
+ Color aCol = pLocalOptions->GetGridColor( &aName );
+ USHORT nSelPos = aColorLB.GetEntryPos( aCol );
+
+ if ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
+ aColorLB.SelectEntryPos( nSelPos );
+ else
+ aColorLB.SelectEntryPos( aColorLB.InsertEntry( aCol, aName ) );
+}
+/*-----------------11.01.97 13.40-------------------
+
+--------------------------------------------------*/
+
+IMPL_LINK( ScTpContentOptions, GridHdl, CheckBox*, pBox )
+{
+ BOOL bChecked = pBox->IsChecked();
+ aColorFT.Enable(bChecked);
+ aColorLB.Enable(bChecked);
+ pLocalOptions->SetOption( VOPT_GRID, bChecked );
+ return 0;
+}
+/*-----------------11.01.97 10.53-------------------
+
+--------------------------------------------------*/
+
+ScTpLayoutOptions::ScTpLayoutOptions( Window* pParent,
+ const SfxItemSet& rArgSet ) :
+ SfxTabPage(pParent, ScResId( RID_SCPAGE_LAYOUT ), rArgSet),
+ aUnitGB( this, ScResId(GB_UNIT )),
+ aUnitFT( this, ScResId(FT_UNIT )),
+ aUnitLB( this, ScResId(LB_UNIT )),
+ aTabFT( this, ScResId( FT_TAB )),
+ aTabMF( this, ScResId( MF_TAB )),
+ aSeparatorFL( this, ScResId( FL_SEPARATOR )),
+ aLinkGB (this, ScResId(GB_LINK )),
+ aLinkFT(this, ScResId(FT_UPDATE_LINKS )),
+ aAlwaysRB (this, ScResId(RB_ALWAYS )),
+ aRequestRB (this, ScResId(RB_REQUEST )),
+ aNeverRB (this, ScResId(RB_NEVER )),
+
+ aOptionsGB( this, ScResId( GB_OPTIONS )),
+ aAlignCB ( this, ScResId( CB_ALIGN )),
+ aAlignLB ( this, ScResId( LB_ALIGN )),
+ aEditModeCB( this, ScResId( CB_EDITMODE )),
+ aFormatCB( this, ScResId( CB_FORMAT )),
+ aExpRefCB( this, ScResId( CB_EXPREF )),
+ aMarkHdrCB( this, ScResId( CB_MARKHDR )),
+ aTextFmtCB( this, ScResId( CB_TEXTFMT )),
+ aReplWarnCB( this, ScResId( CB_REPLWARN )),
+ aUnitArr( ScResId(ST_UNIT )),
+ pDoc(NULL)
+{
+ FreeResource();
+ aSeparatorFL.SetStyle( aSeparatorFL.GetStyle() | WB_VERT );
+ SetExchangeSupport();
+
+ aUnitLB. SetSelectHdl( LINK( this, ScTpLayoutOptions, MetricHdl ) );
+
+ aAlignCB.SetClickHdl(LINK(this, ScTpLayoutOptions, AlignHdl));
+
+
+ for ( USHORT i = 0; i < aUnitArr.Count(); ++i )
+ {
+ String sMetric = aUnitArr.GetStringByPos( i );
+ FieldUnit eFUnit = (FieldUnit)aUnitArr.GetValue( i );
+
+ switch ( eFUnit )
+ {
+ case FUNIT_MM:
+ case FUNIT_CM:
+ case FUNIT_POINT:
+ case FUNIT_PICA:
+ case FUNIT_INCH:
+ {
+ // nur diese Metriken benutzen
+ USHORT nPos = aUnitLB.InsertEntry( sMetric );
+ aUnitLB.SetEntryData( nPos, (void*)(long)eFUnit );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+}
+/*-----------------11.01.97 10.53-------------------
+
+--------------------------------------------------*/
+
+ScTpLayoutOptions::~ScTpLayoutOptions()
+{
+}
+/*-----------------11.01.97 10.53-------------------
+
+--------------------------------------------------*/
+
+SfxTabPage* ScTpLayoutOptions::Create( Window* pParent,
+ const SfxItemSet& rCoreSet )
+{
+ ScTpLayoutOptions* pNew = new ScTpLayoutOptions(pParent, rCoreSet);
+ ScDocShell* pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current());
+
+ if(pDocSh!=NULL)
+ pNew->SetDocument(pDocSh->GetDocument());
+ return pNew;
+}
+/*-----------------11.01.97 10.53-------------------
+
+--------------------------------------------------*/
+
+BOOL ScTpLayoutOptions::FillItemSet( SfxItemSet& rCoreSet )
+{
+ BOOL bRet = TRUE;
+ const USHORT nMPos = aUnitLB.GetSelectEntryPos();
+ if ( nMPos != aUnitLB.GetSavedValue() )
+ {
+ USHORT nFieldUnit = (USHORT)(long)aUnitLB.GetEntryData( nMPos );
+ rCoreSet.Put( SfxUInt16Item( SID_ATTR_METRIC,
+ (UINT16)nFieldUnit ) );
+ bRet = TRUE;
+ }
+
+ if(aTabMF.GetText() != aTabMF.GetSavedValue())
+ {
+ rCoreSet.Put(SfxUInt16Item(SID_ATTR_DEFTABSTOP,
+ sal::static_int_cast<UINT16>( aTabMF.Denormalize(aTabMF.GetValue(FUNIT_TWIP)) )));
+ bRet = TRUE;
+ }
+
+ ScLkUpdMode nSet=LM_ALWAYS;
+
+ if(aRequestRB.IsChecked())
+ {
+ nSet=LM_ON_DEMAND;
+ }
+ else if(aNeverRB.IsChecked())
+ {
+ nSet=LM_NEVER;
+ }
+
+ if(aRequestRB.IsChecked() != aRequestRB.GetSavedValue() ||
+ aNeverRB.IsChecked() != aNeverRB.GetSavedValue() )
+ {
+ if(pDoc)
+ pDoc->SetLinkMode(nSet);
+ ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
+ aAppOptions.SetLinkMode(nSet );
+ SC_MOD()->SetAppOptions(aAppOptions);
+ bRet = TRUE;
+ }
+ if(aAlignCB.GetSavedValue() != aAlignCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_SELECTION, aAlignCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+ if(aAlignLB.GetSavedValue() != aAlignLB.GetSelectEntryPos())
+ {
+ rCoreSet.Put(SfxUInt16Item(SID_SC_INPUT_SELECTIONPOS, aAlignLB.GetSelectEntryPos()));
+ bRet = TRUE;
+ }
+
+ if(aEditModeCB.GetSavedValue() != aEditModeCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_EDITMODE, aEditModeCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+ if(aFormatCB.GetSavedValue() != aFormatCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_FMT_EXPAND, aFormatCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+
+ if(aExpRefCB.GetSavedValue() != aExpRefCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_REF_EXPAND, aExpRefCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+ if(aMarkHdrCB.GetSavedValue() != aMarkHdrCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_MARK_HEADER, aMarkHdrCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+ if(aTextFmtCB.GetSavedValue() != aTextFmtCB.IsChecked())
+ {
+ rCoreSet.Put(SfxBoolItem(SID_SC_INPUT_TEXTWYSIWYG, aTextFmtCB.IsChecked()));
+ bRet = TRUE;
+ }
+
+ if( aReplWarnCB.GetSavedValue() != aReplWarnCB.IsChecked() )
+ {
+ rCoreSet.Put( SfxBoolItem( SID_SC_INPUT_REPLCELLSWARN, aReplWarnCB.IsChecked() ) );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+/*-----------------11.01.97 10.53-------------------
+
+--------------------------------------------------*/
+
+void ScTpLayoutOptions::Reset( const SfxItemSet& rCoreSet )
+{
+ aUnitLB.SetNoSelection();
+ if ( rCoreSet.GetItemState( SID_ATTR_METRIC ) >= SFX_ITEM_AVAILABLE )
+ {
+ const SfxUInt16Item& rItem = (SfxUInt16Item&)rCoreSet.Get( SID_ATTR_METRIC );
+ FieldUnit eFieldUnit = (FieldUnit)rItem.GetValue();
+
+ for ( USHORT i = 0; i < aUnitLB.GetEntryCount(); ++i )
+ {
+ if ( (FieldUnit)(long)aUnitLB.GetEntryData( i ) == eFieldUnit )
+ {
+ aUnitLB.SelectEntryPos( i );
+ break;
+ }
+ }
+ ::SetFieldUnit(aTabMF, eFieldUnit);
+ }
+ aUnitLB.SaveValue();
+
+ const SfxPoolItem* pItem;
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_ATTR_DEFTABSTOP, FALSE, &pItem))
+ aTabMF.SetValue(aTabMF.Normalize(((SfxUInt16Item*)pItem)->GetValue()), FUNIT_TWIP);
+ aTabMF.SaveValue();
+
+ aUnitLB .SaveValue();
+ aTabMF .SaveValue();
+
+ ScLkUpdMode nSet=LM_UNKNOWN;
+
+ if(pDoc!=NULL)
+ {
+ nSet=pDoc->GetLinkMode();
+ }
+
+ if(nSet==LM_UNKNOWN)
+ {
+ ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
+ nSet=aAppOptions.GetLinkMode();
+ }
+
+ switch(nSet)
+ {
+ case LM_ALWAYS: aAlwaysRB. Check(); break;
+ case LM_NEVER: aNeverRB. Check(); break;
+ case LM_ON_DEMAND: aRequestRB. Check(); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_SELECTION, FALSE, &pItem))
+ aAlignCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_SELECTIONPOS, FALSE, &pItem))
+ aAlignLB.SelectEntryPos(((const SfxUInt16Item*)pItem)->GetValue());
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_EDITMODE, FALSE, &pItem))
+ aEditModeCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_FMT_EXPAND, FALSE, &pItem))
+ aFormatCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_REF_EXPAND, FALSE, &pItem))
+ aExpRefCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_MARK_HEADER, FALSE, &pItem))
+ aMarkHdrCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+ if(SFX_ITEM_SET == rCoreSet.GetItemState(SID_SC_INPUT_TEXTWYSIWYG, FALSE, &pItem))
+ aTextFmtCB.Check(((const SfxBoolItem*)pItem)->GetValue());
+
+ if( SFX_ITEM_SET == rCoreSet.GetItemState( SID_SC_INPUT_REPLCELLSWARN, FALSE, &pItem ) )
+ aReplWarnCB.Check( ( (const SfxBoolItem*)pItem)->GetValue() );
+
+ aAlignCB .SaveValue();
+ aAlignLB .SaveValue();
+ aEditModeCB .SaveValue();
+ aFormatCB .SaveValue();
+
+ aExpRefCB .SaveValue();
+ aMarkHdrCB .SaveValue();
+ aTextFmtCB .SaveValue();
+ aReplWarnCB .SaveValue();
+ AlignHdl(&aAlignCB);
+
+ aAlwaysRB.SaveValue();
+ aNeverRB.SaveValue();
+ aRequestRB.SaveValue();
+}
+
+/*-----------------11.01.97 12.46-------------------
+
+--------------------------------------------------*/
+
+void ScTpLayoutOptions::ActivatePage( const SfxItemSet& /* rCoreSet */ )
+{
+}
+/*-----------------11.01.97 12.46-------------------
+
+--------------------------------------------------*/
+
+int ScTpLayoutOptions::DeactivatePage( SfxItemSet* pSetP )
+{
+ if(pSetP)
+ FillItemSet(*pSetP);
+ return SfxTabPage::LEAVE_PAGE;
+}
+
+
+/*-----------------13.01.97 14.44-------------------
+ Metric des Deftabstops umschalten
+--------------------------------------------------*/
+
+IMPL_LINK(ScTpLayoutOptions, MetricHdl, ListBox*, EMPTYARG)
+{
+ const USHORT nMPos = aUnitLB.GetSelectEntryPos();
+ if(nMPos != USHRT_MAX)
+ {
+ FieldUnit eFieldUnit = (FieldUnit)(long)aUnitLB.GetEntryData( nMPos );
+ sal_Int64 nVal =
+ aTabMF.Denormalize( aTabMF.GetValue( FUNIT_TWIP ) );
+ ::SetFieldUnit( aTabMF, eFieldUnit );
+ aTabMF.SetValue( aTabMF.Normalize( nVal ), FUNIT_TWIP );
+ }
+
+ return 0;
+}
+/*-----------------11.01.97 15.30-------------------
+
+--------------------------------------------------*/
+IMPL_LINK( ScTpLayoutOptions, AlignHdl, CheckBox*, pBox )
+{
+ aAlignLB.Enable(pBox->IsChecked());
+ return 0;
+}
+
+
diff --git a/sc/source/ui/pagedlg/areasdlg.cxx b/sc/source/ui/pagedlg/areasdlg.cxx
new file mode 100644
index 000000000000..915355d5d0f2
--- /dev/null
+++ b/sc/source/ui/pagedlg/areasdlg.cxx
@@ -0,0 +1,906 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <rangelst.hxx>
+
+#include <sfx2/dispatch.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/msgbox.hxx>
+#include <unotools/charclass.hxx>
+#include <stdlib.h>
+
+#define _AREASDLG_CXX
+#include "areasdlg.hxx"
+#undef _AREASDLG_CXX
+
+#include "scresid.hxx"
+#include "rangenam.hxx"
+#include "reffact.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "globstr.hrc"
+#include "pagedlg.hrc"
+#include "compiler.hxx"
+
+// STATIC DATA ---------------------------------------------------------------
+
+// List box positions for print range (PR)
+const USHORT SC_AREASDLG_PR_NONE = 0;
+const USHORT SC_AREASDLG_PR_ENTIRE = 1;
+const USHORT SC_AREASDLG_PR_USER = 2;
+const USHORT SC_AREASDLG_PR_SELECT = 3;
+const USHORT SC_AREASDLG_PR_OFFSET = 4;
+
+// List box positions for repeat ranges (RR)
+const USHORT SC_AREASDLG_RR_NONE = 0;
+const USHORT SC_AREASDLG_RR_USER = 1;
+const USHORT SC_AREASDLG_RR_OFFSET = 2;
+
+//============================================================================
+
+#define HDL(hdl) LINK( this, ScPrintAreasDlg, hdl )
+#define ERRORBOX(nId) ErrorBox( this, WinBits(WB_OK|WB_DEF_OK), \
+ ScGlobal::GetRscString( nId ) ).Execute()
+#define SWAP(x1,x2) { int n=x1; x1=x2; x2=n; }
+
+// globale Funktionen (->am Ende der Datei):
+
+bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange );
+void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr );
+
+#if 0
+static void printAddressFlags(USHORT nFlag)
+{
+ if ((nFlag & SCA_COL_ABSOLUTE ) == SCA_COL_ABSOLUTE ) printf("SCA_COL_ABSOLUTE \n");
+ if ((nFlag & SCA_ROW_ABSOLUTE ) == SCA_ROW_ABSOLUTE ) printf("SCA_ROW_ABSOLUTE \n");
+ if ((nFlag & SCA_TAB_ABSOLUTE ) == SCA_TAB_ABSOLUTE ) printf("SCA_TAB_ABSOLUTE \n");
+ if ((nFlag & SCA_TAB_3D ) == SCA_TAB_3D ) printf("SCA_TAB_3D \n");
+ if ((nFlag & SCA_COL2_ABSOLUTE ) == SCA_COL2_ABSOLUTE ) printf("SCA_COL2_ABSOLUTE\n");
+ if ((nFlag & SCA_ROW2_ABSOLUTE ) == SCA_ROW2_ABSOLUTE ) printf("SCA_ROW2_ABSOLUTE\n");
+ if ((nFlag & SCA_TAB2_ABSOLUTE ) == SCA_TAB2_ABSOLUTE ) printf("SCA_TAB2_ABSOLUTE\n");
+ if ((nFlag & SCA_TAB2_3D ) == SCA_TAB2_3D ) printf("SCA_TAB2_3D \n");
+ if ((nFlag & SCA_VALID_ROW ) == SCA_VALID_ROW ) printf("SCA_VALID_ROW \n");
+ if ((nFlag & SCA_VALID_COL ) == SCA_VALID_COL ) printf("SCA_VALID_COL \n");
+ if ((nFlag & SCA_VALID_TAB ) == SCA_VALID_TAB ) printf("SCA_VALID_TAB \n");
+ if ((nFlag & SCA_FORCE_DOC ) == SCA_FORCE_DOC ) printf("SCA_FORCE_DOC \n");
+ if ((nFlag & SCA_VALID_ROW2 ) == SCA_VALID_ROW2 ) printf("SCA_VALID_ROW2 \n");
+ if ((nFlag & SCA_VALID_COL2 ) == SCA_VALID_COL2 ) printf("SCA_VALID_COL2 \n");
+ if ((nFlag & SCA_VALID_TAB2 ) == SCA_VALID_TAB2 ) printf("SCA_VALID_TAB2 \n");
+ if ((nFlag & SCA_VALID ) == SCA_VALID ) printf("SCA_VALID \n");
+ if ((nFlag & SCA_ABS ) == SCA_ABS ) printf("SCA_ABS \n");
+ if ((nFlag & SCR_ABS ) == SCR_ABS ) printf("SCR_ABS \n");
+ if ((nFlag & SCA_ABS_3D ) == SCA_ABS_3D ) printf("SCA_ABS_3D \n");
+ if ((nFlag & SCR_ABS_3D ) == SCR_ABS_3D ) printf("SCR_ABS_3D \n");
+}
+#endif
+
+//============================================================================
+// class ScPrintAreasDlg
+
+//----------------------------------------------------------------------------
+
+ScPrintAreasDlg::ScPrintAreasDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent )
+ : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_AREAS),
+ //
+ aLbPrintArea ( this, ScResId( LB_PRINTAREA ) ),
+ aFlPrintArea ( this, ScResId( FL_PRINTAREA ) ),
+ aEdPrintArea ( this, this, ScResId( ED_PRINTAREA ) ),
+ aRbPrintArea ( this, ScResId( RB_PRINTAREA ), &aEdPrintArea, this ),
+ //
+ aLbRepeatRow ( this, ScResId( LB_REPEATROW ) ),
+ aFlRepeatRow ( this, ScResId( FL_REPEATROW ) ),
+ aEdRepeatRow ( this, this, ScResId( ED_REPEATROW ) ),
+ aRbRepeatRow ( this, ScResId( RB_REPEATROW ), &aEdRepeatRow, this ),
+ //
+ aLbRepeatCol ( this, ScResId( LB_REPEATCOL ) ),
+ aFlRepeatCol ( this, ScResId( FL_REPEATCOL ) ),
+ aEdRepeatCol ( this, this, ScResId( ED_REPEATCOL ) ),
+ aRbRepeatCol ( this, ScResId( RB_REPEATCOL ), &aEdRepeatCol, this ),
+ //
+ aBtnOk ( this, ScResId( BTN_OK ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
+ aBtnHelp ( this, ScResId( BTN_HELP ) ),
+ //
+ bDlgLostFocus ( FALSE ),
+ pRefInputEdit ( &aEdPrintArea ),
+ pDoc ( NULL ),
+ pViewData ( NULL ),
+ nCurTab ( 0 )
+{
+ ScTabViewShell* pScViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ ScDocShell* pScDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
+
+ DBG_ASSERT( pScDocSh, "Current DocumentShell not found :-(" );
+
+ pDoc = pScDocSh->GetDocument();
+
+ if ( pScViewSh )
+ {
+ pViewData = pScViewSh->GetViewData();
+ nCurTab = pViewData->GetTabNo();
+ }
+
+ Impl_Reset();
+
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
+
+ FreeResource();
+}
+
+
+//----------------------------------------------------------------------------
+
+ScPrintAreasDlg::~ScPrintAreasDlg()
+{
+ // Extra-Data an ListBox-Entries abraeumen
+ ListBox* pLb[3] = { &aLbPrintArea, &aLbRepeatRow, &aLbRepeatCol };
+
+ for ( USHORT i=0; i<3; i++ )
+ {
+ USHORT nCount = pLb[i]->GetEntryCount();
+ for ( USHORT j=0; j<nCount; j++ )
+ delete (String*)pLb[i]->GetEntryData(j);
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScPrintAreasDlg::Close()
+{
+ return DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScPrintAreasDlg::IsTableLocked() const
+{
+ // Druckbereiche gelten pro Tabelle, darum macht es keinen Sinn,
+ // bei der Eingabe die Tabelle umzuschalten
+
+ return TRUE;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument* /* pDoc */ )
+{
+ if ( pRefInputEdit )
+ {
+ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( pRefInputEdit );
+
+ String aStr;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ if ( &aEdPrintArea == pRefInputEdit )
+ {
+ rRef.Format( aStr, SCR_ABS, pDoc, eConv );
+
+// aEdPrintArea.ReplaceSelected( aStr );
+
+ String aVal = aEdPrintArea.GetText();
+ Selection aSel = aEdPrintArea.GetSelection();
+ aSel.Justify();
+ aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ aVal.Insert( aStr, (xub_StrLen)aSel.Min() );
+ Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() );
+ aEdPrintArea.SetRefString( aVal );
+ aEdPrintArea.SetSelection( aNewSel );
+ }
+ else
+ {
+ BOOL bRow = ( &aEdRepeatRow == pRefInputEdit );
+ lcl_GetRepeatRangeString(&rRef, pDoc, bRow, aStr);
+ pRefInputEdit->SetRefString( aStr );
+ }
+ }
+
+ Impl_ModifyHdl( pRefInputEdit );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScPrintAreasDlg::AddRefEntry()
+{
+ if ( pRefInputEdit == &aEdPrintArea )
+ {
+ const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ String aVal = aEdPrintArea.GetText();
+ aVal += sep;
+ aEdPrintArea.SetText(aVal);
+
+ xub_StrLen nLen = aVal.Len();
+ aEdPrintArea.SetSelection( Selection( nLen, nLen ) );
+
+ Impl_ModifyHdl( &aEdPrintArea );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScPrintAreasDlg::Deactivate()
+{
+ bDlgLostFocus = TRUE;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScPrintAreasDlg::SetActive()
+{
+ if ( bDlgLostFocus )
+ {
+ bDlgLostFocus = FALSE;
+
+ if ( pRefInputEdit )
+ {
+ pRefInputEdit->GrabFocus();
+ Impl_ModifyHdl( pRefInputEdit );
+ }
+ }
+ else
+ GrabFocus();
+
+ RefInputDone();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScPrintAreasDlg::Impl_Reset()
+{
+ String aStrRange;
+ const ScRange* pRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
+ const ScRange* pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );
+
+ aEdPrintArea.SetModifyHdl ( HDL(Impl_ModifyHdl) );
+ aEdRepeatRow.SetModifyHdl ( HDL(Impl_ModifyHdl) );
+ aEdRepeatCol.SetModifyHdl ( HDL(Impl_ModifyHdl) );
+ aEdPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
+ aEdRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
+ aEdRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
+ aLbPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
+ aLbRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
+ aLbRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
+ aLbPrintArea.SetSelectHdl ( HDL(Impl_SelectHdl) );
+ aLbRepeatRow.SetSelectHdl ( HDL(Impl_SelectHdl) );
+ aLbRepeatCol.SetSelectHdl ( HDL(Impl_SelectHdl) );
+ aBtnOk .SetClickHdl ( HDL(Impl_BtnHdl) );
+ aBtnCancel .SetClickHdl ( HDL(Impl_BtnHdl) );
+
+ Impl_FillLists();
+
+ //-------------------------
+ // Druckbereich
+ //-------------------------
+ aStrRange.Erase();
+ String aOne;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ USHORT nRangeCount = pDoc->GetPrintRangeCount( nCurTab );
+ for (USHORT i=0; i<nRangeCount; i++)
+ {
+ const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i );
+ if (pPrintRange)
+ {
+ if ( aStrRange.Len() )
+ aStrRange += sep;
+ pPrintRange->Format( aOne, SCR_ABS, pDoc, eConv );
+ aStrRange += aOne;
+ }
+ }
+ aEdPrintArea.SetText( aStrRange );
+
+ //-------------------------------
+ // Wiederholungszeile
+ //-------------------------------
+ lcl_GetRepeatRangeString(pRepeatRowRange, pDoc, true, aStrRange);
+ aEdRepeatRow.SetText( aStrRange );
+
+ //--------------------------------
+ // Wiederholungsspalte
+ //--------------------------------
+ lcl_GetRepeatRangeString(pRepeatColRange, pDoc, false, aStrRange);
+ aEdRepeatCol.SetText( aStrRange );
+
+ Impl_ModifyHdl( &aEdPrintArea );
+ Impl_ModifyHdl( &aEdRepeatRow );
+ Impl_ModifyHdl( &aEdRepeatCol );
+ if( pDoc->IsPrintEntireSheet( nCurTab ) )
+ aLbPrintArea.SelectEntryPos( SC_AREASDLG_PR_ENTIRE );
+
+ aEdPrintArea.SaveValue(); // fuer FillItemSet() merken:
+ aEdRepeatRow.SaveValue();
+ aEdRepeatCol.SaveValue();
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScPrintAreasDlg::Impl_GetItem( Edit* pEd, SfxStringItem& rItem )
+{
+ String aRangeStr = pEd->GetText();
+ BOOL bDataChanged = (pEd->GetSavedValue() != aRangeStr);
+
+ if ( (aRangeStr.Len() > 0) && &aEdPrintArea != pEd )
+ {
+ ScRange aRange;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ lcl_CheckRepeatString(aRangeStr, pDoc, &aEdRepeatRow == pEd, &aRange);
+ aRange.Format(aRangeStr, SCR_ABS, pDoc, eConv);
+ }
+
+ rItem.SetValue( aRangeStr );
+
+ return bDataChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScPrintAreasDlg::Impl_CheckRefStrings()
+{
+ BOOL bOk = FALSE;
+ String aStrPrintArea = aEdPrintArea.GetText();
+ String aStrRepeatRow = aEdRepeatRow.GetText();
+ String aStrRepeatCol = aEdRepeatCol.GetText();
+
+ BOOL bPrintAreaOk = TRUE;
+ if ( aStrPrintArea.Len() )
+ {
+ const USHORT nValidAddr = SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
+ const USHORT nValidRange = nValidAddr | SCA_VALID_ROW2 | SCA_VALID_COL2;
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ // const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);
+
+ ScAddress aAddr;
+ ScRange aRange;
+ xub_StrLen nSepCount = aStrPrintArea.GetTokenCount(sep);
+ for ( xub_StrLen i = 0; i < nSepCount && bPrintAreaOk; ++i )
+ {
+ String aOne = aStrPrintArea.GetToken(i, sep);
+ USHORT nResult = aRange.Parse( aOne, pDoc, eConv );
+ if ((nResult & nValidRange) != nValidRange)
+ {
+ USHORT nAddrResult = aAddr.Parse( aOne, pDoc, eConv );
+ if ((nAddrResult & nValidAddr) != nValidAddr)
+ bPrintAreaOk = FALSE;
+ }
+ }
+ }
+
+ BOOL bRepeatRowOk = (aStrRepeatRow.Len() == 0);
+ if ( !bRepeatRowOk )
+ bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, pDoc, true, NULL);
+
+ BOOL bRepeatColOk = (aStrRepeatCol.Len() == 0);
+ if ( !bRepeatColOk )
+ bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, pDoc, false, NULL);
+
+ // Fehlermeldungen
+
+ bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk);
+
+ if ( !bOk )
+ {
+ Edit* pEd = NULL;
+
+ if ( !bPrintAreaOk ) pEd = &aEdPrintArea;
+ else if ( !bRepeatRowOk ) pEd = &aEdRepeatRow;
+ else if ( !bRepeatColOk ) pEd = &aEdRepeatCol;
+
+ ERRORBOX( STR_INVALID_TABREF );
+ pEd->GrabFocus();
+ }
+
+ return bOk;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScPrintAreasDlg::Impl_FillLists()
+{
+ //------------------------------------------------------
+ // Selektion holen und String in PrintArea-ListBox merken
+ //------------------------------------------------------
+ ScRange aRange;
+ String aStrRange;
+ BOOL bSimple = TRUE;
+
+ if ( pViewData )
+ bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE);
+
+ formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ if ( bSimple )
+ aRange.Format( aStrRange, SCR_ABS, pDoc, eConv );
+ else
+ {
+ ScRangeListRef aList( new ScRangeList );
+ pViewData->GetMarkData().FillRangeListWithMarks( aList, FALSE );
+ aList->Format( aStrRange, SCR_ABS, pDoc, eConv );
+ }
+
+ aLbPrintArea.SetEntryData( SC_AREASDLG_PR_SELECT, new String( aStrRange ) );
+
+ //------------------------------------------------------
+ // Ranges holen und in ListBoxen merken
+ //------------------------------------------------------
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ const USHORT nCount = pRangeNames ? pRangeNames->GetCount() : 0;
+
+ if ( nCount > 0 )
+ {
+ String aName;
+ String aSymbol;
+// ScRange aRange;
+ ScRangeData* pData = NULL;
+
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ pData = (ScRangeData*)(pRangeNames->At( i ));
+ if ( pData )
+ {
+ if ( pData->HasType( RT_ABSAREA )
+ || pData->HasType( RT_REFAREA )
+ || pData->HasType( RT_ABSPOS ) )
+ {
+ pData->GetName( aName );
+ pData->GetSymbol( aSymbol );
+ if ( aRange.ParseAny( aSymbol, pDoc, eConv ) & SCA_VALID )
+ {
+ if ( pData->HasType( RT_PRINTAREA ) )
+ {
+ aRange.Format( aSymbol, SCR_ABS, pDoc, eConv );
+ aLbPrintArea.SetEntryData(
+ aLbPrintArea.InsertEntry( aName ),
+ new String( aSymbol ) );
+ }
+
+ if ( pData->HasType( RT_ROWHEADER ) )
+ {
+ lcl_GetRepeatRangeString(&aRange, pDoc, true, aSymbol);
+ aLbRepeatRow.SetEntryData(
+ aLbRepeatRow.InsertEntry( aName ),
+ new String( aSymbol ) );
+ }
+
+ if ( pData->HasType( RT_COLHEADER ) )
+ {
+ lcl_GetRepeatRangeString(&aRange, pDoc, false, aSymbol);
+ aLbRepeatCol.SetEntryData(
+ aLbRepeatCol.InsertEntry( aName ),
+ new String( aSymbol ) );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Handler:
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScPrintAreasDlg, Impl_BtnHdl, PushButton*, pBtn )
+{
+ if ( &aBtnOk == pBtn )
+ {
+ if ( Impl_CheckRefStrings() )
+ {
+ BOOL bDataChanged = FALSE;
+ String aStr;
+ SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, aStr );
+ SfxStringItem aRepeatRow( FN_PARAM_2, aStr );
+ SfxStringItem aRepeatCol( FN_PARAM_3, aStr );
+
+ //-------------------------
+ // Druckbereich veraendert?
+ //-------------------------
+
+ // first try the list box, if "Entite sheet" is selected
+ BOOL bEntireSheet = (aLbPrintArea.GetSelectEntryPos() == SC_AREASDLG_PR_ENTIRE);
+ SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
+
+ bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
+ if( !bEntireSheet )
+ {
+ // if new list box selection is not "Entire sheet", get the edit field contents
+ bDataChanged |= Impl_GetItem( &aEdPrintArea, aPrintArea );
+ }
+
+ //-------------------------------
+ // Wiederholungszeile veraendert?
+ //-------------------------------
+ bDataChanged |= Impl_GetItem( &aEdRepeatRow, aRepeatRow );
+
+ //--------------------------------
+ // Wiederholungsspalte veraendert?
+ //--------------------------------
+ bDataChanged |= Impl_GetItem( &aEdRepeatCol, aRepeatCol );
+
+ if ( bDataChanged )
+ {
+ SetDispatcherLock( FALSE );
+ SwitchToDocument();
+ GetBindings().GetDispatcher()->Execute( SID_CHANGE_PRINTAREA,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet, 0L );
+ }
+
+ Close();
+ }
+ }
+ else if ( &aBtnCancel == pBtn )
+ Close();
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScPrintAreasDlg, Impl_GetFocusHdl, Control*, pCtr )
+{
+ if ( pCtr ==(Control *) &aEdPrintArea ||
+ pCtr ==(Control *) &aEdRepeatRow ||
+ pCtr ==(Control *) &aEdRepeatCol)
+ {
+ pRefInputEdit = (formula::RefEdit*) pCtr;
+ }
+ else if ( pCtr ==(Control *) &aLbPrintArea)
+ {
+ pRefInputEdit = &aEdPrintArea;
+ }
+ else if ( pCtr ==(Control *) &aLbRepeatRow)
+ {
+ pRefInputEdit = &aEdRepeatRow;
+ }
+ else if ( pCtr ==(Control *) &aLbRepeatCol)
+ {
+ pRefInputEdit = &aEdRepeatCol;
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, ListBox*, pLb )
+{
+ USHORT nSelPos = pLb->GetSelectEntryPos();
+ Edit* pEd = NULL;
+
+ // list box positions of specific entries, default to "repeat row/column" list boxes
+ USHORT nAllSheetPos = SC_AREASDLG_RR_NONE;
+ USHORT nUserDefPos = SC_AREASDLG_RR_USER;
+ USHORT nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
+
+ // find edit field for list box, and list box positions
+ if( pLb == &aLbPrintArea )
+ {
+ pEd = &aEdPrintArea;
+ nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
+ nUserDefPos = SC_AREASDLG_PR_USER;
+ nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
+ }
+ else if( pLb == &aLbRepeatCol )
+ pEd = &aEdRepeatCol;
+ else if( pLb == &aLbRepeatRow )
+ pEd = &aEdRepeatRow;
+ else
+ return 0;
+
+ // fill edit field according to list box selection
+ if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
+ pEd->SetText( EMPTY_STRING );
+ else if( nSelPos == nUserDefPos && !pLb->IsTravelSelect() && pEd->GetText().Len() == 0 )
+ pLb->SelectEntryPos( 0 );
+ else if( nSelPos >= nFirstCustomPos )
+ pEd->SetText( *static_cast< String* >( pLb->GetEntryData( nSelPos ) ) );
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit*, pEd )
+{
+ ListBox* pLb = NULL;
+
+ // list box positions of specific entries, default to "repeat row/column" list boxes
+ USHORT nUserDefPos = SC_AREASDLG_RR_USER;
+ USHORT nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
+
+ if( pEd == &aEdPrintArea )
+ {
+ pLb = &aLbPrintArea;
+ nUserDefPos = SC_AREASDLG_PR_USER;
+ nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
+ }
+ else if( pEd == &aEdRepeatCol )
+ pLb = &aLbRepeatCol;
+ else if( pEd == &aEdRepeatRow )
+ pLb = &aLbRepeatRow;
+ else
+ return 0;
+
+ // set list box selection according to edit field
+ USHORT nEntryCount = pLb->GetEntryCount();
+ String aStrEd( pEd->GetText() );
+ String aEdUpper = aStrEd;
+ aEdUpper.ToUpperAscii();
+
+ if ( (nEntryCount > nFirstCustomPos) && aStrEd.Len() > 0 )
+ {
+ BOOL bFound = FALSE;
+ String* pSymbol = NULL;
+ USHORT i;
+
+ for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
+ {
+ pSymbol = (String*)pLb->GetEntryData( i );
+ bFound = ( (*pSymbol == aStrEd) || (*pSymbol == aEdUpper) );
+ }
+
+ pLb->SelectEntryPos( bFound ? i-1 : nUserDefPos );
+ }
+ else
+ pLb->SelectEntryPos( aStrEd.Len() ? nUserDefPos : 0 );
+
+ return 0;
+}
+
+
+//============================================================================
+// globale Funktionen:
+
+// ----------------------------------------------------------------------------
+
+// TODO: It might make sense to move these functions to address.?xx. -kohei
+
+bool lcl_CheckOne_OOO( const String& rStr, bool bIsRow, SCCOLROW& rVal )
+{
+ // Zulaessige Syntax fuer rStr:
+ // Row: [$]1-MAXTAB
+ // Col: [$]A-IV
+
+ String aStr = rStr;
+ xub_StrLen nLen = aStr.Len();
+ SCCOLROW nNum = 0;
+ BOOL bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
+
+ if ( bStrOk )
+ {
+ if ( '$' == aStr.GetChar(0) )
+ aStr.Erase( 0, 1 );
+
+ if ( bIsRow )
+ {
+ bStrOk = CharClass::isAsciiNumeric(aStr);
+
+ if ( bStrOk )
+ {
+ sal_Int32 n = aStr.ToInt32();
+
+ if ( ( bStrOk = (n > 0) && ( n <= MAXROWCOUNT ) ) != FALSE )
+ nNum = static_cast<SCCOLROW>(n - 1);
+ }
+ }
+ else
+ {
+ SCCOL nCol = 0;
+ bStrOk = ::AlphaToCol( nCol, aStr);
+ nNum = nCol;
+ }
+ }
+
+ if ( bStrOk )
+ rVal = nNum;
+
+ return bStrOk;
+}
+
+bool lcl_CheckOne_XL_A1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
+{
+ // XL A1 style is identical to OOO one for print range formats.
+ return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
+}
+
+bool lcl_CheckOne_XL_R1C1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
+{
+ xub_StrLen nLen = rStr.Len();
+ if (nLen <= 1)
+ // There must be at least two characters.
+ return false;
+
+ const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
+ const sal_Unicode preLower = bIsRow ? 'r' : 'c';
+ if (rStr.GetChar(0) != preUpper && rStr.GetChar(0) != preLower)
+ return false;
+
+ String aNumStr = rStr.Copy(1);
+ if (!CharClass::isAsciiNumeric(aNumStr))
+ return false;
+
+ sal_Int32 nNum = aNumStr.ToInt32();
+
+ if (nNum <= 0)
+ return false;
+
+ if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
+ return false;
+
+ rVal = static_cast<SCCOLROW>(nNum-1);
+ return true;
+}
+
+bool lcl_CheckRepeatOne( const String& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
+{
+ switch (eConv)
+ {
+ case formula::FormulaGrammar::CONV_OOO:
+ return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
+ case formula::FormulaGrammar::CONV_XL_A1:
+ return lcl_CheckOne_XL_A1(rStr, bIsRow, rVal);
+ case formula::FormulaGrammar::CONV_XL_R1C1:
+ return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return false;
+}
+
+bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange )
+{
+ // Row: [valid row] rsep [valid row]
+ // Col: [valid col] rsep [valid col]
+
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);
+
+ if (pRange)
+ {
+ // initialize the range value.
+ pRange->aStart.SetCol(0);
+ pRange->aStart.SetRow(0);
+ pRange->aEnd.SetCol(0);
+ pRange->aEnd.SetRow(0);
+ }
+
+ String aBuf;
+ SCCOLROW nVal = 0;
+ xub_StrLen nLen = rStr.Len();
+ bool bEndPos = false;
+ for (xub_StrLen i = 0; i < nLen; ++i)
+ {
+ const sal_Unicode c = rStr.GetChar(i);
+ if (c == rsep)
+ {
+ if (bEndPos)
+ // We aren't supposed to have more than one range separator.
+ return false;
+
+ // range separator
+ if (aBuf.Len() == 0)
+ return false;
+
+ bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
+ if (!bRes)
+ return false;
+
+ if (pRange)
+ {
+ if (bIsRow)
+ {
+ pRange->aStart.SetRow(static_cast<SCROW>(nVal));
+ pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
+ }
+ else
+ {
+ pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
+ pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
+ }
+ }
+
+ aBuf.Erase();
+ bEndPos = true;
+ }
+ else
+ aBuf.Append(c);
+ }
+
+ if (aBuf.Len() > 0)
+ {
+ bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
+ if (!bRes)
+ return false;
+
+ if (pRange)
+ {
+ if (bIsRow)
+ {
+ if (!bEndPos)
+ pRange->aStart.SetRow(static_cast<SCROW>(nVal));
+ pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
+ }
+ else
+ {
+ if (!bEndPos)
+ pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
+ pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
+ }
+ }
+ }
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+
+void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr )
+{
+ rStr.Erase();
+ if (!pRange)
+ return;
+
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ const ScAddress& rStart = pRange->aStart;
+ const ScAddress& rEnd = pRange->aEnd;
+
+ const USHORT nFmt = bIsRow ? (SCA_VALID_ROW | SCA_ROW_ABSOLUTE) : (SCA_VALID_COL | SCA_COL_ABSOLUTE);
+ String aTmpStr;
+ rStart.Format(aTmpStr, nFmt, pDoc, eConv);
+ rStr += aTmpStr;
+ if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
+ {
+ rStr += ScCompiler::GetNativeSymbol(ocRange);
+ rEnd.Format(aTmpStr, nFmt, pDoc, eConv);
+ rStr += aTmpStr;
+ }
+}
+
diff --git a/sc/source/ui/pagedlg/hfedtdlg.cxx b/sc/source/ui/pagedlg/hfedtdlg.cxx
new file mode 100644
index 000000000000..52527d3f60ce
--- /dev/null
+++ b/sc/source/ui/pagedlg/hfedtdlg.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/eitem.hxx>
+
+#include "hfedtdlg.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+//CHINA001 #include "tphfedit.hxx"
+#include "scresid.hxx"
+#include "hfedtdlg.hrc"
+#include "scuitphfedit.hxx" //CHINA001
+//------------------------------------------------------------------
+
+// macros from docsh4.cxx
+//! use SIDs?
+
+#define IS_SHARE_HEADER(set) \
+ ((SfxBoolItem&) \
+ ((SvxSetItem&)(set).Get(ATTR_PAGE_HEADERSET)).GetItemSet(). \
+ Get(ATTR_PAGE_SHARED)).GetValue()
+
+#define IS_SHARE_FOOTER(set) \
+ ((SfxBoolItem&) \
+ ((SvxSetItem&)(set).Get(ATTR_PAGE_FOOTERSET)).GetItemSet(). \
+ Get(ATTR_PAGE_SHARED)).GetValue()
+
+//==================================================================
+
+ScHFEditDlg::ScHFEditDlg( SfxViewFrame* pFrameP,
+ Window* pParent,
+ const SfxItemSet& rCoreSet,
+ const String& rPageStyle,
+ USHORT nResIdP )
+ : SfxTabDialog( pFrameP, pParent, ScResId( nResIdP ), &rCoreSet )
+{
+ eNumType = ((const SvxPageItem&)rCoreSet.Get(ATTR_PAGE)).GetNumType();
+
+ String aTmp = GetText();
+
+ aTmp.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aTmp += ScGlobal::GetRscString( STR_PAGESTYLE );
+ aTmp.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+ aTmp += rPageStyle;
+ aTmp += ')';
+ SetText( aTmp );
+
+ switch ( nResIdP )
+ {
+ case RID_SCDLG_HFED_HEADER:
+ case RID_SCDLG_HFEDIT_HEADER:
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ AddTabPage( 2, ScLeftHeaderEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFED_FOOTER:
+ case RID_SCDLG_HFEDIT_FOOTER:
+ AddTabPage( 1, ScRightFooterEditPage::Create, NULL );
+ AddTabPage( 2, ScLeftFooterEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_LEFTHEADER:
+ AddTabPage( 1, ScLeftHeaderEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_RIGHTHEADER:
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_LEFTFOOTER:
+ AddTabPage( 1, ScLeftFooterEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_RIGHTFOOTER:
+ AddTabPage( 1, ScRightFooterEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_SHDR:
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ AddTabPage( 2, ScRightFooterEditPage::Create, NULL );
+ AddTabPage( 3, ScLeftFooterEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_SFTR:
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ AddTabPage( 2, ScLeftHeaderEditPage::Create, NULL );
+ AddTabPage( 3, ScRightFooterEditPage::Create, NULL );
+ break;
+
+ case RID_SCDLG_HFEDIT_ALL:
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ AddTabPage( 2, ScLeftHeaderEditPage::Create, NULL );
+ AddTabPage( 3, ScRightFooterEditPage::Create, NULL );
+ AddTabPage( 4, ScLeftFooterEditPage::Create, NULL );
+ break;
+
+ default:
+ case RID_SCDLG_HFEDIT:
+ {
+ const SvxPageItem& rPageItem = (const SvxPageItem&)
+ rCoreSet.Get(
+ rCoreSet.GetPool()->GetWhich(SID_ATTR_PAGE) );
+
+ BOOL bRightPage = ( SVX_PAGE_LEFT !=
+ SvxPageUsage(rPageItem.GetPageUsage()) );
+
+ if ( bRightPage )
+ {
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ AddTabPage( 2, ScRightFooterEditPage::Create, NULL );
+ }
+ else
+ {
+ // #69193a# respect "shared" setting
+
+ BOOL bShareHeader = IS_SHARE_HEADER(rCoreSet);
+ if ( bShareHeader )
+ AddTabPage( 1, ScRightHeaderEditPage::Create, NULL );
+ else
+ AddTabPage( 1, ScLeftHeaderEditPage::Create, NULL );
+
+ BOOL bShareFooter = IS_SHARE_FOOTER(rCoreSet);
+ if ( bShareFooter )
+ AddTabPage( 2, ScRightFooterEditPage::Create, NULL );
+ else
+ AddTabPage( 2, ScLeftFooterEditPage::Create, NULL );
+ }
+ }
+ break;
+ }
+
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScHFEditDlg::~ScHFEditDlg()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScHFEditDlg::PageCreated( USHORT /* nId */, SfxTabPage& rPage )
+{
+ // kann ja nur ne ScHFEditPage sein...
+
+ ((ScHFEditPage&)rPage).SetNumType(eNumType);
+}
+
+
+
+
diff --git a/sc/source/ui/pagedlg/hfedtdlg.hrc b/sc/source/ui/pagedlg/hfedtdlg.hrc
new file mode 100644
index 000000000000..30e6f8ecae63
--- /dev/null
+++ b/sc/source/ui/pagedlg/hfedtdlg.hrc
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+
+//#define RID_SCPAGE_HFEDIT 256
+//#define RID_SCDLG_HFEDIT 256
+
+#define FT_LEFT 1
+#define FT_CENTER 2
+#define FT_RIGHT 3
+#define FT_INFO 4
+#define WND_LEFT 1
+#define WND_CENTER 2
+#define WND_RIGHT 3
+#define BTN_TEXT 1
+#define BTN_PAGE 2
+#define BTN_PAGES 3
+#define BTN_DATE 4
+#define BTN_TIME 5
+#define BTN_FILE 6
+#define BTN_TABLE 7
+
+#define RID_POPUP_FCOMMAND 10
+#define FILE_COMMAND_TITEL 11
+#define FILE_COMMAND_FILENAME 12
+#define FILE_COMMAND_PATH 13
+
+#define FL_INFO 14
+
+#define IMG_TEXT_H 21
+#define IMG_PAGE_H 22
+#define IMG_PAGES_H 23
+#define IMG_DATE_H 24
+#define IMG_TIME_H 25
+#define IMG_FILE_H 26
+#define IMG_TABLE_H 27
+#define FT_HF_DEFINED 28
+#define LB_DEFINED 29
+#define FT_HF_CUSTOM 30
diff --git a/sc/source/ui/pagedlg/hfedtdlg.src b/sc/source/ui/pagedlg/hfedtdlg.src
new file mode 100644
index 000000000000..1445636e8cc6
--- /dev/null
+++ b/sc/source/ui/pagedlg/hfedtdlg.src
@@ -0,0 +1,829 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+/* StarView ressource file */
+#include "hfedtdlg.hrc"
+#define HFEDIT_DLGTITLE \
+ Text [ en-US ] = "Headers/Footers" ; \
+
+#define HEADER \
+ Text [ en-US ] = "Header" ; \
+
+#define FOOTER \
+ Text [ en-US ] = "Footer" ; \
+
+#define HEADER_RIGHT \
+ Text [ en-US ] = "Header (right)" ; \
+
+#define HEADER_LEFT \
+ Text [ en-US ] = "Header (left)" ; \
+
+#define FOOTER_RIGHT \
+ Text [ en-US ] = "Footer (right)" ; \
+
+#define FOOTER_LEFT \
+ Text [ en-US ] = "Footer (left)" ; \
+
+ //------------------------------------------------------------------------
+ // Bearbeiten vom Seitendialog aus aufgerufen
+ //------------------------------------------------------------------------
+TabDialog RID_SCDLG_HFED_HEADER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Text [ en-US ] = "Headers" ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER_RIGHT
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ HEADER_LEFT
+ PageResID = HID_SCPAGE_HFED_HL ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFED_FOOTER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Text [ en-US ] = "Footers" ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ FOOTER_RIGHT
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ FOOTER_LEFT
+ PageResID = HID_SCPAGE_HFED_FL ;
+ };
+ };
+ };
+};
+ //------------------------------------------------------------------------
+ // Bearbeiten/Kopf-Fusszeile:
+ //------------------------------------------------------------------------
+TabDialog RID_SCDLG_HFEDIT_ALL
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER_RIGHT
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ HEADER_LEFT
+ PageResID = HID_SCPAGE_HFED_HL ;
+ };
+ PageItem
+ {
+ Identifier = 3 ;
+ FOOTER_RIGHT
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ PageItem
+ {
+ Identifier = 4 ;
+ FOOTER_LEFT
+ PageResID = HID_SCPAGE_HFED_FL ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_SHDR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ FOOTER_RIGHT
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ PageItem
+ {
+ Identifier = 3 ;
+ FOOTER_LEFT
+ PageResID = HID_SCPAGE_HFED_FL ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_SFTR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER_RIGHT
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ HEADER_LEFT
+ PageResID = HID_SCPAGE_HFED_HL ;
+ };
+ PageItem
+ {
+ Identifier = 3 ;
+ FOOTER
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ FOOTER
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_HEADER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER_RIGHT
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ HEADER_LEFT
+ PageResID = HID_SCPAGE_HFED_HL ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_FOOTER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ FOOTER_RIGHT
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ PageItem
+ {
+ Identifier = 2 ;
+ FOOTER_LEFT
+ PageResID = HID_SCPAGE_HFED_FL ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_RIGHTHEADER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER_RIGHT
+ PageResID = HID_SCPAGE_HFED_HR ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_LEFTHEADER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ HEADER_LEFT
+ PageResID = HID_SCPAGE_HFED_HL ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_RIGHTFOOTER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ FOOTER_RIGHT
+ PageResID = HID_SCPAGE_HFED_FR ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_HFEDIT_LEFTFOOTER
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 270 , 140 ) ;
+ Moveable = TRUE ;
+ // Closeable = TRUE;
+ HFEDIT_DLGTITLE
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = 1 ;
+ FOOTER_LEFT
+ PageResID = HID_SCPAGE_HFED_FL ;
+ };
+ };
+ };
+};
+ //------------------------------------------------------------------------
+ // ScTpHFEdit
+ //------------------------------------------------------------------------
+TabPage RID_HFBASE
+{
+ Hide = TRUE ;
+ HelpId = HID_SCPAGE_HFEDIT ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedText FT_LEFT
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "~Left area" ;
+ };
+ /* "Control" braucht eigene HelpId, darum in der Ableitung:
+ Control WND_LEFT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+*/
+ FixedText FT_CENTER
+ {
+ Pos = MAP_APPFONT ( 90 , 6 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "~Center area" ;
+ };
+ /* "Control" braucht eigene HelpId, darum in der Ableitung:
+ Control WND_CENTER
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+*/
+ FixedText FT_RIGHT
+ {
+ Pos = MAP_APPFONT ( 174 , 6 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "R~ight area" ;
+ };
+ /* "Control" braucht eigene HelpId, darum in der Ableitung:
+ Control WND_RIGHT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 174 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+*/
+ FixedText FT_HF_DEFINED
+ {
+ Pos = MAP_APPFONT ( 12 , 102 ) ;
+ Size = MAP_APPFONT ( 76 , 10 ) ;
+ Text [ en-US ] = "Hea~der" ;
+ };
+
+ /* #i84123# list box needs own help id, which is set in the derived tab pages
+ ListBox LB_DEFINED
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 100 ) ;
+ Size = MAP_APPFONT ( 130 , 80 ) ;
+ DropDown = TRUE ;
+ TabStop = TRUE ;
+ };
+ */
+
+ FixedText FT_HF_CUSTOM
+ {
+ Pos = MAP_APPFONT ( 12 , 124 ) ;
+ Size = MAP_APPFONT ( 76 , 10 ) ;
+ Text [ en-US ] = "Custom header" ;
+ };
+
+ ImageButton BTN_TEXT
+ {
+ HelpId = HID_SC_HF_TEXT ;
+ Pos = MAP_APPFONT ( 90 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Text Attributes" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "text.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+ };
+ };
+ Image IMG_TEXT_H
+ {
+ ImageBitmap = Bitmap { File = "text_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ ImageButton BTN_FILE
+ {
+ HelpId = HID_SC_HF_FILE ;
+ Pos = MAP_APPFONT ( 113 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Title" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "file.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+ };
+ };
+ Image IMG_FILE_H
+ {
+ ImageBitmap = Bitmap { File = "file_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+
+ Menu RID_POPUP_FCOMMAND
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = FILE_COMMAND_TITEL ;
+ HelpID = HID_FCOMMAND_TITEL ;
+ Text [ en-US ] = "Title";
+ };
+ MenuItem
+ {
+ Identifier = FILE_COMMAND_FILENAME;
+ HelpID = HID_FCOMMAND_FILENAME;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "File Name";
+ };
+ MenuItem
+ {
+ Identifier = FILE_COMMAND_PATH;
+ HelpID = HID_FCOMMAND_PATH;
+ RadioCheck = TRUE ;
+ Text [ en-US ] = "Path/File Name";
+ };
+ };
+ };
+
+ ImageButton BTN_TABLE
+ {
+ HelpId = HID_SC_HF_TABLE ;
+ Pos = MAP_APPFONT ( 130 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Sheet Name" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "table.bmp" ; };
+ MaskColor = STD_MASKCOLOR;
+ };
+ };
+ Image IMG_TABLE_H
+ {
+ ImageBitmap = Bitmap { File = "table_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ ImageButton BTN_PAGE
+ {
+ HelpId = HID_SC_HF_PAGE ;
+ Pos = MAP_APPFONT ( 150 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Page" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "page.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+ };
+ };
+ Image IMG_PAGE_H
+ {
+ ImageBitmap = Bitmap { File = "page_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ ImageButton BTN_PAGES
+ {
+ HelpId = HID_SC_HF_PAGES ;
+ Pos = MAP_APPFONT ( 167 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Pages" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "pages.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+ };
+ };
+ Image IMG_PAGES_H
+ {
+ ImageBitmap = Bitmap { File = "pages_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ ImageButton BTN_DATE
+ {
+ HelpId = HID_SC_HF_DATE ;
+ Pos = MAP_APPFONT ( 187 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Date" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "date.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+ };
+ };
+ Image IMG_DATE_H
+ {
+ ImageBitmap = Bitmap { File = "date_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ ImageButton BTN_TIME
+ {
+ HelpId = HID_SC_HF_TIME ;
+ Pos = MAP_APPFONT ( 204 , 122 ) ;
+ Size = MAP_APPFONT ( 15 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Time" ;
+ ButtonImage = Image
+ {
+ ImageBitmap = Bitmap { File = "time.bmp" ; };
+ MaskColor = STD_MASKCOLOR ;
+ };
+ };
+ Image IMG_TIME_H
+ {
+ ImageBitmap = Bitmap { File = "time_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ FixedText FT_INFO
+ {
+ Pos = MAP_APPFONT ( 12 , 155 ) ;
+ Size = MAP_APPFONT ( 240 , 24 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "Use the buttons to change the font or insert field commands such as date, time, etc." ;
+ };
+ FixedLine FL_INFO
+ {
+ Pos = MAP_APPFONT ( 6 , 144 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Note" ;
+ };
+};
+ // Kombinationen: Header/Footer links/rechts
+ // die Eingabefenster jeweils mit eigener ID, sonst aus RID_HFBASE kopiert
+TabPage RID_SCPAGE_HFED_HL < RID_HFBASE
+{
+ Hide = TRUE ;
+ HelpId = HID_SCPAGE_HFED_HL ;
+ Control WND_LEFT
+ {
+ HelpId = HID_SC_HF_HLL ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_CENTER
+ {
+ HelpId = HID_SC_HF_HLC ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_RIGHT
+ {
+ HelpId = HID_SC_HF_HLR ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 174 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_DEFINED
+ {
+ HelpId = HID_SC_HF_HL_DEFINED ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 100 ) ;
+ Size = MAP_APPFONT ( 130 , 80 ) ;
+ DropDown = TRUE ;
+ TabStop = TRUE ;
+ };
+};
+TabPage RID_SCPAGE_HFED_HR < RID_HFBASE
+{
+ Hide = TRUE ;
+ HelpId = HID_SCPAGE_HFED_HR ;
+ Control WND_LEFT
+ {
+ HelpId = HID_SC_HF_HRL ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_CENTER
+ {
+ HelpId = HID_SC_HF_HRC ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_RIGHT
+ {
+ HelpId = HID_SC_HF_HRR ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 174 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_DEFINED
+ {
+ HelpId = HID_SC_HF_HR_DEFINED ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 100 ) ;
+ Size = MAP_APPFONT ( 130 , 80 ) ;
+ DropDown = TRUE ;
+ TabStop = TRUE ;
+ };
+};
+TabPage RID_SCPAGE_HFED_FL < RID_HFBASE
+{
+ Hide = TRUE ;
+ HelpId = HID_SCPAGE_HFED_FL ;
+ Control WND_LEFT
+ {
+ HelpId = HID_SC_HF_FLL ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_CENTER
+ {
+ HelpId = HID_SC_HF_FLC ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_RIGHT
+ {
+ HelpId = HID_SC_HF_FLR ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 174 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_DEFINED
+ {
+ HelpId = HID_SC_HF_FL_DEFINED ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 100 ) ;
+ Size = MAP_APPFONT ( 130 , 80 ) ;
+ DropDown = TRUE ;
+ TabStop = TRUE ;
+ };
+};
+TabPage RID_SCPAGE_HFED_FR < RID_HFBASE
+{
+ Hide = TRUE ;
+ HelpId = HID_SCPAGE_HFED_FR ;
+ Control WND_LEFT
+ {
+ HelpId = HID_SC_HF_FRL ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_CENTER
+ {
+ HelpId = HID_SC_HF_FRC ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control WND_RIGHT
+ {
+ HelpId = HID_SC_HF_FRR ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 174 , 18 ) ;
+ Size = MAP_APPFONT ( 80 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_DEFINED
+ {
+ HelpId = HID_SC_HF_FR_DEFINED ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 90 , 100 ) ;
+ Size = MAP_APPFONT ( 130 , 80 ) ;
+ DropDown = TRUE ;
+ TabStop = TRUE ;
+ };
+};
+
diff --git a/sc/source/ui/pagedlg/makefile.mk b/sc/source/ui/pagedlg/makefile.mk
new file mode 100644
index 000000000000..500e642e79eb
--- /dev/null
+++ b/sc/source/ui/pagedlg/makefile.mk
@@ -0,0 +1,74 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=pagedlg
+LIBTARGET=no
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ areasdlg.cxx \
+ hfedtdlg.cxx \
+ tptable.cxx \
+ tphf.cxx \
+ tphfedit.cxx
+
+
+
+SLOFILES = \
+ $(SLO)$/areasdlg.obj \
+ $(SLO)$/hfedtdlg.obj \
+ $(SLO)$/tptable.obj \
+ $(SLO)$/tphf.obj \
+ $(SLO)$/tphfedit.obj \
+ $(SLO)$/scuitphfedit.obj
+
+
+SRS1NAME=$(TARGET)
+SRC1FILES = pagedlg.src \
+ hfedtdlg.src \
+ tphf.src
+
+LIB1TARGET = $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO)$/areasdlg.obj \
+ $(SLO)$/tphfedit.obj
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/pagedlg/pagedlg.hrc b/sc/source/ui/pagedlg/pagedlg.hrc
new file mode 100644
index 000000000000..2f3593c2f6d1
--- /dev/null
+++ b/sc/source/ui/pagedlg/pagedlg.hrc
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include "sc.hrc" // -> RID_SCDLG_PAGE
+ // -> RID_SCPAGE_TABLE
+ // -> RID_SCPAGE_AREAS
+
+#define TP_PAGE_STD 1
+#define TP_PAGE_HEADER 2
+#define TP_PAGE_FOOTER 3
+#define TP_PAGE_TABLE 4
+#define TP_PAGE_AREAS 5
+
+//================================================
+// TabPage: Tabelle
+
+#define BTN_GRID 10
+#define BTN_HEADER 11
+#define BTN_NOTES 12
+#define BTN_CHARTS 13
+#define BTN_OBJECTS 14
+#define BTN_DRAWINGS 15
+#define BTN_FORMULAS 16
+#define BTN_NULLVALS 17
+#define FL_PRINT 19
+
+#define BTN_TOPDOWN 20
+#define BTN_LEFTRIGHT 21
+#define BMP_PAGEDIR 22
+#define IMG_LEFTRIGHT 23
+#define IMG_TOPDOWN 24
+#define BTN_PAGENO 25
+#define ED_PAGENO 26
+#define FL_PAGEDIR 29
+
+#define FT_SCALEMODE 30
+#define LB_SCALEMODE 31
+#define ED_SCALEALL 32
+#define ED_SCALEPAGENUM 34
+#define ED_SCALEPAGEWIDTH 35
+#define ED_SCALEPAGEHEIGHT 36
+#define FL_SCALE 39
+
+#define FT_SCALEFACTOR 51
+#define FT_SCALEPAGEWIDTH 52
+#define FT_SCALEPAGEHEIGHT 53
+#define FT_SCALEPAGENUM 54
+
+#define IMG_LEFTRIGHT_H 41
+#define IMG_TOPDOWN_H 42
+
+// List box entries "Scaling mode"
+#define SC_TPTABLE_SCALE_PERCENT 0
+#define SC_TPTABLE_SCALE_TO 1
+#define SC_TPTABLE_SCALE_TO_PAGES 2
+
+//================================================
+// Dialog: Druckbereiche
+
+#define FL_PRINTAREA 10
+#define ED_PRINTAREA 11
+#define RB_PRINTAREA 12
+#define LB_PRINTAREA 13
+
+#define FL_REPEATROW 20
+#define ED_REPEATROW 21
+#define RB_REPEATROW 22
+#define LB_REPEATROW 23
+
+#define FL_REPEATCOL 30
+#define ED_REPEATCOL 31
+#define RB_REPEATCOL 32
+#define LB_REPEATCOL 33
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
diff --git a/sc/source/ui/pagedlg/pagedlg.src b/sc/source/ui/pagedlg/pagedlg.src
new file mode 100644
index 000000000000..d0f95c3d9f6b
--- /dev/null
+++ b/sc/source/ui/pagedlg/pagedlg.src
@@ -0,0 +1,416 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "pagedlg.hrc"
+ModelessDialog RID_SCDLG_AREAS
+{
+ HelpId = HID_SCPAGE_AREAS ;
+ Size = MAP_APPFONT ( 316 , 90 ) ;
+ OutputSize = TRUE ;
+ Moveable = TRUE ;
+ //Closeable = TRUE; // Dieser Dialog hat einen Cancel-Button !
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Text [ en-US ] = "Edit Print Ranges" ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 260 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 260 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 260 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ FixedLine FL_PRINTAREA
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Print range" ;
+ };
+ ListBox LB_PRINTAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 90 , 60 ) ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "- none -" ; Default ; > ;
+ < "- entire sheet -" ; Default ; > ;
+ < "- user defined -" ; Default ; > ;
+ < "- selection -" ; Default ; > ;
+ };
+ };
+ Edit ED_PRINTAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 14 ) ;
+ Size = MAP_APPFONT ( 131 , 12 ) ;
+ };
+ ImageButton RB_PRINTAREA
+ {
+ Pos = MAP_APPFONT ( 239 , 13 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_REPEATROW
+ {
+ Pos = MAP_APPFONT ( 6 , 32 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Rows to repeat" ;
+ };
+ ListBox LB_REPEATROW
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 43 ) ;
+ Size = MAP_APPFONT ( 90 , 60 ) ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "- none -" ; Default ; > ;
+ < "- user defined -" ; Default ; > ;
+ };
+ };
+ Edit ED_REPEATROW
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 43 ) ;
+ Size = MAP_APPFONT ( 131 , 12 ) ;
+ };
+ ImageButton RB_REPEATROW
+ {
+ Pos = MAP_APPFONT ( 239 , 42 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_REPEATCOL
+ {
+ Pos = MAP_APPFONT ( 6 , 61 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Columns to repeat" ;
+ };
+ ListBox LB_REPEATCOL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 72 ) ;
+ Size = MAP_APPFONT ( 90 , 60 ) ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "- none -" ; Default ; > ;
+ < "- user defined -" ; Default ; > ;
+ };
+ };
+ Edit ED_REPEATCOL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 72 ) ;
+ Size = MAP_APPFONT ( 131 , 12 ) ;
+ };
+ ImageButton RB_REPEATCOL
+ {
+ Pos = MAP_APPFONT ( 239 , 71 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+};
+TabPage RID_SCPAGE_TABLE
+{
+ Hide = TRUE ;
+ HelpId = HID_SCPAGE_TABLE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ CheckBox BTN_HEADER
+ {
+ Pos = MAP_APPFONT ( 12 , 73 ) ;
+ Size = MAP_APPFONT ( 142 , 10 ) ;
+ Text [ en-US ] = "~Column and row headers" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_GRID
+ {
+ Pos = MAP_APPFONT ( 12 , 87 ) ;
+ Size = MAP_APPFONT ( 142 , 10 ) ;
+ Text [ en-US ] = "~Grid" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_NOTES
+ {
+ Pos = MAP_APPFONT ( 12 , 101 ) ;
+ Size = MAP_APPFONT ( 142 , 10 ) ;
+ Text [ en-US ] = "~Comments" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_OBJECTS
+ {
+ Pos = MAP_APPFONT ( 12 , 115 ) ;
+ Size = MAP_APPFONT ( 142 , 10 ) ;
+ Text [ en-US ] = "~Objects/graphics" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_CHARTS
+ {
+ Pos = MAP_APPFONT ( 160 , 73 ) ;
+ Size = MAP_APPFONT ( 91 , 10 ) ;
+ Text [ en-US ] = "Ch~arts" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DRAWINGS
+ {
+ Pos = MAP_APPFONT ( 160 , 87 ) ;
+ Size = MAP_APPFONT ( 91 , 10 ) ;
+ Text [ en-US ] = "~Drawing objects" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_FORMULAS
+ {
+ Pos = MAP_APPFONT ( 160 , 101 ) ;
+ Size = MAP_APPFONT ( 91 , 10 ) ;
+ Text [ en-US ] = "~Formulas" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_NULLVALS
+ {
+ Pos = MAP_APPFONT ( 160 , 115 ) ;
+ Size = MAP_APPFONT ( 91 , 10 ) ;
+ Text [ en-US ] = "Zero ~values" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_PRINT
+ {
+ Pos = MAP_APPFONT ( 6 , 62 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Print" ;
+ };
+ RadioButton BTN_TOPDOWN
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 142 , 10 ) ;
+ Text [ en-US ] = "~Top to bottom, then right" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_LEFTRIGHT
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 142 , 10 ) ;
+ Text [ en-US ] = "~Left to right, then down" ;
+ TabStop = TRUE ;
+ };
+ FixedImage BMP_PAGEDIR
+ {
+ Pos = MAP_APPFONT ( 160 , 14 ) ;
+ Size = MAP_APPFONT ( 25 , 25 ) ;
+ };
+ Image IMG_LEFTRIGHT
+ {
+ ImageBitmap = Bitmap { File = "lftrgt.bmp" ; };
+ MaskColor = STD_MASKCOLOR;
+ };
+ Image IMG_LEFTRIGHT_H
+ {
+ ImageBitmap = Bitmap { File = "lftrgt_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ Image IMG_TOPDOWN
+ {
+ ImageBitmap = Bitmap { File = "topdown.bmp" ; };
+ MaskColor = STD_MASKCOLOR;
+ };
+ Image IMG_TOPDOWN_H
+ {
+ ImageBitmap = Bitmap { File = "topdown_h.bmp" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+ };
+ CheckBox BTN_PAGENO
+ {
+ Pos = MAP_APPFONT ( 12 , 46 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "First ~page number" ;
+ TabStop = TRUE ;
+ };
+ NumericField ED_PAGENO
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 106 , 44 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ Minimum = 1 ;
+ Maximum = 9999 ;
+ SpinSize = 1 ;
+ Repeat = TRUE ;
+ };
+ FixedLine FL_PAGEDIR
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Page order" ;
+ };
+ FixedText FT_SCALEMODE
+ {
+ Pos = MAP_APPFONT( 12, 144 );
+ Size = MAP_APPFONT( 124, 8 );
+ Text [ en-US ] = "Scaling ~mode";
+ };
+ ListBox LB_SCALEMODE
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 12, 155 );
+ Size = MAP_APPFONT( 124, 60 );
+ DropDown = TRUE;
+ StringList [ en-US ] =
+ {
+ < "Reduce/enlarge printout"; SC_TPTABLE_SCALE_PERCENT; >;
+ < "Fit print range(s) to width/height"; SC_TPTABLE_SCALE_TO; >;
+ < "Fit print range(s) on number of pages"; SC_TPTABLE_SCALE_TO_PAGES; >;
+ };
+ };
+ MetricField ED_SCALEALL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 218 , 155 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 10 ;
+ Maximum = 400 ;
+ First = 15 ;
+ Last = 200 ;
+ SpinSize = 1 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ NumericField ED_SCALEPAGEWIDTH
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 218 , 144 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ Maximum = 1000 ;
+ SpinSize = 1 ;
+ };
+ NumericField ED_SCALEPAGEHEIGHT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 218 , 160 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ Maximum = 1000 ;
+ SpinSize = 1 ;
+ };
+ NumericField ED_SCALEPAGENUM
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 218 , 155 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ Minimum = 1 ;
+ Maximum = 1000 ;
+ SpinSize = 1 ;
+ };
+ FixedText FT_SCALEFACTOR
+ {
+ Pos = MAP_APPFONT( 148, 157 );
+ Size = MAP_APPFONT( 68 , 8 );
+ Hide = TRUE;
+ Text [ en-US ] = "~Scaling factor";
+ };
+ FixedText FT_SCALEPAGEWIDTH
+ {
+ Pos = MAP_APPFONT( 148, 146 );
+ Size = MAP_APPFONT( 68 , 8 );
+ Hide = TRUE;
+ Text [ en-US ] = "~Width in pages";
+ };
+ FixedText FT_SCALEPAGEHEIGHT
+ {
+ Pos = MAP_APPFONT( 148, 162 );
+ Size = MAP_APPFONT( 68 , 8 );
+ Hide = TRUE;
+ Text [ en-US ] = "H~eight in pages";
+ };
+ FixedText FT_SCALEPAGENUM
+ {
+ Pos = MAP_APPFONT( 148, 157 );
+ Size = MAP_APPFONT( 68, 8 );
+ Hide = TRUE;
+ Text [ en-US ] = "N~umber of pages";
+ };
+ FixedLine FL_SCALE
+ {
+ Pos = MAP_APPFONT ( 6 , 131 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Scale" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/pagedlg/scuitphfedit.cxx b/sc/source/ui/pagedlg/scuitphfedit.cxx
new file mode 100644
index 000000000000..ba89691239c3
--- /dev/null
+++ b/sc/source/ui/pagedlg/scuitphfedit.cxx
@@ -0,0 +1,1001 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#define _TPHFEDIT_CXX
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+//CHINA001 #include <svx/chardlg.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/useroptions.hxx>
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+
+//CHINA001 #include "tphfedit.hxx"
+#include "editutil.hxx"
+#include "global.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "prevwsh.hxx"
+#include "hfedtdlg.hrc"
+#include "textdlgs.hxx"
+#include "AccessibleEditObject.hxx"
+
+#include "scuitphfedit.hxx" //CHINA001
+#include <memory> // header file for auto_ptr
+
+// STATIC DATA -----------------------------------------------------------
+
+static USHORT pPageRightHeaderRanges[] = { SID_SCATTR_PAGE_HEADERRIGHT,
+ SID_SCATTR_PAGE_HEADERRIGHT,
+ 0 };
+
+static USHORT pPageRightFooterRanges[] = { SID_SCATTR_PAGE_FOOTERRIGHT,
+ SID_SCATTR_PAGE_FOOTERRIGHT,
+ 0 };
+
+static USHORT pPageLeftHeaderRanges[] = { SID_SCATTR_PAGE_HEADERLEFT,
+ SID_SCATTR_PAGE_HEADERLEFT,
+ 0 };
+
+static USHORT pPageLeftFooterRanges[] = { SID_SCATTR_PAGE_FOOTERLEFT,
+ SID_SCATTR_PAGE_FOOTERLEFT,
+ 0 };
+
+
+static ScEditWindow* pActiveEdWnd = NULL;
+
+
+//========================================================================
+// class ScHFEditPage
+//
+
+ScHFEditPage::ScHFEditPage( Window* pParent,
+ USHORT nResId,
+ const SfxItemSet& rCoreAttrs,
+ USHORT nWhichId,
+ bool bHeader )
+
+ : SfxTabPage ( pParent, ScResId( nResId ), rCoreAttrs ),
+
+ aFtLeft ( this, ScResId( FT_LEFT ) ),
+ aWndLeft ( this, ScResId( WND_LEFT ), Left ),
+ aFtCenter ( this, ScResId( FT_CENTER ) ),
+ aWndCenter ( this, ScResId( WND_CENTER ), Center ),
+ aFtRight ( this, ScResId( FT_RIGHT ) ),
+ aWndRight ( this, ScResId( WND_RIGHT ), Right ),
+ maFtDefinedHF ( this, ScResId( FT_HF_DEFINED ) ),
+ maLbDefined ( this, ScResId( LB_DEFINED ) ),
+ maFtCustomHF ( this, ScResId( FT_HF_CUSTOM ) ),
+ aBtnText ( this, ScResId( BTN_TEXT ) ),
+ aBtnFile ( this, ScResId( BTN_FILE ) ),
+ aBtnTable ( this, ScResId( BTN_TABLE ) ),
+ aBtnPage ( this, ScResId( BTN_PAGE ) ),
+ aBtnLastPage ( this, ScResId( BTN_PAGES ) ),
+ aBtnDate ( this, ScResId( BTN_DATE ) ),
+ aBtnTime ( this, ScResId( BTN_TIME ) ),
+ aFlInfo ( this, ScResId( FL_INFO ) ),
+ aFtInfo ( this, ScResId( FT_INFO ) ),
+ aPopUpFile ( ScResId( RID_POPUP_FCOMMAND) ),
+ nWhich ( nWhichId )
+{
+ //! use default style from current document?
+ //! if font color is used, header/footer background color must be set
+
+ ScPatternAttr aPatAttr( rCoreAttrs.GetPool() );
+
+
+ aBtnFile.SetPopupMenu(&aPopUpFile);
+
+ maLbDefined.SetSelectHdl( LINK( this, ScHFEditPage, ListHdl_Impl ) );
+ aBtnFile.SetMenuHdl( LINK( this, ScHFEditPage, MenuHdl ) );
+ aBtnText .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+ aBtnPage .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+ aBtnLastPage.SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+ aBtnDate .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+ aBtnTime .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+ aBtnFile .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+ aBtnTable .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+
+ aBtnText .SetModeImage( Image( ScResId( IMG_TEXT_H ) ), BMP_COLOR_HIGHCONTRAST );
+ aBtnFile .SetModeImage( Image( ScResId( IMG_FILE_H ) ), BMP_COLOR_HIGHCONTRAST );
+ aBtnTable .SetModeImage( Image( ScResId( IMG_TABLE_H ) ), BMP_COLOR_HIGHCONTRAST );
+ aBtnPage .SetModeImage( Image( ScResId( IMG_PAGE_H ) ), BMP_COLOR_HIGHCONTRAST );
+ aBtnLastPage.SetModeImage( Image( ScResId( IMG_PAGES_H ) ), BMP_COLOR_HIGHCONTRAST );
+ aBtnDate .SetModeImage( Image( ScResId( IMG_DATE_H ) ), BMP_COLOR_HIGHCONTRAST );
+ aBtnTime .SetModeImage( Image( ScResId( IMG_TIME_H ) ), BMP_COLOR_HIGHCONTRAST );
+
+ if(!bHeader)
+ {
+ maFtDefinedHF.SetText(ScGlobal::GetRscString( STR_FOOTER ));
+ maFtCustomHF.SetText(ScGlobal::GetRscString( STR_HF_CUSTOM_FOOTER ));
+ }
+ if( Application::GetSettings().GetLayoutRTL() )
+ {
+ Point pt1 = aWndLeft.GetPosPixel();
+ Point pt2 = aWndRight.GetPosPixel();
+ aWndLeft.SetPosPixel(pt2);
+ aWndRight.SetPosPixel(pt1);
+
+ pt1 = aFtLeft.GetPosPixel();
+ pt2 = aFtRight.GetPosPixel();
+ aFtLeft.SetPosPixel(pt2);
+ aFtRight.SetPosPixel(pt1);
+ }
+ aWndLeft. SetFont( aPatAttr );
+ aWndCenter. SetFont( aPatAttr );
+ aWndRight. SetFont( aPatAttr );
+
+ FillCmdArr();
+
+ aWndLeft.GrabFocus();
+
+ InitPreDefinedList();
+
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScHFEditPage::~ScHFEditPage()
+{
+}
+
+void ScHFEditPage::SetNumType(SvxNumType eNumType)
+{
+ aWndLeft.SetNumType(eNumType);
+ aWndCenter.SetNumType(eNumType);
+ aWndRight.SetNumType(eNumType);
+}
+
+// -----------------------------------------------------------------------
+
+#define IS_AVAILABLE(w)(rCoreSet.GetItemState( (w) ) >= SFX_ITEM_AVAILABLE)
+
+void __EXPORT ScHFEditPage::Reset( const SfxItemSet& rCoreSet )
+{
+ if ( IS_AVAILABLE( nWhich ) )
+ {
+ const ScPageHFItem& rItem = (const ScPageHFItem&)(rCoreSet.Get( nWhich ));
+
+ if( const EditTextObject* pLeft = rItem.GetLeftArea() )
+ aWndLeft.SetText( *pLeft );
+ if( const EditTextObject* pCenter = rItem.GetCenterArea() )
+ aWndCenter.SetText( *pCenter );
+ if( const EditTextObject* pRight = rItem.GetRightArea() )
+ aWndRight.SetText( *pRight );
+
+ SetSelectDefinedList();
+ }
+}
+
+#undef IS_AVAILABLE
+
+// -----------------------------------------------------------------------
+
+BOOL __EXPORT ScHFEditPage::FillItemSet( SfxItemSet& rCoreSet )
+{
+ ScPageHFItem aItem( nWhich );
+ EditTextObject* pLeft = aWndLeft .CreateTextObject();
+ EditTextObject* pCenter = aWndCenter.CreateTextObject();
+ EditTextObject* pRight = aWndRight .CreateTextObject();
+
+ aItem.SetLeftArea ( *pLeft );
+ aItem.SetCenterArea( *pCenter );
+ aItem.SetRightArea ( *pRight );
+ delete pLeft;
+ delete pCenter;
+ delete pRight;
+
+ rCoreSet.Put( aItem );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+#define SET_CMD(i,id) \
+ aCmd = aDel; \
+ aCmd += ScGlobal::GetRscString( id ); \
+ aCmd += aDel; \
+ aCmdArr[i] = aCmd;
+
+// -----------------------------------------------------------------------
+
+void ScHFEditPage::FillCmdArr()
+{
+ String aDel( ScGlobal::GetRscString( STR_HFCMD_DELIMITER ) );
+ String aCmd;
+
+ SET_CMD( 0, STR_HFCMD_PAGE )
+ SET_CMD( 1, STR_HFCMD_PAGES )
+ SET_CMD( 2, STR_HFCMD_DATE )
+ SET_CMD( 3, STR_HFCMD_TIME )
+ SET_CMD( 4, STR_HFCMD_FILE )
+ SET_CMD( 5, STR_HFCMD_TABLE )
+}
+
+#undef SET_CMD
+
+void ScHFEditPage::InitPreDefinedList()
+{
+ SvtUserOptions aUserOpt;
+
+ Color* pTxtColour = NULL;
+ Color* pFldColour = NULL;
+
+ // Get the all field values at the outset.
+ String aPageFieldValue(aWndLeft.GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour));
+ String aSheetFieldValue(aWndLeft.GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour));
+ String aFileFieldValue(aWndLeft.GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour));
+ String aExtFileFieldValue(aWndLeft.GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxExtFileField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour));
+ String aDateFieldValue(aWndLeft.GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxDateField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour));
+
+ maLbDefined.Clear();
+
+ maLbDefined.InsertEntry( ScGlobal::GetRscString( STR_HF_NONE_IN_BRACKETS ));
+
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aPageEntry += aPageFieldValue;
+ maLbDefined.InsertEntry(aPageEntry);
+
+ String aPageOfEntry(aPageEntry);
+ aPageOfEntry += ' ';
+ aPageOfEntry += ScGlobal::GetRscString( STR_HF_OF_QUESTION );
+ maLbDefined.InsertEntry( aPageOfEntry);
+
+ maLbDefined.InsertEntry(aSheetFieldValue);
+
+ String aConfidentialEntry(aUserOpt.GetCompany());
+ aConfidentialEntry += ' ';
+ aConfidentialEntry += ScGlobal::GetRscString( STR_HF_CONFIDENTIAL );
+ aConfidentialEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aConfidentialEntry += aDateFieldValue;
+ aConfidentialEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aConfidentialEntry += aPageEntry;
+ maLbDefined.InsertEntry( aConfidentialEntry);
+
+ String aFileNamePageEntry(aFileFieldValue);
+ aFileNamePageEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aFileNamePageEntry += aPageEntry;
+ maLbDefined.InsertEntry( aFileNamePageEntry);
+
+ maLbDefined.InsertEntry( aExtFileFieldValue);
+
+ String aPageSheetNameEntry(aPageEntry);
+ aPageSheetNameEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aPageSheetNameEntry += aSheetFieldValue;
+ maLbDefined.InsertEntry( aPageSheetNameEntry);
+
+ String aPageFileNameEntry(aPageEntry);
+ aPageFileNameEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aPageFileNameEntry += aFileFieldValue;
+ maLbDefined.InsertEntry( aPageFileNameEntry);
+
+ String aPagePathNameEntry(aPageEntry);
+ aPagePathNameEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aPagePathNameEntry += aExtFileFieldValue;
+ maLbDefined.InsertEntry( aPagePathNameEntry);
+
+ String aUserNameEntry(aUserOpt.GetFirstName());
+ aUserNameEntry += ' ';
+ aUserNameEntry += (String)aUserOpt.GetLastName();
+ aUserNameEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aUserNameEntry += aPageEntry;
+ aUserNameEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aUserNameEntry += aDateFieldValue;
+ maLbDefined.InsertEntry( aUserNameEntry);
+
+ String aCreatedByEntry(ScGlobal::GetRscString( STR_HF_CREATED_BY ) );
+ aCreatedByEntry += ' ';
+ aCreatedByEntry += (String)aUserOpt.GetFirstName();
+ aCreatedByEntry += ' ';
+ aCreatedByEntry += (String)aUserOpt.GetLastName();
+ aCreatedByEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aCreatedByEntry += aDateFieldValue;
+ aCreatedByEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
+ aCreatedByEntry += aPageEntry;
+ maLbDefined.InsertEntry( aCreatedByEntry);
+}
+
+void ScHFEditPage::InsertToDefinedList()
+{
+ USHORT nCount = maLbDefined.GetEntryCount();
+ if(nCount == eEntryCount)
+ {
+ String aCustomizedEntry(ScGlobal::GetRscString( STR_HF_CUSTOMIZED ) );
+ maLbDefined.InsertEntry( aCustomizedEntry);
+ maLbDefined.SelectEntryPos(eEntryCount);
+ }
+}
+
+void ScHFEditPage::RemoveFromDefinedList()
+{
+ USHORT nCount = maLbDefined.GetEntryCount();
+ if(nCount > eEntryCount )
+ maLbDefined.RemoveEntry( nCount-1);
+}
+
+// determine if the header/footer exists in our predefined list and set select to it.
+void ScHFEditPage::SetSelectDefinedList()
+{
+ SvtUserOptions aUserOpt;
+
+ // default to customized
+ ScHFEntryId eSelectEntry = eEntryCount;
+
+ ::std::auto_ptr< EditTextObject > pLeftObj;
+ ::std::auto_ptr< EditTextObject > pCenterObj;
+ ::std::auto_ptr< EditTextObject > pRightObj;
+
+ XubString aLeftEntry;
+ XubString aCenterEntry;
+ XubString aRightEntry;
+
+ pLeftObj.reset(aWndLeft.GetEditEngine()->CreateTextObject());
+ pCenterObj.reset(aWndCenter.GetEditEngine()->CreateTextObject());
+ pRightObj.reset(aWndRight.GetEditEngine()->CreateTextObject());
+
+ bool bFound = false;
+
+ USHORT i;
+ USHORT nCount = maLbDefined.GetEntryCount();
+ for(i = 0; i < nCount && !bFound; i++)
+ {
+ switch(static_cast<ScHFEntryId>(i))
+ {
+ case eNoneEntry:
+ {
+ aLeftEntry = pLeftObj->GetText(0);
+ aCenterEntry = pCenterObj->GetText(0);
+ aRightEntry = pRightObj->GetText(0);
+ if(aLeftEntry == EMPTY_STRING && aCenterEntry == EMPTY_STRING
+ && aRightEntry == EMPTY_STRING)
+ {
+ eSelectEntry = eNoneEntry;
+ bFound = true;
+ }
+ }
+ break;
+
+ case ePageEntry:
+ {
+ aLeftEntry = pLeftObj->GetText(0);
+ aRightEntry = pRightObj->GetText(0);
+ if(aLeftEntry == EMPTY_STRING && aRightEntry == EMPTY_STRING)
+ {
+ if(IsPageEntry(aWndCenter.GetEditEngine(), pCenterObj.get()))
+ {
+ eSelectEntry = ePageEntry;
+ bFound = true;
+ }
+ }
+ }
+ break;
+
+
+ //TODO
+ case ePagesEntry:
+ {
+ }
+ break;
+
+ case eSheetEntry:
+ {
+ aLeftEntry = pLeftObj->GetText(0);
+ aRightEntry = pRightObj->GetText(0);
+ if(aLeftEntry == EMPTY_STRING && aRightEntry == EMPTY_STRING)
+ {
+ if(pCenterObj->IsFieldObject())
+ {
+ const SvxFieldItem* pFieldItem = pCenterObj->GetField();
+ if(pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if(pField && pField->ISA(SvxTableField))
+ {
+ eSelectEntry = eSheetEntry;
+ bFound = true;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case eConfidentialEntry:
+ {
+ if(IsDateEntry(pCenterObj.get()) && IsPageEntry(aWndRight.GetEditEngine(), pRightObj.get()))
+ {
+ String aConfidentialEntry(aUserOpt.GetCompany());
+ aConfidentialEntry += ' ';
+ aConfidentialEntry += ScGlobal::GetRscString( STR_HF_CONFIDENTIAL );
+ if(aConfidentialEntry == aWndLeft.GetEditEngine()->GetText(0))
+ {
+ eSelectEntry = eConfidentialEntry;
+ bFound = true;
+ }
+ }
+ }
+ break;
+
+ //TODO
+ case eFileNamePageEntry:
+ {
+ }
+ break;
+
+ case eExtFileNameEntry:
+ {
+ aLeftEntry = pLeftObj->GetText(0);
+ aRightEntry = pRightObj->GetText(0);
+ if(IsExtFileNameEntry(pCenterObj.get()) && aLeftEntry == EMPTY_STRING
+ && aRightEntry == EMPTY_STRING)
+ {
+ eSelectEntry = eExtFileNameEntry;
+ bFound = true;
+ }
+ }
+ break;
+
+ //TODO
+ case ePageSheetEntry:
+ {
+ }
+ break;
+
+ //TODO
+ case ePageFileNameEntry:
+ {
+ }
+ break;
+
+ case ePageExtFileNameEntry:
+ {
+ aLeftEntry = pLeftObj->GetText(0);
+ if(IsPageEntry(aWndCenter.GetEditEngine(), pCenterObj.get()) &&
+ IsExtFileNameEntry(pRightObj.get()) && aLeftEntry == EMPTY_STRING)
+ {
+ eSelectEntry = ePageExtFileNameEntry;
+ bFound = true;
+ }
+ }
+ break;
+
+ case eUserNameEntry:
+ {
+ if(IsDateEntry(pRightObj.get()) && IsPageEntry(aWndCenter.GetEditEngine(), pCenterObj.get()))
+ {
+ String aUserNameEntry(aUserOpt.GetFirstName());
+ aUserNameEntry += ' ';
+ aUserNameEntry += (String)aUserOpt.GetLastName();
+ if(aUserNameEntry == aWndLeft.GetEditEngine()->GetText(0))
+ {
+ eSelectEntry = eUserNameEntry;
+ bFound = true;
+ }
+ }
+ }
+ break;
+
+ case eCreatedByEntry:
+ {
+ if(IsDateEntry(pCenterObj.get()) && IsPageEntry(aWndRight.GetEditEngine(), pRightObj.get()))
+ {
+ String aCreatedByEntry(ScGlobal::GetRscString( STR_HF_CREATED_BY ) );
+ aCreatedByEntry += ' ';
+ aCreatedByEntry += (String)aUserOpt.GetFirstName();
+ aCreatedByEntry += ' ';
+ aCreatedByEntry += (String)aUserOpt.GetLastName();
+ if(aCreatedByEntry == aWndLeft.GetEditEngine()->GetText(0))
+ {
+ eSelectEntry = eCreatedByEntry;
+ bFound = true;
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if(eSelectEntry == eEntryCount)
+ InsertToDefinedList();
+
+ maLbDefined.SelectEntryPos( sal::static_int_cast<USHORT>( eSelectEntry ) );
+}
+
+bool ScHFEditPage::IsPageEntry(EditEngine*pEngine, EditTextObject* pTextObj)
+{
+ if(!pEngine && !pTextObj)
+ return false;
+
+ bool bReturn = false;
+
+ if(!pTextObj->IsFieldObject())
+ {
+ SvUShorts aPosList;
+ pEngine->GetPortions(0,aPosList);
+ if(aPosList.Count() == 2)
+ {
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ ESelection aSel(0,0,0,0);
+ aSel.nEndPos = aPageEntry.Len();
+ if(aPageEntry == pEngine->GetText(aSel))
+ {
+ aSel.nStartPos = aSel.nEndPos;
+ aSel.nEndPos++;
+ ::std::auto_ptr< EditTextObject > pPageObj;
+ pPageObj.reset(pEngine->CreateTextObject(aSel));
+ if(pPageObj.get() && pPageObj->IsFieldObject() )
+ {
+ const SvxFieldItem* pFieldItem = pPageObj->GetField();
+ if(pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if(pField && pField->ISA(SvxPageField))
+ bReturn = true;
+ }
+ }
+ }
+ }
+ }
+ return bReturn;
+}
+
+bool ScHFEditPage::IsDateEntry(EditTextObject* pTextObj)
+{
+ if(!pTextObj)
+ return false;
+
+ bool bReturn = false;
+ if(pTextObj->IsFieldObject())
+ {
+ const SvxFieldItem* pFieldItem = pTextObj->GetField();
+ if(pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if(pField && pField->ISA(SvxDateField))
+ bReturn = true;
+ }
+ }
+ return bReturn;
+}
+
+bool ScHFEditPage::IsExtFileNameEntry(EditTextObject* pTextObj)
+{
+ if(!pTextObj)
+ return false;
+ bool bReturn = false;
+ if(pTextObj->IsFieldObject())
+ {
+ const SvxFieldItem* pFieldItem = pTextObj->GetField();
+ if(pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if(pField && pField->ISA(SvxExtFileField))
+ bReturn = true;
+ }
+ }
+ return bReturn;
+}
+
+void ScHFEditPage::ProcessDefinedListSel(ScHFEntryId eSel, bool bTravelling)
+{
+ SvtUserOptions aUserOpt;
+ ::std::auto_ptr< EditTextObject > pTextObj;
+
+ switch(eSel)
+ {
+ case eNoneEntry:
+ ClearTextAreas();
+ if(!bTravelling)
+ aWndLeft.GrabFocus();
+ break;
+
+ case ePageEntry:
+ {
+ ClearTextAreas();
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->SetText(aPageEntry);
+ aWndCenter.InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) );
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ }
+ break;
+
+ case ePagesEntry:
+ {
+ ClearTextAreas();
+ ESelection aSel(0,0,0,0);
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->SetText(aPageEntry);
+ aSel.nEndPos = aPageEntry.Len();
+ aWndCenter.GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ ++aSel.nEndPos;
+ String aPageOfEntry = ' ';
+ aPageOfEntry += ScGlobal::GetRscString( STR_HF_OF );
+ aPageOfEntry += ' ';
+ aWndCenter.GetEditEngine()->QuickInsertText(aPageOfEntry,ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ aSel.nEndPos = sal::static_int_cast<xub_StrLen>( aSel.nEndPos + aPageOfEntry.Len() );
+ aWndCenter.GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ pTextObj.reset(aWndCenter.GetEditEngine()->CreateTextObject());
+ aWndCenter.SetText(*pTextObj);
+ XubString aEntry(pTextObj.get()->GetText(0));
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ }
+ break;
+
+ case eSheetEntry:
+ ClearTextAreas();
+ aWndCenter.InsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD) );
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ break;
+
+ case eConfidentialEntry:
+ {
+ ClearTextAreas();
+ String aConfidentialEntry(aUserOpt.GetCompany());
+ aConfidentialEntry += ' ';
+ aConfidentialEntry += ScGlobal::GetRscString( STR_HF_CONFIDENTIAL );
+ aWndLeft.GetEditEngine()->SetText(aConfidentialEntry);
+ aWndCenter.InsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR), EE_FEATURE_FIELD) );
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndRight.GetEditEngine()->SetText(aPageEntry);
+ aWndRight.InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) );
+ if(!bTravelling)
+ aWndRight.GrabFocus();
+ }
+ break;
+
+ case eFileNamePageEntry:
+ {
+ ClearTextAreas();
+ ESelection aSel(0,0,0,0);
+ aWndCenter.GetEditEngine()->QuickInsertField(SvxFieldItem( SvxFileField(), EE_FEATURE_FIELD ), aSel );
+ ++aSel.nEndPos;
+ String aPageEntry(RTL_CONSTASCII_STRINGPARAM(", "));
+ aPageEntry += ScGlobal::GetRscString( STR_PAGE ) ;
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->QuickInsertText(aPageEntry, ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ aSel.nStartPos = aSel.nEndPos;
+ aSel.nEndPos = sal::static_int_cast<xub_StrLen>( aSel.nEndPos + aPageEntry.Len() );
+ aWndCenter.GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ pTextObj.reset(aWndCenter.GetEditEngine()->CreateTextObject());
+ aWndCenter.SetText(*pTextObj);
+ XubString aEntry2(pTextObj.get()->GetText(0));
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ }
+ break;
+
+ case eExtFileNameEntry:
+ ClearTextAreas();
+ aWndCenter.InsertField( SvxFieldItem( SvxExtFileField(
+ EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_FULLPATH ), EE_FEATURE_FIELD ) );
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ break;
+
+ case ePageSheetEntry:
+ {
+ ClearTextAreas();
+ ESelection aSel(0,0,0,0);
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->SetText(aPageEntry);
+ aSel.nEndPos = aPageEntry.Len();
+ aWndCenter.GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ ++aSel.nEndPos;
+ String aCommaSpace(RTL_CONSTASCII_STRINGPARAM(", "));
+ aWndCenter.GetEditEngine()->QuickInsertText(aCommaSpace,ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ aSel.nEndPos = sal::static_int_cast<xub_StrLen>( aSel.nEndPos + aCommaSpace.Len() );
+ aWndCenter.GetEditEngine()->QuickInsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ pTextObj.reset(aWndCenter.GetEditEngine()->CreateTextObject());
+ aWndCenter.SetText(*pTextObj);
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ }
+ break;
+
+ case ePageFileNameEntry:
+ {
+ ClearTextAreas();
+ ESelection aSel(0,0,0,0);
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->SetText(aPageEntry);
+ aSel.nEndPos = aPageEntry.Len();
+ aWndCenter.GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ ++aSel.nEndPos;
+ String aCommaSpace(RTL_CONSTASCII_STRINGPARAM(", "));
+ aWndCenter.GetEditEngine()->QuickInsertText(aCommaSpace,ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ aSel.nEndPos = sal::static_int_cast<xub_StrLen>( aSel.nEndPos + aCommaSpace.Len() );
+ aWndCenter.GetEditEngine()->QuickInsertField( SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos));
+ pTextObj.reset(aWndCenter.GetEditEngine()->CreateTextObject());
+ aWndCenter.SetText(*pTextObj);
+ if(!bTravelling)
+ aWndCenter.GrabFocus();
+ }
+ break;
+
+ case ePageExtFileNameEntry:
+ {
+ ClearTextAreas();
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->SetText(aPageEntry);
+ aWndCenter.InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) );
+ aWndRight.InsertField( SvxFieldItem( SvxExtFileField(
+ EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_FULLPATH ), EE_FEATURE_FIELD ) );
+ if(!bTravelling)
+ aWndRight.GrabFocus();
+ }
+ break;
+
+ case eUserNameEntry:
+ {
+ ClearTextAreas();
+ String aUserNameEntry(aUserOpt.GetFirstName());
+ aUserNameEntry += ' ';
+ aUserNameEntry += (String)aUserOpt.GetLastName();
+ aWndLeft.GetEditEngine()->SetText(aUserNameEntry);
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndCenter.GetEditEngine()->SetText(aPageEntry);
+ aWndCenter.InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) );
+ aWndRight.InsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR), EE_FEATURE_FIELD) );
+ if(!bTravelling)
+ aWndRight.GrabFocus();
+ }
+ break;
+
+ case eCreatedByEntry:
+ {
+ ClearTextAreas();
+ String aCreatedByEntry(ScGlobal::GetRscString( STR_HF_CREATED_BY ) );
+ aCreatedByEntry += ' ';
+ aCreatedByEntry += (String)aUserOpt.GetFirstName();
+ aCreatedByEntry += ' ';
+ aCreatedByEntry += (String)aUserOpt.GetLastName();
+ aWndLeft.GetEditEngine()->SetText(aCreatedByEntry);
+ aWndCenter.InsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR), EE_FEATURE_FIELD) );
+ String aPageEntry(ScGlobal::GetRscString( STR_PAGE ) );
+ aPageEntry += ' ';
+ aWndRight.GetEditEngine()->SetText(aPageEntry);
+ aWndRight.InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) );
+ if(!bTravelling)
+ aWndRight.GrabFocus();
+ }
+ break;
+
+ default :
+ break;
+ }
+}
+
+void ScHFEditPage::ClearTextAreas()
+{
+ aWndLeft.GetEditEngine()->SetText(EMPTY_STRING);
+ aWndLeft.Invalidate();
+ aWndCenter.GetEditEngine()->SetText(EMPTY_STRING);
+ aWndCenter.Invalidate();
+ aWndRight.GetEditEngine()->SetText(EMPTY_STRING);
+ aWndRight.Invalidate();
+}
+
+//-----------------------------------------------------------------------
+// Handler:
+//-----------------------------------------------------------------------
+
+IMPL_LINK( ScHFEditPage, ListHdl_Impl, ListBox*, pList )
+{
+ if ( pList && pList == &maLbDefined )
+ {
+ ScHFEntryId eSel = static_cast<ScHFEntryId>(maLbDefined.GetSelectEntryPos());
+ if(!maLbDefined.IsTravelSelect())
+ {
+ ProcessDefinedListSel(eSel);
+
+ // check if we need to remove the customized entry.
+ if(eSel < eEntryCount)
+ RemoveFromDefinedList();
+ }
+ else
+ {
+ ProcessDefinedListSel(eSel, true);
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( ScHFEditPage, ClickHdl, ImageButton*, pBtn )
+{
+ pActiveEdWnd = ::GetScEditWindow(); //CHINA001
+ if ( !pActiveEdWnd )
+ return 0;
+
+ if ( pBtn == &aBtnText )
+ {
+ pActiveEdWnd->SetCharAttriutes();
+ }
+ else
+ {
+ if ( pBtn == &aBtnPage )
+ pActiveEdWnd->InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) );
+ else if ( pBtn == &aBtnLastPage )
+ pActiveEdWnd->InsertField( SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD) );
+ else if ( pBtn == &aBtnDate )
+ pActiveEdWnd->InsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR), EE_FEATURE_FIELD) );
+ else if ( pBtn == &aBtnTime )
+ pActiveEdWnd->InsertField( SvxFieldItem(SvxTimeField(), EE_FEATURE_FIELD) );
+ else if ( pBtn == &aBtnFile )
+ {
+ pActiveEdWnd->InsertField( SvxFieldItem( SvxFileField(), EE_FEATURE_FIELD ) );
+ }
+ else if ( pBtn == &aBtnTable )
+ pActiveEdWnd->InsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD) );
+ }
+ InsertToDefinedList();
+ pActiveEdWnd->GrabFocus();
+
+ return 0;
+}
+
+IMPL_LINK( ScHFEditPage, MenuHdl, ScExtIButton*, pBtn )
+{
+ pActiveEdWnd = ::GetScEditWindow(); //CHINA001
+ if ( !pActiveEdWnd )
+ return 0;
+
+ if(pBtn!=NULL)
+ {
+ switch(pBtn->GetSelected())
+ {
+ case FILE_COMMAND_TITEL:
+ pActiveEdWnd->InsertField( SvxFieldItem( SvxFileField(), EE_FEATURE_FIELD ) );
+ break;
+ case FILE_COMMAND_FILENAME:
+ pActiveEdWnd->InsertField( SvxFieldItem( SvxExtFileField(
+ EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT ), EE_FEATURE_FIELD ) );
+ break;
+ case FILE_COMMAND_PATH:
+ pActiveEdWnd->InsertField( SvxFieldItem( SvxExtFileField(
+ EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_FULLPATH ), EE_FEATURE_FIELD ) );
+ break;
+ }
+ }
+ return 0;
+}
+
+//========================================================================
+// class ScRightHeaderEditPage
+//========================================================================
+
+ScRightHeaderEditPage::ScRightHeaderEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+ : ScHFEditPage( pParent, RID_SCPAGE_HFED_HR, rCoreSet,
+ rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_HEADERRIGHT ), true )
+ {}
+
+// -----------------------------------------------------------------------
+
+USHORT* __EXPORT ScRightHeaderEditPage::GetRanges()
+ { return pPageRightHeaderRanges; }
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScRightHeaderEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+ { return ( new ScRightHeaderEditPage( pParent, rCoreSet ) ); };
+
+
+//========================================================================
+// class ScLeftHeaderEditPage
+//========================================================================
+
+ScLeftHeaderEditPage::ScLeftHeaderEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+ : ScHFEditPage( pParent, RID_SCPAGE_HFED_HL, rCoreSet,
+ rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_HEADERLEFT ), true )
+ {}
+
+// -----------------------------------------------------------------------
+
+USHORT* __EXPORT ScLeftHeaderEditPage::GetRanges()
+ { return pPageLeftHeaderRanges; }
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScLeftHeaderEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+ { return ( new ScLeftHeaderEditPage( pParent, rCoreSet ) ); };
+
+//========================================================================
+// class ScRightFooterEditPage
+//========================================================================
+
+ScRightFooterEditPage::ScRightFooterEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+ : ScHFEditPage( pParent, RID_SCPAGE_HFED_FR, rCoreSet,
+ rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_FOOTERRIGHT ), false )
+ {}
+
+// -----------------------------------------------------------------------
+
+USHORT* __EXPORT ScRightFooterEditPage::GetRanges()
+ { return pPageRightFooterRanges; }
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScRightFooterEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+ { return ( new ScRightFooterEditPage( pParent, rCoreSet ) ); };
+
+//========================================================================
+// class ScLeftFooterEditPage
+//========================================================================
+
+ScLeftFooterEditPage::ScLeftFooterEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+ : ScHFEditPage( pParent, RID_SCPAGE_HFED_FL, rCoreSet,
+ rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_FOOTERLEFT ), false )
+ {}
+
+// -----------------------------------------------------------------------
+
+USHORT* __EXPORT ScLeftFooterEditPage::GetRanges()
+ { return pPageLeftFooterRanges; }
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScLeftFooterEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+ { return ( new ScLeftFooterEditPage( pParent, rCoreSet ) ); };
diff --git a/sc/source/ui/pagedlg/tphf.cxx b/sc/source/ui/pagedlg/tphf.cxx
new file mode 100644
index 000000000000..de647cf5f82a
--- /dev/null
+++ b/sc/source/ui/pagedlg/tphf.cxx
@@ -0,0 +1,331 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#define _TPHF_CXX
+#include "scitems.hxx"
+#include <sfx2/basedlgs.hxx>
+#include <svl/style.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "tphf.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+//CHINA001 #include "tphfedit.hxx"
+#include "hfedtdlg.hxx"
+#include "styledlg.hxx"
+#include "scresid.hxx"
+#include "scuitphfedit.hxx" //CHINA001
+#undef _TPHF_CXX
+
+
+
+//==================================================================
+// class ScHFPage
+//==================================================================
+
+ScHFPage::ScHFPage( Window* pParent, USHORT nResId,
+ const SfxItemSet& rSet, USHORT nSetId )
+
+ : SvxHFPage ( pParent, nResId, rSet, nSetId ),
+ aBtnEdit ( this, ScResId( RID_SCBTN_HFEDIT ) ),
+ aDataSet ( *rSet.GetPool(),
+ ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERRIGHT,
+ ATTR_PAGE, ATTR_PAGE, 0 ),
+ nPageUsage ( (USHORT)SVX_PAGE_ALL ),
+ pStyleDlg ( NULL )
+{
+ SetExchangeSupport();
+
+ SfxViewShell* pSh = SfxViewShell::Current();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,pSh);
+ Point aPos( aBackgroundBtn.GetPosPixel() );
+
+ // aBackgroundBtn position not changed anymore
+
+ aPos.X() += aBackgroundBtn.GetSizePixel().Width();
+ aPos.X() += LogicToPixel( Size(3,0), MAP_APPFONT ).Width();
+ aBtnEdit.SetPosPixel( aPos );
+ aBtnEdit.Show();
+
+ aDataSet.Put( rSet );
+
+ if ( pViewSh )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ aStrPageStyle = pDoc->GetPageStyle( pViewData->GetTabNo() );
+ }
+
+ aBtnEdit.SetClickHdl ( LINK( this, ScHFPage, BtnHdl ) );
+ aTurnOnBox.SetClickHdl ( LINK( this, ScHFPage, TurnOnHdl ) );
+
+ if ( nId == SID_ATTR_PAGE_HEADERSET )
+ aBtnEdit.SetHelpId( HID_SC_HEADER_EDIT );
+ else
+ aBtnEdit.SetHelpId( HID_SC_FOOTER_EDIT );
+}
+
+//------------------------------------------------------------------
+
+__EXPORT ScHFPage::~ScHFPage()
+{
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScHFPage::Reset( const SfxItemSet& rSet )
+{
+ SvxHFPage::Reset( rSet );
+ TurnOnHdl( 0 );
+}
+
+//------------------------------------------------------------------
+
+BOOL __EXPORT ScHFPage::FillItemSet( SfxItemSet& rOutSet )
+{
+ BOOL bResult = SvxHFPage::FillItemSet( rOutSet );
+
+ if ( nId == SID_ATTR_PAGE_HEADERSET )
+ {
+ rOutSet.Put( aDataSet.Get( ATTR_PAGE_HEADERLEFT ) );
+ rOutSet.Put( aDataSet.Get( ATTR_PAGE_HEADERRIGHT ) );
+ }
+ else
+ {
+ rOutSet.Put( aDataSet.Get( ATTR_PAGE_FOOTERLEFT ) );
+ rOutSet.Put( aDataSet.Get( ATTR_PAGE_FOOTERRIGHT ) );
+ }
+
+ return bResult;
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScHFPage::ActivatePage( const SfxItemSet& rSet )
+{
+ USHORT nPageWhich = GetWhich( SID_ATTR_PAGE );
+ const SvxPageItem& rPageItem = (const SvxPageItem&)
+ rSet.Get(nPageWhich);
+
+ nPageUsage = rPageItem.GetPageUsage();
+
+ if ( pStyleDlg )
+ aStrPageStyle = pStyleDlg->GetStyleSheet().GetName();
+
+ aDataSet.Put( rSet.Get(ATTR_PAGE) );
+
+ SvxHFPage::ActivatePage( rSet );
+}
+
+//------------------------------------------------------------------
+
+int __EXPORT ScHFPage::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( LEAVE_PAGE == SvxHFPage::DeactivatePage( pSetP ) )
+ if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return LEAVE_PAGE;
+}
+
+//------------------------------------------------------------------
+
+void ScHFPage::ActivatePage()
+{
+}
+
+void ScHFPage::DeactivatePage()
+{
+}
+
+//------------------------------------------------------------------
+// Handler:
+//------------------------------------------------------------------
+
+IMPL_LINK( ScHFPage, TurnOnHdl, CheckBox*, EMPTYARG )
+{
+ SvxHFPage::TurnOnHdl( &aTurnOnBox );
+
+ if ( aTurnOnBox.IsChecked() )
+ aBtnEdit.Enable();
+ else
+ aBtnEdit.Disable();
+
+ return 0;
+}
+
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScHFPage, BtnHdl, PushButton*, EMPTYARG )
+{
+ // Wenn der Bearbeiten-Dialog direkt aus dem Click-Handler des Buttons
+ // aufgerufen wird, funktioniert im Bearbeiten-Dialog unter OS/2 das
+ // GrabFocus nicht (Bug #41805#).
+ // Mit dem neuen StarView sollte dieser Workaround wieder raus koennen!
+
+ Application::PostUserEvent( LINK( this, ScHFPage, HFEditHdl ) );
+ return 0;
+}
+
+IMPL_LINK( ScHFPage, HFEditHdl, void*, EMPTYARG )
+{
+ SfxViewShell* pViewSh = SfxViewShell::Current();
+
+ if ( !pViewSh )
+ {
+ DBG_ERROR( "Current ViewShell not found." );
+ return 0;
+ }
+
+ if ( aCntSharedBox.IsEnabled()
+ && !aCntSharedBox.IsChecked() )
+ {
+ USHORT nResId = ( nId == SID_ATTR_PAGE_HEADERSET )
+ ? RID_SCDLG_HFED_HEADER
+ : RID_SCDLG_HFED_FOOTER;
+
+ ScHFEditDlg* pDlg
+ = new ScHFEditDlg( pViewSh->GetViewFrame(), this,
+ aDataSet, aStrPageStyle, nResId );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ aDataSet.Put( *pDlg->GetOutputItemSet() );
+ }
+
+ delete pDlg;
+ }
+ else
+ {
+ String aText;
+ SfxSingleTabDialog* pDlg = new SfxSingleTabDialog( this, aDataSet, 42 );
+ BOOL bRightPage = aCntSharedBox.IsChecked()
+ || ( SVX_PAGE_LEFT != SvxPageUsage(nPageUsage) );
+
+ if ( nId == SID_ATTR_PAGE_HEADERSET )
+ {
+ aText = ScGlobal::GetRscString( STR_PAGEHEADER );
+ if ( bRightPage )
+ pDlg->SetTabPage( ScRightHeaderEditPage::Create( pDlg, aDataSet ) );
+ else
+ pDlg->SetTabPage( ScLeftHeaderEditPage::Create( pDlg, aDataSet ) );
+ }
+ else
+ {
+ aText = ScGlobal::GetRscString( STR_PAGEFOOTER );
+ if ( bRightPage )
+ pDlg->SetTabPage( ScRightFooterEditPage::Create( pDlg, aDataSet ) );
+ else
+ pDlg->SetTabPage( ScLeftFooterEditPage::Create( pDlg, aDataSet ) );
+ }
+
+ SvxNumType eNumType = ((const SvxPageItem&)aDataSet.Get(ATTR_PAGE)).GetNumType();
+ ((ScHFEditPage*)pDlg->GetTabPage())->SetNumType(eNumType);
+
+ aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ aText += ScGlobal::GetRscString( STR_PAGESTYLE );
+ aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
+ aText += aStrPageStyle;
+ aText += ')';
+
+ pDlg->SetText( aText );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ aDataSet.Put( *pDlg->GetOutputItemSet() );
+ }
+
+ delete pDlg;
+ }
+
+ return 0;
+}
+
+//==================================================================
+// class ScHeaderPage
+//==================================================================
+
+ScHeaderPage::ScHeaderPage( Window* pParent, const SfxItemSet& rSet )
+ : ScHFPage( pParent, RID_SVXPAGE_HEADER, rSet, SID_ATTR_PAGE_HEADERSET )
+{
+}
+
+//------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScHeaderPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+{
+ return ( new ScHeaderPage( pParent, rCoreSet ) );
+}
+
+//------------------------------------------------------------------
+
+USHORT* __EXPORT ScHeaderPage::GetRanges()
+{
+ return SvxHeaderPage::GetRanges();
+}
+
+//==================================================================
+// class ScFooterPage
+//==================================================================
+
+ScFooterPage::ScFooterPage( Window* pParent, const SfxItemSet& rSet )
+ : ScHFPage( pParent, RID_SVXPAGE_FOOTER, rSet, SID_ATTR_PAGE_FOOTERSET )
+{
+}
+
+//------------------------------------------------------------------
+
+SfxTabPage* __EXPORT ScFooterPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+{
+ return ( new ScFooterPage( pParent, rCoreSet ) );
+}
+
+//------------------------------------------------------------------
+
+USHORT* __EXPORT ScFooterPage::GetRanges()
+{
+ return SvxHeaderPage::GetRanges();
+}
+
+
+
+
diff --git a/sc/source/ui/pagedlg/tphf.src b/sc/source/ui/pagedlg/tphf.src
new file mode 100644
index 000000000000..b2f59e06da72
--- /dev/null
+++ b/sc/source/ui/pagedlg/tphf.src
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+PushButton RID_SCBTN_HFEDIT
+{
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Edit..." ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/pagedlg/tphfedit.cxx b/sc/source/ui/pagedlg/tphfedit.cxx
new file mode 100644
index 000000000000..8e6b6efda28d
--- /dev/null
+++ b/sc/source/ui/pagedlg/tphfedit.cxx
@@ -0,0 +1,874 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+
+//------------------------------------------------------------------
+
+#define _TPHFEDIT_CXX
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+//CHINA001 #include <svx/chardlg.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/adjitem.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "tphfedit.hxx"
+#include "editutil.hxx"
+#include "global.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "prevwsh.hxx"
+#include "hfedtdlg.hrc"
+//CHINA001 #include "textdlgs.hxx"
+#include "AccessibleEditObject.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+
+// STATIC DATA -----------------------------------------------------------
+static ScEditWindow* pActiveEdWnd = NULL;
+
+ScEditWindow* GetScEditWindow ()
+{
+ return pActiveEdWnd;
+}
+
+//CHINA001
+//CHINA001 static USHORT pPageRightHeaderRanges[] = { SID_SCATTR_PAGE_HEADERRIGHT,
+//CHINA001 SID_SCATTR_PAGE_HEADERRIGHT,
+//CHINA001 0 };
+//CHINA001
+//CHINA001 static USHORT pPageRightFooterRanges[] = { SID_SCATTR_PAGE_FOOTERRIGHT,
+//CHINA001 SID_SCATTR_PAGE_FOOTERRIGHT,
+//CHINA001 0 };
+//CHINA001
+//CHINA001 static USHORT pPageLeftHeaderRanges[] = { SID_SCATTR_PAGE_HEADERLEFT,
+//CHINA001 SID_SCATTR_PAGE_HEADERLEFT,
+//CHINA001 0 };
+//CHINA001
+//CHINA001 static USHORT pPageLeftFooterRanges[] = { SID_SCATTR_PAGE_FOOTERLEFT,
+//CHINA001 SID_SCATTR_PAGE_FOOTERLEFT,
+//CHINA001 0 };
+//CHINA001
+//CHINA001 static ScEditWindow* pActiveEdWnd = NULL;
+//CHINA001
+//CHINA001
+//CHINA001
+//CHINA001 //========================================================================
+//CHINA001 // class ScHFEditPage
+//CHINA001 //
+//CHINA001
+//CHINA001 ScHFEditPage::ScHFEditPage( Window* pParent,
+//CHINA001 USHORT nResId,
+//CHINA001 const SfxItemSet& rCoreAttrs,
+//CHINA001 USHORT nWhichId )
+//CHINA001
+//CHINA001 : SfxTabPage ( pParent, ScResId( nResId ), rCoreAttrs ),
+//CHINA001
+//CHINA001 aWndLeft ( this, ScResId( WND_LEFT ), Left ),
+//CHINA001 aWndCenter ( this, ScResId( WND_CENTER ), Center ),
+//CHINA001 aWndRight ( this, ScResId( WND_RIGHT ), Right ),
+//CHINA001 aFtLeft ( this, ScResId( FT_LEFT ) ),
+//CHINA001 aFtCenter ( this, ScResId( FT_CENTER ) ),
+//CHINA001 aFtRight ( this, ScResId( FT_RIGHT ) ),
+//CHINA001 aFlInfo ( this, ScResId( FL_INFO ) ),
+//CHINA001 aFtInfo ( this, ScResId( FT_INFO ) ),
+//CHINA001 aBtnText ( this, ScResId( BTN_TEXT ) ),
+//CHINA001 aBtnPage ( this, ScResId( BTN_PAGE ) ),
+//CHINA001 aBtnLastPage ( this, ScResId( BTN_PAGES ) ),
+//CHINA001 aBtnDate ( this, ScResId( BTN_DATE ) ),
+//CHINA001 aBtnTime ( this, ScResId( BTN_TIME ) ),
+//CHINA001 aBtnFile ( this, ScResId( BTN_FILE ) ),
+//CHINA001 aBtnTable ( this, ScResId( BTN_TABLE ) ),
+//CHINA001 aPopUpFile ( ScResId( RID_POPUP_FCOMMAND) ),
+//CHINA001 nWhich ( nWhichId )
+//CHINA001 {
+//CHINA001 //! use default style from current document?
+//CHINA001 //! if font color is used, header/footer background color must be set
+//CHINA001
+//CHINA001 ScPatternAttr aPatAttr( rCoreAttrs.GetPool() );
+//CHINA001
+//CHINA001 aBtnFile.SetPopupMenu(&aPopUpFile);
+//CHINA001
+//CHINA001 aBtnFile.SetMenuHdl( LINK( this, ScHFEditPage, MenuHdl ) );
+//CHINA001 aBtnText .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001 aBtnPage .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001 aBtnLastPage.SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001 aBtnDate .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001 aBtnTime .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001 aBtnFile .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001 aBtnTable .SetClickHdl( LINK( this, ScHFEditPage, ClickHdl ) );
+//CHINA001
+//CHINA001 aBtnText .SetModeImage( Image( ScResId( IMG_TEXT_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001 aBtnFile .SetModeImage( Image( ScResId( IMG_FILE_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001 aBtnTable .SetModeImage( Image( ScResId( IMG_TABLE_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001 aBtnPage .SetModeImage( Image( ScResId( IMG_PAGE_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001 aBtnLastPage.SetModeImage( Image( ScResId( IMG_PAGES_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001 aBtnDate .SetModeImage( Image( ScResId( IMG_DATE_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001 aBtnTime .SetModeImage( Image( ScResId( IMG_TIME_H ) ), BMP_COLOR_HIGHCONTRAST );
+//CHINA001
+//CHINA001 aWndLeft. SetFont( aPatAttr );
+//CHINA001 aWndCenter. SetFont( aPatAttr );
+//CHINA001 aWndRight. SetFont( aPatAttr );
+//CHINA001
+//CHINA001 FillCmdArr();
+//CHINA001
+//CHINA001 aWndLeft.GrabFocus();
+//CHINA001
+//CHINA001 FreeResource();
+//CHINA001 }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 __EXPORT ScHFEditPage::~ScHFEditPage()
+//CHINA001 {
+//CHINA001 }
+//CHINA001
+//CHINA001 void ScHFEditPage::SetNumType(SvxNumType eNumType)
+//CHINA001 {
+//CHINA001 aWndLeft.SetNumType(eNumType);
+//CHINA001 aWndCenter.SetNumType(eNumType);
+//CHINA001 aWndRight.SetNumType(eNumType);
+//CHINA001 }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 #define IS_AVAILABLE(w)(rCoreSet.GetItemState( (w) ) >= SFX_ITEM_AVAILABLE)
+//CHINA001
+//CHINA001 void __EXPORT ScHFEditPage::Reset( const SfxItemSet& rCoreSet )
+//CHINA001 {
+//CHINA001 if ( IS_AVAILABLE( nWhich ) )
+//CHINA001 {
+//CHINA001 const ScPageHFItem& rItem = (const ScPageHFItem&)(rCoreSet.Get( nWhich ));
+//CHINA001
+//CHINA001 const EditTextObject* pLeft = rItem.GetLeftArea();
+//CHINA001 const EditTextObject* pCenter = rItem.GetCenterArea();
+//CHINA001 const EditTextObject* pRight = rItem.GetRightArea();
+//CHINA001
+//CHINA001 if ( pLeft && pCenter && pRight )
+//CHINA001 {
+//CHINA001 aWndLeft .SetText( *pLeft );
+//CHINA001 aWndCenter .SetText( *pCenter );
+//CHINA001 aWndRight .SetText( *pRight );
+//CHINA001 }
+//CHINA001 }
+//CHINA001 }
+//CHINA001
+//CHINA001 #undef IS_AVAILABLE
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 BOOL __EXPORT ScHFEditPage::FillItemSet( SfxItemSet& rCoreSet )
+//CHINA001 {
+//CHINA001 ScPageHFItem aItem( nWhich );
+//CHINA001 EditTextObject* pLeft = aWndLeft .CreateTextObject();
+//CHINA001 EditTextObject* pCenter = aWndCenter.CreateTextObject();
+//CHINA001 EditTextObject* pRight = aWndRight .CreateTextObject();
+//CHINA001
+//CHINA001 aItem.SetLeftArea ( *pLeft );
+//CHINA001 aItem.SetCenterArea( *pCenter );
+//CHINA001 aItem.SetRightArea ( *pRight );
+//CHINA001 delete pLeft;
+//CHINA001 delete pCenter;
+//CHINA001 delete pRight;
+//CHINA001
+//CHINA001 rCoreSet.Put( aItem );
+//CHINA001
+//CHINA001 return TRUE;
+//CHINA001 }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 #define SET_CMD(i,id) x
+//CHINA001 aCmd = aDel; x
+//CHINA001 aCmd += ScGlobal::GetRscString( id ); x
+//CHINA001 aCmd += aDel; x
+//CHINA001 aCmdArr[i] = aCmd;
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 void ScHFEditPage::FillCmdArr()
+//CHINA001 {
+//CHINA001 String aDel( ScGlobal::GetRscString( STR_HFCMD_DELIMITER ) );
+//CHINA001 String aCmd;
+//CHINA001
+//CHINA001 SET_CMD( 0, STR_HFCMD_PAGE )
+//CHINA001 SET_CMD( 1, STR_HFCMD_PAGES )
+//CHINA001 SET_CMD( 2, STR_HFCMD_DATE )
+//CHINA001 SET_CMD( 3, STR_HFCMD_TIME )
+//CHINA001 SET_CMD( 4, STR_HFCMD_FILE )
+//CHINA001 SET_CMD( 5, STR_HFCMD_TABLE )
+//CHINA001 }
+//CHINA001
+//CHINA001 #undef SET_CMD
+//CHINA001
+//CHINA001 //-----------------------------------------------------------------------
+//CHINA001 // Handler:
+//CHINA001 //-----------------------------------------------------------------------
+//CHINA001
+//CHINA001 IMPL_LINK( ScHFEditPage, ClickHdl, ImageButton*, pBtn )
+//CHINA001 {
+//CHINA001 if ( !pActiveEdWnd )
+//CHINA001 return 0;
+//CHINA001
+//CHINA001 if ( pBtn == &aBtnText )
+//CHINA001 {
+//CHINA001 pActiveEdWnd->SetCharAttriutes();
+//CHINA001 }
+//CHINA001 else
+//CHINA001 {
+//CHINA001 if ( pBtn == &aBtnPage )
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem(SvxPageField()) );
+//CHINA001 else if ( pBtn == &aBtnLastPage )
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem(SvxPagesField()) );
+//CHINA001 else if ( pBtn == &aBtnDate )
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem(SvxDateField(Date(),SVXDATETYPE_VAR)) );
+//CHINA001 else if ( pBtn == &aBtnTime )
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem(SvxTimeField()) );
+//CHINA001 else if ( pBtn == &aBtnFile )
+//CHINA001 {
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem( SvxFileField() ) );
+//CHINA001 }
+//CHINA001 else if ( pBtn == &aBtnTable )
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem(SvxTableField()) );
+//CHINA001 }
+//CHINA001 pActiveEdWnd->GrabFocus();
+//CHINA001
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 IMPL_LINK( ScHFEditPage, MenuHdl, ScExtIButton*, pBtn )
+//CHINA001 {
+//CHINA001 if ( !pActiveEdWnd )
+//CHINA001 return 0;
+//CHINA001
+//CHINA001 if(pBtn!=NULL)
+//CHINA001 {
+//CHINA001 switch(pBtn->GetSelected())
+//CHINA001 {
+//CHINA001 case FILE_COMMAND_TITEL:
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem( SvxFileField() ) );
+//CHINA001 break;
+//CHINA001 case FILE_COMMAND_FILENAME:
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem( SvxExtFileField(
+//CHINA001 EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT ) ) );
+//CHINA001 break;
+//CHINA001 case FILE_COMMAND_PATH:
+//CHINA001 pActiveEdWnd->InsertField( SvxFieldItem( SvxExtFileField(
+//CHINA001 EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_FULLPATH ) ) );
+//CHINA001 break;
+//CHINA001 }
+//CHINA001 }
+//CHINA001 return 0;
+//CHINA001 }
+//CHINA001
+//CHINA001 //========================================================================
+//CHINA001 // class ScRightHeaderEditPage
+//CHINA001 //========================================================================
+//CHINA001
+//CHINA001 ScRightHeaderEditPage::ScRightHeaderEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 : ScHFEditPage( pParent, RID_SCPAGE_HFED_HR, rCoreSet,
+//CHINA001 rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_HEADERRIGHT) )
+//CHINA001 {}
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 USHORT* __EXPORT ScRightHeaderEditPage::GetRanges()
+//CHINA001 { return pPageRightHeaderRanges; }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 SfxTabPage* __EXPORT ScRightHeaderEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 { return ( new ScRightHeaderEditPage( pParent, rCoreSet ) ); };
+//CHINA001
+//CHINA001
+//CHINA001 //========================================================================
+//CHINA001 // class ScLeftHeaderEditPage
+//CHINA001 //========================================================================
+//CHINA001
+//CHINA001 ScLeftHeaderEditPage::ScLeftHeaderEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 : ScHFEditPage( pParent, RID_SCPAGE_HFED_HL, rCoreSet,
+//CHINA001 rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_HEADERLEFT) )
+//CHINA001 {}
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 USHORT* __EXPORT ScLeftHeaderEditPage::GetRanges()
+//CHINA001 { return pPageLeftHeaderRanges; }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 SfxTabPage* __EXPORT ScLeftHeaderEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 { return ( new ScLeftHeaderEditPage( pParent, rCoreSet ) ); };
+//CHINA001
+//CHINA001 //========================================================================
+//CHINA001 // class ScRightFooterEditPage
+//CHINA001 //========================================================================
+//CHINA001
+//CHINA001 ScRightFooterEditPage::ScRightFooterEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 : ScHFEditPage( pParent, RID_SCPAGE_HFED_FR, rCoreSet,
+//CHINA001 rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_FOOTERRIGHT) )
+//CHINA001 {}
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 USHORT* __EXPORT ScRightFooterEditPage::GetRanges()
+//CHINA001 { return pPageRightFooterRanges; }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 SfxTabPage* __EXPORT ScRightFooterEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 { return ( new ScRightFooterEditPage( pParent, rCoreSet ) ); };
+//CHINA001
+//CHINA001 //========================================================================
+//CHINA001 // class ScLeftFooterEditPage
+//CHINA001 //========================================================================
+//CHINA001
+//CHINA001 ScLeftFooterEditPage::ScLeftFooterEditPage( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 : ScHFEditPage( pParent, RID_SCPAGE_HFED_FL, rCoreSet,
+//CHINA001 rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_FOOTERLEFT) )
+//CHINA001 {}
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 USHORT* __EXPORT ScLeftFooterEditPage::GetRanges()
+//CHINA001 { return pPageLeftFooterRanges; }
+//CHINA001
+//CHINA001 // -----------------------------------------------------------------------
+//CHINA001
+//CHINA001 SfxTabPage* __EXPORT ScLeftFooterEditPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+//CHINA001 { return ( new ScLeftFooterEditPage( pParent, rCoreSet ) ); };
+
+//========================================================================
+
+void lcl_GetFieldData( ScHeaderFieldData& rData )
+{
+ SfxViewShell* pShell = SfxViewShell::Current();
+ if (pShell)
+ {
+ if (pShell->ISA(ScTabViewShell))
+ ((ScTabViewShell*)pShell)->FillFieldData(rData);
+ else if (pShell->ISA(ScPreviewShell))
+ ((ScPreviewShell*)pShell)->FillFieldData(rData);
+ }
+}
+
+//========================================================================
+// class ScEditWindow
+//========================================================================
+
+ScEditWindow::ScEditWindow( Window* pParent, const ResId& rResId, ScEditWindowLocation eLoc )
+ : Control( pParent, rResId ),
+ eLocation(eLoc),
+ pAcc(NULL)
+{
+ EnableRTL(FALSE);
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aBgColor = rStyleSettings.GetWindowColor();
+
+ SetMapMode( MAP_TWIP );
+ SetPointer( POINTER_TEXT );
+ SetBackground( aBgColor );
+
+ Size aSize( GetOutputSize() );
+ aSize.Height() *= 4;
+
+ pEdEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), TRUE );
+ pEdEngine->SetPaperSize( aSize );
+ pEdEngine->SetRefDevice( this );
+
+ ScHeaderFieldData aData;
+ lcl_GetFieldData( aData );
+
+ // Feldbefehle:
+ pEdEngine->SetData( aData );
+ pEdEngine->SetControlWord( pEdEngine->GetControlWord() | EE_CNTRL_MARKFIELDS );
+ mbRTL = ScGlobal::IsSystemRTL();
+ if (mbRTL)
+ pEdEngine->SetDefaultHorizontalTextDirection(EE_HTEXTDIR_R2L);
+
+ pEdView = new EditView( pEdEngine, this );
+ pEdView->SetOutputArea( Rectangle( Point(0,0), GetOutputSize() ) );
+
+ pEdView->SetBackgroundColor( aBgColor );
+ pEdEngine->InsertView( pEdView );
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScEditWindow::~ScEditWindow()
+{
+ // delete Accessible object before deleting EditEngine and EditView
+ if (pAcc)
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xTemp = xAcc;
+ if (xTemp.is())
+ pAcc->dispose();
+ }
+ delete pEdEngine;
+ delete pEdView;
+}
+
+// -----------------------------------------------------------------------
+
+void ScEditWindow::SetNumType(SvxNumType eNumType)
+{
+ pEdEngine->SetNumType(eNumType);
+ pEdEngine->UpdateFields();
+}
+
+// -----------------------------------------------------------------------
+
+EditTextObject* __EXPORT ScEditWindow::CreateTextObject()
+{
+ // wegen #38841# die Absatzattribute zuruecksetzen
+ // (GetAttribs beim Format-Dialog-Aufruf gibt immer gesetzte Items zurueck)
+
+ const SfxItemSet& rEmpty = pEdEngine->GetEmptyItemSet();
+ USHORT nParCnt = pEdEngine->GetParagraphCount();
+ for (USHORT i=0; i<nParCnt; i++)
+ pEdEngine->SetParaAttribs( i, rEmpty );
+
+ return pEdEngine->CreateTextObject();
+}
+
+// -----------------------------------------------------------------------
+
+void ScEditWindow::SetFont( const ScPatternAttr& rPattern )
+{
+ SfxItemSet* pSet = new SfxItemSet( pEdEngine->GetEmptyItemSet() );
+ rPattern.FillEditItemSet( pSet );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ pSet->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ pSet->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ pSet->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ if (mbRTL)
+ pSet->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+ pEdEngine->SetDefaults( pSet );
+}
+
+// -----------------------------------------------------------------------
+
+void ScEditWindow::SetText( const EditTextObject& rTextObject )
+{
+ pEdEngine->SetText( rTextObject );
+}
+
+// -----------------------------------------------------------------------
+
+void ScEditWindow::InsertField( const SvxFieldItem& rFld )
+{
+ pEdView->InsertField( rFld );
+}
+
+// -----------------------------------------------------------------------
+
+void ScEditWindow::SetCharAttriutes()
+{
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ SfxViewShell* pViewSh = SfxViewShell::Current();
+
+ ScTabViewShell* pTabViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
+
+
+ DBG_ASSERT( pDocSh, "Current DocShell not found" );
+ DBG_ASSERT( pViewSh, "Current ViewShell not found" );
+
+ if ( pDocSh && pViewSh )
+ {
+ if(pTabViewSh!=NULL) pTabViewSh->SetInFormatDialog(TRUE);
+
+ SfxItemSet aSet( pEdView->GetAttribs() );
+
+ //CHINA001 ScCharDlg* pDlg = new ScCharDlg( GetParent(), &aSet, pDocSh );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScCharDlg( GetParent(), &aSet,
+ pDocSh,RID_SCDLG_CHAR );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetText( ScGlobal::GetRscString( STR_TEXTATTRS ) );
+ if ( pDlg->Execute() == RET_OK )
+ {
+ aSet.ClearItem();
+ aSet.Put( *pDlg->GetOutputItemSet() );
+ pEdView->SetAttribs( aSet );
+ }
+
+ if(pTabViewSh!=NULL) pTabViewSh->SetInFormatDialog(FALSE);
+ delete pDlg;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScEditWindow::Paint( const Rectangle& rRec )
+{
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aBgColor = rStyleSettings.GetWindowColor();
+
+ pEdView->SetBackgroundColor( aBgColor );
+
+ SetBackground( aBgColor );
+
+ Control::Paint( rRec );
+
+ pEdView->Paint( rRec );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScEditWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ pEdView->MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScEditWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !HasFocus() )
+ GrabFocus();
+
+ pEdView->MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScEditWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ pEdView->MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScEditWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ USHORT nKey = rKEvt.GetKeyCode().GetModifier()
+ + rKEvt.GetKeyCode().GetCode();
+
+ if ( nKey == KEY_TAB || nKey == KEY_TAB + KEY_SHIFT )
+ {
+ Control::KeyInput( rKEvt );
+ }
+ else if ( !pEdView->PostKeyEvent( rKEvt ) )
+ {
+ Control::KeyInput( rKEvt );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScEditWindow::Command( const CommandEvent& rCEvt )
+{
+ pEdView->Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScEditWindow::GetFocus()
+{
+ pActiveEdWnd = this;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xTemp = xAcc;
+ if (xTemp.is() && pAcc)
+ {
+ pAcc->GotFocus();
+ }
+ else
+ pAcc = NULL;
+}
+
+void __EXPORT ScEditWindow::LoseFocus()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xTemp = xAcc;
+ if (xTemp.is() && pAcc)
+ {
+ pAcc->LostFocus();
+ }
+ else
+ pAcc = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScEditWindow::CreateAccessible()
+{
+ String sName;
+ String sDescription(GetHelpText());
+ switch (eLocation)
+ {
+ case Left:
+ {
+ sName = String(ScResId(STR_ACC_LEFTAREA_NAME));
+// sDescription = String(ScResId(STR_ACC_LEFTAREA_DESCR));
+ }
+ break;
+ case Center:
+ {
+ sName = String(ScResId(STR_ACC_CENTERAREA_NAME));
+// sDescription = String(ScResId(STR_ACC_CENTERAREA_DESCR));
+ }
+ break;
+ case Right:
+ {
+ sName = String(ScResId(STR_ACC_RIGHTAREA_NAME));
+// sDescription = String(ScResId(STR_ACC_RIGHTAREA_DESCR));
+ }
+ break;
+ }
+ pAcc = new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), pEdView, this,
+ rtl::OUString(sName), rtl::OUString(sDescription), EditControl);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAccessible = pAcc;
+ xAcc = xAccessible;
+ return pAcc;
+}
+
+/*
+class ScExtIButton : public ImageButton
+{
+private:
+
+ Timer aTimer;
+ ScPopupMenu* pPopupMenu;
+
+ DECL_LINK( TimerHdl, Timer*);
+
+ void DrawArrow();
+
+protected:
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt);
+
+ virtual void StartPopup();
+
+public:
+
+ ScExtIButton(Window* pParent, const ResId& rResId );
+
+ void SetPopupMenu(ScPopupMenu* pPopUp);
+
+ USHORT GetSelected();
+
+ void SetMenuHdl( const Link& rLink ) { aFxLink = rLink; }
+ const Link& GetMenuHdl() const { return aFxLink; }
+
+}
+*/
+ScExtIButton::ScExtIButton(Window* pParent, const ResId& rResId )
+: ImageButton(pParent,rResId),
+ pPopupMenu(NULL)
+{
+ nSelected=0;
+ aTimer.SetTimeout(600);
+ SetDropDown( TRUE);
+
+// DrawArrow();
+}
+
+void ScExtIButton::SetPopupMenu(ScPopupMenu* pPopUp)
+{
+ pPopupMenu=pPopUp;
+}
+
+USHORT ScExtIButton::GetSelected()
+{
+ return nSelected;
+}
+
+void ScExtIButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if(!aTimer.IsActive())
+ {
+ aTimer.Start();
+ aTimer.SetTimeoutHdl(LINK( this, ScExtIButton, TimerHdl));
+ }
+
+ ImageButton::MouseButtonDown(rMEvt );
+}
+void ScExtIButton::MouseButtonUp( const MouseEvent& rMEvt)
+{
+ aTimer.Stop();
+ aTimer.SetTimeoutHdl(Link());
+ ImageButton::MouseButtonUp(rMEvt );
+}
+
+void ScExtIButton::Click()
+{
+ aTimer.Stop();
+ aTimer.SetTimeoutHdl(Link());
+ ImageButton::Click();
+}
+
+void ScExtIButton::StartPopup()
+{
+ nSelected=0;
+
+ if(pPopupMenu!=NULL)
+ {
+ SetPressed( TRUE );
+ EndSelection();
+ Point aPoint(0,0);
+ aPoint.Y()=GetOutputSizePixel().Height();
+
+ nSelected=pPopupMenu->Execute( this, aPoint );
+
+ if(nSelected)
+ {
+ aMLink.Call(this);
+ }
+ SetPressed( FALSE);
+ }
+}
+
+long ScExtIButton::PreNotify( NotifyEvent& rNEvt )
+{
+ USHORT nSwitch=rNEvt.GetType();
+ if(nSwitch==EVENT_MOUSEBUTTONUP)
+ {
+ MouseButtonUp(*rNEvt.GetMouseEvent());
+ }
+
+ return ImageButton::PreNotify(rNEvt );
+}
+
+IMPL_LINK( ScExtIButton, TimerHdl, Timer*, EMPTYARG )
+{
+ StartPopup();
+ return 0;
+}
+
+/*
+static void ImplDrawToolArrow( ToolBox* pBox, long nX, long nY, BOOL bBlack,
+ BOOL bLeft = FALSE, BOOL bTop = FALSE )
+{
+ Color aOldFillColor = pBox->GetFillColor();
+ WindowAlign eAlign = pBox->meAlign;
+ if ( bLeft )
+ eAlign = WINDOWALIGN_RIGHT;
+ else if ( bTop )
+ eAlign = WINDOWALIGN_BOTTOM;
+
+ switch ( eAlign )
+ {
+ case WINDOWALIGN_LEFT:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+0, nX+0, nY+6 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+1, nX+1, nY+5 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+2, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+1, nY+2, nX+1, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+3, nX+2, nY+3 ) );
+ }
+ break;
+ case WINDOWALIGN_TOP:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
+ }
+ break;
+ case WINDOWALIGN_RIGHT:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+0, nX+3, nY+6 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+1, nX+2, nY+5 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+2, nX+1, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+3, nX+0, nY+3 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+2, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+3, nX+1, nY+3 ) );
+ }
+ break;
+ case WINDOWALIGN_BOTTOM:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+3, nX+6, nY+3 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+2, nX+5, nY+2 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+0, nX+3, nY+0 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+1, nX+3, nY+1 ) );
+ }
+ break;
+ }
+}
+Down
+ - Timer starten
+
+Click
+ - Timer abbrechen
+
+Timer
+ if ( ??? )
+ {
+ - SetPressed( TRUE );
+ - EndSelection();
+ - Menu anzeigen
+ - SetPressed( FALSE );
+ }
+
+
+*/
+
+
diff --git a/sc/source/ui/pagedlg/tptable.cxx b/sc/source/ui/pagedlg/tptable.cxx
new file mode 100644
index 000000000000..a2b732464e12
--- /dev/null
+++ b/sc/source/ui/pagedlg/tptable.cxx
@@ -0,0 +1,570 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+
+#include "tptable.hxx"
+#include "global.hxx"
+#include "attrib.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "pagedlg.hrc"
+
+// =======================================================================
+
+void EmptyNumericField::Modify()
+{
+ if( GetText().Len() )
+ NumericField::Modify();
+ else
+ SetEmptyFieldValue();
+}
+
+void EmptyNumericField::SetValue( sal_Int64 nValue )
+{
+ if( nValue == 0 )
+ SetEmptyFieldValue();
+ else
+ NumericField::SetValue( nValue );
+}
+
+sal_Int64 EmptyNumericField::GetValue() const
+{
+ return IsEmptyFieldValue() ? 0 : NumericField::GetValue();
+}
+
+// =======================================================================
+
+// STATIC DATA -----------------------------------------------------------
+
+static USHORT pPageTableRanges[] =
+{
+ ATTR_PAGE_NOTES, ATTR_PAGE_FIRSTPAGENO,
+ 0
+};
+
+BOOL lcl_PutVObjModeItem( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ const CheckBox& rBtn );
+
+BOOL lcl_PutScaleItem( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ const ListBox& rListBox,
+ USHORT nLBEntry,
+ const SpinField& rEd,
+ UINT16 nValue );
+
+BOOL lcl_PutScaleItem2( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ const ListBox& rListBox,
+ USHORT nLBEntry,
+ const NumericField& rEd1,
+ const NumericField& rEd2 );
+
+BOOL lcl_PutBoolItem( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ BOOL bIsChecked,
+ BOOL bSavedValue );
+
+//------------------------------------------------------------------------
+
+#define PAGENO_HDL LINK(this,ScTablePage,PageNoHdl)
+#define PAGEDIR_HDL LINK(this,ScTablePage,PageDirHdl)
+#define SCALE_HDL LINK(this,ScTablePage,ScaleHdl)
+
+#define WAS_DEFAULT(w,s) (SFX_ITEM_DEFAULT==(s).GetItemState((w),TRUE))
+#define GET_BOOL(sid,set) ((const SfxBoolItem&)((set).Get(GetWhich((sid))))).GetValue()
+#define GET_USHORT(sid,set) (USHORT)((const SfxUInt16Item&)((set).Get(GetWhich((sid))))).GetValue()
+#define GET_SHOW(sid,set) ( ScVObjMode( ((const ScViewObjectModeItem&)((set).Get(GetWhich((sid))))).GetValue() ) \
+ == VOBJ_MODE_SHOW )
+
+//========================================================================
+
+ScTablePage::ScTablePage( Window* pParent, const SfxItemSet& rCoreAttrs ) :
+
+ SfxTabPage( pParent, ScResId( RID_SCPAGE_TABLE ), rCoreAttrs ),
+
+ aFlPageDir ( this, ScResId( FL_PAGEDIR ) ),
+ aBtnTopDown ( this, ScResId( BTN_TOPDOWN ) ),
+ aBtnLeftRight ( this, ScResId( BTN_LEFTRIGHT ) ),
+ aBmpPageDir ( this, ScResId( BMP_PAGEDIR ) ),
+ aImgLeftRight ( ScResId( IMG_LEFTRIGHT ) ),
+ aImgTopDown ( ScResId( IMG_TOPDOWN ) ),
+ aImgLeftRightHC ( ScResId( IMG_LEFTRIGHT_H ) ),
+ aImgTopDownHC ( ScResId( IMG_TOPDOWN_H ) ),
+ aBtnPageNo ( this, ScResId( BTN_PAGENO ) ),
+ aEdPageNo ( this, ScResId( ED_PAGENO ) ),
+ aFlPrint ( this, ScResId( FL_PRINT ) ),
+ aBtnHeaders ( this, ScResId( BTN_HEADER ) ),
+ aBtnGrid ( this, ScResId( BTN_GRID ) ),
+ aBtnNotes ( this, ScResId( BTN_NOTES ) ),
+ aBtnObjects ( this, ScResId( BTN_OBJECTS ) ),
+ aBtnCharts ( this, ScResId( BTN_CHARTS ) ),
+ aBtnDrawings ( this, ScResId( BTN_DRAWINGS ) ),
+ aBtnFormulas ( this, ScResId( BTN_FORMULAS ) ),
+ aBtnNullVals ( this, ScResId( BTN_NULLVALS ) ),
+ aFlScale ( this, ScResId( FL_SCALE ) ),
+ aFtScaleMode ( this, ScResId( FT_SCALEMODE ) ),
+ aLbScaleMode ( this, ScResId( LB_SCALEMODE ) ),
+ aFtScaleAll ( this, ScResId( FT_SCALEFACTOR ) ),
+ aEdScaleAll ( this, ScResId( ED_SCALEALL ) ),
+ aFtScalePageWidth ( this, ScResId( FT_SCALEPAGEWIDTH ) ),
+ aEdScalePageWidth ( this, ScResId( ED_SCALEPAGEWIDTH ) ),
+ aFtScalePageHeight ( this, ScResId( FT_SCALEPAGEHEIGHT ) ),
+ aEdScalePageHeight ( this, ScResId( ED_SCALEPAGEHEIGHT ) ),
+ aFtScalePageNum ( this, ScResId( FT_SCALEPAGENUM ) ),
+ aEdScalePageNum ( this, ScResId( ED_SCALEPAGENUM ) )
+{
+ SetExchangeSupport();
+ aBtnPageNo.SetClickHdl( PAGENO_HDL );
+ aBtnTopDown.SetClickHdl( PAGEDIR_HDL );
+ aBtnLeftRight.SetClickHdl( PAGEDIR_HDL );
+ aLbScaleMode.SetSelectHdl( SCALE_HDL );
+
+ Size aBmpSize = Image( ScResId( IMG_LEFTRIGHT ) ).GetSizePixel();
+ aBmpPageDir.SetOutputSizePixel( aBmpSize );
+
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+void ScTablePage::ShowImage()
+{
+ bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+ bool bLeftRight = aBtnLeftRight.IsChecked();
+ aBmpPageDir.SetImage( bHC ?
+ (bLeftRight ? aImgLeftRightHC : aImgTopDownHC) :
+ (bLeftRight ? aImgLeftRight : aImgTopDown) );
+}
+
+// -----------------------------------------------------------------------
+
+ScTablePage::~ScTablePage()
+{
+}
+
+//------------------------------------------------------------------------
+
+USHORT* ScTablePage::GetRanges()
+{
+ return pPageTableRanges;
+}
+
+// -----------------------------------------------------------------------
+
+SfxTabPage* ScTablePage::Create( Window* pParent, const SfxItemSet& rCoreSet )
+{
+ return ( new ScTablePage( pParent, rCoreSet ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ScTablePage::Reset( const SfxItemSet& rCoreSet )
+{
+ BOOL bTopDown = GET_BOOL( SID_SCATTR_PAGE_TOPDOWN, rCoreSet );
+ USHORT nWhich = 0;
+
+ //-----------
+ // BOOL-Flags
+ //-----------
+ aBtnNotes .Check( GET_BOOL(SID_SCATTR_PAGE_NOTES,rCoreSet) );
+ aBtnGrid .Check( GET_BOOL(SID_SCATTR_PAGE_GRID,rCoreSet) );
+ aBtnHeaders .Check( GET_BOOL(SID_SCATTR_PAGE_HEADERS,rCoreSet) );
+ aBtnFormulas .Check( GET_BOOL(SID_SCATTR_PAGE_FORMULAS,rCoreSet) );
+ aBtnNullVals .Check( GET_BOOL(SID_SCATTR_PAGE_NULLVALS,rCoreSet) );
+ aBtnTopDown .Check( bTopDown );
+ aBtnLeftRight .Check( !bTopDown );
+
+ //------------------
+ // Erste Druckseite:
+ //------------------
+ USHORT nPage = GET_USHORT(SID_SCATTR_PAGE_FIRSTPAGENO,rCoreSet);
+ aBtnPageNo.Check( nPage != 0 );
+ aEdPageNo.SetValue( (nPage != 0) ? nPage : 1 );
+ PageNoHdl( NULL );
+
+ //-------------------
+ // Objektdarstellung:
+ //-------------------
+ aBtnCharts .Check( GET_SHOW( SID_SCATTR_PAGE_CHARTS, rCoreSet ) );
+ aBtnObjects .Check( GET_SHOW( SID_SCATTR_PAGE_OBJECTS, rCoreSet ) );
+ aBtnDrawings .Check( GET_SHOW( SID_SCATTR_PAGE_DRAWINGS, rCoreSet ) );
+
+ //------------
+ // Skalierung:
+ //------------
+
+ nWhich = GetWhich(SID_SCATTR_PAGE_SCALE);
+ if ( rCoreSet.GetItemState( nWhich, TRUE ) >= SFX_ITEM_AVAILABLE )
+ {
+ USHORT nScale = ((const SfxUInt16Item&)rCoreSet.Get(nWhich)).GetValue();
+ if( nScale > 0 )
+ aLbScaleMode.SelectEntryPos( SC_TPTABLE_SCALE_PERCENT );
+ aEdScaleAll.SetValue( (nScale > 0) ? nScale : 100 );
+ }
+
+ nWhich = GetWhich(SID_SCATTR_PAGE_SCALETO);
+ if ( rCoreSet.GetItemState( nWhich, TRUE ) >= SFX_ITEM_AVAILABLE )
+ {
+ const ScPageScaleToItem& rItem = static_cast< const ScPageScaleToItem& >( rCoreSet.Get( nWhich ) );
+ USHORT nWidth = rItem.GetWidth();
+ USHORT nHeight = rItem.GetHeight();
+
+ /* width==0 and height==0 is invalid state, used as "not selected".
+ Dialog shows width=height=1 then. */
+ bool bValid = nWidth || nHeight;
+ if( bValid )
+ aLbScaleMode.SelectEntryPos( SC_TPTABLE_SCALE_TO );
+ aEdScalePageWidth.SetValue( bValid ? nWidth : 1 );
+ aEdScalePageHeight.SetValue( bValid ? nHeight : 1 );
+ }
+
+ nWhich = GetWhich(SID_SCATTR_PAGE_SCALETOPAGES);
+ if ( rCoreSet.GetItemState( nWhich, TRUE ) >= SFX_ITEM_AVAILABLE )
+ {
+ USHORT nPages = ((const SfxUInt16Item&)rCoreSet.Get(nWhich)).GetValue();
+ if( nPages > 0 )
+ aLbScaleMode.SelectEntryPos( SC_TPTABLE_SCALE_TO_PAGES );
+ aEdScalePageNum.SetValue( (nPages > 0) ? nPages : 1 );
+ }
+
+ if( aLbScaleMode.GetSelectEntryCount() == 0 )
+ {
+ // fall back to 100%
+ DBG_ERRORFILE( "ScTablePage::Reset - missing scaling item" );
+ aLbScaleMode.SelectEntryPos( SC_TPTABLE_SCALE_PERCENT );
+ aEdScaleAll.SetValue( 100 );
+ }
+
+ PageDirHdl( NULL );
+ ScaleHdl( NULL );
+
+ // merken fuer FillItemSet
+ aBtnFormulas .SaveValue();
+ aBtnNullVals .SaveValue();
+ aBtnNotes .SaveValue();
+ aBtnGrid .SaveValue();
+ aBtnHeaders .SaveValue();
+ aBtnTopDown .SaveValue();
+ aBtnLeftRight .SaveValue();
+ aLbScaleMode .SaveValue();
+ aBtnCharts .SaveValue();
+ aBtnObjects .SaveValue();
+ aBtnDrawings .SaveValue();
+ aBtnPageNo .SaveValue();
+ aEdPageNo .SaveValue();
+ aEdScaleAll .SaveValue();
+ aEdScalePageWidth.SaveValue();
+ aEdScalePageHeight.SaveValue();
+ aEdScalePageNum .SaveValue();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScTablePage::FillItemSet( SfxItemSet& rCoreSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+ USHORT nWhichPageNo = GetWhich(SID_SCATTR_PAGE_FIRSTPAGENO);
+ BOOL bDataChanged = FALSE;
+
+ //-----------
+ // BOOL-Flags
+ //-----------
+
+ bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_NOTES),
+ rCoreSet, rOldSet,
+ aBtnNotes.IsChecked(),
+ aBtnNotes.GetSavedValue() != STATE_NOCHECK );
+
+ bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_GRID),
+ rCoreSet, rOldSet,
+ aBtnGrid.IsChecked(),
+ aBtnGrid.GetSavedValue() != STATE_NOCHECK );
+
+ bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_HEADERS),
+ rCoreSet, rOldSet,
+ aBtnHeaders.IsChecked(),
+ aBtnHeaders.GetSavedValue() != STATE_NOCHECK );
+
+ bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_TOPDOWN),
+ rCoreSet, rOldSet,
+ aBtnTopDown.IsChecked(),
+ aBtnTopDown.GetSavedValue() );
+
+ bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_FORMULAS),
+ rCoreSet, rOldSet,
+ aBtnFormulas.IsChecked(),
+ aBtnFormulas.GetSavedValue() != STATE_NOCHECK );
+
+ bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_NULLVALS),
+ rCoreSet, rOldSet,
+ aBtnNullVals.IsChecked(),
+ aBtnNullVals.GetSavedValue() != STATE_NOCHECK );
+
+ //------------------
+ // Erste Druckseite:
+ //------------------
+ BOOL bUseValue = aBtnPageNo.IsChecked();
+
+ if ( WAS_DEFAULT(nWhichPageNo,rOldSet)
+ && ( (!bUseValue && bUseValue == aBtnPageNo.GetSavedValue())
+ || ( bUseValue && bUseValue == aBtnPageNo.GetSavedValue()
+ && aEdPageNo.GetText() == aEdPageNo.GetSavedValue() ) ) )
+ {
+ rCoreSet.ClearItem( nWhichPageNo );
+ }
+ else
+ {
+ UINT16 nPage = (UINT16)( aBtnPageNo.IsChecked()
+ ? aEdPageNo.GetValue()
+ : 0 );
+
+ rCoreSet.Put( SfxUInt16Item( nWhichPageNo, nPage ) );
+ bDataChanged = TRUE;
+ }
+
+ //-------------------
+ // Objektdarstellung:
+ //-------------------
+
+ bDataChanged |= lcl_PutVObjModeItem( GetWhich(SID_SCATTR_PAGE_CHARTS),
+ rCoreSet, rOldSet, aBtnCharts );
+
+ bDataChanged |= lcl_PutVObjModeItem( GetWhich(SID_SCATTR_PAGE_OBJECTS),
+ rCoreSet, rOldSet, aBtnObjects );
+
+ bDataChanged |= lcl_PutVObjModeItem( GetWhich(SID_SCATTR_PAGE_DRAWINGS),
+ rCoreSet, rOldSet, aBtnDrawings );
+
+ //------------
+ // Skalierung:
+ //------------
+
+ if( !aEdScalePageWidth.GetValue() && !aEdScalePageHeight.GetValue() )
+ {
+ aLbScaleMode.SelectEntryPos( SC_TPTABLE_SCALE_PERCENT );
+ aEdScaleAll.SetValue( 100 );
+ }
+
+ bDataChanged |= lcl_PutScaleItem( GetWhich(SID_SCATTR_PAGE_SCALE),
+ rCoreSet, rOldSet,
+ aLbScaleMode, SC_TPTABLE_SCALE_PERCENT,
+ aEdScaleAll, (UINT16)aEdScaleAll.GetValue() );
+
+ bDataChanged |= lcl_PutScaleItem2( GetWhich(SID_SCATTR_PAGE_SCALETO),
+ rCoreSet, rOldSet,
+ aLbScaleMode, SC_TPTABLE_SCALE_TO,
+ aEdScalePageWidth, aEdScalePageHeight );
+
+ bDataChanged |= lcl_PutScaleItem( GetWhich(SID_SCATTR_PAGE_SCALETOPAGES),
+ rCoreSet, rOldSet,
+ aLbScaleMode, SC_TPTABLE_SCALE_TO_PAGES,
+ aEdScalePageNum, (UINT16)aEdScalePageNum.GetValue() );
+
+ return bDataChanged;
+}
+
+//------------------------------------------------------------------------
+
+int ScTablePage::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( pSetP )
+ FillItemSet( *pSetP );
+
+ return LEAVE_PAGE;
+}
+
+//------------------------------------------------------------------------
+
+void ScTablePage::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ ShowImage();
+ SfxTabPage::DataChanged( rDCEvt );
+}
+
+//------------------------------------------------------------------------
+// Handler:
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScTablePage, PageDirHdl, RadioButton*, EMPTYARG )
+{
+ ShowImage();
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScTablePage, PageNoHdl, CheckBox*, pBtn )
+{
+ if ( aBtnPageNo.IsChecked() )
+ {
+ aEdPageNo.Enable();
+ if ( pBtn )
+ aEdPageNo.GrabFocus();
+ }
+ else
+ aEdPageNo.Disable();
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+IMPL_LINK( ScTablePage, ScaleHdl, ListBox*, EMPTYARG )
+{
+ // controls for "Reduce/enlarge"
+ bool bPercent = (aLbScaleMode.GetSelectEntryPos() == SC_TPTABLE_SCALE_PERCENT);
+ aFtScaleAll.Show( bPercent );
+ aEdScaleAll.Show( bPercent );
+
+ // controls for "Scale to width/height"
+ bool bScaleTo = (aLbScaleMode.GetSelectEntryPos() == SC_TPTABLE_SCALE_TO);
+ aFtScalePageWidth.Show( bScaleTo );
+ aEdScalePageWidth.Show( bScaleTo );
+ aFtScalePageHeight.Show( bScaleTo );
+ aEdScalePageHeight.Show( bScaleTo );
+
+ // controls for "Scale to pages"
+ bool bScalePages = (aLbScaleMode.GetSelectEntryPos() == SC_TPTABLE_SCALE_TO_PAGES);
+ aFtScalePageNum.Show( bScalePages );
+ aEdScalePageNum.Show( bScalePages );
+
+ return 0;
+}
+
+//========================================================================
+// Hilfsfunktionen fuer FillItemSet:
+//========================================================================
+
+BOOL lcl_PutBoolItem( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ BOOL bIsChecked,
+ BOOL bSavedValue )
+{
+ BOOL bDataChanged = ( bSavedValue == bIsChecked
+ && WAS_DEFAULT(nWhich,rOldSet) );
+
+ if ( bDataChanged )
+ rCoreSet.ClearItem(nWhich);
+ else
+ rCoreSet.Put( SfxBoolItem( nWhich, bIsChecked ) );
+
+ return bDataChanged;
+}
+
+//------------------------------------------------------------------------
+
+BOOL lcl_PutVObjModeItem( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ const CheckBox& rBtn )
+{
+ BOOL bIsChecked = rBtn.IsChecked();
+ BOOL bDataChanged = ( rBtn.GetSavedValue() == bIsChecked
+ && WAS_DEFAULT(nWhich,rOldSet) );
+
+ if ( bDataChanged )
+ rCoreSet.ClearItem( nWhich );
+
+ else
+ rCoreSet.Put( ScViewObjectModeItem( nWhich, bIsChecked
+ ? VOBJ_MODE_SHOW
+ : VOBJ_MODE_HIDE ) );
+ return bDataChanged;
+}
+
+//------------------------------------------------------------------------
+
+BOOL lcl_PutScaleItem( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ const ListBox& rListBox,
+ USHORT nLBEntry,
+ const SpinField& rEd,
+ UINT16 nValue )
+{
+ BOOL bIsSel = (rListBox.GetSelectEntryPos() == nLBEntry);
+ BOOL bDataChanged = (rListBox.GetSavedValue() != nLBEntry) ||
+ (rEd.GetSavedValue() != rEd.GetText()) ||
+ !WAS_DEFAULT( nWhich, rOldSet );
+
+ if( bDataChanged )
+ rCoreSet.Put( SfxUInt16Item( nWhich, bIsSel ? nValue : 0 ) );
+ else
+ rCoreSet.ClearItem( nWhich );
+
+ return bDataChanged;
+}
+
+
+BOOL lcl_PutScaleItem2( USHORT nWhich,
+ SfxItemSet& rCoreSet,
+ const SfxItemSet& rOldSet,
+ const ListBox& rListBox,
+ USHORT nLBEntry,
+ const NumericField& rEd1,
+ const NumericField& rEd2 )
+{
+ UINT16 nValue1 = (UINT16)rEd1.GetValue();
+ UINT16 nValue2 = (UINT16)rEd2.GetValue();
+ BOOL bIsSel = (rListBox.GetSelectEntryPos() == nLBEntry);
+ BOOL bDataChanged = (rListBox.GetSavedValue() != nLBEntry) ||
+ (rEd1.GetSavedValue() != rEd1.GetText()) ||
+ (rEd2.GetSavedValue() != rEd2.GetText()) ||
+ !WAS_DEFAULT( nWhich, rOldSet );
+
+ if( bDataChanged )
+ {
+ ScPageScaleToItem aItem;
+ if( bIsSel )
+ aItem.Set( nValue1, nValue2 );
+ rCoreSet.Put( aItem );
+ }
+ else
+ rCoreSet.ClearItem( nWhich );
+
+ return bDataChanged;
+}
+
+
+
diff --git a/sc/source/ui/src/attrdlg.src b/sc/source/ui/src/attrdlg.src
new file mode 100644
index 000000000000..ae130f7e8a96
--- /dev/null
+++ b/sc/source/ui/src/attrdlg.src
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svx/dialogs.hrc>
+#include "attrdlg.hrc"
+
+ //================================================
+ // Attributdialog:
+
+TabDialog RID_SCDLG_ATTR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 280 , 165 ) ;
+ Text [ en-US ] = "Format Cells" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT ( 23 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = TP_NUMBER ;
+ PageResID = 256 ;
+ Text [ en-US ] = "Numbers" ;
+ };
+ PageItem
+ {
+ Identifier = TP_FONT ;
+ PageResID = 257 ;
+ Text [ en-US ] = "Font" ;
+ };
+ PageItem
+ {
+ Identifier = TP_FONTEFF ;
+ PageResID = 262 ;
+ Text [ en-US ] = "Font Effects";
+ };
+ PageItem
+ {
+ Identifier = TP_ALIGNMENT ;
+ PageResID = 258 ;
+ Text [ en-US ] = "Alignment" ;
+ };
+ PageItem
+ {
+ Identifier = TP_ASIAN ;
+ PageResID = 263 ;
+ Text [ en-US ] = "Asian Typography";
+ };
+ PageItem
+ {
+ Identifier = TP_BORDER ;
+ PageResID = 259 ;
+ Text [ en-US ] = "Borders" ;
+ };
+ PageItem
+ {
+ Identifier = TP_BACKGROUND ;
+ PageResID = 260 ;
+ Text [ en-US ] = "Background" ;
+ };
+ PageItem
+ {
+ Identifier = TP_PROTECTION ;
+ PageResID = 261 ;
+ Text [ en-US ] = "Cell Protection" ;
+ };
+ };
+ };
+};
+
+ //================================================
+ // Zellschutz-TabPage:
+
+TabPage RID_SCPAGE_PROTECTION
+{
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ HelpId = HID_SCPAGE_PROTECTION ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ TriStateBox BTN_PROTECTED
+ {
+ Pos = MAP_APPFONT ( 22 , 28 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "~Protected" ;
+ TabStop = TRUE ;
+ };
+ TriStateBox BTN_HIDE_FORMULAR
+ {
+ Pos = MAP_APPFONT ( 22 , 42 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "Hide ~formula" ;
+ TabStop = TRUE ;
+ };
+ TriStateBox BTN_HIDE_ALL
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 100 , 10 ) ;
+ Text [ en-US ] = "Hide ~all" ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_HINT
+ {
+ Pos = MAP_APPFONT ( 114 , 14 ) ;
+ Size = MAP_APPFONT ( 137 , 56 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "Cell protection is only effective after the current sheet has been protected. \n\nSelect 'Protect Document' from the 'Tools' menu, and specify 'Sheet'." ;
+ };
+ FixedLine FL_PROTECTION
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Protection" ;
+ };
+ TriStateBox BTN_HIDE_PRINT
+ {
+ Pos = MAP_APPFONT ( 12 , 87 ) ;
+ Size = MAP_APPFONT ( 100 , 10 ) ;
+ Text [ en-US ] = "Hide ~when printing" ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_HINT2
+ {
+ Pos = MAP_APPFONT ( 114 , 87 ) ;
+ Size = MAP_APPFONT ( 137 , 24 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "The cells selected will be omitted when printing." ;
+ };
+ FixedLine FL_PRINT
+ {
+ Pos = MAP_APPFONT ( 6 , 76 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Print" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/autofmt.src b/sc/source/ui/src/autofmt.src
new file mode 100644
index 000000000000..cb56f6ac85a4
--- /dev/null
+++ b/sc/source/ui/src/autofmt.src
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "miscdlgs.hrc"
+
+ModalDialog RID_SCDLG_AUTOFORMAT
+{
+ OutputSize = TRUE ;
+ HelpId = SID_AUTOFORMAT ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 312 , 121 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? AutoFormat : Autoformat */
+ /* ### ACHTUNG: Neuer Text in Resource? AutoFormat : Autoformat */
+ Text [ en-US ] = "AutoFormat" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ ListBox LB_FORMAT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 70 , 101 ) ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FORMAT
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 244 , 8 ) ;
+ Text [ en-US ] = "F~ormat" ;
+ };
+ Window WND_PREVIEW
+ {
+ Pos = MAP_APPFONT ( 88 , 14 ) ;
+ Size = MAP_APPFONT ( 159 , 101 ) ;
+ Border = TRUE ;
+ };
+ CheckBox BTN_ADJUST
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 172 , 146 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Breite/Höhe anpassen : ~Breite/H÷he anpassen */
+ Text [ en-US ] = "A~utoFit width and height" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_BORDER
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 146 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "~Borders" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_FONT
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 93 , 132 ) ;
+ Size = MAP_APPFONT ( 73 , 10 ) ;
+ Text [ en-US ] = "F~ont" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_PATTERN
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 93 , 146 ) ;
+ Size = MAP_APPFONT ( 73 , 10 ) ;
+ Text [ en-US ] = "~Pattern" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_ALIGNMENT
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 172 , 132 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "Alignmen~t" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_NUMFORMAT
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 132 ) ;
+ Size = MAP_APPFONT ( 75 , 10 ) ;
+ Text [ en-US ] = "~Number format" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FORMATTING
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 121 ) ;
+ Size = MAP_APPFONT ( 244 , 8 ) ;
+ Text [ en-US ] = "Formatting" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 256 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 256 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 256 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 48 ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 256 , 63 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Einfügen... : ~Einf³gen... */
+ Text [ en-US ] = "~Add..." ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 256 , 81 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Löschen : ~L÷schen */
+ Text [ en-US ] = "~Delete" ;
+ TabStop = TRUE ;
+ };
+
+ PushButton BTN_RENAME
+ {
+ Pos = MAP_APPFONT ( 256 , 123 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ HelpId=HID_SC_RENAME_AUTOFMT;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Rename" ;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 256 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ String STR_ADD_TITLE
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? AutoFormat hinzufügen : Autoformat hinzufügen */
+ /* ### ACHTUNG: Neuer Text in Resource? AutoFormat hinzufügen : Autoformat hinzufügen */
+ /* ### ACHTUNG: Neuer Text in Resource? AutoFormat hinzufügen : AutoFormat hinzuf³gen */
+ Text [ en-US ] = "Add AutoFormat" ;
+ };
+
+ String STR_RENAME_TITLE
+ {
+ Text [ en-US ] = "Rename AutoFormat" ;
+ };
+
+ String STR_ADD_LABEL
+ {
+ Text [ en-US ] = "Name" ;
+ };
+ String STR_DEL_TITLE
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? AutoFormat löschen : AutoFormat l÷schen */
+ Text [ en-US ] = "Delete AutoFormat" ;
+ };
+ String STR_DEL_MSG
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Wollen Sie das AutoFormat # wirklich löschen? : Wollen Sie das AutoFormat # wirklich l÷schen? */
+ Text [ en-US ] = "Do you really want to delete the # AutoFomat?" ;
+ };
+ String STR_BTN_CLOSE
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Schlie~ßen : Schlie~˜en */
+ Text [ en-US ] = "~Close" ;
+ };
+ String STR_JAN
+ {
+ Text [ en-US ] = "Jan" ;
+ };
+ String STR_FEB
+ {
+ Text [ en-US ] = "Feb" ;
+ };
+ String STR_MAR
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Mär : Mõr */
+ Text [ en-US ] = "Mar" ;
+ };
+ String STR_NORTH
+ {
+ Text [ en-US ] = "North" ;
+ };
+ String STR_MID
+ {
+ Text [ en-US ] = "Mid" ;
+ };
+ String STR_SOUTH
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Süd : S³d */
+ Text [ en-US ] = "South" ;
+ };
+ String STR_SUM
+ {
+ Text [ en-US ] = "Total" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/condfrmt.src b/sc/source/ui/src/condfrmt.src
new file mode 100644
index 000000000000..3018cc867e0d
--- /dev/null
+++ b/sc/source/ui/src/condfrmt.src
@@ -0,0 +1,398 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "condfrmt.hrc"
+ModelessDialog RID_SCDLG_CONDFORMAT
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 316 , 161 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ HelpId = HID_SCDLG_CONDFORMAT ;
+ Hide = TRUE ;
+ CheckBox CBX_COND1
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 248 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Condition ~1" ;
+ };
+ ListBox LB_COND1_1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 19 ) ;
+ Size = MAP_APPFONT ( 48 , 40 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Cell value is" ; Default ; > ;
+ < "Formula is" ; Default ; > ;
+ };
+ };
+ ListBox LB_COND1_2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 19 ) ;
+ Size = MAP_APPFONT ( 62 , 88 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "equal to" ; Default ; > ;
+ < "less than" ; Default ; > ;
+ < "greater than" ; Default ; > ;
+ < "less than or equal to" ; Default ; > ;
+ < "greater than or equal to" ; Default ; > ;
+ < "not equal to" ; Default ; > ;
+ < "between" ; Default ; > ;
+ < "not between" ; Default ; > ;
+ };
+ };
+ Edit EDT_COND1_1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 124 , 19 ) ;
+ Size = MAP_APPFONT ( 41 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COND1_1
+ {
+ Pos = MAP_APPFONT ( 167 , 18 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COND1_AND
+ {
+ Pos = MAP_APPFONT ( 181 , 21 ) ;
+ Size = MAP_APPFONT ( 16 , 8 ) ;
+ Center = TRUE ;
+ Text [ en-US ] = "and" ;
+ };
+ Edit EDT_COND1_2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 199 , 19 ) ;
+ Size = MAP_APPFONT ( 41 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COND1_2
+ {
+ Pos = MAP_APPFONT ( 242 , 18 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COND1_TEMPLATE
+ {
+ Pos = MAP_APPFONT ( 6 , 37 ) ;
+ Size = MAP_APPFONT ( 46 , 8 ) ;
+ Right = TRUE ;
+ Text [ en-US ] = "~Cell Style" ;
+ };
+ ListBox LB_COND1_TEMPLATE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 35 ) ;
+ Size = MAP_APPFONT ( 62 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ PushButton BTN_COND1_NEW
+ {
+ Pos = MAP_APPFONT ( 124 , 34 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~New Style..." ;
+ };
+ FixedLine FL_SEP1
+ {
+ Pos = MAP_APPFONT ( 6 , 51 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ };
+ CheckBox CBX_COND2
+ {
+ Pos = MAP_APPFONT ( 6 , 60 ) ;
+ Size = MAP_APPFONT ( 248 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Condition ~2" ;
+ };
+ ListBox LB_COND2_1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 73 ) ;
+ Size = MAP_APPFONT ( 48 , 40 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Cell value is" ; Default ; > ;
+ < "Formula is" ; Default ; > ;
+ };
+ };
+ ListBox LB_COND2_2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 73 ) ;
+ Size = MAP_APPFONT ( 62 , 88 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "equal to" ; Default ; > ;
+ < "less than" ; Default ; > ;
+ < "greater than" ; Default ; > ;
+ < "less than or equal to" ; Default ; > ;
+ < "greater than or equal to" ; Default ; > ;
+ < "not equal to" ; Default ; > ;
+ < "between" ; Default ; > ;
+ < "not between" ; Default ; > ;
+ };
+ };
+ Edit EDT_COND2_1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 124 , 73 ) ;
+ Size = MAP_APPFONT ( 41 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COND2_1
+ {
+ Pos = MAP_APPFONT ( 167 , 72 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COND2_AND
+ {
+ Pos = MAP_APPFONT ( 181 , 75 ) ;
+ Size = MAP_APPFONT ( 16 , 8 ) ;
+ Center = TRUE ;
+ Text [ en-US ] = "and" ;
+ };
+ Edit EDT_COND2_2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 199 , 73 ) ;
+ Size = MAP_APPFONT ( 41 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COND2_2
+ {
+ Pos = MAP_APPFONT ( 242 , 72 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COND2_TEMPLATE
+ {
+ Pos = MAP_APPFONT ( 6 , 91 ) ;
+ Size = MAP_APPFONT ( 46 , 8 ) ;
+ Right = TRUE ;
+ Text [ en-US ] = "C~ell Style" ;
+ };
+ ListBox LB_COND2_TEMPLATE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 89 ) ;
+ Size = MAP_APPFONT ( 62 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ PushButton BTN_COND2_NEW
+ {
+ Pos = MAP_APPFONT ( 124 , 88 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Ne~w Style..." ;
+ };
+ FixedLine FL_SEP2
+ {
+ Pos = MAP_APPFONT ( 6 , 105 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ };
+ CheckBox CBX_COND3
+ {
+ Pos = MAP_APPFONT ( 6 , 114 ) ;
+ Size = MAP_APPFONT ( 248 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Condition ~3" ;
+ };
+ ListBox LB_COND3_1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 127 ) ;
+ Size = MAP_APPFONT ( 48 , 40 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Cell value is" ; Default ; > ;
+ < "Formula is" ; Default ; > ;
+ };
+ };
+ ListBox LB_COND3_2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 127 ) ;
+ Size = MAP_APPFONT ( 62 , 88 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "equal to" ; Default ; > ;
+ < "less than" ; Default ; > ;
+ < "greater than" ; Default ; > ;
+ < "less than or equal to" ; Default ; > ;
+ < "greater than or equal to" ; Default ; > ;
+ < "not equal to" ; Default ; > ;
+ < "between" ; Default ; > ;
+ < "not between" ; Default ; > ;
+ };
+ };
+ Edit EDT_COND3_1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 124 , 127 ) ;
+ Size = MAP_APPFONT ( 41 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COND3_1
+ {
+ Pos = MAP_APPFONT ( 167 , 126 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COND3_AND
+ {
+ Pos = MAP_APPFONT ( 181 , 129 ) ;
+ Size = MAP_APPFONT ( 16 , 8 ) ;
+ Center = TRUE ;
+ Text [ en-US ] = "and" ;
+ };
+ Edit EDT_COND3_2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 199 , 127 ) ;
+ Size = MAP_APPFONT ( 41 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COND3_2
+ {
+ Pos = MAP_APPFONT ( 242 , 126 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COND3_TEMPLATE
+ {
+ Pos = MAP_APPFONT ( 6 , 145 ) ;
+ Size = MAP_APPFONT ( 46 , 8 ) ;
+ Right = TRUE ;
+ Text [ en-US ] = "Ce~ll Style" ;
+ };
+ ListBox LB_COND3_TEMPLATE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 143 ) ;
+ Size = MAP_APPFONT ( 62 , 80 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ PushButton BTN_COND3_NEW
+ {
+ Pos = MAP_APPFONT ( 124 , 142 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "New ~Style..." ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 260 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 260 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 260 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Text [ en-US ] = "Conditional Formatting" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/crnrdlg.src b/sc/source/ui/src/crnrdlg.src
new file mode 100644
index 000000000000..b16a3506bf7b
--- /dev/null
+++ b/sc/source/ui/src/crnrdlg.src
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "crnrdlg.hrc"
+ModelessDialog RID_SCDLG_COLROWNAMERANGES
+{
+ OutputSize = TRUE ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 256 , 181 ) ;
+ HelpId = HID_COLROWNAMERANGES ;
+ Moveable = TRUE ;
+ // Closeable = TRUE; // Dieser Dialog hat einen Cancel-Button !
+ FixedLine FL_ASSIGN
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 188 , 8 ) ;
+ Text [ en-US ] = "Range" ;
+ };
+ ListBox LB_RANGE
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 179 , 85 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ Border = TRUE ;
+ };
+ Edit ED_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 105 ) ;
+ Size = MAP_APPFONT ( 165 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_AREA
+ {
+ Pos = MAP_APPFONT ( 179 , 104 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ RadioButton BTN_COLHEAD
+ {
+ Pos = MAP_APPFONT ( 20 , 121 ) ;
+ Size = MAP_APPFONT ( 171 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Contains ~column labels" ;
+ };
+ RadioButton BTN_ROWHEAD
+ {
+ Pos = MAP_APPFONT ( 20 , 135 ) ;
+ Size = MAP_APPFONT ( 171 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Contains ~row labels" ;
+ };
+ FixedText FT_DATA_LABEL
+ {
+ Pos = MAP_APPFONT ( 12 , 151 ) ;
+ Size = MAP_APPFONT ( 179 , 8 ) ;
+ Text [ en-US ] = "For ~data range" ;
+ };
+ Edit ED_DATA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 162 ) ;
+ Size = MAP_APPFONT ( 165 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_DATA
+ {
+ Pos = MAP_APPFONT ( 179 , 161 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 200 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 200 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 200 , 104 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Add" ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 200 , 122 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Delete" ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 200 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Text [ en-US ] = "Define Label Range" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/dbnamdlg.src b/sc/source/ui/src/dbnamdlg.src
new file mode 100644
index 000000000000..50152d95d9d5
--- /dev/null
+++ b/sc/source/ui/src/dbnamdlg.src
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "dbnamdlg.hrc"
+ModelessDialog RID_SCDLG_DBNAMES
+{
+ OutputSize = TRUE ;
+ HelpId = SID_DEFINE_DBNAME ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 222 , 142 ) ;
+ Text [ en-US ] = "Define Database Range" ;
+ Moveable = TRUE ;
+ // Closeable = TRUE; // Dieser Dialog hat einen Cancel-Button !
+ FixedLine FL_NAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "Na~me" ;
+ };
+ ComboBox ED_NAME
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 145 , 92 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ };
+ FixedLine FL_ASSIGN
+ {
+ Pos = MAP_APPFONT ( 6 , 112 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "~Range" ;
+ };
+ Edit ED_DBAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 123 ) ;
+ Size = MAP_APPFONT ( 131 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_DBAREA
+ {
+ Pos = MAP_APPFONT ( 145 , 122 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_OPTIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 142 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "Options" ;
+ };
+ CheckBox BTN_HEADER
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 153 ) ;
+ Size = MAP_APPFONT ( 145 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Co~ntains column labels" ;
+ };
+ CheckBox BTN_SIZE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 167 ) ;
+ Size = MAP_APPFONT ( 145 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Insert or delete ~cells" ;
+ };
+ CheckBox BTN_FORMAT
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 181 ) ;
+ Size = MAP_APPFONT ( 145 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Keep ~formatting" ;
+ };
+ CheckBox BTN_STRIPDATA
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 195 ) ;
+ Size = MAP_APPFONT ( 145 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Don't save ~imported data" ;
+ };
+ FixedText FT_SOURCE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 209 ) ;
+ Size = MAP_APPFONT ( 145 , 8 ) ;
+ Text [ en-US ] = "Source:" ;
+ };
+ FixedText FT_OPERATIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 221 ) ;
+ Size = MAP_APPFONT ( 145 , 8 ) ;
+ Text [ en-US ] = "Operations:" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 166 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 166 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 166 , 74 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Add" ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 166 , 92 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Delete" ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 166 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 166 , 122 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 93 ;
+ };
+ String STR_ADD
+ {
+ Text [ en-US ] = "~Add" ;
+ };
+ String STR_MODIFY
+ {
+ Text [ en-US ] = "M~odify" ;
+ };
+ String STR_DB_INVALID
+ {
+ Text [ en-US ] = "Invalid range" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/filter.src b/sc/source/ui/src/filter.src
new file mode 100644
index 000000000000..52ce38db1516
--- /dev/null
+++ b/sc/source/ui/src/filter.src
@@ -0,0 +1,820 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "filter.hrc"
+ModelessDialog RID_SCDLG_FILTER
+{
+ OutputSize = TRUE ;
+ HelpId = SID_FILTER ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 279 , 121 ) ;
+ Text [ en-US ] = "Standard Filter" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_OP
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 44 , 8 ) ;
+ Text [ en-US ] = "Operator" ;
+ };
+ FixedText FT_FIELD
+ {
+ Pos = MAP_APPFONT ( 58 , 14 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Field name" ;
+ };
+ FixedText FT_COND
+ {
+ Pos = MAP_APPFONT ( 122 , 14 ) ;
+ Size = MAP_APPFONT ( 47 , 8 ) ;
+ Text [ en-US ] = "Condition" ;
+ };
+ FixedText FT_VAL
+ {
+ Pos = MAP_APPFONT ( 201 , 14 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Value" ;
+ };
+ ListBox LB_OP1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 25 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "AND" ; Default ; > ;
+ < "OR" ; Default ; > ;
+ };
+ };
+ ListBox LB_OP2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 41 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "AND" ; Default ; > ;
+ < "OR" ; Default ; > ;
+ };
+ };
+ ListBox LB_OP3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 57 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "AND" ; Default ; > ;
+ < "OR" ; Default ; > ;
+ };
+ };
+ ListBox LB_OP4
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 73 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "AND" ; Default ; > ;
+ < "OR" ; Default ; > ;
+ };
+ };
+ ListBox LB_FIELD1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 25 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_FIELD2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 41 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_FIELD3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 57 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_FIELD4
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 73 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_COND1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 122 , 25 ) ;
+ Size = MAP_APPFONT ( 75 , 145 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ stringlist [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ < "Largest" ; Default ; > ;
+ < "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 ( 75 , 145 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ stringlist [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ < "Largest" ; Default ; > ;
+ < "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 ( 75 , 145 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ stringlist [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ < "Largest" ; Default ; > ;
+ < "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 ( 75 , 145 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ stringlist [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ < "Largest" ; Default ; > ;
+ < "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 ( 201 , 25 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ComboBox ED_VAL2
+ {
+ Pos = MAP_APPFONT ( 201 , 41 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ComboBox ED_VAL3
+ {
+ Pos = MAP_APPFONT ( 201 , 57 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ComboBox ED_VAL4
+ {
+ Pos = MAP_APPFONT ( 201 , 73 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ScrollBar LB_SCROLL
+ {
+ Pos = MAP_APPFONT ( 265, 25 ) ;
+ Size = MAP_APPFONT ( 8 , 60 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ };
+
+ FixedLine FL_CRITERIA
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 267 , 8 ) ;
+ Text [ en-US ] = "Filter criteria";
+ };
+ CheckBox BTN_CASE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 130 ) ;
+ Size = MAP_APPFONT ( 128 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Case ~sensitive" ;
+ };
+ CheckBox BTN_REGEXP
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 130 ) ;
+ Size = MAP_APPFONT ( 94 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Regular ~expression" ;
+ };
+ CheckBox BTN_HEADER
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 144 ) ;
+ Size = MAP_APPFONT ( 128 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Range contains ~column labels" ;
+ };
+ CheckBox BTN_UNIQUE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 144 ) ;
+ Size = MAP_APPFONT ( 94 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~No duplication" ;
+ };
+ CheckBox BTN_COPY_RESULT
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 158 ) ;
+ Size = MAP_APPFONT ( 128 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Copy ~results to..." ;
+ };
+ CheckBox BTN_DEST_PERS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 158 ) ;
+ Size = MAP_APPFONT ( 94 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Keep filter criteria" ;
+ };
+ ListBox LB_COPY_AREA
+ {
+ Border = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 21 , 170 ) ;
+ Size = MAP_APPFONT ( 110 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ Edit ED_COPY_AREA
+ {
+ Border = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 136 , 170 ) ;
+ Size = MAP_APPFONT ( 110 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COPY_AREA
+ {
+ Pos = MAP_APPFONT ( 248 , 169 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_OPTIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 118 ) ;
+ Size = MAP_APPFONT ( 267 , 8 ) ;
+ };
+ FixedText FT_DBAREA
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 66 , 188 ) ;
+ Size = MAP_APPFONT ( 167 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "dummy" ;
+ };
+ FixedText FT_DBAREA_LABEL
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 188 ) ;
+ Size = MAP_APPFONT ( 58 , 8 ) ;
+ Text [ en-US ] = "Data range:" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 169 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 223 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 62 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 6 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 81 ;
+ };
+ FixedLine FL_SEPARATOR
+ {
+ Pos = MAP_APPFONT ( 0 , 91 ) ;
+ Size = MAP_APPFONT ( 279 , 6 ) ;
+ };
+};
+ //============================================================================
+ModelessDialog RID_SCDLG_SPEC_FILTER
+{
+ OutputSize = TRUE ;
+ HelpId = SID_SPECIAL_FILTER ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 278 , 83 ) ;
+ Text [ en-US ] = "Advanced Filter" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_CRITERIA_AREA
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 210 , 8 ) ;
+ Text [ en-US ] = "Read ~filter criteria from" ;
+ };
+ ListBox LB_CRITERIA_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 14 ) ;
+ Size = MAP_APPFONT ( 90 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ Edit ED_CRITERIA_AREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 100 , 14 ) ;
+ Size = MAP_APPFONT ( 99 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_CRITERIA_AREA
+ {
+ Pos = MAP_APPFONT ( 201 , 13 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ CheckBox BTN_CASE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 43 ) ;
+ Size = MAP_APPFONT ( 128 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Case sensitive" ;
+ };
+ CheckBox BTN_REGEXP
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 43 ) ;
+ Size = MAP_APPFONT ( 74 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Regular ~expressions" ;
+ };
+ CheckBox BTN_HEADER
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 57 ) ;
+ Size = MAP_APPFONT ( 128 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Range c~ontains column labels" ;
+ };
+ CheckBox BTN_UNIQUE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 57 ) ;
+ Size = MAP_APPFONT ( 74 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~No duplication" ;
+ };
+ CheckBox BTN_COPY_RESULT
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 71 ) ;
+ Size = MAP_APPFONT ( 128 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Co~py results to" ;
+ };
+ CheckBox BTN_DEST_PERS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 142 , 71 ) ;
+ Size = MAP_APPFONT ( 74 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Keep filter criteria" ;
+ };
+ ListBox LB_COPY_AREA
+ {
+ Border = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 83 ) ;
+ Size = MAP_APPFONT ( 76 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ Edit ED_COPY_AREA
+ {
+ Border = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 100 , 83 ) ;
+ Size = MAP_APPFONT ( 99 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_COPY_AREA
+ {
+ Pos = MAP_APPFONT ( 201 , 82 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_OPTIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 32 ) ;
+ Size = MAP_APPFONT ( 210 , 8 ) ;
+ Text [ en-US ] = "Options" ;
+ };
+ FixedText FT_DBAREA
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 101 ) ;
+ Size = MAP_APPFONT ( 155 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "dummy" ;
+ };
+ FixedText FT_DBAREA_LABEL
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 101 ) ;
+ Size = MAP_APPFONT ( 50 , 8 ) ;
+ Text [ en-US ] = "Data range:" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 222 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 222 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 222 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 223 , 63 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 32 ;
+ };
+};
+ //============================================================================
+ModalDialog RID_SCDLG_PIVOTFILTER
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_PIVOTFILTER ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 298 , 83 ) ;
+ Text [ en-US ] = "Filter" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_OP
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "Operator" ;
+ };
+ FixedText FT_FIELD
+ {
+ Pos = MAP_APPFONT ( 58 , 14 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Field name" ;
+ };
+ FixedText FT_COND
+ {
+ Pos = MAP_APPFONT ( 122 , 14 ) ;
+ Size = MAP_APPFONT ( 47 , 8 ) ;
+ Text [ en-US ] = "Condition" ;
+ };
+ FixedText FT_VAL
+ {
+ Pos = MAP_APPFONT ( 173 , 14 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Value" ;
+ };
+ ListBox LB_OP1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 41 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "AND" ; Default ; > ;
+ < "OR" ; Default ; > ;
+ };
+ };
+ ListBox LB_OP2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 57 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "AND" ; Default ; > ;
+ < "OR" ; Default ; > ;
+ };
+ };
+ ListBox LB_FIELD1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 25 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_FIELD2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 41 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_FIELD3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 58 , 57 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox LB_COND1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 122 , 25 ) ;
+ Size = MAP_APPFONT ( 47 , 65 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ };
+ };
+ ListBox LB_COND2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 122 , 41 ) ;
+ Size = MAP_APPFONT ( 47 , 65 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ };
+ };
+ ListBox LB_COND3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 122 , 57 ) ;
+ Size = MAP_APPFONT ( 47 , 65 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "=" ; Default ; > ;
+ < "<" ; Default ; > ;
+ < ">" ; Default ; > ;
+ < "<=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "<>" ; Default ; > ;
+ };
+ };
+ ComboBox ED_VAL1
+ {
+ Pos = MAP_APPFONT ( 173 , 25 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ComboBox ED_VAL2
+ {
+ Pos = MAP_APPFONT ( 173 , 41 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ComboBox ED_VAL3
+ {
+ Pos = MAP_APPFONT ( 173 , 57 ) ;
+ Size = MAP_APPFONT ( 60 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedLine FL_CRITERIA
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 230 , 8 ) ;
+ Text [ en-US ] = "Filter criteria";
+ };
+ CheckBox BTN_CASE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 86 ) ;
+ Size = MAP_APPFONT ( 221 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Case sensitive" ;
+ };
+ CheckBox BTN_REGEXP
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 100 ) ;
+ Size = MAP_APPFONT ( 221 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Regular expression" ;
+ };
+ CheckBox BTN_UNIQUE
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 114 ) ;
+ Size = MAP_APPFONT ( 221 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~No duplication" ;
+ };
+ FixedLine FL_OPTIONS
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 75 ) ;
+ Size = MAP_APPFONT ( 230 , 8 ) ;
+ Text [ en-US ] = "Options" ;
+ };
+ FixedText FT_DBAREA
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 130 ) ;
+ Size = MAP_APPFONT ( 166 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "dummy" ;
+ };
+ FixedText FT_DBAREA_LABEL
+ {
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 130 ) ;
+ Size = MAP_APPFONT ( 58 , 8 ) ;
+ Text [ en-US ] = "Data range:" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 242 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 242 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 242 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 242 , 63 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 61 ;
+ };
+};
+
diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src
new file mode 100644
index 000000000000..6c15762bda6a
--- /dev/null
+++ b/sc/source/ui/src/globstr.src
@@ -0,0 +1,1742 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "globstr.hrc"
+#include "sc.hrc"
+
+
+
+Resource RID_GLOBSTR
+{
+ String STR_UNDO_INSERTCELLS
+ {
+ Text [ en-US ] = "Insert" ;
+ };
+ String STR_UNDO_DELETECELLS
+ {
+ Text [ en-US ] = "Delete" ;
+ };
+ String STR_UNDO_CUT
+ {
+ Text [ en-US ] = "Cut" ;
+ };
+ String STR_UNDO_PASTE
+ {
+ Text [ en-US ] = "Insert" ;
+ };
+ String STR_UNDO_DRAGDROP
+ {
+ Text [ en-US ] = "Drag and Drop" ;
+ };
+ String STR_UNDO_MOVE
+ {
+ Text [ en-US ] = "Move" ;
+ };
+ String STR_UNDO_COPY
+ {
+ Text [ en-US ] = "Copy" ;
+ };
+ String STR_UNDO_DELETECONTENTS
+ {
+ Text [ en-US ] = "Delete" ;
+ };
+ String STR_UNDO_SELATTR
+ {
+ Text [ en-US ] = "Attributes" ;
+ };
+ String STR_UNDO_SELATTRLINES
+ {
+ Text [ en-US ] = "Attributes/Lines" ;
+ };
+ String STR_UNDO_COLWIDTH
+ {
+ Text [ en-US ] = "Column Width" ;
+ };
+ String STR_UNDO_OPTCOLWIDTH
+ {
+ Text [ en-US ] = "Optimal Column Width" ;
+ };
+ String STR_UNDO_ROWHEIGHT
+ {
+ Text [ en-US ] = "Row height" ;
+ };
+ String STR_UNDO_OPTROWHEIGHT
+ {
+ Text [ en-US ] = "Optimal Row Height" ;
+ };
+ String STR_UNDO_AUTOFILL
+ {
+ Text [ en-US ] = "Fill" ;
+ };
+ String STR_UNDO_MERGE
+ {
+ Text [ en-US ] = "Merge" ;
+ };
+ String STR_UNDO_REMERGE
+ {
+ Text [ en-US ] = "Split" ;
+ };
+ String STR_UNDO_AUTOFORMAT
+ {
+ Text [ en-US ] = "AutoFormat" ;
+ };
+ String STR_UNDO_REPLACE
+ {
+ Text [ en-US ] = "Replace" ;
+ };
+ String STR_UNDO_CURSORATTR
+ {
+ Text [ en-US ] = "Attributes" ;
+ };
+ String STR_UNDO_ENTERDATA
+ {
+ Text [ en-US ] = "Input" ;
+ };
+ String STR_UNDO_INSCOLBREAK
+ {
+ Text [ en-US ] = "Insert Column Break" ;
+ };
+ String STR_UNDO_DELCOLBREAK
+ {
+ Text [ en-US ] = "Delete column break" ;
+ };
+ String STR_UNDO_INSROWBREAK
+ {
+ Text [ en-US ] = "Insert Row Break" ;
+ };
+ String STR_UNDO_DELROWBREAK
+ {
+ Text [ en-US ] = "Delete row break" ;
+ };
+ String STR_UNDO_DOOUTLINE
+ {
+ Text [ en-US ] = "View Details" ;
+ };
+ String STR_UNDO_REDOOUTLINE
+ {
+ Text [ en-US ] = "Hide details" ;
+ };
+ String STR_UNDO_MAKEOUTLINE
+ {
+ Text [ en-US ] = "Group" ;
+ };
+ String STR_UNDO_REMAKEOUTLINE
+ {
+ Text [ en-US ] = "Ungroup" ;
+ };
+ String STR_UNDO_OUTLINELEVEL
+ {
+ Text [ en-US ] = "Select outline level" ;
+ };
+ String STR_UNDO_DOOUTLINEBLK
+ {
+ Text [ en-US ] = "View Details" ;
+ };
+ String STR_UNDO_REDOOUTLINEBLK
+ {
+ Text [ en-US ] = "Hide details" ;
+ };
+ String STR_UNDO_REMOVEALLOTLNS
+ {
+ Text [ en-US ] = "Clear Outline" ;
+ };
+ String STR_UNDO_AUTOOUTLINE
+ {
+ Text [ en-US ] = "AutoOutline" ;
+ };
+ String STR_UNDO_SUBTOTALS
+ {
+ Text [ en-US ] = "Subtotals" ;
+ };
+ String STR_UNDO_SORT
+ {
+ Text [ en-US ] = "Sort" ;
+ };
+ String STR_UNDO_QUERY
+ {
+ Text [ en-US ] = "Filter" ;
+ };
+ String STR_UNDO_DBDATA
+ {
+ Text [ en-US ] = "Change Database Range" ;
+ };
+ String STR_UNDO_IMPORTDATA
+ {
+ Text [ en-US ] = "Importing" ;
+ };
+ String STR_UNDO_REPEATDB
+ {
+ Text [ en-US ] = "Refresh range" ;
+ };
+ String STR_UNDO_GRAFEDIT
+ {
+ Text [ en-US ] = "Edit graphics" ;
+ };
+ String STR_UNDO_LISTNAMES
+ {
+ Text [ en-US ] = "List names" ;
+ };
+ String STR_UNDO_PIVOT_NEW
+ {
+ Text [ en-US ] = "Create DataPilot Table" ;
+ };
+ String STR_UNDO_PIVOT_MODIFY
+ {
+ Text [ en-US ] = "Edit DataPilot Table" ;
+ };
+ String STR_UNDO_PIVOT_DELETE
+ {
+ Text [ en-US ] = "Delete DataPilot Table" ;
+ };
+ String STR_UNDO_CONSOLIDATE
+ {
+ Text [ en-US ] = "Consolidate" ;
+ };
+ String STR_UNDO_USESCENARIO
+ {
+ Text [ en-US ] = "Use scenario" ;
+ };
+ String STR_UNDO_MAKESCENARIO
+ {
+ Text [ en-US ] = "Create scenario" ;
+ };
+ String STR_UNDO_EDITSCENARIO
+ {
+ Text [ en-US ] = "Edit scenario" ;
+ };
+ String STR_UNDO_APPLYCELLSTYLE
+ {
+ Text [ en-US ] = "Apply Cell Style" ;
+ };
+ String STR_UNDO_EDITCELLSTYLE
+ {
+ Text [ en-US ] = "Edit Cell Style";
+ };
+ String STR_UNDO_APPLYPAGESTYLE
+ {
+ Text [ en-US ] = "Apply Page Style";
+ };
+ String STR_UNDO_EDITPAGESTYLE
+ {
+ Text [ en-US ] = "Edit Page Style";
+ };
+ String STR_UNDO_DETADDPRED
+ {
+ Text [ en-US ] = "Trace Precedents" ;
+ };
+ String STR_UNDO_DETDELPRED
+ {
+ Text [ en-US ] = "Remove Precedent" ;
+ };
+ String STR_UNDO_DETADDSUCC
+ {
+ Text [ en-US ] = "Trace Dependents" ;
+ };
+ String STR_UNDO_DETDELSUCC
+ {
+ Text [ en-US ] = "Remove Dependent" ;
+ };
+ String STR_UNDO_DETADDERROR
+ {
+ Text [ en-US ] = "Trace Error" ;
+ };
+ String STR_UNDO_DETDELALL
+ {
+ Text [ en-US ] = "Remove all Traces" ;
+ };
+ String STR_UNDO_DETINVALID
+ {
+ Text [ en-US ] = "Mark invalid data" ;
+ };
+ String STR_UNDO_DETREFRESH
+ {
+ Text [ en-US ] = "Refresh Traces" ;
+ };
+ String STR_UNDO_CHARTDATA
+ {
+ Text [ en-US ] = "Modify chart data range" ;
+ };
+ String STR_UNDO_ORIGINALSIZE
+ {
+ Text [ en-US ] = "Original Size" ;
+ };
+ String STR_UNDO_UPDATELINK
+ {
+ Text [ en-US ] = "Update Link" ;
+ };
+ String STR_UNDO_REMOVELINK
+ {
+ Text [ en-US ] = "Unlink" ;
+ };
+ String STR_UNDO_INSERTAREALINK
+ {
+ Text [ en-US ] = "Insert Link" ;
+ };
+ String STR_UNDO_ENTERMATRIX
+ {
+ Text [ en-US ] = "Insert Array Formula" ;
+ };
+ String STR_UNDO_INSERTNOTE
+ {
+ Text [ en-US ] = "Insert Comment" ;
+ };
+ String STR_UNDO_DELETENOTE
+ {
+ Text [ en-US ] = "Delete Comment" ;
+ };
+ String STR_UNDO_SHOWNOTE
+ {
+ Text [ en-US ] = "Show Comment" ;
+ };
+ String STR_UNDO_HIDENOTE
+ {
+ Text [ en-US ] = "Hide Comment" ;
+ };
+ String STR_UNDO_EDITNOTE
+ {
+ Text [ en-US ] = "Edit Comment" ;
+ };
+ String STR_UNDO_DEC_INDENT
+ {
+ Text [ en-US ] = "Decrease Indent" ;
+ };
+ String STR_UNDO_INC_INDENT
+ {
+ Text [ en-US ] = "Increase Indent" ;
+ };
+ String STR_UNDO_PROTECT_TAB
+ {
+ Text [ en-US ] = "Protect sheet" ;
+ };
+ String STR_UNDO_UNPROTECT_TAB
+ {
+ Text [ en-US ] = "Unprotect sheet" ;
+ };
+ String STR_UNDO_PROTECT_DOC
+ {
+ Text [ en-US ] = "Protect document" ;
+ };
+ String STR_UNDO_UNPROTECT_DOC
+ {
+ Text [ en-US ] = "Unprotect document" ;
+ };
+ String STR_UNDO_PRINTRANGES
+ {
+ Text [ en-US ] = "Print range" ;
+ };
+ String STR_UNDO_REMOVEBREAKS
+ {
+ Text [ en-US ] = "Delete Page Breaks" ;
+ };
+ String STR_UNDO_PRINTSCALE
+ {
+ Text [ en-US ] = "Change Scale" ;
+ };
+ String STR_UNDO_DRAG_BREAK
+ {
+ Text [ en-US ] = "Move Page Break" ;
+ };
+ String STR_UNDO_RANGENAMES
+ {
+ Text [ en-US ] = "Edit range names" ;
+ };
+ String STR_UNDO_TRANSLITERATE
+ {
+ Text [ en-US ] = "Case/Characters";
+ };
+ String STR_DB_NONAME
+ {
+ Text [ en-US ] = "unnamed" ;
+ };
+ String STR_DBNAME_IMPORT
+ {
+ Text [ en-US ] = "Import" ;
+ };
+ String STR_MSSG_DOSUBTOTALS_0
+ {
+ Text [ en-US ] = "%PRODUCTNAME Calc" ;
+ };
+ String STR_MSSG_DOSUBTOTALS_1
+ {
+ Text [ en-US ] = "Delete data?" ;
+ };
+ String STR_MSSG_DOSUBTOTALS_2
+ {
+ Text [ en-US ] = "Unable to insert rows" ;
+ };
+ String STR_MSSG_REPEATDB_0
+ {
+ Text [ en-US ] = "No operations to execute" ;
+ };
+ String STR_MSSG_MAKEAUTOFILTER_0
+ {
+ Text [ en-US ] = "The range does not contain column headers.\nDo you want the first line to be used as column header?" ;
+ };
+ String STR_MSSG_IMPORTDATA_0
+ {
+ Text [ en-US ] = "Error while importing data!" ;
+ };
+ String STR_DATABASE_NOTFOUND
+ {
+ Text [ en-US ] = "The database '#' could not be opened." ;
+ };
+ String STR_QUERY_NOTFOUND
+ {
+ Text [ en-US ] = "The query '#' could not be opened." ;
+ };
+ String STR_DATABASE_ABORTED
+ {
+ Text [ en-US ] = "Database import terminated." ;
+ };
+ String STR_PROGRESS_IMPORT
+ {
+ Text [ en-US ] = "# records imported..." ;
+ };
+ String STR_MSSG_MAKEOUTLINE_0
+ {
+ Text [ en-US ] = "Grouping not possible" ;
+ };
+ String STR_MSSG_REMOVEOUTLINE_0
+ {
+ Text [ en-US ] = "Ungrouping not possible" ;
+ };
+ String STR_MSSG_PASTEFROMCLIP_0
+ {
+ Text [ en-US ] = "Insert into multiple selection not possible" ;
+ };
+ String STR_MSSG_PASTEFROMCLIP_1
+ {
+ Text [ en-US ] = "Cell merge not possible if cells already merged!" ;
+ };
+ String STR_MSSG_MOVEBLOCKTO_0
+ {
+ Text [ en-US ] = "Cell merge not possible if cells already merged!" ;
+ };
+ String STR_MSSG_INSERTCELLS_0
+ {
+ Text [ en-US ] = "Inserting into merged ranges not possible" ;
+ };
+ String STR_MSSG_DELETECELLS_0
+ {
+ Text [ en-US ] = "Deleting in merged ranges not possible" ;
+ };
+ String STR_MSSG_MERGECELLS_0
+ {
+ Text [ en-US ] = "Cell merge not possible if cells already merged" ;
+ };
+ String STR_SORT_ERR_MERGED
+ {
+ Text [ en-US ] = "Ranges containing merged cells can only be sorted without formats." ;
+ };
+ String STR_MSSG_SEARCHANDREPLACE_0
+ {
+ Text [ en-US ] = "Search key not found." ;
+ };
+ String STR_MSSG_SOLVE_0
+ {
+ Text [ en-US ] = "Goal Seek successful.\n" ;
+ };
+ String STR_MSSG_SOLVE_1
+ {
+ Text [ en-US ] = "Insert result (" ;
+ };
+ String STR_MSSG_SOLVE_2
+ {
+ Text [ en-US ] = ") into current cell?" ;
+ };
+ String STR_MSSG_SOLVE_3
+ {
+ Text [ en-US ] = "Goal Seek not successful.\n" ;
+ };
+ String STR_MSSG_SOLVE_4
+ {
+ Text [ en-US ] = "No exact value found. \n" ;
+ };
+ String STR_MSSG_SOLVE_5
+ {
+ Text [ en-US ] = "Insert closest value (" ;
+ };
+ String STR_MSSG_SOLVE_6
+ {
+ Text [ en-US ] = ")?" ;
+ };
+ String STR_TABLE_GESAMTERGEBNIS
+ {
+ Text [ en-US ] = "Grand Total" ;
+ };
+ String STR_TABLE_ERGEBNIS
+ {
+ Text [ en-US ] = "Result" ;
+ };
+ String STR_UNDO_SPELLING
+ {
+ Text [ en-US ] = "Spellcheck" ;
+ };
+ String STR_TABLE_UND
+ {
+ Text [ en-US ] = "AND" ;
+ };
+ String STR_TABLE_ODER
+ {
+ Text [ en-US ] = "OR" ;
+ };
+ String STR_TABLE_DEF
+ {
+ Text [ en-US ] = "Sheet" ;
+ };
+ String STR_MOVE_TO_END
+ {
+ Text [ en-US ] = "- move to end position -" ;
+ };
+ String STR_BOX_YNI
+ {
+ Text [ en-US ] = "Not implemented in this build." ;
+ };
+ String STR_NO_REF_TABLE
+ {
+ Text [ en-US ] = "#REF!" ;
+ };
+ String STR_PIVOT_INVALID_DBAREA
+ {
+ Text [ en-US ] = "The data range must contain at least one row." ;
+ };
+ String STR_PIVOT_NODATA
+ {
+ Text [ en-US ] = "The DataPilot table must contain at least one entry." ;
+ };
+ String STR_PIVOT_MOVENOTALLOWED
+ {
+ Text [ en-US ] = "The data range can not be deleted." ;
+ };
+ String STR_PIVOT_ERROR
+ {
+ Text [ en-US ] = "Error creating the Data Pilot Table." ;
+ };
+ String STR_PIVOT_OVERLAP
+ {
+ Text [ en-US ] = "DataPilot tables can not overlap." ;
+ };
+ String STR_PIVOT_NOTEMPTY
+ {
+ Text [ en-US ] = "The destination range is not empty. Overwrite existing contents?" ;
+ };
+ String STR_DATAPILOT_SUBTOTAL
+ {
+ Text [ en-US ] = "The source range contains subtotals which may distort the results. Use it anyway?";
+ };
+ String STR_PIVOT_PROGRESS
+ {
+ Text [ en-US ] = "Create DataPilot Table" ;
+ };
+ String STR_PIVOT_TOTAL
+ {
+ Text [ en-US ] = "Total" ;
+ };
+ String STR_PIVOT_DATA
+ {
+ Text [ en-US ] = "Data" ;
+ };
+ String STR_PIVOTFUNC_SUM
+ {
+ Text [ en-US ] = "SUM" ;
+ };
+ String STR_PIVOTFUNC_COUNT
+ {
+ Text [ en-US ] = "COUNT" ;
+ };
+ String STR_PIVOTFUNC_AVG
+ {
+ Text [ en-US ] = "AVERAGE" ;
+ };
+ String STR_PIVOTFUNC_MAX
+ {
+ Text [ en-US ] = "MAX" ;
+ };
+ String STR_PIVOTFUNC_MIN
+ {
+ Text [ en-US ] = "MIN" ;
+ };
+ String STR_PIVOTFUNC_PROD
+ {
+ Text [ en-US ] = "PRODUCT" ;
+ };
+ String STR_PIVOTFUNC_COUNT2
+ {
+ Text [ en-US ] = "COUNTA" ;
+ };
+ String STR_PIVOTFUNC_STDDEV
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String STR_PIVOTFUNC_STDDEV2
+ {
+ Text [ en-US ] = "STDEVP" ;
+ };
+ String STR_PIVOTFUNC_VAR
+ {
+ Text [ en-US ] = "VAR" ;
+ };
+ String STR_PIVOTFUNC_VAR2
+ {
+ Text [ en-US ] = "VARP" ;
+ };
+ String STR_TABLE
+ {
+ Text [ en-US ] = "Sheet" ;
+ };
+ String STR_COLUMN
+ {
+ Text [ en-US ] = "Column" ;
+ };
+ String STR_ROW
+ {
+ Text [ en-US ] = "Row" ;
+ };
+ String STR_PAGE
+ {
+ Text [ en-US ] = "Page" ;
+ };
+ String STR_LOAD_DOC
+ {
+ Text [ en-US ] = "Load document" ;
+ };
+ String STR_SAVE_DOC
+ {
+ Text [ en-US ] = "Save document" ;
+ };
+ String STR_ERR_INVALID_TABREF
+ {
+ Text [ en-US ] = "<unknown table reference>" ;
+ };
+ String STR_AREA_ALREADY_INSERTED
+ {
+ Text [ en-US ] = "This range has already been inserted." ;
+ };
+ String STR_INVALID_TABREF
+ {
+ Text [ en-US ] = "Invalid sheet reference." ;
+ };
+ String STR_INVALID_QUERYAREA
+ {
+ Text [ en-US ] = "This range does not contain a valid query." ;
+ };
+ String STR_REIMPORT_EMPTY
+ {
+ Text [ en-US ] = "This range does not contain imported data." ;
+ };
+ String STR_NOMULTISELECT
+ {
+ Text [ en-US ] = "This function cannot be used with multiple selections." ;
+ };
+ String STR_FILL_SERIES_PROGRESS
+ {
+ Text [ en-US ] = "Fill Row..." ;
+ };
+ String STR_UNKNOWN_FILTER
+ {
+ Text [ en-US ] = "Unknown filter: " ;
+ };
+ String STR_UNDO_THESAURUS
+ {
+ Text [ en-US ] = "Thesaurus" ;
+ };
+ String STR_FILL_TAB
+ {
+ Text [ en-US ] = "Fill Sheets" ;
+ };
+ String STR_UPDATE_SCENARIO
+ {
+ Text [ en-US ] = "Add selected ranges to current scenario?" ;
+ };
+ String STR_ERR_NEWSCENARIO
+ {
+ Text [ en-US ] = "The scenario ranges must be selected in order to be able to create a new scenario." ;
+ };
+ String STR_NOAREASELECTED
+ {
+ Text [ en-US ] = "A range has not been selected." ;
+ };
+ String STR_NEWTABNAMENOTUNIQUE
+ {
+ Text [ en-US ] = "This name already exists." ;
+ };
+ String STR_INVALIDTABNAME
+ {
+ Text [ en-US ] = "Invalid sheet name." ;
+ };
+ String STR_SCENARIO
+ {
+ Text [ en-US ] = "Scenario" ;
+ };
+ String STR_PIVOT_TABLE
+ {
+ Text [ en-US ] = "DataPilot" ;
+ };
+ // Text strings for captions of subtotal functions.
+ String STR_FUN_TEXT_SUM
+ {
+ Text [ en-US ] = "Sum" ;
+ };
+ String STR_FUN_TEXT_COUNT
+ {
+ Text [ en-US ] = "Count" ;
+ };
+ String STR_FUN_TEXT_COUNT2
+ {
+ Text [ en-US ] = "CountA" ;
+ };
+ String STR_FUN_TEXT_AVG
+ {
+ Text [ en-US ] = "Average" ;
+ };
+ String STR_FUN_TEXT_MAX
+ {
+ Text [ en-US ] = "Max" ;
+ };
+ String STR_FUN_TEXT_MIN
+ {
+ Text [ en-US ] = "Min" ;
+ };
+ String STR_FUN_TEXT_PRODUCT
+ {
+ Text [ en-US ] = "Product" ;
+ };
+ String STR_FUN_TEXT_STDDEV
+ {
+ Text [ en-US ] = "StDev" ;
+ };
+ String STR_FUN_TEXT_VAR
+ {
+ Text [ en-US ] = "Var" ;
+ };
+ String STR_NOCHARTATCURSOR
+ {
+ Text [ en-US ] = "No chart found at this position." ;
+ };
+ String STR_PIVOT_NOTFOUND
+ {
+ Text [ en-US ] = "No DataPilot table found at this position." ;
+ };
+ String STR_EMPTYDATA
+ {
+ Text [ en-US ] = "(empty)" ;
+ };
+ String STR_PRINT_INVALID_AREA
+ {
+ Text [ en-US ] = "Invalid print range" ;
+ };
+ String STR_PAGESTYLE
+ {
+ Text [ en-US ] = "Page Style" ;
+ };
+ String STR_HEADER
+ {
+ Text [ en-US ] = "Header" ;
+ };
+ String STR_FOOTER
+ {
+ Text [ en-US ] = "Footer" ;
+ };
+ String STR_TEXTATTRS
+ {
+ Text [ en-US ] = "Text Attributes" ;
+ };
+ String STR_HFCMD_DELIMITER
+ {
+ Text [ en-US ] = "\\" ;
+ };
+ String STR_HFCMD_PAGE
+ {
+ Text [ en-US ] = "PAGE" ;
+ };
+ String STR_HFCMD_PAGES
+ {
+ Text [ en-US ] = "PAGES" ;
+ };
+ String STR_HFCMD_DATE
+ {
+ Text [ en-US ] = "DATE" ;
+ };
+ String STR_HFCMD_TIME
+ {
+ Text [ en-US ] = "TIME" ;
+ };
+ String STR_HFCMD_FILE
+ {
+ Text [ en-US ] = "FILE" ;
+ };
+ String STR_HFCMD_TABLE
+ {
+ Text [ en-US ] = "SHEET" ;
+ };
+ String STR_PROTECTIONERR
+ {
+ Text [ en-US ] = "Protected cells can not be modified." ;
+ };
+ String STR_READONLYERR
+ {
+ Text [ en-US ] = "Document opened in read-only mode.";
+ };
+ String STR_MATRIXFRAGMENTERR
+ {
+ Text [ en-US ] = "You cannot change only part of an array." ;
+ };
+ String STR_PAGEHEADER
+ {
+ Text [ en-US ] = "Header" ;
+ };
+ String STR_PAGEFOOTER
+ {
+ Text [ en-US ] = "Footer" ;
+ };
+
+ /* BEGIN error constants and error strings. */
+
+ String STR_ERROR_STR
+ {
+ Text [ en-US ] = "Err:" ;
+ };
+ /* BEGIN defined ERROR.TYPE() values. */
+ /* ERROR.TYPE( #NULL! ) == 1 */
+ String STR_LONG_ERR_NULL
+ {
+ Text [ en-US ] = "Error: Ranges do not intersect" ;
+ };
+ /* ERROR.TYPE( #DIV/0! ) == 2 */
+ String STR_LONG_ERR_DIV_ZERO
+ {
+ Text [ en-US ] = "Error: Division by zero" ;
+ };
+ /* ERROR.TYPE( #VALUE! ) == 3 */
+ String STR_LONG_ERR_NO_VALUE
+ {
+ Text [ en-US ] = "Error: Wrong data type" ;
+ };
+ /* ERROR.TYPE( #REF! ) == 4 */
+ String STR_LONG_ERR_NO_REF
+ {
+ Text [ en-US ] = "Error: Not a valid reference" ;
+ };
+ /* ERROR.TYPE( #NAME! ) == 5 */
+ String STR_LONG_ERR_NO_NAME
+ {
+ Text [ en-US ] = "Error: Invalid name" ;
+ };
+ /* ERROR.TYPE( #NUM! ) == 6 */
+ String STR_LONG_ERR_ILL_FPO
+ {
+ Text [ en-US ] = "Error: Invalid numeric value" ;
+ };
+ /* ERROR.TYPE( #N/A ) == 7 */
+ String STR_LONG_ERR_NV
+ {
+ Text [ en-US ] = "Error: Value not available" ;
+ };
+ /* END defined ERROR.TYPE() values. */
+ String STR_NO_ADDIN
+ {
+ Text [ en-US ] = "#ADDIN?" ;
+ };
+ String STR_LONG_ERR_NO_ADDIN
+ {
+ Text [ en-US ] = "Error: Add-in not found" ;
+ };
+ String STR_NO_MACRO
+ {
+ Text [ en-US ] = "#MACRO?" ;
+ };
+ String STR_LONG_ERR_NO_MACRO
+ {
+ Text [ en-US ] = "Error: Macro not found" ;
+ };
+ String STR_LONG_ERR_SYNTAX
+ {
+ Text [ en-US ] = "Internal syntactical error" ;
+ };
+ String STR_LONG_ERR_ILL_ARG
+ {
+ Text [ en-US ] = "Error: Invalid argument" ;
+ };
+ String STR_LONG_ERR_ILL_PAR
+ {
+ Text [ en-US ] = "Error in parameter list" ;
+ };
+ String STR_LONG_ERR_ILL_CHAR
+ {
+ Text [ en-US ] = "Error: Invalid character" ;
+ };
+ String STR_LONG_ERR_ILL_SEP
+ {
+ Text [ en-US ] = "Error: Invalid semicolon" ;
+ };
+ String STR_LONG_ERR_PAIR
+ {
+ Text [ en-US ] = "Error: in bracketing" ;
+ };
+ String STR_LONG_ERR_OP_EXP
+ {
+ Text [ en-US ] = "Error: Operator missing" ;
+ };
+ String STR_LONG_ERR_VAR_EXP
+ {
+ Text [ en-US ] = "Error: Variable missing" ;
+ };
+ String STR_LONG_ERR_CODE_OVF
+ {
+ Text [ en-US ] = "Error: Formula overflow" ;
+ };
+ String STR_LONG_ERR_STR_OVF
+ {
+ Text [ en-US ] = "Error: String overflow" ;
+ };
+ String STR_LONG_ERR_STACK_OVF
+ {
+ Text [ en-US ] = "Error: Internal overflow" ;
+ };
+ String STR_LONG_ERR_CIRC_REF
+ {
+ Text [ en-US ] = "Error: Circular reference" ;
+ };
+ String STR_LONG_ERR_NO_CONV
+ {
+ Text [ en-US ] = "Error: Calculation does not converge" ;
+ };
+
+ /* END error constants and error strings. */
+
+ String STR_GRIDCOLOR
+ {
+ Text [ en-US ] = "Grid color" ;
+ };
+ String STR_MERGE_NOTEMPTY
+ {
+ Text [ en-US ] = "Should the contents of the hidden cells be moved into the first cell?" ;
+ };
+ String STR_CELL_FILTER
+ {
+ Text [ en-US ] = "Filter" ;
+ };
+ String STR_TARGETNOTFOUND
+ {
+ Text [ en-US ] = "The target database range does not exist." ;
+ };
+ String STR_INVALID_EPS
+ {
+ Text [ en-US ] = "Invalid increment" ;
+ };
+ String STR_TABLE_OP
+ {
+ Text [ en-US ] = "MULTIPLE.OPERATIONS" ;
+ };
+ String STR_UNDO_TABOP
+ {
+ Text [ en-US ] = "Multiple operations" ;
+ };
+ String STR_INVALID_AFNAME
+ {
+ Text [ en-US ] = "You have entered an invalid name.\nAutoFormat could not be created. \nTry again using a different name." ;
+ };
+ String STR_AREA
+ {
+ Text [ en-US ] = "Range" ;
+ };
+ String STR_YES
+ {
+ Text [ en-US ] = "Yes" ;
+ };
+ String STR_NO
+ {
+ Text [ en-US ] = "No" ;
+ };
+ String STR_PROTECTION
+ {
+ Text [ en-US ] = "Protection" ;
+ };
+ String STR_FORMULAS
+ {
+ Text [ en-US ] = "Formulas" ;
+ };
+ String STR_HIDE
+ {
+ Text [ en-US ] = "Hide" ;
+ };
+ String STR_PRINT
+ {
+ Text [ en-US ] = "Print" ;
+ };
+ String STR_INVALID_AFAREA
+ {
+ Text [ en-US ] = "To apply an AutoFormat,\na table range of at least\n3x3 cells must be selected." ;
+ };
+ String STR_CASCADE
+ {
+ Text [ en-US ] = "(nested)" ;
+ };
+ String STR_OPTIONAL
+ {
+ Text [ en-US ] = "(optional)" ;
+ };
+ String STR_REQUIRED
+ {
+ Text [ en-US ] = "(required)" ;
+ };
+ String STR_INVALID
+ {
+ Text [ en-US ] = "invalid" ;
+ };
+ String STR_EDITFUNCTION
+ {
+ Text [ en-US ] = "Edit Function" ;
+ };
+ String STR_NOTES
+ {
+ Text [ en-US ] = "Comments" ;
+ };
+ String STR_QUERY_DELTAB
+ {
+ Text [ en-US ] = "Are you sure you want to delete the selected sheet(s)?" ;
+ };
+ String STR_QUERY_DELSCENARIO
+ {
+ Text [ en-US ] = "Are you sure you want to delete the selected scenario?" ;
+ };
+ String STR_EXPORT_ASCII_WARNING
+ {
+ Text [ en-US ] = "Thesaurus is not available" ;
+ };
+ String STR_IMPORT_ERROR
+ {
+ Text [ en-US ] = "Spellcheck not available" ;
+ };
+ String STR_IMPORT_ASCII
+ {
+ Text [ en-US ] = "Import text files" ;
+ };
+ String STR_EXPORT_ASCII
+ {
+ Text [ en-US ] = "Export of text files" ;
+ };
+ String STR_IMPORT_LOTUS
+ {
+ Text [ en-US ] = "Import Lotus files" ;
+ };
+ String STR_IMPORT_DBF
+ {
+ Text [ en-US ] = "Import DBase files" ;
+ };
+ String STR_EXPORT_DBF
+ {
+ Text [ en-US ] = "DBase export";
+ };
+ String STR_EXPORT_DIF
+ {
+ Text [ en-US ] = "Dif Export" ;
+ };
+ String STR_IMPORT_DIF
+ {
+ Text [ en-US ] = "Dif Import" ;
+ };
+ String STR_STYLENAME_STANDARD
+ {
+ Text [ en-US ] = "Default" ;
+ };
+ String STR_STYLENAME_RESULT
+ {
+ Text [ en-US ] = "Result" ;
+ };
+ String STR_STYLENAME_RESULT1
+ {
+ Text [ en-US ] = "Result2" ;
+ };
+ String STR_STYLENAME_HEADLINE
+ {
+ Text [ en-US ] = "Heading" ;
+ };
+ String STR_STYLENAME_HEADLINE1
+ {
+ Text [ en-US ] = "Heading1" ;
+ };
+ String STR_STYLENAME_REPORT
+ {
+ Text [ en-US ] = "Report" ;
+ };
+ String STR_STYLENAME_REPORT1
+ {
+ Text [ en-US ] = "Report1" ;
+ };
+ String STR_IMPORT_EXCEL_WARNING
+ {
+ Text [ en-US ] = "is not available for spellchecking\nPlease check your installation and install \nthe desired language if necessary" ;
+ };
+ String STR_THESAURUS_NO_STRING
+ {
+ Text [ en-US ] = "Thesaurus can only be used in text cells!" ;
+ };
+ String STR_SPELLING_BEGIN_TAB
+ {
+ Text [ en-US ] = "Should the spellcheck be continued at the beginning of the current sheet?" ;
+ };
+ String STR_SPELLING_NO_LANG
+ {
+ Text [ en-US ] = "is not available for the thesaurus.\nPlease check your installation and install \nthe desired language if necessary" ;
+ };
+ String STR_SPELLING_STOP_OK
+ {
+ Text [ en-US ] = "The spellcheck of this sheet has been completed." ;
+ };
+ String STR_NOLANGERR
+ {
+ Text [ en-US ] = "No language set" ;
+ };
+ String STR_UNDO_INSERT_TAB
+ {
+ Text [ en-US ] = "Insert Sheet" ;
+ };
+ String STR_UNDO_DELETE_TAB
+ {
+ Text [ en-US ] = "Delete Sheets" ;
+ };
+ String STR_UNDO_RENAME_TAB
+ {
+ Text [ en-US ] = "Rename Sheet" ;
+ };
+ String STR_UNDO_SET_TAB_BG_COLOR
+ {
+ Text [ en-US ] = "Color Tab" ;
+ };
+ String STR_UNDO_SET_MULTI_TAB_BG_COLOR
+ {
+ Text [ en-US ] = "Color Tabs" ;
+ };
+ String STR_UNDO_MOVE_TAB
+ {
+ Text [ en-US ] = "Move Sheets" ;
+ };
+ String STR_UNDO_COPY_TAB
+ {
+ Text [ en-US ] = "Copy Sheet" ;
+ };
+ String STR_UNDO_APPEND_TAB
+ {
+ Text [ en-US ] = "Append sheet" ;
+ };
+ String STR_UNDO_SHOWTAB
+ {
+ Text [ en-US ] = "Show Sheet" ;
+ };
+ String STR_UNDO_HIDETAB
+ {
+ Text [ en-US ] = "Hide sheet" ;
+ };
+ String STR_UNDO_TAB_RTL
+ {
+ Text [ en-US ] = "Flip sheet" ;
+ };
+ String STR_UNDO_TAB_R1C1
+ {
+ Text [ en-US ] = "Toggle the use of R1C1 notation" ;
+ };
+ String STR_CHART_MAINTITLE
+ {
+ Text [ en-US ] = "Main Title" ;
+ };
+ String STR_CHART_SUBTITLE
+ {
+ Text [ en-US ] = "Subtitle" ;
+ };
+ String STR_CHART_XTITLE
+ {
+ Text [ en-US ] = "X axis title" ;
+ };
+ String STR_CHART_YTITLE
+ {
+ Text [ en-US ] = "Y axis title" ;
+ };
+ String STR_CHART_ZTITLE
+ {
+ Text [ en-US ] = "Z axis title" ;
+ };
+ String STR_ABSREFLOST
+ {
+ Text [ en-US ] = "The new table contains absolute references to other tables which may be incorrect!" ;
+ };
+ String STR_NAMECONFLICT
+ {
+ Text [ en-US ] = "Due to identical names, an existing range name in the destination document has been altered!" ;
+ };
+ String STR_ERR_AUTOFILTER
+ {
+ Text [ en-US ] = "AutoFilter not possible" ;
+ };
+ String STR_MSSG_SEARCHANDREPLACE_1
+ {
+ Text [ en-US ] = "%PRODUCTNAME Calc has searched to the beginning of the sheet. Do you want to continue at the end?" ;
+ };
+ String STR_MSSG_SEARCHANDREPLACE_2
+ {
+ Text [ en-US ] = "%PRODUCTNAME Calc has searched to the end of the sheet. Do you want to continue at the beginning?" ;
+ };
+ String STR_MSSG_SEARCHANDREPLACE_3
+ {
+ Text [ en-US ] = "Find & Replace" ;
+ };
+ String STR_MSSG_SEARCHANDREPLACE_4
+ {
+ Text [ en-US ] = "%PRODUCTNAME Calc has searched to the beginning of the document. Do you want to continue at the end?" ;
+ };
+ String STR_MSSG_SEARCHANDREPLACE_5
+ {
+ Text [ en-US ] = "%PRODUCTNAME Calc has searched to the end of the document. Do you want to continue at the beginning?" ;
+ };
+ String STR_CREATENAME_REPLACE
+ {
+ Text [ en-US ] = "Replace existing definition of #?" ;
+ };
+ String STR_CREATENAME_MARKERR
+ {
+ Text [ en-US ] = "Invalid selection for range names" ;
+ };
+ String STR_CONSOLIDATE_ERR1
+ {
+ Text [ en-US ] = "References can not be inserted above the source data." ;
+ };
+ String STR_SCENARIO_NOTFOUND
+ {
+ Text [ en-US ] = "Scenario not found" ;
+ };
+ String STR_QUERY_DELENTRY
+ {
+ Text [ en-US ] = "Do you really want to delete the entry #?" ;
+ };
+ String STR_VOBJ_OBJECT
+ {
+ Text [ en-US ] = "Objects/graphics" ;
+ };
+ String STR_VOBJ_CHART
+ {
+ Text [ en-US ] = "Charts" ;
+ };
+ String STR_VOBJ_DRAWINGS
+ {
+ Text [ en-US ] = "Drawing Objects" ;
+ };
+ String STR_VOBJ_MODE_SHOW
+ {
+ Text [ en-US ] = "Show" ;
+ };
+ String STR_VOBJ_MODE_HIDE
+ {
+ Text [ en-US ] = "Hide" ;
+ };
+ String STR_SCATTR_PAGE_TOPDOWN
+ {
+ Text [ en-US ] = "Top to bottom" ;
+ };
+ String STR_SCATTR_PAGE_LEFTRIGHT
+ {
+ Text [ en-US ] = "Left-to-right" ;
+ };
+ String STR_SCATTR_PAGE_NOTES
+ {
+ Text [ en-US ] = "Comments" ;
+ };
+ String STR_SCATTR_PAGE_GRID
+ {
+ Text [ en-US ] = "Grid" ;
+ };
+ String STR_SCATTR_PAGE_HEADERS
+ {
+ Text [ en-US ] = "Row & Column Headers" ;
+ };
+ String STR_SCATTR_PAGE_FORMULAS
+ {
+ Text [ en-US ] = "Formulas" ;
+ };
+ String STR_SCATTR_PAGE_NULLVALS
+ {
+ Text [ en-US ] = "Zero Values" ;
+ };
+ String STR_SCATTR_PAGE_PRINTDIR
+ {
+ Text [ en-US ] = "Print direction" ;
+ };
+ String STR_SCATTR_PAGE_FIRSTPAGENO
+ {
+ Text [ en-US ] = "First page number" ;
+ };
+ String STR_SCATTR_PAGE_SCALE
+ {
+ Text [ en-US ] = "Reduce/enlarge printout" ;
+ };
+ String STR_SCATTR_PAGE_SCALETOPAGES
+ {
+ Text [ en-US ] = "Fit print range(s) on number of pages" ;
+ };
+ String STR_SCATTR_PAGE_SCALETO
+ {
+ Text [ en-US ] = "Fit print range(s) to width/height" ;
+ };
+ String STR_SCATTR_PAGE_SCALE_WIDTH
+ {
+ Text [ en-US ] = "Width" ;
+ };
+ String STR_SCATTR_PAGE_SCALE_HEIGHT
+ {
+ Text [ en-US ] = "Height" ;
+ };
+ String STR_SCATTR_PAGE_SCALE_PAGES
+ {
+ Text [ en-US ] = "%1 page(s)" ;
+ };
+ String STR_SCATTR_PAGE_SCALE_AUTO
+ {
+ Text [ en-US ] = "automatic" ;
+ };
+ String STR_DOC_STAT
+ {
+ Text [ en-US ] = "Statistics" ;
+ };
+ String STR_LINKERROR
+ {
+ Text [ en-US ] = "The link could not be updated." ;
+ };
+ String STR_LINKERRORFILE
+ {
+ Text [ en-US ] = "File:" ;
+ };
+ String STR_LINKERRORTAB
+ {
+ Text [ en-US ] = "Sheet:" ;
+ };
+ String STR_OVERVIEW
+ {
+ Text [ en-US ] = "Overview" ;
+ };
+ String STR_DOC_INFO
+ {
+ Text [ en-US ] = "Doc.Information" ;
+ };
+ String STR_DOC_CREATED
+ {
+ Text [ en-US ] = "Created" ;
+ };
+ String STR_DOC_MODIFIED
+ {
+ Text [ en-US ] = "Modified" ;
+ };
+ String STR_DOC_PRINTED
+ {
+ Text [ en-US ] = "Printed" ;
+ };
+ String STR_DOC_THEME
+ {
+ Text [ en-US ] = "Subject" ;
+ };
+ String STR_DOC_KEYWORDS
+ {
+ Text [ en-US ] = "Key words" ;
+ };
+ String STR_DOC_COMMENT
+ {
+ Text [ en-US ] = "Comments" ;
+ };
+ String STR_BY
+ {
+ Text [ en-US ] = "by" ;
+ };
+ String STR_ON
+ {
+ Text [ en-US ] = "on" ;
+ };
+ String STR_RELOAD_TABLES
+ {
+ Text [ en-US ] = "This file contains links to other files.\nShould they be updated?" ;
+ };
+ String STR_REIMPORT_AFTER_LOAD
+ {
+ Text [ en-US ] = "This file contains queries. The results of these queries were not saved.\nDo you want these queries to be repeated?" ;
+ };
+ String STR_FILTER_TOOMANY
+ {
+ Text [ en-US ] = "Too many conditions" ;
+ };
+ String STR_INSERT_FULL
+ {
+ Text [ en-US ] = "Filled cells cannot be shifted\nbeyond the sheet." ;
+ };
+ String STR_TABINSERT_ERROR
+ {
+ Text [ en-US ] = "The table could not be inserted." ;
+ };
+ String STR_TABREMOVE_ERROR
+ {
+ Text [ en-US ] = "The sheets could not be deleted." ;
+ };
+ String STR_PASTE_ERROR
+ {
+ Text [ en-US ] = "The contents of the clipboard could not be pasted." ;
+ };
+ String STR_PASTE_FULL
+ {
+ Text [ en-US ] = "There is not enough space on the sheet to insert here." ;
+ };
+ String STR_PASTE_BIGGER
+ {
+ Text [ en-US ] = "The content of the clipboard is bigger than the range selected.\nDo you want to insert it anyway?";
+ };
+ String STR_ERR_NOREF
+ {
+ Text [ en-US ] = "No references found." ;
+ };
+ String STR_ERR_LINKOVERLAP
+ {
+ Text [ en-US ] = "Source and destination must not overlap." ;
+ };
+ String STR_GRAPHICNAME
+ {
+ Text [ en-US ] = "Graphics" ;
+ };
+ String STR_INVALIDNAME
+ {
+ Text [ en-US ] = "Invalid name." ;
+ };
+ String STR_VALID_MACRONOTFOUND
+ {
+ Text [ en-US ] = "Selected macro not found." ;
+ };
+ String STR_VALID_DEFERROR
+ {
+ Text [ en-US ] = "Invalid value." ;
+ };
+ String STR_PROGRESS_CALCULATING
+ {
+ Text [ en-US ] = "calculating" ;
+ };
+ String STR_PROGRESS_SORTING
+ {
+ Text [ en-US ] = "sorting" ;
+ };
+ String STR_PROGRESS_HEIGHTING
+ {
+ Text [ en-US ] = "Adapt row height" ;
+ };
+ String STR_PROGRESS_COMPARING
+ {
+ Text [ en-US ] = "Compare #" ;
+ };
+ String STR_DETINVALID_OVERFLOW
+ {
+ Text [ en-US ] = "The maximum number of invalid cells has been exceeded.\nNot all invalid cells have been marked." ;
+ };
+ String STR_QUICKHELP_DELETE
+ {
+ Text [ en-US ] = "Delete contents" ;
+ };
+ String STR_QUICKHELP_REF
+ {
+ Text [ en-US ] = "%1 R x %2 C" ;
+ };
+ String STR_FUNCTIONLIST_MORE
+ {
+ Text [ en-US ] = "More..." ;
+ };
+ String STR_ERR_INVALID_AREA
+ {
+ Text [ en-US ] = "Invalid range" ;
+ };
+ // Templates for data pilot tables.
+ String STR_PIVOT_STYLE_INNER
+ {
+ Text [ en-US ] = "DataPilot Value" ;
+ };
+ String STR_PIVOT_STYLE_RESULT
+ {
+ Text [ en-US ] = "DataPilot Result" ;
+ };
+ String STR_PIVOT_STYLE_CATEGORY
+ {
+ Text [ en-US ] = "DataPilot Category" ;
+ };
+ String STR_PIVOT_STYLE_TITLE
+ {
+ Text [ en-US ] = "DataPilot Title" ;
+ };
+ String STR_PIVOT_STYLE_FIELDNAME
+ {
+ Text [ en-US ] = "DataPilot Field" ;
+ };
+ String STR_PIVOT_STYLE_TOP
+ {
+ Text [ en-US ] = "DataPilot Corner" ;
+ };
+ String STR_OPERATION_FILTER
+ {
+ Text [ en-US ] = "Filter" ;
+ };
+ String STR_OPERATION_SORT
+ {
+ Text [ en-US ] = "Sort" ;
+ };
+ String STR_OPERATION_SUBTOTAL
+ {
+ Text [ en-US ] = "Subtotals" ;
+ };
+ String STR_OPERATION_NONE
+ {
+ Text [ en-US ] = "None" ;
+ };
+ String STR_IMPORT_REPLACE
+ {
+ Text [ en-US ] = "Do you want to replace the contents of #?" ;
+ };
+ String STR_TIP_WIDTH
+ {
+ Text [ en-US ] = "Width:" ;
+ };
+ String STR_TIP_HEIGHT
+ {
+ Text [ en-US ] = "Height:" ;
+ };
+ String STR_TIP_HIDE
+ {
+ Text [ en-US ] = "Hide" ;
+ };
+ String STR_ERR_INSERTOBJ
+ {
+ Text [ en-US ] = "The object could not be inserted." ;
+ };
+ String STR_CHANGED_BLANK
+ {
+ Text [ en-US ] = "<empty>" ;
+ };
+ String STR_CHANGED_CELL
+ {
+ Text [ en-US ] = "Cell #1 changed from '#2' to '#3'" ;
+ };
+ String STR_CHANGED_INSERT
+ {
+ Text [ en-US ] = "#1 inserted" ;
+ };
+ String STR_CHANGED_DELETE
+ {
+ Text [ en-US ] = "#1deleted" ;
+ };
+ String STR_CHANGED_MOVE
+ {
+ Text [ en-US ] = "Range moved from #1 to #2" ;
+ };
+ String STR_END_REDLINING_TITLE
+ {
+ Text [ en-US ] = "Exit Recording" ;
+ };
+ String STR_END_REDLINING
+ {
+ Text [ en-US ] = "This action will exit the change recording mode.\nAny information about changes will be lost.\n\nExit change recording mode?\n\n" ;
+ };
+ String STR_CLOSE_ERROR_LINK
+ {
+ Text [ en-US ] = "The document can not be closed while a link is being updated." ;
+ };
+ String STR_UNDO_RESIZEMATRIX
+ {
+ Text [ en-US ] = "Adapt array area";
+ };
+ String STR_TIP_RESIZEMATRIX
+ {
+ Text [ en-US ] = "Array formula %1 R x %2 C";
+ };
+ String STR_MACRO_WARNING
+ {
+ Text [ en-US ] = "This document contains macro function calls.\nDo you want to run them?";
+ };
+
+ String STR_UNDO_HANGULHANJA
+ {
+ Text [ en-US ] = "Hangul/Hanja Conversion";
+ };
+
+ String STR_NAME_INPUT_CELL
+ {
+ Text [ en-US ] = "Select Cell";
+ };
+ String STR_NAME_INPUT_RANGE
+ {
+ Text [ en-US ] = "Select Range";
+ };
+ String STR_NAME_INPUT_DBRANGE
+ {
+ Text [ en-US ] = "Select Database Range";
+ };
+ String STR_NAME_INPUT_ROW
+ {
+ Text [ en-US ] = "Go To Row";
+ };
+ String STR_NAME_INPUT_SHEET
+ {
+ Text [ en-US ] = "Go To Sheet";
+ };
+ String STR_NAME_INPUT_DEFINE
+ {
+ Text [ en-US ] = "Define Name for Range";
+ };
+ String STR_NAME_ERROR_SELECTION
+ {
+ Text [ en-US ] = "The selection needs to be rectangular in order to name it.";
+ };
+ String STR_NAME_ERROR_NAME
+ {
+ Text [ en-US ] = "You must enter a valid reference or type a valid name for the selected range.";
+ };
+
+ String STR_CHANGED_MOVE_REJECTION_WARNING
+ {
+ Text[ en-US ] = "WARNING: This action may have resulted in unintended changes to cell references in formulas.";
+ };
+
+ String STR_CHANGED_DELETE_REJECTION_WARNING
+ {
+ Text[ en-US ] = "WARNING: This action may have resulted in references to the deleted area not being restored.";
+ };
+
+ String STR_HF_NONE_IN_BRACKETS
+ {
+ Text [ en-US ] = "(none)";
+ };
+
+ String STR_HF_OF
+ {
+ Text [ en-US ] = "of";
+ };
+
+ String STR_HF_OF_QUESTION
+ {
+ Text [ en-US ] = "of ?";
+ };
+
+ String STR_HF_CREATED_BY
+ {
+ Text [ en-US ] = "Created by";
+ };
+
+ String STR_HF_CONFIDENTIAL
+ {
+ Text [ en-US ] = "Confidential";
+ };
+
+ String STR_HF_CUSTOMIZED
+ {
+ Text [ en-US ] = "Customized";
+ };
+
+ String STR_HF_CUSTOM_FOOTER
+ {
+ Text [ en-US ] = "Custom footer";
+ };
+
+ String STR_UNDO_CHINESE_TRANSLATION
+ {
+ Text [ en-US ] = "Chinese conversion";
+ };
+
+ String STR_ERR_DATAPILOT_INPUT
+ {
+ Text[ en-US ] = "You cannot change this part of the DataPilot table.";
+ };
+
+ String STR_RECALC_MANUAL
+ {
+ Text [ en-US ] = "Manual";
+ };
+ String STR_RECALC_AUTO
+ {
+ Text [ en-US ] = "Automatic";
+ };
+ String STR_ERR_LONG_NESTED_ARRAY
+ {
+ Text [ en-US ] = "Nested arrays are not supported." ;
+ };
+ String STR_UNDO_TEXTTOCOLUMNS
+ {
+ Text [ en-US ] = "Text to Columns";
+ };
+ String STR_DOC_UPDATED
+ {
+ Text [ en-US ] = "Your spreadsheet has been updated with changes saved by other users.";
+ };
+ String STR_DOC_WILLBESAVED
+ {
+ Text [ en-US ] = "The spreadsheet must be saved now to activate sharing mode.\n\nDo you want to continue?";
+ };
+ String STR_DOC_WILLNOTBESAVED
+ {
+ Text [ en-US ] = "Already resolved merge conflicts will be lost and your changes to the shared spreadsheet will not be saved.\n\nDo you want to continue?";
+ };
+ String STR_DOC_DISABLESHARED
+ {
+ Text [ en-US ] = "Disabling shared mode of a spreadsheet hinders all other users of the shared spreadsheet to merge back their work.\n\nDo you want to continue?";
+ };
+ String STR_DOC_NOLONGERSHARED
+ {
+ Text [ en-US ] = "This spreadsheet is no longer in shared mode.\n\nSave your spreadsheet to a separate file and merge your changes to the shared spreadsheet manually.";
+ };
+ String STR_SHARED_DOC_WARNING
+ {
+ Text [ en-US ] = "The spreadsheet is in shared mode. This allows multiple users to access and edit the spreadsheet at the same time.\n\nChanges to formatting attributes like fonts, colors, and number formats will not be saved and some functionalities like editing charts and drawing objects are not available in shared mode. Turn off shared mode to get exclusive access needed for those changes and functionalities.";
+ };
+ String STR_FILE_LOCKED_TRY_LATER
+ {
+ Text [ en-US ] = "The shared spreadsheet file is locked due to a merge in progress by user: '%1'\n\nSharing mode of a locked file cannot be disabled. Try again later.";
+ };
+ String STR_FILE_LOCKED_SAVE_LATER
+ {
+ Text [ en-US ] = "The shared spreadsheet file is locked due to a merge in progress by user: '%1'\n\nTry again later to save your changes.";
+ };
+ String STR_UNKNOWN_USER
+ {
+ Text [ en-US ] = "Unknown User";
+ };
+ String STR_STYLE_FAMILY_CELL
+ {
+ Text [ en-US ] = "Cell Styles";
+ };
+ String STR_STYLE_FAMILY_PAGE
+ {
+ Text [ en-US ] = "Page Styles";
+ };
+ String STR_ERR_DATAPILOTSOURCE
+ {
+ Text [ en-US ] = "DataPilot source data is invalid.";
+ };
+ String STR_PIVOT_FIRSTROWEMPTYERR
+ {
+ Text [ en-US ] = "The field name cannot be empty. Check the first row of data source to make sure there are no empty cells." ;
+ };
+ String STR_PIVOT_ONLYONEROWERR
+ {
+ Text [ en-US ] = "DataPilot table needs at least two rows of data to create or refresh." ;
+ };
+};
+
diff --git a/sc/source/ui/src/hdrcont.src b/sc/source/ui/src/hdrcont.src
new file mode 100644
index 000000000000..e4a82d38ec98
--- /dev/null
+++ b/sc/source/ui/src/hdrcont.src
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sc.hrc"
+
+
+
+#define PART1 \
+ MenuItem\
+ {\
+ Identifier = FID_CELL_FORMAT ; \
+ HelpId = FID_CELL_FORMAT ; \
+ Text [ en-US ] = "~Format Cells..." ; \
+ };
+
+
+#define PART2 \
+ MenuItem\
+ {\
+ Identifier = SID_CUT ; \
+ HelpId = SID_CUT ; \
+ Text [ en-US ] = "Cu~t" ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Die Selektion in die Zwischenablage kopieren und löschen : Die Selektion in die Zwischenablage kopieren und l÷schen */\
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_COPY ; \
+ HelpId = SID_COPY ; \
+ Text [ en-US ] = "~Copy" ; \
+ };\
+ MenuItem\
+ {\
+ Identifier = SID_PASTE ; \
+ HelpId = SID_PASTE ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Einfügen : Einf³gen */\
+ Text [ en-US ] = "~Paste" ; \
+ /* ### ACHTUNG: Neuer Text in Resource? Den Inhalt der Zwischenablage einfügen : Den Inhalt der Zwischenablage einf³gen */\
+ };
+
+ //-------------------------------------------------------------------------------
+
+Menu RID_POPUP_ROWHEADER
+{
+ ItemList =
+ {
+ PART1
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_ROW_HEIGHT ;
+ HelpId = FID_ROW_HEIGHT ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zeilenhöhe... : Zeilenh÷he... */
+ Text [ en-US ] = "Row Hei~ght..." ;
+ };
+ MenuItem
+ {
+ Identifier = FID_ROW_OPT_HEIGHT ;
+ HelpId = FID_ROW_OPT_HEIGHT ;
+ /* ### ACHTUNG: Neuer Text in Resource? Optimale Zeilenhöhe... : Optimale Zeilenh÷he... */
+ Text [ en-US ] = "Optimal ~Row Height..." ;
+ /* ### ACHTUNG: Neuer Text in Resource? Optimale Zeilenhöhe einstellen : Optimale Zeilenh÷he einstellen */
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_INS_ROW ;
+ HelpId = FID_INS_ROW ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zeilen einfügen : Zeilen einf³gen */
+ Text [ en-US ] = "~Insert Rows" ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ganze Zeilen einfügen : Ganze Zeilen einf³gen */
+ };
+ MenuItem
+ {
+ Identifier = SID_DEL_ROWS ;
+ HelpId = SID_DEL_ROWS ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zeilen löschen : Zeilen l÷schen */
+ Text [ en-US ] = "~Delete Rows" ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ganze Zeilen löschen : Ganze Zeilen l÷schen */
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE ;
+ HelpId = SID_DELETE ;
+ /* ### ACHTUNG: Neuer Text in Resource? Inhalte l~öschen... : Inhalte l~÷schen... */
+ Text [ en-US ] = "De~lete Contents..." ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ausgewählte Inhalte löschen (Formeln, Formate etc.) : Ausgewõhlte Inhalte l÷schen (Formeln, Formate etc.) */
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_ROW_HIDE ;
+ HelpId = FID_ROW_HIDE ;
+ Text [ en-US ] = "~Hide" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_ROW_SHOW ;
+ HelpId = FID_ROW_SHOW ;
+ Text [ en-US ] = "~Show" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ PART2
+ MenuItem
+ {
+ Identifier = SID_PASTE_SPECIAL ;
+ HelpId = SID_PASTE_SPECIAL ;
+ Text [ en-US ] = "P~aste Special..." ;
+ };
+ };
+};
+
+ //-------------------------------------------------------------------
+
+Menu RID_POPUP_COLHEADER
+{
+ ItemList =
+ {
+ PART1
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_COL_WIDTH ;
+ HelpId = FID_COL_WIDTH ;
+ Text [ en-US ] = "Col~umn Width..." ;
+ /* ### ACHTUNG: Neuer Text in Resource? Spaltenbreite ändern : Spaltenbreite õndern */
+ };
+ MenuItem
+ {
+ Identifier = FID_COL_OPT_WIDTH ;
+ HelpId = FID_COL_OPT_WIDTH ;
+ Text [ en-US ] = "O~ptimal Column Width..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_INS_COLUMN ;
+ HelpId = FID_INS_COLUMN ;
+ /* ### ACHTUNG: Neuer Text in Resource? Spalten einfügen : Spalten einf³gen */
+ Text [ en-US ] = "~Insert Columns" ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ganze Spalten einfügen : Ganze Spalten einf³gen */
+ };
+ MenuItem
+ {
+ Identifier = SID_DEL_COLS ;
+ HelpId = SID_DEL_COLS ;
+ /* ### ACHTUNG: Neuer Text in Resource? Spalten löschen : Spalten l÷schen */
+ Text [ en-US ] = "~Delete Columns" ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ganze Spalten löschen : Ganze Spalten l÷schen */
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE ;
+ HelpId = SID_DELETE ;
+ /* ### ACHTUNG: Neuer Text in Resource? Inhalte l~öschen... : Inhalte l~÷schen... */
+ Text [ en-US ] = "D~elete Contents..." ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ausgewählte Inhalte löschen (Formeln, Formate etc.) : Ausgewõhlte Inhalte l÷schen (Formeln, Formate etc.) */
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_COL_HIDE ;
+ HelpId = FID_COL_HIDE ;
+ Text [ en-US ] = "~Hide" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_COL_SHOW ;
+ HelpId = FID_COL_SHOW ;
+ Text [ en-US ] = "~Show" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ PART2
+ MenuItem
+ {
+ Identifier = SID_PASTE_SPECIAL ;
+ HelpId = SID_PASTE_SPECIAL ;
+ Text [ en-US ] = "Paste ~Special..." ;
+ };
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/makefile.mk b/sc/source/ui/src/makefile.mk
new file mode 100644
index 000000000000..96bb78e2902c
--- /dev/null
+++ b/sc/source/ui/src/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=ui
+
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ sc.src \
+ pseudo.src \
+ popup.src \
+ toolbox.src \
+ scstring.src \
+ attrdlg.src \
+ sortdlg.src \
+ filter.src \
+ namedlg.src \
+ dbnamdlg.src \
+ subtdlg.src \
+ miscdlgs.src \
+ autofmt.src \
+ solvrdlg.src \
+ optsolver.src \
+ solveroptions.src \
+ tabopdlg.src \
+ hdrcont.src \
+ globstr.src \
+ optdlg.src \
+ scerrors.src \
+ textdlgs.src \
+ scfuncs.src \
+ crnrdlg.src \
+ condfrmt.src \
+ opredlin.src \
+ simpref.src
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SRS)$/ui.srs: $(SOLARINCDIR)$/svx$/globlmn.hrc
+
diff --git a/sc/source/ui/src/miscdlgs.src b/sc/source/ui/src/miscdlgs.src
new file mode 100644
index 000000000000..6d4761c8589c
--- /dev/null
+++ b/sc/source/ui/src/miscdlgs.src
@@ -0,0 +1,1463 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "miscdlgs.hrc"
+
+ModalDialog RID_SCDLG_DELCELL
+{
+ OutputSize = TRUE ;
+ HelpId = FID_DELETE_CELL ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 191 , 70 ) ;
+ Text [ en-US ] = "Delete Cells" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 135 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 135 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 135 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DELCOLS
+ {
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Delete entire ~column(s)" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DELROWS
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Delete entire ~row(s)" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_CELLSLEFT
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Shift cells ~left" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_CELLSUP
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Shift cells ~up" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 123 , 8 ) ;
+ Text [ en-US ] = "Selection" ;
+ };
+};
+ModalDialog RID_SCDLG_INSCELL
+{
+ OutputSize = TRUE ;
+ HelpId = FID_INS_CELL ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 191 , 70 ) ;
+ Text [ en-US ] = "Insert Cells" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 135 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 135 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 135 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_INSCOLS
+ {
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Entire ~column" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_INSROWS
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Entire ro~w" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_CELLSRIGHT
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Shift cells ~right" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_CELLSDOWN
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "Shift cells ~down" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 123 , 8 ) ;
+ Text [ en-US ] = "Selection" ;
+ };
+};
+
+ModalDialog RID_SCDLG_DELCONT
+{
+ OutputSize = TRUE ;
+ HelpId = SID_DELETE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 161 , 130 ) ;
+ Text [ en-US ] = "Delete Contents" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 105 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 105 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 105 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELALL
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Delete ~all" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELSTRINGS
+ {
+ Pos = MAP_APPFONT ( 12 , 30 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Text" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELNUMBERS
+ {
+ Pos = MAP_APPFONT ( 12 , 44 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Numbers" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELDATETIME
+ {
+ Pos = MAP_APPFONT ( 12 , 58 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Date & time" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELFORMULAS
+ {
+ Pos = MAP_APPFONT ( 12 , 72 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Formulas" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELATTRS
+ {
+ Pos = MAP_APPFONT ( 12 , 100 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "For~mats" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELNOTES
+ {
+ Pos = MAP_APPFONT ( 12 , 86 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Comments" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_DELOBJECTS
+ {
+ Pos = MAP_APPFONT ( 12 , 114 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Objects" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ Text [ en-US ] = "Selection" ;
+ };
+};
+
+
+ModalDialog RID_SCDLG_INSCONT
+{
+ OutputSize = TRUE ;
+ HelpId = FID_INS_CELL_CONTENTS ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 187 ) ;
+ Text [ en-US ] = "Paste Special" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 204 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 204 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 204 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSALL
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Paste all" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSSTRINGS
+ {
+ Pos = MAP_APPFONT ( 12 , 30 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "Te~xt" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSNUMBERS
+ {
+ Pos = MAP_APPFONT ( 12 , 44 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Numbers" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSDATETIME
+ {
+ Pos = MAP_APPFONT ( 12 , 58 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Date & time" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSFORMULAS
+ {
+ Pos = MAP_APPFONT ( 12 , 72 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Formulas" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSATTRS
+ {
+ Pos = MAP_APPFONT ( 12 , 100 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "For~mats" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSOBJECTS
+ {
+ Pos = MAP_APPFONT ( 12 , 114 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Objects" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_INSNOTES
+ {
+ Pos = MAP_APPFONT ( 12 , 86 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Comments" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ Text [ en-US ] = "Selection" ;
+ };
+ RadioButton BTN_OP_NOOP
+ {
+ Pos = MAP_APPFONT ( 111 , 14 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Non~e" ;
+ };
+ RadioButton BTN_OP_ADD
+ {
+ Pos = MAP_APPFONT ( 111 , 30 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Add" ;
+ };
+ RadioButton BTN_OP_SUB
+ {
+ Pos = MAP_APPFONT ( 111 , 44 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Subtract" ;
+ };
+ RadioButton BTN_OP_MUL
+ {
+ Pos = MAP_APPFONT ( 111 , 58 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Multipl~y" ;
+ };
+ RadioButton BTN_OP_DIV
+ {
+ Pos = MAP_APPFONT ( 111 , 72 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Di~vide" ;
+ };
+ FixedLine FL_OPERATION
+ {
+ Pos = MAP_APPFONT ( 105 , 3 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ Text [ en-US ] = "Operations" ;
+ };
+ CheckBox BTN_SKIP_EMPTY
+ {
+ Pos = MAP_APPFONT ( 12 , 141 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "S~kip empty cells" ;
+ };
+ CheckBox BTN_TRANSPOSE
+ {
+ Pos = MAP_APPFONT ( 12 , 155 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Transpose" ;
+ };
+ CheckBox BTN_LINK
+ {
+ Pos = MAP_APPFONT ( 12 , 169 ) ;
+ Size = MAP_APPFONT ( 84 , 10 ) ;
+ Text [ en-US ] = "~Link" ;
+ };
+ FixedLine FL_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 130 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ Text [ en-US ] = "Options" ;
+ };
+ RadioButton BTN_MV_NONE
+ {
+ Pos = MAP_APPFONT ( 111 , 141 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Don't sh~ift" ;
+ };
+ RadioButton BTN_MV_DOWN
+ {
+ Pos = MAP_APPFONT ( 111 , 155 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "Do~wn" ;
+ };
+ RadioButton BTN_MV_RIGHT
+ {
+ Pos = MAP_APPFONT ( 111 , 169 ) ;
+ Size = MAP_APPFONT ( 83 , 10 ) ;
+ Text [ en-US ] = "~Right" ;
+ };
+ FixedLine FL_MOVE
+ {
+ Pos = MAP_APPFONT ( 105 , 130 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ Text [ en-US ] = "Shift cells" ;
+ };
+ FixedLine FL_SEP1
+ {
+ Pos = MAP_APPFONT( 102 , 14 ) ;
+ Size = MAP_APPFONT( 1 , 96 ) ;
+ };
+ FixedLine FL_SEP2
+ {
+ Pos = MAP_APPFONT( 102 , 127 ) ;
+ Size = MAP_APPFONT( 1 , 38 ) ;
+ };
+};
+ModalDialog RID_SCDLG_MOVETAB
+{
+ OutputSize = TRUE ;
+ HelpId = FID_TAB_MOVE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 168 , 130 ) ;
+ Text [ en-US ] = "Move/Copy Sheet" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 112 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 112 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 112 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_DEST
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 100 , 8 ) ;
+ Text [ en-US ] = "To ~document" ;
+ };
+ ListBox LB_DEST
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 17 ) ;
+ Size = MAP_APPFONT ( 100 , 60 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_INSERT
+ {
+ Pos = MAP_APPFONT ( 6 , 35 ) ;
+ Size = MAP_APPFONT ( 100 , 8 ) ;
+ Text [ en-US ] = "~Insert before" ;
+ };
+ ListBox LB_INSERT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 46 ) ;
+ Size = MAP_APPFONT ( 100 , 62 ) ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_COPY
+ {
+ Pos = MAP_APPFONT ( 6 , 114 ) ;
+ Size = MAP_APPFONT ( 100 , 10 ) ;
+ Text [ en-US ] = "~Copy" ;
+ TabStop = TRUE ;
+ };
+ String STR_NEWDOC
+ {
+ Text [ en-US ] = "- new document -" ;
+ };
+};
+ModalDialog RID_SCDLG_STRINPUT
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 178 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 122 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 122 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 122 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Edit ED_INPUT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 17 ) ;
+ Size = MAP_APPFONT ( 110 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 110 , 8 ) ;
+ };
+};
+ModalDialog RID_SCDLG_TAB_BG_COLOR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 118 , 167 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Control TAB_BG_COLOR_CT_BORDER
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 1 , 1 ) ; //12, 32
+ Size = MAP_APPFONT ( 116+2 , 145+2 ) ;
+ DialogControl = TRUE;
+ };
+ Control TAB_BG_COLOR_SET_BGDCOLOR
+ {
+ // * HelpId = HID_BACKGROUND_CTL_BGDCOLORSET ;
+ Hide = FALSE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 116 , 145 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 82 , 151 ) ;
+ Size = MAP_APPFONT ( 35 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = FALSE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 45 , 151 ) ;
+ Size = MAP_APPFONT ( 35 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 2 , 151 ) ;
+ Size = MAP_APPFONT ( 35 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = FALSE ;
+ };
+};
+/*
+ModalDialog RID_SCDLG_TAB_BG_COLOR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 180 , 150 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Control TAB_BG_COLOR_CT_BORDER
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 1 , 1 ) ; //12, 32
+ Size = MAP_APPFONT ( 116+2 , 145+2 ) ;
+ DialogControl = TRUE;
+ };
+ Control TAB_BG_COLOR_SET_BGDCOLOR
+ {
+ // * HelpId = HID_BACKGROUND_CTL_BGDCOLORSET ;
+ Hide = FALSE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 116 , 145 ) ;
+ TabStop = TRUE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 125 , 50 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 125 , 67 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = FALSE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 125 , 84 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = FALSE ;
+ };
+};
+*/
+/*
+ModalDialog RID_SCDLG_MTRINPUT
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 190 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 136 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 136 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 136 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ };
+ MetricField ED_VALUE
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ HelpId = HID_SC_MTRIN_VAL ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 6 ) ;
+ Size = MAP_APPFONT ( 60 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ };
+ CheckBox BTN_DEFVAL
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 24 ) ;
+ Size = MAP_APPFONT ( 58 , 10 ) ;
+ Text [ en-US ] = "~Default value" ;
+ };
+};
+*/
+
+ModalDialog RID_SCDLG_COL_MAN
+{
+ Text [ en-US ] = "Column Width" ;
+
+ HelpId = FID_COL_WIDTH ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 190 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 136 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 136 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 136 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "Width" ;
+ };
+ MetricField ED_VALUE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 6 ) ;
+ Size = MAP_APPFONT ( 70 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ };
+ CheckBox BTN_DEFVAL
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 24 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Default value" ;
+ };
+};
+
+ModalDialog RID_SCDLG_COL_OPT
+{
+ Text [ en-US ] = "Optimal Column Width" ;
+
+ HelpId = FID_COL_OPT_WIDTH ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 190 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 136 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 136 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 136 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "Add" ;
+ };
+ MetricField ED_VALUE
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 6 ) ;
+ Size = MAP_APPFONT ( 70 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ };
+ CheckBox BTN_DEFVAL
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 24 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Default value" ;
+ };
+};
+
+ModalDialog RID_SCDLG_ROW_MAN
+{
+ Text [ en-US ] = "Row Height" ;
+
+ HelpId = FID_ROW_HEIGHT ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 190 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 136 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 136 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 136 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "Height" ;
+ };
+ MetricField ED_VALUE
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 6 ) ;
+ Size = MAP_APPFONT ( 70 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ };
+ CheckBox BTN_DEFVAL
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 24 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Default value" ;
+ };
+};
+
+ModalDialog RID_SCDLG_ROW_OPT
+{
+ Text [ en-US ] = "Optimal Row Height" ;
+
+ HelpId = FID_ROW_OPT_HEIGHT ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 190 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 136 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 136 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 136 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "Add" ;
+ };
+ MetricField ED_VALUE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 6 ) ;
+ Size = MAP_APPFONT ( 70 , 12 ) ;
+ TabStop = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ };
+ CheckBox BTN_DEFVAL
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 24 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Default value" ;
+ };
+};
+
+
+ // RID_SCDLG_SELENTRY als Basis fuer RID_SCDLG_SELECTDB und RID_SCDLG_SHOW_TAB
+ // gibt es nicht mehr, weil die beiden jetzt unterschiedlich sind
+
+ModalDialog RID_SCDLG_SELECTDB
+{
+ HelpId = SID_SELECT_DB ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 168 , 100 ) ;
+ Text [ en-US ] = "Select" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 112 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 112 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 112 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_ENTRYLIST
+ {
+ // HelpID aus Zeiten, als noch abgeleitet wurde
+ HelpId = HID_SC_SELENTRY_LIST ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 91 , 80 ) ;
+ TabStop = TRUE ;
+ Sort = TRUE ;
+ };
+ FixedLine FL_ENTRYLIST
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 100 , 8 ) ;
+ };
+};
+
+ModalDialog RID_SCDLG_SHOW_TAB
+{
+ HelpId = FID_TABLE_SHOW ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 168 , 100 ) ;
+ Text [ en-US ] = "Show Sheet" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 112 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 112 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 112 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MultiListBox LB_ENTRYLIST
+ {
+ SimpleMode = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 19 ) ;
+ Size = MAP_APPFONT ( 100 , 75 ) ;
+ TabStop = TRUE ;
+ Sort = FALSE ;
+ };
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "Hidden sheets" ;
+ };
+};
+
+
+ModalDialog RID_SCDLG_FILLSERIES
+{
+ OutputSize = TRUE ;
+ HelpId = FID_FILL_SERIES ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 290 , 122 ) ;
+ Text [ en-US ] = "Fill Series" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ RadioButton BTN_DAY
+ {
+ Pos = MAP_APPFONT ( 159 , 14 ) ;
+ Size = MAP_APPFONT ( 66 , 10 ) ;
+ Text [ en-US ] = "Da~y" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DAY_OF_WEEK
+ {
+ Pos = MAP_APPFONT ( 159 , 28 ) ;
+ Size = MAP_APPFONT ( 66 , 10 ) ;
+ Text [ en-US ] = "~Weekday" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_MONTH
+ {
+ Pos = MAP_APPFONT ( 159 , 42 ) ;
+ Size = MAP_APPFONT ( 66 , 10 ) ;
+ Text [ en-US ] = "~Month" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_YEAR
+ {
+ Pos = MAP_APPFONT ( 159 , 56 ) ;
+ Size = MAP_APPFONT ( 66 , 10 ) ;
+ Text [ en-US ] = "Y~ear" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_TIME_UNIT
+ {
+ Pos = MAP_APPFONT ( 153 , 3 ) ;
+ Size = MAP_APPFONT ( 75 , 8 ) ;
+ Text [ en-US ] = "Time unit" ;
+ };
+ RadioButton BTN_RIGHT
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 51 , 10 ) ;
+ Text [ en-US ] = "~Right" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_LEFT
+ {
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 51 , 10 ) ;
+ Text [ en-US ] = "~Left" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_TOP
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 51 , 10 ) ;
+ Text [ en-US ] = "~Up" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_BOTTOM
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 51 , 10 ) ;
+ Text [ en-US ] = "~Down" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_DIRECTION
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Direction" ;
+ };
+ RadioButton BTN_ARITHMETIC
+ {
+ Pos = MAP_APPFONT ( 78 , 14 ) ;
+ Size = MAP_APPFONT ( 69 , 10 ) ;
+ Text [ en-US ] = "Li~near" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_GEOMETRIC
+ {
+ Pos = MAP_APPFONT ( 78 , 28 ) ;
+ Size = MAP_APPFONT ( 69 , 10 ) ;
+ Text [ en-US ] = "~Growth" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DATE
+ {
+ Pos = MAP_APPFONT ( 78 , 42 ) ;
+ Size = MAP_APPFONT ( 69 , 10 ) ;
+ Text [ en-US ] = "Da~te" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_AUTOFILL
+ {
+ Pos = MAP_APPFONT ( 78 , 56 ) ;
+ Size = MAP_APPFONT ( 69 , 10 ) ;
+ Text [ en-US ] = "~AutoFill" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_TYPE
+ {
+ Pos = MAP_APPFONT ( 72 , 3 ) ;
+ Size = MAP_APPFONT ( 75 , 8 ) ;
+ Text [ en-US ] = "Series type" ;
+ };
+ FixedLine FL_SEP1
+ {
+ Pos = MAP_APPFONT( 69 , 14 ) ;
+ Size = MAP_APPFONT ( 1 , 52 ) ;
+ };
+ FixedLine FL_SEP2
+ {
+ Pos = MAP_APPFONT( 150 , 14 ) ;
+ Size = MAP_APPFONT ( 1 , 52 ) ;
+ };
+ FixedText FT_START_VALUE
+ {
+ Pos = MAP_APPFONT ( 6 , 74 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "~Start value" ;
+ };
+ Edit ED_START_VALUES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 55 , 72 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_END_VALUE
+ {
+ Pos = MAP_APPFONT ( 6 , 90 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "End ~value" ;
+ };
+ Edit ED_END_VALUES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 55 , 88 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_INCREMENT
+ {
+ Pos = MAP_APPFONT ( 6 , 106 ) ;
+ Size = MAP_APPFONT ( 45 , 8 ) ;
+ Text [ en-US ] = "In~crement" ;
+ };
+ Edit ED_INCREMENT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 55 , 104 ) ;
+ Size = MAP_APPFONT ( 58 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ String STR_VALERR
+ {
+ Text [ en-US ] = "Invalid value" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 234 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 234 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 234 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
+
+#define TXT_COLS \
+ Text [ en-US ] = "~Columns" ; \
+
+
+#define TXT_ROWS \
+ Text [ en-US ] = "~Rows" ; \
+
+
+ModalDialog RID_SCDLG_GROUP
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 148 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 92 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 92 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 92 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_GROUP_ROWS
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ HelpId = HID_SC_GROUP_ROWS ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 71 , 10 ) ;
+ TXT_ROWS
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_GROUP_COLS
+ {
+ // HelpID, weil die generierten aus den Ableitungen nicht in die hid.lst kommen
+ HelpId = HID_SC_GROUP_COLS ;
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 71 , 10 ) ;
+ TXT_COLS
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 80 , 8 ) ;
+ Text = "Aktivieren für" ;
+ };
+ String STR_GROUP
+ {
+ Text [ en-US ] = "Include" ;
+ };
+ String STR_UNGROUP
+ {
+ Text [ en-US ] = "Deactivate for" ;
+ };
+ Text [ en-US ] = "Group" ;
+};
+
+ // Ableitungen
+ModalDialog RID_SCDLG_GRP_MAKE < RID_SCDLG_GROUP { HelpId = SID_OUTLINE_MAKE ; };
+ModalDialog RID_SCDLG_GRP_KILL < RID_SCDLG_GROUP { HelpId = SID_OUTLINE_REMOVE ; };
+
+ // RID_SCDLG_COLORROW wird nur in der Optionen-Sortierlisten-Seite benutzt
+
+ModalDialog RID_SCDLG_COLORROW
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 148 , 63 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 92 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 92 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 92 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_GROUP_ROWS
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 71 , 10 ) ;
+ TXT_ROWS
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_GROUP_COLS
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 71 , 10 ) ;
+ TXT_COLS
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 80 , 8 ) ;
+ };
+};
+
+ModalDialog RID_SCDLG_NAMES_CREATE
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ HelpID = FID_USE_NAME ;
+ Size = MAP_APPFONT ( 174 , 72 ) ;
+ Moveable = TRUE ;
+ CheckBox BTN_TOP
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 93 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Top row" ;
+ };
+ CheckBox BTN_LEFT
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 93 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Left column" ;
+ };
+ CheckBox BTN_BOTTOM
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 93 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Bottom row" ;
+ };
+ CheckBox BTN_RIGHT
+ {
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 93 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Right column" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 116 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 116 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 116 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_FRAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 104 , 8 ) ;
+ Text [ en-US ] = "Create names from" ;
+ };
+ Text [ en-US ] = "Create Names" ;
+};
+
+ModalDialog RID_SCDLG_NAMES_PASTE
+{
+ OutputSize = TRUE ;
+ HelpId = FID_INSERT_NAME ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 228 , 85 ) ;
+ Moveable = TRUE ;
+ FixedText FT_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 156 , 10 ) ;
+ Text [ en-US ] = "Insert name" ;
+ };
+ ListBox LB_ENTRYLIST
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 14 ) ;
+ Size = MAP_APPFONT ( 160 , 65 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ Sort = TRUE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 172 , 4 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 172 , 21 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 172 , 41 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 172 , 66 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Insert ~All" ;
+ };
+ Text [ en-US ] = "Insert Name" ;
+};
+
+ModalDialog RID_SCDLG_CHARTCOLROW
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 191 , 63 ) ;
+ Moveable = TRUE ;
+ CheckBox 1
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "First ~column as label" ;
+ };
+ CheckBox 2
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 114 , 10 ) ;
+ Text [ en-US ] = "First ~row as label" ;
+ };
+ FixedLine 6
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 123 , 8 ) ;
+ Text [ en-US ] = "Labels" ;
+ };
+ OKButton 3
+ {
+ Pos = MAP_APPFONT ( 135 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton 4
+ {
+ Pos = MAP_APPFONT ( 135 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton 5
+ {
+ Pos = MAP_APPFONT ( 135 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ Text [ en-US ] = "Change Source Data Range" ;
+};
+
+
+
diff --git a/sc/source/ui/src/namedlg.src b/sc/source/ui/src/namedlg.src
new file mode 100644
index 000000000000..38e1271b2959
--- /dev/null
+++ b/sc/source/ui/src/namedlg.src
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "namedlg.hrc"
+ModelessDialog RID_SCDLG_NAMES
+{
+ OutputSize = TRUE ;
+ HelpId = FID_DEFINE_NAME ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 222 , 142 ) ;
+ Text [ en-US ] = "Define Names" ;
+ Moveable = TRUE ;
+ // Closeable = TRUE; // Dieser Dialog hat einen Cancel-Button !
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 166 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 166 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 166 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 166 , 74 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Hinzu~fügen : Hinzu~f³gen */
+ Text [ en-US ] = "~Add" ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 166 , 92 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Löschen : ~L÷schen */
+ Text [ en-US ] = "~Delete" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_NAME
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "Name" ;
+ };
+ ComboBox ED_NAME
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 145 , 92 ) ;
+ TabStop = TRUE ;
+ VScroll = TRUE ;
+ Sort = TRUE ;
+ };
+ FixedLine FL_ASSIGN
+ {
+ Pos = MAP_APPFONT ( 6 , 112 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "Assigned to" ;
+ };
+ Edit ED_ASSIGN
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 123 ) ;
+ Size = MAP_APPFONT ( 131 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_ASSIGN
+ {
+ Pos = MAP_APPFONT ( 145 , 122 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ MoreButton BTN_MORE
+ {
+ Pos = MAP_APPFONT ( 166 , 122 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+ Delta = 41 ;
+ };
+ FixedLine FL_TYPE
+ {
+ Pos = MAP_APPFONT ( 6 , 142 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "Area type" ;
+ };
+ CheckBox BTN_PRINTAREA
+ {
+ Pos = MAP_APPFONT ( 12 , 153 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "~Print range" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_CRITERIA
+ {
+ Pos = MAP_APPFONT ( 12 , 167 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "~Filter" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_ROWHEADER
+ {
+ Pos = MAP_APPFONT ( 75 , 167 ) ;
+ Size = MAP_APPFONT ( 82 , 10 ) ;
+ Text [ en-US ] = "Repeat ~row" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_COLHEADER
+ {
+ Pos = MAP_APPFONT ( 75 , 153 ) ;
+ Size = MAP_APPFONT ( 82 , 10 ) ;
+ Text [ en-US ] = "Repeat ~column" ;
+ TabStop = TRUE ;
+ };
+ String STR_ADD
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Hinzu~fügen : Hinzu~f³gen */
+ Text [ en-US ] = "~Add" ;
+ };
+ String STR_MODIFY
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? ~Ändern : ~Žndern */
+ Text [ en-US ] = "Mod~ify" ;
+ };
+ String STR_INVALIDSYMBOL
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ungültiger Ausdruck : Ung³ltiger Ausdruck */
+ Text [ en-US ] = "Invalid expression" ;
+ };
+};
diff --git a/sc/source/ui/src/opredlin.src b/sc/source/ui/src/opredlin.src
new file mode 100644
index 000000000000..a8c2daf4892a
--- /dev/null
+++ b/sc/source/ui/src/opredlin.src
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "opredlin.hrc"
+TabPage RID_SCPAGE_OPREDLINE
+{
+ HelpId = HID_SCPAGE_OPREDLINE ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedText FT_CONTENT
+ {
+ HelpID = 1 ;
+ Pos = MAP_APPFONT ( 12 , 15 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "Chan~ges" ;
+ };
+ FixedText FT_REMOVE
+ {
+ Pos = MAP_APPFONT ( 12 , 31 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Deletions" ;
+ };
+ FixedText FT_INSERT
+ {
+ Pos = MAP_APPFONT ( 12 , 47 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Insertions" ;
+ };
+ FixedText FT_MOVE
+ {
+ Pos = MAP_APPFONT ( 12 , 63 ) ;
+ Size = MAP_APPFONT ( 70 , 10 ) ;
+ Text [ en-US ] = "~Moved entries" ;
+ };
+ FixedLine GB_COLORCHGS
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Colors for changes" ;
+ };
+ ListBox CLB_CONTENT
+ {
+ Pos = MAP_APPFONT ( 90 , 14 ) ;
+ Size = MAP_APPFONT ( 120 , 86 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox CLB_REMOVE
+ {
+ Pos = MAP_APPFONT ( 90 , 30 ) ;
+ Size = MAP_APPFONT ( 120 , 86 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox CLB_INSERT
+ {
+ Pos = MAP_APPFONT ( 90 , 46 ) ;
+ Size = MAP_APPFONT ( 120 , 86 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ ListBox CLB_MOVE
+ {
+ Pos = MAP_APPFONT ( 90 , 62 ) ;
+ Size = MAP_APPFONT ( 120 , 86 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ String STR_AUTHOR
+ {
+ Text [ en-US ] = "By author" ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/optdlg.src b/sc/source/ui/src/optdlg.src
new file mode 100644
index 000000000000..4c64e312bc2d
--- /dev/null
+++ b/sc/source/ui/src/optdlg.src
@@ -0,0 +1,722 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "optdlg.hrc"
+
+/**************************************************************************/
+/* */
+/* */
+/* */
+/**************************************************************************/
+
+TabPage RID_SCPAGE_CALC
+{
+ HelpId = HID_SCPAGE_CALC ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ CheckBox BTN_ITERATE
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Iterations" ;
+ };
+ FixedText FT_STEPS
+ {
+ Pos = MAP_APPFONT ( 20 , 28 ) ;
+ Size = MAP_APPFONT ( 58 , 8 ) ;
+ Text [ en-US ] = "~Steps" ;
+ };
+ FixedText FT_EPS
+ {
+ Pos = MAP_APPFONT ( 20 , 42 ) ;
+ Size = MAP_APPFONT ( 58 , 16 ) ;
+ Text [ en-US ] = "~Minimum Change" ;
+ WordBreak = TRUE ;
+ };
+ NumericField ED_STEPS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 82 , 26 ) ;
+ Size = MAP_APPFONT ( 42 , 12 ) ;
+ TabStop = TRUE ;
+ Minimum = 1 ;
+ Maximum = 1000 ;
+ Left = TRUE ;
+ };
+ Edit ED_EPS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 82 , 42 ) ;
+ Size = MAP_APPFONT ( 42 , 12 ) ;
+ };
+ FixedLine GB_ZREFS
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Iterative references" ;
+ };
+ RadioButton BTN_DATESTD
+ {
+ Pos = MAP_APPFONT ( 139 , 14 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "12/30/1899 (defa~ult)" ;
+ QuickHelpText [ en-US ] = "Value 0 corresponds to 12/30/1899" ;
+ };
+ RadioButton BTN_DATESC10
+ {
+ Pos = MAP_APPFONT ( 139 , 28 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? 01.01.1900 ( Star~Calc 1.0 ) : StarCa~lc 1.0 */
+ Text [ en-US ] = "01/01/1900 (Star~Calc 1.0)" ;
+ QuickHelpText [ en-US ] = "Value 0 corresponds to 01/01/1900" ;
+ };
+ RadioButton BTN_DATE1904
+ {
+ Pos = MAP_APPFONT ( 139 , 42 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~01.01.1904 : ~1904 */
+ Text [ en-US ] = "~01/01/1904" ;
+ QuickHelpText [ en-US ] = "0 corresponds to 01/01/1904" ;
+ };
+ FixedLine FL_SEPARATOR
+ {
+ Pos = MAP_APPFONT ( 130 , 14 ) ;
+ Size = MAP_APPFONT ( 1 , 44 ) ;
+ };
+ FixedLine GB_DATE
+ {
+ Pos = MAP_APPFONT ( 133 , 3 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Date" ;
+ };
+ FixedLine FL_H_SEPARATOR
+ {
+ Pos = MAP_APPFONT ( 6 , 64 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ };
+ CheckBox BTN_CASE
+ {
+ Pos = MAP_APPFONT ( 12 , 77 ) ;
+ Size = MAP_APPFONT ( 130 , 10 ) ;
+ Text [ en-US ] = "Case se~nsitive" ;
+ };
+ CheckBox BTN_CALC
+ {
+ Pos = MAP_APPFONT ( 12 , 91 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Precision as shown" ;
+ };
+ CheckBox BTN_MATCH
+ {
+ Pos = MAP_APPFONT ( 12 , 105 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Search criteria = and <> must apply to ~whole cells" ;
+ };
+ CheckBox BTN_REGEX
+ {
+ Pos = MAP_APPFONT ( 12 , 119 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Enable regular expressions in formulas" ;
+ };
+ CheckBox BTN_LOOKUP
+ {
+ Pos = MAP_APPFONT ( 12 , 133 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Automatically find column and row labels " ;
+ };
+ CheckBox BTN_GENERAL_PREC
+ {
+ Pos = MAP_APPFONT ( 12 , 147 ) ;
+ Size = MAP_APPFONT ( 148 , 10 ) ;
+ Text [ en-US ] = "Limit decimals for general number format" ;
+ };
+ FixedText FT_PREC
+ {
+ Pos = MAP_APPFONT ( 138 , 148 ) ;
+ Size = MAP_APPFONT ( 84 , 8 ) ;
+ Text [ en-US ] = "~Decimal places" ;
+ Right = TRUE ;
+ };
+ NumericField ED_PREC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 226 , 146 ) ;
+ Size = MAP_APPFONT ( 25 , 12 ) ;
+ Maximum = 20 ;
+ Spin = TRUE ;
+ Repeat = TRUE ;
+ };
+};
+
+/**************************************************************************/
+/* */
+/* */
+/* */
+/**************************************************************************/
+
+TabPage RID_SCPAGE_USERLISTS
+{
+ HelpId = HID_SCPAGE_USERLISTS ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedText FT_LISTS
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ Text [ en-US ] = "~Lists" ;
+ };
+ ListBox LB_LISTS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 15 ) ;
+ Size = MAP_APPFONT ( 93 , 148 ) ;
+ };
+ FixedText FT_ENTRIES
+ {
+ Pos = MAP_APPFONT ( 105 , 3 ) ;
+ Size = MAP_APPFONT ( 93 , 8 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Ein~träge : Ein~trõge */
+ Text [ en-US ] = "~Entries" ;
+ };
+ MultiLineEdit ED_ENTRIES
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 105 , 15 ) ;
+ Size = MAP_APPFONT ( 93 , 148 ) ;
+ VScroll = TRUE ;
+ IgnoreTab = TRUE ;
+ };
+ Edit ED_COPYFROM
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 70 , 167 ) ;
+ Size = MAP_APPFONT ( 128 , 12 ) ;
+ };
+ FixedText FT_COPYFROM
+ {
+ Pos = MAP_APPFONT ( 6 , 168 ) ;
+ Size = MAP_APPFONT ( 62 , 8 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Liste kopieren ~aus : Liste kopieren aus */
+ Text [ en-US ] = "Copy list ~from" ;
+ };
+ PushButton BTN_NEW
+ {
+ Pos = MAP_APPFONT ( 204 , 15 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~New" ;
+ };
+ PushButton BTN_ADD
+ {
+ Pos = MAP_APPFONT ( 204 , 36 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Hinzufügen : ~Hinzuf³gen */
+ Text [ en-US ] = "~Add" ;
+ Disable = TRUE ;
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 204 , 54 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Löschen : ~L÷schen */
+ Text [ en-US ] = "~Delete" ;
+ };
+ PushButton BTN_COPY
+ {
+ Pos = MAP_APPFONT ( 204 , 166 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Copy" ;
+ };
+ String STR_DISMISS
+ {
+ Text [ en-US ] = "~Discard" ;
+ };
+ String STR_QUERYREMOVE
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Soll der Eintrag\n#\ngelöscht werden? : Soll der Eintrag\n#\ngel÷scht werden? */
+ Text [ en-US ] = "Should the entry\n#\nbe deleted?" ;
+ };
+ String STR_COPYLIST
+ {
+ Text [ en-US ] = "Copy List" ;
+ };
+ String STR_COPYFROM
+ {
+ Text [ en-US ] = "List from" ;
+ };
+ String STR_COPYERR
+ {
+ Text [ en-US ] = "Cells without text have been ignored." ;
+ };
+};
+
+/**************************************************************************/
+/* */
+/* */
+/* */
+/**************************************************************************/
+
+TabPage RID_SCPAGE_CONTENT
+{
+ HelpId = HID_SCPAGE_CONTENT ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedLine GB_LINES
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Visual aids";
+ };
+ CheckBox CB_GRID
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Grid lines" ;
+ };
+ FixedText FT_COLOR
+ {
+ Pos = MAP_APPFONT ( 21 , 28 ) ;
+ Size = MAP_APPFONT ( 31 , 8 ) ;
+ Text [ en-US ] = "~Color" ;
+ };
+ ListBox LB_COLOR
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 26 ) ;
+ Size = MAP_APPFONT ( 70 , 86 ) ;
+ DropDown = TRUE ;
+ DDExtraWidth = TRUE ;
+ };
+ CheckBox CB_PAGEBREAKS
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Page breaks" ;
+ };
+ CheckBox CB_GUIDELINE
+ {
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Guides ~while moving";
+ };
+ CheckBox CB_HANDLES
+ {
+ Pos = MAP_APPFONT ( 12 , 70 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Simple handles";
+ };
+ CheckBox CB_BIGHANDLES
+ {
+ Pos = MAP_APPFONT ( 12 , 84 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Large handles";
+ };
+ FixedLine FL_SEPARATOR1
+ {
+ Pos = MAP_APPFONT ( 130 , 14 ) ;
+ Size = MAP_APPFONT ( 1 , 88 ) ;
+ };
+ FixedLine GB_DISPLAY
+ {
+ Pos = MAP_APPFONT ( 133 , 3 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Display" ;
+ };
+ CheckBox CB_FORMULA
+ {
+ Pos = MAP_APPFONT ( 139 , 14 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Formulas" ;
+ };
+ CheckBox CB_NIL
+ {
+ Pos = MAP_APPFONT ( 139 , 27 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Zero val~ues" ;
+ };
+ CheckBox CB_ANNOT
+ {
+ Pos = MAP_APPFONT ( 139 , 40 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Comment indicator" ;
+ };
+ CheckBox CB_VALUE
+ {
+ Pos = MAP_APPFONT ( 139 , 53 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Value h~ighlighting" ;
+ };
+ CheckBox CB_ANCHOR
+ {
+ Pos = MAP_APPFONT ( 139 , 66 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Anchor" ;
+ };
+ CheckBox CB_CLIP
+ {
+ Pos = MAP_APPFONT ( 139 , 79 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Te~xt overflow" ;
+ };
+ CheckBox CB_RFIND
+ {
+ Pos = MAP_APPFONT ( 139 , 92 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Show references in color" ;
+ };
+ FixedLine GB_OBJECT
+ {
+ Pos = MAP_APPFONT ( 6 , 100 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Objects" ;
+ };
+ FixedText FT_OBJGRF
+ {
+ Pos = MAP_APPFONT ( 12 , 113 ) ;
+ Size = MAP_APPFONT ( 68 , 8 ) ;
+ Text [ en-US ] = "Ob~jects/Graphics" ;
+ };
+ ListBox LB_OBJGRF
+ {
+ Pos = MAP_APPFONT ( 84 , 111 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ Border = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Show" ; Default ; > ;
+ < "Hide" ; Default ; > ;
+ };
+ };
+ FixedText FT_DIAGRAM
+ {
+ Pos = MAP_APPFONT ( 12 , 129 ) ;
+ Size = MAP_APPFONT ( 68 , 8 ) ;
+ Text [ en-US ] = "Cha~rts" ;
+ };
+ ListBox LB_DIAGRAM
+ {
+ Pos = MAP_APPFONT ( 84 , 127 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ Border = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Show" ; Default ; > ;
+ < "Hide" ; Default ; > ;
+ };
+
+ };
+ FixedText FT_DRAW
+ {
+ Pos = MAP_APPFONT ( 12 , 145 ) ;
+ Size = MAP_APPFONT ( 68 , 8 ) ;
+ Text [ en-US ] = "~Drawing objects" ;
+ };
+ ListBox LB_DRAW
+ {
+ Pos = MAP_APPFONT ( 84 , 143 ) ;
+ Size = MAP_APPFONT ( 40 , 46 ) ;
+ Border = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Show" ; Default ; > ;
+ < "Hide" ; Default ; > ;
+ };
+
+ };
+ FixedLine GB_ZOOM
+ {
+ Pos = MAP_APPFONT ( 6 , 160 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Zoom";
+ };
+ CheckBox CB_SYNCZOOM
+ {
+ Pos = MAP_APPFONT ( 12 , 171 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "S~ynchronize sheets" ;
+ };
+ FixedLine FL_SEPARATOR2
+ {
+ Pos = MAP_APPFONT ( 130 , 119 ) ;
+ Size = MAP_APPFONT ( 1 , 62 ) ;
+ };
+ FixedLine GB_WINDOW
+ {
+ Pos = MAP_APPFONT ( 133 , 108 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Window" ;
+ };
+ CheckBox CB_ROWCOLHEADER
+ {
+ Pos = MAP_APPFONT ( 139 , 119 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Colu~mn/row headers" ;
+ };
+ CheckBox CB_HSCROLL
+ {
+ Pos = MAP_APPFONT ( 139 , 132 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Hori~zontal scroll bar" ;
+ };
+ CheckBox CB_VSCROLL
+ {
+ Pos = MAP_APPFONT ( 139 , 145 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Vertical scroll bar" ;
+ };
+ CheckBox CB_TBLREG
+ {
+ Pos = MAP_APPFONT ( 139 , 158 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "Sh~eet tabs" ;
+ };
+ CheckBox CB_OUTLINE
+ {
+ Pos = MAP_APPFONT ( 139 , 171 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ Text [ en-US ] = "~Outline symbols" ;
+ };
+};
+
+/**************************************************************************/
+/* */
+/* */
+/* */
+/**************************************************************************/
+
+
+TabPage RID_SCPAGE_LAYOUT
+{
+ HelpId = HID_SCPAGE_LAYOUT ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedLine GB_UNIT
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 115 , 8 ) ;
+ Text [ en-US ] = "Metrics";
+ };
+ FixedText FT_UNIT
+ {
+ Pos = MAP_APPFONT ( 12 , 16 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "Measurement ~unit";
+ };
+ ListBox LB_UNIT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 72 , 14 ) ;
+ Size = MAP_APPFONT ( 46 , 52 ) ;
+ DropDown = TRUE ;
+ };
+ StringArray ST_UNIT
+ {
+ ItemList [ en-US ] =
+ {
+ < "Millimeter" ; FUNIT_MM ; > ;
+ < "Centimeter" ; FUNIT_CM ; > ;
+ < "Meter" ; FUNIT_M ; > ;
+ < "Kilometer" ; FUNIT_KM ; > ;
+ < "Inch" ; FUNIT_INCH ; > ;
+ < "Foot" ; FUNIT_FOOT ; > ;
+ < "Miles" ; FUNIT_MILE ; > ;
+ < "Pica" ; FUNIT_PICA ; > ;
+ < "Point" ; FUNIT_POINT ; > ;
+ };
+ };
+ FixedText FT_TAB
+ {
+ Pos = MAP_APPFONT ( 12 , 32 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Text [ en-US ] = "~Tab stops";
+ };
+ MetricField MF_TAB
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 72 , 30 ) ;
+ Size = MAP_APPFONT ( 46 , 12 ) ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ DecimalDigits = 2 ;
+ Unit = FUNIT_CM ;
+ SpinSize = 10 ;
+ Minimum = 50 ;
+ Maximum = 9999 ;
+ First = 50 ;
+ Last = 2000 ;
+ };
+ FixedLine FL_SEPARATOR
+ {
+ Pos = MAP_APPFONT ( 124 , 14 ) ;
+ Size = MAP_APPFONT ( 1 , 49 ) ;
+ };
+ FixedLine GB_LINK
+ {
+ Pos = MAP_APPFONT ( 127 , 3 ) ;
+ Size = MAP_APPFONT ( 127 , 8 ) ;
+ Text [ en-US ] = "Updating";
+ };
+ FixedText FT_UPDATE_LINKS
+ {
+ Pos = MAP_APPFONT ( 133 , 14 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Update links when opening";
+ };
+ RadioButton RB_ALWAYS
+ {
+ Pos = MAP_APPFONT ( 139 , 25 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Always";
+ };
+ RadioButton RB_REQUEST
+ {
+ Pos = MAP_APPFONT ( 139 , 39 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~On request";
+ };
+ RadioButton RB_NEVER
+ {
+ Pos = MAP_APPFONT ( 139 , 53 ) ;
+ Size = MAP_APPFONT ( 112 , 10 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Never";
+ };
+ FixedLine GB_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 69 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Input settings";
+ };
+ CheckBox CB_ALIGN
+ {
+ Pos = MAP_APPFONT ( 12 , 82 ) ;
+ Size = MAP_APPFONT ( 175 , 10 ) ;
+ Text [ en-US ] = "Press Enter to ~move selection" ;
+ };
+ ListBox LB_ALIGN
+ {
+ Pos = MAP_APPFONT ( 191 , 80 ) ;
+ Size = MAP_APPFONT ( 60 , 60 ) ;
+ Border = TRUE ;
+ DropDown = TRUE ;
+ // Reihenfolge der Strings wie enum ScDirection
+ StringList [ en-US ] =
+ {
+ < "Down" ; Default ; > ;
+ < "Right" ; Default ; > ;
+ < "Up" ; Default ; > ;
+ < "Left" ; Default ; > ;
+ };
+ };
+ CheckBox CB_EDITMODE
+ {
+ Pos = MAP_APPFONT ( 12 , 96 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Press Enter to switch to ~edit mode" ;
+ };
+ CheckBox CB_FORMAT
+ {
+ Pos = MAP_APPFONT ( 12 , 110 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Expand ~formatting" ;
+ };
+ CheckBox CB_EXPREF
+ {
+ Pos = MAP_APPFONT ( 12 , 124 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Expand ~references when new columns/rows are inserted" ;
+ };
+ CheckBox CB_MARKHDR
+ {
+ Pos = MAP_APPFONT ( 12 , 138 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Highlight sele~ction in column/row headers" ;
+ };
+ CheckBox CB_TEXTFMT
+ {
+ Pos = MAP_APPFONT ( 12 , 152 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Use printer metrics for text formatting";
+ };
+ CheckBox CB_REPLWARN
+ {
+ Pos = MAP_APPFONT ( 12 , 166 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Show overwrite ~warning when pasting data";
+ };
+};
+
+/**************************************************************************/
+/* */
+/* */
+/* */
+/**************************************************************************/
+
+TabPage RID_SCPAGE_PRINT
+{
+ HelpId = HID_SCPAGE_PRINT ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ FixedLine FL_PAGES
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Pages";
+ };
+ CheckBox BTN_SKIPEMPTYPAGES
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Suppress output of empty pages";
+ };
+ FixedLine FL_SHEETS
+ {
+ Pos = MAP_APPFONT ( 6 , 30 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Sheets";
+ };
+ CheckBox BTN_SELECTEDSHEETS
+ {
+ Pos = MAP_APPFONT ( 12 , 41 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Print only selected sheets";
+ };
+};
diff --git a/sc/source/ui/src/optsolver.src b/sc/source/ui/src/optsolver.src
new file mode 100644
index 000000000000..2fc5cf3a3c54
--- /dev/null
+++ b/sc/source/ui/src/optsolver.src
@@ -0,0 +1,540 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "optsolver.hrc"
+
+ModelessDialog RID_SCDLG_OPTSOLVER
+{
+ OutputSize = TRUE ;
+ HelpId = SID_OPENDLG_OPTSOLVER ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 230 , 210 ) ;
+ Text [ en-US ] = "Solver" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+
+ FixedText FT_OBJECTIVECELL
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Text [ en-US ] = "Target cell" ;
+ };
+ Edit ED_OBJECTIVECELL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 67 , 6 ) ;
+ Size = MAP_APPFONT ( 130 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_OBJECTIVECELL
+ {
+ Pos = MAP_APPFONT ( 199 , 5 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+
+ FixedText FT_DIRECTION
+ {
+ Pos = MAP_APPFONT ( 6 , 24 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Text [ en-US ] = "Optimize result to" ;
+ };
+ RadioButton RB_MAX
+ {
+ Pos = MAP_APPFONT ( 67 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Text [ en-US ] = "Maximum" ;
+ TabStop = TRUE ;
+ };
+ RadioButton RB_MIN
+ {
+ Pos = MAP_APPFONT ( 67 , 38 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Text [ en-US ] = "Minimum" ;
+ TabStop = TRUE ;
+ };
+ RadioButton RB_VALUE
+ {
+ Pos = MAP_APPFONT ( 67 , 52 ) ;
+ Size = MAP_APPFONT ( 59 , 10 ) ;
+ Text [ en-US ] = "Value of" ;
+ TabStop = TRUE ;
+ };
+ Edit ED_TARGET
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 128 , 50 ) ;
+ Size = MAP_APPFONT ( 69 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_TARGET
+ {
+ Pos = MAP_APPFONT ( 199 , 49 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+
+ FixedText FT_VARIABLECELLS
+ {
+ Pos = MAP_APPFONT ( 6 , 68 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Text [ en-US ] = "By changing cells" ;
+ };
+ Edit ED_VARIABLECELLS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 67 , 66 ) ;
+ Size = MAP_APPFONT ( 130 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_VARIABLECELLS
+ {
+ Pos = MAP_APPFONT ( 199 , 65 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+
+ FixedLine FL_CONDITIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 88 ) ;
+ Size = MAP_APPFONT ( 221 , 8 ) ;
+ Text [ en-US ] = "Limiting conditions" ;
+ };
+
+ FixedText FT_CELLREF
+ {
+ Pos = MAP_APPFONT ( 12 , 102 ) ;
+ Size = MAP_APPFONT ( 70 , 8 ) ;
+ Text [ en-US ] = "Cell reference" ;
+ };
+ FixedText FT_OPERATOR
+ {
+ Pos = MAP_APPFONT ( 84 , 102 ) ;
+ Size = MAP_APPFONT ( 38 , 8 ) ;
+ Text [ en-US ] = "Operator" ;
+ };
+ FixedText FT_CONSTRAINT
+ {
+ Pos = MAP_APPFONT ( 128 , 102 ) ;
+ Size = MAP_APPFONT ( 70 , 8 ) ;
+ Text [ en-US ] = "Value" ;
+ };
+
+ Edit ED_LEFT1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 114 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_LEFT1
+ {
+ Pos = MAP_APPFONT ( 67 , 113 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ListBox LB_OP1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 84 , 114 ) ;
+ Size = MAP_APPFONT ( 38 , 56 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "<=" ; Default ; > ;
+ < "=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "Integer" ; Default ; > ;
+ < "Binary" ; Default ; > ;
+ };
+ };
+ Edit ED_RIGHT1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 128 , 114 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_RIGHT1
+ {
+ Pos = MAP_APPFONT ( 183 , 113 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ImageButton IB_DELETE1
+ {
+ Pos = MAP_APPFONT ( 199 , 113 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Remove" ;
+ // image is set dynamically
+ };
+
+ Edit ED_LEFT2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 129 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_LEFT2
+ {
+ Pos = MAP_APPFONT ( 67 , 128 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ListBox LB_OP2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 84 , 129 ) ;
+ Size = MAP_APPFONT ( 38 , 56 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "<=" ; Default ; > ;
+ < "=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "Integer" ; Default ; > ;
+ < "Binary" ; Default ; > ;
+ };
+ };
+ Edit ED_RIGHT2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 128 , 129 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_RIGHT2
+ {
+ Pos = MAP_APPFONT ( 183 , 128 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ImageButton IB_DELETE2
+ {
+ Pos = MAP_APPFONT ( 199 , 128 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Remove" ;
+ // image is set dynamically
+ };
+
+ Edit ED_LEFT3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 144 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_LEFT3
+ {
+ Pos = MAP_APPFONT ( 67 , 143 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ListBox LB_OP3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 84 , 144 ) ;
+ Size = MAP_APPFONT ( 38 , 56 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "<=" ; Default ; > ;
+ < "=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "Integer" ; Default ; > ;
+ < "Binary" ; Default ; > ;
+ };
+ };
+ Edit ED_RIGHT3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 128 , 144 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_RIGHT3
+ {
+ Pos = MAP_APPFONT ( 183 , 143 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ImageButton IB_DELETE3
+ {
+ Pos = MAP_APPFONT ( 199 , 143 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Remove" ;
+ // image is set dynamically
+ };
+
+ Edit ED_LEFT4
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 159 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_LEFT4
+ {
+ Pos = MAP_APPFONT ( 67 , 158 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ListBox LB_OP4
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 84 , 159 ) ;
+ Size = MAP_APPFONT ( 38 , 56 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "<=" ; Default ; > ;
+ < "=" ; Default ; > ;
+ < ">=" ; Default ; > ;
+ < "Integer" ; Default ; > ;
+ < "Binary" ; Default ; > ;
+ };
+ };
+ Edit ED_RIGHT4
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 128 , 159 ) ;
+ Size = MAP_APPFONT ( 53 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton IB_RIGHT4
+ {
+ Pos = MAP_APPFONT ( 183 , 158 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ ImageButton IB_DELETE4
+ {
+ Pos = MAP_APPFONT ( 199 , 158 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ QuickHelpText [ en-US ] = "Remove" ;
+ // image is set dynamically
+ };
+
+ ScrollBar SB_SCROLL
+ {
+ Pos = MAP_APPFONT ( 216, 113 ) ;
+ Size = MAP_APPFONT ( 8 , 59 ) ;
+ VScroll = TRUE ;
+ };
+
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 179 ) ;
+ Size = MAP_APPFONT ( 230 , 8 ) ;
+ };
+
+ PushButton BTN_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Options..." ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 62 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CLOSE
+ {
+ Pos = MAP_APPFONT ( 118 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Close" ;
+ };
+ PushButton BTN_SOLVE
+ {
+ Pos = MAP_APPFONT ( 174 , 190 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Solve" ;
+ DefButton = TRUE ;
+ };
+
+ // IMG_DEL_H not used - image is set dynamically
+
+ String STR_INVALIDINPUT
+ {
+ Text [ en-US ] = "Invalid input." ;
+ };
+ String STR_INVALIDCONDITION
+ {
+ Text [ en-US ] = "Invalid condition." ;
+ };
+};
+
+
+ModelessDialog RID_SCDLG_SOLVER_PROGRESS
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_SOLVER_PROGRESS ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 118 , 72 ) ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_PROGRESS
+ {
+ Pos = MAP_APPFONT ( 6 , 11 ) ;
+ Size = MAP_APPFONT ( 106 , 8 ) ;
+ Center = TRUE ;
+ Text [ en-US ] = "Solving in progress..." ;
+ };
+ FixedText FT_TIMELIMIT
+ {
+ Pos = MAP_APPFONT ( 6 , 25 ) ;
+ Size = MAP_APPFONT ( 106 , 8 ) ;
+ Center = TRUE ;
+ Text [ en-US ] = "(time limit # seconds)" ;
+ };
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 41 ) ;
+ Size = MAP_APPFONT ( 118 , 8 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 34 , 52 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ Text [ en-US ] = "Solving..." ;
+};
+
+
+ModalDialog RID_SCDLG_SOLVER_NOSOLUTION
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_SOLVER_NOSOLUTION ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 118 , 72 ) ;
+ Moveable = TRUE ;
+ FixedText FT_NOSOLUTION
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 106 , 8 ) ;
+ Text [ en-US ] = "No solution was found." ;
+ };
+ FixedText FT_ERRORTEXT
+ {
+ Pos = MAP_APPFONT ( 6 , 22 ) ;
+ Size = MAP_APPFONT ( 106 , 16 ) ;
+ WordBreak = TRUE ;
+ // text is dynamic
+ };
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 41 ) ;
+ Size = MAP_APPFONT ( 118 , 8 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 34 , 52 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ Text [ en-US ] = "No Solution" ;
+};
+
+
+ModalDialog RID_SCDLG_SOLVER_SUCCESS
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_SOLVER_SUCCESS ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 138 , 89 ) ;
+ Moveable = TRUE ;
+ FixedText FT_SUCCESS
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 126 , 8 ) ;
+ Text [ en-US ] = "Solving successfully finished." ;
+ };
+ FixedText FT_RESULT
+ {
+ Pos = MAP_APPFONT ( 6 , 22 ) ;
+ Size = MAP_APPFONT ( 126 , 8 ) ;
+ Text [ en-US ] = "Result:" ;
+ };
+ FixedText FT_QUESTION
+ {
+ Pos = MAP_APPFONT ( 6 , 36 ) ;
+ Size = MAP_APPFONT ( 126 , 16 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "Do you want to keep the result or do you want to restore previous values?" ;
+ };
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 58 ) ;
+ Size = MAP_APPFONT ( 138 , 8 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 6 , 69 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ Text [ en-US ] = "Keep Result" ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 72 , 69 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Restore Previous" ;
+ };
+ Text [ en-US ] = "Solving Result" ;
+};
+
diff --git a/sc/source/ui/src/popup.src b/sc/source/ui/src/popup.src
new file mode 100644
index 000000000000..9753aa1590e3
--- /dev/null
+++ b/sc/source/ui/src/popup.src
@@ -0,0 +1,544 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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" // -> #include <sfx.hrc>
+#include <svx/globlmn.hrc>
+
+
+ // Popup-Menues ----------------------------------------------------------------
+
+String RID_POPUP_CELLS
+{
+ Text [ en-US ] = "Cell pop-up menu" ;
+};
+
+Menu RID_POPUP_CELLS
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_CELL_FORMAT_RESET ;
+ HelpId = SID_CELL_FORMAT_RESET ;
+ Text [ en-US ] = "~Default Formatting" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_CELL_FORMAT ;
+ HelpId = FID_CELL_FORMAT ;
+ Text [ en-US ] = "~Format Cells..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_INS_CELL ;
+ HelpId = FID_INS_CELL ;
+ Text [ en-US ] = "~Insert..." ;
+ };
+ MenuItem
+ {
+ Identifier = FID_DELETE_CELL ;
+ HelpId = FID_DELETE_CELL ;
+ Text [ en-US ] = "De~lete..." ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE ;
+ HelpId = SID_DELETE ;
+ Text [ en-US ] = "Delete C~ontents..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = SID_INSERT_POSTIT ;
+ HelpId = SID_INSERT_POSTIT ;
+ Text [ en-US ] = "Insert Co~mment" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE_NOTE ;
+ HelpId = SID_DELETE_NOTE ;
+ Text [ en-US ] = "D~elete Comment" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_NOTE_VISIBLE ;
+ HelpId = FID_NOTE_VISIBLE ;
+ Text [ en-US ] = "Sho~w Comment" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+
+ MenuItem
+ {
+ Identifier = SID_CUT ;
+ HelpId = SID_CUT ;
+ Text [ en-US ] = "Cu~t" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_COPY ;
+ HelpId = SID_COPY ;
+ Text [ en-US ] = "~Copy" ;
+ };
+
+ MenuItem
+ {
+ Identifier = SID_PASTE ;
+ HelpID = SID_PASTE ;
+ Text [ en-US ] = "~Paste" ;
+ };
+
+ MenuItem
+ {
+ Identifier = SID_PASTE_SPECIAL ;
+ HelpId = SID_PASTE_SPECIAL ;
+ Text [ en-US ] = "P~aste Special..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = SID_DATA_SELECT ;
+ HelpId = SID_DATA_SELECT ;
+ Text [ en-US ] = "~Selection List..." ;
+ };
+ };
+};
+
+String RID_POPUP_TAB
+{
+ Text [ en-US ] = "Sheet bar pop-up menu" ;
+};
+
+Menu RID_POPUP_TAB
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = FID_INS_TABLE ;
+ HelpId = FID_INS_TABLE ;
+ Text [ en-US ] = "~Insert Sheet..." ;
+ };
+ MenuItem
+ {
+ Identifier = FID_DELETE_TABLE ;
+ HelpId = FID_DELETE_TABLE ;
+ Text [ en-US ] = "~Delete Sheet..." ;
+ };
+ MenuItem
+ {
+ Identifier = FID_TAB_MENU_RENAME ;
+ HelpId = FID_TAB_MENU_RENAME ;
+ Text [ en-US ] = "~Rename Sheet..." ;
+ };
+ MenuItem
+ {
+ Identifier = FID_TAB_MOVE ;
+ HelpId = FID_TAB_MOVE ;
+ Text [ en-US ] = "~Move/Copy Sheet..." ;
+ };
+ MenuItem
+ {
+ Identifier = FID_TAB_SELECTALL ;
+ HelpId = FID_TAB_SELECTALL ;
+ Text [ en-US ] = "Select All S~heets" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_TAB_DESELECTALL ;
+ HelpId = FID_TAB_DESELECTALL ;
+ Text [ en-US ] = "D~eselect All Sheets" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_TAB_RTL ;
+ HelpId = FID_TAB_RTL ;
+ Text [ en-US ] = "S~heet Right-To-Left" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_TAB_EVENTS ;
+ HelpId = FID_TAB_EVENTS ;
+ Text [ en-US ] = "Sheet E~vents..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_TAB_MENU_SET_TAB_BG_COLOR ;
+ HelpId = FID_TAB_MENU_SET_TAB_BG_COLOR ;
+ Text [ en-US ] = "~Tab Color..." ;
+ };
+ };
+};
+
+String RID_POPUP_PIVOT
+{
+ Text [ en-US ] = "DataPilot pop-up menu" ;
+};
+
+Menu RID_POPUP_PIVOT
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_OPENDLG_PIVOTTABLE ;
+ HelpId = SID_OPENDLG_PIVOTTABLE ;
+ Text [ en-US ] = "~Start..." ;
+ };
+ MenuItem
+ {
+ Identifier = SID_PIVOT_RECALC ;
+ HelpId = SID_PIVOT_RECALC ;
+ Text [ en-US ] = "~Refresh" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DP_FILTER ;
+ HelpId = SID_DP_FILTER ;
+ Text [ en-US ] = "~Filter..." ;
+ };
+ MenuItem
+ {
+ Identifier = SID_PIVOT_KILL ;
+ HelpId = SID_PIVOT_KILL ;
+ Text [ en-US ] = "~Delete" ;
+ };
+ };
+};
+
+String RID_POPUP_PREVIEW
+{
+ Text [ en-US ] = "Page Preview pop-up menu" ;
+};
+
+Menu RID_POPUP_PREVIEW
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_PREVIEW_PREVIOUS ;
+ HelpId = SID_PREVIEW_PREVIOUS ;
+ Text [ en-US ] = "~Previous Page" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_PREVIEW_NEXT ;
+ HelpId = SID_PREVIEW_NEXT ;
+ Text [ en-US ] = "~Next Page" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_FORMATPAGE ;
+ HelpId = SID_FORMATPAGE ;
+ Text [ en-US ] = "Pa~ge Layout..." ;
+ };
+ MenuItem
+ {
+ Identifier = SID_CLOSEWIN ;
+ HelpId = SID_CLOSEWIN ;
+ Text [ en-US ] = "~Close" ;
+ };
+ MenuItem { Separator = TRUE; };
+ MenuItem
+ {
+ Identifier = SID_PREVIEW_CLOSE ;
+ HelpId = SID_PRINTPREVIEW ;
+ Text [ en-US ] = "Close Pre~view" ;
+ };
+ };
+};
+
+
+String RID_POPUP_EDIT
+{
+ Text [ en-US ] = "Text Input pop-up menu" ;
+};
+
+Menu RID_POPUP_EDIT
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_CELL_FORMAT_RESET ;
+ HelpId = SID_CELL_FORMAT_RESET ;
+ Text [ en-US ] = "~Default" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem // Menu-Controller
+ // Menu-Controller
+ // Menu-Controller
+ // Menu-Controller
+ {
+ ITEM_FORMAT_ATTR_CHAR_FONT
+ };
+ MenuItem // Menu-Controller
+ // Menu-Controller
+ // Menu-Controller
+ // Menu-Controller
+ {
+ ITEM_FORMAT_ATTR_CHAR_FONTHEIGHT
+ };
+ MenuItem
+ {
+ Text [ en-US ] = "Style" ;
+ Identifier = RID_MN_FORMAT_STYLE ;
+ HelpID = RID_MN_FORMAT_STYLE ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_WEIGHT
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_POSTURE
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_OVERLINE
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_UNDERLINE
+ };
+ MenuItem
+ {
+ Identifier = SID_ULINE_VAL_DOUBLE ;
+ HelpID = SID_ULINE_VAL_DOUBLE ;
+ Text [ en-US ] = "Do~uble Underline" ;
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_STRIKEOUT
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_SHADOWED
+ };
+ MenuItem
+ {
+ ITEM_FORMAT_ATTR_CHAR_CONTOUR
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = SID_SET_SUPER_SCRIPT ;
+ HelpID = SID_SET_SUPER_SCRIPT ;
+ Text [ en-US ] = "Su~perscript" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_SET_SUB_SCRIPT ;
+ HelpID = SID_SET_SUB_SCRIPT ;
+ Text [ en-US ] = "Su~bscript" ;
+ };
+ };
+ };
+ Text [ en-US ] = "St~yle";
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ ITEM_FORMAT_CHAR_DLG
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ ITEM_OPEN_HYPERLINK
+ };
+ };
+};
+
+String RID_POPUP_AUDIT
+{
+ Text [ en-US ] = "Detective Fill Mode pop-up menu" ;
+};
+
+Menu RID_POPUP_AUDIT
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_FILL_ADD_PRED ;
+ HelpId = SID_FILL_ADD_PRED ;
+ Text [ en-US ] = "Trace ~Precedent" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_FILL_DEL_PRED ;
+ HelpId = SID_FILL_DEL_PRED ;
+ Text [ en-US ] = "~Remove Precedent" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_FILL_ADD_SUCC ;
+ HelpId = SID_FILL_ADD_SUCC ;
+ Text [ en-US ] = "~Trace Dependent" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_FILL_DEL_SUCC ;
+ HelpId = SID_FILL_DEL_SUCC ;
+ Text [ en-US ] = "Remove Dependent" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DETECTIVE_DEL_ALL ;
+ HelpId = SID_DETECTIVE_DEL_ALL ;
+ Text [ en-US ] = "Remove ~All Traces" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_FILL_NONE ;
+ HelpId = SID_FILL_NONE ;
+ Text [ en-US ] = "Exit Fill Mode" ;
+ };
+ };
+};
+
+String RID_POPUP_PAGEBREAK
+{
+ Text [ en-US ] = "Page Break Preview pop-up menu" ;
+};
+
+Menu RID_POPUP_PAGEBREAK
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_CELL_FORMAT_RESET ;
+ HelpId = SID_CELL_FORMAT_RESET ;
+ Text [ en-US ] = "~Default" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_CELL_FORMAT ;
+ HelpId = FID_CELL_FORMAT ;
+ Text [ en-US ] = "~Format Cells..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_INS_ROWBRK ;
+ HelpId = FID_INS_ROWBRK ;
+ Text [ en-US ] = "Insert ~Row Break" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_INS_COLBRK ;
+ HelpId = FID_INS_COLBRK ;
+ Text [ en-US ] = "Insert ~Column Break" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_DEL_MANUALBREAKS ;
+ HelpId = FID_DEL_MANUALBREAKS ;
+ Text [ en-US ] = "Delete All Manual Breaks" ;
+ };
+ MenuItem
+ {
+ Identifier = FID_RESET_PRINTZOOM ;
+ HelpId = FID_RESET_PRINTZOOM ;
+ Text [ en-US ] = "Reset Scale" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = SID_DEFINE_PRINTAREA ;
+ HelpId = SID_DEFINE_PRINTAREA ;
+ Text [ en-US ] = "Define Print Range" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_ADD_PRINTAREA ;
+ HelpId = SID_ADD_PRINTAREA ;
+ Text [ en-US ] = "Add Print Range" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE_PRINTAREA ;
+ HelpId = SID_DELETE_PRINTAREA ;
+ Text [ en-US ] = "Undo Print Range" ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = SID_FORMATPAGE ;
+ HelpId = SID_FORMATPAGE ;
+ Text [ en-US ] = "Page Format..." ;
+ };
+ //------------------------------
+ MenuItem { Separator = TRUE ; };
+ //------------------------------
+ MenuItem
+ {
+ Identifier = FID_NOTE_VISIBLE ;
+ HelpId = FID_NOTE_VISIBLE ;
+ Text [ en-US ] = "Sho~w Comment" ;
+ };
+ };
+};
+
+
diff --git a/sc/source/ui/src/pseudo.src b/sc/source/ui/src/pseudo.src
new file mode 100644
index 000000000000..e3d27edf0ecb
--- /dev/null
+++ b/sc/source/ui/src/pseudo.src
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#include <svx/svxids.hrc>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/sc.src b/sc/source/ui/src/sc.src
new file mode 100644
index 000000000000..dae422e15cd0
--- /dev/null
+++ b/sc/source/ui/src/sc.src
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> #include <sfx.hrc>
+
+
+
+// App-Titel------------------------------------------------------
+
+String RID_APPTITLE
+{
+ /* ### ACHTUNG: Neuer Text in Resource? StarCalc 4.0 : StarCalc 3.1 */
+ Text [ en-US ] = "%PRODUCTNAME Calc" ;
+};
+
+ // About-Dialog --------------------------------------------------------------
+
+ // Icons & Bitmaps: ----------------------------------------------------------
+
+
+
+ // ???
+String 30001 { Text = "Dummy1" ; };
+String 30002 { Text = "Dummy2" ; };
+String 30006 { Text = "Dummy3" ; };
diff --git a/sc/source/ui/src/scerrors.src b/sc/source/ui/src/scerrors.src
new file mode 100644
index 000000000000..bdb76b2b710c
--- /dev/null
+++ b/sc/source/ui/src/scerrors.src
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define __RSC
+#include "scerrors.hxx"
+#include "sc.hrc"
+
+Resource RID_ERRHDLSC
+{
+ //------------------------------------------------------------
+ // ERRORS -----------------------------------------------------
+ //------------------------------------------------------------
+ String SCERR_IMPORT_CONNECT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Impossible to connect to the file." ;
+ };
+ String SCERR_IMPORT_OPEN & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "File could not be opened." ;
+ };
+ String SCERR_IMPORT_UNKNOWN & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "An unknown error has occurred." ;
+ };
+ String SCERR_IMPORT_OUTOFMEM & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Not enough memory while importing." ;
+ };
+ String SCERR_IMPORT_UNKNOWN_WK & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unknown Lotus1-2-3 file format." ;
+ };
+ String SCERR_IMPORT_FORMAT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Error in file structure while importing." ;
+ };
+ String SCERR_IMPORT_NI & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "There is no filter available for this file type." ;
+ };
+ String SCERR_IMPORT_UNKNOWN_BIFF & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unknown or unsupported Excel file format." ;
+ };
+ String SCERR_IMPORT_NI_BIFF & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Excel file format not yet implemented." ;
+ };
+ String SCERR_IMPORT_FILEPASSWD & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "This file is password-protected." ;
+ };
+ String SCERR_IMPORT_INTERNAL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Internal import error." ;
+ };
+ String SCERR_IMPORT_8K_LIMIT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The file contains data after row 8192 and therefore can not be read." ;
+ };
+ String SCERR_IMPORT_FILE_ROWCOL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Format error discovered in the file in sub-document $(ARG1) at $(ARG2)(row,col).";
+ };
+ String SCERR_IMPORT_FORMAT_ROWCOL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "File format error found at $(ARG1)(row,col)." ;
+ };
+
+ // Export ----------------------------------------------------
+ String SCERR_EXPORT_CONNECT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Connection to the file could not be established." ;
+ };
+ String SCERR_EXPORT_DATA & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Data could not be written." ;
+ };
+ String SCERR_EXPORT_SQLEXCEPTION & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "$(ARG1)" ;
+ };
+ String SCERR_EXPORT_ENCODING & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Cell $(ARG1) contains characters that are not representable in the selected target character set \"$(ARG2)\"." ;
+ };
+ String SCERR_EXPORT_FIELDWIDTH & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Cell $(ARG1) contains a string that is longer in the selected target character set \"$(ARG2)\" than the given field width." ;
+ };
+ //------------------------------------------------------------
+ // WARNINGS ---------------------------------------------------
+ //------------------------------------------------------------
+ String SCWARN_EXPORT_ASCII & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Only the active sheet was saved." ;
+ };
+ String SCWARN_IMPORT_RANGE_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The maximum number of rows has been exceeded. Excess rows were not imported!" ;
+ };
+ String SCWARN_IMPORT_ROW_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The data could not be loaded completely because the maximum number of rows per sheet was exceeded." ;
+ };
+ String SCWARN_IMPORT_COLUMN_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The data could not be loaded completely because the maximum number of columns per sheet was exceeded." ;
+ };
+ String SCWARN_IMPORT_SHEET_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Some sheets could not be loaded because the maximum number of sheets was exceeded." ;
+ };
+ String SCWARN_IMPORT_OPEN_FM3 & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Corresponding FM3-File could not be opened." ;
+ };
+ String SCWARN_IMPORT_WRONG_FM3 & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Error in file structure of corresponding FM3-File." ;
+ };
+ String SCWARN_CORE_HARD_RECALC & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Document too complex for automatic calculation. Press F9 to recalculate." ;
+ };
+ String SCWARN_EXPORT_MAXROW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The document contains more rows than supported in the selected format.\nAdditional rows were not saved." ;
+ };
+ String SCWARN_IMPORT_INFOLOST & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The document contains information not recognized by this program version.\nResaving the document will delete this information!" ;
+ };
+ String SCWARN_EXPORT_DATALOST & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Not all cell contents could be saved in the specified format." ;
+ };
+ String SCWARN_EXPORT_NONCONVERTIBLE_CHARS & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "The following characters could not be converted to the selected character set\nand were written as &#1234; surrogates:\n\n$(ARG1)";
+ };
+ String SCWARN_IMPORT_FILE_ROWCOL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Format error discovered in the file in sub-document $(ARG1) at $(ARG2)(row,col).";
+ };
+};
+
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
new file mode 100644
index 000000000000..2f5a2d8c88fb
--- /dev/null
+++ b/sc/source/ui/src/scfuncs.src
@@ -0,0 +1,9043 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* Resource file for the function wizard / autopilot.
+ *
+ * All descriptions of functions are collected within the resources
+ * RID_SC_FUNCTION_DESCRIPTIONS1 respectively RID_SC_FUNCTION_DESCRIPTIONS2,
+ * two blocks because otherwise we had a 64kb overflow.
+ *
+ * For every function there is a sub resource with the number of the OpCode of
+ * the function.
+ *
+ * In this sub resource, with index 1 the description of the function is
+ * given, after that follows an
+ *
+ * ExtraData block with:
+ *
+ * Boolean flag whether function is suppressed. Usually 0. This may be
+ * used to add UI string resources before UI freeze if implementation
+ * isn't ready yet without displaying them in the function wizard,
+ * most recent used list and other UI elements. Also not available via
+ * API then.
+ *
+ * Function group (text, math, ...), one of ID_FUNCTION_GRP_...
+ *
+ * Help ID, U2S(HID_FUNC_...)
+ *
+ * Number of parameters. VAR_ARGS if variable number, or
+ * VAR_ARGS+number if number of fixed parameters and variable
+ * arguments following.
+ *
+ * For every parameter:
+ *
+ * Boolean flag whether the parameter is optional.
+ *
+ * Number of suppressed parameters. Usually 0. Same meaning and
+ * mechanism as the flag for the entire function above.
+ *
+ * For every suppressed parameter:
+ *
+ * The parameter number, offset starting with 0. Variable
+ * arguments can't be suppressed!
+ *
+ *
+ * ExtraData block followed by two string resources for each parameter,
+ * first the type or name of the parameter, second a description of the
+ * parameter.
+ */
+
+// Hack:
+#define U2S(x) ((x)-HID_START)
+// Macro U2S: unsigned to signed
+// is needed because the resource compiler only knows signed short int in
+// ExtraData, but the HID_XXX are unsigned and exceed 32k. Code reading the
+// resource entries must consider this and undo the conversion.
+
+#include "scfuncs.hrc" // ID_FUNCTION_GRP_XXX, HID_FUNC_XXX
+#include "formula/compiler.hrc" // SC_OPCODE_XXX
+
+Resource RID_SC_FUNCTION_DESCRIPTIONS1
+{
+ // -=*# Resource for function DBANZAHL #*=-
+ Resource SC_OPCODE_DB_COUNT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Counts the cells of a data range whose contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBANZAHL );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBANZAHL2 #*=-
+ Resource SC_OPCODE_DB_COUNT_2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Counts all non-blank cells of a data range where the content corresponds to the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBANZAHL2 );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBMITTELWERT #*=-
+ Resource SC_OPCODE_DB_AVERAGE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the average value of all the cells of a data range whose contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBMITTELWERT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBAUSZUG #*=-
+ Resource SC_OPCODE_DB_GET
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Defines the contents of the cell of a data range which matches the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBAUSZUG );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBMAX #*=-
+ Resource SC_OPCODE_DB_MAX
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the maximum value from all of the cells of a data range which correspond to the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBMAX );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBMIN #*=-
+ Resource SC_OPCODE_DB_MIN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the minimum of all cells of a data range where the contents correspond to the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBMIN );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBPRODUKT #*=-
+ Resource SC_OPCODE_DB_PRODUCT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Multiplies all cells of a data range where the contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBPRODUKT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBSTDABW #*=-
+ Resource SC_OPCODE_DB_STD_DEV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the standard deviation of all cells in a data range whose contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBSTDABW );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBSTDABWN #*=-
+ Resource SC_OPCODE_DB_STD_DEV_P
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the standard deviation with regards to the population of all cells of a data range matching the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBSTDABWN );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBSUMME #*=-
+ Resource SC_OPCODE_DB_SUM
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Adds all the cells of a data range where the contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBSUMME );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBVARIANZ #*=-
+ Resource SC_OPCODE_DB_VAR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the variance of all the cells in a data range where the contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBVARIANZ );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DBVARIANZEN #*=-
+ Resource SC_OPCODE_DB_VAR_P
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines variance of a population based on all cells in a data range where contents match the search criteria." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATABASE;
+ U2S( HID_FUNC_DBVARIANZEN );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Database" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells containing data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Database field" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates which database field (column) is to be used for the search criteria." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Search criteria" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Defines the cell range containing the search criteria." ;
+ };
+ };
+ // -=*# Resource for function DATUM #*=-
+ Resource SC_OPCODE_GET_DATE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Provides an internal number for the date given." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_DATUM );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "year" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "An integer between 1583 and 9956 or 0 and 99 (19xx or 20xx depending on the defined option)." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "month" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "An integer between 1 and 12 representing the month." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "day" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "An integer between 1 and 31 representing the day of the month." ;
+ };
+ };
+ // -=*# Resource for function DATWERT #*=-
+ Resource SC_OPCODE_GET_DATE_VALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns an internal number for a text having a possible date format." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_DATWERT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A text enclosed in quotation marks which returns a date in a %PRODUCTNAME date format." ;
+ };
+ };
+ // -=*# Resource for function TAG #*=-
+ Resource SC_OPCODE_GET_DAY
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sequential date of the month as an integer (1-31) in relation to the date value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_TAG );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The internal number for the date." ;
+ };
+ };
+ // -=*# Resource for function TAGE360 #*=-
+ Resource SC_OPCODE_GET_DIFF_DATE_360
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the number of days between two dates based on a 360-day year." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_TAGE360 );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Date_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The start date for calculating the difference in days." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Date_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The end date for calculating the difference in days." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Method used to form differences: Type = 0 denotes US method (NASD), Type = 1 denotes the European method." ;
+ };
+ };
+ // -=*# Resource for function STUNDE #*=-
+ Resource SC_OPCODE_GET_HOUR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the sequential number of the hour of the day (0-23) for the time value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_STUNDE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Internal time value" ;
+ };
+ };
+ // -=*# Resource for function MINUTE #*=-
+ Resource SC_OPCODE_GET_MIN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the sequential number for the minute of the hour (0-59) for the time value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_MINUTE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Internal time value." ;
+ };
+ };
+ // -=*# Resource for function MONAT #*=-
+ Resource SC_OPCODE_GET_MONTH
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the sequential number of a month of the year (1-12) for the date value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_MONAT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The internal number of the date." ;
+ };
+ };
+ // -=*# Resource for function JETZT #*=-
+ Resource SC_OPCODE_GET_ACT_TIME
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the current time of the computer." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_JETZT );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function SEKUNDE #*=-
+ Resource SC_OPCODE_GET_SEC
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the sequential number of the second of a minute (0-59) for the time value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_SEKUNDE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The internal time value." ;
+ };
+ };
+ // -=*# Resource for function ZEIT #*=-
+ Resource SC_OPCODE_GET_TIME
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines a time value from the details for hour, minute and second." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_ZEIT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "hour" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The integer for the hour." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "minute" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The integer for the minute." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "second" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The integer for the second." ;
+ };
+ };
+ // -=*# Resource for function ZEITWERT #*=-
+ Resource SC_OPCODE_GET_TIME_VALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a sequential number for a text shown in a possible time entry format." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_ZEITWERT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A text enclosed in quotation marks which returns a time in a %PRODUCTNAME time format." ;
+ };
+ };
+ // -=*# Resource for function HEUTE #*=-
+ Resource SC_OPCODE_GET_ACT_DATE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines the current date of the computer." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_HEUTE );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function WOCHENTAG #*=-
+ Resource SC_OPCODE_GET_DAY_OF_WEEK
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the day of the week for the date value as an integer (1-7)." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_WOCHENTAG );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The internal number for the date." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Fixes the beginning of the week and the type of calculation to be used." ;
+ };
+ };
+ // -=*# Resource for function JAHR #*=-
+ Resource SC_OPCODE_GET_YEAR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the year of a date value as an integer." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_JAHR );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Internal number of the date." ;
+ };
+ };
+ // -=*# Resource for function TAGE #*=-
+ Resource SC_OPCODE_GET_DIFF_DATE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the number of days between two dates." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_TAGE );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Date_2" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The end date for calculating the difference in days." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Date_1" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The start date for calculating the difference in days." ;
+ };
+ };
+ // -=*# Resource for function KALENDERWOCHE #*=-
+ Resource SC_OPCODE_WEEK
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the calendar week corresponding to the given date." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_KALENDERWOCHE );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The internal number of the date." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mode" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Indicates the first day of the week (1 = Sunday, other values = Monday)." ;
+ };
+ };
+ // -=*# Resource for function OSTERSONNTAG #*=-
+ Resource SC_OPCODE_EASTERSUNDAY
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the date of Easter Sunday in a given year.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_OSTERSONNTAG );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "year";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "An integer between 1583 and 9956, or 0 and 99 (19xx or 20xx depending on the option set).";
+ };
+ };
+ // -=*# Resource for function BW #*=-
+ Resource SC_OPCODE_BW
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Present value. Calculates the present value of an investment." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_BW );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest for the period given." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The payment period. The total number of periods in which the annuity is paid." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "PMT" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Regular payments. The constant amount of annuity that is paid in each period." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Future value. The value (final value) to be attained after the last payment." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function ZW #*=-
+ Resource SC_OPCODE_ZW
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Future value. Returns the future value of an investment based on regular payments and a constant interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_ZW );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "PMT" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Regular payments. The constant annuity to be paid in each period." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "PV" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Present value. The current value of a series of payments" ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function ZZR #*=-
+ Resource SC_OPCODE_ZZR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Payment period. Calculates the number of payment periods for an investment based on regular payments and a constant interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_ZZR );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "PMT" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Regular payments. The constant annuity to be paid in each period." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "PV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Present value. The current value of a series of payments" ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Future value. The value (end value) to be attained after the final payment." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function RMZ #*=-
+ Resource SC_OPCODE_RMZ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Regular payments. Returns the periodic payment of an annuity, based on regular payments and a fixed periodic interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_RMZ );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "PV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Present value. The current value of a series of payments" ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Future value. The value (end value) to be attained after the final payment." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function ZINS #*=-
+ Resource SC_OPCODE_ZINS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the constant interest rate of an investment with regular payments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_ZINS );
+ 6; 0; 0; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "PMT" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Regular payments. The constant annuity to be paid in each period." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "PV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Present value. The current value of a series of payments" ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Future value. The value (end value) to be attained after the final payment." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [ en-US ] = "Guess" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "Guess. The estimate of the interest rate for the iterative calculating method." ;
+ };
+ };
+ // -=*# Resource for function ZINSZ #*=-
+ Resource SC_OPCODE_ZINS_Z
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Compounded interest. Calculates the interest payment on the principal for an investment with regular payments and a constant interest rate for a given period." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_ZINSZ );
+ 6; 0; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Period" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Periods. The periods for which the compounded interest is to be calculated. P = 1 denotes for the first period, P = NPER for the last one." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "pv" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Present value. The current value of a series of payments" ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Future value. The value (end value) to be attained after the final payment." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function KAPZ #*=-
+ Resource SC_OPCODE_KAPZ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Repayment. Calculates the repayment amount for a period for an investment whereby the payments are at regular intervals and the interest rate constant." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_KAPZ );
+ 6; 0; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The interest rate per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Period" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Period. The period for which the repayments are to be calculated. Per = 1 denotes for the first period, P = NPER for the last" ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "PV" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The present value. The present value or the amount the annuity is currently worth." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Future value. The value (end value) attained after the last payment has been made." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function KUMKAPITAL #*=-
+ Resource SC_OPCODE_KUM_KAP_Z
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Cumulative Capital. Calculates the total amount of the repayment share in a period for an investment with constant interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_KUMKAPITAL );
+ 6; 0; 0; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "PV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The present value. The present value or the amount the annuity is currently worth." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "S" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The start period. The first period to be taken into account. A = 1 denotes the very first period." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "E" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "End period. The last period to be taken into account." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function KUMZINSZ #*=-
+ Resource SC_OPCODE_KUM_ZINS_Z
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Cumulative compounded interest. Calculates the total amount of the interest share in a period for an investment with a constant interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_KUMZINSZ );
+ 6; 0; 0; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of interest per period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "NPER" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Payment period. The total number of periods in which the annuity (pension) is paid." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "pv" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The present value. The present value or the amount the annuity is currently worth." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "S" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The start period. The first period to be taken into account. A = 1 denotes the very first period." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "E" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "The end period. The last period to be taken into account." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "Type = 1 denotes due at the beginning of the period, = 0 at the end." ;
+ };
+ };
+ // -=*# Resource for function DIA #*=-
+ Resource SC_OPCODE_DIA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the arithmetically declining value of an asset (depreciation) for a specified period." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_DIA );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Cost" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Acquisition costs. The initial cost of the asset." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Salvage" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Salvage: The remaining value of the asset at the end of its life." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Life" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Useful life. The number of periods in the useful life of the asset." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Period" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Period. The depreciation period which must have the same time unit as average useful life." ;
+ };
+ };
+ // -=*# Resource for function LIA #*=-
+ Resource SC_OPCODE_LIA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the linear depreciation per period." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_LIA );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Cost" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Acquisition cost. The initial cost of an asset." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Salvage" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Salvage: The remaining value of the asset at the end of its life." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Life" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Useful life. The number of periods in the useful life of the asset." ;
+ };
+ };
+ // -=*# Resource for function GDA #*=-
+ Resource SC_OPCODE_GDA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the depreciation of an asset for a specific period using the double-declining balance method or declining balance factor." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_GDA );
+ 5; 0; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Cost" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Acquisition costs. The initial cost of the asset." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Salvage" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Salvage: The remaining value of the asset at the end of its life." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Life" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Useful life. The number of periods in the useful life of the asset." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Period" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Period. The depreciation period in the same time unit as the average useful life entry." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "Factor" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Factor. The factor for balance decline. F = 2 means a double declining balance factor" ;
+ };
+ };
+ // -=*# Resource for function GDA2 #*=-
+ Resource SC_OPCODE_GDA_2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the real depreciation of an asset for a specified period using the fixed-declining balance method." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_GDA2 );
+ 5; 0; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Cost" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Acquisition costs: The initial cost of the asset." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Salvage" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Salvage: The remaining value of the asset at the end of its life." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Life" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Useful life. The number of periods in the useful life of the asset." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Period" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Periods: The period for which the depreciation is calculated. The time unit used for period must be the same as that for the useful life." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "month" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "Months: The number of months in the first year of depreciation." ;
+ };
+ };
+ // -=*# Resource for function VDB #*=-
+ Resource SC_OPCODE_VBD
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Variable declining balance. Returns the declining balance depreciation for a particular period." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_VDB );
+ 7; 0; 0; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Cost" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Cost. The initial cost of the asset." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Salvage" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Salvage. The salvage value of an asset at the end of its useful life." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Life" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Useful life. The number of periods in the useful life of the asset." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "S" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Start. The first period for depreciation in the same time unit as the useful life." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "end" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "End. The last period of the depreciation using the same time unit as for the useful life." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [ en-US ] = "Factor" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "Factor. The factor for the reduction of the depreciation. F = 2 denotes double rate depreciation." ;
+ };
+ String 14 // Name of Parameter 7
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 15 // Description of Parameter 7
+ {
+ Text [ en-US ] = "Do not alter. Type = 1 denotes switch to linear depreciation, type = 0 do not switch." ;
+ };
+ };
+ // -=*# Resource for function EFFEKTIV #*=-
+ Resource SC_OPCODE_EFFEKTIV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the annual net interest rate for a nominal interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_EFFEKTIV );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "NOM" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Nominal Interest" ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "P" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Periods. The number of interest payments per year." ;
+ };
+ };
+ // -=*# Resource for function NOMINAL #*=-
+ Resource SC_OPCODE_NOMINAL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the yearly nominal interest rate as an effective interest rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_NOMINAL );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "effect_rate" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The effective interest rate" ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "npery" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Periods. The number of interest payment per year." ;
+ };
+ };
+ // -=*# Resource for function NBW #*=-
+ Resource SC_OPCODE_NBW
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Net present value. Calculates the net present value of an investment based on a series of periodic payments and a discount rate." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_NBW );
+ VAR_ARGS+1; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "RATE" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The rate of discount for one period." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "value " ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Value 1, value 2,... are 1 to 30 arguments representing payments and income." ;
+ };
+ };
+ // -=*# Resource for function IKV #*=-
+ Resource SC_OPCODE_IKV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the actuarial rate of interest of an investment excluding costs or profits." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_IKV );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Values" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "An array or reference to cells whose contents correspond to the payments. " ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Guess" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Guess. An estimated value of the rate of return to be used for the iteration calculation." ;
+ };
+ };
+ // -=*# Resource for function QIKV/MIRR #*=-
+ Resource SC_OPCODE_MIRR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the modified internal rate of return for a series of investments.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_QIKV );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Values";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "An array or reference to cells whose contents correspond to the payments.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "investment";
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Interest rate for investments (the negative values in the array).";
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "reinvest_rate";
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "interest rate for reinvestments (the positive values in the array).";
+ };
+ };
+ // -=*# Resource for function ISPMT #*=-
+ Resource SC_OPCODE_ISPMT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the amount of interest for constant amortization rates.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_ISPMT );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "rate";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Interest rate for a single amortization rate.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Period";
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Number of amortization periods for the calculation of the interest.";
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "total_periods";
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Sum total of amortization periods.";
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "invest";
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Amount of the investment.";
+ };
+ };
+ // -=*# Resource for function LAUFZEIT #*=-
+ Resource SC_OPCODE_LAUFZ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Duration. Calculates the number of periods required by an investment to attain the desired value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_LAUFZEIT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "RATE" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The constant rate of interest." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "pv" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The present value. The current value of the investment." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The future value of the investment." ;
+ };
+ };
+ // -=*# Resource for function ZGZ #*=-
+ Resource SC_OPCODE_ZGZ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Interest. Calculates the interest rate which represents the rate of return from an investment." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_FINANZ;
+ U2S( HID_FUNC_ZGZ );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "P" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number of periods used in the calculation." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "pv" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Present value. The current value of the investment." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "FV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The future value of the investment." ;
+ };
+ };
+ // -=*# Resource for function ISTBEZUG #*=-
+ Resource SC_OPCODE_IS_REF
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value is a reference." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTBEZUG );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTFEHL #*=-
+ Resource SC_OPCODE_IS_ERR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if the value is an error value not equal to #N/A." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTFEHL );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTFEHLER #*=-
+ Resource SC_OPCODE_IS_ERROR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if the value is an error value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTFEHLER );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTLEER #*=-
+ Resource SC_OPCODE_IS_EMPTY
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value refers to an empty cell." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTLEER );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTLOG #*=-
+ Resource SC_OPCODE_IS_LOGICAL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if the value carries a logical number format." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTLOG );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTNV #*=-
+ Resource SC_OPCODE_IS_NV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value equals #N/A." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTNV );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTKTEXT #*=-
+ Resource SC_OPCODE_IS_NON_STRING
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if the value is not text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTKTEXT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTTEXT #*=-
+ Resource SC_OPCODE_IS_STRING
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value is text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTTEXT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTZAHL #*=-
+ Resource SC_OPCODE_IS_VALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value is a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTZAHL );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTFORMEL #*=-
+ Resource SC_OPCODE_IS_FORMULA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if the cell is a formula cell." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ISTFORMEL );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The cell to be checked." ;
+ };
+ };
+ // -=*# Resource for function FORMEL #*=-
+ Resource SC_OPCODE_FORMULA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the formula of a formula cell.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_FORMEL );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Reference";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The formula cell.";
+ };
+ };
+ // -=*# Resource for function N #*=-
+ Resource SC_OPCODE_N
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a value to a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_N );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be interpreted as a number." ;
+ };
+ };
+ // -=*# Resource for function NV #*=-
+ Resource SC_OPCODE_NO_VALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Not available. Returns the error value #N/A." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_NV );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function TYP #*=-
+ Resource SC_OPCODE_TYPE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Defines the data type of a value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_TYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the data type is to be determined." ;
+ };
+ };
+ // -=*# Resource for function CELL/ZELLE #*=-
+ Resource SC_OPCODE_CELL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines information about address, formatting or contents of a cell.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_ZELLE );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "info_type";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "String that specifies the type of information.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Reference";
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The position of the cell you want to examine.";
+ };
+ };
+ // -=*# Resource for function AKTUELL #*=-
+ Resource SC_OPCODE_CURRENT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the current value of the formula at the present location. " ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_AKTUELL );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function FALSCH #*=-
+ Resource SC_OPCODE_FALSE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Defines the logical value as FALSE." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_LOGIC;
+ U2S( HID_FUNC_FALSCH );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function NICHT #*=-
+ Resource SC_OPCODE_NOT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Reverses the value of the argument." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_LOGIC;
+ U2S( HID_FUNC_NICHT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Logical value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "An expression that can be either TRUE or FALSE." ;
+ };
+ };
+ // -=*# Resource for function WAHR #*=-
+ Resource SC_OPCODE_TRUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the logical value TRUE." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_LOGIC;
+ U2S( HID_FUNC_WAHR );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function WENN #*=-
+ Resource SC_OPCODE_IF
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Specifies a logical test to be performed." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_LOGIC;
+ U2S( HID_FUNC_WENN );
+ 3; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Test" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Any value or expression which can be either TRUE or FALSE." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Then_value" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The result of the function if the logical test returns a TRUE." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Otherwise_value" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The result of the function if the logical test returns FALSE." ;
+ };
+ };
+ // -=*# Resource for function ODER #*=-
+ Resource SC_OPCODE_OR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if an argument is TRUE." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_LOGIC;
+ U2S( HID_FUNC_ODER );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Logical value " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Logical value 1, logical value 2,... are 1 to 30 conditions to be tested and which return either TRUE or FALSE." ;
+ };
+ };
+ // -=*# Resource for function UND #*=-
+ Resource SC_OPCODE_AND
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if all arguments are TRUE." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_LOGIC;
+ U2S( HID_FUNC_UND );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Logical value " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Logical value 1, logical value 2;...are 1 to 30 conditions to be tested and each returns either TRUE or FALSE." ;
+ };
+ };
+ // -=*# Resource for function ABS #*=-
+ Resource SC_OPCODE_ABS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Absolute value of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ABS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number whose absolute value is to be returned." ;
+ };
+ };
+ // -=*# Resource for function POTENZ #*=-
+ Resource SC_OPCODE_POWER
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a^b, base a raised to the power of exponent b." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_POTENZ );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Base" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The base a of the power a^b." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Exponent" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The exponent b of the power a^b." ;
+ };
+ };
+ // -=*# Resource for function ANZAHLLEEREZELLEN #*=-
+ Resource SC_OPCODE_COUNT_EMPTY_CELLS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Counts the blank cells in a specified range." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ANZAHLLEEREZELLEN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "range" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range in which empty cells are to be counted." ;
+ };
+ };
+ // -=*# Resource for function PI #*=-
+ Resource SC_OPCODE_PI
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the value of the number Pi." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_PI );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function SUMME #*=-
+ Resource SC_OPCODE_SUM
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sum of all arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_SUMME );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 arguments whose total is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function QUADRATESUMME #*=-
+ Resource SC_OPCODE_SUM_SQ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sum of the squares of the arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_QUADRATESUMME );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2,... are 1 to 30 arguments for which the sum of the squares is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function PRODUKT #*=-
+ Resource SC_OPCODE_PRODUCT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Multiplies the arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_PRODUKT );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 arguments to be multiplied and a result returned." ;
+ };
+ };
+ // -=*# Resource for function SUMMEWENN #*=-
+ Resource SC_OPCODE_SUM_IF
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Totals the arguments that meet the conditions." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_SUMMEWENN );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "range" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range to be evaluated by the criteria given." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "criteria" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The cell range in which the search criteria are given." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "sum_range" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The range from which the values are to be totalled." ;
+ };
+ };
+ // -=*# Resource for function ZÄHLENWENN #*=-
+ Resource SC_OPCODE_COUNT_IF
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Counts the arguments which meet the set conditions." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ZAEHLENWENN );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "range" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The range of cells on which the criteria are to be applied." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "criteria" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The cell range in which the search criteria are given." ;
+ };
+ };
+ // -=*# Resource for function WURZEL #*=-
+ Resource SC_OPCODE_SQRT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the square root of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_WURZEL );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A positive value for which the square root is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function ZUFALLSZAHL #*=-
+ Resource SC_OPCODE_RANDOM
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a random number between 0 and 1." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ZUFALLSZAHL );
+ 0;
+ 0;
+ };
+ };
+ // -=*# Resource for function ISTGERADE #*=-
+ Resource SC_OPCODE_IS_EVEN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value is an even integer." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ISTGERADE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function ISTUNGERADE #*=-
+ Resource SC_OPCODE_IS_ODD
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns TRUE if value is an odd integer." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ISTUNGERADE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be tested." ;
+ };
+ };
+ // -=*# Resource for function KOMBINATIONEN #*=-
+ Resource SC_OPCODE_KOMBIN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the number of combinations for elements without repetition." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_KOMBINATIONEN );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The total number of elements." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "number_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of elements selected." ;
+ };
+ };
+ // -=*# Resource for function KOMBINATIONEN2 #*=-
+ Resource SC_OPCODE_KOMBIN_2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the number of combinations of elements including repetition." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_KOMBINATIONEN2 );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The total number of elements." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "number_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of elements selected." ;
+ };
+ };
+ // -=*# Resource for function ARCCOS #*=-
+ Resource SC_OPCODE_ARC_COS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the arccosine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCCOS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value between -1 and 1 for which the arccosine is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCSIN #*=-
+ Resource SC_OPCODE_ARC_SIN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the arcsine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCSIN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value between -1 and 1 for which the arcsine is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCCOSHYP #*=-
+ Resource SC_OPCODE_ARC_COS_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse hyperbolic cosine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCOSHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value greater than or equal to 1 for which the hyperbolic cosine is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCSINHYP #*=-
+ Resource SC_OPCODE_ARC_SIN_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse hyperbolic sine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARSINHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the inverse hyperbolic sine is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCCOT #*=-
+ Resource SC_OPCODE_ARC_COT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse cotangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCCOT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the inverse cotangent is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCTAN #*=-
+ Resource SC_OPCODE_ARC_TAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the arctangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCTAN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the arctangent is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCCOTHYP #*=-
+ Resource SC_OPCODE_ARC_COT_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse hyperbolic cotangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCOTHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value smaller than -1 or greater than 1 for which the inverse hyperbolic cotangent is to be returned." ;
+ };
+ };
+ // -=*# Resource for function ARCTANHYP #*=-
+ Resource SC_OPCODE_ARC_TAN_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse hyperbolic tangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARTANHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value between -1 and 1 for which the inverse hyperbolic tangent is to be returned." ;
+ };
+ };
+ // -=*# Resource for function COS #*=-
+ Resource SC_OPCODE_COS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the cosine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_COS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The angle in the radians for which the cosine is to be returned." ;
+ };
+ };
+ // -=*# Resource for function SIN #*=-
+ Resource SC_OPCODE_SIN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_SIN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The angle in radians for which the sine is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function COT #*=-
+ Resource SC_OPCODE_COT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the cotangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_COT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The angle in radians whose cotangent value is to be returned." ;
+ };
+ };
+ // -=*# Resource for function TAN #*=-
+ Resource SC_OPCODE_TAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the tangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_TAN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The angle in radians for which the tangent is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function COSHYP #*=-
+ Resource SC_OPCODE_COS_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the hyperbolic cosine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_COSHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the hyperbolic cosine is to be returned." ;
+ };
+ };
+ // -=*# Resource for function SINHYP #*=-
+ Resource SC_OPCODE_SIN_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the hyperbolic sine of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_SINHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the hyperbolic sine is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function COTHYP #*=-
+ Resource SC_OPCODE_COT_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the hyperbolic cotangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_COTHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value not equal to 0 for which the hyperbolic cotangent is to be returned." ;
+ };
+ };
+ // -=*# Resource for function TANHYP #*=-
+ Resource SC_OPCODE_TAN_HYP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the hyperbolic tangent of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_TANHYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the hyperbolic tangent is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function ARCTAN2 #*=-
+ Resource SC_OPCODE_ARC_TAN_2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the arctangent for the specified coordinates." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ARCTAN2 );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number_x" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for the x coordinate." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "number_y" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The value for the y coordinate." ;
+ };
+ };
+ // -=*# Resource for function DEG #*=-
+ Resource SC_OPCODE_DEG
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a radian to degrees" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_DEG );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The angle in a radian" ;
+ };
+ };
+ // -=*# Resource for function RAD #*=-
+ Resource SC_OPCODE_RAD
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts degrees to radians" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_RAD );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The angle in degrees." ;
+ };
+ };
+ // -=*# Resource for function EXP #*=-
+ Resource SC_OPCODE_EXP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the exponent for basis e." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_EXP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The exponent applied to base e." ;
+ };
+ };
+ // -=*# Resource for function LOG #*=-
+ Resource SC_OPCODE_LOG
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the logarithm to any specified base." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_LOG );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value greater than 0 for which the logarithm is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Base" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The base of the logarithm. If omitted, the base is regarded as 10." ;
+ };
+ };
+ // -=*# Resource for function LN #*=-
+ Resource SC_OPCODE_LN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the natural logarithm of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_LN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value greater than 0 for which the natural logarithm is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function LOG10 #*=-
+ Resource SC_OPCODE_LOG10
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the base-10 logarithm of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_LOG10 );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "A value greater than 0 for which the logarithm is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function FAKULTÄT #*=-
+ Resource SC_OPCODE_FACT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the factorial of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_FAKULTAET );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number for which the factorial is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function REST #*=-
+ Resource SC_OPCODE_MOD
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the remainder of a division." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_REST );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Dividend" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be divided." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Divisor" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number by which the dividend is divided." ;
+ };
+ };
+ // -=*# Resource for function VORZEICHEN #*=-
+ Resource SC_OPCODE_PLUS_MINUS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the algebraic sign of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_VORZEICHEN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number for which the algebraic sign is to be determined." ;
+ };
+ };
+ // -=*# Resource for function TEILERGEBNIS #*=-
+ Resource SC_OPCODE_SUB_TOTAL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates subtotals in a spreadsheet." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_TEILERGEBNIS );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Function" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Function index. Is an index of the possible functions Total, Max, ..." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "range " ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The cells of the range which are to be taken into account." ;
+ };
+ };
+ // -=*# Resource for function GANZZAHL #*=-
+ Resource SC_OPCODE_INT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a number down to the nearest integer." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_GANZZAHL );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded down." ;
+ };
+ };
+ // -=*# Resource for function KÃœRZEN #*=-
+ Resource SC_OPCODE_TRUNC
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Truncates the decimal places of a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_KUERZEN );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be truncated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "count" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of places after the decimal point that are not to be truncated." ;
+ };
+ };
+ // -=*# Resource for function RUNDEN #*=-
+ Resource SC_OPCODE_ROUND
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a number to a predefined accuracy." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_RUNDEN );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "count" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of places to which a number is to be rounded." ;
+ };
+ };
+ // -=*# Resource for function AUFRUNDEN #*=-
+ Resource SC_OPCODE_ROUND_UP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a number up to the predefined accuracy." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_AUFRUNDEN );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded up." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "count" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of places to which a number is to be rounded." ;
+ };
+ };
+ // -=*# Resource for function ABRUNDEN #*=-
+ Resource SC_OPCODE_ROUND_DOWN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a number down to a predefined accuracy." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_ABRUNDEN );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded down." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "count" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of places down to which a number is to be rounded." ;
+ };
+ };
+ // -=*# Resource for function GERADE #*=-
+ Resource SC_OPCODE_EVEN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a positive number up and negative number down to the nearest even integer.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_GERADE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded up." ;
+ };
+ };
+ // -=*# Resource for function UNGERADE #*=-
+ Resource SC_OPCODE_ODD
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a positive number up and negative number down to the nearest odd integer.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_UNGERADE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded up." ;
+ };
+ };
+ // -=*# Resource for function OBERGRENZE #*=-
+ Resource SC_OPCODE_CEIL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds a number up to the nearest multiple of significance." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_OBERGRENZE );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded up." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Significance" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number to whose multiple the value is rounded." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Mode" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "If given and not equal to zero then rounded up according to amount when a negative number and significance." ;
+ };
+ };
+ // -=*# Resource for function UNTERGRENZE #*=-
+ Resource SC_OPCODE_FLOOR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Rounds number down to the nearest multiple of significance." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_UNTERGRENZE );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be rounded down." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Significance" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number to whose multiple the value is to be rounded down." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Mode" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "If given and not equal to zero then rounded down according to amount when a negative number and significance." ;
+ };
+ };
+ // -=*# Resource for function GGT #*=-
+ Resource SC_OPCODE_GGT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Greatest Common Divisor" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_GGT );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Integer " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Integer 1; integer 2,... are integers for which the greatest common divisor is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function KGV #*=-
+ Resource SC_OPCODE_KGV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Lowest common multiple" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_KGV );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Integer " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Integer 1; integer 2,... are integers whose smallest common multiple is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function MTRANS #*=-
+ Resource SC_OPCODE_MAT_TRANS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Array transposition. Exchanges the rows and columns of an array." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_MTRANS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array in which the rows and columns have been transposed." ;
+ };
+ };
+ // -=*# Resource for function MMULT #*=-
+ Resource SC_OPCODE_MAT_MULT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Array multiplication. Returns the product of two arrays." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_MMULT );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first array for the array product." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second array having the same number of rows as the first array has columns." ;
+ };
+ };
+ // -=*# Resource for function MDET #*=-
+ Resource SC_OPCODE_MAT_DET
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the array determinant." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_MDET );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array for which the determinant is to be determined." ;
+ };
+ };
+ // -=*# Resource for function MINV #*=-
+ Resource SC_OPCODE_MAT_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse of an array." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_MINV );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array to be inverted." ;
+ };
+ };
+ // -=*# Resource for function EINHEITSMATRIX #*=-
+ Resource SC_OPCODE_MATRIX_UNIT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the unitary square array of a certain size." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_EINHEITSMATRIX );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Dimensions" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The size of the unitary array." ;
+ };
+ };
+ // -=*# Resource for function SUMMENPRODUKT #*=-
+ Resource SC_OPCODE_SUM_PRODUCT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "(Inner products) Returns the sum of the products of array arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_SUMMENPRODUKT );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Array " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Array 1, array 2, ... are up to 30 arrays whose arguments are to be multiplied." ;
+ };
+ };
+ // -=*# Resource for function SUMMEX2MY2 #*=-
+ Resource SC_OPCODE_SUM_X2MY2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sum of the difference of squares of two arrays." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_SUMMEX2MY2 );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array_x" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "First array where the square of the arguments are totalled." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "array_y" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Second array where the square of the arguments is to be subtracted." ;
+ };
+ };
+ // -=*# Resource for function SUMMEX2PY2 #*=-
+ Resource SC_OPCODE_SUM_X2DY2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the total of the square sum of two arrays." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_SUMMEX2PY2 );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array_x" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "First array where the square of the arguments are totalled." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "array_y" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Second array where the square of the arguments is to be totalled." ;
+ };
+ };
+ // -=*# Resource for function SUMMEXMY2 #*=-
+ Resource SC_OPCODE_SUM_XMY2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sum of squares of differences of two arrays." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_SUMMEXMY2 );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array_x" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "First array for forming argument differences." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "array_y" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Second array for forming the argument differences." ;
+ };
+ };
+};
+
+Resource RID_SC_FUNCTION_DESCRIPTIONS2
+{
+ // -=*# Resource for function HÄUFIGKEIT #*=-
+ Resource SC_OPCODE_FREQUENCY
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a frequency distribution as a vertical array." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_HAEUFIGKEIT );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "classes" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The array for forming classes." ;
+ };
+ };
+ // -=*# Resource for function RGP #*=-
+ Resource SC_OPCODE_RGP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates parameters of the linear regression as an array." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_RGP );
+ 4; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Linear_type" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "If type = 0 the linears will be calculated through the zero point, or else moved linears." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "stats" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If parameter = 0 then only the regression coefficient will be calculated, otherwise other values as well." ;
+ };
+ };
+ // -=*# Resource for function RKP #*=-
+ Resource SC_OPCODE_RKP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the parameters of the exponential regression curve as an array." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_RKP );
+ 4; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Function_type" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "If type = 0 then the functions will be calculated in the form of y=m^x, or also functions y=b*m^x." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "stats" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If parameter = 0 then only the regression coefficient will be calculated, otherwise other values as well." ;
+ };
+ };
+ // -=*# Resource for function TREND #*=-
+ Resource SC_OPCODE_TREND
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates points along a regression line." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_TREND );
+ 4; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array as the basis for the regression." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "new data_X" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The array of X data for recalculating the values." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Linear_type" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If type = 0 the linears will be calculated through the zero point, or else moved linears." ;
+ };
+ };
+ // -=*# Resource for function VARIATION #*=-
+ Resource SC_OPCODE_GROWTH
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates points on the exponential regression function." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATRIX;
+ U2S( HID_FUNC_VARIATION );
+ 4; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array as the basis for the regression." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "new_data_X" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The array of X data for recalculating the values." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Function_type" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If type = 0 then the functions will be calculated in the form of y=m^x, or also functions y=b*m^x." ;
+ };
+ };
+ // -=*# Resource for function ANZAHL #*=-
+ Resource SC_OPCODE_COUNT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Counts how many numbers are in the list of arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_ANZAHL );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1, value 2, ... are 1 to 30 arguments containing different data types but where only numbers are counted." ;
+ };
+ };
+ // -=*# Resource for function ANZAHL2 #*=-
+ Resource SC_OPCODE_COUNT_2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Counts how many values are in the list of arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_ANZAHL2 );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1, value 2, ... are 1 to 30 arguments representing the values to be counted." ;
+ };
+ };
+ // -=*# Resource for function MAX #*=-
+ Resource SC_OPCODE_MAX
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the maximum value in a list of arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MAX );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments for which the largest number is to be determined." ;
+ };
+ };
+ // -=*# Resource for function MAXA #*=-
+ Resource SC_OPCODE_MAX_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the maximum value in a list of arguments. Text is evaluated as Zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MAXA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1, value 2, are 1 to 30 arguments whose largest value is to be determined.";
+ };
+ };
+ // -=*# Resource for function MIN #*=-
+ Resource SC_OPCODE_MIN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the minimum value in a list of arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MIN );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments for which the smallest number is to be determined." ;
+ };
+ };
+ // -=*# Resource for function MINA #*=-
+ Resource SC_OPCODE_MIN_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the smallest value in a list of arguments. Text is evaluated as zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MINA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1; value 2;... are 1 to 30 arguments whose smallest number is to be determined.";
+ };
+ };
+ // -=*# Resource for function VARIANZ #*=-
+ Resource SC_OPCODE_VAR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the variance based on a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_VARIANZ );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample of a population." ;
+ };
+ };
+ // -=*# Resource for function VARIANZ #*=-
+ Resource SC_OPCODE_VAR_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the variance based on a sample. Text is evaluated as zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_VARIANZA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1; value 2; ... are 1 to 30 arguments representing a sample taken from a basic total population.";
+ };
+ };
+ // -=*# Resource for function VARIANZEN #*=-
+ Resource SC_OPCODE_VAR_P
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates variance based on the entire population." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_VARIANZEN );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which represent a population." ;
+ };
+ };
+ // -=*# Resource for function VARIANZENA #*=-
+ Resource SC_OPCODE_VAR_P_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the variance based on the entire population. Text is evaluated as zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_VARIANZENA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1; value 2;... are 1 to 30 arguments representing a population.";
+ };
+ };
+ // -=*# Resource for function STABW #*=-
+ Resource SC_OPCODE_ST_DEV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the standard deviation based on a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STABW );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample of a population." ;
+ };
+ };
+ // -=*# Resource for function STABWA #*=-
+ Resource SC_OPCODE_ST_DEV_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the standard deviation based on a sample. Text is evaluated as zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STABWA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1; value 2; ... are 1 to 30 arguments representing a sample taken from a basic total population.";
+ };
+ };
+ // -=*# Resource for function STABWN #*=-
+ Resource SC_OPCODE_ST_DEV_P
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the standard deviation based on the entire population." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STABWN );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample of a population." ;
+ };
+ };
+ // -=*# Resource for function STABWNA #*=-
+ Resource SC_OPCODE_ST_DEV_P_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the standard deviation based on the entire population. Text is evaluated as zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STABWNA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1; value 2;... are 1 to 30 arguments corresponding to a population.";
+ };
+ };
+ // -=*# Resource for function MITTELWERT #*=-
+ Resource SC_OPCODE_AVERAGE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the average of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MITTELWERT );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2;...are 1 to 30 numeric arguments representing a population sample." ;
+ };
+ };
+ // -=*# Resource for function MITTELWERTA #*=-
+ Resource SC_OPCODE_AVERAGE_A
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the average value for a sample. Text is evaluated as zero.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MITTELWERTA );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value ";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value 1; value 2; ... are 1 to 30 arguments representing a sample taken from a basic total population.";
+ };
+ };
+ // -=*# Resource for function SUMQUADABW #*=-
+ Resource SC_OPCODE_DEV_SQ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the sum of squares of deviations from the sample mean value" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_SUMQUADABW );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample." ;
+ };
+ };
+ // -=*# Resource for function MITTELABW #*=-
+ Resource SC_OPCODE_AVE_DEV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the average of the absolute deviations of a sample from the mean." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MITTELABW );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2;...are 1 to 30 numerical arguments representing a sample." ;
+ };
+ };
+ // -=*# Resource for function SCHIEFE #*=-
+ Resource SC_OPCODE_SCHIEFE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the skewness of a distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_SCHIEFE );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments portraying a sample of the distribution." ;
+ };
+ };
+ // -=*# Resource for function KURT #*=-
+ Resource SC_OPCODE_KURT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the kurtosis of a distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KURT );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments, representing a sample of the distribution." ;
+ };
+ };
+ // -=*# Resource for function GEOMITTEL #*=-
+ Resource SC_OPCODE_GEO_MEAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the geometric mean of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GEOMITTEL );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample." ;
+ };
+ };
+ // -=*# Resource for function HARMITTEL #*=-
+ Resource SC_OPCODE_HAR_MEAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the harmonic mean of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_HARMITTEL );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample." ;
+ };
+ };
+ // -=*# Resource for function MODALWERT #*=-
+ Resource SC_OPCODE_MODAL_VALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the most common value in a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MODALWERT );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample." ;
+ };
+ };
+ // -=*# Resource for function MEDIAN #*=-
+ Resource SC_OPCODE_MEDIAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the median of a given sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_MEDIAN );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Number 1, number 2, ... are 1 to 30 numerical arguments which portray a sample." ;
+ };
+ };
+ // -=*# Resource for function QUANTIL #*=-
+ Resource SC_OPCODE_PERCENTILE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the alpha quantile of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_QUANTIL );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The percentage rate of the quantile between 0 and 1." ;
+ };
+ };
+ // -=*# Resource for function QUARTILE #*=-
+ Resource SC_OPCODE_QUARTILE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the quartile of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_QUARTILE );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The type of the quartile (0 = MIN, 1 = 25%, 2 = 50 %, 3 = 75 %, 4 =MAX)." ;
+ };
+ };
+ // -=*# Resource for function KGRÖSSTE #*=-
+ Resource SC_OPCODE_LARGE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the k-th largest value of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KGROESSTE );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Rank_c" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The ranking of the value." ;
+ };
+ };
+ // -=*# Resource for function KKLEINSTE #*=-
+ Resource SC_OPCODE_SMALL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the k-th smallest value of a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KKLEINSTE );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Rank_c" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The ranking of the value." ;
+ };
+ };
+ // -=*# Resource for function QUANTILSRANG #*=-
+ Resource SC_OPCODE_PERCENT_RANK
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the percentage rank of a value in a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_QUANTILSRANG );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The value for which percentage ranking is to be determined." ;
+ };
+ };
+ // -=*# Resource for function RANG #*=-
+ Resource SC_OPCODE_RANK
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the ranking of a value in a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_RANG );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the rank is to be determined." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Data" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Sequence order: 0 or omitted means descending, any other value than 0 means ascending." ;
+ };
+ };
+ // -=*# Resource for function GESTUTZTMITTEL #*=-
+ Resource SC_OPCODE_TRIM_MEAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the mean of a sample without including the marginal values." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GESTUTZTMITTEL );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array of the data in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The percentage of marginal data that is not to be taken into account." ;
+ };
+ };
+ // -=*# Resource for function WAHRSCHBEREICH #*=-
+ Resource SC_OPCODE_PROB
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the discreet probability of an interval." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_WAHRSCHBEREICH );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The sample data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "probability" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The array of the associated probabilities." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Start" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The start of the value interval whose probabilities is to be totalled." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "End" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The end of the value interval where the probabilities are to be totalled." ;
+ };
+ };
+ // -=*# Resource for function B #*=-
+ Resource SC_OPCODE_B
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the probability of a trial result using binomial distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_B );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "trials" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number of trials." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "SP" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The individual probability of a trial result." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "T_1" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Lower limit for the number of trials." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "T_2" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Upper limit for the number of trials." ;
+ };
+ };
+ // -=*# Resource for function PHI #*=-
+ Resource SC_OPCODE_PHI
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the distribution function for a standard normal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_PHI );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the standard normal distribution is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function GAUSS #*=-
+ Resource SC_OPCODE_GAUSS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the integral values of the standard normal cumulative distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GAUSS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the integral value of the standard normal distribution is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function FISHER #*=-
+ Resource SC_OPCODE_FISHER
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the Fisher transformation." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_FISHER );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be transformed (-1 < VALUE < 1)." ;
+ };
+ };
+ // -=*# Resource for function FISHERINV #*=-
+ Resource SC_OPCODE_FISHER_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the inverse of the Fisher transformation." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_FISHERINV );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value that is to be transformed back." ;
+ };
+ };
+ // -=*# Resource for function BINOMVERT #*=-
+ Resource SC_OPCODE_BINOM_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the binomial distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_BINOMVERT );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "X" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number of successes in a series of trials." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "trials" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The total number of trials." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "SP" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The success probability of a trial." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "C" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Cumulated. C=0 calculates the individual probability, C=1 the cumulated probability." ;
+ };
+ };
+ // -=*# Resource for function NEGBINOMVERT #*=-
+ Resource SC_OPCODE_NEG_BINOM_VERT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the negative binomial distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_NEGBINOMVERT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "X" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number of failures in the trial range." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "R" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of successes in the trial sequence." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "SP" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The success probability of a trial." ;
+ };
+ };
+ // -=*# Resource for function KRITBINOM #*=-
+ Resource SC_OPCODE_KRIT_BINOM
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Border arguments of the binomial distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KRITBINOM );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "trials" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The total number of trials." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "SP" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The success probability of a trial." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "alpha" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The border probability that is attained or exceeded." ;
+ };
+ };
+ // -=*# Resource for function POISSON #*=-
+ Resource SC_OPCODE_POISSON_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the Poisson distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_POISSON );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the Poisson distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mean" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Mean. The mean value of the Poisson distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Cumulative" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
+ };
+ };
+ // -=*# Resource for function NORMVERT #*=-
+ Resource SC_OPCODE_NORM_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the normal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_NORMVERT );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the normal distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Mean" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The mean value. The mean value of the normal distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Standard deviation. The standard deviation of the normal distribution." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "C" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
+ };
+ };
+ // -=*# Resource for function NORMINV #*=-
+ Resource SC_OPCODE_NORM_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse normal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_NORMINV );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse normal distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mean" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The mean value. The mean value of the normal distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Standard deviation. The standard deviation of the normal distribution." ;
+ };
+ };
+ // -=*# Resource for function STANDNORMVERT #*=-
+ Resource SC_OPCODE_STD_NORM_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "The values of the standard normal cumulative distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STANDNORMVERT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the standard normal distribution is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function STANDNORMINV #*=-
+ Resource SC_OPCODE_S_NORM_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse standard normal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STANDNORMINV );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse standard normal distribution is to be calculated." ;
+ };
+ };
+ // -=*# Resource for function LOGNORMVERT #*=-
+ Resource SC_OPCODE_LOG_NORM_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the log normal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_LOGNORMVERT );
+ 4; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the log normal distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mean" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The mean value of the log normal distribution. It is set to 0 if omitted." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The standard deviation of the log normal distribution. It is set to 1 if omitted." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US] = "Cumulative";
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
+ };
+ };
+ // -=*# Resource for function LOGINV #*=-
+ Resource SC_OPCODE_LOG_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse of the lognormal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_LOGINV );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse log normal distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mean" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Mean value. The mean value of the log normal distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Standard deviation. The standard deviation of the log normal distribution." ;
+ };
+ };
+ // -=*# Resource for function EXPONVERT #*=-
+ Resource SC_OPCODE_EXP_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the exponential distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_EXPONVERT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to which the exponential distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "lambda" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The parameters of the exponential distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "C" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ;
+ };
+ };
+ // -=*# Resource for function GAMMAVERT #*=-
+ Resource SC_OPCODE_GAMMA_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the value of the probability density function or the cumulative distribution function for the Gamma distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GAMMAVERT );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the gamma distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The Alpha parameter of the Gamma distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "beta" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The Beta parameter of the Gamma distribution." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Cumulative" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
+ };
+ };
+ // -=*# Resource for function GAMMAINV #*=-
+ Resource SC_OPCODE_GAMMA_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse gamma distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GAMMAINV );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse gamma distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The Alpha (shape) parameter of the Gamma distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "beta" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The Beta (scale) parameter of the Gamma distribution." ;
+ };
+ };
+ // -=*# Resource for function GAMMALN #*=-
+ Resource SC_OPCODE_GAMMA_LN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the natural logarithm of the gamma function." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GAMMALN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the natural logarithm of the gamma function is to be calculated." ;
+ };
+ };
+
+ // -=*# Resource for function GAMMA #*=-
+ Resource SC_OPCODE_GAMMA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the value of the Gamma function." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GAMMA );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the Gamma function is to be calculated." ;
+ };
+ };
+
+ // -=*# Resource for function BETAVERT #*=-
+ Resource SC_OPCODE_BETA_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the beta distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_BETAVERT );
+ 6; 0; 0; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the beta distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The Alpha parameter of the Beta distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "beta" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The Beta parameter of the Beta distribution." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Start" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The starting value for the value interval of the distribution." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "End" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "The final value for the value interval of the distribution." ;
+ };
+ String 12 // Name of Parameter 6
+ {
+ Text [en-US ] = "Cumulative" ;
+ };
+ String 13 // Description of Parameter 6
+ {
+ Text [ en-US ] = "0 or FALSE for probability density function, any other value or TRUE or omitted for cumulative distribution function.";
+ };
+ };
+ // -=*# Resource for function BETAINV #*=-
+ Resource SC_OPCODE_BETA_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse beta distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_BETAINV );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse beta distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The Alpha parameter of the Beta distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "beta" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The Beta parameter of the Beta distribution." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Start" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The starting value for the value interval of the distribution." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "End" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "The final value for the value interval of the distribution." ;
+ };
+ };
+ // -=*# Resource for function WEIBULL #*=-
+ Resource SC_OPCODE_WEIBULL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the values of the Weibull distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_WEIBULL );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the Weibull distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Alpha" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The Alpha parameter of the Weibull distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "beta" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The Beta parameter of the Weibull distribution." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "C" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ;
+ };
+ };
+ // -=*# Resource for function HYPGEOMVERT #*=-
+ Resource SC_OPCODE_HYP_GEOM_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the hypergeometric distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_HYPGEOMVERT );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "X" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number of successes in the sample." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "n_sample" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The size of the sample." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "successes" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The number of successes in the population." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "n_population" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The population size." ;
+ };
+ };
+ // -=*# Resource for function TVERT #*=-
+ Resource SC_OPCODE_T_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the t-distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_TVERT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the T distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "degrees_freedom" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom of the T distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "mode" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Mode = 1 calculates the one-tailed test, 2 = two-tailed distribution." ;
+ };
+ };
+ // -=*# Resource for function TINV #*=-
+ Resource SC_OPCODE_T_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse t-distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_TINV );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse T distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "degrees_freedom" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom of the T distribution." ;
+ };
+ };
+ // -=*# Resource for function FVERT #*=-
+ Resource SC_OPCODE_F_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the F probability distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_FVERT );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the F distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "degrees_freedom_1" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom in the numerator of the F distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "degrees_freedom_2" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The degrees of freedom in the denominator of the F distribution." ;
+ };
+ };
+ // -=*# Resource for function FINV #*=-
+ Resource SC_OPCODE_F_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse F distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_FINV );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse F distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "degrees_freedom_1" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom in the numerator of the F distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "degrees_freedom_2" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The degrees of freedom in the denominator of the F distribution." ;
+ };
+ };
+ // -=*# Resource for function CHIVERT #*=-
+ Resource SC_OPCODE_CHI_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the right-tail probability of the chi-square distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_CHIVERT );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the chi square distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "degrees_freedom" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom of the chi square distribution." ;
+ };
+ };
+
+ // -=*# Resource for function CHISQDIST #*=-
+ Resource SC_OPCODE_CHISQ_DIST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns left-tail probability of the cumulative distribution function or values of the probability density function of the chi-square distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_CHISQDIST );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value for which the probability density function or cumulative distribution function is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Degrees of Freedom" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom of the chi-square distribution." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Cumulative" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
+ };
+ };
+
+
+ // -=*# Resource for function CHIINV #*=-
+ Resource SC_OPCODE_CHI_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse of CHIDIST(x; DegreesOfFreedom)." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_CHIINV );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse chi square distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "degrees_freedom" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom of the chi square distribution." ;
+ };
+ };
+
+ // -=*# Resource for function CHISQINV #*=-
+ Resource SC_OPCODE_CHISQ_INV
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Values of the inverse of CHISQDIST(x;DegreesOfFreedom;TRUE())." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_CHISQINV );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Probability" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The probability value for which the inverse of the chi square distribution is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Degrees of Freedom" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The degrees of freedom of the chi square distribution." ;
+ };
+ };
+
+ // -=*# Resource for function STANDARDISIERUNG #*=-
+ Resource SC_OPCODE_STANDARD
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a random variable to a normalized value." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STANDARDISIERUNG );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be standardized." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mean" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The mean value used for moving." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The standard deviation used for scaling." ;
+ };
+ };
+ // -=*# Resource for function VARIATIONEN #*=-
+ Resource SC_OPCODE_VARIATIONEN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the number of permutations for a given number of elements without repetition." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_VARIATIONEN );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Count_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The total number of elements." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Count_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The selection number taken from the elements." ;
+ };
+ };
+ // -=*# Resource for function VARIATIONEN2 #*=-
+ Resource SC_OPCODE_VARIATIONEN_2
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the number of permutations for a given number of objects (repetition allowed)." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_VARIATIONEN2 );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Count_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The total number of elements." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Count_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The selection number taken from the elements." ;
+ };
+ };
+ // -=*# Resource for function KONFIDENZ #*=-
+ Resource SC_OPCODE_CONFIDENCE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a (1 alpha) confidence interval for a normal distribution." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KONFIDENZ );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "alpha" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The level of the confidence interval." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "STDEV" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The standard deviation of the population." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "size" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The size of the population." ;
+ };
+ };
+ // -=*# Resource for function GTEST #*=-
+ Resource SC_OPCODE_Z_TEST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the probability of observing a z-statistic greater than the one computed based on a sample." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_GTEST );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The given sample, drawn from a normally distributed population." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "mu" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The known mean of the population." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "sigma" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The known standard deviation of the population. If omitted, the standard deviation of the given sample is used." ;
+ };
+ };
+ // -=*# Resource for function CHITEST #*=-
+ Resource SC_OPCODE_CHI_TEST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the chi square independence test." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_CHITEST );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Data_B" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The observed data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_E" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The expected data array." ;
+ };
+ };
+ // -=*# Resource for function FTEST #*=-
+ Resource SC_OPCODE_F_TEST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the F test." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_FTEST );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first record array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second record array." ;
+ };
+ };
+ // -=*# Resource for function TTEST #*=-
+ Resource SC_OPCODE_T_TEST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the T test." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_TTEST );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first record array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second record array." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "mode" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Mode specifies the number of distribution tails to return. 1= one-tailed, 2 = two-tailed distribution" ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The type of the T test." ;
+ };
+ };
+ // -=*# Resource for function BESTIMMTHEITSMASS #*=-
+ Resource SC_OPCODE_RSQ
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the square of the Pearson product moment correlation coefficient." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_BESTIMMTHEITSMASS );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ };
+ // -=*# Resource for function ACHSENABSCHNITT #*=-
+ Resource SC_OPCODE_INTERCEPT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the intercept of the linear regression line and the Y axis." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_ACHSENABSCHNITT );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ };
+ // -=*# Resource for function STEIGUNG #*=-
+ Resource SC_OPCODE_SLOPE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the slope of the linear regression line." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STEIGUNG );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ };
+ // -=*# Resource for function STFEHLERYX #*=-
+ Resource SC_OPCODE_STEYX
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the standard error of the linear regression." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_STFEHLERYX );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ };
+ // -=*# Resource for function PEARSON #*=-
+ Resource SC_OPCODE_PEARSON
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the Pearson product moment correlation coefficient." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_PEARSON );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Data_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first record array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Data_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second record array." ;
+ };
+ };
+ // -=*# Resource for function KORREL #*=-
+ Resource SC_OPCODE_CORREL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the correlation coefficient." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KORREL );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Data_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first record array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Data_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second record array." ;
+ };
+ };
+ // -=*# Resource for function KOVAR #*=-
+ Resource SC_OPCODE_COVAR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the covariance." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_KOVAR );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Data_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first record array." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Data_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second record array." ;
+ };
+ };
+ // -=*# Resource for function SCHÄTZER #*=-
+ Resource SC_OPCODE_FORECAST
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a value along a linear regression" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_STATISTIC;
+ U2S( HID_FUNC_SCHAETZER );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The X value for which the Y value on the regression linear is to be calculated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "data_Y" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The Y data array." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "data_X" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The X data array." ;
+ };
+ };
+ // -=*# Resource for function ADRESSE #*=-
+ Resource SC_OPCODE_ADDRESS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the reference to a cell as text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_ADRESSE );
+ 5; 0; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "row" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The row number of the cell." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "column" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The column number of the cell." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "ABS" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Specifies whether absolute or relative referencing is to be used." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "A1" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The reference style: 0 or FALSE means R1C1 style, any other value or omitted means A1 style." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "sheet" ;
+ Text [ x-comment ] = "previously to OOo3.0 this was String resource RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_ADDRESS 8" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "The spreadsheet name of the cell reference." ;
+ Text [ x-comment ] = "previously to OOo3.0 this was String resource RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_ADDRESS 9" ;
+ };
+ };
+ // -=*# Resource for function BEREICHE #*=-
+ Resource SC_OPCODE_AREAS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the number of individual ranges that belong to a (multiple) range." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_BEREICHE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference to a (multiple) range." ;
+ };
+ };
+ // -=*# Resource for function WAHL #*=-
+ Resource SC_OPCODE_CHOSE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Selects a value from a list of up to 30 value arguments." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_WAHL );
+ VAR_ARGS+1; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Index" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The index of the value (1..30) selected." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "value " ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Value 1, value 2,... The list of arguments from which a value is chosen." ;
+ };
+ };
+ // -=*# Resource for function SPALTE #*=-
+ Resource SC_OPCODE_COLUMN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the internal column number of a reference." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_SPALTE );
+ 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference to a cell or a range." ;
+ };
+ };
+ // -=*# Resource for function ZEILE #*=-
+ Resource SC_OPCODE_ROW
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Defines the internal row number of a reference." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_ZEILE );
+ 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference to a cell or a range." ;
+ };
+ };
+ // -=*# Resource for function TABELLE #*=-
+ Resource SC_OPCODE_TABLE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the internal sheet number of a reference or a string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_TABELLE );
+ 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference to a cell or a range or the character string of a sheet name." ;
+ };
+ };
+ // -=*# Resource for function SPALTEN #*=-
+ Resource SC_OPCODE_COLUMNS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the number of columns in an array or reference." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_SPALTEN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array (reference) for which the number of columns is to be determined." ;
+ };
+ };
+ // -=*# Resource for function ZEILEN #*=-
+ Resource SC_OPCODE_ROWS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the number of rows in a reference or array." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_ZEILEN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The array (reference) for which the number of rows is to be determined." ;
+ };
+ };
+ // -=*# Resource for function TABELLEN #*=-
+ Resource SC_OPCODE_TABLES
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the number of sheets of a given reference. If no parameter has been entered, the total number of sheets in the document is returned." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_TABELLEN );
+ 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference to a cell or a range." ;
+ };
+ };
+ // -=*# Resource for function WVERWEIS #*=-
+ Resource SC_OPCODE_H_LOOKUP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Horizontal search and reference to the cells located below." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_WVERWEIS );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "search_criteria" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be found in the first row." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The array or the range for the reference." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Index" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The row index in the array." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "sorted" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If the value is TRUE or not given, the search row of the array must be sorted in ascending order." ;
+ };
+ };
+ // -=*# Resource for function SVERWEIS #*=-
+ Resource SC_OPCODE_V_LOOKUP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Vertical search and reference to indicated cells." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_SVERWEIS );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Search criterion" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be found in the first column." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "array" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The array or range for referencing." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Index" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Column index number in the array." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "sort order" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If the value is TRUE or not given, the search column of the array must be sorted in ascending order." ;
+ };
+ };
+ // -=*# Resource for function INDEX #*=-
+ Resource SC_OPCODE_INDEX
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a reference to a cell from a defined range." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_INDEX );
+ 4; 0; 1; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference to a (multiple) range." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "row" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The row in the range." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "column" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The column in the range." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "range" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The index of the subrange if referring to a multiple range." ;
+ };
+ };
+ // -=*# Resource for function INDIREKT #*=-
+ Resource SC_OPCODE_INDIRECT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the contents of a cell that is referenced in text form." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_INDIREKT );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "ref " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The cell whose contents are to be evaluated is to be referenced in text form (e.g. \"A1\")." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "A1" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The reference style: 0 or FALSE means R1C1 style, any other value or omitted means A1 style." ;
+ };
+ };
+ // -=*# Resource for function VERWEIS #*=-
+ Resource SC_OPCODE_LOOKUP
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Determines a value in a vector by comparison to values in another vector." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_VERWEIS );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Search criterion" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be used for comparison." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Search vector" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The vector (row or column) in which to search." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "result_vector" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The vector (row or range) from which the value is to be determined." ;
+ };
+ };
+ // -=*# Resource for function VERGLEICH #*=-
+ Resource SC_OPCODE_MATCH
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Defines a position in a array after comparing values." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_VERGLEICH );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Search criterion" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be used for comparison." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "lookup_array" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The array (range) in which the search is made." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Type" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Type can take the value 1, 0 or -1 and determines the criteria are to be used for comparison purposes." ;
+ };
+ };
+ // -=*# Resource for function VERSCHIEBUNG #*=-
+ Resource SC_OPCODE_OFFSET
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a reference which has been moved in relation to the starting point." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_VERSCHIEBUNG );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference (cell) from which to base the movement." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "rows" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of rows to be moved either up or down." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "columns" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The number of columns that are to be moved to the left or to the right." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "height" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The number of rows of the moved reference." ;
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "width" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "The number of columns in the moved reference." ;
+ };
+ };
+ // -=*# Resource for function FEHLERTYP #*=-
+ Resource SC_OPCODE_ERROR_TYPE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a number corresponding to an error type" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_FEHLERTYP );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "reference" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The reference (cell) in which the error occurred." ;
+ };
+ };
+ // -=*# Resource for function VORLAGE #*=-
+ Resource SC_OPCODE_STYLE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Applies a Style to the formula cell." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_VORLAGE );
+ 3; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Style" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The name of the Style to be applied." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Time" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The time (in seconds) that the Style is to remain valid." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Style2" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The Style to be applied after time expires." ;
+ };
+ };
+ // -=*# Resource for function DDE #*=-
+ Resource SC_OPCODE_DDE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Result of a DDE link." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_DDE );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "server" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The name of the server application." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "File" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The name of the file." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "range" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The range from which data is to be taken." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "mode" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Defines how data is to be converted to numbers." ;
+ };
+ };
+ // -=*# Resource for function HYPERLINK #*=-
+ Resource SC_OPCODE_HYPERLINK
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Hyperlink." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_HYPERLINK );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "URL " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "URL";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "CellText " ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Cell Text";
+ };
+ };
+ // -=*# Resource for function GETPIVOTDATA #*=-
+ Resource SC_OPCODE_GET_PIVOT_DATA
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Extracts value(s) from a DataPilot table.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TABLE;
+ U2S( HID_FUNC_GETPIVOTDATA );
+ VAR_ARGS+2; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Data Field";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The name of the data pilot field to extract.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "DataPilot";
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "A reference to a cell or range in the DataPilot table.";
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Field Name / Item";
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Field name/value pair to filter the target data.";
+ };
+ };
+ // -=*# Resource for function BAHTTEXT #*=-
+ Resource SC_OPCODE_BAHTTEXT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a number to text (Baht)." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_BAHTTEXT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to convert.";
+ };
+ };
+ // -=*# Resource for function JIS #*=-
+ Resource SC_OPCODE_JIS
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts half-width ASCII and katakana characters to full-width." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_JIS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to convert.";
+ };
+ };
+ // -=*# Resource for function ASC #*=-
+ Resource SC_OPCODE_ASC
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts full-width ASCII and katakana characters to half-width." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_ASC );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to convert.";
+ };
+ };
+ // -=*# Resource for function CODE #*=-
+ Resource SC_OPCODE_CODE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a numeric code for the first character in a text string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_CODE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "This is the text for which the code of the first character is to be found." ;
+ };
+ };
+ // -=*# Resource for function DM #*=-
+ Resource SC_OPCODE_CURRENCY
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a number to text in currency format." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_DM );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Value is a number, a reference to a cell containing a number or a formula that results in a number." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "decimals" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Decimal places. Denotes the number of digits to the right of the decimal point." ;
+ };
+ };
+ // -=*# Resource for function ZEICHEN #*=-
+ Resource SC_OPCODE_CHAR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a code number into a character or letter." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_ZEICHEN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The code value for the character." ;
+ };
+ };
+ // -=*# Resource for function SÄUBERN #*=-
+ Resource SC_OPCODE_CLEAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Removes all nonprintable characters from text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_SAEUBERN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text from which nonprintable characters are to be removed." ;
+ };
+ };
+ // -=*# Resource for function VERKETTEN #*=-
+ Resource SC_OPCODE_CONCAT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Combines several text items into one." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_VERKETTEN );
+ VAR_ARGS; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text " ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "Text for the concatentation." ;
+ };
+ };
+ // -=*# Resource for function IDENTISCH #*=-
+ Resource SC_OPCODE_EXACT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Specifies whether two texts are identical." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_IDENTISCH );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text_1" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The first text to be used for comparing texts." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "text_2" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The second text for comparing texts." ;
+ };
+ };
+ // -=*# Resource for function FINDEN #*=-
+ Resource SC_OPCODE_FIND
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Looks for a string of text within another (case sensitive)" ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_FINDEN );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "find_text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to be found." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The text in which a search is to be made." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "position" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The position in the text from which the search starts." ;
+ };
+ };
+ // -=*# Resource for function SUCHEN #*=-
+ Resource SC_OPCODE_SEARCH
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Looks for one text value within another (not case-sensitive)." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_SUCHEN );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "find_text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to be found." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The text in which a search is to be made." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "position" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The position in the text where the search is started." ;
+ };
+ };
+ // -=*# Resource for function GLÄTTEN #*=-
+ Resource SC_OPCODE_TRIM
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Removes extra spaces from text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_GLAETTEN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which extra spaces between words are to be deleted." ;
+ };
+ };
+ // -=*# Resource for function GROSS2 #*=-
+ Resource SC_OPCODE_PROPPER
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Capitalizes the first letter in all words." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_GROSS2 );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which the beginning of words are to be replaced by capital letters." ;
+ };
+ };
+ // -=*# Resource for function GROSS #*=-
+ Resource SC_OPCODE_UPPER
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts text to uppercase." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_GROSS );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which lower case letters are to be converted to capitals." ;
+ };
+ };
+ // -=*# Resource for function KLEIN #*=-
+ Resource SC_OPCODE_LOWER
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts text to lowercase." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_KLEIN );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which capitals are converted to lower case letters." ;
+ };
+ };
+ // -=*# Resource for function WERT #*=-
+ Resource SC_OPCODE_VALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts text to a number." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_WERT );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to be converted to a number." ;
+ };
+ };
+ // -=*# Resource for function TEXT #*=-
+ Resource SC_OPCODE_TEXT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a number to text according to a given format." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_TEXT );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The numeric value to be converted." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Format" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The text that describes the format." ;
+ };
+ };
+ // -=*# Resource for function T #*=-
+ Resource SC_OPCODE_T
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a value if it is text, otherwise an empty string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_T );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be checked and returned if it is text." ;
+ };
+ };
+ // -=*# Resource for function ERSETZEN #*=-
+ Resource SC_OPCODE_REPLACE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Replaces characters within a text string with a different text string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_ERSETZEN );
+ 4; 0; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which some characters are to be replaced." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "position" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The character position from which text is to be replaced." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "length" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The number of characters to be replaced." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "new text" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "The text to be inserted." ;
+ };
+ };
+ // -=*# Resource for function FEST #*=-
+ Resource SC_OPCODE_FIXED
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Formats a number with a fixed number of places after the decimal point and thousands separator." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_FEST );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be formatted." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Decimals" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Decimal places. The number of fixed decimal places that are to be displayed." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "No thousands separators" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "No thousands separator. True value, if existing and TRUE (unequal to 0), no thousands separators are set." ;
+ };
+ };
+ // -=*# Resource for function LÄNGE #*=-
+ Resource SC_OPCODE_LEN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates length of a text string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_LAENGE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which the length is to be determined." ;
+ };
+ };
+ // -=*# Resource for function LINKS #*=-
+ Resource SC_OPCODE_LEFT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the first character or characters of a text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_LINKS );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text where the initial partial words are to be determined." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of characters for the start text." ;
+ };
+ };
+ // -=*# Resource for function RECHTS #*=-
+ Resource SC_OPCODE_RIGHT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the last character or characters of a text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_RECHTS );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which the end partial words are to be determined." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of characters for the end text." ;
+ };
+ };
+ // -=*# Resource for function TEIL #*=-
+ Resource SC_OPCODE_MID
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns a partial text string of a text." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_TEIL );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which partial words are to be determined." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "start" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The position from which the part word is to be determined." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The number of characters for the text." ;
+ };
+ };
+ // -=*# Resource for function WIEDERHOLEN #*=-
+ Resource SC_OPCODE_REPT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Repeats text a given number of times." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_WIEDERHOLEN );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to be repeated." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The number of times the text is to be repeated." ;
+ };
+ };
+ // -=*# Resource for function WECHSELN #*=-
+ Resource SC_OPCODE_SUBSTITUTE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Substitutes new text for old text in a string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_WECHSELN );
+ 4; 0; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text in which partial words are to be replaced." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "search_text" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The partial string to be (repeatedly) replaced." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "new text" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "The text which is to replace the text string." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "occurrence" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "Which occurrence of the old text is to be replaced." ;
+ };
+ };
+ // -=*# Resource for function BASIS #*=-
+ Resource SC_OPCODE_BASE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a positive integer to text from a number system to the base defined." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_BASIS );
+ 3; 0; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be converted." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "radix" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The base number for conversion must be in the range 2 - 36." ;
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "Minimum length" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "If the text is shorter than the specified length, zeros are added to the left of the string." ;
+ };
+ };
+ // -=*# Resource for function DEZIMAL #*=-
+ Resource SC_OPCODE_DECIMAL
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a text of a specified number system to a positive integer in the base given." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_DEZIMAL );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to be converted." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "radix" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The base number for conversion must be in the range 2 - 36." ;
+ };
+ };
+ // -=*# Resource for function CONVERT #*=-
+ Resource SC_OPCODE_CONVERT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a value according to a conversion table in the configuration (calc.xcu).";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_UMRECHNEN );
+ 3; 0; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be converted.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Unit from which something is converted, case-sensitive.";
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "Unit into which something is converted, case-sensitive.";
+ };
+ };
+ // -=*# Resource for function ROEMISCH #*=-
+ Resource SC_OPCODE_ROMAN
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a number to a Roman numeral.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_ROEMISCH );
+ 2; 0; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Number";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The number to be converted to a Roman numeral must be in the 0 - 3999 range.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "Mode";
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "The more this value increases, the more the Roman numeral is simplified. The value must be in the 0 - 4 range.";
+ };
+ };
+ // -=*# Resource for function ARABISCH #*=-
+ Resource SC_OPCODE_ARABIC
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Calculates the value of a Roman numeral.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_ARABISCH );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "Text";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text that represents a Roman numeral.";
+ };
+ };
+ Resource SC_OPCODE_INFO
+ {
+ String 1
+ {
+ Text [ en-US ] = "Returns information about the environment.";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_INFO;
+ U2S( HID_FUNC_INFO );
+ 1; 0;
+ 0;
+ };
+ String 2
+ {
+ Text [ en-US ] = "Text";
+ };
+ String 3
+ {
+ Text [ en-US ] = "Can be \"osversion\", \"system\", \"release\", \"numfile\", and \"recalc\".";
+ };
+ };
+ Resource SC_OPCODE_UNICODE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Returns the numeric code for the first Unicode character in a text string." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_UNICODE );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "This is the text for which the code of the first character is to be found." ;
+ };
+ };
+ Resource SC_OPCODE_UNICHAR
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a code number into a Unicode character or letter." ;
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_UNICHAR );
+ 1; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "number" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The code value for the character." ;
+ };
+ };
+ Resource SC_OPCODE_EUROCONVERT
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts a value from one to another Euro currency.";
+ };
+ ExtraData =
+ {
+ 0; // DOING
+ ID_FUNCTION_GRP_MATH;
+ U2S( HID_FUNC_EUROCONVERT );
+ 5; 0; 0; 0; 1; 1;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "value" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The value to be converted.";
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "from_currency" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "ISO 4217 code of the currency from which is converted, case-sensitive.";
+ };
+ String 6 // Name of Parameter 3
+ {
+ Text [ en-US ] = "to_currency" ;
+ };
+ String 7 // Description of Parameter 3
+ {
+ Text [ en-US ] = "ISO 4217 code of the currency into which is converted, case-sensitive.";
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US ] = "full_precision" ;
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US ] = "If omitted or 0 or FALSE, the result is rounded to the decimals of to_currency. Else the result is not rounded.";
+ };
+ String 10 // Name of Parameter 5
+ {
+ Text [ en-US ] = "triangulation_precision" ;
+ };
+ String 11 // Description of Parameter 5
+ {
+ Text [ en-US ] = "If given and >=3, the intermediate result of a triangular conversion is rounded to that precision. If omitted, the result is not rounded.";
+ Text [ x-comment ] = "This description uses almost all available space in the dialog, make sure translations fit in size." ;
+ };
+ };
+ Resource SC_OPCODE_NUMBERVALUE
+ {
+ String 1 // Description
+ {
+ Text [ en-US ] = "Converts text to a number, in a locale-independent way." ;
+ };
+ ExtraData =
+ {
+ 1; // TODO: implementation and unsuppress
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_NUMBERVALUE );
+ 2; 0; 0;
+ 0;
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "text" ;
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "The text to be converted to a number." ;
+ };
+ String 4 // Name of Parameter 2
+ {
+ Text [ en-US ] = "decimal_point" ;
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "Defines the character used as the decimal point." ;
+ };
+ };
+};
+
+#if defined(U2S)
+#undef U2S
+#endif
diff --git a/sc/source/ui/src/scstring.src b/sc/source/ui/src/scstring.src
new file mode 100644
index 000000000000..9c47a42239cc
--- /dev/null
+++ b/sc/source/ui/src/scstring.src
@@ -0,0 +1,771 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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" // -> #include <sfx.hrc>
+
+ // Strings fuer Interface-Namen ------------------------------------------
+
+String SCSTR_APPLICATION
+{
+ Text [ en-US ] = "%PRODUCTNAME Calc 6.0";
+};
+String SCSTR_50_APPLICATION
+{
+ Text [ en-US ] = "StarCalc 5.0" ;
+};
+String SCSTR_40_APPLICATION
+{
+ Text [ en-US ] = "StarCalc 4.0" ;
+};
+String SCSTR_30_APPLICATION
+{
+ Text [ en-US ] = "StarCalc 3.0" ;
+};
+String SCSTR_LONG_SCDOC_NAME
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION Spreadsheet";
+};
+String SCSTR_50_LONG_DOCNAME
+{
+ Text [ en-US ] = "%PRODUCTNAME 5.0 Spreadsheet" ;
+};
+String SCSTR_40_LONG_DOCNAME
+{
+ Text [ en-US ] = "%PRODUCTNAME 4.0 Spreadsheet" ;
+};
+String SCSTR_30_LONG_DOCNAME
+{
+ Text [ en-US ] = "StarCalc 3.0 Spreadsheet" ;
+};
+String SCSTR_SHORT_SCDOC_NAME
+{
+ Text [ en-US ] = "Spreadsheet" ;
+};
+String SCSTR_HUMAN_SCDOC_NAME
+{
+ Text [ en-US ] = "Spreadsheet" ;
+};
+
+String SCSTR_DOCSHELL
+{
+ Text [ en-US ] = "Sheet" ;
+};
+
+String SCSTR_TABVIEWSHELL
+{
+ Text [ en-US ] = "Cells" ;
+};
+
+String SCSTR_CELLSHELL
+{
+ Text [ en-US ] = "Functions for Cells";
+};
+
+String SCSTR_FORMATSHELL
+{
+ Text [ en-US ] = "Formats for Cells";
+};
+
+
+String SCSTR_DRAWSHELL
+{
+ Text [ en-US ] = "Graphics objects" ;
+};
+
+String SCSTR_DRAWTEXTSHELL
+{
+ Text [ en-US ] = "Text objects" ;
+};
+
+String SCSTR_DRAWFORMSHELL
+{
+ Text [ en-US ] = "Form objects";
+};
+
+String SCSTR_CHARTSHELL
+{
+ Text [ en-US ] = "Chart objects";
+};
+
+String SCSTR_OLEOBJECTSHELL
+{
+ Text [ en-US ] = "OLE objects";
+};
+
+String SCSTR_GRAPHICSHELL
+{
+ Text [ en-US ] = "Graphics";
+};
+String SCSTR_PAGEBREAKSHELL
+{
+ Text [ en-US ] = "Pagebreak";
+};
+
+String SCSTR_EDITSHELL
+{
+ Text [ en-US ] = "Text editing" ;
+};
+
+String SCSTR_PREVIEWSHELL
+{
+ Text [ en-US ] = "Print Preview" ;
+};
+
+String SCSTR_PIVOTSHELL
+{
+ Text [ en-US ] = "Data Pilot Tables" ;
+};
+
+String SCSTR_AUDITSHELL
+{
+ Text [ en-US ] = "Detective Fill Mode" ;
+};
+
+ // -----------------------------------------------------------------------
+
+String STR_ROWHEIGHT
+{
+ Text [ en-US ] = "Height" ;
+};
+String STR_OPT_ROWHEIGHT
+{
+ Text [ en-US ] = "Add" ;
+};
+String STR_ROWHEIGHT_TITLE
+{
+ Text [ en-US ] = "Row Height" ;
+};
+String STR_OPT_ROWHEIGHT_TITLE
+{
+ Text [ en-US ] = "Optimal Row Height" ;
+};
+String STR_COLWIDTH
+{
+ Text [ en-US ] = "Width" ;
+};
+String STR_OPT_COLWIDTH
+{
+ Text [ en-US ] = "Add" ;
+};
+String STR_COLWIDTH_TITLE
+{
+ Text [ en-US ] = "Column Width" ;
+};
+String STR_OPT_COLWIDTH_TITLE
+{
+ Text [ en-US ] = "Optimal Column Width" ;
+};
+String SCSTR_UNDEFINED
+{
+ Text [ en-US ] = "- undefined -" ;
+};
+String SCSTR_NONE
+{
+ Text [ en-US ] = "- none -" ;
+};
+String SCSTR_EMPTY
+{
+ Text [ en-US ] = "- empty -" ;
+};
+String SCSTR_NOTEMPTY
+{
+ Text [ en-US ] = "- not empty -" ;
+};
+String SCSTR_NEWTABLE
+{
+ Text [ en-US ] = "- new sheet -" ;
+};
+String SCSTR_ALL
+{
+ Text [ en-US ] = "- all -" ;
+};
+String SCSTR_STDFILTER
+{
+ Text [ en-US ] = "Standard Filter..." ;
+};
+String SCSTR_TOP10FILTER
+{
+ Text [ en-US ] = "Top 10" ;
+};
+String SCSTR_NONAME
+{
+ Text [ en-US ] = "unnamed" ;
+};
+String SCSTR_COLUMN
+{
+ Text [ en-US ] = "Column" ;
+};
+String SCSTR_ROW
+{
+ Text [ en-US ] = "Row" ;
+};
+String SCSTR_NEW
+{
+ Text [ en-US ] = "~New" ;
+};
+String SCSTR_ADD
+{
+ Text [ en-US ] = "~Add" ;
+};
+String SCSTR_REMOVE
+{
+ Text [ en-US ] = "~Delete" ;
+};
+String SCSTR_CANCEL
+{
+ Text [ en-US ] = "Cance~l" ;
+};
+String SCSTR_MODIFY
+{
+ Text [ en-US ] = "Modif~y" ;
+};
+
+
+String SCSTR_SHOWTABLE
+{
+ Text [ en-US ] = "Show Sheet" ;
+};
+String SCSTR_HIDDENTABLES
+{
+ Text [ en-US ] = "Hidden Sheets" ;
+};
+String SCSTR_SELECTDB
+{
+ Text [ en-US ] = "Select Database Range" ;
+};
+String SCSTR_AREAS
+{
+ Text [ en-US ] = "Ranges" ;
+};
+String SCSTR_TABLE
+{
+ Text [ en-US ] = "Sheet" ;
+};
+String SCSTR_NAME
+{
+ Text [ en-US ] = "Name" ;
+};
+String SCSTR_INSTABLE
+{
+ Text [ en-US ] = "Insert Sheet" ;
+};
+String SCSTR_APDTABLE
+{
+ Text [ en-US ] = "Append Sheet" ;
+};
+String SCSTR_RENAMETAB
+{
+ Text [ en-US ] = "Rename Sheet" ;
+};
+String SCSTR_SET_TAB_BG_COLOR
+{
+ Text [ en-US ] = "Tab Color" ;
+};
+String SCSTR_NO_TAB_BG_COLOR
+{
+ Text [ en-US ] = "Default" ;
+};
+String SCSTR_RENAMEOBJECT
+{
+ Text [ en-US ] = "Name Object";
+};
+String STR_INSERTGRAPHIC
+{
+ Text [ en-US ] = "Insert Picture" ;
+};
+
+ // Attribute
+
+String SCSTR_HOR_JUSTIFY_LEFT
+{
+ Text [ en-US ] = "Align left" ;
+};
+String SCSTR_HOR_JUSTIFY_CENTER
+{
+ Text [ en-US ] = "Centered horizontally" ;
+};
+String SCSTR_HOR_JUSTIFY_RIGHT
+{
+ Text [ en-US ] = "Align right" ;
+};
+String SCSTR_HOR_JUSTIFY_BLOCK
+{
+ Text [ en-US ] = "Justify" ;
+};
+String SCSTR_HOR_JUSTIFY_REPEAT
+{
+ Text [ en-US ] = "Repeat alignment" ;
+};
+String SCSTR_HOR_JUSTIFY_STANDARD
+{
+ Text [ en-US ] = "Horizontal alignment default" ;
+};
+String SCSTR_VER_JUSTIFY_TOP
+{
+ Text [ en-US ] = "Align to top" ;
+};
+String SCSTR_VER_JUSTIFY_CENTER
+{
+ Text [ en-US ] = "Centered vertically" ;
+};
+String SCSTR_VER_JUSTIFY_BOTTOM
+{
+ Text [ en-US ] = "Align to bottom" ;
+};
+String SCSTR_VER_JUSTIFY_STANDARD
+{
+ Text [ en-US ] = "Vertical alignment default" ;
+};
+String SCSTR_ORIENTATION_TOPBOTTOM
+{
+ Text [ en-US ] = "Top to bottom" ;
+};
+String SCSTR_ORIENTATION_BOTTOMTOP
+{
+ Text [ en-US ] = "Bottom to Top" ;
+};
+String SCSTR_ORIENTATION_STANDARD
+{
+ Text [ en-US ] = "Default orientation" ;
+};
+
+String SCSTR_PROTECTDOC
+{
+ Text [ en-US ] = "Protect Document" ;
+};
+String SCSTR_UNPROTECTDOC
+{
+ Text [ en-US ] = "Unprotect document" ;
+};
+String SCSTR_PROTECTTAB
+{
+ Text [ en-US ] = "Protect Sheet" ;
+};
+String SCSTR_UNPROTECTTAB
+{
+ Text [ en-US ] = "Unprotect sheet" ;
+};
+String SCSTR_CHG_PROTECT
+{
+ Text [ en-US ] = "Protect Records" ;
+};
+String SCSTR_CHG_UNPROTECT
+{
+ Text [ en-US ] = "Unprotect Records" ;
+};
+String SCSTR_PASSWORD
+{
+ Text [ en-US ] = "Password:" ;
+};
+String SCSTR_PASSWORDOPT
+{
+ Text [ en-US ] = "Password (optional):" ;
+};
+
+String SCSTR_WRONGPASSWORD
+{
+ Text [ en-US ] = "Incorrect Password" ;
+};
+
+String SCSTR_END
+{
+ Text [ en-US ] = "~End" ;
+};
+
+String SCSTR_STAT_PRINT
+{
+ Text [ en-US ] = "Printing..." ;
+};
+
+String SCSTR_UNKNOWN
+{
+ Text [ en-US ] = "Unknown" ;
+};
+
+String SCSTR_CHAR_ATTRS
+{
+ Text [ en-US ] = "Font Attributes" ;
+};
+
+
+String SCSTR_CLPBRD_CLEAR
+{
+ Text [ en-US ] = "You have a large amount of data saved in the clipboard.\nDo you want the clipboard contents to be available in other applications?" ;
+};
+
+String SCSTR_CFG_APP
+{
+ Text [ en-US ] = "System Options" ;
+};
+
+String SCSTR_CFG_DOC
+{
+ Text [ en-US ] = "Document Options" ;
+};
+
+String SCSTR_CFG_VIEW
+{
+ Text [ en-US ] = "View Options" ;
+};
+
+String SCSTR_CFG_INPUT
+{
+ Text [ en-US ] = "Input Options" ;
+};
+
+String SCSTR_CFG_SPELLCHECK
+{
+ Text [ en-US ] = "Spelling Options" ;
+};
+
+String SCSTR_CFG_PRINT
+{
+ Text [ en-US ] = "Print Options" ;
+};
+
+String SCSTR_CFG_NAVIPI
+{
+ Text [ en-US ] = "Navigator Settings" ;
+};
+
+String SCSTR_VALID_MINIMUM
+{
+ Text [ en-US ] = "~Minimum" ;
+};
+String SCSTR_VALID_MAXIMUM
+{
+ Text [ en-US ] = "~Maximum" ;
+};
+String SCSTR_VALID_VALUE
+{
+ Text [ en-US ] = "~Value" ;
+};
+String SCSTR_VALID_RANGE
+{
+ Text [ en-US ] = "~Source" ;
+};
+String SCSTR_VALID_LIST
+{
+ Text [ en-US ] = "~Entries" ;
+};
+
+ // fuer Dialoge:
+
+String SCSTR_CHARSET_USER
+{
+ Text [ en-US ] = "System" ;
+};
+
+String SCSTR_COLUMN_USER
+{
+ Text [ en-US ] = "Standard;Text;Date (DMY);Date (MDY);Date (YMD);US English;Hide" ;
+};
+
+String SCSTR_FIELDSEP
+{
+ Text [ en-US ] = ",\t44\t;\t59\t:\t58\t{Tab}\t9\t{space}\t32 " ;
+};
+
+String SCSTR_TEXTSEP
+{
+ Text = "\"\t34\t'\t39" ;
+};
+
+String SCSTR_FORMULA_AUTOCORRECTION
+{
+ Text [ en-US ] = "%PRODUCTNAME Calc found an error in the formula entered.\nDo you want to accept the correction proposed below?\n\n" ;
+};
+
+//! the graphics filter error strings should be moved to svx or offapp!
+
+String SCSTR_GRFILTER_OPENERROR
+{
+ Text [ en-US ] = "Graphics file can not be opened" ;
+};
+String SCSTR_GRFILTER_IOERROR
+{
+ Text [ en-US ] = "Graphics file can not be read" ;
+};
+String SCSTR_GRFILTER_FORMATERROR
+{
+ Text [ en-US ] = "Unknown graphic format" ;
+};
+String SCSTR_GRFILTER_VERSIONERROR
+{
+ Text [ en-US ] = "This graphic file version is not supported" ;
+};
+String SCSTR_GRFILTER_FILTERERROR
+{
+ Text [ en-US ] = "Graphics filter not found" ;
+};
+String SCSTR_GRFILTER_TOOBIG
+{
+ Text [ en-US ] = "Not enough memory available to insert graphics." ;
+};
+String SCSTR_UNDO_GRAFFILTER
+{
+ Text [ en-US ] = "Graphics Filter" ;
+};
+
+// #98185#
+String STR_CAPTION_DEFAULT_TEXT
+{
+ Text [ en-US ] = "Text" ;
+};
+
+// Select tables dialog title
+String STR_DLG_SELECTTABLES_TITLE
+{
+ Text [ en-US ] = "Select Sheets";
+};
+
+// Select tables dialog listbox
+String STR_DLG_SELECTTABLES_LBNAME
+{
+ Text [ en-US ] = "~Selected sheets";
+};
+
+String STR_REPLCELLSWARN
+{
+ Text [ en-US ] = "You are pasting data into cells that already contain data.\nDo you really want to overwrite the existing data?";
+};
+
+String STR_PRINT_NOTHING
+{
+ Text [ en-US ] = "There is nothing to print. The selected print range or sheet is empty.";
+};
+
+String SCSTR_ALLFILTER
+{
+ Text [ en-US ] = "All";
+};
+
+String STR_ACC_CSVRULER_NAME
+{
+ Text [ en-US ] = "Ruler";
+};
+
+String STR_ACC_CSVRULER_DESCR
+{
+ Text [ en-US ] = "This ruler manages objects at fixed positions.";
+};
+
+String STR_ACC_CSVGRID_NAME
+{
+ Text [ en-US ] = "Preview";
+};
+
+String STR_ACC_CSVGRID_DESCR
+{
+ Text [ en-US ] = "This sheet shows how the data will be arranged in the document.";
+};
+
+String STR_ACC_DOC_NAME
+{
+ Text [ en-US ] = "Document view";
+};
+
+String STR_ACC_DOC_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_TABLE_NAME
+{
+ Text [ en-US ] = "Sheet %1";
+};
+
+String STR_ACC_TABLE_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_CELL_NAME
+{
+ Text [ en-US ] = "Cell %1";
+};
+
+String STR_ACC_CELL_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_PREVIEWDOC_NAME
+{
+ Text [ en-US ] = "Page preview";
+};
+
+String STR_ACC_PREVIEWDOC_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_HEADERCELL_NAME
+{
+ Text = "";
+};
+
+String STR_ACC_HEADERCELL_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_LEFTAREA_NAME
+{
+ Text [ en-US ] = "Left area";
+};
+
+String STR_ACC_LEFTAREA_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_CENTERAREA_NAME
+{
+ Text [ en-US ] = "Center area";
+};
+
+String STR_ACC_CENTERAREA_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_RIGHTAREA_NAME
+{
+ Text [ en-US ] = "Right area";
+};
+
+String STR_ACC_RIGHTAREA_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_HEADER_NAME
+{
+ Text [ en-US ] = "Header of page %1";
+};
+
+String STR_ACC_HEADER_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_FOOTER_NAME
+{
+ Text [ en-US ] = "Footer of page %1";
+};
+
+String STR_ACC_FOOTER_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_EDITLINE_NAME
+{
+ Text [ en-US ] = "Input line";
+};
+
+String STR_ACC_EDITLINE_DESCR
+{
+ Text [ en-US ] = "This is where you enter or edit text, numbers and formulas.";
+};
+
+String STR_ACC_EDITCELL_NAME
+{
+ Text [ en-US ] = "Cell %1";
+};
+
+String STR_ACC_EDITCELL_DESCR
+{
+ Text = "";
+};
+
+String STR_ACC_DATAPILOT_ROW_DESCR
+{
+ Text [ en-US ] = "Fields that you drop here will be displayed as rows in the final DataPilot table.";
+};
+
+String STR_ACC_DATAPILOT_COL_DESCR
+{
+ Text [ en-US ] = "Fields that you drop here will be displayed as columns in the final DataPilot table.";
+};
+
+String STR_ACC_DATAPILOT_DATA_DESCR
+{
+ Text [ en-US ] = "Fields that you drop here will be used for calculations in the final DataPilot table.";
+};
+
+String STR_ACC_DATAPILOT_SEL_DESCR
+{
+ Text [ en-US ] = "Lists the fields that you can drag to one of the other three areas.";
+};
+
+String SCSTR_MEDIASHELL
+{
+ Text [ en-US ] = "Media Playback";
+};
+
+String RID_SCSTR_ONCLICK
+{
+ Text [ en-US ] = "Mouse button pressed";
+};
+
+String SCSTR_MOREBTN_MOREOPTIONS
+{
+ Text [ en-US ] = "More ~Options";
+};
+
+String SCSTR_MOREBTN_FEWEROPTIONS
+{
+ Text [ en-US ] = "Fewer ~Options";
+};
+
+StringArray SCSTR_PRINT_OPTIONS
+{
+ ItemList [en-US] =
+ {
+ < "Pages"; >;
+ < "~Include output of empty pages"; >;
+ < "If checked empty pages that have no cell contents or draw objects are not printed."; >;
+ < "Sheets"; >;
+ < "Print ~only selected sheets"; >;
+ < "If checked only contents from selected sheets are printed, even if you specify a wider range in the Format - Print Ranges dialog. Content from sheets that are not selected will not be printed."; >;
+ < "Print content"; >;
+ < "~All sheets"; >;
+ < "The printout will be created from all sheets in the document."; >;
+ < "~Selected sheets"; >;
+ < "The printout will be created only from the currently selected sheets."; >;
+ < "Selected cells"; >;
+ < "The printout will be created only from the currently selected cells."; >;
+ < "Thereof print"; >;
+ < "All ~pages"; >;
+ < "Print all pages of the printable content."; >;
+ < "Pa~ges"; >;
+ < "Print only some pages of the printable content."; >;
+ < "%PRODUCTNAME %s"; >;
+ };
+};
+
diff --git a/sc/source/ui/src/scwarngs.src b/sc/source/ui/src/scwarngs.src
new file mode 100644
index 000000000000..9cd22567d77c
--- /dev/null
+++ b/sc/source/ui/src/scwarngs.src
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define __RSC
+#include "scwarngs.hxx"
+#include "sc.hrc"
+
+
+
+#define SH_MAX 0x7fff
+
+Resource RID_WRNHDLSC
+{
+ String ERRCODE_SC_EXPORT_WRN_ASCII & SH_MAX
+ {
+ Text [ en-US ] = "Only the active sheet could be saved." ;
+ };
+ String ERRCODE_SC_IMPORT_WRN_RNGOVRFLW & SH_MAX
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Die Maximalanzahl von Zeilen wurde überschritten. überzählige Zeilen wurden nicht mitimportiert! : Die Maximalanzahl von Zeilen wurde ³berschritten. ³berzõhlige Zeilen wurden nicht mitimportiert! */
+ Text [ en-US ] = "The number of rows exceeded the maximum. Additional rows were not imported!" ;
+ };
+ /*
+ String ERRCODE_SC_ & SH_MAX
+ {
+ Text = "";
+ };
+*/
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/simpref.src b/sc/source/ui/src/simpref.src
new file mode 100644
index 000000000000..03f41c1a56aa
--- /dev/null
+++ b/sc/source/ui/src/simpref.src
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "simpref.hrc"
+ModelessDialog RID_SCDLG_SIMPLEREF
+{
+ OutputSize = TRUE ;
+ //HelpId = SID_DEFINE_DBNAME ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 222 , 60 ) ;
+ Text = "Bereich festlegen" ;
+ Moveable = TRUE ;
+ // Closeable = TRUE; // Dieser Dialog hat einen Cancel-Button !
+ FixedText FT_ASSIGN
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ Text [ en-US ] = "Area" ;
+ };
+ Edit ED_ASSIGN
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 48 , 6 ) ;
+ Size = MAP_APPFONT ( 90 , 12 ) ;
+ TabStop = TRUE ;
+ // Text = "<Tabellenbereich>" ;
+ };
+ ImageButton RB_ASSIGN
+ {
+ Pos = MAP_APPFONT ( 142 , 5 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 166 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 166 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 166 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/solveroptions.src b/sc/source/ui/src/solveroptions.src
new file mode 100644
index 000000000000..0a3432344f35
--- /dev/null
+++ b/sc/source/ui/src/solveroptions.src
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "solveroptions.hrc"
+
+ModalDialog RID_SCDLG_SOLVEROPTIONS
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_SOLVEROPTIONS ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 218 , 156 ) ;
+ Moveable = TRUE ;
+ FixedText FT_ENGINE
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Text [ en-US ] = "Solver engine" ;
+ };
+ ListBox LB_ENGINE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 67 , 6 ) ;
+ Size = MAP_APPFONT ( 145 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_SETTINGS
+ {
+ Pos = MAP_APPFONT ( 6 , 24 ) ;
+ Size = MAP_APPFONT ( 156 , 8 ) ;
+ Text [ en-US ] = "Settings:" ;
+ };
+ Control LB_SETTINGS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 35 ) ;
+ Size = MAP_APPFONT ( 206 , 67 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_EDIT
+ {
+ Pos = MAP_APPFONT ( 6 , 108 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Edit..." ;
+ };
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 125 ) ;
+ Size = MAP_APPFONT ( 218 , 8 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 6 , 136 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 106 , 136 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 162 , 136 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Text [ en-US ] = "Options" ;
+};
+
+
+ModalDialog RID_SCDLG_SOLVER_INTEGER
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_SOLVER_INTEGER ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 118 , 76 ) ;
+ Moveable = TRUE ;
+ FixedText FT_OPTIONNAME
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 106 , 16 ) ;
+ WordBreak = TRUE ;
+ // text is dynamic
+ };
+ NumericField NF_VALUE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 27 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Repeat = TRUE ;
+ Minimum = -2147483648 ;
+ Maximum = 2147483647 ;
+ First = 0 ;
+ Last = 100 ;
+ };
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 118 , 8 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 6 , 56 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 62 , 56 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Text [ en-US ] = "Edit Setting" ;
+};
+
+ModalDialog RID_SCDLG_SOLVER_DOUBLE
+{
+ OutputSize = TRUE ;
+ HelpId = HID_SC_SOLVER_DOUBLE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 118 , 76 ) ;
+ Moveable = TRUE ;
+ FixedText FT_OPTIONNAME
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 106 , 16 ) ;
+ WordBreak = TRUE ;
+ // text is dynamic
+ };
+ Edit ED_VALUE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 27 ) ;
+ Size = MAP_APPFONT ( 50 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_BUTTONS
+ {
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 118 , 8 ) ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 6 , 56 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 62 , 56 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Text [ en-US ] = "Edit Setting" ;
+};
+
diff --git a/sc/source/ui/src/solvrdlg.src b/sc/source/ui/src/solvrdlg.src
new file mode 100644
index 000000000000..6a8a3d955644
--- /dev/null
+++ b/sc/source/ui/src/solvrdlg.src
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "solvrdlg.hrc"
+ModelessDialog RID_SCDLG_SOLVER
+{
+ OutputSize = TRUE ;
+ HelpId = SID_OPENDLG_SOLVE ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 222 , 64 ) ;
+ Text [ en-US ] = "Goal Seek" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_FORMULACELL
+ {
+ Pos = MAP_APPFONT ( 12 , 16 ) ;
+ Size = MAP_APPFONT ( 50 , 8 ) ;
+ Text [ en-US ] = "~Formula cell" ;
+ };
+ Edit ED_FORMULACELL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 64 , 14 ) ;
+ Size = MAP_APPFONT ( 79 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_FORMULACELL
+ {
+ Pos = MAP_APPFONT ( 145 , 13 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_TARGETVAL
+ {
+ Pos = MAP_APPFONT ( 12 , 32 ) ;
+ Size = MAP_APPFONT ( 50 , 8 ) ;
+ Text [ en-US ] = "Target ~value" ;
+ };
+ Edit ED_TARGETVAL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 64 , 30 ) ;
+ Size = MAP_APPFONT ( 93 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_VARCELL
+ {
+ Pos = MAP_APPFONT ( 12 , 48 ) ;
+ Size = MAP_APPFONT ( 50 , 8 ) ;
+ Text [ en-US ] = "Variable ~cell" ;
+ };
+ Edit ED_VARCELL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 64 , 46 ) ;
+ Size = MAP_APPFONT ( 79 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ ImageButton RB_VARCELL
+ {
+ Pos = MAP_APPFONT ( 145 , 45 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_VARIABLES
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 154 , 8 ) ;
+ Text [ en-US ] = "Default settings" ;
+ };
+ OKButton BTN_OK
+ {
+ DefButton = TRUE ;
+ Pos = MAP_APPFONT ( 166 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 166 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 166 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ String STR_INVALIDVAL
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Unzulässiger Zielwert! : Unzulõssiger Zielwert! */
+ Text [ en-US ] = "Invalid target value." ;
+ };
+ String STR_INVALIDVAR
+ {
+ Text [ en-US ] = "Undefined name for variable cell." ;
+ };
+ String STR_INVALIDFORM
+ {
+ Text [ en-US ] = "Undefined name as formula cell." ;
+ };
+ String STR_NOFORMULA
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Zelle muß eine Formel enthalten! : Zelle mu˜ eine Formel enthalten! */
+ Text [ en-US ] = "Cell must contain a formula." ;
+ };
+};
diff --git a/sc/source/ui/src/sortdlg.src b/sc/source/ui/src/sortdlg.src
new file mode 100644
index 000000000000..3aca09211edd
--- /dev/null
+++ b/sc/source/ui/src/sortdlg.src
@@ -0,0 +1,348 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "sortdlg.hrc"
+TabPage RID_SCPAGE_SORT_FIELDS
+{
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ HelpId = HID_SCPAGE_SORT_FIELDS ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ ListBox LB_SORT1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 19 ) ;
+ Size = MAP_APPFONT ( 154 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ RadioButton BTN_UP1
+ {
+ Pos = MAP_APPFONT ( 172 , 14 ) ;
+ Size = MAP_APPFONT ( 79 , 10 ) ;
+ Text [ en-US ] = "~Ascending" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DOWN1
+ {
+ Pos = MAP_APPFONT ( 172 , 28 ) ;
+ Size = MAP_APPFONT ( 79 , 10 ) ;
+ Text [ en-US ] = "~Descending" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_SORT1
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Sort ~by" ;
+ };
+ ListBox LB_SORT2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 60 ) ;
+ Size = MAP_APPFONT ( 154 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ RadioButton BTN_UP2
+ {
+ Pos = MAP_APPFONT ( 172 , 55 ) ;
+ Size = MAP_APPFONT ( 79 , 10 ) ;
+ Text [ en-US ] = "A~scending" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DOWN2
+ {
+ Pos = MAP_APPFONT ( 172 , 69 ) ;
+ Size = MAP_APPFONT ( 79 , 10 ) ;
+ Text [ en-US ] = "D~escending" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_SORT2
+ {
+ Pos = MAP_APPFONT ( 6 , 44 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Then b~y" ;
+ };
+ ListBox LB_SORT3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 101 ) ;
+ Size = MAP_APPFONT ( 154 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ RadioButton BTN_UP3
+ {
+ Pos = MAP_APPFONT ( 172 , 96 ) ;
+ Size = MAP_APPFONT ( 79 , 10 ) ;
+ Text [ en-US ] = "As~cending" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DOWN3
+ {
+ Pos = MAP_APPFONT ( 172 , 110 ) ;
+ Size = MAP_APPFONT ( 79 , 10 ) ;
+ Text [ en-US ] = "Desce~nding" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_SORT3
+ {
+ Pos = MAP_APPFONT ( 6 , 85 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "T~hen by" ;
+ };
+};
+TabPage RID_SCPAGE_SORT_OPTIONS
+{
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ HelpId = HID_SCPAGE_SORT_OPTIONS ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ CheckBox BTN_CASESENSITIVE
+ {
+ Pos = MAP_APPFONT ( 12 , 6 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ Text [ en-US ] = "Case ~sensitive" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_LABEL
+ {
+ Pos = MAP_APPFONT ( 12 , 20 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ TabStop = TRUE ;
+ };
+ String STR_COL_LABEL
+ {
+ Text [ en-US ] = "Range contains column la~bels" ;
+ };
+ String STR_ROW_LABEL
+ {
+ Text [ en-US ] = "Range contains ~row labels" ;
+ };
+ CheckBox BTN_FORMATS
+ {
+ Pos = MAP_APPFONT ( 12 , 34 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ Text [ en-US ] = "Include ~formats" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_COPYRESULT
+ {
+ Pos = MAP_APPFONT ( 12 , 48 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ Text [ en-US ] = "~Copy sort results to:" ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_OUTAREA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 59 ) ;
+ Size = MAP_APPFONT ( 93 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ Edit ED_OUTAREA
+ {
+ Disable = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 119 , 59 ) ;
+ Size = MAP_APPFONT ( 132 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_SORT_USER
+ {
+ Pos = MAP_APPFONT ( 12 , 75 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ Text [ en-US ] = "Custom sort ~order" ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_SORT_USER
+ {
+ Disable = TRUE ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 86 ) ;
+ Size = MAP_APPFONT ( 231 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_LANGUAGE
+ {
+ Pos = MAP_APPFONT ( 12 , 104 ) ;
+ Size = MAP_APPFONT ( 101 , 8 ) ;
+ Text [ en-US ] = "~Language";
+ };
+ ListBox LB_LANGUAGE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 115 ) ;
+ Size = MAP_APPFONT ( 101 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ FixedText FT_ALGORITHM
+ {
+ Pos = MAP_APPFONT ( 119 , 104 ) ;
+ Size = MAP_APPFONT ( 132 , 8 ) ;
+ Text [ en-US ] = "O~ptions";
+ };
+ ListBox LB_ALGORITHM
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 119 , 115 ) ;
+ Size = MAP_APPFONT ( 132 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedLine FL_DIRECTION
+ {
+ Pos = MAP_APPFONT ( 6 , 133 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Direction" ;
+ };
+ RadioButton BTN_TOP_DOWN
+ {
+ Pos = MAP_APPFONT ( 12 , 144 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ Text [ en-US ] = "~Top to bottom (sort rows)" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_LEFT_RIGHT
+ {
+ Pos = MAP_APPFONT ( 12 , 158 ) ;
+ Size = MAP_APPFONT ( 242 , 10 ) ;
+ Text [ en-US ] = "L~eft to right (sort columns)" ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_AREA_LABEL
+ {
+ Pos = MAP_APPFONT ( 6 , 171 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Data area:" ;
+ };
+};
+TabDialog RID_SCDLG_SORT
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 220 , 175 ) ;
+ Text [ en-US ] = "Sort" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 210 , 170 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = TP_FIELDS ;
+ PageResID = TP_FIELDS ;
+ Text [ en-US ] = "Sort Criteria" ;
+ };
+ PageItem
+ {
+ Identifier = TP_OPTIONS ;
+ PageResID = TP_OPTIONS ;
+ Text [ en-US ] = "Options" ;
+ };
+ };
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 3 , 157 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 49 , 157 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton 1
+ {
+ Pos = MAP_APPFONT ( 137 , 157 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton 1
+ {
+ Pos = MAP_APPFONT ( 94 , 157 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ };
+};
+
+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/src/subtdlg.src b/sc/source/ui/src/subtdlg.src
new file mode 100644
index 000000000000..c0bcfba1b07b
--- /dev/null
+++ b/sc/source/ui/src/subtdlg.src
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "subtdlg.hrc"
+
+TabPage RID_SCPAGE_SUBT_OPTIONS
+{
+ HelpId = HID_SCPAGE_SUBT_OPTIONS ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ Hide = TRUE ;
+ FixedLine FL_GROUP
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Groups";
+ };
+ CheckBox BTN_PAGEBREAK
+ {
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Page break between groups" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_CASE
+ {
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Groß-/Kleinschreibung beachten : ~Gro˜-/Kleinschreibung beachten */
+ Text [ en-US ] = "~Case sensitive" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_SORT
+ {
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "Pre-~sort area according to groups" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_FORMATS
+ {
+ Pos = MAP_APPFONT ( 12 , 101 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Formate einschließen : ~Formate einschlie˜en */
+ Text [ en-US ] = "I~nclude formats" ;
+ TabStop = TRUE ;
+ };
+ CheckBox BTN_USERDEF
+ {
+ Pos = MAP_APPFONT ( 12 , 115 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "C~ustom sort order" ;
+ TabStop = TRUE ;
+ };
+ ListBox LB_USERDEF
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 20 , 127 ) ;
+ Size = MAP_APPFONT ( 231 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ RadioButton BTN_ASCENDING
+ {
+ Pos = MAP_APPFONT ( 12 , 69 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "~Ascending" ;
+ TabStop = TRUE ;
+ };
+ RadioButton BTN_DESCENDING
+ {
+ Pos = MAP_APPFONT ( 12 , 83 ) ;
+ Size = MAP_APPFONT ( 239 , 10 ) ;
+ Text [ en-US ] = "D~escending" ;
+ TabStop = TRUE ;
+ };
+ FixedLine FL_SORT
+ {
+ Pos = MAP_APPFONT ( 6 , 58 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Sort" ;
+ };
+};
+
+
+TabPage RID_SUBTBASE
+{
+ // Die Elemente haben hart vergebene Hilfe-IDs, weil automatisch generierte
+ // aus den Ableitungen nicht in der HID-Liste auftauchen wuerden
+ HelpId = HID_SCPAGE_SUBT_GROUP ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ Hide = TRUE ;
+ FixedText FT_GROUP
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "~Group by" ;
+ };
+ ListBox LB_GROUP
+ {
+ HelpId = HID_SC_SUBT_GROUP ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 14 ) ;
+ Size = MAP_APPFONT ( 121 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_COLUMNS
+ {
+ Pos = MAP_APPFONT ( 6 , 32 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Teilergebnisse berechnen für : ~Teilergebnisse berechnen f³r */
+ Text [ en-US ] = "~Calculate subtotals for" ;
+ };
+ Control WND_COLUMNS
+ {
+ HelpId = HID_SC_SUBT_COLS ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 43 ) ;
+ Size = MAP_APPFONT ( 121 , 136 ) ;
+ TabStop = TRUE ;
+ };
+ FixedText FT_FUNCTIONS
+ {
+ Pos = MAP_APPFONT ( 133 , 32 ) ;
+ Size = MAP_APPFONT ( 121 , 8 ) ;
+ Text [ en-US ] = "Use ~function" ;
+ };
+ ListBox LB_FUNCTIONS
+ {
+ HelpId = HID_SC_SUBT_FUNC ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 133 , 43 ) ;
+ Size = MAP_APPFONT ( 121 , 136 ) ;
+ TabStop = TRUE ;
+ StringList [ en-US ] =
+ {
+ < "Sum" ; Default ; > ;
+ < "Count" ; Default ; > ;
+ < "Average" ; Default ; > ;
+ < "Max" ; Default ; > ;
+ < "Min" ; Default ; > ;
+ < "Product" ; Default ; > ;
+ < "Count (numbers only)" ; Default ; > ;
+ < "StDev (Sample)" ; Default ; > ;
+ < "StDevP (Population)" ; Default ; > ;
+ < "Var (Sample)" ; Default ; > ;
+ < "VarP (Population)" ; Default ; > ;
+ };
+ };
+};
+
+ // "Control" braucht immer eigene HelpId - ansonsten aus RID_SUBTBASE kopiert
+
+TabPage RID_SCPAGE_SUBT_GROUP1 < RID_SUBTBASE
+{
+ HelpId = HID_SCPAGE_SUBT_GROUP1 ;
+};
+TabPage RID_SCPAGE_SUBT_GROUP2 < RID_SUBTBASE
+{
+ HelpId = HID_SCPAGE_SUBT_GROUP2 ;
+};
+TabPage RID_SCPAGE_SUBT_GROUP3 < RID_SUBTBASE
+{
+ HelpId = HID_SCPAGE_SUBT_GROUP3 ;
+};
+
+TabDialog RID_SCDLG_SUBTOTALS
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 294 , 176 ) ;
+ Text [ en-US ] = "Subtotals" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 3 ) ;
+ Size = MAP_APPFONT ( 240 , 150 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = PAGE_GROUP1 ;
+ Text [ en-US ] = "1st Group" ;
+ };
+ PageItem
+ {
+ Identifier = PAGE_GROUP2 ;
+ Text [ en-US ] = "2nd Group" ;
+ };
+ PageItem
+ {
+ Identifier = PAGE_GROUP3 ;
+ Text [ en-US ] = "3rd Group" ;
+ };
+ PageItem
+ {
+ Identifier = PAGE_OPTIONS ;
+ Text [ en-US ] = "Options" ;
+ };
+ };
+ };
+ PushButton BTN_REMOVE
+ {
+ Pos = MAP_APPFONT ( 143 , 160 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Löschen : ~L÷schen */
+ Text [ en-US ] = "~Delete" ;
+ TabStop = TRUE ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/tabopdlg.src b/sc/source/ui/src/tabopdlg.src
new file mode 100644
index 000000000000..25af654f4147
--- /dev/null
+++ b/sc/source/ui/src/tabopdlg.src
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "tabopdlg.hrc"
+ModelessDialog RID_SCDLG_TABOP
+{
+ OutputSize = TRUE ;
+ HelpId = SID_OPENDLG_TABOP ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 240 , 64 ) ;
+ Text [ en-US ] = "Multiple operations" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_FORMULARANGE
+ {
+ Pos = MAP_APPFONT ( 12 , 16 ) ;
+ Size = MAP_APPFONT ( 68 , 8 ) ;
+ Text [ en-US ] = "~Formulas" ;
+ };
+ Edit ED_FORMULARANGE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 82 , 14 ) ;
+ Size = MAP_APPFONT ( 79 , 12 ) ;
+ };
+ ImageButton RB_FORMULARANGE
+ {
+ Pos = MAP_APPFONT ( 163 , 13 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_ROWCELL
+ {
+ Pos = MAP_APPFONT ( 12 , 32 ) ;
+ Size = MAP_APPFONT ( 70 , 8 ) ;
+ Text [ en-US ] = "~Row input cell" ;
+ };
+ Edit ED_ROWCELL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 82 , 30 ) ;
+ Size = MAP_APPFONT ( 79 , 12 ) ;
+ };
+ ImageButton RB_ROWCELL
+ {
+ Pos = MAP_APPFONT ( 163 , 29 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedText FT_COLCELL
+ {
+ Pos = MAP_APPFONT ( 12 , 48 ) ;
+ Size = MAP_APPFONT ( 70 , 8 ) ;
+ Text [ en-US ] = "~Column input cell" ;
+ };
+ Edit ED_COLCELL
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 82 , 46 ) ;
+ Size = MAP_APPFONT ( 79 , 12 ) ;
+ };
+ ImageButton RB_COLCELL
+ {
+ Pos = MAP_APPFONT ( 163 , 45 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = FALSE ;
+ QuickHelpText [ en-US ] = "Shrink" ;
+ };
+ FixedLine FL_VARIABLES
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 172 , 8 ) ;
+ Text [ en-US ] = "Default settings" ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 184 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 184 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 184 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ String STR_NOFORMULA
+ {
+ Text [ en-US ] = "No formula specified." ;
+ };
+ String STR_NOCOLROW
+ {
+ Text [ en-US ] = "Neither row or column specified." ;
+ };
+ String STR_WRONGFORMULA
+ {
+ Text [ en-US ] = "Undefined name or range." ;
+ };
+ String STR_WRONGROWCOL
+ {
+ Text [ en-US ] = "Undefined name or wrong cell reference." ;
+ };
+ String STR_NOCOLFORMULA
+ {
+ Text [ en-US ] = "Formulas don't form a column." ;
+ };
+ String STR_NOROWFORMULA
+ {
+ Text [ en-US ] = "Formulas don't form a row." ;
+ };
+};
diff --git a/sc/source/ui/src/textdlgs.src b/sc/source/ui/src/textdlgs.src
new file mode 100644
index 000000000000..2b0e408262ba
--- /dev/null
+++ b/sc/source/ui/src/textdlgs.src
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#include <svx/dialogs.hrc>
+#include "sc.hrc"
+
+TabDialog RID_SCDLG_CHAR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 289 , 176 ) ;
+ Text [ en-US ] = "Character" ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_CHAR_NAME ;
+ Text [ en-US ] = "Font";
+ };
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_CHAR_EFFECTS ;
+ Text [ en-US ] = "Font Effects";
+ };
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_CHAR_POSITION ;
+ Text [ en-US ] = "Font Position";
+ };
+ };
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 6 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 60 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton 1
+ {
+ Pos = MAP_APPFONT ( 114 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton 1
+ {
+ Pos = MAP_APPFONT ( 169 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zurück : Zur³ck */
+ Text [ en-US ] = "Back" ;
+ TabStop = TRUE ;
+ };
+};
+
+TabDialog RID_SCDLG_PARAGRAPH
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 289 , 176 ) ;
+ Text [ en-US ] = "Paragraph" ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_STD_PARAGRAPH ;
+ /* ### ACHTUNG: Neuer Text in Resource? Einzüge und Abstände : Einz³ge und Abstõnde */
+ Text [ en-US ] = "Indents & Spacing" ;
+ PageResID = RID_SVXPAGE_STD_PARAGRAPH ;
+ };
+ /*
+ PageItem {
+ Identifier = RID_SVXPAGE_EXT_PARAGRAPH;
+ Text [ en-US ] = "Paragraph (Extensions)";
+ PageResID = RID_SVXPAGE_EXT_PARAGRAPH;
+ };
+*/
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_ALIGN_PARAGRAPH ;
+ PageResID = RID_SVXPAGE_ALIGN_PARAGRAPH ;
+ Text [ en-US ] = "Alignment" ;
+ };
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_PARA_ASIAN ;
+ Text [ en-US ] = "Asian Typography";
+ };
+ PageItem
+ {
+ Identifier = RID_SVXPAGE_TABULATOR ;
+ Text [ en-US ] = "Tab" ;
+ PageResID = RID_SVXPAGE_TABULATOR ;
+ };
+ };
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 6 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 60 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton 1
+ {
+ Pos = MAP_APPFONT ( 114 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton 1
+ {
+ Pos = MAP_APPFONT ( 169 , 151 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zurück : Zur³ck */
+ Text [ en-US ] = "Back" ;
+ TabStop = TRUE ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/src/toolbox.src b/sc/source/ui/src/toolbox.src
new file mode 100644
index 000000000000..6e4b89e5faa0
--- /dev/null
+++ b/sc/source/ui/src/toolbox.src
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc" // -> #include <sfx.hrc>
+#include <svx/globlmn.hrc>
+#include "tbinsert.hrc" // Sub-IDs
+
+
+ // ToolBoxen: ----------------------------------------------------------------
+
+/*
+ * ToolBox mit Eingabezeile: HelpStrings fuer Knoepfe und Fenster:
+ */
+
+#define ITEM_TOOLBAR_SORT_ASCENDING \
+ Identifier = SID_SORT_ASCENDING ; \
+ HelpId = SID_SORT_ASCENDING ;
+
+#define ITEM_TOOLBAR_SORT_DESCENDING \
+ Identifier = SID_SORT_DESCENDING ; \
+ HelpId = SID_SORT_DESCENDING ;
+
+#define ITEM_TOOLBAR_INSERT_FRAME \
+ Identifier = SID_INSERT_FRAME ; \
+ HelpId = SID_INSERT_FRAME ;
+
+
+#define ITEM_TOOLBAR_INSERT_GRAPHIC \
+ Identifier = SID_INSERT_GRAPHIC ; \
+ HelpId = SID_INSERT_GRAPHIC ;
+
+#define ITEM_TOOLBAR_AUTO_FILTER \
+ Identifier = SID_AUTO_FILTER ; \
+ HelpId = SID_AUTO_FILTER ;
+
+
+#define ITEM_TOOLBAR_OUTLINE_MAKE \
+ Identifier = SID_OUTLINE_MAKE ; \
+ HelpId = SID_OUTLINE_MAKE ;
+
+
+#define ITEM_TOOLBAR_OUTLINE_REMOVE \
+ Identifier = SID_OUTLINE_REMOVE ; \
+ HelpId = SID_OUTLINE_REMOVE ;
+
+#define ITEM_TOOLBAR_DRAW_CHART \
+ Identifier = SID_INSERT_DIAGRAM ; \
+ HelpId = SID_DRAW_CHART ;
+
+#define ITEM_TOOLBAR_SPELLING \
+ Identifier = SID_SPELL_DIALOG ; \
+ HelpId = SID_SPELL_DIALOG ;
+
+#define ITEM_TOOLBAR_THESAURUS \
+ Identifier = SID_THESAURUS ; \
+ HelpId = SID_THESAURUS ;
+
+#define ITEM_TOOLBAR_FILTER \
+ Identifier = SID_FILTER ; \
+ HelpId = SID_FILTER ;
+
+#define ITEM_TOOLBAR_SPECIAL_FILTER \
+ Identifier = SID_SPECIAL_FILTER;\
+ HelpId = SID_SPECIAL_FILTER ;
+
+String SCSTR_QHELP_POSWND
+{
+ Text [ en-US ] = "Name Box" ;
+};
+
+String SCSTR_QHELP_INPUTWND
+{
+ Text [ en-US ] = "Input line" ;
+};
+
+String SCSTR_QHELP_BTNCALC
+{
+ Text [ en-US ] = "Function Wizard" ;
+};
+
+String SCSTR_QHELP_BTNOK
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Übernehmen : šbernehmen */
+ Text [ en-US ] = "Accept" ;
+};
+
+String SCSTR_QHELP_BTNCANCEL
+{
+ Text [ en-US ] = "Cancel" ;
+};
+
+String SCSTR_QHELP_BTNSUM
+{
+ Text [ en-US ] = "Sum" ;
+};
+
+String SCSTR_QHELP_BTNEQUAL
+{
+ Text [ en-US ] = "Function" ;
+};
+
+ // --------------------------------------------------------------------
+ // PopUp's fuer Werkzeugleiste
+ // --------------------------------------------------------------------
+
+FloatingWindow RID_TBXCTL_INSERT
+{
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ HelpID = RID_TBXCTL_INSERT ;
+ /* ### ACHTUNG: Neuer Text in Resource? Einfügen : Einf³gen */
+ Text [ en-US ] = "Insert" ;
+
+ ToolBox RID_TOOLBOX_INSERT
+ {
+ MenuStrings = TRUE ;
+ SVLook = TRUE ;
+ HelpID = RID_TOOLBOX_INSERT ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = SID_INSERT_GRAPHIC ;
+ HelpID = SID_INSERT_GRAPHIC ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_CHARMAP ;
+ HelpId = SID_CHARMAP ;
+ };
+ };
+ };
+};
+
+FloatingWindow RID_TBXCTL_INSCELLS
+{
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ HelpID = RID_TBXCTL_INSCELLS ;
+ /* ### ACHTUNG: Neuer Text in Resource? Zellen einfügen : Zellen einf³gen */
+ Text [ en-US ] = "Insert Cells" ;
+
+ ToolBox RID_TOOLBOX_INSCELLS
+ {
+ MenuStrings = TRUE ;
+ SVLook = TRUE ;
+ HelpID = RID_TOOLBOX_INSCELLS ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = FID_INS_CELLSDOWN ;
+ HelpId = FID_INS_CELLSDOWN ;
+ };
+ ToolBoxItem
+ {
+ Identifier = FID_INS_CELLSRIGHT ;
+ HelpId = FID_INS_CELLSRIGHT ;
+ };
+ ToolBoxItem
+ {
+ Identifier = FID_INS_ROW ;
+ HelpId = FID_INS_ROW ;
+ };
+ ToolBoxItem
+ {
+ Identifier = FID_INS_COLUMN ;
+ HelpId = FID_INS_COLUMN ;
+ };
+ };
+ };
+};
+
+FloatingWindow RID_TBXCTL_INSOBJ
+{
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Hide = TRUE ;
+ SVLook = TRUE;
+ HelpID = RID_TBXCTL_INSOBJ ;
+ /* ### ACHTUNG: Neuer Text in Resource? Objekt einfügen : Objekt einf³gen */
+ Text [ en-US ] = "Insert Object" ;
+ ToolBox RID_TOOLBOX_INSOBJ
+ {
+ MenuStrings = TRUE ;
+ SVLook = TRUE ;
+ HelpID = RID_TOOLBOX_INSOBJ ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ // mit Aufziehen des Zielbereichs
+ ITEM_TOOLBAR_DRAW_CHART
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_INSERT_SMATH ;
+ HelpId = SID_INSERT_SMATH ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_INSERT_FLOATINGFRAME ;
+ HelpID = SID_INSERT_FLOATINGFRAME ;
+ };
+ ToolBoxItem
+ {
+ Identifier = SID_INSERT_OBJECT ;
+ HelpId = SID_INSERT_OBJECT ;
+ };
+#ifdef SOLAR_PLUGIN
+ ToolBoxItem
+ {
+ Identifier = SID_INSERT_PLUGIN ;
+ HelpId = SID_INSERT_PLUGIN ;
+ };
+#endif
+#ifdef SOLAR_JAVA
+ ToolBoxItem
+ {
+ Identifier = SID_INSERT_APPLET ;
+ HelpId = SID_INSERT_APPLET ;
+ };
+#endif
+ };
+ };
+};
+
+// Don't use this image list for normal toolbar images. We have now our commandimagelist
+// folder in default_images. This list is now only used for special toolboxes that are
+// used in floating windows.
+
+#define DEFAULT_IDLIST \
+ IdList = { \
+ /* Eingabezeile */ \
+ SID_INPUT_FUNCTION; /* 20047 */ \
+ SID_INPUT_SUM; /* 20048 */ \
+ SID_INPUT_EQUAL; /* 20049 */ \
+ SID_INPUT_CANCEL; \
+ SID_INPUT_OK; \
+ }; \
+ IdCount = { \
+ 5; \
+ };
+
+ImageList RID_DEFAULTIMAGELIST_SC
+{
+ Prefix = "sc";
+ MaskColor = STD_MASKCOLOR ;
+ DEFAULT_IDLIST
+};
+
+ImageList RID_DEFAULTIMAGELIST_LC
+{
+ Prefix = "lc";
+ MaskColor = STD_MASKCOLOR ;
+ DEFAULT_IDLIST
+};
+
+ImageList RID_DEFAULTIMAGELIST_SCH
+{
+ Prefix = "sch";
+ MaskColor = SC_HC_MASKCOLOR ;
+ DEFAULT_IDLIST
+};
+
+ImageList RID_DEFAULTIMAGELIST_LCH
+{
+ Prefix = "lch";
+ MaskColor = SC_HC_MASKCOLOR ;
+ DEFAULT_IDLIST
+};
diff --git a/sc/source/ui/styleui/makefile.mk b/sc/source/ui/styleui/makefile.mk
new file mode 100644
index 000000000000..9361033a34a4
--- /dev/null
+++ b/sc/source/ui/styleui/makefile.mk
@@ -0,0 +1,57 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=styleui
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ styledlg.cxx
+
+SLOFILES = \
+ $(SLO)$/styledlg.obj \
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ scstyles.src \
+ styledlg.src
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/styleui/scstyles.src b/sc/source/ui/styleui/scstyles.src
new file mode 100644
index 000000000000..1968b6dca877
--- /dev/null
+++ b/sc/source/ui/styleui/scstyles.src
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+#include <svl/style.hrc>
+#define IMPL_FAMILY(family,filter) \
+ StyleFamily = family; \
+ FilterList = { filter }
+
+ //------------------------------------------------------------------------
+SfxStyleFamilies DLG_STYLE_DESIGNER
+{
+ StyleFamilyList =
+ {
+ SfxStyleFamilyItem
+ {
+ IMPL_FAMILY ( SFX_STYLE_FAMILY_PARA ,
+ < STR_STYLE_FILTER_ALL ; SFXSTYLEBIT_ALL ; > ;
+ < STR_STYLE_FILTER_USED ; SFXSTYLEBIT_USED ; > ;
+ < STR_STYLE_FILTER_USERDEF ; SFXSTYLEBIT_USERDEF ; > ; ) ;
+ Text [ en-US ] = "Cell Styles" ;
+};
+ SfxStyleFamilyItem
+ {
+ IMPL_FAMILY ( SFX_STYLE_FAMILY_PAGE ,
+ < STR_STYLE_FILTER_ALL ; SFXSTYLEBIT_ALL ; > ;
+ < STR_STYLE_FILTER_USERDEF ; SFXSTYLEBIT_USERDEF ; > ; ) ;
+ Text [ en-US ] = "Page Styles" ;
+};
+ };
+
+ // style family images are now taken from an ImageList
+ // (for each family, there's one entry in the IdList)
+ ImageList 1 // == BMP_COLOR_NORMAL + 1
+ {
+ Prefix = "sf";
+ MaskColor = STD_MASKCOLOR ;
+ IdList = { 1; 2; };
+};
+ ImageList 2 // == BMP_COLOR_HIGHCONTRAST + 1
+ {
+ Prefix = "sfh";
+ MaskColor = SC_HC_MASKCOLOR ;
+ IdList = { 1; 2; };
+};
+};
diff --git a/sc/source/ui/styleui/styledlg.cxx b/sc/source/ui/styleui/styledlg.cxx
new file mode 100644
index 000000000000..72a52520d1c1
--- /dev/null
+++ b/sc/source/ui/styleui/styledlg.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+#undef SC_DLLIMPLEMENTATION
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+//CHINA001 #include <svx/align.hxx>
+//CHINA001 #include <svx/backgrnd.hxx>
+//CHINA001 #include <svx/border.hxx>
+//CHINA001 #include <svx/chardlg.hxx>
+//CHINA001 #include <svx/numfmt.hxx>
+#include <svx/numinf.hxx> //CHINA001
+//CHINA001 #include <svx/page.hxx>
+//CHINA001 #include <svx/paragrph.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/style.hxx>
+#include <svl/cjkoptions.hxx>
+
+#include "styledlg.hxx"
+#include "tabpages.hxx" // Zellvorlagen
+#include "tphf.hxx" // Seitenvorlage: Kopf-/Fusszeilen
+#include "tptable.hxx" // Seitenvorlage: Tabelle
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "styledlg.hrc"
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/svxids.hrc> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+#include <svl/intitem.hxx> //CHINA001
+#include <editeng/flstitem.hxx> //CHINA001
+#include <svl/aeitem.hxx> //CHINA001
+#include <svx/flagsdef.hxx> //CHINA001
+//==================================================================
+
+ScStyleDlg::ScStyleDlg( Window* pParent,
+ SfxStyleSheetBase& rStyleBase,
+ USHORT nRscId )
+
+ : SfxStyleDialog ( pParent,
+ ScResId( nRscId ),
+ rStyleBase,
+ FALSE ),
+ nDlgRsc ( nRscId )
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); //CHINA001
+ DBG_ASSERT(pFact, "Dialogdiet fail!");//CHINA001
+ switch ( nRscId )
+ {
+ case RID_SCDLG_STYLES_PAR: // Zellformatvorlagen
+ {
+ SvtCJKOptions aCJKOptions;
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_NUMBERFORMAT ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_NUMBER, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_NUMBERFORMAT ) ); //CHINA001 AddTabPage( TP_NUMBER, &SvxNumberFormatTabPage::Create, &SvxNumberFormatTabPage::GetRanges );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_NAME ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_FONT, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_NAME ) ); //CHINA001 AddTabPage( TP_FONT, &SvxCharNamePage::Create, &SvxCharNamePage::GetRanges );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_EFFECTS ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_FONTEFF, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_EFFECTS ) ); //CHINA001 AddTabPage( TP_FONTEFF, &SvxCharEffectsPage::Create, &SvxCharEffectsPage::GetRanges );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGNMENT ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT( pFact->GetTabPageRangesFunc( RID_SVXPAGE_ALIGNMENT ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_ALIGNMENT, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGNMENT ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_ALIGNMENT ) ); //CHINA001 AddTabPage( TP_ALIGNMENT, &SvxAlignmentTabPage::Create, &SvxAlignmentTabPage::GetRanges );
+ if ( aCJKOptions.IsAsianTypographyEnabled() )
+ {
+ //CHINA001 AddTabPage( TP_ASIAN, &SvxAsianTabPage::Create, &SvxAsianTabPage::GetRanges );
+
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc(RID_SVXPAGE_PARA_ASIAN), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_ASIAN, pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN), pFact->GetTabPageRangesFunc(RID_SVXPAGE_PARA_ASIAN) );
+ }
+ else
+ RemoveTabPage( TP_ASIAN );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_BORDER, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ) ); //CHINA001 AddTabPage( TP_BORDER, &SvxBorderTabPage::Create, &SvxBorderTabPage::GetRanges );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BACKGROUND ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_BACKGROUND ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_BACKGROUND, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BACKGROUND ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BACKGROUND ) ); //CHINA001 AddTabPage( TP_BACKGROUND, &SvxBackgroundTabPage::Create, &SvxBackgroundTabPage::GetRanges );
+ AddTabPage( TP_PROTECTION, &ScTabPageProtection::Create, &ScTabPageProtection::GetRanges );
+ }
+ break;
+
+ case RID_SCDLG_STYLES_PAGE: // Seitenvorlagen
+ {
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PAGE ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_PAGE ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_PAGE_STD, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PAGE ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_PAGE ) ); //CHINA001 AddTabPage( TP_PAGE_STD, &SvxPageDescPage::Create, &SvxPageDescPage::GetRanges );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_BORDER, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ) ); //CHINA001 AddTabPage( TP_BORDER, &SvxBorderTabPage::Create, &SvxBorderTabPage::GetRanges );
+ DBG_ASSERT(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BACKGROUND ), "GetTabPageCreatorFunc fail!");//CHINA001
+ DBG_ASSERT(pFact->GetTabPageRangesFunc( RID_SVXPAGE_BACKGROUND ), "GetTabPageRangesFunc fail!");//CHINA001
+ AddTabPage( TP_BACKGROUND, pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BACKGROUND ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BACKGROUND ) ); //CHINA001 AddTabPage( TP_BACKGROUND, &SvxBackgroundTabPage::Create, &SvxBackgroundTabPage::GetRanges );
+ AddTabPage( TP_PAGE_HEADER, &ScHeaderPage::Create, &ScHeaderPage::GetRanges );
+ AddTabPage( TP_PAGE_FOOTER, &ScFooterPage::Create, &ScFooterPage::GetRanges );
+ AddTabPage( TP_TABLE, &ScTablePage::Create, &ScTablePage::GetRanges );
+ }
+ break;
+
+ default:
+ DBG_ERROR( "Family not supported" );
+ }
+
+ //--------------------------------------------------------------------
+ FreeResource();
+}
+
+// -----------------------------------------------------------------------
+
+__EXPORT ScStyleDlg::~ScStyleDlg()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScStyleDlg::PageCreated( USHORT nPageId, SfxTabPage& rTabPage )
+{
+ if ( nDlgRsc == RID_SCDLG_STYLES_PAR )
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); //CHINA001
+ switch ( nPageId )
+ {
+ case TP_NUMBER:
+ {
+ const SfxPoolItem* pInfoItem
+ = pDocSh->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
+
+ DBG_ASSERT( pInfoItem, "NumberInfoItem nicht gefunden!" );
+
+ //CHINA001 ((SvxNumberFormatTabPage&)rTabPage).
+ //CHINA001 SetNumberFormatList(
+ //CHINA001 (const SvxNumberInfoItem&)*pInfoItem ) ;
+ aSet.Put (SvxNumberInfoItem( (const SvxNumberInfoItem&)*pInfoItem ) );
+ rTabPage.PageCreated(aSet);
+ }
+ break;
+
+ case TP_FONT:
+ {
+ const SfxPoolItem* pInfoItem
+ = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
+
+ DBG_ASSERT( pInfoItem, "FontListItem nicht gefunden!" );
+
+ //CHINA001 ((SvxCharNamePage&)rTabPage).
+ //CHINA001 SetFontList(
+ //CHINA001 (const SvxFontListItem&)*pInfoItem );
+ aSet.Put (SvxFontListItem(((const SvxFontListItem&)*pInfoItem).GetFontList(), SID_ATTR_CHAR_FONTLIST));
+ rTabPage.PageCreated(aSet);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if ( nDlgRsc == RID_SCDLG_STYLES_PAGE )
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));//CHINA001
+ switch ( nPageId )
+ {
+ case TP_PAGE_STD:
+ //CHINA001 ((SvxPageDescPage&)rTabPage).SetMode( SVX_PAGE_MODE_CENTER );
+ aSet.Put (SfxAllEnumItem((const USHORT)SID_ENUM_PAGE_MODE, SVX_PAGE_MODE_CENTER)); //CHINA001
+ rTabPage.PageCreated(aSet); //CHINA001
+ break;
+
+ case TP_PAGE_HEADER:
+ case TP_PAGE_FOOTER:
+ ((ScHFPage&)rTabPage).SetStyleDlg( this );
+ ((ScHFPage&)rTabPage).SetPageStyle( GetStyleSheet().GetName() );
+ ((ScHFPage&)rTabPage).DisableDeleteQueryBox();
+ break;
+ case TP_BACKGROUND:
+ if( nDlgRsc == RID_SCDLG_STYLES_PAGE)
+ //CHINA001 ((SvxBackgroundTabPage&)rTabPage).ShowSelector();
+ { //add CHINA001
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, SVX_SHOW_SELECTOR));
+ rTabPage.PageCreated(aSet);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+const SfxItemSet* __EXPORT ScStyleDlg::GetRefreshedSet()
+{
+ SfxItemSet* pItemSet = GetInputSetImpl();
+ pItemSet->ClearItem();
+ pItemSet->SetParent( GetStyleSheet().GetItemSet().GetParent() );
+ return pItemSet;
+}
+
+
+
diff --git a/sc/source/ui/styleui/styledlg.src b/sc/source/ui/styleui/styledlg.src
new file mode 100644
index 000000000000..4c862e21ebd0
--- /dev/null
+++ b/sc/source/ui/styleui/styledlg.src
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sc.hrc"
+#include "styledlg.hrc" // -> TP_xxx
+TabDialog RID_SCDLG_STYLES_PAR
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 289 , 176 ) ;
+ Text [ en-US ] = "Cell Style" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 3 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = TP_NUMBER ;
+ Text [ en-US ] = "Numbers" ;
+ };
+ PageItem
+ {
+ Identifier = TP_FONT ;
+ /* ### ACHTUNG: Neuer Text in Resource? Schrift : Zeichen */
+ Text [ en-US ] = "Font" ;
+ };
+ PageItem
+ {
+ Identifier = TP_FONTEFF ;
+ Text [ en-US ] = "Font Effects";
+ };
+ PageItem
+ {
+ Identifier = TP_ALIGNMENT ;
+ Text [ en-US ] = "Alignment" ;
+ };
+ PageItem
+ {
+ Identifier = TP_ASIAN ;
+ Text [ en-US ] = "Asian Typography";
+ };
+ PageItem
+ {
+ Identifier = TP_BORDER ;
+ Text [ en-US ] = "Borders" ;
+ };
+ PageItem
+ {
+ Identifier = TP_BACKGROUND ;
+ Text [ en-US ] = "Background" ;
+ };
+ PageItem
+ {
+ Identifier = TP_PROTECTION ;
+ Text [ en-US ] = "Cell Protection" ;
+ };
+ };
+ };
+};
+TabDialog RID_SCDLG_STYLES_PAGE
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 280 , 165 ) ;
+ Text [ en-US ] = "Page Style" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ TabControl 1
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 6 ) ;
+ Size = MAP_APPFONT ( 260 , 135 ) ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = TP_PAGE_STD ;
+ Text [ en-US ] = "Page" ;
+ };
+ PageItem
+ {
+ Identifier = TP_BORDER ;
+ Text [ en-US ] = "Borders" ;
+ };
+ PageItem
+ {
+ Identifier = TP_BACKGROUND ;
+ Text [ en-US ] = "Background" ;
+ };
+ PageItem
+ {
+ Identifier = TP_PAGE_HEADER ;
+ Text [ en-US ] = "Header" ;
+ };
+ PageItem
+ {
+ Identifier = TP_PAGE_FOOTER ;
+ Text [ en-US ] = "Footer" ;
+ };
+ PageItem
+ {
+ Identifier = TP_TABLE ;
+ Text [ en-US ] = "Sheet" ;
+ };
+ };
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sc/source/ui/styleui/template.cur b/sc/source/ui/styleui/template.cur
new file mode 100644
index 000000000000..0fb6a1f5d0a9
--- /dev/null
+++ b/sc/source/ui/styleui/template.cur
Binary files differ
diff --git a/sc/source/ui/undo/areasave.cxx b/sc/source/ui/undo/areasave.cxx
new file mode 100644
index 000000000000..8f5ce350b887
--- /dev/null
+++ b/sc/source/ui/undo/areasave.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/linkmgr.hxx>
+#include <tools/debug.hxx>
+
+#include "areasave.hxx"
+#include "arealink.hxx"
+#include "document.hxx"
+
+// -----------------------------------------------------------------------
+
+ScAreaLinkSaver::ScAreaLinkSaver( const ScAreaLink& rSource ) :
+ aFileName ( rSource.GetFile() ),
+ aFilterName ( rSource.GetFilter() ),
+ aOptions ( rSource.GetOptions() ),
+ aSourceArea ( rSource.GetSource() ),
+ aDestArea ( rSource.GetDestArea() ),
+ nRefresh ( rSource.GetRefreshDelay() ) // seconds
+{
+}
+
+ScAreaLinkSaver::ScAreaLinkSaver( const ScAreaLinkSaver& rCopy ) :
+ ScDataObject(),
+ aFileName ( rCopy.aFileName ),
+ aFilterName ( rCopy.aFilterName ),
+ aOptions ( rCopy.aOptions ),
+ aSourceArea ( rCopy.aSourceArea ),
+ aDestArea ( rCopy.aDestArea ),
+ nRefresh ( rCopy.nRefresh )
+{
+}
+
+ScAreaLinkSaver::~ScAreaLinkSaver()
+{
+}
+
+ScDataObject* ScAreaLinkSaver::Clone() const
+{
+ return new ScAreaLinkSaver( *this );
+}
+
+BOOL ScAreaLinkSaver::IsEqualSource( const ScAreaLink& rCompare ) const
+{
+ return ( aFileName == rCompare.GetFile() &&
+ aFilterName == rCompare.GetFilter() &&
+ aOptions == rCompare.GetOptions() &&
+ aSourceArea == rCompare.GetSource() &&
+ nRefresh == rCompare.GetRefreshDelay() );
+}
+
+BOOL ScAreaLinkSaver::IsEqual( const ScAreaLink& rCompare ) const
+{
+ return ( IsEqualSource( rCompare ) &&
+ aDestArea == rCompare.GetDestArea() );
+}
+
+void ScAreaLinkSaver::WriteToLink( ScAreaLink& rLink ) const
+{
+ rLink.SetDestArea( aDestArea );
+}
+
+void ScAreaLinkSaver::InsertNewLink( ScDocument* pDoc ) const
+{
+ // (see ScUndoRemoveAreaLink::Undo)
+
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+
+ if ( pLinkManager && pObjSh )
+ {
+ ScAreaLink* pLink = new ScAreaLink( pObjSh, aFileName, aFilterName, aOptions,
+ aSourceArea, aDestArea.aStart, nRefresh );
+ pLink->SetInCreate( TRUE );
+ pLink->SetDestArea( aDestArea );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName, &aSourceArea );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ScAreaLinkSaveCollection::ScAreaLinkSaveCollection()
+{
+}
+
+ScAreaLinkSaveCollection::ScAreaLinkSaveCollection( const ScAreaLinkSaveCollection& rCopy ) :
+ ScCollection( rCopy )
+{
+}
+
+ScAreaLinkSaveCollection::~ScAreaLinkSaveCollection()
+{
+}
+
+ScDataObject* ScAreaLinkSaveCollection::Clone() const
+{
+ return new ScAreaLinkSaveCollection( *this );
+}
+
+BOOL ScAreaLinkSaveCollection::IsEqual( const ScDocument* pDoc ) const
+{
+ // IsEqual can be checked in sequence.
+ // Neither ref-update nor removing links will change the order.
+
+ sfx2::LinkManager* pLinkManager = const_cast<ScDocument*>(pDoc)->GetLinkManager();
+ if (pLinkManager)
+ {
+ USHORT nPos = 0;
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nLinkCount = rLinks.Count();
+ for (USHORT i=0; i<nLinkCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ {
+ if ( nPos >= GetCount() || !(*this)[nPos]->IsEqual( *(ScAreaLink*)pBase ) )
+ return FALSE;
+
+ ++nPos;
+ }
+ }
+ if ( nPos < GetCount() )
+ return FALSE; // fewer links in the document than in the save collection
+ }
+
+ return TRUE;
+}
+
+ScAreaLink* lcl_FindLink( const ::sfx2::SvBaseLinks& rLinks, const ScAreaLinkSaver& rSaver )
+{
+ USHORT nLinkCount = rLinks.Count();
+ for (USHORT i=0; i<nLinkCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if ( pBase->ISA(ScAreaLink) &&
+ rSaver.IsEqualSource( *static_cast<ScAreaLink*>(pBase) ) )
+ {
+ return static_cast<ScAreaLink*>(pBase); // found
+ }
+ }
+ return NULL; // not found
+}
+
+void ScAreaLinkSaveCollection::Restore( ScDocument* pDoc ) const
+{
+ // The save collection may contain additional entries that are not in the document.
+ // They must be inserted again.
+ // Entries from the save collection must be searched via source data, as the order
+ // of links changes if deleted entries are re-added to the link manager (always at the end).
+
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ if (pLinkManager)
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nSaveCount = GetCount();
+ for (USHORT nPos=0; nPos<nSaveCount; nPos++)
+ {
+ ScAreaLinkSaver* pSaver = (*this)[nPos];
+ ScAreaLink* pLink = lcl_FindLink( rLinks, *pSaver );
+ if ( pLink )
+ pSaver->WriteToLink( *pLink ); // restore output position
+ else
+ pSaver->InsertNewLink( pDoc ); // re-insert deleted link
+ }
+ }
+}
+
+// static
+ScAreaLinkSaveCollection* ScAreaLinkSaveCollection::CreateFromDoc( const ScDocument* pDoc )
+{
+ ScAreaLinkSaveCollection* pColl = NULL;
+
+ sfx2::LinkManager* pLinkManager = const_cast<ScDocument*>(pDoc)->GetLinkManager();
+ if (pLinkManager)
+ {
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nLinkCount = rLinks.Count();
+ for (USHORT i=0; i<nLinkCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ {
+ if (!pColl)
+ pColl = new ScAreaLinkSaveCollection;
+
+ ScAreaLinkSaver* pSaver = new ScAreaLinkSaver( *(ScAreaLink*)pBase );
+ if (!pColl->Insert(pSaver))
+ delete pSaver;
+ }
+ }
+ }
+
+ return pColl;
+}
+
diff --git a/sc/source/ui/undo/makefile.mk b/sc/source/ui/undo/makefile.mk
new file mode 100644
index 000000000000..50fab82972ca
--- /dev/null
+++ b/sc/source/ui/undo/makefile.mk
@@ -0,0 +1,85 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=undo
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ target.cxx \
+ refundo.cxx \
+ areasave.cxx \
+ undobase.cxx \
+ undoutil.cxx \
+ undocell.cxx \
+ undostyl.cxx \
+ undoolk.cxx \
+ undoblk.cxx \
+ undoblk2.cxx \
+ undoblk3.cxx \
+ undodat.cxx \
+ undodraw.cxx \
+ undotab.cxx
+
+
+
+SLOFILES = \
+ $(SLO)$/target.obj \
+ $(SLO)$/refundo.obj \
+ $(SLO)$/areasave.obj \
+ $(SLO)$/undobase.obj \
+ $(SLO)$/undoutil.obj \
+ $(SLO)$/undocell.obj \
+ $(SLO)$/undostyl.obj \
+ $(SLO)$/undoolk.obj \
+ $(SLO)$/undoblk.obj \
+ $(SLO)$/undoblk2.obj \
+ $(SLO)$/undoblk3.obj \
+ $(SLO)$/undodat.obj \
+ $(SLO)$/undodraw.obj \
+ $(SLO)$/undotab.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/undoblk3.obj \
+ $(SLO)$/undocell.obj \
+ $(SLO)$/undostyl.obj \
+ $(SLO)$/undotab.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/undo/refundo.cxx b/sc/source/ui/undo/refundo.cxx
new file mode 100644
index 000000000000..c863259ddf94
--- /dev/null
+++ b/sc/source/ui/undo/refundo.cxx
@@ -0,0 +1,214 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "refundo.hxx"
+#include "undobase.hxx"
+#include "document.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "pivot.hxx"
+#include "chartarr.hxx"
+#include "stlpool.hxx"
+#include "conditio.hxx"
+#include "detdata.hxx"
+#include "prnsave.hxx"
+#include "chartlis.hxx"
+#include "dpobject.hxx"
+#include "areasave.hxx"
+#include "unoreflist.hxx"
+
+// -----------------------------------------------------------------------
+
+ScRefUndoData::ScRefUndoData( const ScDocument* pDoc ) :
+ pUnoRefs( NULL )
+{
+ ScDBCollection* pOldDBColl = pDoc->GetDBCollection();
+ pDBCollection = pOldDBColl ? new ScDBCollection(*pOldDBColl) : NULL;
+
+ ScRangeName* pOldRanges = ((ScDocument*)pDoc)->GetRangeName(); //! const
+ pRangeName = pOldRanges ? new ScRangeName(*pOldRanges) : NULL;
+
+ pPrintRanges = pDoc->CreatePrintRangeSaver(); // neu erzeugt
+
+ //! bei Pivot nur Bereiche merken ???
+
+ ScDPCollection* pOldDP = ((ScDocument*)pDoc)->GetDPCollection(); //! const
+ pDPCollection = pOldDP ? new ScDPCollection(*pOldDP) : NULL;
+
+ ScConditionalFormatList* pOldCond = pDoc->GetCondFormList();
+ pCondFormList = pOldCond ? new ScConditionalFormatList(*pOldCond) : NULL;
+
+ ScDetOpList* pOldDetOp = pDoc->GetDetOpList();
+ pDetOpList = pOldDetOp ? new ScDetOpList(*pOldDetOp) : 0;
+
+ ScChartListenerCollection* pOldChartListenerCollection =
+ pDoc->GetChartListenerCollection();
+ pChartListenerCollection = pOldChartListenerCollection ?
+ new ScChartListenerCollection( *pOldChartListenerCollection ) : NULL;
+
+ pAreaLinks = ScAreaLinkSaveCollection::CreateFromDoc(pDoc); // returns NULL if empty
+
+ const_cast<ScDocument*>(pDoc)->BeginUnoRefUndo();
+}
+
+ScRefUndoData::~ScRefUndoData()
+{
+ delete pDBCollection;
+ delete pRangeName;
+ delete pPrintRanges;
+ delete pDPCollection;
+ delete pCondFormList;
+ delete pDetOpList;
+ delete pChartListenerCollection;
+ delete pAreaLinks;
+ delete pUnoRefs;
+}
+
+void ScRefUndoData::DeleteUnchanged( const ScDocument* pDoc )
+{
+ if (pDBCollection)
+ {
+ ScDBCollection* pNewDBColl = pDoc->GetDBCollection();
+ if ( pNewDBColl && *pDBCollection == *pNewDBColl )
+ DELETEZ(pDBCollection);
+ }
+ if (pRangeName)
+ {
+ ScRangeName* pNewRanges = ((ScDocument*)pDoc)->GetRangeName(); //! const
+ if ( pNewRanges && *pRangeName == *pNewRanges )
+ DELETEZ(pRangeName);
+ }
+
+ if (pPrintRanges)
+ {
+ ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
+ if ( pNewRanges && *pPrintRanges == *pNewRanges )
+ DELETEZ(pPrintRanges);
+ delete pNewRanges;
+ }
+
+ if (pDPCollection)
+ {
+ ScDPCollection* pNewDP = ((ScDocument*)pDoc)->GetDPCollection(); //! const
+ if ( pNewDP && pDPCollection->RefsEqual(*pNewDP) )
+ DELETEZ(pDPCollection);
+ }
+
+ if (pCondFormList)
+ {
+ ScConditionalFormatList* pNewCond = pDoc->GetCondFormList();
+ if ( pNewCond && *pCondFormList == *pNewCond )
+ DELETEZ(pCondFormList);
+ }
+
+ if (pDetOpList)
+ {
+ ScDetOpList* pNewDetOp = pDoc->GetDetOpList();
+ if ( pNewDetOp && *pDetOpList == *pNewDetOp )
+ DELETEZ(pDetOpList);
+ }
+
+ if ( pChartListenerCollection )
+ {
+ ScChartListenerCollection* pNewChartListenerCollection =
+ pDoc->GetChartListenerCollection();
+ if ( pNewChartListenerCollection &&
+ *pChartListenerCollection == *pNewChartListenerCollection )
+ DELETEZ( pChartListenerCollection );
+ }
+
+ if (pAreaLinks)
+ {
+ if ( pAreaLinks->IsEqual( pDoc ) )
+ DELETEZ(pAreaLinks);
+ }
+
+ if ( pDoc->HasUnoRefUndo() )
+ {
+ pUnoRefs = const_cast<ScDocument*>(pDoc)->EndUnoRefUndo();
+ if ( pUnoRefs && pUnoRefs->IsEmpty() )
+ {
+ DELETEZ( pUnoRefs );
+ }
+ }
+}
+
+void ScRefUndoData::DoUndo( ScDocument* pDoc, BOOL bUndoRefFirst )
+{
+ if (pDBCollection)
+ pDoc->SetDBCollection( new ScDBCollection(*pDBCollection) );
+ if (pRangeName)
+ pDoc->SetRangeName( new ScRangeName(*pRangeName) );
+
+ if (pPrintRanges)
+ pDoc->RestorePrintRanges(*pPrintRanges);
+
+ if (pDPCollection)
+ {
+ ScDPCollection* pDocDP = pDoc->GetDPCollection();
+ if (pDocDP)
+ pDPCollection->WriteRefsTo( *pDocDP );
+ }
+
+ if (pCondFormList)
+ pDoc->SetCondFormList( new ScConditionalFormatList(*pCondFormList) );
+ if (pDetOpList)
+ pDoc->SetDetOpList( new ScDetOpList(*pDetOpList) );
+
+ // #65055# bUndoRefFirst ist bSetChartRangeLists
+ if ( pChartListenerCollection )
+ pDoc->SetChartListenerCollection( new ScChartListenerCollection(
+ *pChartListenerCollection ), bUndoRefFirst );
+
+ if (pDBCollection || pRangeName)
+ {
+ BOOL bOldAutoCalc = pDoc->GetAutoCalc();
+ pDoc->SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
+ pDoc->CompileAll();
+ pDoc->SetDirty();
+ pDoc->SetAutoCalc( bOldAutoCalc );
+ }
+
+ if (pAreaLinks)
+ pAreaLinks->Restore( pDoc );
+
+ if ( pUnoRefs )
+ pUnoRefs->Undo( pDoc );
+}
+
+
+
+
diff --git a/sc/source/ui/undo/target.cxx b/sc/source/ui/undo/target.cxx
new file mode 100644
index 000000000000..1c2e4a925378
--- /dev/null
+++ b/sc/source/ui/undo/target.cxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "target.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScTabViewTarget, SfxRepeatTarget);
+
+__EXPORT ScTabViewTarget::~ScTabViewTarget()
+{
+}
diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx
new file mode 100644
index 000000000000..fffb76ebd061
--- /dev/null
+++ b/sc/source/ui/undo/undobase.cxx
@@ -0,0 +1,539 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/virdev.hxx>
+
+#include "undobase.hxx"
+#include "refundo.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "undoolk.hxx"
+#include "undodraw.hxx"
+#include "dbcolect.hxx"
+#include "attrib.hxx"
+#include "queryparam.hxx"
+#include "globstr.hrc"
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScSimpleUndo, SfxUndoAction);
+TYPEINIT1(ScBlockUndo, ScSimpleUndo);
+TYPEINIT1(ScMoveUndo, ScSimpleUndo);
+TYPEINIT1(ScDBFuncUndo, ScSimpleUndo);
+TYPEINIT1(ScUndoWrapper, SfxUndoAction);
+
+// -----------------------------------------------------------------------
+
+ScSimpleUndo::ScSimpleUndo( ScDocShell* pDocSh ) :
+ pDocShell( pDocSh ),
+ pDetectiveUndo( NULL )
+{
+}
+
+__EXPORT ScSimpleUndo::~ScSimpleUndo()
+{
+ delete pDetectiveUndo;
+}
+
+BOOL __EXPORT ScSimpleUndo::Merge( SfxUndoAction *pNextAction )
+{
+ // Zu jeder Undo-Action kann eine SdrUndoGroup fuer das Aktualisieren
+ // der Detektiv-Pfeile gehoeren.
+ // DetectiveRefresh kommt immer hinterher, die SdrUndoGroup ist in
+ // eine ScUndoDraw Action verpackt.
+ // Nur beim automatischen Aktualisieren wird AddUndoAction mit
+ // bTryMerg=TRUE gerufen.
+
+ if ( !pDetectiveUndo && pNextAction->ISA(ScUndoDraw) )
+ {
+ // SdrUndoAction aus der ScUndoDraw Action uebernehmen,
+ // ScUndoDraw wird dann vom UndoManager geloescht
+
+ ScUndoDraw* pCalcUndo = (ScUndoDraw*)pNextAction;
+ pDetectiveUndo = pCalcUndo->GetDrawUndo();
+ pCalcUndo->ForgetDrawUndo();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ScSimpleUndo::BeginUndo()
+{
+ pDocShell->SetInUndo( TRUE );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->HideAllCursors(); // z.B. wegen zusammengefassten Zellen
+
+ // detective updates happened last, must be undone first
+ if (pDetectiveUndo)
+ pDetectiveUndo->Undo();
+}
+
+void ScSimpleUndo::EndUndo()
+{
+ pDocShell->SetDocumentModified();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->UpdateAutoFillMark();
+ pViewShell->UpdateInputHandler();
+ pViewShell->ShowAllCursors();
+ }
+
+ pDocShell->SetInUndo( FALSE );
+}
+
+void ScSimpleUndo::BeginRedo()
+{
+ pDocShell->SetInUndo( TRUE ); //! eigenes Flag fuer Redo?
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->HideAllCursors(); // z.B. wegen zusammengefassten Zellen
+}
+
+void ScSimpleUndo::EndRedo()
+{
+ if (pDetectiveUndo)
+ pDetectiveUndo->Redo();
+
+ pDocShell->SetDocumentModified();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->UpdateAutoFillMark();
+ pViewShell->UpdateInputHandler();
+ pViewShell->ShowAllCursors();
+ }
+
+ pDocShell->SetInUndo( FALSE );
+}
+
+void ScSimpleUndo::ShowTable( SCTAB nTab ) // static
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetTabNo( nTab );
+}
+
+void ScSimpleUndo::ShowTable( const ScRange& rRange ) // static
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ SCTAB nStart = rRange.aStart.Tab();
+ SCTAB nEnd = rRange.aEnd.Tab();
+ SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nTab < nStart || nTab > nEnd ) // wenn nicht im Bereich:
+ pViewShell->SetTabNo( nStart ); // auf erste des Bereiches
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+ScBlockUndo::ScBlockUndo( ScDocShell* pDocSh, const ScRange& rRange,
+ ScBlockUndoMode eBlockMode ) :
+ ScSimpleUndo( pDocSh ),
+ aBlockRange( rRange ),
+ eMode( eBlockMode )
+{
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+}
+
+__EXPORT ScBlockUndo::~ScBlockUndo()
+{
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+void ScBlockUndo::BeginUndo()
+{
+ ScSimpleUndo::BeginUndo();
+ EnableDrawAdjust( pDocShell->GetDocument(), FALSE );
+}
+
+void ScBlockUndo::EndUndo()
+{
+ if (eMode == SC_UNDO_AUTOHEIGHT)
+ AdjustHeight();
+
+ EnableDrawAdjust( pDocShell->GetDocument(), TRUE );
+ DoSdrUndoAction( pDrawUndo, pDocShell->GetDocument() );
+
+ ShowBlock();
+ ScSimpleUndo::EndUndo();
+}
+
+/*
+void ScBlockUndo::BeginRedo()
+{
+ ScSimpleUndo::BeginRedo();
+}
+*/
+
+void ScBlockUndo::EndRedo()
+{
+ if (eMode == SC_UNDO_AUTOHEIGHT)
+ AdjustHeight();
+
+ ShowBlock();
+ ScSimpleUndo::EndRedo();
+}
+
+BOOL ScBlockUndo::AdjustHeight()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ VirtualDevice aVirtDev;
+ Fraction aZoomX( 1, 1 );
+ Fraction aZoomY = aZoomX;
+ double nPPTX, nPPTY;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ ScViewData* pData = pViewShell->GetViewData();
+ nPPTX = pData->GetPPTX();
+ nPPTY = pData->GetPPTY();
+ aZoomX = pData->GetZoomX();
+ aZoomY = pData->GetZoomY();
+ }
+ else
+ {
+ // Zoom auf 100 lassen
+ nPPTX = ScGlobal::nScreenPPTX;
+ nPPTY = ScGlobal::nScreenPPTY;
+ }
+
+ BOOL bRet = pDoc->SetOptimalHeight( aBlockRange.aStart.Row(), aBlockRange.aEnd.Row(),
+/*!*/ aBlockRange.aStart.Tab(), 0, &aVirtDev,
+ nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
+
+ if (bRet)
+ pDocShell->PostPaint( 0, aBlockRange.aStart.Row(), aBlockRange.aStart.Tab(),
+ MAXCOL, MAXROW, aBlockRange.aEnd.Tab(),
+ PAINT_GRID | PAINT_LEFT );
+
+ return bRet;
+}
+
+void ScBlockUndo::ShowBlock()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ ShowTable( aBlockRange ); // bei mehreren Tabs im Range ist jede davon gut
+ pViewShell->MoveCursorAbs( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
+ SC_FOLLOW_JUMP, FALSE, FALSE );
+ SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
+ ScRange aRange = aBlockRange;
+ aRange.aStart.SetTab( nTab );
+ aRange.aEnd.SetTab( nTab );
+ pViewShell->MarkRange( aRange );
+
+ // nicht per SetMarkArea an MarkData, wegen evtl. fehlendem Paint
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+ScMoveUndo::ScMoveUndo( ScDocShell* pDocSh, ScDocument* pRefDoc, ScRefUndoData* pRefData,
+ ScMoveUndoMode eRefMode ) :
+ ScSimpleUndo( pDocSh ),
+ pRefUndoDoc( pRefDoc ),
+ pRefUndoData( pRefData ),
+ eMode( eRefMode )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pRefUndoData)
+ pRefUndoData->DeleteUnchanged(pDoc);
+ pDrawUndo = GetSdrUndoAction( pDoc );
+}
+
+__EXPORT ScMoveUndo::~ScMoveUndo()
+{
+ delete pRefUndoData;
+ delete pRefUndoDoc;
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+void ScMoveUndo::UndoRef()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRange aRange(0,0,0, MAXCOL,MAXROW,pRefUndoDoc->GetTableCount()-1);
+ pRefUndoDoc->CopyToDocument( aRange, IDF_FORMULA, FALSE, pDoc, NULL, FALSE );
+ if (pRefUndoData)
+ pRefUndoData->DoUndo( pDoc, (eMode == SC_UNDO_REFFIRST) );
+ // #65055# HACK: ScDragDropUndo ist der einzige mit REFFIRST.
+ // Falls nicht, resultiert daraus evtl. ein zu haeufiges Anpassen
+ // der ChartRefs, nicht schoen, aber auch nicht schlecht..
+}
+
+void ScMoveUndo::BeginUndo()
+{
+ ScSimpleUndo::BeginUndo();
+
+ EnableDrawAdjust( pDocShell->GetDocument(), FALSE );
+
+ if (pRefUndoDoc && eMode == SC_UNDO_REFFIRST)
+ UndoRef();
+}
+
+void ScMoveUndo::EndUndo()
+{
+ //@17.12.97 Reihenfolge der Fkt.s geaendert
+ DoSdrUndoAction( pDrawUndo, pDocShell->GetDocument() ); // #125875# must also be called when pointer is null
+
+ if (pRefUndoDoc && eMode == SC_UNDO_REFLAST)
+ UndoRef();
+
+ EnableDrawAdjust( pDocShell->GetDocument(), TRUE );
+
+ ScSimpleUndo::EndUndo();
+}
+
+/*
+void ScMoveUndo::BeginRedo()
+{
+ ScSimpleUndo::BeginRedo();
+}
+*/
+
+/*
+void ScMoveUndo::EndRedo()
+{
+ ScSimpleUndo::EndRedo();
+}
+*/
+
+// -----------------------------------------------------------------------
+
+ScDBFuncUndo::ScDBFuncUndo( ScDocShell* pDocSh, const ScRange& rOriginal, SdrUndoAction* pDrawUndo ) :
+ ScSimpleUndo( pDocSh ),
+ aOriginalRange( rOriginal ),
+ mpDrawUndo( pDrawUndo )
+{
+ pAutoDBRange = pDocSh->GetOldAutoDBRange();
+}
+
+ScDBFuncUndo::~ScDBFuncUndo()
+{
+ DeleteSdrUndoAction( mpDrawUndo );
+ delete pAutoDBRange;
+}
+
+void ScDBFuncUndo::SetDrawUndoAction( SdrUndoAction* pDrawUndo )
+{
+ DeleteSdrUndoAction( mpDrawUndo );
+ mpDrawUndo = pDrawUndo;
+}
+
+void ScDBFuncUndo::BeginUndo()
+{
+ ScSimpleUndo::BeginUndo();
+ DoSdrUndoAction( mpDrawUndo, pDocShell->GetDocument() );
+}
+
+void ScDBFuncUndo::EndUndo()
+{
+ ScSimpleUndo::EndUndo();
+
+ if ( pAutoDBRange )
+ {
+ USHORT nNoNameIndex;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ if ( pColl->SearchName( ScGlobal::GetRscString( STR_DB_NONAME ), nNoNameIndex ) )
+ {
+ ScDBData* pNoNameData = (*pColl)[nNoNameIndex];
+
+ SCCOL nRangeX1;
+ SCROW nRangeY1;
+ SCCOL nRangeX2;
+ SCROW nRangeY2;
+ SCTAB nRangeTab;
+ pNoNameData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+ pDocShell->DBAreaDeleted( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+
+ *pNoNameData = *pAutoDBRange;
+
+ if ( pAutoDBRange->HasAutoFilter() )
+ {
+ // restore AutoFilter buttons
+ pAutoDBRange->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+ pDoc->ApplyFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, SC_MF_AUTO );
+ pDocShell->PostPaint( nRangeX1, nRangeY1, nRangeTab, nRangeX2, nRangeY1, nRangeTab, PAINT_GRID );
+ }
+ }
+ }
+}
+
+void ScDBFuncUndo::BeginRedo()
+{
+ RedoSdrUndoAction( mpDrawUndo );
+ if ( pAutoDBRange )
+ {
+ // move the database range to this function's position again (see ScDocShell::GetDBData)
+
+ USHORT nNoNameIndex;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ if ( pColl->SearchName( ScGlobal::GetRscString( STR_DB_NONAME ), nNoNameIndex ) )
+ {
+ ScDBData* pNoNameData = (*pColl)[nNoNameIndex];
+
+ SCCOL nRangeX1;
+ SCROW nRangeY1;
+ SCCOL nRangeX2;
+ SCROW nRangeY2;
+ SCTAB nRangeTab;
+ pNoNameData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+ pDocShell->DBAreaDeleted( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+
+ pNoNameData->SetSortParam( ScSortParam() );
+ pNoNameData->SetQueryParam( ScQueryParam() );
+ pNoNameData->SetSubTotalParam( ScSubTotalParam() );
+
+ pNoNameData->SetArea( aOriginalRange.aStart.Tab(),
+ aOriginalRange.aStart.Col(), aOriginalRange.aStart.Row(),
+ aOriginalRange.aEnd.Col(), aOriginalRange.aEnd.Row() );
+
+ pNoNameData->SetByRow( TRUE );
+ pNoNameData->SetAutoFilter( FALSE );
+ // header is always set with the operation in redo
+ }
+ }
+
+ ScSimpleUndo::BeginRedo();
+}
+
+void ScDBFuncUndo::EndRedo()
+{
+ ScSimpleUndo::EndRedo();
+}
+
+// -----------------------------------------------------------------------
+
+ScUndoWrapper::ScUndoWrapper( SfxUndoAction* pUndo ) :
+ pWrappedUndo( pUndo )
+{
+}
+
+ScUndoWrapper::~ScUndoWrapper()
+{
+ delete pWrappedUndo;
+}
+
+void ScUndoWrapper::ForgetWrappedUndo()
+{
+ pWrappedUndo = NULL; // don't delete in dtor - pointer must be stored outside
+}
+
+String ScUndoWrapper::GetComment() const
+{
+ if (pWrappedUndo)
+ return pWrappedUndo->GetComment();
+ else
+ return String();
+}
+
+String ScUndoWrapper::GetRepeatComment(SfxRepeatTarget& rTarget) const
+{
+ if (pWrappedUndo)
+ return pWrappedUndo->GetRepeatComment(rTarget);
+ else
+ return String();
+}
+
+USHORT ScUndoWrapper::GetId() const
+{
+ if (pWrappedUndo)
+ return pWrappedUndo->GetId();
+ else
+ return 0;
+}
+
+BOOL ScUndoWrapper::IsLinked()
+{
+ if (pWrappedUndo)
+ return pWrappedUndo->IsLinked();
+ else
+ return FALSE;
+}
+
+void ScUndoWrapper::SetLinked( BOOL bIsLinked )
+{
+ if (pWrappedUndo)
+ pWrappedUndo->SetLinked(bIsLinked);
+}
+
+BOOL ScUndoWrapper::Merge( SfxUndoAction* pNextAction )
+{
+ if (pWrappedUndo)
+ return pWrappedUndo->Merge(pNextAction);
+ else
+ return FALSE;
+}
+
+void ScUndoWrapper::Undo()
+{
+ if (pWrappedUndo)
+ pWrappedUndo->Undo();
+}
+
+void ScUndoWrapper::Redo()
+{
+ if (pWrappedUndo)
+ pWrappedUndo->Redo();
+}
+
+void ScUndoWrapper::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (pWrappedUndo)
+ pWrappedUndo->Repeat(rTarget);
+}
+
+BOOL ScUndoWrapper::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ if (pWrappedUndo)
+ return pWrappedUndo->CanRepeat(rTarget);
+ else
+ return FALSE;
+}
+
+
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
new file mode 100644
index 000000000000..3fb2c74a9954
--- /dev/null
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -0,0 +1,2253 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <vcl/virdev.hxx>
+#include <vcl/waitobj.hxx>
+#include <editeng/boxitem.hxx>
+#include <sfx2/app.hxx>
+
+#include "undoblk.hxx"
+#include "undoutil.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "dbcolect.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "target.hxx"
+#include "docpool.hxx"
+#include "docfunc.hxx"
+#include "attrib.hxx"
+#include "chgtrack.hxx"
+#include "transobj.hxx"
+#include "refundo.hxx"
+#include "undoolk.hxx"
+#include "clipparam.hxx"
+#include "sc.hrc"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScUndoInsertCells, SfxUndoAction);
+TYPEINIT1(ScUndoDeleteCells, SfxUndoAction);
+TYPEINIT1(ScUndoDeleteMulti, SfxUndoAction);
+TYPEINIT1(ScUndoCut, ScBlockUndo);
+TYPEINIT1(ScUndoPaste, SfxUndoAction);
+TYPEINIT1(ScUndoDragDrop, SfxUndoAction);
+TYPEINIT1(ScUndoListNames, SfxUndoAction);
+TYPEINIT1(ScUndoUseScenario, SfxUndoAction);
+TYPEINIT1(ScUndoSelectionStyle, SfxUndoAction);
+TYPEINIT1(ScUndoEnterMatrix, ScBlockUndo);
+TYPEINIT1(ScUndoIndent, ScBlockUndo);
+TYPEINIT1(ScUndoTransliterate, ScBlockUndo);
+TYPEINIT1(ScUndoClearItems, ScBlockUndo);
+TYPEINIT1(ScUndoRemoveBreaks, SfxUndoAction);
+TYPEINIT1(ScUndoRemoveMerge, ScBlockUndo);
+TYPEINIT1(ScUndoBorder, ScBlockUndo);
+
+
+
+// To Do:
+/*A*/ // SetOptimalHeight auf Dokument, wenn keine View
+/*B*/ // gelinkte Tabellen
+/*C*/ // ScArea
+//? // spaeter mal pruefen
+
+
+// -----------------------------------------------------------------------
+//
+// Zellen einfuegen
+// Zeilen einfuegen
+// einzeln oder Block
+//
+
+ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell,
+ const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
+ InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
+ BOOL bNewPartOfPaste ) :
+ ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
+ aEffRange( rRange ),
+ nCount( nNewCount ),
+ pTabs( pNewTabs ),
+ pScenarios( pNewScenarios ),
+ eCmd( eNewCmd ),
+ bPartOfPaste( bNewPartOfPaste ),
+ pPasteUndo( NULL )
+{
+ if (eCmd == INS_INSROWS) // ganze Zeilen?
+ {
+ aEffRange.aStart.SetCol(0);
+ aEffRange.aEnd.SetCol(MAXCOL);
+ }
+
+ if (eCmd == INS_INSCOLS) // ganze Spalten?
+ {
+ aEffRange.aStart.SetRow(0);
+ aEffRange.aEnd.SetRow(MAXROW);
+ }
+
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoInsertCells::~ScUndoInsertCells()
+{
+ delete pPasteUndo;
+ delete []pTabs;
+ delete []pScenarios;
+}
+
+String __EXPORT ScUndoInsertCells::GetComment() const
+{
+ return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS );
+}
+
+BOOL ScUndoInsertCells::Merge( SfxUndoAction* pNextAction )
+{
+ // If a paste undo action has already been added, append (detective) action there.
+ if ( pPasteUndo )
+ return pPasteUndo->Merge( pNextAction );
+
+ if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) )
+ {
+ ScUndoWrapper* pWrapper = (ScUndoWrapper*)pNextAction;
+ SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo();
+ if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) )
+ {
+ // Store paste action if this is part of paste with inserting cells.
+ // A list action isn't used because Repeat wouldn't work (insert wrong cells).
+
+ pPasteUndo = pWrappedAction;
+ pWrapper->ForgetWrappedUndo(); // pWrapper is deleted by UndoManager
+ return TRUE;
+ }
+ }
+
+ // Call base class for detective handling
+ return ScMoveUndo::Merge( pNextAction );
+}
+
+void ScUndoInsertCells::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ pChangeTrack->AppendInsert( aEffRange );
+ nEndChangeAction = pChangeTrack->GetActionMax();
+ }
+ else
+ nEndChangeAction = 0;
+}
+
+void ScUndoInsertCells::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB i;
+
+ if ( bUndo )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
+ }
+ else
+ SetChangeTrack();
+
+ // refresh of merged cells has to be after inserting/deleting
+
+ switch (eCmd)
+ {
+ case INS_INSROWS:
+ case INS_CELLSDOWN:
+ for( i=0; i<nCount; i++ )
+ {
+ if (bUndo)
+ pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
+ else
+ pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
+ }
+ break;
+ case INS_INSCOLS:
+ case INS_CELLSRIGHT:
+ for( i=0; i<nCount; i++ )
+ {
+ if (bUndo)
+ pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
+ else
+ pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ ScRange aWorkRange( aEffRange );
+ if ( eCmd == INS_CELLSRIGHT ) // only "shift right" requires refresh of the moved area
+ aWorkRange.aEnd.SetCol(MAXCOL);
+ for( i=0; i<nCount; i++ )
+ {
+ if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
+ aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) )
+ {
+ SCCOL nEndCol = aWorkRange.aEnd.Col();
+ SCROW nEndRow = aWorkRange.aEnd.Row();
+ pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], TRUE );
+ }
+ }
+
+//? Undo fuer herausgeschobene Attribute ?
+
+ USHORT nPaint = PAINT_GRID;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ switch (eCmd)
+ {
+ case INS_INSROWS:
+ nPaint |= PAINT_LEFT;
+ aWorkRange.aEnd.SetRow(MAXROW);
+ break;
+ case INS_CELLSDOWN:
+ for( i=0; i<nCount; i++ )
+ {
+ aWorkRange.aEnd.SetRow(MAXROW);
+ if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
+ {
+ aWorkRange.aStart.SetCol(0);
+ aWorkRange.aEnd.SetCol(MAXCOL);
+ nPaint |= PAINT_LEFT;
+ }
+ }
+ break;
+ case INS_INSCOLS:
+ nPaint |= PAINT_TOP; // obere Leiste
+ case INS_CELLSRIGHT:
+ for( i=0; i<nCount; i++ )
+ {
+ aWorkRange.aEnd.SetCol(MAXCOL); // bis ganz nach rechts
+ if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) )
+ { // AdjustDraw zeichnet PAINT_TOP nicht,
+ aWorkRange.aStart.SetCol(0); // daher so geloest
+ aWorkRange.aEnd.SetRow(MAXROW);
+ nPaint |= PAINT_LEFT;
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ for( i=0; i<nCount; i++ )
+ {
+ pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
+ aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint );
+ }
+ pDocShell->PostDataChanged();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+}
+
+void __EXPORT ScUndoInsertCells::Undo()
+{
+ if ( pPasteUndo )
+ pPasteUndo->Undo(); // undo paste first
+
+ WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+void __EXPORT ScUndoInsertCells::Redo()
+{
+ WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+
+ if ( pPasteUndo )
+ pPasteUndo->Redo(); // redo paste last
+}
+
+void __EXPORT ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ if ( pPasteUndo )
+ {
+ // #94115# Repeat for paste with inserting cells is handled completely
+ // by the Paste undo action
+
+ pPasteUndo->Repeat( rTarget );
+ }
+ else
+ ((ScTabViewTarget&)rTarget).GetViewShell()->InsertCells( eCmd, TRUE );
+ }
+}
+
+BOOL __EXPORT ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Zellen loeschen
+// Zeilen loeschen
+// einzeln oder Block
+//
+
+ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell,
+ const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
+ DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
+ ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
+ aEffRange( rRange ),
+ nCount( nNewCount ),
+ pTabs( pNewTabs ),
+ pScenarios( pNewScenarios ),
+ eCmd( eNewCmd )
+{
+ if (eCmd == DEL_DELROWS) // gaze Zeilen?
+ {
+ aEffRange.aStart.SetCol(0);
+ aEffRange.aEnd.SetCol(MAXCOL);
+ }
+
+ if (eCmd == DEL_DELCOLS) // ganze Spalten?
+ {
+ aEffRange.aStart.SetRow(0);
+ aEffRange.aEnd.SetRow(MAXROW);
+ }
+
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoDeleteCells::~ScUndoDeleteCells()
+{
+ delete []pTabs;
+ delete []pScenarios;
+}
+
+String __EXPORT ScUndoDeleteCells::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Loeschen"
+}
+
+void ScUndoDeleteCells::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void ScUndoDeleteCells::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB i;
+
+ if ( bUndo )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+ }
+ else
+ SetChangeTrack();
+
+ // Ausfuehren
+ switch (eCmd)
+ {
+ case DEL_DELROWS:
+ case DEL_CELLSUP:
+ for( i=0; i<nCount; i++ )
+ {
+ if (bUndo)
+ pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
+ else
+ pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
+ }
+ break;
+ case DEL_DELCOLS:
+ case DEL_CELLSLEFT:
+ for( i=0; i<nCount; i++ )
+ {
+ if (bUndo)
+ pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
+ else
+ pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
+ aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ // bei Undo Referenzen wiederherstellen
+ for( i=0; i<nCount && bUndo; i++ )
+ {
+ pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
+ IDF_ALL | IDF_NOCAPTIONS, FALSE, pDoc );
+ }
+
+ ScRange aWorkRange( aEffRange );
+ if ( eCmd == DEL_CELLSLEFT ) // only "shift left" requires refresh of the moved area
+ aWorkRange.aEnd.SetCol(MAXCOL);
+
+ for( i=0; i<nCount; i++ )
+ {
+ if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
+ aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ // #i51445# old merge flag attributes must be deleted also for single cells,
+ // not only for whole columns/rows
+
+ if ( !bUndo )
+ {
+ if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
+ aWorkRange.aEnd.SetCol(MAXCOL);
+ if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
+ aWorkRange.aEnd.SetRow(MAXROW);
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( aWorkRange.aStart.Tab() );
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr() );
+ pDoc->ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(),
+ aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(),
+ aMarkData, aPattern );
+ }
+
+ SCCOL nEndCol = aWorkRange.aEnd.Col();
+ SCROW nEndRow = aWorkRange.aEnd.Row();
+ pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], TRUE );
+ }
+ }
+
+ // Zeichnen
+ USHORT nPaint = PAINT_GRID;
+ switch (eCmd)
+ {
+ case DEL_DELROWS:
+ nPaint |= PAINT_LEFT;
+ aWorkRange.aEnd.SetRow(MAXROW);
+ break;
+ case DEL_CELLSUP:
+ for( i=0; i<nCount; i++ )
+ {
+ aWorkRange.aEnd.SetRow(MAXROW);
+ if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
+ {
+ aWorkRange.aStart.SetCol(0);
+ aWorkRange.aEnd.SetCol(MAXCOL);
+ nPaint |= PAINT_LEFT;
+ }
+ }
+ break;
+ case DEL_DELCOLS:
+ nPaint |= PAINT_TOP; // obere Leiste
+ case DEL_CELLSLEFT:
+ for( i=0; i<nCount; i++ )
+ {
+ aWorkRange.aEnd.SetCol(MAXCOL); // bis ganz nach rechts
+ if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) )
+ {
+ aWorkRange.aStart.SetCol(0);
+ aWorkRange.aEnd.SetRow(MAXROW);
+ nPaint |= PAINT_LEFT;
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ for( i=0; i<nCount; i++ )
+ {
+ pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
+ aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES );
+ }
+ // Markierung erst nach EndUndo
+
+ pDocShell->PostDataChanged();
+ // CellContentChanged kommt mit der Markierung
+}
+
+void __EXPORT ScUndoDeleteCells::Undo()
+{
+ WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+
+ // Markierung erst nach EndUndo
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ for( SCTAB i=0; i<nCount; i++ )
+ {
+ pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) );
+ }
+ }
+}
+
+void __EXPORT ScUndoDeleteCells::Redo()
+{
+ WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+ BeginRedo();
+ DoChange( FALSE);
+ EndRedo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->DoneBlockMode(); // aktuelle weg
+}
+
+void __EXPORT ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( eCmd, TRUE );
+}
+
+BOOL __EXPORT ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Zellen loeschen auf Mehrfachselektion
+//
+
+ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell,
+ BOOL bNewRows, BOOL bNeedsRefresh, SCTAB nNewTab,
+ const SCCOLROW* pRng, SCCOLROW nRngCnt,
+ ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
+ ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
+ bRows( bNewRows ),
+ bRefresh( bNeedsRefresh ),
+ nTab( nNewTab ),
+ nRangeCnt( nRngCnt )
+{
+ pRanges = new SCCOLROW[ 2 * nRangeCnt ];
+ memcpy(pRanges,pRng,nRangeCnt*2*sizeof(SCCOLROW));
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoDeleteMulti::~ScUndoDeleteMulti()
+{
+ delete [] pRanges;
+}
+
+String __EXPORT ScUndoDeleteMulti::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // wie DeleteCells
+}
+
+void ScUndoDeleteMulti::DoChange() const
+{
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ USHORT nPaint;
+ if (bRows)
+ {
+ nStartCol = 0;
+ nStartRow = static_cast<SCROW>(pRanges[0]);
+ nPaint = PAINT_GRID | PAINT_LEFT;
+ }
+ else
+ {
+ nStartCol = static_cast<SCCOL>(pRanges[0]);
+ nStartRow = 0;
+ nPaint = PAINT_GRID | PAINT_TOP;
+ }
+
+ if ( bRefresh )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+ pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
+ pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, TRUE );
+ }
+
+ pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint );
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+ ShowTable( nTab );
+}
+
+void ScUndoDeleteMulti::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ nStartChangeAction = pChangeTrack->GetActionMax() + 1;
+ ScRange aRange( 0, 0, nTab, 0, 0, nTab );
+ if ( bRows )
+ aRange.aEnd.SetCol( MAXCOL );
+ else
+ aRange.aEnd.SetRow( MAXROW );
+ // rueckwaerts loeschen
+ SCCOLROW* pOneRange = &pRanges[2*nRangeCnt];
+ for ( SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++ )
+ {
+ SCCOLROW nEnd = *(--pOneRange);
+ SCCOLROW nStart = *(--pOneRange);
+ if ( bRows )
+ {
+ aRange.aStart.SetRow( nStart );
+ aRange.aEnd.SetRow( nEnd );
+ }
+ else
+ {
+ aRange.aStart.SetCol( static_cast<SCCOL>(nStart) );
+ aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) );
+ }
+ ULONG nDummyStart;
+ pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
+ nDummyStart, nEndChangeAction );
+ }
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void __EXPORT ScUndoDeleteMulti::Undo()
+{
+ WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCCOLROW* pOneRange;
+ SCCOLROW nRangeNo;
+
+ // rueckwaerts geloescht -> vorwaerts einfuegen
+ pOneRange = pRanges;
+ for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nStart = *(pOneRange++);
+ SCCOLROW nEnd = *(pOneRange++);
+ if (bRows)
+ pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
+ else
+ pDoc->InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
+ }
+
+ pOneRange = pRanges;
+ for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nStart = *(pOneRange++);
+ SCCOLROW nEnd = *(pOneRange++);
+ if (bRows)
+ pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,FALSE,pDoc );
+ else
+ pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
+ static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,FALSE,pDoc );
+ }
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ DoChange();
+
+ //! Markierung wieder einzeichnen
+ //! geht im Moment nicht, da keine Daten fuer Markierung vorhanden!
+
+ EndUndo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoDeleteMulti::Redo()
+{
+ WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ // rueckwaerts loeschen
+ SCCOLROW* pOneRange = &pRanges[2*nRangeCnt];
+ for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nEnd = *(--pOneRange);
+ SCCOLROW nStart = *(--pOneRange);
+ if (bRows)
+ pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
+ else
+ pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
+ }
+
+ SetChangeTrack();
+
+ DoChange();
+
+//! Markierung loeschen, derzeit unnoetig (s.o.)
+//! ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+//! if (pViewShell)
+//! DoneBlockMode();
+
+ EndRedo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget)
+{
+ // DeleteCells, falls einfache Selektion
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, TRUE );
+}
+
+BOOL __EXPORT ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Ausschneiden (Cut)
+//
+
+ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell,
+ ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc ) :
+ ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ),
+ aMarkData( rMark ),
+ pUndoDoc( pNewUndoDoc ),
+ aExtendedRange( aRange )
+{
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoCut::~ScUndoCut()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoCut::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_CUT ); // "Ausschneiden"
+}
+
+void ScUndoCut::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
+ nStartChangeAction, nEndChangeAction, SC_CACM_CUT );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void ScUndoCut::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ USHORT nExtFlags = 0;
+
+ // do not undo/redo objects and note captions, they are handled via drawing undo
+ USHORT nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
+
+ if (bUndo) // nur bei Undo
+ {
+ // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScRange aCopyRange = aExtendedRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, FALSE, pDoc );
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+ }
+ else // nur bei Redo
+ {
+ pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange );
+ pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
+ aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags );
+ SetChangeTrack();
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
+/*A*/ pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
+
+ if ( !bUndo ) // draw redo after updating row heights
+ RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
+
+ pDocShell->PostDataChanged();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+}
+
+void __EXPORT ScUndoCut::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+void __EXPORT ScUndoCut::Redo()
+{
+ BeginRedo();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ EnableDrawAdjust( pDoc, FALSE ); //! include in ScBlockUndo?
+ DoChange( FALSE );
+ EnableDrawAdjust( pDoc, TRUE ); //! include in ScBlockUndo?
+ EndRedo();
+}
+
+void __EXPORT ScUndoCut::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->CutToClip( NULL, TRUE );
+}
+
+BOOL __EXPORT ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Einfuegen (Paste)
+//
+
+ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
+ USHORT nNewFlags,
+ ScRefUndoData* pRefData,
+ void* /* pFill1 */, void* /* pFill2 */, void* /* pFill3 */,
+ BOOL bRedoIsFilled, const ScUndoPasteOptions* pOptions ) :
+ ScBlockUndo( pNewDocShell, ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ), SC_UNDO_SIMPLE ),
+ aMarkData( rMark ),
+ pUndoDoc( pNewUndoDoc ),
+ pRedoDoc( pNewRedoDoc ),
+ nFlags( nNewFlags ),
+ pRefUndoData( pRefData ),
+ pRefRedoData( NULL ),
+ bRedoFilled( bRedoIsFilled )
+{
+ // pFill1,pFill2,pFill3 are there so the ctor calls for simple paste (without cutting)
+ // don't have to be changed and branched for 641.
+ // They can be removed later.
+
+ if ( !aMarkData.IsMarked() ) // no cell marked:
+ aMarkData.SetMarkArea( aBlockRange ); // mark paste block
+
+ if ( pRefUndoData )
+ pRefUndoData->DeleteUnchanged( pDocShell->GetDocument() );
+
+ if ( pOptions )
+ aPasteOptions = *pOptions; // used only for Repeat
+
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoPaste::~ScUndoPaste()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+ delete pRefUndoData;
+ delete pRefRedoData;
+}
+
+String __EXPORT ScUndoPaste::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "Einfuegen"
+}
+
+void ScUndoPaste::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
+ pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
+ nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void ScUndoPaste::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ // RefUndoData for redo is created before first undo
+ // (with DeleteUnchanged after the DoUndo call)
+ BOOL bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
+ if ( bCreateRedoData )
+ pRefRedoData = new ScRefUndoData( pDoc );
+
+ ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
+
+ // fuer Undo immer alle oder keine Inhalte sichern
+ USHORT nUndoFlags = IDF_NONE;
+ if (nFlags & IDF_CONTENTS)
+ nUndoFlags |= IDF_CONTENTS;
+ if (nFlags & IDF_ATTRIB)
+ nUndoFlags |= IDF_ATTRIB;
+
+ // do not undo/redo objects and note captions, they are handled via drawing undo
+ (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS;
+
+ BOOL bPaintAll = FALSE;
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // marking is in ScBlockUndo...
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockRange );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( bUndo && !bRedoFilled )
+ {
+ if (!pRedoDoc)
+ {
+ BOOL bColInfo = ( aBlockRange.aStart.Row()==0 && aBlockRange.aEnd.Row()==MAXROW );
+ BOOL bRowInfo = ( aBlockRange.aStart.Col()==0 && aBlockRange.aEnd.Col()==MAXCOL );
+
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndoSelected( pDoc, aMarkData, bColInfo, bRowInfo );
+ }
+ // read "redo" data from the document in the first undo
+ // all sheets - CopyToDocument skips those that don't exist in pRedoDoc
+ ScRange aCopyRange = aBlockRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, nUndoFlags, FALSE, pRedoDoc );
+ bRedoFilled = TRUE;
+ }
+
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aBlockRange );
+
+ aMarkData.MarkToMulti();
+ pDoc->DeleteSelection( nUndoFlags, aMarkData );
+ aMarkData.MarkToSimple();
+
+ SCTAB nFirstSelected = aMarkData.GetFirstSelected();
+ ScRange aTabSelectRange = aBlockRange;
+ SCTAB nTab;
+
+ if ( !bUndo && pRedoDoc ) // Redo: UndoToDocument before handling RefData
+ {
+ aTabSelectRange.aStart.SetTab( nFirstSelected );
+ aTabSelectRange.aEnd.SetTab( nFirstSelected );
+ pRedoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (nTab != nFirstSelected && aMarkData.GetTableSelect(nTab))
+ {
+ aTabSelectRange.aStart.SetTab( nTab );
+ aTabSelectRange.aEnd.SetTab( nTab );
+ pRedoDoc->CopyToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
+ }
+ }
+
+ if (pWorkRefData)
+ {
+ pWorkRefData->DoUndo( pDoc, TRUE ); // TRUE = bSetChartRangeLists for SetChartListenerCollection
+ if ( pDoc->RefreshAutoFilter( 0,0, MAXCOL,MAXROW, aBlockRange.aStart.Tab() ) )
+ bPaintAll = TRUE;
+ }
+
+ if ( bCreateRedoData && pRefRedoData )
+ pRefRedoData->DeleteUnchanged( pDoc );
+
+ if (bUndo) // Undo: UndoToDocument after handling RefData
+ {
+ aTabSelectRange.aStart.SetTab( nFirstSelected );
+ aTabSelectRange.aEnd.SetTab( nFirstSelected );
+ pUndoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (nTab != nFirstSelected && aMarkData.GetTableSelect(nTab))
+ {
+ aTabSelectRange.aStart.SetTab( nTab );
+ aTabSelectRange.aEnd.SetTab( nTab );
+ pUndoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
+ }
+ }
+
+ if ( bUndo )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+ }
+ else
+ SetChangeTrack();
+
+ ScRange aDrawRange( aBlockRange );
+ pDoc->ExtendMerge( aDrawRange, TRUE ); // only needed for single sheet (text/rtf etc.)
+ USHORT nPaint = PAINT_GRID;
+ if (bPaintAll)
+ {
+ aDrawRange.aStart.SetCol(0);
+ aDrawRange.aStart.SetRow(0);
+ aDrawRange.aEnd.SetCol(MAXCOL);
+ aDrawRange.aEnd.SetRow(MAXROW);
+ nPaint |= PAINT_TOP | PAINT_LEFT;
+/*A*/ if (pViewShell)
+ pViewShell->AdjustBlockHeight(FALSE);
+ }
+ else
+ {
+ if ( aBlockRange.aStart.Row() == 0 && aBlockRange.aEnd.Row() == MAXROW ) // ganze Spalte
+ {
+ nPaint |= PAINT_TOP;
+ aDrawRange.aEnd.SetCol(MAXCOL);
+ }
+ if ( aBlockRange.aStart.Col() == 0 && aBlockRange.aEnd.Col() == MAXCOL ) // ganze Zeile
+ {
+ nPaint |= PAINT_LEFT;
+ aDrawRange.aEnd.SetRow(MAXROW);
+ }
+/*A*/ if ((pViewShell) && pViewShell->AdjustBlockHeight(FALSE))
+ {
+ aDrawRange.aStart.SetCol(0);
+ aDrawRange.aStart.SetRow(0);
+ aDrawRange.aEnd.SetCol(MAXCOL);
+ aDrawRange.aEnd.SetRow(MAXROW);
+ nPaint |= PAINT_LEFT;
+ }
+ pDocShell->UpdatePaintExt( nExtFlags, aDrawRange );
+ }
+
+ if ( !bUndo ) // draw redo after updating row heights
+ RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
+
+ pDocShell->PostPaint( aDrawRange, nPaint, nExtFlags );
+
+ pDocShell->PostDataChanged();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+}
+
+void __EXPORT ScUndoPaste::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ ShowTable( aBlockRange );
+ EndUndo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoPaste::Redo()
+{
+ BeginRedo();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ EnableDrawAdjust( pDoc, FALSE ); //! include in ScBlockUndo?
+ DoChange( FALSE );
+ EnableDrawAdjust( pDoc, TRUE ); //! include in ScBlockUndo?
+ EndRedo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell* pViewSh = ((ScTabViewTarget&)rTarget).GetViewShell();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
+ if (pOwnClip)
+ {
+ // #129384# keep a reference in case the clipboard is changed during PasteFromClip
+ com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
+ aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
+ aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE,
+ TRUE ); // allow warning dialog
+ }
+ }
+}
+
+BOOL __EXPORT ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Verschieben/Kopieren (Drag & Drop)
+//
+
+ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
+ const ScRange& rRange, ScAddress aNewDestPos, BOOL bNewCut,
+ ScDocument* pUndoDocument, ScRefUndoData* pRefData, BOOL bScenario ) :
+ ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ),
+ aSrcRange( rRange ),
+ bCut( bNewCut ),
+ bKeepScenarioFlags( bScenario )
+{
+ ScAddress aDestEnd(aNewDestPos);
+ aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row());
+ aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col());
+ aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab());
+
+ BOOL bIncludeFiltered = bCut;
+ if ( !bIncludeFiltered )
+ {
+ // find number of non-filtered rows
+ SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows(
+ aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
+
+ if ( nPastedCount == 0 )
+ nPastedCount = 1;
+ aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
+ }
+
+ aDestRange.aStart = aNewDestPos;
+ aDestRange.aEnd = aDestEnd;
+
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoDragDrop::~ScUndoDragDrop()
+{
+}
+
+String __EXPORT ScUndoDragDrop::GetComment() const
+{ // "Verschieben" : "Kopieren"
+ return bCut ?
+ ScGlobal::GetRscString( STR_UNDO_MOVE ) :
+ ScGlobal::GetRscString( STR_UNDO_COPY );
+}
+
+void ScUndoDragDrop::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ if ( bCut )
+ {
+ nStartChangeAction = pChangeTrack->GetActionMax() + 1;
+ pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc );
+ nEndChangeAction = pChangeTrack->GetActionMax();
+ }
+ else
+ pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void ScUndoDragDrop::PaintArea( ScRange aRange, USHORT nExtFlags ) const
+{
+ USHORT nPaint = PAINT_GRID;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ if (pViewShell)
+ {
+ VirtualDevice aVirtDev;
+ ScViewData* pViewData = pViewShell->GetViewData();
+
+ if ( pDoc->SetOptimalHeight( aRange.aStart.Row(), aRange.aEnd.Row(),
+ aRange.aStart.Tab(), 0, &aVirtDev,
+ pViewData->GetPPTX(), pViewData->GetPPTY(),
+ pViewData->GetZoomX(), pViewData->GetZoomY(),
+ FALSE ) )
+ {
+ aRange.aStart.SetCol(0);
+ aRange.aEnd.SetCol(MAXCOL);
+ aRange.aEnd.SetRow(MAXROW);
+ nPaint |= PAINT_LEFT;
+ }
+ }
+
+ if ( bKeepScenarioFlags )
+ {
+ // Szenarien mitkopiert -> auch Szenario-Rahmen painten
+ aRange.aStart.SetCol(0);
+ aRange.aStart.SetRow(0);
+ aRange.aEnd.SetCol(MAXCOL);
+ aRange.aEnd.SetRow(MAXROW);
+ }
+
+ // column/row info (width/height) included if whole columns/rows were copied
+ if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL )
+ {
+ nPaint |= PAINT_LEFT;
+ aRange.aEnd.SetRow(MAXROW);
+ }
+ if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW )
+ {
+ nPaint |= PAINT_TOP;
+ aRange.aEnd.SetCol(MAXCOL);
+ }
+
+ pDocShell->PostPaint( aRange, nPaint, nExtFlags );
+}
+
+
+void ScUndoDragDrop::DoUndo( ScRange aRange ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+//? DB-Areas vor Daten, damit bei ExtendMerge die Autofilter-Knoepfe stimmen
+
+ ScRange aPaintRange = aRange;
+ pDoc->ExtendMerge( aPaintRange ); // before deleting
+
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aPaintRange );
+
+ // do not undo objects and note captions, they are handled via drawing undo
+ USHORT nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
+
+ pDoc->DeleteAreaTab( aRange, nUndoFlags );
+ pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, FALSE, pDoc );
+ if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
+ pDoc->ExtendMerge( aRange, TRUE );
+
+ aPaintRange.aEnd.SetCol( Max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) );
+ aPaintRange.aEnd.SetRow( Max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) );
+
+ pDocShell->UpdatePaintExt( nExtFlags, aPaintRange );
+ PaintArea( aPaintRange, nExtFlags );
+}
+
+void __EXPORT ScUndoDragDrop::Undo()
+{
+ BeginUndo();
+ DoUndo(aDestRange);
+ if (bCut)
+ DoUndo(aSrcRange);
+ EndUndo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoDragDrop::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+
+ EnableDrawAdjust( pDoc, FALSE ); //! include in ScBlockUndo?
+
+ // do not undo/redo objects and note captions, they are handled via drawing undo
+ USHORT nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
+
+ /* TODO: Redoing note captions is quite tricky due to the fact that a
+ helper clip document is used. While (re-)pasting the contents to the
+ destination area, the original pointers to the captions created while
+ dropping have to be restored. A simple CopyFromClip() would create new
+ caption objects that are not tracked by drawing undo, and the captions
+ restored by drawing redo would live without cell note objects pointing
+ to them. So, first, CopyToClip() and CopyFromClip() are called without
+ cloning the caption objects. This leads to cell notes pointing to the
+ wrong captions from source area that will be removed by drawing redo
+ later. Second, the pointers to the new captions have to be restored.
+ Sadly, currently these pointers are not stored anywhere but in the list
+ of drawing undo actions. */
+
+ SCTAB nTab;
+ ScMarkData aSourceMark;
+ for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
+ aSourceMark.SelectTable( nTab, TRUE );
+
+ // do not clone objects and note captions into clipdoc (see above)
+ ScClipParam aClipParam(aSrcRange, bCut);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, false);
+
+ if (bCut)
+ {
+ ScRange aSrcPaintRange = aSrcRange;
+ pDoc->ExtendMerge( aSrcPaintRange ); // before deleting
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange );
+ pDoc->DeleteAreaTab( aSrcRange, nRedoFlags );
+ PaintArea( aSrcPaintRange, nExtFlags );
+ }
+
+ ScMarkData aDestMark;
+ for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
+ aDestMark.SelectTable( nTab, TRUE );
+
+ BOOL bIncludeFiltered = bCut;
+ // TODO: restore old note captions instead of cloning new captions...
+ pDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc, TRUE, FALSE, bIncludeFiltered );
+
+ if (bCut)
+ for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
+ pDoc->RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(),
+ aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), nTab );
+
+ // skipped rows and merged cells don't mix
+ if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
+ pDocShell->GetDocFunc().UnmergeCells( aDestRange, FALSE, TRUE );
+
+ for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
+ {
+ SCCOL nEndCol = aDestRange.aEnd.Col();
+ SCROW nEndRow = aDestRange.aEnd.Row();
+ pDoc->ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(),
+ nEndCol, nEndRow, nTab, TRUE );
+ PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab,
+ nEndCol, nEndRow, nTab ), 0 );
+ }
+
+ SetChangeTrack();
+
+ delete pClipDoc;
+ ShowTable( aDestRange.aStart.Tab() );
+
+ RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
+ EnableDrawAdjust( pDoc, TRUE ); //! include in ScBlockUndo?
+
+ EndRedo();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // geht nicht
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Liste der Bereichsnamen einfuegen
+// (Einfuegen|Name|Einfuegen =>[Liste])
+//
+
+ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) :
+ ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
+ pUndoDoc( pNewUndoDoc ),
+ pRedoDoc( pNewRedoDoc )
+{
+}
+
+__EXPORT ScUndoListNames::~ScUndoListNames()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+}
+
+String __EXPORT ScUndoListNames::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_LISTNAMES );
+}
+
+void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ pDoc->DeleteAreaTab( aBlockRange, IDF_ALL );
+ pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, FALSE, pDoc );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID );
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+}
+
+void __EXPORT ScUndoListNames::Undo()
+{
+ BeginUndo();
+ DoChange(pUndoDoc);
+ EndUndo();
+}
+
+void __EXPORT ScUndoListNames::Redo()
+{
+ BeginRedo();
+ DoChange(pRedoDoc);
+ EndRedo();
+}
+
+void __EXPORT ScUndoListNames::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->InsertNameList();
+}
+
+BOOL __EXPORT ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Szenario anwenden
+// (Extras|Szenarien)
+//
+
+ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+/*C*/ const ScArea& rDestArea,
+ ScDocument* pNewUndoDoc,
+ const String& rNewName ) :
+ ScSimpleUndo( pNewDocShell ),
+ pUndoDoc( pNewUndoDoc ),
+ aMarkData( rMark ),
+ aName( rNewName )
+{
+ aRange.aStart.SetCol(rDestArea.nColStart);
+ aRange.aStart.SetRow(rDestArea.nRowStart);
+ aRange.aStart.SetTab(rDestArea.nTab);
+ aRange.aEnd.SetCol(rDestArea.nColEnd);
+ aRange.aEnd.SetRow(rDestArea.nRowEnd);
+ aRange.aEnd.SetTab(rDestArea.nTab);
+}
+
+__EXPORT ScUndoUseScenario::~ScUndoUseScenario()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoUseScenario::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_USESCENARIO );
+}
+
+void __EXPORT ScUndoUseScenario::Undo()
+{
+ BeginUndo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->DoneBlockMode();
+ pViewShell->InitOwnBlockMode();
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->DeleteSelection( IDF_ALL, aMarkData );
+ pUndoDoc->CopyToDocument( aRange, IDF_ALL, TRUE, pDoc, &aMarkData );
+
+ // Szenario-Tabellen
+ BOOL bFrame = FALSE;
+ SCTAB nTab = aRange.aStart.Tab();
+ SCTAB nEndTab = nTab;
+ while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) )
+ ++nEndTab;
+ for (SCTAB i = nTab+1; i<=nEndTab; i++)
+ {
+ // Flags immer
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags );
+ pDoc->SetScenarioData( i, aComment, aColor, nScenFlags );
+ BOOL bActive = pUndoDoc->IsActiveScenario( i );
+ pDoc->SetActiveScenario( i, bActive );
+ // Bei Zurueckkopier-Szenarios auch Inhalte
+ if ( nScenFlags & SC_SCENARIO_TWOWAY )
+ {
+ pDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL );
+ pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,FALSE, pDoc );
+ }
+ if ( nScenFlags & SC_SCENARIO_SHOWFRAME )
+ bFrame = TRUE;
+ }
+
+ // Wenn sichtbare Rahmen, dann alles painten
+ if (bFrame)
+ pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS );
+ else
+ pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS );
+ pDocShell->PostDataChanged();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+ ShowTable( aRange.aStart.Tab() );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoUseScenario::Redo()
+{
+ SCTAB nTab = aRange.aStart.Tab();
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->SetTabNo( nTab );
+ pViewShell->DoneBlockMode();
+ pViewShell->InitOwnBlockMode();
+ }
+
+ pDocShell->UseScenario( nTab, aName, FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ String aTemp = aName;
+ ((ScTabViewTarget&)rTarget).GetViewShell()->UseScenario(aTemp);
+ }
+}
+
+BOOL __EXPORT ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData();
+ return !pViewData->GetDocument()->IsScenario( pViewData->GetTabNo() );
+ }
+ return FALSE;
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Vorlage anwenden
+// (Format|Vorlagenkatalog)
+//
+
+ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ const ScRange& rRange,
+ const String& rName,
+ ScDocument* pNewUndoDoc ) :
+ ScSimpleUndo( pNewDocShell ),
+ aMarkData( rMark ),
+ pUndoDoc( pNewUndoDoc ),
+ aStyleName( rName ),
+ aRange( rRange )
+{
+ aMarkData.MarkToMulti();
+}
+
+__EXPORT ScUndoSelectionStyle::~ScUndoSelectionStyle()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoSelectionStyle::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE );
+}
+
+void ScUndoSelectionStyle::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ ScRange aWorkRange( aRange );
+ if ( pDoc->HasAttrib( aWorkRange, HASATTR_MERGED ) ) // zusammengefasste Zellen?
+ pDoc->ExtendMerge( aWorkRange, TRUE );
+
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
+
+ if (bUndo) // bei Undo alte Daten wieder reinschubsen
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScRange aCopyRange = aWorkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
+ }
+ else // bei Redo Style wieder zuweisen
+ {
+ ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
+ ScStyleSheet* pStyleSheet =
+ (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
+ if (!pStyleSheet)
+ {
+ DBG_ERROR("StyleSheet not found");
+ return;
+ }
+ pDoc->ApplySelectionStyle( *pStyleSheet, aMarkData );
+ }
+
+ pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
+
+ if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
+/*A*/ pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
+
+ ShowTable( aWorkRange.aStart.Tab() );
+}
+
+void __EXPORT ScUndoSelectionStyle::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+void __EXPORT ScUndoSelectionStyle::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+}
+
+void __EXPORT ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
+ ScStyleSheet* pStyleSheet = (ScStyleSheet*) pStlPool->
+ Find( aStyleName, SFX_STYLE_FAMILY_PARA );
+ if (!pStyleSheet)
+ {
+ DBG_ERROR("StyleSheet not found");
+ return;
+ }
+
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+ rViewShell.SetStyleSheetToMarked( pStyleSheet, TRUE );
+ }
+}
+
+BOOL __EXPORT ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+USHORT __EXPORT ScUndoSelectionStyle::GetId() const
+{
+ return STR_UNDO_APPLYCELLSTYLE;
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Matrix-Formel eingeben
+//
+
+ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea,
+ ScDocument* pNewUndoDoc, const String& rForm ) :
+ ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
+ pUndoDoc( pNewUndoDoc ),
+ aFormula( rForm )
+{
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoEnterMatrix::~ScUndoEnterMatrix()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoEnterMatrix::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX );
+}
+
+void ScUndoEnterMatrix::SetChangeTrack()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void __EXPORT ScUndoEnterMatrix::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ pDoc->DeleteAreaTab( aBlockRange, IDF_ALL & ~IDF_NOTE );
+ pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID );
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoEnterMatrix::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( aBlockRange.aStart.Tab() );
+ aDestMark.SetMarkArea( aBlockRange );
+
+ pDoc->InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
+ aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
+ aDestMark, aFormula );
+// pDocShell->PostPaint( aBlockRange, PAINT_GRID ); // nicht noetig ???
+
+ SetChangeTrack();
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ String aTemp = aFormula;
+ ((ScTabViewTarget&)rTarget).GetViewShell()->EnterMatrix(aTemp);
+ }
+}
+
+BOOL __EXPORT ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// Einzug vermindern / erhoehen
+//
+
+ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark )
+{
+ DBG_ASSERT( rMark.IsMultiMarked(), "wrong mark type" );
+
+ ScRange aRange;
+ rMark.GetMultiMarkArea( aRange );
+ return aRange;
+}
+
+ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, BOOL bIncrement ) :
+ ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
+ aMarkData( rMark ),
+ pUndoDoc( pNewUndoDoc ),
+ bIsIncrement( bIncrement )
+{
+}
+
+__EXPORT ScUndoIndent::~ScUndoIndent()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoIndent::GetComment() const
+{
+ USHORT nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT;
+ return ScGlobal::GetRscString( nId );
+}
+
+void __EXPORT ScUndoIndent::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScRange aCopyRange = aBlockRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoIndent::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->ChangeSelectionIndent( bIsIncrement, aMarkData );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoIndent::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->ChangeIndent( bIsIncrement );
+}
+
+BOOL __EXPORT ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// Transliteration for cells
+//
+
+ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, sal_Int32 nType ) :
+ ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
+ aMarkData( rMark ),
+ pUndoDoc( pNewUndoDoc ),
+ nTransliterationType( nType )
+{
+}
+
+__EXPORT ScUndoTransliterate::~ScUndoTransliterate()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoTransliterate::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE );
+}
+
+void __EXPORT ScUndoTransliterate::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScRange aCopyRange = aBlockRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, TRUE, pDoc, &aMarkData );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoTransliterate::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->TransliterateText( aMarkData, nTransliterationType );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->TransliterateText( nTransliterationType );
+}
+
+BOOL __EXPORT ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// einzelne Items per Which-IDs aus Bereich loeschen
+//
+
+ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, const USHORT* pW ) :
+ ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
+ aMarkData( rMark ),
+ pUndoDoc( pNewUndoDoc ),
+ pWhich( NULL )
+{
+ DBG_ASSERT( pW, "ScUndoClearItems: Which-Pointer ist 0" );
+
+ USHORT nCount = 0;
+ while ( pW[nCount] )
+ ++nCount;
+ pWhich = new USHORT[nCount+1];
+ for (USHORT i=0; i<=nCount; i++)
+ pWhich[i] = pW[i];
+}
+
+__EXPORT ScUndoClearItems::~ScUndoClearItems()
+{
+ delete pUndoDoc;
+ delete pWhich;
+}
+
+String __EXPORT ScUndoClearItems::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
+}
+
+void __EXPORT ScUndoClearItems::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoClearItems::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->ClearSelectionItems( pWhich, aMarkData );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData();
+ ScDocFunc aFunc(*pViewData->GetDocShell());
+ aFunc.ClearItems( pViewData->GetMarkData(), pWhich, FALSE );
+ }
+}
+
+BOOL __EXPORT ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// Alle Umbrueche einer Tabelle loeschen
+//
+
+ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
+ SCTAB nNewTab, ScDocument* pNewUndoDoc ) :
+ ScSimpleUndo( pNewDocShell ),
+ nTab( nNewTab ),
+ pUndoDoc( pNewUndoDoc )
+{
+}
+
+__EXPORT ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoRemoveBreaks::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS );
+}
+
+void __EXPORT ScUndoRemoveBreaks::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pDoc );
+ if (pViewShell)
+ pViewShell->UpdatePageBreakData( TRUE );
+ pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoRemoveBreaks::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ pDoc->RemoveManualBreaks(nTab);
+ pDoc->UpdatePageBreaks(nTab);
+ if (pViewShell)
+ pViewShell->UpdatePageBreakData( TRUE );
+ pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+ rViewShell.RemoveManualBreaks();
+ }
+}
+
+BOOL __EXPORT ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// Zusammenfassung aufheben (fuer einen ganzen Bereich)
+//
+
+ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
+ const ScRange& rArea, ScDocument* pNewUndoDoc ) :
+ ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
+ pUndoDoc( pNewUndoDoc )
+{
+}
+
+__EXPORT ScUndoRemoveMerge::~ScUndoRemoveMerge()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoRemoveMerge::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_REMERGE ); // "Zusammenfassung aufheben"
+}
+
+void __EXPORT ScUndoRemoveMerge::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScRange aExtended = aBlockRange;
+ pUndoDoc->ExtendMerge( aExtended );
+
+ pDoc->DeleteAreaTab( aExtended, IDF_ATTRIB );
+ pUndoDoc->CopyToDocument( aExtended, IDF_ATTRIB, FALSE, pDoc );
+
+ BOOL bDidPaint = FALSE;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if ( pViewShell )
+ {
+ pViewShell->SetTabNo( aExtended.aStart.Tab() );
+ bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() );
+ }
+ if (!bDidPaint)
+ ScUndoUtil::PaintMore( pDocShell, aExtended );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoRemoveMerge::Redo()
+{
+ BeginRedo();
+
+ SCTAB nTab = aBlockRange.aStart.Tab();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRange aExtended = aBlockRange;
+ pDoc->ExtendMerge( aExtended );
+ ScRange aRefresh = aExtended;
+ pDoc->ExtendOverlapped( aRefresh );
+
+ // ausfuehren
+
+ const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( rDefAttr );
+ pDoc->ApplyPatternAreaTab( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
+ aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), nTab,
+ aPattern );
+
+ pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
+ aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
+ SC_MF_HOR | SC_MF_VER );
+
+ pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
+
+ // Paint
+
+ BOOL bDidPaint = FALSE;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if ( pViewShell )
+ {
+ pViewShell->SetTabNo( aExtended.aStart.Tab() );
+ bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() );
+ }
+ if (!bDidPaint)
+ ScUndoUtil::PaintMore( pDocShell, aExtended );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->RemoveMerge();
+}
+
+BOOL __EXPORT ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// nur Umrandung setzen, per ScRangeList (StarOne)
+//
+
+ScRange lcl_TotalRange( const ScRangeList& rRanges )
+{
+ ScRange aTotal;
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *rRanges.GetObject(i);
+ if (i==0)
+ aTotal = aRange;
+ else
+ {
+ if (aRange.aStart.Col() < aTotal.aStart.Col())
+ aTotal.aStart.SetCol(aRange.aStart.Col());
+ if (aRange.aStart.Row() < aTotal.aStart.Row())
+ aTotal.aStart.SetRow(aRange.aStart.Row());
+ if (aRange.aStart.Tab() < aTotal.aStart.Tab())
+ aTotal.aStart.SetTab(aRange.aStart.Tab());
+ if (aRange.aEnd.Col() > aTotal.aEnd.Col())
+ aTotal.aEnd.SetCol(aRange.aEnd.Col());
+ if (aRange.aEnd.Row() > aTotal.aEnd.Row())
+ aTotal.aEnd.SetRow(aRange.aEnd.Row());
+ if (aRange.aEnd.Tab() > aTotal.aEnd.Tab())
+ aTotal.aEnd.SetTab(aRange.aEnd.Tab());
+ }
+ }
+ return aTotal;
+}
+
+ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell,
+ const ScRangeList& rRangeList, ScDocument* pNewUndoDoc,
+ const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) :
+ ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ),
+ pUndoDoc( pNewUndoDoc )
+{
+ pRanges = new ScRangeList(rRangeList);
+ pOuter = new SvxBoxItem(rNewOuter);
+ pInner = new SvxBoxInfoItem(rNewInner);
+}
+
+__EXPORT ScUndoBorder::~ScUndoBorder()
+{
+ delete pUndoDoc;
+ delete pRanges;
+ delete pOuter;
+ delete pInner;
+}
+
+String __EXPORT ScUndoBorder::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES ); //! eigener String?
+}
+
+void __EXPORT ScUndoBorder::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( *pRanges, FALSE );
+ pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoBorder::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument(); //! Funktion an docfunc aufrufen
+ ULONG nCount = pRanges->Count();
+ ULONG i;
+ for (i=0; i<nCount; i++)
+ {
+ ScRange aRange = *pRanges->GetObject(i);
+ SCTAB nTab = aRange.aStart.Tab();
+
+ ScMarkData aMark;
+ aMark.SetMarkArea( aRange );
+ aMark.SelectTable( nTab, TRUE );
+
+ pDoc->ApplySelectionFrame( aMark, pOuter, pInner );
+ }
+ for (i=0; i<nCount; i++)
+ pDocShell->PostPaint( *pRanges->GetObject(i), PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ //! spaeter (wenn die Funktion aus cellsuno nach docfunc gewandert ist)
+}
+
+BOOL __EXPORT ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // s.o.
+}
+
+
+
+
diff --git a/sc/source/ui/undo/undoblk2.cxx b/sc/source/ui/undo/undoblk2.cxx
new file mode 100644
index 000000000000..2ab03eb71923
--- /dev/null
+++ b/sc/source/ui/undo/undoblk2.cxx
@@ -0,0 +1,215 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+#ifndef PCH
+#include "scitems.hxx" // SearchItem
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "undoblk.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "olinetab.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "target.hxx"
+
+#include "undoolk.hxx" //! GetUndo ins Document verschieben!
+
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScUndoWidthOrHeight, SfxUndoAction);
+
+// -----------------------------------------------------------------------
+
+
+
+//
+// Spaltenbreiten oder Zeilenhoehen aendern
+//
+
+ScUndoWidthOrHeight::ScUndoWidthOrHeight( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOLROW nNewStart, SCTAB nNewStartTab, SCCOLROW nNewEnd, SCTAB nNewEndTab,
+ ScDocument* pNewUndoDoc, SCCOLROW nNewCnt, SCCOLROW* pNewRanges,
+ ScOutlineTable* pNewUndoTab,
+ ScSizeMode eNewMode, USHORT nNewSizeTwips, BOOL bNewWidth ) :
+ ScSimpleUndo( pNewDocShell ),
+ aMarkData( rMark ),
+ nStart( nNewStart ),
+ nEnd( nNewEnd ),
+ nStartTab( nNewStartTab ),
+ nEndTab( nNewEndTab ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTab( pNewUndoTab ),
+ nRangeCnt( nNewCnt ),
+ pRanges( pNewRanges ),
+ nNewSize( nNewSizeTwips ),
+ bWidth( bNewWidth ),
+ eMode( eNewMode ),
+ pDrawUndo( NULL )
+{
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+}
+
+__EXPORT ScUndoWidthOrHeight::~ScUndoWidthOrHeight()
+{
+ delete[] pRanges;
+ delete pUndoDoc;
+ delete pUndoTab;
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String __EXPORT ScUndoWidthOrHeight::GetComment() const
+{
+ // [ "optimale " ] "Spaltenbreite" | "Zeilenhoehe"
+ return ( bWidth ?
+ ( ( eMode == SC_SIZE_OPTIMAL )?
+ ScGlobal::GetRscString( STR_UNDO_OPTCOLWIDTH ) :
+ ScGlobal::GetRscString( STR_UNDO_COLWIDTH )
+ ) :
+ ( ( eMode == SC_SIZE_OPTIMAL )?
+ ScGlobal::GetRscString( STR_UNDO_OPTROWHEIGHT ) :
+ ScGlobal::GetRscString( STR_UNDO_ROWHEIGHT )
+ ) );
+}
+
+void __EXPORT ScUndoWidthOrHeight::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCCOLROW nPaintStart = nStart > 0 ? nStart-1 : static_cast<SCCOLROW>(0);
+
+ if (eMode==SC_SIZE_OPTIMAL)
+ {
+ if (pViewShell)
+ {
+ pViewShell->SetMarkData( aMarkData );
+
+ nPaintStart = 0; // paint all, because of changed selection
+ }
+ }
+
+ //! outlines from all tables?
+ if (pUndoTab) // Outlines mit gespeichert?
+ pDoc->SetOutlineTable( nStartTab, pUndoTab );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTab;
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (aMarkData.GetTableSelect(nTab))
+ {
+ if (bWidth) // Width
+ {
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE,
+ FALSE, pDoc );
+ pDoc->UpdatePageBreaks( nTab );
+ pDocShell->PostPaint( static_cast<SCCOL>(nPaintStart), 0, nTab,
+ MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_TOP );
+ }
+ else // Height
+ {
+ pUndoDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pDoc );
+ pDoc->UpdatePageBreaks( nTab );
+ pDocShell->PostPaint( 0, nPaintStart, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_LEFT );
+ }
+ }
+
+ DoSdrUndoAction( pDrawUndo, pDoc );
+
+ if (pViewShell)
+ {
+ pViewShell->UpdateScrollBars();
+
+ SCTAB nCurrentTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nCurrentTab < nStartTab || nCurrentTab > nEndTab )
+ pViewShell->SetTabNo( nStartTab );
+ }
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoWidthOrHeight::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ BOOL bPaintAll = FALSE;
+ if (eMode==SC_SIZE_OPTIMAL)
+ {
+ if (pViewShell)
+ {
+ pViewShell->SetMarkData( aMarkData );
+
+ bPaintAll = TRUE; // paint all, because of changed selection
+ }
+ }
+
+ if (pViewShell)
+ {
+ SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nTab < nStartTab || nTab > nEndTab )
+ pViewShell->SetTabNo( nStartTab );
+ }
+
+ // SetWidthOrHeight aendert aktuelle Tabelle !
+ pViewShell->SetWidthOrHeight( bWidth, nRangeCnt, pRanges, eMode, nNewSize, FALSE, TRUE, &aMarkData );
+
+ // paint grid if selection was changed directly at the MarkData
+ if (bPaintAll)
+ pDocShell->PostPaint( 0, 0, nStartTab, MAXCOL, MAXROW, nEndTab, PAINT_GRID );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoWidthOrHeight::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->SetMarkedWidthOrHeight( bWidth, eMode, nNewSize, TRUE );
+}
+
+BOOL __EXPORT ScUndoWidthOrHeight::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
new file mode 100644
index 000000000000..506afeac138e
--- /dev/null
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -0,0 +1,2127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/virdev.hxx>
+#include <sfx2/app.hxx>
+
+#include "undoblk.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "rangenam.hxx"
+#include "arealink.hxx"
+#include "patattr.hxx"
+#include "target.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "table.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "undoolk.hxx"
+#include "undoutil.hxx"
+#include "chgtrack.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "paramisc.hxx"
+#include "postit.hxx"
+#include "docuno.hxx"
+
+// STATIC DATA ---------------------------------------------------------------
+
+TYPEINIT1(ScUndoDeleteContents, SfxUndoAction);
+TYPEINIT1(ScUndoFillTable, SfxUndoAction);
+TYPEINIT1(ScUndoSelectionAttr, SfxUndoAction);
+TYPEINIT1(ScUndoAutoFill, SfxUndoAction);
+TYPEINIT1(ScUndoMerge, SfxUndoAction);
+TYPEINIT1(ScUndoAutoFormat, SfxUndoAction);
+TYPEINIT1(ScUndoReplace, SfxUndoAction);
+TYPEINIT1(ScUndoTabOp, SfxUndoAction);
+TYPEINIT1(ScUndoConversion, SfxUndoAction);
+TYPEINIT1(ScUndoRefConversion, SfxUndoAction);
+TYPEINIT1(ScUndoRefreshLink, SfxUndoAction);
+TYPEINIT1(ScUndoInsertAreaLink, SfxUndoAction);
+TYPEINIT1(ScUndoRemoveAreaLink, SfxUndoAction);
+TYPEINIT1(ScUndoUpdateAreaLink, SfxUndoAction);
+
+
+// To Do:
+/*A*/ // SetOptimalHeight auf Dokument, wenn keine View
+
+
+//============================================================================
+// class ScUndoDeleteContents
+//
+// Inhalte loeschen
+
+//----------------------------------------------------------------------------
+
+ScUndoDeleteContents::ScUndoDeleteContents(
+ ScDocShell* pNewDocShell,
+ const ScMarkData& rMark, const ScRange& rRange,
+ ScDocument* pNewUndoDoc, BOOL bNewMulti,
+ USHORT nNewFlags, BOOL bObjects )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ aRange ( rRange ),
+ aMarkData ( rMark ),
+ pUndoDoc ( pNewUndoDoc ),
+ pDrawUndo ( NULL ),
+ nFlags ( nNewFlags ),
+ bMulti ( bNewMulti ) // ueberliquid
+{
+ if (bObjects)
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+
+ if ( !(aMarkData.IsMarked() || aMarkData.IsMultiMarked()) ) // keine Zelle markiert:
+ aMarkData.SetMarkArea( aRange ); // Zelle unter Cursor markieren
+
+ SetChangeTrack();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoDeleteContents::~ScUndoDeleteContents()
+{
+ delete pUndoDoc;
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoDeleteContents::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS ); // "Loeschen"
+}
+
+
+void ScUndoDeleteContents::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
+ pChangeTrack->AppendContentRange( aRange, pUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoDeleteContents::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ USHORT nExtFlags = 0;
+
+ if (bUndo) // nur Undo
+ {
+ USHORT nUndoFlags = IDF_NONE; // entweder alle oder keine Inhalte kopieren
+ if (nFlags & IDF_CONTENTS) // (es sind nur die richtigen ins UndoDoc kopiert worden)
+ nUndoFlags |= IDF_CONTENTS;
+ if (nFlags & IDF_ATTRIB)
+ nUndoFlags |= IDF_ATTRIB;
+ if (nFlags & IDF_EDITATTR) // Edit-Engine-Attribute
+ nUndoFlags |= IDF_STRING; // -> Zellen werden geaendert
+ // do not create clones of note captions, they will be restored via drawing undo
+ nUndoFlags |= IDF_NOCAPTIONS;
+
+ ScRange aCopyRange = aRange;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+
+ pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, bMulti, pDoc, &aMarkData );
+
+ DoSdrUndoAction( pDrawUndo, pDoc );
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ pDocShell->UpdatePaintExt( nExtFlags, aRange ); // content after the change
+ }
+ else // nur Redo
+ {
+ pDocShell->UpdatePaintExt( nExtFlags, aRange ); // content before the change
+
+ aMarkData.MarkToMulti();
+ RedoSdrUndoAction( pDrawUndo );
+ // do not delete objects and note captions, they have been removed via drawing undo
+ USHORT nRedoFlags = (nFlags & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
+ pDoc->DeleteSelection( nRedoFlags, aMarkData );
+ aMarkData.MarkToSimple();
+
+ SetChangeTrack();
+ }
+
+ if ( !( (pViewShell) && pViewShell->AdjustRowHeight(
+ aRange.aStart.Row(), aRange.aEnd.Row() ) ) )
+/*A*/ pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
+
+ pDocShell->PostDataChanged();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+ ShowTable( aRange );
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoDeleteContents::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoDeleteContents::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoDeleteContents::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteContents( nFlags, TRUE );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoDeleteContents::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoFillTable
+//
+// Tabellen ausfuellen
+// (Bearbeiten|Ausfuellen|...)
+
+//----------------------------------------------------------------------------
+
+ScUndoFillTable::ScUndoFillTable( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, BOOL bNewMulti, SCTAB nSrc,
+ USHORT nFlg, USHORT nFunc, BOOL bSkip, BOOL bLink )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
+ aMarkData ( rMark ),
+ pUndoDoc ( pNewUndoDoc ),
+ nFlags ( nFlg ),
+ nFunction ( nFunc ),
+ nSrcTab ( nSrc ),
+ bMulti ( bNewMulti ),
+ bSkipEmpty ( bSkip ),
+ bAsLink ( bLink )
+{
+ SetChangeTrack();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoFillTable::~ScUndoFillTable()
+{
+ delete pUndoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoFillTable::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_FILL_TAB );
+}
+
+
+void ScUndoFillTable::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ ScRange aWorkRange(aRange);
+ nStartChangeAction = 0;
+ ULONG nTmpAction;
+ for ( SCTAB i = 0; i < nTabCount; i++ )
+ {
+ if (i != nSrcTab && aMarkData.GetTableSelect(i))
+ {
+ aWorkRange.aStart.SetTab(i);
+ aWorkRange.aEnd.SetTab(i);
+ pChangeTrack->AppendContentRange( aWorkRange, pUndoDoc,
+ nTmpAction, nEndChangeAction );
+ if ( !nStartChangeAction )
+ nStartChangeAction = nTmpAction;
+ }
+ }
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoFillTable::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ if (bUndo) // nur Undo
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScRange aWorkRange(aRange);
+ for ( SCTAB i = 0; i < nTabCount; i++ )
+ if (i != nSrcTab && aMarkData.GetTableSelect(i))
+ {
+ aWorkRange.aStart.SetTab(i);
+ aWorkRange.aEnd.SetTab(i);
+ if (bMulti)
+ pDoc->DeleteSelectionTab( i, IDF_ALL, aMarkData );
+ else
+ pDoc->DeleteAreaTab( aWorkRange, IDF_ALL );
+ pUndoDoc->CopyToDocument( aWorkRange, IDF_ALL, bMulti, pDoc, &aMarkData );
+ }
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+ }
+ else // nur Redo
+ {
+ aMarkData.MarkToMulti();
+ pDoc->FillTabMarked( nSrcTab, aMarkData, nFlags, nFunction, bSkipEmpty, bAsLink );
+ aMarkData.MarkToSimple();
+ SetChangeTrack();
+ }
+
+ pDocShell->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_EXTRAS);
+ pDocShell->PostDataChanged();
+
+ // CellContentChanged kommt mit der Markierung
+
+ if (pViewShell)
+ {
+ SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
+ if ( !aMarkData.GetTableSelect(nTab) )
+ pViewShell->SetTabNo( nSrcTab );
+
+ pViewShell->DoneBlockMode(); // gibt sonst Probleme, weil Markierung auf falscher Tabelle
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoFillTable::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoFillTable::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoFillTable::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->FillTab( nFlags, nFunction, bSkipEmpty, bAsLink );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoFillTable::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoSelectionAttr
+//
+// Zellformat aendern
+
+//----------------------------------------------------------------------------
+
+ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell,
+ const ScMarkData& rMark,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, BOOL bNewMulti,
+ const ScPatternAttr* pNewApply,
+ const SvxBoxItem* pNewOuter, const SvxBoxInfoItem* pNewInner )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ aMarkData ( rMark ),
+ aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
+ pUndoDoc ( pNewUndoDoc ),
+ bMulti ( bNewMulti )
+{
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ pApplyPattern = (ScPatternAttr*) &pPool->Put( *pNewApply );
+ pLineOuter = pNewOuter ? (SvxBoxItem*) &pPool->Put( *pNewOuter ) : NULL;
+ pLineInner = pNewInner ? (SvxBoxInfoItem*) &pPool->Put( *pNewInner ) : NULL;
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoSelectionAttr::~ScUndoSelectionAttr()
+{
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ pPool->Remove(*pApplyPattern);
+ if (pLineOuter)
+ pPool->Remove(*pLineOuter);
+ if (pLineInner)
+ pPool->Remove(*pLineInner);
+
+ delete pUndoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoSelectionAttr::GetComment() const
+{
+ //"Attribute" "/Linien"
+ return ScGlobal::GetRscString( pLineOuter ? STR_UNDO_SELATTRLINES : STR_UNDO_SELATTR );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoSelectionAttr::DoChange( const BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ ScRange aEffRange( aRange );
+ if ( pDoc->HasAttrib( aEffRange, HASATTR_MERGED ) ) // zusammengefasste Zellen?
+ pDoc->ExtendMerge( aEffRange );
+
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aEffRange );
+
+ if (bUndo) // nur bei Undo
+ {
+ ScRange aCopyRange = aRange;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pDoc, &aMarkData );
+ }
+ else // nur bei Redo
+ {
+ aMarkData.MarkToMulti();
+ pDoc->ApplySelectionPattern( *pApplyPattern, aMarkData );
+ aMarkData.MarkToSimple();
+
+ if (pLineOuter)
+ pDoc->ApplySelectionFrame( aMarkData, pLineOuter, pLineInner );
+ }
+
+ if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
+/*A*/ pDocShell->PostPaint( aEffRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
+
+ ShowTable( aRange );
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoSelectionAttr::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoSelectionAttr::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoSelectionAttr::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+ if (pLineOuter)
+ rViewShell.ApplyPatternLines( *pApplyPattern, pLineOuter, pLineInner, TRUE );
+ else
+ rViewShell.ApplySelectionPattern( *pApplyPattern, TRUE );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoSelectionAttr::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoAutoFill
+//
+// Auto-Fill (nur einfache Bloecke)
+
+//----------------------------------------------------------------------------
+
+ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
+ const ScRange& rRange, const ScRange& rSourceArea,
+ ScDocument* pNewUndoDoc, const ScMarkData& rMark,
+ FillDir eNewFillDir, FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
+ double fNewStartValue, double fNewStepValue, double fNewMaxValue,
+ USHORT nMaxShIndex )
+ //
+ : ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
+ //
+ aSource ( rSourceArea ),
+ aMarkData ( rMark ),
+ pUndoDoc ( pNewUndoDoc ),
+ eFillDir ( eNewFillDir ),
+ eFillCmd ( eNewFillCmd ),
+ eFillDateCmd ( eNewFillDateCmd ),
+ fStartValue ( fNewStartValue ),
+ fStepValue ( fNewStepValue ),
+ fMaxValue ( fNewMaxValue ),
+ nMaxSharedIndex ( nMaxShIndex)
+{
+ SetChangeTrack();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoAutoFill::~ScUndoAutoFill()
+{
+ pDocShell->GetDocument()->EraseNonUsedSharedNames(nMaxSharedIndex);
+ delete pUndoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoAutoFill::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_AUTOFILL ); //"Ausfuellen"
+}
+
+
+void ScUndoAutoFill::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoAutoFill::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (aMarkData.GetTableSelect(nTab))
+ {
+ ScRange aWorkRange = aBlockRange;
+ aWorkRange.aStart.SetTab(nTab);
+ aWorkRange.aEnd.SetTab(nTab);
+
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
+ pDoc->DeleteAreaTab( aWorkRange, IDF_AUTOFILL );
+ pUndoDoc->CopyToDocument( aWorkRange, IDF_AUTOFILL, FALSE, pDoc );
+
+ pDoc->ExtendMerge( aWorkRange, TRUE );
+ pDocShell->PostPaint( aWorkRange, PAINT_GRID, nExtFlags );
+ }
+ }
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+// Shared-Names loeschen
+// Falls Undo ins Dokument gespeichert
+// => automatisches Loeschen am Ende
+// umarbeiten!!
+
+ String aName = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("___SC_"));
+ aName += String::CreateFromInt32(nMaxSharedIndex);
+ aName += '_';
+ ScRangeName* pRangeName = pDoc->GetRangeName();
+ BOOL bHasFound = FALSE;
+ for (USHORT i = 0; i < pRangeName->GetCount(); i++)
+ {
+ ScRangeData* pRangeData = (*pRangeName)[i];
+ if (pRangeData)
+ {
+ String aRName;
+ pRangeData->GetName(aRName);
+ if (aRName.Search(aName) != STRING_NOTFOUND)
+ {
+ pRangeName->AtFree(i);
+ bHasFound = TRUE;
+ }
+ }
+ }
+ if (bHasFound)
+ pRangeName->SetSharedMaxIndex(pRangeName->GetSharedMaxIndex()-1);
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoAutoFill::Redo()
+{
+ BeginRedo();
+
+//! Tabellen selektieren
+
+ SCCOLROW nCount = 0;
+ switch (eFillDir)
+ {
+ case FILL_TO_BOTTOM:
+ nCount = aBlockRange.aEnd.Row() - aSource.aEnd.Row();
+ break;
+ case FILL_TO_RIGHT:
+ nCount = aBlockRange.aEnd.Col() - aSource.aEnd.Col();
+ break;
+ case FILL_TO_TOP:
+ nCount = aSource.aStart.Row() - aBlockRange.aStart.Row();
+ break;
+ case FILL_TO_LEFT:
+ nCount = aSource.aStart.Col() - aBlockRange.aStart.Col();
+ break;
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( fStartValue != MAXDOUBLE )
+ {
+ SCCOL nValX = (eFillDir == FILL_TO_LEFT) ? aSource.aEnd.Col() : aSource.aStart.Col();
+ SCROW nValY = (eFillDir == FILL_TO_TOP ) ? aSource.aEnd.Row() : aSource.aStart.Row();
+ SCTAB nTab = aSource.aStart.Tab();
+ pDoc->SetValue( nValX, nValY, nTab, fStartValue );
+ }
+ pDoc->Fill( aSource.aStart.Col(), aSource.aStart.Row(),
+ aSource.aEnd.Col(), aSource.aEnd.Row(),
+ aMarkData, nCount,
+ eFillDir, eFillCmd, eFillDateCmd,
+ fStepValue, fMaxValue );
+
+ SetChangeTrack();
+
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID );
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoAutoFill::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+ if (eFillCmd==FILL_SIMPLE)
+ rViewShell.FillSimple( eFillDir, TRUE );
+ else
+ rViewShell.FillSeries( eFillDir, eFillCmd, eFillDateCmd,
+ fStartValue, fStepValue, fMaxValue, TRUE );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoAutoFill::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoMerge
+//
+// Zellen zusammenfassen / Zusammenfassung aufheben
+
+//----------------------------------------------------------------------------
+
+ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ maRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
+ mbMergeContents( bMergeContents ),
+ mpUndoDoc( pUndoDoc ),
+ mpDrawUndo( pDrawUndo )
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+ScUndoMerge::~ScUndoMerge()
+{
+ delete mpUndoDoc;
+ DeleteSdrUndoAction( mpDrawUndo );
+}
+
+
+//----------------------------------------------------------------------------
+
+String ScUndoMerge::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_MERGE );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoMerge::DoChange( bool bUndo ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, maRange );
+
+ if (bUndo)
+ // remove merge (contents are copied back below from undo document)
+ pDoc->RemoveMerge( maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
+ else
+ // repeat merge, but do not remove note captions (will be done by drawing redo below)
+/*!*/ pDoc->DoMerge( maRange.aStart.Tab(),
+ maRange.aStart.Col(), maRange.aStart.Row(),
+ maRange.aEnd.Col(), maRange.aEnd.Row(), false );
+
+ // undo -> copy back deleted contents
+ if (bUndo && mpUndoDoc)
+ {
+ pDoc->DeleteAreaTab( maRange, IDF_CONTENTS|IDF_NOCAPTIONS );
+ mpUndoDoc->CopyToDocument( maRange, IDF_ALL|IDF_NOCAPTIONS, FALSE, pDoc );
+ }
+
+ // redo -> merge contents again
+ else if (!bUndo && mbMergeContents)
+ {
+/*!*/ pDoc->DoMergeContents( maRange.aStart.Tab(),
+ maRange.aStart.Col(), maRange.aStart.Row(),
+ maRange.aEnd.Col(), maRange.aEnd.Row() );
+ }
+
+ if (bUndo)
+ DoSdrUndoAction( mpDrawUndo, pDoc );
+ else
+ RedoSdrUndoAction( mpDrawUndo );
+
+ BOOL bDidPaint = FALSE;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if ( pViewShell )
+ {
+ pViewShell->SetTabNo( maRange.aStart.Tab() );
+ bDidPaint = pViewShell->AdjustRowHeight( maRange.aStart.Row(), maRange.aEnd.Row() );
+ }
+
+ if (!bDidPaint)
+ ScUndoUtil::PaintMore( pDocShell, maRange );
+
+ ShowTable( maRange );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoMerge::Undo()
+{
+ BeginUndo();
+ DoChange( true );
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoMerge::Redo()
+{
+ BeginRedo();
+ DoChange( false );
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoMerge::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+ BOOL bCont = FALSE;
+ rViewShell.MergeCells( FALSE, bCont, TRUE );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScUndoMerge::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoAutoFormat
+//
+// Auto-Format (nur einfache Bloecke)
+
+//----------------------------------------------------------------------------
+
+ScUndoAutoFormat::ScUndoAutoFormat( ScDocShell* pNewDocShell,
+ const ScRange& rRange, ScDocument* pNewUndoDoc,
+ const ScMarkData& rMark, BOOL bNewSize, USHORT nNewFormatNo )
+ //
+ : ScBlockUndo( pNewDocShell, rRange, bNewSize ? SC_UNDO_MANUALHEIGHT : SC_UNDO_AUTOHEIGHT ),
+ //
+ pUndoDoc ( pNewUndoDoc ),
+ aMarkData ( rMark ),
+ bSize ( bNewSize ),
+ nFormatNo ( nNewFormatNo )
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoAutoFormat::~ScUndoAutoFormat()
+{
+ delete pUndoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoAutoFormat::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_AUTOFORMAT ); //"Auto-Format"
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoAutoFormat::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ // Attribute
+// pDoc->DeleteAreaTab( aBlockRange, IDF_ATTRIB );
+// pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, FALSE, pDoc );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
+ aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
+ aMarkData, IDF_ATTRIB );
+ ScRange aCopyRange = aBlockRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, FALSE, pDoc, &aMarkData );
+
+ // Zellhoehen und -breiten (IDF_NONE)
+ if (bSize)
+ {
+ SCCOL nStartX = aBlockRange.aStart.Col();
+ SCROW nStartY = aBlockRange.aStart.Row();
+ SCTAB nStartZ = aBlockRange.aStart.Tab();
+ SCCOL nEndX = aBlockRange.aEnd.Col();
+ SCROW nEndY = aBlockRange.aEnd.Row();
+ SCTAB nEndZ = aBlockRange.aEnd.Tab();
+
+ pUndoDoc->CopyToDocument( nStartX, 0, 0, nEndX, MAXROW, nTabCount-1,
+ IDF_NONE, FALSE, pDoc, &aMarkData );
+ pUndoDoc->CopyToDocument( 0, nStartY, 0, MAXCOL, nEndY, nTabCount-1,
+ IDF_NONE, FALSE, pDoc, &aMarkData );
+ pDocShell->PostPaint( 0, 0, nStartZ, MAXCOL, MAXROW, nEndZ,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES );
+ }
+ else
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
+
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoAutoFormat::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ SCCOL nStartX = aBlockRange.aStart.Col();
+ SCROW nStartY = aBlockRange.aStart.Row();
+ SCTAB nStartZ = aBlockRange.aStart.Tab();
+ SCCOL nEndX = aBlockRange.aEnd.Col();
+ SCROW nEndY = aBlockRange.aEnd.Row();
+ SCTAB nEndZ = aBlockRange.aEnd.Tab();
+
+ pDoc->AutoFormat( nStartX, nStartY, nEndX, nEndY, nFormatNo, aMarkData );
+
+ if (bSize)
+ {
+ VirtualDevice aVirtDev;
+ Fraction aZoomX(1,1);
+ Fraction aZoomY = aZoomX;
+ double nPPTX,nPPTY;
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ ScViewData* pData = pViewShell->GetViewData();
+ nPPTX = pData->GetPPTX();
+ nPPTY = pData->GetPPTY();
+ aZoomX = pData->GetZoomX();
+ aZoomY = pData->GetZoomY();
+ }
+ else
+ {
+ // Zoom auf 100 lassen
+ nPPTX = ScGlobal::nScreenPPTX;
+ nPPTY = ScGlobal::nScreenPPTY;
+ }
+
+ BOOL bFormula = FALSE; //! merken
+
+ for (SCTAB nTab=nStartZ; nTab<=nEndZ; nTab++)
+ {
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nTab );
+ aDestMark.SetMarkArea( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
+ aDestMark.MarkToMulti();
+
+ // wie SC_SIZE_VISOPT
+ SCROW nLastRow = -1;
+ for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
+ {
+ BYTE nOld = pDoc->GetRowFlags(nRow,nTab);
+ bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow);
+ if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
+ pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
+ }
+ pDoc->SetOptimalHeight( nStartY, nEndY, nTab, 0, &aVirtDev,
+ nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
+
+ SCCOL nLastCol = -1;
+ for (SCCOL nCol=nStartX; nCol<=nEndX; nCol++)
+ if (!pDoc->ColHidden(nCol, nTab, nLastCol))
+ {
+ USHORT nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab,
+ &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula,
+ &aDestMark );
+ pDoc->SetColWidth( nCol, nTab, nThisSize );
+ pDoc->ShowCol( nCol, nTab, TRUE );
+ }
+ }
+
+ pDocShell->PostPaint( 0, 0, nStartZ,
+ MAXCOL, MAXROW, nEndZ,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES);
+ }
+ else
+ pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
+
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoAutoFormat::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->AutoFormat( nFormatNo, TRUE );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoAutoFormat::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoReplace
+//
+// Ersetzen
+
+//----------------------------------------------------------------------------
+
+ScUndoReplace::ScUndoReplace( ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ const String& rNewUndoStr, ScDocument* pNewUndoDoc,
+ const SvxSearchItem* pItem )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ aCursorPos ( nCurX, nCurY, nCurZ ),
+ aMarkData ( rMark ),
+ aUndoStr ( rNewUndoStr ),
+ pUndoDoc ( pNewUndoDoc )
+{
+ pSearchItem = new SvxSearchItem( *pItem );
+ SetChangeTrack();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoReplace::~ScUndoReplace()
+{
+ delete pUndoDoc;
+ delete pSearchItem;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoReplace::SetChangeTrack()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ if ( pUndoDoc )
+ { //! im UndoDoc stehen nur die geaenderten Zellen,
+ // deswegen per Iterator moeglich
+ pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ }
+ else
+ {
+ nStartChangeAction = pChangeTrack->GetActionMax() + 1;
+ ScChangeActionContent* pContent = new ScChangeActionContent(
+ ScRange( aCursorPos) );
+ pContent->SetOldValue( aUndoStr, pDoc );
+ pContent->SetNewValue( pDoc->GetCell( aCursorPos ), pDoc );
+ pChangeTrack->Append( pContent );
+ nEndChangeAction = pChangeTrack->GetActionMax();
+ }
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoReplace::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_REPLACE ); // "Ersetzen"
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoReplace::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ ShowTable( aCursorPos.Tab() );
+
+ if (pUndoDoc) // nur bei ReplaceAll !!
+ {
+ DBG_ASSERT(pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE_ALL,
+ "ScUndoReplace:: Falscher Modus");
+
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+//! markierte Tabellen
+//! Bereich merken ?
+
+ // Undo-Dokument hat keine Zeilen-/Spalten-Infos, also mit bColRowFlags = FALSE
+ // kopieren, um Outline-Gruppen nicht kaputtzumachen.
+
+ USHORT nUndoFlags = (pSearchItem->GetPattern()) ? IDF_ATTRIB : IDF_CONTENTS;
+ pUndoDoc->CopyToDocument( 0, 0, 0,
+ MAXCOL, MAXROW, MAXTAB,
+ nUndoFlags, FALSE, pDoc, NULL, FALSE ); // ohne Row-Flags
+ pDocShell->PostPaintGridAll();
+ }
+ else if (pSearchItem->GetPattern() &&
+ pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
+ {
+ String aTempStr = pSearchItem->GetSearchString(); // vertauschen
+ pSearchItem->SetSearchString(pSearchItem->GetReplaceString());
+ pSearchItem->SetReplaceString(aTempStr);
+ pDoc->ReplaceStyle( *pSearchItem,
+ aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
+ aMarkData, TRUE);
+ pSearchItem->SetReplaceString(pSearchItem->GetSearchString());
+ pSearchItem->SetSearchString(aTempStr);
+ if (pViewShell)
+ pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
+ SC_FOLLOW_JUMP, FALSE, FALSE );
+ pDocShell->PostPaintGridAll();
+ }
+ else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE)
+ {
+ 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 );
+ }
+ else
+ {
+ // #78889# aUndoStr may contain line breaks
+ if ( aUndoStr.Search('\n') != STRING_NOTFOUND )
+ pDoc->PutCell( aCursorPos, new ScEditCell( aUndoStr, pDoc ) );
+ else
+ pDoc->SetString( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aUndoStr );
+ if (pViewShell)
+ pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
+ SC_FOLLOW_JUMP, FALSE, FALSE );
+ pDocShell->PostPaintGridAll();
+ }
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoReplace::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
+ SC_FOLLOW_JUMP, FALSE, FALSE );
+ if (pUndoDoc)
+ {
+ if (pViewShell)
+ {
+ pViewShell->SetMarkData( aMarkData );
+
+ pViewShell->SearchAndReplace( pSearchItem, FALSE, TRUE );
+ }
+ }
+ else if (pSearchItem->GetPattern() &&
+ pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
+ {
+ pDoc->ReplaceStyle( *pSearchItem,
+ aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
+ aMarkData, TRUE);
+ pDocShell->PostPaintGridAll();
+ }
+ else
+ if (pViewShell)
+ pViewShell->SearchAndReplace( pSearchItem, FALSE, TRUE );
+
+ SetChangeTrack();
+
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoReplace::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->SearchAndReplace( pSearchItem, TRUE, FALSE );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoReplace::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//============================================================================
+// class ScUndoTabOp
+//
+// Mehrfachoperation (nur einfache Bloecke)
+
+//----------------------------------------------------------------------------
+
+ScUndoTabOp::ScUndoTabOp( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ, ScDocument* pNewUndoDoc,
+ const ScRefAddress& rFormulaCell,
+ const ScRefAddress& rFormulaEnd,
+ const ScRefAddress& rRowCell,
+ const ScRefAddress& rColCell,
+ BYTE nMd )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
+ pUndoDoc ( pNewUndoDoc ),
+ theFormulaCell ( rFormulaCell ),
+ theFormulaEnd ( rFormulaEnd ),
+ theRowCell ( rRowCell ),
+ theColCell ( rColCell ),
+ nMode ( nMd )
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoTabOp::~ScUndoTabOp()
+{
+ delete pUndoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoTabOp::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_TABOP ); // "Mehrfachoperation"
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoTabOp::Undo()
+{
+ BeginUndo();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
+
+ USHORT nExtFlags = 0;
+ pDocShell->UpdatePaintExt( nExtFlags, aRange );
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->DeleteAreaTab( aRange,IDF_ALL & ~IDF_NOTE );
+ pUndoDoc->CopyToDocument( aRange, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ pDocShell->PostPaint( aRange, PAINT_GRID, nExtFlags );
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoTabOp::Redo()
+{
+ BeginRedo();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
+
+ ScTabOpParam aParam( theFormulaCell, theFormulaEnd,
+ theRowCell, theColCell,
+ nMode );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->TabOp( aParam, FALSE);
+
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoTabOp::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoTabOp::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//============================================================================
+// class ScUndoConversion
+//
+// Spelling
+
+//----------------------------------------------------------------------------
+
+ScUndoConversion::ScUndoConversion(
+ ScDocShell* pNewDocShell, const ScMarkData& rMark,
+ SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScDocument* pNewUndoDoc,
+ SCCOL nNewX, SCROW nNewY, SCTAB nNewZ, ScDocument* pNewRedoDoc,
+ const ScConversionParam& rConvParam ) :
+ ScSimpleUndo( pNewDocShell ),
+ aMarkData( rMark ),
+ aCursorPos( nCurX, nCurY, nCurZ ),
+ pUndoDoc( pNewUndoDoc ),
+ aNewCursorPos( nNewX, nNewY, nNewZ ),
+ pRedoDoc( pNewRedoDoc ),
+ maConvParam( rConvParam )
+{
+ SetChangeTrack();
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoConversion::~ScUndoConversion()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoConversion::SetChangeTrack()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ if ( pUndoDoc )
+ pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ else
+ {
+ DBG_ERROR( "ScUndoConversion::SetChangeTrack: kein UndoDoc" );
+ nStartChangeAction = nEndChangeAction = 0;
+ }
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+//----------------------------------------------------------------------------
+
+String ScUndoConversion::GetComment() const
+{
+ String aText;
+ switch( maConvParam.GetType() )
+ {
+ case SC_CONVERSION_SPELLCHECK: aText = ScGlobal::GetRscString( STR_UNDO_SPELLING ); break;
+ case SC_CONVERSION_HANGULHANJA: aText = ScGlobal::GetRscString( STR_UNDO_HANGULHANJA ); break;
+ case SC_CONVERSION_CHINESE_TRANSL: aText = ScGlobal::GetRscString( STR_UNDO_CHINESE_TRANSLATION ); break;
+ default: DBG_ERRORFILE( "ScUndoConversion::GetComment - unknown conversion type" );
+ }
+ return aText;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoConversion::DoChange( ScDocument* pRefDoc, const ScAddress& rCursorPos )
+{
+ if (pRefDoc)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ShowTable( rCursorPos.Tab() );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ // Undo/Redo-doc has only selected tables
+
+ BOOL bMulti = aMarkData.IsMultiMarked();
+ pRefDoc->CopyToDocument( 0, 0, 0,
+ MAXCOL, MAXROW, nTabCount-1,
+ IDF_CONTENTS, bMulti, pDoc, &aMarkData );
+ pDocShell->PostPaintGridAll();
+ }
+ else
+ {
+ DBG_ERROR("Kein Un-/RedoDoc bei Un-/RedoSpelling");
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoConversion::Undo()
+{
+ BeginUndo();
+ DoChange( pUndoDoc, aCursorPos );
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoConversion::Redo()
+{
+ BeginRedo();
+ DoChange( pRedoDoc, aNewCursorPos );
+ SetChangeTrack();
+ EndRedo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoConversion::Repeat( SfxRepeatTarget& rTarget )
+{
+ if( rTarget.ISA( ScTabViewTarget ) )
+ ((ScTabViewTarget&)rTarget).GetViewShell()->DoSheetConversion( maConvParam, TRUE );
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScUndoConversion::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return rTarget.ISA( ScTabViewTarget );
+}
+
+
+//============================================================================
+// 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
+
+//----------------------------------------------------------------------------
+
+ScUndoRefreshLink::ScUndoRefreshLink( ScDocShell* pNewDocShell,
+ ScDocument* pNewUndoDoc )
+ //
+ : ScSimpleUndo( pNewDocShell ),
+ //
+ pUndoDoc( pNewUndoDoc ),
+ pRedoDoc( NULL )
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoRefreshLink::~ScUndoRefreshLink()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoRefreshLink::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_UPDATELINK );
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoRefreshLink::Undo()
+{
+ BeginUndo();
+
+ BOOL bMakeRedo = !pRedoDoc;
+ if (bMakeRedo)
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+
+ BOOL bFirst = TRUE;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nCount; nTab++)
+ if (pUndoDoc->HasTable(nTab))
+ {
+ ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
+ if (bMakeRedo)
+ {
+ if (bFirst)
+ pRedoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ else
+ pRedoDoc->AddUndoTab( nTab, nTab, TRUE, TRUE );
+ bFirst = FALSE;
+ pDoc->CopyToDocument(aRange, IDF_ALL, FALSE, pRedoDoc);
+// pRedoDoc->TransferDrawPage( pDoc, nTab, nTab );
+ pRedoDoc->SetLink( nTab,
+ pDoc->GetLinkMode(nTab),
+ pDoc->GetLinkDoc(nTab),
+ pDoc->GetLinkFlt(nTab),
+ pDoc->GetLinkOpt(nTab),
+ pDoc->GetLinkTab(nTab),
+ pDoc->GetLinkRefreshDelay(nTab) );
+ }
+
+ pDoc->DeleteAreaTab( aRange,IDF_ALL );
+ pUndoDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pDoc );
+// pDoc->TransferDrawPage( pUndoDoc, nTab, nTab );
+ pDoc->SetLink( nTab, pUndoDoc->GetLinkMode(nTab), pUndoDoc->GetLinkDoc(nTab),
+ pUndoDoc->GetLinkFlt(nTab), pUndoDoc->GetLinkOpt(nTab),
+ pUndoDoc->GetLinkTab(nTab),
+ pUndoDoc->GetLinkRefreshDelay(nTab) );
+ }
+
+ pDocShell->PostPaintGridAll();
+
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoRefreshLink::Redo()
+{
+ DBG_ASSERT(pRedoDoc, "Kein RedoDoc bei ScUndoRefreshLink::Redo");
+
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nCount; nTab++)
+ if (pRedoDoc->HasTable(nTab))
+ {
+ ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
+
+ pDoc->DeleteAreaTab( aRange, IDF_ALL );
+ pRedoDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pDoc );
+// pDoc->TransferDrawPage( pRedoDoc, nTab, nTab );
+ pDoc->SetLink( nTab,
+ pRedoDoc->GetLinkMode(nTab),
+ pRedoDoc->GetLinkDoc(nTab),
+ pRedoDoc->GetLinkFlt(nTab),
+ pRedoDoc->GetLinkOpt(nTab),
+ pRedoDoc->GetLinkTab(nTab),
+ pRedoDoc->GetLinkRefreshDelay(nTab) );
+ }
+
+ pDocShell->PostPaintGridAll();
+
+ EndUndo();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoRefreshLink::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoRefreshLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------
+
+ScAreaLink* lcl_FindAreaLink( sfx2::LinkManager* pLinkManager, const String& rDoc,
+ const String& rFlt, const String& rOpt,
+ const String& rSrc, const ScRange& rDest )
+{
+ const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+ USHORT nCount = pLinkManager->GetLinks().Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *rLinks[i];
+ if (pBase->ISA(ScAreaLink))
+ if ( ((ScAreaLink*)pBase)->IsEqual( rDoc, rFlt, rOpt, rSrc, rDest ) )
+ return (ScAreaLink*)pBase;
+ }
+
+ DBG_ERROR("ScAreaLink nicht gefunden");
+ return NULL;
+}
+
+
+//============================================================================
+// class ScUndoInsertAreaLink
+//
+// Bereichs-Verknuepfung einfuegen
+
+//----------------------------------------------------------------------------
+
+ScUndoInsertAreaLink::ScUndoInsertAreaLink( ScDocShell* pShell,
+ const String& rDoc,
+ const String& rFlt, const String& rOpt,
+ const String& rArea, const ScRange& rDestRange,
+ ULONG nRefresh )
+ //
+ : ScSimpleUndo ( pShell ),
+ //
+ aDocName ( rDoc ),
+ aFltName ( rFlt ),
+ aOptions ( rOpt ),
+ aAreaName ( rArea ),
+ aRange ( rDestRange ),
+ nRefreshDelay ( nRefresh )
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoInsertAreaLink::~ScUndoInsertAreaLink()
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoInsertAreaLink::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoInsertAreaLink::Undo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
+ aAreaName, aRange );
+ if (pLink)
+ pLinkManager->Remove( pLink );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoInsertAreaLink::Redo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
+ aAreaName, aRange.aStart, nRefreshDelay );
+ pLink->SetInCreate( TRUE );
+ pLink->SetDestArea( aRange );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoInsertAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ //! ....
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoInsertAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//============================================================================
+// class ScUndoRemoveAreaLink
+//
+// Bereichs-Verknuepfung loeschen
+
+//----------------------------------------------------------------------------
+
+ScUndoRemoveAreaLink::ScUndoRemoveAreaLink( ScDocShell* pShell,
+ const String& rDoc, const String& rFlt, const String& rOpt,
+ const String& rArea, const ScRange& rDestRange,
+ ULONG nRefresh )
+ //
+ : ScSimpleUndo ( pShell ),
+ //
+ aDocName ( rDoc ),
+ aFltName ( rFlt ),
+ aOptions ( rOpt ),
+ aAreaName ( rArea ),
+ aRange ( rDestRange ),
+ nRefreshDelay ( nRefresh )
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoRemoveAreaLink::~ScUndoRemoveAreaLink()
+{
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoRemoveAreaLink::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_REMOVELINK ); //! eigener Text ??
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoRemoveAreaLink::Undo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
+ aAreaName, aRange.aStart, nRefreshDelay );
+ pLink->SetInCreate( TRUE );
+ pLink->SetDestArea( aRange );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoRemoveAreaLink::Redo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
+ aAreaName, aRange );
+ if (pLink)
+ pLinkManager->Remove( pLink );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoRemoveAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoRemoveAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//============================================================================
+// class ScUndoUpdateAreaLink
+//
+// Bereichs-Verknuepfung aktualisieren
+
+//----------------------------------------------------------------------------
+
+ScUndoUpdateAreaLink::ScUndoUpdateAreaLink( ScDocShell* pShell,
+ const String& rOldD, const String& rOldF, const String& rOldO,
+ const String& rOldA, const ScRange& rOldR, ULONG nOldRD,
+ const String& rNewD, const String& rNewF, const String& rNewO,
+ const String& rNewA, const ScRange& rNewR, ULONG nNewRD,
+ ScDocument* pUndo, ScDocument* pRedo, BOOL bDoInsert )
+ //
+ : ScSimpleUndo( pShell ),
+ //
+ aOldDoc ( rOldD ),
+ aOldFlt ( rOldF ),
+ aOldOpt ( rOldO ),
+ aOldArea ( rOldA ),
+ aOldRange ( rOldR ),
+ aNewDoc ( rNewD ),
+ aNewFlt ( rNewF ),
+ aNewOpt ( rNewO ),
+ aNewArea ( rNewA ),
+ aNewRange ( rNewR ),
+ pUndoDoc ( pUndo ),
+ pRedoDoc ( pRedo ),
+ nOldRefresh ( nOldRD ),
+ nNewRefresh ( nNewRD ),
+ bWithInsert ( bDoInsert )
+{
+ DBG_ASSERT( aOldRange.aStart == aNewRange.aStart, "AreaLink verschoben ?" );
+}
+
+
+//----------------------------------------------------------------------------
+
+__EXPORT ScUndoUpdateAreaLink::~ScUndoUpdateAreaLink()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+String __EXPORT ScUndoUpdateAreaLink::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_UPDATELINK ); //! eigener Text ??
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScUndoUpdateAreaLink::DoChange( const BOOL bUndo ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ SCCOL nEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() );
+ SCROW nEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() );
+ SCTAB nEndZ = Max( aOldRange.aEnd.Tab(), aNewRange.aEnd.Tab() ); //?
+
+ if ( bUndo )
+ {
+ if ( bWithInsert )
+ {
+ pDoc->FitBlock( aNewRange, aOldRange );
+ pDoc->DeleteAreaTab( aOldRange, IDF_ALL & ~IDF_NOTE );
+ pUndoDoc->UndoToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ }
+ else
+ {
+ ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
+ pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
+ pUndoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ }
+ }
+ else
+ {
+ if ( bWithInsert )
+ {
+ pDoc->FitBlock( aOldRange, aNewRange );
+ pDoc->DeleteAreaTab( aNewRange, IDF_ALL & ~IDF_NOTE );
+ pRedoDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ }
+ else
+ {
+ ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
+ pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
+ pRedoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ }
+ }
+
+ ScRange aWorkRange( aNewRange.aStart, ScAddress( nEndX, nEndY, nEndZ ) );
+ pDoc->ExtendMerge( aWorkRange, TRUE );
+
+ // Paint
+
+ if ( aNewRange.aEnd.Col() != aOldRange.aEnd.Col() )
+ aWorkRange.aEnd.SetCol(MAXCOL);
+ if ( aNewRange.aEnd.Row() != aOldRange.aEnd.Row() )
+ aWorkRange.aEnd.SetRow(MAXROW);
+
+ if ( !pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), aWorkRange.aStart.Tab() ) )
+ pDocShell->PostPaint( aWorkRange, PAINT_GRID );
+
+ pDocShell->PostDataChanged();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoUpdateAreaLink::Undo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aNewDoc, aNewFlt, aNewOpt,
+ aNewArea, aNewRange );
+ if (pLink)
+ {
+ pLink->SetSource( aOldDoc, aOldFlt, aOldOpt, aOldArea ); // alte Werte im Link
+ pLink->SetDestArea( aOldRange );
+ pLink->SetRefreshDelay( nOldRefresh );
+ }
+
+ DoChange(TRUE);
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoUpdateAreaLink::Redo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aOldDoc, aOldFlt, aOldOpt,
+ aOldArea, aOldRange );
+ if (pLink)
+ {
+ pLink->SetSource( aNewDoc, aNewFlt, aNewOpt, aNewArea ); // neue Werte im Link
+ pLink->SetDestArea( aNewRange );
+ pLink->SetRefreshDelay( nNewRefresh );
+ }
+
+ DoChange(FALSE);
+}
+
+
+//----------------------------------------------------------------------------
+
+void __EXPORT ScUndoUpdateAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL __EXPORT ScUndoUpdateAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+
+
diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx
new file mode 100644
index 000000000000..cc13ce9f1412
--- /dev/null
+++ b/sc/source/ui/undo/undocell.cxx
@@ -0,0 +1,1129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editobj.hxx>
+#include <svl/zforlist.hxx>
+#include <sfx2/app.hxx>
+
+#include "undocell.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "cell.hxx"
+#include "target.hxx"
+#include "undoolk.hxx"
+#include "detdata.hxx"
+#include "stlpool.hxx"
+#include "printfun.hxx"
+#include "rangenam.hxx"
+#include "chgtrack.hxx"
+#include "sc.hrc"
+#include "docuno.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScUndoCursorAttr, ScSimpleUndo);
+TYPEINIT1(ScUndoEnterData, ScSimpleUndo);
+TYPEINIT1(ScUndoEnterValue, ScSimpleUndo);
+TYPEINIT1(ScUndoPutCell, ScSimpleUndo);
+TYPEINIT1(ScUndoPageBreak, ScSimpleUndo);
+TYPEINIT1(ScUndoPrintZoom, ScSimpleUndo);
+TYPEINIT1(ScUndoThesaurus, ScSimpleUndo);
+TYPEINIT1(ScUndoReplaceNote, ScSimpleUndo);
+TYPEINIT1(ScUndoShowHideNote, ScSimpleUndo);
+TYPEINIT1(ScUndoDetective, ScSimpleUndo);
+TYPEINIT1(ScUndoRangeNames, ScSimpleUndo);
+
+
+// -----------------------------------------------------------------------
+//
+// Attribute auf Cursor anwenden
+//
+
+ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ const ScPatternAttr* pOldPat, const ScPatternAttr* pNewPat,
+ const ScPatternAttr* pApplyPat, BOOL bAutomatic ) :
+ ScSimpleUndo( pNewDocShell ),
+ nCol( nNewCol ),
+ nRow( nNewRow ),
+ nTab( nNewTab ),
+ bIsAutomatic( bAutomatic )
+{
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ pNewPattern = (ScPatternAttr*) &pPool->Put( *pNewPat );
+ pOldPattern = (ScPatternAttr*) &pPool->Put( *pOldPat );
+ pApplyPattern = (ScPatternAttr*) &pPool->Put( *pApplyPat );
+}
+
+__EXPORT ScUndoCursorAttr::~ScUndoCursorAttr()
+{
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ pPool->Remove(*pNewPattern);
+ pPool->Remove(*pOldPattern);
+ pPool->Remove(*pApplyPattern);
+}
+
+String __EXPORT ScUndoCursorAttr::GetComment() const
+{
+ //! eigener Text fuer automatische Attributierung
+
+ USHORT nId = STR_UNDO_CURSORATTR; // "Attribute"
+ return ScGlobal::GetRscString( nId );
+}
+
+void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern ) const
+{
+ pDocShell->GetDocument()->SetPattern( nCol, nRow, nTab, *pWhichPattern, TRUE );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->SetTabNo( nTab );
+ pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, FALSE, FALSE );
+ pViewShell->AdjustBlockHeight();
+ }
+
+ const SfxItemSet& rApplySet = pApplyPattern->GetItemSet();
+ BOOL bPaintExt = ( rApplySet.GetItemState( ATTR_SHADOW, TRUE ) != SFX_ITEM_DEFAULT ||
+ rApplySet.GetItemState( ATTR_CONDITIONAL, TRUE ) != SFX_ITEM_DEFAULT );
+ BOOL bPaintRows = ( rApplySet.GetItemState( ATTR_HOR_JUSTIFY, TRUE ) != SFX_ITEM_DEFAULT );
+
+ USHORT nFlags = SC_PF_TESTMERGE;
+ if (bPaintExt)
+ nFlags |= SC_PF_LINES;
+ if (bPaintRows)
+ nFlags |= SC_PF_WHOLEROWS;
+ pDocShell->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nFlags );
+}
+
+void __EXPORT ScUndoCursorAttr::Undo()
+{
+ BeginUndo();
+ DoChange(pOldPattern);
+
+ if ( bIsAutomatic )
+ {
+ // wenn automatische Formatierung rueckgaengig gemacht wird,
+ // soll auch nicht weiter automatisch formatiert werden:
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->ForgetFormatArea();
+ }
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoCursorAttr::Redo()
+{
+ BeginRedo();
+ DoChange(pNewPattern);
+ EndRedo();
+}
+
+void __EXPORT ScUndoCursorAttr::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->ApplySelectionPattern( *pApplyPattern );
+}
+
+BOOL __EXPORT ScUndoCursorAttr::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Daten eingeben
+//
+
+ScUndoEnterData::ScUndoEnterData( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ SCTAB nNewCount, SCTAB* pNewTabs, ScBaseCell** ppOldData,
+ BOOL* pHasForm, ULONG* pOldForm,
+ const String& rNewStr, EditTextObject* pObj ) :
+ ScSimpleUndo( pNewDocShell ),
+ aNewString( rNewStr ),
+ pTabs( pNewTabs ),
+ ppOldCells( ppOldData ),
+ pHasFormat( pHasForm ),
+ pOldFormats( pOldForm ),
+ pNewEditData( pObj ),
+ nCol( nNewCol ),
+ nRow( nNewRow ),
+ nTab( nNewTab ),
+ nCount( nNewCount )
+{
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoEnterData::~ScUndoEnterData()
+{
+ for (USHORT i=0; i<nCount; i++)
+ if (ppOldCells[i])
+ ppOldCells[i]->Delete();
+ delete[] ppOldCells;
+
+ delete[] pHasFormat;
+ delete[] pOldFormats;
+ delete[] pTabs;
+
+ delete pNewEditData;
+}
+
+String __EXPORT ScUndoEnterData::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
+}
+
+void ScUndoEnterData::DoChange() const
+{
+ // Zeilenhoehe anpassen
+ //! nur wenn noetig (alte oder neue EditZelle, oder Attribute) ??
+ for (USHORT i=0; i<nCount; i++)
+ pDocShell->AdjustRowHeight( nRow, nRow, pTabs[i] );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->SetTabNo( nTab );
+ pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, FALSE, FALSE );
+ }
+
+ pDocShell->PostDataChanged();
+}
+
+void ScUndoEnterData::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ nEndChangeAction = pChangeTrack->GetActionMax() + 1;
+ ScAddress aPos( nCol, nRow, nTab );
+ for (USHORT i=0; i<nCount; i++)
+ {
+ aPos.SetTab( pTabs[i] );
+ ULONG nFormat = 0;
+ if ( pHasFormat && pOldFormats )
+ {
+ if ( pHasFormat[i] )
+ nFormat = pOldFormats[i];
+ }
+ pChangeTrack->AppendContent( aPos, ppOldCells[i], nFormat );
+ }
+ if ( nEndChangeAction > pChangeTrack->GetActionMax() )
+ nEndChangeAction = 0; // nichts appended
+ }
+ else
+ nEndChangeAction = 0;
+}
+
+void __EXPORT ScUndoEnterData::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScBaseCell* pNewCell = ppOldCells[i] ? ppOldCells[i]->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
+ pDoc->PutCell( nCol, nRow, pTabs[i], pNewCell );
+
+ if (pHasFormat && pOldFormats)
+ {
+ if ( pHasFormat[i] )
+ pDoc->ApplyAttr( nCol, nRow, pTabs[i],
+ SfxUInt32Item( ATTR_VALUE_FORMAT, pOldFormats[i] ) );
+ else
+ {
+ ScPatternAttr aPattern( *pDoc->GetPattern( nCol, nRow, pTabs[i] ) );
+ aPattern.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
+ pDoc->SetPattern( nCol, nRow, pTabs[i], aPattern, TRUE );
+ }
+ }
+ pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
+ }
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack && nEndChangeAction >= sal::static_int_cast<ULONG>(nCount) )
+ pChangeTrack->Undo( nEndChangeAction - nCount + 1, nEndChangeAction );
+
+ DoChange();
+ EndUndo();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+}
+
+void __EXPORT ScUndoEnterData::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ if (pNewEditData)
+ pDoc->PutCell( nCol, nRow, pTabs[i], new ScEditCell( pNewEditData,
+ pDoc, NULL ) );
+ else
+ pDoc->SetString( nCol, nRow, pTabs[i], aNewString );
+ pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
+ }
+
+ SetChangeTrack();
+
+ DoChange();
+ EndRedo();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+}
+
+void __EXPORT ScUndoEnterData::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ String aTemp = aNewString;
+ ((ScTabViewTarget&)rTarget).GetViewShell()->EnterDataAtCursor( aTemp );
+ }
+}
+
+BOOL __EXPORT ScUndoEnterData::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Wert aendern
+//
+
+ScUndoEnterValue::ScUndoEnterValue( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
+ ScBaseCell* pUndoCell, double nVal, BOOL bHeight ) :
+ ScSimpleUndo( pNewDocShell ),
+ aPos ( rNewPos ),
+ pOldCell ( pUndoCell ),
+ nValue ( nVal ),
+ bNeedHeight ( bHeight )
+{
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoEnterValue::~ScUndoEnterValue()
+{
+ if (pOldCell)
+ pOldCell->Delete();
+}
+
+String __EXPORT ScUndoEnterValue::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
+}
+
+void ScUndoEnterValue::SetChangeTrack()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ nEndChangeAction = pChangeTrack->GetActionMax() + 1;
+ pChangeTrack->AppendContent( aPos, pOldCell );
+ if ( nEndChangeAction > pChangeTrack->GetActionMax() )
+ nEndChangeAction = 0; // nichts appended
+ }
+ else
+ nEndChangeAction = 0;
+}
+
+void __EXPORT ScUndoEnterValue::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
+
+ pDoc->PutCell( aPos, pNewCell );
+
+ pDocShell->PostPaintCell( aPos );
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoEnterValue::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->SetValue( aPos.Col(), aPos.Row(), aPos.Tab(), nValue );
+ pDocShell->PostPaintCell( aPos );
+
+ SetChangeTrack();
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoEnterValue::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL __EXPORT ScUndoEnterValue::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Beliebige Zelle eingeben
+//
+
+ScUndoPutCell::ScUndoPutCell( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
+ ScBaseCell* pUndoCell, ScBaseCell* pRedoCell, BOOL bHeight ) :
+ ScSimpleUndo( pNewDocShell ),
+ aPos ( rNewPos ),
+ pOldCell ( pUndoCell ),
+ pEnteredCell( pRedoCell ),
+ bNeedHeight ( bHeight )
+{
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoPutCell::~ScUndoPutCell()
+{
+ if (pOldCell)
+ pOldCell->Delete();
+ if (pEnteredCell)
+ pEnteredCell->Delete();
+}
+
+String __EXPORT ScUndoPutCell::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
+}
+
+void ScUndoPutCell::SetChangeTrack()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ nEndChangeAction = pChangeTrack->GetActionMax() + 1;
+ pChangeTrack->AppendContent( aPos, pOldCell );
+ if ( nEndChangeAction > pChangeTrack->GetActionMax() )
+ nEndChangeAction = 0; // nichts appended
+ }
+ else
+ nEndChangeAction = 0;
+}
+
+void __EXPORT ScUndoPutCell::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;
+
+ pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );
+
+ pDocShell->PostPaintCell( aPos );
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoPutCell::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScBaseCell* pNewCell = pEnteredCell ? pEnteredCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;
+
+ pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );
+
+ pDocShell->PostPaintCell( aPos );
+
+ SetChangeTrack();
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoPutCell::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL __EXPORT ScUndoPutCell::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Seitenumbrueche
+//
+
+ScUndoPageBreak::ScUndoPageBreak( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ BOOL bNewColumn, BOOL bNewInsert ) :
+ ScSimpleUndo( pNewDocShell ),
+ nCol( nNewCol ),
+ nRow( nNewRow ),
+ nTab( nNewTab ),
+ bColumn( bNewColumn ),
+ bInsert( bNewInsert )
+{
+}
+
+__EXPORT ScUndoPageBreak::~ScUndoPageBreak()
+{
+}
+
+String __EXPORT ScUndoPageBreak::GetComment() const
+{
+ //"Spaltenumbruch" | "Zeilenumbruch" "einfuegen" | "loeschen"
+ return String ( bColumn ?
+ ( bInsert ?
+ ScGlobal::GetRscString( STR_UNDO_INSCOLBREAK ) :
+ ScGlobal::GetRscString( STR_UNDO_DELCOLBREAK )
+ ) :
+ ( bInsert ?
+ ScGlobal::GetRscString( STR_UNDO_INSROWBREAK ) :
+ ScGlobal::GetRscString( STR_UNDO_DELROWBREAK )
+ ) );
+}
+
+void ScUndoPageBreak::DoChange( BOOL bInsertP ) const
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ {
+ pViewShell->SetTabNo( nTab );
+ pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, FALSE, FALSE );
+
+ if (bInsertP)
+ pViewShell->InsertPageBreak(bColumn, FALSE);
+ else
+ pViewShell->DeletePageBreak(bColumn, FALSE);
+
+ pDocShell->GetDocument()->InvalidatePageBreaks(nTab);
+ }
+}
+
+void __EXPORT ScUndoPageBreak::Undo()
+{
+ BeginUndo();
+ DoChange(!bInsert);
+ EndUndo();
+}
+
+void __EXPORT ScUndoPageBreak::Redo()
+{
+ BeginRedo();
+ DoChange(bInsert);
+ EndRedo();
+}
+
+void __EXPORT ScUndoPageBreak::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+
+ if (bInsert)
+ rViewShell.InsertPageBreak(bColumn, TRUE);
+ else
+ rViewShell.DeletePageBreak(bColumn, TRUE);
+ }
+}
+
+BOOL __EXPORT ScUndoPageBreak::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// Druck-Skalierung
+//
+
+ScUndoPrintZoom::ScUndoPrintZoom( ScDocShell* pNewDocShell,
+ SCTAB nT, USHORT nOS, USHORT nOP, USHORT nNS, USHORT nNP ) :
+ ScSimpleUndo( pNewDocShell ),
+ nTab( nT ),
+ nOldScale( nOS ),
+ nOldPages( nOP ),
+ nNewScale( nNS ),
+ nNewPages( nNP )
+{
+}
+
+__EXPORT ScUndoPrintZoom::~ScUndoPrintZoom()
+{
+}
+
+String __EXPORT ScUndoPrintZoom::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_PRINTSCALE );
+}
+
+void ScUndoPrintZoom::DoChange( BOOL bUndo )
+{
+ USHORT nScale = bUndo ? nOldScale : nNewScale;
+ USHORT nPages = bUndo ? nOldPages : nNewPages;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ String aStyleName = pDoc->GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
+
+ ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ }
+}
+
+void __EXPORT ScUndoPrintZoom::Undo()
+{
+ BeginUndo();
+ DoChange(TRUE);
+ EndUndo();
+}
+
+void __EXPORT ScUndoPrintZoom::Redo()
+{
+ BeginRedo();
+ DoChange(FALSE);
+ EndRedo();
+}
+
+void __EXPORT ScUndoPrintZoom::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+ ScViewData* pViewData = rViewShell.GetViewData();
+ pViewData->GetDocShell()->SetPrintZoom( pViewData->GetTabNo(), nNewScale, nNewPages );
+ }
+}
+
+BOOL __EXPORT ScUndoPrintZoom::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Thesaurus
+//
+
+ScUndoThesaurus::ScUndoThesaurus( ScDocShell* pNewDocShell,
+ SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
+ const String& rNewUndoStr, const EditTextObject* pUndoTObj,
+ const String& rNewRedoStr, const EditTextObject* pRedoTObj) :
+ ScSimpleUndo( pNewDocShell ),
+ nCol( nNewCol ),
+ nRow( nNewRow ),
+ nTab( nNewTab ),
+ aUndoStr( rNewUndoStr ),
+ aRedoStr( rNewRedoStr )
+{
+ pUndoTObject = (pUndoTObj) ? pUndoTObj->Clone() : NULL;
+ pRedoTObject = (pRedoTObj) ? pRedoTObj->Clone() : NULL;
+
+ ScBaseCell* pOldCell;
+ if ( pUndoTObject )
+ pOldCell = new ScEditCell( pUndoTObject, pDocShell->GetDocument(), NULL );
+ else
+ pOldCell = new ScStringCell( aUndoStr );
+ SetChangeTrack( pOldCell );
+ pOldCell->Delete();
+}
+
+__EXPORT ScUndoThesaurus::~ScUndoThesaurus()
+{
+ delete pUndoTObject;
+ delete pRedoTObject;
+}
+
+String __EXPORT ScUndoThesaurus::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_THESAURUS ); // "Thesaurus"
+}
+
+void ScUndoThesaurus::SetChangeTrack( ScBaseCell* pOldCell )
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ nEndChangeAction = pChangeTrack->GetActionMax() + 1;
+ pChangeTrack->AppendContent( ScAddress( nCol, nRow, nTab ), pOldCell );
+ if ( nEndChangeAction > pChangeTrack->GetActionMax() )
+ nEndChangeAction = 0; // nichts appended
+ }
+ else
+ nEndChangeAction = 0;
+}
+
+void __EXPORT ScUndoThesaurus::DoChange( BOOL bUndo, const String& rStr,
+ const EditTextObject* pTObj )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->SetTabNo( nTab );
+ pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, FALSE, FALSE );
+ }
+
+ if (pTObj)
+ {
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ ScEditCell* pNewCell = new ScEditCell( pTObj, pDoc, NULL );
+ pDoc->PutCell( nCol, nRow, nTab, pNewCell );
+ if ( !bUndo )
+ SetChangeTrack( pCell );
+ }
+ else
+ {
+ DBG_ERROR("Nicht CELLTYPE_EDIT bei Un/RedoThesaurus");
+ }
+ }
+ }
+ else
+ {
+ ScBaseCell* pCell = NULL;
+ if ( !bUndo )
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ pDoc->SetString( nCol, nRow, nTab, rStr );
+ if ( !bUndo )
+ SetChangeTrack( pCell );
+ }
+
+ pDocShell->PostPaintCell( nCol, nRow, nTab );
+}
+
+void __EXPORT ScUndoThesaurus::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE, aUndoStr, pUndoTObject );
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
+ EndUndo();
+}
+
+void __EXPORT ScUndoThesaurus::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE, aRedoStr, pRedoTObject );
+ EndRedo();
+}
+
+void __EXPORT ScUndoThesaurus::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->DoThesaurus( TRUE );
+}
+
+BOOL __EXPORT ScUndoThesaurus::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// ============================================================================
+
+ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
+ const ScNoteData& rNoteData, bool bInsert, SdrUndoAction* pDrawUndo ) :
+ ScSimpleUndo( &rDocShell ),
+ maPos( rPos ),
+ mpDrawUndo( pDrawUndo )
+{
+ DBG_ASSERT( rNoteData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" );
+ (bInsert ? maNewData : maOldData) = rNoteData;
+}
+
+ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
+ const ScNoteData& rOldData, const ScNoteData& rNewData, SdrUndoAction* pDrawUndo ) :
+ ScSimpleUndo( &rDocShell ),
+ maPos( rPos ),
+ maOldData( rOldData ),
+ maNewData( rNewData ),
+ 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()
+{
+ DeleteSdrUndoAction( mpDrawUndo );
+}
+
+void ScUndoReplaceNote::Undo()
+{
+ BeginUndo();
+ DoSdrUndoAction( mpDrawUndo, pDocShell->GetDocument() );
+ /* Undo insert -> remove new note.
+ Undo remove -> insert old note.
+ Undo replace -> remove new note, insert old note. */
+ DoRemoveNote( maNewData );
+ DoInsertNote( maOldData );
+ pDocShell->PostPaintCell( maPos );
+ EndUndo();
+}
+
+void ScUndoReplaceNote::Redo()
+{
+ BeginRedo();
+ RedoSdrUndoAction( mpDrawUndo );
+ /* Redo insert -> insert new note.
+ Redo remove -> remove old note.
+ Redo replace -> remove old note, insert new note. */
+ DoRemoveNote( maOldData );
+ DoInsertNote( maNewData );
+ pDocShell->PostPaintCell( maPos );
+ EndRedo();
+}
+
+void ScUndoReplaceNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
+{
+}
+
+BOOL ScUndoReplaceNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
+{
+ return FALSE;
+}
+
+String ScUndoReplaceNote::GetComment() const
+{
+ return ScGlobal::GetRscString( maNewData.mpCaption ?
+ (maOldData.mpCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE );
+}
+
+void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
+{
+ if( rNoteData.mpCaption )
+ {
+ ScDocument& rDoc = *pDocShell->GetDocument();
+ DBG_ASSERT( !rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
+ ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
+ rDoc.TakeNote( maPos, pNote );
+ }
+}
+
+void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
+{
+ if( rNoteData.mpCaption )
+ {
+ ScDocument& rDoc = *pDocShell->GetDocument();
+ DBG_ASSERT( rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
+ if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
+ {
+ /* 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;
+ }
+ }
+}
+
+// ============================================================================
+
+ScUndoShowHideNote::ScUndoShowHideNote( ScDocShell& rDocShell, const ScAddress& rPos, bool bShow ) :
+ ScSimpleUndo( &rDocShell ),
+ maPos( rPos ),
+ mbShown( bShow )
+{
+}
+
+ScUndoShowHideNote::~ScUndoShowHideNote()
+{
+}
+
+void ScUndoShowHideNote::Undo()
+{
+ BeginUndo();
+ if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
+ pNote->ShowCaption( maPos, !mbShown );
+ EndUndo();
+}
+
+void ScUndoShowHideNote::Redo()
+{
+ BeginRedo();
+ if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
+ pNote->ShowCaption( maPos, mbShown );
+ EndRedo();
+}
+
+void ScUndoShowHideNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
+{
+}
+
+BOOL ScUndoShowHideNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
+{
+ return FALSE;
+}
+
+String ScUndoShowHideNote::GetComment() const
+{
+ return ScGlobal::GetRscString( mbShown ? STR_UNDO_SHOWNOTE : STR_UNDO_HIDENOTE );
+}
+
+// ============================================================================
+
+// -----------------------------------------------------------------------
+//
+// Detektiv
+//
+
+ScUndoDetective::ScUndoDetective( ScDocShell* pNewDocShell,
+ SdrUndoAction* pDraw, const ScDetOpData* pOperation,
+ ScDetOpList* pUndoList ) :
+ ScSimpleUndo( pNewDocShell ),
+ pOldList ( pUndoList ),
+ nAction ( 0 ),
+ pDrawUndo ( pDraw )
+{
+ bIsDelete = ( pOperation == NULL );
+ if (!bIsDelete)
+ {
+ nAction = (USHORT) pOperation->GetOperation();
+ aPos = pOperation->GetPos();
+ }
+}
+
+__EXPORT ScUndoDetective::~ScUndoDetective()
+{
+ DeleteSdrUndoAction( pDrawUndo );
+ delete pOldList;
+}
+
+String __EXPORT ScUndoDetective::GetComment() const
+{
+ USHORT nId = STR_UNDO_DETDELALL;
+ if ( !bIsDelete )
+ switch ( (ScDetOpType) nAction )
+ {
+ case SCDETOP_ADDSUCC: nId = STR_UNDO_DETADDSUCC; break;
+ case SCDETOP_DELSUCC: nId = STR_UNDO_DETDELSUCC; break;
+ case SCDETOP_ADDPRED: nId = STR_UNDO_DETADDPRED; break;
+ case SCDETOP_DELPRED: nId = STR_UNDO_DETDELPRED; break;
+ case SCDETOP_ADDERROR: nId = STR_UNDO_DETADDERROR; break;
+ }
+
+ return ScGlobal::GetRscString( nId );
+}
+
+
+void __EXPORT ScUndoDetective::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ DoSdrUndoAction(pDrawUndo, pDoc);
+
+ if (bIsDelete)
+ {
+ if ( pOldList )
+ pDoc->SetDetOpList( new ScDetOpList(*pOldList) );
+ }
+ else
+ {
+ // Eintrag aus der Liste loeschen
+
+ ScDetOpList* pList = pDoc->GetDetOpList();
+ if (pList && pList->Count())
+ {
+ USHORT nPos = pList->Count() - 1;
+ ScDetOpData* pData = (*pList)[nPos];
+ if ( pData->GetOperation() == (ScDetOpType) nAction && pData->GetPos() == aPos )
+ pList->DeleteAndDestroy( nPos, 1 );
+ else
+ {
+ DBG_ERROR("Detektiv-Eintrag in der Liste nicht gefunden");
+ }
+ }
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->RecalcPPT(); //! use broadcast instead?
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoDetective::Redo()
+{
+ BeginRedo();
+
+ RedoSdrUndoAction(pDrawUndo);
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ if (bIsDelete)
+ pDoc->ClearDetectiveOperations();
+ else
+ pDoc->AddDetectiveOperation( ScDetOpData( aPos, (ScDetOpType) nAction ) );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->RecalcPPT(); //! use broadcast instead?
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoDetective::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // hammanich
+}
+
+BOOL __EXPORT ScUndoDetective::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+//
+// Benannte Bereiche
+//
+
+ScUndoRangeNames::ScUndoRangeNames( ScDocShell* pNewDocShell,
+ ScRangeName* pOld, ScRangeName* pNew ) :
+ ScSimpleUndo( pNewDocShell ),
+ pOldRanges ( pOld ),
+ pNewRanges ( pNew )
+{
+}
+
+__EXPORT ScUndoRangeNames::~ScUndoRangeNames()
+{
+ delete pOldRanges;
+ delete pNewRanges;
+}
+
+String __EXPORT ScUndoRangeNames::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_RANGENAMES );
+}
+
+void ScUndoRangeNames::DoChange( BOOL bUndo )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->CompileNameFormula( TRUE ); // CreateFormulaString
+
+ if ( bUndo )
+ pDoc->SetRangeName( new ScRangeName( *pOldRanges ) );
+ else
+ pDoc->SetRangeName( new ScRangeName( *pNewRanges ) );
+
+ pDoc->CompileNameFormula( FALSE ); // CompileFormulaString
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+}
+
+void __EXPORT ScUndoRangeNames::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+void __EXPORT ScUndoRangeNames::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+}
+
+void __EXPORT ScUndoRangeNames::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // hammanich
+}
+
+BOOL __EXPORT ScUndoRangeNames::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+
+
diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx
new file mode 100644
index 000000000000..0f7834b2a8df
--- /dev/null
+++ b/sc/source/ui/undo/undodat.cxx
@@ -0,0 +1,2193 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/app.hxx>
+
+#include "undodat.hxx"
+#include "undoutil.hxx"
+#include "undoolk.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "olinetab.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "pivot.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "target.hxx"
+#include "chartarr.hxx"
+#include "dbdocfun.hxx"
+#include "olinefun.hxx"
+#include "dpobject.hxx"
+#include "attrib.hxx"
+#include "hints.hxx"
+#include "sc.hrc"
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScUndoDoOutline, ScSimpleUndo);
+TYPEINIT1(ScUndoMakeOutline, ScSimpleUndo);
+TYPEINIT1(ScUndoOutlineLevel, ScSimpleUndo);
+TYPEINIT1(ScUndoOutlineBlock, ScSimpleUndo);
+TYPEINIT1(ScUndoRemoveAllOutlines, ScSimpleUndo);
+TYPEINIT1(ScUndoAutoOutline, ScSimpleUndo);
+TYPEINIT1(ScUndoSubTotals, ScDBFuncUndo);
+TYPEINIT1(ScUndoSort, ScDBFuncUndo);
+TYPEINIT1(ScUndoQuery, ScDBFuncUndo);
+TYPEINIT1(ScUndoAutoFilter, ScDBFuncUndo);
+TYPEINIT1(ScUndoDBData, ScSimpleUndo);
+TYPEINIT1(ScUndoImportData, ScSimpleUndo);
+TYPEINIT1(ScUndoRepeatDB, ScSimpleUndo);
+//UNUSED2008-05 TYPEINIT1(ScUndoPivot, ScSimpleUndo);
+TYPEINIT1(ScUndoDataPilot, ScSimpleUndo);
+TYPEINIT1(ScUndoConsolidate, ScSimpleUndo);
+TYPEINIT1(ScUndoChartData, ScSimpleUndo);
+
+// -----------------------------------------------------------------------
+
+
+//
+// Outline-Gruppen ein- oder ausblenden
+//
+
+ScUndoDoOutline::ScUndoDoOutline( ScDocShell* pNewDocShell,
+ SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
+ ScDocument* pNewUndoDoc, BOOL bNewColumns,
+ USHORT nNewLevel, USHORT nNewEntry, BOOL bNewShow ) :
+ ScSimpleUndo( pNewDocShell ),
+ nStart( nNewStart ),
+ nEnd( nNewEnd ),
+ nTab( nNewTab ),
+ pUndoDoc( pNewUndoDoc ),
+ bColumns( bNewColumns ),
+ nLevel( nNewLevel ),
+ nEntry( nNewEntry ),
+ bShow( bNewShow )
+{
+}
+
+__EXPORT ScUndoDoOutline::~ScUndoDoOutline()
+{
+ delete pUndoDoc;
+}
+
+String __EXPORT ScUndoDoOutline::GetComment() const
+{ // Detail einblenden" "Detail ausblenden"
+ return bShow ?
+ ScGlobal::GetRscString( STR_UNDO_DOOUTLINE ) :
+ ScGlobal::GetRscString( STR_UNDO_REDOOUTLINE );
+}
+
+void __EXPORT ScUndoDoOutline::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // Tabelle muss vorher umgeschaltet sein (#46952#) !!!
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ // inverse Funktion ausfuehren
+
+ if (bShow)
+ pViewShell->HideOutline( bColumns, nLevel, nEntry, FALSE, FALSE );
+ else
+ pViewShell->ShowOutline( bColumns, nLevel, nEntry, FALSE, FALSE );
+
+ // Original Spalten-/Zeilenstatus
+
+ if (bColumns)
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, FALSE, pDoc);
+ else
+ pUndoDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pDoc );
+
+ pViewShell->UpdateScrollBars();
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP);
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoDoOutline::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // Tabelle muss vorher umgeschaltet sein (#46952#) !!!
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ if (bShow)
+ pViewShell->ShowOutline( bColumns, nLevel, nEntry, FALSE );
+ else
+ pViewShell->HideOutline( bColumns, nLevel, nEntry, FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoDoOutline::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoDoOutline::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // geht nicht
+}
+
+//
+// Outline-Gruppen erzeugen oder loeschen
+//
+
+ScUndoMakeOutline::ScUndoMakeOutline( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScOutlineTable* pNewUndoTab, BOOL bNewColumns, BOOL bNewMake ) :
+ ScSimpleUndo( pNewDocShell ),
+ aBlockStart( nStartX, nStartY, nStartZ ),
+ aBlockEnd( nEndX, nEndY, nEndZ ),
+ pUndoTable( pNewUndoTab ),
+ bColumns( bNewColumns ),
+ bMake( bNewMake )
+{
+}
+
+__EXPORT ScUndoMakeOutline::~ScUndoMakeOutline()
+{
+ delete pUndoTable;
+}
+
+String __EXPORT ScUndoMakeOutline::GetComment() const
+{ // "Gruppierung" "Gruppierung aufheben"
+ return bMake ?
+ ScGlobal::GetRscString( STR_UNDO_MAKEOUTLINE ) :
+ ScGlobal::GetRscString( STR_UNDO_REMAKEOUTLINE );
+}
+
+void __EXPORT ScUndoMakeOutline::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SCTAB nTab = aBlockStart.Tab();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart, aBlockEnd );
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoMakeOutline::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart, aBlockEnd );
+
+ if (bMake)
+ pViewShell->MakeOutline( bColumns, FALSE );
+ else
+ pViewShell->RemoveOutline( bColumns, FALSE );
+
+ pDocShell->PostPaint(0,0,aBlockStart.Tab(),MAXCOL,MAXROW,aBlockEnd.Tab(),PAINT_GRID);
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoMakeOutline::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+
+ if (bMake)
+ rViewShell.MakeOutline( bColumns, TRUE );
+ else
+ rViewShell.RemoveOutline( bColumns, TRUE );
+ }
+}
+
+BOOL __EXPORT ScUndoMakeOutline::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+//
+// Outline-Ebene auswaehlen
+//
+
+ScUndoOutlineLevel::ScUndoOutlineLevel( ScDocShell* pNewDocShell,
+ SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+ BOOL bNewColumns, USHORT nNewLevel ) :
+ ScSimpleUndo( pNewDocShell ),
+ nStart( nNewStart ),
+ nEnd( nNewEnd ),
+ nTab( nNewTab ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTable( pNewUndoTab ),
+ bColumns( bNewColumns ),
+ nLevel( nNewLevel )
+{
+}
+
+__EXPORT ScUndoOutlineLevel::~ScUndoOutlineLevel()
+{
+ delete pUndoDoc;
+ delete pUndoTable;
+}
+
+String __EXPORT ScUndoOutlineLevel::GetComment() const
+{ // "Gliederungsebene auswaehlen";
+ return ScGlobal::GetRscString( STR_UNDO_OUTLINELEVEL );
+}
+
+void __EXPORT ScUndoOutlineLevel::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // Original Outline-Table
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ // Original Spalten-/Zeilenstatus
+
+ if (bColumns)
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, FALSE, pDoc);
+ else
+ pUndoDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pDoc );
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ pViewShell->UpdateScrollBars();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP);
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoOutlineLevel::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // Tabelle muss vorher umgeschaltet sein (#46952#) !!!
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pViewShell->SelectLevel( bColumns, nLevel, FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoOutlineLevel::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->SelectLevel( bColumns, nLevel, TRUE );
+}
+
+BOOL __EXPORT ScUndoOutlineLevel::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+//
+// Outline ueber Blockmarken ein- oder ausblenden
+//
+
+ScUndoOutlineBlock::ScUndoOutlineBlock( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab, BOOL bNewShow ) :
+ ScSimpleUndo( pNewDocShell ),
+ aBlockStart( nStartX, nStartY, nStartZ ),
+ aBlockEnd( nEndX, nEndY, nEndZ ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTable( pNewUndoTab ),
+ bShow( bNewShow )
+{
+}
+
+__EXPORT ScUndoOutlineBlock::~ScUndoOutlineBlock()
+{
+ delete pUndoDoc;
+ delete pUndoTable;
+}
+
+String __EXPORT ScUndoOutlineBlock::GetComment() const
+{ // "Detail einblenden" "Detail ausblenden"
+ return bShow ?
+ ScGlobal::GetRscString( STR_UNDO_DOOUTLINEBLK ) :
+ ScGlobal::GetRscString( STR_UNDO_REDOOUTLINEBLK );
+}
+
+void __EXPORT ScUndoOutlineBlock::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SCTAB nTab = aBlockStart.Tab();
+
+ // Original Outline-Table
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ // Original Spalten-/Zeilenstatus
+
+ SCCOLROW nStartCol = aBlockStart.Col();
+ SCCOLROW nEndCol = aBlockEnd.Col();
+ SCCOLROW nStartRow = aBlockStart.Row();
+ SCCOLROW nEndRow = aBlockEnd.Row();
+
+ if (!bShow)
+ { // Groesse des ausgeblendeten Blocks
+ USHORT nLevel;
+ pUndoTable->GetColArray()->FindTouchedLevel( nStartCol, nEndCol, nLevel );
+ pUndoTable->GetColArray()->ExtendBlock( nLevel, nStartCol, nEndCol );
+ pUndoTable->GetRowArray()->FindTouchedLevel( nStartRow, nEndRow, nLevel );
+ pUndoTable->GetRowArray()->ExtendBlock( nLevel, nStartRow, nEndRow );
+ }
+
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
+ static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, FALSE, pDoc );
+ pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pDoc );
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ pViewShell->UpdateScrollBars();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP);
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoOutlineBlock::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart, aBlockEnd );
+ if (bShow)
+ pViewShell->ShowMarkedOutlines( FALSE );
+ else
+ pViewShell->HideMarkedOutlines( FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoOutlineBlock::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+
+ if (bShow)
+ rViewShell.ShowMarkedOutlines( TRUE );
+ else
+ rViewShell.HideMarkedOutlines( TRUE );
+ }
+}
+
+BOOL __EXPORT ScUndoOutlineBlock::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+//
+// alle Outlines loeschen
+//
+
+ScUndoRemoveAllOutlines::ScUndoRemoveAllOutlines( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab ) :
+ ScSimpleUndo( pNewDocShell ),
+ aBlockStart( nStartX, nStartY, nStartZ ),
+ aBlockEnd( nEndX, nEndY, nEndZ ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTable( pNewUndoTab )
+{
+}
+
+__EXPORT ScUndoRemoveAllOutlines::~ScUndoRemoveAllOutlines()
+{
+ delete pUndoDoc;
+ delete pUndoTable;
+}
+
+String __EXPORT ScUndoRemoveAllOutlines::GetComment() const
+{ // "Gliederung entfernen"
+ return ScGlobal::GetRscString( STR_UNDO_REMOVEALLOTLNS );
+}
+
+void __EXPORT ScUndoRemoveAllOutlines::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SCTAB nTab = aBlockStart.Tab();
+
+ // Original Outline-Table
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ // Original Spalten-/Zeilenstatus
+
+ SCCOL nStartCol = aBlockStart.Col();
+ SCCOL nEndCol = aBlockEnd.Col();
+ SCROW nStartRow = aBlockStart.Row();
+ SCROW nEndRow = aBlockEnd.Row();
+
+ pUndoDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, FALSE, pDoc );
+ pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pDoc );
+
+ pDoc->UpdatePageBreaks( nTab );
+
+ pViewShell->UpdateScrollBars();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoRemoveAllOutlines::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // Tabelle muss vorher umgeschaltet sein (#46952#) !!!
+
+ SCTAB nTab = aBlockStart.Tab();
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pViewShell->RemoveAllOutlines( FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoRemoveAllOutlines::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->RemoveAllOutlines( TRUE );
+}
+
+BOOL __EXPORT ScUndoRemoveAllOutlines::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+//
+// Auto-Outline
+//
+
+ScUndoAutoOutline::ScUndoAutoOutline( ScDocShell* pNewDocShell,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab ) :
+ ScSimpleUndo( pNewDocShell ),
+ aBlockStart( nStartX, nStartY, nStartZ ),
+ aBlockEnd( nEndX, nEndY, nEndZ ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTable( pNewUndoTab )
+{
+}
+
+__EXPORT ScUndoAutoOutline::~ScUndoAutoOutline()
+{
+ delete pUndoDoc;
+ delete pUndoTable;
+}
+
+String __EXPORT ScUndoAutoOutline::GetComment() const
+{ // "Auto-Gliederung"
+ return ScGlobal::GetRscString( STR_UNDO_AUTOOUTLINE );
+}
+
+void __EXPORT ScUndoAutoOutline::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SCTAB nTab = aBlockStart.Tab();
+
+ // Original Outline-Table
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ // Original Spalten-/Zeilenstatus
+
+ if (pUndoDoc && pUndoTable)
+ {
+ SCCOLROW nStartCol;
+ SCCOLROW nStartRow;
+ SCCOLROW nEndCol;
+ SCCOLROW nEndRow;
+ pUndoTable->GetColArray()->GetRange( nStartCol, nEndCol );
+ pUndoTable->GetRowArray()->GetRange( nStartRow, nEndRow );
+
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
+ static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, FALSE,
+ pDoc);
+ pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pDoc );
+
+ pViewShell->UpdateScrollBars();
+ }
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoAutoOutline::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCTAB nTab = aBlockStart.Tab();
+ if (pViewShell)
+ {
+ // Tabelle muss vorher umgeschaltet sein (#46952#) !!!
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+ }
+
+ ScRange aRange( aBlockStart.Col(), aBlockStart.Row(), nTab,
+ aBlockEnd.Col(), aBlockEnd.Row(), nTab );
+ ScOutlineDocFunc aFunc( *pDocShell );
+ aFunc.AutoOutline( aRange, FALSE, FALSE );
+
+ // auf der View markieren
+ // Wenn's beim Aufruf eine Mehrfachselektion war, ist es jetzt der
+ // umschliessende Bereich...
+
+ if (pViewShell)
+ pViewShell->MarkRange( aRange );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoAutoOutline::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->AutoOutline( TRUE );
+}
+
+BOOL __EXPORT ScUndoAutoOutline::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+//
+// Zwischenergebnisse
+//
+
+ScUndoSubTotals::ScUndoSubTotals( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ const ScSubTotalParam& rNewParam, SCROW nNewEndY,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+ ScRangeName* pNewUndoRange, ScDBCollection* pNewUndoDB ) :
+ ScDBFuncUndo( pNewDocShell, ScRange( rNewParam.nCol1, rNewParam.nRow1, nNewTab,
+ rNewParam.nCol2, rNewParam.nRow2, nNewTab ) ),
+ nTab( nNewTab ),
+ aParam( rNewParam ),
+ nNewEndRow( nNewEndY ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTable( pNewUndoTab ),
+ pUndoRange( pNewUndoRange ),
+ pUndoDB( pNewUndoDB )
+{
+}
+
+__EXPORT ScUndoSubTotals::~ScUndoSubTotals()
+{
+ delete pUndoDoc;
+ delete pUndoTable;
+ delete pUndoRange;
+ delete pUndoDB;
+}
+
+String __EXPORT ScUndoSubTotals::GetComment() const
+{ // "Teilergebnisse"
+ return ScGlobal::GetRscString( STR_UNDO_SUBTOTALS );
+}
+
+void __EXPORT ScUndoSubTotals::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ // um einzelnen DB-Bereich anzupassen
+/* ScDBData* pOldDBData = ScUndoUtil::GetOldDBData( pUndoDBData, pDoc, nTab,
+ aParam.nCol1, aParam.nRow1, aParam.nCol2, nNewEndRow );
+*/
+
+ if (nNewEndRow > aParam.nRow2)
+ {
+ pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, aParam.nRow2+1, static_cast<SCSIZE>(nNewEndRow-aParam.nRow2) );
+ }
+ else if (nNewEndRow < aParam.nRow2)
+ {
+ pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nNewEndRow+1, static_cast<SCSIZE>(aParam.nRow2-nNewEndRow) );
+ }
+
+
+ // Original Outline-Table
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ // Original Spalten-/Zeilenstatus
+
+ if (pUndoDoc && pUndoTable)
+ {
+ SCCOLROW nStartCol;
+ SCCOLROW nStartRow;
+ SCCOLROW nEndCol;
+ SCCOLROW nEndRow;
+ pUndoTable->GetColArray()->GetRange( nStartCol, nEndCol );
+ pUndoTable->GetRowArray()->GetRange( nStartRow, nEndRow );
+
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
+ static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, FALSE,
+ pDoc);
+ pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pDoc );
+
+ pViewShell->UpdateScrollBars();
+ }
+
+ // Original-Daten & Referenzen
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, 0, aParam.nRow1+1, nTab,
+ MAXCOL, aParam.nRow2, nTab );
+
+ pDoc->DeleteAreaTab( 0,aParam.nRow1+1, MAXCOL,aParam.nRow2, nTab, IDF_ALL );
+
+ pUndoDoc->CopyToDocument( 0, aParam.nRow1+1, nTab, MAXCOL, aParam.nRow2, nTab,
+ IDF_NONE, FALSE, pDoc ); // Flags
+ pUndoDoc->UndoToDocument( 0, aParam.nRow1+1, nTab, MAXCOL, aParam.nRow2, nTab,
+ IDF_ALL, FALSE, pDoc );
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aParam.nCol1,aParam.nRow1,nTab,
+ aParam.nCol2,aParam.nRow2,nTab );
+
+/* if (pUndoDBData)
+ *pOldDBData = *pUndoDBData;
+*/
+ if (pUndoRange)
+ pDoc->SetRangeName( new ScRangeName( *pUndoRange ) );
+ if (pUndoDB)
+ pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE );
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
+ pDocShell->PostDataChanged();
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoSubTotals::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aParam.nCol1,aParam.nRow1,nTab,
+ aParam.nCol2,aParam.nRow2,nTab );
+ pViewShell->DoSubTotals( aParam, FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoSubTotals::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoSubTotals::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // geht nicht wegen Spaltennummern
+}
+
+//
+// Sortieren
+//
+
+ScUndoSort::ScUndoSort( ScDocShell* pNewDocShell,
+ SCTAB nNewTab, const ScSortParam& rParam,
+ BOOL bQuery, ScDocument* pNewUndoDoc, ScDBCollection* pNewUndoDB,
+ const ScRange* pDest ) :
+ ScDBFuncUndo( pNewDocShell, ScRange( rParam.nCol1, rParam.nRow1, nNewTab,
+ rParam.nCol2, rParam.nRow2, nNewTab ) ),
+ nTab( nNewTab ),
+ aSortParam( rParam ),
+ bRepeatQuery( bQuery ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoDB( pNewUndoDB ),
+ bDestArea( FALSE )
+{
+ if ( pDest )
+ {
+ bDestArea = TRUE;
+ aDestRange = *pDest;
+ }
+}
+
+__EXPORT ScUndoSort::~ScUndoSort()
+{
+ delete pUndoDoc;
+ delete pUndoDB;
+}
+
+String __EXPORT ScUndoSort::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_SORT );
+}
+
+void __EXPORT ScUndoSort::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCCOL nStartCol = aSortParam.nCol1;
+ SCROW nStartRow = aSortParam.nRow1;
+ SCCOL nEndCol = aSortParam.nCol2;
+ SCROW nEndRow = aSortParam.nRow2;
+ SCTAB nSortTab = nTab;
+ if ( !aSortParam.bInplace )
+ {
+ nStartCol = aSortParam.nDestCol;
+ nStartRow = aSortParam.nDestRow;
+ nEndCol = nStartCol + ( aSortParam.nCol2 - aSortParam.nCol1 );
+ nEndRow = nStartRow + ( aSortParam.nRow2 - aSortParam.nRow1 );
+ nSortTab = aSortParam.nDestTab;
+ }
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, nStartCol, nStartRow, nSortTab,
+ nEndCol, nEndRow, nSortTab );
+
+ // do not delete/copy note captions, they are handled in drawing undo (ScDBFuncUndo::mpDrawUndo)
+ pDoc->DeleteAreaTab( nStartCol,nStartRow, nEndCol,nEndRow, nSortTab, IDF_ALL|IDF_NOCAPTIONS );
+ pUndoDoc->CopyToDocument( nStartCol, nStartRow, nSortTab, nEndCol, nEndRow, nSortTab,
+ IDF_ALL|IDF_NOCAPTIONS, FALSE, pDoc );
+
+ if (bDestArea)
+ {
+ // do not delete/copy note captions, they are handled in drawing undo (ScDBFuncUndo::mpDrawUndo)
+ pDoc->DeleteAreaTab( aDestRange, IDF_ALL|IDF_NOCAPTIONS );
+ pUndoDoc->CopyToDocument( aDestRange, IDF_ALL|IDF_NOCAPTIONS, FALSE, pDoc );
+ }
+
+ // Zeilenhoehen immer (wegen automatischer Anpassung)
+ //! auf ScBlockUndo umstellen
+// if (bRepeatQuery)
+ pUndoDoc->CopyToDocument( 0, nStartRow, nSortTab, MAXCOL, nEndRow, nSortTab,
+ IDF_NONE, FALSE, pDoc );
+
+ if (pUndoDB)
+ pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE );
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nSortTab )
+ pViewShell->SetTabNo( nSortTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
+ pDocShell->PostDataChanged();
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoSort::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+// pViewShell->DoneBlockMode();
+// pViewShell->InitOwnBlockMode();
+// pViewShell->GetViewData()->GetMarkData() = aMarkData; // CopyMarksTo
+
+ pViewShell->MarkRange( ScRange( aSortParam.nCol1, aSortParam.nRow1, nTab,
+ aSortParam.nCol2, aSortParam.nRow2, nTab ) );
+
+ pViewShell->Sort( aSortParam, FALSE );
+
+ // Quellbereich painten wegen Markierung
+ if ( !aSortParam.bInplace )
+ pDocShell->PostPaint( aSortParam.nCol1, aSortParam.nRow1, nTab,
+ aSortParam.nCol2, aSortParam.nRow2, nTab, PAINT_GRID );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoSort::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoSort::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // geht nicht wegen Spaltennummern
+}
+
+//
+// Filtern
+//
+
+ScUndoQuery::ScUndoQuery( ScDocShell* pNewDocShell, SCTAB nNewTab, const ScQueryParam& rParam,
+ ScDocument* pNewUndoDoc, ScDBCollection* pNewUndoDB,
+ const ScRange* pOld, BOOL bSize, const ScRange* pAdvSrc ) :
+ ScDBFuncUndo( pNewDocShell, ScRange( rParam.nCol1, rParam.nRow1, nNewTab,
+ rParam.nCol2, rParam.nRow2, nNewTab ) ),
+ pDrawUndo( NULL ),
+ nTab( nNewTab ),
+ aQueryParam( rParam ),
+ pUndoDoc( pNewUndoDoc ),
+// pUndoDBData( pNewData )
+ pUndoDB( pNewUndoDB ),
+ bIsAdvanced( FALSE ),
+ bDestArea( FALSE ),
+ bDoSize( bSize )
+{
+ if ( pOld )
+ {
+ bDestArea = TRUE;
+ aOldDest = *pOld;
+ }
+ if ( pAdvSrc )
+ {
+ bIsAdvanced = TRUE;
+ aAdvSource = *pAdvSrc;
+ }
+
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+}
+
+__EXPORT ScUndoQuery::~ScUndoQuery()
+{
+ delete pUndoDoc;
+// delete pUndoDBData;
+ delete pUndoDB;
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String __EXPORT ScUndoQuery::GetComment() const
+{ // "Filtern";
+ return ScGlobal::GetRscString( STR_UNDO_QUERY );
+}
+
+void __EXPORT ScUndoQuery::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ BOOL bCopy = !aQueryParam.bInplace;
+ SCCOL nDestEndCol = 0;
+ SCROW nDestEndRow = 0;
+ if (bCopy)
+ {
+ nDestEndCol = aQueryParam.nDestCol + ( aQueryParam.nCol2-aQueryParam.nCol1 );
+ nDestEndRow = aQueryParam.nDestRow + ( aQueryParam.nRow2-aQueryParam.nRow1 );
+
+ ScDBData* pData = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, TRUE );
+ if (pData)
+ {
+ ScRange aNewDest;
+ pData->GetArea( aNewDest );
+ nDestEndCol = aNewDest.aEnd.Col();
+ nDestEndRow = aNewDest.aEnd.Row();
+ }
+
+ if ( bDoSize && bDestArea )
+ {
+ // aDestRange ist der alte Bereich
+ pDoc->FitBlock( ScRange(
+ aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
+ nDestEndCol, nDestEndRow, aQueryParam.nDestTab ),
+ aOldDest );
+ }
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell,
+ aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
+ nDestEndCol, nDestEndRow, aQueryParam.nDestTab );
+ pDoc->DeleteAreaTab( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ nDestEndCol, nDestEndRow, aQueryParam.nDestTab, IDF_ALL );
+
+ pViewShell->DoneBlockMode();
+
+ pUndoDoc->CopyToDocument( aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
+ nDestEndCol, nDestEndRow, aQueryParam.nDestTab,
+ IDF_ALL, FALSE, pDoc );
+ // Attribute werden immer mitkopiert (#49287#)
+
+ // Rest von altem Bereich
+ if ( bDestArea && !bDoSize )
+ {
+ pDoc->DeleteAreaTab( aOldDest, IDF_ALL );
+ pUndoDoc->CopyToDocument( aOldDest, IDF_ALL, FALSE, pDoc );
+ }
+ }
+ else
+ pUndoDoc->CopyToDocument( 0, aQueryParam.nRow1, nTab, MAXCOL, aQueryParam.nRow2, nTab,
+ IDF_NONE, FALSE, pDoc );
+
+ if (pUndoDB)
+ pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE );
+
+ if (!bCopy)
+ {
+ pDoc->InvalidatePageBreaks(nTab);
+ pDoc->UpdatePageBreaks( nTab );
+ }
+
+ ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab,
+ MAXCOL, aQueryParam.nRow2, nTab );
+ pDoc->SetDirty( aDirtyRange );
+
+ DoSdrUndoAction( pDrawUndo, pDoc );
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ // Paint
+
+ if (bCopy)
+ {
+ SCCOL nEndX = nDestEndCol;
+ SCROW nEndY = nDestEndRow;
+ if (bDestArea)
+ {
+ if ( aOldDest.aEnd.Col() > nEndX )
+ nEndX = aOldDest.aEnd.Col();
+ if ( aOldDest.aEnd.Row() > nEndY )
+ nEndY = aOldDest.aEnd.Row();
+ }
+ if (bDoSize)
+ nEndY = MAXROW;
+ pDocShell->PostPaint( aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
+ nEndX, nEndY, aQueryParam.nDestTab, PAINT_GRID );
+ }
+ else
+ pDocShell->PostPaint( 0, aQueryParam.nRow1, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+ pDocShell->PostDataChanged();
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoQuery::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ if ( bIsAdvanced )
+ pViewShell->Query( aQueryParam, &aAdvSource, FALSE );
+ else
+ pViewShell->Query( aQueryParam, NULL, FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoQuery::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoQuery::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // geht nicht wegen Spaltennummern
+}
+
+//
+// Show or hide AutoFilter buttons (doesn't include filter settings)
+//
+
+ScUndoAutoFilter::ScUndoAutoFilter( ScDocShell* pNewDocShell, const ScRange& rRange,
+ const String& rName, BOOL bSet ) :
+ ScDBFuncUndo( pNewDocShell, rRange ),
+ aDBName( rName ),
+ bFilterSet( bSet )
+{
+}
+
+ScUndoAutoFilter::~ScUndoAutoFilter()
+{
+}
+
+String ScUndoAutoFilter::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_QUERY ); // same as ScUndoQuery
+}
+
+void ScUndoAutoFilter::DoChange( BOOL bUndo )
+{
+ BOOL bNewFilter = bUndo ? !bFilterSet : bFilterSet;
+
+ USHORT nIndex;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ if ( pColl->SearchName( aDBName, nIndex ) )
+ {
+ ScDBData* pDBData = (*pColl)[nIndex];
+ pDBData->SetAutoFilter( bNewFilter );
+
+ SCCOL nRangeX1;
+ SCROW nRangeY1;
+ SCCOL nRangeX2;
+ SCROW nRangeY2;
+ SCTAB nRangeTab;
+ pDBData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
+
+ if ( bNewFilter )
+ pDoc->ApplyFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, SC_MF_AUTO );
+ else
+ pDoc->RemoveFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, SC_MF_AUTO );
+
+ pDocShell->PostPaint( nRangeX1, nRangeY1, nRangeTab, nRangeX2, nRangeY1, nRangeTab, PAINT_GRID );
+ }
+}
+
+void ScUndoAutoFilter::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+void ScUndoAutoFilter::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+}
+
+void ScUndoAutoFilter::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL ScUndoAutoFilter::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+//
+// Datenbankbereiche aendern (Dialog)
+//
+
+ScUndoDBData::ScUndoDBData( ScDocShell* pNewDocShell,
+ ScDBCollection* pNewUndoColl, ScDBCollection* pNewRedoColl ) :
+ ScSimpleUndo( pNewDocShell ),
+ pUndoColl( pNewUndoColl ),
+ pRedoColl( pNewRedoColl )
+{
+}
+
+__EXPORT ScUndoDBData::~ScUndoDBData()
+{
+ delete pUndoColl;
+ delete pRedoColl;
+}
+
+String __EXPORT ScUndoDBData::GetComment() const
+{ // "Datenbankbereiche aendern";
+ return ScGlobal::GetRscString( STR_UNDO_DBDATA );
+}
+
+void __EXPORT ScUndoDBData::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ BOOL bOldAutoCalc = pDoc->GetAutoCalc();
+ pDoc->SetAutoCalc( FALSE ); // unnoetige Berechnungen vermeiden
+ pDoc->CompileDBFormula( TRUE ); // CreateFormulaString
+ pDoc->SetDBCollection( new ScDBCollection(*pUndoColl), TRUE );
+ pDoc->CompileDBFormula( FALSE ); // CompileFormulaString
+ pDoc->SetAutoCalc( bOldAutoCalc );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoDBData::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ BOOL bOldAutoCalc = pDoc->GetAutoCalc();
+ pDoc->SetAutoCalc( FALSE ); // unnoetige Berechnungen vermeiden
+ pDoc->CompileDBFormula( TRUE ); // CreateFormulaString
+ pDoc->SetDBCollection( new ScDBCollection(*pRedoColl), TRUE );
+ pDoc->CompileDBFormula( FALSE ); // CompileFormulaString
+ pDoc->SetAutoCalc( bOldAutoCalc );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoDBData::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoDBData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // geht nicht
+}
+
+//
+// Import
+//
+
+ScUndoImportData::ScUndoImportData( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ const ScImportParam& rParam, SCCOL nNewEndX, SCROW nNewEndY,
+ SCCOL nNewFormula,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
+ ScDBData* pNewUndoData, ScDBData* pNewRedoData ) :
+ ScSimpleUndo( pNewDocShell ),
+ nTab( nNewTab ),
+ aImportParam( rParam ),
+ nEndCol( nNewEndX ),
+ nEndRow( nNewEndY ),
+ pUndoDoc( pNewUndoDoc ),
+ pRedoDoc( pNewRedoDoc ),
+ pUndoDBData( pNewUndoData ),
+ pRedoDBData( pNewRedoData ),
+ nFormulaCols( nNewFormula ),
+ bRedoFilled( FALSE )
+{
+ // redo doc doesn't contain imported data (but everything else)
+}
+
+__EXPORT ScUndoImportData::~ScUndoImportData()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+ delete pUndoDBData;
+ delete pRedoDBData;
+}
+
+String __EXPORT ScUndoImportData::GetComment() const
+{ // "Importieren";
+ return ScGlobal::GetRscString( STR_UNDO_IMPORTDATA );
+}
+
+void __EXPORT ScUndoImportData::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
+ nEndCol,nEndRow,nTab );
+
+ SCTAB nTable;
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ ScDBData* pCurrentData = NULL;
+ if (pUndoDBData && pRedoDBData)
+ {
+ pRedoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
+ pCurrentData = ScUndoUtil::GetOldDBData( pRedoDBData, pDoc, nTab,
+ nCol1, nRow1, nCol2, nRow2 );
+
+ if ( !bRedoFilled )
+ {
+ // read redo data from document at first undo
+ // imported data is deleted later anyway,
+ // so now delete each column after copying to save memory (#41216#)
+
+ BOOL bOldAutoCalc = pDoc->GetAutoCalc();
+ pDoc->SetAutoCalc( FALSE ); // outside of the loop
+ for (SCCOL nCopyCol = nCol1; nCopyCol <= nCol2; nCopyCol++)
+ {
+ pDoc->CopyToDocument( nCopyCol,nRow1,nTab, nCopyCol,nRow2,nTab,
+ IDF_CONTENTS & ~IDF_NOTE, FALSE, pRedoDoc );
+ pDoc->DeleteAreaTab( nCopyCol,nRow1, nCopyCol,nRow2, nTab, IDF_CONTENTS & ~IDF_NOTE );
+ pDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 );
+ }
+ pDoc->SetAutoCalc( bOldAutoCalc );
+ bRedoFilled = TRUE;
+ }
+ }
+ BOOL bMoveCells = pUndoDBData && pRedoDBData &&
+ pRedoDBData->IsDoSize(); // in alt und neu gleich
+ if (bMoveCells)
+ {
+ // Undo: erst die neuen Daten loeschen, dann FitBlock rueckwaerts
+
+ ScRange aOld, aNew;
+ pUndoDBData->GetArea( aOld );
+ pRedoDBData->GetArea( aNew );
+
+ pDoc->DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
+ aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, IDF_ALL & ~IDF_NOTE );
+
+ aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols ); // FitBlock auch fuer Formeln
+ aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
+ pDoc->FitBlock( aNew, aOld, FALSE ); // rueckwaerts
+ }
+ else
+ pDoc->DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
+ nEndCol,nEndRow, nTab, IDF_ALL & ~IDF_NOTE );
+
+ pUndoDoc->CopyToDocument( aImportParam.nCol1,aImportParam.nRow1,nTab,
+ nEndCol+nFormulaCols,nEndRow,nTab,
+ IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+
+ if (pCurrentData)
+ {
+ *pCurrentData = *pUndoDBData;
+
+ pUndoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
+ ScUndoUtil::MarkSimpleBlock( pDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
+ }
+
+// erack! it's broadcasted
+// pDoc->SetDirty();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ if (bMoveCells)
+ pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+ else
+ pDocShell->PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
+ nEndCol,nEndRow,nTab, PAINT_GRID );
+ pDocShell->PostDataChanged();
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoImportData::Redo()
+{
+ BeginRedo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
+ nEndCol,nEndRow,nTab );
+
+ SCTAB nTable;
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ ScDBData* pCurrentData = NULL;
+ if (pUndoDBData && pRedoDBData)
+ {
+ pUndoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
+ pCurrentData = ScUndoUtil::GetOldDBData( pUndoDBData, pDoc, nTab,
+ nCol1, nRow1, nCol2, nRow2 );
+ }
+ BOOL bMoveCells = pUndoDBData && pRedoDBData &&
+ pRedoDBData->IsDoSize(); // in alt und neu gleich
+ if (bMoveCells)
+ {
+ // Redo: FitBlock, dann Daten loeschen (noetig fuer CopyToDocument)
+
+ ScRange aOld, aNew;
+ pUndoDBData->GetArea( aOld );
+ pRedoDBData->GetArea( aNew );
+
+ aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols ); // FitBlock auch fuer Formeln
+ aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
+ pDoc->FitBlock( aOld, aNew );
+
+ pDoc->DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
+ aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, IDF_ALL & ~IDF_NOTE );
+
+ pRedoDoc->CopyToDocument( aNew, IDF_ALL & ~IDF_NOTE, FALSE, pDoc ); // incl. Formeln
+ }
+ else
+ {
+ pDoc->DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
+ nEndCol,nEndRow, nTab, IDF_ALL & ~IDF_NOTE );
+ pRedoDoc->CopyToDocument( aImportParam.nCol1,aImportParam.nRow1,nTab,
+ nEndCol,nEndRow,nTab, IDF_ALL & ~IDF_NOTE, FALSE, pDoc );
+ }
+
+ if (pCurrentData)
+ {
+ *pCurrentData = *pRedoDBData;
+
+ pRedoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
+ ScUndoUtil::MarkSimpleBlock( pDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
+ }
+
+// erack! it's broadcasted
+// pDoc->SetDirty();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ if (bMoveCells)
+ pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+ else
+ pDocShell->PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
+ nEndCol,nEndRow,nTab, PAINT_GRID );
+ pDocShell->PostDataChanged();
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoImportData::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
+
+ SCTAB nDummy;
+ ScImportParam aNewParam(aImportParam);
+ ScDBData* pDBData = rViewShell.GetDBData();
+ pDBData->GetArea( nDummy, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+
+ rViewShell.ImportData( aNewParam );
+ }
+}
+
+BOOL __EXPORT ScUndoImportData::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ // Repeat nur fuer Import per DB-Bereich, dann ist pUndoDBData gesetzt
+
+ if (pUndoDBData)
+ return (rTarget.ISA(ScTabViewTarget));
+ else
+ return FALSE; // Adressbuch
+}
+
+//
+// Operationen wiederholen
+//
+
+ScUndoRepeatDB::ScUndoRepeatDB( ScDocShell* pNewDocShell, SCTAB nNewTab,
+ SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
+ SCROW nResultEndRow, SCCOL nCurX, SCROW nCurY,
+ ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
+ ScRangeName* pNewUndoRange, ScDBCollection* pNewUndoDB,
+ const ScRange* pOldQ, const ScRange* pNewQ ) :
+ ScSimpleUndo( pNewDocShell ),
+ aBlockStart( nStartX,nStartY,nNewTab ),
+ aBlockEnd( nEndX,nEndY,nNewTab ),
+ nNewEndRow( nResultEndRow ),
+ aCursorPos( nCurX,nCurY,nNewTab ),
+ pUndoDoc( pNewUndoDoc ),
+ pUndoTable( pNewUndoTab ),
+ pUndoRange( pNewUndoRange ),
+ pUndoDB( pNewUndoDB ),
+ bQuerySize( FALSE )
+{
+ if ( pOldQ && pNewQ )
+ {
+ aOldQuery = *pOldQ;
+ aNewQuery = *pNewQ;
+ bQuerySize = TRUE;;
+ }
+}
+
+__EXPORT ScUndoRepeatDB::~ScUndoRepeatDB()
+{
+ delete pUndoDoc;
+ delete pUndoTable;
+ delete pUndoRange;
+ delete pUndoDB;
+}
+
+String __EXPORT ScUndoRepeatDB::GetComment() const
+{ // "Wiederholen"; //! bessere Beschreibung!
+ return ScGlobal::GetRscString( STR_UNDO_REPEATDB );
+}
+
+void __EXPORT ScUndoRepeatDB::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SCTAB nTab = aBlockStart.Tab();
+
+ if (bQuerySize)
+ {
+ pDoc->FitBlock( aNewQuery, aOldQuery, FALSE );
+
+ if ( aNewQuery.aEnd.Col() == aOldQuery.aEnd.Col() )
+ {
+ SCCOL nFormulaCols = 0;
+ SCCOL nCol = aOldQuery.aEnd.Col() + 1;
+ SCROW nRow = aOldQuery.aStart.Row() + 1; //! Header testen
+ while ( nCol <= MAXCOL &&
+ pDoc->GetCellType(ScAddress( nCol, nRow, nTab )) == CELLTYPE_FORMULA )
+ ++nCol, ++nFormulaCols;
+
+ if ( nFormulaCols > 0 )
+ {
+ ScRange aOldForm = aOldQuery;
+ aOldForm.aStart.SetCol( aOldQuery.aEnd.Col() + 1 );
+ aOldForm.aEnd.SetCol( aOldQuery.aEnd.Col() + nFormulaCols );
+ ScRange aNewForm = aOldForm;
+ aNewForm.aEnd.SetRow( aNewQuery.aEnd.Row() );
+ pDoc->FitBlock( aNewForm, aOldForm, FALSE );
+ }
+ }
+ }
+
+ //! Daten von Filter in anderen Bereich fehlen noch !!!!!!!!!!!!!!!!!
+
+ if (nNewEndRow > aBlockEnd.Row())
+ {
+ pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, aBlockEnd.Row()+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
+ }
+ else if (nNewEndRow < aBlockEnd.Row())
+ {
+ pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nNewEndRow+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
+ }
+
+ // Original Outline-Table
+
+ pDoc->SetOutlineTable( nTab, pUndoTable );
+
+ // Original Spalten-/Zeilenstatus
+
+ if (pUndoDoc && pUndoTable)
+ {
+ SCCOLROW nStartCol;
+ SCCOLROW nStartRow;
+ SCCOLROW nEndCol;
+ SCCOLROW nEndRow;
+ pUndoTable->GetColArray()->GetRange( nStartCol, nEndCol );
+ pUndoTable->GetRowArray()->GetRange( nStartRow, nEndRow );
+
+ pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
+ static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, FALSE,
+ pDoc );
+ pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pDoc );
+
+ pViewShell->UpdateScrollBars();
+ }
+
+ // Original-Daten & Referenzen
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, 0, aBlockStart.Row(), nTab,
+ MAXCOL, aBlockEnd.Row(), nTab );
+ pDoc->DeleteAreaTab( 0, aBlockStart.Row(),
+ MAXCOL, aBlockEnd.Row(), nTab, IDF_ALL );
+
+ pUndoDoc->CopyToDocument( 0, aBlockStart.Row(), nTab, MAXCOL, aBlockEnd.Row(), nTab,
+ IDF_NONE, FALSE, pDoc ); // Flags
+ pUndoDoc->UndoToDocument( 0, aBlockStart.Row(), nTab, MAXCOL, aBlockEnd.Row(), nTab,
+ IDF_ALL, FALSE, pDoc );
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
+ aBlockEnd.Col(),aBlockEnd.Row(),nTab );
+
+ if (pUndoRange)
+ pDoc->SetRangeName( new ScRangeName( *pUndoRange ) );
+ if (pUndoDB)
+ pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE );
+
+// erack! it's broadcasted
+// pDoc->SetDirty();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
+ pDocShell->PostDataChanged();
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoRepeatDB::Redo()
+{
+ BeginRedo();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SCTAB nTab = aBlockStart.Tab();
+
+ SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nVisTab != nTab )
+ pViewShell->SetTabNo( nTab );
+
+ ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
+ aBlockEnd.Col(),aBlockEnd.Row(),nTab );
+ pViewShell->SetCursor( aCursorPos.Col(), aCursorPos.Row() );
+
+ pViewShell->RepeatDB( FALSE );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoRepeatDB::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->RepeatDB( TRUE );
+}
+
+BOOL __EXPORT ScUndoRepeatDB::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+//UNUSED2008-05 //
+//UNUSED2008-05 // Pivot-Tabellen
+//UNUSED2008-05 //
+//UNUSED2008-05
+//UNUSED2008-05 ScUndoPivot::ScUndoPivot( ScDocShell* pNewDocShell,
+//UNUSED2008-05 const ScArea& rOld, const ScArea& rNew,
+//UNUSED2008-05 ScDocument* pOldDoc, ScDocument* pNewDoc,
+//UNUSED2008-05 const ScPivot* pOldPivot, const ScPivot* pNewPivot ) :
+//UNUSED2008-05 ScSimpleUndo( pNewDocShell ),
+//UNUSED2008-05 aOldArea( rOld ),
+//UNUSED2008-05 aNewArea( rNew ),
+//UNUSED2008-05 pOldUndoDoc( pOldDoc ),
+//UNUSED2008-05 pNewUndoDoc( pNewDoc )
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pNewPivot)
+//UNUSED2008-05 {
+//UNUSED2008-05 pNewPivot->GetParam( aNewParam, aNewQuery, aNewSrc );
+//UNUSED2008-05 aNewName = pNewPivot->GetName();
+//UNUSED2008-05 aNewTag = pNewPivot->GetTag();
+//UNUSED2008-05 }
+//UNUSED2008-05 if (pOldPivot)
+//UNUSED2008-05 {
+//UNUSED2008-05 pOldPivot->GetParam( aOldParam, aOldQuery, aOldSrc );
+//UNUSED2008-05 aOldName = pOldPivot->GetName();
+//UNUSED2008-05 aOldTag = pOldPivot->GetTag();
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 __EXPORT ScUndoPivot::~ScUndoPivot()
+//UNUSED2008-05 {
+//UNUSED2008-05 delete pOldUndoDoc;
+//UNUSED2008-05 delete pNewUndoDoc;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 String __EXPORT ScUndoPivot::GetComment() const
+//UNUSED2008-05 {
+//UNUSED2008-05 USHORT nIndex;
+//UNUSED2008-05 if ( pOldUndoDoc && pNewUndoDoc )
+//UNUSED2008-05 nIndex = STR_UNDO_PIVOT_MODIFY;
+//UNUSED2008-05 else if ( pNewUndoDoc )
+//UNUSED2008-05 nIndex = STR_UNDO_PIVOT_NEW;
+//UNUSED2008-05 else
+//UNUSED2008-05 nIndex = STR_UNDO_PIVOT_DELETE;
+//UNUSED2008-05
+//UNUSED2008-05 return ScGlobal::GetRscString( nIndex );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void __EXPORT ScUndoPivot::Undo()
+//UNUSED2008-05 {
+//UNUSED2008-05 BeginUndo();
+//UNUSED2008-05
+//UNUSED2008-05 ScDocument* pDoc = pDocShell->GetDocument();
+//UNUSED2008-05
+//UNUSED2008-05 if (pNewUndoDoc)
+//UNUSED2008-05 {
+//UNUSED2008-05 pDoc->DeleteAreaTab( aNewArea.nColStart,aNewArea.nRowStart,
+//UNUSED2008-05 aNewArea.nColEnd,aNewArea.nRowEnd, aNewArea.nTab, IDF_ALL );
+//UNUSED2008-05 pNewUndoDoc->CopyToDocument( aNewArea.nColStart, aNewArea.nRowStart, aNewArea.nTab,
+//UNUSED2008-05 aNewArea.nColEnd, aNewArea.nRowEnd, aNewArea.nTab,
+//UNUSED2008-05 IDF_ALL, FALSE, pDoc );
+//UNUSED2008-05 }
+//UNUSED2008-05 if (pOldUndoDoc)
+//UNUSED2008-05 {
+//UNUSED2008-05 pDoc->DeleteAreaTab( aOldArea.nColStart,aOldArea.nRowStart,
+//UNUSED2008-05 aOldArea.nColEnd,aOldArea.nRowEnd, aOldArea.nTab, IDF_ALL );
+//UNUSED2008-05 pOldUndoDoc->CopyToDocument( aOldArea.nColStart, aOldArea.nRowStart, aOldArea.nTab,
+//UNUSED2008-05 aOldArea.nColEnd, aOldArea.nRowEnd, aOldArea.nTab,
+//UNUSED2008-05 IDF_ALL, FALSE, pDoc );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 ScPivotCollection* pPivotCollection = pDoc->GetPivotCollection();
+//UNUSED2008-05 if ( pNewUndoDoc )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScPivot* pNewPivot = pPivotCollection->GetPivotAtCursor(
+//UNUSED2008-05 aNewParam.nCol, aNewParam.nRow, aNewParam.nTab );
+//UNUSED2008-05 if (pNewPivot)
+//UNUSED2008-05 pPivotCollection->Free( pNewPivot );
+//UNUSED2008-05 }
+//UNUSED2008-05 if ( pOldUndoDoc )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScPivot* pOldPivot = new ScPivot( pDoc );
+//UNUSED2008-05 pOldPivot->SetParam( aOldParam, aOldQuery, aOldSrc );
+//UNUSED2008-05 pOldPivot->SetName( aOldName );
+//UNUSED2008-05 pOldPivot->SetTag( aOldTag );
+//UNUSED2008-05 if (pOldPivot->CreateData()) // Felder berechnen
+//UNUSED2008-05 pOldPivot->ReleaseData();
+//UNUSED2008-05 pPivotCollection->Insert( pOldPivot );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 // erack! it's broadcasted
+//UNUSED2008-05 // pDoc->SetDirty();
+//UNUSED2008-05 if (pNewUndoDoc)
+//UNUSED2008-05 pDocShell->PostPaint( aNewArea.nColStart, aNewArea.nRowStart, aNewArea.nTab,
+//UNUSED2008-05 aNewArea.nColEnd, aNewArea.nRowEnd, aNewArea.nTab,
+//UNUSED2008-05 PAINT_GRID, SC_PF_LINES );
+//UNUSED2008-05 if (pOldUndoDoc)
+//UNUSED2008-05 pDocShell->PostPaint( aOldArea.nColStart, aOldArea.nRowStart, aOldArea.nTab,
+//UNUSED2008-05 aOldArea.nColEnd, aOldArea.nRowEnd, aOldArea.nTab,
+//UNUSED2008-05 PAINT_GRID, SC_PF_LINES );
+//UNUSED2008-05 pDocShell->PostDataChanged();
+//UNUSED2008-05
+//UNUSED2008-05 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+//UNUSED2008-05 if (pViewShell)
+//UNUSED2008-05 {
+//UNUSED2008-05 SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
+//UNUSED2008-05 if ( pOldUndoDoc )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( nTab != aOldArea.nTab )
+//UNUSED2008-05 pViewShell->SetTabNo( aOldArea.nTab );
+//UNUSED2008-05 }
+//UNUSED2008-05 else if ( pNewUndoDoc )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( nTab != aNewArea.nTab )
+//UNUSED2008-05 pViewShell->SetTabNo( aNewArea.nTab );
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 EndUndo();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void __EXPORT ScUndoPivot::Redo()
+//UNUSED2008-05 {
+//UNUSED2008-05 BeginRedo();
+//UNUSED2008-05
+//UNUSED2008-05 ScDocument* pDoc = pDocShell->GetDocument();
+//UNUSED2008-05 ScPivotCollection* pPivotCollection = pDoc->GetPivotCollection();
+//UNUSED2008-05 ScPivot* pOldPivot = pPivotCollection->GetPivotAtCursor(
+//UNUSED2008-05 aOldParam.nCol, aOldParam.nRow, aOldParam.nTab );
+//UNUSED2008-05
+//UNUSED2008-05 ScPivot* pNewPivot = NULL;
+//UNUSED2008-05 if (pNewUndoDoc)
+//UNUSED2008-05 {
+//UNUSED2008-05 pNewPivot = new ScPivot( pDoc );
+//UNUSED2008-05 pNewPivot->SetParam( aNewParam, aNewQuery, aNewSrc );
+//UNUSED2008-05 pNewPivot->SetName( aNewName );
+//UNUSED2008-05 pNewPivot->SetTag( aNewTag );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 pDocShell->PivotUpdate( pOldPivot, pNewPivot, FALSE );
+//UNUSED2008-05
+//UNUSED2008-05 EndRedo();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void __EXPORT ScUndoPivot::Repeat(SfxRepeatTarget& rTarget)
+//UNUSED2008-05 {
+//UNUSED2008-05 // Wiederholen: nur loeschen
+//UNUSED2008-05
+//UNUSED2008-05 if ( pOldUndoDoc && !pNewUndoDoc && rTarget.ISA(ScTabViewTarget) )
+//UNUSED2008-05 ((ScTabViewTarget&)rTarget).GetViewShell()->DeletePivotTable();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 BOOL __EXPORT ScUndoPivot::CanRepeat(SfxRepeatTarget& rTarget) const
+//UNUSED2008-05 {
+//UNUSED2008-05 // Wiederholen: nur loeschen
+//UNUSED2008-05
+//UNUSED2008-05 return ( pOldUndoDoc && !pNewUndoDoc && rTarget.ISA(ScTabViewTarget) );
+//UNUSED2008-05 }
+
+//
+// data pilot
+//
+
+ScUndoDataPilot::ScUndoDataPilot( ScDocShell* pNewDocShell,
+ ScDocument* pOldDoc, ScDocument* pNewDoc,
+ const ScDPObject* pOldObj, const ScDPObject* pNewObj, BOOL bMove ) :
+ ScSimpleUndo( pNewDocShell ),
+ pOldUndoDoc( pOldDoc ),
+ pNewUndoDoc( pNewDoc ),
+ pOldDPObject( NULL ),
+ pNewDPObject( NULL ),
+ bAllowMove( bMove )
+{
+ if (pOldObj)
+ pOldDPObject = new ScDPObject( *pOldObj );
+ if (pNewObj)
+ pNewDPObject = new ScDPObject( *pNewObj );
+}
+
+__EXPORT ScUndoDataPilot::~ScUndoDataPilot()
+{
+ delete pOldDPObject;
+ delete pNewDPObject;
+ delete pOldUndoDoc;
+ delete pNewUndoDoc;
+}
+
+String __EXPORT ScUndoDataPilot::GetComment() const
+{
+ USHORT nIndex;
+ if ( pOldUndoDoc && pNewUndoDoc )
+ nIndex = STR_UNDO_PIVOT_MODIFY;
+ else if ( pNewUndoDoc )
+ nIndex = STR_UNDO_PIVOT_NEW;
+ else
+ nIndex = STR_UNDO_PIVOT_DELETE;
+
+ return ScGlobal::GetRscString( nIndex );
+}
+
+void __EXPORT ScUndoDataPilot::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScRange aOldRange;
+ ScRange aNewRange;
+
+ if ( pNewDPObject && pNewUndoDoc )
+ {
+ aNewRange = pNewDPObject->GetOutRange();
+ pDoc->DeleteAreaTab( aNewRange, IDF_ALL );
+ pNewUndoDoc->CopyToDocument( aNewRange, IDF_ALL, FALSE, pDoc );
+ }
+ if ( pOldDPObject && pOldUndoDoc )
+ {
+ aOldRange = pOldDPObject->GetOutRange();
+ pDoc->DeleteAreaTab( aOldRange, IDF_ALL );
+ pOldUndoDoc->CopyToDocument( aOldRange, IDF_ALL, FALSE, pDoc );
+ }
+
+ // update objects in collection
+
+ if ( pNewDPObject )
+ {
+ // find updated object
+ //! find by name!
+
+ ScDPObject* pDocObj = pDoc->GetDPAtCursor(
+ aNewRange.aStart.Col(), aNewRange.aStart.Row(), aNewRange.aStart.Tab() );
+ DBG_ASSERT(pDocObj, "DPObject not found");
+ if (pDocObj)
+ {
+ if ( pOldDPObject )
+ {
+ // restore old settings
+ pOldDPObject->WriteSourceDataTo( *pDocObj );
+ ScDPSaveData* pData = pOldDPObject->GetSaveData();
+ if (pData)
+ pDocObj->SetSaveData(*pData);
+ pDocObj->SetOutRange( pOldDPObject->GetOutRange() );
+ pOldDPObject->WriteTempDataTo( *pDocObj );
+ }
+ else
+ {
+ // delete inserted object
+ pDoc->GetDPCollection()->FreeTable(pDocObj);
+ }
+ }
+ }
+ else if ( pOldDPObject )
+ {
+ // re-insert deleted object
+
+ ScDPObject* pDestObj = new ScDPObject( *pOldDPObject );
+ pDestObj->SetAlive(TRUE);
+ if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
+ {
+ DBG_ERROR("cannot insert DPObject");
+ DELETEZ( pDestObj );
+ }
+ }
+
+ if (pNewUndoDoc)
+ pDocShell->PostPaint( aNewRange, PAINT_GRID, SC_PF_LINES );
+ if (pOldUndoDoc)
+ pDocShell->PostPaint( aOldRange, PAINT_GRID, SC_PF_LINES );
+ pDocShell->PostDataChanged();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ //! set current sheet
+ }
+
+ if (pNewDPObject)
+ {
+ // notify API objects
+ pDoc->BroadcastUno( ScDataPilotModifiedHint( pNewDPObject->GetName() ) );
+ }
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoDataPilot::Redo()
+{
+ BeginRedo();
+
+ //! copy output data instead of repeating the change,
+ //! in case external data have changed!
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScDPObject* pSourceObj = NULL;
+ if ( pOldDPObject )
+ {
+ // find object to modify
+ //! find by name!
+
+ ScRange aOldRange = pOldDPObject->GetOutRange();
+ pSourceObj = pDoc->GetDPAtCursor(
+ aOldRange.aStart.Col(), aOldRange.aStart.Row(), aOldRange.aStart.Tab() );
+ DBG_ASSERT(pSourceObj, "DPObject not found");
+ }
+
+ ScDBDocFunc aFunc( *pDocShell );
+ aFunc.DataPilotUpdate( pSourceObj, pNewDPObject, FALSE, FALSE, bAllowMove ); // no new undo action
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoDataPilot::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ //! allow deletion
+}
+
+BOOL __EXPORT ScUndoDataPilot::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ //! allow deletion
+ return FALSE;
+}
+
+
+//
+// Konsolidieren
+//
+
+ScUndoConsolidate::ScUndoConsolidate( ScDocShell* pNewDocShell, const ScArea& rArea,
+ const ScConsolidateParam& rPar, ScDocument* pNewUndoDoc,
+ BOOL bReference, SCROW nInsCount, ScOutlineTable* pTab,
+ ScDBData* pData ) :
+ ScSimpleUndo( pNewDocShell ),
+ aDestArea( rArea ),
+ pUndoDoc( pNewUndoDoc ),
+ aParam( rPar ),
+ bInsRef( bReference ),
+ nInsertCount( nInsCount ),
+ pUndoTab( pTab ),
+ pUndoData( pData )
+{
+}
+
+__EXPORT ScUndoConsolidate::~ScUndoConsolidate()
+{
+ delete pUndoDoc;
+ delete pUndoTab;
+ delete pUndoData;
+}
+
+String __EXPORT ScUndoConsolidate::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_CONSOLIDATE );
+}
+
+void __EXPORT ScUndoConsolidate::Undo()
+{
+ BeginUndo();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = aDestArea.nTab;
+
+ ScRange aOldRange;
+ if (pUndoData)
+ pUndoData->GetArea(aOldRange);
+
+ if (bInsRef)
+ {
+ // Zeilen loeschen
+ pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, aDestArea.nRowStart, nInsertCount );
+
+ // Outlines
+ pDoc->SetOutlineTable( nTab, pUndoTab );
+
+ // Zeilenstatus
+ pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pDoc );
+
+ // Daten & Referenzen
+ pDoc->DeleteAreaTab( 0,aDestArea.nRowStart, MAXCOL,aDestArea.nRowEnd, nTab, IDF_ALL );
+ pUndoDoc->UndoToDocument( 0, aDestArea.nRowStart, nTab,
+ MAXCOL, aDestArea.nRowEnd, nTab,
+ IDF_ALL, FALSE, pDoc );
+
+ // Original-Bereich
+ if (pUndoData)
+ {
+ pDoc->DeleteAreaTab(aOldRange, IDF_ALL);
+ pUndoDoc->CopyToDocument(aOldRange, IDF_ALL, FALSE, pDoc);
+ }
+
+ pDocShell->PostPaint( 0,aDestArea.nRowStart,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_SIZE );
+ }
+ else
+ {
+ pDoc->DeleteAreaTab( aDestArea.nColStart,aDestArea.nRowStart,
+ aDestArea.nColEnd,aDestArea.nRowEnd, nTab, IDF_ALL );
+ pUndoDoc->CopyToDocument( aDestArea.nColStart, aDestArea.nRowStart, nTab,
+ aDestArea.nColEnd, aDestArea.nRowEnd, nTab,
+ IDF_ALL, FALSE, pDoc );
+
+ // Original-Bereich
+ if (pUndoData)
+ {
+ pDoc->DeleteAreaTab(aOldRange, IDF_ALL);
+ pUndoDoc->CopyToDocument(aOldRange, IDF_ALL, FALSE, pDoc);
+ }
+
+ SCCOL nEndX = aDestArea.nColEnd;
+ SCROW nEndY = aDestArea.nRowEnd;
+ if ( pUndoData )
+ {
+ if ( aOldRange.aEnd.Col() > nEndX )
+ nEndX = aOldRange.aEnd.Col();
+ if ( aOldRange.aEnd.Row() > nEndY )
+ nEndY = aOldRange.aEnd.Row();
+ }
+ pDocShell->PostPaint( aDestArea.nColStart, aDestArea.nRowStart, nTab,
+ nEndX, nEndY, nTab, PAINT_GRID );
+ }
+
+ // DB-Bereich wieder anpassen
+ if (pUndoData)
+ {
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ if (pColl)
+ {
+ USHORT nIndex;
+ if (pColl->SearchName( pUndoData->GetName(), nIndex ))
+ {
+ ScDBData* pDocData = (*pColl)[nIndex];
+ if (pDocData)
+ *pDocData = *pUndoData;
+ }
+ else
+ {
+ DBG_ERROR("alte DB-Daten nicht gefunden");
+ }
+ }
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ SCTAB nViewTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nViewTab != nTab )
+ pViewShell->SetTabNo( nTab );
+ }
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoConsolidate::Redo()
+{
+ BeginRedo();
+
+ pDocShell->DoConsolidate( aParam, FALSE );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ SCTAB nViewTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nViewTab != aParam.nTab )
+ pViewShell->SetTabNo( aParam.nTab );
+ }
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoConsolidate::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoConsolidate::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//
+// Quell-Daten von Chart aendern
+//
+
+void ScUndoChartData::Init()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ aOldRangeListRef = new ScRangeList;
+ pDoc->GetOldChartParameters( aChartName, *aOldRangeListRef, bOldColHeaders, bOldRowHeaders );
+}
+
+ScUndoChartData::ScUndoChartData( ScDocShell* pNewDocShell, const String& rName,
+ const ScRange& rNew, BOOL bColHdr, BOOL bRowHdr,
+ BOOL bAdd ) :
+ ScSimpleUndo( pNewDocShell ),
+ aChartName( rName ),
+ bNewColHeaders( bColHdr ),
+ bNewRowHeaders( bRowHdr ),
+ bAddRange( bAdd )
+{
+ aNewRangeListRef = new ScRangeList;
+ aNewRangeListRef->Append( rNew );
+
+ Init();
+}
+
+ScUndoChartData::ScUndoChartData( ScDocShell* pNewDocShell, const String& rName,
+ const ScRangeListRef& rNew, BOOL bColHdr, BOOL bRowHdr,
+ BOOL bAdd ) :
+ ScSimpleUndo( pNewDocShell ),
+ aChartName( rName ),
+ aNewRangeListRef( rNew ),
+ bNewColHeaders( bColHdr ),
+ bNewRowHeaders( bRowHdr ),
+ bAddRange( bAdd )
+{
+ Init();
+}
+
+__EXPORT ScUndoChartData::~ScUndoChartData()
+{
+}
+
+String __EXPORT ScUndoChartData::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_CHARTDATA );
+}
+
+void __EXPORT ScUndoChartData::Undo()
+{
+ BeginUndo();
+
+ pDocShell->GetDocument()->UpdateChartArea( aChartName, aOldRangeListRef,
+ bOldColHeaders, bOldRowHeaders, FALSE );
+
+ EndUndo();
+}
+
+void __EXPORT ScUndoChartData::Redo()
+{
+ BeginRedo();
+
+ pDocShell->GetDocument()->UpdateChartArea( aChartName, aNewRangeListRef,
+ bNewColHeaders, bNewRowHeaders, bAddRange );
+
+ EndRedo();
+}
+
+void __EXPORT ScUndoChartData::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL __EXPORT ScUndoChartData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/undo/undodraw.cxx b/sc/source/ui/undo/undodraw.cxx
new file mode 100644
index 000000000000..a10a7381d808
--- /dev/null
+++ b/sc/source/ui/undo/undodraw.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+
+//------------------------------------------------------------------
+
+// TOOLS
+#define _BIGINT_HXX
+#define _SFXMULTISEL_HXX
+#define _STACK_HXX
+#define _QUEUE_HXX
+#define _DYNARR_HXX
+#define _TREELIST_HXX
+#define _CACHESTR_HXX
+#define _NEW_HXX
+//#define _SHL_HXX
+//#define _LINK_HXX
+//#define _ERRCODE_HXX
+//#define _GEN_HXX
+//#define _FRACT_HXX
+//#define _STRING_HXX
+//#define _MTF_HXX
+//#define _CONTNR_HXX
+//#define _LIST_HXX
+//#define _TABLE_HXX
+#define _DYNARY_HXX
+//#define _UNQIDX_HXX
+#define _SVMEMPOOL_HXX
+//#define _UNQID_HXX
+//#define _DEBUG_HXX
+//#define _DATE_HXX
+//#define _TIME_HXX
+//#define _DATETIME_HXX
+//#define _INTN_HXX
+//#define _WLDCRD_HXX
+//#define _FSYS_HXX
+//#define _STREAM_HXX
+#define _CACHESTR_HXX
+#define _SV_MULTISEL_HXX
+
+//SV
+//#define _CLIP_HXX
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _FONTDLG_HXX
+#define _PRVWIN_HXX
+//#define _COLOR_HXX
+//#define _PAL_HXX
+//#define _BITMAP_HXX
+//#define _GDIOBJ_HXX
+//#define _POINTR_HXX
+//#define _ICON_HXX
+//#define _IMAGE_HXX
+//#define _KEYCOD_HXX
+//#define _EVENT_HXX
+#define _HELP_HXX
+//#define _APP_HXX
+//#define _MDIAPP_HXX
+//#define _TIMER_HXX
+//#define _METRIC_HXX
+//#define _REGION_HXX
+//#define _OUTDEV_HXX
+//#define _SYSTEM_HXX
+//#define _VIRDEV_HXX
+//#define _JOBSET_HXX
+//#define _PRINT_HXX
+//#define _WINDOW_HXX
+//#define _SYSWIN_HXX
+//#define _WRKWIN_HXX
+#define _MDIWIN_HXX
+//#define _FLOATWIN_HXX
+//#define _DOCKWIN_HXX
+//#define _CTRL_HXX
+//#define _SCRBAR_HXX
+//#define _BUTTON_HXX
+//#define _IMAGEBTN_HXX
+//#define _FIXED_HXX
+//#define _GROUP_HXX
+//#define _EDIT_HXX
+//#define _COMBOBOX_HXX
+//#define _LSTBOX_HXX
+//#define _SELENG_HXX
+//#define _SPLIT_HXX
+#define _SPIN_HXX
+//#define _FIELD_HXX
+//#define _MOREBTN_HXX
+//#define _TOOLBOX_HXX
+//#define _STATUS_HXX
+//#define _DIALOG_HXX
+//#define _MSGBOX_HXX
+//#define _SYSDLG_HXX
+#define _FILDLG_HXX
+//#define _PRNDLG_HXX
+#define _COLDLG_HXX
+//#define _TABDLG_HXX
+//#define _MENU_HXX
+//#define _GDIMTF_HXX
+//#define _POLY_HXX
+//#define _ACCEL_HXX
+//#define _GRAPH_HXX
+#define _SOUND_HXX
+
+
+#define SI_NOITEMS
+//#define SI_NODRW
+#define _SI_NOSBXCONTROLS
+#define _SI_NOOTHERFORMS
+#define _SI_NOCONTROL
+#define _SI_NOSBXCONTROLS
+#define _SIDLL_HXX
+
+// SFX
+#define _SFXAPPWIN_HXX
+#define _SFX_SAVEOPT_HXX
+//#define _SFX_CHILDWIN_HXX
+//#define _SFXCTRLITEM_HXX
+#define _SFXPRNMON_HXX
+#define _INTRO_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXFILEDLG_HXX
+#define _PASSWD_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXSTBMGR_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXEVENT_HXX
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdundo.hxx>
+
+#include "undodraw.hxx"
+#include "docsh.hxx"
+
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScUndoDraw, SfxUndoAction);
+
+// -----------------------------------------------------------------------
+
+ScUndoDraw::ScUndoDraw( SfxUndoAction* pUndo, ScDocShell* pDocSh ) :
+ pDrawUndo( pUndo ),
+ pDocShell( pDocSh )
+{
+}
+
+__EXPORT ScUndoDraw::~ScUndoDraw()
+{
+ delete pDrawUndo;
+}
+
+void ScUndoDraw::ForgetDrawUndo()
+{
+ pDrawUndo = NULL; // nicht loeschen (Draw-Undo muss dann von aussen gemerkt werden)
+}
+
+String __EXPORT ScUndoDraw::GetComment() const
+{
+ if (pDrawUndo)
+ return pDrawUndo->GetComment();
+ else
+ return String();
+}
+
+String __EXPORT ScUndoDraw::GetRepeatComment(SfxRepeatTarget& rTarget) const
+{
+ if (pDrawUndo)
+ return pDrawUndo->GetRepeatComment(rTarget);
+ else
+ return String();
+}
+
+USHORT __EXPORT ScUndoDraw::GetId() const
+{
+ if (pDrawUndo)
+ return pDrawUndo->GetId();
+ else
+ return 0;
+}
+
+BOOL __EXPORT ScUndoDraw::IsLinked()
+{
+ if (pDrawUndo)
+ return pDrawUndo->IsLinked();
+ else
+ return FALSE;
+}
+
+void __EXPORT ScUndoDraw::SetLinked( BOOL bIsLinked )
+{
+ if (pDrawUndo)
+ pDrawUndo->SetLinked(bIsLinked);
+}
+
+BOOL __EXPORT ScUndoDraw::Merge( SfxUndoAction* pNextAction )
+{
+ if (pDrawUndo)
+ return pDrawUndo->Merge(pNextAction);
+ else
+ return FALSE;
+}
+
+void __EXPORT ScUndoDraw::Undo()
+{
+ if (pDrawUndo)
+ {
+ pDrawUndo->Undo();
+ pDocShell->SetDrawModified();
+ }
+}
+
+void __EXPORT ScUndoDraw::Redo()
+{
+ if (pDrawUndo)
+ {
+ pDrawUndo->Redo();
+ pDocShell->SetDrawModified();
+ }
+}
+
+void __EXPORT ScUndoDraw::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (pDrawUndo)
+ pDrawUndo->Repeat(rTarget);
+}
+
+BOOL __EXPORT ScUndoDraw::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ if (pDrawUndo)
+ return pDrawUndo->CanRepeat(rTarget);
+ else
+ return FALSE;
+}
+
+
+
diff --git a/sc/source/ui/undo/undoolk.cxx b/sc/source/ui/undo/undoolk.cxx
new file mode 100644
index 000000000000..183b9d1cd7b4
--- /dev/null
+++ b/sc/source/ui/undo/undoolk.cxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdundo.hxx>
+
+#include "document.hxx"
+#include "drwlayer.hxx"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+SdrUndoAction* GetSdrUndoAction( ScDocument* pDoc )
+{
+ ScDrawLayer* pLayer = pDoc->GetDrawLayer();
+ if (pLayer)
+ return pLayer->GetCalcUndo(); // muss vorhanden sein
+ else
+ return NULL;
+}
+
+void DoSdrUndoAction( SdrUndoAction* pUndoAction, ScDocument* pDoc )
+{
+ if ( pUndoAction )
+ pUndoAction->Undo();
+ else
+ {
+ // #125875# if no drawing layer existed when the action was created,
+ // but it was created after that, there is no draw undo action,
+ // and after undo there might be a drawing layer with a wrong page count.
+ // The drawing layer must have been empty in that case, so any missing
+ // pages can just be created now.
+
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if ( pDrawLayer )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nPages = static_cast<SCTAB>(pDrawLayer->GetPageCount());
+ while ( nPages < nTabCount )
+ {
+ pDrawLayer->ScAddPage( nPages );
+ ++nPages;
+ }
+ }
+ }
+}
+
+
+void RedoSdrUndoAction( SdrUndoAction* pUndoAction )
+{
+ // #125875# DoSdrUndoAction/RedoSdrUndoAction is called even if the pointer is null
+
+ if ( pUndoAction )
+ pUndoAction->Redo();
+}
+
+void DeleteSdrUndoAction( SdrUndoAction* pUndoAction )
+{
+ delete pUndoAction;
+}
+
+void EnableDrawAdjust( ScDocument* pDoc, BOOL bEnable )
+{
+ ScDrawLayer* pLayer = pDoc->GetDrawLayer();
+ if (pLayer)
+ pLayer->EnableAdjust(bEnable);
+}
+
+
+
diff --git a/sc/source/ui/undo/undostyl.cxx b/sc/source/ui/undo/undostyl.cxx
new file mode 100644
index 000000000000..b4ea7f35448c
--- /dev/null
+++ b/sc/source/ui/undo/undostyl.cxx
@@ -0,0 +1,311 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/itemset.hxx>
+#include <vcl/virdev.hxx>
+
+#include "undostyl.hxx"
+#include "docsh.hxx"
+#include "docpool.hxx"
+#include "stlpool.hxx"
+#include "printfun.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "globstr.hrc"
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScUndoModifyStyle, ScSimpleUndo);
+TYPEINIT1(ScUndoApplyPageStyle, ScSimpleUndo);
+
+// -----------------------------------------------------------------------
+//
+// modify style (cell or page style)
+//
+
+ScStyleSaveData::ScStyleSaveData() :
+ pItems( NULL )
+{
+}
+
+ScStyleSaveData::ScStyleSaveData( const ScStyleSaveData& rOther ) :
+ aName( rOther.aName ),
+ aParent( rOther.aParent )
+{
+ if (rOther.pItems)
+ pItems = new SfxItemSet( *rOther.pItems );
+ else
+ pItems = NULL;
+}
+
+ScStyleSaveData::~ScStyleSaveData()
+{
+ delete pItems;
+}
+
+ScStyleSaveData& ScStyleSaveData::operator=( const ScStyleSaveData& rOther )
+{
+ aName = rOther.aName;
+ aParent = rOther.aParent;
+
+ delete pItems;
+ if (rOther.pItems)
+ pItems = new SfxItemSet( *rOther.pItems );
+ else
+ pItems = NULL;
+
+ return *this;
+}
+
+void ScStyleSaveData::InitFromStyle( const SfxStyleSheetBase* pSource )
+{
+ if ( pSource )
+ {
+ aName = pSource->GetName();
+ aParent = pSource->GetParent();
+ delete pItems;
+ pItems = new SfxItemSet( ((SfxStyleSheetBase*)pSource)->GetItemSet() );
+ }
+ else
+ *this = ScStyleSaveData(); // empty
+}
+
+// -----------------------------------------------------------------------
+
+ScUndoModifyStyle::ScUndoModifyStyle( ScDocShell* pDocSh, SfxStyleFamily eFam,
+ const ScStyleSaveData& rOld, const ScStyleSaveData& rNew ) :
+ ScSimpleUndo( pDocSh ),
+ eFamily( eFam ),
+ aOldData( rOld ),
+ aNewData( rNew )
+{
+}
+
+ScUndoModifyStyle::~ScUndoModifyStyle()
+{
+}
+
+String ScUndoModifyStyle::GetComment() const
+{
+ USHORT nId = (eFamily == SFX_STYLE_FAMILY_PARA) ?
+ STR_UNDO_EDITCELLSTYLE :
+ STR_UNDO_EDITPAGESTYLE;
+ return ScGlobal::GetRscString( nId );
+}
+
+void lcl_DocStyleChanged( ScDocument* pDoc, SfxStyleSheetBase* pStyle, BOOL bRemoved )
+{
+ //! move to document or docshell
+
+ VirtualDevice aVDev;
+ Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = aLogic.X() / 1000.0;
+ double nPPTY = aLogic.Y() / 1000.0;
+ Fraction aZoom(1,1);
+ pDoc->StyleSheetChanged( pStyle, bRemoved, &aVDev, nPPTX, nPPTY, aZoom, aZoom );
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+}
+
+// static
+void ScUndoModifyStyle::DoChange( ScDocShell* pDocSh, const String& rName,
+ SfxStyleFamily eStyleFamily, const ScStyleSaveData& rData )
+{
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
+ String aNewName = rData.GetName();
+ BOOL bDelete = ( aNewName.Len() == 0 ); // no new name -> delete style
+ BOOL bNew = ( rName.Len() == 0 && !bDelete ); // creating new style
+
+ SfxStyleSheetBase* pStyle = NULL;
+ if ( rName.Len() )
+ {
+ // find old style to modify
+ pStyle = pStlPool->Find( rName, eStyleFamily );
+ DBG_ASSERT( pStyle, "style not found" );
+
+ if ( pStyle && !bDelete )
+ {
+ // set new name
+ pStyle->SetName( aNewName );
+ }
+ }
+ else if ( !bDelete )
+ {
+ // create style (with new name)
+ pStyle = &pStlPool->Make( aNewName, eStyleFamily, SFXSTYLEBIT_USERDEF );
+
+ if ( eStyleFamily == SFX_STYLE_FAMILY_PARA )
+ pDoc->GetPool()->CellStyleCreated( aNewName );
+ }
+
+ if ( pStyle )
+ {
+ if ( bDelete )
+ {
+ if ( eStyleFamily == SFX_STYLE_FAMILY_PARA )
+ lcl_DocStyleChanged( pDoc, pStyle, TRUE ); // TRUE: remove usage of style
+ else
+ pDoc->RemovePageStyleInUse( rName );
+
+ // delete style
+ pStlPool->Remove( pStyle );
+ }
+ else
+ {
+ // modify style
+
+ String aNewParent = rData.GetParent();
+ if ( aNewParent != pStyle->GetParent() )
+ pStyle->SetParent( aNewParent );
+
+ SfxItemSet& rStyleSet = pStyle->GetItemSet();
+ const SfxItemSet* pNewSet = rData.GetItems();
+ DBG_ASSERT( pNewSet, "no ItemSet for style" );
+ if (pNewSet)
+ rStyleSet.Set( *pNewSet, FALSE );
+
+ if ( eStyleFamily == SFX_STYLE_FAMILY_PARA )
+ {
+ lcl_DocStyleChanged( pDoc, pStyle, FALSE ); // cell styles: row heights
+ }
+ else
+ {
+ // page styles
+
+ if ( bNew && aNewName != rName )
+ pDoc->RenamePageStyleInUse( rName, aNewName );
+
+ if (pNewSet)
+ pDoc->ModifyStyleSheet( *pStyle, *pNewSet );
+
+ pDocSh->PageStyleModified( aNewName, TRUE );
+ }
+ }
+ }
+
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+
+ //! undo/redo document modifications for deleted styles
+ //! undo/redo modifications of number formatter
+}
+
+void ScUndoModifyStyle::Undo()
+{
+ BeginUndo();
+ DoChange( pDocShell, aNewData.GetName(), eFamily, aOldData );
+ EndUndo();
+}
+
+void ScUndoModifyStyle::Redo()
+{
+ BeginRedo();
+ DoChange( pDocShell, aOldData.GetName(), eFamily, aNewData );
+ EndRedo();
+}
+
+void ScUndoModifyStyle::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL ScUndoModifyStyle::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // no repeat possible
+}
+
+// -----------------------------------------------------------------------
+//
+// apply page style
+//
+ScUndoApplyPageStyle::ApplyStyleEntry::ApplyStyleEntry( SCTAB nTab, const String& rOldStyle ) :
+ mnTab( nTab ),
+ maOldStyle( rOldStyle )
+{
+}
+
+ScUndoApplyPageStyle::ScUndoApplyPageStyle( ScDocShell* pDocSh, const String& rNewStyle ) :
+ ScSimpleUndo( pDocSh ),
+ maNewStyle( rNewStyle )
+{
+}
+
+ScUndoApplyPageStyle::~ScUndoApplyPageStyle()
+{
+}
+
+void ScUndoApplyPageStyle::AddSheetAction( SCTAB nTab, const String& rOldStyle )
+{
+ maEntries.push_back( ApplyStyleEntry( nTab, rOldStyle ) );
+}
+
+String ScUndoApplyPageStyle::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_APPLYPAGESTYLE );
+}
+
+void ScUndoApplyPageStyle::Undo()
+{
+ BeginUndo();
+ for( ApplyStyleVec::const_iterator aIt = maEntries.begin(), aEnd = maEntries.end(); aIt != aEnd; ++aIt )
+ {
+ pDocShell->GetDocument()->SetPageStyle( aIt->mnTab, aIt->maOldStyle );
+ ScPrintFunc( pDocShell, pDocShell->GetPrinter(), aIt->mnTab ).UpdatePages();
+ }
+ EndUndo();
+}
+
+void ScUndoApplyPageStyle::Redo()
+{
+ BeginRedo();
+ for( ApplyStyleVec::const_iterator aIt = maEntries.begin(), aEnd = maEntries.end(); aIt != aEnd; ++aIt )
+ {
+ pDocShell->GetDocument()->SetPageStyle( aIt->mnTab, maNewStyle );
+ ScPrintFunc( pDocShell, pDocShell->GetPrinter(), aIt->mnTab ).UpdatePages();
+ }
+ EndRedo();
+}
+
+void ScUndoApplyPageStyle::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ //! set same page style to current tab
+}
+
+BOOL ScUndoApplyPageStyle::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx
new file mode 100644
index 000000000000..70845f6c0bc9
--- /dev/null
+++ b/sc/source/ui/undo/undotab.cxx
@@ -0,0 +1,1725 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/smplhint.hxx>
+
+#include "undotab.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "sc.hrc"
+#include "undoolk.hxx"
+#include "target.hxx"
+#include "uiitems.hxx"
+#include "prnsave.hxx"
+#include "printfun.hxx"
+#include "chgtrack.hxx"
+#include "tabprotection.hxx"
+#include "viewdata.hxx"
+
+// for ScUndoRenameObject - might me moved to another file later
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include "drwlayer.hxx"
+#include "scresid.hxx"
+
+extern BOOL bDrawIsInUndo; //! irgendwo als Member !!!
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
+
+// STATIC DATA -----------------------------------------------------------
+
+TYPEINIT1(ScUndoInsertTab, SfxUndoAction);
+TYPEINIT1(ScUndoInsertTables, SfxUndoAction);
+TYPEINIT1(ScUndoDeleteTab, SfxUndoAction);
+TYPEINIT1(ScUndoRenameTab, SfxUndoAction);
+TYPEINIT1(ScUndoMoveTab, SfxUndoAction);
+TYPEINIT1(ScUndoCopyTab, SfxUndoAction);
+TYPEINIT1(ScUndoMakeScenario, SfxUndoAction);
+TYPEINIT1(ScUndoImportTab, SfxUndoAction);
+TYPEINIT1(ScUndoRemoveLink, SfxUndoAction);
+TYPEINIT1(ScUndoShowHideTab, SfxUndoAction);
+TYPEINIT1(ScUndoPrintRange, SfxUndoAction);
+TYPEINIT1(ScUndoScenarioFlags, SfxUndoAction);
+TYPEINIT1(ScUndoRenameObject, SfxUndoAction);
+TYPEINIT1(ScUndoLayoutRTL, SfxUndoAction);
+//UNUSED2009-05 TYPEINIT1(ScUndoSetGrammar, SfxUndoAction);
+TYPEINIT1(ScUndoTabColor, SfxUndoAction);
+
+
+// -----------------------------------------------------------------------
+//
+// Tabelle einfuegen
+//
+
+ScUndoInsertTab::ScUndoInsertTab( ScDocShell* pNewDocShell,
+ SCTAB nTabNum,
+ BOOL bApp,
+ const String& rNewName) :
+ ScSimpleUndo( pNewDocShell ),
+ sNewName( rNewName ),
+ pDrawUndo( NULL ),
+ nTab( nTabNum ),
+ bAppend( bApp )
+{
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+ SetChangeTrack();
+}
+
+ScUndoInsertTab::~ScUndoInsertTab()
+{
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String ScUndoInsertTab::GetComment() const
+{
+ if (bAppend)
+ return ScGlobal::GetRscString( STR_UNDO_APPEND_TAB );
+ else
+ return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
+}
+
+void ScUndoInsertTab::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
+ pChangeTrack->AppendInsert( aRange );
+ nEndChangeAction = pChangeTrack->GetActionMax();
+ }
+ else
+ nEndChangeAction = 0;
+}
+
+void ScUndoInsertTab::Undo()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ pViewShell->SetTabNo(nTab);
+
+ pDocShell->SetInUndo( TRUE ); //! BeginUndo
+ bDrawIsInUndo = TRUE;
+ pViewShell->DeleteTable( nTab, FALSE );
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( FALSE ); //! EndUndo
+
+ DoSdrUndoAction( pDrawUndo, pDocShell->GetDocument() );
+
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
+
+ // SetTabNo(...,TRUE) for all views to sync with drawing layer pages
+ pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
+}
+
+void ScUndoInsertTab::Redo()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ RedoSdrUndoAction( pDrawUndo ); // Draw Redo first
+
+ pDocShell->SetInUndo( TRUE ); //! BeginRedo
+ bDrawIsInUndo = TRUE;
+ if (bAppend)
+ pViewShell->AppendTable( sNewName, FALSE );
+ else
+ {
+ pViewShell->SetTabNo(nTab);
+ pViewShell->InsertTable( sNewName, nTab, FALSE );
+ }
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( FALSE ); //! EndRedo
+
+ SetChangeTrack();
+}
+
+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 ScUndoInsertTab::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+// -----------------------------------------------------------------------
+//
+// Tabellen einfuegen
+//
+
+ScUndoInsertTables::ScUndoInsertTables( ScDocShell* pNewDocShell,
+ SCTAB nTabNum,
+ BOOL bApp,SvStrings *pNewNameList) :
+ ScSimpleUndo( pNewDocShell ),
+ pDrawUndo( NULL ),
+ nTab( nTabNum ),
+ bAppend( bApp )
+{
+ pNameList = pNewNameList;
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+
+ SetChangeTrack();
+}
+
+ScUndoInsertTables::~ScUndoInsertTables()
+{
+ String *pStr=NULL;
+ if(pNameList!=NULL)
+ {
+ for(int i=0;i<pNameList->Count();i++)
+ {
+ pStr=pNameList->GetObject(sal::static_int_cast<USHORT>(i));
+ delete pStr;
+ }
+ pNameList->Remove(0,pNameList->Count());
+ delete pNameList;
+ }
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String ScUndoInsertTables::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
+}
+
+void ScUndoInsertTables::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ nStartChangeAction = pChangeTrack->GetActionMax() + 1;
+ nEndChangeAction = 0;
+ ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
+ for( int i = 0; i < pNameList->Count(); i++ )
+ {
+ aRange.aStart.SetTab( sal::static_int_cast<SCTAB>( nTab + i ) );
+ aRange.aEnd.SetTab( sal::static_int_cast<SCTAB>( nTab + i ) );
+ pChangeTrack->AppendInsert( aRange );
+ nEndChangeAction = pChangeTrack->GetActionMax();
+ }
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void ScUndoInsertTables::Undo()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ pViewShell->SetTabNo(nTab);
+
+ pDocShell->SetInUndo( TRUE ); //! BeginUndo
+ bDrawIsInUndo = TRUE;
+
+ SvShorts TheTabs;
+ for(int i=0;i<pNameList->Count();i++)
+ {
+ TheTabs.Insert( sal::static_int_cast<short>(nTab+i), TheTabs.Count() );
+ }
+
+ pViewShell->DeleteTables( TheTabs, FALSE );
+ TheTabs.Remove(0,TheTabs.Count());
+
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( FALSE ); //! EndUndo
+
+ DoSdrUndoAction( pDrawUndo, pDocShell->GetDocument() );
+
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ // SetTabNo(...,TRUE) for all views to sync with drawing layer pages
+ pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
+}
+
+void ScUndoInsertTables::Redo()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ RedoSdrUndoAction( pDrawUndo ); // Draw Redo first
+
+ pDocShell->SetInUndo( TRUE ); //! BeginRedo
+ bDrawIsInUndo = TRUE;
+ pViewShell->SetTabNo(nTab);
+ pViewShell->InsertTables( pNameList, nTab, static_cast<SCTAB>(pNameList->Count()),FALSE );
+
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( FALSE ); //! EndRedo
+
+ SetChangeTrack();
+}
+
+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 ScUndoInsertTables::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//----------------------------------------------------------------------------------
+//
+// Tabelle loeschen
+//
+
+ScUndoDeleteTab::ScUndoDeleteTab( ScDocShell* pNewDocShell,const SvShorts &aTab, //SCTAB nNewTab,
+ ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
+ ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST )
+{
+ for(int i=0;i<aTab.Count();i++)
+ theTabs.Insert(aTab[sal::static_int_cast<USHORT>(i)],theTabs.Count());
+
+ SetChangeTrack();
+}
+
+ScUndoDeleteTab::~ScUndoDeleteTab()
+{
+ theTabs.Remove(0,theTabs.Count());
+}
+
+String ScUndoDeleteTab::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_DELETE_TAB );
+}
+
+void ScUndoDeleteTab::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ ULONG nTmpChangeAction;
+ nStartChangeAction = pChangeTrack->GetActionMax() + 1;
+ nEndChangeAction = 0;
+ ScRange aRange( 0, 0, 0, MAXCOL, MAXROW, 0 );
+ for ( int i = 0; i < theTabs.Count(); i++ )
+ {
+ aRange.aStart.SetTab( theTabs[sal::static_int_cast<USHORT>(i)] );
+ aRange.aEnd.SetTab( theTabs[sal::static_int_cast<USHORT>(i)] );
+ pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
+ nTmpChangeAction, nEndChangeAction, (short) i );
+ }
+ }
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+SCTAB lcl_GetVisibleTabBefore( ScDocument& rDoc, SCTAB nTab )
+{
+ while ( nTab > 0 && !rDoc.IsVisible( nTab ) )
+ --nTab;
+
+ return nTab;
+}
+
+void ScUndoDeleteTab::Undo()
+{
+ BeginUndo();
+ int i=0;
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ BOOL bLink = FALSE;
+ String aName;
+
+ for(i=0;i<theTabs.Count();i++)
+ {
+ SCTAB nTab = theTabs[sal::static_int_cast<USHORT>(i)];
+ pRefUndoDoc->GetName( nTab, aName );
+
+ bDrawIsInUndo = TRUE;
+ BOOL bOk = pDoc->InsertTab( nTab, aName );
+ bDrawIsInUndo = FALSE;
+ if (bOk)
+ {
+ // Ref-Undo passiert in EndUndo
+ // pUndoDoc->UndoToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pDoc );
+ pRefUndoDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pDoc );
+
+ String aOldName;
+ pRefUndoDoc->GetName( nTab, aOldName );
+ pDoc->RenameTab( nTab, aOldName, FALSE );
+ if (pRefUndoDoc->IsLinked(nTab))
+ {
+ pDoc->SetLink( nTab, pRefUndoDoc->GetLinkMode(nTab), pRefUndoDoc->GetLinkDoc(nTab),
+ pRefUndoDoc->GetLinkFlt(nTab), pRefUndoDoc->GetLinkOpt(nTab),
+ pRefUndoDoc->GetLinkTab(nTab), pRefUndoDoc->GetLinkRefreshDelay(nTab) );
+ bLink = TRUE;
+ }
+
+ if ( pRefUndoDoc->IsScenario(nTab) )
+ {
+ pDoc->SetScenario( nTab, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pRefUndoDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
+ pDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
+ BOOL bActive = pRefUndoDoc->IsActiveScenario( nTab );
+ pDoc->SetActiveScenario( nTab, bActive );
+ }
+ pDoc->SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) );
+ pDoc->SetTabBgColor( nTab, pRefUndoDoc->GetTabBgColor(nTab) );
+ pDoc->SetSheetEvents( nTab, pRefUndoDoc->GetSheetEvents( nTab ) );
+
+ if ( pRefUndoDoc->IsTabProtected( nTab ) )
+ pDoc->SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab));
+
+ // Drawing-Layer passiert beim MoveUndo::EndUndo
+ // pDoc->TransferDrawPage(pRefUndoDoc, nTab,nTab);
+ }
+ }
+ if (bLink)
+ {
+ pDocShell->UpdateLinks(); // Link-Manager updaten
+ }
+
+ EndUndo(); // Draw-Undo muss vor dem Broadcast kommen!
+
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+
+ for(i=0;i<theTabs.Count();i++)
+ {
+ pDocShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, theTabs[sal::static_int_cast<USHORT>(i)]) );
+ }
+ SfxApplication* pSfxApp = SFX_APP(); // Navigator
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+
+ pDocShell->PostPaint(0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_ALL ); // incl. Extras
+
+ // nicht ShowTable wegen SetTabNo(..., TRUE):
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetTabNo( lcl_GetVisibleTabBefore( *pDoc, theTabs[0] ), TRUE );
+
+// EndUndo();
+}
+
+void ScUndoDeleteTab::Redo()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ pViewShell->SetTabNo( lcl_GetVisibleTabBefore( *pDocShell->GetDocument(), theTabs[0] ) );
+
+ RedoSdrUndoAction( pDrawUndo ); // Draw Redo first
+
+ pDocShell->SetInUndo( TRUE ); //! BeginRedo
+ bDrawIsInUndo = TRUE;
+ pViewShell->DeleteTables( theTabs, FALSE );
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( TRUE ); //! EndRedo
+
+ SetChangeTrack();
+
+ // SetTabNo(...,TRUE) for all views to sync with drawing layer pages
+ pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
+}
+
+void ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ScTabViewShell* pViewShell = ((ScTabViewTarget&)rTarget).GetViewShell();
+ pViewShell->DeleteTable( pViewShell->GetViewData()->GetTabNo(), TRUE );
+ }
+}
+
+BOOL ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+//---------------------------------------------------------------------------------
+//
+// Tabelle umbenennen
+//
+
+ScUndoRenameTab::ScUndoRenameTab( ScDocShell* pNewDocShell,
+ SCTAB nT,
+ const String& rOldName,
+ const String& rNewName) :
+ ScSimpleUndo( pNewDocShell ),
+ nTab ( nT )
+{
+ sOldName = rOldName;
+ sNewName = rNewName;
+}
+
+ScUndoRenameTab::~ScUndoRenameTab()
+{
+}
+
+String ScUndoRenameTab::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_RENAME_TAB );
+}
+
+void ScUndoRenameTab::DoChange( SCTAB nTabP, const String& rName ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->RenameTab( nTabP, rName );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); // Navigator
+
+ pDocShell->PostPaintGridAll();
+ pDocShell->PostPaintExtras();
+ pDocShell->PostDataChanged();
+
+ // Der Tabellenname koennte in einer Formel vorkommen...
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->UpdateInputHandler();
+}
+
+void ScUndoRenameTab::Undo()
+{
+ DoChange(nTab, sOldName);
+}
+
+void ScUndoRenameTab::Redo()
+{
+ DoChange(nTab, sNewName);
+}
+
+void ScUndoRenameTab::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // Repeat macht keinen Sinn
+}
+
+BOOL ScUndoRenameTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------------
+//
+// Tabelle verschieben
+//
+
+ScUndoMoveTab::ScUndoMoveTab( ScDocShell* pNewDocShell,
+ const SvShorts &aOldTab,
+ const SvShorts &aNewTab) :
+ ScSimpleUndo( pNewDocShell )
+{
+ int i;
+ for(i=0;i<aOldTab.Count();i++)
+ theOldTabs.Insert(aOldTab[sal::static_int_cast<USHORT>(i)],theOldTabs.Count());
+
+ for(i=0;i<aNewTab.Count();i++)
+ theNewTabs.Insert(aNewTab[sal::static_int_cast<USHORT>(i)],theNewTabs.Count());
+}
+
+ScUndoMoveTab::~ScUndoMoveTab()
+{
+ theNewTabs.Remove(0,theNewTabs.Count());
+ theOldTabs.Remove(0,theOldTabs.Count());
+}
+
+String ScUndoMoveTab::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_MOVE_TAB );
+}
+
+void ScUndoMoveTab::DoChange( BOOL bUndo ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (bUndo) // UnDo
+ {
+ for(int i=theNewTabs.Count()-1;i>=0;i--)
+ {
+ SCTAB nDestTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ SCTAB nOldTab = theOldTabs[sal::static_int_cast<USHORT>(i)];
+ if (nDestTab > MAXTAB) // angehaengt ?
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ pDoc->MoveTab( nDestTab, nOldTab );
+ pViewShell->GetViewData()->MoveTab( nDestTab, nOldTab );
+ pViewShell->SetTabNo( nOldTab, TRUE );
+ }
+ }
+ else
+ {
+ for(int i=0;i<theNewTabs.Count();i++)
+ {
+ SCTAB nDestTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ SCTAB nNewTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ SCTAB nOldTab = theOldTabs[sal::static_int_cast<USHORT>(i)];
+ if (nDestTab > MAXTAB) // angehaengt ?
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ pDoc->MoveTab( nOldTab, nNewTab );
+ pViewShell->GetViewData()->MoveTab( nOldTab, nNewTab );
+ pViewShell->SetTabNo( nDestTab, TRUE );
+ }
+ }
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); // Navigator
+
+ pDocShell->PostPaintGridAll();
+ pDocShell->PostPaintExtras();
+ pDocShell->PostDataChanged();
+}
+
+void ScUndoMoveTab::Undo()
+{
+ DoChange( TRUE );
+}
+
+void ScUndoMoveTab::Redo()
+{
+ DoChange( FALSE );
+}
+
+void ScUndoMoveTab::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // kein Repeat ! ? !
+}
+
+BOOL ScUndoMoveTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------------
+//
+// Tabelle kopieren
+//
+
+ScUndoCopyTab::ScUndoCopyTab( ScDocShell* pNewDocShell,
+ const SvShorts &aOldTab,
+ const SvShorts &aNewTab) :
+ ScSimpleUndo( pNewDocShell ),
+ pDrawUndo( NULL )
+{
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+
+ int i;
+ for(i=0;i<aOldTab.Count();i++)
+ theOldTabs.Insert(aOldTab[sal::static_int_cast<USHORT>(i)],theOldTabs.Count());
+
+ for(i=0;i<aNewTab.Count();i++)
+ theNewTabs.Insert(aNewTab[sal::static_int_cast<USHORT>(i)],theNewTabs.Count());
+}
+
+ScUndoCopyTab::~ScUndoCopyTab()
+{
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String ScUndoCopyTab::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_COPY_TAB );
+}
+
+void ScUndoCopyTab::DoChange() const
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ if (pViewShell)
+ pViewShell->SetTabNo(theOldTabs[0],TRUE);
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); // Navigator
+
+ pDocShell->PostPaintGridAll();
+ pDocShell->PostPaintExtras();
+ pDocShell->PostDataChanged();
+}
+
+void ScUndoCopyTab::Undo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ DoSdrUndoAction( pDrawUndo, pDoc ); // before the sheets are deleted
+
+ int i;
+ for(i=theNewTabs.Count()-1;i>=0;i--)
+ {
+ SCTAB nDestTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ if (nDestTab > MAXTAB) // append?
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ bDrawIsInUndo = TRUE;
+ pDoc->DeleteTab(nDestTab);
+ bDrawIsInUndo = FALSE;
+ }
+
+ // ScTablesHint broadcasts after all sheets have been deleted,
+ // so sheets and draw pages are in sync!
+
+ for(i=theNewTabs.Count()-1;i>=0;i--)
+ {
+ SCTAB nDestTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ if (nDestTab > MAXTAB) // append?
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ pDocShell->Broadcast( ScTablesHint( SC_TAB_DELETED, nDestTab ) );
+ }
+
+ DoChange();
+}
+
+void ScUndoCopyTab::Redo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+ SCTAB nDestTab = 0;
+ for(int i=0;i<theNewTabs.Count();i++)
+ {
+ nDestTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ SCTAB nNewTab = theNewTabs[sal::static_int_cast<USHORT>(i)];
+ SCTAB nOldTab = theOldTabs[sal::static_int_cast<USHORT>(i)];
+ if (nDestTab > MAXTAB) // angehaengt ?
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ bDrawIsInUndo = TRUE;
+ pDoc->CopyTab( nOldTab, nNewTab );
+ bDrawIsInUndo = FALSE;
+
+ pViewShell->GetViewData()->MoveTab( nOldTab, nNewTab );
+
+ SCTAB nAdjSource = nOldTab;
+ if ( nNewTab <= nOldTab )
+ ++nAdjSource; // new position of source table after CopyTab
+
+ if ( pDoc->IsScenario(nAdjSource) )
+ {
+ pDoc->SetScenario(nNewTab, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pDoc->GetScenarioData(nAdjSource, aComment, aColor, nScenFlags );
+ pDoc->SetScenarioData(nNewTab, aComment, aColor, nScenFlags );
+ BOOL bActive = pDoc->IsActiveScenario(nAdjSource);
+ pDoc->SetActiveScenario(nNewTab, bActive );
+ BOOL bVisible=pDoc->IsVisible(nAdjSource);
+ pDoc->SetVisible(nNewTab,bVisible );
+ }
+
+ if ( pDoc->IsTabProtected( nAdjSource ) )
+ pDoc->CopyTabProtection(nAdjSource, nNewTab);
+ }
+
+ RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
+
+ pViewShell->SetTabNo( nDestTab, TRUE ); // after draw-undo
+
+ DoChange();
+
+}
+
+void ScUndoCopyTab::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // kein Repeat ! ? !
+}
+
+BOOL ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------------
+//
+// Tab Bg Color
+//
+
+ScUndoTabColor::ScUndoTabColor(
+ ScDocShell* pNewDocShell, SCTAB nT, const Color& aOTabBgColor, const Color& aNTabBgColor) :
+ ScSimpleUndo( pNewDocShell )
+{
+ ScUndoTabColorInfo aInfo(nT);
+ aInfo.maOldTabBgColor = aOTabBgColor;
+ aInfo.maNewTabBgColor = aNTabBgColor;
+ aTabColorList.push_back(aInfo);
+}
+
+ScUndoTabColor::ScUndoTabColor(
+ ScDocShell* pNewDocShell,
+ const ScUndoTabColorInfo::List& rUndoTabColorList) :
+ ScSimpleUndo(pNewDocShell),
+ aTabColorList(rUndoTabColorList)
+{
+}
+
+ScUndoTabColor::~ScUndoTabColor()
+{
+}
+
+String ScUndoTabColor::GetComment() const
+{
+ if (aTabColorList.size() > 1)
+ return ScGlobal::GetRscString(STR_UNDO_SET_MULTI_TAB_BG_COLOR);
+ return ScGlobal::GetRscString(STR_UNDO_SET_TAB_BG_COLOR);
+}
+
+void ScUndoTabColor::DoChange(bool bUndoType) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (!pDoc)
+ return;
+
+ size_t nTabColorCount = aTabColorList.size();
+ for (size_t i = 0; i < nTabColorCount; ++i)
+ {
+ const ScUndoTabColorInfo& rTabColor = aTabColorList[i];
+ pDoc->SetTabBgColor(rTabColor.mnTabId,
+ bUndoType ? rTabColor.maOldTabBgColor : rTabColor.maNewTabBgColor);
+ }
+
+ pDocShell->PostPaintExtras();
+ ScDocShellModificator aModificator( *pDocShell );
+ aModificator.SetDocumentModified();
+}
+
+void ScUndoTabColor::Undo()
+{
+ DoChange(true);
+}
+
+void ScUndoTabColor::Redo()
+{
+ DoChange(false);
+}
+
+void ScUndoTabColor::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // No Repeat
+}
+
+BOOL ScUndoTabColor::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+//
+// Szenario anlegen
+//
+
+ScUndoMakeScenario::ScUndoMakeScenario( ScDocShell* pNewDocShell,
+ SCTAB nSrc, SCTAB nDest,
+ const String& rN, const String& rC,
+ const Color& rCol, USHORT nF,
+ const ScMarkData& rMark ) :
+ ScSimpleUndo( pNewDocShell ),
+ nSrcTab( nSrc ),
+ nDestTab( nDest ),
+ aName( rN ),
+ aComment( rC ),
+ aColor( rCol ),
+ nFlags( nF ),
+ aMarkData( rMark ),
+ pDrawUndo( NULL )
+{
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+}
+
+ScUndoMakeScenario::~ScUndoMakeScenario()
+{
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String ScUndoMakeScenario::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_MAKESCENARIO );
+}
+
+void ScUndoMakeScenario::Undo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ pDocShell->SetInUndo( TRUE );
+ bDrawIsInUndo = TRUE;
+ pDoc->DeleteTab( nDestTab );
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( FALSE );
+
+ DoSdrUndoAction( pDrawUndo, pDoc );
+
+ pDocShell->PostPaint(0,0,nDestTab,MAXCOL,MAXROW,MAXTAB, PAINT_ALL);
+ pDocShell->PostDataChanged();
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetTabNo( nSrcTab, TRUE );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+
+ // SetTabNo(...,TRUE) for all views to sync with drawing layer pages
+ pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
+}
+
+void ScUndoMakeScenario::Redo()
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ RedoSdrUndoAction( pDrawUndo ); // Draw Redo first
+
+ pDocShell->SetInUndo( TRUE );
+ bDrawIsInUndo = TRUE;
+
+ pDocShell->MakeScenario( nSrcTab, aName, aComment, aColor, nFlags, aMarkData, FALSE );
+
+ bDrawIsInUndo = FALSE;
+ pDocShell->SetInUndo( FALSE );
+
+ if (pViewShell)
+ pViewShell->SetTabNo( nDestTab, TRUE );
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+}
+
+void ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+ ((ScTabViewTarget&)rTarget).GetViewShell()->MakeScenario( aName, aComment, aColor, nFlags );
+ }
+}
+
+BOOL ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Tabelle einfuegen
+//
+
+ScUndoImportTab::ScUndoImportTab( ScDocShell* pShell,
+ SCTAB nNewTab, SCTAB nNewCount, BOOL bNewLink ) :
+ ScSimpleUndo( pShell ),
+ nTab( nNewTab ),
+ nCount( nNewCount ),
+ bLink( bNewLink ),
+ pRedoDoc( NULL ),
+ pDrawUndo( NULL )
+{
+ pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
+}
+
+ScUndoImportTab::~ScUndoImportTab()
+{
+ delete pRedoDoc;
+ DeleteSdrUndoAction( pDrawUndo );
+}
+
+String ScUndoImportTab::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
+}
+
+void ScUndoImportTab::DoChange() const
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if (pViewShell)
+ {
+ if(nTab<nTabCount)
+ {
+ pViewShell->SetTabNo(nTab,TRUE);
+ }
+ else
+ {
+ pViewShell->SetTabNo(nTab-1,TRUE);
+ }
+ }
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); // Navigator
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
+}
+
+void ScUndoImportTab::Undo()
+{
+ //! eingefuegte Bereichsnamen etc.
+
+ SCTAB i;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bMakeRedo = !pRedoDoc;
+ if (bMakeRedo)
+ {
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nTab,nTab+nCount-1, TRUE,TRUE );
+
+ String aOldName;
+ for (i=0; i<nCount; i++)
+ {
+ SCTAB nTabPos=nTab+i;
+
+ pDoc->CopyToDocument(0,0,nTabPos, MAXCOL,MAXROW,nTabPos, IDF_ALL,FALSE, pRedoDoc );
+ pDoc->GetName( nTabPos, aOldName );
+ pRedoDoc->RenameTab( nTabPos, aOldName, FALSE );
+
+ if ( pDoc->IsScenario(nTabPos) )
+ {
+ pRedoDoc->SetScenario(nTabPos, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pDoc->GetScenarioData(nTabPos, aComment, aColor, nScenFlags );
+ pRedoDoc->SetScenarioData(nTabPos, aComment, aColor, nScenFlags );
+ BOOL bActive = pDoc->IsActiveScenario(nTabPos);
+ pRedoDoc->SetActiveScenario(nTabPos, bActive );
+ BOOL bVisible=pDoc->IsVisible(nTabPos);
+ pRedoDoc->SetVisible(nTabPos,bVisible );
+ }
+
+ if ( pDoc->IsTabProtected( nTabPos ) )
+ pRedoDoc->SetTabProtection(nTabPos, pDoc->GetTabProtection(nTabPos));
+ }
+
+ }
+
+ DoSdrUndoAction( pDrawUndo, pDoc ); // before the sheets are deleted
+
+ bDrawIsInUndo = TRUE;
+ for (i=0; i<nCount; i++)
+ pDoc->DeleteTab( nTab );
+ bDrawIsInUndo = FALSE;
+
+ DoChange();
+}
+
+void ScUndoImportTab::Redo()
+{
+ if (!pRedoDoc)
+ {
+ DBG_ERROR("wo ist mein Redo-Document?");
+ return;
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ String aName;
+ SCTAB i;
+ for (i=0; i<nCount; i++) // first insert all sheets (#63304#)
+ {
+ SCTAB nTabPos=nTab+i;
+ pRedoDoc->GetName(nTabPos,aName);
+ bDrawIsInUndo = TRUE;
+ pDoc->InsertTab(nTabPos,aName);
+ bDrawIsInUndo = FALSE;
+ }
+ for (i=0; i<nCount; i++) // then copy into inserted sheets
+ {
+ SCTAB nTabPos=nTab+i;
+ pRedoDoc->CopyToDocument(0,0,nTabPos, MAXCOL,MAXROW,nTabPos, IDF_ALL,FALSE, pDoc );
+
+ if ( pRedoDoc->IsScenario(nTabPos) )
+ {
+ pDoc->SetScenario(nTabPos, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pRedoDoc->GetScenarioData(nTabPos, aComment, aColor, nScenFlags );
+ pDoc->SetScenarioData(nTabPos, aComment, aColor, nScenFlags );
+ BOOL bActive = pRedoDoc->IsActiveScenario(nTabPos);
+ pDoc->SetActiveScenario(nTabPos, bActive );
+ BOOL bVisible=pRedoDoc->IsVisible(nTabPos);
+ pDoc->SetVisible(nTabPos,bVisible );
+ }
+
+ if ( pRedoDoc->IsTabProtected( nTabPos ) )
+ pDoc->SetTabProtection(nTabPos, pRedoDoc->GetTabProtection(nTabPos));
+ }
+
+ RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
+
+ DoChange();
+}
+
+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 ScUndoImportTab::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Tabellen-Verknuepfung aufheben
+//
+
+ScUndoRemoveLink::ScUndoRemoveLink( ScDocShell* pShell, const String& rDoc ) :
+ ScSimpleUndo( pShell ),
+ aDocName( rDoc ),
+ nCount( 0 )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pTabs = new SCTAB[nTabCount];
+ pModes = new BYTE[nTabCount];
+ pTabNames = new String[nTabCount];
+
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ BYTE nMode = pDoc->GetLinkMode(i);
+ if (nMode)
+ if (pDoc->GetLinkDoc(i) == aDocName)
+ {
+ if (!nCount)
+ {
+ aFltName = pDoc->GetLinkFlt(i);
+ aOptions = pDoc->GetLinkOpt(i);
+ nRefreshDelay = pDoc->GetLinkRefreshDelay(i);
+ }
+ else
+ {
+ DBG_ASSERT(aFltName == pDoc->GetLinkFlt(i) &&
+ aOptions == pDoc->GetLinkOpt(i),
+ "verschiedene Filter fuer ein Dokument?");
+ }
+ pTabs[nCount] = i;
+ pModes[nCount] = nMode;
+ pTabNames[nCount] = pDoc->GetLinkTab(i);
+ ++nCount;
+ }
+ }
+}
+
+ScUndoRemoveLink::~ScUndoRemoveLink()
+{
+ delete pTabs;
+ delete pModes;
+ delete[] pTabNames;
+}
+
+String ScUndoRemoveLink::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_REMOVELINK );
+}
+
+void ScUndoRemoveLink::DoChange( BOOL bLink ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ String aEmpty;
+ for (USHORT i=0; i<nCount; i++)
+ if (bLink) // establish link
+ pDoc->SetLink( pTabs[i], pModes[i], aDocName, aFltName, aOptions, pTabNames[i], nRefreshDelay );
+ else // remove link
+ pDoc->SetLink( pTabs[i], SC_LINK_NONE, aEmpty, aEmpty, aEmpty, aEmpty, 0 );
+ pDocShell->UpdateLinks();
+}
+
+void ScUndoRemoveLink::Undo()
+{
+ DoChange( TRUE );
+}
+
+void ScUndoRemoveLink::Redo()
+{
+ DoChange( FALSE );
+}
+
+void ScUndoRemoveLink::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL ScUndoRemoveLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+// -----------------------------------------------------------------------
+//
+// Tabellen ein-/ausblenden
+//
+
+ScUndoShowHideTab::ScUndoShowHideTab( ScDocShell* pShell, SCTAB nNewTab, BOOL bNewShow ) :
+ ScSimpleUndo( pShell ),
+ nTab( nNewTab ),
+ bShow( bNewShow )
+{
+}
+
+ScUndoShowHideTab::~ScUndoShowHideTab()
+{
+}
+
+void ScUndoShowHideTab::DoChange( BOOL bShowP ) const
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->SetVisible( nTab, bShowP );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetTabNo(nTab,TRUE);
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocShell->SetDocumentModified();
+}
+
+void ScUndoShowHideTab::Undo()
+{
+ DoChange(!bShow);
+}
+
+void ScUndoShowHideTab::Redo()
+{
+ DoChange(bShow);
+}
+
+void ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
+ Execute( bShow ? FID_TABLE_SHOW : FID_TABLE_HIDE,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+}
+
+BOOL ScUndoShowHideTab::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+String ScUndoShowHideTab::GetComment() const
+{
+ USHORT nId = bShow ? STR_UNDO_SHOWTAB : STR_UNDO_HIDETAB;
+ return ScGlobal::GetRscString( nId );
+}
+
+// ============================================================================
+
+ScUndoDocProtect::ScUndoDocProtect(ScDocShell* pShell, auto_ptr<ScDocProtection> pProtectSettings) :
+ ScSimpleUndo(pShell),
+ mpProtectSettings(pProtectSettings)
+{
+}
+
+ScUndoDocProtect::~ScUndoDocProtect()
+{
+}
+
+void ScUndoDocProtect::DoProtect(bool bProtect)
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ if (bProtect)
+ {
+ // set protection.
+ auto_ptr<ScDocProtection> pCopy(new ScDocProtection(*mpProtectSettings));
+ pCopy->setProtected(true);
+ pDoc->SetDocProtection(pCopy.get());
+ }
+ else
+ {
+ // remove protection.
+ pDoc->SetDocProtection(NULL);
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->UpdateLayerLocks();
+ pViewShell->UpdateInputHandler(TRUE); // damit sofort wieder eingegeben werden kann
+ }
+
+ pDocShell->PostPaintGridAll();
+}
+
+void ScUndoDocProtect::Undo()
+{
+ BeginUndo();
+ DoProtect(!mpProtectSettings->isProtected());
+ EndUndo();
+}
+
+void ScUndoDocProtect::Redo()
+{
+ BeginRedo();
+ DoProtect(mpProtectSettings->isProtected());
+ EndRedo();
+}
+
+void ScUndoDocProtect::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL ScUndoDocProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // gippsnich
+}
+
+String ScUndoDocProtect::GetComment() const
+{
+ 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
+ {
+ // 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 );
+}
+
+// -----------------------------------------------------------------------
+//
+// Druck-/Wiederholungsbereiche aendern
+//
+
+ScUndoPrintRange::ScUndoPrintRange( ScDocShell* pShell, SCTAB nNewTab,
+ ScPrintRangeSaver* pOld, ScPrintRangeSaver* pNew ) :
+ ScSimpleUndo( pShell ),
+ nTab( nNewTab ),
+ pOldRanges( pOld ),
+ pNewRanges( pNew )
+{
+}
+
+ScUndoPrintRange::~ScUndoPrintRange()
+{
+ delete pOldRanges;
+ delete pNewRanges;
+}
+
+void ScUndoPrintRange::DoChange(BOOL bUndo)
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (bUndo)
+ pDoc->RestorePrintRanges( *pOldRanges );
+ else
+ pDoc->RestorePrintRanges( *pNewRanges );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetTabNo( nTab );
+
+ ScPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab ).UpdatePages();
+
+ pDocShell->PostPaint( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab), PAINT_GRID );
+}
+
+void ScUndoPrintRange::Undo()
+{
+ BeginUndo();
+ DoChange( TRUE );
+ EndUndo();
+}
+
+void ScUndoPrintRange::Redo()
+{
+ BeginRedo();
+ DoChange( FALSE );
+ EndRedo();
+}
+
+void ScUndoPrintRange::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL ScUndoPrintRange::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // gippsnich
+}
+
+String ScUndoPrintRange::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_PRINTRANGES );
+}
+
+
+//------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------
+//
+// Szenario-Flags
+//
+
+ScUndoScenarioFlags::ScUndoScenarioFlags( ScDocShell* pNewDocShell, SCTAB nT,
+ const String& rON, const String& rNN, const String& rOC, const String& rNC,
+ const Color& rOCol, const Color& rNCol, USHORT nOF, USHORT nNF ) :
+ ScSimpleUndo( pNewDocShell ),
+ nTab ( nT ),
+ aOldName ( rON ),
+ aNewName ( rNN ),
+ aOldComment ( rOC ),
+ aNewComment ( rNC ),
+ aOldColor ( rOCol ),
+ aNewColor ( rNCol ),
+ nOldFlags ( nOF ),
+ nNewFlags ( nNF )
+{
+}
+
+ScUndoScenarioFlags::~ScUndoScenarioFlags()
+{
+}
+
+String ScUndoScenarioFlags::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_EDITSCENARIO );
+}
+
+void ScUndoScenarioFlags::Undo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ pDoc->RenameTab( nTab, aOldName );
+ pDoc->SetScenarioData( nTab, aOldComment, aOldColor, nOldFlags );
+
+ pDocShell->PostPaintGridAll();
+ // Der Tabellenname koennte in einer Formel vorkommen...
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->UpdateInputHandler();
+
+ if ( aOldName != aNewName )
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+}
+
+void ScUndoScenarioFlags::Redo()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ pDoc->RenameTab( nTab, aNewName );
+ pDoc->SetScenarioData( nTab, aNewComment, aNewColor, nNewFlags );
+
+ pDocShell->PostPaintGridAll();
+ // Der Tabellenname koennte in einer Formel vorkommen...
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->UpdateInputHandler();
+
+ if ( aOldName != aNewName )
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+}
+
+void ScUndoScenarioFlags::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // Repeat macht keinen Sinn
+}
+
+BOOL ScUndoScenarioFlags::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+
+//---------------------------------------------------------------------------------
+//
+// rename object
+// (move to different file?)
+//
+
+ScUndoRenameObject::ScUndoRenameObject( ScDocShell* pNewDocShell, const String& rPN,
+ const String& rON, const String& rNN ) :
+ ScSimpleUndo( pNewDocShell ),
+ aPersistName( rPN ),
+ aOldName ( rON ),
+ aNewName ( rNN )
+{
+}
+
+ScUndoRenameObject::~ScUndoRenameObject()
+{
+}
+
+String ScUndoRenameObject::GetComment() const
+{
+ // string resource shared with title for dialog
+ return String( ScResId(SCSTR_RENAMEOBJECT) );
+}
+
+SdrObject* ScUndoRenameObject::GetObject()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if ( pDrawLayer )
+ {
+ USHORT nCount = pDrawLayer->GetPageCount();
+ for (USHORT nTab=0; nTab<nCount; nTab++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(nTab);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
+ ((SdrOle2Obj*)pObject)->GetPersistName() == aPersistName )
+ {
+ return pObject;
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+ DBG_ERROR("Object not found");
+ return NULL;
+}
+
+void ScUndoRenameObject::Undo()
+{
+ BeginUndo();
+ SdrObject* pObj = GetObject();
+ if ( pObj )
+ pObj->SetName( aOldName );
+ EndUndo();
+}
+
+void ScUndoRenameObject::Redo()
+{
+ BeginRedo();
+ SdrObject* pObj = GetObject();
+ if ( pObj )
+ pObj->SetName( aNewName );
+ EndRedo();
+}
+
+void ScUndoRenameObject::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+}
+
+BOOL ScUndoRenameObject::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+//
+// Switch sheet between left-to-right and right-to-left
+//
+
+ScUndoLayoutRTL::ScUndoLayoutRTL( ScDocShell* pShell, SCTAB nNewTab, BOOL bNewRTL ) :
+ ScSimpleUndo( pShell ),
+ nTab( nNewTab ),
+ bRTL( bNewRTL )
+{
+}
+
+ScUndoLayoutRTL::~ScUndoLayoutRTL()
+{
+}
+
+void ScUndoLayoutRTL::DoChange( BOOL bNew )
+{
+ pDocShell->SetInUndo( TRUE );
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->SetLayoutRTL( nTab, bNew );
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetTabNo(nTab,TRUE);
+
+ pDocShell->SetDocumentModified();
+
+ pDocShell->SetInUndo( FALSE );
+}
+
+void ScUndoLayoutRTL::Undo()
+{
+ DoChange(!bRTL);
+}
+
+void ScUndoLayoutRTL::Redo()
+{
+ DoChange(bRTL);
+}
+
+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 ScUndoLayoutRTL::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+
+String ScUndoLayoutRTL::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_TAB_RTL );
+}
+
+
+
+// -----------------------------------------------------------------------
+//
+// Set the grammar used for the sheet
+//
+
+//UNUSED2009-05 ScUndoSetGrammar::ScUndoSetGrammar( ScDocShell* pShell,
+//UNUSED2009-05 formula::FormulaGrammar::Grammar eGrammar ) :
+//UNUSED2009-05 ScSimpleUndo( pShell ),
+//UNUSED2009-05 meNewGrammar( eGrammar )
+//UNUSED2009-05 {
+//UNUSED2009-05 meOldGrammar = pDocShell->GetDocument()->GetGrammar();
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 __EXPORT ScUndoSetGrammar::~ScUndoSetGrammar()
+//UNUSED2009-05 {
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 void ScUndoSetGrammar::DoChange( formula::FormulaGrammar::Grammar eGrammar )
+//UNUSED2009-05 {
+//UNUSED2009-05 pDocShell->SetInUndo( TRUE );
+//UNUSED2009-05 ScDocument* pDoc = pDocShell->GetDocument();
+//UNUSED2009-05 pDoc->SetGrammar( eGrammar );
+//UNUSED2009-05 pDocShell->SetDocumentModified();
+//UNUSED2009-05 pDocShell->SetInUndo( FALSE );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 void __EXPORT ScUndoSetGrammar::Undo()
+//UNUSED2009-05 {
+//UNUSED2009-05 DoChange( meOldGrammar );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 void __EXPORT ScUndoSetGrammar::Redo()
+//UNUSED2009-05 {
+//UNUSED2009-05 DoChange( meNewGrammar );
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 void __EXPORT ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
+//UNUSED2009-05 {
+//UNUSED2009-05 #if 0
+//UNUSED2009-05 // erAck: 2006-09-07T23:00+0200 commented out in CWS scr1c1
+//UNUSED2009-05 if (rTarget.ISA(ScTabViewTarget))
+//UNUSED2009-05 ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
+//UNUSED2009-05 Execute( FID_TAB_USE_R1C1, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+//UNUSED2009-05 #endif
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 BOOL __EXPORT ScUndoSetGrammar::CanRepeat(SfxRepeatTarget& rTarget) const
+//UNUSED2009-05 {
+//UNUSED2009-05 return (rTarget.ISA(ScTabViewTarget));
+//UNUSED2009-05 }
+//UNUSED2009-05
+//UNUSED2009-05 String __EXPORT ScUndoSetGrammar::GetComment() const
+//UNUSED2009-05 {
+//UNUSED2009-05 return ScGlobal::GetRscString( STR_UNDO_TAB_R1C1 );
+//UNUSED2009-05 }
+
diff --git a/sc/source/ui/undo/undoutil.cxx b/sc/source/ui/undo/undoutil.cxx
new file mode 100644
index 000000000000..168975cdda3a
--- /dev/null
+++ b/sc/source/ui/undo/undoutil.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "undoutil.hxx"
+
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "dbcolect.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+
+void ScUndoUtil::MarkSimpleBlock( ScDocShell* /* pDocShell */,
+ SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+ SCCOL nEndX, SCROW nEndY, SCTAB nEndZ )
+{
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ SCTAB nViewTab = pViewShell->GetViewData()->GetTabNo();
+ if ( nViewTab < nStartZ || nViewTab > nEndZ )
+ pViewShell->SetTabNo( nStartZ );
+
+ pViewShell->DoneBlockMode();
+ pViewShell->MoveCursorAbs( nStartX, nStartY, SC_FOLLOW_JUMP, FALSE, FALSE );
+ pViewShell->InitOwnBlockMode();
+ pViewShell->GetViewData()->GetMarkData().
+ SetMarkArea( ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ) );
+ pViewShell->MarkDataChanged();
+ }
+}
+
+
+void ScUndoUtil::MarkSimpleBlock( ScDocShell* pDocShell,
+ const ScAddress& rBlockStart,
+ const ScAddress& rBlockEnd )
+{
+ MarkSimpleBlock( pDocShell, rBlockStart.Col(), rBlockStart.Row(), rBlockStart.Tab(),
+ rBlockEnd.Col(), rBlockEnd.Row(), rBlockEnd.Tab() );
+}
+
+
+void ScUndoUtil::MarkSimpleBlock( ScDocShell* pDocShell,
+ const ScRange& rRange )
+{
+ MarkSimpleBlock( pDocShell, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab() );
+}
+
+
+
+ScDBData* ScUndoUtil::GetOldDBData( ScDBData* pUndoData, ScDocument* pDoc, SCTAB nTab,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ ScDBData* pRet = pDoc->GetDBAtArea( nTab, nCol1, nRow1, nCol2, nRow2 );
+
+ if (!pRet)
+ {
+ BOOL bWasTemp = FALSE;
+ if ( pUndoData )
+ {
+ String aName;
+ pUndoData->GetName( aName );
+ if ( aName == ScGlobal::GetRscString( STR_DB_NONAME ) )
+ bWasTemp = TRUE;
+ }
+ DBG_ASSERT(bWasTemp, "Undo: didn't find database range");
+
+ USHORT nIndex;
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ if (pColl->SearchName( ScGlobal::GetRscString( STR_DB_NONAME ), nIndex ))
+ pRet = (*pColl)[nIndex];
+ else
+ {
+ pRet = new ScDBData( ScGlobal::GetRscString( STR_DB_NONAME ), nTab,
+ nCol1,nRow1, nCol2,nRow2, TRUE,
+ pDoc->HasColHeader( nCol1,nRow1,nCol2,nRow2,nTab ) );
+ pColl->Insert( pRet );
+ }
+ }
+
+ return pRet;
+}
+
+
+void ScUndoUtil::PaintMore( ScDocShell* pDocShell,
+ const ScRange& rRange )
+{
+ SCCOL nCol1 = rRange.aStart.Col();
+ SCROW nRow1 = rRange.aStart.Row();
+ SCCOL nCol2 = rRange.aEnd.Col();
+ SCROW nRow2 = rRange.aEnd.Row();
+ if (nCol1 > 0) --nCol1;
+ if (nRow1 > 0) --nRow1;
+ if (nCol2<MAXCOL) ++nCol2;
+ if (nRow2<MAXROW) ++nRow2;
+
+ pDocShell->PostPaint( nCol1,nRow1,rRange.aStart.Tab(),
+ nCol2,nRow2,rRange.aEnd.Tab(), PAINT_GRID );
+}
diff --git a/sc/source/ui/unoobj/ChartRangeSelectionListener.cxx b/sc/source/ui/unoobj/ChartRangeSelectionListener.cxx
new file mode 100644
index 000000000000..e8000d71518b
--- /dev/null
+++ b/sc/source/ui/unoobj/ChartRangeSelectionListener.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "ChartRangeSelectionListener.hxx"
+
+#include <com/sun/star/chart2/data/XRangeHighlighter.hpp>
+
+#include <sfx2/viewfrm.hxx>
+#include "tabvwsh.hxx"
+#include "unonames.hxx"
+#include "miscuno.hxx"
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+SC_SIMPLE_SERVICE_INFO( ScChartRangeSelectionListener, "ScChartRangeSelectionListener",
+ SC_SERVICENAME_CHRANGEHILIGHT )
+
+ScChartRangeSelectionListener::ScChartRangeSelectionListener( ScTabViewShell * pViewShell ) :
+ ScChartRangeSelectionListener_Base( m_aMutex ),
+ m_pViewShell( pViewShell )
+{}
+
+ScChartRangeSelectionListener::~ScChartRangeSelectionListener()
+{}
+
+// ____ XModifyListener ____
+void SAL_CALL ScChartRangeSelectionListener::selectionChanged( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ Reference< chart2::data::XRangeHighlighter > xRangeHighlighter( aEvent.Source, uno::UNO_QUERY );
+ if( xRangeHighlighter.is())
+ {
+ Sequence< chart2::data::HighlightedRange > aRanges( xRangeHighlighter->getSelectedRanges());
+
+ // search the view on which the chart is active
+
+ if( m_pViewShell )
+ {
+ m_pViewShell->DoChartSelection( aRanges );
+ }
+// SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pDocShell );
+// while (pFrame)
+// {
+// SfxViewShell* pSh = pFrame->GetViewShell();
+// if (pSh && pSh->ISA(ScTabViewShell))
+// {
+// ScTabViewShell* pViewSh = (ScTabViewShell*)pSh;
+// }
+// pFrame = SfxViewFrame::GetNext( *pFrame, m_pDocShell );
+// }
+ }
+}
+
+// ____ XEventListener ____
+void SAL_CALL ScChartRangeSelectionListener::disposing( const lang::EventObject& /*Source*/ )
+ throw (uno::RuntimeException)
+{
+}
+
+// ____ WeakComponentImplHelperBase ____
+void SAL_CALL ScChartRangeSelectionListener::disposing()
+{
+ m_pViewShell = 0;
+}
diff --git a/sc/source/ui/unoobj/addruno.cxx b/sc/source/ui/unoobj/addruno.cxx
new file mode 100644
index 000000000000..10627222be80
--- /dev/null
+++ b/sc/source/ui/unoobj/addruno.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+#include <svl/itemprop.hxx>
+
+#include "docsh.hxx"
+#include "unonames.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "convuno.hxx"
+#include "addruno.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+ScAddressConversionObj::ScAddressConversionObj(ScDocShell* pDocSh, sal_Bool bForRange) :
+ pDocShell( pDocSh ),
+ nRefSheet( 0 ),
+ bIsRange( bForRange )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScAddressConversionObj::~ScAddressConversionObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScAddressConversionObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // invalid
+ }
+}
+
+sal_Bool ScAddressConversionObj::ParseUIString( const String& rUIString )
+{
+ if (!pDocShell)
+ return sal_False;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Bool bSuccess = sal_False;
+ if ( bIsRange )
+ {
+ USHORT nResult = aRange.ParseAny( rUIString, pDoc );
+ if ( nResult & SCA_VALID )
+ {
+ if ( ( nResult & SCA_TAB_3D ) == 0 )
+ aRange.aStart.SetTab( static_cast<SCTAB>(nRefSheet) );
+ if ( ( nResult & SCA_TAB2_3D ) == 0 )
+ aRange.aEnd.SetTab( aRange.aStart.Tab() );
+ // different sheets are not supported in CellRangeAddress
+ if ( aRange.aStart.Tab() == aRange.aEnd.Tab() )
+ bSuccess = sal_True;
+ }
+ }
+ else
+ {
+ USHORT nResult = aRange.aStart.Parse( rUIString, pDoc );
+ if ( nResult & SCA_VALID )
+ {
+ if ( ( nResult & SCA_TAB_3D ) == 0 )
+ aRange.aStart.SetTab( static_cast<SCTAB>(nRefSheet) );
+ bSuccess = sal_True;
+ }
+ }
+ return bSuccess;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAddressConversionObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( bIsRange )
+ {
+ static SfxItemPropertyMapEntry aPropertyMap[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ADDRESS), 0, &getCppuType((table::CellRangeAddress*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PERSREPR), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_REFSHEET), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_UIREPR), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static uno::Reference<beans::XPropertySetInfo> aRef(new SfxItemPropertySetInfo( aPropertyMap ));
+ return aRef;
+ }
+ else
+ {
+ static SfxItemPropertyMapEntry aPropertyMap[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ADDRESS), 0, &getCppuType((table::CellAddress*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PERSREPR), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_REFSHEET), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_UIREPR), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static uno::Reference<beans::XPropertySetInfo> aRef(new SfxItemPropertySetInfo( aPropertyMap ));
+ return aRef;
+ }
+}
+
+void SAL_CALL ScAddressConversionObj::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ sal_Bool bSuccess = sal_False;
+ String aNameStr(aPropertyName);
+ if ( aNameStr.EqualsAscii( SC_UNONAME_ADDRESS ) )
+ {
+ // read the cell/range address from API struct
+ if ( bIsRange )
+ {
+ table::CellRangeAddress aRangeAddress;
+ if ( aValue >>= aRangeAddress )
+ {
+ ScUnoConversion::FillScRange( aRange, aRangeAddress );
+ bSuccess = sal_True;
+ }
+ }
+ else
+ {
+ table::CellAddress aCellAddress;
+ if ( aValue >>= aCellAddress )
+ {
+ ScUnoConversion::FillScAddress( aRange.aStart, aCellAddress );
+ bSuccess = sal_True;
+ }
+ }
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNONAME_REFSHEET ) )
+ {
+ // set the reference sheet
+ sal_Int32 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ nRefSheet = nIntVal;
+ bSuccess = sal_True;
+ }
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNONAME_UIREPR ) )
+ {
+ // parse the UI representation string
+ rtl::OUString sRepresentation;
+ if (aValue >>= sRepresentation)
+ {
+ String aUIString = sRepresentation;
+ bSuccess = ParseUIString( aUIString );
+ }
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) )
+ {
+ // parse the file format string
+ rtl::OUString sRepresentation;
+ if (aValue >>= sRepresentation)
+ {
+ String aUIString(sRepresentation);
+
+ // cell or range: strip a single "." at the start
+ if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
+ aUIString.Erase( 0, 1 );
+
+ if ( bIsRange )
+ {
+ // range: also strip a "." after the last colon
+ sal_Int32 nColon = rtl::OUString(aUIString).lastIndexOf( (sal_Unicode) ':' );
+ if ( nColon >= 0 && nColon < aUIString.Len() - 1 &&
+ aUIString.GetChar((xub_StrLen)nColon+1) == (sal_Unicode) '.' )
+ aUIString.Erase( (xub_StrLen)nColon+1, 1 );
+ }
+
+ // parse the rest like a UI string
+ bSuccess = ParseUIString( aUIString );
+ }
+ }
+ else
+ throw beans::UnknownPropertyException();
+
+ if ( !bSuccess )
+ throw lang::IllegalArgumentException();
+}
+
+uno::Any SAL_CALL ScAddressConversionObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ uno::Any aRet;
+
+ String aNameStr(aPropertyName);
+ if ( aNameStr.EqualsAscii( SC_UNONAME_ADDRESS ) )
+ {
+ if ( bIsRange )
+ {
+ table::CellRangeAddress aRangeAddress;
+ ScUnoConversion::FillApiRange( aRangeAddress, aRange );
+ aRet <<= aRangeAddress;
+ }
+ else
+ {
+ table::CellAddress aCellAddress;
+ ScUnoConversion::FillApiAddress( aCellAddress, aRange.aStart );
+ aRet <<= aCellAddress;
+ }
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNONAME_REFSHEET ) )
+ {
+ aRet <<= nRefSheet;
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNONAME_UIREPR ) )
+ {
+ // generate UI representation string - include sheet only if different from ref sheet
+ String aFormatStr;
+ USHORT nFlags = SCA_VALID;
+ if ( aRange.aStart.Tab() != nRefSheet )
+ nFlags |= SCA_TAB_3D;
+ if ( bIsRange )
+ aRange.Format( aFormatStr, nFlags, pDoc );
+ else
+ aRange.aStart.Format( aFormatStr, nFlags, pDoc );
+ aRet <<= rtl::OUString( aFormatStr );
+ }
+ else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) )
+ {
+ // generate file format string - always include sheet
+ String aFormatStr;
+ aRange.aStart.Format( aFormatStr, SCA_VALID | SCA_TAB_3D, pDoc );
+ if ( bIsRange )
+ {
+ // manually concatenate range so both parts always have the sheet name
+ aFormatStr.Append( (sal_Unicode) ':' );
+ String aSecond;
+ aRange.aEnd.Format( aSecond, SCA_VALID | SCA_TAB_3D, pDoc );
+ aFormatStr.Append( aSecond );
+ }
+ aRet <<= rtl::OUString( aFormatStr );
+ }
+ else
+ throw beans::UnknownPropertyException();
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAddressConversionObj )
+
+// lang::XServiceInfo
+
+rtl::OUString SAL_CALL ScAddressConversionObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScAddressConversionObj" );
+}
+
+sal_Bool SAL_CALL ScAddressConversionObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( bIsRange ? SC_SERVICENAME_RANGEADDRESS
+ : SC_SERVICENAME_CELLADDRESS );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAddressConversionObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( bIsRange ? SC_SERVICENAME_RANGEADDRESS
+ : SC_SERVICENAME_CELLADDRESS );
+ return aRet;
+}
+
diff --git a/sc/source/ui/unoobj/afmtuno.cxx b/sc/source/ui/unoobj/afmtuno.cxx
new file mode 100644
index 000000000000..481c611773ed
--- /dev/null
+++ b/sc/source/ui/unoobj/afmtuno.cxx
@@ -0,0 +1,882 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/memberids.hrc>
+#include <tools/debug.hxx>
+#include <tools/shl.hxx>
+#include <svl/poolitem.hxx>
+#include <svx/unomid.hxx>
+#include "unowids.hxx"
+#include <rtl/uuid.h>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/ShadowLocation.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/util/SortField.hpp>
+#include <com/sun/star/util/SortFieldType.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/awt/SimpleFontMetric.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontWidth.hpp>
+#include <com/sun/star/awt/XFont.hpp>
+#include <com/sun/star/awt/FontType.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontPitch.hpp>
+
+#include "afmtuno.hxx"
+#include "miscuno.hxx"
+#include "autoform.hxx"
+#include "unoguard.hxx"
+#include "scdll.hxx"
+#include "unonames.hxx"
+#include "cellsuno.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+// ein AutoFormat hat immer 16 Eintraege
+#define SC_AF_FIELD_COUNT 16
+
+//------------------------------------------------------------------------
+
+// AutoFormat-Map nur fuer PropertySetInfo, ohne Which-IDs
+
+const SfxItemPropertyMapEntry* lcl_GetAutoFormatMap()
+{
+ static SfxItemPropertyMapEntry aAutoFormatMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_INCBACK), 0, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_INCBORD), 0, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_INCFONT), 0, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_INCJUST), 0, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_INCNUM), 0, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_INCWIDTH), 0, &::getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aAutoFormatMap_Impl;
+}
+
+//! Zahlformat (String/Language) ??? (in XNumberFormat nur ReadOnly)
+//! table::TableBorder ??!?
+
+const SfxItemPropertyMapEntry* lcl_GetAutoFieldMap()
+{
+ static SfxItemPropertyMapEntry aAutoFieldMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT, &::getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &::getCppuType((const sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &::getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &::getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &::getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &::getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &::getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &::getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &::getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &::getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT, &::getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT, &::getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &::getCppuType((const sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &::getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE, &::getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE, &::getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &::getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE, &::getCppuType((const sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &::getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT, &::getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT, &::getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &::getCppuType((const table::CellHoriJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &::getCppuType((const table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &::getCppuType((const table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &::getCppuType((const table::CellVertJustify*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aAutoFieldMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+#define SCAUTOFORMATSOBJ_SERVICE "com.sun.star.sheet.TableAutoFormats"
+
+SC_SIMPLE_SERVICE_INFO( ScAutoFormatFieldObj, "ScAutoFormatFieldObj", "com.sun.star.sheet.TableAutoFormatField" )
+SC_SIMPLE_SERVICE_INFO( ScAutoFormatObj, "ScAutoFormatObj", "com.sun.star.sheet.TableAutoFormat" )
+SC_SIMPLE_SERVICE_INFO( ScAutoFormatsObj, "ScAutoFormatsObj", SCAUTOFORMATSOBJ_SERVICE )
+
+//------------------------------------------------------------------------
+
+sal_Bool lcl_FindAutoFormatIndex( const ScAutoFormat& rFormats, const String& rName, sal_uInt16& rOutIndex )
+{
+ String aEntryName;
+ sal_uInt16 nCount = rFormats.GetCount();
+ for( sal_uInt16 nPos=0; nPos<nCount; nPos++ )
+ {
+ ScAutoFormatData* pEntry = rFormats[nPos];
+ pEntry->GetName( aEntryName );
+ if ( aEntryName == rName )
+ {
+ rOutIndex = nPos;
+ return sal_True;
+ }
+ }
+ return sal_False; // is nich
+}
+
+//------------------------------------------------------------------------
+
+ScAutoFormatsObj::ScAutoFormatsObj()
+{
+ //! Dieses Objekt darf es nur einmal geben, und es muss an den Auto-Format-Daten
+ //! bekannt sein, damit Aenderungen gebroadcasted werden koennen
+}
+
+ScAutoFormatsObj::~ScAutoFormatsObj()
+{
+}
+
+// stuff for exService_...
+
+uno::Reference<uno::XInterface> SAL_CALL ScAutoFormatsObj_CreateInstance(
+ const uno::Reference<lang::XMultiServiceFactory>& )
+{
+ ScUnoGuard aGuard;
+ ScDLL::Init();
+ static uno::Reference< uno::XInterface > xInst((::cppu::OWeakObject*) new ScAutoFormatsObj);
+ return xInst;
+}
+
+rtl::OUString ScAutoFormatsObj::getImplementationName_Static()
+{
+ return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScAutoFormatsObj" );
+}
+
+uno::Sequence<rtl::OUString> ScAutoFormatsObj::getSupportedServiceNames_Static()
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCAUTOFORMATSOBJ_SERVICE );
+ return aRet;
+}
+
+// XTableAutoFormats
+
+ScAutoFormatObj* ScAutoFormatsObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
+{
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats && nIndex < pFormats->GetCount())
+ return new ScAutoFormatObj(nIndex);
+
+ return NULL; // falscher Index
+}
+
+ScAutoFormatObj* ScAutoFormatsObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats)
+ {
+ String aString(aName);
+ sal_uInt16 nIndex;
+ if (lcl_FindAutoFormatIndex( *pFormats, aString, nIndex ))
+ return GetObjectByIndex_Impl(nIndex);
+ }
+ return NULL;
+}
+
+// container::XNameContainer
+
+void SAL_CALL ScAutoFormatsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::ElementExistException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Bool bDone = sal_False;
+ // Reflection muss nicht uno::XInterface sein, kann auch irgendein Interface sein...
+ uno::Reference< uno::XInterface > xInterface(aElement, uno::UNO_QUERY);
+ if ( xInterface.is() )
+ {
+ ScAutoFormatObj* pFormatObj = ScAutoFormatObj::getImplementation( xInterface );
+ if ( pFormatObj && !pFormatObj->IsInserted() ) // noch nicht eingefuegt?
+ {
+ String aNameStr(aName);
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+
+ sal_uInt16 nDummy;
+ if (pFormats && !lcl_FindAutoFormatIndex( *pFormats, aNameStr, nDummy ))
+ {
+ ScAutoFormatData* pNew = new ScAutoFormatData();
+ pNew->SetName( aNameStr );
+
+ if (pFormats->Insert( pNew ))
+ {
+ //! Notify fuer andere Objekte
+ pFormats->Save(); // sofort speichern
+
+ sal_uInt16 nNewIndex;
+ if (lcl_FindAutoFormatIndex( *pFormats, aNameStr, nNewIndex ))
+ {
+ pFormatObj->InitFormat( nNewIndex ); // kann jetzt benutzt werden
+ bDone = sal_True;
+ }
+ }
+ else
+ {
+ delete pNew;
+ DBG_ERROR("AutoFormat konnte nicht eingefuegt werden");
+ throw uno::RuntimeException();
+ }
+ }
+ else
+ {
+ throw container::ElementExistException();
+ }
+ }
+ }
+
+ if (!bDone)
+ {
+ // other errors are handled above
+ throw lang::IllegalArgumentException();
+ }
+}
+
+void SAL_CALL ScAutoFormatsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! zusammenfassen?
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+void SAL_CALL ScAutoFormatsObj::removeByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr(aName);
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+
+ sal_uInt16 nIndex;
+ if (pFormats && lcl_FindAutoFormatIndex( *pFormats, aNameStr, nIndex ))
+ {
+ pFormats->AtFree( nIndex );
+
+ //! Notify fuer andere Objekte
+ pFormats->Save(); // sofort speichern
+ }
+ else
+ {
+ throw container::NoSuchElementException();
+ }
+}
+
+// container::XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScAutoFormatsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.TableAutoFormatEnumeration")));
+}
+
+// container::XIndexAccess
+
+sal_Int32 SAL_CALL ScAutoFormatsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats)
+ return pFormats->GetCount();
+
+ return 0;
+}
+
+uno::Any SAL_CALL ScAutoFormatsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< container::XNamed > xFormat(GetObjectByIndex_Impl((sal_uInt16)nIndex));
+ if (!xFormat.is())
+ throw lang::IndexOutOfBoundsException();
+ return uno::makeAny(xFormat);
+}
+
+uno::Type SAL_CALL ScAutoFormatsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::getCppuType((const uno::Reference< container::XNamed >*)0); // muss zu getByIndex passen
+}
+
+sal_Bool SAL_CALL ScAutoFormatsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// container::XNameAccess
+
+uno::Any SAL_CALL ScAutoFormatsObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< container::XNamed > xFormat(GetObjectByName_Impl(aName));
+ if (!xFormat.is())
+ throw container::NoSuchElementException();
+ return uno::makeAny(xFormat);
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAutoFormatsObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats)
+ {
+ String aName;
+ sal_uInt16 nCount = pFormats->GetCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ (*pFormats)[i]->GetName(aName);
+ pAry[i] = aName;
+ }
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+sal_Bool SAL_CALL ScAutoFormatsObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats)
+ {
+ String aString(aName);
+ sal_uInt16 nDummy;
+ return lcl_FindAutoFormatIndex( *pFormats, aString, nDummy );
+ }
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+ScAutoFormatObj::ScAutoFormatObj(sal_uInt16 nIndex) :
+ aPropSet( lcl_GetAutoFormatMap() ),
+ nFormatIndex( nIndex )
+{
+ //! Listening !!!
+}
+
+ScAutoFormatObj::~ScAutoFormatObj()
+{
+ // Wenn ein AutoFormat-Objekt losgelassen wird, werden eventuelle Aenderungen
+ // gespeichert, damit sie z.B. im Writer sichtbar sind
+
+ if (IsInserted())
+ {
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if ( pFormats && pFormats->IsSaveLater() )
+ pFormats->Save();
+
+ // Save() setzt SaveLater Flag zurueck
+ }
+}
+
+void ScAutoFormatObj::InitFormat( sal_uInt16 nNewIndex )
+{
+ DBG_ASSERT( nFormatIndex == SC_AFMTOBJ_INVALID, "ScAutoFormatObj::InitFormat mehrfach" );
+ nFormatIndex = nNewIndex;
+ //! Listening !!!
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScAutoFormatObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScAutoFormatObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScAutoFormatObj* ScAutoFormatObj::getImplementation(
+ const uno::Reference<uno::XInterface> xObj )
+{
+ ScAutoFormatObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScAutoFormatObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+void ScAutoFormatObj::Notify( SfxBroadcaster& /* rBC */, const SfxHint& /* rHint */ )
+{
+ // spaeter...
+}
+
+// XTableAutoFormat
+
+ScAutoFormatFieldObj* ScAutoFormatObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
+{
+ if ( IsInserted() && nIndex < SC_AF_FIELD_COUNT )
+ return new ScAutoFormatFieldObj( nFormatIndex, nIndex );
+
+ return NULL;
+}
+
+// container::XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScAutoFormatObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.TableAutoFormatEnumeration")));
+}
+
+// container::XIndexAccess
+
+sal_Int32 SAL_CALL ScAutoFormatObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (IsInserted())
+ return SC_AF_FIELD_COUNT; // immer 16 Elemente
+ else
+ return 0;
+}
+
+uno::Any SAL_CALL ScAutoFormatObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( nIndex < 0 || nIndex >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ if (IsInserted())
+ return uno::makeAny(uno::Reference< beans::XPropertySet >(GetObjectByIndex_Impl((sal_uInt16)nIndex)));
+ return uno::Any();
+}
+
+uno::Type SAL_CALL ScAutoFormatObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::getCppuType((const uno::Reference< beans::XPropertySet >*)0); // muss zu getByIndex passen
+}
+
+sal_Bool SAL_CALL ScAutoFormatObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// container::XNamed
+
+rtl::OUString SAL_CALL ScAutoFormatObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount())
+ {
+ String aName;
+ (*pFormats)[nFormatIndex]->GetName(aName);
+ return aName;
+ }
+ return rtl::OUString();
+}
+
+void SAL_CALL ScAutoFormatObj::setName( const rtl::OUString& aNewName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNewString(aNewName);
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+
+ sal_uInt16 nDummy;
+ if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount() &&
+ !lcl_FindAutoFormatIndex( *pFormats, aNewString, nDummy ))
+ {
+ ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
+ DBG_ASSERT(pData,"AutoFormat Daten nicht da");
+
+ ScAutoFormatData* pNew = new ScAutoFormatData(*pData);
+ pNew->SetName( aNewString );
+
+ pFormats->AtFree( nFormatIndex );
+ if (pFormats->Insert( pNew ))
+ {
+ nFormatIndex = pFormats->IndexOf( pNew ); // ist evtl. anders einsortiert...
+
+ //! Notify fuer andere Objekte
+ pFormats->SetSaveLater(sal_True);
+ }
+ else
+ {
+ delete pNew;
+ DBG_ERROR("AutoFormat konnte nicht eingefuegt werden");
+ nFormatIndex = 0; //! alter Index ist ungueltig
+ }
+ }
+ else
+ {
+ // not inserted or name exists
+ throw uno::RuntimeException();
+ }
+}
+
+// beans::XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAutoFormatObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScAutoFormatObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount())
+ {
+ ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
+ DBG_ASSERT(pData,"AutoFormat Daten nicht da");
+
+ String aPropString(aPropertyName);
+ sal_Bool bBool = sal_Bool();
+ if (aPropString.EqualsAscii( SC_UNONAME_INCBACK ) && (aValue >>= bBool))
+ pData->SetIncludeBackground( bBool );
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCBORD ) && (aValue >>= bBool))
+ pData->SetIncludeFrame( bBool );
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCFONT ) && (aValue >>= bBool))
+ pData->SetIncludeFont( bBool );
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCJUST ) && (aValue >>= bBool))
+ pData->SetIncludeJustify( bBool );
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCNUM ) && (aValue >>= bBool))
+ pData->SetIncludeValueFormat( bBool );
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCWIDTH ) && (aValue >>= bBool))
+ pData->SetIncludeWidthHeight( bBool );
+
+ // else Fehler
+
+ //! Notify fuer andere Objekte
+ pFormats->SetSaveLater(sal_True);
+ }
+}
+
+uno::Any SAL_CALL ScAutoFormatObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aAny;
+
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount())
+ {
+ ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
+ DBG_ASSERT(pData,"AutoFormat Daten nicht da");
+
+ sal_Bool bValue;
+ sal_Bool bError = sal_False;
+
+ String aPropString(aPropertyName);
+ if (aPropString.EqualsAscii( SC_UNONAME_INCBACK ))
+ bValue = pData->GetIncludeBackground();
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCBORD ))
+ bValue = pData->GetIncludeFrame();
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCFONT ))
+ bValue = pData->GetIncludeFont();
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCJUST ))
+ bValue = pData->GetIncludeJustify();
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCNUM ))
+ bValue = pData->GetIncludeValueFormat();
+ else if (aPropString.EqualsAscii( SC_UNONAME_INCWIDTH ))
+ bValue = pData->GetIncludeWidthHeight();
+ else
+ bError = sal_True; // unbekannte Property
+
+ if (!bError)
+ aAny <<= bValue;
+ }
+
+ return aAny;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAutoFormatObj )
+
+//------------------------------------------------------------------------
+
+ScAutoFormatFieldObj::ScAutoFormatFieldObj(sal_uInt16 nFormat, sal_uInt16 nField) :
+ aPropSet( lcl_GetAutoFieldMap() ),
+ nFormatIndex( nFormat ),
+ nFieldIndex( nField )
+{
+ //! Listening !!!
+}
+
+ScAutoFormatFieldObj::~ScAutoFormatFieldObj()
+{
+}
+
+void ScAutoFormatFieldObj::Notify( SfxBroadcaster& /* rBC */, const SfxHint& /* rHint */ )
+{
+ // spaeter...
+}
+
+// beans::XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAutoFormatFieldObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScAutoFormatFieldObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ const SfxItemPropertySimpleEntry* pEntry =
+ aPropSet.getPropertyMap()->getByName( aPropertyName );
+
+ if ( pEntry && pEntry->nWID && pFormats && nFormatIndex < pFormats->GetCount() )
+ {
+ ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
+
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ if( const SfxPoolItem* pItem = pData->GetItem( nFieldIndex, pEntry->nWID ) )
+ {
+ sal_Bool bDone = sal_False;
+
+ switch( pEntry->nWID )
+ {
+ case ATTR_STACKED:
+ {
+ table::CellOrientation eOrient;
+ if( aValue >>= eOrient )
+ {
+ switch( eOrient )
+ {
+ case table::CellOrientation_STANDARD:
+ pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, FALSE ) );
+ break;
+ case table::CellOrientation_TOPBOTTOM:
+ pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, FALSE ) );
+ pData->PutItem( nFieldIndex, SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
+ break;
+ case table::CellOrientation_BOTTOMTOP:
+ pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, FALSE ) );
+ pData->PutItem( nFieldIndex, SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
+ break;
+ case table::CellOrientation_STACKED:
+ pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, TRUE ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ bDone = sal_True;
+ }
+ }
+ break;
+ default:
+ SfxPoolItem* pNewItem = pItem->Clone();
+ bDone = pNewItem->PutValue( aValue, pEntry->nMemberId );
+ if (bDone)
+ pData->PutItem( nFieldIndex, *pNewItem );
+ delete pNewItem;
+ }
+
+ if (bDone)
+ //! Notify fuer andere Objekte?
+ pFormats->SetSaveLater(sal_True);
+ }
+ }
+ else
+ {
+ switch (pEntry->nWID)
+ {
+ case SC_WID_UNO_TBLBORD:
+ {
+ table::TableBorder aBorder;
+ if ( aValue >>= aBorder ) // empty = nothing to do
+ {
+ SvxBoxItem aOuter(ATTR_BORDER);
+ SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
+ ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder );
+ pData->PutItem( nFieldIndex, aOuter );
+
+ //! Notify fuer andere Objekte?
+ pFormats->SetSaveLater(sal_True);
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+uno::Any SAL_CALL ScAutoFormatFieldObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aVal;
+
+ ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
+ const SfxItemPropertySimpleEntry* pEntry =
+ aPropSet.getPropertyMap()->getByName( aPropertyName );
+
+ if ( pEntry && pEntry->nWID && pFormats && nFormatIndex < pFormats->GetCount() )
+ {
+ const ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
+
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ if( const SfxPoolItem* pItem = pData->GetItem( nFieldIndex, pEntry->nWID ) )
+ {
+ switch( pEntry->nWID )
+ {
+ case ATTR_STACKED:
+ {
+ const SfxInt32Item* pRotItem = (const SfxInt32Item*)pData->GetItem( nFieldIndex, ATTR_ROTATE_VALUE );
+ sal_Int32 nRot = pRotItem ? pRotItem->GetValue() : 0;
+ BOOL bStacked = ((const SfxBoolItem*)pItem)->GetValue();
+ SvxOrientationItem( nRot, bStacked, 0 ).QueryValue( aVal );
+ }
+ break;
+ default:
+ pItem->QueryValue( aVal, pEntry->nMemberId );
+ }
+ }
+ }
+ else
+ {
+ switch (pEntry->nWID)
+ {
+ case SC_WID_UNO_TBLBORD:
+ {
+ const SfxPoolItem* pItem = pData->GetItem(nFieldIndex, ATTR_BORDER);
+ if (pItem)
+ {
+ SvxBoxItem aOuter(*(static_cast<const SvxBoxItem*>(pItem)));
+ SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
+
+ table::TableBorder aBorder;
+ ScHelperFunctions::FillTableBorder( aBorder, aOuter, aInner );
+ aVal <<= aBorder;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return aVal;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAutoFormatFieldObj )
+
+//------------------------------------------------------------------------
+
+
+
diff --git a/sc/source/ui/unoobj/appluno.cxx b/sc/source/ui/unoobj/appluno.cxx
new file mode 100644
index 000000000000..8b20d9849f47
--- /dev/null
+++ b/sc/source/ui/unoobj/appluno.cxx
@@ -0,0 +1,1086 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "appluno.hxx"
+#include "sal/types.h"
+#include <osl/diagnose.h>
+#include <cppuhelper/factory.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+#include "afmtuno.hxx"
+#include "funcuno.hxx"
+#include "filtuno.hxx"
+#include "miscuno.hxx"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "inputopt.hxx"
+#include "printopt.hxx"
+#include "userlist.hxx"
+#include "sc.hrc" // VAR_ARGS
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "funcdesc.hxx"
+#include <com/sun/star/sheet/FunctionArgument.hpp>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+// Calc document
+extern uno::Sequence< rtl::OUString > SAL_CALL ScDocument_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScDocument_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScDocument_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr, const sal_uInt64 _nCreationFlags ) throw( uno::Exception );
+
+// Calc XML import
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLImport_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Meta_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLImport_Meta_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Styles_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLImport_Styles_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Content_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLImport_Content_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Settings_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLImport_Settings_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+
+// Calc XML export
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOOoExport_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Meta_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOOoExport_Meta_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Styles_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOOoExport_Styles_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Content_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOOoExport_Content_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Settings_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOOoExport_Settings_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+
+// Calc XML Oasis export
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOasisExport_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Meta_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOasisExport_Meta_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Styles_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOasisExport_Styles_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Content_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOasisExport_Content_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+extern uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Settings_getSupportedServiceNames() throw();
+extern rtl::OUString SAL_CALL ScXMLOasisExport_Settings_getImplementationName() throw();
+extern uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception );
+
+//------------------------------------------------------------------------
+
+// Anzahl der Funktionen, die als zuletzt benutzt gespeichert werden
+//! Define mit funcpage.hxx und dwfunctr.hxx zusammenfassen !!!
+#define LRU_MAX 10
+
+// Spezial-Werte fuer Zoom
+//! irgendwo zentral
+#define SC_ZOOMVAL_OPTIMAL (-1)
+#define SC_ZOOMVAL_WHOLEPAGE (-2)
+#define SC_ZOOMVAL_PAGEWIDTH (-3)
+
+// Anzahl der PropertyValues in einer Function-Description
+#define SC_FUNCDESC_PROPCOUNT 5
+
+//------------------------------------------------------------------------
+
+// alles ohne Which-ID, Map nur fuer PropertySetInfo
+
+static const SfxItemPropertyMapEntry* lcl_GetSettingsPropertyMap()
+{
+ static SfxItemPropertyMapEntry aSettingsPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_DOAUTOCP), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ENTERED), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_EXPREF), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_EXTFMT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_LINKUPD), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_MARKHDR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_METRIC), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_MOVEDIR), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_MOVESEL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_PRALLSH), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_PREMPTY), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_RANGEFIN), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SCALE), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_STBFUNC), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ULISTS), 0, &getCppuType((uno::Sequence<rtl::OUString>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_PRMETRICS),0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_USETABCOL),0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_REPLWARN), 0, &getBooleanCppuType(), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aSettingsPropertyMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+#define SCFUNCTIONLISTOBJ_SERVICE "com.sun.star.sheet.FunctionDescriptions"
+#define SCRECENTFUNCTIONSOBJ_SERVICE "com.sun.star.sheet.RecentFunctions"
+#define SCSPREADSHEETSETTINGS_SERVICE "com.sun.star.sheet.GlobalSheetSettings"
+
+SC_SIMPLE_SERVICE_INFO( ScFunctionListObj, "ScFunctionListObj", SCFUNCTIONLISTOBJ_SERVICE )
+SC_SIMPLE_SERVICE_INFO( ScRecentFunctionsObj, "ScRecentFunctionsObj", SCRECENTFUNCTIONSOBJ_SERVICE )
+SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettings, "ScSpreadsheetSettings", SCSPREADSHEETSETTINGS_SERVICE )
+
+//------------------------------------------------------------------------
+
+static void lcl_WriteInfo( registry::XRegistryKey* pRegistryKey,
+ const rtl::OUString& rImplementationName,
+ const uno::Sequence< rtl::OUString >& rServices )
+ throw( registry::InvalidRegistryException )
+{
+ rtl::OUString aImpl(rtl::OUString::createFromAscii( "/" ));
+ aImpl += rImplementationName;
+ aImpl += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+ uno::Reference<registry::XRegistryKey> xNewKey(pRegistryKey->createKey(aImpl));
+
+ const rtl::OUString* pArray = rServices.getConstArray();
+ for( sal_Int32 i = 0; i < rServices.getLength(); i++ )
+ xNewKey->createKey( pArray[i]);
+}
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
+ void * /* pServiceManager */, registry::XRegistryKey * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ lcl_WriteInfo( pRegistryKey,
+ ScSpreadsheetSettings::getImplementationName_Static(),
+ ScSpreadsheetSettings::getSupportedServiceNames_Static() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScRecentFunctionsObj::getImplementationName_Static(),
+ ScRecentFunctionsObj::getSupportedServiceNames_Static() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScFunctionListObj::getImplementationName_Static(),
+ ScFunctionListObj::getSupportedServiceNames_Static() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScAutoFormatsObj::getImplementationName_Static(),
+ ScAutoFormatsObj::getSupportedServiceNames_Static() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScFunctionAccess::getImplementationName_Static(),
+ ScFunctionAccess::getSupportedServiceNames_Static() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScFilterOptionsObj::getImplementationName_Static(),
+ ScFilterOptionsObj::getSupportedServiceNames_Static() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLImport_getImplementationName(),
+ ScXMLImport_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLImport_Meta_getImplementationName(),
+ ScXMLImport_Meta_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLImport_Styles_getImplementationName(),
+ ScXMLImport_Styles_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLImport_Content_getImplementationName(),
+ ScXMLImport_Content_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLImport_Settings_getImplementationName(),
+ ScXMLImport_Settings_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOOoExport_getImplementationName(),
+ ScXMLOOoExport_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOOoExport_Meta_getImplementationName(),
+ ScXMLOOoExport_Meta_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOOoExport_Styles_getImplementationName(),
+ ScXMLOOoExport_Styles_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOOoExport_Content_getImplementationName(),
+ ScXMLOOoExport_Content_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOOoExport_Settings_getImplementationName(),
+ ScXMLOOoExport_Settings_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOasisExport_getImplementationName(),
+ ScXMLOasisExport_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOasisExport_Meta_getImplementationName(),
+ ScXMLOasisExport_Meta_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOasisExport_Styles_getImplementationName(),
+ ScXMLOasisExport_Styles_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOasisExport_Content_getImplementationName(),
+ ScXMLOasisExport_Content_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScXMLOasisExport_Settings_getImplementationName(),
+ ScXMLOasisExport_Settings_getSupportedServiceNames() );
+
+ lcl_WriteInfo( pRegistryKey,
+ ScDocument_getImplementationName(),
+ ScDocument_getSupportedServiceNames() );
+
+ return sal_True;
+ }
+ catch (registry::InvalidRegistryException&)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
+{
+ if (!pServiceManager)
+ return NULL;
+
+ uno::Reference<lang::XSingleServiceFactory> xFactory;
+ rtl::OUString aImpl(rtl::OUString::createFromAscii(pImplName));
+
+ if ( aImpl == ScSpreadsheetSettings::getImplementationName_Static() )
+ xFactory.set(cppu::createOneInstanceFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScSpreadsheetSettings::getImplementationName_Static(),
+ ScSpreadsheetSettings_CreateInstance,
+ ScSpreadsheetSettings::getSupportedServiceNames_Static() ));
+
+ if ( aImpl == ScRecentFunctionsObj::getImplementationName_Static() )
+ xFactory.set(cppu::createOneInstanceFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScRecentFunctionsObj::getImplementationName_Static(),
+ ScRecentFunctionsObj_CreateInstance,
+ ScRecentFunctionsObj::getSupportedServiceNames_Static() ));
+
+ if ( aImpl == ScFunctionListObj::getImplementationName_Static() )
+ xFactory.set(cppu::createOneInstanceFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScFunctionListObj::getImplementationName_Static(),
+ ScFunctionListObj_CreateInstance,
+ ScFunctionListObj::getSupportedServiceNames_Static() ));
+
+ if ( aImpl == ScAutoFormatsObj::getImplementationName_Static() )
+ xFactory.set(cppu::createOneInstanceFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScAutoFormatsObj::getImplementationName_Static(),
+ ScAutoFormatsObj_CreateInstance,
+ ScAutoFormatsObj::getSupportedServiceNames_Static() ));
+
+ if ( aImpl == ScFunctionAccess::getImplementationName_Static() )
+ xFactory.set(cppu::createOneInstanceFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScFunctionAccess::getImplementationName_Static(),
+ ScFunctionAccess_CreateInstance,
+ ScFunctionAccess::getSupportedServiceNames_Static() ));
+
+ if ( aImpl == ScFilterOptionsObj::getImplementationName_Static() )
+ xFactory.set(cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScFilterOptionsObj::getImplementationName_Static(),
+ ScFilterOptionsObj_CreateInstance,
+ ScFilterOptionsObj::getSupportedServiceNames_Static() ));
+
+ if ( aImpl == ScXMLImport_getImplementationName() )
+ xFactory.set(cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLImport_getImplementationName(),
+ ScXMLImport_createInstance,
+ ScXMLImport_getSupportedServiceNames() ));
+
+ if ( aImpl == ScXMLImport_Meta_getImplementationName() )
+ xFactory.set(cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLImport_Meta_getImplementationName(),
+ ScXMLImport_Meta_createInstance,
+ ScXMLImport_Meta_getSupportedServiceNames() ));
+
+ if ( aImpl == ScXMLImport_Styles_getImplementationName() )
+ xFactory.set(cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLImport_Styles_getImplementationName(),
+ ScXMLImport_Styles_createInstance,
+ ScXMLImport_Styles_getSupportedServiceNames() ));
+
+ if ( aImpl == ScXMLImport_Content_getImplementationName() )
+ xFactory.set(cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLImport_Content_getImplementationName(),
+ ScXMLImport_Content_createInstance,
+ ScXMLImport_Content_getSupportedServiceNames() ));
+
+ if ( aImpl == ScXMLImport_Settings_getImplementationName() )
+ xFactory.set(cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLImport_Settings_getImplementationName(),
+ ScXMLImport_Settings_createInstance,
+ ScXMLImport_Settings_getSupportedServiceNames() ));
+
+ if ( aImpl == ScXMLOOoExport_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOOoExport_getImplementationName(),
+ ScXMLOOoExport_createInstance,
+ ScXMLOOoExport_getSupportedServiceNames() );
+
+ if ( aImpl == ScXMLOOoExport_Meta_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOOoExport_Meta_getImplementationName(),
+ ScXMLOOoExport_Meta_createInstance,
+ ScXMLOOoExport_Meta_getSupportedServiceNames() );
+
+ if ( aImpl == ScXMLOOoExport_Styles_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOOoExport_Styles_getImplementationName(),
+ ScXMLOOoExport_Styles_createInstance,
+ ScXMLOOoExport_Styles_getSupportedServiceNames() );
+
+ if ( aImpl == ScXMLOOoExport_Content_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOOoExport_Content_getImplementationName(),
+ ScXMLOOoExport_Content_createInstance,
+ ScXMLOOoExport_Content_getSupportedServiceNames() );
+
+ if ( aImpl == ScXMLOOoExport_Settings_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOOoExport_Settings_getImplementationName(),
+ ScXMLOOoExport_Settings_createInstance,
+ ScXMLOOoExport_Settings_getSupportedServiceNames() );
+
+ if ( aImpl == ScXMLOasisExport_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOasisExport_getImplementationName(),
+ ScXMLOasisExport_createInstance,
+ ScXMLOasisExport_getSupportedServiceNames() );
+ if ( aImpl == ScXMLOasisExport_Meta_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOasisExport_Meta_getImplementationName(),
+ ScXMLOasisExport_Meta_createInstance,
+ ScXMLOasisExport_Meta_getSupportedServiceNames() );
+ if ( aImpl == ScXMLOasisExport_Styles_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOasisExport_Styles_getImplementationName(),
+ ScXMLOasisExport_Styles_createInstance,
+ ScXMLOasisExport_Styles_getSupportedServiceNames() );
+ if ( aImpl == ScXMLOasisExport_Content_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOasisExport_Content_getImplementationName(),
+ ScXMLOasisExport_Content_createInstance,
+ ScXMLOasisExport_Content_getSupportedServiceNames() );
+ if ( aImpl == ScXMLOasisExport_Settings_getImplementationName() )
+ xFactory = cppu::createSingleFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScXMLOasisExport_Settings_getImplementationName(),
+ ScXMLOasisExport_Settings_createInstance,
+ ScXMLOasisExport_Settings_getSupportedServiceNames() );
+
+ if ( aImpl == ScDocument_getImplementationName() )
+ xFactory.set(sfx2::createSfxModelFactory(
+ reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
+ ScDocument_getImplementationName(),
+ ScDocument_createInstance,
+ ScDocument_getSupportedServiceNames() ));
+
+ void* pRet = NULL;
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+}
+
+} // extern C
+
+//------------------------------------------------------------------------
+
+ScSpreadsheetSettings::ScSpreadsheetSettings() :
+ aPropSet( lcl_GetSettingsPropertyMap() )
+{
+}
+
+ScSpreadsheetSettings::~ScSpreadsheetSettings()
+{
+}
+
+uno::Reference<uno::XInterface> SAL_CALL ScSpreadsheetSettings_CreateInstance(
+ const uno::Reference<lang::XMultiServiceFactory>& /* rSMgr */ )
+{
+ ScUnoGuard aGuard;
+ ScDLL::Init();
+ static uno::Reference<uno::XInterface> xInst((cppu::OWeakObject*)new ScSpreadsheetSettings());
+ return xInst;
+}
+
+rtl::OUString ScSpreadsheetSettings::getImplementationName_Static()
+{
+ return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScSpreadsheetSettings" );
+}
+
+uno::Sequence<rtl::OUString> ScSpreadsheetSettings::getSupportedServiceNames_Static()
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSPREADSHEETSETTINGS_SERVICE );
+ return aRet;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettings::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScSpreadsheetSettings::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aAppOpt(pScMod->GetAppOptions());
+ ScInputOptions aInpOpt(pScMod->GetInputOptions());
+ BOOL bSaveApp = FALSE;
+ BOOL bSaveInp = FALSE;
+ // print options aren't loaded until needed
+
+ if (aString.EqualsAscii( SC_UNONAME_DOAUTOCP ))
+ {
+ aAppOpt.SetAutoComplete( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveApp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_ENTERED ))
+ {
+ aInpOpt.SetEnterEdit( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_EXPREF ))
+ {
+ aInpOpt.SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_EXTFMT ))
+ {
+ aInpOpt.SetExtendFormat( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_LINKUPD ))
+ {
+ aAppOpt.SetLinkMode( (ScLkUpdMode) ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ bSaveApp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_MARKHDR ))
+ {
+ aInpOpt.SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_MOVESEL ))
+ {
+ aInpOpt.SetMoveSelection( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_RANGEFIN ))
+ {
+ aInpOpt.SetRangeFinder( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_USETABCOL ))
+ {
+ aInpOpt.SetUseTabCol( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_PRMETRICS ))
+ {
+ aInpOpt.SetTextWysiwyg( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_REPLWARN ))
+ {
+ aInpOpt.SetReplaceCellsWarn( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_METRIC ))
+ {
+ aAppOpt.SetAppMetric( (FieldUnit) ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ bSaveApp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_MOVEDIR ))
+ {
+ aInpOpt.SetMoveDir( ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ bSaveInp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_SCALE ))
+ {
+ short nVal = ScUnoHelpFunctions::GetInt16FromAny( aValue );
+ if ( nVal < 0 )
+ {
+ SvxZoomType eType = SVX_ZOOM_PERCENT;
+ switch (nVal)
+ {
+ case SC_ZOOMVAL_OPTIMAL: eType = SVX_ZOOM_OPTIMAL; break;
+ case SC_ZOOMVAL_WHOLEPAGE: eType = SVX_ZOOM_WHOLEPAGE; break;
+ case SC_ZOOMVAL_PAGEWIDTH: eType = SVX_ZOOM_PAGEWIDTH; break;
+ }
+ aAppOpt.SetZoomType( eType );
+ }
+ else if ( nVal >= MINZOOM && nVal <= MAXZOOM )
+ {
+ aAppOpt.SetZoom( nVal );
+ aAppOpt.SetZoomType( SVX_ZOOM_PERCENT );
+ }
+ bSaveApp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_STBFUNC ))
+ {
+ aAppOpt.SetStatusFunc( ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ bSaveApp = TRUE;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_ULISTS ))
+ {
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ uno::Sequence<rtl::OUString> aSeq;
+ if ( pUserList && ( aValue >>= aSeq ) )
+ {
+ // es wird direkt die "lebende" Liste veraendert,
+ // mehr tut ScGlobal::SetUserList auch nicht
+
+ pUserList->FreeAll(); // alle Eintraege raus
+ USHORT nCount = (USHORT)aSeq.getLength();
+ const rtl::OUString* pAry = aSeq.getConstArray();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ String aEntry = pAry[i];
+ ScUserListData* pData = new ScUserListData(aEntry);
+ if (!pUserList->Insert(pData)) // hinten anhaengen
+ delete pData; // sollte nicht vorkommen
+ }
+ bSaveApp = TRUE; // Liste wird mit den App-Optionen gespeichert
+ }
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_PRALLSH ))
+ {
+ ScPrintOptions aPrintOpt(pScMod->GetPrintOptions());
+ aPrintOpt.SetAllSheets( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ pScMod->SetPrintOptions( aPrintOpt );
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_PREMPTY ))
+ {
+ ScPrintOptions aPrintOpt(pScMod->GetPrintOptions());
+ aPrintOpt.SetSkipEmpty( !ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); // reversed
+ pScMod->SetPrintOptions( aPrintOpt );
+ SFX_APP()->Broadcast( SfxSimpleHint( SID_SCPRINTOPTIONS ) ); // update previews
+ }
+
+ if ( bSaveApp )
+ pScMod->SetAppOptions( aAppOpt );
+ if ( bSaveInp )
+ pScMod->SetInputOptions( aInpOpt );
+}
+
+uno::Any SAL_CALL ScSpreadsheetSettings::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString = aPropertyName;
+ uno::Any aRet;
+
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aAppOpt = pScMod->GetAppOptions();
+ ScInputOptions aInpOpt = pScMod->GetInputOptions();
+ // print options aren't loaded until needed
+
+ if (aString.EqualsAscii( SC_UNONAME_DOAUTOCP )) ScUnoHelpFunctions::SetBoolInAny( aRet, aAppOpt.GetAutoComplete() );
+ else if (aString.EqualsAscii( SC_UNONAME_ENTERED )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetEnterEdit() );
+ else if (aString.EqualsAscii( SC_UNONAME_EXPREF )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetExpandRefs() );
+ else if (aString.EqualsAscii( SC_UNONAME_EXTFMT )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetExtendFormat() );
+ else if (aString.EqualsAscii( SC_UNONAME_LINKUPD )) aRet <<= (sal_Int16) aAppOpt.GetLinkMode();
+ else if (aString.EqualsAscii( SC_UNONAME_MARKHDR )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetMarkHeader() );
+ else if (aString.EqualsAscii( SC_UNONAME_MOVESEL )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetMoveSelection() );
+ else if (aString.EqualsAscii( SC_UNONAME_RANGEFIN )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetRangeFinder() );
+ else if (aString.EqualsAscii( SC_UNONAME_USETABCOL )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetUseTabCol() );
+ else if (aString.EqualsAscii( SC_UNONAME_PRMETRICS )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetTextWysiwyg() );
+ else if (aString.EqualsAscii( SC_UNONAME_REPLWARN )) ScUnoHelpFunctions::SetBoolInAny( aRet, aInpOpt.GetReplaceCellsWarn() );
+ else if (aString.EqualsAscii( SC_UNONAME_METRIC )) aRet <<= (sal_Int16) aAppOpt.GetAppMetric();
+ else if (aString.EqualsAscii( SC_UNONAME_MOVEDIR )) aRet <<= (sal_Int16) aInpOpt.GetMoveDir();
+ else if (aString.EqualsAscii( SC_UNONAME_STBFUNC )) aRet <<= (sal_Int16) aAppOpt.GetStatusFunc();
+ else if (aString.EqualsAscii( SC_UNONAME_SCALE ))
+ {
+ INT16 nZoomVal = 0;
+ switch ( aAppOpt.GetZoomType() )
+ {
+ case SVX_ZOOM_PERCENT: nZoomVal = aAppOpt.GetZoom(); break;
+ case SVX_ZOOM_OPTIMAL: nZoomVal = SC_ZOOMVAL_OPTIMAL; break;
+ case SVX_ZOOM_WHOLEPAGE: nZoomVal = SC_ZOOMVAL_WHOLEPAGE; break;
+ case SVX_ZOOM_PAGEWIDTH: nZoomVal = SC_ZOOMVAL_PAGEWIDTH; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ aRet <<= (sal_Int16) nZoomVal;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_ULISTS ))
+ {
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (pUserList)
+ {
+ USHORT nCount = pUserList->GetCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ String aEntry((*pUserList)[i]->GetString());
+ pAry[i] = aEntry;
+ }
+ aRet <<= aSeq;
+ }
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_PRALLSH ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pScMod->GetPrintOptions().GetAllSheets() );
+ else if (aString.EqualsAscii( SC_UNONAME_PREMPTY ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, !pScMod->GetPrintOptions().GetSkipEmpty() ); // reversed
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettings )
+
+//------------------------------------------------------------------------
+
+ScRecentFunctionsObj::ScRecentFunctionsObj()
+{
+}
+
+ScRecentFunctionsObj::~ScRecentFunctionsObj()
+{
+}
+
+// stuff for exService_...
+
+uno::Reference<uno::XInterface> SAL_CALL ScRecentFunctionsObj_CreateInstance(
+ const uno::Reference<lang::XMultiServiceFactory>& /* rSMgr */ )
+{
+ ScUnoGuard aGuard;
+ ScDLL::Init();
+ static uno::Reference<uno::XInterface> xInst((cppu::OWeakObject*)new ScRecentFunctionsObj());
+ return xInst;
+}
+
+rtl::OUString ScRecentFunctionsObj::getImplementationName_Static()
+{
+ return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScRecentFunctionsObj" );
+}
+
+uno::Sequence<rtl::OUString> ScRecentFunctionsObj::getSupportedServiceNames_Static()
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCRECENTFUNCTIONSOBJ_SERVICE );
+ return aRet;
+}
+
+// XRecentFunctions
+
+uno::Sequence<sal_Int32> SAL_CALL ScRecentFunctionsObj::getRecentFunctionIds()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
+ USHORT nCount = rOpt.GetLRUFuncListCount();
+ const USHORT* pFuncs = rOpt.GetLRUFuncList();
+ if (pFuncs)
+ {
+ uno::Sequence<sal_Int32> aSeq(nCount);
+ sal_Int32* pAry = aSeq.getArray();
+ for (USHORT i=0; i<nCount; i++)
+ pAry[i] = pFuncs[i];
+ return aSeq;
+ }
+ return uno::Sequence<sal_Int32>(0);
+}
+
+void SAL_CALL ScRecentFunctionsObj::setRecentFunctionIds(
+ const uno::Sequence<sal_Int32>& aRecentFunctionIds )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = (USHORT) Min( aRecentFunctionIds.getLength(), (INT32) LRU_MAX );
+ const INT32* pAry = aRecentFunctionIds.getConstArray();
+
+ USHORT* pFuncs = nCount ? new USHORT[nCount] : NULL;
+ for (USHORT i=0; i<nCount; i++)
+ pFuncs[i] = (USHORT)pAry[i]; //! auf gueltige Werte testen?
+
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aNewOpts(pScMod->GetAppOptions());
+ aNewOpts.SetLRUFuncList(pFuncs, nCount);
+ pScMod->SetAppOptions(aNewOpts);
+
+ pScMod->RecentFunctionsChanged(); // update function list child window
+
+ delete[] pFuncs;
+}
+
+sal_Int32 SAL_CALL ScRecentFunctionsObj::getMaxRecentFunctions() throw(uno::RuntimeException)
+{
+ return LRU_MAX;
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionListObj::ScFunctionListObj()
+{
+}
+
+ScFunctionListObj::~ScFunctionListObj()
+{
+}
+
+// stuff for exService_...
+
+uno::Reference<uno::XInterface> SAL_CALL ScFunctionListObj_CreateInstance(
+ const uno::Reference<lang::XMultiServiceFactory>& /* rSMgr */ )
+{
+ ScUnoGuard aGuard;
+ ScDLL::Init();
+ static uno::Reference<uno::XInterface> xInst((cppu::OWeakObject*)new ScFunctionListObj());
+ return xInst;
+}
+
+rtl::OUString ScFunctionListObj::getImplementationName_Static()
+{
+ return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScFunctionListObj" );
+}
+
+uno::Sequence<rtl::OUString> ScFunctionListObj::getSupportedServiceNames_Static()
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCFUNCTIONLISTOBJ_SERVICE );
+ return aRet;
+}
+
+
+static void lcl_FillSequence( uno::Sequence<beans::PropertyValue>& rSequence, const ScFuncDesc& rDesc )
+{
+ rDesc.initArgumentInfo(); // full argument info is needed
+
+ DBG_ASSERT( rSequence.getLength() == SC_FUNCDESC_PROPCOUNT, "Falscher Count" );
+
+ beans::PropertyValue* pArray = rSequence.getArray();
+
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_ID );
+ pArray[0].Value <<= (sal_Int32) rDesc.nFIndex;
+
+ pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_CATEGORY );
+ pArray[1].Value <<= (sal_Int32) rDesc.nCategory;
+
+ pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_NAME );
+ if (rDesc.pFuncName)
+ pArray[2].Value <<= rtl::OUString( *rDesc.pFuncName );
+
+ pArray[3].Name = rtl::OUString::createFromAscii( SC_UNONAME_DESCRIPTION );
+ if (rDesc.pFuncDesc)
+ pArray[3].Value <<= rtl::OUString( *rDesc.pFuncDesc );
+
+ pArray[4].Name = rtl::OUString::createFromAscii( SC_UNONAME_ARGUMENTS );
+ if (rDesc.ppDefArgNames && rDesc.ppDefArgDescs && rDesc.pDefArgFlags )
+ {
+ USHORT nCount = rDesc.nArgCount;
+ if (nCount >= VAR_ARGS)
+ nCount -= VAR_ARGS - 1;
+ USHORT nSeqCount = rDesc.GetSuppressedArgCount();
+ if (nSeqCount >= VAR_ARGS)
+ nSeqCount -= VAR_ARGS - 1;
+
+ if (nSeqCount)
+ {
+ uno::Sequence<sheet::FunctionArgument> aArgSeq(nSeqCount);
+ sheet::FunctionArgument* pArgAry = aArgSeq.getArray();
+ for (USHORT i=0, j=0; i<nCount; i++)
+ {
+ if (!rDesc.pDefArgFlags[i].bSuppress)
+ {
+ String aArgName;
+ if (rDesc.ppDefArgNames[i]) aArgName = *rDesc.ppDefArgNames[i];
+ String aArgDesc;
+ if (rDesc.ppDefArgDescs[i]) aArgDesc = *rDesc.ppDefArgDescs[i];
+ sheet::FunctionArgument aArgument;
+ aArgument.Name = aArgName;
+ aArgument.Description = aArgDesc;
+ aArgument.IsOptional = rDesc.pDefArgFlags[i].bOptional;
+ pArgAry[j++] = aArgument;
+ }
+ }
+ pArray[4].Value <<= aArgSeq;
+ }
+ }
+}
+
+// XFunctionDescriptions
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScFunctionListObj::getById( sal_Int32 nId )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ USHORT nCount = (USHORT)pFuncList->GetCount();
+ for (USHORT nIndex=0; nIndex<nCount; nIndex++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction(nIndex);
+ if ( pDesc && pDesc->nFIndex == nId )
+ {
+ uno::Sequence<beans::PropertyValue> aSeq( SC_FUNCDESC_PROPCOUNT );
+ lcl_FillSequence( aSeq, *pDesc );
+ return aSeq;
+ }
+ }
+
+ throw lang::IllegalArgumentException(); // not found
+ }
+ else
+ throw uno::RuntimeException(); // should not happen
+
+// return uno::Sequence<beans::PropertyValue>(0);
+}
+
+// XNameAccess
+
+uno::Any SAL_CALL ScFunctionListObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr(aName);
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ USHORT nCount = (USHORT)pFuncList->GetCount();
+ for (USHORT nIndex=0; nIndex<nCount; nIndex++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction(nIndex);
+ //! Case-insensitiv ???
+ if ( pDesc && pDesc->pFuncName && aNameStr == *pDesc->pFuncName )
+ {
+ uno::Sequence<beans::PropertyValue> aSeq( SC_FUNCDESC_PROPCOUNT );
+ lcl_FillSequence( aSeq, *pDesc );
+ return uno::makeAny(aSeq);
+ }
+ }
+
+ throw container::NoSuchElementException(); // not found
+ }
+ else
+ throw uno::RuntimeException(); // should not happen
+
+// return uno::Any();
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScFunctionListObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = 0;
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ nCount = (USHORT)pFuncList->GetCount();
+ return nCount;
+}
+
+uno::Any SAL_CALL ScFunctionListObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ if ( nIndex >= 0 && nIndex < (sal_Int32)pFuncList->GetCount() )
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction(nIndex);
+ if ( pDesc )
+ {
+ uno::Sequence<beans::PropertyValue> aSeq( SC_FUNCDESC_PROPCOUNT );
+ lcl_FillSequence( aSeq, *pDesc );
+ return uno::makeAny(aSeq);
+ }
+ }
+
+ throw lang::IndexOutOfBoundsException(); // illegal index
+ }
+ else
+ throw uno::RuntimeException(); // should not happen
+
+// return uno::Any();
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScFunctionListObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.FunctionDescriptionEnumeration")));
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScFunctionListObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Sequence<beans::PropertyValue>*)0);
+}
+
+sal_Bool SAL_CALL ScFunctionListObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() > 0 );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScFunctionListObj::getElementNames() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ USHORT nCount = (USHORT)pFuncList->GetCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (USHORT nIndex=0; nIndex<nCount; nIndex++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction(nIndex);
+ if ( pDesc && pDesc->pFuncName )
+ pAry[nIndex] = *pDesc->pFuncName;
+ }
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+sal_Bool SAL_CALL ScFunctionListObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr(aName);
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ USHORT nCount = (USHORT)pFuncList->GetCount();
+ for (USHORT nIndex=0; nIndex<nCount; nIndex++)
+ {
+ const ScFuncDesc* pDesc = pFuncList->GetFunction(nIndex);
+ //! Case-insensitiv ???
+ if ( pDesc && pDesc->pFuncName && aNameStr == *pDesc->pFuncName )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+
+
+
diff --git a/sc/source/ui/unoobj/celllistsource.cxx b/sc/source/ui/unoobj/celllistsource.cxx
new file mode 100644
index 000000000000..246555d06f25
--- /dev/null
+++ b/sc/source/ui/unoobj/celllistsource.cxx
@@ -0,0 +1,449 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "celllistsource.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+//.........................................................................
+namespace calc
+{
+//.........................................................................
+
+#define PROP_HANDLE_RANGE_ADDRESS 1
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::table;
+ using namespace ::com::sun::star::text;
+ using namespace ::com::sun::star::sheet;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::form::binding;
+
+ //=====================================================================
+ //= OCellListSource
+ //=====================================================================
+ DBG_NAME( OCellListSource )
+ //---------------------------------------------------------------------
+#ifdef DBG_UTIL
+ const char* OCellListSource::checkConsistency_static( const void* _pThis )
+ {
+ return static_cast< const OCellListSource* >( _pThis )->checkConsistency( );
+ }
+
+ const char* OCellListSource::checkConsistency( ) const
+ {
+ const char* pAssertion = NULL;
+
+ // TODO: place any checks here to ensure consistency of this instance
+
+ return pAssertion;
+ }
+#endif
+
+ //---------------------------------------------------------------------
+ OCellListSource::OCellListSource( const Reference< XSpreadsheetDocument >& _rxDocument )
+ :OCellListSource_Base( m_aMutex )
+ ,OCellListSource_PBase( OCellListSource_Base::rBHelper )
+ ,m_xDocument( _rxDocument )
+ ,m_aListEntryListeners( m_aMutex )
+ ,m_bInitialized( sal_False )
+ {
+ DBG_CTOR( OCellListSource, checkConsistency_static );
+
+ OSL_PRECOND( m_xDocument.is(), "OCellListSource::OCellListSource: invalid document!" );
+
+ // register our property at the base class
+ CellRangeAddress aInitialPropValue;
+ registerPropertyNoMember(
+ ::rtl::OUString::createFromAscii( "CellRange" ),
+ PROP_HANDLE_RANGE_ADDRESS,
+ PropertyAttribute::BOUND | PropertyAttribute::READONLY,
+ ::getCppuType( &aInitialPropValue ),
+ &aInitialPropValue
+ );
+ }
+
+ //---------------------------------------------------------------------
+ OCellListSource::~OCellListSource( )
+ {
+ if ( !OCellListSource_Base::rBHelper.bDisposed )
+ {
+ acquire(); // prevent duplicate dtor
+ dispose();
+ }
+
+ DBG_DTOR( OCellListSource, checkConsistency_static );
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XINTERFACE2( OCellListSource, OCellListSource_Base, OCellListSource_PBase )
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCellListSource, OCellListSource_Base, OCellListSource_PBase )
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::disposing()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+
+ Reference<XModifyBroadcaster> xBroadcaster( m_xRange, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ {
+ xBroadcaster->removeModifyListener( this );
+ }
+
+ EventObject aDisposeEvent( *this );
+ m_aListEntryListeners.disposeAndClear( aDisposeEvent );
+
+// OCellListSource_Base::disposing();
+ WeakAggComponentImplHelperBase::disposing();
+
+ // TODO: clean up here whatever you need to clean up (e.g. revoking listeners etc.)
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XPropertySetInfo > SAL_CALL OCellListSource::getPropertySetInfo( ) throw(RuntimeException)
+ {
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ return createPropertySetInfo( getInfoHelper() ) ;
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper& SAL_CALL OCellListSource::getInfoHelper()
+ {
+ return *OCellListSource_PABase::getArrayHelper();
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper* OCellListSource::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper(aProps);
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ DBG_ASSERT( _nHandle == PROP_HANDLE_RANGE_ADDRESS, "OCellListSource::getFastPropertyValue: invalid handle!" );
+ // we only have this one property ....
+ (void)_nHandle; // avoid warning in product version
+
+ _rValue <<= getRangeAddress( );
+ }
+
+ //--------------------------------------------------------------------
+ void OCellListSource::checkDisposed( ) const SAL_THROW( ( DisposedException ) )
+ {
+ if ( OCellListSource_Base::rBHelper.bInDispose || OCellListSource_Base::rBHelper.bDisposed )
+ throw DisposedException();
+ // TODO: is it worth having an error message here?
+ }
+
+ //--------------------------------------------------------------------
+ void OCellListSource::checkInitialized() SAL_THROW( ( RuntimeException ) )
+ {
+ if ( !m_bInitialized )
+ throw RuntimeException();
+ // TODO: error message
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OCellListSource::getImplementationName( ) throw (RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sheet.OCellListSource" ) );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SAL_CALL OCellListSource::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() );
+ const ::rtl::OUString* pLookup = aSupportedServices.getConstArray();
+ const ::rtl::OUString* pLookupEnd = aSupportedServices.getConstArray() + aSupportedServices.getLength();
+ while ( pLookup != pLookupEnd )
+ if ( *pLookup++ == _rServiceName )
+ return sal_True;
+
+ return sal_False;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OCellListSource::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.table.CellRangeListSource" ) );
+ aServices[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.binding.ListEntrySource" ) );
+ return aServices;
+ }
+
+ //--------------------------------------------------------------------
+ CellRangeAddress OCellListSource::getRangeAddress( ) const
+ {
+ OSL_PRECOND( m_xRange.is(), "OCellListSource::getRangeAddress: invalid range!" );
+
+ CellRangeAddress aAddress;
+ Reference< XCellRangeAddressable > xRangeAddress( m_xRange, UNO_QUERY );
+ if ( xRangeAddress.is() )
+ aAddress = xRangeAddress->getRangeAddress( );
+ return aAddress;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString OCellListSource::getCellTextContent_noCheck( sal_Int32 _nRangeRelativeColumn, sal_Int32 _nRangeRelativeRow )
+ {
+ OSL_PRECOND( m_xRange.is(), "OCellListSource::getRangeAddress: invalid range!" );
+ Reference< XTextRange > xCellText;
+ if ( m_xRange.is() )
+ xCellText.set(xCellText.query( m_xRange->getCellByPosition( _nRangeRelativeColumn, _nRangeRelativeRow ) ));
+
+ ::rtl::OUString sText;
+ if ( xCellText.is() )
+ sText = xCellText->getString();
+ return sText;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 SAL_CALL OCellListSource::getListEntryCount( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ checkDisposed();
+ checkInitialized();
+
+ CellRangeAddress aAddress( getRangeAddress( ) );
+ return aAddress.EndRow - aAddress.StartRow + 1;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OCellListSource::getListEntry( sal_Int32 _nPosition ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ checkDisposed();
+ checkInitialized();
+
+ if ( _nPosition >= getListEntryCount() )
+ throw IndexOutOfBoundsException();
+
+ return getCellTextContent_noCheck( 0, _nPosition );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OCellListSource::getAllListEntries( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ checkDisposed();
+ checkInitialized();
+
+ Sequence< ::rtl::OUString > aAllEntries( getListEntryCount() );
+ ::rtl::OUString* pAllEntries = aAllEntries.getArray();
+ for ( sal_Int32 i = 0; i < aAllEntries.getLength(); ++i )
+ {
+ *pAllEntries++ = getCellTextContent_noCheck( 0, i );
+ }
+
+ return aAllEntries;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::addListEntryListener( const Reference< XListEntryListener >& _rxListener ) throw (NullPointerException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ checkDisposed();
+ checkInitialized();
+
+ if ( !_rxListener.is() )
+ throw NullPointerException();
+
+ m_aListEntryListeners.addInterface( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::removeListEntryListener( const Reference< XListEntryListener >& _rxListener ) throw (NullPointerException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+ checkDisposed();
+ checkInitialized();
+
+ if ( !_rxListener.is() )
+ throw NullPointerException();
+
+ m_aListEntryListeners.removeInterface( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::modified( const EventObject& /* aEvent */ ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+
+ notifyModified();
+ }
+
+ //--------------------------------------------------------------------
+ void OCellListSource::notifyModified()
+ {
+ EventObject aEvent;
+ aEvent.Source.set(*this);
+
+ ::cppu::OInterfaceIteratorHelper aIter( m_aListEntryListeners );
+ while ( aIter.hasMoreElements() )
+ {
+ try
+ {
+ static_cast< XListEntryListener* >( aIter.next() )->allEntriesChanged( aEvent );
+ }
+ catch( const RuntimeException& )
+ {
+ // silent this
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "OCellListSource::notifyModified: caught a (non-runtime) exception!" );
+ }
+ }
+
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::disposing( const EventObject& aEvent ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellListSource, checkConsistency_static );
+
+ Reference<XInterface> xRangeInt( m_xRange, UNO_QUERY );
+ if ( xRangeInt == aEvent.Source )
+ {
+ // release references to range object
+ m_xRange.clear();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellListSource::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
+ {
+ if ( m_bInitialized )
+ throw Exception();
+ // TODO: error message
+
+ // get the cell address
+ CellRangeAddress aRangeAddress;
+ sal_Bool bFoundAddress = sal_False;
+
+ const Any* pLoop = _rArguments.getConstArray();
+ const Any* pLoopEnd = _rArguments.getConstArray() + _rArguments.getLength();
+ for ( ; ( pLoop != pLoopEnd ) && !bFoundAddress; ++pLoop )
+ {
+ NamedValue aValue;
+ if ( *pLoop >>= aValue )
+ {
+ if ( aValue.Name.equalsAscii( "CellRange" ) )
+ {
+ if ( aValue.Value >>= aRangeAddress )
+ bFoundAddress = sal_True;
+ }
+ }
+ }
+
+ if ( !bFoundAddress )
+ // TODO: error message
+ throw Exception();
+
+ // determine the range we're bound to
+ try
+ {
+ if ( m_xDocument.is() )
+ {
+ // first the sheets collection
+ Reference< XIndexAccess > xSheets(m_xDocument->getSheets( ), UNO_QUERY);
+ DBG_ASSERT( xSheets.is(), "OCellListSource::initialize: could not retrieve the sheets!" );
+
+ if ( xSheets.is() )
+ {
+ // the concrete sheet
+ Reference< XCellRange > xSheet(xSheets->getByIndex( aRangeAddress.Sheet ), UNO_QUERY);
+ DBG_ASSERT( xSheet.is(), "OCellListSource::initialize: NULL sheet, but no exception!" );
+
+ // the concrete cell
+ if ( xSheet.is() )
+ {
+ m_xRange.set(xSheet->getCellRangeByPosition(
+ aRangeAddress.StartColumn, aRangeAddress.StartRow,
+ aRangeAddress.EndColumn, aRangeAddress.EndRow));
+ DBG_ASSERT( Reference< XCellRangeAddressable >( m_xRange, UNO_QUERY ).is(), "OCellListSource::initialize: either NULL range, or cell without address access!" );
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "OCellListSource::initialize: caught an exception while retrieving the cell object!" );
+ }
+
+
+ if ( !m_xRange.is() )
+ throw Exception();
+ // TODO error message
+
+ Reference<XModifyBroadcaster> xBroadcaster( m_xRange, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ {
+ xBroadcaster->addModifyListener( this );
+ }
+
+ // TODO: add as XEventListener to the cell range, so we get notified when it dies,
+ // and can dispose ourself then
+
+ // TODO: somehow add as listener so we get notified when the address of the cell range changes
+ // We need to forward this as change in our CellRange property to our property change listeners
+
+ // TODO: somehow add as listener to the cells in the range, so that we get notified
+ // when their content changes. We need to forward this to our list entry listeners then
+
+ // TODO: somehow add as listener so that we get notified of insertions and removals of rows in our
+ // range. In this case, we need to fire a change in our CellRange property, and additionally
+ // notify our XListEntryListeners
+
+ m_bInitialized = sal_True;
+ }
+
+//.........................................................................
+} // namespace calc
+//.........................................................................
diff --git a/sc/source/ui/unoobj/celllistsource.hxx b/sc/source/ui/unoobj/celllistsource.hxx
new file mode 100644
index 000000000000..f6b52f0b50f8
--- /dev/null
+++ b/sc/source/ui/unoobj/celllistsource.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CELLLISTSOURCE_HXX
+#define SC_CELLLISTSOURCE_HXX
+
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <cppuhelper/compbase4.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/util/XModifyListener.hpp>
+
+
+//.........................................................................
+namespace calc
+{
+//.........................................................................
+
+ //=====================================================================
+ //= OCellListSource
+ //=====================================================================
+ class OCellListSource;
+ // the base for our interfaces
+ typedef ::cppu::WeakAggComponentImplHelper4 < ::com::sun::star::form::binding::XListEntrySource
+ , ::com::sun::star::util::XModifyListener
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::lang::XInitialization
+ > OCellListSource_Base;
+ // the base for the property handling
+ typedef ::comphelper::OPropertyContainer OCellListSource_PBase;
+ // the second base for property handling
+ typedef ::comphelper::OPropertyArrayUsageHelper< OCellListSource >
+ OCellListSource_PABase;
+
+ class OCellListSource :public ::comphelper::OBaseMutex
+ ,public OCellListSource_Base // order matters! before OCellListSource_PBase, so rBHelper gets initialized
+ ,public OCellListSource_PBase
+ ,public OCellListSource_PABase
+ {
+ private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
+ m_xDocument; /// the document where our cell lives
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ m_xRange; /// the range of cells we're bound to
+ ::cppu::OInterfaceContainerHelper
+ m_aListEntryListeners; /// our listeners
+ sal_Bool m_bInitialized; /// has XInitialization::initialize been called?
+
+ public:
+ OCellListSource(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& _rxDocument
+ );
+
+ using OCellListSource_PBase::getFastPropertyValue;
+
+ protected:
+ ~OCellListSource( );
+
+ protected:
+ // XInterface
+ DECLARE_XINTERFACE()
+
+ // XTypeProvider
+ DECLARE_XTYPEPROVIDER()
+
+ // XListEntrySource
+ virtual sal_Int32 SAL_CALL getListEntryCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getListEntry( sal_Int32 Position ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAllListEntries( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addListEntryListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntryListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeListEntryListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntryListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper/XComponent
+ virtual void SAL_CALL disposing();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const;
+
+ // ::comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // XModifyListener
+ virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ private:
+ void checkDisposed( ) const
+ SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
+ void checkInitialized()
+ SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) );
+
+ /** retrieves the actual address of our cell range
+ @precond
+ our m_xRange is not <NULL/>
+ */
+ ::com::sun::star::table::CellRangeAddress
+ getRangeAddress( ) const;
+
+ /** retrievs the text of a cell within our range
+ @param _nRangeRelativeColumn
+ the relative column index of the cell within our range
+ @param _nRangeRelativeRow
+ the relative row index of the cell within our range
+ @precond
+ our m_xRange is not <NULL/>
+ */
+ ::rtl::OUString
+ getCellTextContent_noCheck(
+ sal_Int32 _nRangeRelativeColumn,
+ sal_Int32 _nRangeRelativeRow
+ );
+
+ void notifyModified();
+
+ private:
+ OCellListSource(); // never implemented
+ OCellListSource( const OCellListSource& ); // never implemented
+ OCellListSource& operator=( const OCellListSource& ); // never implemented
+
+#ifdef DBG_UTIL
+ private:
+ static const char* checkConsistency_static( const void* _pThis );
+ const char* checkConsistency( ) const;
+#endif
+ };
+
+//.........................................................................
+} // namespace calc
+//.........................................................................
+
+#endif // SC_CELLLISTSOURCE_HXX
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
new file mode 100644
index 000000000000..dea7cc056756
--- /dev/null
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -0,0 +1,9842 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <svx/svdpool.hxx>
+
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/fmdpage.hxx>
+#include <editeng/langitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/unomid.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unotext.hxx>
+#include <svx/svdpage.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <rtl/uuid.h>
+#include <float.h> // DBL_MIN
+
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/util/CellProtection.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/sheet/FormulaResult.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
+#include <com/sun/star/beans/SetPropertyTolerantFailed.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+
+#include "autoform.hxx"
+#include "cellsuno.hxx"
+#include "cursuno.hxx"
+#include "textuno.hxx"
+#include "editsrc.hxx"
+#include "notesuno.hxx"
+#include "fielduno.hxx"
+#include "docuno.hxx" // ScTableColumnsObj etc
+#include "datauno.hxx"
+#include "dapiuno.hxx"
+#include "chartuno.hxx"
+#include "fmtuno.hxx"
+#include "miscuno.hxx"
+#include "convuno.hxx"
+#include "srchuno.hxx"
+#include "targuno.hxx"
+#include "tokenuno.hxx"
+#include "eventuno.hxx"
+#include "docsh.hxx"
+#include "markdata.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "docfunc.hxx"
+#include "dbdocfun.hxx"
+#include "olinefun.hxx"
+#include "hints.hxx"
+#include "cell.hxx"
+#include "undocell.hxx"
+#include "undotab.hxx"
+#include "undoblk.hxx" // fuer lcl_ApplyBorder - nach docfunc verschieben!
+#include "stlsheet.hxx"
+#include "dbcolect.hxx"
+#include "attrib.hxx"
+#include "chartarr.hxx"
+#include "chartlis.hxx"
+#include "drwlayer.hxx"
+#include "printfun.hxx"
+#include "prnsave.hxx"
+#include "tablink.hxx"
+#include "dociter.hxx"
+#include "rangeutl.hxx"
+#include "conditio.hxx"
+#include "validat.hxx"
+#include "sc.hrc"
+#include "brdcst.hxx"
+#include "unoguard.hxx"
+#include "cellform.hxx"
+#include "globstr.hrc"
+#include "unonames.hxx"
+#include "styleuno.hxx"
+#include "rangeseq.hxx"
+#include "unowids.hxx"
+#include "paramisc.hxx"
+#include "formula/errorcodes.hxx"
+#include "unoreflist.hxx"
+#include "formula/grammar.hxx"
+
+#include <list>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+
+class ScNamedEntry
+{
+ String aName;
+ ScRange aRange;
+
+public:
+ ScNamedEntry(const String& rN, const ScRange& rR) :
+ aName(rN), aRange(rR) {}
+
+ const String& GetName() const { return aName; }
+ const ScRange& GetRange() const { return aRange; }
+};
+
+
+//------------------------------------------------------------------------
+
+// Die Namen in den Maps muessen (nach strcmp) sortiert sein!
+//! statt Which-ID 0 special IDs verwenden, und nicht ueber Namen vergleichen !!!!!!!!!
+
+// Left/Right/Top/BottomBorder are mapped directly to the core items,
+// not collected/applied to the borders of a range -> ATTR_BORDER can be used directly
+
+const SfxItemPropertySet* lcl_GetCellsPropertySet()
+{
+ static SfxItemPropertyMapEntry aCellsPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ABSNAME), SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &getCppuType((sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &getCppuType((util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDFMT), SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDLOC), SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDXML), SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &getCppuType((table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &getCppuType((sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &getCppuType((table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIDAT), SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALILOC), SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aCellsPropertySet( aCellsPropertyMap_Impl );
+ return &aCellsPropertySet;
+}
+
+// CellRange enthaelt alle Eintraege von Cells, zusaetzlich eigene Eintraege
+// mit Which-ID 0 (werden nur fuer getPropertySetInfo benoetigt).
+
+const SfxItemPropertySet* lcl_GetRangePropertySet()
+{
+ static SfxItemPropertyMapEntry aRangePropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ABSNAME), SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &getCppuType((sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &getCppuType((util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDFMT), SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDLOC), SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDXML), SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &getCppuType((table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &getCppuType((sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_POS), SC_WID_UNO_POS, &getCppuType((awt::Point*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &getCppuType((table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SIZE), SC_WID_UNO_SIZE, &getCppuType((awt::Size*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIDAT), SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALILOC), SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aRangePropertySet( aRangePropertyMap_Impl );
+ return &aRangePropertySet;
+}
+
+// Cell enthaelt alle Eintraege von CellRange, zusaetzlich eigene Eintraege
+// mit Which-ID 0 (werden nur fuer getPropertySetInfo benoetigt).
+
+const SfxItemPropertySet* lcl_GetCellPropertySet()
+{
+ static SfxItemPropertyMapEntry aCellPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ABSNAME), SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &getCppuType((sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &getCppuType((util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDFMT), SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDLOC), SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDXML), SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_FORMLOC), SC_WID_UNO_FORMLOC, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_FORMRT), SC_WID_UNO_FORMRT, &getCppuType((table::CellContentType*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &getCppuType((table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &getCppuType((sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_POS), SC_WID_UNO_POS, &getCppuType((awt::Point*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &getCppuType((table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SIZE), SC_WID_UNO_SIZE, &getCppuType((awt::Size*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIDAT), SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALILOC), SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aCellPropertySet( aCellPropertyMap_Impl );
+ return &aCellPropertySet;
+}
+
+// Column und Row enthalten alle Eintraege von CellRange, zusaetzlich eigene Eintraege
+// mit Which-ID 0 (werden nur fuer getPropertySetInfo benoetigt).
+
+const SfxItemPropertySet* lcl_GetColumnPropertySet()
+{
+ static SfxItemPropertyMapEntry aColumnPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ABSNAME), SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &getCppuType((sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &getCppuType((util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDFMT), SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDLOC), SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDXML), SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+// {MAP_CHAR_LEN(SC_UNONAME_CELLFILT), SC_WID_UNO_CELLFILT,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_MANPAGE), SC_WID_UNO_MANPAGE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NEWPAGE), SC_WID_UNO_NEWPAGE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVIS), SC_WID_UNO_CELLVIS, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_OWIDTH), SC_WID_UNO_OWIDTH, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &getCppuType((table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &getCppuType((sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_POS), SC_WID_UNO_POS, &getCppuType((awt::Point*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &getCppuType((table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SIZE), SC_WID_UNO_SIZE, &getCppuType((awt::Size*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIDAT), SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALILOC), SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLWID), SC_WID_UNO_CELLWID, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aColumnPropertySet( aColumnPropertyMap_Impl );
+ return &aColumnPropertySet;
+}
+
+const SfxItemPropertySet* lcl_GetRowPropertySet()
+{
+ static SfxItemPropertyMapEntry aRowPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ABSNAME), SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &getCppuType((sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &getCppuType((util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDFMT), SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDLOC), SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDXML), SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHGT), SC_WID_UNO_CELLHGT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLFILT), SC_WID_UNO_CELLFILT,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_MANPAGE), SC_WID_UNO_MANPAGE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NEWPAGE), SC_WID_UNO_NEWPAGE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVIS), SC_WID_UNO_CELLVIS, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_OHEIGHT), SC_WID_UNO_OHEIGHT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &getCppuType((table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &getCppuType((sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_POS), SC_WID_UNO_POS, &getCppuType((awt::Point*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &getCppuType((table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SIZE), SC_WID_UNO_SIZE, &getCppuType((awt::Size*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIDAT), SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALILOC), SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aRowPropertySet( aRowPropertyMap_Impl );
+ return &aRowPropertySet;
+}
+
+const SfxItemPropertySet* lcl_GetSheetPropertySet()
+{
+ static SfxItemPropertyMapEntry aSheetPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ABSNAME), SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_AUTOPRINT),SC_WID_UNO_AUTOPRINT,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BORDCOL), SC_WID_UNO_BORDCOL, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &getCppuType((sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &getCppuType((util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDFMT), SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDLOC), SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CONDXML), SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COPYBACK), SC_WID_UNO_COPYBACK,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COPYFORM), SC_WID_UNO_COPYFORM,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COPYSTYL), SC_WID_UNO_COPYSTYL,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_ISACTIVE), SC_WID_UNO_ISACTIVE,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVIS), SC_WID_UNO_CELLVIS, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT), SC_WID_UNO_LINKDISPBIT,&getCppuType((uno::Reference<awt::XBitmap>*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), SC_WID_UNO_LINKDISPNAME,&getCppuType((rtl::OUString*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &getCppuType((table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PAGESTL), SC_WID_UNO_PAGESTL, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &getCppuType((sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &getCppuType((sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_POS), SC_WID_UNO_POS, &getCppuType((awt::Point*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PRINTBORD),SC_WID_UNO_PRINTBORD,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PROTECT), SC_WID_UNO_PROTECT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &getCppuType((table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHOWBORD), SC_WID_UNO_SHOWBORD,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SIZE), SC_WID_UNO_SIZE, &getCppuType((awt::Size*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TABLAYOUT),SC_WID_UNO_TABLAYOUT,&getCppuType((sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIDAT), SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALILOC), SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TABCOLOR), SC_WID_UNO_TABCOLOR, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_CODENAME), SC_WID_UNO_CODENAME, &getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aSheetPropertySet( aSheetPropertyMap_Impl );
+ return &aSheetPropertySet;
+}
+
+const SfxItemPropertyMapEntry* lcl_GetEditPropertyMap()
+{
+ static SfxItemPropertyMapEntry aEditPropertyMap_Impl[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
+ {MAP_CHAR_LEN(SC_UNONAME_TEXTUSER), EE_CHAR_XMLATTRIBS, &getCppuType((const uno::Reference< container::XNameContainer >*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), EE_PARA_XMLATTRIBS, &getCppuType((const uno::Reference< container::XNameContainer >*)0), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aEditPropertyMap_Impl;
+}
+const SvxItemPropertySet* lcl_GetEditPropertySet()
+{
+ static SvxItemPropertySet aEditPropertySet( lcl_GetEditPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool() );
+ return &aEditPropertySet;
+}
+
+
+//------------------------------------------------------------------------
+
+//! diese Funktionen in einen allgemeinen Header verschieben
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+
+//------------------------------------------------------------------------
+
+#define SCCHARPROPERTIES_SERVICE "com.sun.star.style.CharacterProperties"
+#define SCPARAPROPERTIES_SERVICE "com.sun.star.style.ParagraphProperties"
+#define SCCELLPROPERTIES_SERVICE "com.sun.star.table.CellProperties"
+#define SCCELLRANGE_SERVICE "com.sun.star.table.CellRange"
+#define SCCELL_SERVICE "com.sun.star.table.Cell"
+#define SCSHEETCELLRANGES_SERVICE "com.sun.star.sheet.SheetCellRanges"
+#define SCSHEETCELLRANGE_SERVICE "com.sun.star.sheet.SheetCellRange"
+#define SCSPREADSHEET_SERVICE "com.sun.star.sheet.Spreadsheet"
+#define SCSHEETCELL_SERVICE "com.sun.star.sheet.SheetCell"
+
+SC_SIMPLE_SERVICE_INFO( ScCellFormatsEnumeration, "ScCellFormatsEnumeration", "com.sun.star.sheet.CellFormatRangesEnumeration" )
+SC_SIMPLE_SERVICE_INFO( ScCellFormatsObj, "ScCellFormatsObj", "com.sun.star.sheet.CellFormatRanges" )
+SC_SIMPLE_SERVICE_INFO( ScUniqueCellFormatsEnumeration, "ScUniqueCellFormatsEnumeration", "com.sun.star.sheet.UniqueCellFormatRangesEnumeration" )
+SC_SIMPLE_SERVICE_INFO( ScUniqueCellFormatsObj, "ScUniqueCellFormatsObj", "com.sun.star.sheet.UniqueCellFormatRanges" )
+SC_SIMPLE_SERVICE_INFO( ScCellRangesBase, "ScCellRangesBase", "stardiv.unknown" )
+SC_SIMPLE_SERVICE_INFO( ScCellsEnumeration, "ScCellsEnumeration", "com.sun.star.sheet.CellsEnumeration" )
+SC_SIMPLE_SERVICE_INFO( ScCellsObj, "ScCellsObj", "com.sun.star.sheet.Cells" )
+SC_SIMPLE_SERVICE_INFO( ScTableColumnObj, "ScTableColumnObj", "com.sun.star.table.TableColumn" )
+SC_SIMPLE_SERVICE_INFO( ScTableRowObj, "ScTableRowObj", "com.sun.star.table.TableRow" )
+
+//------------------------------------------------------------------------
+
+SV_IMPL_PTRARR( XModifyListenerArr_Impl, XModifyListenerPtr );
+SV_IMPL_PTRARR( ScNamedEntryArr_Impl, ScNamedEntryPtr );
+
+//------------------------------------------------------------------------
+
+//! ScLinkListener in anderes File verschieben !!!
+
+ScLinkListener::~ScLinkListener()
+{
+}
+
+void ScLinkListener::Notify( SvtBroadcaster&, const SfxHint& rHint )
+{
+ aLink.Call( (SfxHint*)&rHint );
+}
+
+//------------------------------------------------------------------------
+
+void lcl_CopyProperties( beans::XPropertySet& rDest, beans::XPropertySet& rSource )
+{
+ uno::Reference<beans::XPropertySetInfo> xInfo(rSource.getPropertySetInfo());
+ if (xInfo.is())
+ {
+ uno::Sequence<beans::Property> aSeq(xInfo->getProperties());
+ const beans::Property* pAry = aSeq.getConstArray();
+ ULONG nCount = aSeq.getLength();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ rtl::OUString aName(pAry[i].Name);
+ rDest.setPropertyValue( aName, rSource.getPropertyValue( aName ) );
+ }
+ }
+}
+
+SCTAB lcl_FirstTab( const ScRangeList& rRanges )
+{
+ DBG_ASSERT(rRanges.Count() >= 1, "was fuer Ranges ?!?!");
+ const ScRange* pFirst = rRanges.GetObject(0);
+ if (pFirst)
+ return pFirst->aStart.Tab();
+
+ return 0; // soll nicht sein
+}
+
+BOOL lcl_WholeSheet( const ScRangeList& rRanges )
+{
+ if ( rRanges.Count() == 1 )
+ {
+ ScRange* pRange = rRanges.GetObject(0);
+ if ( pRange && pRange->aStart.Col() == 0 && pRange->aEnd.Col() == MAXCOL &&
+ pRange->aStart.Row() == 0 && pRange->aEnd.Row() == MAXROW )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalFunc lcl_SummaryToSubTotal( sheet::GeneralFunction eSummary )
+{
+ ScSubTotalFunc eSubTotal;
+ switch (eSummary)
+ {
+ case sheet::GeneralFunction_SUM:
+ eSubTotal = SUBTOTAL_FUNC_SUM;
+ break;
+ case sheet::GeneralFunction_COUNT:
+ eSubTotal = SUBTOTAL_FUNC_CNT2;
+ break;
+ case sheet::GeneralFunction_AVERAGE:
+ eSubTotal = SUBTOTAL_FUNC_AVE;
+ break;
+ case sheet::GeneralFunction_MAX:
+ eSubTotal = SUBTOTAL_FUNC_MAX;
+ break;
+ case sheet::GeneralFunction_MIN:
+ eSubTotal = SUBTOTAL_FUNC_MIN;
+ break;
+ case sheet::GeneralFunction_PRODUCT:
+ eSubTotal = SUBTOTAL_FUNC_PROD;
+ break;
+ case sheet::GeneralFunction_COUNTNUMS:
+ eSubTotal = SUBTOTAL_FUNC_CNT;
+ break;
+ case sheet::GeneralFunction_STDEV:
+ eSubTotal = SUBTOTAL_FUNC_STD;
+ break;
+ case sheet::GeneralFunction_STDEVP:
+ eSubTotal = SUBTOTAL_FUNC_STDP;
+ break;
+ case sheet::GeneralFunction_VAR:
+ eSubTotal = SUBTOTAL_FUNC_VAR;
+ break;
+ case sheet::GeneralFunction_VARP:
+ eSubTotal = SUBTOTAL_FUNC_VARP;
+ break;
+
+ case sheet::GeneralFunction_NONE:
+ case sheet::GeneralFunction_AUTO:
+ default:
+ eSubTotal = SUBTOTAL_FUNC_NONE;
+ break;
+ }
+ return eSubTotal;
+}
+
+//------------------------------------------------------------------------
+
+const SvxBorderLine* ScHelperFunctions::GetBorderLine( SvxBorderLine& rLine, const table::BorderLine& rStruct )
+{
+ // Calc braucht Twips, im Uno-Struct sind 1/100mm
+
+ rLine.SetOutWidth( (USHORT)HMMToTwips( rStruct.OuterLineWidth ) );
+ rLine.SetInWidth( (USHORT)HMMToTwips( rStruct.InnerLineWidth ) );
+ rLine.SetDistance( (USHORT)HMMToTwips( rStruct.LineDistance ) );
+ rLine.SetColor( ColorData( rStruct.Color ) );
+
+ if ( rLine.GetOutWidth() || rLine.GetInWidth() || rLine.GetDistance() )
+ return &rLine;
+ else
+ return NULL;
+}
+
+void ScHelperFunctions::FillBoxItems( SvxBoxItem& rOuter, SvxBoxInfoItem& rInner, const table::TableBorder& rBorder )
+{
+ SvxBorderLine aLine;
+ rOuter.SetDistance( (USHORT)HMMToTwips( rBorder.Distance ) );
+ rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.TopLine ), BOX_LINE_TOP );
+ rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.BottomLine ), BOX_LINE_BOTTOM );
+ rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.LeftLine ), BOX_LINE_LEFT );
+ rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.RightLine ), BOX_LINE_RIGHT );
+ rInner.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.HorizontalLine ), BOXINFO_LINE_HORI );
+ rInner.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.VerticalLine ), BOXINFO_LINE_VERT );
+ rInner.SetValid( VALID_TOP, rBorder.IsTopLineValid );
+ rInner.SetValid( VALID_BOTTOM, rBorder.IsBottomLineValid );
+ rInner.SetValid( VALID_LEFT, rBorder.IsLeftLineValid );
+ rInner.SetValid( VALID_RIGHT, rBorder.IsRightLineValid );
+ rInner.SetValid( VALID_HORI, rBorder.IsHorizontalLineValid );
+ rInner.SetValid( VALID_VERT, rBorder.IsVerticalLineValid );
+ rInner.SetValid( VALID_DISTANCE, rBorder.IsDistanceValid );
+ rInner.SetTable( TRUE );
+}
+
+void ScHelperFunctions::FillBorderLine( table::BorderLine& rStruct, const SvxBorderLine* pLine )
+{
+ if (pLine)
+ {
+ rStruct.Color = pLine->GetColor().GetColor();
+ rStruct.InnerLineWidth = (sal_Int16)TwipsToHMM( pLine->GetInWidth() );
+ rStruct.OuterLineWidth = (sal_Int16)TwipsToHMM( pLine->GetOutWidth() );
+ rStruct.LineDistance = (sal_Int16)TwipsToHMM( pLine->GetDistance() );
+ }
+ else
+ rStruct.Color = rStruct.InnerLineWidth =
+ rStruct.OuterLineWidth = rStruct.LineDistance = 0;
+}
+
+void ScHelperFunctions::FillTableBorder( table::TableBorder& rBorder,
+ const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner )
+{
+ ScHelperFunctions::FillBorderLine( rBorder.TopLine, rOuter.GetTop() );
+ ScHelperFunctions::FillBorderLine( rBorder.BottomLine, rOuter.GetBottom() );
+ ScHelperFunctions::FillBorderLine( rBorder.LeftLine, rOuter.GetLeft() );
+ ScHelperFunctions::FillBorderLine( rBorder.RightLine, rOuter.GetRight() );
+ ScHelperFunctions::FillBorderLine( rBorder.HorizontalLine, rInner.GetHori() );
+ ScHelperFunctions::FillBorderLine( rBorder.VerticalLine, rInner.GetVert() );
+
+ rBorder.Distance = rOuter.GetDistance();
+ rBorder.IsTopLineValid = rInner.IsValid(VALID_TOP);
+ rBorder.IsBottomLineValid = rInner.IsValid(VALID_BOTTOM);
+ rBorder.IsLeftLineValid = rInner.IsValid(VALID_LEFT);
+ rBorder.IsRightLineValid = rInner.IsValid(VALID_RIGHT);
+ rBorder.IsHorizontalLineValid = rInner.IsValid(VALID_HORI);
+ rBorder.IsVerticalLineValid = rInner.IsValid(VALID_VERT);
+ rBorder.IsDistanceValid = rInner.IsValid(VALID_DISTANCE);
+}
+
+//------------------------------------------------------------------------
+
+//! lcl_ApplyBorder nach docfunc verschieben!
+
+void ScHelperFunctions::ApplyBorder( ScDocShell* pDocShell, const ScRangeList& rRanges,
+ const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ ScDocument* pUndoDoc = NULL;
+ if (bUndo)
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ULONG nCount = rRanges.Count();
+ ULONG i;
+ for (i=0; i<nCount; i++)
+ {
+ ScRange aRange(*rRanges.GetObject(i));
+ SCTAB nTab = aRange.aStart.Tab();
+
+ if (bUndo)
+ {
+ if ( i==0 )
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ else
+ pUndoDoc->AddUndoTab( nTab, nTab );
+ pDoc->CopyToDocument( aRange, IDF_ATTRIB, FALSE, pUndoDoc );
+ }
+
+ ScMarkData aMark;
+ aMark.SetMarkArea( aRange );
+ aMark.SelectTable( nTab, TRUE );
+
+ pDoc->ApplySelectionFrame( aMark, &rOuter, &rInner );
+ // RowHeight bei Umrandung alleine nicht noetig
+ }
+
+ if (bUndo)
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoBorder( pDocShell, rRanges, pUndoDoc, rOuter, rInner ) );
+ }
+
+ for (i=0; i<nCount; i++)
+ pDocShell->PostPaint( *rRanges.GetObject(i), PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ pDocShell->SetDocumentModified();
+}
+
+//! move lcl_PutDataArray to docfunc?
+//! merge loop with ScFunctionAccess::callFunction
+
+BOOL lcl_PutDataArray( ScDocShell& rDocShell, const ScRange& rRange,
+ const uno::Sequence< uno::Sequence<uno::Any> >& aData )
+{
+// BOOL bApi = TRUE;
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if ( !pDoc->IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ) )
+ {
+ //! error message
+ return FALSE;
+ }
+
+ long nCols = 0;
+ long nRows = aData.getLength();
+ const uno::Sequence<uno::Any>* pArray = aData.getConstArray();
+ if ( nRows )
+ nCols = pArray[0].getLength();
+
+ if ( nCols != nEndCol-nStartCol+1 || nRows != nEndRow-nStartRow+1 )
+ {
+ //! error message?
+ return FALSE;
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bUndo )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( rRange, IDF_CONTENTS|IDF_NOCAPTIONS, FALSE, pUndoDoc );
+ }
+
+ pDoc->DeleteAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, IDF_CONTENTS );
+
+ BOOL bError = FALSE;
+ SCROW nDocRow = nStartRow;
+ for (long nRow=0; nRow<nRows; nRow++)
+ {
+ const uno::Sequence<uno::Any>& rColSeq = pArray[nRow];
+ if ( rColSeq.getLength() == nCols )
+ {
+ SCCOL nDocCol = nStartCol;
+ const uno::Any* pColArr = rColSeq.getConstArray();
+ for (long nCol=0; nCol<nCols; nCol++)
+ {
+ const uno::Any& rElement = pColArr[nCol];
+ uno::TypeClass eElemClass = rElement.getValueTypeClass();
+ if ( eElemClass == uno::TypeClass_VOID )
+ {
+ // void = "no value"
+ pDoc->SetError( nDocCol, nDocRow, nTab, NOTAVAILABLE );
+ }
+ else if ( eElemClass == uno::TypeClass_BYTE ||
+ eElemClass == uno::TypeClass_SHORT ||
+ eElemClass == uno::TypeClass_UNSIGNED_SHORT ||
+ eElemClass == uno::TypeClass_LONG ||
+ eElemClass == uno::TypeClass_UNSIGNED_LONG ||
+ eElemClass == uno::TypeClass_FLOAT ||
+ eElemClass == uno::TypeClass_DOUBLE )
+ {
+ // #87871# accept integer types because Basic passes a floating point
+ // variable as byte, short or long if it's an integer number.
+ double fVal(0.0);
+ rElement >>= fVal;
+ pDoc->SetValue( nDocCol, nDocRow, nTab, fVal );
+ }
+ else if ( eElemClass == uno::TypeClass_STRING )
+ {
+ rtl::OUString aUStr;
+ rElement >>= aUStr;
+ if ( aUStr.getLength() )
+ pDoc->PutCell( nDocCol, nDocRow, nTab, new ScStringCell( aUStr ) );
+ }
+ else
+ bError = TRUE; // invalid type
+
+ ++nDocCol;
+ }
+ }
+ else
+ bError = TRUE; // wrong size
+
+ ++nDocRow;
+ }
+
+ BOOL bHeight = rDocShell.AdjustRowHeight( nStartRow, nEndRow, nTab );
+
+ if ( pUndoDoc )
+ {
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nTab );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoPaste( &rDocShell,
+ nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, aDestMark,
+ pUndoDoc, NULL, IDF_CONTENTS, NULL,NULL,NULL,NULL, FALSE ) );
+ }
+
+ if (!bHeight)
+ rDocShell.PostPaint( rRange, PAINT_GRID ); // AdjustRowHeight may have painted already
+
+ rDocShell.SetDocumentModified();
+
+ return !bError;
+}
+
+BOOL lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
+ const uno::Sequence< uno::Sequence<rtl::OUString> >& aData,
+ const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
+{
+// BOOL bApi = TRUE;
+
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if ( !pDoc->IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ) )
+ {
+ //! error message
+ return FALSE;
+ }
+
+ long nCols = 0;
+ long nRows = aData.getLength();
+ const uno::Sequence<rtl::OUString>* pArray = aData.getConstArray();
+ if ( nRows )
+ nCols = pArray[0].getLength();
+
+ if ( nCols != nEndCol-nStartCol+1 || nRows != nEndRow-nStartRow+1 )
+ {
+ //! error message?
+ return FALSE;
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bUndo )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( rRange, IDF_CONTENTS, FALSE, pUndoDoc );
+ }
+
+ pDoc->DeleteAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, IDF_CONTENTS );
+
+ ScDocFunc aFunc( rDocShell ); // for InterpretEnglishString
+
+ BOOL bError = FALSE;
+ SCROW nDocRow = nStartRow;
+ for (long nRow=0; nRow<nRows; nRow++)
+ {
+ const uno::Sequence<rtl::OUString>& rColSeq = pArray[nRow];
+ if ( rColSeq.getLength() == nCols )
+ {
+ SCCOL nDocCol = nStartCol;
+ const rtl::OUString* pColArr = rColSeq.getConstArray();
+ for (long nCol=0; nCol<nCols; nCol++)
+ {
+ String aText(pColArr[nCol]);
+ ScAddress aPos( nDocCol, nDocRow, nTab );
+ ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aPos, aText, rFormulaNmsp, eGrammar );
+ pDoc->PutCell( aPos, pNewCell );
+
+ ++nDocCol;
+ }
+ }
+ else
+ bError = TRUE; // wrong size
+
+ ++nDocRow;
+ }
+
+ BOOL bHeight = rDocShell.AdjustRowHeight( nStartRow, nEndRow, nTab );
+
+ if ( pUndoDoc )
+ {
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nTab );
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoPaste( &rDocShell,
+ nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, aDestMark,
+ pUndoDoc, NULL, IDF_CONTENTS, NULL,NULL,NULL,NULL, FALSE ) );
+ }
+
+ if (!bHeight)
+ rDocShell.PostPaint( rRange, PAINT_GRID ); // AdjustRowHeight may have painted already
+
+ rDocShell.SetDocumentModified();
+
+ return !bError;
+}
+
+// used in ScCellRangeObj::getFormulaArray and ScCellObj::GetInputString_Impl
+String lcl_GetInputString( ScDocument* pDoc, const ScAddress& rPosition, BOOL bEnglish )
+{
+ String aVal;
+ if ( pDoc )
+ {
+ ScBaseCell* pCell = pDoc->GetCell( rPosition );
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ CellType eType = pCell->GetCellType();
+ if ( eType == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pForm = (ScFormulaCell*)pCell;
+ pForm->GetFormula( aVal,formula::FormulaGrammar::mapAPItoGrammar( bEnglish, false));
+ }
+ else
+ {
+ SvNumberFormatter* pFormatter = bEnglish ? ScGlobal::GetEnglishFormatter() :
+ pDoc->GetFormatTable();
+ // Since the English formatter was constructed with
+ // LANGUAGE_ENGLISH_US the "General" format has index key 0,
+ // we don't have to query.
+ sal_uInt32 nNumFmt = bEnglish ?
+// pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US) :
+ 0 :
+ pDoc->GetNumberFormat( rPosition );
+
+ if ( eType == CELLTYPE_EDIT )
+ {
+ // GetString an der EditCell macht Leerzeichen aus Umbruechen,
+ // hier werden die Umbrueche aber gebraucht
+ const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
+ if (pData)
+ {
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ aVal = rEngine.GetText( LINEEND_LF );
+ }
+ }
+ else
+ ScCellFormat::GetInputString( pCell, nNumFmt, aVal, *pFormatter );
+
+ // ggf. ein ' davorhaengen wie in ScTabViewShell::UpdateInputHandler
+ if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
+ {
+ double fDummy;
+ sal_Bool bIsNumberFormat(pFormatter->IsNumberFormat(aVal, nNumFmt, fDummy));
+ if ( bIsNumberFormat )
+ aVal.Insert('\'',0);
+ else if ( aVal.Len() && aVal.GetChar(0) == '\'' )
+ {
+ // if the string starts with a "'", add another one because setFormula
+ // strips one (like text input, except for "text" number formats)
+ if ( bEnglish || ( pFormatter->GetType(nNumFmt) != NUMBERFORMAT_TEXT ) )
+ aVal.Insert('\'',0);
+ }
+ }
+ }
+ }
+ }
+ return aVal;
+}
+
+//------------------------------------------------------------------------
+
+// Default-ctor fuer SMART_REFLECTION Krempel
+ScCellRangesBase::ScCellRangesBase() :
+ pPropSet(lcl_GetCellsPropertySet()),
+ pDocShell( NULL ),
+ pValueListener( NULL ),
+ pCurrentFlat( NULL ),
+ pCurrentDeep( NULL ),
+ pCurrentDataSet( NULL ),
+ pNoDfltCurrentDataSet( NULL ),
+ pMarkData( NULL ),
+ nObjectId( 0 ),
+ bChartColAsHdr( FALSE ),
+ bChartRowAsHdr( FALSE ),
+ bCursorOnly( FALSE ),
+ bGotDataChangedHint( FALSE ),
+ aValueListeners( 0 )
+{
+}
+
+ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRange& rR) :
+ pPropSet(lcl_GetCellsPropertySet()),
+ pDocShell( pDocSh ),
+ pValueListener( NULL ),
+ pCurrentFlat( NULL ),
+ pCurrentDeep( NULL ),
+ pCurrentDataSet( NULL ),
+ pNoDfltCurrentDataSet( NULL ),
+ pMarkData( NULL ),
+ nObjectId( 0 ),
+ bChartColAsHdr( FALSE ),
+ bChartRowAsHdr( FALSE ),
+ bCursorOnly( FALSE ),
+ bGotDataChangedHint( FALSE ),
+ aValueListeners( 0 )
+{
+ ScRange aCellRange(rR);
+ aCellRange.Justify();
+ aRanges.Append( aCellRange );
+
+ if (pDocShell) // Null if created with createInstance
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->AddUnoObject(*this);
+ nObjectId = pDoc->GetNewUnoId();
+ }
+}
+
+ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRangeList& rR) :
+ pPropSet(lcl_GetCellsPropertySet()),
+ pDocShell( pDocSh ),
+ pValueListener( NULL ),
+ pCurrentFlat( NULL ),
+ pCurrentDeep( NULL ),
+ pCurrentDataSet( NULL ),
+ pNoDfltCurrentDataSet( NULL ),
+ pMarkData( NULL ),
+ aRanges( rR ),
+ nObjectId( 0 ),
+ bChartColAsHdr( FALSE ),
+ bChartRowAsHdr( FALSE ),
+ bCursorOnly( FALSE ),
+ bGotDataChangedHint( FALSE ),
+ aValueListeners( 0 )
+{
+ if (pDocShell) // Null if created with createInstance
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->AddUnoObject(*this);
+ nObjectId = pDoc->GetNewUnoId();
+ }
+}
+
+ScCellRangesBase::~ScCellRangesBase()
+{
+ // #107294# call RemoveUnoObject first, so no notification can happen
+ // during ForgetCurrentAttrs
+
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+
+ ForgetCurrentAttrs();
+ ForgetMarkData();
+
+ delete pValueListener;
+
+ //! XChartDataChangeEventListener abmelden ??
+ //! (ChartCollection haelt dann auch dieses Objekt fest!)
+}
+
+void ScCellRangesBase::ForgetCurrentAttrs()
+{
+ delete pCurrentFlat;
+ delete pCurrentDeep;
+ delete pCurrentDataSet;
+ delete pNoDfltCurrentDataSet;
+ pCurrentFlat = NULL;
+ pCurrentDeep = NULL;
+ pCurrentDataSet = NULL;
+ pNoDfltCurrentDataSet = NULL;
+
+ // #i62483# pMarkData can remain unchanged, is deleted only if the range changes (RefChanged)
+}
+
+void ScCellRangesBase::ForgetMarkData()
+{
+ delete pMarkData;
+ pMarkData = NULL;
+}
+
+const ScPatternAttr* ScCellRangesBase::GetCurrentAttrsFlat()
+{
+ // get and cache direct cell attributes for this object's range
+
+ if ( !pCurrentFlat && pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pCurrentFlat = pDoc->CreateSelectionPattern( *GetMarkData(), FALSE );
+ }
+ return pCurrentFlat;
+}
+
+const ScPatternAttr* ScCellRangesBase::GetCurrentAttrsDeep()
+{
+ // get and cache cell attributes (incl. styles) for this object's range
+
+ if ( !pCurrentDeep && pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pCurrentDeep = pDoc->CreateSelectionPattern( *GetMarkData(), TRUE );
+ }
+ return pCurrentDeep;
+}
+
+SfxItemSet* ScCellRangesBase::GetCurrentDataSet(bool bNoDflt)
+{
+ if(!pCurrentDataSet)
+ {
+ const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
+ if ( pPattern )
+ {
+ // Dontcare durch Default ersetzen, damit man immer eine Reflection hat
+ pCurrentDataSet = new SfxItemSet( pPattern->GetItemSet() );
+ pNoDfltCurrentDataSet = new SfxItemSet( pPattern->GetItemSet() );
+ pCurrentDataSet->ClearInvalidItems();
+ }
+ }
+ return bNoDflt ? pNoDfltCurrentDataSet : pCurrentDataSet;
+}
+
+const ScMarkData* ScCellRangesBase::GetMarkData()
+{
+ if (!pMarkData)
+ {
+ pMarkData = new ScMarkData();
+ pMarkData->MarkFromRangeList( aRanges, FALSE );
+ }
+ return pMarkData;
+}
+
+void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangeList* pUndoRanges = NULL;
+ if ( pDoc->HasUnoRefUndo() )
+ pUndoRanges = new ScRangeList( aRanges );
+
+ if ( aRanges.UpdateReference( rRef.GetMode(), pDoc, rRef.GetRange(),
+ rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) )
+ {
+ if (rRef.GetMode() == URM_INSDEL &&
+ aRanges.Count() == 1 &&
+ ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ))
+ {
+ // #101755#; the range size of a sheet does not change
+ ScRange* pR = aRanges.First();
+ if (pR)
+ {
+ pR->aStart.SetCol(0);
+ pR->aStart.SetRow(0);
+ pR->aEnd.SetCol(MAXCOL);
+ pR->aEnd.SetRow(MAXROW);
+ }
+ }
+ RefChanged();
+
+ // #129050# any change of the range address is broadcast to value (modify) listeners
+ if ( aValueListeners.Count() )
+ bGotDataChangedHint = TRUE;
+
+ if ( pUndoRanges )
+ pDoc->AddUnoRefChange( nObjectId, *pUndoRanges );
+ }
+
+ delete pUndoRanges;
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ ForgetCurrentAttrs();
+ pDocShell = NULL; // invalid
+
+ if ( aValueListeners.Count() != 0 )
+ {
+ // dispose listeners
+
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for ( USHORT n=0; n<aValueListeners.Count(); n++ )
+ (*aValueListeners[n])->disposing( aEvent );
+
+ aValueListeners.DeleteAndDestroy( 0, aValueListeners.Count() );
+
+ // The listeners can't have the last ref to this, as it's still held
+ // by the DocShell.
+ }
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // document content changed -> forget cached attributes
+ ForgetCurrentAttrs();
+
+ if ( bGotDataChangedHint && pDocShell )
+ {
+ // This object was notified of content changes, so one call
+ // for each listener is generated now.
+ // The calls can't be executed directly because the document's
+ // UNO broadcaster list must not be modified.
+ // Instead, add to the document's list of listener calls,
+ // which will be executed directly after the broadcast of
+ // SFX_HINT_DATACHANGED.
+
+ lang::EventObject aEvent;
+ aEvent.Source.set((cppu::OWeakObject*)this);
+
+ // the EventObject holds a Ref to this object until after the listener calls
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ for ( USHORT n=0; n<aValueListeners.Count(); n++ )
+ pDoc->AddUnoListenerCall( *aValueListeners[n], aEvent );
+
+ bGotDataChangedHint = FALSE;
+ }
+ }
+ else if ( nId == SC_HINT_CALCALL )
+ {
+ // broadcast from DoHardRecalc - set bGotDataChangedHint
+ // (SFX_HINT_DATACHANGED follows separately)
+
+ if ( aValueListeners.Count() )
+ bGotDataChangedHint = TRUE;
+ }
+ }
+ else if ( rHint.ISA( ScUnoRefUndoHint ) )
+ {
+ const ScUnoRefUndoHint& rUndoHint = static_cast<const ScUnoRefUndoHint&>(rHint);
+ if ( rUndoHint.GetObjectId() == nObjectId )
+ {
+ // restore ranges from hint
+
+ aRanges = rUndoHint.GetRanges();
+
+ RefChanged();
+ if ( aValueListeners.Count() )
+ bGotDataChangedHint = TRUE; // need to broadcast the undo, too
+ }
+ }
+}
+
+void ScCellRangesBase::RefChanged()
+{
+ //! adjust XChartDataChangeEventListener
+
+ if ( pValueListener && aValueListeners.Count() != 0 )
+ {
+ pValueListener->EndListeningAll();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ pDoc->StartListeningArea( *aRanges.GetObject(i), pValueListener );
+ }
+
+ ForgetCurrentAttrs();
+ ForgetMarkData();
+}
+
+ScDocument* ScCellRangesBase::GetDocument() const
+{
+ if (pDocShell)
+ return pDocShell->GetDocument();
+ else
+ return NULL;
+}
+
+void ScCellRangesBase::InitInsertRange(ScDocShell* pDocSh, const ScRange& rR)
+{
+ if ( !pDocShell && pDocSh )
+ {
+ pDocShell = pDocSh;
+
+ ScRange aCellRange(rR);
+ aCellRange.Justify();
+ aRanges.RemoveAll();
+ aRanges.Append( aCellRange );
+
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ RefChanged(); // Range im Range-Objekt anpassen
+ }
+}
+
+void ScCellRangesBase::AddRange(const ScRange& rRange, const sal_Bool bMergeRanges)
+{
+ if (bMergeRanges)
+ aRanges.Join(rRange);
+ else
+ aRanges.Append(rRange);
+ RefChanged();
+}
+
+void ScCellRangesBase::SetNewRange(const ScRange& rNew)
+{
+ ScRange aCellRange(rNew);
+ aCellRange.Justify();
+
+ aRanges.RemoveAll();
+ aRanges.Append( aCellRange );
+ RefChanged();
+}
+
+void ScCellRangesBase::SetNewRanges(const ScRangeList& rNew)
+{
+ aRanges = rNew;
+ RefChanged();
+}
+
+void ScCellRangesBase::SetCursorOnly( BOOL bSet )
+{
+ // set for a selection object that is created from the cursor position
+ // without anything selected (may contain several sheets)
+
+ bCursorOnly = bSet;
+}
+
+uno::Any SAL_CALL ScCellRangesBase::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( beans::XMultiPropertySet )
+ SC_QUERYINTERFACE( beans::XTolerantMultiPropertySet )
+ SC_QUERYINTERFACE( beans::XPropertyState )
+ SC_QUERYINTERFACE( sheet::XSheetOperation )
+ SC_QUERYINTERFACE( chart::XChartDataArray )
+ SC_QUERYINTERFACE( chart::XChartData )
+ SC_QUERYINTERFACE( util::XIndent )
+ SC_QUERYINTERFACE( sheet::XCellRangesQuery )
+ SC_QUERYINTERFACE( sheet::XFormulaQuery )
+ SC_QUERYINTERFACE( util::XReplaceable )
+ SC_QUERYINTERFACE( util::XSearchable )
+ SC_QUERYINTERFACE( util::XModifyBroadcaster )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+ SC_QUERYINTERFACE( lang::XUnoTunnel )
+ SC_QUERYINTERFACE( lang::XTypeProvider )
+
+ return OWeakObject::queryInterface( rType );
+}
+
+void SAL_CALL ScCellRangesBase::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ScCellRangesBase::release() throw()
+{
+ OWeakObject::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScCellRangesBase::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ aTypes.realloc(13);
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[0] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
+ pPtr[1] = getCppuType((const uno::Reference<beans::XMultiPropertySet>*)0);
+ pPtr[2] = getCppuType((const uno::Reference<beans::XPropertyState>*)0);
+ pPtr[3] = getCppuType((const uno::Reference<sheet::XSheetOperation>*)0);
+ pPtr[4] = getCppuType((const uno::Reference<chart::XChartDataArray>*)0);
+ pPtr[5] = getCppuType((const uno::Reference<util::XIndent>*)0);
+ pPtr[6] = getCppuType((const uno::Reference<sheet::XCellRangesQuery>*)0);
+ pPtr[7] = getCppuType((const uno::Reference<sheet::XFormulaQuery>*)0);
+ pPtr[8] = getCppuType((const uno::Reference<util::XReplaceable>*)0);
+ pPtr[9] = getCppuType((const uno::Reference<util::XModifyBroadcaster>*)0);
+ pPtr[10]= getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
+ pPtr[11]= getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
+ pPtr[12]= getCppuType((const uno::Reference<lang::XTypeProvider>*)0);
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScCellRangesBase::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// ---
+
+void ScCellRangesBase::PaintRanges_Impl( USHORT nPart )
+{
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ pDocShell->PostPaint( *aRanges.GetObject(i), nPart );
+}
+
+// XSheetOperation
+
+double SAL_CALL ScCellRangesBase::computeFunction( sheet::GeneralFunction nFunction )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScMarkData aMark(*GetMarkData());
+ aMark.MarkToSimple();
+ if (!aMark.IsMarked())
+ aMark.SetMarkNegative(TRUE); // um Dummy Position angeben zu koennen
+
+ ScAddress aDummy; // wenn nicht Marked, ignoriert wegen Negative
+ double fVal;
+ ScSubTotalFunc eFunc = lcl_SummaryToSubTotal( nFunction );
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( !pDoc->GetSelectionFunction( eFunc, aDummy, aMark, fVal ) )
+ {
+ throw uno::RuntimeException(); //! own exception?
+ }
+
+ return fVal;
+}
+
+void SAL_CALL ScCellRangesBase::clearContents( sal_Int32 nContentFlags ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( aRanges.Count() )
+ {
+ // only for clearContents: EDITATTR is only used if no contents are deleted
+ USHORT nDelFlags = static_cast< USHORT >( nContentFlags & IDF_ALL );
+ if ( ( nContentFlags & IDF_EDITATTR ) && ( nContentFlags & IDF_CONTENTS ) == 0 )
+ nDelFlags |= IDF_EDITATTR;
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.DeleteContents( *GetMarkData(), nDelFlags, TRUE, TRUE );
+ }
+ // sonst ist nichts zu tun
+}
+
+// XPropertyState
+
+const SfxItemPropertyMap* ScCellRangesBase::GetItemPropertyMap()
+{
+ return pPropSet->getPropertyMap();
+}
+
+void lcl_GetPropertyWhich( const SfxItemPropertySimpleEntry* pEntry,
+ USHORT& rItemWhich )
+{
+ // Which-ID des betroffenen Items, auch wenn das Item die Property
+ // nicht alleine behandeln kann
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ rItemWhich = pEntry->nWID;
+ else
+ switch ( pEntry->nWID )
+ {
+ case SC_WID_UNO_TBLBORD:
+ rItemWhich = ATTR_BORDER;
+ break;
+ case SC_WID_UNO_CONDFMT:
+ case SC_WID_UNO_CONDLOC:
+ case SC_WID_UNO_CONDXML:
+ rItemWhich = ATTR_CONDITIONAL;
+ break;
+ case SC_WID_UNO_VALIDAT:
+ case SC_WID_UNO_VALILOC:
+ case SC_WID_UNO_VALIXML:
+ rItemWhich = ATTR_VALIDDATA;
+ break;
+ }
+ }
+
+}
+
+beans::PropertyState ScCellRangesBase::GetOnePropertyState( USHORT nItemWhich, const SfxItemPropertySimpleEntry* pEntry )
+{
+ beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
+ if ( nItemWhich ) // item wid (from map or special case)
+ {
+ // For items that contain several properties (like background),
+ // "ambiguous" is returned too often here
+
+ // for PropertyState, don't look at styles
+ const ScPatternAttr* pPattern = GetCurrentAttrsFlat();
+ if ( pPattern )
+ {
+ SfxItemState eState = pPattern->GetItemSet().GetItemState( nItemWhich, FALSE );
+
+// // if no rotate value is set, look at orientation
+// //! also for a fixed value of 0 (in case orientation is ambiguous)?
+// if ( nItemWhich == ATTR_ROTATE_VALUE && eState == SFX_ITEM_DEFAULT )
+// eState = pPattern->GetItemSet().GetItemState( ATTR_ORIENTATION, FALSE );
+
+ if ( nItemWhich == ATTR_VALUE_FORMAT && eState == SFX_ITEM_DEFAULT )
+ eState = pPattern->GetItemSet().GetItemState( ATTR_LANGUAGE_FORMAT, FALSE );
+
+ if ( eState == SFX_ITEM_SET )
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ else if ( eState == SFX_ITEM_DEFAULT )
+ eRet = beans::PropertyState_DEFAULT_VALUE;
+ else if ( eState == SFX_ITEM_DONTCARE )
+ eRet = beans::PropertyState_AMBIGUOUS_VALUE;
+ else
+ {
+ DBG_ERROR("unbekannter ItemState");
+ }
+ }
+ }
+ else if ( pEntry )
+ {
+ if ( pEntry->nWID == SC_WID_UNO_CHCOLHDR || pEntry->nWID == SC_WID_UNO_CHROWHDR || pEntry->nWID == SC_WID_UNO_ABSNAME )
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ else if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
+ {
+ // a style is always set, there's no default state
+ const ScStyleSheet* pStyle = pDocShell->GetDocument()->GetSelectionStyle(*GetMarkData());
+ if (pStyle)
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ else
+ eRet = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_NUMRULES )
+ eRet = beans::PropertyState_DEFAULT_VALUE; // numbering rules are always default
+ }
+ return eRet;
+}
+
+beans::PropertyState SAL_CALL ScCellRangesBase::getPropertyState( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMap* pMap = GetItemPropertyMap(); // from derived class
+ USHORT nItemWhich = 0;
+ const SfxItemPropertySimpleEntry* pEntry = pMap->getByName( aPropertyName );
+ lcl_GetPropertyWhich( pEntry, nItemWhich );
+ return GetOnePropertyState( nItemWhich, pEntry );
+}
+
+uno::Sequence<beans::PropertyState> SAL_CALL ScCellRangesBase::getPropertyStates(
+ const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+
+ uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ for(INT32 i = 0; i < aPropertyNames.getLength(); i++)
+ {
+ USHORT nItemWhich = 0;
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
+ lcl_GetPropertyWhich( pEntry, nItemWhich );
+ pStates[i] = GetOnePropertyState(nItemWhich, pEntry);
+ }
+ return aRet;
+}
+
+void SAL_CALL ScCellRangesBase::setPropertyToDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+ USHORT nItemWhich = 0;
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
+ lcl_GetPropertyWhich( pEntry, nItemWhich );
+ if ( nItemWhich ) // item wid (from map or special case)
+ {
+ if ( aRanges.Count() ) // leer = nichts zu tun
+ {
+ ScDocFunc aFunc(*pDocShell);
+
+ //! Bei Items, die mehrere Properties enthalten (z.B. Hintergrund)
+ //! wird hier zuviel zurueckgesetzt
+
+// //! for ATTR_ROTATE_VALUE, also reset ATTR_ORIENTATION?
+
+ USHORT aWIDs[3];
+ aWIDs[0] = nItemWhich;
+ if ( nItemWhich == ATTR_VALUE_FORMAT )
+ {
+ aWIDs[1] = ATTR_LANGUAGE_FORMAT; // #67847# language for number formats
+ aWIDs[2] = 0;
+ }
+ else
+ aWIDs[1] = 0;
+ aFunc.ClearItems( *GetMarkData(), aWIDs, TRUE );
+ }
+ }
+ else if ( pEntry )
+ {
+ if ( pEntry->nWID == SC_WID_UNO_CHCOLHDR )
+ bChartColAsHdr = FALSE;
+ else if ( pEntry->nWID == SC_WID_UNO_CHROWHDR )
+ bChartRowAsHdr = FALSE;
+ else if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.ApplyStyle( *GetMarkData(), ScGlobal::GetRscString(STR_STYLENAME_STANDARD), TRUE, TRUE );
+ }
+ }
+ }
+}
+
+uno::Any SAL_CALL ScCellRangesBase::getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ //! mit getPropertyValue zusammenfassen
+
+ ScUnoGuard aGuard;
+ uno::Any aAny;
+
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ const ScPatternAttr* pPattern = pDoc->GetDefPattern();
+ if ( pPattern )
+ {
+ const SfxItemSet& rSet = pPattern->GetItemSet();
+
+ switch ( pEntry->nWID ) // fuer Item-Spezial-Behandlungen
+ {
+ case ATTR_VALUE_FORMAT:
+ // default has no language set
+ aAny <<= (sal_Int32)( ((const SfxUInt32Item&)rSet.Get(pEntry->nWID)).GetValue() );
+ break;
+ case ATTR_INDENT:
+ aAny <<= (sal_Int16)( TwipsToHMM(((const SfxUInt16Item&)
+ rSet.Get(pEntry->nWID)).GetValue()) );
+ break;
+ default:
+ pPropSet->getPropertyValue(aPropertyName, rSet, aAny);
+ }
+ }
+ }
+ else
+ switch ( pEntry->nWID )
+ {
+ case SC_WID_UNO_CHCOLHDR:
+ case SC_WID_UNO_CHROWHDR:
+ ScUnoHelpFunctions::SetBoolInAny( aAny, FALSE );
+ break;
+ case SC_WID_UNO_CELLSTYL:
+ aAny <<= rtl::OUString( ScStyleNameConversion::DisplayToProgrammaticName(
+ ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA ) );
+ break;
+ case SC_WID_UNO_TBLBORD:
+ {
+ const ScPatternAttr* pPattern = pDoc->GetDefPattern();
+ if ( pPattern )
+ {
+ table::TableBorder aBorder;
+ ScHelperFunctions::FillTableBorder( aBorder,
+ (const SvxBoxItem&)pPattern->GetItem(ATTR_BORDER),
+ (const SvxBoxInfoItem&)pPattern->GetItem(ATTR_BORDER_INNER) );
+ aAny <<= aBorder;
+ }
+ }
+ break;
+ case SC_WID_UNO_CONDFMT:
+ case SC_WID_UNO_CONDLOC:
+ case SC_WID_UNO_CONDXML:
+ {
+ BOOL bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
+ BOOL bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
+ formula::FormulaGrammar::Grammar eGrammar = (bXML ?
+ pDoc->GetStorageGrammar() :
+ formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
+
+ aAny <<= uno::Reference<sheet::XSheetConditionalEntries>(
+ new ScTableConditionalFormat( pDoc, 0, eGrammar ));
+ }
+ break;
+ case SC_WID_UNO_VALIDAT:
+ case SC_WID_UNO_VALILOC:
+ case SC_WID_UNO_VALIXML:
+ {
+ BOOL bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
+ BOOL bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
+ formula::FormulaGrammar::Grammar eGrammar = (bXML ?
+ pDoc->GetStorageGrammar() :
+ formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
+
+ aAny <<= uno::Reference<beans::XPropertySet>(
+ new ScTableValidationObj( pDoc, 0, eGrammar ));
+ }
+ break;
+ case SC_WID_UNO_NUMRULES:
+ {
+ aAny <<= uno::Reference<container::XIndexReplace>(ScStyleObj::CreateEmptyNumberingRules());
+ }
+ break;
+ }
+ }
+ }
+
+ return aAny;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangesBase::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( pPropSet->getPropertyMap() ));
+ return aRef;
+}
+
+
+void lcl_SetCellProperty( const SfxItemPropertySimpleEntry& rEntry, const uno::Any& rValue,
+ ScPatternAttr& rPattern, ScDocument* pDoc,
+ USHORT& rFirstItemId, USHORT& rSecondItemId )
+{
+ rFirstItemId = rEntry.nWID;
+ rSecondItemId = 0;
+
+ SfxItemSet& rSet = rPattern.GetItemSet();
+ switch ( rEntry.nWID )
+ {
+ case ATTR_VALUE_FORMAT:
+ {
+ // #67847# language for number formats
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ ULONG nOldFormat = ((const SfxUInt32Item&)rSet.Get( ATTR_VALUE_FORMAT )).GetValue();
+ LanguageType eOldLang = ((const SvxLanguageItem&)rSet.Get( ATTR_LANGUAGE_FORMAT )).GetLanguage();
+ nOldFormat = pFormatter->GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
+
+ sal_Int32 nIntVal = 0;
+ if ( rValue >>= nIntVal )
+ {
+ ULONG nNewFormat = (ULONG)nIntVal;
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
+
+ const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
+ LanguageType eNewLang =
+ pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+ if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW )
+ {
+ rSet.Put( SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
+
+ // #40606# if only language is changed,
+ // don't touch number format attribute
+ ULONG nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
+ if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
+ nNewMod <= SV_MAX_ANZ_STANDARD_FORMATE )
+ {
+ rFirstItemId = 0; // don't use ATTR_VALUE_FORMAT value
+ }
+
+ rSecondItemId = ATTR_LANGUAGE_FORMAT;
+ }
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ break;
+ case ATTR_INDENT:
+ {
+ sal_Int16 nIntVal = 0;
+ if ( rValue >>= nIntVal )
+ rSet.Put( SfxUInt16Item( rEntry.nWID, (USHORT)HMMToTwips(nIntVal) ) );
+ else
+ throw lang::IllegalArgumentException();
+ }
+ break;
+ case ATTR_ROTATE_VALUE:
+ {
+ sal_Int32 nRotVal = 0;
+ if ( rValue >>= nRotVal )
+ {
+ // stored value is always between 0 and 360 deg.
+ nRotVal %= 36000;
+ if ( nRotVal < 0 )
+ nRotVal += 36000;
+
+ rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, nRotVal ) );
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ break;
+ case ATTR_STACKED:
+ {
+ table::CellOrientation eOrient;
+ if( rValue >>= eOrient )
+ {
+ switch( eOrient )
+ {
+ case table::CellOrientation_STANDARD:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, FALSE ) );
+ break;
+ case table::CellOrientation_TOPBOTTOM:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, FALSE ) );
+ rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
+ rSecondItemId = ATTR_ROTATE_VALUE;
+ break;
+ case table::CellOrientation_BOTTOMTOP:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, FALSE ) );
+ rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
+ rSecondItemId = ATTR_ROTATE_VALUE;
+ break;
+ case table::CellOrientation_STACKED:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, TRUE ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ lcl_GetCellsPropertySet()->setPropertyValue(rEntry, rValue, rSet);
+ }
+ }
+}
+
+void SAL_CALL ScCellRangesBase::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell || aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ SetOnePropertyValue( pEntry, aValue );
+}
+
+void ScCellRangesBase::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ if ( aRanges.Count() ) // leer = nichts zu tun
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDocFunc aFunc(*pDocShell);
+
+ // Fuer Teile von zusammengesetzten Items mit mehreren Properties (z.B. Hintergrund)
+ // muss vorher das alte Item aus dem Dokument geholt werden
+ //! Das kann hier aber nicht erkannt werden
+ //! -> eigenes Flag im PropertyMap-Eintrag, oder was ???
+ //! Item direkt von einzelner Position im Bereich holen?
+ // ClearInvalidItems, damit auf jeden Fall ein Item vom richtigen Typ da ist
+
+ ScPatternAttr aPattern( *GetCurrentAttrsDeep() );
+ SfxItemSet& rSet = aPattern.GetItemSet();
+ rSet.ClearInvalidItems();
+
+ USHORT nFirstItem, nSecondItem;
+ lcl_SetCellProperty( *pEntry, aValue, aPattern, pDoc, nFirstItem, nSecondItem );
+
+ for (USHORT nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
+ if ( nWhich != nFirstItem && nWhich != nSecondItem )
+ rSet.ClearItem(nWhich);
+
+ aFunc.ApplyAttributes( *GetMarkData(), aPattern, TRUE, TRUE );
+ }
+ }
+ else // implemented here
+ switch ( pEntry->nWID )
+ {
+ case SC_WID_UNO_CHCOLHDR:
+ // chart header flags are set for this object, not stored with document
+ bChartColAsHdr = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ break;
+ case SC_WID_UNO_CHROWHDR:
+ bChartRowAsHdr = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ break;
+ case SC_WID_UNO_CELLSTYL:
+ {
+ rtl::OUString aStrVal;
+ aValue >>= aStrVal;
+ String aString(ScStyleNameConversion::ProgrammaticToDisplayName(
+ aStrVal, SFX_STYLE_FAMILY_PARA ));
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.ApplyStyle( *GetMarkData(), aString, TRUE, TRUE );
+ }
+ break;
+ case SC_WID_UNO_TBLBORD:
+ {
+ table::TableBorder aBorder;
+ if ( aRanges.Count() && ( aValue >>= aBorder ) ) // empty = nothing to do
+ {
+ SvxBoxItem aOuter(ATTR_BORDER);
+ SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
+ ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder );
+
+ ScHelperFunctions::ApplyBorder( pDocShell, aRanges, aOuter, aInner ); //! docfunc
+ }
+ }
+ break;
+ case SC_WID_UNO_CONDFMT:
+ case SC_WID_UNO_CONDLOC:
+ case SC_WID_UNO_CONDXML:
+ {
+ uno::Reference<sheet::XSheetConditionalEntries> xInterface(aValue, uno::UNO_QUERY);
+ if ( aRanges.Count() && xInterface.is() ) // leer = nichts zu tun
+ {
+ ScTableConditionalFormat* pFormat =
+ ScTableConditionalFormat::getImplementation( xInterface );
+ if (pFormat)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
+ BOOL bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
+ formula::FormulaGrammar::Grammar eGrammar = (bXML ?
+ formula::FormulaGrammar::GRAM_UNSPECIFIED :
+ formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
+
+ ScConditionalFormat aNew( 0, pDoc ); // Index wird beim Einfuegen gesetzt
+ pFormat->FillFormat( aNew, pDoc, eGrammar );
+ ULONG nIndex = pDoc->AddCondFormat( aNew );
+
+ ScDocFunc aFunc(*pDocShell);
+
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nIndex ) );
+ aFunc.ApplyAttributes( *GetMarkData(), aPattern, TRUE, TRUE );
+ }
+ }
+ }
+ break;
+ case SC_WID_UNO_VALIDAT:
+ case SC_WID_UNO_VALILOC:
+ case SC_WID_UNO_VALIXML:
+ {
+ uno::Reference<beans::XPropertySet> xInterface(aValue, uno::UNO_QUERY);
+ if ( aRanges.Count() && xInterface.is() ) // leer = nichts zu tun
+ {
+ ScTableValidationObj* pValidObj =
+ ScTableValidationObj::getImplementation( xInterface );
+ if (pValidObj)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
+ BOOL bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
+ formula::FormulaGrammar::Grammar eGrammar = (bXML ?
+ formula::FormulaGrammar::GRAM_UNSPECIFIED :
+ formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
+
+ ScValidationData* pNewData =
+ pValidObj->CreateValidationData( pDoc, eGrammar );
+ ULONG nIndex = pDoc->AddValidationEntry( *pNewData );
+ delete pNewData;
+
+ ScDocFunc aFunc(*pDocShell);
+
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nIndex ) );
+ aFunc.ApplyAttributes( *GetMarkData(), aPattern, TRUE, TRUE );
+ }
+ }
+ }
+ break;
+ // SC_WID_UNO_NUMRULES is ignored...
+ }
+ }
+}
+
+uno::Any SAL_CALL ScCellRangesBase::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell || aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ uno::Any aAny;
+ GetOnePropertyValue( pEntry, aAny );
+ return aAny;
+}
+
+void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
+ uno::Any& rAny )
+ throw(uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ SfxItemSet* pDataSet = GetCurrentDataSet();
+ if ( pDataSet )
+ {
+ switch ( pEntry->nWID ) // fuer Item-Spezial-Behandlungen
+ {
+ case ATTR_VALUE_FORMAT:
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ULONG nOldFormat = ((const SfxUInt32Item&)
+ pDataSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ LanguageType eOldLang = ((const SvxLanguageItem&)
+ pDataSet->Get( ATTR_LANGUAGE_FORMAT )).GetLanguage();
+ nOldFormat = pDoc->GetFormatTable()->
+ GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
+ rAny <<= (sal_Int32)( nOldFormat );
+ }
+ break;
+ case ATTR_INDENT:
+ rAny <<= (sal_Int16)( TwipsToHMM(((const SfxUInt16Item&)
+ pDataSet->Get(pEntry->nWID)).GetValue()) );
+ break;
+ case ATTR_STACKED:
+ {
+ sal_Int32 nRot = ((const SfxInt32Item&)pDataSet->Get(ATTR_ROTATE_VALUE)).GetValue();
+ BOOL bStacked = ((const SfxBoolItem&)pDataSet->Get(pEntry->nWID)).GetValue();
+ SvxOrientationItem( nRot, bStacked, 0 ).QueryValue( rAny );
+ }
+ break;
+ default:
+ pPropSet->getPropertyValue(*pEntry, *pDataSet, rAny);
+ }
+ }
+ }
+ else // implemented here
+ switch ( pEntry->nWID )
+ {
+ case SC_WID_UNO_CHCOLHDR:
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bChartColAsHdr );
+ break;
+ case SC_WID_UNO_CHROWHDR:
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bChartRowAsHdr );
+ break;
+ case SC_WID_UNO_CELLSTYL:
+ {
+ String aStyleName;
+ const ScStyleSheet* pStyle = pDocShell->GetDocument()->GetSelectionStyle(*GetMarkData());
+ if (pStyle)
+ aStyleName = pStyle->GetName();
+ rAny <<= rtl::OUString( ScStyleNameConversion::DisplayToProgrammaticName(
+ aStyleName, SFX_STYLE_FAMILY_PARA ) );
+ }
+ break;
+ case SC_WID_UNO_TBLBORD:
+ {
+ //! loop throgh all ranges
+ const ScRange* pFirst = aRanges.GetObject(0);
+ if (pFirst)
+ {
+ SvxBoxItem aOuter(ATTR_BORDER);
+ SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScMarkData aMark;
+ aMark.SetMarkArea( *pFirst );
+ aMark.SelectTable( pFirst->aStart.Tab(), TRUE );
+ pDoc->GetSelectionFrame( aMark, aOuter, aInner );
+
+ table::TableBorder aBorder;
+ ScHelperFunctions::FillTableBorder( aBorder, aOuter, aInner );
+ rAny <<= aBorder;
+ }
+ }
+ break;
+ case SC_WID_UNO_CONDFMT:
+ case SC_WID_UNO_CONDLOC:
+ case SC_WID_UNO_CONDXML:
+ {
+ const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
+ if ( pPattern )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
+ BOOL bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
+ formula::FormulaGrammar::Grammar eGrammar = (bXML ?
+ pDoc->GetStorageGrammar() :
+ formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
+ ULONG nIndex = ((const SfxUInt32Item&)
+ pPattern->GetItem(ATTR_CONDITIONAL)).GetValue();
+ rAny <<= uno::Reference<sheet::XSheetConditionalEntries>(
+ new ScTableConditionalFormat( pDoc, nIndex, eGrammar ));
+ }
+ }
+ break;
+ case SC_WID_UNO_VALIDAT:
+ case SC_WID_UNO_VALILOC:
+ case SC_WID_UNO_VALIXML:
+ {
+ const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
+ if ( pPattern )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
+ BOOL bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
+ formula::FormulaGrammar::Grammar eGrammar = (bXML ?
+ pDoc->GetStorageGrammar() :
+ formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
+ ULONG nIndex = ((const SfxUInt32Item&)
+ pPattern->GetItem(ATTR_VALIDDATA)).GetValue();
+ rAny <<= uno::Reference<beans::XPropertySet>(
+ new ScTableValidationObj( pDoc, nIndex, eGrammar ));
+ }
+ }
+ break;
+ case SC_WID_UNO_NUMRULES:
+ {
+ // always return empty numbering rules object
+ rAny <<= uno::Reference<container::XIndexReplace>(ScStyleObj::CreateEmptyNumberingRules());
+ }
+ break;
+ case SC_WID_UNO_ABSNAME:
+ {
+ String sRet;
+ aRanges.Format(sRet, SCR_ABS_3D, pDocShell->GetDocument());
+ rAny <<= rtl::OUString(sRet);
+ }
+ }
+ }
+}
+
+void SAL_CALL ScCellRangesBase::addPropertyChangeListener( const rtl::OUString& /* aPropertyName */,
+ const uno::Reference<beans::XPropertyChangeListener>& /* aListener */)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScCellRangesBase::removePropertyChangeListener( const rtl::OUString& /* aPropertyName */,
+ const uno::Reference<beans::XPropertyChangeListener>& /* aListener */)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScCellRangesBase::addVetoableChangeListener( const rtl::OUString&,
+ const uno::Reference<beans::XVetoableChangeListener>&)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScCellRangesBase::removeVetoableChangeListener( const rtl::OUString&,
+ const uno::Reference<beans::XVetoableChangeListener>&)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+// XMultiPropertySet
+
+void SAL_CALL ScCellRangesBase::setPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames,
+ const uno::Sequence< uno::Any >& aValues )
+ throw (beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Int32 nCount(aPropertyNames.getLength());
+ sal_Int32 nValues(aValues.getLength());
+ if (nCount != nValues)
+ throw lang::IllegalArgumentException();
+
+ if ( pDocShell && nCount )
+ {
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ const uno::Any* pValues = aValues.getConstArray();
+
+ const SfxItemPropertySimpleEntry** pEntryArray = new const SfxItemPropertySimpleEntry*[nCount];
+
+ sal_Int32 i;
+ for(i = 0; i < nCount; i++)
+ {
+ // first loop: find all properties in map, but handle only CellStyle
+ // (CellStyle must be set before any other cell properties)
+
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( pNames[i] );
+ pEntryArray[i] = pEntry;
+ if (pEntry)
+ {
+ if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
+ {
+ try
+ {
+ SetOnePropertyValue( pEntry, pValues[i] );
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ DBG_ERROR("exception when setting cell style"); // not supposed to happen
+ }
+ }
+ }
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScPatternAttr* pOldPattern = NULL;
+ ScPatternAttr* pNewPattern = NULL;
+
+ for(i = 0; i < nCount; i++)
+ {
+ // second loop: handle other properties
+
+ const SfxItemPropertySimpleEntry* pEntry = pEntryArray[i];
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) ) // can be handled by SfxItemPropertySet
+ {
+ if ( !pOldPattern )
+ {
+ pOldPattern = new ScPatternAttr( *GetCurrentAttrsDeep() );
+ pOldPattern->GetItemSet().ClearInvalidItems();
+ pNewPattern = new ScPatternAttr( pDoc->GetPool() );
+ }
+
+ // collect items in pNewPattern, apply with one call after the loop
+
+ USHORT nFirstItem, nSecondItem;
+ lcl_SetCellProperty( *pEntry, pValues[i], *pOldPattern, pDoc, nFirstItem, nSecondItem );
+
+ // put only affected items into new set
+ if ( nFirstItem )
+ pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nFirstItem ) );
+ if ( nSecondItem )
+ pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nSecondItem ) );
+ }
+ else if ( pEntry->nWID != SC_WID_UNO_CELLSTYL ) // CellStyle is handled above
+ {
+ // call virtual method to set a single property
+ SetOnePropertyValue( pEntry, pValues[i] );
+ }
+ }
+ }
+
+ if ( pNewPattern && aRanges.Count() )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.ApplyAttributes( *GetMarkData(), *pNewPattern, TRUE, TRUE );
+ }
+
+ delete pNewPattern;
+ delete pOldPattern;
+ delete[] pEntryArray;
+ }
+}
+
+uno::Sequence<uno::Any> SAL_CALL ScCellRangesBase::getPropertyValues(
+ const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+
+ uno::Sequence<uno::Any> aRet(aPropertyNames.getLength());
+ uno::Any* pProperties = aRet.getArray();
+ for(INT32 i = 0; i < aPropertyNames.getLength(); i++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
+ GetOnePropertyValue( pEntry, pProperties[i] );
+ }
+ return aRet;
+}
+
+void SAL_CALL ScCellRangesBase::addPropertiesChangeListener( const uno::Sequence< rtl::OUString >& /* aPropertyNames */,
+ const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScCellRangesBase::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScCellRangesBase::firePropertiesChangeEvent( const uno::Sequence< rtl::OUString >& /* aPropertyNames */,
+ const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+IMPL_LINK( ScCellRangesBase, ValueListenerHdl, SfxHint*, pHint )
+{
+ if ( pDocShell && pHint && pHint->ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint*)pHint)->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING) )
+ {
+ // This may be called several times for a single change, if several formulas
+ // in the range are notified. So only a flag is set that is checked when
+ // SFX_HINT_DATACHANGED is received.
+
+ bGotDataChangedHint = TRUE;
+ }
+ return 0;
+}
+
+// XTolerantMultiPropertySet
+uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL ScCellRangesBase::setPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames,
+ const uno::Sequence< uno::Any >& aValues )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Int32 nCount(aPropertyNames.getLength());
+ sal_Int32 nValues(aValues.getLength());
+ if (nCount != nValues)
+ throw lang::IllegalArgumentException();
+
+ if ( pDocShell && nCount )
+ {
+ uno::Sequence < beans::SetPropertyTolerantFailed > aReturns(nCount);
+ beans::SetPropertyTolerantFailed* pReturns = aReturns.getArray();
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ const uno::Any* pValues = aValues.getConstArray();
+
+ const SfxItemPropertySimpleEntry** pMapArray = new const SfxItemPropertySimpleEntry*[nCount];
+
+ sal_Int32 i;
+ for(i = 0; i < nCount; i++)
+ {
+ // first loop: find all properties in map, but handle only CellStyle
+ // (CellStyle must be set before any other cell properties)
+
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( pNames[i] );
+ pMapArray[i] = pEntry;
+ if (pEntry)
+ {
+ if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
+ {
+ try
+ {
+ SetOnePropertyValue( pEntry, pValues[i] );
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ DBG_ERROR("exception when setting cell style"); // not supposed to happen
+ }
+ }
+ }
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScPatternAttr* pOldPattern = NULL;
+ ScPatternAttr* pNewPattern = NULL;
+
+ sal_Int32 nFailed(0);
+ for(i = 0; i < nCount; i++)
+ {
+ // second loop: handle other properties
+
+ const SfxItemPropertySimpleEntry* pEntry = pMapArray[i];
+ if ( pEntry && ((pEntry->nFlags & beans::PropertyAttribute::READONLY) == 0))
+ {
+ if ( IsScItemWid( pEntry->nWID ) ) // can be handled by SfxItemPropertySet
+ {
+ if ( !pOldPattern )
+ {
+ pOldPattern = new ScPatternAttr( *GetCurrentAttrsDeep() );
+ pOldPattern->GetItemSet().ClearInvalidItems();
+ pNewPattern = new ScPatternAttr( pDoc->GetPool() );
+ }
+
+ // collect items in pNewPattern, apply with one call after the loop
+
+ USHORT nFirstItem, nSecondItem;
+ try
+ {
+ lcl_SetCellProperty( *pEntry, pValues[i], *pOldPattern, pDoc, nFirstItem, nSecondItem );
+
+ // put only affected items into new set
+ if ( nFirstItem )
+ pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nFirstItem ) );
+ if ( nSecondItem )
+ pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nSecondItem ) );
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ pReturns[nFailed].Name = pNames[i];
+ pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
+ }
+ }
+ else if ( pEntry->nWID != SC_WID_UNO_CELLSTYL ) // CellStyle is handled above
+ {
+ // call virtual method to set a single property
+ try
+ {
+ SetOnePropertyValue( pEntry, pValues[i] );
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ pReturns[nFailed].Name = pNames[i];
+ pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
+ }
+ }
+ }
+ else
+ {
+ pReturns[nFailed].Name = pNames[i];
+ if (pEntry)
+ pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ else
+ pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ }
+
+ if ( pNewPattern && aRanges.Count() )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.ApplyAttributes( *GetMarkData(), *pNewPattern, TRUE, TRUE );
+ }
+
+ delete pNewPattern;
+ delete pOldPattern;
+ delete[] pMapArray;
+
+ aReturns.realloc(nFailed);
+
+ return aReturns;
+ }
+ return uno::Sequence < beans::SetPropertyTolerantFailed >();
+}
+
+uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL ScCellRangesBase::getPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Int32 nCount(aPropertyNames.getLength());
+ uno::Sequence < beans::GetPropertyTolerantResult > aReturns(nCount);
+ beans::GetPropertyTolerantResult* pReturns = aReturns.getArray();
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+
+ for(INT32 i = 0; i < nCount; i++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
+ if (!pEntry)
+ {
+ pReturns[i].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ USHORT nItemWhich = 0;
+ lcl_GetPropertyWhich( pEntry, nItemWhich );
+ pReturns[i].State = GetOnePropertyState( nItemWhich, pEntry );
+ GetOnePropertyValue( pEntry, pReturns[i].Value );
+ pReturns[i].Result = beans::TolerantPropertySetResultType::SUCCESS;
+ }
+ }
+ return aReturns;
+}
+
+uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL ScCellRangesBase::getDirectPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Int32 nCount(aPropertyNames.getLength());
+ uno::Sequence < beans::GetDirectPropertyTolerantResult > aReturns(nCount);
+ beans::GetDirectPropertyTolerantResult* pReturns = aReturns.getArray();
+
+ const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap(); // from derived class
+
+ INT32 j = 0;
+ for(INT32 i = 0; i < nCount; i++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
+ if (!pEntry)
+ {
+ pReturns[i].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ USHORT nItemWhich = 0;
+ lcl_GetPropertyWhich( pEntry, nItemWhich );
+ pReturns[j].State = GetOnePropertyState( nItemWhich, pEntry );
+ if (pReturns[j].State == beans::PropertyState_DIRECT_VALUE)
+ {
+ GetOnePropertyValue( pEntry, pReturns[j].Value );
+ pReturns[j].Result = beans::TolerantPropertySetResultType::SUCCESS;
+ pReturns[j].Name = aPropertyNames[i];
+ ++j;
+ }
+ }
+ }
+ if (j < nCount)
+ aReturns.realloc(j);
+ return aReturns;
+}
+
+// XIndent
+
+void SAL_CALL ScCellRangesBase::decrementIndent() throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell && aRanges.Count() ) // leer = nichts zu tun
+ {
+ ScDocFunc aFunc(*pDocShell);
+ //#97041#; put only MultiMarked ScMarkData in ChangeIndent
+ ScMarkData aMarkData(*GetMarkData());
+ aMarkData.MarkToMulti();
+ aFunc.ChangeIndent( aMarkData, FALSE, TRUE );
+ }
+}
+
+void SAL_CALL ScCellRangesBase::incrementIndent() throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell && aRanges.Count() ) // leer = nichts zu tun
+ {
+ ScDocFunc aFunc(*pDocShell);
+ //#97041#; put only MultiMarked ScMarkData in ChangeIndent
+ ScMarkData aMarkData(*GetMarkData());
+ aMarkData.MarkToMulti();
+ aFunc.ChangeIndent( aMarkData, TRUE, TRUE );
+ }
+}
+
+// XChartData
+
+ScMemChart* ScCellRangesBase::CreateMemChart_Impl() const
+{
+ if ( pDocShell && aRanges.Count() )
+ {
+ ScRangeListRef xChartRanges;
+ if ( aRanges.Count() == 1 )
+ {
+ // ganze Tabelle sinnvoll begrenzen (auf belegten Datenbereich)
+ // (nur hier, Listener werden auf den ganzen Bereich angemeldet)
+ //! direkt testen, ob es ein ScTableSheetObj ist?
+
+ ScRange* pRange = aRanges.GetObject(0);
+ if ( pRange->aStart.Col() == 0 && pRange->aEnd.Col() == MAXCOL &&
+ pRange->aStart.Row() == 0 && pRange->aEnd.Row() == MAXROW )
+ {
+ SCTAB nTab = pRange->aStart.Tab();
+
+ SCCOL nStartX;
+ SCROW nStartY; // Anfang holen
+ if (!pDocShell->GetDocument()->GetDataStart( nTab, nStartX, nStartY ))
+ {
+ nStartX = 0;
+ nStartY = 0;
+ }
+
+ SCCOL nEndX;
+ SCROW nEndY; // Ende holen
+ if (!pDocShell->GetDocument()->GetTableArea( nTab, nEndX, nEndY ))
+ {
+ nEndX = 0;
+ nEndY = 0;
+ }
+
+ xChartRanges = new ScRangeList;
+ xChartRanges->Append( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
+ }
+ }
+ if (!xChartRanges.Is()) // sonst Ranges direkt uebernehmen
+ xChartRanges = new ScRangeList(aRanges);
+ ScChartArray aArr( pDocShell->GetDocument(), xChartRanges, String() );
+
+ // RowAsHdr = ColHeaders und umgekehrt
+ aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr );
+
+ return aArr.CreateMemChart();
+ }
+ return NULL;
+}
+
+uno::Sequence< uno::Sequence<double> > SAL_CALL ScCellRangesBase::getData()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScMemChart* pMemChart = CreateMemChart_Impl();
+ if ( pMemChart )
+ {
+ sal_Int32 nColCount = pMemChart->GetColCount();
+ sal_Int32 nRowCount = static_cast<sal_Int32>(pMemChart->GetRowCount());
+
+ uno::Sequence< uno::Sequence<double> > aRowSeq( nRowCount );
+ uno::Sequence<double>* pRowAry = aRowSeq.getArray();
+ for (sal_Int32 nRow = 0; nRow < nRowCount; nRow++)
+ {
+ uno::Sequence<double> aColSeq( nColCount );
+ double* pColAry = aColSeq.getArray();
+ for (sal_Int32 nCol = 0; nCol < nColCount; nCol++)
+ pColAry[nCol] = pMemChart->GetData( static_cast<short>(nCol), static_cast<short>(nRow) );
+
+ pRowAry[nRow] = aColSeq;
+ }
+
+ delete pMemChart;
+ return aRowSeq;
+ }
+
+ return uno::Sequence< uno::Sequence<double> >(0);
+}
+
+ScRangeListRef ScCellRangesBase::GetLimitedChartRanges_Impl( long nDataColumns, long nDataRows ) const
+{
+ if ( aRanges.Count() == 1 )
+ {
+ ScRange* pRange = aRanges.GetObject(0);
+ if ( pRange->aStart.Col() == 0 && pRange->aEnd.Col() == MAXCOL &&
+ pRange->aStart.Row() == 0 && pRange->aEnd.Row() == MAXROW )
+ {
+ // if aRanges is a complete sheet, limit to given size
+
+ SCTAB nTab = pRange->aStart.Tab();
+
+ long nEndColumn = nDataColumns - 1 + ( bChartColAsHdr ? 1 : 0 );
+ if ( nEndColumn < 0 )
+ nEndColumn = 0;
+ if ( nEndColumn > MAXCOL )
+ nEndColumn = MAXCOL;
+
+ long nEndRow = nDataRows - 1 + ( bChartRowAsHdr ? 1 : 0 );
+ if ( nEndRow < 0 )
+ nEndRow = 0;
+ if ( nEndRow > MAXROW )
+ nEndRow = MAXROW;
+
+ ScRangeListRef xChartRanges = new ScRangeList;
+ xChartRanges->Append( ScRange( 0, 0, nTab, (SCCOL)nEndColumn, (SCROW)nEndRow, nTab ) );
+ return xChartRanges;
+ }
+ }
+
+ return new ScRangeList(aRanges); // as-is
+}
+
+void SAL_CALL ScCellRangesBase::setData( const uno::Sequence< uno::Sequence<double> >& aData )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ long nRowCount = aData.getLength();
+ long nColCount = nRowCount ? aData[0].getLength() : 0;
+ ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( nColCount, nRowCount );
+ if ( pDocShell && xChartRanges.Is() )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChartArray aArr( pDoc, xChartRanges, String() );
+ aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr ); // RowAsHdr = ColHeaders
+ const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
+ if (pPosMap)
+ {
+ if ( pPosMap->GetColCount() == static_cast<SCCOL>(nColCount) &&
+ pPosMap->GetRowCount() == static_cast<SCROW>(nRowCount) )
+ {
+ for (long nRow=0; nRow<nRowCount; nRow++)
+ {
+ const uno::Sequence<double>& rRowSeq = aData[nRow];
+ const double* pArray = rRowSeq.getConstArray();
+ nColCount = rRowSeq.getLength();
+ for (long nCol=0; nCol<nColCount; nCol++)
+ {
+ const ScAddress* pPos = pPosMap->GetPosition(
+ sal::static_int_cast<SCCOL>(nCol),
+ sal::static_int_cast<SCROW>(nRow) );
+ if (pPos)
+ {
+ double fVal = pArray[nCol];
+ if ( fVal == DBL_MIN )
+ pDoc->PutCell( *pPos, NULL ); // empty cell
+ else
+ pDoc->SetValue( pPos->Col(), pPos->Row(), pPos->Tab(), pArray[nCol] );
+ }
+ }
+ }
+
+ //! undo
+ PaintRanges_Impl( PAINT_GRID );
+ pDocShell->SetDocumentModified();
+ ForceChartListener_Impl(); // call listeners for this object synchronously
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesBase::getRowDescriptions()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScMemChart* pMemChart = CreateMemChart_Impl();
+ if ( pMemChart )
+ {
+ sal_Int32 nRowCount = static_cast<sal_Int32>(pMemChart->GetRowCount());
+ uno::Sequence<rtl::OUString> aSeq( nRowCount );
+ rtl::OUString* pAry = aSeq.getArray();
+ for (sal_Int32 nRow = 0; nRow < nRowCount; nRow++)
+ pAry[nRow] = pMemChart->GetRowText(static_cast<short>(nRow));
+
+ delete pMemChart;
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+void SAL_CALL ScCellRangesBase::setRowDescriptions(
+ const uno::Sequence<rtl::OUString>& aRowDescriptions )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if ( bChartColAsHdr )
+ {
+ long nRowCount = aRowDescriptions.getLength();
+ ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( 1, nRowCount );
+ if ( pDocShell && xChartRanges.Is() )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChartArray aArr( pDoc, xChartRanges, String() );
+ aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr ); // RowAsHdr = ColHeaders
+ const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
+ if (pPosMap)
+ {
+ if ( pPosMap->GetRowCount() == static_cast<SCROW>(nRowCount) )
+ {
+ const rtl::OUString* pArray = aRowDescriptions.getConstArray();
+ for (long nRow=0; nRow<nRowCount; nRow++)
+ {
+ const ScAddress* pPos = pPosMap->GetRowHeaderPosition(
+ static_cast<SCSIZE>(nRow) );
+ if (pPos)
+ {
+ String aStr = pArray[nRow];
+ if ( aStr.Len() )
+ pDoc->PutCell( *pPos, new ScStringCell( aStr ) );
+ else
+ pDoc->PutCell( *pPos, NULL ); // empty cell
+ }
+ }
+
+ //! undo
+ PaintRanges_Impl( PAINT_GRID );
+ pDocShell->SetDocumentModified();
+ ForceChartListener_Impl(); // call listeners for this object synchronously
+ bDone = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesBase::getColumnDescriptions()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScMemChart* pMemChart = CreateMemChart_Impl();
+ if ( pMemChart )
+ {
+ sal_Int32 nColCount = pMemChart->GetColCount();
+ uno::Sequence<rtl::OUString> aSeq( nColCount );
+ rtl::OUString* pAry = aSeq.getArray();
+ for (sal_Int32 nCol = 0; nCol < nColCount; nCol++)
+ pAry[nCol] = pMemChart->GetColText(static_cast<short>(nCol));
+
+ delete pMemChart;
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+void SAL_CALL ScCellRangesBase::setColumnDescriptions(
+ const uno::Sequence<rtl::OUString>& aColumnDescriptions )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if ( bChartRowAsHdr )
+ {
+ long nColCount = aColumnDescriptions.getLength();
+ ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( nColCount, 1 );
+ if ( pDocShell && xChartRanges.Is() )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChartArray aArr( pDoc, xChartRanges, String() );
+ aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr ); // RowAsHdr = ColHeaders
+ const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
+ if (pPosMap)
+ {
+ if ( pPosMap->GetColCount() == static_cast<SCCOL>(nColCount) )
+ {
+ const rtl::OUString* pArray = aColumnDescriptions.getConstArray();
+ for (long nCol=0; nCol<nColCount; nCol++)
+ {
+ const ScAddress* pPos = pPosMap->GetColHeaderPosition(
+ sal::static_int_cast<SCCOL>(nCol) );
+ if (pPos)
+ {
+ String aStr(pArray[nCol]);
+ if ( aStr.Len() )
+ pDoc->PutCell( *pPos, new ScStringCell( aStr ) );
+ else
+ pDoc->PutCell( *pPos, NULL ); // empty cell
+ }
+ }
+
+ //! undo
+ PaintRanges_Impl( PAINT_GRID );
+ pDocShell->SetDocumentModified();
+ ForceChartListener_Impl(); // call listeners for this object synchronously
+ bDone = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException();
+}
+
+void ScCellRangesBase::ForceChartListener_Impl()
+{
+ // call Update immediately so the caller to setData etc. can
+ // regognize the listener call
+
+ if ( pDocShell )
+ {
+ ScChartListenerCollection* pColl = pDocShell->GetDocument()->GetChartListenerCollection();
+ if ( pColl )
+ {
+ USHORT nCollCount = pColl->GetCount();
+ for ( USHORT nIndex = 0; nIndex < nCollCount; nIndex++ )
+ {
+ ScChartListener* pChartListener = (ScChartListener*)pColl->At(nIndex);
+ if ( pChartListener &&
+ pChartListener->GetUnoSource() == static_cast<chart::XChartData*>(this) &&
+ pChartListener->IsDirty() )
+ pChartListener->Update();
+ }
+ }
+ }
+}
+
+String lcl_UniqueName( ScStrCollection& rColl, const String& rPrefix )
+{
+ long nNumber = 1;
+ USHORT nCollCount = rColl.GetCount();
+ while (TRUE)
+ {
+ String aName(rPrefix);
+ aName += String::CreateFromInt32( nNumber );
+ BOOL bFound = FALSE;
+ for (USHORT i=0; i<nCollCount; i++)
+ if ( rColl[i]->GetString() == aName )
+ {
+ bFound = TRUE;
+ break;
+ }
+ if (!bFound)
+ return aName;
+ ++nNumber;
+ }
+}
+
+void SAL_CALL ScCellRangesBase::addChartDataChangeEventListener( const uno::Reference<
+ chart::XChartDataChangeEventListener >& aListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell && aRanges.Count() )
+ {
+ //! auf doppelte testen?
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangeListRef aRangesRef( new ScRangeList(aRanges) );
+ ScChartListenerCollection* pColl = pDoc->GetChartListenerCollection();
+ String aName(lcl_UniqueName( *pColl,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("__Uno")) ));
+ ScChartListener* pListener = new ScChartListener( aName, pDoc, aRangesRef );
+ pListener->SetUno( aListener, this );
+ pColl->Insert( pListener );
+ pListener->StartListeningTo();
+ }
+}
+
+void SAL_CALL ScCellRangesBase::removeChartDataChangeEventListener( const uno::Reference<
+ chart::XChartDataChangeEventListener >& aListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell && aRanges.Count() )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScChartListenerCollection* pColl = pDoc->GetChartListenerCollection();
+ pColl->FreeUno( aListener, this );
+ }
+}
+
+double SAL_CALL ScCellRangesBase::getNotANumber() throw(::com::sun::star::uno::RuntimeException)
+{
+ // im ScChartArray wird DBL_MIN verwendet, weil das Chart es so will
+ return DBL_MIN;
+}
+
+sal_Bool SAL_CALL ScCellRangesBase::isNotANumber( double nNumber ) throw(uno::RuntimeException)
+{
+ // im ScChartArray wird DBL_MIN verwendet, weil das Chart es so will
+ return (nNumber == DBL_MIN);
+}
+
+// XModifyBroadcaster
+
+void SAL_CALL ScCellRangesBase::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ uno::Reference<util::XModifyListener> *pObj =
+ new uno::Reference<util::XModifyListener>( aListener );
+ aValueListeners.Insert( pObj, aValueListeners.Count() );
+
+ if ( aValueListeners.Count() == 1 )
+ {
+ if (!pValueListener)
+ pValueListener = new ScLinkListener( LINK( this, ScCellRangesBase, ValueListenerHdl ) );
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ pDoc->StartListeningArea( *aRanges.GetObject(i), pValueListener );
+
+ acquire(); // don't lose this object (one ref for all listeners)
+ }
+}
+
+void SAL_CALL ScCellRangesBase::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
+ throw(uno::RuntimeException)
+{
+
+ ScUnoGuard aGuard;
+ if ( aRanges.Count() == 0 )
+ throw uno::RuntimeException();
+
+ acquire(); // in case the listeners have the last ref - released below
+
+ USHORT nCount = aValueListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XModifyListener> *pObj = aValueListeners[n];
+ if ( *pObj == aListener )
+ {
+ aValueListeners.DeleteAndDestroy( n );
+
+ if ( aValueListeners.Count() == 0 )
+ {
+ if (pValueListener)
+ pValueListener->EndListeningAll();
+
+ release(); // release the ref for the listeners
+ }
+
+ break;
+ }
+ }
+
+ release(); // might delete this object
+}
+
+// XCellRangesQuery
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryVisibleCells()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ //! fuer alle Tabellen getrennt, wenn Markierungen pro Tabelle getrennt sind!
+ SCTAB nTab = lcl_FirstTab(aRanges);
+
+ ScMarkData aMarkData(*GetMarkData());
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCCOL nCol = 0, nLastCol;
+ while (nCol <= MAXCOL)
+ {
+ if (pDoc->ColHidden(nCol, nTab, nLastCol))
+ // hidden columns. Unselect them.
+ aMarkData.SetMultiMarkArea(ScRange(nCol, 0, nTab, nLastCol, MAXROW, nTab), false);
+
+ nCol = nLastCol + 1;
+ }
+
+ SCROW nRow = 0, nLastRow;
+ while (nRow <= MAXROW)
+ {
+ if (pDoc->RowHidden(nRow, nTab, nLastRow))
+ // These rows are hidden. Unselect them.
+ aMarkData.SetMultiMarkArea(ScRange(0, nRow, nTab, MAXCOL, nLastRow, nTab), false);
+
+ nRow = nLastRow + 1;
+ }
+
+ ScRangeList aNewRanges;
+ aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE );
+ return new ScCellRangesObj( pDocShell, aNewRanges );
+ }
+
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryEmptyCells()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScMarkData aMarkData(*GetMarkData());
+
+ // belegte Zellen wegmarkieren
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ // Notizen zaehlen als nicht-leer
+ if ( !pCell->IsBlank() )
+ aMarkData.SetMultiMarkArea(
+ ScRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ),
+ FALSE );
+
+ pCell = aIter.GetNext();
+ }
+ }
+
+ ScRangeList aNewRanges;
+ // IsMultiMarked reicht hier nicht (wird beim deselektieren nicht zurueckgesetzt)
+ if (aMarkData.HasAnyMultiMarks())
+ aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE );
+
+ return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges kann leer sein
+ }
+
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentCells(
+ sal_Int16 nContentFlags )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScMarkData aMarkData;
+
+ // passende Zellen selektieren
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ BOOL bAdd = FALSE;
+ if ( pCell->HasNote() && ( nContentFlags & sheet::CellFlags::ANNOTATION ) )
+ bAdd = TRUE;
+ else
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_STRING:
+ if ( nContentFlags & sheet::CellFlags::STRING )
+ bAdd = TRUE;
+ break;
+ case CELLTYPE_EDIT:
+ if ( (nContentFlags & sheet::CellFlags::STRING) || (nContentFlags & sheet::CellFlags::FORMATTED) )
+ bAdd = TRUE;
+ break;
+ case CELLTYPE_FORMULA:
+ if ( nContentFlags & sheet::CellFlags::FORMULA )
+ bAdd = TRUE;
+ break;
+ case CELLTYPE_VALUE:
+ if ( (nContentFlags & (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME))
+ == (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME) )
+ bAdd = TRUE;
+ else
+ {
+ // Date/Time Erkennung
+
+ ULONG nIndex = (ULONG)((SfxUInt32Item*)pDoc->GetAttr(
+ aIter.GetCol(), aIter.GetRow(), aIter.GetTab(),
+ ATTR_VALUE_FORMAT ))->GetValue();
+ short nTyp = pDoc->GetFormatTable()->GetType(nIndex);
+ if ((nTyp == NUMBERFORMAT_DATE) || (nTyp == NUMBERFORMAT_TIME) ||
+ (nTyp == NUMBERFORMAT_DATETIME))
+ {
+ if ( nContentFlags & sheet::CellFlags::DATETIME )
+ bAdd = TRUE;
+ }
+ else
+ {
+ if ( nContentFlags & sheet::CellFlags::VALUE )
+ bAdd = TRUE;
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (bAdd)
+ aMarkData.SetMultiMarkArea(
+ ScRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ),
+ TRUE );
+
+ pCell = aIter.GetNext();
+ }
+ }
+
+ ScRangeList aNewRanges;
+ if (aMarkData.IsMultiMarked())
+ aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE );
+
+ return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges kann leer sein
+ }
+
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryFormulaCells(
+ sal_Int32 nResultFlags )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScMarkData aMarkData;
+
+ // passende Zellen selektieren
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ BOOL bAdd = FALSE;
+ if (pFCell->GetErrCode())
+ {
+ if ( nResultFlags & sheet::FormulaResult::ERROR )
+ bAdd = TRUE;
+ }
+ else if (pFCell->IsValue())
+ {
+ if ( nResultFlags & sheet::FormulaResult::VALUE )
+ bAdd = TRUE;
+ }
+ else // String
+ {
+ if ( nResultFlags & sheet::FormulaResult::STRING )
+ bAdd = TRUE;
+ }
+
+ if (bAdd)
+ aMarkData.SetMultiMarkArea(
+ ScRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ),
+ TRUE );
+ }
+
+ pCell = aIter.GetNext();
+ }
+ }
+
+ ScRangeList aNewRanges;
+ if (aMarkData.IsMultiMarked())
+ aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE );
+
+ return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges kann leer sein
+ }
+
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl(
+ const table::CellAddress& aCompare, BOOL bColumnDiff)
+{
+ if (pDocShell)
+ {
+ ULONG nRangeCount = aRanges.Count();
+ ULONG i;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScMarkData aMarkData;
+
+ SCCOLROW nCmpPos = bColumnDiff ? (SCCOLROW)aCompare.Row : (SCCOLROW)aCompare.Column;
+
+ // zuerst alles selektieren, wo ueberhaupt etwas in der Vergleichsspalte steht
+ // (fuer gleiche Zellen wird die Selektion im zweiten Schritt aufgehoben)
+
+ SCTAB nTab = lcl_FirstTab(aRanges); //! fuer alle Tabellen, wenn Markierungen pro Tabelle!
+ ScRange aCmpRange, aCellRange;
+ if (bColumnDiff)
+ aCmpRange = ScRange( 0,nCmpPos,nTab, MAXCOL,nCmpPos,nTab );
+ else
+ aCmpRange = ScRange( static_cast<SCCOL>(nCmpPos),0,nTab, static_cast<SCCOL>(nCmpPos),MAXROW,nTab );
+ ScCellIterator aCmpIter( pDoc, aCmpRange );
+ ScBaseCell* pCmpCell = aCmpIter.GetFirst();
+ while (pCmpCell)
+ {
+ if (pCmpCell->GetCellType() != CELLTYPE_NOTE)
+ {
+ SCCOLROW nCellPos = bColumnDiff ? static_cast<SCCOLROW>(aCmpIter.GetCol()) : static_cast<SCCOLROW>(aCmpIter.GetRow());
+ if (bColumnDiff)
+ aCellRange = ScRange( static_cast<SCCOL>(nCellPos),0,nTab,
+ static_cast<SCCOL>(nCellPos),MAXROW,nTab );
+ else
+ aCellRange = ScRange( 0,nCellPos,nTab, MAXCOL,nCellPos,nTab );
+
+ for (i=0; i<nRangeCount; i++)
+ {
+ ScRange aRange(*aRanges.GetObject(i));
+ if ( aRange.Intersects( aCellRange ) )
+ {
+ if (bColumnDiff)
+ {
+ aRange.aStart.SetCol(static_cast<SCCOL>(nCellPos));
+ aRange.aEnd.SetCol(static_cast<SCCOL>(nCellPos));
+ }
+ else
+ {
+ aRange.aStart.SetRow(nCellPos);
+ aRange.aEnd.SetRow(nCellPos);
+ }
+ aMarkData.SetMultiMarkArea( aRange );
+ }
+ }
+ }
+ pCmpCell = aCmpIter.GetNext();
+ }
+
+ // alle nichtleeren Zellen mit der Vergleichsspalte vergleichen und entsprechend
+ // selektieren oder aufheben
+
+ ScAddress aCmpAddr;
+ for (i=0; i<nRangeCount; i++)
+ {
+ ScRange aRange(*aRanges.GetObject(i));
+
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (bColumnDiff)
+ aCmpAddr = ScAddress( aIter.GetCol(), nCmpPos, aIter.GetTab() );
+ else
+ aCmpAddr = ScAddress( static_cast<SCCOL>(nCmpPos), aIter.GetRow(), aIter.GetTab() );
+ const ScBaseCell* pOtherCell = pDoc->GetCell( aCmpAddr );
+
+ ScRange aOneRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() );
+ if ( !ScBaseCell::CellEqual( pCell, pOtherCell ) )
+ aMarkData.SetMultiMarkArea( aOneRange );
+ else
+ aMarkData.SetMultiMarkArea( aOneRange, FALSE ); // deselect
+
+ pCell = aIter.GetNext();
+ }
+ }
+
+ ScRangeList aNewRanges;
+ if (aMarkData.IsMultiMarked())
+ aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE );
+
+ return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges kann leer sein
+ }
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellRanges > SAL_CALL ScCellRangesBase::queryColumnDifferences(
+ const table::CellAddress& aCompare ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return QueryDifferences_Impl( aCompare, TRUE );
+}
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryRowDifferences(
+ const table::CellAddress& aCompare ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return QueryDifferences_Impl( aCompare, FALSE );
+}
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryIntersection(
+ const table::CellRangeAddress& aRange ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRange aMask( (SCCOL)aRange.StartColumn, (SCROW)aRange.StartRow, aRange.Sheet,
+ (SCCOL)aRange.EndColumn, (SCROW)aRange.EndRow, aRange.Sheet );
+
+ ScRangeList aNew;
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aTemp(*aRanges.GetObject(i));
+ if ( aTemp.Intersects( aMask ) )
+ aNew.Join( ScRange( Max( aTemp.aStart.Col(), aMask.aStart.Col() ),
+ Max( aTemp.aStart.Row(), aMask.aStart.Row() ),
+ Max( aTemp.aStart.Tab(), aMask.aStart.Tab() ),
+ Min( aTemp.aEnd.Col(), aMask.aEnd.Col() ),
+ Min( aTemp.aEnd.Row(), aMask.aEnd.Row() ),
+ Min( aTemp.aEnd.Tab(), aMask.aEnd.Tab() ) ) );
+ }
+
+ return new ScCellRangesObj( pDocShell, aNew ); // kann leer sein
+}
+
+// XFormulaQuery
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryPrecedents(
+ sal_Bool bRecursive ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScRangeList aNewRanges(aRanges);
+ BOOL bFound;
+ do
+ {
+ bFound = FALSE;
+
+ // #97205# aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( aNewRanges, FALSE );
+ aMarkData.MarkToMulti(); // needed for IsAllMarked
+
+ ULONG nCount = aNewRanges.Count();
+ for (ULONG nR=0; nR<nCount; nR++)
+ {
+ ScRange aRange(*aNewRanges.GetObject(nR));
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+
+ ScDetectiveRefIter aRefIter( pFCell );
+ ScRange aRefRange;
+ while ( aRefIter.GetNextRef( aRefRange) )
+ {
+ if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aRefRange ) )
+ bFound = TRUE;
+ aMarkData.SetMultiMarkArea( aRefRange, TRUE );
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+
+ aMarkData.FillRangeListWithMarks( &aNewRanges, TRUE );
+ }
+ while ( bRecursive && bFound );
+
+ return new ScCellRangesObj( pDocShell, aNewRanges );
+ }
+
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryDependents(
+ sal_Bool bRecursive ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ScRangeList aNewRanges(aRanges);
+ BOOL bFound;
+ do
+ {
+ bFound = FALSE;
+ ULONG nRangesCount = aNewRanges.Count();
+
+ // #97205# aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( aNewRanges, FALSE );
+ aMarkData.MarkToMulti(); // needed for IsAllMarked
+
+ SCTAB nTab = lcl_FirstTab(aNewRanges); //! alle Tabellen
+
+ ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ BOOL bMark = FALSE;
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRefRange;
+ while ( aIter.GetNextRef( aRefRange) )
+ {
+ for (ULONG nR=0; nR<nRangesCount; nR++)
+ {
+ ScRange aRange(*aNewRanges.GetObject(nR));
+ if (aRange.Intersects(aRefRange))
+ bMark = TRUE; // von Teil des Ranges abhaengig
+ }
+ }
+ if (bMark)
+ {
+ ScRange aCellRange( aCellIter.GetCol(),
+ aCellIter.GetRow(),
+ aCellIter.GetTab() );
+ if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aCellRange ) )
+ bFound = TRUE;
+ aMarkData.SetMultiMarkArea( aCellRange, TRUE );
+ }
+ }
+ pCell = aCellIter.GetNext();
+ }
+
+ aMarkData.FillRangeListWithMarks( &aNewRanges, TRUE );
+ }
+ while ( bRecursive && bFound );
+
+ return new ScCellRangesObj( pDocShell, aNewRanges );
+ }
+
+ return NULL;
+}
+
+// XSearchable
+
+uno::Reference<util::XSearchDescriptor> SAL_CALL ScCellRangesBase::createSearchDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScCellSearchObj;
+}
+
+uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangesBase::findAll(
+ const uno::Reference<util::XSearchDescriptor>& xDesc )
+ throw(uno::RuntimeException)
+{
+ // Wenn nichts gefunden wird, soll Null zurueckgegeben werden (?)
+ uno::Reference<container::XIndexAccess> xRet;
+ if ( pDocShell && xDesc.is() )
+ {
+ ScCellSearchObj* pSearch = ScCellSearchObj::getImplementation( xDesc );
+ if (pSearch)
+ {
+ SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
+ if (pSearchItem)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pSearchItem->SetCommand( SVX_SEARCHCMD_FIND_ALL );
+ // immer nur innerhalb dieses Objekts
+ pSearchItem->SetSelection( !lcl_WholeSheet(aRanges) );
+
+ ScMarkData aMark(*GetMarkData());
+
+ String aDummyUndo;
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+ SCTAB nTab = 0;
+ BOOL bFound = pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab,
+ aMark, aDummyUndo, NULL );
+ if (bFound)
+ {
+ ScRangeList aNewRanges;
+ aMark.FillRangeListWithMarks( &aNewRanges, TRUE );
+ // bei findAll immer CellRanges, egal wieviel gefunden wurde
+ xRet.set(new ScCellRangesObj( pDocShell, aNewRanges ));
+ }
+ }
+ }
+ }
+ return xRet;
+}
+
+uno::Reference<uno::XInterface> ScCellRangesBase::Find_Impl(
+ const uno::Reference<util::XSearchDescriptor>& xDesc,
+ const ScAddress* pLastPos )
+{
+ uno::Reference<uno::XInterface> xRet;
+ if ( pDocShell && xDesc.is() )
+ {
+ ScCellSearchObj* pSearch = ScCellSearchObj::getImplementation( xDesc );
+ if (pSearch)
+ {
+ SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
+ if (pSearchItem)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pSearchItem->SetCommand( SVX_SEARCHCMD_FIND );
+ // immer nur innerhalb dieses Objekts
+ pSearchItem->SetSelection( !lcl_WholeSheet(aRanges) );
+
+ ScMarkData aMark(*GetMarkData());
+
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ if (pLastPos)
+ pLastPos->GetVars( nCol, nRow, nTab );
+ else
+ {
+ nTab = lcl_FirstTab(aRanges); //! mehrere Tabellen?
+ ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
+ }
+
+ String aDummyUndo;
+ BOOL bFound = pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab,
+ aMark, aDummyUndo, NULL );
+ if (bFound)
+ {
+ ScAddress aFoundPos( nCol, nRow, nTab );
+ xRet.set((cppu::OWeakObject*) new ScCellObj( pDocShell, aFoundPos ));
+ }
+ }
+ }
+ }
+ return xRet;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findFirst(
+ const uno::Reference<util::XSearchDescriptor>& xDesc )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return Find_Impl( xDesc, NULL );
+}
+
+uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findNext(
+ const uno::Reference<uno::XInterface>& xStartAt,
+ const uno::Reference<util::XSearchDescriptor >& xDesc )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( xStartAt.is() )
+ {
+ ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xStartAt );
+ if ( pRangesImp && pRangesImp->GetDocShell() == pDocShell )
+ {
+ const ScRangeList& rStartRanges = pRangesImp->GetRangeList();
+ if ( rStartRanges.Count() == 1 )
+ {
+ ScAddress aStartPos = rStartRanges.GetObject(0)->aStart;
+ return Find_Impl( xDesc, &aStartPos );
+ }
+ }
+ }
+ return NULL;
+}
+
+// XReplaceable
+
+uno::Reference<util::XReplaceDescriptor> SAL_CALL ScCellRangesBase::createReplaceDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScCellSearchObj;
+}
+
+sal_Int32 SAL_CALL ScCellRangesBase::replaceAll( const uno::Reference<util::XSearchDescriptor>& xDesc )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ INT32 nReplaced = 0;
+ if ( pDocShell && xDesc.is() )
+ {
+ ScCellSearchObj* pSearch = ScCellSearchObj::getImplementation( xDesc );
+ if (pSearch)
+ {
+ SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
+ if (pSearchItem)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ pSearchItem->SetCommand( SVX_SEARCHCMD_REPLACE_ALL );
+ // immer nur innerhalb dieses Objekts
+ pSearchItem->SetSelection( !lcl_WholeSheet(aRanges) );
+
+ ScMarkData aMark(*GetMarkData());
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ BOOL bProtected = !pDocShell->IsEditable();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( aMark.GetTableSelect(i) && pDoc->IsTabProtected(i) )
+ bProtected = TRUE;
+ if (bProtected)
+ {
+ //! Exception, oder was?
+ }
+ else
+ {
+ SCTAB nTab = aMark.GetFirstSelected(); // bei SearchAndReplace nicht benutzt
+ SCCOL nCol = 0;
+ SCROW nRow = 0;
+
+ String aUndoStr;
+ ScDocument* pUndoDoc = NULL;
+ if (bUndo)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ }
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( aMark.GetTableSelect(i) && i != nTab && bUndo)
+ pUndoDoc->AddUndoTab( i, i );
+ ScMarkData* pUndoMark = NULL;
+ if (bUndo)
+ pUndoMark = new ScMarkData(aMark);
+
+ BOOL bFound(FALSE);
+ if (bUndo)
+ bFound = pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab,
+ aMark, aUndoStr, pUndoDoc );
+ if (bFound)
+ {
+ nReplaced = pUndoDoc->GetCellCount();
+
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoReplace( pDocShell, *pUndoMark, nCol, nRow, nTab,
+ aUndoStr, pUndoDoc, pSearchItem ) );
+
+ pDocShell->PostPaintGridAll();
+ pDocShell->SetDocumentModified();
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pUndoMark;
+ // nReplaced bleibt 0
+ }
+ }
+ }
+ }
+ }
+ return nReplaced;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScCellRangesBase::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScCellRangesBase::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScCellRangesBase* ScCellRangesBase::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScCellRangesBase* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScCellRangesBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScCellRangesObj::ScCellRangesObj(ScDocShell* pDocSh, const ScRangeList& rR) :
+ ScCellRangesBase( pDocSh, rR )
+{
+}
+
+ScCellRangesObj::~ScCellRangesObj()
+{
+}
+
+void ScCellRangesObj::RefChanged()
+{
+ ScCellRangesBase::RefChanged();
+
+ // nix weiter...
+}
+
+uno::Any SAL_CALL ScCellRangesObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XSheetCellRangeContainer )
+ SC_QUERYINTERFACE( sheet::XSheetCellRanges )
+ SC_QUERYINTERFACE( container::XIndexAccess )
+ SC_QUERY_MULTIPLE( container::XElementAccess, container::XIndexAccess )
+ SC_QUERYINTERFACE( container::XEnumerationAccess )
+ SC_QUERYINTERFACE( container::XNameContainer )
+ SC_QUERYINTERFACE( container::XNameReplace )
+ SC_QUERYINTERFACE( container::XNameAccess )
+
+ return ScCellRangesBase::queryInterface( rType );
+}
+
+void SAL_CALL ScCellRangesObj::acquire() throw()
+{
+ ScCellRangesBase::acquire();
+}
+
+void SAL_CALL ScCellRangesObj::release() throw()
+{
+ ScCellRangesBase::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScCellRangesObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(ScCellRangesBase::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 3 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSheetCellRangeContainer>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNameContainer>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<container::XEnumerationAccess>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScCellRangesObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XCellRanges
+
+ScCellRangeObj* ScCellRangesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
+{
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ if ( pDocSh && nIndex >= 0 && nIndex < sal::static_int_cast<sal_Int32>(rRanges.Count()) )
+ {
+ ScRange aRange(*rRanges.GetObject(nIndex));
+ if ( aRange.aStart == aRange.aEnd )
+ return new ScCellObj( pDocSh, aRange.aStart );
+ else
+ return new ScCellRangeObj( pDocSh, aRange );
+ }
+
+ return NULL; // keine DocShell oder falscher Index
+}
+
+uno::Sequence<table::CellRangeAddress> SAL_CALL ScCellRangesObj::getRangeAddresses()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ ULONG nCount = rRanges.Count();
+ if ( pDocSh && nCount )
+ {
+ table::CellRangeAddress aRangeAddress;
+ uno::Sequence<table::CellRangeAddress> aSeq(nCount);
+ table::CellRangeAddress* pAry = aSeq.getArray();
+ for (sal_uInt32 i=0; i<nCount; i++)
+ {
+ ScUnoConversion::FillApiRange( aRangeAddress, *rRanges.GetObject(i) );
+ pAry[i] = aRangeAddress;
+ }
+ return aSeq;
+ }
+
+ return uno::Sequence<table::CellRangeAddress>(0); // leer ist moeglich
+}
+
+uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellRangesObj::getCells()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // getCells with empty range list is possible (no exception),
+ // the resulting enumeration just has no elements
+ // (same behaviour as a valid range with no cells)
+ // This is handled in ScCellsEnumeration ctor.
+
+ const ScRangeList& rRanges = GetRangeList();
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ return new ScCellsObj( pDocSh, rRanges );
+ return NULL;
+}
+
+rtl::OUString SAL_CALL ScCellRangesObj::getRangeAddressesAsString()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString;
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ if (pDocSh)
+ rRanges.Format( aString, SCA_VALID | SCA_TAB_3D, pDocSh->GetDocument() );
+ return aString;
+}
+
+// XSheetCellRangeContainer
+
+void SAL_CALL ScCellRangesObj::addRangeAddress( const table::CellRangeAddress& rRange,
+ sal_Bool bMergeRanges )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
+ static_cast<SCROW>(rRange.StartRow),
+ static_cast<SCTAB>(rRange.Sheet),
+ static_cast<SCCOL>(rRange.EndColumn),
+ static_cast<SCROW>(rRange.EndRow),
+ static_cast<SCTAB>(rRange.Sheet));
+ AddRange(aRange, bMergeRanges);
+}
+
+void lcl_RemoveNamedEntry( ScNamedEntryArr_Impl& rNamedEntries, const ScRange& rRange )
+{
+ USHORT nCount = rNamedEntries.Count();
+ for ( USHORT n=nCount; n--; )
+ if ( rNamedEntries[n]->GetRange() == rRange )
+ rNamedEntries.DeleteAndDestroy( n );
+}
+
+void SAL_CALL ScCellRangesObj::removeRangeAddress( const table::CellRangeAddress& rRange )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+
+ ScRangeList aSheetRanges;
+ ScRangeList aNotSheetRanges;
+ for (sal_uInt32 i = 0; i < rRanges.Count(); ++i)
+ {
+ if (rRanges.GetObject(i)->aStart.Tab() == rRange.Sheet)
+ {
+ aSheetRanges.Append(*rRanges.GetObject(i));
+ }
+ else
+ {
+ aNotSheetRanges.Append(*rRanges.GetObject(i));
+ }
+ }
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( aSheetRanges, FALSE );
+ ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
+ static_cast<SCROW>(rRange.StartRow),
+ static_cast<SCTAB>(rRange.Sheet),
+ static_cast<SCCOL>(rRange.EndColumn),
+ static_cast<SCROW>(rRange.EndRow),
+ static_cast<SCTAB>(rRange.Sheet));
+ if (aMarkData.GetTableSelect( aRange.aStart.Tab() ))
+ {
+ aMarkData.MarkToMulti();
+ if (aMarkData.IsAllMarked( aRange ) )
+ {
+ aMarkData.SetMultiMarkArea( aRange, FALSE );
+ lcl_RemoveNamedEntry(aNamedEntries, aRange);
+ }
+ else
+ throw container::NoSuchElementException();
+ }
+ SetNewRanges(aNotSheetRanges);
+ ScRangeList aNew;
+ aMarkData.FillRangeListWithMarks( &aNew, FALSE );
+ for (sal_uInt32 j = 0; j < aNew.Count(); ++j)
+ {
+ AddRange(*aNew.GetObject(j), sal_False);
+ }
+}
+
+void SAL_CALL ScCellRangesObj::addRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRanges,
+ sal_Bool bMergeRanges )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Int32 nCount(rRanges.getLength());
+ if (nCount)
+ {
+ const table::CellRangeAddress* pRanges = rRanges.getConstArray();
+ for (sal_Int32 i = 0; i < rRanges.getLength(); i++, pRanges++)
+ {
+ ScRange aRange(static_cast<SCCOL>(pRanges->StartColumn),
+ static_cast<SCROW>(pRanges->StartRow),
+ static_cast<SCTAB>(pRanges->Sheet),
+ static_cast<SCCOL>(pRanges->EndColumn),
+ static_cast<SCROW>(pRanges->EndRow),
+ static_cast<SCTAB>(pRanges->Sheet));
+ AddRange(aRange, bMergeRanges);
+ }
+ }
+}
+
+void SAL_CALL ScCellRangesObj::removeRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRangeSeq )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ // with this implementation not needed
+// ScUnoGuard aGuard;
+
+
+ // use sometimes a better/faster implementation
+ sal_uInt32 nCount(rRangeSeq.getLength());
+ if (nCount)
+ {
+ const table::CellRangeAddress* pRanges = rRangeSeq.getConstArray();
+ for (sal_uInt32 i=0; i < nCount; ++i, ++pRanges)
+ {
+ removeRangeAddress(*pRanges);
+ }
+ }
+}
+
+// XNameContainer
+
+void lcl_RemoveNamedEntry( ScNamedEntryArr_Impl& rNamedEntries, const String& rName )
+{
+ USHORT nCount = rNamedEntries.Count();
+ for ( USHORT n=nCount; n--; )
+ if ( rNamedEntries[n]->GetName() == rName )
+ rNamedEntries.DeleteAndDestroy( n );
+}
+
+void SAL_CALL ScCellRangesObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::ElementExistException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ BOOL bDone = FALSE;
+
+ //! Type of aElement can be some specific interface instead of XInterface
+
+ uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
+ if ( pDocSh && xInterface.is() )
+ {
+ ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xInterface );
+ if ( pRangesImp && pRangesImp->GetDocShell() == pDocSh )
+ {
+ // if explicit name is given and already existing, throw exception
+
+ String aNamStr(aName);
+ if ( aNamStr.Len() )
+ {
+ USHORT nNamedCount = aNamedEntries.Count();
+ for (USHORT n=0; n<nNamedCount; n++)
+ if ( aNamedEntries[n]->GetName() == aNamStr )
+ throw container::ElementExistException();
+ }
+
+ ScRangeList aNew(GetRangeList());
+ const ScRangeList& rAddRanges = pRangesImp->GetRangeList();
+ ULONG nAddCount = rAddRanges.Count();
+ for (ULONG i=0; i<nAddCount; i++)
+ aNew.Join( *rAddRanges.GetObject(i) );
+ SetNewRanges(aNew);
+ bDone = TRUE;
+
+ if ( aName.getLength() && nAddCount == 1 )
+ {
+ // if a name is given, also insert into list of named entries
+ // (only possible for a single range)
+ // name is not in aNamedEntries (tested above)
+
+ ScNamedEntry* pEntry = new ScNamedEntry( aNamStr, *rAddRanges.GetObject(0) );
+ aNamedEntries.Insert( pEntry, aNamedEntries.Count() );
+ }
+ }
+ }
+
+ if (!bDone)
+ {
+ // invalid element - double names are handled above
+ throw lang::IllegalArgumentException();
+ }
+}
+
+BOOL lcl_FindRangeByName( const ScRangeList& rRanges, ScDocShell* pDocSh,
+ const String& rName, ULONG& rIndex )
+{
+ if (pDocSh)
+ {
+ String aRangeStr;
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ rRanges.GetObject(i)->Format( aRangeStr, SCA_VALID | SCA_TAB_3D, pDoc );
+ if ( aRangeStr == rName )
+ {
+ rIndex = i;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE; // nicht gefunden
+}
+
+BOOL lcl_FindRangeOrEntry( const ScNamedEntryArr_Impl& rNamedEntries,
+ const ScRangeList& rRanges, ScDocShell* pDocSh,
+ const String& rName, ScRange& rFound )
+{
+ // exact range in list?
+
+ ULONG nIndex = 0;
+ if ( lcl_FindRangeByName( rRanges, pDocSh, rName, nIndex ) )
+ {
+ rFound = *rRanges.GetObject(nIndex);
+ return TRUE;
+ }
+
+ // range contained in selection? (sheet must be specified)
+
+ ScRange aCellRange;
+ USHORT nParse = aCellRange.ParseAny( rName, pDocSh->GetDocument() );
+ if ( ( nParse & ( SCA_VALID | SCA_TAB_3D ) ) == ( SCA_VALID | SCA_TAB_3D ) )
+ {
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( rRanges, FALSE );
+ aMarkData.MarkToMulti(); // needed for IsAllMarked
+ if ( aMarkData.IsAllMarked( aCellRange ) )
+ {
+ rFound = aCellRange;
+ return TRUE;
+ }
+ }
+
+ // named entry in this object?
+
+ if ( rNamedEntries.Count() )
+ {
+ for ( USHORT n=0; n<rNamedEntries.Count(); n++ )
+ if ( rNamedEntries[n]->GetName() == rName )
+ {
+ // test if named entry is contained in rRanges
+
+ const ScRange& rComp = rNamedEntries[n]->GetRange();
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( rRanges, FALSE );
+ aMarkData.MarkToMulti(); // needed for IsAllMarked
+ if ( aMarkData.IsAllMarked( rComp ) )
+ {
+ rFound = rComp;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE; // not found
+}
+
+void SAL_CALL ScCellRangesObj::removeByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ String aNameStr(aName);
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ ULONG nIndex = 0;
+ if ( lcl_FindRangeByName( rRanges, pDocSh, aNameStr, nIndex ) )
+ {
+ // einzelnen Range weglassen
+ ScRangeList aNew;
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ if (i != nIndex)
+ aNew.Append( *rRanges.GetObject(i) );
+ SetNewRanges(aNew);
+ bDone = TRUE;
+ }
+ else if (pDocSh)
+ {
+ // deselect any ranges (parsed or named entry)
+ ScRangeList aDiff;
+ BOOL bValid = ( aDiff.Parse( aNameStr, pDocSh->GetDocument() ) & SCA_VALID ) != 0;
+ if ( !bValid && aNamedEntries.Count() )
+ {
+ USHORT nCount = aNamedEntries.Count();
+ for (USHORT n=0; n<nCount && !bValid; n++)
+ if (aNamedEntries[n]->GetName() == aNameStr)
+ {
+ aDiff.RemoveAll();
+ aDiff.Append( aNamedEntries[n]->GetRange() );
+ bValid = TRUE;
+ }
+ }
+ if ( bValid )
+ {
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( rRanges, FALSE );
+
+ ULONG nDiffCount = aDiff.Count();
+ for (ULONG i=0; i<nDiffCount; i++)
+ {
+ ScRange* pDiffRange = aDiff.GetObject(i);
+ if (aMarkData.GetTableSelect( pDiffRange->aStart.Tab() ))
+ aMarkData.SetMultiMarkArea( *pDiffRange, FALSE );
+ }
+
+ ScRangeList aNew;
+ aMarkData.FillRangeListWithMarks( &aNew, FALSE );
+ SetNewRanges(aNew);
+
+ bDone = TRUE; //! error if range was not selected before?
+ }
+ }
+
+ if (aNamedEntries.Count())
+ lcl_RemoveNamedEntry( aNamedEntries, aNameStr ); // remove named entry
+
+ if (!bDone)
+ throw container::NoSuchElementException(); // not found
+}
+
+// XNameReplace
+
+void SAL_CALL ScCellRangesObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! zusammenfassen?
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+// XNameAccess
+
+uno::Any SAL_CALL ScCellRangesObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aRet;
+
+ String aNameStr(aName);
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ ScRange aRange;
+ if ( lcl_FindRangeOrEntry( aNamedEntries, rRanges, pDocSh, aNameStr, aRange ) )
+ {
+ uno::Reference<table::XCellRange> xRange;
+ if ( aRange.aStart == aRange.aEnd )
+ xRange.set(new ScCellObj( pDocSh, aRange.aStart ));
+ else
+ xRange.set(new ScCellRangeObj( pDocSh, aRange ));
+ aRet <<= xRange;
+ }
+ else
+ throw container::NoSuchElementException();
+ return aRet;
+}
+
+BOOL lcl_FindEntryName( const ScNamedEntryArr_Impl& rNamedEntries,
+ const ScRange& rRange, String& rName )
+{
+ USHORT nCount = rNamedEntries.Count();
+ for (USHORT i=0; i<nCount; i++)
+ if (rNamedEntries[i]->GetRange() == rRange)
+ {
+ rName = rNamedEntries[i]->GetName();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ if (pDocSh)
+ {
+ String aRangeStr;
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ULONG nCount = rRanges.Count();
+
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ // use given name if for exactly this range, otherwise just format
+ ScRange aRange = *rRanges.GetObject(i);
+ if ( !aNamedEntries.Count() || !lcl_FindEntryName( aNamedEntries, aRange, aRangeStr ) )
+ aRange.Format( aRangeStr, SCA_VALID | SCA_TAB_3D, pDoc );
+ pAry[i] = aRangeStr;
+ }
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+sal_Bool SAL_CALL ScCellRangesObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr(aName);
+ ScDocShell* pDocSh = GetDocShell();
+ const ScRangeList& rRanges = GetRangeList();
+ ScRange aRange;
+ return lcl_FindRangeOrEntry( aNamedEntries, rRanges, pDocSh, aNameStr, aRange );
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScCellRangesObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRangesEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScCellRangesObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ return rRanges.Count();
+}
+
+uno::Any SAL_CALL ScCellRangesObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex));
+ if (xRange.is())
+ return uno::makeAny(xRange);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScCellRangesObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<table::XCellRange>*)0);
+}
+
+sal_Bool SAL_CALL ScCellRangesObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ return rRanges.Count() != 0;
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScCellRangesObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScCellRangesObj" );
+}
+
+sal_Bool SAL_CALL ScCellRangesObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr(rServiceName);
+ return aServiceStr.EqualsAscii( SCSHEETCELLRANGES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(4);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSHEETCELLRANGES_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
+ pArray[2] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
+ pArray[3] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+// static
+uno::Reference<table::XCellRange> ScCellRangeObj::CreateRangeFromDoc( ScDocument* pDoc, const ScRange& rR )
+{
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ return new ScCellRangeObj( (ScDocShell*) pObjSh, rR );
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+ScCellRangeObj::ScCellRangeObj(ScDocShell* pDocSh, const ScRange& rR) :
+ ScCellRangesBase( pDocSh, rR ),
+ pRangePropSet( lcl_GetRangePropertySet() ),
+ aRange( rR )
+{
+ aRange.Justify(); // Anfang / Ende richtig
+}
+
+ScCellRangeObj::~ScCellRangeObj()
+{
+}
+
+void ScCellRangeObj::RefChanged()
+{
+ ScCellRangesBase::RefChanged();
+
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT(rRanges.Count() == 1, "was fuer Ranges ?!?!");
+ const ScRange* pFirst = rRanges.GetObject(0);
+ if (pFirst)
+ {
+ aRange = *pFirst;
+ aRange.Justify();
+ }
+}
+
+uno::Any SAL_CALL ScCellRangeObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XCellRangeAddressable )
+ SC_QUERYINTERFACE( table::XCellRange )
+ SC_QUERYINTERFACE( sheet::XSheetCellRange )
+ SC_QUERYINTERFACE( sheet::XArrayFormulaRange )
+ SC_QUERYINTERFACE( sheet::XArrayFormulaTokens )
+ SC_QUERYINTERFACE( sheet::XCellRangeData )
+ SC_QUERYINTERFACE( sheet::XCellRangeFormula )
+ SC_QUERYINTERFACE( sheet::XMultipleOperation )
+ SC_QUERYINTERFACE( util::XMergeable )
+ SC_QUERYINTERFACE( sheet::XCellSeries )
+ SC_QUERYINTERFACE( table::XAutoFormattable )
+ SC_QUERYINTERFACE( util::XSortable )
+ SC_QUERYINTERFACE( sheet::XSheetFilterableEx )
+ SC_QUERYINTERFACE( sheet::XSheetFilterable )
+ SC_QUERYINTERFACE( sheet::XSubTotalCalculatable )
+ SC_QUERYINTERFACE( table::XColumnRowRange )
+ SC_QUERYINTERFACE( util::XImportable )
+ SC_QUERYINTERFACE( sheet::XCellFormatRangesSupplier )
+ SC_QUERYINTERFACE( sheet::XUniqueCellFormatRangesSupplier )
+
+ return ScCellRangesBase::queryInterface( rType );
+}
+
+void SAL_CALL ScCellRangeObj::acquire() throw()
+{
+ ScCellRangesBase::acquire();
+}
+
+void SAL_CALL ScCellRangeObj::release() throw()
+{
+ ScCellRangesBase::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScCellRangeObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(ScCellRangesBase::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 17 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XCellRangeAddressable>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XSheetCellRange>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XArrayFormulaRange>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<sheet::XArrayFormulaTokens>*)0);
+ pPtr[nParentLen + 4] = getCppuType((const uno::Reference<sheet::XCellRangeData>*)0);
+ pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XCellRangeFormula>*)0);
+ pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XMultipleOperation>*)0);
+ pPtr[nParentLen + 7] = getCppuType((const uno::Reference<util::XMergeable>*)0);
+ pPtr[nParentLen + 8] = getCppuType((const uno::Reference<sheet::XCellSeries>*)0);
+ pPtr[nParentLen + 9] = getCppuType((const uno::Reference<table::XAutoFormattable>*)0);
+ pPtr[nParentLen +10] = getCppuType((const uno::Reference<util::XSortable>*)0);
+ pPtr[nParentLen +11] = getCppuType((const uno::Reference<sheet::XSheetFilterableEx>*)0);
+ pPtr[nParentLen +12] = getCppuType((const uno::Reference<sheet::XSubTotalCalculatable>*)0);
+ pPtr[nParentLen +13] = getCppuType((const uno::Reference<table::XColumnRowRange>*)0);
+ pPtr[nParentLen +14] = getCppuType((const uno::Reference<util::XImportable>*)0);
+ pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XCellFormatRangesSupplier>*)0);
+ pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XUniqueCellFormatRangesSupplier>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScCellRangeObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XCellRange
+
+// ColumnCount / RowCount sind weggefallen
+//! werden im Writer fuer Tabellen noch gebraucht ???
+
+uno::Reference<table::XCell> ScCellRangeObj::GetCellByPosition_Impl(
+ sal_Int32 nColumn, sal_Int32 nRow )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ throw uno::RuntimeException();
+
+ if ( nColumn >= 0 && nRow >= 0 )
+ {
+ sal_Int32 nPosX = aRange.aStart.Col() + nColumn;
+ sal_Int32 nPosY = aRange.aStart.Row() + nRow;
+
+ if ( nPosX <= aRange.aEnd.Col() && nPosY <= aRange.aEnd.Row() )
+ {
+ ScAddress aNew( (SCCOL)nPosX, (SCROW)nPosY, aRange.aStart.Tab() );
+ return new ScCellObj( pDocSh, aNew );
+ }
+ }
+
+ throw lang::IndexOutOfBoundsException();
+// return NULL;
+}
+
+uno::Reference<table::XCell> SAL_CALL ScCellRangeObj::getCellByPosition(
+ sal_Int32 nColumn, sal_Int32 nRow )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ return GetCellByPosition_Impl(nColumn, nRow);
+}
+
+uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByPosition(
+ sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ throw uno::RuntimeException();
+
+ if ( nLeft >= 0 && nTop >= 0 && nRight >= 0 && nBottom >= 0 )
+ {
+ sal_Int32 nStartX = aRange.aStart.Col() + nLeft;
+ sal_Int32 nStartY = aRange.aStart.Row() + nTop;
+ sal_Int32 nEndX = aRange.aStart.Col() + nRight;
+ sal_Int32 nEndY = aRange.aStart.Row() + nBottom;
+
+ if ( nStartX <= nEndX && nEndX <= aRange.aEnd.Col() &&
+ nStartY <= nEndY && nEndY <= aRange.aEnd.Row() )
+ {
+ ScRange aNew( (SCCOL)nStartX, (SCROW)nStartY, aRange.aStart.Tab(),
+ (SCCOL)nEndX, (SCROW)nEndY, aRange.aEnd.Tab() );
+ return new ScCellRangeObj( pDocSh, aNew );
+ }
+ }
+
+ throw lang::IndexOutOfBoundsException();
+// return NULL;
+}
+
+
+uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByName(
+ const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ return getCellRangeByName( aName, ScAddress::detailsOOOa1 );
+}
+
+uno::Reference<table::XCellRange> ScCellRangeObj::getCellRangeByName(
+ const rtl::OUString& aName, const ScAddress::Details& rDetails ) throw(uno::RuntimeException)
+{
+ // name refers to the whole document (with the range's table as default),
+ // valid only if the range is within this range
+
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = aRange.aStart.Tab();
+
+ ScRange aCellRange;
+ BOOL bFound = FALSE;
+ String aString(aName);
+ USHORT nParse = aCellRange.ParseAny( aString, pDoc, rDetails );
+ if ( nParse & SCA_VALID )
+ {
+ if ( !(nParse & SCA_TAB_3D) ) // keine Tabelle angegeben -> auf dieser Tabelle
+ {
+ aCellRange.aStart.SetTab(nTab);
+ aCellRange.aEnd.SetTab(nTab);
+ }
+ bFound = TRUE;
+ }
+ else
+ {
+ ScRangeUtil aRangeUtil;
+ if ( aRangeUtil.MakeRangeFromName( aString, pDoc, nTab, aCellRange, RUTL_NAMES ) ||
+ aRangeUtil.MakeRangeFromName( aString, pDoc, nTab, aCellRange, RUTL_DBASE ) )
+ bFound = TRUE;
+ }
+
+ if (bFound) // valid only if within this object's range
+ {
+ if (!aRange.In(aCellRange))
+ bFound = FALSE;
+ }
+
+ if (bFound)
+ {
+ if ( aCellRange.aStart == aCellRange.aEnd )
+ return new ScCellObj( pDocSh, aCellRange.aStart );
+ else
+ return new ScCellRangeObj( pDocSh, aCellRange );
+ }
+ }
+
+ throw uno::RuntimeException();
+// return NULL;
+}
+
+// XColumnRowRange
+
+uno::Reference<table::XTableColumns> SAL_CALL ScCellRangeObj::getColumns() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ return new ScTableColumnsObj( pDocSh, aRange.aStart.Tab(),
+ aRange.aStart.Col(), aRange.aEnd.Col() );
+
+ DBG_ERROR("Dokument ungueltig");
+ return NULL;
+}
+
+uno::Reference<table::XTableRows> SAL_CALL ScCellRangeObj::getRows() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ return new ScTableRowsObj( pDocSh, aRange.aStart.Tab(),
+ aRange.aStart.Row(), aRange.aEnd.Row() );
+
+ DBG_ERROR("Dokument ungueltig");
+ return NULL;
+}
+
+// XAddressableCellRange
+
+table::CellRangeAddress SAL_CALL ScCellRangeObj::getRangeAddress() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aRet;
+ ScUnoConversion::FillApiRange( aRet, aRange );
+ return aRet;
+}
+
+// XSheetCellRange
+
+uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellRangeObj::getSpreadsheet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ return new ScTableSheetObj( pDocSh, aRange.aStart.Tab() );
+
+ DBG_ERROR("Dokument ungueltig");
+ return NULL;
+}
+
+// XArrayFormulaRange
+
+rtl::OUString SAL_CALL ScCellRangeObj::getArrayFormula() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // Matrix-Formel, wenn eindeutig Teil einer Matrix,
+ // also wenn Anfang und Ende des Blocks zur selben Matrix gehoeren.
+ // Sonst Leerstring.
+
+ String aFormula;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ const ScBaseCell* pCell1 = pDoc->GetCell( aRange.aStart );
+ const ScBaseCell* pCell2 = pDoc->GetCell( aRange.aEnd );
+ if ( pCell1 && pCell2 && pCell1->GetCellType() == CELLTYPE_FORMULA &&
+ pCell2->GetCellType() == CELLTYPE_FORMULA )
+ {
+ const ScFormulaCell* pFCell1 = (const ScFormulaCell*)pCell1;
+ const ScFormulaCell* pFCell2 = (const ScFormulaCell*)pCell2;
+ ScAddress aStart1;
+ ScAddress aStart2;
+ if ( pFCell1->GetMatrixOrigin( aStart1 ) && pFCell2->GetMatrixOrigin( aStart2 ) )
+ {
+ if ( aStart1 == aStart2 ) // beides dieselbe Matrix
+ pFCell1->GetFormula( aFormula ); // egal, von welcher Zelle
+ }
+ }
+ }
+ return aFormula;
+}
+
+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)
+ {
+ ScDocFunc aFunc(*pDocSh);
+ if ( rFormula.getLength() )
+ {
+ if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
+ {
+ // #74681# don't set array formula for sheet object
+ throw uno::RuntimeException();
+ }
+
+ aFunc.EnterMatrix( aRange, NULL, NULL, rFormula, TRUE, TRUE, rFormulaNmsp, eGrammar );
+ }
+ else
+ {
+ // empty string -> erase array formula
+ ScMarkData aMark;
+ aMark.SetMarkArea( aRange );
+ aMark.SelectTable( aRange.aStart.Tab(), TRUE );
+ aFunc.DeleteContents( aMark, IDF_CONTENTS, TRUE, TRUE );
+ }
+ }
+}
+
+void SAL_CALL ScCellRangeObj::setArrayFormula( const rtl::OUString& aFormula )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // GRAM_PODF_A1 for API compatibility.
+ SetArrayFormula_Impl( aFormula, ::rtl::OUString(), formula::FormulaGrammar::GRAM_PODF_A1);
+}
+
+void ScCellRangeObj::SetArrayFormulaWithGrammar( const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SetArrayFormula_Impl( rFormula, rFormulaNmsp, eGrammar);
+}
+
+// XArrayFormulaTokens
+
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellRangeObj::getArrayTokens() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // same cell logic as in getArrayFormula
+
+ uno::Sequence<sheet::FormulaToken> aSequence;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ const ScBaseCell* pCell1 = pDoc->GetCell( aRange.aStart );
+ const ScBaseCell* pCell2 = pDoc->GetCell( aRange.aEnd );
+ if ( pCell1 && pCell2 && pCell1->GetCellType() == CELLTYPE_FORMULA &&
+ pCell2->GetCellType() == CELLTYPE_FORMULA )
+ {
+ const ScFormulaCell* pFCell1 = (const ScFormulaCell*)pCell1;
+ const ScFormulaCell* pFCell2 = (const ScFormulaCell*)pCell2;
+ ScAddress aStart1;
+ ScAddress aStart2;
+ if ( pFCell1->GetMatrixOrigin( aStart1 ) && pFCell2->GetMatrixOrigin( aStart2 ) )
+ {
+ if ( aStart1 == aStart2 )
+ {
+ ScTokenArray* pTokenArray = pFCell1->GetCode();
+ if ( pTokenArray )
+ (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
+ }
+ }
+ }
+ }
+ return aSequence;
+}
+
+void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ if ( rTokens.getLength() )
+ {
+ if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
+ {
+ throw uno::RuntimeException();
+ }
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScTokenArray aTokenArray;
+ (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, rTokens );
+
+ // 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, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
+ }
+ else
+ {
+ // empty sequence -> erase array formula
+ ScMarkData aMark;
+ aMark.SetMarkArea( aRange );
+ aMark.SelectTable( aRange.aStart.Tab(), TRUE );
+ aFunc.DeleteContents( aMark, IDF_CONTENTS, TRUE, TRUE );
+ }
+ }
+}
+
+// XCellRangeData
+
+uno::Sequence< uno::Sequence<uno::Any> > SAL_CALL ScCellRangeObj::getDataArray()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
+ {
+ // don't create a data array for the sheet
+ throw uno::RuntimeException();
+ }
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ uno::Any aAny;
+ // bAllowNV = TRUE: errors as void
+ if ( ScRangeToSequence::FillMixedArray( aAny, pDocSh->GetDocument(), aRange, TRUE ) )
+ {
+ uno::Sequence< uno::Sequence<uno::Any> > aSeq;
+ if ( aAny >>= aSeq )
+ return aSeq; // success
+ }
+ }
+
+ throw uno::RuntimeException(); // no other exceptions specified
+// return uno::Sequence< uno::Sequence<uno::Any> >(0);
+}
+
+void SAL_CALL ScCellRangeObj::setDataArray(
+ const uno::Sequence< uno::Sequence<uno::Any> >& aArray )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ BOOL bDone = FALSE;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ //! move lcl_PutDataArray to docfunc?
+ bDone = lcl_PutDataArray( *pDocSh, aRange, aArray );
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+// XCellRangeFormula
+
+uno::Sequence< uno::Sequence<rtl::OUString> > SAL_CALL ScCellRangeObj::getFormulaArray()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
+ {
+ // don't create a data array for the sheet
+ throw uno::RuntimeException();
+ }
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ SCCOL nColCount = nEndCol + 1 - nStartCol;
+ SCROW nRowCount = nEndRow + 1 - nStartRow;
+ SCTAB nTab = aRange.aStart.Tab();
+
+ uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( nRowCount );
+ uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray();
+ for (SCROW nRowIndex = 0; nRowIndex < nRowCount; nRowIndex++)
+ {
+ uno::Sequence<rtl::OUString> aColSeq( nColCount );
+ rtl::OUString* pColAry = aColSeq.getArray();
+ for (SCCOL nColIndex = 0; nColIndex < nColCount; nColIndex++)
+ pColAry[nColIndex] = lcl_GetInputString( pDocSh->GetDocument(),
+ ScAddress( nStartCol+nColIndex, nStartRow+nRowIndex, nTab ), TRUE );
+
+ pRowAry[nRowIndex] = aColSeq;
+ }
+
+ return aRowSeq;
+ }
+
+ throw uno::RuntimeException(); // no other exceptions specified
+// return uno::Sequence< uno::Sequence<rtl::OUString> >(0);
+}
+
+void SAL_CALL ScCellRangeObj::setFormulaArray(
+ const uno::Sequence< uno::Sequence<rtl::OUString> >& aArray )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ BOOL bDone = FALSE;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ ScExternalRefManager::ApiGuard aExtRefGuard(pDocSh->GetDocument());
+
+ // GRAM_PODF_A1 for API compatibility.
+ bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+// XMultipleOperation
+
+void SAL_CALL ScCellRangeObj::setTableOperation( const table::CellRangeAddress& aFormulaRange,
+ sheet::TableOperationMode nMode,
+ const table::CellAddress& aColumnCell,
+ const table::CellAddress& aRowCell )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ BOOL bError = FALSE;
+ ScTabOpParam aParam;
+ aParam.aRefFormulaCell = ScRefAddress( (SCCOL)aFormulaRange.StartColumn,
+ (SCROW)aFormulaRange.StartRow, aFormulaRange.Sheet,
+ FALSE, FALSE, FALSE );
+ aParam.aRefFormulaEnd = ScRefAddress( (SCCOL)aFormulaRange.EndColumn,
+ (SCROW)aFormulaRange.EndRow, aFormulaRange.Sheet,
+ FALSE, FALSE, FALSE );
+ aParam.aRefRowCell = ScRefAddress( (SCCOL)aRowCell.Column,
+ (SCROW)aRowCell.Row, aRowCell.Sheet,
+ FALSE, FALSE, FALSE );
+ aParam.aRefColCell = ScRefAddress( (SCCOL)aColumnCell.Column,
+ (SCROW)aColumnCell.Row, aColumnCell.Sheet,
+ FALSE, FALSE, FALSE );
+ switch (nMode)
+ {
+ case sheet::TableOperationMode_COLUMN:
+ aParam.nMode = 0;
+ break;
+ case sheet::TableOperationMode_ROW:
+ aParam.nMode = 1;
+ break;
+ case sheet::TableOperationMode_BOTH:
+ aParam.nMode = 2;
+ break;
+ default:
+ bError = TRUE;
+ }
+
+ if (!bError)
+ {
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.TabOp( aRange, NULL, aParam, TRUE, TRUE );
+ }
+ }
+}
+
+// XMergeable
+
+void SAL_CALL ScCellRangeObj::merge( sal_Bool bMerge ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ if ( bMerge )
+ aFunc.MergeCells( aRange, FALSE, TRUE, TRUE );
+ else
+ aFunc.UnmergeCells( aRange, TRUE, TRUE );
+
+ //! Fehler abfangen?
+ }
+}
+
+sal_Bool SAL_CALL ScCellRangeObj::getIsMerged() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ return pDocSh && pDocSh->GetDocument()->HasAttrib( aRange, HASATTR_MERGED );
+}
+
+// XCellSeries
+
+void SAL_CALL ScCellRangeObj::fillSeries( sheet::FillDirection nFillDirection,
+ sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode,
+ double fStep, double fEndValue ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BOOL bError = FALSE;
+
+ FillDir eDir = FILL_TO_BOTTOM;
+ switch (nFillDirection)
+ {
+ case sheet::FillDirection_TO_BOTTOM:
+ eDir = FILL_TO_BOTTOM;
+ break;
+ case sheet::FillDirection_TO_RIGHT:
+ eDir = FILL_TO_RIGHT;
+ break;
+ case sheet::FillDirection_TO_TOP:
+ eDir = FILL_TO_TOP;
+ break;
+ case sheet::FillDirection_TO_LEFT:
+ eDir = FILL_TO_LEFT;
+ break;
+ default:
+ bError = TRUE;
+ }
+
+ FillCmd eCmd = FILL_SIMPLE;
+ switch ( nFillMode )
+ {
+ case sheet::FillMode_SIMPLE:
+ eCmd = FILL_SIMPLE;
+ break;
+ case sheet::FillMode_LINEAR:
+ eCmd = FILL_LINEAR;
+ break;
+ case sheet::FillMode_GROWTH:
+ eCmd = FILL_GROWTH;
+ break;
+ case sheet::FillMode_DATE:
+ eCmd = FILL_DATE;
+ break;
+ case sheet::FillMode_AUTO:
+ eCmd = FILL_AUTO;
+ break;
+ default:
+ bError = TRUE;
+ }
+
+ FillDateCmd eDateCmd = FILL_DAY;
+ switch ( nFillDateMode )
+ {
+ case sheet::FillDateMode_FILL_DATE_DAY:
+ eDateCmd = FILL_DAY;
+ break;
+ case sheet::FillDateMode_FILL_DATE_WEEKDAY:
+ eDateCmd = FILL_WEEKDAY;
+ break;
+ case sheet::FillDateMode_FILL_DATE_MONTH:
+ eDateCmd = FILL_MONTH;
+ break;
+ case sheet::FillDateMode_FILL_DATE_YEAR:
+ eDateCmd = FILL_YEAR;
+ break;
+ default:
+ bError = TRUE;
+ }
+
+ if (!bError)
+ {
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.FillSeries( aRange, NULL, eDir, eCmd, eDateCmd,
+ MAXDOUBLE, fStep, fEndValue, TRUE, TRUE );
+ }
+ }
+}
+
+void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection,
+ sal_Int32 nSourceCount ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh && nSourceCount )
+ {
+ ScRange aSourceRange(aRange);
+ SCsCOLROW nCount = 0; // "Dest-Count"
+ FillDir eDir = FILL_TO_BOTTOM;
+ BOOL bError = FALSE;
+ switch (nFillDirection)
+ {
+ case sheet::FillDirection_TO_BOTTOM:
+ aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount - 1 ) );
+ nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row();
+ eDir = FILL_TO_BOTTOM;
+ break;
+ case sheet::FillDirection_TO_RIGHT:
+ aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) );
+ nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col();
+ eDir = FILL_TO_RIGHT;
+ break;
+ case sheet::FillDirection_TO_TOP:
+ aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) );
+ nCount = aSourceRange.aStart.Row() - aRange.aStart.Row();
+ eDir = FILL_TO_TOP;
+ break;
+ case sheet::FillDirection_TO_LEFT:
+ aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) );
+ nCount = aSourceRange.aStart.Col() - aRange.aStart.Col();
+ eDir = FILL_TO_LEFT;
+ break;
+ default:
+ bError = TRUE;
+ }
+ if (nCount < 0 || nCount > MAXROW) // overflow
+ bError = TRUE;
+
+ if (!bError)
+ {
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.FillAuto( aSourceRange, NULL, eDir, nCount, TRUE, TRUE );
+ }
+ }
+}
+
+// XAutoFormattable
+
+void SAL_CALL ScCellRangeObj::autoFormat( const rtl::OUString& aName )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh && pAutoFormat )
+ {
+ String aNameString(aName);
+ USHORT nCount = pAutoFormat->GetCount();
+ USHORT nIndex;
+ String aCompare;
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ (*pAutoFormat)[nIndex]->GetName(aCompare);
+ if ( aCompare == aNameString ) //! Case-insensitiv ???
+ break;
+ }
+ if (nIndex<nCount)
+ {
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.AutoFormat( aRange, NULL, nIndex, TRUE, TRUE );
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+}
+
+// XSortable
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createSortDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSortParam aParam;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
+ ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
+ if (pData)
+ {
+ pData->GetSortParam(aParam);
+
+ // im SortDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOLROW nFieldStart = aParam.bByRow ?
+ static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
+ static_cast<SCCOLROW>(aDBRange.aStart.Row());
+ for (USHORT i=0; i<MAXSORT; i++)
+ if ( aParam.bDoSort[i] && aParam.nField[i] >= nFieldStart )
+ aParam.nField[i] -= nFieldStart;
+ }
+ }
+
+ uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() );
+ ScSortDescriptor::FillProperties( aSeq, aParam );
+ return aSeq;
+}
+
+void SAL_CALL ScCellRangeObj::sort( const uno::Sequence<beans::PropertyValue>& aDescriptor )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ USHORT i;
+ ScSortParam aParam;
+ ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
+ if (pData)
+ {
+ // alten Einstellungen holen, falls nicht alles neu gesetzt wird
+ pData->GetSortParam(aParam);
+ SCCOLROW nOldStart = aParam.bByRow ?
+ static_cast<SCCOLROW>(aRange.aStart.Col()) :
+ static_cast<SCCOLROW>(aRange.aStart.Row());
+ for (i=0; i<MAXSORT; i++)
+ if ( aParam.bDoSort[i] && aParam.nField[i] >= nOldStart )
+ aParam.nField[i] -= nOldStart;
+ }
+
+ ScSortDescriptor::FillSortParam( aParam, aDescriptor );
+
+ // im SortDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ // ByRow kann bei FillSortParam umgesetzt worden sein
+ SCCOLROW nFieldStart = aParam.bByRow ?
+ static_cast<SCCOLROW>(aRange.aStart.Col()) :
+ static_cast<SCCOLROW>(aRange.aStart.Row());
+ for (i=0; i<MAXSORT; i++)
+ aParam.nField[i] += nFieldStart;
+
+ SCTAB nTab = aRange.aStart.Tab();
+ aParam.nCol1 = aRange.aStart.Col();
+ aParam.nRow1 = aRange.aStart.Row();
+ aParam.nCol2 = aRange.aEnd.Col();
+ aParam.nRow2 = aRange.aEnd.Row();
+
+ pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
+
+ ScDBDocFunc aFunc(*pDocSh); // Bereich muss angelegt sein
+ aFunc.Sort( nTab, aParam, TRUE, TRUE, TRUE );
+ }
+}
+
+// XFilterable
+
+uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptor(
+ sal_Bool bEmpty ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ ScFilterDescriptor* pNew = new ScFilterDescriptor(pDocSh);
+ if ( !bEmpty && pDocSh )
+ {
+ // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
+ ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
+ if (pData)
+ {
+ ScQueryParam aParam;
+ pData->GetQueryParam(aParam);
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOLROW nFieldStart = aParam.bByRow ?
+ static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
+ static_cast<SCCOLROW>(aDBRange.aStart.Row());
+ SCSIZE nCount = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
+ rEntry.nField -= nFieldStart;
+ }
+ pNew->SetParam(aParam);
+ }
+ }
+ return pNew;
+}
+
+void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDescriptor>& xDescriptor )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // das koennte theoretisch ein fremdes Objekt sein, also nur das
+ // oeffentliche XSheetFilterDescriptor Interface benutzen, um
+ // die Daten in ein ScFilterDescriptor Objekt zu kopieren:
+ //! wenn es schon ein ScFilterDescriptor ist, direkt per getImplementation?
+
+ ScDocShell* pDocSh = GetDocShell();
+ ScFilterDescriptor aImpl(pDocSh);
+ 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 );
+ if (xPropSet.is())
+ lcl_CopyProperties( aImpl, *(beans::XPropertySet*)xPropSet.get() );
+
+ //
+ // ausfuehren...
+ //
+
+ if (pDocSh)
+ {
+ ScQueryParam aParam = aImpl.GetParam();
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ SCCOLROW nFieldStart = aParam.bByRow ?
+ static_cast<SCCOLROW>(aRange.aStart.Col()) :
+ static_cast<SCCOLROW>(aRange.aStart.Row());
+ SCSIZE nCount = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (rEntry.bDoQuery)
+ {
+ rEntry.nField += nFieldStart;
+ // Im Dialog wird immer der String angezeigt -> muss zum Wert passen
+ if ( !rEntry.bQueryByString )
+ pDocSh->GetDocument()->GetFormatTable()->
+ GetInputLineString( rEntry.nVal, 0, *rEntry.pStr );
+ }
+ }
+
+ SCTAB nTab = aRange.aStart.Tab();
+ aParam.nCol1 = aRange.aStart.Col();
+ aParam.nRow1 = aRange.aStart.Row();
+ aParam.nCol2 = aRange.aEnd.Col();
+ aParam.nRow2 = aRange.aEnd.Row();
+
+ pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
+
+ //! keep source range in filter descriptor
+ //! if created by createFilterDescriptorByObject ???
+
+ ScDBDocFunc aFunc(*pDocSh);
+ aFunc.Query( nTab, aParam, NULL, TRUE, TRUE ); // Bereich muss angelegt sein
+ }
+}
+
+//! get/setAutoFilter als Properties!!!
+
+// XAdvancedFilterSource
+
+uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptorByObject(
+ const uno::Reference<sheet::XSheetFilterable>& xObject )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // this ist hier nicht der Bereich, der gefiltert wird, sondern der
+ // Bereich mit der Abfrage...
+
+ uno::Reference<sheet::XCellRangeAddressable> xAddr( xObject, uno::UNO_QUERY );
+
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh && xAddr.is() )
+ {
+ //! Test, ob xObject im selben Dokument ist
+
+ ScFilterDescriptor* pNew = new ScFilterDescriptor(pDocSh); //! stattdessen vom Objekt?
+ //XSheetFilterDescriptorRef xNew = xObject->createFilterDescriptor(TRUE);
+
+ ScQueryParam aParam = pNew->GetParam();
+ aParam.bHasHeader = TRUE;
+
+ table::CellRangeAddress aDataAddress(xAddr->getRangeAddress());
+ aParam.nCol1 = (SCCOL)aDataAddress.StartColumn;
+ aParam.nRow1 = (SCROW)aDataAddress.StartRow;
+ aParam.nCol2 = (SCCOL)aDataAddress.EndColumn;
+ aParam.nRow2 = (SCROW)aDataAddress.EndRow;
+ aParam.nTab = aDataAddress.Sheet;
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bOk = pDoc->CreateQueryParam(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ aRange.aStart.Tab(), aParam );
+ if ( bOk )
+ {
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ SCCOLROW nFieldStart = aParam.bByRow ?
+ static_cast<SCCOLROW>(aDataAddress.StartColumn) :
+ static_cast<SCCOLROW>(aDataAddress.StartRow);
+ SCSIZE nCount = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
+ rEntry.nField -= nFieldStart;
+ }
+
+ pNew->SetParam( aParam );
+ return pNew;
+ }
+ else
+ {
+ delete pNew;
+ return NULL; // ungueltig -> null
+ }
+ }
+
+ DBG_ERROR("kein Dokument oder kein Bereich");
+ return NULL;
+}
+
+// XSubTotalSource
+
+uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScCellRangeObj::createSubTotalDescriptor(
+ sal_Bool bEmpty ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalDescriptor* pNew = new ScSubTotalDescriptor;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( !bEmpty && pDocSh )
+ {
+ // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
+ ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
+ if (pData)
+ {
+ ScSubTotalParam aParam;
+ pData->GetSubTotalParam(aParam);
+ // im SubTotalDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOL nFieldStart = aDBRange.aStart.Col();
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ if ( aParam.bGroupActive[i] )
+ {
+ if ( aParam.nField[i] >= nFieldStart )
+ aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] - nFieldStart );
+ for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
+ if ( aParam.pSubTotals[i][j] >= nFieldStart )
+ aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] - nFieldStart );
+ }
+ }
+ pNew->SetParam(aParam);
+ }
+ }
+ return pNew;
+}
+
+void SAL_CALL ScCellRangeObj::applySubTotals(
+ const uno::Reference<sheet::XSubTotalDescriptor>& xDescriptor,
+ sal_Bool bReplace ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if (!xDescriptor.is()) return;
+
+ ScDocShell* pDocSh = GetDocShell();
+ ScSubTotalDescriptorBase* pImp =
+ ScSubTotalDescriptorBase::getImplementation( xDescriptor );
+
+ if (pDocSh && pImp)
+ {
+ ScSubTotalParam aParam;
+ pImp->GetData(aParam); // virtuelle Methode der Basisklasse
+
+ // im SubTotalDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ SCCOL nFieldStart = aRange.aStart.Col();
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ if ( aParam.bGroupActive[i] )
+ {
+ aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + nFieldStart );
+ for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
+ aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] + nFieldStart );
+ }
+ }
+
+ aParam.bReplace = bReplace;
+
+ SCTAB nTab = aRange.aStart.Tab();
+ aParam.nCol1 = aRange.aStart.Col();
+ aParam.nRow1 = aRange.aStart.Row();
+ aParam.nCol2 = aRange.aEnd.Col();
+ aParam.nRow2 = aRange.aEnd.Row();
+
+ pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
+
+ ScDBDocFunc aFunc(*pDocSh);
+ aFunc.DoSubTotals( nTab, aParam, NULL, TRUE, TRUE ); // Bereich muss angelegt sein
+ }
+}
+
+void SAL_CALL ScCellRangeObj::removeSubTotals() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ ScSubTotalParam aParam;
+ ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
+ if (pData)
+ pData->GetSubTotalParam(aParam); // auch bei Remove die Feld-Eintraege behalten
+
+ aParam.bRemoveOnly = TRUE;
+
+ SCTAB nTab = aRange.aStart.Tab();
+ aParam.nCol1 = aRange.aStart.Col();
+ aParam.nRow1 = aRange.aStart.Row();
+ aParam.nCol2 = aRange.aEnd.Col();
+ aParam.nRow2 = aRange.aEnd.Row();
+
+ pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
+
+ ScDBDocFunc aFunc(*pDocSh);
+ aFunc.DoSubTotals( nTab, aParam, NULL, TRUE, TRUE ); // Bereich muss angelegt sein
+ }
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createImportDescriptor( sal_Bool bEmpty )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScImportParam aParam;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( !bEmpty && pDocSh )
+ {
+ // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
+ ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
+ if (pData)
+ pData->GetImportParam(aParam);
+ }
+
+ uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
+ ScImportDescriptor::FillProperties( aSeq, aParam );
+ return aSeq;
+}
+
+void SAL_CALL ScCellRangeObj::doImport( const uno::Sequence<beans::PropertyValue>& aDescriptor )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ ScImportParam aParam;
+ ScImportDescriptor::FillImportParam( aParam, aDescriptor );
+
+ SCTAB nTab = aRange.aStart.Tab();
+ aParam.nCol1 = aRange.aStart.Col();
+ aParam.nRow1 = aRange.aStart.Row();
+ aParam.nCol2 = aRange.aEnd.Col();
+ aParam.nRow2 = aRange.aEnd.Row();
+
+ //! TODO: could we get passed a valid result set by any means?
+ uno::Reference< sdbc::XResultSet > xResultSet;
+
+ pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
+
+ ScDBDocFunc aFunc(*pDocSh); // Bereich muss angelegt sein
+ aFunc.DoImport( nTab, aParam, xResultSet, NULL, TRUE, FALSE ); //! Api-Flag als Parameter
+ }
+}
+
+// XCellFormatRangesSupplier
+
+uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getCellFormatRanges()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScCellFormatsObj( pDocSh, aRange );
+ return NULL;
+}
+
+// XUniqueCellFormatRangesSupplier
+
+uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getUniqueCellFormatRanges()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScUniqueCellFormatsObj( pDocSh, aRange );
+ return NULL;
+}
+
+// XPropertySet erweitert fuer Range-Properties
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangeObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( pRangePropSet->getPropertyMap() ));
+ return aRef;
+}
+
+void ScCellRangeObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ // Range has only Position and Size in addition to ScCellRangesBase, both are ReadOnly
+ // -> nothing to do here
+
+ ScCellRangesBase::SetOnePropertyValue( pEntry, aValue );
+}
+
+void ScCellRangeObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
+ uno::Any& rAny )
+ throw(uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( pEntry->nWID == SC_WID_UNO_POS )
+ {
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ // GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer
+ Rectangle aMMRect(pDocSh->GetDocument()->GetMMRect(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
+ awt::Point aPos( aMMRect.Left(), aMMRect.Top() );
+ rAny <<= aPos;
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_SIZE )
+ {
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ // GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer
+ Rectangle aMMRect = pDocSh->GetDocument()->GetMMRect(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() );
+ Size aSize(aMMRect.GetSize());
+ awt::Size aAwtSize( aSize.Width(), aSize.Height() );
+ rAny <<= aAwtSize;
+ }
+ }
+ else
+ ScCellRangesBase::GetOnePropertyValue( pEntry, rAny );
+
+ }
+}
+
+const SfxItemPropertyMap* ScCellRangeObj::GetItemPropertyMap()
+{
+ return pRangePropSet->getPropertyMap();
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScCellRangeObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScCellRangeObj" );
+}
+
+sal_Bool SAL_CALL ScCellRangeObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCSHEETCELLRANGE_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLRANGE_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellRangeObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(5);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSHEETCELLRANGE_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCCELLRANGE_SERVICE );
+ pArray[2] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
+ pArray[3] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
+ pArray[4] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+const SvxItemPropertySet* ScCellObj::GetEditPropertySet() // static
+{
+ return lcl_GetEditPropertySet();
+}
+const SfxItemPropertyMap* ScCellObj::GetCellPropertyMap()
+{
+ return lcl_GetCellPropertySet()->getPropertyMap();
+}
+
+ScCellObj::ScCellObj(ScDocShell* pDocSh, const ScAddress& rP) :
+ ScCellRangeObj( pDocSh, ScRange(rP,rP) ),
+ pUnoText( NULL ),
+ pCellPropSet( lcl_GetCellPropertySet() ),
+ aCellPos( rP ),
+ nActionLockCount( 0 )
+{
+ // pUnoText is allocated on demand (GetUnoText)
+ // can't be aggregated because getString/setString is handled here
+}
+
+SvxUnoText& ScCellObj::GetUnoText()
+{
+ if (!pUnoText)
+ {
+ pUnoText = new ScCellTextObj( GetDocShell(), aCellPos );
+ pUnoText->acquire();
+ if (nActionLockCount)
+ {
+ ScSharedCellEditSource* pEditSource =
+ static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
+ if (pEditSource)
+ pEditSource->SetDoUpdateData(sal_False);
+ }
+ }
+ return *pUnoText;
+}
+
+ScCellObj::~ScCellObj()
+{
+ if (pUnoText)
+ pUnoText->release();
+}
+
+void ScCellObj::RefChanged()
+{
+ ScCellRangeObj::RefChanged();
+
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT(rRanges.Count() == 1, "was fuer Ranges ?!?!");
+ const ScRange* pFirst = rRanges.GetObject(0);
+ if (pFirst)
+ aCellPos = pFirst->aStart;
+}
+
+uno::Any SAL_CALL ScCellObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( table::XCell )
+ SC_QUERYINTERFACE( sheet::XFormulaTokens )
+ SC_QUERYINTERFACE( sheet::XCellAddressable )
+ SC_QUERYINTERFACE( text::XText )
+ SC_QUERYINTERFACE( text::XSimpleText )
+ SC_QUERYINTERFACE( text::XTextRange )
+ SC_QUERYINTERFACE( container::XEnumerationAccess )
+ SC_QUERYINTERFACE( container::XElementAccess )
+ SC_QUERYINTERFACE( sheet::XSheetAnnotationAnchor )
+ SC_QUERYINTERFACE( text::XTextFieldsSupplier )
+ SC_QUERYINTERFACE( document::XActionLockable )
+
+ return ScCellRangeObj::queryInterface( rType );
+}
+
+void SAL_CALL ScCellObj::acquire() throw()
+{
+ ScCellRangeObj::acquire();
+}
+
+void SAL_CALL ScCellObj::release() throw()
+{
+ ScCellRangeObj::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScCellObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 8 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<table::XCell>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XCellAddressable>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<text::XText>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<container::XEnumerationAccess>*)0);
+ pPtr[nParentLen + 4] = getCppuType((const uno::Reference<sheet::XSheetAnnotationAnchor>*)0);
+ pPtr[nParentLen + 5] = getCppuType((const uno::Reference<text::XTextFieldsSupplier>*)0);
+ pPtr[nParentLen + 6] = getCppuType((const uno::Reference<document::XActionLockable>*)0);
+ pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XFormulaTokens>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScCellObj::getImplementationId() throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// Hilfsfunktionen
+
+String ScCellObj::GetInputString_Impl(BOOL bEnglish) const // fuer getFormula / FormulaLocal
+{
+ if (GetDocShell())
+ return lcl_GetInputString( GetDocShell()->GetDocument(), aCellPos, bEnglish );
+ return String();
+}
+
+String ScCellObj::GetOutputString_Impl(ScDocument* pDoc, const ScAddress& aCellPos)
+{
+ String aVal;
+ if ( pDoc )
+ {
+ ScBaseCell* pCell = pDoc->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ // GetString an der EditCell macht Leerzeichen aus Umbruechen,
+ // hier werden die Umbrueche aber gebraucht
+ const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
+ if (pData)
+ {
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ aVal = rEngine.GetText( LINEEND_LF );
+ }
+ // Edit-Zellen auch nicht per NumberFormatter formatieren
+ // (passend zur Ausgabe)
+ }
+ else
+ {
+ // wie in GetString am Dokument (column)
+ Color* pColor;
+ ULONG nNumFmt = pDoc->GetNumberFormat( aCellPos );
+ ScCellFormat::GetString( pCell, nNumFmt, aVal, &pColor, *pDoc->GetFormatTable() );
+ }
+ }
+ }
+ return aVal;
+}
+
+String ScCellObj::GetOutputString_Impl() const
+{
+ ScDocShell* pDocSh = GetDocShell();
+ String aVal;
+ if ( pDocSh )
+ aVal = GetOutputString_Impl(pDocSh->GetDocument(), aCellPos);
+ return aVal;
+}
+
+void ScCellObj::SetString_Impl(const String& rString, BOOL bInterpret, BOOL bEnglish)
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ // GRAM_PODF_A1 for API compatibility.
+ (void)aFunc.SetCellText( aCellPos, rString, bInterpret, bEnglish, TRUE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
+ }
+}
+
+double ScCellObj::GetValue_Impl() const
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return pDocSh->GetDocument()->GetValue( aCellPos );
+
+ return 0.0;
+}
+
+void ScCellObj::SetValue_Impl(double fValue)
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ (void)aFunc.PutCell( aCellPos, new ScValueCell(fValue), TRUE );
+ }
+}
+
+// only for XML import
+
+void ScCellObj::SetFormulaResultString( const ::rtl::OUString& rResult )
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->SetHybridString( rResult );
+ }
+}
+
+void ScCellObj::SetFormulaResultDouble( double fResult )
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->SetHybridDouble( fResult );
+ }
+}
+
+void ScCellObj::SetFormulaWithGrammar( const ::rtl::OUString& rFormula,
+ const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.SetCellText( aCellPos, rFormula, TRUE, TRUE, TRUE, rFormulaNmsp, eGrammar);
+ }
+}
+
+// XText
+
+uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScCellTextCursor( *this );
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SvxUnoTextCursor* pCursor = new ScCellTextCursor( *this );
+ uno::Reference<text::XTextCursor> xCursor(pCursor);
+
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
+ if(pRange)
+ pCursor->SetSelection( pRange->GetSelection() );
+ else
+ {
+ ScCellTextCursor* pOther = ScCellTextCursor::getImplementation( aTextPosition );
+ if(pOther)
+ pCursor->SetSelection( pOther->GetSelection() );
+ else
+ throw uno::RuntimeException();
+ }
+
+ return xCursor;
+}
+
+rtl::OUString SAL_CALL ScCellObj::getString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetOutputString_Impl();
+}
+
+void SAL_CALL ScCellObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aText);
+ SetString_Impl(aString, FALSE, FALSE); // immer Text
+
+ // don't create pUnoText here if not there
+ if (pUnoText)
+ pUnoText->SetSelection(ESelection( 0,0, 0,aString.Len() ));
+}
+
+void SAL_CALL ScCellObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ // special handling for ScCellTextCursor is no longer needed,
+ // SvxUnoText::insertString checks for SvxUnoTextRangeBase instead of SvxUnoTextRange
+
+ ScUnoGuard aGuard;
+ GetUnoText().insertString(xRange, aString, bAbsorb);
+}
+
+void SAL_CALL ScCellObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().insertControlCharacter(xRange, nControlCharacter, bAbsorb);
+}
+
+void SAL_CALL ScCellObj::insertTextContent( const uno::Reference<text::XTextRange >& xRange,
+ const uno::Reference<text::XTextContent >& xContent,
+ sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh && xContent.is() )
+ {
+ ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
+ SvxUnoTextRangeBase* pTextRange = ScCellTextCursor::getImplementation( xRange );
+
+#if 0
+ if (!pTextRange)
+ pTextRange = SvxUnoTextRangeBase::getImplementation( xRange );
+
+ //! bei SvxUnoTextRange testen, ob in passendem Objekt !!!
+#endif
+
+ if ( pCellField && !pCellField->IsInserted() && pTextRange )
+ {
+ SvxEditSource* pEditSource = pTextRange->GetEditSource();
+ ESelection aSelection(pTextRange->GetSelection());
+
+ if (!bAbsorb)
+ {
+ // nicht ersetzen -> hinten anhaengen
+ aSelection.Adjust();
+ aSelection.nStartPara = aSelection.nEndPara;
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+
+ SvxFieldItem aItem(pCellField->CreateFieldItem());
+
+ SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
+ pForwarder->QuickInsertField( aItem, aSelection );
+ pEditSource->UpdateData();
+
+ // neue Selektion: ein Zeichen
+ aSelection.Adjust();
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aSelection.nStartPos + 1;
+ pCellField->InitDoc( pDocSh, aCellPos, aSelection );
+
+ // #91431# for bAbsorb=FALSE, the new selection must be behind the inserted content
+ // (the xml filter relies on this)
+ if (!bAbsorb)
+ aSelection.nStartPos = aSelection.nEndPos;
+
+ pTextRange->SetSelection( aSelection );
+
+ return;
+ }
+ }
+ GetUnoText().insertTextContent(xRange, xContent, bAbsorb);
+}
+
+void SAL_CALL ScCellObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( xContent.is() )
+ {
+ ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
+ if ( pCellField && pCellField->IsInserted() )
+ {
+ //! Testen, ob das Feld in dieser Zelle ist
+ pCellField->DeleteField();
+ return;
+ }
+ }
+ GetUnoText().removeTextContent(xContent);
+}
+
+uno::Reference<text::XText> SAL_CALL ScCellObj::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return this;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getStart();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getEnd();
+}
+
+uno::Reference<container::XEnumeration> SAL_CALL ScCellObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().createEnumeration();
+}
+
+uno::Type SAL_CALL ScCellObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getElementType();
+}
+
+sal_Bool SAL_CALL ScCellObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().hasElements();
+}
+
+// XCell
+
+rtl::OUString SAL_CALL ScCellObj::getFormula() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // TRUE = englisch
+ return GetInputString_Impl(TRUE);
+}
+
+void SAL_CALL ScCellObj::setFormula( const rtl::OUString& aFormula ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aFormula);
+ SetString_Impl(aString, TRUE, TRUE); // englisch interpretieren
+}
+
+double SAL_CALL ScCellObj::getValue() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetValue_Impl();
+}
+
+void SAL_CALL ScCellObj::setValue( double nValue ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SetValue_Impl(nValue);
+}
+
+table::CellContentType SAL_CALL ScCellObj::getType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellContentType eRet = table::CellContentType_EMPTY;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ CellType eCalcType = pDocSh->GetDocument()->GetCellType( aCellPos );
+ switch (eCalcType)
+ {
+ case CELLTYPE_VALUE:
+ eRet = table::CellContentType_VALUE;
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ eRet = table::CellContentType_TEXT;
+ break;
+ case CELLTYPE_FORMULA:
+ eRet = table::CellContentType_FORMULA;
+ break;
+ default:
+ eRet = table::CellContentType_EMPTY;
+ }
+ }
+ else
+ {
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ }
+
+ return eRet;
+}
+
+table::CellContentType ScCellObj::GetResultType_Impl()
+{
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScBaseCell* pCell = pDocSh->GetDocument()->GetCell(aCellPos);
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ BOOL bValue = ((ScFormulaCell*)pCell)->IsValue();
+ return bValue ? table::CellContentType_VALUE : table::CellContentType_TEXT;
+ }
+ }
+ return getType(); // wenn keine Formel
+}
+
+sal_Int32 SAL_CALL ScCellObj::getError() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nError = 0;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ {
+ ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ nError = ((ScFormulaCell*)pCell)->GetErrCode();
+ // sonst bleibt's bei 0
+ }
+ else
+ {
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ }
+
+ return nError;
+}
+
+// XFormulaTokens
+
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellObj::getTokens() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence<sheet::FormulaToken> aSequence;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScBaseCell* pCell = pDoc->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScTokenArray* pTokenArray = static_cast<ScFormulaCell*>(pCell)->GetCode();
+ if ( pTokenArray )
+ (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
+ }
+ }
+ return aSequence;
+}
+
+void SAL_CALL ScCellObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScTokenArray aTokenArray;
+ (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, rTokens );
+
+ ScDocFunc aFunc( *pDocSh );
+ ScBaseCell* pNewCell = new ScFormulaCell( pDoc, aCellPos, &aTokenArray );
+ (void)aFunc.PutCell( aCellPos, pNewCell, TRUE );
+ }
+}
+
+// XCellAddressable
+
+table::CellAddress SAL_CALL ScCellObj::getCellAddress() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellAddress aAdr;
+ aAdr.Sheet = aCellPos.Tab();
+ aAdr.Column = aCellPos.Col();
+ aAdr.Row = aCellPos.Row();
+ return aAdr;
+}
+
+// XSheetAnnotationAnchor
+
+uno::Reference<sheet::XSheetAnnotation> SAL_CALL ScCellObj::getAnnotation()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScAnnotationObj( pDocSh, aCellPos );
+
+ DBG_ERROR("getAnnotation ohne DocShell");
+ return NULL;
+}
+
+// XFieldTypesSupplier
+
+uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellObj::getTextFields()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScCellFieldsObj( pDocSh, aCellPos );
+
+ return NULL;
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScCellObj::getTextFieldMasters()
+ throw(uno::RuntimeException)
+{
+ // sowas gibts nicht im Calc (?)
+ return NULL;
+}
+
+// XPropertySet erweitert fuer Zell-Properties
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( pCellPropSet->getPropertyMap() ));
+ return aRef;
+}
+
+void ScCellObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( pEntry->nWID == SC_WID_UNO_FORMLOC )
+ {
+ rtl::OUString aStrVal;
+ aValue >>= aStrVal;
+ String aString(aStrVal);
+ SetString_Impl(aString, TRUE, FALSE); // lokal interpretieren
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_FORMRT )
+ {
+ // Read-Only
+ //! Exception oder so...
+ }
+ else
+ ScCellRangeObj::SetOnePropertyValue( pEntry, aValue );
+ }
+}
+
+void ScCellObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
+ uno::Any& rAny )
+ throw(uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( pEntry->nWID == SC_WID_UNO_FORMLOC )
+ {
+ // FALSE = lokal
+ rAny <<= rtl::OUString( GetInputString_Impl(FALSE) );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_FORMRT )
+ {
+ table::CellContentType eType = GetResultType_Impl();
+ rAny <<= eType;
+ }
+ else
+ ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
+ }
+}
+
+const SfxItemPropertyMap* ScCellObj::GetItemPropertyMap()
+{
+ return pCellPropSet->getPropertyMap();
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScCellObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScCellObj" );
+}
+
+sal_Bool SAL_CALL ScCellObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ // CellRange/SheetCellRange are not in SheetCell service description,
+ // but ScCellObj is used instead of ScCellRangeObj in CellRanges collections,
+ // so it must support them
+
+ String aServiceStr(rServiceName);
+ return aServiceStr.EqualsAscii( SCSHEETCELL_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELL_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCSHEETCELLRANGE_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLRANGE_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(7);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSHEETCELL_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCCELL_SERVICE );
+ pArray[2] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
+ pArray[3] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
+ pArray[4] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
+ pArray[5] = rtl::OUString::createFromAscii( SCSHEETCELLRANGE_SERVICE );
+ pArray[6] = rtl::OUString::createFromAscii( SCCELLRANGE_SERVICE );
+ return aRet;
+}
+
+// XActionLockable
+
+sal_Bool SAL_CALL ScCellObj::isActionLocked() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return nActionLockCount != 0;
+}
+
+void SAL_CALL ScCellObj::addActionLock() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!nActionLockCount)
+ {
+ if (pUnoText)
+ {
+ ScSharedCellEditSource* pEditSource =
+ static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
+ if (pEditSource)
+ pEditSource->SetDoUpdateData(sal_False);
+ }
+ }
+ nActionLockCount++;
+}
+
+void SAL_CALL ScCellObj::removeActionLock() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nActionLockCount > 0)
+ {
+ nActionLockCount--;
+ if (!nActionLockCount)
+ {
+ if (pUnoText)
+ {
+ ScSharedCellEditSource* pEditSource =
+ static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
+ if (pEditSource)
+ {
+ pEditSource->SetDoUpdateData(sal_True);
+ if (pEditSource->IsDirty())
+ pEditSource->UpdateData();
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL ScCellObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pUnoText)
+ {
+ ScSharedCellEditSource* pEditSource =
+ static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
+ if (pEditSource)
+ {
+ pEditSource->SetDoUpdateData(nLock == 0);
+ if ((nActionLockCount > 0) && (nLock == 0) && pEditSource->IsDirty())
+ pEditSource->UpdateData();
+ }
+ }
+ nActionLockCount = nLock;
+}
+
+sal_Int16 SAL_CALL ScCellObj::resetActionLocks() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nRet(nActionLockCount);
+ if (pUnoText)
+ {
+ ScSharedCellEditSource* pEditSource =
+ static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
+ if (pEditSource)
+ {
+ pEditSource->SetDoUpdateData(sal_True);
+ if (pEditSource->IsDirty())
+ pEditSource->UpdateData();
+ }
+ }
+ nActionLockCount = 0;
+ return nRet;
+}
+
+//------------------------------------------------------------------------
+
+ScTableSheetObj::ScTableSheetObj( ScDocShell* pDocSh, SCTAB nTab ) :
+ ScCellRangeObj( pDocSh, ScRange(0,0,nTab, MAXCOL,MAXROW,nTab) ),
+ pSheetPropSet(lcl_GetSheetPropertySet())
+{
+}
+
+ScTableSheetObj::~ScTableSheetObj()
+{
+}
+
+void ScTableSheetObj::InitInsertSheet(ScDocShell* pDocSh, SCTAB nTab)
+{
+ InitInsertRange( pDocSh, ScRange(0,0,nTab, MAXCOL,MAXROW,nTab) );
+}
+
+uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XSpreadsheet )
+ SC_QUERYINTERFACE( container::XNamed )
+ SC_QUERYINTERFACE( sheet::XSheetPageBreak )
+ SC_QUERYINTERFACE( sheet::XCellRangeMovement )
+ SC_QUERYINTERFACE( table::XTableChartsSupplier )
+ SC_QUERYINTERFACE( sheet::XDataPilotTablesSupplier )
+ SC_QUERYINTERFACE( sheet::XScenariosSupplier )
+ SC_QUERYINTERFACE( sheet::XSheetAnnotationsSupplier )
+ SC_QUERYINTERFACE( drawing::XDrawPageSupplier )
+ SC_QUERYINTERFACE( sheet::XPrintAreas )
+ SC_QUERYINTERFACE( sheet::XSheetAuditing )
+ SC_QUERYINTERFACE( sheet::XSheetOutline )
+ SC_QUERYINTERFACE( util::XProtectable )
+ SC_QUERYINTERFACE( sheet::XScenario )
+ SC_QUERYINTERFACE( sheet::XScenarioEnhanced )
+ SC_QUERYINTERFACE( sheet::XSheetLinkable )
+ SC_QUERYINTERFACE( sheet::XExternalSheetName )
+ SC_QUERYINTERFACE( document::XEventsSupplier )
+
+ return ScCellRangeObj::queryInterface( rType );
+}
+
+void SAL_CALL ScTableSheetObj::acquire() throw()
+{
+ ScCellRangeObj::acquire();
+}
+
+void SAL_CALL ScTableSheetObj::release() throw()
+{
+ ScCellRangeObj::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes = ScCellRangeObj::getTypes();
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 18 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheet>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNamed>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XSheetPageBreak>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<sheet::XCellRangeMovement>*)0);
+ pPtr[nParentLen + 4] = getCppuType((const uno::Reference<table::XTableChartsSupplier>*)0);
+ pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XDataPilotTablesSupplier>*)0);
+ pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XScenariosSupplier>*)0);
+ pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XSheetAnnotationsSupplier>*)0);
+ pPtr[nParentLen + 8] = getCppuType((const uno::Reference<drawing::XDrawPageSupplier>*)0);
+ pPtr[nParentLen + 9] = getCppuType((const uno::Reference<sheet::XPrintAreas>*)0);
+ pPtr[nParentLen +10] = getCppuType((const uno::Reference<sheet::XSheetAuditing>*)0);
+ pPtr[nParentLen +11] = getCppuType((const uno::Reference<sheet::XSheetOutline>*)0);
+ pPtr[nParentLen +12] = getCppuType((const uno::Reference<util::XProtectable>*)0);
+ pPtr[nParentLen +13] = getCppuType((const uno::Reference<sheet::XScenario>*)0);
+ pPtr[nParentLen +14] = getCppuType((const uno::Reference<sheet::XScenarioEnhanced>*)0);
+ pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XSheetLinkable>*)0);
+ pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XExternalSheetName>*)0);
+ pPtr[nParentLen +17] = getCppuType((const uno::Reference<document::XEventsSupplier>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScTableSheetObj::getImplementationId() throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// Hilfsfunktionen
+
+SCTAB ScTableSheetObj::GetTab_Impl() const
+{
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT(rRanges.Count() == 1, "was fuer Ranges ?!?!");
+ const ScRange* pFirst = rRanges.GetObject(0);
+ if (pFirst)
+ return pFirst->aStart.Tab();
+
+ return 0; // soll nicht sein
+}
+
+// former XSheet
+
+uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScChartsObj( pDocSh, GetTab_Impl() );
+
+ DBG_ERROR("kein Dokument");
+ return NULL;
+}
+
+uno::Reference<sheet::XDataPilotTables> SAL_CALL ScTableSheetObj::getDataPilotTables()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScDataPilotTablesObj( pDocSh, GetTab_Impl() );
+
+ DBG_ERROR("kein Dokument");
+ return NULL;
+}
+
+uno::Reference<sheet::XScenarios> SAL_CALL ScTableSheetObj::getScenarios() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+
+ if ( pDocSh )
+ return new ScScenariosObj( pDocSh, GetTab_Impl() );
+
+ DBG_ERROR("kein Dokument");
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetAnnotations> SAL_CALL ScTableSheetObj::getAnnotations()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+
+ if ( pDocSh )
+ return new ScAnnotationsObj( pDocSh, GetTab_Impl() );
+
+ DBG_ERROR("kein Dokument");
+ return NULL;
+}
+
+uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByName(
+ const rtl::OUString& rRange ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::getCellRangeByName( rRange );
+}
+
+uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ //! einzelne Zelle oder ganze Tabelle???????
+ SCTAB nTab = GetTab_Impl();
+ return new ScCellCursorObj( pDocSh, ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) );
+ }
+ return NULL;
+}
+
+uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursorByRange(
+ const uno::Reference<sheet::XSheetCellRange>& xCellRange )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh && xCellRange.is() )
+ {
+ ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xCellRange );
+ if (pRangesImp)
+ {
+ const ScRangeList& rRanges = pRangesImp->GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ return new ScCellCursorObj( pDocSh, *rRanges.GetObject(0) );
+ }
+ }
+ return NULL;
+}
+
+// XSheetCellRange
+
+uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTableSheetObj::getSpreadsheet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return this; //!???
+}
+
+// XCellRange
+
+uno::Reference<table::XCell> SAL_CALL ScTableSheetObj::getCellByPosition(
+ sal_Int32 nColumn, sal_Int32 nRow )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::GetCellByPosition_Impl(nColumn, nRow);
+}
+
+uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByPosition(
+ sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom);
+}
+
+uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPageBreaks()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ Size aSize(pDoc->GetPageSize( nTab ));
+ if (aSize.Width() && aSize.Height()) // effektive Groesse schon gesetzt?
+ pDoc->UpdatePageBreaks( nTab );
+ else
+ {
+ // Umbrueche updaten wie in ScDocShell::PageStyleModified:
+ ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ SCCOL nCount = 0;
+ SCCOL nCol;
+ for (nCol=0; nCol<=MAXCOL; nCol++)
+ if (pDoc->HasColBreak(nCol, nTab))
+ ++nCount;
+
+ sheet::TablePageBreakData aData;
+ uno::Sequence<sheet::TablePageBreakData> aSeq(nCount);
+ sheet::TablePageBreakData* pAry = aSeq.getArray();
+ USHORT nPos = 0;
+ for (nCol=0; nCol<=MAXCOL; nCol++)
+ {
+ ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
+ if (nBreak)
+ {
+ aData.Position = nCol;
+ aData.ManualBreak = (nBreak & BREAK_MANUAL);
+ pAry[nPos] = aData;
+ ++nPos;
+ }
+ }
+ return aSeq;
+ }
+ return uno::Sequence<sheet::TablePageBreakData>(0);
+}
+
+uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getRowPageBreaks()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ Size aSize(pDoc->GetPageSize( nTab ));
+ if (aSize.Width() && aSize.Height()) // effektive Groesse schon gesetzt?
+ pDoc->UpdatePageBreaks( nTab );
+ else
+ {
+ // Umbrueche updaten wie in ScDocShell::PageStyleModified:
+ ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ }
+ return pDoc->GetRowBreakData(nTab);
+ }
+ return uno::Sequence<sheet::TablePageBreakData>(0);
+}
+
+void SAL_CALL ScTableSheetObj::removeAllManualPageBreaks() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ //! docfunc Funktion, auch fuer ScViewFunc::RemoveManualBreaks
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+ SCTAB nTab = GetTab_Impl();
+
+ if (bUndo)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
+ }
+
+ pDoc->RemoveManualBreaks(nTab);
+ pDoc->UpdatePageBreaks(nTab);
+
+ //? UpdatePageBreakData( TRUE );
+ pDocSh->SetDocumentModified();
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+ }
+}
+
+// XNamed
+
+rtl::OUString SAL_CALL ScTableSheetObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aName;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ pDocSh->GetDocument()->GetName( GetTab_Impl(), aName );
+ return aName;
+}
+
+void SAL_CALL ScTableSheetObj::setName( const rtl::OUString& aNewName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ String aString(aNewName);
+ ScDocFunc aFunc( *pDocSh );
+ aFunc.RenameTable( GetTab_Impl(), aString, TRUE, TRUE );
+ }
+}
+
+// XDrawPageSupplier
+
+uno::Reference<drawing::XDrawPage> SAL_CALL ScTableSheetObj::getDrawPage()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDrawLayer* pDrawLayer = pDocSh->MakeDrawLayer();
+ DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
+
+ SCTAB nTab = GetTab_Impl();
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Draw-Page nicht gefunden");
+ if (pPage)
+ return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
+
+ // Das DrawPage-Objekt meldet sich als Listener am SdrModel an
+ // und sollte von dort alle Aktionen mitbekommen
+ }
+ return NULL;
+}
+
+// XCellMovement
+
+void SAL_CALL ScTableSheetObj::insertCells( const table::CellRangeAddress& rRangeAddress,
+ sheet::CellInsertMode nMode ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BOOL bDo = TRUE;
+ InsCellCmd eCmd = INS_NONE;
+ switch (nMode)
+ {
+ case sheet::CellInsertMode_NONE: bDo = FALSE; break;
+ case sheet::CellInsertMode_DOWN: eCmd = INS_CELLSDOWN; break;
+ case sheet::CellInsertMode_RIGHT: eCmd = INS_CELLSRIGHT; break;
+ case sheet::CellInsertMode_ROWS: eCmd = INS_INSROWS; break;
+ case sheet::CellInsertMode_COLUMNS: eCmd = INS_INSCOLS; break;
+ default:
+ DBG_ERROR("insertCells: falscher Mode");
+ bDo = FALSE;
+ }
+
+ if (bDo)
+ {
+ DBG_ASSERT( rRangeAddress.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, rRangeAddress );
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.InsertCells( aScRange, NULL, eCmd, TRUE, TRUE );
+ }
+ }
+}
+
+void SAL_CALL ScTableSheetObj::removeRange( const table::CellRangeAddress& rRangeAddress,
+ sheet::CellDeleteMode nMode ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BOOL bDo = TRUE;
+ DelCellCmd eCmd = DEL_NONE;
+ switch (nMode)
+ {
+ case sheet::CellDeleteMode_NONE: bDo = FALSE; break;
+ case sheet::CellDeleteMode_UP: eCmd = DEL_CELLSUP; break;
+ case sheet::CellDeleteMode_LEFT: eCmd = DEL_CELLSLEFT; break;
+ case sheet::CellDeleteMode_ROWS: eCmd = DEL_DELROWS; break;
+ case sheet::CellDeleteMode_COLUMNS: eCmd = DEL_DELCOLS; break;
+ default:
+ DBG_ERROR("deleteCells: falscher Mode");
+ bDo = FALSE;
+ }
+
+ if (bDo)
+ {
+ DBG_ASSERT( rRangeAddress.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, rRangeAddress );
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.DeleteCells( aScRange, NULL, eCmd, TRUE, TRUE );
+ }
+ }
+}
+
+void SAL_CALL ScTableSheetObj::moveRange( const table::CellAddress& aDestination,
+ const table::CellRangeAddress& aSource )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ DBG_ASSERT( aSource.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
+ ScRange aSourceRange;
+ ScUnoConversion::FillScRange( aSourceRange, aSource );
+ ScAddress aDestPos( (SCCOL)aDestination.Column, (SCROW)aDestination.Row, aDestination.Sheet );
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.MoveBlock( aSourceRange, aDestPos, TRUE, TRUE, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::copyRange( const table::CellAddress& aDestination,
+ const table::CellRangeAddress& aSource )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ DBG_ASSERT( aSource.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
+ ScRange aSourceRange;
+ ScUnoConversion::FillScRange( aSourceRange, aSource );
+ ScAddress aDestPos( (SCCOL)aDestination.Column, (SCROW)aDestination.Row, aDestination.Sheet );
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.MoveBlock( aSourceRange, aDestPos, FALSE, TRUE, TRUE, TRUE );
+ }
+}
+
+// XPrintAreas
+
+void ScTableSheetObj::PrintAreaUndo_Impl( ScPrintRangeSaver* pOldRanges )
+{
+ // Umbrueche und Undo
+
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ SCTAB nTab = GetTab_Impl();
+
+ ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPrintRange( pDocSh, nTab, pOldRanges, pNewRanges ) );
+ }
+
+ ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
+
+ SfxBindings* pBindings = pDocSh->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_DELETE_PRINTAREA );
+
+ pDocSh->SetDocumentModified();
+ }
+ else
+ delete pOldRanges;
+}
+
+uno::Sequence<table::CellRangeAddress> SAL_CALL ScTableSheetObj::getPrintAreas()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ USHORT nCount = pDoc->GetPrintRangeCount( nTab );
+
+ table::CellRangeAddress aRangeAddress;
+ uno::Sequence<table::CellRangeAddress> aSeq(nCount);
+ table::CellRangeAddress* pAry = aSeq.getArray();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ const ScRange* pRange = pDoc->GetPrintRange( nTab, i );
+ DBG_ASSERT(pRange,"wo ist der Druckbereich");
+ if (pRange)
+ {
+ ScUnoConversion::FillApiRange( aRangeAddress, *pRange );
+ aRangeAddress.Sheet = nTab; // core does not care about sheet index
+ pAry[i] = aRangeAddress;
+ }
+ }
+ return aSeq;
+ }
+ return uno::Sequence<table::CellRangeAddress>();
+}
+
+void SAL_CALL ScTableSheetObj::setPrintAreas(
+ const uno::Sequence<table::CellRangeAddress>& aPrintAreas )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ USHORT nCount = (USHORT) aPrintAreas.getLength();
+ pDoc->ClearPrintRanges( nTab );
+ if (nCount)
+ {
+ ScRange aPrintRange;
+ const table::CellRangeAddress* pAry = aPrintAreas.getConstArray();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScUnoConversion::FillScRange( aPrintRange, pAry[i] );
+ pDoc->AddPrintRange( nTab, aPrintRange );
+ }
+ }
+
+ PrintAreaUndo_Impl( pOldRanges ); // Undo, Umbrueche, Modified etc.
+ }
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleColumns() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ return ( pDoc->GetRepeatColRange(nTab) != NULL );
+ }
+ return FALSE;
+}
+
+void SAL_CALL ScTableSheetObj::setPrintTitleColumns( sal_Bool bPrintTitleColumns )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ if ( bPrintTitleColumns )
+ {
+ if ( !pDoc->GetRepeatColRange( nTab ) ) // keinen bestehenden Bereich veraendern
+ {
+ ScRange aNew( 0, 0, nTab, 0, 0, nTab ); // Default
+ pDoc->SetRepeatColRange( nTab, &aNew ); // einschalten
+ }
+ }
+ else
+ pDoc->SetRepeatColRange( nTab, NULL ); // abschalten
+
+ PrintAreaUndo_Impl( pOldRanges ); // Undo, Umbrueche, Modified etc.
+
+ //! zuletzt gesetzten Bereich beim Abschalten merken und beim Einschalten wiederherstellen ???
+ }
+}
+
+table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleColumns() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aRet;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ const ScRange* pRange = pDoc->GetRepeatColRange(nTab);
+ if (pRange)
+ {
+ ScUnoConversion::FillApiRange( aRet, *pRange );
+ aRet.Sheet = nTab; // core does not care about sheet index
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL ScTableSheetObj::setTitleColumns( const table::CellRangeAddress& aTitleColumns )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ ScRange aNew;
+ ScUnoConversion::FillScRange( aNew, aTitleColumns );
+ pDoc->SetRepeatColRange( nTab, &aNew ); // immer auch einschalten
+
+ PrintAreaUndo_Impl( pOldRanges ); // Undo, Umbrueche, Modified etc.
+ }
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleRows() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ return ( pDoc->GetRepeatRowRange(nTab) != NULL );
+ }
+ return FALSE;
+}
+
+void SAL_CALL ScTableSheetObj::setPrintTitleRows( sal_Bool bPrintTitleRows )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ if ( bPrintTitleRows )
+ {
+ if ( !pDoc->GetRepeatRowRange( nTab ) ) // keinen bestehenden Bereich veraendern
+ {
+ ScRange aNew( 0, 0, nTab, 0, 0, nTab ); // Default
+ pDoc->SetRepeatRowRange( nTab, &aNew ); // einschalten
+ }
+ }
+ else
+ pDoc->SetRepeatRowRange( nTab, NULL ); // abschalten
+
+ PrintAreaUndo_Impl( pOldRanges ); // Undo, Umbrueche, Modified etc.
+
+ //! zuletzt gesetzten Bereich beim Abschalten merken und beim Einschalten wiederherstellen ???
+ }
+}
+
+table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleRows() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aRet;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ const ScRange* pRange = pDoc->GetRepeatRowRange(nTab);
+ if (pRange)
+ {
+ ScUnoConversion::FillApiRange( aRet, *pRange );
+ aRet.Sheet = nTab; // core does not care about sheet index
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL ScTableSheetObj::setTitleRows( const table::CellRangeAddress& aTitleRows )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ ScRange aNew;
+ ScUnoConversion::FillScRange( aNew, aTitleRows );
+ pDoc->SetRepeatRowRange( nTab, &aNew ); // immer auch einschalten
+
+ PrintAreaUndo_Impl( pOldRanges ); // Undo, Umbrueche, Modified etc.
+ }
+}
+
+// XSheetLinkable
+
+sheet::SheetLinkMode SAL_CALL ScTableSheetObj::getLinkMode() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sheet::SheetLinkMode eRet = sheet::SheetLinkMode_NONE;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BYTE nMode = pDocSh->GetDocument()->GetLinkMode( GetTab_Impl() );
+ if ( nMode == SC_LINK_NORMAL )
+ eRet = sheet::SheetLinkMode_NORMAL;
+ else if ( nMode == SC_LINK_VALUE )
+ eRet = sheet::SheetLinkMode_VALUE;
+ }
+ return eRet;
+}
+
+void SAL_CALL ScTableSheetObj::setLinkMode( sheet::SheetLinkMode nLinkMode )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! Filter und Options aus altem Link suchen
+
+ rtl::OUString aUrl(getLinkUrl());
+ rtl::OUString aSheet(getLinkSheetName());
+
+ rtl::OUString aEmpty;
+ link( aUrl, aSheet, aEmpty, aEmpty, nLinkMode );
+}
+
+rtl::OUString SAL_CALL ScTableSheetObj::getLinkUrl() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aFile;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ aFile = pDocSh->GetDocument()->GetLinkDoc( GetTab_Impl() );
+ return aFile;
+}
+
+void SAL_CALL ScTableSheetObj::setLinkUrl( const rtl::OUString& aLinkUrl )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! Filter und Options aus altem Link suchen
+
+ sheet::SheetLinkMode eMode = getLinkMode();
+ rtl::OUString aSheet(getLinkSheetName());
+
+ rtl::OUString aEmpty;
+ link( aLinkUrl, aSheet, aEmpty, aEmpty, eMode );
+}
+
+rtl::OUString SAL_CALL ScTableSheetObj::getLinkSheetName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aSheet;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ aSheet = pDocSh->GetDocument()->GetLinkTab( GetTab_Impl() );
+ return aSheet;
+}
+
+void SAL_CALL ScTableSheetObj::setLinkSheetName( const rtl::OUString& aLinkSheetName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! Filter und Options aus altem Link suchen
+
+ sheet::SheetLinkMode eMode = getLinkMode();
+ rtl::OUString aUrl(getLinkUrl());
+
+ rtl::OUString aEmpty;
+ link( aUrl, aLinkSheetName, aEmpty, aEmpty, eMode );
+}
+
+void SAL_CALL ScTableSheetObj::link( const rtl::OUString& aUrl, const rtl::OUString& aSheetName,
+ const rtl::OUString& aFilterName, const rtl::OUString& aFilterOptions,
+ sheet::SheetLinkMode nMode ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ String aFileString (aUrl);
+ String aFilterString (aFilterName);
+ String aOptString (aFilterOptions);
+ String aSheetString (aSheetName);
+
+ aFileString = ScGlobal::GetAbsDocName( aFileString, pDocSh );
+ if ( !aFilterString.Len() )
+ ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, TRUE, FALSE );
+
+ // remove application prefix from filter name here, so the filter options
+ // aren't reset when the filter name is changed in ScTableLink::DataChanged
+ ScDocumentLoader::RemoveAppPrefix( aFilterString );
+
+ BYTE nLinkMode = SC_LINK_NONE;
+ if ( nMode == sheet::SheetLinkMode_NORMAL )
+ nLinkMode = SC_LINK_NORMAL;
+ else if ( nMode == sheet::SheetLinkMode_VALUE )
+ nLinkMode = SC_LINK_VALUE;
+
+ ULONG nRefresh = 0;
+ pDoc->SetLink( nTab, nLinkMode, aFileString, aFilterString, aOptString, aSheetString, nRefresh );
+
+ pDocSh->UpdateLinks(); // ggf. Link eintragen oder loeschen
+ SfxBindings* pBindings = pDocSh->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate(SID_LINKS);
+
+ //! Undo fuer Link-Daten an der Table
+
+ if ( nLinkMode != SC_LINK_NONE && pDoc->IsExecuteLinkEnabled() ) // Link updaten
+ {
+ // Update immer, auch wenn der Link schon da war
+ //! Update nur fuer die betroffene Tabelle???
+
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ USHORT nCount = pLinkManager->GetLinks().Count();
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
+ if (pBase->ISA(ScTableLink))
+ {
+ ScTableLink* pTabLink = (ScTableLink*)pBase;
+ if ( pTabLink->GetFileName() == aFileString )
+ pTabLink->Update(); // inkl. Paint&Undo
+
+ //! Der Dateiname sollte nur einmal vorkommen (?)
+ }
+ }
+ }
+
+ //! Notify fuer ScSheetLinkObj Objekte!!!
+ }
+}
+
+// XSheetAuditing
+
+sal_Bool SAL_CALL ScTableSheetObj::hideDependents( const table::CellAddress& aPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCTAB nTab = GetTab_Impl();
+ DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
+ ScDocFunc aFunc(*pDocSh);
+ return aFunc.DetectiveDelSucc( aPos );
+ }
+ return FALSE;
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::hidePrecedents( const table::CellAddress& aPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCTAB nTab = GetTab_Impl();
+ DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
+ ScDocFunc aFunc(*pDocSh);
+ return aFunc.DetectiveDelPred( aPos );
+ }
+ return FALSE;
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::showDependents( const table::CellAddress& aPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCTAB nTab = GetTab_Impl();
+ DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
+ ScDocFunc aFunc(*pDocSh);
+ return aFunc.DetectiveAddSucc( aPos );
+ }
+ return FALSE;
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::showPrecedents( const table::CellAddress& aPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCTAB nTab = GetTab_Impl();
+ DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
+ ScDocFunc aFunc(*pDocSh);
+ return aFunc.DetectiveAddPred( aPos );
+ }
+ return FALSE;
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::showErrors( const table::CellAddress& aPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCTAB nTab = GetTab_Impl();
+ DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
+ ScDocFunc aFunc(*pDocSh);
+ return aFunc.DetectiveAddError( aPos );
+ }
+ return FALSE;
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::showInvalid() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ return aFunc.DetectiveMarkInvalid( GetTab_Impl() );
+ }
+ return FALSE;
+}
+
+void SAL_CALL ScTableSheetObj::clearArrows() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.DetectiveDelAll( GetTab_Impl() );
+ }
+}
+
+// XSheetOutline
+
+void SAL_CALL ScTableSheetObj::group( const table::CellRangeAddress& rGroupRange,
+ table::TableOrientation nOrientation )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BOOL bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
+ ScRange aGroupRange;
+ ScUnoConversion::FillScRange( aGroupRange, rGroupRange );
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.MakeOutline( aGroupRange, bColumns, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::ungroup( const table::CellRangeAddress& rGroupRange,
+ table::TableOrientation nOrientation )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BOOL bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
+ ScRange aGroupRange;
+ ScUnoConversion::FillScRange( aGroupRange, rGroupRange );
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.RemoveOutline( aGroupRange, bColumns, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::autoOutline( const table::CellRangeAddress& rCellRange )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScRange aFormulaRange;
+ ScUnoConversion::FillScRange( aFormulaRange, rCellRange );
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.AutoOutline( aFormulaRange, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::clearOutline() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCTAB nTab = GetTab_Impl();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.RemoveAllOutlines( nTab, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::hideDetail( const table::CellRangeAddress& rCellRange )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScRange aMarkRange;
+ ScUnoConversion::FillScRange( aMarkRange, rCellRange );
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.HideMarkedOutlines( aMarkRange, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::showDetail( const table::CellRangeAddress& rCellRange )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScRange aMarkRange;
+ ScUnoConversion::FillScRange( aMarkRange, rCellRange );
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.ShowMarkedOutlines( aMarkRange, TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::showLevel( sal_Int16 nLevel, table::TableOrientation nOrientation )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ BOOL bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
+ SCTAB nTab = GetTab_Impl();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.SelectLevel( nTab, bColumns, nLevel, TRUE, TRUE, TRUE );
+ }
+}
+
+// XProtectable
+
+void SAL_CALL ScTableSheetObj::protect( const rtl::OUString& aPassword )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ // #i108245# if already protected, don't change anything
+ if ( pDocSh && !pDocSh->GetDocument()->IsTabProtected( GetTab_Impl() ) )
+ {
+ String aString(aPassword);
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.Protect( GetTab_Impl(), aString, TRUE );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::unprotect( const rtl::OUString& aPassword )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ String aString(aPassword);
+ ScDocFunc aFunc(*pDocSh);
+ BOOL bDone = aFunc.Unprotect( GetTab_Impl(), aString, TRUE );
+ if (!bDone)
+ throw lang::IllegalArgumentException();
+ }
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::isProtected() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return pDocSh->GetDocument()->IsTabProtected( GetTab_Impl() );
+
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ return FALSE;
+}
+
+// XScenario
+
+sal_Bool SAL_CALL ScTableSheetObj::getIsScenario() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return pDocSh->GetDocument()->IsScenario( GetTab_Impl() );
+
+ return FALSE;
+}
+
+rtl::OUString SAL_CALL ScTableSheetObj::getScenarioComment() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDocSh->GetDocument()->GetScenarioData( GetTab_Impl(), aComment, aColor, nFlags );
+ return aComment;
+ }
+ return rtl::OUString();
+}
+
+void SAL_CALL ScTableSheetObj::setScenarioComment( const rtl::OUString& aScenarioComment )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ aComment = String( aScenarioComment );
+
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+}
+
+void SAL_CALL ScTableSheetObj::addRanges( const uno::Sequence<table::CellRangeAddress>& rScenRanges )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ if (pDoc->IsScenario(nTab))
+ {
+ ScMarkData aMarkData;
+ aMarkData.SelectTable( nTab, TRUE );
+
+ USHORT nRangeCount = (USHORT)rScenRanges.getLength();
+ if (nRangeCount)
+ {
+ const table::CellRangeAddress* pAry = rScenRanges.getConstArray();
+ for (USHORT i=0; i<nRangeCount; i++)
+ {
+ DBG_ASSERT( pAry[i].Sheet == nTab, "addRanges mit falscher Tab" );
+ ScRange aOneRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
+ (SCCOL)pAry[i].EndColumn, (SCROW)pAry[i].EndRow, nTab );
+
+ aMarkData.SetMultiMarkArea( aOneRange );
+ }
+ }
+
+ // Szenario-Ranges sind durch Attribut gekennzeichnet
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
+ aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.ApplyAttributes( aMarkData, aPattern, TRUE, TRUE );
+ }
+
+ // don't use. We should use therefor a private interface, so we can also set the flags.
+/* else if (nTab > 0 && pDoc->IsImportingXML()) // make this sheet as an scenario and only if it is not the first sheet and only if it is ImportingXML,
+ // because than no UNDO and repaint is necessary.
+ {
+ USHORT nRangeCount = (USHORT)rScenRanges.getLength();
+ if (nRangeCount)
+ {
+ pDoc->SetScenario( nTab, TRUE );
+
+ // default flags
+ Color aColor( COL_LIGHTGRAY ); // Default
+ USHORT nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY;
+ String aComment;
+
+ pDoc->SetScenarioData( nTab, aComment, aColor, nFlags );
+ const table::CellRangeAddress* pAry = rScenRanges.getConstArray();
+ for (USHORT i=0; i<nRangeCount; i++)
+ {
+ DBG_ASSERT( pAry[i].Sheet == nTab, "addRanges mit falscher Tab" );
+ pDoc->ApplyFlagsTab( (USHORT)pAry[i].StartColumn, (USHORT)pAry[i].StartRow,
+ (USHORT)pAry[i].EndColumn, (USHORT)pAry[i].EndRow, nTab, SC_MF_SCENARIO );
+ }
+ pDoc->SetActiveScenario( nTab, TRUE );
+
+ // set to next visible tab
+ USHORT j = nTab - 1;
+ BOOL bFinished = FALSE;
+ while (j < nTab && !bFinished)
+ {
+ if (pDoc->IsVisible(j))
+ {
+ pDoc->SetVisibleTab(j);
+ bFinished = TRUE;
+ }
+ else
+ --j;
+ }
+
+ ScDocFunc aFunc(*pDocSh);
+ aFunc.SetTableVisible( nTab, FALSE, TRUE );
+ }
+ }*/
+ }
+}
+
+void SAL_CALL ScTableSheetObj::apply() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ String aName;
+ pDoc->GetName( nTab, aName ); // Name dieses Szenarios
+
+ SCTAB nDestTab = nTab;
+ while ( nDestTab > 0 && pDoc->IsScenario(nDestTab) )
+ --nDestTab;
+
+ if ( !pDoc->IsScenario(nDestTab) )
+ pDocSh->UseScenario( nDestTab, aName );
+
+ //! sonst Fehler oder so
+ }
+}
+
+// XScenarioEnhanced
+
+uno::Sequence< table::CellRangeAddress > SAL_CALL ScTableSheetObj::getRanges( )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ const ScRangeList* pRangeList = pDoc->GetScenarioRanges(nTab);
+ if (pRangeList)
+ {
+ sal_Int32 nCount = pRangeList->Count();
+ uno::Sequence< table::CellRangeAddress > aRetRanges(nCount);
+ table::CellRangeAddress* pAry = aRetRanges.getArray();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ const ScRange* pRange = pRangeList->GetObject( nIndex );
+ pAry->StartColumn = pRange->aStart.Col();
+ pAry->StartRow = pRange->aStart.Row();
+ pAry->EndColumn = pRange->aEnd.Col();
+ pAry->EndRow = pRange->aEnd.Row();
+ pAry->Sheet = pRange->aStart.Tab();
+ ++pAry;
+ }
+ return aRetRanges;
+ }
+ }
+ return uno::Sequence< table::CellRangeAddress > ();
+}
+
+// XExternalSheetName
+
+void ScTableSheetObj::setExternalName( const ::rtl::OUString& aUrl, const ::rtl::OUString& aSheetName )
+ throw (container::ElementExistException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if ( pDoc )
+ {
+ const SCTAB nTab = GetTab_Impl();
+ const String aAbsDocName( ScGlobal::GetAbsDocName( aUrl, pDocSh ) );
+ const String aDocTabName( ScGlobal::GetDocTabName( aAbsDocName, aSheetName ) );
+ if ( !pDoc->RenameTab( nTab, aDocTabName, FALSE /*bUpdateRef*/, TRUE /*bExternalDocument*/ ) )
+ {
+ throw container::ElementExistException( ::rtl::OUString(), *this );
+ }
+ }
+ }
+}
+
+// XEventsSupplier
+
+uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ return new ScSheetEventsObj( pDocSh, GetTab_Impl() );
+
+ return NULL;
+}
+
+// XPropertySet erweitert fuer Sheet-Properties
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( pSheetPropSet->getPropertyMap() ));
+ return aRef;
+}
+
+void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ // for Item WIDs, call ScCellRangesBase directly
+ ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
+ return;
+ }
+
+ // own properties
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ return; //! Exception oder so?
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+ ScDocFunc aFunc(*pDocSh);
+
+ if ( pEntry->nWID == SC_WID_UNO_PAGESTL )
+ {
+ rtl::OUString aStrVal;
+ aValue >>= aStrVal;
+ String aNewStr(ScStyleNameConversion::ProgrammaticToDisplayName(
+ aStrVal, SFX_STYLE_FAMILY_PAGE ));
+
+ //! Undo? (auch bei SID_STYLE_APPLY an der View)
+
+ if ( pDoc->GetPageStyle( nTab ) != aNewStr )
+ {
+ pDoc->SetPageStyle( nTab, aNewStr );
+ if (!pDoc->IsImportingXML())
+ {
+ ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
+
+ SfxBindings* pBindings = pDocSh->GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_STYLE_FAMILY4 );
+ pBindings->Invalidate( SID_STATUS_PAGESTYLE );
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+ }
+ pDocSh->SetDocumentModified();
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
+ {
+ BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ aFunc.SetTableVisible( nTab, bVis, TRUE );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE )
+ {
+ if (pDoc->IsScenario(nTab))
+ pDoc->SetActiveScenario( nTab, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_BORDCOL )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ sal_Int32 nNewColor = 0;
+ if (aValue >>= nNewColor)
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ aColor = Color(static_cast<sal_uInt32>(nNewColor));
+
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_PROTECT )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+ sal_Bool bModify(sal_False);
+
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ if (!(nFlags & SC_SCENARIO_PROTECT))
+ {
+ nFlags |= SC_SCENARIO_PROTECT;
+ bModify = sal_True;
+ }
+ }
+ else
+ {
+ if (nFlags & SC_SCENARIO_PROTECT)
+ {
+ nFlags -= SC_SCENARIO_PROTECT;
+ bModify = sal_True;
+ }
+ }
+
+ if (bModify)
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+ sal_Bool bModify(sal_False);
+
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ if (!(nFlags & SC_SCENARIO_SHOWFRAME))
+ {
+ nFlags |= SC_SCENARIO_SHOWFRAME;
+ bModify = sal_True;
+ }
+ }
+ else
+ {
+ if (nFlags & SC_SCENARIO_SHOWFRAME)
+ {
+ nFlags -= SC_SCENARIO_SHOWFRAME;
+ bModify = sal_True;
+ }
+ }
+
+ if (bModify)
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+ sal_Bool bModify(sal_False);
+
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ if (!(nFlags & SC_SCENARIO_PRINTFRAME))
+ {
+ nFlags |= SC_SCENARIO_PRINTFRAME;
+ bModify = sal_True;
+ }
+ }
+ else
+ {
+ if (nFlags & SC_SCENARIO_PRINTFRAME)
+ {
+ nFlags -= SC_SCENARIO_PRINTFRAME;
+ bModify = sal_True;
+ }
+ }
+
+ if (bModify)
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_COPYBACK )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+ sal_Bool bModify(sal_False);
+
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ if (!(nFlags & SC_SCENARIO_TWOWAY))
+ {
+ nFlags |= SC_SCENARIO_TWOWAY;
+ bModify = sal_True;
+ }
+ }
+ else
+ {
+ if (nFlags & SC_SCENARIO_TWOWAY)
+ {
+ nFlags -= SC_SCENARIO_TWOWAY;
+ bModify = sal_True;
+ }
+ }
+
+ if (bModify)
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+ sal_Bool bModify(sal_False);
+
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ if (!(nFlags & SC_SCENARIO_ATTRIB))
+ {
+ nFlags |= SC_SCENARIO_ATTRIB;
+ bModify = sal_True;
+ }
+ }
+ else
+ {
+ if (nFlags & SC_SCENARIO_ATTRIB)
+ {
+ nFlags -= SC_SCENARIO_ATTRIB;
+ bModify = sal_True;
+ }
+ }
+
+ if (bModify)
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_COPYFORM )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetName( nTab, aName );
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+ sal_Bool bModify(sal_False);
+
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ if (nFlags & SC_SCENARIO_VALUE)
+ {
+ nFlags -= SC_SCENARIO_VALUE;
+ bModify = sal_True;
+ }
+ }
+ else
+ {
+ if (!(nFlags & SC_SCENARIO_VALUE))
+ {
+ nFlags |= SC_SCENARIO_VALUE;
+ bModify = sal_True;
+ }
+ }
+
+ if (bModify)
+ pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT )
+ {
+ sal_Int16 nValue = 0;
+ if (aValue >>= nValue)
+ {
+ if (nValue == com::sun::star::text::WritingMode2::RL_TB)
+ aFunc.SetLayoutRTL(nTab, sal_True, sal_True);
+ else
+ aFunc.SetLayoutRTL(nTab, sal_False, sal_True);
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT )
+ {
+ BOOL bAutoPrint = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bAutoPrint)
+ pDoc->SetPrintEntireSheet( nTab ); // clears all print ranges
+ else
+ {
+ if (pDoc->IsPrintEntireSheet( nTab ))
+ pDoc->ClearPrintRanges( nTab ); // if this flag is true, there are no PrintRanges, so Clear clears only the flag.
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR )
+ {
+ sal_Int32 nColor = COL_AUTO;
+ if (aValue >>= nColor)
+ {
+ if (static_cast<ColorData>(nColor) != COL_AUTO)
+ pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor)));
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CODENAME )
+ {
+ rtl::OUString aCodeName;
+ if ( pDocSh && ( aValue >>= aCodeName ) )
+ {
+ String sNewName( aCodeName );
+ pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), sNewName );
+ }
+ }
+ else
+ ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID
+ }
+}
+
+void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
+ uno::Any& rAny )
+ throw(uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ throw uno::RuntimeException();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetTab_Impl();
+
+ if ( pEntry->nWID == SC_WID_UNO_PAGESTL )
+ {
+ rAny <<= rtl::OUString( ScStyleNameConversion::DisplayToProgrammaticName(
+ pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE ) );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
+ {
+ BOOL bVis = pDoc->IsVisible( nTab );
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bVis );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_LINKDISPBIT )
+ {
+ // no target bitmaps for individual entries (would be all equal)
+ // ScLinkTargetTypeObj::SetLinkTargetBitmap( aAny, SC_LINKTARGETTYPE_SHEET );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_LINKDISPNAME )
+ {
+ // LinkDisplayName for hyperlink dialog
+ rAny <<= getName(); // sheet name
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE )
+ {
+ if (pDoc->IsScenario(nTab))
+ ScUnoHelpFunctions::SetBoolInAny( rAny, pDoc->IsActiveScenario( nTab ));
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_BORDCOL )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ rAny <<= static_cast<sal_Int32>(aColor.GetColor());
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_PROTECT )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_PROTECT) != 0 );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_SHOWFRAME) != 0 );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_PRINTFRAME) != 0 );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_COPYBACK )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_TWOWAY) != 0 );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_ATTRIB) != 0 );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_COPYFORM )
+ {
+ if (pDoc->IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ ScUnoHelpFunctions::SetBoolInAny( rAny, !(nFlags & SC_SCENARIO_VALUE));
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT )
+ {
+ if (pDoc->IsLayoutRTL(nTab))
+ rAny <<= sal_Int16(com::sun::star::text::WritingMode2::RL_TB);
+ else
+ rAny <<= sal_Int16(com::sun::star::text::WritingMode2::LR_TB);
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT )
+ {
+ BOOL bAutoPrint = pDoc->IsPrintEntireSheet( nTab );
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bAutoPrint );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR )
+ {
+ rAny <<= sal_Int32(pDoc->GetTabBgColor(nTab).GetColor());
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CODENAME )
+ {
+ String aCodeName;
+ if ( pDocSh )
+ pDocSh->GetDocument()->GetCodeName( GetTab_Impl(), aCodeName );
+ rAny <<= rtl::OUString( aCodeName );
+ }
+ else
+ ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
+ }
+}
+
+const SfxItemPropertyMap* ScTableSheetObj::GetItemPropertyMap()
+{
+ return pSheetPropSet->getPropertyMap();
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScTableSheetObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScTableSheetObj" );
+}
+
+sal_Bool SAL_CALL ScTableSheetObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCSPREADSHEET_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCSHEETCELLRANGE_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLRANGE_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCLINKTARGET_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(7);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSPREADSHEET_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCSHEETCELLRANGE_SERVICE );
+ pArray[2] = rtl::OUString::createFromAscii( SCCELLRANGE_SERVICE );
+ pArray[3] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
+ pArray[4] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
+ pArray[5] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
+ pArray[6] = rtl::OUString::createFromAscii( SCLINKTARGET_SERVICE );
+ return aRet;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScTableSheetObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+
+ return ScCellRangeObj::getSomething( rId );
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScTableSheetObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScTableSheetObj* ScTableSheetObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScTableSheetObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScTableSheetObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScTableColumnObj::ScTableColumnObj( ScDocShell* pDocSh, SCCOL nCol, SCTAB nTab ) :
+ ScCellRangeObj( pDocSh, ScRange(nCol,0,nTab, nCol,MAXROW,nTab) ),
+ pColPropSet(lcl_GetColumnPropertySet())
+{
+}
+
+ScTableColumnObj::~ScTableColumnObj()
+{
+}
+
+uno::Any SAL_CALL ScTableColumnObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( container::XNamed )
+
+ return ScCellRangeObj::queryInterface( rType );
+}
+
+void SAL_CALL ScTableColumnObj::acquire() throw()
+{
+ ScCellRangeObj::acquire();
+}
+
+void SAL_CALL ScTableColumnObj::release() throw()
+{
+ ScCellRangeObj::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScTableColumnObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 1 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<container::XNamed>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScTableColumnObj::getImplementationId() throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XNamed
+
+rtl::OUString SAL_CALL ScTableColumnObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ const ScRange& rRange = GetRange();
+ DBG_ASSERT(rRange.aStart.Col() == rRange.aEnd.Col(), "too many columns");
+ SCCOL nCol = rRange.aStart.Col();
+
+ return ScColToAlpha( nCol ); // from global.hxx
+}
+
+void SAL_CALL ScTableColumnObj::setName( const rtl::OUString& /* aNewName */ )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ throw uno::RuntimeException(); // read-only
+}
+
+// XPropertySet erweitert fuer Spalten-Properties
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( pColPropSet->getPropertyMap() ));
+ return aRef;
+}
+
+void ScTableColumnObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ // for Item WIDs, call ScCellRangesBase directly
+ ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
+ return;
+ }
+
+ // own properties
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ return; //! Exception oder so?
+ const ScRange& rRange = GetRange();
+ DBG_ASSERT(rRange.aStart.Col() == rRange.aEnd.Col(), "zuviele Spalten");
+ SCCOL nCol = rRange.aStart.Col();
+ SCTAB nTab = rRange.aStart.Tab();
+ ScDocFunc aFunc(*pDocSh);
+
+ SCCOLROW nColArr[2];
+ nColArr[0] = nColArr[1] = nCol;
+
+ if ( pEntry->nWID == SC_WID_UNO_CELLWID )
+ {
+ sal_Int32 nNewWidth = 0;
+ if ( aValue >>= nNewWidth )
+ {
+ // property is 1/100mm, column width is twips
+ nNewWidth = HMMToTwips(nNewWidth);
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
+ (USHORT)nNewWidth, TRUE, TRUE );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
+ {
+ BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab, eMode, 0, TRUE, TRUE );
+ // SC_SIZE_DIRECT mit Groesse 0 blendet aus
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_OWIDTH )
+ {
+ BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bOpt)
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab,
+ SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, TRUE, TRUE );
+ // FALSE bei Spalten momentan ohne Auswirkung
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE )
+ {
+ BOOL bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bSet)
+ aFunc.InsertPageBreak( TRUE, rRange.aStart, TRUE, TRUE, TRUE );
+ else
+ aFunc.RemovePageBreak( TRUE, rRange.aStart, TRUE, TRUE, TRUE );
+ }
+ else
+ ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID
+ }
+}
+
+void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
+ uno::Any& rAny )
+ throw(uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ throw uno::RuntimeException();
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ const ScRange& rRange = GetRange();
+ DBG_ASSERT(rRange.aStart.Col() == rRange.aEnd.Col(), "zuviele Spalten");
+ SCCOL nCol = rRange.aStart.Col();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ if ( pEntry->nWID == SC_WID_UNO_CELLWID )
+ {
+ // for hidden column, return original height
+ USHORT nWidth = pDoc->GetOriginalWidth( nCol, nTab );
+ // property is 1/100mm, column width is twips
+ nWidth = (USHORT) TwipsToHMM(nWidth);
+ rAny <<= (sal_Int32)( nWidth );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
+ {
+ SCCOL nDummy;
+ bool bHidden = pDoc->ColHidden(nCol, nTab, nDummy);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_OWIDTH )
+ {
+ //! momentan immer gesetzt ??!?!
+ BOOL bOpt = !(pDoc->GetColFlags( nCol, nTab ) & CR_MANUALSIZE);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bOpt );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
+ {
+ ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
+ {
+ ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
+ ScUnoHelpFunctions::SetBoolInAny(rAny, (nBreak & BREAK_MANUAL));
+ }
+ else
+ ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
+ }
+}
+
+const SfxItemPropertyMap* ScTableColumnObj::GetItemPropertyMap()
+{
+ return pColPropSet->getPropertyMap();
+}
+
+//------------------------------------------------------------------------
+
+ScTableRowObj::ScTableRowObj(ScDocShell* pDocSh, SCROW nRow, SCTAB nTab) :
+ ScCellRangeObj( pDocSh, ScRange(0,nRow,nTab, MAXCOL,nRow,nTab) ),
+ pRowPropSet(lcl_GetRowPropertySet())
+{
+}
+
+ScTableRowObj::~ScTableRowObj()
+{
+}
+
+// XPropertySet erweitert fuer Zeilen-Properties
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( pRowPropSet->getPropertyMap() ));
+ return aRef;
+}
+
+void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ // for Item WIDs, call ScCellRangesBase directly
+ ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
+ return;
+ }
+
+ // own properties
+
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ return; //! Exception oder so?
+ ScDocument* pDoc = pDocSh->GetDocument();
+ const ScRange& rRange = GetRange();
+ DBG_ASSERT(rRange.aStart.Row() == rRange.aEnd.Row(), "zuviele Zeilen");
+ SCROW nRow = rRange.aStart.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+ ScDocFunc aFunc(*pDocSh);
+
+ SCCOLROW nRowArr[2];
+ nRowArr[0] = nRowArr[1] = nRow;
+
+ if ( pEntry->nWID == SC_WID_UNO_CELLHGT )
+ {
+ sal_Int32 nNewHeight = 0;
+ if ( aValue >>= nNewHeight )
+ {
+ // property is 1/100mm, row height is twips
+ nNewHeight = HMMToTwips(nNewHeight);
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
+ (USHORT)nNewHeight, TRUE, TRUE );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
+ {
+ BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE );
+ // SC_SIZE_DIRECT mit Groesse 0 blendet aus
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLFILT )
+ {
+ BOOL bFil = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+// ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
+// aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE );
+ // SC_SIZE_DIRECT mit Groesse 0 blendet aus
+ pDoc->SetRowFiltered(nRow, nRow, nTab, bFil);
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT )
+ {
+ BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bOpt)
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, TRUE, TRUE );
+ else
+ {
+ // set current height again manually
+ USHORT nHeight = pDoc->GetOriginalHeight( nRow, nTab );
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_ORIGINAL, nHeight, TRUE, TRUE );
+ }
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE )
+ {
+ BOOL bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bSet)
+ aFunc.InsertPageBreak( FALSE, rRange.aStart, TRUE, TRUE, TRUE );
+ else
+ aFunc.RemovePageBreak( FALSE, rRange.aStart, TRUE, TRUE, TRUE );
+ }
+ else
+ ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID
+ }
+}
+
+void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
+ uno::Any& rAny )
+ throw(uno::RuntimeException)
+{
+ if ( pEntry )
+ {
+ ScDocShell* pDocSh = GetDocShell();
+ if (!pDocSh)
+ throw uno::RuntimeException();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ const ScRange& rRange = GetRange();
+ DBG_ASSERT(rRange.aStart.Row() == rRange.aEnd.Row(), "zuviele Zeilen");
+ SCROW nRow = rRange.aStart.Row();
+ SCTAB nTab = rRange.aStart.Tab();
+
+ if ( pEntry->nWID == SC_WID_UNO_CELLHGT )
+ {
+ // for hidden row, return original height
+ USHORT nHeight = pDoc->GetOriginalHeight( nRow, nTab );
+ // property is 1/100mm, row height is twips
+ nHeight = (USHORT) TwipsToHMM(nHeight);
+ rAny <<= (sal_Int32)( nHeight );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
+ {
+ SCROW nDummy;
+ bool bHidden = pDoc->RowHidden(nRow, nTab, nDummy);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_CELLFILT )
+ {
+ bool bVis = pDoc->RowFiltered(nRow, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bVis );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT )
+ {
+ BOOL bOpt = !(pDoc->GetRowFlags( nRow, nTab ) & CR_MANUALSIZE);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, bOpt );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
+ {
+ ScBreakType nBreak = pDoc->HasRowBreak(nRow, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
+ }
+ else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
+ {
+ ScBreakType nBreak = (pDoc->HasRowBreak(nRow, nTab) & BREAK_MANUAL);
+ ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
+ }
+ else
+ ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
+ }
+}
+
+const SfxItemPropertyMap* ScTableRowObj::GetItemPropertyMap()
+{
+ return pRowPropSet->getPropertyMap();
+}
+
+//------------------------------------------------------------------------
+
+ScCellsObj::ScCellsObj(ScDocShell* pDocSh, const ScRangeList& rR) :
+ pDocShell( pDocSh ),
+ aRanges( rR )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScCellsObj::~ScCellsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScCellsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+ aRanges.UpdateReference( rRef.GetMode(), pDocShell->GetDocument(), rRef.GetRange(),
+ rRef.GetDx(), rRef.GetDy(), rRef.GetDz() );
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScCellsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScCellsEnumeration( pDocShell, aRanges );
+ return NULL;
+}
+
+uno::Type SAL_CALL ScCellsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<table::XCell>*)0);
+}
+
+sal_Bool SAL_CALL ScCellsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bHas = FALSE;
+ if ( pDocShell )
+ {
+ //! schneller selber testen?
+
+ uno::Reference<container::XEnumeration> xEnum(new ScCellsEnumeration( pDocShell, aRanges ));
+ bHas = xEnum->hasMoreElements();
+ }
+ return bHas;
+}
+
+//------------------------------------------------------------------------
+
+ScCellsEnumeration::ScCellsEnumeration(ScDocShell* pDocSh, const ScRangeList& rR) :
+ pDocShell( pDocSh ),
+ aRanges( rR ),
+ pMark( NULL ),
+ bAtEnd( FALSE )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->AddUnoObject(*this);
+
+ if ( aRanges.Count() == 0 )
+ bAtEnd = TRUE;
+ else
+ {
+ SCTAB nTab = 0;
+ const ScRange* pFirst = aRanges.GetObject(0);
+ if (pFirst)
+ nTab = pFirst->aStart.Tab();
+ aPos = ScAddress(0,0,nTab);
+ CheckPos_Impl(); // aPos auf erste passende Zelle setzen
+ }
+}
+
+void ScCellsEnumeration::CheckPos_Impl()
+{
+ if (pDocShell)
+ {
+ BOOL bFound = FALSE;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScBaseCell* pCell = pDoc->GetCell(aPos);
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
+ {
+ if (!pMark)
+ {
+ pMark = new ScMarkData;
+ pMark->MarkFromRangeList( aRanges, FALSE );
+ pMark->MarkToMulti(); // needed for GetNextMarkedCell
+ }
+ bFound = pMark->IsCellMarked( aPos.Col(), aPos.Row() );
+ }
+ if (!bFound)
+ Advance_Impl();
+ }
+}
+
+ScCellsEnumeration::~ScCellsEnumeration()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+ delete pMark;
+}
+
+void ScCellsEnumeration::Advance_Impl()
+{
+ DBG_ASSERT(!bAtEnd,"zuviel Advance_Impl");
+ if (!pMark)
+ {
+ pMark = new ScMarkData;
+ pMark->MarkFromRangeList( aRanges, FALSE );
+ pMark->MarkToMulti(); // needed for GetNextMarkedCell
+ }
+
+ SCCOL nCol = aPos.Col();
+ SCROW nRow = aPos.Row();
+ SCTAB nTab = aPos.Tab();
+ BOOL bFound = pDocShell->GetDocument()->GetNextMarkedCell( nCol, nRow, nTab, *pMark );
+ if (bFound)
+ aPos.Set( nCol, nRow, nTab );
+ else
+ bAtEnd = TRUE; // kommt nix mehr
+}
+
+void ScCellsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ if (pDocShell)
+ {
+ const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+ aRanges.UpdateReference( rRef.GetMode(), pDocShell->GetDocument(), rRef.GetRange(),
+ rRef.GetDx(), rRef.GetDy(), rRef.GetDz() );
+
+ delete pMark; // aus verschobenen Bereichen neu erzeugen
+ pMark = NULL;
+
+ if (!bAtEnd) // aPos anpassen
+ {
+ ScRangeList aNew;
+ aNew.Append(ScRange(aPos));
+ aNew.UpdateReference( rRef.GetMode(), pDocShell->GetDocument(), rRef.GetRange(),
+ rRef.GetDx(), rRef.GetDy(), rRef.GetDz() );
+ if (aNew.Count()==1)
+ {
+ aPos = aNew.GetObject(0)->aStart;
+ CheckPos_Impl();
+ }
+ }
+ }
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XEnumeration
+
+sal_Bool SAL_CALL ScCellsEnumeration::hasMoreElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return !bAtEnd;
+}
+
+uno::Any SAL_CALL ScCellsEnumeration::nextElement() throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell && !bAtEnd)
+ {
+ // Interface-Typ muss zu ScCellsObj::getElementType passen
+
+ ScAddress aTempPos(aPos);
+ Advance_Impl();
+ return uno::makeAny(uno::Reference<table::XCell>(new ScCellObj( pDocShell, aTempPos )));
+ }
+
+ throw container::NoSuchElementException(); // no more elements
+// return uno::Any();
+}
+
+//------------------------------------------------------------------------
+
+ScCellFormatsObj::ScCellFormatsObj(ScDocShell* pDocSh, const ScRange& rRange) :
+ pDocShell( pDocSh ),
+ aTotalRange( rRange )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->AddUnoObject(*this);
+
+ DBG_ASSERT( aTotalRange.aStart.Tab() == aTotalRange.aEnd.Tab(), "unterschiedliche Tabellen" );
+}
+
+ScCellFormatsObj::~ScCellFormatsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ //! aTotalRange...
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+ScCellRangeObj* ScCellFormatsObj::GetObjectByIndex_Impl(long nIndex) const
+{
+ //! direkt auf die AttrArrays zugreifen !!!!
+
+ ScCellRangeObj* pRet = NULL;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ long nPos = 0;
+ ScAttrRectIterator aIter( pDoc, aTotalRange.aStart.Tab(),
+ aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
+ aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
+ {
+ if ( nPos == nIndex )
+ {
+ SCTAB nTab = aTotalRange.aStart.Tab();
+ ScRange aNext( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+
+ if ( aNext.aStart == aNext.aEnd )
+ pRet = new ScCellObj( pDocShell, aNext.aStart );
+ else
+ pRet = new ScCellRangeObj( pDocShell, aNext );
+ }
+ ++nPos;
+ }
+ }
+ return pRet;
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScCellFormatsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! direkt auf die AttrArrays zugreifen !!!!
+
+ long nCount = 0;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScAttrRectIterator aIter( pDoc, aTotalRange.aStart.Tab(),
+ aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
+ aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
+ ++nCount;
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL ScCellFormatsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex));
+ if (xRange.is())
+ return uno::makeAny(xRange);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScCellFormatsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<table::XCellRange>*)0);
+}
+
+sal_Bool SAL_CALL ScCellFormatsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 ); //! immer groesser 0 ??
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScCellFormatsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScCellFormatsEnumeration( pDocShell, aTotalRange );
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+ScCellFormatsEnumeration::ScCellFormatsEnumeration(ScDocShell* pDocSh, const ScRange& rRange) :
+ pDocShell( pDocSh ),
+ nTab( rRange.aStart.Tab() ),
+ pIter( NULL ),
+ bAtEnd( FALSE ),
+ bDirty( FALSE )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->AddUnoObject(*this);
+
+ DBG_ASSERT( rRange.aStart.Tab() == rRange.aEnd.Tab(),
+ "CellFormatsEnumeration: unterschiedliche Tabellen" );
+
+ pIter = new ScAttrRectIterator( pDoc, nTab,
+ rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row() );
+ Advance_Impl();
+}
+
+ScCellFormatsEnumeration::~ScCellFormatsEnumeration()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+ delete pIter;
+}
+
+void ScCellFormatsEnumeration::Advance_Impl()
+{
+ DBG_ASSERT(!bAtEnd,"zuviel Advance_Impl");
+
+ if ( pIter )
+ {
+ if ( bDirty )
+ {
+ pIter->DataChanged(); // AttrArray-Index neu suchen
+ bDirty = FALSE;
+ }
+
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ if ( pIter->GetNext( nCol1, nCol2, nRow1, nRow2 ) )
+ aNext = ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+ else
+ bAtEnd = TRUE; // kommt nix mehr
+ }
+ else
+ bAtEnd = TRUE; // Dok weggekommen oder so
+}
+
+ScCellRangeObj* ScCellFormatsEnumeration::NextObject_Impl()
+{
+ ScCellRangeObj* pRet = NULL;
+ if (pDocShell && !bAtEnd)
+ {
+ if ( aNext.aStart == aNext.aEnd )
+ pRet = new ScCellObj( pDocShell, aNext.aStart );
+ else
+ pRet = new ScCellRangeObj( pDocShell, aNext );
+ Advance_Impl();
+ }
+ return pRet;
+}
+
+void ScCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ //! und nun ???
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ delete pIter;
+ pIter = NULL;
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ bDirty = TRUE; // AttrArray-Index evtl. ungueltig geworden
+ }
+ }
+}
+
+// XEnumeration
+
+sal_Bool SAL_CALL ScCellFormatsEnumeration::hasMoreElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return !bAtEnd;
+}
+
+uno::Any SAL_CALL ScCellFormatsEnumeration::nextElement() throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( bAtEnd || !pDocShell )
+ throw container::NoSuchElementException(); // no more elements
+
+ // Interface-Typ muss zu ScCellFormatsObj::getElementType passen
+
+ return uno::makeAny(uno::Reference<table::XCellRange> (NextObject_Impl()));
+}
+
+//------------------------------------------------------------------------
+
+ScUniqueCellFormatsObj::ScUniqueCellFormatsObj(ScDocShell* pDocSh, const ScRange& rRange) :
+ pDocShell( pDocSh ),
+ aTotalRange( rRange ),
+ aRangeLists()
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ DBG_ASSERT( aTotalRange.aStart.Tab() == aTotalRange.aEnd.Tab(), "unterschiedliche Tabellen" );
+
+ GetObjects_Impl();
+}
+
+ScUniqueCellFormatsObj::~ScUniqueCellFormatsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScUniqueCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ //! aTotalRange...
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+//
+// Fill the list of formats from the document
+//
+
+// hash code to access the range lists by ScPatternAttr pointer
+struct ScPatternHashCode
+{
+ size_t operator()( const ScPatternAttr* pPattern ) const
+ {
+ return reinterpret_cast<size_t>(pPattern);
+ }
+};
+
+// Hash map to find a range by its start row
+typedef ::std::hash_map< SCROW, ScRange > ScRowRangeHashMap;
+
+typedef ::std::vector<ScRange> ScRangeVector;
+
+// Hash map entry.
+// The Join method depends on the column-wise order of ScAttrRectIterator
+class ScUniqueFormatsEntry
+{
+ enum EntryState { STATE_EMPTY, STATE_SINGLE, STATE_COMPLEX };
+
+ EntryState eState;
+ ScRange aSingleRange;
+ ScRowRangeHashMap aJoinedRanges; // "active" ranges to be merged
+ ScRangeVector aCompletedRanges; // ranges that will no longer be touched
+ ScRangeListRef aReturnRanges; // result as ScRangeList for further use
+
+public:
+ ScUniqueFormatsEntry() : eState( STATE_EMPTY ) {}
+ ScUniqueFormatsEntry( const ScUniqueFormatsEntry& r ) :
+ eState( r.eState ),
+ aSingleRange( r.aSingleRange ),
+ aJoinedRanges( r.aJoinedRanges ),
+ aCompletedRanges( r.aCompletedRanges ),
+ aReturnRanges( r.aReturnRanges ) {}
+ ~ScUniqueFormatsEntry() {}
+
+ void Join( const ScRange& rNewRange );
+ const ScRangeList& GetRanges();
+ void Clear() { aReturnRanges.Clear(); } // aJoinedRanges and aCompletedRanges are cleared in GetRanges
+};
+
+void ScUniqueFormatsEntry::Join( const ScRange& rNewRange )
+{
+ // Special-case handling for single range
+
+ if ( eState == STATE_EMPTY )
+ {
+ aSingleRange = rNewRange;
+ eState = STATE_SINGLE;
+ return;
+ }
+ if ( eState == STATE_SINGLE )
+ {
+ if ( aSingleRange.aStart.Row() == rNewRange.aStart.Row() &&
+ aSingleRange.aEnd.Row() == rNewRange.aEnd.Row() &&
+ aSingleRange.aEnd.Col() + 1 == rNewRange.aStart.Col() )
+ {
+ aSingleRange.aEnd.SetCol( rNewRange.aEnd.Col() );
+ return; // still a single range
+ }
+
+ SCROW nSingleRow = aSingleRange.aStart.Row();
+ aJoinedRanges.insert( ScRowRangeHashMap::value_type( nSingleRow, aSingleRange ) );
+ eState = STATE_COMPLEX;
+ // continue normally
+ }
+
+ // This is called in the order of ScAttrRectIterator results.
+ // rNewRange can only be joined with an existing entry if it's the same rows, starting in the next column.
+ // If the old entry for the start row extends to a different end row, or ends in a different column, it
+ // can be moved to aCompletedRanges because it can't be joined with following iterator results.
+ // Everything happens within one sheet, so Tab can be ignored.
+
+ SCROW nStartRow = rNewRange.aStart.Row();
+ ScRowRangeHashMap::iterator aIter( aJoinedRanges.find( nStartRow ) ); // find the active entry for the start row
+ if ( aIter != aJoinedRanges.end() )
+ {
+ ScRange& rOldRange = aIter->second;
+ if ( rOldRange.aEnd.Row() == rNewRange.aEnd.Row() &&
+ rOldRange.aEnd.Col() + 1 == rNewRange.aStart.Col() )
+ {
+ // extend existing range
+ rOldRange.aEnd.SetCol( rNewRange.aEnd.Col() );
+ }
+ else
+ {
+ // move old range to aCompletedRanges, keep rNewRange for joining
+ aCompletedRanges.push_back( rOldRange );
+ rOldRange = rNewRange; // replace in hash map
+ }
+ }
+ else
+ {
+ // keep rNewRange for joining
+ aJoinedRanges.insert( ScRowRangeHashMap::value_type( nStartRow, rNewRange ) );
+ }
+}
+
+const ScRangeList& ScUniqueFormatsEntry::GetRanges()
+{
+ if ( eState == STATE_SINGLE )
+ {
+ aReturnRanges = new ScRangeList;
+ aReturnRanges->Append( aSingleRange );
+ return *aReturnRanges;
+ }
+
+ // move remaining entries from aJoinedRanges to aCompletedRanges
+
+ ScRowRangeHashMap::const_iterator aJoinedEnd = aJoinedRanges.end();
+ for ( ScRowRangeHashMap::const_iterator aJoinedIter = aJoinedRanges.begin(); aJoinedIter != aJoinedEnd; ++aJoinedIter )
+ aCompletedRanges.push_back( aJoinedIter->second );
+ aJoinedRanges.clear();
+
+ // sort all ranges for a predictable API result
+
+ std::sort( aCompletedRanges.begin(), aCompletedRanges.end() );
+
+ // fill and return ScRangeList
+
+ aReturnRanges = new ScRangeList;
+ ScRangeVector::const_iterator aCompEnd( aCompletedRanges.end() );
+ for ( ScRangeVector::const_iterator aCompIter( aCompletedRanges.begin() ); aCompIter != aCompEnd; ++aCompIter )
+ aReturnRanges->Append( *aCompIter );
+ aCompletedRanges.clear();
+
+ return *aReturnRanges;
+}
+
+typedef ::std::hash_map< const ScPatternAttr*, ScUniqueFormatsEntry, ScPatternHashCode > ScUniqueFormatsHashMap;
+
+// function object to sort the range lists by start of first range
+struct ScUniqueFormatsOrder
+{
+ bool operator()( const ScRangeList& rList1, const ScRangeList& rList2 ) const
+ {
+ // all range lists have at least one entry
+ DBG_ASSERT( rList1.Count() > 0 && rList2.Count() > 0, "ScUniqueFormatsOrder: empty list" );
+
+ // compare start positions using ScAddress comparison operator
+ return ( rList1.GetObject(0)->aStart < rList2.GetObject(0)->aStart );
+ }
+};
+
+void ScUniqueCellFormatsObj::GetObjects_Impl()
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = aTotalRange.aStart.Tab();
+ ScAttrRectIterator aIter( pDoc, nTab,
+ aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
+ aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+
+ // Collect the ranges for each format in a hash map, to avoid nested loops
+
+ ScUniqueFormatsHashMap aHashMap;
+ while (aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
+ {
+ ScRange aRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+ const ScPatternAttr* pPattern = pDoc->GetPattern(nCol1, nRow1, nTab);
+ aHashMap[pPattern].Join( aRange );
+ }
+
+ // Fill the vector aRangeLists with the range lists from the hash map
+
+ aRangeLists.reserve( aHashMap.size() );
+ ScUniqueFormatsHashMap::iterator aMapIter( aHashMap.begin() );
+ ScUniqueFormatsHashMap::iterator aMapEnd( aHashMap.end() );
+ while ( aMapIter != aMapEnd )
+ {
+ ScUniqueFormatsEntry& rEntry = aMapIter->second;
+ const ScRangeList& rRanges = rEntry.GetRanges();
+ aRangeLists.push_back( rRanges ); // copy ScRangeList
+ rEntry.Clear(); // free memory, don't hold both copies of all ranges
+ ++aMapIter;
+ }
+
+ // Sort the vector by first range's start position, to avoid random shuffling
+ // due to using the ScPatterAttr pointers
+
+ ScUniqueFormatsOrder aComp;
+ ::std::sort( aRangeLists.begin(), aRangeLists.end(), aComp );
+ }
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScUniqueCellFormatsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ return aRangeLists.size();
+}
+
+uno::Any SAL_CALL ScUniqueCellFormatsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if(static_cast<sal_uInt32>(nIndex) < aRangeLists.size())
+ return uno::makeAny(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nIndex])));
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScUniqueCellFormatsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XSheetCellRangeContainer>*)0);
+}
+
+sal_Bool SAL_CALL ScUniqueCellFormatsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( aRangeLists.size() != 0 );
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScUniqueCellFormatsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScUniqueCellFormatsEnumeration( pDocShell, aRangeLists );
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+ScUniqueCellFormatsEnumeration::ScUniqueCellFormatsEnumeration(ScDocShell* pDocSh, const ScMyRangeLists& rRangeLists) :
+ aRangeLists(rRangeLists),
+ pDocShell( pDocSh ),
+ nCurrentPosition(0)
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScUniqueCellFormatsEnumeration::~ScUniqueCellFormatsEnumeration()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScUniqueCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ //! und nun ???
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XEnumeration
+
+sal_Bool SAL_CALL ScUniqueCellFormatsEnumeration::hasMoreElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return static_cast<sal_uInt32>(nCurrentPosition) < aRangeLists.size();
+}
+
+uno::Any SAL_CALL ScUniqueCellFormatsEnumeration::nextElement() throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !hasMoreElements() || !pDocShell )
+ throw container::NoSuchElementException(); // no more elements
+
+ // Interface-Typ muss zu ScCellFormatsObj::getElementType passen
+
+ return uno::makeAny(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nCurrentPosition++])));
+}
+
+
diff --git a/sc/source/ui/unoobj/cellvaluebinding.cxx b/sc/source/ui/unoobj/cellvaluebinding.cxx
new file mode 100644
index 000000000000..3b806ccf80b7
--- /dev/null
+++ b/sc/source/ui/unoobj/cellvaluebinding.cxx
@@ -0,0 +1,663 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "cellvaluebinding.hxx"
+#include <tools/debug.hxx>
+#include <rtl/math.hxx>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeData.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+
+//.........................................................................
+namespace calc
+{
+//.........................................................................
+
+#define PROP_HANDLE_BOUND_CELL 1
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::table;
+ using namespace ::com::sun::star::text;
+ using namespace ::com::sun::star::sheet;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::form::binding;
+
+ //=====================================================================
+ //= OCellValueBinding
+ //=====================================================================
+ DBG_NAME( OCellValueBinding )
+ //---------------------------------------------------------------------
+#ifdef DBG_UTIL
+ const char* OCellValueBinding::checkConsistency_static( const void* _pThis )
+ {
+ return static_cast< const OCellValueBinding* >( _pThis )->checkConsistency( );
+ }
+
+ const char* OCellValueBinding::checkConsistency( ) const
+ {
+ const char* pAssertion = NULL;
+ if ( m_xCellText.is() && !m_xCell.is() )
+ // there are places (e.g. getSupportedTypes) which rely on the fact
+ // that m_xCellText.is() implies m_xCell.is()
+ pAssertion = "cell references inconsistent!";
+
+ // TODO: place any additional checks here to ensure consistency of this instance
+ return pAssertion;
+ }
+#endif
+
+ //---------------------------------------------------------------------
+ OCellValueBinding::OCellValueBinding( const Reference< XSpreadsheetDocument >& _rxDocument, sal_Bool _bListPos )
+ :OCellValueBinding_Base( m_aMutex )
+ ,OCellValueBinding_PBase( OCellValueBinding_Base::rBHelper )
+ ,m_xDocument( _rxDocument )
+ ,m_aModifyListeners( m_aMutex )
+ ,m_bInitialized( sal_False )
+ ,m_bListPos( _bListPos )
+ {
+ DBG_CTOR( OCellValueBinding, checkConsistency_static );
+
+ // register our property at the base class
+ CellAddress aInitialPropValue;
+ registerPropertyNoMember(
+ ::rtl::OUString::createFromAscii( "BoundCell" ),
+ PROP_HANDLE_BOUND_CELL,
+ PropertyAttribute::BOUND | PropertyAttribute::READONLY,
+ ::getCppuType( &aInitialPropValue ),
+ &aInitialPropValue
+ );
+
+ // TODO: implement a ReadOnly property as required by the service,
+ // which probably maps to the cell being locked
+ }
+
+ //---------------------------------------------------------------------
+ OCellValueBinding::~OCellValueBinding( )
+ {
+ if ( !OCellValueBinding_Base::rBHelper.bDisposed )
+ {
+ acquire(); // prevent duplicate dtor
+ dispose();
+ }
+
+ DBG_DTOR( OCellValueBinding, checkConsistency_static );
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XINTERFACE2( OCellValueBinding, OCellValueBinding_Base, OCellValueBinding_PBase )
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCellValueBinding, OCellValueBinding_Base, OCellValueBinding_PBase )
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::disposing()
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+
+ Reference<XModifyBroadcaster> xBroadcaster( m_xCell, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ {
+ xBroadcaster->removeModifyListener( this );
+ }
+
+// OCellValueBinding_Base::disposing();
+ WeakAggComponentImplHelperBase::disposing();
+
+ // TODO: clean up here whatever you need to clean up (e.g. deregister as XEventListener
+ // for the cell)
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XPropertySetInfo > SAL_CALL OCellValueBinding::getPropertySetInfo( ) throw(RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+ return createPropertySetInfo( getInfoHelper() ) ;
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper& SAL_CALL OCellValueBinding::getInfoHelper()
+ {
+ return *OCellValueBinding_PABase::getArrayHelper();
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper* OCellValueBinding::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper(aProps);
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+ DBG_ASSERT( _nHandle == PROP_HANDLE_BOUND_CELL, "OCellValueBinding::getFastPropertyValue: invalid handle!" );
+ // we only have this one property ....
+ (void)_nHandle; // avoid warning in product version
+
+ _rValue.clear();
+ Reference< XCellAddressable > xCellAddress( m_xCell, UNO_QUERY );
+ if ( xCellAddress.is() )
+ _rValue <<= xCellAddress->getCellAddress( );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< Type > SAL_CALL OCellValueBinding::getSupportedValueTypes( ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+ checkDisposed( );
+ checkInitialized( );
+
+ sal_Int32 nCount = m_xCellText.is() ? 3 : m_xCell.is() ? 1 : 0;
+ if ( m_bListPos )
+ ++nCount;
+
+ Sequence< Type > aTypes( nCount );
+ if ( m_xCell.is() )
+ {
+ // an XCell can be used to set/get "double" values
+ aTypes[0] = ::getCppuType( static_cast< double* >( NULL ) );
+ if ( m_xCellText.is() )
+ {
+ // an XTextRange can be used to set/get "string" values
+ aTypes[1] = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
+ // and additionally, we use it to handle booleans
+ aTypes[2] = ::getCppuType( static_cast< sal_Bool* >( NULL ) );
+ }
+
+ // add sal_Int32 only if constructed as ListPositionCellBinding
+ if ( m_bListPos )
+ aTypes[nCount-1] = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
+ }
+
+ return aTypes;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SAL_CALL OCellValueBinding::supportsType( const Type& aType ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+ checkDisposed( );
+ checkInitialized( );
+
+ // look up in our sequence
+ Sequence< Type > aSupportedTypes( getSupportedValueTypes() );
+ const Type* pTypes = aSupportedTypes.getConstArray();
+ const Type* pTypesEnd = aSupportedTypes.getConstArray() + aSupportedTypes.getLength();
+ while ( pTypes != pTypesEnd )
+ if ( aType.equals( *pTypes++ ) )
+ return sal_True;
+
+ return sal_False;
+ }
+
+ //--------------------------------------------------------------------
+ Any SAL_CALL OCellValueBinding::getValue( const Type& aType ) throw (IncompatibleTypesException, RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+ checkDisposed( );
+ checkInitialized( );
+ checkValueType( aType );
+
+ Any aReturn;
+ switch ( aType.getTypeClass() )
+ {
+ case TypeClass_STRING:
+ DBG_ASSERT( m_xCellText.is(), "OCellValueBinding::getValue: don't have a text!" );
+ if ( m_xCellText.is() )
+ aReturn <<= m_xCellText->getString();
+ else
+ aReturn <<= ::rtl::OUString();
+ break;
+
+ case TypeClass_BOOLEAN:
+ DBG_ASSERT( m_xCell.is(), "OCellValueBinding::getValue: don't have a double value supplier!" );
+ if ( m_xCell.is() )
+ {
+ // check if the cell has a numeric value (this might go into a helper function):
+
+ sal_Bool bHasValue = sal_False;
+ CellContentType eCellType = m_xCell->getType();
+ if ( eCellType == CellContentType_VALUE )
+ bHasValue = sal_True;
+ else if ( eCellType == CellContentType_FORMULA )
+ {
+ // check if the formula result is a value
+ if ( m_xCell->getError() == 0 )
+ {
+ Reference<XPropertySet> xProp( m_xCell, UNO_QUERY );
+ if ( xProp.is() )
+ {
+ CellContentType eResultType;
+ if ( (xProp->getPropertyValue(::rtl::OUString::createFromAscii( "FormulaResultType" ) ) >>= eResultType) && eResultType == CellContentType_VALUE )
+ bHasValue = sal_True;
+ }
+ }
+ }
+
+ if ( bHasValue )
+ {
+ // 0 is "unchecked", any other value is "checked", regardless of number format
+ double nCellValue = m_xCell->getValue();
+ sal_Bool bBoolValue = ( nCellValue != 0.0 );
+ aReturn <<= bBoolValue;
+ }
+ // empty cells, text cells and text or error formula results: leave return value empty
+ }
+ break;
+
+ case TypeClass_DOUBLE:
+ DBG_ASSERT( m_xCell.is(), "OCellValueBinding::getValue: don't have a double value supplier!" );
+ if ( m_xCell.is() )
+ aReturn <<= m_xCell->getValue();
+ else
+ aReturn <<= (double)0;
+ break;
+
+ case TypeClass_LONG:
+ DBG_ASSERT( m_xCell.is(), "OCellValueBinding::getValue: don't have a double value supplier!" );
+ if ( m_xCell.is() )
+ {
+ // The list position value in the cell is 1-based.
+ // We subtract 1 from any cell value (no special handling for 0 or negative values).
+
+ sal_Int32 nValue = (sal_Int32) rtl::math::approxFloor( m_xCell->getValue() );
+ --nValue;
+
+ aReturn <<= nValue;
+ }
+ else
+ aReturn <<= (sal_Int32)0;
+ break;
+
+ default:
+ DBG_ERROR( "OCellValueBinding::getValue: unreachable code!" );
+ // a type other than double and string should never have survived the checkValueType
+ // above
+ }
+ return aReturn;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::setValue( const Any& aValue ) throw (IncompatibleTypesException, NoSupportException, RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+ checkDisposed( );
+ checkInitialized( );
+ if ( aValue.hasValue() )
+ checkValueType( aValue.getValueType() );
+
+ switch ( aValue.getValueType().getTypeClass() )
+ {
+ case TypeClass_STRING:
+ {
+ DBG_ASSERT( m_xCellText.is(), "OCellValueBinding::setValue: don't have a text!" );
+
+ ::rtl::OUString sText;
+ aValue >>= sText;
+ if ( m_xCellText.is() )
+ m_xCellText->setString( sText );
+ }
+ break;
+
+ case TypeClass_BOOLEAN:
+ {
+ DBG_ASSERT( m_xCell.is(), "OCellValueBinding::setValue: don't have a double value supplier!" );
+
+ // boolean is stored as values 0 or 1
+ // TODO: set the number format to boolean if no format is set?
+
+ sal_Bool bValue( sal_False );
+ aValue >>= bValue;
+ double nCellValue = bValue ? 1.0 : 0.0;
+
+ if ( m_xCell.is() )
+ m_xCell->setValue( nCellValue );
+
+ setBooleanFormat();
+ }
+ break;
+
+ case TypeClass_DOUBLE:
+ {
+ DBG_ASSERT( m_xCell.is(), "OCellValueBinding::setValue: don't have a double value supplier!" );
+
+ double nValue = 0;
+ aValue >>= nValue;
+ if ( m_xCell.is() )
+ m_xCell->setValue( nValue );
+ }
+ break;
+
+ case TypeClass_LONG:
+ {
+ DBG_ASSERT( m_xCell.is(), "OCellValueBinding::setValue: don't have a double value supplier!" );
+
+ sal_Int32 nValue = 0;
+ aValue >>= nValue; // list index from control layer (0-based)
+ ++nValue; // the list position value in the cell is 1-based
+ if ( m_xCell.is() )
+ m_xCell->setValue( nValue );
+ }
+ break;
+
+ case TypeClass_VOID:
+ {
+ // #N/A error value can only be set using XCellRangeData
+
+ Reference<XCellRangeData> xData( m_xCell, UNO_QUERY );
+ DBG_ASSERT( xData.is(), "OCellValueBinding::setValue: don't have XCellRangeData!" );
+ if ( xData.is() )
+ {
+ Sequence<Any> aInner(1); // one empty element
+ Sequence< Sequence<Any> > aOuter( &aInner, 1 ); // one row
+ xData->setDataArray( aOuter );
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR( "OCellValueBinding::setValue: unreachable code!" );
+ // a type other than double and string should never have survived the checkValueType
+ // above
+ }
+ }
+ //--------------------------------------------------------------------
+ void OCellValueBinding::setBooleanFormat()
+ {
+ // set boolean number format if not already set
+
+ ::rtl::OUString sPropName( ::rtl::OUString::createFromAscii( "NumberFormat" ) );
+ Reference<XPropertySet> xCellProp( m_xCell, UNO_QUERY );
+ Reference<XNumberFormatsSupplier> xSupplier( m_xDocument, UNO_QUERY );
+ if ( xSupplier.is() && xCellProp.is() )
+ {
+ Reference<XNumberFormats> xFormats(xSupplier->getNumberFormats());
+ Reference<XNumberFormatTypes> xTypes( xFormats, UNO_QUERY );
+ if ( xTypes.is() )
+ {
+ Locale aLocale;
+ sal_Bool bWasBoolean = sal_False;
+
+ sal_Int32 nOldIndex = ::comphelper::getINT32( xCellProp->getPropertyValue( sPropName ) );
+ Reference<XPropertySet> xOldFormat;
+ try
+ {
+ xOldFormat.set(xFormats->getByKey( nOldIndex ));
+ }
+ catch ( Exception& )
+ {
+ // non-existing format - can happen, use defaults
+ }
+ if ( xOldFormat.is() )
+ {
+ // use the locale of the existing format
+ xOldFormat->getPropertyValue( ::rtl::OUString::createFromAscii( "Locale" ) ) >>= aLocale;
+
+ sal_Int16 nOldType = ::comphelper::getINT16(
+ xOldFormat->getPropertyValue( ::rtl::OUString::createFromAscii( "Type" ) ) );
+ if ( nOldType & NumberFormat::LOGICAL )
+ bWasBoolean = sal_True;
+ }
+
+ if ( !bWasBoolean )
+ {
+ sal_Int32 nNewIndex = xTypes->getStandardFormat( NumberFormat::LOGICAL, aLocale );
+ xCellProp->setPropertyValue( sPropName, makeAny( nNewIndex ) );
+ }
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void OCellValueBinding::checkDisposed( ) const SAL_THROW( ( DisposedException ) )
+ {
+ if ( OCellValueBinding_Base::rBHelper.bInDispose || OCellValueBinding_Base::rBHelper.bDisposed )
+ throw DisposedException();
+ // TODO: is it worth having an error message here?
+ }
+
+ //--------------------------------------------------------------------
+ void OCellValueBinding::checkInitialized() SAL_THROW( ( RuntimeException ) )
+ {
+ if ( !m_bInitialized )
+ throw RuntimeException();
+ // TODO: error message
+ }
+
+ //--------------------------------------------------------------------
+ void OCellValueBinding::checkValueType( const Type& _rType ) const SAL_THROW( ( IncompatibleTypesException ) )
+ {
+ OCellValueBinding* pNonConstThis = const_cast< OCellValueBinding* >( this );
+ if ( !pNonConstThis->supportsType( _rType ) )
+ {
+ ::rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "The given type (" ) );
+ sMessage += _rType.getTypeName();
+ sMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ") is not supported by this binding." ) );
+ // TODO: localize this error message
+
+ throw IncompatibleTypesException( sMessage, *pNonConstThis );
+ // TODO: alternatively use a type converter service for this?
+ }
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OCellValueBinding::getImplementationName( ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sheet.OCellValueBinding" ) );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SAL_CALL OCellValueBinding::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+
+ Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() );
+ const ::rtl::OUString* pLookup = aSupportedServices.getConstArray();
+ const ::rtl::OUString* pLookupEnd = aSupportedServices.getConstArray() + aSupportedServices.getLength();
+ while ( pLookup != pLookupEnd )
+ if ( *pLookup++ == _rServiceName )
+ return sal_True;
+
+ return sal_False;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OCellValueBinding::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+
+ Sequence< ::rtl::OUString > aServices( m_bListPos ? 3 : 2 );
+ aServices[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.table.CellValueBinding" ) );
+ aServices[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.binding.ValueBinding" ) );
+ if ( m_bListPos )
+ aServices[ 2 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.table.ListPositionCellBinding" ) );
+ return aServices;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
+ {
+ if ( _rxListener.is() )
+ m_aModifyListeners.addInterface( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
+ {
+ if ( _rxListener.is() )
+ m_aModifyListeners.removeInterface( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void OCellValueBinding::notifyModified()
+ {
+ EventObject aEvent;
+ aEvent.Source.set(*this);
+
+ ::cppu::OInterfaceIteratorHelper aIter( m_aModifyListeners );
+ while ( aIter.hasMoreElements() )
+ {
+ try
+ {
+ static_cast< XModifyListener* >( aIter.next() )->modified( aEvent );
+ }
+ catch( const RuntimeException& )
+ {
+ // silent this
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "OCellValueBinding::notifyModified: caught a (non-runtime) exception!" );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::modified( const EventObject& /* aEvent */ ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+
+ notifyModified();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::disposing( const EventObject& aEvent ) throw (RuntimeException)
+ {
+ DBG_CHKTHIS( OCellValueBinding, checkConsistency_static );
+
+ Reference<XInterface> xCellInt( m_xCell, UNO_QUERY );
+ if ( xCellInt == aEvent.Source )
+ {
+ // release references to cell object
+ m_xCell.clear();
+ m_xCellText.clear();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OCellValueBinding::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
+ {
+ if ( m_bInitialized )
+ throw Exception();
+ // TODO: error message
+
+ // get the cell address
+ CellAddress aAddress;
+ sal_Bool bFoundAddress = sal_False;
+
+ const Any* pLoop = _rArguments.getConstArray();
+ const Any* pLoopEnd = _rArguments.getConstArray() + _rArguments.getLength();
+ for ( ; ( pLoop != pLoopEnd ) && !bFoundAddress; ++pLoop )
+ {
+ NamedValue aValue;
+ if ( *pLoop >>= aValue )
+ {
+ if ( aValue.Name.equalsAscii( "BoundCell" ) )
+ {
+ if ( aValue.Value >>= aAddress )
+ bFoundAddress = sal_True;
+ }
+ }
+ }
+
+ if ( !bFoundAddress )
+ // TODO: error message
+ throw Exception();
+
+ // get the cell object
+ try
+ {
+ // first the sheets collection
+ Reference< XIndexAccess > xSheets;
+ if ( m_xDocument.is() )
+ xSheets.set(xSheets.query( m_xDocument->getSheets( ) ));
+ DBG_ASSERT( xSheets.is(), "OCellValueBinding::initialize: could not retrieve the sheets!" );
+
+ if ( xSheets.is() )
+ {
+ // the concrete sheet
+ Reference< XCellRange > xSheet(xSheets->getByIndex( aAddress.Sheet ), UNO_QUERY);
+ DBG_ASSERT( xSheet.is(), "OCellValueBinding::initialize: NULL sheet, but no exception!" );
+
+ // the concrete cell
+ if ( xSheet.is() )
+ {
+ m_xCell.set(xSheet->getCellByPosition( aAddress.Column, aAddress.Row ));
+ Reference< XCellAddressable > xAddressAccess( m_xCell, UNO_QUERY );
+ DBG_ASSERT( xAddressAccess.is(), "OCellValueBinding::initialize: either NULL cell, or cell without address access!" );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "OCellValueBinding::initialize: caught an exception while retrieving the cell object!" );
+ }
+
+ if ( !m_xCell.is() )
+ throw Exception();
+ // TODO error message
+
+ m_xCellText.set(m_xCellText.query( m_xCell ));
+
+ Reference<XModifyBroadcaster> xBroadcaster( m_xCell, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ {
+ xBroadcaster->addModifyListener( this );
+ }
+
+ // TODO: add as XEventListener to the cell, so we get notified when it dies,
+ // and can dispose ourself then
+
+ // TODO: somehow add as listener so we get notified when the address of the cell changes
+ // We need to forward this as change in our BoundCell property to our property change listeners
+
+ // TODO: be an XModifyBroadcaster, so that changes in our cell can be notified
+ // to the BindableValue which is/will be bound to this instance.
+
+ m_bInitialized = sal_True;
+ // TODO: place your code here
+ }
+
+
+//.........................................................................
+} // namespace calc
+//.........................................................................
diff --git a/sc/source/ui/unoobj/cellvaluebinding.hxx b/sc/source/ui/unoobj/cellvaluebinding.hxx
new file mode 100644
index 000000000000..c9537d546f7b
--- /dev/null
+++ b/sc/source/ui/unoobj/cellvaluebinding.hxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_CELLVALUEBINDING_HXX
+#define SC_CELLVALUEBINDING_HXX
+
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <cppuhelper/compbase5.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+
+//.........................................................................
+namespace calc
+{
+//.........................................................................
+
+ //=====================================================================
+ //= OCellValueBinding
+ //=====================================================================
+ class OCellValueBinding;
+ // the base for our interfaces
+ typedef ::cppu::WeakAggComponentImplHelper5 < ::com::sun::star::form::binding::XValueBinding
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::util::XModifyBroadcaster
+ , ::com::sun::star::util::XModifyListener
+ , ::com::sun::star::lang::XInitialization
+ > OCellValueBinding_Base;
+ // the base for the property handling
+ typedef ::comphelper::OPropertyContainer OCellValueBinding_PBase;
+ // the second base for property handling
+ typedef ::comphelper::OPropertyArrayUsageHelper< OCellValueBinding >
+ OCellValueBinding_PABase;
+
+ class OCellValueBinding :public ::comphelper::OBaseMutex
+ ,public OCellValueBinding_Base // order matters! before OCellValueBinding_PBase, so rBHelper gets initialized
+ ,public OCellValueBinding_PBase
+ ,public OCellValueBinding_PABase
+ {
+ private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
+ m_xDocument; /// the document where our cell lives
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
+ m_xCell; /// the cell we're bound to, for double value access
+ ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >
+ m_xCellText; /// the cell we're bound to, for text access
+ ::cppu::OInterfaceContainerHelper
+ m_aModifyListeners; /// our modify listeners
+ sal_Bool m_bInitialized; /// has XInitialization::initialize been called?
+ sal_Bool m_bListPos; /// constructed as ListPositionCellBinding?
+
+ public:
+ OCellValueBinding(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& _rxDocument,
+ sal_Bool _bListPos
+ );
+
+ using OCellValueBinding_PBase::getFastPropertyValue;
+
+ protected:
+ ~OCellValueBinding( );
+
+ protected:
+ // XInterface
+ DECLARE_XINTERFACE()
+
+ // XTypeProvider
+ DECLARE_XTYPEPROVIDER()
+
+ // XValueBinding
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getSupportedValueTypes( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsType( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper/XComponent
+ virtual void SAL_CALL disposing();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const;
+
+ // ::comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XModifyListener
+ virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ private:
+ void checkDisposed( ) const
+ SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
+ void checkValueType( const ::com::sun::star::uno::Type& _rType ) const
+ SAL_THROW( ( ::com::sun::star::form::binding::IncompatibleTypesException ) );
+ void checkInitialized()
+ SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) );
+
+ /** notifies our modify listeners
+ @precond
+ our mutex is <em>not</em> locked
+ */
+ void notifyModified();
+
+ void setBooleanFormat();
+
+ private:
+ OCellValueBinding(); // never implemented
+ OCellValueBinding( const OCellValueBinding& ); // never implemented
+ OCellValueBinding& operator=( const OCellValueBinding& ); // never implemented
+
+#ifdef DBG_UTIL
+ private:
+ static const char* checkConsistency_static( const void* _pThis );
+ const char* checkConsistency( ) const;
+#endif
+ };
+
+//.........................................................................
+} // namespace calc
+//.........................................................................
+
+#endif // SC_CELLVALUEBINDING_HXX
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
new file mode 100644
index 000000000000..8a8081e412d3
--- /dev/null
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -0,0 +1,3914 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "chart2uno.hxx"
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "unoguard.hxx"
+#include "cell.hxx"
+#include "chartpos.hxx"
+#include "unonames.hxx"
+#include "globstr.hrc"
+#include "convuno.hxx"
+#include "rangeutl.hxx"
+#include "hints.hxx"
+#include "unoreflist.hxx"
+#include "compiler.hxx"
+#include "reftokenhelper.hxx"
+#include "chartlis.hxx"
+
+#include <sfx2/objsh.hxx>
+#include <tools/table.hxx>
+
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <comphelper/extract.hxx>
+
+#include <vector>
+#include <list>
+#include <rtl/math.hxx>
+
+SC_SIMPLE_SERVICE_INFO( ScChart2DataProvider, "ScChart2DataProvider",
+ "com.sun.star.chart2.data.DataProvider")
+SC_SIMPLE_SERVICE_INFO( ScChart2DataSource, "ScChart2DataSource",
+ "com.sun.star.chart2.data.DataSource")
+SC_SIMPLE_SERVICE_INFO( ScChart2LabeledDataSequence, "ScChart2LabeledDataSequence",
+ "com.sun.star.chart2.data.LabeledDataSequence")
+SC_SIMPLE_SERVICE_INFO( ScChart2DataSequence, "ScChart2DataSequence",
+ "com.sun.star.chart2.data.DataSequence")
+#if USE_CHART2_EMPTYDATASEQUENCE
+SC_SIMPLE_SERVICE_INFO( ScChart2EmptyDataSequence, "ScChart2EmptyDataSequence",
+ "com.sun.star.chart2.data.DataSequence")
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::formula;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::std::auto_ptr;
+using ::std::vector;
+using ::std::list;
+using ::std::distance;
+using ::std::unary_function;
+using ::std::hash_set;
+using ::boost::shared_ptr;
+
+namespace
+{
+const SfxItemPropertyMapEntry* lcl_GetDataProviderPropertyMap()
+{
+ static SfxItemPropertyMapEntry aDataProviderPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_INCLUDEHIDDENCELLS), 0, &getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDataProviderPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* lcl_GetDataSequencePropertyMap()
+{
+ static SfxItemPropertyMapEntry aDataSequencePropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_HIDDENVALUES), 0, &getCppuType((uno::Sequence<sal_Int32>*)0 ), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROLE), 0, &getCppuType((::com::sun::star::chart2::data::DataSequenceRole*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_INCLUDEHIDDENCELLS), 0, &getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDataSequencePropertyMap_Impl;
+}
+
+template< typename T >
+::com::sun::star::uno::Sequence< T > lcl_VectorToSequence(
+ const ::std::vector< T > & rCont )
+{
+ ::com::sun::star::uno::Sequence< T > aResult( rCont.size());
+ ::std::copy( rCont.begin(), rCont.end(), aResult.getArray());
+ return aResult;
+}
+
+struct lcl_appendTableNumber : public ::std::unary_function< SCTAB, void >
+{
+ lcl_appendTableNumber( ::rtl::OUStringBuffer & rBuffer ) :
+ m_rBuffer( rBuffer )
+ {}
+ void operator() ( SCTAB nTab )
+ {
+ // there is no append with SCTAB or sal_Int16
+ m_rBuffer.append( static_cast< sal_Int32 >( nTab ));
+ m_rBuffer.append( sal_Unicode( ' ' ));
+ }
+private:
+ ::rtl::OUStringBuffer & m_rBuffer;
+};
+
+::rtl::OUString lcl_createTableNumberList( const ::std::list< SCTAB > & rTableList )
+{
+ ::rtl::OUStringBuffer aBuffer;
+ ::std::for_each( rTableList.begin(), rTableList.end(), lcl_appendTableNumber( aBuffer ));
+ // remove last trailing ' '
+ if( aBuffer.getLength() > 0 )
+ aBuffer.setLength( aBuffer.getLength() - 1 );
+ return aBuffer.makeStringAndClear();
+}
+
+uno::Reference< frame::XModel > lcl_GetXModel( ScDocument * pDoc )
+{
+ uno::Reference< frame::XModel > xModel;
+ SfxObjectShell * pObjSh( pDoc ? pDoc->GetDocumentShell() : 0 );
+ if( pObjSh )
+ xModel.set( pObjSh->GetModel());
+ return xModel;
+}
+
+uno::Reference< sheet::XSpreadsheetDocument > lcl_GetSpreadSheetDocument( ScDocument * pDoc )
+{
+ return uno::Reference< sheet::XSpreadsheetDocument >( lcl_GetXModel( pDoc ), uno::UNO_QUERY );
+}
+
+// ============================================================================
+
+namespace {
+
+struct DeleteInstance : public unary_function<FormulaToken*, void>
+{
+ void operator() (FormulaToken* p) const
+ {
+ delete p;
+ }
+};
+
+}
+
+struct TokenTable
+{
+ SCROW mnRowCount;
+ SCCOL mnColCount;
+ vector<FormulaToken*> maTokens;
+
+ void init( SCCOL nColCount, SCROW nRowCount )
+ {
+ mnColCount = nColCount;
+ mnRowCount = nRowCount;
+ maTokens.reserve(mnColCount*mnRowCount);
+ }
+ void clear()
+ {
+ for_each(maTokens.begin(), maTokens.end(), DeleteInstance());
+ }
+
+ void push_back( FormulaToken* pToken )
+ {
+ maTokens.push_back( pToken );
+ DBG_ASSERT( maTokens.size()<= static_cast<sal_uInt32>( mnColCount*mnRowCount ), "too much tokens" );
+ }
+
+ sal_uInt32 getIndex(SCCOL nCol, SCROW nRow) const
+ {
+ DBG_ASSERT( nCol<mnColCount, "wrong column index" );
+ DBG_ASSERT( nRow<mnRowCount, "wrong row index" );
+ sal_uInt32 nRet = static_cast<sal_uInt32>(nCol*mnRowCount + nRow);
+ DBG_ASSERT( maTokens.size()>= static_cast<sal_uInt32>( mnColCount*mnRowCount ), "too few tokens" );
+ return nRet;
+ }
+
+ vector<ScSharedTokenRef>* getColRanges(SCCOL nCol) const;
+ vector<ScSharedTokenRef>* getRowRanges(SCROW nRow) const;
+ vector<ScSharedTokenRef>* getAllRanges() const;
+};
+
+vector<ScSharedTokenRef>* TokenTable::getColRanges(SCCOL nCol) const
+{
+ if (nCol >= mnColCount)
+ return NULL;
+ if( mnRowCount<=0 )
+ return NULL;
+
+ auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>);
+ sal_uInt32 nLast = getIndex(nCol, mnRowCount-1);
+ for (sal_uInt32 i = getIndex(nCol, 0); i <= nLast; ++i)
+ {
+ FormulaToken* p = maTokens[i];
+ if (!p)
+ continue;
+
+ ScSharedTokenRef pCopy(static_cast<ScToken*>(p->Clone()));
+ ScRefTokenHelper::join(*pTokens, pCopy);
+ }
+ return pTokens.release();
+}
+
+vector<ScSharedTokenRef>* TokenTable::getRowRanges(SCROW nRow) const
+{
+ if (nRow >= mnRowCount)
+ return NULL;
+ if( mnColCount<=0 )
+ return NULL;
+
+ auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>);
+ sal_uInt32 nLast = getIndex(mnColCount-1, nRow);
+ for (sal_uInt32 i = getIndex(0, nRow); i <= nLast; i += mnRowCount)
+ {
+ FormulaToken* p = maTokens[i];
+ if (!p)
+ continue;
+
+ ScSharedTokenRef p2(static_cast<ScToken*>(p->Clone()));
+ ScRefTokenHelper::join(*pTokens, p2);
+ }
+ return pTokens.release();
+}
+
+vector<ScSharedTokenRef>* TokenTable::getAllRanges() const
+{
+ auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>);
+ sal_uInt32 nStop = mnColCount*mnRowCount;
+ for (sal_uInt32 i = 0; i < nStop; i++)
+ {
+ FormulaToken* p = maTokens[i];
+ if (!p)
+ continue;
+
+ ScSharedTokenRef p2(static_cast<ScToken*>(p->Clone()));
+ ScRefTokenHelper::join(*pTokens, p2);
+ }
+ return pTokens.release();
+}
+
+// ============================================================================
+
+class Chart2PositionMap
+{
+public:
+ Chart2PositionMap(SCCOL nColCount, SCROW nRowCount,
+ bool bFillRowHeader, bool bFillColumnHeader, Table& rCols,
+ ScDocument* pDoc );
+ ~Chart2PositionMap();
+
+ SCCOL getDataColCount() const { return mnDataColCount; }
+ SCROW getDataRowCount() const { return mnDataRowCount; }
+
+ vector<ScSharedTokenRef>* getLeftUpperCornerRanges() const;
+ vector<ScSharedTokenRef>* getAllColHeaderRanges() const;
+ vector<ScSharedTokenRef>* getAllRowHeaderRanges() const;
+
+ vector<ScSharedTokenRef>* getColHeaderRanges(SCCOL nChartCol) const;
+ vector<ScSharedTokenRef>* getRowHeaderRanges(SCROW nChartRow) const;
+
+ vector<ScSharedTokenRef>* getDataColRanges(SCCOL nCol) const;
+ vector<ScSharedTokenRef>* getDataRowRanges(SCROW nRow) const;
+
+private:
+ SCCOL mnDataColCount;
+ SCROW mnDataRowCount;
+
+ TokenTable maLeftUpperCorner; //nHeaderColCount*nHeaderRowCount
+ TokenTable maColHeaders; //mnDataColCount*nHeaderRowCount
+ TokenTable maRowHeaders; //nHeaderColCount*mnDataRowCount
+ TokenTable maData;//mnDataColCount*mnDataRowCount
+};
+
+Chart2PositionMap::Chart2PositionMap(SCCOL nAllColCount, SCROW nAllRowCount,
+ bool bFillRowHeader, bool bFillColumnHeader, Table& rCols, ScDocument* pDoc)
+{
+ // if bFillRowHeader is true, at least the first column serves as a row header.
+ // If more than one column is pure text all the first pure text columns are used as header.
+ // Likewise, if bFillColumnHeader is true, at least the first row serves as a column header.
+ // If more than one row is pure text all the first pure text rows are used as header.
+
+ SCROW nHeaderRowCount = (bFillColumnHeader && nAllColCount && nAllRowCount) ? 1 : 0;
+ SCCOL nHeaderColCount = (bFillRowHeader && nAllColCount && nAllRowCount) ? 1 : 0;
+
+ if( nHeaderColCount || nHeaderRowCount )
+ {
+ const SCCOL nInitialHeaderColCount = nHeaderColCount;
+ //check whether there is more than one text column or row that should be added to the headers
+ SCROW nSmallestValueRowIndex = nAllRowCount;
+ bool bFoundValues = false;
+ bool bFoundAnything = false;
+ Table* pCol = static_cast<Table*>(rCols.First());
+ for (SCCOL nCol = 0; !bFoundValues && nCol < nAllColCount; ++nCol)
+ {
+ if (pCol && nCol>=nHeaderColCount)
+ {
+ ScToken* pToken = static_cast<ScToken*>(pCol->First());
+ for (SCROW nRow = 0; !bFoundValues && nRow < nSmallestValueRowIndex; ++nRow)
+ {
+ if (pToken && nRow>=nHeaderRowCount)
+ {
+ ScRange aRange;
+ bool bExternal = false;
+ StackVar eType = pToken->GetType();
+ if( eType==svExternal || eType==svExternalSingleRef || eType==svExternalDoubleRef || eType==svExternalName )
+ bExternal = true;//lllll todo correct?
+ ScSharedTokenRef pSharedToken(static_cast<ScToken*>(pToken->Clone()));
+ ScRefTokenHelper::getRangeFromToken(aRange, pSharedToken, bExternal );
+ SCCOL nCol1=0, nCol2=0;
+ SCROW nRow1=0, nRow2=0;
+ SCTAB nTab1=0, nTab2=0;
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ if (pDoc && pDoc->HasValueData( nCol1, nRow1, nTab1 ))
+ {
+ bFoundValues = bFoundAnything = true;
+ nSmallestValueRowIndex = std::min( nSmallestValueRowIndex, nRow );
+ }
+ if( !bFoundAnything )
+ {
+ if (pDoc && pDoc->HasData( nCol1, nRow1, nTab1 ) )
+ bFoundAnything = true;
+ }
+ }
+ pToken = static_cast<ScToken*>(pCol->Next());
+ }
+ if(!bFoundValues && nHeaderColCount>0)
+ nHeaderColCount++;
+ }
+ pCol = static_cast<Table*>(rCols.Next());
+ }
+ if( bFoundAnything )
+ {
+ if(nHeaderRowCount>0)
+ {
+ if( bFoundValues )
+ nHeaderRowCount = nSmallestValueRowIndex;
+ else if( nAllRowCount>1 )
+ nHeaderRowCount = nAllRowCount-1;
+ }
+ }
+ else //if the cells are completely empty, just use single header rows and columns
+ nHeaderColCount = nInitialHeaderColCount;
+ }
+
+ mnDataColCount = nAllColCount - nHeaderColCount;
+ mnDataRowCount = nAllRowCount - nHeaderRowCount;
+
+ maLeftUpperCorner.init(nHeaderColCount,nHeaderRowCount);
+ maColHeaders.init(mnDataColCount,nHeaderRowCount);
+ maRowHeaders.init(nHeaderColCount,mnDataRowCount);
+ maData.init(mnDataColCount,mnDataRowCount);
+
+ Table* pCol = static_cast<Table*>(rCols.First());
+ FormulaToken* pToken = static_cast<FormulaToken*>(pCol->First());
+ for (SCCOL nCol = 0; nCol < nAllColCount; ++nCol)
+ {
+ if (pCol)
+ {
+ pToken = static_cast<FormulaToken*>(pCol->First());
+ for (SCROW nRow = 0; nRow < nAllRowCount; ++nRow)
+ {
+ if( nCol < nHeaderColCount )
+ {
+ if( nRow < nHeaderRowCount )
+ maLeftUpperCorner.push_back(pToken);
+ else
+ maRowHeaders.push_back(pToken);
+ }
+ else if( nRow < nHeaderRowCount )
+ maColHeaders.push_back(pToken);
+ else
+ maData.push_back(pToken);
+
+ pToken = static_cast<FormulaToken*>(pCol->Next());
+ }
+ }
+ pCol = static_cast<Table*>(rCols.Next());
+ }
+}
+
+Chart2PositionMap::~Chart2PositionMap()
+{
+ maLeftUpperCorner.clear();
+ maColHeaders.clear();
+ maRowHeaders.clear();
+ maData.clear();
+}
+
+vector<ScSharedTokenRef>* Chart2PositionMap::getLeftUpperCornerRanges() const
+{
+ return maLeftUpperCorner.getAllRanges();
+}
+vector<ScSharedTokenRef>* Chart2PositionMap::getAllColHeaderRanges() const
+{
+ return maColHeaders.getAllRanges();
+}
+vector<ScSharedTokenRef>* Chart2PositionMap::getAllRowHeaderRanges() const
+{
+ return maRowHeaders.getAllRanges();
+}
+vector<ScSharedTokenRef>* Chart2PositionMap::getColHeaderRanges(SCCOL nCol) const
+{
+ return maColHeaders.getColRanges( nCol);
+}
+vector<ScSharedTokenRef>* Chart2PositionMap::getRowHeaderRanges(SCROW nRow) const
+{
+ return maRowHeaders.getRowRanges( nRow);
+}
+
+vector<ScSharedTokenRef>* Chart2PositionMap::getDataColRanges(SCCOL nCol) const
+{
+ return maData.getColRanges( nCol);
+}
+
+vector<ScSharedTokenRef>* Chart2PositionMap::getDataRowRanges(SCROW nRow) const
+{
+ return maData.getRowRanges( nRow);
+}
+
+// ----------------------------------------------------------------------------
+
+/**
+ * Designed to be a drop-in replacement for ScChartPositioner, in order to
+ * handle external references.
+ */
+class Chart2Positioner
+{
+ enum GlueType
+ {
+ GLUETYPE_NA,
+ GLUETYPE_NONE,
+ GLUETYPE_COLS,
+ GLUETYPE_ROWS,
+ GLUETYPE_BOTH
+ };
+
+public:
+ Chart2Positioner(ScDocument* pDoc, const vector<ScSharedTokenRef>& rRefTokens) :
+ mpRefTokens(new vector<ScSharedTokenRef>(rRefTokens)),
+ mpPositionMap(NULL),
+ meGlue(GLUETYPE_NA),
+ mpDoc(pDoc),
+ mbColHeaders(false),
+ mbRowHeaders(false),
+ mbDummyUpperLeft(false)
+ {
+ }
+
+ ~Chart2Positioner()
+ {
+ }
+
+ void setHeaders(bool bColHeaders, bool bRowHeaders)
+ {
+ mbColHeaders = bColHeaders;
+ mbRowHeaders = bRowHeaders;
+ }
+
+ bool hasColHeaders() const { return mbColHeaders; }
+ bool hasRowHeaders() const { return mbRowHeaders; }
+
+ Chart2PositionMap* getPositionMap()
+ {
+ createPositionMap();
+ return mpPositionMap.get();
+ }
+
+private:
+ Chart2Positioner(); // disabled
+
+ void invalidateGlue();
+ void glueState();
+ void createPositionMap();
+
+private:
+ shared_ptr< vector<ScSharedTokenRef> > mpRefTokens;
+ auto_ptr<Chart2PositionMap> mpPositionMap;
+ GlueType meGlue;
+ SCCOL mnStartCol;
+ SCROW mnStartRow;
+ ScDocument* mpDoc;
+ bool mbColHeaders:1;
+ bool mbRowHeaders:1;
+ bool mbDummyUpperLeft:1;
+};
+
+void Chart2Positioner::invalidateGlue()
+{
+ meGlue = GLUETYPE_NA;
+ mpPositionMap.reset(NULL);
+}
+
+void Chart2Positioner::glueState()
+{
+ if (meGlue != GLUETYPE_NA)
+ return;
+
+ mbDummyUpperLeft = false;
+ if (mpRefTokens->size() <= 1)
+ {
+ const ScSharedTokenRef& p = mpRefTokens->front();
+ ScComplexRefData aData;
+ if (ScRefTokenHelper::getDoubleRefDataFromToken(aData, p))
+ {
+ if (aData.Ref1.nTab == aData.Ref2.nTab)
+ meGlue = GLUETYPE_NONE;
+ else
+ meGlue = GLUETYPE_COLS;
+ mnStartCol = aData.Ref1.nCol;
+ mnStartRow = aData.Ref1.nRow;
+ }
+ else
+ {
+ invalidateGlue();
+ mnStartCol = 0;
+ mnStartRow = 0;
+ }
+ return;
+ }
+
+ ScComplexRefData aData;
+ ScRefTokenHelper::getDoubleRefDataFromToken(aData, mpRefTokens->front());
+ mnStartCol = aData.Ref1.nCol;
+ mnStartRow = aData.Ref1.nRow;
+
+ SCCOL nMaxCols = 0, nEndCol = 0;
+ SCROW nMaxRows = 0, nEndRow = 0;
+ for (vector<ScSharedTokenRef>::const_iterator itr = mpRefTokens->begin(), itrEnd = mpRefTokens->end()
+ ; itr != itrEnd; ++itr)
+ {
+ ScRefTokenHelper::getDoubleRefDataFromToken(aData, *itr);
+ SCCOLROW n1 = aData.Ref1.nCol;
+ SCCOLROW n2 = aData.Ref2.nCol;
+ if (n1 > MAXCOL)
+ n1 = MAXCOL;
+ if (n2 > MAXCOL)
+ n2 = MAXCOL;
+ SCCOLROW nTmp = n2 - n1 + 1;
+ if (n1 < mnStartCol)
+ mnStartCol = static_cast<SCCOL>(n1);
+ if (n2 > nEndCol)
+ nEndCol = static_cast<SCCOL>(n2);
+ if (nTmp > nMaxCols)
+ nMaxCols = static_cast<SCCOL>(nTmp);
+
+ n1 = aData.Ref1.nRow;
+ n2 = aData.Ref2.nRow;
+ if (n1 > MAXROW)
+ n1 = MAXROW;
+ if (n2 > MAXROW)
+ n2 = MAXROW;
+ nTmp = n2 - n1 + 1;
+
+ if (n1 < mnStartRow)
+ mnStartRow = static_cast<SCROW>(n1);
+ if (n2 > nEndRow)
+ nEndRow = static_cast<SCROW>(n2);
+ if (nTmp > nMaxRows)
+ nMaxRows = static_cast<SCROW>(nTmp);
+ }
+
+ // total column size ?
+ SCCOL nC = nEndCol - mnStartCol + 1;
+ if (nC == 1)
+ {
+ meGlue = GLUETYPE_ROWS;
+ return;
+ }
+ // total row size ?
+ SCROW nR = nEndRow - mnStartRow + 1;
+ if (nR == 1)
+ {
+ meGlue = GLUETYPE_COLS;
+ return;
+ }
+ // #i103540# prevent invalid vector size
+ if ((nC <= 0) || (nR <= 0))
+ {
+ invalidateGlue();
+ mnStartCol = 0;
+ mnStartRow = 0;
+ return;
+ }
+ sal_uInt32 nCR = static_cast<sal_uInt32>(nC*nR);
+
+ const sal_uInt8 nHole = 0;
+ const sal_uInt8 nOccu = 1;
+ const sal_uInt8 nFree = 2;
+ const sal_uInt8 nGlue = 3;
+
+ vector<sal_uInt8> aCellStates(nCR);
+ for (vector<ScSharedTokenRef>::const_iterator itr = mpRefTokens->begin(), itrEnd = mpRefTokens->end();
+ itr != itrEnd; ++itr)
+ {
+ ScRefTokenHelper::getDoubleRefDataFromToken(aData, *itr);
+ SCCOL nCol1 = static_cast<SCCOL>(aData.Ref1.nCol) - mnStartCol;
+ SCCOL nCol2 = static_cast<SCCOL>(aData.Ref2.nCol) - mnStartCol;
+ SCROW nRow1 = static_cast<SCROW>(aData.Ref1.nRow) - mnStartRow;
+ SCROW nRow2 = static_cast<SCROW>(aData.Ref2.nRow) - mnStartRow;
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ {
+ size_t i = nCol*nR + nRow;
+ aCellStates[i] = nOccu;
+ }
+ }
+ bool bGlue = true;
+
+ size_t i = 0;
+ bool bGlueCols = false;
+ for (SCCOL nCol = 0; bGlue && nCol < nC; ++nCol)
+ {
+ for (SCROW nRow = 0; bGlue && nRow < nR; ++nRow)
+ {
+ i = nCol*nR + nRow;
+ if (aCellStates[i] == nOccu)
+ {
+ if (nRow > 0 && nRow > 0)
+ bGlue = false;
+ else
+ nRow = nR;
+ }
+ else
+ aCellStates[i] = nFree;
+ }
+ i = (nCol+1)*nR - 1; // index for the last cell in the column.
+ if (bGlue && (aCellStates[i] == nFree))
+ {
+ aCellStates[i] = nGlue;
+ bGlueCols = true;
+ }
+ }
+
+ bool bGlueRows = false;
+ for (SCROW nRow = 0; bGlue && nRow < nR; ++nRow)
+ {
+ i = nRow;
+ for (SCCOL nCol = 0; bGlue && nCol < nC; ++nCol, i += nR)
+ {
+ if (aCellStates[i] == nOccu)
+ {
+ if (nCol > 0 && nRow > 0)
+ bGlue = false;
+ else
+ nCol = nC;
+ }
+ else
+ aCellStates[i] = nFree;
+ }
+ i = (nC-1)*nR + nRow; // index for the row position in the last column.
+ if (bGlue && aCellStates[i] == nFree)
+ {
+ aCellStates[i] = nGlue;
+ bGlueRows = true;
+ }
+ }
+
+ i = 1;
+ for (sal_uInt32 n = 1; bGlue && n < nCR; ++n, ++i)
+ if (aCellStates[i] == nHole)
+ bGlue = false;
+
+ if (bGlue)
+ {
+ if (bGlueCols && bGlueRows)
+ meGlue = GLUETYPE_BOTH;
+ else if (bGlueRows)
+ meGlue = GLUETYPE_ROWS;
+ else
+ meGlue = GLUETYPE_COLS;
+ if (aCellStates.front() != nOccu)
+ mbDummyUpperLeft = true;
+ }
+ else
+ meGlue = GLUETYPE_NONE;
+}
+
+void Chart2Positioner::createPositionMap()
+{
+ if (meGlue == GLUETYPE_NA && mpPositionMap.get())
+ mpPositionMap.reset(NULL);
+
+ if (mpPositionMap.get())
+ return;
+
+ glueState();
+
+ bool bNoGlue = (meGlue == GLUETYPE_NONE);
+ auto_ptr<Table> pCols(new Table);
+ auto_ptr<FormulaToken> pNewAddress;
+ auto_ptr<Table> pNewRowTable(new Table);
+ Table* pCol = NULL;
+ SCROW nNoGlueRow = 0;
+ for (vector<ScSharedTokenRef>::const_iterator itr = mpRefTokens->begin(), itrEnd = mpRefTokens->end();
+ itr != itrEnd; ++itr)
+ {
+ const ScSharedTokenRef& pToken = *itr;
+
+ bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
+ sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
+ String aTabName = bExternal ? pToken->GetString() : String();
+
+ ScComplexRefData aData;
+ ScRefTokenHelper::getDoubleRefDataFromToken(aData, *itr);
+ const ScSingleRefData& s = aData.Ref1;
+ const ScSingleRefData& e = aData.Ref2;
+ SCCOL nCol1 = s.nCol, nCol2 = e.nCol;
+ SCROW nRow1 = s.nRow, nRow2 = e.nRow;
+ SCTAB nTab1 = s.nTab, nTab2 = e.nTab;
+
+ for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
+ {
+ // What's this for ???
+ sal_uInt32 nInsCol = (static_cast<sal_uInt32>(nTab) << 16) |
+ (bNoGlue ? 0 : static_cast<sal_uInt32>(nCol1));
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol)
+ {
+ if (bNoGlue || meGlue == GLUETYPE_ROWS)
+ {
+ pCol = static_cast<Table*>(pCols->Get(nInsCol));
+ if (!pCol)
+ {
+ pCol = pNewRowTable.get();
+ pCols->Insert(nInsCol, pNewRowTable.release());
+ pNewRowTable.reset(new Table);
+ }
+ }
+ else
+ {
+ if (pCols->Insert(nInsCol, pNewRowTable.get()))
+ {
+ pCol = pNewRowTable.release();
+ pNewRowTable.reset(new Table);
+ }
+ else
+ pCol = static_cast<Table*>(pCols->Get(nInsCol));
+ }
+
+ sal_uInt32 nInsRow = static_cast<sal_uInt32>(bNoGlue ? nNoGlueRow : nRow1);
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow, ++nInsRow)
+ {
+ ScSingleRefData aCellData;
+ aCellData.InitFlags();
+ aCellData.SetFlag3D(true);
+ aCellData.SetColRel(false);
+ aCellData.SetRowRel(false);
+ aCellData.SetTabRel(false);
+ aCellData.nCol = nCol;
+ aCellData.nRow = nRow;
+ aCellData.nTab = nTab;
+
+ if (bExternal)
+ pNewAddress.reset(new ScExternalSingleRefToken(nFileId, aTabName, aCellData));
+ else
+ pNewAddress.reset(new ScSingleRefToken(aCellData));
+
+ if (pCol->Insert(nInsRow, pNewAddress.get()))
+ pNewAddress.release(); // To prevent the instance from being destroyed.
+ }
+ }
+ }
+ nNoGlueRow += nRow2 - nRow1 + 1;
+ }
+ pNewAddress.reset(NULL);
+ pNewRowTable.reset(NULL);
+
+ bool bFillRowHeader = mbRowHeaders;
+ bool bFillColumnHeader = mbColHeaders;
+
+ SCSIZE nAllColCount = static_cast<SCSIZE>(pCols->Count());
+ SCSIZE nAllRowCount = 0;
+ pCol = static_cast<Table*>(pCols->First());
+ if (pCol)
+ {
+ if (mbDummyUpperLeft)
+ pCol->Insert(0, NULL); // Dummy fuer Beschriftung
+ nAllRowCount = static_cast<SCSIZE>(pCol->Count());
+ }
+
+ if( nAllColCount!=0 && nAllRowCount!=0 )
+ {
+ if (bNoGlue)
+ {
+ Table* pFirstCol = static_cast<Table*>(pCols->First());
+ sal_uInt32 nCount = pFirstCol->Count();
+ pFirstCol->First();
+ for (sal_uInt32 n = 0; n < nCount; ++n, pFirstCol->Next())
+ {
+ sal_uInt32 nKey = pFirstCol->GetCurKey();
+ pCols->First();
+ for (pCol = static_cast<Table*>(pCols->Next()); pCol; pCol = static_cast<Table*>(pCols->Next()))
+ pCol->Insert(nKey, NULL);
+ }
+ }
+ }
+ mpPositionMap.reset(
+ new Chart2PositionMap(
+ static_cast<SCCOL>(nAllColCount), static_cast<SCROW>(nAllRowCount),
+ bFillRowHeader, bFillColumnHeader, *pCols, mpDoc));
+
+ // Destroy all column instances.
+ for (pCol = static_cast<Table*>(pCols->First()); pCol; pCol = static_cast<Table*>(pCols->Next()))
+ delete pCol;
+}
+
+// ============================================================================
+
+/**
+ * Function object to create a range string from a token list.
+ */
+class Tokens2RangeString : public unary_function<ScSharedTokenRef, void>
+{
+public:
+ Tokens2RangeString(ScDocument* pDoc, FormulaGrammar::Grammar eGram, sal_Unicode cRangeSep) :
+ mpRangeStr(new OUStringBuffer),
+ mpDoc(pDoc),
+ meGrammar(eGram),
+ mcRangeSep(cRangeSep),
+ mbFirst(true)
+ {
+ }
+
+ Tokens2RangeString(const Tokens2RangeString& r) :
+ mpRangeStr(r.mpRangeStr),
+ mpDoc(r.mpDoc),
+ meGrammar(r.meGrammar),
+ mcRangeSep(r.mcRangeSep),
+ mbFirst(r.mbFirst)
+ {
+ }
+
+ void operator() (const ScSharedTokenRef& rToken)
+ {
+ ScCompiler aCompiler(mpDoc, ScAddress(0,0,0));
+ aCompiler.SetGrammar(meGrammar);
+ String aStr;
+ aCompiler.CreateStringFromToken(aStr, rToken.get());
+ if (mbFirst)
+ mbFirst = false;
+ else
+ mpRangeStr->append(mcRangeSep);
+ mpRangeStr->append(aStr);
+ }
+
+ void getString(OUString& rStr)
+ {
+ rStr = mpRangeStr->makeStringAndClear();
+ }
+
+private:
+ Tokens2RangeString(); // disabled
+
+private:
+ shared_ptr<OUStringBuffer> mpRangeStr;
+ ScDocument* mpDoc;
+ FormulaGrammar::Grammar meGrammar;
+ sal_Unicode mcRangeSep;
+ bool mbFirst;
+};
+
+/**
+ * Function object to convert a list of tokens into a string form suitable
+ * for ODF export. In ODF, a range is expressed as
+ *
+ * (start cell address):(end cell address)
+ *
+ * and each address doesn't include any '$' symbols.
+ */
+class Tokens2RangeStringXML : public unary_function<ScSharedTokenRef, void>
+{
+public:
+ Tokens2RangeStringXML(ScDocument* pDoc) :
+ mpRangeStr(new OUStringBuffer),
+ mpDoc(pDoc),
+ mcRangeSep(' '),
+ mcAddrSep(':'),
+ mbFirst(true)
+ {
+ }
+
+ Tokens2RangeStringXML(const Tokens2RangeStringXML& r) :
+ mpRangeStr(r.mpRangeStr),
+ mpDoc(r.mpDoc),
+ mcRangeSep(r.mcRangeSep),
+ mcAddrSep(r.mcAddrSep),
+ mbFirst(r.mbFirst)
+ {
+ }
+
+ void operator() (const ScSharedTokenRef& rToken)
+ {
+ if (mbFirst)
+ mbFirst = false;
+ else
+ mpRangeStr->append(mcRangeSep);
+
+ ScSharedTokenRef aStart, aEnd;
+ splitRangeToken(rToken, aStart, aEnd);
+ ScCompiler aCompiler(mpDoc, ScAddress(0,0,0));
+ aCompiler.SetGrammar(FormulaGrammar::GRAM_ENGLISH);
+ {
+ String aStr;
+ aCompiler.CreateStringFromToken(aStr, aStart.get());
+ mpRangeStr->append(aStr);
+ }
+ mpRangeStr->append(mcAddrSep);
+ {
+ String aStr;
+ aCompiler.CreateStringFromToken(aStr, aEnd.get());
+ mpRangeStr->append(aStr);
+ }
+ }
+
+ void getString(OUString& rStr)
+ {
+ rStr = mpRangeStr->makeStringAndClear();
+ }
+
+private:
+ Tokens2RangeStringXML(); // disabled
+
+ void splitRangeToken(const ScSharedTokenRef& pToken, ScSharedTokenRef& rStart, ScSharedTokenRef& rEnd) const
+ {
+ ScComplexRefData aData;
+ ScRefTokenHelper::getDoubleRefDataFromToken(aData, pToken);
+ bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
+ sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
+ String aTabName = bExternal ? pToken->GetString() : String();
+
+ // In saving to XML, we don't prepend address with '$'.
+ setRelative(aData.Ref1);
+ setRelative(aData.Ref2);
+
+ // In XML, the end range must explicitly specify sheet name.
+ aData.Ref2.SetFlag3D(true);
+
+ if (bExternal)
+ rStart.reset(new ScExternalSingleRefToken(nFileId, aTabName, aData.Ref1));
+ else
+ rStart.reset(new ScSingleRefToken(aData.Ref1));
+
+ if (bExternal)
+ rEnd.reset(new ScExternalSingleRefToken(nFileId, aTabName, aData.Ref2));
+ else
+ rEnd.reset(new ScSingleRefToken(aData.Ref2));
+ }
+
+ void setRelative(ScSingleRefData& rData) const
+ {
+ rData.SetColRel(true);
+ rData.SetRowRel(true);
+ rData.SetTabRel(true);
+ }
+
+private:
+ shared_ptr<OUStringBuffer> mpRangeStr;
+ ScDocument* mpDoc;
+ sal_Unicode mcRangeSep;
+ sal_Unicode mcAddrSep;
+ bool mbFirst;
+};
+
+void lcl_convertTokensToString(OUString& rStr, const vector<ScSharedTokenRef>& rTokens, ScDocument* pDoc)
+{
+ const sal_Unicode cRangeSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ FormulaGrammar::Grammar eGrammar = pDoc->GetGrammar();
+ Tokens2RangeString func(pDoc, eGrammar, cRangeSep);
+ func = for_each(rTokens.begin(), rTokens.end(), func);
+ func.getString(rStr);
+}
+
+} // anonymous namespace
+
+// DataProvider ==============================================================
+
+ScChart2DataProvider::ScChart2DataProvider( ScDocument* pDoc )
+ : m_pDocument( pDoc)
+ , m_aPropSet(lcl_GetDataProviderPropertyMap())
+ , m_bIncludeHiddenCells( sal_True)
+{
+ if ( m_pDocument )
+ m_pDocument->AddUnoObject( *this);
+}
+
+ScChart2DataProvider::~ScChart2DataProvider()
+{
+ if ( m_pDocument )
+ m_pDocument->RemoveUnoObject( *this);
+}
+
+
+void ScChart2DataProvider::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ m_pDocument = NULL;
+ }
+}
+
+::sal_Bool SAL_CALL ScChart2DataProvider::createDataSourcePossible( const uno::Sequence< beans::PropertyValue >& aArguments )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if( ! m_pDocument )
+ return false;
+
+ rtl::OUString aRangeRepresentation;
+ for(sal_Int32 i = 0; i < aArguments.getLength(); ++i)
+ {
+ rtl::OUString sName(aArguments[i].Name);
+ if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
+ {
+ aArguments[i].Value >>= aRangeRepresentation;
+ }
+ }
+
+ vector<ScSharedTokenRef> aTokens;
+ ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
+ return !aTokens.empty();
+}
+
+namespace
+{
+
+ScChart2LabeledDataSequence* lcl_createScChart2DataSequenceFromTokens( auto_ptr< vector<ScSharedTokenRef> > pValueTokens, auto_ptr< vector<ScSharedTokenRef> > pLabelTokens,
+ ScDocument* pDoc, const uno::Reference < chart2::data::XDataProvider >& xDP, bool bIncludeHiddenCells )
+{
+ ScChart2LabeledDataSequence* pRet = 0;
+ bool bHasValues = pValueTokens.get() && !pValueTokens->empty();
+ bool bHasLabel = pLabelTokens.get() && !pLabelTokens->empty();
+ if( bHasValues || bHasLabel )
+ {
+ pRet = new ScChart2LabeledDataSequence(pDoc);
+ if(bHasValues)
+ {
+ uno::Reference < chart2::data::XDataSequence > xSeq(new ScChart2DataSequence(pDoc, xDP, pValueTokens.release(), bIncludeHiddenCells));
+ pRet->setValues(xSeq);
+ }
+ if(bHasLabel)
+ {
+ uno::Reference < chart2::data::XDataSequence > xLabelSeq(new ScChart2DataSequence(pDoc, xDP, pLabelTokens.release(), bIncludeHiddenCells));
+ pRet->setLabel(xLabelSeq);
+ }
+ }
+ return pRet;
+}
+
+//----------------------------------------------------
+/**
+ * Check the current list of reference tokens, and add the upper left
+ * corner of the minimum range that encloses all ranges if certain
+ * conditions are met.
+ *
+ * @param rRefTokens list of reference tokens
+ *
+ * @return true if the corner was added, false otherwise.
+ */
+bool lcl_addUpperLeftCornerIfMissing(vector<ScSharedTokenRef>& rRefTokens,
+ SCROW nCornerRowCount=1, SCCOL nCornerColumnCount=1)
+{
+ using ::std::max;
+ using ::std::min;
+
+ if (rRefTokens.empty())
+ return false;
+
+ SCCOL nMinCol = MAXCOLCOUNT;
+ SCROW nMinRow = MAXROWCOUNT;
+ SCCOL nMaxCol = 0;
+ SCROW nMaxRow = 0;
+ SCTAB nTab = 0;
+
+ USHORT nFileId = 0;
+ String aExtTabName;
+ bool bExternal = false;
+
+ vector<ScSharedTokenRef>::const_iterator itr = rRefTokens.begin(), itrEnd = rRefTokens.end();
+
+ // Get the first ref token.
+ ScSharedTokenRef pToken = *itr;
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ {
+ const ScSingleRefData& rData = pToken->GetSingleRef();
+ nMinCol = rData.nCol;
+ nMinRow = rData.nRow;
+ nMaxCol = rData.nCol;
+ nMaxRow = rData.nRow;
+ nTab = rData.nTab;
+ }
+ break;
+ case svDoubleRef:
+ {
+ const ScComplexRefData& rData = pToken->GetDoubleRef();
+ nMinCol = min(rData.Ref1.nCol, rData.Ref2.nCol);
+ nMinRow = min(rData.Ref1.nRow, rData.Ref2.nRow);
+ nMaxCol = max(rData.Ref1.nCol, rData.Ref2.nCol);
+ nMaxRow = max(rData.Ref1.nRow, rData.Ref2.nRow);
+ nTab = rData.Ref1.nTab;
+ }
+ break;
+ case svExternalSingleRef:
+ {
+ const ScSingleRefData& rData = pToken->GetSingleRef();
+ nMinCol = rData.nCol;
+ nMinRow = rData.nRow;
+ nMaxCol = rData.nCol;
+ nMaxRow = rData.nRow;
+ nTab = rData.nTab;
+ nFileId = pToken->GetIndex();
+ aExtTabName = pToken->GetString();
+ bExternal = true;
+ }
+ break;
+ case svExternalDoubleRef:
+ {
+ const ScComplexRefData& rData = pToken->GetDoubleRef();
+ nMinCol = min(rData.Ref1.nCol, rData.Ref2.nCol);
+ nMinRow = min(rData.Ref1.nRow, rData.Ref2.nRow);
+ nMaxCol = max(rData.Ref1.nCol, rData.Ref2.nCol);
+ nMaxRow = max(rData.Ref1.nRow, rData.Ref2.nRow);
+ nTab = rData.Ref1.nTab;
+ nFileId = pToken->GetIndex();
+ aExtTabName = pToken->GetString();
+ bExternal = true;
+ }
+ break;
+ default:
+ ;
+ }
+
+ // Determine the minimum range enclosing all data ranges. Also make sure
+ // that they are all on the same table.
+
+ for (++itr; itr != itrEnd; ++itr)
+ {
+ pToken = *itr;
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ {
+ const ScSingleRefData& rData = pToken->GetSingleRef();
+
+ nMinCol = min(nMinCol, rData.nCol);
+ nMinRow = min(nMinRow, rData.nRow);
+ nMaxCol = max(nMaxCol, rData.nCol);
+ nMaxRow = max(nMaxRow, rData.nRow);
+ if (nTab != rData.nTab || bExternal)
+ return false;
+ }
+ break;
+ case svDoubleRef:
+ {
+ const ScComplexRefData& rData = pToken->GetDoubleRef();
+
+ nMinCol = min(nMinCol, rData.Ref1.nCol);
+ nMinCol = min(nMinCol, rData.Ref2.nCol);
+ nMinRow = min(nMinRow, rData.Ref1.nRow);
+ nMinRow = min(nMinRow, rData.Ref2.nRow);
+
+ nMaxCol = max(nMaxCol, rData.Ref1.nCol);
+ nMaxCol = max(nMaxCol, rData.Ref2.nCol);
+ nMaxRow = max(nMaxRow, rData.Ref1.nRow);
+ nMaxRow = max(nMaxRow, rData.Ref2.nRow);
+
+ if (nTab != rData.Ref1.nTab || bExternal)
+ return false;
+ }
+ break;
+ case svExternalSingleRef:
+ {
+ if (!bExternal)
+ return false;
+
+ if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
+ return false;
+
+ const ScSingleRefData& rData = pToken->GetSingleRef();
+
+ nMinCol = min(nMinCol, rData.nCol);
+ nMinRow = min(nMinRow, rData.nRow);
+ nMaxCol = max(nMaxCol, rData.nCol);
+ nMaxRow = max(nMaxRow, rData.nRow);
+ }
+ break;
+ case svExternalDoubleRef:
+ {
+ if (!bExternal)
+ return false;
+
+ if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
+ return false;
+
+ const ScComplexRefData& rData = pToken->GetDoubleRef();
+
+ nMinCol = min(nMinCol, rData.Ref1.nCol);
+ nMinCol = min(nMinCol, rData.Ref2.nCol);
+ nMinRow = min(nMinRow, rData.Ref1.nRow);
+ nMinRow = min(nMinRow, rData.Ref2.nRow);
+
+ nMaxCol = max(nMaxCol, rData.Ref1.nCol);
+ nMaxCol = max(nMaxCol, rData.Ref2.nCol);
+ nMaxRow = max(nMaxRow, rData.Ref1.nRow);
+ nMaxRow = max(nMaxRow, rData.Ref2.nRow);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+
+ if (nMinRow >= nMaxRow || nMinCol >= nMaxCol ||
+ nMinRow >= MAXROWCOUNT || nMinCol >= MAXCOLCOUNT ||
+ nMaxRow >= MAXROWCOUNT || nMaxCol >= MAXCOLCOUNT)
+ {
+ // Invalid range. Bail out.
+ return false;
+ }
+
+ // Check if the following conditions are met:
+ //
+ // 1) The upper-left corner cell is not included.
+ // 2) The three adjacent cells of that corner cell are included.
+
+ bool bRight = false, bBottom = false, bDiagonal = false;
+ for (itr = rRefTokens.begin(); itr != itrEnd; ++itr)
+ {
+ pToken = *itr;
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ case svExternalSingleRef:
+ {
+ const ScSingleRefData& rData = pToken->GetSingleRef();
+ if (rData.nCol == nMinCol && rData.nRow == nMinRow)
+ // The corner cell is contained.
+ return false;
+
+ if (rData.nCol == nMinCol+nCornerColumnCount && rData.nRow == nMinRow)
+ bRight = true;
+
+ if (rData.nCol == nMinCol && rData.nRow == nMinRow+nCornerRowCount)
+ bBottom = true;
+
+ if (rData.nCol == nMinCol+nCornerColumnCount && rData.nRow == nMinRow+nCornerRowCount)
+ bDiagonal = true;
+ }
+ break;
+ case svDoubleRef:
+ case svExternalDoubleRef:
+ {
+ const ScComplexRefData& rData = pToken->GetDoubleRef();
+ const ScSingleRefData& r1 = rData.Ref1;
+ const ScSingleRefData& r2 = rData.Ref2;
+ if (r1.nCol <= nMinCol && nMinCol <= r2.nCol &&
+ r1.nRow <= nMinRow && nMinRow <= r2.nRow)
+ // The corner cell is contained.
+ return false;
+
+ if (r1.nCol <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.nCol &&
+ r1.nRow <= nMinRow && nMinRow <= r2.nRow)
+ bRight = true;
+
+ if (r1.nCol <= nMinCol && nMinCol <= r2.nCol &&
+ r1.nRow <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.nRow)
+ bBottom = true;
+
+ if (r1.nCol <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.nCol &&
+ r1.nRow <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.nRow)
+ bDiagonal = true;
+ }
+ break;
+ default:
+ ;
+ }
+ }
+
+ if (!bRight || !bBottom || !bDiagonal)
+ // Not all the adjacent cells are included. Bail out.
+ return false;
+
+#if 0 // Do we really need to do this ???
+ if (rRefTokens.size() == 2)
+ {
+ // Make a simple rectangular range if possible.
+ ScRange aRightPart(ScAddress(nMinCol+1, nMinRow, nTab), ScAddress(nMaxCol, nMaxRow, nTab));
+ ScRange aBottomPart(ScAddress(nMinCol, nMinRow+1, nTab), ScAddress(nMaxCol, nMaxRow, nTab));
+ vector<ScRange> aRanges;
+ aRanges.reserve(2);
+ aRanges.push_back(aRightPart);
+ aRanges.push_back(aBottomPart);
+ if (lcl_isRangeContained(rRefTokens, aRanges))
+ {
+ // Consolidate them into a single rectangle.
+ ScComplexRefData aData;
+ aData.InitFlags();
+ aData.Ref1.SetFlag3D(true);
+ aData.Ref1.SetColRel(false);
+ aData.Ref1.SetRowRel(false);
+ aData.Ref1.SetTabRel(false);
+ aData.Ref2.SetColRel(false);
+ aData.Ref2.SetRowRel(false);
+ aData.Ref2.SetTabRel(false);
+ aData.Ref1.nCol = nMinCol;
+ aData.Ref1.nRow = nMinRow;
+ aData.Ref1.nTab = nTab;
+ aData.Ref2.nCol = nMaxCol;
+ aData.Ref2.nRow = nMaxRow;
+ aData.Ref2.nTab = nTab;
+ vector<ScSharedTokenRef> aNewTokens;
+ aNewTokens.reserve(1);
+ if (bExternal)
+ {
+ ScSharedTokenRef p(
+ new ScExternalDoubleRefToken(nFileId, aExtTabName, aData));
+ aNewTokens.push_back(p);
+ }
+ else
+ {
+ ScSharedTokenRef p(new ScDoubleRefToken(aData));
+ aNewTokens.push_back(p);
+ }
+ rRefTokens.swap(aNewTokens);
+ return true;
+ }
+ }
+#endif
+
+ ScSingleRefData aData;
+ aData.InitFlags();
+ aData.SetFlag3D(true);
+ aData.SetColRel(false);
+ aData.SetRowRel(false);
+ aData.SetTabRel(false);
+ aData.nCol = nMinCol;
+ aData.nRow = nMinRow;
+ aData.nTab = nTab;
+
+ if( nCornerRowCount==1 && nCornerColumnCount==1 )
+ {
+ if (bExternal)
+ {
+ ScSharedTokenRef pCorner(
+ new ScExternalSingleRefToken(nFileId, aExtTabName, aData));
+ ScRefTokenHelper::join(rRefTokens, pCorner);
+ }
+ else
+ {
+ ScSharedTokenRef pCorner(new ScSingleRefToken(aData));
+ ScRefTokenHelper::join(rRefTokens, pCorner);
+ }
+ }
+ else
+ {
+ ScSingleRefData aDataEnd(aData);
+ aDataEnd.nCol += (nCornerColumnCount-1);
+ aDataEnd.nRow += (nCornerRowCount-1);
+ ScComplexRefData r;
+ r.Ref1=aData;
+ r.Ref2=aDataEnd;
+ if (bExternal)
+ {
+ ScSharedTokenRef pCorner(
+ new ScExternalDoubleRefToken(nFileId, aExtTabName, r));
+ ScRefTokenHelper::join(rRefTokens, pCorner);
+ }
+ else
+ {
+ ScSharedTokenRef pCorner(new ScDoubleRefToken(r));
+ ScRefTokenHelper::join(rRefTokens, pCorner);
+ }
+ }
+
+ return true;
+}
+
+}
+
+uno::Reference< chart2::data::XDataSource> SAL_CALL
+ScChart2DataProvider::createDataSource(
+ const uno::Sequence< beans::PropertyValue >& aArguments )
+ throw( lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( ! m_pDocument )
+ throw uno::RuntimeException();
+
+ uno::Reference< chart2::data::XDataSource> xResult;
+ bool bLabel = true;
+ bool bCategories = false;
+ bool bOrientCol = true;
+ ::rtl::OUString aRangeRepresentation;
+ uno::Sequence< sal_Int32 > aSequenceMapping;
+ for(sal_Int32 i = 0; i < aArguments.getLength(); ++i)
+ {
+ rtl::OUString sName(aArguments[i].Name);
+ if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource")))
+ {
+ chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
+ if( ! (aArguments[i].Value >>= eSource))
+ {
+ sal_Int32 nSource(0);
+ if( aArguments[i].Value >>= nSource )
+ eSource = (static_cast< chart::ChartDataRowSource >( nSource ));
+ }
+ bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
+ }
+ else if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel")))
+ {
+ bLabel = ::cppu::any2bool(aArguments[i].Value);
+ }
+ else if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasCategories")))
+ {
+ bCategories = ::cppu::any2bool(aArguments[i].Value);
+ }
+ else if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
+ {
+ aArguments[i].Value >>= aRangeRepresentation;
+ }
+ else if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping")))
+ {
+ aArguments[i].Value >>= aSequenceMapping;
+ }
+ }
+
+ vector<ScSharedTokenRef> aRefTokens;
+ ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
+ if (aRefTokens.empty())
+ // Invalid range representation. Bail out.
+ throw lang::IllegalArgumentException();
+
+ if (bLabel)
+ lcl_addUpperLeftCornerIfMissing(aRefTokens); //#i90669#
+
+ bool bColHeaders = (bOrientCol ? bLabel : bCategories );
+ bool bRowHeaders = (bOrientCol ? bCategories : bLabel );
+
+ Chart2Positioner aChPositioner(m_pDocument, aRefTokens);
+ aChPositioner.setHeaders(bColHeaders, bRowHeaders);
+
+ const Chart2PositionMap* pChartMap = aChPositioner.getPositionMap();
+ if (!pChartMap)
+ // No chart position map instance. Bail out.
+ return xResult;
+
+ ScChart2DataSource* pDS = NULL;
+ std::list < ScChart2LabeledDataSequence* > aSeqs;
+
+ // Fill Categories
+ if( bCategories )
+ {
+ auto_ptr< vector<ScSharedTokenRef> > pValueTokens(NULL);
+ if (bOrientCol)
+ pValueTokens.reset(pChartMap->getAllRowHeaderRanges());
+ else
+ pValueTokens.reset(pChartMap->getAllColHeaderRanges());
+
+ auto_ptr< vector<ScSharedTokenRef> > pLabelTokens(NULL);
+ pLabelTokens.reset(pChartMap->getLeftUpperCornerRanges());
+
+ ScChart2LabeledDataSequence* pCategories = lcl_createScChart2DataSequenceFromTokens( pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells );//ownership of pointers is transfered!
+ if( pCategories )
+ aSeqs.push_back(pCategories);
+ }
+
+ // Fill Serieses (values and label)
+ sal_Int32 nCount = bOrientCol ? pChartMap->getDataColCount() : pChartMap->getDataRowCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ auto_ptr< vector<ScSharedTokenRef> > pValueTokens(NULL);
+ auto_ptr< vector<ScSharedTokenRef> > pLabelTokens(NULL);
+ if (bOrientCol)
+ {
+ pValueTokens.reset(pChartMap->getDataColRanges(static_cast<SCCOL>(i)));
+ pLabelTokens.reset(pChartMap->getColHeaderRanges(static_cast<SCCOL>(i)));
+ }
+ else
+ {
+ pValueTokens.reset(pChartMap->getDataRowRanges(static_cast<SCROW>(i)));
+ pLabelTokens.reset(pChartMap->getRowHeaderRanges(static_cast<SCROW>(i)));
+ }
+ ScChart2LabeledDataSequence* pChartSeries = lcl_createScChart2DataSequenceFromTokens( pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered!
+ if( pChartSeries )
+ aSeqs.push_back(pChartSeries);
+ }
+
+ pDS = new ScChart2DataSource(m_pDocument);
+ std::list < ScChart2LabeledDataSequence* >::iterator aItr(aSeqs.begin());
+ std::list < ScChart2LabeledDataSequence* >::iterator aEndItr(aSeqs.end());
+
+ //reorder labeled sequences according to aSequenceMapping
+ std::vector< ScChart2LabeledDataSequence* > aSeqVector;
+ while(aItr != aEndItr)
+ {
+ aSeqVector.push_back(*aItr);
+ ++aItr;
+ }
+
+ std::map< sal_Int32, ScChart2LabeledDataSequence* > aSequenceMap;
+ for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
+ {
+ // note: assuming that the values in the sequence mapping are always non-negative
+ std::vector< ScChart2LabeledDataSequence* >::size_type nOldIndex( static_cast< sal_uInt32 >( aSequenceMapping[nNewIndex] ));
+ if( nOldIndex < aSeqVector.size() )
+ {
+ pDS->AddLabeledSequence( aSeqVector[nOldIndex] );
+ aSeqVector[nOldIndex] = 0;
+ }
+
+ }
+
+ std::vector< ScChart2LabeledDataSequence* >::iterator aVectorItr(aSeqVector.begin());
+ std::vector< ScChart2LabeledDataSequence* >::iterator aVectorEndItr(aSeqVector.end());
+ while(aVectorItr != aVectorEndItr)
+ {
+ if(*aVectorItr)
+ pDS->AddLabeledSequence(*aVectorItr);
+ ++aVectorItr;
+ }
+
+ xResult.set( pDS );
+ return xResult;
+}
+
+namespace
+{
+
+/**
+ * Function object to create a list of table numbers from a token list.
+ */
+class InsertTabNumber : public unary_function<ScSharedTokenRef, void>
+{
+public:
+ InsertTabNumber() :
+ mpTabNumList(new list<SCTAB>())
+ {
+ }
+
+ InsertTabNumber(const InsertTabNumber& r) :
+ mpTabNumList(r.mpTabNumList)
+ {
+ }
+
+ void operator() (const ScSharedTokenRef& pToken) const
+ {
+ if (!ScRefTokenHelper::isRef(pToken))
+ return;
+
+ const ScSingleRefData& r = pToken->GetSingleRef();
+ mpTabNumList->push_back(r.nTab);
+ }
+
+ void getList(list<SCTAB>& rList)
+ {
+ mpTabNumList->swap(rList);
+ }
+private:
+ shared_ptr< list<SCTAB> > mpTabNumList;
+};
+
+class RangeAnalyzer
+{
+public:
+ RangeAnalyzer();
+ void initRangeAnalyzer( const vector<ScSharedTokenRef>& rTokens );
+ void analyzeRange( sal_Int32& rnDataInRows, sal_Int32& rnDataInCols,
+ bool& rbRowSourceAmbiguous ) const;
+ bool inSameSingleRow( RangeAnalyzer& rOther );
+ bool inSameSingleColumn( RangeAnalyzer& rOther );
+ SCROW getRowCount() { return mnRowCount; }
+ SCCOL getColumnCount() { return mnColumnCount; }
+
+private:
+ bool mbEmpty;
+ bool mbAmbiguous;
+ SCROW mnRowCount;
+ SCCOL mnColumnCount;
+
+ SCCOL mnStartColumn;
+ SCROW mnStartRow;
+};
+
+RangeAnalyzer::RangeAnalyzer()
+ : mbEmpty(true)
+ , mbAmbiguous(false)
+ , mnRowCount(0)
+ , mnColumnCount(0)
+ , mnStartColumn(-1)
+ , mnStartRow(-1)
+{
+}
+
+void RangeAnalyzer::initRangeAnalyzer( const vector<ScSharedTokenRef>& rTokens )
+{
+ mnRowCount=0;
+ mnColumnCount=0;
+ mnStartColumn = -1;
+ mnStartRow = -1;
+ mbAmbiguous=false;
+ if( rTokens.empty() )
+ {
+ mbEmpty=true;
+ return;
+ }
+ mbEmpty=false;
+
+ vector<ScSharedTokenRef>::const_iterator itr = rTokens.begin(), itrEnd = rTokens.end();
+ for (; itr != itrEnd ; ++itr)
+ {
+ ScSharedTokenRef aRefToken = *itr;
+ StackVar eVar = aRefToken->GetType();
+ if (eVar == svDoubleRef || eVar == svExternalDoubleRef)
+ {
+ const ScComplexRefData& r = aRefToken->GetDoubleRef();
+ if (r.Ref1.nTab == r.Ref2.nTab)
+ {
+ mnColumnCount = std::max<SCCOL>( mnColumnCount, static_cast<SCCOL>(abs(r.Ref2.nCol - r.Ref1.nCol)+1) );
+ mnRowCount = std::max<SCROW>( mnRowCount, static_cast<SCROW>(abs(r.Ref2.nRow - r.Ref1.nRow)+1) );
+ if( mnStartColumn == -1 )
+ {
+ mnStartColumn = r.Ref1.nCol;
+ mnStartRow = r.Ref1.nRow;
+ }
+ else
+ {
+ if( mnStartColumn != r.Ref1.nCol && mnStartRow != r.Ref1.nRow )
+ mbAmbiguous=true;
+ }
+ }
+ else
+ mbAmbiguous=true;
+ }
+ else if (eVar == svSingleRef || eVar == svExternalSingleRef)
+ {
+ const ScSingleRefData& r = aRefToken->GetSingleRef();
+ mnColumnCount = std::max<SCCOL>( mnColumnCount, 1);
+ mnRowCount = std::max<SCROW>( mnRowCount, 1);
+ if( mnStartColumn == -1 )
+ {
+ mnStartColumn = r.nCol;
+ mnStartRow = r.nRow;
+ }
+ else
+ {
+ if( mnStartColumn != r.nCol && mnStartRow != r.nRow )
+ mbAmbiguous=true;
+ }
+ }
+ else
+ mbAmbiguous=true;
+ }
+}
+
+void RangeAnalyzer::analyzeRange( sal_Int32& rnDataInRows,
+ sal_Int32& rnDataInCols,
+ bool& rbRowSourceAmbiguous ) const
+{
+ if(!mbEmpty && !mbAmbiguous)
+ {
+ if( mnRowCount==1 && mnColumnCount>1 )
+ ++rnDataInRows;
+ else if( mnColumnCount==1 && mnRowCount>1 )
+ ++rnDataInCols;
+ else if( mnRowCount>1 && mnColumnCount>1 )
+ rbRowSourceAmbiguous = true;
+ }
+ else if( !mbEmpty )
+ rbRowSourceAmbiguous = true;
+}
+
+bool RangeAnalyzer::inSameSingleRow( RangeAnalyzer& rOther )
+{
+ if( mnStartRow==rOther.mnStartRow &&
+ mnRowCount==1 && rOther.mnRowCount==1 )
+ return true;
+ return false;
+}
+
+bool RangeAnalyzer::inSameSingleColumn( RangeAnalyzer& rOther )
+{
+ if( mnStartColumn==rOther.mnStartColumn &&
+ mnColumnCount==1 && rOther.mnColumnCount==1 )
+ return true;
+ return false;
+}
+
+} //end anonymous namespace
+
+uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArguments(
+ const uno::Reference< chart2::data::XDataSource >& xDataSource )
+ throw (uno::RuntimeException)
+{
+ ::std::vector< beans::PropertyValue > aResult;
+ bool bRowSourceDetected = false;
+ bool bFirstCellAsLabel = false;
+ bool bHasCategories = false;
+ ::rtl::OUString sRangeRep;
+
+ bool bHasCategoriesLabels = false;
+ vector<ScSharedTokenRef> aAllCategoriesValuesTokens;
+ vector<ScSharedTokenRef> aAllSeriesLabelTokens;
+
+ chart::ChartDataRowSource eRowSource = chart::ChartDataRowSource_COLUMNS;
+
+ vector<ScSharedTokenRef> aAllTokens;
+
+ // parse given data source and collect infos
+ {
+ ScUnoGuard aGuard;
+ DBG_ASSERT( m_pDocument, "No Document -> no detectArguments" );
+ if(!m_pDocument ||!xDataSource.is())
+ return lcl_VectorToSequence( aResult );
+
+ sal_Int32 nDataInRows = 0;
+ sal_Int32 nDataInCols = 0;
+ bool bRowSourceAmbiguous = false;
+
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
+ const sal_Int32 nCount( aSequences.getLength());
+ RangeAnalyzer aPrevLabel,aPrevValues;
+ for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
+ {
+ Reference< chart2::data::XLabeledDataSequence > xLS(aSequences[nIdx]);
+ if( xLS.is() )
+ {
+ bool bThisIsCategories = false;
+ if(!bHasCategories)
+ {
+ Reference< beans::XPropertySet > xSeqProp( xLS->getValues(), uno::UNO_QUERY );
+ ::rtl::OUString aRole;
+ if( xSeqProp.is() && (xSeqProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Role"))) >>= aRole) &&
+ aRole.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) )
+ bThisIsCategories = bHasCategories = true;
+ }
+
+ RangeAnalyzer aLabel,aValues;
+ // label
+ Reference< chart2::data::XDataSequence > xLabel( xLS->getLabel());
+ if( xLabel.is())
+ {
+ bFirstCellAsLabel = true;
+ vector<ScSharedTokenRef> aTokens;
+ ScRefTokenHelper::compileRangeRepresentation( aTokens, xLabel->getSourceRangeRepresentation(), m_pDocument, m_pDocument->GetGrammar() );
+ aLabel.initRangeAnalyzer(aTokens);
+ vector<ScSharedTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScRefTokenHelper::join(aAllTokens, *itr);
+ if(!bThisIsCategories)
+ ScRefTokenHelper::join(aAllSeriesLabelTokens, *itr);
+ }
+ if(bThisIsCategories)
+ bHasCategoriesLabels=true;
+ }
+ // values
+ Reference< chart2::data::XDataSequence > xValues( xLS->getValues());
+ if( xValues.is())
+ {
+ vector<ScSharedTokenRef> aTokens;
+ ScRefTokenHelper::compileRangeRepresentation( aTokens, xValues->getSourceRangeRepresentation(), m_pDocument, m_pDocument->GetGrammar() );
+ aValues.initRangeAnalyzer(aTokens);
+ vector<ScSharedTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScRefTokenHelper::join(aAllTokens, *itr);
+ if(bThisIsCategories)
+ ScRefTokenHelper::join(aAllCategoriesValuesTokens, *itr);
+ }
+ }
+ //detect row source
+ if(!bThisIsCategories || nCount==1) //categories might span multiple rows *and* columns, so they should be used for detection only if nothing else is available
+ {
+ if (!bRowSourceAmbiguous)
+ {
+ aValues.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
+ aLabel.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
+ if (nDataInRows > 1 && nDataInCols > 1)
+ bRowSourceAmbiguous = true;
+ else if( !bRowSourceAmbiguous && !nDataInRows && !nDataInCols )
+ {
+ if( aValues.inSameSingleColumn( aLabel ) )
+ nDataInCols++;
+ else if( aValues.inSameSingleRow( aLabel ) )
+ nDataInRows++;
+ else
+ {
+ //#i86188# also detect a single column split into rows correctly
+ if( aValues.inSameSingleColumn( aPrevValues ) )
+ nDataInRows++;
+ else if( aValues.inSameSingleRow( aPrevValues ) )
+ nDataInCols++;
+ else if( aLabel.inSameSingleColumn( aPrevLabel ) )
+ nDataInRows++;
+ else if( aLabel.inSameSingleRow( aPrevLabel ) )
+ nDataInCols++;
+ }
+ }
+ }
+ }
+ aPrevValues=aValues;
+ aPrevLabel=aLabel;
+ }
+ }
+
+ if (!bRowSourceAmbiguous)
+ {
+ bRowSourceDetected = true;
+ eRowSource = ( nDataInRows > 0
+ ? chart::ChartDataRowSource_ROWS
+ : chart::ChartDataRowSource_COLUMNS );
+ }
+ else
+ {
+ // set DataRowSource to the better of the two ambiguities
+ eRowSource = ( nDataInRows > nDataInCols
+ ? chart::ChartDataRowSource_ROWS
+ : chart::ChartDataRowSource_COLUMNS );
+ }
+
+ }
+
+ // TableNumberList
+ {
+ list<SCTAB> aTableNumList;
+ InsertTabNumber func;
+ func = for_each(aAllTokens.begin(), aAllTokens.end(), func);
+ func.getList(aTableNumList);
+ aResult.push_back(
+ beans::PropertyValue( ::rtl::OUString::createFromAscii("TableNumberList"), -1,
+ uno::makeAny( lcl_createTableNumberList( aTableNumList ) ),
+ beans::PropertyState_DIRECT_VALUE ));
+ }
+
+ // DataRowSource (calculated before)
+ if( bRowSourceDetected )
+ {
+ aResult.push_back(
+ beans::PropertyValue( ::rtl::OUString::createFromAscii("DataRowSource"), -1,
+ uno::makeAny( eRowSource ), beans::PropertyState_DIRECT_VALUE ));
+ }
+
+ // HasCategories
+ if( bRowSourceDetected )
+ {
+ aResult.push_back(
+ beans::PropertyValue( ::rtl::OUString::createFromAscii("HasCategories"), -1,
+ uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE ));
+ }
+
+ // FirstCellAsLabel
+ if( bRowSourceDetected )
+ {
+ aResult.push_back(
+ beans::PropertyValue( ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
+ uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE ));
+ }
+
+ // Add the left upper corner to the range if it is missing.
+ if (bRowSourceDetected && bFirstCellAsLabel && bHasCategories && !bHasCategoriesLabels )
+ {
+ RangeAnalyzer aTop,aLeft;
+ if( eRowSource==chart::ChartDataRowSource_COLUMNS )
+ {
+ aTop.initRangeAnalyzer(aAllSeriesLabelTokens);
+ aLeft.initRangeAnalyzer(aAllCategoriesValuesTokens);
+ }
+ else
+ {
+ aTop.initRangeAnalyzer(aAllCategoriesValuesTokens);
+ aLeft.initRangeAnalyzer(aAllSeriesLabelTokens);
+ }
+ lcl_addUpperLeftCornerIfMissing(aAllTokens, aTop.getRowCount(), aLeft.getColumnCount());//e.g. #i91212#
+ }
+
+ // Get range string.
+ lcl_convertTokensToString(sRangeRep, aAllTokens, m_pDocument);
+
+ // add cell range property
+ aResult.push_back(
+ beans::PropertyValue( ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
+ uno::makeAny( sRangeRep ), beans::PropertyState_DIRECT_VALUE ));
+
+ //Sequence Mapping
+ bool bSequencesReordered = true;//todo detect this above or detect this sequence mapping cheaper ...
+ if( bSequencesReordered && bRowSourceDetected )
+ {
+ bool bDifferentIndexes = false;
+
+ std::vector< sal_Int32 > aSequenceMappingVector;
+
+ uno::Reference< chart2::data::XDataSource > xCompareDataSource;
+ try
+ {
+ xCompareDataSource.set( this->createDataSource( lcl_VectorToSequence( aResult ) ) );
+ }
+ catch( const lang::IllegalArgumentException & )
+ {
+ // creation of data source to compare didn't work, so we cannot
+ // create a sequence mapping
+ }
+
+ if( xDataSource.is() && xCompareDataSource.is() )
+ {
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > aOldSequences(
+ xCompareDataSource->getDataSequences() );
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aNewSequences(
+ xDataSource->getDataSequences());
+
+ rtl::OUString aOldLabel;
+ rtl::OUString aNewLabel;
+ rtl::OUString aOldValues;
+ rtl::OUString aNewValues;
+ rtl::OUString aEmpty;
+
+ for( sal_Int32 nNewIndex = 0; nNewIndex < aNewSequences.getLength(); nNewIndex++ )
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence> xNew( aNewSequences[nNewIndex] );
+ for( sal_Int32 nOldIndex = 0; nOldIndex < aOldSequences.getLength(); nOldIndex++ )
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence> xOld( aOldSequences[nOldIndex] );
+
+ if( xOld.is() && xNew.is() )
+ {
+ aOldLabel = aNewLabel = aOldValues = aNewValues = aEmpty;
+ if( xOld.is() && xOld->getLabel().is() )
+ aOldLabel = xOld->getLabel()->getSourceRangeRepresentation();
+ if( xNew.is() && xNew->getLabel().is() )
+ aNewLabel = xNew->getLabel()->getSourceRangeRepresentation();
+ if( xOld.is() && xOld->getValues().is() )
+ aOldValues = xOld->getValues()->getSourceRangeRepresentation();
+ if( xNew.is() && xNew->getValues().is() )
+ aNewValues = xNew->getValues()->getSourceRangeRepresentation();
+
+ if( aOldLabel.equals(aNewLabel)
+ && ( aOldValues.equals(aNewValues) ) )
+ {
+ if( nOldIndex!=nNewIndex )
+ bDifferentIndexes = true;
+ aSequenceMappingVector.push_back(nOldIndex);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if( bDifferentIndexes && aSequenceMappingVector.size() )
+ {
+ aResult.push_back(
+ beans::PropertyValue( ::rtl::OUString::createFromAscii("SequenceMapping"), -1,
+ uno::makeAny( lcl_VectorToSequence(aSequenceMappingVector) )
+ , beans::PropertyState_DIRECT_VALUE ));
+ }
+ }
+
+ return lcl_VectorToSequence( aResult );
+}
+
+::sal_Bool SAL_CALL ScChart2DataProvider::createDataSequenceByRangeRepresentationPossible( const ::rtl::OUString& aRangeRepresentation )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if( ! m_pDocument )
+ return false;
+
+ vector<ScSharedTokenRef> aTokens;
+ ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
+ return !aTokens.empty();
+}
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL
+ ScChart2DataProvider::createDataSequenceByRangeRepresentation(
+ const ::rtl::OUString& aRangeRepresentation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< chart2::data::XDataSequence > xResult;
+
+ DBG_ASSERT( m_pDocument, "No Document -> no createDataSequenceByRangeRepresentation" );
+ 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())
+ return xResult;
+
+ // ScChart2DataSequence manages the life cycle of pRefTokens.
+ vector<ScSharedTokenRef>* pRefTokens = new vector<ScSharedTokenRef>();
+ pRefTokens->swap(aRefTokens);
+ xResult.set(new ScChart2DataSequence(m_pDocument, this, pRefTokens, m_bIncludeHiddenCells));
+
+ return xResult;
+}
+
+uno::Reference< sheet::XRangeSelection > SAL_CALL ScChart2DataProvider::getRangeSelection()
+ throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XRangeSelection > xResult;
+
+ uno::Reference< frame::XModel > xModel( lcl_GetXModel( m_pDocument ));
+ if( xModel.is())
+ xResult.set( xModel->getCurrentController(), uno::UNO_QUERY );
+
+ return xResult;
+}
+
+/*uno::Reference< util::XNumberFormatsSupplier > SAL_CALL ScChart2DataProvider::getNumberFormatsSupplier()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XNumberFormatsSupplier >( lcl_GetXModel( m_pDocument ), uno::UNO_QUERY );
+}*/
+
+// XRangeXMLConversion ---------------------------------------------------
+
+rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const rtl::OUString& sRangeRepresentation )
+ throw ( uno::RuntimeException, lang::IllegalArgumentException )
+{
+ OUString aRet;
+ if (!m_pDocument)
+ return aRet;
+
+ if (!sRangeRepresentation.getLength())
+ // Empty data range is allowed.
+ return aRet;
+
+ vector<ScSharedTokenRef> aRefTokens;
+ ScRefTokenHelper::compileRangeRepresentation(aRefTokens, sRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
+ if (aRefTokens.empty())
+ throw lang::IllegalArgumentException();
+
+ Tokens2RangeStringXML converter(m_pDocument);
+ converter = for_each(aRefTokens.begin(), aRefTokens.end(), converter);
+ converter.getString(aRet);
+
+ return aRet;
+}
+
+rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeFromXML( const rtl::OUString& sXMLRange )
+ throw ( uno::RuntimeException, lang::IllegalArgumentException )
+{
+ const sal_Unicode cSep = ' ';
+ const sal_Unicode cQuote = '\'';
+
+ if (!m_pDocument)
+ {
+ // #i74062# When loading flat XML, this is called before the referenced sheets are in the document,
+ // so the conversion has to take place directly with the strings, without looking up the sheets.
+
+ rtl::OUStringBuffer sRet;
+ sal_Int32 nOffset = 0;
+ while( nOffset >= 0 )
+ {
+ rtl::OUString sToken;
+ ScRangeStringConverter::GetTokenByOffset( sToken, sXMLRange, nOffset, cSep, cQuote );
+ if( nOffset >= 0 )
+ {
+ // convert one address (remove dots)
+
+ String aUIString(sToken);
+
+ sal_Int32 nIndex = ScRangeStringConverter::IndexOf( sToken, ':', 0, cQuote );
+ if ( nIndex >= 0 && nIndex < aUIString.Len() - 1 &&
+ aUIString.GetChar((xub_StrLen)nIndex + 1) == (sal_Unicode) '.' )
+ aUIString.Erase( (xub_StrLen)nIndex + 1, 1 );
+
+ if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
+ aUIString.Erase( 0, 1 );
+
+ if( sRet.getLength() )
+ sRet.append( (sal_Unicode) ';' );
+ sRet.append( aUIString );
+ }
+ }
+
+ return sRet.makeStringAndClear();
+ }
+
+ OUString aRet;
+ ScRangeStringConverter::GetStringFromXMLRangeString(aRet, sXMLRange, m_pDocument);
+ return aRet;
+}
+
+// DataProvider XPropertySet -------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo> SAL_CALL
+ScChart2DataProvider::getPropertySetInfo() throw( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
+ return aRef;
+}
+
+
+void SAL_CALL ScChart2DataProvider::setPropertyValue(
+ const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS)))
+ {
+ if ( !(rValue >>= m_bIncludeHiddenCells))
+ throw lang::IllegalArgumentException();
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+
+uno::Any SAL_CALL ScChart2DataProvider::getPropertyValue(
+ const ::rtl::OUString& rPropertyName)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aRet;
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS)))
+ aRet <<= m_bIncludeHiddenCells;
+ else
+ throw beans::UnknownPropertyException();
+ return aRet;
+}
+
+
+void SAL_CALL ScChart2DataProvider::addPropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2DataProvider::removePropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2DataProvider::addVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2DataProvider::removeVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/ )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+// DataSource ================================================================
+
+ScChart2DataSource::ScChart2DataSource( ScDocument* pDoc)
+ : m_pDocument( pDoc)
+{
+ if ( m_pDocument )
+ m_pDocument->AddUnoObject( *this);
+}
+
+
+ScChart2DataSource::~ScChart2DataSource()
+{
+ if ( m_pDocument )
+ m_pDocument->RemoveUnoObject( *this);
+}
+
+
+void ScChart2DataSource::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ m_pDocument = NULL;
+ }
+}
+
+
+uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > SAL_CALL
+ScChart2DataSource::getDataSequences() throw ( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ LabeledList::const_iterator aItr(m_aLabeledSequences.begin());
+ LabeledList::const_iterator aEndItr(m_aLabeledSequences.end());
+
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aRet(m_aLabeledSequences.size());
+
+ sal_Int32 i = 0;
+ while (aItr != aEndItr)
+ {
+ aRet[i] = *aItr;
+ ++i;
+ ++aItr;
+ }
+
+ return aRet;
+
+/* typedef ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > tVec;
+ tVec aVec;
+ bool bSeries = false;
+ // split into columns - FIXME: different if GlueState() is used
+ for ( ScRangePtr p = m_xRanges->First(); p; p = m_xRanges->Next())
+ {
+ for ( SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
+ new ScChart2LabeledDataSequence( m_pDocument));
+ if( xLabeledSeq.is())
+ {
+ aVec.push_back( xLabeledSeq );
+ if( bSeries )
+ {
+ ScRangeListRef aColRanges = new ScRangeList;
+ // one single sheet selected assumed for now
+ aColRanges->Append( ScRange( nCol, p->aStart.Row(),
+ p->aStart.Tab(), nCol, p->aStart.Row(),
+ p->aStart.Tab()));
+ // TEST: add range two times, once as label, once as data
+ // TODO: create pure Numerical and Text sequences if possible
+ uno::Reference< chart2::data::XDataSequence > xLabel(
+ new ScChart2DataSequence( m_pDocument, aColRanges));
+
+ // set role
+ uno::Reference< beans::XPropertySet > xProp( xLabel, uno::UNO_QUERY );
+ if( xProp.is())
+ xProp->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )),
+ ::uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "label" ))));
+
+ xLabeledSeq->setLabel( xLabel );
+ }
+
+ ScRangeListRef aColRanges = new ScRangeList;
+
+ // one single sheet selected assumed for now
+ aColRanges->Append( ScRange( nCol, p->aStart.Row() + 1,
+ p->aStart.Tab(), nCol, p->aEnd.Row(),
+ p->aStart.Tab()));
+ uno::Reference< chart2::data::XDataSequence > xData(
+ new ScChart2DataSequence( m_pDocument, aColRanges));
+
+ // set role
+ uno::Reference< beans::XPropertySet > xProp( xData, uno::UNO_QUERY );
+ if( xProp.is())
+ xProp->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )),
+ ::uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "values" ))));
+
+ xLabeledSeq->setValues( xData );
+
+ bSeries = true;
+ }
+ }
+ }
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > aSequences(
+ aVec.size());
+ uno::Reference< chart2::data::XLabeledDataSequence> * pArr = aSequences.getArray();
+ sal_Int32 j = 0;
+ for ( tVec::const_iterator iSeq = aVec.begin(); iSeq != aVec.end();
+ ++iSeq, ++j)
+ {
+ pArr[j] = *iSeq;
+ }
+ return aSequences;*/
+}
+
+void ScChart2DataSource::AddLabeledSequence(const uno::Reference < chart2::data::XLabeledDataSequence >& xNew)
+{
+ m_aLabeledSequences.push_back(xNew);
+}
+
+// LabeledDataSequence =======================================================
+
+ScChart2LabeledDataSequence::ScChart2LabeledDataSequence(
+ ScDocument* pDoc ) :
+ m_pDocument( pDoc )
+{
+ if ( m_pDocument )
+ m_pDocument->AddUnoObject( *this);
+}
+
+ScChart2LabeledDataSequence::~ScChart2LabeledDataSequence()
+{
+ if ( m_pDocument )
+ m_pDocument->RemoveUnoObject( *this);
+}
+
+// SfxListener -----------------------------------------------------------
+
+void ScChart2LabeledDataSequence::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ ScUnoGuard aGuard;
+ m_pDocument = NULL;
+ }
+}
+
+// XLabeledDataSequence --------------------------------------------------
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL ScChart2LabeledDataSequence::getValues()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return m_aData;
+}
+
+void SAL_CALL ScChart2LabeledDataSequence::setValues(
+ const uno::Reference< chart2::data::XDataSequence >& xSequence )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ m_aData = xSequence;
+}
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL ScChart2LabeledDataSequence::getLabel()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return m_aLabel;
+}
+
+void SAL_CALL ScChart2LabeledDataSequence::setLabel(
+ const uno::Reference< chart2::data::XDataSequence >& xSequence )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ m_aLabel = xSequence;
+}
+
+// XCloneable ================================================================
+
+uno::Reference< util::XCloneable > SAL_CALL ScChart2LabeledDataSequence::createClone()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< util::XCloneable > xToClone(m_aData, uno::UNO_QUERY);
+ if (xToClone.is())
+ {
+ ScChart2LabeledDataSequence* pRet = new ScChart2LabeledDataSequence(m_pDocument);
+ uno::Reference< chart2::data::XDataSequence > xSequence(xToClone->createClone(), uno::UNO_QUERY);
+ pRet->setValues(xSequence);
+ xToClone.set(m_aLabel, uno::UNO_QUERY);
+ if(xToClone.is())
+ {
+ xSequence.set(xToClone->createClone(), uno::UNO_QUERY);
+ pRet->setLabel(xSequence);
+ }
+ return pRet;
+ }
+ return NULL;
+}
+
+// XModifyBroadcaster ========================================================
+
+void SAL_CALL ScChart2LabeledDataSequence::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ // quick'n dirty: just add the listener to each DataSequence
+
+ uno::Reference<util::XModifyBroadcaster> xDataBroadcaster( m_aData, uno::UNO_QUERY );
+ if ( xDataBroadcaster.is() )
+ xDataBroadcaster->addModifyListener( aListener );
+ uno::Reference<util::XModifyBroadcaster> xLabelBroadcaster( m_aLabel, uno::UNO_QUERY );
+ if ( xLabelBroadcaster.is() )
+ xLabelBroadcaster->addModifyListener( aListener );
+}
+
+void SAL_CALL ScChart2LabeledDataSequence::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<util::XModifyBroadcaster> xDataBroadcaster( m_aData, uno::UNO_QUERY );
+ if ( xDataBroadcaster.is() )
+ xDataBroadcaster->removeModifyListener( aListener );
+ uno::Reference<util::XModifyBroadcaster> xLabelBroadcaster( m_aLabel, uno::UNO_QUERY );
+ if ( xLabelBroadcaster.is() )
+ xLabelBroadcaster->removeModifyListener( aListener );
+}
+
+// DataSequence ==============================================================
+
+ScChart2DataSequence::Item::Item() :
+ mfValue(0.0), mbIsValue(false)
+{
+ ::rtl::math::setNan(&mfValue);
+}
+
+ScChart2DataSequence::HiddenRangeListener::HiddenRangeListener(ScChart2DataSequence& rParent) :
+ mrParent(rParent)
+{
+}
+
+ScChart2DataSequence::HiddenRangeListener::~HiddenRangeListener()
+{
+}
+
+void ScChart2DataSequence::HiddenRangeListener::notify()
+{
+ mrParent.setDataChangedHint(true);
+}
+
+ScChart2DataSequence::ScChart2DataSequence( ScDocument* pDoc,
+ const uno::Reference < chart2::data::XDataProvider >& xDP,
+ vector<ScSharedTokenRef>* pTokens,
+ bool bIncludeHiddenCells )
+ : m_bIncludeHiddenCells( bIncludeHiddenCells)
+ , m_nObjectId( 0 )
+ , m_pDocument( pDoc)
+ , m_pTokens(pTokens)
+ , m_pRangeIndices(NULL)
+ , m_pExtRefListener(NULL)
+ , m_xDataProvider( xDP)
+ , m_aPropSet(lcl_GetDataSequencePropertyMap())
+ , m_pHiddenListener(NULL)
+ , m_pValueListener( NULL )
+ , m_bGotDataChangedHint(false)
+ , m_bExtDataRebuildQueued(false)
+{
+ DBG_ASSERT(pTokens, "reference token list is null");
+
+ if ( m_pDocument )
+ {
+ m_pDocument->AddUnoObject( *this);
+ m_nObjectId = m_pDocument->GetNewUnoId();
+ }
+ // FIXME: real implementation of identifier and it's mapping to ranges.
+ // Reuse ScChartListener?
+
+ // BM: don't use names of named ranges but the UI range strings
+// String aStr;
+// rRangeList->Format( aStr, SCR_ABS_3D, m_pDocument );
+// m_aIdentifier = ::rtl::OUString( aStr );
+
+// m_aIdentifier = ::rtl::OUString::createFromAscii( "ID_");
+// static sal_Int32 nID = 0;
+// m_aIdentifier += ::rtl::OUString::valueOf( ++nID);
+}
+
+ScChart2DataSequence::~ScChart2DataSequence()
+{
+ if ( m_pDocument )
+ {
+ m_pDocument->RemoveUnoObject( *this);
+ if (m_pHiddenListener.get())
+ {
+ ScChartListenerCollection* pCLC = m_pDocument->GetChartListenerCollection();
+ if (pCLC)
+ pCLC->EndListeningHiddenRange(m_pHiddenListener.get());
+ }
+ StopListeningToAllExternalRefs();
+ }
+
+ delete m_pValueListener;
+}
+
+void ScChart2DataSequence::RefChanged()
+{
+ if( m_pValueListener && m_aValueListeners.Count() != 0 )
+ {
+ m_pValueListener->EndListeningAll();
+
+ if( m_pDocument )
+ {
+ ScChartListenerCollection* pCLC = NULL;
+ if (m_pHiddenListener.get())
+ {
+ pCLC = m_pDocument->GetChartListenerCollection();
+ if (pCLC)
+ pCLC->EndListeningHiddenRange(m_pHiddenListener.get());
+ }
+
+ vector<ScSharedTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScRange aRange;
+ if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr))
+ continue;
+
+ m_pDocument->StartListeningArea(aRange, m_pValueListener);
+ if (pCLC)
+ pCLC->StartListeningHiddenRange(aRange, m_pHiddenListener.get());
+ }
+ }
+ }
+}
+
+void ScChart2DataSequence::BuildDataCache()
+{
+ m_bExtDataRebuildQueued = false;
+
+ if (!m_aDataArray.empty())
+ return;
+
+ if (!m_pTokens.get())
+ {
+ DBG_ERROR("m_pTokens == NULL! Something is wrong.");
+ return;
+ }
+
+ StopListeningToAllExternalRefs();
+
+ ::std::list<sal_Int32> aHiddenValues;
+ sal_Int32 nDataCount = 0;
+ sal_Int32 nHiddenValueCount = 0;
+
+ for (vector<ScSharedTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
+ itr != itrEnd; ++itr)
+ {
+ if (ScRefTokenHelper::isExternalRef(*itr))
+ {
+ nDataCount += FillCacheFromExternalRef(*itr);
+ }
+ else
+ {
+ ScRange aRange;
+ if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr))
+ continue;
+
+ SCCOL nLastCol = -1;
+ SCROW nLastRow = -1;
+ for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); ++nTab)
+ {
+ for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
+ {
+ for (SCROW nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow)
+ {
+ bool bColHidden = m_pDocument->ColHidden(nCol, nTab, nLastCol);
+ bool bRowHidden = m_pDocument->RowHidden(nRow, nTab, nLastRow);
+
+ if (bColHidden || bRowHidden)
+ {
+ // hidden cell
+ ++nHiddenValueCount;
+ aHiddenValues.push_back(nDataCount-1);
+
+ if( !m_bIncludeHiddenCells )
+ continue;
+ }
+
+ m_aDataArray.push_back(Item());
+ Item& rItem = m_aDataArray.back();
+ ++nDataCount;
+
+ ScAddress aAdr(nCol, nRow, nTab);
+ ScBaseCell* pCell = m_pDocument->GetCell(aAdr);
+ if (!pCell)
+ continue;
+
+ if (pCell->HasStringData())
+ rItem.maString = pCell->GetStringData();
+ else
+ {
+ String aStr;
+ m_pDocument->GetString(nCol, nRow, nTab, aStr);
+ rItem.maString = aStr;
+ }
+
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ rItem.mfValue = static_cast< ScValueCell*>(pCell)->GetValue();
+ rItem.mbIsValue = true;
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ USHORT nErr = pFCell->GetErrCode();
+ if (nErr)
+ break;
+
+ if (pFCell->HasValueData())
+ {
+ rItem.mfValue = pFCell->GetValue();
+ rItem.mbIsValue = true;
+ }
+ }
+ break;
+#if DBG_UTIL
+ case CELLTYPE_DESTROYED:
+#endif
+ case CELLTYPE_EDIT:
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ case CELLTYPE_STRING:
+ case CELLTYPE_SYMBOLS:
+ default:
+ ; // do nothing
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // convert the hidden cell list to sequence.
+ m_aHiddenValues.realloc(nHiddenValueCount);
+ sal_Int32* pArr = m_aHiddenValues.getArray();
+ ::std::list<sal_Int32>::const_iterator itr = aHiddenValues.begin(), itrEnd = aHiddenValues.end();
+ for (;itr != itrEnd; ++itr, ++pArr)
+ *pArr = *itr;
+
+ // Clear the data series cache when the array is re-built.
+ m_aMixedDataCache.realloc(0);
+}
+
+void ScChart2DataSequence::RebuildDataCache()
+{
+ if (!m_bExtDataRebuildQueued)
+ {
+ m_aDataArray.clear();
+ m_pDocument->BroadcastUno(ScHint(SC_HINT_DATACHANGED, ScAddress(), NULL));
+ m_bExtDataRebuildQueued = true;
+ m_bGotDataChangedHint = true;
+ }
+}
+
+sal_Int32 ScChart2DataSequence::FillCacheFromExternalRef(const ScSharedTokenRef& pToken)
+{
+ ScExternalRefManager* pRefMgr = m_pDocument->GetExternalRefManager();
+ ScRange aRange;
+ if (!ScRefTokenHelper::getRangeFromToken(aRange, pToken, true))
+ return 0;
+
+ sal_uInt16 nFileId = pToken->GetIndex();
+ const String& rTabName = pToken->GetString();
+ ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, aRange, NULL);
+ if (!pArray)
+ // no external data exists for this range.
+ return 0;
+
+ // Start listening for this external document.
+ ExternalRefListener* pExtRefListener = GetExtRefListener();
+ pRefMgr->addLinkListener(nFileId, pExtRefListener);
+ pExtRefListener->addFileId(nFileId);
+
+ ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, rTabName, false, NULL);
+ sal_Int32 nDataCount = 0;
+ for (FormulaToken* p = pArray->First(); p; p = pArray->Next())
+ {
+ // Cached external range is always represented as a single
+ // matrix token, although that might change in the future when
+ // we introduce a new token type to store multi-table range
+ // data.
+
+ if (p->GetType() != svMatrix)
+ {
+ DBG_ERROR("Cached array is not a matrix token.");
+ continue;
+ }
+
+ const ScMatrix* pMat = static_cast<ScToken*>(p)->GetMatrix();
+ SCSIZE nCSize, nRSize;
+ pMat->GetDimensions(nCSize, nRSize);
+ for (SCSIZE nC = 0; nC < nCSize; ++nC)
+ {
+ for (SCSIZE nR = 0; nR < nRSize; ++nR)
+ {
+ if (pMat->IsValue(nC, nR) || pMat->IsBoolean(nC, nR))
+ {
+ m_aDataArray.push_back(Item());
+ Item& rItem = m_aDataArray.back();
+ ++nDataCount;
+
+ rItem.mbIsValue = true;
+ rItem.mfValue = pMat->GetDouble(nC, nR);
+
+ SvNumberFormatter* pFormatter = m_pDocument->GetFormatTable();
+ if (pFormatter)
+ {
+ String aStr;
+ const double fVal = rItem.mfValue;
+ Color* pColor = NULL;
+ sal_uInt32 nFmt = 0;
+ if (pTable)
+ {
+ // Get the correct format index from the cache.
+ SCCOL nCol = aRange.aStart.Col() + static_cast<SCCOL>(nC);
+ SCROW nRow = aRange.aStart.Row() + static_cast<SCROW>(nR);
+ pTable->getCell(nCol, nRow, &nFmt);
+ }
+ pFormatter->GetOutputString(fVal, nFmt, aStr, &pColor);
+ rItem.maString = aStr;
+ }
+ }
+ else if (pMat->IsString(nC, nR))
+ {
+ m_aDataArray.push_back(Item());
+ Item& rItem = m_aDataArray.back();
+ ++nDataCount;
+
+ rItem.mbIsValue = false;
+ rItem.maString = pMat->GetString(nC, nR);
+ }
+ }
+ }
+ }
+ return nDataCount;
+}
+
+void ScChart2DataSequence::UpdateTokensFromRanges(const ScRangeList& rRanges)
+{
+ if (!m_pRangeIndices.get())
+ return;
+
+ sal_uInt32 nCount = rRanges.Count();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ ScSharedTokenRef pToken;
+ ScRange* pRange = static_cast<ScRange*>(rRanges.GetObject(i));
+ DBG_ASSERT(pRange, "range object is NULL.");
+
+ ScRefTokenHelper::getTokenFromRange(pToken, *pRange);
+ sal_uInt32 nOrigPos = (*m_pRangeIndices)[i];
+ (*m_pTokens)[nOrigPos] = pToken;
+ }
+
+ RefChanged();
+
+ // any change of the range address is broadcast to value (modify) listeners
+ if ( m_aValueListeners.Count() )
+ m_bGotDataChangedHint = true;
+}
+
+ScChart2DataSequence::ExternalRefListener* ScChart2DataSequence::GetExtRefListener()
+{
+ if (!m_pExtRefListener.get())
+ m_pExtRefListener.reset(new ExternalRefListener(*this, m_pDocument));
+
+ return m_pExtRefListener.get();
+}
+
+void ScChart2DataSequence::StopListeningToAllExternalRefs()
+{
+ if (!m_pExtRefListener.get())
+ return;
+
+ const hash_set<sal_uInt16>& rFileIds = m_pExtRefListener->getAllFileIds();
+ hash_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
+ ScExternalRefManager* pRefMgr = m_pDocument->GetExternalRefManager();
+ for (; itr != itrEnd; ++itr)
+ pRefMgr->removeLinkListener(*itr, m_pExtRefListener.get());
+
+ m_pExtRefListener.reset(NULL);
+}
+
+void ScChart2DataSequence::CopyData(const ScChart2DataSequence& r)
+{
+ if (!m_pDocument)
+ {
+ DBG_ERROR("document instance is NULL!?");
+ return;
+ }
+
+ list<Item> aDataArray(r.m_aDataArray);
+ m_aDataArray.swap(aDataArray);
+
+ m_aHiddenValues = r.m_aHiddenValues;
+ m_aRole = r.m_aRole;
+
+ if (r.m_pRangeIndices.get())
+ m_pRangeIndices.reset(new vector<sal_uInt32>(*r.m_pRangeIndices));
+
+ if (r.m_pExtRefListener.get())
+ {
+ // Re-register all external files that the old instance was
+ // listening to.
+
+ ScExternalRefManager* pRefMgr = m_pDocument->GetExternalRefManager();
+ m_pExtRefListener.reset(new ExternalRefListener(*this, m_pDocument));
+ const hash_set<sal_uInt16>& rFileIds = r.m_pExtRefListener->getAllFileIds();
+ hash_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ pRefMgr->addLinkListener(*itr, m_pExtRefListener.get());
+ m_pExtRefListener->addFileId(*itr);
+ }
+ }
+}
+
+void ScChart2DataSequence::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = static_cast<const SfxSimpleHint&>(rHint).GetId();
+ if ( nId ==SFX_HINT_DYING )
+ {
+ m_pDocument = NULL;
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // delayed broadcast as in ScCellRangesBase
+
+ if ( m_bGotDataChangedHint && m_pDocument )
+ {
+ m_aDataArray.clear();
+ lang::EventObject aEvent;
+ aEvent.Source.set((cppu::OWeakObject*)this);
+
+ if( m_pDocument )
+ {
+ for ( USHORT n=0; n<m_aValueListeners.Count(); n++ )
+ m_pDocument->AddUnoListenerCall( *m_aValueListeners[n], aEvent );
+ }
+
+ m_bGotDataChangedHint = false;
+ }
+ }
+ else if ( nId == SC_HINT_CALCALL )
+ {
+ // broadcast from DoHardRecalc - set m_bGotDataChangedHint
+ // (SFX_HINT_DATACHANGED follows separately)
+
+ if ( m_aValueListeners.Count() )
+ m_bGotDataChangedHint = true;
+ }
+ }
+ else if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+ // Create a range list from the token list, have the range list
+ // updated, and bring the change back to the token list.
+
+ ScRangeList aRanges;
+ m_pRangeIndices.reset(new vector<sal_uInt32>());
+ vector<ScSharedTokenRef>::const_iterator itrBeg = m_pTokens->begin(), itrEnd = m_pTokens->end();
+ for (vector<ScSharedTokenRef>::const_iterator itr = itrBeg ;itr != itrEnd; ++itr)
+ {
+ if (!ScRefTokenHelper::isExternalRef(*itr))
+ {
+ ScRange aRange;
+ ScRefTokenHelper::getRangeFromToken(aRange, *itr);
+ aRanges.Append(aRange);
+ sal_uInt32 nPos = distance(itrBeg, itr);
+ m_pRangeIndices->push_back(nPos);
+ }
+ }
+
+ DBG_ASSERT(m_pRangeIndices->size() == static_cast<size_t>(aRanges.Count()),
+ "range list and range index list have different sizes.");
+
+ auto_ptr<ScRangeList> pUndoRanges;
+ if ( m_pDocument->HasUnoRefUndo() )
+ pUndoRanges.reset(new ScRangeList(aRanges));
+
+ const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+ bool bChanged = aRanges.UpdateReference(
+ rRef.GetMode(), m_pDocument, rRef.GetRange(), rRef.GetDx(), rRef.GetDy(), rRef.GetDz());
+
+ if (bChanged)
+ {
+ DBG_ASSERT(m_pRangeIndices->size() == static_cast<size_t>(aRanges.Count()),
+ "range list and range index list have different sizes after the reference update.");
+
+ // Bring the change back from the range list to the token list.
+ UpdateTokensFromRanges(aRanges);
+
+ if (pUndoRanges.get())
+ m_pDocument->AddUnoRefChange(m_nObjectId, *pUndoRanges);
+ }
+ }
+ else if ( rHint.ISA( ScUnoRefUndoHint ) )
+ {
+ const ScUnoRefUndoHint& rUndoHint = static_cast<const ScUnoRefUndoHint&>(rHint);
+
+ do
+ {
+ if (rUndoHint.GetObjectId() != m_nObjectId)
+ break;
+
+ // The hint object provides the old ranges. Restore the old state
+ // from these ranges.
+
+ if (!m_pRangeIndices.get() || m_pRangeIndices->empty())
+ {
+ DBG_ERROR(" faulty range indices");
+ break;
+ }
+
+ const ScRangeList& rRanges = rUndoHint.GetRanges();
+
+ sal_uInt32 nCount = rRanges.Count();
+ if (nCount != m_pRangeIndices->size())
+ {
+ DBG_ERROR("range count and range index count differ.");
+ break;
+ }
+
+ UpdateTokensFromRanges(rRanges);
+ }
+ while (false);
+ }
+}
+
+
+IMPL_LINK( ScChart2DataSequence, ValueListenerHdl, SfxHint*, pHint )
+{
+ if ( m_pDocument && pHint && pHint->ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint*)pHint)->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING) )
+ {
+ // This may be called several times for a single change, if several formulas
+ // in the range are notified. So only a flag is set that is checked when
+ // SFX_HINT_DATACHANGED is received.
+
+ setDataChangedHint(true);
+ }
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+ScChart2DataSequence::ExternalRefListener::ExternalRefListener(
+ ScChart2DataSequence& rParent, ScDocument* pDoc) :
+ ScExternalRefManager::LinkListener(),
+ mrParent(rParent),
+ mpDoc(pDoc)
+{
+}
+
+ScChart2DataSequence::ExternalRefListener::~ExternalRefListener()
+{
+ if (!mpDoc || mpDoc->IsInDtorClear())
+ // The document is being destroyed. Do nothing.
+ return;
+
+ // Make sure to remove all pointers to this object.
+ mpDoc->GetExternalRefManager()->removeLinkListener(this);
+}
+
+void ScChart2DataSequence::ExternalRefListener::notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType)
+{
+ switch (eType)
+ {
+ case ScExternalRefManager::LINK_MODIFIED:
+ {
+ if (maFileIds.count(nFileId))
+ // We are listening to this external document.
+ mrParent.RebuildDataCache();
+ }
+ break;
+ case ScExternalRefManager::LINK_BROKEN:
+ removeFileId(nFileId);
+ break;
+ }
+}
+
+void ScChart2DataSequence::ExternalRefListener::addFileId(sal_uInt16 nFileId)
+{
+ maFileIds.insert(nFileId);
+}
+
+void ScChart2DataSequence::ExternalRefListener::removeFileId(sal_uInt16 nFileId)
+{
+ maFileIds.erase(nFileId);
+}
+
+const hash_set<sal_uInt16>& ScChart2DataSequence::ExternalRefListener::getAllFileIds()
+{
+ return maFileIds;
+}
+
+// ----------------------------------------------------------------------------
+
+uno::Sequence< uno::Any> SAL_CALL ScChart2DataSequence::getData()
+ throw ( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ throw uno::RuntimeException();
+
+ BuildDataCache();
+
+ if (!m_aMixedDataCache.getLength())
+ {
+ // Build a cache for the 1st time...
+
+ sal_Int32 nCount = m_aDataArray.size();
+ m_aMixedDataCache.realloc(nCount);
+ uno::Any* pArr = m_aMixedDataCache.getArray();
+ ::std::list<Item>::const_iterator itr = m_aDataArray.begin(), itrEnd = m_aDataArray.end();
+ for (; itr != itrEnd; ++itr, ++pArr)
+ {
+ if (itr->mbIsValue)
+ *pArr <<= itr->mfValue;
+ else
+ *pArr <<= itr->maString;
+ }
+ }
+ return m_aMixedDataCache;
+}
+
+// XNumericalDataSequence --------------------------------------------------
+
+uno::Sequence< double > SAL_CALL ScChart2DataSequence::getNumericalData()
+ throw ( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ throw uno::RuntimeException();
+
+ BuildDataCache();
+
+ double fNAN;
+ ::rtl::math::setNan(&fNAN);
+
+ sal_Int32 nCount = m_aDataArray.size();
+ uno::Sequence<double> aSeq(nCount);
+ double* pArr = aSeq.getArray();
+ ::std::list<Item>::const_iterator itr = m_aDataArray.begin(), itrEnd = m_aDataArray.end();
+ for (; itr != itrEnd; ++itr, ++pArr)
+ *pArr = itr->mbIsValue ? itr->mfValue : fNAN;
+
+ return aSeq;
+}
+
+// XTextualDataSequence --------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL ScChart2DataSequence::getTextualData( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ throw uno::RuntimeException();
+
+ BuildDataCache();
+
+ sal_Int32 nCount = m_aDataArray.size();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pArr = aSeq.getArray();
+ ::std::list<Item>::const_iterator itr = m_aDataArray.begin(), itrEnd = m_aDataArray.end();
+ for (; itr != itrEnd; ++itr, ++pArr)
+ *pArr = itr->maString;
+
+ return aSeq;
+}
+
+::rtl::OUString SAL_CALL ScChart2DataSequence::getSourceRangeRepresentation()
+ throw ( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ OUString aStr;
+ DBG_ASSERT( m_pDocument, "No Document -> no SourceRangeRepresentation" );
+ if (m_pDocument && m_pTokens.get())
+ lcl_convertTokensToString(aStr, *m_pTokens, m_pDocument);
+
+ return aStr;
+}
+
+namespace {
+
+/**
+ * This function object is used to accumulatively count the numbers of
+ * columns and rows in all reference tokens.
+ */
+class AccumulateRangeSize : public unary_function<ScSharedTokenRef, void>
+{
+public:
+ AccumulateRangeSize() :
+ mnCols(0), mnRows(0) {}
+
+ AccumulateRangeSize(const AccumulateRangeSize& r) :
+ mnCols(r.mnCols), mnRows(r.mnRows) {}
+
+ void operator() (const ScSharedTokenRef& pToken)
+ {
+ ScRange r;
+ bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
+ ScRefTokenHelper::getRangeFromToken(r, pToken, bExternal);
+ r.Justify();
+ mnCols += r.aEnd.Col() - r.aStart.Col() + 1;
+ mnRows += r.aEnd.Row() - r.aStart.Row() + 1;
+ }
+
+ SCCOL getCols() const { return mnCols; }
+ SCROW getRows() const { return mnRows; }
+private:
+ SCCOL mnCols;
+ SCROW mnRows;
+};
+
+/**
+ * This function object is used to generate label strings from a list of
+ * reference tokens.
+ */
+class GenerateLabelStrings : public unary_function<ScSharedTokenRef, void>
+{
+public:
+ GenerateLabelStrings(sal_Int32 nSize, chart2::data::LabelOrigin eOrigin, bool bColumn) :
+ mpLabels(new Sequence<OUString>(nSize)),
+ meOrigin(eOrigin),
+ mnCount(0),
+ mbColumn(bColumn) {}
+
+ GenerateLabelStrings(const GenerateLabelStrings& r) :
+ mpLabels(r.mpLabels),
+ meOrigin(r.meOrigin),
+ mnCount(r.mnCount),
+ mbColumn(r.mbColumn) {}
+
+ void operator() (const ScSharedTokenRef& pToken)
+ {
+ bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
+ ScRange aRange;
+ ScRefTokenHelper::getRangeFromToken(aRange, pToken, bExternal);
+ OUString* pArr = mpLabels->getArray();
+ if (mbColumn)
+ {
+ for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
+ {
+ if ( meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
+ {
+ String aString = ScGlobal::GetRscString(STR_COLUMN);
+ aString += ' ';
+ ScAddress aPos( nCol, 0, 0 );
+ String aColStr;
+ aPos.Format( aColStr, SCA_VALID_COL, NULL );
+ aString += aColStr;
+ pArr[mnCount] = aString;
+ }
+ else //only indices for categories
+ pArr[mnCount] = String::CreateFromInt32( mnCount+1 );
+ ++mnCount;
+ }
+ }
+ else
+ {
+ for (sal_Int32 nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow)
+ {
+ if (meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
+ {
+ String aString = ScGlobal::GetRscString(STR_ROW);
+ aString += ' ';
+ aString += String::CreateFromInt32( nRow+1 );
+ pArr[mnCount] = aString;
+ }
+ else //only indices for categories
+ pArr[mnCount] = String::CreateFromInt32( mnCount+1 );
+ ++mnCount;
+ }
+ }
+ }
+
+ Sequence<OUString> getLabels() const { return *mpLabels; }
+
+private:
+ GenerateLabelStrings(); // disabled
+
+ shared_ptr< Sequence<OUString> > mpLabels;
+ chart2::data::LabelOrigin meOrigin;
+ sal_Int32 mnCount;
+ bool mbColumn;
+};
+
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL ScChart2DataSequence::generateLabel(chart2::data::LabelOrigin eOrigin)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ throw uno::RuntimeException();
+
+ if (!m_pTokens.get())
+ return Sequence<OUString>();
+
+ // Determine the total size of all ranges.
+ AccumulateRangeSize func;
+ func = for_each(m_pTokens->begin(), m_pTokens->end(), func);
+ SCCOL nCols = func.getCols();
+ SCROW nRows = func.getRows();
+
+ // Detemine whether this is column-major or row-major.
+ bool bColumn = true;
+ if ((eOrigin == chart2::data::LabelOrigin_SHORT_SIDE) ||
+ (eOrigin == chart2::data::LabelOrigin_LONG_SIDE))
+ {
+ if (nRows > nCols)
+ {
+ if (eOrigin == chart2::data::LabelOrigin_SHORT_SIDE)
+ bColumn = true;
+ else
+ bColumn = false;
+ }
+ else if (nCols > nRows)
+ {
+ if (eOrigin == chart2::data::LabelOrigin_SHORT_SIDE)
+ bColumn = false;
+ else
+ bColumn = true;
+ }
+ else
+ return Sequence<OUString>();
+ }
+
+ // Generate label strings based on the info so far.
+ sal_Int32 nCount = bColumn ? nCols : nRows;
+ GenerateLabelStrings genLabels(nCount, eOrigin, bColumn);
+ genLabels = for_each(m_pTokens->begin(), m_pTokens->end(), genLabels);
+ Sequence<OUString> aSeq = genLabels.getLabels();
+
+ return aSeq;
+}
+
+::sal_Int32 SAL_CALL ScChart2DataSequence::getNumberFormatKeyByIndex( ::sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException,
+ uno::RuntimeException)
+{
+ // index -1 means a heuristic value for the entire sequence
+ bool bGetSeriesFormat = (nIndex == -1);
+ sal_Int32 nResult = 0;
+
+ ScUnoGuard aGuard;
+ if ( !m_pDocument || !m_pTokens.get())
+ return nResult;
+
+ sal_Int32 nCount = 0;
+ bool bFound = false;
+ ScRangePtr p;
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( lcl_GetSpreadSheetDocument( m_pDocument ));
+ if (!xSpreadDoc.is())
+ return nResult;
+
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if (!xIndex.is())
+ return nResult;
+
+ ScRangeList aRanges;
+ ScRefTokenHelper::getRangeListFromTokens(aRanges, *m_pTokens);
+ uno::Reference< table::XCellRange > xSheet;
+ for ( p = aRanges.First(); p && !bFound; p = aRanges.Next())
+ {
+ // TODO: use DocIter?
+ table::CellAddress aStart, aEnd;
+ ScUnoConversion::FillApiAddress( aStart, p->aStart );
+ ScUnoConversion::FillApiAddress( aEnd, p->aEnd );
+ for ( sal_Int16 nSheet = aStart.Sheet; nSheet <= aEnd.Sheet && !bFound; ++nSheet)
+ {
+ xSheet.set(xIndex->getByIndex(nSheet), uno::UNO_QUERY);
+ for ( sal_Int32 nCol = aStart.Column; nCol <= aEnd.Column && !bFound; ++nCol)
+ {
+ for ( sal_Int32 nRow = aStart.Row; nRow <= aEnd.Row && !bFound; ++nRow)
+ {
+ if( bGetSeriesFormat )
+ {
+ // TODO: use nicer heuristic
+ // return format of first non-empty cell
+ uno::Reference< text::XText > xText(
+ xSheet->getCellByPosition(nCol, nRow), uno::UNO_QUERY);
+ if (xText.is() && xText->getString().getLength())
+ {
+ uno::Reference< beans::XPropertySet > xProp(xText, uno::UNO_QUERY);
+ if( xProp.is())
+ xProp->getPropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))) >>= nResult;
+ bFound = true;
+ break;
+ }
+ }
+ else if( nCount == nIndex )
+ {
+ uno::Reference< beans::XPropertySet > xProp(
+ xSheet->getCellByPosition(nCol, nRow), uno::UNO_QUERY);
+ if( xProp.is())
+ xProp->getPropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))) >>= nResult;
+ bFound = true;
+ break;
+ }
+ ++nCount;
+ }
+ }
+ }
+ }
+
+ return nResult;
+}
+
+// XCloneable ================================================================
+
+uno::Reference< util::XCloneable > SAL_CALL ScChart2DataSequence::createClone()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ auto_ptr< vector<ScSharedTokenRef> > pTokensNew;
+ if (m_pTokens.get())
+ {
+ // Clone tokens.
+ pTokensNew.reset(new vector<ScSharedTokenRef>);
+ pTokensNew->reserve(m_pTokens->size());
+ vector<ScSharedTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScSharedTokenRef p(static_cast<ScToken*>((*itr)->Clone()));
+ pTokensNew->push_back(p);
+ }
+ }
+
+ auto_ptr<ScChart2DataSequence> p(new ScChart2DataSequence(m_pDocument, m_xDataProvider, pTokensNew.release(), m_bIncludeHiddenCells));
+ p->CopyData(*this);
+ Reference< util::XCloneable > xClone(p.release());
+
+ return xClone;
+}
+
+// XModifyBroadcaster ========================================================
+
+void SAL_CALL ScChart2DataSequence::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ // like ScCellRangesBase::addModifyListener
+ ScUnoGuard aGuard;
+ if (!m_pTokens.get() || m_pTokens->empty())
+ return;
+
+ ScRangeList aRanges;
+ ScRefTokenHelper::getRangeListFromTokens(aRanges, *m_pTokens);
+ uno::Reference<util::XModifyListener> *pObj =
+ new uno::Reference<util::XModifyListener>( aListener );
+ m_aValueListeners.Insert( pObj, m_aValueListeners.Count() );
+
+ if ( m_aValueListeners.Count() == 1 )
+ {
+ if (!m_pValueListener)
+ m_pValueListener = new ScLinkListener( LINK( this, ScChart2DataSequence, ValueListenerHdl ) );
+
+ if (!m_pHiddenListener.get())
+ m_pHiddenListener.reset(new HiddenRangeListener(*this));
+
+ if( m_pDocument )
+ {
+ ScChartListenerCollection* pCLC = m_pDocument->GetChartListenerCollection();
+ vector<ScSharedTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
+ for (; itr != itrEnd; ++itr)
+ {
+ ScRange aRange;
+ if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr))
+ continue;
+
+ m_pDocument->StartListeningArea( aRange, m_pValueListener );
+ if (pCLC)
+ pCLC->StartListeningHiddenRange(aRange, m_pHiddenListener.get());
+ }
+ }
+
+ acquire(); // don't lose this object (one ref for all listeners)
+ }
+}
+
+void SAL_CALL ScChart2DataSequence::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ // like ScCellRangesBase::removeModifyListener
+
+ ScUnoGuard aGuard;
+ if (!m_pTokens.get() || m_pTokens->empty())
+ return;
+
+ acquire(); // in case the listeners have the last ref - released below
+
+ USHORT nCount = m_aValueListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XModifyListener> *pObj = m_aValueListeners[n];
+ if ( *pObj == aListener )
+ {
+ m_aValueListeners.DeleteAndDestroy( n );
+
+ if ( m_aValueListeners.Count() == 0 )
+ {
+ if (m_pValueListener)
+ m_pValueListener->EndListeningAll();
+
+ if (m_pHiddenListener.get() && m_pDocument)
+ {
+ ScChartListenerCollection* pCLC = m_pDocument->GetChartListenerCollection();
+ if (pCLC)
+ pCLC->EndListeningHiddenRange(m_pHiddenListener.get());
+ }
+
+ release(); // release the ref for the listeners
+ }
+
+ break;
+ }
+ }
+
+ release(); // might delete this object
+}
+
+// DataSequence XPropertySet -------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo> SAL_CALL
+ScChart2DataSequence::getPropertySetInfo() throw( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
+ return aRef;
+}
+
+
+void SAL_CALL ScChart2DataSequence::setPropertyValue(
+ const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE)))
+ {
+ if ( !(rValue >>= m_aRole))
+ throw lang::IllegalArgumentException();
+ }
+ else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS)))
+ {
+ sal_Bool bOldValue = m_bIncludeHiddenCells;
+ if ( !(rValue >>= m_bIncludeHiddenCells))
+ throw lang::IllegalArgumentException();
+ if( bOldValue != m_bIncludeHiddenCells )
+ m_aDataArray.clear();//data array is dirty now
+ }
+ else
+ throw beans::UnknownPropertyException();
+ // TODO: support optional properties
+}
+
+
+uno::Any SAL_CALL ScChart2DataSequence::getPropertyValue(
+ const ::rtl::OUString& rPropertyName)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aRet;
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE)))
+ aRet <<= m_aRole;
+ else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS)))
+ aRet <<= m_bIncludeHiddenCells;
+ else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SC_UNONAME_HIDDENVALUES)))
+ {
+ // This property is read-only thus cannot be set externally via
+ // setPropertyValue(...).
+ BuildDataCache();
+ aRet <<= m_aHiddenValues;
+ }
+ else
+ throw beans::UnknownPropertyException();
+ // TODO: support optional properties
+ return aRet;
+}
+
+
+void SAL_CALL ScChart2DataSequence::addPropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2DataSequence::removePropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2DataSequence::addVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2DataSequence::removeVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+void ScChart2DataSequence::setDataChangedHint(bool b)
+{
+ m_bGotDataChangedHint = b;
+}
+
+// XUnoTunnel
+
+// sal_Int64 SAL_CALL ScChart2DataSequence::getSomething(
+// const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+// {
+// if ( rId.getLength() == 16 &&
+// 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+// rId.getConstArray(), 16 ) )
+// {
+// return (sal_Int64)this;
+// }
+// return 0;
+// }
+
+// // static
+// const uno::Sequence<sal_Int8>& ScChart2DataSequence::getUnoTunnelId()
+// {
+// static uno::Sequence<sal_Int8> * pSeq = 0;
+// if( !pSeq )
+// {
+// osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+// if( !pSeq )
+// {
+// static uno::Sequence< sal_Int8 > aSeq( 16 );
+// rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+// pSeq = &aSeq;
+// }
+// }
+// return *pSeq;
+// }
+
+// // static
+// ScChart2DataSequence* ScChart2DataSequence::getImplementation( const uno::Reference<uno::XInterface> xObj )
+// {
+// ScChart2DataSequence* pRet = NULL;
+// uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+// if (xUT.is())
+// pRet = (ScChart2DataSequence*) xUT->getSomething( getUnoTunnelId() );
+// return pRet;
+// }
+
+#if USE_CHART2_EMPTYDATASEQUENCE
+// DataSequence ==============================================================
+
+ScChart2EmptyDataSequence::ScChart2EmptyDataSequence( ScDocument* pDoc,
+ const uno::Reference < chart2::data::XDataProvider >& xDP,
+ const ScRangeListRef& rRangeList,
+ sal_Bool bColumn)
+ : m_bIncludeHiddenCells( sal_True)
+ , m_xRanges( rRangeList)
+ , m_pDocument( pDoc)
+ , m_xDataProvider( xDP)
+ , m_aPropSet(lcl_GetDataSequencePropertyMap())
+ , m_bColumn(bColumn)
+{
+ if ( m_pDocument )
+ m_pDocument->AddUnoObject( *this);
+ // FIXME: real implementation of identifier and it's mapping to ranges.
+ // Reuse ScChartListener?
+
+ // BM: don't use names of named ranges but the UI range strings
+// String aStr;
+// rRangeList->Format( aStr, SCR_ABS_3D, m_pDocument );
+// m_aIdentifier = ::rtl::OUString( aStr );
+
+// m_aIdentifier = ::rtl::OUString::createFromAscii( "ID_");
+// static sal_Int32 nID = 0;
+// m_aIdentifier += ::rtl::OUString::valueOf( ++nID);
+}
+
+
+ScChart2EmptyDataSequence::~ScChart2EmptyDataSequence()
+{
+ if ( m_pDocument )
+ m_pDocument->RemoveUnoObject( *this);
+}
+
+
+void ScChart2EmptyDataSequence::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ m_pDocument = NULL;
+ }
+}
+
+
+uno::Sequence< uno::Any> SAL_CALL ScChart2EmptyDataSequence::getData()
+ throw ( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ throw uno::RuntimeException();
+ return uno::Sequence< uno::Any>();
+}
+
+// XTextualDataSequence --------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL ScChart2EmptyDataSequence::getTextualData( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ throw uno::RuntimeException();
+
+ sal_Int32 nCount = 0;
+ ScRangePtr p;
+
+ DBG_ASSERT(m_xRanges->Count() == 1, "not handled count of ranges");
+
+ for ( p = m_xRanges->First(); p; p = m_xRanges->Next())
+ {
+ p->Justify();
+ // TODO: handle overlaping ranges?
+ nCount += m_bColumn ? p->aEnd.Col() - p->aStart.Col() + 1 : p->aEnd.Row() - p->aStart.Row() + 1;
+ }
+ uno::Sequence< rtl::OUString > aSeq( nCount);
+ rtl::OUString* pArr = aSeq.getArray();
+ nCount = 0;
+ for ( p = m_xRanges->First(); p; p = m_xRanges->Next())
+ {
+ if (m_bColumn)
+ {
+ for (SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
+ {
+ String aString = ScGlobal::GetRscString(STR_COLUMN);
+ aString += ' ';
+ ScAddress aPos( nCol, 0, 0 );
+ String aColStr;
+ aPos.Format( aColStr, SCA_VALID_COL, NULL );
+ aString += aColStr;
+ pArr[nCount] = aString;
+ ++nCount;
+ }
+ }
+ else
+ {
+ for (sal_Int32 nRow = p->aStart.Row(); nRow <= p->aEnd.Row(); ++nRow)
+ {
+ String aString = ScGlobal::GetRscString(STR_ROW);
+ aString += ' ';
+ aString += String::CreateFromInt32( nRow+1 );
+ pArr[nCount] = aString;
+ ++nCount;
+ }
+ }
+ }
+ return aSeq;
+}
+
+::rtl::OUString SAL_CALL ScChart2EmptyDataSequence::getSourceRangeRepresentation()
+ throw ( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aStr;
+ DBG_ASSERT( m_pDocument, "No Document -> no SourceRangeRepresentation" );
+ if( m_pDocument )
+ m_xRanges->Format( aStr, SCR_ABS_3D, m_pDocument, m_pDocument->GetAddressConvention() );
+ return aStr;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL ScChart2EmptyDataSequence::generateLabel(chart2::data::LabelOrigin /*nOrigin*/)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence< ::rtl::OUString > aRet;
+ return aRet;
+}
+
+::sal_Int32 SAL_CALL ScChart2EmptyDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 /*nIndex*/ )
+ throw (lang::IndexOutOfBoundsException,
+ uno::RuntimeException)
+{
+ sal_Int32 nResult = 0;
+
+ ScUnoGuard aGuard;
+ if ( !m_pDocument)
+ return nResult;
+
+ return nResult;
+}
+
+// XCloneable ================================================================
+
+uno::Reference< util::XCloneable > SAL_CALL ScChart2EmptyDataSequence::createClone()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (m_xDataProvider.is())
+ {
+ // copy properties
+ uno::Reference < util::XCloneable > xClone(new ScChart2EmptyDataSequence(m_pDocument, m_xDataProvider, new ScRangeList(*m_xRanges), m_bColumn));
+ uno::Reference< beans::XPropertySet > xProp( xClone, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ xProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ROLE )),
+ uno::makeAny( m_aRole ));
+ xProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS )),
+ uno::makeAny( m_bIncludeHiddenCells ));
+ }
+ return xClone;
+ }
+ return uno::Reference< util::XCloneable >();
+}
+
+// XModifyBroadcaster ========================================================
+
+void SAL_CALL ScChart2EmptyDataSequence::addModifyListener( const uno::Reference< util::XModifyListener >& /*aListener*/ )
+ throw (uno::RuntimeException)
+{
+ // TODO: Implement
+}
+
+void SAL_CALL ScChart2EmptyDataSequence::removeModifyListener( const uno::Reference< util::XModifyListener >& /*aListener*/ )
+ throw (uno::RuntimeException)
+{
+ // TODO: Implement
+}
+
+// DataSequence XPropertySet -------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo> SAL_CALL
+ScChart2EmptyDataSequence::getPropertySetInfo() throw( uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
+ return aRef;
+}
+
+
+void SAL_CALL ScChart2EmptyDataSequence::setPropertyValue(
+ const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE)))
+ {
+ if ( !(rValue >>= m_aRole))
+ throw lang::IllegalArgumentException();
+ }
+ else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS)))
+ {
+ if ( !(rValue >>= m_bIncludeHiddenCells))
+ throw lang::IllegalArgumentException();
+ }
+ else
+ throw beans::UnknownPropertyException();
+ // TODO: support optional properties
+}
+
+
+uno::Any SAL_CALL ScChart2EmptyDataSequence::getPropertyValue(
+ const ::rtl::OUString& rPropertyName)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aRet;
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE)))
+ aRet <<= m_aRole;
+ else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS)))
+ aRet <<= m_bIncludeHiddenCells;
+ else
+ throw beans::UnknownPropertyException();
+ // TODO: support optional properties
+ return aRet;
+}
+
+
+void SAL_CALL ScChart2EmptyDataSequence::addPropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2EmptyDataSequence::removePropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2EmptyDataSequence::addVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+
+void SAL_CALL ScChart2EmptyDataSequence::removeVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/ )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ // FIXME: real implementation
+// throw uno::RuntimeException();
+ OSL_ENSURE( false, "Not yet implemented" );
+}
+
+// XUnoTunnel
+
+// sal_Int64 SAL_CALL ScChart2EmptyDataSequence::getSomething(
+// const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+// {
+// if ( rId.getLength() == 16 &&
+// 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+// rId.getConstArray(), 16 ) )
+// {
+// return (sal_Int64)this;
+// }
+// return 0;
+// }
+
+// // static
+// const uno::Sequence<sal_Int8>& ScChart2EmptyDataSequence::getUnoTunnelId()
+// {
+// static uno::Sequence<sal_Int8> * pSeq = 0;
+// if( !pSeq )
+// {
+// osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+// if( !pSeq )
+// {
+// static uno::Sequence< sal_Int8 > aSeq( 16 );
+// rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+// pSeq = &aSeq;
+// }
+// }
+// return *pSeq;
+// }
+
+// // static
+// ScChart2DataSequence* ScChart2EmptyDataSequence::getImplementation( const uno::Reference<uno::XInterface> xObj )
+// {
+// ScChart2DataSequence* pRet = NULL;
+// uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+// if (xUT.is())
+// pRet = (ScChart2EmptyDataSequence*) xUT->getSomething( getUnoTunnelId() );
+// return pRet;
+// }
+#endif
diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx
new file mode 100644
index 000000000000..86f59d66a7a4
--- /dev/null
+++ b/sc/source/ui/unoobj/chartuno.cxx
@@ -0,0 +1,817 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <sfx2/app.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sot/clsids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include "chartuno.hxx"
+#include "miscuno.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "undodat.hxx"
+#include "chartarr.hxx"
+#include "chartlis.hxx"
+#include "unoguard.hxx"
+#include "chart2uno.hxx"
+#include "convuno.hxx"
+
+using namespace com::sun::star;
+
+#define PROP_HANDLE_RELATED_CELLRANGES 1
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" )
+SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" )
+
+//------------------------------------------------------------------------
+
+SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const String& rName )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage, "Page nicht gefunden");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if ( xObj.is() )
+ {
+ String aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
+ if ( aObjName == rName )
+ return (SdrOle2Obj*)pObject;
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
+ pDocShell( pDocSh ),
+ nTab( nT )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScChartsObj::~ScChartsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! Referenz-Update
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const
+{
+ String aName;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage, "Page nicht gefunden");
+ if (pPage)
+ {
+ long nPos = 0;
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) )
+ {
+ if ( nPos == nIndex )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if ( xObj.is() )
+ aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
+ break; // nicht weitersuchen
+ }
+ ++nPos;
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+
+ if (aName.Len())
+ return new ScChartObj( pDocShell, nTab, aName );
+ return NULL;
+}
+
+ScChartObj* ScChartsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
+{
+ String aNameString(aName);
+ if ( lcl_FindChartObj( pDocShell, nTab, aNameString ) )
+ return new ScChartObj( pDocShell, nTab, aNameString );
+ return NULL;
+}
+
+// XTableCharts
+
+void SAL_CALL ScChartsObj::addNewByName( const rtl::OUString& aName,
+ const awt::Rectangle& aRect,
+ const uno::Sequence<table::CellRangeAddress>& aRanges,
+ sal_Bool bColumnHeaders, sal_Bool bRowHeaders )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ return;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"addChart: keine Page");
+ if (!pPage || !pDoc)
+ return;
+
+ // chart can't be inserted if any ole object with that name exists on any table
+ // (empty string: generate valid name)
+
+ String aNameString(aName);
+ SCTAB nDummy;
+ if ( aNameString.Len() && pModel->GetNamedObject( aNameString, OBJ_OLE2, nDummy ) )
+ {
+ // object exists - only RuntimeException is specified
+ throw uno::RuntimeException();
+ }
+
+ ScRangeList* pList = new ScRangeList;
+ USHORT nRangeCount = (USHORT)aRanges.getLength();
+ if (nRangeCount)
+ {
+ const table::CellRangeAddress* pAry = aRanges.getConstArray();
+ for (USHORT i=0; i<nRangeCount; i++)
+ {
+ ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet,
+ static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet );
+ pList->Append( aRange );
+ }
+ }
+ ScRangeListRef xNewRanges( pList );
+
+ uno::Reference < embed::XEmbeddedObject > xObj;
+ ::rtl::OUString aTmp( aNameString );
+ if ( SvtModuleOptions().IsChart() )
+ xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aTmp );
+ if ( xObj.is() )
+ {
+ String aObjName = aTmp; // wirklich eingefuegter Name...
+
+ // Rechteck anpassen
+ //! Fehler/Exception, wenn leer/ungueltig ???
+ Point aRectPos( aRect.X, aRect.Y );
+ if (aRectPos.X() < 0) aRectPos.X() = 0;
+ if (aRectPos.Y() < 0) aRectPos.Y() = 0;
+ Size aRectSize( aRect.Width, aRect.Height );
+ if (aRectSize.Width() <= 0) aRectSize.Width() = 5000; // Default-Groesse
+ if (aRectSize.Height() <= 0) aRectSize.Height() = 5000;
+ Rectangle aInsRect( aRectPos, aRectSize );
+
+ sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
+ MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ));
+ Size aSize(aInsRect.GetSize());
+ aSize = Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) );
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+
+ // Calc -> DataProvider
+ uno::Reference< chart2::data::XDataProvider > xDataProvider = new
+ ScChart2DataProvider( pDoc );
+ // Chart -> DataReceiver
+ uno::Reference< chart2::data::XDataReceiver > xReceiver;
+ uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
+ if( xCompSupp.is())
+ xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
+ if( xReceiver.is())
+ {
+ String sRangeStr;
+ xNewRanges->Format(sRangeStr, SCR_ABS_3D, pDoc);
+
+ // connect
+ if( sRangeStr.Len() )
+ xReceiver->attachDataProvider( xDataProvider );
+ else
+ sRangeStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "all" ) );
+
+ uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
+ xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
+
+ // set arguments
+ uno::Sequence< beans::PropertyValue > aArgs( 4 );
+ aArgs[0] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
+ uno::makeAny( ::rtl::OUString( sRangeStr )), beans::PropertyState_DIRECT_VALUE );
+ aArgs[1] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("HasCategories"), -1,
+ uno::makeAny( bRowHeaders ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[2] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
+ uno::makeAny( bColumnHeaders ), beans::PropertyState_DIRECT_VALUE );
+ aArgs[3] = beans::PropertyValue(
+ ::rtl::OUString::createFromAscii("DataRowSource"), -1,
+ uno::makeAny( chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE );
+ xReceiver->setArguments( aArgs );
+ }
+
+ ScChartListener* pChartListener =
+ new ScChartListener( aObjName, pDoc, xNewRanges );
+ pDoc->GetChartListenerCollection()->Insert( pChartListener );
+ pChartListener->StartListeningTo();
+
+ SdrOle2Obj* pObj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aObjName, aInsRect );
+
+ // set VisArea
+ if( xObj.is())
+ xObj->setVisualAreaSize( nAspect, aSz );
+
+ pPage->InsertObject( pObj );
+ pModel->AddUndo( new SdrUndoInsertObj( *pObj ) ); //! Undo-Kommentar?
+
+ // Dies veranlaesst Chart zum sofortigen Update
+ //SvData aEmpty;
+ //aIPObj->SendDataChanged( aEmpty );
+ }
+}
+
+void SAL_CALL ScChartsObj::removeByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aName);
+ SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aNameString );
+ if (pObj)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pModel = pDoc->GetDrawLayer(); // ist nicht 0
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // ist nicht 0
+
+ pModel->AddUndo( new SdrUndoRemoveObj( *pObj ) ); //! Undo-Kommentar?
+ pPage->RemoveObject( pObj->GetOrdNum() );
+
+ //! Notify etc.???
+ }
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableChartsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScChartsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ INT32 nCount = 0;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage, "Page nicht gefunden");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) )
+ ++nCount;
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XTableChart> xChart(GetObjectByIndex_Impl(nIndex));
+ if (xChart.is())
+ return uno::makeAny(xChart);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScChartsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<table::XTableChart>*)0);
+}
+
+sal_Bool SAL_CALL ScChartsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCount() != 0;
+}
+
+uno::Any SAL_CALL ScChartsObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName));
+ if (xChart.is())
+ return uno::makeAny(xChart);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScChartsObj::getElementNames() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ long nCount = getCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+
+ long nPos = 0;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage, "Page nicht gefunden");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) )
+ {
+ String aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if ( xObj.is() )
+ aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
+
+ DBG_ASSERT(nPos<nCount, "huch, verzaehlt?");
+ pAry[nPos++] = aName;
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ DBG_ASSERT(nPos==nCount, "nanu, verzaehlt?");
+
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+sal_Bool SAL_CALL ScChartsObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aName);
+ return ( lcl_FindChartObj( pDocShell, nTab, aNameString ) != NULL );
+}
+
+//------------------------------------------------------------------------
+
+ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN)
+ :ScChartObj_Base( m_aMutex )
+ ,ScChartObj_PBase( ScChartObj_Base::rBHelper )
+ ,pDocShell( pDocSh )
+ ,nTab( nT )
+ ,aChartName( rN )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ uno::Sequence< table::CellRangeAddress > aInitialPropValue;
+ registerPropertyNoMember( ::rtl::OUString::createFromAscii( "RelatedCellRanges" ),
+ PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID,
+ ::getCppuType( &aInitialPropValue ), &aInitialPropValue );
+}
+
+ScChartObj::~ScChartObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! Referenz-Update
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const
+{
+ bool bFound = false;
+ ScDocument* pDoc = (pDocShell? pDocShell->GetDocument(): 0);
+
+ if( pDoc )
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( pDoc->GetChartByName( aChartName ) );
+ if( xChartDoc.is() )
+ {
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
+ uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
+ if( xReceiver.is() && xProvider.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) );
+
+ rtl::OUString aRanges;
+ chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
+ bool bHasCategories=false;
+ bool bFirstCellAsLabel=false;
+ const beans::PropertyValue* pPropArray = aArgs.getConstArray();
+ long nPropCount = aArgs.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( "CellRangeRepresentation" ))
+ rProp.Value >>= aRanges;
+ else if (aPropName.EqualsAscii( "DataRowSource" ))
+ eDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( "HasCategories" ))
+ bHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( "FirstCellAsLabel" ))
+ bFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ }
+
+ if( chart::ChartDataRowSource_COLUMNS == eDataRowSource )
+ {
+ rColHeaders=bFirstCellAsLabel;
+ rRowHeaders=bHasCategories;
+ }
+ else
+ {
+ rColHeaders=bHasCategories;
+ rRowHeaders=bFirstCellAsLabel;
+ }
+ rRanges->Parse( aRanges, pDoc);
+ }
+ bFound = true;
+ }
+ }
+ if( !bFound )
+ {
+ rRanges = 0;
+ rColHeaders = false;
+ rRowHeaders = false;
+ }
+}
+
+void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if (bUndo)
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoChartData( pDocShell, aChartName, rRanges, bColHeaders, bRowHeaders, FALSE ) );
+ }
+ pDoc->UpdateChartArea( aChartName, rRanges, bColHeaders, bRowHeaders, FALSE );
+ }
+}
+
+// ::comphelper::OPropertySetHelper
+
+::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper()
+{
+ return *ScChartObj_PABase::getArrayHelper();
+}
+
+void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) throw (uno::Exception)
+{
+ switch ( nHandle )
+ {
+ case PROP_HANDLE_RELATED_CELLRANGES:
+ {
+ uno::Sequence< table::CellRangeAddress > aCellRanges;
+ if ( rValue >>= aCellRanges )
+ {
+ ScRangeListRef rRangeList = new ScRangeList();
+ const table::CellRangeAddress* pCellRanges = aCellRanges.getArray();
+ sal_Int32 nCount = aCellRanges.getLength();
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ table::CellRangeAddress aCellRange = pCellRanges[ i ];
+ ScRange aRange;
+ ScUnoConversion::FillScRange( aRange, aCellRange );
+ rRangeList->Append( aRange );
+ }
+ ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL );
+ ScChartListenerCollection* pCollection = ( pDoc ? pDoc->GetChartListenerCollection() : NULL );
+ if ( pCollection )
+ {
+ pCollection->ChangeListening( aChartName, rRangeList );
+ }
+ }
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+}
+
+void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const
+{
+ switch ( nHandle )
+ {
+ case PROP_HANDLE_RELATED_CELLRANGES:
+ {
+ ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL );
+ if ( pDoc )
+ {
+ ScRange aEmptyRange;
+ USHORT nIndex = 0;
+ ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
+ ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
+ if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
+ {
+ ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
+ if ( pListener )
+ {
+ const ScRangeListRef& rRangeList = pListener->GetRangeList();
+ if ( rRangeList.Is() )
+ {
+ ULONG nCount = rRangeList->Count();
+ uno::Sequence< table::CellRangeAddress > aCellRanges( nCount );
+ table::CellRangeAddress* pCellRanges = aCellRanges.getArray();
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ ScRange aRange( *rRangeList->GetObject( i ) );
+ table::CellRangeAddress aCellRange;
+ ScUnoConversion::FillApiRange( aCellRange, aRange );
+ pCellRanges[ i ] = aCellRange;
+ }
+ rValue <<= aCellRanges;
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+}
+
+// ::comphelper::OPropertyArrayUsageHelper
+
+::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const
+{
+ uno::Sequence< beans::Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+}
+
+// XInterface
+
+IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase )
+
+// XTypeProvider
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase )
+
+// XComponent
+
+void ScChartObj::disposing()
+{
+ ScChartObj_Base::disposing();
+}
+
+// XTableChart
+
+sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRangeListRef xRanges = new ScRangeList;
+ bool bColHeaders, bRowHeaders;
+ GetData_Impl( xRanges, bColHeaders, bRowHeaders );
+ return bColHeaders;
+}
+
+void SAL_CALL ScChartObj::setHasColumnHeaders( sal_Bool bHasColumnHeaders )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRangeListRef xRanges = new ScRangeList;
+ bool bOldColHeaders, bOldRowHeaders;
+ GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders );
+ if ( bOldColHeaders != (bHasColumnHeaders != sal_False) )
+ Update_Impl( xRanges, bHasColumnHeaders, bOldRowHeaders );
+}
+
+sal_Bool SAL_CALL ScChartObj::getHasRowHeaders() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRangeListRef xRanges = new ScRangeList;
+ bool bColHeaders, bRowHeaders;
+ GetData_Impl( xRanges, bColHeaders, bRowHeaders );
+ return bRowHeaders;
+}
+
+void SAL_CALL ScChartObj::setHasRowHeaders( sal_Bool bHasRowHeaders )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRangeListRef xRanges = new ScRangeList;
+ bool bOldColHeaders, bOldRowHeaders;
+ GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders );
+ if ( bOldRowHeaders != (bHasRowHeaders != sal_False) )
+ Update_Impl( xRanges, bOldColHeaders, bHasRowHeaders );
+}
+
+uno::Sequence<table::CellRangeAddress> SAL_CALL ScChartObj::getRanges() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRangeListRef xRanges = new ScRangeList;
+ bool bColHeaders, bRowHeaders;
+ GetData_Impl( xRanges, bColHeaders, bRowHeaders );
+ if ( xRanges.Is() )
+ {
+ ULONG nCount = xRanges->Count();
+
+ table::CellRangeAddress aRangeAddress;
+ uno::Sequence<table::CellRangeAddress> aSeq(nCount);
+ table::CellRangeAddress* pAry = aSeq.getArray();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScRange aRange(*xRanges->GetObject(i));
+
+ aRangeAddress.Sheet = aRange.aStart.Tab();
+ aRangeAddress.StartColumn = aRange.aStart.Col();
+ aRangeAddress.StartRow = aRange.aStart.Row();
+ aRangeAddress.EndColumn = aRange.aEnd.Col();
+ aRangeAddress.EndRow = aRange.aEnd.Row();
+
+ pAry[i] = aRangeAddress;
+ }
+ return aSeq;
+ }
+
+ DBG_ERROR("ScChartObj::getRanges: keine Ranges");
+ return uno::Sequence<table::CellRangeAddress>();
+}
+
+void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRangeListRef xOldRanges = new ScRangeList;
+ bool bColHeaders, bRowHeaders;
+ GetData_Impl( xOldRanges, bColHeaders, bRowHeaders );
+
+ ScRangeList* pList = new ScRangeList;
+ USHORT nRangeCount = (USHORT)aRanges.getLength();
+ if (nRangeCount)
+ {
+ const table::CellRangeAddress* pAry = aRanges.getConstArray();
+ for (USHORT i=0; i<nRangeCount; i++)
+ {
+ ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet,
+ static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet );
+ pList->Append( aRange );
+ }
+ }
+ ScRangeListRef xNewRanges( pList );
+
+ if ( !xOldRanges.Is() || *xOldRanges != *xNewRanges )
+ Update_Impl( xNewRanges, bColHeaders, bRowHeaders );
+}
+
+// XEmbeddedObjectSupplier
+
+uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName );
+ if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) )
+ {
+ //TODO/LATER: is it OK that something is returned for *all* objects, not only own objects?
+ return uno::Reference < lang::XComponent > ( pObject->GetObjRef()->getComponent(), uno::UNO_QUERY );
+ }
+
+ return NULL;
+}
+
+// XNamed
+
+rtl::OUString SAL_CALL ScChartObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aChartName;
+}
+
+void SAL_CALL ScChartObj::setName( const rtl::OUString& /* aName */ ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ throw uno::RuntimeException(); // name cannot be changed
+}
+
+// XPropertySet
+
+uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException)
+{
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+//------------------------------------------------------------------------
+
+
+
diff --git a/sc/source/ui/unoobj/confuno.cxx b/sc/source/ui/unoobj/confuno.cxx
new file mode 100644
index 000000000000..a680185a1d1c
--- /dev/null
+++ b/sc/source/ui/unoobj/confuno.cxx
@@ -0,0 +1,488 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "confuno.hxx"
+#include "unonames.hxx"
+#include "unoguard.hxx"
+#include "scdll.hxx"
+#include "docsh.hxx"
+#include "miscuno.hxx"
+#include "forbiuno.hxx"
+#include "viewopti.hxx"
+#include "docpool.hxx"
+#include "sc.hrc"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <sfx2/printer.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace com::sun::star;
+
+#define SCCOMPSCPREADSHEETSETTINGS_SERVICE "com.sun.star.comp.SpreadsheetSettings"
+#define SCDOCUMENTSETTINGS_SERVICE "com.sun.star.document.Settings"
+#define SCSAVEVERSION "SaveVersionOnClose"
+
+
+const SfxItemPropertyMapEntry* lcl_GetConfigPropertyMap()
+{
+ static SfxItemPropertyMapEntry aConfigPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_SHOWZERO), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWNOTES), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWGRID), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_GRIDCOLOR), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWPAGEBR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_LINKUPD), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_COLROWHDR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHEETTABS), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_OUTLSYMB), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SNAPTORASTER), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RASTERVIS), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RASTERRESX), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RASTERRESY), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RASTERSUBX), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RASTERSUBY), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RASTERSYNC), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_AUTOCALC), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_PRINTERNAME), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_PRINTERSETUP), 0, &getCppuType((uno::Sequence<sal_Int8>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_APPLYDOCINF), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_FORBIDDEN), 0, &getCppuType((uno::Reference<i18n::XForbiddenCharacters>*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_CHARCOMP), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ASIANKERN), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SCSAVEVERSION), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_UPDTEMPL), 0, &getBooleanCppuType(), 0, 0},
+ /*Stampit enable/disable print cancel */
+ {MAP_CHAR_LEN(SC_UNO_ALLOWPRINTJOBCANCEL), 0, &getBooleanCppuType(), 0, 0},
+ // --> PB 2004-08-25 #i33095# Security Options
+ {MAP_CHAR_LEN(SC_UNO_LOADREADONLY), 0, &getBooleanCppuType(), 0, 0},
+ // <--
+ {MAP_CHAR_LEN(SC_UNO_SHAREDOC), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_MODIFYPASSWORDINFO), 0, &getCppuType((uno::Sequence< beans::PropertyValue >*)0), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aConfigPropertyMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+ScDocumentConfiguration::ScDocumentConfiguration(ScDocShell* pDocSh)
+ : pDocShell(pDocSh) ,
+ aPropSet ( lcl_GetConfigPropertyMap() )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDocumentConfiguration::~ScDocumentConfiguration()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDocumentConfiguration::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDocumentConfiguration::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScDocumentConfiguration::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if(pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ sal_Bool bUpdateHeights = sal_False;
+
+ ScViewOptions aViewOpt(pDoc->GetViewOptions());
+
+ /*Stampit enable/disable print cancel */
+ if ( aPropertyName.compareToAscii( SC_UNO_ALLOWPRINTJOBCANCEL ) == 0 )
+ pDocShell->Stamp_SetPrintCancelState( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ /*Stampit enable/disable print cancel */
+
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWZERO ) == 0 )
+ aViewOpt.SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWNOTES ) == 0 )
+ aViewOpt.SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWGRID ) == 0 )
+ aViewOpt.SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_GRIDCOLOR ) == 0 )
+ {
+ sal_Int64 nColor = 0;
+ if (aValue >>= nColor)
+ {
+ String aColorName;
+ Color aColor(static_cast<sal_uInt32>(nColor));
+ aViewOpt.SetGridColor(aColor, aColorName);
+ }
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWPAGEBR ) == 0 )
+ aViewOpt.SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNONAME_LINKUPD ) == 0 )
+ pDoc->SetLinkMode( static_cast<ScLkUpdMode> ( ScUnoHelpFunctions::GetInt16FromAny( aValue ) ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_COLROWHDR ) == 0 )
+ aViewOpt.SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHEETTABS ) == 0 )
+ aViewOpt.SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_OUTLSYMB ) == 0 )
+ aViewOpt.SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_AUTOCALC ) == 0 )
+ pDoc->SetAutoCalc( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_PRINTERNAME ) == 0 )
+ {
+ rtl::OUString sPrinterName;
+ if ( aValue >>= sPrinterName )
+ {
+ // #i75610# if the name is empty, do nothing (don't create any printer)
+ if ( sPrinterName.getLength() != 0 && pDocShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ SfxPrinter* pPrinter = pDocShell->GetPrinter();
+ if (pPrinter)
+ {
+ String aString(sPrinterName);
+ if (pPrinter->GetName() != aString)
+ {
+ SfxPrinter* pNewPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aString );
+ if (pNewPrinter->IsKnown())
+ pDocShell->SetPrinter( pNewPrinter, SFX_PRINTER_PRINTER );
+ else
+ delete pNewPrinter;
+ }
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_PRINTERSETUP ) == 0 )
+ {
+ uno::Sequence<sal_Int8> aSequence;
+ if ( aValue >>= aSequence )
+ {
+ sal_uInt32 nSize = aSequence.getLength();
+ // #i75610# if the sequence is empty, do nothing (don't create any printer)
+ if ( nSize != 0 )
+ {
+ SvMemoryStream aStream (aSequence.getArray(), nSize, STREAM_READ );
+ aStream.Seek ( STREAM_SEEK_TO_BEGIN );
+ SfxItemSet* pSet = new SfxItemSet( *pDoc->GetPool(),
+ SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
+ SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
+ SID_PRINT_SELECTEDSHEET, SID_PRINT_SELECTEDSHEET,
+ SID_SCPRINTOPTIONS, SID_SCPRINTOPTIONS,
+ NULL );
+ pDocShell->SetPrinter( SfxPrinter::Create( aStream, pSet ) );
+ }
+ }
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_APPLYDOCINF ) == 0 )
+ {
+ sal_Bool bTmp=sal_True;
+ if ( aValue >>= bTmp )
+ pDocShell->SetUseUserData( bTmp );
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_FORBIDDEN ) == 0 )
+ {
+ // read-only - should not be set
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_CHARCOMP ) == 0 )
+ {
+ // Int16 contains CharacterCompressionType values
+ sal_Int16 nUno = ScUnoHelpFunctions::GetInt16FromAny( aValue );
+ pDoc->SetAsianCompression( (BYTE) nUno );
+ bUpdateHeights = sal_True;
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_ASIANKERN ) == 0 )
+ {
+ pDoc->SetAsianKerning( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ bUpdateHeights = sal_True;
+ }
+ else if ( aPropertyName.compareToAscii( SCSAVEVERSION ) == 0)
+ {
+ sal_Bool bTmp=sal_False;
+ if ( aValue >>= bTmp )
+ pDocShell->SetSaveVersionOnClose( bTmp );
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_UPDTEMPL ) == 0 )
+ {
+ sal_Bool bTmp=sal_True;
+ if ( aValue >>= bTmp )
+ pDocShell->SetQueryLoadTemplate( bTmp );
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_LOADREADONLY ) == 0 )
+ {
+ sal_Bool bTmp=sal_False;
+ if ( aValue >>= bTmp )
+ pDocShell->SetLoadReadonly( bTmp );
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHAREDOC ) == 0 )
+ {
+ sal_Bool bDocShared = sal_False;
+ if ( aValue >>= bDocShared )
+ {
+ pDocShell->SetSharedXMLFlag( bDocShared );
+ }
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_MODIFYPASSWORDINFO ) == 0 )
+ {
+ uno::Sequence< beans::PropertyValue > aInfo;
+ if ( !( aValue >>= aInfo ) )
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value of type Sequence<PropertyValue> expected!" ) ),
+ uno::Reference< uno::XInterface >(),
+ 2 );
+
+ if ( !pDocShell->SetModifyPasswordInfo( aInfo ) )
+ throw beans::PropertyVetoException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The hash is not allowed to be changed now!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ else
+ {
+ ScGridOptions aGridOpt(aViewOpt.GetGridOptions());
+ if ( aPropertyName.compareToAscii( SC_UNO_SNAPTORASTER ) == 0 )
+ aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERVIS ) == 0 )
+ aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERRESX ) == 0 )
+ aGridOpt.SetFldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( aValue ) ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERRESY ) == 0 )
+ aGridOpt.SetFldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( aValue ) ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERSUBX ) == 0 )
+ aGridOpt.SetFldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( aValue ) ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERSUBY ) == 0 )
+ aGridOpt.SetFldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( aValue ) ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERSYNC ) == 0 )
+ aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else
+ throw beans::UnknownPropertyException();
+ aViewOpt.SetGridOptions(aGridOpt);
+ }
+ pDoc->SetViewOptions(aViewOpt);
+
+ if ( bUpdateHeights && !pDoc->IsImportingXML() )
+ {
+ // update automatic row heights and repaint
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( !pDocShell->AdjustRowHeight( 0, MAXROW, nTab ) )
+ pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+ pDocShell->SetDocumentModified();
+ }
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ else
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL ScDocumentConfiguration::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aRet;
+
+ if(pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ const ScViewOptions& aViewOpt = pDoc->GetViewOptions();
+
+ /*Stampit enable/disable print cancel */
+ if ( aPropertyName.compareToAscii( SC_UNO_ALLOWPRINTJOBCANCEL ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDocShell->Stamp_GetPrintCancelState() );
+ /*Stampit enable/disable print cancel */
+
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWZERO ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_NULLVALS ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWNOTES ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_NOTES ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWGRID ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_GRID ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_GRIDCOLOR ) == 0 )
+ {
+ String aColorName;
+ Color aColor = aViewOpt.GetGridColor(&aColorName);
+ aRet <<= static_cast<sal_Int64>(aColor.GetColor());
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHOWPAGEBR ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_PAGEBREAKS ) );
+ else if ( aPropertyName.compareToAscii( SC_UNONAME_LINKUPD ) == 0 )
+ aRet <<= static_cast<sal_Int16> ( pDoc->GetLinkMode() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_COLROWHDR ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_HEADER ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHEETTABS ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_TABCONTROLS ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_OUTLSYMB ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aViewOpt.GetOption( VOPT_OUTLINER ) );
+ else if ( aPropertyName.compareToAscii( SC_UNO_AUTOCALC ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->GetAutoCalc() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_PRINTERNAME ) == 0 )
+ {
+ // #i75610# don't create the printer, return empty string if no printer created yet
+ // (as in SwXDocumentSettings)
+ SfxPrinter* pPrinter = pDoc->GetPrinter( FALSE );
+ if (pPrinter)
+ aRet <<= rtl::OUString ( pPrinter->GetName());
+ else
+ aRet <<= rtl::OUString();
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_PRINTERSETUP ) == 0 )
+ {
+ // #i75610# don't create the printer, return empty sequence if no printer created yet
+ // (as in SwXDocumentSettings)
+ SfxPrinter* pPrinter = pDoc->GetPrinter( FALSE );
+ if (pPrinter)
+ {
+ SvMemoryStream aStream;
+ pPrinter->Store( aStream );
+ aStream.Seek ( STREAM_SEEK_TO_END );
+ sal_uInt32 nSize = aStream.Tell();
+ aStream.Seek ( STREAM_SEEK_TO_BEGIN );
+ uno::Sequence < sal_Int8 > aSequence( nSize );
+ aStream.Read ( aSequence.getArray(), nSize );
+ aRet <<= aSequence;
+ }
+ else
+ aRet <<= uno::Sequence<sal_Int8>();
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_APPLYDOCINF ) == 0 )
+ aRet <<= pDocShell->IsUseUserData();
+ else if ( aPropertyName.compareToAscii( SC_UNO_FORBIDDEN ) == 0 )
+ {
+ aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_CHARCOMP ) == 0 )
+ aRet <<= static_cast<sal_Int16> ( pDoc->GetAsianCompression() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_ASIANKERN ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->GetAsianKerning() );
+ else if ( aPropertyName.compareToAscii( SCSAVEVERSION ) == 0)
+ aRet <<= pDocShell->IsSaveVersionOnClose();
+ else if ( aPropertyName.compareToAscii( SC_UNO_UPDTEMPL ) == 0 )
+ aRet <<= pDocShell->IsQueryLoadTemplate();
+ else if ( aPropertyName.compareToAscii( SC_UNO_LOADREADONLY ) == 0 )
+ aRet <<= pDocShell->IsLoadReadonly();
+ // <--
+ else if ( aPropertyName.compareToAscii( SC_UNO_SHAREDOC ) == 0 )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDocShell->HasSharedXMLFlagSet() );
+ }
+ else if ( aPropertyName.compareToAscii( SC_UNO_MODIFYPASSWORDINFO ) == 0 )
+ aRet <<= pDocShell->GetModifyPasswordInfo();
+ else
+ {
+ const ScGridOptions& aGridOpt = aViewOpt.GetGridOptions();
+ if ( aPropertyName.compareToAscii( SC_UNO_SNAPTORASTER ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aGridOpt.GetUseGridSnap() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERVIS ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aGridOpt.GetGridVisible() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERRESX ) == 0 )
+ aRet <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawX() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERRESY ) == 0 )
+ aRet <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawY() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERSUBX ) == 0 )
+ aRet <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionX() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERSUBY ) == 0 )
+ aRet <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionY() );
+ else if ( aPropertyName.compareToAscii( SC_UNO_RASTERSYNC ) == 0 )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aGridOpt.GetSynchronize() );
+ else
+ throw beans::UnknownPropertyException();
+ }
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ else
+ throw uno::RuntimeException();
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocumentConfiguration )
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScDocumentConfiguration::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScDocumentConfiguration" );
+}
+
+sal_Bool SAL_CALL ScDocumentConfiguration::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCCOMPSCPREADSHEETSETTINGS_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCDOCUMENTSETTINGS_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDocumentConfiguration::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCCOMPSCPREADSHEETSETTINGS_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCDOCUMENTSETTINGS_SERVICE );
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+
diff --git a/sc/source/ui/unoobj/convuno.cxx b/sc/source/ui/unoobj/convuno.cxx
new file mode 100644
index 000000000000..e3b0c09b25c2
--- /dev/null
+++ b/sc/source/ui/unoobj/convuno.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+#include <i18npool/mslangid.hxx>
+
+#include "convuno.hxx"
+#include "global.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+// everything is static...
+
+LanguageType ScUnoConversion::GetLanguage( const lang::Locale& rLocale )
+{
+ // empty language -> LANGUAGE_SYSTEM
+ if ( rLocale.Language.getLength() == 0 )
+ return LANGUAGE_SYSTEM;
+
+ LanguageType eRet = MsLangId::convertLocaleToLanguage( rLocale );
+ if ( eRet == LANGUAGE_NONE )
+ eRet = LANGUAGE_SYSTEM; //! or throw an exception?
+
+ return eRet;
+}
+
+void ScUnoConversion::FillLocale( lang::Locale& rLocale, LanguageType eLang )
+{
+ MsLangId::convertLanguageToLocale( eLang, rLocale );
+}
+
+
+
diff --git a/sc/source/ui/unoobj/cursuno.cxx b/sc/source/ui/unoobj/cursuno.cxx
new file mode 100644
index 000000000000..daf075964a3a
--- /dev/null
+++ b/sc/source/ui/unoobj/cursuno.cxx
@@ -0,0 +1,510 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include <rtl/uuid.h>
+
+#include "cursuno.hxx"
+#include "cellsuno.hxx"
+#include "docsh.hxx"
+#include "hints.hxx"
+#include "markdata.hxx"
+#include "dociter.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+#define SCSHEETCELLCURSOR_SERVICE "com.sun.star.sheet.SheetCellCursor"
+#define SCCELLCURSOR_SERVICE "com.sun.star.table.CellCursor"
+
+//------------------------------------------------------------------------
+
+ScCellCursorObj::ScCellCursorObj(ScDocShell* pDocSh, const ScRange& rR) :
+ ScCellRangeObj( pDocSh, rR )
+{
+}
+
+ScCellCursorObj::~ScCellCursorObj()
+{
+}
+
+uno::Any SAL_CALL ScCellCursorObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XSheetCellCursor )
+ SC_QUERYINTERFACE( sheet::XUsedAreaCursor )
+ SC_QUERYINTERFACE( table::XCellCursor )
+
+ return ScCellRangeObj::queryInterface( rType );
+}
+
+void SAL_CALL ScCellCursorObj::acquire() throw()
+{
+ ScCellRangeObj::acquire();
+}
+
+void SAL_CALL ScCellCursorObj::release() throw()
+{
+ ScCellRangeObj::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScCellCursorObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 3 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSheetCellCursor>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XUsedAreaCursor>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<table::XCellCursor>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScCellCursorObj::getImplementationId() throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XSheetCellCursor
+
+void SAL_CALL ScCellCursorObj::collapseToCurrentRegion() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+
+ aOneRange.Justify();
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCCOL nStartCol = aOneRange.aStart.Col();
+ SCROW nStartRow = aOneRange.aStart.Row();
+ SCCOL nEndCol = aOneRange.aEnd.Col();
+ SCROW nEndRow = aOneRange.aEnd.Row();
+ SCTAB nTab = aOneRange.aStart.Tab();
+
+ pDocSh->GetDocument()->GetDataArea(
+ nTab, nStartCol, nStartRow, nEndCol, nEndRow, TRUE, false );
+
+ ScRange aNew( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
+ SetNewRange( aNew );
+ }
+}
+
+void SAL_CALL ScCellCursorObj::collapseToCurrentArray() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+
+ aOneRange.Justify();
+ ScAddress aCursor(aOneRange.aStart); // use the start address of the range
+
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScRange aMatrix;
+
+ // finding the matrix range is now in GetMatrixFormulaRange in the document
+ if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
+ {
+ SetNewRange( aMatrix );
+ }
+ }
+ // thats a Bug, that this assertion comes; the API Reference says, that
+ // if there is no Matrix, the Range is left unchanged; they says nothing
+ // about a exception
+ /*if (!bFound)
+ {
+ DBG_ERROR("keine Matrix");
+ //! Exception, oder was?
+ }*/
+}
+
+void SAL_CALL ScCellCursorObj::collapseToMergedArea() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aNewRange(*rRanges.GetObject(0));
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ pDoc->ExtendOverlapped( aNewRange );
+ pDoc->ExtendMerge( aNewRange ); // after ExtendOverlapped!
+
+ SetNewRange( aNewRange );
+ }
+}
+
+void SAL_CALL ScCellCursorObj::expandToEntireColumns() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aNewRange(*rRanges.GetObject(0));
+
+ aNewRange.aStart.SetRow( 0 );
+ aNewRange.aEnd.SetRow( MAXROW );
+
+ SetNewRange( aNewRange );
+}
+
+void SAL_CALL ScCellCursorObj::expandToEntireRows() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aNewRange(*rRanges.GetObject(0));
+
+ aNewRange.aStart.SetCol( 0 );
+ aNewRange.aEnd.SetCol( MAXCOL );
+
+ SetNewRange( aNewRange );
+}
+
+void SAL_CALL ScCellCursorObj::collapseToSize( sal_Int32 nColumns, sal_Int32 nRows )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( nColumns <= 0 || nRows <= 0 )
+ {
+ DBG_ERROR("leerer Range geht nicht");
+ //! und dann?
+ }
+ else
+ {
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aNewRange(*rRanges.GetObject(0));
+
+ aNewRange.Justify(); //! wirklich?
+
+ long nEndX = aNewRange.aStart.Col() + nColumns - 1;
+ long nEndY = aNewRange.aStart.Row() + nRows - 1;
+ if ( nEndX < 0 ) nEndX = 0;
+ if ( nEndX > MAXCOL ) nEndX = MAXCOL;
+ if ( nEndY < 0 ) nEndY = 0;
+ if ( nEndY > MAXROW ) nEndY = MAXROW;
+ //! Fehler/Exception oder so, wenn zu gross/zu klein?
+
+ aNewRange.aEnd.SetCol((SCCOL)nEndX);
+ aNewRange.aEnd.SetRow((SCROW)nEndY);
+
+ aNewRange.Justify(); //! wirklich?
+
+ SetNewRange( aNewRange );
+ }
+}
+
+// XUsedAreaCursor
+
+void SAL_CALL ScCellCursorObj::gotoStartOfUsedArea( sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aNewRange(*rRanges.GetObject(0));
+ SCTAB nTab = aNewRange.aStart.Tab();
+
+ SCCOL nUsedX = 0; // Anfang holen
+ SCROW nUsedY = 0;
+ if (!pDocSh->GetDocument()->GetDataStart( nTab, nUsedX, nUsedY ))
+ {
+ nUsedX = 0;
+ nUsedY = 0;
+ }
+
+ aNewRange.aStart.SetCol( nUsedX );
+ aNewRange.aStart.SetRow( nUsedY );
+ if (!bExpand)
+ aNewRange.aEnd = aNewRange.aStart;
+ SetNewRange( aNewRange );
+ }
+}
+
+void SAL_CALL ScCellCursorObj::gotoEndOfUsedArea( sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aNewRange(*rRanges.GetObject(0));
+ SCTAB nTab = aNewRange.aStart.Tab();
+
+ SCCOL nUsedX = 0; // Ende holen
+ SCROW nUsedY = 0;
+ if (!pDocSh->GetDocument()->GetTableArea( nTab, nUsedX, nUsedY ))
+ {
+ nUsedX = 0;
+ nUsedY = 0;
+ }
+
+ aNewRange.aEnd.SetCol( nUsedX );
+ aNewRange.aEnd.SetRow( nUsedY );
+ if (!bExpand)
+ aNewRange.aStart = aNewRange.aEnd;
+ SetNewRange( aNewRange );
+ }
+}
+
+// XCellCursor
+
+void SAL_CALL ScCellCursorObj::gotoStart() throw(uno::RuntimeException)
+{
+ // this is similar to collapseToCurrentRegion
+ //! something like gotoEdge with 4 possible directions is needed
+
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+
+ aOneRange.Justify();
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCCOL nStartCol = aOneRange.aStart.Col();
+ SCROW nStartRow = aOneRange.aStart.Row();
+ SCCOL nEndCol = aOneRange.aEnd.Col();
+ SCROW nEndRow = aOneRange.aEnd.Row();
+ SCTAB nTab = aOneRange.aStart.Tab();
+
+ pDocSh->GetDocument()->GetDataArea(
+ nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, false );
+
+ ScRange aNew( nStartCol, nStartRow, nTab );
+ SetNewRange( aNew );
+ }
+}
+
+void SAL_CALL ScCellCursorObj::gotoEnd() throw(uno::RuntimeException)
+{
+ // this is similar to collapseToCurrentRegion
+ //! something like gotoEdge with 4 possible directions is needed
+
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+
+ aOneRange.Justify();
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ {
+ SCCOL nStartCol = aOneRange.aStart.Col();
+ SCROW nStartRow = aOneRange.aStart.Row();
+ SCCOL nEndCol = aOneRange.aEnd.Col();
+ SCROW nEndRow = aOneRange.aEnd.Row();
+ SCTAB nTab = aOneRange.aStart.Tab();
+
+ pDocSh->GetDocument()->GetDataArea(
+ nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, false );
+
+ ScRange aNew( nEndCol, nEndRow, nTab );
+ SetNewRange( aNew );
+ }
+}
+
+void SAL_CALL ScCellCursorObj::gotoNext() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+
+ aOneRange.Justify();
+ ScAddress aCursor(aOneRange.aStart); // bei Block immer den Start nehmen
+
+ ScMarkData aMark; // not used with bMarked=FALSE
+ SCCOL nNewX = aCursor.Col();
+ SCROW nNewY = aCursor.Row();
+ SCTAB nTab = aCursor.Tab();
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ pDocSh->GetDocument()->GetNextPos( nNewX,nNewY, nTab, 1,0, FALSE,TRUE, aMark );
+ //! sonst Exception oder so
+
+ SetNewRange( ScRange( nNewX, nNewY, nTab ) );
+}
+
+void SAL_CALL ScCellCursorObj::gotoPrevious() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+
+ aOneRange.Justify();
+ ScAddress aCursor(aOneRange.aStart); // bei Block immer den Start nehmen
+
+ ScMarkData aMark; // not used with bMarked=FALSE
+ SCCOL nNewX = aCursor.Col();
+ SCROW nNewY = aCursor.Row();
+ SCTAB nTab = aCursor.Tab();
+ ScDocShell* pDocSh = GetDocShell();
+ if ( pDocSh )
+ pDocSh->GetDocument()->GetNextPos( nNewX,nNewY, nTab, -1,0, FALSE,TRUE, aMark );
+ //! sonst Exception oder so
+
+ SetNewRange( ScRange( nNewX, nNewY, nTab ) );
+}
+
+void SAL_CALL ScCellCursorObj::gotoOffset( sal_Int32 nColumnOffset, sal_Int32 nRowOffset )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScRangeList& rRanges = GetRangeList();
+ DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
+ ScRange aOneRange(*rRanges.GetObject(0));
+ aOneRange.Justify();
+
+ if ( aOneRange.aStart.Col() + nColumnOffset >= 0 &&
+ aOneRange.aEnd.Col() + nColumnOffset <= MAXCOL &&
+ aOneRange.aStart.Row() + nRowOffset >= 0 &&
+ aOneRange.aEnd.Row() + nRowOffset <= MAXROW )
+ {
+ ScRange aNew( (SCCOL)(aOneRange.aStart.Col() + nColumnOffset),
+ (SCROW)(aOneRange.aStart.Row() + nRowOffset),
+ aOneRange.aStart.Tab(),
+ (SCCOL)(aOneRange.aEnd.Col() + nColumnOffset),
+ (SCROW)(aOneRange.aEnd.Row() + nRowOffset),
+ aOneRange.aEnd.Tab() );
+ SetNewRange( aNew );
+ }
+}
+
+// XSheetCellRange
+
+uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellCursorObj::getSpreadsheet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::getSpreadsheet();
+}
+
+// XCellRange
+
+uno::Reference<table::XCell> SAL_CALL ScCellCursorObj::getCellByPosition(
+ sal_Int32 nColumn, sal_Int32 nRow )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::getCellByPosition(nColumn,nRow);
+}
+
+uno::Reference<table::XCellRange> SAL_CALL ScCellCursorObj::getCellRangeByPosition(
+ sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
+ throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom);
+}
+
+uno::Reference<table::XCellRange> SAL_CALL ScCellCursorObj::getCellRangeByName(
+ const rtl::OUString& rRange ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScCellRangeObj::getCellRangeByName(rRange);
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScCellCursorObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScCellCursorObj" );
+}
+
+sal_Bool SAL_CALL ScCellCursorObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCSHEETCELLCURSOR_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCCELLCURSOR_SERVICE ) ||
+ ScCellRangeObj::supportsService(rServiceName);
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellCursorObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ // get all service names from cell range
+ uno::Sequence<rtl::OUString> aParentSeq(ScCellRangeObj::getSupportedServiceNames());
+ sal_Int32 nParentLen = aParentSeq.getLength();
+ const rtl::OUString* pParentArr = aParentSeq.getConstArray();
+
+ // SheetCellCursor should be first (?)
+ uno::Sequence<rtl::OUString> aTotalSeq( nParentLen + 2 );
+ rtl::OUString* pTotalArr = aTotalSeq.getArray();
+ pTotalArr[0] = rtl::OUString::createFromAscii( SCSHEETCELLCURSOR_SERVICE );
+ pTotalArr[1] = rtl::OUString::createFromAscii( SCCELLCURSOR_SERVICE );
+
+ // append cell range services
+ for (long i=0; i<nParentLen; i++)
+ pTotalArr[i+2] = pParentArr[i];
+
+ return aTotalSeq;
+}
+
+
+
+
diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx
new file mode 100755
index 000000000000..c7bf89671161
--- /dev/null
+++ b/sc/source/ui/unoobj/dapiuno.cxx
@@ -0,0 +1,3554 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <algorithm>
+#include <svl/smplhint.hxx>
+#include <rtl/uuid.h>
+
+#include "dapiuno.hxx"
+#include "datauno.hxx"
+#include "miscuno.hxx"
+#include "convuno.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "pivot.hxx"
+#include "rangeutl.hxx"
+#include "unoguard.hxx"
+#include "dpobject.hxx"
+#include "dpshttab.hxx"
+#include "dpsdbtab.hxx"
+#include "dpsave.hxx"
+#include "dbdocfun.hxx"
+#include "unonames.hxx"
+#include "dpgroup.hxx"
+#include "dpdimsave.hxx"
+#include "hints.hxx"
+
+#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
+#include <com/sun/star/sheet/XLevelsSupplier.hpp>
+#include <com/sun/star/sheet/XMembersSupplier.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
+
+#include <comphelper/extract.hxx>
+#include <comphelper/sequence.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::sheet;
+
+using ::rtl::OUString;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+
+using ::com::sun::star::container::ElementExistException;
+using ::com::sun::star::container::NoSuchElementException;
+using ::com::sun::star::container::XEnumeration;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XNamed;
+
+using ::com::sun::star::beans::PropertyVetoException;
+using ::com::sun::star::beans::UnknownPropertyException;
+using ::com::sun::star::beans::XPropertyChangeListener;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertySetInfo;
+using ::com::sun::star::beans::XVetoableChangeListener;
+
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::lang::WrappedTargetException;
+
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+
+// ============================================================================
+
+namespace {
+
+const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
+{
+ static SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_COLGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_DRILLDOWN), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_IGNEMPROWS), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_IMPORTDESC), 0, &getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_RPTEMPTY), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SERVICEARG), 0, &getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SHOWFILT), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_SOURCESERV), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDataPilotDescriptorBaseMap_Impl;
+}
+
+// ----------------------------------------------------------------------------
+
+const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
+{
+ using namespace ::com::sun::star::beans::PropertyAttribute;
+ static SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_AUTOSHOW), 0, &getCppuType((DataPilotFieldAutoShowInfo*)0), MAYBEVOID, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_FUNCTION), 0, &getCppuType((GeneralFunction*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_GROUPINFO), 0, &getCppuType((DataPilotFieldGroupInfo*)0), MAYBEVOID, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_HASAUTOSHOW), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_HASLAYOUTINFO),0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_HASREFERENCE), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_HASSORTINFO), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ISGROUP), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LAYOUTINFO), 0, &getCppuType((DataPilotFieldLayoutInfo*)0), MAYBEVOID, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ORIENT), 0, &getCppuType((DataPilotFieldOrientation*)0), MAYBEVOID, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_REFERENCE), 0, &getCppuType((DataPilotFieldReference*)0), MAYBEVOID, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SELPAGE), 0, &getCppuType((OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHOWEMPTY), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SORTINFO), 0, &getCppuType((DataPilotFieldSortInfo*)0), MAYBEVOID, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SUBTOTALS), 0, &getCppuType((Sequence<GeneralFunction>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_USESELPAGE), 0, &getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDataPilotFieldMap_Impl;
+}
+
+// ----------------------------------------------------------------------------
+
+const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
+{
+ static SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ISHIDDEN), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_POS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHOWDETAIL), 0, &getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDataPilotItemMap_Impl;
+}
+
+// ----------------------------------------------------------------------------
+
+inline bool lclCheckValidDouble( double fValue, sal_Bool bAuto )
+{
+ return bAuto || ::rtl::math::isFinite( fValue );
+}
+
+bool lclCheckMinMaxStep( const DataPilotFieldGroupInfo& rInfo )
+{
+ return
+ lclCheckValidDouble( rInfo.Start, rInfo.HasAutoStart ) &&
+ lclCheckValidDouble( rInfo.End, rInfo.HasAutoEnd ) &&
+ (rInfo.HasAutoStart || rInfo.HasAutoEnd || (rInfo.Start <= rInfo.End)) &&
+ lclCheckValidDouble( rInfo.Step, sal_False ) &&
+ (0.0 <= rInfo.Step);
+}
+
+} // namespace
+
+// ============================================================================
+
+SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
+
+SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
+SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupItemObj, "ScDataPilotFieldGroupItemObj", "com.sun.star.sheet.DataPilotFieldGroupItem" )
+
+//------------------------------------------------------------------------
+
+// name that is used in the API for the data layout field
+#define SC_DATALAYOUT_NAME "Data"
+
+//------------------------------------------------------------------------
+
+GeneralFunction ScDataPilotConversion::FirstFunc( USHORT nBits )
+{
+ if ( nBits & PIVOT_FUNC_SUM ) return GeneralFunction_SUM;
+ if ( nBits & PIVOT_FUNC_COUNT ) return GeneralFunction_COUNT;
+ if ( nBits & PIVOT_FUNC_AVERAGE ) return GeneralFunction_AVERAGE;
+ if ( nBits & PIVOT_FUNC_MAX ) return GeneralFunction_MAX;
+ if ( nBits & PIVOT_FUNC_MIN ) return GeneralFunction_MIN;
+ if ( nBits & PIVOT_FUNC_PRODUCT ) return GeneralFunction_PRODUCT;
+ if ( nBits & PIVOT_FUNC_COUNT_NUM ) return GeneralFunction_COUNTNUMS;
+ if ( nBits & PIVOT_FUNC_STD_DEV ) return GeneralFunction_STDEV;
+ if ( nBits & PIVOT_FUNC_STD_DEVP ) return GeneralFunction_STDEVP;
+ if ( nBits & PIVOT_FUNC_STD_VAR ) return GeneralFunction_VAR;
+ if ( nBits & PIVOT_FUNC_STD_VARP ) return GeneralFunction_VARP;
+ if ( nBits & PIVOT_FUNC_AUTO ) return GeneralFunction_AUTO;
+ return GeneralFunction_NONE;
+}
+
+USHORT ScDataPilotConversion::FunctionBit( GeneralFunction eFunc )
+{
+ USHORT nRet = PIVOT_FUNC_NONE; // 0
+ switch (eFunc)
+ {
+ case GeneralFunction_SUM: nRet = PIVOT_FUNC_SUM; break;
+ case GeneralFunction_COUNT: nRet = PIVOT_FUNC_COUNT; break;
+ case GeneralFunction_AVERAGE: nRet = PIVOT_FUNC_AVERAGE; break;
+ case GeneralFunction_MAX: nRet = PIVOT_FUNC_MAX; break;
+ case GeneralFunction_MIN: nRet = PIVOT_FUNC_MIN; break;
+ case GeneralFunction_PRODUCT: nRet = PIVOT_FUNC_PRODUCT; break;
+ case GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break;
+ case GeneralFunction_STDEV: nRet = PIVOT_FUNC_STD_DEV; break;
+ case GeneralFunction_STDEVP: nRet = PIVOT_FUNC_STD_DEVP; break;
+ case GeneralFunction_VAR: nRet = PIVOT_FUNC_STD_VAR; break;
+ case GeneralFunction_VARP: nRet = PIVOT_FUNC_STD_VARP; break;
+ case GeneralFunction_AUTO: nRet = PIVOT_FUNC_AUTO; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return nRet;
+}
+
+void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
+{
+ rInfo.HasDateValues = rGroupInfo.DateValues;
+ rInfo.HasAutoStart = rGroupInfo.AutoStart;
+ rInfo.Start = rGroupInfo.Start;
+ rInfo.HasAutoEnd = rGroupInfo.AutoEnd;
+ rInfo.End = rGroupInfo.End;
+ rInfo.Step = rGroupInfo.Step;
+}
+
+//------------------------------------------------------------------------
+
+ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const String& rName )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDPCollection* pColl = pDoc->GetDPCollection();
+ if ( pColl )
+ {
+ USHORT nCount = pColl->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScDPObject* pDPObj = (*pColl)[i];
+ if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
+ pDPObj->GetName() == rName )
+ return pDPObj;
+ }
+ }
+ }
+ return NULL; // nicht gefunden
+}
+
+String lcl_CreatePivotName( ScDocShell* pDocShell )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDPCollection* pColl = pDoc->GetDPCollection();
+ if ( pColl )
+ return pColl->CreateNewName();
+ }
+ return String(); // sollte nicht vorkommen
+}
+
+sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
+{
+ // used for items - nRepeat in identifier can be ignored
+ if ( pDPObj )
+ {
+ sal_Int32 nCount = pDPObj->GetDimCount();
+ for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
+ {
+ BOOL bIsDataLayout = FALSE;
+ OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
+ if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
+ return nDim;
+ }
+ }
+ return -1; // none
+}
+
+//------------------------------------------------------------------------
+
+ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
+ pDocShell( pDocSh ),
+ nTab( nT )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDataPilotTablesObj::~ScDataPilotTablesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! Referenz-Update
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XDataPilotTables
+
+ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDPCollection* pColl = pDoc->GetDPCollection();
+ if ( pColl )
+ {
+ // count tables on this sheet
+ // api only handles sheet data at this time
+ //! allow all data sources!!!
+ sal_Int32 nFound = 0;
+ USHORT nCount = pColl->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScDPObject* pDPObj = (*pColl)[i];
+ if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
+ {
+ if ( nFound == nIndex )
+ {
+ String aName = pDPObj->GetName();
+ return new ScDataPilotTableObj( pDocShell, nTab, aName );
+ }
+ ++nFound;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
+{
+ if (hasByName(rName))
+ return new ScDataPilotTableObj( pDocShell, nTab, rName );
+ return 0;
+}
+
+Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScDataPilotDescriptor(pDocShell);
+ return NULL;
+}
+
+bool lcl_IsDuplicated( const Reference<XPropertySet> xDimProps )
+{
+ try
+ {
+ Any aAny = xDimProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ORIGINAL ) ) );
+ Reference< XNamed > xOriginal( aAny, UNO_QUERY );
+ return xOriginal.is();
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+OUString lcl_GetOriginalName( const Reference< XNamed > xDim )
+{
+ Reference< XNamed > xOriginal;
+
+ Reference< XPropertySet > xDimProps( xDim, UNO_QUERY );
+ if ( xDimProps.is() )
+ {
+ try
+ {
+ Any aAny = xDimProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ORIGINAL)));
+ aAny >>= xOriginal;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ if ( !xOriginal.is() )
+ xOriginal = xDim;
+
+ return xOriginal->getName();
+}
+
+void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
+ const CellAddress& aOutputAddress,
+ const Reference<XDataPilotDescriptor>& xDescriptor )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!xDescriptor.is()) return;
+
+ // inserting with already existing name?
+ if ( aNewName.getLength() && hasByName( aNewName ) )
+ throw RuntimeException(); // no other exceptions specified
+
+ BOOL bDone = FALSE;
+ ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
+ if ( pDocShell && pImp )
+ {
+ ScDPObject* pNewObj = pImp->GetDPObject();
+
+ if (pNewObj)
+ {
+ ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
+ (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
+ pNewObj->SetOutRange(aOutputRange);
+ String aName = aNewName;
+ if (!aName.Len())
+ aName = lcl_CreatePivotName( pDocShell );
+ pNewObj->SetName(aName);
+ String aTag = xDescriptor->getTag();
+ pNewObj->SetTag(aTag);
+
+ // todo: handle double fields (for more information see ScDPObject
+
+ ScDBDocFunc aFunc(*pDocShell);
+ bDone = aFunc.DataPilotUpdate( NULL, pNewObj, TRUE, TRUE );
+ }
+ }
+
+ if (!bDone)
+ throw RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr(aName);
+ ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
+ if (pDPObj && pDocShell)
+ {
+ ScDBDocFunc aFunc(*pDocShell);
+ aFunc.DataPilotUpdate( pDPObj, NULL, TRUE, TRUE ); // remove - incl. undo etc.
+ }
+ else
+ throw RuntimeException(); // no other exceptions specified
+}
+
+// XEnumerationAccess
+
+Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotTablesEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDPCollection* pColl = pDoc->GetDPCollection();
+ if ( pColl )
+ {
+ // count tables on this sheet
+ // api only handles sheet data at this time
+ //! allow all data sources!!!
+
+ USHORT nFound = 0;
+ USHORT nCount = pColl->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScDPObject* pDPObj = (*pColl)[i];
+ if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
+ ++nFound;
+ }
+ return nFound;
+ }
+ }
+
+ return 0;
+}
+
+Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
+ throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
+ if (!xTable.is())
+ throw IndexOutOfBoundsException();
+ return Any( xTable );
+}
+
+uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((Reference<XDataPilotTable2>*)0);
+}
+
+sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XNameAccess
+
+Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
+ if (!xTable.is())
+ throw NoSuchElementException();
+ return Any( xTable );
+}
+
+Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDPCollection* pColl = pDoc->GetDPCollection();
+ if ( pColl )
+ {
+ // count tables on this sheet
+ // api only handles sheet data at this time
+ //! allow all data sources!!!
+
+ USHORT nFound = 0;
+ USHORT nCount = pColl->GetCount();
+ USHORT i;
+ for (i=0; i<nCount; i++)
+ {
+ ScDPObject* pDPObj = (*pColl)[i];
+ if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
+ ++nFound;
+ }
+
+ USHORT nPos = 0;
+ Sequence<OUString> aSeq(nFound);
+ OUString* pAry = aSeq.getArray();
+ for (i=0; i<nCount; i++)
+ {
+ ScDPObject* pDPObj = (*pColl)[i];
+ if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
+ pAry[nPos++] = pDPObj->GetName();
+ }
+
+ return aSeq;
+ }
+ }
+ return Sequence<OUString>(0);
+}
+
+sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDPCollection* pColl = pDoc->GetDPCollection();
+ if ( pColl )
+ {
+ String aNamStr(aName);
+ USHORT nCount = pColl->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ // api only handles sheet data at this time
+ //! allow all data sources!!!
+
+ ScDPObject* pDPObj = (*pColl)[i];
+ if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
+ pDPObj->GetName() == aNamStr )
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
+ maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
+ throw(RuntimeException)
+{
+ SC_QUERYINTERFACE( XDataPilotDescriptor )
+ SC_QUERYINTERFACE( XPropertySet )
+ SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
+ SC_QUERYINTERFACE( XNamed ) // base of XDataPilotDescriptor
+ SC_QUERYINTERFACE( lang::XUnoTunnel )
+ SC_QUERYINTERFACE( lang::XTypeProvider )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+
+ return OWeakObject::queryInterface( rType );
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::release() throw()
+{
+ OWeakObject::release();
+}
+
+Sequence< uno::Type > SAL_CALL ScDataPilotDescriptorBase::getTypes()
+ throw(RuntimeException)
+{
+ static Sequence< uno::Type > aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ aTypes.realloc( 6 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[ 0 ] = getCppuType( (const Reference< XDataPilotDescriptor >*)0 );
+ pPtr[ 1 ] = getCppuType( (const Reference< XPropertySet >*)0 );
+ pPtr[ 2 ] = getCppuType( (const Reference< XDataPilotDataLayoutFieldSupplier >*)0 );
+ pPtr[ 3 ] = getCppuType( (const Reference< lang::XUnoTunnel >*)0 );
+ pPtr[ 4 ] = getCppuType( (const Reference< lang::XTypeProvider >*)0 );
+ pPtr[ 5 ] = getCppuType( (const Reference< lang::XServiceInfo >*)0 );
+ }
+ return aTypes;
+}
+
+Sequence<sal_Int8> SAL_CALL ScDataPilotDescriptorBase::getImplementationId()
+ throw(RuntimeException)
+{
+ static Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! Referenz-Update?
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XDataPilotDescriptor
+
+CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ ScDPObject* pDPObject(GetDPObject());
+ if (!pDPObject)
+ throw RuntimeException();
+
+ CellRangeAddress aRet;
+ if (pDPObject->IsSheetData())
+ ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->aSourceRange );
+ return aRet;
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ ScDPObject* pDPObject = GetDPObject();
+ if (!pDPObject)
+ throw RuntimeException();
+
+ ScSheetSourceDesc aSheetDesc;
+ if (pDPObject->IsSheetData())
+ aSheetDesc = *pDPObject->GetSheetDesc();
+ ScUnoConversion::FillScRange( aSheetDesc.aSourceRange, aSourceRange );
+ pDPObject->SetSheetDesc( aSheetDesc );
+ SetDPObject( pDPObject );
+}
+
+Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFilterDescriptor( pDocShell, this );
+}
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFieldsObj( *this );
+}
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
+}
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
+}
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
+}
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
+}
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_HIDDEN );
+}
+
+// XPropertySet
+Reference< XPropertySetInfo > SAL_CALL ScDataPilotDescriptorBase::getPropertySetInfo( )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static Reference<XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
+ return aRef;
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
+ WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObject = GetDPObject();
+ if (pDPObject)
+ {
+ ScDPSaveData* pOldData = pDPObject->GetSaveData();
+ DBG_ASSERT(pOldData, "Here should be a SaveData");
+ if ( pOldData )
+ {
+ ScDPSaveData aNewData( *pOldData );
+
+ String aNameString = aPropertyName;
+ if ( aNameString.EqualsAscii( SC_UNO_COLGRAND ) )
+ {
+ aNewData.SetColumnGrand(::cppu::any2bool( aValue ));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_IGNEMPROWS ) )
+ {
+ aNewData.SetIgnoreEmptyRows(::cppu::any2bool( aValue ));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_RPTEMPTY ) )
+ {
+ aNewData.SetRepeatIfEmpty(::cppu::any2bool( aValue ));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_ROWGRAND ) )
+ {
+ aNewData.SetRowGrand(::cppu::any2bool( aValue ));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_SHOWFILT ) )
+ {
+ aNewData.SetFilterButton(::cppu::any2bool( aValue ));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_DRILLDOWN ) )
+ {
+ aNewData.SetDrillDown(::cppu::any2bool( aValue ));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_IMPORTDESC ) )
+ {
+ uno::Sequence<beans::PropertyValue> aArgSeq;
+ if ( aValue >>= aArgSeq )
+ {
+ ScImportSourceDesc aImportDesc;
+
+ const ScImportSourceDesc* pOldDesc = pDPObject->GetImportSourceDesc();
+ if (pOldDesc)
+ aImportDesc = *pOldDesc;
+
+ ScImportParam aParam;
+ ScImportDescriptor::FillImportParam( aParam, aArgSeq );
+
+ USHORT nNewType = sheet::DataImportMode_NONE;
+ if ( aParam.bImport )
+ {
+ if ( aParam.bSql )
+ nNewType = sheet::DataImportMode_SQL;
+ else if ( aParam.nType == ScDbQuery )
+ nNewType = sheet::DataImportMode_QUERY;
+ else
+ nNewType = sheet::DataImportMode_TABLE;
+ }
+ aImportDesc.nType = nNewType;
+ aImportDesc.aDBName = aParam.aDBName;
+ aImportDesc.aObject = aParam.aStatement;
+ aImportDesc.bNative = aParam.bNative;
+
+ pDPObject->SetImportDesc( aImportDesc );
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_SOURCESERV ) )
+ {
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ {
+ String aEmpty;
+ ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
+
+ const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
+ if (pOldDesc)
+ aServiceDesc = *pOldDesc;
+
+ aServiceDesc.aServiceName = aStrVal;
+
+ pDPObject->SetServiceData( aServiceDesc );
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_SERVICEARG ) )
+ {
+ uno::Sequence<beans::PropertyValue> aArgSeq;
+ if ( aValue >>= aArgSeq )
+ {
+ String aEmpty;
+ ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
+
+ const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
+ if (pOldDesc)
+ aServiceDesc = *pOldDesc;
+
+ rtl::OUString aStrVal;
+ sal_Int32 nArgs = aArgSeq.getLength();
+ for (sal_Int32 nArgPos=0; nArgPos<nArgs; ++nArgPos)
+ {
+ const beans::PropertyValue& rProp = aArgSeq[nArgPos];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( SC_UNO_SOURCENAME ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aServiceDesc.aParSource = aStrVal;
+ }
+ else if (aPropName.EqualsAscii( SC_UNO_OBJECTNAME ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aServiceDesc.aParName = aStrVal;
+ }
+ else if (aPropName.EqualsAscii( SC_UNO_USERNAME ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aServiceDesc.aParUser = aStrVal;
+ }
+ else if (aPropName.EqualsAscii( SC_UNO_PASSWORD ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aServiceDesc.aParPass = aStrVal;
+ }
+ }
+
+ pDPObject->SetServiceData( aServiceDesc );
+ }
+ }
+ else
+ throw UnknownPropertyException();
+
+ pDPObject->SetSaveData( aNewData );
+ }
+
+ SetDPObject(pDPObject);
+ }
+}
+
+Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPropertyName )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Any aRet;
+
+ ScDPObject* pDPObject(GetDPObject());
+ if (pDPObject)
+ {
+ ScDPSaveData* pOldData = pDPObject->GetSaveData();
+ DBG_ASSERT(pOldData, "Here should be a SaveData");
+ if ( pOldData )
+ {
+ ScDPSaveData aNewData( *pOldData );
+
+ String aNameString = aPropertyName;
+ if ( aNameString.EqualsAscii( SC_UNO_COLGRAND ) )
+ {
+ aRet = ::cppu::bool2any( aNewData.GetColumnGrand() );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_IGNEMPROWS ) )
+ {
+ aRet = ::cppu::bool2any( aNewData.GetIgnoreEmptyRows() );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_RPTEMPTY ) )
+ {
+ aRet = ::cppu::bool2any( aNewData.GetRepeatIfEmpty() );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_ROWGRAND ) )
+ {
+ aRet = ::cppu::bool2any( aNewData.GetRowGrand() );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_SHOWFILT ) )
+ {
+ aRet = ::cppu::bool2any( aNewData.GetFilterButton() );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_DRILLDOWN ) )
+ {
+ aRet = ::cppu::bool2any( aNewData.GetDrillDown() );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_IMPORTDESC ) )
+ {
+ const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc();
+ if ( pImportDesc )
+ {
+ // fill ScImportParam so ScImportDescriptor::FillProperties can be used
+ ScImportParam aParam;
+ aParam.bImport = ( pImportDesc->nType != sheet::DataImportMode_NONE );
+ aParam.aDBName = pImportDesc->aDBName;
+ aParam.aStatement = pImportDesc->aObject;
+ aParam.bNative = pImportDesc->bNative;
+ aParam.bSql = ( pImportDesc->nType == sheet::DataImportMode_SQL );
+ aParam.nType = static_cast<BYTE>(( pImportDesc->nType == sheet::DataImportMode_QUERY ) ? ScDbQuery : ScDbTable);
+
+ uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
+ ScImportDescriptor::FillProperties( aSeq, aParam );
+ aRet <<= aSeq;
+ }
+ else
+ {
+ // empty sequence
+ uno::Sequence<beans::PropertyValue> aEmpty(0);
+ aRet <<= aEmpty;
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_SOURCESERV ) )
+ {
+ rtl::OUString aServiceName;
+ const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
+ if (pServiceDesc)
+ aServiceName = pServiceDesc->aServiceName;
+ aRet <<= aServiceName; // empty string if no ServiceDesc set
+ }
+ else if ( aNameString.EqualsAscii( SC_UNO_SERVICEARG ) )
+ {
+ const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
+ if (pServiceDesc)
+ {
+ uno::Sequence<beans::PropertyValue> aSeq( 4 );
+ beans::PropertyValue* pArray = aSeq.getArray();
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNO_SOURCENAME );
+ pArray[0].Value <<= rtl::OUString( pServiceDesc->aParSource );
+ pArray[1].Name = rtl::OUString::createFromAscii( SC_UNO_OBJECTNAME );
+ pArray[1].Value <<= rtl::OUString( pServiceDesc->aParName );
+ pArray[2].Name = rtl::OUString::createFromAscii( SC_UNO_USERNAME );
+ pArray[2].Value <<= rtl::OUString( pServiceDesc->aParUser );
+ pArray[3].Name = rtl::OUString::createFromAscii( SC_UNO_PASSWORD );
+ pArray[3].Value <<= rtl::OUString( pServiceDesc->aParPass );
+ aRet <<= aSeq;
+ }
+ else
+ {
+ // empty sequence
+ uno::Sequence<beans::PropertyValue> aEmpty(0);
+ aRet <<= aEmpty;
+ }
+ }
+ else
+ throw UnknownPropertyException();
+ }
+ }
+
+ return aRet;
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::addPropertyChangeListener(
+ const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* xListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::removePropertyChangeListener(
+ const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* aListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::addVetoableChangeListener(
+ const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+void SAL_CALL ScDataPilotDescriptorBase::removeVetoableChangeListener(
+ const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// XDataPilotDataLayoutFieldSupplier
+
+Reference< XDataPilotField > SAL_CALL ScDataPilotDescriptorBase::getDataLayoutField() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if( ScDPObject* pDPObject = GetDPObject() )
+ {
+ if( ScDPSaveData* pSaveData = pDPObject->GetSaveData() )
+ {
+ if( /*ScDPSaveDimension* pDataDim =*/ pSaveData->GetDataLayoutDimension() )
+ {
+ ScFieldIdentifier aFieldId( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) ), 0, true );
+ return new ScDataPilotFieldObj( *this, aFieldId );
+ }
+ }
+ }
+ return 0;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
+ const Sequence<sal_Int8 >& rId ) throw(RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
+{
+ static Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(
+ const Reference<XDataPilotDescriptor> xObj )
+{
+ ScDataPilotDescriptorBase* pRet = NULL;
+ Reference<lang::XUnoTunnel> xUT( xObj, UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) :
+ ScDataPilotDescriptorBase( pDocSh ),
+ nTab( nT ),
+ aName( rN ),
+ aModifyListeners( 0 )
+{
+}
+
+ScDataPilotTableObj::~ScDataPilotTableObj()
+{
+}
+
+Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
+ throw(RuntimeException)
+{
+ // since we manually do resolve the query for XDataPilotTable2
+ // we also need to do the same for XDataPilotTable
+ SC_QUERYINTERFACE( XDataPilotTable )
+ SC_QUERYINTERFACE( XDataPilotTable2 )
+ SC_QUERYINTERFACE( XModifyBroadcaster )
+
+ return ScDataPilotDescriptorBase::queryInterface( rType );
+}
+
+void SAL_CALL ScDataPilotTableObj::acquire() throw()
+{
+ ScDataPilotDescriptorBase::acquire();
+}
+
+void SAL_CALL ScDataPilotTableObj::release() throw()
+{
+ ScDataPilotDescriptorBase::release();
+}
+
+Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeException)
+{
+ static Sequence< uno::Type > aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ Sequence< uno::Type > aParentTypes = ScDataPilotDescriptorBase::getTypes();
+ sal_Int32 nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 2 );
+ uno::Type* pPtr = aTypes.getArray();
+ for (sal_Int32 i = 0; i < nParentLen; ++i)
+ pPtr[ i ] = pParentPtr[ i ]; // parent types first
+
+ pPtr[ nParentLen ] = getCppuType( (const Reference< XDataPilotTable2 >*)0 );
+ pPtr[ nParentLen+1 ] = getCppuType( (const Reference< XModifyBroadcaster >*)0 );
+ }
+ return aTypes;
+}
+
+Sequence<sal_Int8> SAL_CALL ScDataPilotTableObj::getImplementationId()
+ throw(RuntimeException)
+{
+ static Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// ---
+ScDPObject* ScDataPilotTableObj::GetDPObject() const
+{
+ return lcl_GetDPObject(GetDocShell(), nTab, aName);
+}
+
+void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
+{
+ ScDocShell* pDocSh = GetDocShell();
+ ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
+ if ( pDPObj && pDocSh )
+ {
+ ScDBDocFunc aFunc(*pDocSh);
+ aFunc.DataPilotUpdate( pDPObj, pDPObject, TRUE, TRUE );
+ }
+}
+
+// "rest of XDataPilotDescriptor"
+
+OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
+ if (pDPObj)
+ return pDPObj->GetName();
+ return OUString();
+}
+
+void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
+ if (pDPObj)
+ {
+ //! test for existing names !!!
+
+ String aString(aNewName);
+ pDPObj->SetName( aString ); //! Undo - DBDocFunc ???
+ aName = aString;
+
+ // DataPilotUpdate would do too much (output table is not changed)
+ GetDocShell()->SetDocumentModified();
+ }
+}
+
+OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
+ if (pDPObj)
+ return pDPObj->GetTag();
+ return OUString();
+}
+
+void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
+ if (pDPObj)
+ {
+ String aString(aNewTag);
+ pDPObj->SetTag( aString ); //! Undo - DBDocFunc ???
+
+ // DataPilotUpdate would do too much (output table is not changed)
+ GetDocShell()->SetDocumentModified();
+ }
+}
+
+// XDataPilotTable
+
+CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ CellRangeAddress aRet;
+ ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
+ if (pDPObj)
+ {
+ ScRange aRange(pDPObj->GetOutRange());
+ aRet.Sheet = aRange.aStart.Tab();
+ aRet.StartColumn = aRange.aStart.Col();
+ aRet.StartRow = aRange.aStart.Row();
+ aRet.EndColumn = aRange.aEnd.Col();
+ aRet.EndRow = aRange.aEnd.Row();
+ }
+ return aRet;
+}
+
+ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, BOOL bRecord, BOOL bApi );
+
+void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if( ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName) )
+ RefreshDPObject( pDPObj, NULL, GetDocShell(), TRUE, TRUE );
+ //if (pDPObj)
+ //{
+ // ScDPObject* pNew = new ScDPObject(*pDPObj);
+ // ScDBDocFunc aFunc(*GetDocShell());
+ // aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE );
+ // delete pNew; // DataPilotUpdate copies settings from "new" object
+ //}
+
+}
+
+Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Sequence< Sequence<Any> > aTabData;
+ ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
+ ScDPObject* pObj = GetDPObject();
+ if (!pObj)
+ throw RuntimeException();
+
+ pObj->GetDrillDownData(aAddr2, aTabData);
+ return aTabData;
+}
+
+DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ DataPilotTablePositionData aPosData;
+ ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
+ ScDPObject* pObj = GetDPObject();
+ if (!pObj)
+ throw RuntimeException();
+
+ pObj->GetPositionData(aAddr2, aPosData);
+ return aPosData;
+}
+
+void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = GetDPObject();
+ if (!pDPObj)
+ throw RuntimeException();
+
+ Sequence<DataPilotFieldFilter> aFilters;
+ pDPObj->GetDataFieldPositionData(
+ ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
+ GetDocShell()->GetBestViewShell()->ShowDataPilotSourceData(*pDPObj, aFilters);
+}
+
+CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
+ throw (IllegalArgumentException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
+ throw IllegalArgumentException();
+
+ CellRangeAddress aRet;
+ if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
+ ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
+ return aRet;
+}
+
+void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener );
+ aModifyListeners.Insert( pObj, aModifyListeners.Count() );
+
+ if ( aModifyListeners.Count() == 1 )
+ {
+ acquire(); // don't lose this object (one ref for all listeners)
+ }
+}
+
+void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ acquire(); // in case the listeners have the last ref - released below
+
+ USHORT nCount = aModifyListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XModifyListener> *pObj = aModifyListeners[n];
+ if ( *pObj == aListener )
+ {
+ aModifyListeners.DeleteAndDestroy( n );
+
+ if ( aModifyListeners.Count() == 0 )
+ {
+ release(); // release the ref for the listeners
+ }
+
+ break;
+ }
+ }
+
+ release(); // might delete this object
+}
+
+void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA(ScDataPilotModifiedHint) &&
+ static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
+ {
+ Refreshed_Impl();
+ }
+
+ ScDataPilotDescriptorBase::Notify( rBC, rHint );
+}
+
+void ScDataPilotTableObj::Refreshed_Impl()
+{
+ lang::EventObject aEvent;
+ aEvent.Source.set((cppu::OWeakObject*)this);
+
+ // the EventObject holds a Ref to this object until after the listener calls
+
+ ScDocument* pDoc = GetDocShell()->GetDocument();
+ for ( USHORT n=0; n<aModifyListeners.Count(); n++ )
+ pDoc->AddUnoListenerCall( *aModifyListeners[n], aEvent );
+}
+
+// ============================================================================
+
+ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
+ ScDataPilotDescriptorBase( pDocSh ),
+ mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
+{
+ mpDPObject->SetAlive(sal_True);
+ ScDPSaveData aSaveData;
+ // set defaults like in ScPivotParam constructor
+ aSaveData.SetColumnGrand( sal_True );
+ aSaveData.SetRowGrand( sal_True );
+ aSaveData.SetIgnoreEmptyRows( sal_False );
+ aSaveData.SetRepeatIfEmpty( sal_False );
+ mpDPObject->SetSaveData(aSaveData);
+ ScSheetSourceDesc aSheetDesc;
+ mpDPObject->SetSheetDesc(aSheetDesc);
+ mpDPObject->GetSource();
+}
+
+ScDataPilotDescriptor::~ScDataPilotDescriptor()
+{
+ delete mpDPObject;
+}
+
+ScDPObject* ScDataPilotDescriptor::GetDPObject() const
+{
+ return mpDPObject;
+}
+
+void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
+{
+ if (mpDPObject != pDPObject)
+ {
+ delete mpDPObject;
+ mpDPObject = pDPObject;
+ DBG_ERROR("replace DPObject should not happen");
+ }
+}
+
+// "rest of XDataPilotDescriptor"
+
+OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return mpDPObject->GetName();
+}
+
+void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ mpDPObject->SetName( aNewName );
+}
+
+OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return mpDPObject->GetTag();
+}
+
+void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ mpDPObject->SetTag( aNewTag );
+}
+
+// ============================================================================
+
+ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
+ mrParent( rParent )
+{
+ mrParent.acquire();
+}
+
+ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
+ mrParent( rParent ),
+ maFieldId( rFieldId )
+{
+ mrParent.acquire();
+}
+
+ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
+{
+ mrParent.release();
+}
+
+ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
+{
+ return mrParent.GetDPObject();
+}
+
+void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
+{
+ mrParent.SetDPObject( pDPObject );
+}
+
+ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
+{
+ if( ScDPObject* pDPObj = GetDPObject() )
+ {
+ if( ppDPObject ) *ppDPObject = pDPObj;
+ if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
+ {
+ if( maFieldId.mbDataLayout )
+ return pSaveData->GetDataLayoutDimension();
+
+ if( maFieldId.mnFieldIdx == 0 )
+ return pSaveData->GetDimensionByName( maFieldId.maFieldName );
+
+ // find dimension with specified index (search in duplicated dimensions)
+ String aFieldName = maFieldId.maFieldName; // needed for comparison
+ const List& rDimensions = pSaveData->GetDimensions();
+ ULONG nDimCount = rDimensions.Count();
+ sal_Int32 nFoundIdx = 0;
+ for( ULONG nDim = 0; nDim < nDimCount; ++nDim )
+ {
+ ScDPSaveDimension* pDim = static_cast< ScDPSaveDimension* >( rDimensions.GetObject( nDim ) );
+ if( !pDim->IsDataLayout() && (pDim->GetName() == aFieldName) )
+ {
+ if( nFoundIdx == maFieldId.mnFieldIdx )
+ return pDim;
+ ++nFoundIdx;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
+{
+ sal_Int32 nRet = 0;
+ Reference<XNameAccess> xMembersNA = GetMembers();
+ if (xMembersNA.is())
+ {
+ Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
+ nRet = xMembersIA->getCount();
+ }
+ return nRet;
+}
+
+Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
+{
+ Reference< XNameAccess > xMembersNA;
+ if( ScDPObject* pDPObj = GetDPObject() )
+ pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
+ return xMembersNA;
+}
+
+// ============================================================================
+
+ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
+ ScDataPilotChildObjBase( rParent )
+{
+}
+
+ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
+ ScDataPilotChildObjBase( rParent ),
+ maOrient( eOrient )
+{
+}
+
+ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
+{
+}
+
+sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
+{
+ sal_Int32 nRet = 0;
+
+ Reference<XNameAccess> xDimsName(rSource->getDimensions());
+ Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
+ sal_Int32 nIntCount = xIntDims->getCount();
+ if (rOrient.hasValue())
+ {
+ // all fields of the specified orientation, including duplicated
+ Reference<XPropertySet> xDim;
+ for (sal_Int32 i = 0; i < nIntCount; ++i)
+ {
+ xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
+ if (xDim.is() && (xDim->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ORIENTAT))) == rOrient))
+ ++nRet;
+ }
+ }
+ else
+ {
+ // count all non-duplicated fields
+
+ Reference<XPropertySet> xDim;
+ for (sal_Int32 i = 0; i < nIntCount; ++i)
+ {
+ xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
+ if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
+ ++nRet;
+ }
+ }
+
+ return nRet;
+}
+
+BOOL lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
+ const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
+{
+ BOOL bOk = FALSE;
+ SCSIZE nPos = 0;
+ sal_Int32 nDimIndex = 0;
+
+ Reference<XNameAccess> xDimsName(rSource->getDimensions());
+ Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
+ sal_Int32 nIntCount = xIntDims->getCount();
+ Reference<XPropertySet> xDim;
+ if (rOrient.hasValue())
+ {
+ sal_Int32 i = 0;
+ while (i < nIntCount && !bOk)
+ {
+ xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
+ if (xDim.is() && (xDim->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ORIENTAT))) == rOrient))
+ {
+ if (nPos == nIndex)
+ {
+ bOk = sal_True;
+ nDimIndex = i;
+ }
+ else
+ ++nPos;
+ }
+ ++i;
+ }
+ }
+ else
+ {
+ sal_Int32 i = 0;
+ while (i < nIntCount && !bOk)
+ {
+ xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
+ if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
+ {
+ if (nPos == nIndex)
+ {
+ bOk = sal_True;
+ nDimIndex = i;
+ }
+ else
+ ++nPos;
+ }
+ ++i;
+ }
+ }
+
+ if ( bOk )
+ {
+ xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
+ Reference<XNamed> xDimName( xDim, UNO_QUERY );
+ if ( xDimName.is() )
+ {
+ OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
+ rFieldId.maFieldName = sOriginalName;
+ rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
+ OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ISDATALA)) );
+
+ sal_Int32 nRepeat = 0;
+ if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
+ {
+ // find the repeat count
+ // (this relies on the original dimension always being before the duplicates)
+
+ Reference<XNamed> xPrevName;
+ for (sal_Int32 i = 0; i < nDimIndex; ++i)
+ {
+ xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
+ if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
+ ++nRepeat;
+ }
+ }
+ rFieldId.mnFieldIdx = nRepeat;
+ }
+ else
+ bOk = sal_False;
+ }
+
+ return bOk;
+}
+
+BOOL lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
+{
+ // "By name" is always the first match.
+ // The name "Data" always refers to the data layout field.
+ rFieldId.maFieldName = rFieldName;
+ rFieldId.mnFieldIdx = 0;
+ rFieldId.mbDataLayout = rFieldName.equalsAscii( SC_DATALAYOUT_NAME );
+
+ pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
+
+ // check if the named field exists (not for data layout)
+ return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
+}
+
+// XDataPilotFields
+
+ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
+{
+// TODO
+ if (ScDPObject* pObj = GetDPObject())
+ {
+ ScFieldIdentifier aFieldId;
+ if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
+ return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
+ }
+ return 0;
+}
+
+ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
+{
+ if (ScDPObject* pDPObj = GetDPObject())
+ {
+ ScFieldIdentifier aFieldId;
+ if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
+ return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
+ }
+ return 0;
+}
+
+// XEnumerationAccess
+
+Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotFieldsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+// TODO
+ ScDPObject* pDPObj = GetDPObject();
+ return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
+}
+
+Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
+ throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
+ if (!xField.is())
+ throw IndexOutOfBoundsException();
+ return Any( xField );
+}
+
+uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((Reference<XPropertySet>*)0);
+}
+
+sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
+ if (!xField.is())
+ throw NoSuchElementException();
+ return Any( xField );
+}
+
+Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+// TODO
+ if (ScDPObject* pDPObj = GetDPObject())
+ {
+ Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
+ OUString* pAry = aSeq.getArray();
+ const List& rDimensions = pDPObj->GetSaveData()->GetDimensions();
+ sal_Int32 nDimCount = rDimensions.Count();
+ for (sal_Int32 nDim = 0; nDim < nDimCount; nDim++)
+ {
+ ScDPSaveDimension* pDim = (ScDPSaveDimension*)rDimensions.GetObject(nDim);
+ if(maOrient.hasValue() && (pDim->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
+ {
+ *pAry = pDim->GetName();
+ ++pAry;
+ }
+ }
+ return aSeq;
+ }
+ return Sequence<OUString>();
+}
+
+sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ return GetObjectByName_Impl(aName) != NULL;
+}
+
+//------------------------------------------------------------------------
+
+ScDataPilotFieldObj::ScDataPilotFieldObj(
+ ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
+ ScDataPilotChildObjBase( rParent, rFieldId ),
+ maPropSet( lcl_GetDataPilotFieldMap() )
+{
+}
+
+ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
+ const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
+ ScDataPilotChildObjBase( rParent, rFieldId ),
+ maPropSet( lcl_GetDataPilotFieldMap() ),
+ maOrient( rOrient )
+{
+}
+
+ScDataPilotFieldObj::~ScDataPilotFieldObj()
+{
+}
+
+// XNamed
+
+OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ OUString aName;
+ if( ScDPSaveDimension* pDim = GetDPDimension() )
+ {
+ if( pDim->IsDataLayout() )
+ aName = OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) );
+ else
+ {
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ aName = *pLayoutName;
+ else
+ aName = pDim->GetName();
+ } }
+ return aName;
+}
+
+void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
+ if( pDim && !pDim->IsDataLayout() )
+ {
+ String aName( rName );
+ pDim->SetLayoutName(aName);
+ SetDPObject( pDPObj );
+ }
+}
+
+// XPropertySet
+
+Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static Reference<XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) )
+ {
+ // #i109350# use GetEnumFromAny because it also allows sal_Int32
+ GeneralFunction eFunction = (GeneralFunction)
+ ScUnoHelpFunctions::GetEnumFromAny( aValue );
+ setFunction( eFunction );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) )
+ {
+ Sequence< GeneralFunction > aSubtotals;
+ if( aValue >>= aSubtotals )
+ setSubtotals( aSubtotals );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) )
+ {
+ //! test for correct enum type?
+ DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
+ ScUnoHelpFunctions::GetEnumFromAny( aValue );
+ setOrientation( eOrient );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SELPAGE ) )
+ {
+ OUString sCurrentPage;
+ if (aValue >>= sCurrentPage)
+ setCurrentPage(sCurrentPage);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_USESELPAGE ) )
+ {
+ setUseCurrentPage(cppu::any2bool(aValue));
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASAUTOSHOW ) )
+ {
+ if (!cppu::any2bool(aValue))
+ setAutoShowInfo(NULL);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_AUTOSHOW ) )
+ {
+ DataPilotFieldAutoShowInfo aInfo;
+ if (aValue >>= aInfo)
+ setAutoShowInfo(&aInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASLAYOUTINFO ) )
+ {
+ if (!cppu::any2bool(aValue))
+ setLayoutInfo(NULL);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_LAYOUTINFO ) )
+ {
+ DataPilotFieldLayoutInfo aInfo;
+ if (aValue >>= aInfo)
+ setLayoutInfo(&aInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASREFERENCE ) )
+ {
+ if (!cppu::any2bool(aValue))
+ setReference(NULL);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFERENCE ) )
+ {
+ DataPilotFieldReference aRef;
+ if (aValue >>= aRef)
+ setReference(&aRef);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASSORTINFO ) )
+ {
+ if (!cppu::any2bool(aValue))
+ setSortInfo(NULL);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SORTINFO ) )
+ {
+ DataPilotFieldSortInfo aInfo;
+ if (aValue >>= aInfo)
+ setSortInfo(&aInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ISGROUP ) )
+ {
+ if (!cppu::any2bool(aValue))
+ setGroupInfo(NULL);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_GROUPINFO ) )
+ {
+ DataPilotFieldGroupInfo aInfo;
+ if (aValue >>= aInfo)
+ setGroupInfo(&aInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SHOWEMPTY ) )
+ {
+ setShowEmpty(cppu::any2bool(aValue));
+ }
+}
+
+Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ Any aRet;
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) )
+ aRet <<= getFunction();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) )
+ aRet <<= getSubtotals();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) )
+ aRet <<= getOrientation();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SELPAGE ) )
+ aRet <<= getCurrentPage();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_USESELPAGE ) )
+ aRet <<= getUseCurrentPage();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASAUTOSHOW ) )
+ aRet = ::cppu::bool2any(getAutoShowInfo() != NULL);
+ else if ( aNameString.EqualsAscii( SC_UNONAME_AUTOSHOW ) )
+ {
+ const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
+ if (pInfo)
+ aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASLAYOUTINFO ) )
+ aRet = ::cppu::bool2any(getLayoutInfo() != NULL);
+ else if ( aNameString.EqualsAscii( SC_UNONAME_LAYOUTINFO ) )
+ {
+ const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
+ if (pInfo)
+ aRet <<= DataPilotFieldLayoutInfo(*pInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASREFERENCE ) )
+ aRet = ::cppu::bool2any(getReference() != NULL);
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFERENCE ) )
+ {
+ const DataPilotFieldReference* pRef = getReference();
+ if (pRef)
+ aRet <<= DataPilotFieldReference(*pRef);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HASSORTINFO ) )
+ aRet = ::cppu::bool2any(getSortInfo() != NULL);
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SORTINFO ) )
+ {
+ const DataPilotFieldSortInfo* pInfo = getSortInfo();
+ if (pInfo)
+ aRet <<= DataPilotFieldSortInfo(*pInfo);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ISGROUP ) )
+ aRet = ::cppu::bool2any(hasGroupInfo());
+ else if ( aNameString.EqualsAscii( SC_UNONAME_GROUPINFO ) )
+ {
+ aRet <<= getGroupInfo();
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_SHOWEMPTY ) )
+ aRet <<= getShowEmpty();
+
+ return aRet;
+}
+
+// XDatePilotField
+
+Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!mxItems.is())
+ mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
+ return mxItems;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
+
+DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
+}
+
+void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
+{
+ ScUnoGuard aGuard;
+ if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
+ return;
+
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+
+ /* If the field was taken from getDataPilotFields(), don't reset the
+ orientation for an existing use, but create a duplicated field
+ instead (for "Data" orientation only). */
+ if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
+ (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
+ (eNew == DataPilotFieldOrientation_DATA) )
+ {
+
+ ScDPSaveDimension* pNewDim = 0;
+
+ // look for existing duplicate with orientation "hidden"
+
+ String aNameStr( maFieldId.maFieldName );
+ const List& rDimensions = pSaveData->GetDimensions();
+ sal_Int32 nDimCount = rDimensions.Count();
+ sal_Int32 nFound = 0;
+ for ( sal_Int32 nDim = 0; nDim < nDimCount && !pNewDim; nDim++ )
+ {
+ ScDPSaveDimension* pOneDim = static_cast<ScDPSaveDimension*>(rDimensions.GetObject(nDim));
+ if ( !pOneDim->IsDataLayout() && (pOneDim->GetName() == aNameStr) )
+ {
+ if ( pOneDim->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
+ pNewDim = pOneDim; // use this one
+ else
+ ++nFound; // count existing non-hidden occurences
+ }
+ }
+
+ if ( !pNewDim ) // if none found, create a new duplicated dimension
+ pNewDim = &pSaveData->DuplicateDimension( *pDim );
+
+ maFieldId.mnFieldIdx = nFound; // keep accessing the new one
+ pDim = pNewDim;
+ }
+
+ pDim->SetOrientation(sal::static_int_cast<USHORT>(eNew));
+
+ // move changed field behind all other fields (make it the last field in dimension)
+ pSaveData->SetPosition( pDim, pSaveData->GetDimensions().Count() );
+
+ SetDPObject( pDPObj );
+
+ maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
+ }
+}
+
+GeneralFunction ScDataPilotFieldObj::getFunction() const
+{
+ ScUnoGuard aGuard;
+ GeneralFunction eRet = GeneralFunction_NONE;
+ if( ScDPSaveDimension* pDim = GetDPDimension() )
+ {
+ if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
+ {
+ // for non-data fields, property Function is the subtotals
+ long nSubCount = pDim->GetSubTotalsCount();
+ if ( nSubCount > 0 )
+ eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
+ // else keep NONE
+ }
+ else
+ eRet = (GeneralFunction)pDim->GetFunction();
+ }
+ return eRet;
+}
+
+void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
+ {
+ // for non-data fields, property Function is the subtotals
+ if ( eNewFunc == GeneralFunction_NONE )
+ pDim->SetSubTotals( 0, NULL );
+ else
+ {
+ USHORT nFunc = sal::static_int_cast<USHORT>( eNewFunc );
+ pDim->SetSubTotals( 1, &nFunc );
+ }
+ }
+ else
+ pDim->SetFunction( sal::static_int_cast<USHORT>( eNewFunc ) );
+ SetDPObject( pDPObj );
+ }
+}
+
+Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
+{
+ ScUnoGuard aGuard;
+ Sequence< GeneralFunction > aRet;
+ if( ScDPSaveDimension* pDim = GetDPDimension() )
+ {
+ if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
+ {
+ // for non-data fields, property Functions is the sequence of subtotals
+ sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
+ if ( nCount > 0 )
+ {
+ aRet.realloc( nCount );
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
+ }
+ }
+ }
+ return aRet;
+}
+
+void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
+ {
+ sal_Int32 nCount = rSubtotals.getLength();
+ if( nCount == 1 )
+ {
+ // count 1: all values are allowed (including NONE and AUTO)
+ if( rSubtotals[ 0 ] == GeneralFunction_NONE )
+ pDim->SetSubTotals( 0, NULL );
+ else
+ {
+ USHORT nFunc = sal::static_int_cast<USHORT>( rSubtotals[ 0 ] );
+ pDim->SetSubTotals( 1, &nFunc );
+ }
+ }
+ else if( nCount > 1 )
+ {
+ // set multiple functions, ignore NONE and AUTO in this case
+ ::std::vector< USHORT > aSubt;
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ GeneralFunction eFunc = rSubtotals[ nIdx ];
+ if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
+ {
+ // do not insert functions twice
+ USHORT nFunc = static_cast< USHORT >( eFunc );
+ if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
+ aSubt.push_back( nFunc );
+ }
+ }
+ // set values from vector to ScDPSaveDimension
+ if ( aSubt.empty() )
+ pDim->SetSubTotals( 0, NULL );
+ else
+ pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
+ }
+ }
+ SetDPObject( pDPObj );
+ }
+}
+
+OUString ScDataPilotFieldObj::getCurrentPage() const
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ if( pDim && pDim->HasCurrentPage() )
+ return pDim->GetCurrentPage();
+ return OUString();
+}
+
+void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ String aPage( rPage );
+ pDim->SetCurrentPage( &aPage );
+ SetDPObject( pDPObj );
+ }
+}
+
+sal_Bool ScDataPilotFieldObj::getUseCurrentPage() const
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim && pDim->HasCurrentPage();
+}
+
+void ScDataPilotFieldObj::setUseCurrentPage( sal_Bool bUse )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ if( bUse )
+ {
+ /* It is somehow useless to set the property "HasSelectedPage" to
+ true, because it is still needed to set an explicit page name. */
+ if( !pDim->HasCurrentPage() )
+ {
+ String aPage;
+ pDim->SetCurrentPage( &aPage );
+ }
+ }
+ else
+ pDim->SetCurrentPage( 0 );
+ SetDPObject( pDPObj );
+ }
+}
+
+const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim ? pDim->GetAutoShowInfo() : 0;
+}
+
+void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ pDim->SetAutoShowInfo( pInfo );
+ SetDPObject( pDPObj );
+ }
+}
+
+const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim ? pDim->GetLayoutInfo() : 0;
+}
+
+void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ pDim->SetLayoutInfo( pInfo );
+ SetDPObject( pDPObj );
+ }
+}
+
+const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim ? pDim->GetReferenceValue() : 0;
+}
+
+void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ pDim->SetReferenceValue( pInfo );
+ SetDPObject( pDPObj );
+ }
+}
+
+const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim ? pDim->GetSortInfo() : 0;
+}
+
+void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ pDim->SetSortInfo( pInfo );
+ SetDPObject( pDPObj );
+ }
+}
+
+sal_Bool ScDataPilotFieldObj::getShowEmpty() const
+{
+ ScUnoGuard aGuard;
+ ScDPSaveDimension* pDim = GetDPDimension();
+ return pDim && pDim->GetShowEmpty();
+}
+
+void ScDataPilotFieldObj::setShowEmpty( sal_Bool bShow )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ pDim->SetShowEmpty( bShow );
+ SetDPObject( pDPObj );
+ }
+}
+
+sal_Bool ScDataPilotFieldObj::hasGroupInfo()
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
+ return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
+ return sal_False;
+}
+
+DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
+{
+ ScUnoGuard aGuard;
+ DataPilotFieldGroupInfo aInfo;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
+ {
+ if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
+ {
+ // grouped by ...
+ aInfo.GroupBy = pGroupDim->GetDatePart();
+
+ // find source field
+ try
+ {
+ Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
+ aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+
+ ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
+ if( pGroupDim->GetDatePart() == 0 )
+ {
+ // fill vector of group and group member information
+ ScFieldGroups aGroups;
+ for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
+ {
+ if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
+ {
+ ScFieldGroup aGroup;
+ aGroup.maName = pGroup->GetGroupName();
+ for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
+ if( const String* pMem = pGroup->GetElementByIndex( nMemIdx ) )
+ aGroup.maMembers.push_back( *pMem );
+ aGroups.push_back( aGroup );
+ }
+ }
+ aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
+ }
+ }
+ else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
+ {
+ if (pNumGroupDim->GetDatePart())
+ {
+ ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
+ aInfo.GroupBy = pNumGroupDim->GetDatePart();
+ }
+ else
+ {
+ ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
+ }
+ }
+ }
+ }
+ return aInfo;
+}
+
+void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
+ {
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if( pInfo && lclCheckMinMaxStep( *pInfo ) )
+ {
+ ScDPNumGroupInfo aInfo;
+ aInfo.Enable = sal_True;
+ aInfo.DateValues = pInfo->HasDateValues;
+ aInfo.AutoStart = pInfo->HasAutoStart;
+ aInfo.AutoEnd = pInfo->HasAutoEnd;
+ aInfo.Start = pInfo->Start;
+ aInfo.End = pInfo->End;
+ aInfo.Step = pInfo->Step;
+ Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
+ if( xNamed.is() )
+ {
+ ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
+ if( pInfo->GroupBy )
+ aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
+ else
+ {
+ Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nCount(xIndex->getCount());
+ for(sal_Int32 i = 0; i < nCount; i++)
+ {
+ Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
+ if (xGroupNamed.is())
+ {
+ ScDPSaveGroupItem aItem(xGroupNamed->getName());
+ Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
+ if (xGroupIndex.is())
+ {
+ sal_Int32 nItemCount(xGroupIndex->getCount());
+ for (sal_Int32 j = 0; j < nItemCount; ++j)
+ {
+ Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
+ if (xItemNamed.is())
+ aItem.AddElement(xItemNamed->getName());
+ }
+ }
+ aGroupDim.AddGroupItem(aItem);
+ }
+ }
+ }
+ }
+
+ // get dimension savedata or create new if none
+ ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
+ rDimSaveData.ReplaceGroupDimension( aGroupDim );
+ }
+ else // no source field in group info -> numeric group
+ {
+ ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData(); // created if not there
+
+ ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
+ if ( pExisting )
+ {
+ if (pInfo->GroupBy)
+ pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
+ // modify existing group dimension
+ pExisting->SetGroupInfo( aInfo );
+ }
+ else if (pInfo->GroupBy)
+ {
+ // create new group dimension
+ ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+ else
+ {
+ // create new group dimension
+ ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+ }
+ }
+ else // null passed as argument
+ {
+ pSaveData->SetDimensionData( 0 );
+ }
+
+ pDPObj->SetSaveData( *pSaveData );
+ SetDPObject( pDPObj );
+ }
+}
+
+sal_Bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
+{
+ sal_Bool bRet = sal_False;
+
+ sal_Int32 nCount(rItems.getLength());
+ sal_Int32 nItem(0);
+ while (nItem < nCount && !bRet)
+ {
+ bRet = rItems[nItem] == aString;
+ ++nItem;
+ }
+
+ return bRet;
+}
+
+// XDataPilotFieldGrouping
+Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
+ throw (RuntimeException, IllegalArgumentException)
+{
+ ScUnoGuard aGuard;
+
+ Reference< XDataPilotField > xRet;
+ OUString sNewDim;
+
+ if( !rItems.hasElements() )
+ throw IllegalArgumentException();
+
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ String aDimName = pDim->GetName();
+
+ ScDPSaveData aSaveData = *pDPObj->GetSaveData();
+ ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
+
+ // find original base
+ String aBaseDimName( aDimName );
+ const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
+ if ( pBaseGroupDim )
+ {
+ // any entry's SourceDimName is the original base
+ aBaseDimName = pBaseGroupDim->GetSourceDimName();
+ }
+
+ // find existing group dimension
+ // (using the selected dim, can be intermediate group dim)
+ ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
+
+ // remove the selected items from their groups
+ // (empty groups are removed, too)
+ sal_Int32 nEntryCount = rItems.getLength();
+ sal_Int32 nEntry;
+ if ( pGroupDimension )
+ {
+ for (nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName(rItems[nEntry]);
+ if ( pBaseGroupDim )
+ {
+ // for each selected (intermediate) group, remove all its items
+ // (same logic as for adding, below)
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
+ if ( pBaseGroup )
+ pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
+ else
+ pGroupDimension->RemoveFromGroups( aEntryName );
+ }
+ else
+ pGroupDimension->RemoveFromGroups( aEntryName );
+ }
+ }
+
+ ScDPSaveGroupDimension* pNewGroupDim = 0;
+ if ( !pGroupDimension )
+ {
+ // create a new group dimension
+ String aGroupDimName = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
+ pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, aGroupDimName );
+ sNewDim = aGroupDimName;
+
+ pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
+
+ if ( pBaseGroupDim )
+ {
+ // If it's a higher-order group dimension, pre-allocate groups for all
+ // non-selected original groups, so the individual base members aren't
+ // used for automatic groups (this would make the original groups hard
+ // to find).
+ //! Also do this when removing groups?
+ //! Handle this case dynamically with automatic groups?
+
+ long nGroupCount = pBaseGroupDim->GetGroupCount();
+ for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
+ {
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
+
+ StrData aStrData( pBaseGroup->GetGroupName() );
+ if ( !HasString(rItems, aStrData.GetString()) ) //! ignore case?
+ {
+ // add an additional group for each item that is not in the selection
+ ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
+ aGroup.AddElementsFromGroup( *pBaseGroup );
+ pGroupDimension->AddGroupItem( aGroup );
+ }
+ }
+ }
+ }
+ String aGroupDimName = pGroupDimension->GetGroupDimName();
+
+ //! localized prefix string
+ String aGroupName = pGroupDimension->CreateGroupName( String( RTL_CONSTASCII_USTRINGPARAM( "Group" ) ) );
+ ScDPSaveGroupItem aGroup( aGroupName );
+ Reference< XNameAccess > xMembers = GetMembers();
+ if (!xMembers.is())
+ {
+ delete pNewGroupDim;
+ throw RuntimeException();
+ }
+
+ for (nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName(rItems[nEntry]);
+
+ if (!xMembers->hasByName(aEntryName))
+ {
+ delete pNewGroupDim;
+ throw IllegalArgumentException();
+ }
+
+ if ( pBaseGroupDim )
+ {
+ // for each selected (intermediate) group, add all its items
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
+ if ( pBaseGroup )
+ aGroup.AddElementsFromGroup( *pBaseGroup );
+ else
+ aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
+ }
+ else
+ aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
+ }
+
+ pGroupDimension->AddGroupItem( aGroup );
+
+ if ( pNewGroupDim )
+ {
+ pDimData->AddGroupDimension( *pNewGroupDim );
+ delete pNewGroupDim; // AddGroupDimension copies the object
+ // don't access pGroupDimension after here
+ }
+ pGroupDimension = pNewGroupDim = NULL;
+
+ // set orientation
+ ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
+ if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
+ {
+ ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
+ pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
+ long nPosition = 0; //! before (immediate) base
+ aSaveData.SetPosition( pSaveDimension, nPosition );
+ }
+
+ // apply changes
+ pDPObj->SetSaveData( aSaveData );
+ SetDPObject( pDPObj );
+ }
+
+ // if new grouping field has been created (on first group), return it
+ if( sNewDim.getLength() > 0 )
+ {
+ Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
+ if (xFields.is())
+ {
+ xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
+ DBG_ASSERT(xRet.is(), "there is a name, so there should be also a field");
+ }
+ }
+ return xRet;
+}
+
+Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
+ throw (RuntimeException, IllegalArgumentException)
+{
+ ScUnoGuard aGuard;
+ using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
+
+ // check min/max/step, HasDateValues must be set always
+ if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
+ throw IllegalArgumentException();
+ // only a single date flag is allowed
+ if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
+ throw IllegalArgumentException();
+ // step must be zero, if something else than DAYS is specified
+ if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
+ throw IllegalArgumentException();
+
+ String aGroupDimName;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ ScDPNumGroupInfo aInfo;
+ aInfo.Enable = sal_True;
+ aInfo.DateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
+ aInfo.AutoStart = rInfo.HasAutoStart;
+ aInfo.AutoEnd = rInfo.HasAutoEnd;
+ aInfo.Start = rInfo.Start;
+ aInfo.End = rInfo.End;
+ aInfo.Step = static_cast< sal_Int32 >( rInfo.Step );
+
+ // create a local copy of the entire save data (will be written back below)
+ ScDPSaveData aSaveData = *pDPObj->GetSaveData();
+ // get or create dimension save data
+ ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
+
+ // find source dimension name
+ const String& rDimName = pDim->GetName();
+ const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
+ String aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
+
+ // find a group dimension for the base field, or get numeric grouping
+ pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
+ const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
+
+ // do not group by dates, if named groups or numeric grouping is present
+ bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().Enable;
+ bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().Enable && !pNumGroupDim->GetInfo().DateValues && !pNumGroupDim->GetDateInfo().Enable;
+ if( bHasNamedGrouping || bHasNumGrouping )
+ throw IllegalArgumentException();
+
+ if( aInfo.DateValues ) // create day ranges grouping
+ {
+ // first remove all named group dimensions
+ while( pGroupDim )
+ {
+ String aGroupDimName2 = pGroupDim->GetGroupDimName();
+ // find next group dimension before deleting this group
+ pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
+ // remove from dimension save data
+ rDimData.RemoveGroupDimension( aGroupDimName2 );
+ // also remove save data settings for the dimension that no longer exists
+ aSaveData.RemoveDimensionByName( aGroupDimName2 );
+ }
+ // create or replace the number grouping dimension
+ ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
+ rDimData.ReplaceNumGroupDimension( aNumGroupDim );
+ }
+ else // create date grouping
+ {
+ // collect all existing date flags
+ sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
+ if( nDateParts == 0 )
+ {
+ // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
+ ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
+ rDimData.ReplaceNumGroupDimension( aNumGroupDim );
+ }
+ else if( (nDateParts & rInfo.GroupBy) == 0 ) // do nothing if date field exists already
+ {
+ // create new named group dimension for additional date groups
+ aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
+ ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
+ rDimData.AddGroupDimension( aGroupDim );
+
+ // set orientation of new named group dimension
+ ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
+ if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
+ {
+ ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
+ rSaveDim.SetOrientation( rOldDim.GetOrientation() );
+ aSaveData.SetPosition( &rSaveDim, 0 ); //! before (immediate) base
+ }
+ }
+ }
+
+ // apply changes
+ pDPObj->SetSaveData( aSaveData );
+ SetDPObject( pDPObj );
+ }
+
+ // return the UNO object of the new dimension, after writing back saved data
+ Reference< XDataPilotField > xRet;
+ if( aGroupDimName.Len() > 0 ) try
+ {
+ Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
+ xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xRet;
+}
+
+// ============================================================================
+
+namespace {
+
+bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
+{
+ // allow empty value to create a new group
+ if( !rElement.hasValue() )
+ return true;
+
+ // try to extract a simple sequence of strings
+ Sequence< OUString > aSeq;
+ if( rElement >>= aSeq )
+ {
+ if( aSeq.hasElements() )
+ rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
+ return true;
+ }
+
+ // try to use XIndexAccess providing objects that support XNamed
+ Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
+ if( xItemsIA.is() )
+ {
+ for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
+ {
+ try // getByIndex() should not throw, but we cannot be sure
+ {
+ Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
+ rMembers.push_back( xItemName->getName() );
+ }
+ catch( Exception& )
+ {
+ // ignore exceptions, go ahead with next element in the array
+ }
+ }
+ return true;
+ }
+
+ // nothing valid inside the Any -> return false
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
+ maGroups( rGroups )
+{
+}
+
+ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
+{
+}
+
+// XNameAccess
+
+Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if( implFindByName( rName ) == maGroups.end() )
+ throw NoSuchElementException();
+ return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
+}
+
+Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Sequence< OUString > aSeq;
+ if( !maGroups.empty() )
+ {
+ aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
+ OUString* pName = aSeq.getArray();
+ for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
+ *pName = aIt->maName;
+ }
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return implFindByName( rName ) != maGroups.end();
+}
+
+// XNameReplace
+
+void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
+ throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if( rName.getLength() == 0 )
+ throw IllegalArgumentException();
+
+ ScFieldGroups::iterator aIt = implFindByName( rName );
+ if( aIt == maGroups.end() )
+ throw NoSuchElementException();
+
+ // read all item names provided by the passed object
+ ScFieldGroupMembers aMembers;
+ if( !lclExtractGroupMembers( aMembers, rElement ) )
+ throw IllegalArgumentException();
+
+ // copy and forget, faster than vector assignment
+ aIt->maMembers.swap( aMembers );
+}
+
+// XNameContainer
+
+void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
+ throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if( rName.getLength() == 0 )
+ throw IllegalArgumentException();
+
+ ScFieldGroups::iterator aIt = implFindByName( rName );
+ if( aIt != maGroups.end() )
+ throw ElementExistException();
+
+ // read all item names provided by the passed object
+ ScFieldGroupMembers aMembers;
+ if( !lclExtractGroupMembers( aMembers, rElement ) )
+ throw IllegalArgumentException();
+
+ // create the new entry if no error has been occured
+ maGroups.resize( maGroups.size() + 1 );
+ ScFieldGroup& rGroup = maGroups.back();
+ rGroup.maName = rName;
+ rGroup.maMembers.swap( aMembers );
+}
+
+void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
+ throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if( rName.getLength() == 0 )
+ throw IllegalArgumentException();
+
+ ScFieldGroups::iterator aIt = implFindByName( rName );
+ if( aIt == maGroups.end() )
+ throw NoSuchElementException();
+
+ maGroups.erase( aIt );
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return static_cast< sal_Int32 >( maGroups.size() );
+}
+
+Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
+ throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
+ throw IndexOutOfBoundsException();
+ return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
+}
+
+// XEnumerationAccess
+
+Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration( this, OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) ) );
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType( (Reference< XNameAccess >*)0 );
+}
+
+sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return !maGroups.empty();
+}
+
+// implementation
+
+ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScFieldGroups::iterator aIt = implFindByName( rName );
+ if( aIt == maGroups.end() )
+ throw RuntimeException();
+ return *aIt;
+}
+
+void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
+ ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
+ // new name must not exist yet
+ if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
+ throw RuntimeException();
+ aOldIt->maName = rNewName;
+}
+
+// private
+
+ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
+{
+ for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
+ if( aIt->maName == rName )
+ return aIt;
+ return maGroups.end();
+}
+
+// ============================================================================
+
+namespace {
+
+OUString lclExtractMember( const Any& rElement )
+{
+ if( rElement.has< OUString >() )
+ return rElement.get< OUString >();
+
+ Reference< XNamed > xNamed( rElement, UNO_QUERY );
+ if( xNamed.is() )
+ return xNamed->getName();
+
+ return OUString();
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
+ mrParent( rParent ),
+ maGroupName( rGroupName )
+{
+ mrParent.acquire();
+}
+
+ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
+{
+ mrParent.release();
+}
+
+// XNameAccess
+
+Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
+ ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
+ if( aIt == rMembers.end() )
+ throw NoSuchElementException();
+ return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
+}
+
+Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
+}
+
+sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
+ return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
+}
+
+// XNameReplace
+
+void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
+ throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // it should be possible to quickly rename an item -> accept string or XNamed
+ OUString aNewName = lclExtractMember( rElement );
+ if( (rName.getLength() == 0) || (aNewName.getLength() == 0) )
+ throw IllegalArgumentException();
+ if( rName == aNewName )
+ return;
+
+ ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
+ ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
+ ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
+ // throw if passed member name does not exist
+ if( aOldIt == rMembers.end() )
+ throw NoSuchElementException();
+ // throw if new name already exists
+ if( aNewIt != rMembers.end() )
+ throw IllegalArgumentException();
+ *aOldIt = aNewName;
+}
+
+// XNameContainer
+
+void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
+ throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // we will ignore the passed element and just try to insert the name
+ if( rName.getLength() == 0 )
+ throw IllegalArgumentException();
+
+ ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
+ ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
+ // throw if passed name already exists
+ if( aIt != rMembers.end() )
+ throw IllegalArgumentException();
+ rMembers.push_back( rName );
+}
+
+void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
+ throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if( rName.getLength() == 0 )
+ throw IllegalArgumentException();
+ ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
+ ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
+ // throw if passed name does not exist
+ if( aIt == rMembers.end() )
+ throw NoSuchElementException();
+ rMembers.erase( aIt );
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
+}
+
+Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
+ throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
+ if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
+ throw IndexOutOfBoundsException();
+ return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
+}
+
+// XEnumerationAccess
+
+Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration( this, OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) ) );
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType( (Reference< XNamed >*)0 );
+}
+
+sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
+}
+
+// XNamed
+
+OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return maGroupName;
+}
+
+void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ mrParent.renameFieldGroup( maGroupName, rName );
+ // if call to renameFieldGroup() did not throw, remember the new name
+ maGroupName = rName;
+}
+
+// ============================================================================
+
+ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
+ mrParent( rParent ),
+ maName( rName )
+{
+ mrParent.acquire();
+}
+
+ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
+{
+ mrParent.release();
+}
+
+// XNamed
+
+OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return maName;
+}
+
+void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ mrParent.replaceByName( maName, Any( rName ) );
+ // if call to replaceByName() did not throw, remember the new name
+ maName = rName;
+}
+
+// ============================================================================
+
+ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
+ ScDataPilotChildObjBase( rParent, rFieldId )
+{
+}
+
+ScDataPilotItemsObj::~ScDataPilotItemsObj()
+{
+}
+
+// XDataPilotItems
+
+ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
+{
+ return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
+ new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
+}
+
+// XNameAccess
+
+Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference<XNameAccess> xMembers = GetMembers();
+ if (xMembers.is())
+ {
+ Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
+ sal_Int32 nCount = xMembersIndex->getCount();
+ sal_Bool bFound(sal_False);
+ sal_Int32 nItem = 0;
+ while (nItem < nCount && !bFound )
+ {
+ Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
+ if (xMember.is() && (aName == xMember->getName()))
+ return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
+ ++nItem;
+ }
+ if (!bFound)
+ throw NoSuchElementException();
+ }
+ return Any();
+}
+
+Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Sequence< OUString > aSeq;
+ if( ScDPObject* pDPObj = GetDPObject() )
+ pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Bool bFound = sal_False;
+ Reference<XNameAccess> xMembers = GetMembers();
+ if (xMembers.is())
+ {
+ Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
+ sal_Int32 nCount = xMembersIndex->getCount();
+ sal_Int32 nItem = 0;
+ while (nItem < nCount && !bFound )
+ {
+ Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
+ if (xMember.is() && aName == xMember->getName())
+ bFound = sal_True;
+ else
+ nItem++;
+ }
+ }
+ return bFound;
+}
+
+// XEnumerationAccess
+
+Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotItemsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetMemberCount();
+}
+
+Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
+ throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
+ if (!xItem.is())
+ throw IndexOutOfBoundsException();
+ return Any( xItem );
+}
+
+uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((Reference<XPropertySet>*)0);
+}
+
+sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+//------------------------------------------------------------------------
+
+ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
+ ScDataPilotChildObjBase( rParent, rFieldId ),
+ maPropSet( lcl_GetDataPilotItemMap() ),
+ mnIndex( nIndex )
+{
+}
+
+ScDataPilotItemObj::~ScDataPilotItemObj()
+{
+}
+
+ // XNamed
+OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ OUString sRet;
+ Reference<XNameAccess> xMembers = GetMembers();
+ if (xMembers.is())
+ {
+ Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
+ sal_Int32 nCount = xMembersIndex->getCount();
+ if (mnIndex < nCount)
+ {
+ Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
+ sRet = xMember->getName();
+ }
+ }
+ return sRet;
+}
+
+void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
+ throw(RuntimeException)
+{
+}
+
+ // XPropertySet
+Reference< XPropertySetInfo >
+ SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
+ throw(RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static Reference<XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
+ return aRef;
+}
+
+void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDPObject* pDPObj = 0;
+ if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
+ {
+ Reference<XNameAccess> xMembers = GetMembers();
+ if( xMembers.is() )
+ {
+ Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
+ sal_Int32 nCount = xMembersIndex->getCount();
+ if( mnIndex < nCount )
+ {
+ Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
+ String sName(xMember->getName());
+ ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
+ if (pMember)
+ {
+ bool bGetNewIndex = false;
+ if ( aPropertyName.equalsAscii( SC_UNONAME_SHOWDETAIL ) )
+ pMember->SetShowDetails(cppu::any2bool(aValue));
+ else if ( aPropertyName.equalsAscii( SC_UNONAME_ISHIDDEN ) )
+ pMember->SetIsVisible(!cppu::any2bool(aValue));
+ else if ( aPropertyName.equalsAscii( SC_UNONAME_POS ) )
+ {
+ sal_Int32 nNewPos = 0;
+ if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
+ {
+ pDim->SetMemberPosition( sName, nNewPos );
+ // get new effective index (depends on sorting mode, which isn't modified)
+ bGetNewIndex = true;
+ }
+ else
+ throw IllegalArgumentException();
+ }
+ SetDPObject( pDPObj );
+
+ if ( bGetNewIndex ) // after SetDPObject, get the new index
+ {
+ OUString aOUName( sName );
+ Sequence< OUString > aItemNames = xMembers->getElementNames();
+ sal_Int32 nItemCount = aItemNames.getLength();
+ for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
+ if (aItemNames[nItem] == aOUName)
+ mnIndex = nItem;
+ }
+ }
+ }
+ }
+ }
+}
+
+Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Any aRet;
+ if( ScDPSaveDimension* pDim = GetDPDimension() )
+ {
+ Reference< XNameAccess > xMembers = GetMembers();
+ if( xMembers.is() )
+ {
+ Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
+ sal_Int32 nCount = xMembersIndex->getCount();
+ if( mnIndex < nCount )
+ {
+ Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
+ String sName( xMember->getName() );
+ ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
+ if( aPropertyName.equalsAscii( SC_UNONAME_SHOWDETAIL ) )
+ {
+ if (pMember && pMember->HasShowDetails())
+ {
+ aRet <<= (bool)pMember->GetShowDetails();
+ }
+ else
+ {
+ Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
+ if( xMemberProps.is() )
+ aRet = xMemberProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA ) ) );
+ else
+ aRet <<= true;
+ }
+ }
+ else if ( aPropertyName.equalsAscii( SC_UNONAME_ISHIDDEN ) )
+ {
+ if (pMember && pMember->HasIsVisible())
+ {
+ aRet <<= !pMember->GetIsVisible();
+ }
+ else
+ {
+ Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
+ if( xMemberProps.is() )
+ aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL ) ) ) );
+ else
+ aRet <<= false;
+ }
+ }
+ else if ( aPropertyName.equalsAscii( SC_UNONAME_POS ) )
+ {
+ aRet <<= mnIndex;
+ }
+ }
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
+ const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
+ const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
+ const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
+ const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+//------------------------------------------------------------------------
+
+
+
+
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
new file mode 100644
index 000000000000..6e416764eb76
--- /dev/null
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -0,0 +1,2371 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+#include <svl/smplhint.hxx>
+#include <svl/zforlist.hxx>
+#include <rtl/uuid.h>
+
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/util/SortField.hpp>
+#include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#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"
+#include "cellsuno.hxx"
+#include "miscuno.hxx"
+#include "targuno.hxx"
+#include "rangeutl.hxx"
+#include "dbcolect.hxx"
+#include "docsh.hxx"
+#include "dbdocfun.hxx"
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "globstr.hrc"
+#ifndef SC_CONVUNO_HXX
+#include "convuno.hxx"
+#include "hints.hxx"
+#endif
+#include "attrib.hxx"
+#include "dpshttab.hxx"
+#include <comphelper/extract.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+
+using namespace com::sun::star;
+
+SV_IMPL_PTRARR( XDBRefreshListenerArr_Impl, XDBRefreshListenerPtr );
+
+//------------------------------------------------------------------------
+
+// alles ohne Which-ID, Map nur fuer PropertySetInfo
+
+const SfxItemPropertyMapEntry* lcl_GetSubTotalPropertyMap()
+{
+ // some old property names are for 5.2 compatibility
+
+ static SfxItemPropertyMapEntry aSubTotalPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_BINDFMT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_CASE), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ENABSORT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ENUSLIST), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_FORMATS), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_INSBRK), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ISCASE), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_MAXFLD), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SORTASC), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ULIST), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_UINDEX), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_USINDEX), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aSubTotalPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* lcl_GetFilterPropertyMap()
+{
+ static SfxItemPropertyMapEntry aFilterPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_CONTHDR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_COPYOUT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ISCASE), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_MAXFLD), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ORIENT), 0, &getCppuType((table::TableOrientation*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_OUTPOS), 0, &getCppuType((table::CellAddress*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SAVEOUT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SKIPDUP), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_USEREGEX), 0, &getBooleanCppuType(), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aFilterPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* lcl_GetDBRangePropertyMap()
+{
+ static SfxItemPropertyMapEntry aDBRangePropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_AUTOFLT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_FLTCRT), 0, &getCppuType((table::CellRangeAddress*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_FROMSELECT),0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ISUSER), 0, &getBooleanCppuType(), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_KEEPFORM), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT), 0, &getCppuType((uno::Reference<awt::XBitmap>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), 0, &getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_MOVCELLS), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_STRIPDAT), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_TOKENINDEX),0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_USEFLTCRT),0, &getBooleanCppuType(), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aDBRangePropertyMap_Impl;
+}
+
+
+//------------------------------------------------------------------------
+
+#define SCDATABASERANGEOBJ_SERVICE "com.sun.star.sheet.DatabaseRange"
+
+SC_SIMPLE_SERVICE_INFO( ScConsolidationDescriptor, "ScConsolidationDescriptor", "com.sun.star.sheet.ConsolidationDescriptor" )
+SC_SIMPLE_SERVICE_INFO( ScDatabaseRangesObj, "ScDatabaseRangesObj", "com.sun.star.sheet.DatabaseRanges" )
+SC_SIMPLE_SERVICE_INFO( ScFilterDescriptorBase, "ScFilterDescriptorBase", "com.sun.star.sheet.SheetFilterDescriptor" )
+SC_SIMPLE_SERVICE_INFO( ScSubTotalDescriptorBase, "ScSubTotalDescriptorBase", "com.sun.star.sheet.SubTotalDescriptor" )
+SC_SIMPLE_SERVICE_INFO( ScSubTotalFieldObj, "ScSubTotalFieldObj", "com.sun.star.sheet.SubTotalField" )
+
+
+//------------------------------------------------------------------------
+
+// static
+ScSubTotalFunc ScDataUnoConversion::GeneralToSubTotal( sheet::GeneralFunction eSummary )
+{
+ ScSubTotalFunc eSubTotal;
+ switch (eSummary)
+ {
+ case sheet::GeneralFunction_NONE: eSubTotal = SUBTOTAL_FUNC_NONE; break;
+ case sheet::GeneralFunction_SUM: eSubTotal = SUBTOTAL_FUNC_SUM; break;
+ case sheet::GeneralFunction_COUNT: eSubTotal = SUBTOTAL_FUNC_CNT2; break;
+ case sheet::GeneralFunction_AVERAGE: eSubTotal = SUBTOTAL_FUNC_AVE; break;
+ case sheet::GeneralFunction_MAX: eSubTotal = SUBTOTAL_FUNC_MAX; break;
+ case sheet::GeneralFunction_MIN: eSubTotal = SUBTOTAL_FUNC_MIN; break;
+ case sheet::GeneralFunction_PRODUCT: eSubTotal = SUBTOTAL_FUNC_PROD; break;
+ case sheet::GeneralFunction_COUNTNUMS: eSubTotal = SUBTOTAL_FUNC_CNT; break;
+ case sheet::GeneralFunction_STDEV: eSubTotal = SUBTOTAL_FUNC_STD; break;
+ case sheet::GeneralFunction_STDEVP: eSubTotal = SUBTOTAL_FUNC_STDP; break;
+ case sheet::GeneralFunction_VAR: eSubTotal = SUBTOTAL_FUNC_VAR; break;
+ case sheet::GeneralFunction_VARP: eSubTotal = SUBTOTAL_FUNC_VARP; break;
+ case sheet::GeneralFunction_AUTO:
+ default:
+ DBG_ERROR("GeneralToSubTotal: falscher enum");
+ eSubTotal = SUBTOTAL_FUNC_NONE;
+ }
+ return eSubTotal;
+}
+
+// static
+sheet::GeneralFunction ScDataUnoConversion::SubTotalToGeneral( ScSubTotalFunc eSubTotal )
+{
+ sheet::GeneralFunction eGeneral;
+ switch (eSubTotal)
+ {
+ case SUBTOTAL_FUNC_NONE: eGeneral = sheet::GeneralFunction_NONE; break;
+ case SUBTOTAL_FUNC_AVE: eGeneral = sheet::GeneralFunction_AVERAGE; break;
+ case SUBTOTAL_FUNC_CNT: eGeneral = sheet::GeneralFunction_COUNTNUMS; break;
+ case SUBTOTAL_FUNC_CNT2: eGeneral = sheet::GeneralFunction_COUNT; break;
+ case SUBTOTAL_FUNC_MAX: eGeneral = sheet::GeneralFunction_MAX; break;
+ case SUBTOTAL_FUNC_MIN: eGeneral = sheet::GeneralFunction_MIN; break;
+ case SUBTOTAL_FUNC_PROD: eGeneral = sheet::GeneralFunction_PRODUCT; break;
+ case SUBTOTAL_FUNC_STD: eGeneral = sheet::GeneralFunction_STDEV; break;
+ case SUBTOTAL_FUNC_STDP: eGeneral = sheet::GeneralFunction_STDEVP; break;
+ case SUBTOTAL_FUNC_SUM: eGeneral = sheet::GeneralFunction_SUM; break;
+ case SUBTOTAL_FUNC_VAR: eGeneral = sheet::GeneralFunction_VAR; break;
+ case SUBTOTAL_FUNC_VARP: eGeneral = sheet::GeneralFunction_VARP; break;
+ default:
+ DBG_ERROR("SubTotalToGeneral: falscher enum");
+ eGeneral = sheet::GeneralFunction_NONE;
+ break;
+ }
+ return eGeneral;
+}
+
+//------------------------------------------------------------------------
+
+// ScImportDescriptor: alles static
+
+long ScImportDescriptor::GetPropertyCount()
+{
+ return 4;
+}
+
+void ScImportDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq, const ScImportParam& rParam )
+{
+ DBG_ASSERT( rSeq.getLength() == GetPropertyCount(), "falscher Count" );
+
+ beans::PropertyValue* pArray = rSeq.getArray();
+
+ sheet::DataImportMode eMode = sheet::DataImportMode_NONE;
+ if ( rParam.bImport )
+ {
+ if ( rParam.bSql )
+ eMode = sheet::DataImportMode_SQL;
+ else if ( rParam.nType == ScDbQuery )
+ eMode = sheet::DataImportMode_QUERY;
+ else
+ eMode = sheet::DataImportMode_TABLE; // Type ist immer ScDbQuery oder ScDbTable
+ }
+
+ ::svx::ODataAccessDescriptor aDescriptor;
+ aDescriptor.setDataSource(rParam.aDBName);
+ if (aDescriptor.has( svx::daDataSource ))
+ {
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_DBNAME );
+ pArray[0].Value <<= rtl::OUString( rParam.aDBName );
+ }
+ else if (aDescriptor.has( svx::daConnectionResource ))
+ {
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_CONRES );
+ pArray[0].Value <<= rtl::OUString( rParam.aDBName );
+ }
+
+ pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_SRCTYPE );
+ pArray[1].Value <<= eMode;
+
+ pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_SRCOBJ );
+ pArray[2].Value <<= rtl::OUString( rParam.aStatement );
+
+ pArray[3].Name = rtl::OUString::createFromAscii( SC_UNONAME_ISNATIVE );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[3].Value, rParam.bNative );
+}
+
+void ScImportDescriptor::FillImportParam( ScImportParam& rParam, const uno::Sequence<beans::PropertyValue>& rSeq )
+{
+ rtl::OUString aStrVal;
+ const beans::PropertyValue* pPropArray = rSeq.getConstArray();
+ long nPropCount = rSeq.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( SC_UNONAME_ISNATIVE ))
+ rParam.bNative = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_DBNAME ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ rParam.aDBName = String( aStrVal );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_CONRES ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ rParam.aDBName = String( aStrVal );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_SRCOBJ ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ rParam.aStatement = String( aStrVal );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_SRCTYPE ))
+ {
+ //! test for correct enum type?
+ sheet::DataImportMode eMode = (sheet::DataImportMode)
+ ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
+ switch (eMode)
+ {
+ case sheet::DataImportMode_NONE:
+ rParam.bImport = FALSE;
+ break;
+ case sheet::DataImportMode_SQL:
+ rParam.bImport = TRUE;
+ rParam.bSql = TRUE;
+ break;
+ case sheet::DataImportMode_TABLE:
+ rParam.bImport = TRUE;
+ rParam.bSql = FALSE;
+ rParam.nType = ScDbTable;
+ break;
+ case sheet::DataImportMode_QUERY:
+ rParam.bImport = TRUE;
+ rParam.bSql = FALSE;
+ rParam.nType = ScDbQuery;
+ break;
+ default:
+ DBG_ERROR("falscher Mode");
+ rParam.bImport = FALSE;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+// ScSortDescriptor: alles static
+
+//! SortAscending muss aus der SheetSortDescriptor service-Beschreibung raus
+
+long ScSortDescriptor::GetPropertyCount()
+{
+ return 9; // TableSortDescriptor and SheetSortDescriptor
+}
+
+void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq, const ScSortParam& rParam )
+{
+ DBG_ASSERT( rSeq.getLength() == GetPropertyCount(), "falscher Count" );
+
+ beans::PropertyValue* pArray = rSeq.getArray();
+
+ // Uno-Werte zusammensuchen
+
+ table::CellAddress aOutPos;
+ aOutPos.Sheet = rParam.nDestTab;
+ aOutPos.Column = rParam.nDestCol;
+ aOutPos.Row = rParam.nDestRow;
+
+ USHORT nSortCount = 0;
+ while ( nSortCount < MAXSORT && rParam.bDoSort[nSortCount] )
+ ++nSortCount;
+
+ uno::Sequence<table::TableSortField> aFields(nSortCount);
+ if (nSortCount)
+ {
+ table::TableSortField* pFieldArray = aFields.getArray();
+ for (USHORT i=0; i<nSortCount; i++)
+ {
+ pFieldArray[i].Field = rParam.nField[i];
+ pFieldArray[i].IsAscending = rParam.bAscending[i];
+ pFieldArray[i].FieldType = table::TableSortFieldType_AUTOMATIC; // immer Automatic
+ pFieldArray[i].IsCaseSensitive = rParam.bCaseSens;
+ pFieldArray[i].CollatorLocale = rParam.aCollatorLocale;
+ pFieldArray[i].CollatorAlgorithm = rtl::OUString( rParam.aCollatorAlgorithm );
+ }
+ }
+
+ // Sequence fuellen
+
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_ISSORTCOLUMNS );
+ pArray[0].Value = ::cppu::bool2any(!rParam.bByRow);
+
+ pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_CONTHDR );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[1].Value, rParam.bHasHeader );
+
+ pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_MAXFLD );
+ pArray[2].Value <<= (sal_Int32) MAXSORT;
+
+ pArray[3].Name = rtl::OUString::createFromAscii( SC_UNONAME_SORTFLD );
+ pArray[3].Value <<= aFields;
+
+ pArray[4].Name = rtl::OUString::createFromAscii( SC_UNONAME_BINDFMT );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[4].Value, rParam.bIncludePattern );
+
+ pArray[5].Name = rtl::OUString::createFromAscii( SC_UNONAME_COPYOUT );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[5].Value, !rParam.bInplace );
+
+ pArray[6].Name = rtl::OUString::createFromAscii( SC_UNONAME_OUTPOS );
+ pArray[6].Value <<= aOutPos;
+
+ pArray[7].Name = rtl::OUString::createFromAscii( SC_UNONAME_ISULIST );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[7].Value, rParam.bUserDef );
+
+ pArray[8].Name = rtl::OUString::createFromAscii( SC_UNONAME_UINDEX );
+ pArray[8].Value <<= (sal_Int32) rParam.nUserIndex;
+}
+
+void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const uno::Sequence<beans::PropertyValue>& rSeq )
+{
+ sal_Bool bOldSortDescriptor(sal_False);
+ sal_Bool bNewSortDescriptor(sal_False);
+ const beans::PropertyValue* pPropArray = rSeq.getConstArray();
+ long nPropCount = rSeq.getLength();
+ for (long nProp = 0; nProp < nPropCount; nProp++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[nProp];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( SC_UNONAME_ORIENT ))
+ {
+ bOldSortDescriptor = sal_True;
+ //! test for correct enum type?
+ table::TableOrientation eOrient = (table::TableOrientation)
+ ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
+ rParam.bByRow = ( eOrient != table::TableOrientation_COLUMNS );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_ISSORTCOLUMNS ))
+ {
+ bNewSortDescriptor = sal_True;
+ rParam.bByRow = !::cppu::any2bool(rProp.Value);
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_CONTHDR ))
+ rParam.bHasHeader = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_MAXFLD ))
+ {
+ sal_Int32 nVal;
+ if ( (rProp.Value >>= nVal) && nVal > MAXSORT )
+ {
+ //! specify exceptions
+ //! throw lang::IllegalArgumentException();
+ }
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_SORTFLD ))
+ {
+ uno::Sequence<util::SortField> aSeq;
+ uno::Sequence<table::TableSortField> aNewSeq;
+ if ( rProp.Value >>= aSeq )
+ {
+ bOldSortDescriptor = sal_True;
+ INT32 nCount = aSeq.getLength();
+ INT32 i;
+ if ( nCount > MAXSORT )
+ {
+ DBG_ERROR("Zu viele Sortierfelder");
+ nCount = MAXSORT;
+ }
+ const util::SortField* pFieldArray = aSeq.getConstArray();
+ for (i=0; i<nCount; i++)
+ {
+ rParam.nField[i] = (SCCOLROW)pFieldArray[i].Field;
+ rParam.bAscending[i] = pFieldArray[i].SortAscending;
+
+ // FieldType wird ignoriert
+ rParam.bDoSort[i] = TRUE;
+ }
+ for (i=nCount; i<MAXSORT; i++)
+ rParam.bDoSort[i] = FALSE;
+ }
+ else if ( rProp.Value >>= aNewSeq )
+ {
+ bNewSortDescriptor = sal_True;
+ INT32 nCount = aNewSeq.getLength();
+ INT32 i;
+ if ( nCount > MAXSORT )
+ {
+ DBG_ERROR("Zu viele Sortierfelder");
+ nCount = MAXSORT;
+ }
+ const table::TableSortField* pFieldArray = aNewSeq.getConstArray();
+ for (i=0; i<nCount; i++)
+ {
+ rParam.nField[i] = (SCCOLROW)pFieldArray[i].Field;
+ rParam.bAscending[i] = pFieldArray[i].IsAscending;
+
+ // only one is possible, sometime we should make it possible to have different for every entry
+ rParam.bCaseSens = pFieldArray[i].IsCaseSensitive;
+ rParam.aCollatorLocale = pFieldArray[i].CollatorLocale;
+ rParam.aCollatorAlgorithm = pFieldArray[i].CollatorAlgorithm;
+
+ // FieldType wird ignoriert
+ rParam.bDoSort[i] = TRUE;
+ }
+ for (i=nCount; i<MAXSORT; i++)
+ rParam.bDoSort[i] = FALSE;
+ }
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_ISCASE ))
+ {
+ bOldSortDescriptor = sal_True;
+ rParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_BINDFMT ))
+ rParam.bIncludePattern = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_COPYOUT ))
+ rParam.bInplace = !ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_OUTPOS ))
+ {
+ table::CellAddress aAddress;
+ if ( rProp.Value >>= aAddress )
+ {
+ rParam.nDestTab = aAddress.Sheet;
+ rParam.nDestCol = (SCCOL)aAddress.Column;
+ rParam.nDestRow = (SCROW)aAddress.Row;
+ }
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_ISULIST ))
+ rParam.bUserDef = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_UINDEX ))
+ {
+ sal_Int32 nVal = 0;
+ if ( rProp.Value >>= nVal )
+ rParam.nUserIndex = (USHORT)nVal;
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_COLLLOC ))
+ {
+ bOldSortDescriptor = sal_True;
+ rProp.Value >>= rParam.aCollatorLocale;
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_COLLALG ))
+ {
+ bOldSortDescriptor = sal_True;
+ rtl::OUString sStr;
+ if ( rProp.Value >>= sStr )
+ rParam.aCollatorAlgorithm = sStr;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalFieldObj::ScSubTotalFieldObj( ScSubTotalDescriptorBase* pDesc, USHORT nP ) :
+ xRef( pDesc ), // Objekt festhalten
+ rParent( *pDesc ),
+ nPos( nP )
+{
+ DBG_ASSERT(pDesc, "ScSubTotalFieldObj: Parent ist 0");
+}
+
+ScSubTotalFieldObj::~ScSubTotalFieldObj()
+{
+}
+
+// XSubTotalField
+
+sal_Int32 SAL_CALL ScSubTotalFieldObj::getGroupColumn() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ rParent.GetData(aParam);
+
+ return aParam.nField[nPos];
+}
+
+void SAL_CALL ScSubTotalFieldObj::setGroupColumn( sal_Int32 nGroupColumn ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ rParent.GetData(aParam);
+
+ aParam.nField[nPos] = (SCCOL)nGroupColumn;
+
+ rParent.PutData(aParam);
+}
+
+uno::Sequence<sheet::SubTotalColumn> SAL_CALL ScSubTotalFieldObj::getSubTotalColumns()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ rParent.GetData(aParam);
+
+ SCCOL nCount = aParam.nSubTotals[nPos];
+ uno::Sequence<sheet::SubTotalColumn> aSeq(nCount);
+ sheet::SubTotalColumn* pAry = aSeq.getArray();
+ for (SCCOL i=0; i<nCount; i++)
+ {
+ pAry[i].Column = aParam.pSubTotals[nPos][i];
+ pAry[i].Function = ScDataUnoConversion::SubTotalToGeneral(
+ aParam.pFunctions[nPos][i] );
+ }
+ return aSeq;
+}
+
+void SAL_CALL ScSubTotalFieldObj::setSubTotalColumns(
+ const uno::Sequence<sheet::SubTotalColumn>& aSubTotalColumns )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ rParent.GetData(aParam);
+
+ UINT32 nColCount = aSubTotalColumns.getLength();
+ if ( nColCount <= sal::static_int_cast<UINT32>(SCCOL_MAX) )
+ {
+ SCCOL nCount = static_cast<SCCOL>(nColCount);
+ aParam.nSubTotals[nPos] = nCount;
+ if (nCount != 0)
+ {
+ aParam.pSubTotals[nPos] = new SCCOL[nCount];
+ aParam.pFunctions[nPos] = new ScSubTotalFunc[nCount];
+
+ const sheet::SubTotalColumn* pAry = aSubTotalColumns.getConstArray();
+ for (SCCOL i=0; i<nCount; i++)
+ {
+ aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
+ aParam.pFunctions[nPos][i] =
+ ScDataUnoConversion::GeneralToSubTotal( pAry[i].Function );
+ }
+ }
+ else
+ {
+ aParam.pSubTotals[nPos] = NULL;
+ aParam.pFunctions[nPos] = NULL;
+ }
+ }
+ //! sonst Exception oder so? (zuviele Spalten)
+
+ rParent.PutData(aParam);
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalDescriptorBase::ScSubTotalDescriptorBase() :
+ aPropSet( lcl_GetSubTotalPropertyMap() )
+{
+}
+
+ScSubTotalDescriptorBase::~ScSubTotalDescriptorBase()
+{
+}
+
+// GetData/PutData hier nur wegen NewInstance-Krempel implementiert...
+
+void ScSubTotalDescriptorBase::GetData( ScSubTotalParam& /* rParam */ ) const
+{
+ DBG_ERROR("ScSubTotalDescriptorBase::GetData soll nicht gerufen werden");
+}
+
+void ScSubTotalDescriptorBase::PutData( const ScSubTotalParam& /* rParam */ )
+{
+ DBG_ERROR("ScSubTotalDescriptorBase::PutData soll nicht gerufen werden");
+}
+
+// XSubTotalDesctiptor
+
+ScSubTotalFieldObj* ScSubTotalDescriptorBase::GetObjectByIndex_Impl(USHORT nIndex)
+{
+ if ( nIndex < getCount() )
+ return new ScSubTotalFieldObj( this, nIndex );
+ return NULL;
+}
+
+void SAL_CALL ScSubTotalDescriptorBase::clear() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ GetData(aParam);
+
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ aParam.bGroupActive[i] = FALSE;
+
+ //! Notify oder so fuer die Field-Objekte???
+
+ PutData(aParam);
+}
+
+void SAL_CALL ScSubTotalDescriptorBase::addNew(
+ const uno::Sequence<sheet::SubTotalColumn>& aSubTotalColumns,
+ sal_Int32 nGroupColumn ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ GetData(aParam);
+
+ USHORT nPos = 0;
+ while ( nPos < MAXSUBTOTAL && aParam.bGroupActive[nPos] )
+ ++nPos;
+
+ UINT32 nColCount = aSubTotalColumns.getLength();
+
+ if ( nPos < MAXSUBTOTAL && nColCount <= sal::static_int_cast<UINT32>(SCCOL_MAX) )
+ {
+ aParam.bGroupActive[nPos] = TRUE;
+ aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
+
+ delete aParam.pSubTotals[nPos];
+ delete aParam.pFunctions[nPos];
+
+ SCCOL nCount = static_cast<SCCOL>(nColCount);
+ aParam.nSubTotals[nPos] = nCount;
+ if (nCount != 0)
+ {
+ aParam.pSubTotals[nPos] = new SCCOL[nCount];
+ aParam.pFunctions[nPos] = new ScSubTotalFunc[nCount];
+
+ const sheet::SubTotalColumn* pAry = aSubTotalColumns.getConstArray();
+ for (SCCOL i=0; i<nCount; i++)
+ {
+ aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
+ aParam.pFunctions[nPos][i] =
+ ScDataUnoConversion::GeneralToSubTotal( pAry[i].Function );
+ }
+ }
+ else
+ {
+ aParam.pSubTotals[nPos] = NULL;
+ aParam.pFunctions[nPos] = NULL;
+ }
+ }
+ else // too many fields / columns
+ throw uno::RuntimeException(); // no other exceptions specified
+
+ PutData(aParam);
+}
+
+// Flags/Einstellungen als Properties
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScSubTotalDescriptorBase::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SubTotalFieldsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScSubTotalDescriptorBase::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ GetData(aParam);
+
+ USHORT nCount = 0;
+ while ( nCount < MAXSUBTOTAL && aParam.bGroupActive[nCount] )
+ ++nCount;
+ return nCount;
+}
+
+uno::Any SAL_CALL ScSubTotalDescriptorBase::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XSubTotalField> xField(GetObjectByIndex_Impl((USHORT)nIndex));
+ if (xField.is())
+ return uno::makeAny(xField);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScSubTotalDescriptorBase::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XSubTotalField>*)0);
+}
+
+sal_Bool SAL_CALL ScSubTotalDescriptorBase::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSubTotalDescriptorBase::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScSubTotalDescriptorBase::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ GetData(aParam);
+
+ String aString(aPropertyName);
+
+ // some old property names are for 5.2 compatibility
+
+ if (aString.EqualsAscii( SC_UNONAME_CASE ) || aString.EqualsAscii( SC_UNONAME_ISCASE ))
+ aParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_FORMATS ) || aString.EqualsAscii( SC_UNONAME_BINDFMT ))
+ aParam.bIncludePattern = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_ENABSORT ))
+ aParam.bDoSort = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_SORTASC ))
+ aParam.bAscending = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_INSBRK ))
+ aParam.bPagebreak = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_ULIST ) || aString.EqualsAscii( SC_UNONAME_ENUSLIST ))
+ aParam.bUserDef = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_UINDEX ) || aString.EqualsAscii( SC_UNONAME_USINDEX ))
+ {
+ sal_Int32 nVal = 0;
+ if ( aValue >>= nVal )
+ aParam.nUserIndex = (USHORT)nVal;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_MAXFLD ))
+ {
+ sal_Int32 nVal = 0;
+ if ( (aValue >>= nVal) && nVal > sal::static_int_cast<sal_Int32>(MAXSUBTOTAL) )
+ {
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ PutData(aParam);
+}
+
+uno::Any SAL_CALL ScSubTotalDescriptorBase::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSubTotalParam aParam;
+ GetData(aParam);
+
+ String aString(aPropertyName);
+ uno::Any aRet;
+
+ // some old property names are for 5.2 compatibility
+
+ if (aString.EqualsAscii( SC_UNONAME_CASE ) || aString.EqualsAscii( SC_UNONAME_ISCASE ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bCaseSens );
+ else if (aString.EqualsAscii( SC_UNONAME_FORMATS ) || aString.EqualsAscii( SC_UNONAME_BINDFMT ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bIncludePattern );
+ else if (aString.EqualsAscii( SC_UNONAME_ENABSORT ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bDoSort );
+ else if (aString.EqualsAscii( SC_UNONAME_SORTASC ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bAscending );
+ else if (aString.EqualsAscii( SC_UNONAME_INSBRK ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bPagebreak );
+ else if (aString.EqualsAscii( SC_UNONAME_ULIST ) || aString.EqualsAscii( SC_UNONAME_ENUSLIST ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bUserDef );
+ else if (aString.EqualsAscii( SC_UNONAME_UINDEX ) || aString.EqualsAscii( SC_UNONAME_USINDEX ))
+ aRet <<= (sal_Int32) aParam.nUserIndex;
+ else if (aString.EqualsAscii( SC_UNONAME_MAXFLD ))
+ aRet <<= (sal_Int32) MAXSUBTOTAL;
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSubTotalDescriptorBase )
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScSubTotalDescriptorBase::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScSubTotalDescriptorBase::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScSubTotalDescriptorBase* ScSubTotalDescriptorBase::getImplementation(
+ const uno::Reference<sheet::XSubTotalDescriptor> xObj )
+{
+ ScSubTotalDescriptorBase* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScSubTotalDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScSubTotalDescriptor::ScSubTotalDescriptor()
+{
+}
+
+ScSubTotalDescriptor::~ScSubTotalDescriptor()
+{
+}
+
+void ScSubTotalDescriptor::GetData( ScSubTotalParam& rParam ) const
+{
+ rParam = aStoredParam; // Abfrage fuer Interface
+}
+
+void ScSubTotalDescriptor::PutData( const ScSubTotalParam& rParam )
+{
+ aStoredParam = rParam; // vom Interface gesetzt
+}
+
+void ScSubTotalDescriptor::SetParam( const ScSubTotalParam& rNew )
+{
+ aStoredParam = rNew; // von aussen gesetzt
+}
+
+//------------------------------------------------------------------------
+
+ScRangeSubTotalDescriptor::ScRangeSubTotalDescriptor(ScDatabaseRangeObj* pPar) :
+ pParent(pPar)
+{
+ if (pParent)
+ pParent->acquire();
+}
+
+ScRangeSubTotalDescriptor::~ScRangeSubTotalDescriptor()
+{
+ if (pParent)
+ pParent->release();
+}
+
+void ScRangeSubTotalDescriptor::GetData( ScSubTotalParam& rParam ) const
+{
+ if (pParent)
+ pParent->GetSubTotalParam( rParam );
+}
+
+void ScRangeSubTotalDescriptor::PutData( const ScSubTotalParam& rParam )
+{
+ if (pParent)
+ pParent->SetSubTotalParam( rParam );
+}
+
+//------------------------------------------------------------------------
+
+ScConsolidationDescriptor::ScConsolidationDescriptor()
+{
+}
+
+ScConsolidationDescriptor::~ScConsolidationDescriptor()
+{
+}
+
+void ScConsolidationDescriptor::SetParam( const ScConsolidateParam& rNew )
+{
+ aParam = rNew;
+}
+
+// XConsolidationDescriptor
+
+sheet::GeneralFunction SAL_CALL ScConsolidationDescriptor::getFunction() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScDataUnoConversion::SubTotalToGeneral(aParam.eFunction);
+}
+
+void SAL_CALL ScConsolidationDescriptor::setFunction( sheet::GeneralFunction nFunction )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aParam.eFunction = ScDataUnoConversion::GeneralToSubTotal(nFunction);
+}
+
+uno::Sequence<table::CellRangeAddress> SAL_CALL ScConsolidationDescriptor::getSources()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aParam.nDataAreaCount;
+ if (!aParam.ppDataAreas)
+ nCount = 0;
+ table::CellRangeAddress aRange;
+ uno::Sequence<table::CellRangeAddress> aSeq(nCount);
+ table::CellRangeAddress* pAry = aSeq.getArray();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScArea* pArea = aParam.ppDataAreas[i];
+ if (pArea)
+ {
+ aRange.Sheet = pArea->nTab;
+ aRange.StartColumn = pArea->nColStart;
+ aRange.StartRow = pArea->nRowStart;
+ aRange.EndColumn = pArea->nColEnd;
+ aRange.EndRow = pArea->nRowEnd;
+ }
+ pAry[i] = aRange;
+ }
+ return aSeq;
+}
+
+void SAL_CALL ScConsolidationDescriptor::setSources(
+ const uno::Sequence<table::CellRangeAddress>& aSources )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = (USHORT)aSources.getLength();
+ if (nCount)
+ {
+ const table::CellRangeAddress* pAry = aSources.getConstArray();
+ ScArea** pNew = new ScArea*[nCount];
+ USHORT i;
+ for (i=0; i<nCount; i++)
+ pNew[i] = new ScArea( pAry[i].Sheet,
+ static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow,
+ static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow );
+
+ aParam.SetAreas( pNew, nCount ); // kopiert alles
+
+ for (i=0; i<nCount; i++)
+ delete pNew[i];
+ delete[] pNew;
+ }
+ else
+ aParam.ClearDataAreas();
+}
+
+table::CellAddress SAL_CALL ScConsolidationDescriptor::getStartOutputPosition()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellAddress aPos;
+ aPos.Column = aParam.nCol;
+ aPos.Row = aParam.nRow;
+ aPos.Sheet = aParam.nTab;
+ return aPos;
+}
+
+void SAL_CALL ScConsolidationDescriptor::setStartOutputPosition(
+ const table::CellAddress& aStartOutputPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aParam.nCol = (SCCOL)aStartOutputPosition.Column;
+ aParam.nRow = (SCROW)aStartOutputPosition.Row;
+ aParam.nTab = aStartOutputPosition.Sheet;
+}
+
+sal_Bool SAL_CALL ScConsolidationDescriptor::getUseColumnHeaders() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aParam.bByCol;
+}
+
+void SAL_CALL ScConsolidationDescriptor::setUseColumnHeaders( sal_Bool bUseColumnHeaders )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aParam.bByCol = bUseColumnHeaders;
+}
+
+sal_Bool SAL_CALL ScConsolidationDescriptor::getUseRowHeaders() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aParam.bByRow;
+}
+
+void SAL_CALL ScConsolidationDescriptor::setUseRowHeaders( sal_Bool bUseRowHeaders )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aParam.bByRow = bUseRowHeaders;
+}
+
+sal_Bool SAL_CALL ScConsolidationDescriptor::getInsertLinks() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aParam.bReferenceData;
+}
+
+void SAL_CALL ScConsolidationDescriptor::setInsertLinks( sal_Bool bInsertLinks )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aParam.bReferenceData = bInsertLinks;
+}
+
+//------------------------------------------------------------------------
+
+ScFilterDescriptorBase::ScFilterDescriptorBase(ScDocShell* pDocShell) :
+ aPropSet( lcl_GetFilterPropertyMap() ),
+ pDocSh(pDocShell)
+{
+ if (pDocSh)
+ pDocSh->GetDocument()->AddUnoObject(*this);
+}
+
+ScFilterDescriptorBase::~ScFilterDescriptorBase()
+{
+ if (pDocSh)
+ pDocSh->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScFilterDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ pDocSh = NULL; // invalid
+ }
+ }
+}
+
+// XSheetFilterDescriptor and XSheetFilterDescriptor2
+
+uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilterFields()
+ 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::TableFilterField aField;
+ uno::Sequence<sheet::TableFilterField> aSeq(static_cast<sal_Int32>(nCount));
+ sheet::TableFilterField* 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::FilterOperator_EQUAL;
+ if (!rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING)
+ {
+ if (rEntry.nVal == SC_EMPTYFIELDS)
+ {
+ aField.Operator = sheet::FilterOperator_EMPTY;
+ aField.NumericValue = 0;
+ }
+ else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+ {
+ aField.Operator = sheet::FilterOperator_NOT_EMPTY;
+ aField.NumericValue = 0;
+ }
+ }
+ }
+ break;
+ case SC_LESS: aField.Operator = sheet::FilterOperator_LESS; break;
+ case SC_GREATER: aField.Operator = sheet::FilterOperator_GREATER; break;
+ case SC_LESS_EQUAL: aField.Operator = sheet::FilterOperator_LESS_EQUAL; break;
+ case SC_GREATER_EQUAL: aField.Operator = sheet::FilterOperator_GREATER_EQUAL; break;
+ case SC_NOT_EQUAL: aField.Operator = sheet::FilterOperator_NOT_EQUAL; break;
+ case SC_TOPVAL: aField.Operator = sheet::FilterOperator_TOP_VALUES; break;
+ case SC_BOTVAL: aField.Operator = sheet::FilterOperator_BOTTOM_VALUES; break;
+ case SC_TOPPERC: aField.Operator = sheet::FilterOperator_TOP_PERCENT; break;
+ case SC_BOTPERC: aField.Operator = sheet::FilterOperator_BOTTOM_PERCENT; break;
+ default:
+ DBG_ERROR("Falscher Filter-enum");
+ aField.Operator = sheet::FilterOperator_EMPTY;
+ }
+ pAry[i] = aField;
+ }
+ 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)
+{
+ 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::TableFilterField* 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::FilterOperator_EQUAL: rEntry.eOp = SC_EQUAL; break;
+ case sheet::FilterOperator_LESS: rEntry.eOp = SC_LESS; break;
+ case sheet::FilterOperator_GREATER: rEntry.eOp = SC_GREATER; break;
+ case sheet::FilterOperator_LESS_EQUAL: rEntry.eOp = SC_LESS_EQUAL; break;
+ case sheet::FilterOperator_GREATER_EQUAL: rEntry.eOp = SC_GREATER_EQUAL; break;
+ case sheet::FilterOperator_NOT_EQUAL: rEntry.eOp = SC_NOT_EQUAL; break;
+ case sheet::FilterOperator_TOP_VALUES: rEntry.eOp = SC_TOPVAL; break;
+ case sheet::FilterOperator_BOTTOM_VALUES: rEntry.eOp = SC_BOTVAL; break;
+ case sheet::FilterOperator_TOP_PERCENT: rEntry.eOp = SC_TOPPERC; break;
+ case sheet::FilterOperator_BOTTOM_PERCENT: rEntry.eOp = SC_BOTPERC; break;
+ case sheet::FilterOperator_EMPTY:
+ {
+ rEntry.eOp = SC_EQUAL;
+ rEntry.nVal = SC_EMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ *rEntry.pStr = EMPTY_STRING;
+ }
+ break;
+ case sheet::FilterOperator_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);
+}
+
+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
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFilterDescriptorBase::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScFilterDescriptorBase::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScQueryParam aParam;
+ GetData(aParam);
+
+ String aString(aPropertyName);
+ if (aString.EqualsAscii( SC_UNONAME_CONTHDR ))
+ aParam.bHasHeader = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_COPYOUT ))
+ aParam.bInplace = !(ScUnoHelpFunctions::GetBoolFromAny( aValue ));
+ else if (aString.EqualsAscii( SC_UNONAME_ISCASE ))
+ aParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_MAXFLD ))
+ {
+ sal_Int32 nVal = 0;
+ if ( (aValue >>= nVal) && nVal > sal::static_int_cast<sal_Int32>(MAXQUERY) )
+ {
+ throw lang::IllegalArgumentException();
+ }
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_ORIENT ))
+ {
+ //! test for correct enum type?
+ table::TableOrientation eOrient = (table::TableOrientation)
+ ScUnoHelpFunctions::GetEnumFromAny( aValue );
+ aParam.bByRow = ( eOrient != table::TableOrientation_COLUMNS );
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_OUTPOS ))
+ {
+ table::CellAddress aAddress;
+ if ( aValue >>= aAddress )
+ {
+ aParam.nDestTab = aAddress.Sheet;
+ aParam.nDestCol = (SCCOL)aAddress.Column;
+ aParam.nDestRow = (SCROW)aAddress.Row;
+ }
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_SAVEOUT ))
+ aParam.bDestPers = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if (aString.EqualsAscii( SC_UNONAME_SKIPDUP ))
+ aParam.bDuplicate = !(ScUnoHelpFunctions::GetBoolFromAny( aValue ));
+ else if (aString.EqualsAscii( SC_UNONAME_USEREGEX ))
+ aParam.bRegExp = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+
+ PutData(aParam);
+}
+
+uno::Any SAL_CALL ScFilterDescriptorBase::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScQueryParam aParam;
+ GetData(aParam);
+
+ String aString(aPropertyName);
+ uno::Any aRet;
+
+ if (aString.EqualsAscii( SC_UNONAME_CONTHDR ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bHasHeader );
+ else if (aString.EqualsAscii( SC_UNONAME_COPYOUT ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, !(aParam.bInplace) );
+ else if (aString.EqualsAscii( SC_UNONAME_ISCASE ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bCaseSens );
+ else if (aString.EqualsAscii( SC_UNONAME_MAXFLD ))
+ aRet <<= (sal_Int32) MAXQUERY;
+ else if (aString.EqualsAscii( SC_UNONAME_ORIENT ))
+ {
+ table::TableOrientation eOrient = aParam.bByRow ? table::TableOrientation_ROWS :
+ table::TableOrientation_COLUMNS;
+ aRet <<= eOrient;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_OUTPOS ))
+ {
+ table::CellAddress aOutPos;
+ aOutPos.Sheet = aParam.nDestTab;
+ aOutPos.Column = aParam.nDestCol;
+ aOutPos.Row = aParam.nDestRow;
+ aRet <<= aOutPos;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_SAVEOUT ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bDestPers );
+ else if (aString.EqualsAscii( SC_UNONAME_SKIPDUP ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, !(aParam.bDuplicate) );
+ else if (aString.EqualsAscii( SC_UNONAME_USEREGEX ))
+ ScUnoHelpFunctions::SetBoolInAny( aRet, aParam.bRegExp );
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFilterDescriptorBase )
+
+//------------------------------------------------------------------------
+
+ScFilterDescriptor::ScFilterDescriptor(ScDocShell* pDocShell)
+ :
+ ScFilterDescriptorBase(pDocShell)
+{
+}
+
+ScFilterDescriptor::~ScFilterDescriptor()
+{
+}
+
+void ScFilterDescriptor::GetData( ScQueryParam& rParam ) const
+{
+ rParam = aStoredParam; // Abfrage fuer Interface
+}
+
+void ScFilterDescriptor::PutData( const ScQueryParam& rParam )
+{
+ aStoredParam = rParam; // vom Interface gesetzt
+}
+
+void ScFilterDescriptor::SetParam( const ScQueryParam& rNew )
+{
+ aStoredParam = rNew; // von aussen gesetzt
+}
+
+//------------------------------------------------------------------------
+
+ScRangeFilterDescriptor::ScRangeFilterDescriptor(ScDocShell* pDocShell, ScDatabaseRangeObj* pPar) :
+ ScFilterDescriptorBase(pDocShell),
+ pParent(pPar)
+{
+ if (pParent)
+ pParent->acquire();
+}
+
+ScRangeFilterDescriptor::~ScRangeFilterDescriptor()
+{
+ if (pParent)
+ pParent->release();
+}
+
+void ScRangeFilterDescriptor::GetData( ScQueryParam& rParam ) const
+{
+ if (pParent)
+ pParent->GetQueryParam( rParam );
+}
+
+void ScRangeFilterDescriptor::PutData( const ScQueryParam& rParam )
+{
+ if (pParent)
+ pParent->SetQueryParam( rParam );
+}
+
+//------------------------------------------------------------------------
+
+ScDataPilotFilterDescriptor::ScDataPilotFilterDescriptor(ScDocShell* pDocShell, ScDataPilotDescriptorBase* pPar) :
+ ScFilterDescriptorBase(pDocShell),
+ pParent(pPar)
+{
+ if (pParent)
+ pParent->acquire();
+}
+
+ScDataPilotFilterDescriptor::~ScDataPilotFilterDescriptor()
+{
+ if (pParent)
+ pParent->release();
+}
+
+void ScDataPilotFilterDescriptor::GetData( ScQueryParam& rParam ) const
+{
+ if (pParent)
+ {
+ ScDPObject* pDPObj = pParent->GetDPObject();
+ if (pDPObj && pDPObj->IsSheetData())
+ rParam = pDPObj->GetSheetDesc()->aQueryParam;
+ }
+}
+
+void ScDataPilotFilterDescriptor::PutData( const ScQueryParam& rParam )
+{
+ if (pParent)
+ {
+ ScDPObject* pDPObj = pParent->GetDPObject();
+ if (pDPObj)
+ {
+ ScSheetSourceDesc aSheetDesc;
+ if (pDPObj->IsSheetData())
+ aSheetDesc = *pDPObj->GetSheetDesc();
+ aSheetDesc.aQueryParam = rParam;
+ pDPObj->SetSheetDesc(aSheetDesc);
+ pParent->SetDPObject(pDPObj);
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell* pDocSh, const String& rNm) :
+ pDocShell( pDocSh ),
+ aName( rNm ),
+ aPropSet( lcl_GetDBRangePropertyMap() )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDatabaseRangeObj::~ScDatabaseRangeObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDatabaseRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+
+ if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // ungueltig geworden
+ else if ( rHint.ISA (ScDBRangeRefreshedHint) )
+ {
+ ScDBData* pDBData = GetDBData_Impl();
+ const ScDBRangeRefreshedHint& rRef = (const ScDBRangeRefreshedHint&)rHint;
+ ScImportParam aParam;
+ pDBData->GetImportParam(aParam);
+ if (aParam == rRef.GetImportParam())
+ Refreshed_Impl();
+ }
+}
+
+// Hilfsfuntionen
+
+ScDBData* ScDatabaseRangeObj::GetDBData_Impl() const
+{
+ ScDBData* pRet = NULL;
+ if (pDocShell)
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames)
+ {
+ USHORT nPos = 0;
+ if (pNames->SearchName( aName, nPos ))
+ pRet = (*pNames)[nPos];
+ }
+ }
+ return pRet;
+}
+
+// XNamed
+
+rtl::OUString SAL_CALL ScDatabaseRangeObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aName;
+}
+
+void SAL_CALL ScDatabaseRangeObj::setName( const rtl::OUString& aNewName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDBDocFunc aFunc(*pDocShell);
+ String aNewStr(aNewName);
+ BOOL bOk = aFunc.RenameDBRange( aName, aNewStr, TRUE );
+ if (bOk)
+ aName = aNewStr;
+ }
+}
+
+// XDatabaseRange
+
+table::CellRangeAddress SAL_CALL ScDatabaseRangeObj::getDataArea() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aAddress;
+ ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ {
+ ScRange aRange;
+ pData->GetArea(aRange);
+ aAddress.Sheet = aRange.aStart.Tab();
+ aAddress.StartColumn = aRange.aStart.Col();
+ aAddress.StartRow = aRange.aStart.Row();
+ aAddress.EndColumn = aRange.aEnd.Col();
+ aAddress.EndRow = aRange.aEnd.Row();
+ }
+ return aAddress;
+}
+
+void SAL_CALL ScDatabaseRangeObj::setDataArea( const table::CellRangeAddress& aDataArea )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDBData* pData = GetDBData_Impl();
+ if ( pDocShell && pData )
+ {
+ ScDBData aNewData( *pData );
+ //! MoveTo ???
+ aNewData.SetArea( aDataArea.Sheet, (SCCOL)aDataArea.StartColumn, (SCROW)aDataArea.StartRow,
+ (SCCOL)aDataArea.EndColumn, (SCROW)aDataArea.EndRow );
+ ScDBDocFunc aFunc(*pDocShell);
+ aFunc.ModifyDBData(aNewData, TRUE);
+ }
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScDatabaseRangeObj::getSortDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScSortParam aParam;
+ const ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ {
+ pData->GetSortParam(aParam);
+
+ // im SortDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOLROW nFieldStart = aParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : static_cast<SCCOLROW>(aDBRange.aStart.Row());
+ for (USHORT i=0; i<MAXSORT; i++)
+ if ( aParam.bDoSort[i] && aParam.nField[i] >= nFieldStart )
+ aParam.nField[i] -= nFieldStart;
+ }
+
+ uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() );
+ ScSortDescriptor::FillProperties( aSeq, aParam );
+ return aSeq;
+}
+
+void ScDatabaseRangeObj::GetQueryParam(ScQueryParam& rQueryParam) const
+{
+ const ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ {
+ pData->GetQueryParam(rQueryParam);
+
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOLROW nFieldStart = rQueryParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : static_cast<SCCOLROW>(aDBRange.aStart.Row());
+ SCSIZE nCount = rQueryParam.GetEntryCount();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
+ if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
+ rEntry.nField -= nFieldStart;
+ }
+ }
+}
+
+void ScDatabaseRangeObj::SetQueryParam(const ScQueryParam& rQueryParam)
+{
+ const ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ {
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScQueryParam aParam(rQueryParam);
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOLROW nFieldStart = aParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : static_cast<SCCOLROW>(aDBRange.aStart.Row());
+
+ SCSIZE nCount = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (rEntry.bDoQuery)
+ rEntry.nField += nFieldStart;
+ }
+
+ ScDBData aNewData( *pData );
+ aNewData.SetQueryParam(aParam);
+ aNewData.SetHeader(aParam.bHasHeader); // not in ScDBData::SetQueryParam
+ ScDBDocFunc aFunc(*pDocShell);
+ aFunc.ModifyDBData(aNewData, TRUE);
+ }
+}
+
+uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScDatabaseRangeObj::getFilterDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScRangeFilterDescriptor(pDocShell, this);
+}
+
+void ScDatabaseRangeObj::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
+{
+ const ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ {
+ pData->GetSubTotalParam(rSubTotalParam);
+
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOL nFieldStart = aDBRange.aStart.Col();
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ if ( rSubTotalParam.bGroupActive[i] )
+ {
+ if ( rSubTotalParam.nField[i] >= nFieldStart )
+ rSubTotalParam.nField[i] = sal::static_int_cast<SCCOL>( rSubTotalParam.nField[i] - nFieldStart );
+ for (SCCOL j=0; j<rSubTotalParam.nSubTotals[i]; j++)
+ if ( rSubTotalParam.pSubTotals[i][j] >= nFieldStart )
+ rSubTotalParam.pSubTotals[i][j] =
+ sal::static_int_cast<SCCOL>( rSubTotalParam.pSubTotals[i][j] - nFieldStart );
+ }
+ }
+ }
+}
+
+void ScDatabaseRangeObj::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam)
+{
+ const ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ {
+ // im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
+ ScSubTotalParam aParam(rSubTotalParam);
+ ScRange aDBRange;
+ pData->GetArea(aDBRange);
+ SCCOL nFieldStart = aDBRange.aStart.Col();
+ for (USHORT i=0; i<MAXSUBTOTAL; i++)
+ {
+ if ( aParam.bGroupActive[i] )
+ {
+ aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + nFieldStart );
+ for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
+ aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] + nFieldStart );
+ }
+ }
+
+ ScDBData aNewData( *pData );
+ aNewData.SetSubTotalParam(aParam);
+ ScDBDocFunc aFunc(*pDocShell);
+ aFunc.ModifyDBData(aNewData, TRUE);
+ }
+}
+
+uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScDatabaseRangeObj::getSubTotalDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScRangeSubTotalDescriptor(this);
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScDatabaseRangeObj::getImportDescriptor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScImportParam aParam;
+ const ScDBData* pData = GetDBData_Impl();
+ if (pData)
+ pData->GetImportParam(aParam);
+
+ uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
+ ScImportDescriptor::FillProperties( aSeq, aParam );
+ return aSeq;
+}
+
+// XRefreshable
+
+void SAL_CALL ScDatabaseRangeObj::refresh() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDBData* pData = GetDBData_Impl();
+ if ( pDocShell && pData )
+ {
+ ScDBDocFunc aFunc(*pDocShell);
+
+ // Import zu wiederholen?
+ BOOL bContinue = TRUE;
+ ScImportParam aImportParam;
+ pData->GetImportParam( aImportParam );
+ if (aImportParam.bImport && !pData->HasImportSelection())
+ {
+ SCTAB nTab;
+ SCCOL nDummyCol;
+ SCROW nDummyRow;
+ pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow );
+ uno::Reference< sdbc::XResultSet > xResultSet;
+ bContinue = aFunc.DoImport( nTab, aImportParam, xResultSet, NULL, TRUE, FALSE ); //! Api-Flag als Parameter
+ }
+
+ // interne Operationen (sort, query, subtotal) nur, wenn kein Fehler
+ if (bContinue)
+ aFunc.RepeatDB( pData->GetName(), TRUE, TRUE );
+ }
+}
+
+void SAL_CALL ScDatabaseRangeObj::addRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<util::XRefreshListener>* pObj =
+ new uno::Reference<util::XRefreshListener>( xListener );
+ aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
+
+ // hold one additional ref to keep this object alive as long as there are listeners
+ if ( aRefreshListeners.Count() == 1 )
+ acquire();
+}
+
+void SAL_CALL ScDatabaseRangeObj::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aRefreshListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
+ if ( *pObj == xListener )
+ {
+ aRefreshListeners.DeleteAndDestroy( n );
+ if ( aRefreshListeners.Count() == 0 )
+ release(); // release ref for listeners
+ break;
+ }
+ }
+}
+
+void ScDatabaseRangeObj::Refreshed_Impl()
+{
+ lang::EventObject aEvent;
+ aEvent.Source = (cppu::OWeakObject*)this;
+ for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
+ (*aRefreshListeners[n])->refreshed( aEvent );
+}
+
+// XCellRangeSource
+
+uno::Reference<table::XCellRange> SAL_CALL ScDatabaseRangeObj::getReferredCells()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRange aRange;
+ ScDBData* pData = GetDBData_Impl();
+ if ( pData )
+ {
+ //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ???
+
+ pData->GetArea(aRange);
+ if ( aRange.aStart == aRange.aEnd )
+ return new ScCellObj( pDocShell, aRange.aStart );
+ else
+ return new ScCellRangeObj( pDocShell, aRange );
+ }
+ return NULL;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDatabaseRangeObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScDatabaseRangeObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDBData* pData = GetDBData_Impl();
+ if ( pDocShell && pData )
+ {
+ ScDBData aNewData( *pData );
+ BOOL bDo = TRUE;
+
+ String aString(aPropertyName);
+ if ( aString.EqualsAscii( SC_UNONAME_KEEPFORM ) )
+ aNewData.SetKeepFmt( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNONAME_MOVCELLS ) )
+ aNewData.SetDoSize( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNONAME_STRIPDAT ) )
+ aNewData.SetStripData( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNONAME_AUTOFLT ))
+ {
+ sal_Bool bAutoFilter(ScUnoHelpFunctions::GetBoolFromAny( aValue ));
+ aNewData.SetAutoFilter(bAutoFilter);
+ ScRange aRange;
+ aNewData.GetArea(aRange);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (bAutoFilter && pDoc)
+ pDoc->ApplyFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), SC_MF_AUTO );
+ else if (!bAutoFilter && pDoc)
+ pDoc->RemoveFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), SC_MF_AUTO );
+ ScRange aPaintRange(aRange.aStart, aRange.aEnd);
+ aPaintRange.aEnd.SetRow(aPaintRange.aStart.Row());
+ pDocShell->PostPaint(aPaintRange, PAINT_GRID);
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_USEFLTCRT ))
+ {
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ {
+ ScRange aRange;
+ aNewData.GetAdvancedQuerySource(aRange);
+ aNewData.SetAdvancedQuerySource(&aRange);
+ }
+ else
+ aNewData.SetAdvancedQuerySource(NULL);
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_FLTCRT ))
+ {
+ table::CellRangeAddress aRange;
+ if (aValue >>= aRange)
+ {
+ ScRange aCoreRange;
+ ScUnoConversion::FillScRange(aCoreRange, aRange);
+
+ aNewData.SetAdvancedQuerySource(&aCoreRange);
+ }
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_FROMSELECT ))
+ {
+ aNewData.SetImportSelection(::cppu::any2bool(aValue));
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_REFPERIOD ))
+ {
+ sal_Int32 nRefresh = 0;
+ if (aValue >>= nRefresh)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ aNewData.SetRefreshDelay(nRefresh);
+ if (pDoc && pDoc->GetDBCollection())
+ {
+ aNewData.SetRefreshHandler( pDoc->GetDBCollection()->GetRefreshHandler() );
+ aNewData.SetRefreshControl( pDoc->GetRefreshTimerControlAddress() );
+ }
+ }
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_CONRES ))
+ {
+ }
+ else
+ bDo = FALSE;
+
+ if (bDo)
+ {
+ ScDBDocFunc aFunc(*pDocShell);
+ aFunc.ModifyDBData(aNewData, TRUE);
+ }
+ }
+}
+
+uno::Any SAL_CALL ScDatabaseRangeObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aRet;
+ ScDBData* pData = GetDBData_Impl();
+ if ( pData )
+ {
+ String aString(aPropertyName);
+ if ( aString.EqualsAscii( SC_UNONAME_KEEPFORM ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pData->IsKeepFmt() );
+ else if ( aString.EqualsAscii( SC_UNONAME_MOVCELLS ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pData->IsDoSize() );
+ else if ( aString.EqualsAscii( SC_UNONAME_STRIPDAT ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pData->IsStripData() );
+ else if ( aString.EqualsAscii( SC_UNONAME_ISUSER ) )
+ {
+ // all database ranges except "unnamed" are user defined
+ ScUnoHelpFunctions::SetBoolInAny( aRet,
+ ( pData->GetName() != ScGlobal::GetRscString(STR_DB_NONAME) ) );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_LINKDISPBIT ) )
+ {
+ // no target bitmaps for individual entries (would be all equal)
+ // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_DBAREA );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_LINKDISPNAME ) )
+ aRet <<= rtl::OUString( aName );
+ else if (aString.EqualsAscii( SC_UNONAME_AUTOFLT ))
+ {
+ sal_Bool bAutoFilter(GetDBData_Impl()->HasAutoFilter());
+
+ ScUnoHelpFunctions::SetBoolInAny( aRet, bAutoFilter );
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_USEFLTCRT ))
+ {
+ ScRange aRange;
+ sal_Bool bIsAdvancedSource(GetDBData_Impl()->GetAdvancedQuerySource(aRange));
+
+ ScUnoHelpFunctions::SetBoolInAny( aRet, bIsAdvancedSource );
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_FLTCRT ))
+ {
+ table::CellRangeAddress aRange;
+ ScRange aCoreRange;
+ if (GetDBData_Impl()->GetAdvancedQuerySource(aCoreRange))
+ ScUnoConversion::FillApiRange(aRange, aCoreRange);
+
+ aRet <<= aRange;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_FROMSELECT ))
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, GetDBData_Impl()->HasImportSelection() );
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_REFPERIOD ))
+ {
+ sal_Int32 nRefresh(GetDBData_Impl()->GetRefreshDelay());
+ aRet <<= nRefresh;
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_CONRES ))
+ {
+ }
+ else if (aString.EqualsAscii( SC_UNONAME_TOKENINDEX ))
+ {
+ // get index for use in formula tokens (read-only)
+ aRet <<= static_cast<sal_Int32>(GetDBData_Impl()->GetIndex());
+ }
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDatabaseRangeObj )
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScDatabaseRangeObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScDatabaseRangeObj" );
+}
+
+sal_Bool SAL_CALL ScDatabaseRangeObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCDATABASERANGEOBJ_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCLINKTARGET_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDatabaseRangeObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCDATABASERANGEOBJ_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCLINKTARGET_SERVICE );
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+ScDatabaseRangesObj::ScDatabaseRangesObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDatabaseRangesObj::~ScDatabaseRangesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDatabaseRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XDatabaseRanges
+
+ScDatabaseRangeObj* ScDatabaseRangesObj::GetObjectByIndex_Impl(USHORT nIndex)
+{
+ if (pDocShell)
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames && nIndex < pNames->GetCount())
+ return new ScDatabaseRangeObj( pDocShell, (*pNames)[nIndex]->GetName() );
+ }
+ return NULL;
+}
+
+ScDatabaseRangeObj* ScDatabaseRangesObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ if ( pDocShell && hasByName(aName) )
+ {
+ String aString(aName);
+ return new ScDatabaseRangeObj( pDocShell, aString );
+ }
+ return NULL;
+}
+
+
+void SAL_CALL ScDatabaseRangesObj::addNewByName( const rtl::OUString& aName,
+ const table::CellRangeAddress& aRange )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ ScDBDocFunc aFunc(*pDocShell);
+
+ String aString(aName);
+ ScRange aNameRange( (SCCOL)aRange.StartColumn, (SCROW)aRange.StartRow, aRange.Sheet,
+ (SCCOL)aRange.EndColumn, (SCROW)aRange.EndRow, aRange.Sheet );
+ bDone = aFunc.AddDBRange( aString, aNameRange, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScDatabaseRangesObj::removeByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ ScDBDocFunc aFunc(*pDocShell);
+ String aString(aName);
+ bDone = aFunc.DeleteDBRange( aString, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScDatabaseRangesObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DatabaseRangesEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDatabaseRangesObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! "unbenannt" weglassen ?
+
+ if (pDocShell)
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames)
+ return pNames->GetCount();
+ }
+ return 0;
+}
+
+uno::Any SAL_CALL ScDatabaseRangesObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XDatabaseRange> xRange(GetObjectByIndex_Impl((USHORT)nIndex));
+ if (xRange.is())
+ return uno::makeAny(xRange);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScDatabaseRangesObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XDatabaseRange>*)0);
+}
+
+sal_Bool SAL_CALL ScDatabaseRangesObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XNameAccess
+
+uno::Any SAL_CALL ScDatabaseRangesObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XDatabaseRange> xRange(GetObjectByName_Impl(aName));
+ if (xRange.is())
+ return uno::makeAny(xRange);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDatabaseRangesObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! "unbenannt" weglassen ?
+
+ if (pDocShell)
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames)
+ {
+ USHORT nCount = pNames->GetCount();
+ String aName;
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (USHORT i=0; i<nCount; i++)
+ pAry[i] = (*pNames)[i]->GetName();
+
+ return aSeq;
+ }
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+sal_Bool SAL_CALL ScDatabaseRangesObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! "unbenannt" weglassen ?
+
+ if (pDocShell)
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames)
+ {
+ String aString(aName);
+ USHORT nPos = 0;
+ if (pNames->SearchName( aString, nPos ))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+
+
+
+
diff --git a/sc/source/ui/unoobj/defltuno.cxx b/sc/source/ui/unoobj/defltuno.cxx
new file mode 100644
index 000000000000..f3f76685e5cb
--- /dev/null
+++ b/sc/source/ui/unoobj/defltuno.cxx
@@ -0,0 +1,387 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <editeng/memberids.hrc>
+#include <svl/smplhint.hxx>
+#include <svl/itemprop.hxx>
+#include <svx/unomid.hxx>
+#include <i18npool/mslangid.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include "scitems.hxx"
+#include "defltuno.hxx"
+#include "miscuno.hxx"
+#include "docsh.hxx"
+#include "docpool.hxx"
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "docoptio.hxx"
+
+#include <limits>
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+const SfxItemPropertyMapEntry* lcl_GetDocDefaultsMap()
+{
+ static SfxItemPropertyMapEntry aDocDefaultsMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_STANDARDDEC), 0, &getCppuType((sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_TABSTOPDIS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDocDefaultsMap_Impl;
+}
+
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; }
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScDocDefaultsObj, "ScDocDefaultsObj", "com.sun.star.sheet.Defaults" )
+
+//------------------------------------------------------------------------
+
+ScDocDefaultsObj::ScDocDefaultsObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh ),
+ aPropertyMap(lcl_GetDocDefaultsMap())
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDocDefaultsObj::~ScDocDefaultsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDocDefaultsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // document gone
+ }
+}
+
+void ScDocDefaultsObj::ItemsChanged()
+{
+ if (pDocShell)
+ {
+ //! if not in XML import, adjust row heights
+
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ }
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDocDefaultsObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef = new SfxItemPropertySetInfo(
+ &aPropertyMap );
+ return aRef;
+}
+
+void SAL_CALL ScDocDefaultsObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+ if(!pEntry->nWID)
+ {
+ if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ ScDocOptions aDocOpt(pDoc->GetDocOptions());
+ sal_Int16 nValue = 0;
+ if (aValue >>= nValue)
+ {
+ aDocOpt.SetStdPrecision(static_cast<sal_uInt16> (nValue));
+ pDoc->SetDocOptions(aDocOpt);
+ }
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ ScDocOptions aDocOpt(pDoc->GetDocOptions());
+ sal_Int32 nValue = 0;
+ if (aValue >>= nValue)
+ {
+ aDocOpt.SetTabDistance(static_cast<sal_uInt16>(HMMToTwips(nValue)));
+ pDoc->SetDocOptions(aDocOpt);
+ }
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ }
+ else if ( pEntry->nWID == ATTR_FONT_LANGUAGE ||
+ pEntry->nWID == ATTR_CJK_FONT_LANGUAGE ||
+ pEntry->nWID == ATTR_CTL_FONT_LANGUAGE )
+ {
+ // for getPropertyValue the PoolDefaults are sufficient,
+ // but setPropertyValue has to be handled differently
+
+ lang::Locale aLocale;
+ if ( aValue >>= aLocale )
+ {
+ LanguageType eNew;
+ if (aLocale.Language.getLength() || aLocale.Country.getLength())
+ eNew = MsLangId::convertLocaleToLanguage( aLocale );
+ else
+ eNew = LANGUAGE_NONE;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+
+ if ( pEntry->nWID == ATTR_CJK_FONT_LANGUAGE )
+ eCjk = eNew;
+ else if ( pEntry->nWID == ATTR_CTL_FONT_LANGUAGE )
+ eCtl = eNew;
+ else
+ eLatin = eNew;
+
+ pDoc->SetLanguage( eLatin, eCjk, eCtl );
+ }
+ }
+ else
+ {
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ SfxPoolItem* pNewItem = pPool->GetDefaultItem(pEntry->nWID).Clone();
+
+ if( !pNewItem->PutValue( aValue, pEntry->nMemberId ) )
+ throw lang::IllegalArgumentException();
+
+ pPool->SetPoolDefaultItem( *pNewItem );
+ delete pNewItem; // copied in SetPoolDefaultItem
+
+ ItemsChanged();
+ }
+}
+
+uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ // use pool default if set
+
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ uno::Any aRet;
+ const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ if (!pEntry->nWID)
+ {
+ if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ const ScDocOptions& aDocOpt = pDoc->GetDocOptions();
+ sal_uInt16 nPrec = aDocOpt.GetStdPrecision();
+ // the max value of unsigned 16-bit integer is used as the flag
+ // value for unlimited precision, c.f.
+ // SvNumberFormatter::UNLIMITED_PRECISION.
+ if (nPrec <= ::std::numeric_limits<sal_Int16>::max())
+ aRet <<= static_cast<sal_Int16> (nPrec);
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ const ScDocOptions& aDocOpt = pDoc->GetDocOptions();
+ sal_Int32 nValue (TwipsToEvenHMM(aDocOpt.GetTabDistance()));
+ aRet <<= nValue;
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ }
+ else
+ {
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ const SfxPoolItem& rItem = pPool->GetDefaultItem( pEntry->nWID );
+ rItem.QueryValue( aRet, pEntry->nMemberId );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocDefaultsObj )
+
+// XPropertyState
+
+beans::PropertyState SAL_CALL ScDocDefaultsObj::getPropertyState( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
+
+ USHORT nWID = pEntry->nWID;
+ if ( nWID == ATTR_FONT || nWID == ATTR_CJK_FONT || nWID == ATTR_CTL_FONT || !nWID )
+ {
+ // static default for font is system-dependent,
+ // so font default is always treated as "direct value".
+
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ // check if pool default is set
+
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ if ( pPool->GetPoolDefaultItem( nWID ) != NULL )
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ }
+
+ return eRet;
+}
+
+uno::Sequence<beans::PropertyState> SAL_CALL ScDocDefaultsObj::getPropertyStates(
+ const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ // the simple way: call getPropertyState
+
+ ScUnoGuard aGuard;
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
+ pStates[i] = getPropertyState(pNames[i]);
+ return aRet;
+}
+
+void SAL_CALL ScDocDefaultsObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ if (pEntry->nWID)
+ {
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ pPool->ResetPoolDefaultItem( pEntry->nWID );
+
+ ItemsChanged();
+ }
+}
+
+uno::Any SAL_CALL ScDocDefaultsObj::getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ // always use static default
+
+ ScUnoGuard aGuard;
+
+ if ( !pDocShell )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ uno::Any aRet;
+ if (pEntry->nWID)
+ {
+ ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
+ const SfxPoolItem* pItem = pPool->GetItem( pEntry->nWID, SFX_ITEMS_STATICDEFAULT );
+ if (pItem)
+ pItem->QueryValue( aRet, pEntry->nMemberId );
+ }
+ return aRet;
+}
+
+
diff --git a/sc/source/ui/unoobj/detreg.cxx b/sc/source/ui/unoobj/detreg.cxx
new file mode 100644
index 000000000000..498d0fc886ec
--- /dev/null
+++ b/sc/source/ui/unoobj/detreg.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scdetect.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/uno/Sequence.h>
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment** /* ppEnvironment */ )
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceManager */ ,
+ void* pRegistryKey )
+{
+ Reference< ::registry::XRegistryKey >
+ xKey( reinterpret_cast< ::registry::XRegistryKey* >( pRegistryKey ) ) ;
+
+ OUString aDelimiter( RTL_CONSTASCII_USTRINGPARAM("/") );
+ OUString aUnoServices( RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") );
+
+ // Eigentliche Implementierung und ihre Services registrieren
+ sal_Int32 i;
+ Reference< ::registry::XRegistryKey > xNewKey(xKey->createKey( aDelimiter + ScFilterDetect::impl_getStaticImplementationName() +
+ aUnoServices ));
+
+ Sequence< OUString > aServices(ScFilterDetect::impl_getStaticSupportedServiceNames());
+ for(i = 0; i < aServices.getLength(); i++ )
+ xNewKey->createKey( aServices.getConstArray()[i] );
+
+ return sal_True;
+}
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void* /* pRegistryKey */ )
+{
+ // Set default return value for this operation - if it failed.
+ void* pReturn = NULL ;
+
+ if (
+ ( pImplementationName != NULL ) &&
+ ( pServiceManager != NULL )
+ )
+ {
+ // Define variables which are used in following macros.
+ Reference< XSingleServiceFactory > xFactory ;
+ Reference< XMultiServiceFactory > xServiceManager( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ if( ScFilterDetect::impl_getStaticImplementationName().equalsAscii( pImplementationName ) )
+ {
+ xFactory.set(::cppu::createSingleFactory( xServiceManager,
+ ScFilterDetect::impl_getStaticImplementationName(),
+ ScFilterDetect::impl_createInstance,
+ ScFilterDetect::impl_getStaticSupportedServiceNames() ));
+ }
+
+ // Factory is valid - service was found.
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pReturn = xFactory.get();
+ }
+ }
+
+ // Return with result of this operation.
+ return pReturn ;
+}
+} // extern "C"
+
+
+
diff --git a/sc/source/ui/unoobj/dispuno.cxx b/sc/source/ui/unoobj/dispuno.cxx
new file mode 100644
index 000000000000..6c82871d02da
--- /dev/null
+++ b/sc/source/ui/unoobj/dispuno.cxx
@@ -0,0 +1,415 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <sfx2/viewfrm.hxx>
+#include <comphelper/uno3.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <svl/smplhint.hxx>
+
+#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+
+#include "dispuno.hxx"
+#include "unoguard.hxx"
+#include "tabvwsh.hxx"
+#include "dbdocfun.hxx"
+#include "dbcolect.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns"; //data into text
+const char* cURLDocDataSource = ".uno:DataSourceBrowser/DocumentDataSource";
+
+//------------------------------------------------------------------------
+
+SV_IMPL_PTRARR( XStatusListenerArr_Impl, XStatusListenerPtr );
+
+//------------------------------------------------------------------------
+
+uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( SfxViewShell* pViewShell )
+{
+ if ( pViewShell )
+ {
+ SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
+ if (pViewFrame)
+ {
+ return uno::Reference<view::XSelectionSupplier>( pViewFrame->GetFrame().GetController(), uno::UNO_QUERY );
+ }
+ }
+ return uno::Reference<view::XSelectionSupplier>();
+}
+
+//------------------------------------------------------------------------
+
+
+ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pViewSh) :
+ pViewShell( pViewSh )
+{
+ if ( pViewShell )
+ {
+ m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY));
+ if (m_xIntercepted.is())
+ {
+ comphelper::increment( m_refCount );
+
+ m_xIntercepted->registerDispatchProviderInterceptor(
+ static_cast<frame::XDispatchProviderInterceptor*>(this));
+ // this should make us the top-level dispatch-provider for the component, via a call to our
+ // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
+ uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
+ if (xInterceptedComponent.is())
+ xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
+
+ comphelper::decrement( m_refCount );
+ }
+
+ StartListening(*pViewShell);
+ }
+}
+
+ScDispatchProviderInterceptor::~ScDispatchProviderInterceptor()
+{
+ if (pViewShell)
+ EndListening(*pViewShell);
+}
+
+void ScDispatchProviderInterceptor::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pViewShell = NULL;
+}
+
+// XDispatchProvider
+
+uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
+ const util::URL& aURL, const rtl::OUString& aTargetFrameName,
+ sal_Int32 nSearchFlags )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<frame::XDispatch> xResult;
+ // create some dispatch ...
+ if ( pViewShell && (
+ !aURL.Complete.compareToAscii(cURLInsertColumns) ||
+ !aURL.Complete.compareToAscii(cURLDocDataSource) ) )
+ {
+ if (!m_xMyDispatch.is())
+ m_xMyDispatch = new ScDispatch( pViewShell );
+ xResult = m_xMyDispatch;
+ }
+
+ // ask our slave provider
+ if (!xResult.is() && m_xSlaveDispatcher.is())
+ xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
+
+ return xResult;
+}
+
+uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
+ ScDispatchProviderInterceptor::queryDispatches(
+ const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
+ uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
+ const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
+ for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
+ {
+ *pReturn = queryDispatch(pDescripts->FeatureURL,
+ pDescripts->FrameName, pDescripts->SearchFlags);
+ }
+ return aReturn;
+}
+
+// XDispatchProviderInterceptor
+
+uno::Reference<frame::XDispatchProvider> SAL_CALL
+ ScDispatchProviderInterceptor::getSlaveDispatchProvider()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return m_xSlaveDispatcher;
+}
+
+void SAL_CALL ScDispatchProviderInterceptor::setSlaveDispatchProvider(
+ const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ m_xSlaveDispatcher.set(xNewDispatchProvider);
+}
+
+uno::Reference<frame::XDispatchProvider> SAL_CALL
+ ScDispatchProviderInterceptor::getMasterDispatchProvider()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return m_xMasterDispatcher;
+}
+
+void SAL_CALL ScDispatchProviderInterceptor::setMasterDispatchProvider(
+ const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ m_xMasterDispatcher.set(xNewSupplier);
+}
+
+// XEventListener
+
+void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if (m_xIntercepted.is())
+ {
+ m_xIntercepted->releaseDispatchProviderInterceptor(
+ static_cast<frame::XDispatchProviderInterceptor*>(this));
+ uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
+ if (xInterceptedComponent.is())
+ xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
+
+ m_xMyDispatch = NULL;
+ }
+ m_xIntercepted = NULL;
+}
+
+//------------------------------------------------------------------------
+
+ScDispatch::ScDispatch(ScTabViewShell* pViewSh) :
+ pViewShell( pViewSh ),
+ bListeningToView( FALSE )
+{
+ if (pViewShell)
+ StartListening(*pViewShell);
+}
+
+ScDispatch::~ScDispatch()
+{
+ if (pViewShell)
+ EndListening(*pViewShell);
+
+ if (bListeningToView && pViewShell)
+ {
+ uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
+ if ( xSupplier.is() )
+ xSupplier->removeSelectionChangeListener(this);
+ }
+}
+
+void ScDispatch::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pViewShell = NULL;
+}
+
+// XDispatch
+
+void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
+ const uno::Sequence<beans::PropertyValue>& aArgs )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ BOOL bDone = FALSE;
+ if ( pViewShell && !aURL.Complete.compareToAscii(cURLInsertColumns) )
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScAddress aPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
+
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ bDone = aFunc.DoImportUno( aPos, aArgs );
+ }
+ // cURLDocDataSource is never dispatched
+
+ if (!bDone)
+ throw uno::RuntimeException();
+}
+
+void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
+{
+ rEvent.IsEnabled = rParam.bImport;
+
+ ::svx::ODataAccessDescriptor aDescriptor;
+ if ( rParam.bImport )
+ {
+ sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
+ ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
+ sdb::CommandType::TABLE );
+
+ aDescriptor.setDataSource(rtl::OUString( rParam.aDBName ));
+ aDescriptor[svx::daCommand] <<= rtl::OUString( rParam.aStatement );
+ aDescriptor[svx::daCommandType] <<= nType;
+ }
+ else
+ {
+ // descriptor has to be complete anyway
+
+ rtl::OUString aEmpty;
+ aDescriptor[svx::daDataSource] <<= aEmpty;
+ aDescriptor[svx::daCommand] <<= aEmpty;
+ aDescriptor[svx::daCommandType] <<= (sal_Int32)sdb::CommandType::TABLE;
+ }
+ rEvent.State <<= aDescriptor.createPropertyValueSequence();
+}
+
+void SAL_CALL ScDispatch::addStatusListener(
+ const uno::Reference<frame::XStatusListener>& xListener,
+ const util::URL& aURL )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if (!pViewShell)
+ throw uno::RuntimeException();
+
+ // initial state
+ frame::FeatureStateEvent aEvent;
+ aEvent.IsEnabled = sal_True;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.FeatureURL = aURL;
+
+ if ( !aURL.Complete.compareToAscii(cURLDocDataSource) )
+ {
+ uno::Reference<frame::XStatusListener>* pObj =
+ new uno::Reference<frame::XStatusListener>( xListener );
+ aDataSourceListeners.Insert( pObj, aDataSourceListeners.Count() );
+
+ if (!bListeningToView)
+ {
+ uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
+ if ( xSupplier.is() )
+ xSupplier->addSelectionChangeListener(this);
+ bListeningToView = sal_True;
+ }
+
+ ScDBData* pDBData = pViewShell->GetDBData(FALSE,SC_DB_OLD);
+ if ( pDBData )
+ pDBData->GetImportParam( aLastImport );
+ lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
+ }
+ //! else add to listener for "enabled" changes?
+
+ xListener->statusChanged( aEvent );
+}
+
+void SAL_CALL ScDispatch::removeStatusListener(
+ const uno::Reference<frame::XStatusListener>& xListener,
+ const util::URL& aURL )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( !aURL.Complete.compareToAscii(cURLDocDataSource) )
+ {
+ USHORT nCount = aDataSourceListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<frame::XStatusListener> *pObj = aDataSourceListeners[n];
+ if ( *pObj == xListener )
+ {
+ aDataSourceListeners.DeleteAndDestroy( n );
+ break;
+ }
+ }
+
+ if ( aDataSourceListeners.Count() == 0 && pViewShell )
+ {
+ uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
+ if ( xSupplier.is() )
+ xSupplier->removeSelectionChangeListener(this);
+ bListeningToView = sal_False;
+ }
+ }
+}
+
+// XSelectionChangeListener
+
+void SAL_CALL ScDispatch::selectionChanged( const ::com::sun::star::lang::EventObject& /* aEvent */ )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ // currently only called for URL cURLDocDataSource
+
+ if ( pViewShell )
+ {
+ ScImportParam aNewImport;
+ ScDBData* pDBData = pViewShell->GetDBData(FALSE,SC_DB_OLD);
+ if ( pDBData )
+ pDBData->GetImportParam( aNewImport );
+
+ // notify listeners only if data source has changed
+ if ( aNewImport.bImport != aLastImport.bImport ||
+ aNewImport.aDBName != aLastImport.aDBName ||
+ aNewImport.aStatement != aLastImport.aStatement ||
+ aNewImport.bSql != aLastImport.bSql ||
+ aNewImport.nType != aLastImport.nType )
+ {
+ frame::FeatureStateEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.FeatureURL.Complete = rtl::OUString::createFromAscii( cURLDocDataSource );
+
+ lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
+
+ for ( USHORT n=0; n<aDataSourceListeners.Count(); n++ )
+ (*aDataSourceListeners[n])->statusChanged( aEvent );
+
+ aLastImport = aNewImport;
+ }
+ }
+}
+
+// XEventListener
+
+void SAL_CALL ScDispatch::disposing( const ::com::sun::star::lang::EventObject& rSource )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
+ xSupplier->removeSelectionChangeListener(this);
+ bListeningToView = sal_False;
+
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for ( USHORT n=0; n<aDataSourceListeners.Count(); n++ )
+ (*aDataSourceListeners[n])->disposing( aEvent );
+
+ pViewShell = NULL;
+}
+
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
new file mode 100644
index 000000000000..c92525b8ca57
--- /dev/null
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -0,0 +1,3788 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <svx/fmdpage.hxx>
+#include <svx/fmview.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svxids.hrc>
+#include <svx/unoshape.hxx>
+
+#include <svl/numuno.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/undoopt.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+#include <vcl/waitobj.hxx>
+#include <unotools/charclass.hxx>
+#include <tools/multisel.hxx>
+#include <tools/resary.hxx>
+#include <toolkit/awt/vclxdevice.hxx>
+
+#include <ctype.h>
+#include <float.h> // DBL_MAX
+
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include "docuno.hxx"
+#include "cellsuno.hxx"
+#include "nameuno.hxx"
+#include "datauno.hxx"
+#include "miscuno.hxx"
+#include "notesuno.hxx"
+#include "styleuno.hxx"
+#include "linkuno.hxx"
+#include "servuno.hxx"
+#include "targuno.hxx"
+#include "convuno.hxx"
+#include "optuno.hxx"
+#include "forbiuno.hxx"
+#include "docsh.hxx"
+#include "hints.hxx"
+#include "docfunc.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "drwlayer.hxx"
+#include "rangeutl.hxx"
+#include "markdata.hxx"
+#include "docoptio.hxx"
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "shapeuno.hxx"
+#include "viewuno.hxx"
+#include "tabvwsh.hxx"
+#include "printfun.hxx"
+#include "pfuncache.hxx"
+#include "scmod.hxx"
+#include "rangeutl.hxx"
+#include "ViewSettingsSequenceDefines.hxx"
+#include "sheetevents.hxx"
+#include "sc.hrc"
+#include "scresid.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+// alles ohne Which-ID, Map nur fuer PropertySetInfo
+
+//! umbenennen, sind nicht mehr nur Options
+const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap()
+{
+ static SfxItemPropertyMapEntry aDocOptPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_APPLYFMDES), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_AREALINKS), 0, &getCppuType((uno::Reference<sheet::XAreaLinks>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_AUTOCONTFOC), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_BASICLIBRARIES), 0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_DIALOGLIBRARIES), 0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_CALCASSHOWN), PROP_UNO_CALCASSHOWN, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), 0, &getCppuType((lang::Locale*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), 0, &getCppuType((lang::Locale*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), 0, &getCppuType((lang::Locale*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_COLLABELRNG), 0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_DDELINKS), 0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_DEFTABSTOP), PROP_UNO_DEFTABSTOP, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_EXTERNALDOCLINKS), 0, &getCppuType((uno::Reference<sheet::XExternalDocLinks>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_FORBIDDEN), 0, &getCppuType((uno::Reference<i18n::XForbiddenCharacters>*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_HASDRAWPAGES), 0, &getBooleanCppuType(), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_IGNORECASE), PROP_UNO_IGNORECASE, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ITERENABLED), PROP_UNO_ITERENABLED, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ITERCOUNT), PROP_UNO_ITERCOUNT, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ITEREPSILON), PROP_UNO_ITEREPSILON, &getCppuType((double*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_LOOKUPLABELS), PROP_UNO_LOOKUPLABELS, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_MATCHWHOLE), PROP_UNO_MATCHWHOLE, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_NAMEDRANGES), 0, &getCppuType((uno::Reference<sheet::XNamedRanges>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_DATABASERNG), 0, &getCppuType((uno::Reference<sheet::XDatabaseRanges>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_NULLDATE), PROP_UNO_NULLDATE, &getCppuType((util::Date*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ROWLABELRNG), 0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHEETLINKS), 0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SPELLONLINE), PROP_UNO_SPELLONLINE, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_STANDARDDEC), PROP_UNO_STANDARDDEC, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_REGEXENABLED), PROP_UNO_REGEXENABLED, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_RUNTIMEUID), 0, &getCppuType(static_cast< const rtl::OUString * >(0)), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_HASVALIDSIGNATURES),0, &getBooleanCppuType(), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN(SC_UNO_ISLOADED), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ISUNDOENABLED), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ISADJUSTHEIGHTENABLED), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ISEXECUTELINKENABLED), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ISCHANGEREADONLYENABLED), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_REFERENCEDEVICE), 0, &getCppuType((uno::Reference<awt::XDevice>*)0), beans::PropertyAttribute::READONLY, 0},
+ {MAP_CHAR_LEN("BuildId"), 0, &::getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_CODENAME), 0, &getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0},
+
+ {0,0,0,0,0,0}
+ };
+ return aDocOptPropertyMap_Impl;
+}
+
+//! StandardDecimals als Property und vom NumberFormatter ????????
+
+const SfxItemPropertyMapEntry* lcl_GetColumnsPropertyMap()
+{
+ static SfxItemPropertyMapEntry aColumnsPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_MANPAGE), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NEWPAGE), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVIS), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_OWIDTH), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLWID), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aColumnsPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* lcl_GetRowsPropertyMap()
+{
+ static SfxItemPropertyMapEntry aRowsPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHGT), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLFILT), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_OHEIGHT), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_MANPAGE), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_NEWPAGE), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVIS), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ // not sorted, not used with SfxItemPropertyMapEntry::GetByName
+ {0,0,0,0,0,0}
+ };
+ return aRowsPropertyMap_Impl;
+}
+
+//! move these functions to a header file
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+
+//------------------------------------------------------------------------
+
+#define SCMODELOBJ_SERVICE "com.sun.star.sheet.SpreadsheetDocument"
+#define SCDOCSETTINGS_SERVICE "com.sun.star.sheet.SpreadsheetDocumentSettings"
+#define SCDOC_SERVICE "com.sun.star.document.OfficeDocument"
+
+SC_SIMPLE_SERVICE_INFO( ScAnnotationsObj, "ScAnnotationsObj", "com.sun.star.sheet.CellAnnotations" )
+SC_SIMPLE_SERVICE_INFO( ScDrawPagesObj, "ScDrawPagesObj", "com.sun.star.drawing.DrawPages" )
+SC_SIMPLE_SERVICE_INFO( ScScenariosObj, "ScScenariosObj", "com.sun.star.sheet.Scenarios" )
+SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettingsObj, "ScSpreadsheetSettingsObj", "com.sun.star.sheet.SpreadsheetDocumentSettings" )
+SC_SIMPLE_SERVICE_INFO( ScTableColumnsObj, "ScTableColumnsObj", "com.sun.star.table.TableColumns" )
+SC_SIMPLE_SERVICE_INFO( ScTableRowsObj, "ScTableRowsObj", "com.sun.star.table.TableRows" )
+SC_SIMPLE_SERVICE_INFO( ScTableSheetsObj, "ScTableSheetsObj", "com.sun.star.sheet.Spreadsheets" )
+
+//------------------------------------------------------------------------
+
+class ScPrintUIOptions : public vcl::PrinterOptionsHelper
+{
+public:
+ ScPrintUIOptions();
+ void SetDefaults();
+};
+
+ScPrintUIOptions::ScPrintUIOptions()
+{
+ const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
+ sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
+ sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();
+
+ ResStringArray aStrings( ScResId( SCSTR_PRINT_OPTIONS ) );
+ DBG_ASSERT( aStrings.Count() >= 19, "resource incomplete" );
+ if( aStrings.Count() < 19 ) // bad resource ?
+ return;
+
+ m_aUIProperties.realloc( 8 );
+
+ // create Section for spreadsheet (results in an extra tab page in dialog)
+ SvtModuleOptions aOpt;
+ String aAppGroupname( aStrings.GetString( 18 ) );
+ aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
+ aOpt.GetModuleName( SvtModuleOptions::E_SCALC ) );
+ m_aUIProperties[0].Value = getGroupControlOpt( aAppGroupname, rtl::OUString() );
+
+ // create subgroup for pages
+ m_aUIProperties[1].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 0 ) ), rtl::OUString() );
+
+ // create a bool option for empty pages
+ m_aUIProperties[2].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 1 ) ),
+ rtl::OUString( aStrings.GetString( 2 ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsIncludeEmptyPages" ) ),
+ ! bSuppress
+ );
+ // create Subgroup for print content
+ vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
+ aPrintRangeOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
+ m_aUIProperties[3].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 6 ) ),
+ rtl::OUString(),
+ aPrintRangeOpt
+ );
+
+ // create a choice for the content to create
+ uno::Sequence< rtl::OUString > aChoices( 3 ), aHelpTexts( 3 );
+ aChoices[0] = aStrings.GetString( 7 );
+ aHelpTexts[0] = aStrings.GetString( 8 );
+ aChoices[1] = aStrings.GetString( 9 );
+ aHelpTexts[1] = aStrings.GetString( 10 );
+ aChoices[2] = aStrings.GetString( 11 );
+ aHelpTexts[2] = aStrings.GetString( 12 );
+ m_aUIProperties[4].Value = getChoiceControlOpt( rtl::OUString(),
+ aHelpTexts,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ),
+ aChoices,
+ nContent );
+
+ // create Subgroup for print range
+ aPrintRangeOpt.mbInternalOnly = sal_True;
+ m_aUIProperties[5].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 13 ) ),
+ rtl::OUString(),
+ aPrintRangeOpt
+ );
+
+ // create a choice for the range to print
+ rtl::OUString aPrintRangeName( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
+ aChoices.realloc( 2 );
+ aHelpTexts.realloc( 2 );
+ aChoices[0] = aStrings.GetString( 14 );
+ aHelpTexts[0] = aStrings.GetString( 15 );
+ aChoices[1] = aStrings.GetString( 16 );
+ aHelpTexts[1] = aStrings.GetString( 17 );
+ m_aUIProperties[6].Value = getChoiceControlOpt( rtl::OUString(),
+ aHelpTexts,
+ aPrintRangeName,
+ aChoices,
+ 0 );
+
+ // create a an Edit dependent on "Pages" selected
+ vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, sal_True );
+ m_aUIProperties[7].Value = getEditControlOpt( rtl::OUString(),
+ rtl::OUString(),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ),
+ rtl::OUString(),
+ aPageRangeOpt
+ );
+
+ // "Print only selected sheets" isn't needed because of the "Selected Sheets" choice in "Print content"
+#if 0
+ // create subgroup for sheets
+ m_aUIProperties[8].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 3 ) ), rtl::OUString() );
+
+ // create a bool option for selected pages only
+ m_aUIProperties[9].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 4 ) ),
+ rtl::OUString( aStrings.GetString( 5 ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsOnlySelectedSheets" ) ),
+ i_bSelectedOnly
+ );
+#endif
+}
+
+void ScPrintUIOptions::SetDefaults()
+{
+ // re-initialize the default values from print options
+
+ const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
+ sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
+ sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();
+
+ for (sal_Int32 nUIPos=0; nUIPos<m_aUIProperties.getLength(); ++nUIPos)
+ {
+ uno::Sequence<beans::PropertyValue> aUIProp;
+ if ( m_aUIProperties[nUIPos].Value >>= aUIProp )
+ {
+ for (sal_Int32 nPropPos=0; nPropPos<aUIProp.getLength(); ++nPropPos)
+ {
+ rtl::OUString aName = aUIProp[nPropPos].Name;
+ if ( aName.equalsAscii("Property") )
+ {
+ beans::PropertyValue aPropertyValue;
+ if ( aUIProp[nPropPos].Value >>= aPropertyValue )
+ {
+ if ( aPropertyValue.Name.equalsAscii( "PrintContent" ) )
+ {
+ aPropertyValue.Value <<= nContent;
+ aUIProp[nPropPos].Value <<= aPropertyValue;
+ }
+ else if ( aPropertyValue.Name.equalsAscii( "IsIncludeEmptyPages" ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aPropertyValue.Value, ! bSuppress );
+ aUIProp[nPropPos].Value <<= aPropertyValue;
+ }
+ }
+ }
+ }
+ m_aUIProperties[nUIPos].Value <<= aUIProp;
+ }
+ }
+}
+
+// static
+void ScModelObj::CreateAndSet(ScDocShell* pDocSh)
+{
+ if (pDocSh)
+ pDocSh->SetBaseModel( new ScModelObj(pDocSh) );
+}
+
+ScModelObj::ScModelObj( ScDocShell* pDocSh ) :
+ SfxBaseModel( pDocSh ),
+ aPropSet( lcl_GetDocOptPropertyMap() ),
+ pDocShell( pDocSh ),
+ pPrintFuncCache( NULL ),
+ pPrinterOptions( NULL ),
+ maChangesListeners( m_aMutex )
+{
+ // pDocShell may be NULL if this is the base of a ScDocOptionsObj
+ if ( pDocShell )
+ {
+ pDocShell->GetDocument()->AddUnoObject(*this); // SfxModel is derived from SfxListener
+ }
+}
+
+ScModelObj::~ScModelObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+
+ if (xNumberAgg.is())
+ xNumberAgg->setDelegator(uno::Reference<uno::XInterface>());
+
+ delete pPrintFuncCache;
+ delete pPrinterOptions;
+}
+
+uno::Reference< uno::XAggregation> ScModelObj::GetFormatter()
+{
+ // pDocShell may be NULL if this is the base of a ScDocOptionsObj
+ if ( !xNumberAgg.is() && pDocShell )
+ {
+ // setDelegator veraendert den RefCount, darum eine Referenz selber halten
+ // (direkt am m_refCount, um sich beim release nicht selbst zu loeschen)
+ comphelper::increment( m_refCount );
+ // waehrend des queryInterface braucht man ein Ref auf das
+ // SvNumberFormatsSupplierObj, sonst wird es geloescht.
+ uno::Reference<util::XNumberFormatsSupplier> xFormatter(new SvNumberFormatsSupplierObj(pDocShell->GetDocument()->GetFormatTable() ));
+ {
+ xNumberAgg.set(uno::Reference<uno::XAggregation>( xFormatter, uno::UNO_QUERY ));
+ // extra block to force deletion of the temporary before setDelegator
+ }
+
+ // beim setDelegator darf die zusaetzliche Ref nicht mehr existieren
+ xFormatter = NULL;
+
+ if (xNumberAgg.is())
+ xNumberAgg->setDelegator( (cppu::OWeakObject*)this );
+ comphelper::decrement( m_refCount );
+ } // if ( !xNumberAgg.is() )
+ return xNumberAgg;
+}
+
+ScDocument* ScModelObj::GetDocument() const
+{
+ if (pDocShell)
+ return pDocShell->GetDocument();
+ return NULL;
+}
+
+SfxObjectShell* ScModelObj::GetEmbeddedObject() const
+{
+ return pDocShell;
+}
+
+void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark)
+{
+ if (pDocShell)
+ pDocShell->UpdateAllRowHeights(pTabMark);
+}
+
+void ScModelObj::BeforeXMLLoading()
+{
+ if (pDocShell)
+ pDocShell->BeforeXMLLoading();
+}
+
+void ScModelObj::AfterXMLLoading(sal_Bool bRet)
+{
+ if (pDocShell)
+ pDocShell->AfterXMLLoading(bRet);
+}
+
+ScSheetSaveData* ScModelObj::GetSheetSaveData()
+{
+ if (pDocShell)
+ return pDocShell->GetSheetSaveData();
+ return NULL;
+}
+
+uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XSpreadsheetDocument )
+ SC_QUERYINTERFACE( document::XActionLockable )
+ SC_QUERYINTERFACE( sheet::XCalculatable )
+ SC_QUERYINTERFACE( util::XProtectable )
+ SC_QUERYINTERFACE( drawing::XDrawPagesSupplier )
+ SC_QUERYINTERFACE( sheet::XGoalSeek )
+ SC_QUERYINTERFACE( sheet::XConsolidatable )
+ SC_QUERYINTERFACE( sheet::XDocumentAuditing )
+ SC_QUERYINTERFACE( style::XStyleFamiliesSupplier )
+ SC_QUERYINTERFACE( view::XRenderable )
+ SC_QUERYINTERFACE( document::XLinkTargetSupplier )
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( lang::XMultiServiceFactory )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+ SC_QUERYINTERFACE( util::XChangesNotifier )
+
+ uno::Any aRet(SfxBaseModel::queryInterface( rType ));
+ if ( !aRet.hasValue()
+ && rType != ::getCppuType((uno::Reference< com::sun::star::document::XDocumentEventBroadcaster>*)0)
+ && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XController>*)0)
+ && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XFrame>*)0)
+ && rType != ::getCppuType((uno::Reference< com::sun::star::script::XInvocation>*)0)
+ && rType != ::getCppuType((uno::Reference< com::sun::star::reflection::XIdlClassProvider>*)0)
+ && rType != ::getCppuType((uno::Reference< com::sun::star::beans::XFastPropertySet>*)0)
+ && rType != ::getCppuType((uno::Reference< com::sun::star::awt::XWindow>*)0))
+ {
+ GetFormatter();
+ if ( xNumberAgg.is() )
+ aRet = xNumberAgg->queryAggregation( rType );
+ }
+
+ return aRet;
+}
+
+void SAL_CALL ScModelObj::acquire() throw()
+{
+ SfxBaseModel::acquire();
+}
+
+void SAL_CALL ScModelObj::release() throw()
+{
+ SfxBaseModel::release();
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScModelObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(SfxBaseModel::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ uno::Sequence<uno::Type> aAggTypes;
+ if ( GetFormatter().is() )
+ {
+ const uno::Type& rProvType = ::getCppuType((uno::Reference<lang::XTypeProvider>*) 0);
+ uno::Any aNumProv(xNumberAgg->queryAggregation(rProvType));
+ if(aNumProv.getValueType() == rProvType)
+ {
+ uno::Reference<lang::XTypeProvider> xNumProv(
+ *(uno::Reference<lang::XTypeProvider>*)aNumProv.getValue());
+ aAggTypes = xNumProv->getTypes();
+ }
+ }
+ long nAggLen = aAggTypes.getLength();
+ const uno::Type* pAggPtr = aAggTypes.getConstArray();
+
+ const long nThisLen = 15;
+ aTypes.realloc( nParentLen + nAggLen + nThisLen );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheetDocument>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<document::XActionLockable>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XCalculatable>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<util::XProtectable>*)0);
+ pPtr[nParentLen + 4] = getCppuType((const uno::Reference<drawing::XDrawPagesSupplier>*)0);
+ pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XGoalSeek>*)0);
+ pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XConsolidatable>*)0);
+ pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XDocumentAuditing>*)0);
+ pPtr[nParentLen + 8] = getCppuType((const uno::Reference<style::XStyleFamiliesSupplier>*)0);
+ pPtr[nParentLen + 9] = getCppuType((const uno::Reference<view::XRenderable>*)0);
+ pPtr[nParentLen +10] = getCppuType((const uno::Reference<document::XLinkTargetSupplier>*)0);
+ pPtr[nParentLen +11] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
+ pPtr[nParentLen +12] = getCppuType((const uno::Reference<lang::XMultiServiceFactory>*)0);
+ pPtr[nParentLen +13] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
+ pPtr[nParentLen +14] = getCppuType((const uno::Reference<util::XChangesNotifier>*)0);
+
+ long i;
+ for (i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+
+ for (i=0; i<nAggLen; i++)
+ pPtr[nParentLen+nThisLen+i] = pAggPtr[i]; // aggregated types last
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScModelObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ // Not interested in reference update hints here
+
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // has become invalid
+ if (xNumberAgg.is())
+ {
+ SvNumberFormatsSupplierObj* pNumFmt =
+ SvNumberFormatsSupplierObj::getImplementation(
+ uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
+ if ( pNumFmt )
+ pNumFmt->SetNumberFormatter( NULL );
+ }
+
+ DELETEZ( pPrintFuncCache ); // must be deleted because it has a pointer to the DocShell
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // cached data for rendering become invalid when contents change
+ // (if a broadcast is added to SetDrawModified, is has to be tested here, too)
+
+ DELETEZ( pPrintFuncCache );
+
+ // handle "OnCalculate" sheet events (search also for VBA event handlers)
+ if ( pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) )
+ HandleCalculateEvents();
+ }
+ }
+ else if ( rHint.ISA( ScPointerChangedHint ) )
+ {
+ USHORT nFlags = ((const ScPointerChangedHint&)rHint).GetFlags();
+ if (nFlags & SC_POINTERCHANGED_NUMFMT)
+ {
+ // NumberFormatter-Pointer am Uno-Objekt neu setzen
+
+ if (GetFormatter().is())
+ {
+ SvNumberFormatsSupplierObj* pNumFmt =
+ SvNumberFormatsSupplierObj::getImplementation(
+ uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
+ if ( pNumFmt && pDocShell )
+ pNumFmt->SetNumberFormatter( pDocShell->GetDocument()->GetFormatTable() );
+ }
+ }
+ }
+
+ // always call parent - SfxBaseModel might need to handle the same hints again
+ SfxBaseModel::Notify( rBC, rHint ); // SfxBaseModel is derived from SfxListener
+}
+
+// XSpreadsheetDocument
+
+uno::Reference<sheet::XSpreadsheets> SAL_CALL ScModelObj::getSheets() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScTableSheetsObj(pDocShell);
+ return NULL;
+}
+
+// XStyleFamiliesSupplier
+
+uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getStyleFamilies()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScStyleFamiliesObj(pDocShell);
+ return NULL;
+}
+
+// XRenderable
+
+OutputDevice* lcl_GetRenderDevice( const uno::Sequence<beans::PropertyValue>& rOptions )
+{
+ OutputDevice* pRet = NULL;
+ const beans::PropertyValue* pPropArray = rOptions.getConstArray();
+ long nPropCount = rOptions.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( SC_UNONAME_RENDERDEV ))
+ {
+ uno::Reference<awt::XDevice> xRenderDevice(rProp.Value, uno::UNO_QUERY);
+ if ( xRenderDevice.is() )
+ {
+ VCLXDevice* pDevice = VCLXDevice::GetImplementation( xRenderDevice );
+ if ( pDevice )
+ {
+ pRet = pDevice->GetOutputDevice();
+ pRet->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ }
+ }
+ }
+ }
+ return pRet;
+}
+
+bool lcl_ParseTarget( const String& rTarget, ScRange& rTargetRange, Rectangle& rTargetRect,
+ bool& rIsSheet, ScDocument* pDoc, SCTAB nSourceTab )
+{
+ // test in same order as in SID_CURRENTCELL execute
+
+ ScAddress aAddress;
+ ScRangeUtil aRangeUtil;
+ SCTAB nNameTab;
+ sal_Int32 nNumeric = 0;
+
+ bool bRangeValid = false;
+ bool bRectValid = false;
+
+ if ( rTargetRange.Parse( rTarget, pDoc ) & SCA_VALID )
+ {
+ bRangeValid = true; // range reference
+ }
+ else if ( aAddress.Parse( rTarget, pDoc ) & SCA_VALID )
+ {
+ rTargetRange = aAddress;
+ bRangeValid = true; // cell reference
+ }
+ else if ( aRangeUtil.MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_NAMES ) ||
+ aRangeUtil.MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_DBASE ) )
+ {
+ bRangeValid = true; // named range or database range
+ }
+ else if ( ByteString( rTarget, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() &&
+ ( nNumeric = rTarget.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
+ {
+ // row number is always mapped to cell A(row) on the same sheet
+ rTargetRange = ScAddress( 0, (SCROW)(nNumeric-1), nSourceTab ); // target row number is 1-based
+ bRangeValid = true; // row number
+ }
+ else if ( pDoc->GetTable( rTarget, nNameTab ) )
+ {
+ rTargetRange = ScAddress(0,0,nNameTab);
+ bRangeValid = true; // sheet name
+ rIsSheet = true; // needs special handling (first page of the sheet)
+ }
+ else
+ {
+ // look for named drawing object
+
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if ( pDrawLayer )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount && !bRangeValid; i++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bRangeValid)
+ {
+ if ( ScDrawLayer::GetVisibleName( pObject ) == rTarget )
+ {
+ rTargetRect = pObject->GetLogicRect(); // 1/100th mm
+ rTargetRange = pDoc->GetRange( i, rTargetRect ); // underlying cells
+ bRangeValid = bRectValid = true; // rectangle is valid
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+ }
+ if ( bRangeValid && !bRectValid )
+ {
+ // get rectangle for cell range
+ rTargetRect = pDoc->GetMMRect( rTargetRange.aStart.Col(), rTargetRange.aStart.Row(),
+ rTargetRange.aEnd.Col(), rTargetRange.aEnd.Row(),
+ rTargetRange.aStart.Tab() );
+ }
+
+ return bRangeValid;
+}
+
+BOOL ScModelObj::FillRenderMarkData( const uno::Any& aSelection,
+ const uno::Sequence< beans::PropertyValue >& rOptions,
+ ScMarkData& rMark,
+ ScPrintSelectionStatus& rStatus, String& rPagesStr ) const
+{
+ DBG_ASSERT( !rMark.IsMarked() && !rMark.IsMultiMarked(), "FillRenderMarkData: MarkData must be empty" );
+ DBG_ASSERT( pDocShell, "FillRenderMarkData: DocShell must be set" );
+
+ BOOL bDone = FALSE;
+
+ uno::Reference<frame::XController> xView;
+
+ // defaults when no options are passed: all sheets, include empty pages
+ sal_Bool bSelectedSheetsOnly = sal_False;
+ sal_Bool bIncludeEmptyPages = sal_True;
+
+ bool bHasPrintContent = false;
+ sal_Int32 nPrintContent = 0; // all sheets / selected sheets / selected cells
+ sal_Int32 nPrintRange = 0; // all pages / pages
+ rtl::OUString aPageRange; // "pages" edit value
+
+ for( sal_Int32 i = 0, nLen = rOptions.getLength(); i < nLen; i++ )
+ {
+ if( rOptions[i].Name.equalsAscii( "IsOnlySelectedSheets" ) )
+ {
+ rOptions[i].Value >>= bSelectedSheetsOnly;
+ }
+ else if( rOptions[i].Name.equalsAscii( "IsIncludeEmptyPages" ) )
+ {
+ rOptions[i].Value >>= bIncludeEmptyPages;
+ }
+ else if( rOptions[i].Name.equalsAscii( "PageRange" ) )
+ {
+ rOptions[i].Value >>= aPageRange;
+ }
+ else if( rOptions[i].Name.equalsAscii( "PrintRange" ) )
+ {
+ rOptions[i].Value >>= nPrintRange;
+ }
+ else if( rOptions[i].Name.equalsAscii( "PrintContent" ) )
+ {
+ bHasPrintContent = true;
+ rOptions[i].Value >>= nPrintContent;
+ }
+ else if( rOptions[i].Name.equalsAscii( "View" ) )
+ {
+ rOptions[i].Value >>= xView;
+ }
+ }
+
+ // "Print Content" selection wins over "Selected Sheets" option
+ if ( bHasPrintContent )
+ bSelectedSheetsOnly = ( nPrintContent != 0 );
+
+ uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
+ if ( xInterface.is() )
+ {
+ ScCellRangesBase* pSelObj = ScCellRangesBase::getImplementation( xInterface );
+ uno::Reference< drawing::XShapes > xShapes( xInterface, uno::UNO_QUERY );
+ if ( pSelObj && pSelObj->GetDocShell() == pDocShell )
+ {
+ BOOL bSheet = ( ScTableSheetObj::getImplementation( xInterface ) != NULL );
+ BOOL bCursor = pSelObj->IsCursorOnly();
+ const ScRangeList& rRanges = pSelObj->GetRangeList();
+
+ rMark.MarkFromRangeList( rRanges, FALSE );
+ rMark.MarkToSimple();
+
+ if ( rMark.IsMultiMarked() )
+ {
+ // #i115266# copy behavior of old printing:
+ // treat multiple selection like a single selection with the enclosing range
+ ScRange aMultiMarkArea;
+ rMark.GetMultiMarkArea( aMultiMarkArea );
+ rMark.ResetMark();
+ rMark.SetMarkArea( aMultiMarkArea );
+ }
+
+ if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // a sheet object is treated like an empty selection: print the used area of the sheet
+
+ if ( bCursor || bSheet ) // nothing selected -> use whole tables
+ {
+ rMark.ResetMark(); // doesn't change table selection
+ rStatus.SetMode( SC_PRINTSEL_CURSOR );
+ }
+ else
+ rStatus.SetMode( SC_PRINTSEL_RANGE );
+
+ rStatus.SetRanges( rRanges );
+ bDone = TRUE;
+ }
+ // multi selection isn't supported
+ }
+ else if( xShapes.is() )
+ {
+ //print a selected ole object
+ uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY );
+ if( xIndexAccess.is() )
+ {
+ // multi selection isn't supported yet
+ uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY );
+ SvxShape* pShape = SvxShape::getImplementation( xShape );
+ if( pShape )
+ {
+ SdrObject *pSdrObj = pShape->GetSdrObject();
+ if( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if( pDoc && pSdrObj )
+ {
+ Rectangle aObjRect = pSdrObj->GetCurrentBoundRect();
+ SCTAB nCurrentTab = ScDocShell::GetCurTab();
+ ScRange aRange = pDoc->GetRange( nCurrentTab, aObjRect );
+ rMark.SetMarkArea( aRange );
+
+ if( rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ rStatus.SetMode( SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS );
+ bDone = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( ScModelObj::getImplementation( xInterface ) == this )
+ {
+ // render the whole document
+ // -> no selection, all sheets
+
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
+ rMark.SelectTable( nTab, TRUE );
+ rStatus.SetMode( SC_PRINTSEL_DOCUMENT );
+ bDone = TRUE;
+ }
+ // other selection types aren't supported
+ }
+
+ // restrict to selected sheets if a view is available
+ if ( bSelectedSheetsOnly && xView.is() )
+ {
+ ScTabViewObj* pViewObj = ScTabViewObj::getImplementation( xView );
+ if (pViewObj)
+ {
+ ScTabViewShell* pViewSh = pViewObj->GetViewShell();
+ if (pViewSh)
+ {
+ const ScMarkData& rViewMark = pViewSh->GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
+ if (!rViewMark.GetTableSelect(nTab))
+ rMark.SelectTable( nTab, FALSE );
+ }
+ }
+ }
+
+ ScPrintOptions aNewOptions;
+ aNewOptions.SetSkipEmpty( !bIncludeEmptyPages );
+ aNewOptions.SetAllSheets( !bSelectedSheetsOnly );
+ rStatus.SetOptions( aNewOptions );
+
+ // "PrintRange" enables (1) or disables (0) the "PageRange" edit
+ if ( nPrintRange == 1 )
+ rPagesStr = aPageRange;
+ else
+ rPagesStr.Erase();
+
+ return bDone;
+}
+
+
+sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection,
+ const uno::Sequence<beans::PropertyValue>& rOptions )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScMarkData aMark;
+ ScPrintSelectionStatus aStatus;
+ String aPagesStr;
+ if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
+ return 0;
+
+ // The same ScPrintFuncCache object in pPrintFuncCache is used as long as
+ // the same selection is used (aStatus) and the document isn't changed
+ // (pPrintFuncCache is cleared in Notify handler)
+
+ if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
+ {
+ delete pPrintFuncCache;
+ pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
+ }
+ sal_Int32 nPages = pPrintFuncCache->GetPageCount();
+
+ sal_Int32 nSelectCount = nPages;
+ if ( aPagesStr.Len() )
+ {
+ MultiSelection aPageRanges( aPagesStr );
+ aPageRanges.SetTotalRange( Range( 1, nPages ) );
+ nSelectCount = aPageRanges.GetSelectCount();
+ }
+ return nSelectCount;
+}
+
+sal_Int32 lcl_GetRendererNum( sal_Int32 nSelRenderer, const String& rPagesStr, sal_Int32 nTotalPages )
+{
+ if ( !rPagesStr.Len() )
+ return nSelRenderer;
+
+ MultiSelection aPageRanges( rPagesStr );
+ aPageRanges.SetTotalRange( Range( 1, nTotalPages ) );
+
+ sal_Int32 nSelected = aPageRanges.FirstSelected();
+ while ( nSelRenderer > 0 )
+ {
+ nSelected = aPageRanges.NextSelected();
+ --nSelRenderer;
+ }
+ return nSelected - 1; // selection is 1-based
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 nSelRenderer,
+ const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& rOptions )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScMarkData aMark;
+ ScPrintSelectionStatus aStatus;
+ String aPagesStr;
+ // #i115266# if FillRenderMarkData fails, keep nTotalPages at 0, but still handle getRenderer(0) below
+ long nTotalPages = 0;
+ if ( FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
+ {
+ if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
+ {
+ delete pPrintFuncCache;
+ pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
+ }
+ nTotalPages = pPrintFuncCache->GetPageCount();
+ }
+ sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
+ if ( nRenderer >= nTotalPages )
+ {
+ if ( nSelRenderer == 0 )
+ {
+ // getRenderer(0) is used to query the settings, so it must always return something
+
+ SCTAB nCurTab = 0; //! use current sheet from view?
+ ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab );
+ Size aTwips = aDefaultFunc.GetPageSize();
+ awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );
+
+ uno::Sequence<beans::PropertyValue> aSequence(1);
+ beans::PropertyValue* pArray = aSequence.getArray();
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
+ pArray[0].Value <<= aPageSize;
+
+ if( ! pPrinterOptions )
+ pPrinterOptions = new ScPrintUIOptions;
+ else
+ pPrinterOptions->SetDefaults();
+ pPrinterOptions->appendPrintUIOptions( aSequence );
+ return aSequence;
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+
+ // printer is used as device (just for page layout), draw view is not needed
+
+ SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer );
+
+ ScRange aRange;
+ const ScRange* pSelRange = NULL;
+ if ( aMark.IsMarked() )
+ {
+ aMark.GetMarkArea( aRange );
+ pSelRange = &aRange;
+ }
+ ScPrintFunc aFunc( pDocShell, pDocShell->GetPrinter(), nTab,
+ pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
+ aFunc.SetRenderFlag( TRUE );
+
+ Range aPageRange( nRenderer+1, nRenderer+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
+ long nTabStart = pPrintFuncCache->GetTabStart( nTab );
+
+ (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, FALSE, NULL, NULL );
+
+ ScRange aCellRange;
+ BOOL bWasCellRange = aFunc.GetLastSourceRange( aCellRange );
+ Size aTwips = aFunc.GetPageSize();
+ awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );
+
+ long nPropCount = bWasCellRange ? 3 : 2;
+ uno::Sequence<beans::PropertyValue> aSequence(nPropCount);
+ beans::PropertyValue* pArray = aSequence.getArray();
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
+ pArray[0].Value <<= aPageSize;
+ // #i111158# all positions are relative to the whole page, including non-printable area
+ pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_INC_NP_AREA );
+ pArray[1].Value = uno::makeAny( sal_True );
+ if ( bWasCellRange )
+ {
+ table::CellRangeAddress aRangeAddress( nTab,
+ aCellRange.aStart.Col(), aCellRange.aStart.Row(),
+ aCellRange.aEnd.Col(), aCellRange.aEnd.Row() );
+ pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_SOURCERANGE );
+ pArray[2].Value <<= aRangeAddress;
+ }
+
+ #if 0
+ const ScPrintOptions& rPrintOpt =
+ #endif
+ // FIXME: is this for side effects ?
+ SC_MOD()->GetPrintOptions();
+ if( ! pPrinterOptions )
+ pPrinterOptions = new ScPrintUIOptions;
+ else
+ pPrinterOptions->SetDefaults();
+ pPrinterOptions->appendPrintUIOptions( aSequence );
+ return aSequence;
+}
+
+void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection,
+ const uno::Sequence<beans::PropertyValue>& rOptions )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScMarkData aMark;
+ ScPrintSelectionStatus aStatus;
+ String aPagesStr;
+ if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
+ throw lang::IllegalArgumentException();
+
+ if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
+ {
+ delete pPrintFuncCache;
+ pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
+ }
+ long nTotalPages = pPrintFuncCache->GetPageCount();
+ sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
+ if ( nRenderer >= nTotalPages )
+ throw lang::IllegalArgumentException();
+
+ OutputDevice* pDev = lcl_GetRenderDevice( rOptions );
+ if ( !pDev )
+ throw lang::IllegalArgumentException();
+
+ SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer );
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ FmFormView* pDrawView = NULL;
+ Rectangle aFull( 0, 0, LONG_MAX, LONG_MAX );
+
+ // #114135#
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+
+ if( pModel )
+ {
+ pDrawView = new FmFormView( pModel, pDev );
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ pDrawView->SetPrintPreview( TRUE );
+ }
+
+ ScRange aRange;
+ const ScRange* pSelRange = NULL;
+ if ( aMark.IsMarked() )
+ {
+ aMark.GetMarkArea( aRange );
+ pSelRange = &aRange;
+ }
+
+ // to increase performance, ScPrintState might be used here for subsequent
+ // pages of the same sheet
+
+ ScPrintFunc aFunc( pDev, pDocShell, nTab, pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
+ aFunc.SetDrawView( pDrawView );
+ aFunc.SetRenderFlag( TRUE );
+ if( aStatus.GetMode() == SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS )
+ aFunc.SetExclusivelyDrawOleAndDrawObjects();
+
+ Range aPageRange( nRenderer+1, nRenderer+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
+ long nTabStart = pPrintFuncCache->GetTabStart( nTab );
+
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+ if ( nRenderer == nTabStart )
+ {
+ // first page of a sheet: add outline item for the sheet name
+
+ if ( pPDFData && pPDFData->GetIsExportBookmarks() )
+ {
+ // the sheet starts at the top of the page
+ Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
+ sal_Int32 nDestID = pPDFData->CreateDest( aArea );
+ String aTabName;
+ pDoc->GetName( nTab, aTabName );
+ sal_Int32 nParent = -1; // top-level
+ pPDFData->CreateOutlineItem( nParent, aTabName, nDestID );
+ }
+ //--->i56629
+ // add the named destination stuff
+ if( pPDFData && pPDFData->GetIsExportNamedDestinations() )
+ {
+ Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
+ String aTabName;
+ pDoc->GetName( nTab, aTabName );
+//need the PDF page number here
+ pPDFData->CreateNamedDest( aTabName, aArea );
+ }
+ //<---i56629
+ }
+
+ (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, TRUE, NULL, NULL );
+
+ // resolve the hyperlinks for PDF export
+
+ if ( pPDFData )
+ {
+ // iterate over the hyperlinks that were output for this page
+
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >::iterator aIter = rBookmarks.begin();
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >::iterator aIEnd = rBookmarks.end();
+ while ( aIter != aIEnd )
+ {
+ rtl::OUString aBookmark = aIter->aBookmark;
+ if ( aBookmark.toChar() == (sal_Unicode) '#' )
+ {
+ // try to resolve internal link
+
+ String aTarget( aBookmark.copy( 1 ) );
+
+ ScRange aTargetRange;
+ Rectangle aTargetRect; // 1/100th mm
+ bool bIsSheet = false;
+ bool bValid = lcl_ParseTarget( aTarget, aTargetRange, aTargetRect, bIsSheet, pDoc, nTab );
+
+ if ( bValid )
+ {
+ sal_Int32 nPage = -1;
+ Rectangle aArea;
+ if ( bIsSheet )
+ {
+ // Get first page for sheet (if nothing from that sheet is printed,
+ // this page can show a different sheet)
+ nPage = pPrintFuncCache->GetTabStart( aTargetRange.aStart.Tab() );
+ aArea = pDev->PixelToLogic( Rectangle( 0,0,0,0 ) );
+ }
+ else
+ {
+ pPrintFuncCache->InitLocations( aMark, pDev ); // does nothing if already initialized
+
+ ScPrintPageLocation aLocation;
+ if ( pPrintFuncCache->FindLocation( aTargetRange.aStart, aLocation ) )
+ {
+ nPage = aLocation.nPage;
+
+ // get the rectangle of the page's cell range in 1/100th mm
+ ScRange aLocRange = aLocation.aCellRange;
+ Rectangle aLocationMM = pDoc->GetMMRect(
+ aLocRange.aStart.Col(), aLocRange.aStart.Row(),
+ aLocRange.aEnd.Col(), aLocRange.aEnd.Row(),
+ aLocRange.aStart.Tab() );
+ Rectangle aLocationPixel = aLocation.aRectangle;
+
+ // Scale and move the target rectangle from aLocationMM to aLocationPixel,
+ // to get the target rectangle in pixels.
+
+ Fraction aScaleX( aLocationPixel.GetWidth(), aLocationMM.GetWidth() );
+ Fraction aScaleY( aLocationPixel.GetHeight(), aLocationMM.GetHeight() );
+
+ long nX1 = aLocationPixel.Left() + (long)
+ ( Fraction( aTargetRect.Left() - aLocationMM.Left(), 1 ) * aScaleX );
+ long nX2 = aLocationPixel.Left() + (long)
+ ( Fraction( aTargetRect.Right() - aLocationMM.Left(), 1 ) * aScaleX );
+ long nY1 = aLocationPixel.Top() + (long)
+ ( Fraction( aTargetRect.Top() - aLocationMM.Top(), 1 ) * aScaleY );
+ long nY2 = aLocationPixel.Top() + (long)
+ ( Fraction( aTargetRect.Bottom() - aLocationMM.Top(), 1 ) * aScaleY );
+
+ if ( nX1 > aLocationPixel.Right() ) nX1 = aLocationPixel.Right();
+ if ( nX2 > aLocationPixel.Right() ) nX2 = aLocationPixel.Right();
+ if ( nY1 > aLocationPixel.Bottom() ) nY1 = aLocationPixel.Bottom();
+ if ( nY2 > aLocationPixel.Bottom() ) nY2 = aLocationPixel.Bottom();
+
+ // The link target area is interpreted using the device's MapMode at
+ // the time of the CreateDest call, so PixelToLogic can be used here,
+ // regardless of the MapMode that is actually selected.
+
+ aArea = pDev->PixelToLogic( Rectangle( nX1, nY1, nX2, nY2 ) );
+ }
+ }
+
+ if ( nPage >= 0 )
+ pPDFData->SetLinkDest( aIter->nLinkId, pPDFData->CreateDest( aArea, nPage ) );
+ }
+ }
+ else
+ {
+ // external link, use as-is
+ pPDFData->SetLinkURL( aIter->nLinkId, aBookmark );
+ }
+ aIter++;
+ }
+ rBookmarks.clear();
+ }
+
+ delete pDrawView;
+}
+
+// XLinkTargetSupplier
+
+uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getLinks() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScLinkTargetTypesObj(pDocShell);
+ return NULL;
+}
+
+// XActionLockable
+
+sal_Bool SAL_CALL ScModelObj::isActionLocked() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bLocked = FALSE;
+ if (pDocShell)
+ bLocked = ( pDocShell->GetLockCount() != 0 );
+ return bLocked;
+}
+
+void SAL_CALL ScModelObj::addActionLock() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ pDocShell->LockDocument();
+}
+
+void SAL_CALL ScModelObj::removeActionLock() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ pDocShell->UnlockDocument();
+}
+
+void SAL_CALL ScModelObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ pDocShell->SetLockCount(nLock);
+}
+
+sal_Int16 SAL_CALL ScModelObj::resetActionLocks() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nRet = 0;
+ if (pDocShell)
+ {
+ nRet = pDocShell->GetLockCount();
+ pDocShell->SetLockCount(0);
+ }
+ return nRet;
+}
+
+void SAL_CALL ScModelObj::lockControllers() throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxBaseModel::lockControllers();
+ if (pDocShell)
+ pDocShell->LockPaint();
+}
+
+void SAL_CALL ScModelObj::unlockControllers() throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (hasControllersLocked())
+ {
+ SfxBaseModel::unlockControllers();
+ if (pDocShell)
+ pDocShell->UnlockPaint();
+ }
+}
+
+// XCalculate
+
+void SAL_CALL ScModelObj::calculate() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ pDocShell->DoRecalc(TRUE);
+ else
+ {
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ }
+}
+
+void SAL_CALL ScModelObj::calculateAll() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ pDocShell->DoHardRecalc(TRUE);
+ else
+ {
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ }
+}
+
+sal_Bool SAL_CALL ScModelObj::isAutomaticCalculationEnabled() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return pDocShell->GetDocument()->GetAutoCalc();
+
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ return FALSE;
+}
+
+void SAL_CALL ScModelObj::enableAutomaticCalculation( sal_Bool bEnabled )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( pDoc->GetAutoCalc() != bEnabled )
+ {
+ pDoc->SetAutoCalc( bEnabled );
+ pDocShell->SetDocumentModified();
+ }
+ }
+ else
+ {
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ }
+}
+
+// XProtectable
+
+void SAL_CALL ScModelObj::protect( const rtl::OUString& aPassword ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // #i108245# if already protected, don't change anything
+ if ( pDocShell && !pDocShell->GetDocument()->IsDocProtected() )
+ {
+ String aString(aPassword);
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.Protect( TABLEID_DOC, aString, TRUE );
+ }
+}
+
+void SAL_CALL ScModelObj::unprotect( const rtl::OUString& aPassword )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ String aString(aPassword);
+
+ ScDocFunc aFunc(*pDocShell);
+ BOOL bDone = aFunc.Unprotect( TABLEID_DOC, aString, TRUE );
+ if (!bDone)
+ throw lang::IllegalArgumentException();
+ }
+}
+
+sal_Bool SAL_CALL ScModelObj::isProtected() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return pDocShell->GetDocument()->IsDocProtected();
+
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ return FALSE;
+}
+
+// XDrawPagesSupplier
+
+uno::Reference<drawing::XDrawPages> SAL_CALL ScModelObj::getDrawPages() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScDrawPagesObj(pDocShell);
+
+ DBG_ERROR("keine DocShell"); //! Exception oder so?
+ return NULL;
+}
+
+#if 0
+// XPrintable
+
+rtl::OUString ScModelObj::getPrinterName(void) const
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ SfxPrinter* pPrinter = pDocShell->GetPrinter();
+ if (pPrinter)
+ return pPrinter->GetName();
+ }
+
+ DBG_ERROR("getPrinterName: keine DocShell oder kein Printer");
+ return rtl::OUString();
+}
+
+void ScModelObj::setPrinterName(const rtl::OUString& PrinterName)
+{
+ ScUnoGuard aGuard;
+ // Drucker setzen - wie in SfxViewShell::ExecPrint_Impl
+
+ if (pDocShell)
+ {
+ SfxPrinter* pPrinter = pDocShell->GetPrinter();
+ if (pPrinter)
+ {
+ String aString(PrinterName);
+ SfxPrinter* pNewPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aString );
+ if (pNewPrinter->IsKnown())
+ pDocShell->SetPrinter( pNewPrinter, SFX_PRINTER_PRINTER );
+ else
+ delete pNewPrinter;
+ }
+ }
+}
+
+XPropertySetRef ScModelObj::createPrintOptions(void)
+{
+ ScUnoGuard aGuard;
+ return new ScPrintSettingsObj; //! ScPrintSettingsObj implementieren!
+}
+
+void ScModelObj::print(const XPropertySetRef& xOptions)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ //! xOptions auswerten (wie denn?)
+
+ //! muss noch
+ }
+}
+#endif
+
+// XGoalSeek
+
+sheet::GoalResult SAL_CALL ScModelObj::seekGoal(
+ const table::CellAddress& aFormulaPosition,
+ const table::CellAddress& aVariablePosition,
+ const ::rtl::OUString& aGoalValue )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sheet::GoalResult aResult;
+ aResult.Divergence = DBL_MAX; // nichts gefunden
+ if (pDocShell)
+ {
+ WaitObject aWait( pDocShell->GetActiveDialogParent() );
+ String aGoalString(aGoalValue);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ double fValue = 0.0;
+ BOOL bFound = pDoc->Solver(
+ (SCCOL)aFormulaPosition.Column, (SCROW)aFormulaPosition.Row, aFormulaPosition.Sheet,
+ (SCCOL)aVariablePosition.Column, (SCROW)aVariablePosition.Row, aVariablePosition.Sheet,
+ aGoalString, fValue );
+ aResult.Result = fValue;
+ if (bFound)
+ aResult.Divergence = 0.0; //! das ist gelogen
+ }
+ return aResult;
+}
+
+// XConsolidatable
+
+uno::Reference<sheet::XConsolidationDescriptor> SAL_CALL ScModelObj::createConsolidationDescriptor(
+ sal_Bool bEmpty ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScConsolidationDescriptor* pNew = new ScConsolidationDescriptor;
+ if ( pDocShell && !bEmpty )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ const ScConsolidateParam* pParam = pDoc->GetConsolidateDlgData();
+ if (pParam)
+ pNew->SetParam( *pParam );
+ }
+ return pNew;
+}
+
+void SAL_CALL ScModelObj::consolidate(
+ const uno::Reference<sheet::XConsolidationDescriptor>& xDescriptor )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // das koennte theoretisch ein fremdes Objekt sein, also nur das
+ // oeffentliche XConsolidationDescriptor Interface benutzen, um
+ // die Daten in ein ScConsolidationDescriptor Objekt zu kopieren:
+ //! wenn es schon ein ScConsolidationDescriptor ist, direkt per getImplementation?
+
+ ScConsolidationDescriptor aImpl;
+ aImpl.setFunction( xDescriptor->getFunction() );
+ aImpl.setSources( xDescriptor->getSources() );
+ aImpl.setStartOutputPosition( xDescriptor->getStartOutputPosition() );
+ aImpl.setUseColumnHeaders( xDescriptor->getUseColumnHeaders() );
+ aImpl.setUseRowHeaders( xDescriptor->getUseRowHeaders() );
+ aImpl.setInsertLinks( xDescriptor->getInsertLinks() );
+
+ if (pDocShell)
+ {
+ const ScConsolidateParam& rParam = aImpl.GetParam();
+ pDocShell->DoConsolidate( rParam, TRUE );
+ pDocShell->GetDocument()->SetConsolidateDlgData( &rParam );
+ }
+}
+
+// XDocumentAuditing
+
+void SAL_CALL ScModelObj::refreshArrows() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.DetectiveRefresh();
+ }
+}
+
+// XViewDataSupplier
+uno::Reference< container::XIndexAccess > SAL_CALL ScModelObj::getViewData( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
+
+ if( !xRet.is() )
+ {
+ ScUnoGuard aGuard;
+ if (pDocShell && pDocShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED)
+ {
+ xRet.set(uno::Reference < container::XIndexAccess >::query(::comphelper::getProcessServiceFactory()->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.IndexedPropertyValues")))));
+
+ uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
+ DBG_ASSERT( xCont.is(), "ScModelObj::getViewData() failed for OLE object" );
+ if( xCont.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aSeq;
+ aSeq.realloc(1);
+ String sName;
+ pDocShell->GetDocument()->GetName( pDocShell->GetDocument()->GetVisibleTab(), sName );
+ rtl::OUString sOUName(sName);
+ aSeq[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
+ aSeq[0].Value <<= sOUName;
+ xCont->insertByIndex( 0, uno::makeAny( aSeq ) );
+ }
+ }
+ }
+
+ return xRet;
+}
+
+// XPropertySet (Doc-Optionen)
+//! auch an der Applikation anbieten?
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScModelObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScModelObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ const ScDocOptions& rOldOpt = pDoc->GetDocOptions();
+ ScDocOptions aNewOpt = rOldOpt;
+
+ BOOL bOpt = ScDocOptionsHelper::setPropertyValue( aNewOpt, *aPropSet.getPropertyMap(), aPropertyName, aValue );
+ if (bOpt)
+ {
+ // done...
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
+ {
+ lang::Locale aLocale;
+ if ( aValue >>= aLocale )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ eLatin = ScUnoConversion::GetLanguage(aLocale);
+ pDoc->SetLanguage( eLatin, eCjk, eCtl );
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
+ {
+ rtl::OUString sCodeName;
+ if ( aValue >>= sCodeName )
+ pDoc->SetCodeName( sCodeName );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
+ {
+ lang::Locale aLocale;
+ if ( aValue >>= aLocale )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ eCjk = ScUnoConversion::GetLanguage(aLocale);
+ pDoc->SetLanguage( eLatin, eCjk, eCtl );
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
+ {
+ lang::Locale aLocale;
+ if ( aValue >>= aLocale )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ eCtl = ScUnoConversion::GetLanguage(aLocale);
+ pDoc->SetLanguage( eLatin, eCjk, eCtl );
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
+ {
+ // model is created if not there
+ ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
+ pModel->SetOpenInDesignMode( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+
+ SfxBindings* pBindings = pDocShell->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_FM_OPEN_READONLY );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
+ {
+ // model is created if not there
+ ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
+ pModel->SetAutoControlFocus( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+
+ SfxBindings* pBindings = pDocShell->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_FM_AUTOCONTROLFOCUS );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
+ {
+ pDocShell->SetEmpty( !ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
+ {
+ BOOL bUndoEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ pDoc->EnableUndo( bUndoEnabled );
+ USHORT nCount = ( bUndoEnabled ?
+ static_cast< USHORT >( SvtUndoOptions().GetUndoCount() ) : 0 );
+ pDocShell->GetUndoManager()->SetMaxUndoActionCount( nCount );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
+ {
+ bool bOldAdjustHeightEnabled = pDoc->IsAdjustHeightEnabled();
+ bool bAdjustHeightEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if( bOldAdjustHeightEnabled != bAdjustHeightEnabled )
+ {
+ pDoc->EnableAdjustHeight( bAdjustHeightEnabled );
+ if( bAdjustHeightEnabled )
+ pDocShell->UpdateAllRowHeights();
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
+ {
+ pDoc->EnableExecuteLink( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
+ {
+ pDoc->EnableChangeReadOnly( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ }
+ else if ( aString.EqualsAscii( "BuildId" ) )
+ {
+ aValue >>= maBuildId;
+ }
+ else if ( aString.EqualsAscii( "SavedObject" ) ) // set from chart after saving
+ {
+ rtl::OUString aObjName;
+ aValue >>= aObjName;
+ if ( aObjName.getLength() )
+ pDoc->RestoreChartListener( aObjName );
+ }
+
+ if ( aNewOpt != rOldOpt )
+ {
+ pDoc->SetDocOptions( aNewOpt );
+ // Don't recalculate while loading XML, when the formula text is stored.
+ // Recalculation after loading is handled separately.
+ //! Recalc only for options that need it?
+ if ( !pDoc->IsImportingXML() )
+ pDocShell->DoHardRecalc( TRUE );
+ pDocShell->SetDocumentModified();
+ }
+ }
+}
+
+uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+ uno::Any aRet;
+
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ const ScDocOptions& rOpt = pDoc->GetDocOptions();
+ aRet = ScDocOptionsHelper::getPropertyValue( rOpt, *aPropSet.getPropertyMap(), aPropertyName );
+ if ( aRet.hasValue() )
+ {
+ // done...
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+
+ lang::Locale aLocale;
+ ScUnoConversion::FillLocale( aLocale, eLatin );
+ aRet <<= aLocale;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
+ {
+ rtl::OUString sCodeName = pDoc->GetCodeName();
+ aRet <<= sCodeName;
+ }
+
+ else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+
+ lang::Locale aLocale;
+ ScUnoConversion::FillLocale( aLocale, eCjk );
+ aRet <<= aLocale;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+
+ lang::Locale aLocale;
+ ScUnoConversion::FillLocale( aLocale, eCtl );
+ aRet <<= aLocale;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES ) )
+ {
+ aRet <<= uno::Reference<sheet::XNamedRanges>(new ScNamedRangesObj( pDocShell ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_DATABASERNG ) )
+ {
+ aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_COLLABELRNG ) )
+ {
+ aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, TRUE ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ROWLABELRNG ) )
+ {
+ aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, FALSE ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_AREALINKS ) )
+ {
+ aRet <<= uno::Reference<sheet::XAreaLinks>(new ScAreaLinksObj( pDocShell ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_DDELINKS ) )
+ {
+ aRet <<= uno::Reference<container::XNameAccess>(new ScDDELinksObj( pDocShell ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_EXTERNALDOCLINKS ) )
+ {
+ aRet <<= uno::Reference<sheet::XExternalDocLinks>(new ScExternalDocLinksObj(pDocShell));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_SHEETLINKS ) )
+ {
+ aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
+ {
+ // default for no model is TRUE
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ sal_Bool bOpenInDesign = pModel ? pModel->GetOpenInDesignMode() : sal_True;
+ ScUnoHelpFunctions::SetBoolInAny( aRet, bOpenInDesign );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
+ {
+ // default for no model is FALSE
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ sal_Bool bAutoControlFocus = pModel ? pModel->GetAutoControlFocus() : sal_False;
+ ScUnoHelpFunctions::SetBoolInAny( aRet, bAutoControlFocus );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_FORBIDDEN ) )
+ {
+ aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
+ }
+ else if ( aString.EqualsAscii( SC_UNO_HASDRAWPAGES ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetDocument()->GetDrawLayer() != 0) );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_BASICLIBRARIES ) )
+ {
+ aRet <<= pDocShell->GetBasicContainer();
+ }
+ else if ( aString.EqualsAscii( SC_UNO_DIALOGLIBRARIES ) )
+ {
+ aRet <<= pDocShell->GetDialogContainer();
+ }
+ else if ( aString.EqualsAscii( SC_UNO_RUNTIMEUID ) )
+ {
+ aRet <<= getRuntimeUID();
+ }
+ else if ( aString.EqualsAscii( SC_UNO_HASVALIDSIGNATURES ) )
+ {
+ aRet <<= hasValidSignatures();
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, !pDocShell->IsEmpty() );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsUndoEnabled() );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsAdjustHeightEnabled() );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsExecuteLinkEnabled() );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsChangeReadOnlyEnabled() );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_REFERENCEDEVICE ) )
+ {
+ VCLXDevice* pXDev = new VCLXDevice();
+ pXDev->SetOutputDevice( pDoc->GetRefDevice() );
+ aRet <<= uno::Reference< awt::XDevice >( pXDev );
+ }
+ else if ( aString.EqualsAscii( "BuildId" ) )
+ {
+ aRet <<= maBuildId;
+ }
+ else if ( aString.EqualsAscii( "InternalDocument" ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) );
+ }
+ }
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScModelObj )
+
+// XMultiServiceFactory
+
+uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance(
+ const rtl::OUString& aServiceSpecifier )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<uno::XInterface> xRet;
+ String aNameStr(aServiceSpecifier);
+ USHORT nType = ScServiceProvider::GetProviderType(aNameStr);
+ if ( nType != SC_SERVICE_INVALID )
+ {
+ // drawing layer tables must be kept as long as the model is alive
+ // return stored instance if already set
+ switch ( nType )
+ {
+ case SC_SERVICE_GRADTAB: xRet.set(xDrawGradTab); break;
+ case SC_SERVICE_HATCHTAB: xRet.set(xDrawHatchTab); break;
+ case SC_SERVICE_BITMAPTAB: xRet.set(xDrawBitmapTab); break;
+ case SC_SERVICE_TRGRADTAB: xRet.set(xDrawTrGradTab); break;
+ case SC_SERVICE_MARKERTAB: xRet.set(xDrawMarkerTab); break;
+ case SC_SERVICE_DASHTAB: xRet.set(xDrawDashTab); break;
+ case SC_SERVICE_CHDATAPROV: xRet.set(xChartDataProv); break;
+ }
+
+ // #i64497# If a chart is in a temporary document during clipoard paste,
+ // there should be no data provider, so that own data is used
+ bool bCreate =
+ ! ( nType == SC_SERVICE_CHDATAPROV &&
+ ( pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL ));
+ // this should never happen, i.e. the temporary document should never be
+ // loaded, becuase this unlinks the data
+ OSL_ASSERT( bCreate );
+
+ if ( !xRet.is() && bCreate )
+ {
+ xRet.set(ScServiceProvider::MakeInstance( nType, pDocShell ));
+
+ // store created instance
+ switch ( nType )
+ {
+ case SC_SERVICE_GRADTAB: xDrawGradTab.set(xRet); break;
+ case SC_SERVICE_HATCHTAB: xDrawHatchTab.set(xRet); break;
+ case SC_SERVICE_BITMAPTAB: xDrawBitmapTab.set(xRet); break;
+ case SC_SERVICE_TRGRADTAB: xDrawTrGradTab.set(xRet); break;
+ case SC_SERVICE_MARKERTAB: xDrawMarkerTab.set(xRet); break;
+ case SC_SERVICE_DASHTAB: xDrawDashTab.set(xRet); break;
+ case SC_SERVICE_CHDATAPROV: xChartDataProv.set(xRet); break;
+ }
+ }
+ }
+ else
+ {
+ // alles was ich nicht kenn, werf ich der SvxFmMSFactory an den Hals,
+ // da wird dann 'ne Exception geworfen, wenn's nicht passt...
+
+ try
+ {
+ xRet.set(SvxFmMSFactory::createInstance(aServiceSpecifier));
+ // extra block to force deletion of the temporary before ScShapeObj ctor (setDelegator)
+ }
+ catch ( lang::ServiceNotRegisteredException & )
+ {
+ }
+
+ // #96117# if the drawing factory created a shape, a ScShapeObj has to be used
+ // to support own properties like ImageMap:
+
+ uno::Reference<drawing::XShape> xShape( xRet, uno::UNO_QUERY );
+ if ( xShape.is() )
+ {
+ xRet.clear(); // for aggregation, xShape must be the object's only ref
+ new ScShapeObj( xShape ); // aggregates object and modifies xShape
+ xRet.set(xShape);
+ }
+ }
+ return xRet;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstanceWithArguments(
+ const rtl::OUString& ServiceSpecifier,
+ const uno::Sequence<uno::Any>& aArgs )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ //! unterscheiden zwischen eigenen Services und denen vom Drawing-Layer?
+
+ ScUnoGuard aGuard;
+ uno::Reference<uno::XInterface> xInt(createInstance(ServiceSpecifier));
+
+ if ( aArgs.getLength() )
+ {
+ // used only for cell value binding so far - it can be initialized after creating
+
+ uno::Reference<lang::XInitialization> xInit( xInt, uno::UNO_QUERY );
+ if ( xInit.is() )
+ xInit->initialize( aArgs );
+ }
+
+ return xInt;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getAvailableServiceNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! warum sind die Parameter bei concatServiceNames nicht const ???
+ //! return concatServiceNames( ScServiceProvider::GetAllServiceNames(),
+ //! SvxFmMSFactory::getAvailableServiceNames() );
+
+ uno::Sequence<rtl::OUString> aMyServices(ScServiceProvider::GetAllServiceNames());
+ uno::Sequence<rtl::OUString> aDrawServices(SvxFmMSFactory::getAvailableServiceNames());
+
+ return concatServiceNames( aMyServices, aDrawServices );
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScModelObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScModelObj" );
+}
+
+sal_Bool SAL_CALL ScModelObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr(rServiceName);
+ return aServiceStr.EqualsAscii( SCMODELOBJ_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCDOC_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCMODELOBJ_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
+ return aRet;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScModelObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
+ }
+
+ // aggregated number formats supplier has XUnoTunnel, too
+ // interface from aggregated object must be obtained via queryAggregation
+
+ sal_Int64 nRet = SfxBaseModel::getSomething( rId );
+ if ( nRet )
+ return nRet;
+
+ if ( GetFormatter().is() )
+ {
+ const uno::Type& rTunnelType = ::getCppuType((uno::Reference<lang::XUnoTunnel>*) 0);
+ uno::Any aNumTunnel(xNumberAgg->queryAggregation(rTunnelType));
+ if(aNumTunnel.getValueType() == rTunnelType)
+ {
+ uno::Reference<lang::XUnoTunnel> xTunnelAgg(
+ *(uno::Reference<lang::XUnoTunnel>*)aNumTunnel.getValue());
+ return xTunnelAgg->getSomething( rId );
+ }
+ }
+
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScModelObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScModelObj* ScModelObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScModelObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScModelObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+// XChangesNotifier
+
+void ScModelObj::addChangesListener( const uno::Reference< util::XChangesListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ maChangesListeners.addInterface( aListener );
+}
+
+void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ maChangesListeners.removeInterface( aListener );
+}
+
+bool ScModelObj::HasChangesListeners() const
+{
+ if ( maChangesListeners.getLength() > 0 )
+ return true;
+
+ // "change" event set in any sheet?
+ return pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript(SC_SHEETEVENT_CHANGE);
+}
+
+void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges,
+ const uno::Sequence< beans::PropertyValue >& rProperties )
+{
+ if ( pDocShell && HasChangesListeners() )
+ {
+ util::ChangesEvent aEvent;
+ aEvent.Source.set( static_cast< cppu::OWeakObject* >( this ) );
+ aEvent.Base <<= aEvent.Source;
+
+ ULONG nRangeCount = rRanges.Count();
+ aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) );
+ for ( ULONG nIndex = 0; nIndex < nRangeCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRangeObj;
+
+ ScRange aRange( *rRanges.GetObject( nIndex ) );
+ if ( aRange.aStart == aRange.aEnd )
+ {
+ xRangeObj.set( new ScCellObj( pDocShell, aRange.aStart ) );
+ }
+ else
+ {
+ xRangeObj.set( new ScCellRangeObj( pDocShell, aRange ) );
+ }
+
+ util::ElementChange& rChange = aEvent.Changes[ static_cast< sal_Int32 >( nIndex ) ];
+ rChange.Accessor <<= rOperation;
+ rChange.Element <<= rProperties;
+ rChange.ReplacedElement <<= xRangeObj;
+ }
+
+ ::cppu::OInterfaceIteratorHelper aIter( maChangesListeners );
+ while ( aIter.hasMoreElements() )
+ {
+ try
+ {
+ static_cast< util::XChangesListener* >( aIter.next() )->changesOccurred( aEvent );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ // handle sheet events
+ //! separate method with ScMarkData? Then change HasChangesListeners back.
+ if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell )
+ {
+ ScMarkData aMarkData;
+ aMarkData.MarkFromRangeList( rRanges, FALSE );
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
+ if (aMarkData.GetTableSelect(nTab))
+ {
+ const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE);
+ if (pScript)
+ {
+ ScRangeList aTabRanges; // collect ranges on this sheet
+ ULONG nRangeCount = rRanges.Count();
+ for ( ULONG nIndex = 0; nIndex < nRangeCount; ++nIndex )
+ {
+ ScRange aRange( *rRanges.GetObject( nIndex ) );
+ if ( aRange.aStart.Tab() == nTab )
+ aTabRanges.Append( aRange );
+ }
+ ULONG nTabRangeCount = aTabRanges.Count();
+ if ( nTabRangeCount > 0 )
+ {
+ uno::Reference<uno::XInterface> xTarget;
+ if ( nTabRangeCount == 1 )
+ {
+ ScRange aRange( *aTabRanges.GetObject( 0 ) );
+ if ( aRange.aStart == aRange.aEnd )
+ xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) );
+ else
+ xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) );
+ }
+ else
+ xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) );
+
+ uno::Sequence<uno::Any> aParams(1);
+ aParams[0] <<= xTarget;
+
+ uno::Any aRet;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+
+ /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScModelObj::HandleCalculateEvents()
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ // don't call events before the document is visible
+ // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading)
+ if ( pDoc->IsDocVisible() )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
+ {
+ if (pDoc->HasCalcNotification(nTab))
+ {
+ if (const ScSheetEvents* pEvents = pDoc->GetSheetEvents( nTab ))
+ {
+ if (const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE))
+ {
+ uno::Any aRet;
+ uno::Sequence<uno::Any> aParams;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+ }
+ }
+
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= nTab;
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_CALCULATE ), aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ pDoc->ResetCalcNotifications();
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScDrawPagesObj::ScDrawPagesObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDrawPagesObj::~ScDrawPagesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDrawPagesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(INT32 nIndex) const
+{
+ if (pDocShell)
+ {
+ ScDrawLayer* pDrawLayer = pDocShell->MakeDrawLayer();
+ DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
+ if ( pDrawLayer && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
+ {
+ SdrPage* pPage = pDrawLayer->GetPage((USHORT)nIndex);
+ DBG_ASSERT(pPage,"Draw-Page nicht gefunden");
+ if (pPage)
+ {
+ return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
+ }
+ }
+ }
+ return NULL;
+}
+
+// XDrawPages
+
+uno::Reference<drawing::XDrawPage> SAL_CALL ScDrawPagesObj::insertNewByIndex( sal_Int32 nPos )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<drawing::XDrawPage> xRet;
+ if (pDocShell)
+ {
+ String aNewName;
+ pDocShell->GetDocument()->CreateValidTabName(aNewName);
+ ScDocFunc aFunc(*pDocShell);
+ if ( aFunc.InsertTable( (SCTAB)nPos, aNewName, TRUE, TRUE ) )
+ xRet.set(GetObjectByIndex_Impl( nPos ));
+ }
+ return xRet;
+}
+
+void SAL_CALL ScDrawPagesObj::remove( const uno::Reference<drawing::XDrawPage>& xPage )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SvxDrawPage* pImp = SvxDrawPage::getImplementation( xPage );
+ if ( pDocShell && pImp )
+ {
+ SdrPage* pPage = pImp->GetSdrPage();
+ if (pPage)
+ {
+ SCTAB nPageNum = static_cast<SCTAB>(pPage->GetPageNum());
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.DeleteTable( nPageNum, TRUE, TRUE );
+ }
+ }
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDrawPagesObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return pDocShell->GetDocument()->GetTableCount();
+ return 0;
+}
+
+uno::Any SAL_CALL ScDrawPagesObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<drawing::XDrawPage> xPage(GetObjectByIndex_Impl(nIndex));
+ if (xPage.is())
+ return uno::makeAny(xPage);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScDrawPagesObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<drawing::XDrawPage>*)0);
+}
+
+sal_Bool SAL_CALL ScDrawPagesObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+//------------------------------------------------------------------------
+
+ScTableSheetsObj::ScTableSheetsObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScTableSheetsObj::~ScTableSheetsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScTableSheetsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XSpreadsheets
+
+ScTableSheetObj* ScTableSheetsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
+{
+ if ( pDocShell && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
+ return new ScTableSheetObj( pDocShell, static_cast<SCTAB>(nIndex) );
+
+ return NULL;
+}
+
+ScTableSheetObj* ScTableSheetsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
+{
+ if (pDocShell)
+ {
+ SCTAB nIndex;
+ String aString(aName);
+ if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
+ return new ScTableSheetObj( pDocShell, nIndex );
+ }
+ return NULL;
+}
+
+void SAL_CALL ScTableSheetsObj::insertNewByName( const rtl::OUString& aName, sal_Int16 nPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ String aNamStr(aName);
+ ScDocFunc aFunc(*pDocShell);
+ bDone = aFunc.InsertTable( nPosition, aNamStr, TRUE, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScTableSheetsObj::moveByName( const rtl::OUString& aName, sal_Int16 nDestination )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ String aNamStr(aName);
+ SCTAB nSource;
+ if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
+ bDone = pDocShell->MoveTable( nSource, nDestination, FALSE, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScTableSheetsObj::copyByName( const rtl::OUString& aName,
+ const rtl::OUString& aCopy, sal_Int16 nDestination )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ String aNamStr(aName);
+ String aNewStr(aCopy);
+ SCTAB nSource;
+ if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
+ {
+ bDone = pDocShell->MoveTable( nSource, nDestination, TRUE, TRUE );
+ if (bDone)
+ {
+ // #i92477# any index past the last sheet means "append" in MoveTable
+ SCTAB nResultTab = static_cast<SCTAB>(nDestination);
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount(); // count after copying
+ if (nResultTab >= nTabCount)
+ nResultTab = nTabCount - 1;
+
+ ScDocFunc aFunc(*pDocShell);
+ bDone = aFunc.RenameTable( nResultTab, aNewStr, TRUE, TRUE );
+ }
+ }
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScTableSheetsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::ElementExistException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ BOOL bIllArg = FALSE;
+
+ //! Type of aElement can be some specific interface instead of XInterface
+
+ if ( pDocShell )
+ {
+ uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
+ if ( xInterface.is() )
+ {
+ ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
+ if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ String aNamStr(aName);
+ SCTAB nDummy;
+ if ( pDoc->GetTable( aNamStr, nDummy ) )
+ {
+ // name already exists
+ throw container::ElementExistException();
+ }
+ else
+ {
+ SCTAB nPosition = pDoc->GetTableCount();
+ ScDocFunc aFunc(*pDocShell);
+ bDone = aFunc.InsertTable( nPosition, aNamStr, TRUE, TRUE );
+ if (bDone)
+ pSheetObj->InitInsertSheet( pDocShell, nPosition );
+ // Dokument und neuen Range am Objekt setzen
+ }
+ }
+ else
+ bIllArg = TRUE;
+ }
+ else
+ bIllArg = TRUE;
+ }
+
+ if (!bDone)
+ {
+ if (bIllArg)
+ throw lang::IllegalArgumentException();
+ else
+ throw uno::RuntimeException(); // ElementExistException is handled above
+ }
+}
+
+void SAL_CALL ScTableSheetsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ BOOL bIllArg = FALSE;
+
+ //! Type of aElement can be some specific interface instead of XInterface
+
+ if ( pDocShell )
+ {
+ uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
+ if ( xInterface.is() )
+ {
+ ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
+ if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
+ {
+ String aNamStr(aName);
+ SCTAB nPosition;
+ if ( pDocShell->GetDocument()->GetTable( aNamStr, nPosition ) )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ if ( aFunc.DeleteTable( nPosition, TRUE, TRUE ) )
+ {
+ // InsertTable kann jetzt eigentlich nicht schiefgehen...
+ bDone = aFunc.InsertTable( nPosition, aNamStr, TRUE, TRUE );
+ if (bDone)
+ pSheetObj->InitInsertSheet( pDocShell, nPosition );
+ }
+ }
+ else
+ {
+ // not found
+ throw container::NoSuchElementException();
+ }
+ }
+ else
+ bIllArg = TRUE;
+ }
+ else
+ bIllArg = TRUE;
+ }
+
+ if (!bDone)
+ {
+ if (bIllArg)
+ throw lang::IllegalArgumentException();
+ else
+ throw uno::RuntimeException(); // NoSuchElementException is handled above
+ }
+}
+
+void SAL_CALL ScTableSheetsObj::removeByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ SCTAB nIndex;
+ String aString(aName);
+ if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ bDone = aFunc.DeleteTable( nIndex, TRUE, TRUE );
+ }
+ else
+ {
+ // not found
+ throw container::NoSuchElementException();
+ }
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException(); // NoSuchElementException is handled above
+}
+
+// XCellRangesAccess
+
+uno::Reference< table::XCell > SAL_CALL ScTableSheetsObj::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow, sal_Int32 nSheet )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((USHORT)nSheet)));
+ if (! xSheet.is())
+ throw lang::IndexOutOfBoundsException();
+
+ return xSheet->getCellByPosition(nColumn, nRow);
+}
+
+uno::Reference< table::XCellRange > SAL_CALL ScTableSheetsObj::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom, sal_Int32 nSheet )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((USHORT)nSheet)));
+ if (! xSheet.is())
+ throw lang::IndexOutOfBoundsException();
+
+ return xSheet->getCellRangeByPosition(nLeft, nTop, nRight, nBottom);
+}
+
+uno::Sequence < uno::Reference< table::XCellRange > > SAL_CALL ScTableSheetsObj::getCellRangesByName( const rtl::OUString& aRange )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence < uno::Reference < table::XCellRange > > xRet;
+
+ ScRangeList aRangeList;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (ScRangeStringConverter::GetRangeListFromString( aRangeList, aRange, pDoc, ::formula::FormulaGrammar::CONV_OOO, ';' ))
+ {
+ sal_Int32 nCount = aRangeList.Count();
+ if (nCount)
+ {
+ xRet.realloc(nCount);
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ const ScRange* pRange = aRangeList.GetObject( nIndex );
+ if( pRange )
+ xRet[nIndex] = new ScCellRangeObj(pDocShell, *pRange);
+ }
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ else
+ throw lang::IllegalArgumentException();
+ return xRet;
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScTableSheetsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScTableSheetsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return pDocShell->GetDocument()->GetTableCount();
+ return 0;
+}
+
+uno::Any SAL_CALL ScTableSheetsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByIndex_Impl(nIndex));
+ if (xSheet.is())
+ return uno::makeAny(xSheet);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScTableSheetsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XSpreadsheet>*)0);
+}
+
+sal_Bool SAL_CALL ScTableSheetsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XNameAccess
+
+uno::Any SAL_CALL ScTableSheetsObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByName_Impl(aName));
+ if (xSheet.is())
+ return uno::makeAny(xSheet);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetsObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nCount = pDoc->GetTableCount();
+ String aName;
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pDoc->GetName( i, aName );
+ pAry[i] = aName;
+ }
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>();
+}
+
+sal_Bool SAL_CALL ScTableSheetsObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ SCTAB nIndex;
+ if ( pDocShell->GetDocument()->GetTable( String(aName), nIndex ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------
+
+ScTableColumnsObj::ScTableColumnsObj(ScDocShell* pDocSh, SCTAB nT, SCCOL nSC, SCCOL nEC) :
+ pDocShell( pDocSh ),
+ nTab ( nT ),
+ nStartCol( nSC ),
+ nEndCol ( nEC )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScTableColumnsObj::~ScTableColumnsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScTableColumnsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Referenz-Update fuer Tab und Start/Ende
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XTableColumns
+
+ScTableColumnObj* ScTableColumnsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
+{
+ SCCOL nCol = static_cast<SCCOL>(nIndex) + nStartCol;
+ if ( pDocShell && nCol <= nEndCol )
+ return new ScTableColumnObj( pDocShell, nCol, nTab );
+
+ return NULL; // falscher Index
+}
+
+ScTableColumnObj* ScTableColumnsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
+{
+ SCCOL nCol = 0;
+ String aString(aName);
+ if ( ::AlphaToCol( nCol, aString) )
+ if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
+ return new ScTableColumnObj( pDocShell, nCol, nTab );
+
+ return NULL;
+}
+
+void SAL_CALL ScTableColumnsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartCol+nPosition <= nEndCol &&
+ nStartCol+nPosition+nCount-1 <= MAXCOL )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ ScRange aRange( (SCCOL)(nStartCol+nPosition), 0, nTab,
+ (SCCOL)(nStartCol+nPosition+nCount-1), MAXROW, nTab );
+ bDone = aFunc.InsertCells( aRange, NULL, INS_INSCOLS, TRUE, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScTableColumnsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ // Der zu loeschende Bereich muss innerhalb des Objekts liegen
+ if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartCol+nIndex+nCount-1 <= nEndCol )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ ScRange aRange( (SCCOL)(nStartCol+nIndex), 0, nTab,
+ (SCCOL)(nStartCol+nIndex+nCount-1), MAXROW, nTab );
+ bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELCOLS, TRUE, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScTableColumnsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableColumnsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScTableColumnsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return nEndCol - nStartCol + 1;
+}
+
+uno::Any SAL_CALL ScTableColumnsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XCellRange> xColumn(GetObjectByIndex_Impl(nIndex));
+ if (xColumn.is())
+ return uno::makeAny(xColumn);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScTableColumnsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<table::XCellRange>*)0);
+}
+
+sal_Bool SAL_CALL ScTableColumnsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Any SAL_CALL ScTableColumnsObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XCellRange> xColumn(GetObjectByName_Impl(aName));
+ if (xColumn.is())
+ return uno::makeAny(xColumn);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScTableColumnsObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SCCOL nCount = nEndCol - nStartCol + 1;
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ for (SCCOL i=0; i<nCount; i++)
+ pAry[i] = ::ScColToAlpha( nStartCol + i );
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScTableColumnsObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SCCOL nCol = 0;
+ String aString(aName);
+ if ( ::AlphaToCol( nCol, aString) )
+ if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
+ return TRUE;
+
+ return FALSE; // nicht gefunden
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnsObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( lcl_GetColumnsPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScTableColumnsObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScDocFunc aFunc(*pDocShell);
+ SCCOLROW nColArr[2];
+ nColArr[0] = nStartCol;
+ nColArr[1] = nEndCol;
+ String aNameString(aPropertyName);
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
+ {
+ sal_Int32 nNewWidth = 0;
+ if ( aValue >>= nNewWidth )
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
+ (USHORT)HMMToTwips(nNewWidth), TRUE, TRUE );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
+ {
+ BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab, eMode, 0, TRUE, TRUE );
+ // SC_SIZE_DIRECT with size 0: hide
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
+ {
+ BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bOpt)
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab,
+ SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, TRUE, TRUE );
+ // FALSE for columns currently has no effect
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
+ {
+ //! single function to set/remove all breaks?
+ BOOL bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
+ if (bSet)
+ aFunc.InsertPageBreak( TRUE, ScAddress(nCol,0,nTab), TRUE, TRUE, TRUE );
+ else
+ aFunc.RemovePageBreak( TRUE, ScAddress(nCol,0,nTab), TRUE, TRUE, TRUE );
+ }
+}
+
+uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ String aNameString(aPropertyName);
+ uno::Any aAny;
+
+ //! loop over all columns for current state?
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
+ {
+ // for hidden column, return original height
+ USHORT nWidth = pDoc->GetOriginalWidth( nStartCol, nTab );
+ aAny <<= (sal_Int32)TwipsToHMM(nWidth);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
+ {
+ SCCOL nLastCol;
+ bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
+ {
+ BOOL bOpt = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_MANUALSIZE);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
+ {
+ ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
+ {
+ ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
+ }
+
+ return aAny;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableColumnsObj )
+
+//------------------------------------------------------------------------
+
+ScTableRowsObj::ScTableRowsObj(ScDocShell* pDocSh, SCTAB nT, SCROW nSR, SCROW nER) :
+ pDocShell( pDocSh ),
+ nTab ( nT ),
+ nStartRow( nSR ),
+ nEndRow ( nER )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScTableRowsObj::~ScTableRowsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScTableRowsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Referenz-Update fuer Tab und Start/Ende
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XTableRows
+
+ScTableRowObj* ScTableRowsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
+{
+ SCROW nRow = static_cast<SCROW>(nIndex) + nStartRow;
+ if ( pDocShell && nRow <= nEndRow )
+ return new ScTableRowObj( pDocShell, nRow, nTab );
+
+ return NULL; // falscher Index
+}
+
+void SAL_CALL ScTableRowsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartRow+nPosition <= nEndRow &&
+ nStartRow+nPosition+nCount-1 <= MAXROW )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ ScRange aRange( 0, (SCROW)(nStartRow+nPosition), nTab,
+ MAXCOL, (SCROW)(nStartRow+nPosition+nCount-1), nTab );
+ bDone = aFunc.InsertCells( aRange, NULL, INS_INSROWS, TRUE, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScTableRowsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ // Der zu loeschende Bereich muss innerhalb des Objekts liegen
+ if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartRow+nIndex+nCount-1 <= nEndRow )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ ScRange aRange( 0, (SCROW)(nStartRow+nIndex), nTab,
+ MAXCOL, (SCROW)(nStartRow+nIndex+nCount-1), nTab );
+ bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELROWS, TRUE, TRUE );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScTableRowsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableRowsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScTableRowsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return nEndRow - nStartRow + 1;
+}
+
+uno::Any SAL_CALL ScTableRowsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<table::XCellRange> xRow(GetObjectByIndex_Impl(nIndex));
+ if (xRow.is())
+ return uno::makeAny(xRow);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScTableRowsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<table::XCellRange>*)0);
+}
+
+sal_Bool SAL_CALL ScTableRowsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowsObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( lcl_GetRowsPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScTableRowsObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScDocFunc aFunc(*pDocShell);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCCOLROW nRowArr[2];
+ nRowArr[0] = nStartRow;
+ nRowArr[1] = nEndRow;
+ String aNameString(aPropertyName);
+
+ 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.
+
+ // TODO: It's probably cleaner to use a different property name
+ // for this.
+ pDoc->SetRowHeightOnly( 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 )
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
+ (USHORT)HMMToTwips(nNewHeight), TRUE, TRUE );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
+ {
+ BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE );
+ // SC_SIZE_DIRECT with size 0: hide
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
+ {
+ //! undo etc.
+ if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+ pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true);
+ else
+ pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
+ {
+ //! single function to set/remove all breaks?
+ BOOL bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
+ if (bSet)
+ aFunc.InsertPageBreak( FALSE, ScAddress(0,nRow,nTab), TRUE, TRUE, TRUE );
+ else
+ aFunc.RemovePageBreak( FALSE, ScAddress(0,nRow,nTab), TRUE, TRUE, TRUE );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
+ {
+ // #i57867# Background color is specified for row styles in the file format,
+ // so it has to be supported along with the row properties (import only).
+
+ // Use ScCellRangeObj to set the property for all cells in the rows
+ // (this means, the "row attribute" must be set before individual cell attributes).
+
+ ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
+ uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
+ xRangeObj->setPropertyValue( aPropertyName, aValue );
+ }
+}
+
+uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pDocShell)
+ throw uno::RuntimeException();
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ String aNameString(aPropertyName);
+ uno::Any aAny;
+
+ //! loop over all rows for current state?
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
+ {
+ // for hidden row, return original height
+ USHORT nHeight = pDoc->GetOriginalHeight( nStartRow, nTab );
+ aAny <<= (sal_Int32)TwipsToHMM(nHeight);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
+ {
+ SCROW nLastRow;
+ bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
+ {
+ bool bVis = pDoc->RowFiltered(nStartRow, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
+ {
+ BOOL bOpt = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_MANUALSIZE);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
+ {
+ ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
+ {
+ ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
+ ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
+ {
+ // Use ScCellRangeObj to get the property from the cell range
+ // (for completeness only, this is not used by the XML filter).
+
+ ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
+ uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
+ aAny = xRangeObj->getPropertyValue( aPropertyName );
+ }
+
+ return aAny;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableRowsObj )
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 ScSpreadsheetSettingsObj::ScSpreadsheetSettingsObj(ScDocShell* pDocSh) :
+//UNUSED2008-05 pDocShell( pDocSh )
+//UNUSED2008-05 {
+//UNUSED2008-05 pDocShell->GetDocument()->AddUnoObject(*this);
+//UNUSED2008-05 }
+
+ScSpreadsheetSettingsObj::~ScSpreadsheetSettingsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScSpreadsheetSettingsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettingsObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ //! muss noch
+ return NULL;
+}
+
+void SAL_CALL ScSpreadsheetSettingsObj::setPropertyValue(
+ const rtl::OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ //! muss noch
+}
+
+uno::Any SAL_CALL ScSpreadsheetSettingsObj::getPropertyValue( const rtl::OUString& /* aPropertyName */ )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ //! muss noch
+ return uno::Any();
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettingsObj )
+
+//------------------------------------------------------------------------
+
+ScAnnotationsObj::ScAnnotationsObj(ScDocShell* pDocSh, SCTAB nT) :
+ pDocShell( pDocSh ),
+ nTab( nT )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScAnnotationsObj::~ScAnnotationsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScAnnotationsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! nTab bei Referenz-Update anpassen!!!
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos ) const
+{
+ if (pDocShell)
+ {
+ sal_Int32 nFound = 0;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
+ for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
+ {
+ if (pCell->HasNote())
+ {
+ if (nFound == nIndex)
+ {
+ rPos = ScAddress( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
+ return true;
+ }
+ ++nFound;
+ }
+ }
+ }
+ return false;
+}
+
+ScAnnotationObj* ScAnnotationsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
+{
+ if (pDocShell)
+ {
+ ScAddress aPos;
+ if ( GetAddressByIndex_Impl( nIndex, aPos ) )
+ return new ScAnnotationObj( pDocShell, aPos );
+ }
+ return NULL;
+}
+
+// XSheetAnnotations
+
+void SAL_CALL ScAnnotationsObj::insertNew(
+ const table::CellAddress& aPosition, const ::rtl::OUString& rText )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ DBG_ASSERT( aPosition.Sheet == nTab, "addAnnotation mit falschem Sheet" );
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
+
+ ScDocFunc aFunc( *pDocShell );
+ aFunc.ReplaceNote( aPos, rText, 0, 0, TRUE );
+ }
+}
+
+void SAL_CALL ScAnnotationsObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScAddress aPos;
+ if ( GetAddressByIndex_Impl( nIndex, aPos ) )
+ {
+ ScMarkData aMarkData;
+ aMarkData.SelectTable( aPos.Tab(), TRUE );
+ aMarkData.SetMultiMarkArea( ScRange(aPos) );
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.DeleteContents( aMarkData, IDF_NOTE, TRUE, TRUE );
+ }
+ }
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScAnnotationsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ //! iterate directly (more efficiently)?
+
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAnnotationsEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScAnnotationsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ULONG nCount = 0;
+ if (pDocShell)
+ {
+ ScCellIterator aCellIter( pDocShell->GetDocument(), 0,0, nTab, MAXCOL,MAXROW, nTab );
+ for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
+ if (pCell->HasNote())
+ ++nCount;
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL ScAnnotationsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XSheetAnnotation> xAnnotation(GetObjectByIndex_Impl(nIndex));
+ if (xAnnotation.is())
+ return uno::makeAny(xAnnotation);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScAnnotationsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XSheetAnnotation>*)0);
+}
+
+sal_Bool SAL_CALL ScAnnotationsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+//------------------------------------------------------------------------
+
+ScScenariosObj::ScScenariosObj(ScDocShell* pDocSh, SCTAB nT) :
+ pDocShell( pDocSh ),
+ nTab ( nT )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScScenariosObj::~ScScenariosObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScScenariosObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Referenz-Update fuer Tab und Start/Ende
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XScenarios
+
+BOOL ScScenariosObj::GetScenarioIndex_Impl( const rtl::OUString& rName, SCTAB& rIndex )
+{
+ //! Case-insensitiv ????
+
+ if ( pDocShell )
+ {
+ String aString(rName);
+
+ String aTabName;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nCount = (SCTAB)getCount();
+ for (SCTAB i=0; i<nCount; i++)
+ if (pDoc->GetName( nTab+i+1, aTabName ))
+ if ( aTabName == aString )
+ {
+ rIndex = i;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+ScTableSheetObj* ScScenariosObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
+{
+ USHORT nCount = (USHORT)getCount();
+ if ( pDocShell && nIndex >= 0 && nIndex < nCount )
+ return new ScTableSheetObj( pDocShell, nTab+static_cast<SCTAB>(nIndex)+1 );
+
+ return NULL; // kein Dokument oder falscher Index
+}
+
+ScTableSheetObj* ScScenariosObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ SCTAB nIndex;
+ if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
+ return new ScTableSheetObj( pDocShell, nTab+nIndex+1 );
+
+ return NULL; // nicht gefunden
+}
+
+void SAL_CALL ScScenariosObj::addNewByName( const rtl::OUString& aName,
+ const uno::Sequence<table::CellRangeAddress>& aRanges,
+ const rtl::OUString& aComment )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ ScMarkData aMarkData;
+ aMarkData.SelectTable( nTab, TRUE );
+
+ USHORT nRangeCount = (USHORT)aRanges.getLength();
+ if (nRangeCount)
+ {
+ const table::CellRangeAddress* pAry = aRanges.getConstArray();
+ for (USHORT i=0; i<nRangeCount; i++)
+ {
+ DBG_ASSERT( pAry[i].Sheet == nTab, "addScenario mit falscher Tab" );
+ ScRange aRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
+ (SCCOL)pAry[i].EndColumn, (SCROW)pAry[i].EndRow, nTab );
+
+ aMarkData.SetMultiMarkArea( aRange );
+ }
+ }
+
+ String aNameStr(aName);
+ String aCommStr(aComment);
+
+ Color aColor( COL_LIGHTGRAY ); // Default
+ USHORT nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY | SC_SCENARIO_PROTECT;
+
+ pDocShell->MakeScenario( nTab, aNameStr, aCommStr, aColor, nFlags, aMarkData );
+ }
+}
+
+void SAL_CALL ScScenariosObj::removeByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SCTAB nIndex;
+ if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.DeleteTable( nTab+nIndex+1, TRUE, TRUE );
+ }
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScScenariosObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.ScenariosEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScScenariosObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SCTAB nCount = 0;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (!pDoc->IsScenario(nTab))
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nNext = nTab + 1;
+ while (nNext < nTabCount && pDoc->IsScenario(nNext))
+ {
+ ++nCount;
+ ++nNext;
+ }
+ }
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL ScScenariosObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XScenario> xScen(GetObjectByIndex_Impl(nIndex));
+ if (xScen.is())
+ return uno::makeAny(xScen);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScScenariosObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XScenario>*)0);
+}
+
+sal_Bool SAL_CALL ScScenariosObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Any SAL_CALL ScScenariosObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XScenario> xScen(GetObjectByName_Impl(aName));
+ if (xScen.is())
+ return uno::makeAny(xScen);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScScenariosObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SCTAB nCount = (SCTAB)getCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+
+ if ( pDocShell ) // sonst ist auch Count = 0
+ {
+ String aTabName;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ rtl::OUString* pAry = aSeq.getArray();
+ for (SCTAB i=0; i<nCount; i++)
+ if (pDoc->GetName( nTab+i+1, aTabName ))
+ pAry[i] = aTabName;
+ }
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScScenariosObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SCTAB nIndex;
+ return GetScenarioIndex_Impl( aName, nIndex );
+}
+
+
+
+
+
diff --git a/sc/source/ui/unoobj/drdefuno.cxx b/sc/source/ui/unoobj/drdefuno.cxx
new file mode 100644
index 000000000000..52fce55dfc58
--- /dev/null
+++ b/sc/source/ui/unoobj/drdefuno.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "drdefuno.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+ScDrawDefaultsObj::ScDrawDefaultsObj(ScDocShell* pDocSh) :
+ SvxUnoDrawPool( NULL ),
+ pDocShell( pDocSh )
+{
+ // SvxUnoDrawPool is initialized without model,
+ // draw layer is created on demand in getModelPool
+
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDrawDefaultsObj::~ScDrawDefaultsObj() throw ()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDrawDefaultsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // document gone
+ }
+}
+
+SfxItemPool* ScDrawDefaultsObj::getModelPool( sal_Bool bReadOnly ) throw()
+{
+ SfxItemPool* pRet = NULL;
+ if ( pDocShell )
+ {
+ ScDrawLayer* pModel = bReadOnly ?
+ pDocShell->GetDocument()->GetDrawLayer() :
+ pDocShell->MakeDrawLayer();
+ if ( pModel )
+ pRet = &pModel->GetItemPool();
+ }
+ if ( !pRet )
+ pRet = SvxUnoDrawPool::getModelPool( bReadOnly ); // uses default pool
+
+ return pRet;
+}
+
+
diff --git a/sc/source/ui/unoobj/editsrc.cxx b/sc/source/ui/unoobj/editsrc.cxx
new file mode 100644
index 000000000000..7febe374d0d9
--- /dev/null
+++ b/sc/source/ui/unoobj/editsrc.cxx
@@ -0,0 +1,373 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "editsrc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/unofored.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/outliner.hxx>
+#include "textuno.hxx"
+#include "editutil.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "hints.hxx"
+#include "patattr.hxx"
+#include "unoguard.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "postit.hxx"
+#include "AccessibleText.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScHeaderFooterChangedHint, SfxHint );
+
+ScHeaderFooterChangedHint::ScHeaderFooterChangedHint(USHORT nP) :
+ nPart( nP )
+{
+}
+
+ScHeaderFooterChangedHint::~ScHeaderFooterChangedHint()
+{
+}
+
+//------------------------------------------------------------------------
+
+ScSharedHeaderFooterEditSource::ScSharedHeaderFooterEditSource( ScHeaderFooterTextData* pData ) :
+ pTextData( pData )
+{
+ // pTextData is held by the ScHeaderFooterTextObj.
+ // Text range and cursor keep a reference to their parent text, so the text object is
+ // always alive and the TextData is valid as long as there are children.
+}
+
+ScSharedHeaderFooterEditSource::~ScSharedHeaderFooterEditSource()
+{
+}
+
+SvxEditSource* ScSharedHeaderFooterEditSource::Clone() const
+{
+ return new ScSharedHeaderFooterEditSource( pTextData );
+}
+
+SvxTextForwarder* ScSharedHeaderFooterEditSource::GetTextForwarder()
+{
+ return pTextData->GetTextForwarder();
+}
+
+void ScSharedHeaderFooterEditSource::UpdateData()
+{
+ pTextData->UpdateData();
+}
+
+ScEditEngineDefaulter* ScSharedHeaderFooterEditSource::GetEditEngine()
+{
+ return pTextData->GetEditEngine();
+}
+
+//------------------------------------------------------------------------
+
+// each ScHeaderFooterEditSource object has its own ScHeaderFooterTextData
+
+ScHeaderFooterEditSource::ScHeaderFooterEditSource( ScHeaderFooterContentObj* pContent,
+ USHORT nP ) :
+ ScSharedHeaderFooterEditSource( new ScHeaderFooterTextData( *pContent, nP ) )
+{
+}
+
+ScHeaderFooterEditSource::ScHeaderFooterEditSource( ScHeaderFooterContentObj& rContent,
+ USHORT nP ) :
+ ScSharedHeaderFooterEditSource( new ScHeaderFooterTextData( rContent, nP ) )
+{
+}
+
+ScHeaderFooterEditSource::~ScHeaderFooterEditSource()
+{
+ delete GetTextData(); // not accessed in ScSharedHeaderFooterEditSource dtor
+}
+
+SvxEditSource* ScHeaderFooterEditSource::Clone() const
+{
+ const ScHeaderFooterTextData* pData = GetTextData();
+ return new ScHeaderFooterEditSource( pData->GetContentObj(), pData->GetPart() );
+}
+
+//------------------------------------------------------------------------
+
+ScSharedCellEditSource::ScSharedCellEditSource( ScCellTextData* pData ) :
+ pCellTextData( pData )
+{
+ // pCellTextData is part of the ScCellTextObj.
+ // Text range and cursor keep a reference to their parent text, so the text object is
+ // always alive and the CellTextData is valid as long as there are children.
+}
+
+ScSharedCellEditSource::~ScSharedCellEditSource()
+{
+}
+
+SvxEditSource* ScSharedCellEditSource::Clone() const
+{
+ return new ScSharedCellEditSource( pCellTextData );
+}
+
+SvxTextForwarder* ScSharedCellEditSource::GetTextForwarder()
+{
+ return pCellTextData->GetTextForwarder();
+}
+
+void ScSharedCellEditSource::UpdateData()
+{
+ pCellTextData->UpdateData();
+}
+
+void ScSharedCellEditSource::SetDoUpdateData(sal_Bool bValue)
+{
+ pCellTextData->SetDoUpdate(bValue);
+}
+
+sal_Bool ScSharedCellEditSource::IsDirty() const
+{
+ return pCellTextData->IsDirty();
+}
+
+ScEditEngineDefaulter* ScSharedCellEditSource::GetEditEngine()
+{
+ return pCellTextData->GetEditEngine();
+}
+
+//------------------------------------------------------------------------
+
+// each ScCellEditSource object has its own ScCellTextData
+
+ScCellEditSource::ScCellEditSource( ScDocShell* pDocSh, const ScAddress& rP ) :
+ ScSharedCellEditSource( new ScCellTextData( pDocSh, rP ) )
+{
+}
+
+ScCellEditSource::~ScCellEditSource()
+{
+ delete GetCellTextData(); // not accessed in ScSharedCellEditSource dtor
+}
+
+SvxEditSource* ScCellEditSource::Clone() const
+{
+ const ScCellTextData* pData = GetCellTextData();
+ return new ScCellEditSource( pData->GetDocShell(), pData->GetCellPos() );
+}
+
+//------------------------------------------------------------------------
+
+ScAnnotationEditSource::ScAnnotationEditSource(ScDocShell* pDocSh, const ScAddress& rP) :
+ pDocShell( pDocSh ),
+ aCellPos( rP ),
+ pEditEngine( NULL ),
+ pForwarder( NULL ),
+ bDataValid( FALSE )
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScAnnotationEditSource::~ScAnnotationEditSource()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+
+ delete pForwarder;
+ delete pEditEngine;
+}
+
+SvxEditSource* ScAnnotationEditSource::Clone() const
+{
+ return new ScAnnotationEditSource( pDocShell, aCellPos );
+}
+
+SdrObject* ScAnnotationEditSource::GetCaptionObj()
+{
+ ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos );
+ return pNote ? pNote->GetOrCreateCaption( aCellPos ) : 0;
+}
+
+SvxTextForwarder* ScAnnotationEditSource::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ // Notizen haben keine Felder
+ if ( pDocShell )
+ {
+ pEditEngine = new ScNoteEditEngine( pDocShell->GetDocument()->GetNoteEngine() );
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ pEditEngine = new ScEditEngineDefaulter( pEnginePool, TRUE );
+ }
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ if ( pDocShell )
+ if ( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos ) )
+ if ( const EditTextObject* pEditObj = pNote->GetEditTextObject() )
+ pEditEngine->SetText( *pEditObj ); // incl. Umbrueche
+
+ bDataValid = TRUE;
+ return pForwarder;
+}
+
+void ScAnnotationEditSource::UpdateData()
+{
+ if ( pDocShell && pEditEngine )
+ {
+ ScDocShellModificator aModificator( *pDocShell );
+
+ if( SdrObject* pObj = GetCaptionObj() )
+ {
+ EditTextObject* pEditObj = pEditEngine->CreateTextObject();
+ OutlinerParaObject* pOPO = new OutlinerParaObject( *pEditObj );
+ delete pEditObj;
+ pOPO->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
+ pObj->NbcSetOutlinerParaObject( pOPO );
+ pObj->ActionChanged();
+ }
+
+ //! Undo !!!
+
+ aModificator.SetDocumentModified();
+
+ // bDataValid wird bei SetDocumentModified zurueckgesetzt
+ }
+}
+
+void ScAnnotationEditSource::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+
+ DELETEZ( pForwarder );
+ DELETEZ( pEditEngine ); // EditEngine uses document's pool
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ bDataValid = FALSE; // Text muss neu geholt werden
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScSimpleEditSource::ScSimpleEditSource( SvxTextForwarder* pForw ) :
+ pForwarder( pForw )
+{
+ // The same forwarder (and EditEngine) is shared by all children of the same Text object.
+ // Text range and cursor keep a reference to their parent text, so the text object is
+ // always alive and the forwarder is valid as long as there are children.
+}
+
+ScSimpleEditSource::~ScSimpleEditSource()
+{
+}
+
+SvxEditSource* ScSimpleEditSource::Clone() const
+{
+ return new ScSimpleEditSource( pForwarder );
+}
+
+SvxTextForwarder* ScSimpleEditSource::GetTextForwarder()
+{
+ return pForwarder;
+}
+
+void ScSimpleEditSource::UpdateData()
+{
+ // nothing
+}
+
+//------------------------------------------------------------------------
+
+ScAccessibilityEditSource::ScAccessibilityEditSource( ::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData )
+ : mpAccessibleTextData(pAccessibleCellTextData)
+{
+}
+
+ScAccessibilityEditSource::~ScAccessibilityEditSource()
+{
+}
+
+SvxEditSource* ScAccessibilityEditSource::Clone() const
+{
+ return new ScAccessibilityEditSource(::std::auto_ptr < ScAccessibleTextData > (mpAccessibleTextData->Clone()));
+}
+
+SvxTextForwarder* ScAccessibilityEditSource::GetTextForwarder()
+{
+ return mpAccessibleTextData->GetTextForwarder();
+}
+
+SvxViewForwarder* ScAccessibilityEditSource::GetViewForwarder()
+{
+ return mpAccessibleTextData->GetViewForwarder();
+}
+
+SvxEditViewForwarder* ScAccessibilityEditSource::GetEditViewForwarder( sal_Bool bCreate )
+{
+ return mpAccessibleTextData->GetEditViewForwarder(bCreate);
+}
+
+void ScAccessibilityEditSource::UpdateData()
+{
+ mpAccessibleTextData->UpdateData();
+}
+
+SfxBroadcaster& ScAccessibilityEditSource::GetBroadcaster() const
+{
+ return mpAccessibleTextData->GetBroadcaster();
+}
+
diff --git a/sc/source/ui/unoobj/eventuno.cxx b/sc/source/ui/unoobj/eventuno.cxx
new file mode 100755
index 000000000000..d7de00f4cc56
--- /dev/null
+++ b/sc/source/ui/unoobj/eventuno.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * 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: tokenuno.cxx,v $
+ * $Revision: 1.6.108.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "eventuno.hxx"
+#include "miscuno.hxx"
+#include "unoguard.hxx"
+#include "docsh.hxx"
+#include "sheetevents.hxx"
+#include "unonames.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScSheetEventsObj, "ScSheetEventsObj", "com.sun.star.document.Events" )
+
+//------------------------------------------------------------------------
+
+ScSheetEventsObj::ScSheetEventsObj(ScDocShell* pDocSh, SCTAB nT) :
+ mpDocShell( pDocSh ),
+ mnTab( nT )
+{
+ mpDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScSheetEventsObj::~ScSheetEventsObj()
+{
+ if (mpDocShell)
+ mpDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScSheetEventsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! reference update
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ mpDocShell = NULL;
+ }
+}
+
+sal_Int32 lcl_GetEventFromName( const rtl::OUString& aName )
+{
+ for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent)
+ if ( aName == ScSheetEvents::GetEventName(nEvent) )
+ return nEvent;
+
+ return -1; // not found
+}
+
+// XNameReplace
+
+void SAL_CALL ScSheetEventsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!mpDocShell)
+ throw uno::RuntimeException();
+
+ sal_Int32 nEvent = lcl_GetEventFromName(aName);
+ if (nEvent < 0)
+ throw container::NoSuchElementException();
+
+ ScSheetEvents aNewEvents;
+ const ScSheetEvents* pOldEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab);
+ if (pOldEvents)
+ aNewEvents = *pOldEvents;
+
+ rtl::OUString aScript;
+ if ( aElement.hasValue() ) // empty Any -> reset event
+ {
+ uno::Sequence<beans::PropertyValue> aPropSeq;
+ if ( aElement >>= aPropSeq )
+ {
+ sal_Int32 nPropCount = aPropSeq.getLength();
+ for (sal_Int32 nPos=0; nPos<nPropCount; ++nPos)
+ {
+ const beans::PropertyValue& rProp = aPropSeq[nPos];
+ if ( rProp.Name.compareToAscii( SC_UNO_EVENTTYPE ) == 0 )
+ {
+ rtl::OUString aEventType;
+ if ( rProp.Value >>= aEventType )
+ {
+ // only "Script" is supported
+ if ( aEventType.compareToAscii( SC_UNO_SCRIPT ) != 0 )
+ throw lang::IllegalArgumentException();
+ }
+ }
+ else if ( rProp.Name.compareToAscii( SC_UNO_SCRIPT ) == 0 )
+ rProp.Value >>= aScript;
+ }
+ }
+ }
+ if (aScript.getLength())
+ aNewEvents.SetScript( nEvent, &aScript );
+ else
+ aNewEvents.SetScript( nEvent, NULL ); // reset
+
+ mpDocShell->GetDocument()->SetSheetEvents( mnTab, &aNewEvents );
+ mpDocShell->SetDocumentModified();
+}
+
+// XNameAccess
+
+uno::Any SAL_CALL ScSheetEventsObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Int32 nEvent = lcl_GetEventFromName(aName);
+ if (nEvent < 0)
+ throw container::NoSuchElementException();
+
+ const rtl::OUString* pScript = NULL;
+ if (mpDocShell)
+ {
+ const ScSheetEvents* pEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab);
+ if (pEvents)
+ pScript = pEvents->GetScript(nEvent);
+ }
+
+ uno::Any aRet;
+ if (pScript)
+ {
+ uno::Sequence<beans::PropertyValue> aPropSeq( 2 );
+ aPropSeq[0] = beans::PropertyValue(
+ rtl::OUString::createFromAscii("EventType"), -1,
+ uno::makeAny( rtl::OUString::createFromAscii("Script") ), beans::PropertyState_DIRECT_VALUE );
+ aPropSeq[1] = beans::PropertyValue(
+ rtl::OUString::createFromAscii("Script"), -1,
+ uno::makeAny( *pScript ), beans::PropertyState_DIRECT_VALUE );
+ aRet <<= aPropSeq;
+ }
+ // empty Any if nothing was set
+ return aRet;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScSheetEventsObj::getElementNames() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence<rtl::OUString> aNames(SC_SHEETEVENT_COUNT);
+ for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent)
+ aNames[nEvent] = ScSheetEvents::GetEventName(nEvent);
+ return aNames;
+}
+
+sal_Bool SAL_CALL ScSheetEventsObj::hasByName( const ::rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Int32 nEvent = lcl_GetEventFromName(aName);
+ return (nEvent >= 0);
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScSheetEventsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Sequence<beans::PropertyValue>*)0);
+}
+
+sal_Bool SAL_CALL ScSheetEventsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (mpDocShell)
+ return sal_True;
+ return sal_False;
+}
+
+
+
diff --git a/sc/source/ui/unoobj/fielduno.cxx b/sc/source/ui/unoobj/fielduno.cxx
new file mode 100644
index 000000000000..8e3e39d07ef4
--- /dev/null
+++ b/sc/source/ui/unoobj/fielduno.cxx
@@ -0,0 +1,1549 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svl/smplhint.hxx>
+
+
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/flditem.hxx>
+#include <rtl/uuid.h>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/FilenameDisplayFormat.hpp>
+
+#include "fielduno.hxx"
+#include "textuno.hxx"
+#include "miscuno.hxx"
+#include "docsh.hxx"
+#include "hints.hxx"
+#include "editsrc.hxx"
+#include "cellsuno.hxx"
+#include "servuno.hxx" // fuer IDs
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "editutil.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+// alles ohne Which-ID, Map nur fuer PropertySetInfo
+
+const SfxItemPropertySet* lcl_GetURLPropertySet()
+{
+ static SfxItemPropertyMapEntry aURLPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE), 0, &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0, &getCppuType((uno::Sequence<text::TextContentAnchorType>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_REPR), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_TARGET), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0, &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_URL), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aURLPropertySet_Impl( aURLPropertyMap_Impl );
+ return &aURLPropertySet_Impl;
+}
+
+const SfxItemPropertySet* lcl_GetHeaderFieldPropertySet()
+{
+ static SfxItemPropertyMapEntry aHeaderFieldPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE), 0, &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0, &getCppuType((uno::Sequence<text::TextContentAnchorType>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0, &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aHeaderFieldPropertySet_Impl( aHeaderFieldPropertyMap_Impl );
+ return &aHeaderFieldPropertySet_Impl;
+}
+
+const SfxItemPropertySet* lcl_GetFileFieldPropertySet()
+{
+ static SfxItemPropertyMapEntry aFileFieldPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE), 0, &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0, &getCppuType((uno::Sequence<text::TextContentAnchorType>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_FILEFORM), 0, &getCppuType((sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0, &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aFileFieldPropertySet_Impl( aFileFieldPropertyMap_Impl );
+ return &aFileFieldPropertySet_Impl;
+}
+
+//------------------------------------------------------------------------
+
+#define SCTEXTFIELD_SERVICE "com.sun.star.text.TextField"
+#define SCTEXTCONTENT_SERVICE "com.sun.star.text.TextContent"
+
+SC_SIMPLE_SERVICE_INFO( ScCellFieldsObj, "ScCellFieldsObj", "com.sun.star.text.TextFields" )
+SC_SIMPLE_SERVICE_INFO( ScHeaderFieldsObj, "ScHeaderFieldsObj", "com.sun.star.text.TextFields" )
+
+//------------------------------------------------------------------------
+
+// ScUnoEditEngine nur um aus einer EditEngine die Felder herauszubekommen...
+
+enum ScUnoCollectMode
+{
+ SC_UNO_COLLECT_NONE,
+ SC_UNO_COLLECT_COUNT,
+ SC_UNO_COLLECT_FINDINDEX,
+ SC_UNO_COLLECT_FINDPOS
+};
+
+class ScUnoEditEngine : public ScEditEngineDefaulter
+{
+ ScUnoCollectMode eMode;
+ USHORT nFieldCount;
+ TypeId aFieldType;
+ SvxFieldData* pFound; // lokale Kopie
+ USHORT nFieldPar;
+ xub_StrLen nFieldPos;
+ USHORT nFieldIndex;
+
+public:
+ ScUnoEditEngine(ScEditEngineDefaulter* pSource);
+ ~ScUnoEditEngine();
+
+ //! nPos should be xub_StrLen
+ virtual String CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos,
+ Color*& rTxtColor, Color*& rFldColor );
+
+ USHORT CountFields(TypeId aType);
+ SvxFieldData* FindByIndex(USHORT nIndex, TypeId aType);
+ SvxFieldData* FindByPos(USHORT nPar, xub_StrLen nPos, TypeId aType);
+
+ USHORT GetFieldPar() const { return nFieldPar; }
+ xub_StrLen GetFieldPos() const { return nFieldPos; }
+};
+
+ScUnoEditEngine::ScUnoEditEngine(ScEditEngineDefaulter* pSource) :
+ ScEditEngineDefaulter( *pSource ),
+ eMode( SC_UNO_COLLECT_NONE ),
+ nFieldCount( 0 ),
+ aFieldType( NULL ),
+ pFound( NULL )
+{
+ if (pSource)
+ {
+ EditTextObject* pData = pSource->CreateTextObject();
+ SetText( *pData );
+ delete pData;
+ }
+}
+
+ScUnoEditEngine::~ScUnoEditEngine()
+{
+ delete pFound;
+}
+
+String ScUnoEditEngine::CalcFieldValue( const SvxFieldItem& rField,
+ USHORT nPara, USHORT nPos, Color*& rTxtColor, Color*& rFldColor )
+{
+ String aRet(EditEngine::CalcFieldValue( rField, nPara, nPos, rTxtColor, rFldColor ));
+ if (eMode != SC_UNO_COLLECT_NONE)
+ {
+ const SvxFieldData* pFieldData = rField.GetField();
+ if ( pFieldData )
+ {
+ if ( !aFieldType || pFieldData->Type() == aFieldType )
+ {
+ if ( eMode == SC_UNO_COLLECT_FINDINDEX && !pFound && nFieldCount == nFieldIndex )
+ {
+ pFound = pFieldData->Clone();
+ nFieldPar = nPara;
+ nFieldPos = nPos;
+ }
+ if ( eMode == SC_UNO_COLLECT_FINDPOS && !pFound &&
+ nPara == nFieldPar && nPos == nFieldPos )
+ {
+ pFound = pFieldData->Clone();
+ nFieldIndex = nFieldCount;
+ }
+ ++nFieldCount;
+ }
+ }
+ }
+ return aRet;
+}
+
+USHORT ScUnoEditEngine::CountFields(TypeId aType)
+{
+ eMode = SC_UNO_COLLECT_COUNT;
+ aFieldType = aType;
+ nFieldCount = 0;
+ UpdateFields();
+ aFieldType = NULL;
+ eMode = SC_UNO_COLLECT_NONE;
+
+ return nFieldCount;
+}
+
+SvxFieldData* ScUnoEditEngine::FindByIndex(USHORT nIndex, TypeId aType)
+{
+ eMode = SC_UNO_COLLECT_FINDINDEX;
+ nFieldIndex = nIndex;
+ aFieldType = aType;
+ nFieldCount = 0;
+ UpdateFields();
+ aFieldType = NULL;
+ eMode = SC_UNO_COLLECT_NONE;
+
+ return pFound;
+}
+
+SvxFieldData* ScUnoEditEngine::FindByPos(USHORT nPar, xub_StrLen nPos, TypeId aType)
+{
+ eMode = SC_UNO_COLLECT_FINDPOS;
+ nFieldPar = nPar;
+ nFieldPos = nPos;
+ aFieldType = aType;
+ nFieldCount = 0;
+ UpdateFields();
+ aFieldType = NULL;
+ eMode = SC_UNO_COLLECT_NONE;
+
+ return pFound;
+}
+
+//------------------------------------------------------------------------
+
+ScCellFieldsObj::ScCellFieldsObj(ScDocShell* pDocSh, const ScAddress& rPos) :
+ pDocShell( pDocSh ),
+ aCellPos( rPos ),
+ mpRefreshListeners( NULL )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ pEditSource = new ScCellEditSource( pDocShell, aCellPos );
+}
+
+ScCellFieldsObj::~ScCellFieldsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+
+ delete pEditSource;
+
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+
+ if (mpRefreshListeners)
+ {
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ if (mpRefreshListeners)
+ {
+ mpRefreshListeners->disposeAndClear(aEvent);
+ DELETEZ( mpRefreshListeners );
+ }
+ }
+}
+
+void ScCellFieldsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+
+ // EditSource hat sich selber als Listener angemeldet
+}
+
+// XIndexAccess (via XTextFields)
+
+ScCellFieldObj* ScCellFieldsObj::GetObjectByIndex_Impl(INT32 Index) const
+{
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ if ( aTempEngine.FindByIndex( (USHORT)Index, NULL ) ) // in der Zelle ist der Typ egal
+ {
+ USHORT nPar = aTempEngine.GetFieldPar();
+ xub_StrLen nPos = aTempEngine.GetFieldPos();
+ ESelection aSelection( nPar, nPos, nPar, nPos+1 ); // Feld ist 1 Zeichen
+ return new ScCellFieldObj( pDocShell, aCellPos, aSelection );
+ }
+ return NULL;
+}
+
+sal_Int32 SAL_CALL ScCellFieldsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ return aTempEngine.CountFields(NULL); // Felder zaehlen, in Zelle ist der Typ egal
+}
+
+uno::Any SAL_CALL ScCellFieldsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<text::XTextField> xField(GetObjectByIndex_Impl(nIndex));
+ if (xField.is())
+ return uno::makeAny(xField);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScCellFieldsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<text::XTextField>*)0);
+}
+
+sal_Bool SAL_CALL ScCellFieldsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Reference<container::XEnumeration> SAL_CALL ScCellFieldsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFieldEnumeration")));
+}
+
+void SAL_CALL ScCellFieldsObj::addContainerListener(
+ const uno::Reference<container::XContainerListener>& /* xListener */ )
+ throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScCellFieldsObj::removeContainerListener(
+ const uno::Reference<container::XContainerListener>& /* xListener */ )
+ throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+// XRefreshable
+void SAL_CALL ScCellFieldsObj::refresh( )
+ throw (uno::RuntimeException)
+{
+ if (mpRefreshListeners)
+ {
+ // Call all listeners.
+ uno::Sequence< uno::Reference< uno::XInterface > > aListeners(mpRefreshListeners->getElements());
+ sal_uInt32 nLength(aListeners.getLength());
+ if (nLength)
+ {
+ const uno::Reference< uno::XInterface >* pInterfaces = aListeners.getConstArray();
+ if (pInterfaces)
+ {
+ lang::EventObject aEvent;
+ aEvent.Source.set(uno::Reference< util::XRefreshable >(const_cast<ScCellFieldsObj*>(this)));
+ sal_uInt32 i(0);
+ while (i < nLength)
+ {
+ try
+ {
+ while(i < nLength)
+ {
+ static_cast< util::XRefreshListener* >(pInterfaces->get())->refreshed(aEvent);
+ ++pInterfaces;
+ ++i;
+ }
+ }
+ catch(uno::RuntimeException&)
+ {
+// DBG_ERROR("a object is gone without to remove from Broadcaster");
+ ++pInterfaces;
+ ++i;
+ }
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL ScCellFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ if (!mpRefreshListeners)
+ mpRefreshListeners = new cppu::OInterfaceContainerHelper(aMutex);
+ mpRefreshListeners->addInterface(xListener);
+ }
+}
+
+void SAL_CALL ScCellFieldsObj::removeRefreshListener( const uno::Reference<util::XRefreshListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ if (mpRefreshListeners)
+ mpRefreshListeners->removeInterface(xListener);
+ }
+}
+
+//------------------------------------------------------------------------
+
+// Default-ctor wird fuer SMART_REFLECTION_IMPLEMENTATION gebraucht
+
+
+//UNUSED2008-05 ScCellFieldObj::ScCellFieldObj() :
+//UNUSED2008-05 OComponentHelper( getMutex() ),
+//UNUSED2008-05 aPropSet( lcl_GetURLPropertyMap() ),
+//UNUSED2008-05 pDocShell( NULL )
+//UNUSED2008-05 {
+//UNUSED2008-05 pEditSource = NULL;
+//UNUSED2008-05 }
+
+ScCellFieldObj::ScCellFieldObj(ScDocShell* pDocSh, const ScAddress& rPos,
+ const ESelection& rSel) :
+ OComponentHelper( getMutex() ),
+ pPropSet( lcl_GetURLPropertySet() ),
+ pDocShell( pDocSh ),
+ aCellPos( rPos ),
+ aSelection( rSel )
+{
+ // pDocShell ist Null, wenn per ServiceProvider erzeugt
+
+ if (pDocShell)
+ {
+ pDocShell->GetDocument()->AddUnoObject(*this);
+ pEditSource = new ScCellEditSource( pDocShell, aCellPos );
+ }
+ else
+ pEditSource = NULL;
+}
+
+uno::Any SAL_CALL ScCellFieldObj::queryAggregation( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( text::XTextField )
+ SC_QUERYINTERFACE( text::XTextContent ) // parent of XTextField
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( lang::XUnoTunnel )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+
+ return OComponentHelper::queryAggregation( rType ); // XComponent
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScCellFieldObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(OComponentHelper::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 4 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<text::XTextField>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScCellFieldObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+uno::Any SAL_CALL ScCellFieldObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ return OComponentHelper::queryInterface( rType );
+}
+
+void SAL_CALL ScCellFieldObj::acquire() throw()
+{
+ OComponentHelper::acquire();
+}
+
+void SAL_CALL ScCellFieldObj::release() throw()
+{
+ OComponentHelper::release();
+}
+
+void ScCellFieldObj::InitDoc( ScDocShell* pDocSh, const ScAddress& rPos,
+ const ESelection& rSel )
+{
+ if ( pDocSh && !pEditSource )
+ {
+ aCellPos = rPos;
+ aSelection = rSel;
+ pDocShell = pDocSh;
+
+ pDocShell->GetDocument()->AddUnoObject(*this);
+ pEditSource = new ScCellEditSource( pDocShell, aCellPos );
+ }
+}
+
+ScCellFieldObj::~ScCellFieldObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+
+ delete pEditSource;
+}
+
+void ScCellFieldObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! Updates fuer aSelection (muessen erst noch erzeugt werden) !!!!!!
+
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+
+ // EditSource hat sich selber als Listener angemeldet
+}
+
+// per getImplementation gerufen:
+
+SvxFieldItem ScCellFieldObj::CreateFieldItem()
+{
+ DBG_ASSERT( !pEditSource, "CreateFieldItem mit eingefuegtem Feld" );
+
+ SvxURLField aField;
+ aField.SetFormat(SVXURLFORMAT_APPDEFAULT);
+ aField.SetURL( aUrl );
+ aField.SetRepresentation( aRepresentation );
+ aField.SetTargetFrame( aTarget );
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+}
+
+void ScCellFieldObj::DeleteField()
+{
+ if (pEditSource)
+ {
+ SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
+// pEditEngine->QuickDelete( aSelection );
+ pForwarder->QuickInsertText( String(), aSelection );
+ pEditSource->UpdateData();
+
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aSelection.nStartPos;
+
+ //! Broadcast, um Selektion in anderen Objekten anzupassen
+ //! (auch bei anderen Aktionen)
+ }
+}
+
+// XTextField
+
+rtl::OUString SAL_CALL ScCellFieldObj::getPresentation( sal_Bool bShowCommand )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aRet;
+
+ if (pEditSource)
+ {
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ // Typ egal (in Zellen gibts nur URLs)
+ SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, 0 );
+ DBG_ASSERT(pField,"getPresentation: Feld nicht gefunden");
+ if (pField)
+ {
+ SvxURLField* pURL = (SvxURLField*)pField;
+ if (bShowCommand)
+ aRet = pURL->GetURL();
+ else
+ aRet = pURL->GetRepresentation();
+ }
+ }
+
+ return aRet;
+}
+
+// XTextContent
+
+void SAL_CALL ScCellFieldObj::attach( const uno::Reference<text::XTextRange>& xTextRange )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (xTextRange.is())
+ {
+ uno::Reference<text::XText> xText(xTextRange->getText());
+ if (xText.is())
+ {
+ xText->insertTextContent( xTextRange, this, TRUE );
+ }
+ }
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellFieldObj::getAnchor() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ return new ScCellObj( pDocShell, aCellPos );
+ return NULL;
+}
+
+// XComponent
+
+void SAL_CALL ScCellFieldObj::dispose() throw(uno::RuntimeException)
+{
+ OComponentHelper::dispose();
+}
+
+void SAL_CALL ScCellFieldObj::addEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::addEventListener( xListener );
+}
+
+void SAL_CALL ScCellFieldObj::removeEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::removeEventListener( xListener );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellFieldObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef = pPropSet->getPropertySetInfo();
+ return aRef;
+}
+
+void SAL_CALL ScCellFieldObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ rtl::OUString aStrVal;
+ if (pEditSource)
+ {
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ // Typ egal (in Zellen gibts nur URLs)
+ SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, 0 );
+ DBG_ASSERT(pField,"setPropertyValue: Feld nicht gefunden");
+ if (pField)
+ {
+ SvxURLField* pURL = (SvxURLField*)pField; // ist eine Kopie in der ScUnoEditEngine
+
+ BOOL bOk = TRUE;
+ if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
+ {
+ if (aValue >>= aStrVal)
+ pURL->SetURL( aStrVal );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
+ {
+ if (aValue >>= aStrVal)
+ pURL->SetRepresentation( aStrVal );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
+ {
+ if (aValue >>= aStrVal)
+ pURL->SetTargetFrame( aStrVal );
+ }
+ else
+ bOk = FALSE;
+
+ if (bOk)
+ {
+ pEditEngine->QuickInsertField( SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection );
+ pEditSource->UpdateData();
+ }
+ }
+ }
+ else // noch nicht eingefuegt
+ {
+ if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
+ {
+ if (aValue >>= aStrVal)
+ aUrl = String( aStrVal );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
+ {
+ if (aValue >>= aStrVal)
+ aRepresentation = String( aStrVal );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
+ {
+ if (aValue >>= aStrVal)
+ aTarget = String( aStrVal );
+ }
+ }
+}
+
+uno::Any SAL_CALL ScCellFieldObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aRet;
+ String aNameString(aPropertyName);
+
+ // anchor type is always "as character", text wrap always "none"
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPE ) )
+ aRet <<= text::TextContentAnchorType_AS_CHARACTER;
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPES ) )
+ {
+ uno::Sequence<text::TextContentAnchorType> aSeq(1);
+ aSeq[0] = text::TextContentAnchorType_AS_CHARACTER;
+ aRet <<= aSeq;
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_TEXTWRAP ) )
+ aRet <<= text::WrapTextMode_NONE;
+ else if (pEditSource)
+ {
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ // Typ egal (in Zellen gibts nur URLs)
+ SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, 0 );
+ DBG_ASSERT(pField,"getPropertyValue: Feld nicht gefunden");
+ if (pField)
+ {
+ SvxURLField* pURL = (SvxURLField*)pField;
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
+ aRet <<= rtl::OUString( pURL->GetURL() );
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
+ aRet <<= rtl::OUString( pURL->GetRepresentation() );
+ else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
+ aRet <<= rtl::OUString( pURL->GetTargetFrame() );
+ }
+ }
+ else // noch nicht eingefuegt
+ {
+ if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
+ aRet <<= rtl::OUString( aUrl );
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
+ aRet <<= rtl::OUString( aRepresentation );
+ else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
+ aRet <<= rtl::OUString( aTarget );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScCellFieldObj )
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScCellFieldObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScCellFieldObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScCellFieldObj* ScCellFieldObj::getImplementation(
+ const uno::Reference<text::XTextContent> xObj )
+{
+ ScCellFieldObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScCellFieldObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScCellFieldObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScCellFieldObj" );
+}
+
+sal_Bool SAL_CALL ScCellFieldObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCTEXTFIELD_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCTEXTCONTENT_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellFieldObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCTEXTFIELD_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCTEXTCONTENT_SERVICE );
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderFieldsObj::ScHeaderFieldsObj(ScHeaderFooterContentObj* pContent, USHORT nP, USHORT nT) :
+ pContentObj( pContent ),
+ nPart( nP ),
+ nType( nT ),
+ mpRefreshListeners( NULL )
+{
+ DBG_ASSERT( pContentObj, "ScHeaderFieldsObj ohne Objekt?" );
+
+ if (pContentObj)
+ {
+ pContentObj->acquire(); // darf nicht wegkommen
+ pEditSource = new ScHeaderFooterEditSource( pContentObj, nPart );
+ }
+ else
+ pEditSource = NULL;
+}
+
+ScHeaderFieldsObj::~ScHeaderFieldsObj()
+{
+ delete pEditSource;
+
+ if (pContentObj)
+ pContentObj->release();
+
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+
+ if (mpRefreshListeners)
+ {
+ lang::EventObject aEvent;
+ aEvent.Source = static_cast<cppu::OWeakObject*>(this);
+ if (mpRefreshListeners)
+ {
+ mpRefreshListeners->disposeAndClear(aEvent);
+ DELETEZ( mpRefreshListeners );
+ }
+ }
+}
+
+// XIndexAccess (via XTextFields)
+
+ScHeaderFieldObj* ScHeaderFieldsObj::GetObjectByIndex_Impl(INT32 Index) const
+{
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ TypeId aTypeId = NULL;
+ switch (nType)
+ {
+ case SC_SERVICE_PAGEFIELD: aTypeId = TYPE(SvxPageField); break;
+ case SC_SERVICE_PAGESFIELD: aTypeId = TYPE(SvxPagesField); break;
+ case SC_SERVICE_DATEFIELD: aTypeId = TYPE(SvxDateField); break;
+ case SC_SERVICE_TIMEFIELD: aTypeId = TYPE(SvxTimeField); break;
+ case SC_SERVICE_TITLEFIELD: aTypeId = TYPE(SvxFileField); break;
+ case SC_SERVICE_FILEFIELD: aTypeId = TYPE(SvxExtFileField); break;
+ case SC_SERVICE_SHEETFIELD: aTypeId = TYPE(SvxTableField); break;
+ // bei SC_SERVICE_INVALID bleibt TypeId Null
+ }
+ SvxFieldData* pData = aTempEngine.FindByIndex( (USHORT)Index, aTypeId );
+ if ( pData )
+ {
+ USHORT nPar = aTempEngine.GetFieldPar();
+ xub_StrLen nPos = aTempEngine.GetFieldPos();
+
+ USHORT nFieldType = nType;
+ if ( nFieldType == SC_SERVICE_INVALID )
+ {
+ if ( pData->ISA( SvxPageField ) ) nFieldType = SC_SERVICE_PAGEFIELD;
+ else if ( pData->ISA( SvxPagesField ) ) nFieldType = SC_SERVICE_PAGESFIELD;
+ else if ( pData->ISA( SvxDateField ) ) nFieldType = SC_SERVICE_DATEFIELD;
+ else if ( pData->ISA( SvxTimeField ) ) nFieldType = SC_SERVICE_TIMEFIELD;
+ else if ( pData->ISA( SvxFileField ) ) nFieldType = SC_SERVICE_TITLEFIELD;
+ else if ( pData->ISA( SvxExtFileField ) ) nFieldType = SC_SERVICE_FILEFIELD;
+ else if ( pData->ISA( SvxTableField ) ) nFieldType = SC_SERVICE_SHEETFIELD;
+ }
+
+ ESelection aSelection( nPar, nPos, nPar, nPos+1 ); // Field is 1 character
+ return new ScHeaderFieldObj( pContentObj, nPart, nFieldType, aSelection );
+ }
+ return NULL;
+}
+
+sal_Int32 SAL_CALL ScHeaderFieldsObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! Feld-Funktionen muessen an den Forwarder !!!
+ ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+
+ TypeId aTypeId = NULL;
+ switch (nType)
+ {
+ case SC_SERVICE_PAGEFIELD: aTypeId = TYPE(SvxPageField); break;
+ case SC_SERVICE_PAGESFIELD: aTypeId = TYPE(SvxPagesField); break;
+ case SC_SERVICE_DATEFIELD: aTypeId = TYPE(SvxDateField); break;
+ case SC_SERVICE_TIMEFIELD: aTypeId = TYPE(SvxTimeField); break;
+ case SC_SERVICE_TITLEFIELD: aTypeId = TYPE(SvxFileField); break;
+ case SC_SERVICE_FILEFIELD: aTypeId = TYPE(SvxExtFileField); break;
+ case SC_SERVICE_SHEETFIELD: aTypeId = TYPE(SvxTableField); break;
+ }
+ return aTempEngine.CountFields(aTypeId); // Felder zaehlen
+}
+
+uno::Any SAL_CALL ScHeaderFieldsObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<text::XTextField> xField(GetObjectByIndex_Impl(nIndex));
+ if (xField.is())
+ return uno::makeAny(xField);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScHeaderFieldsObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<text::XTextField>*)0);
+}
+
+sal_Bool SAL_CALL ScHeaderFieldsObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFieldsObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFieldEnumeration")));
+}
+
+void SAL_CALL ScHeaderFieldsObj::addContainerListener(
+ const uno::Reference<container::XContainerListener>& /* xListener */ )
+ throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+void SAL_CALL ScHeaderFieldsObj::removeContainerListener(
+ const uno::Reference<container::XContainerListener>& /* xListener */ )
+ throw(uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+// XRefreshable
+void SAL_CALL ScHeaderFieldsObj::refresh( )
+ throw (uno::RuntimeException)
+{
+ if (mpRefreshListeners)
+ {
+ // Call all listeners.
+ uno::Sequence< uno::Reference< uno::XInterface > > aListeners(mpRefreshListeners->getElements());
+ sal_uInt32 nLength(aListeners.getLength());
+ if (nLength)
+ {
+ const uno::Reference< uno::XInterface >* pInterfaces = aListeners.getConstArray();
+ if (pInterfaces)
+ {
+ lang::EventObject aEvent;
+ aEvent.Source.set(uno::Reference< util::XRefreshable >(const_cast<ScHeaderFieldsObj*>(this)));
+ sal_uInt32 i(0);
+ while (i < nLength)
+ {
+ try
+ {
+ while(i < nLength)
+ {
+ static_cast< util::XRefreshListener* >(pInterfaces->get())->refreshed(aEvent);
+ ++pInterfaces;
+ ++i;
+ }
+ }
+ catch(uno::RuntimeException&)
+ {
+// DBG_ERROR("a object is gone without to remove from Broadcaster");
+ ++pInterfaces;
+ ++i;
+ }
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL ScHeaderFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ if (!mpRefreshListeners)
+ mpRefreshListeners = new cppu::OInterfaceContainerHelper(aMutex);
+ mpRefreshListeners->addInterface(xListener);
+ }
+}
+
+void SAL_CALL ScHeaderFieldsObj::removeRefreshListener( const uno::Reference<util::XRefreshListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ if (mpRefreshListeners)
+ mpRefreshListeners->removeInterface(xListener);
+ }
+}
+
+//------------------------------------------------------------------------
+
+SvxFileFormat lcl_UnoToSvxFileFormat( sal_Int16 nUnoValue )
+{
+ switch( nUnoValue )
+ {
+ case text::FilenameDisplayFormat::FULL: return SVXFILEFORMAT_FULLPATH;
+ case text::FilenameDisplayFormat::PATH: return SVXFILEFORMAT_PATH;
+ case text::FilenameDisplayFormat::NAME: return SVXFILEFORMAT_NAME;
+// case text::FilenameDisplayFormat::NAME_AND_EXT:
+ default:
+ return SVXFILEFORMAT_NAME_EXT;
+ }
+}
+
+sal_Int16 lcl_SvxToUnoFileFormat( SvxFileFormat nSvxValue )
+{
+ switch( nSvxValue )
+ {
+ case SVXFILEFORMAT_NAME_EXT: return text::FilenameDisplayFormat::NAME_AND_EXT;
+ case SVXFILEFORMAT_FULLPATH: return text::FilenameDisplayFormat::FULL;
+ case SVXFILEFORMAT_PATH: return text::FilenameDisplayFormat::PATH;
+// case SVXFILEFORMAT_NAME:
+ default:
+ return text::FilenameDisplayFormat::NAME;
+ }
+}
+
+
+// Default-ctor wird fuer SMART_REFLECTION_IMPLEMENTATION gebraucht
+//UNUSED2008-05 ScHeaderFieldObj::ScHeaderFieldObj() :
+//UNUSED2008-05 OComponentHelper( getMutex() ),
+//UNUSED2008-05 aPropSet( lcl_GetHeaderFieldPropertyMap() ),
+//UNUSED2008-05 pContentObj( NULL ),
+//UNUSED2008-05 nPart( 0 ),
+//UNUSED2008-05 nType( 0 ),
+//UNUSED2008-05 nFileFormat( SVXFILEFORMAT_NAME_EXT )
+//UNUSED2008-05 {
+//UNUSED2008-05 pEditSource = NULL;
+//UNUSED2008-05 }
+
+ScHeaderFieldObj::ScHeaderFieldObj(ScHeaderFooterContentObj* pContent, USHORT nP,
+ USHORT nT, const ESelection& rSel) :
+ OComponentHelper( getMutex() ),
+ pPropSet( (nT == SC_SERVICE_FILEFIELD) ? lcl_GetFileFieldPropertySet() : lcl_GetHeaderFieldPropertySet() ),
+ pContentObj( pContent ),
+ nPart( nP ),
+ nType( nT ),
+ aSelection( rSel ),
+ nFileFormat( SVXFILEFORMAT_NAME_EXT )
+{
+ // pContent ist Null, wenn per ServiceProvider erzeugt
+
+ if (pContentObj)
+ {
+ pContentObj->acquire(); // darf nicht wegkommen
+ pEditSource = new ScHeaderFooterEditSource( pContentObj, nPart );
+ }
+ else
+ pEditSource = NULL;
+}
+
+uno::Any SAL_CALL ScHeaderFieldObj::queryAggregation( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( text::XTextField )
+ SC_QUERYINTERFACE( text::XTextContent ) // parent of XTextField
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( lang::XUnoTunnel )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+
+ return OComponentHelper::queryAggregation( rType ); // XComponent
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScHeaderFieldObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aParentTypes(OComponentHelper::getTypes());
+ long nParentLen = aParentTypes.getLength();
+ const uno::Type* pParentPtr = aParentTypes.getConstArray();
+
+ aTypes.realloc( nParentLen + 4 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<text::XTextField>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
+
+ for (long i=0; i<nParentLen; i++)
+ pPtr[i] = pParentPtr[i]; // parent types first
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScHeaderFieldObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+uno::Any SAL_CALL ScHeaderFieldObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ return OComponentHelper::queryInterface( rType );
+}
+
+void SAL_CALL ScHeaderFieldObj::acquire() throw()
+{
+ OComponentHelper::acquire();
+}
+
+void SAL_CALL ScHeaderFieldObj::release() throw()
+{
+ OComponentHelper::release();
+}
+
+void ScHeaderFieldObj::InitDoc( ScHeaderFooterContentObj* pContent, USHORT nP,
+ const ESelection& rSel )
+{
+ if ( pContent && !pEditSource )
+ {
+ DBG_ASSERT( !pContentObj, "ContentObj, aber kein EditSource?" );
+
+ aSelection = rSel;
+ nPart = nP;
+ pContentObj = pContent;
+
+ pContentObj->acquire(); // darf nicht wegkommen
+ pEditSource = new ScHeaderFooterEditSource( pContentObj, nPart );
+ }
+}
+
+ScHeaderFieldObj::~ScHeaderFieldObj()
+{
+ delete pEditSource;
+
+ if (pContentObj)
+ pContentObj->release();
+}
+
+// per getImplementation gerufen:
+
+SvxFieldItem ScHeaderFieldObj::CreateFieldItem()
+{
+ DBG_ASSERT( !pEditSource, "CreateFieldItem mit eingefuegtem Feld" );
+
+ switch (nType)
+ {
+ case SC_SERVICE_PAGEFIELD:
+ {
+ SvxPageField aField;
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ case SC_SERVICE_PAGESFIELD:
+ {
+ SvxPagesField aField;
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ case SC_SERVICE_DATEFIELD:
+ {
+ SvxDateField aField;
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ case SC_SERVICE_TIMEFIELD:
+ {
+ SvxTimeField aField;
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ case SC_SERVICE_TITLEFIELD:
+ {
+ SvxFileField aField;
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ case SC_SERVICE_FILEFIELD:
+ {
+ SvxExtFileField aField;
+ aField.SetFormat( (SvxFileFormat) nFileFormat );
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ case SC_SERVICE_SHEETFIELD:
+ {
+ SvxTableField aField;
+ return SvxFieldItem( aField, EE_FEATURE_FIELD );
+ }
+ }
+
+ return SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD );
+}
+
+void ScHeaderFieldObj::DeleteField()
+{
+ if (pEditSource)
+ {
+ SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
+// pEditEngine->QuickDelete( aSelection );
+ pForwarder->QuickInsertText( String(), aSelection );
+ pEditSource->UpdateData();
+
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aSelection.nStartPos;
+
+ //! Broadcast, um Selektion in anderen Objekten anzupassen
+ //! (auch bei anderen Aktionen)
+ }
+}
+
+// XTextField
+
+rtl::OUString SAL_CALL ScHeaderFieldObj::getPresentation( sal_Bool /* bShowCommand */ )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aRet;
+
+ if (pEditSource)
+ {
+ // Feld von der EditEngine formatieren lassen, bShowCommand gibt's nicht
+
+ SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
+ aRet = pForwarder->GetText( aSelection );
+ }
+
+ return aRet;
+}
+
+// XTextContent
+
+void SAL_CALL ScHeaderFieldObj::attach( const uno::Reference<text::XTextRange>& xTextRange )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (xTextRange.is())
+ {
+ uno::Reference<text::XText> xText(xTextRange->getText());
+ if (xText.is())
+ {
+ xText->insertTextContent( xTextRange, this, TRUE );
+ }
+ }
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFieldObj::getAnchor() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pContentObj)
+ {
+ uno::Reference<text::XText> xText;
+ if ( nPart == SC_HDFT_LEFT )
+ xText = pContentObj->getLeftText();
+ else if (nPart == SC_HDFT_CENTER)
+ xText = pContentObj->getCenterText();
+ else
+ xText = pContentObj->getRightText();
+ return uno::Reference<text::XTextRange>( xText, uno::UNO_QUERY );
+ }
+ return NULL;
+}
+
+// XComponent
+
+void SAL_CALL ScHeaderFieldObj::dispose() throw(uno::RuntimeException)
+{
+ OComponentHelper::dispose();
+}
+
+void SAL_CALL ScHeaderFieldObj::addEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::addEventListener( xListener );
+}
+
+void SAL_CALL ScHeaderFieldObj::removeEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::removeEventListener( xListener );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScHeaderFieldObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nType == SC_SERVICE_FILEFIELD)
+ {
+ // file field has different properties
+ static uno::Reference<beans::XPropertySetInfo> aFileFieldInfo = pPropSet->getPropertySetInfo();
+ return aFileFieldInfo;
+ }
+ else
+ {
+ static uno::Reference<beans::XPropertySetInfo> aRef = pPropSet->getPropertySetInfo();
+ return aRef;
+ }
+}
+
+void SAL_CALL ScHeaderFieldObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ if ( nType == SC_SERVICE_FILEFIELD && aNameString.EqualsAscii( SC_UNONAME_FILEFORM ) )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ SvxFileFormat eFormat = lcl_UnoToSvxFileFormat( nIntVal );
+ if (pEditSource)
+ {
+ ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+ SvxFieldData* pField = aTempEngine.FindByPos(
+ aSelection.nStartPara, aSelection.nStartPos, TYPE(SvxExtFileField) );
+ DBG_ASSERT(pField,"setPropertyValue: Field not found");
+ if (pField)
+ {
+ SvxExtFileField* pExtFile = (SvxExtFileField*)pField; // local to the ScUnoEditEngine
+ pExtFile->SetFormat( eFormat );
+ pEditEngine->QuickInsertField( SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection );
+ pEditSource->UpdateData();
+ }
+ }
+ else
+ nFileFormat = sal::static_int_cast<sal_Int16>(eFormat); // not inserted yet - store value
+ }
+ }
+}
+
+uno::Any SAL_CALL ScHeaderFieldObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! Properties?
+ uno::Any aRet;
+ String aNameString(aPropertyName);
+
+ // anchor type is always "as character", text wrap always "none"
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPE ) )
+ aRet <<= text::TextContentAnchorType_AS_CHARACTER;
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPES ) )
+ {
+ uno::Sequence<text::TextContentAnchorType> aSeq(1);
+ aSeq[0] = text::TextContentAnchorType_AS_CHARACTER;
+ aRet <<= aSeq;
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_TEXTWRAP ) )
+ aRet <<= text::WrapTextMode_NONE;
+ else if ( nType == SC_SERVICE_FILEFIELD && aNameString.EqualsAscii( SC_UNONAME_FILEFORM ) )
+ {
+ SvxFileFormat eFormat = SVXFILEFORMAT_NAME_EXT;
+ if (pEditSource)
+ {
+ ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
+ ScUnoEditEngine aTempEngine(pEditEngine);
+ SvxFieldData* pField = aTempEngine.FindByPos(
+ aSelection.nStartPara, aSelection.nStartPos, TYPE(SvxExtFileField) );
+ DBG_ASSERT(pField,"setPropertyValue: Field not found");
+ if (pField)
+ {
+ const SvxExtFileField* pExtFile = (const SvxExtFileField*)pField;
+ eFormat = pExtFile->GetFormat();
+ }
+ }
+ else
+ eFormat = (SvxFileFormat) nFileFormat; // not inserted yet - use stored value
+
+ sal_Int16 nIntVal = lcl_SvxToUnoFileFormat( eFormat );
+ aRet <<= nIntVal;
+ }
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScHeaderFieldObj )
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScHeaderFieldObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScHeaderFieldObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScHeaderFieldObj* ScHeaderFieldObj::getImplementation(
+ const uno::Reference<text::XTextContent> xObj )
+{
+ ScHeaderFieldObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScHeaderFieldObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScHeaderFieldObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScHeaderFieldObj" );
+}
+
+sal_Bool SAL_CALL ScHeaderFieldObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCTEXTFIELD_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCTEXTCONTENT_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScHeaderFieldObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCTEXTFIELD_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCTEXTCONTENT_SERVICE );
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+
+
+
diff --git a/sc/source/ui/unoobj/filtuno.cxx b/sc/source/ui/unoobj/filtuno.cxx
new file mode 100644
index 000000000000..efe804784a40
--- /dev/null
+++ b/sc/source/ui/unoobj/filtuno.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <tools/urlobj.hxx>
+#include <vcl/msgbox.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include "editutil.hxx"
+#include "filtuno.hxx"
+#include "miscuno.hxx"
+#include "unoguard.hxx"
+#include "scdll.hxx"
+#include "imoptdlg.hxx"
+#include "asciiopt.hxx"
+#include "docsh.hxx"
+#include "globstr.hrc"
+
+
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "i18npool/lang.h"
+
+#include <memory>
+
+using namespace ::com::sun::star;
+using ::rtl::OUStringBuffer;
+
+//------------------------------------------------------------------------
+
+#define SCFILTEROPTIONSOBJ_SERVICE "com.sun.star.ui.dialogs.FilterOptionsDialog"
+#define SCFILTEROPTIONSOBJ_IMPLNAME "com.sun.star.comp.Calc.FilterOptionsDialog"
+
+SC_SIMPLE_SERVICE_INFO( ScFilterOptionsObj, SCFILTEROPTIONSOBJ_IMPLNAME, SCFILTEROPTIONSOBJ_SERVICE )
+
+#define SC_UNONAME_FILENAME "URL"
+#define SC_UNONAME_FILTERNAME "FilterName"
+#define SC_UNONAME_FILTEROPTIONS "FilterOptions"
+#define SC_UNONAME_INPUTSTREAM "InputStream"
+
+//------------------------------------------------------------------------
+
+ScFilterOptionsObj::ScFilterOptionsObj() :
+ bExport( sal_False )
+{
+}
+
+ScFilterOptionsObj::~ScFilterOptionsObj()
+{
+}
+
+// stuff for exService_...
+
+uno::Reference<uno::XInterface> SAL_CALL ScFilterOptionsObj_CreateInstance(
+ const uno::Reference<lang::XMultiServiceFactory>& )
+{
+ ScUnoGuard aGuard;
+ ScDLL::Init();
+ return (::cppu::OWeakObject*) new ScFilterOptionsObj;
+}
+
+rtl::OUString ScFilterOptionsObj::getImplementationName_Static()
+{
+ return rtl::OUString::createFromAscii( SCFILTEROPTIONSOBJ_IMPLNAME );
+}
+
+uno::Sequence<rtl::OUString> ScFilterOptionsObj::getSupportedServiceNames_Static()
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCFILTEROPTIONSOBJ_SERVICE );
+ return aRet;
+}
+
+// XPropertyAccess
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScFilterOptionsObj::getPropertyValues() throw(uno::RuntimeException)
+{
+ uno::Sequence<beans::PropertyValue> aRet(1);
+ beans::PropertyValue* pArray = aRet.getArray();
+
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_FILTEROPTIONS );
+ pArray[0].Value <<= aFilterOptions;
+
+ return aRet;
+}
+
+void SAL_CALL ScFilterOptionsObj::setPropertyValues( const uno::Sequence<beans::PropertyValue>& aProps )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ const beans::PropertyValue* pPropArray = aProps.getConstArray();
+ long nPropCount = aProps.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if ( aPropName.EqualsAscii( SC_UNONAME_FILENAME ) )
+ rProp.Value >>= aFileName;
+ else if ( aPropName.EqualsAscii( SC_UNONAME_FILTERNAME ) )
+ rProp.Value >>= aFilterName;
+ else if ( aPropName.EqualsAscii( SC_UNONAME_FILTEROPTIONS ) )
+ rProp.Value >>= aFilterOptions;
+ else if ( aPropName.EqualsAscii( SC_UNONAME_INPUTSTREAM ) )
+ rProp.Value >>= xInputStream;
+ }
+}
+
+// XExecutableDialog
+
+void SAL_CALL ScFilterOptionsObj::setTitle( const ::rtl::OUString& /* aTitle */ ) throw(uno::RuntimeException)
+{
+ // not used
+}
+
+sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException)
+{
+ sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;
+
+ String aFilterString( aFilterName );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");
+
+ if ( !bExport && aFilterString == ScDocShell::GetAsciiFilterName() )
+ {
+ // ascii import is special...
+
+ INetURLObject aURL( aFileName );
+ String aExt(aURL.getExtension());
+ String aPrivDatName(aURL.getName());
+ sal_Unicode cAsciiDel;
+ if (aExt.EqualsIgnoreCaseAscii("CSV"))
+ cAsciiDel = ',';
+ else
+ cAsciiDel = '\t';
+
+ SvStream* pInStream = NULL;
+ if ( xInputStream.is() )
+ pInStream = utl::UcbStreamHelper::CreateStream( xInputStream );
+
+ //CHINA001 ScImportAsciiDlg* pDlg = new ScImportAsciiDlg( NULL, aPrivDatName, pInStream, cAsciiDel );
+ AbstractScImportAsciiDlg* pDlg = pFact->CreateScImportAsciiDlg( NULL, aPrivDatName, pInStream, RID_SCDLG_ASCII, cAsciiDel);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScAsciiOptions aOptions;
+ pDlg->GetOptions( aOptions );
+ pDlg->SaveParameters();
+ aFilterOptions = aOptions.WriteToString();
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ delete pDlg;
+ delete pInStream;
+ }
+ else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() )
+ {
+ if (bExport)
+ nRet = ui::dialogs::ExecutableDialogResults::OK; // export HTML without dialog
+ else
+ {
+ // HTML import.
+ ::std::auto_ptr<AbstractScTextImportOptionsDlg> pDlg(
+ pFact->CreateScTextImportOptionsDlg(NULL, RID_SCDLG_TEXT_IMPORT_OPTIONS));
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ LanguageType eLang = pDlg->GetLanguageType();
+ OUStringBuffer aBuf;
+
+ aBuf.append(String::CreateFromInt32(static_cast<sal_Int32>(eLang)));
+ aBuf.append(sal_Unicode(' '));
+ aBuf.append(pDlg->IsDateConversionSet() ? sal_Unicode('1') : sal_Unicode('0'));
+ aFilterOptions = aBuf.makeStringAndClear();
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ }
+ }
+ else
+ {
+ sal_Bool bMultiByte = sal_True;
+ sal_Bool bDBEnc = sal_False;
+ sal_Bool bAscii = sal_False;
+
+ sal_Unicode cStrDel = '"';
+ sal_Unicode cAsciiDel = ';';
+ rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
+
+ String aTitle;
+
+ if ( aFilterString == ScDocShell::GetAsciiFilterName() )
+ {
+ // ascii export (import is handled above)
+
+ INetURLObject aURL( aFileName );
+ String aExt(aURL.getExtension());
+ if (aExt.EqualsIgnoreCaseAscii("CSV"))
+ cAsciiDel = ',';
+ else
+ cAsciiDel = '\t';
+
+ aTitle = ScGlobal::GetRscString( STR_EXPORT_ASCII );
+ bAscii = sal_True;
+ }
+ else if ( aFilterString == ScDocShell::GetLotusFilterName() )
+ {
+ // lotus is only imported
+ DBG_ASSERT( !bExport, "Filter Options for Lotus Export is not implemented" );
+
+ aTitle = ScGlobal::GetRscString( STR_IMPORT_LOTUS );
+ eEncoding = RTL_TEXTENCODING_IBM_437;
+ }
+ else if ( aFilterString == ScDocShell::GetDBaseFilterName() )
+ {
+ if ( bExport )
+ {
+ // dBase export
+ aTitle = ScGlobal::GetRscString( STR_EXPORT_DBF );
+ }
+ else
+ {
+ // dBase import
+ aTitle = ScGlobal::GetRscString( STR_IMPORT_DBF );
+ }
+ // common for dBase import/export
+ eEncoding = RTL_TEXTENCODING_IBM_850;
+ bDBEnc = sal_True;
+ }
+ else if ( aFilterString == ScDocShell::GetDifFilterName() )
+ {
+ if ( bExport )
+ {
+ // DIF export
+ aTitle = ScGlobal::GetRscString( STR_EXPORT_DIF );
+ }
+ else
+ {
+ // DIF import
+ aTitle = ScGlobal::GetRscString( STR_IMPORT_DIF );
+ }
+ // common for DIF import/export
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+ }
+
+ ScImportOptions aOptions( cAsciiDel, cStrDel, eEncoding);
+//CHINA001 ScImportOptionsDlg* pDlg = new ScImportOptionsDlg( NULL, bAscii,
+//CHINA001 &aOptions, &aTitle, bMultiByte, bDBEnc,
+//CHINA001 !bExport );
+//CHINA001
+
+ AbstractScImportOptionsDlg* pDlg = pFact->CreateScImportOptionsDlg( NULL, RID_SCDLG_IMPORTOPT,
+ bAscii, &aOptions, &aTitle, bMultiByte, bDBEnc,
+ !bExport);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetImportOptions( aOptions );
+ if ( bAscii )
+ aFilterOptions = aOptions.BuildString();
+ else
+ aFilterOptions = aOptions.aStrFont;
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ delete pDlg;
+ }
+
+ xInputStream.clear(); // don't hold the stream longer than necessary
+
+ return nRet;
+}
+
+// XImporter
+
+void SAL_CALL ScFilterOptionsObj::setTargetDocument( const uno::Reference<lang::XComponent>& /* xDoc */ )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ bExport = sal_False;
+}
+
+// XExporter
+
+void SAL_CALL ScFilterOptionsObj::setSourceDocument( const uno::Reference<lang::XComponent>& /* xDoc */ )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ bExport = sal_True;
+}
+
diff --git a/sc/source/ui/unoobj/fmtuno.cxx b/sc/source/ui/unoobj/fmtuno.cxx
new file mode 100644
index 000000000000..392533c7cf93
--- /dev/null
+++ b/sc/source/ui/unoobj/fmtuno.cxx
@@ -0,0 +1,1066 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+#include <rtl/uuid.h>
+
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+
+#include "fmtuno.hxx"
+#include "miscuno.hxx"
+#include "validat.hxx"
+#include "document.hxx"
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "styleuno.hxx" // ScStyleNameConversion
+#include "tokenarray.hxx"
+#include "tokenuno.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::formula;
+
+//------------------------------------------------------------------------
+
+// Map nur fuer PropertySetInfo
+
+const SfxItemPropertyMapEntry* lcl_GetValidatePropertyMap()
+{
+ static SfxItemPropertyMapEntry aValidatePropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ERRALSTY), 0, &getCppuType((sheet::ValidationAlertStyle*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ERRMESS), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_ERRTITLE), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_IGNOREBL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_INPMESS), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_INPTITLE), 0, &getCppuType((rtl::OUString*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SHOWERR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SHOWINP), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_SHOWLIST), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNONAME_TYPE), 0, &getCppuType((sheet::ValidationType*)0), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aValidatePropertyMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScTableConditionalEntry, "ScTableConditionalEntry", "com.sun.star.sheet.TableConditionalEntry" )
+SC_SIMPLE_SERVICE_INFO( ScTableConditionalFormat, "ScTableConditionalFormat", "com.sun.star.sheet.TableConditionalFormat" )
+SC_SIMPLE_SERVICE_INFO( ScTableValidationObj, "ScTableValidationObj", "com.sun.star.sheet.TableValidation" )
+
+//------------------------------------------------------------------------
+
+sheet::ConditionOperator lcl_ConditionModeToOperator( ScConditionMode eMode )
+{
+ sheet::ConditionOperator eOper = sheet::ConditionOperator_NONE;
+ switch (eMode)
+ {
+ case SC_COND_EQUAL: eOper = sheet::ConditionOperator_EQUAL; break;
+ case SC_COND_LESS: eOper = sheet::ConditionOperator_LESS; break;
+ case SC_COND_GREATER: eOper = sheet::ConditionOperator_GREATER; break;
+ case SC_COND_EQLESS: eOper = sheet::ConditionOperator_LESS_EQUAL; break;
+ case SC_COND_EQGREATER: eOper = sheet::ConditionOperator_GREATER_EQUAL; break;
+ case SC_COND_NOTEQUAL: eOper = sheet::ConditionOperator_NOT_EQUAL; break;
+ case SC_COND_BETWEEN: eOper = sheet::ConditionOperator_BETWEEN; break;
+ case SC_COND_NOTBETWEEN: eOper = sheet::ConditionOperator_NOT_BETWEEN; break;
+ case SC_COND_DIRECT: eOper = sheet::ConditionOperator_FORMULA; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return eOper;
+}
+
+ScConditionMode lcl_ConditionOperatorToMode( sheet::ConditionOperator eOper )
+{
+ ScConditionMode eMode = SC_COND_NONE;
+ switch (eOper)
+ {
+ case sheet::ConditionOperator_EQUAL: eMode = SC_COND_EQUAL; break;
+ case sheet::ConditionOperator_LESS: eMode = SC_COND_LESS; break;
+ case sheet::ConditionOperator_GREATER: eMode = SC_COND_GREATER; break;
+ case sheet::ConditionOperator_LESS_EQUAL: eMode = SC_COND_EQLESS; break;
+ case sheet::ConditionOperator_GREATER_EQUAL: eMode = SC_COND_EQGREATER; break;
+ case sheet::ConditionOperator_NOT_EQUAL: eMode = SC_COND_NOTEQUAL; break;
+ case sheet::ConditionOperator_BETWEEN: eMode = SC_COND_BETWEEN; break;
+ case sheet::ConditionOperator_NOT_BETWEEN: eMode = SC_COND_NOTBETWEEN; break;
+ case sheet::ConditionOperator_FORMULA: eMode = SC_COND_DIRECT; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return eMode;
+}
+
+//------------------------------------------------------------------------
+
+ScCondFormatEntryItem::ScCondFormatEntryItem() :
+ meGrammar1( FormulaGrammar::GRAM_UNSPECIFIED ),
+ meGrammar2( FormulaGrammar::GRAM_UNSPECIFIED ),
+ meMode( SC_COND_NONE )
+{
+}
+
+//------------------------------------------------------------------------
+
+ScTableConditionalFormat::ScTableConditionalFormat(
+ ScDocument* pDoc, ULONG nKey, FormulaGrammar::Grammar eGrammar)
+{
+ // Eintrag aus dem Dokument lesen...
+
+ if ( pDoc && nKey )
+ {
+ ScConditionalFormatList* pList = pDoc->GetCondFormList();
+ if (pList)
+ {
+ const ScConditionalFormat* pFormat = pList->GetFormat( nKey );
+ if (pFormat)
+ {
+ // During save to XML.
+ if (pDoc->IsInExternalReferenceMarking())
+ pFormat->MarkUsedExternalReferences();
+
+ USHORT nEntryCount = pFormat->Count();
+ for (USHORT i=0; i<nEntryCount; i++)
+ {
+ ScCondFormatEntryItem aItem;
+ const ScCondFormatEntry* pFormatEntry = pFormat->GetEntry(i);
+ 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.meGrammar1 = aItem.meGrammar2 = eGrammar;
+ aItem.maStyle = pFormatEntry->GetStyle();
+
+ AddEntry_Impl(aItem);
+ }
+ }
+ }
+ }
+}
+
+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, FormulaGrammar::Grammar eGrammar) const
+{
+ // ScConditionalFormat = Core-Struktur, muss leer sein
+
+ DBG_ASSERT( rFormat.IsEmpty(), "FillFormat: Format nicht leer" );
+ USHORT nCount = (USHORT)aEntries.Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScTableConditionalEntry* pEntry = (ScTableConditionalEntry*)aEntries.GetObject(i);
+ if ( !pEntry )
+ continue;
+
+ ScCondFormatEntryItem aData;
+ pEntry->GetData(aData);
+
+ 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 );
+
+ if ( aData.maTokens1.getLength() )
+ {
+ ScTokenArray aTokenArray;
+ if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aData.maTokens1) )
+ aCoreEntry.SetFormula1(aTokenArray);
+ }
+
+ if ( aData.maTokens2.getLength() )
+ {
+ ScTokenArray aTokenArray;
+ if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aData.maTokens2) )
+ aCoreEntry.SetFormula2(aTokenArray);
+ }
+ rFormat.AddEntry( aCoreEntry );
+ }
+}
+
+ScTableConditionalFormat::~ScTableConditionalFormat()
+{
+ ScTableConditionalEntry* pEntry;
+ aEntries.First();
+ while ( ( pEntry = (ScTableConditionalEntry*)aEntries.Remove() ) != NULL )
+ pEntry->release();
+}
+
+void ScTableConditionalFormat::AddEntry_Impl(const ScCondFormatEntryItem& aEntry)
+{
+ ScTableConditionalEntry* pNew = new ScTableConditionalEntry(this, aEntry);
+ pNew->acquire();
+ aEntries.Insert( pNew, LIST_APPEND );
+}
+
+void ScTableConditionalFormat::DataChanged()
+{
+ // wenn's mal das "lebende Objekt" ist, muss hier was passieren...
+}
+
+// XSheetConditionalFormat
+
+ScTableConditionalEntry* ScTableConditionalFormat::GetObjectByIndex_Impl(USHORT nIndex) const
+{
+ return (ScTableConditionalEntry*)aEntries.GetObject(nIndex);
+}
+
+void SAL_CALL ScTableConditionalFormat::addNew(
+ const uno::Sequence<beans::PropertyValue >& aConditionalEntry )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScCondFormatEntryItem aEntry;
+ 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];
+
+ if ( rProp.Name.equalsAscii( SC_UNONAME_OPERATOR ) )
+ {
+ sheet::ConditionOperator eOper = (sheet::ConditionOperator)
+ ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
+ aEntry.meMode = lcl_ConditionOperatorToMode( eOper );
+ }
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULA1 ) )
+ {
+ rtl::OUString aStrVal;
+ uno::Sequence<sheet::FormulaToken> aTokens;
+ if ( rProp.Value >>= aStrVal )
+ aEntry.maExpr1 = aStrVal;
+ else if ( rProp.Value >>= aTokens )
+ {
+ aEntry.maExpr1.Erase();
+ aEntry.maTokens1 = aTokens;
+ }
+ }
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULA2 ) )
+ {
+ rtl::OUString aStrVal;
+ uno::Sequence<sheet::FormulaToken> aTokens;
+ if ( rProp.Value >>= aStrVal )
+ aEntry.maExpr2 = aStrVal;
+ else if ( rProp.Value >>= aTokens )
+ {
+ aEntry.maExpr2.Erase();
+ aEntry.maTokens2 = aTokens;
+ }
+ }
+ 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 ( rProp.Name.equalsAscii( SC_UNONAME_SOURCESTR ) )
+ {
+ rtl::OUString aStrVal;
+ if ( rProp.Value >>= aStrVal )
+ aEntry.maPosStr = String( aStrVal );
+ }
+ 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 ( 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.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
+ {
+ DBG_ERROR("falsche Property");
+ //! Exception...
+ }
+ }
+
+ AddEntry_Impl(aEntry);
+ DataChanged();
+}
+
+void SAL_CALL ScTableConditionalFormat::removeByIndex( sal_Int32 nIndex )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTableConditionalEntry* pEntry = (ScTableConditionalEntry*)aEntries.GetObject(nIndex);
+ if (pEntry)
+ {
+ aEntries.Remove(pEntry);
+ pEntry->release();
+ DataChanged();
+ }
+}
+
+void SAL_CALL ScTableConditionalFormat::clear() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTableConditionalEntry* pEntry;
+ aEntries.First();
+ while ( ( pEntry = (ScTableConditionalEntry*)aEntries.Remove() ) != NULL )
+ pEntry->release();
+
+ DataChanged();
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScTableConditionalFormat::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.TableConditionalEntryEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScTableConditionalFormat::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aEntries.Count();
+}
+
+uno::Any SAL_CALL ScTableConditionalFormat::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XSheetConditionalEntry> xEntry(GetObjectByIndex_Impl((USHORT)nIndex));
+ if (xEntry.is())
+ return uno::makeAny(xEntry);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScTableConditionalFormat::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XSheetConditionalEntry>*)0);
+}
+
+sal_Bool SAL_CALL ScTableConditionalFormat::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// conditional format entries have no real names
+// -> generate name from index
+
+rtl::OUString lcl_GetEntryNameFromIndex( sal_Int32 nIndex )
+{
+ rtl::OUString aRet( RTL_CONSTASCII_USTRINGPARAM( "Entry" ) );
+ aRet += rtl::OUString::valueOf( nIndex );
+ return aRet;
+}
+
+uno::Any SAL_CALL ScTableConditionalFormat::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<sheet::XSheetConditionalEntry> xEntry;
+ long nCount = aEntries.Count();
+ for (long i=0; i<nCount; i++)
+ if ( aName == lcl_GetEntryNameFromIndex(i) )
+ {
+ xEntry.set(GetObjectByIndex_Impl((USHORT)i));
+ break;
+ }
+
+ if (xEntry.is())
+ return uno::makeAny(xEntry);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScTableConditionalFormat::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ long nCount = aEntries.Count();
+ uno::Sequence<rtl::OUString> aNames(nCount);
+ rtl::OUString* pArray = aNames.getArray();
+ for (long i=0; i<nCount; i++)
+ pArray[i] = lcl_GetEntryNameFromIndex(i);
+
+ return aNames;
+}
+
+sal_Bool SAL_CALL ScTableConditionalFormat::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ long nCount = aEntries.Count();
+ for (long i=0; i<nCount; i++)
+ if ( aName == lcl_GetEntryNameFromIndex(i) )
+ return TRUE;
+
+ return FALSE;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScTableConditionalFormat::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScTableConditionalFormat::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScTableConditionalFormat* ScTableConditionalFormat::getImplementation(
+ const uno::Reference<sheet::XSheetConditionalEntries> xObj )
+{
+ ScTableConditionalFormat* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScTableConditionalFormat*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 ScTableConditionalEntry::ScTableConditionalEntry() :
+//UNUSED2008-05 pParent( NULL )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScTableConditionalEntry::ScTableConditionalEntry(ScTableConditionalFormat* pPar,
+ const ScCondFormatEntryItem& aItem) :
+ pParent( pPar ),
+ aData( aItem )
+{
+ if (pParent)
+ pParent->acquire();
+}
+
+ScTableConditionalEntry::~ScTableConditionalEntry()
+{
+ if (pParent)
+ pParent->release();
+}
+
+void ScTableConditionalEntry::GetData(ScCondFormatEntryItem& rData) const
+{
+ rData = aData;
+}
+
+// XSheetCondition
+
+sheet::ConditionOperator SAL_CALL ScTableConditionalEntry::getOperator()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return lcl_ConditionModeToOperator( aData.meMode );
+}
+
+void SAL_CALL ScTableConditionalEntry::setOperator( sheet::ConditionOperator nOperator )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aData.meMode = lcl_ConditionOperatorToMode( nOperator );
+ if (pParent)
+ pParent->DataChanged();
+}
+
+rtl::OUString SAL_CALL ScTableConditionalEntry::getFormula1() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aData.maExpr1;
+}
+
+void SAL_CALL ScTableConditionalEntry::setFormula1( const rtl::OUString& aFormula1 )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aData.maExpr1 = String( aFormula1 );
+ if (pParent)
+ pParent->DataChanged();
+}
+
+rtl::OUString SAL_CALL ScTableConditionalEntry::getFormula2() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aData.maExpr2;
+}
+
+void SAL_CALL ScTableConditionalEntry::setFormula2( const rtl::OUString& aFormula2 )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aData.maExpr2 = String( aFormula2 );
+ if (pParent)
+ pParent->DataChanged();
+}
+
+table::CellAddress SAL_CALL ScTableConditionalEntry::getSourcePosition() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellAddress aRet;
+ aRet.Column = aData.maPos.Col();
+ aRet.Row = aData.maPos.Row();
+ aRet.Sheet = aData.maPos.Tab();
+ return aRet;
+}
+
+void SAL_CALL ScTableConditionalEntry::setSourcePosition( const table::CellAddress& aSourcePosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aData.maPos.Set( (SCCOL)aSourcePosition.Column, (SCROW)aSourcePosition.Row, aSourcePosition.Sheet );
+ if (pParent)
+ pParent->DataChanged();
+}
+
+// XSheetConditionalEntry
+
+rtl::OUString SAL_CALL ScTableConditionalEntry::getStyleName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ScStyleNameConversion::DisplayToProgrammaticName( aData.maStyle, SFX_STYLE_FAMILY_PARA );
+}
+
+void SAL_CALL ScTableConditionalEntry::setStyleName( const rtl::OUString& aStyleName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aData.maStyle = ScStyleNameConversion::ProgrammaticToDisplayName( aStyleName, SFX_STYLE_FAMILY_PARA );
+ if (pParent)
+ pParent->DataChanged();
+}
+
+//------------------------------------------------------------------------
+
+ScTableValidationObj::ScTableValidationObj(ScDocument* pDoc, ULONG nKey,
+ const formula::FormulaGrammar::Grammar eGrammar) :
+ aPropSet( lcl_GetValidatePropertyMap() )
+{
+ // Eintrag aus dem Dokument lesen...
+
+ BOOL bFound = FALSE;
+ if ( pDoc && nKey )
+ {
+ const ScValidationData* pData = pDoc->GetValidationEntry( nKey );
+ if (pData)
+ {
+ nMode = sal::static_int_cast<USHORT>( pData->GetOperation() );
+ aSrcPos = pData->GetValidSrcPos(); // #b4974740# valid pos for expressions
+ aExpr1 = pData->GetExpression( aSrcPos, 0, 0, eGrammar );
+ aExpr2 = pData->GetExpression( aSrcPos, 1, 0, eGrammar );
+ meGrammar1 = meGrammar2 = eGrammar;
+ nValMode = sal::static_int_cast<USHORT>( pData->GetDataMode() );
+ bIgnoreBlank = pData->IsIgnoreBlank();
+ nShowList = pData->GetListType();
+ bShowInput = pData->GetInput( aInputTitle, aInputMessage );
+ ScValidErrorStyle eStyle;
+ bShowError = pData->GetErrMsg( aErrorTitle, aErrorMessage, eStyle );
+ nErrorStyle = sal::static_int_cast<USHORT>( eStyle );
+
+ // During save to XML, sheet::ValidationType_ANY formulas are not
+ // saved, even if in the list, see
+ // ScMyValidationsContainer::GetCondition(), so shall not mark
+ // anything in use.
+ if (nValMode != SC_VALID_ANY && pDoc->IsInExternalReferenceMarking())
+ pData->MarkUsedExternalReferences();
+
+ bFound = TRUE;
+ }
+ }
+ if (!bFound)
+ ClearData_Impl(); // Defaults
+}
+
+ScValidationData* ScTableValidationObj::CreateValidationData( ScDocument* pDoc,
+ formula::FormulaGrammar::Grammar eGrammar ) const
+{
+ // ScValidationData = Core-Struktur
+
+ FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, meGrammar1 );
+ FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, meGrammar2 );
+
+ ScValidationData* pRet = new ScValidationData( (ScValidationMode)nValMode,
+ (ScConditionMode)nMode,
+ aExpr1, aExpr2, pDoc, aSrcPos,
+ maExprNmsp1, maExprNmsp2,
+ eGrammar1, eGrammar2 );
+ pRet->SetIgnoreBlank(bIgnoreBlank);
+ pRet->SetListType(nShowList);
+
+ if ( aTokens1.getLength() )
+ {
+ ScTokenArray aTokenArray;
+ if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aTokens1) )
+ pRet->SetFormula1(aTokenArray);
+ }
+
+ if ( aTokens2.getLength() )
+ {
+ ScTokenArray aTokenArray;
+ if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aTokens2) )
+ pRet->SetFormula2(aTokenArray);
+ }
+
+ // set strings for error / input even if disabled (and disable afterwards)
+ pRet->SetInput( aInputTitle, aInputMessage );
+ if (!bShowInput)
+ pRet->ResetInput();
+ pRet->SetError( aErrorTitle, aErrorMessage, (ScValidErrorStyle)nErrorStyle );
+ if (!bShowError)
+ pRet->ResetError();
+
+ if ( aPosString.Len() )
+ pRet->SetSrcString( aPosString );
+
+ return pRet;
+}
+
+void ScTableValidationObj::ClearData_Impl()
+{
+ nMode = SC_COND_NONE;
+ nValMode = SC_VALID_ANY;
+ bIgnoreBlank = TRUE;
+ nShowList = sheet::TableValidationVisibility::UNSORTED;
+ bShowInput = FALSE;
+ bShowError = FALSE;
+ nErrorStyle = SC_VALERR_STOP;
+ aSrcPos.Set(0,0,0);
+ aExpr1.Erase();
+ aExpr2.Erase();
+ maExprNmsp1.Erase();
+ maExprNmsp2.Erase();
+ meGrammar1 = meGrammar2 = FormulaGrammar::GRAM_UNSPECIFIED; // will be overriden when needed
+ aInputTitle.Erase();
+ aInputMessage.Erase();
+ aErrorTitle.Erase();
+ aErrorMessage.Erase();
+}
+
+ScTableValidationObj::~ScTableValidationObj()
+{
+}
+
+void ScTableValidationObj::DataChanged()
+{
+ // wenn's mal das "lebende Objekt" ist, muss hier was passieren...
+}
+
+// XSheetCondition
+
+sheet::ConditionOperator SAL_CALL ScTableValidationObj::getOperator()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return lcl_ConditionModeToOperator( (ScConditionMode)nMode );
+}
+
+void SAL_CALL ScTableValidationObj::setOperator( sheet::ConditionOperator nOperator )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ nMode = sal::static_int_cast<USHORT>( lcl_ConditionOperatorToMode( nOperator ) );
+ DataChanged();
+}
+
+rtl::OUString SAL_CALL ScTableValidationObj::getFormula1() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aExpr1;
+}
+
+void SAL_CALL ScTableValidationObj::setFormula1( const rtl::OUString& aFormula1 )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aExpr1 = String( aFormula1 );
+ DataChanged();
+}
+
+rtl::OUString SAL_CALL ScTableValidationObj::getFormula2() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aExpr2;
+}
+
+void SAL_CALL ScTableValidationObj::setFormula2( const rtl::OUString& aFormula2 )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aExpr2 = String( aFormula2 );
+ DataChanged();
+}
+
+table::CellAddress SAL_CALL ScTableValidationObj::getSourcePosition() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellAddress aRet;
+ aRet.Column = aSrcPos.Col();
+ aRet.Row = aSrcPos.Row();
+ aRet.Sheet = aSrcPos.Tab();
+ return aRet;
+}
+
+void SAL_CALL ScTableValidationObj::setSourcePosition( const table::CellAddress& aSourcePosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ aSrcPos.Set( (SCCOL)aSourcePosition.Column, (SCROW)aSourcePosition.Row, aSourcePosition.Sheet );
+ DataChanged();
+}
+
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScTableValidationObj::getTokens( sal_Int32 nIndex )
+ throw(uno::RuntimeException,lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ if (nIndex >= 2 || nIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return nIndex == 0 ? aTokens1 : aTokens2;
+}
+
+void SAL_CALL ScTableValidationObj::setTokens( sal_Int32 nIndex, const uno::Sequence<sheet::FormulaToken>& aTokens )
+ throw(uno::RuntimeException,lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ if (nIndex >= 2 || nIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ if (nIndex == 0)
+ {
+ aTokens1 = aTokens;
+ aExpr1.Erase();
+ }
+ else if (nIndex == 1)
+ {
+ aTokens2 = aTokens;
+ aExpr2.Erase();
+ }
+}
+
+sal_Int32 SAL_CALL ScTableValidationObj::getCount() throw(uno::RuntimeException)
+{
+ return 2;
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableValidationObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScTableValidationObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+
+ if ( aString.EqualsAscii( SC_UNONAME_SHOWINP ) ) bShowInput = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if ( aString.EqualsAscii( SC_UNONAME_SHOWERR ) ) bShowError = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if ( aString.EqualsAscii( SC_UNONAME_IGNOREBL ) ) bIgnoreBlank = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ else if ( aString.EqualsAscii( SC_UNONAME_SHOWLIST ) ) aValue >>= nShowList;
+ else if ( aString.EqualsAscii( SC_UNONAME_INPTITLE ) )
+ {
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ aInputTitle = String( aStrVal );
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_INPMESS ) )
+ {
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ aInputMessage = String( aStrVal );
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_ERRTITLE ) )
+ {
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ aErrorTitle = String( aStrVal );
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_ERRMESS ) )
+ {
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ aErrorMessage = String( aStrVal );
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_TYPE ) )
+ {
+ sheet::ValidationType eType = (sheet::ValidationType)
+ ScUnoHelpFunctions::GetEnumFromAny( aValue );
+ switch (eType)
+ {
+ case sheet::ValidationType_ANY: nValMode = SC_VALID_ANY; break;
+ case sheet::ValidationType_WHOLE: nValMode = SC_VALID_WHOLE; break;
+ case sheet::ValidationType_DECIMAL: nValMode = SC_VALID_DECIMAL; break;
+ case sheet::ValidationType_DATE: nValMode = SC_VALID_DATE; break;
+ case sheet::ValidationType_TIME: nValMode = SC_VALID_TIME; break;
+ case sheet::ValidationType_TEXT_LEN: nValMode = SC_VALID_TEXTLEN; break;
+ case sheet::ValidationType_LIST: nValMode = SC_VALID_LIST; break;
+ case sheet::ValidationType_CUSTOM: nValMode = SC_VALID_CUSTOM; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_ERRALSTY ) )
+ {
+ sheet::ValidationAlertStyle eStyle = (sheet::ValidationAlertStyle)
+ ScUnoHelpFunctions::GetEnumFromAny( aValue );
+ switch (eStyle)
+ {
+ case sheet::ValidationAlertStyle_STOP: nErrorStyle = SC_VALERR_STOP; break;
+ case sheet::ValidationAlertStyle_WARNING: nErrorStyle = SC_VALERR_WARNING; break;
+ case sheet::ValidationAlertStyle_INFO: nErrorStyle = SC_VALERR_INFO; break;
+ case sheet::ValidationAlertStyle_MACRO: nErrorStyle = SC_VALERR_MACRO; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_SOURCESTR ) )
+ {
+ // internal - only for XML filter, not in PropertySetInfo, only set
+
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ aPosString = String( aStrVal );
+ }
+ 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 )
+ meGrammar2 = static_cast< FormulaGrammar::Grammar >(nVal);
+ }
+
+ DataChanged();
+}
+
+uno::Any SAL_CALL ScTableValidationObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+ uno::Any aRet;
+
+ if ( aString.EqualsAscii( SC_UNONAME_SHOWINP ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, bShowInput );
+ else if ( aString.EqualsAscii( SC_UNONAME_SHOWERR ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, bShowError );
+ else if ( aString.EqualsAscii( SC_UNONAME_IGNOREBL ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, bIgnoreBlank );
+ else if ( aString.EqualsAscii( SC_UNONAME_SHOWLIST ) ) aRet <<= nShowList;
+ else if ( aString.EqualsAscii( SC_UNONAME_INPTITLE ) ) aRet <<= rtl::OUString( aInputTitle );
+ else if ( aString.EqualsAscii( SC_UNONAME_INPMESS ) ) aRet <<= rtl::OUString( aInputMessage );
+ else if ( aString.EqualsAscii( SC_UNONAME_ERRTITLE ) ) aRet <<= rtl::OUString( aErrorTitle );
+ else if ( aString.EqualsAscii( SC_UNONAME_ERRMESS ) ) aRet <<= rtl::OUString( aErrorMessage );
+ else if ( aString.EqualsAscii( SC_UNONAME_TYPE ) )
+ {
+ sheet::ValidationType eType = sheet::ValidationType_ANY;
+ switch (nValMode)
+ {
+ case SC_VALID_ANY: eType = sheet::ValidationType_ANY; break;
+ case SC_VALID_WHOLE: eType = sheet::ValidationType_WHOLE; break;
+ case SC_VALID_DECIMAL: eType = sheet::ValidationType_DECIMAL; break;
+ case SC_VALID_DATE: eType = sheet::ValidationType_DATE; break;
+ case SC_VALID_TIME: eType = sheet::ValidationType_TIME; break;
+ case SC_VALID_TEXTLEN: eType = sheet::ValidationType_TEXT_LEN; break;
+ case SC_VALID_LIST: eType = sheet::ValidationType_LIST; break;
+ case SC_VALID_CUSTOM: eType = sheet::ValidationType_CUSTOM; break;
+ }
+ aRet <<= eType;
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_ERRALSTY ) )
+ {
+ sheet::ValidationAlertStyle eStyle = sheet::ValidationAlertStyle_STOP;
+ switch (nErrorStyle)
+ {
+ case SC_VALERR_STOP: eStyle = sheet::ValidationAlertStyle_STOP; break;
+ case SC_VALERR_WARNING: eStyle = sheet::ValidationAlertStyle_WARNING; break;
+ case SC_VALERR_INFO: eStyle = sheet::ValidationAlertStyle_INFO; break;
+ case SC_VALERR_MACRO: eStyle = sheet::ValidationAlertStyle_MACRO; break;
+ }
+ aRet <<= eStyle;
+ }
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableValidationObj )
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScTableValidationObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScTableValidationObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScTableValidationObj* ScTableValidationObj::getImplementation(
+ const uno::Reference<beans::XPropertySet> xObj )
+{
+ ScTableValidationObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScTableValidationObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+
+
+
diff --git a/sc/source/ui/unoobj/forbiuno.cxx b/sc/source/ui/unoobj/forbiuno.cxx
new file mode 100644
index 000000000000..2807a12f7dac
--- /dev/null
+++ b/sc/source/ui/unoobj/forbiuno.cxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <editeng/forbiddencharacterstable.hxx>
+
+#include "forbiuno.hxx"
+#include "docsh.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+vos::ORef<SvxForbiddenCharactersTable> lcl_GetForbidden( ScDocShell* pDocSh )
+{
+ vos::ORef<SvxForbiddenCharactersTable> xRet;
+ if ( pDocSh )
+ {
+ ScDocument* pDoc = pDocSh->GetDocument();
+ xRet = pDoc->GetForbiddenCharacters();
+ if ( !xRet.isValid() )
+ {
+ // create an empty SvxForbiddenCharactersTable for SvxUnoForbiddenCharsTable,
+ // so changes can be stored.
+
+ xRet = new SvxForbiddenCharactersTable( pDoc->GetServiceManager() );
+ pDoc->SetForbiddenCharacters( xRet );
+ }
+ }
+ return xRet;
+}
+
+ScForbiddenCharsObj::ScForbiddenCharsObj( ScDocShell* pDocSh ) :
+ SvxUnoForbiddenCharsTable( lcl_GetForbidden( pDocSh ) ),
+ pDocShell( pDocSh )
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScForbiddenCharsObj::~ScForbiddenCharsObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScForbiddenCharsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // document gone
+ }
+}
+
+void ScForbiddenCharsObj::onChange()
+{
+ if (pDocShell)
+ {
+ pDocShell->GetDocument()->SetForbiddenCharacters( mxForbiddenChars );
+ pDocShell->PostPaintGridAll();
+ pDocShell->SetDocumentModified();
+ }
+}
+
diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx
new file mode 100644
index 000000000000..7012b477050c
--- /dev/null
+++ b/sc/source/ui/unoobj/funcuno.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+#include <sfx2/app.hxx>
+#include <svl/itemprop.hxx>
+
+#include "scitems.hxx"
+#include "funcuno.hxx"
+#include "miscuno.hxx"
+#include "cellsuno.hxx"
+#include "unoguard.hxx"
+#include "scdll.hxx"
+#include "document.hxx"
+#include "compiler.hxx"
+#include "formula/errorcodes.hxx"
+#include "callform.hxx"
+#include "addincol.hxx"
+#include "rangeseq.hxx"
+#include "cell.hxx"
+#include "docoptio.hxx"
+#include "optuno.hxx"
+#include <docuno.hxx>
+// for lcl_CopyData:
+#include "markdata.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "clipparam.hxx"
+#include "dociter.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+// registered as implementation for service FunctionAccess,
+// also supports service SpreadsheetDocumentSettings (to set null date etc.)
+
+#define SCFUNCTIONACCESS_SERVICE "com.sun.star.sheet.FunctionAccess"
+#define SCDOCSETTINGS_SERVICE "com.sun.star.sheet.SpreadsheetDocumentSettings"
+
+//------------------------------------------------------------------------
+
+// helper to use cached document if not in use, temporary document otherwise
+
+class ScTempDocSource
+{
+private:
+ ScTempDocCache& rCache;
+ ScDocument* pTempDoc;
+
+ static ScDocument* CreateDocument(); // create and initialize doc
+
+public:
+ ScTempDocSource( ScTempDocCache& rDocCache );
+ ~ScTempDocSource();
+
+ ScDocument* GetDocument();
+};
+
+//------------------------------------------------------------------------
+
+// static
+ScDocument* ScTempDocSource::CreateDocument()
+{
+ ScDocument* pDoc = new ScDocument; // SCDOCMODE_DOCUMENT
+ pDoc->MakeTable( 0 );
+ return pDoc;
+}
+
+ScTempDocSource::ScTempDocSource( ScTempDocCache& rDocCache ) :
+ rCache( rDocCache ),
+ pTempDoc( NULL )
+{
+ if ( rCache.IsInUse() )
+ pTempDoc = CreateDocument();
+ else
+ {
+ rCache.SetInUse( TRUE );
+ if ( !rCache.GetDocument() )
+ rCache.SetDocument( CreateDocument() );
+ }
+}
+
+ScTempDocSource::~ScTempDocSource()
+{
+ if ( pTempDoc )
+ delete pTempDoc;
+ else
+ rCache.SetInUse( FALSE );
+}
+
+ScDocument* ScTempDocSource::GetDocument()
+{
+ if ( pTempDoc )
+ return pTempDoc;
+ else
+ return rCache.GetDocument();
+}
+
+//------------------------------------------------------------------------
+
+ScTempDocCache::ScTempDocCache() :
+ pDoc( NULL ),
+ bInUse( FALSE )
+{
+}
+
+ScTempDocCache::~ScTempDocCache()
+{
+ DBG_ASSERT( !bInUse, "ScTempDocCache dtor: bInUse" );
+ delete pDoc;
+}
+
+void ScTempDocCache::SetDocument( ScDocument* pNew )
+{
+ DBG_ASSERT( !pDoc, "ScTempDocCache::SetDocument: already set" );
+ pDoc = pNew;
+}
+
+void ScTempDocCache::Clear()
+{
+ DBG_ASSERT( !bInUse, "ScTempDocCache::Clear: bInUse" );
+ delete pDoc;
+ pDoc = NULL;
+}
+
+//------------------------------------------------------------------------
+
+// copy results from one document into another
+//! merge this with ScAreaLink::Refresh
+//! copy directly without a clipboard document?
+
+BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange,
+ ScDocument* pDestDoc, const ScAddress& rDestPos )
+{
+ SCTAB nSrcTab = rSrcRange.aStart.Tab();
+ SCTAB nDestTab = rDestPos.Tab();
+
+ ScRange aNewRange( rDestPos, ScAddress(
+ rSrcRange.aEnd.Col() - rSrcRange.aStart.Col() + rDestPos.Col(),
+ rSrcRange.aEnd.Row() - rSrcRange.aStart.Row() + rDestPos.Row(),
+ nDestTab ) );
+
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ ScMarkData aSourceMark;
+ aSourceMark.SelectOneTable( nSrcTab ); // for CopyToClip
+ aSourceMark.SetMarkArea( rSrcRange );
+ ScClipParam aClipParam(rSrcRange, false);
+ pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false);
+
+ if ( pClipDoc->HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ ScPatternAttr aPattern( pSrcDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults
+ aPattern.GetItemSet().Put( ScMergeFlagAttr() );
+ pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern );
+ }
+
+ // If the range contains formula cells with default number format,
+ // apply a number format for the formula result
+ ScCellIterator aIter( pClipDoc, rSrcRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScAddress aCellPos = aIter.GetPos();
+ sal_uInt32 nFormat = pClipDoc->GetNumberFormat(aCellPos);
+ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ USHORT nErrCode = pFCell->GetErrCode();
+ if ( nErrCode == 0 && pFCell->IsValue() )
+ {
+ sal_uInt32 nNewFormat = pFCell->GetStandardFormat( *pClipDoc->GetFormatTable(), nFormat );
+ if ( nNewFormat != nFormat )
+ pClipDoc->ApplyAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(),
+ SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
+ }
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nDestTab );
+ aDestMark.SetMarkArea( aNewRange );
+ pDestDoc->CopyFromClip( aNewRange, aDestMark, IDF_ALL & ~IDF_FORMULA, NULL, pClipDoc, FALSE );
+
+ delete pClipDoc;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionAccess::ScFunctionAccess() :
+ pOptions( NULL ),
+ aPropertyMap( ScDocOptionsHelper::GetPropertyMap() ),
+ mbArray( true ), // default according to behaviour of older Office versions
+ mbValid( true )
+{
+ StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING
+}
+
+ScFunctionAccess::~ScFunctionAccess()
+{
+ delete pOptions;
+}
+
+void ScFunctionAccess::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA(SfxSimpleHint) &&
+ ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DEINITIALIZING )
+ {
+ // document must not be used anymore
+ aDocCache.Clear();
+ mbValid = false;
+ }
+}
+
+// stuff for exService_...
+
+uno::Reference<uno::XInterface> SAL_CALL ScFunctionAccess_CreateInstance(
+ const uno::Reference<lang::XMultiServiceFactory>& )
+{
+ ScUnoGuard aGuard;
+ ScDLL::Init();
+ static uno::Reference< uno::XInterface > xInst((::cppu::OWeakObject*) new ScFunctionAccess);
+ return xInst;
+}
+
+rtl::OUString ScFunctionAccess::getImplementationName_Static()
+{
+ return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScFunctionAccess" );
+}
+
+uno::Sequence<rtl::OUString> ScFunctionAccess::getSupportedServiceNames_Static()
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCFUNCTIONACCESS_SERVICE );
+ return aRet;
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScFunctionAccess::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScFunctionAccess" );
+}
+
+sal_Bool SAL_CALL ScFunctionAccess::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr(rServiceName);
+ return aServiceStr.EqualsAscii( SCFUNCTIONACCESS_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScFunctionAccess::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCFUNCTIONACCESS_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
+ return aRet;
+}
+
+// XPropertySet (document settings)
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFunctionAccess::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( &aPropertyMap ));
+ return aRef;
+}
+
+void SAL_CALL ScFunctionAccess::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) )
+ {
+ if( !(aValue >>= mbArray) )
+ throw lang::IllegalArgumentException();
+ }
+ else
+ {
+ if ( !pOptions )
+ pOptions = new ScDocOptions();
+
+ // options aren't initialized from configuration - always get the same default behaviour
+
+ BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue );
+ if (!bDone)
+ throw beans::UnknownPropertyException();
+ }
+}
+
+uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) )
+ return uno::Any( mbArray );
+
+ if ( !pOptions )
+ pOptions = new ScDocOptions();
+
+ // options aren't initialized from configuration - always get the same default behaviour
+
+ return ScDocOptionsHelper::getPropertyValue( *pOptions, aPropertyMap, aPropertyName );
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFunctionAccess )
+
+// XFunctionAccess
+
+BOOL lcl_AddFunctionToken( ScTokenArray& rArray, const rtl::OUString& rName,const ScCompiler& rCompiler )
+{
+ // function names are always case-insensitive
+ String aUpper( ScGlobal::pCharClass->upper( rName ) );
+
+ // same options as in ScCompiler::IsOpCode:
+ // 1. built-in function name
+
+ OpCode eOp = rCompiler.GetEnglishOpCode( aUpper );
+ if ( eOp != ocNone )
+ {
+ rArray.AddOpCode( eOp );
+ return TRUE;
+ }
+
+ // 2. old add in functions
+
+ USHORT nIndex;
+ if ( ScGlobal::GetFuncCollection()->SearchFunc( aUpper, nIndex ) )
+ {
+ rArray.AddExternal( aUpper.GetBuffer() );
+ return TRUE;
+ }
+
+ // 3. new (uno) add in functions
+
+ String aIntName(ScGlobal::GetAddInCollection()->FindFunction( aUpper, FALSE ));
+ if (aIntName.Len())
+ {
+ rArray.AddExternal( aIntName.GetBuffer() ); // international name
+ return TRUE;
+ }
+
+ return FALSE; // no valid function name
+}
+
+void lcl_AddRef( ScTokenArray& rArray, long nStartRow, long nColCount, long nRowCount )
+{
+ ScComplexRefData aRef;
+ aRef.InitFlags();
+ aRef.Ref1.nTab = 0;
+ aRef.Ref2.nTab = 0;
+ aRef.Ref1.nCol = 0;
+ aRef.Ref1.nRow = (SCROW) nStartRow;
+ aRef.Ref2.nCol = (SCCOL) (nColCount - 1);
+ aRef.Ref2.nRow = (SCROW) (nStartRow + nRowCount - 1);
+ rArray.AddDoubleReference(aRef);
+}
+
+class SimpleVisitor
+{
+protected:
+ bool mbArgError;
+ ScDocument* mpDoc;
+public:
+ SimpleVisitor( ScDocument* pDoc ) : mbArgError( false ), mpDoc( pDoc ) {}
+ // could possibly just get away with JUST the following overload
+ // 1) virtual void visitElem( long& nCol, long& nRow, const double& elem )
+ // 2) virtual void visitElem( long& nCol, long& nRow, const rtl::OUString& elem )
+ // 3) virtual void visitElem( long& nCol, long& nRow, const uno::Any& elem )
+ // the other types methods are here just to reflect the orig code and for
+ // completeness.
+
+ void visitElem( long nCol, long nRow, const sal_Int16& elem )
+ {
+ mpDoc->SetValue( (SCCOL) nCol, (SCROW) nRow, 0, elem );
+ }
+ void visitElem( long nCol, long nRow, const sal_Int32& elem )
+ {
+ mpDoc->SetValue( (SCCOL) nCol, (SCROW) nRow, 0, elem );
+ }
+ void visitElem( long nCol, long nRow, const double& elem )
+ {
+ mpDoc->SetValue( (SCCOL) nCol, (SCROW) nRow, 0, elem );
+ }
+ void visitElem( long nCol, long nRow, const rtl::OUString& elem )
+ {
+ if ( elem.getLength() )
+ mpDoc->PutCell( (SCCOL) nCol, (SCROW) nRow, 0,
+ new ScStringCell( elem ) );
+ }
+ void visitElem( long nCol, long nRow, const uno::Any& rElement )
+ {
+ uno::TypeClass eElemClass = rElement.getValueTypeClass();
+ if ( eElemClass == uno::TypeClass_VOID )
+ {
+ // leave empty
+ }
+ else if ( eElemClass == uno::TypeClass_BYTE ||
+ eElemClass == uno::TypeClass_SHORT ||
+ eElemClass == uno::TypeClass_UNSIGNED_SHORT ||
+ eElemClass == uno::TypeClass_LONG ||
+ eElemClass == uno::TypeClass_UNSIGNED_LONG ||
+ eElemClass == uno::TypeClass_FLOAT ||
+ eElemClass == uno::TypeClass_DOUBLE )
+ {
+ // #87871# accept integer types because Basic passes a floating point
+ // variable as byte, short or long if it's an integer number.
+ double fVal(0.0);
+ rElement >>= fVal;
+ visitElem( nCol, nRow, fVal );
+ }
+ else if ( eElemClass == uno::TypeClass_STRING )
+ {
+ rtl::OUString aUStr;
+ rElement >>= aUStr;
+ visitElem( nCol, nRow, aUStr );
+ }
+ else
+ mbArgError = true;
+ }
+ bool hasArgError() { return mbArgError; }
+};
+
+template< class seq >
+class SequencesContainer
+{
+ uno::Sequence< uno::Sequence< seq > > maSeq;
+
+ long& mrDocRow;
+ bool mbOverflow;
+ bool mbArgError;
+ ScDocument* mpDoc;
+ ScTokenArray& mrTokenArr;
+
+public:
+ SequencesContainer( const uno::Any& rArg, ScTokenArray& rTokenArr, long& rDocRow, ScDocument* pDoc ) :
+ mrDocRow( rDocRow ), mbOverflow(false), mbArgError(false), mpDoc( pDoc ), mrTokenArr( rTokenArr )
+ {
+ rArg >>= maSeq;
+ }
+
+ void process()
+ {
+ SimpleVisitor aVisitor(mpDoc);
+ long nStartRow = mrDocRow;
+ long nRowCount = maSeq.getLength();
+ long nMaxColCount = 0;
+ const uno::Sequence< seq >* pRowArr = maSeq.getConstArray();
+ for ( long nRow=0; nRow<nRowCount; nRow++ )
+ {
+ long nColCount = pRowArr[nRow].getLength();
+ if ( nColCount > nMaxColCount )
+ nMaxColCount = nColCount;
+ const seq* pColArr = pRowArr[nRow].getConstArray();
+ for (long nCol=0; nCol<nColCount; nCol++)
+ if ( nCol <= MAXCOL && mrDocRow <= MAXROW )
+ aVisitor.visitElem( nCol, mrDocRow, pColArr[ nCol ] );
+ else
+ mbOverflow=true;
+ mrDocRow++;
+ }
+ mbArgError = aVisitor.hasArgError();
+ if ( nRowCount && nMaxColCount && !mbOverflow )
+ lcl_AddRef( mrTokenArr, nStartRow, nMaxColCount, nRowCount );
+ }
+ bool getOverflow() { return mbOverflow; }
+ bool getArgError() { return mbArgError; }
+};
+
+template <class T>
+class ArrayOfArrayProc
+{
+public:
+static void processSequences( ScDocument* pDoc, const uno::Any& rArg, ScTokenArray& rTokenArr,
+ long& rDocRow, BOOL& rArgErr, BOOL& rOverflow )
+{
+ SequencesContainer< T > aContainer( rArg, rTokenArr, rDocRow, pDoc );
+ aContainer.process();
+ rArgErr = aContainer.getArgError();
+ rOverflow = aContainer.getOverflow();
+}
+};
+
+uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName,
+ const uno::Sequence<uno::Any>& aArguments )
+ throw(container::NoSuchElementException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if (!mbValid)
+ throw uno::RuntimeException();
+
+ // use cached document if not in use, temporary document otherwise
+ // (deleted in ScTempDocSource dtor)
+ ScTempDocSource aSource( aDocCache );
+ ScDocument* pDoc = aSource.GetDocument();
+ const static SCTAB nTempSheet = 1;
+ // Create an extra tab to contain the Function Cell
+ // this will allow full rows to be used.
+ if ( !pDoc->HasTable( nTempSheet ) )
+ pDoc->MakeTable( nTempSheet );
+
+ /// TODO: check
+ ScAddress aAdr;
+ ScCompiler aCompiler(pDoc,aAdr);
+ aCompiler.SetGrammar(pDoc->GetGrammar());
+ //if (!ScCompiler::IsInitialized())
+ // ScCompiler::InitSymbolsEnglish();
+
+ //
+ // find function
+ //
+
+ ScTokenArray aTokenArr;
+ if ( !lcl_AddFunctionToken( aTokenArr, aName,aCompiler ) )
+ {
+ // function not found
+ throw container::NoSuchElementException();
+ }
+
+ //
+ // set options (null date, etc.)
+ //
+
+ if ( pOptions )
+ pDoc->SetDocOptions( *pOptions );
+
+ //
+ // add arguments to token array
+ //
+
+ BOOL bArgErr = FALSE;
+ BOOL bOverflow = FALSE;
+ long nDocRow = 0;
+ long nArgCount = aArguments.getLength();
+ const uno::Any* pArgArr = aArguments.getConstArray();
+
+ aTokenArr.AddOpCode(ocOpen);
+ for (long nPos=0; nPos<nArgCount; nPos++)
+ {
+ if ( nPos > 0 )
+ aTokenArr.AddOpCode(ocSep);
+
+ const uno::Any& rArg = pArgArr[nPos];
+
+ uno::TypeClass eClass = rArg.getValueTypeClass();
+ uno::Type aType = rArg.getValueType();
+ if ( eClass == uno::TypeClass_BYTE ||
+ eClass == uno::TypeClass_BOOLEAN ||
+ eClass == uno::TypeClass_SHORT ||
+ eClass == uno::TypeClass_UNSIGNED_SHORT ||
+ eClass == uno::TypeClass_LONG ||
+ eClass == uno::TypeClass_UNSIGNED_LONG ||
+ eClass == uno::TypeClass_FLOAT ||
+ eClass == uno::TypeClass_DOUBLE )
+ {
+ // #87871# accept integer types because Basic passes a floating point
+ // variable as byte, short or long if it's an integer number.
+ double fVal = 0;
+ rArg >>= fVal;
+ aTokenArr.AddDouble( fVal );
+ }
+ else if ( eClass == uno::TypeClass_STRING )
+ {
+ rtl::OUString aUStr;
+ rArg >>= aUStr;
+ String aStr( aUStr );
+ aTokenArr.AddString( aStr.GetBuffer() );
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int16> > *)0 ) ) )
+ {
+ ArrayOfArrayProc<sal_Int16>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int32> > *)0 ) ) )
+ {
+ ArrayOfArrayProc<sal_Int32>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
+ {
+ ArrayOfArrayProc<double>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) )
+ {
+ ArrayOfArrayProc<rtl::OUString>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
+ }
+ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
+ {
+ ArrayOfArrayProc<uno::Any>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
+ }
+ else if ( aType.equals( getCppuType( (uno::Reference<table::XCellRange>*)0 ) ) )
+ {
+ // currently, only our own cell ranges are supported
+
+ uno::Reference<table::XCellRange> xRange(rArg, uno::UNO_QUERY);
+ ScCellRangesBase* pImpl = ScCellRangesBase::getImplementation( xRange );
+ if ( pImpl )
+ {
+ ScDocument* pSrcDoc = pImpl->GetDocument();
+ const ScRangeList& rRanges = pImpl->GetRangeList();
+ if ( pSrcDoc && rRanges.Count() == 1 )
+ {
+ ScRange aSrcRange = *rRanges.GetObject(0);
+
+ long nStartRow = nDocRow;
+ long nColCount = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
+ long nRowCount = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
+
+ if ( nStartRow + nRowCount > MAXROWCOUNT )
+ bOverflow = TRUE;
+ else
+ {
+ // copy data
+ if ( !lcl_CopyData( pSrcDoc, aSrcRange, pDoc, ScAddress( 0, (SCROW)nDocRow, 0 ) ) )
+ bOverflow = TRUE;
+ }
+
+ nDocRow += nRowCount;
+ if ( !bOverflow )
+ lcl_AddRef( aTokenArr, nStartRow, nColCount, nRowCount );
+ }
+ else
+ bArgErr = TRUE;
+ }
+ else
+ bArgErr = TRUE;
+ }
+ else
+ bArgErr = TRUE; // invalid type
+ }
+ aTokenArr.AddOpCode(ocClose);
+ aTokenArr.AddOpCode(ocStop);
+
+ //
+ // execute formula
+ //
+
+ uno::Any aRet;
+ if ( !bArgErr && !bOverflow && nDocRow <= MAXROWCOUNT )
+ {
+ ScAddress aFormulaPos( 0, 0, nTempSheet );
+ // GRAM_PODF_A1 doesn't really matter for the token array but fits with
+ // other API compatibility grammars.
+ ScFormulaCell* pFormula = new ScFormulaCell( pDoc, aFormulaPos,
+ &aTokenArr, formula::FormulaGrammar::GRAM_PODF_A1, (BYTE)(mbArray ? MM_FORMULA : MM_NONE) );
+ pDoc->PutCell( aFormulaPos, pFormula ); //! necessary?
+
+ // call GetMatrix before GetErrCode because GetMatrix always recalculates
+ // if there is no matrix result
+
+ const ScMatrix* pMat = mbArray ? pFormula->GetMatrix() : 0;
+ USHORT nErrCode = pFormula->GetErrCode();
+ if ( nErrCode == 0 )
+ {
+ if ( pMat )
+ {
+ // array result
+ ScRangeToSequence::FillMixedArray( aRet, pMat );
+ }
+ else if ( pFormula->IsValue() )
+ {
+ // numeric value
+ aRet <<= (double) pFormula->GetValue();
+ }
+ else
+ {
+ // string result
+ String aStrVal;
+ pFormula->GetString( aStrVal );
+ aRet <<= rtl::OUString( aStrVal );
+ }
+ }
+ else if ( nErrCode == NOTAVAILABLE )
+ {
+ // #N/A: leave result empty, no exception
+ }
+ else
+ {
+ // any other error: IllegalArgumentException
+ bArgErr = TRUE;
+ }
+
+ pDoc->DeleteAreaTab( 0, 0, MAXCOL, MAXROW, 0, IDF_ALL );
+ pDoc->DeleteAreaTab( 0, 0, 0, 0, nTempSheet, IDF_ALL );
+ }
+
+ if (bOverflow)
+ throw uno::RuntimeException();
+
+ if (bArgErr)
+ throw lang::IllegalArgumentException();
+
+ return aRet;
+}
+
+
diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx
new file mode 100644
index 000000000000..a119eda13a32
--- /dev/null
+++ b/sc/source/ui/unoobj/linkuno.cxx
@@ -0,0 +1,1821 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svl/smplhint.hxx>
+#include <sfx2/linkmgr.hxx>
+
+#include "linkuno.hxx"
+#include "miscuno.hxx"
+#include "convuno.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "collect.hxx"
+#include "tablink.hxx"
+#include "arealink.hxx"
+#include "unoguard.hxx"
+#include "hints.hxx"
+#include "unonames.hxx"
+#include "rangeseq.hxx"
+#include "token.hxx"
+
+#include <vector>
+#include <climits>
+
+using namespace com::sun::star;
+using namespace formula;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+using ::std::vector;
+
+//------------------------------------------------------------------------
+
+// fuer Sheet- und Area-Links benutzt:
+const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
+{
+ static SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_FILTER), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_FILTOPT), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LINKURL), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_REFDELAY), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_REFPERIOD), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aSheetLinkMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+SV_IMPL_PTRARR( XRefreshListenerArr_Impl, XRefreshListenerPtr );
+
+SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
+SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
+SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
+SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
+SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
+SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
+
+//------------------------------------------------------------------------
+
+ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const String& rName) :
+ aPropSet( lcl_GetSheetLinkMap() ),
+ pDocShell( pDocSh ),
+ aFileName( rName )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScSheetLinkObj::~ScSheetLinkObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! notify if links in document are changed
+ // UpdateRef is not needed here
+
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // pointer is invalid
+ }
+ else if ( rHint.ISA( ScLinkRefreshedHint ) )
+ {
+ const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
+ if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName )
+ Refreshed_Impl();
+ }
+}
+
+ScTableLink* ScSheetLinkObj::GetLink_Impl() const
+{
+ if (pDocShell)
+ {
+ sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
+ USHORT nCount = pLinkManager->GetLinks().Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
+ if (pBase->ISA(ScTableLink))
+ {
+ ScTableLink* pTabLink = (ScTableLink*)pBase;
+ if ( pTabLink->GetFileName() == aFileName )
+ return pTabLink;
+ }
+ }
+ }
+ return NULL; // nicht gefunden
+}
+
+// XNamed
+
+rtl::OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getFileName(); // Name ist der Dateiname (URL)
+}
+
+void SAL_CALL ScSheetLinkObj::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ setFileName(aName); // Name ist der Dateiname (URL)
+}
+
+// XRefreshable
+
+void SAL_CALL ScSheetLinkObj::refresh() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() );
+}
+
+void SAL_CALL ScSheetLinkObj::addRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<util::XRefreshListener>* pObj =
+ new uno::Reference<util::XRefreshListener>( xListener );
+ aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
+
+ // hold one additional ref to keep this object alive as long as there are listeners
+ if ( aRefreshListeners.Count() == 1 )
+ acquire();
+}
+
+void SAL_CALL ScSheetLinkObj::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aRefreshListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
+ if ( *pObj == xListener )
+ {
+ aRefreshListeners.DeleteAndDestroy( n );
+ if ( aRefreshListeners.Count() == 0 )
+ release(); // release ref for listeners
+ break;
+ }
+ }
+}
+
+void ScSheetLinkObj::Refreshed_Impl()
+{
+ lang::EventObject aEvent;
+ aEvent.Source.set((cppu::OWeakObject*)this);
+ for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
+ (*aRefreshListeners[n])->refreshed( aEvent );
+}
+
+void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
+{
+ ScTableLink* pLink = GetLink_Impl();
+ if( pLink )
+ pLink->SetRefreshDelay( (ULONG) nRefresh );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScSheetLinkObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ rtl::OUString aValStr;
+ if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
+ {
+ if ( aValue >>= aValStr )
+ setFileName( aValStr );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
+ {
+ if ( aValue >>= aValStr )
+ setFilter( aValStr );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
+ {
+ if ( aValue >>= aValStr )
+ setFilterOptions( aValStr );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
+ {
+ sal_Int32 nRefresh = 0;
+ if ( aValue >>= nRefresh )
+ setRefreshDelay( nRefresh );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
+ {
+ sal_Int32 nRefresh = 0;
+ if ( aValue >>= nRefresh )
+ setRefreshDelay( nRefresh );
+ }
+}
+
+uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ uno::Any aRet;
+ if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
+ aRet <<= getFileName();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
+ aRet <<= getFilter();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
+ aRet <<= getFilterOptions();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
+ aRet <<= getRefreshDelay();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
+ aRet <<= getRefreshDelay();
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
+
+// internal:
+
+rtl::OUString ScSheetLinkObj::getFileName(void) const
+{
+ ScUnoGuard aGuard;
+ return aFileName;
+}
+
+void ScSheetLinkObj::setFileName(const rtl::OUString& rNewName)
+{
+ ScUnoGuard aGuard;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ {
+ // pLink->Refresh mit neuem Dateinamen bringt sfx2::LinkManager durcheinander
+ // darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen
+
+ String aNewStr(ScGlobal::GetAbsDocName( String(rNewName), pDocShell ));
+
+ // zuerst Tabellen umsetzen
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == aFileName ) // alte Datei
+ pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr,
+ pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
+ pDoc->GetLinkTab(nTab),
+ pDoc->GetLinkRefreshDelay(nTab) ); // nur Datei aendern
+
+ // Links updaten
+ //! Undo !!!
+
+ pLink = NULL; // wird bei UpdateLinks ungueltig
+ pDocShell->UpdateLinks(); // alter Link raus, evtl. neuen Link anlegen
+
+ // Daten kopieren
+
+ aFileName = aNewStr;
+ pLink = GetLink_Impl(); // neuer Link mit neuem Namen
+ if (pLink)
+ pLink->Update(); // inkl. Paint & Undo fuer Daten
+ }
+}
+
+rtl::OUString ScSheetLinkObj::getFilter(void) const
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ aRet = pLink->GetFilterName();
+ return aRet;
+}
+
+void ScSheetLinkObj::setFilter(const rtl::OUString& Filter)
+{
+ ScUnoGuard aGuard;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ {
+ String aFilterStr(Filter);
+ pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() );
+ }
+}
+
+rtl::OUString ScSheetLinkObj::getFilterOptions(void) const
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ aRet = pLink->GetOptions();
+ return aRet;
+}
+
+void ScSheetLinkObj::setFilterOptions(const rtl::OUString& FilterOptions)
+{
+ ScUnoGuard aGuard;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ {
+ String aOptStr(FilterOptions);
+ pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() );
+ }
+}
+
+sal_Int32 ScSheetLinkObj::getRefreshDelay(void) const
+{
+ ScUnoGuard aGuard;
+ sal_Int32 nRet = 0;
+ ScTableLink* pLink = GetLink_Impl();
+ if (pLink)
+ nRet = (sal_Int32) pLink->GetRefreshDelay();
+ return nRet;
+}
+
+void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
+{
+ ScUnoGuard aGuard;
+ ModifyRefreshDelay_Impl( nRefreshDelay );
+}
+
+//------------------------------------------------------------------------
+
+ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScSheetLinksObj::~ScSheetLinksObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XSheetLinks
+
+ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(INT32 nIndex)
+{
+ if (pDocShell)
+ {
+ INT32 nCount = 0;
+ ScStrCollection aNames; // um doppelte wegzulassen
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsLinked(nTab))
+ {
+ String aLinkDoc = pDoc->GetLinkDoc( nTab );
+ StrData* pData = new StrData(aLinkDoc);
+ if (aNames.Insert(pData))
+ {
+ if ( nCount == nIndex )
+ return new ScSheetLinkObj( pDocShell, aLinkDoc );
+ ++nCount;
+ }
+ else
+ delete pData;
+ }
+ }
+ return NULL; // kein Dokument oder Index zu gross
+}
+
+ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ // Name ist der Dateiname
+
+ if (pDocShell)
+ {
+ String aNameStr(aName);
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsLinked(nTab))
+ {
+ //! case-insensitiv ???
+ String aLinkDoc = pDoc->GetLinkDoc( nTab );
+ if ( aLinkDoc == aNameStr )
+ return new ScSheetLinkObj( pDocShell, aNameStr );
+ }
+ }
+
+ return NULL;
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetLinksEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ INT32 nCount = 0;
+ if (pDocShell)
+ {
+ ScStrCollection aNames; // um doppelte wegzulassen
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsLinked(nTab))
+ {
+ String aLinkDoc(pDoc->GetLinkDoc( nTab ));
+ StrData* pData = new StrData(aLinkDoc);
+ if (aNames.Insert(pData))
+ ++nCount;
+ else
+ delete pData;
+ }
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
+ if (xLink.is())
+ return uno::makeAny(xLink);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<beans::XPropertySet>*)0);
+}
+
+sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Any SAL_CALL ScSheetLinksObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
+ if (xLink.is())
+ return uno::makeAny(xLink);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // Name ist der Dateiname
+
+ if (pDocShell)
+ {
+ String aNameStr(aName);
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsLinked(nTab))
+ {
+ //! case-insensitiv ???
+ String aLinkDoc(pDoc->GetLinkDoc( nTab ));
+ if ( aLinkDoc == aNameStr )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // Name ist der Dateiname
+
+ if (pDocShell)
+ {
+ ScStrCollection aNames; // um doppelte wegzulassen
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ String aName;
+
+ INT32 nLinkCount = getCount();
+ uno::Sequence<rtl::OUString> aSeq(nLinkCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ USHORT nPos = 0;
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pDoc->IsLinked(nTab))
+ {
+ String aLinkDoc(pDoc->GetLinkDoc( nTab ));
+ StrData* pData = new StrData(aLinkDoc);
+ if (aNames.Insert(pData))
+ pAry[nPos++] = aLinkDoc;
+ else
+ delete pData;
+ }
+ }
+ DBG_ASSERT( nPos==nLinkCount, "verzaehlt" );
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>();
+}
+
+//------------------------------------------------------------------------
+
+ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, USHORT nPos )
+{
+ if (pDocShell)
+ {
+ sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
+ USHORT nTotalCount = pLinkManager->GetLinks().Count();
+ USHORT nAreaCount = 0;
+ for (USHORT i=0; i<nTotalCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
+ if (pBase->ISA(ScAreaLink))
+ {
+ if ( nAreaCount == nPos )
+ return (ScAreaLink*)pBase;
+ ++nAreaCount;
+ }
+ }
+ }
+ return NULL; // nicht gefunden
+}
+
+ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, USHORT nP) :
+ aPropSet( lcl_GetSheetLinkMap() ),
+ pDocShell( pDocSh ),
+ nPos( nP )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScAreaLinkObj::~ScAreaLinkObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! notify if links in document are changed
+ // UpdateRef is not needed here
+
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // pointer is invalid
+ }
+ else if ( rHint.ISA( ScLinkRefreshedHint ) )
+ {
+ const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
+ if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
+ {
+ // get this link to compare dest position
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
+ Refreshed_Impl();
+ }
+ }
+}
+
+// XFileLink
+
+void ScAreaLinkObj::Modify_Impl( const rtl::OUString* pNewFile, const rtl::OUString* pNewFilter,
+ const rtl::OUString* pNewOptions, const rtl::OUString* pNewSource,
+ const table::CellRangeAddress* pNewDest )
+{
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ {
+ String aFile (pLink->GetFile());
+ String aFilter (pLink->GetFilter());
+ String aOptions (pLink->GetOptions());
+ String aSource (pLink->GetSource());
+ ScRange aDest (pLink->GetDestArea());
+ ULONG nRefresh = pLink->GetRefreshDelay();
+
+ //! Undo fuer Loeschen
+ //! Undo zusammenfassen
+
+ sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
+ pLinkManager->Remove( pLink );
+ pLink = NULL; // bei Remove geloescht
+
+ BOOL bFitBlock = TRUE; // verschieben, wenn durch Update Groesse geaendert
+ if (pNewFile)
+ {
+ aFile = String( *pNewFile );
+ aFile = ScGlobal::GetAbsDocName( aFile, pDocShell ); //! in InsertAreaLink?
+ }
+ if (pNewFilter)
+ aFilter = String( *pNewFilter );
+ if (pNewOptions)
+ aOptions = String( *pNewOptions );
+ if (pNewSource)
+ aSource = String( *pNewSource );
+ if (pNewDest)
+ {
+ ScUnoConversion::FillScRange( aDest, *pNewDest );
+ bFitBlock = FALSE; // neuer Bereich angegeben -> keine Inhalte verschieben
+ }
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.InsertAreaLink( aFile, aFilter, aOptions, aSource, aDest, nRefresh, bFitBlock, TRUE );
+ }
+}
+
+void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
+{
+ ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
+ if( pLink )
+ pLink->SetRefreshDelay( (ULONG) nRefresh );
+}
+
+// XRefreshable
+
+void SAL_CALL ScAreaLinkObj::refresh() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() );
+}
+
+void SAL_CALL ScAreaLinkObj::addRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<util::XRefreshListener>* pObj =
+ new uno::Reference<util::XRefreshListener>( xListener );
+ aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
+
+ // hold one additional ref to keep this object alive as long as there are listeners
+ if ( aRefreshListeners.Count() == 1 )
+ acquire();
+}
+
+void SAL_CALL ScAreaLinkObj::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aRefreshListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
+ if ( *pObj == xListener )
+ {
+ aRefreshListeners.DeleteAndDestroy( n );
+ if ( aRefreshListeners.Count() == 0 )
+ release(); // release ref for listeners
+ break;
+ }
+ }
+}
+
+void ScAreaLinkObj::Refreshed_Impl()
+{
+ lang::EventObject aEvent;
+ aEvent.Source.set((cppu::OWeakObject*)this);
+ for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
+ (*aRefreshListeners[n])->refreshed( aEvent );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScAreaLinkObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ rtl::OUString aValStr;
+ if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
+ {
+ if ( aValue >>= aValStr )
+ setFileName( aValStr );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
+ {
+ if ( aValue >>= aValStr )
+ setFilter( aValStr );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
+ {
+ if ( aValue >>= aValStr )
+ setFilterOptions( aValStr );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
+ {
+ sal_Int32 nRefresh = 0;
+ if ( aValue >>= nRefresh )
+ setRefreshDelay( nRefresh );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
+ {
+ sal_Int32 nRefresh = 0;
+ if ( aValue >>= nRefresh )
+ setRefreshDelay( nRefresh );
+ }
+}
+
+uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+ uno::Any aRet;
+ if ( aNameString.EqualsAscii( SC_UNONAME_LINKURL ) )
+ aRet <<= getFileName();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTER ) )
+ aRet <<= getFilter();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_FILTOPT ) )
+ aRet <<= getFilterOptions();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFPERIOD ) )
+ aRet <<= getRefreshDelay();
+ else if ( aNameString.EqualsAscii( SC_UNONAME_REFDELAY ) )
+ aRet <<= getRefreshDelay();
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
+
+// internal:
+
+rtl::OUString ScAreaLinkObj::getFileName(void) const
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ aRet = pLink->GetFile();
+ return aRet;
+}
+
+void ScAreaLinkObj::setFileName(const rtl::OUString& rNewName)
+{
+ ScUnoGuard aGuard;
+ Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
+}
+
+rtl::OUString ScAreaLinkObj::getFilter(void) const
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ aRet = pLink->GetFilter();
+ return aRet;
+}
+
+void ScAreaLinkObj::setFilter(const rtl::OUString& Filter)
+{
+ ScUnoGuard aGuard;
+ Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
+}
+
+rtl::OUString ScAreaLinkObj::getFilterOptions(void) const
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ aRet = pLink->GetOptions();
+ return aRet;
+}
+
+void ScAreaLinkObj::setFilterOptions(const rtl::OUString& FilterOptions)
+{
+ ScUnoGuard aGuard;
+ Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
+}
+
+sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const
+{
+ ScUnoGuard aGuard;
+ sal_Int32 nRet = 0;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ nRet = (sal_Int32) pLink->GetRefreshDelay();
+ return nRet;
+}
+
+void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
+{
+ ScUnoGuard aGuard;
+ ModifyRefreshDelay_Impl( nRefreshDelay );
+}
+
+// XAreaLink
+
+rtl::OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ aRet = pLink->GetSource();
+ return aRet;
+}
+
+void SAL_CALL ScAreaLinkObj::setSourceArea( const rtl::OUString& aSourceArea )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
+}
+
+table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aRet;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
+ if (pLink)
+ ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
+ return aRet;
+}
+
+void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
+}
+
+//------------------------------------------------------------------------
+
+ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScAreaLinksObj::~ScAreaLinksObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XAreaLinks
+
+ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(INT32 nIndex)
+{
+ if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
+ return new ScAreaLinkObj( pDocShell, (USHORT)nIndex );
+
+ return NULL; // nicht gefunden
+}
+
+void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos,
+ const rtl::OUString& aFileName,
+ const rtl::OUString& aSourceArea,
+ const rtl::OUString& aFilter,
+ const rtl::OUString& aFilterOptions )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ String aFileStr (aFileName);
+ String aFilterStr (aFilter);
+ String aOptionStr (aFilterOptions);
+ String aSourceStr (aSourceArea);
+ ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
+
+ aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ???
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
+ aSourceStr, ScRange(aDestAddr),
+ 0, FALSE, TRUE ); // keine Inhalte verschieben
+ }
+}
+
+void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (USHORT)nIndex);
+ if (pLink)
+ {
+ //! SetAddUndo oder so
+
+ sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
+ pLinkManager->Remove( pLink );
+ }
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAreaLinksEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ INT32 nAreaCount = 0;
+ if (pDocShell)
+ {
+ sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
+ USHORT nTotalCount = pLinkManager->GetLinks().Count();
+ for (USHORT i=0; i<nTotalCount; i++)
+ {
+ ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
+ if (pBase->ISA(ScAreaLink))
+ ++nAreaCount;
+ }
+ }
+ return nAreaCount;
+}
+
+uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
+ if (xLink.is())
+ return uno::makeAny(xLink);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
+}
+
+sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+//------------------------------------------------------------------------
+
+ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const String& rA,
+ const String& rT, const String& rI) :
+ pDocShell( pDocSh ),
+ aAppl( rA ),
+ aTopic( rT ),
+ aItem( rI )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDDELinkObj::~ScDDELinkObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! notify if links in document are changed
+ // UpdateRef is not needed here
+
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // pointer is invalid
+ }
+ else if ( rHint.ISA( ScLinkRefreshedHint ) )
+ {
+ const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
+ if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
+ rLH.GetDdeAppl() == aAppl &&
+ rLH.GetDdeTopic() == aTopic &&
+ rLH.GetDdeItem() == aItem ) //! mode is ignored
+ Refreshed_Impl();
+ }
+}
+
+// XNamed
+
+String lcl_BuildDDEName( const String& rAppl, const String& rTopic, const String& rItem )
+{
+ // Appl|Topic!Item (wie Excel)
+ String aRet = rAppl;
+ aRet += '|';
+ aRet += rTopic;
+ aRet += '!';
+ aRet += rItem;
+ return aRet;
+}
+
+rtl::OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return lcl_BuildDDEName( aAppl, aTopic, aItem );
+}
+
+void SAL_CALL ScDDELinkObj::setName( const rtl::OUString& /* aName */ ) throw(uno::RuntimeException)
+{
+ // name can't be changed (formulas wouldn't find the link)
+ throw uno::RuntimeException();
+}
+
+// XDDELink
+
+rtl::OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! Test, ob Link noch im Dokument enthalten?
+
+ return aAppl;
+}
+
+rtl::OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! Test, ob Link noch im Dokument enthalten?
+
+ return aTopic;
+}
+
+rtl::OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! Test, ob Link noch im Dokument enthalten?
+
+ return aItem;
+}
+
+// XRefreshable
+
+void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ (void)pDoc->UpdateDdeLink( aAppl, aTopic, aItem );
+ //! Fehler abfragen
+ }
+}
+
+void SAL_CALL ScDDELinkObj::addRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<util::XRefreshListener>* pObj =
+ new uno::Reference<util::XRefreshListener>( xListener );
+ aRefreshListeners.Insert( pObj, aRefreshListeners.Count() );
+
+ // hold one additional ref to keep this object alive as long as there are listeners
+ if ( aRefreshListeners.Count() == 1 )
+ acquire();
+}
+
+void SAL_CALL ScDDELinkObj::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aRefreshListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<util::XRefreshListener>* pObj = aRefreshListeners[n];
+ if ( *pObj == xListener )
+ {
+ aRefreshListeners.DeleteAndDestroy( n );
+ if ( aRefreshListeners.Count() == 0 )
+ release(); // release ref for listeners
+ break;
+ }
+ }
+}
+
+// XDDELinkResults
+
+uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence< uno::Sequence< uno::Any > > aReturn;
+ bool bSuccess = false;
+
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( pDoc )
+ {
+ USHORT nPos = 0;
+ if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
+ {
+ const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix( nPos );
+ if ( pMatrix )
+ {
+ uno::Any aAny;
+ if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
+ {
+ aAny >>= aReturn;
+ }
+ }
+ bSuccess = true;
+ }
+ }
+ }
+
+ if ( !bSuccess )
+ {
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "ScDDELinkObj::getResults: failed to get results!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ return aReturn;
+}
+
+void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ bool bSuccess = false;
+
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( pDoc )
+ {
+ USHORT nPos = 0;
+ if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
+ {
+ uno::Any aAny;
+ aAny <<= aResults;
+ ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
+ bSuccess = pDoc->SetDdeLinkResultMatrix( nPos, xMatrix );
+ }
+ }
+ }
+
+ if ( !bSuccess )
+ {
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "ScDDELinkObj::setResults: failed to set results!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+}
+
+void ScDDELinkObj::Refreshed_Impl()
+{
+ lang::EventObject aEvent;
+ aEvent.Source.set((cppu::OWeakObject*)this);
+ for ( USHORT n=0; n<aRefreshListeners.Count(); n++ )
+ (*aRefreshListeners[n])->refreshed( aEvent );
+}
+
+//------------------------------------------------------------------------
+
+ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDDELinksObj::~ScDDELinksObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XDDELinks
+
+ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(INT32 nIndex)
+{
+ if (pDocShell)
+ {
+ String aAppl, aTopic, aItem;
+ if ( nIndex <= USHRT_MAX &&
+ pDocShell->GetDocument()->GetDdeLinkData( (USHORT)nIndex, aAppl, aTopic, aItem ) )
+ return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
+ }
+ return NULL;
+}
+
+ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ if (pDocShell)
+ {
+ String aNamStr(aName);
+ String aAppl, aTopic, aItem;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ USHORT nCount = pDoc->GetDdeLinkCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
+ if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
+ return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
+ }
+ }
+ return NULL;
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DDELinksEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ INT32 nAreaCount = 0;
+ if (pDocShell)
+ nAreaCount = pDocShell->GetDocument()->GetDdeLinkCount();
+ return nAreaCount;
+}
+
+uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
+ if (xLink.is())
+ return uno::makeAny(xLink);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XDDELink>*)0);
+}
+
+sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Any SAL_CALL ScDDELinksObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
+ if (xLink.is())
+ return uno::makeAny(xLink);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ String aAppl, aTopic, aItem;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ USHORT nCount = pDoc->GetDdeLinkCount();
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+
+ for (USHORT i=0; i<nCount; i++)
+ {
+ pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
+ pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
+ }
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>();
+}
+
+sal_Bool SAL_CALL ScDDELinksObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ String aNamStr(aName);
+ String aAppl, aTopic, aItem;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ USHORT nCount = pDoc->GetDdeLinkCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
+ if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// XDDELinks
+
+uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
+ const ::rtl::OUString& aApplication, const ::rtl::OUString& aTopic,
+ const ::rtl::OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< sheet::XDDELink > xLink;
+
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( pDoc )
+ {
+ BYTE nMod = SC_DDE_DEFAULT;
+ switch ( nMode )
+ {
+ case sheet::DDELinkMode_DEFAULT:
+ {
+ nMod = SC_DDE_DEFAULT;
+ }
+ break;
+ case sheet::DDELinkMode_ENGLISH:
+ {
+ nMod = SC_DDE_ENGLISH;
+ }
+ break;
+ case sheet::DDELinkMode_TEXT:
+ {
+ nMod = SC_DDE_TEXT;
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+
+ if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod ) )
+ {
+ const ::rtl::OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
+ xLink.set( GetObjectByName_Impl( aName ) );
+ }
+ }
+ }
+
+ if ( !xLink.is() )
+ {
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "ScDDELinksObj::addDDELink: cannot add DDE link!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ return xLink;
+}
+
+// ============================================================================
+
+ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
+ mpTable(pTable),
+ mnIndex(nIndex)
+{
+}
+
+ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
+{
+}
+
+void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
+ throw (IllegalArgumentException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nRow < 0 || nCol < 0)
+ throw IllegalArgumentException();
+
+ ScExternalRefCache::TokenRef pToken;
+ double fVal = 0.0;
+ OUString aVal;
+ if (rValue >>= fVal)
+ pToken.reset(new FormulaDoubleToken(fVal));
+ else if (rValue >>= aVal)
+ pToken.reset(new FormulaStringToken(aVal));
+ else
+ // unidentified value type.
+ return;
+
+ mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
+}
+
+Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
+ throw (IllegalArgumentException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nRow < 0 || nCol < 0)
+ throw IllegalArgumentException();
+
+ FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
+ if (!pToken)
+ throw IllegalArgumentException();
+
+ Any aValue;
+ switch (pToken->GetType())
+ {
+ case svDouble:
+ {
+ double fVal = pToken->GetDouble();
+ aValue <<= fVal;
+ }
+ break;
+ case svString:
+ {
+ OUString aVal = pToken->GetString();
+ aValue <<= aVal;
+ }
+ break;
+ default:
+ throw IllegalArgumentException();
+ }
+ return aValue;
+}
+
+Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ vector<SCROW> aRows;
+ mpTable->getAllRows(aRows);
+ size_t nSize = aRows.size();
+ Sequence<sal_Int32> aRowsSeq(nSize);
+ for (size_t i = 0; i < nSize; ++i)
+ aRowsSeq[i] = aRows[i];
+
+ return aRowsSeq;
+}
+
+Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
+ throw (IllegalArgumentException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nRow < 0)
+ throw IllegalArgumentException();
+
+ vector<SCCOL> aCols;
+ mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
+ size_t nSize = aCols.size();
+ Sequence<sal_Int32> aColsSeq(nSize);
+ for (size_t i = 0; i < nSize; ++i)
+ aColsSeq[i] = aCols[i];
+
+ return aColsSeq;
+}
+
+sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
+ throw (RuntimeException)
+{
+ return static_cast< sal_Int32 >( mnIndex );
+}
+
+// ============================================================================
+
+ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
+ mpRefMgr(pRefMgr), mnFileId(nFileId)
+{
+}
+
+ScExternalDocLinkObj::~ScExternalDocLinkObj()
+{
+}
+
+Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
+ const OUString& aSheetName, sal_Bool bDynamicCache )
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ size_t nIndex = 0;
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
+ if (!bDynamicCache)
+ // Set the whole table cached to prevent access to the source document.
+ pTable->setWholeTableCached();
+
+ Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
+ return aSheetCache;
+}
+
+Any SAL_CALL ScExternalDocLinkObj::getByName(const::rtl::OUString &aName)
+ throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ size_t nIndex = 0;
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
+ if (!pTable)
+ throw container::NoSuchElementException();
+
+ Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
+
+ Any aAny;
+ aAny <<= aSheetCache;
+ return aAny;
+}
+
+Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ vector<String> aTabNames;
+ mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
+ size_t n = aTabNames.size();
+ Sequence<OUString> aSeq(n);
+ for (size_t i = 0; i < n; ++i)
+ aSeq[i] = aTabNames[i];
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName));
+}
+
+sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId));
+}
+
+Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex)
+ throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId);
+ if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount))
+ throw lang::IndexOutOfBoundsException();
+
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex));
+ if (!pTable)
+ throw lang::IndexOutOfBoundsException();
+
+ Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
+
+ Any aAny;
+ aAny <<= aSheetCache;
+ return aAny;
+}
+
+Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference< container::XEnumeration > aRef(
+ new ScIndexEnumeration(this, OUString::createFromAscii(
+ "com.sun.star.sheet.ExternalDocLink")));
+ return aRef;
+}
+
+uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
+}
+
+sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0);
+}
+
+sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
+ throw (RuntimeException)
+{
+ return static_cast<sal_Int32>(mnFileId);
+}
+
+// ============================================================================
+
+ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
+ mpDocShell(pDocShell),
+ mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
+{
+}
+
+ScExternalDocLinksObj::~ScExternalDocLinksObj()
+{
+}
+
+Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
+ const OUString& aDocName )
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
+ Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
+ return aDocLink;
+}
+
+Any SAL_CALL ScExternalDocLinksObj::getByName(const::rtl::OUString &aName)
+ throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!mpRefMgr->hasExternalFile(aName))
+ throw container::NoSuchElementException();
+
+ sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
+ Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
+
+ Any aAny;
+ aAny <<= aDocLink;
+ return aAny;
+}
+
+Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_uInt16 n = mpRefMgr->getExternalFileCount();
+ Sequence<OUString> aSeq(n);
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ const String* pName = mpRefMgr->getExternalFileName(i);
+ aSeq[i] = pName ? *pName : EMPTY_STRING;
+ }
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return mpRefMgr->hasExternalFile(aName);
+}
+
+sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return mpRefMgr->getExternalFileCount();
+}
+
+Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
+ throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
+ throw lang::IndexOutOfBoundsException();
+
+ sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
+
+ if (!mpRefMgr->hasExternalFile(nFileId))
+ throw lang::IndexOutOfBoundsException();
+
+ Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
+ Any aAny;
+ aAny <<= aDocLink;
+ return aAny;
+}
+
+Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ Reference< container::XEnumeration > aRef(
+ new ScIndexEnumeration(this, OUString::createFromAscii(
+ "com.sun.star.sheet.ExternalDocLinks")));
+ return aRef;
+}
+
+uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
+}
+
+sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return mpRefMgr->getExternalFileCount() > 0;
+}
+
diff --git a/sc/source/ui/unoobj/listenercalls.cxx b/sc/source/ui/unoobj/listenercalls.cxx
new file mode 100644
index 000000000000..9abc8e0ab826
--- /dev/null
+++ b/sc/source/ui/unoobj/listenercalls.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <com/sun/star/util/XModifyListener.hpp>
+#include <tools/debug.hxx>
+
+#include "listenercalls.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+ScUnoListenerCalls::ScUnoListenerCalls()
+{
+}
+
+ScUnoListenerCalls::~ScUnoListenerCalls()
+{
+ DBG_ASSERT( aEntries.empty(), "unhandled listener calls remaining" );
+}
+
+void ScUnoListenerCalls::Add( const uno::Reference<util::XModifyListener>& rListener,
+ const lang::EventObject& rEvent )
+{
+ if ( rListener.is() )
+ aEntries.push_back( ScUnoListenerEntry( rListener, rEvent ) );
+}
+
+void ScUnoListenerCalls::ExecuteAndClear()
+{
+ // Execute all stored calls and remove them from the list.
+ // During each modified() call, Add may be called again.
+ // These new calls are executed here, too.
+
+ if (!aEntries.empty())
+ {
+ std::list<ScUnoListenerEntry>::iterator aItr(aEntries.begin());
+ std::list<ScUnoListenerEntry>::iterator aEndItr(aEntries.end());
+ while ( aItr != aEndItr )
+ {
+ ScUnoListenerEntry aEntry = *aItr;
+ try
+ {
+ aEntry.xListener->modified( aEntry.aEvent );
+ }
+ catch ( uno::RuntimeException )
+ {
+ // the listener is an external object and may throw a RuntimeException
+ // for reasons we don't know
+ }
+
+ // New calls that are added during the modified() call are appended to the end
+ // of aEntries, so the loop will catch them, too (as long as erase happens
+ // after modified).
+
+ aItr = aEntries.erase(aItr);
+ }
+ }
+}
+
diff --git a/sc/source/ui/unoobj/makefile.mk b/sc/source/ui/unoobj/makefile.mk
new file mode 100644
index 000000000000..36c3493ceefc
--- /dev/null
+++ b/sc/source/ui/unoobj/makefile.mk
@@ -0,0 +1,120 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=unoobj
+
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+SLO1FILES = \
+ $(SLO)$/docuno.obj \
+ $(SLO)$/servuno.obj \
+ $(SLO)$/defltuno.obj \
+ $(SLO)$/drdefuno.obj \
+ $(SLO)$/cellsuno.obj \
+ $(SLO)$/tokenuno.obj \
+ $(SLO)$/textuno.obj \
+ $(SLO)$/notesuno.obj \
+ $(SLO)$/cursuno.obj \
+ $(SLO)$/srchuno.obj \
+ $(SLO)$/fielduno.obj \
+ $(SLO)$/miscuno.obj \
+ $(SLO)$/optuno.obj \
+ $(SLO)$/appluno.obj \
+ $(SLO)$/funcuno.obj \
+ $(SLO)$/nameuno.obj \
+ $(SLO)$/viewuno.obj \
+ $(SLO)$/dispuno.obj \
+ $(SLO)$/datauno.obj \
+ $(SLO)$/dapiuno.obj \
+ $(SLO)$/chartuno.obj \
+ $(SLO)$/chart2uno.obj \
+ $(SLO)$/shapeuno.obj \
+ $(SLO)$/pageuno.obj \
+ $(SLO)$/forbiuno.obj \
+ $(SLO)$/styleuno.obj \
+ $(SLO)$/afmtuno.obj \
+ $(SLO)$/fmtuno.obj \
+ $(SLO)$/linkuno.obj \
+ $(SLO)$/targuno.obj \
+ $(SLO)$/convuno.obj \
+ $(SLO)$/editsrc.obj \
+ $(SLO)$/unoguard.obj \
+ $(SLO)$/confuno.obj \
+ $(SLO)$/filtuno.obj \
+ $(SLO)$/unodoc.obj \
+ $(SLO)$/addruno.obj \
+ $(SLO)$/eventuno.obj \
+ $(SLO)$/listenercalls.obj \
+ $(SLO)$/cellvaluebinding.obj \
+ $(SLO)$/celllistsource.obj \
+ $(SLO)$/warnpassword.obj \
+ $(SLO)$/unoreflist.obj \
+ $(SLO)$/ChartRangeSelectionListener.obj
+
+SLO2FILES = \
+ $(SLO)$/scdetect.obj \
+ $(SLO)$/detreg.obj
+
+SLOFILES = \
+ $(SLO1FILES) \
+ $(SLO2FILES)
+
+LIB1TARGET = \
+ $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO1FILES)
+
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
+NOOPTFILES= \
+ $(SLO)$/cellsuno.obj
+.ENDIF
+
+# Work around bug in gcc 4.2 / 4.3, see
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35182
+.IF "$(COM)"=="GCC"
+NOOPTFILES+= \
+ $(SLO)$/chart2uno.obj
+.ENDIF
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/unoobj/miscuno.cxx b/sc/source/ui/unoobj/miscuno.cxx
new file mode 100644
index 000000000000..4fdac0288796
--- /dev/null
+++ b/sc/source/ui/unoobj/miscuno.cxx
@@ -0,0 +1,424 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+
+#include "miscuno.hxx"
+#include "unoguard.hxx"
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 SC_SIMPLE_SERVICE_INFO( ScEmptyEnumeration, "ScEmptyEnumeration", "stardiv.unknown" )
+//UNUSED2008-05 SC_SIMPLE_SERVICE_INFO( ScEmptyEnumerationAccess, "ScEmptyEnumerationAccess", "stardiv.unknown" )
+//UNUSED2008-05 SC_SIMPLE_SERVICE_INFO( ScIndexEnumeration, "ScIndexEnumeration", "stardiv.unknown" )
+//UNUSED2008-05 SC_SIMPLE_SERVICE_INFO( ScPrintSettingsObj, "ScPrintSettingsObj", "stardiv.unknown" )
+
+SC_SIMPLE_SERVICE_INFO( ScNameToIndexAccess, "ScNameToIndexAccess", "stardiv.unknown" )
+
+//------------------------------------------------------------------------
+
+// static
+uno::Reference<uno::XInterface> ScUnoHelpFunctions::AnyToInterface( const uno::Any& rAny )
+{
+ if ( rAny.getValueTypeClass() == uno::TypeClass_INTERFACE )
+ {
+ return uno::Reference<uno::XInterface>(rAny, uno::UNO_QUERY);
+ }
+ return uno::Reference<uno::XInterface>(); //! Exception?
+}
+
+// static
+sal_Bool ScUnoHelpFunctions::GetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
+ const rtl::OUString& rName, sal_Bool bDefault )
+{
+ sal_Bool bRet = bDefault;
+ if ( xProp.is() )
+ {
+ try
+ {
+ uno::Any aAny(xProp->getPropertyValue( rName ));
+ //! type conversion???
+ // operator >>= shouldn't be used for bool (?)
+ if ( aAny.getValueTypeClass() == uno::TypeClass_BOOLEAN )
+ {
+ //! safe way to get bool value from any???
+ bRet = *(sal_Bool*)aAny.getValue();
+ }
+ }
+ catch(uno::Exception&)
+ {
+ // keep default
+ }
+ }
+ return bRet;
+}
+
+// static
+sal_Int32 ScUnoHelpFunctions::GetLongProperty( const uno::Reference<beans::XPropertySet>& xProp,
+ const rtl::OUString& rName, long nDefault )
+{
+ sal_Int32 nRet = nDefault;
+ if ( xProp.is() )
+ {
+ try
+ {
+ //! type conversion???
+ xProp->getPropertyValue( rName ) >>= nRet;
+ }
+ catch(uno::Exception&)
+ {
+ // keep default
+ }
+ }
+ return nRet;
+}
+
+// static
+sal_Int32 ScUnoHelpFunctions::GetEnumProperty( const uno::Reference<beans::XPropertySet>& xProp,
+ const rtl::OUString& rName, long nDefault )
+{
+ sal_Int32 nRet = nDefault;
+ if ( xProp.is() )
+ {
+ try
+ {
+ uno::Any aAny(xProp->getPropertyValue( rName ));
+
+ if ( aAny.getValueTypeClass() == uno::TypeClass_ENUM )
+ {
+ //! get enum value from any???
+ nRet = *(sal_Int32*)aAny.getValue();
+ }
+ else
+ {
+ //! type conversion???
+ aAny >>= nRet;
+ }
+ }
+ catch(uno::Exception&)
+ {
+ // keep default
+ }
+ }
+ return nRet;
+}
+
+// static
+OUString ScUnoHelpFunctions::GetStringProperty(
+ const Reference<beans::XPropertySet>& xProp, const OUString& rName, const OUString& rDefault )
+{
+ OUString aRet = rDefault;
+ if (!xProp.is())
+ return aRet;
+
+ try
+ {
+ Any any = xProp->getPropertyValue(rName);
+ any >>= aRet;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ return aRet;
+}
+
+// static
+sal_Bool ScUnoHelpFunctions::GetBoolFromAny( const uno::Any& aAny )
+{
+ if ( aAny.getValueTypeClass() == uno::TypeClass_BOOLEAN )
+ return *(sal_Bool*)aAny.getValue();
+ return FALSE;
+}
+
+// static
+sal_Int16 ScUnoHelpFunctions::GetInt16FromAny( const uno::Any& aAny )
+{
+ sal_Int16 nRet = 0;
+ if ( aAny >>= nRet )
+ return nRet;
+ return 0;
+}
+
+// static
+sal_Int32 ScUnoHelpFunctions::GetInt32FromAny( const uno::Any& aAny )
+{
+ sal_Int32 nRet = 0;
+ if ( aAny >>= nRet )
+ return nRet;
+ return 0;
+}
+
+// static
+sal_Int32 ScUnoHelpFunctions::GetEnumFromAny( const uno::Any& aAny )
+{
+ sal_Int32 nRet = 0;
+ if ( aAny.getValueTypeClass() == uno::TypeClass_ENUM )
+ nRet = *(sal_Int32*)aAny.getValue();
+ else
+ aAny >>= nRet;
+ return nRet;
+}
+
+// static
+void ScUnoHelpFunctions::SetBoolInAny( uno::Any& rAny, sal_Bool bValue )
+{
+ rAny.setValue( &bValue, getBooleanCppuType() );
+}
+
+// static
+void ScUnoHelpFunctions::SetOptionalPropertyValue(
+ Reference<beans::XPropertySet>& rPropSet, const sal_Char* pPropName, const Any& rVal )
+{
+ try
+ {
+ rPropSet->setPropertyValue(OUString::createFromAscii(pPropName), rVal);
+ }
+ catch (const beans::UnknownPropertyException&)
+ {
+ // ignored - not supported.
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScIndexEnumeration::ScIndexEnumeration(const uno::Reference<container::XIndexAccess>& rInd,
+ const rtl::OUString& rServiceName) :
+ xIndex( rInd ),
+ sServiceName(rServiceName),
+ nPos( 0 )
+{
+}
+
+ScIndexEnumeration::~ScIndexEnumeration()
+{
+}
+
+// XEnumeration
+
+sal_Bool SAL_CALL ScIndexEnumeration::hasMoreElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( nPos < xIndex->getCount() );
+}
+
+uno::Any SAL_CALL ScIndexEnumeration::nextElement() throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aReturn;
+ try
+ {
+ aReturn = xIndex->getByIndex(nPos++);
+ }
+ catch (lang::IndexOutOfBoundsException&)
+ {
+ throw container::NoSuchElementException();
+ }
+ return aReturn;
+}
+
+::rtl::OUString SAL_CALL ScIndexEnumeration::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii("ScIndexEnumeration");
+}
+
+sal_Bool SAL_CALL ScIndexEnumeration::supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return sServiceName == ServiceName;
+}
+
+::com::sun::star::uno::Sequence< ::rtl::OUString >
+ SAL_CALL ScIndexEnumeration::getSupportedServiceNames(void)
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > aRet(1);
+ ::rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = sServiceName;
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 ScEmptyEnumerationAccess::ScEmptyEnumerationAccess()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 ScEmptyEnumerationAccess::~ScEmptyEnumerationAccess()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 // XEnumerationAccess
+//UNUSED2008-05
+//UNUSED2008-05 uno::Reference<container::XEnumeration> SAL_CALL ScEmptyEnumerationAccess::createEnumeration()
+//UNUSED2008-05 throw(uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 ScUnoGuard aGuard;
+//UNUSED2008-05 return new ScEmptyEnumeration;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 uno::Type SAL_CALL ScEmptyEnumerationAccess::getElementType() throw(uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 ScUnoGuard aGuard;
+//UNUSED2008-05 return getCppuType((uno::Reference<uno::XInterface>*)0); // or what?
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 sal_Bool SAL_CALL ScEmptyEnumerationAccess::hasElements() throw(uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 return FALSE;
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 ScEmptyEnumeration::ScEmptyEnumeration()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 ScEmptyEnumeration::~ScEmptyEnumeration()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 // XEnumeration
+//UNUSED2008-05
+//UNUSED2008-05 sal_Bool SAL_CALL ScEmptyEnumeration::hasMoreElements() throw(uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 ScUnoGuard aGuard;
+//UNUSED2008-05 return FALSE;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 uno::Any SAL_CALL ScEmptyEnumeration::nextElement() throw(container::NoSuchElementException,
+//UNUSED2008-05 lang::WrappedTargetException, uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 ScUnoGuard aGuard;
+//UNUSED2008-05 return uno::Any();
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------------
+
+ScNameToIndexAccess::ScNameToIndexAccess( const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameAccess>& rNameObj ) :
+ xNameAccess( rNameObj )
+{
+ //! test for XIndexAccess interface at rNameObj, use that instead!
+
+ if ( xNameAccess.is() )
+ aNames = xNameAccess->getElementNames();
+}
+
+ScNameToIndexAccess::~ScNameToIndexAccess()
+{
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScNameToIndexAccess::getCount( ) throw(::com::sun::star::uno::RuntimeException)
+{
+ return aNames.getLength();
+}
+
+::com::sun::star::uno::Any SAL_CALL ScNameToIndexAccess::getByIndex( sal_Int32 nIndex )
+ throw(::com::sun::star::lang::IndexOutOfBoundsException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ if ( xNameAccess.is() && nIndex >= 0 && nIndex < aNames.getLength() )
+ return xNameAccess->getByName( aNames.getConstArray()[nIndex] );
+
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+// XElementAccess
+
+::com::sun::star::uno::Type SAL_CALL ScNameToIndexAccess::getElementType( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if ( xNameAccess.is() )
+ return xNameAccess->getElementType();
+ else
+ return uno::Type();
+}
+
+sal_Bool SAL_CALL ScNameToIndexAccess::hasElements( ) throw(::com::sun::star::uno::RuntimeException)
+{
+ return getCount() > 0;
+}
+
+//------------------------------------------------------------------------
+
+//UNUSED2008-05 ScPrintSettingsObj::ScPrintSettingsObj()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 ScPrintSettingsObj::~ScPrintSettingsObj()
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 // XPropertySet
+//UNUSED2008-05
+//UNUSED2008-05 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScPrintSettingsObj::getPropertySetInfo()
+//UNUSED2008-05 throw(uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 return NULL;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void SAL_CALL ScPrintSettingsObj::setPropertyValue(
+//UNUSED2008-05 const rtl::OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
+//UNUSED2008-05 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+//UNUSED2008-05 lang::IllegalArgumentException, lang::WrappedTargetException,
+//UNUSED2008-05 uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 //! later...
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 uno::Any SAL_CALL ScPrintSettingsObj::getPropertyValue( const rtl::OUString& /* aPropertyName */ )
+//UNUSED2008-05 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+//UNUSED2008-05 uno::RuntimeException)
+//UNUSED2008-05 {
+//UNUSED2008-05 //! later...
+//UNUSED2008-05 return uno::Any();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScPrintSettingsObj )
+
+
+//------------------------------------------------------------------------
+
+
+
diff --git a/sc/source/ui/unoobj/nameuno.cxx b/sc/source/ui/unoobj/nameuno.cxx
new file mode 100644
index 000000000000..75686df460d6
--- /dev/null
+++ b/sc/source/ui/unoobj/nameuno.cxx
@@ -0,0 +1,1131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svl/smplhint.hxx>
+
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+using namespace ::com::sun::star;
+
+
+#include "nameuno.hxx"
+#include "miscuno.hxx"
+#include "cellsuno.hxx"
+#include "convuno.hxx"
+#include "targuno.hxx"
+#include "tokenuno.hxx"
+#include "tokenarray.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "rangenam.hxx"
+//CHINA001 #include "namecrea.hxx" // NAME_TOP etc.
+#include "unoguard.hxx"
+#include "unonames.hxx"
+
+#include "scui_def.hxx" //CHINA001
+
+//------------------------------------------------------------------------
+
+const SfxItemPropertyMapEntry* lcl_GetNamedRangeMap()
+{
+ static SfxItemPropertyMapEntry aNamedRangeMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT), 0, &getCppuType((uno::Reference<awt::XBitmap>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), 0, &getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TOKENINDEX), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ISSHAREDFMLA), 0, &getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aNamedRangeMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+#define SCNAMEDRANGEOBJ_SERVICE "com.sun.star.sheet.NamedRange"
+
+SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj, "ScLabelRangeObj", "com.sun.star.sheet.LabelRange" )
+SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj, "ScLabelRangesObj", "com.sun.star.sheet.LabelRanges" )
+SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj, "ScNamedRangesObj", "com.sun.star.sheet.NamedRanges" )
+
+//------------------------------------------------------------------------
+
+sal_Bool lcl_UserVisibleName( const ScRangeData* pData )
+{
+ //! als Methode an ScRangeData
+
+ return ( pData && !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) );
+}
+
+//------------------------------------------------------------------------
+
+ScNamedRangeObj::ScNamedRangeObj(ScDocShell* pDocSh, const String& rNm) :
+ pDocShell( pDocSh ),
+ aName( rNm )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScNamedRangeObj::~ScNamedRangeObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScNamedRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Ref-Update interessiert nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // ungueltig geworden
+}
+
+// Hilfsfuntionen
+
+ScRangeData* ScNamedRangeObj::GetRangeData_Impl()
+{
+ ScRangeData* pRet = NULL;
+ if (pDocShell)
+ {
+ ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
+ if (pNames)
+ {
+ sal_uInt16 nPos = 0;
+ if (pNames->SearchName( aName, nPos ))
+ {
+ pRet = (*pNames)[nPos];
+ pRet->ValidateTabRefs(); // adjust relative tab refs to valid tables
+ }
+ }
+ }
+ return pRet;
+}
+
+// sheet::XNamedRange
+
+void ScNamedRangeObj::Modify_Impl( const String* pNewName, const ScTokenArray* pNewTokens, const String* pNewContent,
+ const ScAddress* pNewPos, const sal_uInt16* pNewType,
+ const formula::FormulaGrammar::Grammar eGrammar )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangeName* pNames = pDoc->GetRangeName();
+ if (pNames)
+ {
+ sal_uInt16 nPos = 0;
+ if (pNames->SearchName( aName, nPos ))
+ {
+ ScRangeName* pNewRanges = new ScRangeName( *pNames );
+ ScRangeData* pOld = (*pNames)[nPos];
+
+ String aInsName(pOld->GetName());
+ if (pNewName)
+ aInsName = *pNewName;
+ String aContent; // Content string based =>
+ pOld->GetSymbol( aContent, eGrammar); // no problems with changed positions and such.
+ if (pNewContent)
+ aContent = *pNewContent;
+ ScAddress aPos(pOld->GetPos());
+ if (pNewPos)
+ aPos = *pNewPos;
+ sal_uInt16 nType = pOld->GetType();
+ if (pNewType)
+ nType = *pNewType;
+
+ ScRangeData* pNew = NULL;
+ if ( pNewTokens )
+ pNew = new ScRangeData( pDoc, aInsName, *pNewTokens, aPos, nType );
+ else
+ pNew = new ScRangeData( pDoc, aInsName, aContent, aPos, nType, eGrammar );
+ pNew->SetIndex( pOld->GetIndex() );
+
+ pNewRanges->AtFree( nPos );
+ if ( pNewRanges->Insert(pNew) )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.SetNewRangeNames( pNewRanges, sal_True );
+
+ aName = aInsName; //! broadcast?
+ }
+ else
+ {
+ delete pNew; //! uno::Exception/Fehler oder so
+ delete pNewRanges;
+ }
+ }
+ }
+ }
+}
+
+
+rtl::OUString SAL_CALL ScNamedRangeObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return aName;
+}
+
+void SAL_CALL ScNamedRangeObj::setName( const rtl::OUString& aNewName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! Formeln anpassen ?????
+
+ String aNewStr(aNewName);
+ // GRAM_PODF_A1 for API compatibility.
+ Modify_Impl( &aNewStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
+
+ if ( aName != aNewStr ) // some error occured...
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+rtl::OUString SAL_CALL ScNamedRangeObj::getContent() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aContent;
+ ScRangeData* pData = GetRangeData_Impl();
+ if (pData)
+ // GRAM_PODF_A1 for API compatibility.
+ pData->GetSymbol( aContent,formula::FormulaGrammar::GRAM_PODF_A1);
+ return aContent;
+}
+
+void SAL_CALL ScNamedRangeObj::setContent( const rtl::OUString& aContent )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aContStr(aContent);
+ // GRAM_PODF_A1 for API compatibility.
+ Modify_Impl( NULL, NULL, &aContStr, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
+}
+
+void ScNamedRangeObj::SetContentWithGrammar( const ::rtl::OUString& aContent,
+ const formula::FormulaGrammar::Grammar eGrammar )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ String aContStr(aContent);
+ Modify_Impl( NULL, NULL, &aContStr, NULL, NULL, eGrammar );
+}
+
+table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAddress aPos;
+ ScRangeData* pData = GetRangeData_Impl();
+ if (pData)
+ aPos = pData->GetPos();
+ table::CellAddress aAddress;
+ aAddress.Column = aPos.Col();
+ aAddress.Row = aPos.Row();
+ aAddress.Sheet = aPos.Tab();
+ if (pDocShell)
+ {
+ SCTAB nDocTabs = pDocShell->GetDocument()->GetTableCount();
+ if ( aAddress.Sheet >= nDocTabs && nDocTabs > 0 )
+ {
+ // Even after ValidateTabRefs, the position can be invalid if
+ // the content points to preceding tables. The resulting string
+ // is invalid in any case, so the position is just shifted.
+ aAddress.Sheet = nDocTabs - 1;
+ }
+ }
+ return aAddress;
+}
+
+void SAL_CALL ScNamedRangeObj::setReferencePosition( const table::CellAddress& aReferencePosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAddress aPos( (SCCOL)aReferencePosition.Column, (SCROW)aReferencePosition.Row, aReferencePosition.Sheet );
+ // GRAM_PODF_A1 for API compatibility.
+ Modify_Impl( NULL, NULL, NULL, &aPos, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
+}
+
+sal_Int32 SAL_CALL ScNamedRangeObj::getType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Int32 nType=0;
+ ScRangeData* pData = GetRangeData_Impl();
+ if (pData)
+ {
+ // do not return internal RT_* flags
+ // see property 'IsSharedFormula' for RT_SHARED
+ if ( pData->HasType(RT_CRITERIA) ) nType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
+ if ( pData->HasType(RT_PRINTAREA) ) nType |= sheet::NamedRangeFlag::PRINT_AREA;
+ if ( pData->HasType(RT_COLHEADER) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER;
+ if ( pData->HasType(RT_ROWHEADER) ) nType |= sheet::NamedRangeFlag::ROW_HEADER;
+ }
+ return nType;
+}
+
+void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType ) throw(uno::RuntimeException)
+{
+ // see property 'IsSharedFormula' for RT_SHARED
+ ScUnoGuard aGuard;
+ sal_uInt16 nNewType = RT_NAME;
+ if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
+ if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
+ if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
+ if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
+
+ // GRAM_PODF_A1 for API compatibility.
+ Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
+}
+
+// XFormulaTokens
+
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence<sheet::FormulaToken> aSequence;
+ ScRangeData* pData = GetRangeData_Impl();
+ if (pData && pDocShell)
+ {
+ ScTokenArray* pTokenArray = pData->GetCode();
+ if ( pTokenArray )
+ (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray );
+ }
+ return aSequence;
+}
+
+void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if( pDocShell )
+ {
+ ScTokenArray aTokenArray;
+ (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens );
+ // GRAM_PODF_A1 for API compatibility.
+ Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, formula::FormulaGrammar::GRAM_PODF_A1 );
+ }
+}
+
+
+// XCellRangeSource
+
+uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRange aRange;
+ ScRangeData* pData = GetRangeData_Impl();
+ if ( pData && pData->IsValidReference( aRange ) )
+ {
+ //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ???
+
+ if ( aRange.aStart == aRange.aEnd )
+ return new ScCellObj( pDocShell, aRange.aStart );
+ else
+ return new ScCellRangeObj( pDocShell, aRange );
+ }
+ return NULL;
+}
+
+// beans::XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScNamedRangeObj::setPropertyValue(
+ const rtl::OUString& rPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) )
+ {
+ bool bIsShared = false;
+ if( aValue >>= bIsShared )
+ {
+ sal_uInt16 nNewType = bIsShared ? RT_SHARED : RT_NAME;
+ Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
+ }
+ }
+}
+
+uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const rtl::OUString& rPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aRet;
+ if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPBIT ) )
+ {
+ // no target bitmaps for individual entries (would be all equal)
+ // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME );
+ }
+ else if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPNAME ) )
+ aRet <<= rtl::OUString( aName );
+ else if ( rPropertyName.equalsAscii( SC_UNONAME_TOKENINDEX ) )
+ {
+ // get index for use in formula tokens (read-only)
+ ScRangeData* pData = GetRangeData_Impl();
+ if (pData)
+ aRet <<= static_cast<sal_Int32>(pData->GetIndex());
+ }
+ else if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) )
+ {
+ if( ScRangeData* pData = GetRangeData_Impl() )
+ aRet <<= static_cast< bool >( pData->HasType( RT_SHARED ) );
+ }
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj )
+
+// lang::XServiceInfo
+
+rtl::OUString SAL_CALL ScNamedRangeObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScNamedRangeObj" ) );
+}
+
+sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ return rServiceName.equalsAscii( SCNAMEDRANGEOBJ_SERVICE ) ||
+ rServiceName.equalsAscii( SCLINKTARGET_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ aRet[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCNAMEDRANGEOBJ_SERVICE ) );
+ aRet[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCLINKTARGET_SERVICE ) );
+ return aRet;
+}
+
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScNamedRangeObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScNamedRangeObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScNamedRangeObj* ScNamedRangeObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScNamedRangeObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScNamedRangeObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScNamedRangesObj::~ScNamedRangesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScNamedRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// sheet::XNamedRanges
+
+ScNamedRangeObj* ScNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
+{
+ if (pDocShell)
+ {
+ ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
+ if (pNames)
+ {
+ sal_uInt16 nCount = pNames->GetCount();
+ sal_uInt16 nPos = 0;
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ ScRangeData* pData = (*pNames)[i];
+ if (lcl_UserVisibleName(pData)) // interne weglassen
+ {
+ if ( nPos == nIndex )
+ return new ScNamedRangeObj( pDocShell, pData->GetName() );
+ ++nPos;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+ScNamedRangeObj* ScNamedRangesObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ if ( pDocShell && hasByName(aName) )
+ return new ScNamedRangeObj( pDocShell, String(aName) );
+ return NULL;
+}
+
+void SAL_CALL ScNamedRangesObj::addNewByName( const rtl::OUString& aName,
+ const rtl::OUString& aContent, const table::CellAddress& aPosition,
+ sal_Int32 nUnoType ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr(aName);
+ String aContStr(aContent);
+ ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, aPosition.Sheet );
+
+ sal_uInt16 nNewType = RT_NAME;
+ if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
+ if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
+ if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
+ if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
+
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangeName* pNames = pDoc->GetRangeName();
+ USHORT nIndex = 0;
+ if (pNames && !pNames->SearchName(aNameStr, nIndex))
+ {
+ ScRangeName* pNewRanges = new ScRangeName( *pNames );
+ // GRAM_PODF_A1 for API compatibility.
+ ScRangeData* pNew = new ScRangeData( pDoc, aNameStr, aContStr,
+ aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
+ if ( pNewRanges->Insert(pNew) )
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.SetNewRangeNames( pNewRanges, sal_True );
+ bDone = TRUE;
+ }
+ else
+ {
+ delete pNew;
+ delete pNewRanges;
+ }
+ }
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource,
+ sheet::Border aBorder ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! das darf kein enum sein, weil mehrere Bits gesetzt sein koennen !!!
+
+ sal_Bool bTop = ( aBorder == sheet::Border_TOP );
+ sal_Bool bLeft = ( aBorder == sheet::Border_LEFT );
+ sal_Bool bBottom = ( aBorder == sheet::Border_BOTTOM );
+ sal_Bool bRight = ( aBorder == sheet::Border_RIGHT );
+
+ ScRange aRange;
+ ScUnoConversion::FillScRange( aRange, aSource );
+
+ sal_uInt16 nFlags = 0;
+ if (bTop) nFlags |= NAME_TOP;
+ if (bLeft) nFlags |= NAME_LEFT;
+ if (bBottom) nFlags |= NAME_BOTTOM;
+ if (bRight) nFlags |= NAME_RIGHT;
+
+ if (nFlags)
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.CreateNames( aRange, nFlags, sal_True );
+ }
+}
+
+void SAL_CALL ScNamedRangesObj::removeByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
+ if (pNames)
+ {
+ String aString(aName);
+ sal_uInt16 nPos = 0;
+ if (pNames->SearchName( aString, nPos ))
+ if ( lcl_UserVisibleName((*pNames)[nPos]) )
+ {
+ ScRangeName* pNewRanges = new ScRangeName(*pNames);
+ pNewRanges->AtFree(nPos);
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.SetNewRangeNames( pNewRanges, sal_True );
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScAddress aPos( (SCCOL)aOutputPosition.Column, (SCROW)aOutputPosition.Row, aOutputPosition.Sheet );
+ if (pDocShell)
+ {
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.InsertNameList( aPos, sal_True );
+ }
+}
+
+// container::XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.NamedRangesEnumeration")));
+}
+
+// container::XIndexAccess
+
+sal_Int32 SAL_CALL ScNamedRangesObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ long nRet = 0;
+ if (pDocShell)
+ {
+ ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
+ if (pNames)
+ {
+ sal_uInt16 nCount = pNames->GetCount();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ if (lcl_UserVisibleName( (*pNames)[i] )) // interne weglassen
+ ++nRet;
+ }
+ }
+ return nRet;
+}
+
+uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< sheet::XNamedRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
+ if ( xRange.is() )
+ return uno::makeAny(xRange);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScNamedRangesObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::getCppuType((const uno::Reference< sheet::XNamedRange >*)0); // muss zu getByIndex passen
+}
+
+sal_Bool SAL_CALL ScNamedRangesObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+uno::Any SAL_CALL ScNamedRangesObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< sheet::XNamedRange > xRange(GetObjectByName_Impl(aName));
+ if ( xRange.is() )
+ return uno::makeAny(xRange);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangesObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
+ if (pNames)
+ {
+ long nVisCount = getCount(); // Namen mit lcl_UserVisibleName
+ uno::Sequence<rtl::OUString> aSeq(nVisCount);
+ rtl::OUString* pAry = aSeq.getArray();
+
+ sal_uInt16 nCount = pNames->GetCount();
+ sal_uInt16 nVisPos = 0;
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ ScRangeData* pData = (*pNames)[i];
+ if ( lcl_UserVisibleName(pData) )
+ pAry[nVisPos++] = pData->GetName();
+ }
+// DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?");
+ return aSeq;
+ }
+ }
+ return uno::Sequence<rtl::OUString>(0);
+}
+
+sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
+ if (pNames)
+ {
+ sal_uInt16 nPos = 0;
+ if (pNames->SearchName( String(aName), nPos ))
+ if ( lcl_UserVisibleName((*pNames)[nPos]) )
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+/** called from the XActionLockable interface methods on initial locking */
+void ScNamedRangesObj::lock()
+{
+ pDocShell->GetDocument()->CompileNameFormula( TRUE ); // CreateFormulaString
+}
+
+/** called from the XActionLockable interface methods on final unlock */
+void ScNamedRangesObj::unlock()
+{
+ pDocShell->GetDocument()->CompileNameFormula( FALSE ); // CompileFormulaString
+}
+
+// document::XActionLockable
+
+sal_Bool ScNamedRangesObj::isActionLocked() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return pDocShell->GetDocument()->GetNamedRangesLockCount() != 0;
+}
+
+void ScNamedRangesObj::addActionLock() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
+ ++nLockCount;
+ if ( nLockCount == 1 )
+ {
+ lock();
+ }
+ pDoc->SetNamedRangesLockCount( nLockCount );
+}
+
+void ScNamedRangesObj::removeActionLock() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
+ if ( nLockCount > 0 )
+ {
+ --nLockCount;
+ if ( nLockCount == 0 )
+ {
+ unlock();
+ }
+ pDoc->SetNamedRangesLockCount( nLockCount );
+ }
+}
+
+void ScNamedRangesObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( nLock >= 0 )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
+ if ( nLock == 0 && nLockCount > 0 )
+ {
+ unlock();
+ }
+ if ( nLock > 0 && nLockCount == 0 )
+ {
+ lock();
+ }
+ pDoc->SetNamedRangesLockCount( nLock );
+ }
+}
+
+sal_Int16 ScNamedRangesObj::resetActionLocks() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
+ if ( nLockCount > 0 )
+ {
+ unlock();
+ }
+ pDoc->SetNamedRangesLockCount( 0 );
+ return nLockCount;
+}
+
+//------------------------------------------------------------------------
+
+ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, sal_Bool bCol, const ScRange& rR) :
+ pDocShell( pDocSh ),
+ bColumn( bCol ),
+ aRange( rR )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScLabelRangeObj::~ScLabelRangeObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ //! Ref-Update !!!
+
+ if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // ungueltig geworden
+}
+
+// Hilfsfuntionen
+
+ScRangePair* ScLabelRangeObj::GetData_Impl()
+{
+ ScRangePair* pRet = NULL;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
+ if (pList)
+ pRet = pList->Find( aRange );
+ }
+ return pRet;
+}
+
+void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData )
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
+ if (pOldList)
+ {
+ ScRangePairListRef xNewList(pOldList->Clone());
+ ScRangePair* pEntry = xNewList->Find( aRange );
+ if (pEntry)
+ {
+ xNewList->Remove( pEntry ); // nur aus der Liste entfernt, nicht geloescht
+
+ if ( pLabel )
+ pEntry->GetRange(0) = *pLabel;
+ if ( pData )
+ pEntry->GetRange(1) = *pData;
+
+ xNewList->Join( *pEntry );
+ delete pEntry;
+
+ if (bColumn)
+ pDoc->GetColNameRangesRef() = xNewList;
+ else
+ pDoc->GetRowNameRangesRef() = xNewList;
+
+ pDoc->CompileColRowNameFormula();
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ pDocShell->SetDocumentModified();
+
+ //! Undo ?!?! (hier und aus Dialog)
+
+ if ( pLabel )
+ aRange = *pLabel; // Objekt anpassen, um Range wiederzufinden
+ }
+ }
+ }
+}
+
+// sheet::XLabelRange
+
+table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aRet;
+ ScRangePair* pData = GetData_Impl();
+ if (pData)
+ ScUnoConversion::FillApiRange( aRet, pData->GetRange(0) );
+ return aRet;
+}
+
+void SAL_CALL ScLabelRangeObj::setLabelArea( const table::CellRangeAddress& aLabelArea )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRange aLabelRange;
+ ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
+ Modify_Impl( &aLabelRange, NULL );
+}
+
+table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aRet;
+ ScRangePair* pData = GetData_Impl();
+ if (pData)
+ ScUnoConversion::FillApiRange( aRet, pData->GetRange(1) );
+ return aRet;
+}
+
+void SAL_CALL ScLabelRangeObj::setDataArea( const table::CellRangeAddress& aDataArea )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScRange aDataRange;
+ ScUnoConversion::FillScRange( aDataRange, aDataArea );
+ Modify_Impl( NULL, &aDataRange );
+}
+
+//------------------------------------------------------------------------
+
+ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, sal_Bool bCol) :
+ pDocShell( pDocSh ),
+ bColumn( bCol )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScLabelRangesObj::~ScLabelRangesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScLabelRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// sheet::XLabelRanges
+
+ScLabelRangeObj* ScLabelRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
+ if ( pList && nIndex < pList->Count() )
+ {
+ ScRangePair* pData = pList->GetObject(nIndex);
+ if (pData)
+ return new ScLabelRangeObj( pDocShell, bColumn, pData->GetRange(0) );
+ }
+ }
+ return NULL;
+}
+
+void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea,
+ const table::CellRangeAddress& aDataArea )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
+ if (pOldList)
+ {
+ ScRangePairListRef xNewList(pOldList->Clone());
+
+ ScRange aLabelRange;
+ ScRange aDataRange;
+ ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
+ ScUnoConversion::FillScRange( aDataRange, aDataArea );
+ xNewList->Join( ScRangePair( aLabelRange, aDataRange ) );
+
+ if (bColumn)
+ pDoc->GetColNameRangesRef() = xNewList;
+ else
+ pDoc->GetRowNameRangesRef() = xNewList;
+
+ pDoc->CompileColRowNameFormula();
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ pDocShell->SetDocumentModified();
+
+ //! Undo ?!?! (hier und aus Dialog)
+ }
+ }
+}
+
+void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bDone = FALSE;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
+
+ if ( pOldList && nIndex >= 0 && nIndex < (sal_Int32)pOldList->Count() )
+ {
+ ScRangePairListRef xNewList(pOldList->Clone());
+
+ ScRangePair* pEntry = xNewList->GetObject( nIndex );
+ if (pEntry)
+ {
+ xNewList->Remove( pEntry );
+ delete pEntry;
+
+ if (bColumn)
+ pDoc->GetColNameRangesRef() = xNewList;
+ else
+ pDoc->GetRowNameRangesRef() = xNewList;
+
+ pDoc->CompileColRowNameFormula();
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ pDocShell->SetDocumentModified();
+ bDone = TRUE;
+
+ //! Undo ?!?! (hier und aus Dialog)
+ }
+ }
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+
+// container::XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.LabelRangesEnumeration")));
+}
+
+// container::XIndexAccess
+
+sal_Int32 SAL_CALL ScLabelRangesObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
+ if (pList)
+ return pList->Count();
+ }
+ return 0;
+}
+
+uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< sheet::XLabelRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
+ if ( xRange.is() )
+ return uno::makeAny(xRange);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScLabelRangesObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::getCppuType((const uno::Reference< sheet::XLabelRange >*)0); // muss zu getByIndex passen
+
+}
+
+sal_Bool SAL_CALL ScLabelRangesObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+//------------------------------------------------------------------------
+
+
+
diff --git a/sc/source/ui/unoobj/notesuno.cxx b/sc/source/ui/unoobj/notesuno.cxx
new file mode 100644
index 000000000000..c5dd11977478
--- /dev/null
+++ b/sc/source/ui/unoobj/notesuno.cxx
@@ -0,0 +1,729 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svl/smplhint.hxx>
+
+
+#include "rangelst.hxx"
+#include <editeng/unotext.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdobj.hxx>
+#include "notesuno.hxx"
+#include "textuno.hxx"
+#include "cellsuno.hxx" // getParent
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "hints.hxx"
+#include "editsrc.hxx"
+#include "miscuno.hxx"
+
+// setVisible:
+#include <svx/svdundo.hxx>
+#include "drwlayer.hxx"
+#include "detfunc.hxx"
+#include "undocell.hxx"
+#include "unoguard.hxx"
+#include "userdat.hxx"
+#include <editeng/outlobj.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <com/sun/star/drawing/XShapeDescriptor.hpp>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+// keine Properties fuer Text in Notizen
+const SvxItemPropertySet* lcl_GetAnnotationPropertySet()
+{
+ static SfxItemPropertyMapEntry aAnnotationPropertyMap_Impl[] =
+ {
+ {0,0,0,0,0,0}
+ };
+ static SvxItemPropertySet aAnnotationPropertySet_Impl( aAnnotationPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
+ return &aAnnotationPropertySet_Impl;
+}
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScAnnotationObj, "ScAnnotationObj", "com.sun.star.sheet.CellAnnotation" )
+SC_SIMPLE_SERVICE_INFO( ScAnnotationShapeObj, "ScAnnotationShapeObj", "com.sun.star.sheet.CellAnnotationShape" )
+
+//------------------------------------------------------------------------
+
+ScAnnotationObj::ScAnnotationObj(ScDocShell* pDocSh, const ScAddress& rPos) :
+ pDocShell( pDocSh ),
+ aCellPos( rPos ),
+ pUnoText( NULL )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ // pUnoText is allocated on demand (GetUnoText)
+ // can't be aggregated because getString/setString is handled here
+}
+
+ScAnnotationObj::~ScAnnotationObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+
+ if (pUnoText)
+ pUnoText->release();
+}
+
+void ScAnnotationObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+
+// XChild
+
+uno::Reference<uno::XInterface> SAL_CALL ScAnnotationObj::getParent() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // Parent der Notiz ist die zugehoerige Zelle
+ //! existierendes Objekt finden und zurueckgeben ???
+
+ if (pDocShell)
+ return (cppu::OWeakObject*)new ScCellObj( pDocShell, aCellPos );
+
+ return NULL;
+}
+
+void SAL_CALL ScAnnotationObj::setParent( const uno::Reference<uno::XInterface>& /* Parent */ )
+ throw(lang::NoSupportException, uno::RuntimeException)
+{
+ // hamma nich
+ //! Exception oder so ??!
+}
+
+// XSimpleText
+
+uno::Reference<text::XTextCursor> SAL_CALL ScAnnotationObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // Notizen brauchen keine Extrawurst
+ return GetUnoText().createTextCursor();
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScAnnotationObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // Notizen brauchen keine Extrawurst
+ return GetUnoText().createTextCursorByRange(aTextPosition);
+}
+
+rtl::OUString SAL_CALL ScAnnotationObj::getString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getString();
+}
+
+void SAL_CALL ScAnnotationObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().setString(aText);
+}
+
+void SAL_CALL ScAnnotationObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().insertString( xRange, aString, bAbsorb );
+}
+
+void SAL_CALL ScAnnotationObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+}
+
+uno::Reference<text::XText> SAL_CALL ScAnnotationObj::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getText();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScAnnotationObj::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getStart();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScAnnotationObj::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getEnd();
+}
+
+// XSheetAnnotation
+
+table::CellAddress SAL_CALL ScAnnotationObj::getPosition() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellAddress aAdr;
+ aAdr.Sheet = aCellPos.Tab();
+ aAdr.Column = aCellPos.Col();
+ aAdr.Row = aCellPos.Row();
+ return aAdr;
+}
+
+rtl::OUString SAL_CALL ScAnnotationObj::getAuthor() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScPostIt* pNote = ImplGetNote();
+ 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() : rtl::OUString();
+}
+
+sal_Bool SAL_CALL ScAnnotationObj::getIsVisible() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ const ScPostIt* pNote = ImplGetNote();
+ return pNote && pNote->IsCaptionShown();
+}
+
+void SAL_CALL ScAnnotationObj::setIsVisible( sal_Bool bIsVisible ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // show/hide note with undo action
+ if( pDocShell )
+ pDocShell->GetDocFunc().ShowNote( aCellPos, bIsVisible );
+}
+
+// XSheetAnnotationShapeSupplier
+uno::Reference < drawing::XShape > SAL_CALL ScAnnotationObj::getAnnotationShape()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScAnnotationShapeObj(pDocShell, aCellPos);
+}
+
+SvxUnoText& ScAnnotationObj::GetUnoText()
+{
+ if (!pUnoText)
+ {
+ ScAnnotationEditSource aEditSource( pDocShell, aCellPos );
+ pUnoText = new SvxUnoText( &aEditSource, lcl_GetAnnotationPropertySet(),
+ uno::Reference<text::XText>() );
+ pUnoText->acquire();
+ }
+ return *pUnoText;
+}
+
+const ScPostIt* ScAnnotationObj::ImplGetNote() const
+{
+ return pDocShell ? pDocShell->GetDocument()->GetNote( aCellPos ) : 0;
+}
+//------------------------------------------------------------------------
+
+ScAnnotationShapeObj::ScAnnotationShapeObj(ScDocShell* pDocSh, const ScAddress& rPos) :
+ pDocShell( pDocSh ),
+ aCellPos( rPos ),
+ pUnoText( NULL )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ // pUnoText is allocated on demand (GetUnoText)
+ // can't be aggregated because getString/setString is handled here
+}
+
+SvxUnoText& ScAnnotationShapeObj::GetUnoText()
+{
+ if (!pUnoText)
+ {
+ ScAnnotationEditSource aEditSource( pDocShell, aCellPos );
+ pUnoText = new SvxUnoText( &aEditSource, lcl_GetAnnotationPropertySet(),
+ uno::Reference<text::XText>() );
+ pUnoText->acquire();
+ }
+ return *pUnoText;
+}
+
+uno::Reference < drawing::XShape > ScAnnotationShapeObj::GetXShape()
+{
+ if (!xShape.is())
+ if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos ) )
+ if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ) )
+ xShape.set( pCaption->getUnoShape(), uno::UNO_QUERY );
+ return xShape;
+}
+
+ScAnnotationShapeObj::~ScAnnotationShapeObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+ if (pUnoText)
+ pUnoText->release();
+}
+
+void ScAnnotationShapeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+
+// XChild
+
+uno::Reference<uno::XInterface> SAL_CALL ScAnnotationShapeObj::getParent() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // Parent der Notiz ist die zugehoerige Zelle
+ //! existierendes Objekt finden und zurueckgeben ???
+
+ if (pDocShell)
+ return (cppu::OWeakObject*)new ScCellObj( pDocShell, aCellPos );
+
+ return NULL;
+}
+
+void SAL_CALL ScAnnotationShapeObj::setParent( const uno::Reference<uno::XInterface>& /* Parent */ )
+ throw(lang::NoSupportException, uno::RuntimeException)
+{
+ // hamma nich
+ //! Exception oder so ??!
+}
+
+// XElementAccess
+uno::Type SAL_CALL ScAnnotationShapeObj::getElementType( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ return GetUnoText().getElementType();
+}
+
+sal_Bool SAL_CALL ScAnnotationShapeObj::hasElements( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ return GetUnoText().hasElements();
+}
+
+// XEnumerationAccess
+uno::Reference< container::XEnumeration > SAL_CALL ScAnnotationShapeObj::createEnumeration( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ return GetUnoText().createEnumeration();
+}
+
+// XTextRangeMover
+void SAL_CALL ScAnnotationShapeObj::moveTextRange( const uno::Reference< text::XTextRange >& xRange, sal_Int16 nParagraphs )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetUnoText().moveTextRange( xRange, nParagraphs );
+}
+
+// XText
+void SAL_CALL ScAnnotationShapeObj::insertTextContent( const uno::Reference< text::XTextRange >& xRange,
+ const uno::Reference< text::XTextContent >& xContent, sal_Bool bAbsorb )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetUnoText().insertTextContent( xRange, xContent, bAbsorb );
+}
+
+void SAL_CALL ScAnnotationShapeObj::removeTextContent( const uno::Reference< text::XTextContent >& xContent )
+ throw (container::NoSuchElementException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetUnoText().removeTextContent( xContent );
+}
+
+// XSimpleText
+
+uno::Reference<text::XTextCursor> SAL_CALL ScAnnotationShapeObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // Notizen brauchen keine Extrawurst
+ return GetUnoText().createTextCursor();
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScAnnotationShapeObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // Notizen brauchen keine Extrawurst
+ return GetUnoText().createTextCursorByRange(aTextPosition);
+}
+
+rtl::OUString SAL_CALL ScAnnotationShapeObj::getString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getString();
+}
+
+void SAL_CALL ScAnnotationShapeObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().setString(aText);
+}
+
+void SAL_CALL ScAnnotationShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().insertString( xRange, aString, bAbsorb );
+}
+
+void SAL_CALL ScAnnotationShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetUnoText().insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+}
+
+uno::Reference<text::XText> SAL_CALL ScAnnotationShapeObj::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getText();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScAnnotationShapeObj::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getStart();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScAnnotationShapeObj::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return GetUnoText().getEnd();
+}
+
+// XShapeDescriptor
+::rtl::OUString SAL_CALL ScAnnotationShapeObj::getShapeType( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < drawing::XShapeDescriptor > xDesc(GetXShape(), uno::UNO_QUERY);
+ if (xDesc.is())
+ return xDesc->getShapeType();
+ return rtl::OUString();
+}
+
+// XShape
+awt::Point SAL_CALL ScAnnotationShapeObj::getPosition( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetXShape();
+ return xShape.is() ? xShape->getPosition() : awt::Point();
+}
+
+void SAL_CALL ScAnnotationShapeObj::setPosition( const awt::Point& aPosition )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetXShape();
+ if( xShape.is() )
+ xShape->setPosition(aPosition);
+}
+
+awt::Size SAL_CALL ScAnnotationShapeObj::getSize( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetXShape();
+ return xShape.is() ? xShape->getSize() : awt::Size();
+}
+
+void SAL_CALL ScAnnotationShapeObj::setSize( const awt::Size& aSize )
+ throw (beans::PropertyVetoException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ GetXShape();
+ if( xShape.is() )
+ xShape->setSize(aSize);
+}
+
+// XPropertyState
+beans::PropertyState SAL_CALL ScAnnotationShapeObj::getPropertyState( const rtl::OUString& PropertyName )
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY);
+ if (xState.is())
+ return xState->getPropertyState( PropertyName );
+ return beans::PropertyState();
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL ScAnnotationShapeObj::getPropertyStates(
+ const uno::Sequence< rtl::OUString >& aPropertyName )
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY);
+ if (xState.is())
+ return xState->getPropertyStates( aPropertyName );
+ return uno::Sequence< beans::PropertyState >();
+}
+
+void SAL_CALL ScAnnotationShapeObj::setPropertyToDefault( const ::rtl::OUString& PropertyName )
+ throw (::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY);
+ if (xState.is())
+ xState->setPropertyToDefault( PropertyName );
+}
+
+uno::Any SAL_CALL ScAnnotationShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY);
+ if (xState.is())
+ return xState->getPropertyDefault( aPropertyName );
+ return uno::Any();
+}
+
+// XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL ScAnnotationShapeObj::getPropertySetInfo( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->getPropertySetInfo();
+ return uno::Reference< beans::XPropertySetInfo >();
+}
+
+void SAL_CALL ScAnnotationShapeObj::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw (beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ xProp->setPropertyValue( aPropertyName, aValue );
+}
+
+uno::Any SAL_CALL ScAnnotationShapeObj::getPropertyValue( const rtl::OUString& PropertyName )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->getPropertyValue( PropertyName );
+ return uno::Any();
+}
+
+void SAL_CALL ScAnnotationShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& xListener )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->addPropertyChangeListener( aPropertyName, xListener );
+}
+
+void SAL_CALL ScAnnotationShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& aListener )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->removePropertyChangeListener( aPropertyName, aListener );
+}
+
+void SAL_CALL ScAnnotationShapeObj::addVetoableChangeListener( const rtl::OUString& PropertyName,
+ const uno::Reference< beans::XVetoableChangeListener >& aListener )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->addVetoableChangeListener( PropertyName, aListener );
+}
+
+void SAL_CALL ScAnnotationShapeObj::removeVetoableChangeListener( const rtl::OUString& PropertyName,
+ const uno::Reference< beans::XVetoableChangeListener >& aListener )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->removeVetoableChangeListener( PropertyName, aListener );
+}
+
+ // XMultiPropertySet
+void SAL_CALL ScAnnotationShapeObj::setPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames,
+ const uno::Sequence< uno::Any >& aValues )
+ throw (beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ xProp->setPropertyValues( aPropertyNames, aValues );
+}
+
+uno::Sequence< uno::Any > SAL_CALL ScAnnotationShapeObj::getPropertyValues(
+ const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ return xProp->getPropertyValues( aPropertyNames );
+ return uno::Sequence< uno::Any >();
+}
+
+void SAL_CALL ScAnnotationShapeObj::addPropertiesChangeListener( const uno::Sequence< rtl::OUString >& aPropertyNames,
+ const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ xProp->addPropertiesChangeListener( aPropertyNames, xListener );
+}
+
+void SAL_CALL ScAnnotationShapeObj::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ xProp->removePropertiesChangeListener( xListener );
+}
+
+void SAL_CALL ScAnnotationShapeObj::firePropertiesChangeEvent( const uno::Sequence< rtl::OUString >& aPropertyNames,
+ const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY);
+ if (xProp.is())
+ xProp->firePropertiesChangeEvent( aPropertyNames, xListener );
+}
+
+ // XComponent
+void SAL_CALL ScAnnotationShapeObj::dispose( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < lang::XComponent > xComp (GetXShape(), uno::UNO_QUERY);
+ if (xComp.is())
+ xComp->dispose();
+ if (xShape.is())
+ xShape.clear();
+}
+
+void SAL_CALL ScAnnotationShapeObj::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < lang::XComponent > xComp (GetXShape(), uno::UNO_QUERY);
+ if (xComp.is())
+ xComp->addEventListener( xListener );
+}
+
+void SAL_CALL ScAnnotationShapeObj::removeEventListener( const uno::Reference< lang::XEventListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference < lang::XComponent > xComp (GetXShape(), uno::UNO_QUERY);
+ if (xComp.is())
+ xComp->removeEventListener( aListener );
+}
+
+//------------------------------------------------------------------------
+
+
+
+
diff --git a/sc/source/ui/unoobj/optuno.cxx b/sc/source/ui/unoobj/optuno.cxx
new file mode 100644
index 000000000000..0d277fdb19fe
--- /dev/null
+++ b/sc/source/ui/unoobj/optuno.cxx
@@ -0,0 +1,237 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svl/itemprop.hxx>
+
+#include <com/sun/star/util/Date.hpp>
+
+#include "optuno.hxx"
+#include "miscuno.hxx"
+#include "unonames.hxx"
+#include "docoptio.hxx"
+#include "unoguard.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+// static
+const SfxItemPropertyMapEntry* ScDocOptionsHelper::GetPropertyMap()
+{
+ static SfxItemPropertyMapEntry aMap[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_CALCASSHOWN), PROP_UNO_CALCASSHOWN , &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_DEFTABSTOP), PROP_UNO_DEFTABSTOP , &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_IGNORECASE), PROP_UNO_IGNORECASE , &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ITERENABLED), PROP_UNO_ITERENABLED , &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ITERCOUNT), PROP_UNO_ITERCOUNT , &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ITEREPSILON), PROP_UNO_ITEREPSILON , &getCppuType((double*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_LOOKUPLABELS), PROP_UNO_LOOKUPLABELS, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_MATCHWHOLE), PROP_UNO_MATCHWHOLE , &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_NULLDATE), PROP_UNO_NULLDATE , &getCppuType((util::Date*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SPELLONLINE), PROP_UNO_SPELLONLINE , &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_STANDARDDEC), PROP_UNO_STANDARDDEC , &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_REGEXENABLED), PROP_UNO_REGEXENABLED, &getBooleanCppuType(), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aMap;
+}
+
+// static
+sal_Bool ScDocOptionsHelper::setPropertyValue( ScDocOptions& rOptions,
+ const SfxItemPropertyMap& rPropMap,
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+{
+ //! use map (with new identifiers)
+
+ const SfxItemPropertySimpleEntry* pEntry = rPropMap.getByName(aPropertyName );
+ if( !pEntry || !pEntry->nWID )
+ return sal_False;
+ switch( pEntry->nWID )
+ {
+ case PROP_UNO_CALCASSHOWN :
+ rOptions.SetCalcAsShown( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ case PROP_UNO_DEFTABSTOP :
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ rOptions.SetTabDistance( nIntVal );
+ }
+ break;
+ case PROP_UNO_IGNORECASE :
+ rOptions.SetIgnoreCase( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ case PROP_UNO_ITERENABLED:
+ rOptions.SetIter( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ case PROP_UNO_ITERCOUNT :
+ {
+ sal_Int32 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ rOptions.SetIterCount( (USHORT)nIntVal );
+ }
+ break;
+ case PROP_UNO_ITEREPSILON :
+ {
+ double fDoubleVal = 0;
+ if ( aValue >>= fDoubleVal )
+ rOptions.SetIterEps( fDoubleVal );
+ }
+ break;
+ case PROP_UNO_LOOKUPLABELS :
+ rOptions.SetLookUpColRowNames( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ case PROP_UNO_MATCHWHOLE :
+ rOptions.SetMatchWholeCell( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ case PROP_UNO_NULLDATE:
+ {
+ util::Date aDate;
+ if ( aValue >>= aDate )
+ rOptions.SetDate( aDate.Day, aDate.Month, aDate.Year );
+ }
+ break;
+ case PROP_UNO_SPELLONLINE:
+ rOptions.SetAutoSpell( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ case PROP_UNO_STANDARDDEC:
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ rOptions.SetStdPrecision( nIntVal );
+ }
+ break;
+ case PROP_UNO_REGEXENABLED:
+ rOptions.SetFormulaRegexEnabled( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ break;
+ default:;
+ }
+ return sal_True;
+}
+
+// static
+uno::Any ScDocOptionsHelper::getPropertyValue(
+ const ScDocOptions& rOptions,
+ const SfxItemPropertyMap& rPropMap,
+ const rtl::OUString& aPropertyName )
+{
+ uno::Any aRet;
+ const SfxItemPropertySimpleEntry* pEntry = rPropMap.getByName( aPropertyName );
+ if( !pEntry || !pEntry->nWID )
+ return aRet;
+ switch( pEntry->nWID )
+ {
+ case PROP_UNO_CALCASSHOWN :
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsCalcAsShown() );
+ break;
+ case PROP_UNO_DEFTABSTOP :
+ aRet <<= (sal_Int16)( rOptions.GetTabDistance() );
+ break;
+ case PROP_UNO_IGNORECASE :
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsIgnoreCase() );
+ break;
+ case PROP_UNO_ITERENABLED:
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsIter() );
+ break;
+ case PROP_UNO_ITERCOUNT:
+ aRet <<= (sal_Int32)( rOptions.GetIterCount() );
+ break;
+ case PROP_UNO_ITEREPSILON:
+ aRet <<= (double)( rOptions.GetIterEps() );
+ break;
+ case PROP_UNO_LOOKUPLABELS:
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsLookUpColRowNames() );
+ break;
+ case PROP_UNO_MATCHWHOLE:
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsMatchWholeCell() );
+ break;
+ case PROP_UNO_NULLDATE:
+ {
+ USHORT nD, nM, nY;
+ rOptions.GetDate( nD, nM, nY );
+ util::Date aDate( nD, nM, nY );
+ aRet <<= aDate;
+ }
+ break;
+ case PROP_UNO_SPELLONLINE:
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsAutoSpell() );
+ break;
+ case PROP_UNO_STANDARDDEC :
+ aRet <<= (sal_Int16)( rOptions.GetStdPrecision() );
+ break;
+ case PROP_UNO_REGEXENABLED:
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOptions.IsFormulaRegexEnabled() );
+ break;
+ default:;
+ }
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+ScDocOptionsObj::ScDocOptionsObj( const ScDocOptions& rOpt ) :
+ ScModelObj( NULL ),
+ aOptions( rOpt )
+{
+}
+
+ScDocOptionsObj::~ScDocOptionsObj()
+{
+}
+
+void SAL_CALL ScDocOptionsObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ BOOL bDone = ScDocOptionsHelper::setPropertyValue( aOptions, *GetPropertySet().getPropertyMap(), aPropertyName, aValue );
+
+ if (!bDone)
+ ScModelObj::setPropertyValue( aPropertyName, aValue );
+}
+
+uno::Any SAL_CALL ScDocOptionsObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Any aRet(ScDocOptionsHelper::getPropertyValue( aOptions, *GetPropertySet().getPropertyMap(), aPropertyName ));
+ if ( !aRet.hasValue() )
+ aRet = ScModelObj::getPropertyValue( aPropertyName );
+
+ return aRet;
+}
+
diff --git a/sc/source/ui/unoobj/pageuno.cxx b/sc/source/ui/unoobj/pageuno.cxx
new file mode 100644
index 000000000000..4687683a8ef4
--- /dev/null
+++ b/sc/source/ui/unoobj/pageuno.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "pageuno.hxx"
+#include "shapeuno.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+ScPageObj::ScPageObj( SdrPage* pPage ) :
+ SvxFmDrawPage( pPage )
+{
+}
+
+ScPageObj::~ScPageObj() throw()
+{
+}
+
+uno::Reference<drawing::XShape > ScPageObj::_CreateShape( SdrObject *pObj ) const throw()
+{
+ uno::Reference<drawing::XShape> xShape(SvxFmDrawPage::_CreateShape( pObj ));
+
+ new ScShapeObj( xShape ); // aggregates object and modifies xShape
+
+ return xShape;
+}
+
+::rtl::OUString SAL_CALL ScPageObj::getImplementationName()
+ throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScPageObj"));
+}
+
+sal_Bool SAL_CALL ScPageObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr(rServiceName);
+ return aServiceStr.EqualsAscii( "com.sun.star.sheet.SpreadsheetDrawPage" );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScPageObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(1);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDrawPage"));
+ return aRet;
+}
diff --git a/sc/source/ui/unoobj/scdetect.cxx b/sc/source/ui/unoobj/scdetect.cxx
new file mode 100755
index 000000000000..03d6d14a3ac7
--- /dev/null
+++ b/sc/source/ui/unoobj/scdetect.cxx
@@ -0,0 +1,918 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "scdetect.hxx"
+
+#include <framework/interaction.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/InteractiveAppException.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+
+
+#include <framework/interaction.hxx>
+
+#ifndef _TOOLKIT_UNOHLP_HXX
+#include <toolkit/helper/vclunohelper.hxx>
+#endif
+#include <ucbhelper/simpleinteractionrequest.hxx>
+
+#include <svtools/parhtml.hxx>
+#include <rtl/ustring.h>
+#include <rtl/logfile.hxx>
+#include <svl/itemset.hxx>
+#include <vcl/window.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <tools/urlobj.hxx>
+#include <vos/mutex.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <sot/storinfo.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/request.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/brokenpackageint.hxx>
+#include <sot/storage.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+ScFilterDetect::ScFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& /* xFactory */ )
+{
+}
+
+ScFilterDetect::~ScFilterDetect()
+{
+}
+
+static const sal_Char __FAR_DATA pFilterSc50[] = "StarCalc 5.0";
+static const sal_Char __FAR_DATA pFilterSc50Temp[] = "StarCalc 5.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterSc40[] = "StarCalc 4.0";
+static const sal_Char __FAR_DATA pFilterSc40Temp[] = "StarCalc 4.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterSc30[] = "StarCalc 3.0";
+static const sal_Char __FAR_DATA pFilterSc30Temp[] = "StarCalc 3.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterSc10[] = "StarCalc 1.0";
+static const sal_Char __FAR_DATA pFilterXML[] = "StarOffice XML (Calc)";
+static const sal_Char __FAR_DATA pFilterAscii[] = "Text - txt - csv (StarCalc)";
+static const sal_Char __FAR_DATA pFilterLotus[] = "Lotus";
+static const sal_Char __FAR_DATA pFilterQPro6[] = "Quattro Pro 6.0";
+static const sal_Char __FAR_DATA pFilterExcel4[] = "MS Excel 4.0";
+static const sal_Char __FAR_DATA pFilterEx4Temp[] = "MS Excel 4.0 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterExcel5[] = "MS Excel 5.0/95";
+static const sal_Char __FAR_DATA pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterExcel95[] = "MS Excel 95";
+static const sal_Char __FAR_DATA pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterExcel97[] = "MS Excel 97";
+static const sal_Char __FAR_DATA pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template";
+static const sal_Char __FAR_DATA pFilterDBase[] = "dBase";
+static const sal_Char __FAR_DATA pFilterDif[] = "DIF";
+static const sal_Char __FAR_DATA pFilterSylk[] = "SYLK";
+static const sal_Char __FAR_DATA pFilterHtml[] = "HTML (StarCalc)";
+static const sal_Char __FAR_DATA pFilterHtmlWeb[] = "calc_HTML_WebQuery";
+static const sal_Char __FAR_DATA pFilterRtf[] = "Rich Text Format (StarCalc)";
+
+
+static BOOL lcl_MayBeAscii( SvStream& rStream )
+{
+ // ASCII/CSV is considered possible if there are no null bytes, or a Byte
+ // Order Mark is present, or if, for Unicode UCS2/UTF-16, all null bytes
+ // are on either even or uneven byte positions.
+
+ rStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ const size_t nBufSize = 2048;
+ sal_uInt16 aBuffer[ nBufSize ];
+ sal_uInt8* pByte = reinterpret_cast<sal_uInt8*>(aBuffer);
+ ULONG nBytesRead = rStream.Read( pByte, nBufSize*2);
+
+ if ( nBytesRead >= 2 && (aBuffer[0] == 0xfffe || aBuffer[0] == 0xfeff) )
+ {
+ // Unicode BOM file may contain null bytes.
+ return TRUE;
+ }
+
+ const sal_uInt16* p = aBuffer;
+ sal_uInt16 nMask = 0xffff;
+ nBytesRead /= 2;
+ while( nBytesRead-- && nMask )
+ {
+ sal_uInt16 nVal = *p++ & nMask;
+ if (!(nVal & 0x00ff))
+ nMask &= 0xff00;
+ if (!(nVal & 0xff00))
+ nMask &= 0x00ff;
+ }
+
+ return nMask != 0;
+}
+
+static BOOL lcl_MayBeDBase( SvStream& rStream )
+{
+ // Look for dbf marker, see connectivity/source/inc/dbase/DTable.hxx
+ // DBFType for values.
+ const BYTE nValidMarks[] = {
+ 0x03, 0x04, 0x05, 0x30, 0x43, 0xB3, 0x83, 0x8b, 0x8e, 0xf5 };
+ BYTE nMark;
+ rStream.Seek(STREAM_SEEK_TO_BEGIN);
+ rStream >> nMark;
+ bool bValidMark = false;
+ for (size_t i=0; i < sizeof(nValidMarks)/sizeof(nValidMarks[0]) && !bValidMark; ++i)
+ {
+ if (nValidMarks[i] == nMark)
+ bValidMark = true;
+ }
+ if ( !bValidMark )
+ return FALSE;
+
+ const size_t nHeaderBlockSize = 32;
+ // Empty dbf is >= 32*2+1 bytes in size.
+ const size_t nEmptyDbf = nHeaderBlockSize * 2 + 1;
+
+ rStream.Seek(STREAM_SEEK_TO_END);
+ ULONG nSize = rStream.Tell();
+ if ( nSize < nEmptyDbf )
+ return FALSE;
+
+ // length of header starts at 8
+ rStream.Seek(8);
+ USHORT nHeaderLen;
+ rStream >> nHeaderLen;
+
+ if ( nHeaderLen < nEmptyDbf || nSize < nHeaderLen )
+ return FALSE;
+
+ // Last byte of header must be 0x0d, this is how it's specified.
+ // #i9581#,#i26407# but some applications don't follow the specification
+ // and pad the header with one byte 0x00 to reach an
+ // even boundary. Some (#i88577# ) even pad more or pad using a 0x1a ^Z
+ // control character (#i8857#). This results in:
+ // Last byte of header must be 0x0d on 32 bytes boundary.
+ USHORT nBlocks = (nHeaderLen - 1) / nHeaderBlockSize;
+ BYTE nEndFlag = 0;
+ while ( nBlocks > 1 && nEndFlag != 0x0d ) {
+ rStream.Seek( nBlocks-- * nHeaderBlockSize );
+ rStream >> nEndFlag;
+ }
+
+ return ( 0x0d == nEndFlag );
+}
+
+#if 0
+static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter )
+{
+ if ( !pFilter )
+ return FALSE;
+
+ // TRUE for XML file or template
+ // (template filter has no internal name -> allow configuration key names)
+
+ String aName(pFilter->GetFilterName());
+ return aName.EqualsAscii(pFilterXML) ||
+ aName.EqualsAscii("calc_StarOffice_XML_Calc") ||
+ aName.EqualsAscii("calc_StarOffice_XML_Calc_Template");
+}
+#endif
+
+::rtl::OUString SAL_CALL ScFilterDetect::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
+{
+ REFERENCE< XInputStream > xStream;
+ REFERENCE< XContent > xContent;
+ REFERENCE< XInteractionHandler > xInteraction;
+ String aURL;
+ ::rtl::OUString sTemp;
+ String aTypeName; // a name describing the type (from MediaDescriptor, usually from flat detection)
+ String aPreselectedFilterName; // a name describing the filter to use (from MediaDescriptor, usually from UI action)
+
+ ::rtl::OUString aDocumentTitle; // interesting only if set in this method
+
+ // opening as template is done when a parameter tells to do so and a template filter can be detected
+ // (otherwise no valid filter would be found) or if the detected filter is a template filter and
+ // there is no parameter that forbids to open as template
+ sal_Bool bOpenAsTemplate = sal_False;
+ sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
+
+ sal_Bool bRepairPackage = sal_False;
+ sal_Bool bRepairAllowed = sal_False;
+
+ // now some parameters that can already be in the array, but may be overwritten or new inserted here
+ // remember their indices in the case new values must be added to the array
+ sal_Int32 nPropertyCount = lDescriptor.getLength();
+ sal_Int32 nIndexOfFilterName = -1;
+ sal_Int32 nIndexOfInputStream = -1;
+ sal_Int32 nIndexOfContent = -1;
+ sal_Int32 nIndexOfReadOnlyFlag = -1;
+ sal_Int32 nIndexOfTemplateFlag = -1;
+ sal_Int32 nIndexOfDocumentTitle = -1;
+ bool bFakeXLS = false;
+
+ for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ // extract properties
+ if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aURL = sTemp;
+ }
+ else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aURL = sTemp;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aTypeName = sTemp;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aPreselectedFilterName = sTemp;
+
+ // if the preselected filter name is not correct, it must be erased after detection
+ // remember index of property to get access to it later
+ nIndexOfFilterName = nProperty;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
+ nIndexOfInputStream = nProperty;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
+ nIndexOfReadOnlyFlag = nProperty;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
+ nIndexOfContent = nProperty;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
+ {
+ lDescriptor[nProperty].Value >>= bOpenAsTemplate;
+ nIndexOfTemplateFlag = nProperty;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
+ lDescriptor[nProperty].Value >>= xInteraction;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) )
+ lDescriptor[nProperty].Value >>= bRepairPackage;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
+ nIndexOfDocumentTitle = nProperty;
+ }
+
+ // can't check the type for external filters, so set the "dont" flag accordingly
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ //SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED;
+
+ SfxAllItemSet *pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+ TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
+ SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, FALSE );
+
+ bWasReadOnly = pItem && pItem->GetValue();
+
+ const SfxFilter* pFilter = 0;
+ String aPrefix = String::CreateFromAscii( "private:factory/" );
+ if( aURL.Match( aPrefix ) == aPrefix.Len() )
+ {
+ String aPattern( aPrefix );
+ aPattern += String::CreateFromAscii("scalc");
+ if ( aURL.Match( aPattern ) >= aPattern.Len() )
+ pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
+ }
+ else
+ {
+ // container for Calc filters
+ SfxFilterMatcher aMatcher( String::CreateFromAscii("scalc") );
+ if ( aPreselectedFilterName.Len() )
+ pFilter = SfxFilter::GetFilterByName( aPreselectedFilterName );
+ else if( aTypeName.Len() )
+ pFilter = aMatcher.GetFilter4EA( aTypeName );
+
+ // ctor of SfxMedium uses owner transition of ItemSet
+ SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, FALSE, NULL, pSet );
+ aMedium.UseInteractionHandler( TRUE );
+
+ BOOL bIsStorage = aMedium.IsStorage();
+ if ( aMedium.GetErrorCode() == ERRCODE_NONE )
+ {
+ // remember input stream and content and put them into the descriptor later
+ // should be done here since later the medium can switch to a version
+ xStream.set(aMedium.GetInputStream());
+ xContent.set(aMedium.GetContent());
+ bReadOnly = aMedium.IsReadOnly();
+
+ // maybe that IsStorage() already created an error!
+ if ( bIsStorage )
+ {
+ uno::Reference < embed::XStorage > xStorage(aMedium.GetStorage( sal_False ));
+ if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
+ {
+ // 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(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ if ( xInteraction.is() )
+ {
+ OUString empty;
+ try
+ {
+ InteractiveAppException xException( empty,
+ REFERENCE< XInterface >(),
+ InteractionClassification_ERROR,
+ aMedium.GetError() );
+
+ REFERENCE< XInteractionRequest > xRequest(
+ new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
+ ucbhelper::CONTINUATION_APPROVE ) );
+ xInteraction->handle( xRequest );
+ }
+ catch ( Exception & ) {};
+ }
+ }
+ else if ( xStorage.is() )
+ {
+ try
+ {
+ String aFilterName;
+ if ( pFilter )
+ aFilterName = pFilter->GetName();
+ aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsOwnTemplateFormat() : FALSE, &aFilterName );
+ }
+ catch( lang::WrappedTargetException& aWrap )
+ {
+ packages::zip::ZipIOException aZipException;
+
+ // repairing is done only if this type is requested from outside
+ if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() )
+ {
+ if ( xInteraction.is() )
+ {
+ // the package is broken one
+ aDocumentTitle = aMedium.GetURLObject().getName(
+ INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET );
+
+ if ( !bRepairPackage )
+ {
+ // ask the user whether he wants to try to repair
+ RequestPackageReparation* pRequest = new RequestPackageReparation( aDocumentTitle );
+ uno::Reference< task::XInteractionRequest > xRequest ( pRequest );
+
+ xInteraction->handle( xRequest );
+
+ bRepairAllowed = pRequest->isApproved();
+ }
+
+ if ( !bRepairAllowed )
+ {
+ // repair either not allowed or not successful
+ NotifyBrokenPackage* pNotifyRequest = new NotifyBrokenPackage( aDocumentTitle );
+ uno::Reference< task::XInteractionRequest > xRequest ( pNotifyRequest );
+ xInteraction->handle( xRequest );
+ }
+ }
+
+ if ( !bRepairAllowed )
+ aTypeName.Erase();
+ }
+ }
+ catch( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ aTypeName.Erase();
+ }
+
+ if ( aTypeName.Len() )
+ pFilter = SfxFilterMatcher( String::CreateFromAscii("scalc") ).GetFilter4EA( aTypeName );
+
+ }
+ }
+ else
+ {
+ bool bIsXLS = false;
+ SvStream* pStream = aMedium.GetInStream();
+ const SfxFilter* pPreselectedFilter = pFilter;
+ if ( pPreselectedFilter && pPreselectedFilter->GetName().SearchAscii("Excel") != STRING_NOTFOUND )
+ bIsXLS = true;
+ pFilter = 0;
+ if ( pStream )
+ {
+ SotStorageRef aStorage = new SotStorage ( pStream, FALSE );
+ if ( !aStorage->GetError() )
+ {
+ // Excel-5: detect through contained streams
+ // there are some "excel" formats from 3rd party vendors that need to be distinguished
+ String aStreamName(RTL_CONSTASCII_STRINGPARAM("Workbook"));
+ BOOL bExcel97Stream = ( aStorage->IsStream( aStreamName ) );
+
+ aStreamName = String(RTL_CONSTASCII_STRINGPARAM("Book"));
+ BOOL bExcel5Stream = ( aStorage->IsStream( aStreamName ) );
+ if ( bExcel97Stream || bExcel5Stream )
+ {
+ if ( bExcel97Stream )
+ {
+ String aOldName;
+ BOOL bIsCalcFilter = TRUE;
+ if ( pPreselectedFilter )
+ {
+ // cross filter; now this should be a type detection only, not a filter detection
+ // we can simulate it by preserving the preselected filter if the type matches
+ // example: Excel filters for Writer
+ aOldName = pPreselectedFilter->GetFilterName();
+ bIsCalcFilter = pPreselectedFilter->GetServiceName().EqualsAscii("com.sun.star.sheet.SpreadsheetDocument");
+ }
+
+ if ( aOldName.EqualsAscii(pFilterEx97Temp) || !bIsCalcFilter )
+ {
+ // Excel 97 template selected -> keep selection
+ }
+ else if ( bExcel5Stream &&
+ ( aOldName.EqualsAscii(pFilterExcel5) || aOldName.EqualsAscii(pFilterEx5Temp) ||
+ aOldName.EqualsAscii(pFilterExcel95) || aOldName.EqualsAscii(pFilterEx95Temp) ) )
+ {
+ // dual format file and Excel 5 selected -> keep selection
+ }
+ else
+ {
+ // else use Excel 97 filter
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterExcel97) );
+ }
+ }
+ else if ( bExcel5Stream )
+ {
+ String aOldName;
+ BOOL bIsCalcFilter = TRUE;
+ if ( pPreselectedFilter )
+ {
+ // cross filter; now this should be a type detection only, not a filter detection
+ // we can simulate it by preserving the preselected filter if the type matches
+ // example: Excel filters for Writer
+ aOldName = pPreselectedFilter->GetFilterName();
+ bIsCalcFilter = pPreselectedFilter->GetServiceName().EqualsAscii("com.sun.star.sheet.SpreadsheetDocument");
+ }
+
+ if ( aOldName.EqualsAscii(pFilterExcel95) || aOldName.EqualsAscii(pFilterEx95Temp) ||
+ aOldName.EqualsAscii(pFilterEx5Temp) || !bIsCalcFilter )
+ {
+ // Excel 95 oder Vorlage (5 oder 95) eingestellt -> auch gut
+ }
+ else if ( aOldName.EqualsAscii(pFilterEx97Temp) )
+ {
+ // #101923# auto detection has found template -> return Excel5 template
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterEx5Temp) );
+ }
+ else
+ {
+ // sonst wird als Excel 5-Datei erkannt
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterExcel5) );
+ }
+ }
+ }
+ }
+ else
+ {
+ SvStream &rStr = *pStream;
+
+ // Tabelle mit Suchmustern
+ // Bedeutung der Sequenzen
+ // 0x00??: genau Byte 0x?? muss an dieser Stelle stehen
+ // 0x0100: ein Byte ueberlesen (don't care)
+ // 0x02nn: ein Byte aus 0xnn Alternativen folgt
+ // 0x8000: Erkennung abgeschlossen
+ //
+
+ #define M_DC 0x0100
+ #define M_ALT(ANZ) (0x0200+(ANZ))
+ #define M_ENDE 0x8000
+
+ static const UINT16 pLotus[] = // Lotus 1/1A/2
+ { 0x0000, 0x0000, 0x0002, 0x0000,
+ M_ALT(2), 0x0004, 0x0006,
+ 0x0004, M_ENDE };
+
+ static const UINT16 pLotusNew[] = // Lotus >= 9.7
+ { 0x0000, 0x0000, M_DC, 0x0000, // Rec# + Len (0x1a)
+ M_ALT(3), 0x0003, 0x0004, 0x0005, // File Revision Code 97->ME
+ 0x0010, 0x0004, 0x0000, 0x0000,
+ M_ENDE };
+
+ static const UINT16 pExcel1[] = // Excel BIFF2, BIFF3, BIFF4
+ { 0x09, // lobyte of BOF rec ID (0x0009, 0x0209, 0x0409)
+ M_ALT(3), 0x00, 0x02, 0x04, // hibyte of BOF rec ID (0x0009, 0x0209, 0x0409)
+ M_ALT(3), 4, 6, 8, // lobyte of BOF rec size (4, 6, 8, 16)
+ 0x00, // hibyte of BOF rec size (4, 6, 8, 16)
+ M_DC, M_DC, // any version
+ M_ALT(3), 0x10, 0x20, 0x40, // lobyte of data type (0x0010, 0x0020, 0x0040)
+ 0x00, // hibyte of data type (0x0010, 0x0020, 0x0040)
+ M_ENDE };
+
+ static const UINT16 pExcel2[] = // Excel BIFF4 Workspace
+ { 0x09, // lobyte of BOF rec ID (0x0409)
+ 0x04, // hibyte of BOF rec ID (0x0409)
+ M_ALT(3), 4, 6, 8, // lobyte of BOF rec size (4, 6, 8, 16)
+ 0x00, // hibyte of BOF rec size (4, 6, 8, 16)
+ M_DC, M_DC, // any version
+ 0x00, // lobyte of data type (0x0100)
+ 0x01, // hibyte of data type (0x0100)
+ M_ENDE };
+
+ static const UINT16 pExcel3[] = // #i23425# Excel BIFF5, BIFF7, BIFF8 (simple book stream)
+ { 0x09, // lobyte of BOF rec ID (0x0809)
+ 0x08, // hibyte of BOF rec ID (0x0809)
+ M_ALT(4), 4, 6, 8, 16, // lobyte of BOF rec size
+ 0x00, // hibyte of BOF rec size
+ M_DC, M_DC, // any version
+ M_ALT(5), 0x05, 0x06, 0x10, 0x20, 0x40, // lobyte of data type
+ 0x00, // hibyte of data type
+ M_ENDE };
+
+ static const UINT16 pSc10[] = // StarCalc 1.0 Dokumente
+ { 'B', 'l', 'a', 'i', 's', 'e', '-', 'T', 'a', 'b', 'e', 'l', 'l',
+ 'e', 0x000A, 0x000D, 0x0000, // Sc10CopyRight[16]
+ M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC,
+ M_DC, M_DC, // Sc10CopyRight[29]
+ M_ALT(2), 0x0065, 0x0066, // Versionsnummer 101 oder 102
+ 0x0000,
+ M_ENDE };
+
+ static const UINT16 pLotus2[] = // Lotus >3
+ { 0x0000, 0x0000, 0x001A, 0x0000, // Rec# + Len (26)
+ M_ALT(2), 0x0000, 0x0002, // File Revision Code
+ 0x0010,
+ 0x0004, 0x0000, // File Revision Subcode
+ M_ENDE };
+
+ static const UINT16 pQPro[] =
+ { 0x0000, 0x0000, 0x0002, 0x0000,
+ M_ALT(4), 0x0001, 0x0002, // WB1, WB2
+ 0x0006, 0x0007, // QPro 6/7 (?)
+ 0x0010,
+ M_ENDE };
+
+ static const UINT16 pDIF1[] = // DIF mit CR-LF
+ {
+ 'T', 'A', 'B', 'L', 'E',
+ M_DC, M_DC,
+ '0', ',', '1',
+ M_DC, M_DC,
+ '\"',
+ M_ENDE };
+
+ static const UINT16 pDIF2[] = // DIF mit CR oder LF
+ {
+ 'T', 'A', 'B', 'L', 'E',
+ M_DC,
+ '0', ',', '1',
+ M_DC,
+ '\"',
+ M_ENDE };
+
+ static const UINT16 pSylk[] = // Sylk
+ {
+ 'I', 'D', ';',
+ M_ALT(3), 'P', 'N', 'E', // 'P' plus undocumented Excel extensions 'N' and 'E'
+ M_ENDE };
+
+ static const UINT16 *ppFilterPatterns[] = // Arrays mit Suchmustern
+ {
+ pLotus,
+ pExcel1,
+ pExcel2,
+ pExcel3,
+ pSc10,
+ pDIF1,
+ pDIF2,
+ pSylk,
+ pLotusNew,
+ pLotus2,
+ pQPro
+ };
+ const UINT16 nFilterCount = sizeof(ppFilterPatterns) / sizeof(ppFilterPatterns[0]);
+
+ static const sal_Char* const pFilterName[] = // zugehoerige Filter
+ {
+ pFilterLotus,
+ pFilterExcel4,
+ pFilterExcel4,
+ pFilterExcel4,
+ pFilterSc10,
+ pFilterDif,
+ pFilterDif,
+ pFilterSylk,
+ pFilterLotus,
+ pFilterLotus,
+ pFilterQPro6
+ };
+
+ // const UINT16 nByteMask = 0xFF;
+
+ // suchen Sie jetzt!
+ // ... realisiert ueber 'Mustererkennung'
+
+ BYTE nAkt;
+ BOOL bSync; // Datei und Muster stimmen ueberein
+ USHORT nFilter; // Zaehler ueber alle Filter
+ const UINT16 *pSearch; // aktuelles Musterwort
+
+ for ( nFilter = 0 ; nFilter < nFilterCount ; nFilter++ )
+ {
+ rStr.Seek( 0 ); // am Anfang war alles Uebel...
+ rStr >> nAkt;
+ pSearch = ppFilterPatterns[ nFilter ];
+ bSync = TRUE;
+ while( !rStr.IsEof() && bSync )
+ {
+ register UINT16 nMuster = *pSearch;
+
+ if( nMuster < 0x0100 )
+ { // direkter Byte-Vergleich
+ if( ( BYTE ) nMuster != nAkt )
+ bSync = FALSE;
+ }
+ else if( nMuster & M_DC )
+ { // don't care
+ }
+ else if( nMuster & M_ALT(0) )
+ { // alternative Bytes
+ BYTE nAnzAlt = ( BYTE ) nMuster;
+ bSync = FALSE; // zunaechst unsynchron
+ while( nAnzAlt > 0 )
+ {
+ pSearch++;
+ if( ( BYTE ) *pSearch == nAkt )
+ bSync = TRUE; // jetzt erst Synchronisierung
+ nAnzAlt--;
+ }
+ }
+ else if( nMuster & M_ENDE )
+ { // Format detected
+ if ( pFilterName[nFilter] == pFilterExcel4 && pPreselectedFilter &&
+ ( (pPreselectedFilter)->GetFilterName().EqualsAscii(pFilterEx4Temp) || pPreselectedFilter->GetTypeName().EqualsAscii("calc_MS_Excel_40") ) )
+ {
+ // Excel 4 erkannt, Excel 4 Vorlage eingestellt -> auch gut
+ // oder Excel 4 Filter anderer Applikation (simulated type detection!)
+ }
+ else
+ { // gefundenen Filter einstellen
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterName[ nFilter ]) );
+ }
+ bSync = FALSE; // leave inner loop
+ nFilter = nFilterCount; // leave outer loop
+ }
+ else
+ { // Tabellenfehler
+ DBG_ERROR( "-ScApplication::DetectFilter(): Fehler in Mustertabelle");
+ }
+
+ pSearch++;
+ rStr >> nAkt;
+ }
+ }
+
+ if ( pPreselectedFilter && !pFilter )
+ {
+ // further checks for filters only if they are preselected: ASCII, HTML, RTF, DBase
+ // without the preselection other filters (Writer) take precedence
+ // DBase can't be detected reliably, so it also needs preselection
+ bool bMaybeText = lcl_MayBeAscii( rStr );
+ if ( pPreselectedFilter->GetFilterName().EqualsAscii(pFilterAscii) && bMaybeText )
+ {
+ // Text filter is accepted if preselected
+ pFilter = pPreselectedFilter;
+ }
+ else
+ {
+ // get file header
+ rStr.Seek( 0 );
+ const int nTrySize = 80;
+ ByteString aHeader;
+ for ( int j = 0; j < nTrySize && !rStr.IsEof(); j++ )
+ {
+ sal_Char c;
+ rStr >> c;
+ aHeader += c;
+ }
+ aHeader += '\0';
+
+ if ( HTMLParser::IsHTMLFormat( aHeader.GetBuffer() ) )
+ {
+ // test for HTML
+ if ( pPreselectedFilter->GetName().EqualsAscii(pFilterHtml) )
+ {
+ pFilter = pPreselectedFilter;
+ }
+ else
+ {
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterHtmlWeb) );
+ if ( bIsXLS )
+ bFakeXLS = true;
+ }
+ }
+ else if ( bIsXLS && bMaybeText )
+ {
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterAscii) );
+ bFakeXLS = true;
+ }
+ else if ( aHeader.CompareTo( "{\\rtf", 5 ) == COMPARE_EQUAL )
+ {
+ // test for RTF
+ pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterRtf) );
+ }
+ else if ( pPreselectedFilter->GetName().EqualsAscii(pFilterDBase) && lcl_MayBeDBase( rStr ) )
+ pFilter = pPreselectedFilter;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( nIndexOfInputStream == -1 && xStream.is() )
+ {
+ // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("InputStream");
+ lDescriptor[nPropertyCount].Value <<= xStream;
+ nPropertyCount++;
+ }
+
+ if ( nIndexOfContent == -1 && xContent.is() )
+ {
+ // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("UCBContent");
+ lDescriptor[nPropertyCount].Value <<= xContent;
+ nPropertyCount++;
+ }
+
+ if ( bReadOnly != bWasReadOnly )
+ {
+ if ( nIndexOfReadOnlyFlag == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("ReadOnly");
+ lDescriptor[nPropertyCount].Value <<= bReadOnly;
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
+ }
+
+ if ( !bRepairPackage && bRepairAllowed )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("RepairPackage");
+ lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
+ nPropertyCount++;
+
+ bOpenAsTemplate = sal_True;
+
+ // TODO/LATER: set progress bar that should be used
+ }
+
+ if ( bOpenAsTemplate )
+ {
+ if ( nIndexOfTemplateFlag == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("AsTemplate");
+ lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
+ }
+
+ if ( aDocumentTitle.getLength() )
+ {
+ // the title was set here
+ if ( nIndexOfDocumentTitle == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("DocumentTitle");
+ lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
+ }
+
+ if ( bFakeXLS )
+ {
+ if ( nIndexOfFilterName == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("FilterName");
+ lDescriptor[nPropertyCount].Value <<= rtl::OUString(pFilter->GetName());
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfFilterName].Value <<= rtl::OUString(pFilter->GetName());
+ }
+
+ if ( pFilter )
+ aTypeName = pFilter->GetTypeName();
+ else
+ aTypeName.Erase();
+ return aTypeName;
+}
+
+SFX_IMPL_SINGLEFACTORY( ScFilterDetect )
+
+/* XServiceInfo */
+UNOOUSTRING SAL_CALL ScFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
+{
+ return impl_getStaticImplementationName();
+}
+ \
+/* XServiceInfo */
+sal_Bool SAL_CALL ScFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION )
+{
+ UNOSEQUENCE< UNOOUSTRING > seqServiceNames(getSupportedServiceNames());
+ const UNOOUSTRING* pArray = seqServiceNames.getConstArray();
+ for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
+ {
+ if ( pArray[nCounter] == sServiceName )
+ {
+ return sal_True ;
+ }
+ }
+ return sal_False ;
+}
+
+/* XServiceInfo */
+UNOSEQUENCE< UNOOUSTRING > SAL_CALL ScFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+/* Helper for XServiceInfo */
+UNOSEQUENCE< UNOOUSTRING > ScFilterDetect::impl_getStaticSupportedServiceNames()
+{
+ UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() );
+ UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 1 );
+ seqServiceNames.getArray() [0] = UNOOUSTRING::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection" );
+ return seqServiceNames ;
+}
+
+/* Helper for XServiceInfo */
+UNOOUSTRING ScFilterDetect::impl_getStaticImplementationName()
+{
+ return UNOOUSTRING::createFromAscii( "com.sun.star.comp.calc.FormatDetector" );
+}
+
+/* Helper for registry */
+UNOREFERENCE< UNOXINTERFACE > SAL_CALL ScFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
+{
+ return UNOREFERENCE< UNOXINTERFACE >( *new ScFilterDetect( xServiceManager ) );
+}
+
diff --git a/sc/source/ui/unoobj/scdetect.hxx b/sc/source/ui/unoobj/scdetect.hxx
new file mode 100644
index 000000000000..a652d11df951
--- /dev/null
+++ b/sc/source/ui/unoobj/scdetect.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SC_TYPEDETECT_HXX
+#define _SC_TYPEDETECT_HXX
+
+#include <rtl/ustring.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <cppuhelper/implbase2.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/factory.hxx>
+#include <tools/link.hxx>
+#include <tools/string.hxx>
+
+class SfxObjectFactory;
+class SfxFilterMatcher;
+class LoadEnvironment_Impl;
+class SfxMedium;
+
+namespace com
+{
+ namespace sun
+ {
+ namespace star
+ {
+ namespace uno
+ {
+ class Any;
+ }
+ namespace lang
+ {
+ class XMultiServiceFactory;
+ }
+ namespace frame
+ {
+ class XFrame;
+ }
+ namespace beans
+ {
+ struct PropertyValue;
+ }
+ }
+ }
+}
+
+#include <sfx2/sfxuno.hxx>
+
+#define REFERENCE ::com::sun::star::uno::Reference
+#define SEQUENCE ::com::sun::star::uno::Sequence
+#define RUNTIME_EXCEPTION ::com::sun::star::uno::RuntimeException
+
+class ScFilterDetect : public ::cppu::WeakImplHelper2< ::com::sun::star::document::XExtendedFilterDetection, ::com::sun::star::lang::XServiceInfo >
+{
+public:
+ ScFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& xFactory );
+ virtual ~ScFilterDetect();
+
+ SFX_DECL_XSERVICEINFO
+
+ //----------------------------------------------------------------------------------
+ // XExtendedFilterDetect
+ //----------------------------------------------------------------------------------
+ virtual ::rtl::OUString SAL_CALL detect( SEQUENCE< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( RUNTIME_EXCEPTION );
+};
+
+#endif
diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx
new file mode 100644
index 000000000000..a173e6d1e051
--- /dev/null
+++ b/sc/source/ui/unoobj/servuno.cxx
@@ -0,0 +1,598 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <tools/debug.hxx>
+#include <svtools/unoimap.hxx>
+#include <svx/unofill.hxx>
+#include <editeng/unonrule.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+#include "servuno.hxx"
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "cellsuno.hxx"
+#include "fielduno.hxx"
+#include "styleuno.hxx"
+#include "afmtuno.hxx"
+#include "defltuno.hxx"
+#include "drdefuno.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "confuno.hxx"
+#include "shapeuno.hxx"
+#include "cellvaluebinding.hxx"
+#include "celllistsource.hxx"
+#include "addruno.hxx"
+#include "chart2uno.hxx"
+#include "tokenuno.hxx"
+
+// #100263# Support creation of GraphicObjectResolver and EmbeddedObjectResolver
+#include <svx/xmleohlp.hxx>
+#include <svx/xmlgrhlp.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/document/XCodeNameQuery.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <svx/unomod.hxx>
+#include <vbahelper/vbaaccesshelper.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <basic/basmgr.hxx>
+#include <sfx2/app.hxx>
+
+using namespace ::com::sun::star;
+
+class ScVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper1< container::XNameAccess >
+{
+ uno::Any maWorkbook;
+ uno::Any maCachedObject;
+ ScDocShell* mpDocShell;
+public:
+ ScVbaObjectForCodeNameProvider( ScDocShell* pDocShell ) : mpDocShell( pDocShell )
+ {
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ if ( !pDoc )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("")), uno::Reference< uno::XInterface >() );
+
+ uno::Sequence< uno::Any > aArgs(2);
+ // access the application object ( parent for workbook )
+ aArgs[0] = uno::Any( ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.Application", uno::Sequence< uno::Any >() ) );
+ aArgs[1] = uno::Any( mpDocShell->GetModel() );
+ maWorkbook <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs );
+ }
+
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException )
+ {
+ ScUnoGuard aGuard;
+ maCachedObject = uno::Any(); // clear cached object
+ String sName = aName;
+
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ if ( !pDoc )
+ throw uno::RuntimeException();
+ if ( sName == pDoc->GetCodeName() )
+ maCachedObject = maWorkbook;
+ else
+ {
+ String sCodeName;
+ SCTAB nCount = pDoc->GetTableCount();
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ pDoc->GetCodeName( i, sCodeName );
+ if( sCodeName == sName )
+ {
+ String sSheetName;
+ if( pDoc->GetName( i, sSheetName ) )
+ {
+ uno::Reference< frame::XModel > xModel( mpDocShell->GetModel() );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference<sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xSheets, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW );
+ uno::Sequence< uno::Any > aArgs(3);
+ aArgs[0] = maWorkbook;
+ aArgs[1] = uno::Any( xModel );
+ aArgs[2] = uno::Any( rtl::OUString( sSheetName ) );
+ // use the convience function
+ maCachedObject <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs );
+ break;
+ }
+ }
+ }
+ }
+ return maCachedObject.hasValue();
+
+ }
+ ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+ {
+ ScUnoGuard aGuard;
+ OSL_TRACE("ScVbaObjectForCodeNameProvider::getByName( %s )",
+ rtl::OUStringToOString( aName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ if ( !hasByName( aName ) )
+ throw ::com::sun::star::container::NoSuchElementException();
+ return maCachedObject;
+ }
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ ScUnoGuard aGuard;
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ if ( !pDoc )
+ throw uno::RuntimeException();
+ SCTAB nCount = pDoc->GetTableCount();
+ uno::Sequence< rtl::OUString > aNames( nCount + 1 );
+ SCTAB index = 0;
+ String sCodeName;
+ for( ; index < nCount; ++index )
+ {
+ pDoc->GetCodeName( index, sCodeName );
+ aNames[ index ] = sCodeName;
+ }
+ aNames[ index ] = pDoc->GetCodeName();
+ return aNames;
+ }
+ // XElemenAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException){ return uno::Type(); }
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException ) { return sal_True; }
+
+};
+
+class ScVbaCodeNameProvider : public ::cppu::WeakImplHelper1< document::XCodeNameQuery >
+{
+ScDocShell* mpDocShell;
+public:
+ ScVbaCodeNameProvider( ScDocShell* pDocShell ) : mpDocShell( pDocShell ) {}
+ // XCodeNameQuery
+ rtl::OUString SAL_CALL getCodeNameForObject( const uno::Reference< uno::XInterface >& xIf ) throw( uno::RuntimeException )
+ {
+ ScUnoGuard aGuard;
+ rtl::OUString sCodeName;
+ if ( mpDocShell )
+ {
+ OSL_TRACE( "*** In ScVbaCodeNameProvider::getCodeNameForObject");
+ // need to find the page ( and index ) for this control
+ uno::Reference< drawing::XDrawPagesSupplier > xSupplier( mpDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndex( xSupplier->getDrawPages(), uno::UNO_QUERY_THROW );
+ sal_Int32 nLen = xIndex->getCount();
+ bool bMatched = false;
+ uno::Sequence< script::ScriptEventDescriptor > aFakeEvents;
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ try
+ {
+ uno::Reference< form::XFormsSupplier > xFormSupplier( xIndex->getByIndex( index ), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xFormIndex( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
+ // get the www-standard container
+ uno::Reference< container::XIndexAccess > xFormControls( xFormIndex->getByIndex(0), uno::UNO_QUERY_THROW );
+ sal_Int32 nCntrls = xFormControls->getCount();
+ for( sal_Int32 cIndex = 0; cIndex < nCntrls; ++cIndex )
+ {
+ uno::Reference< uno::XInterface > xControl( xFormControls->getByIndex( cIndex ), uno::UNO_QUERY_THROW );
+ bMatched = ( xControl == xIf );
+ if ( bMatched )
+ {
+ String sName;
+ mpDocShell->GetDocument()->GetCodeName( static_cast<SCTAB>( index ), sName );
+ sCodeName = sName;
+ }
+ }
+ }
+ catch( uno::Exception& ) {}
+ if ( bMatched )
+ break;
+ }
+ }
+ // Probably should throw here ( if !bMatched )
+ return sCodeName;
+ }
+
+};
+
+//------------------------------------------------------------------------
+//
+struct ProvNamesId_Type
+{
+ const char * pName;
+ sal_uInt16 nType;
+};
+
+static const ProvNamesId_Type __FAR_DATA aProvNamesId[] =
+{
+ { "com.sun.star.sheet.Spreadsheet", SC_SERVICE_SHEET },
+ { "com.sun.star.text.TextField.URL", SC_SERVICE_URLFIELD },
+ { "com.sun.star.text.TextField.PageNumber", SC_SERVICE_PAGEFIELD },
+ { "com.sun.star.text.TextField.PageCount", SC_SERVICE_PAGESFIELD },
+ { "com.sun.star.text.TextField.Date", SC_SERVICE_DATEFIELD },
+ { "com.sun.star.text.TextField.Time", SC_SERVICE_TIMEFIELD },
+ { "com.sun.star.text.TextField.DocumentTitle", SC_SERVICE_TITLEFIELD },
+ { "com.sun.star.text.TextField.FileName", SC_SERVICE_FILEFIELD },
+ { "com.sun.star.text.TextField.SheetName", SC_SERVICE_SHEETFIELD },
+ { "com.sun.star.style.CellStyle", SC_SERVICE_CELLSTYLE },
+ { "com.sun.star.style.PageStyle", SC_SERVICE_PAGESTYLE },
+ { "com.sun.star.sheet.TableAutoFormat", SC_SERVICE_AUTOFORMAT },
+ { "com.sun.star.sheet.SheetCellRanges", SC_SERVICE_CELLRANGES },
+ { "com.sun.star.drawing.GradientTable", SC_SERVICE_GRADTAB },
+ { "com.sun.star.drawing.HatchTable", SC_SERVICE_HATCHTAB },
+ { "com.sun.star.drawing.BitmapTable", SC_SERVICE_BITMAPTAB },
+ { "com.sun.star.drawing.TransparencyGradientTable", SC_SERVICE_TRGRADTAB },
+ { "com.sun.star.drawing.MarkerTable", SC_SERVICE_MARKERTAB },
+ { "com.sun.star.drawing.DashTable", SC_SERVICE_DASHTAB },
+ { "com.sun.star.text.NumberingRules", SC_SERVICE_NUMRULES },
+ { "com.sun.star.sheet.Defaults", SC_SERVICE_DOCDEFLTS },
+ { "com.sun.star.drawing.Defaults", SC_SERVICE_DRAWDEFLTS },
+ { "com.sun.star.comp.SpreadsheetSettings", SC_SERVICE_DOCSPRSETT },
+ { "com.sun.star.document.Settings", SC_SERVICE_DOCCONF },
+ { "com.sun.star.image.ImageMapRectangleObject", SC_SERVICE_IMAP_RECT },
+ { "com.sun.star.image.ImageMapCircleObject", SC_SERVICE_IMAP_CIRC },
+ { "com.sun.star.image.ImageMapPolygonObject", SC_SERVICE_IMAP_POLY },
+
+ // #100263# Support creation of GraphicObjectResolver and EmbeddedObjectResolver
+ { "com.sun.star.document.ExportGraphicObjectResolver", SC_SERVICE_EXPORT_GOR },
+ { "com.sun.star.document.ImportGraphicObjectResolver", SC_SERVICE_IMPORT_GOR },
+ { "com.sun.star.document.ExportEmbeddedObjectResolver", SC_SERVICE_EXPORT_EOR },
+ { "com.sun.star.document.ImportEmbeddedObjectResolver", SC_SERVICE_IMPORT_EOR },
+
+ { SC_SERVICENAME_VALBIND, SC_SERVICE_VALBIND },
+ { SC_SERVICENAME_LISTCELLBIND, SC_SERVICE_LISTCELLBIND },
+ { SC_SERVICENAME_LISTSOURCE, SC_SERVICE_LISTSOURCE },
+ { SC_SERVICENAME_CELLADDRESS, SC_SERVICE_CELLADDRESS },
+ { SC_SERVICENAME_RANGEADDRESS, SC_SERVICE_RANGEADDRESS },
+
+ { "com.sun.star.sheet.DocumentSettings",SC_SERVICE_SHEETDOCSET },
+
+ { SC_SERVICENAME_CHDATAPROV, SC_SERVICE_CHDATAPROV },
+ { SC_SERVICENAME_FORMULAPARS, SC_SERVICE_FORMULAPARS },
+ { SC_SERVICENAME_OPCODEMAPPER, SC_SERVICE_OPCODEMAPPER },
+ { "ooo.vba.VBAObjectModuleObjectProvider", SC_SERVICE_VBAOBJECTPROVIDER },
+ { "ooo.vba.VBACodeNameProvider", SC_SERVICE_VBACODENAMEPROVIDER },
+ { "ooo.vba.VBAGlobals", SC_SERVICE_VBAGLOBALS },
+
+ // case-correct versions of the service names (#i102468#)
+ { "com.sun.star.text.textfield.URL", SC_SERVICE_URLFIELD },
+ { "com.sun.star.text.textfield.PageNumber", SC_SERVICE_PAGEFIELD },
+ { "com.sun.star.text.textfield.PageCount", SC_SERVICE_PAGESFIELD },
+ { "com.sun.star.text.textfield.Date", SC_SERVICE_DATEFIELD },
+ { "com.sun.star.text.textfield.Time", SC_SERVICE_TIMEFIELD },
+ { "com.sun.star.text.textfield.DocumentTitle", SC_SERVICE_TITLEFIELD },
+ { "com.sun.star.text.textfield.FileName", SC_SERVICE_FILEFIELD },
+ { "com.sun.star.text.textfield.SheetName", SC_SERVICE_SHEETFIELD }
+};
+
+//
+// old service names that were in 567 still work in createInstance,
+// in case some macro is still using them
+//
+
+static const sal_Char* __FAR_DATA aOldNames[SC_SERVICE_COUNT] =
+ {
+ "", // SC_SERVICE_SHEET
+ "stardiv.one.text.TextField.URL", // SC_SERVICE_URLFIELD
+ "stardiv.one.text.TextField.PageNumber", // SC_SERVICE_PAGEFIELD
+ "stardiv.one.text.TextField.PageCount", // SC_SERVICE_PAGESFIELD
+ "stardiv.one.text.TextField.Date", // SC_SERVICE_DATEFIELD
+ "stardiv.one.text.TextField.Time", // SC_SERVICE_TIMEFIELD
+ "stardiv.one.text.TextField.DocumentTitle", // SC_SERVICE_TITLEFIELD
+ "stardiv.one.text.TextField.FileName", // SC_SERVICE_FILEFIELD
+ "stardiv.one.text.TextField.SheetName", // SC_SERVICE_SHEETFIELD
+ "stardiv.one.style.CellStyle", // SC_SERVICE_CELLSTYLE
+ "stardiv.one.style.PageStyle", // SC_SERVICE_PAGESTYLE
+ "", // SC_SERVICE_AUTOFORMAT
+ "", // SC_SERVICE_CELLRANGES
+ "", // SC_SERVICE_GRADTAB
+ "", // SC_SERVICE_HATCHTAB
+ "", // SC_SERVICE_BITMAPTAB
+ "", // SC_SERVICE_TRGRADTAB
+ "", // SC_SERVICE_MARKERTAB
+ "", // SC_SERVICE_DASHTAB
+ "", // SC_SERVICE_NUMRULES
+ "", // SC_SERVICE_DOCDEFLTS
+ "", // SC_SERVICE_DRAWDEFLTS
+ "", // SC_SERVICE_DOCSPRSETT
+ "", // SC_SERVICE_DOCCONF
+ "", // SC_SERVICE_IMAP_RECT
+ "", // SC_SERVICE_IMAP_CIRC
+ "", // SC_SERVICE_IMAP_POLY
+
+ // #100263# Support creation of GraphicObjectResolver and EmbeddedObjectResolver
+ "", // SC_SERVICE_EXPORT_GOR
+ "", // SC_SERVICE_IMPORT_GOR
+ "", // SC_SERVICE_EXPORT_EOR
+ "", // SC_SERVICE_IMPORT_EOR
+
+ "", // SC_SERVICE_VALBIND
+ "", // SC_SERVICE_LISTCELLBIND
+ "", // SC_SERVICE_LISTSOURCE
+ "", // SC_SERVICE_CELLADDRESS
+ "", // SC_SERVICE_RANGEADDRESS
+ "", // SC_SERVICE_SHEETDOCSET
+ "", // SC_SERVICE_CHDATAPROV
+ "", // SC_SERVICE_FORMULAPARS
+ "", // SC_SERVICE_OPCODEMAPPER
+ "", // SC_SERVICE_VBAOBJECTPROVIDER
+ "", // SC_SERVICE_VBACODENAMEPROVIDER
+ "", // SC_SERVICE_VBAGLOBALS
+ };
+
+
+
+
+//------------------------------------------------------------------------
+
+// alles static
+
+//UNUSED2008-05 String ScServiceProvider::GetProviderName(sal_uInt16 nObjectType)
+//UNUSED2008-05 {
+//UNUSED2008-05 String sRet;
+//UNUSED2008-05 if (nObjectType < SC_SERVICE_COUNT)
+//UNUSED2008-05 sRet = String::CreateFromAscii( aProvNames[nObjectType] );
+//UNUSED2008-05 return sRet;
+//UNUSED2008-05 }
+
+sal_uInt16 ScServiceProvider::GetProviderType(const String& rServiceName)
+{
+ if (rServiceName.Len())
+ {
+ const sal_uInt16 nEntries =
+ sizeof(aProvNamesId) / sizeof(aProvNamesId[0]);
+ for (sal_uInt16 i = 0; i < nEntries; i++)
+ {
+ if (rServiceName.EqualsAscii( aProvNamesId[i].pName ))
+ {
+ return aProvNamesId[i].nType;
+ }
+ }
+
+ USHORT i;
+ for (i=0; i<SC_SERVICE_COUNT; i++)
+ {
+ DBG_ASSERT( aOldNames[i], "ScServiceProvider::GetProviderType: no oldname => crash");
+ if (rServiceName.EqualsAscii( aOldNames[i] ))
+ {
+ DBG_ERROR("old service name used");
+ return i;
+ }
+ }
+ }
+ return SC_SERVICE_INVALID;
+}
+
+uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance(
+ sal_uInt16 nType, ScDocShell* pDocShell )
+{
+ uno::Reference<uno::XInterface> xRet;
+ switch (nType)
+ {
+ case SC_SERVICE_SHEET:
+ // noch nicht eingefuegt - DocShell=Null
+ xRet.set((sheet::XSpreadsheet*)new ScTableSheetObj(NULL,0));
+ break;
+ case SC_SERVICE_URLFIELD:
+ xRet.set((text::XTextField*)new ScCellFieldObj( NULL, ScAddress(), ESelection() ));
+ break;
+ case SC_SERVICE_PAGEFIELD:
+ case SC_SERVICE_PAGESFIELD:
+ case SC_SERVICE_DATEFIELD:
+ case SC_SERVICE_TIMEFIELD:
+ case SC_SERVICE_TITLEFIELD:
+ case SC_SERVICE_FILEFIELD:
+ case SC_SERVICE_SHEETFIELD:
+ xRet.set((text::XTextField*)new ScHeaderFieldObj( NULL, 0, nType, ESelection() ));
+ break;
+ case SC_SERVICE_CELLSTYLE:
+ xRet.set((style::XStyle*)new ScStyleObj( NULL, SFX_STYLE_FAMILY_PARA, String() ));
+ break;
+ case SC_SERVICE_PAGESTYLE:
+ xRet.set((style::XStyle*)new ScStyleObj( NULL, SFX_STYLE_FAMILY_PAGE, String() ));
+ break;
+ case SC_SERVICE_AUTOFORMAT:
+ xRet.set((container::XIndexAccess*)new ScAutoFormatObj( SC_AFMTOBJ_INVALID ));
+ break;
+ case SC_SERVICE_CELLRANGES:
+ // wird nicht eingefuegt, sondern gefuellt
+ // -> DocShell muss gesetzt sein, aber leere Ranges
+ if (pDocShell)
+ xRet.set((sheet::XSheetCellRanges*)new ScCellRangesObj( pDocShell, ScRangeList() ));
+ break;
+
+ case SC_SERVICE_DOCDEFLTS:
+ if (pDocShell)
+ xRet.set((beans::XPropertySet*)new ScDocDefaultsObj( pDocShell ));
+ break;
+ case SC_SERVICE_DRAWDEFLTS:
+ if (pDocShell)
+ xRet.set((beans::XPropertySet*)new ScDrawDefaultsObj( pDocShell ));
+ break;
+
+ // Drawing layer tables are not in SvxUnoDrawMSFactory,
+ // because SvxUnoDrawMSFactory doesn't have a SdrModel pointer.
+ // Drawing layer is always allocated if not there (MakeDrawLayer).
+
+ case SC_SERVICE_GRADTAB:
+ if (pDocShell)
+ xRet.set(SvxUnoGradientTable_createInstance( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_HATCHTAB:
+ if (pDocShell)
+ xRet.set(SvxUnoHatchTable_createInstance( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_BITMAPTAB:
+ if (pDocShell)
+ xRet.set(SvxUnoBitmapTable_createInstance( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_TRGRADTAB:
+ if (pDocShell)
+ xRet.set(SvxUnoTransGradientTable_createInstance( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_MARKERTAB:
+ if (pDocShell)
+ xRet.set(SvxUnoMarkerTable_createInstance( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_DASHTAB:
+ if (pDocShell)
+ xRet.set(SvxUnoDashTable_createInstance( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_NUMRULES:
+ if (pDocShell)
+ xRet.set(SvxCreateNumRule( pDocShell->MakeDrawLayer() ));
+ break;
+ case SC_SERVICE_DOCSPRSETT:
+ case SC_SERVICE_SHEETDOCSET:
+ case SC_SERVICE_DOCCONF:
+ if (pDocShell)
+ xRet.set((beans::XPropertySet*)new ScDocumentConfiguration(pDocShell));
+ break;
+
+ case SC_SERVICE_IMAP_RECT:
+ xRet.set(SvUnoImageMapRectangleObject_createInstance( ScShapeObj::GetSupportedMacroItems() ));
+ break;
+ case SC_SERVICE_IMAP_CIRC:
+ xRet.set(SvUnoImageMapCircleObject_createInstance( ScShapeObj::GetSupportedMacroItems() ));
+ break;
+ case SC_SERVICE_IMAP_POLY:
+ xRet.set(SvUnoImageMapPolygonObject_createInstance( ScShapeObj::GetSupportedMacroItems() ));
+ break;
+
+ // #100263# Support creation of GraphicObjectResolver and EmbeddedObjectResolver
+ case SC_SERVICE_EXPORT_GOR:
+ xRet.set((::cppu::OWeakObject * )new SvXMLGraphicHelper( GRAPHICHELPER_MODE_WRITE ));
+ break;
+
+ case SC_SERVICE_IMPORT_GOR:
+ xRet.set((::cppu::OWeakObject * )new SvXMLGraphicHelper( GRAPHICHELPER_MODE_READ ));
+ break;
+
+ case SC_SERVICE_EXPORT_EOR:
+ if (pDocShell)
+ xRet.set((::cppu::OWeakObject * )new SvXMLEmbeddedObjectHelper( *pDocShell, EMBEDDEDOBJECTHELPER_MODE_WRITE ));
+ break;
+
+ case SC_SERVICE_IMPORT_EOR:
+ if (pDocShell)
+ xRet.set((::cppu::OWeakObject * )new SvXMLEmbeddedObjectHelper( *pDocShell, EMBEDDEDOBJECTHELPER_MODE_READ ));
+ break;
+
+ case SC_SERVICE_VALBIND:
+ case SC_SERVICE_LISTCELLBIND:
+ if (pDocShell)
+ {
+ sal_Bool bListPos = ( nType == SC_SERVICE_LISTCELLBIND );
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc( pDocShell->GetBaseModel(), uno::UNO_QUERY );
+ xRet.set(*new calc::OCellValueBinding( xDoc, bListPos ));
+ }
+ break;
+ case SC_SERVICE_LISTSOURCE:
+ if (pDocShell)
+ {
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc( pDocShell->GetBaseModel(), uno::UNO_QUERY );
+ xRet.set(*new calc::OCellListSource( xDoc ));
+ }
+ break;
+ case SC_SERVICE_CELLADDRESS:
+ case SC_SERVICE_RANGEADDRESS:
+ if (pDocShell)
+ {
+ sal_Bool bRange = ( nType == SC_SERVICE_RANGEADDRESS );
+ xRet.set(*new ScAddressConversionObj( pDocShell, bRange ));
+ }
+ break;
+
+ case SC_SERVICE_CHDATAPROV:
+ if (pDocShell && pDocShell->GetDocument())
+ xRet = *new ScChart2DataProvider( pDocShell->GetDocument() );
+ break;
+
+ case SC_SERVICE_FORMULAPARS:
+ if (pDocShell)
+ xRet.set(static_cast<sheet::XFormulaParser*>(new ScFormulaParserObj( pDocShell )));
+ break;
+
+ case SC_SERVICE_OPCODEMAPPER:
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScAddress aAddress;
+ ScCompiler* pComp = new ScCompiler(pDoc,aAddress);
+ pComp->SetGrammar( pDoc->GetGrammar() );
+ xRet.set(static_cast<sheet::XFormulaOpCodeMapper*>(new ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> (pComp))));
+ break;
+ }
+ case SC_SERVICE_VBAOBJECTPROVIDER:
+ if (pDocShell && pDocShell->GetDocument()->IsInVBAMode())
+ {
+ OSL_TRACE("**** creating VBA Object mapper");
+ xRet.set(static_cast<container::XNameAccess*>(new ScVbaObjectForCodeNameProvider( pDocShell )));
+ }
+ break;
+ case SC_SERVICE_VBACODENAMEPROVIDER:
+ if (pDocShell && pDocShell->GetDocument()->IsInVBAMode())
+ {
+ OSL_TRACE("**** creating VBA Object provider");
+ xRet.set(static_cast<document::XCodeNameQuery*>(new ScVbaCodeNameProvider( pDocShell )));
+ }
+ break;
+ case SC_SERVICE_VBAGLOBALS:
+ if (pDocShell)
+ {
+ uno::Any aGlobs;
+ if ( !pDocShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aGlobs ) )
+ {
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[ 0 ] <<= pDocShell->GetModel();
+ xRet = ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs );
+ pDocShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", uno::Any( xRet ) );
+ BasicManager* pAppMgr = SFX_APP()->GetBasicManager();
+ if ( pAppMgr )
+ pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] );
+ }
+ }
+ break;
+ }
+
+ return xRet;
+}
+
+uno::Sequence<rtl::OUString> ScServiceProvider::GetAllServiceNames()
+{
+ const sal_uInt16 nEntries = sizeof(aProvNamesId) / sizeof(aProvNamesId[0]);
+ uno::Sequence<rtl::OUString> aRet(nEntries);
+ rtl::OUString* pArray = aRet.getArray();
+ for (sal_uInt16 i = 0; i < nEntries; i++)
+ {
+ pArray[i] = rtl::OUString::createFromAscii( aProvNamesId[i].pName );
+ }
+ return aRet;
+}
+
+
+
+
diff --git a/sc/source/ui/unoobj/shapeuno.cxx b/sc/source/ui/unoobj/shapeuno.cxx
new file mode 100644
index 000000000000..1ed384ed2ebd
--- /dev/null
+++ b/sc/source/ui/unoobj/shapeuno.cxx
@@ -0,0 +1,1521 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <tools/debug.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/stl_types.hxx>
+#include <svtools/unoevent.hxx>
+#include <svtools/unoimap.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/unoshape.hxx>
+#include <editeng/unofield.hxx>
+#include <svx/shapepropertynotifier.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include "shapeuno.hxx"
+#include "miscuno.hxx"
+#include "cellsuno.hxx"
+#include "textuno.hxx"
+#include "fielduno.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "unonames.hxx"
+#include "unoguard.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap );
+
+static ScShapeImplementationIdMap aImplementationIdMap;
+
+const SfxItemPropertyMapEntry* lcl_GetShapeMap()
+{
+ static SfxItemPropertyMapEntry aShapeMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ANCHOR), 0, &getCppuType((uno::Reference<uno::XInterface>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_HORIPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VERTPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aShapeMap_Impl;
+}
+
+// static
+const SvEventDescription* ScShapeObj::GetSupportedMacroItems()
+{
+ static const SvEventDescription aMacroDescriptionsImpl[] =
+ {
+ { 0, NULL }
+ };
+ return aMacroDescriptionsImpl;
+}
+
+//------------------------------------------------------------------------
+
+namespace
+{
+ void lcl_initializeNotifier( SdrObject& _rSdrObj, ::cppu::OWeakObject& _rShape )
+ {
+ ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "Anchor" ) );
+ _rSdrObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eSpreadsheetAnchor, pProvider );
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
+ pShapePropertySet(NULL),
+ pShapePropertyState(NULL),
+ pImplementationId(NULL),
+ bIsTextShape(FALSE),
+ bInitializedNotifier(false)
+{
+ comphelper::increment( m_refCount );
+
+ {
+ mxShapeAgg = uno::Reference<uno::XAggregation>( xShape, uno::UNO_QUERY );
+ // extra block to force deletion of the temporary before setDelegator
+ }
+
+ if (mxShapeAgg.is())
+ {
+ xShape = NULL; // during setDelegator, mxShapeAgg must be the only ref
+
+ mxShapeAgg->setDelegator( (cppu::OWeakObject*)this );
+
+ xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY ));
+
+ bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL );
+ }
+
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ lcl_initializeNotifier( *pObj, *this );
+ bInitializedNotifier = true;
+ }
+ }
+
+ comphelper::decrement( m_refCount );
+}
+
+ScShapeObj::~ScShapeObj()
+{
+// if (mxShapeAgg.is())
+// mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
+}
+
+// XInterface
+
+uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ uno::Any aRet = ScShapeObj_Base::queryInterface( rType );
+
+ if ( !aRet.hasValue() && bIsTextShape )
+ aRet = ScShapeObj_TextBase::queryInterface( rType );
+
+ if ( !aRet.hasValue() && mxShapeAgg.is() )
+ aRet = mxShapeAgg->queryAggregation( rType );
+
+ return aRet;
+}
+
+void SAL_CALL ScShapeObj::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ScShapeObj::release() throw()
+{
+ OWeakObject::release();
+}
+
+void ScShapeObj::GetShapePropertySet()
+{
+ // #i61908# Store the result of queryAggregation in a member.
+ // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
+
+ if (!pShapePropertySet)
+ {
+ uno::Reference<beans::XPropertySet> xProp;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xProp;
+ pShapePropertySet = xProp.get();
+ }
+}
+
+void ScShapeObj::GetShapePropertyState()
+{
+ // #i61908# Store the result of queryAggregation in a member.
+ // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
+
+ if (!pShapePropertyState)
+ {
+ uno::Reference<beans::XPropertyState> xState;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xState;
+ pShapePropertyState = xState.get();
+ }
+}
+
+uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<lang::XComponent> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<lang::XComponent>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<text::XText> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<text::XText>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<text::XSimpleText> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<text::XSimpleText>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<text::XTextRange> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<text::XTextRange>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // #i61527# cache property set info for this object
+ if ( !mxPropSetInfo.is() )
+ {
+ // mix own and aggregated properties:
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ {
+ uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo());
+ const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties());
+ mxPropSetInfo.set(new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq ));
+ }
+ }
+ return mxPropSetInfo;
+}
+
+BOOL lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
+{
+ USHORT nCount = rModel.GetPageCount();
+ for (USHORT i=0; i<nCount; i++)
+ if ( rModel.GetPage(i) == pPage )
+ {
+ rNum = static_cast<SCTAB>(i);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
+{
+ BOOL bReturn = FALSE;
+ rtl::OUString sType(xShape->getShapeType());
+ sal_Bool bCaptionShape(sType.equalsAscii("com.sun.star.drawing.CaptionShape"));
+ if (bCaptionShape)
+ {
+ uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
+ if (xShapeProp.is())
+ {
+ xShapeProp->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )) ) >>= rCaptionPoint;
+ bReturn = TRUE;
+ }
+ }
+ return bReturn;
+}
+
+ScRange lcl_GetAnchorCell( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab,
+ awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint )
+{
+ ScRange aReturn;
+ rUnoPoint = xShape->getPosition();
+ rtl::OUString sType(xShape->getShapeType());
+ sal_Bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint));
+ if (pDoc->IsNegativePage(nTab))
+ {
+ rUnoSize = xShape->getSize();
+ rUnoPoint.X += rUnoSize.Width; // the right top point is base
+ if (bCaptionShape)
+ {
+ if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width)
+ rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width;
+ if (rCaptionPoint.Y < 0)
+ rUnoPoint.Y += rCaptionPoint.Y;
+ }
+ aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
+ }
+ else
+ {
+ if (bCaptionShape)
+ {
+ if (rCaptionPoint.X < 0)
+ rUnoPoint.X += rCaptionPoint.X;
+ if (rCaptionPoint.Y < 0)
+ rUnoPoint.Y += rCaptionPoint.Y;
+ }
+ aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
+ }
+
+ return aReturn;
+}
+
+awt::Point lcl_GetRelativePos( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, ScRange& rRange,
+ awt::Size& rUnoSize, awt::Point& rCaptionPoint)
+{
+ awt::Point aUnoPoint;
+ rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint);
+ if (pDoc->IsNegativePage(nTab))
+ {
+ Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
+ Point aPoint(aRect.TopRight());
+ aUnoPoint.X -= aPoint.X();
+ aUnoPoint.Y -= aPoint.Y();
+ }
+ else
+ {
+ ScRange aRange = pDoc->GetRange( nTab, Rectangle( VCLPoint(aUnoPoint), VCLPoint(aUnoPoint) ));
+ Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
+ Point aPoint(aRect.TopLeft());
+ aUnoPoint.X -= aPoint.X();
+ aUnoPoint.Y -= aPoint.Y();
+ }
+
+ return aUnoPoint;
+}
+
+void SAL_CALL ScShapeObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
+ {
+ uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY);
+ if (xRangeAdd.is())
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress();
+ if (nTab == aAddress.Sheet)
+ {
+ if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet
+ {
+ DBG_ASSERT(aAddress.StartRow == 0 && aAddress.EndRow == MAXROW &&
+ aAddress.StartColumn == 0 && aAddress.EndColumn == MAXCOL, "here should be a XSpreadsheet");
+ ScDrawLayer::SetAnchor(pObj, SCA_PAGE);
+ }
+ else
+ {
+ DBG_ASSERT(aAddress.StartRow == aAddress.EndRow &&
+ aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell");
+ ScDrawLayer::SetAnchor(pObj, SCA_CELL);
+ }
+ Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow),
+ static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet ));
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ Point aPoint;
+ Point aEndPoint;
+ if (pDoc->IsNegativePage(nTab))
+ {
+ aPoint = aRect.TopRight();
+ aEndPoint = aRect.BottomLeft();
+ }
+ else
+ {
+ aPoint = aRect.TopLeft();
+ aEndPoint = aRect.BottomRight();
+ }
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+
+ aUnoPoint.X += aPoint.X();
+ aUnoPoint.Y += aPoint.Y();
+
+ if ( aUnoPoint.Y > aEndPoint.Y() )
+ aUnoPoint.Y = aEndPoint.Y() - 2;
+ if (pDoc->IsNegativePage(nTab))
+ {
+ if ( aUnoPoint.X < aEndPoint.X() )
+ aUnoPoint.X = aEndPoint.X() + 2;
+ aUnoPoint.X -= aUnoSize.Width;
+ // remove difference to caption point
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
+ aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
+ }
+ else
+ {
+ if ( aUnoPoint.X > aEndPoint.X() )
+ aUnoPoint.X = aEndPoint.X() - 2;
+ if (aCaptionPoint.X < 0)
+ aUnoPoint.X -= aCaptionPoint.X;
+ }
+ if (aCaptionPoint.Y < 0)
+ aUnoPoint.Y -= aCaptionPoint.Y;
+
+ xShape->setPosition(aUnoPoint);
+ pDocSh->SetModified();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("only XCell or XSpreadsheet objects allowed")), static_cast<cppu::OWeakObject*>(this), 0);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ImageMap aImageMap;
+ uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY);
+
+ if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) )
+ throw lang::IllegalArgumentException();
+
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
+ if( pIMapInfo )
+ {
+ // replace existing image map
+ pIMapInfo->SetImageMap( aImageMap );
+ }
+ else
+ {
+ // insert new user data with image map
+ pObj->InsertUserData(new ScIMapInfo(aImageMap) );
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
+ {
+ sal_Int32 nPos = 0;
+ if (aValue >>= nPos)
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
+ {
+ awt::Point aPoint(xShape->getPosition());
+ awt::Size aSize(xShape->getSize());
+ awt::Point aCaptionPoint;
+ if (pDoc->IsNegativePage(nTab))
+ {
+ nPos *= -1;
+ nPos -= aSize.Width;
+ }
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (pDoc->IsNegativePage(nTab))
+ {
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width)
+ nPos -= aCaptionPoint.X - aSize.Width;
+ }
+ else
+ {
+ if (aCaptionPoint.X < 0)
+ nPos -= aCaptionPoint.X;
+ }
+ }
+ aPoint.X = nPos;
+ xShape->setPosition(aPoint);
+ pDocSh->SetModified();
+ }
+ else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+ Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
+ if (pDoc->IsNegativePage(nTab))
+ {
+ aUnoPoint.X = -nPos;
+ Point aPoint(aRect.TopRight());
+ Point aEndPoint(aRect.BottomLeft());
+ aUnoPoint.X += aPoint.X();
+ if (aUnoPoint.X < aEndPoint.X())
+ aUnoPoint.X = aEndPoint.X() + 2;
+ aUnoPoint.X -= aUnoSize.Width;
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
+ aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
+ }
+ else
+ {
+ aUnoPoint.X = nPos;
+ Point aPoint(aRect.TopLeft());
+ Point aEndPoint(aRect.BottomRight());
+ aUnoPoint.X += aPoint.X();
+ if (aUnoPoint.X > aEndPoint.X())
+ aUnoPoint.X = aEndPoint.X() - 2;
+ if (aCaptionPoint.X < 0)
+ aUnoPoint.X -= aCaptionPoint.X;
+ }
+ aUnoPoint.Y = xShape->getPosition().Y;
+ xShape->setPosition(aUnoPoint);
+ pDocSh->SetModified();
+ }
+ else
+ {
+ DBG_ERROR("unknown anchor type");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
+ {
+ sal_Int32 nPos = 0;
+ if (aValue >>= nPos)
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
+ {
+ awt::Point aPoint = xShape->getPosition();
+ awt::Point aCaptionPoint;
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (aCaptionPoint.Y < 0)
+ nPos -= aCaptionPoint.Y;
+ }
+ aPoint.Y = nPos;
+ xShape->setPosition(aPoint);
+ pDocSh->SetModified();
+ }
+ else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+ Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
+ Point aPoint(aRect.TopRight());
+ Point aEndPoint(aRect.BottomLeft());
+ aUnoPoint.Y = nPos;
+ aUnoPoint.Y += aPoint.Y();
+ if (aUnoPoint.Y > aEndPoint.Y())
+ aUnoPoint.Y = aEndPoint.Y() - 2;
+ if (aCaptionPoint.Y < 0)
+ aUnoPoint.Y -= aCaptionPoint.Y;
+ aUnoPoint.X = xShape->getPosition().X;
+ xShape->setPosition(aUnoPoint);
+ pDocSh->SetModified();
+ }
+ else
+ {
+ DBG_ERROR("unknown anchor type");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->setPropertyValue( aPropertyName, aValue );
+ }
+}
+
+uno::Any SAL_CALL ScShapeObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString = aPropertyName;
+
+ uno::Any aAny;
+ if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+ uno::Reference< uno::XInterface > xAnchor;
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+
+ xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, aRange.aStart )));
+ }
+ }
+ else
+ {
+ xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab )));
+ }
+ aAny <<= xAnchor;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ uno::Reference< uno::XInterface > xImageMap;
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(GetSdrObject());
+ if( pIMapInfo )
+ {
+ const ImageMap& rIMap = pIMapInfo->GetImageMap();
+ xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
+ }
+ else
+ xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() );
+ }
+ aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+ if (pDoc->IsNegativePage(nTab))
+ aUnoPoint.X *= -1;
+ aAny <<= aUnoPoint.X;
+ }
+ else
+ {
+ awt::Point aCaptionPoint;
+ awt::Point aUnoPoint(xShape->getPosition());
+ awt::Size aUnoSize(xShape->getSize());
+ if (pDoc->IsNegativePage(nTab))
+ {
+ aUnoPoint.X *= -1;
+ aUnoPoint.X -= aUnoSize.Width;
+ }
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (pDoc->IsNegativePage(nTab))
+ {
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
+ aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
+ }
+ else
+ {
+ if (aCaptionPoint.X < 0)
+ aUnoPoint.X += aCaptionPoint.X;
+ }
+ }
+ aAny <<= aUnoPoint.X;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ uno::Reference< uno::XInterface > xAnchor;
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+
+ aAny <<= aUnoPoint.Y;
+ }
+ else
+ {
+ awt::Point aUnoPoint(xShape->getPosition());
+ awt::Point aCaptionPoint;
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (aCaptionPoint.Y < 0)
+ aUnoPoint.Y += aCaptionPoint.Y;
+ }
+ aAny <<= aUnoPoint.Y;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ aAny = pShapePropertySet->getPropertyValue( aPropertyName );
+ }
+
+ return aAny;
+}
+
+void SAL_CALL ScShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XPropertyChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
+
+ if ( !bInitializedNotifier )
+ {
+ // here's the latest chance to initialize the property notification at the SdrObject
+ // (in the ctor, where we also attempt to do this, we do not necessarily have
+ // and SdrObject, yet)
+ SdrObject* pObj = GetSdrObject();
+ OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" );
+ if ( pObj )
+ lcl_initializeNotifier( *pObj, *this );
+ bInitializedNotifier = true;
+ }
+}
+
+void SAL_CALL ScShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XPropertyChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
+}
+
+void SAL_CALL ScShapeObj::addVetoableChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XVetoableChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
+}
+
+void SAL_CALL ScShapeObj::removeVetoableChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XVetoableChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
+}
+
+// XPropertyState
+
+beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+
+ beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ // ImageMap is always "direct"
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
+ {
+ // Anchor is always "direct"
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
+ {
+ // HoriPos is always "direct"
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
+ {
+ // VertPos is always "direct"
+ }
+ else
+ {
+ GetShapePropertyState();
+ if (pShapePropertyState)
+ eRet = pShapePropertyState->getPropertyState( aPropertyName );
+ }
+
+ return eRet;
+}
+
+uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
+ const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // simple loop to get own and aggregated states
+
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
+ pStates[i] = getPropertyState(pNames[i]);
+ return aRet;
+}
+
+void SAL_CALL ScShapeObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
+ if( pIMapInfo )
+ {
+ ImageMap aEmpty;
+ pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
+ }
+ else
+ {
+ // nothing to do (no need to insert user data for an empty map)
+ }
+ }
+ }
+ else
+ {
+ GetShapePropertyState();
+ if (pShapePropertyState)
+ pShapePropertyState->setPropertyToDefault( aPropertyName );
+ }
+}
+
+uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString = aPropertyName;
+
+ uno::Any aAny;
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ // default: empty ImageMap
+ uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() ));
+ aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
+ }
+ else
+ {
+ GetShapePropertyState();
+ if (pShapePropertyState)
+ aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
+ }
+
+ return aAny;
+}
+
+// XTextContent
+
+void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ throw lang::IllegalArgumentException(); // anchor cannot be changed
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xRet;
+
+ SdrObject* pObj = GetSdrObject();
+ if( pObj )
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ Point aPos(pObj->GetCurrentBoundRect().TopLeft());
+ ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) ));
+
+ // anchor is always the cell
+
+ xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
+ }
+ }
+ }
+ }
+ }
+
+ return xRet;
+}
+
+// XComponent
+
+void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
+ if ( xAggComp.is() )
+ xAggComp->dispose();
+}
+
+void SAL_CALL ScShapeObj::addEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
+ if ( xAggComp.is() )
+ xAggComp->addEventListener(xListener);
+}
+
+void SAL_CALL ScShapeObj::removeEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
+ if ( xAggComp.is() )
+ xAggComp->removeEventListener(xListener);
+}
+
+// XText
+// (special handling for ScCellFieldObj)
+
+void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName )
+{
+ rtl::OUString aNameStr(rtl::OUString::createFromAscii(pName));
+ try
+ {
+ rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
+ }
+ catch (uno::Exception&)
+ {
+ DBG_ERROR("Exception in text field");
+ }
+}
+
+void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
+ const uno::Reference<text::XTextContent>& xContent,
+ sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextContent> xEffContent;
+
+ ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
+ if ( pCellField )
+ {
+ // #105585# createInstance("TextField.URL") from the document creates a ScCellFieldObj.
+ // To insert it into drawing text, a SvxUnoTextField is needed instead.
+ // The ScCellFieldObj object is left in non-inserted state.
+
+ SvxUnoTextField* pDrawField = new SvxUnoTextField( ID_URLFIELD );
+ xEffContent.set(pDrawField);
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
+ }
+ else
+ xEffContent.set(xContent);
+
+ uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
+ if ( xAggText.is() )
+ xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
+}
+
+void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // ScCellFieldObj can't be used here.
+
+ uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
+ if ( xAggText.is() )
+ xAggText->removeTextContent( xContent );
+}
+
+// XSimpleText (parent of XText)
+// Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
+
+uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( mxShapeAgg.is() )
+ {
+ // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
+
+ SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
+ if (pText)
+ return new ScDrawTextCursor( this, *pText );
+ }
+
+ return uno::Reference<text::XTextCursor>();
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( mxShapeAgg.is() && aTextPosition.is() )
+ {
+ // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
+
+ SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
+ if ( pText && pRange )
+ {
+ SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
+ uno::Reference<text::XTextCursor> xCursor( pCursor );
+ pCursor->SetSelection( pRange->GetSelection() );
+ return xCursor;
+ }
+ }
+
+ return uno::Reference<text::XTextCursor>();
+}
+
+void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
+ if ( xAggSimpleText.is() )
+ xAggSimpleText->insertString( xRange, aString, bAbsorb );
+ else
+ throw uno::RuntimeException();
+}
+
+void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
+ if ( xAggSimpleText.is() )
+ xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+ else
+ throw uno::RuntimeException();
+}
+
+// XTextRange
+// (parent of XSimpleText)
+
+uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return this;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ return xAggTextRange->getStart();
+ else
+ throw uno::RuntimeException();
+
+// return uno::Reference<text::XTextRange>();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ return xAggTextRange->getEnd();
+ else
+ throw uno::RuntimeException();
+
+// return uno::Reference<text::XTextRange>();
+}
+
+rtl::OUString SAL_CALL ScShapeObj::getString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ return xAggTextRange->getString();
+ else
+ throw uno::RuntimeException();
+
+// return rtl::OUString();
+}
+
+void SAL_CALL ScShapeObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ xAggTextRange->setString( aText );
+ else
+ throw uno::RuntimeException();
+}
+
+// XTypeProvider
+
+uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException)
+{
+ uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
+
+ uno::Sequence< uno::Type > aTextTypes;
+ if ( bIsTextShape )
+ aTextTypes = ScShapeObj_TextBase::getTypes();
+
+ uno::Reference<lang::XTypeProvider> xBaseProvider;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider;
+ DBG_ASSERT( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
+
+ uno::Sequence< uno::Type > aAggTypes;
+ if( xBaseProvider.is() )
+ aAggTypes = xBaseProvider->getTypes();
+
+ return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // do we need to compute the implementation id for this instance?
+ if( !pImplementationId && mxShapeAgg.is())
+ {
+ uno::Reference< drawing::XShape > xAggShape;
+ mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape;
+
+ if( xAggShape.is() )
+ {
+ const rtl::OUString aShapeType( xAggShape->getShapeType() );
+ // did we already compute an implementation id for the agregated shape type?
+ ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
+ if( aIter == aImplementationIdMap.end() )
+ {
+ // we need to create a new implementation id for this
+ // note: this memory is not free'd until application exists
+ // but since we have a fixed set of shapetypes and the
+ // memory will be reused this is ok.
+ pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
+ rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
+ aImplementationIdMap[ aShapeType ] = pImplementationId;
+ }
+ else
+ {
+ // use the already computed implementation id
+ pImplementationId = (*aIter).second;
+ }
+ }
+ }
+ if( NULL == pImplementationId )
+ {
+ DBG_ERROR( "Could not create an implementation id for a ScXShape!" );
+ return uno::Sequence< sal_Int8 > ();
+ }
+ else
+ {
+ return *pImplementationId;
+ }
+}
+
+SdrObject* ScShapeObj::GetSdrObject() const throw()
+{
+ if(mxShapeAgg.is())
+ {
+ SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg );
+ if(pShape)
+ return pShape->GetSdrObject();
+ }
+
+ return NULL;
+}
+
+#define SC_EVENTACC_ONCLICK ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) )
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+#define SC_EVENTACC_ONACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAction" ) )
+#define SC_EVENTACC_URL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) )
+#define SC_EVENTACC_ACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Action" ) )
+#endif
+#define SC_EVENTACC_SCRIPT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) )
+#define SC_EVENTACC_EVENTTYPE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) )
+
+typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE;
+class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE
+{
+private:
+ ScShapeObj* mpShape;
+
+ ScMacroInfo* getInfo( BOOL bCreate = FALSE )
+ {
+ if( mpShape )
+ if( SdrObject* pObj = mpShape->GetSdrObject() )
+ return ScDrawLayer::GetMacroInfo( pObj, bCreate );
+ return 0;
+ }
+
+public:
+ ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
+ {
+ }
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ uno::Sequence< beans::PropertyValue > aProperties;
+ aElement >>= aProperties;
+ const beans::PropertyValue* pProperties = aProperties.getConstArray();
+ const sal_Int32 nCount = aProperties.getLength();
+ sal_Int32 nIndex;
+ bool isEventType = false;
+ for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ )
+ {
+ if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) )
+ {
+ isEventType = true;
+ continue;
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ if ( isEventType && ((pProperties->Name == SC_EVENTACC_SCRIPT) || (pProperties->Name == SC_EVENTACC_URL)) )
+#else
+ if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) )
+#endif
+ {
+ rtl::OUString sValue;
+ if ( pProperties->Value >>= sValue )
+ {
+ ScMacroInfo* pInfo = getInfo( TRUE );
+ DBG_ASSERT( pInfo, "shape macro info could not be created!" );
+ if ( !pInfo )
+ break;
+ if ( pProperties->Name == SC_EVENTACC_SCRIPT )
+ pInfo->SetMacro( sValue );
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ else
+ pInfo->SetHlink( sValue );
+#endif
+ }
+ }
+ }
+ }
+
+ // XNameAccess
+ virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ uno::Sequence< beans::PropertyValue > aProperties;
+ ScMacroInfo* pInfo = getInfo();
+
+ if ( aName == SC_EVENTACC_ONCLICK )
+ {
+ if ( pInfo && (pInfo->GetMacro().getLength() > 0) )
+ {
+ aProperties.realloc( 2 );
+ aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
+ aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT;
+ aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
+ aProperties[ 1 ].Value <<= pInfo->GetMacro();
+ }
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ else if( aName == SC_EVENTACC_ONACTION )
+ {
+ if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
+ {
+ aProperties.realloc( 2 );
+ aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
+ aProperties[ 0 ].Value <<= SC_EVENTACC_ACTION;
+ aProperties[ 1 ].Name = SC_EVENTACC_URL;
+ aProperties[ 1 ].Value <<= pInfo->GetHlink();
+ }
+ }
+#endif
+ else
+ {
+ throw container::NoSuchElementException();
+ }
+
+ return uno::Any( aProperties );
+ }
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames() throw(uno::RuntimeException)
+ {
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ uno::Sequence< rtl::OUString > aSeq( 2 );
+#else
+ uno::Sequence< rtl::OUString > aSeq( 1 );
+#endif
+ aSeq[ 0 ] = SC_EVENTACC_ONCLICK;
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ aSeq[ 1 ] = SC_EVENTACC_ONACTION;
+#endif
+ return aSeq;
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+ {
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ return (aName == SC_EVENTACC_ONCLICK) || (aName == SC_EVENTACC_ONACTION);
+#else
+ return aName == SC_EVENTACC_ONCLICK;
+#endif
+ }
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException)
+ {
+ return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
+ }
+
+ virtual sal_Bool SAL_CALL hasElements() throw(uno::RuntimeException)
+ {
+ // elements are always present (but contained property sequences may be empty)
+ return sal_True;
+ }
+};
+
+::uno::Reference< container::XNameReplace > SAL_CALL
+ScShapeObj::getEvents( ) throw(uno::RuntimeException)
+{
+ return new ShapeUnoEventAccessImpl( this );
+}
+
+::rtl::OUString SAL_CALL ScShapeObj::getImplementationName( ) throw (uno::RuntimeException)
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sc.ScShapeObj" ) );
+}
+
+::sal_Bool SAL_CALL ScShapeObj::supportsService( const ::rtl::OUString& _ServiceName ) throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
+ for ( const ::rtl::OUString* pSupported = aSupported.getConstArray();
+ pSupported != aSupported.getConstArray() + aSupported.getLength();
+ ++pSupported
+ )
+ if ( _ServiceName == *pSupported )
+ return sal_True;
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( ) throw (uno::RuntimeException)
+{
+ uno::Reference<lang::XServiceInfo> xSI;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI;
+
+ uno::Sequence< ::rtl::OUString > aSupported;
+ if ( xSI.is() )
+ aSupported = xSI->getSupportedServiceNames();
+
+ aSupported.realloc( aSupported.getLength() + 1 );
+ aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) );
+ return aSupported;
+}
diff --git a/sc/source/ui/unoobj/srchuno.cxx b/sc/source/ui/unoobj/srchuno.cxx
new file mode 100644
index 000000000000..b005d16ce482
--- /dev/null
+++ b/sc/source/ui/unoobj/srchuno.cxx
@@ -0,0 +1,276 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/uuid.h>
+
+#include "srchuno.hxx"
+#include "docsh.hxx"
+#include "undoblk.hxx"
+#include "hints.hxx"
+#include "markdata.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "unonames.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+//! SearchWords sucht in ganzen Zellen - umbenennen ???
+
+// SfxItemPropertyMapEntry nur fuer GetPropertySetInfo
+
+const SfxItemPropertyMapEntry* lcl_GetSearchPropertyMap()
+{
+ static SfxItemPropertyMapEntry aSearchPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_SRCHBACK), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHBYROW), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHCASE), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHREGEXP), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHSIM), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHSIMADD), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHSIMEX), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHSIMREL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHSIMREM), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHSTYLES), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SRCHTYPE), 0, &getCppuType((sal_Int16*)0), 0, 0}, // enum TableSearch ist weg
+ {MAP_CHAR_LEN(SC_UNO_SRCHWORDS), 0, &getBooleanCppuType(), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aSearchPropertyMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+#define SCSEARCHDESCRIPTOR_SERVICE "com.sun.star.util.SearchDescriptor"
+#define SCREPLACEDESCRIPTOR_SERVICE "com.sun.star.util.ReplaceDescriptor"
+
+//------------------------------------------------------------------------
+
+ScCellSearchObj::ScCellSearchObj() :
+ aPropSet(lcl_GetSearchPropertyMap())
+{
+ pSearchItem = new SvxSearchItem( SCITEM_SEARCHDATA );
+ // Defaults:
+ pSearchItem->SetWordOnly(FALSE);
+ pSearchItem->SetExact(FALSE);
+ pSearchItem->SetMatchFullHalfWidthForms(FALSE);
+ pSearchItem->SetUseAsianOptions(FALSE); // or all asian bits would have to be handled
+ pSearchItem->SetBackward(FALSE);
+ pSearchItem->SetSelection(FALSE);
+ pSearchItem->SetRegExp(FALSE);
+ pSearchItem->SetPattern(FALSE);
+ pSearchItem->SetLevenshtein(FALSE);
+ pSearchItem->SetLEVRelaxed(FALSE);
+ pSearchItem->SetLEVOther(2);
+ pSearchItem->SetLEVShorter(2);
+ pSearchItem->SetLEVLonger(2);
+ // Calc-Flags
+ pSearchItem->SetRowDirection(FALSE);
+ pSearchItem->SetCellType(SVX_SEARCHIN_FORMULA);
+
+ // Selection-Flag wird beim Aufruf gesetzt
+}
+
+ScCellSearchObj::~ScCellSearchObj()
+{
+ delete pSearchItem;
+}
+
+// XSearchDescriptor
+
+rtl::OUString SAL_CALL ScCellSearchObj::getSearchString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return pSearchItem->GetSearchString();
+}
+
+void SAL_CALL ScCellSearchObj::setSearchString( const rtl::OUString& aString )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ pSearchItem->SetSearchString( aString );
+}
+
+// XReplaceDescriptor
+
+rtl::OUString SAL_CALL ScCellSearchObj::getReplaceString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return pSearchItem->GetReplaceString();
+}
+
+void SAL_CALL ScCellSearchObj::setReplaceString( const rtl::OUString& aReplaceString )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ pSearchItem->SetReplaceString( aReplaceString );
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellSearchObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScCellSearchObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+
+ if (aString.EqualsAscii( SC_UNO_SRCHBACK )) pSearchItem->SetBackward( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHBYROW )) pSearchItem->SetRowDirection( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHCASE )) pSearchItem->SetExact( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHREGEXP )) pSearchItem->SetRegExp( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIM )) pSearchItem->SetLevenshtein( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMREL )) pSearchItem->SetLEVRelaxed( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSTYLES )) pSearchItem->SetPattern( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHWORDS )) pSearchItem->SetWordOnly( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMADD )) pSearchItem->SetLEVLonger( ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMEX )) pSearchItem->SetLEVOther( ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMREM )) pSearchItem->SetLEVShorter( ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+ else if (aString.EqualsAscii( SC_UNO_SRCHTYPE )) pSearchItem->SetCellType( ScUnoHelpFunctions::GetInt16FromAny( aValue ) );
+}
+
+uno::Any SAL_CALL ScCellSearchObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+ uno::Any aRet;
+
+ if (aString.EqualsAscii( SC_UNO_SRCHBACK )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->GetBackward() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHBYROW )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->GetRowDirection() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHCASE )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->GetExact() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHREGEXP )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->GetRegExp() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIM )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->IsLevenshtein() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMREL )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->IsLEVRelaxed() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSTYLES )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->GetPattern() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHWORDS )) ScUnoHelpFunctions::SetBoolInAny( aRet, pSearchItem->GetWordOnly() );
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMADD )) aRet <<= (sal_Int16) pSearchItem->GetLEVLonger();
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMEX )) aRet <<= (sal_Int16) pSearchItem->GetLEVOther();
+ else if (aString.EqualsAscii( SC_UNO_SRCHSIMREM )) aRet <<= (sal_Int16) pSearchItem->GetLEVShorter();
+ else if (aString.EqualsAscii( SC_UNO_SRCHTYPE )) aRet <<= (sal_Int16) pSearchItem->GetCellType();
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScCellSearchObj )
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScCellSearchObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScCellSearchObj" );
+}
+
+sal_Bool SAL_CALL ScCellSearchObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr(rServiceName);
+ return aServiceStr.EqualsAscii( SCSEARCHDESCRIPTOR_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCREPLACEDESCRIPTOR_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScCellSearchObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSEARCHDESCRIPTOR_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCREPLACEDESCRIPTOR_SERVICE );
+ return aRet;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScCellSearchObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScCellSearchObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScCellSearchObj* ScCellSearchObj::getImplementation(
+ const uno::Reference<util::XSearchDescriptor> xObj )
+{
+ ScCellSearchObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScCellSearchObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+
+//------------------------------------------------------------------------
+
+
+
+
+
diff --git a/sc/source/ui/unoobj/styleuno.cxx b/sc/source/ui/unoobj/styleuno.cxx
new file mode 100644
index 000000000000..50aecbe7f2e3
--- /dev/null
+++ b/sc/source/ui/unoobj/styleuno.cxx
@@ -0,0 +1,2140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/memberids.hrc>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/numitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <svx/unomid.hxx>
+#include <editeng/unonrule.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/printer.hxx>
+#include <vcl/virdev.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zformat.hxx>
+#include <rtl/uuid.h>
+
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/style/PageStyleLayout.hpp>
+#include <com/sun/star/style/GraphicLocation.hpp>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include <com/sun/star/util/CellProtection.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include "styleuno.hxx"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "stlpool.hxx"
+#include "docpool.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "convuno.hxx"
+#include "tablink.hxx"
+#include "unonames.hxx"
+#include "unowids.hxx"
+#include "globstr.hrc"
+#include "cellsuno.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+const SfxItemPropertySet* lcl_GetCellStyleSet()
+{
+ static SfxItemPropertyMapEntry aCellStyleMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLPRO), ATTR_PROTECTION, &::getCppuType((const util::CellProtection*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCOLOR), ATTR_FONT_COLOR, &::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_COUTL), ATTR_FONT_CONTOUR, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CCROSS), ATTR_FONT_CROSSEDOUT,&::getBooleanCppuType(), 0, MID_CROSSED_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS), ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0), 0, MID_EMPHASIS },
+ {MAP_CHAR_LEN(SC_UNONAME_CFONT), ATTR_FONT, &::getCppuType((const sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET },
+ {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY },
+ {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH },
+ {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME },
+ {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT), ATTR_FONT_HEIGHT, &::getCppuType((const float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT), ATTR_CJK_FONT_HEIGHT,&::getCppuType((const float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT), ATTR_CTL_FONT_HEIGHT,&::getCppuType((const float*)0), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &::getCppuType((const lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE,&::getCppuType((const lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE,&::getCppuType((const lang::Locale*)0), 0, MID_LANG_LOCALE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVER), ATTR_FONT_OVERLINE, &::getCppuType((const sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CPOST), ATTR_FONT_POSTURE, &::getCppuType((const awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CPOST), ATTR_CJK_FONT_POSTURE,&::getCppuType((const awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CPOST), ATTR_CTL_FONT_POSTURE,&::getCppuType((const awt::FontSlant*)0), 0, MID_POSTURE },
+ {MAP_CHAR_LEN(SC_UNONAME_CRELIEF), ATTR_FONT_RELIEF, &getCppuType((sal_Int16*)0), 0, MID_RELIEF },
+ {MAP_CHAR_LEN(SC_UNONAME_CSHADD), ATTR_FONT_SHADOWED, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE), ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0), 0, MID_CROSS_OUT },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDER), ATTR_FONT_UNDERLINE,&::getCppuType((const sal_Int16*)0), 0, MID_TL_STYLE },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0), 0, MID_TL_COLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(), 0, MID_TL_HASCOLOR },
+ {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT), ATTR_FONT_WEIGHT, &::getCppuType((const float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT), ATTR_CJK_FONT_WEIGHT,&::getCppuType((const float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT), ATTR_CTL_FONT_WEIGHT,&::getCppuType((const float*)0), 0, MID_WEIGHT },
+ {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_DISPNAME), SC_WID_UNO_DISPNAME,&::getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY, &::getCppuType((const table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNONAME_WRAP), ATTR_LINEBREAK, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_NUMFMT), ATTR_VALUE_FORMAT, &::getCppuType((const sal_Int32*)0), 0, 0 },
+// {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLORI), ATTR_STACKED, &::getCppuType((const table::CellOrientation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PADJUST), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PINDENT), ATTR_INDENT, &::getCppuType((const sal_Int16*)0), 0, 0 }, //! CONVERT_TWIPS
+ {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHANG), ATTR_HANGPUNCTUATION,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY, &::getCppuType((const sal_Int16*)0), 0, MID_HORJUST_ADJUST },
+ {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN, &::getCppuType((const sal_Int32*)0), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTANG), ATTR_ROTATE_VALUE, &::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_ROTREF), ATTR_ROTATE_MODE, &::getCppuType((const table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_SHADOW), ATTR_SHADOW, &::getCppuType((const table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_TBLBORD), SC_WID_UNO_TBLBORD, &::getCppuType((const table::TableBorder*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &::getCppuType((const table::CellVertJustify*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aCellStyleSet_Impl( aCellStyleMap_Impl );
+ return &aCellStyleSet_Impl;
+}
+
+// Map mit allen Seitenattributen, incl. Kopf-/Fusszeilenattribute
+
+const SfxItemPropertySet * lcl_GetPageStyleSet()
+{
+ static SfxItemPropertyMapEntry aPageStyleMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_PAGE_BACKCOLOR), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_GRAPHICFILT), ATTR_BACKGROUND, &::getCppuType((const ::rtl::OUString*)0), 0, MID_GRAPHIC_FILTER },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_GRAPHICLOC), ATTR_BACKGROUND, &::getCppuType((const style::GraphicLocation*)0), 0, MID_GRAPHIC_POSITION },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_GRAPHICURL), ATTR_BACKGROUND, &::getCppuType((const ::rtl::OUString*)0), 0, MID_GRAPHIC_URL },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_BACKTRANS), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_BACKCOLOR), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_BORDERDIST), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_BOTTBORDER), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_BOTTBRDDIST), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_BOTTMARGIN), ATTR_ULSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_CENTERHOR), ATTR_PAGE_HORCENTER,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_CENTERVER), ATTR_PAGE_VERCENTER,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_DISPNAME), SC_WID_UNO_DISPNAME,&::getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FIRSTPAGE), ATTR_PAGE_FIRSTPAGENO,&::getCppuType((const sal_Int16*)0), 0, 0 },
+//
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBACKCOL), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRGRFFILT), SC_WID_UNO_FOOTERSET,&::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRGRFLOC), SC_WID_UNO_FOOTERSET,&::getCppuType((const style::GraphicLocation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRGRFURL), SC_WID_UNO_FOOTERSET,&::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBACKTRAN), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRBACKCOL), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBODYDIST), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBRDDIST), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBOTTBOR), SC_WID_UNO_FOOTERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBOTTBDIS), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRDYNAMIC), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRHEIGHT), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRDYNAMIC), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRON), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRSHARED), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRLEFTBOR), SC_WID_UNO_FOOTERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRLEFTBDIS), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRLEFTMAR), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRON), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRRIGHTBOR), SC_WID_UNO_FOOTERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRRIGHTBDIS),SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRRIGHTMAR), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRSHADOW), SC_WID_UNO_FOOTERSET,&::getCppuType((const table::ShadowFormat*)0), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRSHARED), SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRTOPBOR), SC_WID_UNO_FOOTERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRTOPBDIS), SC_WID_UNO_FOOTERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+//
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBACKCOL), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRGRFFILT), SC_WID_UNO_HEADERSET,&::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRGRFLOC), SC_WID_UNO_HEADERSET,&::getCppuType((const style::GraphicLocation*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRGRFURL), SC_WID_UNO_HEADERSET,&::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBACKTRAN), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRBACKCOL), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBODYDIST), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBRDDIST), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBOTTBOR), SC_WID_UNO_HEADERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBOTTBDIS), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRDYNAMIC), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRHEIGHT), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRDYNAMIC), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRON), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRSHARED), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRLEFTBOR), SC_WID_UNO_HEADERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRLEFTBDIS), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRLEFTMAR), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRON), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRRIGHTBOR), SC_WID_UNO_HEADERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRRIGHTBDIS),SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRRIGHTMAR), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRSHADOW), SC_WID_UNO_HEADERSET,&::getCppuType((const table::ShadowFormat*)0), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRSHARED), SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRTOPBOR), SC_WID_UNO_HEADERSET,&::getCppuType((const table::BorderLine*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRTOPBDIS), SC_WID_UNO_HEADERSET,&::getCppuType((const sal_Int32*)0), 0, 0 },
+//
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HEIGHT), ATTR_PAGE_SIZE, &::getCppuType((const sal_Int32*)0), 0, MID_SIZE_HEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_BACKTRANS), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_LANDSCAPE), ATTR_PAGE, &::getBooleanCppuType(), 0, MID_PAGE_ORIENTATION },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_LEFTBORDER), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_LEFTBRDDIST), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, LEFT_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_LEFTMARGIN), ATTR_LRSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_LEFTFTRCONT), ATTR_PAGE_FOOTERLEFT,&::getCppuType((const uno::Reference< sheet::XHeaderFooterContent >*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_LEFTHDRCONT), ATTR_PAGE_HEADERLEFT,&::getCppuType((const uno::Reference< sheet::XHeaderFooterContent >*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_NUMBERTYPE), ATTR_PAGE, &::getCppuType((const sal_Int16*)0), 0, MID_PAGE_NUMTYPE },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SCALEVAL), ATTR_PAGE_SCALE, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SYTLELAYOUT), ATTR_PAGE, &::getCppuType((const style::PageStyleLayout*)0), 0, MID_PAGE_LAYOUT },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTANNOT), ATTR_PAGE_NOTES, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTCHARTS), ATTR_PAGE_CHARTS, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTDOWN), ATTR_PAGE_TOPDOWN, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTDRAW), ATTR_PAGE_DRAWINGS, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTFORMUL), ATTR_PAGE_FORMULAS, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTGRID), ATTR_PAGE_GRID, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTHEADER), ATTR_PAGE_HEADERS, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTOBJS), ATTR_PAGE_OBJECTS, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PRINTZERO), ATTR_PAGE_NULLVALS, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_PAPERTRAY), ATTR_PAGE_PAPERBIN, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_RIGHTBORDER), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_RIGHTBRDDIST),ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_RIGHTMARGIN), ATTR_LRSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_RIGHTFTRCON), ATTR_PAGE_FOOTERRIGHT,&::getCppuType((const uno::Reference< sheet::XHeaderFooterContent >*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_RIGHTHDRCON), ATTR_PAGE_HEADERRIGHT,&::getCppuType((const uno::Reference< sheet::XHeaderFooterContent >*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SCALETOPAG), ATTR_PAGE_SCALETOPAGES,&::getCppuType((const sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SCALETOX), ATTR_PAGE_SCALETO, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SCALETOY), ATTR_PAGE_SCALETO, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SHADOWFORM), ATTR_SHADOW, &::getCppuType((const table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_SIZE), ATTR_PAGE_SIZE, &::getCppuType((const awt::Size*)0), 0, MID_SIZE_SIZE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_TOPBORDER), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_TOPBRDDIST), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, TOP_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_TOPMARGIN), ATTR_ULSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRBACKTRAN),SC_WID_UNO_FOOTERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRBACKTRAN),SC_WID_UNO_HEADERSET,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_USERDEF), ATTR_USERDEF, &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_WIDTH), ATTR_PAGE_SIZE, &::getCppuType((const sal_Int32*)0), 0, MID_SIZE_WIDTH | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aPageStyleSet_Impl( aPageStyleMap_Impl );
+ return &aPageStyleSet_Impl;
+}
+
+// Map mit Inhalten des Header-Item-Sets
+
+const SfxItemPropertyMap* lcl_GetHeaderStyleMap()
+{
+ static SfxItemPropertyMapEntry aHeaderStyleMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBACKCOL), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRGRFFILT), ATTR_BACKGROUND, &::getCppuType((const ::rtl::OUString*)0), 0, MID_GRAPHIC_FILTER },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRGRFLOC), ATTR_BACKGROUND, &::getCppuType((const style::GraphicLocation*)0), 0, MID_GRAPHIC_POSITION },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRGRFURL), ATTR_BACKGROUND, &::getCppuType((const ::rtl::OUString*)0), 0, MID_GRAPHIC_URL },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBACKTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRBACKCOL), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBODYDIST), ATTR_ULSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_LO_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBRDDIST), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBOTTBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRBOTTBDIS), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRDYNAMIC), ATTR_PAGE_DYNAMIC, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRHEIGHT), ATTR_PAGE_SIZE, &::getCppuType((const sal_Int32*)0), 0, MID_SIZE_HEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRDYNAMIC), ATTR_PAGE_DYNAMIC, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRON), ATTR_PAGE_ON, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRSHARED), ATTR_PAGE_SHARED, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRLEFTBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRLEFTBDIS), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, LEFT_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRLEFTMAR), ATTR_LRSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRON), ATTR_PAGE_ON, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRRIGHTBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRRIGHTBDIS),ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRRIGHTMAR), ATTR_LRSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRSHADOW), ATTR_SHADOW, &::getCppuType((const table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRSHARED), ATTR_PAGE_SHARED, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRTOPBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_HDRTOPBDIS), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, TOP_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_HDRBACKTRAN),ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertyMap aHeaderStyleMap( aHeaderStyleMap_Impl );
+ return &aHeaderStyleMap;
+}
+
+// Map mit Inhalten des Footer-Item-Sets
+
+const SfxItemPropertyMap* lcl_GetFooterStyleMap()
+{
+ static SfxItemPropertyMapEntry aFooterStyleMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBACKCOL), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRGRFFILT), ATTR_BACKGROUND, &::getCppuType((const ::rtl::OUString*)0), 0, MID_GRAPHIC_FILTER },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRGRFLOC), ATTR_BACKGROUND, &::getCppuType((const style::GraphicLocation*)0), 0, MID_GRAPHIC_POSITION },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRGRFURL), ATTR_BACKGROUND, &::getCppuType((const ::rtl::OUString*)0), 0, MID_GRAPHIC_URL },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBACKTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRBACKCOL), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBODYDIST), ATTR_ULSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_UP_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBRDDIST), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBOTTBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRBOTTBDIS), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRDYNAMIC), ATTR_PAGE_DYNAMIC, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRHEIGHT), ATTR_PAGE_SIZE, &::getCppuType((const sal_Int32*)0), 0, MID_SIZE_HEIGHT | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRDYNAMIC), ATTR_PAGE_DYNAMIC, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRON), ATTR_PAGE_ON, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRSHARED), ATTR_PAGE_SHARED, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRLEFTBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRLEFTBDIS), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, LEFT_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRLEFTMAR), ATTR_LRSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_L_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRON), ATTR_PAGE_ON, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRRIGHTBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRRIGHTBDIS),ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRRIGHTMAR), ATTR_LRSPACE, &::getCppuType((const sal_Int32*)0), 0, MID_R_MARGIN | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRSHADOW), ATTR_SHADOW, &::getCppuType((const table::ShadowFormat*)0), 0, 0 | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRSHARED), ATTR_PAGE_SHARED, &::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRTOPBOR), ATTR_BORDER, &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(SC_UNO_PAGE_FTRTOPBDIS), ATTR_BORDER, &::getCppuType((const sal_Int32*)0), 0, TOP_BORDER_DISTANCE | CONVERT_TWIPS },
+ {MAP_CHAR_LEN(OLD_UNO_PAGE_FTRBACKTRAN),ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertyMap aFooterStyleMap( aFooterStyleMap_Impl );
+ return &aFooterStyleMap;
+}
+
+
+//------------------------------------------------------------------------
+
+// Index-Access auf die Style-Typen: 0 = Cell, 1 = Page
+
+#define SC_STYLE_FAMILY_COUNT 2
+
+#define SC_FAMILYNAME_CELL "CellStyles"
+#define SC_FAMILYNAME_PAGE "PageStyles"
+
+static UINT16 aStyleFamilyTypes[SC_STYLE_FAMILY_COUNT] = { SFX_STYLE_FAMILY_PARA, SFX_STYLE_FAMILY_PAGE };
+
+//------------------------------------------------------------------------
+
+//! diese Funktionen in einen allgemeinen Header verschieben
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+
+//------------------------------------------------------------------------
+
+#define SCSTYLE_SERVICE "com.sun.star.style.Style"
+#define SCCELLSTYLE_SERVICE "com.sun.star.style.CellStyle"
+#define SCPAGESTYLE_SERVICE "com.sun.star.style.PageStyle"
+
+SC_SIMPLE_SERVICE_INFO( ScStyleFamiliesObj, "ScStyleFamiliesObj", "com.sun.star.style.StyleFamilies" )
+SC_SIMPLE_SERVICE_INFO( ScStyleFamilyObj, "ScStyleFamilyObj", "com.sun.star.style.StyleFamily" )
+
+//------------------------------------------------------------------------
+
+#define SC_PAPERBIN_DEFAULTNAME "[From printer settings]"
+
+//------------------------------------------------------------------------
+
+// conversion programmatic <-> display (visible) name
+// currently, the core always has the visible names
+// the api is required to use programmatic names for default styles
+// these programmatic names must never change!
+
+#define SC_STYLE_PROG_STANDARD "Default"
+#define SC_STYLE_PROG_RESULT "Result"
+#define SC_STYLE_PROG_RESULT1 "Result2"
+#define SC_STYLE_PROG_HEADLINE "Heading"
+#define SC_STYLE_PROG_HEADLINE1 "Heading1"
+#define SC_STYLE_PROG_REPORT "Report"
+
+struct ScDisplayNameMap
+{
+ String aDispName;
+ String aProgName;
+};
+
+const ScDisplayNameMap* lcl_GetStyleNameMap( UINT16 nType )
+{
+ if ( nType == SFX_STYLE_FAMILY_PARA )
+ {
+ static BOOL bCellMapFilled = FALSE;
+ static ScDisplayNameMap aCellMap[6];
+ if ( !bCellMapFilled )
+ {
+ aCellMap[0].aDispName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
+ aCellMap[0].aProgName = String::CreateFromAscii( SC_STYLE_PROG_STANDARD );
+
+ aCellMap[1].aDispName = ScGlobal::GetRscString( STR_STYLENAME_RESULT );
+ aCellMap[1].aProgName = String::CreateFromAscii( SC_STYLE_PROG_RESULT );
+
+ aCellMap[2].aDispName = ScGlobal::GetRscString( STR_STYLENAME_RESULT1 );
+ aCellMap[2].aProgName = String::CreateFromAscii( SC_STYLE_PROG_RESULT1 );
+
+ aCellMap[3].aDispName = ScGlobal::GetRscString( STR_STYLENAME_HEADLINE );
+ aCellMap[3].aProgName = String::CreateFromAscii( SC_STYLE_PROG_HEADLINE );
+
+ aCellMap[4].aDispName = ScGlobal::GetRscString( STR_STYLENAME_HEADLINE1 );
+ aCellMap[4].aProgName = String::CreateFromAscii( SC_STYLE_PROG_HEADLINE1 );
+
+ // last entry remains empty
+
+ bCellMapFilled = TRUE;
+ }
+ return aCellMap;
+ }
+ else if ( nType == SFX_STYLE_FAMILY_PAGE )
+ {
+ static BOOL bPageMapFilled = FALSE;
+ static ScDisplayNameMap aPageMap[3];
+ if ( !bPageMapFilled )
+ {
+ aPageMap[0].aDispName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
+ aPageMap[0].aProgName = String::CreateFromAscii( SC_STYLE_PROG_STANDARD );
+
+ aPageMap[1].aDispName = ScGlobal::GetRscString( STR_STYLENAME_REPORT );
+ aPageMap[1].aProgName = String::CreateFromAscii( SC_STYLE_PROG_REPORT );
+
+ // last entry remains empty
+
+ bPageMapFilled = TRUE;
+ }
+ return aPageMap;
+ }
+ DBG_ERROR("invalid family");
+ return NULL;
+}
+
+// programmatic name suffix for display names that match other programmatic names
+// is " (user)" including a space
+
+#define SC_SUFFIX_USER " (user)"
+#define SC_SUFFIX_USER_LEN 7
+
+BOOL lcl_EndsWithUser( const String& rString )
+{
+ const sal_Unicode *pChar = rString.GetBuffer();
+ xub_StrLen nLen = rString.Len();
+ return nLen >= SC_SUFFIX_USER_LEN &&
+ pChar[nLen-7] == ' ' &&
+ pChar[nLen-6] == '(' &&
+ pChar[nLen-5] == 'u' &&
+ pChar[nLen-4] == 's' &&
+ pChar[nLen-3] == 'e' &&
+ pChar[nLen-2] == 'r' &&
+ pChar[nLen-1] == ')';
+}
+
+// static
+String ScStyleNameConversion::DisplayToProgrammaticName( const String& rDispName, UINT16 nType )
+{
+ BOOL bDisplayIsProgrammatic = FALSE;
+
+ const ScDisplayNameMap* pNames = lcl_GetStyleNameMap( nType );
+ if (pNames)
+ {
+ do
+ {
+ if (pNames->aDispName == rDispName)
+ return pNames->aProgName;
+ else if (pNames->aProgName == rDispName)
+ bDisplayIsProgrammatic = TRUE; // display name matches any programmatic name
+ }
+ while( (++pNames)->aDispName.Len() );
+ }
+
+ if ( bDisplayIsProgrammatic || lcl_EndsWithUser( rDispName ) )
+ {
+ // add the (user) suffix if the display name matches any style's programmatic name
+ // or if it already contains the suffix
+
+ String aRet(rDispName);
+ aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SC_SUFFIX_USER ) );
+ return aRet;
+ }
+
+ return rDispName;
+}
+
+// static
+String ScStyleNameConversion::ProgrammaticToDisplayName( const String& rProgName, UINT16 nType )
+{
+ if ( lcl_EndsWithUser( rProgName ) )
+ {
+ // remove the (user) suffix, don't compare to map entries
+ return rProgName.Copy( 0, rProgName.Len() - SC_SUFFIX_USER_LEN );
+ }
+
+ const ScDisplayNameMap* pNames = lcl_GetStyleNameMap( nType );
+ if (pNames)
+ {
+ do
+ {
+ if (pNames->aProgName == rProgName)
+ return pNames->aDispName;
+ }
+ while( (++pNames)->aDispName.Len() );
+ }
+ return rProgName;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool lcl_AnyTabProtected( ScDocument& rDoc )
+{
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (rDoc.IsTabProtected(i))
+ return sal_True;
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+ScStyleFamiliesObj::ScStyleFamiliesObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScStyleFamiliesObj::~ScStyleFamiliesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScStyleFamiliesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XStyleFamilies
+
+ScStyleFamilyObj*ScStyleFamiliesObj::GetObjectByType_Impl(UINT16 nType) const
+{
+ if ( pDocShell )
+ {
+ if ( nType == SFX_STYLE_FAMILY_PARA )
+ return new ScStyleFamilyObj( pDocShell, SFX_STYLE_FAMILY_PARA );
+ else if ( nType == SFX_STYLE_FAMILY_PAGE )
+ return new ScStyleFamilyObj( pDocShell, SFX_STYLE_FAMILY_PAGE );
+ }
+ DBG_ERROR("getStyleFamilyByType: keine DocShell oder falscher Typ");
+ return NULL;
+}
+
+ScStyleFamilyObj* ScStyleFamiliesObj::GetObjectByIndex_Impl(UINT32 nIndex) const
+{
+ if ( nIndex < SC_STYLE_FAMILY_COUNT )
+ return GetObjectByType_Impl(aStyleFamilyTypes[nIndex]);
+
+ return NULL; // ungueltiger Index
+}
+
+ScStyleFamilyObj* ScStyleFamiliesObj::GetObjectByName_Impl(const rtl::OUString& aName) const
+{
+ if ( pDocShell )
+ {
+ String aNameStr( aName );
+ if ( aNameStr.EqualsAscii( SC_FAMILYNAME_CELL ) )
+ return new ScStyleFamilyObj( pDocShell, SFX_STYLE_FAMILY_PARA );
+ else if ( aNameStr.EqualsAscii( SC_FAMILYNAME_PAGE ) )
+ return new ScStyleFamilyObj( pDocShell, SFX_STYLE_FAMILY_PAGE );
+ }
+ // no assertion - called directly from getByName
+ return NULL;
+}
+
+// container::XIndexAccess
+
+sal_Int32 SAL_CALL ScStyleFamiliesObj::getCount() throw(uno::RuntimeException)
+{
+ return SC_STYLE_FAMILY_COUNT;
+}
+
+uno::Any SAL_CALL ScStyleFamiliesObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< container::XNameContainer > xFamily(GetObjectByIndex_Impl(nIndex));
+ if (xFamily.is())
+ return uno::makeAny(xFamily);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScStyleFamiliesObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::getCppuType((const uno::Reference< container::XNameContainer >*)0); // muss zu getByIndex passen
+}
+
+sal_Bool SAL_CALL ScStyleFamiliesObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// container::XNameAccess
+
+uno::Any SAL_CALL ScStyleFamiliesObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< container::XNameContainer > xFamily(GetObjectByName_Impl(aName));
+ if (xFamily.is())
+ return uno::makeAny(xFamily);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScStyleFamiliesObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence<rtl::OUString> aNames(SC_STYLE_FAMILY_COUNT);
+ rtl::OUString* pNames = aNames.getArray();
+ pNames[0] = rtl::OUString::createFromAscii( SC_FAMILYNAME_CELL );
+ pNames[1] = rtl::OUString::createFromAscii( SC_FAMILYNAME_PAGE );
+ return aNames;
+}
+
+sal_Bool SAL_CALL ScStyleFamiliesObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameStr( aName );
+ return ( aNameStr.EqualsAscii( SC_FAMILYNAME_CELL ) || aNameStr.EqualsAscii( SC_FAMILYNAME_PAGE ) );
+}
+
+// style::XStyleLoader
+
+void SAL_CALL ScStyleFamiliesObj::loadStylesFromURL( const rtl::OUString& aURL,
+ const uno::Sequence<beans::PropertyValue>& aOptions )
+ throw(io::IOException, uno::RuntimeException)
+{
+ //! use aOptions (like Writer)
+ //! set flag to disable filter option dialogs when importing
+
+ String aFilter; // empty - detect
+ String aFiltOpt;
+ ScDocumentLoader aLoader( aURL, aFilter, aFiltOpt );
+
+ ScDocShell* pSource = aLoader.GetDocShell();
+ if ( pSource && pDocShell )
+ {
+ // collect options
+
+ BOOL bLoadReplace = TRUE; // defaults
+ BOOL bLoadCellStyles = TRUE;
+ BOOL bLoadPageStyles = TRUE;
+
+ const beans::PropertyValue* pPropArray = aOptions.getConstArray();
+ long nPropCount = aOptions.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( SC_UNONAME_OVERWSTL ))
+ bLoadReplace = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_LOADCELL ))
+ bLoadCellStyles = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_LOADPAGE ))
+ bLoadPageStyles = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ }
+
+ pDocShell->LoadStylesArgs( *pSource, bLoadReplace, bLoadCellStyles, bLoadPageStyles );
+ pDocShell->SetDocumentModified(); // paint is inside LoadStyles
+ }
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScStyleFamiliesObj::getStyleLoaderOptions()
+ throw(uno::RuntimeException)
+{
+ // return defaults for options (?)
+
+ uno::Sequence<beans::PropertyValue> aSequence(3);
+ beans::PropertyValue* pArray = aSequence.getArray();
+
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_OVERWSTL );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[0].Value, TRUE );
+
+ pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_LOADCELL );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[1].Value, TRUE );
+
+ pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_LOADPAGE );
+ ScUnoHelpFunctions::SetBoolInAny( pArray[2].Value, TRUE );
+
+ return aSequence;
+}
+
+//------------------------------------------------------------------------
+
+ScStyleFamilyObj::ScStyleFamilyObj(ScDocShell* pDocSh, SfxStyleFamily eFam) :
+ pDocShell( pDocSh ),
+ eFamily( eFam )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScStyleFamilyObj::~ScStyleFamilyObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScStyleFamilyObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XStyleFamily
+
+ScStyleObj* ScStyleFamilyObj::GetObjectByIndex_Impl(UINT32 nIndex)
+{
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+
+ SfxStyleSheetIterator aIter( pStylePool, eFamily );
+ if ( nIndex < aIter.Count() )
+ {
+ SfxStyleSheetBase* pStyle = aIter[(USHORT)nIndex];
+ if ( pStyle )
+ {
+ return new ScStyleObj( pDocShell, eFamily, String (pStyle->GetName()) );
+ }
+ }
+ }
+ return NULL;
+}
+
+ScStyleObj* ScStyleFamilyObj::GetObjectByName_Impl(const rtl::OUString& aName)
+{
+ if ( pDocShell )
+ {
+ String aString(aName);
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ if ( pStylePool->Find( aString, eFamily ) )
+ return new ScStyleObj( pDocShell, eFamily, aString );
+ }
+ return NULL;
+}
+
+void SAL_CALL ScStyleFamilyObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::ElementExistException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ sal_Bool bDone = sal_False;
+ // Reflection muss nicht uno::XInterface sein, kann auch irgendein Interface sein...
+ uno::Reference< uno::XInterface > xInterface(aElement, uno::UNO_QUERY);
+ if ( xInterface.is() )
+ {
+ ScStyleObj* pStyleObj = ScStyleObj::getImplementation( xInterface );
+ if ( pStyleObj && pStyleObj->GetFamily() == eFamily &&
+ !pStyleObj->IsInserted() ) // noch nicht eingefuegt?
+ {
+ String aNameStr(ScStyleNameConversion::ProgrammaticToDisplayName( aName, sal::static_int_cast<UINT16>(eFamily) ));
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+
+ //! DocFunc-Funktion??
+ //! Undo ?????????????
+
+ if ( !pStylePool->Find( aNameStr, eFamily ) ) // noch nicht vorhanden
+ {
+ (void)pStylePool->Make( aNameStr, eFamily, SFXSTYLEBIT_USERDEF );
+
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && !pDoc->IsImportingXML() )
+ pDoc->GetPool()->CellStyleCreated( aNameStr );
+
+ pStyleObj->InitDoc( pDocShell, aNameStr ); // Objekt kann benutzt werden
+
+ pDocShell->SetDocumentModified(); // verwendet wird der neue Style noch nicht
+ bDone = sal_True;
+ }
+ else
+ throw container::ElementExistException();
+ }
+ }
+
+ if (!bDone)
+ {
+ // other errors are handled above
+ throw lang::IllegalArgumentException();
+ }
+}
+
+void SAL_CALL ScStyleFamilyObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ //! zusammenfassen?
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+void SAL_CALL ScStyleFamilyObj::removeByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ BOOL bFound = FALSE;
+ if ( pDocShell )
+ {
+ String aString(ScStyleNameConversion::ProgrammaticToDisplayName( aName, sal::static_int_cast<UINT16>(eFamily) ));
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+
+ //! DocFunc-Funktion??
+ //! Undo ?????????????
+
+ SfxStyleSheetBase* pStyle = pStylePool->Find( aString, eFamily );
+ if (pStyle)
+ {
+ bFound = TRUE;
+ if ( eFamily == SFX_STYLE_FAMILY_PARA )
+ {
+ // wie ScViewFunc::RemoveStyleSheetInUse
+ VirtualDevice aVDev;
+ Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = aLogic.X() / 1000.0;
+ double nPPTY = aLogic.Y() / 1000.0;
+ Fraction aZoom(1,1);
+ pDoc->StyleSheetChanged( pStyle, sal_False, &aVDev, nPPTX, nPPTY, aZoom, aZoom );
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ pDocShell->SetDocumentModified();
+
+ pStylePool->Remove( pStyle );
+
+ //! InvalidateAttribs(); // Bindings-Invalidate
+ }
+ else
+ {
+ if ( pDoc->RemovePageStyleInUse( aString ) )
+ pDocShell->PageStyleModified( ScGlobal::GetRscString(STR_STYLENAME_STANDARD), sal_True );
+
+ pStylePool->Remove( pStyle );
+
+ SfxBindings* pBindings = pDocShell->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_STYLE_FAMILY4 );
+ pDocShell->SetDocumentModified();
+ }
+ }
+ }
+
+ if (!bFound)
+ throw container::NoSuchElementException();
+}
+
+// container::XIndexAccess
+
+sal_Int32 SAL_CALL ScStyleFamilyObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+
+ SfxStyleSheetIterator aIter( pStylePool, eFamily );
+ return aIter.Count();
+ }
+ return 0;
+}
+
+uno::Any SAL_CALL ScStyleFamilyObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< style::XStyle > xObj(GetObjectByIndex_Impl(nIndex));
+ if (xObj.is())
+ return uno::makeAny(xObj);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScStyleFamilyObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ::getCppuType((const uno::Reference< style::XStyle >*)0); // muss zu getByIndex passen
+}
+
+sal_Bool SAL_CALL ScStyleFamilyObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// container::XNameAccess
+
+uno::Any SAL_CALL ScStyleFamilyObj::getByName( const rtl::OUString& aName )
+ throw(container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference< style::XStyle > xObj(
+ GetObjectByName_Impl( ScStyleNameConversion::ProgrammaticToDisplayName( aName, sal::static_int_cast<UINT16>(eFamily) ) ));
+ if (xObj.is())
+ return uno::makeAny(xObj);
+ else
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScStyleFamilyObj::getElementNames()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+
+ SfxStyleSheetIterator aIter( pStylePool, eFamily );
+ UINT16 nCount = aIter.Count();
+
+ String aName;
+ uno::Sequence<rtl::OUString> aSeq(nCount);
+ rtl::OUString* pAry = aSeq.getArray();
+ SfxStyleSheetBase* pStyle = aIter.First();
+ UINT16 nPos = 0;
+ while (pStyle)
+ {
+ DBG_ASSERT( nPos<nCount, "Anzahl durcheinandergekommen" );
+ if (nPos<nCount)
+ pAry[nPos++] = ScStyleNameConversion::DisplayToProgrammaticName(
+ pStyle->GetName(), sal::static_int_cast<UINT16>(eFamily) );
+ pStyle = aIter.Next();
+ }
+ return aSeq;
+ }
+ return uno::Sequence<rtl::OUString>();
+}
+
+sal_Bool SAL_CALL ScStyleFamilyObj::hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( pDocShell )
+ {
+ String aString(ScStyleNameConversion::ProgrammaticToDisplayName( aName, sal::static_int_cast<UINT16>(eFamily) ));
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ if ( pStylePool->Find( aString, eFamily ) )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+// XPropertySet
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL ScStyleFamilyObj::getPropertySetInfo( ) throw (uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+ return uno::Reference< beans::XPropertySetInfo >();
+}
+
+void SAL_CALL ScStyleFamilyObj::setPropertyValue( const ::rtl::OUString&, const uno::Any& ) throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+uno::Any SAL_CALL ScStyleFamilyObj::getPropertyValue( const ::rtl::OUString& sPropertyName ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aRet;
+
+ if ( sPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DisplayName") ) )
+ {
+ ScUnoGuard aGuard;
+ sal_uInt32 nResId = 0;
+ switch ( eFamily )
+ {
+ case SFX_STYLE_FAMILY_PARA:
+ nResId = STR_STYLE_FAMILY_CELL; break;
+ case SFX_STYLE_FAMILY_PAGE:
+ nResId = STR_STYLE_FAMILY_PAGE; break;
+ default:
+ OSL_ENSURE( 0, "ScStyleFamilyObj::getPropertyValue(): invalid family" );
+ }
+ if ( nResId > 0 )
+ {
+ ::rtl::OUString sDisplayName( ScGlobal::GetRscString( static_cast< USHORT >( nResId ) ) );
+ aRet = uno::makeAny( sDisplayName );
+ }
+ }
+ else
+ {
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("unknown property: ") ) + sPropertyName, static_cast<OWeakObject *>(this) );
+ }
+
+ return aRet;
+}
+
+void SAL_CALL ScStyleFamilyObj::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+void SAL_CALL ScStyleFamilyObj::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+void SAL_CALL ScStyleFamilyObj::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+void SAL_CALL ScStyleFamilyObj::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+//------------------------------------------------------------------------
+
+// Default-ctor wird fuer die Reflection gebraucht
+
+//UNUSED2008-05 ScStyleObj::ScStyleObj() :
+//UNUSED2008-05 aPropSet( lcl_GetCellStyleMap() ),
+//UNUSED2008-05 pDocShell( NULL ),
+//UNUSED2008-05 eFamily( SFX_STYLE_FAMILY_PARA )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScStyleObj::ScStyleObj(ScDocShell* pDocSh, SfxStyleFamily eFam, const String& rName) :
+ pPropSet( (eFam == SFX_STYLE_FAMILY_PARA) ? lcl_GetCellStyleSet() : lcl_GetPageStyleSet() ),
+ pDocShell( pDocSh ),
+ eFamily( eFam ),
+ aStyleName( rName )
+{
+ // pDocShell ist Null, wenn per ServiceProvider erzeugt
+
+ if (pDocShell)
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+void ScStyleObj::InitDoc( ScDocShell* pNewDocSh, const String& rNewName )
+{
+ if ( pNewDocSh && !pDocShell )
+ {
+ aStyleName = rNewName;
+ pDocShell = pNewDocSh;
+ pDocShell->GetDocument()->AddUnoObject(*this);
+ }
+}
+
+ScStyleObj::~ScStyleObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScStyleObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScStyleObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScStyleObj* ScStyleObj::getImplementation(
+ const uno::Reference<uno::XInterface> xObj )
+{
+ ScStyleObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScStyleObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+void ScStyleObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+SfxStyleSheetBase* ScStyleObj::GetStyle_Impl()
+{
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ return pStylePool->Find( aStyleName, eFamily );
+ }
+ return NULL;
+}
+
+// style::XStyle
+
+sal_Bool SAL_CALL ScStyleObj::isUserDefined() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ return pStyle->IsUserDefined();
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScStyleObj::isInUse() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ return pStyle->IsUsed();
+ return sal_False;
+}
+
+rtl::OUString SAL_CALL ScStyleObj::getParentStyle() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ return ScStyleNameConversion::DisplayToProgrammaticName( pStyle->GetParent(), sal::static_int_cast<UINT16>(eFamily) );
+ return rtl::OUString();
+}
+
+void SAL_CALL ScStyleObj::setParentStyle( const rtl::OUString& rParentStyle )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ {
+ // #70909# cell styles cannot be modified if any sheet is protected
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && lcl_AnyTabProtected( *pDocShell->GetDocument() ) )
+ return; //! exception?
+
+ //! DocFunc-Funktion??
+ //! Undo ?????????????
+
+ String aString(ScStyleNameConversion::ProgrammaticToDisplayName( rParentStyle, sal::static_int_cast<UINT16>(eFamily) ));
+ sal_Bool bOk = pStyle->SetParent( aString );
+ if (bOk)
+ {
+ // wie bei setPropertyValue
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( eFamily == SFX_STYLE_FAMILY_PARA )
+ {
+ // Zeilenhoehen anpassen...
+
+ VirtualDevice aVDev;
+ Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = aLogic.X() / 1000.0;
+ double nPPTY = aLogic.Y() / 1000.0;
+ Fraction aZoom(1,1);
+ pDoc->StyleSheetChanged( pStyle, sal_False, &aVDev, nPPTX, nPPTY, aZoom, aZoom );
+
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ pDocShell->SetDocumentModified();
+ }
+ else
+ {
+ //! ModifyStyleSheet am Dokument (alte Werte merken)
+
+ pDocShell->PageStyleModified( aStyleName, sal_True );
+ }
+ }
+ }
+}
+
+// container::XNamed
+
+rtl::OUString SAL_CALL ScStyleObj::getName() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ return ScStyleNameConversion::DisplayToProgrammaticName( pStyle->GetName(), sal::static_int_cast<UINT16>(eFamily) );
+ return rtl::OUString();
+}
+
+void SAL_CALL ScStyleObj::setName( const rtl::OUString& aNewName )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ {
+ // #71225# cell styles cannot be renamed if any sheet is protected
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && lcl_AnyTabProtected( *pDocShell->GetDocument() ) )
+ return; //! exception?
+
+ //! DocFunc-Funktion??
+ //! Undo ?????????????
+
+ String aString(aNewName);
+ sal_Bool bOk = pStyle->SetName( aString );
+ if (bOk)
+ {
+ aStyleName = aString; //! notify other objects for this style?
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && !pDoc->IsImportingXML() )
+ pDoc->GetPool()->CellStyleCreated( aString );
+
+ // Zellvorlagen = 2, Seitenvorlagen = 4
+ UINT16 nId = ( eFamily == SFX_STYLE_FAMILY_PARA ) ?
+ SID_STYLE_FAMILY2 : SID_STYLE_FAMILY4;
+ SfxBindings* pBindings = pDocShell->GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( nId );
+ pBindings->Invalidate( SID_STYLE_APPLY );
+ }
+ }
+ }
+}
+
+// static
+uno::Reference<container::XIndexReplace> ScStyleObj::CreateEmptyNumberingRules()
+{
+ SvxNumRule aRule( 0, 0, TRUE ); // nothing supported
+ return SvxCreateNumRule( &aRule );
+}
+
+// beans::XPropertyState
+
+const SfxItemSet* ScStyleObj::GetStyleItemSet_Impl( const ::rtl::OUString& rPropName,
+ const SfxItemPropertySimpleEntry*& rpResultEntry )
+{
+ //! OUString as argument?
+
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = NULL;
+ if ( eFamily == SFX_STYLE_FAMILY_PAGE )
+ {
+ pEntry = lcl_GetHeaderStyleMap()->getByName( rPropName );
+ if ( pEntry ) // only item-wids in header/footer map
+ {
+ rpResultEntry = pEntry;
+ return &((const SvxSetItem&)pStyle->GetItemSet().Get(ATTR_PAGE_HEADERSET)).GetItemSet();
+ }
+ pEntry = lcl_GetFooterStyleMap()->getByName( rPropName );
+ if ( pEntry ) // only item-wids in header/footer map
+ {
+ rpResultEntry = pEntry;
+ return &((const SvxSetItem&)pStyle->GetItemSet().Get(ATTR_PAGE_FOOTERSET)).GetItemSet();
+ }
+ }
+ pEntry = pPropSet->getPropertyMap()->getByName( rPropName );
+ if ( pEntry )
+ {
+ rpResultEntry = pEntry;
+ return &pStyle->GetItemSet();
+ }
+ }
+
+ rpResultEntry = NULL;
+ return NULL;
+}
+
+beans::PropertyState SAL_CALL ScStyleObj::getPropertyState( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
+
+ const SfxItemPropertySimpleEntry* pResultEntry = NULL;
+ const SfxItemSet* pItemSet = GetStyleItemSet_Impl( aPropertyName, pResultEntry );
+
+ if ( pItemSet && pResultEntry )
+ {
+ USHORT nWhich = pResultEntry->nWID;
+ if ( nWhich == SC_WID_UNO_TBLBORD )
+ {
+ nWhich = ATTR_BORDER;
+ }
+ if ( IsScItemWid( nWhich ) )
+ {
+ SfxItemState eState = pItemSet->GetItemState( nWhich, sal_False );
+
+// // if no rotate value is set, look at orientation
+// //! also for a fixed value of 0 (in case orientation is ambiguous)?
+// if ( nWhich == ATTR_ROTATE_VALUE && eState == SFX_ITEM_DEFAULT )
+// eState = pItemSet->GetItemState( ATTR_ORIENTATION, sal_False );
+
+ if ( eState == SFX_ITEM_SET )
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ else if ( eState == SFX_ITEM_DEFAULT )
+ eRet = beans::PropertyState_DEFAULT_VALUE;
+ else if ( eState == SFX_ITEM_DONTCARE )
+ eRet = beans::PropertyState_AMBIGUOUS_VALUE; // kann eigentlich nicht sein...
+ else
+ {
+ DBG_ERROR("unbekannter ItemState");
+ }
+ }
+ }
+ return eRet;
+}
+
+uno::Sequence<beans::PropertyState> SAL_CALL ScStyleObj::getPropertyStates(
+ const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ // duemmliche Default-Implementierung: alles einzeln per getPropertyState holen
+ //! sollte optimiert werden!
+
+ ScUnoGuard aGuard;
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
+ pStates[i] = getPropertyState(pNames[i]);
+ return aRet;
+}
+
+void SAL_CALL ScStyleObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ const SfxItemPropertyMap* pMap = pPropSet->getPropertyMap();
+ const SfxItemPropertySimpleEntry* pEntry = pMap->getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ SetOnePropertyValue( aPropertyName, pEntry, NULL );
+}
+
+uno::Any SAL_CALL ScStyleObj::getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aAny;
+
+ const SfxItemPropertySimpleEntry* pResultEntry = NULL;
+ const SfxItemSet* pStyleSet = GetStyleItemSet_Impl( aPropertyName, pResultEntry );
+
+ if ( pStyleSet && pResultEntry )
+ {
+ USHORT nWhich = pResultEntry->nWID;
+
+ if ( IsScItemWid( nWhich ) )
+ {
+ // Default ist Default vom ItemPool, nicht vom Standard-Style,
+ // damit es zu setPropertyToDefault passt
+ SfxItemSet aEmptySet( *pStyleSet->GetPool(), pStyleSet->GetRanges() );
+ // #65253# Default-Items mit falscher Slot-ID funktionieren im SfxItemPropertySet3 nicht
+ //! Slot-IDs aendern...
+ if ( aEmptySet.GetPool()->GetSlotId(nWhich) == nWhich &&
+ aEmptySet.GetItemState(nWhich, sal_False) == SFX_ITEM_DEFAULT )
+ {
+ aEmptySet.Put( aEmptySet.Get( nWhich ) );
+ }
+ const SfxItemSet* pItemSet = &aEmptySet;
+
+ switch ( nWhich ) // fuer Item-Spezial-Behandlungen
+ {
+ case ATTR_VALUE_FORMAT:
+ // default has no language set
+ aAny <<= sal_Int32( ((const SfxUInt32Item&)pItemSet->Get(nWhich)).GetValue() );
+ break;
+ case ATTR_INDENT:
+ aAny <<= sal_Int16( TwipsToHMM(((const SfxUInt16Item&)
+ pItemSet->Get(nWhich)).GetValue()) );
+ break;
+ case ATTR_PAGE_SCALE:
+ case ATTR_PAGE_SCALETOPAGES:
+ case ATTR_PAGE_FIRSTPAGENO:
+ aAny <<= sal_Int16( ((const SfxUInt16Item&)pItemSet->Get(nWhich)).GetValue() );
+ break;
+ case ATTR_PAGE_CHARTS:
+ case ATTR_PAGE_OBJECTS:
+ case ATTR_PAGE_DRAWINGS:
+ //! sal_Bool-MID fuer ScViewObjectModeItem definieren?
+ aAny <<= sal_Bool( ((const ScViewObjectModeItem&)pItemSet->Get(nWhich)).
+ GetValue() == VOBJ_MODE_SHOW );
+ break;
+ case ATTR_PAGE_SCALETO:
+ {
+ const ScPageScaleToItem aItem((const ScPageScaleToItem&)pItemSet->Get(nWhich));
+ if (aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SC_UNO_PAGE_SCALETOX )))
+ aAny = uno::makeAny(static_cast<sal_Int16>(aItem.GetWidth()));
+ else
+ aAny = uno::makeAny(static_cast<sal_Int16>(aItem.GetHeight()));
+ }
+ break;
+ default:
+ pPropSet->getPropertyValue( *pResultEntry, *pItemSet, aAny );
+ }
+ }
+ else if ( IsScUnoWid( nWhich ) )
+ {
+ SfxItemSet aEmptySet( *pStyleSet->GetPool(), pStyleSet->GetRanges() );
+ const SfxItemSet* pItemSet = &aEmptySet;
+ switch ( nWhich )
+ {
+ case SC_WID_UNO_TBLBORD:
+ {
+ const SfxPoolItem* pItem = &pItemSet->Get( ATTR_BORDER );
+ if ( pItem )
+ {
+ SvxBoxItem aOuter( *( static_cast<const SvxBoxItem*>( pItem ) ) );
+ SvxBoxInfoItem aInner( ATTR_BORDER_INNER );
+ table::TableBorder aBorder;
+ ScHelperFunctions::FillTableBorder( aBorder, aOuter, aInner );
+ aBorder.IsHorizontalLineValid = sal_False;
+ aBorder.IsVerticalLineValid = sal_False;
+ aBorder.IsDistanceValid = sal_False;
+ aAny <<= aBorder;
+ }
+ }
+ break;
+ }
+ }
+ }
+ return aAny;
+}
+
+// XMultiPropertySet
+
+void SAL_CALL ScStyleObj::setPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames,
+ const uno::Sequence< uno::Any >& aValues )
+ throw (beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Int32 nCount = aPropertyNames.getLength();
+ if ( aValues.getLength() != nCount )
+ throw lang::IllegalArgumentException();
+
+ if ( nCount )
+ {
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ const uno::Any* pValues = aValues.getConstArray();
+
+ const SfxItemPropertyMap* pPropertyMap = pPropSet->getPropertyMap();
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( pNames[i] );
+ SetOnePropertyValue( pNames[i], pEntry, &pValues[i] );
+ }
+ }
+}
+
+uno::Sequence<uno::Any> SAL_CALL ScStyleObj::getPropertyValues(
+ const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! optimize
+
+ sal_Int32 nCount = aPropertyNames.getLength();
+ uno::Sequence<uno::Any> aSequence( nCount );
+ if ( nCount )
+ {
+ uno::Any* pValues = aSequence.getArray();
+ for (sal_Int32 i=0; i<nCount; i++)
+ pValues[i] = getPropertyValue( aPropertyNames[i] );
+ }
+ return aSequence;
+}
+
+void SAL_CALL ScStyleObj::addPropertiesChangeListener( const uno::Sequence<rtl::OUString>& /* aPropertyNames */,
+ const uno::Reference<beans::XPropertiesChangeListener>& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ // no bound properties
+}
+
+void SAL_CALL ScStyleObj::removePropertiesChangeListener(
+ const uno::Reference<beans::XPropertiesChangeListener>& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ // no bound properties
+}
+
+void SAL_CALL ScStyleObj::firePropertiesChangeEvent( const uno::Sequence<rtl::OUString>& /* aPropertyNames */,
+ const uno::Reference<beans::XPropertiesChangeListener>& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ // no bound properties
+}
+
+// XMultiPropertyStates
+// getPropertyStates already defined for XPropertyState
+
+void SAL_CALL ScStyleObj::setAllPropertiesToDefault() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if ( pStyle )
+ {
+ // #70909# cell styles cannot be modified if any sheet is protected
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && lcl_AnyTabProtected( *pDocShell->GetDocument() ) )
+ throw uno::RuntimeException();
+
+ SfxItemSet& rSet = pStyle->GetItemSet();
+ rSet.ClearItem(); // set all items to default
+
+ //! merge with SetOneProperty
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( eFamily == SFX_STYLE_FAMILY_PARA )
+ {
+ // row heights
+
+ VirtualDevice aVDev;
+ Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = aLogic.X() / 1000.0;
+ double nPPTY = aLogic.Y() / 1000.0;
+ Fraction aZoom(1,1);
+ pDoc->StyleSheetChanged( pStyle, sal_False, &aVDev, nPPTX, nPPTY, aZoom, aZoom );
+
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ pDocShell->SetDocumentModified();
+ }
+ else
+ {
+ // #i22448# apply the default BoxInfoItem for page styles again
+ // (same content as in ScStyleSheet::GetItemSet, to control the dialog)
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+ aBoxInfoItem.SetTable( FALSE );
+ aBoxInfoItem.SetDist( TRUE );
+ aBoxInfoItem.SetValid( VALID_DISTANCE, TRUE );
+ rSet.Put( aBoxInfoItem );
+
+ pDocShell->PageStyleModified( aStyleName, sal_True );
+ }
+ }
+}
+
+void SAL_CALL ScStyleObj::setPropertiesToDefault( const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Int32 nCount = aPropertyNames.getLength();
+ if ( nCount )
+ {
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+
+ const SfxItemPropertyMap* pPropertyMap = pPropSet->getPropertyMap();
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( pNames[i] );
+ SetOnePropertyValue( pNames[i], pEntry, NULL );
+ }
+ }
+}
+
+uno::Sequence<uno::Any> SAL_CALL ScStyleObj::getPropertyDefaults(
+ const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! optimize
+
+ sal_Int32 nCount = aPropertyNames.getLength();
+ uno::Sequence<uno::Any> aSequence( nCount );
+ if ( nCount )
+ {
+ uno::Any* pValues = aSequence.getArray();
+ for (sal_Int32 i=0; i<nCount; i++)
+ pValues[i] = getPropertyDefault( aPropertyNames[i] );
+ }
+ return aSequence;
+}
+
+// beans::XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScStyleObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return pPropSet->getPropertySetInfo();
+}
+
+void SAL_CALL ScStyleObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ const SfxItemPropertySimpleEntry* pEntry = pPropSet->getPropertyMap()->getByName( aPropertyName );
+ if ( !pEntry )
+ throw beans::UnknownPropertyException();
+
+ SetOnePropertyValue( aPropertyName, pEntry, &aValue );
+}
+
+void ScStyleObj::SetOnePropertyValue( const ::rtl::OUString& rPropertyName, const SfxItemPropertySimpleEntry* pEntry, const uno::Any* pValue )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if ( pStyle && pEntry )
+ {
+ // #70909# cell styles cannot be modified if any sheet is protected
+ if ( eFamily == SFX_STYLE_FAMILY_PARA && lcl_AnyTabProtected( *pDocShell->GetDocument() ) )
+ throw uno::RuntimeException();
+
+ SfxItemSet& rSet = pStyle->GetItemSet(); // direkt im lebenden Style aendern...
+ sal_Bool bDone = sal_False;
+ if ( eFamily == SFX_STYLE_FAMILY_PAGE )
+ {
+ if(pEntry->nWID == SC_WID_UNO_HEADERSET)
+ {
+ const SfxItemPropertySimpleEntry* pHeaderEntry = lcl_GetHeaderStyleMap()->getByName( rPropertyName );
+ if ( pHeaderEntry ) // only item-wids in header/footer map
+ {
+ SvxSetItem aNewHeader( (const SvxSetItem&)rSet.Get(ATTR_PAGE_HEADERSET) );
+ if (pValue)
+ pPropSet->setPropertyValue( *pHeaderEntry, *pValue, aNewHeader.GetItemSet() );
+ else
+ aNewHeader.GetItemSet().ClearItem( pHeaderEntry->nWID );
+ rSet.Put( aNewHeader );
+ bDone = sal_True;
+ }
+ }
+ else if(pEntry->nWID == SC_WID_UNO_FOOTERSET)
+ {
+ const SfxItemPropertySimpleEntry* pFooterEntry = lcl_GetFooterStyleMap()->getByName( rPropertyName );
+ if ( pFooterEntry ) // only item-wids in header/footer map
+ {
+ SvxSetItem aNewFooter( (const SvxSetItem&)rSet.Get(ATTR_PAGE_FOOTERSET) );
+ if (pValue)
+ pPropSet->setPropertyValue( *pFooterEntry, *pValue, aNewFooter.GetItemSet() );
+ else
+ aNewFooter.GetItemSet().ClearItem( pFooterEntry->nWID );
+ rSet.Put( aNewFooter );
+ bDone = sal_True;
+ }
+ }
+ }
+ if (!bDone)
+ {
+ if ( pEntry )
+ {
+ if ( IsScItemWid( pEntry->nWID ) )
+ {
+ if (pValue)
+ {
+ switch ( pEntry->nWID ) // fuer Item-Spezial-Behandlungen
+ {
+ case ATTR_VALUE_FORMAT:
+ {
+ // #67847# language for number formats
+ SvNumberFormatter* pFormatter =
+ pDocShell->GetDocument()->GetFormatTable();
+ UINT32 nOldFormat = ((const SfxUInt32Item&)
+ rSet.Get( ATTR_VALUE_FORMAT )).GetValue();
+ LanguageType eOldLang = ((const SvxLanguageItem&)
+ rSet.Get( ATTR_LANGUAGE_FORMAT )).GetLanguage();
+ nOldFormat = pFormatter->
+ GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
+
+ UINT32 nNewFormat = 0;
+ *pValue >>= nNewFormat;
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
+
+ const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
+ LanguageType eNewLang =
+ pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+ if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW )
+ rSet.Put( SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
+
+ //! keep default state of number format if only language changed?
+ }
+ break;
+ case ATTR_INDENT:
+ {
+ sal_Int16 nVal = 0;
+ *pValue >>= nVal;
+ rSet.Put( SfxUInt16Item( pEntry->nWID, (USHORT)HMMToTwips(nVal) ) );
+ }
+ break;
+ case ATTR_ROTATE_VALUE:
+ {
+ sal_Int32 nRotVal = 0;
+ if ( *pValue >>= nRotVal )
+ {
+ // stored value is always between 0 and 360 deg.
+ nRotVal %= 36000;
+ if ( nRotVal < 0 )
+ nRotVal += 36000;
+ rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, nRotVal ) );
+ }
+ }
+ break;
+ case ATTR_STACKED:
+ {
+ table::CellOrientation eOrient;
+ if( *pValue >>= eOrient )
+ {
+ switch( eOrient )
+ {
+ case table::CellOrientation_STANDARD:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, FALSE ) );
+ break;
+ case table::CellOrientation_TOPBOTTOM:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, FALSE ) );
+ rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
+ break;
+ case table::CellOrientation_BOTTOMTOP:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, FALSE ) );
+ rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
+ break;
+ case table::CellOrientation_STACKED:
+ rSet.Put( SfxBoolItem( ATTR_STACKED, TRUE ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ }
+ break;
+ case ATTR_PAGE_SCALE:
+ case ATTR_PAGE_SCALETOPAGES:
+ {
+ rSet.ClearItem(ATTR_PAGE_SCALETOPAGES);
+ rSet.ClearItem(ATTR_PAGE_SCALE);
+ rSet.ClearItem(ATTR_PAGE_SCALETO);
+ sal_Int16 nVal = 0;
+ *pValue >>= nVal;
+ rSet.Put( SfxUInt16Item( pEntry->nWID, nVal ) );
+ }
+ break;
+ case ATTR_PAGE_FIRSTPAGENO:
+ {
+ sal_Int16 nVal = 0;
+ *pValue >>= nVal;
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, nVal ) );
+ }
+ break;
+ case ATTR_PAGE_CHARTS:
+ case ATTR_PAGE_OBJECTS:
+ case ATTR_PAGE_DRAWINGS:
+ {
+ sal_Bool bBool = sal_False;
+ *pValue >>= bBool;
+ //! sal_Bool-MID fuer ScViewObjectModeItem definieren?
+ rSet.Put( ScViewObjectModeItem( pEntry->nWID,
+ bBool ? VOBJ_MODE_SHOW : VOBJ_MODE_HIDE ) );
+ }
+ break;
+ case ATTR_PAGE_PAPERBIN:
+ {
+ BYTE nTray = PAPERBIN_PRINTER_SETTINGS;
+ BOOL bFound = FALSE;
+
+ rtl::OUString aName;
+ if ( *pValue >>= aName )
+ {
+ if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_PAPERBIN_DEFAULTNAME ) ) )
+ bFound = TRUE;
+ else
+ {
+ Printer* pPrinter = pDocShell->GetPrinter();
+ if (pPrinter)
+ {
+ String aNameStr = aName;
+ USHORT nCount = pPrinter->GetPaperBinCount();
+ for (USHORT i=0; i<nCount; i++)
+ if ( aNameStr == pPrinter->GetPaperBinName(i) )
+ {
+ nTray = (BYTE) i;
+ bFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if ( bFound )
+ rSet.Put( SvxPaperBinItem( ATTR_PAGE_PAPERBIN, nTray ) );
+ else
+ throw lang::IllegalArgumentException();
+ }
+ break;
+ case ATTR_PAGE_SCALETO:
+ {
+ sal_Int16 nPages = 0;
+ if (*pValue >>= nPages)
+ {
+ ScPageScaleToItem aItem = ((const ScPageScaleToItem&)rSet.Get(ATTR_PAGE_SCALETO));
+ if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SC_UNO_PAGE_SCALETOX)))
+ aItem.SetWidth(static_cast<sal_uInt16>(nPages));
+ else
+ aItem.SetHeight(static_cast<sal_uInt16>(nPages));
+ rSet.Put( aItem );
+ rSet.ClearItem(ATTR_PAGE_SCALETOPAGES);
+ rSet.ClearItem(ATTR_PAGE_SCALE);
+ }
+ }
+ break;
+ default:
+ // #65253# Default-Items mit falscher Slot-ID
+ // funktionieren im SfxItemPropertySet3 nicht
+ //! Slot-IDs aendern...
+ if ( rSet.GetPool()->GetSlotId(pEntry->nWID) == pEntry->nWID &&
+ rSet.GetItemState(pEntry->nWID, sal_False) == SFX_ITEM_DEFAULT )
+ {
+ rSet.Put( rSet.Get(pEntry->nWID) );
+ }
+ pPropSet->setPropertyValue( *pEntry, *pValue, rSet );
+ }
+ }
+ else
+ {
+ rSet.ClearItem( pEntry->nWID );
+ // #67847# language for number formats
+ if ( pEntry->nWID == ATTR_VALUE_FORMAT )
+ rSet.ClearItem( ATTR_LANGUAGE_FORMAT );
+
+ //! for ATTR_ROTATE_VALUE, also reset ATTR_ORIENTATION?
+ }
+ }
+ else if ( IsScUnoWid( pEntry->nWID ) )
+ {
+ switch ( pEntry->nWID )
+ {
+ case SC_WID_UNO_TBLBORD:
+ {
+ if (pValue)
+ {
+ table::TableBorder aBorder;
+ if ( *pValue >>= aBorder )
+ {
+ SvxBoxItem aOuter( ATTR_BORDER );
+ SvxBoxInfoItem aInner( ATTR_BORDER_INNER );
+ ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder );
+ rSet.Put( aOuter );
+ }
+ }
+ else
+ {
+ rSet.ClearItem( ATTR_BORDER );
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ //! DocFunc-Funktion??
+ //! Undo ?????????????
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( eFamily == SFX_STYLE_FAMILY_PARA )
+ {
+ // Zeilenhoehen anpassen...
+
+ VirtualDevice aVDev;
+ Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = aLogic.X() / 1000.0;
+ double nPPTY = aLogic.Y() / 1000.0;
+ Fraction aZoom(1,1);
+ pDoc->StyleSheetChanged( pStyle, sal_False, &aVDev, nPPTX, nPPTY, aZoom, aZoom );
+
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ pDocShell->SetDocumentModified();
+ }
+ else
+ {
+ //! ModifyStyleSheet am Dokument (alte Werte merken)
+
+ pDocShell->PageStyleModified( aStyleName, sal_True );
+ }
+ }
+}
+
+uno::Any SAL_CALL ScStyleObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aAny;
+
+ if ( aPropertyName.equalsAscii( SC_UNONAME_DISPNAME ) ) // read-only
+ {
+ // core always has the display name
+ SfxStyleSheetBase* pStyle = GetStyle_Impl();
+ if (pStyle)
+ aAny <<= rtl::OUString( pStyle->GetName() );
+ }
+ else
+ {
+ const SfxItemPropertySimpleEntry* pResultEntry = NULL;
+ const SfxItemSet* pItemSet = GetStyleItemSet_Impl( aPropertyName, pResultEntry );
+
+ if ( pItemSet && pResultEntry )
+ {
+ USHORT nWhich = pResultEntry->nWID;
+
+ if ( IsScItemWid( nWhich ) )
+ {
+ switch ( nWhich ) // fuer Item-Spezial-Behandlungen
+ {
+ case ATTR_VALUE_FORMAT:
+ if ( pDocShell )
+ {
+ UINT32 nOldFormat = ((const SfxUInt32Item&)
+ pItemSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ LanguageType eOldLang = ((const SvxLanguageItem&)
+ pItemSet->Get( ATTR_LANGUAGE_FORMAT )).GetLanguage();
+ nOldFormat = pDocShell->GetDocument()->GetFormatTable()->
+ GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
+ aAny <<= nOldFormat;
+ }
+ break;
+ case ATTR_INDENT:
+ aAny <<= sal_Int16( TwipsToHMM(((const SfxUInt16Item&)
+ pItemSet->Get(nWhich)).GetValue()) );
+ break;
+ case ATTR_STACKED:
+ {
+ sal_Int32 nRot = ((const SfxInt32Item&)pItemSet->Get(ATTR_ROTATE_VALUE)).GetValue();
+ BOOL bStacked = ((const SfxBoolItem&)pItemSet->Get(nWhich)).GetValue();
+ SvxOrientationItem( nRot, bStacked, 0 ).QueryValue( aAny );
+ }
+ break;
+ case ATTR_PAGE_SCALE:
+ case ATTR_PAGE_SCALETOPAGES:
+ case ATTR_PAGE_FIRSTPAGENO:
+ aAny <<= sal_Int16( ((const SfxUInt16Item&)pItemSet->Get(nWhich)).GetValue() );
+ break;
+ case ATTR_PAGE_CHARTS:
+ case ATTR_PAGE_OBJECTS:
+ case ATTR_PAGE_DRAWINGS:
+ //! sal_Bool-MID fuer ScViewObjectModeItem definieren?
+ aAny <<= sal_Bool( ((const ScViewObjectModeItem&)pItemSet->
+ Get(nWhich)).GetValue() == VOBJ_MODE_SHOW );
+ break;
+ case ATTR_PAGE_PAPERBIN:
+ {
+ // property PrinterPaperTray is the name of the tray
+
+ BYTE nValue = ((const SvxPaperBinItem&)pItemSet->Get(nWhich)).GetValue();
+ rtl::OUString aName;
+ if ( nValue == PAPERBIN_PRINTER_SETTINGS )
+ aName = rtl::OUString::createFromAscii( SC_PAPERBIN_DEFAULTNAME );
+ else
+ {
+ Printer* pPrinter = pDocShell->GetPrinter();
+ if (pPrinter)
+ aName = pPrinter->GetPaperBinName( nValue );
+ }
+ aAny <<= aName;
+ }
+ break;
+ case ATTR_PAGE_SCALETO:
+ {
+ ScPageScaleToItem aItem((const ScPageScaleToItem&)pItemSet->Get(ATTR_PAGE_SCALETO));
+ if (aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SC_UNO_PAGE_SCALETOX)))
+ aAny = uno::makeAny(static_cast<sal_Int16>(aItem.GetWidth()));
+ else
+ aAny = uno::makeAny(static_cast<sal_Int16>(aItem.GetHeight()));
+ }
+ break;
+ default:
+ // #65253# Default-Items mit falscher Slot-ID
+ // funktionieren im SfxItemPropertySet3 nicht
+ //! Slot-IDs aendern...
+ if ( pItemSet->GetPool()->GetSlotId(nWhich) == nWhich &&
+ pItemSet->GetItemState(nWhich, sal_False) == SFX_ITEM_DEFAULT )
+ {
+ SfxItemSet aNoEmptySet( *pItemSet );
+ aNoEmptySet.Put( aNoEmptySet.Get( nWhich ) );
+ pPropSet->getPropertyValue( *pResultEntry, aNoEmptySet, aAny );
+ }
+ else
+ pPropSet->getPropertyValue( *pResultEntry, *pItemSet, aAny );
+ }
+ }
+ else if ( IsScUnoWid( nWhich ) )
+ {
+ switch ( nWhich )
+ {
+ case SC_WID_UNO_TBLBORD:
+ {
+ const SfxPoolItem* pItem = &pItemSet->Get( ATTR_BORDER );
+ if ( pItem )
+ {
+ SvxBoxItem aOuter( *( static_cast<const SvxBoxItem*>( pItem ) ) );
+ SvxBoxInfoItem aInner( ATTR_BORDER_INNER );
+ table::TableBorder aBorder;
+ ScHelperFunctions::FillTableBorder( aBorder, aOuter, aInner );
+ aBorder.IsHorizontalLineValid = sal_False;
+ aBorder.IsVerticalLineValid = sal_False;
+ aBorder.IsDistanceValid = sal_False;
+ aAny <<= aBorder;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return aAny;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScStyleObj )
+
+// lang::XServiceInfo
+
+rtl::OUString SAL_CALL ScStyleObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScStyleObj" );
+}
+
+sal_Bool SAL_CALL ScStyleObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ BOOL bPage = ( eFamily == SFX_STYLE_FAMILY_PAGE );
+ return rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SCSTYLE_SERVICE ) )||
+ rServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM ( bPage ? SCPAGESTYLE_SERVICE : SCCELLSTYLE_SERVICE ));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScStyleObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ BOOL bPage = ( eFamily == SFX_STYLE_FAMILY_PAGE );
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCSTYLE_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( bPage ? SCPAGESTYLE_SERVICE
+ : SCCELLSTYLE_SERVICE );
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+
+
diff --git a/sc/source/ui/unoobj/targuno.cxx b/sc/source/ui/unoobj/targuno.cxx
new file mode 100644
index 000000000000..aa4cdf58882d
--- /dev/null
+++ b/sc/source/ui/unoobj/targuno.cxx
@@ -0,0 +1,318 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/image.hxx>
+#include <vcl/virdev.hxx>
+//#include <toolkit/unoiface.hxx>
+#include <toolkit/unohlp.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/smplhint.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <com/sun/star/awt/XBitmap.hpp>
+
+#include "targuno.hxx"
+#include "miscuno.hxx"
+#include "docuno.hxx"
+#include "datauno.hxx"
+#include "nameuno.hxx"
+#include "docsh.hxx"
+#include "content.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "unonames.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+sal_uInt16 nTypeResIds[SC_LINKTARGETTYPE_COUNT] =
+{
+ SCSTR_CONTENT_TABLE, // SC_LINKTARGETTYPE_SHEET
+ SCSTR_CONTENT_RANGENAME, // SC_LINKTARGETTYPE_RANGENAME
+ SCSTR_CONTENT_DBAREA // SC_LINKTARGETTYPE_DBAREA
+};
+
+const SfxItemPropertyMapEntry* lcl_GetLinkTargetMap()
+{
+ static SfxItemPropertyMapEntry aLinkTargetMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT), 0, &getCppuType((const uno::Reference<awt::XBitmap>*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), 0, &getCppuType((const ::rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aLinkTargetMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+// service for ScLinkTargetTypeObj is not defined
+// must not support document::LinkTarget because the target type cannot be used as a target
+
+SC_SIMPLE_SERVICE_INFO( ScLinkTargetTypesObj, "ScLinkTargetTypesObj", "com.sun.star.document.LinkTargets" )
+SC_SIMPLE_SERVICE_INFO( ScLinkTargetTypeObj, "ScLinkTargetTypeObj", "com.sun.star.document.LinkTargetSupplier" )
+SC_SIMPLE_SERVICE_INFO( ScLinkTargetsObj, "ScLinkTargetsObj", "com.sun.star.document.LinkTargets" )
+
+//------------------------------------------------------------------------
+
+ScLinkTargetTypesObj::ScLinkTargetTypesObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+
+ for (sal_uInt16 i=0; i<SC_LINKTARGETTYPE_COUNT; i++)
+ aNames[i] = String( ScResId( nTypeResIds[i] ) );
+}
+
+ScLinkTargetTypesObj::~ScLinkTargetTypesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScLinkTargetTypesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // document gone
+}
+
+// container::XNameAccess
+
+uno::Any SAL_CALL ScLinkTargetTypesObj::getByName(const rtl::OUString& aName)
+ throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ if (pDocShell)
+ {
+ String aNameStr(aName);
+ for (sal_uInt16 i=0; i<SC_LINKTARGETTYPE_COUNT; i++)
+ if ( aNames[i] == aNameStr )
+ return uno::makeAny(uno::Reference< beans::XPropertySet >(new ScLinkTargetTypeObj( pDocShell, i )));
+ }
+
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScLinkTargetTypesObj::getElementNames(void) throw( uno::RuntimeException )
+{
+ uno::Sequence<rtl::OUString> aRet(SC_LINKTARGETTYPE_COUNT);
+ rtl::OUString* pArray = aRet.getArray();
+ for (sal_uInt16 i=0; i<SC_LINKTARGETTYPE_COUNT; i++)
+ pArray[i] = aNames[i];
+ return aRet;
+}
+
+sal_Bool SAL_CALL ScLinkTargetTypesObj::hasByName(const rtl::OUString& aName) throw( uno::RuntimeException )
+{
+ String aNameStr = aName;
+ for (sal_uInt16 i=0; i<SC_LINKTARGETTYPE_COUNT; i++)
+ if ( aNames[i] == aNameStr )
+ return sal_True;
+ return sal_False;
+}
+
+// container::XElementAccess
+
+uno::Type SAL_CALL ScLinkTargetTypesObj::getElementType(void) throw( uno::RuntimeException )
+{
+ return ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);
+}
+
+sal_Bool SAL_CALL ScLinkTargetTypesObj::hasElements(void) throw( uno::RuntimeException )
+{
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+ScLinkTargetTypeObj::ScLinkTargetTypeObj(ScDocShell* pDocSh, sal_uInt16 nT) :
+ pDocShell( pDocSh ),
+ nType( nT )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+ aName = String( ScResId( nTypeResIds[nType] ) ); //! on demand?
+}
+
+ScLinkTargetTypeObj::~ScLinkTargetTypeObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScLinkTargetTypeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pDocShell = NULL; // document gone
+}
+
+// document::XLinkTargetSupplier
+
+uno::Reference< container::XNameAccess > SAL_CALL ScLinkTargetTypeObj::getLinks(void) throw( uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xCollection;
+
+ if ( pDocShell )
+ {
+ switch ( nType )
+ {
+ case SC_LINKTARGETTYPE_SHEET:
+ xCollection.set(new ScTableSheetsObj(pDocShell));
+ break;
+ case SC_LINKTARGETTYPE_RANGENAME:
+ xCollection.set(new ScNamedRangesObj(pDocShell));
+ break;
+ case SC_LINKTARGETTYPE_DBAREA:
+ xCollection.set(new ScDatabaseRangesObj(pDocShell));
+ break;
+ default:
+ DBG_ERROR("invalid type");
+ }
+ }
+
+ // wrap collection in ScLinkTargetsObj because service document::LinkTargets requires
+ // beans::XPropertySet as ElementType in container::XNameAccess.
+ if ( xCollection.is() )
+ return new ScLinkTargetsObj( xCollection );
+ return NULL;
+}
+
+// beans::XPropertySet
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL ScLinkTargetTypeObj::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+ ScUnoGuard aGuard;
+ static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetLinkTargetMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScLinkTargetTypeObj::setPropertyValue(const rtl::OUString& /* aPropertyName */,
+ const uno::Any& /* aValue */)
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ // everything is read-only
+ //! exception?
+}
+
+// static
+void ScLinkTargetTypeObj::SetLinkTargetBitmap( uno::Any& rRet, sal_uInt16 nType )
+{
+ sal_uInt16 nImgId = 0;
+ switch ( nType )
+ {
+ case SC_LINKTARGETTYPE_SHEET:
+ nImgId = SC_CONTENT_TABLE;
+ break;
+ case SC_LINKTARGETTYPE_RANGENAME:
+ nImgId = SC_CONTENT_RANGENAME;
+ break;
+ case SC_LINKTARGETTYPE_DBAREA:
+ nImgId = SC_CONTENT_DBAREA;
+ break;
+ }
+ if (nImgId)
+ {
+ BOOL bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+ ImageList aEntryImages( ScResId( bHighContrast ? RID_IMAGELIST_H_NAVCONT : RID_IMAGELIST_NAVCONT ) );
+ const Image& rImage = aEntryImages.GetImage( nImgId );
+ rRet <<= uno::Reference< awt::XBitmap > (VCLUnoHelper::CreateBitmap( rImage.GetBitmapEx() ));
+ }
+}
+
+uno::Any SAL_CALL ScLinkTargetTypeObj::getPropertyValue(const rtl::OUString& PropertyName)
+ throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ uno::Any aRet;
+ String aNameStr(PropertyName);
+ if ( aNameStr.EqualsAscii( SC_UNO_LINKDISPBIT ) )
+ SetLinkTargetBitmap( aRet, nType );
+ else if ( aNameStr.EqualsAscii( SC_UNO_LINKDISPNAME ) )
+ aRet <<= rtl::OUString( aName );
+
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScLinkTargetTypeObj )
+
+//------------------------------------------------------------------------
+
+ScLinkTargetsObj::ScLinkTargetsObj( const uno::Reference< container::XNameAccess > & rColl ) :
+ xCollection( rColl )
+{
+ DBG_ASSERT( xCollection.is(), "ScLinkTargetsObj: NULL" );
+}
+
+ScLinkTargetsObj::~ScLinkTargetsObj()
+{
+}
+
+// container::XNameAccess
+
+uno::Any SAL_CALL ScLinkTargetsObj::getByName(const rtl::OUString& aName)
+ throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ uno::Reference< beans::XPropertySet > xProp( ScUnoHelpFunctions::AnyToInterface( xCollection->getByName(aName) ), uno::UNO_QUERY );
+ if (xProp.is())
+ return uno::makeAny(xProp);
+
+ throw container::NoSuchElementException();
+// return uno::Any();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScLinkTargetsObj::getElementNames(void) throw( uno::RuntimeException )
+{
+ return xCollection->getElementNames();
+}
+
+sal_Bool SAL_CALL ScLinkTargetsObj::hasByName(const rtl::OUString& aName) throw( uno::RuntimeException )
+{
+ return xCollection->hasByName(aName);
+}
+
+// container::XElementAccess
+
+uno::Type SAL_CALL ScLinkTargetsObj::getElementType(void) throw( uno::RuntimeException )
+{
+ return ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);
+}
+
+sal_Bool SAL_CALL ScLinkTargetsObj::hasElements(void) throw( uno::RuntimeException )
+{
+ return xCollection->hasElements();
+}
+
+
+
diff --git a/sc/source/ui/unoobj/textuno.cxx b/sc/source/ui/unoobj/textuno.cxx
new file mode 100644
index 000000000000..5c45195621d8
--- /dev/null
+++ b/sc/source/ui/unoobj/textuno.cxx
@@ -0,0 +1,1152 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdobj.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/unomid.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unofored.hxx>
+#include <rtl/uuid.h>
+#include <vcl/virdev.hxx>
+#include <com/sun/star/awt/FontSlant.hpp>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <editeng/unoipset.hxx>
+#include "textuno.hxx"
+#include "fielduno.hxx"
+#include "servuno.hxx"
+#include "editsrc.hxx"
+#include "docsh.hxx"
+#include "editutil.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "cellsuno.hxx"
+#include "hints.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "docfunc.hxx"
+#include "scmod.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+const SvxItemPropertySet * lcl_GetHdFtPropertySet()
+{
+ static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
+ {0,0,0,0,0,0}
+ };
+ static BOOL bTwipsSet = FALSE;
+
+ if (!bTwipsSet)
+ {
+ // modify PropertyMap to include CONVERT_TWIPS flag for font height
+ // (headers/footers are in twips)
+
+ SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
+ while (pEntry->pName)
+ {
+ if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
+ pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
+ pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
+ pEntry->nMemberId == MID_FONTHEIGHT )
+ {
+ pEntry->nMemberId |= CONVERT_TWIPS;
+ }
+
+ ++pEntry;
+ }
+ bTwipsSet = TRUE;
+ }
+ static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
+ return &aHdFtPropertySet_Impl;
+}
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
+SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
+ const EditTextObject* pCenter,
+ const EditTextObject* pRight ) :
+ pLeftText ( NULL ),
+ pCenterText ( NULL ),
+ pRightText ( NULL )
+{
+ if ( pLeft )
+ pLeftText = pLeft->Clone();
+ if ( pCenter )
+ pCenterText = pCenter->Clone();
+ if ( pRight )
+ pRightText = pRight->Clone();
+}
+
+ScHeaderFooterContentObj::~ScHeaderFooterContentObj()
+{
+ delete pLeftText;
+ delete pCenterText;
+ delete pRightText;
+}
+
+void ScHeaderFooterContentObj::AddListener( SfxListener& rListener )
+{
+ rListener.StartListening( aBC );
+}
+
+void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener )
+{
+ rListener.EndListening( aBC );
+}
+
+void ScHeaderFooterContentObj::UpdateText( USHORT nPart, EditEngine& rSource )
+{
+ EditTextObject* pNew = rSource.CreateTextObject();
+ switch (nPart)
+ {
+ case SC_HDFT_LEFT:
+ delete pLeftText;
+ pLeftText = pNew;
+ break;
+ case SC_HDFT_CENTER:
+ delete pCenterText;
+ pCenterText = pNew;
+ break;
+ default: // SC_HDFT_RIGHT
+ delete pRightText;
+ pRightText = pNew;
+ break;
+ }
+
+ aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) );
+}
+
+// XHeaderFooterContent
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT );
+}
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER );
+}
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT );
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
+ const uno::Reference<sheet::XHeaderFooterContent> xObj )
+{
+ ScHeaderFooterContentObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent,
+ USHORT nP ) :
+ rContentObj( rContent ),
+ nPart( nP ),
+ pEditEngine( NULL ),
+ pForwarder( NULL ),
+ bDataValid( FALSE ),
+ bInUpdate( FALSE )
+{
+ rContentObj.acquire(); // must not go away
+ rContentObj.AddListener( *this );
+}
+
+ScHeaderFooterTextData::~ScHeaderFooterTextData()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ rContentObj.RemoveListener( *this );
+
+ delete pForwarder;
+ delete pEditEngine;
+
+ rContentObj.release();
+}
+
+void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScHeaderFooterChangedHint ) )
+ {
+ if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart )
+ {
+ if (!bInUpdate) // not for own updates
+ bDataValid = FALSE; // text has to be fetched again
+ }
+ }
+}
+
+SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, TRUE );
+
+ pHdrEngine->EnableUndo( FALSE );
+ pHdrEngine->SetRefMapMode( MAP_TWIP );
+
+ // default font must be set, independently of document
+ // -> use global pool from module
+
+ SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
+ const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
+ rPattern.FillEditItemSet( &aDefaults );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ pHdrEngine->SetDefaults( aDefaults );
+
+ ScHeaderFieldData aData;
+ ScHeaderFooterTextObj::FillDummyFieldData( aData );
+ pHdrEngine->SetData( aData );
+
+ pEditEngine = pHdrEngine;
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ const EditTextObject* pData;
+ if (nPart == SC_HDFT_LEFT)
+ pData = rContentObj.GetLeftEditObject();
+ else if (nPart == SC_HDFT_CENTER)
+ pData = rContentObj.GetCenterEditObject();
+ else
+ pData = rContentObj.GetRightEditObject();
+
+ if (pData)
+ pEditEngine->SetText(*pData);
+
+ bDataValid = TRUE;
+ return pForwarder;
+}
+
+void ScHeaderFooterTextData::UpdateData()
+{
+ if ( pEditEngine )
+ {
+ bInUpdate = TRUE; // don't reset bDataValid during UpdateText
+
+ rContentObj.UpdateText( nPart, *pEditEngine );
+
+ bInUpdate = FALSE;
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent,
+ USHORT nP ) :
+ aTextData( rContent, nP ),
+ pUnoText( NULL )
+{
+ // ScHeaderFooterTextData acquires rContent
+ // pUnoText is created on demand (getString/setString work without it)
+}
+
+void ScHeaderFooterTextObj::CreateUnoText_Impl()
+{
+ if ( !pUnoText )
+ {
+ // can't be aggregated because getString/setString is handled here
+ ScSharedHeaderFooterEditSource aEditSource( &aTextData );
+ pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() );
+ pUnoText->acquire();
+ }
+}
+
+ScHeaderFooterTextObj::~ScHeaderFooterTextObj()
+{
+ if (pUnoText)
+ pUnoText->release();
+}
+
+const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
+{
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return *pUnoText;
+}
+
+// XText
+
+uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScHeaderFooterTextCursor( *this );
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->createTextCursorByRange(aTextPosition);
+ //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
+}
+
+void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData ) // static
+{
+ String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" )));
+ rData.aTitle = aDummy;
+ rData.aLongDocName = aDummy;
+ rData.aShortDocName = aDummy;
+ rData.aTabName = aDummy;
+ rData.nPageNo = 1;
+ rData.nTotalPages = 99;
+}
+
+rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+ const EditTextObject* pData;
+
+ USHORT nPart = aTextData.GetPart();
+ ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
+
+ if (nPart == SC_HDFT_LEFT)
+ pData = rContentObj.GetLeftEditObject();
+ else if (nPart == SC_HDFT_CENTER)
+ pData = rContentObj.GetCenterEditObject();
+ else
+ pData = rContentObj.GetRightEditObject();
+ if (pData)
+ {
+ // for pure text, no font info is needed in pool defaults
+ ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), TRUE );
+
+ ScHeaderFieldData aData;
+ FillDummyFieldData( aData );
+ aEditEngine.SetData( aData );
+
+ aEditEngine.SetText(*pData);
+ aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
+ }
+ return aRet;
+}
+
+void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aText);
+
+ // for pure text, no font info is needed in pool defaults
+ ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), TRUE );
+ aEditEngine.SetText( aString );
+
+ aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->insertString( xRange, aString, bAbsorb );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
+ const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
+ const uno::Reference<text::XTextRange >& xRange,
+ const uno::Reference<text::XTextContent >& xContent,
+ sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( xContent.is() && xRange.is() )
+ {
+ ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
+
+ SvxUnoTextRangeBase* pTextRange =
+ ScHeaderFooterTextCursor::getImplementation( xRange );
+
+#if 0
+ if (!pTextRange)
+ pTextRange = (SvxUnoTextRange*)xRange->getImplementation(
+ SvxUnoTextRange_getReflection() );
+ //! bei SvxUnoTextRange testen, ob in passendem Objekt !!!
+#endif
+
+ if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
+ {
+ SvxEditSource* pEditSource = pTextRange->GetEditSource();
+ ESelection aSelection(pTextRange->GetSelection());
+
+ if (!bAbsorb)
+ {
+ // don't replace -> append at end
+ aSelection.Adjust();
+ aSelection.nStartPara = aSelection.nEndPara;
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+
+ SvxFieldItem aItem(pHeaderField->CreateFieldItem());
+
+ SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
+ pForwarder->QuickInsertField( aItem, aSelection );
+ pEditSource->UpdateData();
+
+ // neue Selektion: ein Zeichen
+ aSelection.Adjust();
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aSelection.nStartPos + 1;
+ pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection );
+
+ // #91431# for bAbsorb=FALSE, the new selection must be behind the inserted content
+ // (the xml filter relies on this)
+ if (!bAbsorb)
+ aSelection.nStartPos = aSelection.nEndPos;
+
+ pTextRange->SetSelection( aSelection );
+
+ return;
+ }
+ }
+
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->insertTextContent( xRange, xContent, bAbsorb );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
+ const uno::Reference<text::XTextContent>& xContent )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if ( xContent.is() )
+ {
+ ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
+ if ( pHeaderField && pHeaderField->IsInserted() )
+ {
+ //! Testen, ob das Feld in dieser Zelle ist
+ pHeaderField->DeleteField();
+ return;
+ }
+ }
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->removeTextContent( xContent );
+}
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getText();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getStart();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getEnd();
+}
+
+// XTextFieldsSupplier
+
+uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // all fields
+ return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID );
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
+ throw(uno::RuntimeException)
+{
+ // sowas gibts nicht im Calc (?)
+ return NULL;
+}
+
+// XTextRangeMover
+
+void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
+ const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nParagraphs )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->moveTextRange( xRange, nParagraphs );
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->createEnumeration();
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getElementType();
+}
+
+sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->hasElements();
+}
+
+//------------------------------------------------------------------------
+
+ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
+ SvxUnoTextCursor( rOther ),
+ rTextObj( rOther.rTextObj )
+{
+ rTextObj.acquire();
+}
+
+ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
+ SvxUnoTextCursor( rText.GetUnoText() ),
+ rTextObj( rText )
+{
+ rTextObj.acquire();
+}
+
+ScCellTextCursor::~ScCellTextCursor() throw()
+{
+ rTextObj.release();
+}
+
+// SvxUnoTextCursor methods reimplemented here to return the right objects:
+
+uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return &rTextObj;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScCellTextCursor* pNew = new ScCellTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScCellTextCursor* pNew = new ScCellTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScCellTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
+ SvxUnoTextCursor( rOther ),
+ rTextObj( rOther.rTextObj )
+{
+ rTextObj.acquire();
+}
+
+ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
+ SvxUnoTextCursor( rText.GetUnoText() ),
+ rTextObj( rText )
+{
+ rTextObj.acquire();
+}
+
+ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
+{
+ rTextObj.release();
+}
+
+// SvxUnoTextCursor methods reimplemented here to return the right objects:
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return &rTextObj;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
+ const uno::Reference<uno::XInterface> xObj )
+{
+ ScHeaderFooterTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
+ SvxUnoTextCursor( rOther ),
+ xParentText( rOther.xParentText )
+{
+}
+
+ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
+ const SvxUnoTextBase& rText ) :
+ SvxUnoTextCursor( rText ),
+ xParentText( xParent )
+
+{
+}
+
+ScDrawTextCursor::~ScDrawTextCursor() throw()
+{
+}
+
+// SvxUnoTextCursor methods reimplemented here to return the right objects:
+
+uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return xParentText;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScDrawTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
+{
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
+ pEnginePool->FreezeIdRanges();
+
+ pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE ); // TRUE: become owner of pool
+ pForwarder = new SvxEditEngineForwarder( *pEditEngine );
+ pOriginalSource = new ScSimpleEditSource( pForwarder );
+}
+
+ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ delete pOriginalSource;
+ delete pForwarder;
+ delete pEditEngine;
+}
+
+ScEditEngineTextObj::ScEditEngineTextObj() :
+ SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
+{
+}
+
+ScEditEngineTextObj::~ScEditEngineTextObj() throw()
+{
+}
+
+void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
+{
+ GetEditEngine()->SetText( rTextObject );
+
+ ESelection aSel;
+ ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
+ SetSelection( aSel );
+}
+
+EditTextObject* ScEditEngineTextObj::CreateTextObject()
+{
+ return GetEditEngine()->CreateTextObject();
+}
+
+//------------------------------------------------------------------------
+
+ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
+ pDocShell( pDocSh ),
+ aCellPos( rP ),
+ pEditEngine( NULL ),
+ pForwarder( NULL ),
+ pOriginalSource( NULL ),
+ bDataValid( FALSE ),
+ bInUpdate( FALSE ),
+ bDirty( FALSE ),
+ bDoUpdate( TRUE )
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScCellTextData::~ScCellTextData()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ if (pDocShell)
+ {
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+ pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
+ }
+ else
+ delete pEditEngine;
+
+ delete pForwarder;
+
+ delete pOriginalSource;
+}
+
+ScSharedCellEditSource* ScCellTextData::GetOriginalSource()
+{
+ if (!pOriginalSource)
+ pOriginalSource = new ScSharedCellEditSource( this );
+ return pOriginalSource;
+}
+
+void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
+ }
+}
+
+SvxTextForwarder* ScCellTextData::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pEditEngine = pDoc->CreateFieldEditEngine();
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ }
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+// pEditEngine->SetUpdateMode( FALSE );
+ pEditEngine->EnableUndo( FALSE );
+ if (pDocShell)
+ pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
+ else
+ pEditEngine->SetRefMapMode( MAP_100TH_MM );
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ String aText;
+
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
+ if( const ScPatternAttr* pPattern =
+ pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
+ {
+ pPattern->FillEditItemSet( &aDefaults );
+ pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
+ }
+
+ const ScBaseCell* pCell = pDoc->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
+ pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults );
+ else
+ {
+ GetCellText( aCellPos, aText );
+ if (aText.Len())
+ pEditEngine->SetTextNewDefaults( aText, aDefaults );
+ else
+ pEditEngine->SetDefaults(aDefaults);
+ }
+ }
+
+ bDataValid = TRUE;
+ return pForwarder;
+}
+
+void ScCellTextData::UpdateData()
+{
+ if ( bDoUpdate )
+ {
+ DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()");
+ if ( pDocShell && pEditEngine )
+ {
+ // during the own UpdateData call, bDataValid must not be reset,
+ // or things like attributes after the text would be lost
+ // (are not stored in the cell)
+
+ bInUpdate = TRUE; // prevents bDataValid from being reset
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.PutData( aCellPos, *pEditEngine, FALSE, TRUE ); // always as text
+
+ bInUpdate = FALSE;
+ bDirty = FALSE;
+ }
+ }
+ else
+ bDirty = TRUE;
+}
+
+void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // invalid now
+
+ DELETEZ( pForwarder );
+ DELETEZ( pEditEngine ); // EditEngine uses document's pool
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ if (!bInUpdate) // not for own UpdateData calls
+ bDataValid = FALSE; // text has to be read from the cell again
+ }
+ }
+}
+
+ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
+ ScCellTextData( pDocSh, rP ),
+ SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
+{
+}
+
+ScCellTextObj::~ScCellTextObj() throw()
+{
+}
+
diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx
new file mode 100644
index 000000000000..5e3b3102e14a
--- /dev/null
+++ b/sc/source/ui/unoobj/tokenuno.cxx
@@ -0,0 +1,467 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "tokenuno.hxx"
+
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/AddressConvention.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <svl/itemprop.hxx>
+
+#include "miscuno.hxx"
+#include "convuno.hxx"
+#include "unonames.hxx"
+#include "unoguard.hxx"
+#include "token.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+#include "docsh.hxx"
+#include "rangeseq.hxx"
+#include "externalrefmgr.hxx"
+
+using namespace ::formula;
+using namespace ::com::sun::star;
+
+// ============================================================================
+
+const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap()
+{
+ static SfxItemPropertyMapEntry aFormulaParserMap_Impl[] =
+ {
+ {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 },
+ {MAP_CHAR_LEN(SC_UNO_FORMULACONVENTION), 0, &getCppuType(&sheet::AddressConvention::UNSPECIFIED), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_OPCODEMAP), 0, &getCppuType((uno::Sequence< sheet::FormulaOpCodeMapEntry >*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aFormulaParserMap_Impl;
+}
+
+SC_SIMPLE_SERVICE_INFO( ScFormulaParserObj, "ScFormulaParserObj", SC_SERVICENAME_FORMULAPARS )
+
+// ============================================================================
+
+ScFormulaParserObj::ScFormulaParserObj(ScDocShell* pDocSh) :
+ mpDocShell( pDocSh ),
+ mnConv( sheet::AddressConvention::UNSPECIFIED ),
+ mbEnglish( false ),
+ mbIgnoreSpaces( true ),
+ mbCompileFAP( false )
+{
+ mpDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScFormulaParserObj::~ScFormulaParserObj()
+{
+ if (mpDocShell)
+ mpDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScFormulaParserObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ mpDocShell = NULL;
+}
+
+// XFormulaParser
+
+void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
+{
+ static const formula::FormulaGrammar::AddressConvention aConvMap[] = {
+ formula::FormulaGrammar::CONV_OOO, // <- AddressConvention::OOO
+ formula::FormulaGrammar::CONV_XL_A1, // <- AddressConvention::XL_A1
+ formula::FormulaGrammar::CONV_XL_R1C1, // <- AddressConvention::XL_R1C1
+ formula::FormulaGrammar::CONV_XL_OOX, // <- AddressConvention::XL_OOX
+ formula::FormulaGrammar::CONV_LOTUS_A1 // <- AddressConvention::LOTUS_A1
+ };
+ static const sal_Int16 nConvMapCount = sizeof(aConvMap)/sizeof(aConvMap[0]);
+
+ // If mxOpCodeMap is not empty it overrides mbEnglish, and vice versa. We
+ // don't need to initialize things twice.
+ if (mxOpCodeMap.get())
+ rCompiler.SetFormulaLanguage( mxOpCodeMap );
+ else
+ {
+ sal_Int32 nFormulaLanguage = mbEnglish ?
+ sheet::FormulaLanguage::ENGLISH :
+ sheet::FormulaLanguage::NATIVE;
+ ScCompiler::OpCodeMapPtr xMap = rCompiler.GetOpCodeMap( nFormulaLanguage);
+ rCompiler.SetFormulaLanguage( xMap);
+ }
+
+ formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_UNSPECIFIED;
+ if (mnConv >= 0 && mnConv < nConvMapCount)
+ eConv = aConvMap[mnConv];
+
+ rCompiler.SetRefConvention( eConv );
+
+ rCompiler.SetCompileForFAP(mbCompileFAP);
+
+ rCompiler.SetExternalLinks( maExternalLinks);
+}
+
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula(
+ const rtl::OUString& aFormula, const table::CellAddress& rReferencePos )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Sequence<sheet::FormulaToken> aRet;
+
+ if (mpDocShell)
+ {
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ ScExternalRefManager::ApiGuard aExtRefGuard(pDoc);
+
+ ScAddress aRefPos( ScAddress::UNINITIALIZED );
+ ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
+ ScCompiler aCompiler( pDoc, aRefPos);
+ aCompiler.SetGrammar(pDoc->GetGrammar());
+ SetCompilerFlags( aCompiler );
+
+ ScTokenArray* pCode = aCompiler.CompileString( aFormula );
+ (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aRet, *pCode );
+ delete pCode;
+ }
+
+ return aRet;
+}
+
+rtl::OUString SAL_CALL ScFormulaParserObj::printFormula(
+ const uno::Sequence<sheet::FormulaToken>& aTokens, const table::CellAddress& rReferencePos )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ rtl::OUString aRet;
+
+ if (mpDocShell)
+ {
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ ScTokenArray aCode;
+ (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aCode, aTokens );
+ ScAddress aRefPos( ScAddress::UNINITIALIZED );
+ ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
+ ScCompiler aCompiler( pDoc, aRefPos, aCode);
+ aCompiler.SetGrammar(pDoc->GetGrammar());
+ SetCompilerFlags( aCompiler );
+
+ rtl::OUStringBuffer aBuffer;
+ aCompiler.CreateStringFromTokenArray( aBuffer );
+ aRet = aBuffer.makeStringAndClear();
+ }
+
+ return aRet;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFormulaParserObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetFormulaParserMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScFormulaParserObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+ if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
+ {
+ aValue >>= mbCompileFAP;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_COMPILEENGLISH ) )
+ {
+ bool bOldEnglish = mbEnglish;
+ if (aValue >>= mbEnglish)
+ {
+ // Need to recreate the symbol map to change English property
+ // because the map is const. So for performance reasons set
+ // CompileEnglish _before_ OpCodeMap!
+ if (mxOpCodeMap.get() && mbEnglish != bOldEnglish)
+ {
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ ScCompiler aCompiler( pDoc, ScAddress());
+ aCompiler.SetGrammar(pDoc->GetGrammar());
+ mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
+ }
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ else if ( aString.EqualsAscii( SC_UNO_FORMULACONVENTION ) )
+ {
+ aValue >>= mnConv;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_IGNORELEADING ) )
+ {
+ aValue >>= mbIgnoreSpaces;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_OPCODEMAP ) )
+ {
+ if (aValue >>= maOpCodeMapping)
+ {
+ ScDocument* pDoc = mpDocShell->GetDocument();
+ ScCompiler aCompiler( pDoc, ScAddress());
+ aCompiler.SetGrammar(pDoc->GetGrammar());
+ mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) )
+ {
+ if (!(aValue >>= maExternalLinks))
+ throw lang::IllegalArgumentException();
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Any aRet;
+ String aString(aPropertyName);
+ if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
+ {
+ aRet <<= mbCompileFAP;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_COMPILEENGLISH ) )
+ {
+ aRet <<= mbEnglish;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_FORMULACONVENTION ) )
+ {
+ aRet <<= mnConv;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_IGNORELEADING ) )
+ {
+ aRet <<= mbIgnoreSpaces;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_OPCODEMAP ) )
+ {
+ aRet <<= maOpCodeMapping;
+ }
+ else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) )
+ {
+ aRet <<= maExternalLinks;
+ }
+ else
+ throw beans::UnknownPropertyException();
+ return aRet;
+}
+
+SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFormulaParserObj )
+
+// ============================================================================
+
+void lcl_ExternalRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef )
+{
+ rAPI.Column = rRef.nCol;
+ rAPI.Row = rRef.nRow;
+ rAPI.Sheet = 0;
+ rAPI.RelativeColumn = rRef.nRelCol;
+ rAPI.RelativeRow = rRef.nRelRow;
+ rAPI.RelativeSheet = 0;
+
+ sal_Int32 nFlags = 0;
+ if ( rRef.IsColRel() ) nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE;
+ if ( rRef.IsRowRel() ) nFlags |= sheet::ReferenceFlags::ROW_RELATIVE;
+ if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED;
+ if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED;
+ if ( rRef.IsFlag3D() ) nFlags |= sheet::ReferenceFlags::SHEET_3D;
+ if ( rRef.IsRelName() ) nFlags |= sheet::ReferenceFlags::RELATIVE_NAME;
+ rAPI.Flags = nFlags;
+}
+
+void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef )
+{
+ rAPI.Column = rRef.nCol;
+ rAPI.Row = rRef.nRow;
+ rAPI.Sheet = rRef.nTab;
+ rAPI.RelativeColumn = rRef.nRelCol;
+ rAPI.RelativeRow = rRef.nRelRow;
+ rAPI.RelativeSheet = rRef.nRelTab;
+
+ sal_Int32 nFlags = 0;
+ if ( rRef.IsColRel() ) nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE;
+ if ( rRef.IsRowRel() ) nFlags |= sheet::ReferenceFlags::ROW_RELATIVE;
+ if ( rRef.IsTabRel() ) nFlags |= sheet::ReferenceFlags::SHEET_RELATIVE;
+ if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED;
+ if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED;
+ if ( rRef.IsTabDeleted() ) nFlags |= sheet::ReferenceFlags::SHEET_DELETED;
+ if ( rRef.IsFlag3D() ) nFlags |= sheet::ReferenceFlags::SHEET_3D;
+ if ( rRef.IsRelName() ) nFlags |= sheet::ReferenceFlags::RELATIVE_NAME;
+ rAPI.Flags = nFlags;
+}
+
+// static
+bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc,
+ ScTokenArray& rTokenArray, const uno::Sequence<sheet::FormulaToken>& rSequence )
+{
+ return !rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager());
+}
+
+// static
+bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc,
+ uno::Sequence<sheet::FormulaToken>& rSequence, const ScTokenArray& rTokenArray )
+{
+ bool bError = false;
+
+ sal_Int32 nLen = static_cast<sal_Int32>(rTokenArray.GetLen());
+ formula::FormulaToken** pTokens = rTokenArray.GetArray();
+ if ( pTokens )
+ {
+ rSequence.realloc(nLen);
+ for (sal_Int32 nPos=0; nPos<nLen; nPos++)
+ {
+ const formula::FormulaToken& rToken = *pTokens[nPos];
+ sheet::FormulaToken& rAPI = rSequence[nPos];
+
+ OpCode eOpCode = rToken.GetOpCode();
+ // eOpCode may be changed in the following switch/case
+ switch ( rToken.GetType() )
+ {
+ case svByte:
+ // Only the count of spaces is stored as "long". Parameter count is ignored.
+ if ( eOpCode == ocSpaces )
+ rAPI.Data <<= (sal_Int32) rToken.GetByte();
+ else
+ rAPI.Data.clear(); // no data
+ break;
+ case formula::svDouble:
+ rAPI.Data <<= rToken.GetDouble();
+ break;
+ case formula::svString:
+ rAPI.Data <<= rtl::OUString( rToken.GetString() );
+ break;
+ case svExternal:
+ // Function name is stored as string.
+ // Byte (parameter count) is ignored.
+ rAPI.Data <<= rtl::OUString( rToken.GetExternal() );
+ break;
+ case svSingleRef:
+ {
+ sheet::SingleReference aSingleRef;
+ lcl_SingleRefToApi( aSingleRef, static_cast<const ScToken&>(rToken).GetSingleRef() );
+ rAPI.Data <<= aSingleRef;
+ }
+ break;
+ case formula::svDoubleRef:
+ {
+ sheet::ComplexReference aCompRef;
+ lcl_SingleRefToApi( aCompRef.Reference1, static_cast<const ScToken&>(rToken).GetSingleRef() );
+ lcl_SingleRefToApi( aCompRef.Reference2, static_cast<const ScToken&>(rToken).GetSingleRef2() );
+ rAPI.Data <<= aCompRef;
+ }
+ break;
+ case svIndex:
+ rAPI.Data <<= static_cast<sal_Int32>( rToken.GetIndex() );
+ break;
+ case svMatrix:
+ if (!ScRangeToSequence::FillMixedArray( rAPI.Data, static_cast<const ScToken&>(rToken).GetMatrix(), true))
+ rAPI.Data.clear();
+ break;
+ case svExternalSingleRef:
+ {
+ sheet::SingleReference aSingleRef;
+ lcl_ExternalRefToApi( aSingleRef, static_cast<const ScToken&>(rToken).GetSingleRef() );
+ size_t nCacheId;
+ rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId );
+ aSingleRef.Sheet = static_cast< sal_Int32 >( nCacheId );
+ sheet::ExternalReference aExtRef;
+ aExtRef.Index = rToken.GetIndex();
+ aExtRef.Reference <<= aSingleRef;
+ rAPI.Data <<= aExtRef;
+ eOpCode = ocPush;
+ }
+ break;
+ case svExternalDoubleRef:
+ {
+ sheet::ComplexReference aComplRef;
+ lcl_ExternalRefToApi( aComplRef.Reference1, static_cast<const ScToken&>(rToken).GetSingleRef() );
+ lcl_ExternalRefToApi( aComplRef.Reference2, static_cast<const ScToken&>(rToken).GetSingleRef2() );
+ size_t nCacheId;
+ rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId );
+ aComplRef.Reference1.Sheet = static_cast< sal_Int32 >( nCacheId );
+ // NOTE: This assumes that cached sheets are in consecutive order!
+ aComplRef.Reference2.Sheet = aComplRef.Reference1.Sheet + (static_cast<const ScToken&>(rToken).GetSingleRef2().nTab - static_cast<const ScToken&>(rToken).GetSingleRef().nTab);
+ sheet::ExternalReference aExtRef;
+ aExtRef.Index = rToken.GetIndex();
+ aExtRef.Reference <<= aComplRef;
+ rAPI.Data <<= aExtRef;
+ eOpCode = ocPush;
+ }
+ break;
+ case svExternalName:
+ {
+ sheet::ExternalReference aExtRef;
+ aExtRef.Index = rToken.GetIndex();
+ aExtRef.Reference <<= ::rtl::OUString( rToken.GetString() );
+ rAPI.Data <<= aExtRef;
+ eOpCode = ocPush;
+ }
+ break;
+ default:
+ DBG_ERROR1( "ScTokenConversion::ConvertToTokenSequence: unhandled token type SvStackVar %d", rToken.GetType());
+ case svSep: // occurs with ocSep, ocOpen, ocClose, ocArray*
+ case svJump: // occurs with ocIf, ocChose
+ case svMissing: // occurs with ocMissing
+ rAPI.Data.clear(); // no data
+ }
+ rAPI.OpCode = static_cast<sal_Int32>(eOpCode); //! assuming equal values for the moment
+ }
+ }
+ else
+ rSequence.realloc(0);
+
+ return !bError;
+}
+
+// ============================================================================
+
+ScFormulaOpCodeMapperObj::ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler)
+: formula::FormulaOpCodeMapperObj(_pCompiler)
+{
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/unoobj/unodoc.cxx b/sc/source/ui/unoobj/unodoc.cxx
new file mode 100644
index 000000000000..d3d755e8b495
--- /dev/null
+++ b/sc/source/ui/unoobj/unodoc.cxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+#include <tools/string.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include "scmod.hxx"
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include "docsh.hxx"
+
+using namespace ::com::sun::star;
+
+::rtl::OUString SAL_CALL ScDocument_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.SpreadsheetDocument" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScDocument_getSupportedServiceNames() throw()
+{
+ uno::Sequence< rtl::OUString > aSeq( 1 );
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScDocument_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & /* rSMgr */, const sal_uInt64 _nCreationFlags ) throw( uno::Exception )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ ScDLL::Init();
+ SfxObjectShell* pShell = new ScDocShell( _nCreationFlags );
+ return uno::Reference< uno::XInterface >( pShell->GetModel() );
+}
+
+
diff --git a/sc/source/ui/unoobj/unoguard.cxx b/sc/source/ui/unoobj/unoguard.cxx
new file mode 100644
index 000000000000..ff1c94338b72
--- /dev/null
+++ b/sc/source/ui/unoobj/unoguard.cxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+
+#include "unoguard.hxx"
+
+//------------------------------------------------------------------------
+
+ScUnoGuard::ScUnoGuard() :
+ OGuard( Application::GetSolarMutex() )
+{
+}
+
+
+
+
diff --git a/sc/source/ui/unoobj/unoreflist.cxx b/sc/source/ui/unoobj/unoreflist.cxx
new file mode 100644
index 000000000000..65f43273f6e7
--- /dev/null
+++ b/sc/source/ui/unoobj/unoreflist.cxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "unoreflist.hxx"
+#include "document.hxx"
+
+//------------------------------------------------------------------------
+
+ScUnoRefList::ScUnoRefList()
+{
+}
+
+ScUnoRefList::~ScUnoRefList()
+{
+}
+
+void ScUnoRefList::Add( sal_Int64 nId, const ScRangeList& rOldRanges )
+{
+ aEntries.push_back( ScUnoRefEntry( nId, rOldRanges ) );
+}
+
+void ScUnoRefList::Undo( ScDocument* pDoc )
+{
+ std::list<ScUnoRefEntry>::const_iterator aEnd( aEntries.end() );
+ for ( std::list<ScUnoRefEntry>::const_iterator aIter( aEntries.begin() );
+ aIter != aEnd; ++aIter )
+ {
+ ScUnoRefUndoHint aHint( *aIter );
+ pDoc->BroadcastUno( aHint );
+ }
+}
+
+//------------------------------------------------------------------------
+
+TYPEINIT1(ScUnoRefUndoHint, SfxHint);
+
+ScUnoRefUndoHint::ScUnoRefUndoHint( const ScUnoRefEntry& rRefEntry ) :
+ aEntry( rRefEntry )
+{
+}
+
+ScUnoRefUndoHint::~ScUnoRefUndoHint()
+{
+}
+
diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx
new file mode 100644
index 000000000000..fd1e655b8ffb
--- /dev/null
+++ b/sc/source/ui/unoobj/viewuno.cxx
@@ -0,0 +1,2358 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/view/DocumentZoomType.hpp>
+
+#include <editeng/outliner.hxx>
+#include <svx/fmdpage.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/unoshcol.hxx>
+#include <svx/fmshell.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <rtl/uuid.h>
+#include <toolkit/helper/convert.hxx>
+
+#include "drawsh.hxx"
+#include "drtxtob.hxx"
+#include "transobj.hxx"
+#include "editsh.hxx"
+#include "viewuno.hxx"
+#include "cellsuno.hxx"
+#include "miscuno.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+#include "sc.hrc"
+#include "unoguard.hxx"
+#include "unonames.hxx"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "gridwin.hxx"
+#include "sheetevents.hxx"
+#include "AccessibilityHints.hxx"
+#include <svx/sdrhittesthelper.hxx>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+//! Clipping-Markierungen
+
+// alles ohne Which-ID, Map nur fuer PropertySetInfo
+
+const SfxItemPropertyMapEntry* lcl_GetViewOptPropertyMap()
+{
+ static SfxItemPropertyMapEntry aViewOptPropertyMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(OLD_UNO_COLROWHDR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_GRIDCOLOR), 0, &getCppuType((sal_Int32*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_COLROWHDR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_HORSCROLL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHEETTABS), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_VERTSCROLL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_HIDESPELL), 0, &getBooleanCppuType(), 0, 0}, /* deprecated #i91949 */
+ {MAP_CHAR_LEN(OLD_UNO_HORSCROLL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_OUTLSYMB), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_VALUEHIGH), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(OLD_UNO_OUTLSYMB), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(OLD_UNO_SHEETTABS), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWANCHOR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWCHARTS), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWDRAW), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWFORM), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWGRID), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWHELP), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWNOTES), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWOBJ), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWPAGEBR), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWZERO), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_SHOWSOLID), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(OLD_UNO_VALUEHIGH), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(OLD_UNO_VERTSCROLL), 0, &getBooleanCppuType(), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_VISAREA), 0, &getCppuType((awt::Rectangle*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ZOOMTYPE), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {MAP_CHAR_LEN(SC_UNO_ZOOMVALUE), 0, &getCppuType((sal_Int16*)0), 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aViewOptPropertyMap_Impl;
+}
+
+//------------------------------------------------------------------------
+
+SV_IMPL_PTRARR( XRangeSelectionListenerArr_Impl, XRangeSelectionListenerPtr );
+SV_IMPL_PTRARR( XRangeSelectionChangeListenerArr_Impl, XRangeSelectionChangeListenerPtr );
+SV_IMPL_PTRARR( XSelectionChangeListenerArr_Impl, XSelectionChangeListenerPtr );
+SV_IMPL_PTRARR( XViewPropertyChangeListenerArr_Impl, XViewPropertyChangeListenerPtr );
+SV_IMPL_PTRARR( XMouseClickHandlerArr_Impl, XMouseClickHandlerPtr );
+SV_IMPL_PTRARR( XActivationEventListenerArr_Impl, XActivationEventListenerPtr );
+
+#define SCTABVIEWOBJ_SERVICE "com.sun.star.sheet.SpreadsheetView"
+#define SCVIEWSETTINGS_SERVICE "com.sun.star.sheet.SpreadsheetViewSettings"
+
+SC_SIMPLE_SERVICE_INFO( ScViewPaneBase, "ScViewPaneObj", "com.sun.star.sheet.SpreadsheetViewPane" )
+
+//------------------------------------------------------------------------
+
+ScViewPaneBase::ScViewPaneBase(ScTabViewShell* pViewSh, USHORT nP) :
+ pViewShell( pViewSh ),
+ nPane( nP )
+{
+ if (pViewShell)
+ StartListening(*pViewShell);
+}
+
+ScViewPaneBase::~ScViewPaneBase()
+{
+ if (pViewShell)
+ EndListening(*pViewShell);
+}
+
+void ScViewPaneBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ pViewShell = NULL;
+}
+
+uno::Any SAL_CALL ScViewPaneBase::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XViewPane )
+ SC_QUERYINTERFACE( sheet::XCellRangeReferrer )
+ SC_QUERYINTERFACE( view::XFormLayerAccess )
+ SC_QUERYINTERFACE( view::XControlAccess )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+ SC_QUERYINTERFACE( lang::XTypeProvider )
+
+ return uno::Any(); // OWeakObject is in derived objects
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScViewPaneBase::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ aTypes.realloc(5);
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[0] = getCppuType((const uno::Reference<sheet::XViewPane>*)0);
+ pPtr[1] = getCppuType((const uno::Reference<sheet::XCellRangeReferrer>*)0);
+ pPtr[2] = getCppuType((const uno::Reference<view::XFormLayerAccess>*)0);
+ pPtr[3] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
+ pPtr[4] = getCppuType((const uno::Reference<lang::XTypeProvider>*)0);
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScViewPaneBase::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XViewPane
+
+sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleColumn() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewData->GetActivePart() :
+ (ScSplitPos) nPane;
+ ScHSplitPos eWhichH = WhichH( eWhich );
+
+ return pViewData->GetPosX( eWhichH );
+ }
+ DBG_ERROR("keine View ?!?"); //! Exception?
+ return 0;
+}
+
+void SAL_CALL ScViewPaneBase::setFirstVisibleColumn( sal_Int32 nFirstVisibleColumn )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewData->GetActivePart() :
+ (ScSplitPos) nPane;
+ ScHSplitPos eWhichH = WhichH( eWhich );
+
+ long nDeltaX = ((long)nFirstVisibleColumn) - pViewData->GetPosX( eWhichH );
+ pViewShell->ScrollX( nDeltaX, eWhichH );
+ }
+}
+
+sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleRow() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewData->GetActivePart() :
+ (ScSplitPos) nPane;
+ ScVSplitPos eWhichV = WhichV( eWhich );
+
+ return pViewData->GetPosY( eWhichV );
+ }
+ DBG_ERROR("keine View ?!?"); //! Exception?
+ return 0;
+}
+
+void SAL_CALL ScViewPaneBase::setFirstVisibleRow( sal_Int32 nFirstVisibleRow )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewData->GetActivePart() :
+ (ScSplitPos) nPane;
+ ScVSplitPos eWhichV = WhichV( eWhich );
+
+ long nDeltaY = ((long)nFirstVisibleRow) - pViewData->GetPosY( eWhichV );
+ pViewShell->ScrollY( nDeltaY, eWhichV );
+ }
+}
+
+table::CellRangeAddress SAL_CALL ScViewPaneBase::getVisibleRange() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ table::CellRangeAddress aAdr;
+ if (pViewShell)
+ {
+ ScViewData* pViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewData->GetActivePart() :
+ (ScSplitPos) nPane;
+ ScHSplitPos eWhichH = WhichH( eWhich );
+ ScVSplitPos eWhichV = WhichV( eWhich );
+
+ // VisibleCellsX gibt nur komplett sichtbare Zellen,
+ // VisibleRange in Excel auch teilweise sichtbare.
+ //! anpassen ???
+
+ SCCOL nVisX = pViewData->VisibleCellsX( eWhichH );
+ SCROW nVisY = pViewData->VisibleCellsY( eWhichV );
+ if (!nVisX) nVisX = 1; // irgendwas muss ja im Range sein
+ if (!nVisY) nVisY = 1;
+ aAdr.Sheet = pViewData->GetTabNo();
+ aAdr.StartColumn = pViewData->GetPosX( eWhichH );
+ aAdr.StartRow = pViewData->GetPosY( eWhichV );
+ aAdr.EndColumn = aAdr.StartColumn + nVisX - 1;
+ aAdr.EndRow = aAdr.StartRow + nVisY - 1;
+ }
+ return aAdr;
+}
+
+// XCellRangeSource
+
+uno::Reference<table::XCellRange> SAL_CALL ScViewPaneBase::getReferredCells()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (pViewShell)
+ {
+ ScDocShell* pDocSh = pViewShell->GetViewData()->GetDocShell();
+
+ table::CellRangeAddress aAdr(getVisibleRange()); //! Hilfsfunktion mit ScRange?
+ ScRange aRange( (SCCOL)aAdr.StartColumn, (SCROW)aAdr.StartRow, aAdr.Sheet,
+ (SCCOL)aAdr.EndColumn, (SCROW)aAdr.EndRow, aAdr.Sheet );
+ if ( aRange.aStart == aRange.aEnd )
+ return new ScCellObj( pDocSh, aRange.aStart );
+ else
+ return new ScCellRangeObj( pDocSh, aRange );
+ }
+
+ return NULL;
+}
+
+namespace
+{
+ bool lcl_prepareFormShellCall( ScTabViewShell* _pViewShell, USHORT _nPane, FmFormShell*& _rpFormShell, Window*& _rpWindow, SdrView*& _rpSdrView )
+ {
+ if ( !_pViewShell )
+ return false;
+
+ ScViewData* pViewData = _pViewShell->GetViewData();
+ ScSplitPos eWhich = ( _nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewData->GetActivePart() :
+ (ScSplitPos) _nPane;
+ _rpWindow = _pViewShell->GetWindowByPos( eWhich );
+ _rpSdrView = _pViewShell->GetSdrView();
+ _rpFormShell = _pViewShell->GetFormShell();
+ return ( _rpFormShell != NULL ) && ( _rpSdrView != NULL )&& ( _rpWindow != NULL );
+ }
+}
+
+// XFormLayerAccess
+uno::Reference< form::runtime::XFormController > SAL_CALL ScViewPaneBase::getFormController( const uno::Reference< form::XForm >& _Form ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference< form::runtime::XFormController > xController;
+
+ Window* pWindow( NULL );
+ SdrView* pSdrView( NULL );
+ FmFormShell* pFormShell( NULL );
+ if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
+ xController = pFormShell->GetFormController( _Form, *pSdrView, *pWindow );
+
+ return xController;
+}
+
+::sal_Bool SAL_CALL ScViewPaneBase::isFormDesignMode( ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ sal_Bool bIsFormDesignMode( sal_True );
+
+ FmFormShell* pFormShell( pViewShell ? pViewShell->GetFormShell() : NULL );
+ if ( pFormShell )
+ bIsFormDesignMode = pFormShell->IsDesignMode();
+
+ return bIsFormDesignMode;
+}
+
+void SAL_CALL ScViewPaneBase::setFormDesignMode( ::sal_Bool _DesignMode ) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ Window* pWindow( NULL );
+ SdrView* pSdrView( NULL );
+ FmFormShell* pFormShell( NULL );
+ if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
+ pFormShell->SetDesignMode( _DesignMode );
+}
+
+// XControlAccess
+
+uno::Reference<awt::XControl> SAL_CALL ScViewPaneBase::getControl(
+ const uno::Reference<awt::XControlModel>& xModel )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<awt::XControl> xRet;
+
+ Window* pWindow( NULL );
+ SdrView* pSdrView( NULL );
+ FmFormShell* pFormShell( NULL );
+ if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
+ pFormShell->GetFormControl( xModel, *pSdrView, *pWindow, xRet );
+
+ if ( !xRet.is() )
+ throw container::NoSuchElementException(); // no control found
+
+ return xRet;
+}
+
+awt::Rectangle ScViewPaneBase::GetVisArea() const
+{
+ awt::Rectangle aVisArea;
+ if (pViewShell)
+ {
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewShell->GetViewData()->GetActivePart() :
+ (ScSplitPos) nPane;
+ ScGridWindow* pWindow = (ScGridWindow*)pViewShell->GetWindowByPos(eWhich);
+ ScDocument* pDoc = pViewShell->GetViewData()->GetDocument();
+ if (pWindow && pDoc)
+ {
+ ScHSplitPos eWhichH = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_BOTTOMLEFT)) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+ ScVSplitPos eWhichV = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_TOPRIGHT)) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+ ScAddress aCell(pViewShell->GetViewData()->GetPosX(eWhichH),
+ pViewShell->GetViewData()->GetPosY(eWhichV),
+ pViewShell->GetViewData()->GetTabNo());
+ Rectangle aVisRect(pDoc->GetMMRect(aCell.Col(), aCell.Row(), aCell.Col(), aCell.Row(), aCell.Tab()));
+
+ aVisRect.SetSize(pWindow->PixelToLogic(pWindow->GetSizePixel(), pWindow->GetDrawMapMode(sal_True)));
+
+ aVisArea = AWTRectangle(aVisRect);
+ }
+ }
+ return aVisArea;
+}
+
+//------------------------------------------------------------------------
+
+ScViewPaneObj::ScViewPaneObj(ScTabViewShell* pViewSh, USHORT nP) :
+ ScViewPaneBase( pViewSh, nP )
+{
+}
+
+ScViewPaneObj::~ScViewPaneObj()
+{
+}
+
+uno::Any SAL_CALL ScViewPaneObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ // ScViewPaneBase has everything except OWeakObject
+
+ uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
+ if (!aRet.hasValue())
+ aRet = OWeakObject::queryInterface( rType );
+ return aRet;
+}
+
+void SAL_CALL ScViewPaneObj::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ScViewPaneObj::release() throw()
+{
+ OWeakObject::release();
+}
+
+//------------------------------------------------------------------------
+
+// Default-ctor wird fuer SMART_REFLECTION_IMPLEMENTATION gebraucht
+
+//UNUSED2008-05 ScTabViewObj::ScTabViewObj() :
+//UNUSED2008-05 ScViewPaneBase( NULL, SC_VIEWPANE_ACTIVE ),
+//UNUSED2008-05 SfxBaseController( NULL ),
+//UNUSED2008-05 aPropSet( lcl_GetViewOptPropertyMap() ),
+//UNUSED2008-05 aMouseClickHandlers( 0 ),
+//UNUSED2008-05 aActivationListeners( 0 ),
+//UNUSED2008-05 bDrawSelModeSet(sal_False),
+//UNUSED2008-05 bFilteredRangeSelection(sal_True)
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) :
+ ScViewPaneBase( pViewSh, SC_VIEWPANE_ACTIVE ),
+ SfxBaseController( pViewSh ),
+ aPropSet( lcl_GetViewOptPropertyMap() ),
+ aMouseClickHandlers( 0 ),
+ aActivationListeners( 0 ),
+ nPreviousTab( 0 ),
+ bDrawSelModeSet(sal_False)
+{
+ if (pViewSh)
+ nPreviousTab = pViewSh->GetViewData()->GetTabNo();
+}
+
+ScTabViewObj::~ScTabViewObj()
+{
+ //! Listening oder so
+ if (aMouseClickHandlers.Count())
+ {
+ acquire();
+ EndMouseListening();
+ }
+ if (aActivationListeners.Count())
+ {
+ acquire();
+ EndActivationListening();
+ }
+}
+
+uno::Any SAL_CALL ScTabViewObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ SC_QUERYINTERFACE( sheet::XSpreadsheetView )
+ SC_QUERYINTERFACE( sheet::XEnhancedMouseClickBroadcaster )
+ SC_QUERYINTERFACE( sheet::XActivationBroadcaster )
+ SC_QUERYINTERFACE( container::XEnumerationAccess )
+ SC_QUERYINTERFACE( container::XIndexAccess )
+ SC_QUERY_MULTIPLE( container::XElementAccess, container::XIndexAccess )
+ SC_QUERYINTERFACE( view::XSelectionSupplier )
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( sheet::XViewSplitable )
+ SC_QUERYINTERFACE( sheet::XViewFreezable )
+ SC_QUERYINTERFACE( sheet::XRangeSelection )
+ SC_QUERYINTERFACE( lang::XUnoTunnel )
+ SC_QUERYINTERFACE( datatransfer::XTransferableSupplier )
+
+ uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
+ if (!aRet.hasValue())
+ aRet = SfxBaseController::queryInterface( rType );
+ return aRet;
+}
+
+void SAL_CALL ScTabViewObj::acquire() throw()
+{
+ SfxBaseController::acquire();
+}
+
+void SAL_CALL ScTabViewObj::release() throw()
+{
+ SfxBaseController::release();
+}
+
+void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, sal_Int32 nEvent )
+{
+ ScDocument* pDoc = pDocSh->GetDocument();
+ // when deleting a sheet, nPreviousTab can be invalid
+ // (could be handled with reference updates)
+ if (!pDoc->HasTable(nTab))
+ return;
+
+ const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const rtl::OUString* pScript = pEvents->GetScript(nEvent);
+ if (pScript)
+ {
+ uno::Any aRet;
+ uno::Sequence<uno::Any> aParams;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+ /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+ }
+ }
+
+ // execute VBA event handlers
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ // the parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= nTab;
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+void ScTabViewObj::SheetChanged()
+{
+ if ( !GetViewShell() )
+ return;
+
+ ScViewData* pViewData = GetViewShell()->GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ if (aActivationListeners.Count() > 0)
+ {
+ sheet::ActivationEvent aEvent;
+ uno::Reference< sheet::XSpreadsheetView > xView(this);
+ uno::Reference< uno::XInterface > xSource(xView, uno::UNO_QUERY);
+ aEvent.Source = xSource;
+ aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, pViewData->GetTabNo());
+ for ( USHORT n=0; n<aActivationListeners.Count(); n++ )
+ {
+ try
+ {
+ (*aActivationListeners[n])->activeSpreadsheetChanged( aEvent );
+ }
+ catch( uno::Exception& )
+ {
+ aActivationListeners.DeleteAndDestroy( n );
+ --n; // because it will be increased again in the loop
+ }
+ }
+ }
+
+ // handle sheet events
+ SCTAB nNewTab = pViewData->GetTabNo();
+ if ( nNewTab != nPreviousTab )
+ {
+ lcl_CallActivate( pDocSh, nPreviousTab, SC_SHEETEVENT_UNFOCUS );
+ lcl_CallActivate( pDocSh, nNewTab, SC_SHEETEVENT_FOCUS );
+ }
+ nPreviousTab = nNewTab;
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes() throw(uno::RuntimeException)
+{
+ static uno::Sequence<uno::Type> aTypes;
+ if ( aTypes.getLength() == 0 )
+ {
+ uno::Sequence<uno::Type> aViewPaneTypes(ScViewPaneBase::getTypes());
+ long nViewPaneLen = aViewPaneTypes.getLength();
+ const uno::Type* pViewPanePtr = aViewPaneTypes.getConstArray();
+
+ uno::Sequence<uno::Type> aControllerTypes(SfxBaseController::getTypes());
+ long nControllerLen = aControllerTypes.getLength();
+ const uno::Type* pControllerPtr = aControllerTypes.getConstArray();
+
+ long nParentLen = nViewPaneLen + nControllerLen;
+
+ aTypes.realloc( nParentLen + 12 );
+ uno::Type* pPtr = aTypes.getArray();
+ pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheetView>*)0);
+ pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XEnumerationAccess>*)0);
+ pPtr[nParentLen + 2] = getCppuType((const uno::Reference<container::XIndexAccess>*)0);
+ pPtr[nParentLen + 3] = getCppuType((const uno::Reference<view::XSelectionSupplier>*)0);
+ pPtr[nParentLen + 4] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
+ pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XViewSplitable>*)0);
+ pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XViewFreezable>*)0);
+ pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XRangeSelection>*)0);
+ pPtr[nParentLen + 8] = getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
+ pPtr[nParentLen + 9] = getCppuType((const uno::Reference<sheet::XEnhancedMouseClickBroadcaster>*)0);
+ pPtr[nParentLen + 10] = getCppuType((const uno::Reference<sheet::XActivationBroadcaster>*)0);
+ pPtr[nParentLen + 11] = getCppuType((const uno::Reference<datatransfer::XTransferableSupplier>*)0);
+
+ long i;
+ for (i=0; i<nViewPaneLen; i++)
+ pPtr[i] = pViewPanePtr[i]; // parent types first
+ for (i=0; i<nControllerLen; i++)
+ pPtr[nViewPaneLen+i] = pControllerPtr[i];
+ }
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScTabViewObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XDocumentView
+
+BOOL lcl_TabInRanges( SCTAB nTab, const ScRangeList& rRanges )
+{
+ ULONG nCount = rRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ const ScRange* pRange = rRanges.GetObject(i);
+ if ( nTab >= pRange->aStart.Tab() && nTab <= pRange->aEnd.Tab() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void lcl_ShowObject( ScTabViewShell& rViewSh, ScDrawView& rDrawView, SdrObject* pSelObj )
+{
+ BOOL bFound = FALSE;
+ SCTAB nObjectTab = 0;
+
+ SdrModel* pModel = rDrawView.GetModel();
+ USHORT nPageCount = pModel->GetPageCount();
+ for (USHORT i=0; i<nPageCount && !bFound; i++)
+ {
+ SdrPage* pPage = pModel->GetPage(i);
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if ( pObject == pSelObj )
+ {
+ bFound = TRUE;
+ nObjectTab = static_cast<SCTAB>(i);
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ rViewSh.SetTabNo( nObjectTab );
+ rViewSh.ScrollToObject( pSelObj );
+ }
+}
+
+sal_Bool SAL_CALL ScTabViewObj::select( const uno::Any& aSelection )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+
+ if ( !pViewSh )
+ return FALSE;
+
+ //! Type of aSelection can be some specific interface instead of XInterface
+
+ BOOL bRet = FALSE;
+ uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
+ if ( !xInterface.is() ) //clear all selections
+ {
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ if (pDrawView)
+ {
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+ }
+ else //#102232#; if there is no DrawView remove range selection
+ pViewSh->Unmark();
+ bRet = TRUE;
+ }
+
+ if (bDrawSelModeSet) // remove DrawSelMode if set by API; if necessary it will be set again later
+ {
+ pViewSh->SetDrawSelMode(sal_False);
+ pViewSh->UpdateLayerLocks();
+ bDrawSelModeSet = sal_False;
+ }
+
+ if (bRet)
+ return bRet;
+
+
+ ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xInterface );
+ uno::Reference<drawing::XShapes> xShapeColl( xInterface, uno::UNO_QUERY );
+ uno::Reference<drawing::XShape> xShapeSel( xInterface, uno::UNO_QUERY );
+ SvxShape* pShapeImp = SvxShape::getImplementation( xShapeSel );
+
+ if (pRangesImp) // Zell-Ranges
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ if ( pViewData->GetDocShell() == pRangesImp->GetDocShell() )
+ {
+ // Zuerst evtl. Drawing-Selektion aufheben
+ // (MarkListHasChanged hebt Tabellen-Selektion auf)
+
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ if (pDrawView)
+ {
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+ }
+ FuPoor* pFunc = pViewSh->GetDrawFuncPtr();
+ if ( pFunc && pFunc->GetSlotID() != SID_OBJECT_SELECT )
+ {
+ // Slot der Zeichenfunktion nochmal ausfuehren -> abschalten
+ SfxDispatcher* pDisp = pViewSh->GetDispatcher();
+ if (pDisp)
+ pDisp->Execute( pFunc->GetSlotID(), SFX_CALLMODE_SYNCHRON );
+ }
+ pViewSh->SetDrawShell(FALSE);
+ pViewSh->SetDrawSelMode(FALSE); // nach dem Dispatcher-Execute
+
+ // Ranges selektieren
+
+ const ScRangeList& rRanges = pRangesImp->GetRangeList();
+ ULONG nRangeCount = rRanges.Count();
+ // for empty range list, remove selection (cursor remains where it was)
+ if ( nRangeCount == 0 )
+ pViewSh->Unmark();
+ else if ( nRangeCount == 1 )
+ pViewSh->MarkRange( *rRanges.GetObject(0) );
+ else
+ {
+ // Mehrfachselektion
+
+ const ScRange* pFirst = rRanges.GetObject(0);
+ if ( pFirst && !lcl_TabInRanges( pViewData->GetTabNo(), rRanges ) )
+ pViewSh->SetTabNo( pFirst->aStart.Tab() );
+ pViewSh->DoneBlockMode();
+ pViewSh->InitOwnBlockMode();
+ pViewData->GetMarkData().MarkFromRangeList( rRanges, TRUE );
+ pViewSh->MarkDataChanged();
+ pViewData->GetDocShell()->PostPaintGridAll(); // Markierung (alt&neu)
+ if ( pFirst )
+ {
+ pViewSh->AlignToCursor( pFirst->aStart.Col(), pFirst->aStart.Row(),
+ SC_FOLLOW_JUMP );
+ pViewSh->SetCursor( pFirst->aStart.Col(), pFirst->aStart.Row() );
+ }
+
+ //! Methode an der View, um RangeList zu selektieren
+ }
+ bRet = TRUE;
+ }
+ }
+ else if ( pShapeImp || xShapeColl.is() ) // Drawing-Layer
+ {
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ if (pDrawView)
+ {
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+
+ if (pShapeImp) // einzelnes Shape
+ {
+ SdrObject *pObj = pShapeImp->GetSdrObject();
+ if (pObj)
+ {
+ lcl_ShowObject( *pViewSh, *pDrawView, pObj );
+ SdrPageView* pPV = pDrawView->GetSdrPageView();
+ if ( pPV && pObj->GetPage() == pPV->GetPage() )
+ {
+ pDrawView->MarkObj( pObj, pPV );
+ bRet = TRUE;
+ }
+ }
+ }
+ else // Shape-Collection (xShapeColl ist nicht 0)
+ {
+ // Es wird auf die Tabelle des ersten Objekts umgeschaltet,
+ // und alle Objekte selektiert, die auf dieser Tabelle liegen
+ //! Exception, wenn Objekte auf verschiedenen Tabellen?
+
+ SdrPageView* pPV = NULL;
+ long nCount = xShapeColl->getCount();
+ if (nCount)
+ {
+ sal_Bool bAllMarked(sal_True);
+ for ( long i = 0; i < nCount; i++ )
+ {
+ uno::Reference<drawing::XShape> xShapeInt(xShapeColl->getByIndex(i), uno::UNO_QUERY);
+ if (xShapeInt.is())
+ {
+ SvxShape* pShape = SvxShape::getImplementation( xShapeInt );
+ if (pShape)
+ {
+ SdrObject *pObj = pShape->GetSdrObject();
+ if (pObj)
+ {
+ if (!bDrawSelModeSet && (pObj->GetLayer() == SC_LAYER_BACK))
+ {
+ pViewSh->SetDrawSelMode(sal_True);
+ pViewSh->UpdateLayerLocks();
+ bDrawSelModeSet = sal_True;
+ }
+ if (!pPV) // erstes Objekt
+ {
+ lcl_ShowObject( *pViewSh, *pDrawView, pObj );
+ pPV = pDrawView->GetSdrPageView();
+ }
+ if ( pPV && pObj->GetPage() == pPV->GetPage() )
+ {
+ if (pDrawView->IsObjMarkable( pObj, pPV ))
+ pDrawView->MarkObj( pObj, pPV );
+ else
+ bAllMarked = sal_False;
+ }
+ }
+ }
+ }
+ }
+ if (bAllMarked)
+ bRet = TRUE;
+ }
+ else
+ bRet = TRUE; // empty XShapes (all shapes are deselected)
+ }
+
+ if (bRet)
+ pViewSh->SetDrawShell(TRUE);
+ }
+ }
+
+ if (!bRet)
+ throw lang::IllegalArgumentException();
+
+ return bRet;
+}
+
+uno::Any SAL_CALL ScTabViewObj::getSelection() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ ScCellRangesBase* pObj = NULL;
+ if (pViewSh)
+ {
+ // Ist auf dem Drawing-Layer etwas selektiert?
+
+ SdrView* pDrawView = pViewSh->GetSdrView();
+ if (pDrawView)
+ {
+ const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+ if (nMarkCount)
+ {
+ // ShapeCollection erzeugen (wie in SdXImpressView::getSelection im Draw)
+ // Zurueckgegeben wird XInterfaceRef, das muss das UsrObject-XInterface sein
+
+ SvxShapeCollection* pShapes = new SvxShapeCollection();
+ uno::Reference<uno::XInterface> xRet(static_cast<cppu::OWeakObject*>(pShapes));
+
+ for (ULONG i=0; i<nMarkCount; i++)
+ {
+ SdrObject* pDrawObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ if (pDrawObj)
+ {
+ uno::Reference<drawing::XShape> xShape( pDrawObj->getUnoShape(), uno::UNO_QUERY );
+ if (xShape.is())
+ pShapes->add(xShape);
+ }
+ }
+ return uno::makeAny(xRet);
+ }
+ }
+
+ // sonst Tabellen-(Zellen-)Selektion
+
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ const ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabs = rMark.GetSelectCount();
+
+ ScRange aRange;
+ ScMarkType eMarkType = pViewData->GetSimpleArea(aRange);
+ if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE) )
+ {
+ if (aRange.aStart == aRange.aEnd)
+ pObj = new ScCellObj( pDocSh, aRange.aStart );
+ else
+ pObj = new ScCellRangeObj( pDocSh, aRange );
+ }
+ else if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE_FILTERED) )
+ {
+ ScMarkData aFilteredMark( rMark );
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDocSh->GetDocument());
+ ScRangeList aRangeList;
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, FALSE);
+ // Theoretically a selection may start and end on a filtered row.
+ switch (aRangeList.Count())
+ {
+ case 0:
+ // No unfiltered row, we have to return some object, so
+ // here is one with no ranges.
+ pObj = new ScCellRangesObj( pDocSh, aRangeList );
+ break;
+ case 1:
+ {
+ const ScRange& rRange = *(aRangeList.GetObject(0));
+ if (rRange.aStart == rRange.aEnd)
+ pObj = new ScCellObj( pDocSh, rRange.aStart );
+ else
+ pObj = new ScCellRangeObj( pDocSh, rRange );
+ }
+ break;
+ default:
+ pObj = new ScCellRangesObj( pDocSh, aRangeList );
+ }
+ }
+ else // Mehrfachselektion
+ {
+ ScRangeListRef xRanges;
+ pViewData->GetMultiArea( xRanges );
+
+ // bei mehreren Tabellen Ranges kopieren
+ //! sollte eigentlich schon in ScMarkData::FillRangeListWithMarks passieren?
+ if ( nTabs > 1 )
+ rMark.ExtendRangeListTables( xRanges );
+
+ pObj = new ScCellRangesObj( pDocSh, *xRanges );
+ }
+
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // remember if the selection was from the cursor position without anything selected
+ // (used when rendering the selection)
+
+ pObj->SetCursorOnly( TRUE );
+ }
+ }
+
+ return uno::makeAny(uno::Reference<uno::XInterface>(static_cast<cppu::OWeakObject*>(pObj)));
+}
+
+
+#if 0
+// XPrintable
+
+rtl::OUString ScTabViewObj::getPrinterName(void) const
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ SfxPrinter* pPrinter = pViewSh->GetPrinter(TRUE);
+ if (pPrinter)
+ return pPrinter->GetName();
+ }
+
+ DBG_ERROR("getPrinterName: keine View oder kein Printer");
+ return rtl::OUString();
+}
+
+void ScTabViewObj::setPrinterName(const rtl::OUString& PrinterName)
+{
+ ScUnoGuard aGuard;
+ // Drucker setzen - wie in SfxViewShell::ExecPrint_Impl
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ SfxPrinter* pPrinter = pViewSh->GetPrinter(TRUE);
+ if (pPrinter)
+ {
+ String aString(PrinterName);
+ SfxPrinter* pNewPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aString );
+ if (pNewPrinter->IsKnown())
+ pViewSh->SetPrinter( pNewPrinter, SFX_PRINTER_PRINTER );
+ else
+ delete pNewPrinter;
+ }
+ }
+}
+
+XPropertySetRef ScTabViewObj::createPrintOptions(void)
+{
+ ScUnoGuard aGuard;
+ return new ScPrintSettingsObj; //! ScPrintSettingsObj implementieren!
+}
+
+void ScTabViewObj::print(const XPropertySetRef& xOptions)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ //! xOptions auswerten (wie denn?)
+
+ SfxRequest aReq( SID_PRINTDOCDIRECT, SFX_CALLMODE_SYNCHRON, pViewSh->GetPool() );
+ pViewSh->ExecuteSlot( aReq );
+ }
+}
+#endif
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScTabViewObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetViewPanesEnumeration")));
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScTabViewObj::getCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ USHORT nPanes = 0;
+ if (pViewSh)
+ {
+ nPanes = 1;
+ ScViewData* pViewData = pViewSh->GetViewData();
+ if ( pViewData->GetHSplitMode() != SC_SPLIT_NONE )
+ nPanes *= 2;
+ if ( pViewData->GetVSplitMode() != SC_SPLIT_NONE )
+ nPanes *= 2;
+ }
+ return nPanes;
+}
+
+uno::Any SAL_CALL ScTabViewObj::getByIndex( sal_Int32 nIndex )
+ throw(lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XViewPane> xPane(GetObjectByIndex_Impl((USHORT)nIndex));
+ if (xPane.is())
+ return uno::makeAny(xPane);
+ else
+ throw lang::IndexOutOfBoundsException();
+// return uno::Any();
+}
+
+uno::Type SAL_CALL ScTabViewObj::getElementType() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return getCppuType((uno::Reference<sheet::XViewPane>*)0);
+}
+
+sal_Bool SAL_CALL ScTabViewObj::hasElements() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XSpreadsheetView
+
+ScViewPaneObj* ScTabViewObj::GetObjectByIndex_Impl(USHORT nIndex) const
+{
+ static ScSplitPos ePosHV[4] =
+ { SC_SPLIT_TOPLEFT, SC_SPLIT_BOTTOMLEFT, SC_SPLIT_TOPRIGHT, SC_SPLIT_BOTTOMRIGHT };
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScSplitPos eWhich = SC_SPLIT_BOTTOMLEFT; // default Position
+ BOOL bError = FALSE;
+ ScViewData* pViewData = pViewSh->GetViewData();
+ BOOL bHor = ( pViewData->GetHSplitMode() != SC_SPLIT_NONE );
+ BOOL bVer = ( pViewData->GetVSplitMode() != SC_SPLIT_NONE );
+ if ( bHor && bVer )
+ {
+ // links oben, links unten, rechts oben, rechts unten - wie in Excel
+ if ( nIndex < 4 )
+ eWhich = ePosHV[nIndex];
+ else
+ bError = TRUE;
+ }
+ else if ( bHor )
+ {
+ if ( nIndex > 1 )
+ bError = TRUE;
+ else if ( nIndex == 1 )
+ eWhich = SC_SPLIT_BOTTOMRIGHT;
+ // sonst SC_SPLIT_BOTTOMLEFT
+ }
+ else if ( bVer )
+ {
+ if ( nIndex > 1 )
+ bError = TRUE;
+ else if ( nIndex == 0 )
+ eWhich = SC_SPLIT_TOPLEFT;
+ // sonst SC_SPLIT_BOTTOMLEFT
+ }
+ else if ( nIndex > 0 )
+ bError = TRUE; // nicht geteilt: nur 0 gueltig
+
+ if (!bError)
+ return new ScViewPaneObj( pViewSh, sal::static_int_cast<USHORT>(eWhich) );
+ }
+
+ return NULL;
+}
+
+uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTabViewObj::getActiveSheet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pData = pViewSh->GetViewData();
+ SCTAB nTab = pData->GetTabNo();
+ return new ScTableSheetObj( pData->GetDocShell(), nTab );
+ }
+ return NULL;
+}
+
+void SAL_CALL ScTabViewObj::setActiveSheet( const uno::Reference<sheet::XSpreadsheet>& xActiveSheet )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if ( pViewSh && xActiveSheet.is() )
+ {
+ // XSpreadsheet und ScCellRangesBase -> muss ein Sheet sein
+
+ ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xActiveSheet );
+ if ( pRangesImp && pViewSh->GetViewData()->GetDocShell() == pRangesImp->GetDocShell() )
+ {
+ const ScRangeList& rRanges = pRangesImp->GetRangeList();
+ if ( rRanges.Count() == 1 )
+ {
+ SCTAB nNewTab = rRanges.GetObject(0)->aStart.Tab();
+ if ( pViewSh->GetViewData()->GetDocument()->HasTable(nNewTab) )
+ pViewSh->SetTabNo( nNewTab );
+ }
+ }
+ }
+}
+
+uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rPoint) const
+{
+ uno::Reference< uno::XInterface > xTarget;
+ if (GetViewShell())
+ {
+ SCsCOL nX;
+ SCsROW nY;
+ ScViewData* pData = GetViewShell()->GetViewData();
+ ScSplitPos eSplitMode = pData->GetActivePart();
+ SCTAB nTab(pData->GetTabNo());
+ pData->GetPosFromPixel( rPoint.X(), rPoint.Y(), eSplitMode, nX, nY);
+
+ ScAddress aCellPos (nX, nY, nTab);
+ ScCellObj* pCellObj = new ScCellObj(pData->GetDocShell(), aCellPos);
+
+ xTarget.set(uno::Reference<table::XCell>(pCellObj), uno::UNO_QUERY);
+
+ ScDocument* pDoc = pData->GetDocument();
+ if (pDoc && pDoc->GetDrawLayer())
+ {
+ SdrPage* pDrawPage = NULL;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
+ pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+
+ SdrView* pDrawView = GetViewShell()->GetSdrView();
+
+ if (pDrawPage && pDrawView && pDrawView->GetSdrPageView())
+ {
+ Window* pActiveWin = pData->GetActiveWin();
+ Point aPos = pActiveWin->PixelToLogic(rPoint);
+
+ USHORT nHitLog = (USHORT) pActiveWin->PixelToLogic(
+ Size(pDrawView->GetHitTolerancePixel(),0)).Width();
+
+ sal_uInt32 nCount(pDrawPage->GetObjCount());
+ sal_Bool bFound(sal_False);
+ sal_uInt32 i(0);
+ while (i < nCount && !bFound)
+ {
+ SdrObject* pObj = pDrawPage->GetObj(i);
+ if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, nHitLog, *pDrawView->GetSdrPageView(), 0, false))
+ {
+ xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY);
+ bFound = sal_True;
+ }
+ ++i;
+ }
+ }
+ }
+ }
+ return xTarget;
+}
+
+bool ScTabViewObj::IsMouseListening() const
+{
+ if ( aMouseClickHandlers.Count() > 0 )
+ return true;
+
+ // also include sheet events, because MousePressed must be called for them
+ ScViewData* pViewData = GetViewShell()->GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ return
+ pDoc->HasSheetEventScript( nTab, SC_SHEETEVENT_RIGHTCLICK, true ) ||
+ pDoc->HasSheetEventScript( nTab, SC_SHEETEVENT_DOUBLECLICK, true );
+}
+
+sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e )
+ throw (::uno::RuntimeException)
+{
+ sal_Bool bReturn(sal_False);
+
+ uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
+ if (aMouseClickHandlers.Count() && xTarget.is())
+ {
+ awt::EnhancedMouseEvent aMouseEvent;
+
+ aMouseEvent.Buttons = e.Buttons;
+ aMouseEvent.X = e.X;
+ aMouseEvent.Y = e.Y;
+ aMouseEvent.ClickCount = e.ClickCount;
+ aMouseEvent.PopupTrigger = e.PopupTrigger;
+ aMouseEvent.Target = xTarget;
+
+ for ( USHORT n=0; n<aMouseClickHandlers.Count(); n++ )
+ {
+ try
+ {
+ if (!(*aMouseClickHandlers[n])->mousePressed( aMouseEvent ))
+ bReturn = sal_True;
+ }
+ catch ( uno::Exception& )
+ {
+ aMouseClickHandlers.DeleteAndDestroy(n);
+ --n; // because it will be increased again in the loop
+ }
+ }
+ }
+
+ // handle sheet events
+ bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 );
+ bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 );
+ if ( ( bDoubleClick || bRightClick ) && !bReturn && xTarget.is())
+ {
+ sal_Int32 nEvent = bDoubleClick ? SC_SHEETEVENT_DOUBLECLICK : SC_SHEETEVENT_RIGHTCLICK;
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const rtl::OUString* pScript = pEvents->GetScript(nEvent);
+ if (pScript)
+ {
+ // the macro parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence<uno::Any> aParams(1);
+ aParams[0] <<= xTarget;
+
+ uno::Any aRet;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+
+ /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+
+ // look for a boolean return value of true
+ sal_Bool bRetValue = sal_False;
+ if (aRet >>= bRetValue)
+ {
+ if (bRetValue)
+ bReturn = sal_True;
+ }
+ }
+ }
+
+ // execute VBA event handler
+ if (!bReturn && xTarget.is()) try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ // the parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= xTarget;
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
+ }
+ catch( util::VetoException& )
+ {
+ bReturn = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+
+ return bReturn;
+}
+
+sal_Bool ScTabViewObj::MouseReleased( const awt::MouseEvent& e )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bReturn(sal_False);
+
+ if (aMouseClickHandlers.Count())
+ {
+ uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
+
+ if (xTarget.is())
+ {
+ awt::EnhancedMouseEvent aMouseEvent;
+
+ aMouseEvent.Buttons = e.Buttons;
+ aMouseEvent.X = e.X;
+ aMouseEvent.Y = e.Y;
+ aMouseEvent.ClickCount = e.ClickCount;
+ aMouseEvent.PopupTrigger = e.PopupTrigger;
+ aMouseEvent.Target = xTarget;
+
+ for ( USHORT n=0; n<aMouseClickHandlers.Count(); n++ )
+ {
+ try
+ {
+ if (!(*aMouseClickHandlers[n])->mouseReleased( aMouseEvent ))
+ bReturn = sal_True;
+ }
+ catch ( uno::Exception& )
+ {
+ aMouseClickHandlers.DeleteAndDestroy(n);
+ --n; // because it will be increased again in the loop
+ }
+ }
+ }
+ }
+ return bReturn;
+}
+
+// XEnhancedMouseClickBroadcaster
+
+void ScTabViewObj::StartMouseListening()
+{
+}
+
+void ScTabViewObj::EndMouseListening()
+{
+ USHORT nCount(aMouseClickHandlers.Count());
+ lang::EventObject aEvent;
+ aEvent.Source = (cppu::OWeakObject*)this;
+ for ( USHORT n=0; n<nCount; n++ )
+ {
+ try
+ {
+ (*aMouseClickHandlers[n])->disposing(aEvent);
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ aMouseClickHandlers.DeleteAndDestroy(0, nCount);
+}
+
+void ScTabViewObj::StartActivationListening()
+{
+}
+
+void ScTabViewObj::EndActivationListening()
+{
+ USHORT nCount = aActivationListeners.Count();
+ lang::EventObject aEvent;
+ aEvent.Source = (cppu::OWeakObject*)this;
+ for ( USHORT n=0; n<nCount; n++ )
+ {
+ try
+ {
+ (*aActivationListeners[n])->disposing(aEvent);
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ aActivationListeners.DeleteAndDestroy(0, nCount);
+}
+
+void SAL_CALL ScTabViewObj::addEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if (aListener.is())
+ {
+ USHORT nCount = aMouseClickHandlers.Count();
+ uno::Reference<awt::XEnhancedMouseClickHandler> *pObj =
+ new uno::Reference<awt::XEnhancedMouseClickHandler>( aListener );
+ aMouseClickHandlers.Insert( pObj, nCount );
+
+ if (aMouseClickHandlers.Count() == 1 && nCount == 0) // only if a listener added
+ StartMouseListening();
+ }
+}
+
+void SAL_CALL ScTabViewObj::removeEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aMouseClickHandlers.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<awt::XEnhancedMouseClickHandler> *pObj = aMouseClickHandlers[n];
+ if ( *pObj == aListener )
+ aMouseClickHandlers.DeleteAndDestroy( n );
+ }
+ if ((aMouseClickHandlers.Count() == 0) && (nCount > 0)) // only if last listener removed
+ EndMouseListening();
+}
+
+// XActivationBroadcaster
+
+void SAL_CALL ScTabViewObj::addActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if (aListener.is())
+ {
+ USHORT nCount = aActivationListeners.Count();
+ uno::Reference<sheet::XActivationEventListener> *pObj =
+ new uno::Reference<sheet::XActivationEventListener>( aListener );
+ aActivationListeners.Insert( pObj, nCount );
+
+ if (aActivationListeners.Count() == 1 && nCount == 0) // only if a listener added
+ StartActivationListening();
+ }
+}
+
+void SAL_CALL ScTabViewObj::removeActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aActivationListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<sheet::XActivationEventListener> *pObj = aActivationListeners[n];
+ if ( *pObj == aListener )
+ aActivationListeners.DeleteAndDestroy( n );
+ }
+ if ((aActivationListeners.Count() == 0) && (nCount > 0)) // only if last listener removed
+ EndActivationListening();
+}
+
+// PageBreakMode / Zoom sind Properties
+
+#if 0
+
+BOOL ScTabViewObj::getPagebreakMode(void) const
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ return pViewSh->GetViewData()->IsPagebreakMode();
+ return FALSE;
+}
+
+void ScTabViewObj::setPagebreakMode(BOOL PagebreakMode)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ pViewSh->SetPagebreakMode(PagebreakMode);
+}
+
+#endif
+
+INT16 ScTabViewObj::GetZoom(void) const
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ const Fraction& rZoomY = pViewSh->GetViewData()->GetZoomY(); // Y wird angezeigt
+ return (INT16)(( rZoomY.GetNumerator() * 100 ) / rZoomY.GetDenominator());
+ }
+ return 0;
+}
+
+void ScTabViewObj::SetZoom(INT16 nZoom)
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ if ( nZoom != GetZoom() && nZoom != 0 )
+ {
+ if (!pViewSh->GetViewData()->IsPagebreakMode())
+ {
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aNewOpt(pScMod->GetAppOptions());
+ aNewOpt.SetZoom( nZoom );
+ aNewOpt.SetZoomType( pViewSh->GetViewData()->GetView()->GetZoomType() );
+ pScMod->SetAppOptions( aNewOpt );
+ }
+ }
+ Fraction aFract( nZoom, 100 );
+ pViewSh->SetZoom( aFract, aFract, TRUE );
+ pViewSh->PaintGrid();
+ pViewSh->PaintTop();
+ pViewSh->PaintLeft();
+ pViewSh->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
+ pViewSh->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
+ }
+}
+
+INT16 ScTabViewObj::GetZoomType(void) const
+{
+ INT16 aZoomType = view::DocumentZoomType::OPTIMAL;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ SvxZoomType eZoomType = pViewSh->GetViewData()->GetView()->GetZoomType();
+ switch (eZoomType)
+ {
+ case SVX_ZOOM_PERCENT:
+ aZoomType = view::DocumentZoomType::BY_VALUE;
+ break;
+ case SVX_ZOOM_OPTIMAL:
+ aZoomType = view::DocumentZoomType::OPTIMAL;
+ break;
+ case SVX_ZOOM_WHOLEPAGE:
+ aZoomType = view::DocumentZoomType::ENTIRE_PAGE;
+ break;
+ case SVX_ZOOM_PAGEWIDTH:
+ aZoomType = view::DocumentZoomType::PAGE_WIDTH;
+ break;
+ case SVX_ZOOM_PAGEWIDTH_NOBORDER:
+ aZoomType = view::DocumentZoomType::PAGE_WIDTH_EXACT;
+ break;
+ }
+ }
+ return aZoomType;
+}
+
+void ScTabViewObj::SetZoomType(INT16 aZoomType)
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScDBFunc* pView = pViewSh->GetViewData()->GetView();
+ if (pView)
+ {
+ SvxZoomType eZoomType;
+ switch (aZoomType)
+ {
+ case view::DocumentZoomType::BY_VALUE:
+ eZoomType = SVX_ZOOM_PERCENT;
+ break;
+ case view::DocumentZoomType::OPTIMAL:
+ eZoomType = SVX_ZOOM_OPTIMAL;
+ break;
+ case view::DocumentZoomType::ENTIRE_PAGE:
+ eZoomType = SVX_ZOOM_WHOLEPAGE;
+ break;
+ case view::DocumentZoomType::PAGE_WIDTH:
+ eZoomType = SVX_ZOOM_PAGEWIDTH;
+ break;
+ case view::DocumentZoomType::PAGE_WIDTH_EXACT:
+ eZoomType = SVX_ZOOM_PAGEWIDTH_NOBORDER;
+ break;
+ default:
+ eZoomType = SVX_ZOOM_OPTIMAL;
+ }
+ sal_Int16 nZoom(GetZoom());
+ sal_Int16 nOldZoom(nZoom);
+ if ( eZoomType == SVX_ZOOM_PERCENT )
+ {
+ if ( nZoom < MINZOOM ) nZoom = MINZOOM;
+ if ( nZoom > MAXZOOM ) nZoom = MAXZOOM;
+ }
+ else
+ nZoom = pView->CalcZoom( eZoomType, nOldZoom );
+
+ switch ( eZoomType )
+ {
+ case SVX_ZOOM_WHOLEPAGE:
+ case SVX_ZOOM_PAGEWIDTH:
+ pView->SetZoomType( eZoomType, TRUE );
+ break;
+
+ default:
+ pView->SetZoomType( SVX_ZOOM_PERCENT, TRUE );
+ }
+ SetZoom( nZoom );
+ }
+ }
+}
+
+sal_Bool SAL_CALL ScTabViewObj::getIsWindowSplit() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // wie Menue-Slot SID_WINDOW_SPLIT
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ return ( pViewData->GetHSplitMode() == SC_SPLIT_NORMAL ||
+ pViewData->GetVSplitMode() == SC_SPLIT_NORMAL );
+ }
+
+ return FALSE;
+}
+
+sal_Bool SAL_CALL ScTabViewObj::hasFrozenPanes() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // wie Menue-Slot SID_WINDOW_FIX
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ return ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+ pViewData->GetVSplitMode() == SC_SPLIT_FIX );
+ }
+
+ return FALSE;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitHorizontal() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ if ( pViewData->GetHSplitMode() != SC_SPLIT_NONE )
+ return pViewData->GetHSplitPos();
+ }
+ return 0;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitVertical() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ if ( pViewData->GetVSplitMode() != SC_SPLIT_NONE )
+ return pViewData->GetVSplitPos();
+ }
+ return 0;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitColumn() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ if ( pViewData->GetHSplitMode() != SC_SPLIT_NONE )
+ {
+ long nSplit = pViewData->GetHSplitPos();
+
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( pViewData->GetVSplitMode() != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+
+ SCsCOL nCol;
+ SCsROW nRow;
+ pViewData->GetPosFromPixel( nSplit, 0, ePos, nCol, nRow, FALSE );
+ if ( nCol > 0 )
+ return nCol;
+ }
+ }
+ return 0;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitRow() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ if ( pViewData->GetVSplitMode() != SC_SPLIT_NONE )
+ {
+ long nSplit = pViewData->GetVSplitPos();
+
+ ScSplitPos ePos = SC_SPLIT_TOPLEFT; // es ist vertikal geteilt
+ SCsCOL nCol;
+ SCsROW nRow;
+ pViewData->GetPosFromPixel( 0, nSplit, ePos, nCol, nRow, FALSE );
+ if ( nRow > 0 )
+ return nRow;
+ }
+ }
+ return 0;
+}
+
+void SAL_CALL ScTabViewObj::splitAtPosition( sal_Int32 nPixelX, sal_Int32 nPixelY )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ pViewSh->SplitAtPixel( Point( nPixelX, nPixelY ), TRUE, TRUE );
+ pViewSh->FreezeSplitters( FALSE );
+ pViewSh->InvalidateSplit();
+ }
+}
+
+void SAL_CALL ScTabViewObj::freezeAtPosition( sal_Int32 nColumns, sal_Int32 nRows )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ // erst alles aufheben -> kein Stress mit Scrolling zwischendurch o.ae.
+
+ pViewSh->RemoveSplit();
+
+ Point aWinStart;
+ Window* pWin = pViewSh->GetWindowByPos( SC_SPLIT_BOTTOMLEFT );
+ if (pWin)
+ aWinStart = pWin->GetPosPixel();
+
+ ScViewData* pViewData = pViewSh->GetViewData();
+ Point aSplit(pViewData->GetScrPos( (SCCOL)nColumns, (SCROW)nRows, SC_SPLIT_BOTTOMLEFT, TRUE ));
+ aSplit += aWinStart;
+
+ pViewSh->SplitAtPixel( aSplit, TRUE, TRUE );
+ pViewSh->FreezeSplitters( TRUE );
+ pViewSh->InvalidateSplit();
+ }
+}
+
+void SAL_CALL ScTabViewObj::addSelectionChangeListener(
+ const uno::Reference<view::XSelectionChangeListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<view::XSelectionChangeListener>* pObj =
+ new uno::Reference<view::XSelectionChangeListener>( xListener );
+ aSelectionListeners.Insert( pObj, aSelectionListeners.Count() );
+}
+
+void SAL_CALL ScTabViewObj::removeSelectionChangeListener(
+ const uno::Reference< view::XSelectionChangeListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aSelectionListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<view::XSelectionChangeListener> *pObj = aSelectionListeners[n];
+ if ( *pObj == xListener ) //! wozu der Mumpitz mit queryInterface?
+ {
+ aSelectionListeners.DeleteAndDestroy( n );
+ break;
+ }
+ }
+}
+
+void ScTabViewObj::SelectionChanged()
+{
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for ( USHORT n=0; n<aSelectionListeners.Count(); n++ )
+ (*aSelectionListeners[n])->selectionChanged( aEvent );
+
+ // handle sheet events
+ ScTabViewShell* pViewSh = GetViewShell();
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_SELECT);
+ if (pScript)
+ {
+ // the macro parameter is the selection as returned by getSelection
+ uno::Sequence<uno::Any> aParams(1);
+ aParams[0] = getSelection();
+ uno::Any aRet;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+ /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+ }
+ }
+
+ // execute VBA event handler
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ // the parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= getSelection();
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_SELECT ), aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+
+// XPropertySet (View-Optionen)
+//! auch an der Applikation anbieten?
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTabViewObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScTabViewObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ const ScViewOptions& rOldOpt = pViewSh->GetViewData()->GetOptions();
+ ScViewOptions aNewOpt(rOldOpt);
+
+ if ( aString.EqualsAscii( SC_UNO_COLROWHDR ) || aString.EqualsAscii( OLD_UNO_COLROWHDR ) )
+ aNewOpt.SetOption( VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_HORSCROLL ) || aString.EqualsAscii( OLD_UNO_HORSCROLL ) )
+ aNewOpt.SetOption( VOPT_HSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_OUTLSYMB ) || aString.EqualsAscii( OLD_UNO_OUTLSYMB ) )
+ aNewOpt.SetOption( VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHEETTABS ) || aString.EqualsAscii( OLD_UNO_SHEETTABS ) )
+ aNewOpt.SetOption( VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWANCHOR ) )
+ aNewOpt.SetOption( VOPT_ANCHOR, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWFORM ) )
+ aNewOpt.SetOption( VOPT_FORMULAS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWGRID ) )
+ aNewOpt.SetOption( VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWHELP ) )
+ aNewOpt.SetOption( VOPT_HELPLINES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWNOTES ) )
+ aNewOpt.SetOption( VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWPAGEBR ) )
+ aNewOpt.SetOption( VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWZERO ) )
+ aNewOpt.SetOption( VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWSOLID ) )
+ aNewOpt.SetOption( VOPT_SOLIDHANDLES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_VALUEHIGH ) || aString.EqualsAscii( OLD_UNO_VALUEHIGH ) )
+ aNewOpt.SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_VERTSCROLL ) || aString.EqualsAscii( OLD_UNO_VERTSCROLL ) )
+ aNewOpt.SetOption( VOPT_VSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWOBJ ) )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if((sal_Int16)VOBJ_MODE_HIDE < nIntVal) nIntVal = (sal_Int16)VOBJ_MODE_SHOW;
+
+ aNewOpt.SetObjMode( VOBJ_TYPE_OLE, (ScVObjMode)nIntVal);
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_SHOWCHARTS ) )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if((sal_Int16)VOBJ_MODE_HIDE < nIntVal) nIntVal = (sal_Int16)VOBJ_MODE_SHOW;
+
+ aNewOpt.SetObjMode( VOBJ_TYPE_CHART, (ScVObjMode)nIntVal);
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_SHOWDRAW ) )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if((sal_Int16)VOBJ_MODE_HIDE < nIntVal) nIntVal = (sal_Int16)VOBJ_MODE_SHOW;
+
+ aNewOpt.SetObjMode( VOBJ_TYPE_DRAW, (ScVObjMode)nIntVal);
+ }
+ }
+ else if ( aString.EqualsAscii( SC_UNO_GRIDCOLOR ) )
+ {
+ sal_Int32 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ aNewOpt.SetGridColor( nIntVal, String() );
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ZOOMTYPE ) )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ SetZoomType(nIntVal);
+ }
+ else if ( aString.EqualsAscii( SC_UNO_ZOOMVALUE ) )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ SetZoom(nIntVal);
+ }
+
+ // Optionen werden an der View und am Dokument (fuer neue Views) gesetzt,
+ // damit sie beim Speichern erhalten bleiben.
+ //! An der App (Module) braeuchte man noch eine Extra-Moeglichkeit,
+ //! das einzustellen (fuer neue Dokumente)
+
+ if ( aNewOpt != rOldOpt )
+ {
+ pViewData->SetOptions( aNewOpt );
+ pViewData->GetDocument()->SetViewOptions( aNewOpt );
+ pViewData->GetDocShell()->SetDocumentModified(); //! wirklich?
+
+ pViewSh->UpdateFixPos();
+ pViewSh->PaintGrid();
+ pViewSh->PaintTop();
+ pViewSh->PaintLeft();
+ pViewSh->PaintExtras();
+ pViewSh->InvalidateBorder();
+
+ SfxBindings& rBindings = pViewSh->GetViewFrame()->GetBindings();
+ rBindings.Invalidate( FID_TOGGLEHEADERS ); // -> Checks im Menue
+ rBindings.Invalidate( FID_TOGGLESYNTAX );
+ }
+ }
+}
+
+uno::Any SAL_CALL ScTabViewObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aString(aPropertyName);
+ uno::Any aRet;
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ const ScViewOptions& rOpt = pViewSh->GetViewData()->GetOptions();
+
+ if ( aString.EqualsAscii( SC_UNO_COLROWHDR ) || aString.EqualsAscii( OLD_UNO_COLROWHDR ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_HEADER ) );
+ else if ( aString.EqualsAscii( SC_UNO_HORSCROLL ) || aString.EqualsAscii( OLD_UNO_HORSCROLL ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_HSCROLL ) );
+ else if ( aString.EqualsAscii( SC_UNO_OUTLSYMB ) || aString.EqualsAscii( OLD_UNO_OUTLSYMB ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_OUTLINER ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHEETTABS ) || aString.EqualsAscii( OLD_UNO_SHEETTABS ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_TABCONTROLS ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWANCHOR ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_ANCHOR ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWFORM ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_FORMULAS ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWGRID ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_GRID ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWHELP ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_HELPLINES ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWNOTES ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_NOTES ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWPAGEBR ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_PAGEBREAKS ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWZERO ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_NULLVALS ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWSOLID ) ) ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_SOLIDHANDLES ) );
+ else if ( aString.EqualsAscii( SC_UNO_VALUEHIGH ) || aString.EqualsAscii( OLD_UNO_VALUEHIGH ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_SYNTAX ) );
+ else if ( aString.EqualsAscii( SC_UNO_VERTSCROLL ) || aString.EqualsAscii( OLD_UNO_VERTSCROLL ) )
+ ScUnoHelpFunctions::SetBoolInAny( aRet, rOpt.GetOption( VOPT_VSCROLL ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWOBJ ) ) aRet <<= (sal_Int16)( rOpt.GetObjMode( VOBJ_TYPE_OLE ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWCHARTS ) ) aRet <<= (sal_Int16)( rOpt.GetObjMode( VOBJ_TYPE_CHART ) );
+ else if ( aString.EqualsAscii( SC_UNO_SHOWDRAW ) ) aRet <<= (sal_Int16)( rOpt.GetObjMode( VOBJ_TYPE_DRAW ) );
+ else if ( aString.EqualsAscii( SC_UNO_GRIDCOLOR ) ) aRet <<= (sal_Int32)( rOpt.GetGridColor().GetColor() );
+ else if ( aString.EqualsAscii( SC_UNO_VISAREA ) ) aRet <<= GetVisArea();
+ else if ( aString.EqualsAscii( SC_UNO_ZOOMTYPE ) ) aRet <<= GetZoomType();
+ else if ( aString.EqualsAscii( SC_UNO_ZOOMVALUE ) ) aRet <<= GetZoom();
+ }
+
+ return aRet;
+}
+
+void SAL_CALL ScTabViewObj::addPropertyChangeListener( const ::rtl::OUString& /* aPropertyName */,
+ const uno::Reference<beans::XPropertyChangeListener >& xListener )
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<beans::XPropertyChangeListener>* pObj =
+ new uno::Reference<beans::XPropertyChangeListener>( xListener );
+ aPropertyChgListeners.Insert( pObj, aPropertyChgListeners.Count() );
+}
+
+void SAL_CALL ScTabViewObj::removePropertyChangeListener( const ::rtl::OUString& /* aPropertyName */,
+ const uno::Reference<beans::XPropertyChangeListener >& xListener )
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aPropertyChgListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<beans::XPropertyChangeListener> *pObj = aPropertyChgListeners[n];
+ if ( *pObj == xListener ) //! wozu der Mumpitz mit queryInterface?
+ {
+ aPropertyChgListeners.DeleteAndDestroy( n );
+ break;
+ }
+ }
+}
+
+void SAL_CALL ScTabViewObj::addVetoableChangeListener( const ::rtl::OUString& /* PropertyName */,
+ const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+}
+
+void SAL_CALL ScTabViewObj::removeVetoableChangeListener( const ::rtl::OUString& /* PropertyName */,
+ const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+}
+
+void ScTabViewObj::VisAreaChanged()
+{
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for ( USHORT n=0; n<aPropertyChgListeners.Count(); n++ )
+ (*aPropertyChgListeners[n])->propertyChange( aEvent );
+}
+
+// XRangeSelection
+
+void SAL_CALL ScTabViewObj::startRangeSelection(
+ const uno::Sequence<beans::PropertyValue>& aArguments )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ String aInitVal, aTitle;
+ BOOL bCloseOnButtonUp = FALSE;
+ BOOL bSingleCell = FALSE;
+ BOOL bMultiSelection = FALSE;
+
+ rtl::OUString aStrVal;
+ const beans::PropertyValue* pPropArray = aArguments.getConstArray();
+ long nPropCount = aArguments.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ String aPropName(rProp.Name);
+
+ if (aPropName.EqualsAscii( SC_UNONAME_CLOSEONUP ))
+ bCloseOnButtonUp = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_TITLE ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aTitle = String( aStrVal );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_INITVAL ))
+ {
+ if ( rProp.Value >>= aStrVal )
+ aInitVal = String( aStrVal );
+ }
+ else if (aPropName.EqualsAscii( SC_UNONAME_SINGLECELL ))
+ bSingleCell = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName.EqualsAscii( SC_UNONAME_MULTISEL ))
+ bMultiSelection = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ }
+
+ pViewSh->StartSimpleRefDialog( aTitle, aInitVal, bCloseOnButtonUp, bSingleCell, bMultiSelection );
+ }
+}
+
+void SAL_CALL ScTabViewObj::abortRangeSelection() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ pViewSh->StopSimpleRefDialog();
+}
+
+void SAL_CALL ScTabViewObj::addRangeSelectionListener(
+ const uno::Reference<sheet::XRangeSelectionListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XRangeSelectionListener>* pObj =
+ new uno::Reference<sheet::XRangeSelectionListener>( xListener );
+ aRangeSelListeners.Insert( pObj, aRangeSelListeners.Count() );
+}
+
+void SAL_CALL ScTabViewObj::removeRangeSelectionListener(
+ const uno::Reference<sheet::XRangeSelectionListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aRangeSelListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<sheet::XRangeSelectionListener> *pObj = aRangeSelListeners[n];
+ if ( *pObj == xListener )
+ {
+ aRangeSelListeners.DeleteAndDestroy( n );
+ break;
+ }
+ }
+}
+
+void SAL_CALL ScTabViewObj::addRangeSelectionChangeListener(
+ const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<sheet::XRangeSelectionChangeListener>* pObj =
+ new uno::Reference<sheet::XRangeSelectionChangeListener>( xListener );
+ aRangeChgListeners.Insert( pObj, aRangeChgListeners.Count() );
+}
+
+void SAL_CALL ScTabViewObj::removeRangeSelectionChangeListener(
+ const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ USHORT nCount = aRangeChgListeners.Count();
+ for ( USHORT n=nCount; n--; )
+ {
+ uno::Reference<sheet::XRangeSelectionChangeListener> *pObj = aRangeChgListeners[n];
+ if ( *pObj == xListener )
+ {
+ aRangeChgListeners.DeleteAndDestroy( n );
+ break;
+ }
+ }
+}
+
+void ScTabViewObj::RangeSelDone( const String& rText )
+{
+ sheet::RangeSelectionEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.RangeDescriptor = rtl::OUString( rText );
+
+ for ( USHORT n=0; n<aRangeSelListeners.Count(); n++ )
+ (*aRangeSelListeners[n])->done( aEvent );
+}
+
+void ScTabViewObj::RangeSelAborted( const String& rText )
+{
+ sheet::RangeSelectionEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.RangeDescriptor = rtl::OUString( rText );
+
+ for ( USHORT n=0; n<aRangeSelListeners.Count(); n++ )
+ (*aRangeSelListeners[n])->aborted( aEvent );
+}
+
+void ScTabViewObj::RangeSelChanged( const String& rText )
+{
+ sheet::RangeSelectionEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.RangeDescriptor = rtl::OUString( rText );
+
+ for ( USHORT n=0; n<aRangeChgListeners.Count(); n++ )
+ (*aRangeChgListeners[n])->descriptorChanged( aEvent );
+}
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL ScTabViewObj::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "ScTabViewObj" );
+}
+
+sal_Bool SAL_CALL ScTabViewObj::supportsService( const rtl::OUString& rServiceName )
+ throw(uno::RuntimeException)
+{
+ String aServiceStr( rServiceName );
+ return aServiceStr.EqualsAscii( SCTABVIEWOBJ_SERVICE ) ||
+ aServiceStr.EqualsAscii( SCVIEWSETTINGS_SERVICE );
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScTabViewObj::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence<rtl::OUString> aRet(2);
+ rtl::OUString* pArray = aRet.getArray();
+ pArray[0] = rtl::OUString::createFromAscii( SCTABVIEWOBJ_SERVICE );
+ pArray[1] = rtl::OUString::createFromAscii( SCVIEWSETTINGS_SERVICE );
+ return aRet;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScTabViewObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScTabViewObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScTabViewObj* ScTabViewObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScTabViewObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScTabViewObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > SAL_CALL ScTabViewObj::getTransferable( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScEditShell* pShell = PTR_CAST( ScEditShell, GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pShell)
+ return pShell->GetEditView()->GetTransferable();
+
+ ScDrawTextObjectBar* pTextShell = PTR_CAST( ScDrawTextObjectBar, GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pTextShell)
+ {
+ ScViewData* pViewData = GetViewShell()->GetViewData();
+ ScDrawView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if (pOutView)
+ return pOutView->GetEditView().GetTransferable();
+ }
+
+ ScDrawShell* pDrawShell = PTR_CAST( ScDrawShell, GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pDrawShell)
+ return pDrawShell->GetDrawView()->CopyToTransferable();
+
+ ScTransferObj* pObj = GetViewShell()->CopyToTransferable();
+ uno::Reference<datatransfer::XTransferable> xTransferable( pObj );
+ return xTransferable;
+}
+
+void SAL_CALL ScTabViewObj::insertTransferable( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTrans ) throw (::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScEditShell* pShell = PTR_CAST( ScEditShell, GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pShell)
+ pShell->GetEditView()->InsertText( xTrans, ::rtl::OUString(), FALSE );
+ else
+ {
+ ScDrawTextObjectBar* pTextShell = PTR_CAST( ScDrawTextObjectBar, GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pTextShell)
+ {
+ ScViewData* pViewData = GetViewShell()->GetViewData();
+ ScDrawView* pView = pViewData->GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if ( pOutView )
+ {
+ pOutView->GetEditView().InsertText( xTrans, ::rtl::OUString(), FALSE );
+ return;
+ }
+ }
+
+ GetViewShell()->PasteFromTransferable( xTrans );
+ }
+}
+
+//------------------------------------------------------------------------
+
+
+
+
diff --git a/sc/source/ui/unoobj/warnpassword.cxx b/sc/source/ui/unoobj/warnpassword.cxx
new file mode 100644
index 000000000000..ce81fd2645c4
--- /dev/null
+++ b/sc/source/ui/unoobj/warnpassword.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// ============================================================================
+#include "warnpassword.hxx"
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <svl/itemset.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <ucbhelper/simpleinteractionrequest.hxx>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/ucb/InteractiveAppException.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <svx/svxerr.hxx>
+
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::task::InteractionClassification_QUERY;
+using ::com::sun::star::task::XInteractionHandler;
+using ::com::sun::star::task::XInteractionRequest;
+using ::com::sun::star::ucb::InteractiveAppException;
+
+bool ScWarnPassword::WarningOnPassword( SfxMedium& rMedium )
+{
+ bool bReturn = true;
+ Reference< XInteractionHandler > xHandler( rMedium.GetInteractionHandler());
+ if( xHandler.is() )
+ {
+
+ OUString empty;
+ Any xException( makeAny(InteractiveAppException(empty,
+ Reference <XInterface> (),
+ InteractionClassification_QUERY,
+ ERRCODE_SVX_EXPORT_FILTER_CRYPT)));
+
+ Reference< ucbhelper::SimpleInteractionRequest > xRequest
+ = new ucbhelper::SimpleInteractionRequest(
+ xException,
+ ucbhelper::CONTINUATION_APPROVE
+ | ucbhelper::CONTINUATION_DISAPPROVE );
+
+ xHandler->handle( xRequest.get() );
+
+ const sal_Int32 nResp = xRequest->getResponse();
+
+ switch ( nResp )
+ {
+ case ucbhelper::CONTINUATION_UNKNOWN:
+ break;
+
+ case ucbhelper::CONTINUATION_APPROVE:
+ // Continue
+ break;
+
+ case ucbhelper::CONTINUATION_DISAPPROVE:
+ bReturn = false;
+ break;
+ }
+ }
+ return bReturn;
+}
+
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx
new file mode 100644
index 000000000000..2c39d7154b4b
--- /dev/null
+++ b/sc/source/ui/vba/excelvbahelper.cxx
@@ -0,0 +1,268 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <docuno.hxx>
+#include "excelvbahelper.hxx"
+#include "tabvwsh.hxx"
+#include "transobj.hxx"
+#include "scmod.hxx"
+#include "cellsuno.hxx"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace ooo
+{
+namespace vba
+{
+namespace excel
+{
+
+ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException )
+{
+ ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xRange );
+ if ( !pScCellRangesBase )
+ {
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying doc shell uno range object" ) ), uno::Reference< uno::XInterface >() );
+ }
+ return pScCellRangesBase->GetDocShell();
+}
+
+ScDocument* GetDocumentFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException )
+{
+ ScDocShell* pDocShell = GetDocShellFromRange( xRange );
+ if ( !pDocShell )
+ {
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying document from uno range object" ) ), uno::Reference< uno::XInterface >() );
+ }
+ return pDocShell->GetDocument();
+}
+
+void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs )
+{
+ ScTabViewShell* pViewSh = excel::getBestViewShell( xModel );
+ Fraction aFract( nZoom, 100 );
+ pViewSh->GetViewData()->SetZoom( aFract, aFract, nTabs );
+ pViewSh->RefreshZoom();
+}
+bool isInPrintPreview( SfxViewFrame* pView )
+{
+ sal_uInt16 nViewNo = SID_VIEWSHELL1 - SID_VIEWSHELL0;
+ if ( pView->GetObjectShell()->GetFactory().GetViewFactoryCount() >
+nViewNo && !pView->GetObjectShell()->IsInPlaceActive() )
+ {
+ SfxViewFactory &rViewFactory =
+ pView->GetObjectShell()->GetFactory().GetViewFactory(nViewNo);
+ if ( pView->GetCurViewId() == rViewFactory.GetOrdinal() )
+ return true;
+ }
+ return false;
+}
+
+const ::rtl::OUString REPLACE_CELLS_WARNING( RTL_CONSTASCII_USTRINGPARAM( "ReplaceCellsWarning"));
+
+class PasteCellsWarningReseter
+{
+private:
+ bool bInitialWarningState;
+ static uno::Reference< beans::XPropertySet > getGlobalSheetSettings() throw ( uno::RuntimeException )
+ {
+ static uno::Reference< beans::XPropertySet > xTmpProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ static uno::Reference<uno::XComponentContext > xContext( xTmpProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
+ static uno::Reference<lang::XMultiComponentFactory > xServiceManager(
+ xContext->getServiceManager(), uno::UNO_QUERY_THROW );
+ static uno::Reference< beans::XPropertySet > xProps( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" ) ) ,xContext ), uno::UNO_QUERY_THROW );
+ return xProps;
+ }
+
+ bool getReplaceCellsWarning() throw ( uno::RuntimeException )
+ {
+ sal_Bool res = sal_False;
+ getGlobalSheetSettings()->getPropertyValue( REPLACE_CELLS_WARNING ) >>= res;
+ return ( res == sal_True );
+ }
+
+ void setReplaceCellsWarning( bool bState ) throw ( uno::RuntimeException )
+ {
+ getGlobalSheetSettings()->setPropertyValue( REPLACE_CELLS_WARNING, uno::makeAny( bState ) );
+ }
+public:
+ PasteCellsWarningReseter() throw ( uno::RuntimeException )
+ {
+ bInitialWarningState = getReplaceCellsWarning();
+ if ( bInitialWarningState )
+ setReplaceCellsWarning( false );
+ }
+ ~PasteCellsWarningReseter()
+ {
+ if ( bInitialWarningState )
+ {
+ // don't allow dtor to throw
+ try
+ {
+ setReplaceCellsWarning( true );
+ }
+ catch ( uno::Exception& /*e*/ ){}
+ }
+ }
+};
+
+void
+implnPaste( const uno::Reference< frame::XModel>& xModel )
+{
+ PasteCellsWarningReseter resetWarningBox;
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ if ( pViewShell )
+ {
+ pViewShell->PasteFromSystem();
+ pViewShell->CellContentChanged();
+ }
+}
+
+
+void
+implnCopy( const uno::Reference< frame::XModel>& xModel )
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ if ( pViewShell )
+ pViewShell->CopyToClip(NULL,false,false,true);
+}
+
+void
+implnCut( const uno::Reference< frame::XModel>& xModel )
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ if ( pViewShell )
+ pViewShell->CutToClip( NULL, TRUE );
+}
+
+void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, USHORT nFlags,USHORT nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose)
+{
+ PasteCellsWarningReseter resetWarningBox;
+ sal_Bool bAsLink(sal_False), bOtherDoc(sal_False);
+ InsCellCmd eMoveMode = INS_NONE;
+
+ ScTabViewShell* pTabViewShell = getBestViewShell( xModel );
+ if ( pTabViewShell )
+ {
+ ScViewData* pView = pTabViewShell->GetViewData();
+ Window* pWin = ( pView != NULL ) ? pView->GetActiveWin() : NULL;
+ if ( pView && pWin )
+ {
+ if ( bAsLink && bOtherDoc )
+ pTabViewShell->PasteFromSystem(0);//SOT_FORMATSTR_ID_LINK
+ else
+ {
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ ScDocument* pDoc = NULL;
+ if ( pOwnClip )
+ pDoc = pOwnClip->GetDocument();
+ pTabViewShell->PasteFromClip( nFlags, pDoc,
+ nFunction, bSkipEmpty, bTranspose, bAsLink,
+ eMoveMode, IDF_NONE, TRUE );
+ pTabViewShell->CellContentChanged();
+ }
+ }
+ }
+
+}
+
+ScDocShell*
+getDocShell( const css::uno::Reference< css::frame::XModel>& xModel )
+{
+ uno::Reference< uno::XInterface > xIf( xModel, uno::UNO_QUERY_THROW );
+ ScModelObj* pModel = dynamic_cast< ScModelObj* >( xIf.get() );
+ ScDocShell* pDocShell = NULL;
+ if ( pModel )
+ pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
+ return pDocShell;
+
+}
+
+ScTabViewShell*
+getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel )
+{
+ ScDocShell* pDocShell = getDocShell( xModel );
+ if ( pDocShell )
+ return pDocShell->GetBestViewShell();
+ return NULL;
+}
+
+ScTabViewShell*
+getCurrentBestViewShell( const uno::Reference< uno::XComponentContext >& xContext )
+{
+ uno::Reference< frame::XModel > xModel = getCurrentExcelDoc( xContext );
+ return getBestViewShell( xModel );
+}
+
+SfxViewFrame*
+getViewFrame( const uno::Reference< frame::XModel >& xModel )
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ if ( pViewShell )
+ return pViewShell->GetViewFrame();
+ return NULL;
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xProps( xSheetRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
+ rtl::OUString sCodeName;
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName;
+ // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
+ // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
+ // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
+ // the document in the future could fix this, especially IF the switching of the vba mode takes care to
+ // create the special document module objects if they don't exist.
+ uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xRange ) ), uno::UNO_QUERY );
+
+ return xParent;
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
+ uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+
+ return getUnoSheetModuleObj( xRange );
+}
+
+SfxItemSet*
+ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj )
+{
+ return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0;
+}
+
+
+} //excel
+} //vba
+} //ooo
diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx
new file mode 100644
index 000000000000..da0474e6ceb0
--- /dev/null
+++ b/sc/source/ui/vba/excelvbahelper.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_EXCEL_VBA_HELPER_HXX
+#define SC_EXCEL_VBA_HELPER_HXX
+
+#include<vbahelper/vbahelper.hxx>
+#include <docsh.hxx>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <ooo/vba/XHelperInterface.hpp>
+
+class ScCellRangesBase;
+
+namespace ooo
+{
+ namespace vba
+ {
+ namespace excel
+ {
+ // nTabs empty means apply zoom to all sheets
+ void implSetZoom( const css::uno::Reference< css::frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs );
+ void implnCopy( const css::uno::Reference< css::frame::XModel>& xModel );
+ void implnPaste ( const css::uno::Reference< css::frame::XModel>& xModel );
+ void implnCut( const css::uno::Reference< css::frame::XModel>& xModel );
+ void implnPasteSpecial( const css::uno::Reference< css::frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose);
+ ScTabViewShell* getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel ) ;
+ ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ;
+ ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ SfxViewFrame* getViewFrame( const css::uno::Reference< css::frame::XModel >& xModel );
+ css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException );
+ css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException );
+ ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException );
+ ScDocument* GetDocumentFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException );
+ css::uno::Reference< css::frame::XModel > GetModelFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException );
+ class ScVbaCellRangeAccess
+ {
+ public:
+ static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj );
+ };
+}
+}
+}
+#endif
diff --git a/sc/source/ui/vba/helperdecl.hxx b/sc/source/ui/vba/helperdecl.hxx
new file mode 100644
index 000000000000..a9969179d52f
--- /dev/null
+++ b/sc/source/ui/vba/helperdecl.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <comphelper/servicedecl.hxx>
+#include <ooo/vba/XHelperInterface.hpp>
+
+namespace comphelper {
+namespace service_decl {
+template <typename ImplT_, typename WithArgsT = with_args<false> >
+struct vba_service_class_ : public serviceimpl_base< detail::OwnServiceImpl<ImplT_>, WithArgsT >
+{
+ typedef serviceimpl_base< detail::OwnServiceImpl<ImplT_>, WithArgsT > baseT;
+ /** Default ctor. Implementation class without args, expecting
+ component context as single argument.
+ */
+ vba_service_class_() : baseT() {}
+ template <typename PostProcessFuncT>
+ /** Ctor to pass a post processing function/functor.
+
+ @tpl PostProcessDefaultT let your compiler deduce this
+ @param postProcessFunc function/functor that gets the yet unacquired
+ ImplT_ pointer returning a
+ uno::Reference<uno::XInterface>
+ */
+ explicit vba_service_class_( PostProcessFuncT const& postProcessFunc ) : baseT( postProcessFunc ) {}
+};
+
+} // namespace service_decl
+} // namespace comphelper
+
diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk
new file mode 100644
index 000000000000..92bb3fd39db0
--- /dev/null
+++ b/sc/source/ui/vba/makefile.mk
@@ -0,0 +1,124 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=vbaobj
+ENABLE_EXCEPTIONS=TRUE
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+.IF "$(ENABLE_VBA)"!="YES"
+dummy:
+ @echo "not building vba..."
+.ENDIF
+.IF "$(L10N_framework)"==""
+INCPRE=$(INCCOM)$/$(TARGET)
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/excelvbahelper.obj \
+ $(SLO)$/service.obj \
+ $(SLO)$/vbaapplication.obj \
+ $(SLO)$/vbaassistant.obj \
+ $(SLO)$/vbaaxes.obj \
+ $(SLO)$/vbaaxis.obj \
+ $(SLO)$/vbaaxistitle.obj \
+ $(SLO)$/vbaborders.obj \
+ $(SLO)$/vbacharacters.obj \
+ $(SLO)$/vbachart.obj \
+ $(SLO)$/vbachartobject.obj \
+ $(SLO)$/vbachartobjects.obj \
+ $(SLO)$/vbacharts.obj \
+ $(SLO)$/vbacharttitle.obj \
+ $(SLO)$/vbacomment.obj \
+ $(SLO)$/vbacomments.obj \
+ $(SLO)$/vbacondition.obj \
+ $(SLO)$/vbadialog.obj \
+ $(SLO)$/vbadialogs.obj \
+ $(SLO)$/vbaeventshelper.obj \
+ $(SLO)$/vbafont.obj \
+ $(SLO)$/vbaformat.obj \
+ $(SLO)$/vbaformatcondition.obj \
+ $(SLO)$/vbaformatconditions.obj \
+ $(SLO)$/vbaglobals.obj \
+ $(SLO)$/vbahyperlink.obj \
+ $(SLO)$/vbahyperlinks.obj \
+ $(SLO)$/vbainterior.obj \
+ $(SLO)$/vbaname.obj \
+ $(SLO)$/vbanames.obj \
+ $(SLO)$/vbaoleobject.obj \
+ $(SLO)$/vbaoleobjects.obj \
+ $(SLO)$/vbaoutline.obj \
+ $(SLO)$/vbapagebreak.obj \
+ $(SLO)$/vbapagebreaks.obj \
+ $(SLO)$/vbapagesetup.obj \
+ $(SLO)$/vbapalette.obj \
+ $(SLO)$/vbapane.obj \
+ $(SLO)$/vbapivotcache.obj \
+ $(SLO)$/vbapivottable.obj \
+ $(SLO)$/vbapivottables.obj \
+ $(SLO)$/vbarange.obj \
+ $(SLO)$/vbaseriescollection.obj \
+ $(SLO)$/vbasheetobject.obj \
+ $(SLO)$/vbasheetobjects.obj \
+ $(SLO)$/vbastyle.obj \
+ $(SLO)$/vbastyles.obj \
+ $(SLO)$/vbatextboxshape.obj \
+ $(SLO)$/vbatextframe.obj \
+ $(SLO)$/vbavalidation.obj \
+ $(SLO)$/vbawindow.obj \
+ $(SLO)$/vbawindows.obj \
+ $(SLO)$/vbaworkbook.obj \
+ $(SLO)$/vbaworkbooks.obj \
+ $(SLO)$/vbaworksheet.obj \
+ $(SLO)$/vbaworksheets.obj \
+ $(SLO)$/vbawsfunction.obj
+
+.ENDIF
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(L10N_framework)"==""
+
+ALLTAR : \
+ $(MISC)$/$(TARGET).don \
+
+$(SLOFILES) : $(MISC)$/$(TARGET).don
+
+$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb
+ +$(CPPUMAKER) -O$(INCCOM)$/$(TARGET) -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@
+ echo $@
+
+.ENDIF
diff --git a/sc/source/ui/vba/service.cxx b/sc/source/ui/vba/service.cxx
new file mode 100644
index 000000000000..2b1f14cf154a
--- /dev/null
+++ b/sc/source/ui/vba/service.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "cppuhelper/implementationentry.hxx"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "comphelper/servicedecl.hxx"
+
+// =============================================================================
+// component exports
+// =============================================================================
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace sdecl = comphelper::service_decl;
+
+// reference service helper(s)
+namespace range
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace workbook
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace worksheet
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace window
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace globals
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace hyperlink
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace application
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace vbaeventshelper
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+namespace textframe
+{
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+extern "C"
+{
+ SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+ {
+ OSL_TRACE("In component_getImplementationEnv");
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+ }
+
+ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
+ lang::XMultiServiceFactory * pServiceManager, registry::XRegistryKey * pRegistryKey )
+ {
+ OSL_TRACE("In component_writeInfo");
+#if 0
+ // Component registration
+ if ( component_writeInfoHelper( pServiceManager, pRegistryKey,
+ range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl ) )
+ {
+ // Singleton registration
+ try
+ {
+ registry::XRegistryKey * pKey =
+ reinterpret_cast< registry::XRegistryKey * >(pRegistryKey);
+
+ Reference< registry::XRegistryKey >xKey = pKey->createKey(
+ rtl::OUString::createFromAscii( ("ooo.vba.Globals/UNO/SINGLETONS/ooo.vba.theGlobals") ) );
+ xKey->setStringValue( ::rtl::OUString::createFromAscii(
+ ("ooo.vba.Globals") ) );
+ return sal_True;
+ }
+ catch( uno::Exception& /*e*/ )
+ {
+ //recomp & friends will detect false returned and fail
+ }
+ }
+ return sal_False;
+#else
+ // Component registration
+ return component_writeInfoHelper( pServiceManager, pRegistryKey,
+ range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl, textframe::serviceDecl );
+#endif
+
+ }
+
+ SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+ {
+ OSL_TRACE("In component_getFactory for %s", pImplName );
+ void* pRet = component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl );
+ if( !pRet )
+ pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl, textframe::serviceDecl );
+ OSL_TRACE("Ret is 0x%x", pRet);
+ return pRet;
+ }
+}
diff --git a/sc/source/ui/vba/testvba/README b/sc/source/ui/vba/testvba/README
new file mode 100644
index 000000000000..3a91946de8df
--- /dev/null
+++ b/sc/source/ui/vba/testvba/README
@@ -0,0 +1,37 @@
+to run the tests
+
+build
+=====
+ dmake
+
+windows
+=======
+ a) you can download a cygwin bash shell environment and install perl ( http://cygwin.com/setup.exe )
+ from the cmdline './runTests.pl $(OFFICE_PROGRAM_PATH)' should run the testclient and compare the logs
+ b) use ordinary windows perl [1], but additionally you will need the 'diff' program for window ( download from http://gnuwin32.sourceforge.net/packages/diffutils.htm )
+
+[1] for the testclient the perl ( all inclusive ) bundle from ActivePerl is mor e than adeqate ( download from http://downloads.activestate.com/ActivePerl/Windows/5.8/ActivePerl-5.8.8.822-MSWin32-x86-280952.msi )
+
+ to run all test cases type
+ 'perl ./runTests.pl $(OFFICE_PROGRAM_PATH)'
+ to run a test case type
+ 'perl ./runTests.pl $(OFFICE_PROGRAM_PATH) testfilename'
+
+unix
+====
+
+assuming perl is installed
+ './runTests.pl $(OFFICE_PROGRAM_PATH)'
+ or './runTests.pl $(OFFICE_PROGRAM_PATH) testfilename' for one file test.
+
+
+Note: For either windows or unix all of the tests should pass ( and you should get a result like )
+Note Also: If you meat a problem that stop running test after serveral test documents have been run. please clean your .ooo-2.0 or .oooxxx first, and then re-run.
+
+========>
+
+skipped 0 test-cases(s)
+compared 9 test-case documents
+ 9 tests passedTests
+
+Note also: the testclient will attempt to connect to an existing instance of open-office, when the testClient exits the soffice process may still be running, if you wish to repeat tests you may want to kill the office instance before re-running.
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/ApplicationRunTest.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/ApplicationRunTest.xls
new file mode 100644
index 000000000000..a5a591c1f849
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/ApplicationRunTest.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/AutoFilter.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/AutoFilter.xls
new file mode 100644
index 000000000000..9b3a1043c5ee
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/AutoFilter.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcFont.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcFont.xls
new file mode 100644
index 000000000000..9ddb69600643
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcFont.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcZoom.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcZoom.xls
new file mode 100644
index 000000000000..5db47c76dbe9
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/CalcZoom.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncTests.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncTests.xls
new file mode 100644
index 000000000000..d4776b98fe1d
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncTests.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncs.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncs.xls
new file mode 100644
index 000000000000..bb8941809947
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/FinancialFuncs.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscOperatorTests.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscOperatorTests.xls
new file mode 100644
index 000000000000..23227ae37e24
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscOperatorTests.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscRangeTests.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscRangeTests.xls
new file mode 100644
index 000000000000..ebd9e91b5b28
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/MiscRangeTests.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/PageBreaks.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/PageBreaks.xls
new file mode 100644
index 000000000000..b6651fa5d617
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/PageBreaks.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-2.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-2.xls
new file mode 100644
index 000000000000..f6e81cf933fd
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-2.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-3.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-3.xls
new file mode 100644
index 000000000000..8722f6d3057e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges-3.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges.xls
new file mode 100644
index 000000000000..1c1d74d37486
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Ranges.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Shapes.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Shapes.xls
new file mode 100644
index 000000000000..254f3c97756c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Shapes.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/StrConv-test.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/StrConv-test.xls
new file mode 100644
index 000000000000..198abbec5871
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/StrConv-test.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Template.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Template.xls
new file mode 100644
index 000000000000..4387231fe744
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Template.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestAddress.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestAddress.xls
new file mode 100644
index 000000000000..48d30cbe2e9e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestAddress.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest.xls
new file mode 100644
index 000000000000..a497d4f10f3e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest2.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest2.xls
new file mode 100644
index 000000000000..34c606fc28f5
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestCalc_Rangetest2.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestIntersection.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestIntersection.xls
new file mode 100644
index 000000000000..24f88db87ccc
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestIntersection.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestUnion.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestUnion.xls
new file mode 100644
index 000000000000..5b8f0968cf38
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/TestUnion.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/VariantTest.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/VariantTest.xls
new file mode 100644
index 000000000000..f604cfbe3975
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/VariantTest.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Window.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Window.xls
new file mode 100644
index 000000000000..6fb6963c2f31
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/Window.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/bytearraystring.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/bytearraystring.xls
new file mode 100644
index 000000000000..471bbc349e5b
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/bytearraystring.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/dateserial.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/dateserial.xls
new file mode 100644
index 000000000000..768fb513eba4
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/dateserial.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/datevalue.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/datevalue.xls
new file mode 100644
index 000000000000..852a51d100b8
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/datevalue.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/format.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/format.xls
new file mode 100644
index 000000000000..99ed64d38915
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/format.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/AutoFilter.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/AutoFilter.log
new file mode 100644
index 000000000000..1fe0cbd01fe5
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/AutoFilter.log
@@ -0,0 +1,20 @@
+Test run started : 17/07/2007 17:36:22
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 'starts with' string criteria
+ ITEM Assertion OK : test2 'not equal to' string criteria
+ ITEM Assertion OK : test3 'ends with' string criteria
+ ITEM Assertion OK : test4 field 'all'
+ ITEM Assertion OK : test5 numeric '<15'
+ ITEM Assertion OK : test6 numeric '>=15'
+ ITEM Assertion OK : test7 numeric '<=12'
+Test Results
+============
+
+Tests passed: 7
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 17/07/2007 17:36:23
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/MiscRangeTests.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/MiscRangeTests.log
new file mode 100644
index 000000000000..260465386d07
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/MiscRangeTests.log
@@ -0,0 +1,45 @@
+Test run started : 17/07/2007 15:01:37
+----------------------------------------------------------------
+MiscRangeTests
+ TEST START : MiscRangeTests
+ ITEM Assertion OK : test 1
+ ITEM Assertion OK : test 2
+ ITEM Assertion OK : test 3
+ ITEM Assertion OK : test 4
+ ITEM Assertion OK : test 5
+ ITEM Assertion OK : test 6
+ ITEM Assertion OK : test 7
+ ITEM Assertion OK : test 8
+ ITEM Assertion OK : test 9
+ ITEM Assertion OK : test 10
+ ITEM Assertion OK : test 11
+ ITEM Assertion OK : test 12
+ ITEM Assertion OK : test 13
+ ITEM Assertion OK : test 14
+ ITEM Assertion OK : test 15
+ ITEM Assertion OK : test 16
+ ITEM Assertion OK : test 17
+ ITEM Assertion OK : test 18
+ ITEM Assertion OK : test 19
+ ITEM Assertion OK : test 20
+ ITEM Assertion OK : test 21
+ ITEM Assertion OK : test 22
+ ITEM Assertion OK : test 23
+ ITEM Assertion OK : test 24
+ ITEM Assertion OK : test 25
+ ITEM Assertion OK : test 26
+ ITEM Assertion OK : test 27
+ ITEM Assertion OK : test 28
+ ITEM Assertion OK : test 29
+ ITEM Assertion OK : test 30
+ ITEM Assertion OK : test 31
+No. tests: 31
+Summary
+=======
+Run: 31
+Passed: 31
+Failed: 0
+
+END 'MiscRangeTests
+ TEST OK : MiscRangeTests
+Test run finished : 17/07/2007 15:01:39
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-2.log
new file mode 100644
index 000000000000..736d5bbc42d0
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-2.log
@@ -0,0 +1,68 @@
+Test run started : 18/06/2007 17:50:04
+----------------------------------------------------------------
+ClearFormtsIssue
+ TEST START : ClearFormtsIssue
+ ITEM Assertion OK : Range.Font.Bold is: True
+ ITEM Assertion OK : Range.Font.Bold is: False
+END 'ClearFormtsIssue' Symbol
+ TEST OK : ClearFormtsIssue
+----------------------------------------------------------------
+VerticalAlignment-Issue
+ TEST START : VerticalAlignment-Issue
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : Range.VeritcalAlignment is Null
+END 'VerticalAlignment-Issue' Symbol
+ TEST OK : VerticalAlignment-Issue
+----------------------------------------------------------------
+HorizontalAlignment-Issue
+ TEST START : HorizontalAlignment-Issue
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : Range.HorizontalAlignment is Null
+END 'HorizontalAlignment-Issue' Symbol
+ TEST OK : HorizontalAlignment-Issue
+----------------------------------------------------------------
+WrapText-Issue
+ TEST START : WrapText-Issue
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : Range.WrapText is Null
+END 'WrapText-Issue' Symbol
+ TEST OK : WrapText-Issue
+----------------------------------------------------------------
+FontBorderIssues
+ TEST START : FontBorderIssues
+ ITEM Assertion OK : - = Borders.Color (getColor)
+ ITEM Assertion OK : - = Font.Color (getColor)
+END 'FontBorderIssues' Symbol
+ TEST OK : FontBorderIssues
+----------------------------------------------------------------
+RangeSizeIssues
+ TEST START : RangeSizeIssues
+ ITEM Assertion OK : Range.Left is: 114
+ ITEM Assertion OK : Range.Top is: 95.25
+ ITEM Assertion OK : Range.Width is: 216
+ ITEM Assertion OK : Range.Height is: 271.5
+END 'RangeSizeIssues' Symbol
+ TEST OK : RangeSizeIssues
+----------------------------------------------------------------
+ApplicationIssues
+ TEST START : ApplicationIssues
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Application.ActiveSheet.Name: Sheet1
+END 'ApplicationIssues' Symbol
+ TEST OK : ApplicationIssues
+Test run finished : 18/06/2007 17:50:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-3.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-3.log
new file mode 100644
index 000000000000..a7de979d5e13
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges-3.log
@@ -0,0 +1,8 @@
+Test run started : 19/06/2007 11:21:42
+----------------------------------------------------------------
+MyGoalseek-Issue
+ TEST START : MyGoalseek-Issue
+ ITEM Assertion OK : Variable Range value: 15
+END 'MyGoalseek-Issue' Symbol
+ TEST OK : MyGoalseek-Issue
+Test run finished : 19/06/2007 11:21:42
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges.log
new file mode 100644
index 000000000000..8c9644aac155
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/Ranges.log
@@ -0,0 +1,280 @@
+Test run started : 01/06/2007 11:28:58
+----------------------------------------------------------------
+ApplicationMethods
+ TEST START : ApplicationMethods
+ ITEM Assertion OK : Name of Workbook is: Ranges.xls
+ ITEM Assertion OK : Address of Application.Columns is: $A:$A
+ ITEM Assertion OK : Address of Application.Rows is: $1:$1
+ ITEM Assertion OK : Address of Application.Range is: $1:$1,$5:$7
+ ITEM Assertion OK : Please check manually: DefaultFilePath is: C:\Documents and Settings\vituosity\My Documents
+ ITEM Assertion OK : Please check manually: Library Path is: C:\Program Files\Microsoft Office\OFFICE11\LIBRARY
+ ITEM Assertion OK : Please check manually: Template Path is: C:\Documents and Settings\vituosity\Application Data\Microsoft\Templates\
+ ITEM Assertion OK : FileSeparator is \
+ ITEM Assertion OK : Name of ActiveWorkbook is: Ranges.xls
+END 'ApplicationMethods' Symbol
+ TEST OK : ApplicationMethods
+----------------------------------------------------------------
+Insert-Issue
+ TEST START : Insert-Issue
+ ITEM Assertion OK : Insert with xlShiftToRight: 10
+END 'Insert-Issue' Symbol
+ TEST OK : Insert-Issue
+----------------------------------------------------------------
+MergeCells-Issue
+ TEST START : MergeCells-Issue
+ ITEM Assertion OK : Range.MergeCells is True
+ ITEM Assertion OK : MergeCells is null: True
+ ITEM Assertion OK : RowCount after Merge: 6
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : MergeCells of Second Area is null : True
+ ITEM Assertion OK : MergeCells of Ranges is Null: True
+ ITEM Assertion OK : RowCount after Merge: 7
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+END 'MergeCells-Issue' Symbol
+ TEST OK : MergeCells-Issue
+----------------------------------------------------------------
+Areas-Issue
+ TEST START : Areas-Issue
+ ITEM Assertion OK : Range Areas Count is2
+ ITEM Assertion OK : First Range Address is: $E$8:$G$13
+ ITEM Assertion OK : First Row is: 8
+ ITEM Assertion OK : First Column is: 5
+ ITEM Assertion OK : EntireRow Address is: $8:$13,$13:$19
+ ITEM Assertion OK : EntireColumn Address is: $E:$G,$G:$K
+ ITEM Assertion OK : Range Count:53
+END 'Areas-Issue' Symbol
+ TEST OK : Areas-Issue
+----------------------------------------------------------------
+Fill-Methods-Issue
+ TEST START : Fill-Methods-Issue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyRightFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyBottomFillValue
+END 'Fill-Methods-Issue' Symbol
+ TEST OK : Fill-Methods-Issue
+----------------------------------------------------------------
+Range/Item-Method-Issue
+ TEST START : Range/Item-Method-Issue
+ ITEM Assertion OK : Range of multiple columns is: $A:$A,$C:$C
+ ITEM Assertion OK : Range of multiple rows is: $1:$1,$5:$7
+ ITEM Assertion OK : Range of several columns is: $C:$E,$D:$D
+ ITEM Assertion OK : Range of several rows is: $5:$8,$6:$10
+ ITEM Assertion OK : Range of several single cells is: $C$5,$E$8
+ ITEM Assertion OK : Range of several named ranges is: $L$1:$M$6,$E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range of a single Item Cell is: $E$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$10
+END 'Range/Item-Method-Issue' Symbol
+ TEST OK : Range/Item-Method-Issue
+----------------------------------------------------------------
+R1C1-Formulas-Issue
+ TEST START : R1C1-Formulas-Issue
+ ITEM Assertion OK : R1C1 Range.Formula is: =IF(OR(R[-2]C[1]=0,RC[2]="YES"),"")
+ ITEM Assertion OK : Range.Formula is: =IF(OR(J8=0,K10="YES"),"")
+END 'R1C1-Formulas-Issue' Symbol
+ TEST OK : R1C1-Formulas-Issue
+----------------------------------------------------------------
+Verify_Delete
+ TEST START : Verify_Delete
+ ITEM Assertion OK : Ranges are intersecting: $G$13
+ ITEM Assertion OK : Delete with Default: $AJ$4
+ ITEM Assertion OK : Delete with ShifttoLeft: $AJ$4
+ ITEM Assertion OK : Delete with ShiftUp: $M$22
+END 'Verify_Delete' Symbol
+ TEST OK : Verify_Delete
+----------------------------------------------------------------
+Value-Issue
+ TEST START : Value-Issue
+ ITEM Assertion OK : Value of Range is: 12.3
+ ITEM Assertion OK : Text of Range is: 12.3
+ ITEM Assertion OK : Range has Formula: False
+ ITEM Assertion OK : Cell has Formula: False
+ ITEM Assertion OK : Text of Range is null: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Cell has Formula: True
+ ITEM Assertion OK : Value of Cell is: 12
+ ITEM Assertion OK : Application.Calculation is : -4135
+ ITEM Assertion OK : Calculation is automated: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Value of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Range has Formula after 'ClearContents: False
+ ITEM Assertion OK : Text of Cell is:
+ ITEM Assertion OK : Text of Cell is:
+END 'Value-Issue' Symbol
+ TEST OK : Value-Issue
+----------------------------------------------------------------
+AutoFit issue
+ TEST START : AutoFit issue
+ ITEM Assertion OK : Columns.AutoFit: CurrentWidth is 673
+ ITEM Assertion OK : Rows.AutoFit: CurrentHeight is 612
+END 'AutoFit issue' Symbol
+ TEST OK : AutoFit issue
+----------------------------------------------------------------
+Selections
+ TEST START : Selections
+ ITEM Assertion OK : ActiveCell is : $E$8
+ ITEM Assertion OK : Active Cell is : $E$8
+ ITEM Assertion OK : Number of Cells in Range: 53
+ ITEM Assertion OK : Number of Cells in Range: 53
+ ITEM Assertion OK : Number of Cells in Range: 53
+END 'Selections' Symbol
+ TEST OK : Selections
+----------------------------------------------------------------
+Offset-Resize
+ TEST START : Offset-Resize
+ ITEM Assertion OK : Offset is : $G$10:$I$15,$I$15:$M$21
+ ITEM Assertion OK : Offset is : $G$7:$I$12,$I$12:$M$18
+ ITEM Assertion OK : Resized Range is : $A$20:$D$23
+END 'Offset-Resize' Symbol
+ TEST OK : Offset-Resize
+----------------------------------------------------------------
+Ranges-Address
+ TEST START : Ranges-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: $E8:$G13,$G13:$K19
+ ITEM Assertion OK : Range Address is: E$8:G$13,G$13:K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5],R[11]C[5]:R[17]C[9]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13,$G$13:$K$19
+END 'Ranges-Address' Symbol
+ TEST OK : Ranges-Address
+----------------------------------------------------------------
+Range-Address
+ TEST START : Range-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: $E8:$G13
+ ITEM Assertion OK : Range Address is: E$8:G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13
+END 'Range-Address' Symbol
+ TEST OK : Range-Address
+----------------------------------------------------------------
+Column-Address
+ TEST START : Column-Address
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: $F8:$F13
+ ITEM Assertion OK : Range Address is: F$8:F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R[6]C[4]:R[11]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$8:$F$13
+END 'Column-Address' Symbol
+ TEST OK : Column-Address
+----------------------------------------------------------------
+Row-Address
+ TEST START : Row-Address
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: $E9:$G9
+ ITEM Assertion OK : Range Address is: E$9:G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R[7]C[3]:R[7]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$9:$G$9
+END 'Row-Address' Symbol
+ TEST OK : Row-Address
+----------------------------------------------------------------
+SingleCell-Address
+ TEST START : SingleCell-Address
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: $F9
+ ITEM Assertion OK : Range Address is: F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R[7]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$9
+END 'SingleCell-Address' Symbol
+ TEST OK : SingleCell-Address
+----------------------------------------------------------------
+Heights and Widths
+ TEST START : Heights and Widths
+ ITEM Assertion OK : Range RowHeight is 40
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 238
+ ITEM Assertion OK : Range Width is 798.75
+ ITEM Assertion OK : Range RowHeight is 50
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 297
+ ITEM Assertion OK : Range Width is 798.75
+ ITEM Assertion OK : RowHeight is null: True
+ ITEM Assertion OK : ColumnWidth is null: True
+END 'Heights and Widths' Symbol
+ TEST OK : Heights and Widths
+----------------------------------------------------------------
+RangeRowColumn-Issue
+ TEST START : RangeRowColumn-Issue
+ ITEM Assertion OK : Row is: 8
+ ITEM Assertion OK : Column is: 5
+ ITEM Assertion OK : EntireRow.Columns.Count = 256
+ ITEM Assertion OK : EntireColumn.Rows.Count = 65536
+END 'RangeRowColumn-Issue' Symbol
+ TEST OK : RangeRowColumn-Issue
+----------------------------------------------------------------
+Replace-Issue
+ TEST START : Replace-Issue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New Replace
+ ITEM Assertion OK : Value after Replace:
+END 'Replace-Issue' Symbol
+ TEST OK : Replace-Issue
+----------------------------------------------------------------
+Hidden-Issue
+ TEST START : Hidden-Issue
+ ITEM Assertion OK : - Range.Rows.Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Hidden (get)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (get)
+END 'Hidden-Issue' Symbol
+ TEST OK : Hidden-Issue
+----------------------------------------------------------------
+End issue
+ TEST START : End issue
+ ITEM Assertion OK : - = $E$48
+ ITEM Assertion OK : - = $E$1
+ ITEM Assertion OK : - = $E$3
+ ITEM Assertion OK : - = $A$8
+ ITEM Assertion OK : - = $B$8
+ ITEM Assertion OK : - = $IV$8
+ ITEM Assertion OK : - = $Z$8
+END 'End issue' Symbol
+ TEST OK : End issue
+----------------------------------------------------------------
+Outline issue
+ TEST START : Outline issue
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+END 'Outline issue' Symbol
+ TEST OK : Outline issue
+----------------------------------------------------------------
+Validation
+ TEST START : Validation
+ ITEM Assertion OK : Validation Input Message is : Attention!
+ ITEM Assertion OK : Validation Input Message is : Enter an integer from five to ten
+ ITEM Assertion OK : Validation Error Title is : You must enter a number from five to ten
+ ITEM Assertion OK : Validation Error Message is : An Error occured
+ ITEM Assertion OK : Validation Error Title is : Microsoft Excel
+END 'Validation' Symbol
+ TEST OK : Validation
+Test run finished : 01/06/2007 11:29:00
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestAddress.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestAddress.log
new file mode 100644
index 000000000000..01e5503a7e62
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestAddress.log
@@ -0,0 +1,62 @@
+Test run started : 17/07/2007 15:25:17
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 Range('e3:f3') A1 style addressing
+ ITEM Assertion OK : test2 Range('e3:f3') R1C1 style addressing
+ ITEM Assertion OK : test3 Range ('e:f') A1 style addressing
+ ITEM Assertion OK : test4 Range ('e:f') R1C1 style addressing
+ ITEM Assertion OK : test5 Columns A1 style addressing
+ ITEM Assertion OK : test6 Columns R1C1 style addressing
+ ITEM Assertion OK : test7 Columns(3) A1 style addressing
+ ITEM Assertion OK : test8 Columns(3) R1C1 style addressing
+ ITEM Assertion OK : test9 Columns('e') A1 style addressing
+ ITEM Assertion OK : test10 Columns('e') R1C1 style addressing
+ ITEM Assertion OK : test11 Columns('b:d') A1 style addressing
+ ITEM Assertion OK : test12 Columns('b:d') R1C1 style addressing
+ ITEM Assertion OK : test13 Range('c1:g10').Columns A1 style addressing
+ ITEM Assertion OK : test14 Range('c1:g10').Columns R1C1 style addressing
+ ITEM Assertion OK : test15 Range('c1:g10').Columns(1) A1 style addressing
+ ITEM Assertion OK : test16 Range('c1:g10').Columns(1) R1C1 style addressing
+ ITEM Assertion OK : test17 Range('c1:g10').Columns('a') A1 style addressing
+ ITEM Assertion OK : test18 Range('c1:g10').Columns('a') R1C1 style addressing
+ ITEM Assertion OK : test19 Range('c1:g10').Columns('c') A1 style addressing
+ ITEM Assertion OK : test20 Range('c1:g10').Columns('c') R1C1 style addressing
+ ITEM Assertion OK : test21 Range('c1:g10').Columns('x:z') A1 style addressing
+ ITEM Assertion OK : test22 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test23 Range('c1:g10').Columns(30) A1 style addressing
+ ITEM Assertion OK : test24 Range('c1:g10').Columns(30) R1C1 style addressing
+ ITEM Assertion OK : test25 Worksheets('Sheet2').Cells(1, 1) A1 style addressing
+ ITEM Assertion OK : test26 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, RowAddressAbsolute is false
+ ITEM Assertion OK : test27 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, ColAddressAbsolute is false
+ ITEM Assertion OK : test28 Worksheets('Sheet2').Cells(1, 1) R1C1 style addressing
+ ITEM Assertion OK : test29 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test30 Worksheets('Sheet2').Range('A1').EntireColumn A1 style addressing
+ ITEM Assertion OK : test31 Worksheets('Sheet2').Range('A1:E5').EntireRow A1 style addressing
+ ITEM Assertion OK : test32 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test33 Worksheets('Sheet2').Range('IV65536').EntireRow A1 style addressing
+ ITEM Assertion OK : test34 Worksheets('Sheet2').Range('IU2:IV65536') A1 style addressing
+ ITEM Assertion OK : test35 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test36 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test37 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test38 Worksheets('Sheet2').Range('10:12') A1 style addressing
+ ITEM Assertion OK : test39 Worksheets('Sheet2').Range('10:12') R1C1 style addressing
+ ITEM Assertion OK : test40 Range('Sheet3!A1:B4') A1 style addressing
+ ITEM Assertion OK : test41 Range('Sheet3!A1,B1,D4:F20') A1 style addressing
+ ITEM Assertion OK : test42 Range('g20:h40').Columns('c:c')
+ ITEM Assertion OK : test43 Range('g20:h40').Columns('c:f')
+ ITEM Assertion OK : test44 Range('g20:h40').Columns(-1)
+ ITEM Assertion OK : test45 Range('c4:g10').Rows(-1)
+ ITEM Assertion OK : test46 Range('a2:b4').Rows('1:1')
+ ITEM Assertion OK : test47 Range('a2:b4').Rows('1:2')
+ ITEM Assertion OK : test48 Range('a2:b4').Rows('2:2')
+ ITEM Assertion OK : test49 Range('a2:b4').Rows('2:3')
+Test Results
+============
+
+Tests passed: 49
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 17/07/2007 15:25:19
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest.log
new file mode 100644
index 000000000000..f055279ec6f4
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest.log
@@ -0,0 +1,60 @@
+Test run started : 30/05/2007 11:33:13
+BEGIN TestCalc
+ TEST START : RangeTest2
+ ITEM Assertion OK : - Range("D15").Row
+ ITEM Assertion OK : - WorkSheet("D15").Range.Row
+ ITEM Assertion OK : - Range("D15").Column
+ ITEM Assertion OK : - Worksheet.Range("D15").Column
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Columns.Count
+ ITEM Assertion OK : - Range("D1").EntireColumn.Rows.Count
+ ITEM Assertion OK : - Range("D15").ClearContent
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (get)
+ ITEM Assertion OK : - Range("B38").Orientation (get)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlDownward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlUpward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B39").WrapText (get)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (get)
+ ITEM Assertion OK : - Range("F39").MergeCells (get)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("D41:D42").Replace MatchCase:=False
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM OK (RangeTest2)
+ TEST succesfully completed : RangeTest2
+END TestCalc
+Test run finished : 30/05/2007 11:33:14
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest2.log
new file mode 100644
index 000000000000..19a5ba96b54a
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/excel/TestCalc_Rangetest2.log
@@ -0,0 +1,64 @@
+Test run started : 31/05/2007 11:02:10
+BEGIN TestCalc
+ TEST START : RangeTest3
+ ITEM Assertion OK : - setFormulaR1C1
+ ITEM Assertion OK : - getFormulaR1C1
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy(Range("I10"))
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteValues
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormulas
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormats
+ ITEM Assertion OK : PasteSpecial
+ ITEM Assertion OK : PasteSpecial SkipBlanks:=True
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationAdd
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationSubtract
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationMultiply
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationDivide
+ ITEM Assertion OK : PasteSpecial Transpose:=True
+ ITEM Assertion OK : ActiveWorkbook.Name
+ ITEM Assertion OK : ActiveWorkbook.FullName und ActiveWorkbook.Path
+ ITEM Assertion OK : - = Range("K22").End (xlDown)
+ ITEM Assertion OK : - = Range("K22").End (xlUo)
+ ITEM Assertion OK : - = Range("K22").End (xlToLeft)
+ ITEM Assertion OK : - = Range("K22").End (xlRight)
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="x"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="<>"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="="
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter
+ ITEM Assertion OK : - ActiveSheet.Resize.Select
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Application.GoTo Reference:="R[8]C[2]"
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Ungroup- please check visually
+ ITEM Assertion OK : - Range.Ungroup - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - ActiveSheet.UsedRange.Select
+ ITEM Assertion FAIL : - Range("A13").AddIndent
+ ITEM Assertion OK : - Range("A13").IndentLevel set
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Calculate
+ ITEM Assertion OK : Worksheet.Calculate
+ ITEM Assertion OK : - Application.Calculate
+ ITEM Assertion OK : Global.Calculate
+ ITEM Assertion OK : Calculation set
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) set
+ ITEM Assertion OK : - = ActiveWorkbook.ResetColors
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) get
+ ITEM FAIL (RangeTest3)
+ TEST Not succesfully completed : RangeTest3
+END TestCalc
+Test run finished : 31/05/2007 11:02:12
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/format.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/format.log
new file mode 100644
index 000000000000..5226a161c61a
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/format.log
@@ -0,0 +1,36 @@
+Test run started : 08/10/2008 13:08:40
+BEGIN Format
+ TEST START : Test Predefined_Number_Format_Sample function
+ ITEM Assertion OK : General Number: 562486.2356
+ ITEM Assertion OK : Fixed: 0.20
+ ITEM Assertion OK : Standard: 562,486.24
+ ITEM Assertion OK : Percent: 75.21%
+ ITEM Assertion OK : Scientific: 5.62E+05
+ ITEM Assertion OK : Scientific: -3.46E+03
+ ITEM Assertion OK : Yes/No: No
+ ITEM Assertion OK : Yes/No: Yes
+ ITEM Assertion OK : True/False: False
+ ITEM Assertion OK : True/False: True
+ ITEM Assertion OK : On/Off: Off
+ ITEM Assertion OK : On/Off: On
+ TEST OK : Test Predefined_Number_Format_Sample function
+ TEST START : Test Custom_Number_Format_Sample function
+ ITEM Assertion OK : 00.0000: 23.6750
+ ITEM Assertion OK : 00.00: 23.68
+ ITEM Assertion OK : 00000: 02658
+ ITEM Assertion OK : 00.00: 2658.00
+ ITEM Assertion OK : ##.####: 23.675
+ ITEM Assertion OK : ##.##: 23.68
+ ITEM Assertion OK : #,###.##: 12,345.25
+ ITEM Assertion OK : ##.00%: 25.00%
+ ITEM Assertion OK : #,###: 1,000,000
+ ITEM Assertion OK : ######E-###: 109838E-5
+ ITEM Assertion OK : $#,###.##: $2,345.25
+ ITEM Assertion OK : ##.###\%: .25%
+ TEST OK : Test Custom_Number_Format_Sample function
+ TEST START : Test Custom_Text_Format_Sample function
+ ITEM Assertion OK : <: vba
+ ITEM Assertion OK : >: VBA
+ TEST OK : Test Custom_Text_Format_Sample function
+END Format
+Test run finished : 08/10/2008 13:08:40
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/AutoFilter.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/AutoFilter.log
new file mode 100644
index 000000000000..55f5d9526618
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/AutoFilter.log
@@ -0,0 +1,20 @@
+Test run started : 18/07/2007 10:56:38
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 'starts with' string criteria
+ ITEM Assertion OK : test2 'not equal to' string criteria
+ ITEM Assertion OK : test3 'ends with' string criteria
+ ITEM Assertion OK : test4 field 'all'
+ ITEM Assertion OK : test5 numeric '<15'
+ ITEM Assertion OK : test6 numeric '>=15'
+ ITEM Assertion OK : test7 numeric '<=12'
+Test Results
+============
+
+Tests passed: 7
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 18/07/2007 10:56:44
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcFont.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcFont.log
new file mode 100644
index 000000000000..f3583e4cbb12
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcFont.log
@@ -0,0 +1,17 @@
+Test run started : 10/09/2008 02:40:17 PM
+CalcFont_Format
+ TEST START : Font_Format
+ ITEM Assertion OK : correctly set font to Bold
+ ITEM Assertion OK : correctly set font to Italic
+ ITEM Assertion OK : correctly read FontStyle
+ ITEM Assertion OK : correctly set font to Shadow
+ ITEM Assertion OK : correctly set font color
+ ITEM Assertion OK : correctly set font color index
+ ITEM Assertion OK : correctly set font name
+ ITEM Assertion OK : correctly set font outline
+ ITEM Assertion OK : correctly set font size
+ ITEM Assertion OK : correctly set font strikethrough
+ ITEM Assertion OK : correctly set font underline
+ TEST Success. : Font_Format
+CalcFont_Format
+Test run finished : 10/09/2008 02:40:17 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcZoom.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcZoom.log
new file mode 100644
index 000000000000..f8c83531a8a2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/CalcZoom.log
@@ -0,0 +1,18 @@
+Test run started : 15/06/2009 12:49:35
+CalcZoom
+ TEST START : CalcZoom
+ ITEM Assertion OK : test1 read window.zoom activesheet = sheet1
+ ITEM Assertion OK : test2 read window.zoom activesheet = sheet2
+ ITEM Assertion OK : test3 read window.zoom activesheet = sheet3
+ ITEM Assertion OK : test4 read window.zoom activesheet = sheet3
+ ITEM Assertion OK : test4 read window.zoom activesheet = sheet2
+ ITEM Assertion OK : test4 read window.zoom activesheet = sheet1
+ TEST Success. : CalcZoom
+CalcZoom
+Test Results
+============
+
+Tests passed: 6
+Tests failed: 0
+
+Test run finished : 15/06/2009 12:49:37
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/FinancialFuncTests.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/FinancialFuncTests.log
new file mode 100644
index 000000000000..5633a8100e08
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/FinancialFuncTests.log
@@ -0,0 +1,31 @@
+Test run started : 04/08/2009 12:42:26
+----------------------------------------------------------------
+FinancialFuncs
+ TEST START : FinancialFuncs
+ ITEM Assertion OK : DDB test
+ ITEM Assertion OK : FV test
+ ITEM Assertion OK : IPmt test
+ ITEM Assertion FAIL : IRR test
+ ITEM Assertion OK : MIRR test
+ ITEM Assertion FAIL : NPer test
+ ITEM Assertion FAIL : NPV test
+ ITEM Assertion FAIL : Pmt test
+ ITEM Assertion OK : PPmt test
+ ITEM Assertion OK : PV test
+ ITEM Assertion FAIL : Rate test
+ ITEM Assertion OK : SLN test
+ ITEM Assertion OK : SYD test
+Test Results
+============
+
+IRR test Failed: expected 35.8625323270733 got 35.8625323273411
+NPer test Failed: expected 21.5365977313406 got 21.5365977313408
+NPV test Failed: expected 3874.42183648785 got 3874.42183648784
+Pmt test Failed: expected 20276.3942884139 got 20276.3942884138
+Rate test Failed: expected 4.67819164224935E-02 got 4.67819164225E-02
+Tests passed: 8
+Tests failed: 5
+
+END 'FinancialFuncs
+ TEST OK : FinancialFuncs
+Test run finished : 04/08/2009 12:42:36
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscOperatorTests.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscOperatorTests.log
new file mode 100644
index 000000000000..116f9f98c7e8
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscOperatorTests.log
@@ -0,0 +1,30 @@
+Test run started : 12/05/2009 12:36:15
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1: res = Not ( A > B )
+ ITEM Assertion OK : test2: res = Not ( B > A )
+ ITEM Assertion OK : test3: res = Not ( D )
+ ITEM Assertion OK : test4: res = Not A
+ ITEM Assertion OK : test5: res = ( A > D )
+ ITEM Assertion OK : test6: res = ( D > A )
+ ITEM Assertion OK : test7: res = ( A < D )
+ ITEM Assertion OK : test8: res = ( D < A )
+ ITEM Assertion OK : test9: res = ( A >= D )
+ ITEM Assertion OK : test10: res = ( D >= A )
+ ITEM Assertion OK : test11: res = ( A <= D )
+ ITEM Assertion OK : test12: res = ( D <= A )
+ ITEM Assertion OK : test13: res = ( D = A )
+ ITEM Assertion OK : test14: res = ( A = D )
+ ITEM Assertion OK : test15: res = ( D <> A )
+ ITEM Assertion OK : test16: res = ( A <> D )
+ ITEM Assertion OK : test17: ( A = D ) = True
+Test Results
+============
+
+Tests passed: 17
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 12/05/2009 12:36:15
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscRangeTests.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscRangeTests.log
new file mode 100644
index 000000000000..215842f9a7e6
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/MiscRangeTests.log
@@ -0,0 +1,45 @@
+Test run started : 17/07/2007 20:54:56
+----------------------------------------------------------------
+MiscRangeTests
+ TEST START : MiscRangeTests
+ ITEM Assertion OK : test 1
+ ITEM Assertion OK : test 2
+ ITEM Assertion OK : test 3
+ ITEM Assertion OK : test 4
+ ITEM Assertion OK : test 5
+ ITEM Assertion OK : test 6
+ ITEM Assertion OK : test 7
+ ITEM Assertion OK : test 8
+ ITEM Assertion OK : test 9
+ ITEM Assertion OK : test 10
+ ITEM Assertion OK : test 11
+ ITEM Assertion OK : test 12
+ ITEM Assertion OK : test 13
+ ITEM Assertion OK : test 14
+ ITEM Assertion OK : test 15
+ ITEM Assertion OK : test 16
+ ITEM Assertion OK : test 17
+ ITEM Assertion OK : test 18
+ ITEM Assertion OK : test 19
+ ITEM Assertion OK : test 20
+ ITEM Assertion OK : test 21
+ ITEM Assertion OK : test 22
+ ITEM Assertion OK : test 23
+ ITEM Assertion OK : test 24
+ ITEM Assertion OK : test 25
+ ITEM Assertion OK : test 26
+ ITEM Assertion OK : test 27
+ ITEM Assertion OK : test 28
+ ITEM Assertion OK : test 29
+ ITEM Assertion OK : test 30
+ ITEM Assertion OK : test 31
+No. tests: 31
+Summary
+=======
+Run: 31
+Passed: 31
+Failed: 0
+
+END 'MiscRangeTests
+ TEST OK : MiscRangeTests
+Test run finished : 17/07/2007 20:55:03
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/PageBreaks.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/PageBreaks.log
new file mode 100644
index 000000000000..0ff400d49e85
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/PageBreaks.log
@@ -0,0 +1,10 @@
+Test run started : 07/24/2008 05:06:12 PM
+----------------------------------------------------------------
+ TEST START : PageBreaks-Issue
+ ITEM Assertion OK : HPageBreaks.Count is 3
+ ITEM Assertion OK : HPageBreak.Type is -4135
+ ITEM Assertion OK : HPageBreak.Location: Range.Row is 5
+ ITEM Assertion OK : HPageBreak.Delete: HPageBreaks.Count is 2
+END 'PageBreaks-Issue' Symbol
+ TEST OK : PageBreaks-Issue
+Test run finished : 07/24/2008 05:06:13 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-2.log
new file mode 100644
index 000000000000..8b7076efaea0
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-2.log
@@ -0,0 +1,68 @@
+Test run started : 19/06/2007 11:14:01
+----------------------------------------------------------------
+ClearFormtsIssue
+ TEST START : ClearFormtsIssue
+ ITEM Assertion OK : Range.Font.Bold is: True
+ ITEM Assertion OK : Range.Font.Bold is: False
+END 'ClearFormtsIssue' Symbol
+ TEST OK : ClearFormtsIssue
+----------------------------------------------------------------
+VerticalAlignment-Issue
+ TEST START : VerticalAlignment-Issue
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : Range.VeritcalAlignment is Null
+END 'VerticalAlignment-Issue' Symbol
+ TEST OK : VerticalAlignment-Issue
+----------------------------------------------------------------
+HorizontalAlignment-Issue
+ TEST START : HorizontalAlignment-Issue
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : Range.HorizontalAlignment is Null
+END 'HorizontalAlignment-Issue' Symbol
+ TEST OK : HorizontalAlignment-Issue
+----------------------------------------------------------------
+WrapText-Issue
+ TEST START : WrapText-Issue
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : Range.WrapText is Null
+END 'WrapText-Issue' Symbol
+ TEST OK : WrapText-Issue
+----------------------------------------------------------------
+FontBorderIssues
+ TEST START : FontBorderIssues
+ ITEM Assertion OK : - = Borders.Color (getColor)
+ ITEM Assertion OK : - = Font.Color (getColor)
+END 'FontBorderIssues' Symbol
+ TEST OK : FontBorderIssues
+----------------------------------------------------------------
+RangeSizeIssues
+ TEST START : RangeSizeIssues
+ ITEM Assertion OK : Range.Left is: 118.8432
+ ITEM Assertion OK : Range.Top is: 92.16585
+ ITEM Assertion OK : Range.Width is: 226.2
+ ITEM Assertion OK : Range.Height is: 271.5
+END 'RangeSizeIssues' Symbol
+ TEST OK : RangeSizeIssues
+----------------------------------------------------------------
+ApplicationIssues
+ TEST START : ApplicationIssues
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Application.ActiveSheet.Name: Sheet1
+END 'ApplicationIssues' Symbol
+ TEST OK : ApplicationIssues
+Test run finished : 19/06/2007 11:14:02
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-3.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-3.log
new file mode 100644
index 000000000000..a130737ceb65
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges-3.log
@@ -0,0 +1,8 @@
+Test run started : 19/06/2007 11:26:09
+----------------------------------------------------------------
+MyGoalseek-Issue
+ TEST START : MyGoalseek-Issue
+ ITEM Assertion OK : Variable Range value: 15
+END 'MyGoalseek-Issue' Symbol
+ TEST OK : MyGoalseek-Issue
+Test run finished : 19/06/2007 11:26:10
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges.log
new file mode 100644
index 000000000000..cdd18685e977
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Ranges.log
@@ -0,0 +1,280 @@
+Test run started : 10/03/2008 15:15:11
+----------------------------------------------------------------
+ApplicationMethods
+ TEST START : ApplicationMethods
+ ITEM Assertion OK : Name of Workbook is: Ranges.xls
+ ITEM Assertion OK : Address of Application.Columns is: $A:$A
+ ITEM Assertion OK : Address of Application.Rows is: $1:$1
+ ITEM Assertion OK : Address of Application.Range is: $1:$1,$5:$7
+ ITEM Assertion OK : Please check manually: DefaultFilePath is: /data4/home/npower/Documents
+ ITEM Assertion OK : Please check manually: Library Path is: /data4/home/npower/.ooo-2.0/user/basic
+ ITEM Assertion OK : Please check manually: Template Path is: /data4/home/npower/.ooo-2.0/user/template
+ ITEM Assertion OK : FileSeparator is /
+ ITEM Assertion OK : Name of ActiveWorkbook is: Ranges.xls
+END 'ApplicationMethods' Symbol
+ TEST OK : ApplicationMethods
+----------------------------------------------------------------
+Insert-Issue
+ TEST START : Insert-Issue
+ ITEM Assertion OK : Insert with xlShiftToRight: 10
+END 'Insert-Issue' Symbol
+ TEST OK : Insert-Issue
+----------------------------------------------------------------
+MergeCells-Issue
+ TEST START : MergeCells-Issue
+ ITEM Assertion OK : Range.MergeCells is True
+ ITEM Assertion FAIL : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 13
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion FAIL : MergeCells of Second Area is null : False
+ ITEM Assertion FAIL : MergeCells of Ranges is Null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+END 'MergeCells-Issue' Symbol
+ TEST OK : MergeCells-Issue
+----------------------------------------------------------------
+Areas-Issue
+ TEST START : Areas-Issue
+ ITEM Assertion OK : Range Areas Count is2
+ ITEM Assertion OK : First Range Address is: $E$8:$G$13
+ ITEM Assertion OK : First Row is: 8
+ ITEM Assertion OK : First Column is: 5
+ ITEM Assertion OK : EntireRow Address is: $8:$13,$13:$19
+ ITEM Assertion OK : EntireColumn Address is: $E:$G,$G:$K
+ ITEM Assertion OK : Range Count:53
+END 'Areas-Issue' Symbol
+ TEST OK : Areas-Issue
+----------------------------------------------------------------
+Fill-Methods-Issue
+ TEST START : Fill-Methods-Issue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyRightFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyBottomFillValue
+END 'Fill-Methods-Issue' Symbol
+ TEST OK : Fill-Methods-Issue
+----------------------------------------------------------------
+Range/Item-Method-Issue
+ TEST START : Range/Item-Method-Issue
+ ITEM Assertion OK : Range of multiple columns is: $A:$A,$C:$C
+ ITEM Assertion OK : Range of multiple rows is: $1:$1,$5:$7
+ ITEM Assertion OK : Range of several columns is: $C:$E,$D:$D
+ ITEM Assertion OK : Range of several rows is: $5:$8,$6:$10
+ ITEM Assertion OK : Range of several single cells is: $C$5,$E$8
+ ITEM Assertion OK : Range of several named ranges is: $L$1:$M$6,$E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range of a single Item Cell is: $E$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$10
+END 'Range/Item-Method-Issue' Symbol
+ TEST OK : Range/Item-Method-Issue
+----------------------------------------------------------------
+R1C1-Formulas-Issue
+ TEST START : R1C1-Formulas-Issue
+ ITEM Assertion OK : R1C1 Range.Formula is: =IF(OR(R[-2]C[1]=0,RC[2]="YES"),"")
+ ITEM Assertion OK : Range.Formula is: =IF(OR(J8=0,K10="YES"),"")
+END 'R1C1-Formulas-Issue' Symbol
+ TEST OK : R1C1-Formulas-Issue
+----------------------------------------------------------------
+Verify_Delete
+ TEST START : Verify_Delete
+ ITEM Assertion OK : Ranges are intersecting: $G$13
+ ITEM Assertion OK : Delete with Default: $AJ$4
+ ITEM Assertion OK : Delete with ShifttoLeft: $AJ$4
+ ITEM Assertion OK : Delete with ShiftUp: $M$22
+END 'Verify_Delete' Symbol
+ TEST OK : Verify_Delete
+----------------------------------------------------------------
+Value-Issue
+ TEST START : Value-Issue
+ ITEM Assertion OK : Value of Range is: 12.3
+ ITEM Assertion OK : Text of Range is: 12.3
+ ITEM Assertion OK : Range has Formula: False
+ ITEM Assertion OK : Cell has Formula: False
+ ITEM Assertion FAIL : Text of Range is null: False
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Cell has Formula: True
+ ITEM Assertion OK : Value of Cell is: 12
+ ITEM Assertion OK : Application.Calculation is : -4135
+ ITEM Assertion OK : Calculation is automated: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Value of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Range has Formula after 'ClearContents: False
+ ITEM Assertion OK : Text of Cell is:
+ ITEM Assertion OK : Text of Cell is:
+END 'Value-Issue' Symbol
+ TEST OK : Value-Issue
+----------------------------------------------------------------
+AutoFit issue
+ TEST START : AutoFit issue
+ ITEM Assertion OK : Columns.AutoFit: CurrentWidth is 680
+ ITEM Assertion OK : Rows.AutoFit: CurrentHeight is 554
+END 'AutoFit issue' Symbol
+ TEST OK : AutoFit issue
+----------------------------------------------------------------
+Selections
+ TEST START : Selections
+ ITEM Assertion OK : ActiveCell is : $E$8
+ ITEM Assertion OK : Active Cell is : $E$8
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+END 'Selections' Symbol
+ TEST OK : Selections
+----------------------------------------------------------------
+Offset-Resize
+ TEST START : Offset-Resize
+ ITEM Assertion OK : Offset is : $G$10:$I$15,$I$15:$M$21
+ ITEM Assertion OK : Offset is : $G$7:$I$12,$I$12:$M$18
+ ITEM Assertion OK : Resized Range is : $A$20:$D$23
+END 'Offset-Resize' Symbol
+ TEST OK : Offset-Resize
+----------------------------------------------------------------
+Ranges-Address
+ TEST START : Ranges-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: $E8:$G13,$G13:$K19
+ ITEM Assertion OK : Range Address is: E$8:G$13,G$13:K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5],R[11]C[5]:R[17]C[9]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13,$G$13:$K$19
+END 'Ranges-Address' Symbol
+ TEST OK : Ranges-Address
+----------------------------------------------------------------
+Range-Address
+ TEST START : Range-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: $E8:$G13
+ ITEM Assertion OK : Range Address is: E$8:G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13
+END 'Range-Address' Symbol
+ TEST OK : Range-Address
+----------------------------------------------------------------
+Column-Address
+ TEST START : Column-Address
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: $F8:$F13
+ ITEM Assertion OK : Range Address is: F$8:F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion FAIL : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R[6]C[4]:R[11]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$8:$F$13
+END 'Column-Address' Symbol
+ TEST OK : Column-Address
+----------------------------------------------------------------
+Row-Address
+ TEST START : Row-Address
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: $E9:$G9
+ ITEM Assertion OK : Range Address is: E$9:G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion FAIL : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R[7]C[3]:R[7]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$9:$G$9
+END 'Row-Address' Symbol
+ TEST OK : Row-Address
+----------------------------------------------------------------
+SingleCell-Address
+ TEST START : SingleCell-Address
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: $F9
+ ITEM Assertion OK : Range Address is: F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion FAIL : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R[7]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$9
+END 'SingleCell-Address' Symbol
+ TEST OK : SingleCell-Address
+----------------------------------------------------------------
+Heights and Widths
+ TEST START : Heights and Widths
+ ITEM Assertion OK : Range RowHeight is 40
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 240
+ ITEM Assertion OK : Range Width is 795
+ ITEM Assertion OK : Range RowHeight is 50
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 300
+ ITEM Assertion OK : Range Width is 795
+ ITEM Assertion OK : RowHeight is null: True
+ ITEM Assertion OK : ColumnWidth is null: True
+END 'Heights and Widths' Symbol
+ TEST OK : Heights and Widths
+----------------------------------------------------------------
+RangeRowColumn-Issue
+ TEST START : RangeRowColumn-Issue
+ ITEM Assertion OK : Row is: 8
+ ITEM Assertion OK : Column is: 5
+ ITEM Assertion OK : EntireRow.Columns.Count = 256
+ ITEM Assertion OK : EntireColumn.Rows.Count = 131072
+END 'RangeRowColumn-Issue' Symbol
+ TEST OK : RangeRowColumn-Issue
+----------------------------------------------------------------
+Replace-Issue
+ TEST START : Replace-Issue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New Replace
+ ITEM Assertion OK : Value after Replace:
+END 'Replace-Issue' Symbol
+ TEST OK : Replace-Issue
+----------------------------------------------------------------
+Hidden-Issue
+ TEST START : Hidden-Issue
+ ITEM Assertion OK : - Range.Rows.Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Hidden (get)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (get)
+END 'Hidden-Issue' Symbol
+ TEST OK : Hidden-Issue
+----------------------------------------------------------------
+End issue
+ TEST START : End issue
+ ITEM Assertion OK : - = $E$48
+ ITEM Assertion OK : - = $E$1
+ ITEM Assertion OK : - = $E$3
+ ITEM Assertion OK : - = $A$8
+ ITEM Assertion OK : - = $B$8
+ ITEM Assertion OK : - = $IV$8
+ ITEM Assertion OK : - = $Z$8
+END 'End issue' Symbol
+ TEST OK : End issue
+----------------------------------------------------------------
+Outline issue
+ TEST START : Outline issue
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+END 'Outline issue' Symbol
+ TEST OK : Outline issue
+----------------------------------------------------------------
+Validation
+ TEST START : Validation
+ ITEM Assertion OK : Validation Input Message is : Attention!
+ ITEM Assertion OK : Validation Input Message is : Enter an integer from five to ten
+ ITEM Assertion OK : Validation Error Title is : You must enter a number from five to ten
+ ITEM Assertion OK : Validation Error Message is : An Error occured
+ ITEM Assertion OK : Validation Error Title is : Microsoft Excel
+END 'Validation' Symbol
+ TEST OK : Validation
+Test run finished : 10/03/2008 15:15:13
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Shapes.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Shapes.log
new file mode 100644
index 000000000000..3193a0b1094d
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Shapes.log
@@ -0,0 +1,77 @@
+Test run started : 10/16/2007 05:25:21 PM
+BEGIN Shapes_Collection_Behaviour
+ TEST START : Shapes_Collection_Behaviour
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape1'
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape2'
+ TEST Success. : Shapes_Collection_Behaviour
+END Shapes_Collection_Behaviour
+BEGIN Shapes_Select_Item
+ TEST START : Shapes_Select_Item
+ ITEM Assertion OK : Correctly selected shape through Range
+ ITEM Assertion OK : Correctly selected shape through Item
+ ITEM Assertion OK : Needs to be visually checked. Is there a line on the document?
+ ITEM Assertion OK : Needs to be visually checked. Are All Shapes Selected?
+ TEST Success. : Shapes_Select_Item
+END Shapes_Select_Item
+BEGIN Shapes_Fill
+ TEST START : Shapes_Fill
+ ITEM Assertion OK : correctly set visibility of shape fill
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set backcolor of shape fill
+ ITEM Assertion OK : the success of the TwoColorGradient method needs to be verified visually!
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set forecolor of shape fill
+ TEST Success. : Shapes_Fill
+END Shapes_Fill
+BEGIN Shapes_Line
+ TEST START : Shapes_Line
+ ITEM Assertion FAIL : correctly set weight of shape line
+ ITEM Assertion OK : correctly set visibility of shape line
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set forecolor of shape line
+ ITEM Assertion FAIL : correctly set backcolor of shape line
+ TEST Success. : Shapes_Line
+END Shapes_Line
+BEGIN Shapes_TextFrame
+ TEST START : Shapes_TextFrame
+ ITEM Assertion OK : correctly set Autosize of Shape TextFrame
+ TEST Success. : Shapes_TextFrame
+END Shapes_TextFrame
+BEGIN Shapes_SimpleGeometry
+ TEST START : Shapes_SimpleGeometery
+ ITEM Assertion OK : shape height should be 47.0425168477155 and got 46.9984222363199
+ ITEM Assertion OK : shape width should be 101.467710269751 and got 101.423615658355
+ ITEM Assertion OK : shape left should be 68.5574761223637 and got 68.5417279658754
+ ITEM Assertion OK : shape top should be 42.0251943291216 and got 42.0094461726333
+ ITEM Assertion OK : shape rotation should be 0 and got 0
+ ITEM Assertion OK : shape rotation should be 25 and got 25
+ ITEM Assertion OK : shape incrementrotation should be 50 and got 50
+ ITEM Assertion OK : shape incrementleft should be 70.6834602404119 and got 70.6677120839236
+ ITEM Assertion OK : shape incrementtop should be 91.262986503119 and got 91.2472383466307
+ TEST Success. : Shapes_SimpleGeometery
+END Shapes_SimpleGeometry
+BEGIN Shapes_Range
+ TEST START : Shapes_Range
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to return Sheet2Shape1 got Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to return Sheet2Shape3 got Sheet2Shape3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to contain 2 elements, it contains 2
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to return concated element/shape names Sheet2Shape3Sheet2Shape1 and got Sheet2Shape3Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to contain 3 elements, it contains 3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to return concated element/shape names Sheet2Shape3Sheet2Shape1Sheet2Shape2 and got Sheet2Shape3Sheet2Shape1Sheet2Shape2
+ TEST Success. : Shapes_Range
+END Shapes_Range
+BEGIN Shapes_ShapeRange
+ TEST START : Shapes_ShapeRange
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp1.left should be 90.6677120839236 and got 90.6519627935771
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp2.left should be 240.02518299054 and got 240.009433700193
+ ITEM Assertion OK : ShapeRange.IncrementTop shp1.Top should be 111.247238346631 and got 111.231489056284
+ ITEM Assertion OK : ShapeRange.IncrementTop shp2.Top should be 65.0708633026228 and got 65.0551140122763
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp1.Rotation should be 70 and got 70
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp2.Rotation should be 20 and got 20
+END Shapes_ShapeRange
+Test run finished : 10/16/2007 05:25:22 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/StrConv-test.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/StrConv-test.log
new file mode 100644
index 000000000000..c7a7d8750583
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/StrConv-test.log
@@ -0,0 +1,9 @@
+Test run started : 05/29/2008 02:51:03 PM
+BEGIN StrConv
+ TEST START : Test StrConv function
+ ITEM Assertion OK : Converts the string to uppercase characters:ABC EFG HIJ
+ ITEM Assertion OK : Converts the string to lowercase characters:abc efg hij
+ ITEM Assertion OK : Converts the first letter of every word in string to uppercase:Abc Efg Hij
+ TEST OK : Test StrConv function
+END StrConv
+Test run finished : 05/29/2008 02:51:03 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Template.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Template.log
new file mode 100644
index 000000000000..c6376c5b3732
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Template.log
@@ -0,0 +1,14 @@
+Test run started : 2008ï¼07ï¼10 11:57:05
+----------------------------------------------------------------
+TestCaseName
+ TEST START : TestCaseName
+ ITEM Assertion OK : Something has been done.
+Test Results
+============
+
+Tests passed: 1
+Tests failed: 0
+
+END 'TestCaseName
+ TEST OK : TestCaseName
+Test run finished : 2008ï¼07ï¼10 11:57:05
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestAddress.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestAddress.log
new file mode 100644
index 000000000000..4fa4bc820f59
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestAddress.log
@@ -0,0 +1,67 @@
+Test run started : 12/05/2009 11:23:35
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 Range('e3:f3') A1 style addressing
+ ITEM Assertion OK : test2 Range('e3:f3') R1C1 style addressing
+ ITEM Assertion OK : test3 Range ('e:f') A1 style addressing
+ ITEM Assertion OK : test4 Range ('e:f') R1C1 style addressing
+ ITEM Assertion OK : test5 Columns A1 style addressing
+ ITEM Assertion OK : test6 Columns R1C1 style addressing
+ ITEM Assertion OK : test7 Columns(3) A1 style addressing
+ ITEM Assertion OK : test8 Columns(3) R1C1 style addressing
+ ITEM Assertion OK : test9 Columns('e') A1 style addressing
+ ITEM Assertion OK : test10 Columns('e') R1C1 style addressing
+ ITEM Assertion OK : test11 Columns('b:d') A1 style addressing
+ ITEM Assertion OK : test12 Columns('b:d') R1C1 style addressing
+ ITEM Assertion OK : test13 Range('c1:g10').Columns A1 style addressing
+ ITEM Assertion OK : test14 Range('c1:g10').Columns R1C1 style addressing
+ ITEM Assertion OK : test15 Range('c1:g10').Columns(1) A1 style addressing
+ ITEM Assertion OK : test16 Range('c1:g10').Columns(1) R1C1 style addressing
+ ITEM Assertion OK : test17 Range('c1:g10').Columns('a') A1 style addressing
+ ITEM Assertion OK : test18 Range('c1:g10').Columns('a') R1C1 style addressing
+ ITEM Assertion OK : test19 Range('c1:g10').Columns('c') A1 style addressing
+ ITEM Assertion OK : test20 Range('c1:g10').Columns('c') R1C1 style addressing
+ ITEM Assertion OK : test21 Range('c1:g10').Columns('x:z') A1 style addressing
+ ITEM Assertion OK : test22 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test23 Range('c1:g10').Columns(30) A1 style addressing
+ ITEM Assertion OK : test24 Range('c1:g10').Columns(30) R1C1 style addressing
+ ITEM Assertion OK : test25 Worksheets('Sheet2').Cells(1, 1) A1 style addressing
+ ITEM Assertion OK : test26 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, RowAddressAbsolute is false
+ ITEM Assertion OK : test27 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, ColAddressAbsolute is false
+ ITEM Assertion OK : test28 Worksheets('Sheet2').Cells(1, 1) R1C1 style addressing
+ ITEM Assertion OK : test29 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test30 Worksheets('Sheet2').Range('A1').EntireColumn A1 style addressing
+ ITEM Assertion OK : test31 Worksheets('Sheet2').Range('A1:E5').EntireRow A1 style addressing
+ ITEM Assertion OK : test32 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test33 Worksheets('Sheet2').Range('IV65536').EntireRow A1 style addressing
+ ITEM Assertion OK : test34 Worksheets('Sheet2').Range('IU2:IV65536') A1 style addressing
+ ITEM Assertion OK : test35 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test36 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test37 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test38 Worksheets('Sheet2').Range('10:12') A1 style addressing
+ ITEM Assertion OK : test39 Worksheets('Sheet2').Range('10:12') R1C1 style addressing
+ ITEM Assertion OK : test40 Range('Sheet3!A1:B4') A1 style addressing
+ ITEM Assertion OK : test41 Range('Sheet3!A1,B1,D4:F20') A1 style addressing
+ ITEM Assertion OK : test42 Range('g20:h40').Columns('c:c')
+ ITEM Assertion OK : test43 Range('g20:h40').Columns('c:f')
+ ITEM Assertion OK : test44 Range('g20:h40').Columns(-1)
+ ITEM Assertion OK : test45 Range('c4:g10').Rows(-1)
+ ITEM Assertion OK : test46 Range('a2:b4').Rows('1:1')
+ ITEM Assertion OK : test47 Range('a2:b4').Rows('1:2')
+ ITEM Assertion OK : test48 Range('a2:b4').Rows('2:2')
+ ITEM Assertion OK : test49 Range('a2:b4').Rows('2:3')
+ ITEM Assertion OK : test50 Range(' A2:B4 ')
+ ITEM Assertion OK : test51 Range('A 2:B 4')
+ ITEM Assertion OK : test52 Range('A2 : B4 ')
+ ITEM Assertion OK : test53 Range('Sheet1 !A2 : B4 ')
+ ITEM Assertion OK : test54 Range('Sheet1! A2 : B4 ')
+Test Results
+============
+
+Tests passed: 54
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 12/05/2009 11:23:35
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest.log
new file mode 100644
index 000000000000..083819d4b64e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest.log
@@ -0,0 +1,60 @@
+Test run started : 30/05/2007 15:59:40
+BEGIN TestCalc
+ TEST START : RangeTest2
+ ITEM Assertion OK : - Range("D15").Row
+ ITEM Assertion OK : - WorkSheet("D15").Range.Row
+ ITEM Assertion OK : - Range("D15").Column
+ ITEM Assertion OK : - Worksheet.Range("D15").Column
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Columns.Count
+ ITEM Assertion OK : - Range("D1").EntireColumn.Rows.Count
+ ITEM Assertion OK : - Range("D15").ClearContent
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (get)
+ ITEM Assertion OK : - Range("B38").Orientation (get)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlDownward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlUpward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B39").WrapText (get)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (get)
+ ITEM Assertion OK : - Range("F39").MergeCells (get)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion FAIL : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("D41:D42").Replace MatchCase:=False
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM FAIL (RangeTest2)
+ TEST Not succesfully completed : RangeTest2
+END TestCalc
+Test run finished : 30/05/2007 15:59:42
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest2.log
new file mode 100644
index 000000000000..b1573c06d90e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestCalc_Rangetest2.log
@@ -0,0 +1,65 @@
+Test run started : 10/03/2008 15:15:19
+BEGIN TestCalc
+ TEST START : RangeTest3
+ ITEM Assertion OK : - setFormulaR1C1
+ ITEM Assertion OK : - getFormulaR1C1
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy(Range("I10"))
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteValues
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormulas
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormats
+ ITEM Assertion OK : PasteSpecial
+ ITEM Assertion OK : PasteSpecial SkipBlanks:=True
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationAdd
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationSubtract
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationMultiply
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationDivide
+ ITEM Assertion OK : PasteSpecial Transpose:=True
+ ITEM Assertion FAIL : ActiveWorkbook.FileFormat
+ ITEM Assertion OK : ActiveWorkbook.Name
+ ITEM Assertion OK : ActiveWorkbook.FullName und ActiveWorkbook.Path
+ ITEM Assertion FAIL : - = ActiveWorkbook.Colors(3) set
+ ITEM Assertion OK : - = ActiveWorkbook.ResetColors
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) get
+ ITEM Assertion OK : - = Range("K22").End (xlDown)
+ ITEM Assertion OK : - = Range("K22").End (xlUo)
+ ITEM Assertion OK : - = Range("K22").End (xlToLeft)
+ ITEM Assertion OK : - = Range("K22").End (xlRight)
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="x"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="<>"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="="
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter
+ ITEM Assertion OK : - ActiveSheet.Resize.Select
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion FAIL : - Application.GoTo Reference:="R[8]C[2]"
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Ungroup- please check visually
+ ITEM Assertion OK : - Range.Ungroup - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - ActiveSheet.UsedRange.Select
+ ITEM Assertion OK : - Range("A13").AddIndent
+ ITEM Assertion OK : - Range("A13").IndentLevel set
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Calculate
+ ITEM Assertion OK : Worksheet.Calculate
+ ITEM Assertion OK : - Application.Calculate
+ ITEM Assertion OK : Global.Calculate
+ ITEM Assertion OK : Calculation set
+ ITEM FAIL (RangeTest3)
+ TEST Not succesfully completed : RangeTest3
+END TestCalc
+Test run finished : 10/03/2008 15:15:21
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestIntersection.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestIntersection.log
new file mode 100644
index 000000000000..ea686a830cde
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestIntersection.log
@@ -0,0 +1,26 @@
+Test run started : 13/01/2009 14:31:43
+----------------------------------------------------------------
+TestIntersection
+ TEST START : TestIntersection
+ ITEM Assertion OK : test1 Application.Intersect( Range('A2:D10'), Range('C4:E6'))
+ ITEM Assertion OK : test2 Application.Intersect( Range('A2:D10'), Range('A4:G10'))
+ ITEM Assertion OK : test3 Application.Intersect( Range('A2:c8,d2:f8,g2:i8'), Range('A4:G10'))
+ ITEM Assertion OK : test4 Application.Intersect( Range('A4:G10'), Range('A2:c8,d2:f8,g2:i8'))
+ ITEM Assertion OK : test5 Application.Intersect( Range('A2:c8,d2:f8,g2:i8'), Range('g4:i10,A4:G10'))
+ ITEM Assertion OK : test6 Application.Intersect( Range('g4:i10,A4:G10'), Range('A2:c8,d2:f8,g2:i8'))
+ ITEM Assertion OK : test7 Application.Intersect( Range('a2:d10,b5:e10'), Range('a5:i10'))
+ ITEM Assertion OK : test8 Application.Intersect( Range('a2:c8,d2:f8'), Range('b6:e9,a6:f9'))
+ ITEM Assertion OK : test9 Application.Intersect( Range('a2:c8,e2:f8'), Range('b6:e9,a6:f9'))
+ ITEM Assertion OK : test10 Application.Intersect( Range('a1:a3,c1:c3'), Range('a2:c3'))
+ ITEM Assertion OK : test11 Application.Intersect( Range('a1:a3,b1:b3'), Range('a2:c3'))
+ ITEM Assertion OK : test12 Application.Intersect( Range('a2:d5,b3:f7,c1:g4'), Range('b2:e6'))
+ ITEM Assertion OK : test13 Range(" a2:d10,b5:e10,g13:j32 "), Range(" a5:i10,b6:e9 "), Range("b2:r5,f10:h19")
+Test Results
+============
+
+Tests passed: 13
+Tests failed: 0
+
+END 'TestIntersection
+ TEST OK : TestIntersection
+Test run finished : 13/01/2009 14:31:43
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestUnion.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestUnion.log
new file mode 100644
index 000000000000..da3cb35dedb3
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/TestUnion.log
@@ -0,0 +1,17 @@
+Test run started : 13/01/2009 14:32:16
+----------------------------------------------------------------
+TestUnion
+ TEST START : TestUnion
+ ITEM Assertion OK : test1Application.Range('A2:D10'), Range('C4:E6')
+ ITEM Assertion OK : test2Application.Range('A2:D5,a3:d4'), Range('A4:G10')
+ ITEM Assertion OK : test3Application.Range('A4:G10,A1:B6'), Range('A2:D5,A3:D4')
+ ITEM Assertion OK : test4Application.Range('A5:D10'), Range('B5:E10')
+Test Results
+============
+
+Tests passed: 4
+Tests failed: 0
+
+END 'TestUnion
+ TEST OK : TestUnion
+Test run finished : 13/01/2009 14:32:16
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/VariantTest.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/VariantTest.log
new file mode 100644
index 000000000000..a916ac4a37fd
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/VariantTest.log
@@ -0,0 +1,47 @@
+Test run started : 24/09/2008 10:58:18
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1: res = (aboo = '')
+ ITEM Assertion OK : test 2: res = (aboo = 'fiddlesticks')
+ ITEM Assertion OK : test 3: res = ('' = aboo)
+ ITEM Assertion OK : test 4: res = ('fiddlesticks' = aboo )
+ ITEM Assertion OK : test 5: res = (testString = '')
+ ITEM Assertion OK : test 6: res = (testString = 'fiddlesticks')
+ ITEM Assertion OK : test 7: res = ('' = testString)
+ ITEM Assertion OK : test 8: res = ('fiddlesticks' = testString )
+ ITEM Assertion OK : test 9: res = ( aboo < " )
+ ITEM Assertion OK : test 10: res = ( testString < " )
+ ITEM Assertion OK : test 11: res = ( aboo > " )
+ ITEM Assertion OK : test 12: res = ( testString > " )
+ ITEM Assertion OK : test 13: res = ( aboo <> '' )
+ ITEM Assertion OK : test 14: res = ( testString <> '' )
+ ITEM Assertion OK : test 15: res = (aboo = something/14)
+ ITEM Assertion OK : test 16: res = something + 'string'
+ ITEM Assertion OK : test 17: res = something & 'string'
+ ITEM Assertion OK : test 18: res = something MOD 10 )
+ ITEM Assertion OK : test 19: res = something AND 1 )
+ ITEM Assertion OK : test 20: res = something AND 0 )
+ ITEM Assertion OK : test 21: res = something OR 12)
+ ITEM Assertion OK : test 22: res = something OR 0 )
+ ITEM Assertion OK : test 23: res = something XOR 0 )
+ ITEM Assertion OK : test 24: res = something XOR 1 )
+ ITEM Assertion OK : test 25: res = something EQV 0 )
+ ITEM Assertion OK : test 26: res = something EQV 1 )
+ ITEM Assertion OK : test 27: res = something IMP 0 )
+ ITEM Assertion OK : test 28: res = something IMP 1 )
+ ITEM Assertion OK : test 29: res = something IMP 14 )
+ ITEM Assertion OK : test 30: res = NOT something )
+ ITEM Assertion OK : test 31: res = something + 12 )
+ ITEM Assertion OK : test 32: res = something - 12 )
+ ITEM Assertion OK : test 33: res = -something )
+ ITEM Assertion OK : test 34: res = something * 12 )
+Test Results
+============
+
+Tests passed: 34
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 24/09/2008 10:58:20
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Window.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Window.log
new file mode 100644
index 000000000000..ec9a6656113e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/Window.log
@@ -0,0 +1,46 @@
+Test run started : 05/29/2008 02:55:00 PM
+----------------------------------------------------------------
+ TEST START : Window-Issue
+ ITEM Assertion OK : Window.Left is: 0 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Top is: 21 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Width is: 1280 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Height is: 752 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.ScrollColumn is: 100
+ ITEM Assertion OK : Window.ScrollColumn is: 1
+ ITEM Assertion OK : Window.ScrollRow is: 100
+ ITEM Assertion OK : Window.ScrollRow is: 1
+ ITEM Assertion OK : Window.LargeScroll(Down): ScrollRow is: 94 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.LargeScroll(Up): ScrollRow is: 1
+ ITEM Assertion OK : Window.LargeScroll(ToRight): ScrollColumn is: 58 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.LargeScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window.SmallScroll(ToRight): ScrollColumn is: 4 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.SmallScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window.DisplayWorkBookTabs is: False
+ ITEM Assertion OK : Window.DisplayWorkBookTabs is: True
+ ITEM Assertion OK : Window.DisplayVerticalScrollBar is: True
+ ITEM Assertion OK : Window.DisplayVerticalScrollBar is: False
+ ITEM Assertion OK : Window.DisplayHorizontalScrollBar is: False
+ ITEM Assertion OK : Window.DisplayHorizontalScrollBar is: True
+ ITEM Assertion OK : Window.DisplayHeadings is: False
+ ITEM Assertion OK : Window.DisplayHeadings is: True
+ ITEM Assertion OK : Window.DisplayOutline is: False
+ ITEM Assertion OK : Window.DisplayOutline is: True
+ ITEM Assertion OK : Window.Visible is: False
+ ITEM Assertion OK : Window.Visible is: True
+ ITEM Assertion OK : Window.Caption is: MyCaption
+ ITEM Assertion OK : Pane.ScrollColumn is: 100
+ ITEM Assertion OK : Pane.ScrollColumn is: 1
+ ITEM Assertion OK : Pane.ScrollRow is: 100
+ ITEM Assertion OK : Pane.ScrollRow is: 1
+ ITEM Assertion OK : Pane.LargeScroll(Down): ScrollRow is: 94 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.LargeScroll(Up): ScrollRow is: 1
+ ITEM Assertion OK : Pane.LargeScroll(ToRight): ScrollColumn is: 58 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.LargeScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Pane.SmallScroll(ToRight): ScrollColumn is: 4 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.SmallScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window Selection: $A$2:$D$5
+ ITEM Assertion OK : ActiveSheet name of Window: Sheet1
+ ITEM Assertion OK : Window ActiveCell: $A$1
+END 'Window-Issue' Symbol
+ TEST OK : Window-Issue
+Test run finished : 05/29/2008 02:55:01 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/bytearraystring.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/bytearraystring.log
new file mode 100644
index 000000000000..bd243283d8f1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/bytearraystring.log
@@ -0,0 +1,8 @@
+Test run started : 05/29/2008 02:25:58 PM
+BEGIN Bytearray To String
+ TEST START : Test the conversion between bytearray and string
+ ITEM Assertion OK : The number of byte is:6
+ ITEM Assertion OK : the return string is: abc
+ TEST OK : Test the conversion between bytearray and string
+END Bytearray To String
+Test run finished : 05/29/2008 02:25:58 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/dateserial.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/dateserial.log
new file mode 100644
index 000000000000..4dd5f53160f2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/dateserial.log
@@ -0,0 +1,9 @@
+Test run started : 01/24/2008 01:24:50 PM
+BEGIN DateSerial
+ TEST START : Test DateSerial function
+ ITEM Assertion OK : the return date is: 06/15/1999
+ ITEM Assertion OK : the return date is: 06/15/1999
+ ITEM Assertion OK : the return date is: 06/15/1999
+ TEST OK : Test DateSerial function
+END DateSerial
+Test run finished : 01/24/2008 01:24:50 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/datevalue.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/datevalue.log
new file mode 100644
index 000000000000..830d5e7b6c3e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/datevalue.log
@@ -0,0 +1,8 @@
+Test run started : 01/24/2008 01:24:41 PM
+BEGIN DateValue
+ TEST START : Test DateValue function
+ ITEM Assertion OK : the return date is: 02/12/1969
+ ITEM Assertion OK : the return date is: 01/21/2008
+ TEST OK : Test DateValue function
+END DateValue
+Test run finished : 01/24/2008 01:24:41 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/format.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/format.log
new file mode 100644
index 000000000000..96725bf7daa8
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/format.log
@@ -0,0 +1,36 @@
+Test run started : 2008ï¼09ï¼18 11:35:34
+BEGIN Format
+ TEST START : Test Predefined_Number_Format_Sample function
+ ITEM Assertion OK : General Number: 562486.2356
+ ITEM Assertion OK : Fixed: 0.20
+ ITEM Assertion OK : Standard: 562,486.24
+ ITEM Assertion OK : Percent: 75.21%
+ ITEM Assertion OK : Scientific: 5.62E+05
+ ITEM Assertion OK : Scientific: -3.46E+03
+ ITEM Assertion OK : Yes/No: No
+ ITEM Assertion OK : Yes/No: Yes
+ ITEM Assertion OK : True/False: False
+ ITEM Assertion OK : True/False: True
+ ITEM Assertion OK : On/Off: Off
+ ITEM Assertion OK : On/Off: On
+ TEST OK : Test Predefined_Number_Format_Sample function
+ TEST START : Test Custom_Number_Format_Sample function
+ ITEM Assertion OK : 00.0000: 23.6750
+ ITEM Assertion OK : 00.00: 23.68
+ ITEM Assertion OK : 00000: 02658
+ ITEM Assertion OK : 00.00: 2658.00
+ ITEM Assertion OK : ##.####: 23.675
+ ITEM Assertion OK : ##.##: 23.68
+ ITEM Assertion OK : #,###.##: 12,345.25
+ ITEM Assertion OK : ##.00%: 25.00%
+ ITEM Assertion OK : #,###: 1,000,000
+ ITEM Assertion OK : ######E-###: 109838E-5
+ ITEM Assertion OK : $#,###.##: $2,345.25
+ ITEM Assertion OK : ##.###\%: .25%
+ TEST OK : Test Custom_Number_Format_Sample function
+ TEST START : Test Custom_Text_Format_Sample function
+ ITEM Assertion OK : <: vba
+ ITEM Assertion OK : >: VBA
+ TEST OK : Test Custom_Text_Format_Sample function
+END Format
+Test run finished : 2008ï¼09ï¼18 11:35:34
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/pagesetup.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/pagesetup.log
new file mode 100644
index 000000000000..f04585c3f9e1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/pagesetup.log
@@ -0,0 +1,77 @@
+Test run started : 07/21/2008 02:00:06 PM
+BEGIN PageSetup
+ TEST START : Sheet_PrintArea
+ ITEM Assertion OK : PrintArea has changed as expected
+ TEST OK : Sheet_PrintArea
+ TEST START : Test margins (no headers)
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.RightMargin set/get
+ ITEM Assertion OK : PageSetup.TopMargin set/get
+ ITEM Assertion OK : PageSetup.BottomMargin set/get
+Verify that page margins on sheet 1 are all 0.5inch
+ TEST OK : Test margins (no headers)
+ TEST START : Test margins (headers)
+ ITEM Assertion OK : PageSetup.HeaderMargin set/get
+ ITEM Assertion OK : PageSetup.FooterMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+Verify that top/bottom/header/footer page margins on sheet 2 are all 0.5inch
+ TEST OK : Test margins (headers)
+ TEST START : Test header/footer text
+ ITEM Assertion OK : PageSetup.LeftHeader set
+ ITEM Assertion OK : PageSetup.LeftHeader set/get
+ ITEM Assertion OK : PageSetup.CenterHeader set
+ ITEM Assertion OK : PageSetup.CenterHeader set/get
+ ITEM Assertion OK : PageSetup.RightHeader set
+ ITEM Assertion OK : PageSetup.RightHeader set/get
+ ITEM Assertion OK : PageSetup.LeftFooter set
+ ITEM Assertion OK : PageSetup.LeftFooter set/get
+ ITEM Assertion OK : PageSetup.CenterFooter set
+ ITEM Assertion OK : PageSetup.CenterFooter set/get
+ ITEM Assertion OK : PageSetup.RightFooter set
+ ITEM Assertion OK : PageSetup.RightFooter set/get
+Verify that headers on sheet 2 are Ready,to,go
+Verify that footers on sheet 2 are This,now,Works
+ TEST OK : Test header/footer text
+ TEST START : Test zoom
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Zoom set/get
+Verify that sheet 1 zoom is 10%
+ TEST OK : Test zoom
+ TEST START : Test orientation
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Orientation set/get
+Verify that sheet 1 orientation is now landscape
+ TEST OK : Test orientation
+ TEST START : Test order
+ ITEM Assertion OK : PageSetup.Order get
+ ITEM Assertion OK : PageSetup.Order set/get
+Verify that order on sheet 1 is now over, then down.
+ TEST OK : Test order
+ TEST START : Test first page number
+ ITEM Assertion OK : PageSetup.FirstPageNumber get
+ ITEM Assertion OK : PageSetup.FirstPageNumber set/get
+Verify that first page number on sheet 1 is now 2.
+ TEST OK : Test first page number
+ TEST START : Test center vertically
+ ITEM Assertion OK : PageSetup.CenterVertically get
+ ITEM Assertion OK : PageSetup.CenterVertically set/get
+Verify that CenterVertically on sheet 1 is now true.
+ TEST OK : Test center vertically
+ TEST START : Test center horizontally
+ ITEM Assertion OK : PageSetup.CenterHorizontally get
+ ITEM Assertion OK : PageSetup.CenterHorizontally set/get
+Verify that CenterHorizontally on sheet 1 is now true.
+ TEST OK : Test center horizontally
+ TEST START : Test FitToPagesTall
+ ITEM Assertion OK : PageSetup.FitToPagesTall set/get
+ TEST OK : Test FitToPagesTall
+ TEST START : Test FitToPagesWide
+ ITEM Assertion OK : PageSetup.FitToPagesWide set/get
+ TEST OK : Test FitToPagesWide
+ TEST START : Test PrintHeadings
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ TEST OK : Test PrintHeadings
+END PageSetup
+Test run finished : 07/21/2008 02:00:07 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/partition.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/partition.log
new file mode 100644
index 000000000000..7b4f2a01bead
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/partition.log
@@ -0,0 +1,11 @@
+Test run started : 12/10/2007 11:26:43 AM
+BEGIN Partition
+ TEST START : Test Partition function
+ ITEM Assertion OK : the number 20 occurs in the range:20:24
+ ITEM Assertion OK : the number 20 occurs in the range: 20: 20
+ ITEM Assertion OK : the number 120 occurs in the range:100:
+ ITEM Assertion OK : the number -5 occurs in the range: : -1
+ ITEM Assertion OK : the number 2 occurs in the range: 2: 3
+ TEST OK : Test Partition function
+END Partition
+Test run finished : 12/10/2007 11:26:43 AM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/range-4.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/range-4.log
new file mode 100644
index 000000000000..fb37b6ff201b
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/range-4.log
@@ -0,0 +1,16 @@
+Test run started : 2008ï¼06ï¼19 17:14:57
+----------------------------------------------------------------
+ShowDetail-Issue
+ TEST START : ShowDetail-Issue
+ ITEM Assertion OK : Range.ShowDetail is True
+ ITEM Assertion OK : Range.ShowDetail is False
+END 'ShowDetail-Issue' Symbol
+ TEST OK : ShowDetail-Issue
+----------------------------------------------------------------
+RangeMerged-Issue
+ TEST START : RangeMerged-Issue
+ ITEM Assertion OK : Range.RangeMerged is $F$2:$H$5
+ ITEM Assertion OK : The first address of Range.RangeMerged is $F$2
+END 'RangeMerged-Issue' Symbol
+ TEST OK : RangeMerged-Issue
+Test run finished : 2008ï¼06ï¼19 17:14:57
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/replace.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/replace.log
new file mode 100644
index 000000000000..8f600faaa6b1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/replace.log
@@ -0,0 +1,14 @@
+Test run started : 09/05/2008 10:21:46 AM
+BEGIN Replace
+ TEST START : Test Replace function
+ ITEM Assertion OK : common string:aefefdBc
+ ITEM Assertion OK : expression string:aefefdef
+ ITEM Assertion OK : binanary compare:aefefdBc
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : start = 3:cefdBc
+ ITEM Assertion OK : count = 2: aefefdBc
+ ITEM Assertion OK : start = 1, count = 0, not support in Unix: abcbcdBc
+ TEST OK : Test Replace function
+END Replace
+Test run finished : 09/05/2008 10:21:47 AM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/stringplusdouble.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/stringplusdouble.log
new file mode 100644
index 000000000000..6e8b8d994bd1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/stringplusdouble.log
@@ -0,0 +1,62 @@
+Test run started : 05/29/2008 02:51:22 PM
+BEGIN String Plus Double
+ TEST START : double = string + double
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: 0
+The next compute raises error: s = null, d = 20, r = s + d
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 100
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 30
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = null, r = s & d
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s & d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: -1
+ TEST OK : double = string + double
+ TEST START : string = string + double
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: 0
+The next compute raises error: s = null, d = 20, r = s + d
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 100
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 30
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: abc0
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: abc20
+ TEST OK : string = string + double
+ TEST START : double = string + string
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+The next compute raises error: s = null, d = null, r = s & d
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: 20
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 10
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 1020
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = null, r = s & d
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s & d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: -1
+ TEST OK : double = string + string
+END String Plus Double
+Test run finished : 05/29/2008 02:51:22 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/window2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/window2.log
new file mode 100644
index 000000000000..8e26d0580621
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/unix/window2.log
@@ -0,0 +1,41 @@
+Test run started : 2008ï¼09ï¼22 11:18:57
+BEGIN Window2
+ TEST START : Test Window.SplitRow
+ ITEM Assertion OK : Test SplitColumn: 2 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitRow: 2 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitVertical: 242.465788476212
+ ITEM Assertion OK : Test SplitHorizontal: 242.465788476212
+ ITEM Assertion OK : Test SplitRow: 4 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitColumn: 3 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitColumn: 0
+ ITEM Assertion OK : Test SplitRow: 0
+ TEST OK : Test Window.SplitRow
+ TEST START : Test Window.DisplayGridlines
+ ITEM Assertion OK : Test gridlines are on
+ ITEM Assertion OK : Test gridlines are off
+ TEST OK : Test Window.DisplayGridlines
+ TEST START : Test Window.DisplayHeadings
+ ITEM Assertion OK : Test Headings are on
+ ITEM Assertion OK : Test Headings are off
+ TEST OK : Test Window.DisplayHeadings
+ TEST START : Test Window.Visibility
+ ITEM Assertion OK : Window is visible
+ ITEM Assertion OK : Window is not visible
+ TEST OK : Test Window.Visibility
+ TEST START : Test Window.FreezePanes
+ ITEM Assertion OK : Test no panes frozen
+ ITEM Assertion OK : Test panes frozen at center
+ ITEM Assertion OK : Test panes frozen at split
+ TEST OK : Test Window.FreezePanes
+ TEST START : Test Window.View
+ TEST OK : Test Window.View
+ TEST START : Test Window.Zoom
+ ITEM Assertion OK : Test zoom=100%
+ ITEM Assertion OK : Test zoom=150%
+ TEST OK : Test Window.Zoom
+ TEST START : Test Windows.Count
+ ITEM Assertion OK : Windows Count: 1
+ ITEM Assertion OK : Application.Windows Count: 1
+ TEST OK : Test Windows.Count
+END Window2
+Test run finished : 2008ï¼09ï¼22 11:18:58
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/AutoFilter.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/AutoFilter.log
new file mode 100644
index 000000000000..b8d0b85a8ff9
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/AutoFilter.log
@@ -0,0 +1,20 @@
+Test run started : 16/10/2007 17:42:01
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 'starts with' string criteria
+ ITEM Assertion OK : test2 'not equal to' string criteria
+ ITEM Assertion OK : test3 'ends with' string criteria
+ ITEM Assertion OK : test4 field 'all'
+ ITEM Assertion OK : test5 numeric '<15'
+ ITEM Assertion OK : test6 numeric '>=15'
+ ITEM Assertion OK : test7 numeric '<=12'
+Test Results
+============
+
+Tests passed: 7
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 16/10/2007 17:42:02
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/CalcFont.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/CalcFont.log
new file mode 100644
index 000000000000..e8695523a0a1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/CalcFont.log
@@ -0,0 +1,17 @@
+Test run started : 15/01/2009 17:00:35
+CalcFont_Format
+ TEST START : Font_Format
+ ITEM Assertion OK : correctly set font to Bold
+ ITEM Assertion OK : correctly set font to Italic
+ ITEM Assertion OK : correctly read FontStyle
+ ITEM Assertion OK : correctly set font to Shadow
+ ITEM Assertion OK : correctly set font color
+ ITEM Assertion OK : correctly set font color index
+ ITEM Assertion OK : correctly set font name
+ ITEM Assertion OK : correctly set font outline
+ ITEM Assertion OK : correctly set font size
+ ITEM Assertion OK : correctly set font strikethrough
+ ITEM Assertion OK : correctly set font underline
+ TEST Success. : Font_Format
+CalcFont_Format
+Test run finished : 15/01/2009 17:00:36
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscOperatorTests.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscOperatorTests.log
new file mode 100644
index 000000000000..3ccec0a1577d
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscOperatorTests.log
@@ -0,0 +1,29 @@
+Test run started : 15/01/2009 17:03:13
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1: res = Not ( A > B )
+ ITEM Assertion OK : test2: res = Not ( B > A )
+ ITEM Assertion OK : test3: res = Not ( D )
+ ITEM Assertion OK : test4: res = Not A
+ ITEM Assertion OK : test5: res = ( A > D )
+ ITEM Assertion OK : test6: res = ( D > A )
+ ITEM Assertion OK : test7: res = ( A < D )
+ ITEM Assertion OK : test8: res = ( D < A )
+ ITEM Assertion OK : test9: res = ( A >= D )
+ ITEM Assertion OK : test10: res = ( D >= A )
+ ITEM Assertion OK : test11: res = ( A <= D )
+ ITEM Assertion OK : test12: res = ( D <= A )
+ ITEM Assertion OK : test13: res = ( D = A )
+ ITEM Assertion OK : test14: res = ( A = D )
+ ITEM Assertion OK : test15: res = ( D <> A )
+ ITEM Assertion OK : test16: res = ( A <> D )
+Test Results
+============
+
+Tests passed: 16
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 15/01/2009 17:03:15
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscRangeTests.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscRangeTests.log
new file mode 100644
index 000000000000..d190abb5f645
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/MiscRangeTests.log
@@ -0,0 +1,45 @@
+Test run started : 17/07/2007 15:08:56
+----------------------------------------------------------------
+MiscRangeTests
+ TEST START : MiscRangeTests
+ ITEM Assertion OK : test 1
+ ITEM Assertion OK : test 2
+ ITEM Assertion OK : test 3
+ ITEM Assertion OK : test 4
+ ITEM Assertion OK : test 5
+ ITEM Assertion OK : test 6
+ ITEM Assertion OK : test 7
+ ITEM Assertion OK : test 8
+ ITEM Assertion OK : test 9
+ ITEM Assertion OK : test 10
+ ITEM Assertion OK : test 11
+ ITEM Assertion OK : test 12
+ ITEM Assertion OK : test 13
+ ITEM Assertion OK : test 14
+ ITEM Assertion OK : test 15
+ ITEM Assertion OK : test 16
+ ITEM Assertion OK : test 17
+ ITEM Assertion OK : test 18
+ ITEM Assertion OK : test 19
+ ITEM Assertion OK : test 20
+ ITEM Assertion OK : test 21
+ ITEM Assertion OK : test 22
+ ITEM Assertion OK : test 23
+ ITEM Assertion OK : test 24
+ ITEM Assertion OK : test 25
+ ITEM Assertion OK : test 26
+ ITEM Assertion OK : test 27
+ ITEM Assertion OK : test 28
+ ITEM Assertion OK : test 29
+ ITEM Assertion OK : test 30
+ ITEM Assertion OK : test 31
+No. tests: 31
+Summary
+=======
+Run: 31
+Passed: 31
+Failed: 0
+
+END 'MiscRangeTests
+ TEST OK : MiscRangeTests
+Test run finished : 17/07/2007 15:08:59
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/PageBreaks.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/PageBreaks.log
new file mode 100644
index 000000000000..30b6e45d1681
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/PageBreaks.log
@@ -0,0 +1,10 @@
+Test run started : 08/10/2008 12:02:12
+----------------------------------------------------------------
+ TEST START : PageBreaks-Issue
+ ITEM Assertion OK : HPageBreaks.Count is 3
+ ITEM Assertion OK : HPageBreak.Type is -4135
+ ITEM Assertion OK : HPageBreak.Location: Range.Row is 5
+ ITEM Assertion OK : HPageBreak.Delete: HPageBreaks.Count is 2
+END 'PageBreaks-Issue' Symbol
+ TEST OK : PageBreaks-Issue
+Test run finished : 08/10/2008 12:02:12
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-2.log
new file mode 100644
index 000000000000..b80d996e3d3f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-2.log
@@ -0,0 +1,68 @@
+Test run started : 10/07/2007 01:55:47
+----------------------------------------------------------------
+ClearFormtsIssue
+ TEST START : ClearFormtsIssue
+ ITEM Assertion OK : Range.Font.Bold is: True
+ ITEM Assertion OK : Range.Font.Bold is: False
+END 'ClearFormtsIssue' Symbol
+ TEST OK : ClearFormtsIssue
+----------------------------------------------------------------
+VerticalAlignment-Issue
+ TEST START : VerticalAlignment-Issue
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : Range.VeritcalAlignment is Null
+END 'VerticalAlignment-Issue' Symbol
+ TEST OK : VerticalAlignment-Issue
+----------------------------------------------------------------
+HorizontalAlignment-Issue
+ TEST START : HorizontalAlignment-Issue
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : Range.HorizontalAlignment is Null
+END 'HorizontalAlignment-Issue' Symbol
+ TEST OK : HorizontalAlignment-Issue
+----------------------------------------------------------------
+WrapText-Issue
+ TEST START : WrapText-Issue
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : Range.WrapText is Null
+END 'WrapText-Issue' Symbol
+ TEST OK : WrapText-Issue
+----------------------------------------------------------------
+FontBorderIssues
+ TEST START : FontBorderIssues
+ ITEM Assertion OK : - = Borders.Color (getColor)
+ ITEM Assertion OK : - = Font.Color (getColor)
+END 'FontBorderIssues' Symbol
+ TEST OK : FontBorderIssues
+----------------------------------------------------------------
+RangeSizeIssues
+ TEST START : RangeSizeIssues
+ ITEM Assertion OK : Range.Left is: 100.5291
+ ITEM Assertion OK : Range.Top is: 95.39775
+ ITEM Assertion OK : Range.Width is: 191.25
+ ITEM Assertion OK : Range.Height is: 271.5
+END 'RangeSizeIssues' Symbol
+ TEST OK : RangeSizeIssues
+----------------------------------------------------------------
+ApplicationIssues
+ TEST START : ApplicationIssues
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Application.ActiveSheet.Name: Sheet1
+END 'ApplicationIssues' Symbol
+ TEST OK : ApplicationIssues
+Test run finished : 10/07/2007 01:55:48
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-3.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-3.log
new file mode 100644
index 000000000000..365d126a7e2d
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges-3.log
@@ -0,0 +1,8 @@
+Test run started : 10/07/2007 01:55:51
+----------------------------------------------------------------
+MyGoalseek-Issue
+ TEST START : MyGoalseek-Issue
+ ITEM Assertion OK : Variable Range value: 15
+END 'MyGoalseek-Issue' Symbol
+ TEST OK : MyGoalseek-Issue
+Test run finished : 10/07/2007 01:55:51
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges.log
new file mode 100644
index 000000000000..6491fe4173ec
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Ranges.log
@@ -0,0 +1,280 @@
+Test run started : 08/10/2008 11:30:21
+----------------------------------------------------------------
+ApplicationMethods
+ TEST START : ApplicationMethods
+ ITEM Assertion OK : Name of Workbook is: Ranges.xls
+ ITEM Assertion OK : Address of Application.Columns is: $A:$A
+ ITEM Assertion OK : Address of Application.Rows is: $1:$1
+ ITEM Assertion OK : Address of Application.Range is: $1:$1,$5:$7
+ ITEM Assertion OK : Please check manually: DefaultFilePath is: C:\Documents and Settings\vituosity\My Documents
+ ITEM Assertion OK : Please check manually: Library Path is: C:\Documents and Settings\vituosity\Application Data\OpenOffice.org\3\user\basic
+ ITEM Assertion OK : Please check manually: Template Path is: C:\Documents and Settings\vituosity\Application Data\OpenOffice.org\3\user\template
+ ITEM Assertion OK : FileSeparator is \
+ ITEM Assertion OK : Name of ActiveWorkbook is: Ranges.xls
+END 'ApplicationMethods' Symbol
+ TEST OK : ApplicationMethods
+----------------------------------------------------------------
+Insert-Issue
+ TEST START : Insert-Issue
+ ITEM Assertion OK : Insert with xlShiftToRight: 10
+END 'Insert-Issue' Symbol
+ TEST OK : Insert-Issue
+----------------------------------------------------------------
+MergeCells-Issue
+ TEST START : MergeCells-Issue
+ ITEM Assertion OK : Range.MergeCells is True
+ ITEM Assertion FAIL : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 13
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion FAIL : MergeCells of Second Area is null : False
+ ITEM Assertion FAIL : MergeCells of Ranges is Null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+END 'MergeCells-Issue' Symbol
+ TEST OK : MergeCells-Issue
+----------------------------------------------------------------
+Areas-Issue
+ TEST START : Areas-Issue
+ ITEM Assertion OK : Range Areas Count is2
+ ITEM Assertion OK : First Range Address is: $E$8:$G$13
+ ITEM Assertion OK : First Row is: 8
+ ITEM Assertion OK : First Column is: 5
+ ITEM Assertion OK : EntireRow Address is: $8:$13,$13:$19
+ ITEM Assertion OK : EntireColumn Address is: $E:$G,$G:$K
+ ITEM Assertion OK : Range Count:53
+END 'Areas-Issue' Symbol
+ TEST OK : Areas-Issue
+----------------------------------------------------------------
+Fill-Methods-Issue
+ TEST START : Fill-Methods-Issue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyRightFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyBottomFillValue
+END 'Fill-Methods-Issue' Symbol
+ TEST OK : Fill-Methods-Issue
+----------------------------------------------------------------
+Range/Item-Method-Issue
+ TEST START : Range/Item-Method-Issue
+ ITEM Assertion OK : Range of multiple columns is: $A:$A,$C:$C
+ ITEM Assertion OK : Range of multiple rows is: $1:$1,$5:$7
+ ITEM Assertion OK : Range of several columns is: $C:$E,$D:$D
+ ITEM Assertion OK : Range of several rows is: $5:$8,$6:$10
+ ITEM Assertion OK : Range of several single cells is: $C$5,$E$8
+ ITEM Assertion OK : Range of several named ranges is: $L$1:$M$6,$E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range of a single Item Cell is: $E$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$10
+END 'Range/Item-Method-Issue' Symbol
+ TEST OK : Range/Item-Method-Issue
+----------------------------------------------------------------
+R1C1-Formulas-Issue
+ TEST START : R1C1-Formulas-Issue
+ ITEM Assertion OK : R1C1 Range.Formula is: =IF(OR(R[-2]C[1]=0,RC[2]="YES"),"")
+ ITEM Assertion OK : Range.Formula is: =IF(OR(J8=0,K10="YES"),"")
+END 'R1C1-Formulas-Issue' Symbol
+ TEST OK : R1C1-Formulas-Issue
+----------------------------------------------------------------
+Verify_Delete
+ TEST START : Verify_Delete
+ ITEM Assertion OK : Ranges are intersecting: $G$13
+ ITEM Assertion OK : Delete with Default: $AJ$4
+ ITEM Assertion OK : Delete with ShifttoLeft: $AJ$4
+ ITEM Assertion OK : Delete with ShiftUp: $M$22
+END 'Verify_Delete' Symbol
+ TEST OK : Verify_Delete
+----------------------------------------------------------------
+Value-Issue
+ TEST START : Value-Issue
+ ITEM Assertion OK : Value of Range is: 12.3
+ ITEM Assertion OK : Text of Range is: 12.3
+ ITEM Assertion OK : Range has Formula: False
+ ITEM Assertion OK : Cell has Formula: False
+ ITEM Assertion FAIL : Text of Range is null: False
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Cell has Formula: True
+ ITEM Assertion OK : Value of Cell is: 12
+ ITEM Assertion OK : Application.Calculation is : -4135
+ ITEM Assertion OK : Calculation is automated: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Value of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Range has Formula after 'ClearContents: False
+ ITEM Assertion OK : Text of Cell is:
+ ITEM Assertion OK : Text of Cell is:
+END 'Value-Issue' Symbol
+ TEST OK : Value-Issue
+----------------------------------------------------------------
+AutoFit issue
+ TEST START : AutoFit issue
+ ITEM Assertion OK : Columns.AutoFit: CurrentWidth is 680
+ ITEM Assertion OK : Rows.AutoFit: CurrentHeight is 582
+END 'AutoFit issue' Symbol
+ TEST OK : AutoFit issue
+----------------------------------------------------------------
+Selections
+ TEST START : Selections
+ ITEM Assertion OK : ActiveCell is : $E$8
+ ITEM Assertion OK : Active Cell is : $E$8
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+END 'Selections' Symbol
+ TEST OK : Selections
+----------------------------------------------------------------
+Offset-Resize
+ TEST START : Offset-Resize
+ ITEM Assertion OK : Offset is : $G$10:$I$15,$I$15:$M$21
+ ITEM Assertion OK : Offset is : $G$7:$I$12,$I$12:$M$18
+ ITEM Assertion OK : Resized Range is : $A$20:$D$23
+END 'Offset-Resize' Symbol
+ TEST OK : Offset-Resize
+----------------------------------------------------------------
+Ranges-Address
+ TEST START : Ranges-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: $E8:$G13,$G13:$K19
+ ITEM Assertion OK : Range Address is: E$8:G$13,G$13:K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5],R[11]C[5]:R[17]C[9]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13,$G$13:$K$19
+END 'Ranges-Address' Symbol
+ TEST OK : Ranges-Address
+----------------------------------------------------------------
+Range-Address
+ TEST START : Range-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: $E8:$G13
+ ITEM Assertion OK : Range Address is: E$8:G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13
+END 'Range-Address' Symbol
+ TEST OK : Range-Address
+----------------------------------------------------------------
+Column-Address
+ TEST START : Column-Address
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: $F8:$F13
+ ITEM Assertion OK : Range Address is: F$8:F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion FAIL : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R[6]C[4]:R[11]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$8:$F$13
+END 'Column-Address' Symbol
+ TEST OK : Column-Address
+----------------------------------------------------------------
+Row-Address
+ TEST START : Row-Address
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: $E9:$G9
+ ITEM Assertion OK : Range Address is: E$9:G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion FAIL : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R[7]C[3]:R[7]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$9:$G$9
+END 'Row-Address' Symbol
+ TEST OK : Row-Address
+----------------------------------------------------------------
+SingleCell-Address
+ TEST START : SingleCell-Address
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: $F9
+ ITEM Assertion OK : Range Address is: F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion FAIL : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R[7]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$9
+END 'SingleCell-Address' Symbol
+ TEST OK : SingleCell-Address
+----------------------------------------------------------------
+Heights and Widths
+ TEST START : Heights and Widths
+ ITEM Assertion OK : Range RowHeight is 40
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 240
+ ITEM Assertion FAIL : Range Width is 675
+ ITEM Assertion OK : Range RowHeight is 50
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 300
+ ITEM Assertion FAIL : Range Width is 675
+ ITEM Assertion OK : RowHeight is null: True
+ ITEM Assertion OK : ColumnWidth is null: True
+END 'Heights and Widths' Symbol
+ TEST OK : Heights and Widths
+----------------------------------------------------------------
+RangeRowColumn-Issue
+ TEST START : RangeRowColumn-Issue
+ ITEM Assertion OK : Row is: 8
+ ITEM Assertion OK : Column is: 5
+ ITEM Assertion OK : EntireRow.Columns.Count = 1024
+ ITEM Assertion OK : EntireColumn.Rows.Count = 131072
+END 'RangeRowColumn-Issue' Symbol
+ TEST OK : RangeRowColumn-Issue
+----------------------------------------------------------------
+Replace-Issue
+ TEST START : Replace-Issue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New Replace
+ ITEM Assertion OK : Value after Replace:
+END 'Replace-Issue' Symbol
+ TEST OK : Replace-Issue
+----------------------------------------------------------------
+Hidden-Issue
+ TEST START : Hidden-Issue
+ ITEM Assertion OK : - Range.Rows.Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Hidden (get)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (get)
+END 'Hidden-Issue' Symbol
+ TEST OK : Hidden-Issue
+----------------------------------------------------------------
+End issue
+ TEST START : End issue
+ ITEM Assertion OK : - = $E$48
+ ITEM Assertion OK : - = $E$1
+ ITEM Assertion OK : - = $E$3
+ ITEM Assertion OK : - = $A$8
+ ITEM Assertion OK : - = $B$8
+ ITEM Assertion OK : - = $AMJ$8
+ ITEM Assertion OK : - = $Z$8
+END 'End issue' Symbol
+ TEST OK : End issue
+----------------------------------------------------------------
+Outline issue
+ TEST START : Outline issue
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+END 'Outline issue' Symbol
+ TEST OK : Outline issue
+----------------------------------------------------------------
+Validation
+ TEST START : Validation
+ ITEM Assertion OK : Validation Input Message is : Attention!
+ ITEM Assertion OK : Validation Input Message is : Enter an integer from five to ten
+ ITEM Assertion OK : Validation Error Title is : You must enter a number from five to ten
+ ITEM Assertion OK : Validation Error Message is : An Error occured
+ ITEM Assertion OK : Validation Error Title is : Microsoft Excel
+END 'Validation' Symbol
+ TEST OK : Validation
+Test run finished : 08/10/2008 11:30:24
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Shapes.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Shapes.log
new file mode 100644
index 000000000000..fe62ab03d3f2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Shapes.log
@@ -0,0 +1,77 @@
+Test run started : 16/10/2007 17:46:03
+BEGIN Shapes_Collection_Behaviour
+ TEST START : Shapes_Collection_Behaviour
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape1'
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape2'
+ TEST Success. : Shapes_Collection_Behaviour
+END Shapes_Collection_Behaviour
+BEGIN Shapes_Select_Item
+ TEST START : Shapes_Select_Item
+ ITEM Assertion OK : Correctly selected shape through Range
+ ITEM Assertion OK : Correctly selected shape through Item
+ ITEM Assertion OK : Needs to be visually checked. Is there a line on the document?
+ ITEM Assertion OK : Needs to be visually checked. Are All Shapes Selected?
+ TEST Success. : Shapes_Select_Item
+END Shapes_Select_Item
+BEGIN Shapes_Fill
+ TEST START : Shapes_Fill
+ ITEM Assertion OK : correctly set visibility of shape fill
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set backcolor of shape fill
+ ITEM Assertion OK : the success of the TwoColorGradient method needs to be verified visually!
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set forecolor of shape fill
+ TEST Success. : Shapes_Fill
+END Shapes_Fill
+BEGIN Shapes_Line
+ TEST START : Shapes_Line
+ ITEM Assertion FAIL : correctly set weight of shape line
+ ITEM Assertion OK : correctly set visibility of shape line
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set forecolor of shape line
+ ITEM Assertion FAIL : correctly set backcolor of shape line
+ TEST Success. : Shapes_Line
+END Shapes_Line
+BEGIN Shapes_TextFrame
+ TEST START : Shapes_TextFrame
+ ITEM Assertion OK : correctly set Autosize of Shape TextFrame
+ TEST Success. : Shapes_TextFrame
+END Shapes_TextFrame
+BEGIN Shapes_SimpleGeometry
+ TEST START : Shapes_SimpleGeometery
+ ITEM Assertion OK : shape height should be 49.4519655148368 and got 49.4078709034412
+ ITEM Assertion OK : shape width should be 101.467710269751 and got 101.423615658355
+ ITEM Assertion OK : shape left should be 68.5574761223637 and got 68.5417279658754
+ ITEM Assertion OK : shape top should be 44.1511784471699 and got 44.1354302906816
+ ITEM Assertion OK : shape rotation should be 0 and got 0
+ ITEM Assertion OK : shape rotation should be 25 and got 25
+ ITEM Assertion OK : shape incrementrotation should be 50 and got 50
+ ITEM Assertion OK : shape incrementleft should be 69.7480272284707 and got 69.7322790719824
+ ITEM Assertion OK : shape incrementtop should be 93.8141674447769 and got 93.7984192882885
+ TEST Success. : Shapes_SimpleGeometery
+END Shapes_SimpleGeometry
+BEGIN Shapes_Range
+ TEST START : Shapes_Range
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to return Sheet2Shape1 got Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to return Sheet2Shape3 got Sheet2Shape3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to contain 2 elements, it contains 2
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to return concated element/shape names Sheet2Shape3Sheet2Shape1 and got Sheet2Shape3Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to contain 3 elements, it contains 3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to return concated element/shape names Sheet2Shape3Sheet2Shape1Sheet2Shape2 and got Sheet2Shape3Sheet2Shape1Sheet2Shape2
+ TEST Success. : Shapes_Range
+END Shapes_Range
+BEGIN Shapes_ShapeRange
+ TEST START : Shapes_ShapeRange
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp1.left should be 89.7322790719824 and got 89.7165297816359
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp2.left should be 240.02518299054 and got 240.009433700193
+ ITEM Assertion OK : ShapeRange.IncrementTop shp1.Top should be 113.798419288289 and got 113.782669997942
+ ITEM Assertion OK : ShapeRange.IncrementTop shp2.Top should be 67.4519655148368 and got 67.4362162244903
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp1.Rotation should be 70 and got 70
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp2.Rotation should be 20 and got 20
+END Shapes_ShapeRange
+Test run finished : 16/10/2007 17:46:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/StrConv-test.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/StrConv-test.log
new file mode 100644
index 000000000000..b1f7794234f9
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/StrConv-test.log
@@ -0,0 +1,9 @@
+Test run started : 08/10/2008 12:04:16
+BEGIN StrConv
+ TEST START : Test StrConv function
+ ITEM Assertion OK : Converts the string to uppercase characters:ABC EFG HIJ
+ ITEM Assertion OK : Converts the string to lowercase characters:abc efg hij
+ ITEM Assertion OK : Converts the first letter of every word in string to uppercase:Abc Efg Hij
+ TEST OK : Test StrConv function
+END StrConv
+Test run finished : 08/10/2008 12:04:16
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Template.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Template.log
new file mode 100644
index 000000000000..774994adb02c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Template.log
@@ -0,0 +1,14 @@
+Test run started : 08/10/2008 12:05:52
+----------------------------------------------------------------
+TestCaseName
+ TEST START : TestCaseName
+ ITEM Assertion OK : Something has been done.
+Test Results
+============
+
+Tests passed: 1
+Tests failed: 0
+
+END 'TestCaseName
+ TEST OK : TestCaseName
+Test run finished : 08/10/2008 12:05:52
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestAddress.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestAddress.log
new file mode 100644
index 000000000000..0007e6f9c958
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestAddress.log
@@ -0,0 +1,67 @@
+Test run started : 08/10/2008 11:30:32
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 Range('e3:f3') A1 style addressing
+ ITEM Assertion OK : test2 Range('e3:f3') R1C1 style addressing
+ ITEM Assertion OK : test3 Range ('e:f') A1 style addressing
+ ITEM Assertion OK : test4 Range ('e:f') R1C1 style addressing
+ ITEM Assertion OK : test5 Columns A1 style addressing
+ ITEM Assertion OK : test6 Columns R1C1 style addressing
+ ITEM Assertion OK : test7 Columns(3) A1 style addressing
+ ITEM Assertion OK : test8 Columns(3) R1C1 style addressing
+ ITEM Assertion OK : test9 Columns('e') A1 style addressing
+ ITEM Assertion OK : test10 Columns('e') R1C1 style addressing
+ ITEM Assertion OK : test11 Columns('b:d') A1 style addressing
+ ITEM Assertion OK : test12 Columns('b:d') R1C1 style addressing
+ ITEM Assertion OK : test13 Range('c1:g10').Columns A1 style addressing
+ ITEM Assertion OK : test14 Range('c1:g10').Columns R1C1 style addressing
+ ITEM Assertion OK : test15 Range('c1:g10').Columns(1) A1 style addressing
+ ITEM Assertion OK : test16 Range('c1:g10').Columns(1) R1C1 style addressing
+ ITEM Assertion OK : test17 Range('c1:g10').Columns('a') A1 style addressing
+ ITEM Assertion OK : test18 Range('c1:g10').Columns('a') R1C1 style addressing
+ ITEM Assertion OK : test19 Range('c1:g10').Columns('c') A1 style addressing
+ ITEM Assertion OK : test20 Range('c1:g10').Columns('c') R1C1 style addressing
+ ITEM Assertion OK : test21 Range('c1:g10').Columns('x:z') A1 style addressing
+ ITEM Assertion OK : test22 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test23 Range('c1:g10').Columns(30) A1 style addressing
+ ITEM Assertion OK : test24 Range('c1:g10').Columns(30) R1C1 style addressing
+ ITEM Assertion OK : test25 Worksheets('Sheet2').Cells(1, 1) A1 style addressing
+ ITEM Assertion OK : test26 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, RowAddressAbsolute is false
+ ITEM Assertion OK : test27 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, ColAddressAbsolute is false
+ ITEM Assertion OK : test28 Worksheets('Sheet2').Cells(1, 1) R1C1 style addressing
+ ITEM Assertion OK : test29 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test30 Worksheets('Sheet2').Range('A1').EntireColumn A1 style addressing
+ ITEM Assertion OK : test31 Worksheets('Sheet2').Range('A1:E5').EntireRow A1 style addressing
+ ITEM Assertion OK : test32 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test33 Worksheets('Sheet2').Range('IV65536').EntireRow A1 style addressing
+ ITEM Assertion OK : test34 Worksheets('Sheet2').Range('IU2:IV65536') A1 style addressing
+ ITEM Assertion OK : test35 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test36 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test37 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test38 Worksheets('Sheet2').Range('10:12') A1 style addressing
+ ITEM Assertion OK : test39 Worksheets('Sheet2').Range('10:12') R1C1 style addressing
+ ITEM Assertion OK : test40 Range('Sheet3!A1:B4') A1 style addressing
+ ITEM Assertion OK : test41 Range('Sheet3!A1,B1,D4:F20') A1 style addressing
+ ITEM Assertion OK : test42 Range('g20:h40').Columns('c:c')
+ ITEM Assertion OK : test43 Range('g20:h40').Columns('c:f')
+ ITEM Assertion OK : test44 Range('g20:h40').Columns(-1)
+ ITEM Assertion OK : test45 Range('c4:g10').Rows(-1)
+ ITEM Assertion OK : test46 Range('a2:b4').Rows('1:1')
+ ITEM Assertion OK : test47 Range('a2:b4').Rows('1:2')
+ ITEM Assertion OK : test48 Range('a2:b4').Rows('2:2')
+ ITEM Assertion OK : test49 Range('a2:b4').Rows('2:3')
+ ITEM Assertion OK : test50 Range(' A2:B4 ')
+ ITEM Assertion OK : test51 Range('A 2:B 4')
+ ITEM Assertion OK : test52 Range('A2 : B4 ')
+ ITEM Assertion OK : test53 Range('Sheet1 !A2 : B4 ')
+ ITEM Assertion OK : test54 Range('Sheet1! A2 : B4 ')
+Test Results
+============
+
+Tests passed: 54
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 08/10/2008 11:30:32
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest.log
new file mode 100644
index 000000000000..492c24bc023c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest.log
@@ -0,0 +1,60 @@
+Test run started : 10/07/2007 01:56:07
+BEGIN TestCalc
+ TEST START : RangeTest2
+ ITEM Assertion OK : - Range("D15").Row
+ ITEM Assertion OK : - WorkSheet("D15").Range.Row
+ ITEM Assertion OK : - Range("D15").Column
+ ITEM Assertion OK : - Worksheet.Range("D15").Column
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Columns.Count
+ ITEM Assertion OK : - Range("D1").EntireColumn.Rows.Count
+ ITEM Assertion OK : - Range("D15").ClearContent
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (get)
+ ITEM Assertion OK : - Range("B38").Orientation (get)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlDownward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlUpward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B39").WrapText (get)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (get)
+ ITEM Assertion OK : - Range("F39").MergeCells (get)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion FAIL : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("D41:D42").Replace MatchCase:=False
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM FAIL (RangeTest2)
+ TEST Not succesfully completed : RangeTest2
+END TestCalc
+Test run finished : 10/07/2007 01:56:12
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest2.log
new file mode 100644
index 000000000000..9159217cb442
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestCalc_Rangetest2.log
@@ -0,0 +1,65 @@
+Test run started : 08/10/2008 11:30:38
+BEGIN TestCalc
+ TEST START : RangeTest3
+ ITEM Assertion OK : - setFormulaR1C1
+ ITEM Assertion OK : - getFormulaR1C1
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy(Range("I10"))
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteValues
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormulas
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormats
+ ITEM Assertion OK : PasteSpecial
+ ITEM Assertion OK : PasteSpecial SkipBlanks:=True
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationAdd
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationSubtract
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationMultiply
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationDivide
+ ITEM Assertion OK : PasteSpecial Transpose:=True
+ ITEM Assertion FAIL : ActiveWorkbook.FileFormat
+ ITEM Assertion OK : ActiveWorkbook.Name
+ ITEM Assertion OK : ActiveWorkbook.FullName und ActiveWorkbook.Path
+ ITEM Assertion FAIL : - = ActiveWorkbook.Colors(3) set
+ ITEM Assertion OK : - = ActiveWorkbook.ResetColors
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) get
+ ITEM Assertion OK : - = Range("K22").End (xlDown)
+ ITEM Assertion OK : - = Range("K22").End (xlUo)
+ ITEM Assertion OK : - = Range("K22").End (xlToLeft)
+ ITEM Assertion OK : - = Range("K22").End (xlRight)
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="x"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="<>"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="="
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter
+ ITEM Assertion OK : - ActiveSheet.Resize.Select
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion FAIL : - Application.GoTo Reference:="R[8]C[2]"
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Ungroup- please check visually
+ ITEM Assertion OK : - Range.Ungroup - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - ActiveSheet.UsedRange.Select
+ ITEM Assertion OK : - Range("A13").AddIndent
+ ITEM Assertion OK : - Range("A13").IndentLevel set
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Calculate
+ ITEM Assertion OK : Worksheet.Calculate
+ ITEM Assertion OK : - Application.Calculate
+ ITEM Assertion OK : Global.Calculate
+ ITEM Assertion OK : Calculation set
+ ITEM FAIL (RangeTest3)
+ TEST Not succesfully completed : RangeTest3
+END TestCalc
+Test run finished : 08/10/2008 11:30:41
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestIntersection.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestIntersection.log
new file mode 100644
index 000000000000..2cf4fe36ea6f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestIntersection.log
@@ -0,0 +1,26 @@
+Test run started : 15/01/2009 17:05:08
+----------------------------------------------------------------
+TestIntersection
+ TEST START : TestIntersection
+ ITEM Assertion OK : test1 Application.Intersect( Range('A2:D10'), Range('C4:E6'))
+ ITEM Assertion OK : test2 Application.Intersect( Range('A2:D10'), Range('A4:G10'))
+ ITEM Assertion OK : test3 Application.Intersect( Range('A2:c8,d2:f8,g2:i8'), Range('A4:G10'))
+ ITEM Assertion OK : test4 Application.Intersect( Range('A4:G10'), Range('A2:c8,d2:f8,g2:i8'))
+ ITEM Assertion OK : test5 Application.Intersect( Range('A2:c8,d2:f8,g2:i8'), Range('g4:i10,A4:G10'))
+ ITEM Assertion OK : test6 Application.Intersect( Range('g4:i10,A4:G10'), Range('A2:c8,d2:f8,g2:i8'))
+ ITEM Assertion OK : test7 Application.Intersect( Range('a2:d10,b5:e10'), Range('a5:i10'))
+ ITEM Assertion OK : test8 Application.Intersect( Range('a2:c8,d2:f8'), Range('b6:e9,a6:f9'))
+ ITEM Assertion OK : test9 Application.Intersect( Range('a2:c8,e2:f8'), Range('b6:e9,a6:f9'))
+ ITEM Assertion OK : test10 Application.Intersect( Range('a1:a3,c1:c3'), Range('a2:c3'))
+ ITEM Assertion OK : test11 Application.Intersect( Range('a1:a3,b1:b3'), Range('a2:c3'))
+ ITEM Assertion OK : test12 Application.Intersect( Range('a2:d5,b3:f7,c1:g4'), Range('b2:e6'))
+ ITEM Assertion OK : test13 Range(" a2:d10,b5:e10,g13:j32 "), Range(" a5:i10,b6:e9 "), Range("b2:r5,f10:h19")
+Test Results
+============
+
+Tests passed: 13
+Tests failed: 0
+
+END 'TestIntersection
+ TEST OK : TestIntersection
+Test run finished : 15/01/2009 17:05:09
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestUnion.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestUnion.log
new file mode 100644
index 000000000000..2382db549554
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/TestUnion.log
@@ -0,0 +1,17 @@
+Test run started : 15/01/2009 17:06:07
+----------------------------------------------------------------
+TestUnion
+ TEST START : TestUnion
+ ITEM Assertion OK : test1Application.Range('A2:D10'), Range('C4:E6')
+ ITEM Assertion OK : test2Application.Range('A2:D5,a3:d4'), Range('A4:G10')
+ ITEM Assertion OK : test3Application.Range('A4:G10,A1:B6'), Range('A2:D5,A3:D4')
+ ITEM Assertion OK : test4Application.Range('A5:D10'), Range('B5:E10')
+Test Results
+============
+
+Tests passed: 4
+Tests failed: 0
+
+END 'TestUnion
+ TEST OK : TestUnion
+Test run finished : 15/01/2009 17:06:08
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/VariantTest.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/VariantTest.log
new file mode 100644
index 000000000000..d2bfeb8e14a1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/VariantTest.log
@@ -0,0 +1,47 @@
+Test run started : 08/10/2008 12:07:24
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1: res = (aboo = '')
+ ITEM Assertion OK : test 2: res = (aboo = 'fiddlesticks')
+ ITEM Assertion OK : test 3: res = ('' = aboo)
+ ITEM Assertion OK : test 4: res = ('fiddlesticks' = aboo )
+ ITEM Assertion OK : test 5: res = (testString = '')
+ ITEM Assertion OK : test 6: res = (testString = 'fiddlesticks')
+ ITEM Assertion OK : test 7: res = ('' = testString)
+ ITEM Assertion OK : test 8: res = ('fiddlesticks' = testString )
+ ITEM Assertion OK : test 9: res = ( aboo < " )
+ ITEM Assertion OK : test 10: res = ( testString < " )
+ ITEM Assertion OK : test 11: res = ( aboo > " )
+ ITEM Assertion OK : test 12: res = ( testString > " )
+ ITEM Assertion OK : test 13: res = ( aboo <> '' )
+ ITEM Assertion OK : test 14: res = ( testString <> '' )
+ ITEM Assertion OK : test 15: res = (aboo = something/14)
+ ITEM Assertion OK : test 16: res = something + 'string'
+ ITEM Assertion OK : test 17: res = something & 'string'
+ ITEM Assertion OK : test 18: res = something MOD 10 )
+ ITEM Assertion OK : test 19: res = something AND 1 )
+ ITEM Assertion OK : test 20: res = something AND 0 )
+ ITEM Assertion OK : test 21: res = something OR 12)
+ ITEM Assertion OK : test 22: res = something OR 0 )
+ ITEM Assertion OK : test 23: res = something XOR 0 )
+ ITEM Assertion OK : test 24: res = something XOR 1 )
+ ITEM Assertion OK : test 25: res = something EQV 0 )
+ ITEM Assertion OK : test 26: res = something EQV 1 )
+ ITEM Assertion OK : test 27: res = something IMP 0 )
+ ITEM Assertion OK : test 28: res = something IMP 1 )
+ ITEM Assertion OK : test 29: res = something IMP 14 )
+ ITEM Assertion OK : test 30: res = NOT something )
+ ITEM Assertion OK : test 31: res = something + 12 )
+ ITEM Assertion OK : test 32: res = something - 12 )
+ ITEM Assertion OK : test 33: res = -something )
+ ITEM Assertion OK : test 34: res = something * 12 )
+Test Results
+============
+
+Tests passed: 34
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 08/10/2008 12:07:26
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Window.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Window.log
new file mode 100644
index 000000000000..178582e753c7
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/Window.log
@@ -0,0 +1,46 @@
+Test run started : 08/10/2008 12:09:50
+----------------------------------------------------------------
+ TEST START : Window-Issue
+ ITEM Assertion OK : Window.Left is: 0 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Top is: 26 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Width is: 1280 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Height is: 968 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.ScrollColumn is: 100
+ ITEM Assertion OK : Window.ScrollColumn is: 1
+ ITEM Assertion OK : Window.ScrollRow is: 100
+ ITEM Assertion OK : Window.ScrollRow is: 1
+ ITEM Assertion OK : Window.LargeScroll(Down): ScrollRow is: 127 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.LargeScroll(Up): ScrollRow is: 1
+ ITEM Assertion OK : Window.LargeScroll(ToRight): ScrollColumn is: 58 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.LargeScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window.SmallScroll(ToRight): ScrollColumn is: 4 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.SmallScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window.DisplayWorkBookTabs is: False
+ ITEM Assertion OK : Window.DisplayWorkBookTabs is: True
+ ITEM Assertion OK : Window.DisplayVerticalScrollBar is: True
+ ITEM Assertion OK : Window.DisplayVerticalScrollBar is: False
+ ITEM Assertion OK : Window.DisplayHorizontalScrollBar is: False
+ ITEM Assertion OK : Window.DisplayHorizontalScrollBar is: True
+ ITEM Assertion OK : Window.DisplayHeadings is: False
+ ITEM Assertion OK : Window.DisplayHeadings is: True
+ ITEM Assertion OK : Window.DisplayOutline is: False
+ ITEM Assertion OK : Window.DisplayOutline is: True
+ ITEM Assertion OK : Window.Visible is: False
+ ITEM Assertion OK : Window.Visible is: True
+ ITEM Assertion OK : Window.Caption is: MyCaption
+ ITEM Assertion OK : Pane.ScrollColumn is: 100
+ ITEM Assertion OK : Pane.ScrollColumn is: 1
+ ITEM Assertion OK : Pane.ScrollRow is: 100
+ ITEM Assertion OK : Pane.ScrollRow is: 1
+ ITEM Assertion OK : Pane.LargeScroll(Down): ScrollRow is: 127 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.LargeScroll(Up): ScrollRow is: 1
+ ITEM Assertion OK : Pane.LargeScroll(ToRight): ScrollColumn is: 58 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.LargeScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Pane.SmallScroll(ToRight): ScrollColumn is: 4 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.SmallScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window Selection: $A$2:$D$5
+ ITEM Assertion OK : ActiveSheet name of Window: Sheet1
+ ITEM Assertion OK : Window ActiveCell: $A$1
+END 'Window-Issue' Symbol
+ TEST OK : Window-Issue
+Test run finished : 08/10/2008 12:09:50
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/bytearraystring.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/bytearraystring.log
new file mode 100644
index 000000000000..8913fc096dc2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/bytearraystring.log
@@ -0,0 +1,8 @@
+Test run started : 08/10/2008 12:54:46
+BEGIN Bytearray To String
+ TEST START : Test the conversion between bytearray and string
+ ITEM Assertion OK : The number of byte is:6
+ ITEM Assertion OK : the return string is: abc
+ TEST OK : Test the conversion between bytearray and string
+END Bytearray To String
+Test run finished : 08/10/2008 12:54:46
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/dateserial.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/dateserial.log
new file mode 100644
index 000000000000..0b02f7b91a2c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/dateserial.log
@@ -0,0 +1,9 @@
+Test run started : 08/10/2008 12:56:07
+BEGIN DateSerial
+ TEST START : Test DateSerial function
+ ITEM Assertion OK : the return date is: 15/06/1999
+ ITEM Assertion OK : the return date is: 15/06/1999
+ ITEM Assertion OK : the return date is: 15/06/1999
+ TEST OK : Test DateSerial function
+END DateSerial
+Test run finished : 08/10/2008 12:56:07
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/datevalue.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/datevalue.log
new file mode 100644
index 000000000000..4698463362d2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/datevalue.log
@@ -0,0 +1,8 @@
+Test run started : 08/10/2008 13:07:49
+BEGIN DateValue
+ TEST START : Test DateValue function
+ ITEM Assertion OK : the return date is: 12/02/1969
+ ITEM Assertion OK : the return date is: 21/01/2008
+ TEST OK : Test DateValue function
+END DateValue
+Test run finished : 08/10/2008 13:07:49
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/format.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/format.log
new file mode 100644
index 000000000000..ef84cbbdb925
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/format.log
@@ -0,0 +1,36 @@
+Test run started : 15/01/2009 17:07:59
+BEGIN Format
+ TEST START : Test Predefined_Number_Format_Sample function
+ ITEM Assertion OK : General Number: 562486.2356
+ ITEM Assertion OK : Fixed: 0.20
+ ITEM Assertion OK : Standard: 562,486.24
+ ITEM Assertion OK : Percent: 75.21%
+ ITEM Assertion OK : Scientific: 5.62E+05
+ ITEM Assertion OK : Scientific: -3.46E+03
+ ITEM Assertion OK : Yes/No: No
+ ITEM Assertion OK : Yes/No: Yes
+ ITEM Assertion OK : True/False: False
+ ITEM Assertion OK : True/False: True
+ ITEM Assertion OK : On/Off: Off
+ ITEM Assertion OK : On/Off: On
+ TEST OK : Test Predefined_Number_Format_Sample function
+ TEST START : Test Custom_Number_Format_Sample function
+ ITEM Assertion OK : 00.0000: 23.6750
+ ITEM Assertion OK : 00.00: 23.68
+ ITEM Assertion OK : 00000: 02658
+ ITEM Assertion OK : 00.00: 2658.00
+ ITEM Assertion OK : ##.####: 23.675
+ ITEM Assertion OK : ##.##: 23.68
+ ITEM Assertion OK : #,###.##: 12,345.25
+ ITEM Assertion OK : ##.00%: 25.00%
+ ITEM Assertion OK : #,###: 1,000,000
+ ITEM Assertion OK : ######E-###: 109838E-5
+ ITEM Assertion OK : $#,###.##: $2,345.25
+ ITEM Assertion OK : ##.###\%: .25%
+ TEST OK : Test Custom_Number_Format_Sample function
+ TEST START : Test Custom_Text_Format_Sample function
+ ITEM Assertion OK : <: vba
+ ITEM Assertion OK : >: VBA
+ TEST OK : Test Custom_Text_Format_Sample function
+END Format
+Test run finished : 15/01/2009 17:07:59
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/pagesetup.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/pagesetup.log
new file mode 100644
index 000000000000..a1c90473ce07
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/pagesetup.log
@@ -0,0 +1,87 @@
+Test run started : 7/21/2008 10:37:24 AM
+BEGIN PageSetup
+ TEST START : Sheet_PrintArea
+ ITEM Assertion OK : PrintArea has changed as expected
+ TEST OK : Sheet_PrintArea
+ TEST START : Test margins (no headers)
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.RightMargin set/get
+ ITEM Assertion OK : PageSetup.TopMargin set/get
+ ITEM Assertion OK : PageSetup.BottomMargin set/get
+Verify that page margins on sheet 1 are all 0.5inch
+ TEST OK : Test margins (no headers)
+ TEST START : Test margins (headers)
+ ITEM Assertion OK : PageSetup.HeaderMargin set/get
+ ITEM Assertion OK : PageSetup.FooterMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+Verify that top/bottom/header/footer page margins on sheet 2 are all 0.5inch
+ TEST OK : Test margins (headers)
+ TEST START : Test header/footer text
+ ITEM Assertion OK : PageSetup.LeftHeader set
+ ITEM Assertion OK : PageSetup.LeftHeader set/get
+ ITEM Assertion OK : PageSetup.CenterHeader set
+ ITEM Assertion OK : PageSetup.CenterHeader set/get
+ ITEM Assertion OK : PageSetup.RightHeader set
+ ITEM Assertion OK : PageSetup.RightHeader set/get
+ ITEM Assertion OK : PageSetup.LeftFooter set
+ ITEM Assertion OK : PageSetup.LeftFooter set/get
+ ITEM Assertion OK : PageSetup.CenterFooter set
+ ITEM Assertion OK : PageSetup.CenterFooter set/get
+ ITEM Assertion OK : PageSetup.RightFooter set
+ ITEM Assertion OK : PageSetup.RightFooter set/get
+Verify that headers on sheet 2 are Ready,to,go
+Verify that footers on sheet 2 are This,now,Works
+ TEST OK : Test header/footer text
+ TEST START : Test zoom
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Zoom set/get
+Verify that sheet 1 zoom is 10%
+ TEST OK : Test zoom
+ TEST START : Test orientation
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Orientation set/get
+Verify that sheet 1 orientation is now landscape
+ TEST OK : Test orientation
+ TEST START : Test paper size
+ ITEM Assertion OK : PageSetup.PaperSize get
+ ITEM Assertion OK : PageSetup.PaperSize set/get
+Verify that paper size on sheet 1 is now Letter
+ TEST OK : Test paper size
+ TEST START : Test order
+ ITEM Assertion OK : PageSetup.Order get
+ ITEM Assertion OK : PageSetup.Order set/get
+Verify that order on sheet 1 is now over, then down.
+ TEST OK : Test order
+ TEST START : Test first page number
+ ITEM Assertion OK : PageSetup.FirstPageNumber get
+ ITEM Assertion OK : PageSetup.FirstPageNumber set/get
+Verify that first page number on sheet 1 is now 2.
+ TEST OK : Test first page number
+ TEST START : Test center vertically
+ ITEM Assertion OK : PageSetup.CenterVertically get
+ ITEM Assertion OK : PageSetup.CenterVertically set/get
+Verify that CenterVertically on sheet 1 is now true.
+ TEST OK : Test center vertically
+ TEST START : Test center horizontally
+ ITEM Assertion OK : PageSetup.CenterHorizontally get
+ ITEM Assertion OK : PageSetup.CenterHorizontally set/get
+Verify that CenterHorizontally on sheet 1 is now true.
+ TEST OK : Test center horizontally
+ TEST START : Test FitToPagesTall
+ ITEM Assertion OK : PageSetup.FitToPagesTall set/get
+ TEST OK : Test FitToPagesTall
+ TEST START : Test FitToPagesWide
+ ITEM Assertion OK : PageSetup.FitToPagesWide set/get
+ TEST OK : Test FitToPagesWide
+ TEST START : Test PrintHeadings
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ TEST OK : Test PrintHeadings
+ TEST START : Test PrintTitleRows
+ ITEM Assertion OK : PageSetup.PrintTitleRows get
+ ITEM Assertion OK : PageSetup.PrintTitleRows set range/get
+ ITEM Assertion OK : PageSetup.PrintTitleRows set false/get
+ TEST OK : Test PrintTitleRows
+END PageSetup
+Test run finished : 7/21/2008 10:37:32 AM
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/partition.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/partition.log
new file mode 100644
index 000000000000..1ea267d641e8
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/partition.log
@@ -0,0 +1,11 @@
+Test run started : 08/10/2008 13:09:51
+BEGIN Partition
+ TEST START : Test Partition function
+ ITEM Assertion OK : the number 20 occurs in the range:20:24
+ ITEM Assertion OK : the number 20 occurs in the range: 20: 20
+ ITEM Assertion OK : the number 120 occurs in the range:100:
+ ITEM Assertion OK : the number -5 occurs in the range: : -1
+ ITEM Assertion OK : the number 2 occurs in the range: 2: 3
+ TEST OK : Test Partition function
+END Partition
+Test run finished : 08/10/2008 13:09:51
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/range-4.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/range-4.log
new file mode 100644
index 000000000000..11de80133dfa
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/range-4.log
@@ -0,0 +1,16 @@
+Test run started : 08/10/2008 11:30:16
+----------------------------------------------------------------
+ShowDetail-Issue
+ TEST START : ShowDetail-Issue
+ ITEM Assertion OK : Range.ShowDetail is True
+ ITEM Assertion OK : Range.ShowDetail is False
+END 'ShowDetail-Issue' Symbol
+ TEST OK : ShowDetail-Issue
+----------------------------------------------------------------
+RangeMerged-Issue
+ TEST START : RangeMerged-Issue
+ ITEM Assertion OK : Range.RangeMerged is $F$2:$H$5
+ ITEM Assertion OK : The first address of Range.RangeMerged is $F$2
+END 'RangeMerged-Issue' Symbol
+ TEST OK : RangeMerged-Issue
+Test run finished : 08/10/2008 11:30:16
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/replace.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/replace.log
new file mode 100644
index 000000000000..e96004e4d2a6
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/replace.log
@@ -0,0 +1,14 @@
+Test run started : 2007-11-21 11:24:04
+BEGIN Replace
+ TEST START : Test Replace function
+ ITEM Assertion OK : common string:aefefdBc
+ ITEM Assertion OK : expression string:aefefdef
+ ITEM Assertion OK : binanary compare:aefefdBc
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : start = 3:cefdBc
+ ITEM Assertion OK : count = 2: aefefdBc
+ ITEM Assertion OK : start = 1, count = 0, not support in Unix: abcbcdBc
+ TEST OK : Test Replace function
+END Replace
+Test run finished : 2007-11-21 11:24:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/stringplusdouble.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/stringplusdouble.log
new file mode 100644
index 000000000000..51a958a412cf
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/stringplusdouble.log
@@ -0,0 +1,62 @@
+Test run started : 15/01/2009 17:09:03
+BEGIN String Plus Double
+ TEST START : double = string + double
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: 0
+The next compute raises error: s = null, d = 20, r = s + d
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 100
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 30
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = null, r = s & d
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s & d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: -1
+ TEST OK : double = string + double
+ TEST START : string = string + double
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: 0
+The next compute raises error: s = null, d = 20, r = s + d
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 100
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 30
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: abc0
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: abc20
+ TEST OK : string = string + double
+ TEST START : double = string + string
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+The next compute raises error: s = null, d = null, r = s & d
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: 20
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 10
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 1020
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = null, r = s & d
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s & d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: -1
+ TEST OK : double = string + string
+END String Plus Double
+Test run finished : 15/01/2009 17:09:03
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/window2.log b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/window2.log
new file mode 100644
index 000000000000..01fba9c6dfa6
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/logs/win/window2.log
@@ -0,0 +1,41 @@
+Test run started : 15/01/2009 17:10:02
+BEGIN Window2
+ TEST START : Test Window.SplitRow
+ ITEM Assertion OK : Test SplitColumn: 2 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion FAIL : Test SplitRow: 1 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitVertical: 242.283803521067
+ ITEM Assertion OK : Test SplitHorizontal: 242.283803521067
+ ITEM Assertion FAIL : Test SplitRow: 3 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitColumn: 3 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitColumn: 0
+ ITEM Assertion OK : Test SplitRow: 0
+ TEST OK : Test Window.SplitRow
+ TEST START : Test Window.DisplayGridlines
+ ITEM Assertion OK : Test gridlines are on
+ ITEM Assertion OK : Test gridlines are off
+ TEST OK : Test Window.DisplayGridlines
+ TEST START : Test Window.DisplayHeadings
+ ITEM Assertion OK : Test Headings are on
+ ITEM Assertion OK : Test Headings are off
+ TEST OK : Test Window.DisplayHeadings
+ TEST START : Test Window.Visibility
+ ITEM Assertion OK : Window is visible
+ ITEM Assertion OK : Window is not visible
+ TEST OK : Test Window.Visibility
+ TEST START : Test Window.FreezePanes
+ ITEM Assertion OK : Test no panes frozen
+ ITEM Assertion OK : Test panes frozen at center
+ ITEM Assertion OK : Test panes frozen at split
+ TEST OK : Test Window.FreezePanes
+ TEST START : Test Window.View
+ TEST OK : Test Window.View
+ TEST START : Test Window.Zoom
+ ITEM Assertion OK : Test zoom=100%
+ ITEM Assertion OK : Test zoom=150%
+ TEST OK : Test Window.Zoom
+ TEST START : Test Windows.Count
+ ITEM Assertion OK : Windows Count: 1
+ ITEM Assertion OK : Application.Windows Count: 1
+ TEST OK : Test Windows.Count
+END Window2
+Test run finished : 15/01/2009 17:10:03
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/error.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/error.xls
new file mode 100644
index 000000000000..ea2095d5e3d7
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/error.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/imagecontrols.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/imagecontrols.xls
new file mode 100644
index 000000000000..0de17b403f23
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/imagecontrols.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/keyword.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/keyword.xls
new file mode 100644
index 000000000000..3bf711ed4f42
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/keyword.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/objectmodule.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/objectmodule.xls
new file mode 100644
index 000000000000..d3aff35b938c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/objectmodule.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/stringtodouble.ods b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/stringtodouble.ods
new file mode 100644
index 000000000000..5a732a765886
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/notwork/stringtodouble.ods
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/partition.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/partition.xls
new file mode 100644
index 000000000000..5c8d12b1d54f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/partition.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/range-4.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/range-4.xls
new file mode 100644
index 000000000000..52452369462f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/range-4.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/replace.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/replace.xls
new file mode 100644
index 000000000000..dcf3c6e8ec06
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/replace.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/stringplusdouble.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/stringplusdouble.xls
new file mode 100644
index 000000000000..596be7f6b9bc
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/stringplusdouble.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments-ooo-build/window2.xls b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/window2.xls
new file mode 100644
index 000000000000..4d5e1cbfe944
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments-ooo-build/window2.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/ApplicationRunTest.xls b/sc/source/ui/vba/testvba/TestDocuments/ApplicationRunTest.xls
new file mode 100644
index 000000000000..a5a591c1f849
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/ApplicationRunTest.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/AutoFilter.xls b/sc/source/ui/vba/testvba/TestDocuments/AutoFilter.xls
new file mode 100644
index 000000000000..9b3a1043c5ee
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/AutoFilter.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/CalcFont.xls b/sc/source/ui/vba/testvba/TestDocuments/CalcFont.xls
new file mode 100644
index 000000000000..9ddb69600643
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/CalcFont.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/FinancialFuncs.xls b/sc/source/ui/vba/testvba/TestDocuments/FinancialFuncs.xls
new file mode 100644
index 000000000000..bb8941809947
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/FinancialFuncs.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/MiscRangeTests.xls b/sc/source/ui/vba/testvba/TestDocuments/MiscRangeTests.xls
new file mode 100644
index 000000000000..ebd9e91b5b28
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/MiscRangeTests.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/PageBreaks.xls b/sc/source/ui/vba/testvba/TestDocuments/PageBreaks.xls
new file mode 100644
index 000000000000..b6651fa5d617
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/PageBreaks.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/Ranges-2.xls b/sc/source/ui/vba/testvba/TestDocuments/Ranges-2.xls
new file mode 100644
index 000000000000..f6e81cf933fd
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/Ranges-2.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/Ranges-3.xls b/sc/source/ui/vba/testvba/TestDocuments/Ranges-3.xls
new file mode 100644
index 000000000000..8722f6d3057e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/Ranges-3.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/Ranges.xls b/sc/source/ui/vba/testvba/TestDocuments/Ranges.xls
new file mode 100644
index 000000000000..1c1d74d37486
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/Ranges.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/Shapes.xls b/sc/source/ui/vba/testvba/TestDocuments/Shapes.xls
new file mode 100644
index 000000000000..254f3c97756c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/Shapes.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/StrConv-test.xls b/sc/source/ui/vba/testvba/TestDocuments/StrConv-test.xls
new file mode 100755
index 000000000000..198abbec5871
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/StrConv-test.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/Template.xls b/sc/source/ui/vba/testvba/TestDocuments/Template.xls
new file mode 100755
index 000000000000..4387231fe744
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/Template.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/TestAddress.xls b/sc/source/ui/vba/testvba/TestDocuments/TestAddress.xls
new file mode 100644
index 000000000000..48d30cbe2e9e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/TestAddress.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest.xls b/sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest.xls
new file mode 100644
index 000000000000..a497d4f10f3e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest2.xls b/sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest2.xls
new file mode 100644
index 000000000000..34c606fc28f5
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/TestCalc_Rangetest2.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/TestIntersection.xls b/sc/source/ui/vba/testvba/TestDocuments/TestIntersection.xls
new file mode 100644
index 000000000000..24f88db87ccc
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/TestIntersection.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/TestUnion.xls b/sc/source/ui/vba/testvba/TestDocuments/TestUnion.xls
new file mode 100644
index 000000000000..5b8f0968cf38
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/TestUnion.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/Window.xls b/sc/source/ui/vba/testvba/TestDocuments/Window.xls
new file mode 100644
index 000000000000..6fb6963c2f31
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/Window.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/bytearraystring.xls b/sc/source/ui/vba/testvba/TestDocuments/bytearraystring.xls
new file mode 100755
index 000000000000..471bbc349e5b
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/bytearraystring.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/dateserial.xls b/sc/source/ui/vba/testvba/TestDocuments/dateserial.xls
new file mode 100755
index 000000000000..768fb513eba4
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/dateserial.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/datevalue.xls b/sc/source/ui/vba/testvba/TestDocuments/datevalue.xls
new file mode 100755
index 000000000000..852a51d100b8
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/datevalue.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/format.xls b/sc/source/ui/vba/testvba/TestDocuments/format.xls
new file mode 100644
index 000000000000..99ed64d38915
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/format.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/AutoFilter.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/AutoFilter.log
new file mode 100644
index 000000000000..1fe0cbd01fe5
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/AutoFilter.log
@@ -0,0 +1,20 @@
+Test run started : 17/07/2007 17:36:22
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 'starts with' string criteria
+ ITEM Assertion OK : test2 'not equal to' string criteria
+ ITEM Assertion OK : test3 'ends with' string criteria
+ ITEM Assertion OK : test4 field 'all'
+ ITEM Assertion OK : test5 numeric '<15'
+ ITEM Assertion OK : test6 numeric '>=15'
+ ITEM Assertion OK : test7 numeric '<=12'
+Test Results
+============
+
+Tests passed: 7
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 17/07/2007 17:36:23
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/MiscRangeTests.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/MiscRangeTests.log
new file mode 100644
index 000000000000..260465386d07
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/MiscRangeTests.log
@@ -0,0 +1,45 @@
+Test run started : 17/07/2007 15:01:37
+----------------------------------------------------------------
+MiscRangeTests
+ TEST START : MiscRangeTests
+ ITEM Assertion OK : test 1
+ ITEM Assertion OK : test 2
+ ITEM Assertion OK : test 3
+ ITEM Assertion OK : test 4
+ ITEM Assertion OK : test 5
+ ITEM Assertion OK : test 6
+ ITEM Assertion OK : test 7
+ ITEM Assertion OK : test 8
+ ITEM Assertion OK : test 9
+ ITEM Assertion OK : test 10
+ ITEM Assertion OK : test 11
+ ITEM Assertion OK : test 12
+ ITEM Assertion OK : test 13
+ ITEM Assertion OK : test 14
+ ITEM Assertion OK : test 15
+ ITEM Assertion OK : test 16
+ ITEM Assertion OK : test 17
+ ITEM Assertion OK : test 18
+ ITEM Assertion OK : test 19
+ ITEM Assertion OK : test 20
+ ITEM Assertion OK : test 21
+ ITEM Assertion OK : test 22
+ ITEM Assertion OK : test 23
+ ITEM Assertion OK : test 24
+ ITEM Assertion OK : test 25
+ ITEM Assertion OK : test 26
+ ITEM Assertion OK : test 27
+ ITEM Assertion OK : test 28
+ ITEM Assertion OK : test 29
+ ITEM Assertion OK : test 30
+ ITEM Assertion OK : test 31
+No. tests: 31
+Summary
+=======
+Run: 31
+Passed: 31
+Failed: 0
+
+END 'MiscRangeTests
+ TEST OK : MiscRangeTests
+Test run finished : 17/07/2007 15:01:39
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-2.log
new file mode 100644
index 000000000000..736d5bbc42d0
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-2.log
@@ -0,0 +1,68 @@
+Test run started : 18/06/2007 17:50:04
+----------------------------------------------------------------
+ClearFormtsIssue
+ TEST START : ClearFormtsIssue
+ ITEM Assertion OK : Range.Font.Bold is: True
+ ITEM Assertion OK : Range.Font.Bold is: False
+END 'ClearFormtsIssue' Symbol
+ TEST OK : ClearFormtsIssue
+----------------------------------------------------------------
+VerticalAlignment-Issue
+ TEST START : VerticalAlignment-Issue
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : Range.VeritcalAlignment is Null
+END 'VerticalAlignment-Issue' Symbol
+ TEST OK : VerticalAlignment-Issue
+----------------------------------------------------------------
+HorizontalAlignment-Issue
+ TEST START : HorizontalAlignment-Issue
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : Range.HorizontalAlignment is Null
+END 'HorizontalAlignment-Issue' Symbol
+ TEST OK : HorizontalAlignment-Issue
+----------------------------------------------------------------
+WrapText-Issue
+ TEST START : WrapText-Issue
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : Range.WrapText is Null
+END 'WrapText-Issue' Symbol
+ TEST OK : WrapText-Issue
+----------------------------------------------------------------
+FontBorderIssues
+ TEST START : FontBorderIssues
+ ITEM Assertion OK : - = Borders.Color (getColor)
+ ITEM Assertion OK : - = Font.Color (getColor)
+END 'FontBorderIssues' Symbol
+ TEST OK : FontBorderIssues
+----------------------------------------------------------------
+RangeSizeIssues
+ TEST START : RangeSizeIssues
+ ITEM Assertion OK : Range.Left is: 114
+ ITEM Assertion OK : Range.Top is: 95.25
+ ITEM Assertion OK : Range.Width is: 216
+ ITEM Assertion OK : Range.Height is: 271.5
+END 'RangeSizeIssues' Symbol
+ TEST OK : RangeSizeIssues
+----------------------------------------------------------------
+ApplicationIssues
+ TEST START : ApplicationIssues
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Application.ActiveSheet.Name: Sheet1
+END 'ApplicationIssues' Symbol
+ TEST OK : ApplicationIssues
+Test run finished : 18/06/2007 17:50:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-3.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-3.log
new file mode 100644
index 000000000000..a7de979d5e13
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges-3.log
@@ -0,0 +1,8 @@
+Test run started : 19/06/2007 11:21:42
+----------------------------------------------------------------
+MyGoalseek-Issue
+ TEST START : MyGoalseek-Issue
+ ITEM Assertion OK : Variable Range value: 15
+END 'MyGoalseek-Issue' Symbol
+ TEST OK : MyGoalseek-Issue
+Test run finished : 19/06/2007 11:21:42
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges.log
new file mode 100644
index 000000000000..8c9644aac155
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/Ranges.log
@@ -0,0 +1,280 @@
+Test run started : 01/06/2007 11:28:58
+----------------------------------------------------------------
+ApplicationMethods
+ TEST START : ApplicationMethods
+ ITEM Assertion OK : Name of Workbook is: Ranges.xls
+ ITEM Assertion OK : Address of Application.Columns is: $A:$A
+ ITEM Assertion OK : Address of Application.Rows is: $1:$1
+ ITEM Assertion OK : Address of Application.Range is: $1:$1,$5:$7
+ ITEM Assertion OK : Please check manually: DefaultFilePath is: C:\Documents and Settings\vituosity\My Documents
+ ITEM Assertion OK : Please check manually: Library Path is: C:\Program Files\Microsoft Office\OFFICE11\LIBRARY
+ ITEM Assertion OK : Please check manually: Template Path is: C:\Documents and Settings\vituosity\Application Data\Microsoft\Templates\
+ ITEM Assertion OK : FileSeparator is \
+ ITEM Assertion OK : Name of ActiveWorkbook is: Ranges.xls
+END 'ApplicationMethods' Symbol
+ TEST OK : ApplicationMethods
+----------------------------------------------------------------
+Insert-Issue
+ TEST START : Insert-Issue
+ ITEM Assertion OK : Insert with xlShiftToRight: 10
+END 'Insert-Issue' Symbol
+ TEST OK : Insert-Issue
+----------------------------------------------------------------
+MergeCells-Issue
+ TEST START : MergeCells-Issue
+ ITEM Assertion OK : Range.MergeCells is True
+ ITEM Assertion OK : MergeCells is null: True
+ ITEM Assertion OK : RowCount after Merge: 6
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : MergeCells of Second Area is null : True
+ ITEM Assertion OK : MergeCells of Ranges is Null: True
+ ITEM Assertion OK : RowCount after Merge: 7
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+END 'MergeCells-Issue' Symbol
+ TEST OK : MergeCells-Issue
+----------------------------------------------------------------
+Areas-Issue
+ TEST START : Areas-Issue
+ ITEM Assertion OK : Range Areas Count is2
+ ITEM Assertion OK : First Range Address is: $E$8:$G$13
+ ITEM Assertion OK : First Row is: 8
+ ITEM Assertion OK : First Column is: 5
+ ITEM Assertion OK : EntireRow Address is: $8:$13,$13:$19
+ ITEM Assertion OK : EntireColumn Address is: $E:$G,$G:$K
+ ITEM Assertion OK : Range Count:53
+END 'Areas-Issue' Symbol
+ TEST OK : Areas-Issue
+----------------------------------------------------------------
+Fill-Methods-Issue
+ TEST START : Fill-Methods-Issue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyRightFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyBottomFillValue
+END 'Fill-Methods-Issue' Symbol
+ TEST OK : Fill-Methods-Issue
+----------------------------------------------------------------
+Range/Item-Method-Issue
+ TEST START : Range/Item-Method-Issue
+ ITEM Assertion OK : Range of multiple columns is: $A:$A,$C:$C
+ ITEM Assertion OK : Range of multiple rows is: $1:$1,$5:$7
+ ITEM Assertion OK : Range of several columns is: $C:$E,$D:$D
+ ITEM Assertion OK : Range of several rows is: $5:$8,$6:$10
+ ITEM Assertion OK : Range of several single cells is: $C$5,$E$8
+ ITEM Assertion OK : Range of several named ranges is: $L$1:$M$6,$E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range of a single Item Cell is: $E$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$10
+END 'Range/Item-Method-Issue' Symbol
+ TEST OK : Range/Item-Method-Issue
+----------------------------------------------------------------
+R1C1-Formulas-Issue
+ TEST START : R1C1-Formulas-Issue
+ ITEM Assertion OK : R1C1 Range.Formula is: =IF(OR(R[-2]C[1]=0,RC[2]="YES"),"")
+ ITEM Assertion OK : Range.Formula is: =IF(OR(J8=0,K10="YES"),"")
+END 'R1C1-Formulas-Issue' Symbol
+ TEST OK : R1C1-Formulas-Issue
+----------------------------------------------------------------
+Verify_Delete
+ TEST START : Verify_Delete
+ ITEM Assertion OK : Ranges are intersecting: $G$13
+ ITEM Assertion OK : Delete with Default: $AJ$4
+ ITEM Assertion OK : Delete with ShifttoLeft: $AJ$4
+ ITEM Assertion OK : Delete with ShiftUp: $M$22
+END 'Verify_Delete' Symbol
+ TEST OK : Verify_Delete
+----------------------------------------------------------------
+Value-Issue
+ TEST START : Value-Issue
+ ITEM Assertion OK : Value of Range is: 12.3
+ ITEM Assertion OK : Text of Range is: 12.3
+ ITEM Assertion OK : Range has Formula: False
+ ITEM Assertion OK : Cell has Formula: False
+ ITEM Assertion OK : Text of Range is null: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Cell has Formula: True
+ ITEM Assertion OK : Value of Cell is: 12
+ ITEM Assertion OK : Application.Calculation is : -4135
+ ITEM Assertion OK : Calculation is automated: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Value of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Range has Formula after 'ClearContents: False
+ ITEM Assertion OK : Text of Cell is:
+ ITEM Assertion OK : Text of Cell is:
+END 'Value-Issue' Symbol
+ TEST OK : Value-Issue
+----------------------------------------------------------------
+AutoFit issue
+ TEST START : AutoFit issue
+ ITEM Assertion OK : Columns.AutoFit: CurrentWidth is 673
+ ITEM Assertion OK : Rows.AutoFit: CurrentHeight is 612
+END 'AutoFit issue' Symbol
+ TEST OK : AutoFit issue
+----------------------------------------------------------------
+Selections
+ TEST START : Selections
+ ITEM Assertion OK : ActiveCell is : $E$8
+ ITEM Assertion OK : Active Cell is : $E$8
+ ITEM Assertion OK : Number of Cells in Range: 53
+ ITEM Assertion OK : Number of Cells in Range: 53
+ ITEM Assertion OK : Number of Cells in Range: 53
+END 'Selections' Symbol
+ TEST OK : Selections
+----------------------------------------------------------------
+Offset-Resize
+ TEST START : Offset-Resize
+ ITEM Assertion OK : Offset is : $G$10:$I$15,$I$15:$M$21
+ ITEM Assertion OK : Offset is : $G$7:$I$12,$I$12:$M$18
+ ITEM Assertion OK : Resized Range is : $A$20:$D$23
+END 'Offset-Resize' Symbol
+ TEST OK : Offset-Resize
+----------------------------------------------------------------
+Ranges-Address
+ TEST START : Ranges-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: $E8:$G13,$G13:$K19
+ ITEM Assertion OK : Range Address is: E$8:G$13,G$13:K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5],R[11]C[5]:R[17]C[9]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13,$G$13:$K$19
+END 'Ranges-Address' Symbol
+ TEST OK : Ranges-Address
+----------------------------------------------------------------
+Range-Address
+ TEST START : Range-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: $E8:$G13
+ ITEM Assertion OK : Range Address is: E$8:G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13
+END 'Range-Address' Symbol
+ TEST OK : Range-Address
+----------------------------------------------------------------
+Column-Address
+ TEST START : Column-Address
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: $F8:$F13
+ ITEM Assertion OK : Range Address is: F$8:F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R[6]C[4]:R[11]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$8:$F$13
+END 'Column-Address' Symbol
+ TEST OK : Column-Address
+----------------------------------------------------------------
+Row-Address
+ TEST START : Row-Address
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: $E9:$G9
+ ITEM Assertion OK : Range Address is: E$9:G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R[7]C[3]:R[7]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$9:$G$9
+END 'Row-Address' Symbol
+ TEST OK : Row-Address
+----------------------------------------------------------------
+SingleCell-Address
+ TEST START : SingleCell-Address
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: $F9
+ ITEM Assertion OK : Range Address is: F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R[7]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$9
+END 'SingleCell-Address' Symbol
+ TEST OK : SingleCell-Address
+----------------------------------------------------------------
+Heights and Widths
+ TEST START : Heights and Widths
+ ITEM Assertion OK : Range RowHeight is 40
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 238
+ ITEM Assertion OK : Range Width is 798.75
+ ITEM Assertion OK : Range RowHeight is 50
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 297
+ ITEM Assertion OK : Range Width is 798.75
+ ITEM Assertion OK : RowHeight is null: True
+ ITEM Assertion OK : ColumnWidth is null: True
+END 'Heights and Widths' Symbol
+ TEST OK : Heights and Widths
+----------------------------------------------------------------
+RangeRowColumn-Issue
+ TEST START : RangeRowColumn-Issue
+ ITEM Assertion OK : Row is: 8
+ ITEM Assertion OK : Column is: 5
+ ITEM Assertion OK : EntireRow.Columns.Count = 256
+ ITEM Assertion OK : EntireColumn.Rows.Count = 65536
+END 'RangeRowColumn-Issue' Symbol
+ TEST OK : RangeRowColumn-Issue
+----------------------------------------------------------------
+Replace-Issue
+ TEST START : Replace-Issue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New Replace
+ ITEM Assertion OK : Value after Replace:
+END 'Replace-Issue' Symbol
+ TEST OK : Replace-Issue
+----------------------------------------------------------------
+Hidden-Issue
+ TEST START : Hidden-Issue
+ ITEM Assertion OK : - Range.Rows.Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Hidden (get)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (get)
+END 'Hidden-Issue' Symbol
+ TEST OK : Hidden-Issue
+----------------------------------------------------------------
+End issue
+ TEST START : End issue
+ ITEM Assertion OK : - = $E$48
+ ITEM Assertion OK : - = $E$1
+ ITEM Assertion OK : - = $E$3
+ ITEM Assertion OK : - = $A$8
+ ITEM Assertion OK : - = $B$8
+ ITEM Assertion OK : - = $IV$8
+ ITEM Assertion OK : - = $Z$8
+END 'End issue' Symbol
+ TEST OK : End issue
+----------------------------------------------------------------
+Outline issue
+ TEST START : Outline issue
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+END 'Outline issue' Symbol
+ TEST OK : Outline issue
+----------------------------------------------------------------
+Validation
+ TEST START : Validation
+ ITEM Assertion OK : Validation Input Message is : Attention!
+ ITEM Assertion OK : Validation Input Message is : Enter an integer from five to ten
+ ITEM Assertion OK : Validation Error Title is : You must enter a number from five to ten
+ ITEM Assertion OK : Validation Error Message is : An Error occured
+ ITEM Assertion OK : Validation Error Title is : Microsoft Excel
+END 'Validation' Symbol
+ TEST OK : Validation
+Test run finished : 01/06/2007 11:29:00
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestAddress.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestAddress.log
new file mode 100644
index 000000000000..01e5503a7e62
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestAddress.log
@@ -0,0 +1,62 @@
+Test run started : 17/07/2007 15:25:17
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 Range('e3:f3') A1 style addressing
+ ITEM Assertion OK : test2 Range('e3:f3') R1C1 style addressing
+ ITEM Assertion OK : test3 Range ('e:f') A1 style addressing
+ ITEM Assertion OK : test4 Range ('e:f') R1C1 style addressing
+ ITEM Assertion OK : test5 Columns A1 style addressing
+ ITEM Assertion OK : test6 Columns R1C1 style addressing
+ ITEM Assertion OK : test7 Columns(3) A1 style addressing
+ ITEM Assertion OK : test8 Columns(3) R1C1 style addressing
+ ITEM Assertion OK : test9 Columns('e') A1 style addressing
+ ITEM Assertion OK : test10 Columns('e') R1C1 style addressing
+ ITEM Assertion OK : test11 Columns('b:d') A1 style addressing
+ ITEM Assertion OK : test12 Columns('b:d') R1C1 style addressing
+ ITEM Assertion OK : test13 Range('c1:g10').Columns A1 style addressing
+ ITEM Assertion OK : test14 Range('c1:g10').Columns R1C1 style addressing
+ ITEM Assertion OK : test15 Range('c1:g10').Columns(1) A1 style addressing
+ ITEM Assertion OK : test16 Range('c1:g10').Columns(1) R1C1 style addressing
+ ITEM Assertion OK : test17 Range('c1:g10').Columns('a') A1 style addressing
+ ITEM Assertion OK : test18 Range('c1:g10').Columns('a') R1C1 style addressing
+ ITEM Assertion OK : test19 Range('c1:g10').Columns('c') A1 style addressing
+ ITEM Assertion OK : test20 Range('c1:g10').Columns('c') R1C1 style addressing
+ ITEM Assertion OK : test21 Range('c1:g10').Columns('x:z') A1 style addressing
+ ITEM Assertion OK : test22 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test23 Range('c1:g10').Columns(30) A1 style addressing
+ ITEM Assertion OK : test24 Range('c1:g10').Columns(30) R1C1 style addressing
+ ITEM Assertion OK : test25 Worksheets('Sheet2').Cells(1, 1) A1 style addressing
+ ITEM Assertion OK : test26 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, RowAddressAbsolute is false
+ ITEM Assertion OK : test27 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, ColAddressAbsolute is false
+ ITEM Assertion OK : test28 Worksheets('Sheet2').Cells(1, 1) R1C1 style addressing
+ ITEM Assertion OK : test29 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test30 Worksheets('Sheet2').Range('A1').EntireColumn A1 style addressing
+ ITEM Assertion OK : test31 Worksheets('Sheet2').Range('A1:E5').EntireRow A1 style addressing
+ ITEM Assertion OK : test32 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test33 Worksheets('Sheet2').Range('IV65536').EntireRow A1 style addressing
+ ITEM Assertion OK : test34 Worksheets('Sheet2').Range('IU2:IV65536') A1 style addressing
+ ITEM Assertion OK : test35 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test36 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test37 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test38 Worksheets('Sheet2').Range('10:12') A1 style addressing
+ ITEM Assertion OK : test39 Worksheets('Sheet2').Range('10:12') R1C1 style addressing
+ ITEM Assertion OK : test40 Range('Sheet3!A1:B4') A1 style addressing
+ ITEM Assertion OK : test41 Range('Sheet3!A1,B1,D4:F20') A1 style addressing
+ ITEM Assertion OK : test42 Range('g20:h40').Columns('c:c')
+ ITEM Assertion OK : test43 Range('g20:h40').Columns('c:f')
+ ITEM Assertion OK : test44 Range('g20:h40').Columns(-1)
+ ITEM Assertion OK : test45 Range('c4:g10').Rows(-1)
+ ITEM Assertion OK : test46 Range('a2:b4').Rows('1:1')
+ ITEM Assertion OK : test47 Range('a2:b4').Rows('1:2')
+ ITEM Assertion OK : test48 Range('a2:b4').Rows('2:2')
+ ITEM Assertion OK : test49 Range('a2:b4').Rows('2:3')
+Test Results
+============
+
+Tests passed: 49
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 17/07/2007 15:25:19
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest.log
new file mode 100644
index 000000000000..f055279ec6f4
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest.log
@@ -0,0 +1,60 @@
+Test run started : 30/05/2007 11:33:13
+BEGIN TestCalc
+ TEST START : RangeTest2
+ ITEM Assertion OK : - Range("D15").Row
+ ITEM Assertion OK : - WorkSheet("D15").Range.Row
+ ITEM Assertion OK : - Range("D15").Column
+ ITEM Assertion OK : - Worksheet.Range("D15").Column
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Columns.Count
+ ITEM Assertion OK : - Range("D1").EntireColumn.Rows.Count
+ ITEM Assertion OK : - Range("D15").ClearContent
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (get)
+ ITEM Assertion OK : - Range("B38").Orientation (get)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlDownward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlUpward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B39").WrapText (get)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (get)
+ ITEM Assertion OK : - Range("F39").MergeCells (get)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("D41:D42").Replace MatchCase:=False
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM OK (RangeTest2)
+ TEST succesfully completed : RangeTest2
+END TestCalc
+Test run finished : 30/05/2007 11:33:14
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest2.log
new file mode 100644
index 000000000000..19a5ba96b54a
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/excel/TestCalc_Rangetest2.log
@@ -0,0 +1,64 @@
+Test run started : 31/05/2007 11:02:10
+BEGIN TestCalc
+ TEST START : RangeTest3
+ ITEM Assertion OK : - setFormulaR1C1
+ ITEM Assertion OK : - getFormulaR1C1
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy(Range("I10"))
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteValues
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormulas
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormats
+ ITEM Assertion OK : PasteSpecial
+ ITEM Assertion OK : PasteSpecial SkipBlanks:=True
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationAdd
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationSubtract
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationMultiply
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationDivide
+ ITEM Assertion OK : PasteSpecial Transpose:=True
+ ITEM Assertion OK : ActiveWorkbook.Name
+ ITEM Assertion OK : ActiveWorkbook.FullName und ActiveWorkbook.Path
+ ITEM Assertion OK : - = Range("K22").End (xlDown)
+ ITEM Assertion OK : - = Range("K22").End (xlUo)
+ ITEM Assertion OK : - = Range("K22").End (xlToLeft)
+ ITEM Assertion OK : - = Range("K22").End (xlRight)
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="x"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="<>"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="="
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter
+ ITEM Assertion OK : - ActiveSheet.Resize.Select
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Application.GoTo Reference:="R[8]C[2]"
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Ungroup- please check visually
+ ITEM Assertion OK : - Range.Ungroup - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - ActiveSheet.UsedRange.Select
+ ITEM Assertion FAIL : - Range("A13").AddIndent
+ ITEM Assertion OK : - Range("A13").IndentLevel set
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Calculate
+ ITEM Assertion OK : Worksheet.Calculate
+ ITEM Assertion OK : - Application.Calculate
+ ITEM Assertion OK : Global.Calculate
+ ITEM Assertion OK : Calculation set
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) set
+ ITEM Assertion OK : - = ActiveWorkbook.ResetColors
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) get
+ ITEM FAIL (RangeTest3)
+ TEST Not succesfully completed : RangeTest3
+END TestCalc
+Test run finished : 31/05/2007 11:02:12
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/AutoFilter.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/AutoFilter.log
new file mode 100644
index 000000000000..55f5d9526618
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/AutoFilter.log
@@ -0,0 +1,20 @@
+Test run started : 18/07/2007 10:56:38
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 'starts with' string criteria
+ ITEM Assertion OK : test2 'not equal to' string criteria
+ ITEM Assertion OK : test3 'ends with' string criteria
+ ITEM Assertion OK : test4 field 'all'
+ ITEM Assertion OK : test5 numeric '<15'
+ ITEM Assertion OK : test6 numeric '>=15'
+ ITEM Assertion OK : test7 numeric '<=12'
+Test Results
+============
+
+Tests passed: 7
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 18/07/2007 10:56:44
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/CalcFont.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/CalcFont.log
new file mode 100644
index 000000000000..f3583e4cbb12
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/CalcFont.log
@@ -0,0 +1,17 @@
+Test run started : 10/09/2008 02:40:17 PM
+CalcFont_Format
+ TEST START : Font_Format
+ ITEM Assertion OK : correctly set font to Bold
+ ITEM Assertion OK : correctly set font to Italic
+ ITEM Assertion OK : correctly read FontStyle
+ ITEM Assertion OK : correctly set font to Shadow
+ ITEM Assertion OK : correctly set font color
+ ITEM Assertion OK : correctly set font color index
+ ITEM Assertion OK : correctly set font name
+ ITEM Assertion OK : correctly set font outline
+ ITEM Assertion OK : correctly set font size
+ ITEM Assertion OK : correctly set font strikethrough
+ ITEM Assertion OK : correctly set font underline
+ TEST Success. : Font_Format
+CalcFont_Format
+Test run finished : 10/09/2008 02:40:17 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/MiscRangeTests.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/MiscRangeTests.log
new file mode 100644
index 000000000000..215842f9a7e6
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/MiscRangeTests.log
@@ -0,0 +1,45 @@
+Test run started : 17/07/2007 20:54:56
+----------------------------------------------------------------
+MiscRangeTests
+ TEST START : MiscRangeTests
+ ITEM Assertion OK : test 1
+ ITEM Assertion OK : test 2
+ ITEM Assertion OK : test 3
+ ITEM Assertion OK : test 4
+ ITEM Assertion OK : test 5
+ ITEM Assertion OK : test 6
+ ITEM Assertion OK : test 7
+ ITEM Assertion OK : test 8
+ ITEM Assertion OK : test 9
+ ITEM Assertion OK : test 10
+ ITEM Assertion OK : test 11
+ ITEM Assertion OK : test 12
+ ITEM Assertion OK : test 13
+ ITEM Assertion OK : test 14
+ ITEM Assertion OK : test 15
+ ITEM Assertion OK : test 16
+ ITEM Assertion OK : test 17
+ ITEM Assertion OK : test 18
+ ITEM Assertion OK : test 19
+ ITEM Assertion OK : test 20
+ ITEM Assertion OK : test 21
+ ITEM Assertion OK : test 22
+ ITEM Assertion OK : test 23
+ ITEM Assertion OK : test 24
+ ITEM Assertion OK : test 25
+ ITEM Assertion OK : test 26
+ ITEM Assertion OK : test 27
+ ITEM Assertion OK : test 28
+ ITEM Assertion OK : test 29
+ ITEM Assertion OK : test 30
+ ITEM Assertion OK : test 31
+No. tests: 31
+Summary
+=======
+Run: 31
+Passed: 31
+Failed: 0
+
+END 'MiscRangeTests
+ TEST OK : MiscRangeTests
+Test run finished : 17/07/2007 20:55:03
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/PageBreaks.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/PageBreaks.log
new file mode 100644
index 000000000000..0ff400d49e85
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/PageBreaks.log
@@ -0,0 +1,10 @@
+Test run started : 07/24/2008 05:06:12 PM
+----------------------------------------------------------------
+ TEST START : PageBreaks-Issue
+ ITEM Assertion OK : HPageBreaks.Count is 3
+ ITEM Assertion OK : HPageBreak.Type is -4135
+ ITEM Assertion OK : HPageBreak.Location: Range.Row is 5
+ ITEM Assertion OK : HPageBreak.Delete: HPageBreaks.Count is 2
+END 'PageBreaks-Issue' Symbol
+ TEST OK : PageBreaks-Issue
+Test run finished : 07/24/2008 05:06:13 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-2.log
new file mode 100644
index 000000000000..8b7076efaea0
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-2.log
@@ -0,0 +1,68 @@
+Test run started : 19/06/2007 11:14:01
+----------------------------------------------------------------
+ClearFormtsIssue
+ TEST START : ClearFormtsIssue
+ ITEM Assertion OK : Range.Font.Bold is: True
+ ITEM Assertion OK : Range.Font.Bold is: False
+END 'ClearFormtsIssue' Symbol
+ TEST OK : ClearFormtsIssue
+----------------------------------------------------------------
+VerticalAlignment-Issue
+ TEST START : VerticalAlignment-Issue
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : Range.VeritcalAlignment is Null
+END 'VerticalAlignment-Issue' Symbol
+ TEST OK : VerticalAlignment-Issue
+----------------------------------------------------------------
+HorizontalAlignment-Issue
+ TEST START : HorizontalAlignment-Issue
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : Range.HorizontalAlignment is Null
+END 'HorizontalAlignment-Issue' Symbol
+ TEST OK : HorizontalAlignment-Issue
+----------------------------------------------------------------
+WrapText-Issue
+ TEST START : WrapText-Issue
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : Range.WrapText is Null
+END 'WrapText-Issue' Symbol
+ TEST OK : WrapText-Issue
+----------------------------------------------------------------
+FontBorderIssues
+ TEST START : FontBorderIssues
+ ITEM Assertion OK : - = Borders.Color (getColor)
+ ITEM Assertion OK : - = Font.Color (getColor)
+END 'FontBorderIssues' Symbol
+ TEST OK : FontBorderIssues
+----------------------------------------------------------------
+RangeSizeIssues
+ TEST START : RangeSizeIssues
+ ITEM Assertion OK : Range.Left is: 118.8432
+ ITEM Assertion OK : Range.Top is: 92.16585
+ ITEM Assertion OK : Range.Width is: 226.2
+ ITEM Assertion OK : Range.Height is: 271.5
+END 'RangeSizeIssues' Symbol
+ TEST OK : RangeSizeIssues
+----------------------------------------------------------------
+ApplicationIssues
+ TEST START : ApplicationIssues
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Application.ActiveSheet.Name: Sheet1
+END 'ApplicationIssues' Symbol
+ TEST OK : ApplicationIssues
+Test run finished : 19/06/2007 11:14:02
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-3.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-3.log
new file mode 100644
index 000000000000..a130737ceb65
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges-3.log
@@ -0,0 +1,8 @@
+Test run started : 19/06/2007 11:26:09
+----------------------------------------------------------------
+MyGoalseek-Issue
+ TEST START : MyGoalseek-Issue
+ ITEM Assertion OK : Variable Range value: 15
+END 'MyGoalseek-Issue' Symbol
+ TEST OK : MyGoalseek-Issue
+Test run finished : 19/06/2007 11:26:10
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges.log
new file mode 100644
index 000000000000..cdd18685e977
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Ranges.log
@@ -0,0 +1,280 @@
+Test run started : 10/03/2008 15:15:11
+----------------------------------------------------------------
+ApplicationMethods
+ TEST START : ApplicationMethods
+ ITEM Assertion OK : Name of Workbook is: Ranges.xls
+ ITEM Assertion OK : Address of Application.Columns is: $A:$A
+ ITEM Assertion OK : Address of Application.Rows is: $1:$1
+ ITEM Assertion OK : Address of Application.Range is: $1:$1,$5:$7
+ ITEM Assertion OK : Please check manually: DefaultFilePath is: /data4/home/npower/Documents
+ ITEM Assertion OK : Please check manually: Library Path is: /data4/home/npower/.ooo-2.0/user/basic
+ ITEM Assertion OK : Please check manually: Template Path is: /data4/home/npower/.ooo-2.0/user/template
+ ITEM Assertion OK : FileSeparator is /
+ ITEM Assertion OK : Name of ActiveWorkbook is: Ranges.xls
+END 'ApplicationMethods' Symbol
+ TEST OK : ApplicationMethods
+----------------------------------------------------------------
+Insert-Issue
+ TEST START : Insert-Issue
+ ITEM Assertion OK : Insert with xlShiftToRight: 10
+END 'Insert-Issue' Symbol
+ TEST OK : Insert-Issue
+----------------------------------------------------------------
+MergeCells-Issue
+ TEST START : MergeCells-Issue
+ ITEM Assertion OK : Range.MergeCells is True
+ ITEM Assertion FAIL : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 13
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion FAIL : MergeCells of Second Area is null : False
+ ITEM Assertion FAIL : MergeCells of Ranges is Null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+END 'MergeCells-Issue' Symbol
+ TEST OK : MergeCells-Issue
+----------------------------------------------------------------
+Areas-Issue
+ TEST START : Areas-Issue
+ ITEM Assertion OK : Range Areas Count is2
+ ITEM Assertion OK : First Range Address is: $E$8:$G$13
+ ITEM Assertion OK : First Row is: 8
+ ITEM Assertion OK : First Column is: 5
+ ITEM Assertion OK : EntireRow Address is: $8:$13,$13:$19
+ ITEM Assertion OK : EntireColumn Address is: $E:$G,$G:$K
+ ITEM Assertion OK : Range Count:53
+END 'Areas-Issue' Symbol
+ TEST OK : Areas-Issue
+----------------------------------------------------------------
+Fill-Methods-Issue
+ TEST START : Fill-Methods-Issue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyRightFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyBottomFillValue
+END 'Fill-Methods-Issue' Symbol
+ TEST OK : Fill-Methods-Issue
+----------------------------------------------------------------
+Range/Item-Method-Issue
+ TEST START : Range/Item-Method-Issue
+ ITEM Assertion OK : Range of multiple columns is: $A:$A,$C:$C
+ ITEM Assertion OK : Range of multiple rows is: $1:$1,$5:$7
+ ITEM Assertion OK : Range of several columns is: $C:$E,$D:$D
+ ITEM Assertion OK : Range of several rows is: $5:$8,$6:$10
+ ITEM Assertion OK : Range of several single cells is: $C$5,$E$8
+ ITEM Assertion OK : Range of several named ranges is: $L$1:$M$6,$E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range of a single Item Cell is: $E$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$10
+END 'Range/Item-Method-Issue' Symbol
+ TEST OK : Range/Item-Method-Issue
+----------------------------------------------------------------
+R1C1-Formulas-Issue
+ TEST START : R1C1-Formulas-Issue
+ ITEM Assertion OK : R1C1 Range.Formula is: =IF(OR(R[-2]C[1]=0,RC[2]="YES"),"")
+ ITEM Assertion OK : Range.Formula is: =IF(OR(J8=0,K10="YES"),"")
+END 'R1C1-Formulas-Issue' Symbol
+ TEST OK : R1C1-Formulas-Issue
+----------------------------------------------------------------
+Verify_Delete
+ TEST START : Verify_Delete
+ ITEM Assertion OK : Ranges are intersecting: $G$13
+ ITEM Assertion OK : Delete with Default: $AJ$4
+ ITEM Assertion OK : Delete with ShifttoLeft: $AJ$4
+ ITEM Assertion OK : Delete with ShiftUp: $M$22
+END 'Verify_Delete' Symbol
+ TEST OK : Verify_Delete
+----------------------------------------------------------------
+Value-Issue
+ TEST START : Value-Issue
+ ITEM Assertion OK : Value of Range is: 12.3
+ ITEM Assertion OK : Text of Range is: 12.3
+ ITEM Assertion OK : Range has Formula: False
+ ITEM Assertion OK : Cell has Formula: False
+ ITEM Assertion FAIL : Text of Range is null: False
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Cell has Formula: True
+ ITEM Assertion OK : Value of Cell is: 12
+ ITEM Assertion OK : Application.Calculation is : -4135
+ ITEM Assertion OK : Calculation is automated: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Value of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Range has Formula after 'ClearContents: False
+ ITEM Assertion OK : Text of Cell is:
+ ITEM Assertion OK : Text of Cell is:
+END 'Value-Issue' Symbol
+ TEST OK : Value-Issue
+----------------------------------------------------------------
+AutoFit issue
+ TEST START : AutoFit issue
+ ITEM Assertion OK : Columns.AutoFit: CurrentWidth is 680
+ ITEM Assertion OK : Rows.AutoFit: CurrentHeight is 554
+END 'AutoFit issue' Symbol
+ TEST OK : AutoFit issue
+----------------------------------------------------------------
+Selections
+ TEST START : Selections
+ ITEM Assertion OK : ActiveCell is : $E$8
+ ITEM Assertion OK : Active Cell is : $E$8
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+END 'Selections' Symbol
+ TEST OK : Selections
+----------------------------------------------------------------
+Offset-Resize
+ TEST START : Offset-Resize
+ ITEM Assertion OK : Offset is : $G$10:$I$15,$I$15:$M$21
+ ITEM Assertion OK : Offset is : $G$7:$I$12,$I$12:$M$18
+ ITEM Assertion OK : Resized Range is : $A$20:$D$23
+END 'Offset-Resize' Symbol
+ TEST OK : Offset-Resize
+----------------------------------------------------------------
+Ranges-Address
+ TEST START : Ranges-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: $E8:$G13,$G13:$K19
+ ITEM Assertion OK : Range Address is: E$8:G$13,G$13:K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5],R[11]C[5]:R[17]C[9]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13,$G$13:$K$19
+END 'Ranges-Address' Symbol
+ TEST OK : Ranges-Address
+----------------------------------------------------------------
+Range-Address
+ TEST START : Range-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: $E8:$G13
+ ITEM Assertion OK : Range Address is: E$8:G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13
+END 'Range-Address' Symbol
+ TEST OK : Range-Address
+----------------------------------------------------------------
+Column-Address
+ TEST START : Column-Address
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: $F8:$F13
+ ITEM Assertion OK : Range Address is: F$8:F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion FAIL : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R[6]C[4]:R[11]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$8:$F$13
+END 'Column-Address' Symbol
+ TEST OK : Column-Address
+----------------------------------------------------------------
+Row-Address
+ TEST START : Row-Address
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: $E9:$G9
+ ITEM Assertion OK : Range Address is: E$9:G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion FAIL : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R[7]C[3]:R[7]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$9:$G$9
+END 'Row-Address' Symbol
+ TEST OK : Row-Address
+----------------------------------------------------------------
+SingleCell-Address
+ TEST START : SingleCell-Address
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: $F9
+ ITEM Assertion OK : Range Address is: F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion FAIL : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R[7]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$9
+END 'SingleCell-Address' Symbol
+ TEST OK : SingleCell-Address
+----------------------------------------------------------------
+Heights and Widths
+ TEST START : Heights and Widths
+ ITEM Assertion OK : Range RowHeight is 40
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 240
+ ITEM Assertion OK : Range Width is 795
+ ITEM Assertion OK : Range RowHeight is 50
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 300
+ ITEM Assertion OK : Range Width is 795
+ ITEM Assertion OK : RowHeight is null: True
+ ITEM Assertion OK : ColumnWidth is null: True
+END 'Heights and Widths' Symbol
+ TEST OK : Heights and Widths
+----------------------------------------------------------------
+RangeRowColumn-Issue
+ TEST START : RangeRowColumn-Issue
+ ITEM Assertion OK : Row is: 8
+ ITEM Assertion OK : Column is: 5
+ ITEM Assertion OK : EntireRow.Columns.Count = 256
+ ITEM Assertion OK : EntireColumn.Rows.Count = 131072
+END 'RangeRowColumn-Issue' Symbol
+ TEST OK : RangeRowColumn-Issue
+----------------------------------------------------------------
+Replace-Issue
+ TEST START : Replace-Issue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New Replace
+ ITEM Assertion OK : Value after Replace:
+END 'Replace-Issue' Symbol
+ TEST OK : Replace-Issue
+----------------------------------------------------------------
+Hidden-Issue
+ TEST START : Hidden-Issue
+ ITEM Assertion OK : - Range.Rows.Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Hidden (get)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (get)
+END 'Hidden-Issue' Symbol
+ TEST OK : Hidden-Issue
+----------------------------------------------------------------
+End issue
+ TEST START : End issue
+ ITEM Assertion OK : - = $E$48
+ ITEM Assertion OK : - = $E$1
+ ITEM Assertion OK : - = $E$3
+ ITEM Assertion OK : - = $A$8
+ ITEM Assertion OK : - = $B$8
+ ITEM Assertion OK : - = $IV$8
+ ITEM Assertion OK : - = $Z$8
+END 'End issue' Symbol
+ TEST OK : End issue
+----------------------------------------------------------------
+Outline issue
+ TEST START : Outline issue
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+END 'Outline issue' Symbol
+ TEST OK : Outline issue
+----------------------------------------------------------------
+Validation
+ TEST START : Validation
+ ITEM Assertion OK : Validation Input Message is : Attention!
+ ITEM Assertion OK : Validation Input Message is : Enter an integer from five to ten
+ ITEM Assertion OK : Validation Error Title is : You must enter a number from five to ten
+ ITEM Assertion OK : Validation Error Message is : An Error occured
+ ITEM Assertion OK : Validation Error Title is : Microsoft Excel
+END 'Validation' Symbol
+ TEST OK : Validation
+Test run finished : 10/03/2008 15:15:13
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Shapes.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Shapes.log
new file mode 100644
index 000000000000..3193a0b1094d
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Shapes.log
@@ -0,0 +1,77 @@
+Test run started : 10/16/2007 05:25:21 PM
+BEGIN Shapes_Collection_Behaviour
+ TEST START : Shapes_Collection_Behaviour
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape1'
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape2'
+ TEST Success. : Shapes_Collection_Behaviour
+END Shapes_Collection_Behaviour
+BEGIN Shapes_Select_Item
+ TEST START : Shapes_Select_Item
+ ITEM Assertion OK : Correctly selected shape through Range
+ ITEM Assertion OK : Correctly selected shape through Item
+ ITEM Assertion OK : Needs to be visually checked. Is there a line on the document?
+ ITEM Assertion OK : Needs to be visually checked. Are All Shapes Selected?
+ TEST Success. : Shapes_Select_Item
+END Shapes_Select_Item
+BEGIN Shapes_Fill
+ TEST START : Shapes_Fill
+ ITEM Assertion OK : correctly set visibility of shape fill
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set backcolor of shape fill
+ ITEM Assertion OK : the success of the TwoColorGradient method needs to be verified visually!
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set forecolor of shape fill
+ TEST Success. : Shapes_Fill
+END Shapes_Fill
+BEGIN Shapes_Line
+ TEST START : Shapes_Line
+ ITEM Assertion FAIL : correctly set weight of shape line
+ ITEM Assertion OK : correctly set visibility of shape line
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set forecolor of shape line
+ ITEM Assertion FAIL : correctly set backcolor of shape line
+ TEST Success. : Shapes_Line
+END Shapes_Line
+BEGIN Shapes_TextFrame
+ TEST START : Shapes_TextFrame
+ ITEM Assertion OK : correctly set Autosize of Shape TextFrame
+ TEST Success. : Shapes_TextFrame
+END Shapes_TextFrame
+BEGIN Shapes_SimpleGeometry
+ TEST START : Shapes_SimpleGeometery
+ ITEM Assertion OK : shape height should be 47.0425168477155 and got 46.9984222363199
+ ITEM Assertion OK : shape width should be 101.467710269751 and got 101.423615658355
+ ITEM Assertion OK : shape left should be 68.5574761223637 and got 68.5417279658754
+ ITEM Assertion OK : shape top should be 42.0251943291216 and got 42.0094461726333
+ ITEM Assertion OK : shape rotation should be 0 and got 0
+ ITEM Assertion OK : shape rotation should be 25 and got 25
+ ITEM Assertion OK : shape incrementrotation should be 50 and got 50
+ ITEM Assertion OK : shape incrementleft should be 70.6834602404119 and got 70.6677120839236
+ ITEM Assertion OK : shape incrementtop should be 91.262986503119 and got 91.2472383466307
+ TEST Success. : Shapes_SimpleGeometery
+END Shapes_SimpleGeometry
+BEGIN Shapes_Range
+ TEST START : Shapes_Range
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to return Sheet2Shape1 got Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to return Sheet2Shape3 got Sheet2Shape3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to contain 2 elements, it contains 2
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to return concated element/shape names Sheet2Shape3Sheet2Shape1 and got Sheet2Shape3Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to contain 3 elements, it contains 3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to return concated element/shape names Sheet2Shape3Sheet2Shape1Sheet2Shape2 and got Sheet2Shape3Sheet2Shape1Sheet2Shape2
+ TEST Success. : Shapes_Range
+END Shapes_Range
+BEGIN Shapes_ShapeRange
+ TEST START : Shapes_ShapeRange
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp1.left should be 90.6677120839236 and got 90.6519627935771
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp2.left should be 240.02518299054 and got 240.009433700193
+ ITEM Assertion OK : ShapeRange.IncrementTop shp1.Top should be 111.247238346631 and got 111.231489056284
+ ITEM Assertion OK : ShapeRange.IncrementTop shp2.Top should be 65.0708633026228 and got 65.0551140122763
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp1.Rotation should be 70 and got 70
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp2.Rotation should be 20 and got 20
+END Shapes_ShapeRange
+Test run finished : 10/16/2007 05:25:22 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/StrConv-test.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/StrConv-test.log
new file mode 100644
index 000000000000..c7a7d8750583
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/StrConv-test.log
@@ -0,0 +1,9 @@
+Test run started : 05/29/2008 02:51:03 PM
+BEGIN StrConv
+ TEST START : Test StrConv function
+ ITEM Assertion OK : Converts the string to uppercase characters:ABC EFG HIJ
+ ITEM Assertion OK : Converts the string to lowercase characters:abc efg hij
+ ITEM Assertion OK : Converts the first letter of every word in string to uppercase:Abc Efg Hij
+ TEST OK : Test StrConv function
+END StrConv
+Test run finished : 05/29/2008 02:51:03 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Template.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Template.log
new file mode 100644
index 000000000000..c6376c5b3732
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Template.log
@@ -0,0 +1,14 @@
+Test run started : 2008ï¼07ï¼10 11:57:05
+----------------------------------------------------------------
+TestCaseName
+ TEST START : TestCaseName
+ ITEM Assertion OK : Something has been done.
+Test Results
+============
+
+Tests passed: 1
+Tests failed: 0
+
+END 'TestCaseName
+ TEST OK : TestCaseName
+Test run finished : 2008ï¼07ï¼10 11:57:05
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestAddress.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestAddress.log
new file mode 100644
index 000000000000..4fa4bc820f59
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestAddress.log
@@ -0,0 +1,67 @@
+Test run started : 12/05/2009 11:23:35
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 Range('e3:f3') A1 style addressing
+ ITEM Assertion OK : test2 Range('e3:f3') R1C1 style addressing
+ ITEM Assertion OK : test3 Range ('e:f') A1 style addressing
+ ITEM Assertion OK : test4 Range ('e:f') R1C1 style addressing
+ ITEM Assertion OK : test5 Columns A1 style addressing
+ ITEM Assertion OK : test6 Columns R1C1 style addressing
+ ITEM Assertion OK : test7 Columns(3) A1 style addressing
+ ITEM Assertion OK : test8 Columns(3) R1C1 style addressing
+ ITEM Assertion OK : test9 Columns('e') A1 style addressing
+ ITEM Assertion OK : test10 Columns('e') R1C1 style addressing
+ ITEM Assertion OK : test11 Columns('b:d') A1 style addressing
+ ITEM Assertion OK : test12 Columns('b:d') R1C1 style addressing
+ ITEM Assertion OK : test13 Range('c1:g10').Columns A1 style addressing
+ ITEM Assertion OK : test14 Range('c1:g10').Columns R1C1 style addressing
+ ITEM Assertion OK : test15 Range('c1:g10').Columns(1) A1 style addressing
+ ITEM Assertion OK : test16 Range('c1:g10').Columns(1) R1C1 style addressing
+ ITEM Assertion OK : test17 Range('c1:g10').Columns('a') A1 style addressing
+ ITEM Assertion OK : test18 Range('c1:g10').Columns('a') R1C1 style addressing
+ ITEM Assertion OK : test19 Range('c1:g10').Columns('c') A1 style addressing
+ ITEM Assertion OK : test20 Range('c1:g10').Columns('c') R1C1 style addressing
+ ITEM Assertion OK : test21 Range('c1:g10').Columns('x:z') A1 style addressing
+ ITEM Assertion OK : test22 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test23 Range('c1:g10').Columns(30) A1 style addressing
+ ITEM Assertion OK : test24 Range('c1:g10').Columns(30) R1C1 style addressing
+ ITEM Assertion OK : test25 Worksheets('Sheet2').Cells(1, 1) A1 style addressing
+ ITEM Assertion OK : test26 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, RowAddressAbsolute is false
+ ITEM Assertion OK : test27 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, ColAddressAbsolute is false
+ ITEM Assertion OK : test28 Worksheets('Sheet2').Cells(1, 1) R1C1 style addressing
+ ITEM Assertion OK : test29 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test30 Worksheets('Sheet2').Range('A1').EntireColumn A1 style addressing
+ ITEM Assertion OK : test31 Worksheets('Sheet2').Range('A1:E5').EntireRow A1 style addressing
+ ITEM Assertion OK : test32 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test33 Worksheets('Sheet2').Range('IV65536').EntireRow A1 style addressing
+ ITEM Assertion OK : test34 Worksheets('Sheet2').Range('IU2:IV65536') A1 style addressing
+ ITEM Assertion OK : test35 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test36 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test37 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test38 Worksheets('Sheet2').Range('10:12') A1 style addressing
+ ITEM Assertion OK : test39 Worksheets('Sheet2').Range('10:12') R1C1 style addressing
+ ITEM Assertion OK : test40 Range('Sheet3!A1:B4') A1 style addressing
+ ITEM Assertion OK : test41 Range('Sheet3!A1,B1,D4:F20') A1 style addressing
+ ITEM Assertion OK : test42 Range('g20:h40').Columns('c:c')
+ ITEM Assertion OK : test43 Range('g20:h40').Columns('c:f')
+ ITEM Assertion OK : test44 Range('g20:h40').Columns(-1)
+ ITEM Assertion OK : test45 Range('c4:g10').Rows(-1)
+ ITEM Assertion OK : test46 Range('a2:b4').Rows('1:1')
+ ITEM Assertion OK : test47 Range('a2:b4').Rows('1:2')
+ ITEM Assertion OK : test48 Range('a2:b4').Rows('2:2')
+ ITEM Assertion OK : test49 Range('a2:b4').Rows('2:3')
+ ITEM Assertion OK : test50 Range(' A2:B4 ')
+ ITEM Assertion OK : test51 Range('A 2:B 4')
+ ITEM Assertion OK : test52 Range('A2 : B4 ')
+ ITEM Assertion OK : test53 Range('Sheet1 !A2 : B4 ')
+ ITEM Assertion OK : test54 Range('Sheet1! A2 : B4 ')
+Test Results
+============
+
+Tests passed: 54
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 12/05/2009 11:23:35
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest.log
new file mode 100644
index 000000000000..083819d4b64e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest.log
@@ -0,0 +1,60 @@
+Test run started : 30/05/2007 15:59:40
+BEGIN TestCalc
+ TEST START : RangeTest2
+ ITEM Assertion OK : - Range("D15").Row
+ ITEM Assertion OK : - WorkSheet("D15").Range.Row
+ ITEM Assertion OK : - Range("D15").Column
+ ITEM Assertion OK : - Worksheet.Range("D15").Column
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Columns.Count
+ ITEM Assertion OK : - Range("D1").EntireColumn.Rows.Count
+ ITEM Assertion OK : - Range("D15").ClearContent
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (get)
+ ITEM Assertion OK : - Range("B38").Orientation (get)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlDownward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlUpward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B39").WrapText (get)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (get)
+ ITEM Assertion OK : - Range("F39").MergeCells (get)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion FAIL : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("D41:D42").Replace MatchCase:=False
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM FAIL (RangeTest2)
+ TEST Not succesfully completed : RangeTest2
+END TestCalc
+Test run finished : 30/05/2007 15:59:42
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest2.log
new file mode 100644
index 000000000000..b1573c06d90e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestCalc_Rangetest2.log
@@ -0,0 +1,65 @@
+Test run started : 10/03/2008 15:15:19
+BEGIN TestCalc
+ TEST START : RangeTest3
+ ITEM Assertion OK : - setFormulaR1C1
+ ITEM Assertion OK : - getFormulaR1C1
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy(Range("I10"))
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteValues
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormulas
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormats
+ ITEM Assertion OK : PasteSpecial
+ ITEM Assertion OK : PasteSpecial SkipBlanks:=True
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationAdd
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationSubtract
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationMultiply
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationDivide
+ ITEM Assertion OK : PasteSpecial Transpose:=True
+ ITEM Assertion FAIL : ActiveWorkbook.FileFormat
+ ITEM Assertion OK : ActiveWorkbook.Name
+ ITEM Assertion OK : ActiveWorkbook.FullName und ActiveWorkbook.Path
+ ITEM Assertion FAIL : - = ActiveWorkbook.Colors(3) set
+ ITEM Assertion OK : - = ActiveWorkbook.ResetColors
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) get
+ ITEM Assertion OK : - = Range("K22").End (xlDown)
+ ITEM Assertion OK : - = Range("K22").End (xlUo)
+ ITEM Assertion OK : - = Range("K22").End (xlToLeft)
+ ITEM Assertion OK : - = Range("K22").End (xlRight)
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="x"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="<>"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="="
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter
+ ITEM Assertion OK : - ActiveSheet.Resize.Select
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion FAIL : - Application.GoTo Reference:="R[8]C[2]"
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Ungroup- please check visually
+ ITEM Assertion OK : - Range.Ungroup - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - ActiveSheet.UsedRange.Select
+ ITEM Assertion OK : - Range("A13").AddIndent
+ ITEM Assertion OK : - Range("A13").IndentLevel set
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Calculate
+ ITEM Assertion OK : Worksheet.Calculate
+ ITEM Assertion OK : - Application.Calculate
+ ITEM Assertion OK : Global.Calculate
+ ITEM Assertion OK : Calculation set
+ ITEM FAIL (RangeTest3)
+ TEST Not succesfully completed : RangeTest3
+END TestCalc
+Test run finished : 10/03/2008 15:15:21
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestIntersection.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestIntersection.log
new file mode 100644
index 000000000000..ea686a830cde
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestIntersection.log
@@ -0,0 +1,26 @@
+Test run started : 13/01/2009 14:31:43
+----------------------------------------------------------------
+TestIntersection
+ TEST START : TestIntersection
+ ITEM Assertion OK : test1 Application.Intersect( Range('A2:D10'), Range('C4:E6'))
+ ITEM Assertion OK : test2 Application.Intersect( Range('A2:D10'), Range('A4:G10'))
+ ITEM Assertion OK : test3 Application.Intersect( Range('A2:c8,d2:f8,g2:i8'), Range('A4:G10'))
+ ITEM Assertion OK : test4 Application.Intersect( Range('A4:G10'), Range('A2:c8,d2:f8,g2:i8'))
+ ITEM Assertion OK : test5 Application.Intersect( Range('A2:c8,d2:f8,g2:i8'), Range('g4:i10,A4:G10'))
+ ITEM Assertion OK : test6 Application.Intersect( Range('g4:i10,A4:G10'), Range('A2:c8,d2:f8,g2:i8'))
+ ITEM Assertion OK : test7 Application.Intersect( Range('a2:d10,b5:e10'), Range('a5:i10'))
+ ITEM Assertion OK : test8 Application.Intersect( Range('a2:c8,d2:f8'), Range('b6:e9,a6:f9'))
+ ITEM Assertion OK : test9 Application.Intersect( Range('a2:c8,e2:f8'), Range('b6:e9,a6:f9'))
+ ITEM Assertion OK : test10 Application.Intersect( Range('a1:a3,c1:c3'), Range('a2:c3'))
+ ITEM Assertion OK : test11 Application.Intersect( Range('a1:a3,b1:b3'), Range('a2:c3'))
+ ITEM Assertion OK : test12 Application.Intersect( Range('a2:d5,b3:f7,c1:g4'), Range('b2:e6'))
+ ITEM Assertion OK : test13 Range(" a2:d10,b5:e10,g13:j32 "), Range(" a5:i10,b6:e9 "), Range("b2:r5,f10:h19")
+Test Results
+============
+
+Tests passed: 13
+Tests failed: 0
+
+END 'TestIntersection
+ TEST OK : TestIntersection
+Test run finished : 13/01/2009 14:31:43
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestUnion.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestUnion.log
new file mode 100644
index 000000000000..da3cb35dedb3
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/TestUnion.log
@@ -0,0 +1,17 @@
+Test run started : 13/01/2009 14:32:16
+----------------------------------------------------------------
+TestUnion
+ TEST START : TestUnion
+ ITEM Assertion OK : test1Application.Range('A2:D10'), Range('C4:E6')
+ ITEM Assertion OK : test2Application.Range('A2:D5,a3:d4'), Range('A4:G10')
+ ITEM Assertion OK : test3Application.Range('A4:G10,A1:B6'), Range('A2:D5,A3:D4')
+ ITEM Assertion OK : test4Application.Range('A5:D10'), Range('B5:E10')
+Test Results
+============
+
+Tests passed: 4
+Tests failed: 0
+
+END 'TestUnion
+ TEST OK : TestUnion
+Test run finished : 13/01/2009 14:32:16
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Window.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Window.log
new file mode 100644
index 000000000000..ec9a6656113e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/Window.log
@@ -0,0 +1,46 @@
+Test run started : 05/29/2008 02:55:00 PM
+----------------------------------------------------------------
+ TEST START : Window-Issue
+ ITEM Assertion OK : Window.Left is: 0 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Top is: 21 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Width is: 1280 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.Height is: 752 (Test only applies to maximized Window)
+ ITEM Assertion OK : Window.ScrollColumn is: 100
+ ITEM Assertion OK : Window.ScrollColumn is: 1
+ ITEM Assertion OK : Window.ScrollRow is: 100
+ ITEM Assertion OK : Window.ScrollRow is: 1
+ ITEM Assertion OK : Window.LargeScroll(Down): ScrollRow is: 94 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.LargeScroll(Up): ScrollRow is: 1
+ ITEM Assertion OK : Window.LargeScroll(ToRight): ScrollColumn is: 58 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.LargeScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window.SmallScroll(ToRight): ScrollColumn is: 4 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Window.SmallScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window.DisplayWorkBookTabs is: False
+ ITEM Assertion OK : Window.DisplayWorkBookTabs is: True
+ ITEM Assertion OK : Window.DisplayVerticalScrollBar is: True
+ ITEM Assertion OK : Window.DisplayVerticalScrollBar is: False
+ ITEM Assertion OK : Window.DisplayHorizontalScrollBar is: False
+ ITEM Assertion OK : Window.DisplayHorizontalScrollBar is: True
+ ITEM Assertion OK : Window.DisplayHeadings is: False
+ ITEM Assertion OK : Window.DisplayHeadings is: True
+ ITEM Assertion OK : Window.DisplayOutline is: False
+ ITEM Assertion OK : Window.DisplayOutline is: True
+ ITEM Assertion OK : Window.Visible is: False
+ ITEM Assertion OK : Window.Visible is: True
+ ITEM Assertion OK : Window.Caption is: MyCaption
+ ITEM Assertion OK : Pane.ScrollColumn is: 100
+ ITEM Assertion OK : Pane.ScrollColumn is: 1
+ ITEM Assertion OK : Pane.ScrollRow is: 100
+ ITEM Assertion OK : Pane.ScrollRow is: 1
+ ITEM Assertion OK : Pane.LargeScroll(Down): ScrollRow is: 94 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.LargeScroll(Up): ScrollRow is: 1
+ ITEM Assertion OK : Pane.LargeScroll(ToRight): ScrollColumn is: 58 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.LargeScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Pane.SmallScroll(ToRight): ScrollColumn is: 4 (Test may only apply to maximized Window)
+ ITEM Assertion OK : Pane.SmallScroll(ToLeft): ScrollColumn is: 1
+ ITEM Assertion OK : Window Selection: $A$2:$D$5
+ ITEM Assertion OK : ActiveSheet name of Window: Sheet1
+ ITEM Assertion OK : Window ActiveCell: $A$1
+END 'Window-Issue' Symbol
+ TEST OK : Window-Issue
+Test run finished : 05/29/2008 02:55:01 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/bytearraystring.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/bytearraystring.log
new file mode 100644
index 000000000000..bd243283d8f1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/bytearraystring.log
@@ -0,0 +1,8 @@
+Test run started : 05/29/2008 02:25:58 PM
+BEGIN Bytearray To String
+ TEST START : Test the conversion between bytearray and string
+ ITEM Assertion OK : The number of byte is:6
+ ITEM Assertion OK : the return string is: abc
+ TEST OK : Test the conversion between bytearray and string
+END Bytearray To String
+Test run finished : 05/29/2008 02:25:58 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/dateserial.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/dateserial.log
new file mode 100644
index 000000000000..4dd5f53160f2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/dateserial.log
@@ -0,0 +1,9 @@
+Test run started : 01/24/2008 01:24:50 PM
+BEGIN DateSerial
+ TEST START : Test DateSerial function
+ ITEM Assertion OK : the return date is: 06/15/1999
+ ITEM Assertion OK : the return date is: 06/15/1999
+ ITEM Assertion OK : the return date is: 06/15/1999
+ TEST OK : Test DateSerial function
+END DateSerial
+Test run finished : 01/24/2008 01:24:50 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/datevalue.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/datevalue.log
new file mode 100644
index 000000000000..830d5e7b6c3e
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/datevalue.log
@@ -0,0 +1,8 @@
+Test run started : 01/24/2008 01:24:41 PM
+BEGIN DateValue
+ TEST START : Test DateValue function
+ ITEM Assertion OK : the return date is: 02/12/1969
+ ITEM Assertion OK : the return date is: 01/21/2008
+ TEST OK : Test DateValue function
+END DateValue
+Test run finished : 01/24/2008 01:24:41 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/format.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/format.log
new file mode 100644
index 000000000000..96725bf7daa8
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/format.log
@@ -0,0 +1,36 @@
+Test run started : 2008ï¼09ï¼18 11:35:34
+BEGIN Format
+ TEST START : Test Predefined_Number_Format_Sample function
+ ITEM Assertion OK : General Number: 562486.2356
+ ITEM Assertion OK : Fixed: 0.20
+ ITEM Assertion OK : Standard: 562,486.24
+ ITEM Assertion OK : Percent: 75.21%
+ ITEM Assertion OK : Scientific: 5.62E+05
+ ITEM Assertion OK : Scientific: -3.46E+03
+ ITEM Assertion OK : Yes/No: No
+ ITEM Assertion OK : Yes/No: Yes
+ ITEM Assertion OK : True/False: False
+ ITEM Assertion OK : True/False: True
+ ITEM Assertion OK : On/Off: Off
+ ITEM Assertion OK : On/Off: On
+ TEST OK : Test Predefined_Number_Format_Sample function
+ TEST START : Test Custom_Number_Format_Sample function
+ ITEM Assertion OK : 00.0000: 23.6750
+ ITEM Assertion OK : 00.00: 23.68
+ ITEM Assertion OK : 00000: 02658
+ ITEM Assertion OK : 00.00: 2658.00
+ ITEM Assertion OK : ##.####: 23.675
+ ITEM Assertion OK : ##.##: 23.68
+ ITEM Assertion OK : #,###.##: 12,345.25
+ ITEM Assertion OK : ##.00%: 25.00%
+ ITEM Assertion OK : #,###: 1,000,000
+ ITEM Assertion OK : ######E-###: 109838E-5
+ ITEM Assertion OK : $#,###.##: $2,345.25
+ ITEM Assertion OK : ##.###\%: .25%
+ TEST OK : Test Custom_Number_Format_Sample function
+ TEST START : Test Custom_Text_Format_Sample function
+ ITEM Assertion OK : <: vba
+ ITEM Assertion OK : >: VBA
+ TEST OK : Test Custom_Text_Format_Sample function
+END Format
+Test run finished : 2008ï¼09ï¼18 11:35:34
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/pagesetup.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/pagesetup.log
new file mode 100644
index 000000000000..f04585c3f9e1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/pagesetup.log
@@ -0,0 +1,77 @@
+Test run started : 07/21/2008 02:00:06 PM
+BEGIN PageSetup
+ TEST START : Sheet_PrintArea
+ ITEM Assertion OK : PrintArea has changed as expected
+ TEST OK : Sheet_PrintArea
+ TEST START : Test margins (no headers)
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.RightMargin set/get
+ ITEM Assertion OK : PageSetup.TopMargin set/get
+ ITEM Assertion OK : PageSetup.BottomMargin set/get
+Verify that page margins on sheet 1 are all 0.5inch
+ TEST OK : Test margins (no headers)
+ TEST START : Test margins (headers)
+ ITEM Assertion OK : PageSetup.HeaderMargin set/get
+ ITEM Assertion OK : PageSetup.FooterMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+Verify that top/bottom/header/footer page margins on sheet 2 are all 0.5inch
+ TEST OK : Test margins (headers)
+ TEST START : Test header/footer text
+ ITEM Assertion OK : PageSetup.LeftHeader set
+ ITEM Assertion OK : PageSetup.LeftHeader set/get
+ ITEM Assertion OK : PageSetup.CenterHeader set
+ ITEM Assertion OK : PageSetup.CenterHeader set/get
+ ITEM Assertion OK : PageSetup.RightHeader set
+ ITEM Assertion OK : PageSetup.RightHeader set/get
+ ITEM Assertion OK : PageSetup.LeftFooter set
+ ITEM Assertion OK : PageSetup.LeftFooter set/get
+ ITEM Assertion OK : PageSetup.CenterFooter set
+ ITEM Assertion OK : PageSetup.CenterFooter set/get
+ ITEM Assertion OK : PageSetup.RightFooter set
+ ITEM Assertion OK : PageSetup.RightFooter set/get
+Verify that headers on sheet 2 are Ready,to,go
+Verify that footers on sheet 2 are This,now,Works
+ TEST OK : Test header/footer text
+ TEST START : Test zoom
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Zoom set/get
+Verify that sheet 1 zoom is 10%
+ TEST OK : Test zoom
+ TEST START : Test orientation
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Orientation set/get
+Verify that sheet 1 orientation is now landscape
+ TEST OK : Test orientation
+ TEST START : Test order
+ ITEM Assertion OK : PageSetup.Order get
+ ITEM Assertion OK : PageSetup.Order set/get
+Verify that order on sheet 1 is now over, then down.
+ TEST OK : Test order
+ TEST START : Test first page number
+ ITEM Assertion OK : PageSetup.FirstPageNumber get
+ ITEM Assertion OK : PageSetup.FirstPageNumber set/get
+Verify that first page number on sheet 1 is now 2.
+ TEST OK : Test first page number
+ TEST START : Test center vertically
+ ITEM Assertion OK : PageSetup.CenterVertically get
+ ITEM Assertion OK : PageSetup.CenterVertically set/get
+Verify that CenterVertically on sheet 1 is now true.
+ TEST OK : Test center vertically
+ TEST START : Test center horizontally
+ ITEM Assertion OK : PageSetup.CenterHorizontally get
+ ITEM Assertion OK : PageSetup.CenterHorizontally set/get
+Verify that CenterHorizontally on sheet 1 is now true.
+ TEST OK : Test center horizontally
+ TEST START : Test FitToPagesTall
+ ITEM Assertion OK : PageSetup.FitToPagesTall set/get
+ TEST OK : Test FitToPagesTall
+ TEST START : Test FitToPagesWide
+ ITEM Assertion OK : PageSetup.FitToPagesWide set/get
+ TEST OK : Test FitToPagesWide
+ TEST START : Test PrintHeadings
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ TEST OK : Test PrintHeadings
+END PageSetup
+Test run finished : 07/21/2008 02:00:07 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/partition.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/partition.log
new file mode 100644
index 000000000000..7b4f2a01bead
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/partition.log
@@ -0,0 +1,11 @@
+Test run started : 12/10/2007 11:26:43 AM
+BEGIN Partition
+ TEST START : Test Partition function
+ ITEM Assertion OK : the number 20 occurs in the range:20:24
+ ITEM Assertion OK : the number 20 occurs in the range: 20: 20
+ ITEM Assertion OK : the number 120 occurs in the range:100:
+ ITEM Assertion OK : the number -5 occurs in the range: : -1
+ ITEM Assertion OK : the number 2 occurs in the range: 2: 3
+ TEST OK : Test Partition function
+END Partition
+Test run finished : 12/10/2007 11:26:43 AM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/range-4.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/range-4.log
new file mode 100644
index 000000000000..fb37b6ff201b
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/range-4.log
@@ -0,0 +1,16 @@
+Test run started : 2008ï¼06ï¼19 17:14:57
+----------------------------------------------------------------
+ShowDetail-Issue
+ TEST START : ShowDetail-Issue
+ ITEM Assertion OK : Range.ShowDetail is True
+ ITEM Assertion OK : Range.ShowDetail is False
+END 'ShowDetail-Issue' Symbol
+ TEST OK : ShowDetail-Issue
+----------------------------------------------------------------
+RangeMerged-Issue
+ TEST START : RangeMerged-Issue
+ ITEM Assertion OK : Range.RangeMerged is $F$2:$H$5
+ ITEM Assertion OK : The first address of Range.RangeMerged is $F$2
+END 'RangeMerged-Issue' Symbol
+ TEST OK : RangeMerged-Issue
+Test run finished : 2008ï¼06ï¼19 17:14:57
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/replace.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/replace.log
new file mode 100644
index 000000000000..8f600faaa6b1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/replace.log
@@ -0,0 +1,14 @@
+Test run started : 09/05/2008 10:21:46 AM
+BEGIN Replace
+ TEST START : Test Replace function
+ ITEM Assertion OK : common string:aefefdBc
+ ITEM Assertion OK : expression string:aefefdef
+ ITEM Assertion OK : binanary compare:aefefdBc
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : start = 3:cefdBc
+ ITEM Assertion OK : count = 2: aefefdBc
+ ITEM Assertion OK : start = 1, count = 0, not support in Unix: abcbcdBc
+ TEST OK : Test Replace function
+END Replace
+Test run finished : 09/05/2008 10:21:47 AM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/stringplusdouble.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/stringplusdouble.log
new file mode 100644
index 000000000000..6e8b8d994bd1
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/stringplusdouble.log
@@ -0,0 +1,62 @@
+Test run started : 05/29/2008 02:51:22 PM
+BEGIN String Plus Double
+ TEST START : double = string + double
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: 0
+The next compute raises error: s = null, d = 20, r = s + d
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 100
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 30
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = null, r = s & d
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s & d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: -1
+ TEST OK : double = string + double
+ TEST START : string = string + double
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: 0
+The next compute raises error: s = null, d = 20, r = s + d
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 100
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 30
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: abc0
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: abc20
+ TEST OK : string = string + double
+ TEST START : double = string + string
+The next compute raises error: s = null, d = null, r = s + d
+ ITEM Assertion OK : s = null, d = null, r = s + d .The result is: -1
+The next compute raises error: s = null, d = null, r = s & d
+ ITEM Assertion OK : s = null, d = null, r = s & d .The result is: -1
+ ITEM Assertion OK : s = null, d = 20, r = s + d .The result is: 20
+ ITEM Assertion OK : s = null, d = 20, r = s & d .The result is: 20
+ ITEM Assertion OK : s = '10', d = null, r = s + d .The result is: 10
+ ITEM Assertion OK : s = '10', d = null, r = s & d .The result is: 10
+ ITEM Assertion OK : s = '10', d = 20, r = s + d .The result is: 1020
+ ITEM Assertion OK : s = '10', d = 20, r = s & d .The result is: 1020
+The next compute raises error: s = 'abc', d = null, r = s + d
+ ITEM Assertion OK : s = 'abc', d = null, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = null, r = s & d
+ ITEM Assertion OK : s = 'abc', d = null, r = s & d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s + d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s + d .The result is: -1
+The next compute raises error: s = 'abc', d = 20, r = s & d
+ ITEM Assertion OK : s = 'abc', d = 20, r = s & d .The result is: -1
+ TEST OK : double = string + string
+END String Plus Double
+Test run finished : 05/29/2008 02:51:22 PM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/unix/window2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/window2.log
new file mode 100644
index 000000000000..8e26d0580621
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/unix/window2.log
@@ -0,0 +1,41 @@
+Test run started : 2008ï¼09ï¼22 11:18:57
+BEGIN Window2
+ TEST START : Test Window.SplitRow
+ ITEM Assertion OK : Test SplitColumn: 2 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitRow: 2 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitVertical: 242.465788476212
+ ITEM Assertion OK : Test SplitHorizontal: 242.465788476212
+ ITEM Assertion OK : Test SplitRow: 4 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitColumn: 3 (Test only applies to maximized Window and at least has 800*600 solotion)
+ ITEM Assertion OK : Test SplitColumn: 0
+ ITEM Assertion OK : Test SplitRow: 0
+ TEST OK : Test Window.SplitRow
+ TEST START : Test Window.DisplayGridlines
+ ITEM Assertion OK : Test gridlines are on
+ ITEM Assertion OK : Test gridlines are off
+ TEST OK : Test Window.DisplayGridlines
+ TEST START : Test Window.DisplayHeadings
+ ITEM Assertion OK : Test Headings are on
+ ITEM Assertion OK : Test Headings are off
+ TEST OK : Test Window.DisplayHeadings
+ TEST START : Test Window.Visibility
+ ITEM Assertion OK : Window is visible
+ ITEM Assertion OK : Window is not visible
+ TEST OK : Test Window.Visibility
+ TEST START : Test Window.FreezePanes
+ ITEM Assertion OK : Test no panes frozen
+ ITEM Assertion OK : Test panes frozen at center
+ ITEM Assertion OK : Test panes frozen at split
+ TEST OK : Test Window.FreezePanes
+ TEST START : Test Window.View
+ TEST OK : Test Window.View
+ TEST START : Test Window.Zoom
+ ITEM Assertion OK : Test zoom=100%
+ ITEM Assertion OK : Test zoom=150%
+ TEST OK : Test Window.Zoom
+ TEST START : Test Windows.Count
+ ITEM Assertion OK : Windows Count: 1
+ ITEM Assertion OK : Application.Windows Count: 1
+ TEST OK : Test Windows.Count
+END Window2
+Test run finished : 2008ï¼09ï¼22 11:18:58
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/AutoFilter.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/AutoFilter.log
new file mode 100644
index 000000000000..b8d0b85a8ff9
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/AutoFilter.log
@@ -0,0 +1,20 @@
+Test run started : 16/10/2007 17:42:01
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 'starts with' string criteria
+ ITEM Assertion OK : test2 'not equal to' string criteria
+ ITEM Assertion OK : test3 'ends with' string criteria
+ ITEM Assertion OK : test4 field 'all'
+ ITEM Assertion OK : test5 numeric '<15'
+ ITEM Assertion OK : test6 numeric '>=15'
+ ITEM Assertion OK : test7 numeric '<=12'
+Test Results
+============
+
+Tests passed: 7
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 16/10/2007 17:42:02
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/MiscRangeTests.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/MiscRangeTests.log
new file mode 100644
index 000000000000..d190abb5f645
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/MiscRangeTests.log
@@ -0,0 +1,45 @@
+Test run started : 17/07/2007 15:08:56
+----------------------------------------------------------------
+MiscRangeTests
+ TEST START : MiscRangeTests
+ ITEM Assertion OK : test 1
+ ITEM Assertion OK : test 2
+ ITEM Assertion OK : test 3
+ ITEM Assertion OK : test 4
+ ITEM Assertion OK : test 5
+ ITEM Assertion OK : test 6
+ ITEM Assertion OK : test 7
+ ITEM Assertion OK : test 8
+ ITEM Assertion OK : test 9
+ ITEM Assertion OK : test 10
+ ITEM Assertion OK : test 11
+ ITEM Assertion OK : test 12
+ ITEM Assertion OK : test 13
+ ITEM Assertion OK : test 14
+ ITEM Assertion OK : test 15
+ ITEM Assertion OK : test 16
+ ITEM Assertion OK : test 17
+ ITEM Assertion OK : test 18
+ ITEM Assertion OK : test 19
+ ITEM Assertion OK : test 20
+ ITEM Assertion OK : test 21
+ ITEM Assertion OK : test 22
+ ITEM Assertion OK : test 23
+ ITEM Assertion OK : test 24
+ ITEM Assertion OK : test 25
+ ITEM Assertion OK : test 26
+ ITEM Assertion OK : test 27
+ ITEM Assertion OK : test 28
+ ITEM Assertion OK : test 29
+ ITEM Assertion OK : test 30
+ ITEM Assertion OK : test 31
+No. tests: 31
+Summary
+=======
+Run: 31
+Passed: 31
+Failed: 0
+
+END 'MiscRangeTests
+ TEST OK : MiscRangeTests
+Test run finished : 17/07/2007 15:08:59
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-2.log
new file mode 100644
index 000000000000..b80d996e3d3f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-2.log
@@ -0,0 +1,68 @@
+Test run started : 10/07/2007 01:55:47
+----------------------------------------------------------------
+ClearFormtsIssue
+ TEST START : ClearFormtsIssue
+ ITEM Assertion OK : Range.Font.Bold is: True
+ ITEM Assertion OK : Range.Font.Bold is: False
+END 'ClearFormtsIssue' Symbol
+ TEST OK : ClearFormtsIssue
+----------------------------------------------------------------
+VerticalAlignment-Issue
+ TEST START : VerticalAlignment-Issue
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : - Range.VerticalAlignment (get)
+ ITEM Assertion OK : - Range.VerticalAlignment (set)
+ ITEM Assertion OK : Range.VeritcalAlignment is Null
+END 'VerticalAlignment-Issue' Symbol
+ TEST OK : VerticalAlignment-Issue
+----------------------------------------------------------------
+HorizontalAlignment-Issue
+ TEST START : HorizontalAlignment-Issue
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : - Range.HorizontalAlignment (get)
+ ITEM Assertion OK : - Range.HorizontalAlignment (set)
+ ITEM Assertion OK : Range.HorizontalAlignment is Null
+END 'HorizontalAlignment-Issue' Symbol
+ TEST OK : HorizontalAlignment-Issue
+----------------------------------------------------------------
+WrapText-Issue
+ TEST START : WrapText-Issue
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : - Range.WrapText (get)
+ ITEM Assertion OK : Range.WrapText is Null
+END 'WrapText-Issue' Symbol
+ TEST OK : WrapText-Issue
+----------------------------------------------------------------
+FontBorderIssues
+ TEST START : FontBorderIssues
+ ITEM Assertion OK : - = Borders.Color (getColor)
+ ITEM Assertion OK : - = Font.Color (getColor)
+END 'FontBorderIssues' Symbol
+ TEST OK : FontBorderIssues
+----------------------------------------------------------------
+RangeSizeIssues
+ TEST START : RangeSizeIssues
+ ITEM Assertion OK : Range.Left is: 100.5291
+ ITEM Assertion OK : Range.Top is: 95.39775
+ ITEM Assertion OK : Range.Width is: 191.25
+ ITEM Assertion OK : Range.Height is: 271.5
+END 'RangeSizeIssues' Symbol
+ TEST OK : RangeSizeIssues
+----------------------------------------------------------------
+ApplicationIssues
+ TEST START : ApplicationIssues
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range.Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Application.ActiveSheet.Name: Sheet1
+END 'ApplicationIssues' Symbol
+ TEST OK : ApplicationIssues
+Test run finished : 10/07/2007 01:55:48
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-3.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-3.log
new file mode 100644
index 000000000000..365d126a7e2d
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges-3.log
@@ -0,0 +1,8 @@
+Test run started : 10/07/2007 01:55:51
+----------------------------------------------------------------
+MyGoalseek-Issue
+ TEST START : MyGoalseek-Issue
+ ITEM Assertion OK : Variable Range value: 15
+END 'MyGoalseek-Issue' Symbol
+ TEST OK : MyGoalseek-Issue
+Test run finished : 10/07/2007 01:55:51
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges.log
new file mode 100644
index 000000000000..fe77d7a9d467
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Ranges.log
@@ -0,0 +1,280 @@
+Test run started : 10/07/2007 01:55:56
+----------------------------------------------------------------
+ApplicationMethods
+ TEST START : ApplicationMethods
+ ITEM Assertion OK : Name of Workbook is: Ranges.xls
+ ITEM Assertion OK : Address of Application.Columns is: $A:$A
+ ITEM Assertion OK : Address of Application.Rows is: $1:$1
+ ITEM Assertion OK : Address of Application.Range is: $1:$1,$5:$7
+ ITEM Assertion OK : Please check manually: DefaultFilePath is: C:\Documents and Settings\vituosity\My Documents
+ ITEM Assertion OK : Please check manually: Library Path is: C:\Documents and Settings\vituosity\Application Data\OpenOffice.org2\user\basic
+ ITEM Assertion OK : Please check manually: Template Path is: C:\Documents and Settings\vituosity\Application Data\OpenOffice.org2\user\template
+ ITEM Assertion OK : FileSeparator is \
+ ITEM Assertion OK : Name of ActiveWorkbook is: Ranges.xls
+END 'ApplicationMethods' Symbol
+ TEST OK : ApplicationMethods
+----------------------------------------------------------------
+Insert-Issue
+ TEST START : Insert-Issue
+ ITEM Assertion OK : Insert with xlShiftToRight: 10
+END 'Insert-Issue' Symbol
+ TEST OK : Insert-Issue
+----------------------------------------------------------------
+MergeCells-Issue
+ TEST START : MergeCells-Issue
+ ITEM Assertion OK : Range.MergeCells is True
+ ITEM Assertion FAIL : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 13
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion FAIL : MergeCells of Second Area is null : False
+ ITEM Assertion FAIL : MergeCells of Ranges is Null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+ ITEM Assertion OK : Range.MergeCells is False
+ ITEM Assertion OK : MergeCells is null: False
+ ITEM Assertion OK : RowCount after Merge: 7
+END 'MergeCells-Issue' Symbol
+ TEST OK : MergeCells-Issue
+----------------------------------------------------------------
+Areas-Issue
+ TEST START : Areas-Issue
+ ITEM Assertion OK : Range Areas Count is2
+ ITEM Assertion OK : First Range Address is: $E$8:$G$13
+ ITEM Assertion OK : First Row is: 8
+ ITEM Assertion OK : First Column is: 5
+ ITEM Assertion OK : EntireRow Address is: $8:$13,$13:$19
+ ITEM Assertion OK : EntireColumn Address is: $E:$G,$G:$K
+ ITEM Assertion OK : Range Count:53
+END 'Areas-Issue' Symbol
+ TEST OK : Areas-Issue
+----------------------------------------------------------------
+Fill-Methods-Issue
+ TEST START : Fill-Methods-Issue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyRightFillValue
+ ITEM Assertion OK : Range Value after FillDown: MyBottomFillValue
+END 'Fill-Methods-Issue' Symbol
+ TEST OK : Fill-Methods-Issue
+----------------------------------------------------------------
+Range/Item-Method-Issue
+ TEST START : Range/Item-Method-Issue
+ ITEM Assertion OK : Range of multiple columns is: $A:$A,$C:$C
+ ITEM Assertion OK : Range of multiple rows is: $1:$1,$5:$7
+ ITEM Assertion OK : Range of several columns is: $C:$E,$D:$D
+ ITEM Assertion OK : Range of several rows is: $5:$8,$6:$10
+ ITEM Assertion OK : Range of several single cells is: $C$5,$E$8
+ ITEM Assertion OK : Range of several named ranges is: $L$1:$M$6,$E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range of a single Item Cell is: $E$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$21
+ ITEM Assertion OK : Range of a single Item Cell is: $F$10
+END 'Range/Item-Method-Issue' Symbol
+ TEST OK : Range/Item-Method-Issue
+----------------------------------------------------------------
+R1C1-Formulas-Issue
+ TEST START : R1C1-Formulas-Issue
+ ITEM Assertion OK : R1C1 Range.Formula is: =IF(OR(R[-2]C[1]=0,RC[2]="YES"),"")
+ ITEM Assertion FAIL : Range.Formula is: =IF(OR(J8=0,RC[2]="YES"),"")
+END 'R1C1-Formulas-Issue' Symbol
+ TEST OK : R1C1-Formulas-Issue
+----------------------------------------------------------------
+Verify_Delete
+ TEST START : Verify_Delete
+ ITEM Assertion OK : Ranges are intersecting: $G$13
+ ITEM Assertion OK : Delete with Default: $AJ$4
+ ITEM Assertion OK : Delete with ShifttoLeft: $AJ$4
+ ITEM Assertion OK : Delete with ShiftUp: $M$22
+END 'Verify_Delete' Symbol
+ TEST OK : Verify_Delete
+----------------------------------------------------------------
+Value-Issue
+ TEST START : Value-Issue
+ ITEM Assertion OK : Value of Range is: 12.3
+ ITEM Assertion OK : Text of Range is: 12.3
+ ITEM Assertion OK : Range has Formula: False
+ ITEM Assertion OK : Cell has Formula: False
+ ITEM Assertion FAIL : Text of Range is null: False
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Cell has Formula: True
+ ITEM Assertion OK : Value of Cell is: 12
+ ITEM Assertion OK : Application.Calculation is : -4135
+ ITEM Assertion OK : Calculation is automated: True
+ ITEM Assertion OK : Range has Formula: True
+ ITEM Assertion OK : Value of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Text of Cell is: 16
+ ITEM Assertion OK : Range has Formula after 'ClearContents: False
+ ITEM Assertion OK : Text of Cell is:
+ ITEM Assertion OK : Text of Cell is:
+END 'Value-Issue' Symbol
+ TEST OK : Value-Issue
+----------------------------------------------------------------
+AutoFit issue
+ TEST START : AutoFit issue
+ ITEM Assertion OK : Columns.AutoFit: CurrentWidth is 467
+ ITEM Assertion FAIL : Rows.AutoFit: CurrentHeight is 78
+END 'AutoFit issue' Symbol
+ TEST OK : AutoFit issue
+----------------------------------------------------------------
+Selections
+ TEST START : Selections
+ ITEM Assertion OK : ActiveCell is : $E$8
+ ITEM Assertion OK : Active Cell is : $E$8
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+ ITEM Assertion OK : Number of Cells in Range: 52
+END 'Selections' Symbol
+ TEST OK : Selections
+----------------------------------------------------------------
+Offset-Resize
+ TEST START : Offset-Resize
+ ITEM Assertion OK : Offset is : $G$10:$I$15,$I$15:$M$21
+ ITEM Assertion OK : Offset is : $G$7:$I$12,$I$12:$M$18
+ ITEM Assertion OK : Resized Range is : $A$20:$D$23
+END 'Offset-Resize' Symbol
+ TEST OK : Offset-Resize
+----------------------------------------------------------------
+Ranges-Address
+ TEST START : Ranges-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13,$G$13:$K$19
+ ITEM Assertion OK : Range Address is: $E8:$G13,$G13:$K19
+ ITEM Assertion OK : Range Address is: E$8:G$13,G$13:K$19
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R8C5:R13C7,R13C7:R19C11
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5],R[11]C[5]:R[17]C[9]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13,$G$13:$K$19
+END 'Ranges-Address' Symbol
+ TEST OK : Ranges-Address
+----------------------------------------------------------------
+Range-Address
+ TEST START : Range-Address
+ ITEM Assertion OK : Range Address is: $E$8:$G$13
+ ITEM Assertion OK : Range Address is: $E8:$G13
+ ITEM Assertion OK : Range Address is: E$8:G$13
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion FAIL : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R8C5:R13C7
+ ITEM Assertion OK : Range Address is: R[6]C[3]:R[11]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$8:$G$13
+END 'Range-Address' Symbol
+ TEST OK : Range-Address
+----------------------------------------------------------------
+Column-Address
+ TEST START : Column-Address
+ ITEM Assertion OK : Range Address is: $F$8:$F$13
+ ITEM Assertion OK : Range Address is: $F8:$F13
+ ITEM Assertion OK : Range Address is: F$8:F$13
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion FAIL : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R8C6:R13C6
+ ITEM Assertion OK : Range Address is: R[6]C[4]:R[11]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$8:$F$13
+END 'Column-Address' Symbol
+ TEST OK : Column-Address
+----------------------------------------------------------------
+Row-Address
+ TEST START : Row-Address
+ ITEM Assertion OK : Range Address is: $E$9:$G$9
+ ITEM Assertion OK : Range Address is: $E9:$G9
+ ITEM Assertion OK : Range Address is: E$9:G$9
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion FAIL : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R9C5:R9C7
+ ITEM Assertion OK : Range Address is: R[7]C[3]:R[7]C[5]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$E$9:$G$9
+END 'Row-Address' Symbol
+ TEST OK : Row-Address
+----------------------------------------------------------------
+SingleCell-Address
+ TEST START : SingleCell-Address
+ ITEM Assertion OK : Range Address is: $F$9
+ ITEM Assertion OK : Range Address is: $F9
+ ITEM Assertion OK : Range Address is: F$9
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion FAIL : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R9C6
+ ITEM Assertion OK : Range Address is: R[7]C[4]
+ ITEM Assertion OK : RangeAddress is [Ranges.xls]Sheet1!$F$9
+END 'SingleCell-Address' Symbol
+ TEST OK : SingleCell-Address
+----------------------------------------------------------------
+Heights and Widths
+ TEST START : Heights and Widths
+ ITEM Assertion OK : Range RowHeight is 40
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 240
+ ITEM Assertion FAIL : Range Width is 675
+ ITEM Assertion OK : Range RowHeight is 50
+ ITEM Assertion OK : Range ColumnWidth is 50
+ ITEM Assertion OK : Range Height is 300
+ ITEM Assertion FAIL : Range Width is 675
+ ITEM Assertion FAIL : RowHeight is null: False
+ ITEM Assertion OK : ColumnWidth is null: True
+END 'Heights and Widths' Symbol
+ TEST OK : Heights and Widths
+----------------------------------------------------------------
+RangeRowColumn-Issue
+ TEST START : RangeRowColumn-Issue
+ ITEM Assertion OK : Row is: 8
+ ITEM Assertion OK : Column is: 5
+ ITEM Assertion OK : EntireRow.Columns.Count = 256
+ ITEM Assertion OK : EntireColumn.Rows.Count = 131072
+END 'RangeRowColumn-Issue' Symbol
+ TEST OK : RangeRowColumn-Issue
+----------------------------------------------------------------
+Replace-Issue
+ TEST START : Replace-Issue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: YourValue
+ ITEM Assertion OK : Value after Replace: ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New ReplaceValue
+ ITEM Assertion OK : Value after Replace: New Replace
+ ITEM Assertion OK : Value after Replace:
+END 'Replace-Issue' Symbol
+ TEST OK : Replace-Issue
+----------------------------------------------------------------
+Hidden-Issue
+ TEST START : Hidden-Issue
+ ITEM Assertion OK : - Range.Rows.Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Hidden (get)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Rows.Item(1).Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Hidden (get)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (set)
+ ITEM Assertion OK : - Range.Columns.Item(1).Hidden (get)
+END 'Hidden-Issue' Symbol
+ TEST OK : Hidden-Issue
+----------------------------------------------------------------
+End issue
+ TEST START : End issue
+ ITEM Assertion OK : - = $E$48
+ ITEM Assertion OK : - = $E$1
+ ITEM Assertion OK : - = $E$3
+ ITEM Assertion OK : - = $A$8
+ ITEM Assertion OK : - = $B$8
+ ITEM Assertion OK : - = $IV$8
+ ITEM Assertion OK : - = $Z$8
+END 'End issue' Symbol
+ TEST OK : End issue
+----------------------------------------------------------------
+Outline issue
+ TEST START : Outline issue
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+END 'Outline issue' Symbol
+ TEST OK : Outline issue
+----------------------------------------------------------------
+Validation
+ TEST START : Validation
+ ITEM Assertion OK : Validation Input Message is : Attention!
+ ITEM Assertion OK : Validation Input Message is : Enter an integer from five to ten
+ ITEM Assertion OK : Validation Error Title is : You must enter a number from five to ten
+ ITEM Assertion OK : Validation Error Message is : An Error occured
+ ITEM Assertion OK : Validation Error Title is : Microsoft Excel
+END 'Validation' Symbol
+ TEST OK : Validation
+Test run finished : 10/07/2007 01:56:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/Shapes.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Shapes.log
new file mode 100644
index 000000000000..fe62ab03d3f2
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/Shapes.log
@@ -0,0 +1,77 @@
+Test run started : 16/10/2007 17:46:03
+BEGIN Shapes_Collection_Behaviour
+ TEST START : Shapes_Collection_Behaviour
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape1'
+ ITEM Assertion OK : Name of indexed shape should be 'Sheet2Shape2'
+ TEST Success. : Shapes_Collection_Behaviour
+END Shapes_Collection_Behaviour
+BEGIN Shapes_Select_Item
+ TEST START : Shapes_Select_Item
+ ITEM Assertion OK : Correctly selected shape through Range
+ ITEM Assertion OK : Correctly selected shape through Item
+ ITEM Assertion OK : Needs to be visually checked. Is there a line on the document?
+ ITEM Assertion OK : Needs to be visually checked. Are All Shapes Selected?
+ TEST Success. : Shapes_Select_Item
+END Shapes_Select_Item
+BEGIN Shapes_Fill
+ TEST START : Shapes_Fill
+ ITEM Assertion OK : correctly set visibility of shape fill
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set backcolor of shape fill
+ ITEM Assertion OK : the success of the TwoColorGradient method needs to be verified visually!
+ ITEM Assertion OK : correctly set forecolor of shape fill
+ ITEM Assertion FAIL : correctly set forecolor of shape fill
+ TEST Success. : Shapes_Fill
+END Shapes_Fill
+BEGIN Shapes_Line
+ TEST START : Shapes_Line
+ ITEM Assertion FAIL : correctly set weight of shape line
+ ITEM Assertion OK : correctly set visibility of shape line
+ ITEM Assertion OK : correctly set transparency of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set dash style of shape line
+ ITEM Assertion OK : correctly set forecolor of shape line
+ ITEM Assertion FAIL : correctly set backcolor of shape line
+ TEST Success. : Shapes_Line
+END Shapes_Line
+BEGIN Shapes_TextFrame
+ TEST START : Shapes_TextFrame
+ ITEM Assertion OK : correctly set Autosize of Shape TextFrame
+ TEST Success. : Shapes_TextFrame
+END Shapes_TextFrame
+BEGIN Shapes_SimpleGeometry
+ TEST START : Shapes_SimpleGeometery
+ ITEM Assertion OK : shape height should be 49.4519655148368 and got 49.4078709034412
+ ITEM Assertion OK : shape width should be 101.467710269751 and got 101.423615658355
+ ITEM Assertion OK : shape left should be 68.5574761223637 and got 68.5417279658754
+ ITEM Assertion OK : shape top should be 44.1511784471699 and got 44.1354302906816
+ ITEM Assertion OK : shape rotation should be 0 and got 0
+ ITEM Assertion OK : shape rotation should be 25 and got 25
+ ITEM Assertion OK : shape incrementrotation should be 50 and got 50
+ ITEM Assertion OK : shape incrementleft should be 69.7480272284707 and got 69.7322790719824
+ ITEM Assertion OK : shape incrementtop should be 93.8141674447769 and got 93.7984192882885
+ TEST Success. : Shapes_SimpleGeometery
+END Shapes_SimpleGeometry
+BEGIN Shapes_Range
+ TEST START : Shapes_Range
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(1) to return Sheet2Shape1 got Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to contain 1 element, it contains 1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Sheet2Shape3) to return Sheet2Shape3 got Sheet2Shape3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to contain 2 elements, it contains 2
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array(3, 1) to return concated element/shape names Sheet2Shape3Sheet2Shape1 and got Sheet2Shape3Sheet2Shape1
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to contain 3 elements, it contains 3
+ ITEM Assertion OK : expected Sheets(2).Shapes.Range(Array('Sheet2Shape3', 1, 'Sheet2Shape2')) to return concated element/shape names Sheet2Shape3Sheet2Shape1Sheet2Shape2 and got Sheet2Shape3Sheet2Shape1Sheet2Shape2
+ TEST Success. : Shapes_Range
+END Shapes_Range
+BEGIN Shapes_ShapeRange
+ TEST START : Shapes_ShapeRange
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp1.left should be 89.7322790719824 and got 89.7165297816359
+ ITEM Assertion OK : ShapeRange.IncrementLeft shp2.left should be 240.02518299054 and got 240.009433700193
+ ITEM Assertion OK : ShapeRange.IncrementTop shp1.Top should be 113.798419288289 and got 113.782669997942
+ ITEM Assertion OK : ShapeRange.IncrementTop shp2.Top should be 67.4519655148368 and got 67.4362162244903
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp1.Rotation should be 70 and got 70
+ ITEM Assertion OK : ShapeRange.IncrementRotation shp2.Rotation should be 20 and got 20
+END Shapes_ShapeRange
+Test run finished : 16/10/2007 17:46:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestAddress.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestAddress.log
new file mode 100644
index 000000000000..cc51e378f06a
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestAddress.log
@@ -0,0 +1,62 @@
+Test run started : 17/07/2007 15:26:54
+----------------------------------------------------------------
+TestAddress
+ TEST START : TestAddress
+ ITEM Assertion OK : test1 Range('e3:f3') A1 style addressing
+ ITEM Assertion OK : test2 Range('e3:f3') R1C1 style addressing
+ ITEM Assertion OK : test3 Range ('e:f') A1 style addressing
+ ITEM Assertion OK : test4 Range ('e:f') R1C1 style addressing
+ ITEM Assertion OK : test5 Columns A1 style addressing
+ ITEM Assertion OK : test6 Columns R1C1 style addressing
+ ITEM Assertion OK : test7 Columns(3) A1 style addressing
+ ITEM Assertion OK : test8 Columns(3) R1C1 style addressing
+ ITEM Assertion OK : test9 Columns('e') A1 style addressing
+ ITEM Assertion OK : test10 Columns('e') R1C1 style addressing
+ ITEM Assertion OK : test11 Columns('b:d') A1 style addressing
+ ITEM Assertion OK : test12 Columns('b:d') R1C1 style addressing
+ ITEM Assertion OK : test13 Range('c1:g10').Columns A1 style addressing
+ ITEM Assertion OK : test14 Range('c1:g10').Columns R1C1 style addressing
+ ITEM Assertion OK : test15 Range('c1:g10').Columns(1) A1 style addressing
+ ITEM Assertion OK : test16 Range('c1:g10').Columns(1) R1C1 style addressing
+ ITEM Assertion OK : test17 Range('c1:g10').Columns('a') A1 style addressing
+ ITEM Assertion OK : test18 Range('c1:g10').Columns('a') R1C1 style addressing
+ ITEM Assertion OK : test19 Range('c1:g10').Columns('c') A1 style addressing
+ ITEM Assertion OK : test20 Range('c1:g10').Columns('c') R1C1 style addressing
+ ITEM Assertion OK : test21 Range('c1:g10').Columns('x:z') A1 style addressing
+ ITEM Assertion OK : test22 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test23 Range('c1:g10').Columns(30) A1 style addressing
+ ITEM Assertion OK : test24 Range('c1:g10').Columns(30) R1C1 style addressing
+ ITEM Assertion OK : test25 Worksheets('Sheet2').Cells(1, 1) A1 style addressing
+ ITEM Assertion OK : test26 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, RowAddressAbsolute is false
+ ITEM Assertion OK : test27 Worksheets('Sheet2').Cells(1, 1) A1 style addressing, ColAddressAbsolute is false
+ ITEM Assertion OK : test28 Worksheets('Sheet2').Cells(1, 1) R1C1 style addressing
+ ITEM Assertion OK : test29 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test30 Worksheets('Sheet2').Range('A1').EntireColumn A1 style addressing
+ ITEM Assertion OK : test31 Worksheets('Sheet2').Range('A1:E5').EntireRow A1 style addressing
+ ITEM Assertion OK : test32 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test33 Worksheets('Sheet2').Range('IV65536').EntireRow A1 style addressing
+ ITEM Assertion OK : test34 Worksheets('Sheet2').Range('IU2:IV65536') A1 style addressing
+ ITEM Assertion OK : test35 Range('c1:g10').Columns('x:z') R1C1 style addressing
+ ITEM Assertion OK : test36 Worksheets('Sheet2').Range('A1') A1 style addressing
+ ITEM Assertion OK : test37 Worksheets('Sheet2').Range('A1:E5').EntireColumn A1 style addressing
+ ITEM Assertion OK : test38 Worksheets('Sheet2').Range('10:12') A1 style addressing
+ ITEM Assertion OK : test39 Worksheets('Sheet2').Range('10:12') R1C1 style addressing
+ ITEM Assertion OK : test40 Range('Sheet3!A1:B4') A1 style addressing
+ ITEM Assertion OK : test41 Range('Sheet3!A1,B1,D4:F20') A1 style addressing
+ ITEM Assertion OK : test42 Range('g20:h40').Columns('c:c')
+ ITEM Assertion OK : test43 Range('g20:h40').Columns('c:f')
+ ITEM Assertion OK : test44 Range('g20:h40').Columns(-1)
+ ITEM Assertion OK : test45 Range('c4:g10').Rows(-1)
+ ITEM Assertion OK : test46 Range('a2:b4').Rows('1:1')
+ ITEM Assertion OK : test47 Range('a2:b4').Rows('1:2')
+ ITEM Assertion OK : test48 Range('a2:b4').Rows('2:2')
+ ITEM Assertion OK : test49 Range('a2:b4').Rows('2:3')
+Test Results
+============
+
+Tests passed: 49
+Tests failed: 0
+
+END 'TestAddress
+ TEST OK : TestAddress
+Test run finished : 17/07/2007 15:26:56
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest.log
new file mode 100644
index 000000000000..492c24bc023c
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest.log
@@ -0,0 +1,60 @@
+Test run started : 10/07/2007 01:56:07
+BEGIN TestCalc
+ TEST START : RangeTest2
+ ITEM Assertion OK : - Range("D15").Row
+ ITEM Assertion OK : - WorkSheet("D15").Range.Row
+ ITEM Assertion OK : - Range("D15").Column
+ ITEM Assertion OK : - Worksheet.Range("D15").Column
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Valuer
+ ITEM Assertion OK : - Range("D1").EntireRow.Columns.Count
+ ITEM Assertion OK : - Range("D1").EntireColumn.Rows.Count
+ ITEM Assertion OK : - Range("D15").ClearContent
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Rows(1).Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns.Hidden (get)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (set)
+ ITEM Assertion OK : - Range("M1:N2").Columns(1).Hidden (get)
+ ITEM Assertion OK : - Range("B38").Orientation (get)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlDownward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlUpward)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B38").Orientation (set)
+ ITEM Assertion OK : - Range("B38").Orientation (set = xlVertical)
+ ITEM Assertion OK : - Range("B39").WrapText (get)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("B39").WrapText (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (get)
+ ITEM Assertion OK : - Range("F39").MergeCells (get)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion FAIL : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("E39").MergeCells (set)
+ ITEM Assertion OK : - Range("F39").MergeCells (set)
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("C41:C42").Replace MatchCase:=True
+ ITEM Assertion OK : - Range("D41:D42").Replace MatchCase:=False
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (get)
+ ITEM Assertion OK : - Range("B39").VerticalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (get)
+ ITEM Assertion OK : - Range("B39").HorizontalAlignment (set)
+ ITEM FAIL (RangeTest2)
+ TEST Not succesfully completed : RangeTest2
+END TestCalc
+Test run finished : 10/07/2007 01:56:12
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest2.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest2.log
new file mode 100644
index 000000000000..2532289bbe41
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/TestCalc_Rangetest2.log
@@ -0,0 +1,65 @@
+Test run started : 10/07/2007 01:56:15
+BEGIN TestCalc
+ TEST START : RangeTest3
+ ITEM Assertion FAIL : - setFormulaR1C1
+ ITEM Assertion OK : - getFormulaR1C1
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy(Range("I10"))
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteValues
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormulas
+ ITEM Assertion OK : PasteSpecial Paste:=xlPasteFormats
+ ITEM Assertion OK : PasteSpecial
+ ITEM Assertion OK : PasteSpecial SkipBlanks:=True
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationAdd
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationSubtract
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationMultiply
+ ITEM Assertion OK : PasteSpecial Operation:=xlPasteSpecialOperationDivide
+ ITEM Assertion OK : PasteSpecial Transpose:=True
+ ITEM Assertion FAIL : ActiveWorkbook.FileFormat
+ ITEM Assertion OK : ActiveWorkbook.Name
+ ITEM Assertion OK : ActiveWorkbook.FullName und ActiveWorkbook.Path
+ ITEM Assertion FAIL : - = ActiveWorkbook.Colors(3) set
+ ITEM Assertion OK : - = ActiveWorkbook.ResetColors
+ ITEM Assertion OK : - = ActiveWorkbook.Colors(3) get
+ ITEM Assertion OK : - = Range("K22").End (xlDown)
+ ITEM Assertion OK : - = Range("K22").End (xlUo)
+ ITEM Assertion OK : - = Range("K22").End (xlToLeft)
+ ITEM Assertion OK : - = Range("K22").End (xlRight)
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Next
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - ActiveSpreadsheet.Previous
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="x"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="<>"
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter field:=1, Criteria1:="="
+ ITEM Assertion OK : - Range("J4:J11").AutoFilter
+ ITEM Assertion OK : - ActiveSheet.Resize.Select
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion FAIL : - Application.GoTo Reference:="R[8]C[2]"
+ ITEM Assertion OK : - Application.GoTo Reference:="R8C2"
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Ungroup- please check visually
+ ITEM Assertion OK : - Range.Ungroup - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.Group - please check visually
+ ITEM Assertion OK : - Range.clearOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - Range.AutoOutline - please check visually
+ ITEM Assertion OK : - ActiveSheet.UsedRange.Select
+ ITEM Assertion OK : - Range("A13").AddIndent
+ ITEM Assertion OK : - Range("A13").IndentLevel set
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range("A13").IndentLevel get
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Copy() and Range.PasteSpecial()
+ ITEM Assertion OK : - Range.Calculate
+ ITEM Assertion OK : Worksheet.Calculate
+ ITEM Assertion OK : - Application.Calculate
+ ITEM Assertion OK : Global.Calculate
+ ITEM Assertion OK : Calculation set
+ ITEM FAIL (RangeTest3)
+ TEST Not succesfully completed : RangeTest3
+END TestCalc
+Test run finished : 10/07/2007 01:56:23
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/pagesetup.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/pagesetup.log
new file mode 100644
index 000000000000..a1c90473ce07
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/pagesetup.log
@@ -0,0 +1,87 @@
+Test run started : 7/21/2008 10:37:24 AM
+BEGIN PageSetup
+ TEST START : Sheet_PrintArea
+ ITEM Assertion OK : PrintArea has changed as expected
+ TEST OK : Sheet_PrintArea
+ TEST START : Test margins (no headers)
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.RightMargin set/get
+ ITEM Assertion OK : PageSetup.TopMargin set/get
+ ITEM Assertion OK : PageSetup.BottomMargin set/get
+Verify that page margins on sheet 1 are all 0.5inch
+ TEST OK : Test margins (no headers)
+ TEST START : Test margins (headers)
+ ITEM Assertion OK : PageSetup.HeaderMargin set/get
+ ITEM Assertion OK : PageSetup.FooterMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+ ITEM Assertion OK : PageSetup.LeftMargin set/get
+Verify that top/bottom/header/footer page margins on sheet 2 are all 0.5inch
+ TEST OK : Test margins (headers)
+ TEST START : Test header/footer text
+ ITEM Assertion OK : PageSetup.LeftHeader set
+ ITEM Assertion OK : PageSetup.LeftHeader set/get
+ ITEM Assertion OK : PageSetup.CenterHeader set
+ ITEM Assertion OK : PageSetup.CenterHeader set/get
+ ITEM Assertion OK : PageSetup.RightHeader set
+ ITEM Assertion OK : PageSetup.RightHeader set/get
+ ITEM Assertion OK : PageSetup.LeftFooter set
+ ITEM Assertion OK : PageSetup.LeftFooter set/get
+ ITEM Assertion OK : PageSetup.CenterFooter set
+ ITEM Assertion OK : PageSetup.CenterFooter set/get
+ ITEM Assertion OK : PageSetup.RightFooter set
+ ITEM Assertion OK : PageSetup.RightFooter set/get
+Verify that headers on sheet 2 are Ready,to,go
+Verify that footers on sheet 2 are This,now,Works
+ TEST OK : Test header/footer text
+ TEST START : Test zoom
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Zoom set/get
+Verify that sheet 1 zoom is 10%
+ TEST OK : Test zoom
+ TEST START : Test orientation
+ ITEM Assertion OK : PageSetup.Zoom set
+ ITEM Assertion OK : PageSetup.Orientation set/get
+Verify that sheet 1 orientation is now landscape
+ TEST OK : Test orientation
+ TEST START : Test paper size
+ ITEM Assertion OK : PageSetup.PaperSize get
+ ITEM Assertion OK : PageSetup.PaperSize set/get
+Verify that paper size on sheet 1 is now Letter
+ TEST OK : Test paper size
+ TEST START : Test order
+ ITEM Assertion OK : PageSetup.Order get
+ ITEM Assertion OK : PageSetup.Order set/get
+Verify that order on sheet 1 is now over, then down.
+ TEST OK : Test order
+ TEST START : Test first page number
+ ITEM Assertion OK : PageSetup.FirstPageNumber get
+ ITEM Assertion OK : PageSetup.FirstPageNumber set/get
+Verify that first page number on sheet 1 is now 2.
+ TEST OK : Test first page number
+ TEST START : Test center vertically
+ ITEM Assertion OK : PageSetup.CenterVertically get
+ ITEM Assertion OK : PageSetup.CenterVertically set/get
+Verify that CenterVertically on sheet 1 is now true.
+ TEST OK : Test center vertically
+ TEST START : Test center horizontally
+ ITEM Assertion OK : PageSetup.CenterHorizontally get
+ ITEM Assertion OK : PageSetup.CenterHorizontally set/get
+Verify that CenterHorizontally on sheet 1 is now true.
+ TEST OK : Test center horizontally
+ TEST START : Test FitToPagesTall
+ ITEM Assertion OK : PageSetup.FitToPagesTall set/get
+ TEST OK : Test FitToPagesTall
+ TEST START : Test FitToPagesWide
+ ITEM Assertion OK : PageSetup.FitToPagesWide set/get
+ TEST OK : Test FitToPagesWide
+ TEST START : Test PrintHeadings
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ ITEM Assertion OK : PageSetup.PrintHeadings set/get
+ TEST OK : Test PrintHeadings
+ TEST START : Test PrintTitleRows
+ ITEM Assertion OK : PageSetup.PrintTitleRows get
+ ITEM Assertion OK : PageSetup.PrintTitleRows set range/get
+ ITEM Assertion OK : PageSetup.PrintTitleRows set false/get
+ TEST OK : Test PrintTitleRows
+END PageSetup
+Test run finished : 7/21/2008 10:37:32 AM
diff --git a/sc/source/ui/vba/testvba/TestDocuments/logs/win/replace.log b/sc/source/ui/vba/testvba/TestDocuments/logs/win/replace.log
new file mode 100644
index 000000000000..e96004e4d2a6
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/logs/win/replace.log
@@ -0,0 +1,14 @@
+Test run started : 2007-11-21 11:24:04
+BEGIN Replace
+ TEST START : Test Replace function
+ ITEM Assertion OK : common string:aefefdBc
+ ITEM Assertion OK : expression string:aefefdef
+ ITEM Assertion OK : binanary compare:aefefdBc
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : text compare:aefefdef
+ ITEM Assertion OK : start = 3:cefdBc
+ ITEM Assertion OK : count = 2: aefefdBc
+ ITEM Assertion OK : start = 1, count = 0, not support in Unix: abcbcdBc
+ TEST OK : Test Replace function
+END Replace
+Test run finished : 2007-11-21 11:24:04
diff --git a/sc/source/ui/vba/testvba/TestDocuments/pagesetup.xls b/sc/source/ui/vba/testvba/TestDocuments/pagesetup.xls
new file mode 100755
index 000000000000..dfa1b2a8be58
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/pagesetup.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/partition.xls b/sc/source/ui/vba/testvba/TestDocuments/partition.xls
new file mode 100644
index 000000000000..5c8d12b1d54f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/partition.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/range-4.xls b/sc/source/ui/vba/testvba/TestDocuments/range-4.xls
new file mode 100755
index 000000000000..52452369462f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/range-4.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/replace.xls b/sc/source/ui/vba/testvba/TestDocuments/replace.xls
new file mode 100644
index 000000000000..dcf3c6e8ec06
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/replace.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/stringplusdouble.xls b/sc/source/ui/vba/testvba/TestDocuments/stringplusdouble.xls
new file mode 100644
index 000000000000..596be7f6b9bc
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/stringplusdouble.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/TestDocuments/window2.xls b/sc/source/ui/vba/testvba/TestDocuments/window2.xls
new file mode 100755
index 000000000000..4d5e1cbfe944
--- /dev/null
+++ b/sc/source/ui/vba/testvba/TestDocuments/window2.xls
Binary files differ
diff --git a/sc/source/ui/vba/testvba/launchTest.pl b/sc/source/ui/vba/testvba/launchTest.pl
new file mode 100644
index 000000000000..243798616052
--- /dev/null
+++ b/sc/source/ui/vba/testvba/launchTest.pl
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+use File::Basename;
+
+my $test_class = shift || die 'must provide a ext name';
+my $TESTDOCUMENT = shift || die 'must provide a path to testdocument dirs';
+my $OUTPUTDIR = shift || die 'must provide an output path to deposit logs in';
+
+die "can't access TestClass $test_class/TestVBA.class" unless -f "$test_class/TestVBA.class";
+die "can't access officepath env variable \$OFFICEPATH" unless -d $ENV{OFFICEPATH};
+die "can't access testdocuments" unless -d $TESTDOCUMENT;
+die "testdocument not of the correct structure $TESTDOCUMENT/logs/excel" unless -d "$TESTDOCUMENT/logs/excel";
+die "can't access output dir" unless -d $OUTPUTDIR;
+
+
+my $officeclasspath = "$ENV{OFFICEPATH}/program/classes/";
+my $classpath = "$officeclasspath/jurt.jar:$officeclasspath/unoil.jar:$officeclasspath/juh.jar:$officeclasspath/java_uno.jar:$officeclasspath/ridl.jar:$test_class:$ENV{CLASSPATH}";
+$ENV{CLASSPATH}=$classpath;
+print "classpath $ENV{CLASSPATH}\n";
+my $status = system("java -classpath $ENV{CLASSPATH} TestVBA $TESTDOCUMENT $OUTPUTDIR" );
diff --git a/sc/source/ui/vba/testvba/makefile.mk b/sc/source/ui/vba/testvba/makefile.mk
new file mode 100644
index 000000000000..fb131f314ed3
--- /dev/null
+++ b/sc/source/ui/vba/testvba/makefile.mk
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..$/
+
+PRJNAME=sc
+TARGET=testvba
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+.IF "$(ENABLE_VBA)"!="YES"
+dummy:
+ @echo "not building vba..."
+.ENDIF
+
+INCPRE=$(INCCOM)$/$(TARGET)
+CDEFS+=-DVBA_OOBUILD_HACK
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/testvba.obj \
+
+
+# --- Targets ------------------------------------------------------
+
+APP1TARGET=testclient
+APP1OBJS= $(SLOFILES)
+
+APP1STDLIBS=\
+ $(SALLIB) \
+ $(STDLIBCPP) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(TOOLSLIB) \
+ $(UNOTOOLSLIB) \
+
+#APP1OBJS= $(OBJ)$/testclient.obj
+.INCLUDE : target.mk
+
+
diff --git a/sc/source/ui/vba/testvba/runTests.pl b/sc/source/ui/vba/testvba/runTests.pl
new file mode 100755
index 000000000000..e686a1d4cb89
--- /dev/null
+++ b/sc/source/ui/vba/testvba/runTests.pl
@@ -0,0 +1,121 @@
+#!/usr/bin/perl -w
+use URI::Escape;
+use File::Basename;
+use Cwd;
+use Cwd 'abs_path';
+
+$numArgs = $#ARGV + 1;
+print "thanks, you gave me $numArgs command-line arguments.\n";
+
+foreach $argnum (0 .. $#ARGV) {
+ print "$ARGV[$argnum]\n";
+}
+
+
+my $binDir = abs_path( dirname($0) );
+
+my $sysDir = "unix";
+my $fileSep = "/";
+my $theResult;
+my $officepath = shift || die "please specify path to office installation program dir";
+my $DocName = shift || "";
+my $programpath = "$officepath"."3/program:$officepath/program:";
+my $basiclibrarypath = "$officepath/basis3.3/program";
+my $urelibpath = "$officepath/ure/lib";
+my $binext = "";
+my $testDocDir = "$binDir/TestDocuments";
+my $testLogDir = "$binDir/Logs";
+my $testclientname = "testclient";
+my $buildtestclient = "../../../../unxlngi6.pro/bin/$testclientname";
+
+# test testclient
+if ( -e "$buildtestclient" )
+{
+ print "use the latest build\n";
+ system( "cp $buildtestclient ." );
+}
+elsif ( !( -e "$testclientname" ) )
+{
+ print "$testclientname do not exist\n";
+ exit;
+}
+
+# test for uname
+system("uname");
+$exit_value = $? >> 8;
+$signal_num = $? & 127;
+$dumped_core = $? & 128;
+
+$failed = ( $exit_value || $signal_num || $dumped_core );
+
+print "$failed = ( $exit_value || $signal_num || $dumped_core )\n";
+
+if ( !$failed && open(UNAME, "uname -a|") ) {
+ $theResult = <UNAME>;
+ close(UNAME);
+ if ( $theResult =~ /^CYGWIN/ ) {
+ # windows under cygwin
+ $sysDir = "win" ;
+ $tmpPath=$ENV{"PATH"};
+ $ENV{"PATH"} = "$officepath:$tmpPath";
+ $testDocDir=`cygpath -m $testDocDir`;
+ uri_escape($testDocDir);
+ # hacky windows url construction
+ $testDocDir="file:///$testDocDir";
+
+ chomp($testDocDir);
+ #print "*** doc dir is $testDocDir\n";
+ $testLogDir = `cygpath -m "$testLogDir"`;
+ uri_escape($testLogDir);
+ $testLogDir="file:///$testLogDir";
+ chomp($testLogDir);
+ #print "*** log dir is $testLogDir\n";
+ $binext = ".exe";
+ }
+ else{
+ # unix we need to find sal etc. ( from the office path )
+ my $tmpPath=$ENV{"PATH"};
+ $ENV{"PATH"} = "$programpath:$basiclibrarypath:$urelibpath/../bin:$tmpPath";
+ $tmpPATH = $ENV{"LD_LIBRARY_PATH"};
+ $ENV{"LD_LIBRARY_PATH"} = "$officepath:$programpath:$basiclibrarypath:$urelibpath:$urelibpath../bin/javaldx:$urelibpath/../bin:$tmpPATH";
+ $ENV{"LD_LIBRARY_PATH"} = "$officepath:$programpath:$basiclibrarypath:$urelibpath:$tmpPATH";
+ my $testPath = $ENV{"LD_LIBRARY_PATH"};
+ print "$testPath\n";
+ $testPath = $ENV{"PATH"};
+ print "$testPath\n";
+ $ENV{"STAR_RESOURCEPATH"} = "$officepath/basis3.0/program/resource";
+ $ENV{"SAL_ALLOW_LINKOO_SYMLINKS"} = "1";
+ $testPath = $ENV{"LANG"};
+ print "$testPath\n";
+ }
+}
+else
+{
+ # ordinary windows, not sure if this will actually work
+ $sysDir = "win" ;
+ $tmpPath=$ENV{"PATH"};
+ $ENV{"PATH"} = "$tmpPath;$officepath";
+ $binext = ".exe";
+}
+
+# the exe needs system paths or urls ( urls are by far the least troublesome )
+
+my $runCmd = "";
+my $analyseCmd = "";
+
+if ( "$DocName" eq "" )
+{
+ $runCmd = "$binDir/testclient$binext $testDocDir $testLogDir";
+ $analyseCmd = "perl $binDir/testResults.pl $binDir/Logs $binDir/TestDocuments/logs/$sysDir";
+}
+else
+{
+ $runCmd = "$binDir/testclient$binext $testDocDir $testLogDir $testDocDir/$DocName";
+ $analyseCmd = "perl $binDir/testResult.pl $binDir/Logs $binDir/TestDocuments/logs/$sysDir $DocName";
+}
+print "runCmd = $runCmd\n";
+
+system ("rm -rf $testLogDir/*");
+my $status = system( $runCmd );
+print "analyseCmd = $analyseCmd\n";
+$status = system( $analyseCmd );
diff --git a/sc/source/ui/vba/testvba/testResult.pl b/sc/source/ui/vba/testvba/testResult.pl
new file mode 100644
index 000000000000..5f065924d5c4
--- /dev/null
+++ b/sc/source/ui/vba/testvba/testResult.pl
@@ -0,0 +1,171 @@
+#!/usr/bin/perl -w
+use File::Temp qw/ tempfile tempdir /;
+use File::Basename;
+use File::stat;
+use File::Copy;
+
+my $binDir = dirname($0);
+my $timestampclean= "perl $binDir/timestampsClean.pl";
+#sub gen_diff($)
+
+sub testLog
+{
+ # 2 No Log to compare against
+ # 1 Log passed
+ # 0 Log failed
+ my $result = 0;
+ my $testfile = shift;
+ my $dirtocheck = shift;
+ my $filename = basename($testfile);
+ $filename = "$logdir/$filename";
+ print "processing $testfile $filename\n";
+ if ( -f $filename ) {
+ my $tmpFile;
+ $dir = tempdir( CLEANUP => 1 );
+ ($fh, $tmpFile) = tempfile( DIR => $dir );
+ close($fh);
+ #
+ my $status = system("diff -U 0 -p $testfile $filename | $timestampclean > $tmpFile");
+ my $info = stat($tmpFile) or die "no $tmpFile: $!";
+ if ( ($status >>=8) == 0 && ( $info->size == 0) ) {
+ #print "diff worked size is 0\n";
+ $result = 1;
+ }
+ elsif ( ($status >>=8) == 0 && ( $info->size > 0) )
+ {
+ #print "diff worked size > 0\n";
+ $result = 0;
+ }
+ else
+ {
+ #print "diff failed size > 0\n";
+ $result = 0;
+ }
+ }
+ else
+ {
+ #print "not file > 0\n";
+ $result = 2;
+ }
+ #print "diff result = $result\n";
+ return $result;
+}
+
+if ( ! ( $logdir = shift @ARGV ) ) {
+ print STDERR "No logdir specified!\n";
+ usage();
+ exit 1;
+}
+
+if ( ! ( $testlogdir = shift @ARGV ) ) {
+ print STDERR "No testdocuments dir to compare against specified!\n";
+ usage();
+ exit 1;
+}
+
+if ( !(-d $logdir ) ) {
+ print STDERR "No output directory $logdir exists, please create it!!!!\n";
+ exit 1;
+}
+if ( !(-d $testlogdir ) ) {
+ print STDERR "the directory containing the logfiles to compare against \"$logdir\" does not exist\n";
+ usage();
+ exit 1;
+}
+print "logdir $logdir\n";
+print "testlogdir $testlogdir\n";
+sub filter_crud($)
+{
+ my $a = shift;
+
+ $a =~ /~$/ && return;
+ $a =~ /\#$/ && return;
+ $a =~ /\.orig$/ && return;
+ $a =~ /unxlng.*\.pro$/ && return;
+ $a =~ /wntmsc.*\.pro$/ && return;
+ $a =~ /.swp$/ && return;
+ $a =~ /POSITION/ && return;
+ $a =~ /ReadMe/ && return;
+ $a =~ /.tmp$/ && return;
+ $a =~ /\.svn/ && return;
+ $a eq 'CVS' && return;
+ $a eq '.' && return;
+ $a eq '..' && return;
+
+ return $a;
+}
+sub slurp_dir($);
+
+sub slurp_dir($)
+{
+ my $dir = shift;
+ my ($dirhandle, $fname);
+ my @files = ();
+
+ opendir ($dirhandle, $dir) || die "Can't open $dir";
+ while ($fname = readdir ($dirhandle)) {
+ $fname = filter_crud($fname);
+ defined $fname || next;
+# if (-d "$dir/$fname") {
+# push @files, slurp_dir("$dir/$fname");
+# } else
+ {
+ push @files, "$dir/$fname";
+ }
+ }
+ closedir ($dirhandle);
+
+ return @files;
+}
+
+if (-d $testlogdir) {
+ push @files, slurp_dir($testlogdir);
+}
+
+my $processed = 0;
+my $passed = 0;
+my @passedTests=();
+my @skippedTests=();
+my @failedTests=();
+
+my $failureCmd="";
+my $testfile = shift @ARGV;
+my $testfilepath = "$testlogdir/$testfile";
+$testfilepath =~ s/\.xls/\.log/;
+print "$testfilepath\n";
+for $a (@files) {
+ $filename = $a;
+ if ( "$testfilepath" eq "$filename" )
+ {
+ $processed++;
+ my $testcase = $a;
+ $testcase =~ s/\.log/\.xls/;
+ my $result = testLog( $a, $logdir );
+ if ( $result == 0 ) {
+ push @failedTests, basename($testcase);
+ if ( $failureCmd eq "" ) { $failureCmd = " diff -up $a $logdir "; }
+ }
+ elsif ( $result == 2 ) {
+ #print "skipped $a\n";
+ push @skippedTests, $testcase;
+ }
+ else {
+ $passed++;
+ push @passedTests, $testcase;
+ #print "Test document for $a \t \t passed. \n";
+ }
+ }
+}
+my $compared=@passedTests+@failedTests;
+my $skip = @skippedTests;
+print "skipped $skip test-cases(s)\n";
+print "compared $compared test-case documents\n";
+print "\t \t $passed tests $@passedTests\n";
+if ( @failedTests > 0 ) {
+ print "the following test-case documents failed, please examine the logs manually\n";
+
+ for $a (@failedTests) {
+ print "\t$a\n";
+ }
+ print "e.g. $failureCmd\n"
+}
diff --git a/sc/source/ui/vba/testvba/testResults.pl b/sc/source/ui/vba/testvba/testResults.pl
new file mode 100755
index 000000000000..39ec26ba38be
--- /dev/null
+++ b/sc/source/ui/vba/testvba/testResults.pl
@@ -0,0 +1,163 @@
+#!/usr/bin/perl -w
+use File::Temp qw/ tempfile tempdir /;
+use File::Basename;
+use File::stat;
+use File::Copy;
+
+my $binDir = dirname($0);
+my $timestampclean= "perl $binDir/timestampsClean.pl";
+#sub gen_diff($)
+
+sub testLog
+{
+ # 2 No Log to compare against
+ # 1 Log passed
+ # 0 Log failed
+ my $result = 0;
+ my $testfile = shift;
+ my $dirtocheck = shift;
+ my $filename = basename($testfile);
+ $filename = "$logdir/$filename";
+ print "processing $testfile $filename\n";
+ if ( -f $filename ) {
+ my $tmpFile;
+ $dir = tempdir( CLEANUP => 1 );
+ ($fh, $tmpFile) = tempfile( DIR => $dir );
+ close($fh);
+ #
+ my $status = system("diff -U 0 -p $testfile $filename | $timestampclean > $tmpFile");
+ my $info = stat($tmpFile) or die "no $tmpFile: $!";
+ if ( ($status >>=8) == 0 && ( $info->size == 0) ) {
+ #print "diff worked size is 0\n";
+ $result = 1;
+ }
+ elsif ( ($status >>=8) == 0 && ( $info->size > 0) )
+ {
+ #print "diff worked size > 0\n";
+ $result = 0;
+ }
+ else
+ {
+ #print "diff failed size > 0\n";
+ $result = 0;
+ }
+ }
+ else
+ {
+ #print "not file > 0\n";
+ $result = 2;
+ }
+ #print "diff result = $result\n";
+ return $result;
+}
+
+if ( ! ( $logdir = shift @ARGV ) ) {
+ print STDERR "No logdir specified!\n";
+ usage();
+ exit 1;
+}
+
+if ( ! ( $testlogdir = shift @ARGV ) ) {
+ print STDERR "No testdocuments dir to compare against specified!\n";
+ usage();
+ exit 1;
+}
+
+if ( !(-d $logdir ) ) {
+ print STDERR "No output directory $logdir exists, please create it!!!!\n";
+ exit 1;
+}
+if ( !(-d $testlogdir ) ) {
+ print STDERR "the directory containing the logfiles to compare against \"$logdir\" does not exist\n";
+ usage();
+ exit 1;
+}
+print "logdir $logdir\n";
+print "testlogdir $testlogdir\n";
+sub filter_crud($)
+{
+ my $a = shift;
+
+ $a =~ /~$/ && return;
+ $a =~ /\#$/ && return;
+ $a =~ /\.orig$/ && return;
+ $a =~ /unxlng.*\.pro$/ && return;
+ $a =~ /wntmsc.*\.pro$/ && return;
+ $a =~ /.swp$/ && return;
+ $a =~ /POSITION/ && return;
+ $a =~ /ReadMe/ && return;
+ $a =~ /.tmp$/ && return;
+ $a =~ /\.svn/ && return;
+ $a eq 'CVS' && return;
+ $a eq '.' && return;
+ $a eq '..' && return;
+
+ return $a;
+}
+sub slurp_dir($);
+
+sub slurp_dir($)
+{
+ my $dir = shift;
+ my ($dirhandle, $fname);
+ my @files = ();
+
+ opendir ($dirhandle, $dir) || die "Can't open $dir";
+ while ($fname = readdir ($dirhandle)) {
+ $fname = filter_crud($fname);
+ defined $fname || next;
+# if (-d "$dir/$fname") {
+# push @files, slurp_dir("$dir/$fname");
+# } else
+ {
+ push @files, "$dir/$fname";
+ }
+ }
+ closedir ($dirhandle);
+
+ return @files;
+}
+
+if (-d $testlogdir) {
+ push @files, slurp_dir($testlogdir);
+}
+
+my $processed = 0;
+my $passed = 0;
+my @passedTests=();
+my @skippedTests=();
+my @failedTests=();
+
+my $failureCmd="";
+for $a (@files) {
+ $processed++;
+ my $testcase = $a;
+ $testcase =~ s/\.log/\.xls/;
+ my $result = testLog( $a, $logdir );
+ if ( $result == 0 ) {
+ push @failedTests, basename($testcase);
+ if ( $failureCmd eq "" ) { $failureCmd = " diff -up $a $logdir "; }
+ }
+ elsif ( $result == 2 ) {
+ #print "skipped $a\n";
+ push @skippedTests, $testcase;
+ }
+ else {
+ $passed++;
+ push @passedTests, $testcase;
+ #print "Test document for $a \t \t passed. \n";
+ }
+}
+my $compared=@passedTests+@failedTests;
+my $skip = @skippedTests;
+print "skipped $skip test-cases(s)\n";
+print "compared $compared test-case documents\n";
+print "\t \t $passed tests $@passedTests\n";
+if ( @failedTests > 0 ) {
+ print "the following test-case documents failed, please examine the logs manually\n";
+
+ for $a (@failedTests) {
+ print "\t$a\n";
+ }
+ print "e.g. $failureCmd\n"
+}
diff --git a/sc/source/ui/vba/testvba/testclient b/sc/source/ui/vba/testvba/testclient
new file mode 100755
index 000000000000..c9cde8c5b052
--- /dev/null
+++ b/sc/source/ui/vba/testvba/testclient
Binary files differ
diff --git a/sc/source/ui/vba/testvba/testvba.cxx b/sc/source/ui/vba/testvba/testvba.cxx
new file mode 100644
index 000000000000..686b3e47eaa9
--- /dev/null
+++ b/sc/source/ui/vba/testvba/testvba.cxx
@@ -0,0 +1,309 @@
+#include "cppuhelper/bootstrap.hxx"
+
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+
+#include <memory>
+#include <iostream>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sheet;
+
+using ::com::sun::star::beans::Property;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertySetInfo;
+using ::com::sun::star::container::XNameContainer;
+using ::com::sun::star::lang::XComponent;
+using ::com::sun::star::lang::XMultiComponentFactory;
+using ::com::sun::star::frame::XComponentLoader;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::XComponentContext;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::ucb::XSimpleFileAccess;
+using ::com::sun::star::document::XTypeDetection;
+using ::rtl::OUString;
+
+using ::std::auto_ptr;
+
+const OUString EXTN = rtl::OUString::createFromAscii(".xls");
+
+OUString convertToURL( const OUString& rPath )
+{
+ rtl::OUString aURL;
+ INetURLObject aObj;
+ aObj.SetURL( rPath );
+ bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
+ if ( bIsURL )
+ aURL = rPath;
+ else
+ {
+ osl::FileBase::getFileURLFromSystemPath( rPath, aURL );
+ if ( aURL.equals( rPath ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "could'nt convert " ).concat( rPath ).concat( rtl::OUString::createFromAscii( " to a URL, is it a fully qualified path name? " ) ), Reference< uno::XInterface >() );
+ }
+ return aURL;
+}
+
+OUString ascii(const sal_Char* cstr)
+{
+ return OUString::createFromAscii(cstr);
+}
+
+const sal_Char* getStr(const OUString& ou)
+{
+ return OUStringToOString(ou, RTL_TEXTENCODING_UTF8).getStr();
+}
+
+
+int usage( const char* pName )
+{
+ std::cerr << "usage: " << pName << "<path to testdocument dir> <output_directory>" << std::endl;
+ return 1;
+
+}
+
+class TestVBA
+{
+private:
+ Reference< XComponentContext > mxContext;
+ Reference< XMultiComponentFactory > mxMCF;
+ Reference< XComponentLoader > mxCompLoader;
+ Reference< XSimpleFileAccess > mxSFA;
+ rtl::OUString msOutDirPath;
+protected:
+public:
+ TestVBA( const Reference< XComponentContext >& _xContext,
+ const Reference< XMultiComponentFactory >& _xMCF,
+ const Reference< XComponentLoader >& _xCompLoader,
+ const rtl::OUString& _outDirPath ) : mxContext( _xContext ), mxMCF( _xMCF ),
+mxCompLoader( _xCompLoader ), msOutDirPath( convertToURL( _outDirPath ) )
+ {
+ mxSFA.set( mxMCF->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), mxContext), uno::UNO_QUERY_THROW );
+ }
+
+ rtl::OUString getLogLocation() throw ( beans::UnknownPropertyException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::Exception )
+ {
+ rtl::OUString sLogLocation;
+ Reference< XPropertySet > pathSettings( mxMCF->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.comp.framework.PathSettings" ), mxContext), uno::UNO_QUERY_THROW );
+ pathSettings->getPropertyValue( rtl::OUString::createFromAscii( "Work" ) ) >>= sLogLocation;
+ sLogLocation = sLogLocation.concat( rtl::OUString::createFromAscii( "/" ) ).concat( rtl::OUString::createFromAscii( "HelperAPI-test.log" ) );
+ return sLogLocation;
+ }
+ rtl::OUString getLogLocationWithName( OUString fileName ) throw ( beans::UnknownPropertyException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::Exception )
+ {
+ printf("%s\n", getenv("HOME") );
+ printf("file name %s\n", rtl::OUStringToOString( fileName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ //rtl::OUString sLogLocation( rtl::OUString::createFromAscii( getenv("HOME") ) );
+ rtl::OUString sLogLocation;
+ Reference< XPropertySet > pathSettings( mxMCF->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.comp.framework.PathSettings" ), mxContext), uno::UNO_QUERY_THROW );
+ pathSettings->getPropertyValue( rtl::OUString::createFromAscii( "Work" ) ) >>= sLogLocation;
+ sLogLocation = sLogLocation.concat( rtl::OUString::createFromAscii( "/" ) ).concat( fileName.copy ( 0, fileName.lastIndexOf( EXTN ) ) + rtl::OUString::createFromAscii( ".log" ) );
+ return sLogLocation;
+ }
+
+ void init()
+ {
+ // blow away previous logs?
+ }
+
+ void proccessDocument( const rtl::OUString& sUrl )
+ {
+ if ( !mxSFA->isFolder( sUrl ) && sUrl.endsWithIgnoreAsciiCaseAsciiL( ".xls", 4 ) )
+
+ {
+ try
+ {
+ OSL_TRACE( "processing %s", rtl::OUStringToOString( sUrl, RTL_TEXTENCODING_UTF8 ).getStr() );
+ printf( "processing %s\n", rtl::OUStringToOString( sUrl, RTL_TEXTENCODING_UTF8 ).getStr() );
+ // Loading the wanted document
+ Sequence< PropertyValue > propertyValues(1);
+ propertyValues[0].Name = rtl::OUString::createFromAscii( "Hidden" );
+ propertyValues[0].Value <<= sal_False;
+
+ rtl::OUString sfileUrl = convertToURL( sUrl );
+ printf( "try to get xDoc %s\n", rtl::OUStringToOString( sfileUrl, RTL_TEXTENCODING_UTF8 ).getStr() );
+ Reference< uno::XInterface > xDoc =
+ mxCompLoader->loadComponentFromURL( sfileUrl, rtl::OUString::createFromAscii( "_blank" ), 0, propertyValues);
+ printf( "got xDoc\n" );
+
+ OUString logFileURL = convertToURL( getLogLocation() );
+ try
+ {
+ Reference< script::provider::XScriptProviderSupplier > xSupplier( xDoc, uno::UNO_QUERY_THROW ) ;
+ if ( mxSFA->exists( logFileURL ) )
+ mxSFA->kill( logFileURL );
+
+ printf("try to get the ScriptProvider\n");
+ Reference< script::provider::XScriptProvider > xProv = xSupplier->getScriptProvider();
+ printf("get the ScriptProvider\n");
+ printf("try to get the Script\n");
+ Reference< script::provider::XScript > xScript;
+ try
+ {
+ xScript = xProv->getScript( rtl::OUString::createFromAscii( "vnd.sun.star.script:Standard.TestMacros.Main?language=Basic&location=document" ));
+ } catch ( uno::Exception& e )
+ {
+ try
+ {
+ xScript = xProv->getScript( rtl::OUString::createFromAscii( "vnd.sun.star.script:Standard.testMacro.Main?language=Basic&location=document" ));
+ } catch ( uno::Exception& e2 )
+ {
+ xScript = xProv->getScript( rtl::OUString::createFromAscii( "vnd.sun.star.script:Standard.testMain.Main?language=Basic&location=document" ));
+ }
+ }
+ OSL_TRACE("Got script for doc %s", rtl::OUStringToOString( sUrl, RTL_TEXTENCODING_UTF8 ).getStr() );
+ printf("get the Script\n");
+ Sequence< uno::Any > aArgs;
+ Sequence< sal_Int16 > aOutArgsIndex;
+ Sequence< uno::Any > aOutArgs;
+
+ xScript->invoke(aArgs, aOutArgsIndex, aOutArgs);
+
+ OUString fileName = sUrl.copy ( sUrl.lastIndexOf( '/' ) );
+ OUString newLocation = msOutDirPath + fileName.copy ( 0, fileName.lastIndexOf( EXTN ) ) + rtl::OUString::createFromAscii( ".log" );
+ try
+ {
+ printf("move log file\n");
+ mxSFA->move( logFileURL, newLocation );
+ OSL_TRACE("new logfile location is %s ", rtl::OUStringToOString( newLocation, RTL_TEXTENCODING_UTF8 ).getStr() );
+ printf("moved to new location\n");
+ }
+ catch ( uno::Exception& e )
+ {
+ logFileURL = convertToURL( getLogLocationWithName( fileName ) );
+ printf("move log file from %s\n", rtl::OUStringToOString( logFileURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+ mxSFA->move( logFileURL, newLocation );
+ OSL_TRACE("new logfile location is %s ", rtl::OUStringToOString( newLocation, RTL_TEXTENCODING_UTF8 ).getStr() );
+ printf("moved to new location\n");
+ }
+
+ }
+ catch ( uno::Exception& e )
+ {
+ std::cerr << "Caught exception " << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() << std::endl;
+ }
+
+ // interface is supported, otherwise use XComponent.dispose
+ Reference< util::XCloseable > xCloseable ( xDoc, uno::UNO_QUERY );
+
+ if ( xCloseable.is() )
+ {
+ printf("try to close\n");
+ // will close application. and only run a test case for 3.0
+ // maybe it is a bug. yes, it is a bug
+ // if only one frame and model, click a button which related will colse.
+ // will make a crash. It related with window listener.
+ // so, for run all test cases, it should not close the document at this moment.
+ xCloseable->close(sal_False);
+ printf("closed\n");
+ }
+ else
+ {
+ printf("try to dispose\n");
+ Reference< XComponent > xComp( xDoc, uno::UNO_QUERY_THROW );
+ // same as close.
+ xComp->dispose();
+ printf("disposed\n");
+ }
+ }
+ catch( uno::Exception& e )
+ {
+ std::cerr << "Caught exception " << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() << std::endl;
+ }
+
+ }
+ printf("complete processing %s\n", rtl::OUStringToOString( sUrl, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ void traverse( const rtl::OUString& sFileDirectory )
+ {
+ rtl::OUString sFileDirectoryURL = convertToURL( sFileDirectory );
+ if ( !mxSFA->isFolder( sFileDirectoryURL) )
+ {
+ throw lang::IllegalArgumentException( rtl::OUString::createFromAscii( "not a directory: ").concat( sFileDirectoryURL ), Reference<uno::XInterface>(), 1 );
+ }
+ // Getting all files and directories in the current directory
+ Sequence<OUString> entries = mxSFA->getFolderContents( sFileDirectoryURL, sal_False );
+
+ // Iterating for each file and directory
+ printf( "Entries %d\n", (int)entries.getLength() );
+ for ( sal_Int32 i = 0; i < entries.getLength(); ++i )
+ {
+ proccessDocument( entries[ i ] );
+ }
+ }
+};
+
+void tryDispose( Reference< uno::XInterface > xIF, const char* sComp )
+{
+ Reference< lang::XComponent > xComponent( xIF, uno::UNO_QUERY );
+ if ( xComponent.is() )
+ {
+ try
+ {
+ xComponent->dispose();
+ }
+ catch( uno::Exception& e )
+ {
+ std::cerr << "tryDispose caught exception " <<rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() << " while disposing " << sComp << std::endl;
+ }
+ }
+}
+int main( int argv, char** argc )
+{
+ if ( !( argv > 2 ) )
+ return usage( argc[0] );
+ try
+ {
+
+ OSL_TRACE("Attempting to bootstrap normal");
+ Reference<XComponentContext> xCC = ::cppu::bootstrap();
+ Reference<XMultiComponentFactory> xFactory = xCC->getServiceManager();
+ OSL_TRACE("got servicemanager");
+ std::cout << "got servicemanager" << std::endl;
+ Reference<XInterface> desktop = xFactory->createInstanceWithContext(
+ ascii("com.sun.star.frame.Desktop"), xCC);
+ OSL_TRACE("got desktop");
+ std::cout << "got desktop" << std::endl;
+ Reference<frame::XComponentLoader> xLoader(desktop, UNO_QUERY_THROW);
+ TestVBA* dTest = new TestVBA( xCC, xFactory, xLoader, ascii( argc[ 2 ] ) );
+ if ( argv == 4 )
+ {
+ std::cout << "before process" << std::endl;
+ dTest->proccessDocument( ascii( argc[ 3 ] ) );
+ std::cout << "after process" << std::endl;
+ }
+ else
+ {
+ dTest->traverse( ascii( argc[ 1 ] ) );
+ }
+ delete dTest;
+// tryDispose( xLoader, "desktop" );
+// tryDispose( xCC, "remote context" );
+
+ }
+ catch( uno::Exception& e )
+ {
+ std::cerr << "Caught Exception " << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() << std::endl;
+ }
+
+}
diff --git a/sc/source/ui/vba/testvba/timestampsClean.pl b/sc/source/ui/vba/testvba/timestampsClean.pl
new file mode 100755
index 000000000000..dade65c7200f
--- /dev/null
+++ b/sc/source/ui/vba/testvba/timestampsClean.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/perl -w
+
+my @output_buffer = ();
+my $fname;
+my $detectedSomeGuff = 0;
+sub pure_guff($)
+{
+ my $array = shift;
+ my @lines = @{$array};
+ my $contains_sense = '';
+ my $contains_guff = '';
+ while (scalar @lines)
+ {
+ my $line = pop @lines;
+ if ($line =~ m/Test run started :/ ||
+ $line =~ m/ITEM Assertion OK/ ||
+ $line =~ m/Test run finished :/) {
+ $contains_guff = '1';
+ } elsif ($line =~ m/^[\+\-][^\-\+]/) {
+ $contains_sense = '1';
+ }
+ }
+ if ($contains_guff && $contains_sense) {
+ print STDERR "Patch fragment with mixed good/bad changes in '$ARGV' near $line_index\n";
+ $contains_guff = '';
+ }
+ elsif ( $contains_guff ) {
+ $detectedSomeGuff++;
+ }
+# print "contains guff: $contains_guff\n";
+ return $contains_guff;
+}
+
+sub output_lines($)
+{
+ my $array = shift;
+ my @lines = @{$array};
+
+ if (pure_guff (\@lines)) {
+ return;
+ }
+
+ while (scalar @lines)
+ {
+ my $line = pop @lines;
+ push @output_buffer, $line;
+ }
+}
+
+my $header;
+my @lines;
+my $frag_count = 0;
+$line_index = 0;
+
+while (<>) {
+ if (/^\@\@/ || /^[^ \-\+]/) {
+ output_lines (\@lines);
+ @lines = ();
+ $frag_count++;
+ }
+ unshift @lines, $_;
+ $line_index++;
+ close ARGV if eof;
+}
+output_lines(\@lines);
+
+# $detectedSomeGuff contains the skipped hunks that contain acceptable diff
+# e.g. a timestamp or an OK assertion that contains different content
+# like perhaps a path
+#print "frag_count = $frag_count fragstocount = $fragstocount detectedSomeGuff = $detectedSomeGuff \n";
+if ($frag_count > $detectedSomeGuff) {
+ print @output_buffer;
+}
diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx
new file mode 100644
index 000000000000..f3965393e919
--- /dev/null
+++ b/sc/source/ui/vba/vbaapplication.cxx
@@ -0,0 +1,1184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <stdio.h>
+
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <ooo/vba/excel/XlCalculation.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/XCalculatable.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <ooo/vba/excel/XlMousePointer.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+
+#include "vbaapplication.hxx"
+#include "vbaworkbooks.hxx"
+#include "vbaworkbook.hxx"
+#include "vbaworksheets.hxx"
+#include "vbarange.hxx"
+#include "vbawsfunction.hxx"
+#include "vbadialogs.hxx"
+#include "vbawindow.hxx"
+#include "vbawindows.hxx"
+#include "vbaglobals.hxx"
+#include "tabvwsh.hxx"
+#include "gridwin.hxx"
+#include "vbanames.hxx"
+#include <vbahelper/vbashape.hxx>
+#include "vbatextboxshape.hxx"
+#include "vbaassistant.hxx"
+#include "sc.hrc"
+
+#include <osl/file.hxx>
+
+#include <sfx2/request.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/app.hxx>
+
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <tools/diagnose_ex.h>
+
+#include <docuno.hxx>
+
+#include <basic/sbx.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbuno.hxx>
+#include <basic/sbmeth.hxx>
+
+#include "convuno.hxx"
+#include "cellsuno.hxx"
+#include "docsh.hxx"
+#include <vbahelper/helperdecl.hxx>
+#include "excelvbahelper.hxx"
+
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+// #TODO is this defined somewhere else?
+#if ( defined UNX ) || ( defined OS2 ) //unix
+#define FILE_PATH_SEPERATOR "/"
+#else // windows
+#define FILE_PATH_SEPERATOR "\\"
+#endif
+
+uno::Any sbxToUnoValue( SbxVariable* pVar );
+
+class ActiveWorkbook : public ScVbaWorkbook
+{
+protected:
+ virtual uno::Reference< frame::XModel > getModel()
+ {
+ return getCurrentExcelDoc(mxContext);
+ }
+public:
+ ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){}
+};
+
+ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
+ ScVbaApplication_BASE( xContext ),
+ m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ),
+ m_bDisplayAlerts( sal_True ),
+ m_bEnableEvents( sal_True )
+{
+}
+
+ScVbaApplication::~ScVbaApplication()
+{
+}
+
+SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException)
+{
+ return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaApplication::getExactName( const ::rtl::OUString& aApproximateName ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ return xWSF->getExactName( aApproximateName );
+}
+
+uno::Reference< beans::XIntrospectionAccess > SAL_CALL
+ScVbaApplication::getIntrospection() throw(css::uno::RuntimeException)
+{
+ uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ return xWSF->getIntrospection();
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::invoke( const ::rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+{
+ /* When calling the functions directly at the Application object, no runtime
+ errors are thrown, but the error is inserted into the return value. */
+ uno::Any aAny;
+ try
+ {
+ uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam );
+ }
+ catch( uno::Exception& )
+ {
+ aAny <<= script::BasicErrorException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), 1000, ::rtl::OUString() );
+ }
+ return aAny;
+}
+
+void SAL_CALL
+ScVbaApplication::setValue( const ::rtl::OUString& PropertyName, const uno::Any& Value ) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+{
+ uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ xWSF->setValue( PropertyName, Value );
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::getValue( const ::rtl::OUString& PropertyName ) throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ return xWSF->getValue( PropertyName );
+}
+
+sal_Bool SAL_CALL
+ScVbaApplication::hasMethod( const ::rtl::OUString& Name ) throw(uno::RuntimeException)
+{
+ uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ return xWSF->hasMethod( Name );
+}
+
+sal_Bool SAL_CALL
+ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeException)
+{
+ uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
+ return xWSF->hasProperty( Name );
+}
+
+uno::Reference< excel::XWorkbook >
+ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XWorkbook > xWrkbk;
+ ScDocShell* pShell = excel::getDocShell( getCurrentExcelDoc( mxContext ) );
+ if ( pShell )
+ {
+ String aName;
+ if ( pShell->GetDocument() )
+ {
+ aName = pShell->GetDocument()->GetCodeName();
+ xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY );
+ // fallback ( e.g. it's possible a new document was created via the api )
+ // in that case the document will not have the appropriate Document Modules
+ // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document
+ // vba mode etc. )
+ if ( !xWrkbk.is() )
+ return new ActiveWorkbook( this, mxContext );
+ }
+ }
+ return xWrkbk;
+}
+
+uno::Reference< excel::XWorkbook > SAL_CALL
+ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XWorkbook > xWrkbk;
+ ScDocShell* pShell = excel::getDocShell( getThisExcelDoc( mxContext ) );
+ if ( pShell )
+ {
+ String aName;
+ if ( pShell->GetDocument() )
+ {
+ aName = pShell->GetDocument()->GetCodeName();
+ xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY );
+ // fallback ( e.g. it's possible a new document was created via the api )
+ // in that case the document will not have the appropriate Document Modules
+ // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document
+ // vba mode etc. )
+ if ( !xWrkbk.is() )
+ return new ActiveWorkbook( this, mxContext );
+ }
+ }
+ return xWrkbk;
+}
+
+uno::Reference< XAssistant > SAL_CALL
+ScVbaApplication::getAssistant() throw (uno::RuntimeException)
+{
+ return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) );
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::getSelection() throw (uno::RuntimeException)
+{
+ OSL_TRACE("** ScVbaApplication::getSelection() ** ");
+ uno::Reference< frame::XModel > xModel( getCurrentDocument() );
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
+ rtl::OUString sImpementaionName = xServiceInfo->getImplementationName();
+ if( sImpementaionName.equalsIgnoreAsciiCaseAscii("com.sun.star.drawing.SvxShapeCollection") )
+ {
+ uno::Reference< drawing::XShapes > xShapes( xModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW );
+ // if ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape
+ // and the uno object implements the com.sun.star.drawing.Text service
+ // return a textboxshape object
+ if ( ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape )
+ {
+ uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW );
+ if ( xShapeServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.Text" ) ) ) )
+ {
+ return uno::makeAny( uno::Reference< msforms::XTextBoxShape >(new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) );
+ }
+ }
+ return uno::makeAny( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) );
+ }
+ else if( xServiceInfo->supportsService( rtl::OUString::createFromAscii("com.sun.star.sheet.SheetCellRange")) ||
+ xServiceInfo->supportsService( rtl::OUString::createFromAscii("com.sun.star.sheet.SheetCellRanges")))
+ {
+ uno::Reference< table::XCellRange > xRange( getCurrentDocument()->getCurrentSelection(), ::uno::UNO_QUERY);
+ if ( !xRange.is() )
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( getCurrentDocument()->getCurrentSelection(), ::uno::UNO_QUERY);
+ if ( xRanges.is() )
+ return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) );
+
+ }
+ return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
+ }
+ else
+ {
+ throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" not suported"), uno::Reference< uno::XInterface >() );
+ }
+}
+
+uno::Reference< excel::XRange >
+ScVbaApplication::getActiveCell() throw (uno::RuntimeException )
+{
+ uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xView->getActiveSheet(), ::uno::UNO_QUERY_THROW);
+ ScTabViewShell* pViewShell = excel::getCurrentBestViewShell(mxContext);
+ if ( !pViewShell )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("No ViewShell available"), uno::Reference< uno::XInterface >() );
+ ScViewData* pTabView = pViewShell->GetViewData();
+ if ( !pTabView )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("No ViewData available"), uno::Reference< uno::XInterface >() );
+
+ sal_Int32 nCursorX = pTabView->GetCurX();
+ sal_Int32 nCursorY = pTabView->GetCurY();
+
+ uno::Reference< XHelperInterface > xParent( excel::getUnoSheetModuleObj( xRange ), uno::UNO_QUERY_THROW );
+ return new ScVbaRange( xParent, mxContext, xRange->getCellRangeByPosition( nCursorX, nCursorY, nCursorX, nCursorY ) );
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Workbooks( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< XCollection > xWorkBooks( new ScVbaWorkbooks( this, mxContext ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ {
+ // void then somebody did Workbooks.something in vba
+ return uno::Any( xWorkBooks );
+ }
+
+ return uno::Any ( xWorkBooks->Item( aIndex, uno::Any() ) );
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_QUERY );
+ uno::Any result;
+ if ( xWorkbook.is() )
+ result = xWorkbook->Worksheets( aIndex );
+
+ else
+ // Fixme - check if this is reasonable/desired behavior
+ throw uno::RuntimeException( rtl::OUString::createFromAscii(
+ "No ActiveWorkBook available" ), uno::Reference< uno::XInterface >() );
+
+ return result;
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::WorksheetFunction( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) );
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Evaluate( const ::rtl::OUString& Name ) throw (uno::RuntimeException)
+{
+ // #TODO Evaluate allows other things to be evaluated, e.g. functions
+ // I think ( like SIN(3) etc. ) need to investigate that
+ // named Ranges also? e.g. [MyRange] if so need a list of named ranges
+ uno::Any aVoid;
+ return uno::Any( getActiveWorkbook()->getActiveSheet()->Range( uno::Any( Name ), aVoid ) );
+}
+
+uno::Any
+ScVbaApplication::Dialogs( const uno::Any &aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XDialogs > xDialogs( new ScVbaDialogs( uno::Reference< XHelperInterface >( this ), mxContext, getCurrentDocument() ) );
+ if( !aIndex.hasValue() )
+ return uno::Any( xDialogs );
+ return uno::Any( xDialogs->Item( aIndex ) );
+}
+
+uno::Reference< excel::XWindow > SAL_CALL
+ScVbaApplication::getActiveWindow() throw (uno::RuntimeException)
+{
+ // #FIXME sofar can't determine Parent
+ uno::Reference< frame::XModel > xModel = getCurrentDocument();
+ ScVbaWindow* pWin = new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel );
+ uno::Reference< excel::XWindow > xWin( pWin );
+ return xWin;
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::getCutCopyMode() throw (uno::RuntimeException)
+{
+ //# FIXME TODO, implementation
+ uno::Any result;
+ result <<= sal_False;
+ return result;
+}
+
+void SAL_CALL
+ScVbaApplication::setCutCopyMode( const uno::Any& /*_cutcopymode*/ ) throw (uno::RuntimeException)
+{
+ //# FIXME TODO, implementation
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::getStatusBar() throw (uno::RuntimeException)
+{
+ return uno::makeAny( !getDisplayStatusBar() );
+}
+
+void SAL_CALL
+ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::RuntimeException)
+{
+ rtl::OUString sText;
+ sal_Bool bDefault = sal_False;
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< task::XStatusIndicator > xStatusIndicator( xStatusIndicatorSupplier->getStatusIndicator(), uno::UNO_QUERY_THROW );
+ if( _statusbar >>= sText )
+ {
+ setDisplayStatusBar( sal_True );
+ xStatusIndicator->start( sText, 100 );
+ //xStatusIndicator->setText( sText );
+ }
+ else if( _statusbar >>= bDefault )
+ {
+ if( bDefault == sal_False )
+ {
+ xStatusIndicator->end();
+ setDisplayStatusBar( sal_True );
+ }
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid prarameter. It should be a string or False" ),
+ uno::Reference< uno::XInterface >() );
+}
+
+::sal_Int32 SAL_CALL
+ScVbaApplication::getCalculation() throw (uno::RuntimeException)
+{
+ uno::Reference<sheet::XCalculatable> xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
+ if(xCalc->isAutomaticCalculationEnabled())
+ return excel::XlCalculation::xlCalculationAutomatic;
+ else
+ return excel::XlCalculation::xlCalculationManual;
+}
+
+void SAL_CALL
+ScVbaApplication::setCalculation( ::sal_Int32 _calculation ) throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
+ switch(_calculation)
+ {
+ case excel::XlCalculation::xlCalculationManual:
+ xCalc->enableAutomaticCalculation(sal_False);
+ break;
+ case excel::XlCalculation::xlCalculationAutomatic:
+ case excel::XlCalculation::xlCalculationSemiautomatic:
+ xCalc->enableAutomaticCalculation(sal_True);
+ break;
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( this, mxContext ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ return uno::Any( xWindows );
+ return uno::Any( xWindows->Item( aIndex, uno::Any() ) );
+}
+void SAL_CALL
+ScVbaApplication::wait( double time ) throw (uno::RuntimeException)
+{
+ StarBASIC* pBasic = SFX_APP()->GetBasic();
+ SFX_APP()->EnterBasicCall();
+ SbxArrayRef aArgs = new SbxArray;
+ SbxVariableRef aRef = new SbxVariable;
+ aRef->PutDouble( time );
+ aArgs->Put( aRef, 1 );
+ SbMethod* pMeth = (SbMethod*)pBasic->GetRtl()->Find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WaitUntil") ), SbxCLASS_METHOD );
+
+ if ( pMeth )
+ {
+ pMeth->SetParameters( aArgs );
+ SbxVariableRef refTemp = pMeth;
+ // forces a broadcast
+ SbxVariableRef pNew = new SbxMethod( *((SbxMethod*)pMeth));
+ }
+ SFX_APP()->LeaveBasicCall();
+
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 );
+ return uno::makeAny( xVbRange );
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Names( const css::uno::Any& aIndex ) throw ( uno::RuntimeException )
+{
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XNamedRanges > xNamedRanges( xPropertySet->getPropertyValue( rtl::OUString::createFromAscii("NamedRanges")) , uno::UNO_QUERY_THROW );
+ css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ {
+ return uno::Any( xNames );
+}
+ return uno::Any( xNames->Item( aIndex, uno::Any() ) );
+}
+
+
+uno::Reference< excel::XWorksheet > SAL_CALL
+ScVbaApplication::getActiveSheet() throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XWorksheet > result;
+ uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_QUERY );
+ if ( xWorkbook.is() )
+ {
+ uno::Reference< excel::XWorksheet > xWorksheet(
+ xWorkbook->getActiveSheet(), uno::UNO_QUERY );
+ if ( xWorksheet.is() )
+ {
+ result = xWorksheet;
+ }
+ }
+
+ if ( !result.is() )
+ {
+ // Fixme - check if this is reasonable/desired behavior
+ throw uno::RuntimeException( rtl::OUString::createFromAscii(
+ "No activeSheet available" ), uno::Reference< uno::XInterface >() );
+ }
+ return result;
+
+}
+
+/*******************************************************************************
+ * In msdn:
+ * Reference Optional Variant. The destination. Can be a Range
+ * object, a string that contains a cell reference in R1C1-style notation,
+ * or a string that contains a Visual Basic procedure name.
+ * Scroll Optional Variant. True to scrol, False to not scroll through
+ * the window. The default is False.
+ * Parser is split to three parts, Range, R1C1 string and procedure name.
+ * by test excel, it seems Scroll no effect. ???
+*******************************************************************************/
+void SAL_CALL
+ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) throw (uno::RuntimeException)
+{
+ //test Scroll is a boolean
+ sal_Bool bScroll = sal_False;
+ //R1C1-style string or a string of procedure name.
+
+ if( Scroll.hasValue() )
+ {
+ sal_Bool aScroll = sal_False;
+ if( Scroll >>= aScroll )
+ {
+ bScroll = aScroll;
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "sencond parameter should be boolean" ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ rtl::OUString sRangeName;
+ if( Reference >>= sRangeName )
+ {
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
+ xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xDoc = xSpreadsheet->getActiveSheet();
+
+ ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
+ ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow();
+ try
+ {
+ uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName(
+ mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
+
+ if( bScroll )
+ {
+ xVbaSheetRange->Select();
+ uno::Reference< excel::XWindow > xWindow = getActiveWindow();
+ ScSplitPos eWhich = pShell->GetViewData()->GetActivePart();
+ sal_Int32 nValueX = pShell->GetViewData()->GetPosX(WhichH(eWhich));
+ sal_Int32 nValueY = pShell->GetViewData()->GetPosY(WhichV(eWhich));
+ xWindow->SmallScroll( uno::makeAny( (sal_Int16)(xVbaSheetRange->getRow() - 1) ),
+ uno::makeAny( (sal_Int16)nValueY ),
+ uno::makeAny( (sal_Int16)(xVbaSheetRange->getColumn() - 1) ),
+ uno::makeAny( (sal_Int16)nValueX ) );
+ gridWindow->GrabFocus();
+ }
+ else
+ {
+ xVbaSheetRange->Select();
+ gridWindow->GrabFocus();
+ }
+ }
+ catch( uno::RuntimeException )
+ {
+ //maybe this should be a procedure name
+ //TODO for procedure name
+ //browse::XBrowseNodeFactory is a singlton. OUString::createFromAscii( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory")
+ //and the createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) to get a root browse::XBrowseNode.
+ //for query XInvocation interface.
+ //but how to directly get the XInvocation?
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "invalid reference for range name, it should be procedure name" ),
+ uno::Reference< uno::XInterface >() );
+ }
+ return;
+ }
+ uno::Reference< excel::XRange > xRange;
+ if( Reference >>= xRange )
+ {
+ uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY );
+ ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
+ ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow();
+ if ( xVbaRange.is() )
+ {
+ //TODO bScroll should be using, In this time, it doesenot have effection
+ if( bScroll )
+ {
+ xVbaRange->Select();
+ uno::Reference< excel::XWindow > xWindow = getActiveWindow();
+ ScSplitPos eWhich = pShell->GetViewData()->GetActivePart();
+ sal_Int32 nValueX = pShell->GetViewData()->GetPosX(WhichH(eWhich));
+ sal_Int32 nValueY = pShell->GetViewData()->GetPosY(WhichV(eWhich));
+ xWindow->SmallScroll( uno::makeAny( (sal_Int16)(xVbaRange->getRow() - 1) ),
+ uno::makeAny( (sal_Int16)nValueY ),
+ uno::makeAny( (sal_Int16)(xVbaRange->getColumn() - 1) ),
+ uno::makeAny( (sal_Int16)nValueX ) );
+ gridWindow->GrabFocus();
+ }
+ else
+ {
+ xVbaRange->Select();
+ gridWindow->GrabFocus();
+ }
+ }
+ return;
+ }
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "invalid reference or name" ),
+ uno::Reference< uno::XInterface >() );
+}
+
+sal_Int32 SAL_CALL
+ScVbaApplication::getCursor() throw (uno::RuntimeException)
+{
+ sal_Int32 nPointerStyle = getPointerStyle(getCurrentDocument());
+
+ switch( nPointerStyle )
+ {
+ case POINTER_ARROW:
+ return excel::XlMousePointer::xlNorthwestArrow;
+ case POINTER_NULL:
+ return excel::XlMousePointer::xlDefault;
+ case POINTER_WAIT:
+ return excel::XlMousePointer::xlWait;
+ case POINTER_TEXT:
+ return excel::XlMousePointer::xlIBeam;
+ default:
+ return excel::XlMousePointer::xlDefault;
+ }
+}
+
+void SAL_CALL
+ScVbaApplication::setCursor( sal_Int32 _cursor ) throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ switch( _cursor )
+ {
+ case excel::XlMousePointer::xlNorthwestArrow:
+ {
+ const Pointer& rPointer( POINTER_ARROW );
+ setCursorHelper( xModel, rPointer, sal_False );
+ break;
+ }
+ case excel::XlMousePointer::xlWait:
+ case excel::XlMousePointer::xlIBeam:
+ {
+ const Pointer& rPointer( static_cast< PointerStyle >( _cursor ) );
+ //It will set the edit window, toobar and statusbar's mouse pointer.
+ setCursorHelper( xModel, rPointer, sal_True );
+ break;
+ }
+ case excel::XlMousePointer::xlDefault:
+ {
+ const Pointer& rPointer( POINTER_NULL );
+ setCursorHelper( xModel, rPointer, sal_False );
+ break;
+ }
+ default:
+ throw uno::RuntimeException( rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Unknown value for Cursor pointer")), uno::Reference< uno::XInterface >() );
+ // TODO: isn't this a flaw in the API? It should be allowed to throw an
+ // IllegalArgumentException, or so
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+// #TODO perhaps we should switch the return type depending of the filter
+// type, e.g. return Calc for Calc and Excel if its an imported doc
+rtl::OUString SAL_CALL
+ScVbaApplication::getName() throw (uno::RuntimeException)
+{
+ static rtl::OUString appName( RTL_CONSTASCII_USTRINGPARAM("Microsoft Excel" ) );
+ return appName;
+}
+
+// #TODO #FIXME get/setDisplayAlerts are just stub impl
+// here just the status of the switch is set
+// the function that throws an error message needs to
+// evaluate this switch in order to know whether it has to disable the
+// error message thrown by OpenOffice
+
+void SAL_CALL
+ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException)
+{
+ m_bDisplayAlerts = displayAlerts;
+}
+
+sal_Bool SAL_CALL
+ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException)
+{
+ return m_bDisplayAlerts;
+}
+
+void SAL_CALL
+ScVbaApplication::setEnableEvents(sal_Bool bEnable) throw (uno::RuntimeException)
+{
+ m_bEnableEvents = bEnable;
+}
+
+sal_Bool SAL_CALL
+ScVbaApplication::getEnableEvents() throw (uno::RuntimeException)
+{
+ return m_bEnableEvents;
+}
+
+void SAL_CALL
+ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException )
+{
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCalculatable > xCalculatable( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ xCalculatable->calculateAll();
+}
+
+uno::Reference< beans::XPropertySet > lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::RuntimeException )
+{
+ static uno::Reference< beans::XPropertySet > xPathSettings;
+ if ( !xPathSettings.is() )
+ {
+ uno::Reference< lang::XMultiComponentFactory > xSMgr( xContext->getServiceManager(), uno::UNO_QUERY_THROW );
+ xPathSettings.set( xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.util.PathSettings"), xContext), uno::UNO_QUERY_THROW );
+ }
+ return xPathSettings;
+}
+rtl::OUString ScVbaApplication::getOfficePath( const rtl::OUString& _sPathType ) throw ( uno::RuntimeException )
+{
+ rtl::OUString sRetPath;
+ uno::Reference< beans::XPropertySet > xProps = lcl_getPathSettingsService( mxContext );
+ try
+ {
+ rtl::OUString sUrl;
+ xProps->getPropertyValue( _sPathType ) >>= sUrl;
+
+ // if its a list of paths then use the last one
+ sal_Int32 nIndex = sUrl.lastIndexOf( ';' ) ;
+ if ( nIndex > 0 )
+ sUrl = sUrl.copy( nIndex + 1 );
+ ::osl::File::getSystemPathFromFileURL( sUrl, sRetPath );
+ }
+ catch (uno::Exception&)
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return sRetPath;
+}
+void SAL_CALL
+ScVbaApplication::setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getPathSettingsService( mxContext );
+ rtl::OUString aURL;
+ osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL );
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work")), uno::makeAny( aURL ) );
+
+
+}
+
+::rtl::OUString SAL_CALL
+ScVbaApplication::getDefaultFilePath( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work")));
+}
+
+::rtl::OUString SAL_CALL
+ScVbaApplication::LibraryPath( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Basic")));
+}
+
+::rtl::OUString SAL_CALL
+ScVbaApplication::TemplatesPath( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Template")));
+}
+
+::rtl::OUString SAL_CALL
+ScVbaApplication::PathSeparator( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ static rtl::OUString sPathSep( RTL_CONSTASCII_USTRINGPARAM( FILE_PATH_SEPERATOR ) );
+ return sPathSep;
+}
+
+// ----------------------------------------------------------------------------
+// Helpers for Intersect and Union
+
+namespace {
+
+typedef ::std::list< ScRange > ListOfScRange;
+
+/** Appends all ranges of a VBA Range object in the passed Any to the list of ranges. */
+void lclAddToListOfScRange( ListOfScRange& rList, const uno::Any& rArg )
+ throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if( rArg.hasValue() )
+ {
+ uno::Reference< excel::XRange > xRange( rArg, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW );
+ for( sal_Int32 nIdx = 1, nCount = xCol->getCount(); nIdx <= nCount; ++nIdx )
+ {
+ uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::Any( nIdx ), uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW );
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, xAddressable->getRangeAddress() );
+ rList.push_back( aScRange );
+ }
+ }
+}
+
+/** Returns true, if the passed ranges can be expressed by a single range. The
+ new range will be contained in r1 then, the range r2 can be removed. */
+bool lclTryJoin( ScRange& r1, const ScRange& r2 )
+{
+ // 1) r2 is completely inside r1
+ if( r1.In( r2 ) )
+ return true;
+
+ // 2) r1 is completely inside r2
+ if( r2.In( r1 ) )
+ {
+ r1 = r2;
+ return true;
+ }
+
+ SCCOL n1L = r1.aStart.Col();
+ SCCOL n1R = r1.aEnd.Col();
+ SCROW n1T = r1.aStart.Row();
+ SCROW n1B = r1.aEnd.Row();
+ SCCOL n2L = r2.aStart.Col();
+ SCCOL n2R = r2.aEnd.Col();
+ SCROW n2T = r2.aStart.Row();
+ SCROW n2B = r2.aEnd.Row();
+
+ // 3) r1 and r2 have equal upper and lower border
+ if( (n1T == n2T) && (n1B == n2B) )
+ {
+ // check that r1 overlaps or touches r2
+ if( ((n1L < n2L) && (n2L - 1 <= n1R)) || ((n2L < n1L) && (n1L - 1 <= n2R)) )
+ {
+ r1.aStart.SetCol( ::std::min( n1L, n2L ) );
+ r1.aEnd.SetCol( ::std::max( n1R, n2R ) );
+ return true;
+ }
+ return false;
+ }
+
+ // 4) r1 and r2 have equal left and right border
+ if( (n1L == n2L) && (n1R == n2R) )
+ {
+ // check that r1 overlaps or touches r2
+ if( ((n1T < n2T) && (n2T + 1 <= n1B)) || ((n2T < n1T) && (n1T + 1 <= n2B)) )
+ {
+ r1.aStart.SetRow( ::std::min( n1T, n2T ) );
+ r1.aEnd.SetRow( ::std::max( n1B, n2B ) );
+ return true;
+ }
+ return false;
+ }
+
+ // 5) cannot join these ranges
+ return false;
+}
+
+/** Strips out ranges that are contained by other ranges, joins ranges that can be joined
+ together (aligned borders, e.g. A4:D10 and B4:E10 would be combined to A4:E10. */
+void lclJoinRanges( ListOfScRange& rList )
+{
+ ListOfScRange::iterator aOuterIt = rList.begin();
+ while( aOuterIt != rList.end() )
+ {
+ bool bAnyErased = false; // true = any range erased from rList
+ ListOfScRange::iterator aInnerIt = rList.begin();
+ while( aInnerIt != rList.end() )
+ {
+ bool bInnerErased = false; // true = aInnerIt erased from rList
+ // do not compare a range with itself
+ if( (aOuterIt != aInnerIt) && lclTryJoin( *aOuterIt, *aInnerIt ) )
+ {
+ // aOuterIt points to joined range, aInnerIt will be removed
+ aInnerIt = rList.erase( aInnerIt );
+ bInnerErased = bAnyErased = true;
+ }
+ /* If aInnerIt has been erased from rList, it already points to
+ the next element (return value of list::erase()). */
+ if( !bInnerErased )
+ ++aInnerIt;
+ }
+ // if any range has been erased, repeat outer loop with the same range
+ if( !bAnyErased )
+ ++aOuterIt;
+ }
+}
+
+/** Intersects the passed list with all ranges of a VBA Range object in the passed Any. */
+void lclIntersectRanges( ListOfScRange& rList, const uno::Any& rArg )
+ throw (script::BasicErrorException, uno::RuntimeException)
+{
+ // extract the ranges from the passed argument, will throw on invalid data
+ ListOfScRange aList2;
+ lclAddToListOfScRange( aList2, rArg );
+ // do nothing, if the passed list is already empty
+ if( !rList.empty() && !aList2.empty() )
+ {
+ // save original list in a local
+ ListOfScRange aList1;
+ aList1.swap( rList );
+ // join ranges from passed argument
+ lclJoinRanges( aList2 );
+ // calculate intersection of the ranges in both lists
+ for( ListOfScRange::const_iterator aOuterIt = aList1.begin(), aOuterEnd = aList1.end(); aOuterIt != aOuterEnd; ++aOuterIt )
+ {
+ for( ListOfScRange::const_iterator aInnerIt = aList2.begin(), aInnerEnd = aList2.end(); aInnerIt != aInnerEnd; ++aInnerIt )
+ {
+ if( aOuterIt->Intersects( *aInnerIt ) )
+ {
+ ScRange aIsectRange(
+ Max( aOuterIt->aStart.Col(), aInnerIt->aStart.Col() ),
+ Max( aOuterIt->aStart.Row(), aInnerIt->aStart.Row() ),
+ Max( aOuterIt->aStart.Tab(), aInnerIt->aStart.Tab() ),
+ Min( aOuterIt->aEnd.Col(), aInnerIt->aEnd.Col() ),
+ Min( aOuterIt->aEnd.Row(), aInnerIt->aEnd.Row() ),
+ Min( aOuterIt->aEnd.Tab(), aInnerIt->aEnd.Tab() ) );
+ rList.push_back( aIsectRange );
+ }
+ }
+ }
+ // again, join the result ranges
+ lclJoinRanges( rList );
+ }
+}
+
+/** Creates a VBA Range object from the passed list of ranges. */
+uno::Reference< excel::XRange > lclCreateVbaRange(
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const ListOfScRange& rList ) throw (uno::RuntimeException)
+{
+ ScDocShell* pDocShell = excel::getDocShell( rxModel );
+ if( !pDocShell ) throw uno::RuntimeException();
+
+ ScRangeList aCellRanges;
+ for( ListOfScRange::const_iterator aIt = rList.begin(), aEnd = rList.end(); aIt != aEnd; ++aIt )
+ aCellRanges.Append( *aIt );
+
+ if( aCellRanges.Count() == 1 )
+ {
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() ) );
+ return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), rxContext, xRange );
+ }
+ if( aCellRanges.Count() > 1 )
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
+ return new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), rxContext, xRanges );
+ }
+ return 0;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Intersect(
+ const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
+ const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
+ const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
+ const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
+ const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
+ const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
+ const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
+ const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
+ throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if( !rArg1.is() || !rArg2.is() )
+ DebugHelper::exception( SbERR_BAD_PARAMETER, rtl::OUString() );
+
+ // initialize the result list with 1st parameter, join its ranges together
+ ListOfScRange aList;
+ lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
+ lclJoinRanges( aList );
+
+ // process all other parameters, this updates the list with intersection
+ lclIntersectRanges( aList, uno::Any( rArg2 ) );
+ lclIntersectRanges( aList, rArg3 );
+ lclIntersectRanges( aList, rArg4 );
+ lclIntersectRanges( aList, rArg5 );
+ lclIntersectRanges( aList, rArg6 );
+ lclIntersectRanges( aList, rArg7 );
+ lclIntersectRanges( aList, rArg8 );
+ lclIntersectRanges( aList, rArg9 );
+ lclIntersectRanges( aList, rArg10 );
+ lclIntersectRanges( aList, rArg11 );
+ lclIntersectRanges( aList, rArg12 );
+ lclIntersectRanges( aList, rArg13 );
+ lclIntersectRanges( aList, rArg14 );
+ lclIntersectRanges( aList, rArg15 );
+ lclIntersectRanges( aList, rArg16 );
+ lclIntersectRanges( aList, rArg17 );
+ lclIntersectRanges( aList, rArg18 );
+ lclIntersectRanges( aList, rArg19 );
+ lclIntersectRanges( aList, rArg20 );
+ lclIntersectRanges( aList, rArg21 );
+ lclIntersectRanges( aList, rArg22 );
+ lclIntersectRanges( aList, rArg23 );
+ lclIntersectRanges( aList, rArg24 );
+ lclIntersectRanges( aList, rArg25 );
+ lclIntersectRanges( aList, rArg26 );
+ lclIntersectRanges( aList, rArg27 );
+ lclIntersectRanges( aList, rArg28 );
+ lclIntersectRanges( aList, rArg29 );
+ lclIntersectRanges( aList, rArg30 );
+
+ // create the VBA Range object
+ return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
+}
+
+uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Union(
+ const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
+ const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
+ const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
+ const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
+ const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
+ const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
+ const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
+ const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
+ throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if( !rArg1.is() || !rArg2.is() )
+ DebugHelper::exception( SbERR_BAD_PARAMETER, rtl::OUString() );
+
+ ListOfScRange aList;
+ lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
+ lclAddToListOfScRange( aList, uno::Any( rArg2 ) );
+ lclAddToListOfScRange( aList, rArg3 );
+ lclAddToListOfScRange( aList, rArg4 );
+ lclAddToListOfScRange( aList, rArg5 );
+ lclAddToListOfScRange( aList, rArg6 );
+ lclAddToListOfScRange( aList, rArg7 );
+ lclAddToListOfScRange( aList, rArg8 );
+ lclAddToListOfScRange( aList, rArg9 );
+ lclAddToListOfScRange( aList, rArg10 );
+ lclAddToListOfScRange( aList, rArg11 );
+ lclAddToListOfScRange( aList, rArg12 );
+ lclAddToListOfScRange( aList, rArg13 );
+ lclAddToListOfScRange( aList, rArg14 );
+ lclAddToListOfScRange( aList, rArg15 );
+ lclAddToListOfScRange( aList, rArg16 );
+ lclAddToListOfScRange( aList, rArg17 );
+ lclAddToListOfScRange( aList, rArg18 );
+ lclAddToListOfScRange( aList, rArg19 );
+ lclAddToListOfScRange( aList, rArg20 );
+ lclAddToListOfScRange( aList, rArg21 );
+ lclAddToListOfScRange( aList, rArg22 );
+ lclAddToListOfScRange( aList, rArg23 );
+ lclAddToListOfScRange( aList, rArg24 );
+ lclAddToListOfScRange( aList, rArg25 );
+ lclAddToListOfScRange( aList, rArg26 );
+ lclAddToListOfScRange( aList, rArg27 );
+ lclAddToListOfScRange( aList, rArg28 );
+ lclAddToListOfScRange( aList, rArg29 );
+ lclAddToListOfScRange( aList, rArg30 );
+
+ // simply join together all ranges as much as possible, strip out covered ranges etc.
+ lclJoinRanges( aList );
+
+ // create the VBA Range object
+ return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
+}
+
+void
+ScVbaApplication::Volatile( const uno::Any& aVolatile ) throw ( uno::RuntimeException )
+{
+ sal_Bool bVolatile = sal_True;
+ aVolatile >>= bVolatile;
+ return;
+}
+
+void SAL_CALL
+ScVbaApplication::DoEvents() throw ( uno::RuntimeException )
+{
+}
+::sal_Bool SAL_CALL
+ScVbaApplication::getDisplayFormulaBar() throw ( css::uno::RuntimeException )
+{
+ sal_Bool bRes = sal_False;
+ ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
+ if ( pViewShell )
+ {
+ SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE);
+ SfxAllItemSet reqList( SFX_APP()->GetPool() );
+ reqList.Put( sfxFormBar );
+
+ pViewShell->GetState( reqList );
+ const SfxPoolItem *pItem=0;
+ if ( reqList.GetItemState( FID_TOGGLEINPUTLINE, sal_False, &pItem ) == SFX_ITEM_SET )
+ bRes = ((SfxBoolItem*)pItem)->GetValue();
+ }
+ return bRes;
+}
+
+void SAL_CALL
+ScVbaApplication::setDisplayFormulaBar( ::sal_Bool _displayformulabar ) throw ( css::uno::RuntimeException )
+{
+ ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
+ if ( pViewShell && ( _displayformulabar != getDisplayFormulaBar() ) )
+ {
+ SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE, _displayformulabar);
+ SfxAllItemSet reqList( SFX_APP()->GetPool() );
+ SfxRequest aReq( FID_TOGGLEINPUTLINE, 0, reqList );
+ pViewShell->Execute( aReq );
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaApplication::Caller( const uno::Any& /*aIndex*/ ) throw ( uno::RuntimeException )
+{
+ StarBASIC* pBasic = SFX_APP()->GetBasic();
+ SFX_APP()->EnterBasicCall();
+ SbMethod* pMeth = (SbMethod*)pBasic->GetRtl()->Find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FuncCaller") ), SbxCLASS_METHOD );
+ uno::Any aRet;
+ if ( pMeth )
+ {
+ SbxVariableRef refTemp = pMeth;
+ // forces a broadcast
+ SbxVariableRef pNew = new SbxMethod( *((SbxMethod*)pMeth));
+ OSL_TRACE("pNew has type %d and string value %s", pNew->GetType(), rtl::OUStringToOString( pNew->GetString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+ aRet = sbxToUnoValue( pNew );
+ }
+ SFX_APP()->LeaveBasicCall();
+ return aRet;
+}
+
+uno::Reference< frame::XModel >
+ScVbaApplication::getCurrentDocument() throw (css::uno::RuntimeException)
+{
+ return getCurrentExcelDoc(mxContext);
+}
+
+rtl::OUString&
+ScVbaApplication::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaApplication") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaApplication::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Application" ) );
+ }
+ return aServiceNames;
+}
+
+namespace application
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaApplication, sdecl::with_args<false> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaApplication",
+ "ooo.vba.excel.Application" );
+}
diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx
new file mode 100644
index 000000000000..a7be5feb1d27
--- /dev/null
+++ b/sc/source/ui/vba/vbaapplication.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_APPLICATION_HXX
+#define SC_VBA_APPLICATION_HXX
+
+
+#include <ooo/vba/excel/XWorksheetFunction.hpp>
+#include <ooo/vba/excel/XApplication.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbaapplicationbase.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+//typedef InheritedHelperInterfaceImpl1< ov::excel::XApplication > ScVbaApplication_BASE;
+typedef cppu::ImplInheritanceHelper1< VbaApplicationBase, ov::excel::XApplication > ScVbaApplication_BASE;
+
+class ScVbaApplication : public ScVbaApplication_BASE
+{
+private:
+ sal_Int32 m_xCalculation;
+ sal_Bool m_bDisplayAlerts;
+ sal_Bool m_bEnableEvents;
+
+ rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException );
+
+protected:
+ virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException);
+
+public:
+ ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext );
+ virtual ~ScVbaApplication();
+
+ virtual SfxObjectShell* GetDocShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException);
+
+ // XExactName
+ virtual ::rtl::OUString SAL_CALL getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException);
+
+ // XInvocation
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL invoke(const rtl::OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException);
+ virtual void SAL_CALL setValue(const rtl::OUString& PropertyName, const css::uno::Any& Value) throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getValue(const rtl::OUString& PropertyName) throw(css::beans::UnknownPropertyException, css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasMethod(const rtl::OUString& Name) throw(css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasProperty(const rtl::OUString& Name) throw(css::uno::RuntimeException);
+
+ // XApplication
+ virtual ::rtl::OUString SAL_CALL PathSeparator( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDefaultFilePath( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL LibraryPath( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL TemplatesPath( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getDisplayAlerts() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayAlerts( sal_Bool displayAlerts ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCalculation() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCalculation( ::sal_Int32 _calculation ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getSelection() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() throw ( css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayFormulaBar() throw ( css::uno::RuntimeException );
+ virtual void SAL_CALL setDisplayFormulaBar( ::sal_Bool _displayformulabar ) throw ( css::uno::RuntimeException );
+
+ virtual css::uno::Reference< ov::XAssistant > SAL_CALL getAssistant() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getThisWorkbook() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Workbooks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Worksheets( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL WorksheetFunction( ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Evaluate( const ::rtl::OUString& Name ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Dialogs( const css::uno::Any& DialogIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getCutCopyMode() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCutCopyMode( const css::uno::Any& _cutcopymode ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getStatusBar() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setStatusBar( const css::uno::Any& _statusbar ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCursor() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL getEnableEvents() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setEnableEvents( sal_Bool bEnable ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL wait( double time ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) throw ( css::uno::RuntimeException );
+ virtual void SAL_CALL GoTo( const css::uno::Any& Reference, const css::uno::Any& Scroll ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Calculate() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Intersect( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Union( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Volatile( const css::uno::Any& Volatile ) throw (css::uno::RuntimeException );
+ virtual void SAL_CALL DoEvents() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Caller( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif /* SC_VBA_APPLICATION_HXX */
diff --git a/sc/source/ui/vba/vbaassistant.cxx b/sc/source/ui/vba/vbaassistant.cxx
new file mode 100644
index 000000000000..51105d60b0d4
--- /dev/null
+++ b/sc/source/ui/vba/vbaassistant.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <sfx2/app.hxx>
+#include <svtools/helpopt.hxx>
+
+#include <ooo/vba/office/MsoAnimationType.hpp>
+
+#include"vbaassistant.hxx"
+
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+using namespace ooo::vba::office::MsoAnimationType;
+
+ScVbaAssistant::ScVbaAssistant( const uno::Reference< XHelperInterface > xParent, const uno::Reference< uno::XComponentContext > xContext ): ScVbaAssistantImpl_BASE( xParent, xContext )
+{
+ m_bIsVisible = sal_False;
+ m_nPointsLeft = 795;
+ m_nPointsTop = 248;
+ m_sName = rtl::OUString::createFromAscii( "Clippit" );
+ m_nAnimation = msoAnimationIdle;
+}
+
+ScVbaAssistant::~ScVbaAssistant()
+{
+}
+
+sal_Bool SAL_CALL ScVbaAssistant::getVisible() throw (uno::RuntimeException)
+{
+ return m_bIsVisible;
+}
+
+void SAL_CALL ScVbaAssistant::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException)
+{
+ m_bIsVisible = bVisible;
+}
+
+sal_Bool SAL_CALL ScVbaAssistant::getOn() throw (uno::RuntimeException)
+{
+ if( SvtHelpOptions().IsHelpAgentAutoStartMode() )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+void SAL_CALL ScVbaAssistant::setOn( sal_Bool bOn ) throw (uno::RuntimeException)
+{
+ SvtHelpOptions().SetHelpAgentAutoStartMode( bOn );
+ setVisible( bOn );
+}
+
+
+::sal_Int32 SAL_CALL
+ScVbaAssistant::getTop() throw (css::uno::RuntimeException)
+{
+ return m_nPointsTop;
+}
+void SAL_CALL
+ScVbaAssistant::setTop( ::sal_Int32 _top ) throw (css::uno::RuntimeException)
+{
+ m_nPointsTop = _top;
+}
+::sal_Int32 SAL_CALL
+ScVbaAssistant::getLeft() throw (css::uno::RuntimeException)
+{
+ return m_nPointsLeft;
+}
+void SAL_CALL
+ScVbaAssistant::setLeft( ::sal_Int32 _left ) throw (css::uno::RuntimeException)
+{
+ m_nPointsLeft = _left;
+}
+::sal_Int32 SAL_CALL
+ScVbaAssistant::getAnimation() throw (css::uno::RuntimeException)
+{
+ return m_nAnimation;
+}
+void SAL_CALL
+ScVbaAssistant::setAnimation( ::sal_Int32 _animation ) throw (css::uno::RuntimeException)
+{
+ m_nAnimation = _animation;
+}
+
+::rtl::OUString SAL_CALL
+ScVbaAssistant::Name( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return m_sName;
+}
+
+rtl::OUString&
+ScVbaAssistant::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaAssistant") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaAssistant::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.Assistant" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbaassistant.hxx b/sc/source/ui/vba/vbaassistant.hxx
new file mode 100644
index 000000000000..dbb95af4b689
--- /dev/null
+++ b/sc/source/ui/vba/vbaassistant.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_ASSISTANT_HXX
+#define SC_VBA_ASSISTANT_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/XAssistant.hpp>
+
+#include <sfx2/sfxhelp.hxx>
+
+#include "excelvbahelper.hxx"
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef ::cppu::WeakImplHelper1< ov::XAssistant > Assistant;
+typedef InheritedHelperInterfaceImpl< Assistant > ScVbaAssistantImpl_BASE;
+
+class ScVbaAssistant : public ScVbaAssistantImpl_BASE
+{
+private:
+ sal_Bool m_bIsVisible;
+ sal_Int32 m_nPointsLeft;
+ sal_Int32 m_nPointsTop;
+ rtl::OUString m_sName;
+ sal_Int32 m_nAnimation;
+public:
+ ScVbaAssistant( const css::uno::Reference< ov::XHelperInterface > xParent, const css::uno::Reference< css::uno::XComponentContext > xContext );
+ virtual ~ScVbaAssistant();
+ // XAssistant
+ virtual sal_Bool SAL_CALL getOn() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setOn( sal_Bool _on ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVisible( sal_Bool _visible ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getTop() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTop( ::sal_Int32 _top ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getLeft() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLeft( ::sal_Int32 _left ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getAnimation() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAnimation( ::sal_Int32 _animation ) throw (css::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL Name( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif//SC_VBA_ASSISTANT_HXX
diff --git a/sc/source/ui/vba/vbaaxes.cxx b/sc/source/ui/vba/vbaaxes.cxx
new file mode 100644
index 000000000000..d563ba105108
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxes.cxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbaaxes.hxx"
+#include "vbaaxis.hxx"
+#include "vbachart.hxx"
+#include <ooo/vba/excel/XlAxisType.hpp>
+#include <ooo/vba/excel/XlAxisGroup.hpp>
+#include <ooo/vba/excel/XAxis.hpp>
+#include <map>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlAxisType;
+using namespace ::ooo::vba::excel::XlAxisGroup;
+
+// each 'Item' in the Axes collection is indexed via 2 indexes, group and type.
+// We need to 'flatten' this into a single index in order to be able to wrap
+// iteration over the set of Axis(s) in a XIndexAccess implementation
+//
+typedef ::std::pair<sal_Int32, sal_Int32 > AxesCoordinate; // type and group combination
+typedef ::std::vector< AxesCoordinate > vecAxesIndices;
+
+typedef ::cppu::WeakImplHelper1< container::XIndexAccess > AxisIndexWrapper_BASE;
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+
+uno::Reference< excel::XAxis >
+ScVbaAxes::createAxis( const uno::Reference< excel::XChart >& xChart, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 nType, sal_Int32 nAxisGroup ) throw ( uno::RuntimeException )
+{
+ ScVbaChart* pChart = static_cast< ScVbaChart* >( xChart.get() );
+ if ( !pChart )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Object failure, can't access chart implementation" ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< beans::XPropertySet > xAxisPropertySet;
+ if (((nType == xlCategory) || (nType == xlSeriesAxis) || (nType == xlValue)))
+ {
+ if ((nAxisGroup != xlPrimary) && (nAxisGroup != xlSecondary))
+ throw script::BasicErrorException( rtl::OUString(), NULL, SbERR_METHOD_FAILED, rtl::OUString());
+ xAxisPropertySet.set( pChart->getAxisPropertySet(nType, nAxisGroup), uno::UNO_QUERY_THROW );
+ }
+ else
+ throw script::BasicErrorException( rtl::OUString(), NULL, SbERR_METHOD_FAILED, rtl::OUString());
+ uno::Reference< XHelperInterface > xParent( xChart, uno::UNO_QUERY_THROW );
+ return new ScVbaAxis( xParent, xContext, xAxisPropertySet, nType, nAxisGroup);
+}
+
+class AxisIndexWrapper : public AxisIndexWrapper_BASE
+{
+ // if necessary for better performance we could change this into a map and cache the
+ // indices -> Axis, currently we create a new Axis object
+ // on each getByIndex
+ uno::Reference< uno::XComponentContext > mxContext;
+ vecAxesIndices mCoordinates;
+ uno::Reference< excel::XChart > mxChart;
+public:
+ AxisIndexWrapper( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< excel::XChart >& xChart ) : mxContext( xContext ), mxChart( xChart )
+ {
+ if ( mxChart.is() )
+ {
+ ScVbaChart* pChart = static_cast< ScVbaChart* >( mxChart.get() );
+ // primary
+ sal_Bool bBool = false;
+ uno::Reference< beans::XPropertySet > xDiagramPropertySet( pChart->xDiagramPropertySet() );
+ if ( ( xDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasXAxis" ) ) ) >>= bBool ) && bBool )
+ mCoordinates.push_back( AxesCoordinate( xlPrimary, xlCategory ) );
+ if ( ( xDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasYAxis" ) ) ) >>= bBool ) && bBool )
+ mCoordinates.push_back( AxesCoordinate( xlPrimary, xlSeriesAxis ) );
+
+ if ( pChart->is3D() )
+ mCoordinates.push_back( AxesCoordinate( xlPrimary, xlValue ) );
+
+ // secondary
+ if ( ( xDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSecondaryXAxis" ) ) ) >>= bBool ) && bBool )
+ mCoordinates.push_back( AxesCoordinate( xlSecondary, xlCategory ) );
+ if ( ( xDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasSecondaryYAxis" ) ) ) >>= bBool ) && bBool )
+ mCoordinates.push_back( AxesCoordinate( xlSecondary, xlSeriesAxis ) );
+ }
+
+ }
+ virtual ::sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException) { return mCoordinates.size(); }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, ::uno::RuntimeException)
+ {
+ AxesCoordinate dIndexes = mCoordinates[ Index ];
+ return uno::makeAny( ScVbaAxes::createAxis( mxChart, mxContext, dIndexes.second, dIndexes.first ) );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException)
+ {
+ return excel::XAxis::static_type(0);
+ }
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
+ {
+ return ( mCoordinates.size() > 0 );
+ }
+};
+
+uno::Reference< container::XIndexAccess > createIndexWrapper( const uno::Reference< excel::XChart >& xChart, const uno::Reference< uno::XComponentContext >& xContext )
+{
+ return new AxisIndexWrapper( xContext, xChart );
+}
+
+// #FIXME The collection semantics will never work as this object is not yet initialised correctly
+ScVbaAxes::ScVbaAxes( const uno::Reference< XHelperInterface >& xParent,const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< excel::XChart >& xChart ) : ScVbaAxes_BASE( xParent, xContext, createIndexWrapper( xChart, xContext )), moChartParent( xChart )
+{
+}
+
+uno::Type SAL_CALL
+ScVbaAxes::getElementType() throw (css::uno::RuntimeException)
+{
+ return excel::XAxes::static_type(0);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaAxes::createEnumeration() throw (css::uno::RuntimeException)
+{
+ return new EnumWrapper( m_xIndexAccess );
+}
+
+uno::Any SAL_CALL
+ScVbaAxes::Item( const css::uno::Any& _nType, const css::uno::Any& _oAxisGroup) throw (css::uno::RuntimeException)
+{
+ // #TODO map the possible index combinations to a container::XIndexAccess wrapper impl
+ // using a vector of valid std::pair maybe?
+ // bodgy helperapi port bits
+ sal_Int32 nAxisGroup = xlPrimary;
+ sal_Int32 nType = -1;
+ if ( !_nType.hasValue() || ( ( _nType >>= nType ) == sal_False ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Axes::Item Failed to extract type" ), uno::Reference< uno::XInterface >() );
+
+ if ( _oAxisGroup.hasValue() )
+ _oAxisGroup >>= nAxisGroup ;
+
+ return uno::makeAny( createAxis( moChartParent, mxContext, nType, nAxisGroup ) );
+}
+
+uno::Any
+ScVbaAxes::createCollectionObject(const css::uno::Any& aSource)
+{
+ return aSource; // pass through ( it's already an XAxis object
+}
+
+rtl::OUString&
+ScVbaAxes::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaAxes") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaAxes::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Axes" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbaaxes.hxx b/sc/source/ui/vba/vbaaxes.hxx
new file mode 100644
index 000000000000..5b5f88e2b72f
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxes.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_AXES_HXX
+#define SC_VBA_AXES_HXX
+#include <ooo/vba/excel/XAxes.hpp>
+#include <ooo/vba/excel/XAxis.hpp>
+#include <ooo/vba/excel/XChart.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XAxes > ScVbaAxes_BASE;
+class ScVbaAxes : public ScVbaAxes_BASE
+{
+ css::uno::Reference< ov::excel::XChart > moChartParent; // not the true parent I guess
+public:
+ ScVbaAxes( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< ov::excel::XChart >& xChart );
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ css::uno::Any SAL_CALL Item( const css::uno::Any& aIndex, const css::uno::Any& aIndex2 ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+ static css::uno::Reference< ov::excel::XAxis > createAxis( const css::uno::Reference< ov::excel::XChart >& xChart, const css::uno::Reference< css::uno::XComponentContext >& xContext, sal_Int32 nType, sal_Int32 nAxisGroup ) throw ( css::uno::RuntimeException );
+};
+
+#endif //SC_VBA_AXES_HXX
diff --git a/sc/source/ui/vba/vbaaxis.cxx b/sc/source/ui/vba/vbaaxis.cxx
new file mode 100644
index 000000000000..a9c91a4cea31
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxis.cxx
@@ -0,0 +1,670 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vbaaxis.hxx"
+#include <ooo/vba/excel/XlAxisCrosses.hpp>
+#include <ooo/vba/excel/XlAxisType.hpp>
+#include <ooo/vba/excel/XlScaleType.hpp>
+#include "vbaaxistitle.hxx"
+#include "vbachart.hxx"
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlAxisCrosses;
+using namespace ::ooo::vba::excel::XlAxisType;
+using namespace ::ooo::vba::excel::XlScaleType;
+
+const rtl::OUString ORIGIN( RTL_CONSTASCII_USTRINGPARAM("Origin") );
+const rtl::OUString AUTOORIGIN( RTL_CONSTASCII_USTRINGPARAM("AutoOrigin") );
+const rtl::OUString VBA_MIN( RTL_CONSTASCII_USTRINGPARAM("Max") );
+const rtl::OUString VBA_MAX( RTL_CONSTASCII_USTRINGPARAM("Min") );
+ScVbaChart*
+ScVbaAxis::getChartPtr() throw( uno::RuntimeException )
+{
+ ScVbaChart* pChart = static_cast< ScVbaChart* >( moChartParent.get() );
+ if ( !pChart )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("Can't access parent chart impl"), uno::Reference< uno::XInterface >() );
+ return pChart;
+}
+
+sal_Bool
+ScVbaAxis::isValueAxis() throw( script::BasicErrorException )
+{
+ if ( getType() == xlCategory )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return sal_True;
+}
+
+ScVbaAxis::ScVbaAxis( const uno::Reference< XHelperInterface >& xParent,const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertySet >& _xPropertySet, sal_Int32 _nType, sal_Int32 _nGroup ) : ScVbaAxis_BASE( xParent, xContext ), mxPropertySet( _xPropertySet ), mnType( _nType ), mnGroup( _nGroup ), bCrossesAreCustomized( sal_False )
+{
+ oShapeHelper.reset( new ShapeHelper( uno::Reference< drawing::XShape >( mxPropertySet, uno::UNO_QUERY ) ) );
+ moChartParent.set( xParent, uno::UNO_QUERY_THROW );
+ setType(_nType);
+ setCrosses(xlAxisCrossesAutomatic);
+}
+
+void SAL_CALL
+ScVbaAxis::Delete( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< lang::XComponent > xComponent( mxPropertySet, uno::UNO_QUERY_THROW );
+ xComponent->dispose();
+}
+
+ uno::Reference< ::ooo::vba::excel::XAxisTitle > SAL_CALL
+ScVbaAxis::getAxisTitle( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< excel::XAxisTitle > xAxisTitle;
+ try
+ {
+ ScVbaChart* pChart = getChartPtr();
+
+ if (getHasTitle() )
+ {
+ int nType = getType();
+ switch(nType)
+ {
+ case xlCategory:
+ xAxisTitle = new ScVbaAxisTitle(this, mxContext, pChart->xAxisXSupplier->getXAxisTitle());
+ break;
+ case xlSeriesAxis:
+ xAxisTitle = new ScVbaAxisTitle(this, mxContext, pChart->xAxisZSupplier->getZAxisTitle());
+ break;
+ default: // xlValue:
+ xAxisTitle = new ScVbaAxisTitle(this, mxContext, pChart->xAxisYSupplier->getYAxisTitle());
+ break;
+ }
+ }
+ }
+ catch (uno::Exception& e)
+ {
+ DebugHelper::exception(e);
+ }
+ return xAxisTitle;
+
+}
+
+void SAL_CALL
+ScVbaAxis::setDisplayUnit( ::sal_Int32 /*DisplayUnit*/ ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getDisplayUnit( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ return -1;
+}
+
+void SAL_CALL
+ScVbaAxis::setCrosses( ::sal_Int32 _nCrosses ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ double fNum = 0.0;
+ switch (_nCrosses)
+ {
+ case xlAxisCrossesAutomatic: //Microsoft Excel sets the axis crossing point.
+ mxPropertySet->setPropertyValue(AUTOORIGIN, uno::makeAny( sal_True ) );
+ bCrossesAreCustomized = sal_False;
+ return;
+ case xlAxisCrossesMinimum: // The axis crosses at the minimum value.
+ mxPropertySet->getPropertyValue(VBA_MIN) >>= fNum;
+ setCrossesAt( fNum );
+ bCrossesAreCustomized = sal_False;
+ break;
+ case xlAxisCrossesMaximum: // The axis crosses at the maximum value.
+ mxPropertySet->getPropertyValue(VBA_MAX) >>= fNum;
+ setCrossesAt(fNum);
+ bCrossesAreCustomized = sal_False;
+ break;
+ default: //xlAxisCrossesCustom
+ bCrossesAreCustomized = sal_True;
+ break;
+ }
+ mxPropertySet->setPropertyValue(AUTOORIGIN, uno::makeAny(sal_False) );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+::sal_Int32 SAL_CALL
+ScVbaAxis::getCrosses( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Int32 nCrosses = xlAxisCrossesCustom;
+ try
+ {
+ sal_Bool bisAutoOrigin = sal_False;
+ mxPropertySet->getPropertyValue(AUTOORIGIN) >>= bisAutoOrigin;
+ if (bisAutoOrigin)
+ nCrosses = xlAxisCrossesAutomatic;
+ else
+ {
+ if (bCrossesAreCustomized)
+ nCrosses = xlAxisCrossesCustom;
+ else
+ {
+ double forigin = 0.0;
+ mxPropertySet->getPropertyValue(ORIGIN) >>= forigin;
+//obsolete double fmax = AnyConverter.toDouble(mxPropertySet.getPropertyValue("Max"));
+ double fmin = 0.0;
+ mxPropertySet->getPropertyValue(VBA_MIN) >>= fmin;
+ if (forigin == fmin)
+ nCrosses = xlAxisCrossesMinimum;
+ else
+ nCrosses = xlAxisCrossesMaximum;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return nCrosses;
+}
+
+ void SAL_CALL
+ScVbaAxis::setCrossesAt( double _fCrossesAt ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+// if (getCrosses() == xlAxisCrossesCustom){
+ setMaximumScaleIsAuto( sal_False );
+ setMinimumScaleIsAuto( sal_False );
+ mxPropertySet->setPropertyValue(ORIGIN, uno::makeAny(_fCrossesAt));
+// }
+ }
+ catch (uno::Exception& e)
+ {
+ DebugHelper::exception(e);
+ }
+}
+
+ double SAL_CALL
+ScVbaAxis::getCrossesAt( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ double fCrosses = 0.0;
+ try
+ {
+ mxPropertySet->getPropertyValue(ORIGIN) >>= fCrosses;
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return fCrosses;
+}
+
+void SAL_CALL
+ScVbaAxis::setType( ::sal_Int32 _nType ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ mnType = _nType;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getType( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return mnType;
+}
+
+void SAL_CALL
+ScVbaAxis::setHasTitle( ::sal_Bool _bHasTitle ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ ScVbaChart* pChart = getChartPtr();
+ sal_Int32 nType = getType();
+ switch(nType)
+ {
+ case xlCategory:
+ pChart->mxDiagramPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HasXAxisTitle")), uno::makeAny(_bHasTitle));
+ break;
+ case xlSeriesAxis:
+ pChart->mxDiagramPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HasZAxisTitle")), uno::makeAny(_bHasTitle));
+ break;
+ default: // xlValue:
+ pChart->mxDiagramPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HasYAxisTitle")), uno::makeAny(_bHasTitle));
+ }
+
+ }
+ catch (uno::Exception& e)
+ {
+ DebugHelper::exception(e);
+ }
+}
+
+ ::sal_Bool SAL_CALL
+ScVbaAxis::getHasTitle( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bHasTitle = sal_False;
+ try
+ {
+ ScVbaChart* pChart = getChartPtr();
+ int nType = getType();
+ switch(nType)
+ {
+ case xlCategory:
+ pChart->mxDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HasXAxisTitle")) ) >>= bHasTitle;
+ break;
+ case xlSeriesAxis:
+ pChart->mxDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HasZAxisTitle")) ) >>= bHasTitle;
+ break;
+ default: // xlValue:
+ pChart->mxDiagramPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HasYAxisTitle")) ) >>= bHasTitle;
+ }
+ }
+ catch (uno::Exception& e)
+ {
+ DebugHelper::exception(e);
+ }
+ return bHasTitle;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinorUnit( double _fMinorUnit ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StepHelp") ), uno::makeAny(_fMinorUnit));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMinorUnit( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ double fMinor = 1.0;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StepHelp"))) >>= fMinor;
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return fMinor;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinorUnitIsAuto( ::sal_Bool _bMinorUnitIsAuto ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoStepHelp" ) ), uno::makeAny(_bMinorUnitIsAuto));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+ ::sal_Bool SAL_CALL
+ScVbaAxis::getMinorUnitIsAuto( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bIsAuto = sal_False;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoStepHelp")) ) >>= bIsAuto;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return bIsAuto;
+}
+
+void SAL_CALL
+ScVbaAxis::setReversePlotOrder( ::sal_Bool /*ReversePlotOrder*/ ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+}
+
+::sal_Bool SAL_CALL
+ScVbaAxis::getReversePlotOrder( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ return sal_False;
+}
+
+void SAL_CALL
+ScVbaAxis::setMajorUnit( double _fMajorUnit ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StepMain")), uno::makeAny(_fMajorUnit));
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMajorUnit( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ double fMax = 1.0;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StepMain"))) >>= fMax;
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return fMax;
+}
+
+void SAL_CALL
+ScVbaAxis::setMajorUnitIsAuto( ::sal_Bool _bMajorUnitIsAuto ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoStepMain" ) ), uno::makeAny( _bMajorUnitIsAuto ));
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+::sal_Bool SAL_CALL
+ScVbaAxis::getMajorUnitIsAuto( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bIsAuto = sal_False;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoStepMain"))) >>= bIsAuto;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return bIsAuto;
+}
+
+void SAL_CALL
+ScVbaAxis::setMaximumScale( double _fMaximumScale ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if ( isValueAxis() )
+ {
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Max" ) ), uno::makeAny(_fMaximumScale));
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMaximumScale( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ double fMax = 1.0;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Max" ))) >>= fMax;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return fMax;
+
+}
+
+void SAL_CALL
+ScVbaAxis::setMaximumScaleIsAuto( ::sal_Bool _bMaximumScaleIsAuto ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if ( isValueAxis() )
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoMax" ) ), uno::makeAny( _bMaximumScaleIsAuto ));
+
+ }
+ catch ( uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+
+::sal_Bool SAL_CALL
+ScVbaAxis::getMaximumScaleIsAuto( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bIsAuto = sal_False;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoMax" )) ) >>= bIsAuto;
+ }
+ catch ( uno::Exception& )
+ {
+ DebugHelper::exception( SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return bIsAuto;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinimumScale( double _fMinimumScale ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Min") ), uno::makeAny( _fMinimumScale ) );
+ }
+ catch ( uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMinimumScale( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ double fMin = 0.0;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Min") )) >>= fMin;
+ }
+ catch (uno::Exception& e)
+ {
+ DebugHelper::exception(e);
+ }
+ return fMin;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinimumScaleIsAuto( ::sal_Bool _bMinimumScaleIsAuto ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoMin") ), uno::makeAny(_bMinimumScaleIsAuto));
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+::sal_Bool SAL_CALL
+ScVbaAxis::getMinimumScaleIsAuto( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bIsAuto = sal_False;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoMin")) ) >>= bIsAuto;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return bIsAuto;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getAxisGroup( ) throw (uno::RuntimeException)
+{
+ return mnGroup;
+}
+
+void SAL_CALL
+ScVbaAxis::setScaleType( ::sal_Int32 _nScaleType ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ switch (_nScaleType)
+ {
+ case xlScaleLinear:
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Logarithmic" ) ), uno::makeAny( sal_False ) );
+ break;
+ case xlScaleLogarithmic:
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Logarithmic" ) ), uno::makeAny( sal_True ) );
+ break;
+ default:
+ // According to MS the paramenter is ignored and no Error is thrown
+ break;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getScaleType( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Int32 nScaleType = xlScaleLinear;
+ try
+ {
+ if (isValueAxis())
+ {
+ sal_Bool bisLogarithmic = sal_False;
+ mxPropertySet->getPropertyValue( rtl::OUString( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Logarithmic"))) ) >>= bisLogarithmic;
+ if (bisLogarithmic)
+ nScaleType = xlScaleLogarithmic;
+ else
+ nScaleType = xlScaleLinear;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return nScaleType;
+}
+
+double SAL_CALL
+ScVbaAxis::getHeight( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return oShapeHelper->getHeight();
+}
+
+void SAL_CALL ScVbaAxis::setHeight( double height ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ oShapeHelper->setHeight( height );
+}
+double SAL_CALL ScVbaAxis::getWidth( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return oShapeHelper->getWidth( );
+}
+void SAL_CALL ScVbaAxis::setWidth( double width ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ oShapeHelper->setWidth( width );
+}
+double SAL_CALL ScVbaAxis::getTop( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return oShapeHelper->getTop( );
+}
+void SAL_CALL ScVbaAxis::setTop( double top ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ oShapeHelper->setTop( top );
+}
+double SAL_CALL ScVbaAxis::getLeft( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return oShapeHelper->getLeft( );
+}
+void SAL_CALL ScVbaAxis::setLeft( double left ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ oShapeHelper->setLeft( left );
+}
+
+rtl::OUString&
+ScVbaAxis::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaAxis") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaAxis::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Axis" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbaaxis.hxx b/sc/source/ui/vba/vbaaxis.hxx
new file mode 100644
index 000000000000..13432b231a27
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxis.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_AXIS_HXX
+#define SC_VBA_AXOS_HXX
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XAxis.hpp>
+#include <ooo/vba/excel/XChart.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <memory>
+typedef InheritedHelperInterfaceImpl1< ov::excel::XAxis > ScVbaAxis_BASE;
+class ScVbaChart;
+class ScVbaAxis : public ScVbaAxis_BASE
+{
+ css::uno::Reference< ov::excel::XChart > moChartParent;
+ css::uno::Reference< css::beans::XPropertySet > mxPropertySet;
+ sal_Int32 mnType;
+ sal_Int32 mnGroup;
+ sal_Int32 mnCrosses;
+ sal_Bool bCrossesAreCustomized;
+ ScVbaChart* getChartPtr() throw( css::uno::RuntimeException );
+ sal_Bool isValueAxis() throw( css::script::BasicErrorException );
+ std::auto_ptr<ov::ShapeHelper> oShapeHelper;
+
+public:
+ ScVbaAxis( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, sal_Int32 _nType, sal_Int32 _nGroup );
+ // Methods
+ virtual void SAL_CALL Delete( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ::ooo::vba::excel::XAxisTitle > SAL_CALL getAxisTitle( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayUnit( ::sal_Int32 DisplayUnit ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getDisplayUnit( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setCrosses( ::sal_Int32 Crosses ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCrosses( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setCrossesAt( double CrossesAt ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getCrossesAt( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setType( ::sal_Int32 Type ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getType( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setHasTitle( ::sal_Bool HasTitle ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getHasTitle( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMinorUnit( double MinorUnit ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getMinorUnit( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMinorUnitIsAuto( ::sal_Bool MinorUnitIsAuto ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getMinorUnitIsAuto( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setReversePlotOrder( ::sal_Bool ReversePlotOrder ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getReversePlotOrder( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMajorUnit( double MajorUnit ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getMajorUnit( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMajorUnitIsAuto( ::sal_Bool MajorUnitIsAuto ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getMajorUnitIsAuto( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMaximumScale( double MaximumScale ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getMaximumScale( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMaximumScaleIsAuto( ::sal_Bool MaximumScaleIsAuto ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getMaximumScaleIsAuto( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMinimumScale( double MinimumScale ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getMinimumScale( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMinimumScaleIsAuto( ::sal_Bool MinimumScaleIsAuto ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getMinimumScaleIsAuto( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getAxisGroup( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setScaleType( ::sal_Int32 ScaleType ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getScaleType( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getHeight( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setHeight( double height ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getWidth( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setWidth( double width ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getTop( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setTop( double top ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual double SAL_CALL getLeft( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setLeft( double left ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_AXIS_HXX
diff --git a/sc/source/ui/vba/vbaaxistitle.cxx b/sc/source/ui/vba/vbaaxistitle.cxx
new file mode 100644
index 000000000000..89b12b6e2870
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxistitle.cxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbaaxistitle.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaAxisTitle::ScVbaAxisTitle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& _xTitleShape ) : AxisTitleBase( xParent, xContext, _xTitleShape )
+{
+}
+
+rtl::OUString&
+ScVbaAxisTitle::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaAxisTitle") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaAxisTitle::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ uno::Sequence< rtl::OUString > BaseServiceNames = AxisTitleBase::getServiceNames();
+ aServiceNames.realloc( BaseServiceNames.getLength() + 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.AxisTitle" ) );
+ for ( sal_Int32 index = 1; index < (BaseServiceNames.getLength() + 1); ++index )
+ aServiceNames[ index ] = BaseServiceNames[ index ];
+ }
+ return aServiceNames;
+}
+
+
diff --git a/sc/source/ui/vba/vbaaxistitle.hxx b/sc/source/ui/vba/vbaaxistitle.hxx
new file mode 100644
index 000000000000..59ba71d99a87
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxistitle.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_VBA_AXISTITLE_HXX
+#define SC_VBA_AXISTITLE_HXX
+
+#include "vbatitle.hxx"
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XAxisTitle.hpp>
+
+typedef TitleImpl< cppu::WeakImplHelper1< ov::excel::XAxisTitle > > AxisTitleBase;
+
+class ScVbaAxisTitle : public AxisTitleBase
+{
+public:
+ ScVbaAxisTitle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& _xTitleShape );
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
diff --git a/sc/source/ui/vba/vbaborders.cxx b/sc/source/ui/vba/vbaborders.cxx
new file mode 100644
index 000000000000..5424da041f84
--- /dev/null
+++ b/sc/source/ui/vba/vbaborders.cxx
@@ -0,0 +1,574 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbaborders.hxx"
+
+#include <cppuhelper/implbase3.hxx>
+#include <ooo/vba/excel/XlBordersIndex.hpp>
+#include <ooo/vba/excel/XlBorderWeight.hpp>
+#include <ooo/vba/excel/XlLineStyle.hpp>
+#include <ooo/vba/excel/XlColorIndex.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+
+#include "vbapalette.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel;
+
+
+typedef ::cppu::WeakImplHelper1<container::XIndexAccess > RangeBorders_Base;
+typedef InheritedHelperInterfaceImpl1<excel::XBorder > ScVbaBorder_Base;
+
+// #TODO sort these indexes to match the order in which Excel iterates over the
+// borders, the enumeration will match the order in this list
+static const sal_Int16 supportedIndexTable[] = { XlBordersIndex::xlEdgeLeft, XlBordersIndex::xlEdgeTop, XlBordersIndex::xlEdgeBottom, XlBordersIndex::xlEdgeRight, XlBordersIndex::xlDiagonalDown, XlBordersIndex::xlDiagonalUp, XlBordersIndex::xlInsideVertical, XlBordersIndex::xlInsideHorizontal };
+
+const static rtl::OUString sTableBorder( RTL_CONSTASCII_USTRINGPARAM("TableBorder") );
+
+// Equiv widths in in 1/100 mm
+const static sal_Int32 OOLineThin = 35;
+const static sal_Int32 OOLineMedium = 88;
+const static sal_Int32 OOLineThick = 141;
+const static sal_Int32 OOLineHairline = 2;
+
+class ScVbaBorder : public ScVbaBorder_Base
+{
+private:
+ uno::Reference< beans::XPropertySet > m_xProps;
+ sal_Int32 m_LineType;
+ ScVbaPalette m_Palette;
+ bool setBorderLine( table::BorderLine& rBorderLine )
+ {
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
+
+ switch ( m_LineType )
+ {
+ case XlBordersIndex::xlEdgeLeft:
+ aTableBorder.IsLeftLineValid = sal_True;
+ aTableBorder.LeftLine= rBorderLine;
+ break;
+ case XlBordersIndex::xlEdgeTop:
+ aTableBorder.IsTopLineValid = sal_True;
+ aTableBorder.TopLine = rBorderLine;
+ break;
+
+ case XlBordersIndex::xlEdgeBottom:
+ aTableBorder.IsBottomLineValid = sal_True;
+ aTableBorder.BottomLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlEdgeRight:
+ aTableBorder.IsRightLineValid = sal_True;
+ aTableBorder.RightLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlInsideVertical:
+ aTableBorder.IsVerticalLineValid = sal_True;
+ aTableBorder.VerticalLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlInsideHorizontal:
+ aTableBorder.IsHorizontalLineValid = sal_True;
+ aTableBorder.HorizontalLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlDiagonalDown:
+ case XlBordersIndex::xlDiagonalUp:
+ // #TODO have to ignore at the momement, would be
+ // nice to investigate what we can do here
+ break;
+ default:
+ return false;
+ }
+ m_xProps->setPropertyValue( sTableBorder, uno::makeAny(aTableBorder) );
+ return true;
+ }
+
+ bool getBorderLine( table::BorderLine& rBorderLine )
+ {
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
+ switch ( m_LineType )
+ {
+ case XlBordersIndex::xlEdgeLeft:
+ if ( aTableBorder.IsLeftLineValid )
+ rBorderLine = aTableBorder.LeftLine;
+ break;
+ case XlBordersIndex::xlEdgeTop:
+ if ( aTableBorder.IsTopLineValid )
+ rBorderLine = aTableBorder.TopLine;
+ break;
+
+ case XlBordersIndex::xlEdgeBottom:
+ if ( aTableBorder.IsBottomLineValid )
+ rBorderLine = aTableBorder.BottomLine;
+ break;
+ case XlBordersIndex::xlEdgeRight:
+ if ( aTableBorder.IsRightLineValid )
+ rBorderLine = aTableBorder.RightLine;
+ break;
+ case XlBordersIndex::xlInsideVertical:
+ if ( aTableBorder.IsVerticalLineValid )
+ rBorderLine = aTableBorder.VerticalLine;
+ break;
+ case XlBordersIndex::xlInsideHorizontal:
+ if ( aTableBorder.IsHorizontalLineValid )
+ rBorderLine = aTableBorder.HorizontalLine;
+ break;
+
+ case XlBordersIndex::xlDiagonalDown:
+ case XlBordersIndex::xlDiagonalUp:
+ // #TODO have to ignore at the momement, would be
+ // nice to investigate what we can do here
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ ScVbaBorder(); // no impl
+protected:
+ virtual rtl::OUString& getServiceImplName()
+ {
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaBorder") );
+ return sImplName;
+ }
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames()
+ {
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Border" ) );
+ }
+ return aServiceNames;
+ }
+public:
+ ScVbaBorder( const uno::Reference< beans::XPropertySet > & xProps, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 lineType, ScVbaPalette& rPalette) : ScVbaBorder_Base( uno::Reference< XHelperInterface >( xProps, uno::UNO_QUERY ), xContext ), m_xProps( xProps ), m_LineType( lineType ), m_Palette( rPalette ) {}
+
+ // XBorder
+ uno::Any SAL_CALL getColor() throw (uno::RuntimeException)
+ {
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ return uno::makeAny( OORGBToXLRGB( aBorderLine.Color ) );
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No Implementation available" ) ), uno::Reference< uno::XInterface >() );
+ }
+ void SAL_CALL setColor( const uno::Any& _color ) throw (uno::RuntimeException)
+ {
+ sal_Int32 nColor = 0;
+ _color >>= nColor;
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ {
+ aBorderLine.Color = XLRGBToOORGB( nColor );
+ setBorderLine( aBorderLine );
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No Implementation available" ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ uno::Any SAL_CALL getColorIndex() throw (uno::RuntimeException)
+ {
+ sal_Int32 nColor = 0;
+ XLRGBToOORGB( getColor() ) >>= nColor;
+ uno::Reference< container::XIndexAccess > xIndex = m_Palette.getPalette();
+ sal_Int32 nElems = xIndex->getCount();
+ sal_Int32 nIndex = -1;
+ for ( sal_Int32 count=0; count<nElems; ++count )
+ {
+ sal_Int32 nPaletteColor = 0;
+ xIndex->getByIndex( count ) >>= nPaletteColor;
+ if ( nPaletteColor == nColor )
+ {
+ nIndex = count + 1;
+ break;
+ }
+ }
+ return uno::makeAny(nIndex);
+ }
+
+ void SAL_CALL setColorIndex( const uno::Any& _colorindex ) throw (uno::RuntimeException)
+ {
+ sal_Int32 nColor = 0;
+ _colorindex >>= nColor;
+ if ( !nColor || nColor == XlColorIndex::xlColorIndexAutomatic )
+ nColor = 1;
+ setColor( OORGBToXLRGB( m_Palette.getPalette()->getByIndex( --nColor ) ) );
+ }
+ uno::Any SAL_CALL getWeight() throw (uno::RuntimeException)
+ {
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ {
+ switch ( aBorderLine.OuterLineWidth )
+ {
+ case 0: // Thin = default OO thickness
+ case OOLineThin:
+ return uno::makeAny( XlBorderWeight::xlThin );
+ case OOLineMedium:
+ return uno::makeAny( XlBorderWeight::xlMedium );
+ case OOLineThick:
+ return uno::makeAny( XlBorderWeight::xlThick );
+ case OOLineHairline:
+ return uno::makeAny( XlBorderWeight::xlHairline );
+ default:
+ break;
+ }
+ }
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Method failed" ) ), uno::Reference< uno::XInterface >() );
+ }
+ void SAL_CALL setWeight( const uno::Any& _weight ) throw (uno::RuntimeException)
+ {
+ sal_Int32 nWeight = 0;
+ _weight >>= nWeight;
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ {
+ switch ( nWeight )
+ {
+ case XlBorderWeight::xlThin:
+ aBorderLine.OuterLineWidth = OOLineThin;
+ break;
+ case XlBorderWeight::xlMedium:
+ aBorderLine.OuterLineWidth = OOLineMedium;
+ break;
+ case XlBorderWeight::xlThick:
+ aBorderLine.OuterLineWidth = OOLineThick;
+ break;
+ case XlBorderWeight::xlHairline:
+ aBorderLine.OuterLineWidth = OOLineHairline;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Bad param" ) ), uno::Reference< uno::XInterface >() );
+ }
+ setBorderLine( aBorderLine );
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Method failed" ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ uno::Any SAL_CALL getLineStyle() throw (uno::RuntimeException)
+ {
+ // always return xlContinuous;
+ return uno::makeAny( XlLineStyle::xlContinuous );
+ }
+ void SAL_CALL setLineStyle( const uno::Any& _linestyle ) throw (uno::RuntimeException)
+ {
+ // Urk no choice but to silently ignore we don't support this attribute
+ // #TODO would be nice to support the excel line styles
+ sal_Int32 nLineStyle = 0;
+ _linestyle >>= nLineStyle;
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ {
+ switch ( nLineStyle )
+ {
+ case XlLineStyle::xlContinuous:
+ case XlLineStyle::xlDash:
+ case XlLineStyle::xlDashDot:
+ case XlLineStyle::xlDashDotDot:
+ case XlLineStyle::xlDot:
+ case XlLineStyle::xlDouble:
+ case XlLineStyle::xlLineStyleNone:
+ case XlLineStyle::xlSlantDashDot:
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Bad param" ) ), uno::Reference< uno::XInterface >() );
+ }
+ setBorderLine( aBorderLine );
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Method failed" ) ), uno::Reference< uno::XInterface >() );
+ }
+};
+
+class RangeBorders : public RangeBorders_Base
+{
+private:
+ uno::Reference< table::XCellRange > m_xRange;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ ScVbaPalette m_Palette;
+ sal_Int32 getTableIndex( sal_Int32 nConst )
+ {
+ // hokay return position of the index in the table
+ sal_Int32 nIndexes = getCount();
+ sal_Int32 realIndex = 0;
+ const sal_Int16* pTableEntry = supportedIndexTable;
+ for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry )
+ {
+ if ( *pTableEntry == nConst )
+ return realIndex;
+ }
+ return getCount(); // error condition
+ }
+public:
+ RangeBorders( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, ScVbaPalette& rPalette ) : m_xRange( xRange ), m_xContext( xContext ), m_Palette( rPalette )
+ {
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
+ {
+ return sizeof( supportedIndexTable ) / sizeof( supportedIndexTable[0] );
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+
+ sal_Int32 nIndex = getTableIndex( Index );
+ if ( nIndex >= 0 && nIndex < getCount() )
+ {
+ uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW );
+ return uno::makeAny( uno::Reference< excel::XBorder >( new ScVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ], m_Palette )) );
+ }
+ throw lang::IndexOutOfBoundsException();
+ }
+ virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
+ {
+ return excel::XBorder::static_type(0);
+ }
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
+ {
+ return sal_True;
+ }
+};
+
+uno::Reference< container::XIndexAccess >
+rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, ScVbaPalette& rPalette )
+{
+ return new RangeBorders( xRange, xContext, rPalette );
+}
+
+class RangeBorderEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ RangeBorderEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+ScVbaBorders::ScVbaBorders( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< table::XCellRange >& xRange, ScVbaPalette& rPalette ): ScVbaBorders_BASE( xParent, xContext, rangeToBorderIndexAccess( xRange ,xContext, rPalette ) ), bRangeIsSingleCell( false )
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
+ if ( xColumnRowRange->getRows()->getCount() == 1 && xColumnRowRange->getColumns()->getCount() == 1 )
+ bRangeIsSingleCell = true;
+ m_xProps.set( xRange, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaBorders::createEnumeration() throw (uno::RuntimeException)
+{
+ return new RangeBorderEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+ScVbaBorders::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // its already a Border object
+}
+
+uno::Type
+ScVbaBorders::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XBorders::static_type(0);
+}
+
+uno::Any
+ScVbaBorders::getItemByIntIndex( const sal_Int32 nIndex ) throw (uno::RuntimeException)
+{
+ return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) );
+}
+
+
+uno::Any SAL_CALL ScVbaBorders::getColor() throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ uno::Any color;
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ if( color.hasValue() )
+ {
+ if( color != xBorder->getColor() )
+ return uno::makeAny( uno::Reference< uno::XInterface >() );
+ }
+ else
+ color = xBorder->getColor();
+ }
+ }
+ return color;
+}
+void SAL_CALL ScVbaBorders::setColor( const uno::Any& _color ) throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setColor( _color );
+ }
+}
+uno::Any SAL_CALL ScVbaBorders::getColorIndex() throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ uno::Any nColorIndex;
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ if( nColorIndex.hasValue() )
+ {
+ if( nColorIndex != xBorder->getColorIndex() )
+ return uno::makeAny( uno::Reference< uno::XInterface >() );
+ }
+ else
+ nColorIndex = xBorder->getColorIndex();
+ }
+ }
+ return nColorIndex;
+}
+void SAL_CALL ScVbaBorders::setColorIndex( const uno::Any& _colorindex ) throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setColorIndex( _colorindex );
+ }
+}
+
+bool
+lcl_areAllLineWidthsSame( const table::TableBorder& maTableBorder, bool bIsCell )
+{
+
+ bool bRes = false;
+ if (bIsCell)
+ {
+ bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
+ }
+ else
+ {
+ bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.HorizontalLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.VerticalLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
+ }
+ return bRes;
+}
+
+uno::Any SAL_CALL ScVbaBorders::getLineStyle() throw (uno::RuntimeException)
+{
+ table::TableBorder maTableBorder;
+ m_xProps->getPropertyValue( sTableBorder ) >>= maTableBorder;
+
+ sal_Int32 aLinestyle = XlLineStyle::xlLineStyleNone;
+
+ if ( lcl_areAllLineWidthsSame( maTableBorder, bRangeIsSingleCell ))
+ {
+ if (maTableBorder.TopLine.LineDistance != 0)
+ {
+ aLinestyle = XlLineStyle::xlDouble;
+ }
+ else if ( maTableBorder.TopLine.OuterLineWidth != 0 )
+ {
+ aLinestyle = XlLineStyle::xlContinuous;
+ }
+ }
+ return uno::makeAny( aLinestyle );
+}
+void SAL_CALL ScVbaBorders::setLineStyle( const uno::Any& _linestyle ) throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setLineStyle( _linestyle );
+ }
+}
+uno::Any SAL_CALL ScVbaBorders::getWeight() throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ uno::Any weight;
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ if( weight.hasValue() )
+ {
+ if( weight != xBorder->getWeight() )
+ return uno::makeAny( uno::Reference< uno::XInterface >() );
+ }
+ else
+ weight = xBorder->getWeight();
+ }
+ }
+ return weight;
+}
+void SAL_CALL ScVbaBorders::setWeight( const uno::Any& _weight ) throw (uno::RuntimeException)
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setWeight( _weight );
+ }
+}
+
+
+rtl::OUString&
+ScVbaBorders::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaBorders") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaBorders::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Borders" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbaborders.hxx b/sc/source/ui/vba/vbaborders.hxx
new file mode 100644
index 000000000000..a385ad2e7a14
--- /dev/null
+++ b/sc/source/ui/vba/vbaborders.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_BORDERS_HXX
+#define SC_VBA_BORDERS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XBorders.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XBorders > ScVbaBorders_BASE;
+class ScVbaPalette;
+class ScVbaBorders : public ScVbaBorders_BASE
+{
+ // XEnumerationAccess
+ virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex ) throw (css::uno::RuntimeException);
+ bool bRangeIsSingleCell;
+ css::uno::Reference< css::beans::XPropertySet > m_xProps;
+public:
+ ScVbaBorders( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::table::XCellRange >& xRange, ScVbaPalette& rPalette );
+ virtual ~ScVbaBorders() {}
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+
+ // XBorders
+
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+
+ virtual css::uno::Any SAL_CALL getColor() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setColor( const css::uno::Any& _color ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getColorIndex() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setColorIndex( const css::uno::Any& _colorindex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getLineStyle() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLineStyle( const css::uno::Any& _linestyle ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getWeight() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setWeight( const css::uno::Any& ) throw (css::uno::RuntimeException);
+ // xxxxBASE
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_BORDERS_HXX
+
diff --git a/sc/source/ui/vba/vbacharacters.cxx b/sc/source/ui/vba/vbacharacters.cxx
new file mode 100644
index 000000000000..6c0079ac7a82
--- /dev/null
+++ b/sc/source/ui/vba/vbacharacters.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbacharacters.hxx"
+
+#include "vbaglobals.hxx"
+#include "vbafont.hxx"
+
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaCharacters::ScVbaCharacters( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, const uno::Reference< text::XSimpleText>& xRange,const css::uno::Any& Start, const css::uno::Any& Length, sal_Bool Replace ) throw ( css::lang::IllegalArgumentException ) : ScVbaCharacters_BASE( xParent, xContext ), m_xSimpleText(xRange), m_aPalette( dPalette), nLength(-1), nStart(1), bReplace( Replace )
+{
+ Start >>= nStart;
+ if ( nStart < 1 )
+ nStart = 1; // silently correct user error ( as ms )
+ nStart--; // OOo is 0 based
+ Length >>=nLength;
+ uno::Reference< text::XTextCursor > xTextCursor( m_xSimpleText->createTextCursor(), uno::UNO_QUERY_THROW );
+ xTextCursor->collapseToStart();
+ if ( nStart )
+ {
+ if ( ( nStart + 1 ) > m_xSimpleText->getString().getLength() )
+ //nStart = m_xSimpleText->getString().getLength();
+ xTextCursor->gotoEnd( sal_False );
+ xTextCursor->goRight( nStart, sal_False );
+ }
+ if ( nLength < 0 ) // expand to end
+ xTextCursor->gotoEnd( sal_True );
+ else
+ xTextCursor->goRight( nLength, sal_True );
+ m_xTextRange.set( xTextCursor, uno::UNO_QUERY_THROW );
+
+}
+
+::rtl::OUString SAL_CALL
+ScVbaCharacters::getCaption() throw (css::uno::RuntimeException)
+{
+ return m_xTextRange->getString();
+}
+void SAL_CALL
+ScVbaCharacters::setCaption( const ::rtl::OUString& _caption ) throw (css::uno::RuntimeException)
+{
+ m_xTextRange->setString( _caption );
+
+}
+
+::sal_Int32 SAL_CALL
+ScVbaCharacters::getCount() throw (css::uno::RuntimeException)
+{
+ return getCaption().getLength();
+}
+
+::rtl::OUString SAL_CALL
+ScVbaCharacters::getText() throw (css::uno::RuntimeException)
+{
+ return getCaption();
+}
+void SAL_CALL
+ScVbaCharacters::setText( const ::rtl::OUString& _text ) throw (css::uno::RuntimeException)
+{
+ setCaption( _text );
+}
+uno::Reference< excel::XFont > SAL_CALL
+ScVbaCharacters::getFont() throw (css::uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xTextRange, uno::UNO_QUERY_THROW );
+ return uno::Reference< excel::XFont >( new ScVbaFont( this, mxContext, m_aPalette, xProps ) );
+}
+void SAL_CALL
+ScVbaCharacters::setFont( const uno::Reference< excel::XFont >& /*_font*/ ) throw (css::uno::RuntimeException)
+{
+ // #TODO #FIXME needs implementation, or can't be done?
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Not Implemented") ), uno::Reference< XInterface >() );
+}
+
+
+// Methods
+void SAL_CALL
+ScVbaCharacters::Insert( const ::rtl::OUString& String ) throw (css::uno::RuntimeException)
+{
+ m_xSimpleText->insertString( m_xTextRange, String, bReplace );
+}
+
+void SAL_CALL
+ScVbaCharacters::Delete( ) throw (css::uno::RuntimeException)
+{
+ // #FIXME #TODO is this a bit suspect?, I wonder should the contents
+ // of the cell be deleted from the parent ( range )
+ m_xSimpleText->setString(rtl::OUString());
+}
+
+
+rtl::OUString&
+ScVbaCharacters::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaCharacters") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaCharacters::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Characters" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbacharacters.hxx b/sc/source/ui/vba/vbacharacters.hxx
new file mode 100644
index 000000000000..3400ff159d5e
--- /dev/null
+++ b/sc/source/ui/vba/vbacharacters.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_CHARACTERS_HXX
+#define SC_VBA_CHARACTERS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <ooo/vba/excel/XCharacters.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include "vbapalette.hxx"
+typedef InheritedHelperInterfaceImpl1< ov::excel::XCharacters > ScVbaCharacters_BASE;
+
+class ScVbaCharacters : public ScVbaCharacters_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextRange > m_xTextRange;
+ css::uno::Reference< css::text::XSimpleText > m_xSimpleText;
+ ScVbaPalette m_aPalette;
+ sal_Int16 nLength;
+ sal_Int16 nStart;
+ // Add becuase of MSO has diferent behavior.
+ sal_Bool bReplace;
+public:
+ ScVbaCharacters( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, const css::uno::Reference< css::text::XSimpleText >& xRange, const css::uno::Any& Start, const css::uno::Any& Length, sal_Bool bReplace = sal_False ) throw ( css::lang::IllegalArgumentException );
+
+ virtual ~ScVbaCharacters() {}
+ // Attributes
+ virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCaption( const ::rtl::OUString& _caption ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setText( const ::rtl::OUString& _text ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& _font ) throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual void SAL_CALL Insert( const ::rtl::OUString& String ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Delete( ) throw (css::uno::RuntimeException);
+
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+};
+
+#endif /* SC_VBA_CHARACTER_HXX */
+
diff --git a/sc/source/ui/vba/vbachart.cxx b/sc/source/ui/vba/vbachart.cxx
new file mode 100644
index 000000000000..e2f446f93f2b
--- /dev/null
+++ b/sc/source/ui/vba/vbachart.cxx
@@ -0,0 +1,1253 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbachart.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/chart/XAxisXSupplier.hpp>
+#include <com/sun/star/chart/XAxisYSupplier.hpp>
+#include <com/sun/star/chart/XAxisZSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
+#include <com/sun/star/chart/XChartDataArray.hpp>
+#include <com/sun/star/chart/ChartSymbolType.hpp>
+#include <com/sun/star/chart/ChartSolidType.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart/ChartDataCaption.hpp>
+#include <ooo/vba/excel/XlChartType.hpp>
+#include <ooo/vba/excel/XlRowCol.hpp>
+#include <ooo/vba/excel/XlAxisType.hpp>
+#include <ooo/vba/excel/XlAxisGroup.hpp>
+
+#include <basic/sberrors.hxx>
+#include "vbachartobject.hxx"
+#include "vbarange.hxx"
+#include "vbacharttitle.hxx"
+#include "vbaaxes.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlChartType;
+using namespace ::ooo::vba::excel::XlRowCol;
+using namespace ::ooo::vba::excel::XlAxisType;
+using namespace ::ooo::vba::excel::XlAxisGroup;
+
+const rtl::OUString CHART_NAME( RTL_CONSTASCII_USTRINGPARAM("Name") );
+// #TODO move this constant to vbaseries.[ch]xx ( when it exists )
+const rtl::OUString DEFAULTSERIESPREFIX( RTL_CONSTASCII_USTRINGPARAM("Series") );
+const rtl::OUString DATAROWSOURCE( RTL_CONSTASCII_USTRINGPARAM("DataRowSource") );
+const rtl::OUString UPDOWN( RTL_CONSTASCII_USTRINGPARAM("UpDown") );
+const rtl::OUString VOLUME( RTL_CONSTASCII_USTRINGPARAM("Volume") );
+const rtl::OUString LINES( RTL_CONSTASCII_USTRINGPARAM("Lines") );
+const rtl::OUString SPLINETYPE( RTL_CONSTASCII_USTRINGPARAM("SplineType") );
+const rtl::OUString SYMBOLTYPE( RTL_CONSTASCII_USTRINGPARAM("SymbolType") );
+const rtl::OUString DEEP( RTL_CONSTASCII_USTRINGPARAM("Deep") );
+const rtl::OUString SOLIDTYPE( RTL_CONSTASCII_USTRINGPARAM("SolidType") );
+const rtl::OUString VERTICAL( RTL_CONSTASCII_USTRINGPARAM("Vertical") );
+const rtl::OUString PERCENT( RTL_CONSTASCII_USTRINGPARAM("Percent") );
+const rtl::OUString STACKED( RTL_CONSTASCII_USTRINGPARAM("Stacked") );
+const rtl::OUString DIM3D( RTL_CONSTASCII_USTRINGPARAM("Dim3D") );
+const rtl::OUString HASMAINTITLE( RTL_CONSTASCII_USTRINGPARAM("HasMainTitle") );
+const rtl::OUString HASLEGEND( RTL_CONSTASCII_USTRINGPARAM("HasLegend") );
+const rtl::OUString DATACAPTION( RTL_CONSTASCII_USTRINGPARAM("DataCaption") );
+
+ScVbaChart::ScVbaChart( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::lang::XComponent >& _xChartComponent, const css::uno::Reference< css::table::XTableChart >& _xTableChart ) : ChartImpl_BASE( _xParent, _xContext ), mxTableChart( _xTableChart )
+{
+ mxChartDocument.set( _xChartComponent, uno::UNO_QUERY_THROW ) ;
+ // #TODO is is possible that the XPropertySet interface is not set
+ // code in setPlotBy seems to indicate that this is possible? but
+ // additionally there is no check in most of the places where it is used
+ // ( and therefore could possibly be NULL )
+ // I'm going to let it throw for the moment ( npower )
+ mxDiagramPropertySet.set( mxChartDocument->getDiagram(), uno::UNO_QUERY_THROW );
+ mxChartPropertySet.set( _xChartComponent, uno::UNO_QUERY_THROW ) ;
+}
+
+::rtl::OUString SAL_CALL
+ScVbaChart::getName() throw (css::uno::RuntimeException)
+{
+ rtl::OUString sName;
+ uno::Reference< beans::XPropertySet > xProps( mxChartDocument, uno::UNO_QUERY_THROW );
+ try
+ {
+ xProps->getPropertyValue( CHART_NAME ) >>= sName;
+ }
+ catch( uno::Exception e ) // swallow exceptions
+ {
+ }
+ return sName;
+}
+
+uno::Any SAL_CALL
+ScVbaChart::SeriesCollection(const uno::Any&) throw (uno::RuntimeException)
+{
+ return uno::Any();
+}
+
+::sal_Int32 SAL_CALL
+ScVbaChart::getChartType() throw ( uno::RuntimeException, script::BasicErrorException)
+{
+ sal_Int32 nChartType = -1;
+ try
+ {
+ rtl::OUString sDiagramType = mxChartDocument->getDiagram()->getDiagramType();
+ if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart.AreaDiagram" ))))
+ {
+ if (is3D())
+ {
+ nChartType = getStackedType(xl3DAreaStacked, xl3DAreaStacked100, xl3DArea);
+ }
+ else
+ {
+ nChartType = getStackedType(xlAreaStacked, xlAreaStacked100, xlArea);
+ }
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.PieDiagram"))))
+ {
+ if (is3D())
+ nChartType = xl3DPie;
+ else
+ nChartType = xlPie; /*TODO XlChartType xlPieExploded, XlChartType xlPieOfPie */
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.BarDiagram"))))
+ {
+ sal_Int32 nSolidType = chart::ChartSolidType::RECTANGULAR_SOLID;
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SOLIDTYPE))
+ { //in 2D diagrams 'SolidType' may not be set
+ if (is3D())
+ mxDiagramPropertySet->getPropertyValue(SOLIDTYPE) >>= nSolidType;
+ }
+ switch (nSolidType)
+ {
+ case chart::ChartSolidType::CONE:
+ nChartType = getSolidType(xlConeCol, xlConeColStacked, xlConeColStacked100, xlConeColClustered, xlConeBarStacked, xlConeBarStacked100, xlConeBarClustered);
+ break;
+ case chart::ChartSolidType::CYLINDER:
+ nChartType = getSolidType(xlCylinderCol, xlCylinderColStacked, xlCylinderColStacked100, xlCylinderColClustered, xlCylinderBarStacked, xlCylinderBarStacked100, xlCylinderBarClustered);
+ break;
+ case chart::ChartSolidType::PYRAMID:
+ nChartType = getSolidType(xlPyramidCol, xlPyramidColStacked, xlPyramidColStacked100, xlPyramidColClustered, xlPyramidBarStacked, xlPyramidBarStacked100, xlPyramidBarClustered);
+ break;
+ default: // RECTANGULAR_SOLID
+ if (is3D())
+ {
+ nChartType = getSolidType(xl3DColumn, xl3DColumnStacked, xl3DColumnStacked100, xl3DColumnClustered, xl3DBarStacked, xl3DBarStacked100, xl3DBarClustered);
+ }
+ else
+ {
+ nChartType = getSolidType(xlColumnClustered, xlColumnStacked, xlColumnStacked100, xlColumnClustered, xlBarStacked, xlBarStacked100, xlBarClustered);
+ }
+ break;
+ }
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.StockDiagram"))))
+ {
+ sal_Bool bVolume = sal_False;
+ mxDiagramPropertySet->getPropertyValue(VOLUME) >>= bVolume;
+ if (bVolume)
+ {
+ nChartType = getStockUpDownValue(xlStockVOHLC, xlStockVHLC);
+ }
+ else
+ {
+ nChartType = getStockUpDownValue(xlStockOHLC, xlStockHLC);
+ }
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.XYDiagram"))))
+ {
+ sal_Bool bHasLines = sal_False;
+ mxDiagramPropertySet->getPropertyValue(LINES) >>= bHasLines;
+ sal_Int32 nSplineType = 0;
+ mxDiagramPropertySet->getPropertyValue(SPLINETYPE) >>= nSplineType;
+ if (nSplineType == 1)
+ {
+ nChartType = getMarkerType(xlXYScatterSmooth, xlXYScatterSmoothNoMarkers);
+ }
+ else if (bHasLines)
+ {
+ nChartType = getMarkerType(xlXYScatterLines, xlXYScatterLinesNoMarkers);
+ }
+ else
+ {
+ nChartType = xlXYScatter;
+ }
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.LineDiagram"))))
+ {
+ if (is3D())
+ {
+ nChartType = xl3DLine;
+ }
+ else if (hasMarkers())
+ {
+ nChartType = getStackedType(xlLineMarkersStacked, xlLineMarkersStacked100, xlLineMarkers);
+ }
+ else
+ {
+ nChartType = getStackedType(xlLineStacked, xlLineStacked100, xlLine);
+ }
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.DonutDiagram"))))
+ {
+ nChartType = xlDoughnut; // TODO DoughnutExploded ??
+ }
+ else if (sDiagramType.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.NetDiagram"))))
+ {
+ nChartType = getMarkerType(xlRadarMarkers, xlRadar);
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return nChartType;
+}
+
+void SAL_CALL
+ScVbaChart::setChartType( ::sal_Int32 _nChartType ) throw ( uno::RuntimeException, script::BasicErrorException)
+{
+try
+{
+ switch (_nChartType)
+ {
+ case xlColumnClustered:
+ case xlColumnStacked:
+ case xlColumnStacked100:
+ case xl3DColumnClustered:
+ case xl3DColumnStacked:
+ case xl3DColumnStacked100:
+ case xl3DColumn:
+ case xlBarClustered:
+ case xlBarStacked:
+ case xlBarStacked100:
+ case xl3DBarClustered:
+ case xl3DBarStacked:
+ case xl3DBarStacked100:
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlConeBarClustered:
+ case xlConeBarStacked:
+ case xlConeBarStacked100:
+ case xlConeCol:
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlPyramidBarClustered:
+ case xlPyramidBarStacked:
+ case xlPyramidBarStacked100:
+ case xlPyramidCol:
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlCylinderBarClustered:
+ case xlCylinderBarStacked:
+ case xlCylinderBarStacked100:
+ case xlCylinderCol:
+ case xlSurface: // not possible
+ case xlSurfaceWireframe:
+ case xlSurfaceTopView:
+ case xlSurfaceTopViewWireframe:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.BarDiagram")));
+ break;
+ case xlLine:
+ case xl3DLine:
+ case xlLineStacked:
+ case xlLineStacked100:
+ case xlLineMarkers:
+ case xlLineMarkersStacked:
+ case xlLineMarkersStacked100:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.LineDiagram")));
+ break;
+ case xl3DArea:
+ case xlArea:
+ case xlAreaStacked:
+ case xlAreaStacked100:
+ case xl3DAreaStacked:
+ case xl3DAreaStacked100:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.AreaDiagram")) );
+ break;
+ case xlDoughnut:
+ case xlDoughnutExploded:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.DonutDiagram") ) );
+ break;
+ case xlStockHLC:
+ case xlStockOHLC:
+ case xlStockVHLC:
+ case xlStockVOHLC:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.StockDiagram")));
+ mxDiagramPropertySet->setPropertyValue( UPDOWN, uno::makeAny(sal_Bool((_nChartType == xlStockOHLC) || (_nChartType == xlStockVOHLC))));
+ mxDiagramPropertySet->setPropertyValue(VOLUME, uno::makeAny(sal_Bool((_nChartType == xlStockVHLC) || (_nChartType == xlStockVOHLC))));
+ break;
+
+ case xlPieOfPie: // not possible
+ case xlPieExploded: // SegmentOffset an ChartDataPointProperties ->am XDiagram abholen //wie macht Excel das?
+ case xl3DPieExploded:
+ case xl3DPie:
+ case xlPie:
+ case xlBarOfPie: // not possible (Zoom pie)
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.PieDiagram")));
+ break;
+
+ case xlRadar:
+ case xlRadarMarkers:
+ case xlRadarFilled:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.NetDiagram")));
+ break;
+ case xlXYScatter:
+ case xlBubble: // not possible
+ case xlBubble3DEffect: // not possible
+ case xlXYScatterLines:
+ case xlXYScatterLinesNoMarkers:
+ case xlXYScatterSmooth:
+ case xlXYScatterSmoothNoMarkers:
+ setDiagram( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart.XYDiagram")));
+ switch(_nChartType)
+ {
+ case xlXYScatter:
+ case xlBubble: // not possible
+ case xlBubble3DEffect: // not possible
+ mxDiagramPropertySet->setPropertyValue(LINES, uno::makeAny( sal_False ));
+ break;
+ case xlXYScatterLines:
+ case xlXYScatterLinesNoMarkers:
+ mxDiagramPropertySet->setPropertyValue(LINES, uno::makeAny( sal_True ));
+ break;
+ case xlXYScatterSmooth:
+ case xlXYScatterSmoothNoMarkers:
+ mxDiagramPropertySet->setPropertyValue(SPLINETYPE, uno::makeAny( sal_Int32(1)));
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_CONVERSION, rtl::OUString() );
+ }
+
+ switch (_nChartType)
+ {
+ case xlLineMarkers:
+ case xlLineMarkersStacked:
+ case xlLineMarkersStacked100:
+ case xlRadarMarkers:
+ case xlXYScatterLines:
+ case xlXYScatterSmooth:
+ case xlXYScatter:
+ case xlBubble: // not possible
+ case xlBubble3DEffect: // not possible
+ mxDiagramPropertySet->setPropertyValue(SYMBOLTYPE, uno::makeAny( chart::ChartSymbolType::AUTO));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SYMBOLTYPE))
+ {
+ mxDiagramPropertySet->setPropertyValue(SYMBOLTYPE, uno::makeAny(chart::ChartSymbolType::NONE));
+ }
+ break;
+ }
+
+ switch (_nChartType)
+ {
+ case xlConeCol:
+ case xlPyramidCol:
+ case xlCylinderCol:
+ case xl3DColumn:
+ case xlSurface: // not possible
+ case xlSurfaceWireframe:
+ case xlSurfaceTopView:
+ case xlSurfaceTopViewWireframe:
+ mxDiagramPropertySet->setPropertyValue(DEEP,uno::makeAny( sal_True ));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(DEEP))
+ {
+ mxDiagramPropertySet->setPropertyValue(DEEP, uno::makeAny( sal_False));
+ }
+ break;
+ }
+
+
+ switch (_nChartType)
+ {
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlConeBarClustered:
+ case xlConeBarStacked:
+ case xlConeBarStacked100:
+ case xlConeCol:
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::makeAny(chart::ChartSolidType::CONE));
+ break;
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlPyramidBarClustered:
+ case xlPyramidBarStacked:
+ case xlPyramidBarStacked100:
+ case xlPyramidCol:
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::makeAny(chart::ChartSolidType::PYRAMID));
+ break;
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlCylinderBarClustered:
+ case xlCylinderBarStacked:
+ case xlCylinderBarStacked100:
+ case xlCylinderCol:
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::makeAny(chart::ChartSolidType::CYLINDER));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SOLIDTYPE))
+ {
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::makeAny(chart::ChartSolidType::RECTANGULAR_SOLID));
+ }
+ break;
+ }
+
+ switch ( _nChartType)
+ {
+ case xlConeCol:
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlColumnClustered:
+ case xlColumnStacked:
+ case xlColumnStacked100:
+ case xl3DColumnClustered:
+ case xl3DColumnStacked:
+ case xl3DColumnStacked100:
+ case xlSurface: // not possible
+ case xlSurfaceWireframe:
+ case xlSurfaceTopView:
+ case xlSurfaceTopViewWireframe:
+ mxDiagramPropertySet->setPropertyValue(VERTICAL, uno::makeAny( sal_True));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(VERTICAL))
+ {
+ mxDiagramPropertySet->setPropertyValue(VERTICAL, uno::makeAny(sal_False));
+ }
+ break;
+ }
+
+ switch (_nChartType)
+ {
+ case xlColumnStacked:
+ case xl3DColumnStacked:
+ case xlBarStacked:
+ case xl3DBarStacked:
+ case xlLineStacked:
+ case xlLineMarkersStacked:
+ case xlAreaStacked:
+ case xl3DAreaStacked:
+ case xlCylinderColStacked:
+ case xlCylinderBarStacked:
+ case xlConeColStacked:
+ case xlConeBarStacked:
+ case xlPyramidColStacked:
+ case xlPyramidBarStacked:
+ mxDiagramPropertySet->setPropertyValue(PERCENT, uno::makeAny( sal_False ));
+ mxDiagramPropertySet->setPropertyValue(STACKED, uno::makeAny( sal_True ));
+ break;
+ case xlPyramidColStacked100:
+ case xlPyramidBarStacked100:
+ case xlConeColStacked100:
+ case xlConeBarStacked100:
+ case xlCylinderBarStacked100:
+ case xlCylinderColStacked100:
+ case xl3DAreaStacked100:
+ case xlLineMarkersStacked100:
+ case xlAreaStacked100:
+ case xlLineStacked100:
+ case xl3DBarStacked100:
+ case xlBarStacked100:
+ case xl3DColumnStacked100:
+ case xlColumnStacked100:
+ mxDiagramPropertySet->setPropertyValue(STACKED, uno::makeAny( sal_True));
+ mxDiagramPropertySet->setPropertyValue(PERCENT, uno::makeAny( sal_True ));
+ break;
+ default:
+ mxDiagramPropertySet->setPropertyValue(PERCENT, uno::makeAny( sal_False));
+ mxDiagramPropertySet->setPropertyValue(STACKED, uno::makeAny( sal_False));
+ break;
+ }
+ switch (_nChartType)
+ {
+ case xl3DArea:
+ case xl3DAreaStacked:
+ case xl3DAreaStacked100:
+ case xl3DBarClustered:
+ case xl3DBarStacked:
+ case xl3DBarStacked100:
+ case xl3DColumn:
+ case xl3DColumnClustered:
+ case xl3DColumnStacked:
+ case xl3DColumnStacked100:
+ case xl3DLine:
+ case xl3DPie:
+ case xl3DPieExploded:
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlConeBarClustered:
+ case xlConeBarStacked:
+ case xlConeBarStacked100:
+ case xlConeCol:
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlPyramidBarClustered:
+ case xlPyramidBarStacked:
+ case xlPyramidBarStacked100:
+ case xlPyramidCol:
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlCylinderBarClustered:
+ case xlCylinderBarStacked:
+ case xlCylinderBarStacked100:
+ case xlCylinderCol:
+ mxDiagramPropertySet->setPropertyValue(DIM3D, uno::makeAny( sal_True));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(DIM3D))
+ {
+ mxDiagramPropertySet->setPropertyValue(DIM3D, uno::makeAny( sal_False));
+ }
+ break;
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+void SAL_CALL
+ScVbaChart::Activate() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ // #TODO how are Chart sheets handled ( I know we don't even consider
+ // them in the worksheets/sheets collections ), but.....???
+ // note: in vba for excel the parent of a Chart sheet is a workbook,
+ // e.g. 'ThisWorkbook'
+ uno::Reference< XHelperInterface > xParent( getParent() );
+ ScVbaChartObject* pChartObj = static_cast< ScVbaChartObject* >( xParent.get() );
+ if ( pChartObj )
+ pChartObj->Activate();
+ else
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no ChartObject as parent" ) ) );
+}
+
+void SAL_CALL
+ScVbaChart::setSourceData( const css::uno::Reference< ::ooo::vba::excel::XRange >& _xCalcRange, const css::uno::Any& _aPlotBy ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Sequence< table::CellRangeAddress > mRangeAddresses(1);
+ table::CellRangeAddress mSingleRangeAddress;
+
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( _xCalcRange->getCellRange(), uno::UNO_QUERY_THROW );
+ mSingleRangeAddress = xAddressable->getRangeAddress();
+
+ mRangeAddresses[0] = mSingleRangeAddress;
+
+ mxTableChart->setRanges(mRangeAddresses);
+
+ sal_Bool bsetRowHeaders = sal_False;
+ sal_Bool bsetColumnHeaders = sal_False;
+
+ ScVbaRange* pRange = static_cast< ScVbaRange* >( _xCalcRange.get() );
+ if ( pRange )
+ {
+ ScDocument* pDoc = pRange->getScDocument();
+ if ( pDoc )
+ {
+ bsetRowHeaders = pDoc->HasRowHeader( static_cast< SCCOL >( mSingleRangeAddress.StartColumn ), static_cast< SCROW >( mSingleRangeAddress.StartRow ), static_cast< SCCOL >( mSingleRangeAddress.EndColumn ), static_cast< SCROW >( mSingleRangeAddress.EndRow ), static_cast< SCTAB >( mSingleRangeAddress.Sheet ) );;
+ bsetColumnHeaders = pDoc->HasColHeader( static_cast< SCCOL >( mSingleRangeAddress.StartColumn ), static_cast< SCROW >( mSingleRangeAddress.StartRow ), static_cast< SCCOL >( mSingleRangeAddress.EndColumn ), static_cast< SCROW >( mSingleRangeAddress.EndRow ), static_cast< SCTAB >( mSingleRangeAddress.Sheet ));
+;
+ }
+ }
+ mxTableChart->setHasRowHeaders(bsetRowHeaders);
+ mxTableChart->setHasColumnHeaders(bsetColumnHeaders);
+
+ if ((!bsetColumnHeaders) || (!bsetRowHeaders))
+ {
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ if (!bsetColumnHeaders)
+ {
+ xChartDataArray->setColumnDescriptions( getDefaultSeriesDescriptions(xChartDataArray->getColumnDescriptions().getLength() ));
+ }
+ if (!bsetRowHeaders)
+ {
+ xChartDataArray->setRowDescriptions(getDefaultSeriesDescriptions(xChartDataArray->getRowDescriptions().getLength() ));
+ }
+ }
+
+ if ( _aPlotBy.hasValue() )
+ {
+ sal_Int32 nVal = 0;
+ _aPlotBy >>= nVal;
+ setPlotBy( nVal );
+ }
+ else
+ {
+ sal_Int32 nRows = mSingleRangeAddress.EndRow - mSingleRangeAddress.StartRow;
+ sal_Int32 nCols = mSingleRangeAddress.EndColumn - mSingleRangeAddress.StartColumn;
+ // AutoDetect emulation
+ if ( nRows > nCols )
+ setPlotBy( xlColumns );
+ else if ( nRows <= nCols )
+ setPlotBy( xlRows );
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaChart::getDefaultSeriesDescriptions( sal_Int32 _nCount )
+{
+ uno::Sequence< rtl::OUString > sDescriptions ( _nCount );
+ sal_Int32 nLen = sDescriptions.getLength();
+ for (sal_Int32 i = 0; i < nLen; i++)
+ {
+ sDescriptions[i] = DEFAULTSERIESPREFIX + rtl::OUString::valueOf(i+1);
+ }
+ return sDescriptions;
+}
+
+void
+ScVbaChart::setDefaultChartType() throw ( script::BasicErrorException )
+{
+ setChartType( xlColumnClustered );
+}
+
+void
+ScVbaChart::setPlotBy( ::sal_Int32 _nPlotBy ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ try
+ {
+ if ( !mxDiagramPropertySet.is() )
+ setDefaultChartType();
+ switch (_nPlotBy)
+ {
+ case xlRows:
+ mxDiagramPropertySet->setPropertyValue( DATAROWSOURCE, uno::makeAny( chart::ChartDataRowSource_ROWS ) );
+ break;
+ case xlColumns:
+ mxDiagramPropertySet->setPropertyValue( DATAROWSOURCE, uno::makeAny( chart::ChartDataRowSource_COLUMNS) );
+ break;
+ default:
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+::sal_Int32 SAL_CALL
+ScVbaChart::getPlotBy( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ chart::ChartDataRowSource aChartDataRowSource;
+ mxDiagramPropertySet->getPropertyValue(DATAROWSOURCE) >>= aChartDataRowSource;
+ if (aChartDataRowSource == chart::ChartDataRowSource_COLUMNS)
+ {
+ return xlColumns;
+ }
+ else
+ {
+ return xlRows;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+void
+ScVbaChart::setDiagram( const rtl::OUString& _sDiagramType ) throw( script::BasicErrorException )
+{
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF( mxChartDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< chart::XDiagram > xDiagram( xMSF->createInstance( _sDiagramType ), uno::UNO_QUERY_THROW );
+ mxChartDocument->setDiagram( xDiagram );
+ mxDiagramPropertySet.set( xDiagram, uno::UNO_QUERY_THROW );
+ }
+ catch ( uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+// #TODO find out why we have Location/getLocation ? there is afaiks no
+// Location property, just a Location function for the Chart object
+sal_Int32 SAL_CALL
+ScVbaChart::Location() throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return getLocation();
+}
+
+sal_Int32 SAL_CALL
+ScVbaChart::getLocation() throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return -1;
+}
+
+void SAL_CALL
+ScVbaChart::setLocation( ::sal_Int32 /*where*/, const css::uno::Any& /*Name*/ ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ // Helper api just stubs out the code <shrug>
+ // #TODO come back and make sense out of this
+// String sheetName = null;
+//
+// if ((name != null) && name instanceof String) {
+// sheetName = (String) name;
+// }
+// XSpreadsheetDocument xShDoc = (XSpreadsheetDocument) UnoRuntime.queryInterface( XSpreadsheetDocument.class,getXModel() );
+// com.sun.star.sheet.XSpreadsheets xSheets = xShDoc.Sheets();
+//
+// switch (where) {
+// case ClLocationType.clLocationAsObject_value: //{
+//
+// if (sheetName == null) {
+// DebugHelper.writeInfo("Can't embed in Chart without knowing SheetName");
+// return;
+// }
+//
+// try {
+// Any any = (Any) xSheets.getByName(sheetName);
+// chartSheet = (XSpreadsheet) any.getObject();
+//
+// // chartSheet = (XSpreadsheet) xSheets.getByName( sheetName );
+// } catch (NoSuchElementException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// } catch (WrappedTargetException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// } catch (java.lang.Exception e) {
+// e.printStackTrace();
+// }
+//
+// XTableChartsSupplier xTCS = (XTableChartsSupplier) UnoRuntime.queryInterface( XTableChartsSupplier.class, chartSheet);
+// XTableCharts xTableCharts = xTCS.getCharts();
+// XIndexAccess xIA = (XIndexAccess) UnoRuntime.queryInterface( XIndexAccess.class, xTableCharts);
+// int numCharts = xIA.getCount();
+// chartName = "Chart " + (numCharts + 1);
+//
+// //}
+// break;
+//
+// case ClLocationType.clLocationAsNewSheet_value:
+// case ClLocationType.clLocationAutomatic_value:default: //{
+// chartName = "Chart 1"; // Since it's a new sheet, it's the first on it...
+//
+// XIndexAccess xSheetIA = (XIndexAccess) UnoRuntime.queryInterface( XIndexAccess.class, xSheets);
+//
+// short newSheetNum = (short) (xSheetIA.getCount() + 1);
+//
+// if (sheetName == null){
+// sheetName = "ChartSheet " + newSheetNum; // Why not?
+// }
+// // DPK TODO : Probably should use Sheets to create this!
+// xSheets.insertNewByName(sheetName, newSheetNum);
+//
+// try {
+// chartSheet =
+// (XSpreadsheet) xSheets.getByName(sheetName);
+// } catch (NoSuchElementException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// } catch (WrappedTargetException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// }
+//
+// //}
+// break;
+// }
+//
+// // Last thing should be a call to createChartForReal(), one of them
+// // should succeed.
+// createChartForReal();
+
+}
+
+sal_Bool SAL_CALL
+ScVbaChart::getHasTitle( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bHasTitle = sal_False;
+ try
+ {
+ mxChartPropertySet->getPropertyValue(HASMAINTITLE) >>= bHasTitle;
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return bHasTitle;
+}
+
+void SAL_CALL
+ScVbaChart::setHasTitle( ::sal_Bool bTitle ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ mxChartPropertySet->setPropertyValue(HASMAINTITLE, uno::makeAny( bTitle ));
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+
+}
+
+::sal_Bool SAL_CALL
+ScVbaChart::getHasLegend( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Bool bHasLegend = sal_False;
+ try
+ {
+ mxChartPropertySet->getPropertyValue(HASLEGEND) >>= bHasLegend;
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return bHasLegend;
+}
+
+void SAL_CALL
+ScVbaChart::setHasLegend( ::sal_Bool bLegend ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ mxChartPropertySet->setPropertyValue(HASLEGEND, uno::makeAny(bLegend));
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+uno::Reference< excel::XChartTitle > SAL_CALL
+ScVbaChart::getChartTitle( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< drawing::XShape > xTitleShape = mxChartDocument->getTitle();
+ // #TODO check parent
+ return new ScVbaChartTitle(this, mxContext, xTitleShape);
+}
+
+uno::Any SAL_CALL
+ScVbaChart::Axes( const uno::Any& Type, const uno::Any& AxisGroup ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ // mmm chart probably is the parent, #TODO check parent
+ uno::Reference< excel::XAxes > xAxes = new ScVbaAxes( this, mxContext, this );
+ if ( !Type.hasValue() )
+ return uno::makeAny( xAxes );
+ return xAxes->Item( Type, AxisGroup );
+}
+bool
+ScVbaChart::is3D() throw ( uno::RuntimeException )
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ sal_Bool is3d = sal_False;
+ mxDiagramPropertySet->getPropertyValue(DIM3D) >>= is3d;
+ return is3d;
+}
+
+sal_Int32
+ScVbaChart::getStackedType( sal_Int32 _nStacked, sal_Int32 _n100PercentStacked, sal_Int32 _nUnStacked ) throw ( uno::RuntimeException )
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ if (isStacked())
+ {
+ if (is100PercentStacked())
+ return _n100PercentStacked;
+ else
+ return _nStacked;
+ }
+ else
+ return _nUnStacked;
+}
+
+bool
+ScVbaChart::isStacked() throw ( uno::RuntimeException )
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ sal_Bool bStacked = sal_False;
+ mxDiagramPropertySet->getPropertyValue(STACKED) >>= bStacked;
+ return bStacked;
+}
+
+bool
+ScVbaChart::is100PercentStacked() throw ( uno::RuntimeException )
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ sal_Bool b100Percent = sal_False;
+ mxDiagramPropertySet->getPropertyValue(PERCENT) >>= b100Percent;
+ return b100Percent;
+}
+
+sal_Int32
+ScVbaChart::getSolidType(sal_Int32 _nDeep, sal_Int32 _nVertiStacked, sal_Int32 _nVerti100PercentStacked, sal_Int32 _nVertiUnStacked, sal_Int32 _nHoriStacked, sal_Int32 _nHori100PercentStacked, sal_Int32 _nHoriUnStacked) throw ( script::BasicErrorException )
+{
+ sal_Bool bIsVertical = true;
+ try
+ {
+ mxDiagramPropertySet->getPropertyValue(VERTICAL) >>= bIsVertical;
+ sal_Bool bIsDeep = false;
+ mxDiagramPropertySet->getPropertyValue(DEEP) >>= bIsDeep;
+
+ if (bIsDeep)
+ {
+ return _nDeep;
+ }
+ else
+ {
+ if (bIsVertical)
+ {
+ return getStackedType(_nVertiStacked, _nVerti100PercentStacked, _nVertiUnStacked);
+ }
+ else
+ {
+ return getStackedType(_nHoriStacked, _nHori100PercentStacked, _nHoriUnStacked);
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+
+sal_Int32
+ScVbaChart::getStockUpDownValue(sal_Int32 _nUpDown, sal_Int32 _nNotUpDown) throw (script::BasicErrorException)
+{
+ sal_Bool bUpDown = sal_False;
+ try
+ {
+ mxDiagramPropertySet->getPropertyValue(UPDOWN) >>= bUpDown;
+ if (bUpDown)
+ {
+ return _nUpDown;
+ }
+ else
+ {
+ return _nNotUpDown;
+ }
+ }
+ catch (uno::Exception& )
+ {
+ rtl::OUString aTemp; // temporary needed for g++ 3.3.5
+ script::BasicErrorException( aTemp, uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return _nNotUpDown;
+}
+
+bool
+ScVbaChart::hasMarkers() throw ( script::BasicErrorException )
+{
+ bool bHasMarkers = false;
+ try
+ {
+ sal_Int32 nSymbol=0;
+ mxDiagramPropertySet->getPropertyValue(SYMBOLTYPE) >>= nSymbol;
+ bHasMarkers = nSymbol != chart::ChartSymbolType::NONE;
+ }
+ catch ( uno::Exception& )
+ {
+ rtl::OUString aTemp; // temporary needed for g++ 3.3.5
+ script::BasicErrorException( aTemp, uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return bHasMarkers;
+}
+
+sal_Int32
+ScVbaChart::getMarkerType(sal_Int32 _nWithMarkers, sal_Int32 _nWithoutMarkers) throw ( script::BasicErrorException )
+{
+ if (hasMarkers())
+ return _nWithMarkers;
+ return _nWithoutMarkers;
+}
+
+void
+ScVbaChart::assignDiagramAttributes()
+{
+ xAxisXSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xAxisYSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xAxisZSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xTwoAxisXSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xTwoAxisYSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+}
+
+bool
+ScVbaChart::isSeriesIndexValid(sal_Int32 _seriesindex) throw( script::BasicErrorException )
+{
+ bool bret = false;
+ try
+ {
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ // dblValues = xChartDataArray.getData();
+ //TODO I guess we have to differentiate between XlRowCol
+ if ( !xChartDataArray.is() )
+ {
+ if (getPlotBy() == xlRows)
+ {
+ if ((_seriesindex < xChartDataArray->getRowDescriptions().getLength() ) && (_seriesindex >= 0))
+ bret = true;
+ }
+ else
+ {
+ if ((_seriesindex < xChartDataArray->getColumnDescriptions().getLength() ) && (_seriesindex >= 0))
+ bret = true;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ if (!bret)
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_OUT_OF_RANGE, rtl::OUString() );
+ }
+ return bret;
+}
+
+bool
+ScVbaChart::areIndicesValid( sal_Int32 _seriesindex, sal_Int32 _valindex) throw ( css::script::BasicErrorException )
+{
+ if (isSeriesIndexValid(_seriesindex))
+ {
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ dblValues = xChartDataArray->getData();
+ return (_valindex < dblValues[_seriesindex].getLength() );
+ }
+ return false;
+}
+
+sal_Int32
+ScVbaChart::getSeriesIndex(rtl::OUString _sseriesname) throw ( script::BasicErrorException )
+{
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ if (getPlotBy() == xlRows)
+ return ContainerUtilities::FieldInList(xChartDataArray->getRowDescriptions(), _sseriesname);
+ return ContainerUtilities::FieldInList(xChartDataArray->getColumnDescriptions(), _sseriesname);
+}
+void
+ScVbaChart::setSeriesName(sal_Int32 _index, rtl::OUString _sname) throw ( script::BasicErrorException )
+{
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ if (isSeriesIndexValid(_index))
+ {
+ uno::Sequence< rtl::OUString > sDescriptions = xChartDataArray->getColumnDescriptions();
+ sDescriptions[_index] = _sname;
+ xChartDataArray->setColumnDescriptions(sDescriptions);
+ }
+}
+
+sal_Int32
+ScVbaChart::getSeriesCount() throw ( script::BasicErrorException )
+{
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+
+ if (getPlotBy() == xlRows)
+ return xChartDataArray->getRowDescriptions().getLength();
+ return xChartDataArray->getColumnDescriptions().getLength();
+
+}
+
+rtl::OUString
+ScVbaChart::getSeriesName(sal_Int32 _index) throw ( script::BasicErrorException )
+{
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ uno::Sequence< rtl::OUString > sDescriptions;
+ rtl::OUString sName;
+ if (isSeriesIndexValid(_index))
+ {
+ if (getPlotBy() == xlRows)
+ sDescriptions = xChartDataArray->getRowDescriptions();
+ else
+ sDescriptions = xChartDataArray->getColumnDescriptions();
+ sName = sDescriptions[_index];
+ }
+ return sName;
+}
+
+double
+ScVbaChart::getValue(sal_Int32 _seriesindex, sal_Int32 _valindex) throw ( script::BasicErrorException )
+{
+ double result = -1.0;
+ if (areIndicesValid(_seriesindex, _valindex))
+ {
+ if (getPlotBy() == xlRows)
+ result = dblValues[_seriesindex][_valindex];
+ else
+ result = dblValues[_valindex][_seriesindex];
+ }
+ return result;
+}
+
+sal_Int32
+ScVbaChart::getValuesCount(sal_Int32 _seriesIndex) throw ( script::BasicErrorException )
+{
+ sal_Int32 nCount = 0;
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ if (isSeriesIndexValid(_seriesIndex))
+ {
+ dblValues = xChartDataArray->getData();
+ if (getPlotBy() == xlRows)
+ nCount = dblValues[_seriesIndex].getLength();
+ else
+ nCount = dblValues.getLength();
+ }
+ return nCount;
+}
+
+
+uno::Reference< excel::XDataLabels >
+ScVbaChart::DataLabels( const uno::Reference< ov::excel::XSeries > /*_oSeries*/ ) throw ( css::script::BasicErrorException )
+{
+ if ( true )
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ // #TODO #FIXE provide implementation
+ return uno::Reference< excel::XDataLabels > ();
+}
+
+bool
+ScVbaChart::getHasDataCaption( const uno::Reference< css::beans::XPropertySet >& _xPropertySet )throw ( script::BasicErrorException )
+{
+ bool bResult = false;
+ try
+ {
+ sal_Int32 nChartDataCaption = 0;
+ _xPropertySet->getPropertyValue(DATACAPTION) >>= nChartDataCaption;
+ bResult = (nChartDataCaption != chart::ChartDataCaption::NONE);
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return bResult;
+}
+
+void
+ScVbaChart::setHasDataCaption( const uno::Reference< beans::XPropertySet >& _xPropertySet, bool _bHasDataLabels )throw ( script::BasicErrorException )
+{
+ try
+ {
+ if ( _bHasDataLabels )
+ _xPropertySet->setPropertyValue(DATACAPTION, uno::makeAny ( chart::ChartDataCaption::VALUE) );
+ else
+ _xPropertySet->setPropertyValue(DATACAPTION, uno::makeAny ( chart::ChartDataCaption::NONE) );
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+uno::Reference< beans::XPropertySet >
+ScVbaChart::getAxisPropertySet(sal_Int32 _nAxisType, sal_Int32 _nAxisGroup) throw ( script::BasicErrorException )
+{
+ assignDiagramAttributes();
+ uno::Reference< beans::XPropertySet > xAxisProps;
+ switch(_nAxisType)
+ {
+ case xlCategory:
+ if (_nAxisGroup == xlPrimary)
+ {
+ xAxisProps = xAxisXSupplier->getXAxis();
+ }
+ else if (_nAxisGroup == xlSecondary)
+ {
+ xAxisProps = xTwoAxisXSupplier->getSecondaryXAxis();
+ }
+ break;
+ case xlSeriesAxis:
+// if (_nAxisGroup == xlPrimary){
+ xAxisProps = xAxisZSupplier->getZAxis();
+ break;
+// }
+// else if (_nAxisGroup == xlSecondary){
+ // return xTwoAxisXSupplier.getSecondaryZAxis();
+ // }
+ case xlValue:
+ if (_nAxisGroup == xlPrimary)
+ xAxisProps = xAxisYSupplier->getYAxis();
+ else if (_nAxisGroup == xlSecondary)
+ xAxisProps = xTwoAxisYSupplier->getSecondaryYAxis();
+ break;
+ default:
+ return xAxisProps;
+ }
+ return xAxisProps;
+}
+
+
+rtl::OUString&
+ScVbaChart::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaChart") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaChart::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Chart" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbachart.hxx b/sc/source/ui/vba/vbachart.hxx
new file mode 100644
index 000000000000..d0b53c34421f
--- /dev/null
+++ b/sc/source/ui/vba/vbachart.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_CHART_HXX
+#define SC_VBA_CHART_HXX
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XAxisXSupplier.hpp>
+#include <com/sun/star/chart/XAxisYSupplier.hpp>
+#include <com/sun/star/chart/XAxisZSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
+#include <ooo/vba/excel/XChart.hpp>
+#include <ooo/vba/excel/XDataLabels.hpp>
+#include <ooo/vba/excel/XSeries.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1<ov::excel::XChart > ChartImpl_BASE;
+
+class ScVbaChart : public ChartImpl_BASE
+{
+friend class ScVbaAxis;
+
+ css::uno::Reference< css::chart::XChartDocument > mxChartDocument;
+ css::uno::Reference< css::table::XTableChart > mxTableChart;
+ css::uno::Reference< css::beans::XPropertySet > mxDiagramPropertySet;
+ css::uno::Reference< css::beans::XPropertySet > mxChartPropertySet;
+ css::uno::Reference< css::chart::XAxisXSupplier > xAxisXSupplier;
+ css::uno::Reference< css::chart::XAxisYSupplier> xAxisYSupplier;
+ css::uno::Reference< css::chart::XAxisZSupplier > xAxisZSupplier;
+ css::uno::Reference< css::chart::XTwoAxisXSupplier > xTwoAxisXSupplier;
+ css::uno::Reference< css::chart::XTwoAxisYSupplier > xTwoAxisYSupplier;
+
+ css::uno::Sequence< rtl::OUString > getDefaultSeriesDescriptions( sal_Int32 nCount );
+ css::uno::Sequence< css::uno::Sequence< double > > dblValues;
+ void setDefaultChartType()throw ( css::script::BasicErrorException ) ;
+ void setDiagram( const rtl::OUString& _sDiagramType) throw( css::script::BasicErrorException );
+ bool isStacked() throw ( css::uno::RuntimeException );
+ bool is100PercentStacked() throw ( css::uno::RuntimeException );
+ sal_Int32 getStackedType( sal_Int32 _nStacked, sal_Int32 _n100PercentStacked, sal_Int32 _nUnStacked ) throw ( css::uno::RuntimeException );
+ sal_Int32 getSolidType(sal_Int32 _nDeep, sal_Int32 _nVertiStacked, sal_Int32 _nVerti100PercentStacked, sal_Int32 _nVertiUnStacked, sal_Int32 _nHoriStacked, sal_Int32 _nHori100PercentStacked, sal_Int32 _nHoriUnStacked) throw ( css::script::BasicErrorException );
+ sal_Int32 getStockUpDownValue(sal_Int32 _nUpDown, sal_Int32 _nNotUpDown) throw (css::script::BasicErrorException);
+ bool hasMarkers() throw ( css::script::BasicErrorException );
+ sal_Int32 getMarkerType(sal_Int32 _nWithMarkers, sal_Int32 _nWithoutMarkers) throw ( css::script::BasicErrorException );
+ void assignDiagramAttributes();
+ void setDefaultSeriesDescriptionLabels(){}
+public:
+ ScVbaChart( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::lang::XComponent >& _xChartComponent, const css::uno::Reference< css::table::XTableChart >& _xTableChart );
+
+ // Non-interface
+ css::uno::Reference< css::beans::XPropertySet > xDiagramPropertySet() { return mxDiagramPropertySet; }
+ bool isSeriesIndexValid(sal_Int32 _seriesindex) throw( css::script::BasicErrorException );
+ bool areIndicesValid(sal_Int32 _seriesindex, sal_Int32 _valindex) throw ( css::script::BasicErrorException );
+ void setSeriesName(sal_Int32 _index, rtl::OUString _sname) throw ( css::script::BasicErrorException );
+ sal_Int32 getSeriesIndex(rtl::OUString _sseriesname) throw ( css::script::BasicErrorException );
+ sal_Int32 getSeriesCount() throw ( css::script::BasicErrorException );
+ rtl::OUString getSeriesName(sal_Int32 _index) throw ( css::script::BasicErrorException );
+ double getValue(sal_Int32 _seriesIndex, sal_Int32 _valindex) throw ( css::script::BasicErrorException );
+ sal_Int32 getValuesCount(sal_Int32 _seriesIndex) throw ( css::script::BasicErrorException );
+ css::uno::Reference< ov::excel::XDataLabels > DataLabels( const css::uno::Reference< ov::excel::XSeries > _oSeries ) throw ( css::script::BasicErrorException );
+ bool getHasDataCaption( const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet )throw ( css::script::BasicErrorException );
+ void setHasDataCaption( const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, bool _bHasDataLabels )throw ( css::script::BasicErrorException );
+ bool is3D() throw ( css::uno::RuntimeException );
+ css::uno::Reference< css::beans::XPropertySet > getAxisPropertySet(sal_Int32 _nAxisType, sal_Int32 _nAxisGroup) throw ( css::script::BasicErrorException );
+ // Methods
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL SeriesCollection(const css::uno::Any&) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getChartType() throw ( css::uno::RuntimeException, css::script::BasicErrorException);
+ virtual void SAL_CALL setChartType( ::sal_Int32 _charttype ) throw ( css::uno::RuntimeException, css::script::BasicErrorException);
+ virtual void SAL_CALL Activate( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setSourceData( const css::uno::Reference< ::ooo::vba::excel::XRange >& range, const css::uno::Any& PlotBy ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL Location( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getLocation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setLocation( ::sal_Int32 where, const css::uno::Any& Name ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getHasTitle( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setHasTitle( ::sal_Bool bTitle ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getHasLegend( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setHasLegend( ::sal_Bool bLegend ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setPlotBy( ::sal_Int32 xlRowCol ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getPlotBy( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XChartTitle > SAL_CALL getChartTitle( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Axes( const css::uno::Any& Type, const css::uno::Any& AxisGroup ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+};
+
+#endif //SC_VBA_WINDOW_HXX
diff --git a/sc/source/ui/vba/vbachartobject.cxx b/sc/source/ui/vba/vbachartobject.cxx
new file mode 100644
index 000000000000..617a090b6d7a
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobject.cxx
@@ -0,0 +1,210 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbachart.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <basic/sberrors.hxx>
+#include "vbachartobject.hxx"
+#include "vbachartobjects.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+const rtl::OUString CHART_NAME( RTL_CONSTASCII_USTRINGPARAM("Name") );
+const rtl::OUString PERSIST_NAME( RTL_CONSTASCII_USTRINGPARAM("PersistName") );
+
+ScVbaChartObject::ScVbaChartObject( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableChart >& _xTableChart, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier ) : ChartObjectImpl_BASE( _xParent, _xContext ), xTableChart( _xTableChart ), xDrawPageSupplier( _xDrawPageSupplier )
+{
+ xDrawPage = xDrawPageSupplier->getDrawPage();
+ xEmbeddedObjectSupplier.set( xTableChart, uno::UNO_QUERY_THROW );
+ xNamed.set( xTableChart, uno::UNO_QUERY_THROW );
+ sPersistName = getPersistName();
+ xShape = setShape();
+ setName(sPersistName);
+ oShapeHelper.reset(new ShapeHelper(xShape));
+}
+
+rtl::OUString ScVbaChartObject::getPersistName()
+{
+ if ( !sPersistName.getLength() )
+ sPersistName = xNamed->getName();
+ return sPersistName;
+}
+
+uno::Reference< drawing::XShape >
+ScVbaChartObject::setShape() throw ( script::BasicErrorException )
+{
+ try
+ {
+ sal_Int32 nItems = xDrawPage->getCount();
+ for (int i = 0; i < nItems; i++)
+ {
+ xShape.set( xDrawPage->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (xShape->getShapeType().compareToAscii("com.sun.star.drawing.OLE2Shape") == 0 )
+ {
+ uno::Reference< beans::XPropertySet > xShapePropertySet(xShape, uno::UNO_QUERY_THROW );
+ rtl::OUString sName;
+ xShapePropertySet->getPropertyValue(PERSIST_NAME ) >>=sName;
+ if ( sName.equals(sPersistName))
+ {
+ xNamedShape.set( xShape, uno::UNO_QUERY_THROW );
+ return xShape;
+ }
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return NULL;
+}
+
+void SAL_CALL
+ScVbaChartObject::setName( const rtl::OUString& sName ) throw (css::uno::RuntimeException)
+{
+ xNamedShape->setName(sName);
+}
+
+
+::rtl::OUString SAL_CALL
+ScVbaChartObject::getName() throw (css::uno::RuntimeException)
+{
+ return xNamedShape->getName();
+}
+
+void SAL_CALL
+ScVbaChartObject::Delete() throw ( css::script::BasicErrorException )
+{
+ // parent of this object is sheet
+ uno::Reference< excel::XWorksheet > xParent( getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XChartObjects > xColl( xParent->ChartObjects( uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaChartObjects* pChartObjectsImpl = static_cast< ScVbaChartObjects* >( xColl.get() );
+ if (pChartObjectsImpl)
+ pChartObjectsImpl->removeByName( getPersistName() );
+ else
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent is not ChartObjects" ) ) );
+}
+
+void
+ScVbaChartObject::Activate() throw ( script::BasicErrorException )
+{
+ try
+ {
+ // #TODO #FIXME should be ThisWorkbook or equivelant, or in
+ // fact probably the chart object should be created with
+ // the XModel owner
+ //uno::Reference< view::XSelectionSupplier > xSelectionSupplier( getXModel().getCurrentController());
+ uno::Reference< view::XSelectionSupplier > xSelectionSupplier( getCurrentExcelDoc(mxContext)->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelectionSupplier->select(uno::makeAny(xShape));
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChartObject Activate internal error" ) ) );
+ }
+}
+
+uno::Reference< excel::XChart > SAL_CALL
+ScVbaChartObject::getChart() throw (css::uno::RuntimeException)
+{
+ return new ScVbaChart( this, mxContext, xEmbeddedObjectSupplier->getEmbeddedObject(), xTableChart );
+}
+
+rtl::OUString&
+ScVbaChartObject::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaChartObject") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaChartObject::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.ChartObject" ) );
+ }
+ return aServiceNames;
+}
+
+double
+ScVbaChartObject::getHeight()
+{
+ return oShapeHelper->getHeight();
+}
+
+void
+ScVbaChartObject::setHeight(double _fheight) throw ( script::BasicErrorException )
+{
+ oShapeHelper->setHeight(_fheight);
+}
+
+double
+ScVbaChartObject::getWidth()
+{
+ return oShapeHelper->getWidth();
+}
+
+void
+ScVbaChartObject::setWidth(double _fWidth) throw ( script::BasicErrorException )
+{
+ oShapeHelper->setWidth(_fWidth);
+}
+
+double
+ScVbaChartObject::getLeft()
+{
+ return oShapeHelper->getLeft();
+}
+
+void
+ScVbaChartObject::setLeft(double _fLeft)
+{
+ oShapeHelper->setLeft(_fLeft);
+}
+
+double
+ScVbaChartObject::getTop()
+{
+ return oShapeHelper->getTop();
+}
+
+void
+ScVbaChartObject::setTop(double _fTop)
+{
+ oShapeHelper->setTop(_fTop);
+}
+
+uno::Reference< uno::XInterface >
+ScVbaChartObject::getUnoObject() throw (script::BasicErrorException)
+{
+ return uno::Reference< uno::XInterface >( xShape, uno::UNO_QUERY );
+}
diff --git a/sc/source/ui/vba/vbachartobject.hxx b/sc/source/ui/vba/vbachartobject.hxx
new file mode 100644
index 000000000000..3c1e224728ee
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobject.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_CHARTOBJECT_HXX
+#define SC_VBA_CHARTOBJECT_HXX
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <ooo/vba/excel/XChartObject.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <memory>
+
+typedef InheritedHelperInterfaceImpl1<ov::excel::XChartObject > ChartObjectImpl_BASE;
+
+class ScVbaChartObject : public ChartObjectImpl_BASE
+{
+
+ css::uno::Reference< css::table::XTableChart > xTableChart;
+ css::uno::Reference< css::document::XEmbeddedObjectSupplier > xEmbeddedObjectSupplier;
+ css::uno::Reference< css::beans::XPropertySet > xPropertySet;
+ css::uno::Reference< css::drawing::XDrawPageSupplier > xDrawPageSupplier;
+ css::uno::Reference< css::drawing::XDrawPage > xDrawPage;
+ css::uno::Reference< css::drawing::XShape > xShape;
+ css::uno::Reference< css::container::XNamed > xNamed;
+ rtl::OUString sPersistName;
+ std::auto_ptr<ov::ShapeHelper> oShapeHelper;
+ css::uno::Reference< css::container::XNamed > xNamedShape;
+ rtl::OUString getPersistName();
+ css::uno::Reference< css::drawing::XShape > setShape() throw ( css::script::BasicErrorException );
+public:
+ ScVbaChartObject( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableChart >& _xTableChart, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier );
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& sName ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XChart > SAL_CALL getChart() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Delete() throw ( css::script::BasicErrorException );
+ virtual void Activate() throw ( css::script::BasicErrorException );
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+ // non interface methods
+ double getHeight();
+ void setHeight( double _fheight ) throw ( css::script::BasicErrorException );
+ double getWidth();
+ void setWidth( double _fwidth ) throw ( css::script::BasicErrorException );
+ double getLeft();
+ void setLeft( double _fleft );
+ double getTop();
+ void setTop( double _ftop );
+ // should make this part of the XHelperInterface with a default
+ // implementation returning NULL
+ css::uno::Reference< css::uno::XInterface > getUnoObject() throw ( css::script::BasicErrorException );
+};
+
+#endif //SC_VBA_WINDOW_HXX
diff --git a/sc/source/ui/vba/vbachartobjects.cxx b/sc/source/ui/vba/vbachartobjects.cxx
new file mode 100644
index 000000000000..5117cfd75858
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobjects.cxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbachart.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <com/sun/star/table/XTableChartsSupplier.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <ooo/vba/excel/XlChartType.hpp>
+
+
+#include "vbachartobjects.hxx"
+#include "vbachartobject.hxx"
+#include "vbaglobals.hxx"
+#include "cellsuno.hxx"
+#include <vector>
+#include <basic/sberrors.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+
+class ChartObjectEnumerationImpl : public EnumerationHelperImpl
+{
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier;
+
+public:
+
+ ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( _xParent, xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ) {}
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ uno::Reference< table::XTableChart > xTableChart( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ // parent Object is sheet
+ return uno::makeAny( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( m_xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) );
+ }
+};
+
+
+ScVbaChartObjects::ScVbaChartObjects( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableCharts >& _xTableCharts, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier ) : ChartObjects_BASE(_xParent, _xContext, css::uno::Reference< css::container::XIndexAccess >( _xTableCharts, css::uno::UNO_QUERY ) ), xTableCharts( _xTableCharts ) , xDrawPageSupplier( _xDrawPageSupplier )
+{
+
+}
+
+void
+ScVbaChartObjects::removeByName(const rtl::OUString& _sChartName)
+{
+ xTableCharts->removeByName( _sChartName );
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaChartObjects::getChartObjectNames() throw( css::script::BasicErrorException )
+{
+ uno::Sequence< rtl::OUString > sChartNames;
+ try
+ {
+ // c++ hackery
+ uno::Reference< uno::XInterface > xIf( xDrawPageSupplier, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUno= dynamic_cast< ScCellRangesBase* >( xIf.get() );
+ ScDocShell* pDocShell = NULL;
+ if ( !pUno )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("Failed to obtain the impl class from the drawpage"), uno::Reference< uno::XInterface >() );
+ pDocShell = pUno->GetDocShell();
+ if ( !pDocShell )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("Failed to obtain the docshell implclass"), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< sheet::XSpreadsheetDocument > xSpreadsheetDocument( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets = xSpreadsheetDocument->getSheets();
+ std::vector< rtl::OUString > aChartNamesVector;
+
+ uno::Sequence< rtl::OUString > sSheetNames = xSpreadsheets->getElementNames();
+ sal_Int32 nItems = sSheetNames.getLength();
+ for (sal_Int32 i = 0; i < nItems; i++)
+ {
+ uno::Reference< table::XTableChartsSupplier > xLocTableChartsSupplier( xSpreadsheets->getByName(sSheetNames[i]), uno::UNO_QUERY_THROW );
+ uno::Sequence< rtl::OUString > scurchartnames = xLocTableChartsSupplier->getCharts()->getElementNames();
+ sal_Int32 nChartNames = scurchartnames.getLength();
+ for (sal_Int32 n = 0; n < nChartNames; n++ )
+ aChartNamesVector.push_back(scurchartnames[n]);
+ }
+ sChartNames.realloc( aChartNamesVector.size() );
+ std::vector< rtl::OUString > ::const_iterator it = aChartNamesVector.begin();
+ std::vector< rtl::OUString > ::const_iterator it_end = aChartNamesVector.end();
+ for ( sal_Int32 index = 0 ; it != it_end; ++it, ++index )
+ sChartNames[index] = *it;
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return sChartNames;
+}
+
+// XChartObjects
+uno::Any SAL_CALL
+ScVbaChartObjects::Add( double _nX, double _nY, double _nWidth, double _nHeight ) throw (script::BasicErrorException)
+{
+ try
+ {
+ uno::Sequence< table::CellRangeAddress > aCellRangeAddress( 1 );
+ awt::Rectangle aRectangle;
+ aRectangle.X = Millimeter::getInHundredthsOfOneMillimeter(_nX);
+ aRectangle.Y = Millimeter::getInHundredthsOfOneMillimeter(_nY);
+ aRectangle.Width = Millimeter::getInHundredthsOfOneMillimeter(_nWidth);
+ aRectangle.Height = Millimeter::getInHundredthsOfOneMillimeter(_nHeight);
+ // Note the space at the end of the stem ("Chart "). In ChartSheets only "Chart" is the stem
+ rtl::OUString sPersistChartName = ContainerUtilities::getUniqueName( getChartObjectNames(), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Chart " ) ) , rtl::OUString(), 1);
+ xTableCharts->addNewByName(sPersistChartName, aRectangle, aCellRangeAddress, true, false );
+ uno::Reference< excel::XChartObject > xChartObject( getItemByStringIndex( sPersistChartName ), uno::UNO_QUERY_THROW );
+ xChartObject->getChart()->setChartType(excel::XlChartType::xlColumnClustered);
+ return uno::makeAny( xChartObject );
+ }
+ catch ( uno::Exception& ex)
+ {
+ OSL_TRACE("AddItem caught exception ->%s", rtl::OUStringToOString( ex.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ return aNULL();
+}
+void SAL_CALL ScVbaChartObjects::Delete( ) throw (script::BasicErrorException)
+{
+ uno::Sequence< rtl::OUString > sChartNames = xTableCharts->getElementNames();
+ sal_Int32 ncount = sChartNames.getLength();
+ for (sal_Int32 i = 0; i < ncount ; i++)
+ removeByName(sChartNames[i]);
+}
+
+// XEnumerationAccess
+
+uno::Reference< container::XEnumeration >
+ScVbaChartObjects::createEnumeration() throw (uno::RuntimeException)
+{
+ css::uno::Reference< container::XEnumerationAccess > xEnumAccess( xTableCharts, uno::UNO_QUERY_THROW );
+ return new ChartObjectEnumerationImpl( mxContext, xEnumAccess->createEnumeration(), xDrawPageSupplier, getParent() /* sheet */);
+}
+
+// XElementAccess
+
+uno::Type
+ScVbaChartObjects::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XChartObject::static_type(0);
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any
+ScVbaChartObjects::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< table::XTableChart > xTableChart( aSource, uno::UNO_QUERY_THROW );
+ // correct parent object is sheet
+ return uno::makeAny( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( getParent(), mxContext, xTableChart, xDrawPageSupplier ) ) );
+}
+
+rtl::OUString&
+ScVbaChartObjects::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaChartObjects") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaChartObjects::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.ChartObjects") );
+ }
+ return sNames;
+}
+
diff --git a/sc/source/ui/vba/vbachartobjects.hxx b/sc/source/ui/vba/vbachartobjects.hxx
new file mode 100644
index 000000000000..80ea038bb15d
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobjects.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_CHARTOBJECTS_HXX
+#define SC_VBA_CHARTOBJECTS_HXX
+#include <ooo/vba/excel/XChartObjects.hpp>
+#include <ooo/vba/excel/XChartObject.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XTableCharts.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+#include "excelvbahelper.hxx"
+#include <hash_map>
+
+typedef CollTestImplHelper< ov::excel::XChartObjects > ChartObjects_BASE;
+/* #TODO see if this hash table is 'really' necessary
+typedef ::std::hash_map< ::rtl::OUString,
+css::uno::Reference< ov::excel::XChartObject >,
+ ::rtl::OUStringHash,
+ ::std::equal_to< ::rtl::OUString > > aHashTable;
+*/
+
+class ScVbaChartObjects : public ChartObjects_BASE
+{
+
+ css::uno::Reference< css::table::XTableCharts > xTableCharts;
+ css::uno::Reference< css::drawing::XDrawPageSupplier > xDrawPageSupplier;
+ // method associated with populating the hashmap ( I'm not convinced this is necessary )
+ //css::uno::Reference< ov::excel::XChartObject > putByPersistName( const rtl:::OUString& _sPersistChartName );
+public:
+ ScVbaChartObjects( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableCharts >& _xTableCharts, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier );
+
+ css::uno::Sequence< rtl::OUString > getChartObjectNames() throw( css::script::BasicErrorException );
+ void removeByName(const rtl::OUString& _sChartName);
+
+ // XChartObjects
+ virtual ::com::sun::star::uno::Any SAL_CALL Add( double Left, double Top, double Width, double Height ) throw (::com::sun::star::script::BasicErrorException);
+ virtual void SAL_CALL Delete( ) throw (::com::sun::star::script::BasicErrorException);
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+ // ChartObjects_BASE
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_WINDOW_HXX
diff --git a/sc/source/ui/vba/vbacharts.cxx b/sc/source/ui/vba/vbacharts.cxx
new file mode 100644
index 000000000000..da0c7789134b
--- /dev/null
+++ b/sc/source/ui/vba/vbacharts.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbacharts.hxx"
+#include <basic/sberrors.hxx>
+#include <com/sun/star/table/XTableChartsSupplier.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+
+ScVbaCharts::ScVbaCharts( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const uno::Reference< frame::XModel >& xModel ) : Charts_BASE(_xParent, _xContext, uno::Reference< container::XIndexAccess >())
+{
+ xComponent.set( xModel, uno::UNO_QUERY_THROW );
+ xSpreadsheetDocument.set( xComponent, uno::UNO_QUERY_THROW );
+}
+
+uno::Any SAL_CALL
+ScVbaCharts::Add() throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ // Not implemented in the helperapi ( see ChartsImpl.java )
+ if ( true )
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_BAD_METHOD, rtl::OUString() );
+ return aNULL();
+}
+
+uno::Reference< excel::XChart > SAL_CALL
+ScVbaCharts::getActiveChart() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return xActiveChart;
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaCharts::createEnumeration() throw (uno::RuntimeException)
+{
+ // #FIXME not implemented
+ if ( true )
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_BAD_METHOD, rtl::OUString() );
+ return uno::Reference< container::XEnumeration >();
+}
+
+// #FIXME #TODO this method shouldn't appear in this class directly
+// a XIndexAccess/XNameAccess wrapper should be passed to the base class instead
+::sal_Int32 SAL_CALL
+ScVbaCharts::getCount() throw (uno::RuntimeException)
+{
+ sal_Int32 ncount = 0;
+ try
+ {
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets( xSpreadsheetDocument->getSheets() );
+ uno::Sequence< rtl::OUString > SheetNames = xSpreadsheets->getElementNames();
+ sal_Int32 nLen = SheetNames.getLength();
+ for (sal_Int32 i = 0; i < nLen; i++)
+ {
+ uno::Reference< table::XTableChartsSupplier > xTableChartsSupplier( xSpreadsheets->getByName(SheetNames[i]), uno::UNO_QUERY);
+ if ( xTableChartsSupplier.is() )
+ {
+ uno::Reference< table::XTableCharts > xTableCharts = xTableChartsSupplier->getCharts();
+ ncount =+ xTableCharts->getElementNames().getLength();
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return ncount;
+}
+
+uno::Any
+ScVbaCharts::createCollectionObject( const uno::Any& aSource )
+{
+ if ( true )
+ throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_BAD_METHOD, rtl::OUString() );
+ // #TODO implementation please
+ return aSource;
+}
+
+rtl::OUString&
+ScVbaCharts::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaCharts") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaCharts::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Charts") );
+ }
+ return sNames;
+}
+
diff --git a/sc/source/ui/vba/vbacharts.hxx b/sc/source/ui/vba/vbacharts.hxx
new file mode 100644
index 000000000000..b2ecfe23270f
--- /dev/null
+++ b/sc/source/ui/vba/vbacharts.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_CHARTS_HXX
+#define SC_VBA_CHARTS_HXX
+#include <ooo/vba/excel/XCharts.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+#include "excelvbahelper.hxx"
+#include <hash_map>
+
+typedef CollTestImplHelper< ov::excel::XCharts > Charts_BASE;
+
+class ScVbaCharts : public Charts_BASE
+{
+ css::uno::Reference< ov::excel::XChart > xActiveChart;
+ css::uno::Reference< css::sheet::XSpreadsheetDocument > xSpreadsheetDocument;
+ css::uno::Reference< css::lang::XComponent > xComponent;
+public:
+ ScVbaCharts( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+ // XCharts
+ virtual css::uno::Any SAL_CALL Add() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XChart > SAL_CALL getActiveChart( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XCollection
+ ::sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException);
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException) { return ov::excel::XChart::static_type(0); }
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+ // Charts_BASE or HelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif
diff --git a/sc/source/ui/vba/vbacharttitle.cxx b/sc/source/ui/vba/vbacharttitle.cxx
new file mode 100644
index 000000000000..e797c4a0269e
--- /dev/null
+++ b/sc/source/ui/vba/vbacharttitle.cxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbacharttitle.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaChartTitle::ScVbaChartTitle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& _xTitleShape ) : ChartTitleBase( xParent, xContext, _xTitleShape )
+{
+}
+
+rtl::OUString&
+ScVbaChartTitle::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaChartTitle") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaChartTitle::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ uno::Sequence< rtl::OUString > BaseServiceNames = ChartTitleBase::getServiceNames();
+ aServiceNames.realloc( BaseServiceNames.getLength() + 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Chart" ) );
+ for ( sal_Int32 index = 1; index < (BaseServiceNames.getLength() + 1); ++index )
+ aServiceNames[ index ] = BaseServiceNames[ index ];
+ }
+ return aServiceNames;
+}
+
+
diff --git a/sc/source/ui/vba/vbacharttitle.hxx b/sc/source/ui/vba/vbacharttitle.hxx
new file mode 100644
index 000000000000..4d6ed34a86b6
--- /dev/null
+++ b/sc/source/ui/vba/vbacharttitle.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_VBA_CHARTTITLE_HXX
+#define SC_VBA_CHARTTITLE_HXX
+#include "vbatitle.hxx"
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XChartTitle.hpp>
+
+
+typedef TitleImpl< cppu::WeakImplHelper1< ov::excel::XChartTitle > > ChartTitleBase;
+
+class ScVbaChartTitle : public ChartTitleBase
+{
+public:
+ ScVbaChartTitle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& _xTitleShape );
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
diff --git a/sc/source/ui/vba/vbacomment.cxx b/sc/source/ui/vba/vbacomment.cxx
new file mode 100644
index 000000000000..9c50a25b8b7c
--- /dev/null
+++ b/sc/source/ui/vba/vbacomment.cxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbacomment.hxx"
+
+#include <ooo/vba/excel/XlCreator.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XText.hpp>
+
+#include <vbahelper/vbashape.hxx>
+#include "vbaglobals.hxx"
+#include "vbacomments.hxx"
+
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaComment::ScVbaComment(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) :
+ ScVbaComment_BASE( xParent, xContext ),
+ mxModel( xModel, uno::UNO_SET_THROW ),
+ mxRange( xRange )
+{
+ if ( !xRange.is() )
+ throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 );
+ uno::Reference< text::XSimpleText > xAnnoText( getAnnotation(), uno::UNO_QUERY );
+}
+
+// private helper functions
+
+uno::Reference< sheet::XSheetAnnotation > SAL_CALL
+ScVbaComment::getAnnotation() throw (uno::RuntimeException)
+{
+ uno::Reference< table::XCell > xCell( mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetAnnotationAnchor > xAnnoAnchor( xCell, uno::UNO_QUERY_THROW );
+ return uno::Reference< sheet::XSheetAnnotation > ( xAnnoAnchor->getAnnotation(), uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< sheet::XSheetAnnotations > SAL_CALL
+ScVbaComment::getAnnotations() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(mxRange, ::uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
+ uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW );
+
+ return uno::Reference< sheet::XSheetAnnotations > ( xAnnosSupp->getAnnotations(), uno::UNO_QUERY_THROW );
+}
+
+sal_Int32 SAL_CALL
+ScVbaComment::getAnnotationIndex() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetAnnotations > xAnnos = getAnnotations();
+ table::CellAddress aAddress = getAnnotation()->getPosition();
+
+ sal_Int32 aIndex = 0;
+ sal_Int32 aCount = xAnnos->getCount();
+
+ for ( ; aIndex < aCount ; aIndex++ )
+ {
+ uno::Reference< sheet::XSheetAnnotation > xAnno( xAnnos->getByIndex( aIndex ), uno::UNO_QUERY_THROW );
+ table::CellAddress xAddress = xAnno->getPosition();
+
+ if ( xAddress.Column == aAddress.Column && xAddress.Row == aAddress.Row && xAddress.Sheet == aAddress.Sheet )
+ {
+ OSL_TRACE("** terminating search, index is %d", aIndex );
+ break;
+ }
+ }
+ OSL_TRACE("** returning index is %d", aIndex );
+
+ return aIndex;
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaComment::getCommentByIndex( sal_Int32 Index ) throw (uno::RuntimeException)
+{
+ uno::Reference< container::XIndexAccess > xIndexAccess( getAnnotations(), uno::UNO_QUERY_THROW );
+ // parent is sheet ( parent of the range which is the parent of the comment )
+ uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, mxModel, xIndexAccess ) );
+
+ return uno::Reference< excel::XComment > ( xColl->Item( uno::makeAny( Index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ }
+
+// public vba functions
+
+rtl::OUString SAL_CALL
+ScVbaComment::getAuthor() throw (uno::RuntimeException)
+{
+ return getAnnotation()->getAuthor();
+}
+
+void SAL_CALL
+ScVbaComment::setAuthor( const rtl::OUString& /*_author*/ ) throw (uno::RuntimeException)
+{
+ // #TODO #FIXME implementation needed
+}
+
+uno::Reference< msforms::XShape > SAL_CALL
+ScVbaComment::getShape() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetAnnotationShapeSupplier > xAnnoShapeSupp( getAnnotation(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShapes > xShapes( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW );
+ return new ScVbaShape( this, mxContext, xAnnoShape, xShapes, mxModel, office::MsoShapeType::msoComment );
+}
+
+sal_Bool SAL_CALL
+ScVbaComment::getVisible() throw (uno::RuntimeException)
+{
+ return getAnnotation()->getIsVisible();
+}
+
+void SAL_CALL
+ScVbaComment::setVisible( sal_Bool _visible ) throw (uno::RuntimeException)
+{
+ getAnnotation()->setIsVisible( _visible );
+}
+
+void SAL_CALL
+ScVbaComment::Delete() throw (uno::RuntimeException)
+{
+ getAnnotations()->removeByIndex( getAnnotationIndex() );
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaComment::Next() throw (uno::RuntimeException)
+{
+ // index: uno = 0, vba = 1
+ return getCommentByIndex( getAnnotationIndex() + 2 );
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaComment::Previous() throw (uno::RuntimeException)
+{
+ // index: uno = 0, vba = 1
+ return getCommentByIndex( getAnnotationIndex() );
+}
+
+rtl::OUString SAL_CALL
+ScVbaComment::Text( const uno::Any& aText, const uno::Any& aStart, const uno::Any& Overwrite ) throw (uno::RuntimeException)
+{
+ rtl::OUString sText;
+ aText >>= sText;
+
+ uno::Reference< text::XSimpleText > xAnnoText( getAnnotation(), uno::UNO_QUERY_THROW );
+ rtl::OUString sAnnoText = xAnnoText->getString();
+
+ if ( aStart.hasValue() )
+ {
+ sal_Int16 nStart = 0;
+ sal_Bool bOverwrite = sal_True;
+ Overwrite >>= bOverwrite;
+
+ if ( aStart >>= nStart )
+ {
+ uno::Reference< text::XTextCursor > xTextCursor( xAnnoText->createTextCursor(), uno::UNO_QUERY_THROW );
+
+ if ( bOverwrite )
+ {
+ xTextCursor->collapseToStart();
+ xTextCursor->gotoStart( sal_False );
+ xTextCursor->goRight( nStart - 1, sal_False );
+ xTextCursor->gotoEnd( sal_True );
+ }
+ else
+ {
+ xTextCursor->collapseToStart();
+ xTextCursor->gotoStart( sal_False );
+ xTextCursor->goRight( nStart - 1 , sal_True );
+ }
+
+ uno::Reference< text::XTextRange > xRange( xTextCursor, uno::UNO_QUERY_THROW );
+ xAnnoText->insertString( xRange, sText, bOverwrite );
+ return xAnnoText->getString();
+ }
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() );
+ }
+ else if ( aText.hasValue() )
+ {
+ xAnnoText->setString( sText );
+ return sText;
+ }
+
+ return sAnnoText;
+}
+
+rtl::OUString&
+ScVbaComment::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaComment") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaComment::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.ScVbaComment" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbacomment.hxx b/sc/source/ui/vba/vbacomment.hxx
new file mode 100644
index 000000000000..4a7d2fab91ef
--- /dev/null
+++ b/sc/source/ui/vba/vbacomment.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_COMMENT_HXX
+#define SC_VBA_COMMENT_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <ooo/vba/excel/XComment.hpp>
+#include <ooo/vba/excel/XApplication.hpp>
+#include <ooo/vba/msforms/XShape.hpp>
+#include <com/sun/star/sheet/XSheetAnnotations.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XComment > ScVbaComment_BASE;
+
+class ScVbaComment : public ScVbaComment_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::table::XCellRange > mxRange;
+
+private:
+ css::uno::Reference< css::sheet::XSheetAnnotation > SAL_CALL getAnnotation() throw (css::uno::RuntimeException);
+ css::uno::Reference< css::sheet::XSheetAnnotations > SAL_CALL getAnnotations() throw (css::uno::RuntimeException);
+ sal_Int32 SAL_CALL getAnnotationIndex() throw (css::uno::RuntimeException);
+ css::uno::Reference< ov::excel::XComment > SAL_CALL getCommentByIndex( sal_Int32 Index ) throw (css::uno::RuntimeException);
+public:
+ ScVbaComment(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException );
+
+ virtual ~ScVbaComment() {}
+
+ // Attributes
+ virtual rtl::OUString SAL_CALL getAuthor() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAuthor( const rtl::OUString& _author ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVisible( sal_Bool _visible ) throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual void SAL_CALL Delete() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL Next() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL Previous() throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL Text( const css::uno::Any& Text, const css::uno::Any& Start, const css::uno::Any& Overwrite ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif /* SC_VBA_COMMENT_HXX */
+
diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx
new file mode 100644
index 000000000000..7a6d3d774937
--- /dev/null
+++ b/sc/source/ui/vba/vbacomments.cxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbacomments.hxx"
+
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+
+#include "vbaglobals.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< sheet::XSheetAnnotation > xAnno( aSource, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XChild > xChild( xAnno, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( xChild->getParent(), uno::UNO_QUERY_THROW );
+
+ // #FIXME needs to find the correct Parent
+ return uno::makeAny( uno::Reference< excel::XComment > (
+ new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xModel, xCellRange ) ) );
+}
+
+class CommentEnumeration : public EnumerationHelperImpl
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+public:
+ CommentEnumeration(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< container::XEnumeration >& xEnumeration,
+ const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) :
+ EnumerationHelperImpl( xParent, xContext, xEnumeration ),
+ mxModel( xModel, uno::UNO_SET_THROW )
+ {}
+
+ virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext, mxModel );
+ }
+
+};
+
+ScVbaComments::ScVbaComments(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< container::XIndexAccess >& xIndexAccess ) :
+ ScVbaComments_BASE( xParent, xContext, xIndexAccess ),
+ mxModel( xModel, uno::UNO_SET_THROW )
+{
+}
+
+// public helper functions
+
+uno::Reference< container::XEnumeration >
+ScVbaComments::createEnumeration() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new CommentEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+ScVbaComments::createCollectionObject( const css::uno::Any& aSource )
+{
+ return AnnotationToComment( aSource, mxContext, mxModel );
+}
+
+uno::Type
+ScVbaComments::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XComment::static_type(0);
+}
+
+rtl::OUString&
+ScVbaComments::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaComments") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaComments::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Comments") );
+ }
+ return sNames;
+}
diff --git a/sc/source/ui/vba/vbacomments.hxx b/sc/source/ui/vba/vbacomments.hxx
new file mode 100644
index 000000000000..2f98e5b71897
--- /dev/null
+++ b/sc/source/ui/vba/vbacomments.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_COMMENTS_HXX
+#define SC_VBA_COMMENTS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <ooo/vba/excel/XComments.hpp>
+
+#include "excelvbahelper.hxx"
+#include <vbahelper/vbacollectionimpl.hxx>
+#include "vbacomment.hxx"
+
+typedef CollTestImplHelper< ov::excel::XComments > ScVbaComments_BASE;
+
+class ScVbaComments : public ScVbaComments_BASE
+{
+public:
+ ScVbaComments(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext > & xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+
+ virtual ~ScVbaComments() {}
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // ScVbaComments_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+};
+
+#endif /* SC_VBA_COMMENTS_HXX */
+
diff --git a/sc/source/ui/vba/vbacondition.cxx b/sc/source/ui/vba/vbacondition.cxx
new file mode 100644
index 000000000000..590d649ae561
--- /dev/null
+++ b/sc/source/ui/vba/vbacondition.cxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vbacondition.hxx"
+#include <ooo/vba/excel/XlFormatConditionOperator.hpp>
+#include <ooo/vba/excel/XFormatCondition.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int32 ISFORMULA = 98765432;
+
+template< typename Ifc1 >
+ScVbaCondition< Ifc1 >::ScVbaCondition( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetCondition >& _xSheetCondition ) : ScVbaCondition_BASE( xParent, xContext ), mxSheetCondition( _xSheetCondition )
+{
+ mxAddressable.set( xParent, uno::UNO_QUERY_THROW );
+}
+
+template< typename Ifc1 >
+sheet::ConditionOperator
+ScVbaCondition< Ifc1 >::retrieveAPIOperator( const uno::Any& _aOperator) throw ( script::BasicErrorException )
+{
+ sheet::ConditionOperator aRetAPIOperator = sheet::ConditionOperator_NONE;
+ sal_Int32 nOperator = 0;
+ if ( (_aOperator >>= nOperator ) )
+ {
+ switch(nOperator)
+ {
+ case excel::XlFormatConditionOperator::xlBetween:
+ aRetAPIOperator = sheet::ConditionOperator_BETWEEN;
+ break;
+ case excel::XlFormatConditionOperator::xlNotBetween:
+ aRetAPIOperator = sheet::ConditionOperator_NOT_BETWEEN;
+ break;
+ case excel::XlFormatConditionOperator::xlEqual:
+ aRetAPIOperator = sheet::ConditionOperator_EQUAL;
+ break;
+ case excel::XlFormatConditionOperator::xlNotEqual:
+ aRetAPIOperator = sheet::ConditionOperator_NOT_EQUAL;
+ break;
+ case excel::XlFormatConditionOperator::xlGreater:
+ aRetAPIOperator = sheet::ConditionOperator_GREATER;
+ break;
+ case excel::XlFormatConditionOperator::xlLess:
+ aRetAPIOperator = sheet::ConditionOperator_LESS;
+ break;
+ case excel::XlFormatConditionOperator::xlGreaterEqual:
+ aRetAPIOperator = sheet::ConditionOperator_GREATER_EQUAL;
+ break;
+ case excel::XlFormatConditionOperator::xlLessEqual:
+ aRetAPIOperator = sheet::ConditionOperator_LESS_EQUAL;
+ break;
+ default:
+ aRetAPIOperator = sheet::ConditionOperator_NONE;
+ break;
+ }
+ }
+ return aRetAPIOperator;
+}
+
+template< typename Ifc1 >
+rtl::OUString
+ScVbaCondition< Ifc1 >::Formula1( ) throw ( script::BasicErrorException, uno::RuntimeException )
+{
+ return mxSheetCondition->getFormula1();
+}
+
+template< typename Ifc1 >
+rtl::OUString
+ScVbaCondition< Ifc1 >::Formula2( ) throw ( script::BasicErrorException, uno::RuntimeException )
+{
+ return mxSheetCondition->getFormula2();
+}
+
+template< typename Ifc1 >
+void
+ScVbaCondition< Ifc1 >::setFormula1( const uno::Any& _aFormula1) throw ( script::BasicErrorException )
+{
+ rtl::OUString sFormula;
+ if ( (_aFormula1 >>= sFormula ))
+ {
+ mxSheetCondition->setFormula1( sFormula );
+ table::CellRangeAddress aCellRangeAddress = mxAddressable->getRangeAddress();
+ table::CellAddress aCellAddress( aCellRangeAddress.Sheet, aCellRangeAddress.StartColumn, aCellRangeAddress.StartRow );
+ mxSheetCondition->setSourcePosition(aCellAddress);
+ }
+}
+
+template< typename Ifc1 >
+void
+ScVbaCondition< Ifc1 >::setFormula2( const uno::Any& _aFormula2) throw ( script::BasicErrorException )
+{
+ rtl::OUString sFormula2;
+ // #TODO surely this can't be right?
+ // ( from helperapi/impl/.../calc/ConditionImpl.java
+ if ( (_aFormula2 >>= sFormula2 ))
+ mxSheetCondition->setFormula1(sFormula2);
+}
+
+template< typename Ifc1 >
+sal_Int32
+ScVbaCondition< Ifc1 >::Operator(sal_Bool _bIncludeFormulaValue) throw ( script::BasicErrorException )
+{
+ sal_Int32 retvalue = -1;
+ sheet::ConditionOperator aConditionalOperator = mxSheetCondition->getOperator();
+ switch (aConditionalOperator)
+ {
+ case sheet::ConditionOperator_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlEqual;
+ break;
+ case sheet::ConditionOperator_NOT_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlNotEqual;
+ break;
+ case sheet::ConditionOperator_GREATER:
+ retvalue = excel::XlFormatConditionOperator::xlGreater;
+ break;
+ case sheet::ConditionOperator_GREATER_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlGreaterEqual;
+ break;
+ case sheet::ConditionOperator_LESS:
+ retvalue = excel::XlFormatConditionOperator::xlLess;
+ break;
+ case sheet::ConditionOperator_LESS_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlLessEqual;
+ break;
+ case sheet::ConditionOperator_BETWEEN:
+ retvalue = excel::XlFormatConditionOperator::xlBetween;
+ break;
+ case sheet::ConditionOperator_NOT_BETWEEN:
+ retvalue = excel::XlFormatConditionOperator::xlNotBetween;
+ break;
+ case sheet::ConditionOperator_FORMULA:
+ if (_bIncludeFormulaValue)
+ {
+ //#FIXME huh what's this all about
+ // from helperapi/impl/.../calc/ConditionImpl
+ retvalue = ISFORMULA;
+ break;
+ }
+ case sheet::ConditionOperator_NONE:
+ default:
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Operator not supported")));
+ break;
+ }
+ return retvalue;
+}
+
+template class ScVbaCondition< excel::XFormatCondition >;
+
diff --git a/sc/source/ui/vba/vbacondition.hxx b/sc/source/ui/vba/vbacondition.hxx
new file mode 100644
index 000000000000..36052fe217ee
--- /dev/null
+++ b/sc/source/ui/vba/vbacondition.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_CONDITION_HXX
+#define SC_VBA_CONDITION_HXX
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+
+template< typename Ifc1 >
+class ScVbaCondition : public InheritedHelperInterfaceImpl1< Ifc1 >
+{
+typedef InheritedHelperInterfaceImpl1< Ifc1 > ScVbaCondition_BASE;
+protected:
+ css::uno::Reference< css::sheet::XCellRangeAddressable > mxAddressable;
+ css::uno::Reference< css::sheet::XSheetCondition > mxSheetCondition;
+public:
+ ScVbaCondition( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::sheet::XSheetCondition >& _xSheetCondition );
+
+ static css::sheet::ConditionOperator retrieveAPIOperator( const css::uno::Any& _aOperator) throw ( css::script::BasicErrorException );
+
+ virtual rtl::OUString SAL_CALL Formula1( ) throw ( css::script::BasicErrorException, css::uno::RuntimeException );
+ virtual rtl::OUString SAL_CALL Formula2( ) throw ( css::script::BasicErrorException, css::uno::RuntimeException );
+ virtual void setFormula1( const css::uno::Any& _aFormula1) throw ( css::script::BasicErrorException );
+ virtual void setFormula2( const css::uno::Any& _aFormula2) throw ( css::script::BasicErrorException );
+ virtual sal_Int32 Operator(sal_Bool _bIncludeFormulaValue) throw ( css::script::BasicErrorException );
+ virtual sal_Int32 SAL_CALL Operator() throw ( css::script::BasicErrorException, css::uno::RuntimeException ) = 0;
+
+};
+#endif
diff --git a/sc/source/ui/vba/vbadialog.cxx b/sc/source/ui/vba/vbadialog.cxx
new file mode 100644
index 000000000000..3c578a04e5d0
--- /dev/null
+++ b/sc/source/ui/vba/vbadialog.cxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbadialog.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static const rtl::OUString aStringList[]=
+{
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Open" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormatCellDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertCell" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Print" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:PasteSpecial" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ToolProtectionDocument" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ColumnWidth" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DefineName" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ConfigureDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:HyperlinkDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertGraphic" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertObject" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:PageFormatDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DataSort" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:RowHeight" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:AutoCorrectDlg" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ConditionalFormatDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DataConsolidate" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CreateNames" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillSeries" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Validation") ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DefineLabelRange" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DataFilterAutoFilter" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DataFilterSpecialFilter" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:AutoFormat" ) )
+};
+
+const sal_Int32 nDialogSize = sizeof( aStringList ) / sizeof( aStringList[ 0 ] );
+
+rtl::OUString
+ScVbaDialog::mapIndexToName( sal_Int32 nIndex )
+{
+ if( nIndex < nDialogSize )
+ return aStringList[ nIndex ];
+ return rtl::OUString();
+}
+
+rtl::OUString&
+ScVbaDialog::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaDialog") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaDialog::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Dialog" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbadialog.hxx b/sc/source/ui/vba/vbadialog.hxx
new file mode 100644
index 000000000000..40f4a4a83a11
--- /dev/null
+++ b/sc/source/ui/vba/vbadialog.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_DIALOG_HXX
+#define SC_VBA_DIALOG_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XDialog.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbadialogbase.hxx>
+
+typedef cppu::ImplInheritanceHelper1< VbaDialogBase, ov::excel::XDialog > ScVbaDialog_BASE;
+
+class ScVbaDialog : public ScVbaDialog_BASE
+{
+public:
+ ScVbaDialog( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > xContext, const css::uno::Reference< css::frame::XModel >& xModel, sal_Int32 nIndex ):ScVbaDialog_BASE( xParent, xContext, xModel, nIndex ) {}
+ virtual ~ScVbaDialog() {}
+
+ // Methods
+ virtual rtl::OUString mapIndexToName( sal_Int32 nIndex );
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif /* SC_VBA_DIALOG_HXX */
diff --git a/sc/source/ui/vba/vbadialogs.cxx b/sc/source/ui/vba/vbadialogs.cxx
new file mode 100644
index 000000000000..67070879535b
--- /dev/null
+++ b/sc/source/ui/vba/vbadialogs.cxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <ooo/vba/excel/XDialog.hpp>
+#include "vbadialogs.hxx"
+#include "vbadialog.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+void
+ScVbaDialogs::Dummy() throw (uno::RuntimeException)
+{
+}
+
+uno::Any
+ScVbaDialogs::Item( const uno::Any &aItem ) throw (uno::RuntimeException)
+{
+ sal_Int32 nIndex = 0;
+ aItem >>= nIndex;
+ uno::Reference< excel::XDialog > aDialog( new ScVbaDialog( uno::Reference< XHelperInterface >( Application(),uno::UNO_QUERY_THROW ), mxContext, m_xModel, nIndex ) );
+ return uno::Any( aDialog );
+}
+
+rtl::OUString&
+ScVbaDialogs::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaDialogs") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaDialogs::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Dialogs" ) );
+ }
+ return aServiceNames;
+}
+
+
+
diff --git a/sc/source/ui/vba/vbadialogs.hxx b/sc/source/ui/vba/vbadialogs.hxx
new file mode 100644
index 000000000000..9aab5daf11fe
--- /dev/null
+++ b/sc/source/ui/vba/vbadialogs.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_DIALOGS_HXX
+#define SC_VBA_DIALOGS_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <ooo/vba/excel/XDialogs.hpp>
+#include <ooo/vba/XCollection.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbadialogsbase.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+typedef cppu::ImplInheritanceHelper1< VbaDialogsBase, ov::excel::XDialogs > ScVbaDialogs_BASE;
+
+class ScVbaDialogs : public ScVbaDialogs_BASE
+{
+public:
+ ScVbaDialogs( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel >& xModel ): ScVbaDialogs_BASE( xParent, xContext, xModel ) {}
+ virtual ~ScVbaDialogs() {}
+
+ // XCollection
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index ) throw (css::uno::RuntimeException);
+
+ // XDialogs
+ virtual void SAL_CALL Dummy() throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif /* SC_VBA_DIALOGS_HXX */
diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx
new file mode 100755
index 000000000000..45667adf2f2c
--- /dev/null
+++ b/sc/source/ui/vba/vbaeventshelper.cxx
@@ -0,0 +1,753 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbaeventshelper.hxx"
+
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/frame/XBorderResizeListener.hpp>
+#include <com/sun/star/frame/XControllerBorder.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/util/XCloseListener.hpp>
+
+#include <ooo/vba/excel/XApplication.hpp>
+
+#include <cppuhelper/implbase4.hxx>
+#include <toolkit/unohlp.hxx>
+#include <vbahelper/helperdecl.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+
+#include "cellsuno.hxx"
+#include "convuno.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::script::vba::VBAEventId;
+using namespace ::ooo::vba;
+
+// ============================================================================
+
+typedef ::cppu::WeakImplHelper4<
+ awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE;
+
+// This class is to process Workbook window related event
+class ScVbaEventsListener : public ScVbaEventsListener_BASE
+{
+public :
+ ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell );
+ virtual ~ScVbaEventsListener();
+
+ void startListening();
+ void stopListening();
+
+ // XWindowListener
+ virtual void SAL_CALL windowResized( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException);
+ virtual void SAL_CALL windowMoved( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException);
+ virtual void SAL_CALL windowShown( const lang::EventObject& aEvent ) throw (uno::RuntimeException);
+ virtual void SAL_CALL windowHidden( const lang::EventObject& aEvent ) throw (uno::RuntimeException);
+ virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (uno::RuntimeException);
+
+ // XCloseListener
+ virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException);
+ virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException);
+
+ // XBorderResizeListener
+ virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException);
+
+ // XChangesListener
+ virtual void SAL_CALL changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException);
+
+private:
+ uno::Reference< frame::XFrame > getFrame();
+ uno::Reference< awt::XWindow > getContainerWindow();
+ bool isMouseReleased();
+ DECL_LINK( fireResizeMacro, void* );
+ void processWindowResizeMacro();
+
+private:
+ ::osl::Mutex maMutex;
+ ScVbaEventsHelper& mrVbaEvents;
+ uno::Reference< frame::XModel > mxModel;
+ ScDocShell* mpDocShell;
+ bool mbWindowResized;
+ bool mbBorderChanged;
+ bool mbDisposed;
+};
+
+// ----------------------------------------------------------------------------
+
+ScVbaEventsListener::ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) :
+ mrVbaEvents( rVbaEvents ),
+ mxModel( rxModel ),
+ mpDocShell( pDocShell ),
+ mbWindowResized( false ),
+ mbBorderChanged( false ),
+ mbDisposed( !rxModel.is() )
+{
+ OSL_TRACE( "ScVbaEventsListener::ScVbaEventsListener( 0x%x ) - ctor ", this );
+}
+
+ScVbaEventsListener::~ScVbaEventsListener()
+{
+ OSL_TRACE( "ScVbaEventsListener::~ScVbaEventsListener( 0x%x ) - dtor ", this );
+ stopListening();
+}
+
+void ScVbaEventsListener::startListening()
+{
+ if( !mbDisposed )
+ {
+ // add window listener
+ try
+ {
+ uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW );
+ xWindow->addWindowListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ // add close listener
+ try
+ {
+ uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW );
+ xCloseBroadcaster->addCloseListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ // add Border resize listener
+ try
+ {
+ uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xControllerBorder->addBorderResizeListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ // add content change listener
+ try
+ {
+ uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
+ xChangesNotifier->addChangesListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+}
+
+void ScVbaEventsListener::stopListening()
+{
+ if( !mbDisposed )
+ {
+ try
+ {
+ uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW );
+ xWindow->removeWindowListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ try
+ {
+ uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW );
+ xCloseBroadcaster->removeCloseListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ try
+ {
+ uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xControllerBorder->removeBorderResizeListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ try
+ {
+ uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
+ xChangesNotifier->removeChangesListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ mbDisposed = true;
+}
+
+void SAL_CALL ScVbaEventsListener::windowResized( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ // Workbook_window_resize event
+ mbWindowResized = true;
+ if( !mbDisposed && mbBorderChanged )
+ {
+ if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) )
+ {
+ mbBorderChanged = mbWindowResized = false;
+ acquire(); // ensure we don't get deleted before the event is handled
+ Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 );
+ }
+ }
+}
+
+void SAL_CALL ScVbaEventsListener::windowMoved( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException )
+{
+ // not interest this time
+}
+
+void SAL_CALL ScVbaEventsListener::windowShown( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException )
+{
+ // not interest this time
+}
+
+void SAL_CALL ScVbaEventsListener::windowHidden( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException )
+{
+ // not interest this time
+}
+
+void SAL_CALL ScVbaEventsListener::disposing( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ OSL_TRACE( "ScVbaEventsListener::disposing( 0x%x )", this );
+ mbDisposed = true;
+}
+
+void SAL_CALL ScVbaEventsListener::queryClosing( const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) throw (util::CloseVetoException, uno::RuntimeException)
+{
+ // it can cancel the close, but need to throw a CloseVetoException, and it will be transmit to caller.
+}
+
+void SAL_CALL ScVbaEventsListener::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ stopListening();
+}
+
+void SAL_CALL ScVbaEventsListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& /*aObject*/, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ // work with WindowResized event to guard Window Resize event.
+ mbBorderChanged = true;
+ if( !mbDisposed && mbWindowResized )
+ {
+ if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) )
+ {
+ mbWindowResized = mbBorderChanged = false;
+ acquire(); // ensure we don't get deleted before the timer fires.
+ Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 );
+ }
+ }
+}
+
+void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException)
+{
+ sal_Int32 nCount = aEvent.Changes.getLength();
+ if( nCount == 0 )
+ return;
+
+ util::ElementChange aChange = aEvent.Changes[ 0 ];
+ rtl::OUString sOperation;
+ aChange.Accessor >>= sOperation;
+ if( !sOperation.equalsIgnoreAsciiCaseAscii("cell-change") )
+ return;
+
+ if( nCount == 1 )
+ {
+ uno::Reference< table::XCellRange > xRangeObj;
+ aChange.ReplacedElement >>= xRangeObj;
+ if( xRangeObj.is() )
+ {
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[0] <<= xRangeObj;
+ mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs );
+ }
+ return;
+ }
+
+ ScRangeList aRangeList;
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ aChange = aEvent.Changes[ nIndex ];
+ aChange.Accessor >>= sOperation;
+ uno::Reference< table::XCellRange > xRangeObj;
+ aChange.ReplacedElement >>= xRangeObj;
+ if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCaseAscii("cell-change") )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY );
+ if( xCellRangeAddressable.is() )
+ {
+ ScRange aRange;
+ ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() );
+ aRangeList.Append( aRange );
+ }
+ }
+ }
+
+ if( (aRangeList.Count() > 0) && mpDocShell )
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) );
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[0] <<= xRanges;
+ mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+uno::Reference< frame::XFrame > ScVbaEventsListener::getFrame()
+{
+ if( !mbDisposed && mxModel.is() ) try
+ {
+ uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ return xController->getFrame();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return uno::Reference< frame::XFrame >();
+}
+
+uno::Reference< awt::XWindow > ScVbaEventsListener::getContainerWindow()
+{
+ try
+ {
+ uno::Reference< frame::XFrame > xFrame( getFrame(), uno::UNO_SET_THROW );
+ return xFrame->getContainerWindow();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return uno::Reference< awt::XWindow >();
+}
+
+bool ScVbaEventsListener::isMouseReleased()
+{
+ if( Window* pWindow = VCLUnoHelper::GetWindow( getContainerWindow() ) )
+ {
+ Window::PointerState aPointerState = pWindow->GetPointerState();
+ return (aPointerState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT )) == 0;
+ }
+ return false;
+}
+
+IMPL_LINK( ScVbaEventsListener, fireResizeMacro, void*, EMPTYARG )
+{
+ if( !mbDisposed && isMouseReleased() )
+ processWindowResizeMacro();
+ release();
+ return 0;
+}
+
+void ScVbaEventsListener::processWindowResizeMacro()
+{
+ OSL_TRACE( "**** Attempt to FIRE MACRO **** " );
+ if( !mbDisposed )
+ mrVbaEvents.processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() );
+}
+
+// ============================================================================
+
+ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) :
+ VbaEventsHelperBase( rArgs, xContext ),
+ mbOpened( false )
+{
+ mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class
+ mpDoc = mpDocShell ? mpDocShell->GetDocument() : 0;
+
+ if( !mxModel.is() || !mpDocShell || !mpDoc )
+ return;
+
+#define REGISTER_EVENT( eventid, eventname, type, cancelindex, worksheet ) \
+ registerEventHandler( eventid, eventname, type, cancelindex, uno::Any( worksheet ) )
+
+#define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \
+ REGISTER_EVENT( WORKBOOK_##eventid, "Workbook_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, false )
+
+#define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \
+ REGISTER_EVENT( WORKSHEET_##eventid, "Worksheet_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, true ); \
+ REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), "Workbook_Sheet" eventname, EVENTHANDLER_DOCUMENT, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false )
+
+ // global
+ REGISTER_EVENT( AUTO_OPEN, "Auto_Open", EVENTHANDLER_GLOBAL, -1, false );
+ REGISTER_EVENT( AUTO_CLOSE, "Auto_Close", EVENTHANDLER_GLOBAL, -1, false );
+
+ // Workbook
+ REGISTER_WORKBOOK_EVENT( ACTIVATE, "Activate", -1 );
+ REGISTER_WORKBOOK_EVENT( DEACTIVATE, "Deactivate", -1 );
+ REGISTER_WORKBOOK_EVENT( OPEN, "Open", -1 );
+ REGISTER_WORKBOOK_EVENT( BEFORECLOSE, "BeforeClose", 0 );
+ REGISTER_WORKBOOK_EVENT( BEFOREPRINT, "BeforePrint", 0 );
+ REGISTER_WORKBOOK_EVENT( BEFORESAVE, "BeforeSave", 1 );
+ REGISTER_WORKBOOK_EVENT( AFTERSAVE, "AfterSave", -1 );
+ REGISTER_WORKBOOK_EVENT( NEWSHEET, "NewSheet", -1 );
+ REGISTER_WORKBOOK_EVENT( WINDOWACTIVATE, "WindowActivate", -1 );
+ REGISTER_WORKBOOK_EVENT( WINDOWDEACTIVATE, "WindowDeactivate", -1 );
+ REGISTER_WORKBOOK_EVENT( WINDOWRESIZE, "WindowResize", -1 );
+
+ // Worksheet events. All events have a corresponding workbook event.
+ REGISTER_WORKSHEET_EVENT( ACTIVATE, "Activate", -1 );
+ REGISTER_WORKSHEET_EVENT( DEACTIVATE, "Deactivate", -1 );
+ REGISTER_WORKSHEET_EVENT( BEFOREDOUBLECLICK, "BeforeDoubleClick", 1 );
+ REGISTER_WORKSHEET_EVENT( BEFORERIGHTCLICK, "BeforeRightClick", 1 );
+ REGISTER_WORKSHEET_EVENT( CALCULATE, "Calculate", -1 );
+ REGISTER_WORKSHEET_EVENT( CHANGE, "Change", -1 );
+ REGISTER_WORKSHEET_EVENT( SELECTIONCHANGE, "SelectionChange", -1 );
+ REGISTER_WORKSHEET_EVENT( FOLLOWHYPERLINK, "FollowHyperlink", -1 );
+
+#undef REGISTER_EVENT
+#undef REGISTER_WORKBOOK_EVENT
+#undef REGISTER_WORKSHEET_EVENT
+}
+
+ScVbaEventsHelper::~ScVbaEventsHelper()
+{
+}
+
+void SAL_CALL ScVbaEventsHelper::disposing( const lang::EventObject& rSource ) throw (uno::RuntimeException)
+{
+ mxListener.clear();
+ VbaEventsHelperBase::disposing( rSource );
+}
+
+// protected ------------------------------------------------------------------
+
+bool ScVbaEventsHelper::implEventsEnabled() throw (uno::RuntimeException)
+{
+ // document and document shell are needed during event processing
+ if( !mpDocShell || !mpDoc )
+ throw uno::RuntimeException();
+
+ // get Application object and check if events are enabled (this is an Excel-only attribute)
+ uno::Reference< excel::XApplication > xApplication( mxApplication.get(), uno::UNO_QUERY );
+ if( !xApplication.is() && mpShell )
+ {
+ uno::Any aVBAGlobals;
+ mpShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aVBAGlobals );
+ uno::Reference< XHelperInterface > xHelperInterface( aVBAGlobals, uno::UNO_QUERY );
+ if( xHelperInterface.is() )
+ {
+ xApplication.set( xHelperInterface->Application(), uno::UNO_QUERY );
+ mxApplication = xApplication;
+ }
+ }
+ if( !xApplication.is() )
+ throw uno::RuntimeException();
+
+ // return whether event processing is enabled
+ return xApplication->getEnableEvents();
+}
+
+bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
+ const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException)
+{
+ // check preconditions for some events, add more events if needed
+ bool bExecuteEvent = true;
+ switch( rInfo.mnEventId )
+ {
+ case WORKBOOK_ACTIVATE:
+ // while loading, framework fires this before 'opened' event, delay it
+ bExecuteEvent = mbOpened;
+ break;
+ case WORKBOOK_OPEN:
+ bExecuteEvent = !mbOpened;
+ if( bExecuteEvent )
+ {
+ // execute delayed Activate event too (see above)
+ rEventQueue.push_back( WORKBOOK_ACTIVATE );
+ rEventQueue.push_back( WORKBOOK_WINDOWACTIVATE );
+ rEventQueue.push_back( AUTO_OPEN );
+ }
+ break;
+ case WORKSHEET_SELECTIONCHANGE:
+ // if selection is not changed, then do not fire the event
+ bExecuteEvent = mbOpened && isSelectionChanged( rArgs, 0 );
+ break;
+ }
+
+ // add workbook event associated to a sheet event
+ bool bSheetEvent = false;
+ rInfo.maUserData >>= bSheetEvent;
+ if( bSheetEvent && bExecuteEvent )
+ rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) );
+
+ return bExecuteEvent;
+}
+
+uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo,
+ const uno::Sequence< uno::Any >& rArgs ) throw (lang::IllegalArgumentException)
+{
+ // fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below
+ bool bSheetEventAsBookEvent = rInfo.mnEventId > USERDEFINED_START;
+ sal_Int32 nEventId = bSheetEventAsBookEvent ? (rInfo.mnEventId - USERDEFINED_START) : rInfo.mnEventId;
+
+ uno::Sequence< uno::Any > aVbaArgs;
+ switch( nEventId )
+ {
+ // *** Workbook ***
+
+ // no arguments
+ case WORKBOOK_ACTIVATE:
+ case WORKBOOK_DEACTIVATE:
+ case WORKBOOK_OPEN:
+ break;
+ // 1 arg: cancel
+ case WORKBOOK_BEFORECLOSE:
+ case WORKBOOK_BEFOREPRINT:
+ aVbaArgs.realloc( 1 );
+ // current cancel state will be inserted by caller
+ break;
+ // 2 args: saveAs, cancel
+ case WORKBOOK_BEFORESAVE:
+ aVbaArgs.realloc( 2 );
+ checkArgumentType< bool >( rArgs, 0 );
+ aVbaArgs[ 0 ] = rArgs[ 0 ];
+ // current cancel state will be inserted by caller
+ break;
+ // 1 arg: success
+ case WORKBOOK_AFTERSAVE:
+ aVbaArgs.realloc( 1 );
+ checkArgumentType< bool >( rArgs, 0 );
+ aVbaArgs[ 0 ] = rArgs[ 0 ];
+ break;
+ // 1 arg: window
+ case WORKBOOK_WINDOWACTIVATE:
+ case WORKBOOK_WINDOWDEACTIVATE:
+ case WORKBOOK_WINDOWRESIZE:
+ aVbaArgs.realloc( 1 );
+ aVbaArgs[ 0 ] = createWindow();
+ break;
+ // 1 arg: worksheet
+ case WORKBOOK_NEWSHEET:
+ aVbaArgs.realloc( 1 );
+ aVbaArgs[ 0 ] = createWorksheet( rArgs, 0 );
+ break;
+
+ // *** Worksheet ***
+
+ // no arguments
+ case WORKSHEET_ACTIVATE:
+ case WORKSHEET_CALCULATE:
+ case WORKSHEET_DEACTIVATE:
+ break;
+ // 1 arg: range
+ case WORKSHEET_CHANGE:
+ case WORKSHEET_SELECTIONCHANGE:
+ aVbaArgs.realloc( 1 );
+ aVbaArgs[ 0 ] = createRange( rArgs, 0 );
+ break;
+ // 2 args: range, cancel
+ case WORKSHEET_BEFOREDOUBLECLICK:
+ case WORKSHEET_BEFORERIGHTCLICK:
+ aVbaArgs.realloc( 2 );
+ aVbaArgs[ 0 ] = createRange( rArgs, 0 );
+ // current cancel state will be inserted by caller
+ break;
+ // 1 arg: hyperlink
+ case WORKSHEET_FOLLOWHYPERLINK:
+ aVbaArgs.realloc( 1 );
+ aVbaArgs[ 0 ] = createHyperlink( rArgs, 0 );
+ break;
+ }
+
+ /* For workbook events associated to sheet events, the workbook event gets
+ the same arguments but with a Worksheet object in front of them. */
+ if( bSheetEventAsBookEvent )
+ {
+ sal_Int32 nLength = aVbaArgs.getLength();
+ uno::Sequence< uno::Any > aVbaArgs2( nLength + 1 );
+ aVbaArgs2[ 0 ] = createWorksheet( rArgs, 0 );
+ for( sal_Int32 nIndex = 0; nIndex < nLength; ++nIndex )
+ aVbaArgs2[ nIndex + 1 ] = aVbaArgs[ nIndex ];
+ aVbaArgs = aVbaArgs2;
+ }
+
+ return aVbaArgs;
+}
+
+void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
+ const EventHandlerInfo& rInfo, bool /*bSuccess*/, bool bCancel ) throw (uno::RuntimeException)
+{
+ switch( rInfo.mnEventId )
+ {
+ case WORKBOOK_OPEN:
+ mbOpened = true;
+ // register the listeners
+ if( !mxListener.is() )
+ {
+ mxListener = new ScVbaEventsListener( *this, mxModel, mpDocShell );
+ mxListener->startListening();
+ }
+ break;
+ case WORKBOOK_BEFORECLOSE:
+ /* Execute Auto_Close only if not cancelled by event handler, but
+ before UI asks user whether to cancel closing the document. */
+ if( !bCancel )
+ rEventQueue.push_back( AUTO_CLOSE );
+ break;
+ }
+}
+
+::rtl::OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo,
+ const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException)
+{
+ bool bSheetEvent = false;
+ rInfo.maUserData >>= bSheetEvent;
+ SCTAB nTab = bSheetEvent ? getTabFromArgs( rArgs, 0 ) : -1;
+ if( bSheetEvent && (nTab < 0) )
+ throw lang::IllegalArgumentException();
+
+ String aCodeName;
+ if( bSheetEvent )
+ mpDoc->GetCodeName( nTab, aCodeName );
+ else
+ aCodeName = mpDoc->GetCodeName();
+ return aCodeName;
+}
+
+// private --------------------------------------------------------------------
+
+SCTAB ScVbaEventsHelper::getTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException)
+{
+ checkArgument( rArgs, nIndex );
+
+ // first try to extract a sheet index
+ SCTAB nTab = -1;
+ if( rArgs[ nIndex ] >>= nTab )
+ return nTab;
+
+ // next, try single range object
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
+ if( xCellRangeAddressable.is() )
+ return xCellRangeAddressable->getRangeAddress().Sheet;
+
+ // at last, try range list
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
+ if( xRanges.is() )
+ {
+ uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
+ if( aRangeAddresses.getLength() > 0 )
+ return aRangeAddresses[ 0 ].Sheet;
+ }
+
+ throw lang::IllegalArgumentException();
+}
+
+bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false );
+ if( ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection ) )
+ {
+ bool bChanged = maOldSelection != pNewCellRanges->GetRangeList();
+ maOldSelection = pNewCellRanges->GetRangeList();
+ return bChanged;
+ }
+ maOldSelection.Clear();
+ return true;
+}
+
+uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ // Eventually we will be able to pull the Workbook/Worksheet objects
+ // directly from basic and register them as listeners
+
+ // extract sheet index, will throw, if parameter is invalid
+ SCTAB nTab = getTabFromArgs( rArgs, nIndex );
+
+ // create Workbook
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= uno::Reference< uno::XInterface >();
+ aArgs[ 1 ] <<= mxModel;
+ uno::Reference< uno::XInterface > xWorkbook( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Workbook", aArgs ), uno::UNO_SET_THROW );
+
+ // create WorkSheet
+ String aSheetName;
+ mpDoc->GetName( nTab, aSheetName );
+ aArgs = uno::Sequence< uno::Any >( 3 );
+ aArgs[ 0 ] <<= xWorkbook;
+ aArgs[ 1 ] <<= mxModel;
+ aArgs[ 2 ] <<= ::rtl::OUString( aSheetName );
+ uno::Reference< uno::XInterface > xWorksheet( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Worksheet", aArgs ), uno::UNO_SET_THROW );
+ return uno::Any( xWorksheet );
+}
+
+uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
+ uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex );
+ if ( !xRanges.is() && !xRange.is() )
+ throw lang::IllegalArgumentException();
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent
+ if ( xRanges.is() )
+ aArgs[ 1 ] <<= xRanges;
+ else
+ aArgs[ 1 ] <<= xRange;
+ uno::Reference< uno::XInterface > xVbaRange( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_SET_THROW );
+ return uno::Any( xVbaRange );
+}
+
+uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent
+ aArgs[ 1 ] <<= getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false );
+ uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW );
+ return uno::Any( xHyperlink );
+}
+
+uno::Any ScVbaEventsHelper::createWindow() const throw (uno::RuntimeException)
+{
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= createVBAUnoAPIService( mpShell, "ooo.vba.Application" );
+ aArgs[ 1 ] <<= mxModel;
+ uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW );
+ return uno::Any( xWindow );
+}
+
+// ============================================================================
+
+namespace vbaeventshelper
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ScVbaEventsHelper, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaEventsHelper",
+ "com.sun.star.script.vba.VBASpreadsheetEventProcessor" );
+}
+
+// ============================================================================
diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx
new file mode 100755
index 000000000000..a77f5128b3e9
--- /dev/null
+++ b/sc/source/ui/vba/vbaeventshelper.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_VBAEVENTS_HXX
+#define SC_VBAEVENTS_HXX
+
+#include <rtl/ref.hxx>
+#include <vbahelper/vbaeventshelperbase.hxx>
+#include "excelvbahelper.hxx"
+#include "rangelst.hxx"
+
+namespace ooo { namespace vba { namespace excel { class XApplication; } } }
+
+class ScVbaEventsListener;
+
+// ============================================================================
+
+class ScVbaEventsHelper : public VbaEventsHelperBase
+{
+public:
+ ScVbaEventsHelper(
+ const css::uno::Sequence< css::uno::Any >& rArgs,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+ virtual ~ScVbaEventsHelper();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& rSource ) throw (css::uno::RuntimeException);
+
+protected:
+ virtual bool implEventsEnabled() throw (css::uno::RuntimeException);
+ virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException);
+ virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bSuccess, bool bCancel ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException);
+
+private:
+ /** Extracts a sheet index from the first element of the passed sequence. The
+ element may be an integer, or a Calc range or ranges object. */
+ static SCTAB getTabFromArgs( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException);
+ /** Checks if selection has been changed compared to selection of last call.
+ @return true, if the selection has been changed. */
+ bool isSelectionChanged( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
+
+ /** Creates a VBA Worksheet object (the argument must contain a sheet index). */
+ css::uno::Any createWorksheet( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
+ /** Creates a VBA Range object (the argument must contain a UNO range or UNO range list). */
+ css::uno::Any createRange( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
+ /** Creates a VBA Hyperlink object (the argument must contain a UNO cell). */
+ css::uno::Any createHyperlink( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
+ /** Creates a VBA Window object. */
+ css::uno::Any createWindow() const throw (css::uno::RuntimeException);
+
+private:
+ mutable css::uno::WeakReference< ov::excel::XApplication > mxApplication;
+ ::rtl::Reference< ScVbaEventsListener > mxListener;
+ ScDocShell* mpDocShell;
+ ScDocument* mpDoc;
+ ScRangeList maOldSelection;
+ bool mbOpened;
+};
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/ui/vba/vbafont.cxx b/sc/source/ui/vba/vbafont.cxx
new file mode 100644
index 000000000000..5894d3ea8c71
--- /dev/null
+++ b/sc/source/ui/vba/vbafont.cxx
@@ -0,0 +1,501 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <com/sun/star/beans/XProperty.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <ooo/vba/excel/XlColorIndex.hpp>
+#include <ooo/vba/excel/XlUnderlineStyle.hpp>
+#include <svl/itemset.hxx>
+#include "excelvbahelper.hxx"
+#include "vbafont.hxx"
+#include "scitems.hxx"
+#include "cellsuno.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaFont::ScVbaFont(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const ScVbaPalette& dPalette,
+ const uno::Reference< beans::XPropertySet >& xPropertySet,
+ ScCellRangeObj* pRangeObj, bool bFormControl ) throw ( uno::RuntimeException ) :
+ ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet, bFormControl ),
+ mPalette( dPalette ),
+ mpRangeObj( pRangeObj )
+{
+}
+
+SfxItemSet*
+ScVbaFont::GetDataSet()
+{
+ return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : 0;
+}
+
+ScVbaFont::~ScVbaFont()
+{
+}
+
+
+uno::Reference< beans::XPropertySet > lcl_TextProperties( uno::Reference< table::XCell >& xIf ) throw ( uno::RuntimeException )
+{
+ uno::Reference< text::XTextRange > xTxtRange( xIf, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XSimpleText > xTxt( xTxtRange->getText(), uno::UNO_QUERY_THROW ) ;
+ uno::Reference< beans::XPropertySet > xProps( xTxt->createTextCursor(), uno::UNO_QUERY_THROW );
+ return xProps;
+}
+void SAL_CALL
+ScVbaFont::setSuperscript( const uno::Any& aValue ) throw ( uno::RuntimeException )
+{
+ // #FIXEME create some sort of generic get/set code where
+ // you can pass a functor
+ // get/set - Super/sub script code is exactly the same
+ // except for the call applied at each cell position
+ uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
+ uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
+ if ( !xCell.is() )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
+ sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
+ for ( sal_Int32 col = 0; col < nCols; ++col )
+ {
+ for ( sal_Int32 row = 0; row < nRows; ++row )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ) , uno::UNO_QUERY_THROW );
+ ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
+ aFont.setSuperscript( aValue );
+ }
+ }
+ return;
+
+ }
+ xCell.set( xCellRange->getCellByPosition( 0,0 ) );
+
+ uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
+ sal_Bool bValue = sal_False;
+ aValue >>= bValue;
+ sal_Int16 nValue = NORMAL;
+ sal_Int8 nValue2 = NORMALHEIGHT;
+
+ if( bValue )
+ {
+ nValue = SUPERSCRIPT;
+ nValue2 = SUPERSCRIPTHEIGHT;
+ }
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), ( uno::Any )nValue );
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapementHeight" ) ), ( uno::Any )nValue2 );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getSuperscript() throw ( uno::RuntimeException )
+{
+ uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
+ uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
+ if ( !xCell.is() )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
+ sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
+ uno::Any aRes;
+ for ( sal_Int32 col = 0; col < nCols; ++col )
+ {
+ for ( sal_Int32 row = 0; row < nRows; ++row )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ), uno::UNO_QUERY_THROW );
+ ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
+ if ( !col && !row )
+ aRes = aFont.getSuperscript();
+ else if ( aRes != aFont.getSuperscript() )
+ return aNULL();
+ }
+ }
+ return aRes;
+
+ }
+ xCell.set( xCellRange->getCellByPosition( 0,0 ) );
+ uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
+ short nValue = 0;
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue;
+ return uno::makeAny( ( nValue == SUPERSCRIPT ) );
+}
+
+void SAL_CALL
+ScVbaFont::setSubscript( const uno::Any& aValue ) throw ( uno::RuntimeException )
+{
+ uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
+ uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
+ if ( !xCell.is() )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
+ sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
+ for ( sal_Int32 col = 0; col < nCols; ++col )
+ {
+ for ( sal_Int32 row = 0; row < nRows; ++row )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ) , uno::UNO_QUERY_THROW );
+ ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
+ aFont.setSubscript( aValue );
+ }
+ }
+ return;
+
+ }
+ xCell.set( xCellRange->getCellByPosition( 0,0 ) );
+ uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
+
+ sal_Bool bValue = sal_False;
+ aValue >>= bValue;
+ sal_Int16 nValue = NORMAL;
+ sal_Int8 nValue2 = NORMALHEIGHT;
+
+ if( bValue )
+ {
+ nValue= SUBSCRIPT;
+ nValue2 = SUBSCRIPTHEIGHT;
+ }
+
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapementHeight" ) ), ( uno::Any )nValue2 );
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), ( uno::Any )nValue );
+
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getSubscript() throw ( uno::RuntimeException )
+{
+ uno::Reference< table::XCell> xCell( mxFont, uno::UNO_QUERY );
+ uno::Reference< table::XCellRange > xCellRange( mxFont, uno::UNO_QUERY );
+ if ( !xCell.is() )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xCellRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nCols = xColumnRowRange->getColumns()->getCount();
+ sal_Int32 nRows = xColumnRowRange->getRows()->getCount();
+ uno::Any aRes;
+ for ( sal_Int32 col = 0; col < nCols; ++col )
+ {
+ for ( sal_Int32 row = 0; row < nRows; ++row )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xCellRange->getCellByPosition( col, row ), uno::UNO_QUERY_THROW );
+ ScVbaFont aFont( getParent(), mxContext, mPalette, xProps );
+ if ( !col && !row )
+ aRes = aFont.getSubscript();
+ else if ( aRes != aFont.getSubscript() )
+ return aNULL();
+ }
+ }
+ return aRes;
+
+ }
+ xCell.set( xCellRange->getCellByPosition( 0,0 ) );
+ uno::Reference< beans::XPropertySet > xProps = lcl_TextProperties( xCell );
+
+ short nValue = NORMAL;
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue;
+ return uno::makeAny( ( nValue == SUBSCRIPT ) );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getSize() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_HEIGHT, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getSize();
+}
+
+void SAL_CALL
+ScVbaFont::setColorIndex( const uno::Any& _colorindex ) throw( uno::RuntimeException )
+{
+ sal_Int32 nIndex = 0;
+ _colorindex >>= nIndex;
+ // #FIXME xlColorIndexAutomatic & xlColorIndexNone are not really
+ // handled properly here
+
+ if ( !nIndex || ( nIndex == excel::XlColorIndex::xlColorIndexAutomatic ) )
+ {
+ nIndex = 1; // check defualt ( assume black )
+ ScVbaFont_BASE::setColorIndex( uno::makeAny( nIndex ) );
+ }
+ else
+ ScVbaFont_BASE::setColorIndex( _colorindex );
+}
+
+
+uno::Any SAL_CALL
+ScVbaFont::getColorIndex() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_COLOR, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getColorIndex();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL
+ScVbaFont::setStandardFontSize( const uno::Any& /*aValue*/ ) throw( uno::RuntimeException )
+{
+//XXX #TODO# #FIXME#
+ //mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharSize" ) ), ( uno::Any )fValue );
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("setStandardFontSize not supported") ), uno::Reference< uno::XInterface >() );
+}
+
+
+uno::Any SAL_CALL
+ScVbaFont::getStandardFontSize() throw ( uno::RuntimeException )
+{
+//XXX #TODO# #FIXME#
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("getStandardFontSize not supported") ), uno::Reference< uno::XInterface >() );
+ // return uno::Any();
+}
+
+
+void SAL_CALL
+ScVbaFont::setStandardFont( const uno::Any& /*aValue*/ ) throw( uno::RuntimeException )
+{
+//XXX #TODO# #FIXME#
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("setStandardFont not supported") ), uno::Reference< uno::XInterface >() );
+}
+
+
+uno::Any SAL_CALL
+ScVbaFont::getStandardFont() throw ( uno::RuntimeException )
+{
+//XXX #TODO# #FIXME#
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("getStandardFont not supported") ), uno::Reference< uno::XInterface >() );
+ // return uno::Any();
+}
+
+void SAL_CALL
+ScVbaFont::setFontStyle( const uno::Any& aValue ) throw( uno::RuntimeException )
+{
+ sal_Bool bBold = sal_False;
+ sal_Bool bItalic = sal_False;
+
+ rtl::OUString aStyles;
+ aValue >>= aStyles;
+
+ std::vector< rtl::OUString > aTokens;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ rtl::OUString aToken = aStyles.getToken( 0, ' ', nIndex );
+ aTokens.push_back( aToken );
+ }while( nIndex >= 0 );
+
+ std::vector< rtl::OUString >::iterator it;
+ for( it = aTokens.begin(); it != aTokens.end(); ++it )
+ {
+ if( (*it).equalsIgnoreAsciiCaseAscii( "Bold" ) )
+ bBold = sal_True;
+
+ if( (*it).equalsIgnoreAsciiCaseAscii( "Italic" ) )
+ bItalic = sal_True;
+ }
+
+ setBold( uno::makeAny( bBold ) );
+ setItalic( uno::makeAny( bItalic ) );
+}
+
+
+uno::Any SAL_CALL
+ScVbaFont::getFontStyle() throw ( uno::RuntimeException )
+{
+ rtl::OUStringBuffer aStyles;
+ sal_Bool bValue = sal_False;
+ getBold() >>= bValue;
+ if( bValue )
+ aStyles.appendAscii("Bold");
+
+ getItalic() >>= bValue;
+ if( bValue )
+ {
+ if( aStyles.getLength() )
+ aStyles.appendAscii(" ");
+ aStyles.appendAscii("Italic");
+ }
+ return uno::makeAny( aStyles.makeStringAndClear() );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getBold() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_WEIGHT, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getBold();
+}
+
+void SAL_CALL
+ScVbaFont::setUnderline( const uno::Any& aValue ) throw ( uno::RuntimeException )
+{
+ // default
+ sal_Int32 nValue = excel::XlUnderlineStyle::xlUnderlineStyleNone;
+ aValue >>= nValue;
+ switch ( nValue )
+ {
+// NOTE:: #TODO #FIMXE
+// xlUnderlineStyleDoubleAccounting & xlUnderlineStyleSingleAccounting
+// don't seem to be supported in Openoffice.
+// The import filter converts them to single or double underlines as appropriate
+// So, here at the moment we are similarly silently converting
+// xlUnderlineStyleSingleAccounting to xlUnderlineStyleSingle.
+
+ case excel::XlUnderlineStyle::xlUnderlineStyleNone:
+ nValue = awt::FontUnderline::NONE;
+ break;
+ case excel::XlUnderlineStyle::xlUnderlineStyleSingle:
+ case excel::XlUnderlineStyle::xlUnderlineStyleSingleAccounting:
+ nValue = awt::FontUnderline::SINGLE;
+ break;
+ case excel::XlUnderlineStyle::xlUnderlineStyleDouble:
+ case excel::XlUnderlineStyle::xlUnderlineStyleDoubleAccounting:
+ nValue = awt::FontUnderline::DOUBLE;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown value for Underline")), uno::Reference< uno::XInterface >() );
+ }
+
+ mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ), ( uno::Any )nValue );
+
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getUnderline() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_UNDERLINE, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+
+ sal_Int32 nValue = awt::FontUnderline::NONE;
+ mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ) ) >>= nValue;
+ switch ( nValue )
+ {
+ case awt::FontUnderline::DOUBLE:
+ nValue = excel::XlUnderlineStyle::xlUnderlineStyleDouble;
+ break;
+ case awt::FontUnderline::SINGLE:
+ nValue = excel::XlUnderlineStyle::xlUnderlineStyleSingle;
+ break;
+ case awt::FontUnderline::NONE:
+ nValue = excel::XlUnderlineStyle::xlUnderlineStyleNone;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown value retrieved for Underline") ), uno::Reference< uno::XInterface >() );
+
+ }
+ return uno::makeAny( nValue );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getStrikethrough() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_CROSSEDOUT, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getStrikethrough();
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getShadow() throw (uno::RuntimeException)
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_SHADOWED, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getShadow();
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getItalic() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_POSTURE, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+
+ return ScVbaFont_BASE::getItalic();
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getName() throw ( uno::RuntimeException )
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getName();
+}
+uno::Any
+ScVbaFont::getColor() throw (uno::RuntimeException)
+{
+ // #TODO #FIXME - behave like getXXX above ( wrt. GetDataSet )
+ uno::Any aAny;
+ aAny = OORGBToXLRGB( mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ) ) );
+ return aAny;
+}
+
+void SAL_CALL
+ScVbaFont::setOutlineFont( const uno::Any& aValue ) throw ( uno::RuntimeException )
+{
+ mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharContoured" ) ), aValue );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getOutlineFont() throw (uno::RuntimeException)
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_CONTOUR, TRUE, NULL) == SFX_ITEM_DONTCARE )
+ return aNULL();
+ return mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharContoured" ) ) );
+}
+
+rtl::OUString&
+ScVbaFont::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFont") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaFont::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Font" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbafont.hxx b/sc/source/ui/vba/vbafont.hxx
new file mode 100644
index 000000000000..3ef52c6d240f
--- /dev/null
+++ b/sc/source/ui/vba/vbafont.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_FONT_HXX
+#define SC_VBA_FONT_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XFont.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbafontbase.hxx>
+#include "vbapalette.hxx"
+
+class ScTableSheetsObj;
+class ScCellRangeObj;
+
+typedef cppu::ImplInheritanceHelper1< VbaFontBase, ov::excel::XFont > ScVbaFont_BASE;
+
+class ScVbaFont : public ScVbaFont_BASE
+{
+ ScVbaPalette mPalette;
+ ScCellRangeObj* mpRangeObj;
+ SfxItemSet* GetDataSet();
+public:
+ ScVbaFont(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const ScVbaPalette& dPalette,
+ const css::uno::Reference< css::beans::XPropertySet >& xPropertySet,
+ ScCellRangeObj* pRangeObj = 0, bool bFormControl = false ) throw ( css::uno::RuntimeException );
+ virtual ~ScVbaFont();// {}
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getSize() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getStandardFontSize() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setStandardFontSize( const css::uno::Any& _standardfontsize ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getStandardFont() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setStandardFont( const css::uno::Any& _standardfont ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFontStyle() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFontStyle( const css::uno::Any& _fontstyle ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getColorIndex() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setColorIndex( const css::uno::Any& _colorindex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getBold() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getUnderline() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setUnderline( const css::uno::Any& _underline ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getStrikethrough() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getShadow() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getItalic() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getSubscript() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setSubscript( const css::uno::Any& _subscript ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getSuperscript() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setSuperscript( const css::uno::Any& _superscript ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getColor() throw (css::uno::RuntimeException) ;
+ virtual css::uno::Any SAL_CALL getOutlineFont() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setOutlineFont( const css::uno::Any& _outlinefont ) throw (css::uno::RuntimeException) ;
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+};
+
+
+
+#endif /* SC_VBA_FONT_HXX */
+
diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx
new file mode 100644
index 000000000000..d08451af63f4
--- /dev/null
+++ b/sc/source/ui/vba/vbaformat.cxx
@@ -0,0 +1,843 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbaformat.hxx"
+#include <ooo/vba/excel/XStyle.hpp>
+#include <ooo/vba/excel/XlVAlign.hpp>
+#include <ooo/vba/excel/XlHAlign.hpp>
+#include <ooo/vba/excel/XlOrientation.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/util/CellProtection.hpp>
+
+#include <rtl/math.hxx>
+
+#include "excelvbahelper.hxx"
+#include "vbaborders.hxx"
+#include "vbapalette.hxx"
+#include "vbafont.hxx"
+#include "vbainterior.hxx"
+
+#include <unonames.hxx>
+#include <cellsuno.hxx>
+#include <scitems.hxx>
+#include <attrib.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+#define FORMATSTRING "FormatString"
+#define LOCALE "Locale"
+
+template< typename Ifc1 >
+ScVbaFormat< Ifc1 >::ScVbaFormat( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertySet >& _xPropertySet, const uno::Reference< frame::XModel >& xModel, bool bCheckAmbiguoity ) throw ( script::BasicErrorException ) : ScVbaFormat_BASE( xParent, xContext ), m_aDefaultLocale( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("en") ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "US") ), rtl::OUString() ), mxPropertySet( _xPropertySet ), mxModel( xModel ), mbCheckAmbiguoity( bCheckAmbiguoity ), mbAddIndent( sal_False )
+{
+ try
+ {
+ mxServiceInfo.set( mxPropertySet, uno::UNO_QUERY_THROW );
+ if ( !mxModel.is() )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XModel Interface could not be retrieved") ) );
+ mxNumberFormatsSupplier.set( mxModel, uno::UNO_QUERY_THROW );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setVerticalAlignment( const uno::Any& _oAlignment) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ uno::Any aVal;
+ sal_Int32 nAlignment = 0;
+ if ( !(_oAlignment >>= nAlignment ))
+ throw uno::RuntimeException();
+ switch (nAlignment)
+ {
+ case excel::XlVAlign::xlVAlignBottom :
+ aVal = uno::makeAny( table::CellVertJustify_BOTTOM );
+ break;
+ case excel::XlVAlign::xlVAlignCenter :
+ aVal = uno::makeAny( table::CellVertJustify_CENTER );
+ break;
+ case excel::XlVAlign::xlVAlignDistributed:
+ case excel::XlVAlign::xlVAlignJustify:
+ aVal = uno::makeAny( table::CellVertJustify_STANDARD );
+ break;
+
+ case excel::XlVAlign::xlVAlignTop:
+ aVal = uno::makeAny( table::CellVertJustify_TOP);
+ break;
+ default:
+ aVal = uno::makeAny( table::CellVertJustify_STANDARD );
+ break;
+ }
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLVJUS ) ), aVal );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getVerticalAlignment( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aResult = aNULL();
+ try
+ {
+ if (!isAmbiguous( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLVJUS ) ) ) )
+ {
+ table::CellVertJustify aAPIAlignment;
+ mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLVJUS ) ) ) >>= aAPIAlignment;
+ switch( aAPIAlignment )
+ {
+ case table::CellVertJustify_BOTTOM:
+ aResult = uno::makeAny( excel::XlVAlign::xlVAlignBottom );
+ break;
+ case table::CellVertJustify_CENTER:
+ aResult = uno::makeAny( excel::XlVAlign::xlVAlignCenter );
+ break;
+ case table::CellVertJustify_STANDARD:
+ aResult = uno::makeAny( excel::XlVAlign::xlVAlignBottom );
+ break;
+ case table::CellVertJustify_TOP:
+ aResult = uno::makeAny( excel::XlVAlign::xlVAlignTop );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return aResult;
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setHorizontalAlignment( const uno::Any& HorizontalAlignment ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ uno::Any aVal;
+ sal_Int32 nAlignment = 0;
+ if ( !( HorizontalAlignment >>= nAlignment ) )
+ throw uno::RuntimeException();
+ switch ( nAlignment )
+ {
+ case excel::XlHAlign::xlHAlignJustify:
+ aVal = uno::makeAny( table::CellHoriJustify_BLOCK);
+ break;
+ case excel::XlHAlign::xlHAlignCenter:
+ aVal = uno::makeAny( table::CellHoriJustify_CENTER );
+ break;
+ case excel::XlHAlign::xlHAlignDistributed:
+ aVal = uno::makeAny( table::CellHoriJustify_BLOCK);
+ break;
+ case excel::XlHAlign::xlHAlignLeft:
+ aVal = uno::makeAny( table::CellHoriJustify_LEFT);
+ break;
+ case excel::XlHAlign::xlHAlignRight:
+ aVal = uno::makeAny( table::CellHoriJustify_RIGHT);
+ break;
+ }
+ // #FIXME what about the default case above?
+ // shouldn't need the test below
+ if ( aVal.hasValue() )
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLHJUS ) ), aVal );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getHorizontalAlignment( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any NRetAlignment = aNULL();
+ try
+ {
+ rtl::OUString sHoriJust( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLHJUS ) );
+ if (!isAmbiguous(sHoriJust))
+ {
+ table::CellHoriJustify aAPIAlignment = table::CellHoriJustify_BLOCK;
+
+ if ( mxPropertySet->getPropertyValue(sHoriJust) >>= aAPIAlignment )
+ {
+ switch( aAPIAlignment )
+ {
+ case table::CellHoriJustify_BLOCK:
+ NRetAlignment = uno::makeAny( excel::XlHAlign::xlHAlignJustify );
+ break;
+ case table::CellHoriJustify_CENTER:
+ NRetAlignment = uno::makeAny( excel::XlHAlign::xlHAlignCenter );
+ break;
+ case table::CellHoriJustify_LEFT:
+ NRetAlignment = uno::makeAny( excel::XlHAlign::xlHAlignLeft );
+ break;
+ case table::CellHoriJustify_RIGHT:
+ NRetAlignment = uno::makeAny( excel::XlHAlign::xlHAlignRight );
+ break;
+ default: // handle those other cases with a NULL return
+ break;
+ }
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return NRetAlignment;
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setOrientation( const uno::Any& _aOrientation ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Int32 nOrientation = 0;
+ if ( !( _aOrientation >>= nOrientation ) )
+ throw uno::RuntimeException();
+ uno::Any aVal;
+ switch( nOrientation )
+ {
+ case excel::XlOrientation::xlDownward:
+ aVal = uno::makeAny( table::CellOrientation_TOPBOTTOM);
+ break;
+ case excel::XlOrientation::xlHorizontal:
+ aVal = uno::makeAny( table::CellOrientation_STANDARD );
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ROTANG ) ), uno::makeAny( sal_Int32(0) ) );
+ break;
+ case excel::XlOrientation::xlUpward:
+ aVal = uno::makeAny( table::CellOrientation_BOTTOMTOP);
+ break;
+ case excel::XlOrientation::xlVertical:
+ aVal = uno::makeAny( table::CellOrientation_STACKED);
+ break;
+ }
+ // #FIXME what about the default case above?
+ // shouldn't need the test below
+ if ( aVal.hasValue() )
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLORI ) ), aVal );
+
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getOrientation( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any NRetOrientation = aNULL();
+ try
+ {
+ if (!isAmbiguous(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLORI ) )))
+ {
+ table::CellOrientation aOrientation = table::CellOrientation_STANDARD;
+ if ( !( mxPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLORI ) ) ) >>= aOrientation ) )
+ throw uno::RuntimeException();
+
+ switch(aOrientation)
+ {
+ case table::CellOrientation_STANDARD:
+ NRetOrientation = uno::makeAny( excel::XlOrientation::xlHorizontal );
+ break;
+ case table::CellOrientation_BOTTOMTOP:
+ NRetOrientation = uno::makeAny( excel::XlOrientation::xlUpward );
+ break;
+ case table::CellOrientation_TOPBOTTOM:
+ NRetOrientation = uno::makeAny( excel::XlOrientation::xlDownward );
+ break;
+ case table::CellOrientation_STACKED:
+ NRetOrientation = uno::makeAny( excel::XlOrientation::xlVertical );
+ break;
+ default:
+ NRetOrientation = uno::makeAny( excel::XlOrientation::xlHorizontal );
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return NRetOrientation;
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setWrapText( const uno::Any& _aWrapText ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_WRAP ) ), _aWrapText);
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getWrapText( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aWrap = aNULL();
+ try
+ {
+ rtl::OUString aPropName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_WRAP ) ) );
+ if (!isAmbiguous( aPropName ))
+ {
+ aWrap = mxPropertySet->getPropertyValue(aPropName);
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return aWrap;
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::Borders( const uno::Any& Index ) throw (script::BasicErrorException, uno::RuntimeException )
+{
+ ScVbaPalette aPalette( excel::getDocShell( mxModel ) );
+ uno::Reference< XCollection > xColl = new ScVbaBorders( thisHelperIface(), ScVbaFormat_BASE::mxContext, uno::Reference< table::XCellRange >( mxPropertySet, uno::UNO_QUERY_THROW ), aPalette );
+
+ if ( Index.hasValue() )
+ {
+ return xColl->Item( Index, uno::Any() );
+ }
+ return uno::makeAny( xColl );
+}
+
+template< typename Ifc1 >
+uno::Reference< excel::XFont > SAL_CALL
+ScVbaFormat<Ifc1>::Font( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ ScVbaPalette aPalette( excel::getDocShell( mxModel ) );
+ return new ScVbaFont( thisHelperIface(), ScVbaFormat_BASE::mxContext, aPalette, mxPropertySet );
+}
+
+template< typename Ifc1 >
+uno::Reference< excel::XInterior > SAL_CALL
+ScVbaFormat<Ifc1>::Interior( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return new ScVbaInterior( thisHelperIface(), ScVbaFormat_BASE::mxContext, mxPropertySet );
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getNumberFormatLocal( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aRet = uno::makeAny( rtl::OUString() );
+ try
+ {
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_NUMBERFO ) );
+ if (!isAmbiguous( sPropName ))
+ {
+
+ initializeNumberFormats();
+
+ sal_Int32 nFormat = 0;
+ if ( ! (mxPropertySet->getPropertyValue( sPropName ) >>= nFormat ) )
+ throw uno::RuntimeException();
+
+ rtl::OUString sFormat;
+ xNumberFormats->getByKey(nFormat)->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( FORMATSTRING ))) >>= sFormat;
+ aRet = uno::makeAny( sFormat.toAsciiLowerCase() );
+
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return aRet;
+
+}
+
+template< typename Ifc1 >
+void
+ScVbaFormat<Ifc1>::setNumberFormat( lang::Locale _aLocale, const rtl::OUString& _sFormatString) throw( script::BasicErrorException )
+{
+ try
+ {
+ initializeNumberFormats();
+ sal_Int32 nFormat = xNumberFormats->queryKey(_sFormatString, _aLocale , sal_True);
+ if (nFormat == -1)
+ {
+ xNumberFormats->addNew(_sFormatString, _aLocale);
+ }
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_NUMBERFO ) ), uno::makeAny( nFormat ) );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setNumberFormatLocal( const uno::Any& _oLocalFormatString ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ rtl::OUString sLocalFormatString;
+ sal_Int32 nFormat = -1;
+ rtl::OUString sNumFormat( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_NUMBERFO ) );
+ if ( !(_oLocalFormatString >>= sLocalFormatString )
+ || !( mxPropertySet->getPropertyValue(sNumFormat) >>= nFormat ) )
+ throw uno::RuntimeException();
+
+ sLocalFormatString = sLocalFormatString.toAsciiUpperCase();
+ initializeNumberFormats();
+ lang::Locale aRangeLocale;
+ xNumberFormats->getByKey(nFormat)->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALE ) ) ) >>= aRangeLocale;
+ sal_Int32 nNewFormat = xNumberFormats->queryKey(sLocalFormatString, aRangeLocale, sal_True);
+
+ if (nNewFormat == -1)
+ nNewFormat = xNumberFormats->addNew(sLocalFormatString, aRangeLocale);
+ mxPropertySet->setPropertyValue(sNumFormat, uno::makeAny( nNewFormat ));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setNumberFormat( const uno::Any& _oFormatString ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ rtl::OUString sFormatString;
+ if ( !( _oFormatString >>= sFormatString ) )
+ throw uno::RuntimeException();
+
+ sFormatString = sFormatString.toAsciiUpperCase();
+
+ lang::Locale aDefaultLocale = m_aDefaultLocale;
+ initializeNumberFormats();
+ sal_Int32 nFormat = xNumberFormats->queryKey(sFormatString, aDefaultLocale, sal_True);
+
+ if (nFormat == -1)
+ nFormat = xNumberFormats->addNew(sFormatString, aDefaultLocale);
+
+ lang::Locale aRangeLocale;
+ xNumberFormats->getByKey(nFormat)->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALE ) ) ) >>= aRangeLocale;
+ sal_Int32 nNewFormat = xNumberFormatTypes->getFormatForLocale(nFormat, aRangeLocale);
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_NUMBERFO ) ), uno::makeAny( nNewFormat));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setIndentLevel( const uno::Any& _aLevel ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Int32 nLevel = 0;
+ if ( !(_aLevel >>= nLevel ) )
+ throw uno::RuntimeException();
+ table::CellHoriJustify aAPIAlignment = table::CellHoriJustify_STANDARD;
+
+ rtl::OUString sHoriJust( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLHJUS ) );
+ if ( !( mxPropertySet->getPropertyValue(sHoriJust) >>= aAPIAlignment ) )
+ throw uno::RuntimeException();
+ if (aAPIAlignment == table::CellHoriJustify_STANDARD)
+ mxPropertySet->setPropertyValue( sHoriJust, uno::makeAny( table::CellHoriJustify_LEFT) ) ;
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_PINDENT ) ), uno::makeAny( sal_Int16(nLevel * 352.8) ) );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getIndentLevel( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any NRetIndentLevel = aNULL();
+ try
+ {
+ rtl::OUString sParaIndent( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_PINDENT ) );
+ if (!isAmbiguous(sParaIndent))
+ {
+ sal_Int16 IndentLevel = 0;
+ if ( ( mxPropertySet->getPropertyValue(sParaIndent) >>= IndentLevel ) )
+ NRetIndentLevel = uno::makeAny( sal_Int32( rtl::math::round(static_cast<double>( IndentLevel ) / 352.8)) );
+ else
+ NRetIndentLevel = uno::makeAny( sal_Int32(0) );
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return NRetIndentLevel;
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setLocked( const uno::Any& _aLocked ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Bool bIsLocked = sal_False;
+ if ( !( _aLocked >>= bIsLocked ) )
+ throw uno::RuntimeException();
+ util::CellProtection aCellProtection;
+ rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) );
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aCellProtection.IsLocked = bIsLocked;
+ mxPropertySet->setPropertyValue(sCellProt, uno::makeAny( aCellProtection ) );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setFormulaHidden( const uno::Any& FormulaHidden ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Bool bIsFormulaHidden = sal_False;
+ FormulaHidden >>= bIsFormulaHidden;
+ util::CellProtection aCellProtection;
+ rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) );
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aCellProtection.IsFormulaHidden = bIsFormulaHidden;
+ mxPropertySet->setPropertyValue(sCellProt,uno::makeAny(aCellProtection));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception( SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getLocked( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aCellProtection = aNULL();
+ try
+ {
+ rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) );
+
+ if (!isAmbiguous(sCellProt))
+ {
+ SfxItemSet* pDataSet = getCurrentDataSet();
+ if ( pDataSet )
+ {
+ const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) pDataSet->Get(ATTR_PROTECTION, TRUE);
+ SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL);
+ if(eState != SFX_ITEM_DONTCARE)
+ aCellProtection = uno::makeAny(rProtAttr.GetProtection());
+ }
+ else // fallback to propertyset
+ {
+ util::CellProtection cellProtection;
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aCellProtection = uno::makeAny( cellProtection.IsLocked );
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return aCellProtection;
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getFormulaHidden( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aBoolRet = aNULL();
+ try
+ {
+ rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) );
+ if (!isAmbiguous(sCellProt))
+ {
+ SfxItemSet* pDataSet = getCurrentDataSet();
+ if ( pDataSet )
+ {
+ const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) pDataSet->Get(ATTR_PROTECTION, TRUE);
+ SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL);
+ if(eState != SFX_ITEM_DONTCARE)
+ aBoolRet = uno::makeAny(rProtAttr.GetHideFormula());
+ }
+ else
+ {
+ util::CellProtection aCellProtection;
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aBoolRet = uno::makeAny( aCellProtection.IsFormulaHidden );
+ }
+ }
+ }
+ catch (uno::Exception e)
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return aBoolRet;
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setShrinkToFit( const uno::Any& ShrinkToFit ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ mxPropertySet->setPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SHRINK_TO_FIT ) ), ShrinkToFit);
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString() );
+ }
+
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getShrinkToFit( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aRet = aNULL();
+ try
+ {
+ rtl::OUString sShrinkToFit( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SHRINK_TO_FIT ) );
+ if (!isAmbiguous(sShrinkToFit))
+ aRet = mxPropertySet->getPropertyValue(sShrinkToFit);
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ }
+ return aRet;
+}
+
+template< typename Ifc1 >
+void SAL_CALL
+ScVbaFormat<Ifc1>::setReadingOrder( const uno::Any& ReadingOrder ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Int32 nReadingOrder = 0;
+ if ( !(ReadingOrder >>= nReadingOrder ))
+ throw uno::RuntimeException();
+ uno::Any aVal;
+ switch(nReadingOrder)
+ {
+ case excel::Constants::xlLTR:
+ aVal = uno::makeAny( text::WritingMode_LR_TB );
+ break;
+ case excel::Constants::xlRTL:
+ aVal = uno::makeAny( text::WritingMode_RL_TB );
+ break;
+ case excel::Constants::xlContext:
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ break;
+ default:
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ mxPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_WRITING ) ), aVal );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat<Ifc1>::getReadingOrder( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any NRetReadingOrder = aNULL();
+ try
+ {
+ rtl::OUString sWritingMode( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_WRITING ) );
+ if (!isAmbiguous(sWritingMode))
+ {
+ text::WritingMode aWritingMode = text::WritingMode_LR_TB;
+ if ( ( mxPropertySet->getPropertyValue(sWritingMode) ) >>= aWritingMode )
+ switch (aWritingMode){
+ case text::WritingMode_LR_TB:
+ NRetReadingOrder = uno::makeAny(excel::Constants::xlLTR);
+ break;
+ case text::WritingMode_RL_TB:
+ NRetReadingOrder = uno::makeAny(excel::Constants::xlRTL);
+ break;
+ default:
+ NRetReadingOrder = uno::makeAny(excel::Constants::xlRTL);
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ }
+ return NRetReadingOrder;
+
+}
+
+template< typename Ifc1 >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc1 >::getNumberFormat( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Any aFormat = aNULL();
+ try
+ {
+ sal_Int32 nFormat = -1;
+ rtl::OUString sNumFormat( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_NUMBERFO ) );
+ if (!isAmbiguous(sNumFormat) &&
+ ( mxPropertySet->getPropertyValue(sNumFormat) >>= nFormat) )
+ {
+ initializeNumberFormats();
+
+ sal_Int32 nNewFormat = xNumberFormatTypes->getFormatForLocale(nFormat, getDefaultLocale() );
+ rtl::OUString sFormat;
+ xNumberFormats->getByKey(nNewFormat)->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( FORMATSTRING ))) >>= sFormat;
+ aFormat = uno::makeAny( sFormat );
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return aFormat;
+}
+
+template< typename Ifc1 >
+bool
+ScVbaFormat<Ifc1>::isAmbiguous(const rtl::OUString& _sPropertyName) throw ( script::BasicErrorException )
+{
+ bool bResult = false;
+ try
+ {
+ if (mbCheckAmbiguoity)
+ bResult = ( getXPropertyState()->getPropertyState(_sPropertyName) == beans::PropertyState_AMBIGUOUS_VALUE );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return bResult;
+}
+
+template< typename Ifc1 >
+void
+ScVbaFormat<Ifc1>::initializeNumberFormats() throw ( script::BasicErrorException )
+{
+ if ( !xNumberFormats.is() )
+ {
+ mxNumberFormatsSupplier.set( mxModel, uno::UNO_QUERY_THROW );
+ xNumberFormats = mxNumberFormatsSupplier->getNumberFormats();
+ xNumberFormatTypes.set( xNumberFormats, uno::UNO_QUERY ); // _THROW?
+ }
+}
+
+template< typename Ifc1 >
+uno::Reference< beans::XPropertyState >
+ScVbaFormat<Ifc1>::getXPropertyState() throw ( uno::RuntimeException )
+{
+ if ( !xPropertyState.is() )
+ xPropertyState.set( mxPropertySet, uno::UNO_QUERY_THROW );
+ return xPropertyState;
+}
+
+template< typename Ifc1 >
+rtl::OUString&
+ScVbaFormat<Ifc1>::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFormat") );
+ return sImplName;
+}
+
+template< typename Ifc1 >
+uno::Sequence< rtl::OUString >
+ScVbaFormat<Ifc1>::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Format" ) );
+ }
+ return aServiceNames;
+}
+
+template< typename Ifc1 >
+ScCellRangesBase*
+ScVbaFormat<Ifc1>::getCellRangesBase() throw ( ::uno::RuntimeException )
+{
+ return ScCellRangesBase::getImplementation( mxPropertySet );
+}
+
+template< typename Ifc1 >
+SfxItemSet*
+ScVbaFormat<Ifc1>::getCurrentDataSet( ) throw ( uno::RuntimeException )
+{
+ SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() );
+ if ( !pDataSet )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for XPropertySet" ) ), uno::Reference< uno::XInterface >() );
+ return pDataSet;
+}
+
+
+template class ScVbaFormat< excel::XStyle >;
+template class ScVbaFormat< excel::XRange >;
+
+
diff --git a/sc/source/ui/vba/vbaformat.hxx b/sc/source/ui/vba/vbaformat.hxx
new file mode 100644
index 000000000000..bfa88d6c7cb8
--- /dev/null
+++ b/sc/source/ui/vba/vbaformat.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_FORMAT_HXX
+#define SC_VBA_FORMAT_HXX
+#include <ooo/vba/excel/XFormat.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+class ScCellRangesBase;
+
+template< typename Ifc1 >
+class ScVbaFormat : public InheritedHelperInterfaceImpl1< Ifc1 >
+{
+typedef InheritedHelperInterfaceImpl1< Ifc1 > ScVbaFormat_BASE;
+ css::lang::Locale m_aDefaultLocale;
+protected:
+ css::lang::Locale getDefaultLocale() { return m_aDefaultLocale; }
+ css::uno::Reference< css::beans::XPropertySet > mxPropertySet;
+ css::uno::Reference< css::util::XNumberFormatsSupplier > mxNumberFormatsSupplier;
+ css::uno::Reference< css::util::XNumberFormats > xNumberFormats;
+ css::uno::Reference< css::util::XNumberFormatTypes > xNumberFormatTypes;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::lang::XServiceInfo > mxServiceInfo;
+ css::uno::Reference< css::beans::XPropertyState > xPropertyState;
+ sal_Bool mbCheckAmbiguoity;
+ sal_Bool mbAddIndent;
+ //NumberFormatter oNumberFormatter = null;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xMultiServiceFactory;
+ bool isAmbiguous(const rtl::OUString& _sPropertyName) throw ( css::script::BasicErrorException );
+ css::uno::Reference< css::beans::XPropertyState > getXPropertyState() throw ( css::uno::RuntimeException );
+ void initializeNumberFormats() throw ( css::script::BasicErrorException );
+ void setNumberFormat( css::lang::Locale _aLocale, const rtl::OUString& _sFormatString) throw( css::script::BasicErrorException );
+ SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException );
+protected:
+ virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException );
+public:
+ ScVbaFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& xModel, bool bCheckAmbiguoity ) throw ( css::script::BasicErrorException );
+ virtual ~ScVbaFormat() {}
+ virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() = 0;
+ css::uno::Reference< css::lang::XServiceInfo > getXServiceInfo() { return mxServiceInfo; }
+ void SAL_CALL setAddIndent( const css::uno::Any& _BAddIndent) throw( css::uno::RuntimeException ) { _BAddIndent >>= mbAddIndent; }
+ css::uno::Any SAL_CALL getAddIndent() throw( css::uno::RuntimeException ) { return css::uno::makeAny( mbAddIndent ); }
+ // Interface Methods
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& Index ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ::ooo::vba::excel::XFont > SAL_CALL Font( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ::ooo::vba::excel::XInterior > SAL_CALL Interior( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setNumberFormat( const css::uno::Any& NumberFormat ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getNumberFormat( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setNumberFormatLocal( const css::uno::Any& NumberFormatLocal ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getNumberFormatLocal( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setIndentLevel( const css::uno::Any& IndentLevel ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getIndentLevel( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setHorizontalAlignment( const css::uno::Any& HorizontalAlignment ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getHorizontalAlignment( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setVerticalAlignment( const css::uno::Any& VerticalAlignment ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getVerticalAlignment( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setOrientation( const css::uno::Any& Orientation ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getOrientation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setShrinkToFit( const css::uno::Any& ShrinkToFit ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getShrinkToFit( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setWrapText( const css::uno::Any& WrapText ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getWrapText( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setLocked( const css::uno::Any& Locked ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getLocked( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setFormulaHidden( const css::uno::Any& FormulaHidden ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFormulaHidden( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& MergeCells ) throw (css::script::BasicErrorException, css::uno::RuntimeException) = 0;
+ virtual css::uno::Any SAL_CALL getMergeCells( ) throw (css::script::BasicErrorException, css::uno::RuntimeException) = 0;
+ virtual void SAL_CALL setReadingOrder( const css::uno::Any& ReadingOrder ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getReadingOrder( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif
diff --git a/sc/source/ui/vba/vbaformatcondition.cxx b/sc/source/ui/vba/vbaformatcondition.cxx
new file mode 100644
index 000000000000..99d8a579956a
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatcondition.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbaformatcondition.hxx"
+#include "vbaformatconditions.hxx"
+#include <ooo/vba/excel/XlFormatConditionType.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaFormatConditions*
+lcl_getScVbaFormatConditionsPtr( const uno::Reference< excel::XFormatConditions >& xFormatConditions ) throw ( script::BasicErrorException )
+{
+ ScVbaFormatConditions* pFormatConditions = static_cast< ScVbaFormatConditions* >( xFormatConditions.get() );
+ if ( !pFormatConditions )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ return pFormatConditions;
+}
+ScVbaFormatCondition::ScVbaFormatCondition( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntry >& _xSheetConditionalEntry, const uno::Reference< excel::XStyle >& _xStyle, const uno::Reference< excel::XFormatConditions >& _xFormatConditions, const uno::Reference< css::beans::XPropertySet >& _xPropertySet ) throw ( css::uno::RuntimeException ) : ScVbaFormatCondition_BASE( xParent, xContext, uno::Reference< sheet::XSheetCondition >( _xSheetConditionalEntry, css::uno::UNO_QUERY_THROW ) ), moFormatConditions( _xFormatConditions ), mxStyle( _xStyle ), mxParentRangePropertySet( _xPropertySet )
+{
+ mxSheetConditionalEntries = lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getSheetConditionalEntries();
+
+ mxSheetConditionalEntry = _xSheetConditionalEntry;
+ msStyleName = mxStyle->getName();
+}
+
+
+void SAL_CALL
+ScVbaFormatCondition::Delete( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ ScVbaFormatConditions* pFormatConditions = lcl_getScVbaFormatConditionsPtr( moFormatConditions );
+ pFormatConditions->removeFormatCondition(msStyleName, sal_True);
+ notifyRange();
+}
+
+void SAL_CALL
+ScVbaFormatCondition::Modify( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2 ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ ScVbaFormatConditions* pFormatConditions = lcl_getScVbaFormatConditionsPtr( moFormatConditions );
+ pFormatConditions->removeFormatCondition(msStyleName, sal_False);
+ pFormatConditions->Add(_nType, _aOperator, _aFormula1, _aFormula2, mxStyle);
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+uno::Reference< excel::XInterior > SAL_CALL
+ScVbaFormatCondition::Interior( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return mxStyle->Interior();
+}
+
+uno::Reference< excel::XFont > SAL_CALL
+ScVbaFormatCondition::Font( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return mxStyle->Font();
+}
+uno::Any SAL_CALL
+ScVbaFormatCondition::Borders( const uno::Any& Index ) throw (script::BasicErrorException, uno::RuntimeException)
+{ return mxStyle->Borders( Index );
+}
+
+sheet::ConditionOperator
+ScVbaFormatCondition::retrieveAPIType(sal_Int32 _nVBAType, const uno::Reference< sheet::XSheetCondition >& _xSheetCondition ) throw ( script::BasicErrorException )
+{
+ sheet::ConditionOperator aAPIType = sheet::ConditionOperator_NONE;
+ switch (_nVBAType)
+ {
+ case excel::XlFormatConditionType::xlExpression:
+ aAPIType = sheet::ConditionOperator_FORMULA;
+ break;
+ case excel::XlFormatConditionType::xlCellValue:
+ if ( _xSheetCondition.is() && (_xSheetCondition->getOperator() == sheet::ConditionOperator_FORMULA ) )
+ aAPIType = sheet::ConditionOperator_NONE;
+ break;
+ default:
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return aAPIType;
+}
+
+void
+ScVbaFormatCondition::setFormula1( const uno::Any& _aFormula1) throw ( script::BasicErrorException )
+{
+ // getA1Formula *SHOULD* detect whether the formula is r1c1 or A1 syntax
+ // and if R1C1 convert to A1
+ ScVbaFormatCondition_BASE::setFormula1( uno::makeAny( lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getA1Formula(_aFormula1) ) );
+}
+
+void
+ScVbaFormatCondition::setFormula2( const uno::Any& _aFormula2) throw ( script::BasicErrorException )
+{
+ ScVbaFormatCondition_BASE::setFormula1( uno::makeAny( lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getA1Formula(_aFormula2)) );
+}
+
+::sal_Int32 SAL_CALL
+ScVbaFormatCondition::Type( ) throw ( script::BasicErrorException, uno::RuntimeException )
+{
+ sal_Int32 nReturnType = 0;
+ if ( mxSheetCondition->getOperator() == sheet::ConditionOperator_FORMULA)
+ nReturnType = excel::XlFormatConditionType::xlExpression;
+ else
+ nReturnType = excel::XlFormatConditionType::xlCellValue;
+ return nReturnType;
+}
+
+
+::sal_Int32
+ScVbaFormatCondition::Operator( sal_Bool bVal ) throw (script::BasicErrorException )
+{
+ return ScVbaFormatCondition_BASE::Operator( bVal );
+}
+::sal_Int32 SAL_CALL
+ScVbaFormatCondition::Operator( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return ScVbaFormatCondition_BASE::Operator( sal_True );
+}
+
+void
+ScVbaFormatCondition::notifyRange() throw ( script::BasicErrorException )
+{
+ try
+ {
+ mxParentRangePropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConditionalFormat") ), uno::makeAny( mxSheetConditionalEntries) );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+}
+
+rtl::OUString&
+ScVbaFormatCondition::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFormatCondition") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaFormatCondition::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.FormatCondition" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbaformatcondition.hxx b/sc/source/ui/vba/vbaformatcondition.hxx
new file mode 100644
index 000000000000..075dbf658203
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatcondition.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_FORMATCONDITION_HXX
+#define SC_VBA_FORMATCONDITION_HXX
+#include <ooo/vba/excel/XFormatCondition.hpp>
+#include <ooo/vba/excel/XFormatConditions.hpp>
+#include <ooo/vba/excel/XStyle.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "vbacondition.hxx"
+
+typedef ScVbaCondition< ov::excel::XFormatCondition > ScVbaFormatCondition_BASE;
+class ScVbaFormatCondition : public ScVbaFormatCondition_BASE
+{
+protected:
+ rtl::OUString msStyleName;
+ css::uno::Reference< css::sheet::XSheetConditionalEntry > mxSheetConditionalEntry;
+ css::uno::Reference< css::sheet::XSheetConditionalEntries > mxSheetConditionalEntries;
+ css::uno::Reference< ov::excel::XFormatConditions> moFormatConditions;
+ css::uno::Reference< ov::excel::XStyle > mxStyle;
+ css::uno::Reference< css::beans::XPropertySet > mxParentRangePropertySet;
+public:
+ ScVbaFormatCondition( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::sheet::XSheetConditionalEntry >& _xSheetConditionalEntry, const css::uno::Reference< ov::excel::XStyle >&, const css::uno::Reference< ov::excel::XFormatConditions >& _xFormatConditions, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet ) throw ( css::uno::RuntimeException );
+
+ void notifyRange() throw ( css::script::BasicErrorException );
+ static css::sheet::ConditionOperator retrieveAPIType(sal_Int32 _nVBAType, const css::uno::Reference< css::sheet::XSheetCondition >& _xSheetCondition ) throw( css::script::BasicErrorException );
+
+ //Methods
+ virtual void SAL_CALL Delete( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Modify( ::sal_Int32 Type, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2 ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL Type( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 Operator( sal_Bool ) throw (css::script::BasicErrorException);
+ virtual ::sal_Int32 SAL_CALL Operator( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void setFormula1( const css::uno::Any& _aFormula1) throw ( css::script::BasicErrorException );
+ virtual void setFormula2( const css::uno::Any& _aFormula2) throw ( css::script::BasicErrorException );
+ virtual css::uno::Reference< ::ooo::vba::excel::XInterior > SAL_CALL Interior( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& Index ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ::ooo::vba::excel::XFont > SAL_CALL Font( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
diff --git a/sc/source/ui/vba/vbaformatconditions.cxx b/sc/source/ui/vba/vbaformatconditions.cxx
new file mode 100644
index 000000000000..8dd67843ec00
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatconditions.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <vector>
+#include "vbaformatconditions.hxx"
+#include "vbaformatcondition.hxx"
+#include "vbaworkbook.hxx"
+#include "vbastyles.hxx"
+#include "vbaglobals.hxx"
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+typedef std::vector< beans::PropertyValue > VecPropValues;
+
+static rtl::OUString OPERATOR( RTL_CONSTASCII_USTRINGPARAM("Operator") );
+static rtl::OUString FORMULA1( RTL_CONSTASCII_USTRINGPARAM("Formula1") );
+static rtl::OUString FORMULA2( RTL_CONSTASCII_USTRINGPARAM("Formula2") );
+static rtl::OUString STYLENAME( RTL_CONSTASCII_USTRINGPARAM("StyleName") );
+static rtl::OUString sStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM("Excel_CondFormat") );
+
+ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntries >& _xSheetConditionalEntries, const uno::Reference< frame::XModel >& /*xModel*/ ) : ScVbaFormatConditions_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( _xSheetConditionalEntries, uno::UNO_QUERY_THROW ) ), mxSheetConditionalEntries( _xSheetConditionalEntries )
+{
+ mxRangeParent.set( xParent, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XApplication> xApp( Application(), uno::UNO_QUERY_THROW );
+ mxStyles.set( xApp->getThisWorkbook()->Styles( uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeAddressable > xCellRange( mxRangeParent->getCellRange(), uno::UNO_QUERY_THROW );
+ mxParentRangePropertySet.set( xCellRange, uno::UNO_QUERY_THROW );
+
+ table::CellRangeAddress rangeAddress = xCellRange->getRangeAddress();
+ maCellAddress = table::CellAddress( rangeAddress.Sheet, rangeAddress.StartColumn, rangeAddress.StartRow );
+}
+
+void SAL_CALL
+ScVbaFormatConditions::Delete( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() );
+ if ( !pStyles )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ sal_Int32 nCount = mxSheetConditionalEntries->getCount();
+ for (sal_Int32 i = nCount - 1; i >= 0; i--)
+ {
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW );
+ pStyles->Delete(xSheetConditionalEntry->getStyleName());
+ mxSheetConditionalEntries->removeByIndex(i);
+ }
+ notifyRange();
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+uno::Type SAL_CALL
+ScVbaFormatConditions::getElementType() throw (css::uno::RuntimeException)
+{
+ return excel::XFormatCondition::static_type(0);
+}
+
+
+uno::Any xSheetConditionToFormatCondition( const uno::Reference< XHelperInterface >& xRangeParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< excel::XStyles >& xStyles, const uno::Reference< excel::XFormatConditions >& xFormatConditions, const uno::Reference< beans::XPropertySet >& xRangeProps, const uno::Any& aObject )
+{
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry;
+ aObject >>= xSheetConditionalEntry;
+
+ uno::Reference< excel::XStyle > xStyle( xStyles->Item( uno::makeAny( xSheetConditionalEntry->getStyleName() ), uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XFormatCondition > xCondition = new ScVbaFormatCondition( xRangeParent, xContext, xSheetConditionalEntry, xStyle, xFormatConditions, xRangeProps );
+ return uno::makeAny( xCondition );
+}
+
+uno::Any
+ScVbaFormatConditions::createCollectionObject(const uno::Any& aObject )
+{
+ return xSheetConditionToFormatCondition( uno::Reference< XHelperInterface >( mxRangeParent, uno::UNO_QUERY_THROW ), mxContext, mxStyles, this, mxParentRangePropertySet, aObject );
+}
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ uno::Reference<excel::XRange > m_xParentRange;
+ uno::Reference<uno::XComponentContext > m_xContext;
+ uno::Reference<excel::XStyles > m_xStyles;
+ uno::Reference<excel::XFormatConditions > m_xParentCollection;
+ uno::Reference<beans::XPropertySet > m_xProps;
+
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference<excel::XRange >& xRange, const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference<excel::XStyles >& xStyles, const uno::Reference< excel::XFormatConditions >& xCollection, const uno::Reference<beans::XPropertySet >& xProps ) : m_xIndexAccess( xIndexAccess ), m_xParentRange( xRange ), m_xContext( xContext ), m_xStyles( xStyles ), m_xParentCollection( xCollection ), m_xProps( xProps ), nIndex( 0 ) {}
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return xSheetConditionToFormatCondition( uno::Reference< XHelperInterface >( m_xParentRange, uno::UNO_QUERY_THROW ), m_xContext, m_xStyles, m_xParentCollection, m_xProps, m_xIndexAccess->getByIndex( nIndex++ ) );
+ throw container::NoSuchElementException();
+ }
+};
+
+uno::Reference< excel::XFormatCondition > SAL_CALL
+ScVbaFormatConditions::Add( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2 ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return Add( _nType, _aOperator, _aFormula1, _aFormula2, uno::Reference< excel::XStyle >() );
+}
+
+uno::Reference< excel::XFormatCondition >
+ScVbaFormatConditions::Add( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2, const css::uno::Reference< excel::XStyle >& _xStyle ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ // #TODO
+ // #FIXME
+ // This method will NOT handle r1c1 formulas [*]and only assumes that
+ // the formulas are _xlA1 based ( need to hook into calc work ths should
+ // address this )
+ // [*] reason: getA1Formula method below is just a hook and just
+ // returns whats it gets ( e.g. doesn't convert anything )
+ uno::Reference< excel::XStyle > xStyle( _xStyle );
+ uno::Reference< excel::XFormatCondition > xFormatCondition;
+ try
+ {
+ rtl::OUString sStyleName;
+ if ( !xStyle.is() )
+ {
+ sStyleName = getStyleName();
+ xStyle = mxStyles->Add(sStyleName, uno::Any() );
+ }
+ else
+ {
+ sStyleName = xStyle->getName();
+ }
+
+ VecPropValues aPropertyValueVector;
+ sheet::ConditionOperator aType = ScVbaFormatCondition::retrieveAPIType(_nType, uno::Reference< sheet::XSheetCondition >() );
+ uno::Any aValue;
+
+ if ( aType == sheet::ConditionOperator_FORMULA)
+ aValue = uno::makeAny( sheet::ConditionOperator_FORMULA );
+ else
+ aValue = uno::makeAny( ScVbaFormatCondition::retrieveAPIOperator(_aOperator) );
+
+ beans::PropertyValue aProperty( OPERATOR, 0, aValue, beans::PropertyState_DIRECT_VALUE );
+ aPropertyValueVector.push_back( aProperty );
+
+ if ( _aFormula1.hasValue() )
+ {
+ beans::PropertyValue aProp( FORMULA1, 0, uno::makeAny( getA1Formula( _aFormula1 ) ), beans::PropertyState_DIRECT_VALUE );
+ aPropertyValueVector.push_back( aProp );
+ }
+ if ( _aFormula2.hasValue() )
+ {
+ beans::PropertyValue aProp( FORMULA2, 0, uno::makeAny( getA1Formula( _aFormula2 ) ), beans::PropertyState_DIRECT_VALUE );
+ aPropertyValueVector.push_back( aProp );
+ }
+ aProperty.Name = STYLENAME;
+ aProperty.Value = uno::makeAny( sStyleName );
+
+ // convert vector to sequence
+ uno::Sequence< beans::PropertyValue > aPropertyValueList(aPropertyValueVector.size());
+ VecPropValues::iterator it = aPropertyValueVector.begin();
+ VecPropValues::iterator it_end = aPropertyValueVector.end();
+ for ( sal_Int32 index=0; it != it_end; ++it )
+ aPropertyValueList[ index++ ] = *it;
+
+ mxSheetConditionalEntries->addNew(aPropertyValueList);
+ for (sal_Int32 i = mxSheetConditionalEntries->getCount()-1; i >= 0; i--)
+ {
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (xSheetConditionalEntry->getStyleName().equals(sStyleName))
+ {
+ xFormatCondition = new ScVbaFormatCondition(uno::Reference< XHelperInterface >( mxRangeParent, uno::UNO_QUERY_THROW ), mxContext, xSheetConditionalEntry, xStyle, this, mxParentRangePropertySet);
+ notifyRange();
+ return xFormatCondition;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ }
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ return xFormatCondition;
+}
+
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaFormatConditions::createEnumeration() throw (uno::RuntimeException)
+{
+ return new EnumWrapper( m_xIndexAccess, mxRangeParent, mxContext, mxStyles, this, mxParentRangePropertySet );
+}
+
+
+void
+ScVbaFormatConditions::notifyRange() throw ( script::BasicErrorException )
+{
+ try
+ {
+ mxParentRangePropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConditionalFormat")), uno::makeAny( mxSheetConditionalEntries ));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+rtl::OUString
+ScVbaFormatConditions::getA1Formula(const css::uno::Any& _aFormula) throw ( script::BasicErrorException )
+{
+ // #TODO, #FIXME hook-in proper formula conversion detection & logic
+ rtl::OUString sFormula;
+ if ( !( _aFormula >>= sFormula ) )
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ return sFormula;
+}
+
+rtl::OUString
+ScVbaFormatConditions::getStyleName()
+{
+ ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() );
+ if ( !pStyles )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ uno::Sequence< rtl::OUString > sCellStyleNames = pStyles->getStyleNames();
+ return ContainerUtilities::getUniqueName(sCellStyleNames, sStyleNamePrefix, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") ));
+}
+
+void
+ScVbaFormatConditions::removeFormatCondition( const rtl::OUString& _sStyleName, sal_Bool _bRemoveStyle) throw ( script::BasicErrorException )
+{
+ try
+ {
+ sal_Int32 nElems = mxSheetConditionalEntries->getCount();
+ for (sal_Int32 i = 0; i < nElems; i++)
+ {
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (_sStyleName.equals(xSheetConditionalEntry->getStyleName()))
+ {
+ mxSheetConditionalEntries->removeByIndex(i);
+ if (_bRemoveStyle)
+ {
+ ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() );
+ if ( !pStyles )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ pStyles->Delete( _sStyleName );
+ }
+ return;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+rtl::OUString&
+ScVbaFormatConditions::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFormatConditions") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaFormatConditions::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.FormatConditions" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbaformatconditions.hxx b/sc/source/ui/vba/vbaformatconditions.hxx
new file mode 100644
index 000000000000..7dfa065ea8b6
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatconditions.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_FORMATCONDITIONS_HXX
+#define SC_VBA_FORMATCONDITIONS_HXX
+#include <ooo/vba/excel/XFormatConditions.hpp>
+#include <ooo/vba/excel/XStyles.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XFormatConditions > ScVbaFormatConditions_BASE;
+class ScVbaFormatConditions: public ScVbaFormatConditions_BASE
+{
+ css::table::CellAddress maCellAddress;
+ css::uno::Reference< css::sheet::XSheetConditionalEntries > mxSheetConditionalEntries;
+ css::uno::Reference< ov::excel::XStyles > mxStyles;
+ css::uno::Reference< ov::excel::XRange > mxRangeParent;
+ css::uno::Reference< css::beans::XPropertySet > mxParentRangePropertySet;
+public:
+ ScVbaFormatConditions( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::sheet::XSheetConditionalEntries >&, const css::uno::Reference< css::frame::XModel >& );
+ void notifyRange() throw ( css::script::BasicErrorException );
+ virtual css::uno::Reference< ov::excel::XFormatCondition > Add( ::sal_Int32 Type, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2, const css::uno::Reference< ov::excel::XStyle >& _xCalcStyle ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ rtl::OUString getA1Formula(const css::uno::Any& _aFormula) throw ( css::script::BasicErrorException );
+ rtl::OUString getStyleName();
+ void removeFormatCondition( const rtl::OUString& _sStyleName, sal_Bool _bRemoveStyle) throw ( css::script::BasicErrorException );
+ css::uno::Reference< css::sheet::XSheetConditionalEntries > getSheetConditionalEntries() { return mxSheetConditionalEntries; }
+ // XFormatConditions
+ virtual void SAL_CALL Delete( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XFormatCondition > SAL_CALL Add( ::sal_Int32 Type, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2 ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_AXES_HXX
diff --git a/sc/source/ui/vba/vbaglobals.cxx b/sc/source/ui/vba/vbaglobals.cxx
new file mode 100644
index 000000000000..c70a7f83726d
--- /dev/null
+++ b/sc/source/ui/vba/vbaglobals.cxx
@@ -0,0 +1,304 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vbahelper/helperdecl.hxx>
+#include "vbaglobals.hxx"
+
+#include <comphelper/unwrapargs.hxx>
+
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <cppuhelper/component_context.hxx>
+
+#include "vbaapplication.hxx"
+#include "vbaworksheet.hxx"
+#include "vbarange.hxx"
+#include <cppuhelper/bootstrap.hxx>
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::ooo::vba;
+
+
+
+// =============================================================================
+// ScVbaGlobals
+// =============================================================================
+
+//ScVbaGlobals::ScVbaGlobals( css::uno::Reference< css::uno::XComponentContext >const& rxContext, ) : ScVbaGlobals_BASE( uno::Reference< XHelperInterface >(), rxContext )
+rtl::OUString sDocCtxName( RTL_CONSTASCII_USTRINGPARAM("ExcelDocumentContext") );
+
+ScVbaGlobals::ScVbaGlobals( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& rxContext ) : ScVbaGlobals_BASE( uno::Reference< XHelperInterface >(), rxContext, sDocCtxName )
+{
+ OSL_TRACE("ScVbaGlobals::ScVbaGlobals()");
+
+ uno::Sequence< beans::PropertyValue > aInitArgs( 2 );
+ aInitArgs[ 0 ].Name = rtl::OUString::createFromAscii("Application");
+ aInitArgs[ 0 ].Value = uno::makeAny( getApplication() );
+ aInitArgs[ 1 ].Name = sDocCtxName;
+ aInitArgs[ 1 ].Value = uno::makeAny( getXSomethingFromArgs< frame::XModel >( aArgs, 0 ) );
+
+ init( aInitArgs );
+}
+
+ScVbaGlobals::~ScVbaGlobals()
+{
+ OSL_TRACE("ScVbaGlobals::~ScVbaGlobals");
+}
+
+// =============================================================================
+// XGlobals
+// =============================================================================
+uno::Reference<excel::XApplication >
+ScVbaGlobals::getApplication() throw (uno::RuntimeException)
+{
+// OSL_TRACE("In ScVbaGlobals::getApplication");
+ if ( !mxApplication.is() )
+ mxApplication.set( new ScVbaApplication( mxContext) );
+ return mxApplication;
+}
+
+
+uno::Reference<excel::XApplication > SAL_CALL
+ScVbaGlobals::getExcel() throw (uno::RuntimeException)
+{
+ return getApplication();
+}
+
+
+
+uno::Reference< excel::XWorkbook > SAL_CALL
+ScVbaGlobals::getActiveWorkbook() throw (uno::RuntimeException)
+{
+// OSL_TRACE("In ScVbaGlobals::getActiveWorkbook");
+ uno::Reference< excel::XWorkbook > xWorkbook( getApplication()->getActiveWorkbook(), uno::UNO_QUERY);
+ if ( xWorkbook.is() )
+ {
+ return xWorkbook;
+ }
+// FIXME check if this is correct/desired behavior
+ throw uno::RuntimeException( rtl::OUString::createFromAscii(
+ "No activeWorkbook available" ), Reference< uno::XInterface >() );
+}
+
+
+uno::Reference< excel::XWindow > SAL_CALL
+ScVbaGlobals::getActiveWindow() throw (uno::RuntimeException)
+{
+ return getApplication()->getActiveWindow();
+}
+
+uno::Reference< excel::XWorksheet > SAL_CALL
+ScVbaGlobals::getActiveSheet() throw (uno::RuntimeException)
+{
+ return getApplication()->getActiveSheet();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::WorkBooks( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return uno::Any( getApplication()->Workbooks(aIndex) );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::WorkSheets(const uno::Any& aIndex) throw (uno::RuntimeException)
+{
+ return getApplication()->Worksheets( aIndex );
+}
+uno::Any SAL_CALL
+ScVbaGlobals::Sheets( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return WorkSheets( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Range( const uno::Any& Cell1, const uno::Any& Cell2 ) throw (uno::RuntimeException)
+{
+ return getApplication()->Range( Cell1, Cell2 );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Names( const css::uno::Any& aIndex ) throw ( uno::RuntimeException )
+{
+ return getApplication()->Names( aIndex );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::getActiveCell() throw (uno::RuntimeException)
+{
+ return getApplication()->getActiveCell();
+}
+
+uno::Reference< XAssistant > SAL_CALL
+ScVbaGlobals::getAssistant() throw (uno::RuntimeException)
+{
+ return getApplication()->getAssistant();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::getSelection() throw (uno::RuntimeException)
+{
+ return getApplication()->getSelection();
+}
+
+uno::Reference< excel::XWorkbook > SAL_CALL
+ScVbaGlobals::getThisWorkbook() throw (uno::RuntimeException)
+{
+ return getApplication()->getThisWorkbook();
+}
+void SAL_CALL
+ScVbaGlobals::Calculate() throw (::com::sun::star::script::BasicErrorException, ::com::sun::star::uno::RuntimeException)
+{
+ return getApplication()->Calculate();
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::Cells( const uno::Any& RowIndex, const uno::Any& ColumnIndex ) throw (uno::RuntimeException)
+{
+ return getApplication()->getActiveSheet()->Cells( RowIndex, ColumnIndex );
+}
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::Columns( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return getApplication()->getActiveSheet()->Columns( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::CommandBars( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< XApplicationBase > xBase( getApplication(), uno::UNO_QUERY_THROW );
+ return xBase->CommandBars( aIndex );
+}
+
+css::uno::Reference< ov::excel::XRange > SAL_CALL
+ScVbaGlobals::Union( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return getApplication()->Union( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30 );
+}
+css::uno::Reference< ov::excel::XRange > SAL_CALL
+ScVbaGlobals::Intersect( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ return getApplication()->Intersect( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30 );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Evaluate( const ::rtl::OUString& Name ) throw (uno::RuntimeException)
+{
+ return getApplication()->Evaluate( Name );
+}
+
+css::uno::Any SAL_CALL
+ScVbaGlobals::WorksheetFunction( ) throw (css::uno::RuntimeException)
+{
+ return getApplication()->WorksheetFunction();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return getApplication()->Windows( aIndex );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::Rows( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return getApplication()->getActiveSheet()->Rows( aIndex );
+
+}
+
+
+uno::Any SAL_CALL
+ScVbaGlobals::getDebug() throw (uno::RuntimeException)
+{
+ try // return empty object on error
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this );
+ uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
+ uno::Reference< uno::XInterface > xVBADebug = xServiceManager->createInstanceWithArgumentsAndContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.Debug" ) ), aArgs, mxContext );
+ return uno::Any( xVBADebug );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return uno::Any();
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ScVbaGlobals::getAvailableServiceNames( ) throw (uno::RuntimeException)
+{
+ static bool bInit = false;
+ static uno::Sequence< rtl::OUString > serviceNames( ScVbaGlobals_BASE::getAvailableServiceNames() );
+ if ( !bInit )
+ {
+ rtl::OUString names[] = {
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Range" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Workbook" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Window" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Worksheet" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Application" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Hyperlink" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.script.vba.VBASpreadsheetEventProcessor" ) )
+ };
+ sal_Int32 nExcelServices = ( sizeof( names )/ sizeof( names[0] ) );
+ sal_Int32 startIndex = serviceNames.getLength();
+ serviceNames.realloc( serviceNames.getLength() + nExcelServices );
+ for ( sal_Int32 index = 0; index < nExcelServices; ++index )
+ serviceNames[ startIndex + index ] = names[ index ];
+ bInit = true;
+ }
+ return serviceNames;
+}
+
+rtl::OUString&
+ScVbaGlobals::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaGlobals") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaGlobals::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Globals" ) );
+ }
+ return aServiceNames;
+}
+
+namespace globals
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaGlobals, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaGlobals",
+ "ooo.vba.excel.Globals" );
+}
+
diff --git a/sc/source/ui/vba/vbaglobals.hxx b/sc/source/ui/vba/vbaglobals.hxx
new file mode 100644
index 000000000000..f22e5b19faa4
--- /dev/null
+++ b/sc/source/ui/vba/vbaglobals.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_GLOBALS
+#define SC_VBA_GLOBALS
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <ooo/vba/excel/XGlobals.hpp>
+#include <ooo/vba/excel/XApplication.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+#include "excelvbahelper.hxx"
+
+#include <vbahelper/vbaglobalbase.hxx>
+ // =============================================================================
+ // class ScVbaGlobals
+ // =============================================================================
+
+typedef ::cppu::ImplInheritanceHelper1< VbaGlobalsBase, ov::excel::XGlobals > ScVbaGlobals_BASE;
+
+ class ScVbaGlobals : public ScVbaGlobals_BASE
+ {
+ css::uno::Reference< ov::excel::XApplication > mxApplication;
+ virtual css::uno::Reference<
+ ov::excel::XApplication > SAL_CALL getApplication()
+ throw (css::uno::RuntimeException);
+ public:
+
+ ScVbaGlobals( css::uno::Sequence< css::uno::Any > const& aArgs,
+ css::uno::Reference< css::uno::XComponentContext >const& rxContext );
+ //ScVbaGlobals(
+ // css::uno::Reference< css::uno::XComponentContext >const& rxContext, );
+ virtual ~ScVbaGlobals();
+
+ // XGlobals
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::XAssistant > SAL_CALL getAssistant() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Calculate( ) throw (::com::sun::star::script::BasicErrorException, ::com::sun::star::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL getSelection() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getThisWorkbook() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Cells( const css::uno::Any& RowIndex, const css::uno::Any& ColumnIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Columns( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL CommandBars( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Evaluate( const ::rtl::OUString& Name ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL WorkSheets(const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL WorkBooks(const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL WorksheetFunction( ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Sheets( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ::ooo::vba::excel::XRange > SAL_CALL Rows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) throw ( css::uno::RuntimeException );
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Intersect( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Union( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XApplication > SAL_CALL getExcel() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getDebug() throw (css::uno::RuntimeException);
+
+
+ // XMultiServiceFactory
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames( ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+ };
+#endif //
diff --git a/sc/source/ui/vba/vbahelper.cxx b/sc/source/ui/vba/vbahelper.cxx
new file mode 100644
index 000000000000..cc76b1e60125
--- /dev/null
+++ b/sc/source/ui/vba/vbahelper.cxx
@@ -0,0 +1,758 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/app.hxx>
+#include <svl/stritem.hxx>
+
+#include <docuno.hxx>
+
+#include <basic/sbx.hxx>
+#include <basic/sbstar.hxx>
+#include <rtl/math.hxx>
+
+#include <math.h>
+#include "vbahelper.hxx"
+#include "tabvwsh.hxx"
+#include "transobj.hxx"
+#include "scmod.hxx"
+#include "vbashape.hxx"
+#include "unonames.hxx"
+#include "cellsuno.hxx"
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+#define POINTTO100THMILLIMETERFACTOR 35.27778
+void unoToSbxValue( SbxVariable* pVar, const uno::Any& aValue );
+
+uno::Any sbxToUnoValue( SbxVariable* pVar );
+
+
+namespace ooo
+{
+namespace vba
+{
+
+const double Millimeter::factor = 35.27778;
+
+uno::Reference< beans::XIntrospectionAccess >
+getIntrospectionAccess( const uno::Any& aObject ) throw (uno::RuntimeException)
+{
+ static uno::Reference< beans::XIntrospection > xIntrospection;
+ if( !xIntrospection.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ xIntrospection.set( xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") ), uno::UNO_QUERY_THROW );
+ }
+ return xIntrospection->inspect( aObject );
+}
+
+uno::Reference< script::XTypeConverter >
+getTypeConverter( const uno::Reference< uno::XComponentContext >& xContext ) throw (uno::RuntimeException)
+{
+ static uno::Reference< script::XTypeConverter > xTypeConv( xContext->getServiceManager()->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter") ), xContext ), uno::UNO_QUERY_THROW );
+ return xTypeConv;
+}
+// helper method to determine if the view ( calc ) is in print-preview mode
+bool isInPrintPreview( SfxViewFrame* pView )
+{
+ sal_uInt16 nViewNo = SID_VIEWSHELL1 - SID_VIEWSHELL0;
+ if ( pView->GetObjectShell()->GetFactory().GetViewFactoryCount() >
+nViewNo && !pView->GetObjectShell()->IsInPlaceActive() )
+ {
+ SfxViewFactory &rViewFactory =
+ pView->GetObjectShell()->GetFactory().GetViewFactory(nViewNo);
+ if ( pView->GetCurViewId() == rViewFactory.GetOrdinal() )
+ return true;
+ }
+ return false;
+}
+const ::rtl::OUString REPLACE_CELLS_WARNING( RTL_CONSTASCII_USTRINGPARAM( "ReplaceCellsWarning"));
+const uno::Any&
+aNULL()
+{
+ static uno::Any aNULLL = uno::makeAny( uno::Reference< uno::XInterface >() );
+ return aNULLL;
+}
+
+class PasteCellsWarningReseter
+{
+private:
+ bool bInitialWarningState;
+ static uno::Reference< beans::XPropertySet > getGlobalSheetSettings() throw ( uno::RuntimeException )
+ {
+ static uno::Reference< beans::XPropertySet > xTmpProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ static uno::Reference<uno::XComponentContext > xContext( xTmpProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
+ static uno::Reference<lang::XMultiComponentFactory > xServiceManager(
+ xContext->getServiceManager(), uno::UNO_QUERY_THROW );
+ static uno::Reference< beans::XPropertySet > xProps( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" ) ) ,xContext ), uno::UNO_QUERY_THROW );
+ return xProps;
+ }
+
+ bool getReplaceCellsWarning() throw ( uno::RuntimeException )
+ {
+ sal_Bool res = sal_False;
+ getGlobalSheetSettings()->getPropertyValue( REPLACE_CELLS_WARNING ) >>= res;
+ return ( res == sal_True );
+ }
+
+ void setReplaceCellsWarning( bool bState ) throw ( uno::RuntimeException )
+ {
+ getGlobalSheetSettings()->setPropertyValue( REPLACE_CELLS_WARNING, uno::makeAny( bState ) );
+ }
+public:
+ PasteCellsWarningReseter() throw ( uno::RuntimeException )
+ {
+ bInitialWarningState = getReplaceCellsWarning();
+ if ( bInitialWarningState )
+ setReplaceCellsWarning( false );
+ }
+ ~PasteCellsWarningReseter()
+ {
+ if ( bInitialWarningState )
+ {
+ // don't allow dtor to throw
+ try
+ {
+ setReplaceCellsWarning( true );
+ }
+ catch ( uno::Exception& /*e*/ ){}
+ }
+ }
+};
+
+void dispatchExecute(css::uno::Reference< css::frame::XModel>& xModel, USHORT nSlot, SfxCallMode nCall)
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ SfxViewFrame* pViewFrame = NULL;
+ if ( pViewShell )
+ pViewFrame = pViewShell->GetViewFrame();
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+ if( pDispatcher )
+ {
+ pDispatcher->Execute( nSlot , nCall );
+ }
+ }
+}
+
+void
+implnPaste()
+{
+ PasteCellsWarningReseter resetWarningBox;
+ ScTabViewShell* pViewShell = getCurrentBestViewShell();
+ if ( pViewShell )
+ {
+ pViewShell->PasteFromSystem();
+ pViewShell->CellContentChanged();
+ }
+}
+
+
+void
+implnCopy()
+{
+ ScTabViewShell* pViewShell = getCurrentBestViewShell();
+ if ( pViewShell )
+ pViewShell->CopyToClip(NULL,false,false,true);
+}
+
+void
+implnCut()
+{
+ ScTabViewShell* pViewShell = getCurrentBestViewShell();
+ if ( pViewShell )
+ pViewShell->CutToClip( NULL, TRUE );
+}
+
+void implnPasteSpecial(USHORT nFlags,USHORT nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose)
+{
+ PasteCellsWarningReseter resetWarningBox;
+ sal_Bool bAsLink(sal_False), bOtherDoc(sal_False);
+ InsCellCmd eMoveMode = INS_NONE;
+
+ ScTabViewShell* pTabViewShell = ScTabViewShell::GetActiveViewShell();
+ if ( !pTabViewShell )
+ // none active, try next best
+ pTabViewShell = getCurrentBestViewShell();
+ if ( pTabViewShell )
+ {
+ ScViewData* pView = pTabViewShell->GetViewData();
+ Window* pWin = ( pView != NULL ) ? pView->GetActiveWin() : NULL;
+ if ( pView && pWin )
+ {
+ if ( bAsLink && bOtherDoc )
+ pTabViewShell->PasteFromSystem(0);//SOT_FORMATSTR_ID_LINK
+ else
+ {
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ ScDocument* pDoc = NULL;
+ if ( pOwnClip )
+ pDoc = pOwnClip->GetDocument();
+ pTabViewShell->PasteFromClip( nFlags, pDoc,
+ nFunction, bSkipEmpty, bTranspose, bAsLink,
+ eMoveMode, IDF_NONE, TRUE );
+ pTabViewShell->CellContentChanged();
+ }
+ }
+ }
+
+}
+
+ uno::Reference< frame::XModel >
+getCurrentDocument() throw (uno::RuntimeException)
+{
+ uno::Reference< frame::XModel > xModel;
+ SbxObject* pBasic = dynamic_cast< SbxObject* > ( SFX_APP()->GetBasic() );
+ SbxObject* basicChosen = pBasic ;
+ if ( basicChosen == NULL)
+ {
+ OSL_TRACE("getModelFromBasic() StarBASIC* is NULL" );
+ return xModel;
+ }
+ SbxObject* p = pBasic;
+ SbxObject* pParent = p->GetParent();
+ SbxObject* pParentParent = pParent ? pParent->GetParent() : NULL;
+
+ if( pParentParent )
+ {
+ basicChosen = pParentParent;
+ }
+ else if( pParent )
+ {
+ basicChosen = pParent;
+ }
+
+
+ uno::Any aModel;
+ SbxVariable *pCompVar = basicChosen->Find( UniString(RTL_CONSTASCII_USTRINGPARAM("ThisComponent")), SbxCLASS_OBJECT );
+
+ if ( pCompVar )
+ {
+ aModel = sbxToUnoValue( pCompVar );
+ if ( sal_False == ( aModel >>= xModel ) ||
+ !xModel.is() )
+ {
+ // trying last gasp try the current component
+ uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ // test if vba service is present
+ uno::Reference< uno::XComponentContext > xCtx( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
+ uno::Reference<lang::XMultiComponentFactory > xSMgr( xCtx->getServiceManager(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XDesktop > xDesktop (xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"), xCtx), uno::UNO_QUERY_THROW );
+ xModel.set( xDesktop->getCurrentComponent(), uno::UNO_QUERY );
+ if ( !xModel.is() )
+ {
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't extract model from basic ( its obviously not set yet ) therefore don't know the currently selected document") ), uno::Reference< uno::XInterface >() );
+ }
+ return xModel;
+ }
+ else
+ {
+ OSL_TRACE("Have model ThisComponent points to url %s",
+ ::rtl::OUStringToOString( xModel->getURL(),
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+ }
+ else
+ {
+ OSL_TRACE("Failed to get ThisComponent");
+ throw uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Can't determine the currently selected document") ),
+ uno::Reference< uno::XInterface >() );
+ }
+ return xModel;
+}
+
+ScDocShell*
+getDocShell( css::uno::Reference< css::frame::XModel>& xModel )
+{
+ uno::Reference< uno::XInterface > xIf( xModel, uno::UNO_QUERY_THROW );
+ ScModelObj* pModel = dynamic_cast< ScModelObj* >( xIf.get() );
+ ScDocShell* pDocShell = NULL;
+ if ( pModel )
+ pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
+ return pDocShell;
+
+}
+
+ScTabViewShell*
+getBestViewShell( css::uno::Reference< css::frame::XModel>& xModel )
+{
+ ScDocShell* pDocShell = getDocShell( xModel );
+ if ( pDocShell )
+ return pDocShell->GetBestViewShell();
+ return NULL;
+}
+
+ScTabViewShell*
+getCurrentBestViewShell()
+{
+ uno::Reference< frame::XModel > xModel = getCurrentDocument();
+ return getBestViewShell( xModel );
+}
+
+SfxViewFrame*
+getCurrentViewFrame()
+{
+ ScTabViewShell* pViewShell = getCurrentBestViewShell();
+ if ( pViewShell )
+ return pViewShell->GetViewFrame();
+ return NULL;
+}
+
+sal_Int32
+OORGBToXLRGB( sal_Int32 nCol )
+{
+ sal_Int32 nRed = nCol;
+ nRed &= 0x00FF0000;
+ nRed >>= 16;
+ sal_Int32 nGreen = nCol;
+ nGreen &= 0x0000FF00;
+ nGreen >>= 8;
+ sal_Int32 nBlue = nCol;
+ nBlue &= 0x000000FF;
+ sal_Int32 nRGB = ( (nBlue << 16) | (nGreen << 8) | nRed );
+ return nRGB;
+}
+sal_Int32
+XLRGBToOORGB( sal_Int32 nCol )
+{
+ sal_Int32 nBlue = nCol;
+ nBlue &= 0x00FF0000;
+ nBlue >>= 16;
+ sal_Int32 nGreen = nCol;
+ nGreen &= 0x0000FF00;
+ nGreen >>= 8;
+ sal_Int32 nRed = nCol;
+ nRed &= 0x000000FF;
+ sal_Int32 nRGB = ( (nRed << 16) | (nGreen << 8) | nBlue );
+ return nRGB;
+}
+uno::Any
+OORGBToXLRGB( const uno::Any& aCol )
+{
+ sal_Int32 nCol=0;
+ aCol >>= nCol;
+ nCol = OORGBToXLRGB( nCol );
+ return uno::makeAny( nCol );
+}
+uno::Any
+XLRGBToOORGB( const uno::Any& aCol )
+{
+ sal_Int32 nCol=0;
+ aCol >>= nCol;
+ nCol = XLRGBToOORGB( nCol );
+ return uno::makeAny( nCol );
+}
+
+void PrintOutHelper( const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& /*ActivePrinter*/, const uno::Any& /*PrintToFile*/, const uno::Any& Collate, const uno::Any& PrToFileName, css::uno::Reference< frame::XModel >& xModel, sal_Bool bUseSelection )
+{
+ sal_Int32 nTo = 0;
+ sal_Int32 nFrom = 0;
+ sal_Int16 nCopies = 1;
+ sal_Bool bPreview = sal_False;
+ sal_Bool bCollate = sal_False;
+ sal_Bool bSelection = bUseSelection;
+ From >>= nFrom;
+ To >>= nTo;
+ Copies >>= nCopies;
+ Preview >>= bPreview;
+ if ( nCopies > 1 ) // Collate only useful when more that 1 copy
+ Collate >>= bCollate;
+
+ rtl::OUString sRange( RTL_CONSTASCII_USTRINGPARAM( "-" ) );
+ rtl::OUString sFileName;
+
+ if (( nFrom || nTo ) )
+ {
+ if ( nFrom )
+ sRange = ( ::rtl::OUString::valueOf( nFrom ) + sRange );
+ if ( nTo )
+ sRange += ::rtl::OUString::valueOf( nTo );
+ }
+
+ if ( PrToFileName.getValue() )
+ {
+ PrToFileName >>= sFileName;
+ }
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ SfxViewFrame* pViewFrame = NULL;
+ if ( pViewShell )
+ pViewFrame = pViewShell->GetViewFrame();
+ if ( pViewFrame )
+ {
+ SfxAllItemSet aArgs( SFX_APP()->GetPool() );
+
+ SfxBoolItem sfxCollate( SID_PRINT_COLLATE, bCollate );
+ aArgs.Put( sfxCollate, sfxCollate.Which() );
+ SfxInt16Item sfxCopies( SID_PRINT_COPIES, nCopies );
+ aArgs.Put( sfxCopies, sfxCopies.Which() );
+ if ( sFileName.getLength() )
+ {
+ SfxStringItem sfxFileName( SID_FILE_NAME, sFileName);
+ aArgs.Put( sfxFileName, sfxFileName.Which() );
+
+ }
+ if ( sRange.getLength() )
+ {
+ SfxStringItem sfxRange( SID_PRINT_PAGES, sRange );
+ aArgs.Put( sfxRange, sfxRange.Which() );
+ }
+ SfxBoolItem sfxSelection( SID_SELECTION, bSelection );
+ aArgs.Put( sfxSelection, sfxSelection.Which() );
+ SfxBoolItem sfxAsync( SID_ASYNCHRON, sal_False );
+ aArgs.Put( sfxAsync, sfxAsync.Which() );
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+
+ if ( pDispatcher )
+ {
+ if ( bPreview )
+ {
+ if ( !pViewFrame->GetFrame().IsInPlace() )
+ {
+ SC_MOD()->InputEnterHandler();
+ pViewFrame->GetDispatcher()->Execute( SID_VIEWSHELL1, SFX_CALLMODE_SYNCHRON );
+ while ( isInPrintPreview( pViewFrame ) )
+ Application::Yield();
+ }
+ }
+ else
+ pDispatcher->Execute( (USHORT)SID_PRINTDOC, (SfxCallMode)SFX_CALLMODE_SYNCHRON, aArgs );
+ }
+
+ }
+
+ // #FIXME #TODO
+ // 1 ActivePrinter ( how/can we switch a printer via API? )
+ // 2 PrintToFile ( ms behaviour if this option is specified but no
+ // filename supplied 'PrToFileName' then the user will be prompted )
+ // 3 Need to check behaviour of Selected sheets with range ( e.g. From & To
+ // values ) in oOO these options are mutually exclusive
+ // 4 There is a pop up to do with transparent objects in the print source
+ // should be able to disable that via configuration for the duration
+ // of this method
+}
+
+ void PrintPreviewHelper( const css::uno::Any& /*EnableChanges*/, css::uno::Reference< css::frame::XModel >& xModel )
+{
+ dispatchExecute( xModel, SID_VIEWSHELL1 );
+}
+
+rtl::OUString getAnyAsString( const uno::Any& pvargItem ) throw ( uno::RuntimeException )
+{
+ uno::Type aType = pvargItem.getValueType();
+ uno::TypeClass eTypeClass = aType.getTypeClass();
+ rtl::OUString sString;
+ switch ( eTypeClass )
+ {
+ case uno::TypeClass_BOOLEAN:
+ {
+ sal_Bool bBool = sal_False;
+ pvargItem >>= bBool;
+ sString = rtl::OUString::valueOf( bBool );
+ break;
+ }
+ case uno::TypeClass_STRING:
+ pvargItem >>= sString;
+ break;
+ case uno::TypeClass_FLOAT:
+ {
+ float aFloat = 0;
+ pvargItem >>= aFloat;
+ sString = rtl::OUString::valueOf( aFloat );
+ break;
+ }
+ case uno::TypeClass_DOUBLE:
+ {
+ double aDouble = 0;
+ pvargItem >>= aDouble;
+ sString = rtl::OUString::valueOf( aDouble );
+ break;
+ }
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_BYTE:
+ {
+ sal_Int32 aNum = 0;
+ pvargItem >>= aNum;
+ sString = rtl::OUString::valueOf( aNum );
+ break;
+ }
+
+ case uno::TypeClass_HYPER:
+ {
+ sal_Int64 aHyper = 0;
+ pvargItem >>= aHyper;
+ sString = rtl::OUString::valueOf( aHyper );
+ break;
+ }
+ default:
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid type, can't convert" ), uno::Reference< uno::XInterface >() );
+ }
+ return sString;
+}
+
+
+rtl::OUString
+ContainerUtilities::getUniqueName( const uno::Sequence< ::rtl::OUString >& _slist, const rtl::OUString& _sElementName, const ::rtl::OUString& _sSuffixSeparator)
+{
+ return getUniqueName(_slist, _sElementName, _sSuffixSeparator, sal_Int32(2));
+}
+
+rtl::OUString
+ContainerUtilities::getUniqueName( const uno::Sequence< rtl::OUString >& _slist, const rtl::OUString _sElementName, const rtl::OUString& _sSuffixSeparator, sal_Int32 _nStartSuffix)
+{
+ sal_Int32 a = _nStartSuffix;
+ rtl::OUString scompname = _sElementName;
+ bool bElementexists = true;
+ sal_Int32 nLen = _slist.getLength();
+ if ( nLen == 0 )
+ return _sElementName;
+
+ while (bElementexists == true)
+ {
+ for (sal_Int32 i = 0; i < nLen; i++)
+ {
+ if (FieldInList(_slist, scompname) == -1)
+ {
+ return scompname;
+ }
+ }
+ scompname = _sElementName + _sSuffixSeparator + rtl::OUString::valueOf( a++ );
+ }
+ return rtl::OUString();
+}
+
+sal_Int32
+ContainerUtilities::FieldInList( const uno::Sequence< rtl::OUString >& SearchList, const rtl::OUString& SearchString )
+{
+ sal_Int32 FieldLen = SearchList.getLength();
+ sal_Int32 retvalue = -1;
+ for (sal_Int32 i = 0; i < FieldLen; i++)
+ {
+ // I wonder why comparing lexicographically is done
+ // when its a match is whats interesting?
+ //if (SearchList[i].compareTo(SearchString) == 0)
+ if ( SearchList[i].equals( SearchString ) )
+ {
+ retvalue = i;
+ break;
+ }
+ }
+ return retvalue;
+
+}
+bool NeedEsc(sal_Unicode cCode)
+{
+ String sEsc(RTL_CONSTASCII_USTRINGPARAM(".^$+\\|{}()"));
+ return (STRING_NOTFOUND != sEsc.Search(cCode));
+}
+
+rtl::OUString VBAToRegexp(const rtl::OUString &rIn, bool bForLike )
+{
+ rtl::OUStringBuffer sResult;
+ const sal_Unicode *start = rIn.getStr();
+ const sal_Unicode *end = start + rIn.getLength();
+
+ int seenright = 0;
+ if ( bForLike )
+ sResult.append(static_cast<sal_Unicode>('^'));
+
+ while (start < end)
+ {
+ switch (*start)
+ {
+ case '?':
+ sResult.append(static_cast<sal_Unicode>('.'));
+ start++;
+ break;
+ case '*':
+ sResult.append(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".*")));
+ start++;
+ break;
+ case '#':
+ sResult.append(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[0-9]")));
+ start++;
+ break;
+ case '~':
+ sResult.append(static_cast<sal_Unicode>('\\'));
+ sResult.append(*(++start));
+ start++;
+ break;
+ // dump the ~ and escape the next characture
+ case ']':
+ sResult.append(static_cast<sal_Unicode>('\\'));
+ sResult.append(*start++);
+ break;
+ case '[':
+ sResult.append(*start++);
+ seenright = 0;
+ while (start < end && !seenright)
+ {
+ switch (*start)
+ {
+ case '[':
+ case '?':
+ case '*':
+ sResult.append(static_cast<sal_Unicode>('\\'));
+ sResult.append(*start);
+ break;
+ case ']':
+ sResult.append(*start);
+ seenright = 1;
+ break;
+ case '!':
+ sResult.append(static_cast<sal_Unicode>('^'));
+ break;
+ default:
+ if (NeedEsc(*start))
+ sResult.append(static_cast<sal_Unicode>('\\'));
+ sResult.append(*start);
+ break;
+ }
+ start++;
+ }
+ break;
+ default:
+ if (NeedEsc(*start))
+ sResult.append(static_cast<sal_Unicode>('\\'));
+ sResult.append(*start++);
+ }
+ }
+
+ if ( bForLike )
+ sResult.append(static_cast<sal_Unicode>('$'));
+
+ return sResult.makeStringAndClear( );
+}
+
+double getPixelTo100thMillimeterConversionFactor( css::uno::Reference< css::awt::XDevice >& xDevice, sal_Bool bVertical)
+{
+ double fConvertFactor = 1.0;
+ if( bVertical )
+ {
+ fConvertFactor = xDevice->getInfo().PixelPerMeterY/100000;
+ }
+ else
+ {
+ fConvertFactor = xDevice->getInfo().PixelPerMeterX/100000;
+ }
+ return fConvertFactor;
+}
+
+double PointsToPixels( css::uno::Reference< css::awt::XDevice >& xDevice, double fPoints, sal_Bool bVertical)
+{
+ double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical );
+ return fPoints * POINTTO100THMILLIMETERFACTOR * fConvertFactor;
+}
+double PixelsToPoints( css::uno::Reference< css::awt::XDevice >& xDevice, double fPixels, sal_Bool bVertical)
+{
+ double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical );
+ return (fPixels/fConvertFactor)/POINTTO100THMILLIMETERFACTOR;
+}
+
+ConcreteXShapeGeometryAttributes::ConcreteXShapeGeometryAttributes( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape )
+{
+ m_xShape = new ScVbaShape( xContext, xShape );
+}
+
+#define VBA_LEFT "PositionX"
+#define VBA_TOP "PositionY"
+UserFormGeometryHelper::UserFormGeometryHelper( const uno::Reference< uno::XComponentContext >& /*xContext*/, const uno::Reference< awt::XControl >& xControl )
+{
+ mxModel.set( xControl->getModel(), uno::UNO_QUERY_THROW );
+}
+ double UserFormGeometryHelper::getLeft()
+ {
+ sal_Int32 nLeft = 0;
+ mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_LEFT ) ) ) >>= nLeft;
+ return Millimeter::getInPoints( nLeft );
+ }
+ void UserFormGeometryHelper::setLeft( double nLeft )
+ {
+ mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_LEFT ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nLeft ) ) );
+ }
+ double UserFormGeometryHelper::getTop()
+ {
+ sal_Int32 nTop = 0;
+ mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_TOP ) ) ) >>= nTop;
+ return Millimeter::getInPoints( nTop );
+ }
+ void UserFormGeometryHelper::setTop( double nTop )
+ {
+ mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_TOP ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nTop ) ) );
+ }
+ double UserFormGeometryHelper::getHeight()
+ {
+ sal_Int32 nHeight = 0;
+ mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLHGT ) ) ) >>= nHeight;
+ return Millimeter::getInPoints( nHeight );
+ }
+ void UserFormGeometryHelper::setHeight( double nHeight )
+ {
+ mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLHGT ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nHeight ) ) );
+ }
+ double UserFormGeometryHelper::getWidth()
+ {
+ sal_Int32 nWidth = 0;
+ mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLWID ) ) ) >>= nWidth;
+ return Millimeter::getInPoints( nWidth );
+ }
+ void UserFormGeometryHelper::setWidth( double nWidth)
+ {
+ mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLWID ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nWidth ) ) );
+ }
+
+SfxItemSet*
+ScVbaCellRangeAccess::GetDataSet( ScCellRangeObj* pRangeObj )
+{
+ SfxItemSet* pDataSet = pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : NULL ;
+ return pDataSet;
+
+}
+
+} // vba
+} // ooo
diff --git a/sc/source/ui/vba/vbahyperlink.cxx b/sc/source/ui/vba/vbahyperlink.cxx
new file mode 100644
index 000000000000..e37df1e118b4
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlink.cxx
@@ -0,0 +1,246 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbahyperlink.hxx"
+#include <vbahelper/helperdecl.hxx>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <ooo/vba/office/MsoHyperlinkType.hpp>
+#include <ooo/vba/msforms/XShape.hpp>
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence< uno::Any >& rArgs,
+ const uno::Reference< uno::XComponentContext >& rxContext ) throw (lang::IllegalArgumentException) :
+ HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( rArgs, 0 ), rxContext ),
+ mxCell( getXSomethingFromArgs< table::XCell >( rArgs, 1, false ) ),
+ mnType( office::MsoHyperlinkType::msoHyperlinkRange )
+{
+ uno::Reference< text::XTextFieldsSupplier > xTextFields( mxCell, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndex( xTextFields->getTextFields(), uno::UNO_QUERY_THROW );
+ mxTextField.set( xIndex->getByIndex(0), uno::UNO_QUERY_THROW );
+}
+
+ScVbaHyperlink::ScVbaHyperlink( const uno::Reference< XHelperInterface >& rxAnchor,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Any& rAddress, const uno::Any& rSubAddress,
+ const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) :
+ HyperlinkImpl_BASE( rxAnchor, rxContext ) // parent of Hyperlink is the anchor object
+{
+ // extract parameters, Address must not be empty
+ UrlComponents aUrlComp;
+ OUString aTextToDisplay;
+ if( !(rAddress >>= aUrlComp.first) || (aUrlComp.first.getLength() == 0) )
+ throw uno::RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot get address" ) ), uno::Reference< uno::XInterface >() );
+ rSubAddress >>= aUrlComp.second;
+ rScreenTip >>= maScreenTip;
+ rTextToDisplay >>= aTextToDisplay;
+
+ // get anchor range or anchor shape
+ uno::Reference< excel::XRange > xAnchorRange( rxAnchor, uno::UNO_QUERY );
+ if( xAnchorRange.is() )
+ {
+ mnType = office::MsoHyperlinkType::msoHyperlinkRange;
+ // only single ranges are allowed
+ uno::Reference< table::XCellRange > xUnoRange( ScVbaRange::getCellRange( xAnchorRange ), uno::UNO_QUERY_THROW );
+ // insert the hyperlink into the top-left cell only
+ mxCell.set( xUnoRange->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW );
+ uno::Reference< text::XText > xText( mxCell, uno::UNO_QUERY_THROW );
+ // use cell text or URL if no TextToDisplay has been passed
+ if( aTextToDisplay.getLength() == 0 )
+ {
+ aTextToDisplay = xText->getString();
+ if( aTextToDisplay.getLength() == 0 )
+ {
+ OUStringBuffer aBuffer( aUrlComp.first );
+ if( aUrlComp.second.getLength() > 0 )
+ aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) ).append( aUrlComp.second );
+ aTextToDisplay = aBuffer.makeStringAndClear();
+ }
+ }
+ // create and initialize a new URL text field
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ScVbaRange::getUnoModel( xAnchorRange ), uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextContent > xUrlField( xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextField.URL" ) ) ), uno::UNO_QUERY_THROW );
+ mxTextField.set( xUrlField, uno::UNO_QUERY_THROW );
+ setUrlComponents( aUrlComp );
+ setTextToDisplay( aTextToDisplay );
+ // insert the text field into the document
+ xText->setString( OUString() );
+ uno::Reference< text::XTextRange > xRange( xText->createTextCursor(), uno::UNO_QUERY_THROW );
+ xText->insertTextContent( xRange, xUrlField, sal_False );
+ }
+ else
+ {
+ uno::Reference< msforms::XShape > xAnchorShape( rxAnchor, uno::UNO_QUERY_THROW );
+ mnType = office::MsoHyperlinkType::msoHyperlinkShape;
+ // FIXME: insert hyperlink into shape
+ throw uno::RuntimeException();
+ }
+}
+
+ScVbaHyperlink::~ScVbaHyperlink()
+{
+}
+
+OUString ScVbaHyperlink::getName() throw (uno::RuntimeException)
+{
+ // it seems this attribute is same as TextToDisplay
+ return getTextToDisplay();
+}
+
+void ScVbaHyperlink::setName( const OUString& rName ) throw (uno::RuntimeException)
+{
+ setTextToDisplay( rName );
+}
+
+OUString ScVbaHyperlink::getAddress() throw (uno::RuntimeException)
+{
+ return getUrlComponents().first;
+}
+
+void ScVbaHyperlink::setAddress( const OUString& rAddress ) throw (uno::RuntimeException)
+{
+ UrlComponents aUrlComp = getUrlComponents();
+ aUrlComp.first = rAddress;
+ setUrlComponents( aUrlComp );
+}
+
+OUString ScVbaHyperlink::getSubAddress() throw (uno::RuntimeException)
+{
+ return getUrlComponents().second;
+}
+
+void ScVbaHyperlink::setSubAddress( const OUString& rSubAddress ) throw (uno::RuntimeException)
+{
+ UrlComponents aUrlComp = getUrlComponents();
+ aUrlComp.second = rSubAddress;
+ setUrlComponents( aUrlComp );
+}
+
+OUString SAL_CALL ScVbaHyperlink::getScreenTip() throw (uno::RuntimeException)
+{
+ return maScreenTip;
+}
+
+void SAL_CALL ScVbaHyperlink::setScreenTip( const OUString& rScreenTip ) throw (uno::RuntimeException)
+{
+ maScreenTip = rScreenTip;
+}
+
+OUString ScVbaHyperlink::getTextToDisplay() throw (uno::RuntimeException)
+{
+ ensureTextField();
+ OUString aTextToDisplay;
+ mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ) >>= aTextToDisplay;
+ return aTextToDisplay;
+}
+
+void ScVbaHyperlink::setTextToDisplay( const OUString& rTextToDisplay ) throw (uno::RuntimeException)
+{
+ ensureTextField();
+ mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), uno::Any( rTextToDisplay ) );
+}
+
+sal_Int32 SAL_CALL ScVbaHyperlink::getType() throw (uno::RuntimeException)
+{
+ return mnType;
+}
+
+uno::Reference< excel::XRange > SAL_CALL ScVbaHyperlink::getRange() throw (uno::RuntimeException)
+{
+ if( mnType == office::MsoHyperlinkType::msoHyperlinkRange )
+ {
+ // if constructed from Hyperlinks object, range has been passed as parent
+ uno::Reference< excel::XRange > xAnchorRange( getParent(), uno::UNO_QUERY );
+ if( !xAnchorRange.is() )
+ {
+ // if constructed via service c'tor, create new range based on cell
+ uno::Reference< table::XCellRange > xRange( mxCell, uno::UNO_QUERY_THROW );
+ // FIXME: need to pass current worksheet as the parent of XRange.
+ xAnchorRange.set( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRange ) );
+ }
+ return xAnchorRange;
+ }
+ // error if called at a shape Hyperlink object
+ throw uno::RuntimeException();
+}
+
+uno::Reference< msforms::XShape > SAL_CALL ScVbaHyperlink::getShape() throw (uno::RuntimeException)
+{
+ // error if called at a range Hyperlink object
+ return uno::Reference< msforms::XShape >( getParent(), uno::UNO_QUERY_THROW );
+}
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink, "ooo.vba.excel.Hyperlink" )
+
+// private --------------------------------------------------------------------
+
+void ScVbaHyperlink::ensureTextField() throw (uno::RuntimeException)
+{
+ if( !mxTextField.is() )
+ throw uno::RuntimeException();
+}
+
+ScVbaHyperlink::UrlComponents ScVbaHyperlink::getUrlComponents() throw (uno::RuntimeException)
+{
+ ensureTextField();
+ OUString aUrl;
+ mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ) >>= aUrl;
+ sal_Int32 nHashPos = aUrl.indexOf( '#' );
+ if( nHashPos < 0 )
+ return UrlComponents( aUrl, OUString() );
+ return UrlComponents( aUrl.copy( 0, nHashPos ), aUrl.copy( nHashPos + 1 ) );
+}
+
+void ScVbaHyperlink::setUrlComponents( const UrlComponents& rUrlComp ) throw (uno::RuntimeException)
+{
+ ensureTextField();
+ OUStringBuffer aUrl( rUrlComp.first );
+ if( rUrlComp.second.getLength() > 0 )
+ aUrl.append( sal_Unicode( '#' ) ).append( rUrlComp.second );
+ mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), uno::Any( aUrl.makeStringAndClear() ) );
+}
+
+namespace hyperlink
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaHyperlink, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaHyperlink",
+ "ooo.vba.excel.Hyperlink" );
+}
+
+// ============================================================================
diff --git a/sc/source/ui/vba/vbahyperlink.hxx b/sc/source/ui/vba/vbahyperlink.hxx
new file mode 100644
index 000000000000..e1520b59c15a
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlink.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_VBA_HYPERLINK_HXX
+#define SC_VBA_HYPERLINK_HXX
+
+#include <ooo/vba/excel/XHyperlink.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XHyperlink > HyperlinkImpl_BASE;
+
+class ScVbaHyperlink : public HyperlinkImpl_BASE
+{
+public:
+ ScVbaHyperlink(
+ const css::uno::Sequence< css::uno::Any >& rArgs,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::lang::IllegalArgumentException);
+
+ ScVbaHyperlink(
+ const css::uno::Reference< ov::XHelperInterface >& rxAnchor,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Any& rAddress, const css::uno::Any& rSubAddress,
+ const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) throw (css::uno::RuntimeException);
+
+ virtual ~ScVbaHyperlink();
+
+ // Attributes
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAddress( const ::rtl::OUString& rAddress ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getSubAddress() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setSubAddress( const ::rtl::OUString& rSubAddress ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getScreenTip() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setScreenTip( const ::rtl::OUString& rScreenTip ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTextToDisplay() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString& rTextToDisplay ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRange() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException);
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+private:
+ typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > UrlComponents;
+
+ void ensureTextField() throw (css::uno::RuntimeException);
+ UrlComponents getUrlComponents() throw (css::uno::RuntimeException);
+ void setUrlComponents( const UrlComponents& rUrlComp ) throw (css::uno::RuntimeException);
+
+private:
+ css::uno::Reference< css::table::XCell > mxCell;
+ css::uno::Reference< css::beans::XPropertySet > mxTextField;
+ ::rtl::OUString maScreenTip;
+ long mnType;
+};
+
+#endif /* SC_VBA_HYPERLINK_HXX */
+
diff --git a/sc/source/ui/vba/vbahyperlinks.cxx b/sc/source/ui/vba/vbahyperlinks.cxx
new file mode 100755
index 000000000000..89a8109e6aa2
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlinks.cxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbahyperlinks.hxx"
+#include <algorithm>
+#include <vector>
+#include <ooo/vba/office/MsoHyperlinkType.hpp>
+#include "rangelst.hxx"
+#include "vbahyperlink.hxx"
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+/** Returns true, if every range of rxInner is contained in any range of rScOuter. */
+bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner ) throw (uno::RuntimeException)
+{
+ const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner );
+ if( (rScInner.Count() == 0) || (rScOuter.Count() == 0) )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty range objects" ) ), uno::Reference< uno::XInterface >() );
+
+ for( ULONG nIndex = 0, nCount = rScInner.Count(); nIndex < nCount; ++nIndex )
+ if( !rScOuter.In( *rScInner.GetObject( nIndex ) ) )
+ return false;
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Functor to decide whether the anchors of two Hyperlink objects are equal. */
+struct EqualAnchorFunctor
+{
+ uno::Reference< excel::XRange > mxAnchorRange;
+ uno::Reference< msforms::XShape > mxAnchorShape;
+ sal_Int32 mnType;
+ EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException);
+ bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException);
+};
+
+EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) :
+ mnType( rxHlink->getType() )
+{
+ switch( mnType )
+ {
+ case office::MsoHyperlinkType::msoHyperlinkRange:
+ mxAnchorRange.set( rxHlink->getRange(), uno::UNO_QUERY_THROW );
+ break;
+ case office::MsoHyperlinkType::msoHyperlinkShape:
+ case office::MsoHyperlinkType::msoHyperlinkInlineShape:
+ mxAnchorShape.set( rxHlink->getShape(), uno::UNO_QUERY_THROW );
+ break;
+ default:
+ throw uno::RuntimeException();
+ }
+}
+
+bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException)
+{
+ sal_Int32 nType = rxHlink->getType();
+ if( nType != mnType )
+ return false;
+
+ switch( nType )
+ {
+ case office::MsoHyperlinkType::msoHyperlinkRange:
+ {
+ uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_QUERY_THROW );
+ const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange );
+ const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange );
+ return (rScRanges1.Count() == 1) && (rScRanges2.Count() == 1) && (*rScRanges1.GetObject( 0 ) == *rScRanges2.GetObject( 0 ));
+ }
+ case office::MsoHyperlinkType::msoHyperlinkShape:
+ case office::MsoHyperlinkType::msoHyperlinkInlineShape:
+ {
+ uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_QUERY_THROW );
+ return xAnchorShape.get() == mxAnchorShape.get();
+ }
+ default:
+ throw uno::RuntimeException();
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+namespace detail {
+
+class ScVbaHlinkContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess >
+{
+public:
+ explicit ScVbaHlinkContainer() throw (uno::RuntimeException);
+ explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges ) throw (uno::RuntimeException);
+ virtual ~ScVbaHlinkContainer();
+
+ /** Inserts the passed hyperlink into the collection. Will remove a
+ Hyperlink object with the same anchor as the passed Hyperlink object. */
+ void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException);
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException);
+
+private:
+ typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector;
+ HyperlinkVector maHlinks;
+};
+
+// ----------------------------------------------------------------------------
+
+ScVbaHlinkContainer::ScVbaHlinkContainer() throw (uno::RuntimeException)
+{
+ // TODO FIXME: fill with existing hyperlinks
+}
+
+ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer,
+ const ScRangeList& rScRanges ) throw (uno::RuntimeException)
+{
+ for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_QUERY_THROW );
+ if( lclContains( rScRanges, xHlinkRange ) )
+ maHlinks.push_back( xHlink );
+ }
+}
+
+ScVbaHlinkContainer::~ScVbaHlinkContainer()
+{
+}
+
+void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException)
+{
+ HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) );
+ if( aIt == maHlinks.end() )
+ maHlinks.push_back( rxHlink );
+ else
+ *aIt = rxHlink;
+}
+
+sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount() throw (uno::RuntimeException)
+{
+ return static_cast< sal_Int32 >( maHlinks.size() );
+}
+
+uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if( (0 <= nIndex) && (nIndex < getCount()) )
+ return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] );
+ throw lang::IndexOutOfBoundsException();
+}
+
+uno::Type SAL_CALL ScVbaHlinkContainer::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XHyperlink::static_type( 0 );
+}
+
+sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements() throw (uno::RuntimeException)
+{
+ return !maHlinks.empty();
+}
+
+// ============================================================================
+
+ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) :
+ mxContainer( pContainer )
+{
+}
+
+ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember()
+{
+}
+
+} // namespace detail
+
+// ============================================================================
+
+ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext ) throw (uno::RuntimeException) :
+ detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer ),
+ ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) )
+{
+}
+
+ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (uno::RuntimeException) :
+ detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ),
+ ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ),
+ mxSheetHlinks( rxSheetHlinks )
+{
+}
+
+ScVbaHyperlinks::~ScVbaHyperlinks()
+{
+}
+
+// XHyperlinks ----------------------------------------------------------------
+
+uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add(
+ const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress,
+ const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException)
+{
+ /* If this Hyperlinks object has been craeted from a Range object, the
+ call to Add() is passed to the Hyperlinks object of the parent
+ worksheet. This container will not be modified (it will not contain the
+ inserted hyperlink).
+ For details, see documentation in hyperlinks.hxx.
+ */
+ if( mxSheetHlinks.is() )
+ return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay );
+
+ // get anchor object (can be a Range or a Shape object)
+ uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW );
+
+ /* Create the Hyperlink object, this tries to insert the hyperlink into
+ the spreadsheet document. Parent of the Hyperlink is the anchor object. */
+ uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink(
+ xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) );
+
+ /* If creation of the hyperlink did not throw, insert it into the
+ collection. */
+ mxContainer->insertHyperlink( xHlink );
+ return xHlink;
+}
+
+void SAL_CALL ScVbaHyperlinks::Delete() throw (uno::RuntimeException)
+{
+ // FIXME not implemented
+ throw uno::RuntimeException();
+}
+
+// XEnumerationAccess ---------------------------------------------------------
+
+uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration() throw (uno::RuntimeException)
+{
+ return new SimpleIndexAccessToEnumeration( m_xIndexAccess );
+}
+
+// XElementAccess -------------------------------------------------------------
+
+uno::Type SAL_CALL ScVbaHyperlinks::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XHyperlink::static_type( 0 );
+}
+
+// ScVbaCollectionBase --------------------------------------------------------
+
+uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource )
+{
+ // container stores XHyperlink objects, just return the passed object
+ return rSource;
+}
+
+// XHelperInterface -----------------------------------------------------------
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" )
+
+// ============================================================================
diff --git a/sc/source/ui/vba/vbahyperlinks.hxx b/sc/source/ui/vba/vbahyperlinks.hxx
new file mode 100755
index 000000000000..ca7d990ad6a8
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlinks.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_VBA_HYPERLINKS_HXX
+#define SC_VBA_HYPERLINKS_HXX
+
+#include <ooo/vba/excel/XHyperlinks.hpp>
+#include <rtl/ref.hxx>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+class ScRangeList;
+
+// ============================================================================
+
+namespace detail {
+
+class ScVbaHlinkContainer;
+typedef ::rtl::Reference< ScVbaHlinkContainer > ScVbaHlinkContainerRef;
+
+/** Base class for ScVbaHyperlinks to get an initialized ScVbaHlinkContainer
+ class member before the ScVbaHyperlinks_BASE base class will be constructed.
+ */
+struct ScVbaHlinkContainerMember
+{
+ ScVbaHlinkContainerRef mxContainer;
+
+ explicit ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer );
+ ~ScVbaHlinkContainerMember();
+};
+
+} // namespace detail
+
+// ============================================================================
+
+class ScVbaHyperlinks;
+typedef ::rtl::Reference< ScVbaHyperlinks > ScVbaHyperlinksRef;
+
+typedef CollTestImplHelper< ov::excel::XHyperlinks > ScVbaHyperlinks_BASE;
+
+/** Represents a collection of hyperlinks of a worksheet or of a range.
+
+ When a Hyperlinks collection object has been constructed from a VBA
+ Worksheet object, it will always represent the current set of all
+ hyperlinks existing in the sheet. Insertion and deletion of hyperlinks will
+ be reflected by the instance.
+
+ When a Hyperlinks collection object has been constructed from a VBA Range
+ object, it will represent the set of hyperlinks that have existed at its
+ construction time, and that are located completely inside the range(s)
+ represented by the Range object. Insertion and deletion of hyperlinks will
+ *not* be reflected by that instance. The instance will always offer all
+ hyperlinks it has been constructed with, even if they no longer exist.
+ Furthermore, the instance will not offer hyperlinks inserted later, even if
+ the instance itself has been used to insert the new hyperlinks.
+
+ VBA code example:
+
+ With ThisWorkbook.Worksheets(1)
+
+ Set hlinks = .Hyperlinks ' global Hyperlinks object
+ Set myrange = .Range("A1:C3")
+ Set rangelinks1 = myrange.Hyperlinks ' hyperlinks of range A1:C3
+
+ MsgBox hlinks.Count ' 0
+ MsgBox rangelinks1.Count ' 0
+
+ hlinks.Add .Range("A1"), "http://example.com"
+ ' a new hyperlink has been added in cell A1
+
+ MsgBox hlinks.Count ' 1
+ MsgBox rangelinks1.Count ' still 0!
+ Set rangelinks2 = myrange.Hyperlinks ' hyperlinks of range A1:C3
+ MsgBox rangelinks2.Count ' 1 (constructed after Add)
+
+ rangelinks1.Add .Range("A2"), "http://example.com"
+ ' a new hyperlink has been constructed via the rangelinks1 object
+ ' but this addition has been done by the worksheet Hyperlinks object
+
+ MsgBox hlinks.Count ' 2
+ MsgBox rangelinks1.Count ' still 0!!!
+ MsgBox rangelinks2.Count ' still 1!!!
+ MsgBox myrange.Hyperlinks.Count ' 2 (constructed after Add)
+
+ End With
+ */
+class ScVbaHyperlinks : private detail::ScVbaHlinkContainerMember, public ScVbaHyperlinks_BASE
+{
+public:
+ explicit ScVbaHyperlinks(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::uno::RuntimeException);
+
+ explicit ScVbaHyperlinks(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (css::uno::RuntimeException);
+
+ virtual ~ScVbaHyperlinks();
+
+ // XHyperlinks
+ virtual css::uno::Reference< ov::excel::XHyperlink > SAL_CALL Add(
+ const css::uno::Any& rAnchor, const css::uno::Any& rAddress, const css::uno::Any& rSubAddress,
+ const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay )
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL Delete() throw (css::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+
+ // ScVbaCollectionBase
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource );
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+private:
+ ScVbaHyperlinksRef mxSheetHlinks;
+};
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/ui/vba/vbainterior.cxx b/sc/source/ui/vba/vbainterior.cxx
new file mode 100644
index 000000000000..face47767bdc
--- /dev/null
+++ b/sc/source/ui/vba/vbainterior.cxx
@@ -0,0 +1,417 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/reflection/XIdlMethod.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/xml/AttributeData.hpp>
+
+#include <ooo/vba/excel/XlColorIndex.hpp>
+#include <ooo/vba/excel/XlPattern.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/queryinterface.hxx>
+
+#include <map>
+
+#include <svx/xtable.hxx>
+
+#include "vbainterior.hxx"
+#include "vbapalette.hxx"
+#include "document.hxx"
+
+#define STATIC_TABLE_SIZE( array ) (sizeof(array)/sizeof(*(array)))
+#define COLORMAST 0xFFFFFF
+const sal_uInt16 EXC_COLOR_WINDOWBACK = 65;
+typedef std::map< sal_Int32, sal_Int32 > PatternMap;
+typedef std::pair< sal_Int32, sal_Int32 > PatternPair;
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlPattern;
+static const rtl::OUString BACKCOLOR( RTL_CONSTASCII_USTRINGPARAM( "CellBackColor" ) );
+static const rtl::OUString PATTERN( RTL_CONSTASCII_USTRINGPARAM( "Pattern" ) );
+static const rtl::OUString PATTERNCOLOR( RTL_CONSTASCII_USTRINGPARAM( "PatternColor" ) );
+
+PatternMap lcl_getPatternMap()
+{
+ PatternMap aPatternMap;
+ aPatternMap.insert( PatternPair( xlPatternAutomatic, 0 ) );
+ aPatternMap.insert( PatternPair( xlPatternChecker, 9 ) );
+ aPatternMap.insert( PatternPair( xlPatternCrissCross, 16 ) );
+ aPatternMap.insert( PatternPair( xlPatternDown, 7 ) );
+ aPatternMap.insert( PatternPair( xlPatternGray16, 17 ) );
+ aPatternMap.insert( PatternPair( xlPatternGray25, 4 ) );
+ aPatternMap.insert( PatternPair( xlPatternGray50, 2 ) );
+ aPatternMap.insert( PatternPair( xlPatternGray75, 3 ) );
+ aPatternMap.insert( PatternPair( xlPatternGray8, 18 ) );
+ aPatternMap.insert( PatternPair( xlPatternGrid, 15 ) );
+ aPatternMap.insert( PatternPair( xlPatternHorizontal, 5 ) );
+ aPatternMap.insert( PatternPair( xlPatternLightDown, 13 ) );
+ aPatternMap.insert( PatternPair( xlPatternLightHorizontal, 11 ) );
+ aPatternMap.insert( PatternPair( xlPatternLightUp, 14 ) );
+ aPatternMap.insert( PatternPair( xlPatternLightVertical, 12 ) );
+ aPatternMap.insert( PatternPair( xlPatternNone, 0 ) );
+ aPatternMap.insert( PatternPair( xlPatternSemiGray75, 10 ) );
+ aPatternMap.insert( PatternPair( xlPatternSolid, 0 ) );
+ aPatternMap.insert( PatternPair( xlPatternUp, 8 ) );
+ aPatternMap.insert( PatternPair( xlPatternVertical, 6 ) );
+ return aPatternMap;
+}
+
+static PatternMap aPatternMap( lcl_getPatternMap() );
+
+ScVbaInterior::ScVbaInterior( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< beans::XPropertySet >& xProps, ScDocument* pScDoc ) throw ( lang::IllegalArgumentException) : ScVbaInterior_BASE( xParent, xContext ), m_xProps(xProps), m_pScDoc( pScDoc )
+{
+ // auto color
+ //m_aPattColor.SetColor( (sal_uInt32)0xFFFFFFFF );
+ m_aPattColor.SetColor( (sal_uInt32)0x0 );
+ m_nPattern = 0L;
+ if ( !m_xProps.is() )
+ throw lang::IllegalArgumentException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "properties") ), uno::Reference< uno::XInterface >(), 2 );
+}
+
+uno::Any
+ScVbaInterior::getColor() throw (uno::RuntimeException)
+{
+ Color aBackColor( GetBackColor() );
+ return uno::makeAny( OORGBToXLRGB( aBackColor.GetColor() ) );
+}
+
+void
+ScVbaInterior::setColor( const uno::Any& _color ) throw (uno::RuntimeException)
+{
+ sal_Int32 nColor = 0;
+ if( _color >>= nColor )
+ {
+ SetUserDefinedAttributes( BACKCOLOR, SetAttributeData( XLRGBToOORGB( nColor ) ) );
+ //m_xProps->setPropertyValue( BACKCOLOR , XLRGBToOORGB(_color));
+ SetMixedColor();
+ }
+}
+
+void
+ScVbaInterior::SetMixedColor()
+{
+ // pattern
+ uno::Any aPattern = GetUserDefinedAttributes( PATTERN );
+ if( aPattern.hasValue() )
+ {
+ m_nPattern = GetAttributeData( aPattern );
+ }
+ sal_Int32 nPattern = aPatternMap[ m_nPattern ];
+ // pattern color
+ uno::Any aPatternColor = GetUserDefinedAttributes( PATTERNCOLOR );
+ if( aPatternColor.hasValue() )
+ {
+ sal_uInt32 nPatternColor = GetAttributeData( aPatternColor );
+ m_aPattColor.SetColor( nPatternColor );
+ }
+ sal_Int32 nPatternColor = m_aPattColor.GetColor();
+ // back color
+ Color aBackColor( GetBackColor() );
+ // set mixed color
+ Color aMixedColor;
+ if( nPattern > 0 )
+ aMixedColor = GetPatternColor( Color(nPatternColor), aBackColor, (sal_uInt32)nPattern );
+ else
+ aMixedColor = GetPatternColor( aBackColor, aBackColor, (sal_uInt32)nPattern );
+ sal_Int32 nMixedColor = aMixedColor.GetColor() & COLORMAST;
+ m_xProps->setPropertyValue( BACKCOLOR , uno::makeAny( nMixedColor ) );
+}
+
+uno::Reference< container::XIndexAccess >
+ScVbaInterior::getPalette()
+{
+ if ( !m_pScDoc )
+ throw uno::RuntimeException();
+ SfxObjectShell* pShell = m_pScDoc->GetDocumentShell();
+ ScVbaPalette aPalette( pShell );
+ return aPalette.getPalette();
+}
+
+void SAL_CALL
+ScVbaInterior::setColorIndex( const css::uno::Any& _colorindex ) throw (css::uno::RuntimeException)
+{
+ sal_Int32 nIndex = 0;
+ _colorindex >>= nIndex;
+
+ // hackly for excel::XlColorIndex::xlColorIndexNone
+ if( nIndex == excel::XlColorIndex::xlColorIndexNone )
+ {
+ m_xProps->setPropertyValue( BACKCOLOR, uno::makeAny( sal_Int32( -1 ) ) );
+ }
+ else
+ {
+ // setColor expects colors in XL RGB values
+ // #FIXME this is daft we convert OO RGB val to XL RGB val and
+ // then back again to OO RGB value
+ setColor( OORGBToXLRGB( GetIndexColor( nIndex ) ) );
+ }
+}
+uno::Any
+ScVbaInterior::GetIndexColor( const sal_Int32& nColorIndex )
+{
+ sal_Int32 nIndex = nColorIndex;
+ // #FIXME xlColorIndexAutomatic & xlColorIndexNone are not really
+ // handled properly here
+ if ( !nIndex || ( nIndex == excel::XlColorIndex::xlColorIndexAutomatic ) || ( nIndex == excel::XlColorIndex::xlColorIndexNone ) )
+ nIndex = 2; // default is white ( this maybe will probably break, e.g. we may at some stage need to know what this interior is, a cell or something else and then pick a default colour based on that )
+ --nIndex; // OOo indices are zero bases
+ uno::Reference< container::XIndexAccess > xIndex = getPalette();
+ return xIndex->getByIndex( nIndex );
+}
+
+sal_Int32
+ScVbaInterior::GetColorIndex( const sal_Int32 nColor )
+{
+ uno::Reference< container::XIndexAccess > xIndex = getPalette();
+ sal_Int32 nElems = xIndex->getCount();
+ sal_Int32 nIndex = -1;
+ for ( sal_Int32 count=0; count<nElems; ++count )
+ {
+ sal_Int32 nPaletteColor = 0;
+ xIndex->getByIndex( count ) >>= nPaletteColor;
+ if ( nPaletteColor == nColor )
+ {
+ nIndex = count + 1; // 1 based
+ break;
+ }
+ }
+ return nIndex;
+}
+
+uno::Any SAL_CALL
+ScVbaInterior::getColorIndex() throw ( css::uno::RuntimeException )
+{
+ sal_Int32 nColor = 0;
+ // hackly for excel::XlColorIndex::xlColorIndexNone
+ uno::Any aColor = m_xProps->getPropertyValue( BACKCOLOR );
+ if( ( aColor >>= nColor ) && ( nColor == -1 ) )
+ {
+ nColor = excel::XlColorIndex::xlColorIndexNone;
+ return uno::makeAny( nColor );
+ }
+
+ // getColor returns Xl ColorValue, need to convert it to OO val
+ // as the palette deals with OO RGB values
+ // #FIXME this is daft in getColor we convert OO RGB val to XL RGB val
+ // and then back again to OO RGB value
+ XLRGBToOORGB( getColor() ) >>= nColor;
+
+ return uno::makeAny( GetColorIndex( nColor ) );
+}
+Color
+ScVbaInterior::GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt32 nXclPattern )
+{
+ // 0x00 == 0% transparence (full rPattColor)
+ // 0x80 == 100% transparence (full rBackColor)
+ static const sal_uInt8 pnRatioTable[] =
+ {
+ 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
+ 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
+ 0x50, 0x70, 0x78 // 16 - 18
+ };
+ return ( nXclPattern < STATIC_TABLE_SIZE( pnRatioTable ) ) ?
+ GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor;
+}
+Color
+ScVbaInterior::GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans )
+{
+ return Color(
+ nTrans,
+ GetMixedColorComp( rFore.GetRed(), rBack.GetRed(), nTrans ),
+ GetMixedColorComp( rFore.GetGreen(), rBack.GetGreen(), nTrans ),
+ GetMixedColorComp( rFore.GetBlue(), rBack.GetBlue(), nTrans ));
+}
+sal_uInt8
+ScVbaInterior::GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans )
+{
+ sal_uInt32 nTemp = ((static_cast< sal_Int32 >( nBack ) - nFore) * nTrans) / 0x80 + nFore;
+ return static_cast< sal_uInt8 >( nTemp );
+}
+uno::Reference< container::XNameContainer >
+ScVbaInterior::GetAttributeContainer()
+{
+ return uno::Reference < container::XNameContainer > ( m_xProps->getPropertyValue( rtl::OUString::createFromAscii( "UserDefinedAttributes" ) ), uno::UNO_QUERY_THROW );
+}
+sal_Int32
+ScVbaInterior::GetAttributeData( uno::Any aValue )
+{
+ xml::AttributeData aDataValue;
+ if( aValue >>= aDataValue )
+ {
+ return aDataValue.Value.toInt32();
+ }
+ return sal_Int32( 0 );
+}
+uno::Any
+ScVbaInterior::SetAttributeData( sal_Int32 nValue )
+{
+ xml::AttributeData aAttributeData;
+ //aAttributeData.Namespace = rtl::OUString::createFromAscii( "ooo.vba.excel.CellPatten");
+ aAttributeData.Type = rtl::OUString::createFromAscii( "sal_Int32" );
+ aAttributeData.Value = rtl::OUString::valueOf( nValue );
+ return uno::makeAny( aAttributeData );
+}
+uno::Any
+ScVbaInterior::GetUserDefinedAttributes( const rtl::OUString& sName )
+{
+ uno::Reference< container::XNameContainer > xNameContainer( GetAttributeContainer(), uno::UNO_QUERY_THROW );
+ if( xNameContainer->hasByName( sName ) )
+ {
+ return xNameContainer->getByName( sName );
+ }
+ return uno::Any();
+}
+void
+ScVbaInterior::SetUserDefinedAttributes( const rtl::OUString& sName, const uno::Any& aValue )
+{
+ if( aValue.hasValue() )
+ {
+ uno::Reference< container::XNameContainer > xNameContainer( GetAttributeContainer(), uno::UNO_QUERY_THROW );
+ if( xNameContainer->hasByName( sName ) )
+ xNameContainer->removeByName( sName );
+ xNameContainer->insertByName( sName, aValue );
+ m_xProps->setPropertyValue( rtl::OUString::createFromAscii( "UserDefinedAttributes" ), uno::makeAny( xNameContainer ) );
+ }
+}
+// OOo do not support below API
+uno::Any SAL_CALL
+ScVbaInterior::getPattern() throw (uno::RuntimeException)
+{
+ // XlPattern
+ uno::Any aPattern = GetUserDefinedAttributes( PATTERN );
+ if( aPattern.hasValue() )
+ return uno::makeAny( GetAttributeData( aPattern ) );
+ return uno::makeAny( excel::XlPattern::xlPatternNone );
+}
+void SAL_CALL
+ScVbaInterior::setPattern( const uno::Any& _pattern ) throw (uno::RuntimeException)
+{
+ if( _pattern >>= m_nPattern )
+ {
+ SetUserDefinedAttributes( PATTERN, SetAttributeData( m_nPattern ) );
+ SetMixedColor();
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid Pattern index" ), uno::Reference< uno::XInterface >() );
+}
+Color
+ScVbaInterior::GetBackColor()
+{
+ sal_Int32 nColor = 0;
+ Color aBackColor;
+ uno::Any aColor = GetUserDefinedAttributes( BACKCOLOR );
+ if( aColor.hasValue() )
+ {
+ nColor = GetAttributeData( aColor );
+ aBackColor.SetColor( nColor );
+ }
+ else
+ {
+ uno::Any aAny;
+ aAny = OORGBToXLRGB( m_xProps->getPropertyValue( BACKCOLOR ) );
+ if( aAny >>= nColor )
+ {
+ nColor = XLRGBToOORGB( nColor );
+ aBackColor.SetColor( nColor );
+ SetUserDefinedAttributes( BACKCOLOR, SetAttributeData( nColor ) );
+ }
+ }
+ return aBackColor;
+}
+uno::Any SAL_CALL
+ScVbaInterior::getPatternColor() throw (uno::RuntimeException)
+{
+ // 0 is the default color. no filled.
+ uno::Any aPatternColor = GetUserDefinedAttributes( PATTERNCOLOR );
+ if( aPatternColor.hasValue() )
+ {
+ sal_uInt32 nPatternColor = GetAttributeData( aPatternColor );
+ return uno::makeAny( OORGBToXLRGB( nPatternColor ) );
+ }
+ return uno::makeAny( sal_Int32( 0 ) );
+}
+void SAL_CALL
+ScVbaInterior::setPatternColor( const uno::Any& _patterncolor ) throw (uno::RuntimeException)
+{
+ sal_Int32 nPattColor = 0;
+ if( _patterncolor >>= nPattColor )
+ {
+ SetUserDefinedAttributes( PATTERNCOLOR, SetAttributeData( XLRGBToOORGB( nPattColor ) ) );
+ SetMixedColor();
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid Pattern Color" ), uno::Reference< uno::XInterface >() );
+}
+uno::Any SAL_CALL
+ScVbaInterior::getPatternColorIndex() throw (uno::RuntimeException)
+{
+ sal_Int32 nColor = 0;
+ XLRGBToOORGB( getPatternColor() ) >>= nColor;
+
+ return uno::makeAny( GetIndexColor( nColor ) );
+}
+void SAL_CALL
+ScVbaInterior::setPatternColorIndex( const uno::Any& _patterncolorindex ) throw (uno::RuntimeException)
+{
+ sal_Int32 nColorIndex = 0;
+ if( _patterncolorindex >>= nColorIndex )
+ {
+ if( nColorIndex == 0 )
+ return;
+ sal_Int32 nPattColor = 0;
+ GetIndexColor( nColorIndex ) >>= nPattColor;
+ setPatternColor( uno::makeAny( OORGBToXLRGB( nPattColor ) ) );
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid Pattern Color" ), uno::Reference< uno::XInterface >() );
+}
+
+rtl::OUString&
+ScVbaInterior::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaInterior") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaInterior::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Interior" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbainterior.hxx b/sc/source/ui/vba/vbainterior.hxx
new file mode 100644
index 000000000000..027d06040af9
--- /dev/null
+++ b/sc/source/ui/vba/vbainterior.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_INTERIOR_HXX
+#define SC_VBA_INTERIOR_HXX
+
+#include <ooo/vba/excel/XInterior.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+#include <com/sun/star/script/XInvocation.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <tools/color.hxx>
+
+class ScDocument;
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XInterior > ScVbaInterior_BASE;
+
+class ScVbaInterior : public ScVbaInterior_BASE
+{
+ css::uno::Reference< css::beans::XPropertySet > m_xProps;
+ ScDocument* m_pScDoc;
+ Color m_aPattColor;
+ sal_Int32 m_nPattern;
+
+ css::uno::Reference< css::container::XIndexAccess > getPalette();
+ css::uno::Reference< css::container::XNameContainer > GetAttributeContainer();
+ css::uno::Any SetAttributeData( sal_Int32 nValue );
+ sal_Int32 GetAttributeData( css::uno::Any aValue );
+ Color GetBackColor();
+protected:
+ Color GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt32 nXclPattern );
+ Color GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans );
+ sal_uInt8 GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans );
+ css::uno::Any GetIndexColor( const sal_Int32& nColorIndex );
+ sal_Int32 GetColorIndex( const sal_Int32 nColor );
+ css::uno::Any GetUserDefinedAttributes( const rtl::OUString& sName );
+ void SetUserDefinedAttributes( const rtl::OUString& sName, const css::uno::Any& aValue );
+ void SetMixedColor();
+public:
+ ScVbaInterior( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps, ScDocument* pScDoc = NULL) throw ( css::lang::IllegalArgumentException);
+
+ virtual ~ScVbaInterior(){}
+
+ virtual css::uno::Any SAL_CALL getColor() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setColor( const css::uno::Any& _color ) throw (css::uno::RuntimeException) ;
+
+ virtual css::uno::Any SAL_CALL getColorIndex() throw ( css::uno::RuntimeException);
+ virtual void SAL_CALL setColorIndex( const css::uno::Any& _colorindex ) throw ( css::uno::RuntimeException );
+ virtual css::uno::Any SAL_CALL getPattern() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPattern( const css::uno::Any& _pattern ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getPatternColor() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPatternColor( const css::uno::Any& _patterncolor ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getPatternColorIndex() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPatternColorIndex( const css::uno::Any& _patterncolorindex ) throw (css::uno::RuntimeException);
+ //XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
+
diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx
new file mode 100644
index 000000000000..464b167df250
--- /dev/null
+++ b/sc/source/ui/vba/vbaname.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vbahelper/helperdecl.hxx>
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+
+#include "vbaname.hxx"
+#include "vbarange.hxx"
+#include "vbaglobals.hxx"
+#include <vector>
+#include <rangenam.hxx>
+#include <vcl/msgbox.hxx>
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaName::ScVbaName(const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XNamedRange >& xName,
+ const css::uno::Reference< css::sheet::XNamedRanges >& xNames,
+ const css::uno::Reference< css::frame::XModel >& xModel ):
+ NameImpl_BASE( xParent , xContext ),
+ mxModel( xModel ),
+ mxNamedRange( xName ),
+ mxNames( xNames )
+{
+}
+
+ScVbaName::~ScVbaName()
+{
+}
+
+css::uno::Reference< ov::excel::XWorksheet >
+ScVbaName::getWorkSheet() throw (css::uno::RuntimeException)
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getActiveSheet();
+}
+
+::rtl::OUString
+ScVbaName::getName() throw (css::uno::RuntimeException)
+{
+ String sName;
+ sName += UniString( getWorkSheet()->getName());
+ sName += String::CreateFromAscii("!");
+ sName += UniString ( mxNamedRange->getName() );
+ return ::rtl::OUString( sName );
+}
+
+void
+ScVbaName::setName( const ::rtl::OUString & rName ) throw (css::uno::RuntimeException)
+{
+ mxNamedRange->setName( rName );
+}
+
+::rtl::OUString
+ScVbaName::getNameLocal() throw (css::uno::RuntimeException)
+{
+ return getName();
+}
+
+void
+ScVbaName::setNameLocal( const ::rtl::OUString & rName ) throw (css::uno::RuntimeException)
+{
+ setName( rName );
+}
+
+sal_Bool
+ScVbaName::getVisible() throw (css::uno::RuntimeException)
+{
+ return true;
+}
+
+void
+ScVbaName::setVisible( sal_Bool /*bVisible*/ ) throw (css::uno::RuntimeException)
+{
+}
+
+::rtl::OUString
+ScVbaName::getValue() throw (css::uno::RuntimeException)
+{
+ ::rtl::OUString sValue = mxNamedRange->getContent();
+ ::rtl::OUString sSheetName = getWorkSheet()->getName();
+ ::rtl::OUString sSegmentation = ::rtl::OUString::createFromAscii( ";" );
+ ::rtl::OUString sNewSegmentation = ::rtl::OUString::createFromAscii( "," );
+ ::rtl::OUString sResult;
+ sal_Int32 nFrom = 0;
+ sal_Int32 nTo = 0;
+ nTo = sValue.indexOf( sSegmentation, nFrom );
+ while ( nTo != -1 )
+ {
+ ::rtl::OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
+ if ( sTmpValue.toChar() == '$' )
+ {
+ ::rtl::OUString sTmp = sTmpValue.copy( 1 );
+ sTmp = sTmp.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii(".")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("!"));
+ sResult += sTmp;
+ sResult += sNewSegmentation;
+ }
+ nFrom = nTo + 1;
+ nTo = sValue.indexOf( sSegmentation, nFrom );
+ }
+ ::rtl::OUString sTmpValue = sValue.copy( nFrom );
+ if ( sTmpValue.toChar() == '$' )
+ {
+ ::rtl::OUString sTmp = sTmpValue.copy(1);
+ sTmp = sTmp.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii(".")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("!"));
+ sResult += sTmp;
+ }
+ if (sResult.indexOf('=') != 0)
+ {
+ sResult = ::rtl::OUString::createFromAscii("=") + sResult;
+ }
+ return sResult;
+}
+
+void
+ScVbaName::setValue( const ::rtl::OUString & rValue ) throw (css::uno::RuntimeException)
+{
+ ::rtl::OUString sSheetName = getWorkSheet()->getName();
+ ::rtl::OUString sValue = rValue;
+ ::rtl::OUString sSegmentation = ::rtl::OUString::createFromAscii( "," );
+ ::rtl::OUString sNewSegmentation = ::rtl::OUString::createFromAscii( ";" );
+ ::rtl::OUString sResult;
+ sal_Int32 nFrom = 0;
+ sal_Int32 nTo = 0;
+ if (sValue.indexOf('=') == 0)
+ {
+ ::rtl::OUString sTmp = sValue.copy(1);
+ sValue = sTmp;
+ }
+ nTo = sValue.indexOf( sSegmentation, nFrom );
+ while ( nTo != -1 )
+ {
+ ::rtl::OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
+ sTmpValue = sTmpValue.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii("!")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("."));
+ if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
+ {
+ sTmpValue = ::rtl::OUString::createFromAscii("$") + sTmpValue;
+ }
+ sTmpValue += sNewSegmentation;
+ sResult += sTmpValue;
+ nFrom = nTo + 1;
+ nTo = sValue.indexOf( sSegmentation, nFrom );
+ }
+ ::rtl::OUString sTmpValue = sValue.copy( nFrom );
+ sTmpValue = sTmpValue.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii("!")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("."));
+ if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
+ {
+ sTmpValue = ::rtl::OUString::createFromAscii("$") + sTmpValue;
+ }
+ sResult += sTmpValue;
+ mxNamedRange->setContent(sResult);
+}
+
+::rtl::OUString
+ScVbaName::getRefersTo() throw (css::uno::RuntimeException)
+{
+ return getValue();
+}
+
+void
+ScVbaName::setRefersTo( const ::rtl::OUString & rRefersTo ) throw (css::uno::RuntimeException)
+{
+ setValue( rRefersTo );
+}
+
+::rtl::OUString
+ScVbaName::getRefersToLocal() throw (css::uno::RuntimeException)
+{
+ return getRefersTo();
+}
+
+void
+ScVbaName::setRefersToLocal( const ::rtl::OUString & rRefersTo ) throw (css::uno::RuntimeException)
+{
+ setRefersTo( rRefersTo );
+}
+
+::rtl::OUString
+ScVbaName::getRefersToR1C1() throw (css::uno::RuntimeException)
+{
+ return getRefersTo();
+}
+
+void
+ScVbaName::setRefersToR1C1( const ::rtl::OUString & rRefersTo ) throw (css::uno::RuntimeException)
+{
+ setRefersTo( rRefersTo );
+}
+
+::rtl::OUString
+ScVbaName::getRefersToR1C1Local() throw (css::uno::RuntimeException)
+{
+ return getRefersTo();
+}
+
+void
+ScVbaName::setRefersToR1C1Local( const ::rtl::OUString & rRefersTo ) throw (css::uno::RuntimeException)
+{
+ setRefersTo( rRefersTo );
+}
+
+css::uno::Reference< ov::excel::XRange >
+ScVbaName::getRefersToRange() throw (css::uno::RuntimeException)
+{
+ uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName(
+ mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
+ return xRange;
+}
+
+void
+ScVbaName::setRefersToRange( const css::uno::Reference< ov::excel::XRange > /*rRange*/ ) throw (css::uno::RuntimeException)
+{
+}
+
+void
+ScVbaName::Delete() throw (css::uno::RuntimeException)
+{
+ mxNames->removeByName( mxNamedRange->getName() );
+}
+
+rtl::OUString&
+ScVbaName::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaName") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaName::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Name" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbaname.hxx b/sc/source/ui/vba/vbaname.hxx
new file mode 100644
index 000000000000..81b2555a4ce1
--- /dev/null
+++ b/sc/source/ui/vba/vbaname.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_NAME_HXX
+#define SC_VBA_NAME_HXX
+
+#include <ooo/vba/excel/XName.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+class ScDocument;
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XName > NameImpl_BASE;
+
+class ScVbaName : public NameImpl_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::sheet::XNamedRange > mxNamedRange;
+ css::uno::Reference< css::sheet::XNamedRanges > mxNames;
+
+ ScDocument * m_pDoc;
+
+protected:
+ virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; }
+ virtual css::uno::Reference< ov::excel::XWorksheet > getWorkSheet() throw (css::uno::RuntimeException);
+
+public:
+ ScVbaName( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XNamedRange >& xName , const css::uno::Reference< css::sheet::XNamedRanges >& xNames , const css::uno::Reference< css::frame::XModel >& xModel );
+ virtual ~ScVbaName();
+
+ // Attributes
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getNameLocal() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setNameLocal( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVisible( sal_Bool bVisible ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getValue() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setValue( const ::rtl::OUString &rValue ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRefersTo() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRefersTo( const ::rtl::OUString &rRefersTo ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRefersToLocal() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRefersToLocal( const ::rtl::OUString &rRefersTo ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRefersToR1C1() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRefersToR1C1( const ::rtl::OUString &rRefersTo ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRefersToR1C1Local() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRefersToR1C1Local( const ::rtl::OUString &rRefersTo ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRefersToRange() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRefersToRange( const css::uno::Reference< ov::excel::XRange > xRange ) throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual void SAL_CALL Delete() throw (css::uno::RuntimeException);
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif /* SC_VBA_NAME_HXX */
+
diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx
new file mode 100644
index 000000000000..9fd22bf89f7a
--- /dev/null
+++ b/sc/source/ui/vba/vbanames.cxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <vbahelper/helperdecl.hxx>
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+
+#include "vbanames.hxx"
+#include "vbaname.hxx"
+#include "vbarange.hxx"
+#include "vbaglobals.hxx"
+#include <vector>
+#include <rangenam.hxx>
+#include <vcl/msgbox.hxx>
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+class NamesEnumeration : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > m_xModel;
+ uno::WeakReference< XHelperInterface > m_xParent;
+ uno::Reference< sheet::XNamedRanges > m_xNames;
+public:
+ NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ uno::Reference< sheet::XNamedRange > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return uno::makeAny( uno::Reference< excel::XName > ( new ScVbaName( m_xParent, m_xContext, xNamed ,m_xNames , m_xModel ) ) );
+ }
+
+};
+
+
+ScVbaNames::ScVbaNames(const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XNamedRanges >& xNames,
+ const css::uno::Reference< css::frame::XModel >& xModel ):
+ ScVbaNames_BASE( xParent , xContext , uno::Reference< container::XIndexAccess >( xNames, uno::UNO_QUERY ) ),
+ mxModel( xModel ),
+ mxNames( xNames )
+{
+ m_xNameAccess.set( xNames, uno::UNO_QUERY_THROW );
+}
+
+ScVbaNames::~ScVbaNames()
+{
+}
+
+ScDocument *
+ScVbaNames::getScDocument()
+{
+ uno::Reference< frame::XModel > xModel( getModel() , uno::UNO_QUERY_THROW );
+ ScTabViewShell * pTabViewShell = excel::getBestViewShell( xModel );
+ if ( !pTabViewShell )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("No ViewShell available"), uno::Reference< uno::XInterface >() );
+ ScViewData* pViewData = pTabViewShell->GetViewData();
+ if ( !pViewData )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("No ViewData available"), uno::Reference< uno::XInterface >() );
+ return pViewData->GetDocument();
+}
+
+css::uno::Any
+ScVbaNames::Add( const css::uno::Any& Name ,
+ const css::uno::Any& RefersTo,
+ const css::uno::Any& /*Visible*/,
+ const css::uno::Any& /*MacroType*/,
+ const css::uno::Any& /*ShoutcutKey*/,
+ const css::uno::Any& /*Category*/,
+ const css::uno::Any& NameLocal,
+ const css::uno::Any& /*RefersToLocal*/,
+ const css::uno::Any& /*CategoryLocal*/,
+ const css::uno::Any& RefersToR1C1,
+ const css::uno::Any& RefersToR1C1Local ) throw (css::uno::RuntimeException)
+{
+
+ rtl::OUString sName;
+ uno::Reference< excel::XRange > xRange;
+ if ( Name.hasValue() )
+ Name >>= sName;
+ else if ( NameLocal.hasValue() )
+ NameLocal >>= sName;
+ if ( sName.getLength() != 0 )
+ {
+ if ( !ScRangeData::IsNameValid( sName , getScDocument() ) )
+ {
+ ::rtl::OUString sResult ;
+ sal_Int32 nToken = 0;
+ sal_Int32 nIndex = 0;
+ sResult = sName.getToken( nToken , '!' , nIndex );
+ if ( -1 == nIndex )
+ sResult = sName;
+ else
+ sResult = sName.copy( nIndex );
+ sName = sResult ;
+ if ( !ScRangeData::IsNameValid( sName , getScDocument() ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("This Name is a valid ."), uno::Reference< uno::XInterface >() );
+ }
+ }
+ if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
+ {
+ if ( RefersTo.hasValue() )
+ RefersTo >>= xRange;
+ if ( RefersToR1C1.hasValue() )
+ RefersToR1C1 >>= xRange;
+ if ( RefersToR1C1Local.hasValue() )
+ RefersToR1C1Local >>= xRange;
+ }
+
+ if ( xRange.is() )
+ {
+ ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() );
+ uno::Reference< table::XCellRange > thisRange ;
+ uno::Any xAny = pRange->getCellRange() ;
+ if ( xAny.hasValue() )
+ xAny >>= thisRange;
+ uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( thisRange, ::uno::UNO_QUERY_THROW);
+ table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
+ ScAddress aPos( static_cast< SCCOL >( aAddr.StartColumn ) , static_cast< SCROW >( aAddr.StartRow ) , static_cast< SCTAB >(aAddr.Sheet ) );
+ uno::Any xAny2 ;
+ String sRangeAdd = xRange->Address( xAny2, xAny2 , xAny2 , xAny2, xAny2 );
+ String sTmp;
+ sTmp += String::CreateFromAscii("$");
+ sTmp += UniString(xRange->getWorksheet()->getName());
+ sTmp += String::CreateFromAscii(".");
+ sTmp += sRangeAdd;
+ if ( mxNames.is() )
+ {
+ RangeType nType = RT_NAME;
+ table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
+ if ( mxNames->hasByName( sName ) )
+ mxNames->removeByName(sName);
+ mxNames->addNewByName( sName , rtl::OUString(sTmp) , aCellAddr , (sal_Int32)nType);
+ }
+ }
+ return css::uno::Any();
+}
+
+// XEnumerationAccess
+css::uno::Type
+ScVbaNames::getElementType() throw( css::uno::RuntimeException )
+{
+ return ov::excel::XName::static_type(0);
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaNames::createEnumeration() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( mxNames, uno::UNO_QUERY_THROW );
+ return new NamesEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel , mxNames );
+}
+
+uno::Any
+ScVbaNames::createCollectionObject( const uno::Any& aSource )
+{
+ uno::Reference< sheet::XNamedRange > xName( aSource, uno::UNO_QUERY );
+ return uno::makeAny( uno::Reference< excel::XName > ( new ScVbaName( getParent(), mxContext, xName, mxNames , mxModel ) ) );
+}
+
+rtl::OUString&
+ScVbaNames::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaNames") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaNames::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.NamedRanges" ) );
+ }
+ return aServiceNames;
+}
+
+
diff --git a/sc/source/ui/vba/vbanames.hxx b/sc/source/ui/vba/vbanames.hxx
new file mode 100644
index 000000000000..1997ac6163d7
--- /dev/null
+++ b/sc/source/ui/vba/vbanames.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_NAMES_HXX
+#define SC_VBA_NAMES_HXX
+
+#include <ooo/vba/excel/XNames.hpp>
+#include <ooo/vba/XCollection.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+class ScDocument;
+class ScDocShell;
+
+typedef CollTestImplHelper< ov::excel::XNames > ScVbaNames_BASE;
+
+class ScVbaNames : public ScVbaNames_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::sheet::XNamedRanges > mxNames;
+
+protected:
+ virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; }
+
+public:
+ ScVbaNames( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XNamedRanges >& xNames , const css::uno::Reference< css::frame::XModel >& xModel );
+
+ ScDocument* getScDocument();
+ ScDocShell* getScDocShell();
+
+ virtual ~ScVbaNames();
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& aName ,
+ const css::uno::Any& aRefersTo,
+ const css::uno::Any& aVisible,
+ const css::uno::Any& aMacroType,
+ const css::uno::Any& aShoutcutKey,
+ const css::uno::Any& aCategory,
+ const css::uno::Any& aNameLocal,
+ const css::uno::Any& aRefersToLocal,
+ const css::uno::Any& aCategoryLocal,
+ const css::uno::Any& aRefersToR1C1,
+ const css::uno::Any& aRefersToR1C1Local ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+
+ // ScVbaNames_BASE
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+};
+#endif /* SC_VBA_NAMES_HXX */
+
diff --git a/sc/source/ui/vba/vbaoleobject.cxx b/sc/source/ui/vba/vbaoleobject.cxx
new file mode 100644
index 000000000000..a35ce4b3120f
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobject.cxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/view/XControlAccess.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <ooo/vba/XControlProvider.hpp>
+
+#include "vbaoleobject.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+
+sal_Int32 pt2mm( double pt ) //1/100mm
+{
+ return static_cast<sal_Int32>(pt * 0.352778);
+}
+
+double mm2pt( sal_Int32 mm )
+{
+ return mm * 2.8345;
+}
+
+
+ScVbaOLEObject::ScVbaOLEObject( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
+ css::uno::Reference< css::drawing::XControlShape > xControlShape )
+: OLEObjectImpl_BASE( xParent, xContext ), m_xControlShape( xControlShape )
+{
+ //init m_xWindowPeer
+ uno::Reference< awt::XControlModel > xControlModel( xControlShape->getControl(), css::uno::UNO_QUERY_THROW );
+ uno::Reference< container::XChild > xChild( xControlModel, uno::UNO_QUERY_THROW );
+ xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
+ xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
+ css::uno::Reference< css::frame::XModel > xModel( xChild->getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
+ uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.ControlProvider" ) ), mxContext ), uno::UNO_QUERY_THROW );
+ m_xControl.set( xControlProvider->createControl( xControlShape, xModel ) );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+ScVbaOLEObject::getObject() throw (uno::RuntimeException)
+{
+ return uno::Reference< uno::XInterface >( m_xControlShape, uno::UNO_QUERY_THROW );
+}
+
+sal_Bool SAL_CALL
+ScVbaOLEObject::getEnabled() throw (uno::RuntimeException)
+{
+ return m_xControl->getEnabled();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setEnabled( sal_Bool _enabled ) throw (uno::RuntimeException)
+{
+ m_xControl->setEnabled( _enabled );
+}
+
+sal_Bool SAL_CALL
+ScVbaOLEObject::getVisible() throw (uno::RuntimeException)
+{
+ OSL_TRACE("OleObject %s returning visible %s", rtl::OUStringToOString( m_xControl->getName(), RTL_TEXTENCODING_UTF8 ).getStr(), m_xControl->getVisible() ? "true" : "false" );
+ return m_xControl->getVisible();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setVisible( sal_Bool _visible ) throw (uno::RuntimeException)
+{
+ OSL_TRACE("OleObject %s set visible %s", rtl::OUStringToOString( m_xControl->getName(), RTL_TEXTENCODING_UTF8 ).getStr(), _visible ? "true" : "false" );
+ m_xControl->setVisible( _visible );
+}
+
+double SAL_CALL
+ScVbaOLEObject::getLeft() throw (uno::RuntimeException)
+{
+ return m_xControl->getLeft();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setLeft( double _left ) throw (uno::RuntimeException)
+{
+ m_xControl->setLeft( _left );
+
+}
+
+double SAL_CALL
+ScVbaOLEObject::getTop() throw (uno::RuntimeException)
+{
+ return m_xControl->getTop();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setTop( double _top ) throw (uno::RuntimeException)
+{
+ m_xControl->setTop( _top );
+}
+
+double SAL_CALL
+ScVbaOLEObject::getHeight() throw (uno::RuntimeException)
+{
+ return m_xControl->getHeight();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setHeight( double _height ) throw (uno::RuntimeException)
+{
+ m_xControl->setHeight( _height );
+}
+
+double SAL_CALL
+ScVbaOLEObject::getWidth() throw (uno::RuntimeException)
+{
+ return m_xControl->getWidth();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setWidth( double _width ) throw (uno::RuntimeException)
+{
+ m_xControl->setWidth( _width );
+}
+rtl::OUString&
+ScVbaOLEObject::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaOLEObject") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaOLEObject::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.OLEObject" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbaoleobject.hxx b/sc/source/ui/vba/vbaoleobject.hxx
new file mode 100644
index 000000000000..008564d71e16
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobject.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_OLEOBJECT_HXX
+#define SC_VBA_OLEOBJECT_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <ooo/vba/excel/XOLEObject.hpp>
+#include <ooo/vba/msforms/XControl.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XOLEObject > OLEObjectImpl_BASE;
+
+class ScVbaOLEObject : public OLEObjectImpl_BASE
+{
+protected:
+ css::uno::Reference< css::drawing::XControlShape > m_xControlShape;
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+ css::uno::Reference< ov::msforms::XControl> m_xControl;
+public:
+ ScVbaOLEObject( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::drawing::XControlShape > xControlShape );
+
+ // XOLEObject Attributes
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getObject() throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getEnabled() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setEnabled( ::sal_Bool _enabled ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVisible( ::sal_Bool _visible ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getLeft() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLeft( double _left ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getTop() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTop( double _top ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getHeight() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setHeight( double _height ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getWidth() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setWidth( double _width ) throw (css::uno::RuntimeException);
+
+};
+#endif //SC_VBA_OLEOBJECT_HXX
+
diff --git a/sc/source/ui/vba/vbaoleobjects.cxx b/sc/source/ui/vba/vbaoleobjects.cxx
new file mode 100644
index 000000000000..69ba36cf8279
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobjects.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <ooo/vba/excel/XOLEObject.hpp>
+
+#include "vbaoleobject.hxx"
+#include "vbaoleobjects.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+typedef ::cppu::WeakImplHelper1< container::XIndexAccess > XIndexAccess_BASE;
+
+class IndexAccessWrapper : public XIndexAccess_BASE
+{
+typedef std::vector< uno::Reference< drawing::XControlShape > > OLEObjects;
+ OLEObjects vObjects;
+public:
+ IndexAccessWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess )
+ {
+ sal_Int32 nLen = xIndexAccess->getCount();
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ uno::Reference< drawing::XControlShape > xControlShape( xIndexAccess->getByIndex( index), uno::UNO_QUERY);
+ if ( xControlShape.is() )
+ vObjects.push_back( xControlShape );
+ }
+ }
+
+ virtual ::sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException)
+ {
+ return vObjects.size();
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+ return uno::makeAny( vObjects[ Index ] );
+ }
+
+ // Methods XElementAcess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException)
+ {
+ return drawing::XControlShape::static_type(0);
+ }
+
+ virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException)
+ {
+ return ( getCount() > 0 );
+ }
+
+};
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+
+ uno::Reference<XHelperInterface > m_xParent;
+ uno::Reference<uno::XComponentContext > m_xContext;
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xParent( xParent ), m_xContext( xContext), m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ {
+ uno::Reference< drawing::XControlShape > xControlShape ( m_xIndexAccess->getByIndex( nIndex++ ), uno::UNO_QUERY_THROW );
+ return uno::makeAny( uno::Reference< ov::excel::XOLEObject >( new ScVbaOLEObject( m_xParent, m_xContext, xControlShape ) ) );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+uno::Reference< container::XIndexAccess > oleObjectIndexWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess )
+{
+ return new IndexAccessWrapper( xIndexAccess );
+}
+
+ScVbaOLEObjects::ScVbaOLEObjects( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess )
+ : OLEObjectsImpl_BASE( xParent, xContext, oleObjectIndexWrapper( xIndexAccess ) )
+{
+}
+uno::Reference< container::XEnumeration >
+ScVbaOLEObjects::createEnumeration() throw (uno::RuntimeException)
+{
+ return new EnumWrapper( getParent(), mxContext, m_xIndexAccess );
+}
+
+uno::Any
+ScVbaOLEObjects::createCollectionObject( const css::uno::Any& aSource )
+{
+ if( aSource.hasValue() )
+ {
+ uno::Reference< drawing::XControlShape > xControlShape( aSource, uno::UNO_QUERY_THROW );
+ // parent of OLEObject is the same parent as the collection ( e.g. the sheet )
+ return uno::makeAny( uno::Reference< ov::excel::XOLEObject >( new ScVbaOLEObject( getParent(), mxContext, xControlShape ) ) );
+ }
+ return uno::Any();
+}
+
+uno::Any
+ScVbaOLEObjects::getItemByStringIndex( const rtl::OUString& sIndex ) throw (uno::RuntimeException)
+{
+ try
+ {
+ return OLEObjectsImpl_BASE::getItemByStringIndex( sIndex );
+ }
+ catch( uno::RuntimeException )
+ {
+ uno::Reference< container::XIndexAccess > xIndexAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ sal_Int32 nCount = xIndexAccess->getCount();
+ for( int index = 0; index < nCount; index++ )
+ {
+ uno::Any aUnoObj = xIndexAccess->getByIndex( index );
+ uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY_THROW );
+ uno::Reference< awt::XControlModel > xControlModel( xControlShape->getControl() );
+ uno::Reference< container::XNamed > xNamed( xControlModel, uno::UNO_QUERY_THROW );
+ if( sIndex.equals( xNamed->getName() ))
+ {
+ return createCollectionObject( aUnoObj );
+ }
+
+ }
+ return uno::Any();
+ }
+}
+
+uno::Type
+ScVbaOLEObjects::getElementType() throw (uno::RuntimeException)
+{
+ return ooo::vba::excel::XOLEObject::static_type(0);
+}
+rtl::OUString&
+ScVbaOLEObjects::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaOLEObjects") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaOLEObjects::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.OLEObjects" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbaoleobjects.hxx b/sc/source/ui/vba/vbaoleobjects.hxx
new file mode 100644
index 000000000000..ab4ed29d163d
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobjects.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_OLEOBJECTS_HXX
+#define SC_VBA_OLEOBJECTS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XOLEObjects.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include "excelvbahelper.hxx"
+
+typedef CollTestImplHelper< ov::excel::XOLEObjects > OLEObjectsImpl_BASE;
+
+class ScVbaOLEObjects : public OLEObjectsImpl_BASE
+{
+protected:
+ virtual css::uno::Any getItemByStringIndex( const rtl::OUString& sIndex ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+public:
+ ScVbaOLEObjects( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+
+};
+#endif //SC_VBA_OLEOBJECTS_HXX
+
diff --git a/sc/source/ui/vba/vbaoutline.cxx b/sc/source/ui/vba/vbaoutline.cxx
new file mode 100644
index 000000000000..ee4c78c73151
--- /dev/null
+++ b/sc/source/ui/vba/vbaoutline.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbaoutline.hxx"
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+void
+ScVbaOutline::ShowLevels( const uno::Any& RowLevels, const uno::Any& ColumnLevels ) throw (uno::RuntimeException)
+{
+ sal_Int16 nLevel = 0;
+ if (mxOutline.is())
+ {
+ if (RowLevels >>= nLevel)
+ {
+ mxOutline->showLevel(nLevel, table::TableOrientation_ROWS);
+ }
+ if (ColumnLevels >>= nLevel)
+ {
+ mxOutline->showLevel(nLevel,table::TableOrientation_COLUMNS);
+ }
+ }
+}
+
+rtl::OUString&
+ScVbaOutline::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaOutline") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaOutline::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Outline" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbaoutline.hxx b/sc/source/ui/vba/vbaoutline.hxx
new file mode 100644
index 000000000000..c954842cf7fd
--- /dev/null
+++ b/sc/source/ui/vba/vbaoutline.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_OUTLINE_HXX
+#define SC_VBA_OUTLINE_HXX
+
+#include <com/sun/star/sheet/XSheetOutline.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XOutline.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XOutline > ScVbaOutline_BASE;
+
+class ScVbaOutline : public ScVbaOutline_BASE
+{
+ css::uno::Reference< css::sheet::XSheetOutline > mxOutline;
+public:
+ ScVbaOutline( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference<css::sheet::XSheetOutline> outline): ScVbaOutline_BASE( xParent, xContext) , mxOutline(outline)
+ {}
+ virtual ~ScVbaOutline(){}
+
+ virtual void SAL_CALL ShowLevels( const css::uno::Any& RowLevels, const css::uno::Any& ColumnLevels ) throw (css::uno::RuntimeException) ;
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
diff --git a/sc/source/ui/vba/vbapagebreak.cxx b/sc/source/ui/vba/vbapagebreak.cxx
new file mode 100644
index 000000000000..1103c10f54c8
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreak.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbapagebreak.hxx"
+#include "vbarange.hxx"
+#include <ooo/vba/excel/XlPageBreak.hpp>
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+template< typename Ifc1 >
+ScVbaPageBreak<Ifc1>::ScVbaPageBreak( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ uno::Reference< beans::XPropertySet >& xProps,
+ sheet::TablePageBreakData aTablePageBreakData) throw (uno::RuntimeException):
+ ScVbaPageBreak_BASE( xParent, xContext ),
+ mxRowColPropertySet( xProps ),
+ maTablePageBreakData( aTablePageBreakData )
+{
+}
+
+template< typename Ifc1 >
+sal_Int32 ScVbaPageBreak<Ifc1>::getType() throw (uno::RuntimeException)
+{
+ uno::Any aValue = mxRowColPropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )));
+ sal_Bool hasPageBreak = sal_False;
+ aValue >>= hasPageBreak;
+
+ if( !hasPageBreak )
+ return excel::XlPageBreak::xlPageBreakNone;
+
+ if( maTablePageBreakData.ManualBreak )
+ return excel::XlPageBreak::xlPageBreakManual;
+
+ return excel::XlPageBreak::xlPageBreakAutomatic;
+}
+
+template< typename Ifc1 >
+void ScVbaPageBreak<Ifc1>::setType(sal_Int32 type) throw (uno::RuntimeException)
+{
+ if( (type != excel::XlPageBreak::xlPageBreakNone) &&
+ (type != excel::XlPageBreak::xlPageBreakManual) &&
+ (type != excel::XlPageBreak::xlPageBreakAutomatic) )
+ {
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+
+ if( type == excel::XlPageBreak::xlPageBreakNone )
+ {
+ mxRowColPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )), uno::makeAny(sal_False));
+ return;
+ }
+
+ mxRowColPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )), uno::makeAny(sal_True));
+ if( type == excel::XlPageBreak::xlPageBreakManual )
+ maTablePageBreakData.ManualBreak = sal_True;
+ else
+ maTablePageBreakData.ManualBreak = sal_False;
+}
+
+template< typename Ifc1 >
+void ScVbaPageBreak<Ifc1>::Delete() throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ mxRowColPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )), uno::makeAny(sal_False));
+}
+
+template< typename Ifc1 >
+uno::Reference< excel::XRange> ScVbaPageBreak<Ifc1>::Location() throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< table::XCellRange > xRange( mxRowColPropertySet, uno::UNO_QUERY_THROW );
+ return new ScVbaRange( ScVbaPageBreak_BASE::getParent(), ScVbaPageBreak_BASE::mxContext, xRange);
+}
+
+template< typename Ifc1 >
+rtl::OUString&
+ScVbaPageBreak<Ifc1>::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaPageBreak") );
+ return sImplName;
+}
+
+template< typename Ifc1 >
+uno::Sequence< rtl::OUString >
+ScVbaPageBreak<Ifc1>::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.PageBreak" ) );
+ }
+ return aServiceNames;
+}
+
+template class ScVbaPageBreak< excel::XHPageBreak >;
+
+/* class ScVbaHPageBreak */
+rtl::OUString&
+ScVbaHPageBreak::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaHPageBreak") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaHPageBreak::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.HPageBreak" ) );
+ }
+ return aServiceNames;
+}
+
+template class ScVbaPageBreak< excel::XVPageBreak >;
+
+/* class ScVbaVPageBreak */
+ScVbaVPageBreak::ScVbaVPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData ) throw ( css::uno::RuntimeException )
+: ScVbaVPageBreak_BASE( xParent, xContext, xProps, aTablePageBreakData )
+{
+}
+
+ScVbaVPageBreak::~ScVbaVPageBreak()
+{
+}
+
+rtl::OUString&
+ScVbaVPageBreak::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaVPageBreak") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaVPageBreak::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.VPageBreak" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbapagebreak.hxx b/sc/source/ui/vba/vbapagebreak.hxx
new file mode 100644
index 000000000000..4832464c1296
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreak.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PAGEBREAK_HXX
+#define SC_VBA_PAGEBREAK_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XPageBreak.hpp>
+#include <ooo/vba/excel/XHPageBreak.hpp>
+#include <ooo/vba/excel/XVPageBreak.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+template< typename Ifc1 >
+class ScVbaPageBreak : public InheritedHelperInterfaceImpl1< Ifc1 >
+{
+typedef InheritedHelperInterfaceImpl1< Ifc1 > ScVbaPageBreak_BASE;
+protected:
+ css::uno::Reference< css::beans::XPropertySet > mxRowColPropertySet;
+ css::sheet::TablePageBreakData maTablePageBreakData;
+public:
+ ScVbaPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData) throw (css::uno::RuntimeException);
+ virtual ~ScVbaPageBreak(){}
+
+ virtual sal_Int32 SAL_CALL getType( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setType(sal_Int32 type) throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL Delete() throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange> SAL_CALL Location() throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+
+typedef ScVbaPageBreak < ov::excel::XHPageBreak > ScVbaHPageBreak_BASE;
+
+class ScVbaHPageBreak : public ScVbaHPageBreak_BASE
+{
+public:
+ ScVbaHPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData) throw (css::uno::RuntimeException):
+ ScVbaHPageBreak_BASE( xParent,xContext,xProps,aTablePageBreakData ){}
+
+ virtual ~ScVbaHPageBreak(){}
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+//VPageBreak
+typedef ScVbaPageBreak < ov::excel::XVPageBreak > ScVbaVPageBreak_BASE;
+
+class ScVbaVPageBreak : public ScVbaVPageBreak_BASE
+{
+public:
+ ScVbaVPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData) throw (css::uno::RuntimeException);
+
+ virtual ~ScVbaVPageBreak();
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif
diff --git a/sc/source/ui/vba/vbapagebreaks.cxx b/sc/source/ui/vba/vbapagebreaks.cxx
new file mode 100644
index 000000000000..25ccbb0f4cdc
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreaks.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbapagebreaks.hxx"
+#include "vbapagebreak.hxx"
+#include <ooo/vba/excel/XWorksheet.hpp>
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+typedef ::cppu::WeakImplHelper1<container::XIndexAccess > RangePageBreaks_Base;
+class RangePageBreaks : public RangePageBreaks_Base
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< sheet::XSheetPageBreak > mxSheetPageBreak;
+ sal_Bool m_bColumn;
+
+public:
+ RangePageBreaks( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak,
+ sal_Bool bColumn ) : mxParent( xParent ), mxContext( xContext ), mxSheetPageBreak( xSheetPageBreak ), m_bColumn( bColumn )
+ {
+ }
+
+ sal_Int32 getAPIStartofRange( const uno::Reference< excel::XRange >& xRange ) throw (css::uno::RuntimeException)
+ {
+ if( m_bColumn )
+ return xRange->getColumn() - 1;
+ return xRange->getRow() - 1;
+ }
+
+ sal_Int32 getAPIEndIndexofRange( const uno::Reference< excel::XRange >& xRange, sal_Int32 nUsedStart ) throw (uno::RuntimeException)
+ {
+ if( m_bColumn )
+ return nUsedStart + xRange->Columns( uno::Any() )->getCount();
+ return nUsedStart + xRange->Rows( uno::Any() )->getCount();
+ }
+
+ uno::Sequence<sheet::TablePageBreakData> getAllPageBreaks() throw (uno::RuntimeException)
+ {
+ if( m_bColumn )
+ return mxSheetPageBreak->getColumnPageBreaks();
+ return mxSheetPageBreak->getRowPageBreaks();
+ }
+
+ uno::Reference<container::XIndexAccess> getRowColContainer() throw (uno::RuntimeException)
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange( mxSheetPageBreak, uno::UNO_QUERY_THROW );
+ uno::Reference<container::XIndexAccess> xIndexAccess;
+ if( m_bColumn )
+ xIndexAccess.set( xColumnRowRange->getColumns(), uno::UNO_QUERY_THROW );
+ else
+ xIndexAccess.set( xColumnRowRange->getRows(), uno::UNO_QUERY_THROW );
+ return xIndexAccess;
+ }
+
+ sheet::TablePageBreakData getTablePageBreakData( sal_Int32 nAPIItemIndex ) throw ( script::BasicErrorException, uno::RuntimeException);
+ uno::Any Add( const css::uno::Any& Before ) throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException);
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
+ virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
+ {
+ if( m_bColumn )
+ return excel::XVPageBreak::static_type(0);
+ return excel::XHPageBreak::static_type(0);
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
+ {
+ return sal_True;
+ }
+};
+
+/** @TODO Unlike MS Excel this method only considers the pagebreaks that intersect the used range
+* To become completely compatible the print area has to be considered. As far as I found out this printarea
+* also considers the position and sizes of shapes and manually inserted page breaks
+* Note: In MS there is a limit of 1026 horizontal page breaks per sheet.
+*/
+sal_Int32 SAL_CALL RangePageBreaks::getCount( ) throw (uno::RuntimeException)
+{
+ sal_Int32 nCount = 0;
+ uno::Reference< excel::XWorksheet > xWorksheet( mxParent, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xRange = xWorksheet->getUsedRange();
+ sal_Int32 nUsedStart = getAPIStartofRange( xRange );
+ sal_Int32 nUsedEnd = getAPIEndIndexofRange( xRange, nUsedStart );
+ uno::Sequence<sheet::TablePageBreakData> aTablePageBreakData = getAllPageBreaks();
+
+ sal_Int32 nLength = aTablePageBreakData.getLength();
+ for( sal_Int32 i=0; i<nLength; i++ )
+ {
+ sal_Int32 nPos = aTablePageBreakData[i].Position;
+ if( nPos > nUsedEnd )
+ return nCount;
+ if( nPos >= nUsedStart )
+ nCount++;
+ }
+
+ return nCount;
+}
+
+uno::Any SAL_CALL RangePageBreaks::getByIndex( sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if( (Index < getCount()) && ( Index >= 0 ))
+ {
+ sheet::TablePageBreakData aTablePageBreakData = getTablePageBreakData( Index );
+ uno::Reference< container::XIndexAccess > xIndexAccess = getRowColContainer();
+ sal_Int32 nPos = aTablePageBreakData.Position;
+ if( (nPos < xIndexAccess->getCount()) && (nPos > -1) )
+ {
+ uno::Reference< beans::XPropertySet > xRowColPropertySet( xIndexAccess->getByIndex(nPos), uno::UNO_QUERY_THROW );
+ if( m_bColumn )
+ return uno::makeAny( uno::Reference< excel::XVPageBreak >( new ScVbaVPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+ return uno::makeAny( uno::Reference< excel::XHPageBreak >( new ScVbaHPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+ }
+ }
+ throw lang::IndexOutOfBoundsException();
+}
+
+sheet::TablePageBreakData RangePageBreaks::getTablePageBreakData( sal_Int32 nAPIItemIndex ) throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ sal_Int32 index = -1;
+ sheet::TablePageBreakData aTablePageBreakData;
+ uno::Reference< excel::XWorksheet > xWorksheet( mxParent, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xRange = xWorksheet->getUsedRange();
+ sal_Int32 nUsedStart = getAPIStartofRange( xRange );
+ sal_Int32 nUsedEnd = getAPIEndIndexofRange( xRange, nUsedStart );
+ uno::Sequence<sheet::TablePageBreakData> aTablePageBreakDataList = getAllPageBreaks();
+
+ sal_Int32 nLength = aTablePageBreakDataList.getLength();
+ for( sal_Int32 i=0; i<nLength; i++ )
+ {
+ aTablePageBreakData = aTablePageBreakDataList[i];
+ sal_Int32 nPos = aTablePageBreakData.Position;
+ if( nPos >= nUsedStart )
+ index++;
+ if( nPos > nUsedEnd )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ if( index == nAPIItemIndex )
+ return aTablePageBreakData;
+ }
+
+ return aTablePageBreakData;
+}
+
+uno::Any RangePageBreaks::Add( const css::uno::Any& Before ) throw ( css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ uno::Reference< excel::XRange > xRange;
+ Before >>= xRange;
+ if( !xRange.is() )
+ {
+ DebugHelper::exception(SbERR_BAD_ARGUMENT, rtl::OUString());
+ }
+
+ sal_Int32 nAPIRowColIndex = getAPIStartofRange( xRange );
+ uno::Reference< container::XIndexAccess > xIndexAccess = getRowColContainer();
+ uno::Reference< beans::XPropertySet > xRowColPropertySet( xIndexAccess->getByIndex(nAPIRowColIndex), uno::UNO_QUERY_THROW );
+ xRowColPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )), uno::makeAny(sal_True));
+ sheet::TablePageBreakData aTablePageBreakData;
+ aTablePageBreakData.ManualBreak = sal_True;
+ aTablePageBreakData.Position = nAPIRowColIndex;
+ if( m_bColumn )
+ return uno::makeAny( uno::Reference< excel::XVPageBreak >( new ScVbaVPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+ return uno::makeAny( uno::Reference< excel::XHPageBreak >( new ScVbaHPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+}
+
+
+class RangePageBreaksEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ RangePageBreaksEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+ScVbaHPageBreaks::ScVbaHPageBreaks( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak) throw (uno::RuntimeException):
+ ScVbaHPageBreaks_BASE( xParent,xContext, new RangePageBreaks( xParent, xContext, xSheetPageBreak, sal_False )),
+ mxSheetPageBreak( xSheetPageBreak )
+{
+}
+
+uno::Any SAL_CALL ScVbaHPageBreaks::Add( const uno::Any& Before) throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ RangePageBreaks* pPageBreaks = dynamic_cast< RangePageBreaks* >( m_xIndexAccess.get() );
+ if( pPageBreaks )
+ {
+ return pPageBreaks->Add( Before );
+ }
+ return uno::Any();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaHPageBreaks::createEnumeration() throw (uno::RuntimeException)
+{
+ return new RangePageBreaksEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+ScVbaHPageBreaks::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // its already a pagebreak object
+}
+
+uno::Type
+ScVbaHPageBreaks::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XHPageBreak::static_type(0);
+}
+
+rtl::OUString&
+ScVbaHPageBreaks::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaHPageBreaks") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaHPageBreaks::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.HPageBreaks" ) );
+ }
+ return aServiceNames;
+}
+
+//VPageBreak
+ScVbaVPageBreaks::ScVbaVPageBreaks( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak ) throw ( uno::RuntimeException )
+: ScVbaVPageBreaks_BASE( xParent, xContext, new RangePageBreaks( xParent, xContext, xSheetPageBreak, sal_True ) ),
+ mxSheetPageBreak( xSheetPageBreak )
+{
+}
+
+ScVbaVPageBreaks::~ScVbaVPageBreaks()
+{
+}
+
+uno::Any SAL_CALL
+ScVbaVPageBreaks::Add( const uno::Any& Before ) throw ( script::BasicErrorException, uno::RuntimeException )
+{
+ RangePageBreaks* pPageBreaks = dynamic_cast< RangePageBreaks* >( m_xIndexAccess.get() );
+ if( pPageBreaks )
+ {
+ return pPageBreaks->Add( Before );
+ }
+ return uno::Any();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaVPageBreaks::createEnumeration() throw ( uno::RuntimeException )
+{
+ return new RangePageBreaksEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+ScVbaVPageBreaks::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // its already a pagebreak object
+}
+
+uno::Type
+ScVbaVPageBreaks::getElementType() throw ( uno::RuntimeException )
+{
+ return excel::XVPageBreak::static_type( 0 );
+}
+
+rtl::OUString&
+ScVbaVPageBreaks::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM( "ScVbaVPageBreaks" ) );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaVPageBreaks::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.VPageBreaks" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbapagebreaks.hxx b/sc/source/ui/vba/vbapagebreaks.hxx
new file mode 100644
index 000000000000..de6174191e95
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreaks.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PAGEBREAKS_HXX
+#define SC_VBA_PAGEBREAKS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XHPageBreaks.hpp>
+#include <ooo/vba/excel/XHPageBreak.hpp>
+#include <ooo/vba/excel/XVPageBreaks.hpp>
+#include <ooo/vba/excel/XVPageBreak.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/sheet/XSheetPageBreak.hpp>
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XHPageBreaks > ScVbaHPageBreaks_BASE;
+
+class ScVbaHPageBreaks : public ScVbaHPageBreaks_BASE
+{
+ css::uno::Reference< css::sheet::XSheetPageBreak > mxSheetPageBreak;
+public:
+ ScVbaHPageBreaks( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::sheet::XSheetPageBreak >& xSheetPageBreak) throw (css::uno::RuntimeException);
+ virtual ~ScVbaHPageBreaks(){}
+
+ // XHPageBreaks
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Before) throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&);
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+//VPageBreaks
+typedef CollTestImplHelper< ov::excel::XVPageBreaks > ScVbaVPageBreaks_BASE;
+
+class ScVbaVPageBreaks : public ScVbaVPageBreaks_BASE
+{
+ css::uno::Reference< css::sheet::XSheetPageBreak > mxSheetPageBreak;
+
+public:
+ ScVbaVPageBreaks( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::sheet::XSheetPageBreak >& xSheetPageBreak ) throw ( css::uno::RuntimeException );
+
+ virtual ~ScVbaVPageBreaks();
+
+ // XVPageBreaks
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Before ) throw ( css::script::BasicErrorException, css::uno::RuntimeException );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw ( css::uno::RuntimeException );
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw ( css::uno::RuntimeException );
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& );
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif
diff --git a/sc/source/ui/vba/vbapagesetup.cxx b/sc/source/ui/vba/vbapagesetup.cxx
new file mode 100644
index 000000000000..d660ddbbfd77
--- /dev/null
+++ b/sc/source/ui/vba/vbapagesetup.cxx
@@ -0,0 +1,626 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbapagesetup.hxx"
+#include "cellsuno.hxx"
+#include "convuno.hxx"
+#include "rangelst.hxx"
+#include "excelvbahelper.hxx"
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <ooo/vba/excel/XlPageOrientation.hpp>
+#include <ooo/vba/excel/XlOrder.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+#define ZOOM_IN 10
+#define ZOOM_MAX 400
+
+bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, ScRange& refRange, ScRangeList& aCellRanges, formula::FormulaGrammar::AddressConvention aConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException );
+
+ScVbaPageSetup::ScVbaPageSetup(const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSpreadsheet >& xSheet,
+ const uno::Reference< frame::XModel >& xModel) throw (uno::RuntimeException):
+ ScVbaPageSetup_BASE( xParent, xContext ), mxSheet( xSheet )
+{
+ // query for current page style
+ mxModel.set( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xSheetProps( mxSheet, uno::UNO_QUERY_THROW );
+ uno::Any aValue = xSheetProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageStyle" )));
+ rtl::OUString aStyleName;
+ aValue >>= aStyleName;
+
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleFamiliesSup( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xStyleFamilies = xStyleFamiliesSup->getStyleFamilies();
+ uno::Reference< container::XNameAccess > xPageStyle( xStyleFamilies->getByName(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PageStyles"))), uno::UNO_QUERY_THROW );
+ mxPageProps.set( xPageStyle->getByName(aStyleName), uno::UNO_QUERY_THROW );
+ mnOrientLandscape = excel::XlPageOrientation::xlLandscape;
+ mnOrientPortrait = excel::XlPageOrientation::xlPortrait;
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getPrintArea() throw (css::uno::RuntimeException)
+{
+ String aPrintArea;
+ uno::Reference< sheet::XPrintAreas > xPrintAreas( mxSheet, uno::UNO_QUERY_THROW );
+ uno::Sequence< table::CellRangeAddress > aSeq = xPrintAreas->getPrintAreas();
+ sal_Int32 nCount = aSeq.getLength();
+ if( nCount )
+ {
+ ScAddress::Details aDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ USHORT nFlags = SCA_VALID;
+ nFlags |= ( SCA_TAB_ABSOLUTE | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB2_ABSOLUTE | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE );
+ ScRangeList aRangeList;
+ for( sal_Int32 i=0; i<nCount; i++ )
+ {
+ ScRange aRange;
+ ScUnoConversion::FillScRange( aRange, aSeq[i] );
+ aRangeList.Append( aRange );
+ }
+ ScDocument* pDoc = excel::getDocShell( mxModel )->GetDocument();
+ aRangeList.Format( aPrintArea, nFlags, pDoc, formula::FormulaGrammar::CONV_XL_A1, ',' );
+ }
+
+ return aPrintArea;
+}
+
+void SAL_CALL ScVbaPageSetup::setPrintArea( const rtl::OUString& rAreas ) throw (css::uno::RuntimeException)
+{
+ uno::Reference< sheet::XPrintAreas > xPrintAreas( mxSheet, uno::UNO_QUERY_THROW );
+ if( rAreas.getLength() == 0 ||
+ rAreas.equalsIgnoreAsciiCase ( rtl::OUString::createFromAscii("FALSE") ) )
+ {
+ // print the whole sheet
+ uno::Sequence< table::CellRangeAddress > aSeq;
+ xPrintAreas->setPrintAreas( aSeq );
+ }
+ else
+ {
+ ScRangeList aCellRanges;
+ ScRange aRange;
+ if( getScRangeListForAddress( rAreas, excel::getDocShell( mxModel ) , aRange, aCellRanges ) )
+ {
+ uno::Sequence< table::CellRangeAddress > aSeq( aCellRanges.Count() );
+ USHORT i=0;
+ for( ScRange* pRange = aCellRanges.First(); pRange; pRange = aCellRanges.Next() )
+ {
+ table::CellRangeAddress aRangeAddress;
+ ScUnoConversion::FillApiRange( aRangeAddress, *pRange );
+ aSeq[ i++ ] = aRangeAddress;
+ }
+ xPrintAreas->setPrintAreas( aSeq );
+ }
+ }
+}
+
+double SAL_CALL ScVbaPageSetup::getHeaderMargin() throw (css::uno::RuntimeException)
+{
+ return VbaPageSetupBase::getHeaderMargin();
+}
+
+void SAL_CALL ScVbaPageSetup::setHeaderMargin( double margin ) throw (css::uno::RuntimeException)
+{
+ VbaPageSetupBase::setHeaderMargin( margin );
+}
+
+double SAL_CALL ScVbaPageSetup::getFooterMargin() throw (css::uno::RuntimeException)
+{
+ return VbaPageSetupBase::getFooterMargin();
+}
+
+void SAL_CALL ScVbaPageSetup::setFooterMargin( double margin ) throw (css::uno::RuntimeException)
+{
+ VbaPageSetupBase::setFooterMargin( margin );
+}
+
+uno::Any SAL_CALL ScVbaPageSetup::getFitToPagesTall() throw (css::uno::RuntimeException)
+{
+ return mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPagesY")));
+}
+
+void SAL_CALL ScVbaPageSetup::setFitToPagesTall( const uno::Any& fitToPagesTall) throw (css::uno::RuntimeException)
+{
+ USHORT scaleToPageY = 0;
+ try
+ {
+ sal_Bool aValue;
+ if( fitToPagesTall.getValueTypeClass() != uno::TypeClass_BOOLEAN || (fitToPagesTall >>= aValue))
+ {
+ fitToPagesTall >>= scaleToPageY;
+ }
+
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPagesY")), uno::makeAny( scaleToPageY ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+uno::Any SAL_CALL ScVbaPageSetup::getFitToPagesWide() throw (css::uno::RuntimeException)
+{
+ return mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPagesX")));
+}
+
+void SAL_CALL ScVbaPageSetup::setFitToPagesWide( const uno::Any& fitToPagesWide) throw (css::uno::RuntimeException)
+{
+ USHORT scaleToPageX = 0;
+ try
+ {
+ sal_Bool aValue = sal_False;
+ if( fitToPagesWide.getValueTypeClass() != uno::TypeClass_BOOLEAN || (fitToPagesWide >>= aValue))
+ {
+ fitToPagesWide >>= scaleToPageX;
+ }
+
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPagesX")), uno::makeAny( scaleToPageX ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+uno::Any SAL_CALL ScVbaPageSetup::getZoom() throw (css::uno::RuntimeException)
+{
+ return mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PageScale")));
+}
+
+void SAL_CALL ScVbaPageSetup::setZoom( const uno::Any& zoom) throw (css::uno::RuntimeException)
+{
+ USHORT pageScale = 0;
+ try
+ {
+ if( zoom.getValueTypeClass() == uno::TypeClass_BOOLEAN )
+ {
+ sal_Bool aValue = sal_False;
+ zoom >>= aValue;
+ if( aValue )
+ {
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+ }
+ else
+ {
+ zoom >>= pageScale;
+ if(( pageScale < ZOOM_IN )||( pageScale > ZOOM_MAX ))
+ {
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+ }
+
+ // these only exist in S08
+ USHORT nScale = 0;
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPages")), uno::makeAny( nScale ));
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPagesX")), uno::makeAny( nScale ));
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleToPagesY")), uno::makeAny( nScale ));
+ }
+ catch( beans::UnknownPropertyException& )
+ {
+ if( pageScale == 0 )
+ {
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PageScale")), uno::makeAny( pageScale ));
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getLeftHeader() throw (css::uno::RuntimeException)
+{
+ rtl::OUString leftHeader;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent"))), uno::UNO_QUERY_THROW);
+ if( xHeaderContent.is() )
+ {
+ uno::Reference< text::XText > xText = xHeaderContent->getLeftText();
+ leftHeader = xText->getString();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return leftHeader;
+}
+
+void SAL_CALL ScVbaPageSetup::setLeftHeader( const rtl::OUString& leftHeader) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent"))), uno::UNO_QUERY_THROW);
+ if( xHeaderContent.is() )
+ {
+ uno::Reference< text::XText > xText = xHeaderContent->getLeftText();
+ xText->setString( leftHeader );
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent")), uno::makeAny(xHeaderContent) );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getCenterHeader() throw (css::uno::RuntimeException)
+{
+ rtl::OUString centerHeader;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent"))), uno::UNO_QUERY_THROW);
+ if( xHeaderContent.is() )
+ {
+ uno::Reference< text::XText > xText = xHeaderContent->getCenterText();
+ centerHeader = xText->getString();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return centerHeader;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterHeader( const rtl::OUString& centerHeader) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent"))), uno::UNO_QUERY_THROW);
+ if( xHeaderContent.is() )
+ {
+ uno::Reference< text::XText > xText = xHeaderContent->getCenterText();
+ xText->setString( centerHeader );
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent")), uno::makeAny(xHeaderContent) );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getRightHeader() throw (css::uno::RuntimeException)
+{
+ rtl::OUString rightHeader;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent"))), uno::UNO_QUERY_THROW);
+ if( xHeaderContent.is() )
+ {
+ uno::Reference< text::XText > xText = xHeaderContent->getRightText();
+ rightHeader = xText->getString();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return rightHeader;
+}
+
+void SAL_CALL ScVbaPageSetup::setRightHeader( const rtl::OUString& rightHeader) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent"))), uno::UNO_QUERY_THROW);
+ if( xHeaderContent.is() )
+ {
+ uno::Reference< text::XText > xText = xHeaderContent->getRightText();
+ xText->setString( rightHeader );
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageHeaderContent")), uno::makeAny(xHeaderContent) );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getLeftFooter() throw (css::uno::RuntimeException)
+{
+ rtl::OUString leftFooter;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent"))), uno::UNO_QUERY_THROW);
+ if( xFooterContent.is() )
+ {
+ uno::Reference< text::XText > xText = xFooterContent->getLeftText();
+ leftFooter = xText->getString();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return leftFooter;
+}
+
+void SAL_CALL ScVbaPageSetup::setLeftFooter( const rtl::OUString& leftFooter) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent"))), uno::UNO_QUERY_THROW);
+ if( xFooterContent.is() )
+ {
+ uno::Reference< text::XText > xText = xFooterContent->getLeftText();
+ xText->setString( leftFooter );
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent")), uno::makeAny(xFooterContent) );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getCenterFooter() throw (css::uno::RuntimeException)
+{
+ rtl::OUString centerFooter;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent"))), uno::UNO_QUERY_THROW);
+ if( xFooterContent.is() )
+ {
+ uno::Reference< text::XText > xText = xFooterContent->getCenterText();
+ centerFooter = xText->getString();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return centerFooter;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterFooter( const rtl::OUString& centerFooter) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent"))), uno::UNO_QUERY_THROW);
+ if( xFooterContent.is() )
+ {
+ uno::Reference< text::XText > xText = xFooterContent->getCenterText();
+ xText->setString( centerFooter );
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent")), uno::makeAny(xFooterContent) );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+}
+
+rtl::OUString SAL_CALL ScVbaPageSetup::getRightFooter() throw (css::uno::RuntimeException)
+{
+ rtl::OUString rightFooter;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent"))), uno::UNO_QUERY_THROW);
+ if( xFooterContent.is() )
+ {
+ uno::Reference< text::XText > xText = xFooterContent->getRightText();
+ rightFooter = xText->getString();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return rightFooter;
+}
+
+void SAL_CALL ScVbaPageSetup::setRightFooter( const rtl::OUString& rightFooter) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent"))), uno::UNO_QUERY_THROW);
+ if( xFooterContent.is() )
+ {
+ uno::Reference< text::XText > xText = xFooterContent->getRightText();
+ xText->setString( rightFooter );
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightPageFooterContent")), uno::makeAny(xFooterContent) );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Int32 SAL_CALL ScVbaPageSetup::getOrder() throw (css::uno::RuntimeException)
+{
+ sal_Int32 order = excel::XlOrder::xlDownThenOver;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrintDownFirst")));
+ sal_Bool bPrintDownFirst = sal_False;
+ aValue >>= bPrintDownFirst;
+ if( !bPrintDownFirst )
+ order = excel::XlOrder::xlOverThenDown;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return order;
+}
+
+void SAL_CALL ScVbaPageSetup::setOrder( sal_Int32 order) throw (css::uno::RuntimeException)
+{
+ sal_Bool bOrder = sal_True;
+ switch( order )
+ {
+ case excel::XlOrder::xlDownThenOver:
+ break;
+ case excel::XlOrder::xlOverThenDown:
+ bOrder = sal_False;
+ break;
+ default:
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+
+ try
+ {
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrintDownFirst")), uno::makeAny( bOrder ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Int32 SAL_CALL ScVbaPageSetup::getFirstPageNumber() throw (css::uno::RuntimeException)
+{
+ sal_Int16 number = 0;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FirstPageNumber")));
+ aValue >>= number;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ if( number ==0 )
+ {
+ number = excel::Constants::xlAutomatic;
+ }
+
+ return number;
+}
+
+void SAL_CALL ScVbaPageSetup::setFirstPageNumber( sal_Int32 firstPageNumber) throw (css::uno::RuntimeException)
+{
+ if( firstPageNumber < 0 )
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ if( firstPageNumber == excel::Constants::xlAutomatic )
+ firstPageNumber = 0;
+
+ try
+ {
+ uno::Any aValue;
+ aValue <<= (sal_Int16)firstPageNumber;
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FirstPageNumber")), aValue );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getCenterVertically() throw (css::uno::RuntimeException)
+{
+ sal_Bool centerVertically = sal_False;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CenterVertically")));
+ aValue >>= centerVertically;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return centerVertically;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterVertically( sal_Bool centerVertically) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CenterVertically")), uno::makeAny( centerVertically ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getCenterHorizontally() throw (css::uno::RuntimeException)
+{
+ sal_Bool centerHorizontally = sal_False;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CenterHorizontally")));
+ aValue >>= centerHorizontally;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return centerHorizontally;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterHorizontally( sal_Bool centerHorizontally) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CenterHorizontally")), uno::makeAny( centerHorizontally ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getPrintHeadings() throw (css::uno::RuntimeException)
+{
+ sal_Bool printHeadings = sal_False;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrintHeaders")));
+ aValue >>= printHeadings;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return printHeadings;
+}
+
+void SAL_CALL ScVbaPageSetup::setPrintHeadings( sal_Bool printHeadings) throw (css::uno::RuntimeException)
+{
+ try
+ {
+ mxPageProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrintHeaders")), uno::makeAny( printHeadings ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+rtl::OUString&
+ScVbaPageSetup::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaPageSetup") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaPageSetup::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.PageSetup" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbapagesetup.hxx b/sc/source/ui/vba/vbapagesetup.hxx
new file mode 100644
index 000000000000..d2c001b225cf
--- /dev/null
+++ b/sc/source/ui/vba/vbapagesetup.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PAGESETUP_HXX
+#define SC_VBA_PAGESETUP_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XPageSetup.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbapagesetupbase.hxx>
+
+typedef cppu::ImplInheritanceHelper1< VbaPageSetupBase, ov::excel::XPageSetup > ScVbaPageSetup_BASE;
+
+class ScVbaPageSetup : public ScVbaPageSetup_BASE
+{
+ css::uno::Reference< css::sheet::XSpreadsheet > mxSheet;
+public:
+ ScVbaPageSetup( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XSpreadsheet>& xSheet,
+ const css::uno::Reference< css::frame::XModel >& xModel) throw (css::uno::RuntimeException);
+ virtual ~ScVbaPageSetup(){}
+
+ // Attribute
+ virtual rtl::OUString SAL_CALL getPrintArea() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrintArea( const rtl::OUString& rAreas ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getHeaderMargin() throw (css::uno::RuntimeException);
+ void SAL_CALL setHeaderMargin( double margin ) throw (css::uno::RuntimeException);
+ double SAL_CALL getFooterMargin() throw (css::uno::RuntimeException);
+ void SAL_CALL setFooterMargin( double margin ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFitToPagesTall() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFitToPagesTall( const css::uno::Any& fitToPagesTall ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFitToPagesWide() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFitToPagesWide( const css::uno::Any& fitToPagesWide ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getZoom() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setZoom( const css::uno::Any& zoom ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL getLeftHeader() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLeftHeader( const rtl::OUString& leftHeader ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL getCenterHeader() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCenterHeader( const rtl::OUString& centerHeader ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL getRightHeader() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRightHeader( const rtl::OUString& rightHeader ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL getLeftFooter() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLeftFooter( const rtl::OUString& leftFooter ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL getCenterFooter() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCenterFooter( const rtl::OUString& centerFooter ) throw (css::uno::RuntimeException);
+ virtual rtl::OUString SAL_CALL getRightFooter() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRightFooter( const rtl::OUString& rightFooter ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getOrder() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setOrder( sal_Int32 order ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getFirstPageNumber() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFirstPageNumber( sal_Int32 firstPageNumber ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getCenterVertically() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCenterVertically( sal_Bool centerVertically ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getCenterHorizontally() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCenterHorizontally( sal_Bool centerHorizontally ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getPrintHeadings() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrintHeadings( sal_Bool printHeadings ) throw (css::uno::RuntimeException);
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
diff --git a/sc/source/ui/vba/vbapalette.cxx b/sc/source/ui/vba/vbapalette.cxx
new file mode 100644
index 000000000000..c6ae5c488a20
--- /dev/null
+++ b/sc/source/ui/vba/vbapalette.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vbapalette.hxx"
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include "excelvbahelper.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+/** Standard EGA colors, bright. */
+#define EXC_PALETTE_EGA_COLORS_LIGHT \
+ 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
+/** Standard EGA colors, dark. */
+#define EXC_PALETTE_EGA_COLORS_DARK \
+ 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
+
+static const ColorData spnDefColorTable8[] =
+{
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_PALETTE_EGA_COLORS_DARK,
+/* 24 */ 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF,
+/* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
+/* 40 */ 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99,
+/* 48 */ 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696,
+/* 56 */ 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333
+};
+
+typedef ::cppu::WeakImplHelper1< container::XIndexAccess > XIndexAccess_BASE;
+
+class DefaultPalette : public XIndexAccess_BASE
+{
+public:
+ DefaultPalette(){}
+
+ // Methods XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException)
+ {
+ return sizeof(spnDefColorTable8) / sizeof(spnDefColorTable8[0]);
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+ return uno::makeAny( sal_Int32( spnDefColorTable8[ Index ] ) );
+ }
+
+ // Methods XElementAcess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException)
+ {
+ return ::getCppuType( (sal_Int32*)0 );
+ }
+ virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException)
+ {
+ return sal_True;
+ }
+
+};
+
+ScVbaPalette::ScVbaPalette( const uno::Reference< frame::XModel >& rxModel ) :
+ m_pShell( excel::getDocShell( rxModel ) )
+{
+}
+
+uno::Reference< container::XIndexAccess >
+ScVbaPalette::getDefaultPalette()
+{
+ return new DefaultPalette();
+}
+
+uno::Reference< container::XIndexAccess >
+ScVbaPalette::getPalette() const
+{
+ uno::Reference< container::XIndexAccess > xIndex;
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( m_pShell )
+ xProps.set( m_pShell->GetModel(), uno::UNO_QUERY_THROW );
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't extract palette, no doc shell" ) ), uno::Reference< uno::XInterface >() );
+ xIndex.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ColorPalette") ) ), uno::UNO_QUERY );
+ if ( !xIndex.is() )
+ return new DefaultPalette();
+ return xIndex;
+}
diff --git a/sc/source/ui/vba/vbapalette.hxx b/sc/source/ui/vba/vbapalette.hxx
new file mode 100644
index 000000000000..b51483772674
--- /dev/null
+++ b/sc/source/ui/vba/vbapalette.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_VBAPALETTE_HXX
+#define SC_VBAPALETTE_HXX
+
+#include <vbahelper/vbahelper.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XIndexAccess; }
+ namespace frame { class XModel; }
+} } }
+
+class SfxObjectShell;
+
+class ScVbaPalette
+{
+private:
+ SfxObjectShell* m_pShell;
+public:
+ ScVbaPalette( SfxObjectShell* pShell = 0 ) : m_pShell( pShell ) {}
+ ScVbaPalette( const css::uno::Reference< css::frame::XModel >& rxModel );
+ // if no palette available e.g. because the document doesn't have a
+ // palette defined then a default palette will be returned.
+ css::uno::Reference< css::container::XIndexAccess > getPalette() const;
+ static css::uno::Reference< css::container::XIndexAccess > getDefaultPalette();
+};
+
+#endif //SC_VBAPALETTE_HXX
+
diff --git a/sc/source/ui/vba/vbapane.cxx b/sc/source/ui/vba/vbapane.cxx
new file mode 100644
index 000000000000..29d7a286b402
--- /dev/null
+++ b/sc/source/ui/vba/vbapane.cxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vbapane.hxx"
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "vbarange.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaPane::ScVbaPane(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< sheet::XViewPane > xViewPane ) throw (uno::RuntimeException) :
+ ScVbaPane_BASE( xParent, xContext ),
+ m_xModel( xModel, uno::UNO_SET_THROW ),
+ m_xViewPane( xViewPane, uno::UNO_SET_THROW )
+{
+}
+
+sal_Int32 SAL_CALL
+ScVbaPane::getScrollColumn() throw (uno::RuntimeException)
+{
+ return ( m_xViewPane->getFirstVisibleColumn() + 1 );
+}
+
+void SAL_CALL
+ScVbaPane::setScrollColumn( sal_Int32 _scrollcolumn ) throw (uno::RuntimeException)
+{
+ if( _scrollcolumn < 1 )
+ {
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Column number should not less than 1" ),
+ uno::Reference< uno::XInterface >() );
+ }
+ m_xViewPane->setFirstVisibleColumn( _scrollcolumn - 1 );
+}
+
+sal_Int32 SAL_CALL
+ScVbaPane::getScrollRow() throw (uno::RuntimeException)
+{
+ return ( m_xViewPane->getFirstVisibleRow() + 1 );
+}
+
+void SAL_CALL
+ScVbaPane::setScrollRow( sal_Int32 _scrollrow ) throw (uno::RuntimeException)
+{
+ if( _scrollrow < 1 )
+ {
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Row number should not less than 1" ),
+ uno::Reference< uno::XInterface >() );
+ }
+ m_xViewPane->setFirstVisibleRow( _scrollrow - 1 );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaPane::getVisibleRange() throw (uno::RuntimeException)
+{
+ // TODO: Excel includes partly visible rows/columns, Calc does not
+ table::CellRangeAddress aRangeAddr = m_xViewPane->getVisibleRange();
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xSheetsIA( xDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xSheetsIA->getByIndex( aRangeAddr.Sheet ), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xSheet->getCellRangeByPosition( aRangeAddr.StartColumn, aRangeAddr.StartRow, aRangeAddr.EndColumn, aRangeAddr.EndRow ), uno::UNO_SET_THROW );
+ // TODO: getParent() returns the window, Range needs the worksheet
+ return new ScVbaRange( getParent(), mxContext, xRange );
+}
+
+//Method
+void SAL_CALL
+ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException)
+{
+ rtl::OUString messageBuffer;
+ sal_Int32 downRows = 0;
+ sal_Int32 rightCols = 0;
+ table::CellRangeAddress visibleRange = m_xViewPane->getVisibleRange();
+
+ if( Down.hasValue() )
+ {
+ sal_Int32 down = 0;
+ if( Down >>= down )
+ downRows += down;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" );
+ }
+ if( Up.hasValue() )
+ {
+ sal_Int32 up = 0;
+ if( Up >>= up )
+ downRows -= up;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" );
+ }
+ if( ToRight.hasValue() )
+ {
+ sal_Int32 right = 0;
+ if( ToRight >>= right )
+ rightCols += right;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" );
+ }
+ if( ToLeft.hasValue() )
+ {
+ sal_Int32 left = 0;
+ if( ToLeft >>= left )
+ rightCols -= left;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" );
+ }
+ if( messageBuffer.getLength() > 0 )
+ throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) );
+
+ sal_Int32 newStartRow = visibleRange.StartRow + downRows;
+ if( newStartRow < 0 )
+ newStartRow = 0;
+ sal_Int32 newStartCol = visibleRange.StartColumn + rightCols;
+ if( newStartCol < 0 )
+ newStartCol = 0;
+ m_xViewPane->setFirstVisibleRow( newStartRow );
+ m_xViewPane->setFirstVisibleColumn( newStartCol );
+}
+
+void SAL_CALL
+ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException)
+{
+ rtl::OUString messageBuffer;
+ table::CellRangeAddress visibleRange = m_xViewPane->getVisibleRange();
+
+ sal_Int32 vertPageSize = 1 + visibleRange.EndRow - visibleRange.StartRow;
+ sal_Int32 horizPageSize = 1 + visibleRange.EndColumn - visibleRange.StartColumn;
+ sal_Int32 downPages = 0;
+ sal_Int32 acrossPages = 0;
+ if( Down.hasValue() )
+ {
+ sal_Int32 down = 0;
+ if( Down >>= down )
+ downPages += down;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" );
+ }
+ if( Up.hasValue() )
+ {
+ sal_Int32 up = 0;
+ if( Up >>= up )
+ downPages -= up;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" );
+ }
+ if( ToRight.hasValue() )
+ {
+ sal_Int32 right = 0;
+ if( ToRight >>= right )
+ acrossPages += right;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" );
+ }
+ if( ToLeft.hasValue() )
+ {
+ sal_Int32 left = 0;
+ if( ToLeft >>= left )
+ acrossPages -= left;
+ else
+ messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" );
+ }
+ if( messageBuffer.getLength() > 0 )
+ throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) );
+
+ sal_Int32 newStartRow = visibleRange.StartRow + (downPages * vertPageSize );
+ if( newStartRow < 0 )
+ newStartRow = 0;
+ sal_Int32 newStartCol = visibleRange.StartColumn + (acrossPages * horizPageSize );
+ if( newStartCol < 0 )
+ newStartCol = 0;
+ m_xViewPane->setFirstVisibleRow( newStartRow );
+ m_xViewPane->setFirstVisibleColumn( newStartCol );
+}
+
+// XHelperInterface
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaPane, "ooo.vba.excel.Pane" )
diff --git a/sc/source/ui/vba/vbapane.hxx b/sc/source/ui/vba/vbapane.hxx
new file mode 100644
index 000000000000..ff87a9966d80
--- /dev/null
+++ b/sc/source/ui/vba/vbapane.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PANE_HXX
+#define SC_VBA_PANE_HXX
+
+#include <com/sun/star/sheet/XViewPane.hpp>
+#include <ooo/vba/excel/XPane.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include "excelvbahelper.hxx"
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XPane > ScVbaPane_BASE;
+
+class ScVbaPane : public ScVbaPane_BASE
+{
+public:
+ ScVbaPane(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::sheet::XViewPane > xViewPane ) throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::sheet::XViewPane > getViewPane() { return m_xViewPane; }
+
+ // XPane attributes
+ virtual sal_Int32 SAL_CALL getScrollColumn() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setScrollColumn( sal_Int32 _scrollcolumn ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getScrollRow() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setScrollRow( sal_Int32 _scrollrow ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException);
+
+ // XPane methods
+ virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException);
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+protected:
+ css::uno::Reference< css::frame::XModel > m_xModel;
+ css::uno::Reference< css::sheet::XViewPane > m_xViewPane;
+};
+
+#endif //SC_VBA_PANE_HXX
diff --git a/sc/source/ui/vba/vbapivotcache.cxx b/sc/source/ui/vba/vbapivotcache.cxx
new file mode 100644
index 000000000000..322b42368b48
--- /dev/null
+++ b/sc/source/ui/vba/vbapivotcache.cxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbapivotcache.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaPivotCache::ScVbaPivotCache( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XDataPilotTable >& xTable ) : PivotCacheImpl_BASE( xParent, xContext ), m_xTable( xTable )
+{
+}
+
+void SAL_CALL
+ScVbaPivotCache::Refresh() throw (css::uno::RuntimeException)
+{
+ m_xTable->refresh();
+}
+rtl::OUString&
+ScVbaPivotCache::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaPivotCache") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaPivotCache::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.PivotCache" ) );
+ }
+ return aServiceNames;
+}
+
diff --git a/sc/source/ui/vba/vbapivotcache.hxx b/sc/source/ui/vba/vbapivotcache.hxx
new file mode 100644
index 000000000000..dea3e35d18bd
--- /dev/null
+++ b/sc/source/ui/vba/vbapivotcache.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PIVOTCACHE_HXX
+#define SC_VBA_PIVOTCACHE_HXX
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+
+#include <ooo/vba/excel/XPivotCache.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1<ov::excel::XPivotCache > PivotCacheImpl_BASE;
+
+class ScVbaPivotCache : public PivotCacheImpl_BASE
+{
+ css::uno::Reference< css::sheet::XDataPilotTable > m_xTable;
+public:
+ ScVbaPivotCache( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XDataPilotTable >& xTable );
+ virtual void SAL_CALL Refresh() throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_PIVOTCACHE_HXX
diff --git a/sc/source/ui/vba/vbapivottable.cxx b/sc/source/ui/vba/vbapivottable.cxx
new file mode 100644
index 000000000000..e5d78602dcdd
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottable.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbapivottable.hxx"
+#include "vbapivotcache.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaPivotTable::ScVbaPivotTable( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XDataPilotTable >& xTable ) : PivotTableImpl_BASE( uno::Reference< XHelperInterface >(), xContext), m_xTable( xTable )
+{
+}
+
+uno::Reference< excel::XPivotCache >
+ScVbaPivotTable::PivotCache() throw (uno::RuntimeException)
+{
+ // #FIXME with a quick example failed to determine what the parent
+ // should be, leaving as null at the moment
+ return new ScVbaPivotCache( uno::Reference< XHelperInterface >(), mxContext, m_xTable );
+}
+
+rtl::OUString&
+ScVbaPivotTable::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaPivotTable") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaPivotTable::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.PivotTable" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbapivottable.hxx b/sc/source/ui/vba/vbapivottable.hxx
new file mode 100644
index 000000000000..e6e341830489
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottable.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PIVOTTABLE_HXX
+#define SC_VBA_PIVOTTABLE_HXX
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+#include <ooo/vba/excel/XPivotTable.hpp>
+#include "excelvbahelper.hxx"
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XPivotTable > PivotTableImpl_BASE;
+
+class ScVbaPivotTable : public PivotTableImpl_BASE
+{
+ css::uno::Reference< css::sheet::XDataPilotTable > m_xTable;
+public:
+ ScVbaPivotTable( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XDataPilotTable >& xTable );
+ virtual css::uno::Reference< ov::excel::XPivotCache > SAL_CALL PivotCache( ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_PIVOTTABLE_HXX
diff --git a/sc/source/ui/vba/vbapivottables.cxx b/sc/source/ui/vba/vbapivottables.cxx
new file mode 100644
index 000000000000..fcbf347a3cd4
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottables.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbapivottables.hxx"
+#include "vbapivottable.hxx"
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+#include <ooo/vba/excel/XPivotTable.hpp>
+
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+uno::Any DataPilotToPivotTable( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext )
+{
+ uno::Reference< sheet::XDataPilotTable > xTable( aSource, uno::UNO_QUERY_THROW );
+ return uno::makeAny( uno::Reference< excel::XPivotTable > ( new ScVbaPivotTable( xContext, xTable ) ) );
+}
+
+class PivotTableEnumeration : public EnumerationHelperImpl
+{
+public:
+ PivotTableEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ return DataPilotToPivotTable( m_xEnumeration->nextElement(), m_xContext );
+ }
+
+};
+
+ScVbaPivotTables::ScVbaPivotTables( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ): ScVbaPivotTables_BASE( xParent, xContext, xIndexAccess )
+{
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaPivotTables::createEnumeration() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new PivotTableEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration() );
+}
+
+uno::Any
+ScVbaPivotTables::createCollectionObject( const css::uno::Any& aSource )
+{
+ return DataPilotToPivotTable( aSource, mxContext );
+}
+
+uno::Type
+ScVbaPivotTables::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XPivotTable::static_type(0);
+}
+
+rtl::OUString&
+ScVbaPivotTables::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaPivotTables") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaPivotTables::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.PivotTables") );
+ }
+ return sNames;
+}
diff --git a/sc/source/ui/vba/vbapivottables.hxx b/sc/source/ui/vba/vbapivottables.hxx
new file mode 100644
index 000000000000..3354d8a82953
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottables.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PIVOTTABLES_HXX
+#define SC_VBA_PIVOTTABLES_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <ooo/vba/excel/XPivotTables.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include "excelvbahelper.hxx"
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+
+typedef CollTestImplHelper< ov::excel::XPivotTables > ScVbaPivotTables_BASE;
+
+class ScVbaPivotTables : public ScVbaPivotTables_BASE
+{
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+public:
+ ScVbaPivotTables( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+ virtual ~ScVbaPivotTables() {}
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+
+ // XPivotTables
+
+ // ScVbaPivotTables_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+
+ virtual rtl::OUString& getServiceImplName();
+
+};
+
+#endif //SC_VBA_PIVOTTABLES
diff --git a/sc/source/ui/vba/vbapropvalue.cxx b/sc/source/ui/vba/vbapropvalue.cxx
new file mode 100644
index 000000000000..ff821d17f479
--- /dev/null
+++ b/sc/source/ui/vba/vbapropvalue.cxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbapropvalue.hxx"
+
+using namespace com::sun::star;
+
+ScVbaPropValue::ScVbaPropValue( PropListener* pListener ) : m_pListener( pListener )
+{
+}
+
+css::uno::Any SAL_CALL
+ScVbaPropValue::getValue() throw (css::uno::RuntimeException)
+{
+ return m_pListener->getValueEvent();
+}
+
+void SAL_CALL
+ScVbaPropValue::setValue( const css::uno::Any& _value ) throw (css::uno::RuntimeException)
+{
+ m_pListener->setValueEvent( _value );
+}
diff --git a/sc/source/ui/vba/vbapropvalue.hxx b/sc/source/ui/vba/vbapropvalue.hxx
new file mode 100644
index 000000000000..af748dae5585
--- /dev/null
+++ b/sc/source/ui/vba/vbapropvalue.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_PROPVALULE_HXX
+#define SC_VBA_PROPVALULE_HXX
+#include <ooo/vba/XPropValue.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include "excelvbahelper.hxx"
+
+typedef ::cppu::WeakImplHelper1< ov::XPropValue > PropValueImpl_BASE;
+
+class PropListener
+{
+public:
+ virtual void setValueEvent( const css::uno::Any& value ) = 0;
+ virtual css::uno::Any getValueEvent() = 0;
+};
+
+
+class ScVbaPropValue : public PropValueImpl_BASE
+{
+ PropListener* m_pListener;
+public:
+ ScVbaPropValue( PropListener* pListener );
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setValue( const css::uno::Any& _value ) throw (css::uno::RuntimeException);
+
+ rtl::OUString SAL_CALL getDefaultPropertyName() throw (css::uno::RuntimeException) { return ::rtl::OUString::createFromAscii("Value"); }
+
+};
+#endif //SC_VBA_PROPVALULE_HXX
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
new file mode 100755
index 000000000000..455af075306c
--- /dev/null
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -0,0 +1,5671 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vbahelper/helperdecl.hxx>
+
+#include <comphelper/unwrapargs.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/objsh.hxx>
+
+#include <com/sun/star/script/ArrayWrapper.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XGoalSeek.hpp>
+#include <com/sun/star/sheet/XSheetOperation.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+#include <com/sun/star/sheet/XCellSeries.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XFunctionAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/table/XCellCursor.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/table/XTableColumns.hpp>
+#include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XReplaceable.hpp>
+#include <com/sun/star/util/XSortable.hpp>
+#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>
+#include <com/sun/star/util/TriState.hpp>
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+
+//#include <com/sun/star/sheet/CellDeleteMode.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/sheet/XSubTotalCalculatable.hpp>
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hdl>
+
+#include <ooo/vba/excel/XlPasteSpecialOperation.hpp>
+#include <ooo/vba/excel/XlPasteType.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+#include <ooo/vba/excel/XlFindLookIn.hpp>
+#include <ooo/vba/excel/XlLookAt.hpp>
+#include <ooo/vba/excel/XlSearchOrder.hpp>
+#include <ooo/vba/excel/XlSortOrder.hpp>
+#include <ooo/vba/excel/XlYesNoGuess.hpp>
+#include <ooo/vba/excel/XlSortOrientation.hpp>
+#include <ooo/vba/excel/XlSortMethod.hpp>
+#include <ooo/vba/excel/XlDirection.hpp>
+#include <ooo/vba/excel/XlSortDataOption.hpp>
+#include <ooo/vba/excel/XlDeleteShiftDirection.hpp>
+#include <ooo/vba/excel/XlInsertShiftDirection.hpp>
+#include <ooo/vba/excel/XlReferenceStyle.hpp>
+#include <ooo/vba/excel/XlBordersIndex.hpp>
+#include <ooo/vba/excel/XlPageBreak.hpp>
+#include <ooo/vba/excel/XlAutoFilterOperator.hpp>
+#include <ooo/vba/excel/XlAutoFillType.hpp>
+#include <ooo/vba/excel/XlTextParsingType.hpp>
+#include <ooo/vba/excel/XlTextQualifier.hpp>
+#include <ooo/vba/excel/XlCellType.hpp>
+#include <ooo/vba/excel/XlSpecialCellsValue.hpp>
+#include <ooo/vba/excel/XlConsolidationFunction.hpp>
+#include <ooo/vba/excel/XlSearchDirection.hpp>
+
+#include <scitems.hxx>
+#include <svl/srchitem.hxx>
+#include <cellsuno.hxx>
+#include <dbcolect.hxx>
+#include "docfunc.hxx"
+
+#include <sfx2/dispatch.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/itemwrapper.hxx>
+#include <sc.hrc>
+#include <globstr.hrc>
+#include <unonames.hxx>
+
+#include "vbarange.hxx"
+#include "vbafont.hxx"
+#include "vbacomment.hxx"
+#include "vbainterior.hxx"
+#include "vbacharacters.hxx"
+#include "vbaborders.hxx"
+#include "vbaworksheet.hxx"
+#include "vbavalidation.hxx"
+#include "vbahyperlinks.hxx"
+
+#include "tabvwsh.hxx"
+#include "rangelst.hxx"
+#include "convuno.hxx"
+#include "compiler.hxx"
+#include "attrib.hxx"
+#include "undodat.hxx"
+#include "dbdocfun.hxx"
+#include "patattr.hxx"
+#include "olinetab.hxx"
+#include <comphelper/anytostring.hxx>
+
+#include <global.hxx>
+
+#include "vbaglobals.hxx"
+#include "vbastyle.hxx"
+#include <vector>
+#include <vbahelper/vbacollectionimpl.hxx>
+// begin test includes
+#include <com/sun/star/sheet/FunctionArgument.hpp>
+// end test includes
+
+#include <ooo/vba/excel/Range.hpp>
+#include <com/sun/star/bridge/oleautomation/Date.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+using ::std::vector;
+
+// * 1 point = 1/72 inch = 20 twips
+// * 1 inch = 72 points = 1440 twips
+// * 1 cm = 567 twips
+double lcl_hmmToPoints( double nVal ) { return ( (double)((nVal /1000 ) * 567 ) / 20 ); }
+
+static const sal_Int16 supportedIndexTable[] = { excel::XlBordersIndex::xlEdgeLeft, excel::XlBordersIndex::xlEdgeTop, excel::XlBordersIndex::xlEdgeBottom, excel::XlBordersIndex::xlEdgeRight, excel::XlBordersIndex::xlDiagonalDown, excel::XlBordersIndex::xlDiagonalUp, excel::XlBordersIndex::xlInsideVertical, excel::XlBordersIndex::xlInsideHorizontal };
+
+USHORT lcl_pointsToTwips( double nVal )
+{
+ nVal = nVal * static_cast<double>(20);
+ short nTwips = static_cast<short>(nVal);
+ return nTwips;
+}
+double lcl_TwipsToPoints( USHORT nVal )
+{
+ double nPoints = nVal;
+ return nPoints / 20;
+}
+
+double lcl_Round2DecPlaces( double nVal )
+{
+ nVal = (nVal * (double)100);
+ long tmp = static_cast<long>(nVal);
+ if ( ( ( nVal - tmp ) >= 0.5 ) )
+ ++tmp;
+ nVal = tmp;
+ nVal = nVal/100;
+ return nVal;
+}
+
+uno::Any lcl_makeRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns )
+{
+ uno::Reference< table::XCellRange > xCellRange( aAny, uno::UNO_QUERY_THROW );
+ return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xCellRange, bIsRows, bIsColumns ) ) );
+}
+
+uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRanges >& xLocSheetCellRanges, ScDocShell* pDoc )
+{
+ uno::Reference< excel::XRange > xRange;
+ uno::Sequence< table::CellRangeAddress > sAddresses = xLocSheetCellRanges->getRangeAddresses();
+ ScRangeList aCellRanges;
+ sal_Int32 nLen = sAddresses.getLength();
+ if ( nLen )
+ {
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ ScRange refRange;
+ ScUnoConversion::FillScRange( refRange, sAddresses[ index ] );
+ aCellRanges.Append( refRange );
+ }
+ // Single range
+ if ( aCellRanges.First() == aCellRanges.Last() )
+ {
+ uno::Reference< table::XCellRange > xTmpRange( new ScCellRangeObj( pDoc, *aCellRanges.First() ) );
+ xRange = new ScVbaRange( xParent, xContext, xTmpRange );
+ }
+ else
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDoc, aCellRanges ) );
+ xRange = new ScVbaRange( xParent, xContext, xRanges );
+ }
+ }
+ return xRange;
+}
+
+ScCellRangesBase* ScVbaRange::getCellRangesBase() throw ( uno::RuntimeException )
+{
+ if( mxRanges.is() )
+ return ScCellRangesBase::getImplementation( mxRanges );
+ if( mxRange.is() )
+ return ScCellRangesBase::getImplementation( mxRange );
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("General Error creating range - Unknown" ), uno::Reference< uno::XInterface >() );
+}
+
+ScCellRangeObj* ScVbaRange::getCellRangeObj() throw ( uno::RuntimeException )
+{
+ return dynamic_cast< ScCellRangeObj* >( getCellRangesBase() );
+}
+
+ScCellRangesObj* ScVbaRange::getCellRangesObj() throw ( uno::RuntimeException )
+{
+ return dynamic_cast< ScCellRangesObj* >( getCellRangesBase() );
+}
+
+SfxItemSet* ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException )
+{
+ SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() );
+ if ( !pDataSet )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for range" ) ), uno::Reference< uno::XInterface >() );
+ return pDataSet;
+}
+
+class SingleRangeEnumeration : public EnumerationHelper_BASE
+{
+ uno::Reference< XHelperInterface > m_xParent;
+ uno::Reference< table::XCellRange > m_xRange;
+ uno::Reference< uno::XComponentContext > mxContext;
+ bool bHasMore;
+public:
+
+ SingleRangeEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { }
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException) { return bHasMore; }
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !bHasMore )
+ throw container::NoSuchElementException();
+ bHasMore = false;
+ return uno::makeAny( m_xRange );
+ }
+};
+
+// very simple class to pass to ScVbaCollectionBaseImpl containing
+// just one item
+typedef ::cppu::WeakImplHelper2< container::XIndexAccess, container::XEnumerationAccess > SingleRange_BASE;
+
+class SingleRangeIndexAccess : public SingleRange_BASE
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< table::XCellRange > m_xRange;
+ uno::Reference< uno::XComponentContext > mxContext;
+ SingleRangeIndexAccess(); // not defined
+public:
+ SingleRangeIndexAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):mxParent( xParent ), m_xRange( xRange ), mxContext( xContext ) {}
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount() throw (::uno::RuntimeException) { return 1; }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( Index != 0 )
+ throw lang::IndexOutOfBoundsException();
+ return uno::makeAny( m_xRange );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException){ return table::XCellRange::static_type(0); }
+
+ virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException) { return sal_True; }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxParent, mxContext, m_xRange ); }
+
+};
+
+
+
+class RangesEnumerationImpl : public EnumerationHelperImpl
+{
+ bool mbIsRows;
+ bool mbIsColumns;
+public:
+
+ RangesEnumerationImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ return lcl_makeRange( m_xParent, m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns );
+ }
+};
+
+
+class ScVbaRangeAreas : public ScVbaCollectionBaseImpl
+{
+ bool mbIsRows;
+ bool mbIsColumns;
+public:
+ ScVbaRangeAreas( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( xParent, xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
+
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException);
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException){ return excel::XRange::static_type(0); }
+
+ virtual uno::Any createCollectionObject( const uno::Any& aSource );
+
+ virtual rtl::OUString& getServiceImplName() { static rtl::OUString sDummy; return sDummy; }
+
+ virtual uno::Sequence< rtl::OUString > getServiceNames() { return uno::Sequence< rtl::OUString >(); }
+
+};
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaRangeAreas::createEnumeration() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new RangesEnumerationImpl( mxParent, mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns );
+}
+
+uno::Any
+ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource )
+{
+ return lcl_makeRange( mxParent, mxContext, aSource, mbIsRows, mbIsColumns );
+}
+
+// assume that xIf is infact a ScCellRangesBase
+ScDocShell*
+getDocShellFromIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException )
+{
+ ScCellRangesBase* pUno = ScCellRangesBase::getImplementation( xIf );
+ if ( !pUno )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >() );
+ return pUno->GetDocShell();
+}
+
+ScDocShell*
+getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
+{
+ // need the ScCellRangesBase to get docshell
+ uno::Reference< uno::XInterface > xIf( xRange, uno::UNO_QUERY_THROW );
+ return getDocShellFromIf(xIf );
+}
+
+ScDocShell*
+getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException )
+{
+ // need the ScCellRangesBase to get docshell
+ uno::Reference< uno::XInterface > xIf( xRanges, uno::UNO_QUERY_THROW );
+ return getDocShellFromIf(xIf );
+}
+
+uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException )
+{
+ ScDocShell* pDocShell = getDocShellFromIf(xIf );
+ return pDocShell->GetModel();
+}
+
+uno::Reference< frame::XModel > getModelFromRange( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
+{
+ uno::Reference< uno::XInterface > xIf( xRange, uno::UNO_QUERY_THROW );
+ return getModelFromXIf( xIf );
+}
+
+ScDocument*
+getDocumentFromRange( const uno::Reference< table::XCellRange >& xRange )
+{
+ ScDocShell* pDocShell = getDocShellFromRange( xRange );
+ if ( !pDocShell )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying docshell from uno range object" ) ), uno::Reference< uno::XInterface >() );
+ ScDocument* pDoc = pDocShell->GetDocument();
+ return pDoc;
+}
+
+
+ScDocument*
+ScVbaRange::getScDocument() throw (uno::RuntimeException)
+{
+ if ( mxRanges.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ return getDocumentFromRange( xRange );
+ }
+ return getDocumentFromRange( mxRange );
+}
+
+ScDocShell*
+ScVbaRange::getScDocShell() throw (uno::RuntimeException)
+{
+ if ( mxRanges.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ return getDocShellFromRange( xRange );
+ }
+ return getDocShellFromRange( mxRange );
+}
+
+/*static*/ ScVbaRange* ScVbaRange::getImplementation( const uno::Reference< excel::XRange >& rxRange )
+{
+ // FIXME: always save to use dynamic_cast? Or better to (implement and) use XTunnel?
+ return dynamic_cast< ScVbaRange* >( rxRange.get() );
+}
+
+uno::Reference< frame::XModel > ScVbaRange::getUnoModel() throw (uno::RuntimeException)
+{
+ if( ScDocShell* pDocShell = getScDocShell() )
+ return pDocShell->GetModel();
+ throw uno::RuntimeException();
+}
+
+/*static*/ uno::Reference< frame::XModel > ScVbaRange::getUnoModel( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException)
+{
+ if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) )
+ return pScVbaRange->getUnoModel();
+ throw uno::RuntimeException();
+}
+
+const ScRangeList& ScVbaRange::getScRangeList() throw (uno::RuntimeException)
+{
+ if( ScCellRangesBase* pScRangesBase = getCellRangesBase() )
+ return pScRangesBase->GetRangeList();
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain UNO range implementation object" ) ), uno::Reference< uno::XInterface >() );
+}
+
+/*static*/ const ScRangeList& ScVbaRange::getScRangeList( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException)
+{
+ if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) )
+ return pScVbaRange->getScRangeList();
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain VBA range implementation object" ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+class NumFormatHelper
+{
+ uno::Reference< util::XNumberFormatsSupplier > mxSupplier;
+ uno::Reference< beans::XPropertySet > mxRangeProps;
+ uno::Reference< util::XNumberFormats > mxFormats;
+public:
+ NumFormatHelper( const uno::Reference< table::XCellRange >& xRange )
+ {
+ mxSupplier.set( getModelFromRange( xRange ), uno::UNO_QUERY_THROW );
+ mxRangeProps.set( xRange, uno::UNO_QUERY_THROW);
+ mxFormats = mxSupplier->getNumberFormats();
+ }
+ uno::Reference< beans::XPropertySet > getNumberProps()
+ {
+ long nIndexKey = 0;
+ uno::Any aValue = mxRangeProps->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat")));
+ aValue >>= nIndexKey;
+
+ if ( mxFormats.is() )
+ return mxFormats->getByKey( nIndexKey );
+ return uno::Reference< beans::XPropertySet > ();
+ }
+
+ bool isBooleanType()
+ {
+
+ if ( getNumberFormat() & util::NumberFormat::LOGICAL )
+ return true;
+ return false;
+ }
+
+ bool isDateType()
+ {
+ sal_Int16 nType = getNumberFormat();
+ if(( nType & util::NumberFormat::DATETIME ))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ rtl::OUString getNumberFormatString()
+ {
+ uno::Reference< uno::XInterface > xIf( mxRangeProps, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUnoCellRange = ScCellRangesBase::getImplementation( xIf );
+ if ( pUnoCellRange )
+ {
+
+ SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( pUnoCellRange );
+ SfxItemState eState = pDataSet->GetItemState( ATTR_VALUE_FORMAT, TRUE, NULL);
+ // one of the cells in the range is not like the other ;-)
+ // so return a zero length format to indicate that
+ if ( eState == SFX_ITEM_DONTCARE )
+ return rtl::OUString();
+ }
+
+
+ uno::Reference< beans::XPropertySet > xNumberProps( getNumberProps(), uno::UNO_QUERY_THROW );
+ ::rtl::OUString aFormatString;
+ uno::Any aString = xNumberProps->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FormatString")));
+ aString >>= aFormatString;
+ return aFormatString;
+ }
+
+ sal_Int16 getNumberFormat()
+ {
+ uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps();
+ sal_Int16 nType = ::comphelper::getINT16(
+ xNumberProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Type" ) ) );
+ return nType;
+ }
+
+ bool setNumberFormat( const rtl::OUString& rFormat )
+ {
+ lang::Locale aLocale;
+ uno::Reference< beans::XPropertySet > xNumProps = getNumberProps();
+ xNumProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Locale" ) ) >>= aLocale;
+ sal_Int32 nNewIndex = mxFormats->queryKey(rFormat, aLocale, false );
+ if ( nNewIndex == -1 ) // format not defined
+ {
+ nNewIndex = mxFormats->addNew( rFormat, aLocale );
+ }
+ mxRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat") ), uno::makeAny( nNewIndex ) );
+ return true;
+ }
+
+ bool setNumberFormat( sal_Int16 nType )
+ {
+ uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps();
+ lang::Locale aLocale;
+ xNumberProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Locale" ) ) >>= aLocale;
+ uno::Reference<util::XNumberFormatTypes> xTypes( mxFormats, uno::UNO_QUERY );
+ if ( xTypes.is() )
+ {
+ sal_Int32 nNewIndex = xTypes->getStandardFormat( nType, aLocale );
+ mxRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat") ), uno::makeAny( nNewIndex ) );
+ return true;
+ }
+ return false;
+ }
+
+};
+
+struct CellPos
+{
+ CellPos():m_nRow(-1), m_nCol(-1), m_nArea(0) {};
+ CellPos( sal_Int32 nRow, sal_Int32 nCol, sal_Int32 nArea ):m_nRow(nRow), m_nCol(nCol), m_nArea( nArea ) {};
+sal_Int32 m_nRow;
+sal_Int32 m_nCol;
+sal_Int32 m_nArea;
+};
+
+typedef ::cppu::WeakImplHelper1< container::XEnumeration > CellsEnumeration_BASE;
+typedef ::std::vector< CellPos > vCellPos;
+
+// #FIXME - QUICK
+// we could probably could and should modify CellsEnumeration below
+// to handle rows and columns ( but I do this seperately for now
+// and.. this class only handles singe areas ( does it have to handle
+// multi area ranges?? )
+class ColumnsRowEnumeration: public CellsEnumeration_BASE
+{
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< excel::XRange > mxRange;
+ sal_Int32 mMaxElems;
+ sal_Int32 mCurElem;
+
+public:
+ ColumnsRowEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< excel::XRange >& xRange, sal_Int32 nElems ) : mxContext( xContext ), mxRange( xRange ), mMaxElems( nElems ), mCurElem( 0 )
+ {
+ }
+
+ virtual ::sal_Bool SAL_CALL hasMoreElements() throw (::uno::RuntimeException){ return mCurElem < mMaxElems; }
+
+ virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ sal_Int32 vbaIndex = 1 + mCurElem++;
+ return uno::makeAny( mxRange->Item( uno::makeAny( vbaIndex ), uno::Any() ) );
+ }
+};
+
+class CellsEnumeration : public CellsEnumeration_BASE
+{
+ uno::WeakReference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< XCollection > m_xAreas;
+ vCellPos m_CellPositions;
+ vCellPos::const_iterator m_it;
+
+ uno::Reference< table::XCellRange > getArea( sal_Int32 nVBAIndex ) throw ( uno::RuntimeException )
+ {
+ if ( nVBAIndex < 1 || nVBAIndex > m_xAreas->getCount() )
+ throw uno::RuntimeException();
+ uno::Reference< excel::XRange > xRange( m_xAreas->Item( uno::makeAny(nVBAIndex), uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( ScVbaRange::getCellRange( xRange ), uno::UNO_QUERY_THROW );
+ return xCellRange;
+ }
+
+ void populateArea( sal_Int32 nVBAIndex )
+ {
+ uno::Reference< table::XCellRange > xRange = getArea( nVBAIndex );
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount();
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+ for ( sal_Int32 i=0; i<nRowCount; ++i )
+ {
+ for ( sal_Int32 j=0; j<nColCount; ++j )
+ m_CellPositions.push_back( CellPos( i,j,nVBAIndex ) );
+ }
+ }
+public:
+ CellsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxParent( xParent ), mxContext( xContext ), m_xAreas( xAreas )
+ {
+ sal_Int32 nItems = m_xAreas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ populateArea( index );
+ }
+ m_it = m_CellPositions.begin();
+ }
+ virtual ::sal_Bool SAL_CALL hasMoreElements() throw (::uno::RuntimeException){ return m_it != m_CellPositions.end(); }
+
+ virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ CellPos aPos = *(m_it)++;
+
+ uno::Reference< table::XCellRange > xRangeArea = getArea( aPos.m_nArea );
+ uno::Reference< table::XCellRange > xCellRange( xRangeArea->getCellByPosition( aPos.m_nCol, aPos.m_nRow ), uno::UNO_QUERY_THROW );
+ return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, xCellRange ) ) );
+
+ }
+};
+
+
+const static ::rtl::OUString ISVISIBLE( RTL_CONSTASCII_USTRINGPARAM( "IsVisible"));
+const static ::rtl::OUString WIDTH( RTL_CONSTASCII_USTRINGPARAM( "Width"));
+const static ::rtl::OUString HEIGHT( RTL_CONSTASCII_USTRINGPARAM( "Height"));
+const static ::rtl::OUString POSITION( RTL_CONSTASCII_USTRINGPARAM( "Position"));
+const static rtl::OUString EQUALS( RTL_CONSTASCII_USTRINGPARAM("=") );
+const static rtl::OUString NOTEQUALS( RTL_CONSTASCII_USTRINGPARAM("<>") );
+const static rtl::OUString GREATERTHAN( RTL_CONSTASCII_USTRINGPARAM(">") );
+const static rtl::OUString GREATERTHANEQUALS( RTL_CONSTASCII_USTRINGPARAM(">=") );
+const static rtl::OUString LESSTHAN( RTL_CONSTASCII_USTRINGPARAM("<") );
+const static rtl::OUString LESSTHANEQUALS( RTL_CONSTASCII_USTRINGPARAM("<=") );
+const static rtl::OUString CONTS_HEADER( RTL_CONSTASCII_USTRINGPARAM("ContainsHeader" ));
+const static rtl::OUString INSERTPAGEBREAKS( RTL_CONSTASCII_USTRINGPARAM("InsertPageBreaks" ));
+const static rtl::OUString STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY( RTL_CONSTASCII_USTRINGPARAM("The command you chose cannot be performed with multiple selections.\nSelect a single range and click the command again") );
+const static rtl::OUString STR_ERRORMESSAGE_NOCELLSWEREFOUND( RTL_CONSTASCII_USTRINGPARAM("No cells were found") );
+const static rtl::OUString STR_ERRORMESSAGE_APPLIESTOROWCOLUMNSONLY( RTL_CONSTASCII_USTRINGPARAM("Property only applicable for Columns and Rows") );
+const static rtl::OUString CELLSTYLE( RTL_CONSTASCII_USTRINGPARAM("CellStyle") );
+
+class CellValueSetter : public ValueSetter
+{
+protected:
+ uno::Any maValue;
+ uno::TypeClass mTypeClass;
+public:
+ CellValueSetter( const uno::Any& aValue );
+ virtual bool processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell );
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell );
+
+};
+
+CellValueSetter::CellValueSetter( const uno::Any& aValue ): maValue( aValue ), mTypeClass( aValue.getValueTypeClass() ) {}
+
+void
+CellValueSetter::visitNode( sal_Int32 /*i*/, sal_Int32 /*j*/, const uno::Reference< table::XCell >& xCell )
+{
+ processValue( maValue, xCell );
+}
+
+bool
+CellValueSetter::processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell )
+{
+
+ bool isExtracted = false;
+ switch ( aValue.getValueTypeClass() )
+ {
+ case uno::TypeClass_BOOLEAN:
+ {
+ sal_Bool bState = sal_False;
+ if ( aValue >>= bState )
+ {
+ uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
+ if ( bState )
+ xCell->setValue( (double) 1 );
+ else
+ xCell->setValue( (double) 0 );
+ NumFormatHelper cellNumFormat( xRange );
+ cellNumFormat.setNumberFormat( util::NumberFormat::LOGICAL );
+ }
+ break;
+ }
+ case uno::TypeClass_STRING:
+ {
+ rtl::OUString aString;
+ if ( aValue >>= aString )
+ {
+ uno::Reference< text::XTextRange > xTextRange( xCell, uno::UNO_QUERY_THROW );
+ xTextRange->setString( aString );
+ }
+ else
+ isExtracted = false;
+ break;
+ }
+ default:
+ {
+ double nDouble = 0.0;
+ if ( aValue >>= nDouble )
+ xCell->setValue( nDouble );
+ else
+ isExtracted = false;
+ break;
+ }
+ }
+ return isExtracted;
+
+}
+
+
+class CellValueGetter : public ValueGetter
+{
+protected:
+ uno::Any maValue;
+ uno::TypeClass mTypeClass;
+public:
+ CellValueGetter() {}
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell );
+ virtual void processValue( sal_Int32 x, sal_Int32 y, const uno::Any& aValue );
+ const uno::Any& getValue() const { return maValue; }
+
+};
+
+void
+CellValueGetter::processValue( sal_Int32 /*x*/, sal_Int32 /*y*/, const uno::Any& aValue )
+{
+ maValue = aValue;
+}
+void CellValueGetter::visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
+{
+ uno::Any aValue;
+ table::CellContentType eType = xCell->getType();
+ if( eType == table::CellContentType_VALUE || eType == table::CellContentType_FORMULA )
+ {
+ if ( eType == table::CellContentType_FORMULA )
+ {
+
+ rtl::OUString sFormula = xCell->getFormula();
+ if ( sFormula.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("=TRUE()") ) ) )
+ aValue <<= sal_True;
+ else if ( sFormula.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("=FALSE()") ) ) )
+ aValue <<= sal_False;
+ else
+ {
+ uno::Reference< beans::XPropertySet > xProp( xCell, uno::UNO_QUERY_THROW );
+
+ table::CellContentType eFormulaType = table::CellContentType_VALUE;
+ // some formulas give textual results
+ xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FormulaResultType" ) ) ) >>= eFormulaType;
+
+ if ( eFormulaType == table::CellContentType_TEXT )
+ {
+ uno::Reference< text::XTextRange > xTextRange(xCell, ::uno::UNO_QUERY_THROW);
+ aValue <<= xTextRange->getString();
+ }
+ else
+ aValue <<= xCell->getValue();
+ }
+ }
+ else
+ {
+ uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
+ NumFormatHelper cellFormat( xRange );
+ if ( cellFormat.isBooleanType() )
+ aValue = uno::makeAny( ( xCell->getValue() != 0.0 ) );
+ else if ( cellFormat.isDateType() )
+ aValue = uno::makeAny( bridge::oleautomation::Date( xCell->getValue() ) );
+ else
+ aValue <<= xCell->getValue();
+ }
+ }
+ if( eType == table::CellContentType_TEXT )
+ {
+ uno::Reference< text::XTextRange > xTextRange(xCell, ::uno::UNO_QUERY_THROW);
+ aValue <<= xTextRange->getString();
+ }
+ processValue( x,y,aValue );
+}
+
+class CellFormulaValueSetter : public CellValueSetter
+{
+private:
+ ScDocument* m_pDoc;
+ formula::FormulaGrammar::Grammar m_eGrammar;
+public:
+ CellFormulaValueSetter( const uno::Any& aValue, ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ):CellValueSetter( aValue ), m_pDoc( pDoc ), m_eGrammar( eGram ){}
+protected:
+ bool processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell )
+ {
+ rtl::OUString sFormula;
+ double aDblValue = 0.0;
+ if ( aValue >>= sFormula )
+ {
+ // convert to CONV_OOO style formula string because XCell::setFormula
+ // always compile it in CONV_OOO style. Perhaps css.sheet.FormulaParser
+ // should be used in future to directly pass formula tokens.
+ if ( m_eGrammar != formula::FormulaGrammar::GRAM_PODF_A1 && ( sFormula.trim().indexOf('=') == 0 ) )
+ {
+ uno::Reference< uno::XInterface > xIf( xCell, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
+ if ( pUnoRangesBase )
+ {
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+ ScCompiler aCompiler( m_pDoc, aCellRanges.First()->aStart );
+ aCompiler.SetGrammar(m_eGrammar);
+ // compile the string in the format passed in
+ aCompiler.CompileString( sFormula );
+ // set desired convention to that of the document
+ aCompiler.SetGrammar( formula::FormulaGrammar::GRAM_PODF_A1 );
+ String sConverted;
+ aCompiler.CreateStringFromTokenArray(sConverted);
+ sFormula = EQUALS + sConverted;
+ }
+ }
+
+ xCell->setFormula( sFormula );
+ return true;
+ }
+ else if ( aValue >>= aDblValue )
+ {
+ xCell->setValue( aDblValue );
+ return true;
+ }
+ return false;
+ }
+
+};
+
+class CellFormulaValueGetter : public CellValueGetter
+{
+private:
+ ScDocument* m_pDoc;
+ formula::FormulaGrammar::Grammar m_eGrammar;
+public:
+ CellFormulaValueGetter(ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ) : CellValueGetter( ), m_pDoc( pDoc ), m_eGrammar( eGram ) {}
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
+ {
+ uno::Any aValue;
+ aValue <<= xCell->getFormula();
+ rtl::OUString sVal;
+ aValue >>= sVal;
+ uno::Reference< uno::XInterface > xIf( xCell, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
+ if ( ( xCell->getType() == table::CellContentType_FORMULA ) &&
+ pUnoRangesBase )
+ {
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+ ScCompiler aCompiler( m_pDoc, aCellRanges.First()->aStart );
+ aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_DEFAULT);
+ aCompiler.CompileString( sVal );
+ // set desired convention
+ aCompiler.SetGrammar( m_eGrammar );
+ String sConverted;
+ aCompiler.CreateStringFromTokenArray(sConverted);
+ sVal = EQUALS + sConverted;
+ aValue <<= sVal;
+ }
+
+ processValue( x,y,aValue );
+ }
+
+};
+
+
+class Dim2ArrayValueGetter : public ArrayVisitor
+{
+protected:
+ uno::Any maValue;
+ ValueGetter& mValueGetter;
+ virtual void processValue( sal_Int32 x, sal_Int32 y, const uno::Any& aValue )
+ {
+ uno::Sequence< uno::Sequence< uno::Any > >& aMatrix = *( uno::Sequence< uno::Sequence< uno::Any > >* )( maValue.getValue() );
+ aMatrix[x][y] = aValue;
+ }
+
+public:
+ Dim2ArrayValueGetter(sal_Int32 nRowCount, sal_Int32 nColCount, ValueGetter& rValueGetter ): mValueGetter(rValueGetter)
+ {
+ uno::Sequence< uno::Sequence< uno::Any > > aMatrix;
+ aMatrix.realloc( nRowCount );
+ for ( sal_Int32 index = 0; index < nRowCount; ++index )
+ aMatrix[index].realloc( nColCount );
+ maValue <<= aMatrix;
+ }
+ void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
+
+ {
+ mValueGetter.visitNode( x, y, xCell );
+ processValue( x, y, mValueGetter.getValue() );
+ }
+ const uno::Any& getValue() const { return maValue; }
+
+};
+
+const static rtl::OUString sNA = rtl::OUString::createFromAscii("#N/A");
+
+class Dim1ArrayValueSetter : public ArrayVisitor
+{
+ uno::Sequence< uno::Any > aMatrix;
+ sal_Int32 nColCount;
+ ValueSetter& mCellValueSetter;
+public:
+ Dim1ArrayValueSetter( const uno::Any& aValue, ValueSetter& rCellValueSetter ):mCellValueSetter( rCellValueSetter )
+ {
+ aValue >>= aMatrix;
+ nColCount = aMatrix.getLength();
+ }
+ virtual void visitNode( sal_Int32 /*x*/, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
+ {
+ if ( y < nColCount )
+ mCellValueSetter.processValue( aMatrix[ y ], xCell );
+ else
+ mCellValueSetter.processValue( uno::makeAny( sNA ), xCell );
+ }
+};
+
+
+
+class Dim2ArrayValueSetter : public ArrayVisitor
+{
+ uno::Sequence< uno::Sequence< uno::Any > > aMatrix;
+ ValueSetter& mCellValueSetter;
+ sal_Int32 nRowCount;
+ sal_Int32 nColCount;
+public:
+ Dim2ArrayValueSetter( const uno::Any& aValue, ValueSetter& rCellValueSetter ) : mCellValueSetter( rCellValueSetter )
+ {
+ aValue >>= aMatrix;
+ nRowCount = aMatrix.getLength();
+ nColCount = aMatrix[0].getLength();
+ }
+
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
+ {
+ if ( x < nRowCount && y < nColCount )
+ mCellValueSetter.processValue( aMatrix[ x ][ y ], xCell );
+ else
+ mCellValueSetter.processValue( uno::makeAny( sNA ), xCell );
+
+ }
+};
+
+class RangeProcessor
+{
+public:
+ virtual void process( const uno::Reference< excel::XRange >& xRange ) = 0;
+};
+
+class RangeValueProcessor : public RangeProcessor
+{
+ const uno::Any& m_aVal;
+public:
+ RangeValueProcessor( const uno::Any& rVal ):m_aVal( rVal ) {}
+ virtual void process( const uno::Reference< excel::XRange >& xRange )
+ {
+ xRange->setValue( m_aVal );
+ }
+};
+
+class RangeFormulaProcessor : public RangeProcessor
+{
+ const uno::Any& m_aVal;
+public:
+ RangeFormulaProcessor( const uno::Any& rVal ):m_aVal( rVal ) {}
+ virtual void process( const uno::Reference< excel::XRange >& xRange )
+ {
+ xRange->setFormula( m_aVal );
+ }
+};
+
+class RangeCountProcessor : public RangeProcessor
+{
+ sal_Int32 nCount;
+public:
+ RangeCountProcessor():nCount(0){}
+ virtual void process( const uno::Reference< excel::XRange >& xRange )
+ {
+ nCount = nCount + xRange->getCount();
+ }
+ sal_Int32 value() { return nCount; }
+};
+class AreasVisitor
+{
+private:
+ uno::Reference< XCollection > m_Areas;
+public:
+ AreasVisitor( const uno::Reference< XCollection >& rAreas ):m_Areas( rAreas ){}
+
+ void visit( RangeProcessor& processor )
+ {
+ if ( m_Areas.is() )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ processor.process( xRange );
+ }
+ }
+ }
+};
+
+class RangeHelper
+{
+ uno::Reference< table::XCellRange > m_xCellRange;
+
+public:
+ RangeHelper( const uno::Reference< table::XCellRange >& xCellRange ) throw (uno::RuntimeException) : m_xCellRange( xCellRange )
+ {
+ if ( !m_xCellRange.is() )
+ throw uno::RuntimeException();
+ }
+ RangeHelper( const uno::Any aCellRange ) throw (uno::RuntimeException)
+ {
+ m_xCellRange.set( aCellRange, uno::UNO_QUERY_THROW );
+ }
+ uno::Reference< sheet::XSheetCellRange > getSheetCellRange() throw (uno::RuntimeException)
+ {
+ return uno::Reference< sheet::XSheetCellRange >(m_xCellRange, uno::UNO_QUERY_THROW);
+ }
+ uno::Reference< sheet::XSpreadsheet > getSpreadSheet() throw (uno::RuntimeException)
+ {
+ return getSheetCellRange()->getSpreadsheet();
+ }
+
+ uno::Reference< table::XCellRange > getCellRangeFromSheet() throw (uno::RuntimeException)
+ {
+ return uno::Reference< table::XCellRange >(getSpreadSheet(), uno::UNO_QUERY_THROW );
+ }
+
+ uno::Reference< sheet::XCellRangeAddressable > getCellRangeAddressable() throw (uno::RuntimeException)
+ {
+ return uno::Reference< sheet::XCellRangeAddressable >(m_xCellRange, ::uno::UNO_QUERY_THROW);
+
+ }
+
+ uno::Reference< sheet::XSheetCellCursor > getSheetCellCursor() throw ( uno::RuntimeException )
+ {
+ return uno::Reference< sheet::XSheetCellCursor >( getSpreadSheet()->createCursorByRange( getSheetCellRange() ), uno::UNO_QUERY_THROW );
+ }
+
+ static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext,
+ const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable,
+ sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0, sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 )
+ {
+ return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext,
+ xRange->getCellRangeByPosition(
+ xCellRangeAddressable->getRangeAddress().StartColumn + nStartColOffset,
+ xCellRangeAddressable->getRangeAddress().StartRow + nStartRowOffset,
+ xCellRangeAddressable->getRangeAddress().EndColumn + nEndColOffset,
+ xCellRangeAddressable->getRangeAddress().EndRow + nEndRowOffset ) ) );
+ }
+
+};
+
+bool
+getCellRangesForAddress( USHORT& rResFlags, const rtl::OUString& sAddress, ScDocShell* pDocSh, ScRangeList& rCellRanges, formula::FormulaGrammar::AddressConvention& eConv )
+{
+
+ ScDocument* pDoc = NULL;
+ if ( pDocSh )
+ {
+ pDoc = pDocSh->GetDocument();
+ String aString(sAddress);
+ USHORT nMask = SCA_VALID;
+ //USHORT nParse = rCellRanges.Parse( sAddress, pDoc, nMask, formula::FormulaGrammar::CONV_XL_A1 );
+ rResFlags = rCellRanges.Parse( sAddress, pDoc, nMask, eConv, 0 );
+ if ( rResFlags & SCA_VALID )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, ScRange& refRange, ScRangeList& aCellRanges, formula::FormulaGrammar::AddressConvention aConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException )
+{
+ // see if there is a match with a named range
+ uno::Reference< beans::XPropertySet > xProps( pDocSh->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW );
+ // Strangly enough you can have Range( "namedRange1, namedRange2, etc," )
+ // loop around each ',' seperated name
+ std::vector< rtl::OUString > vNames;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ rtl::OUString aToken = sName.getToken( 0, ',', nIndex );
+ vNames.push_back( aToken );
+ } while ( nIndex >= 0 );
+
+ if ( !vNames.size() )
+ vNames.push_back( sName );
+
+ std::vector< rtl::OUString >::iterator it = vNames.begin();
+ std::vector< rtl::OUString >::iterator it_end = vNames.end();
+ for ( ; it != it_end; ++it )
+ {
+
+ formula::FormulaGrammar::AddressConvention eConv = aConv;
+ // spaces are illegal ( but the user of course can enter them )
+ rtl::OUString sAddress = (*it).trim();
+ if ( xNameAccess->hasByName( sAddress ) )
+ {
+ uno::Reference< sheet::XNamedRange > xNamed( xNameAccess->getByName( sAddress ), uno::UNO_QUERY_THROW );
+ sAddress = xNamed->getContent();
+ // As the address comes from OOO, the addressing
+ // style is may not be XL_A1
+ eConv = pDocSh->GetDocument()->GetAddressConvention();
+ }
+
+ USHORT nFlags = 0;
+ if ( !getCellRangesForAddress( nFlags, sAddress, pDocSh, aCellRanges, eConv ) )
+ return false;
+
+ bool bTabFromReferrer = !( nFlags & SCA_TAB_3D );
+
+ for ( ScRange* pRange = aCellRanges.First() ; pRange; pRange = aCellRanges.Next() )
+ {
+ pRange->aStart.SetCol( refRange.aStart.Col() + pRange->aStart.Col() );
+ pRange->aStart.SetRow( refRange.aStart.Row() + pRange->aStart.Row() );
+ pRange->aStart.SetTab( bTabFromReferrer ? refRange.aStart.Tab() : pRange->aStart.Tab() );
+ pRange->aEnd.SetCol( refRange.aStart.Col() + pRange->aEnd.Col() );
+ pRange->aEnd.SetRow( refRange.aStart.Row() + pRange->aEnd.Row() );
+ pRange->aEnd.SetTab( bTabFromReferrer ? refRange.aEnd.Tab() : pRange->aEnd.Tab() );
+ }
+ }
+ return true;
+}
+
+
+ScVbaRange*
+getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException )
+{
+ ScRangeList aCellRanges;
+ ScRange refRange;
+ ScUnoConversion::FillScRange( refRange, pAddr );
+ if ( !getScRangeListForAddress ( sName, pDocSh, refRange, aCellRanges, eConv ) )
+ throw uno::RuntimeException();
+ // Single range
+ if ( aCellRanges.First() == aCellRanges.Last() )
+ {
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) );
+ uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRange );
+ return new ScVbaRange( xFixThisParent, xContext, xRange );
+ }
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
+
+ uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRanges );
+ return new ScVbaRange( xFixThisParent, xContext, xRanges );
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+template< typename RangeType >
+inline table::CellRangeAddress lclGetRangeAddress( const uno::Reference< RangeType >& rxCellRange ) throw (uno::RuntimeException)
+{
+ return uno::Reference< sheet::XCellRangeAddressable >( rxCellRange, uno::UNO_QUERY_THROW )->getRangeAddress();
+}
+
+void lclClearRange( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException)
+{
+ using namespace ::com::sun::star::sheet::CellFlags;
+ sal_Int32 nFlags = VALUE | DATETIME | STRING | ANNOTATION | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED;
+ uno::Reference< sheet::XSheetOperation > xSheetOperation( rxCellRange, uno::UNO_QUERY_THROW );
+ xSheetOperation->clearContents( nFlags );
+}
+
+uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference< table::XCellRange >& rxCellRange, bool bRecursive ) throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCellRange > xNewCellRange( rxCellRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xNewCellRange->getSpreadsheet(), uno::UNO_SET_THROW );
+ table::CellRangeAddress aNewAddress = lclGetRangeAddress( xNewCellRange );
+ table::CellRangeAddress aOldAddress;
+ // expand as long as there are new merged ranges included
+ do
+ {
+ aOldAddress = aNewAddress;
+ uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW );
+ xCursor->collapseToMergedArea();
+ xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW );
+ aNewAddress = lclGetRangeAddress( xNewCellRange );
+ }
+ while( bRecursive && (aOldAddress != aNewAddress) );
+ return xNewCellRange;
+}
+
+uno::Reference< sheet::XSheetCellRangeContainer > lclExpandToMerged( const uno::Reference< sheet::XSheetCellRangeContainer >& rxCellRanges, bool bRecursive ) throw (uno::RuntimeException)
+{
+ if( !rxCellRanges.is() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() );
+ sal_Int32 nCount = rxCellRanges->getCount();
+ if( nCount < 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() );
+
+ ScRangeList aScRanges;
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRange( rxCellRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( lclExpandToMerged( xRange, bRecursive ) );
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, aRangeAddr );
+ aScRanges.Append( aScRange );
+ }
+ return new ScCellRangesObj( getDocShellFromRanges( rxCellRanges ), aScRanges );
+}
+
+void lclExpandAndMerge( const uno::Reference< table::XCellRange >& rxCellRange, bool bMerge ) throw (uno::RuntimeException)
+{
+ uno::Reference< util::XMergeable > xMerge( lclExpandToMerged( rxCellRange, true ), uno::UNO_QUERY_THROW );
+ // Calc cannot merge over merged ranges, always unmerge first
+ xMerge->merge( sal_False );
+ if( bMerge )
+ {
+ // clear all contents of the covered cells (not the top-left cell)
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange );
+ sal_Int32 nLastColIdx = aRangeAddr.EndColumn - aRangeAddr.StartColumn;
+ sal_Int32 nLastRowIdx = aRangeAddr.EndRow - aRangeAddr.StartRow;
+ // clear cells of top row, right of top-left cell
+ if( nLastColIdx > 0 )
+ lclClearRange( rxCellRange->getCellRangeByPosition( 1, 0, nLastColIdx, 0 ) );
+ // clear all rows below top row
+ if( nLastRowIdx > 0 )
+ lclClearRange( rxCellRange->getCellRangeByPosition( 0, 1, nLastColIdx, nLastRowIdx ) );
+ // merge the range
+ xMerge->merge( sal_True );
+ }
+}
+
+util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException)
+{
+ /* 1) Check if range is completely inside one single merged range. To do
+ this, try to extend from top-left cell only (not from entire range).
+ This will exclude cases where this range consists of several merged
+ ranges (or parts of them). */
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange );
+ uno::Reference< table::XCellRange > xTopLeft( rxCellRange->getCellRangeByPosition( 0, 0, 0, 0 ), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSheetCellRange > xExpanded( lclExpandToMerged( xTopLeft, false ), uno::UNO_SET_THROW );
+ table::CellRangeAddress aExpAddr = lclGetRangeAddress( xExpanded );
+ // check that expanded range has more than one cell (really merged)
+ if( ((aExpAddr.StartColumn < aExpAddr.EndColumn) || (aExpAddr.StartRow < aExpAddr.EndRow)) && ScUnoConversion::Contains( aExpAddr, aRangeAddr ) )
+ return util::TriState_YES;
+
+ /* 2) Check if this range contains any merged cells (completely or
+ partly). This seems to be hardly possible via API, as
+ XMergeable::getIsMerged() returns only true, if the top-left cell of a
+ merged range is part of this range, so cases where just the lower part
+ of a merged range is part of this range are not covered. */
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, aRangeAddr );
+ bool bHasMerged = getDocumentFromRange( rxCellRange )->HasAttrib( aScRange, HASATTR_MERGED | HASATTR_OVERLAPPED );
+ return bHasMerged ? util::TriState_INDETERMINATE : util::TriState_NO;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+css::uno::Reference< excel::XRange >
+ScVbaRange::getRangeObjectForName(
+ const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName,
+ ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException )
+{
+ table::CellRangeAddress refAddr;
+ return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv );
+}
+
+
+table::CellRangeAddress getCellRangeAddressForVBARange( const uno::Any& aParam, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention aConv = formula::FormulaGrammar::CONV_XL_A1) throw ( uno::RuntimeException )
+{
+ uno::Reference< table::XCellRange > xRangeParam;
+ switch ( aParam.getValueTypeClass() )
+ {
+ case uno::TypeClass_STRING:
+ {
+ rtl::OUString rString;
+ aParam >>= rString;
+ ScRangeList aCellRanges;
+ ScRange refRange;
+ if ( getScRangeListForAddress ( rString, pDocSh, refRange, aCellRanges, aConv ) )
+ {
+ if ( aCellRanges.First() == aCellRanges.Last() )
+ {
+ table::CellRangeAddress aRangeAddress;
+ ScUnoConversion::FillApiRange( aRangeAddress, *aCellRanges.First() );
+ return aRangeAddress;
+ }
+ }
+ }
+ case uno::TypeClass_INTERFACE:
+ {
+ uno::Reference< excel::XRange > xRange;
+ aParam >>= xRange;
+ if ( xRange.is() )
+ xRange->getCellRange() >>= xRangeParam;
+ break;
+ }
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't extact CellRangeAddress from type" ) ), uno::Reference< uno::XInterface >() );
+ }
+ return lclGetRangeAddress( xRangeParam );
+}
+
+uno::Reference< XCollection >
+lcl_setupBorders( const uno::Reference< excel::XRange >& xParentRange, const uno::Reference<uno::XComponentContext>& xContext, const uno::Reference< table::XCellRange >& xRange ) throw( uno::RuntimeException )
+{
+ uno::Reference< XHelperInterface > xParent( xParentRange, uno::UNO_QUERY_THROW );
+ ScDocument* pDoc = getDocumentFromRange(xRange);
+ if ( !pDoc )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
+ ScVbaPalette aPalette( pDoc->GetDocumentShell() );
+ uno::Reference< XCollection > borders( new ScVbaBorders( xParent, xContext, xRange, aPalette ) );
+ return borders;
+}
+
+ScVbaRange::ScVbaRange( uno::Sequence< uno::Any> const & args,
+ uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : ScVbaRange_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext, getXSomethingFromArgs< beans::XPropertySet >( args, 1, false ), getModelFromXIf( getXSomethingFromArgs< uno::XInterface >( args, 1 ) ), true ), mbIsRows( sal_False ), mbIsColumns( sal_False )
+{
+ mxRange.set( mxPropertySet, uno::UNO_QUERY );
+ mxRanges.set( mxPropertySet, uno::UNO_QUERY );
+ uno::Reference< container::XIndexAccess > xIndex;
+ if ( mxRange.is() )
+ {
+ xIndex = new SingleRangeIndexAccess( mxParent, mxContext, mxRange );
+ }
+ else if ( mxRanges.is() )
+ {
+ xIndex.set( mxRanges, uno::UNO_QUERY_THROW );
+ }
+ m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
+}
+
+ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, sal_Bool bIsRows, sal_Bool bIsColumns ) throw( lang::IllegalArgumentException )
+: ScVbaRange_BASE( xParent, xContext, uno::Reference< beans::XPropertySet >( xRange, uno::UNO_QUERY_THROW ), getModelFromRange( xRange), true ), mxRange( xRange ),
+ mbIsRows( bIsRows ),
+ mbIsColumns( bIsColumns )
+{
+ if ( !xContext.is() )
+ throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "context is not set " ) ), uno::Reference< uno::XInterface >() , 1 );
+ if ( !xRange.is() )
+ throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 );
+
+ uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxParent, mxContext, xRange ) );
+ m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
+
+}
+
+ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges, sal_Bool bIsRows, sal_Bool bIsColumns ) throw ( lang::IllegalArgumentException )
+: ScVbaRange_BASE( xParent, xContext, uno::Reference< beans::XPropertySet >( xRanges, uno::UNO_QUERY_THROW ), getModelFromXIf( uno::Reference< uno::XInterface >( xRanges, uno::UNO_QUERY_THROW ) ), true ), mxRanges( xRanges ),mbIsRows( bIsRows ), mbIsColumns( bIsColumns )
+
+{
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ m_Areas = new ScVbaRangeAreas( xParent, mxContext, xIndex, mbIsRows, mbIsColumns );
+
+}
+
+ScVbaRange::~ScVbaRange()
+{
+}
+
+uno::Reference< XCollection >& ScVbaRange::getBorders()
+{
+ if ( !m_Borders.is() )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ m_Borders = lcl_setupBorders( this, mxContext, uno::Reference< table::XCellRange >( xRange->getCellRange(), uno::UNO_QUERY_THROW ) );
+ }
+ return m_Borders;
+}
+
+void
+ScVbaRange::visitArray( ArrayVisitor& visitor )
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount();
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+ for ( sal_Int32 i=0; i<nRowCount; ++i )
+ {
+ for ( sal_Int32 j=0; j<nColCount; ++j )
+ {
+ uno::Reference< table::XCell > xCell( mxRange->getCellByPosition( j, i ), uno::UNO_QUERY_THROW );
+
+ visitor.visitNode( i, j, xCell );
+ }
+ }
+}
+
+
+
+uno::Any
+ScVbaRange::getValue( ValueGetter& valueGetter) throw (uno::RuntimeException)
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
+ // single cell range
+ if ( isSingleCellRange() )
+ {
+ visitArray( valueGetter );
+ return valueGetter.getValue();
+ }
+ sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount();
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+ // multi cell range ( return array )
+ Dim2ArrayValueGetter arrayGetter( nRowCount, nColCount, valueGetter );
+ visitArray( arrayGetter );
+ return uno::makeAny( script::ArrayWrapper( sal_False, arrayGetter.getValue() ) );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getValue() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->getValue();
+ }
+
+ CellValueGetter valueGetter;
+ return getValue( valueGetter );
+
+}
+
+
+void
+ScVbaRange::setValue( const uno::Any &aValue, ValueSetter& valueSetter ) throw (uno::RuntimeException)
+{
+ uno::TypeClass aClass = aValue.getValueTypeClass();
+ if ( aClass == uno::TypeClass_SEQUENCE )
+ {
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
+ uno::Any aConverted;
+ try
+ {
+ // test for single dimension, could do
+ // with a better test than this
+ if ( aValue.getValueTypeName().indexOf('[') == aValue.getValueTypeName().lastIndexOf('[') )
+ {
+ aConverted = xConverter->convertTo( aValue, getCppuType((uno::Sequence< uno::Any >*)0) );
+ Dim1ArrayValueSetter setter( aConverted, valueSetter );
+ visitArray( setter );
+ }
+ else
+ {
+ aConverted = xConverter->convertTo( aValue, getCppuType((uno::Sequence< uno::Sequence< uno::Any > >*)0) );
+ Dim2ArrayValueSetter setter( aConverted, valueSetter );
+ visitArray( setter );
+ }
+ }
+ catch ( uno::Exception& e )
+ {
+ OSL_TRACE("Bahhh, caught exception %s",
+ rtl::OUStringToOString( e.Message,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ else
+ {
+ visitArray( valueSetter );
+ }
+}
+
+void SAL_CALL
+ScVbaRange::setValue( const uno::Any &aValue ) throw (uno::RuntimeException)
+{
+ // If this is a multiple selection apply setValue over all areas
+ if ( m_Areas->getCount() > 1 )
+ {
+ AreasVisitor aVisitor( m_Areas );
+ RangeValueProcessor valueProcessor( aValue );
+ aVisitor.visit( valueProcessor );
+ return;
+ }
+ CellValueSetter valueSetter( aValue );
+ setValue( aValue, valueSetter );
+}
+
+void
+ScVbaRange::Clear() throw (uno::RuntimeException)
+{
+ using namespace ::com::sun::star::sheet::CellFlags;
+ sal_Int32 nFlags = VALUE | DATETIME | STRING | FORMULA | HARDATTR | EDITATTR | FORMATTED;
+ ClearContents( nFlags );
+}
+
+//helper ClearContent
+void
+ScVbaRange::ClearContents( sal_Int32 nFlags ) throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaRange* pRange = getImplementation( xRange );
+ if ( pRange )
+ pRange->ClearContents( nFlags );
+ }
+ return;
+ }
+
+
+ uno::Reference< sheet::XSheetOperation > xSheetOperation(mxRange, uno::UNO_QUERY_THROW);
+ xSheetOperation->clearContents( nFlags );
+}
+void
+ScVbaRange::ClearComments() throw (uno::RuntimeException)
+{
+ ClearContents( sheet::CellFlags::ANNOTATION );
+}
+
+void
+ScVbaRange::ClearContents() throw (uno::RuntimeException)
+{
+ sal_Int32 nClearFlags = ( sheet::CellFlags::VALUE |
+ sheet::CellFlags::STRING | sheet::CellFlags::DATETIME |
+ sheet::CellFlags::FORMULA );
+ ClearContents( nClearFlags );
+}
+
+void
+ScVbaRange::ClearFormats() throw (uno::RuntimeException)
+{
+ //FIXME: need to check if we need to combine sheet::CellFlags::FORMATTED
+ sal_Int32 nClearFlags = sheet::CellFlags::HARDATTR | sheet::CellFlags::FORMATTED | sheet::CellFlags::EDITATTR;
+ ClearContents( nClearFlags );
+}
+
+void
+ScVbaRange::setFormulaValue( const uno::Any& rFormula, formula::FormulaGrammar::Grammar eGram ) throw (uno::RuntimeException)
+{
+ // If this is a multiple selection apply setFormula over all areas
+ if ( m_Areas->getCount() > 1 )
+ {
+ AreasVisitor aVisitor( m_Areas );
+ RangeFormulaProcessor valueProcessor( rFormula );
+ aVisitor.visit( valueProcessor );
+ return;
+ }
+ CellFormulaValueSetter formulaValueSetter( rFormula, getScDocument(), eGram );
+ setValue( rFormula, formulaValueSetter );
+}
+
+uno::Any
+ScVbaRange::getFormulaValue( formula::FormulaGrammar::Grammar eGram ) throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->getFormula();
+ }
+ CellFormulaValueGetter valueGetter( getScDocument(), eGram );
+ return getValue( valueGetter );
+
+}
+
+void
+ScVbaRange::setFormula(const uno::Any &rFormula ) throw (uno::RuntimeException)
+{
+ // #FIXME converting "=$a$1" e.g. CONV_XL_A1 -> CONV_OOO // results in "=$a$1:a1", temporalily disable conversion
+ setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );;
+}
+
+uno::Any
+ScVbaRange::getFormulaR1C1() throw (::com::sun::star::uno::RuntimeException)
+{
+ return getFormulaValue( formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
+}
+
+void
+ScVbaRange::setFormulaR1C1(const uno::Any& rFormula ) throw (uno::RuntimeException)
+{
+ setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
+}
+
+uno::Any
+ScVbaRange::getFormula() throw (::com::sun::star::uno::RuntimeException)
+{
+ return getFormulaValue( formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
+}
+
+sal_Int32
+ScVbaRange::getCount() throw (uno::RuntimeException)
+{
+ // If this is a multiple selection apply setValue over all areas
+ if ( m_Areas->getCount() > 1 )
+ {
+ AreasVisitor aVisitor( m_Areas );
+ RangeCountProcessor valueProcessor;
+ aVisitor.visit( valueProcessor );
+ return valueProcessor.value();
+ }
+ sal_Int32 rowCount = 0;
+ sal_Int32 colCount = 0;
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
+ rowCount = xColumnRowRange->getRows()->getCount();
+ colCount = xColumnRowRange->getColumns()->getCount();
+
+ if( IsRows() )
+ return rowCount;
+ if( IsColumns() )
+ return colCount;
+ return rowCount * colCount;
+}
+
+sal_Int32
+ScVbaRange::getRow() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->getRow();
+ }
+ uno::Reference< sheet::XCellAddressable > xCellAddressable(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ return xCellAddressable->getCellAddress().Row + 1; // Zero value indexing
+}
+
+sal_Int32
+ScVbaRange::getColumn() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->getColumn();
+ }
+ uno::Reference< sheet::XCellAddressable > xCellAddressable(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ return xCellAddressable->getCellAddress().Column + 1; // Zero value indexing
+}
+
+uno::Any
+ScVbaRange::HasFormula() throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult = aNULL();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ // if the HasFormula for any area is different to another
+ // return null
+ if ( index > 1 )
+ if ( aResult != xRange->HasFormula() )
+ return aNULL();
+ aResult = xRange->HasFormula();
+ if ( aNULL() == aResult )
+ return aNULL();
+ }
+ return aResult;
+ }
+ uno::Reference< uno::XInterface > xIf( mxRange, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pThisRanges = dynamic_cast< ScCellRangesBase * > ( xIf.get() );
+ if ( pThisRanges )
+ {
+ uno::Reference<uno::XInterface> xRanges( pThisRanges->queryFormulaCells( ( sheet::FormulaResult::ERROR | sheet::FormulaResult::VALUE | sheet::FormulaResult::STRING ) ), uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pFormulaRanges = dynamic_cast< ScCellRangesBase * > ( xRanges.get() );
+ // check if there are no formula cell, return false
+ if ( pFormulaRanges->GetRangeList().Count() == 0 )
+ return uno::makeAny(sal_False);
+
+ // chech if there are holes (where some cells are not formulas)
+ // or returned range is not equal to this range
+ if ( ( pFormulaRanges->GetRangeList().Count() > 1 )
+ || ( pFormulaRanges->GetRangeList().GetObject(0)->aStart != pThisRanges->GetRangeList().GetObject(0)->aStart )
+ || ( pFormulaRanges->GetRangeList().GetObject(0)->aEnd != pThisRanges->GetRangeList().GetObject(0)->aEnd ) )
+ return aNULL(); // should return aNULL;
+ }
+ return uno::makeAny( sal_True );
+}
+void
+ScVbaRange::fillSeries( sheet::FillDirection nFillDirection, sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode, double fStep, double fEndValue ) throw( uno::RuntimeException )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ // Multi-Area Range
+ uno::Reference< XCollection > xCollection( m_Areas, uno::UNO_QUERY_THROW );
+ for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index )
+ {
+ uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaRange* pThisRange = getImplementation( xRange );
+ pThisRange->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue );
+
+ }
+ return;
+ }
+
+ uno::Reference< sheet::XCellSeries > xCellSeries(mxRange, uno::UNO_QUERY_THROW );
+ xCellSeries->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue );
+}
+
+void
+ScVbaRange::FillLeft() throw (uno::RuntimeException)
+{
+ fillSeries(sheet::FillDirection_TO_LEFT,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+void
+ScVbaRange::FillRight() throw (uno::RuntimeException)
+{
+ fillSeries(sheet::FillDirection_TO_RIGHT,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+void
+ScVbaRange::FillUp() throw (uno::RuntimeException)
+{
+ fillSeries(sheet::FillDirection_TO_TOP,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+void
+ScVbaRange::FillDown() throw (uno::RuntimeException)
+{
+ fillSeries(sheet::FillDirection_TO_BOTTOM,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+::rtl::OUString
+ScVbaRange::getText() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->getText();
+ }
+ uno::Reference< text::XTextRange > xTextRange(mxRange->getCellByPosition(0,0), uno::UNO_QUERY_THROW );
+ return xTextRange->getString();
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Offset( const ::uno::Any &nRowOff, const uno::Any &nColOff ) throw (uno::RuntimeException)
+{
+ SCROW nRowOffset = 0;
+ SCCOL nColOffset = 0;
+ sal_Bool bIsRowOffset = ( nRowOff >>= nRowOffset );
+ sal_Bool bIsColumnOffset = ( nColOff >>= nColOffset );
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+
+
+ for ( ScRange* pRange = aCellRanges.First() ; pRange; pRange = aCellRanges.Next() )
+ {
+ if ( bIsColumnOffset )
+ {
+ pRange->aStart.SetCol( pRange->aStart.Col() + nColOffset );
+ pRange->aEnd.SetCol( pRange->aEnd.Col() + nColOffset );
+ }
+ if ( bIsRowOffset )
+ {
+ pRange->aStart.SetRow( pRange->aStart.Row() + nRowOffset );
+ pRange->aEnd.SetRow( pRange->aEnd.Row() + nRowOffset );
+ }
+ }
+
+ if ( aCellRanges.Count() > 1 ) // Multi-Area
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
+ return new ScVbaRange( mxParent, mxContext, xRanges );
+ }
+ // normal range
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) );
+ return new ScVbaRange( mxParent, mxContext, xRange );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::CurrentRegion() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->CurrentRegion();
+ }
+
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor =
+ helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::CurrentArray() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->CurrentArray();
+ }
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor =
+ helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentArray();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );
+}
+
+uno::Any
+ScVbaRange::getFormulaArray() throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->getFormulaArray();
+ }
+
+ uno::Reference< sheet::XCellRangeFormula> xCellRangeFormula( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
+ uno::Any aMatrix;
+ aMatrix = xConverter->convertTo( uno::makeAny( xCellRangeFormula->getFormulaArray() ) , getCppuType((uno::Sequence< uno::Sequence< uno::Any > >*)0) ) ;
+ return aMatrix;
+}
+
+void
+ScVbaRange::setFormulaArray(const uno::Any& rFormula) throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->setFormulaArray( rFormula );
+ }
+ // #TODO need to distinguish between getFormula and getFormulaArray e.g. (R1C1)
+ // but for the moment its just easier to treat them the same for setting
+
+ setFormula( rFormula );
+}
+
+::rtl::OUString
+ScVbaRange::Characters(const uno::Any& Start, const uno::Any& Length) throw (uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->Characters( Start, Length );
+ }
+
+ long nIndex = 0, nCount = 0;
+ ::rtl::OUString rString;
+ uno::Reference< text::XTextRange > xTextRange(mxRange, ::uno::UNO_QUERY_THROW );
+ rString = xTextRange->getString();
+ if( !( Start >>= nIndex ) && !( Length >>= nCount ) )
+ return rString;
+ if(!( Start >>= nIndex ) )
+ nIndex = 1;
+ if(!( Length >>= nCount ) )
+ nIndex = rString.getLength();
+ return rString.copy( --nIndex, nCount ); // Zero value indexing
+}
+
+::rtl::OUString
+ScVbaRange::Address( const uno::Any& RowAbsolute, const uno::Any& ColumnAbsolute, const uno::Any& ReferenceStyle, const uno::Any& External, const uno::Any& RelativeTo ) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ // Multi-Area Range
+ rtl::OUString sAddress;
+ uno::Reference< XCollection > xCollection( m_Areas, uno::UNO_QUERY_THROW );
+ uno::Any aExternalCopy = External;
+ for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index )
+ {
+ uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ if ( index > 1 )
+ {
+ sAddress += rtl::OUString( ',' );
+ // force external to be false
+ // only first address should have the
+ // document and sheet specifications
+ aExternalCopy = uno::makeAny(sal_False);
+ }
+ sAddress += xRange->Address( RowAbsolute, ColumnAbsolute, ReferenceStyle, aExternalCopy, RelativeTo );
+ }
+ return sAddress;
+
+ }
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ if ( ReferenceStyle.hasValue() )
+ {
+ sal_Int32 refStyle = excel::XlReferenceStyle::xlA1;
+ ReferenceStyle >>= refStyle;
+ if ( refStyle == excel::XlReferenceStyle::xlR1C1 )
+ dDetails = ScAddress::Details( formula::FormulaGrammar::CONV_XL_R1C1, 0, 0 );
+ }
+ USHORT nFlags = SCA_VALID;
+ ScDocShell* pDocShell = getScDocShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
+ String sRange;
+ USHORT ROW_ABSOLUTE = ( SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE );
+ USHORT COL_ABSOLUTE = ( SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE );
+ // default
+ nFlags |= ( SCA_TAB_ABSOLUTE | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB2_ABSOLUTE | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE );
+ if ( RowAbsolute.hasValue() )
+ {
+ sal_Bool bVal = sal_True;
+ RowAbsolute >>= bVal;
+ if ( !bVal )
+ nFlags &= ~ROW_ABSOLUTE;
+ }
+ if ( ColumnAbsolute.hasValue() )
+ {
+ sal_Bool bVal = sal_True;
+ ColumnAbsolute >>= bVal;
+ if ( !bVal )
+ nFlags &= ~COL_ABSOLUTE;
+ }
+ sal_Bool bLocal = sal_False;
+ if ( External.hasValue() )
+ {
+ External >>= bLocal;
+ if ( bLocal )
+ nFlags |= SCA_TAB_3D | SCA_FORCE_DOC;
+ }
+ if ( RelativeTo.hasValue() )
+ {
+ // #TODO should I throw an error if R1C1 is not set?
+
+ table::CellRangeAddress refAddress = getCellRangeAddressForVBARange( RelativeTo, pDocShell );
+ dDetails = ScAddress::Details( formula::FormulaGrammar::CONV_XL_R1C1, static_cast< SCROW >( refAddress.StartRow ), static_cast< SCCOL >( refAddress.StartColumn ) );
+ }
+ aRange.Format( sRange, nFlags, pDoc, dDetails );
+ return sRange;
+}
+
+uno::Reference < excel::XFont >
+ScVbaRange::Font() throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY );
+ ScDocument* pDoc = getScDocument();
+ if ( mxRange.is() )
+ xProps.set(mxRange, ::uno::UNO_QUERY );
+ else if ( mxRanges.is() )
+ xProps.set(mxRanges, ::uno::UNO_QUERY );
+ if ( !pDoc )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
+
+ ScVbaPalette aPalette( pDoc->GetDocumentShell() );
+ ScCellRangeObj* pRangeObj = NULL;
+ try
+ {
+ pRangeObj = getCellRangeObj();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return new ScVbaFont( this, mxContext, aPalette, xProps, pRangeObj );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) throw(uno::RuntimeException)
+{
+ // #TODO code within the test below "if ( m_Areas.... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->Cells( nRowIndex, nColumnIndex );
+ }
+
+ sal_Int32 nRow = 0, nColumn = 0;
+
+ sal_Bool bIsIndex = nRowIndex.hasValue();
+ sal_Bool bIsColumnIndex = nColumnIndex.hasValue();
+
+ // Sometimes we might get a float or a double or whatever
+ // set in the Any, we should convert as appropriate
+ // #FIXME - perhaps worth turning this into some sort of
+ // convertion routine e.g. bSuccess = getValueFromAny( nRow, nRowIndex, getCppuType((sal_Int32*)0) )
+ if ( nRowIndex.hasValue() && !( nRowIndex >>= nRow ) )
+ {
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
+ uno::Any aConverted;
+ try
+ {
+ aConverted = xConverter->convertTo( nRowIndex, getCppuType((sal_Int32*)0) );
+ bIsIndex = ( aConverted >>= nRow );
+ }
+ catch( uno::Exception& ) {} // silence any errors
+ }
+ if ( bIsColumnIndex && !( nColumnIndex >>= nColumn ) )
+ {
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
+ uno::Any aConverted;
+ try
+ {
+ aConverted = xConverter->convertTo( nColumnIndex, getCppuType((sal_Int32*)0) );
+ bIsColumnIndex = ( aConverted >>= nColumn );
+ }
+ catch( uno::Exception& ) {} // silence any errors
+ }
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet();
+ if( !bIsIndex && !bIsColumnIndex ) // .Cells
+ // #FIXE needs proper parent ( Worksheet )
+ return uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, mxRange ) );
+
+ sal_Int32 nIndex = --nRow;
+ if( bIsIndex && !bIsColumnIndex ) // .Cells(n)
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, ::uno::UNO_QUERY_THROW);
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+
+ if ( !nIndex || nIndex < 0 )
+ nRow = 0;
+ else
+ nRow = nIndex / nColCount;
+ nColumn = nIndex % nColCount;
+ }
+ else
+ --nColumn;
+ nRow = nRow + thisRangeAddress.StartRow;
+ nColumn = nColumn + thisRangeAddress.StartColumn;
+ return new ScVbaRange( mxParent, mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) );
+}
+
+void
+ScVbaRange::Select() throw (uno::RuntimeException)
+{
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ if ( !pUnoRangesBase )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >() );
+ ScDocShell* pShell = pUnoRangesBase->GetDocShell();
+ if ( pShell )
+ {
+ uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ if ( mxRanges.is() )
+ xSelection->select( uno::Any( lclExpandToMerged( mxRanges, true ) ) );
+ else
+ xSelection->select( uno::Any( lclExpandToMerged( mxRange, true ) ) );
+ // set focus on document e.g.
+ // ThisComponent.CurrentController.Frame.getContainerWindow.SetFocus
+ try
+ {
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_QUERY_THROW );
+ uno::Reference< awt::XWindow > xWin( xFrame->getContainerWindow(), uno::UNO_QUERY_THROW );
+ xWin->setFocus();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+}
+
+bool cellInRange( const table::CellRangeAddress& rAddr, const sal_Int32& nCol, const sal_Int32& nRow )
+{
+ if ( nCol >= rAddr.StartColumn && nCol <= rAddr.EndColumn &&
+ nRow >= rAddr.StartRow && nRow <= rAddr.EndRow )
+ return true;
+ return false;
+}
+
+void setCursor( const SCCOL& nCol, const SCROW& nRow, const uno::Reference< frame::XModel >& xModel, bool bInSel = true )
+{
+ ScTabViewShell* pShell = excel::getBestViewShell( xModel );
+ if ( pShell )
+ {
+ if ( bInSel )
+ pShell->SetCursor( nCol, nRow );
+ else
+ pShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_NONE, FALSE, FALSE, TRUE, FALSE );
+ }
+}
+
+void
+ScVbaRange::Activate() throw (uno::RuntimeException)
+{
+ // get first cell of current range
+ uno::Reference< table::XCellRange > xCellRange;
+ if ( mxRanges.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ xCellRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ }
+ else
+ xCellRange.set( mxRange, uno::UNO_QUERY_THROW );
+
+ RangeHelper thisRange( xCellRange );
+ uno::Reference< sheet::XCellRangeAddressable > xThisRangeAddress = thisRange.getCellRangeAddressable();
+ table::CellRangeAddress thisRangeAddress = xThisRangeAddress->getRangeAddress();
+ uno::Reference< frame::XModel > xModel;
+ ScDocShell* pShell = getScDocShell();
+
+ if ( pShell )
+ xModel = pShell->GetModel();
+
+ if ( !xModel.is() )
+ throw uno::RuntimeException();
+
+ // get current selection
+ uno::Reference< sheet::XCellRangeAddressable > xRange( xModel->getCurrentSelection(), ::uno::UNO_QUERY);
+
+ uno::Reference< sheet::XSheetCellRanges > xRanges( xModel->getCurrentSelection(), ::uno::UNO_QUERY);
+
+ if ( xRanges.is() )
+ {
+ uno::Sequence< table::CellRangeAddress > nAddrs = xRanges->getRangeAddresses();
+ for ( sal_Int32 index = 0; index < nAddrs.getLength(); ++index )
+ {
+ if ( cellInRange( nAddrs[index], thisRangeAddress.StartColumn, thisRangeAddress.StartRow ) )
+ {
+ setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel );
+ return;
+ }
+
+ }
+ }
+
+ if ( xRange.is() && cellInRange( xRange->getRangeAddress(), thisRangeAddress.StartColumn, thisRangeAddress.StartRow ) )
+ setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel );
+ else
+ {
+ // if this range is multi cell select the range other
+ // wise just position the cell at this single range position
+ if ( isSingleCellRange() )
+ // This top-leftmost cell of this Range is not in the current
+ // selection so just select this range
+ setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel, false );
+ else
+ Select();
+ }
+
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Rows(const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ SCROW nStartRow = 0;
+ SCROW nEndRow = 0;
+
+ sal_Int32 nValue = 0;
+ rtl::OUString sAddress;
+
+ if ( aIndex.hasValue() )
+ {
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+
+ ScRange aRange = *aCellRanges.First();
+ if( aIndex >>= nValue )
+ {
+ aRange.aStart.SetRow( aRange.aStart.Row() + --nValue );
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ }
+
+ else if ( aIndex >>= sAddress )
+ {
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ ScRange tmpRange;
+ tmpRange.ParseRows( sAddress, getDocumentFromRange( mxRange ), dDetails );
+ nStartRow = tmpRange.aStart.Row();
+ nEndRow = tmpRange.aEnd.Row();
+
+ aRange.aStart.SetRow( aRange.aStart.Row() + nStartRow );
+ aRange.aEnd.SetRow( aRange.aStart.Row() + ( nEndRow - nStartRow ));
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Illegal param" ) ), uno::Reference< uno::XInterface >() );
+
+ if ( aRange.aStart.Row() < 0 || aRange.aEnd.Row() < 0 )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() );
+ // return a normal range ( even for multi-selection
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
+ return new ScVbaRange( mxParent, mxContext, xRange, true );
+ }
+ // Rows() - no params
+ if ( m_Areas->getCount() > 1 )
+ return new ScVbaRange( mxParent, mxContext, mxRanges, true );
+ return new ScVbaRange( mxParent, mxContext, mxRange, true );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ SCCOL nStartCol = 0;
+ SCCOL nEndCol = 0;
+
+ sal_Int32 nValue = 0;
+ rtl::OUString sAddress;
+
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+
+ ScRange aRange = *aCellRanges.First();
+ if ( aIndex.hasValue() )
+ {
+ if ( aIndex >>= nValue )
+ {
+ aRange.aStart.SetCol( aRange.aStart.Col() + static_cast< SCCOL > ( --nValue ) );
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+ }
+
+ else if ( aIndex >>= sAddress )
+ {
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ ScRange tmpRange;
+ tmpRange.ParseCols( sAddress, getDocumentFromRange( mxRange ), dDetails );
+ nStartCol = tmpRange.aStart.Col();
+ nEndCol = tmpRange.aEnd.Col();
+
+ aRange.aStart.SetCol( aRange.aStart.Col() + nStartCol );
+ aRange.aEnd.SetCol( aRange.aStart.Col() + ( nEndCol - nStartCol ));
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Illegal param" ) ), uno::Reference< uno::XInterface >() );
+
+ if ( aRange.aStart.Col() < 0 || aRange.aEnd.Col() < 0 )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() );
+ }
+ // Columns() - no params
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
+ return new ScVbaRange( mxParent, mxContext, xRange, false, true );
+}
+
+void
+ScVbaRange::setMergeCells( const uno::Any& aIsMerged ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ bool bMerge = extractBoolFromAny( aIsMerged );
+
+ if( mxRanges.is() )
+ {
+ sal_Int32 nCount = mxRanges->getCount();
+
+ // VBA does nothing (no error) if the own ranges overlap somehow
+ ::std::vector< table::CellRangeAddress > aList;
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ table::CellRangeAddress aAddress = xRangeAddr->getRangeAddress();
+ for( ::std::vector< table::CellRangeAddress >::const_iterator aIt = aList.begin(), aEnd = aList.end(); aIt != aEnd; ++aIt )
+ if( ScUnoConversion::Intersects( *aIt, aAddress ) )
+ return;
+ aList.push_back( aAddress );
+ }
+
+ // (un)merge every range after it has been extended to intersecting merged ranges from sheet
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ lclExpandAndMerge( xRange, bMerge );
+ }
+ return;
+ }
+
+ // otherwise, merge single range
+ lclExpandAndMerge( mxRange, bMerge );
+}
+
+uno::Any
+ScVbaRange::getMergeCells() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if( mxRanges.is() )
+ {
+ sal_Int32 nCount = mxRanges->getCount();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ util::TriState eMerged = lclGetMergedState( xRange );
+ /* Excel always returns NULL, if one range of the range list is
+ partly or completely merged. Even if all ranges are completely
+ merged, the return value is still NULL. */
+ if( eMerged != util::TriState_NO )
+ return aNULL();
+ }
+ // no range is merged anyhow, return false
+ return uno::Any( false );
+ }
+
+ // otherwise, check single range
+ switch( lclGetMergedState( mxRange ) )
+ {
+ case util::TriState_YES: return uno::Any( true );
+ case util::TriState_NO: return uno::Any( false );
+ default: return aNULL();
+ }
+}
+
+void
+ScVbaRange::Copy(const ::uno::Any& Destination) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
+ if ( Destination.hasValue() )
+ {
+ uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
+ uno::Any aRange = xRange->getCellRange();
+ uno::Reference< table::XCellRange > xCellRange;
+ aRange >>= xCellRange;
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(xCellRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
+ uno::Reference< table::XCellRange > xDest( xSheet, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeMovement > xMover( xSheet, uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XCellAddressable > xDestination( xDest->getCellByPosition(
+ xRange->getColumn()-1,xRange->getRow()-1), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY);
+ xMover->copyRange( xDestination->getCellAddress(), xSource->getRangeAddress() );
+ }
+ else
+ {
+ uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
+ Select();
+ excel::implnCopy( xModel );
+ }
+}
+
+void
+ScVbaRange::Cut(const ::uno::Any& Destination) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
+ if (Destination.hasValue())
+ {
+ uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( xRange->getCellRange(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(xCellRange, ::uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
+ uno::Reference< table::XCellRange > xDest( xSheet, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeMovement > xMover( xSheet, uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XCellAddressable > xDestination( xDest->getCellByPosition(
+ xRange->getColumn()-1,xRange->getRow()-1), uno::UNO_QUERY);
+ uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY);
+ xMover->moveRange( xDestination->getCellAddress(), xSource->getRangeAddress() );
+ }
+ {
+ uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
+ Select();
+ excel::implnCut( xModel );
+ }
+}
+
+void
+ScVbaRange::setNumberFormat( const uno::Any& aFormat ) throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ rtl::OUString sFormat;
+ aFormat >>= sFormat;
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setNumberFormat( aFormat );
+ }
+ return;
+ }
+ NumFormatHelper numFormat( mxRange );
+ numFormat.setNumberFormat( sFormat );
+}
+
+uno::Any
+ScVbaRange::getNumberFormat() throw ( script::BasicErrorException, uno::RuntimeException)
+{
+
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult = aNULL();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ // if the numberformat of one area is different to another
+ // return null
+ if ( index > 1 )
+ if ( aResult != xRange->getNumberFormat() )
+ return aNULL();
+ aResult = xRange->getNumberFormat();
+ if ( aNULL() == aResult )
+ return aNULL();
+ }
+ return aResult;
+ }
+ NumFormatHelper numFormat( mxRange );
+ rtl::OUString sFormat = numFormat.getNumberFormatString();
+ if ( sFormat.getLength() > 0 )
+ return uno::makeAny( sFormat );
+ return aNULL();
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Resize( const uno::Any &RowSize, const uno::Any &ColumnSize ) throw (uno::RuntimeException)
+{
+ long nRowSize = 0, nColumnSize = 0;
+ sal_Bool bIsRowChanged = ( RowSize >>= nRowSize ), bIsColumnChanged = ( ColumnSize >>= nColumnSize );
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellRange > xSheetRange(mxRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xCursor( xSheetRange->getSpreadsheet()->createCursorByRange(xSheetRange), ::uno::UNO_QUERY_THROW );
+
+ if( !bIsRowChanged )
+ nRowSize = xColumnRowRange->getRows()->getCount();
+ if( !bIsColumnChanged )
+ nColumnSize = xColumnRowRange->getColumns()->getCount();
+
+ xCursor->collapseToSize( nColumnSize, nRowSize );
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xCursor, ::uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xSheetRange->getSpreadsheet(), ::uno::UNO_QUERY_THROW );
+ return new ScVbaRange( mxParent, mxContext,xRange->getCellRangeByPosition(
+ xCellRangeAddressable->getRangeAddress().StartColumn,
+ xCellRangeAddressable->getRangeAddress().StartRow,
+ xCellRangeAddressable->getRangeAddress().EndColumn,
+ xCellRangeAddressable->getRangeAddress().EndRow ) );
+}
+
+void
+ScVbaRange::setWrapText( const uno::Any& aIsWrapped ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult;
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setWrapText( aIsWrapped );
+ }
+ return;
+ }
+
+ uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW );
+ bool bIsWrapped = extractBoolFromAny( aIsWrapped );
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsTextWrapped" ) ), uno::Any( bIsWrapped ) );
+}
+
+uno::Any
+ScVbaRange::getWrapText() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult;
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ if ( index > 1 )
+ if ( aResult != xRange->getWrapText() )
+ return aNULL();
+ aResult = xRange->getWrapText();
+ }
+ return aResult;
+ }
+
+ SfxItemSet* pDataSet = getCurrentDataSet();
+
+ SfxItemState eState = pDataSet->GetItemState( ATTR_LINEBREAK, TRUE, NULL);
+ if ( eState == SFX_ITEM_DONTCARE )
+ return aNULL();
+
+ uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW );
+ uno::Any aValue = xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsTextWrapped" ) ) );
+ return aValue;
+}
+
+uno::Reference< excel::XInterior > ScVbaRange::Interior( ) throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
+ return new ScVbaInterior ( this, mxContext, xProps, getScDocument() );
+}
+uno::Reference< excel::XRange >
+ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2 ) throw (uno::RuntimeException)
+{
+ return Range( Cell1, Cell2, false );
+}
+uno::Reference< excel::XRange >
+ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseInpuRangeTab ) throw (uno::RuntimeException)
+
+{
+ uno::Reference< table::XCellRange > xCellRange = mxRange;
+
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ xCellRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ }
+ else
+ xCellRange.set( mxRange );
+
+ RangeHelper thisRange( xCellRange );
+ uno::Reference< table::XCellRange > xRanges = thisRange.getCellRangeFromSheet();
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xRanges, uno::UNO_QUERY_THROW );
+
+ uno::Reference< table::XCellRange > xReferrer =
+ xRanges->getCellRangeByPosition( getColumn()-1, getRow()-1,
+ xAddressable->getRangeAddress().EndColumn,
+ xAddressable->getRangeAddress().EndRow );
+ // xAddressable now for this range
+ xAddressable.set( xReferrer, uno::UNO_QUERY_THROW );
+
+ if( !Cell1.hasValue() )
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " Invalid Argument " ) ),
+ uno::Reference< XInterface >() );
+
+ table::CellRangeAddress resultAddress;
+ table::CellRangeAddress parentRangeAddress = xAddressable->getRangeAddress();
+
+ ScRange aRange;
+ // Cell1 defined only
+ if ( !Cell2.hasValue() )
+ {
+ rtl::OUString sName;
+ Cell1 >>= sName;
+ RangeHelper referRange( xReferrer );
+ table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress();
+ return getRangeForName( mxContext, sName, getScDocShell(), referAddress );
+
+ }
+ else
+ {
+ table::CellRangeAddress cell1, cell2;
+ cell1 = getCellRangeAddressForVBARange( Cell1, getScDocShell() );
+ // Cell1 & Cell2 defined
+ // Excel seems to combine the range as the range defined by
+ // the combination of Cell1 & Cell2
+
+ cell2 = getCellRangeAddressForVBARange( Cell2, getScDocShell() );
+
+ resultAddress.StartColumn = ( cell1.StartColumn < cell2.StartColumn ) ? cell1.StartColumn : cell2.StartColumn;
+ resultAddress.StartRow = ( cell1.StartRow < cell2.StartRow ) ? cell1.StartRow : cell2.StartRow;
+ resultAddress.EndColumn = ( cell1.EndColumn > cell2.EndColumn ) ? cell1.EndColumn : cell2.EndColumn;
+ resultAddress.EndRow = ( cell1.EndRow > cell2.EndRow ) ? cell1.EndRow : cell2.EndRow;
+ if ( bForceUseInpuRangeTab )
+ {
+ // this is a call from Application.Range( x,y )
+ // its possiblefor x or y to specify a different sheet from
+ // the current or active on ( but they must be the same )
+ if ( cell1.Sheet != cell2.Sheet )
+ throw uno::RuntimeException();
+ parentRangeAddress.Sheet = cell1.Sheet;
+ }
+ else
+ {
+ // this is not a call from Application.Range( x,y )
+ // if a different sheet from this range is specified it's
+ // an error
+ if ( parentRangeAddress.Sheet != cell1.Sheet
+ || parentRangeAddress.Sheet != cell2.Sheet
+ )
+ throw uno::RuntimeException();
+
+ }
+ ScUnoConversion::FillScRange( aRange, resultAddress );
+ }
+ ScRange parentAddress;
+ ScUnoConversion::FillScRange( parentAddress, parentRangeAddress);
+ if ( aRange.aStart.Col() >= 0 && aRange.aStart.Row() >= 0 && aRange.aEnd.Col() >= 0 && aRange.aEnd.Row() >= 0 )
+ {
+ sal_Int32 nStartX = parentAddress.aStart.Col() + aRange.aStart.Col();
+ sal_Int32 nStartY = parentAddress.aStart.Row() + aRange.aStart.Row();
+ sal_Int32 nEndX = parentAddress.aStart.Col() + aRange.aEnd.Col();
+ sal_Int32 nEndY = parentAddress.aStart.Row() + aRange.aEnd.Row();
+
+ if ( nStartX <= nEndX && nEndX <= parentAddress.aEnd.Col() &&
+ nStartY <= nEndY && nEndY <= parentAddress.aEnd.Row() )
+ {
+ ScRange aNew( (SCCOL)nStartX, (SCROW)nStartY, parentAddress.aStart.Tab(),
+ (SCCOL)nEndX, (SCROW)nEndY, parentAddress.aEnd.Tab() );
+ xCellRange = new ScCellRangeObj( getScDocShell(), aNew );
+ }
+ }
+
+ return new ScVbaRange( mxParent, mxContext, xCellRange );
+
+}
+
+// Allow access to underlying openoffice uno api ( useful for debugging
+// with openoffice basic )
+uno::Any SAL_CALL ScVbaRange::getCellRange( ) throw (uno::RuntimeException)
+{
+ uno::Any aAny;
+ if ( mxRanges.is() )
+ aAny <<= mxRanges;
+ else if ( mxRange.is() )
+ aAny <<= mxRange;
+ return aAny;
+}
+
+/*static*/ uno::Any ScVbaRange::getCellRange( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException)
+{
+ if( ScVbaRange* pVbaRange = getImplementation( rxRange ) )
+ return pVbaRange->getCellRange();
+ throw uno::RuntimeException();
+}
+
+static USHORT
+getPasteFlags (sal_Int32 Paste)
+{
+ USHORT nFlags = IDF_NONE;
+ switch (Paste) {
+ case excel::XlPasteType::xlPasteComments:
+ nFlags = IDF_NOTE;break;
+ case excel::XlPasteType::xlPasteFormats:
+ nFlags = IDF_ATTRIB;break;
+ case excel::XlPasteType::xlPasteFormulas:
+ nFlags = IDF_FORMULA;break;
+ case excel::XlPasteType::xlPasteFormulasAndNumberFormats :
+ case excel::XlPasteType::xlPasteValues:
+#ifdef VBA_OOBUILD_HACK
+ nFlags = ( IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_SPECIAL_BOOLEAN ); break;
+#else
+ nFlags = ( IDF_VALUE | IDF_DATETIME | IDF_STRING ); break;
+#endif
+ case excel::XlPasteType::xlPasteValuesAndNumberFormats:
+ nFlags = IDF_VALUE | IDF_ATTRIB; break;
+ case excel::XlPasteType::xlPasteColumnWidths:
+ case excel::XlPasteType::xlPasteValidation:
+ nFlags = IDF_NONE;break;
+ case excel::XlPasteType::xlPasteAll:
+ case excel::XlPasteType::xlPasteAllExceptBorders:
+ default:
+ nFlags = IDF_ALL;break;
+ };
+return nFlags;
+}
+
+static USHORT
+getPasteFormulaBits( sal_Int32 Operation)
+{
+ USHORT nFormulaBits = PASTE_NOFUNC ;
+ switch (Operation)
+ {
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationAdd:
+ nFormulaBits = PASTE_ADD;break;
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationSubtract:
+ nFormulaBits = PASTE_SUB;break;
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationMultiply:
+ nFormulaBits = PASTE_MUL;break;
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationDivide:
+ nFormulaBits = PASTE_DIV;break;
+
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationNone:
+ default:
+ nFormulaBits = PASTE_NOFUNC; break;
+ };
+
+return nFormulaBits;
+}
+void SAL_CALL
+ScVbaRange::PasteSpecial( const uno::Any& Paste, const uno::Any& Operation, const uno::Any& SkipBlanks, const uno::Any& Transpose ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
+ ScDocShell* pShell = getScDocShell();
+
+ uno::Reference< frame::XModel > xModel( ( pShell ? pShell->GetModel() : NULL ), uno::UNO_QUERY_THROW );
+ uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ // save old selection
+ uno::Reference< uno::XInterface > xSel( xModel->getCurrentSelection() );
+ // select this range
+ xSelection->select( uno::makeAny( mxRange ) );
+ // set up defaults
+ sal_Int32 nPaste = excel::XlPasteType::xlPasteAll;
+ sal_Int32 nOperation = excel::XlPasteSpecialOperation::xlPasteSpecialOperationNone;
+ sal_Bool bTranspose = sal_False;
+ sal_Bool bSkipBlanks = sal_False;
+
+ if ( Paste.hasValue() )
+ Paste >>= nPaste;
+ if ( Operation.hasValue() )
+ Operation >>= nOperation;
+ if ( SkipBlanks.hasValue() )
+ SkipBlanks >>= bSkipBlanks;
+ if ( Transpose.hasValue() )
+ Transpose >>= bTranspose;
+
+ USHORT nFlags = getPasteFlags(nPaste);
+ USHORT nFormulaBits = getPasteFormulaBits(nOperation);
+ excel::implnPasteSpecial(pShell->GetModel(), nFlags,nFormulaBits,bSkipBlanks,bTranspose);
+ // restore selection
+ xSelection->select( uno::makeAny( xSel ) );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::getEntireColumnOrRow( bool bColumn ) throw (uno::RuntimeException)
+{
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ // copy the range list
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+
+ for ( ScRange* pRange = aCellRanges.First() ; pRange; pRange = aCellRanges.Next() )
+ {
+ if ( bColumn )
+ {
+ pRange->aStart.SetRow( 0 );
+ pRange->aEnd.SetRow( MAXROW );
+ }
+ else
+ {
+ pRange->aStart.SetCol( 0 );
+ pRange->aEnd.SetCol( MAXCOL );
+ }
+ }
+ if ( aCellRanges.Count() > 1 ) // Multi-Area
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
+
+ return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn );
+ }
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) );
+ return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::getEntireRow() throw (uno::RuntimeException)
+{
+ return getEntireColumnOrRow(false);
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::getEntireColumn() throw (uno::RuntimeException)
+{
+ return getEntireColumnOrRow();
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaRange::AddComment( const uno::Any& Text ) throw (uno::RuntimeException)
+{
+ // if there is already a comment in the top-left cell then throw
+ if( getComment().is() )
+ throw uno::RuntimeException();
+
+ // workaround: Excel allows to create empty comment, Calc does not
+ ::rtl::OUString aNoteText;
+ if( Text.hasValue() && !(Text >>= aNoteText) )
+ throw uno::RuntimeException();
+ if( aNoteText.getLength() == 0 )
+ aNoteText = ::rtl::OUString( sal_Unicode( ' ' ) );
+
+ // try to create a new annotation
+ table::CellRangeAddress aRangePos = lclGetRangeAddress( mxRange );
+ table::CellAddress aNotePos( aRangePos.Sheet, aRangePos.StartColumn, aRangePos.StartRow );
+ uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW );
+ xAnnos->insertNew( aNotePos, aNoteText );
+ return new ScVbaComment( this, mxContext, getUnoModel(), mxRange );
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaRange::getComment() throw (uno::RuntimeException)
+{
+ // intentional behavior to return a null object if no
+ // comment defined
+ uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, getUnoModel(), mxRange ) );
+ if ( !xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() )
+ return NULL;
+ return xComment;
+
+}
+
+uno::Reference< beans::XPropertySet >
+getRowOrColumnProps( const uno::Reference< table::XCellRange >& xCellRange, bool bRows ) throw ( uno::RuntimeException )
+{
+ uno::Reference< table::XColumnRowRange > xColRow( xCellRange, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( bRows )
+ xProps.set( xColRow->getRows(), uno::UNO_QUERY_THROW );
+ else
+ xProps.set( xColRow->getColumns(), uno::UNO_QUERY_THROW );
+ return xProps;
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getHidden() throw (uno::RuntimeException)
+{
+ // if multi-area result is the result of the
+ // first area
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(sal_Int32(1)), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getHidden();
+ }
+ bool bIsVisible = false;
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps = getRowOrColumnProps( mxRange, mbIsRows );
+ if ( !( xProps->getPropertyValue( ISVISIBLE ) >>= bIsVisible ) )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to get IsVisible property")), uno::Reference< uno::XInterface >() );
+ }
+ catch( uno::Exception& e )
+ {
+ throw uno::RuntimeException( e.Message, uno::Reference< uno::XInterface >() );
+ }
+ return uno::makeAny( !bIsVisible );
+}
+
+void SAL_CALL
+ScVbaRange::setHidden( const uno::Any& _hidden ) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setHidden( _hidden );
+ }
+ return;
+ }
+
+ bool bHidden = extractBoolFromAny( _hidden );
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps = getRowOrColumnProps( mxRange, mbIsRows );
+ xProps->setPropertyValue( ISVISIBLE, uno::Any( !bHidden ) );
+ }
+ catch( uno::Exception& e )
+ {
+ throw uno::RuntimeException( e.Message, uno::Reference< uno::XInterface >() );
+ }
+}
+
+::sal_Bool SAL_CALL
+ScVbaRange::Replace( const ::rtl::OUString& What, const ::rtl::OUString& Replacement, const uno::Any& LookAt, const uno::Any& SearchOrder, const uno::Any& MatchCase, const uno::Any& MatchByte, const uno::Any& SearchFormat, const uno::Any& ReplaceFormat ) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ for ( sal_Int32 index = 1; index <= m_Areas->getCount(); ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Replace( What, Replacement, LookAt, SearchOrder, MatchCase, MatchByte, SearchFormat, ReplaceFormat );
+ }
+ return sal_True; // seems to return true always ( or at least I haven't found the trick of
+ }
+
+ // sanity check required params
+ if ( !What.getLength() /*|| !Replacement.getLength()*/ )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, missing params" )) , uno::Reference< uno::XInterface >() );
+ rtl::OUString sWhat = VBAToRegexp( What);
+ // #TODO #FIXME SearchFormat & ReplacesFormat are not processed
+ // What do we do about MatchByte.. we don't seem to support that
+ const SvxSearchItem& globalSearchOptions = ScGlobal::GetSearchItem();
+ SvxSearchItem newOptions( globalSearchOptions );
+
+ sal_Int16 nLook = globalSearchOptions.GetWordOnly() ? excel::XlLookAt::xlPart : excel::XlLookAt::xlWhole;
+ sal_Int16 nSearchOrder = globalSearchOptions.GetRowDirection() ? excel::XlSearchOrder::xlByRows : excel::XlSearchOrder::xlByColumns;
+
+ sal_Bool bMatchCase = sal_False;
+ uno::Reference< util::XReplaceable > xReplace( mxRange, uno::UNO_QUERY );
+ if ( xReplace.is() )
+ {
+ uno::Reference< util::XReplaceDescriptor > xDescriptor =
+ xReplace->createReplaceDescriptor();
+
+ xDescriptor->setSearchString( sWhat);
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHREGEXP ) ), uno::makeAny( sal_True ) );
+ xDescriptor->setReplaceString( Replacement);
+ if ( LookAt.hasValue() )
+ {
+ // sets SearchWords ( true is Cell match )
+ nLook = ::comphelper::getINT16( LookAt );
+ sal_Bool bSearchWords = sal_False;
+ if ( nLook == excel::XlLookAt::xlPart )
+ bSearchWords = sal_False;
+ else if ( nLook == excel::XlLookAt::xlWhole )
+ bSearchWords = sal_True;
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for LookAt" )) , uno::Reference< uno::XInterface >() );
+ // set global search props ( affects the find dialog
+ // and of course the defaults for this method
+ newOptions.SetWordOnly( bSearchWords );
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHWORDS ) ), uno::makeAny( bSearchWords ) );
+ }
+ // sets SearchByRow ( true for Rows )
+ if ( SearchOrder.hasValue() )
+ {
+ nSearchOrder = ::comphelper::getINT16( SearchOrder );
+ sal_Bool bSearchByRow = sal_False;
+ if ( nSearchOrder == excel::XlSearchOrder::xlByColumns )
+ bSearchByRow = sal_False;
+ else if ( nSearchOrder == excel::XlSearchOrder::xlByRows )
+ bSearchByRow = sal_True;
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for SearchOrder" )) , uno::Reference< uno::XInterface >() );
+
+ newOptions.SetRowDirection( bSearchByRow );
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHBYROW ) ), uno::makeAny( bSearchByRow ) );
+ }
+ if ( MatchCase.hasValue() )
+ {
+ // SearchCaseSensitive
+ MatchCase >>= bMatchCase;
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHCASE ) ), uno::makeAny( bMatchCase ) );
+ }
+
+ ScGlobal::SetSearchItem( newOptions );
+ // ignore MatchByte for the moment, its not supported in
+ // OOo.org afaik
+
+ uno::Reference< util::XSearchDescriptor > xSearch( xDescriptor, uno::UNO_QUERY );
+ xReplace->replaceAll( xSearch );
+ }
+ return sal_True; // always
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Find( const uno::Any& What, const uno::Any& After, const uno::Any& LookIn, const uno::Any& LookAt, const uno::Any& SearchOrder, const uno::Any& SearchDirection, const uno::Any& MatchCase, const uno::Any& /*MatchByte*/, const uno::Any& /*SearchFormat*/ ) throw (uno::RuntimeException)
+{
+ // return a Range object that represents the first cell where that information is found.
+ rtl::OUString sWhat;
+ sal_Int32 nWhat = 0;
+ double fWhat = 0.0;
+
+ // string.
+ if( What >>= sWhat )
+ {
+ if( !sWhat.getLength() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Find, missing params" )) , uno::Reference< uno::XInterface >() );
+ }
+ else if( What >>= nWhat )
+ {
+ sWhat = rtl::OUString::valueOf( nWhat );
+ }
+ else if( What >>= fWhat )
+ {
+ sWhat = rtl::OUString::valueOf( fWhat );
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Find, missing params" )) , uno::Reference< uno::XInterface >() );
+
+ rtl::OUString sSearch = VBAToRegexp( sWhat );
+
+ const SvxSearchItem& globalSearchOptions = ScGlobal::GetSearchItem();
+ SvxSearchItem newOptions( globalSearchOptions );
+
+ sal_Int16 nLookAt = globalSearchOptions.GetWordOnly() ? excel::XlLookAt::xlPart : excel::XlLookAt::xlWhole;
+ sal_Int16 nSearchOrder = globalSearchOptions.GetRowDirection() ? excel::XlSearchOrder::xlByRows : excel::XlSearchOrder::xlByColumns;
+
+ uno::Reference< util::XSearchable > xSearch( mxRange, uno::UNO_QUERY );
+ if( xSearch.is() )
+ {
+ uno::Reference< util::XSearchDescriptor > xDescriptor = xSearch->createSearchDescriptor();
+ xDescriptor->setSearchString( sSearch );
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHREGEXP ) ), uno::Any( true ) );
+
+ uno::Reference< excel::XRange > xAfterRange;
+ uno::Reference< table::XCellRange > xStartCell;
+ if( After >>= xAfterRange )
+ {
+ // After must be a single cell in the range
+ if( xAfterRange->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("After must be a single cell." )) , uno::Reference< uno::XInterface >() );
+ uno::Reference< excel::XRange > xCell( Cells( uno::makeAny( xAfterRange->getRow() ), uno::makeAny( xAfterRange->getColumn() ) ), uno::UNO_QUERY );
+ if( !xCell.is() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("After must be in range." )) , uno::Reference< uno::XInterface >() );
+ xStartCell.set( xAfterRange->getCellRange(), uno::UNO_QUERY_THROW );
+ }
+
+ // LookIn
+ if( LookIn.hasValue() )
+ {
+ sal_Int32 nLookIn = 0;
+ if( LookIn >>= nLookIn )
+ {
+ sal_Int16 nSearchType = 0;
+ switch( nLookIn )
+ {
+ case excel::XlFindLookIn::xlComments :
+ nSearchType = SVX_SEARCHIN_NOTE; // Notes
+ break;
+ case excel::XlFindLookIn::xlFormulas :
+ nSearchType = SVX_SEARCHIN_FORMULA;
+ break;
+ case excel::XlFindLookIn::xlValues :
+ nSearchType = SVX_SEARCHIN_VALUE;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for LookIn." )) , uno::Reference< uno::XInterface >() );
+ }
+ newOptions.SetCellType( nSearchType );
+ xDescriptor->setPropertyValue( rtl::OUString::createFromAscii( "SearchType" ), uno::makeAny( nSearchType ) );
+ }
+ }
+
+ // LookAt
+ if ( LookAt.hasValue() )
+ {
+ nLookAt = ::comphelper::getINT16( LookAt );
+ sal_Bool bSearchWords = sal_False;
+ if ( nLookAt == excel::XlLookAt::xlPart )
+ bSearchWords = sal_False;
+ else if ( nLookAt == excel::XlLookAt::xlWhole )
+ bSearchWords = sal_True;
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for LookAt" )) , uno::Reference< uno::XInterface >() );
+ newOptions.SetWordOnly( bSearchWords );
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHWORDS ) ), uno::makeAny( bSearchWords ) );
+ }
+
+ // SearchOrder
+ if ( SearchOrder.hasValue() )
+ {
+ nSearchOrder = ::comphelper::getINT16( SearchOrder );
+ sal_Bool bSearchByRow = sal_False;
+ if ( nSearchOrder == excel::XlSearchOrder::xlByColumns )
+ bSearchByRow = sal_False;
+ else if ( nSearchOrder == excel::XlSearchOrder::xlByRows )
+ bSearchByRow = sal_True;
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for SearchOrder" )) , uno::Reference< uno::XInterface >() );
+
+ newOptions.SetRowDirection( bSearchByRow );
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHBYROW ) ), uno::makeAny( bSearchByRow ) );
+ }
+
+ // SearchDirection
+ if ( SearchDirection.hasValue() )
+ {
+ sal_Int32 nSearchDirection = 0;
+ if( SearchDirection >>= nSearchDirection )
+ {
+ sal_Bool bSearchBackwards = sal_False;
+ if ( nSearchDirection == excel::XlSearchDirection::xlNext )
+ bSearchBackwards = sal_False;
+ else if( nSearchDirection == excel::XlSearchDirection::xlPrevious )
+ bSearchBackwards = sal_True;
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for SearchDirection" )) , uno::Reference< uno::XInterface >() );
+ newOptions.SetBackward( bSearchBackwards );
+ xDescriptor->setPropertyValue( rtl::OUString::createFromAscii( "SearchBackwards" ), uno::makeAny( bSearchBackwards ) );
+ }
+ }
+
+ // MatchCase
+ sal_Bool bMatchCase = sal_False;
+ if ( MatchCase.hasValue() )
+ {
+ // SearchCaseSensitive
+ if( !( MatchCase >>= bMatchCase ) )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for MatchCase" )) , uno::Reference< uno::XInterface >() );
+ }
+ xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHCASE ) ), uno::makeAny( bMatchCase ) );
+
+ // MatchByte
+ // SearchFormat
+ // ignore
+
+ ScGlobal::SetSearchItem( newOptions );
+
+ uno::Reference< uno::XInterface > xInterface = xStartCell.is() ? xSearch->findNext( xStartCell, xDescriptor) : xSearch->findFirst( xDescriptor );
+ uno::Reference< table::XCellRange > xCellRange( xInterface, uno::UNO_QUERY );
+ if ( xCellRange.is() )
+ {
+ uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange );
+ if( xResultRange.is() )
+ {
+ xResultRange->Select();
+ return xResultRange;
+ }
+ }
+
+ }
+
+ return uno::Reference< excel::XRange >();
+}
+
+uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Reference< uno::XComponentContext >& xContext, ScDocShell* pDocSh )
+{
+ uno::Reference< excel::XRange > xKeyRange;
+ if ( Key.getValueType() == excel::XRange::static_type() )
+ {
+ xKeyRange.set( Key, uno::UNO_QUERY_THROW );
+ }
+ else if ( Key.getValueType() == ::getCppuType( static_cast< const rtl::OUString* >(0) ) )
+
+ {
+ rtl::OUString sRangeName = ::comphelper::getString( Key );
+ table::CellRangeAddress aRefAddr;
+ if ( !pDocSh )
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() );
+ xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr );
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() );
+ uno::Reference< table::XCellRange > xKey;
+ xKey.set( xKeyRange->getCellRange(), uno::UNO_QUERY_THROW );
+ return xKey;
+}
+
+// helper method for Sort
+sal_Int32 findSortPropertyIndex( const uno::Sequence< beans::PropertyValue >& props,
+const rtl::OUString& sPropName ) throw( uno::RuntimeException )
+{
+ const beans::PropertyValue* pProp = props.getConstArray();
+ sal_Int32 nItems = props.getLength();
+
+ sal_Int32 count=0;
+ for ( ; count < nItems; ++count, ++pProp )
+ if ( pProp->Name.equals( sPropName ) )
+ return count;
+ if ( count == nItems )
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort unknown sort property")), uno::Reference< uno::XInterface >() );
+ return -1; //should never reach here ( satisfy compiler )
+}
+
+// helper method for Sort
+void updateTableSortField( const uno::Reference< table::XCellRange >& xParentRange,
+ const uno::Reference< table::XCellRange >& xColRowKey, sal_Int16 nOrder,
+ table::TableSortField& aTableField, sal_Bool bIsSortColumn, sal_Bool bMatchCase ) throw ( uno::RuntimeException )
+{
+ RangeHelper parentRange( xParentRange );
+ RangeHelper colRowRange( xColRowKey );
+
+ table::CellRangeAddress parentRangeAddress = parentRange.getCellRangeAddressable()->getRangeAddress();
+
+ table::CellRangeAddress colRowKeyAddress = colRowRange.getCellRangeAddressable()->getRangeAddress();
+
+ // make sure that upper left poing of key range is within the
+ // parent range
+ if ( ( !bIsSortColumn && colRowKeyAddress.StartColumn >= parentRangeAddress.StartColumn &&
+ colRowKeyAddress.StartColumn <= parentRangeAddress.EndColumn ) || ( bIsSortColumn &&
+ colRowKeyAddress.StartRow >= parentRangeAddress.StartRow &&
+ colRowKeyAddress.StartRow <= parentRangeAddress.EndRow ) )
+ {
+ //determine col/row index
+ if ( bIsSortColumn )
+ aTableField.Field = colRowKeyAddress.StartRow - parentRangeAddress.StartRow;
+ else
+ aTableField.Field = colRowKeyAddress.StartColumn - parentRangeAddress.StartColumn;
+ aTableField.IsCaseSensitive = bMatchCase;
+
+ if ( nOrder == excel::XlSortOrder::xlAscending )
+ aTableField.IsAscending = sal_True;
+ else
+ aTableField.IsAscending = sal_False;
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal Key param" ) ), uno::Reference< uno::XInterface >() );
+
+
+}
+
+void SAL_CALL
+ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const uno::Any& Key2, const uno::Any& /*Type*/, const uno::Any& Order2, const uno::Any& Key3, const uno::Any& Order3, const uno::Any& Header, const uno::Any& OrderCustom, const uno::Any& MatchCase, const uno::Any& Orientation, const uno::Any& SortMethod, const uno::Any& DataOption1, const uno::Any& DataOption2, const uno::Any& DataOption3 ) throw (uno::RuntimeException)
+{
+ // #TODO# #FIXME# can we do something with Type
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
+
+ sal_Int16 nDataOption1 = excel::XlSortDataOption::xlSortNormal;
+ sal_Int16 nDataOption2 = excel::XlSortDataOption::xlSortNormal;;
+ sal_Int16 nDataOption3 = excel::XlSortDataOption::xlSortNormal;
+
+ ScDocument* pDoc = getScDocument();
+ if ( !pDoc )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ ScSortParam aSortParam;
+ SCTAB nTab = thisRangeAddress.Sheet;
+ pDoc->GetSortParam( aSortParam, nTab );
+
+ if ( DataOption1.hasValue() )
+ DataOption1 >>= nDataOption1;
+ if ( DataOption2.hasValue() )
+ DataOption2 >>= nDataOption2;
+ if ( DataOption3.hasValue() )
+ DataOption3 >>= nDataOption3;
+
+ // 1) #TODO #FIXME need to process DataOption[1..3] not used currently
+ // 2) #TODO #FIXME need to refactor this ( below ) into a IsSingleCell() method
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
+
+ // 'Fraid I don't remember what I was trying to achieve here ???
+/*
+ if ( isSingleCellRange() )
+ {
+ uno::Reference< XRange > xCurrent = CurrentRegion();
+ xCurrent->Sort( Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3 );
+ return;
+ }
+*/
+ // set up defaults
+
+ sal_Int16 nOrder1 = aSortParam.bAscending[0] ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder2 = aSortParam.bAscending[1] ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder3 = aSortParam.bAscending[2] ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+
+ sal_Int16 nCustom = aSortParam.nUserIndex;
+ sal_Int16 nSortMethod = excel::XlSortMethod::xlPinYin;
+ sal_Bool bMatchCase = aSortParam.bCaseSens;
+
+ // seems to work opposite to expected, see below
+ sal_Int16 nOrientation = aSortParam.bByRow ? excel::XlSortOrientation::xlSortColumns : excel::XlSortOrientation::xlSortRows;
+
+ if ( Orientation.hasValue() )
+ {
+ // Documentation says xlSortRows is default but that doesn't appear to be
+ // the case. Also it appears that xlSortColumns is the default which
+ // strangely enought sorts by Row
+ nOrientation = ::comphelper::getINT16( Orientation );
+ // persist new option to be next calls default
+ if ( nOrientation == excel::XlSortOrientation::xlSortRows )
+ aSortParam.bByRow = FALSE;
+ else
+ aSortParam.bByRow = TRUE;
+
+ }
+
+ sal_Bool bIsSortColumns=sal_False; // sort by row
+
+ if ( nOrientation == excel::XlSortOrientation::xlSortRows )
+ bIsSortColumns = sal_True;
+ sal_Int16 nHeader = 0;
+#ifdef VBA_OOBUILD_HACK
+ nHeader = aSortParam.nCompatHeader;
+#endif
+ sal_Bool bContainsHeader = sal_False;
+
+ if ( Header.hasValue() )
+ {
+ nHeader = ::comphelper::getINT16( Header );
+#ifdef VBA_OOBUILD_HACK
+ aSortParam.nCompatHeader = nHeader;
+#endif
+ }
+
+ if ( nHeader == excel::XlYesNoGuess::xlGuess )
+ {
+ bool bHasColHeader = pDoc->HasColHeader( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), static_cast< SCCOL >( thisRangeAddress.EndColumn ), static_cast< SCROW >( thisRangeAddress.EndRow ), static_cast< SCTAB >( thisRangeAddress.Sheet ));
+ bool bHasRowHeader = pDoc->HasRowHeader( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), static_cast< SCCOL >( thisRangeAddress.EndColumn ), static_cast< SCROW >( thisRangeAddress.EndRow ), static_cast< SCTAB >( thisRangeAddress.Sheet ) );
+ if ( bHasColHeader || bHasRowHeader )
+ nHeader = excel::XlYesNoGuess::xlYes;
+ else
+ nHeader = excel::XlYesNoGuess::xlNo;
+#ifdef VBA_OOBUILD_HACK
+ aSortParam.nCompatHeader = nHeader;
+#endif
+ }
+
+ if ( nHeader == excel::XlYesNoGuess::xlYes )
+ bContainsHeader = sal_True;
+
+ if ( SortMethod.hasValue() )
+ {
+ nSortMethod = ::comphelper::getINT16( SortMethod );
+ }
+
+ if ( OrderCustom.hasValue() )
+ {
+ OrderCustom >>= nCustom;
+ --nCustom; // 0-based in OOo
+ aSortParam.nUserIndex = nCustom;
+ }
+
+ if ( MatchCase.hasValue() )
+ {
+ MatchCase >>= bMatchCase;
+ aSortParam.bCaseSens = bMatchCase;
+ }
+
+ if ( Order1.hasValue() )
+ {
+ nOrder1 = ::comphelper::getINT16(Order1);
+ if ( nOrder1 == excel::XlSortOrder::xlAscending )
+ aSortParam.bAscending[0] = TRUE;
+ else
+ aSortParam.bAscending[0] = FALSE;
+
+ }
+ if ( Order2.hasValue() )
+ {
+ nOrder2 = ::comphelper::getINT16(Order2);
+ if ( nOrder2 == excel::XlSortOrder::xlAscending )
+ aSortParam.bAscending[1] = TRUE;
+ else
+ aSortParam.bAscending[1] = FALSE;
+ }
+ if ( Order3.hasValue() )
+ {
+ nOrder3 = ::comphelper::getINT16(Order3);
+ if ( nOrder3 == excel::XlSortOrder::xlAscending )
+ aSortParam.bAscending[2] = TRUE;
+ else
+ aSortParam.bAscending[2] = FALSE;
+ }
+
+ uno::Reference< table::XCellRange > xKey1;
+ uno::Reference< table::XCellRange > xKey2;
+ uno::Reference< table::XCellRange > xKey3;
+ ScDocShell* pDocShell = getScDocShell();
+ xKey1 = processKey( Key1, mxContext, pDocShell );
+ if ( !xKey1.is() )
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort needs a key1 param")), uno::Reference< uno::XInterface >() );
+
+ if ( Key2.hasValue() )
+ xKey2 = processKey( Key2, mxContext, pDocShell );
+ if ( Key3.hasValue() )
+ xKey3 = processKey( Key3, mxContext, pDocShell );
+
+ uno::Reference< util::XSortable > xSort( mxRange, uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::PropertyValue > sortDescriptor = xSort->createSortDescriptor();
+ sal_Int32 nTableSortFieldIndex = findSortPropertyIndex( sortDescriptor, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SortFields") ) );
+
+ uno::Sequence< table::TableSortField > sTableFields(1);
+ sal_Int32 nTableIndex = 0;
+ updateTableSortField( mxRange, xKey1, nOrder1, sTableFields[ nTableIndex++ ], bIsSortColumns, bMatchCase );
+
+ if ( xKey2.is() )
+ {
+ sTableFields.realloc( sTableFields.getLength() + 1 );
+ updateTableSortField( mxRange, xKey2, nOrder2, sTableFields[ nTableIndex++ ], bIsSortColumns, bMatchCase );
+ }
+ if ( xKey3.is() )
+ {
+ sTableFields.realloc( sTableFields.getLength() + 1 );
+ updateTableSortField( mxRange, xKey3, nOrder3, sTableFields[ nTableIndex++ ], bIsSortColumns, bMatchCase );
+ }
+ sortDescriptor[ nTableSortFieldIndex ].Value <<= sTableFields;
+
+ sal_Int32 nIndex = findSortPropertyIndex( sortDescriptor, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSortColumns")) );
+ sortDescriptor[ nIndex ].Value <<= bIsSortColumns;
+
+ nIndex = findSortPropertyIndex( sortDescriptor, CONTS_HEADER );
+ sortDescriptor[ nIndex ].Value <<= bContainsHeader;
+
+ pDoc->SetSortParam( aSortParam, nTab );
+ xSort->sort( sortDescriptor );
+
+ // #FIXME #TODO
+ // The SortMethod param is not processed ( not sure what its all about, need to
+
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::End( ::sal_Int32 Direction ) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
+ return xRange->End( Direction );
+ }
+
+
+ // #FIXME #TODO
+ // euch! found my orig implementation sucked, so
+ // trying this even suckier one ( really need to use/expose code in
+ // around ScTabView::MoveCursorArea(), thats the bit that calcutes
+ // where the cursor should go )
+ // Main problem with this method is the ultra hacky attempt to preserve
+ // the ActiveCell, there should be no need to go to these extreems
+
+ // Save ActiveCell pos ( to restore later )
+ uno::Any aDft;
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ rtl::OUString sActiveCell = xApplication->getActiveCell()->Address(aDft, aDft, aDft, aDft, aDft );
+
+ // position current cell upper left of this range
+ Cells( uno::makeAny( (sal_Int32) 1 ), uno::makeAny( (sal_Int32) 1 ) )->Select();
+
+ uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
+
+ SfxViewFrame* pViewFrame = excel::getViewFrame( xModel );
+ if ( pViewFrame )
+ {
+ SfxAllItemSet aArgs( SFX_APP()->GetPool() );
+ // Hoping this will make sure this slot is called
+ // synchronously
+ SfxBoolItem sfxAsync( SID_ASYNCHRON, sal_False );
+ aArgs.Put( sfxAsync, sfxAsync.Which() );
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+
+ USHORT nSID = 0;
+
+ switch( Direction )
+ {
+ case excel::XlDirection::xlDown:
+ nSID = SID_CURSORBLKDOWN;
+ break;
+ case excel::XlDirection::xlUp:
+ nSID = SID_CURSORBLKUP;
+ break;
+ case excel::XlDirection::xlToLeft:
+ nSID = SID_CURSORBLKLEFT;
+ break;
+ case excel::XlDirection::xlToRight:
+ nSID = SID_CURSORBLKRIGHT;
+ break;
+ default:
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": Invalid ColumnIndex" ) ), uno::Reference< uno::XInterface >() );
+ }
+ if ( pDispatcher )
+ {
+ pDispatcher->Execute( nSID, (SfxCallMode)SFX_CALLMODE_SYNCHRON, aArgs );
+ }
+ }
+
+ // result is the ActiveCell
+ rtl::OUString sMoved = xApplication->getActiveCell()->Address(aDft, aDft, aDft, aDft, aDft );
+
+ // restore old ActiveCell
+ uno::Any aVoid;
+
+ uno::Reference< excel::XRange > xOldActiveCell( xApplication->getActiveSheet()->Range( uno::makeAny( sActiveCell ), aVoid ), uno::UNO_QUERY_THROW );
+ xOldActiveCell->Select();
+
+ uno::Reference< excel::XRange > resultCell;
+
+ resultCell.set( xApplication->getActiveSheet()->Range( uno::makeAny( sMoved ), aVoid ), uno::UNO_QUERY_THROW );
+
+ // return result
+
+ return resultCell;
+}
+
+bool
+ScVbaRange::isSingleCellRange()
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY);
+ if ( xColumnRowRange.is() && xColumnRowRange->getRows()->getCount() == 1 && xColumnRowRange->getColumns()->getCount() == 1 )
+ return true;
+ return false;
+}
+
+uno::Reference< excel::XCharacters > SAL_CALL
+ScVbaRange::characters( const uno::Any& Start, const uno::Any& Length ) throw (uno::RuntimeException)
+{
+ if ( !isSingleCellRange() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create Characters property for multicell range ") ), uno::Reference< uno::XInterface >() );
+ uno::Reference< text::XSimpleText > xSimple(mxRange->getCellByPosition(0,0) , uno::UNO_QUERY_THROW );
+ ScDocument* pDoc = getDocumentFromRange(mxRange);
+ if ( !pDoc )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
+
+ ScVbaPalette aPalette( pDoc->GetDocumentShell() );
+ return new ScVbaCharacters( this, mxContext, aPalette, xSimple, Start, Length );
+}
+
+ void SAL_CALL
+ScVbaRange::Delete( const uno::Any& Shift ) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Delete( Shift );
+ }
+ return;
+ }
+ sheet::CellDeleteMode mode = sheet::CellDeleteMode_NONE ;
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ if ( Shift.hasValue() )
+ {
+ sal_Int32 nShift = 0;
+ Shift >>= nShift;
+ switch ( nShift )
+ {
+ case excel::XlDeleteShiftDirection::xlShiftUp:
+ mode = sheet::CellDeleteMode_UP;
+ break;
+ case excel::XlDeleteShiftDirection::xlShiftToLeft:
+ mode = sheet::CellDeleteMode_LEFT;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ("Illegal paramater ") ), uno::Reference< uno::XInterface >() );
+ }
+ }
+ else
+ {
+ bool bFullRow = ( thisAddress.StartColumn == 0 && thisAddress.EndColumn == MAXCOL );
+ sal_Int32 nCols = thisAddress.EndColumn - thisAddress.StartColumn;
+ sal_Int32 nRows = thisAddress.EndRow - thisAddress.StartRow;
+ if ( mbIsRows || bFullRow || ( nCols >= nRows ) )
+ mode = sheet::CellDeleteMode_UP;
+ else
+ mode = sheet::CellDeleteMode_LEFT;
+ }
+ uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xCellRangeMove->removeRange( thisAddress, mode );
+
+}
+
+//XElementAccess
+sal_Bool SAL_CALL
+ScVbaRange::hasElements() throw (uno::RuntimeException)
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY );
+ if ( xColumnRowRange.is() )
+ if ( xColumnRowRange->getRows()->getCount() ||
+ xColumnRowRange->getColumns()->getCount() )
+ return sal_True;
+ return sal_False;
+}
+
+// XEnumerationAccess
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaRange::createEnumeration() throw (uno::RuntimeException)
+{
+ if ( mbIsColumns || mbIsRows )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY );
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ sal_Int32 nElems = 0;
+ if ( mbIsColumns )
+ nElems = xColumnRowRange->getColumns()->getCount();
+ else
+ nElems = xColumnRowRange->getRows()->getCount();
+ return new ColumnsRowEnumeration( mxContext, xRange, nElems );
+
+ }
+ return new CellsEnumeration( mxParent, mxContext, m_Areas );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaRange::getDefaultMethodName( ) throw (uno::RuntimeException)
+{
+ const static rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM("Item") );
+ return sName;
+}
+
+
+uno::Reference< awt::XDevice >
+getDeviceFromDoc( const uno::Reference< frame::XModel >& xModel ) throw( uno::RuntimeException )
+{
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XFrame> xFrame( xController->getFrame(), uno::UNO_QUERY_THROW );
+ uno::Reference< awt::XDevice > xDevice( xFrame->getComponentWindow(), uno::UNO_QUERY_THROW );
+ return xDevice;
+}
+
+// returns calc internal col. width ( in points )
+double
+ScVbaRange::getCalcColWidth( const table::CellRangeAddress& rAddress) throw (uno::RuntimeException)
+{
+ ScDocument* pDoc = getScDocument();
+ USHORT nWidth = pDoc->GetOriginalWidth( static_cast< SCCOL >( rAddress.StartColumn ), static_cast< SCTAB >( rAddress.Sheet ) );
+ double nPoints = lcl_TwipsToPoints( nWidth );
+ nPoints = lcl_Round2DecPlaces( nPoints );
+ return nPoints;
+}
+
+double
+ScVbaRange::getCalcRowHeight( const table::CellRangeAddress& rAddress ) throw (uno::RuntimeException)
+{
+ ScDocument* pDoc = getDocumentFromRange( mxRange );
+ USHORT nWidth = pDoc->GetOriginalHeight( rAddress.StartRow, rAddress.Sheet );
+ double nPoints = lcl_TwipsToPoints( nWidth );
+ nPoints = lcl_Round2DecPlaces( nPoints );
+ return nPoints;
+}
+
+// return Char Width in points
+double getDefaultCharWidth( const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException )
+{
+ const static rtl::OUString sDflt( RTL_CONSTASCII_USTRINGPARAM("Default"));
+ const static rtl::OUString sCharFontName( RTL_CONSTASCII_USTRINGPARAM("CharFontName"));
+ const static rtl::OUString sPageStyles( RTL_CONSTASCII_USTRINGPARAM("PageStyles"));
+ // get the font from the default style
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xStyleSupplier->getStyleFamilies(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess2( xNameAccess->getByName( sPageStyles ), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xProps( xNameAccess2->getByName( sDflt ), uno::UNO_QUERY_THROW );
+ rtl::OUString sFontName;
+ xProps->getPropertyValue( sCharFontName ) >>= sFontName;
+
+ uno::Reference< awt::XDevice > xDevice = getDeviceFromDoc( xModel );
+ awt::FontDescriptor aDesc;
+ aDesc.Name = sFontName;
+ uno::Reference< awt::XFont > xFont( xDevice->getFont( aDesc ), uno::UNO_QUERY_THROW );
+ double nCharPixelWidth = xFont->getCharWidth( (sal_Int8)'0' );
+
+ double nPixelsPerMeter = xDevice->getInfo().PixelPerMeterX;
+ double nCharWidth = nCharPixelWidth / nPixelsPerMeter;
+ nCharWidth = nCharWidth * (double)56700;// in twips
+ return lcl_TwipsToPoints( (USHORT)nCharWidth );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getColumnWidth() throw (uno::RuntimeException)
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getColumnWidth();
+ }
+
+ double nColWidth = 0;
+ ScDocShell* pShell = getScDocShell();
+ if ( pShell )
+ {
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ double defaultCharWidth = getDefaultCharWidth( xModel );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ sal_Int32 nStartCol = thisAddress.StartColumn;
+ sal_Int32 nEndCol = thisAddress.EndColumn;
+ USHORT nColTwips = 0;
+ for( sal_Int32 nCol = nStartCol ; nCol <= nEndCol; ++nCol )
+ {
+ thisAddress.StartColumn = nCol;
+ USHORT nCurTwips = pShell->GetDocument()->GetOriginalWidth( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCTAB >( thisAddress.Sheet ) );
+ if ( nCol == nStartCol )
+ nColTwips = nCurTwips;
+ if ( nColTwips != nCurTwips )
+ return aNULL();
+ }
+ nColWidth = lcl_Round2DecPlaces( lcl_TwipsToPoints( nColTwips ) );
+ if ( xModel.is() )
+ nColWidth = nColWidth / defaultCharWidth;
+ }
+ nColWidth = lcl_Round2DecPlaces( nColWidth );
+ return uno::makeAny( nColWidth );
+}
+
+void SAL_CALL
+ScVbaRange::setColumnWidth( const uno::Any& _columnwidth ) throw (uno::RuntimeException)
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ for ( sal_Int32 index = 1; index != nLen; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(index) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setColumnWidth( _columnwidth );
+ }
+ return;
+ }
+ double nColWidth = 0;
+ _columnwidth >>= nColWidth;
+ nColWidth = lcl_Round2DecPlaces( nColWidth );
+ ScDocShell* pDocShell = getScDocShell();
+ if ( pDocShell )
+ {
+ uno::Reference< frame::XModel > xModel = pDocShell->GetModel();
+ if ( xModel.is() )
+ {
+
+ nColWidth = ( nColWidth * getDefaultCharWidth( xModel ) );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ USHORT nTwips = lcl_pointsToTwips( nColWidth );
+
+ ScDocFunc aFunc(*pDocShell);
+ SCCOLROW nColArr[2];
+ nColArr[0] = thisAddress.StartColumn;
+ nColArr[1] = thisAddress.EndColumn;
+ aFunc.SetWidthOrHeight( TRUE, 1, nColArr, thisAddress.Sheet, SC_SIZE_ORIGINAL,
+ nTwips, TRUE, TRUE );
+
+ }
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getWidth() throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getWidth();
+ }
+ uno::Reference< table::XColumnRowRange > xColRowRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xColRowRange->getColumns(), uno::UNO_QUERY_THROW );
+ sal_Int32 nElems = xIndexAccess->getCount();
+ double nWidth = 0;
+ for ( sal_Int32 index=0; index<nElems; ++index )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ double nTmpWidth = getCalcColWidth( xAddressable->getRangeAddress() );
+ nWidth += nTmpWidth;
+ }
+ return uno::makeAny( nWidth );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::Areas( const uno::Any& item) throw (uno::RuntimeException)
+{
+ if ( !item.hasValue() )
+ return uno::makeAny( m_Areas );
+ return m_Areas->Item( item, uno::Any() );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::getArea( sal_Int32 nIndex ) throw( css::uno::RuntimeException )
+{
+ if ( !m_Areas.is() )
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No areas available")), uno::Reference< uno::XInterface >() );
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( ++nIndex ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange;
+}
+
+uno::Any
+ScVbaRange::Borders( const uno::Any& item ) throw( script::BasicErrorException, uno::RuntimeException )
+{
+ if ( !item.hasValue() )
+ return uno::makeAny( getBorders() );
+ return getBorders()->Item( item, uno::Any() );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::BorderAround( const css::uno::Any& LineStyle, const css::uno::Any& Weight,
+ const css::uno::Any& ColorIndex, const css::uno::Any& Color ) throw (css::uno::RuntimeException)
+{
+ sal_Int32 nCount = getBorders()->getCount();
+
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ const sal_Int32 nLineType = supportedIndexTable[i];
+ switch( nLineType )
+ {
+ case excel::XlBordersIndex::xlEdgeLeft:
+ case excel::XlBordersIndex::xlEdgeTop:
+ case excel::XlBordersIndex::xlEdgeBottom:
+ case excel::XlBordersIndex::xlEdgeRight:
+ {
+ uno::Reference< excel::XBorder > xBorder( m_Borders->Item( uno::makeAny( nLineType ), uno::Any() ), uno::UNO_QUERY_THROW );
+ if( LineStyle.hasValue() )
+ {
+ xBorder->setLineStyle( LineStyle );
+ }
+ if( Weight.hasValue() )
+ {
+ xBorder->setWeight( Weight );
+ }
+ if( ColorIndex.hasValue() )
+ {
+ xBorder->setColorIndex( ColorIndex );
+ }
+ if( Color.hasValue() )
+ {
+ xBorder->setColor( Color );
+ }
+ break;
+ }
+ case excel::XlBordersIndex::xlInsideVertical:
+ case excel::XlBordersIndex::xlInsideHorizontal:
+ case excel::XlBordersIndex::xlDiagonalDown:
+ case excel::XlBordersIndex::xlDiagonalUp:
+ break;
+ default:
+ return uno::makeAny( sal_False );
+ }
+ }
+ return uno::makeAny( sal_True );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getRowHeight() throw (uno::RuntimeException)
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getRowHeight();
+ }
+
+ // if any row's RowHeight in the
+ // range is different from any other then return NULL
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ sal_Int32 nStartRow = thisAddress.StartRow;
+ sal_Int32 nEndRow = thisAddress.EndRow;
+ USHORT nRowTwips = 0;
+ // #TODO probably possible to use the SfxItemSet ( and see if
+ // SFX_ITEM_DONTCARE is set ) to improve performance
+// #CHECKME looks like this is general behaviour not just row Range specific
+// if ( mbIsRows )
+ ScDocShell* pShell = getScDocShell();
+ if ( pShell )
+ {
+ for ( sal_Int32 nRow = nStartRow ; nRow <= nEndRow; ++nRow )
+ {
+ thisAddress.StartRow = nRow;
+ USHORT nCurTwips = pShell->GetDocument()->GetOriginalHeight( thisAddress.StartRow, thisAddress.Sheet );
+ if ( nRow == nStartRow )
+ nRowTwips = nCurTwips;
+ if ( nRowTwips != nCurTwips )
+ return aNULL();
+ }
+ }
+ double nHeight = lcl_Round2DecPlaces( lcl_TwipsToPoints( nRowTwips ) );
+ return uno::makeAny( nHeight );
+}
+
+void SAL_CALL
+ScVbaRange::setRowHeight( const uno::Any& _rowheight) throw (uno::RuntimeException)
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ for ( sal_Int32 index = 1; index != nLen; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(index) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setRowHeight( _rowheight );
+ }
+ return;
+ }
+ double nHeight = 0; // Incomming height is in points
+ _rowheight >>= nHeight;
+ nHeight = lcl_Round2DecPlaces( nHeight );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ USHORT nTwips = lcl_pointsToTwips( nHeight );
+
+ ScDocShell* pDocShell = getDocShellFromRange( mxRange );
+ ScDocFunc aFunc(*pDocShell);
+ SCCOLROW nRowArr[2];
+ nRowArr[0] = thisAddress.StartRow;
+ nRowArr[1] = thisAddress.EndRow;
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, thisAddress.Sheet, SC_SIZE_ORIGINAL,
+ nTwips, TRUE, TRUE );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getPageBreak() throw (uno::RuntimeException)
+{
+ sal_Int32 nPageBreak = excel::XlPageBreak::xlPageBreakNone;
+ ScDocShell* pShell = getDocShellFromRange( mxRange );
+ if ( pShell )
+ {
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ BOOL bColumn = FALSE;
+
+ if (thisAddress.StartRow==0)
+ bColumn = TRUE;
+
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ if ( xModel.is() )
+ {
+ ScDocument* pDoc = getDocumentFromRange( mxRange );
+
+ ScBreakType nBreak = BREAK_NONE;
+ if ( !bColumn )
+ nBreak = pDoc->HasRowBreak(thisAddress.StartRow, thisAddress.Sheet);
+ else
+ nBreak = pDoc->HasColBreak(thisAddress.StartColumn, thisAddress.Sheet);
+
+ if (nBreak & BREAK_PAGE)
+ nPageBreak = excel::XlPageBreak::xlPageBreakAutomatic;
+
+ if (nBreak & BREAK_MANUAL)
+ nPageBreak = excel::XlPageBreak::xlPageBreakManual;
+ }
+ }
+
+ return uno::makeAny( nPageBreak );
+}
+
+void SAL_CALL
+ScVbaRange::setPageBreak( const uno::Any& _pagebreak) throw (uno::RuntimeException)
+{
+ sal_Int32 nPageBreak = 0;
+ _pagebreak >>= nPageBreak;
+
+ ScDocShell* pShell = getDocShellFromRange( mxRange );
+ if ( pShell )
+ {
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ if ((thisAddress.StartColumn==0) && (thisAddress.StartRow==0))
+ return;
+ BOOL bColumn = FALSE;
+
+ if (thisAddress.StartRow==0)
+ bColumn = TRUE;
+
+ ScAddress aAddr( static_cast<SCCOL>(thisAddress.StartColumn), thisAddress.StartRow, thisAddress.Sheet );
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ if ( xModel.is() )
+ {
+ ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
+ if ( nPageBreak == excel::XlPageBreak::xlPageBreakManual )
+ pViewShell->InsertPageBreak( bColumn, TRUE, &aAddr);
+ else if ( nPageBreak == excel::XlPageBreak::xlPageBreakNone )
+ pViewShell->DeletePageBreak( bColumn, TRUE, &aAddr);
+ }
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getHeight() throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getHeight();
+ }
+
+ uno::Reference< table::XColumnRowRange > xColRowRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xColRowRange->getRows(), uno::UNO_QUERY_THROW );
+ sal_Int32 nElems = xIndexAccess->getCount();
+ double nHeight = 0;
+ for ( sal_Int32 index=0; index<nElems; ++index )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ nHeight += getCalcRowHeight(xAddressable->getRangeAddress() );
+ }
+ return uno::makeAny( nHeight );
+}
+
+awt::Point
+ScVbaRange::getPosition() throw ( uno::RuntimeException )
+{
+ awt::Point aPoint;
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( mxRange.is() )
+ xProps.set( mxRange, uno::UNO_QUERY_THROW );
+ else
+ xProps.set( mxRanges, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue(POSITION) >>= aPoint;
+ return aPoint;
+}
+uno::Any SAL_CALL
+ScVbaRange::getLeft() throw (uno::RuntimeException)
+{
+ // helperapi returns the first ranges left ( and top below )
+ if ( m_Areas->getCount() > 1 )
+ return getArea( 0 )->getLeft();
+ awt::Point aPoint = getPosition();
+ return uno::makeAny( lcl_hmmToPoints( aPoint.X ) );
+}
+
+
+uno::Any SAL_CALL
+ScVbaRange::getTop() throw (uno::RuntimeException)
+{
+ // helperapi returns the first ranges top
+ if ( m_Areas->getCount() > 1 )
+ return getArea( 0 )->getTop();
+ awt::Point aPoint= getPosition();
+ return uno::makeAny( lcl_hmmToPoints( aPoint.Y ) );
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaRange::getWorksheet() throw (uno::RuntimeException)
+{
+ // #TODO #FIXME parent should always be set up ( currently thats not
+ // the case )
+ uno::Reference< excel::XWorksheet > xSheet( getParent(), uno::UNO_QUERY );
+ if ( !xSheet.is() )
+ {
+ uno::Reference< table::XCellRange > xRange = mxRange;
+
+ if ( mxRanges.is() ) // assign xRange to first range
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ xRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ }
+ ScDocShell* pDocShell = getDocShellFromRange(xRange);
+ RangeHelper rHelper(xRange);
+ // parent should be Thisworkbook
+ xSheet.set( new ScVbaWorksheet( uno::Reference< XHelperInterface >(), mxContext,rHelper.getSpreadSheet(),pDocShell->GetModel()) );
+ }
+ return xSheet;
+}
+
+// #TODO remove this ugly application processing
+// Process an application Range request e.g. 'Range("a1,b2,a4:b6")
+uno::Reference< excel::XRange >
+ScVbaRange::ApplicationRange( const uno::Reference< uno::XComponentContext >& xContext, const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException)
+{
+ // Althought the documentation seems clear that Range without a
+ // qualifier then its a shortcut for ActiveSheet.Range
+ // however, similarly Application.Range is apparently also a
+ // shortcut for ActiveSheet.Range
+ // The is however a subtle behavioural difference I've come across
+ // wrt to named ranges.
+ // If a named range "test" exists { Sheet1!$A1 } and the active sheet
+ // is Sheet2 then the following will fail
+ // msgbox ActiveSheet.Range("test").Address ' failes
+ // msgbox WorkSheets("Sheet2").Range("test").Address
+ // but !!!
+ // msgbox Range("test").Address ' works
+ // msgbox Application.Range("test").Address ' works
+
+ // Single param Range
+ rtl::OUString sRangeName;
+ Cell1 >>= sRangeName;
+ if ( Cell1.hasValue() && !Cell2.hasValue() && sRangeName.getLength() )
+ {
+ const static rtl::OUString sNamedRanges( RTL_CONSTASCII_USTRINGPARAM("NamedRanges"));
+ uno::Reference< beans::XPropertySet > xPropSet( getCurrentExcelDoc(xContext), uno::UNO_QUERY_THROW );
+
+ uno::Reference< container::XNameAccess > xNamed( xPropSet->getPropertyValue( sNamedRanges ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeReferrer > xReferrer;
+ try
+ {
+ xReferrer.set ( xNamed->getByName( sRangeName ), uno::UNO_QUERY );
+ }
+ catch( uno::Exception& /*e*/ )
+ {
+ // do nothing
+ }
+ if ( xReferrer.is() )
+ {
+ uno::Reference< table::XCellRange > xRange = xReferrer->getReferredCells();
+ if ( xRange.is() )
+ {
+ uno::Reference< excel::XRange > xVbRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), xContext, xRange );
+ return xVbRange;
+ }
+ }
+ }
+ uno::Reference< sheet::XSpreadsheetView > xView( getCurrentExcelDoc(xContext)->getCurrentController(), uno::UNO_QUERY );
+ uno::Reference< table::XCellRange > xSheetRange( xView->getActiveSheet(), uno::UNO_QUERY_THROW );
+ ScVbaRange* pRange = new ScVbaRange( excel::getUnoSheetModuleObj( xSheetRange ), xContext, xSheetRange );
+ uno::Reference< excel::XRange > xVbSheetRange( pRange );
+ return pRange->Range( Cell1, Cell2, true );
+}
+
+uno::Reference< sheet::XDatabaseRanges >
+lcl_GetDataBaseRanges( ScDocShell* pShell ) throw ( uno::RuntimeException )
+{
+ uno::Reference< frame::XModel > xModel;
+ if ( pShell )
+ xModel.set( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xModelProps( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XDatabaseRanges > xDBRanges( xModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DatabaseRanges") ) ), uno::UNO_QUERY_THROW );
+ return xDBRanges;
+}
+// returns the XDatabaseRange for the autofilter on sheet (nSheet)
+// also populates sName with the name of range
+uno::Reference< sheet::XDatabaseRange >
+lcl_GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet, rtl::OUString& sName )
+{
+ uno::Reference< container::XIndexAccess > xIndexAccess( lcl_GetDataBaseRanges( pShell ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XDatabaseRange > xDataBaseRange;
+ table::CellRangeAddress dbAddress;
+ for ( sal_Int32 index=0; index < xIndexAccess->getCount(); ++index )
+ {
+ uno::Reference< sheet::XDatabaseRange > xDBRange( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNamed > xNamed( xDBRange, uno::UNO_QUERY_THROW );
+ // autofilters work weirdly with openoffice, unnamed is the default
+ // named range which is used to create an autofilter, but
+ // its also possible that another name could be used
+ // this also causes problems when an autofilter is created on
+ // another sheet
+ // ( but.. you can use any named range )
+ dbAddress = xDBRange->getDataArea();
+ if ( dbAddress.Sheet == nSheet )
+ {
+ sal_Bool bHasAuto = sal_False;
+ uno::Reference< beans::XPropertySet > xProps( xDBRange, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ) ) >>= bHasAuto;
+ if ( bHasAuto )
+ {
+ sName = xNamed->getName();
+ xDataBaseRange=xDBRange;
+ break;
+ }
+ }
+ }
+ return xDataBaseRange;
+}
+
+// Helper functions for AutoFilter
+ScDBData* lcl_GetDBData_Impl( ScDocShell* pDocShell, sal_Int16 nSheet )
+{
+ rtl::OUString sName;
+ lcl_GetAutoFiltRange( pDocShell, nSheet, sName );
+ OSL_TRACE("lcl_GetDBData_Impl got autofilter range %s for sheet %d",
+ rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr() , nSheet );
+ ScDBData* pRet = NULL;
+ if (pDocShell)
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames)
+ {
+ USHORT nPos = 0;
+ if (pNames->SearchName( sName , nPos ))
+ pRet = (*pNames)[nPos];
+ }
+ }
+ return pRet;
+}
+
+void lcl_SelectAll( ScDocShell* pDocShell, ScQueryParam& aParam )
+{
+ if ( pDocShell )
+ {
+ ScViewData* pViewData = pDocShell->GetViewData();
+ if ( pViewData )
+ {
+ OSL_TRACE("Pushing out SelectAll query");
+ pViewData->GetView()->Query( aParam, NULL, TRUE );
+ }
+ }
+}
+
+ScQueryParam lcl_GetQueryParam( ScDocShell* pDocShell, sal_Int16 nSheet )
+{
+ ScDBData* pDBData = lcl_GetDBData_Impl( pDocShell, nSheet );
+ ScQueryParam aParam;
+ if (pDBData)
+ {
+ pDBData->GetQueryParam( aParam );
+ }
+ return aParam;
+}
+
+void lcl_SetAllQueryForField( ScQueryParam& aParam, SCCOLROW nField )
+{
+ bool bFound = false;
+ SCSIZE i = 0;
+ for (; i<MAXQUERY && !bFound; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if ( rEntry.nField == nField)
+ {
+ OSL_TRACE("found at pos %d", i );
+ bFound = true;
+ }
+ }
+ if ( bFound )
+ {
+ OSL_TRACE("field %d to delete at pos %d", nField, ( i - 1 ) );
+ aParam.DeleteQuery(--i);
+ }
+}
+
+
+void lcl_SetAllQueryForField( ScDocShell* pDocShell, SCCOLROW nField, sal_Int16 nSheet )
+{
+ ScQueryParam aParam = lcl_GetQueryParam( pDocShell, nSheet );
+ lcl_SetAllQueryForField( aParam, nField );
+ lcl_SelectAll( pDocShell, aParam );
+}
+
+// Modifies sCriteria, and nOp depending on the value of sCriteria
+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.
+ // right now I am more concerned with just getting it to work right
+
+ sCriteria1 = sCriteria1.trim();
+ // table of translation of criteria text to FilterOperators
+ // <>searchtext - NOT_EQUAL
+ // =searchtext - EQUAL
+ // *searchtext - startwith
+ // <>*searchtext - doesn't startwith
+ // *searchtext* - contains
+ // <>*searchtext* - doesn't contain
+ // [>|>=|<=|...]searchtext for GREATER_value, GREATER_EQUAL_value etc.
+ sal_Int32 nPos = 0;
+ bool bIsNumeric = false;
+ if ( ( nPos = sCriteria1.indexOf( EQUALS ) ) == 0 )
+ {
+ if ( sCriteria1.getLength() == EQUALS.getLength() )
+ rFilterField.Operator = sheet::FilterOperator2::EMPTY;
+ else
+ {
+ rFilterField.Operator = sheet::FilterOperator2::EQUAL;
+ sCriteria1 = sCriteria1.copy( EQUALS.getLength() );
+ sCriteria1 = VBAToRegexp( sCriteria1 );
+ // UseRegularExpressions
+ if ( xDescProps.is() )
+ xDescProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseRegularExpressions" ) ), uno::Any( sal_True ) );
+ }
+
+ }
+ else if ( ( nPos = sCriteria1.indexOf( NOTEQUALS ) ) == 0 )
+ {
+ if ( sCriteria1.getLength() == NOTEQUALS.getLength() )
+ rFilterField.Operator = sheet::FilterOperator2::NOT_EMPTY;
+ else
+ {
+ rFilterField.Operator = sheet::FilterOperator2::NOT_EQUAL;
+ sCriteria1 = sCriteria1.copy( NOTEQUALS.getLength() );
+ sCriteria1 = VBAToRegexp( sCriteria1 );
+ // UseRegularExpressions
+ if ( xDescProps.is() )
+ xDescProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseRegularExpressions" ) ), uno::Any( sal_True ) );
+ }
+ }
+ else if ( ( nPos = sCriteria1.indexOf( GREATERTHAN ) ) == 0 )
+ {
+ bIsNumeric = true;
+ if ( ( nPos = sCriteria1.indexOf( GREATERTHANEQUALS ) ) == 0 )
+ {
+ sCriteria1 = sCriteria1.copy( GREATERTHANEQUALS.getLength() );
+ rFilterField.Operator = sheet::FilterOperator2::GREATER_EQUAL;
+ }
+ else
+ {
+ sCriteria1 = sCriteria1.copy( GREATERTHAN.getLength() );
+ rFilterField.Operator = sheet::FilterOperator2::GREATER;
+ }
+
+ }
+ else if ( ( nPos = sCriteria1.indexOf( LESSTHAN ) ) == 0 )
+ {
+ bIsNumeric = true;
+ if ( ( nPos = sCriteria1.indexOf( LESSTHANEQUALS ) ) == 0 )
+ {
+ sCriteria1 = sCriteria1.copy( LESSTHANEQUALS.getLength() );
+ rFilterField.Operator = sheet::FilterOperator2::LESS_EQUAL;
+ }
+ else
+ {
+ sCriteria1 = sCriteria1.copy( LESSTHAN.getLength() );
+ rFilterField.Operator = sheet::FilterOperator2::LESS;
+ }
+
+ }
+ else
+ rFilterField.Operator = sheet::FilterOperator2::EQUAL;
+
+ if ( bIsNumeric )
+ {
+ rFilterField.IsNumeric= sal_True;
+ rFilterField.NumericValue = sCriteria1.toDouble();
+ }
+ rFilterField.StringValue = sCriteria1;
+}
+
+void SAL_CALL
+ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const uno::Any& Operator, const uno::Any& Criteria2, const uno::Any& VisibleDropDown ) throw (uno::RuntimeException)
+{
+ // Is there an existing autofilter
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ sal_Int16 nSheet = thisAddress.Sheet;
+ ScDocShell* pShell = getScDocShell();
+ sal_Bool bHasAuto = sal_False;
+ rtl::OUString sAutofiltRangeName;
+ uno::Reference< sheet::XDatabaseRange > xDataBaseRange = lcl_GetAutoFiltRange( pShell, nSheet, sAutofiltRangeName );
+ if ( xDataBaseRange.is() )
+ bHasAuto = true;
+
+ uno::Reference< table::XCellRange > xFilterRange;
+ if ( !bHasAuto )
+ {
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY, uno::Reference< uno::XInterface >() );
+
+ table::CellRangeAddress autoFiltAddress;
+ //CurrentRegion()
+ if ( isSingleCellRange() )
+ {
+ uno::Reference< excel::XRange > xCurrent( CurrentRegion() );
+ if ( xCurrent.is() )
+ {
+ ScVbaRange* pRange = getImplementation( xCurrent );
+ if ( pRange->isSingleCellRange() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create AutoFilter") ), uno::Reference< uno::XInterface >() );
+ if ( pRange )
+ {
+ RangeHelper currentRegion( pRange->mxRange );
+ autoFiltAddress = currentRegion.getCellRangeAddressable()->getRangeAddress();
+ }
+ }
+ }
+ else // multi-cell range
+ {
+ RangeHelper multiCellRange( mxRange );
+ autoFiltAddress = multiCellRange.getCellRangeAddressable()->getRangeAddress();
+ }
+
+ uno::Reference< sheet::XDatabaseRanges > xDBRanges = lcl_GetDataBaseRanges( pShell );
+ if ( xDBRanges.is() )
+ {
+ rtl::OUString sGenName( RTL_CONSTASCII_USTRINGPARAM("VBA_Autofilter_") );
+ sGenName += rtl::OUString::valueOf( static_cast< sal_Int32 >( nSheet ) );
+ OSL_TRACE("Going to add new autofilter range.. name %s",
+ rtl::OUStringToOString( sGenName, RTL_TEXTENCODING_UTF8 ).getStr() , nSheet );
+ if ( !xDBRanges->hasByName( sGenName ) )
+ xDBRanges->addNewByName( sGenName, autoFiltAddress );
+ xDataBaseRange.set( xDBRanges->getByName( sGenName ), uno::UNO_QUERY_THROW );
+ }
+ if ( !xDataBaseRange.is() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Failed to find the autofilter placeholder range" ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW );
+ // set autofilt
+ xDBRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ), uno::Any(sal_True) );
+ // set header
+ uno::Reference< beans::XPropertySet > xFiltProps( xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY_THROW );
+ sal_Bool bHasColHeader = sal_False;
+ ScDocument* pDoc = pShell ? pShell->GetDocument() : NULL;
+
+ bHasColHeader = pDoc->HasColHeader( static_cast< SCCOL >( autoFiltAddress.StartColumn ), static_cast< SCROW >( autoFiltAddress.StartRow ), static_cast< SCCOL >( autoFiltAddress.EndColumn ), static_cast< SCROW >( autoFiltAddress.EndRow ), static_cast< SCTAB >( autoFiltAddress.Sheet ) ) ? sal_True : sal_False;
+ xFiltProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ContainsHeader") ), uno::Any( bHasColHeader ) );
+ }
+
+
+ sal_Int32 nField = 0; // *IS* 1 based
+ rtl::OUString sCriteria1;
+ sal_Int32 nOperator = excel::XlAutoFilterOperator::xlAnd;
+
+ sal_Bool bVisible = sal_True;
+ bool bChangeDropDown = false;
+ VisibleDropDown >>= bVisible;
+
+ if ( bVisible == bHasAuto ) // dropdown is displayed/notdisplayed as
+ // required
+ bVisible = sal_False;
+ else
+ bChangeDropDown = true;
+ sheet::FilterConnection nConn = sheet::FilterConnection_AND;
+ double nCriteria1 = 0;
+
+ bool bHasCritValue = Criteria1.hasValue();
+ bool bCritHasNumericValue = sal_False; // not sure if a numeric criteria is possible
+ if ( bHasCritValue )
+ bCritHasNumericValue = ( Criteria1 >>= nCriteria1 );
+
+ if ( !Field.hasValue() && ( Criteria1.hasValue() || Operator.hasValue() || Criteria2.hasValue() ) )
+ throw uno::RuntimeException();
+ // Use the normal uno api, sometimes e.g. when you want to use ALL as the filter
+ // we can't use refresh as the uno interface doesn't have a concept of ALL
+ // in this case we just call the core calc functionality -
+ bool bAll = false;;
+ if ( ( Field >>= nField ) )
+ {
+ 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::FilterOperator2::EQUAL;// sensible default
+ if ( !bCritHasNumericValue )
+ {
+ Criteria1 >>= sCriteria1;
+ sTabFilts[0].IsNumeric = bCritHasNumericValue;
+ if ( bHasCritValue && sCriteria1.getLength() )
+ lcl_setTableFieldsFromCriteria( sCriteria1, xDescProps, sTabFilts[0] );
+ else
+ bAll = true;
+ }
+ else // numeric
+ {
+ sTabFilts[0].IsNumeric = sal_True;
+ sTabFilts[0].NumericValue = nCriteria1;
+ }
+ }
+ else // no value specified
+ bAll = true;
+ // not sure what the relationship between Criteria1 and Operator is,
+ // e.g. can you have a Operator without a Criteria ? in openoffice it
+ if ( Operator.hasValue() && ( Operator >>= nOperator ) )
+ {
+ // if its a bottom/top Ten(Percent/Value) and there
+ // is no value specified for critera1 set it to 10
+ if ( !bCritHasNumericValue && !sCriteria1.getLength() && ( nOperator != excel::XlAutoFilterOperator::xlOr ) && ( nOperator != excel::XlAutoFilterOperator::xlAnd ) )
+ {
+ sTabFilts[0].IsNumeric = sal_True;
+ sTabFilts[0].NumericValue = 10;
+ bAll = false;
+ }
+ switch ( nOperator )
+ {
+ case excel::XlAutoFilterOperator::xlBottom10Items:
+ sTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_VALUES;
+ break;
+ case excel::XlAutoFilterOperator::xlBottom10Percent:
+ sTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_PERCENT;
+ break;
+ case excel::XlAutoFilterOperator::xlTop10Items:
+ sTabFilts[0].Operator = sheet::FilterOperator2::TOP_VALUES;
+ break;
+ case excel::XlAutoFilterOperator::xlTop10Percent:
+ sTabFilts[0].Operator = sheet::FilterOperator2::TOP_PERCENT;
+ break;
+ case excel::XlAutoFilterOperator::xlOr:
+ nConn = sheet::FilterConnection_OR;
+ break;
+ case excel::XlAutoFilterOperator::xlAnd:
+ nConn = sheet::FilterConnection_AND;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UnknownOption") ), uno::Reference< uno::XInterface >() );
+
+ }
+
+ }
+ if ( !bAll )
+ {
+ sTabFilts[0].Connection = sheet::FilterConnection_AND;
+ sTabFilts[0].Field = (nField - 1);
+
+ rtl::OUString sCriteria2;
+ if ( Criteria2.hasValue() ) // there is a Criteria2
+ {
+ sTabFilts.realloc(2);
+ sTabFilts[1].Field = sTabFilts[0].Field;
+ sTabFilts[1].Connection = nConn;
+
+ if ( Criteria2 >>= sCriteria2 )
+ {
+ if ( sCriteria2.getLength() > 0 )
+ {
+ uno::Reference< beans::XPropertySet > xProps;
+ lcl_setTableFieldsFromCriteria( sCriteria2, xProps, sTabFilts[1] );
+ sTabFilts[1].IsNumeric = sal_False;
+ }
+ }
+ else // numeric
+ {
+ Criteria2 >>= sTabFilts[1].NumericValue;
+ sTabFilts[1].IsNumeric = sal_True;
+ sTabFilts[1].Operator = sheet::FilterOperator2::EQUAL;
+ }
+ }
+ }
+
+ xDesc->setFilterFields2( sTabFilts );
+ if ( !bAll )
+ {
+ xDataBaseRange->refresh();
+ }
+ else
+ // was 0 based now seems to be 1
+ lcl_SetAllQueryForField( pShell, nField, nSheet );
+ }
+ }
+ else
+ {
+ // this is just to toggle autofilter on and off ( not to be confused with
+ // a VisibleDropDown option combined with a field, in that case just the
+ // button should be disabled ) - currently we don't support that
+ bChangeDropDown = true;
+ uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW );
+ if ( bHasAuto )
+ {
+ // find the any field with the query and select all
+ ScQueryParam aParam = lcl_GetQueryParam( pShell, nSheet );
+ SCSIZE i = 0;
+ for (; i<MAXQUERY; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if ( rEntry.bDoQuery )
+ lcl_SetAllQueryForField( pShell, rEntry.nField, nSheet );
+ }
+ // remove exising filters
+ 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) );
+
+ }
+}
+
+void SAL_CALL
+ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (uno::RuntimeException)
+{
+ sal_Bool bCopyOrigin = sal_True;
+ CopyOrigin >>= bCopyOrigin;
+ // It appears ( from the web ) that the undocumented CopyOrigin
+ // param should contain member of enum XlInsertFormatOrigin
+ // which can have values xlFormatFromLeftOrAbove or xlFormatFromRightOrBelow
+ // #TODO investigate resultant behaviour using these constants
+ // currently just processing Shift
+
+ sheet::CellInsertMode mode = sheet::CellInsertMode_NONE;
+ if ( Shift.hasValue() )
+ {
+ sal_Int32 nShift = 0;
+ Shift >>= nShift;
+ switch ( nShift )
+ {
+ case excel::XlInsertShiftDirection::xlShiftToRight:
+ mode = sheet::CellInsertMode_RIGHT;
+ break;
+ case excel::XlInsertShiftDirection::xlShiftDown:
+ mode = sheet::CellInsertMode_DOWN;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ("Illegal paramater ") ), uno::Reference< uno::XInterface >() );
+ }
+ }
+ else
+ {
+ if ( getRow() >= getColumn() )
+ mode = sheet::CellInsertMode_DOWN;
+ else
+ mode = sheet::CellInsertMode_RIGHT;
+ }
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xCellRangeMove->insertCells( thisAddress, mode );
+ if ( bCopyOrigin )
+ {
+ // After the insert ( this range ) actually has moved
+ ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getDocShellFromRange( mxRange ) , aRange ) );
+ uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( mxParent, mxContext, xRange, mbIsRows, mbIsColumns ) );
+ xVbaRange->PasteSpecial( uno::Any(), uno::Any(), uno::Any(), uno::Any() );
+ }
+}
+
+void SAL_CALL
+ScVbaRange::Autofit() throw (uno::RuntimeException)
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ for ( sal_Int32 index = 1; index != nLen; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(index) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Autofit();
+ }
+ return;
+ }
+ // if the range is a not a row or column range autofit will
+ // throw an error
+
+ if ( !( mbIsColumns || mbIsRows ) )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ ScDocShell* pDocShell = getDocShellFromRange( mxRange );
+ if ( pDocShell )
+ {
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ ScDocFunc aFunc(*pDocShell);
+ SCCOLROW nColArr[2];
+ nColArr[0] = thisAddress.StartColumn;
+ nColArr[1] = thisAddress.EndColumn;
+ BOOL bDirection = TRUE;
+ if ( mbIsRows )
+ {
+ bDirection = FALSE;
+ nColArr[0] = thisAddress.StartRow;
+ nColArr[1] = thisAddress.EndRow;
+ }
+ aFunc.SetWidthOrHeight( bDirection, 1, nColArr, thisAddress.Sheet, SC_SIZE_OPTIMAL,
+ 0, TRUE, TRUE );
+
+ }
+}
+
+/***************************************************************************************
+ * interface for text:
+ * com.sun.star.text.XText, com.sun.star.table.XCell, com.sun.star.container.XEnumerationAccess
+ * com.sun.star.text.XTextRange,
+ * the main problem is to recognize the numeric and date, which assosiate with DecimalSeparator, ThousandsSeparator,
+ * TrailingMinusNumbers and FieldInfo.
+***************************************************************************************/
+void SAL_CALL
+ScVbaRange::TextToColumns( const css::uno::Any& Destination, const css::uno::Any& DataType, const css::uno::Any& TextQualifier,
+ const css::uno::Any& ConsecutinveDelimiter, const css::uno::Any& Tab, const css::uno::Any& Semicolon, const css::uno::Any& Comma,
+ const css::uno::Any& Space, const css::uno::Any& Other, const css::uno::Any& OtherChar, const css::uno::Any& /*FieldInfo*/,
+ const css::uno::Any& DecimalSeparator, const css::uno::Any& ThousandsSeparator, const css::uno::Any& /*TrailingMinusNumbers*/ ) throw (css::uno::RuntimeException)
+{
+ uno::Reference< excel::XRange > xRange;
+ if( Destination.hasValue() )
+ {
+ if( !( Destination >>= xRange ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Destination parameter should be a range" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set range\n");
+ }
+ else
+ {
+ //set as current
+ xRange = this;
+ OSL_TRACE("set range as himself\n");
+ }
+
+ sal_Int16 xlTextParsingType = excel::XlTextParsingType::xlDelimited;
+ if ( DataType.hasValue() )
+ {
+ if( !( DataType >>= xlTextParsingType ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "DataType parameter should be a short" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set Datatype\n" );
+ }
+ sal_Bool bDilimited = ( xlTextParsingType == excel::XlTextParsingType::xlDelimited );
+
+ sal_Int16 xlTextQualifier = excel::XlTextQualifier::xlTextQualifierDoubleQuote;
+ if( TextQualifier.hasValue() )
+ {
+ if( !( TextQualifier >>= xlTextQualifier ))
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "TextQualifier parameter should be a short" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set TextQualifier\n");
+ }
+
+ sal_Bool bConsecutinveDelimiter = sal_False;
+ if( ConsecutinveDelimiter.hasValue() )
+ {
+ if( !( ConsecutinveDelimiter >>= bConsecutinveDelimiter ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "ConsecutinveDelimiter parameter should be a boolean" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set ConsecutinveDelimiter\n");
+ }
+
+ sal_Bool bTab = sal_False;
+ if( Tab.hasValue() && bDilimited )
+ {
+ if( !( Tab >>= bTab ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Tab parameter should be a boolean" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set Tab\n");
+ }
+
+ sal_Bool bSemicolon = sal_False;
+ if( Semicolon.hasValue() && bDilimited )
+ {
+ if( !( Semicolon >>= bSemicolon ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Semicolon parameter should be a boolean" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set Semicolon\n");
+ }
+ sal_Bool bComma = sal_False;
+ if( Comma.hasValue() && bDilimited )
+ {
+ if( !( Comma >>= bComma ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Comma parameter should be a boolean" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set Comma\n");
+ }
+ sal_Bool bSpace = sal_False;
+ if( Space.hasValue() && bDilimited )
+ {
+ if( !( Space >>= bSpace ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Space parameter should be a boolean" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set Space\n");
+ }
+ sal_Bool bOther = sal_False;
+ rtl::OUString sOtherChar;
+ if( Other.hasValue() && bDilimited )
+ {
+ if( Other >>= bOther )
+ {
+ if( OtherChar.hasValue() )
+ if( !( OtherChar >>= sOtherChar ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "OtherChar parameter should be a String" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set OtherChar\n" );
+ }
+ else if( bOther )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "Other parameter should be a True" ),
+ uno::Reference< uno::XInterface >() );
+ }
+ //TODO* FieldInfo Optional Variant. An array containing parse information for the individual columns of data. The interpretation depends on the value of DataType. When the data is delimited, this argument is an array of two-element arrays, with each two-element array specifying the conversion options for a particular column. The first element is the column number (1-based), and the second element is one of the xlColumnDataType constants specifying how the column is parsed.
+
+ rtl::OUString sDecimalSeparator;
+ if( DecimalSeparator.hasValue() )
+ {
+ if( !( DecimalSeparator >>= sDecimalSeparator ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "DecimalSeparator parameter should be a String" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set DecimalSeparator\n" );
+ }
+ rtl::OUString sThousandsSeparator;
+ if( ThousandsSeparator.hasValue() )
+ {
+ if( !( ThousandsSeparator >>= sThousandsSeparator ) )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii( "ThousandsSeparator parameter should be a String" ),
+ uno::Reference< uno::XInterface >() );
+ OSL_TRACE("set ThousandsSpeparator\n" );
+ }
+ //TODO* TrailingMinusNumbers Optional Variant. Numbers that begin with a minus character.
+}
+
+uno::Any SAL_CALL
+ScVbaRange::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ /* The range object always returns a new Hyperlinks object containing a
+ fixed list of existing hyperlinks in the range.
+ See vbahyperlinks.hxx for more details. */
+
+ // get the global hyperlink object of the sheet (sheet should always be the parent of a Range object)
+ uno::Reference< excel::XWorksheet > xWorksheet( getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XHyperlinks > xSheetHlinks( xWorksheet->Hyperlinks( uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaHyperlinksRef xScSheetHlinks( dynamic_cast< ScVbaHyperlinks* >( xSheetHlinks.get() ) );
+ if( !xScSheetHlinks.is() )
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain hyperlinks implementation object" ) ), uno::Reference< uno::XInterface >() );
+
+ // create a new local hyperlinks object based on the sheet hyperlinks
+ ScVbaHyperlinksRef xHlinks( new ScVbaHyperlinks( getParent(), mxContext, xScSheetHlinks, getScRangeList() ) );
+ if( aIndex.hasValue() )
+ return xHlinks->Item( aIndex, uno::Any() );
+ return uno::Any( uno::Reference< excel::XHyperlinks >( xHlinks.get() ) );
+}
+
+css::uno::Reference< excel::XValidation > SAL_CALL
+ScVbaRange::getValidation() throw (css::uno::RuntimeException)
+{
+ if ( !m_xValidation.is() )
+ m_xValidation = new ScVbaValidation( this, mxContext, mxRange );
+ return m_xValidation;
+}
+
+namespace {
+
+sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCell >& rxCell ) throw (uno::RuntimeException)
+{
+ /* TODO/FIXME: We need an apostroph-prefix property at the cell to
+ implement this correctly. For now, return an apostroph for every text
+ cell.
+
+ TODO/FIXME: When Application.TransitionNavigKeys is supported and true,
+ this function needs to inspect the cell formatting and return different
+ prefixes according to the horizontal cell alignment.
+ */
+ return (rxCell->getType() == table::CellContentType_TEXT) ? '\'' : 0;
+}
+
+sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCellRange >& rxRange ) throw (uno::RuntimeException)
+{
+ /* This implementation is able to handle different prefixes (needed if
+ Application.TransitionNavigKeys is true). The function lclGetPrefixChar
+ for single cells called from here may return any prefix. If that
+ function returns an empty prefix (NUL character) or different non-empty
+ prefixes for two cells, this function returns 0.
+ */
+ sal_Unicode cCurrPrefix = 0;
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxRange );
+ sal_Int32 nEndCol = aRangeAddr.EndColumn - aRangeAddr.StartColumn;
+ sal_Int32 nEndRow = aRangeAddr.EndRow - aRangeAddr.StartRow;
+ for( sal_Int32 nRow = 0; nRow <= nEndRow; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol <= nEndCol; ++nCol )
+ {
+ uno::Reference< table::XCell > xCell( rxRange->getCellByPosition( nCol, nRow ), uno::UNO_SET_THROW );
+ sal_Unicode cNewPrefix = lclGetPrefixChar( xCell );
+ if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) )
+ return 0;
+ cCurrPrefix = cNewPrefix;
+ }
+ }
+ // all cells contain the same prefix - return it
+ return cCurrPrefix;
+}
+
+sal_Unicode lclGetPrefixChar( const uno::Reference< sheet::XSheetCellRangeContainer >& rxRanges ) throw (uno::RuntimeException)
+{
+ sal_Unicode cCurrPrefix = 0;
+ uno::Reference< container::XEnumerationAccess > xRangesEA( rxRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > xRangesEnum( xRangesEA->createEnumeration(), uno::UNO_SET_THROW );
+ while( xRangesEnum->hasMoreElements() )
+ {
+ uno::Reference< table::XCellRange > xRange( xRangesEnum->nextElement(), uno::UNO_QUERY_THROW );
+ sal_Unicode cNewPrefix = lclGetPrefixChar( xRange );
+ if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) )
+ return 0;
+ cCurrPrefix = cNewPrefix;
+ }
+ // all ranges contain the same prefix - return it
+ return cCurrPrefix;
+}
+
+inline uno::Any lclGetPrefixVariant( sal_Unicode cPrefixChar )
+{
+ return uno::Any( (cPrefixChar == 0) ? ::rtl::OUString() : ::rtl::OUString( cPrefixChar ) );
+}
+
+} // namespace
+
+uno::Any SAL_CALL ScVbaRange::getPrefixCharacter() throw (uno::RuntimeException)
+{
+ /* (1) If Application.TransitionNavigKeys is false, this function returns
+ an apostroph character if the text cell begins with an apostroph
+ character (formula return values are not taken into account); otherwise
+ an empty string.
+
+ (2) If Application.TransitionNavigKeys is true, this function returns
+ an apostroph character, if the cell is left-aligned; a double-quote
+ character, if the cell is right-aligned; a circumflex character, if the
+ cell is centered; a backslash character, if the cell is set to filled;
+ or an empty string, if nothing of the above.
+
+ If a range or a list of ranges contains texts with leading apostroph
+ character as well as other cells, this function returns an empty
+ string.
+ */
+
+ if( mxRange.is() )
+ return lclGetPrefixVariant( lclGetPrefixChar( mxRange ) );
+ if( mxRanges.is() )
+ return lclGetPrefixVariant( lclGetPrefixChar( mxRanges ) );
+ throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected empty Range object" ) ), uno::Reference< uno::XInterface >() );
+}
+
+uno::Any ScVbaRange::getShowDetail() throw ( css::uno::RuntimeException)
+{
+ // #FIXME, If the specified range is in a PivotTable report
+
+ // In MSO VBA, the specified range must be a single summary column or row in an outline. otherwise throw exception
+ if( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not get Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
+
+ sal_Bool bShowDetail = sal_False;
+
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ table::CellRangeAddress aOutlineAddress = xCellRangeAddressable->getRangeAddress();
+
+ // check if the specified range is a single summary column or row.
+ table::CellRangeAddress thisAddress = helper.getCellRangeAddressable()->getRangeAddress();
+ if( (thisAddress.StartRow == thisAddress.EndRow && thisAddress.EndRow == aOutlineAddress.EndRow ) ||
+ (thisAddress.StartColumn == thisAddress.EndColumn && thisAddress.EndColumn == aOutlineAddress.EndColumn ))
+ {
+ sal_Bool bColumn =thisAddress.StartRow == thisAddress.EndRow ? sal_False:sal_True;
+ ScDocument* pDoc = getDocumentFromRange( mxRange );
+ ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(static_cast<SCTAB>(thisAddress.Sheet), sal_True);
+ const ScOutlineArray* pOutlineArray = bColumn ? pOutlineTable->GetColArray(): pOutlineTable->GetRowArray();
+ if( pOutlineArray )
+ {
+ SCCOLROW nPos = bColumn ? (SCCOLROW)(thisAddress.EndColumn-1):(SCCOLROW)(thisAddress.EndRow-1);
+ ScOutlineEntry* pEntry = pOutlineArray->GetEntryByPos( 0, nPos );
+ if( pEntry )
+ {
+ bShowDetail = !pEntry->IsHidden();
+ return uno::makeAny( bShowDetail );
+ }
+ }
+ }
+ else
+ {
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not set Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
+ }
+ return aNULL();
+}
+
+void ScVbaRange::setShowDetail(const uno::Any& aShowDetail) throw ( css::uno::RuntimeException)
+{
+ // #FIXME, If the specified range is in a PivotTable report
+
+ // In MSO VBA, the specified range must be a single summary column or row in an outline. otherwise throw exception
+ if( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not set Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
+
+ bool bShowDetail = extractBoolFromAny( aShowDetail );
+
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ table::CellRangeAddress aOutlineAddress = xCellRangeAddressable->getRangeAddress();
+
+ // check if the specified range is a single summary column or row.
+ table::CellRangeAddress thisAddress = helper.getCellRangeAddressable()->getRangeAddress();
+ if( (thisAddress.StartRow == thisAddress.EndRow && thisAddress.EndRow == aOutlineAddress.EndRow ) ||
+ (thisAddress.StartColumn == thisAddress.EndColumn && thisAddress.EndColumn == aOutlineAddress.EndColumn ))
+ {
+ // #FIXME, seems there is a different behavior between MSO and OOo.
+ // In OOo, the showDetail will show all the level entrys, while only show the first level entry in MSO
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( helper.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ if( bShowDetail )
+ xSheetOutline->showDetail( aOutlineAddress );
+ else
+ xSheetOutline->hideDetail( aOutlineAddress );
+ }
+ else
+ {
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not set Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
+ }
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::MergeArea() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCellRange > xMergeShellCellRange(mxRange->getCellRangeByPosition(0,0,0,0), uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xMergeSheetCursor(xMergeShellCellRange->getSpreadsheet()->createCursorByRange( xMergeShellCellRange ), uno::UNO_QUERY_THROW);
+ if( xMergeSheetCursor.is() )
+ {
+ xMergeSheetCursor->collapseToMergedArea();
+ uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress(xMergeSheetCursor, uno::UNO_QUERY_THROW);
+ if( xMergeCellAddress.is() )
+ {
+ table::CellRangeAddress aCellAddress = xMergeCellAddress->getRangeAddress();
+ if( aCellAddress.StartColumn ==0 && aCellAddress.EndColumn==0 &&
+ aCellAddress.StartRow==0 && aCellAddress.EndRow==0)
+ {
+ return new ScVbaRange( mxParent,mxContext,mxRange );
+ }
+ else
+ {
+ ScRange refRange( static_cast< SCCOL >( aCellAddress.StartColumn ), static_cast< SCROW >( aCellAddress.StartRow ), static_cast< SCTAB >( aCellAddress.Sheet ),
+ static_cast< SCCOL >( aCellAddress.EndColumn ), static_cast< SCROW >( aCellAddress.EndRow ), static_cast< SCTAB >( aCellAddress.Sheet ) );
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
+ return new ScVbaRange( mxParent, mxContext,xRange );
+ }
+ }
+ }
+ return new ScVbaRange( mxParent, mxContext, mxRange );
+}
+
+void SAL_CALL
+ScVbaRange::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& ActivePrinter, const uno::Any& PrintToFile, const uno::Any& Collate, const uno::Any& PrToFileName ) throw (uno::RuntimeException)
+{
+ ScDocShell* pShell = NULL;
+
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Sequence< table::CellRangeAddress > printAreas( nItems );
+ uno::Reference< sheet::XPrintAreas > xPrintAreas;
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+
+ RangeHelper thisRange( xRange->getCellRange() );
+ table::CellRangeAddress rangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ if ( index == 1 )
+ {
+ ScVbaRange* pRange = getImplementation( xRange );
+ // initialise the doc shell and the printareas
+ pShell = getDocShellFromRange( pRange->mxRange );
+ xPrintAreas.set( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ }
+ printAreas[ index - 1 ] = rangeAddress;
+ }
+ if ( pShell )
+ {
+ if ( xPrintAreas.is() )
+ {
+ xPrintAreas->setPrintAreas( printAreas );
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, sal_True );
+ }
+ }
+}
+
+void SAL_CALL
+ScVbaRange::AutoFill( const uno::Reference< excel::XRange >& Destination, const uno::Any& Type ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XRange > xDest( Destination, uno::UNO_QUERY_THROW );
+ ScVbaRange* pRange = getImplementation( xDest );
+ RangeHelper destRangeHelper( pRange->mxRange );
+ table::CellRangeAddress destAddress = destRangeHelper.getCellRangeAddressable()->getRangeAddress();
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ ScRange sourceRange;
+ ScRange destRange;
+
+ ScUnoConversion::FillScRange( destRange, destAddress );
+ ScUnoConversion::FillScRange( sourceRange, thisAddress );
+
+
+ // source is valid
+// if ( !sourceRange.In( destRange ) )
+// throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "source not in destination" ) ), uno::Reference< uno::XInterface >() );
+
+ FillDir eDir = FILL_TO_BOTTOM;
+ double fStep = 1.0;
+
+ ScRange aRange( destRange );
+ ScRange aSourceRange( destRange );
+
+ // default to include the number of Rows in the source range;
+ SCCOLROW nSourceCount = ( sourceRange.aEnd.Row() - sourceRange.aStart.Row() ) + 1;
+ SCCOLROW nCount = 0;
+
+ if ( sourceRange != destRange )
+ {
+ // Find direction of fill, vertical or horizontal
+ if ( sourceRange.aStart == destRange.aStart )
+ {
+ if ( sourceRange.aEnd.Row() == destRange.aEnd.Row() )
+ {
+ nSourceCount = ( sourceRange.aEnd.Col() - sourceRange.aStart.Col() + 1 );
+ aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) );
+ eDir = FILL_TO_RIGHT;
+ nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col();
+ }
+ else if ( sourceRange.aEnd.Col() == destRange.aEnd.Col() )
+ {
+ aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount ) - 1 );
+ nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row();
+ eDir = FILL_TO_BOTTOM;
+ }
+ }
+
+ else if ( aSourceRange.aEnd == destRange.aEnd )
+ {
+ if ( sourceRange.aStart.Col() == destRange.aStart.Col() )
+ {
+ aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) );
+ nCount = aSourceRange.aStart.Row() - aRange.aStart.Row();
+ eDir = FILL_TO_TOP;
+ fStep = -fStep;
+ }
+ else if ( sourceRange.aStart.Row() == destRange.aStart.Row() )
+ {
+ nSourceCount = ( sourceRange.aEnd.Col() - sourceRange.aStart.Col() ) + 1;
+ aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) );
+ nCount = aSourceRange.aStart.Col() - aRange.aStart.Col();
+ eDir = FILL_TO_LEFT;
+ fStep = -fStep;
+ }
+ }
+ }
+ ScDocShell* pDocSh= getDocShellFromRange( mxRange );
+
+ FillCmd eCmd = FILL_AUTO;
+ FillDateCmd eDateCmd = FILL_DAY;
+
+#ifdef VBA_OOBUILD_HACK
+ double fEndValue = MAXDOUBLE;
+#endif
+
+ if ( Type.hasValue() )
+ {
+ sal_Int16 nFillType = excel::XlAutoFillType::xlFillDefault;
+ Type >>= nFillType;
+ switch ( nFillType )
+ {
+ case excel::XlAutoFillType::xlFillCopy:
+ eCmd = FILL_SIMPLE;
+ fStep = 0.0;
+ break;
+ case excel::XlAutoFillType::xlFillDays:
+ eCmd = FILL_DATE;
+ break;
+ case excel::XlAutoFillType::xlFillMonths:
+ eCmd = FILL_DATE;
+ eDateCmd = FILL_MONTH;
+ break;
+ case excel::XlAutoFillType::xlFillWeekdays:
+ eCmd = FILL_DATE;
+ eDateCmd = FILL_WEEKDAY;
+ break;
+ case excel::XlAutoFillType::xlFillYears:
+ eCmd = FILL_DATE;
+ eDateCmd = FILL_YEAR;
+ break;
+ case excel::XlAutoFillType::xlGrowthTrend:
+ eCmd = FILL_GROWTH;
+ break;
+ case excel::XlAutoFillType::xlFillFormats:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "xlFillFormat not supported for AutoFill" ) ), uno::Reference< uno::XInterface >() );
+ case excel::XlAutoFillType::xlFillValues:
+ case excel::XlAutoFillType::xlFillSeries:
+ case excel::XlAutoFillType::xlLinearTrend:
+ eCmd = FILL_LINEAR;
+ break;
+ case excel::XlAutoFillType::xlFillDefault:
+ default:
+ eCmd = FILL_AUTO;
+ break;
+ }
+ }
+ ScDocFunc aFunc(*pDocSh);
+#ifdef VBA_OOBUILD_HACK
+ aFunc.FillAuto( aSourceRange, NULL, eDir, eCmd, eDateCmd, nCount, fStep, fEndValue, TRUE, TRUE );
+#endif
+}
+sal_Bool SAL_CALL
+ScVbaRange::GoalSeek( const uno::Any& Goal, const uno::Reference< excel::XRange >& ChangingCell ) throw (uno::RuntimeException)
+{
+ ScDocShell* pDocShell = getScDocShell();
+ sal_Bool bRes = sal_True;
+ ScVbaRange* pRange = static_cast< ScVbaRange* >( ChangingCell.get() );
+ if ( pDocShell && pRange )
+ {
+ uno::Reference< sheet::XGoalSeek > xGoalSeek( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ RangeHelper changingCellRange( pRange->mxRange );
+ table::CellRangeAddress changingCellAddr = changingCellRange.getCellRangeAddressable()->getRangeAddress();
+ rtl::OUString sGoal = getAnyAsString( Goal );
+ table::CellAddress thisCell( thisAddress.Sheet, thisAddress.StartColumn, thisAddress.StartRow );
+ table::CellAddress changingCell( changingCellAddr.Sheet, changingCellAddr.StartColumn, changingCellAddr.StartRow );
+ sheet::GoalResult res = xGoalSeek->seekGoal( thisCell, changingCell, sGoal );
+ ChangingCell->setValue( uno::makeAny( res.Result ) );
+
+ // openoffice behaves differently, result is 0 if the divergence is too great
+ // but... if it detects 0 is the value it requires then it will use that
+ // e.g. divergence & result both = 0.0 does NOT mean there is an error
+ if ( ( res.Divergence != 0.0 ) && ( res.Result == 0.0 ) )
+ bRes = sal_False;
+ }
+ else
+ bRes = sal_False;
+ return bRes;
+}
+
+void
+ScVbaRange::Calculate( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ getWorksheet()->Calculate();
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Item( const uno::Any& row, const uno::Any& column ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( mbIsRows || mbIsColumns )
+ {
+ if ( column.hasValue() )
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ uno::Reference< excel::XRange > xRange;
+ if ( mbIsColumns )
+ xRange = Columns( row );
+ else
+ xRange = Rows( row );
+ return xRange;
+ }
+ return Cells( row, column );
+}
+
+void
+ScVbaRange::AutoOutline( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ // #TODO #FIXME needs to check for summary row/col ( whatever they are )
+ // not valid for multi Area Addresses
+ if ( m_Areas->getCount() > 1 )
+ DebugHelper::exception(SbERR_METHOD_FAILED, STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY);
+ // So needs to either span an entire Row or a just be a single cell
+ // ( that contains a summary RowColumn )
+ // also the Single cell cause doesn't seem to be handled specially in
+ // this code ( ported from the helperapi RangeImpl.java,
+ // RangeRowsImpl.java, RangesImpl.java, RangeSingleCellImpl.java
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ if ( isSingleCellRange() || mbIsRows )
+ {
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xSheetOutline->autoOutline( thisAddress );
+ }
+ else
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+}
+
+void SAL_CALL
+ScVbaRange:: ClearOutline( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->ClearOutline();
+ }
+ return;
+ }
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xSheetOutline->clearOutline();
+}
+
+void
+ScVbaRange::groupUnGroup( bool bUnGroup ) throw ( script::BasicErrorException, uno::RuntimeException )
+{
+ if ( m_Areas->getCount() > 1 )
+ DebugHelper::exception(SbERR_METHOD_FAILED, STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY);
+ table::TableOrientation nOrient = table::TableOrientation_ROWS;
+ if ( mbIsColumns )
+ nOrient = table::TableOrientation_COLUMNS;
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ if ( bUnGroup )
+ xSheetOutline->ungroup( thisAddress, nOrient );
+ else
+ xSheetOutline->group( thisAddress, nOrient );
+}
+
+void SAL_CALL
+ScVbaRange::Group( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ groupUnGroup();
+}
+void SAL_CALL
+ScVbaRange::Ungroup( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ groupUnGroup(true);
+}
+
+void lcl_mergeCellsOfRange( const uno::Reference< table::XCellRange >& xCellRange, sal_Bool _bMerge = sal_True ) throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XMergeable > xMergeable( xCellRange, uno::UNO_QUERY_THROW );
+ xMergeable->merge(_bMerge);
+}
+void SAL_CALL
+ScVbaRange::Merge( const uno::Any& Across ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Merge(Across);
+ }
+ return;
+ }
+ uno::Reference< table::XCellRange > oCellRange;
+ sal_Bool bAcross = sal_False;
+ Across >>= bAcross;
+ if ( !bAcross )
+ lcl_mergeCellsOfRange( mxRange );
+ else
+ {
+ uno::Reference< excel::XRange > oRangeRowsImpl = Rows( uno::Any() );
+ // #TODO #FIXME this seems incredibly lame, this can't be right
+ for (sal_Int32 i=1; i <= oRangeRowsImpl->getCount();i++)
+ {
+ oRangeRowsImpl->Cells( uno::makeAny( i ), uno::Any() )->Merge( uno::makeAny( sal_False ) );
+ }
+ }
+}
+
+void SAL_CALL
+ScVbaRange::UnMerge( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->UnMerge();
+ }
+ return;
+ }
+ lcl_mergeCellsOfRange( mxRange, sal_False);
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getStyle() throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getStyle();
+ }
+ uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
+ rtl::OUString sStyleName;
+ xProps->getPropertyValue(CELLSTYLE) >>= sStyleName;
+ ScDocShell* pShell = getScDocShell();
+ uno::Reference< frame::XModel > xModel( pShell->GetModel() );
+ uno::Reference< excel::XStyle > xStyle = new ScVbaStyle( this, mxContext, sStyleName, xModel );
+ return uno::makeAny( xStyle );
+}
+void SAL_CALL
+ScVbaRange::setStyle( const uno::Any& _style ) throw (uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setStyle( _style );
+ return;
+ }
+ uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XStyle > xStyle;
+ _style >>= xStyle;
+ xProps->setPropertyValue(CELLSTYLE, uno::makeAny(xStyle->getName()));
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::PreviousNext( bool bIsPrevious )
+{
+ ScMarkData markedRange;
+ ScRange refRange;
+ RangeHelper thisRange( mxRange );
+
+ ScUnoConversion::FillScRange( refRange, thisRange.getCellRangeAddressable()->getRangeAddress());
+ markedRange. SetMarkArea( refRange );
+ short nMove = bIsPrevious ? -1 : 1;
+
+ SCCOL nNewX = refRange.aStart.Col();
+ SCROW nNewY = refRange.aStart.Row();
+ SCTAB nTab = refRange.aStart.Tab();
+
+ ScDocument* pDoc = getScDocument();
+ pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, TRUE,TRUE, markedRange );
+ refRange.aStart.SetCol( nNewX );
+ refRange.aStart.SetRow( nNewY );
+ refRange.aStart.SetTab( nTab );
+ refRange.aEnd.SetCol( nNewX );
+ refRange.aEnd.SetRow( nNewY );
+ refRange.aEnd.SetTab( nTab );
+
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
+
+ return new ScVbaRange( mxParent, mxContext, xRange );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Next() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ) , uno::UNO_QUERY_THROW );
+ return xRange->Next();
+ }
+ return PreviousNext( false );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Previous() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->Previous();
+ }
+ return PreviousNext( true );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw ( script::BasicErrorException )
+{
+ bool bIsSingleCell = isSingleCellRange();
+ bool bIsMultiArea = ( m_Areas->getCount() > 1 );
+ ScVbaRange* pRangeToUse = this;
+ sal_Int32 nType = 0;
+ if ( !( _oType >>= nType ) )
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ switch(nType)
+ {
+ case excel::XlCellType::xlCellTypeSameFormatConditions:
+ case excel::XlCellType::xlCellTypeAllValidation:
+ case excel::XlCellType::xlCellTypeSameValidation:
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ break;
+ case excel::XlCellType::xlCellTypeBlanks:
+ case excel::XlCellType::xlCellTypeComments:
+ case excel::XlCellType::xlCellTypeConstants:
+ case excel::XlCellType::xlCellTypeFormulas:
+ case excel::XlCellType::xlCellTypeVisible:
+ case excel::XlCellType::xlCellTypeLastCell:
+ {
+ if ( bIsMultiArea )
+ {
+ // need to process each area, gather the results and
+ // create a new range from those
+ std::vector< table::CellRangeAddress > rangeResults;
+ sal_Int32 nItems = ( m_Areas->getCount() + 1 );
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange = xRange->SpecialCells( _oType, _oValue);
+ ScVbaRange* pRange = getImplementation( xRange );
+ if ( xRange.is() && pRange )
+ {
+ sal_Int32 nElems = ( pRange->m_Areas->getCount() + 1 );
+ for ( sal_Int32 nArea = 1; nArea < nElems; ++nArea )
+ {
+ uno::Reference< excel::XRange > xTmpRange( m_Areas->Item( uno::makeAny( nArea ), uno::Any() ), uno::UNO_QUERY_THROW );
+ RangeHelper rHelper( xTmpRange->getCellRange() );
+ rangeResults.push_back( rHelper.getCellRangeAddressable()->getRangeAddress() );
+ }
+ }
+ }
+ ScRangeList aCellRanges;
+ std::vector< table::CellRangeAddress >::iterator it = rangeResults.begin();
+ std::vector< table::CellRangeAddress >::iterator it_end = rangeResults.end();
+ for ( ; it != it_end; ++ it )
+ {
+ ScRange refRange;
+ ScUnoConversion::FillScRange( refRange, *it );
+ aCellRanges.Append( refRange );
+ }
+ // Single range
+ if ( aCellRanges.First() == aCellRanges.Last() )
+ {
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell(), *aCellRanges.First() ) );
+ return new ScVbaRange( mxParent, mxContext, xRange );
+ }
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( getScDocShell(), aCellRanges ) );
+
+ return new ScVbaRange( mxParent, mxContext, xRanges );
+ }
+ else if ( bIsSingleCell )
+ {
+ uno::Reference< excel::XRange > xUsedRange = getWorksheet()->getUsedRange();
+ pRangeToUse = static_cast< ScVbaRange* >( xUsedRange.get() );
+ }
+
+ break;
+ }
+ default:
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ break;
+ }
+ if ( !pRangeToUse )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ return pRangeToUse->SpecialCellsImpl( nType, _oValue );
+}
+
+sal_Int32 lcl_getFormulaResultFlags(const uno::Any& aType) throw ( script::BasicErrorException )
+{
+ sal_Int32 nType = excel::XlSpecialCellsValue::xlNumbers;
+ aType >>= nType;
+ sal_Int32 nRes = sheet::FormulaResult::VALUE;
+
+ switch(nType)
+ {
+ case excel::XlSpecialCellsValue::xlErrors:
+ nRes= sheet::FormulaResult::ERROR;
+ break;
+ case excel::XlSpecialCellsValue::xlLogical:
+ //TODO bc93774: ask NN if this is really an appropriate substitute
+ nRes = sheet::FormulaResult::VALUE;
+ break;
+ case excel::XlSpecialCellsValue::xlNumbers:
+ nRes = sheet::FormulaResult::VALUE;
+ break;
+ case excel::XlSpecialCellsValue::xlTextValues:
+ nRes = sheet::FormulaResult::STRING;
+ break;
+ default:
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+ return nRes;
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::SpecialCellsImpl( sal_Int32 nType, const uno::Any& _oValue) throw ( script::BasicErrorException )
+{
+ uno::Reference< excel::XRange > xRange;
+ try
+ {
+ uno::Reference< sheet::XCellRangesQuery > xQuery( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > oLocRangeImpl;
+ uno::Reference< sheet::XSheetCellRanges > xLocSheetCellRanges;
+ switch(nType)
+ {
+ case excel::XlCellType::xlCellTypeAllFormatConditions:
+ case excel::XlCellType::xlCellTypeSameFormatConditions:
+ case excel::XlCellType::xlCellTypeAllValidation:
+ case excel::XlCellType::xlCellTypeSameValidation:
+ // Shouldn't get here ( should be filtered out by
+ // ScVbaRange::SpecialCells()
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ break;
+ case excel::XlCellType::xlCellTypeBlanks:
+ xLocSheetCellRanges = xQuery->queryEmptyCells();
+ break;
+ case excel::XlCellType::xlCellTypeComments:
+ xLocSheetCellRanges = xQuery->queryContentCells(sheet::CellFlags::ANNOTATION);
+ break;
+ case excel::XlCellType::xlCellTypeConstants:
+ xLocSheetCellRanges = xQuery->queryContentCells(23);
+ break;
+ case excel::XlCellType::xlCellTypeFormulas:
+ {
+ sal_Int32 nFormulaResult = lcl_getFormulaResultFlags(_oValue);
+ xLocSheetCellRanges = xQuery->queryFormulaCells(nFormulaResult);
+ break;
+ }
+ case excel::XlCellType::xlCellTypeLastCell:
+ xRange = Cells( uno::makeAny( getCount() ), uno::Any() );
+ case excel::XlCellType::xlCellTypeVisible:
+ xLocSheetCellRanges = xQuery->queryVisibleCells();
+ break;
+ default:
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ break;
+ }
+ if (xLocSheetCellRanges.is())
+ {
+ xRange = lcl_makeXRangeFromSheetCellRanges( getParent(), mxContext, xLocSheetCellRanges, getScDocShell() );
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, STR_ERRORMESSAGE_NOCELLSWEREFOUND);
+ }
+ return xRange;
+}
+
+void SAL_CALL
+ScVbaRange::RemoveSubtotal( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< sheet::XSubTotalCalculatable > xSub( mxRange, uno::UNO_QUERY_THROW );
+ xSub->removeSubTotals();
+}
+
+void SAL_CALL
+ScVbaRange::Subtotal( ::sal_Int32 _nGroupBy, ::sal_Int32 _nFunction, const uno::Sequence< ::sal_Int32 >& _nTotalList, const uno::Any& aReplace, const uno::Any& PageBreaks, const uno::Any& /*SummaryBelowData*/ ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Bool bDoReplace = sal_False;
+ aReplace >>= bDoReplace;
+ sal_Bool bAddPageBreaks = sal_False;
+ PageBreaks >>= bAddPageBreaks;
+
+ uno::Reference< sheet::XSubTotalCalculatable> xSub(mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSubTotalDescriptor > xSubDesc = xSub->createSubTotalDescriptor(sal_True);
+ uno::Reference< beans::XPropertySet > xSubDescPropertySet( xSubDesc, uno::UNO_QUERY_THROW );
+ xSubDescPropertySet->setPropertyValue(INSERTPAGEBREAKS, uno::makeAny( bAddPageBreaks));
+ sal_Int32 nLen = _nTotalList.getLength();
+ uno::Sequence< sheet::SubTotalColumn > aColumns( nLen );
+ for (int i = 0; i < nLen; i++)
+ {
+ aColumns[i].Column = _nTotalList[i] - 1;
+ switch (_nFunction)
+ {
+ case excel::XlConsolidationFunction::xlAverage:
+ aColumns[i].Function = sheet::GeneralFunction_AVERAGE;
+ break;
+ case excel::XlConsolidationFunction::xlCount:
+ aColumns[i].Function = sheet::GeneralFunction_COUNT;
+ break;
+ case excel::XlConsolidationFunction::xlCountNums:
+ aColumns[i].Function = sheet::GeneralFunction_COUNTNUMS;
+ break;
+ case excel::XlConsolidationFunction::xlMax:
+ aColumns[i].Function = sheet::GeneralFunction_MAX;
+ break;
+ case excel::XlConsolidationFunction::xlMin:
+ aColumns[i].Function = sheet::GeneralFunction_MIN;
+ break;
+ case excel::XlConsolidationFunction::xlProduct:
+ aColumns[i].Function = sheet::GeneralFunction_PRODUCT;
+ break;
+ case excel::XlConsolidationFunction::xlStDev:
+ aColumns[i].Function = sheet::GeneralFunction_STDEV;
+ break;
+ case excel::XlConsolidationFunction::xlStDevP:
+ aColumns[i].Function = sheet::GeneralFunction_STDEVP;
+ break;
+ case excel::XlConsolidationFunction::xlSum:
+ aColumns[i].Function = sheet::GeneralFunction_SUM;
+ break;
+ case excel::XlConsolidationFunction::xlUnknown:
+ aColumns[i].Function = sheet::GeneralFunction_NONE;
+ break;
+ case excel::XlConsolidationFunction::xlVar:
+ aColumns[i].Function = sheet::GeneralFunction_VAR;
+ break;
+ case excel::XlConsolidationFunction::xlVarP:
+ aColumns[i].Function = sheet::GeneralFunction_VARP;
+ break;
+ default:
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString()) ;
+ return;
+ }
+ }
+ xSubDesc->addNew(aColumns, _nGroupBy - 1);
+ xSub->applySubTotals(xSubDesc, bDoReplace);
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+rtl::OUString&
+ScVbaRange::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaRange") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaRange::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Range" ) );
+ }
+ return aServiceNames;
+}
+
+namespace range
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaRange, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "SvVbaRange",
+ "ooo.vba.excel.Range" );
+}
diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx
new file mode 100644
index 000000000000..e7488e434f30
--- /dev/null
+++ b/sc/source/ui/vba/vbarange.hxx
@@ -0,0 +1,298 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_RANGE_HXX
+#define SC_VBA_RANGE_HXX
+
+#include <cppuhelper/implbase4.hxx>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <ooo/vba/excel/XFont.hpp>
+#include <ooo/vba/excel/XComment.hpp>
+#include <ooo/vba/XCollection.hpp>
+#include <ooo/vba/excel/XlPasteType.hdl>
+#include <ooo/vba/excel/XlPasteSpecialOperation.hdl>
+
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/script/XDefaultMethod.hpp>
+#include <com/sun/star/script/XDefaultProperty.hpp>
+#include <com/sun/star/sheet/FillDateMode.hpp>
+#include <com/sun/star/sheet/FillMode.hpp>
+#include <com/sun/star/sheet/FillDirection.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+
+//#include <vbahelper/vbahelperinterface.hxx>
+#include "vbaformat.hxx"
+#include <formula/grammar.hxx>
+
+class ScTableSheetsObj;
+class ScCellRangesBase;
+class ScCellRangeObj;
+class ScCellRangesObj;
+class ScDocShell;
+class ScDocument;
+class ScRangeList;
+
+//typedef InheritedHelperInterfaceImpl1< ov::excel::XRange > ScVbaRange_BASE;
+typedef ScVbaFormat< ov::excel::XRange > ScVbaRange_BASE;
+
+class ArrayVisitor
+{
+public:
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const css::uno::Reference< css::table::XCell >& xCell ) = 0;
+ virtual ~ArrayVisitor(){}
+};
+
+class ValueSetter : public ArrayVisitor
+{
+public:
+ virtual bool processValue( const css::uno::Any& aValue, const css::uno::Reference< css::table::XCell >& xCell ) = 0;
+
+
+};
+
+class ValueGetter : public ArrayVisitor
+{
+
+public:
+ virtual void processValue( sal_Int32 x, sal_Int32 y, const css::uno::Any& aValue ) = 0;
+ virtual const css::uno::Any& getValue() const = 0;
+};
+
+
+
+class ScVbaRange : public ScVbaRange_BASE
+{
+ css::uno::Reference< ov::XCollection > m_Areas;
+ css::uno::Reference< ov::XCollection > m_Borders;
+ css::uno::Reference< css::table::XCellRange > mxRange;
+ css::uno::Reference< css::sheet::XSheetCellRangeContainer > mxRanges;
+ sal_Bool mbIsRows;
+ sal_Bool mbIsColumns;
+ css::uno::Reference< ov::excel::XValidation > m_xValidation;
+ double getCalcColWidth( const css::table::CellRangeAddress& ) throw (css::uno::RuntimeException);
+ double getCalcRowHeight( const css::table::CellRangeAddress& ) throw (css::uno::RuntimeException);
+ void visitArray( ArrayVisitor& vistor );
+
+ css::uno::Reference< ov::excel::XRange > getEntireColumnOrRow( bool bColumn = true ) throw( css::uno::RuntimeException );
+
+ void fillSeries( css::sheet::FillDirection nFillDirection, css::sheet::FillMode nFillMode, css::sheet::FillDateMode nFillDateMode, double fStep, double fEndValue ) throw( css::uno::RuntimeException );
+
+ void ClearContents( sal_Int32 nFlags ) throw (css::uno::RuntimeException);
+ virtual void setValue( const css::uno::Any& aValue, ValueSetter& setter) throw ( css::uno::RuntimeException);
+ virtual css::uno::Any getValue( ValueGetter& rValueGetter ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any getFormulaValue( formula::FormulaGrammar::Grammar ) throw (css::uno::RuntimeException);
+ virtual void setFormulaValue( const css::uno::Any& aValue, formula::FormulaGrammar::Grammar ) throw ( css::uno::RuntimeException);
+ css::uno::Reference< ov::excel::XRange > getArea( sal_Int32 nIndex ) throw( css::uno::RuntimeException );
+ ScCellRangeObj* getCellRangeObj( ) throw ( css::uno::RuntimeException );
+ ScCellRangesObj* getCellRangesObj() throw ( css::uno::RuntimeException );
+ css::uno::Reference< ov::XCollection >& getBorders();
+ void groupUnGroup( bool bUnGroup = false ) throw ( css::script::BasicErrorException, css::uno::RuntimeException );
+ css::uno::Reference< ov::excel::XRange > PreviousNext( bool bIsPrevious );
+ css::uno::Reference< ov::excel::XRange > SpecialCellsImpl( sal_Int32 nType, const css::uno::Any& _oValue) throw ( css::script::BasicErrorException );
+ css::awt::Point getPosition() throw ( css::uno::RuntimeException );
+protected:
+ virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException );
+ virtual SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException );
+public:
+ ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException );
+ ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException );
+ ScVbaRange( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException );
+
+ ScDocument* getScDocument() throw (css::uno::RuntimeException);
+ ScDocShell* getScDocShell() throw (css::uno::RuntimeException);
+
+ /** Returns the ScVbaRange implementation object for the passed VBA Range object. */
+ static ScVbaRange* getImplementation( const css::uno::Reference< ov::excel::XRange >& rxRange );
+
+ css::uno::Reference< css::frame::XModel > getUnoModel() throw (css::uno::RuntimeException);
+ static css::uno::Reference< css::frame::XModel > getUnoModel( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException);
+
+ const ScRangeList& getScRangeList() throw (css::uno::RuntimeException);
+ static const ScRangeList& getScRangeList( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException);
+
+ virtual ~ScVbaRange();
+ virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() { return this; }
+ bool isSingleCellRange();
+
+ static css::uno::Reference< ov::excel::XRange > getRangeObjectForName(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const rtl::OUString& sRangeName, ScDocShell* pDocSh,
+ formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException );
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setValue( const css::uno::Any& aValue ) throw ( css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFormula() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFormula( const css::uno::Any& rFormula ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFormulaArray() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFormulaArray(const css::uno::Any& rFormula) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getFormulaR1C1() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFormulaR1C1( const css::uno::Any &rFormula ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getRow() throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getColumn() throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException);
+ using ScVbaRange_BASE::setNumberFormat;
+ virtual void SAL_CALL setNumberFormat( const css::uno::Any& rNumberFormat ) throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getNumberFormat() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& bMerge ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getMergeCells() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setWrapText( const css::uno::Any& bIsWrapped ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getWrapText() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getEntireRow() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getEntireColumn() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL getComment() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getHidden() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setHidden( const css::uno::Any& _hidden ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getColumnWidth() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setColumnWidth( const css::uno::Any& _columnwidth ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getRowHeight() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRowHeight( const css::uno::Any& _rowheight ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getWidth() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getHeight() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getTop() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getLeft() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getWorksheet() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getPageBreak() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPageBreak( const css::uno::Any& _pagebreak ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XValidation > SAL_CALL getValidation() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getPrefixCharacter() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getShowDetail() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setShowDetail(const css::uno::Any& aShowDetail) throw (css::uno::RuntimeException);
+ // Methods
+ sal_Bool IsRows() { return mbIsRows; }
+ sal_Bool IsColumns() { return mbIsColumns; }
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL AddComment( const css::uno::Any& Text ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Clear() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL ClearComments() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL ClearContents() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL ClearFormats() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL HasFormula() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL FillLeft() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL FillRight() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL FillUp() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL FillDown() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Offset( const css::uno::Any &nRowOffset, const css::uno::Any &nColOffset )
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL CurrentRegion() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL CurrentArray() throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL Characters( const css::uno::Any& nIndex, const css::uno::Any& nCount )
+ throw (css::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL Address( const css::uno::Any& RowAbsolute, const css::uno::Any& ColumnAbsolute, const css::uno::Any& ReferenceStyle, const css::uno::Any& External, const css::uno::Any& RelativeTo ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Cells( const css::uno::Any &nRow, const css::uno::Any &nCol )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Select() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Activate() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Rows( const css::uno::Any& nIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Columns( const css::uno::Any &nIndex ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Copy( const css::uno::Any& Destination ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Cut( const css::uno::Any& Destination ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Resize( const css::uno::Any& RowSize, const css::uno::Any& ColumnSize )
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL Font() throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XInterior > SAL_CALL Interior( ) throw ( css::script::BasicErrorException, css::uno::RuntimeException) ;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2, bool bForceUseInpuRangeTab ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getCellRange( ) throw (css::uno::RuntimeException);
+ static css::uno::Any getCellRange( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL PasteSpecial( const css::uno::Any& Paste, const css::uno::Any& Operation, const css::uno::Any& SkipBlanks, const css::uno::Any& Transpose ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL Replace( const ::rtl::OUString& What, const ::rtl::OUString& Replacement, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat, const css::uno::Any& ReplaceFormat ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Find( const css::uno::Any& What, const css::uno::Any& After, const css::uno::Any& LookIn, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& SearchDirection, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Sort( const css::uno::Any& Key1, const css::uno::Any& Order1, const css::uno::Any& Key2, const css::uno::Any& Type, const css::uno::Any& Order2, const css::uno::Any& Key3, const css::uno::Any& Order3, const css::uno::Any& Header, const css::uno::Any& OrderCustom, const css::uno::Any& MatchCase, const css::uno::Any& Orientation, const css::uno::Any& SortMethod, const css::uno::Any& DataOption1, const css::uno::Any& DataOption2, const css::uno::Any& DataOption3 ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL End( ::sal_Int32 Direction ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XCharacters > SAL_CALL characters( const css::uno::Any& Start, const css::uno::Any& Length ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Delete( const css::uno::Any& Shift ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Areas( const css::uno::Any& ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& ) throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL BorderAround( const css::uno::Any& LineStyle,
+ const css::uno::Any& Weight, const css::uno::Any& ColorIndex, const css::uno::Any& Color ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL TextToColumns( const css::uno::Any& Destination, const css::uno::Any& DataType, const css::uno::Any& TextQualifier,
+ const css::uno::Any& ConsecutinveDelimiter, const css::uno::Any& Tab, const css::uno::Any& Semicolon, const css::uno::Any& Comma,
+ const css::uno::Any& Space, const css::uno::Any& Other, const css::uno::Any& OtherChar, const css::uno::Any& FieldInfo,
+ const css::uno::Any& DecimalSeparator, const css::uno::Any& ThousandsSeparator, const css::uno::Any& TrailingMinusNumbers ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL AutoFilter( const css::uno::Any& Field, const css::uno::Any& Criteria1, const css::uno::Any& Operator, const css::uno::Any& Criteria2, const css::uno::Any& VisibleDropDown ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Insert( const css::uno::Any& Shift, const css::uno::Any& CopyOrigin ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Autofit() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL AutoFill( const css::uno::Reference< ov::excel::XRange >& Destination, const css::uno::Any& Type ) throw (css::uno::RuntimeException) ;
+ void SAL_CALL Calculate( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL AutoOutline( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Item( const ::css::uno::Any& row, const css::uno::Any& column ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL ClearOutline( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Ungroup( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Group( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Merge( const css::uno::Any& Across ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL UnMerge( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getStyle() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setStyle( const css::uno::Any& _style ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Next() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Previous() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL RemoveSubtotal( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL MergeArea() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Subtotal( ::sal_Int32 GroupBy, ::sal_Int32 Function, const css::uno::Sequence< ::sal_Int32 >& TotalList, const css::uno::Any& Replace, const css::uno::Any& PageBreaks, const css::uno::Any& SummaryBelowData ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException)
+ {
+ return ov::excel::XRange::static_type(0);
+
+ }
+ virtual sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException);
+ // XDefaultMethod
+ ::rtl::OUString SAL_CALL getDefaultMethodName( ) throw (css::uno::RuntimeException);
+ // XDefaultProperty
+ ::rtl::OUString SAL_CALL getDefaultPropertyName( ) throw (css::uno::RuntimeException) { return ::rtl::OUString::createFromAscii("Value"); }
+
+
+// #TODO completely rewrite ScVbaRange, its become a hackfest
+// it needs to be closer to ScCellRangeBase in that the underlying
+// object model should probably be a ScRangelst.
+// * would be nice to be able to construct a range from an addres only
+// * or a list of address ( multi-area )
+// * object should be a lightweight as possible
+// * we shouldn't need hacks like this below
+ static css::uno::Reference< ov::excel::XRange > ApplicationRange( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL GoalSeek( const css::uno::Any& Goal, const css::uno::Reference< ov::excel::XRange >& ChangingCell ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL SpecialCells( const css::uno::Any& _oType, const css::uno::Any& _oValue) throw ( css::script::BasicErrorException );
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif /* SC_VBA_RANGE_HXX */
+
diff --git a/sc/source/ui/vba/vbaseriescollection.cxx b/sc/source/ui/vba/vbaseriescollection.cxx
new file mode 100644
index 000000000000..8caa746beff0
--- /dev/null
+++ b/sc/source/ui/vba/vbaseriescollection.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbaseriescollection.hxx"
+#include <ooo/vba/excel/XSeries.hpp>
+
+#include "vbaglobals.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaSeriesCollection::ScVbaSeriesCollection( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : SeriesCollection_BASE( xParent, xContext, uno::Reference< container::XIndexAccess>() )
+{
+}
+
+// XEnumerationAccess
+
+uno::Reference< container::XEnumeration >
+ScVbaSeriesCollection::createEnumeration() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XEnumeration > xEnum;
+ return xEnum;
+}
+
+// XElementAccess
+
+uno::Type
+ScVbaSeriesCollection::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XSeries::static_type(0);
+}
+
+uno::Any
+ScVbaSeriesCollection::createCollectionObject( const css::uno::Any& rSource )
+{
+ return rSource;
+}
+
+rtl::OUString&
+ScVbaSeriesCollection::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaSeriesCollection") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaSeriesCollection::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.SeriesCollection") );
+ }
+ return sNames;
+}
+
diff --git a/sc/source/ui/vba/vbaseriescollection.hxx b/sc/source/ui/vba/vbaseriescollection.hxx
new file mode 100644
index 000000000000..f61720102919
--- /dev/null
+++ b/sc/source/ui/vba/vbaseriescollection.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_SERIESCOLLECTION_HXX
+#define SC_VBA_SERIESCOLLECTION_HXX
+
+#include <ooo/vba/excel/XSeriesCollection.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbacollectionimpl.hxx>
+#include "excelvbahelper.hxx"
+
+
+typedef CollTestImplHelper< ov::excel::XSeriesCollection > SeriesCollection_BASE;
+
+class ScVbaSeriesCollection : public SeriesCollection_BASE
+{
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+public:
+ ScVbaSeriesCollection( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // SeriesCollection_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_WINDOW_HXX
diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx
new file mode 100755
index 000000000000..4bd0f1d60547
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobject.cxx
@@ -0,0 +1,517 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbasheetobject.hxx"
+#include <com/sun/star/awt/TextAlign.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+#include <ooo/vba/excel/XlOrientation.hpp>
+#include <ooo/vba/excel/XlPlacement.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <filter/msfilter/msvbahelper.hxx>
+#include <oox/helper/helper.hxx>
+#include "vbafont.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+// ============================================================================
+
+ScVbaButtonCharacters::ScVbaButtonCharacters(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< beans::XPropertySet >& rxPropSet,
+ const ScVbaPalette& rPalette,
+ const uno::Any& rStart,
+ const uno::Any& rLength ) throw (uno::RuntimeException) :
+ ScVbaButtonCharacters_BASE( rxParent, rxContext ),
+ maPalette( rPalette ),
+ mxPropSet( rxPropSet, uno::UNO_SET_THROW )
+{
+ // extract optional start parameter (missing or invalid -> from beginning)
+ if( !(rStart >>= mnStart) || (mnStart < 1) )
+ mnStart = 1;
+ --mnStart; // VBA is 1-based, rtl string is 0-based
+
+ // extract optional length parameter (missing or invalid -> to end)
+ if( !(rLength >>= mnLength) || (mnLength < 1) )
+ mnLength = SAL_MAX_INT32;
+}
+
+ScVbaButtonCharacters::~ScVbaButtonCharacters()
+{
+}
+
+// XCharacters attributes
+
+OUString SAL_CALL ScVbaButtonCharacters::getCaption() throw (uno::RuntimeException)
+{
+ // ignore invalid mnStart and/or mnLength members
+ OUString aString = getFullString();
+ sal_Int32 nStart = ::std::min( mnStart, aString.getLength() );
+ sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart );
+ return aString.copy( nStart, nLength );
+}
+
+void SAL_CALL ScVbaButtonCharacters::setCaption( const OUString& rCaption ) throw (uno::RuntimeException)
+{
+ /* Replace the covered text with the passed text, ignore invalid mnStart
+ and/or mnLength members. This operation does not affect the mnLength
+ parameter. If the inserted text is longer than mnLength, the additional
+ characters are not covered by this object. If the inserted text is
+ shorter than mnLength, other uncovered characters from the original
+ string will be covered now, thus may be changed with subsequent
+ operations. */
+ OUString aString = getFullString();
+ sal_Int32 nStart = ::std::min( mnStart, aString.getLength() );
+ sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart );
+ setFullString( aString.replaceAt( nStart, nLength, rCaption ) );
+}
+
+sal_Int32 SAL_CALL ScVbaButtonCharacters::getCount() throw (uno::RuntimeException)
+{
+ // always return the total length of the caption
+ return getFullString().getLength();
+}
+
+OUString SAL_CALL ScVbaButtonCharacters::getText() throw (uno::RuntimeException)
+{
+ // Text attribute same as Caption attribute?
+ return getCaption();
+}
+
+void SAL_CALL ScVbaButtonCharacters::setText( const OUString& rText ) throw (uno::RuntimeException)
+{
+ // Text attribute same as Caption attribute?
+ setCaption( rText );
+}
+
+uno::Reference< excel::XFont > SAL_CALL ScVbaButtonCharacters::getFont() throw (uno::RuntimeException)
+{
+ return new ScVbaFont( this, mxContext, maPalette, mxPropSet, 0, true );
+}
+
+void SAL_CALL ScVbaButtonCharacters::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException)
+{
+ // TODO
+}
+
+// XCharacters methods
+
+void SAL_CALL ScVbaButtonCharacters::Insert( const OUString& rString ) throw (uno::RuntimeException)
+{
+ /* The Insert() operation is in fact "replace covered characters", at
+ least for buttons... It seems there is no easy way to really insert a
+ substring. This operation does not affect the mnLength parameter. */
+ setCaption( rString );
+}
+
+void SAL_CALL ScVbaButtonCharacters::Delete() throw (uno::RuntimeException)
+{
+ /* The Delete() operation is nothing else than "replace with empty string".
+ This does not affect the mnLength parameter, multiple calls of Delete()
+ will remove characters as long as there are some more covered by this
+ object. */
+ setCaption( OUString() );
+}
+
+// XHelperInterface
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters, "ooo.vba.excel.Characters" )
+
+// private
+
+OUString ScVbaButtonCharacters::getFullString() const throw (uno::RuntimeException)
+{
+ return mxPropSet->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >();
+}
+
+void ScVbaButtonCharacters::setFullString( const OUString& rString ) throw (uno::RuntimeException)
+{
+ mxPropSet->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rString ) );
+}
+
+// ============================================================================
+
+ScVbaSheetObjectBase::ScVbaSheetObjectBase(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) :
+ ScVbaSheetObject_BASE( rxParent, rxContext ),
+ maPalette( rxModel ),
+ mxModel( rxModel, uno::UNO_SET_THROW ),
+ mxShape( rxShape, uno::UNO_SET_THROW ),
+ mxShapeProps( rxShape, uno::UNO_QUERY_THROW )
+{
+}
+
+// XSheetObject attributes
+
+double SAL_CALL ScVbaSheetObjectBase::getLeft() throw (uno::RuntimeException)
+{
+ return HmmToPoints( mxShape->getPosition().X );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setLeft( double fLeft ) throw (uno::RuntimeException)
+{
+ if( fLeft < 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setPosition( awt::Point( PointsToHmm( fLeft ), mxShape->getPosition().Y ) );
+}
+
+double SAL_CALL ScVbaSheetObjectBase::getTop() throw (uno::RuntimeException)
+{
+ return HmmToPoints( mxShape->getPosition().Y );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setTop( double fTop ) throw (uno::RuntimeException)
+{
+ if( fTop < 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setPosition( awt::Point( mxShape->getPosition().X, PointsToHmm( fTop ) ) );
+}
+
+double SAL_CALL ScVbaSheetObjectBase::getWidth() throw (uno::RuntimeException)
+{
+ return HmmToPoints( mxShape->getSize().Width );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setWidth( double fWidth ) throw (uno::RuntimeException)
+{
+ if( fWidth <= 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setSize( awt::Size( PointsToHmm( fWidth ), mxShape->getSize().Height ) );
+}
+
+double SAL_CALL ScVbaSheetObjectBase::getHeight() throw (uno::RuntimeException)
+{
+ return HmmToPoints( mxShape->getSize().Height );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setHeight( double fHeight ) throw (uno::RuntimeException)
+{
+ if( fHeight <= 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setSize( awt::Size( mxShape->getSize().Width, PointsToHmm( fHeight ) ) );
+}
+
+OUString SAL_CALL ScVbaSheetObjectBase::getName() throw (uno::RuntimeException)
+{
+ return mxShapeProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >();
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException)
+{
+ mxShapeProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) );
+}
+
+sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException)
+{
+ // TODO
+ return excel::XlPlacement::xlMoveAndSize;
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ ) throw (uno::RuntimeException)
+{
+ // TODO
+}
+
+sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException)
+{
+ // not supported
+ return sal_True;
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setPrintObject( sal_Bool /*bPrintObject*/ ) throw (uno::RuntimeException)
+{
+ // not supported
+}
+
+// private
+
+void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex ) throw (uno::RuntimeException)
+{
+ OUString aName = ::rtl::OUStringBuffer( implGetBaseName() ).append( sal_Unicode( ' ' ) ).append( nIndex + 1 ).makeStringAndClear();
+ setName( aName );
+ implSetDefaultProperties();
+}
+
+void ScVbaSheetObjectBase::implSetDefaultProperties() throw (uno::RuntimeException)
+{
+}
+
+// ============================================================================
+
+ScVbaControlObjectBase::ScVbaControlObjectBase(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< container::XIndexContainer >& rxFormIC,
+ const uno::Reference< drawing::XControlShape >& rxControlShape,
+ ListenerType eListenerType ) throw (uno::RuntimeException) :
+ ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ),
+ mxFormIC( rxFormIC, uno::UNO_SET_THROW ),
+ mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW )
+{
+ // set listener and event name to be used for OnAction attribute
+ switch( eListenerType )
+ {
+ case LISTENER_ACTION:
+ maListenerType = CREATE_OUSTRING( "XActionListener" );
+ maEventMethod = CREATE_OUSTRING( "actionPerformed" );
+ break;
+ case LISTENER_MOUSE:
+ maListenerType = CREATE_OUSTRING( "XMouseListener" );
+ maEventMethod = CREATE_OUSTRING( "mouseReleased" );
+ break;
+ case LISTENER_TEXT:
+ maListenerType = CREATE_OUSTRING( "XTextListener" );
+ maEventMethod = CREATE_OUSTRING( "textChanged" );
+ break;
+ case LISTENER_VALUE:
+ maListenerType = CREATE_OUSTRING( "XAdjustmentListener" );
+ maEventMethod = CREATE_OUSTRING( "adjustmentValueChanged" );
+ break;
+ case LISTENER_CHANGE:
+ maListenerType = CREATE_OUSTRING( "XChangeListener" );
+ maEventMethod = CREATE_OUSTRING( "changed" );
+ break;
+ // no default, to let the compiler complain about missing case
+ }
+}
+
+// XSheetObject attributes
+
+OUString SAL_CALL ScVbaControlObjectBase::getName() throw (uno::RuntimeException)
+{
+ return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >();
+}
+
+void SAL_CALL ScVbaControlObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException)
+{
+ mxControlProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) );
+}
+
+OUString SAL_CALL ScVbaControlObjectBase::getOnAction() throw (uno::RuntimeException)
+{
+ uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW );
+ sal_Int32 nIndex = getModelIndexInForm();
+ uno::Sequence< script::ScriptEventDescriptor > aEvents = xEventMgr->getScriptEvents( nIndex );
+ if( aEvents.hasElements() )
+ {
+ const script::ScriptEventDescriptor* pEvent = aEvents.getConstArray();
+ const script::ScriptEventDescriptor* pEventEnd = pEvent + aEvents.getLength();
+ const OUString aScriptType = CREATE_OUSTRING( "Script" );
+ for( ; pEvent < pEventEnd; ++pEvent )
+ if( (pEvent->ListenerType == maListenerType) && (pEvent->EventMethod == maEventMethod) && (pEvent->ScriptType == aScriptType) )
+ return extractMacroName( pEvent->ScriptCode );
+ }
+ return OUString();
+}
+
+void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) throw (uno::RuntimeException)
+{
+ uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW );
+ sal_Int32 nIndex = getModelIndexInForm();
+
+ // first, remove a registered event (try/catch just in case implementation throws)
+ try { xEventMgr->revokeScriptEvent( nIndex, maListenerType, maEventMethod, OUString() ); } catch( uno::Exception& ) {}
+
+ // if a macro name has been passed, try to attach it to the event
+ if( rMacroName.getLength() > 0 )
+ {
+ VBAMacroResolvedInfo aResolvedMacro = resolveVBAMacro( getSfxObjShell( mxModel ), rMacroName );
+ if( !aResolvedMacro.IsResolved() )
+ throw uno::RuntimeException();
+ script::ScriptEventDescriptor aDescriptor;
+ aDescriptor.ListenerType = maListenerType;
+ aDescriptor.EventMethod = maEventMethod;
+ aDescriptor.ScriptType = CREATE_OUSTRING( "Script" );
+ aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.ResolvedMacro() );
+ xEventMgr->registerScriptEvent( nIndex, aDescriptor );
+ }
+}
+
+sal_Bool SAL_CALL ScVbaControlObjectBase::getPrintObject() throw (uno::RuntimeException)
+{
+ return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Printable" ) ).get< sal_Bool >();
+}
+
+void SAL_CALL ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject ) throw (uno::RuntimeException)
+{
+ mxControlProps->setPropertyValue( CREATE_OUSTRING( "Printable" ), uno::Any( bPrintObject ) );
+}
+
+// XControlObject attributes
+
+sal_Bool SAL_CALL ScVbaControlObjectBase::getAutoSize() throw (uno::RuntimeException)
+{
+ // not supported
+ return sal_False;
+}
+
+void SAL_CALL ScVbaControlObjectBase::setAutoSize( sal_Bool /*bAutoSize*/ ) throw (uno::RuntimeException)
+{
+ // not supported
+}
+
+// private
+
+sal_Int32 ScVbaControlObjectBase::getModelIndexInForm() const throw (uno::RuntimeException)
+{
+ for( sal_Int32 nIndex = 0, nCount = mxFormIC->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< beans::XPropertySet > xProps( mxFormIC->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ if( mxControlProps.get() == xProps.get() )
+ return nIndex;
+ }
+ throw uno::RuntimeException();
+}
+
+// ============================================================================
+
+ScVbaButton::ScVbaButton(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< container::XIndexContainer >& rxFormIC,
+ const uno::Reference< drawing::XControlShape >& rxControlShape ) throw (uno::RuntimeException) :
+ ScVbaButton_BASE( rxParent, rxContext, rxModel, rxFormIC, rxControlShape, LISTENER_ACTION )
+{
+}
+
+// XButton attributes
+
+OUString SAL_CALL ScVbaButton::getCaption() throw (uno::RuntimeException)
+{
+ return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >();
+}
+
+void SAL_CALL ScVbaButton::setCaption( const OUString& rCaption ) throw (uno::RuntimeException)
+{
+ mxControlProps->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rCaption ) );
+}
+
+uno::Reference< excel::XFont > SAL_CALL ScVbaButton::getFont() throw (uno::RuntimeException)
+{
+ return new ScVbaFont( this, mxContext, maPalette, mxControlProps, 0, true );
+}
+
+void SAL_CALL ScVbaButton::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException)
+{
+ // TODO
+}
+
+sal_Int32 SAL_CALL ScVbaButton::getHorizontalAlignment() throw (uno::RuntimeException)
+{
+ switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "Align" ) ).get< sal_Int16 >() )
+ {
+ case awt::TextAlign::LEFT: return excel::Constants::xlLeft;
+ case awt::TextAlign::RIGHT: return excel::Constants::xlRight;
+ case awt::TextAlign::CENTER: return excel::Constants::xlCenter;
+ }
+ return excel::Constants::xlCenter;
+}
+
+void SAL_CALL ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException)
+{
+ sal_Int32 nAwtAlign = awt::TextAlign::CENTER;
+ switch( nAlign )
+ {
+ case excel::Constants::xlLeft: nAwtAlign = awt::TextAlign::LEFT; break;
+ case excel::Constants::xlRight: nAwtAlign = awt::TextAlign::RIGHT; break;
+ case excel::Constants::xlCenter: nAwtAlign = awt::TextAlign::CENTER; break;
+ }
+ // form controls expect short value
+ mxControlProps->setPropertyValue( CREATE_OUSTRING( "Align" ), uno::Any( static_cast< sal_Int16 >( nAwtAlign ) ) );
+}
+
+sal_Int32 SAL_CALL ScVbaButton::getVerticalAlignment() throw (uno::RuntimeException)
+{
+ switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "VerticalAlign" ) ).get< style::VerticalAlignment >() )
+ {
+ case style::VerticalAlignment_TOP: return excel::Constants::xlTop;
+ case style::VerticalAlignment_BOTTOM: return excel::Constants::xlBottom;
+ case style::VerticalAlignment_MIDDLE: return excel::Constants::xlCenter;
+ default:;
+ }
+ return excel::Constants::xlCenter;
+}
+
+void SAL_CALL ScVbaButton::setVerticalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException)
+{
+ style::VerticalAlignment eAwtAlign = style::VerticalAlignment_MIDDLE;
+ switch( nAlign )
+ {
+ case excel::Constants::xlTop: eAwtAlign = style::VerticalAlignment_TOP; break;
+ case excel::Constants::xlBottom: eAwtAlign = style::VerticalAlignment_BOTTOM; break;
+ case excel::Constants::xlCenter: eAwtAlign = style::VerticalAlignment_MIDDLE; break;
+ }
+ mxControlProps->setPropertyValue( CREATE_OUSTRING( "VerticalAlign" ), uno::Any( eAwtAlign ) );
+}
+
+sal_Int32 SAL_CALL ScVbaButton::getOrientation() throw (uno::RuntimeException)
+{
+ // not supported
+ return excel::XlOrientation::xlHorizontal;
+}
+
+void SAL_CALL ScVbaButton::setOrientation( sal_Int32 /*nOrientation*/ ) throw (uno::RuntimeException)
+{
+ // not supported
+}
+
+// XButton methods
+
+uno::Reference< excel::XCharacters > SAL_CALL ScVbaButton::Characters( const uno::Any& rStart, const uno::Any& rLength ) throw (uno::RuntimeException)
+{
+ return new ScVbaButtonCharacters( this, mxContext, mxControlProps, maPalette, rStart, rLength );
+}
+
+// XHelperInterface
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton, "ooo.vba.excel.Button" )
+
+// private
+
+OUString ScVbaButton::implGetBaseName() const
+{
+ return CREATE_OUSTRING( "Button" );
+}
+
+void ScVbaButton::implSetDefaultProperties() throw (uno::RuntimeException)
+{
+ setCaption( getName() );
+}
+
+// ============================================================================
diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx
new file mode 100755
index 000000000000..b2546ca09c93
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobject.hxx
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_VBA_SHEETOBJECT_HXX
+#define SC_VBA_SHEETOBJECT_HXX
+
+#include <memory>
+#include <ooo/vba/excel/XButton.hpp>
+#include <ooo/vba/excel/XControlObject.hpp>
+#include <ooo/vba/excel/XSheetObject.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include "vbapalette.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XIndexContainer; }
+ namespace drawing { class XControlShape; }
+} } }
+
+// ============================================================================
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XCharacters > ScVbaButtonCharacters_BASE;
+
+/** Simple implementation of the Characters symbol for drawing button objects. */
+class ScVbaButtonCharacters : public ScVbaButtonCharacters_BASE
+{
+public:
+ explicit ScVbaButtonCharacters(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::beans::XPropertySet >& rxPropSet,
+ const ScVbaPalette& rPalette,
+ const css::uno::Any& rStart,
+ const css::uno::Any& rLength ) throw (css::uno::RuntimeException);
+ virtual ~ScVbaButtonCharacters();
+
+ // XCharacters attributes
+ virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setText( const ::rtl::OUString& rText ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException);
+
+ // XCharacters methods
+ virtual void SAL_CALL Insert( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Delete() throw (css::uno::RuntimeException);
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+private:
+ ::rtl::OUString getFullString() const throw (css::uno::RuntimeException);
+ void setFullString( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException);
+
+private:
+ ScVbaPalette maPalette;
+ css::uno::Reference< css::beans::XPropertySet > mxPropSet;
+ sal_Int32 mnStart;
+ sal_Int32 mnLength;
+};
+
+// ============================================================================
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XSheetObject > ScVbaSheetObject_BASE;
+
+/** Base class for drawing objects embedded in sheets. */
+class ScVbaSheetObjectBase : public ScVbaSheetObject_BASE
+{
+public:
+ explicit ScVbaSheetObjectBase(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::drawing::XShape >& rxShape ) throw (css::uno::RuntimeException);
+
+ // XSheetObject attributes
+ virtual double SAL_CALL getLeft() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLeft( double fLeft ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getTop() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTop( double fTop ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getWidth() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setWidth( double fWidth ) throw (css::uno::RuntimeException);
+ virtual double SAL_CALL getHeight() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setHeight( double fHeight ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getPlacement() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPlacement( sal_Int32 nPlacement ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException);
+
+ /** Sets default properties after a new object has been created. */
+ void setDefaultProperties( sal_Int32 nIndex ) throw (css::uno::RuntimeException);
+
+protected:
+ /** Derived classes return the base name used for new objects. */
+ virtual ::rtl::OUString implGetBaseName() const = 0;
+ /** Derived classes set default properties for new drawing objects. */
+ virtual void implSetDefaultProperties() throw (css::uno::RuntimeException);
+
+protected:
+ ScVbaPalette maPalette;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::drawing::XShape > mxShape;
+ css::uno::Reference< css::beans::XPropertySet > mxShapeProps;
+};
+
+// ============================================================================
+
+typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectBase, ov::excel::XControlObject > ScVbaControlObject_BASE;
+
+class ScVbaControlObjectBase : public ScVbaControlObject_BASE
+{
+public:
+ /** Specifies the listener used for OnAction events. */
+ enum ListenerType
+ {
+ LISTENER_ACTION, /// XActionListener.actionPerformed
+ LISTENER_MOUSE, /// XMouseListener.mouseReleased
+ LISTENER_TEXT, /// XTextListener.textChanged
+ LISTENER_VALUE, /// XAdjustmentListener.adjustmentValueChanged
+ LISTENER_CHANGE /// XChangeListener.changed
+ };
+
+ explicit ScVbaControlObjectBase(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::container::XIndexContainer >& rxFormIC,
+ const css::uno::Reference< css::drawing::XControlShape >& rxControlShape,
+ ListenerType eListenerType ) throw (css::uno::RuntimeException);
+
+ // XSheetObject attributes
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getOnAction() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setOnAction( const ::rtl::OUString& rMacroName ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException);
+
+ // XControlObject attributes
+ virtual sal_Bool SAL_CALL getAutoSize() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) throw (css::uno::RuntimeException);
+
+protected:
+ sal_Int32 getModelIndexInForm() const throw (css::uno::RuntimeException);
+
+protected:
+ css::uno::Reference< css::container::XIndexContainer > mxFormIC;
+ css::uno::Reference< css::beans::XPropertySet > mxControlProps;
+ ::rtl::OUString maListenerType;
+ ::rtl::OUString maEventMethod;
+};
+
+// ============================================================================
+
+typedef ::cppu::ImplInheritanceHelper1< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE;
+
+class ScVbaButton : public ScVbaButton_BASE
+{
+public:
+ explicit ScVbaButton(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::container::XIndexContainer >& rxFormIC,
+ const css::uno::Reference< css::drawing::XControlShape >& rxControlShape ) throw (css::uno::RuntimeException);
+
+ // XButton attributes
+ virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getHorizontalAlignment() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setHorizontalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getVerticalAlignment() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVerticalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getOrientation() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setOrientation( sal_Int32 nOrientation ) throw (css::uno::RuntimeException);
+
+ // XButton methods
+ css::uno::Reference< ov::excel::XCharacters > SAL_CALL Characters(
+ const css::uno::Any& rStart, const css::uno::Any& rLength ) throw (css::uno::RuntimeException);
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+protected:
+ virtual ::rtl::OUString implGetBaseName() const;
+ virtual void implSetDefaultProperties() throw (css::uno::RuntimeException);
+};
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/ui/vba/vbasheetobjects.cxx b/sc/source/ui/vba/vbasheetobjects.cxx
new file mode 100755
index 000000000000..ced94db5ba76
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobjects.cxx
@@ -0,0 +1,534 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbasheetobjects.hxx"
+#include <vector>
+#include <rtl/math.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XFormComponent.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <oox/helper/helper.hxx>
+#include "vbasheetobject.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+// ============================================================================
+
+namespace {
+
+template< typename Type >
+inline bool lclGetProperty( Type& orValue, const uno::Reference< beans::XPropertySet >& rxPropSet, const OUString& rPropName )
+{
+ try
+ {
+ return rxPropSet->getPropertyValue( rPropName ) >>= orValue;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return false;
+}
+
+/** Rounds the passed value to a multiple of 0.75 and converts it to 1/100 mm. */
+inline double lclPointsToHmm( const uno::Any& rPoints ) throw (uno::RuntimeException)
+{
+ return PointsToHmm( ::rtl::math::approxFloor( rPoints.get< double >() / 0.75 ) * 0.75 );
+}
+
+} // namespace
+
+// ============================================================================
+// Base implementations
+// ============================================================================
+
+/** Container for a specific type of drawing object in a spreadsheet.
+
+ Derived classes provide all required functionality specific to the type of
+ shapes covered by the container.
+ */
+class ScVbaObjectContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess >
+{
+public:
+ explicit ScVbaObjectContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType ) throw (uno::RuntimeException);
+
+ /** Returns the VBA helper interface of the VBA collection object. */
+ inline const uno::Reference< XHelperInterface >& getParent() const { return mxParent; }
+ /** Returns the component context of the VBA collection object. */
+ inline const uno::Reference< uno::XComponentContext >& getContext() const { return mxContext; }
+ /** Returns the VBA type information of the objects in this container. */
+ inline const uno::Type& getVbaType() const { return maVbaType; }
+
+ /** Collects all shapes supported by this instance and inserts them into
+ the internal shape vector. */
+ void collectShapes() throw (uno::RuntimeException);
+ /** Creates and returns a new UNO shape. */
+ uno::Reference< drawing::XShape > createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException);
+ /** Inserts the passed shape into the draw page and into this container, and returns its index in the draw page. */
+ sal_Int32 insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
+ /** Creates and returns a new VBA implementation object for the passed shape. */
+ ::rtl::Reference< ScVbaSheetObjectBase > createVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
+ /** Creates and returns a new VBA implementation object for the passed shape in an Any. */
+ uno::Any createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException);
+ /** Returns the VBA implementation object with the specified name. */
+ uno::Any getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException);
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException);
+
+protected:
+ /** Derived classes return true, if the passed shape is supported by the instance. */
+ virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const = 0;
+ /** Derived classes create and return a new VBA implementation object for the passed shape. */
+ virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) = 0;
+ /** Derived classes return the service name of the UNO shape. */
+ virtual OUString implGetShapeServiceName() const = 0;
+
+ /** Returns the shape name via 'Name' property of the UNO shape. May be overwritten. */
+ virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException);
+ /** Is called when a new UNO shape has been created but not yet inserted into the drawing page. */
+ virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
+ /** Is called when a new UNO shape has been inserted into the drawing page. */
+ virtual void implOnShapeInserted( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
+
+protected:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+ uno::Reference< lang::XMultiServiceFactory > mxFactory;
+ uno::Reference< drawing::XShapes > mxShapes;
+
+private:
+ typedef ::std::vector< uno::Reference< drawing::XShape > > ShapeVector;
+ const uno::Type maVbaType;
+ ShapeVector maShapes;
+};
+
+// ----------------------------------------------------------------------------
+
+ScVbaObjectContainer::ScVbaObjectContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType ) throw (uno::RuntimeException) :
+ mxParent( rxParent ),
+ mxContext( rxContext ),
+ mxModel( rxModel, uno::UNO_SET_THROW ),
+ mxFactory( rxModel, uno::UNO_QUERY_THROW ),
+ maVbaType( rVbaType )
+{
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( rxSheet, uno::UNO_QUERY_THROW );
+ mxShapes.set( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW );
+}
+
+void ScVbaObjectContainer::collectShapes() throw (uno::RuntimeException)
+{
+ maShapes.clear();
+ for( sal_Int32 nIndex = 0, nCount = mxShapes->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< drawing::XShape > xShape( mxShapes->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ if( implPickShape( xShape ) )
+ maShapes.push_back( xShape );
+ }
+}
+
+uno::Reference< drawing::XShape > ScVbaObjectContainer::createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException)
+{
+ uno::Reference< drawing::XShape > xShape( mxFactory->createInstance( implGetShapeServiceName() ), uno::UNO_QUERY_THROW );
+ xShape->setPosition( rPos );
+ xShape->setSize( rSize );
+ implOnShapeCreated( xShape );
+ return xShape;
+}
+
+sal_Int32 ScVbaObjectContainer::insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
+{
+ mxShapes->add( rxShape );
+ maShapes.push_back( rxShape );
+ implOnShapeInserted( rxShape );
+ return mxShapes->getCount() - 1;
+}
+
+::rtl::Reference< ScVbaSheetObjectBase > ScVbaObjectContainer::createVbaObject(
+ const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
+{
+ return implCreateVbaObject( rxShape );
+}
+
+uno::Any ScVbaObjectContainer::createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException)
+{
+ uno::Reference< drawing::XShape > xShape( rSource, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XSheetObject > xSheetObject( implCreateVbaObject( xShape ) );
+ return uno::Any( xSheetObject );
+}
+
+uno::Any ScVbaObjectContainer::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException)
+{
+ for( ShapeVector::iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt )
+ if( rIndex == implGetShapeName( *aIt ) )
+ return createCollectionObject( uno::Any( *aIt ) );
+ throw uno::RuntimeException();
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScVbaObjectContainer::getCount() throw (uno::RuntimeException)
+{
+ return static_cast< sal_Int32 >( maShapes.size() );
+}
+
+uno::Any SAL_CALL ScVbaObjectContainer::getByIndex( sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if( (0 <= nIndex) && (nIndex < getCount()) )
+ return uno::Any( maShapes[ static_cast< size_t >( nIndex ) ] );
+ throw lang::IndexOutOfBoundsException();
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScVbaObjectContainer::getElementType() throw (uno::RuntimeException)
+{
+ return drawing::XShape::static_type( 0 );
+}
+
+sal_Bool SAL_CALL ScVbaObjectContainer::hasElements() throw (uno::RuntimeException)
+{
+ return !maShapes.empty();
+}
+
+// private
+
+OUString ScVbaObjectContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xPropSet( rxShape, uno::UNO_QUERY_THROW );
+ return xPropSet->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >();
+}
+
+void ScVbaObjectContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException)
+{
+}
+
+void ScVbaObjectContainer::implOnShapeInserted( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException)
+{
+}
+
+// ============================================================================
+
+class ScVbaObjectEnumeration : public SimpleEnumerationBase
+{
+public:
+ explicit ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer );
+ virtual uno::Any createCollectionObject( const uno::Any& rSource );
+
+private:
+ ScVbaObjectContainerRef mxContainer;
+};
+
+// ----------------------------------------------------------------------------
+
+ScVbaObjectEnumeration::ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ) :
+ SimpleEnumerationBase( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ),
+ mxContainer( rxContainer )
+{
+}
+
+uno::Any ScVbaObjectEnumeration::createCollectionObject( const uno::Any& rSource )
+{
+ return mxContainer->createCollectionObject( rSource );
+}
+
+// ============================================================================
+
+ScVbaSheetObjectsBase::ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException) :
+ ScVbaSheetObjects_BASE( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ),
+ mxContainer( rxContainer )
+{
+ mxContainer->collectShapes();
+}
+
+ScVbaSheetObjectsBase::~ScVbaSheetObjectsBase()
+{
+}
+
+void ScVbaSheetObjectsBase::collectShapes() throw (uno::RuntimeException)
+{
+ mxContainer->collectShapes();
+}
+
+// XEnumerationAccess
+
+uno::Reference< container::XEnumeration > SAL_CALL ScVbaSheetObjectsBase::createEnumeration() throw (uno::RuntimeException)
+{
+ return new ScVbaObjectEnumeration( mxContainer );
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScVbaSheetObjectsBase::getElementType() throw (uno::RuntimeException)
+{
+ return mxContainer->getVbaType();
+}
+
+// ScVbaCollectionBase
+
+uno::Any ScVbaSheetObjectsBase::createCollectionObject( const uno::Any& rSource )
+{
+ return mxContainer->createCollectionObject( rSource );
+}
+
+uno::Any ScVbaSheetObjectsBase::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException)
+{
+ return mxContainer->getItemByStringIndex( rIndex );
+}
+
+// ============================================================================
+// Graphic object containers supporting ooo.vba.excel.XGraphicObject
+// ============================================================================
+
+ScVbaGraphicObjectsBase::ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (uno::RuntimeException) :
+ ScVbaGraphicObjects_BASE( rxContainer )
+{
+}
+
+// XGraphicObjects
+
+uno::Any SAL_CALL ScVbaGraphicObjectsBase::Add( const uno::Any& rLeft, const uno::Any& rTop, const uno::Any& rWidth, const uno::Any& rHeight ) throw (uno::RuntimeException)
+{
+ /* Extract double values from passed Anys (the lclPointsToHmm() helper
+ function will throw a RuntimeException on any error), and convert from
+ points to 1/100 mm. */
+ awt::Point aPos( lclPointsToHmm( rLeft ), lclPointsToHmm( rTop ) );
+ awt::Size aSize( lclPointsToHmm( rWidth ), lclPointsToHmm( rHeight ) );
+ // TODO: translate coordinates for RTL sheets
+ if( (aPos.X < 0) || (aPos.Y < 0) || (aSize.Width <= 0) || (aSize.Height <= 0) )
+ throw uno::RuntimeException();
+
+ // create the UNO shape
+ uno::Reference< drawing::XShape > xShape( mxContainer->createShape( aPos, aSize ), uno::UNO_SET_THROW );
+ sal_Int32 nIndex = mxContainer->insertShape( xShape );
+
+ // create and return the VBA object
+ ::rtl::Reference< ScVbaSheetObjectBase > xVbaObject = mxContainer->createVbaObject( xShape );
+ xVbaObject->setDefaultProperties( nIndex );
+ return uno::Any( uno::Reference< excel::XSheetObject >( xVbaObject.get() ) );
+}
+
+// ============================================================================
+// Drawing controls
+// ============================================================================
+
+class ScVbaControlContainer : public ScVbaObjectContainer
+{
+public:
+ explicit ScVbaControlContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType,
+ const OUString& rModelServiceName,
+ sal_Int16 nComponentType ) throw (uno::RuntimeException);
+
+protected:
+ uno::Reference< container::XIndexContainer > createForm() throw (uno::RuntimeException);
+
+ virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const;
+ virtual OUString implGetShapeServiceName() const;
+ virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const;
+ virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException);
+ virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
+
+protected:
+ uno::Reference< container::XIndexContainer > mxFormIC;
+ OUString maModelServiceName;
+ sal_Int16 mnComponentType;
+};
+
+// ----------------------------------------------------------------------------
+
+ScVbaControlContainer::ScVbaControlContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType,
+ const OUString& rModelServiceName,
+ sal_Int16 nComponentType ) throw (uno::RuntimeException) :
+ ScVbaObjectContainer( rxParent, rxContext, rxModel, rxSheet, rVbaType ),
+ maModelServiceName( rModelServiceName ),
+ mnComponentType( nComponentType )
+{
+}
+
+uno::Reference< container::XIndexContainer > ScVbaControlContainer::createForm() throw (uno::RuntimeException)
+{
+ if( !mxFormIC.is() )
+ {
+ uno::Reference< form::XFormsSupplier > xFormsSupp( mxShapes, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameContainer > xFormsNC( xFormsSupp->getForms(), uno::UNO_SET_THROW );
+ OUString aFormName = CREATE_OUSTRING( "Standard" );
+ if( xFormsNC->hasByName( aFormName ) )
+ {
+ mxFormIC.set( xFormsNC->getByName( aFormName ), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ uno::Reference< form::XForm > xForm( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), uno::UNO_QUERY_THROW );
+ xFormsNC->insertByName( aFormName, uno::Any( xForm ) );
+ mxFormIC.set( xForm, uno::UNO_QUERY_THROW );
+ }
+ }
+ return mxFormIC;
+}
+
+bool ScVbaControlContainer::implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const
+{
+ try
+ {
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xModelProps( xControlShape->getControl(), uno::UNO_QUERY_THROW );
+ sal_Int16 nClassId = -1;
+ return lclGetProperty( nClassId, xModelProps, CREATE_OUSTRING( "ClassId" ) ) &&
+ (nClassId == mnComponentType) && implCheckProperties( xModelProps );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return false;
+}
+
+OUString ScVbaControlContainer::implGetShapeServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" );
+}
+
+bool ScVbaControlContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& /*rxModelProps*/ ) const
+{
+ return true;
+}
+
+OUString ScVbaControlContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException)
+{
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+ return uno::Reference< container::XNamed >( xControlShape->getControl(), uno::UNO_QUERY_THROW )->getName();
+}
+
+void ScVbaControlContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
+{
+ // passed shape must be a control shape
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+
+ // create the UNO control model
+ uno::Reference< form::XFormComponent > xFormComponent( mxFactory->createInstance( maModelServiceName ), uno::UNO_QUERY_THROW );
+ uno::Reference< awt::XControlModel > xControlModel( xFormComponent, uno::UNO_QUERY_THROW );
+
+ // insert the control model into the form and the shape
+ createForm();
+ mxFormIC->insertByIndex( mxFormIC->getCount(), uno::Any( xFormComponent ) );
+ xControlShape->setControl( xControlModel );
+}
+
+// ============================================================================
+// Push button
+// ============================================================================
+
+class ScVbaButtonContainer : public ScVbaControlContainer
+{
+public:
+ explicit ScVbaButtonContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException);
+
+protected:
+ virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException);
+ virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+ScVbaButtonContainer::ScVbaButtonContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) :
+ ScVbaControlContainer(
+ rxParent, rxContext, rxModel, rxSheet,
+ excel::XButton::static_type( 0 ),
+ CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" ),
+ form::FormComponentType::COMMANDBUTTON )
+{
+}
+
+ScVbaSheetObjectBase* ScVbaButtonContainer::implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException)
+{
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+ return new ScVbaButton( mxParent, mxContext, mxModel, createForm(), xControlShape );
+}
+
+bool ScVbaButtonContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const
+{
+ // do not insert toggle buttons into the 'Buttons' collection
+ bool bToggle = false;
+ return lclGetProperty( bToggle, rxModelProps, CREATE_OUSTRING( "Toggle" ) ) && !bToggle;
+}
+
+// ============================================================================
+
+ScVbaButtons::ScVbaButtons(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) :
+ ScVbaGraphicObjectsBase( new ScVbaButtonContainer( rxParent, rxContext, rxModel, rxSheet ) )
+{
+}
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtons, "ooo.vba.excel.Buttons" )
+
+// ============================================================================
diff --git a/sc/source/ui/vba/vbasheetobjects.hxx b/sc/source/ui/vba/vbasheetobjects.hxx
new file mode 100755
index 000000000000..fd69d4927a20
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobjects.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_VBA_SHEETOBJECTS_HXX
+#define SC_VBA_SHEETOBJECTS_HXX
+
+#include <ooo/vba/excel/XGraphicObjects.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <rtl/ref.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XEnumeration; }
+ namespace frame { class XModel; }
+ namespace sheet { class XSpreadsheet; }
+} } }
+
+// ============================================================================
+
+class ScVbaObjectContainer;
+typedef ::rtl::Reference< ScVbaObjectContainer > ScVbaObjectContainerRef;
+
+// ============================================================================
+
+typedef CollTestImplHelper< ov::XCollection > ScVbaSheetObjects_BASE;
+
+/** Base class for collections containing a specific type of drawing object
+ embedded in a sheet (worksheet, chart sheet, or dialog sheet).
+ */
+class ScVbaSheetObjectsBase : public ScVbaSheetObjects_BASE
+{
+public:
+ explicit ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException);
+ virtual ~ScVbaSheetObjectsBase();
+
+ /** Updates the collection by fetching all shapes from the draw page. */
+ void collectShapes() throw (css::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+
+ // ScVbaCollectionBase
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource );
+ virtual css::uno::Any getItemByStringIndex( const ::rtl::OUString& rIndex ) throw (css::uno::RuntimeException);
+
+protected:
+ ScVbaObjectContainerRef mxContainer;
+};
+
+// ============================================================================
+
+typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectsBase, ov::excel::XGraphicObjects > ScVbaGraphicObjects_BASE;
+
+/** Base class for collections containing a specific type of graphic object
+ from a sheet.
+ */
+class ScVbaGraphicObjectsBase : public ScVbaGraphicObjects_BASE
+{
+public:
+ explicit ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException);
+
+ // XGraphicObjects
+ virtual css::uno::Any SAL_CALL Add(
+ const css::uno::Any& rLeft,
+ const css::uno::Any& rTop,
+ const css::uno::Any& rWidth,
+ const css::uno::Any& rHeight ) throw (css::uno::RuntimeException);
+};
+
+// ============================================================================
+
+/** Collection containing all button controls from a sheet (not ActiveX controls). */
+class ScVbaButtons : public ScVbaGraphicObjectsBase
+{
+public:
+ explicit ScVbaButtons(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::sheet::XSpreadsheet >& rxSheet ) throw (css::uno::RuntimeException);
+
+ VBAHELPER_DECL_XHELPERINTERFACE
+};
+
+// ============================================================================
+
+#endif
diff --git a/sc/source/ui/vba/vbastyle.cxx b/sc/source/ui/vba/vbastyle.cxx
new file mode 100644
index 000000000000..b99b2e783101
--- /dev/null
+++ b/sc/source/ui/vba/vbastyle.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vbastyle.hxx"
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static rtl::OUString DISPLAYNAME( RTL_CONSTASCII_USTRINGPARAM("DisplayName") );
+
+
+
+uno::Reference< container::XNameAccess >
+ScVbaStyle::getStylesNameContainer( const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException )
+{
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( xModel, uno::UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xStylesAccess( xStyleSupplier->getStyleFamilies()->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CellStyles" ) ) ), uno::UNO_QUERY_THROW );
+ return xStylesAccess;
+}
+
+uno::Reference< beans::XPropertySet >
+lcl_getStyleProps( const rtl::OUString& sStyleName, const uno::Reference< frame::XModel >& xModel ) throw ( script::BasicErrorException, uno::RuntimeException )
+{
+
+ uno::Reference< beans::XPropertySet > xStyleProps( ScVbaStyle::getStylesNameContainer( xModel )->getByName( sStyleName ), uno::UNO_QUERY_THROW );
+ return xStyleProps;
+}
+
+
+void ScVbaStyle::initialise() throw ( uno::RuntimeException )
+{
+ if (!mxModel.is() )
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XModel Interface could not be retrieved")) );
+ uno::Reference< lang::XServiceInfo > xServiceInfo( mxPropertySet, uno::UNO_QUERY_THROW );
+ if ( !xServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CellStyle" ) ) ) )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ mxStyle.set( mxPropertySet, uno::UNO_QUERY_THROW );
+
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxModel, uno::UNO_QUERY_THROW );
+ mxStyleFamilyNameContainer.set( ScVbaStyle::getStylesNameContainer( mxModel ), uno::UNO_QUERY_THROW );
+
+}
+
+ScVbaStyle::ScVbaStyle( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const rtl::OUString& sStyleName, const uno::Reference< frame::XModel >& _xModel ) throw ( script::BasicErrorException, uno::RuntimeException ) : ScVbaStyle_BASE( xParent, xContext, lcl_getStyleProps( sStyleName, _xModel ), _xModel, false ), mxModel( _xModel )
+{
+ try
+ {
+ initialise();
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+ScVbaStyle::ScVbaStyle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertySet >& _xPropertySet, const uno::Reference< frame::XModel >& _xModel ) throw ( script::BasicErrorException, uno::RuntimeException ) : ScVbaStyle_BASE( xParent, xContext, _xPropertySet, _xModel, false ), mxModel( _xModel )
+{
+ try
+ {
+ initialise();
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+
+::sal_Bool SAL_CALL
+ScVbaStyle::BuiltIn() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return !mxStyle->isUserDefined();
+
+}
+void SAL_CALL
+ScVbaStyle::setName( const ::rtl::OUString& Name ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ mxStyle->setName(Name);
+}
+
+::rtl::OUString SAL_CALL
+ScVbaStyle::getName() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return mxStyle->getName();
+}
+
+void SAL_CALL
+ScVbaStyle::setNameLocal( const ::rtl::OUString& NameLocal ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ mxPropertySet->setPropertyValue(DISPLAYNAME, uno::makeAny( NameLocal ) );
+ }
+ catch (uno::Exception& e)
+ {
+ DebugHelper::exception(e);
+ }
+}
+
+::rtl::OUString SAL_CALL
+ScVbaStyle::getNameLocal() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ rtl::OUString sName;
+ try
+ {
+ mxPropertySet->getPropertyValue(DISPLAYNAME) >>= sName;
+ }
+ catch (uno::Exception e)
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return sName;
+}
+
+void SAL_CALL
+ScVbaStyle::Delete() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ try
+ {
+ mxStyleFamilyNameContainer->removeByName(mxStyle->getName());
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+void SAL_CALL
+ScVbaStyle::setMergeCells( const uno::Any& /*MergeCells*/ ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+}
+
+uno::Any SAL_CALL
+ScVbaStyle::getMergeCells( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
+ return uno::Any();
+}
+
+
+rtl::OUString&
+ScVbaStyle::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaStyle") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaStyle::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.XStyle" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbastyle.hxx b/sc/source/ui/vba/vbastyle.hxx
new file mode 100644
index 000000000000..d5bb232dabc2
--- /dev/null
+++ b/sc/source/ui/vba/vbastyle.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_STYLE_HXX
+#define SC_VBA_STYLE_HXX
+#include <ooo/vba/excel/XStyle.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include "vbaformat.hxx"
+
+
+typedef ScVbaFormat< ov::excel::XStyle > ScVbaStyle_BASE;
+
+class ScVbaStyle : public ScVbaStyle_BASE
+{
+protected:
+ css::uno::Reference< css::style::XStyle > mxStyle;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::container::XNameContainer > mxStyleFamilyNameContainer;
+ void initialise() throw ( css::uno::RuntimeException );
+public:
+ ScVbaStyle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const rtl::OUString& sStyleName, const css::uno::Reference< css::frame::XModel >& _xModel ) throw ( css::script::BasicErrorException, css::uno::RuntimeException );
+ ScVbaStyle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& _xModel ) throw ( css::script::BasicErrorException, css::uno::RuntimeException );
+ virtual ~ScVbaStyle(){}
+ static css::uno::Reference< css::container::XNameAccess > getStylesNameContainer( const css::uno::Reference< css::frame::XModel >& xModel ) throw( css::uno::RuntimeException );
+ virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() { return this; };
+ // XStyle Methods
+ virtual ::sal_Bool SAL_CALL BuiltIn() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& Name ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setNameLocal( const ::rtl::OUString& NameLocal ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getNameLocal() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL Delete() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XFormat
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& MergeCells ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getMergeCells( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+/*
+ // XFormat
+ virtual css::uno::Reference< ::ooo::vba::excel::XBorders > SAL_CALL Borders( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Reference< ::ooo::vba::excel::XFont > SAL_CALL Font( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Reference< ::ooo::vba::excel::XInterior > SAL_CALL Interior( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setNumberFormat( const css::uno::Any& NumberFormat ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getNumberFormat( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setNumberFormatLocal( const css::uno::Any& NumberFormatLocal ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getNumberFormatLocal( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setIndentLevel( const css::uno::Any& IndentLevel ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getIndentLevel( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setHorizontalAlignment( const css::uno::Any& HorizontalAlignment ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getHorizontalAlignment( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setVerticalAlignment( const css::uno::Any& VerticalAlignment ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getVerticalAlignment( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setOrientation( const css::uno::Any& Orientation ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getOrientation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setShrinkToFit( const css::uno::Any& ShrinkToFit ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getShrinkToFit( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setWrapText( const css::uno::Any& WrapText ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getWrapText( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setLocked( const css::uno::Any& Locked ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getLocked( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setFormulaHidden( const css::uno::Any& FormulaHidden ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+/ virtual css::uno::Any SAL_CALL getFormulaHidden( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& MergeCells ) throw (css::script::BasicErrorException, css::uno::RuntimeException) = 0;
+ virtual css::uno::Any SAL_CALL getMergeCells( ) throw (css::script::BasicErrorException, css::uno::RuntimeException) = 0;
+ virtual void SAL_CALL setReadingOrder( const css::uno::Any& ReadingOrder ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+ virtual css::uno::Any SAL_CALL getReadingOrder( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);;
+*/
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_AXIS_HXX
diff --git a/sc/source/ui/vba/vbastyles.cxx b/sc/source/ui/vba/vbastyles.cxx
new file mode 100644
index 000000000000..c323e2b3f6f6
--- /dev/null
+++ b/sc/source/ui/vba/vbastyles.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbastyles.hxx"
+#include "vbastyle.hxx"
+#include <ooo/vba/excel/XRange.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static rtl::OUString SDEFAULTCELLSTYLENAME( RTL_CONSTASCII_USTRINGPARAM("Default") );
+css::uno::Any
+lcl_createAPIStyleToVBAObject( const css::uno::Any& aObject, const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< beans::XPropertySet > xStyleProps( aObject, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XStyle > xStyle( new ScVbaStyle( xParent, xContext, xStyleProps, xModel ) );
+ return uno::makeAny( xStyle );
+}
+
+
+ScVbaStyles::ScVbaStyles( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) throw ( script::BasicErrorException ) : ScVbaStyles_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( ScVbaStyle::getStylesNameContainer( xModel ), uno::UNO_QUERY_THROW ) ), mxModel( xModel ), mxParent( xParent )
+{
+ try
+ {
+ mxMSF.set( mxModel, uno::UNO_QUERY_THROW );
+ mxNameContainerCellStyles.set( m_xNameAccess, uno::UNO_QUERY_THROW );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaStyles::getStyleNames() throw ( uno::RuntimeException )
+{
+ return mxNameContainerCellStyles->getElementNames();
+}
+
+
+uno::Any
+ScVbaStyles::createCollectionObject(const uno::Any& aObject)
+{
+ return lcl_createAPIStyleToVBAObject( aObject, mxParent, mxContext, mxModel );
+}
+
+uno::Type SAL_CALL
+ScVbaStyles::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XStyle::static_type(0);
+}
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ uno::Reference<XHelperInterface > m_xParent;
+ uno::Reference<uno::XComponentContext > m_xContext;
+ uno::Reference<frame::XModel > m_xModel;
+
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference<XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference<frame::XModel >& xModel ) : m_xIndexAccess( xIndexAccess ), m_xParent( xParent ), m_xContext( xContext ), m_xModel( xModel ), nIndex( 0 ) {}
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return lcl_createAPIStyleToVBAObject( m_xIndexAccess->getByIndex( nIndex++ ), m_xParent, m_xContext, m_xModel );
+ throw container::NoSuchElementException();
+ }
+};
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaStyles::createEnumeration() throw (uno::RuntimeException)
+{
+ return new EnumWrapper( m_xIndexAccess, mxParent, mxContext, mxModel );
+}
+
+uno::Reference< excel::XStyle > SAL_CALL
+ScVbaStyles::Add( const ::rtl::OUString& _sName, const uno::Any& _aBasedOn ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< excel::XStyle > aRet;
+ try
+ {
+ rtl::OUString sParentCellStyleName( RTL_CONSTASCII_USTRINGPARAM("Default"));
+ if ( _aBasedOn.hasValue() )
+ {
+ uno::Reference< excel::XRange > oRange;
+ if ( _aBasedOn >>= oRange)
+ {
+ uno::Reference< excel::XStyle > oStyle( oRange->getStyle(), uno::UNO_QUERY_THROW );
+ if ( oStyle.is() )
+ {
+ sParentCellStyleName = oStyle->getName();
+ }
+ else
+ {
+ DebugHelper::exception(SbERR_BAD_ARGUMENT, rtl::OUString() );
+ }
+ }
+ else
+ {
+ DebugHelper::exception(SbERR_BAD_ARGUMENT, rtl::OUString());
+ }
+ }
+
+ uno::Reference< style::XStyle > xStyle( mxMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.CellStyle"))), uno::UNO_QUERY_THROW );
+
+ if (!mxNameContainerCellStyles->hasByName(_sName))
+ {
+ mxNameContainerCellStyles->insertByName(_sName, uno::makeAny( xStyle) );
+ }
+ if (!sParentCellStyleName.equals(SDEFAULTCELLSTYLENAME))
+ {
+ xStyle->setParentStyle( sParentCellStyleName );
+ }
+ aRet.set( Item( uno::makeAny( _sName ), uno::Any() ), uno::UNO_QUERY_THROW );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+ return aRet;
+}
+
+void
+ScVbaStyles::Delete(const rtl::OUString _sStyleName) throw ( script::BasicErrorException )
+{
+ try
+ {
+ if (mxNameContainerCellStyles->hasByName( _sStyleName ) )
+ mxNameContainerCellStyles->removeByName( _sStyleName );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
+ }
+}
+
+rtl::OUString&
+ScVbaStyles::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaStyles") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaStyles::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.XStyles" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbastyles.hxx b/sc/source/ui/vba/vbastyles.hxx
new file mode 100644
index 000000000000..300596d6b3fe
--- /dev/null
+++ b/sc/source/ui/vba/vbastyles.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_STYLES_HXX
+#define SC_VBA_STYLES_HXX
+#include <ooo/vba/excel/XStyles.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XStyles > ScVbaStyles_BASE;
+class ScVbaStyles: public ScVbaStyles_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ // hard ref to parent ( perhaps we should try this in the
+ // XHelperInterface itself
+ css::uno::Reference< ov::XHelperInterface > mxParent;
+ css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF;
+ css::uno::Reference< css::container::XNameContainer > mxNameContainerCellStyles;
+public:
+ ScVbaStyles( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel ) throw ( css::script::BasicErrorException );
+ css::uno::Sequence< rtl::OUString > getStyleNames() throw ( css::uno::RuntimeException );
+ void Delete(const rtl::OUString _sStyleName) throw ( css::script::BasicErrorException );
+ // XStyles
+ virtual css::uno::Reference< ov::excel::XStyle > SAL_CALL Add( const ::rtl::OUString& Name, const css::uno::Any& BasedOn ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif
diff --git a/sc/source/ui/vba/vbatextboxshape.cxx b/sc/source/ui/vba/vbatextboxshape.cxx
new file mode 100644
index 000000000000..0ef9e0f7393b
--- /dev/null
+++ b/sc/source/ui/vba/vbatextboxshape.cxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vbatextboxshape.hxx"
+#include "vbacharacters.hxx"
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <vector>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaTextBoxShape::ScVbaTextBoxShape( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape, const uno::Reference< drawing::XShapes >& xShapes, const uno::Reference< frame::XModel >& xModel ) : TextBoxShapeImpl_BASE( uno::Reference< XHelperInterface >(), xContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) )
+{
+ m_xTextRange.set( xShape , uno::UNO_QUERY_THROW );
+ m_xModel.set( xModel );
+}
+
+rtl::OUString SAL_CALL
+ScVbaTextBoxShape::getText() throw (css::uno::RuntimeException)
+{
+ return m_xTextRange->getString();
+}
+
+void SAL_CALL
+ScVbaTextBoxShape::setText( const rtl::OUString& _text ) throw (css::uno::RuntimeException)
+{
+ m_xTextRange->setString( _text );
+}
+
+uno::Reference< excel::XCharacters > SAL_CALL
+ScVbaTextBoxShape::characters( const uno::Any& Start, const uno::Any& Length ) throw (uno::RuntimeException)
+{
+ ScDocShell* pDocShell = excel::getDocShell( m_xModel );
+ ScDocument* pDoc = pDocShell ? pDocShell->GetDocument() : NULL;
+
+ if ( !pDoc )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
+ uno::Reference< text::XSimpleText > xSimple( m_xTextRange, uno::UNO_QUERY_THROW );
+
+ ScVbaPalette aPalette( pDoc->GetDocumentShell() );
+ return new ScVbaCharacters( this, mxContext, aPalette, xSimple, Start, Length, sal_True );
+}
diff --git a/sc/source/ui/vba/vbatextboxshape.hxx b/sc/source/ui/vba/vbatextboxshape.hxx
new file mode 100644
index 000000000000..c08a576b7155
--- /dev/null
+++ b/sc/source/ui/vba/vbatextboxshape.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_TEXTBOX_HXX
+#define SC_VBA_TEXTBOX_HXX
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <ooo/vba/msforms/XTextBoxShape.hpp>
+#include <vbahelper/vbashape.hxx>
+#include "excelvbahelper.hxx"
+#include "vbacharacters.hxx"
+
+typedef cppu::ImplInheritanceHelper1< ScVbaShape, ov::msforms::XTextBoxShape > TextBoxShapeImpl_BASE;
+
+class ScVbaTextBoxShape : public TextBoxShapeImpl_BASE
+{
+ css::uno::Reference< css::text::XTextRange > m_xTextRange;
+ css::uno::Reference< css::frame::XModel > m_xModel;
+public:
+ ScVbaTextBoxShape( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::drawing::XShapes >& xShapes, const css::uno::Reference< css::frame::XModel >& xModel );
+
+ // Attributes
+ virtual rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setText( const rtl::OUString& _text ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XCharacters > SAL_CALL characters( const css::uno::Any& Start, const css::uno::Any& Length ) throw (css::uno::RuntimeException);
+};
+#endif //SC_VBA_TEXTBOX_HXX
diff --git a/sc/source/ui/vba/vbatextframe.cxx b/sc/source/ui/vba/vbatextframe.cxx
new file mode 100644
index 000000000000..b06777526c1f
--- /dev/null
+++ b/sc/source/ui/vba/vbatextframe.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <vbahelper/helperdecl.hxx>
+#include <com/sun/star/drawing/TextFitToSizeType.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include "vbatextframe.hxx"
+#include "vbacharacters.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaTextFrame::ScVbaTextFrame( uno::Sequence< uno::Any> const & args, uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : ScVbaTextFrame_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext, getXSomethingFromArgs< drawing::XShape >( args, 1, false ) )
+{
+}
+
+// Methods
+uno::Any SAL_CALL
+ScVbaTextFrame::Characters() throw (uno::RuntimeException)
+{
+ uno::Reference< text::XSimpleText > xSimpleText( m_xShape, uno::UNO_QUERY_THROW );
+ ScVbaPalette aPalette( SfxObjectShell::Current() );
+ uno::Any aStart( sal_Int32( 1 ) );
+ uno::Any aLength(sal_Int32( -1 ) );
+ return uno::makeAny( uno::Reference< ov::excel::XCharacters >( new ScVbaCharacters( this, mxContext, aPalette, xSimpleText, aStart, aLength, sal_True ) ) );
+}
+
+rtl::OUString&
+ScVbaTextFrame::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaTextFrame") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaTextFrame::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.TextFrame" ) );
+ }
+ return aServiceNames;
+}
+
+namespace textframe
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaTextFrame, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaTextFrame",
+ "ooo.vba.excel.TextFrame" );
+}
diff --git a/sc/source/ui/vba/vbatextframe.hxx b/sc/source/ui/vba/vbatextframe.hxx
new file mode 100644
index 000000000000..b48cd8752ef9
--- /dev/null
+++ b/sc/source/ui/vba/vbatextframe.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_TEXTFRAME_HXX
+#define SC_VBA_TEXTFRAME_HXX
+#include <ooo/vba/excel/XTextFrame.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbatextframe.hxx>
+
+//typedef InheritedHelperInterfaceImpl1< ov::excel::XTextFrame > ScVbaTextFrame_BASE;
+typedef cppu::ImplInheritanceHelper1< VbaTextFrame, ov::excel::XTextFrame > ScVbaTextFrame_BASE;
+
+class ScVbaTextFrame : public ScVbaTextFrame_BASE
+{
+public:
+ ScVbaTextFrame( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext ) throw ( css::lang::IllegalArgumentException );
+ virtual ~ScVbaTextFrame() {}
+ // Methods
+ virtual css::uno::Any SAL_CALL Characters( ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+};
+
+#endif//SC_VBA_TEXTFRAME_HXX
diff --git a/sc/source/ui/vba/vbatitle.hxx b/sc/source/ui/vba/vbatitle.hxx
new file mode 100644
index 000000000000..fb97f3f20f0c
--- /dev/null
+++ b/sc/source/ui/vba/vbatitle.hxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_TITLE_HXX
+#define SC_VBA_TITLE_HXX
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include "excelvbahelper.hxx"
+#include "vbainterior.hxx"
+#include "vbafont.hxx"
+#include "vbapalette.hxx"
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XTitle.hpp>
+#include <ooo/vba/excel/XCharacters.hpp>
+#include <basic/sberrors.hxx>
+#include <memory>
+
+template< typename Ifc1 >
+class TitleImpl : public InheritedHelperInterfaceImpl< Ifc1 >
+{
+typedef InheritedHelperInterfaceImpl< Ifc1 > BaseClass;
+
+protected:
+ css::uno::Reference< css::drawing::XShape > xTitleShape;
+ css::uno::Reference< css::beans::XPropertySet > xShapePropertySet;
+ std::auto_ptr<ov::ShapeHelper> oShapeHelper;
+ ScVbaPalette m_Palette;
+public:
+ TitleImpl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& _xTitleShape ) : BaseClass( xParent, xContext ), xTitleShape( _xTitleShape )
+ {
+ xShapePropertySet.set( xTitleShape, css::uno::UNO_QUERY_THROW );
+ oShapeHelper.reset( new ov::ShapeHelper(xTitleShape) );
+ }
+ css::uno::Reference< ov::excel::XInterior > SAL_CALL Interior( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ // #TODO find out what the proper parent should be
+ // leaving as set by the helperapi for the moment
+ // #TODO we really need the ScDocument to pass to ScVbaInterior
+ // otherwise attemps to access the palette will fail
+ return new ScVbaInterior( BaseClass::mxParent, BaseClass::mxContext, xShapePropertySet );
+ }
+ css::uno::Reference< ov::excel::XFont > SAL_CALL Font( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ // #TODO find out what the proper parent should be
+ // leaving as set by the helperapi for the moment
+ return new ScVbaFont( BaseClass::mxParent, BaseClass::mxContext, m_Palette, xShapePropertySet );
+
+ }
+ void SAL_CALL setText( const ::rtl::OUString& Text ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ try
+ {
+ xShapePropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("String") ), css::uno::makeAny( Text ));
+ }
+ catch ( css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ }
+ ::rtl::OUString SAL_CALL getText( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ ::rtl::OUString sText;
+ try
+ {
+ xShapePropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("String") ) ) >>= sText;
+ }
+ catch ( css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return sText;
+ }
+
+ css::uno::Reference< ov::excel::XCharacters > SAL_CALL Characters( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ // #FIXME #TODO the helperapi Characters implementation doesn't
+ // seem to do very much, need to know how the existing Characters
+ // impl ( that we use for Range ) can be reused
+ return css::uno::Reference< ov::excel::XCharacters > ();
+ }
+
+ void SAL_CALL setTop( double Top ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ oShapeHelper->setTop( Top );
+ }
+ double SAL_CALL getTop( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ return oShapeHelper->getTop();
+ }
+ void SAL_CALL setLeft( double Left ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ oShapeHelper->setLeft( Left );
+ }
+ double SAL_CALL getLeft( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ return oShapeHelper->getLeft();
+ }
+ void SAL_CALL setOrientation( ::sal_Int32 _nOrientation ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ try
+ {
+ xShapePropertySet->setPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TextRotation")), css::uno::makeAny(_nOrientation*100));
+ }
+ catch (css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ }
+ ::sal_Int32 SAL_CALL getOrientation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+ {
+ sal_Int32 nSOOrientation = 0;
+ try
+ {
+ xShapePropertySet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TextRotation"))) >>= nSOOrientation;
+ }
+ catch (css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( rtl::OUString(), css::uno::Reference< css::uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
+ }
+ return static_cast< sal_Int32 >(nSOOrientation / 100) ;
+ }
+// XHelperInterface
+ rtl::OUString& getServiceImplName()
+ {
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("TitleImpl") );
+ return sImplName;
+ }
+ css::uno::Sequence< rtl::OUString > getServiceNames()
+ {
+ static css::uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.XTitle" ) );
+ }
+ return aServiceNames;
+ }
+};
+#endif
diff --git a/sc/source/ui/vba/vbavalidation.cxx b/sc/source/ui/vba/vbavalidation.cxx
new file mode 100644
index 000000000000..e2a768549e11
--- /dev/null
+++ b/sc/source/ui/vba/vbavalidation.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbavalidation.hxx"
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XlDVType.hpp>
+#include <ooo/vba/excel/XlFormatConditionOperator.hpp>
+#include <ooo/vba/excel/XlDVAlertStyle.hpp>
+
+#include "unonames.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const static rtl::OUString VALIDATION( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_VALIDAT ) );
+const static rtl::OUString IGNOREBLANK( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_IGNOREBL ) );
+const static rtl::OUString SHOWINPUT( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SHOWINP ) );
+const static rtl::OUString SHOWERROR( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SHOWERR ) );
+const static rtl::OUString ERRORTITLE( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ERRTITLE ) );
+const static rtl::OUString INPUTTITLE( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_INPTITLE ) );
+const static rtl::OUString INPUTMESS( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_INPMESS ) );
+const static rtl::OUString ERRORMESS( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ERRMESS ) );
+const static rtl::OUString STYPE( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_TYPE ) );
+const static rtl::OUString SHOWLIST( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SHOWLIST ) );
+const static rtl::OUString ALERTSTYLE( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ERRALSTY ) );
+
+void
+lcl_setValidationProps( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< beans::XPropertySet >& xProps )
+{
+ uno::Reference< beans::XPropertySet > xRangeProps( xRange, uno::UNO_QUERY_THROW );
+ xRangeProps->setPropertyValue( VALIDATION , uno::makeAny( xProps ) );
+}
+
+uno::Reference< beans::XPropertySet >
+lcl_getValidationProps( const uno::Reference< table::XCellRange >& xRange )
+{
+ uno::Reference< beans::XPropertySet > xProps( xRange, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xValProps;
+ xValProps.set( xProps->getPropertyValue( VALIDATION ), uno::UNO_QUERY_THROW );
+ return xValProps;
+}
+
+::sal_Bool SAL_CALL
+ScVbaValidation::getIgnoreBlank() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ sal_Bool bBlank = sal_False;
+ xProps->getPropertyValue( IGNOREBLANK ) >>= bBlank;
+ return bBlank;
+}
+
+void SAL_CALL
+ScVbaValidation::setIgnoreBlank( ::sal_Bool _ignoreblank ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( IGNOREBLANK, uno::makeAny( _ignoreblank ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::sal_Bool SAL_CALL
+ScVbaValidation::getInCellDropdown() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ sal_Int32 nShowList = 0;
+ xProps->getPropertyValue( SHOWLIST ) >>= nShowList;
+ return ( nShowList ? sal_True : sal_False );
+}
+
+void SAL_CALL
+ScVbaValidation::setInCellDropdown( ::sal_Bool _incelldropdown ) throw (uno::RuntimeException)
+{
+ sal_Int32 nDropDown = sal_False;
+ if ( _incelldropdown )
+ nDropDown = 1;
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps(m_xRange) );
+ xProps->setPropertyValue( SHOWLIST, uno::makeAny( nDropDown ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::sal_Bool SAL_CALL
+ScVbaValidation::getShowInput() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ sal_Bool bShowInput = sal_False;
+ xProps->getPropertyValue( SHOWINPUT ) >>= bShowInput;
+ return bShowInput;
+}
+
+void SAL_CALL
+ScVbaValidation:: setShowInput( ::sal_Bool _showinput ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps(m_xRange) );
+ xProps->setPropertyValue( IGNOREBLANK, uno::makeAny( _showinput ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::sal_Bool SAL_CALL
+ScVbaValidation::getShowError() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ sal_Bool bShowError = sal_False;
+ xProps->getPropertyValue( SHOWERROR ) >>= bShowError;
+ return bShowError;
+}
+
+void SAL_CALL
+ScVbaValidation::setShowError( ::sal_Bool _showerror ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SHOWERROR, uno::makeAny( _showerror ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaValidation::getErrorTitle() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ rtl::OUString sErrorTitle;
+ xProps->getPropertyValue( ERRORTITLE ) >>= sErrorTitle;
+ return sErrorTitle;
+}
+
+void
+ScVbaValidation::setErrorTitle( const rtl::OUString& _errormessage ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( ERRORTITLE, uno::makeAny( _errormessage ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaValidation::getInputMessage() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ rtl::OUString sMsg;
+ xProps->getPropertyValue( INPUTMESS ) >>= sMsg;
+ return sMsg;
+}
+
+void SAL_CALL
+ScVbaValidation::setInputMessage( const ::rtl::OUString& _inputmessage ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( INPUTMESS, uno::makeAny( _inputmessage ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaValidation::getInputTitle() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ rtl::OUString sString;
+ xProps->getPropertyValue( INPUTTITLE ) >>= sString;
+ return sString;
+}
+
+void SAL_CALL
+ScVbaValidation::setInputTitle( const ::rtl::OUString& _inputtitle ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( INPUTTITLE, uno::makeAny( _inputtitle ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaValidation::getErrorMessage() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ rtl::OUString sString;
+ xProps->getPropertyValue( ERRORMESS ) >>= sString;
+ return sString;
+}
+
+void SAL_CALL
+ScVbaValidation::setErrorMessage( const ::rtl::OUString& _errormessage ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( ERRORMESS, uno::makeAny( _errormessage ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+
+void SAL_CALL
+ScVbaValidation::Delete( ) throw (uno::RuntimeException)
+{
+ rtl::OUString sBlank;
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ uno::Reference< sheet::XSheetCondition > xCond( xProps, uno::UNO_QUERY_THROW );
+ xProps->setPropertyValue( IGNOREBLANK, uno::makeAny( sal_True ) );
+ xProps->setPropertyValue( SHOWINPUT, uno::makeAny( sal_True ) );
+ xProps->setPropertyValue( SHOWERROR, uno::makeAny( sal_True ) );
+ xProps->setPropertyValue( ERRORTITLE, uno::makeAny( sBlank ) );
+ xProps->setPropertyValue( INPUTMESS, uno::makeAny( sBlank) );
+ xProps->setPropertyValue( ALERTSTYLE, uno::makeAny( sheet::ValidationAlertStyle_STOP) );
+ xProps->setPropertyValue( STYPE, uno::makeAny( sheet::ValidationType_ANY ) );
+ xCond->setFormula1( sBlank );
+ xCond->setFormula2( sBlank );
+ xCond->setOperator( sheet::ConditionOperator_NONE );
+
+ lcl_setValidationProps( m_xRange, xProps );
+}
+void SAL_CALL
+ScVbaValidation::Add( const uno::Any& Type, const uno::Any& AlertStyle, const uno::Any& /*Operator*/, const uno::Any& Formula1, const uno::Any& Formula2 ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ uno::Reference< sheet::XSheetCondition > xCond( xProps, uno::UNO_QUERY_THROW );
+
+ sheet::ValidationType nValType = sheet::ValidationType_ANY;
+ xProps->getPropertyValue( STYPE ) >>= nValType;
+ if ( nValType != sheet::ValidationType_ANY )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "validation object already exists" ) ), uno::Reference< uno::XInterface >() );
+ sal_Int32 nType = -1;
+ if ( !Type.hasValue() || !( Type >>= nType ) )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "missing required param" ) ), uno::Reference< uno::XInterface >() );
+
+ Delete(); // set up defaults
+ rtl::OUString sFormula1;
+ Formula1 >>= sFormula1;
+ rtl::OUString sFormula2;
+ Formula2 >>= sFormula2;
+ switch ( nType )
+ {
+ case excel::XlDVType::xlValidateList:
+ {
+ // for validate list
+ // at least formula1 is required
+ if ( !Formula1.hasValue() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "missing param" ) ), uno::Reference< uno::XInterface >() );
+ nValType = sheet::ValidationType_LIST;
+ xProps->setPropertyValue( STYPE, uno::makeAny(nValType ));
+ // #TODO validate required params
+ // #TODO need to correct the ';' delimited formula on get/set
+ break;
+ }
+ case excel::XlDVType::xlValidateWholeNumber:
+ nValType = sheet::ValidationType_WHOLE;
+ xProps->setPropertyValue( STYPE, uno::makeAny(nValType ));
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unsupported operation..." ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ sheet::ValidationAlertStyle eStyle = sheet::ValidationAlertStyle_STOP;
+ sal_Int32 nVbaAlertStyle = excel::XlDVAlertStyle::xlValidAlertStop;
+ if ( AlertStyle.hasValue() && ( AlertStyle >>= nVbaAlertStyle ) )
+ {
+ switch( nVbaAlertStyle )
+ {
+ case excel::XlDVAlertStyle::xlValidAlertStop:
+ // yes I know it's already defaulted but safer to assume
+ // someone propbably could change the code above
+ eStyle = sheet::ValidationAlertStyle_STOP;
+ break;
+ case excel::XlDVAlertStyle::xlValidAlertWarning:
+ eStyle = sheet::ValidationAlertStyle_WARNING;
+ break;
+ case excel::XlDVAlertStyle::xlValidAlertInformation:
+ eStyle = sheet::ValidationAlertStyle_INFO;
+ break;
+ default:
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "bad param..." ) ), uno::Reference< uno::XInterface >() );
+
+ }
+ }
+
+ xProps->setPropertyValue( ALERTSTYLE, uno::makeAny( eStyle ) );
+
+ if ( sFormula1.getLength() )
+ xCond->setFormula1( sFormula1 );
+ if ( sFormula2.getLength() )
+ xCond->setFormula2( sFormula2 );
+
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+::rtl::OUString SAL_CALL
+ScVbaValidation::getFormula1() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCondition > xCond( lcl_getValidationProps( m_xRange ), uno::UNO_QUERY_THROW );
+ return xCond->getFormula1();
+}
+
+::rtl::OUString SAL_CALL
+ScVbaValidation::getFormula2() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCondition > xCond( lcl_getValidationProps( m_xRange ), uno::UNO_QUERY_THROW );
+ return xCond->getFormula2();
+}
+
+rtl::OUString&
+ScVbaValidation::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaValidation") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaValidation::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Validation" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbavalidation.hxx b/sc/source/ui/vba/vbavalidation.hxx
new file mode 100644
index 000000000000..563ee1d003b6
--- /dev/null
+++ b/sc/source/ui/vba/vbavalidation.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_VALIDATION_HXX
+#define SC_VBA_VALIDATION_HXX
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <ooo/vba/excel/XValidation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceImpl1<ov::excel::XValidation > ValidationImpl_BASE;
+
+class ScVbaValidation : public ValidationImpl_BASE
+{
+ css::uno::Reference< css::table::XCellRange > m_xRange;
+
+public:
+ ScVbaValidation( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange ) : ValidationImpl_BASE( xParent, xContext ), m_xRange( xRange) {}
+ // Attributes
+ virtual ::sal_Bool SAL_CALL getIgnoreBlank() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setIgnoreBlank( ::sal_Bool _ignoreblank ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getInCellDropdown() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setInCellDropdown( ::sal_Bool _incelldropdown ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getShowInput() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setShowInput( ::sal_Bool _showinput ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getShowError() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setShowError( ::sal_Bool _showerror ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getInputTitle() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setInputTitle( const ::rtl::OUString& _inputtitle ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getErrorTitle() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setErrorTitle( const ::rtl::OUString& _errortitle ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getInputMessage() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setInputMessage( const ::rtl::OUString& _inputmessage ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getErrorMessage() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setErrorMessage( const ::rtl::OUString& _errormessage ) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getFormula1() throw (css::uno::RuntimeException) ;
+ virtual ::rtl::OUString SAL_CALL getFormula2() throw (css::uno::RuntimeException);
+ // Methods
+ virtual void SAL_CALL Delete( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Add( const css::uno::Any& Type, const css::uno::Any& AlertStyle, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2 ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+};
+
+#endif
diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx
new file mode 100644
index 000000000000..10dad39341b7
--- /dev/null
+++ b/sc/source/ui/vba/vbawindow.cxx
@@ -0,0 +1,858 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vbahelper/helperdecl.hxx>
+#include "vbawindow.hxx"
+#include "vbaworksheets.hxx"
+#include "vbaworksheet.hxx"
+#include "vbaglobals.hxx"
+#include "vbapane.hxx"
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/view/DocumentZoomType.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <ooo/vba/excel/XlWindowState.hpp>
+#include <ooo/vba/excel/XlWindowView.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+
+#include <docsh.hxx>
+#include <tabvwsh.hxx>
+#include <docuno.hxx>
+#include <sc.hrc>
+#include <hash_map>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/wrkwin.hxx>
+#include "unonames.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlWindowState;
+
+typedef std::hash_map< rtl::OUString,
+SCTAB, ::rtl::OUStringHash,
+::std::equal_to< ::rtl::OUString > > NameIndexHash;
+
+typedef std::vector < uno::Reference< sheet::XSpreadsheet > > Sheets;
+
+typedef ::cppu::WeakImplHelper1< container::XEnumeration
+
+> Enumeration_BASE;
+
+typedef ::cppu::WeakImplHelper3< container::XEnumerationAccess
+ , com::sun::star::container::XIndexAccess
+ , com::sun::star::container::XNameAccess
+ > SelectedSheets_BASE;
+
+
+class SelectedSheetsEnum : public Enumeration_BASE
+{
+public:
+ uno::Reference< uno::XComponentContext > m_xContext;
+ Sheets m_sheets;
+ uno::Reference< frame::XModel > m_xModel;
+ Sheets::const_iterator m_it;
+
+ SelectedSheetsEnum( const uno::Reference< uno::XComponentContext >& xContext, const Sheets& sheets, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : m_xContext( xContext ), m_sheets( sheets ), m_xModel( xModel )
+ {
+ m_it = m_sheets.begin();
+ }
+ // XEnumeration
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return m_it != m_sheets.end();
+ }
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasMoreElements() )
+ {
+ throw container::NoSuchElementException();
+ }
+ // #FIXME needs ThisWorkbook as parent
+ return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( uno::Reference< XHelperInterface >(), m_xContext, *(m_it++), m_xModel ) ) );
+ }
+
+
+};
+
+class SelectedSheetsEnumAccess : public SelectedSheets_BASE
+{
+ uno::Reference< uno::XComponentContext > m_xContext;
+ NameIndexHash namesToIndices;
+ Sheets sheets;
+ uno::Reference< frame::XModel > m_xModel;
+public:
+ SelectedSheetsEnumAccess( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ):m_xContext( xContext ), m_xModel( xModel )
+ {
+ ScModelObj* pModel = static_cast< ScModelObj* >( m_xModel.get() );
+ if ( !pModel )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain current document" ) ), uno::Reference< uno::XInterface >() );
+ ScDocShell* pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
+ if ( !pDocShell )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain docshell" ) ), uno::Reference< uno::XInterface >() );
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( !pViewShell )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain view shell" ) ), uno::Reference< uno::XInterface >() );
+
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ uno::Sequence<sal_Int32> aSheets( nTabCount );
+ SCTAB nIndex = 0;
+ const ScMarkData& rMarkData = pViewShell->GetViewData()->GetMarkData();
+ sheets.reserve( nTabCount );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadSheet( m_xModel, uno::UNO_QUERY_THROW );
+ uno::Reference <container::XIndexAccess> xIndex( xSpreadSheet->getSheets(), uno::UNO_QUERY_THROW );
+ for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
+ {
+ if ( rMarkData.GetTableSelect(nTab) )
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet( xIndex->getByIndex( nTab ), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
+ sheets.push_back( xSheet );
+ namesToIndices[ xNamed->getName() ] = nIndex++;
+ }
+ }
+
+ }
+
+ //XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException)
+ {
+ return new SelectedSheetsEnum( m_xContext, sheets, m_xModel );
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
+ {
+ return sheets.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw ( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( Index < 0
+ || static_cast< Sheets::size_type >( Index ) >= sheets.size() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::makeAny( sheets[ Index ] );
+ }
+
+ //XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
+ {
+ return excel::XWorksheet::static_type(0);
+ }
+
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
+ {
+ return (sheets.size() > 0);
+ }
+
+ //XNameAccess
+ virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ if ( it == namesToIndices.end() )
+ throw container::NoSuchElementException();
+ return uno::makeAny( sheets[ it->second ] );
+
+ }
+
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
+ {
+ uno::Sequence< ::rtl::OUString > names( namesToIndices.size() );
+ ::rtl::OUString* pString = names.getArray();
+ NameIndexHash::const_iterator it = namesToIndices.begin();
+ NameIndexHash::const_iterator it_end = namesToIndices.end();
+ for ( ; it != it_end; ++it, ++pString )
+ *pString = it->first;
+ return names;
+ }
+
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ return (it != namesToIndices.end());
+ }
+
+
+};
+
+ScVbaWindow::ScVbaWindow( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : WindowImpl_BASE( xParent, xContext, xModel )
+{
+ init();
+}
+
+ScVbaWindow::ScVbaWindow( uno::Sequence< uno::Any > const & args, uno::Reference< uno::XComponentContext > const & xContext )
+ : WindowImpl_BASE( args, xContext )
+{
+ init();
+}
+
+void
+ScVbaWindow::init()
+{
+ /* This method is called from the constructor, thus the own refcount is
+ still zero. The implementation of ActivePane() uses a UNO reference of
+ this (to set this window as parent of the pane obejct). This requires
+ the own refcount to be non-zero, otherwise this instance will be
+ desctructed immediately! */
+ osl_incrementInterlockedCount( &m_refCount );
+ uno::Reference< frame::XController > xController( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ m_xViewPane.set( xController, uno::UNO_QUERY_THROW );
+ m_xViewFreezable.set( xController, uno::UNO_QUERY_THROW );
+ m_xViewSplitable.set( xController, uno::UNO_QUERY_THROW );
+ m_xPane.set( ActivePane(), uno::UNO_QUERY_THROW );
+ m_xDevice.set( xController->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW );
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+void
+ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll ) throw (uno::RuntimeException)
+{
+ if( bLargeScroll )
+ m_xPane->LargeScroll( Down, Up, ToRight, ToLeft );
+ else
+ m_xPane->SmallScroll( Down, Up, ToRight, ToLeft );
+}
+
+void SAL_CALL
+ScVbaWindow::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException)
+{
+ Scroll( Down, Up, ToRight, ToLeft );
+}
+
+void SAL_CALL
+ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException)
+{
+ Scroll( Down, Up, ToRight, ToLeft, true );
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::SelectedSheets( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( new SelectedSheetsEnumAccess( mxContext, m_xModel ) );
+ // #FIXME needs a workbook as a parent
+ uno::Reference< excel::XWorksheets > xSheets( new ScVbaWorksheets( uno::Reference< XHelperInterface >(), mxContext, xEnumAccess, m_xModel ) );
+ if ( aIndex.hasValue() )
+ {
+ uno::Reference< XCollection > xColl( xSheets, uno::UNO_QUERY_THROW );
+ return xColl->Item( aIndex, uno::Any() );
+ }
+ return uno::makeAny( xSheets );
+}
+
+void SAL_CALL
+ScVbaWindow::ScrollWorkbookTabs( const uno::Any& /*Sheets*/, const uno::Any& /*Position*/ ) throw (uno::RuntimeException)
+{
+// #TODO #FIXME need some implementation to scroll through the tabs
+// but where is this done?
+/*
+ sal_Int32 nSheets = 0;
+ sal_Int32 nPosition = 0;
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("No Implemented" ), uno::Reference< uno::XInterface >() );
+ sal_Bool bSheets = ( Sheets >>= nSheets );
+ sal_Bool bPosition = ( Position >>= nPosition );
+ if ( bSheets || bPosition ) // at least one param specified
+ if ( bSheets )
+ ;// use sheets
+ else if ( bPosition )
+ ; //use position
+*/
+
+}
+uno::Reference< beans::XPropertySet >
+getPropsFromModel( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< frame::XController > xController = xModel->getCurrentController();
+ if ( !xController.is() )
+ throw uno::RuntimeException( rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM ("No controller for model") ), uno::Reference< uno::XInterface >() );
+ return uno::Reference< beans::XPropertySet >( xController->getFrame(), uno::UNO_QUERY );
+}
+
+
+uno::Any SAL_CALL
+ScVbaWindow::getCaption() throw (uno::RuntimeException)
+{
+ static rtl::OUString sCrud(RTL_CONSTASCII_USTRINGPARAM(" - OpenOffice.org Calc" ) );
+ static sal_Int32 nCrudLen = sCrud.getLength();
+
+ uno::Reference< beans::XPropertySet > xProps = getPropsFromModel( m_xModel );
+ rtl::OUString sTitle;
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SC_UNONAME_TITLE ) ) ) >>= sTitle;
+ sal_Int32 nCrudIndex = sTitle.indexOf( sCrud );
+ // adjust title ( by removing crud )
+ // sCrud string present
+ if ( nCrudIndex != -1 )
+ {
+ // and ends with sCrud
+ if ( ( nCrudLen + nCrudIndex ) == sTitle.getLength() )
+ {
+ sTitle = sTitle.copy( 0, nCrudIndex );
+ ScVbaWorkbook workbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel );
+ rtl::OUString sName = workbook.getName();
+ // rather bizare hack to make sure the name behavior
+ // is like XL
+ // if the adjusted title == workbook name, use name
+ // if the adjusted title != workbook name but ...
+ // name == title + extension ( .csv, ,odt, .xls )
+ // etc. then also use the name
+
+ if ( !sTitle.equals( sName ) )
+ {
+ static rtl::OUString sDot( RTL_CONSTASCII_USTRINGPARAM(".") );
+ // starts with title
+ if ( sName.indexOf( sTitle ) == 0 )
+ // extention starts immediately after
+ if ( sName.match( sDot, sTitle.getLength() ) )
+ sTitle = sName;
+ }
+ }
+ }
+ return uno::makeAny( sTitle );
+}
+
+void SAL_CALL
+ScVbaWindow::setCaption( const uno::Any& _caption ) throw (uno::RuntimeException)
+{
+
+ uno::Reference< beans::XPropertySet > xProps = getPropsFromModel( m_xModel );
+ xProps->setPropertyValue( rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM ( SC_UNONAME_TITLE ) ) , _caption );
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getScrollRow() throw (uno::RuntimeException)
+{
+ sal_Int32 nValue = 0;
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
+ nValue = pViewShell->GetViewData()->GetPosY(WhichV(eWhich));
+ }
+
+ return uno::makeAny( nValue + 1);
+}
+
+void SAL_CALL
+ScVbaWindow::setScrollRow( const uno::Any& _scrollrow ) throw (uno::RuntimeException)
+{
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ sal_Int32 scrollRow = 0;
+ _scrollrow >>= scrollRow;
+ ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
+ sal_Int32 nOldValue = pViewShell->GetViewData()->GetPosY(WhichV(eWhich)) + 1;
+ pViewShell->ScrollLines(0, scrollRow - nOldValue);
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getScrollColumn() throw (uno::RuntimeException)
+{
+ sal_Int32 nValue = 0;
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
+ nValue = pViewShell->GetViewData()->GetPosX(WhichH(eWhich));
+ }
+
+ return uno::makeAny( nValue + 1);
+}
+
+void SAL_CALL
+ScVbaWindow::setScrollColumn( const uno::Any& _scrollcolumn ) throw (uno::RuntimeException)
+{
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ sal_Int32 scrollColumn = 0;
+ _scrollcolumn >>= scrollColumn;
+ ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
+ sal_Int32 nOldValue = pViewShell->GetViewData()->GetPosX(WhichH(eWhich)) + 1;
+ pViewShell->ScrollLines(scrollColumn - nOldValue, 0);
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getWindowState() throw (uno::RuntimeException)
+{
+ sal_Int32 nwindowState = xlNormal;
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame();
+ WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow();
+ if ( pWork )
+ {
+ if ( pWork -> IsMaximized())
+ nwindowState = xlMaximized;
+ else if (pWork -> IsMinimized())
+ nwindowState = xlMinimized;
+ }
+ return uno::makeAny( nwindowState );
+}
+
+void SAL_CALL
+ScVbaWindow::setWindowState( const uno::Any& _windowstate ) throw (uno::RuntimeException)
+{
+ sal_Int32 nwindowState = xlMaximized;
+ _windowstate >>= nwindowState;
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame();
+ WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow();
+ if ( pWork )
+ {
+ if ( nwindowState == xlMaximized)
+ pWork -> Maximize();
+ else if (nwindowState == xlMinimized)
+ pWork -> Minimize();
+ else if (nwindowState == xlNormal)
+ pWork -> Restore();
+ else
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Invalid Parameter" ) ), uno::Reference< uno::XInterface >() );
+ }
+}
+
+void
+ScVbaWindow::Activate() throw (css::uno::RuntimeException)
+{
+ ScVbaWorkbook workbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel );
+
+ workbook.Activate();
+}
+
+void
+ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Any& RouteWorkBook ) throw (uno::RuntimeException)
+{
+ ScVbaWorkbook workbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel );
+ workbook.Close(SaveChanges, FileName, RouteWorkBook );
+}
+
+uno::Reference< excel::XPane > SAL_CALL
+ScVbaWindow::ActivePane() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ return new ScVbaPane( this, mxContext, m_xModel, m_xViewPane );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaWindow::ActiveCell( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getActiveCell();
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::Selection( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getSelection();
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaWindow::RangeSelection() throw (script::BasicErrorException, uno::RuntimeException)
+{
+ /* TODO / FIXME: According to documentation, this method returns the range
+ selection even if shapes are selected. */
+ return uno::Reference< excel::XRange >( Selection(), uno::UNO_QUERY_THROW );
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWGRID ) );
+ sal_Bool bGrid = sal_True;
+ xProps->getPropertyValue( sName ) >>= bGrid;
+ return bGrid;
+}
+
+
+void SAL_CALL
+ScVbaWindow::setDisplayGridlines( ::sal_Bool _displaygridlines ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWGRID ) );
+ xProps->setPropertyValue( sName, uno::makeAny( _displaygridlines ));
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getDisplayHeadings() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLROWHDR ) );
+ sal_Bool bHeading = sal_True;
+ xProps->getPropertyValue( sName ) >>= bHeading;
+ return bHeading;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayHeadings( ::sal_Bool _bDisplayHeadings ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLROWHDR ) );
+ xProps->setPropertyValue( sName, uno::makeAny( _bDisplayHeadings ));
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getDisplayHorizontalScrollBar() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_HORSCROLL ) );
+ sal_Bool bHorizontalScrollBar = sal_True;
+ xProps->getPropertyValue( sName ) >>= bHorizontalScrollBar;
+ return bHorizontalScrollBar;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayHorizontalScrollBar( ::sal_Bool _bDisplayHorizontalScrollBar ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_HORSCROLL ) );
+ xProps->setPropertyValue( sName, uno::makeAny( _bDisplayHorizontalScrollBar ));
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getDisplayOutline() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_OUTLSYMB ) );
+ sal_Bool bOutline = sal_True;
+ xProps->getPropertyValue( sName ) >>= bOutline;
+ return bOutline;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayOutline( ::sal_Bool _bDisplayOutline ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_OUTLSYMB ) );
+ xProps->setPropertyValue( sName, uno::makeAny( _bDisplayOutline ));
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getDisplayVerticalScrollBar() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VERTSCROLL ) );
+ sal_Bool bVerticalScrollBar = sal_True;
+ xProps->getPropertyValue( sName ) >>= bVerticalScrollBar;
+ return bVerticalScrollBar;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayVerticalScrollBar( ::sal_Bool _bDisplayVerticalScrollBar ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VERTSCROLL ) );
+ xProps->setPropertyValue( sName, uno::makeAny( _bDisplayVerticalScrollBar ));
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getDisplayWorkbookTabs() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHEETTABS ) );
+ sal_Bool bWorkbookTabs = sal_True;
+ xProps->getPropertyValue( sName ) >>= bWorkbookTabs;
+ return bWorkbookTabs;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayWorkbookTabs( ::sal_Bool _bDisplayWorkbookTabs ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHEETTABS ) );
+ xProps->setPropertyValue( sName, uno::makeAny( _bDisplayWorkbookTabs ));
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getFreezePanes() throw (uno::RuntimeException)
+{
+ return m_xViewFreezable->hasFrozenPanes();
+}
+
+void SAL_CALL
+ScVbaWindow::setFreezePanes( ::sal_Bool /*_bFreezePanes*/ ) throw (uno::RuntimeException)
+{
+ if( m_xViewSplitable->getIsWindowSplit() )
+ {
+ // if there is a split we freeze at the split
+ sal_Int32 nColumn = getSplitColumn();
+ sal_Int32 nRow = getSplitRow();
+ m_xViewFreezable->freezeAtPosition( nColumn, nRow );
+ }
+ else
+ {
+ // otherwise we freeze in the center of the visible sheet
+ table::CellRangeAddress aCellRangeAddress = m_xViewPane->getVisibleRange();
+ sal_Int32 nColumn = aCellRangeAddress.StartColumn + (( aCellRangeAddress.EndColumn - aCellRangeAddress.StartColumn )/2 );
+ sal_Int32 nRow = aCellRangeAddress.StartRow + (( aCellRangeAddress.EndRow - aCellRangeAddress.StartRow )/2 );
+ m_xViewFreezable->freezeAtPosition( nColumn, nRow );
+ }
+}
+
+::sal_Bool SAL_CALL
+ScVbaWindow::getSplit() throw (uno::RuntimeException)
+{
+ return m_xViewSplitable->getIsWindowSplit();
+}
+
+void SAL_CALL
+ScVbaWindow::setSplit( ::sal_Bool _bSplit ) throw (uno::RuntimeException)
+{
+ if( !_bSplit )
+ {
+ m_xViewSplitable->splitAtPosition(0,0);
+ }
+ else
+ {
+ uno::Reference< excel::XRange > xRange = ActiveCell();
+ sal_Int32 nRow = xRange->getRow();
+ sal_Int32 nColumn = xRange->getColumn();
+ m_xViewFreezable->freezeAtPosition( nColumn-1, nRow-1 );
+ SplitAtDefinedPosition( sal_True );
+ }
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::getSplitColumn() throw (uno::RuntimeException)
+{
+ return m_xViewSplitable->getSplitColumn();
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitColumn( sal_Int32 _splitcolumn ) throw (uno::RuntimeException)
+{
+ if( getSplitColumn() != _splitcolumn )
+ {
+ sal_Bool bFrozen = getFreezePanes();
+ sal_Int32 nRow = getSplitRow();
+ m_xViewFreezable->freezeAtPosition( _splitcolumn, nRow );
+ SplitAtDefinedPosition( !bFrozen );
+ }
+}
+
+double SAL_CALL
+ScVbaWindow::getSplitHorizontal() throw (uno::RuntimeException)
+{
+ double fSplitHorizontal = m_xViewSplitable->getSplitHorizontal();
+ double fHoriPoints = PixelsToPoints( m_xDevice, fSplitHorizontal, sal_True );
+ return fHoriPoints;
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitHorizontal( double _splithorizontal ) throw (uno::RuntimeException)
+{
+ double fHoriPixels = PointsToPixels( m_xDevice, _splithorizontal, sal_True );
+ m_xViewSplitable->splitAtPosition( static_cast<sal_Int32>( fHoriPixels ), 0 );
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::getSplitRow() throw (uno::RuntimeException)
+{
+ sal_Int32 nValue = m_xViewSplitable->getSplitRow();
+ return nValue ? nValue - 1 : nValue;
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitRow( sal_Int32 _splitrow ) throw (uno::RuntimeException)
+{
+ if( getSplitRow() != _splitrow )
+ {
+ sal_Bool bFrozen = getFreezePanes();
+ sal_Int32 nColumn = getSplitColumn();
+ m_xViewFreezable->freezeAtPosition( nColumn , _splitrow );
+ SplitAtDefinedPosition( !bFrozen );
+ }
+}
+
+double SAL_CALL
+ScVbaWindow::getSplitVertical() throw (uno::RuntimeException)
+{
+ double fSplitVertical = m_xViewSplitable->getSplitVertical();
+ double fVertiPoints = PixelsToPoints( m_xDevice, fSplitVertical, sal_False );
+ return fVertiPoints;
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitVertical(double _splitvertical ) throw (uno::RuntimeException)
+{
+ double fVertiPixels = PointsToPixels( m_xDevice, _splitvertical, sal_False );
+ m_xViewSplitable->splitAtPosition( 0, static_cast<sal_Int32>( fVertiPixels ) );
+}
+
+void ScVbaWindow::SplitAtDefinedPosition(sal_Bool _bUnFreezePane)
+{
+ sal_Int32 nVertSplit = m_xViewSplitable->getSplitVertical();
+ sal_Int32 nHoriSplit = m_xViewSplitable->getSplitHorizontal();
+ if( _bUnFreezePane )
+ {
+ m_xViewFreezable->freezeAtPosition(0,0);
+ }
+ m_xViewSplitable->splitAtPosition(nHoriSplit, nVertSplit);
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getZoom() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ZOOMTYPE ) );
+ sal_Int16 nZoomType = view::DocumentZoomType::PAGE_WIDTH;
+ xProps->getPropertyValue( sName ) >>= nZoomType;
+ if( nZoomType == view::DocumentZoomType::PAGE_WIDTH )
+ {
+ return uno::makeAny( sal_True );
+ }
+ else if( nZoomType == view::DocumentZoomType::BY_VALUE )
+ {
+ sName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ZOOMVALUE));
+ sal_Int16 nZoom = 100;
+ xProps->getPropertyValue( sName ) >>= nZoom;
+ return uno::makeAny( nZoom );
+ }
+ return uno::Any();
+}
+
+void SAL_CALL
+ScVbaWindow::setZoom( const uno::Any& _zoom ) throw (uno::RuntimeException)
+{
+ sal_Int16 nZoom = 100;
+ _zoom >>= nZoom;
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( m_xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XWorksheet > xActiveSheet = ActiveSheet();
+ SCTAB nTab = 0;
+ if ( !ScVbaWorksheets::nameExists (xSpreadDoc, xActiveSheet->getName(), nTab) )
+ throw uno::RuntimeException();
+ std::vector< SCTAB > vTabs;
+ vTabs.push_back( nTab );
+ excel::implSetZoom( m_xModel, nZoom, vTabs );
+}
+
+uno::Reference< excel::XWorksheet > SAL_CALL
+ScVbaWindow::ActiveSheet( ) throw (script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getActiveSheet();
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getView() throw (uno::RuntimeException)
+{
+ // not supported now
+ sal_Int32 nWindowView = excel::XlWindowView::xlNormalView;
+ return uno::makeAny( nWindowView );
+}
+
+void SAL_CALL
+ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException)
+{
+ sal_Int32 nWindowView = excel::XlWindowView::xlNormalView;
+ _view >>= nWindowView;
+ USHORT nSlot = FID_NORMALVIEWMODE;
+ switch ( nWindowView )
+ {
+ case excel::XlWindowView::xlNormalView:
+ nSlot = FID_NORMALVIEWMODE;
+ break;
+ case excel::XlWindowView::xlPageBreakPreview:
+ nSlot = FID_PAGEBREAKMODE;
+ break;
+ default:
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ dispatchExecute( pViewShell, nSlot );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaWindow::getVisibleRange() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XIndexAccess > xPanesIA( m_xViewPane, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) );
+ return xPane->getVisibleRange();
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points );
+ double fConvertFactor = (m_xDevice->getInfo().PixelPerMeterX/100000);
+ return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters );
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points );
+ double fConvertFactor = (m_xDevice->getInfo().PixelPerMeterY/100000);
+ return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters );
+}
+
+void SAL_CALL
+ScVbaWindow::PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ // need test, print current active sheet
+ PrintOutHelper( excel::getBestViewShell( m_xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, sal_True );
+}
+
+void SAL_CALL
+ScVbaWindow::PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ // need test, print preview current active sheet
+ PrintPreviewHelper( EnableChanges, excel::getBestViewShell( m_xModel ) );
+}
+
+rtl::OUString&
+ScVbaWindow::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWindow") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaWindow::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Window" ) );
+ }
+ return aServiceNames;
+}
+namespace window
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaWindow, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaWindow",
+ "ooo.vba.excel.Window" );
+}
diff --git a/sc/source/ui/vba/vbawindow.hxx b/sc/source/ui/vba/vbawindow.hxx
new file mode 100644
index 000000000000..d58d2a07cb4b
--- /dev/null
+++ b/sc/source/ui/vba/vbawindow.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_WINDOW_HXX
+#define SC_VBA_WINDOW_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XWindow.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XViewPane.hpp>
+#include <com/sun/star/sheet/XViewFreezable.hpp>
+#include <com/sun/star/sheet/XViewSplitable.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <ooo/vba/excel/XPane.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbawindowbase.hxx>
+#include "vbaworkbook.hxx"
+
+typedef cppu::ImplInheritanceHelper1< VbaWindowBase, ov::excel::XWindow > WindowImpl_BASE;
+
+class ScVbaWindow : public WindowImpl_BASE
+{
+private:
+ css::uno::Reference< css::sheet::XViewPane > m_xViewPane;
+ css::uno::Reference< css::sheet::XViewFreezable > m_xViewFreezable;
+ css::uno::Reference< css::sheet::XViewSplitable > m_xViewSplitable;
+ css::uno::Reference< ov::excel::XPane > m_xPane;
+ css::uno::Reference< css::awt::XDevice > m_xDevice;
+ void init();
+protected:
+ void SplitAtDefinedPosition(sal_Bool _bUnFreezePane);
+public:
+ void Scroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft, bool bLargeScroll = false ) throw (css::uno::RuntimeException);
+public:
+ ScVbaWindow( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+ ScVbaWindow( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext );
+
+ // XWindow
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL ActiveCell( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XPane > SAL_CALL ActivePane() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL ActiveSheet( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL setCaption( const css::uno::Any& _caption ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getCaption() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayGridlines() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayGridlines( ::sal_Bool _displaygridlines ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayHeadings() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayHeadings( ::sal_Bool _bDisplayHeadings ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayHorizontalScrollBar() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayHorizontalScrollBar( ::sal_Bool _bDisplayHorizontalScrollBar ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayOutline() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayOutline( ::sal_Bool _bDisplayOutline ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayVerticalScrollBar() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayVerticalScrollBar( ::sal_Bool _bDisplayVerticalScrollBar ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getDisplayWorkbookTabs() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDisplayWorkbookTabs( ::sal_Bool _bDisplayWorkbookTabs ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getFreezePanes() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setFreezePanes( ::sal_Bool _bFreezePanes ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getSplit() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setSplit( ::sal_Bool _bSplit ) throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getSplitColumn() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setSplitColumn( sal_Int32 _splitcolumn ) throw (css::uno::RuntimeException) ;
+ virtual double SAL_CALL getSplitHorizontal() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setSplitHorizontal( double _splithorizontal ) throw (css::uno::RuntimeException) ;
+ virtual sal_Int32 SAL_CALL getSplitRow() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setSplitRow( sal_Int32 _splitrow ) throw (css::uno::RuntimeException) ;
+ virtual double SAL_CALL getSplitVertical() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setSplitVertical( double _splitvertical ) throw (css::uno::RuntimeException) ;
+ virtual css::uno::Any SAL_CALL getScrollRow() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setScrollRow( const css::uno::Any& _scrollrow ) throw (css::uno::RuntimeException) ;
+ virtual css::uno::Any SAL_CALL getScrollColumn() throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL setScrollColumn( const css::uno::Any& _scrollcolumn ) throw (css::uno::RuntimeException) ;
+ virtual css::uno::Any SAL_CALL getView() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setView( const css::uno::Any& _view ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getWindowState() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getZoom() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setZoom( const css::uno::Any& _zoom ) throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL SelectedSheets( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL ScrollWorkbookTabs( const css::uno::Any& Sheets, const css::uno::Any& Position ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Activate( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& FileName, const css::uno::Any& RouteWorkBook ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL RangeSelection() throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_WINDOW_HXX
diff --git a/sc/source/ui/vba/vbawindows.cxx b/sc/source/ui/vba/vbawindows.cxx
new file mode 100644
index 000000000000..3ddc5f5b3b45
--- /dev/null
+++ b/sc/source/ui/vba/vbawindows.cxx
@@ -0,0 +1,260 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "vbawindows.hxx"
+
+#include <hash_map>
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <cppuhelper/implbase3.hxx>
+
+#include <tools/urlobj.hxx>
+#include "vbawindow.hxx"
+#include "vbaglobals.hxx"
+//#include "vbaworkbook.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+typedef std::hash_map< rtl::OUString,
+sal_Int32, ::rtl::OUStringHash,
+::std::equal_to< ::rtl::OUString > > NameIndexHash;
+
+
+uno::Reference< XHelperInterface > lcl_createWorkbookHIParent( const uno::Reference< frame::XModel >& xModel, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication )
+{
+ return new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel );
+}
+
+uno::Any ComponentToWindow( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Any& aApplication )
+{
+ uno::Reference< frame::XModel > xModel( aSource, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XWindow > xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel, xContext, aApplication ), xContext,xModel ) );
+ return uno::makeAny( xWin );
+}
+
+typedef std::vector < uno::Reference< sheet::XSpreadsheetDocument > > Components;
+// #TODO more or less the same as class in workwindows ( code sharing needed )
+class WindowComponentEnumImpl : public EnumerationHelper_BASE
+{
+protected:
+ uno::Reference< uno::XComponentContext > m_xContext;
+ Components m_components;
+ Components::const_iterator m_it;
+
+public:
+ WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const Components& components ) throw ( uno::RuntimeException ) : m_xContext( xContext ), m_components( components )
+ {
+ m_it = m_components.begin();
+ }
+
+ WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::RuntimeException ) : m_xContext( xContext )
+ {
+ uno::Reference< lang::XMultiComponentFactory > xSMgr(
+ m_xContext->getServiceManager(), uno::UNO_QUERY_THROW );
+
+ uno::Reference< frame::XDesktop > xDesktop
+ (xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"), m_xContext), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > mxComponents = xDesktop->getComponents()->createEnumeration();
+ while( mxComponents->hasMoreElements() )
+ {
+ uno::Reference< sheet::XSpreadsheetDocument > xNext( mxComponents->nextElement(), uno::UNO_QUERY );
+ if ( xNext.is() )
+ m_components.push_back( xNext );
+ }
+ m_it = m_components.begin();
+ }
+ // XEnumeration
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return m_it != m_components.end();
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasMoreElements() )
+ {
+ throw container::NoSuchElementException();
+ }
+ return makeAny( *(m_it++) );
+ }
+};
+
+class WindowEnumImpl : public WindowComponentEnumImpl
+{
+ uno::Any m_aApplication;
+public:
+ WindowEnumImpl(const uno::Reference< uno::XComponentContext >& xContext, const Components& components, const uno::Any& aApplication ):WindowComponentEnumImpl( xContext, components ), m_aApplication( aApplication ){}
+ WindowEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication ): WindowComponentEnumImpl( xContext ), m_aApplication( aApplication ) {}
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ return ComponentToWindow( WindowComponentEnumImpl::nextElement(), m_xContext, m_aApplication );
+ }
+};
+
+typedef ::cppu::WeakImplHelper3< container::XEnumerationAccess
+ , com::sun::star::container::XIndexAccess
+ , com::sun::star::container::XNameAccess
+ > WindowsAccessImpl_BASE;
+
+class WindowsAccessImpl : public WindowsAccessImpl_BASE
+{
+ uno::Reference< uno::XComponentContext > m_xContext;
+ Components m_windows;
+ NameIndexHash namesToIndices;
+public:
+ WindowsAccessImpl( const uno::Reference< uno::XComponentContext >& xContext ):m_xContext( xContext )
+ {
+ uno::Reference< container::XEnumeration > xEnum = new WindowComponentEnumImpl( m_xContext );
+ sal_Int32 nIndex=0;
+ while( xEnum->hasMoreElements() )
+ {
+ uno::Reference< sheet::XSpreadsheetDocument > xNext( xEnum->nextElement(), uno::UNO_QUERY );
+ if ( xNext.is() )
+ {
+ m_windows.push_back( xNext );
+ uno::Reference< frame::XModel > xModel( xNext, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given
+ uno::Reference< XHelperInterface > xTemp; // temporary needed for g++ 3.3.5
+ ScVbaWindow window( xTemp, m_xContext, xModel );
+ rtl::OUString sCaption;
+ window.getCaption() >>= sCaption;
+ namesToIndices[ sCaption ] = nIndex++;
+ }
+ }
+
+ }
+
+ //XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException)
+ {
+ return new WindowComponentEnumImpl( m_xContext, m_windows );
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
+ {
+ return m_windows.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw ( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( Index < 0
+ || static_cast< Components::size_type >( Index ) >= m_windows.size() )
+ throw lang::IndexOutOfBoundsException();
+ return makeAny( m_windows[ Index ] ); // returns xspreadsheetdoc
+ }
+
+ //XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
+ {
+ return sheet::XSpreadsheetDocument::static_type(0);
+ }
+
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
+ {
+ return (m_windows.size() > 0);
+ }
+
+ //XNameAccess
+ virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ if ( it == namesToIndices.end() )
+ throw container::NoSuchElementException();
+ return makeAny( m_windows[ it->second ] );
+
+ }
+
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
+ {
+ uno::Sequence< ::rtl::OUString > names( namesToIndices.size() );
+ ::rtl::OUString* pString = names.getArray();
+ NameIndexHash::const_iterator it = namesToIndices.begin();
+ NameIndexHash::const_iterator it_end = namesToIndices.end();
+ for ( ; it != it_end; ++it, ++pString )
+ *pString = it->first;
+ return names;
+ }
+
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ return (it != namesToIndices.end());
+ }
+
+};
+
+
+ScVbaWindows::ScVbaWindows( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ): ScVbaWindows_BASE( xParent, xContext, xIndexAccess )
+{
+}
+
+ScVbaWindows::ScVbaWindows( const uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : ScVbaWindows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess > ( new WindowsAccessImpl( xContext ) ) )
+{
+}
+uno::Reference< container::XEnumeration >
+ScVbaWindows::createEnumeration() throw (uno::RuntimeException)
+{
+ return new WindowEnumImpl( mxContext, Application() );
+}
+
+uno::Any
+ScVbaWindows::createCollectionObject( const css::uno::Any& aSource )
+{
+ return ComponentToWindow( aSource, mxContext, Application() );
+}
+
+uno::Type
+ScVbaWindows::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XWindows::static_type(0);
+}
+
+
+void SAL_CALL
+ScVbaWindows::Arrange( ::sal_Int32 /*ArrangeStyle*/, const uno::Any& /*ActiveWorkbook*/, const uno::Any& /*SyncHorizontal*/, const uno::Any& /*SyncVertical*/ ) throw (uno::RuntimeException)
+{
+ //#TODO #FIXME see what can be done for an implementation here
+}
+
+
+rtl::OUString&
+ScVbaWindows::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWindows") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaWindows::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Windows") );
+ }
+ return sNames;
+}
diff --git a/sc/source/ui/vba/vbawindows.hxx b/sc/source/ui/vba/vbawindows.hxx
new file mode 100644
index 000000000000..3441b6ccbac4
--- /dev/null
+++ b/sc/source/ui/vba/vbawindows.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_WINDOWS_HXX
+#define SC_VBA_WINDOWS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <ooo/vba/excel/XWindows.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include "excelvbahelper.hxx"
+#include <vbahelper/vbacollectionimpl.hxx>
+
+
+typedef CollTestImplHelper< ov::excel::XWindows > ScVbaWindows_BASE;
+
+class ScVbaWindows : public ScVbaWindows_BASE
+{
+public:
+ ScVbaWindows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+ ScVbaWindows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext );
+ virtual ~ScVbaWindows() {}
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+
+ // XWindows
+ virtual void SAL_CALL Arrange( ::sal_Int32 ArrangeStyle, const css::uno::Any& ActiveWorkbook, const css::uno::Any& SyncHorizontal, const css::uno::Any& SyncVertical ) throw (::com::sun::star::uno::RuntimeException);
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif //SC_VBA_WINDOWS_HXX
+
diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx
new file mode 100644
index 000000000000..28469c4685a2
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbook.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <vbahelper/helperdecl.hxx>
+#include <tools/urlobj.hxx>
+#include <comphelper/unwrapargs.hxx>
+
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XlFileFormat.hpp>
+
+#include "scextopt.hxx"
+#include "vbaworksheet.hxx"
+#include "vbaworksheets.hxx"
+#include "vbaworkbook.hxx"
+#include "vbawindows.hxx"
+#include "vbastyles.hxx"
+#include "excelvbahelper.hxx"
+#include "vbapalette.hxx"
+#include <osl/file.hxx>
+#include <stdio.h>
+#include "vbanames.hxx" // Amelia Wang
+#include "nameuno.hxx"
+#include "docoptio.hxx"
+#include "unonames.hxx"
+
+// Much of the impl. for the equivalend UNO module is
+// sc/source/ui/unoobj/docuno.cxx, viewuno.cxx
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+class ActiveSheet : public ScVbaWorksheet
+{
+protected:
+ virtual uno::Reference< frame::XModel > getModel()
+ {
+ return getCurrentExcelDoc( mxContext );
+ }
+ virtual uno::Reference< sheet::XSpreadsheet > getSheet()
+ {
+ uno::Reference< frame::XModel > xModel = getModel();
+ uno::Reference< sheet::XSpreadsheet > xSheet;
+ if ( xModel.is() )
+ {
+ uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
+ xModel->getCurrentController(), uno::UNO_QUERY );
+ if ( xSpreadsheet.is() )
+ xSheet = xSpreadsheet->getActiveSheet();
+ }
+ return xSheet;
+ }
+public:
+ ActiveSheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : ScVbaWorksheet( xParent, xContext ) {}
+
+};
+
+uno::Sequence< sal_Int32 > ScVbaWorkbook::ColorData;
+
+void ScVbaWorkbook::initColorData( const uno::Sequence< sal_Int32 >& sColors )
+{
+ const sal_Int32* pSource = sColors.getConstArray();
+ sal_Int32* pDest = ColorData.getArray();
+ const sal_Int32* pEnd = pSource + sColors.getLength();
+ for ( ; pSource != pEnd; ++pSource, ++pDest )
+ *pDest = *pSource;
+}
+
+
+void SAL_CALL
+ScVbaWorkbook::ResetColors( ) throw (::script::BasicErrorException, ::uno::RuntimeException)
+{
+ uno::Reference< container::XIndexAccess > xIndexAccess( ScVbaPalette::getDefaultPalette(), uno::UNO_QUERY_THROW );
+ sal_Int32 nLen = xIndexAccess->getCount();
+ ColorData.realloc( nLen );
+
+ uno::Sequence< sal_Int32 > dDefaultColors( nLen );
+ sal_Int32* pDest = dDefaultColors.getArray();
+ for ( sal_Int32 index=0; index < nLen; ++pDest, ++index )
+ xIndexAccess->getByIndex( index ) >>= (*pDest);
+ initColorData( dDefaultColors );
+}
+
+::uno::Any SAL_CALL
+ScVbaWorkbook::Colors( const ::uno::Any& Index ) throw (::script::BasicErrorException, ::uno::RuntimeException)
+{
+ uno::Any aRet;
+ if ( Index.getValue() )
+ {
+ sal_Int32 nIndex = 0;
+ Index >>= nIndex;
+ aRet = uno::makeAny( XLRGBToOORGB( ColorData[ --nIndex ] ) );
+ }
+ else
+ aRet = uno::makeAny( ColorData );
+ return aRet;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaWorkbook::FileFormat( ) throw (::script::BasicErrorException, ::uno::RuntimeException)
+{
+ sal_Int32 aFileFormat = 0;
+ rtl::OUString aFilterName;
+ uno::Sequence< beans::PropertyValue > aArgs = getModel()->getArgs();
+
+ // #FIXME - seems suspect should we not walk through the properties
+ // to find the FilterName
+ if (aArgs[0].Name.equalsAscii( "FilterName")) {
+ aArgs[0].Value >>= aFilterName;
+ } else {
+ aArgs[1].Value >>= aFilterName;
+ }
+
+ if (aFilterName.equalsAscii("Text - txt - csv (StarCalc)")) {
+ aFileFormat = excel::XlFileFormat::xlCSV; //xlFileFormat.
+ }
+
+ if (aFilterName.equalsAscii("DBF")) {
+ aFileFormat = excel::XlFileFormat::xlDBF4;
+ }
+
+ if (aFilterName.equalsAscii("DIF")) {
+ aFileFormat = excel::XlFileFormat::xlDIF;
+ }
+
+ if (aFilterName.equalsAscii("Lotus")) {
+ aFileFormat = excel::XlFileFormat::xlWK3;
+ }
+
+ if (aFilterName.equalsAscii("MS Excel 4.0")) {
+ aFileFormat = excel::XlFileFormat::xlExcel4Workbook;
+ }
+
+ if (aFilterName.equalsAscii("MS Excel 5.0/95")) {
+ aFileFormat = excel::XlFileFormat::xlExcel5;
+ }
+
+ if (aFilterName.equalsAscii("MS Excel 97")) {
+ aFileFormat = excel::XlFileFormat::xlExcel9795;
+ }
+
+ if (aFilterName.equalsAscii("HTML (StarCalc)")) {
+ aFileFormat = excel::XlFileFormat::xlHtml;
+ }
+
+ if (aFilterName.equalsAscii("calc_StarOffice_XML_Calc_Template")) {
+ aFileFormat = excel::XlFileFormat::xlTemplate;
+ }
+
+ if (aFilterName.equalsAscii("StarOffice XML (Calc)")) {
+ aFileFormat = excel::XlFileFormat::xlWorkbookNormal;
+ }
+ if (aFilterName.equalsAscii("calc8")) {
+ aFileFormat = excel::XlFileFormat::xlWorkbookNormal;
+ }
+
+ return aFileFormat;
+}
+
+void
+ScVbaWorkbook::init()
+{
+ if ( !ColorData.getLength() )
+ ResetColors();
+}
+ScVbaWorkbook::ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext) :ScVbaWorkbook_BASE( xParent, xContext )
+{
+ //#FIXME this persists the color data per office instance and
+ // not per workbook instance, need to hook the data into XModel
+ // ( e.g. we already store the imported palette in there )
+ // so we should,
+ // a) make the class that does that a service
+ // b) make that service implement XIndexContainer
+ init();
+}
+
+ScVbaWorkbook::ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, css::uno::Reference< css::frame::XModel > xModel ) : ScVbaWorkbook_BASE( xParent, xContext, xModel )
+{
+ init();
+}
+
+ScVbaWorkbook::ScVbaWorkbook( uno::Sequence< uno::Any> const & args,
+ uno::Reference< uno::XComponentContext> const & xContext ) : ScVbaWorkbook_BASE( args, xContext )
+{
+ init();
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaWorkbook::getActiveSheet() throw (uno::RuntimeException)
+{
+ uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSpreadsheetView > xView( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xSheetProps( xView->getActiveSheet(), uno::UNO_QUERY_THROW );
+ // #162503# return the original document module wrapper object, instead of a new instance
+ ::rtl::OUString aCodeName;
+ xSheetProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= aCodeName;
+ ScDocShell* pShell = excel::getDocShell( xModel );
+ if( !pShell )
+ throw uno::RuntimeException();
+ return uno::Reference< excel::XWorksheet >( getUnoDocModule( aCodeName, pShell ), uno::UNO_QUERY_THROW );
+}
+
+uno::Any SAL_CALL
+ScVbaWorkbook::Sheets( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return Worksheets( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaWorkbook::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< frame::XModel > xModel( getModel() );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference<container::XIndexAccess > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xWorkSheets( new ScVbaWorksheets( this, mxContext, xSheets, xModel ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ {
+ return uno::Any( xWorkSheets );
+ }
+ // pass on to collection
+ return uno::Any( xWorkSheets->Item( aIndex, uno::Any() ) );
+}
+uno::Any SAL_CALL
+ScVbaWorkbook::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+
+ uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( getParent(), mxContext ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ return uno::Any( xWindows );
+ return uno::Any( xWindows->Item( aIndex, uno::Any() ) );
+}
+
+void SAL_CALL
+ScVbaWorkbook::Activate() throw (uno::RuntimeException)
+{
+ VbaDocumentBase::Activate();
+}
+
+::sal_Bool
+ScVbaWorkbook::getProtectStructure() throw (uno::RuntimeException)
+{
+ uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
+ return xProt->isProtected();
+}
+
+::sal_Bool SAL_CALL ScVbaWorkbook::getPrecisionAsDisplayed() throw (uno::RuntimeException)
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW );
+ ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument();
+ return pDoc->GetDocOptions().IsCalcAsShown();
+}
+
+void SAL_CALL ScVbaWorkbook::setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed ) throw (uno::RuntimeException)
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW );
+ ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument();
+ ScDocOptions aOpt = pDoc->GetDocOptions();
+ aOpt.SetCalcAsShown( _precisionAsDisplayed );
+ pDoc->SetDocOptions( aOpt );
+}
+
+void
+ScVbaWorkbook::SaveCopyAs( const rtl::OUString& sFileName ) throw ( uno::RuntimeException)
+{
+ rtl::OUString aURL;
+ osl::FileBase::getFileURLFromSystemPath( sFileName, aURL );
+ uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::PropertyValue > storeProps(1);
+ storeProps[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ storeProps[0].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MS Excel 97" ) );
+ xStor->storeToURL( aURL, storeProps );
+}
+
+css::uno::Any SAL_CALL
+ScVbaWorkbook::Styles( const::uno::Any& Item ) throw (uno::RuntimeException)
+{
+ // quick look and Styles object doesn't seem to have a valid parent
+ // or a least the object browser just shows an object that has no
+ // variables ( therefore... leave as NULL for now )
+ uno::Reference< XCollection > dStyles = new ScVbaStyles( uno::Reference< XHelperInterface >(), mxContext, getModel() );
+ if ( Item.hasValue() )
+ return dStyles->Item( Item, uno::Any() );
+ return uno::makeAny( dStyles );
+}
+
+// Amelia Wang
+uno::Any SAL_CALL
+ScVbaWorkbook::Names( const css::uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< frame::XModel > xModel( getModel() );
+ uno::Reference< beans::XPropertySet > xProps( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xNames( new ScVbaNames( this , mxContext , xNamedRanges , xModel ));
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ {
+ return uno::Any( xNames );
+}
+ return uno::Any( xNames->Item( aIndex, uno::Any() ) );
+}
+
+rtl::OUString&
+ScVbaWorkbook::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorkbook") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaWorkbook::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Workbook" ) );
+ }
+ return aServiceNames;
+}
+
+::rtl::OUString SAL_CALL
+ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW );
+ return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >();
+}
+
+namespace workbook
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaWorkbook, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaWorkbook",
+ "ooo.vba.excel.Workbook" );
+}
diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx
new file mode 100644
index 000000000000..4aff58078403
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbook.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_WORKBOOK_HXX
+#define SC_VBA_WORKBOOK_HXX
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <ooo/vba/excel/XWorkbook.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbadocumentbase.hxx>
+
+class ScModelObj;
+
+typedef cppu::ImplInheritanceHelper1< VbaDocumentBase, ov::excel::XWorkbook > ScVbaWorkbook_BASE;
+
+class ScVbaWorkbook : public ScVbaWorkbook_BASE
+{
+ static css::uno::Sequence< sal_Int32 > ColorData;
+ void initColorData( const css::uno::Sequence< sal_Int32 >& sColors );
+ void init();
+protected:
+
+ ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext);
+public:
+ ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::frame::XModel > xModel );
+ ScVbaWorkbook( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
+ virtual ~ScVbaWorkbook() {}
+
+ // Attributes
+ virtual ::sal_Bool SAL_CALL getProtectStructure() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getPrecisionAsDisplayed() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed ) throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Worksheets( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Sheets( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Activate() throw (css::uno::RuntimeException);
+ // Amelia Wang
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL Styles( const css::uno::Any& Item ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL ResetColors( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Colors( const css::uno::Any& Index ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL FileFormat( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL SaveCopyAs( const rtl::OUString& Filename ) throw ( css::uno::RuntimeException);
+ // code name
+ virtual ::rtl::OUString SAL_CALL getCodeName() throw ( css::uno::RuntimeException);
+
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif /* SC_VBA_WORKBOOK_HXX */
diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx
new file mode 100644
index 000000000000..7efee1505dcb
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbooks.cxx
@@ -0,0 +1,367 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <comphelper/processfactory.hxx>
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+
+#include "vbaglobals.hxx"
+#include "vbaworkbook.hxx"
+#include "vbaworkbooks.hxx"
+#include <vbahelper/vbahelper.hxx>
+
+#include <hash_map>
+#include <vector>
+#include <osl/file.hxx>
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int16 CUSTOM_CHAR = 5;
+
+void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& xDoc )
+{
+ uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+ ScDocShell* pShell = excel::getDocShell( xModel );
+ if ( pShell )
+ {
+ uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer();
+ uno::Reference<script::vba::XVBACompatibility> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW );
+ xVBACompat->setVBACompatibilityMode( sal_True );
+ String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ pShell->GetBasicManager()->SetName( aPrjName );
+
+ if( xLibContainer.is() )
+ {
+ if( !xLibContainer->hasByName( aPrjName ) )
+ xLibContainer->createLibrary( aPrjName );
+ uno::Any aLibAny = xLibContainer->getByName( aPrjName );
+ uno::Reference< container::XNameContainer > xLib;
+ aLibAny >>= xLib;
+ if( xLib.is() )
+ {
+ uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW );
+ uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW);
+ // bootstrap vbaglobals
+ xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals")));
+ uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY_THROW );
+ // set up the module info for the workbook and sheets in the nealy created
+ // spreadsheet
+ ScDocument* pDoc = pShell->GetDocument();
+ String sCodeName = pDoc->GetCodeName();
+ if ( sCodeName.Len() == 0 )
+ {
+ sCodeName = String( RTL_CONSTASCII_USTRINGPARAM("ThisWorkbook") );
+ pDoc->SetCodeName( sCodeName );
+ }
+
+ std::vector< rtl::OUString > sDocModuleNames;
+ sDocModuleNames.push_back( sCodeName );
+
+ uno::Reference<container::XNameAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Sequence< rtl::OUString > sSheets( xSheets->getElementNames() );
+
+ for ( sal_Int32 index=0; index < sSheets.getLength() ; ++index )
+ {
+ sDocModuleNames.push_back( sSheets[ index ] );
+ }
+
+ std::vector<rtl::OUString>::iterator it_end = sDocModuleNames.end();
+
+ for ( std::vector<rtl::OUString>::iterator it = sDocModuleNames.begin(); it != it_end; ++it )
+ {
+ script::ModuleInfo sModuleInfo;
+
+ sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( *it ), uno::UNO_QUERY );
+ sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
+ xVBAModuleInfo->insertModuleInfo( *it, sModuleInfo );
+ if( xLib->hasByName( *it ) )
+ xLib->replaceByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n") ) ) );
+ else
+ xLib->insertByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) ) ) );
+ }
+ }
+ }
+ }
+}
+
+static uno::Any
+getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Reference< XHelperInterface >& xParent )
+{
+ // FIXME: fine as long as ScVbaWorkbook is stateless ...
+ uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+ if( !xModel.is() )
+ return uno::Any();
+
+ ScDocShell* pShell = excel::getDocShell( xModel );
+ if ( pShell )
+ {
+ String sCodeName = pShell->GetDocument()->GetCodeName();
+ uno::Reference< uno::XInterface > xIf = getUnoDocModule( sCodeName, pShell );
+ if ( xIf.is() )
+ {
+ OSL_TRACE(" *** Returning Module uno Object *** ");
+ return uno::makeAny( xIf );
+ }
+ }
+
+ ScVbaWorkbook *pWb = new ScVbaWorkbook( xParent, xContext, xModel );
+ return uno::Any( uno::Reference< excel::XWorkbook > (pWb) );
+}
+
+class WorkBookEnumImpl : public EnumerationHelperImpl
+{
+ uno::Any m_aApplication;
+public:
+ WorkBookEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication( aApplication ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return getWorkbook( m_xContext, xDoc, m_xParent );
+ }
+
+};
+
+ScVbaWorkbooks::ScVbaWorkbooks( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext ) : ScVbaWorkbooks_BASE( xParent, xContext, VbaDocumentsBase::EXCEL_DOCUMENT )
+{
+}
+// XEnumerationAccess
+uno::Type
+ScVbaWorkbooks::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XWorkbook::static_type(0);
+}
+uno::Reference< container::XEnumeration >
+ScVbaWorkbooks::createEnumeration() throw (uno::RuntimeException)
+{
+ // #FIXME its possible the WorkBookEnumImpl here doens't reflect
+ // the state of this object ( although it should ) would be
+ // safer to create an enumeration based on this objects state
+ // rather than one effectively based of the desktop component
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new WorkBookEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() );
+}
+
+uno::Any
+ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( aSource, uno::UNO_QUERY_THROW );
+ return getWorkbook( mxContext, xDoc, mxParent );
+}
+
+
+uno::Any SAL_CALL
+ScVbaWorkbooks::Add() throw (uno::RuntimeException)
+{
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW );
+
+ // need to set up the document modules ( and vba mode ) here
+ setUpDocumentModules( xSpreadDoc );
+ if( xSpreadDoc.is() )
+ return getWorkbook( mxContext, xSpreadDoc, mxParent );
+ return uno::Any();
+}
+
+void
+ScVbaWorkbooks::Close() throw (uno::RuntimeException)
+{
+ VbaDocumentsBase::Close();
+}
+
+bool
+ScVbaWorkbooks::isTextFile( const rtl::OUString& sType )
+{
+ // will return true if the file is
+ // a) a variant of a text file
+ // b) a csv file
+ // c) unknown
+ // returning true basically means treat this like a csv file
+ const static rtl::OUString txtType( RTL_CONSTASCII_USTRINGPARAM("writer_Text" ) );
+ const static rtl::OUString csvType( RTL_CONSTASCII_USTRINGPARAM("calc_Text_txt_csv_StarCalc" ) );
+ const static rtl::OUString encodedTxtType( RTL_CONSTASCII_USTRINGPARAM("writer_Text_encoded" ) );
+ return sType.equals( txtType ) || sType.equals( csvType ) || ( sType.getLength() == 0 ) || sType.equals( encodedTxtType );
+}
+
+bool
+ScVbaWorkbooks::isSpreadSheetFile( const rtl::OUString& sType )
+{
+ // include calc_QPro etc. ? ( not for the moment anyway )
+ if ( sType.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("calc_MS"))) == 0
+ || sType.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("calc8"))) == 0
+ || sType.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("calc_StarOffice"))) == 0 )
+ return true;
+ return false;
+}
+
+rtl::OUString
+ScVbaWorkbooks::getFileFilterType( const rtl::OUString& rFileName )
+{
+ uno::Reference< document::XTypeDetection > xTypeDetect( mxContext->getServiceManager()->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection"), mxContext), uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::PropertyValue > aMediaDesc(1);
+ aMediaDesc[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ("URL" ) );
+ aMediaDesc[ 0 ].Value <<= rFileName;
+ rtl::OUString sType = xTypeDetect->queryTypeByDescriptor( aMediaDesc, sal_True );
+ return sType;
+}
+
+// #TODO# #FIXME# can any of the unused params below be used?
+uno::Any
+ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLinks*/, const uno::Any& ReadOnly, const uno::Any& Format, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*IgnoreReadOnlyRecommended*/, const uno::Any& /*Origin*/, const uno::Any& Delimiter, const uno::Any& /*Editable*/, const uno::Any& /*Notify*/, const uno::Any& /*Converter*/, const uno::Any& /*AddToMru*/ ) throw (uno::RuntimeException)
+{
+ // we need to detect if this is a URL, if not then assume its a file path
+ rtl::OUString aURL;
+ INetURLObject aObj;
+ aObj.SetURL( rFileName );
+ bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
+ if ( bIsURL )
+ aURL = rFileName;
+ else
+ osl::FileBase::getFileURLFromSystemPath( rFileName, aURL );
+
+ uno::Sequence< beans::PropertyValue > sProps(0);
+ sal_Int32 nIndex = 0;
+
+ rtl::OUString sType = getFileFilterType( aURL );
+ // A text file means it needs to be processed as a csv file
+ if ( isTextFile( sType ) )
+ {
+ // Values for format
+ // 1 Tabs
+ // 2 Commas
+ // 3 Spaces
+ // 4 Semicolons
+ // 5 Nothing
+ // 6 Custom character (see the Delimiter argument
+ // no format means use the current delimiter
+ sProps.realloc( 3 );
+ sProps[ nIndex ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FilterOptions" ) );
+ sal_Int16 delims[] = { 0 /*default not used*/, 9/*tab*/, 44/*comma*/, 32/*space*/, 59/*semicolon*/ };
+ static rtl::OUString sRestOfFormat( RTL_CONSTASCII_USTRINGPARAM(",34,0,1" ) );
+
+ rtl::OUString sFormat;
+ sal_Int16 nFormat = 0; // default indicator
+
+
+ if ( Format.hasValue() )
+ {
+ Format >>= nFormat; // val of nFormat overwritten if extracted
+ // validate param
+ if ( nFormat < 1 || nFormat > 6 )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal value for Format" ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ sal_Int16 nDelim = getCurrentDelim();
+
+ if ( nFormat > 0 && nFormat < CUSTOM_CHAR )
+ {
+ nDelim = delims[ nFormat ];
+ }
+ else if ( nFormat > CUSTOM_CHAR )
+ {
+ // Need to check Delimiter param
+ if ( !Delimiter.hasValue() )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expected value for Delimiter" ) ), uno::Reference< uno::XInterface >() );
+ rtl::OUString sStr;
+ Delimiter >>= sStr;
+ String aUniStr( sStr );
+ if ( aUniStr.Len() )
+ nDelim = aUniStr.GetChar(0);
+ else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Incorrect value for Delimiter" ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ getCurrentDelim() = nDelim; //set new current
+
+ sFormat = rtl::OUString::valueOf( (sal_Int32)nDelim ) + sRestOfFormat;
+ sProps[ nIndex++ ].Value <<= sFormat;
+ sProps[ nIndex ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FilterName") );
+ sProps[ nIndex++ ].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Text - txt - csv (StarCalc)") );
+ // Ensure WORKAROUND_CSV_TXT_BUG_i60158 gets called in typedetection.cxx so
+ // csv is forced for deep detected 'writerxxx' types
+ sProps[ nIndex ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentService") );
+ sProps[ nIndex ].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument") );
+ }
+ else if ( !isSpreadSheetFile( sType ) )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() );
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW );
+ uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent );
+ uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
+ if ( xWBook.is() )
+ xWBook->Activate();
+ return aRet;
+}
+
+uno::Any
+ScVbaWorkbooks::Open( const rtl::OUString& Filename, const uno::Any& ReadOnly, const uno::Sequence< beans::PropertyValue >& rProps ) throw (css::uno::RuntimeException)
+{
+ return VbaDocumentsBase::Open( Filename, ReadOnly, rProps );
+}
+
+rtl::OUString&
+ScVbaWorkbooks::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorkbooks") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaWorkbooks::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Workbooks") );
+ }
+ return sNames;
+}
diff --git a/sc/source/ui/vba/vbaworkbooks.hxx b/sc/source/ui/vba/vbaworkbooks.hxx
new file mode 100644
index 000000000000..5d6210244d80
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbooks.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_WORKBOOKS_HXX
+#define SC_VBA_WORKBOOKS_HXX
+
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/excel/XWorkbooks.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <vbahelper/vbadocumentsbase.hxx>
+#include "excelvbahelper.hxx"
+
+
+class ScModelObj;
+
+typedef cppu::ImplInheritanceHelper1< VbaDocumentsBase, ov::excel::XWorkbooks > ScVbaWorkbooks_BASE;
+
+class ScVbaWorkbooks : public ScVbaWorkbooks_BASE
+{
+private:
+ rtl::OUString getFileFilterType( const rtl::OUString& rString );
+ bool isTextFile( const rtl::OUString& rString );
+ bool isSpreadSheetFile( const rtl::OUString& rString );
+ static sal_Int16& getCurrentDelim(){ static sal_Int16 nDelim = 44; return nDelim; }
+public:
+ ScVbaWorkbooks( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ virtual ~ScVbaWorkbooks() {}
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+ // ScVbaWorkbooks_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+ // XWorkbooks
+ virtual css::uno::Any SAL_CALL Add() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Close( ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Open( const ::rtl::OUString& Filename, const css::uno::Any& UpdateLinks, const css::uno::Any& ReadOnly, const css::uno::Any& Format, const css::uno::Any& Password, const css::uno::Any& WriteResPassword, const css::uno::Any& IgnoreReadOnlyRecommended, const css::uno::Any& Origin, const css::uno::Any& Delimiter, const css::uno::Any& Editable, const css::uno::Any& Notify, const css::uno::Any& Converter, const css::uno::Any& AddToMru ) throw (css::uno::RuntimeException);
+
+ // VbaDocumentsBase / XDocumentsBase (to avoid warning C4266 for hiding function on wntmsci)
+ virtual css::uno::Any SAL_CALL Open( const ::rtl::OUString& Filename, const css::uno::Any& ReadOnly, const css::uno::Sequence< css::beans::PropertyValue >& rProps ) throw (css::uno::RuntimeException);
+};
+
+#endif /* SC_VBA_WORKBOOKS_HXX */
diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx
new file mode 100644
index 000000000000..6ee6fa1f6b19
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheet.cxx
@@ -0,0 +1,1019 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vbahelper/helperdecl.hxx>
+#include <cppuhelper/queryinterface.hxx>
+
+#include "vbaworksheet.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XCalculatable.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSheetPastable.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/XSheetOutline.hpp>
+#include <com/sun/star/sheet/XSheetPageBreak.hpp>
+#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/table/XTableChartsSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <ooo/vba/excel/XlEnableSelection.hpp>
+#include <ooo/vba/excel/XWorkbook.hpp>
+#include <ooo/vba/XControlProvider.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <vbahelper/vbashapes.hxx>
+
+#include <tools/string.hxx>
+
+//zhangyun showdataform
+#include <sfx2/sfxdlg.hxx>
+#include "scabstdlg.hxx"
+#include "tabvwsh.hxx"
+#include "scitems.hxx"
+
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+
+#include "cellsuno.hxx"
+#include "drwlayer.hxx"
+
+#include "scextopt.hxx"
+#include "vbaoutline.hxx"
+#include "vbarange.hxx"
+#include "vbacomments.hxx"
+#include "vbachartobjects.hxx"
+#include "vbapivottables.hxx"
+#include "vbaoleobject.hxx"
+#include "vbaoleobjects.hxx"
+#include "vbapagesetup.hxx"
+#include "vbapagebreaks.hxx"
+#include "vbaworksheets.hxx"
+#include "vbahyperlinks.hxx"
+#include "vbasheetobjects.hxx"
+
+#define STANDARDWIDTH 2267
+#define STANDARDHEIGHT 427
+#define DOESNOTEXIST -1
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldName, uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc )
+{
+ if (!xSpreadDoc.is())
+ throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getNewSpreadsheetName() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 );
+ static rtl::OUString aUnderScre( RTL_CONSTASCII_USTRINGPARAM( "_" ) );
+ int currentNum =2;
+ aNewName = aOldName + aUnderScre+ String::CreateFromInt32(currentNum) ;
+ SCTAB nTab = 0;
+ while ( ScVbaWorksheets::nameExists(xSpreadDoc,aNewName, nTab ) )
+ {
+ aNewName = aOldName + aUnderScre +
+ String::CreateFromInt32(++currentNum) ;
+ }
+}
+
+static void removeAllSheets( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, rtl::OUString aSheetName)
+{
+ if (!xSpreadDoc.is())
+ throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "removeAllSheets() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 );
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+
+ if ( xIndex.is() )
+ {
+ uno::Reference<container::XNameContainer> xNameContainer(xSheets,uno::UNO_QUERY_THROW);
+ for (sal_Int32 i = xIndex->getCount() -1; i>= 1; i--)
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(i), uno::UNO_QUERY);
+ uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
+ if (xNamed.is())
+ {
+ xNameContainer->removeByName(xNamed->getName());
+ }
+ }
+
+ uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
+ if (xNamed.is())
+ {
+ xNamed->setName(aSheetName);
+ }
+ }
+}
+
+static uno::Reference<frame::XModel>
+openNewDoc(rtl::OUString aSheetName )
+{
+ uno::Reference<frame::XModel> xModel;
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ uno::Reference< uno::XComponentContext > xContext( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
+ uno::Reference<lang::XMultiComponentFactory > xServiceManager(
+ xContext->getServiceManager(), uno::UNO_QUERY_THROW );
+
+ uno::Reference <frame::XComponentLoader > xComponentLoader(
+ xServiceManager->createInstanceWithContext(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ),
+ xContext ), uno::UNO_QUERY_THROW );
+
+ uno::Reference<lang::XComponent > xComponent( xComponentLoader->loadComponentFromURL(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:factory/scalc" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" ) ), 0,
+ uno::Sequence < ::com::sun::star::beans::PropertyValue >() ) );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xComponent, uno::UNO_QUERY_THROW );
+ if ( xSpreadDoc.is() )
+ {
+ removeAllSheets(xSpreadDoc,aSheetName);
+ }
+ xModel.set(xSpreadDoc,uno::UNO_QUERY_THROW);
+ }
+ catch ( uno::Exception & /*e*/ )
+ {
+ }
+ return xModel;
+}
+
+ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext )
+{
+}
+
+ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSpreadsheet >& xSheet,
+ const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel)
+{
+}
+
+ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args,
+ uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) )
+{
+ if ( args.getLength() < 2 )
+ throw lang::IllegalArgumentException();
+
+ rtl::OUString sSheetName;
+ args[2] >>= sSheetName;
+
+ uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
+ mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW );
+}
+
+ScVbaWorksheet::~ScVbaWorksheet()
+{
+}
+
+::rtl::OUString
+ScVbaWorksheet::getName() throw (uno::RuntimeException)
+{
+ uno::Reference< container::XNamed > xNamed( getSheet(), uno::UNO_QUERY_THROW );
+ return xNamed->getName();
+}
+
+void
+ScVbaWorksheet::setName(const ::rtl::OUString &rName ) throw (uno::RuntimeException)
+{
+ uno::Reference< container::XNamed > xNamed( getSheet(), uno::UNO_QUERY_THROW );
+ xNamed->setName( rName );
+}
+
+sal_Bool
+ScVbaWorksheet::getVisible() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Any aValue = xProps->getPropertyValue
+ (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) ) );
+ sal_Bool bRet = false;
+ aValue >>= bRet;
+ return bRet;
+}
+
+void
+ScVbaWorksheet::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Any aValue( bVisible );
+ xProps->setPropertyValue
+ (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) ), aValue);
+}
+
+sal_Int16
+ScVbaWorksheet::getIndex() throw (uno::RuntimeException)
+{
+ return getSheetID() + 1;
+}
+
+sal_Int32
+ScVbaWorksheet::getEnableSelection() throw (uno::RuntimeException)
+{
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
+ SCTAB nTab = 0;
+ if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) )
+ {
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW );
+ ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument();
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ sal_Bool bLockedCells = sal_False;
+ sal_Bool bUnlockedCells = sal_False;
+ if( pProtect )
+ {
+ bLockedCells = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bUnlockedCells = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+ }
+ if( bLockedCells )
+ return excel::XlEnableSelection::xlNoRestrictions;
+ if( bUnlockedCells )
+ return excel::XlEnableSelection::xlUnlockedCells;
+ return excel::XlEnableSelection::xlNoSelection;
+ }
+ else
+ throw uno::RuntimeException(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ),
+ uno::Reference< XInterface >() );
+ return excel::XlEnableSelection::xlNoSelection;
+}
+
+
+void
+ScVbaWorksheet::setEnableSelection( sal_Int32 nSelection ) throw (uno::RuntimeException)
+{
+ if( (nSelection != excel::XlEnableSelection::xlNoRestrictions) &&
+ (nSelection != excel::XlEnableSelection::xlUnlockedCells) &&
+ (nSelection != excel::XlEnableSelection::xlNoSelection) )
+ {
+ DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
+ }
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
+ SCTAB nTab = 0;
+ if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) )
+ {
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW );
+ ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument();
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ // default is xlNoSelection
+ sal_Bool bLockedCells = sal_False;
+ sal_Bool bUnlockedCells = sal_False;
+ if( nSelection == excel::XlEnableSelection::xlNoRestrictions )
+ {
+ bLockedCells = sal_True;
+ bUnlockedCells = sal_True;
+ }
+ else if( nSelection == excel::XlEnableSelection::xlUnlockedCells )
+ {
+ bUnlockedCells = sal_True;
+ }
+ if( pProtect )
+ {
+ pProtect->setOption( ScTableProtection::SELECT_LOCKED_CELLS, bLockedCells );
+ pProtect->setOption( ScTableProtection::SELECT_UNLOCKED_CELLS, bUnlockedCells );
+ }
+ }
+ else
+ throw uno::RuntimeException(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ),
+ uno::Reference< XInterface >() );
+
+}
+
+uno::Reference< beans::XPropertySet > ScVbaWorksheet::getFirstDBRangeProperties() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xModelProps( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xDBRangesIA( xModelProps->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DatabaseRanges" ) ) ), uno::UNO_QUERY_THROW );
+
+ for( sal_Int32 nIndex = 0, nCount = xDBRangesIA->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XCellRangeReferrer > xDBRange( xDBRangesIA->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ // check if the database area is on this sheet
+ uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( xDBRange->getReferredCells(), uno::UNO_QUERY_THROW );
+ if( getSheetID() == xRangeAddr->getRangeAddress().Sheet )
+ return uno::Reference< beans::XPropertySet >( xDBRange, uno::UNO_QUERY_THROW );
+ }
+ return uno::Reference< beans::XPropertySet >();
+}
+
+sal_Bool SAL_CALL ScVbaWorksheet::getAutoFilterMode() throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xDBRangeProps = getFirstDBRangeProperties();
+ sal_Bool bAutoFilterMode = sal_False;
+ return
+ xDBRangeProps.is() &&
+ (xDBRangeProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoFilter" ) ) ) >>= bAutoFilterMode) &&
+ bAutoFilterMode;
+}
+
+void SAL_CALL ScVbaWorksheet::setAutoFilterMode( sal_Bool bAutoFilterMode ) throw (uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xDBRangeProps = getFirstDBRangeProperties();
+ if( xDBRangeProps.is() )
+ xDBRangeProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoFilter" ) ), uno::Any( bAutoFilterMode ) );
+}
+
+uno::Reference< excel::XRange >
+ScVbaWorksheet::getUsedRange() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor( getSheet()->createCursorByRange( xSheetCellRange ), uno::UNO_QUERY_THROW );
+ uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
+ xUsedCursor->gotoStartOfUsedArea( false );
+ xUsedCursor->gotoEndOfUsedArea( true );
+ uno::Reference< table::XCellRange > xRange( xSheetCellCursor, uno::UNO_QUERY);
+ return new ScVbaRange(this, mxContext, xRange);
+}
+
+uno::Reference< excel::XOutline >
+ScVbaWorksheet::Outline( ) throw (uno::RuntimeException)
+{
+ uno::Reference<sheet::XSheetOutline> xOutline(getSheet(),uno::UNO_QUERY_THROW);
+ return new ScVbaOutline( this, mxContext, xOutline);
+}
+
+uno::Reference< excel::XPageSetup >
+ScVbaWorksheet::PageSetup( ) throw (uno::RuntimeException)
+{
+ return new ScVbaPageSetup( this, mxContext, getSheet(), getModel() );
+}
+
+uno::Any
+ScVbaWorksheet::HPageBreaks( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak(getSheet(),uno::UNO_QUERY_THROW);
+ uno::Reference< excel::XHPageBreaks > xHPageBreaks( new ScVbaHPageBreaks( this, mxContext, xSheetPageBreak));
+ if ( aIndex.hasValue() )
+ return xHPageBreaks->Item( aIndex, uno::Any());
+ return uno::makeAny( xHPageBreaks );
+}
+
+uno::Any
+ScVbaWorksheet::VPageBreaks( const uno::Any& aIndex ) throw ( uno::RuntimeException )
+{
+ uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XVPageBreaks > xVPageBreaks( new ScVbaVPageBreaks( this, mxContext, xSheetPageBreak ) );
+ if( aIndex.hasValue() )
+ return xVPageBreaks->Item( aIndex, uno::Any());
+ return uno::makeAny( xVPageBreaks );
+}
+
+sal_Int32
+ScVbaWorksheet::getStandardWidth() throw (uno::RuntimeException)
+{
+ return STANDARDWIDTH ;
+}
+
+sal_Int32
+ScVbaWorksheet::getStandardHeight() throw (uno::RuntimeException)
+{
+ return STANDARDHEIGHT;
+}
+
+sal_Bool
+ScVbaWorksheet::getProtectionMode() throw (uno::RuntimeException)
+{
+ return sal_False;
+}
+
+sal_Bool
+ScVbaWorksheet::getProtectContents()throw (uno::RuntimeException)
+{
+ uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
+ return xProtectable->isProtected();
+}
+
+sal_Bool
+ScVbaWorksheet::getProtectDrawingObjects() throw (uno::RuntimeException)
+{
+ return sal_False;
+}
+
+sal_Bool
+ScVbaWorksheet::getProtectScenarios() throw (uno::RuntimeException)
+{
+ return sal_False;
+}
+
+void
+ScVbaWorksheet::Activate() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
+ getModel()->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSpreadsheet->setActiveSheet(getSheet());
+}
+
+void
+ScVbaWorksheet::Select() throw (uno::RuntimeException)
+{
+ Activate();
+}
+
+void
+ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException)
+{
+ uno::Reference<excel::XWorksheet> xSheet;
+ rtl::OUString aCurrSheetName = getName();
+
+ if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
+ {
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
+ uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
+ uno::Reference< table::XCellRange > xRange1( xSheetCellCursor, uno::UNO_QUERY);
+ // #FIXME needs worksheet as parent
+ uno::Reference<excel::XRange> xRange = new ScVbaRange( this, mxContext, xRange1);
+ if (xRange.is())
+ xRange->Select();
+ excel::implnCopy(mxModel);
+ uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
+ if (xModel.is())
+ {
+ excel::implnPaste(xModel);
+ Delete();
+ }
+ return ;
+ }
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
+ SCTAB nDest = 0;
+ if ( ScVbaWorksheets::nameExists (xSpreadDoc, xSheet->getName(), nDest) )
+ {
+ sal_Bool bAfter = After.hasValue();
+ if (bAfter)
+ nDest++;
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ xSheets->moveByName(aCurrSheetName,nDest);
+ }
+}
+
+void
+ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException)
+{
+ uno::Reference<excel::XWorksheet> xSheet;
+ rtl::OUString aCurrSheetName =getName();
+ if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
+ {
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
+ uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
+ uno::Reference< table::XCellRange > xRange1( xSheetCellCursor, uno::UNO_QUERY);
+ uno::Reference<excel::XRange> xRange = new ScVbaRange( this, mxContext, xRange1);
+ if (xRange.is())
+ xRange->Select();
+ excel::implnCopy(mxModel);
+ uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
+ if (xModel.is())
+ {
+ excel::implnPaste(xModel);
+ }
+ return;
+ }
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY );
+ SCTAB nDest = 0;
+ rtl::OUString aSheetName = xSheet->getName();
+ if ( ScVbaWorksheets::nameExists (xSpreadDoc, aSheetName, nDest ) )
+ {
+ sal_Bool bAfter = After.hasValue();
+ if(bAfter)
+ nDest++;
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ getNewSpreadsheetName(aSheetName,aCurrSheetName,xSpreadDoc);
+ xSheets->copyByName(aCurrSheetName,aSheetName,nDest);
+ }
+}
+
+
+void
+ScVbaWorksheet::Paste( const uno::Any& Destination, const uno::Any& /*Link*/ ) throw (uno::RuntimeException)
+{
+ // #TODO# #FIXME# Link is not used
+ uno::Reference<excel::XRange> xRange( Destination, uno::UNO_QUERY );
+ if ( xRange.is() )
+ xRange->Select();
+ excel::implnPaste( mxModel );
+}
+
+void
+ScVbaWorksheet::Delete() throw (uno::RuntimeException)
+{
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
+ rtl::OUString aSheetName = getName();
+ if ( xSpreadDoc.is() )
+ {
+ SCTAB nTab = 0;
+ if (!ScVbaWorksheets::nameExists(xSpreadDoc, aSheetName, nTab ))
+ {
+ return;
+ }
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ uno::Reference<container::XNameContainer> xNameContainer(xSheets,uno::UNO_QUERY_THROW);
+ xNameContainer->removeByName(aSheetName);
+ mxSheet.clear();
+ }
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaWorksheet::getSheetAtOffset(SCTAB offset) throw (uno::RuntimeException)
+{
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
+ uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW );
+
+ SCTAB nIdx = 0;
+ if ( !ScVbaWorksheets::nameExists (xSpreadDoc, getName(), nIdx ) )
+ return uno::Reference< excel::XWorksheet >();
+ nIdx = nIdx + offset;
+ uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(nIdx), uno::UNO_QUERY_THROW);
+ // parent will be the parent of 'this' worksheet
+ return new ScVbaWorksheet (getParent(), mxContext, xSheet, getModel());
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaWorksheet::getNext() throw (uno::RuntimeException)
+{
+ return getSheetAtOffset(static_cast<SCTAB>(1));
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaWorksheet::getPrevious() throw (uno::RuntimeException)
+{
+ return getSheetAtOffset(-1);
+}
+
+
+void
+ScVbaWorksheet::Protect( const uno::Any& Password, const uno::Any& /*DrawingObjects*/, const uno::Any& /*Contents*/, const uno::Any& /*Scenarios*/, const uno::Any& /*UserInterfaceOnly*/ ) throw (uno::RuntimeException)
+{
+ // #TODO# #FIXME# is there anything we can do witht the unused param
+ // can the implementation use anything else here
+ uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
+ ::rtl::OUString aPasswd;
+ Password >>= aPasswd;
+ xProtectable->protect( aPasswd );
+}
+
+void
+ScVbaWorksheet::Unprotect( const uno::Any& Password ) throw (uno::RuntimeException)
+{
+ uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
+ ::rtl::OUString aPasswd;
+ Password >>= aPasswd;
+ xProtectable->unprotect( aPasswd );
+}
+
+void
+ScVbaWorksheet::Calculate() throw (uno::RuntimeException)
+{
+ uno::Reference <sheet::XCalculatable> xReCalculate(getModel(), uno::UNO_QUERY_THROW);
+ xReCalculate->calculate();
+}
+
+uno::Reference< excel::XRange >
+ScVbaWorksheet::Range( const ::uno::Any& Cell1, const ::uno::Any& Cell2 ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XRange > xSheetRange( new ScVbaRange( this, mxContext
+, uno::Reference< table::XCellRange >( getSheet(), uno::UNO_QUERY_THROW ) ) );
+ return xSheetRange->Range( Cell1, Cell2 );
+}
+
+void
+ScVbaWorksheet::CheckSpelling( const uno::Any& /*CustomDictionary*/,const uno::Any& /*IgnoreUppercase*/,const uno::Any& /*AlwaysSuggest*/, const uno::Any& /*SpellingLang*/ ) throw (uno::RuntimeException)
+{
+ // #TODO# #FIXME# unused params above, can we do anything with those
+ rtl::OUString url = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SpellDialog"));
+ uno::Reference< frame::XModel > xModel( getModel() );
+ dispatchRequests(xModel,url);
+}
+
+uno::Reference< excel::XRange >
+ScVbaWorksheet::getSheetRange() throw (uno::RuntimeException)
+{
+ uno::Reference< table::XCellRange > xRange( getSheet(),uno::UNO_QUERY_THROW );
+ return uno::Reference< excel::XRange >( new ScVbaRange( this, mxContext, xRange ) );
+}
+
+// These are hacks - we prolly (somehow) need to inherit
+// the vbarange functionality here ...
+uno::Reference< excel::XRange >
+ScVbaWorksheet::Cells( const ::uno::Any &nRow, const ::uno::Any &nCol )
+ throw (uno::RuntimeException)
+{
+ return getSheetRange()->Cells( nRow, nCol );
+}
+
+uno::Reference< excel::XRange >
+ScVbaWorksheet::Rows(const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return getSheetRange()->Rows( aIndex );
+}
+
+uno::Reference< excel::XRange >
+ScVbaWorksheet::Columns( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ return getSheetRange()->Columns( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::ChartObjects( const uno::Any& Index ) throw (uno::RuntimeException)
+{
+ if ( !mxCharts.is() )
+ {
+ uno::Reference< table::XTableChartsSupplier > xChartSupplier( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XTableCharts > xTableCharts = xChartSupplier->getCharts();
+
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxSheet, uno::UNO_QUERY_THROW );
+ mxCharts = new ScVbaChartObjects( this, mxContext, xTableCharts, xDrawPageSupplier );
+ }
+ if ( Index.hasValue() )
+ {
+ uno::Reference< XCollection > xColl( mxCharts, uno::UNO_QUERY_THROW );
+ return xColl->Item( Index, uno::Any() );
+ }
+ else
+ return uno::makeAny( mxCharts );
+
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::PivotTables( const uno::Any& Index ) throw (uno::RuntimeException)
+{
+ uno::Reference< css::sheet::XSpreadsheet > xSheet = getSheet();
+ uno::Reference< sheet::XDataPilotTablesSupplier > xTables(xSheet, uno::UNO_QUERY_THROW ) ;
+ uno::Reference< container::XIndexAccess > xIndexAccess( xTables->getDataPilotTables(), uno::UNO_QUERY_THROW );
+
+ uno::Reference< XCollection > xColl( new ScVbaPivotTables( this, mxContext, xIndexAccess ) );
+ if ( Index.hasValue() )
+ return xColl->Item( Index, uno::Any() );
+ return uno::makeAny( xColl );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Comments( const uno::Any& Index ) throw (uno::RuntimeException)
+{
+ uno::Reference< css::sheet::XSpreadsheet > xSheet = getSheet();
+ uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xAnnos, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, mxModel, xIndexAccess ) );
+ if ( Index.hasValue() )
+ return xColl->Item( Index, uno::Any() );
+ return uno::makeAny( xColl );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ /* The worksheet always returns the same Hyperlinks object.
+ See vbahyperlinks.hxx for more details. */
+ if( !mxHlinks.is() )
+ mxHlinks.set( new ScVbaHyperlinks( this, mxContext ) );
+ if( aIndex.hasValue() )
+ return uno::Reference< XCollection >( mxHlinks, uno::UNO_QUERY_THROW )->Item( aIndex, uno::Any() );
+ return uno::Any( mxHlinks );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Names( const css::uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< excel::XWorkbook > xWorkbook( getParent(), uno::UNO_QUERY_THROW );
+ return xWorkbook->Names( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::OLEObjects( const uno::Any& Index ) throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPage, uno::UNO_QUERY_THROW );
+
+ uno::Reference< excel::XOLEObjects >xOleObjects( new ScVbaOLEObjects( this, mxContext, xIndexAccess ) );
+ if( Index.hasValue() )
+ return xOleObjects->Item( Index, uno::Any() );
+ return uno::Any( xOleObjects );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Shapes( const uno::Any& aIndex ) throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShapes > xShapes( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );
+
+ uno::Reference< msforms::XShapes> xVbaShapes( new ScVbaShapes( this, mxContext, xIndexAccess, getModel() ) );
+ if ( aIndex.hasValue() )
+ return xVbaShapes->Item( aIndex, uno::Any() );
+ return uno::makeAny( xVbaShapes );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Buttons( const uno::Any& rIndex ) throw (uno::RuntimeException)
+{
+ if( !mxButtons.is() )
+ mxButtons.set( new ScVbaButtons( this, mxContext, mxModel, mxSheet ) );
+ else
+ mxButtons->collectShapes();
+ if( rIndex.hasValue() )
+ return mxButtons->Item( rIndex, uno::Any() );
+ return uno::Any( uno::Reference< XCollection >( mxButtons.get() ) );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::CheckBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::DropDowns( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::GroupBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Labels( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::ListBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::OptionButtons( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::ScrollBars( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Spinners( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException)
+{
+ throw uno::RuntimeException();
+}
+
+void SAL_CALL
+ScVbaWorksheet::ShowDataForm( ) throw (uno::RuntimeException)
+{
+#ifdef VBA_OOBUILD_HACK
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW );
+ ScTabViewShell* pTabViewShell = excel::getBestViewShell( xModel );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDataFormDlg* pDlg = pFact->CreateScDataFormDlg( pTabViewShell->GetDialogParent(),RID_SCDLG_DATAFORM, pTabViewShell);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ pDlg->Execute();
+#else
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() );
+#endif
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::Evaluate( const ::rtl::OUString& Name ) throw (uno::RuntimeException)
+{
+ // #TODO Evaluate allows other things to be evaluated, e.g. functions
+ // I think ( like SIN(3) etc. ) need to investigate that
+ // named Ranges also? e.g. [MyRange] if so need a list of named ranges
+ uno::Any aVoid;
+ return uno::Any( Range( uno::Any( Name ), aVoid ) );
+}
+
+
+uno::Reference< beans::XIntrospectionAccess > SAL_CALL
+ScVbaWorksheet::getIntrospection( ) throw (uno::RuntimeException)
+{
+ return uno::Reference< beans::XIntrospectionAccess >();
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheet::invoke( const ::rtl::OUString& aFunctionName, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ ) throw (lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+{
+ OSL_TRACE("** ScVbaWorksheet::invoke( %s ), will barf",
+ rtl::OUStringToOString( aFunctionName, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ throw uno::RuntimeException(); // unsupported operation
+}
+
+void SAL_CALL
+ScVbaWorksheet::setValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue ) throw (beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+{
+ setDefaultPropByIntrospection( uno::makeAny( getValue( aPropertyName ) ), aValue );
+}
+uno::Any SAL_CALL
+ScVbaWorksheet::getValue( const ::rtl::OUString& aPropertyName ) throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW );
+
+ uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
+ uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.ControlProvider" ) ), mxContext ), uno::UNO_QUERY_THROW );
+ uno::Reference< msforms::XControl > xControl( xControlProvider->createControl( xControlShape, getModel() ) );
+ return uno::makeAny( xControl );
+}
+
+::sal_Bool SAL_CALL
+ScVbaWorksheet::hasMethod( const ::rtl::OUString& /*aName*/ ) throw (uno::RuntimeException)
+{
+ return sal_False;
+}
+
+uno::Reference< container::XNameAccess >
+ScVbaWorksheet::getFormControls()
+{
+ uno::Reference< container::XNameAccess > xFormControls;
+ try
+ {
+ uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
+ uno::Reference< form::XFormsSupplier > xFormSupplier( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
+ // get the www-standard container ( maybe we should access the
+ // 'www-standard' by name rather than index, this seems an
+ // implementation detail
+ xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW );
+
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return xFormControls;
+
+ }
+::sal_Bool SAL_CALL
+ScVbaWorksheet::hasProperty( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
+{
+ uno::Reference< container::XNameAccess > xFormControls( getFormControls() );
+ if ( xFormControls.is() )
+ return xFormControls->hasByName( aName );
+ return sal_False;
+}
+
+uno::Any
+ScVbaWorksheet::getControlShape( const ::rtl::OUString& sName )
+{
+ // ideally we would get an XControl object but it appears an XControl
+ // implementation only exists for a Control implementation optained from the
+ // view ( e.g. in basic you would get this from
+ // thiscomponent.currentcontroller.getControl( controlModel ) )
+ // and the thing to realise is that it is only possible to get an XControl
+ // for a currently displayed control :-( often we would want to modify
+ // a control not on the active sheet. But.. you can always access the
+ // XControlShape from the DrawPage whether that is the active drawpage or not
+
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( getSheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+
+ sal_Int32 nCount = xIndexAccess->getCount();
+ for( int index = 0; index < nCount; index++ )
+ {
+ uno::Any aUnoObj = xIndexAccess->getByIndex( index );
+ // It seems there are some drawing objects that can not query into Control shapes?
+ uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY );
+ if( xControlShape.is() )
+ {
+ uno::Reference< container::XNamed > xNamed( xControlShape->getControl(), uno::UNO_QUERY_THROW );
+ if( sName.equals( xNamed->getName() ))
+ {
+ return aUnoObj;
+ }
+ }
+ }
+ return uno::Any();
+}
+
+
+rtl::OUString&
+ScVbaWorksheet::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorksheet") );
+ return sImplName;
+}
+void SAL_CALL
+ScVbaWorksheet::setEnableCalculation( ::sal_Bool bEnableCalculation ) throw ( script::BasicErrorException, uno::RuntimeException)
+{
+ uno::Reference <sheet::XCalculatable> xCalculatable(getModel(), uno::UNO_QUERY_THROW);
+ xCalculatable->enableAutomaticCalculation( bEnableCalculation);
+}
+::sal_Bool SAL_CALL
+ScVbaWorksheet::getEnableCalculation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
+{
+ uno::Reference <sheet::XCalculatable> xCalculatable(getModel(), uno::UNO_QUERY_THROW);
+ return xCalculatable->isAutomaticCalculationEnabled();
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaWorksheet::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Worksheet" ) );
+ }
+ return aServiceNames;
+}
+
+rtl::OUString SAL_CALL
+ScVbaWorksheet::getCodeName() throw (css::uno::RuntimeException)
+{
+ uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW );
+ return xSheetProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >();
+}
+
+sal_Int16
+ScVbaWorksheet::getSheetID() throw (uno::RuntimeException)
+{
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( mxSheet, uno::UNO_QUERY_THROW );
+ return xAddressable->getRangeAddress().Sheet;
+}
+
+void SAL_CALL
+ScVbaWorksheet::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& ActivePrinter, const uno::Any& PrintToFile, const uno::Any& Collate, const uno::Any& PrToFileName, const uno::Any& IgnorePrintAreas ) throw (uno::RuntimeException)
+{
+ sal_Int32 nTo = 0;
+ sal_Int32 nFrom = 0;
+ sal_Int16 nCopies = 1;
+ sal_Bool bCollate = sal_False;
+ sal_Bool bSelection = sal_False;
+ sal_Bool bIgnorePrintAreas = sal_False;
+ From >>= nFrom;
+ To >>= nTo;
+ Copies >>= nCopies;
+ IgnorePrintAreas >>= bIgnorePrintAreas;
+ if ( nCopies > 1 ) // Collate only useful when more that 1 copy
+ Collate >>= bCollate;
+
+ if ( !( nFrom || nTo ) )
+ bSelection = sal_True;
+
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW );
+ PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
+}
+
+namespace worksheet
+{
+namespace sdecl = comphelper::service_decl;
+sdecl::vba_service_class_<ScVbaWorksheet, sdecl::with_args<true> > serviceImpl;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceImpl,
+ "ScVbaWorksheet",
+ "ooo.vba.excel.Worksheet" );
+}
diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx
new file mode 100644
index 000000000000..78bcc2503a49
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheet.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_WORKSHEET_HXX
+#define SC_VBA_WORKSHEET_HXX
+
+#include <cppuhelper/implbase2.hxx>
+#include <comphelper/unwrapargs.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <ooo/vba/excel/XWorksheet.hpp>
+#include <ooo/vba/excel/XComments.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <ooo/vba/excel/XOutline.hpp>
+#include <ooo/vba/excel/XPageSetup.hpp>
+#include <ooo/vba/excel/XHPageBreaks.hpp>
+#include <ooo/vba/excel/XVPageBreaks.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include "address.hxx"
+
+namespace ooo { namespace vba { namespace excel {
+ class XChartObjects;
+ class XHyperlinks;
+} } }
+
+class ScVbaSheetObjectsBase;
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XWorksheet > WorksheetImpl_BASE;
+
+class ScVbaWorksheet : public WorksheetImpl_BASE
+{
+ css::uno::Reference< css::sheet::XSpreadsheet > mxSheet;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< ov::excel::XChartObjects > mxCharts;
+ css::uno::Reference< ov::excel::XHyperlinks > mxHlinks;
+ ::rtl::Reference< ScVbaSheetObjectsBase > mxButtons;
+
+ css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset) throw (css::uno::RuntimeException);
+ css::uno::Reference< ov::excel::XRange > getSheetRange() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::container::XNameAccess > getFormControls();
+ css::uno::Any getControlShape( const rtl::OUString& sName );
+
+ css::uno::Reference< css::beans::XPropertySet > getFirstDBRangeProperties() throw (css::uno::RuntimeException);
+
+protected:
+
+ ScVbaWorksheet( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext );
+public:
+ ScVbaWorksheet( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XSpreadsheet >& xSheet,
+ const css::uno::Reference< css::frame::XModel >& xModel )throw (css::uno::RuntimeException) ;
+ ScVbaWorksheet( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException );
+
+ virtual ~ScVbaWorksheet();
+
+ virtual css::uno::Reference< css::frame::XModel > getModel()
+ { return mxModel; }
+ virtual css::uno::Reference< css::sheet::XSpreadsheet > getSheet()
+ { return mxSheet; }
+
+ // Attributes
+ virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVisible( sal_Bool bVisible ) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getStandardWidth() throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getStandardHeight() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getProtectionMode() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getProtectContents() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getProtectDrawingObjects() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getProtectScenarios() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getUsedRange() throw (css::uno::RuntimeException) ;
+ virtual css::uno::Any SAL_CALL ChartObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XOutline > SAL_CALL Outline( ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XPageSetup > SAL_CALL PageSetup( ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL HPageBreaks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL VPageBreaks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getNext() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getPrevious() throw (css::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getIndex() throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getEnableSelection() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setEnableSelection( sal_Int32 nSelection ) throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getAutoFilterMode() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAutoFilterMode( sal_Bool bAutoFilterMode ) throw (css::uno::RuntimeException);
+
+ // Methods
+ virtual void SAL_CALL Activate() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Select() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Move( const css::uno::Any& Before, const css::uno::Any& After ) throw (css::uno::RuntimeException) ;
+ virtual void SAL_CALL Copy( const css::uno::Any& Before, const css::uno::Any& After ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Paste( const css::uno::Any& Destination, const css::uno::Any& Link ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Delete( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Protect( const css::uno::Any& Password, const css::uno::Any& DrawingObjects, const css::uno::Any& Contents, const css::uno::Any& Scenarios, const css::uno::Any& UserInterfaceOnly ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Unprotect( const css::uno::Any& Password ) throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL Calculate( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL CheckSpelling( const css::uno::Any& CustomDictionary,const css::uno::Any& IgnoreUppercase,const css::uno::Any& AlwaysSuggest, const css::uno::Any& SpellingLang ) throw (css::uno::RuntimeException);
+ // Hacks (?)
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Cells( const css::uno::Any &nRow, const css::uno::Any &nCol ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Rows(const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Columns(const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL Evaluate( const ::rtl::OUString& Name ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Any SAL_CALL Buttons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL CheckBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL DropDowns( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL GroupBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Labels( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL ListBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL OptionButtons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL ScrollBars( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Spinners( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setEnableCalculation( ::sal_Bool EnableCalculation ) throw ( css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getEnableCalculation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException);
+ virtual void SAL_CALL ShowDataForm( ) throw (css::uno::RuntimeException);
+ // XInvocation
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection( ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL invoke( const ::rtl::OUString& aFunctionName, const css::uno::Sequence< css::uno::Any >& aParams, css::uno::Sequence< ::sal_Int16 >& aOutParamIndex, css::uno::Sequence< css::uno::Any >& aOutParam ) throw (css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException);
+ virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const css::uno::Any& aValue ) throw (css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) throw (css::beans::UnknownPropertyException, css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException);
+ // CodeName
+ virtual rtl::OUString SAL_CALL getCodeName() throw (css::uno::RuntimeException);
+ sal_Int16 getSheetID() throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName, const css::uno::Any& IgnorePrintAreas ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+
+#endif /* SC_VBA_WORKSHEET_HXX */
+
diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx
new file mode 100644
index 000000000000..7fa5196a6b04
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheets.cxx
@@ -0,0 +1,501 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "vbaworksheets.hxx"
+
+#include <sfx2/dispatch.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/itemwrapper.hxx>
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <ooo/vba/excel/XApplication.hpp>
+#include <tools/string.hxx>
+#include "tabvwsh.hxx"
+
+#include "vbaglobals.hxx"
+#include "vbaworksheet.hxx"
+#include "vbaworkbook.hxx"
+#include "unonames.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+
+typedef ::cppu::WeakImplHelper1< container::XEnumeration > SheetEnumeration_BASE;
+typedef ::cppu::WeakImplHelper3< container::XNameAccess, container::XIndexAccess, container::XEnumerationAccess > SheetCollectionHelper_BASE;
+// a map ( or hashmap ) wont do as we need also to preserve the order
+// (as added ) of the items
+typedef std::vector< uno::Reference< sheet::XSpreadsheet > > SheetMap;
+
+
+// #FIXME #TODO the implementation of the Sheets collections sucks,
+// e.g. there is no support for tracking sheets added/removed from the collection
+
+uno::Reference< uno::XInterface >
+lcl_getModulAsUnoObject( const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException )
+{
+ uno::Reference< uno::XInterface > xRet;
+ if ( !xSheet.is() )
+ throw uno::RuntimeException();
+ uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW );
+ rtl::OUString sName;
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= sName;
+
+ ScDocShell* pShell = excel::getDocShell( xModel );
+
+ if ( pShell )
+ xRet = getUnoDocModule( sName, pShell );
+ return xRet;
+}
+
+class WorkSheetsEnumeration : public SheetEnumeration_BASE
+{
+ SheetMap mSheetMap;
+ SheetMap::iterator mIt;
+public:
+ WorkSheetsEnumeration( const SheetMap& sMap ) : mSheetMap( sMap ), mIt( mSheetMap.begin() ) {}
+ virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
+ {
+ return ( mIt != mSheetMap.end() );
+ }
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ uno::Reference< sheet::XSpreadsheet > xSheet( *mIt++ );
+ return uno::makeAny( xSheet ) ;
+ }
+};
+
+class SheetCollectionHelper : public SheetCollectionHelper_BASE
+{
+ SheetMap mSheetMap;
+ SheetMap::iterator cachePos;
+public:
+ SheetCollectionHelper( const SheetMap& sMap ) : mSheetMap( sMap ), cachePos(mSheetMap.begin()) {}
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) { return sheet::XSpreadsheet::static_type(0); }
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException) { return ( mSheetMap.size() > 0 ); }
+ // XNameAcess
+ virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasByName(aName) )
+ throw container::NoSuchElementException();
+ return uno::makeAny( *cachePos );
+ }
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
+ {
+ uno::Sequence< rtl::OUString > sNames( mSheetMap.size() );
+ rtl::OUString* pString = sNames.getArray();
+ SheetMap::iterator it = mSheetMap.begin();
+ SheetMap::iterator it_end = mSheetMap.end();
+
+ for ( ; it != it_end; ++it, ++pString )
+ {
+ uno::Reference< container::XNamed > xName( *it, uno::UNO_QUERY_THROW );
+ *pString = xName->getName();
+ }
+ return sNames;
+ }
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
+ {
+ cachePos = mSheetMap.begin();
+ SheetMap::iterator it_end = mSheetMap.end();
+ for ( ; cachePos != it_end; ++cachePos )
+ {
+ uno::Reference< container::XNamed > xName( *cachePos, uno::UNO_QUERY_THROW );
+ if ( aName.equals( xName->getName() ) )
+ break;
+ }
+ return ( cachePos != it_end );
+ }
+
+ // XElementAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) { return mSheetMap.size(); }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::makeAny( mSheetMap[ Index ] );
+
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException)
+ {
+ return new WorkSheetsEnumeration( mSheetMap );
+ }
+};
+
+class SheetsEnumeration : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > m_xModel;
+public:
+ SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ uno::Reference< uno::XInterface > xIf = lcl_getModulAsUnoObject( xSheet, m_xModel );
+ uno::Any aRet;
+ if ( !xIf.is() )
+ {
+ // if the Sheet is in a document created by the api unfortunately ( at the
+ // moment, it actually wont have the special Document modules
+ uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) );
+ aRet <<= xNewSheet;
+ }
+ else
+ aRet <<= xIf;
+ return aRet;
+ }
+
+};
+
+ScVbaWorksheets::ScVbaWorksheets( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xSheets, const uno::Reference< frame::XModel >& xModel ): ScVbaWorksheets_BASE( xParent, xContext, xSheets ), mxModel( xModel ), m_xSheets( uno::Reference< sheet::XSpreadsheets >( xSheets, uno::UNO_QUERY ) )
+{
+}
+
+ScVbaWorksheets::ScVbaWorksheets( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext, const uno::Reference< container::XEnumerationAccess >& xEnumAccess, const uno::Reference< frame::XModel >& xModel ): ScVbaWorksheets_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xEnumAccess, uno::UNO_QUERY ) ), mxModel(xModel)
+{
+}
+
+// XEnumerationAccess
+uno::Type
+ScVbaWorksheets::getElementType() throw (uno::RuntimeException)
+{
+ return excel::XWorksheet::static_type(0);
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaWorksheets::createEnumeration() throw (uno::RuntimeException)
+{
+ if ( !m_xSheets.is() )
+ {
+ uno::Reference< container::XEnumerationAccess > xAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xAccess->createEnumeration();
+ }
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xSheets, uno::UNO_QUERY_THROW );
+ return new SheetsEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+ScVbaWorksheets::createCollectionObject( const uno::Any& aSource )
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY );
+ uno::Reference< XInterface > xIf = lcl_getModulAsUnoObject( xSheet, mxModel );
+ uno::Any aRet;
+ if ( !xIf.is() )
+ {
+ // if the Sheet is in a document created by the api unfortunately ( at the
+ // moment, it actually wont have the special Document modules
+ uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) );
+ aRet <<= xNewSheet;
+ }
+ else
+ aRet <<= xIf;
+ return aRet;
+}
+
+// XWorksheets
+uno::Any
+ScVbaWorksheets::Add( const uno::Any& Before, const uno::Any& After,
+ const uno::Any& Count, const uno::Any& Type ) throw (uno::RuntimeException)
+{
+ if ( isSelectedSheets() )
+ return uno::Any(); // or should we throw?
+
+ rtl::OUString aStringSheet;
+ sal_Bool bBefore(sal_True);
+ SCTAB nSheetIndex = 0;
+ SCTAB nNewSheets = 1, nType = 0;
+ Count >>= nNewSheets;
+ Type >>= nType;
+ SCTAB nCount = 0;
+
+ uno::Reference< excel::XWorksheet > xBeforeAfterSheet;
+
+ if ( Before.hasValue() )
+ {
+ if ( Before >>= xBeforeAfterSheet )
+ aStringSheet = xBeforeAfterSheet->getName();
+ else
+ Before >>= aStringSheet;
+ }
+
+ if (!aStringSheet.getLength() && After.hasValue() )
+ {
+ if ( After >>= xBeforeAfterSheet )
+ aStringSheet = xBeforeAfterSheet->getName();
+ else
+ After >>= aStringSheet;
+ bBefore = sal_False;
+ }
+ if (!aStringSheet.getLength())
+ {
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ aStringSheet = xApplication->getActiveWorkbook()->getActiveSheet()->getName();
+ bBefore = sal_True;
+ }
+ nCount = static_cast< SCTAB >( m_xIndexAccess->getCount() );
+ for (SCTAB i=0; i < nCount; i++)
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet(m_xIndexAccess->getByIndex(i), uno::UNO_QUERY);
+ uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
+ if (xNamed->getName() == aStringSheet)
+ {
+ nSheetIndex = i;
+ break;
+ }
+ }
+
+ if(!bBefore)
+ nSheetIndex++;
+
+ SCTAB nSheetName = nCount + 1L;
+ String aStringBase( RTL_CONSTASCII_USTRINGPARAM("Sheet") );
+ uno::Any result;
+ for (SCTAB i=0; i < nNewSheets; i++, nSheetName++)
+ {
+ String aStringName = aStringBase;
+ aStringName += String::CreateFromInt32(nSheetName);
+ while (m_xNameAccess->hasByName(aStringName))
+ {
+ nSheetName++;
+ aStringName = aStringBase;
+ aStringName += String::CreateFromInt32(nSheetName);
+ }
+ m_xSheets->insertNewByName(aStringName, nSheetIndex + i);
+ result = getItemByStringIndex( aStringName );
+ }
+ uno::Reference< excel::XWorksheet > xNewSheet( result, uno::UNO_QUERY );
+ if ( xNewSheet.is() )
+ xNewSheet->Activate();
+ return result;
+}
+
+void
+ScVbaWorksheets::Delete() throw (uno::RuntimeException)
+{
+ // #TODO #INVESTIGATE
+ // mmm this method could be trouble if the underlying
+ // uno objects ( the m_xIndexAccess etc ) aren't aware of the
+ // contents that are deleted
+ sal_Int32 nElems = getCount();
+ for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xSheet->Delete();
+ }
+}
+
+bool
+ScVbaWorksheets::isSelectedSheets()
+{
+ return !m_xSheets.is();
+}
+
+void SAL_CALL
+ScVbaWorksheets::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& ActivePrinter, const uno::Any& PrintToFile, const uno::Any& Collate, const uno::Any& PrToFileName ) throw (uno::RuntimeException)
+{
+ sal_Int32 nTo = 0;
+ sal_Int32 nFrom = 0;
+ sal_Int16 nCopies = 1;
+ sal_Bool bCollate = sal_False;
+ sal_Bool bSelection = sal_False;
+ From >>= nFrom;
+ To >>= nTo;
+ Copies >>= nCopies;
+ if ( nCopies > 1 ) // Collate only useful when more that 1 copy
+ Collate >>= bCollate;
+
+ if ( !( nFrom || nTo ) )
+ if ( isSelectedSheets() )
+ bSelection = sal_True;
+
+ PrintOutHelper( excel::getBestViewShell( mxModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheets::getVisible() throw (uno::RuntimeException)
+{
+ sal_Bool bVisible = sal_True;
+ uno::Reference< container::XEnumeration > xEnum( createEnumeration(), uno::UNO_QUERY_THROW );
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ if ( xSheet->getVisible() == sal_False )
+ {
+ bVisible = sal_False;
+ break;
+ }
+ }
+ return uno::makeAny( bVisible );
+}
+
+void SAL_CALL
+ScVbaWorksheets::setVisible( const uno::Any& _visible ) throw (uno::RuntimeException)
+{
+ sal_Bool bState = sal_False;
+ if ( _visible >>= bState )
+ {
+ uno::Reference< container::XEnumeration > xEnum( createEnumeration(), uno::UNO_QUERY_THROW );
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ xSheet->setVisible( bState );
+ }
+ }
+ else
+ throw uno::RuntimeException( rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Visible property doesn't support non boolean #FIXME" ) ), uno::Reference< uno::XInterface >() );
+}
+
+void SAL_CALL
+ScVbaWorksheets::Select( const uno::Any& Replace ) throw (uno::RuntimeException)
+{
+ ScTabViewShell* pViewShell = excel::getBestViewShell( mxModel );
+ if ( !pViewShell )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain view shell" ) ), uno::Reference< uno::XInterface >() );
+
+ ScMarkData& rMarkData = pViewShell->GetViewData()->GetMarkData();
+ sal_Bool bReplace = sal_True;
+ Replace >>= bReplace;
+ // Replace is defaulted to True, meanining this current collection
+ // becomes the Selection, if it were false then the current selection would
+ // be extended
+ bool bSelectSingle = bReplace;
+ sal_Int32 nElems = getCount();
+ for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaWorksheet* pSheet = dynamic_cast< ScVbaWorksheet* >( xSheet.get() );
+ if ( pSheet )
+ {
+ if ( bSelectSingle )
+ {
+ rMarkData.SelectOneTable( static_cast< SCTAB >( pSheet->getSheetID() ) );
+ bSelectSingle = false;
+ }
+ else
+ rMarkData.SelectTable( static_cast< SCTAB >( pSheet->getSheetID() ), TRUE );
+
+ }
+ }
+
+
+}
+
+//ScVbaCollectionBaseImpl
+uno::Any SAL_CALL
+ScVbaWorksheets::Item( const uno::Any& Index, const uno::Any& Index2 ) throw (uno::RuntimeException)
+{
+ if ( Index.getValueTypeClass() == uno::TypeClass_SEQUENCE )
+ {
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter(mxContext);
+ uno::Any aConverted;
+ aConverted = xConverter->convertTo( Index, getCppuType((uno::Sequence< uno::Any >*)0) );
+ SheetMap mSheets;
+ uno::Sequence< uno::Any > sIndices;
+ aConverted >>= sIndices;
+ sal_Int32 nElems = sIndices.getLength();
+ for( sal_Int32 index = 0; index < nElems; ++index )
+ {
+ uno::Reference< excel::XWorksheet > xWorkSheet( ScVbaWorksheets_BASE::Item( sIndices[ index ], Index2 ), uno::UNO_QUERY_THROW );
+ ScVbaWorksheet* pWorkSheet = dynamic_cast< ScVbaWorksheet* >( xWorkSheet.get() );
+ if ( pWorkSheet )
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet( pWorkSheet->getSheet() , uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNamed > xName( xSheet, uno::UNO_QUERY_THROW );
+ mSheets.push_back( xSheet );
+ }
+ }
+ uno::Reference< container::XIndexAccess > xIndexAccess = new SheetCollectionHelper( mSheets );
+ uno::Reference< XCollection > xSelectedSheets( new ScVbaWorksheets( this->getParent(), mxContext, xIndexAccess, mxModel ) );
+ return uno::makeAny( xSelectedSheets );
+ }
+ return ScVbaWorksheets_BASE::Item( Index, Index2 );
+}
+
+uno::Any
+ScVbaWorksheets::getItemByStringIndex( const rtl::OUString& sIndex ) throw (uno::RuntimeException)
+{
+ return ScVbaWorksheets_BASE::getItemByStringIndex( sIndex );
+}
+
+rtl::OUString&
+ScVbaWorksheets::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWorksheets") );
+ return sImplName;
+}
+
+css::uno::Sequence<rtl::OUString>
+ScVbaWorksheets::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > sNames;
+ if ( sNames.getLength() == 0 )
+ {
+ sNames.realloc( 1 );
+ sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Worksheets") );
+ }
+ return sNames;
+}
+
+/*static*/ bool ScVbaWorksheets::nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException )
+{
+ if (!xSpreadDoc.is())
+ throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 );
+ uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() );
+ for (SCTAB i=0; i < nCount; i++)
+ {
+ uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (xNamed->getName() == name)
+ {
+ nTab = i;
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/sc/source/ui/vba/vbaworksheets.hxx b/sc/source/ui/vba/vbaworksheets.hxx
new file mode 100644
index 000000000000..2ced68bc9e27
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheets.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_WORKSHEETS_HXX
+#define SC_VBA_WORKSHEETS_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <ooo/vba/excel/XWorksheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+#include "address.hxx"
+
+class ScModelObj;
+
+
+typedef CollTestImplHelper< ov::excel::XWorksheets > ScVbaWorksheets_BASE;
+
+class ScVbaWorksheets : public ScVbaWorksheets_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::sheet::XSpreadsheets > m_xSheets;
+protected:
+ // ScVbaWorksheets_BASE
+ virtual css::uno::Any getItemByStringIndex( const rtl::OUString& sIndex ) throw (css::uno::RuntimeException);
+public:
+ ScVbaWorksheets( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xSheets, const css::uno::Reference< css::frame::XModel >& xModel );
+ ScVbaWorksheets( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XEnumerationAccess >& xEnum, const css::uno::Reference< css::frame::XModel >& xModel );
+ virtual ~ScVbaWorksheets() {}
+
+ bool isSelectedSheets();
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException);
+
+
+ // XWorksheets
+ virtual css::uno::Any SAL_CALL getVisible() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setVisible( const css::uno::Any& _visible ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Before, const css::uno::Any& After, const css::uno::Any& Count, const css::uno::Any& Type ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL Delete( ) throw (css::uno::RuntimeException);
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::uno::RuntimeException);
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource );
+ virtual void SAL_CALL Select( const css::uno::Any& Replace ) throw (css::uno::RuntimeException);
+ // ScVbaWorksheets_BASE
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& Index2 ) throw
+(css::uno::RuntimeException);
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+
+ static bool nameExists( css::uno::Reference <css::sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( css::lang::IllegalArgumentException );
+};
+
+#endif /* SC_VBA_WORKSHEETS_HXX */
diff --git a/sc/source/ui/vba/vbawsfunction.cxx b/sc/source/ui/vba/vbawsfunction.cxx
new file mode 100644
index 000000000000..60daa7303f2e
--- /dev/null
+++ b/sc/source/ui/vba/vbawsfunction.cxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/sheet/XFunctionAccess.hpp>
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/reflection/XIdlMethod.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <comphelper/anytostring.hxx>
+
+#include "vbawsfunction.hxx"
+#include "compiler.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+namespace {
+
+void lclConvertDoubleToBoolean( uno::Any& rAny )
+{
+ if( rAny.has< double >() )
+ {
+ double fValue = rAny.get< double >();
+ if( fValue == 0.0 )
+ rAny <<= false;
+ else if( fValue == 1.0 )
+ rAny <<= true;
+ // do nothing for other values or types
+ }
+}
+
+} // namespace
+
+ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
+ ScVbaWSFunction_BASE( xParent, xContext )
+{
+}
+
+uno::Reference< beans::XIntrospectionAccess >
+ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException)
+{
+ return uno::Reference<beans::XIntrospectionAccess>();
+}
+
+uno::Any SAL_CALL
+ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+{
+ // create copy of parameters, replace Excel range objects with UNO range objects
+ uno::Sequence< uno::Any > aParamTemp( Params );
+ if( aParamTemp.hasElements() )
+ {
+ uno::Any* pArray = aParamTemp.getArray();
+ uno::Any* pArrayEnd = pArray + aParamTemp.getLength();
+ for( ; pArray < pArrayEnd; ++pArray )
+ {
+ uno::Reference< excel::XRange > myRange( *pArray, uno::UNO_QUERY );
+ if( myRange.is() )
+ *pArray = myRange->getCellRange();
+ OSL_TRACE("Param[%d] is %s", (int)(pArray - aParamTemp.getConstArray()), rtl::OUStringToOString( comphelper::anyToString( *pArray ), RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+
+ uno::Any aRet;
+ bool bAsArray = true;
+
+ // special handing for some functions that don't work correctly in FunctionAccess
+ ScCompiler aCompiler( 0, ScAddress() );
+ OpCode eOpCode = aCompiler.GetEnglishOpCode( FunctionName.toAsciiUpperCase() );
+ switch( eOpCode )
+ {
+ // ISLOGICAL does not work in array formula mode
+ case ocIsLogical:
+ {
+ if( aParamTemp.getLength() != 1 )
+ throw lang::IllegalArgumentException();
+ const uno::Any& rParam = aParamTemp[ 0 ];
+ if( rParam.has< bool >() )
+ {
+ aRet <<= true;
+ }
+ else if( rParam.has< uno::Reference< table::XCellRange > >() ) try
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( rParam, uno::UNO_QUERY_THROW );
+ table::CellRangeAddress aRangeAddr = xRangeAddr->getRangeAddress();
+ bAsArray = (aRangeAddr.StartColumn != aRangeAddr.EndColumn) || (aRangeAddr.StartRow != aRangeAddr.EndRow);
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ break;
+ default:;
+ }
+
+ if( !aRet.hasValue() )
+ {
+ uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XFunctionAccess > xFunctionAccess( xSMgr->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FunctionAccess" ) ), mxContext ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPropSet( xFunctionAccess, uno::UNO_QUERY_THROW );
+ xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsArrayFunction" ) ), uno::Any( bAsArray ) );
+ aRet = xFunctionAccess->callFunction( FunctionName, aParamTemp );
+ }
+
+ /* Convert return value from double to to Boolean for some functions that
+ return Booleans. */
+ typedef uno::Sequence< uno::Sequence< uno::Any > > AnySeqSeq;
+ if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || (eOpCode == ocIsLogical) ||
+ (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == ocIsNA) ||
+ (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == ocIsOdd) ||
+ (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocNot) || (eOpCode == ocTrue) || (eOpCode == ocFalse) )
+ {
+ if( aRet.has< AnySeqSeq >() )
+ {
+ AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >();
+ for( sal_Int32 nRow = 0; nRow < aAnySeqSeq.getLength(); ++nRow )
+ for( sal_Int32 nCol = 0; nCol < aAnySeqSeq[ nRow ].getLength(); ++nCol )
+ lclConvertDoubleToBoolean( aAnySeqSeq[ nRow ][ nCol ] );
+ aRet <<= aAnySeqSeq;
+ }
+ else
+ {
+ lclConvertDoubleToBoolean( aRet );
+ }
+ }
+
+ /* Hack/workaround (?): shorten single-row matrix to simple array, shorten
+ 1x1 matrix to single value. */
+ if( aRet.has< AnySeqSeq >() )
+ {
+ AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >();
+ if( aAnySeqSeq.getLength() == 1 )
+ {
+ if( aAnySeqSeq[ 0 ].getLength() == 1 )
+ aRet = aAnySeqSeq[ 0 ][ 0 ];
+ else
+ aRet <<= aAnySeqSeq[ 0 ];
+ }
+ }
+
+#if 0
+ // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why?
+ // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function.
+ String aUpper( FunctionName );
+ ScCompiler aCompiler( NULL, ScAddress() );
+ OpCode eOp = aCompiler.GetEnglishOpCode( aUpper.ToUpperAscii() );
+ if( eOp == ocMatch )
+ {
+ double fVal = 0.0;
+ if( aRet >>= fVal )
+ return aRet;
+ uno::Sequence< uno::Sequence< uno::Any > > aSequence;
+ if( !( ( aRet >>= aSequence ) && ( aSequence.getLength() > 0 ) &&
+ ( aSequence[0].getLength() > 0 ) && ( aSequence[0][0] >>= fVal ) ) )
+ throw uno::RuntimeException();
+ aRet <<= fVal;
+ }
+#endif
+
+ return aRet;
+}
+
+void SAL_CALL
+ScVbaWSFunction::setValue(const rtl::OUString& /*PropertyName*/, const uno::Any& /*Value*/) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+{
+ throw beans::UnknownPropertyException();
+}
+
+uno::Any SAL_CALL
+ScVbaWSFunction::getValue(const rtl::OUString& /*PropertyName*/) throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ throw beans::UnknownPropertyException();
+}
+
+sal_Bool SAL_CALL
+ScVbaWSFunction::hasMethod(const rtl::OUString& Name) throw(uno::RuntimeException)
+{
+ sal_Bool bIsFound = sal_False;
+ try
+ {
+ // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized.
+ // but the function name used in WorksheetFunction is a programmatic name (seems English).
+ // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name.
+ ScCompiler aCompiler( NULL, ScAddress() );
+ if( aCompiler.IsEnglishSymbol( Name ) )
+ bIsFound = sal_True;
+ }
+ catch( uno::Exception& /*e*/ )
+ {
+ // failed to find name
+ }
+ return bIsFound;
+}
+
+sal_Bool SAL_CALL
+ScVbaWSFunction::hasProperty(const rtl::OUString& /*Name*/) throw(uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::rtl::OUString SAL_CALL
+ScVbaWSFunction::getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException)
+{
+ rtl::OUString sName = aApproximateName.toAsciiUpperCase();
+ if ( !hasMethod( sName ) )
+ return rtl::OUString();
+ return sName;
+}
+
+rtl::OUString&
+ScVbaWSFunction::getServiceImplName()
+{
+ static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWSFunction") );
+ return sImplName;
+}
+
+uno::Sequence< rtl::OUString >
+ScVbaWSFunction::getServiceNames()
+{
+ static uno::Sequence< rtl::OUString > aServiceNames;
+ if ( aServiceNames.getLength() == 0 )
+ {
+ aServiceNames.realloc( 1 );
+ aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.WorksheetFunction" ) );
+ }
+ return aServiceNames;
+}
diff --git a/sc/source/ui/vba/vbawsfunction.hxx b/sc/source/ui/vba/vbawsfunction.hxx
new file mode 100644
index 000000000000..ffd33849afe5
--- /dev/null
+++ b/sc/source/ui/vba/vbawsfunction.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_VBA_INTERIOR_HXX
+#define SC_VBA_INTERIOR_HXX
+
+#include <ooo/vba/excel/XWorksheetFunction.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include "vbarange.hxx"
+
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+typedef InheritedHelperInterfaceImpl1< ov::excel::XWorksheetFunction > ScVbaWSFunction_BASE;
+
+class ScVbaWSFunction : public ScVbaWSFunction_BASE
+{
+public:
+ ScVbaWSFunction( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext);
+ virtual ~ScVbaWSFunction(){}
+
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL invoke(const rtl::OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException);
+ virtual void SAL_CALL setValue(const rtl::OUString& PropertyName, const css::uno::Any& Value) throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getValue(const rtl::OUString& PropertyName) throw(css::beans::UnknownPropertyException, css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasMethod(const rtl::OUString& Name) throw(css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasProperty(const rtl::OUString& Name) throw(css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException);
+ // XHelperInterface
+ virtual rtl::OUString& getServiceImplName();
+ virtual css::uno::Sequence<rtl::OUString> getServiceNames();
+};
+#endif
+
diff --git a/sc/source/ui/view/auditsh.cxx b/sc/source/ui/view/auditsh.cxx
new file mode 100644
index 000000000000..2c80c154759d
--- /dev/null
+++ b/sc/source/ui/view/auditsh.cxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+
+#include "auditsh.hxx"
+#include "tabvwsh.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "document.hxx"
+
+//------------------------------------------------------------------------
+
+#define ScAuditingShell
+#include "scslots.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScAuditingShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScAuditingShell, SfxShell, ScResId(SCSTR_AUDITSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_AUDIT) );
+}
+
+
+//------------------------------------------------------------------------
+
+ScAuditingShell::ScAuditingShell(ScViewData* pData) :
+ SfxShell(pData->GetViewShell()),
+ pViewData( pData ),
+ nFunction( SID_FILL_ADD_PRED )
+{
+ SetPool( &pViewData->GetViewShell()->GetPool() );
+ SfxUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_AUDIT );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Auditing")));
+}
+
+//------------------------------------------------------------------------
+
+ScAuditingShell::~ScAuditingShell()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScAuditingShell::Execute( SfxRequest& rReq )
+{
+ SfxBindings& rBindings = pViewData->GetBindings();
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_FILL_ADD_PRED:
+ case SID_FILL_DEL_PRED:
+ case SID_FILL_ADD_SUCC:
+ case SID_FILL_DEL_SUCC:
+ nFunction = nSlot;
+ rBindings.Invalidate( SID_FILL_ADD_PRED );
+ rBindings.Invalidate( SID_FILL_DEL_PRED );
+ rBindings.Invalidate( SID_FILL_ADD_SUCC );
+ rBindings.Invalidate( SID_FILL_DEL_SUCC );
+ break;
+ case SID_CANCEL: // Escape
+ case SID_FILL_NONE:
+ pViewData->GetViewShell()->SetAuditShell( FALSE );
+ break;
+
+ case SID_FILL_SELECT:
+ {
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pXItem;
+ const SfxPoolItem* pYItem;
+ if ( pReqArgs->GetItemState( SID_RANGE_COL, TRUE, &pXItem ) == SFX_ITEM_SET
+ && pReqArgs->GetItemState( SID_RANGE_ROW, TRUE, &pYItem ) == SFX_ITEM_SET )
+ {
+ DBG_ASSERT( pXItem->ISA(SfxInt16Item) && pYItem->ISA(SfxInt32Item),
+ "falsche Items" );
+ SCsCOL nCol = static_cast<SCsCOL>(((const SfxInt16Item*) pXItem)->GetValue());
+ SCsROW nRow = static_cast<SCsROW>(((const SfxInt32Item*) pYItem)->GetValue());
+ ScViewFunc* pView = pViewData->GetView();
+ pView->MoveCursorAbs( nCol, nRow, SC_FOLLOW_LINE, FALSE, FALSE );
+ switch ( nFunction )
+ {
+ case SID_FILL_ADD_PRED:
+ pView->DetectiveAddPred();
+ break;
+ case SID_FILL_DEL_PRED:
+ pView->DetectiveDelPred();
+ break;
+ case SID_FILL_ADD_SUCC:
+ pView->DetectiveAddSucc();
+ break;
+ case SID_FILL_DEL_SUCC:
+ pView->DetectiveDelSucc();
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScAuditingShell::GetState( SfxItemSet& rSet )
+{
+ rSet.Put( SfxBoolItem( nFunction, TRUE ) ); // aktive Funktion markieren
+}
+
+
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
new file mode 100644
index 000000000000..c880a29f8067
--- /dev/null
+++ b/sc/source/ui/view/cellsh.cxx
@@ -0,0 +1,1005 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svtools/cliplistener.hxx>
+#include <svtools/insdlg.hxx>
+#include <sot/formats.hxx>
+#include <svx/hlnkitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <editeng/langitem.hxx>
+
+#include "cellsh.hxx"
+#include "sc.hrc"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "cell.hxx"
+#include "scmod.hxx"
+#include "globstr.hrc"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "scabstdlg.hxx"
+#include "dociter.hxx"
+#include "postit.hxx"
+
+//------------------------------------------------------------------
+
+#define ScCellShell
+#define CellMovement
+#include "scslots.hxx"
+
+#define SearchSettings
+#include <svx/svxslots.hxx>
+
+TYPEINIT1( ScCellShell, ScFormatShell );
+
+SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_FORMAT));
+ SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
+}
+
+
+ScCellShell::ScCellShell(ScViewData* pData) :
+ ScFormatShell(pData),
+ pImpl( new CellShell_Impl() ),
+ bPastePossible(FALSE)
+{
+ SetHelpId(HID_SCSHELL_CELLSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell")));
+}
+
+ScCellShell::~ScCellShell()
+{
+ if ( pImpl->m_pClipEvtLstnr )
+ {
+ pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), FALSE );
+
+ // #103849# The listener may just now be waiting for the SolarMutex and call the link
+ // afterwards, in spite of RemoveListener. So the link has to be reset, too.
+ pImpl->m_pClipEvtLstnr->ClearCallbackLink();
+
+ pImpl->m_pClipEvtLstnr->release();
+ }
+
+ delete pImpl->m_pLinkedDlg;
+ delete pImpl->m_pRequest;
+ delete pImpl;
+}
+
+//------------------------------------------------------------------
+
+void ScCellShell::GetBlockState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ ScRange aMarkRange;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
+ BOOL bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
+ BOOL bOnlyNotBecauseOfMatrix;
+ BOOL bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ nCol1 = aMarkRange.aStart.Col();
+ nRow1 = aMarkRange.aStart.Row();
+ nCol2 = aMarkRange.aEnd.Col();
+ nRow2 = aMarkRange.aEnd.Row();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ BOOL bDisable = FALSE;
+ BOOL bNeedEdit = TRUE; // muss Selektion editierbar sein?
+ switch ( nWhich )
+ {
+ case FID_FILL_TO_BOTTOM: // Fuellen oben/unten
+ case FID_FILL_TO_TOP: // mind. 2 Zeilen markiert?
+ bDisable = (!bSimpleArea) || (nRow1 == nRow2);
+ if ( !bDisable && bEditable )
+ { // Matrix nicht zerreissen
+ if ( nWhich == FID_FILL_TO_BOTTOM )
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol2, nRow1, rMark ); // erste Zeile
+ else
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow2, nCol2, nRow2, rMark ); // letzte Zeile
+ }
+ break;
+
+ case FID_FILL_TO_RIGHT: // Fuellen links/rechts
+ case FID_FILL_TO_LEFT: // mind. 2 Spalten markiert?
+ bDisable = (!bSimpleArea) || (nCol1 == nCol2);
+ if ( !bDisable && bEditable )
+ { // Matrix nicht zerreissen
+ if ( nWhich == FID_FILL_TO_RIGHT )
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol1, nRow2, rMark ); // erste Spalte
+ else
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte
+ }
+ break;
+
+ case FID_FILL_SERIES: // Block fuellen
+ case SID_OPENDLG_TABOP: // Mehrfachoperationen, mind. 2 Zellen markiert?
+ if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
+ bDisable = TRUE;
+ else
+ bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
+
+ if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
+ { // Matrix nicht zerreissen
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol2, nRow1, rMark ) // erste Zeile
+ || pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow2, nCol2, nRow2, rMark ) // letzte Zeile
+ || pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol1, nRow2, rMark ) // erste Spalte
+ || pDoc->HasSelectedBlockMatrixFragment(
+ nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte
+ }
+ break;
+
+ case SID_CUT: // Ausschneiden,
+ case FID_INS_CELL: // Zellen einfuegen, nur einf. Selektion
+ bDisable = (!bSimpleArea);
+ break;
+
+ case FID_INS_ROW: // insert rows
+ case FID_INS_CELLSDOWN:
+ bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
+ break;
+
+ case FID_INS_COLUMN: // insert columns
+ case FID_INS_CELLSRIGHT:
+ bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
+ break;
+
+ case SID_COPY: // Kopieren
+ // nur wegen Matrix nicht editierbar? Matrix nicht zerreissen
+ //! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit
+ //! muss man leben.. wird in Copy-Routine abgefangen, sonst
+ //! muesste hier nochmal Aufwand getrieben werden
+ if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
+ bNeedEdit = FALSE; // erlaubt, wenn geschuetzt/ReadOnly
+ break;
+
+ case SID_AUTOFORMAT: // Autoformat, mind. 3x3 selektiert
+ bDisable = (!bSimpleArea)
+ || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
+ break;
+
+ case SID_OPENDLG_CONDFRMT :
+ {
+ if ( !bEditable && bOnlyNotBecauseOfMatrix )
+ {
+ bNeedEdit = FALSE;
+ }
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ bDisable = TRUE;
+ }
+ }
+ break;
+
+ case FID_CONDITIONAL_FORMAT :
+ case SID_CELL_FORMAT_RESET :
+ case FID_CELL_FORMAT :
+ case SID_ENABLE_HYPHENATION :
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ if ( !bEditable && bOnlyNotBecauseOfMatrix )
+ bNeedEdit = FALSE;
+ break;
+
+ case FID_VALIDATION:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ bDisable = TRUE;
+ }
+ }
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAGANA:
+ ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
+ break;
+ }
+ if (!bDisable && bNeedEdit && !bEditable)
+ bDisable = TRUE;
+
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ else if (nWhich == SID_ENABLE_HYPHENATION)
+ {
+ // toggle slots need a bool item
+ rSet.Put( SfxBoolItem( nWhich, FALSE ) );
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// Funktionen, die je nach Cursorposition disabled sind
+// Default:
+// SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
+
+void ScCellShell::GetCellState( SfxItemSet& rSet )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
+ ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ BOOL bDisable = FALSE;
+ BOOL bNeedEdit = TRUE; // muss Cursorposition editierbar sein?
+ switch ( nWhich )
+ {
+ case SID_THESAURUS:
+ {
+ CellType eType = pDoc->GetCellType( aCursor );
+ bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
+ if (!bDisable)
+ {
+ // test for available languages
+ USHORT nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
+ bDisable = !ScModule::HasThesaurusLanguage( nLang );
+ }
+ }
+ break;
+ case SID_OPENDLG_FUNCTION:
+ {
+ ScMarkData aMarkData=GetViewData()->GetMarkData();
+ aMarkData.MarkToSimple();
+ ScRange aRange;
+ aMarkData.GetMarkArea(aRange);
+ if(aMarkData.IsMarked())
+ {
+ if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
+ aRange.aEnd.Col(),aRange.aEnd.Row() ))
+ {
+ bDisable = TRUE;
+ }
+ bNeedEdit=FALSE;
+ }
+
+ }
+ break;
+ case SID_INSERT_POSTIT:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ bDisable = TRUE;
+ }
+ }
+ break;
+ }
+ if (!bDisable && bNeedEdit)
+ if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
+ aCursor.Col(),aCursor.Row() ))
+ bDisable = TRUE;
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ nWhich = aIter.NextWhich();
+ }
+}
+
+sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
+ SotFormatStringId nFormatId )
+{
+ if ( rDataHelper.HasFormat( nFormatId ) )
+ {
+ // #90675# translated format name strings are no longer inserted here,
+ // handled by "paste special" dialog / toolbox controller instead.
+ // Only the object type name has to be set here:
+ String aStrVal;
+ if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ {
+ TransferableObjectDescriptor aDesc;
+ if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
+ SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
+ aStrVal = aDesc.maTypeName;
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
+ || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
+ {
+ String aSource;
+ SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
+ }
+
+ if ( aStrVal.Len() )
+ rFormats.AddClipbrdFormat( nFormatId, aStrVal );
+ else
+ rFormats.AddClipbrdFormat( nFormatId );
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
+{
+ Window* pWin = GetViewData()->GetActiveWin();
+ BOOL bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
+
+ if ( !bDraw )
+ {
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
+ }
+
+ if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
+}
+
+// Einfuegen, Inhalte einfuegen
+
+BOOL lcl_IsCellPastePossible( const TransferableDataHelper& rData )
+{
+ BOOL bPossible = FALSE;
+ if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
+ bPossible = TRUE;
+ else
+ {
+ if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
+ rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
+ rData.HasFormat( FORMAT_PRIVATE ) ||
+ rData.HasFormat( SOT_FORMAT_RTF ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
+ rData.HasFormat( SOT_FORMAT_STRING ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
+ {
+ bPossible = TRUE;
+ }
+ }
+ return bPossible;
+}
+
+IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
+{
+ if ( pDataHelper )
+ {
+ bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+ rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ return 0;
+}
+
+
+void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
+{
+// SID_PASTE
+// SID_PASTE_SPECIAL
+// SID_CLIPBOARD_FORMAT_ITEMS
+
+ if ( !pImpl->m_pClipEvtLstnr )
+ {
+ // create listener
+ pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
+ pImpl->m_pClipEvtLstnr->acquire();
+ Window* pWin = GetViewData()->GetActiveWin();
+ pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, TRUE );
+
+ // get initial state
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+ bPastePossible = lcl_IsCellPastePossible( aDataHelper );
+ }
+
+ BOOL bDisable = !bPastePossible;
+
+ // Zellschutz / Multiselektion
+
+ if (!bDisable)
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
+ if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
+ bDisable = TRUE;
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ bDisable = TRUE;
+ }
+
+ if (bDisable)
+ {
+ rSet.DisableItem( SID_PASTE );
+ rSet.DisableItem( SID_PASTE_SPECIAL );
+ rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
+ {
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ GetPossibleClipboardFormats( aFormats );
+ rSet.Put( aFormats );
+ }
+}
+
+// only SID_HYPERLINK_GETLINK:
+
+void ScCellShell::GetHLinkState( SfxItemSet& rSet )
+{
+ // always return an item (or inserting will be disabled)
+ // if the cell at the cursor contains only a link, return that link
+
+ SvxHyperlinkItem aHLinkItem;
+ if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
+ {
+ //! put selected text into item?
+ }
+
+ rSet.Put(aHLinkItem);
+}
+
+void ScCellShell::GetState(SfxItemSet &rSet)
+{
+ // removed: SID_BORDER_OBJECT (old Basic)
+
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+// BOOL bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace();
+// BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScViewData* pData = GetViewData();
+ ScDocument* pDoc = pData->GetDocument();
+ ScMarkData& rMark = pData->GetMarkData();
+ SCCOL nPosX = pData->GetCurX();
+ SCROW nPosY = pData->GetCurY();
+ SCTAB nTab = pData->GetTabNo();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_DETECTIVE_REFRESH:
+ if (!pDoc->HasDetectiveOperations())
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_RANGE_ADDRESS:
+ {
+ ScRange aRange;
+ if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ String aStr;
+ USHORT nFlags = SCA_VALID | SCA_TAB_3D;
+ aRange.Format(aStr,nFlags,pDoc);
+ rSet.Put( SfxStringItem( nWhich, aStr ) );
+ }
+ }
+ break;
+
+ case SID_RANGE_NOTETEXT:
+ {
+ // #43343# always take cursor position, do not use top-left cell of selection
+ ScAddress aPos( nPosX, nPosY, nTab );
+ String aNoteText;
+ if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
+ aNoteText = pNote->GetText();
+ rSet.Put( SfxStringItem( nWhich, aNoteText ) );
+ }
+ break;
+
+ case SID_RANGE_ROW:
+ rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
+ break;
+
+ case SID_RANGE_COL:
+ rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
+ break;
+
+ case SID_RANGE_TABLE:
+ rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
+ break;
+
+ case SID_RANGE_VALUE:
+ {
+ double nValue;
+ pDoc->GetValue( nPosX, nPosY, nTab, nValue );
+ rSet.Put( ScDoubleItem( nWhich, nValue ) );
+ }
+ break;
+
+ case SID_RANGE_FORMULA:
+ {
+ String aString;
+ pDoc->GetFormula( nPosX, nPosY, nTab, aString );
+ if( aString.Len() == 0 )
+ {
+ pDoc->GetInputString( nPosX, nPosY, nTab, aString );
+ }
+ rSet.Put( SfxStringItem( nWhich, aString ) );
+ }
+ break;
+
+ case SID_RANGE_TEXTVALUE:
+ {
+ String aString;
+ pDoc->GetString( nPosX, nPosY, nTab, aString );
+ rSet.Put( SfxStringItem( nWhich, aString ) );
+ }
+ break;
+
+ case SID_STATUS_SELMODE:
+ {
+ /* 0: STD Click hebt Sel auf
+ * 1: ER Click erweitert Selektion
+ * 2: ERG Click definiert weitere Selektion
+ */
+ USHORT nMode = pTabViewShell->GetLockedModifiers();
+
+ switch ( nMode )
+ {
+ case KEY_SHIFT: nMode = 1; break;
+ case KEY_MOD1: nMode = 2; break; // Control-Taste
+ case 0:
+ default:
+ nMode = 0;
+ }
+
+ rSet.Put( SfxUInt16Item( nWhich, nMode ) );
+ }
+ break;
+
+ case SID_STATUS_DOCPOS:
+ {
+ String aStr( ScGlobal::GetRscString( STR_TABLE ) );
+
+ aStr += ' ';
+ aStr += String::CreateFromInt32( nTab + 1 );
+ aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aStr += String::CreateFromInt32( nTabCount );
+ rSet.Put( SfxStringItem( nWhich, aStr ) );
+ }
+ break;
+
+ // Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst
+
+ // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
+ // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
+ case SID_TABLE_CELL:
+ {
+ // Testen, ob Fehler unter Cursor
+ // (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)
+
+ // In interpreter may happen via rescheduled Basic
+ if ( pDoc->IsInInterpreter() )
+ rSet.Put( SfxStringItem( nWhich,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
+ else
+ {
+ USHORT nErrCode = 0;
+ ScBaseCell* pCell;
+ pDoc->GetCell( nPosX, nPosY, nTab, pCell );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ if (!pFCell->IsRunning())
+ nErrCode = pFCell->GetErrCode();
+ }
+
+ String aFuncStr;
+ if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
+ rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
+ }
+ }
+ break;
+
+ case SID_DATA_SELECT:
+ // HasSelectionData includes column content and validity,
+ // page fields have to be checked separately.
+ if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
+ !pTabViewShell->HasPageFieldDataAtCursor() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_STATUS_SUM:
+ {
+ String aFuncStr;
+ if ( pTabViewShell->GetFunction( aFuncStr ) )
+ rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
+ }
+ break;
+
+ case FID_MERGE_ON:
+ if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_MERGE_OFF:
+ if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_MERGE_TOGGLE:
+ if ( pDoc->GetChangeTrack() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ bool bCanMerge = pTabViewShell->TestMergeCells();
+ bool bCanSplit = pTabViewShell->TestRemoveMerge();
+ if( !bCanMerge && !bCanSplit )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
+ }
+ break;
+
+ case FID_INS_ROWBRK:
+ if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_INS_COLBRK:
+ if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_DEL_ROWBRK:
+ if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_DEL_COLBRK:
+ if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_FILL_TAB:
+ if ( nTabSelCount < 2 )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_SELECT_SCENARIO:
+ {
+ // ScDocument* pDoc = GetViewData()->GetDocument();
+ // SCTAB nTab = GetViewData()->GetTabNo();
+ List aList;
+
+ Color aDummyCol;
+
+ if ( !pDoc->IsScenario(nTab) )
+ {
+ String aStr;
+ USHORT nFlags;
+ SCTAB nScTab = nTab + 1;
+ String aProtect;
+ bool bSheetProtected = pDoc->IsTabProtected(nTab);
+
+ while ( pDoc->IsScenario(nScTab) )
+ {
+ pDoc->GetName( nScTab, aStr );
+ aList.Insert( new String( aStr ), LIST_APPEND );
+ pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
+ aList.Insert( new String( aStr ), LIST_APPEND );
+ // Protection is TRUE if both Sheet and Scenario are protected
+ aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
+ aList.Insert( new String( aProtect), LIST_APPEND );
+ ++nScTab;
+ }
+ }
+ else
+ {
+ String aComment;
+ USHORT nDummyFlags;
+ pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
+ DBG_ASSERT( aList.Count() == 0, "List not empty!" );
+ aList.Insert( new String( aComment ) );
+ }
+
+ rSet.Put( SfxStringListItem( nWhich, &aList ) );
+
+ ULONG nCount = aList.Count();
+ for ( ULONG i=0; i<nCount; i++ )
+ delete (String*) aList.GetObject(i);
+ }
+ break;
+
+ case FID_ROW_HIDE:
+ case FID_ROW_SHOW:
+ case FID_COL_HIDE:
+ case FID_COL_SHOW:
+ case FID_COL_OPT_WIDTH:
+ case FID_ROW_OPT_HEIGHT:
+ case FID_DELETE_CELL:
+ if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
+ rSet.DisableItem( nWhich );
+ break;
+
+/* Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
+ case SID_DELETE:
+ {
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ const SfxItemSet& rAttrSet = GetSelectionPattern()->GetItemSet();
+ const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, TRUE );
+ if ( rProtAttr.GetProtection() )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+*/
+ case SID_OUTLINE_MAKE:
+ {
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ case SID_OUTLINE_SHOW:
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else if (!pTabViewShell->OutlinePossible(FALSE))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OUTLINE_HIDE:
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else if (!pTabViewShell->OutlinePossible(TRUE))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OUTLINE_REMOVE:
+ {
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else
+ {
+ BOOL bCol, bRow;
+ pTabViewShell->TestRemoveOutline( bCol, bRow );
+ if ( !bCol && !bRow )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_COL_WIDTH:
+ {
+ //GetViewData()->GetCurX();
+ SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
+ rSet.Put( aWidthItem );
+ if ( pDocSh->IsReadOnly())
+ rSet.DisableItem( nWhich );
+
+ //XXX Disablen wenn nicht eindeutig
+ }
+ break;
+
+ case FID_ROW_HEIGHT:
+ {
+ //GetViewData()->GetCurY();
+ SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
+ rSet.Put( aHeightItem );
+ //XXX Disablen wenn nicht eindeutig
+ if ( pDocSh->IsReadOnly())
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DETECTIVE_FILLMODE:
+ rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
+ break;
+
+ case FID_INPUTLINE_STATUS:
+ DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
+ break;
+
+ case SID_SCENARIOS: // Szenarios:
+ if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // nur, wenn etwas selektiert
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_NOTE_VISIBLE:
+ {
+ const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
+ if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
+ rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DELETE_NOTE:
+ {
+ BOOL bEnable = FALSE;
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ if ( pDoc->IsSelectionEditable( rMark ) )
+ {
+ // look for at least one note in selection
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, FALSE );
+ ULONG nCount = aRanges.Count();
+ for (ULONG nPos=0; nPos<nCount && !bEnable; nPos++)
+ {
+ ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
+ for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
+ if ( pCell->HasNote() )
+ bEnable = TRUE; // note found
+ }
+ }
+ }
+ else
+ {
+ bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
+ pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
+ }
+ if ( !bEnable )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_OPENDLG_CONSOLIDATE:
+ case SCITEM_CONSOLIDATEDATA:
+ {
+ if(pDoc->GetChangeTrack()!=NULL)
+ rSet.DisableItem( nWhich);
+ }
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ case SID_HANGUL_HANJA_CONVERSION:
+ ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
+ break;
+
+ case FID_USE_NAME:
+ {
+ if ( pDocSh && pDocSh->IsDocShared() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ ScRange aRange;
+ if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_DEFINE_NAME:
+ case FID_INSERT_NAME:
+ case SID_DEFINE_COLROWNAMERANGES:
+ {
+ if ( pDocSh && pDocSh->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_SPELL_DIALOG:
+ {
+ if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
+ {
+ bool bVisible = false;
+ SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
+ if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
+ {
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
+ Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
+ if ( pWin && pWin->IsVisible() )
+ {
+ bVisible = true;
+ }
+ }
+ if ( !bVisible )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ }
+ break;
+
+ } // switch ( nWitch )
+ nWhich = aIter.NextWhich();
+ } // while ( nWitch )
+}
+
+//------------------------------------------------------------------
+
+
+
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
new file mode 100644
index 000000000000..95d86032ef56
--- /dev/null
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -0,0 +1,2206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+//------------------------------------------------------------------
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+#define _SI_NOSBXCONTROLS
+#define _VCONT_HXX
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+
+//------------------------------------------------------------------
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+
+#define _ZFORLIST_DECLARE_TABLE
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/svxdlg.hxx>
+#include <sot/formats.hxx>
+#include <svx/postattr.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <sfx2/passwd.hxx>
+#include <svx/hlnkitem.hxx>
+#include <basic/sbxcore.hxx>
+#include <unotools/useroptions.hxx>
+#include <vcl/waitobj.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "cellsh.hxx"
+#include "sc.hrc"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+//CHINA001 #include "inscldlg.hxx"
+//CHINA001 #include "inscodlg.hxx"
+//CHINA001 #include "delcldlg.hxx"
+//CHINA001 #include "delcodlg.hxx"
+//CHINA001 #include "filldlg.hxx"
+//CHINA001 #include "groupdlg.hxx"
+#include "impex.hxx"
+#include "reffind.hxx"
+//CHINA001 #include "namecrea.hxx"
+#include "uiitems.hxx"
+#include "reffact.hxx"
+//CHINA001 #include "namepast.hxx"
+#include "inputhdl.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+//CHINA001 #include "linkarea.hxx"
+#include "docfunc.hxx"
+#include "editable.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpgroup.hxx" // for ScDPNumGroupInfo
+#include "spellparam.hxx"
+#include "postit.hxx"
+#include "clipparam.hxx"
+
+#include "globstr.hrc"
+#include "scui_def.hxx" //CHINA001
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <cppuhelper/bootstrap.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------
+void ScCellShell::ExecuteEdit( SfxRequest& rReq )
+{
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ // Eingabe beenden
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ switch ( nSlot )
+ {
+ case FID_DEFINE_NAME:
+ case FID_USE_NAME:
+ case FID_INSERT_NAME:
+ case SID_SPELL_DIALOG:
+ case SID_HANGUL_HANJA_CONVERSION:
+
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ( nSlot )
+ {
+ //
+ // Einfuegen / Loeschen von Zellen / Zeilen / Spalten
+ //
+
+ case FID_INS_ROW:
+ pTabViewShell->InsertCells(INS_INSROWS);
+ rReq.Done();
+ break;
+
+ case FID_INS_COLUMN:
+ pTabViewShell->InsertCells(INS_INSCOLS);
+ rReq.Done();
+ break;
+
+ case FID_INS_CELLSDOWN:
+ pTabViewShell->InsertCells(INS_CELLSDOWN);
+ rReq.Done();
+ break;
+
+ case FID_INS_CELLSRIGHT:
+ pTabViewShell->InsertCells(INS_CELLSRIGHT);
+ rReq.Done();
+ break;
+
+ case SID_DEL_ROWS:
+ pTabViewShell->DeleteCells( DEL_DELROWS );
+ rReq.Done();
+ break;
+
+ case SID_DEL_COLS:
+ pTabViewShell->DeleteCells( DEL_DELCOLS );
+ rReq.Done();
+ break;
+
+ case FID_INS_CELL:
+ {
+ InsCellCmd eCmd=INS_NONE;
+
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags;
+
+ if( IS_AVAILABLE( FID_INS_CELL, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+ if( aFlags.Len() )
+ {
+ switch( aFlags.GetChar(0) )
+ {
+ case 'V': eCmd = INS_CELLSDOWN ;break;
+ case '>': eCmd = INS_CELLSRIGHT ;break;
+ case 'R': eCmd = INS_INSROWS ;break;
+ case 'C': eCmd = INS_INSCOLS ;break;
+ }
+ }
+ }
+ else
+ {
+ if ( GetViewData()->SimpleColMarked() )
+ eCmd = INS_INSCOLS;
+ else if ( GetViewData()->SimpleRowMarked() )
+ eCmd = INS_INSROWS;
+ else
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ BOOL bTheFlag=(pDoc->GetChangeTrack()!=NULL);
+
+//CHINA001 ScInsertCellDlg* pDlg = new ScInsertCellDlg( pTabViewShell->GetDialogParent(),
+//CHINA001 bTheFlag);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertCellDlg* pDlg = pFact->CreateScInsertCellDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_INSCELL, bTheFlag);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if (pDlg->Execute() == RET_OK)
+ eCmd = pDlg->GetInsCellCmd();
+ delete pDlg;
+ }
+ }
+
+ if (eCmd!=INS_NONE)
+ {
+ pTabViewShell->InsertCells( eCmd );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aParam;
+
+ switch( eCmd )
+ {
+ case INS_CELLSDOWN: aParam='V'; break;
+ case INS_CELLSRIGHT: aParam='>'; break;
+ case INS_INSROWS: aParam='R'; break;
+ case INS_INSCOLS: aParam='C'; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ rReq.AppendItem( SfxStringItem( FID_INS_CELL, aParam ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case FID_DELETE_CELL:
+ {
+ DelCellCmd eCmd = DEL_NONE;
+
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags;
+
+ if( IS_AVAILABLE( FID_DELETE_CELL, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+ if( aFlags.Len() )
+ {
+ switch( aFlags.GetChar(0) )
+ {
+ case 'U': eCmd = DEL_CELLSUP ;break;
+ case 'L': eCmd = DEL_CELLSLEFT ;break;
+ case 'R': eCmd = DEL_DELROWS ;break;
+ case 'C': eCmd = DEL_DELCOLS ;break;
+ }
+ }
+ }
+ else
+ {
+ if ( GetViewData()->SimpleColMarked() )
+ eCmd = DEL_DELCOLS;
+ else if ( GetViewData()->SimpleRowMarked() )
+ eCmd = DEL_DELROWS;
+ else
+ {
+ ScRange aRange;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ BOOL bTheFlag=GetViewData()->IsMultiMarked() ||
+ (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE_FILTERED) ||
+ (pDoc->GetChangeTrack() != NULL);
+
+ //CHINA001 ScDeleteCellDlg* pDlg = new ScDeleteCellDlg(
+ //CHINA001 pTabViewShell->GetDialogParent(),bTheFlag);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDeleteCellDlg* pDlg = pFact->CreateScDeleteCellDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_DELCELL, bTheFlag );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if (pDlg->Execute() == RET_OK)
+ eCmd = pDlg->GetDelCellCmd();
+ delete pDlg;
+ }
+ }
+
+ if (eCmd != DEL_NONE )
+ {
+ pTabViewShell->DeleteCells( eCmd );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aParam;
+
+ switch( eCmd )
+ {
+ case DEL_CELLSUP: aParam='U'; break;
+ case DEL_CELLSLEFT: aParam='L'; break;
+ case DEL_DELROWS: aParam='R'; break;
+ case DEL_DELCOLS: aParam='C'; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ rReq.AppendItem( SfxStringItem( FID_DELETE_CELL, aParam ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //
+ // Inhalte von Zellen loeschen
+ //
+
+ case SID_DELETE_CONTENTS:
+ pTabViewShell->DeleteContents( IDF_CONTENTS );
+ rReq.Done();
+ break;
+
+ case SID_DELETE:
+ {
+ USHORT nFlags = IDF_NONE;
+
+ if ( pReqArgs!=NULL && pTabViewShell->SelectionEditable() )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags = 'A';
+
+ if( IS_AVAILABLE( SID_DELETE, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+
+ aFlags.ToUpperAscii();
+ BOOL bCont = TRUE;
+
+ for( xub_StrLen i=0 ; bCont && i<aFlags.Len() ; i++ )
+ {
+ switch( aFlags.GetChar(i) )
+ {
+ case 'A': // Alle
+ nFlags |= IDF_ALL;
+ bCont = FALSE; // nicht mehr weitermachen!
+ break;
+ case 'S': nFlags |= IDF_STRING; break;
+ case 'V': nFlags |= IDF_VALUE; break;
+ case 'D': nFlags |= IDF_DATETIME; break;
+ case 'F': nFlags |= IDF_FORMULA; break;
+ case 'N': nFlags |= IDF_NOTE; break;
+ case 'T': nFlags |= IDF_ATTRIB; break;
+ case 'O': nFlags |= IDF_OBJECTS; break;
+ }
+ }
+ }
+ else
+ {
+ ScEditableTester aTester( pTabViewShell );
+ if (aTester.IsEditable())
+ {
+ //CHINA001 ScDeleteContentsDlg* pDlg = new ScDeleteContentsDlg( pTabViewShell->GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDeleteContentsDlg* pDlg = pFact->CreateScDeleteContentsDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_DELCONT );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if ( pDoc->IsTabProtected(nTab) )
+ pDlg->DisableObjects();
+ if (pDlg->Execute() == RET_OK)
+ {
+ nFlags = pDlg->GetDelContentsCmdBits();
+ }
+ delete pDlg;
+ }
+ else
+ pTabViewShell->ErrorMessage(aTester.GetMessageId());
+ }
+
+ if( nFlags != IDF_NONE )
+ {
+ pTabViewShell->DeleteContents( nFlags );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aFlags;
+
+ if( nFlags == IDF_ALL )
+ {
+ aFlags += 'A';
+ }
+ else
+ {
+ if( nFlags & IDF_STRING ) aFlags += 'S';
+ if( nFlags & IDF_VALUE ) aFlags += 'V';
+ if( nFlags & IDF_DATETIME ) aFlags += 'D';
+ if( nFlags & IDF_FORMULA ) aFlags += 'F';
+ if( nFlags & IDF_NOTE ) aFlags += 'N';
+ if( nFlags & IDF_ATTRIB ) aFlags += 'T';
+ if( nFlags & IDF_OBJECTS ) aFlags += 'O';
+ }
+
+ rReq.AppendItem( SfxStringItem( SID_DELETE, aFlags ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //
+ // Ausfuellen...
+ //
+
+ case FID_FILL_TO_BOTTOM:
+ pTabViewShell->FillSimple( FILL_TO_BOTTOM );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TO_RIGHT:
+ pTabViewShell->FillSimple( FILL_TO_RIGHT );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TO_TOP:
+ pTabViewShell->FillSimple( FILL_TO_TOP );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TO_LEFT:
+ pTabViewShell->FillSimple( FILL_TO_LEFT );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TAB:
+ {
+ USHORT nFlags = IDF_NONE;
+ USHORT nFunction = PASTE_NOFUNC;
+ BOOL bSkipEmpty = FALSE;
+ BOOL bAsLink = FALSE;
+
+ if ( pReqArgs!=NULL && pTabViewShell->SelectionEditable() )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags = 'A';
+
+ if( IS_AVAILABLE( FID_FILL_TAB, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+
+ aFlags.ToUpperAscii();
+ BOOL bCont = TRUE;
+
+ for( xub_StrLen i=0 ; bCont && i<aFlags.Len() ; i++ )
+ {
+ switch( aFlags.GetChar(i) )
+ {
+ case 'A': // Alle
+ nFlags |= IDF_ALL;
+ bCont = FALSE; // nicht mehr weitermachen!
+ break;
+ case 'S': nFlags |= IDF_STRING; break;
+ case 'V': nFlags |= IDF_VALUE; break;
+ case 'D': nFlags |= IDF_DATETIME; break;
+ case 'F': nFlags |= IDF_FORMULA; break;
+ case 'N': nFlags |= IDF_NOTE; break;
+ case 'T': nFlags |= IDF_ATTRIB; break;
+ }
+ }
+ }
+ else
+ {
+//CHINA001 ScInsertContentsDlg* pDlg =
+//CHINA001 new ScInsertContentsDlg(pTabViewShell->GetDialogParent(),
+//CHINA001 0, /* nCheckDefaults */
+//CHINA001 &ScGlobal::GetRscString(STR_FILL_TAB) );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertContentsDlg* pDlg = pFact->CreateScInsertContentsDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_INSCONT, 0, /* nCheckDefaults */
+ &ScGlobal::GetRscString(STR_FILL_TAB));
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetFillMode(TRUE);
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ nFlags = pDlg->GetInsContentsCmdBits();
+ nFunction = pDlg->GetFormulaCmdBits();
+ bSkipEmpty = pDlg->IsSkipEmptyCells();
+ bAsLink = pDlg->IsLink();
+ // MoveMode gibt's bei Tabelle fuellen nicht
+ }
+ delete pDlg;
+ }
+
+ if( nFlags != IDF_NONE )
+ {
+ pTabViewShell->FillTab( nFlags, nFunction, bSkipEmpty, bAsLink );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aFlags;
+
+ if( nFlags == IDF_ALL )
+ {
+ aFlags += 'A';
+ }
+ else
+ {
+ if( nFlags & IDF_STRING ) aFlags += 'S';
+ if( nFlags & IDF_VALUE ) aFlags += 'V';
+ if( nFlags & IDF_DATETIME ) aFlags += 'D';
+ if( nFlags & IDF_FORMULA ) aFlags += 'F';
+ if( nFlags & IDF_NOTE ) aFlags += 'N';
+ if( nFlags & IDF_ATTRIB ) aFlags += 'T';
+ }
+
+ rReq.AppendItem( SfxStringItem( FID_FILL_TAB, aFlags ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case FID_FILL_SERIES:
+ {
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ USHORT nPossDir = FDS_OPT_NONE;
+ FillDir eFillDir = FILL_TO_BOTTOM;
+ FillCmd eFillCmd = FILL_LINEAR;
+ FillDateCmd eFillDateCmd = FILL_DAY;
+ double fStartVal = MAXDOUBLE;
+ double fIncVal = 1;
+ double fMaxVal = MAXDOUBLE;
+ BOOL bDoIt = FALSE;
+
+ GetViewData()->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ if( nStartCol!=nEndCol )
+ {
+ nPossDir |= FDS_OPT_HORZ;
+ eFillDir=FILL_TO_RIGHT;
+ }
+
+ if( nStartRow!=nEndRow )
+ {
+ nPossDir |= FDS_OPT_VERT;
+ eFillDir=FILL_TO_BOTTOM;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aFillDir, aFillCmd, aFillDateCmd;
+ String aFillStep, aFillStart, aFillMax;
+ sal_uInt32 nKey;
+ double fTmpVal;
+
+ bDoIt=FALSE;
+
+ if( IS_AVAILABLE( FID_FILL_SERIES, &pItem ) )
+ aFillDir = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ aFillCmd = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ aFillDateCmd = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_3, &pItem ) )
+ aFillStep = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_4, &pItem ) )
+ aFillStart = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_5, &pItem ) )
+ aFillMax = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( aFillDir.Len() )
+ switch( aFillDir.GetChar(0) )
+ {
+ case 'B': case 'b': eFillDir=FILL_TO_BOTTOM; break;
+ case 'R': case 'r': eFillDir=FILL_TO_RIGHT; break;
+ case 'T': case 't': eFillDir=FILL_TO_TOP; break;
+ case 'L': case 'l': eFillDir=FILL_TO_LEFT; break;
+ }
+
+ if( aFillCmd.Len() )
+ switch( aFillCmd.GetChar(0) )
+ {
+ case 'S': case 's': eFillCmd=FILL_SIMPLE; break;
+ case 'L': case 'l': eFillCmd=FILL_LINEAR; break;
+ case 'G': case 'g': eFillCmd=FILL_GROWTH; break;
+ case 'D': case 'd': eFillCmd=FILL_DATE; break;
+ case 'A': case 'a': eFillCmd=FILL_AUTO; break;
+ }
+
+ if( aFillDateCmd.Len() )
+ switch( aFillDateCmd.GetChar(0) )
+ {
+ case 'D': case 'd': eFillDateCmd=FILL_DAY; break;
+ case 'W': case 'w': eFillDateCmd=FILL_WEEKDAY; break;
+ case 'M': case 'm': eFillDateCmd=FILL_MONTH; break;
+ case 'Y': case 'y': eFillDateCmd=FILL_YEAR; break;
+ }
+
+ nKey = 0;
+ if( pFormatter->IsNumberFormat( aFillStart, nKey, fTmpVal ))
+ fStartVal = fTmpVal;
+
+ nKey = 0;
+ if( pFormatter->IsNumberFormat( aFillStep, nKey, fTmpVal ))
+ fIncVal = fTmpVal;
+
+ nKey = 0;
+ if( pFormatter->IsNumberFormat( aFillMax, nKey, fTmpVal ))
+ fMaxVal = fTmpVal;
+
+ bDoIt = TRUE;
+
+ }
+ else // (pReqArgs == NULL) => Dialog hochziehen
+ {
+ //
+ sal_uInt32 nPrivFormat;
+ CellType eCellType;
+ pDoc->GetNumberFormat( nStartCol, nStartRow, nStartTab, nPrivFormat );
+ pDoc->GetCellType( nStartCol, nStartRow, nStartTab,eCellType );
+ const SvNumberformat* pPrivEntry = pFormatter->GetEntry( nPrivFormat );
+ if (!pPrivEntry)
+ {
+ DBG_ERROR("Zahlformat nicht gefunden !!!");
+ }
+ else
+ {
+ short nPrivType = pPrivEntry->GetType();
+ if ( ( nPrivType & NUMBERFORMAT_DATE)>0)
+ {
+ eFillCmd=FILL_DATE;
+ }
+ else if(eCellType==CELLTYPE_STRING)
+ {
+ eFillCmd=FILL_AUTO;
+ }
+ }
+
+ //
+ String aStartStr;
+
+ // Startwert nur vorbelegen, wenn nur 1 Zeile oder Spalte:
+ if ( nStartCol == nEndCol || nStartRow == nEndRow )
+ {
+ double fInputEndVal = 0.0;
+ String aEndStr;
+
+ pDoc->GetInputString( nStartCol, nStartRow, nStartTab, aStartStr);
+ pDoc->GetValue( nStartCol, nStartRow, nStartTab, fStartVal );
+
+
+ if(eFillDir==FILL_TO_BOTTOM && nStartRow < nEndRow )
+ {
+ pDoc->GetInputString( nStartCol, nStartRow+1, nStartTab, aEndStr);
+ if(aEndStr.Len()>0)
+ {
+ pDoc->GetValue( nStartCol, nStartRow+1, nStartTab, fInputEndVal);
+ fIncVal=fInputEndVal-fStartVal;
+ }
+ }
+ else
+ {
+ if(nStartCol < nEndCol)
+ {
+ pDoc->GetInputString( nStartCol+1, nStartRow, nStartTab, aEndStr);
+ if(aEndStr.Len()>0)
+ {
+ pDoc->GetValue( nStartCol+1, nStartRow, nStartTab, fInputEndVal);
+ fIncVal=fInputEndVal-fStartVal;
+ }
+ }
+ }
+ if(eFillCmd==FILL_DATE)
+ {
+ Date aNullDate = *pDoc->GetFormatTable()->GetNullDate();
+ Date aStartDate = aNullDate;
+ aStartDate+= (long)fStartVal;
+ Date aEndDate = aNullDate;
+ aEndDate+= (long)fInputEndVal;
+ double fTempDate=0;
+
+ if(aStartDate.GetYear()!=aEndDate.GetYear())
+ {
+ eFillDateCmd = FILL_YEAR;
+ fTempDate=aEndDate.GetYear()-aStartDate.GetYear();
+ }
+ if(aStartDate.GetMonth()!=aEndDate.GetMonth())
+ {
+ eFillDateCmd = FILL_MONTH;
+ fTempDate=fTempDate*12+aEndDate.GetMonth()-aStartDate.GetMonth();
+ }
+ if(aStartDate.GetDay()==aEndDate.GetDay())
+ {
+ fIncVal=fTempDate;
+ }
+ }
+ }
+//CHINA001 ScFillSeriesDlg* pDlg = new ScFillSeriesDlg(
+//CHINA001 pTabViewShell->GetDialogParent(), *pDoc,
+//CHINA001 eFillDir, eFillCmd, eFillDateCmd,
+//CHINA001 aStartStr, fIncVal, fMaxVal,
+//CHINA001 nPossDir);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScFillSeriesDlg* pDlg = pFact->CreateScFillSeriesDlg( pTabViewShell->GetDialogParent(),
+ *pDoc,
+ eFillDir, eFillCmd, eFillDateCmd,
+ aStartStr, fIncVal, fMaxVal,
+ nPossDir,
+ RID_SCDLG_FILLSERIES);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( nStartCol != nEndCol && nStartRow != nEndRow )
+ {
+ pDlg->SetEdStartValEnabled(FALSE);
+ }
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ eFillDir = pDlg->GetFillDir();
+ eFillCmd = pDlg->GetFillCmd();
+ eFillDateCmd = pDlg->GetFillDateCmd();
+
+ if(eFillCmd==FILL_AUTO)
+ {
+ String aStr=pDlg->GetStartStr();
+ if(aStr.Len()>0)
+ pTabViewShell->EnterData( nStartCol, nStartRow, nStartTab, aStr );
+ }
+ fStartVal = pDlg->GetStart();
+ fIncVal = pDlg->GetStep();
+ fMaxVal = pDlg->GetMax();
+ bDoIt = TRUE;
+ }
+ delete pDlg;
+ }
+
+ if( bDoIt )
+ {
+ //nScFillModeMouseModifier = 0; // kein Ctrl/Copy
+ pTabViewShell->FillSeries( eFillDir, eFillCmd, eFillDateCmd, fStartVal, fIncVal, fMaxVal );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aPara;
+ Color* pColor=0;
+
+ switch( eFillDir )
+ {
+ case FILL_TO_BOTTOM: aPara = 'B'; break;
+ case FILL_TO_RIGHT: aPara = 'R'; break;
+ case FILL_TO_TOP: aPara = 'T'; break;
+ case FILL_TO_LEFT: aPara = 'L'; break;
+ default: aPara.Erase(); break;
+ }
+ rReq.AppendItem( SfxStringItem( FID_FILL_SERIES, aPara ) );
+
+ switch( eFillCmd )
+ {
+ case FILL_SIMPLE: aPara = 'S'; break;
+ case FILL_LINEAR: aPara = 'L'; break;
+ case FILL_GROWTH: aPara = 'G'; break;
+ case FILL_DATE: aPara = 'D'; break;
+ case FILL_AUTO: aPara = 'A'; break;
+ default: aPara.Erase(); break;
+ }
+ rReq.AppendItem( SfxStringItem( FN_PARAM_1, aPara ) );
+
+ switch( eFillDateCmd )
+ {
+ case FILL_DAY: aPara = 'D'; break;
+ case FILL_WEEKDAY: aPara = 'W'; break;
+ case FILL_MONTH: aPara = 'M'; break;
+ case FILL_YEAR: aPara = 'Y'; break;
+ default: aPara.Erase(); break;
+ }
+ rReq.AppendItem( SfxStringItem( FN_PARAM_2, aPara ) );
+
+ ULONG nFormatKey = pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge );
+
+ pFormatter->GetOutputString( fIncVal, nFormatKey, aPara, &pColor );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_3, aPara ) );
+
+ pFormatter->GetOutputString( fStartVal, nFormatKey, aPara, &pColor );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_4, aPara ) );
+
+ pFormatter->GetOutputString( fMaxVal, nFormatKey, aPara, &pColor );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_5, aPara ) );
+
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case FID_FILL_AUTO:
+ {
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nStartTab, nEndTab;
+
+ GetViewData()->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
+ SCCOL nFillCol = GetViewData()->GetRefEndX();
+ SCROW nFillRow = GetViewData()->GetRefEndY();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+
+ if( IS_AVAILABLE( FID_FILL_AUTO, &pItem ) )
+ {
+ ScAddress aScAddress;
+ String aArg = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( aScAddress.Parse( aArg, pDoc, pDoc->GetAddressConvention() ) & SCA_VALID )
+ {
+ nFillRow = aScAddress.Row();
+ nFillCol = aScAddress.Col();
+ }
+ }
+
+ GetViewData()->GetSimpleArea( nStartCol,nStartRow,nStartTab,
+ nEndCol,nEndRow,nEndTab );
+ }
+ else // Aufruf per Maus
+ {
+ // #55284# nicht innerhalb einer zusammengefassten Zelle
+
+ if ( nStartCol == nEndCol && nStartRow == nEndRow )
+ {
+ SCCOL nMergeCol = nStartCol;
+ SCROW nMergeRow = nStartRow;
+ if ( GetViewData()->GetDocument()->ExtendMerge(
+ nStartCol, nStartRow, nMergeCol, nMergeRow,
+ GetViewData()->GetTabNo() ) )
+ {
+ if ( nFillCol >= nStartCol && nFillCol <= nMergeCol && nFillRow == nStartRow )
+ nFillCol = nStartCol;
+ if ( nFillRow >= nStartRow && nFillRow <= nMergeRow && nFillCol == nStartCol )
+ nFillRow = nStartRow;
+ }
+ }
+ }
+
+ if ( nFillCol != nEndCol || nFillRow != nEndRow )
+ {
+ if ( nFillCol==nEndCol || nFillRow==nEndRow )
+ {
+ FillDir eDir = FILL_TO_BOTTOM;
+ SCCOLROW nCount = 0;
+
+ if ( nFillCol==nEndCol )
+ {
+ if ( nFillRow > nEndRow )
+ {
+ eDir = FILL_TO_BOTTOM;
+ nCount = nFillRow - nEndRow;
+ }
+ else if ( nFillRow < nStartRow )
+ {
+ eDir = FILL_TO_TOP;
+ nCount = nStartRow - nFillRow;
+ }
+ }
+ else
+ {
+ if ( nFillCol > nEndCol )
+ {
+ eDir = FILL_TO_RIGHT;
+ nCount = nFillCol - nEndCol;
+ }
+ else if ( nFillCol < nStartCol )
+ {
+ eDir = FILL_TO_LEFT;
+ nCount = nStartCol - nFillCol;
+ }
+ }
+
+ if ( nCount != 0)
+ {
+ pTabViewShell->FillAuto( eDir, nStartCol, nStartRow, nEndCol, nEndRow, nCount );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aAdrStr;
+ ScAddress aAdr( nFillCol, nFillRow, 0 );
+ aAdr.Format( aAdrStr, SCR_ABS, pDoc, pDoc->GetAddressConvention() );
+
+ rReq.AppendItem( SfxStringItem( FID_FILL_AUTO, aAdrStr ) );
+ rReq.Done();
+ }
+ }
+
+ }
+ else
+ {
+ DBG_ERROR( "Richtung nicht eindeutig fuer AutoFill" );
+ }
+ }
+ }
+ break;
+
+ //
+ // Gliederung (Outlines)
+ // SID_AUTO_OUTLINE, SID_OUTLINE_DELETEALL in Execute (in docsh.idl)
+ //
+
+ case SID_OUTLINE_HIDE:
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ pTabViewShell->SetDataPilotDetails( FALSE );
+ else
+ pTabViewShell->HideMarkedOutlines();
+ rReq.Done();
+ break;
+
+ case SID_OUTLINE_SHOW:
+ {
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ Sequence<sheet::DataPilotFieldFilter> aFilters;
+ USHORT nOrientation;
+ if ( pTabViewShell->HasSelectionForDrillDown( nOrientation ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDPShowDetailDlg* pDlg = pFact->CreateScDPShowDetailDlg(
+ pTabViewShell->GetDialogParent(), RID_SCDLG_DPSHOWDETAIL, *pDPObj, nOrientation );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ String aNewDimName( pDlg->GetDimensionName() );
+ pTabViewShell->SetDataPilotDetails( TRUE, &aNewDimName );
+ }
+ }
+ else if ( !pDPObj->IsServiceData() &&
+ pDPObj->GetDataFieldPositionData(
+ ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ),
+ aFilters ) )
+ pTabViewShell->ShowDataPilotSourceData( *pDPObj, aFilters );
+ else
+ pTabViewShell->SetDataPilotDetails( TRUE );
+ }
+ else
+ pTabViewShell->ShowMarkedOutlines();
+ rReq.Done();
+ }
+ break;
+
+ case SID_OUTLINE_MAKE:
+ {
+ BOOL bColumns = FALSE;
+ BOOL bOk = TRUE;
+
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ ScDPNumGroupInfo aNumInfo;
+ aNumInfo.Enable = sal_True;
+ aNumInfo.AutoStart = sal_True;
+ aNumInfo.AutoEnd = sal_True;
+ sal_Int32 nParts = 0;
+ if ( pTabViewShell->HasSelectionForDateGroup( aNumInfo, nParts ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT( pFact, "ScAbstractFactory create fail!" );
+ Date aNullDate( *GetViewData()->GetDocument()->GetFormatTable()->GetNullDate() );
+ AbstractScDPDateGroupDlg* pDlg = pFact->CreateScDPDateGroupDlg(
+ pTabViewShell->GetDialogParent(), RID_SCDLG_DPDATEGROUP,
+ aNumInfo, nParts, aNullDate );
+ DBG_ASSERT( pDlg, "Dialog create fail!" );
+ if( pDlg->Execute() == RET_OK )
+ {
+ aNumInfo = pDlg->GetGroupInfo();
+ pTabViewShell->DateGroupDataPilot( aNumInfo, pDlg->GetDatePart() );
+ }
+ }
+ else if ( pTabViewShell->HasSelectionForNumGroup( aNumInfo ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT( pFact, "ScAbstractFactory create fail!" );
+ AbstractScDPNumGroupDlg* pDlg = pFact->CreateScDPNumGroupDlg(
+ pTabViewShell->GetDialogParent(), RID_SCDLG_DPNUMGROUP, aNumInfo );
+ DBG_ASSERT( pDlg, "Dialog create fail!" );
+ if( pDlg->Execute() == RET_OK )
+ pTabViewShell->NumGroupDataPilot( pDlg->GetGroupInfo() );
+ }
+ else
+ pTabViewShell->GroupDataPilot();
+
+ bOk = FALSE;
+ }
+ else if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ bOk = FALSE;
+
+ if( IS_AVAILABLE( SID_OUTLINE_MAKE, &pItem ) )
+ {
+ String aCol = ((const SfxStringItem*)pItem)->GetValue();
+ aCol.ToUpperAscii();
+
+ switch( aCol.GetChar(0) )
+ {
+ case 'R': bColumns=FALSE; bOk = TRUE;break;
+ case 'C': bColumns=TRUE; bOk = TRUE;break;
+ }
+ }
+ }
+ else // Dialog, wenn nicht ganze Zeilen/Spalten markiert
+ {
+ if ( GetViewData()->SimpleColMarked() && !GetViewData()->SimpleRowMarked() )
+ bColumns = TRUE;
+ else if ( !GetViewData()->SimpleColMarked() && GetViewData()->SimpleRowMarked() )
+ bColumns = FALSE;
+ else
+ {
+//CHINA001 ScGroupDlg* pDlg = new ScGroupDlg(pTabViewShell->GetDialogParent(),
+//CHINA001 RID_SCDLG_GRP_MAKE, FALSE );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScGroupDlg* pDlg = pFact->CreateAbstractScGroupDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_GRP_MAKE, RID_SCDLG_GRP_MAKE,FALSE);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ bColumns = pDlg->GetColsChecked();
+ else
+ bOk = FALSE;
+ delete pDlg;
+ }
+ }
+ if (bOk)
+ {
+ pTabViewShell->MakeOutline( bColumns );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aCol = bColumns ? 'C' : 'R';
+ rReq.AppendItem( SfxStringItem( SID_OUTLINE_MAKE, aCol ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case SID_OUTLINE_REMOVE:
+ {
+ BOOL bColumns = FALSE;
+ BOOL bOk = TRUE;
+
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ pTabViewShell->UngroupDataPilot();
+ bOk = FALSE;
+ }
+ else if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ bOk = FALSE;
+
+ if( IS_AVAILABLE( SID_OUTLINE_REMOVE, &pItem ) )
+ {
+ String aCol = ((const SfxStringItem*)pItem)->GetValue();
+ aCol.ToUpperAscii();
+
+ switch( aCol.GetChar(0) )
+ {
+ case 'R': bColumns=FALSE; bOk = TRUE;break;
+ case 'C': bColumns=TRUE; bOk = TRUE;break;
+ }
+ }
+ }
+ else // Dialog nur, wenn Aufheben fuer Zeilen und Spalten moeglich
+ {
+ BOOL bColPoss, bRowPoss;
+ pTabViewShell->TestRemoveOutline( bColPoss, bRowPoss );
+ if ( bColPoss && bRowPoss )
+ {
+ //CHINA001 ScGroupDlg* pDlg = new ScGroupDlg( pTabViewShell->GetDialogParent(),
+ //CHINA001 RID_SCDLG_GRP_KILL, TRUE );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScGroupDlg* pDlg = pFact->CreateAbstractScGroupDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_GRP_KILL, RID_SCDLG_GRP_KILL,TRUE);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ bColumns = pDlg->GetColsChecked();
+ else
+ bOk = FALSE;
+ delete pDlg;
+ }
+ else if ( bColPoss )
+ bColumns = TRUE;
+ else if ( bRowPoss )
+ bColumns = FALSE;
+ else
+ bOk = FALSE;
+ }
+ if (bOk)
+ {
+ pTabViewShell->RemoveOutline( bColumns );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aCol = bColumns ? 'C' : 'R';
+ rReq.AppendItem( SfxStringItem( SID_OUTLINE_REMOVE, aCol ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //
+ // Clipboard
+ //
+
+ case SID_COPY: // fuer Grafiken in DrawShell
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ pTabViewShell->CopyToClip( NULL, FALSE, FALSE, TRUE );
+ rReq.Done();
+ }
+ break;
+
+ case SID_CUT: // fuer Grafiken in DrawShell
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ pTabViewShell->CutToClip( NULL, TRUE );
+ rReq.Done();
+ }
+ break;
+
+ case SID_PASTE:
+ {
+ PasteFromClipboard ( GetViewData(), pTabViewShell, true );
+ rReq.Done();
+ }
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+
+ ULONG nFormat = 0;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+
+ if ( nFormat )
+ {
+ Window* pWin = GetViewData()->GetActiveWin();
+ BOOL bCells = ( ScTransferObj::GetOwnClipboard( pWin ) != NULL );
+ BOOL bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+ BOOL bOle = ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE );
+
+ if ( bCells && bOle )
+ pTabViewShell->PasteFromSystem();
+ else if ( bDraw && bOle )
+ pTabViewShell->PasteDraw();
+ else
+ pTabViewShell->PasteFromSystem(nFormat);
+ }
+ //?else
+ //? pTabViewShell->PasteFromSystem();
+
+ rReq.Done();
+ }
+ pTabViewShell->CellContentChanged();
+ break;
+
+ case FID_INS_CELL_CONTENTS:
+ {
+ USHORT nFlags = IDF_NONE;
+ USHORT nFunction = PASTE_NOFUNC;
+ BOOL bSkipEmpty = FALSE;
+ BOOL bTranspose = FALSE;
+ BOOL bAsLink = FALSE;
+ InsCellCmd eMoveMode = INS_NONE;
+
+ Window* pWin = GetViewData()->GetActiveWin();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ BOOL bOtherDoc = !pDoc->IsClipboardSource();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ if ( pOwnClip )
+ {
+ // #129384# keep a reference in case the clipboard is changed during dialog or PasteFromClip
+ uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ if ( pReqArgs!=NULL && pTabViewShell->SelectionEditable() )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags = 'A';
+
+ if( IS_AVAILABLE( FID_INS_CELL_CONTENTS, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+
+ aFlags.ToUpperAscii();
+ BOOL bCont = TRUE;
+
+ for( xub_StrLen i=0 ; bCont && i<aFlags.Len() ; i++ )
+ {
+ switch( aFlags.GetChar(i) )
+ {
+ case 'A': // Alle
+ nFlags |= IDF_ALL;
+ bCont = FALSE; // nicht mehr weitermachen!
+ break;
+ case 'S': nFlags |= IDF_STRING; break;
+ case 'V': nFlags |= IDF_VALUE; break;
+ case 'D': nFlags |= IDF_DATETIME; break;
+ case 'F': nFlags |= IDF_FORMULA; break;
+ case 'N': nFlags |= IDF_NOTE; break;
+ case 'T': nFlags |= IDF_ATTRIB; break;
+ }
+ }
+
+ SFX_REQUEST_ARG( rReq, pFuncItem, SfxUInt16Item, FN_PARAM_1, sal_False );
+ SFX_REQUEST_ARG( rReq, pSkipItem, SfxBoolItem, FN_PARAM_2, sal_False );
+ SFX_REQUEST_ARG( rReq, pTransposeItem, SfxBoolItem, FN_PARAM_3, sal_False );
+ SFX_REQUEST_ARG( rReq, pLinkItem, SfxBoolItem, FN_PARAM_4, sal_False );
+ SFX_REQUEST_ARG( rReq, pMoveItem, SfxInt16Item, FN_PARAM_5, sal_False );
+ if ( pFuncItem )
+ nFunction = pFuncItem->GetValue();
+ if ( pSkipItem )
+ bSkipEmpty = pSkipItem->GetValue();
+ if ( pTransposeItem )
+ bTranspose = pTransposeItem->GetValue();
+ if ( pLinkItem )
+ bAsLink = pLinkItem->GetValue();
+ if ( pMoveItem )
+ eMoveMode = (InsCellCmd) pMoveItem->GetValue();
+ }
+ else
+ {
+ ScEditableTester aTester( pTabViewShell );
+ if (aTester.IsEditable())
+ {
+ //CHINA001 ScInsertContentsDlg* pDlg = new ScInsertContentsDlg( pTabViewShell->GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertContentsDlg* pDlg = pFact->CreateScInsertContentsDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_INSCONT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetOtherDoc( bOtherDoc );
+ // #53661# bei ChangeTrack MoveMode disablen
+ pDlg->SetChangeTrack( pDoc->GetChangeTrack() != NULL );
+ // #72930# cut/move references may disable shift
+ // directions if source and destination ranges intersect
+ if ( !bOtherDoc )
+ {
+ if ( pOwnClip && pOwnClip->GetDocument()->IsCutMode() )
+ {
+ ScViewData* pData = GetViewData();
+ if ( pData->GetMarkData().GetTableSelect(
+ pData->GetTabNo() ) )
+ {
+ SCCOL nPosX = pData->GetCurX();
+ SCROW nPosY = pData->GetCurY();
+ SCCOL nClipStartX, nClipSizeX;
+ SCROW nClipStartY, nClipSizeY;
+ pOwnClip->GetDocument()->GetClipStart( nClipStartX, nClipStartY );
+ // for CutMode, filtered rows can always be included
+ pOwnClip->GetDocument()->GetClipArea( nClipSizeX, nClipSizeY, TRUE );
+ int nDisableShift = 0;
+ if ( nClipStartX <= nPosX + nClipSizeX &&
+ nPosX <= nClipStartX + nClipSizeX )
+ nDisableShift |= SC_CELL_SHIFT_DISABLE_DOWN;
+ if ( nClipStartY <= nPosY + nClipSizeY &&
+ nPosY <= nClipStartY + nClipSizeY )
+ nDisableShift |= SC_CELL_SHIFT_DISABLE_RIGHT;
+ if ( nDisableShift )
+ pDlg->SetCellShiftDisabled( nDisableShift );
+ }
+ }
+ }
+ if (pDlg->Execute() == RET_OK)
+ {
+ nFlags = pDlg->GetInsContentsCmdBits();
+ nFunction = pDlg->GetFormulaCmdBits();
+ bSkipEmpty = pDlg->IsSkipEmptyCells();
+ bTranspose = pDlg->IsTranspose();
+ bAsLink = pDlg->IsLink();
+ eMoveMode = pDlg->GetMoveMode();
+ }
+ delete pDlg;
+ }
+ else
+ pTabViewShell->ErrorMessage(aTester.GetMessageId());
+ }
+
+ if( nFlags != IDF_NONE )
+ {
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ if ( bAsLink && bOtherDoc )
+ pTabViewShell->PasteFromSystem(SOT_FORMATSTR_ID_LINK); // DDE einfuegen
+ else
+ pTabViewShell->PasteFromClip( nFlags, pOwnClip->GetDocument(),
+ nFunction, bSkipEmpty, bTranspose, bAsLink,
+ eMoveMode, IDF_NONE, TRUE ); // allow warning dialog
+ }
+
+ if( !pReqArgs )
+ {
+ String aFlags;
+
+ if( nFlags == IDF_ALL )
+ {
+ aFlags += 'A';
+ }
+ else
+ {
+ if( nFlags & IDF_STRING ) aFlags += 'S';
+ if( nFlags & IDF_VALUE ) aFlags += 'V';
+ if( nFlags & IDF_DATETIME ) aFlags += 'D';
+ if( nFlags & IDF_FORMULA ) aFlags += 'F';
+ if( nFlags & IDF_NOTE ) aFlags += 'N';
+ if( nFlags & IDF_ATTRIB ) aFlags += 'T';
+ }
+
+ rReq.AppendItem( SfxStringItem( FID_INS_CELL_CONTENTS, aFlags ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_2, bSkipEmpty ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_3, bTranspose ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_4, bAsLink ) );
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, nFunction ) );
+ rReq.AppendItem( SfxInt16Item( FN_PARAM_5, (sal_Int16) eMoveMode ) );
+ rReq.Done();
+ }
+ }
+ }
+ }
+ pTabViewShell->CellContentChanged(); // => PasteFromXXX ???
+ break;
+
+ case SID_PASTE_SPECIAL:
+ // Unterscheidung, ob eigene oder fremde Daten,
+ // dadurch FID_INS_CELL_CONTENTS ueberfluessig
+ {
+ Window* pWin = GetViewData()->GetActiveWin();
+
+ // Clipboard-ID als Parameter angegeben? Basic "PasteSpecial(Format)"
+ const SfxPoolItem* pItem=NULL;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ ULONG nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ BOOL bRet=TRUE;
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ BOOL bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+ if ( bDraw && nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ pTabViewShell->PasteDraw();
+ else
+ bRet = pTabViewShell->PasteFromSystem(nFormat, TRUE); // TRUE: keine Fehlermeldungen
+ }
+
+ if ( bRet )
+ {
+ rReq.SetReturnValue(SfxInt16Item(nSlot, bRet)); // 1 = Erfolg, 0 = Fehler
+ rReq.Done();
+ }
+ else
+ // if format is not available -> fallback to request without parameters
+ pItem = NULL;
+ }
+
+ if ( !pItem )
+ {
+ if ( ScTransferObj::GetOwnClipboard( pWin ) ) // own cell data
+ {
+ rReq.SetSlot( FID_INS_CELL_CONTENTS );
+ ExecuteSlot( rReq, GetInterface() );
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 1)); // 1 = Erfolg
+ }
+ else // Zeichenobjekte oder fremde Daten
+ {
+ BOOL bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ GetPossibleClipboardFormats( aFormats );
+
+ USHORT nFormatCount = aFormats.Count();
+ if ( nFormatCount )
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( pTabViewShell->GetDialogParent() );
+ if ( pDlg )
+ {
+ for (USHORT i=0; i<nFormatCount; i++)
+ {
+ ULONG nFormatId = aFormats.GetClipbrdFormatId( i );
+ String aName = aFormats.GetClipbrdFormatName( i );
+ // special case for paste dialog: '*' is replaced by object type
+ if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ aName.Assign((sal_Unicode)'*');
+ pDlg->Insert( nFormatId, aName );
+ }
+
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+ ULONG nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+ if (nFormat > 0)
+ {
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ if ( bDraw && nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ pTabViewShell->PasteDraw();
+ else
+ pTabViewShell->PasteFromSystem(nFormat);
+ }
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 1)); // 1 = Erfolg
+ rReq.AppendItem( SfxUInt32Item( nSlot, nFormat ) );
+ rReq.Done();
+ }
+ else
+ {
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 0)); // 0 = Fehler
+ rReq.Ignore();
+ }
+
+ delete pDlg;
+ }
+ }
+ else
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 0)); // 0 = Fehler
+ }
+ }
+ }
+ pTabViewShell->CellContentChanged(); // => PasteFromSystem() ???
+ break;
+
+ //
+ // sonstiges
+ //
+
+ case FID_INS_ROWBRK:
+ pTabViewShell->InsertPageBreak( FALSE );
+ rReq.Done();
+ break;
+
+ case FID_INS_COLBRK:
+ pTabViewShell->InsertPageBreak( TRUE );
+ rReq.Done();
+ break;
+
+ case FID_DEL_ROWBRK:
+ pTabViewShell->DeletePageBreak( FALSE );
+ rReq.Done();
+ break;
+
+ case FID_DEL_COLBRK:
+ pTabViewShell->DeletePageBreak( TRUE );
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_ADD_PRED:
+ pTabViewShell->DetectiveAddPred();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_DEL_PRED:
+ pTabViewShell->DetectiveDelPred();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_ADD_SUCC:
+ pTabViewShell->DetectiveAddSucc();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_DEL_SUCC:
+ pTabViewShell->DetectiveDelSucc();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_ADD_ERR:
+ pTabViewShell->DetectiveAddError();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_INVALID:
+ pTabViewShell->DetectiveMarkInvalid();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_REFRESH:
+ pTabViewShell->DetectiveRefresh();
+ rReq.Done();
+ break;
+
+ case SID_SPELL_DIALOG:
+// pTabViewShell->DoSpellingChecker();
+ {
+ SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame();
+ if( rReq.GetArgs() )
+ pViewFrame->SetChildWindow( SID_SPELL_DIALOG,
+ static_cast< const SfxBoolItem& >( rReq.GetArgs()->
+ Get( SID_SPELL_DIALOG ) ).GetValue() );
+ else
+ pViewFrame->ToggleChildWindow( SID_SPELL_DIALOG );
+
+ pViewFrame->GetBindings().Invalidate( SID_SPELL_DIALOG );
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_HANGUL_HANJA_CONVERSION:
+ pTabViewShell->DoHangulHanjaConversion();
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ {
+ //open ChineseTranslationDialog
+ Reference< XComponentContext > xContext(
+ ::cppu::defaultBootstrap_InitialComponentContext() ); //@todo get context from calc if that has one
+ if(xContext.is())
+ {
+ Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
+ if(xMCF.is())
+ {
+ Reference< ui::dialogs::XExecutableDialog > xDialog(
+ xMCF->createInstanceWithContext(
+ rtl::OUString::createFromAscii("com.sun.star.linguistic2.ChineseTranslationDialog")
+ , xContext), UNO_QUERY);
+ Reference< lang::XInitialization > xInit( xDialog, UNO_QUERY );
+ if( xInit.is() )
+ {
+ // initialize dialog
+ Reference< awt::XWindow > xDialogParentWindow(0);
+ Sequence<Any> aSeq(1);
+ Any* pArray = aSeq.getArray();
+ PropertyValue aParam;
+ aParam.Name = rtl::OUString::createFromAscii("ParentWindow");
+ aParam.Value <<= makeAny(xDialogParentWindow);
+ pArray[0] <<= makeAny(aParam);
+ xInit->initialize( aSeq );
+
+ //execute dialog
+ sal_Int16 nDialogRet = xDialog->execute();
+ if( RET_OK == nDialogRet )
+ {
+ //get some parameters from the dialog
+ sal_Bool bToSimplified = sal_True;
+ sal_Bool bUseVariants = sal_True;
+ sal_Bool bCommonTerms = sal_True;
+ Reference< beans::XPropertySet > xProp( xDialog, UNO_QUERY );
+ if( xProp.is() )
+ {
+ try
+ {
+ xProp->getPropertyValue( C2U("IsDirectionToSimplified") ) >>= bToSimplified;
+ xProp->getPropertyValue( C2U("IsUseCharacterVariants") ) >>= bUseVariants;
+ xProp->getPropertyValue( C2U("IsTranslateCommonTerms") ) >>= bCommonTerms;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ //execute translation
+ LanguageType eSourceLang = bToSimplified ? LANGUAGE_CHINESE_TRADITIONAL : LANGUAGE_CHINESE_SIMPLIFIED;
+ LanguageType eTargetLang = bToSimplified ? LANGUAGE_CHINESE_SIMPLIFIED : LANGUAGE_CHINESE_TRADITIONAL;
+ sal_Int32 nOptions = bUseVariants ? i18n::TextConversionOption::USE_CHARACTER_VARIANTS : 0;
+ if( !bCommonTerms )
+ nOptions |= i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+
+ Font aTargetFont = GetViewData()->GetActiveWin()->GetDefaultFont(
+ DEFAULTFONT_CJK_SPREADSHEET,
+ eTargetLang, DEFAULTFONT_FLAGS_ONLYONE );
+ ScConversionParam aConvParam( SC_CONVERSION_CHINESE_TRANSL,
+ eSourceLang, eTargetLang, aTargetFont, nOptions, false );
+ pTabViewShell->DoSheetConversion( aConvParam );
+ }
+ }
+ Reference< lang::XComponent > xComponent( xDialog, UNO_QUERY );
+ if( xComponent.is() )
+ xComponent->dispose();
+ }
+ }
+ }
+ break;
+
+ case SID_THESAURUS:
+ pTabViewShell->DoThesaurus();
+ break;
+
+ case SID_TOGGLE_REL:
+ pTabViewShell->DoRefConversion();
+ break;
+
+ case SID_DEC_INDENT:
+ pTabViewShell->ChangeIndent( FALSE );
+ break;
+ case SID_INC_INDENT:
+ pTabViewShell->ChangeIndent( TRUE );
+ break;
+
+ case FID_USE_NAME:
+ {
+ USHORT nFlags = pTabViewShell->GetCreateNameFlags();
+
+ //CHINA001 ScNameCreateDlg* pDlg = new ScNameCreateDlg( pTabViewShell->GetDialogParent(), nFlags );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNameCreateDlg* pDlg = pFact->CreateScNameCreateDlg(pTabViewShell->GetDialogParent(), nFlags, RID_SCDLG_NAMES_CREATE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if( pDlg->Execute() )
+ {
+ nFlags = pDlg->GetFlags();
+ pTabViewShell->CreateNames(nFlags);
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_CONSOLIDATE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState( SCITEM_CONSOLIDATEDATA, TRUE, &pItem ) )
+ {
+ const ScConsolidateParam& rParam =
+ ((const ScConsolidateItem*)pItem)->GetData();
+
+ pTabViewShell->Consolidate( rParam );
+ GetViewData()->GetDocument()->SetConsolidateDlgData( &rParam );
+
+ rReq.Done();
+ }
+ else if (rReq.IsAPI())
+ SbxBase::SetError(SbxERR_BAD_PARAMETER);
+ }
+ break;
+
+ case SID_INS_FUNCTION:
+ {
+ const SfxBoolItem* pOkItem = (const SfxBoolItem*)&pReqArgs->Get( SID_DLG_RETOK );
+
+// pScMod->SetFunctionDlg( NULL );
+
+ if ( pOkItem->GetValue() ) // OK
+ {
+ String aFormula;
+ const SfxStringItem* pSItem = (const SfxStringItem*)&pReqArgs->Get( SCITEM_STRING );
+ const SfxBoolItem* pMatrixItem = (const SfxBoolItem*) &pReqArgs->Get( SID_DLG_MATRIX );
+
+ aFormula += pSItem->GetValue();
+ pScMod->ActivateInputWindow( &aFormula, pMatrixItem->GetValue() );
+ }
+ else // CANCEL
+ {
+ pScMod->ActivateInputWindow( NULL );
+ }
+ rReq.Ignore(); // only SID_ENTER_STRING is recorded
+ }
+ break;
+
+ case FID_DEFINE_NAME:
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aName, aSymbol, aAttrib;
+
+ if( IS_AVAILABLE( FID_DEFINE_NAME, &pItem ) )
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ aSymbol = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ aAttrib = ((const SfxStringItem*)pItem)->GetValue();
+
+ if ( aName.Len() && aSymbol.Len() )
+ {
+ if (pTabViewShell->InsertName( aName, aSymbol, aAttrib ))
+ rReq.Done();
+ else
+ SbxBase::SetError( SbxERR_BAD_PARAMETER ); // Basic-Fehler
+ }
+ }
+ else
+ {
+ USHORT nId = ScNameDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case SID_DEFINE_COLROWNAMERANGES:
+ {
+
+ USHORT nId = ScColRowNameRangesDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+
+ }
+ break;
+
+ case SID_UPDATECHART:
+ {
+ BOOL bAll = FALSE;
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+
+ if( IS_AVAILABLE( SID_UPDATECHART, &pItem ) )
+ bAll = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+
+ pTabViewShell->UpdateCharts( bAll );
+
+ if( ! rReq.IsAPI() )
+ {
+ rReq.AppendItem( SfxBoolItem( SID_UPDATECHART, bAll ) );
+ rReq.Done();
+ }
+ }
+ break;
+
+
+ case SID_TABOP:
+ if (pReqArgs)
+ {
+ const ScTabOpItem& rItem =
+ (const ScTabOpItem&)
+ pReqArgs->Get( SID_TABOP );
+
+ pTabViewShell->TabOp( rItem.GetData() );
+
+ rReq.Done( *pReqArgs );
+ }
+ break;
+
+ case SID_SOLVE:
+ if (pReqArgs)
+ {
+ const ScSolveItem& rItem =
+ (const ScSolveItem&)
+ pReqArgs->Get( SCITEM_SOLVEDATA );
+
+ pTabViewShell->Solve( rItem.GetData() );
+
+ rReq.Done( *pReqArgs );
+ }
+ break;
+
+ case FID_INSERT_NAME:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ //CHINA001 ScNamePasteDlg* pDlg = new ScNamePasteDlg( pTabViewShell->GetDialogParent(), pDoc->GetRangeName() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNamePasteDlg* pDlg = pFact->CreateScNamePasteDlg( pTabViewShell->GetDialogParent(), pDoc->GetRangeName(), RID_SCDLG_NAMES_PASTE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ switch( pDlg->Execute() )
+ {
+ case BTN_PASTE_LIST:
+ pTabViewShell->InsertNameList();
+ break;
+ case BTN_PASTE_NAME:
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pTabViewShell );
+ if (pHdl)
+ {
+ // das "=" per Key-Event, schaltet in den Eingabe-Modus
+ pScMod->InputKeyEvent( KeyEvent('=',KeyCode()) );
+
+ String aName = pDlg->GetSelectedName();
+ pHdl->InsertFunction( aName, FALSE ); // ohne "()"
+ }
+ }
+ break;
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_RANGE_NOTETEXT:
+ if (pReqArgs)
+ {
+ const SfxStringItem& rTextItem = (const SfxStringItem&)pReqArgs->Get( SID_RANGE_NOTETEXT );
+
+ // #43343# immer Cursorposition
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ pTabViewShell->SetNoteText( aPos, rTextItem.GetValue() );
+ rReq.Done();
+ }
+ break;
+
+ case SID_INSERT_POSTIT:
+ if ( pReqArgs )
+ {
+ const SvxPostItAuthorItem& rAuthorItem = (const SvxPostItAuthorItem&)pReqArgs->Get( SID_ATTR_POSTIT_AUTHOR );
+ const SvxPostItDateItem& rDateItem = (const SvxPostItDateItem&) pReqArgs->Get( SID_ATTR_POSTIT_DATE );
+ const SvxPostItTextItem& rTextItem = (const SvxPostItTextItem&) pReqArgs->Get( SID_ATTR_POSTIT_TEXT );
+
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ pTabViewShell->ReplaceNote( aPos, rTextItem.GetValue(), &rAuthorItem.GetValue(), &rDateItem.GetValue() );
+ rReq.Done();
+ }
+ else
+ {
+ pTabViewShell->EditNote(); // Zeichenobjekt zum Editieren
+ }
+ break;
+
+ case FID_NOTE_VISIBLE:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if( ScPostIt* pNote = pDoc->GetNote( aPos ) )
+ {
+ bool bShow;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && (pReqArgs->GetItemState( FID_NOTE_VISIBLE, TRUE, &pItem ) == SFX_ITEM_SET) )
+ bShow = ((const SfxBoolItem*) pItem)->GetValue();
+ else
+ bShow = !pNote->IsCaptionShown();
+
+ pTabViewShell->ShowNote( bShow );
+
+ if (!pReqArgs)
+ rReq.AppendItem( SfxBoolItem( FID_NOTE_VISIBLE, bShow ) );
+
+ rReq.Done();
+ rBindings.Invalidate( FID_NOTE_VISIBLE );
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_DELETE_NOTE:
+ pTabViewShell->DeleteContents( IDF_NOTE ); // delete all notes in selection
+ rReq.Done();
+ break;
+
+ case SID_CHARMAP:
+ if( pReqArgs != NULL )
+ {
+ String aChars, aFontName;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = 0;
+ if ( pArgs )
+ pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), FALSE, &pItem);
+ if ( pItem )
+ {
+ const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, pItem );
+ if ( pStringItem )
+ aChars = pStringItem->GetValue();
+ const SfxPoolItem* pFtItem = NULL;
+ pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), FALSE, &pFtItem);
+ const SfxStringItem* pFontItem = PTR_CAST( SfxStringItem, pFtItem );
+ if ( pFontItem )
+ aFontName = pFontItem->GetValue();
+ }
+
+ if ( aChars.Len() )
+ {
+ Font aFont;
+ pTabViewShell->GetSelectionPattern()->GetFont( aFont, SC_AUTOCOL_BLACK, NULL, NULL, NULL,
+ pTabViewShell->GetSelectionScriptType() );
+ if ( aFontName.Len() )
+ aFont = Font( aFontName, Size(1,1) );
+ pTabViewShell->InsertSpecialChar( aChars, aFont );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ }
+ else
+ {
+ //CHINA001 SvxCharacterMap* pDlg = new SvxCharacterMap( pTabViewShell->GetDialogParent(), FALSE );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+
+ // font color doesn't matter here
+ Font aCurFont;
+ pTabViewShell->GetSelectionPattern()->GetFont( aCurFont, SC_AUTOCOL_BLACK, NULL, NULL, NULL,
+ pTabViewShell->GetSelectionScriptType() );
+
+ SfxAllItemSet aSet( GetPool() );
+ aSet.Put( SfxBoolItem( FN_PARAM_1, FALSE ) );
+ aSet.Put( SvxFontItem( aCurFont.GetFamily(), aCurFont.GetName(), aCurFont.GetStyleName(), aCurFont.GetPitch(), aCurFont.GetCharSet(), GetPool().GetWhich(SID_ATTR_CHAR_FONT) ) );
+
+ SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( pTabViewShell->GetDialogParent(), aSet,
+ pTabViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, FALSE );
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT, FALSE );
+
+ if ( pItem && pFontItem )
+ {
+ Font aNewFont( pFontItem->GetFamilyName(), pFontItem->GetStyleName(), Size(1,1) );
+ aNewFont.SetCharSet( pFontItem->GetCharSet() );
+ aNewFont.SetPitch( pFontItem->GetPitch() );
+ pTabViewShell->InsertSpecialChar( pItem->GetValue(), aNewFont );
+ rReq.AppendItem( *pFontItem );
+ rReq.AppendItem( *pItem );
+ rReq.Done();
+ }
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_SELECT_SCENARIO:
+ {
+ // Testing
+
+ if ( pReqArgs )
+ {
+ const SfxStringItem* pItem =
+ (const SfxStringItem*)&pReqArgs->Get( SID_SELECT_SCENARIO );
+
+ if( pItem )
+ {
+ pTabViewShell->UseScenario( pItem->GetValue() );
+ //! wofuer soll der Return-Wert gut sein?!?!
+ rReq.SetReturnValue( SfxStringItem( SID_SELECT_SCENARIO, pItem->GetValue() ) );
+ rReq.Done();
+ }
+ else
+ {
+ DBG_ERROR("NULL");
+ }
+ }
+ }
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( SID_HYPERLINK_SETLINK, &pItem ) )
+ {
+ const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem;
+ const String& rName = pHyper->GetName();
+ const String& rURL = pHyper->GetURL();
+ const String& rTarget = pHyper->GetTargetFrame();
+ USHORT nType = (USHORT) pHyper->GetInsertMode();
+
+ pTabViewShell->InsertURL( rName, rURL, rTarget, nType );
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case FID_CONDITIONAL_FORMAT:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_CONDITIONAL_FORMAT, &pItem ) )
+ {
+ // Wenn RefInput auf andere Tabelle als Datentabelle umgeschaltet
+ // hat wieder zurueckschalten:
+ if ( GetViewData()->GetTabNo() != GetViewData()->GetRefTabNo() )
+ {
+ pTabViewShell->SetTabNo( GetViewData()->GetRefTabNo() );
+ pTabViewShell->PaintExtras();
+ }
+
+ const ScCondFrmtItem* pCndFmtItem = (const ScCondFrmtItem*) pItem;
+ pTabViewShell->SetConditionalFormat( pCndFmtItem->GetData() );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_EXTERNAL_SOURCE:
+ {
+ String aFile;
+ String aFilter;
+ String aOptions;
+ String aSource;
+ ULONG nRefresh=0;
+
+ SFX_REQUEST_ARG( rReq, pFile, SfxStringItem, SID_FILE_NAME, sal_False );
+ SFX_REQUEST_ARG( rReq, pSource, SfxStringItem, FN_PARAM_1, sal_False );
+ if ( pFile && pSource )
+ {
+ aFile = pFile->GetValue();
+ aSource = pSource->GetValue();
+ SFX_REQUEST_ARG( rReq, pFilter, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if ( pFilter )
+ aFilter = pFilter->GetValue();
+ SFX_REQUEST_ARG( rReq, pOptions, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False );
+ if ( pOptions )
+ aOptions = pOptions->GetValue();
+ SFX_REQUEST_ARG( rReq, pRefresh, SfxUInt32Item, FN_PARAM_2, sal_False );
+ if ( pRefresh )
+ nRefresh = pRefresh->GetValue();
+ }
+ else
+ {
+ //CHINA001 ScLinkedAreaDlg* pDlg = new ScLinkedAreaDlg( pTabViewShell->GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ delete pImpl->m_pLinkedDlg;
+ pImpl->m_pLinkedDlg =
+ pFact->CreateScLinkedAreaDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_LINKAREA);
+ DBG_ASSERT(pImpl->m_pLinkedDlg, "Dialog create fail!");//CHINA001
+ delete pImpl->m_pRequest;
+ pImpl->m_pRequest = new SfxRequest( rReq );
+ pImpl->m_pLinkedDlg->StartExecuteModal( LINK( this, ScCellShell, DialogClosed ) );
+ return;
+ }
+
+ ExecuteExternalSource( aFile, aFilter, aOptions, aSource, nRefresh, rReq );
+ }
+ break;
+
+ //
+ //
+ //
+
+ default:
+ DBG_ERROR("falscher Slot bei ExecuteEdit");
+ break;
+ }
+}
+
+void ScCellShell::ExecuteTrans( SfxRequest& rReq )
+{
+ sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
+ if ( nType )
+ {
+ GetViewData()->GetView()->TransliterateText( nType );
+ rReq.Done();
+ }
+}
+
+void ScCellShell::ExecuteExternalSource(
+ const String& _rFile, const String& _rFilter, const String& _rOptions,
+ const String& _rSource, ULONG _nRefresh, SfxRequest& _rRequest )
+{
+ if ( _rFile.Len() && _rSource.Len() ) // filter may be empty
+ {
+ ScRange aLinkRange;
+ BOOL bMove = FALSE;
+
+ ScViewData* pData = GetViewData();
+ ScMarkData& rMark = pData->GetMarkData();
+ rMark.MarkToSimple();
+ if ( rMark.IsMarked() )
+ {
+ rMark.GetMarkArea( aLinkRange );
+ bMove = TRUE; // insert/delete cells to fit range
+ }
+ else
+ aLinkRange = ScRange( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+
+ ScDocFunc aFunc(*pData->GetDocShell());
+ aFunc.InsertAreaLink( _rFile, _rFilter, _rOptions, _rSource,
+ aLinkRange, _nRefresh, bMove, FALSE );
+ _rRequest.Done();
+ }
+ else
+ _rRequest.Ignore();
+}
+
+IMPL_LINK( ScCellShell, DialogClosed, AbstractScLinkedAreaDlg*, EMPTYARG )
+{
+ DBG_ASSERT( pImpl->m_pLinkedDlg, "ScCellShell::DialogClosed(): invalid request" );
+ DBG_ASSERT( pImpl->m_pRequest, "ScCellShell::DialogClosed(): invalid request" );
+ String sFile, sFilter, sOptions, sSource;
+ ULONG nRefresh = 0;
+
+ if ( pImpl->m_pLinkedDlg->GetResult() == RET_OK )
+ {
+ sFile = pImpl->m_pLinkedDlg->GetURL();
+ sFilter = pImpl->m_pLinkedDlg->GetFilter();
+ sOptions = pImpl->m_pLinkedDlg->GetOptions();
+ sSource = pImpl->m_pLinkedDlg->GetSource();
+ nRefresh = pImpl->m_pLinkedDlg->GetRefresh();
+ if ( sFile.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( SID_FILE_NAME, sFile ) );
+ if ( sFilter.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( SID_FILTER_NAME, sFilter ) );
+ if ( sOptions.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, sOptions ) );
+ if ( sSource.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( FN_PARAM_1, sSource ) );
+ if ( nRefresh )
+ pImpl->m_pRequest->AppendItem( SfxUInt32Item( FN_PARAM_2, nRefresh ) );
+ }
+
+ ExecuteExternalSource( sFile, sFilter, sOptions, sSource, nRefresh, *(pImpl->m_pRequest) );
+ return 0;
+}
+
+void ScCellShell::PasteFromClipboard( ScViewData* pViewData, ScTabViewShell* pTabViewShell, bool bShowDialog )
+{
+ Window* pWin = pViewData->GetActiveWin();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ ScDPObject* pDPObj = pThisDoc->GetDPAtCursor( pViewData->GetCurX(),
+ pViewData->GetCurY(), pViewData->GetTabNo() );
+ if ( pOwnClip && pDPObj )
+ {
+ // paste from Calc into DataPilot table: sort (similar to drag & drop)
+
+ ScDocument* pClipDoc = pOwnClip->GetDocument();
+ SCTAB nSourceTab = pOwnClip->GetVisibleTab();
+
+ SCCOL nClipStartX;
+ SCROW nClipStartY;
+ SCCOL nClipEndX;
+ SCROW nClipEndY;
+ pClipDoc->GetClipStart( nClipStartX, nClipStartY );
+ pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE );
+ nClipEndX = nClipEndX + nClipStartX;
+ nClipEndY = nClipEndY + nClipStartY; // GetClipArea returns the difference
+
+ ScRange aSource( nClipStartX, nClipStartY, nSourceTab, nClipEndX, nClipEndY, nSourceTab );
+ BOOL bDone = pTabViewShell->DataPilotMove( aSource, pViewData->GetCurPos() );
+ if ( !bDone )
+ pTabViewShell->ErrorMessage( STR_ERR_DATAPILOT_INPUT );
+ }
+ else
+ {
+ // normal paste
+ WaitObject aWait( pViewData->GetDialogParent() );
+ if (!pOwnClip)
+ pTabViewShell->PasteFromSystem();
+ else
+ {
+ ScDocument* pClipDoc = pOwnClip->GetDocument();
+ sal_uInt16 nFlags = IDF_ALL;
+ if (pClipDoc->GetClipParam().isMultiRange())
+ // For multi-range paste, we paste values by default.
+ nFlags &= ~IDF_FORMULA;
+
+ pTabViewShell->PasteFromClip( nFlags, pClipDoc,
+ PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
+ bShowDialog ); // allow warning dialog
+ }
+ }
+ pTabViewShell->CellContentChanged(); // => PasteFromSystem() ???
+}
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
new file mode 100644
index 000000000000..086160263739
--- /dev/null
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -0,0 +1,1432 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/request.hxx>
+#include <svl/aeitem.hxx>
+#include <basic/sbxcore.hxx>
+#include <svl/whiter.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/stritem.hxx>
+#include <svl/visitem.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include "cellsh.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "uiitems.hxx"
+#include "dbfunc.hxx"
+#include "dbdocfun.hxx"
+//CHINA001 #include "lbseldlg.hxx"
+//CHINA001 #include "sortdlg.hxx"
+#include "filtdlg.hxx"
+#include "dbnamdlg.hxx"
+//CHINA001 #include "subtdlg.hxx"
+#include "reffact.hxx"
+#include "pvlaydlg.hxx"
+#include "validat.hxx"
+#include "scresid.hxx"
+//CHINA001 #include "validate.hxx"
+#include "pivot.hxx"
+#include "dpobject.hxx"
+//CHINA001 #include "dapitype.hxx"
+//CHINA001 #include "dapidata.hxx"
+#include "dpsdbtab.hxx" // ScImportSourceDesc
+#include "dpshttab.hxx" // ScSheetSourceDesc
+
+#include "validate.hrc" //CHINA001 add for ScValidationDlg
+#include "scui_def.hxx" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "impex.hxx"
+#include "asciiopt.hxx"
+using namespace com::sun::star;
+
+//#include "strindlg.hxx" //! Test !!!!!
+
+//static ScArea aPivotSource; //! wohin? (ueber den Dialog retten)
+
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+//------------------------------------------------------------------
+
+bool lcl_GetTextToColumnsRange( const ScViewData* pData, ScRange& rRange )
+{
+ DBG_ASSERT( pData, "lcl_GetTextToColumnsRange: pData is null!" );
+
+ bool bRet = false;
+ const ScMarkData& rMark = pData->GetMarkData();
+
+ if ( rMark.IsMarked() )
+ {
+ if ( !rMark.IsMultiMarked() )
+ {
+ rMark.GetMarkArea( rRange );
+ if ( rRange.aStart.Col() == rRange.aEnd.Col() )
+ {
+ bRet = true;
+ }
+ }
+ }
+ else
+ {
+ const SCCOL nCol = pData->GetCurX();
+ const SCROW nRow = pData->GetCurY();
+ const SCTAB nTab = pData->GetTabNo();
+ rRange = ScRange( nCol, nRow, nTab, nCol, nRow, nTab );
+ bRet = true;
+ }
+
+ const ScDocument* pDoc = pData->GetDocument();
+ DBG_ASSERT( pDoc, "lcl_GetTextToColumnsRange: pDoc is null!" );
+
+ if ( bRet && pDoc->IsBlockEmpty( rRange.aStart.Tab(), rRange.aStart.Col(),
+ rRange.aStart.Row(), rRange.aEnd.Col(),
+ rRange.aEnd.Row() ) )
+ {
+ bRet = false;
+ }
+
+ 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, 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;
+}
+
+//<!-- Added by PengYunQuan for Validity Cell Range Picker
+//after end execute from !IsModalInputMode, it is safer to delay deleting
+namespace
+{
+ long DelayDeleteAbstractDialog( void *pAbstractDialog, void * /*pArg*/ )
+ {
+ delete reinterpret_cast<VclAbstractDialog*>( pAbstractDialog );
+ return 0;
+ }
+}
+//--> Added by PengYunQuan for Validity Cell Range Picker
+
+void ScCellShell::ExecuteDB( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ USHORT nSlotId = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ ScModule* pScMod = SC_MOD();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ }
+
+ switch ( nSlotId )
+ {
+ case SID_VIEW_DATA_SOURCE_BROWSER:
+ {
+ // check if database beamer is open
+
+ SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame();
+ BOOL bWasOpen = FALSE;
+ {
+ uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame(
+ rtl::OUString::createFromAscii("_beamer"),
+ frame::FrameSearchFlag::CHILDREN);
+ if ( xBeamerFrame.is() )
+ bWasOpen = TRUE;
+ }
+
+ if ( bWasOpen )
+ {
+ // close database beamer: just forward to SfxViewFrame
+
+ pViewFrame->ExecuteSlot( rReq );
+ }
+ else
+ {
+ // show database beamer: SfxViewFrame call must be synchronous
+
+ pViewFrame->ExecuteSlot( rReq, (BOOL) FALSE ); // FALSE = synchronous
+
+ // select current database in database beamer
+
+ ScImportParam aImportParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData(TRUE,SC_DB_OLD); // don't create if none found
+ if (pDBData)
+ pDBData->GetImportParam( aImportParam );
+
+ ScDBDocFunc::ShowInBeamer( aImportParam, pTabViewShell->GetViewFrame() );
+ }
+ rReq.Done(); // needed because it's a toggle slot
+ }
+ break;
+
+ case SID_REIMPORT_DATA:
+ {
+ BOOL bOk = FALSE;
+ ScDBData* pDBData = pTabViewShell->GetDBData(TRUE,SC_DB_OLD);
+ if (pDBData)
+ {
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ if (aImportParam.bImport && !pDBData->HasImportSelection())
+ {
+ pTabViewShell->ImportData( aImportParam );
+ pDBData->SetImportParam( aImportParam ); //! Undo ??
+ bOk = TRUE;
+ }
+ }
+
+ if (!bOk && ! rReq.IsAPI() )
+ pTabViewShell->ErrorMessage(STR_REIMPORT_EMPTY);
+
+ if( bOk )
+ rReq.Done();
+ }
+ break;
+
+ case SID_REFRESH_DBAREA:
+ {
+ ScDBData* pDBData = pTabViewShell->GetDBData(TRUE,SC_DB_OLD);
+ if (pDBData)
+ {
+ // Import wiederholen wie SID_REIMPORT_DATA
+
+ BOOL bContinue = TRUE;
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ if (aImportParam.bImport && !pDBData->HasImportSelection())
+ {
+ bContinue = pTabViewShell->ImportData( aImportParam );
+ pDBData->SetImportParam( aImportParam ); //! Undo ??
+
+ // markieren (Groesse kann sich geaendert haben)
+ ScRange aNewRange;
+ pDBData->GetArea(aNewRange);
+ pTabViewShell->MarkRange(aNewRange);
+ }
+
+ if ( bContinue ) // #41905# Fehler beim Import -> Abbruch
+ {
+ // interne Operationen, wenn welche gespeichert
+
+ if ( pDBData->HasQueryParam() || pDBData->HasSortParam() ||
+ pDBData->HasSubTotalParam() )
+ pTabViewShell->RepeatDB();
+
+ // Pivottabellen die den Bereich als Quelldaten haben
+
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ GetViewData()->GetDocShell()->RefreshPivotTables(aRange);
+ }
+ }
+ rReq.Done();
+ }
+ break;
+
+ case SID_SBA_BRW_INSERT:
+ {
+ DBG_ERROR( "Deprecated Slot" );
+ }
+ break;
+
+ case SID_SUBTOTALS:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ pTabViewShell->DoSubTotals( ((const ScSubTotalItem&) pArgs->Get( SCITEM_SUBTDATA )).
+ GetSubTotalData() );
+ rReq.Done();
+ }
+ else
+ {
+ //CHINA001 ScSubTotalDlg* pDlg = NULL;
+ SfxAbstractTabDialog * pDlg = NULL;
+ ScSubTotalParam aSubTotalParam;
+ SfxItemSet aArgSet( GetPool(), SCITEM_SUBTDATA, SCITEM_SUBTDATA );
+
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ aSubTotalParam.bRemoveOnly = FALSE;
+
+ aArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA, GetViewData(), &aSubTotalParam ) );
+ //CHINA001 pDlg = new ScSubTotalDlg( pTabViewShell->GetDialogParent(), &aArgSet );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScSubTotalDlg( pTabViewShell->GetDialogParent(), &aArgSet, RID_SCDLG_SUBTOTALS );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetCurPageId(1);
+
+ short bResult = pDlg->Execute();
+
+ if ( (bResult == RET_OK) || (bResult == SCRET_REMOVE) )
+ {
+ const SfxItemSet* pOutSet = NULL;
+
+ if ( bResult == RET_OK )
+ {
+ pOutSet = pDlg->GetOutputItemSet();
+ aSubTotalParam =
+ ((const ScSubTotalItem&)
+ pOutSet->Get( SCITEM_SUBTDATA )).
+ GetSubTotalData();
+ }
+ else // if (bResult == SCRET_REMOVE)
+ {
+ pOutSet = &aArgSet;
+ aSubTotalParam.bRemoveOnly = TRUE;
+ aSubTotalParam.bReplace = TRUE;
+ aArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA,
+ GetViewData(),
+ &aSubTotalParam ) );
+ }
+
+ pTabViewShell->DoSubTotals( aSubTotalParam );
+ rReq.Done( *pOutSet );
+ }
+ else
+ GetViewData()->GetDocShell()->CancelAutoDBRange();
+
+ delete pDlg;
+ }
+ }
+ break;
+
+ case SID_SORT_DESCENDING:
+ case SID_SORT_ASCENDING:
+ {
+ //#i60401 ux-ctest: Calc does not support all users' strategies regarding sorting data
+ //the patch comes from maoyg
+ ScSortParam aSortParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
+
+ pDBData->GetSortParam( aSortParam );
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCCOL nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ pDBData->GetSortParam( aSortParam );
+ BOOL bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, nTab );
+
+ if( nCol < aSortParam.nCol1 )
+ nCol = aSortParam.nCol1;
+ else if( nCol > aSortParam.nCol2 )
+ nCol = aSortParam.nCol2;
+
+ 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);
+
+ for ( USHORT i=1; i<MAXSORT; i++ )
+ aSortParam.bDoSort[i] = FALSE;
+
+ aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
+
+ pTabViewShell->UISort( aSortParam ); // Teilergebnisse bei Bedarf neu
+
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_SORT:
+ {
+ 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();
+ ScViewData* pData = GetViewData();
+
+ pDBData->GetSortParam( aSortParam );
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ 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();
+ }
+ }
+ else
+ {
+ ScSortParam aSortParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
+
+ pDBData->GetSortParam( aSortParam );
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ SfxAbstractTabDialog* pDlg = NULL;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+
+ pDBData->GetSortParam( aSortParam );
+ BOOL bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, pData->GetTabNo() );
+ if( bHasHeader )
+ aSortParam.bHasHeader = bHasHeader;
+
+ aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
+
+ 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 ( pDlg->Execute() == RET_OK )
+ {
+ 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( 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();
+
+ delete pDlg;
+ }
+ }
+ }
+ break;
+
+ case SID_FILTER:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ DBG_ERROR("SID_FILTER with arguments?");
+ pTabViewShell->Query( ((const ScQueryItem&)
+ pArgs->Get( SCITEM_QUERYDATA )).GetQueryData(), NULL, TRUE );
+ rReq.Done();
+ }
+ else
+ {
+ USHORT nId = ScFilterDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ }
+ break;
+
+ case SID_SPECIAL_FILTER:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ DBG_ERROR("SID_SPECIAL_FILTER with arguments?");
+ pTabViewShell->Query( ((const ScQueryItem&)
+ pArgs->Get( SCITEM_QUERYDATA )).GetQueryData(), NULL, TRUE );
+ rReq.Done();
+ }
+ else
+ {
+ USHORT nId = ScSpecialFilterDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ }
+ break;
+
+ case FID_FILTER_OK:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState( SCITEM_QUERYDATA, TRUE, &pItem ) )
+ {
+ const ScQueryItem& rQueryItem = static_cast<const ScQueryItem&>(*pItem);
+
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ SCTAB nRefTab = GetViewData()->GetRefTabNo();
+
+ // If RefInput switched to a different sheet from the data sheet,
+ // switch back:
+
+ if ( nCurTab != nRefTab )
+ {
+ pTabViewShell->SetTabNo( nRefTab );
+ pTabViewShell->PaintExtras();
+ }
+
+ ScRange aAdvSource;
+ if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
+ pTabViewShell->Query( rQueryItem.GetQueryData(), &aAdvSource, TRUE );
+ else
+ pTabViewShell->Query( rQueryItem.GetQueryData(), NULL, TRUE );
+ rReq.Done( *pReqArgs );
+ }
+ }
+ break;
+
+ case SID_UNFILTER:
+ {
+ ScQueryParam aParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+
+ pDBData->GetQueryParam( aParam );
+ SCSIZE nEC = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aParam.GetEntry(i).bDoQuery = FALSE;
+ aParam.bDuplicate = TRUE;
+ pTabViewShell->Query( aParam, NULL, TRUE );
+ rReq.Done();
+ }
+ break;
+
+ case SID_AUTO_FILTER:
+ pTabViewShell->ToggleAutoFilter();
+ rReq.Done();
+ break;
+
+ case SID_AUTOFILTER_HIDE:
+ pTabViewShell->HideAutoFilter();
+ rReq.Done();
+ break;
+
+ case SID_PIVOT_TABLE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState( SCITEM_PIVOTDATA, TRUE, &pItem ) )
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ SCTAB nRefTab = GetViewData()->GetRefTabNo();
+
+ // Wenn RefInput auf andere Tabelle als Datentabelle umgeschaltet
+ // hat wieder zurueckschalten:
+
+ if ( nCurTab != nRefTab )
+ {
+ pTabViewShell->SetTabNo( nRefTab );
+ pTabViewShell->PaintExtras();
+ }
+
+ const ScDPObject* pDPObject = pTabViewShell->GetDialogDPObject();
+ if ( pDPObject )
+ {
+ const ScPivotItem* pPItem = (const ScPivotItem*)pItem;
+ bool bSuccess = pTabViewShell->MakePivotTable(
+ pPItem->GetData(), pPItem->GetDestRange(), pPItem->IsNewSheet(), *pDPObject );
+ SfxBoolItem aRet(0, bSuccess);
+ rReq.SetReturnValue(aRet);
+ }
+ rReq.Done();
+ }
+ else if (rReq.IsAPI())
+ SbxBase::SetError(SbxERR_BAD_PARAMETER);
+ }
+ break;
+
+ case SID_OPENDLG_PIVOTTABLE:
+ {
+ ScViewData* pData = GetViewData();
+ ScDocument* pDoc = pData->GetDocument();
+
+ ScDPObject* pNewDPObject = NULL;
+
+ // ScPivot is no longer used...
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(
+ pData->GetCurX(), pData->GetCurY(),
+ pData->GetTabNo() );
+ if ( pDPObj ) // on an existing table?
+ {
+ pNewDPObject = new ScDPObject( *pDPObj );
+ }
+ else // create new table
+ {
+ // select database range or data
+ pTabViewShell->GetDBData( TRUE, SC_DB_OLD );
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ pTabViewShell->MarkDataArea( FALSE );
+
+ // output to cursor position for non-sheet data
+ ScAddress aDestPos( pData->GetCurX(), pData->GetCurY(),
+ pData->GetTabNo() );
+
+ // first select type of source data
+
+ BOOL bEnableExt = ScDPObject::HasRegisteredSources();
+ //CHINA001 ScDataPilotSourceTypeDlg* pTypeDlg = new ScDataPilotSourceTypeDlg(
+ //CHINA001 pTabViewShell->GetDialogParent(), bEnableExt );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDataPilotSourceTypeDlg* pTypeDlg = pFact->CreateScDataPilotSourceTypeDlg( pTabViewShell->GetDialogParent(), bEnableExt, RID_SCDLG_DAPITYPE );
+ DBG_ASSERT(pTypeDlg, "Dialog create fail!");//CHINA001
+ if ( pTypeDlg->Execute() == RET_OK )
+ {
+ if ( pTypeDlg->IsExternal() )
+ {
+ uno::Sequence<rtl::OUString> aSources = ScDPObject::GetRegisteredSources();
+ //CHINA001 ScDataPilotServiceDlg* pServDlg = new ScDataPilotServiceDlg(
+ //CHINA001 pTabViewShell->GetDialogParent(), aSources );
+ AbstractScDataPilotServiceDlg* pServDlg = pFact->CreateScDataPilotServiceDlg( pTabViewShell->GetDialogParent(), aSources, RID_SCDLG_DAPISERVICE );
+ DBG_ASSERT(pServDlg, "Dialog create fail!");//CHINA001
+ if ( pServDlg->Execute() == RET_OK )
+ {
+ ScDPServiceDesc aServDesc(
+ pServDlg->GetServiceName(),
+ pServDlg->GetParSource(),
+ pServDlg->GetParName(),
+ pServDlg->GetParUser(),
+ pServDlg->GetParPass() );
+ pNewDPObject = new ScDPObject( pDoc );
+ pNewDPObject->SetServiceData( aServDesc );
+ }
+ delete pServDlg;
+ }
+ else if ( pTypeDlg->IsDatabase() )
+ {
+ //CHINA001 ScDataPilotDatabaseDlg* pDataDlg = new ScDataPilotDatabaseDlg(
+ //CHINA001 pTabViewShell->GetDialogParent() );
+ //ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDataPilotDatabaseDlg* pDataDlg = pFact->CreateScDataPilotDatabaseDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_DAPIDATA);
+ DBG_ASSERT(pDataDlg, "Dialog create fail!");//CHINA001
+ if ( pDataDlg->Execute() == RET_OK )
+ {
+ ScImportSourceDesc aImpDesc;
+ pDataDlg->GetValues( aImpDesc );
+ pNewDPObject = new ScDPObject( pDoc );
+ pNewDPObject->SetImportDesc( aImpDesc );
+ }
+ delete pDataDlg;
+ }
+ else // selection
+ {
+ //! use database ranges (select before type dialog?)
+ ScRange aRange;
+ ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
+ if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
+ {
+ // Shrink the range to the data area.
+ SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
+ SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
+ {
+ aRange.aStart.SetCol(nStartCol);
+ aRange.aStart.SetRow(nStartRow);
+ aRange.aEnd.SetCol(nEndCol);
+ aRange.aEnd.SetRow(nEndRow);
+ rMark.SetMarkArea(aRange);
+ pTabViewShell->MarkRange(aRange);
+ }
+
+ BOOL bOK = TRUE;
+ if ( pDoc->HasSubTotalCells( aRange ) )
+ {
+ // confirm selection if it contains SubTotal cells
+
+ QueryBox aBox( pTabViewShell->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_DATAPILOT_SUBTOTAL) );
+ if (aBox.Execute() == RET_NO)
+ bOK = FALSE;
+ }
+ if (bOK)
+ {
+ ScSheetSourceDesc aShtDesc;
+ aShtDesc.aSourceRange = aRange;
+ pNewDPObject = new ScDPObject( pDoc );
+ pNewDPObject->SetSheetDesc( aShtDesc );
+
+ // output below source data
+ if ( aRange.aEnd.Row()+2 <= MAXROW - 4 )
+ aDestPos = ScAddress( aRange.aStart.Col(),
+ aRange.aEnd.Row()+2,
+ aRange.aStart.Tab() );
+ }
+ }
+ }
+ }
+ delete pTypeDlg;
+
+ if ( pNewDPObject )
+ pNewDPObject->SetOutRange( aDestPos );
+
+#if 0
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ String aErrMsg;
+
+ pDBData->GetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
+
+ bAreaOk = TRUE;
+ if ( nRow2-nRow1 < 1 )
+ {
+ // "mindestens eine Datenzeile"
+ pTabViewShell->ErrorMessage(STR_PIVOT_INVALID_DBAREA);
+ bAreaOk = FALSE;
+ }
+ else if (!pDBData->HasHeader())
+ {
+ if ( MessBox( pTabViewShell->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), // "StarCalc"
+ ScGlobal::GetRscString( STR_MSSG_MAKEAUTOFILTER_0 ) // Koepfe aus erster Zeile?
+ ).Execute() == RET_YES )
+ {
+ pDBData->SetHeader( TRUE ); //! Undo ??
+ }
+ else
+ bAreaOk = FALSE;
+ }
+#endif
+ }
+
+ pTabViewShell->SetDialogDPObject( pNewDPObject ); // is copied
+ if ( pNewDPObject )
+ {
+ // start layout dialog
+
+ USHORT nId = ScPivotLayoutWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ delete pNewDPObject;
+ }
+ break;
+
+ case SID_DEFINE_DBNAME:
+ {
+
+ USHORT nId = ScDbNameDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+
+ }
+ break;
+
+ case SID_SELECT_DB:
+ {
+ if ( pReqArgs )
+ {
+ const SfxStringItem* pItem =
+ (const SfxStringItem*)&pReqArgs->Get( SID_SELECT_DB );
+
+ if( pItem )
+ {
+ pTabViewShell->GotoDBArea( pItem->GetValue() );
+ rReq.Done();
+ }
+ else
+ {
+ DBG_ERROR("NULL");
+ }
+ }
+ else
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBCollection* pDBCol = pDoc->GetDBCollection();
+
+ if ( pDBCol )
+ {
+ const String aStrNoName( ScGlobal::GetRscString(STR_DB_NONAME) );
+ List aList;
+ USHORT nDBCount = pDBCol->GetCount();
+ ScDBData* pDbData = NULL;
+ String* pDBName = NULL;
+
+ for ( USHORT i=0; i < nDBCount; i++ )
+ {
+ pDbData = (ScDBData*)(pDBCol->At( i ));
+ if ( pDbData )
+ {
+ pDBName = new String;
+ pDbData->GetName( *pDBName );
+
+ if ( *pDBName != aStrNoName )
+ aList.Insert( pDBName );
+ else
+ DELETEZ(pDBName);
+ }
+ }
+
+//CHINA001 ScSelEntryDlg* pDlg =
+//CHINA001 new ScSelEntryDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_SELECTDB,
+//CHINA001 String(ScResId(SCSTR_SELECTDB)),
+//CHINA001 String(ScResId(SCSTR_AREAS)),
+//CHINA001 aList );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScSelEntryDlg* pDlg = pFact->CreateScSelEntryDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_SELECTDB,
+ String(ScResId(SCSTR_SELECTDB)),
+ String(ScResId(SCSTR_AREAS)),
+ aList,
+ RID_SCDLG_SELECTDB);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ String aName = pDlg->GetSelectEntry();
+ pTabViewShell->GotoDBArea( aName );
+ rReq.AppendItem( SfxStringItem( SID_SELECT_DB, aName ) );
+ rReq.Done();
+ }
+
+ delete pDlg;
+
+ void* pEntry = aList.First();
+ while ( pEntry )
+ {
+ delete (String*) aList.Remove( pEntry );
+ pEntry = aList.Next();
+ }
+ }
+ }
+ }
+ break;
+
+ case FID_VALIDATION:
+ {
+ const SfxPoolItem* pItem;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ DBG_ERROR("spaeter...");
+ }
+ else
+ {
+ //CHINA001 SfxItemSet aArgSet( GetPool(), ScTPValidationValue::GetRanges() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ ::GetTabPageRanges ScTPValidationValueGetRanges = pFact->GetTabPageRangesFunc(TP_VALIDATION_VALUES);
+ DBG_ASSERT(ScTPValidationValueGetRanges, "TabPage create fail!");//CHINA001
+ SfxItemSet aArgSet( GetPool(), (*ScTPValidationValueGetRanges)() );//CHINA001
+ ScValidationMode eMode = SC_VALID_ANY;
+ ScConditionMode eOper = SC_COND_EQUAL;
+ String aExpr1, aExpr2;
+ BOOL bBlank = TRUE;
+ sal_Int16 nListType = ValidListType::UNSORTED;
+ BOOL bShowHelp = FALSE;
+ String aHelpTitle, aHelpText;
+ BOOL bShowError = FALSE;
+ ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
+ String aErrTitle, aErrText;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursorPos( nCurX, nCurY, nTab );
+ ULONG nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
+ nCurX, nCurY, nTab, ATTR_VALIDDATA ))->GetValue();
+ if ( nIndex )
+ {
+ const ScValidationData* pOldData = pDoc->GetValidationEntry( nIndex );
+ if ( pOldData )
+ {
+ eMode = pOldData->GetDataMode();
+ eOper = pOldData->GetOperation();
+ ULONG nNumFmt = 0;
+ if ( eMode == SC_VALID_DATE || eMode == SC_VALID_TIME )
+ {
+ short nType = ( eMode == SC_VALID_DATE ) ? NUMBERFORMAT_DATE
+ : NUMBERFORMAT_TIME;
+ nNumFmt = pDoc->GetFormatTable()->GetStandardFormat(
+ nType, ScGlobal::eLnge );
+ }
+ aExpr1 = pOldData->GetExpression( aCursorPos, 0, nNumFmt );
+ aExpr2 = pOldData->GetExpression( aCursorPos, 1, nNumFmt );
+ bBlank = pOldData->IsIgnoreBlank();
+ nListType = pOldData->GetListType();
+
+ bShowHelp = pOldData->GetInput( aHelpTitle, aHelpText );
+ bShowError = pOldData->GetErrMsg( aErrTitle, aErrText, eErrStyle );
+
+ aArgSet.Put( SfxAllEnumItem( FID_VALID_MODE, sal::static_int_cast<USHORT>(eMode) ) );
+ aArgSet.Put( SfxAllEnumItem( FID_VALID_CONDMODE, sal::static_int_cast<USHORT>(eOper) ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_VALUE1, aExpr1 ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_VALUE2, aExpr2 ) );
+ aArgSet.Put( SfxBoolItem( FID_VALID_BLANK, bBlank ) );
+ aArgSet.Put( SfxInt16Item( FID_VALID_LISTTYPE, nListType ) );
+ aArgSet.Put( SfxBoolItem( FID_VALID_SHOWHELP, bShowHelp ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_HELPTITLE, aHelpTitle ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_HELPTEXT, aHelpText ) );
+ aArgSet.Put( SfxBoolItem( FID_VALID_SHOWERR, bShowError ) );
+ aArgSet.Put( SfxAllEnumItem( FID_VALID_ERRSTYLE, sal::static_int_cast<USHORT>(eErrStyle) ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_ERRTITLE, aErrTitle ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_ERRTEXT, aErrText ) );
+ }
+ }
+
+ //CHINA001 ScValidationDlg* pDlg = new ScValidationDlg( NULL, &aArgSet );
+ //CHINA001 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ //CHINA001 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //SfxAbstractTabDialog* pDlg = pFact->CreateScValidationDlg( NULL, &aArgSet, TAB_DLG_VALIDATION );
+ SfxAbstractTabDialog* pDlg = pFact->CreateScValidationDlg( NULL, &aArgSet, TAB_DLG_VALIDATION, pTabViewShell );
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //if ( pDlg->Execute() == RET_OK )
+ short nResult = pDlg->Execute();
+ pTabViewShell->SetTabNo( nTab );//When picking Cell Range ,other Tab may be switched. Need restore the correct tab
+ if ( nResult == RET_OK )
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ if ( pOutSet->GetItemState( FID_VALID_MODE, TRUE, &pItem ) == SFX_ITEM_SET )
+ eMode = (ScValidationMode) ((const SfxAllEnumItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_CONDMODE, TRUE, &pItem ) == SFX_ITEM_SET )
+ eOper = (ScConditionMode) ((const SfxAllEnumItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_VALUE1, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ String aTemp1 = ((const SfxStringItem*)pItem)->GetValue();
+ if (eMode == SC_VALID_DATE || eMode == SC_VALID_TIME)
+ {
+ sal_uInt32 nNumIndex = 0;
+ double nVal;
+ if (pDoc->GetFormatTable()->IsNumberFormat(aTemp1, nNumIndex, nVal))
+ aExpr1 =String( ::rtl::math::doubleToUString( nVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), TRUE));
+ else
+ aExpr1 = aTemp1;
+ }
+ else
+ aExpr1 = aTemp1;
+ }
+ if ( pOutSet->GetItemState( FID_VALID_VALUE2, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ String aTemp2 = ((const SfxStringItem*)pItem)->GetValue();
+ if (eMode == SC_VALID_DATE || eMode == SC_VALID_TIME)
+ {
+ sal_uInt32 nNumIndex = 0;
+ double nVal;
+ if (pDoc->GetFormatTable()->IsNumberFormat(aTemp2, nNumIndex, nVal))
+ aExpr2 =String( ::rtl::math::doubleToUString( nVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), TRUE));
+ else
+ aExpr2 = aTemp2;
+ }
+ else
+ aExpr2 = aTemp2;
+ }
+
+ if ( pOutSet->GetItemState( FID_VALID_BLANK, TRUE, &pItem ) == SFX_ITEM_SET )
+ bBlank = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_LISTTYPE, TRUE, &pItem ) == SFX_ITEM_SET )
+ nListType = ((const SfxInt16Item*)pItem)->GetValue();
+
+ if ( pOutSet->GetItemState( FID_VALID_SHOWHELP, TRUE, &pItem ) == SFX_ITEM_SET )
+ bShowHelp = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_HELPTITLE, TRUE, &pItem ) == SFX_ITEM_SET )
+ aHelpTitle = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_HELPTEXT, TRUE, &pItem ) == SFX_ITEM_SET )
+ aHelpText = ((const SfxStringItem*)pItem)->GetValue();
+
+ if ( pOutSet->GetItemState( FID_VALID_SHOWERR, TRUE, &pItem ) == SFX_ITEM_SET )
+ bShowError = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_ERRSTYLE, TRUE, &pItem ) == SFX_ITEM_SET )
+ eErrStyle = (ScValidErrorStyle) ((const SfxAllEnumItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_ERRTITLE, TRUE, &pItem ) == SFX_ITEM_SET )
+ aErrTitle = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_ERRTEXT, TRUE, &pItem ) == SFX_ITEM_SET )
+ aErrText = ((const SfxStringItem*)pItem)->GetValue();
+
+ ScValidationData aData( eMode, eOper, aExpr1, aExpr2, pDoc, aCursorPos );
+ aData.SetIgnoreBlank( bBlank );
+ aData.SetListType( nListType );
+
+ aData.SetInput(aHelpTitle, aHelpText); // sets bShowInput to TRUE
+ if (!bShowHelp)
+ aData.ResetInput(); // reset only bShowInput
+
+ aData.SetError(aErrTitle, aErrText, eErrStyle); // sets bShowError to TRUE
+ if (!bShowError)
+ aData.ResetError(); // reset only bShowError
+
+ pTabViewShell->SetValidation( aData );
+ rReq.Done( *pOutSet );
+ }
+ //<!-- Modified by PengYunQuan for Validity Cell Range Picker
+ //after end execute from !IsModalInputMode, it is safer to delay deleting
+ //delete pDlg;
+ Application::PostUserEvent( Link( pDlg, &DelayDeleteAbstractDialog ) );
+ //--> Modified by PengYunQuan for Validity Cell Range Picker
+ }
+ }
+ break;
+
+ case SID_TEXT_TO_COLUMNS:
+ {
+ ScViewData* pData = GetViewData();
+ DBG_ASSERT( pData, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pData is null!" );
+ ScRange aRange;
+
+ if ( lcl_GetTextToColumnsRange( pData, aRange ) )
+ {
+ ScDocument* pDoc = pData->GetDocument();
+ DBG_ASSERT( pDoc, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pDoc is null!" );
+
+ ScImportExport aExport( pDoc, aRange );
+ aExport.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::None, 0, false ) );
+
+ // #i87703# text to columns fails with tab separator
+ aExport.SetDelimiter( static_cast< sal_Unicode >( 0 ) );
+
+ SvMemoryStream aStream;
+ aStream.SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
+ ScImportExport::SetNoEndianSwap( aStream );
+ aExport.ExportStream( aStream, String(), FORMAT_STRING );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT( pFact, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pFact is null!" );
+ AbstractScImportAsciiDlg *pDlg = pFact->CreateScImportAsciiDlg(
+ NULL, String(), &aStream, RID_SCDLG_ASCII );
+ DBG_ASSERT( pDlg, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pDlg is null!" );
+ pDlg->SetTextToColumnsMode();
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScDocShell* pDocSh = pData->GetDocShell();
+ DBG_ASSERT( pDocSh, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pDocSh is null!" );
+
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_TEXTTOCOLUMNS );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ ScImportExport aImport( pDoc, aRange.aStart );
+ ScAsciiOptions aOptions;
+ pDlg->GetOptions( aOptions );
+ aImport.SetExtOptions( aOptions );
+ aImport.SetApi( false );
+ aStream.Seek( 0 );
+ aImport.ImportStream( aStream, String(), FORMAT_STRING );
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ delete pDlg;
+ }
+ }
+ break;
+ }
+}
+
+void __EXPORT ScCellShell::GetDBState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ ScViewData* pData = GetViewData();
+ ScDocShell* pDocSh = pData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nPosX = pData->GetCurX();
+ SCROW nPosY = pData->GetCurY();
+ SCTAB nTab = pData->GetTabNo();
+
+ BOOL bAutoFilter = FALSE;
+ BOOL bAutoFilterTested = FALSE;
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_REFRESH_DBAREA:
+ {
+ // importierte Daten ohne Selektion
+ // oder Filter,Sortierung,Teilergebis (auch ohne Import)
+ BOOL bOk = FALSE;
+ ScDBData* pDBData = pTabViewShell->GetDBData(FALSE,SC_DB_OLD);
+ if (pDBData && pDoc->GetChangeTrack() == NULL)
+ {
+ if ( pDBData->HasImportParam() )
+ bOk = !pDBData->HasImportSelection();
+ else
+ {
+ bOk = pDBData->HasQueryParam() ||
+ pDBData->HasSortParam() ||
+ pDBData->HasSubTotalParam();
+ }
+ }
+ if (!bOk)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_FILTER:
+ case SID_SPECIAL_FILTER:
+ {
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+
+ //Bei Redlining und Multiselektion Disablen
+ case SID_SORT_ASCENDING:
+ case SID_SORT_DESCENDING:
+ case SCITEM_SORTDATA:
+ case SCITEM_SUBTDATA:
+ case SID_OPENDLG_PIVOTTABLE:
+ {
+ //! move ReadOnly check to idl flags
+
+ if ( pDocSh->IsReadOnly() || pDoc->GetChangeTrack()!=NULL ||
+ GetViewData()->IsMultiMarked() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_REIMPORT_DATA:
+ {
+ // nur importierte Daten ohne Selektion
+ ScDBData* pDBData = pTabViewShell->GetDBData(FALSE,SC_DB_OLD);
+ if (!pDBData || !pDBData->HasImportParam() || pDBData->HasImportSelection() ||
+ pDoc->GetChangeTrack()!=NULL)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_VIEW_DATA_SOURCE_BROWSER:
+ {
+ if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SDATABASE))
+ rSet.Put(SfxVisibilityItem(nWhich, sal_False));
+ else
+ // get state (BoolItem) from SfxViewFrame
+ pTabViewShell->GetViewFrame()->GetSlotState( nWhich, NULL, &rSet );
+ }
+ break;
+ case SID_SBA_BRW_INSERT:
+ {
+ // SBA will ein BOOL-Item, damit ueberhaupt enabled
+
+ BOOL bEnable = TRUE;
+ rSet.Put(SfxBoolItem(nWhich, bEnable));
+ }
+ break;
+
+ case SID_AUTO_FILTER:
+ case SID_AUTOFILTER_HIDE:
+ {
+ if (!bAutoFilterTested)
+ {
+ bAutoFilter = pDoc->HasAutoFilter( nPosX, nPosY, nTab );
+ bAutoFilterTested = TRUE;
+ }
+ if ( nWhich == SID_AUTO_FILTER )
+ {
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else if (pDoc->GetDPAtBlock(aDummy))
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ rSet.Put( SfxBoolItem( nWhich, bAutoFilter ) );
+ }
+ else
+ if (!bAutoFilter)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_UNFILTER:
+ {
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nStartTab, nEndTab;
+ BOOL bAnyQuery = FALSE;
+
+ BOOL bSelected = (GetViewData()->GetSimpleArea(
+ nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab )
+ == SC_MARK_SIMPLE);
+
+ if ( bSelected )
+ {
+ if (nStartCol==nEndCol && nStartRow==nEndRow)
+ bSelected = FALSE;
+ }
+ else
+ {
+ nStartCol = GetViewData()->GetCurX();
+ nStartRow = GetViewData()->GetCurY();
+ nStartTab = GetViewData()->GetTabNo();
+ }
+
+ ScDBData* pDBData = bSelected
+ ? pDoc->GetDBAtArea( nStartTab, nStartCol, nStartRow, nEndCol, nEndRow )
+ : pDoc->GetDBAtCursor( nStartCol, nStartRow, nStartTab );
+
+ if ( pDBData )
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam );
+ if ( aParam.GetEntry(0).bDoQuery )
+ bAnyQuery = TRUE;
+ }
+
+ if ( !bAnyQuery )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DEFINE_DBNAME:
+ {
+ if ( pDocSh && pDocSh->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_TEXT_TO_COLUMNS:
+ {
+ ScRange aRange;
+ if ( !lcl_GetTextToColumnsRange( pData, aRange ) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
new file mode 100644
index 000000000000..ed391f154892
--- /dev/null
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -0,0 +1,966 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "docsh.hxx"
+#include "reffact.hxx"
+#include "uiitems.hxx"
+//CHINA001 #include "scendlg.hxx"
+//CHINA001 #include "mtrindlg.hxx"
+#include "autoform.hxx"
+#include "autofmt.hxx"
+#include "cellsh.hxx"
+#include "attrdlg.hrc" // TP_ALIGNMENT
+#include "inputhdl.hxx"
+#include "editable.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
+
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; }
+
+//------------------------------------------------------------------
+
+void ScCellShell::Execute( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
+ ScModule* pScMod = SC_MOD();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ if (nSlot != SID_CURRENTCELL) // der kommt beim MouseButtonUp
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( IS_EDITMODE() )
+ {
+ switch ( nSlot )
+ {
+ // beim Oeffnen eines Referenz-Dialogs darf die SubShell nicht umgeschaltet werden
+ // (beim Schliessen des Dialogs wird StopEditShell gerufen)
+ case SID_OPENDLG_FUNCTION:
+ // #53318# inplace macht die EditShell Aerger...
+ //! kann nicht immer umgeschaltet werden ????
+ if (!pTabViewShell->GetViewFrame()->GetFrame().IsInPlace())
+ pTabViewShell->SetDontSwitch(TRUE); // EditShell nicht abschalten
+ // kein break
+
+ case FID_CELL_FORMAT:
+ case SID_ENABLE_HYPHENATION:
+ case SID_DATA_SELECT:
+ case SID_OPENDLG_CONSOLIDATE:
+ case SID_OPENDLG_SOLVE:
+ case SID_OPENDLG_OPTSOLVER:
+
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+
+ pTabViewShell->SetDontSwitch(FALSE);
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ( nSlot )
+ {
+
+
+
+ case SID_ATTR_SIZE://XXX ???
+ break;
+
+ case SID_STATUS_SELMODE:
+ if ( pReqArgs )
+ {
+ /* 0: STD Click hebt Sel auf
+ * 1: ER Click erweitert Selektion
+ * 2: ERG Click definiert weitere Selektion
+ */
+ UINT16 nMode = ((const SfxUInt16Item&)pReqArgs->Get( nSlot )).GetValue();
+
+ switch ( nMode )
+ {
+ case 1: nMode = KEY_SHIFT; break;
+ case 2: nMode = KEY_MOD1; break; // Control-Taste
+ case 0:
+ default:
+ nMode = 0;
+ }
+
+ pTabViewShell->LockModifiers( nMode );
+ }
+ else
+ {
+ // no arguments (also executed by double click on the status bar controller):
+ // advance to next selection mode
+
+ USHORT nModifiers = pTabViewShell->GetLockedModifiers();
+ switch ( nModifiers )
+ {
+ case KEY_SHIFT: nModifiers = KEY_MOD1; break; // EXT -> ADD
+ case KEY_MOD1: nModifiers = 0; break; // ADD -> STD
+ default: nModifiers = KEY_SHIFT; break; // STD -> EXT
+ }
+ pTabViewShell->LockModifiers( nModifiers );
+ }
+
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ rReq.Done();
+ break;
+
+ // SID_STATUS_SELMODE_NORM wird nicht benutzt ???
+
+ case SID_STATUS_SELMODE_NORM:
+ pTabViewShell->LockModifiers( 0 );
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ break;
+
+ // SID_STATUS_SELMODE_ERG / SID_STATUS_SELMODE_ERW als Toggles:
+
+ case SID_STATUS_SELMODE_ERG:
+ if ( pTabViewShell->GetLockedModifiers() & KEY_MOD1 )
+ pTabViewShell->LockModifiers( 0 );
+ else
+ pTabViewShell->LockModifiers( KEY_MOD1 );
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ break;
+
+ case SID_STATUS_SELMODE_ERW:
+ if ( pTabViewShell->GetLockedModifiers() & KEY_SHIFT )
+ pTabViewShell->LockModifiers( 0 );
+ else
+ pTabViewShell->LockModifiers( KEY_SHIFT );
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ break;
+
+ case SID_ENTER_STRING:
+ {
+ if ( pReqArgs )
+ {
+ String aStr( ((const SfxStringItem&)pReqArgs->
+ Get( SID_ENTER_STRING )).GetValue() );
+
+ pTabViewShell->EnterData( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo(),
+ aStr );
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pTabViewShell );
+ if ( !pHdl || !pHdl->IsInEnterHandler() )
+ {
+ // #101061# UpdateInputHandler is needed after the cell content
+ // has changed, but if called from EnterHandler, UpdateInputHandler
+ // will be called later when moving the cursor.
+
+ pTabViewShell->UpdateInputHandler();
+ }
+
+ rReq.Done();
+
+ // hier kein GrabFocus, weil sonst auf dem Mac die Tabelle vor die
+ // Seitenansicht springt, wenn die Eingabe nicht abgeschlossen war
+ // (GrabFocus passiert in KillEditView)
+ }
+ }
+ break;
+
+ case SID_INSERT_MATRIX:
+ {
+ if ( pReqArgs )
+ {
+ String aStr = ((const SfxStringItem&)pReqArgs->
+ Get( SID_INSERT_MATRIX )).GetValue();
+ pTabViewShell->EnterMatrix( aStr );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case FID_INPUTLINE_ENTER:
+ case FID_INPUTLINE_BLOCK:
+ case FID_INPUTLINE_MATRIX:
+ {
+ if( pReqArgs == 0 ) //XXX vorlaufiger HACK um GPF zu vermeiden
+ break;
+
+ const ScInputStatusItem* pStatusItem
+ = (const ScInputStatusItem*)&pReqArgs->
+ Get( FID_INPUTLINE_STATUS );
+
+ ScAddress aCursorPos = pStatusItem->GetPos();
+ String aString = pStatusItem->GetString();
+ const EditTextObject* pData = pStatusItem->GetEditData();
+ if (pData)
+ {
+ if (nSlot == FID_INPUTLINE_BLOCK)
+ {
+ pTabViewShell->EnterBlock( aString, pData );
+ }
+ else if ( aString.Len() > 0 && ( aString.GetChar(0) == '=' || aString.GetChar(0) == '+' || aString.GetChar(0) == '-' ) )
+ {
+ pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aString, TRUE, pData );
+ }
+ else
+ {
+ pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), pData );
+ }
+ }
+ else
+ {
+ if (nSlot == FID_INPUTLINE_ENTER)
+ {
+ if (
+ aCursorPos.Col() == GetViewData()->GetCurX() &&
+ aCursorPos.Row() == GetViewData()->GetCurY() &&
+ aCursorPos.Tab() == GetViewData()->GetTabNo()
+ )
+ {
+ SfxStringItem aItem( SID_ENTER_STRING, aString );
+
+ // SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
+ const SfxPoolItem* aArgs[2];
+ aArgs[0] = &aItem;
+ aArgs[1] = NULL;
+ rBindings.Execute( SID_ENTER_STRING, aArgs );
+ }
+ else
+ {
+ pTabViewShell->EnterData( aCursorPos.Col(),
+ aCursorPos.Row(),
+ aCursorPos.Tab(),
+ aString );
+ rReq.Done();
+ }
+ }
+ else if (nSlot == FID_INPUTLINE_BLOCK)
+ {
+ pTabViewShell->EnterBlock( aString, NULL );
+ rReq.Done();
+ }
+ else
+ {
+ pTabViewShell->EnterMatrix( aString );
+ rReq.Done();
+ }
+
+ }
+
+ // hier kein GrabFocus, weil sonst auf dem Mac die Tabelle vor die
+ // Seitenansicht springt, wenn die Eingabe nicht abgeschlossen war
+ // (GrabFocus passiert in KillEditView)
+ }
+ break;
+
+ case SID_OPENDLG_FUNCTION:
+ {
+ USHORT nId = SID_OPENDLG_FUNCTION;
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_OPENDLG_CONSOLIDATE:
+ {
+ USHORT nId = ScConsolidateDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case FID_CELL_FORMAT:
+ {
+ if ( pReqArgs != NULL )
+ {
+ //----------------------------------
+ // Zellattribute ohne Dialog setzen:
+ //----------------------------------
+ SfxItemSet* pEmptySet =
+ new SfxItemSet( *pReqArgs->GetPool(),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ SfxItemSet* pNewSet =
+ new SfxItemSet( *pReqArgs->GetPool(),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ const SfxPoolItem* pAttr = NULL;
+ USHORT nWhich = 0;
+
+ for ( nWhich=ATTR_PATTERN_START; nWhich<=ATTR_PATTERN_END; nWhich++ )
+ if ( pReqArgs->GetItemState( nWhich, TRUE, &pAttr ) == SFX_ITEM_SET )
+ pNewSet->Put( *pAttr );
+
+ pTabViewShell->ApplyAttributes( pNewSet, pEmptySet );
+
+ delete pNewSet;
+ delete pEmptySet;
+
+ rReq.Done();
+ }
+ else if ( pReqArgs == NULL )
+ {
+ pTabViewShell->ExecuteCellFormatDlg( rReq );
+ }
+ }
+ break;
+
+ case SID_ENABLE_HYPHENATION:
+ pTabViewShell->ExecuteCellFormatDlg( rReq, TP_ALIGNMENT );
+ break;
+
+ case SID_OPENDLG_SOLVE:
+ {
+ USHORT nId = ScSolverDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case SID_OPENDLG_OPTSOLVER:
+ {
+ USHORT nId = ScOptSolverDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case SID_OPENDLG_TABOP:
+ {
+ USHORT nId = ScTabOpDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case SID_SCENARIOS:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ if ( pDoc->IsScenario(nTab) )
+ {
+ rMark.MarkToMulti();
+ if ( rMark.IsMultiMarked() )
+ {
+ if ( rReq.IsAPI()
+ || RET_YES ==
+ QueryBox( pTabViewShell->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_UPDATE_SCENARIO) ).
+ Execute() )
+ {
+ pTabViewShell->ExtendScenario();
+ rReq.Done();
+ }
+ }
+ else if( ! rReq.IsAPI() )
+ {
+ ErrorBox aErrorBox( pTabViewShell->GetDialogParent(), WinBits(WB_OK | WB_DEF_OK),
+ ScGlobal::GetRscString(STR_NOAREASELECTED) );
+ aErrorBox.Execute();
+ }
+ }
+ else
+ {
+ rMark.MarkToMulti();
+ if ( rMark.IsMultiMarked() )
+ {
+ SCTAB i=1;
+ String aBaseName;
+ String aName;
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pDoc->GetName( nTab, aBaseName );
+ aBaseName += '_';
+ aBaseName += ScGlobal::GetRscString(STR_SCENARIO);
+ aBaseName += '_';
+
+ // vorneweg testen, ob der Prefix als gueltig erkannt wird
+ // wenn nicht, nur doppelte vermeiden
+ BOOL bPrefix = pDoc->ValidTabName( aBaseName );
+ DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
+
+ while ( pDoc->IsScenario(nTab+i) )
+ i++;
+
+ BOOL bValid;
+ SCTAB nDummy;
+ do
+ {
+ aName = aBaseName;
+ aName += String::CreateFromInt32( i );
+ if (bPrefix)
+ bValid = pDoc->ValidNewTabName( aName );
+ else
+ bValid = !pDoc->GetTable( aName, nDummy );
+ ++i;
+ }
+ while ( !bValid && i <= 2*MAXTAB );
+
+ if ( pReqArgs != NULL )
+ {
+ String aArgName;
+ String aArgComment;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_SCENARIOS, TRUE, &pItem ) == SFX_ITEM_SET )
+ aArgName = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pReqArgs->GetItemState( SID_NEW_TABLENAME, TRUE, &pItem ) == SFX_ITEM_SET )
+ aArgComment = ((const SfxStringItem*)pItem)->GetValue();
+
+ aColor = Color( COL_LIGHTGRAY ); // Default
+ nFlags = 0; // nicht-TwoWay
+
+ pTabViewShell->MakeScenario( aArgName, aArgComment, aColor, nFlags );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ BOOL bSheetProtected = pDoc->IsTabProtected(nTab);
+ //CHINA001 ScNewScenarioDlg* pNewDlg =
+ //CHINA001 new ScNewScenarioDlg( pTabViewShell->GetDialogParent(), aName, FALSE, bSheetProtected );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNewScenarioDlg* pNewDlg = pFact->CreateScNewScenarioDlg( pTabViewShell->GetDialogParent(), aName, RID_SCDLG_NEWSCENARIO, FALSE,bSheetProtected);
+ DBG_ASSERT(pNewDlg, "Dialog create fail!");//CHINA001
+ if ( pNewDlg->Execute() == RET_OK )
+ {
+ pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
+ pTabViewShell->MakeScenario( aName, aComment, aColor, nFlags );
+
+ rReq.AppendItem( SfxStringItem( SID_SCENARIOS, aName ) );
+ rReq.AppendItem( SfxStringItem( SID_NEW_TABLENAME, aComment ) );
+ rReq.Done();
+ }
+ delete pNewDlg;
+ }
+ }
+ else if( ! rReq.IsAPI() )
+ {
+ pTabViewShell->ErrorMessage(STR_ERR_NEWSCENARIO);
+ }
+ }
+ }
+ break;
+
+
+ case SID_SELECTALL:
+ {
+ pTabViewShell->SelectAll();
+ rReq.Done();
+ }
+ break;
+
+ //----------------------------------------------------------------
+
+ case FID_ROW_HEIGHT:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_ROW_HEIGHT );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( FALSE, SC_SIZE_DIRECT,
+ sal::static_int_cast<USHORT>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ ScViewData* pData = GetViewData();
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+ USHORT nCurHeight = pData->GetDocument()->
+ GetRowHeight( pData->GetCurY(),
+ pData->GetTabNo() );
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_MAN,
+//CHINA001 nCurHeight,
+//CHINA001 ScGlobal::nStdRowHeight,
+//CHINA001 eMetric,
+//CHINA001 2,
+//CHINA001 MAX_COL_HEIGHT );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_MAN,
+ nCurHeight,
+ ScGlobal::nStdRowHeight,
+ RID_SCDLG_ROW_MAN,
+ eMetric,
+ 2,
+ MAX_COL_HEIGHT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( FALSE, SC_SIZE_DIRECT, (USHORT)nVal );
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_ROW_HEIGHT, (USHORT)TwipsToEvenHMM(nVal) ) );
+ rReq.Done();
+
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_ROW_OPT_HEIGHT:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_ROW_OPT_HEIGHT );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( FALSE, SC_SIZE_OPTIMAL,
+ sal::static_int_cast<USHORT>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ ScGlobal::nLastRowHeightExtra = rUInt16Item.GetValue();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_OPT,
+//CHINA001 ScGlobal::nLastRowHeightExtra,
+//CHINA001 0,
+//CHINA001 eMetric,
+//CHINA001 1,
+//CHINA001 MAX_EXTRA_HEIGHT );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_OPT,
+ ScGlobal::nLastRowHeightExtra,
+ 0,
+ RID_SCDLG_ROW_OPT,
+ eMetric,
+ 1,
+ MAX_EXTRA_HEIGHT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( FALSE, SC_SIZE_OPTIMAL, (USHORT)nVal );
+ ScGlobal::nLastRowHeightExtra = nVal;
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_ROW_OPT_HEIGHT, (USHORT)TwipsToEvenHMM(nVal) ) );
+ rReq.Done();
+
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_COL_WIDTH:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_COL_WIDTH );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_DIRECT,
+ sal::static_int_cast<USHORT>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+ ScViewData* pData = GetViewData();
+ USHORT nCurHeight = pData->GetDocument()->
+ GetColWidth( pData->GetCurX(),
+ pData->GetTabNo() );
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_MAN,
+//CHINA001 nCurHeight,
+//CHINA001 STD_COL_WIDTH,
+//CHINA001 eMetric,
+//CHINA001 2,
+//CHINA001 MAX_COL_WIDTH );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_MAN,
+ nCurHeight,
+ STD_COL_WIDTH,
+ RID_SCDLG_COL_MAN,
+ eMetric,
+ 2,
+ MAX_COL_WIDTH);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_DIRECT, (USHORT)nVal );
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_COL_WIDTH, (USHORT)TwipsToEvenHMM(nVal)) );
+ rReq.Done();
+
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_COL_OPT_WIDTH:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_COL_OPT_WIDTH );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_OPTIMAL,
+ sal::static_int_cast<USHORT>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ ScGlobal::nLastColWidthExtra = rUInt16Item.GetValue();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_OPT,
+//CHINA001 ScGlobal::nLastColWidthExtra,
+//CHINA001 STD_EXTRA_WIDTH,
+//CHINA001 eMetric,
+//CHINA001 1,
+//CHINA001 MAX_EXTRA_WIDTH );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_OPT,
+ ScGlobal::nLastColWidthExtra,
+ STD_EXTRA_WIDTH,
+ RID_SCDLG_COL_OPT,
+ eMetric,
+ 1,
+ MAX_EXTRA_WIDTH);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_OPTIMAL, (USHORT)nVal );
+ ScGlobal::nLastColWidthExtra = nVal;
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_COL_OPT_WIDTH, (USHORT)TwipsToEvenHMM(nVal) ) );
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_COL_OPT_DIRECT:
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH );
+ rReq.Done();
+ break;
+
+ case FID_ROW_HIDE:
+ pTabViewShell->SetMarkedWidthOrHeight( FALSE, SC_SIZE_DIRECT, 0 );
+ rReq.Done();
+ break;
+ case FID_ROW_SHOW:
+ pTabViewShell->SetMarkedWidthOrHeight( FALSE, SC_SIZE_SHOW, 0 );
+ rReq.Done();
+ break;
+ case FID_COL_HIDE:
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_DIRECT, 0 );
+ rReq.Done();
+ break;
+ case FID_COL_SHOW:
+ pTabViewShell->SetMarkedWidthOrHeight( TRUE, SC_SIZE_SHOW, 0 );
+ rReq.Done();
+ break;
+
+ //----------------------------------------------------------------
+
+
+ case SID_CELL_FORMAT_RESET:
+ {
+ pTabViewShell->DeleteContents( IDF_HARDATTR | IDF_EDITATTR );
+ rReq.Done();
+ }
+ break;
+
+ case FID_MERGE_ON:
+ case FID_MERGE_OFF:
+ case FID_MERGE_TOGGLE:
+ {
+ if ( !GetViewData()->GetDocument()->GetChangeTrack() )
+ {
+ // test whether to merge or to split
+ bool bMerge = false;
+ switch( nSlot )
+ {
+ case FID_MERGE_ON:
+ bMerge = true;
+ break;
+ case FID_MERGE_OFF:
+ bMerge = false;
+ break;
+ case FID_MERGE_TOGGLE:
+ {
+ SfxPoolItem* pItem = 0;
+ if( rBindings.QueryState( nSlot, pItem ) >= SFX_ITEM_DEFAULT )
+ bMerge = !static_cast< SfxBoolItem* >( pItem )->GetValue();
+ }
+ break;
+ }
+
+ if( bMerge )
+ {
+ // merge - check if to move contents of covered cells
+ BOOL bMoveContents = FALSE;
+ BOOL bApi = rReq.IsAPI();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET )
+ {
+ DBG_ASSERT(pItem && pItem->ISA(SfxBoolItem), "falsches Item");
+ bMoveContents = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+
+ if (pTabViewShell->MergeCells( bApi, bMoveContents ))
+ {
+ if (!bApi && bMoveContents) // "ja" im Dialog geklickt
+ rReq.AppendItem( SfxBoolItem( nSlot, bMoveContents ) );
+ rBindings.Invalidate( nSlot );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ // split cells
+ if (pTabViewShell->RemoveMerge())
+ {
+ rBindings.Invalidate( nSlot );
+ rReq.Done();
+ }
+ }
+ break;
+ }
+ }
+ break;
+
+ case SID_AUTOFORMAT:
+ {
+ Window* pDlgParent = pTabViewShell->GetDialogParent();
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ pTabViewShell->MarkDataArea( TRUE );
+
+ GetViewData()->GetSimpleArea( nStartCol,nStartRow,nStartTab,
+ nEndCol,nEndRow,nEndTab );
+
+ if ( ( Abs((SCsCOL)nEndCol-(SCsCOL)nStartCol) > 1 )
+ && ( Abs((SCsROW)nEndRow-(SCsROW)nStartRow) > 1 ) )
+ {
+ if ( pReqArgs )
+ {
+ const SfxStringItem& rNameItem = (const SfxStringItem&)pReqArgs->Get( SID_AUTOFORMAT );
+ ScAutoFormat* pFormat = ScGlobal::GetAutoFormat();
+ USHORT nIndex = pFormat->FindIndexPerName( rNameItem.GetValue() );
+
+ pTabViewShell->AutoFormat( nIndex );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ ScGlobal::ClearAutoFormat();
+ ScAutoFormatData* pNewEntry = pTabViewShell->CreateAutoFormatData();
+//CHINA001 ScAutoFormatDlg* pDlg = new ScAutoFormatDlg(
+//CHINA001 pDlgParent,
+//CHINA001 ScGlobal::GetAutoFormat(),
+//CHINA001 pNewEntry,
+//CHINA001 GetViewData()->GetDocument() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScAutoFormatDlg* pDlg = pFact->CreateScAutoFormatDlg( pDlgParent, ScGlobal::GetAutoFormat(), pNewEntry,GetViewData()->GetDocument(), RID_SCDLG_AUTOFORMAT );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScEditableTester aTester( pTabViewShell );
+ if ( !aTester.IsEditable() )
+ {
+ pTabViewShell->ErrorMessage(aTester.GetMessageId());
+ }
+ else
+ {
+ pTabViewShell->AutoFormat( pDlg->GetIndex() );
+
+ rReq.AppendItem( SfxStringItem( SID_AUTOFORMAT, pDlg->GetCurrFormatName() ) );
+ rReq.Done();
+ }
+ }
+ delete pDlg;
+ delete pNewEntry;
+ }
+ }
+ else
+ ErrorBox( pDlgParent, WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString(STR_INVALID_AFAREA) ).Execute();
+ }
+ break;
+
+ case SID_CANCEL:
+ {
+ if (GetViewData()->HasEditView(GetViewData()->GetActivePart()))
+ pScMod->InputCancelHandler();
+ else if (pTabViewShell->HasPaintBrush())
+ pTabViewShell->ResetBrushDocument(); // abort format paint brush
+ else if (pTabViewShell->HasHintWindow())
+ pTabViewShell->RemoveHintWindow(); // Eingabemeldung abschalten
+ else if( ScViewUtil::IsFullScreen( *pTabViewShell ) )
+ ScViewUtil::SetFullScreen( *pTabViewShell, false );
+ else
+ {
+ // TODO/LATER: when is this code executed?
+ pTabViewShell->Escape();
+ //SfxObjectShell* pObjSh = GetViewData()->GetSfxDocShell();
+ //if (pObjSh->GetInPlaceObject() &&
+ // pObjSh->GetInPlaceObject()->GetIPClient())
+ //{
+ // GetViewData()->GetDocShell()->
+ // DoInPlaceActivate(FALSE); // OLE beenden
+ //}
+ }
+
+// SetSumAssignMode(); //ScInputWindow
+ }
+ break;
+
+ case SID_DATA_SELECT:
+ pTabViewShell->StartDataSelect();
+ break;
+
+ case SID_DETECTIVE_FILLMODE:
+ {
+ BOOL bOldMode = pTabViewShell->IsAuditShell();
+ pTabViewShell->SetAuditShell( !bOldMode );
+ pTabViewShell->Invalidate( nSlot );
+ }
+ break;
+
+ case SID_OPENDLG_CONDFRMT:
+ {
+ USHORT nId = ScCondFormatDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ // ----------------------------------------------------------------
+
+ case FID_INPUTLINE_STATUS:
+ DBG_ERROR("Execute von InputLine-Status");
+ break;
+
+ case SID_STATUS_DOCPOS:
+ // 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");
+ break;
+
+ default:
+ DBG_ERROR("Unbekannter Slot bei ScCellShell::Execute");
+ break;
+ }
+}
+
diff --git a/sc/source/ui/view/cellsh4.cxx b/sc/source/ui/view/cellsh4.cxx
new file mode 100644
index 000000000000..e8419a24c80f
--- /dev/null
+++ b/sc/source/ui/view/cellsh4.cxx
@@ -0,0 +1,382 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/request.hxx>
+
+#include "cellsh.hxx"
+#include "tabvwsh.hxx"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+
+
+//------------------------------------------------------------------
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+
+void ScCellShell::ExecuteCursor( SfxRequest& rReq )
+{
+ ScViewData* pData = GetViewData();
+ ScTabViewShell* pTabViewShell = pData->GetViewShell();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlotId = rReq.GetSlot();
+ SCsCOLROW nRepeat = 1;
+ BOOL bSel = FALSE;
+ BOOL bKeep = FALSE;
+
+ if ( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nRepeat = static_cast<SCsCOLROW>(((const SfxInt16Item*)pItem)->GetValue());
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ bSel = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+ else
+ {
+ // evaluate locked selection mode
+
+ USHORT nLocked = pTabViewShell->GetLockedModifiers();
+ if ( nLocked & KEY_SHIFT )
+ bSel = TRUE; // EXT
+ else if ( nLocked & KEY_MOD1 )
+ {
+ // ADD mode: keep the selection, start a new block when marking with shift again
+ bKeep = TRUE;
+ pTabViewShell->SetNewStartIfMarking();
+ }
+ }
+
+ SCsCOLROW nRTLSign = 1;
+ if ( pData->GetDocument()->IsLayoutRTL( pData->GetTabNo() ) )
+ {
+ //! evaluate cursor movement option?
+ nRTLSign = -1;
+ }
+
+ // einmal extra, damit der Cursor bei ExecuteInputDirect nicht zuoft gemalt wird:
+ pTabViewShell->HideAllCursors();
+
+ //OS: einmal fuer alle wird doch reichen!
+ pTabViewShell->ExecuteInputDirect();
+ switch ( nSlotId )
+ {
+ case SID_CURSORDOWN:
+ pTabViewShell->MoveCursorRel( 0, nRepeat, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKDOWN:
+ pTabViewShell->MoveCursorArea( 0, nRepeat, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORUP:
+ pTabViewShell->MoveCursorRel( 0, -nRepeat, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKUP:
+ pTabViewShell->MoveCursorArea( 0, -nRepeat, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORLEFT:
+ pTabViewShell->MoveCursorRel( static_cast<SCsCOL>(-nRepeat * nRTLSign), 0, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKLEFT:
+ pTabViewShell->MoveCursorArea( static_cast<SCsCOL>(-nRepeat * nRTLSign), 0, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORRIGHT:
+ pTabViewShell->MoveCursorRel( static_cast<SCsCOL>(nRepeat * nRTLSign), 0, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKRIGHT:
+ pTabViewShell->MoveCursorArea( static_cast<SCsCOL>(nRepeat * nRTLSign), 0, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGEDOWN:
+ pTabViewShell->MoveCursorPage( 0, nRepeat, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGEUP:
+ pTabViewShell->MoveCursorPage( 0, -nRepeat, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGERIGHT_: //XXX !!!
+ pTabViewShell->MoveCursorPage( static_cast<SCsCOL>(nRepeat), 0, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGELEFT_: //XXX !!!
+ pTabViewShell->MoveCursorPage( static_cast<SCsCOL>(-nRepeat), 0, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (Cursor)");
+ return;
+ }
+
+ pTabViewShell->ShowAllCursors();
+
+ rReq.AppendItem( SfxInt16Item(FN_PARAM_1, static_cast<sal_Int16>(nRepeat)) );
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, bSel) );
+ rReq.Done();
+}
+
+void ScCellShell::GetStateCursor( SfxItemSet& /* rSet */ )
+{
+}
+
+void ScCellShell::ExecuteCursorSel( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlotId = rReq.GetSlot();
+ short nRepeat = 1;
+
+ if ( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nRepeat = ((const SfxInt16Item*)pItem)->GetValue();
+ }
+
+ switch ( nSlotId )
+ {
+ case SID_CURSORDOWN_SEL: rReq.SetSlot( SID_CURSORDOWN ); break;
+ case SID_CURSORBLKDOWN_SEL: rReq.SetSlot( SID_CURSORBLKDOWN ); break;
+ case SID_CURSORUP_SEL: rReq.SetSlot( SID_CURSORUP ); break;
+ case SID_CURSORBLKUP_SEL: rReq.SetSlot( SID_CURSORBLKUP ); break;
+ case SID_CURSORLEFT_SEL: rReq.SetSlot( SID_CURSORLEFT ); break;
+ case SID_CURSORBLKLEFT_SEL: rReq.SetSlot( SID_CURSORBLKLEFT ); break;
+ case SID_CURSORRIGHT_SEL: rReq.SetSlot( SID_CURSORRIGHT ); break;
+ case SID_CURSORBLKRIGHT_SEL: rReq.SetSlot( SID_CURSORBLKRIGHT ); break;
+ case SID_CURSORPAGEDOWN_SEL: rReq.SetSlot( SID_CURSORPAGEDOWN ); break;
+ case SID_CURSORPAGEUP_SEL: rReq.SetSlot( SID_CURSORPAGEUP ); break;
+ case SID_CURSORPAGERIGHT_SEL: rReq.SetSlot( SID_CURSORPAGERIGHT_ ); break;
+ case SID_CURSORPAGELEFT_SEL: rReq.SetSlot( SID_CURSORPAGELEFT_ ); break;
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (CursorSel)");
+ return;
+ }
+ rReq.AppendItem( SfxInt16Item(FN_PARAM_1, nRepeat ) );
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, TRUE) );
+ ExecuteSlot( rReq, GetInterface() );
+}
+
+void ScCellShell::ExecuteMove( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ USHORT nSlotId = rReq.GetSlot();
+
+ if(nSlotId != SID_CURSORTOPOFSCREEN && nSlotId != SID_CURSORENDOFSCREEN)
+ pTabViewShell->ExecuteInputDirect();
+ switch ( nSlotId )
+ {
+ case SID_NEXT_TABLE:
+ case SID_NEXT_TABLE_SEL:
+ pTabViewShell->SelectNextTab( 1, (nSlotId == SID_NEXT_TABLE_SEL) );
+ break;
+
+ case SID_PREV_TABLE:
+ case SID_PREV_TABLE_SEL:
+ pTabViewShell->SelectNextTab( -1, (nSlotId == SID_PREV_TABLE_SEL) );
+ break;
+
+ // Cursorbewegungen in Bloecken gehen nicht von Basic aus,
+ // weil das ScSbxRange-Objekt bei Eingaben die Markierung veraendert
+
+ case SID_NEXT_UNPROTECT:
+ pTabViewShell->FindNextUnprot( FALSE, !rReq.IsAPI() );
+ break;
+
+ case SID_PREV_UNPROTECT:
+ pTabViewShell->FindNextUnprot( TRUE, !rReq.IsAPI() );
+ break;
+
+ case SID_CURSORENTERUP:
+ if (rReq.IsAPI())
+ pTabViewShell->MoveCursorRel( 0, -1, SC_FOLLOW_LINE, FALSE );
+ else
+ pTabViewShell->MoveCursorEnter( TRUE );
+ break;
+
+ case SID_CURSORENTERDOWN:
+ if (rReq.IsAPI())
+ pTabViewShell->MoveCursorRel( 0, 1, SC_FOLLOW_LINE, FALSE );
+ else
+ pTabViewShell->MoveCursorEnter( FALSE );
+ break;
+
+ case SID_SELECT_COL:
+ pTabViewShell->MarkColumns();
+ break;
+
+ case SID_SELECT_ROW:
+ pTabViewShell->MarkRows();
+ break;
+
+ case SID_SELECT_NONE:
+ pTabViewShell->Unmark();
+ break;
+
+ case SID_ALIGNCURSOR:
+ pTabViewShell->AlignToCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), SC_FOLLOW_JUMP );
+ break;
+
+ case SID_MARKDATAAREA:
+ pTabViewShell->MarkDataArea();
+ break;
+
+ case SID_MARKARRAYFORMULA:
+ pTabViewShell->MarkMatrixFormula();
+ break;
+
+ case SID_SETINPUTMODE:
+ SC_MOD()->SetInputMode( SC_INPUT_TABLE );
+ break;
+
+ case SID_FOCUS_INPUTLINE:
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pTabViewShell );
+ if (pHdl)
+ {
+ ScInputWindow* pWin = pHdl->GetInputWindow();
+ if (pWin)
+ pWin->SwitchToTextWin();
+ }
+ }
+ break;
+
+ case SID_CURSORTOPOFSCREEN:
+ pTabViewShell->MoveCursorScreen( 0, -1, SC_FOLLOW_LINE, FALSE );
+ break;
+
+ case SID_CURSORENDOFSCREEN:
+ pTabViewShell->MoveCursorScreen( 0, 1, SC_FOLLOW_LINE, FALSE );
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (Cursor)");
+ return;
+ }
+
+ rReq.Done();
+}
+
+void ScCellShell::ExecutePageSel( SfxRequest& rReq )
+{
+ USHORT nSlotId = rReq.GetSlot();
+ switch ( nSlotId )
+ {
+ case SID_CURSORHOME_SEL: rReq.SetSlot( SID_CURSORHOME ); break;
+ case SID_CURSOREND_SEL: rReq.SetSlot( SID_CURSOREND ); break;
+ case SID_CURSORTOPOFFILE_SEL: rReq.SetSlot( SID_CURSORTOPOFFILE ); break;
+ case SID_CURSORENDOFFILE_SEL: rReq.SetSlot( SID_CURSORENDOFFILE ); break;
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (ExecutePageSel)");
+ return;
+ }
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, TRUE) );
+ ExecuteSlot( rReq, GetInterface() );
+}
+
+void ScCellShell::ExecutePage( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlotId = rReq.GetSlot();
+ BOOL bSel = FALSE;
+ BOOL bKeep = FALSE;
+
+ if ( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ bSel = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+ else
+ {
+ // evaluate locked selection mode
+
+ USHORT nLocked = pTabViewShell->GetLockedModifiers();
+ if ( nLocked & KEY_SHIFT )
+ bSel = TRUE; // EXT
+ else if ( nLocked & KEY_MOD1 )
+ {
+ // ADD mode: keep the selection, start a new block when marking with shift again
+ bKeep = TRUE;
+ pTabViewShell->SetNewStartIfMarking();
+ }
+ }
+
+ pTabViewShell->ExecuteInputDirect();
+ switch ( nSlotId )
+ {
+ case SID_CURSORHOME:
+ pTabViewShell->MoveCursorEnd( -1, 0, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSOREND:
+ pTabViewShell->MoveCursorEnd( 1, 0, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORTOPOFFILE:
+ pTabViewShell->MoveCursorEnd( -1, -1, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORENDOFFILE:
+ pTabViewShell->MoveCursorEnd( 1, 1, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (ExecutePage)");
+ return;
+ }
+
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, bSel) );
+ rReq.Done();
+}
+
+
+
+
diff --git a/sc/source/ui/view/colrowba.cxx b/sc/source/ui/view/colrowba.cxx
new file mode 100644
index 000000000000..d802c08f642f
--- /dev/null
+++ b/sc/source/ui/view/colrowba.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svx/svdtrans.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "colrowba.hxx"
+#include "document.hxx"
+#include "scmod.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "appoptio.hxx"
+#include "globstr.hrc"
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+String lcl_MetricString( long nTwips, const String& rText )
+{
+ if ( nTwips <= 0 )
+ return ScGlobal::GetRscString(STR_TIP_HIDE);
+ else
+ {
+ FieldUnit eUserMet = SC_MOD()->GetAppOptions().GetAppMetric();
+
+ sal_Int64 nUserVal = MetricField::ConvertValue( nTwips*100, 1, 2, FUNIT_TWIP, eUserMet );
+
+ String aStr = rText;
+ aStr += ' ';
+ aStr += ScGlobal::pLocaleData->getNum( nUserVal, 2 );
+ aStr += ' ';
+ aStr += SdrFormatter::GetUnitStr(eUserMet);
+
+ return aStr;
+ }
+}
+
+//==================================================================
+
+ScColBar::ScColBar( Window* pParent, ScViewData* pData, ScHSplitPos eWhichPos,
+ ScHeaderFunctionSet* pFunc, ScHeaderSelectionEngine* pEng ) :
+ ScHeaderControl( pParent, pEng, MAXCOL+1, HDR_HORIZONTAL ),
+ pViewData( pData ),
+ eWhich( eWhichPos ),
+ pFuncSet( pFunc ),
+ pSelEngine( pEng )
+{
+ Show();
+}
+
+ScColBar::~ScColBar()
+{
+}
+
+inline BOOL ScColBar::UseNumericHeader() const
+{
+ return pViewData->GetDocument()->GetAddressConvention() == formula::FormulaGrammar::CONV_XL_R1C1;
+}
+
+SCCOLROW ScColBar::GetPos()
+{
+ return pViewData->GetPosX(eWhich);
+}
+
+USHORT ScColBar::GetEntrySize( SCCOLROW nEntryNo )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCCOL nLastCol = -1;
+ if (pDoc->ColHidden(static_cast<SCCOL>(nEntryNo), nTab, nLastCol))
+ return 0;
+ else
+ return (USHORT) ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(nEntryNo), nTab ), pViewData->GetPPTX() );
+}
+
+String ScColBar::GetEntryText( SCCOLROW nEntryNo )
+{
+ return UseNumericHeader()
+ ? String::CreateFromInt32( nEntryNo + 1 )
+ : ScColToAlpha( static_cast<SCCOL>(nEntryNo) );
+}
+
+void ScColBar::SetEntrySize( SCCOLROW nPos, USHORT nNewSize )
+{
+ USHORT nSizeTwips;
+ ScSizeMode eMode = SC_SIZE_DIRECT;
+ if (nNewSize>0 && nNewSize<10) nNewSize=10; // (Pixel)
+
+ if ( nNewSize == HDR_SIZE_OPTIMUM )
+ {
+ nSizeTwips = STD_EXTRA_WIDTH;
+ eMode = SC_SIZE_OPTIMAL;
+ }
+ else
+ nSizeTwips = (USHORT) ( nNewSize / pViewData->GetPPTX() );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+// SCTAB nTab = pViewData->GetTabNo();
+
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOL+1];
+ SCCOL nRangeCnt = 0;
+ if ( rMark.IsColumnMarked( static_cast<SCCOL>(nPos) ) )
+ {
+ SCCOL nStart = 0;
+ while (nStart<=MAXCOL)
+ {
+ while (nStart<MAXCOL && !rMark.IsColumnMarked(nStart))
+ ++nStart;
+ if (rMark.IsColumnMarked(nStart))
+ {
+ SCCOL nEnd = nStart;
+ while (nEnd<MAXCOL && rMark.IsColumnMarked(nEnd))
+ ++nEnd;
+ if (!rMark.IsColumnMarked(nEnd))
+ --nEnd;
+ pRanges[static_cast<size_t>(2*nRangeCnt) ] = nStart;
+ pRanges[static_cast<size_t>(2*nRangeCnt+1)] = nEnd;
+ ++nRangeCnt;
+ nStart = nEnd+1;
+ }
+ else
+ nStart = MAXCOL+1;
+ }
+ }
+ else
+ {
+ pRanges[0] = nPos;
+ pRanges[1] = nPos;
+ nRangeCnt = 1;
+ }
+
+ pViewData->GetView()->SetWidthOrHeight( TRUE, nRangeCnt, pRanges, eMode, nSizeTwips );
+ delete[] pRanges;
+}
+
+void ScColBar::HideEntries( SCCOLROW nStart, SCCOLROW nEnd )
+{
+ SCCOLROW nRange[2];
+ nRange[0] = nStart;
+ nRange[1] = nEnd;
+ pViewData->GetView()->SetWidthOrHeight( TRUE, 1, nRange, SC_SIZE_DIRECT, 0 );
+}
+
+void ScColBar::SetMarking( BOOL bSet )
+{
+ pViewData->GetMarkData().SetMarking( bSet );
+ if (!bSet)
+ {
+ pViewData->GetView()->UpdateAutoFillMark();
+ }
+}
+
+void ScColBar::SelectWindow()
+{
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ pViewSh->SetActive(); // Appear und SetViewFrame
+ pViewSh->DrawDeselectAll();
+
+ ScSplitPos eActive = pViewData->GetActivePart();
+ if (eWhich==SC_SPLIT_LEFT)
+ {
+ if (eActive==SC_SPLIT_TOPRIGHT) eActive=SC_SPLIT_TOPLEFT;
+ if (eActive==SC_SPLIT_BOTTOMRIGHT) eActive=SC_SPLIT_BOTTOMLEFT;
+ }
+ else
+ {
+ if (eActive==SC_SPLIT_TOPLEFT) eActive=SC_SPLIT_TOPRIGHT;
+ if (eActive==SC_SPLIT_BOTTOMLEFT) eActive=SC_SPLIT_BOTTOMRIGHT;
+ }
+ pViewSh->ActivatePart( eActive );
+
+ pFuncSet->SetColumn( TRUE );
+ pFuncSet->SetWhich( eActive );
+
+ pViewSh->ActiveGrabFocus();
+}
+
+BOOL ScColBar::IsDisabled()
+{
+ ScModule* pScMod = SC_MOD();
+ return pScMod->IsFormulaMode() || pScMod->IsModalMode();
+}
+
+BOOL ScColBar::ResizeAllowed()
+{
+ return !pViewData->HasEditView( pViewData->GetActivePart() ) &&
+ !pViewData->GetDocShell()->IsReadOnly();
+}
+
+void ScColBar::DrawInvert( long nDragPosP )
+{
+ Rectangle aRect( nDragPosP,0, nDragPosP+HDR_SLIDERSIZE-1,GetOutputSizePixel().Width()-1 );
+ Update();
+ Invert(aRect);
+
+ pViewData->GetView()->InvertVertical(eWhich,nDragPosP);
+}
+
+String ScColBar::GetDragHelp( long nVal )
+{
+ long nTwips = (long) ( nVal / pViewData->GetPPTX() );
+ return lcl_MetricString( nTwips, ScGlobal::GetRscString(STR_TIP_WIDTH) );
+}
+
+BOOL ScColBar::IsLayoutRTL() // overloaded only for columns
+{
+ return pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+}
+
+//==================================================================
+
+ScRowBar::ScRowBar( Window* pParent, ScViewData* pData, ScVSplitPos eWhichPos,
+ ScHeaderFunctionSet* pFunc, ScHeaderSelectionEngine* pEng ) :
+ ScHeaderControl( pParent, pEng, MAXROW+1, HDR_VERTICAL ),
+ pViewData( pData ),
+ eWhich( eWhichPos ),
+ pFuncSet( pFunc ),
+ pSelEngine( pEng )
+{
+ Show();
+}
+
+ScRowBar::~ScRowBar()
+{
+}
+
+SCCOLROW ScRowBar::GetPos()
+{
+ return pViewData->GetPosY(eWhich);
+}
+
+USHORT ScRowBar::GetEntrySize( SCCOLROW nEntryNo )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCROW nLastRow = -1;
+ if (pDoc->RowHidden(nEntryNo, nTab, nLastRow))
+ return 0;
+ else
+ return (USHORT) ScViewData::ToPixel( pDoc->GetOriginalHeight( nEntryNo,
+ nTab ), pViewData->GetPPTY() );
+}
+
+String ScRowBar::GetEntryText( SCCOLROW nEntryNo )
+{
+ return String::CreateFromInt32( nEntryNo + 1 );
+}
+
+void ScRowBar::SetEntrySize( SCCOLROW nPos, USHORT nNewSize )
+{
+ USHORT nSizeTwips;
+ ScSizeMode eMode = SC_SIZE_DIRECT;
+ if (nNewSize>0 && nNewSize<10) nNewSize=10; // (Pixel)
+
+ if ( nNewSize == HDR_SIZE_OPTIMUM )
+ {
+ nSizeTwips = 0;
+ eMode = SC_SIZE_OPTIMAL;
+ }
+ else
+ nSizeTwips = (USHORT) ( nNewSize / pViewData->GetPPTY() );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+// SCTAB nTab = pViewData->GetTabNo();
+
+ SCCOLROW* pRanges = new SCCOLROW[MAXROW+1];
+ SCROW nRangeCnt = 0;
+ if ( rMark.IsRowMarked( nPos ) )
+ {
+ SCROW nStart = 0;
+ while (nStart<=MAXROW)
+ {
+ while (nStart<MAXROW && !rMark.IsRowMarked(nStart))
+ ++nStart;
+ if (rMark.IsRowMarked(nStart))
+ {
+ SCROW nEnd = nStart;
+ while (nEnd<MAXROW && rMark.IsRowMarked(nEnd))
+ ++nEnd;
+ if (!rMark.IsRowMarked(nEnd))
+ --nEnd;
+ pRanges[static_cast<size_t>(2*nRangeCnt) ] = nStart;
+ pRanges[static_cast<size_t>(2*nRangeCnt+1)] = nEnd;
+ ++nRangeCnt;
+ nStart = nEnd+1;
+ }
+ else
+ nStart = MAXROW+1;
+ }
+ }
+ else
+ {
+ pRanges[0] = nPos;
+ pRanges[1] = nPos;
+ nRangeCnt = 1;
+ }
+
+ pViewData->GetView()->SetWidthOrHeight( FALSE, nRangeCnt, pRanges, eMode, nSizeTwips );
+ delete[] pRanges;
+}
+
+void ScRowBar::HideEntries( SCCOLROW nStart, SCCOLROW nEnd )
+{
+ SCCOLROW nRange[2];
+ nRange[0] = nStart;
+ nRange[1] = nEnd;
+ pViewData->GetView()->SetWidthOrHeight( FALSE, 1, nRange, SC_SIZE_DIRECT, 0 );
+}
+
+void ScRowBar::SetMarking( BOOL bSet )
+{
+ pViewData->GetMarkData().SetMarking( bSet );
+ if (!bSet)
+ {
+ pViewData->GetView()->UpdateAutoFillMark();
+ }
+}
+
+void ScRowBar::SelectWindow()
+{
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ pViewSh->SetActive(); // Appear und SetViewFrame
+ pViewSh->DrawDeselectAll();
+
+ ScSplitPos eActive = pViewData->GetActivePart();
+ if (eWhich==SC_SPLIT_TOP)
+ {
+ if (eActive==SC_SPLIT_BOTTOMLEFT) eActive=SC_SPLIT_TOPLEFT;
+ if (eActive==SC_SPLIT_BOTTOMRIGHT) eActive=SC_SPLIT_TOPRIGHT;
+ }
+ else
+ {
+ if (eActive==SC_SPLIT_TOPLEFT) eActive=SC_SPLIT_BOTTOMLEFT;
+ if (eActive==SC_SPLIT_TOPRIGHT) eActive=SC_SPLIT_BOTTOMRIGHT;
+ }
+ pViewSh->ActivatePart( eActive );
+
+ pFuncSet->SetColumn( FALSE );
+ pFuncSet->SetWhich( eActive );
+
+ pViewSh->ActiveGrabFocus();
+}
+
+BOOL ScRowBar::IsDisabled()
+{
+ ScModule* pScMod = SC_MOD();
+ return pScMod->IsFormulaMode() || pScMod->IsModalMode();
+}
+
+BOOL ScRowBar::ResizeAllowed()
+{
+ return !pViewData->HasEditView( pViewData->GetActivePart() ) &&
+ !pViewData->GetDocShell()->IsReadOnly();
+}
+
+void ScRowBar::DrawInvert( long nDragPosP )
+{
+ Rectangle aRect( 0,nDragPosP, GetOutputSizePixel().Width()-1,nDragPosP+HDR_SLIDERSIZE-1 );
+ Update();
+ Invert(aRect);
+
+ pViewData->GetView()->InvertHorizontal(eWhich,nDragPosP);
+}
+
+String ScRowBar::GetDragHelp( long nVal )
+{
+ long nTwips = (long) ( nVal / pViewData->GetPPTY() );
+ return lcl_MetricString( nTwips, ScGlobal::GetRscString(STR_TIP_HEIGHT) );
+}
+
+// GetHiddenCount ist nur fuer Zeilen ueberladen
+
+SCROW ScRowBar::GetHiddenCount( SCROW nEntryNo )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ return pDoc->GetHiddenRowCount( nEntryNo, nTab );
+}
+
+BOOL ScRowBar::IsMirrored() // overloaded only for rows
+{
+ return pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+}
+
+
diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
new file mode 100644
index 000000000000..f2a277b987df
--- /dev/null
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -0,0 +1,512 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include "dbfunc.hxx"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "sc.hrc"
+#include "undodat.hxx"
+#include "dbcolect.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "dbdocfun.hxx"
+#include "editable.hxx"
+
+//==================================================================
+
+ScDBFunc::ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
+ ScViewFunc( pParent, rDocSh, pViewShell )
+{
+}
+
+//UNUSED2008-05 ScDBFunc::ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell ) :
+//UNUSED2008-05 ScViewFunc( pParent, rDBFunc, pViewShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScDBFunc::~ScDBFunc()
+{
+}
+
+//
+// Hilfsfunktionen
+//
+
+void ScDBFunc::GotoDBArea( const String& rDBName )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBCollection* pDBCol = pDoc->GetDBCollection();
+
+ USHORT nFoundAt = 0;
+ if ( pDBCol->SearchName( rDBName, nFoundAt ) )
+ {
+ ScDBData* pData = (*pDBCol)[nFoundAt];
+ DBG_ASSERT( pData, "GotoDBArea: Datenbankbereich nicht gefunden!" );
+
+ if ( pData )
+ {
+ SCTAB nTab = 0;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+
+ pData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ SetTabNo( nTab );
+
+ MoveCursorAbs( nStartCol, nStartRow, ScFollowMode( SC_FOLLOW_JUMP ),
+ FALSE, FALSE ); // bShift,bControl
+ DoneBlockMode();
+ InitBlockMode( nStartCol, nStartRow, nTab );
+ MarkCursor( nEndCol, nEndRow, nTab );
+ SelectionChanged();
+ }
+ }
+}
+
+// aktuellen Datenbereich fuer Sortieren / Filtern suchen
+
+ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, ScGetDBSelection eSel )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDBData* pData = NULL;
+ ScRange aRange;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
+ if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
+ {
+ bool bShrinkColumnsOnly = false;
+ if (eSel == SC_DBSEL_ROW_DOWN)
+ {
+ // Don't alter row range, additional rows may have been selected on
+ // purpose to append data, or to have a fake header row.
+ bShrinkColumnsOnly = true;
+ // Select further rows only if only one row or a portion thereof is
+ // selected.
+ if (aRange.aStart.Row() != aRange.aEnd.Row())
+ {
+ // If an area is selected shrink that to the actual used
+ // columns, don't draw filter buttons for empty columns.
+ eSel = SC_DBSEL_SHRINK_TO_USED_DATA;
+ }
+ else if (aRange.aStart.Col() == aRange.aEnd.Col())
+ {
+ // One cell only, if it is not marked obtain entire used data
+ // area.
+ const ScMarkData& rMarkData = GetViewData()->GetMarkData();
+ if (!(rMarkData.IsMarked() || rMarkData.IsMultiMarked()))
+ eSel = SC_DBSEL_KEEP;
+ }
+ }
+ switch (eSel)
+ {
+ case SC_DBSEL_SHRINK_TO_SHEET_DATA:
+ {
+ // Shrink the selection to sheet data area.
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
+ SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea( aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
+ {
+ aRange.aStart.SetCol(nCol1);
+ aRange.aEnd.SetCol(nCol2);
+ aRange.aStart.SetRow(nRow1);
+ aRange.aEnd.SetRow(nRow2);
+ }
+ }
+ break;
+ case SC_DBSEL_SHRINK_TO_USED_DATA:
+ case SC_DBSEL_ROW_DOWN:
+ {
+ // Shrink the selection to actual used area.
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
+ SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
+ bool bShrunk;
+ pDoc->ShrinkToUsedDataArea( bShrunk, aRange.aStart.Tab(),
+ nCol1, nRow1, nCol2, nRow2, bShrinkColumnsOnly);
+ if (bShrunk)
+ {
+ aRange.aStart.SetCol(nCol1);
+ aRange.aEnd.SetCol(nCol2);
+ aRange.aStart.SetRow(nRow1);
+ aRange.aEnd.SetRow(nRow2);
+ }
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ pData = pDocSh->GetDBData( aRange, eMode, eSel );
+ }
+ else if ( eMode != SC_DB_OLD )
+ pData = pDocSh->GetDBData(
+ ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() ),
+ eMode, SC_DBSEL_KEEP );
+
+ if ( pData && bMark )
+ {
+ ScRange aFound;
+ pData->GetArea(aFound);
+ MarkRange( aFound, FALSE );
+ }
+ return pData;
+}
+
+// Datenbankbereiche aendern (Dialog)
+
+void ScDBFunc::NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList )
+{
+
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocShell );
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDBCollection* pOldColl = pDoc->GetDBCollection();
+ ScDBCollection* pUndoColl = NULL;
+ ScDBCollection* pRedoColl = NULL;
+ const BOOL bRecord (pDoc->IsUndoEnabled());
+
+ long nDelCount = rDelAreaList.Count();
+ for (long nDelPos=0; nDelPos<nDelCount; nDelPos++)
+ {
+ ScRange* pEntry = (ScRange*) rDelAreaList.GetObject(nDelPos);
+
+ if ( pEntry )
+ {
+ ScAddress& rStart = pEntry->aStart;
+ ScAddress& rEnd = pEntry->aEnd;
+ pDocShell->DBAreaDeleted( rStart.Tab(),
+ rStart.Col(), rStart.Row(),
+ rEnd.Col(), rEnd.Row() );
+
+ // Targets am SBA abmelden nicht mehr noetig
+ }
+ }
+
+ if (bRecord)
+ pUndoColl = new ScDBCollection( *pOldColl );
+
+ // neue Targets am SBA anmelden nicht mehr noetig
+
+ pDoc->CompileDBFormula( TRUE ); // CreateFormulaString
+ pDoc->SetDBCollection( new ScDBCollection( rNewColl ) );
+ pDoc->CompileDBFormula( FALSE ); // CompileFormulaString
+ pOldColl = NULL;
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+
+ if (bRecord)
+ {
+ pRedoColl = new ScDBCollection( rNewColl );
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoDBData( pDocShell, pUndoColl, pRedoColl ) );
+ }
+}
+
+//
+// wirkliche Funktionen
+//
+
+// Sortieren
+
+void ScDBFunc::UISort( const ScSortParam& rSortParam, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
+ rSortParam.nCol2, rSortParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "Sort: keine DBData" );
+ return;
+ }
+
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ if (aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly)
+ {
+ // Subtotals wiederholen, mit neuer Sortierung
+
+ DoSubTotals( aSubTotalParam, bRecord, &rSortParam );
+ }
+ else
+ {
+ Sort( rSortParam, bRecord ); // nur sortieren
+ }
+}
+
+void ScDBFunc::Sort( const ScSortParam& rSortParam, BOOL bRecord, BOOL bPaint )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDBDocFunc aDBDocFunc( *pDocSh );
+ BOOL bSuccess = aDBDocFunc.Sort( nTab, rSortParam, bRecord, bPaint, FALSE );
+ if ( bSuccess && !rSortParam.bInplace )
+ {
+ // Ziel markieren
+ ScRange aDestRange( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab,
+ rSortParam.nDestCol + rSortParam.nCol2 - rSortParam.nCol1,
+ rSortParam.nDestRow + rSortParam.nRow2 - rSortParam.nRow1,
+ rSortParam.nDestTab );
+ MarkRange( aDestRange );
+ }
+}
+
+// Filtern
+
+void ScDBFunc::Query( const ScQueryParam& rQueryParam, const ScRange* pAdvSource, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDBDocFunc aDBDocFunc( *pDocSh );
+ BOOL bSuccess = aDBDocFunc.Query( nTab, rQueryParam, pAdvSource, bRecord, FALSE );
+
+ if (bSuccess)
+ {
+ BOOL bCopy = !rQueryParam.bInplace;
+ if (bCopy)
+ {
+ // Zielbereich markieren (DB-Bereich wurde ggf. angelegt)
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDBData* pDestData = pDoc->GetDBAtCursor(
+ rQueryParam.nDestCol, rQueryParam.nDestRow,
+ rQueryParam.nDestTab, TRUE );
+ if (pDestData)
+ {
+ ScRange aDestRange;
+ pDestData->GetArea(aDestRange);
+ MarkRange( aDestRange );
+ }
+ }
+
+ if (!bCopy)
+ {
+ UpdateScrollBars();
+ SelectionChanged(); // for attribute states (filtered rows are ignored)
+ }
+
+ GetViewData()->GetBindings().Invalidate( SID_UNFILTER );
+ }
+}
+
+// Autofilter-Knoepfe ein-/ausblenden
+
+void ScDBFunc::ToggleAutoFilter()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScQueryParam aParam;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBData* pDBData = GetDBData( FALSE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN );
+
+ pDBData->SetByRow( TRUE ); //! Undo, vorher abfragen ??
+ pDBData->GetQueryParam( aParam );
+
+
+ SCCOL nCol;
+ SCROW nRow = aParam.nRow1;
+ SCTAB nTab = GetViewData()->GetTabNo();
+ INT16 nFlag;
+ BOOL bHasAuto = TRUE;
+ BOOL bHeader = pDBData->HasHeader();
+ BOOL bPaint = FALSE;
+
+ //! stattdessen aus DB-Bereich abfragen?
+
+ for (nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAuto; nCol++)
+ {
+ nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
+
+ if ( (nFlag & SC_MF_AUTO) == 0 )
+ bHasAuto = FALSE;
+ }
+
+ if (bHasAuto) // aufheben
+ {
+ // Filterknoepfe ausblenden
+
+ for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
+ {
+ nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
+ }
+
+ // use a list action for the AutoFilter buttons (ScUndoAutoFilter) and the filter operation
+
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_QUERY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), FALSE ) );
+
+ pDBData->SetAutoFilter(FALSE);
+
+ // Filter aufheben (incl. Paint / Undo)
+
+ SCSIZE nEC = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aParam.GetEntry(i).bDoQuery = FALSE;
+ aParam.bDuplicate = TRUE;
+ Query( aParam, NULL, TRUE );
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ bPaint = TRUE;
+ }
+ else // Filterknoepfe einblenden
+ {
+ if ( !pDoc->IsBlockEmpty( nTab,
+ aParam.nCol1, aParam.nRow1,
+ aParam.nCol2, aParam.nRow2 ) )
+ {
+ if (!bHeader)
+ {
+ if ( MessBox( GetViewData()->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), // "StarCalc"
+ ScGlobal::GetRscString( STR_MSSG_MAKEAUTOFILTER_0 ) // Koepfe aus erster Zeile?
+ ).Execute() == RET_YES )
+ {
+ pDBData->SetHeader( TRUE ); //! Undo ??
+ bHeader = TRUE;
+ }
+ }
+
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), TRUE ) );
+
+ pDBData->SetAutoFilter(TRUE);
+
+ for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
+ {
+ nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag | SC_MF_AUTO ) );
+ }
+ pDocSh->PostPaint( aParam.nCol1, nRow, nTab, aParam.nCol2, nRow, nTab,
+ PAINT_GRID );
+ bPaint = TRUE;
+ }
+ else
+ {
+ ErrorBox aErrorBox( GetViewData()->GetDialogParent(), WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_ERR_AUTOFILTER ) );
+ aErrorBox.Execute();
+ }
+ }
+
+ if ( bPaint )
+ {
+ aModificator.SetDocumentModified();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_AUTO_FILTER );
+ rBindings.Invalidate( SID_AUTOFILTER_HIDE );
+ }
+}
+
+// nur ausblenden, keine Daten veraendern
+
+void ScDBFunc::HideAutoFilter()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ ScQueryParam aParam;
+ ScDBData* pDBData = GetDBData( FALSE );
+
+ SCTAB nTab;
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ pDBData->GetArea(nTab, nCol1, nRow1, nCol2, nRow2);
+
+ for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
+ {
+ INT16 nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow1, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ pDoc->ApplyAttr( nCol, nRow1, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
+ }
+
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), FALSE ) );
+
+ pDBData->SetAutoFilter(FALSE);
+
+ pDocSh->PostPaint( nCol1,nRow1,nTab, nCol2,nRow1,nTab, PAINT_GRID );
+ aModificator.SetDocumentModified();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_AUTO_FILTER );
+ rBindings.Invalidate( SID_AUTOFILTER_HIDE );
+}
+
+// Re-Import
+
+BOOL ScDBFunc::ImportData( const ScImportParam& rParam, BOOL bRecord )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScEditableTester aTester( pDoc, GetViewData()->GetTabNo(), rParam.nCol1,rParam.nRow1,
+ rParam.nCol2,rParam.nRow2 );
+ if ( !aTester.IsEditable() )
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ ScDBDocFunc aDBDocFunc( *GetViewData()->GetDocShell() );
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
+ return aDBDocFunc.DoImport( GetViewData()->GetTabNo(), rParam, xResultSet, NULL, bRecord );
+}
+
+
+
diff --git a/sc/source/ui/view/dbfunc2.cxx b/sc/source/ui/view/dbfunc2.cxx
new file mode 100644
index 000000000000..54ddde9b7710
--- /dev/null
+++ b/sc/source/ui/view/dbfunc2.cxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+
+#include "dbfunc.hxx"
+#include "docsh.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+//==================================================================
+
+class ScDrawLayer;
+class ScChartCollection;
+
+void ScDBFunc::UpdateCharts( BOOL bAllCharts )
+{
+ USHORT nFound = 0;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ if ( pDoc->GetDrawLayer() )
+ nFound = DoUpdateCharts( ScAddress( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo()),
+ pDoc,
+ bAllCharts );
+
+ if ( !nFound && !bAllCharts )
+ ErrorMessage(STR_NOCHARTATCURSOR);
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
new file mode 100755
index 000000000000..dbdeae1ae0b1
--- /dev/null
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -0,0 +1,2375 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "dbfunc.hxx"
+#include "scitems.hxx"
+#include <sfx2/bindings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/waitobj.hxx>
+#include <svl/zforlist.hxx>
+#include <sfx2/app.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/MemberResultFlags.hpp>
+#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "undotab.hxx"
+#include "undodat.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "docsh.hxx"
+#include "olinetab.hxx"
+#include "consoli.hxx"
+#include "olinefun.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dbdocfun.hxx"
+#include "dpoutput.hxx"
+#include "dptabsrc.hxx"
+#include "editable.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "unonames.hxx"
+#include "cell.hxx"
+#include "userlist.hxx"
+
+#include <hash_set>
+#include <hash_map>
+#include <memory>
+#include <list>
+#include <vector>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::sheet::XDimensionsSupplier;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::rtl::OUStringBuffer;
+using ::std::auto_ptr;
+using ::std::list;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//==================================================================
+
+//
+// Outliner
+//
+
+// Outline-Gruppierung erzeugen
+
+void ScDBFunc::MakeOutline( BOOL bColumns, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.MakeOutline( aRange, bColumns, bRecord, FALSE );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// Outline-Gruppierung loeschen
+
+void ScDBFunc::RemoveOutline( BOOL bColumns, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.RemoveOutline( aRange, bColumns, bRecord, FALSE );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// Menue-Status: Outlines loeschen
+
+void ScDBFunc::TestRemoveOutline( BOOL& rCol, BOOL& rRow )
+{
+ BOOL bColFound = FALSE;
+ BOOL bRowFound = FALSE;
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nStartTab, nEndTab;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ SCTAB nTab = nStartTab;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ ScOutlineArray* pArray;
+ ScOutlineEntry* pEntry;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ BOOL bColMarked = ( nStartRow == 0 && nEndRow == MAXROW );
+ BOOL bRowMarked = ( nStartCol == 0 && nEndCol == MAXCOL );
+
+ // Spalten
+
+ if ( !bRowMarked || bColMarked ) // nicht wenn ganze Zeilen markiert
+ {
+ pArray = pTable->GetColArray();
+ ScSubOutlineIterator aColIter( pArray );
+ while ((pEntry=aColIter.GetNext()) != NULL && !bColFound)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( nStartCol<=static_cast<SCCOL>(nEnd) && nEndCol>=static_cast<SCCOL>(nStart) )
+ bColFound = TRUE;
+ }
+ }
+
+ // Zeilen
+
+ if ( !bColMarked || bRowMarked ) // nicht wenn ganze Spalten markiert
+ {
+ pArray = pTable->GetRowArray();
+ ScSubOutlineIterator aRowIter( pArray );
+ while ((pEntry=aRowIter.GetNext()) != NULL && !bRowFound)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( nStartRow<=nEnd && nEndRow>=nStart )
+ bRowFound = TRUE;
+ }
+ }
+ }
+ }
+
+ rCol = bColFound;
+ rRow = bRowFound;
+}
+
+void ScDBFunc::RemoveAllOutlines( BOOL bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ BOOL bOk = aFunc.RemoveAllOutlines( nTab, bRecord, FALSE );
+ ShowCursor();
+
+ if (bOk)
+ UpdateScrollBars();
+}
+
+// Auto-Outlines
+
+void ScDBFunc::AutoOutline( BOOL bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab ); // ganze Tabelle, wenn nichts markiert
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ rMark.MarkToMulti();
+ rMark.GetMultiMarkArea( aRange );
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.AutoOutline( aRange, bRecord, FALSE );
+}
+
+// Outline-Ebene auswaehlen
+
+void ScDBFunc::SelectLevel( BOOL bColumns, USHORT nLevel, BOOL bRecord, BOOL bPaint )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ BOOL bOk = aFunc.SelectLevel( nTab, bColumns, nLevel, bRecord, bPaint, FALSE );
+ ShowCursor();
+
+ if (bOk)
+ UpdateScrollBars();
+}
+
+// einzelne Outline-Gruppe einblenden
+
+void ScDBFunc::ShowOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry, BOOL bRecord, BOOL bPaint )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ BOOL bOk = aFunc.ShowOutline( nTab, bColumns, nLevel, nEntry, bRecord, bPaint, FALSE );
+ ShowCursor();
+
+ if ( bOk && bPaint )
+ UpdateScrollBars();
+}
+
+// einzelne Outline-Gruppe ausblenden
+
+void ScDBFunc::HideOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry, BOOL bRecord, BOOL bPaint )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ BOOL bOk = aFunc.HideOutline( nTab, bColumns, nLevel, nEntry, bRecord, bPaint, FALSE );
+ ShowCursor();
+
+ if ( bOk && bPaint )
+ UpdateScrollBars();
+}
+
+// Menue-Status: markierten Bereich ein-/ausblenden
+
+BOOL ScDBFunc::OutlinePossible(BOOL bHide)
+{
+ BOOL bEnable = FALSE;
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ ScOutlineArray* pArray;
+ ScOutlineEntry* pEntry;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+
+ // Spalten
+
+ pArray = pTable->GetColArray();
+ ScSubOutlineIterator aColIter( pArray );
+ while ((pEntry=aColIter.GetNext()) != NULL && !bEnable)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( bHide )
+ {
+ if ( nStartCol<=static_cast<SCCOL>(nEnd) && nEndCol>=static_cast<SCCOL>(nStart) )
+ if (!pEntry->IsHidden())
+ bEnable = TRUE;
+ }
+ else
+ {
+ if ( nStart>=nStartCol && nEnd<=nEndCol )
+ if (pEntry->IsHidden())
+ bEnable = TRUE;
+ }
+ }
+
+ // Zeilen
+
+ pArray = pTable->GetRowArray();
+ ScSubOutlineIterator aRowIter( pArray );
+ while ((pEntry=aRowIter.GetNext()) != NULL)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( bHide )
+ {
+ if ( nStartRow<=nEnd && nEndRow>=nStart )
+ if (!pEntry->IsHidden())
+ bEnable = TRUE;
+ }
+ else
+ {
+ if ( nStart>=nStartRow && nEnd<=nEndRow )
+ if (pEntry->IsHidden())
+ bEnable = TRUE;
+ }
+ }
+ }
+ }
+
+ return bEnable;
+}
+
+// markierten Bereich einblenden
+
+void ScDBFunc::ShowMarkedOutlines( BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ HideCursor();
+ BOOL bDone = aFunc.ShowMarkedOutlines( aRange, bRecord, FALSE );
+ ShowCursor();
+ if (bDone)
+ UpdateScrollBars();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// markierten Bereich ausblenden
+
+void ScDBFunc::HideMarkedOutlines( BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ HideCursor();
+ BOOL bDone = aFunc.HideMarkedOutlines( aRange, bRecord, FALSE );
+ ShowCursor();
+ if (bDone)
+ UpdateScrollBars();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// --------------------------------------------------------------------------
+
+//
+// Teilergebnisse
+//
+
+void ScDBFunc::DoSubTotals( const ScSubTotalParam& rParam, BOOL bRecord,
+ const ScSortParam* pForceNewSort )
+{
+ BOOL bDo = !rParam.bRemoveOnly; // FALSE = nur loeschen
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
+ rParam.nCol2, rParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "SubTotals: keine DBData" );
+ return;
+ }
+
+ ScEditableTester aTester( pDoc, nTab, 0,rParam.nRow1+1, MAXCOL,MAXROW );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ if (pDoc->HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab,
+ rParam.nCol2, rParam.nRow2, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ ErrorMessage(STR_MSSG_INSERTCELLS_0); // nicht in zusammengefasste einfuegen
+ return;
+ }
+
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ BOOL bOk = TRUE;
+ BOOL bDelete = FALSE;
+ if (rParam.bReplace)
+ if (pDoc->TestRemoveSubTotals( nTab, rParam ))
+ {
+ bDelete = TRUE;
+ bOk = ( MessBox( GetViewData()->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ // "StarCalc" "Daten loeschen?"
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_1 ) ).Execute()
+ == RET_YES );
+ }
+
+ if (bOk)
+ {
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScSubTotalParam aNewParam( rParam ); // Bereichsende wird veraendert
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ ScRangeName* pUndoRange = NULL;
+ ScDBCollection* pUndoDB = NULL;
+ SCTAB nTabCount = 0; // fuer Referenz-Undo
+
+ if (bRecord) // alte Daten sichern
+ {
+ BOOL bOldFilter = bDo && rParam.bDoSort;
+
+ nTabCount = pDoc->GetTableCount();
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ SCCOLROW nOutStartCol; // Zeilen/Spaltenstatus
+ SCCOLROW nOutStartRow;
+ SCCOLROW nOutEndCol;
+ SCCOLROW nOutEndRow;
+ pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
+ pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, bOldFilter );
+
+ // Datenbereich sichern - incl. Filter-Ergebnis
+ pDoc->CopyToDocument( 0,rParam.nRow1+1,nTab, MAXCOL,rParam.nRow2,nTab,
+ IDF_ALL, FALSE, pUndoDoc );
+
+ // alle Formeln wegen Referenzen
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
+ IDF_FORMULA, FALSE, pUndoDoc );
+
+ // DB- und andere Bereiche
+ ScRangeName* pDocRange = pDoc->GetRangeName();
+ if (pDocRange->GetCount())
+ pUndoRange = new ScRangeName( *pDocRange );
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+ }
+
+// pDoc->SetOutlineTable( nTab, NULL );
+ ScOutlineTable* pOut = pDoc->GetOutlineTable( nTab );
+ if (pOut)
+ pOut->GetRowArray()->RemoveAll(); // nur Zeilen-Outlines loeschen
+
+ if (rParam.bReplace)
+ pDoc->RemoveSubTotals( nTab, aNewParam );
+ BOOL bSuccess = TRUE;
+ if (bDo)
+ {
+ // Sortieren
+ if ( rParam.bDoSort || pForceNewSort )
+ {
+ pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+
+ // Teilergebnis-Felder vor die Sortierung setzen
+ // (doppelte werden weggelassen, kann darum auch wieder aufgerufen werden)
+
+ ScSortParam aOldSort;
+ pDBData->GetSortParam( aOldSort );
+ ScSortParam aSortParam( aNewParam, pForceNewSort ? *pForceNewSort : aOldSort );
+ Sort( aSortParam, FALSE, FALSE );
+ }
+
+ bSuccess = pDoc->DoSubTotals( nTab, aNewParam );
+ }
+ ScRange aDirtyRange( aNewParam.nCol1, aNewParam.nRow1, nTab,
+ aNewParam.nCol2, aNewParam.nRow2, nTab );
+ pDoc->SetDirty( aDirtyRange );
+
+ if (bRecord)
+ {
+// ScDBData* pUndoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSubTotals( pDocSh, nTab,
+ rParam, aNewParam.nRow2,
+ pUndoDoc, pUndoTab, // pUndoDBData,
+ pUndoRange, pUndoDB ) );
+ }
+
+ if (!bSuccess)
+ {
+ // "Kann keine Zeilen einfuegen"
+ ErrorMessage(STR_MSSG_DOSUBTOTALS_2);
+ }
+
+ // merken
+ pDBData->SetSubTotalParam( aNewParam );
+ pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+ pDoc->CompileDBFormula();
+
+ DoneBlockMode();
+ InitOwnBlockMode();
+ rMark.SetMarkArea( ScRange( aNewParam.nCol1,aNewParam.nRow1,nTab,
+ aNewParam.nCol2,aNewParam.nRow2,nTab ) );
+ MarkDataChanged();
+
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+
+ aModificator.SetDocumentModified();
+
+ SelectionChanged();
+ }
+}
+
+//
+// Consolidate
+//
+
+void ScDBFunc::Consolidate( const ScConsolidateParam& rParam, BOOL bRecord )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ pDocShell->DoConsolidate( rParam, bRecord );
+ SetTabNo( rParam.nTab, TRUE );
+}
+
+//
+// Pivot
+//
+
+String lcl_MakePivotTabName( const String& rPrefix, SCTAB nNumber )
+{
+ String aName = rPrefix;
+ aName += String::CreateFromInt32( nNumber );
+ return aName;
+}
+
+bool ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable,
+ const ScDPObject& rSource, BOOL bApi )
+{
+ // #70096# error message if no fields are set
+ // this must be removed when drag&drop of fields from a toolbox is available
+
+ if ( rData.IsEmpty() && !bApi )
+ {
+ ErrorMessage(STR_PIVOT_NODATA);
+ return false;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ ScRange aDestRange = rDest;
+ if ( bNewTable )
+ {
+ SCTAB nSrcTab = GetViewData()->GetTabNo();
+
+ String aName( ScGlobal::GetRscString(STR_PIVOT_TABLE) );
+ String aStr;
+
+ pDoc->GetName( nSrcTab, aStr );
+ aName += '_';
+ aName += aStr;
+ aName += '_';
+
+ SCTAB nNewTab = nSrcTab+1;
+
+ SCTAB i=1;
+ while ( !pDoc->InsertTab( nNewTab, lcl_MakePivotTabName( aName, i ) ) && i <= MAXTAB )
+ i++;
+
+ BOOL bAppend = ( nNewTab+1 == pDoc->GetTableCount() );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDocSh, nNewTab, bAppend, lcl_MakePivotTabName( aName, i ) ));
+ }
+
+ GetViewData()->InsertTab( nNewTab );
+ SetTabNo( nNewTab, TRUE );
+
+ aDestRange = ScRange( 0, 0, nNewTab );
+ }
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(
+ aDestRange.aStart.Col(), aDestRange.aStart.Row(), aDestRange.aStart.Tab() );
+
+ ScDPObject aObj( rSource );
+ aObj.SetOutRange( aDestRange );
+ if ( pDPObj && !rData.GetExistingDimensionData() )
+ {
+ // copy dimension data from old object - lost in the dialog
+ //! change the dialog to keep the dimension data
+
+ ScDPSaveData aNewData( rData );
+ const ScDPSaveData* pOldData = pDPObj->GetSaveData();
+ if ( pOldData )
+ {
+ const ScDPDimensionSaveData* pDimSave = pOldData->GetExistingDimensionData();
+ aNewData.SetDimensionData( pDimSave );
+ }
+ aObj.SetSaveData( aNewData );
+ }
+ else
+ aObj.SetSaveData( rData );
+
+ BOOL bAllowMove = ( pDPObj != NULL ); // allow re-positioning when editing existing table
+
+ ScDBDocFunc aFunc( *pDocSh );
+ bool bSuccess = aFunc.DataPilotUpdate( pDPObj, &aObj, TRUE, FALSE, bAllowMove );
+
+ CursorPosChanged(); // shells may be switched
+
+ if ( bNewTable )
+ {
+ pDocSh->PostPaintExtras();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+
+ return bSuccess;
+}
+
+void ScDBFunc::DeletePivotTable()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScDBDocFunc aFunc( *pDocSh );
+ aFunc.DataPilotUpdate( pDPObj, NULL, TRUE, FALSE );
+ CursorPosChanged(); // shells may be switched
+ }
+ else
+ ErrorMessage(STR_PIVOT_NOTFOUND);
+}
+ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, BOOL bRecord, BOOL bApi )
+{
+ if( !pDPObj )
+ return STR_PIVOT_NOTFOUND;
+
+ if ( pDocSh && !pDoc )
+ pDoc = pDocSh->GetDocument();
+
+ if( !pDoc )
+ return static_cast<ULONG>(-1);
+
+ if( !pDocSh && ( pDocSh = PTR_CAST( ScDocShell, pDoc->GetDocumentShell() ) ) == NULL )
+ return static_cast<ULONG>(-1);
+
+ if( ULONG nErrId = pDPObj->RefreshCache() )
+ return nErrId;
+ else if ( nErrId == 0 )
+ {
+ //Refresh all dpobjects
+ ScDPCollection* pDPCollection = pDoc->GetDPCollection();
+ USHORT nCount = pDPCollection->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ if ( (*pDPCollection)[i]->GetCacheId() == pDPObj->GetCacheId() )
+ {
+ ScDBDocFunc aFunc( * pDocSh );
+ if ( !aFunc.DataPilotUpdate( (*pDPCollection)[i], (*pDPCollection)[i], bRecord, bApi ) )
+ break;
+ }
+ }
+
+ return nErrId;
+ }
+
+ return 0U;
+}
+
+ULONG ScDBFunc::RecalcPivotTable()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ // old pivot not used any more
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ // Wang Xu Ming -- 2009-6-17
+ // DataPilot Migration
+ //ScDBDocFunc aFunc( *pDocSh );
+ //aFunc.DataPilotUpdate( pDPObj, pDPObj, TRUE, FALSE );
+ //CursorPosChanged(); // shells may be switched
+ ULONG nErrId = RefreshDPObject( pDPObj, pDoc, pDocSh, TRUE, FALSE );//pDPObj->RefreshCache();
+ if ( nErrId == 0 )
+ {
+ // There is no undo for the refresh of the cache table, but the undo history for cell changes
+ // remains valid and should be preserved, so the history isn't cleared here.
+ //GetViewData()->GetDocShell()->GetUndoManager()->Clear();
+ }
+ else if (nErrId <= USHRT_MAX)
+ ErrorMessage(static_cast<USHORT>(nErrId));
+ return nErrId;
+ // End Comments
+ }
+ else
+ ErrorMessage(STR_PIVOT_NOTFOUND);
+ return STR_PIVOT_NOTFOUND;
+}
+
+void ScDBFunc::GetSelectedMemberList( ScStrCollection& rEntries, long& rDimension )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( !pDPObj )
+ return;
+
+ long nStartDimension = -1;
+ long nStartHierarchy = -1;
+ long nStartLevel = -1;
+
+ ScRangeListRef xRanges;
+ GetViewData()->GetMultiArea( xRanges ); // incl. cursor if nothing is selected
+ ULONG nRangeCount = xRanges->Count();
+ BOOL bContinue = TRUE;
+
+ for (ULONG nRangePos=0; nRangePos<nRangeCount && bContinue; nRangePos++)
+ {
+ ScRange aRange = *xRanges->GetObject(nRangePos);
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ SCTAB nTab = aRange.aStart.Tab();
+
+ for (SCROW nRow=nStartRow; nRow<=nEndRow && bContinue; nRow++)
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol && bContinue; nCol++)
+ {
+ sheet::DataPilotTableHeaderData aData;
+ pDPObj->GetHeaderPositionData(ScAddress(nCol, nRow, nTab), aData);
+ if ( aData.Dimension < 0 )
+ bContinue = FALSE; // not part of any dimension
+ else
+ {
+ if ( nStartDimension < 0 ) // first member?
+ {
+ nStartDimension = aData.Dimension;
+ nStartHierarchy = aData.Hierarchy;
+ nStartLevel = aData.Level;
+ }
+ if ( aData.Dimension != nStartDimension ||
+ aData.Hierarchy != nStartHierarchy ||
+ aData.Level != nStartLevel )
+ {
+ bContinue = FALSE; // cannot mix dimensions
+ }
+ }
+ if ( bContinue )
+ {
+ // accept any part of a member description, also subtotals,
+ // but don't stop if empty parts are contained
+ if ( aData.Flags & sheet::MemberResultFlags::HASMEMBER )
+ {
+ StrData* pNew = new StrData( aData.MemberName );
+ if ( !rEntries.Insert( pNew ) )
+ delete pNew;
+ }
+ }
+ }
+ }
+
+ rDimension = nStartDimension; // dimension from which the found members came
+ if (!bContinue)
+ rEntries.FreeAll(); // remove all if not valid
+}
+
+BOOL ScDBFunc::HasSelectionForDateGroup( ScDPNumGroupInfo& rOldInfo, sal_Int32& rParts )
+{
+ // determine if the date group dialog has to be shown for the current selection
+
+ BOOL bFound = FALSE;
+
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nCurX, nCurY, nTab );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+ String aBaseDimName( aDimName );
+
+ BOOL bInGroupDim = FALSE;
+ BOOL bFoundParts = FALSE;
+
+ ScDPDimensionSaveData* pDimData =
+ const_cast<ScDPDimensionSaveData*>( pDPObj->GetSaveData()->GetExistingDimensionData() );
+ if ( pDimData )
+ {
+ const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName );
+ const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( aDimName );
+ if ( pNumGroupDim )
+ {
+ // existing num group dimension
+
+ if ( pNumGroupDim->GetDatePart() != 0 )
+ {
+ // dimension has date info -> edit settings of this dimension
+ // (parts are collected below)
+
+ rOldInfo = pNumGroupDim->GetDateInfo();
+ bFound = TRUE;
+ }
+ else if ( pNumGroupDim->GetInfo().DateValues )
+ {
+ // Numerical grouping with DateValues flag is used for grouping
+ // of days with a "Number of days" value.
+
+ rOldInfo = pNumGroupDim->GetInfo();
+ rParts = com::sun::star::sheet::DataPilotFieldGroupBy::DAYS; // not found in CollectDateParts
+ bFoundParts = TRUE;
+ bFound = TRUE;
+ }
+ bInGroupDim = TRUE;
+ }
+ else if ( pGroupDim )
+ {
+ // existing additional group dimension
+
+ if ( pGroupDim->GetDatePart() != 0 )
+ {
+ // dimension has date info -> edit settings of this dimension
+ // (parts are collected below)
+
+ rOldInfo = pGroupDim->GetDateInfo();
+ aBaseDimName = pGroupDim->GetSourceDimName();
+ bFound = TRUE;
+ }
+ bInGroupDim = TRUE;
+ }
+ }
+ if ( bFound && !bFoundParts )
+ {
+ // collect date parts from all group dimensions
+ rParts = pDimData->CollectDateParts( aBaseDimName );
+ }
+ if ( !bFound && !bInGroupDim )
+ {
+ // create new date group dimensions if the selection is a single cell
+ // in a normal dimension with date content
+
+ ScRange aSelRange;
+ if ( (GetViewData()->GetSimpleArea( aSelRange ) == SC_MARK_SIMPLE) &&
+ aSelRange.aStart == aSelRange.aEnd )
+ {
+ SCCOL nSelCol = aSelRange.aStart.Col();
+ SCROW nSelRow = aSelRange.aStart.Row();
+ SCTAB nSelTab = aSelRange.aStart.Tab();
+ if ( pDoc->HasValueData( nSelCol, nSelRow, nSelTab ) )
+ {
+ ULONG nIndex = static_cast<const SfxUInt32Item*>(pDoc->GetAttr(
+ nSelCol, nSelRow, nSelTab, ATTR_VALUE_FORMAT))->GetValue();
+ short nType = pDoc->GetFormatTable()->GetType(nIndex);
+ if ( nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME || nType == NUMBERFORMAT_DATETIME )
+ {
+ bFound = TRUE;
+ // use currently selected value for automatic limits
+ if( rOldInfo.AutoStart )
+ rOldInfo.Start = pDoc->GetValue( aSelRange.aStart );
+ if( rOldInfo.AutoEnd )
+ rOldInfo.End = pDoc->GetValue( aSelRange.aStart );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bFound;
+}
+
+BOOL ScDBFunc::HasSelectionForNumGroup( ScDPNumGroupInfo& rOldInfo )
+{
+ // determine if the numeric group dialog has to be shown for the current selection
+
+ BOOL bFound = FALSE;
+
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nCurX, nCurY, nTab );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ BOOL bInGroupDim = FALSE;
+
+ ScDPDimensionSaveData* pDimData =
+ const_cast<ScDPDimensionSaveData*>( pDPObj->GetSaveData()->GetExistingDimensionData() );
+ if ( pDimData )
+ {
+ const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName );
+ if ( pNumGroupDim )
+ {
+ // existing num group dimension
+ // -> edit settings of this dimension
+
+ rOldInfo = pNumGroupDim->GetInfo();
+ bFound = TRUE;
+ }
+ else if ( pDimData->GetNamedGroupDim( aDimName ) )
+ bInGroupDim = TRUE; // in a group dimension
+ }
+ if ( !bFound && !bInGroupDim )
+ {
+ // create a new num group dimension if the selection is a single cell
+ // in a normal dimension with numeric content
+
+ ScRange aSelRange;
+ if ( (GetViewData()->GetSimpleArea( aSelRange ) == SC_MARK_SIMPLE) &&
+ aSelRange.aStart == aSelRange.aEnd )
+ {
+ if ( pDoc->HasValueData( aSelRange.aStart.Col(), aSelRange.aStart.Row(),
+ aSelRange.aStart.Tab() ) )
+ {
+ bFound = TRUE;
+ // use currently selected value for automatic limits
+ if( rOldInfo.AutoStart )
+ rOldInfo.Start = pDoc->GetValue( aSelRange.aStart );
+ if( rOldInfo.AutoEnd )
+ rOldInfo.End = pDoc->GetValue( aSelRange.aStart );
+ }
+ }
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScDBFunc::DateGroupDataPilot( const ScDPNumGroupInfo& rInfo, sal_Int32 nParts )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+
+ // find original base
+ String aBaseDimName = aDimName;
+ if( const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName ) )
+ aBaseDimName = pBaseGroupDim->GetSourceDimName();
+
+ // remove all existing parts (the grouping is built completely new)
+
+ /* Remove numeric group dimension (exists once at most). No need
+ to delete anything in save data (grouping was done inplace in
+ an existing base dimension). */
+ pDimData->RemoveNumGroupDimension( aBaseDimName );
+
+ /* Remove named group dimension(s). Collect deleted dimension
+ names which may be reused while recreating the groups.
+ Dimensions have to be removed from dimension save data and from
+ save data too. */
+ std::vector< String > aDeletedNames;
+ const ScDPSaveGroupDimension* pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName );
+ while ( pExistingGroup )
+ {
+ String aGroupDimName = pExistingGroup->GetGroupDimName();
+ pDimData->RemoveGroupDimension( aGroupDimName ); // pExistingGroup is deleted
+
+ // also remove SaveData settings for the dimension that no longer exists
+ aData.RemoveDimensionByName( aGroupDimName );
+
+ /* The name can be used for the new group dimensions, although
+ it is still in use with the DataPilotSource. */
+ aDeletedNames.push_back( aGroupDimName );
+
+ // see if there are more group dimensions
+ pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName );
+
+ if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
+ {
+ // still get the same group dimension?
+ DBG_ERROR("couldn't remove group dimension");
+ pExistingGroup = NULL; // avoid endless loop
+ }
+ }
+
+ if ( nParts )
+ {
+ // create date group dimensions
+
+ ScDPNumGroupInfo aEmpty;
+ bool bFirst = true;
+ sal_Int32 nMask = 1;
+ for (USHORT nBit=0; nBit<32; nBit++)
+ {
+ if ( nParts & nMask )
+ {
+ if ( bFirst )
+ {
+ // innermost part: create NumGroupDimension (replacing original values)
+ // Dimension name is left unchanged
+
+ if ( (nParts == sheet::DataPilotFieldGroupBy::DAYS) && (rInfo.Step >= 1.0) )
+ {
+ // only days, and a step value specified: use numerical grouping
+ // with DateValues flag, not date grouping
+
+ ScDPNumGroupInfo aNumInfo( rInfo );
+ aNumInfo.DateValues = sal_True;
+
+ ScDPSaveNumGroupDimension aNumGroupDim( aBaseDimName, aNumInfo );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+ else
+ {
+ ScDPSaveNumGroupDimension aNumGroupDim( aBaseDimName, rInfo, nMask );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+
+ bFirst = false;
+ }
+ else
+ {
+ // additional parts: create GroupDimension (shown as additional dimensions)
+ String aGroupDimName = pDimData->CreateDateGroupDimName( nMask, *pDPObj, true, &aDeletedNames );
+ ScDPSaveGroupDimension aGroupDim( aBaseDimName, aGroupDimName );
+ aGroupDim.SetDateInfo( rInfo, nMask );
+ pDimData->AddGroupDimension( aGroupDim );
+
+ // set orientation
+ ScDPSaveDimension* pSaveDimension = aData.GetDimensionByName( aGroupDimName );
+ if ( pSaveDimension->GetOrientation() == sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ ScDPSaveDimension* pOldDimension = aData.GetDimensionByName( aBaseDimName );
+ pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
+ long nPosition = 0; //! before (immediate) base
+ aData.SetPosition( pSaveDimension, nPosition );
+ }
+ }
+ }
+ nMask *= 2;
+ }
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+}
+
+void ScDBFunc::NumGroupDataPilot( const ScDPNumGroupInfo& rInfo )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+
+ ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( aDimName );
+ if ( pExisting )
+ {
+ // modify existing group dimension
+ pExisting->SetGroupInfo( rInfo );
+ }
+ else
+ {
+ // create new group dimension
+ ScDPSaveNumGroupDimension aNumGroupDim( aDimName, rInfo );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+}
+
+void ScDBFunc::GroupDataPilot()
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+
+ // find original base
+ String aBaseDimName( aDimName );
+ const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
+ if ( pBaseGroupDim )
+ {
+ // any entry's SourceDimName is the original base
+ aBaseDimName = pBaseGroupDim->GetSourceDimName();
+ }
+
+ // find existing group dimension
+ // (using the selected dim, can be intermediate group dim)
+ ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
+
+ // remove the selected items from their groups
+ // (empty groups are removed, too)
+ USHORT nEntryCount = aEntries.GetCount();
+ USHORT nEntry;
+ if ( pGroupDimension )
+ {
+ for (nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ if ( pBaseGroupDim )
+ {
+ // for each selected (intermediate) group, remove all its items
+ // (same logic as for adding, below)
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
+ if ( pBaseGroup )
+ pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
+ else
+ pGroupDimension->RemoveFromGroups( aEntryName );
+ }
+ else
+ pGroupDimension->RemoveFromGroups( aEntryName );
+ }
+ }
+
+ ScDPSaveGroupDimension* pNewGroupDim = NULL;
+ if ( !pGroupDimension )
+ {
+ // create a new group dimension
+ String aGroupDimName = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
+ pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, aGroupDimName );
+
+ pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
+
+ if ( pBaseGroupDim )
+ {
+ // If it's a higher-order group dimension, pre-allocate groups for all
+ // non-selected original groups, so the individual base members aren't
+ // used for automatic groups (this would make the original groups hard
+ // to find).
+ //! Also do this when removing groups?
+ //! Handle this case dynamically with automatic groups?
+
+ long nGroupCount = pBaseGroupDim->GetGroupCount();
+ for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
+ {
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
+
+ StrData aStrData( pBaseGroup->GetGroupName() );
+ USHORT nCollIndex;
+ if ( !aEntries.Search( &aStrData, nCollIndex ) ) //! ignore case?
+ {
+ // add an additional group for each item that is not in the selection
+ ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
+ aGroup.AddElementsFromGroup( *pBaseGroup );
+ pGroupDimension->AddGroupItem( aGroup );
+ }
+ }
+ }
+ }
+ String aGroupDimName = pGroupDimension->GetGroupDimName();
+
+ //! localized prefix string
+ String aGroupName = pGroupDimension->CreateGroupName( String::CreateFromAscii("Group") );
+ ScDPSaveGroupItem aGroup( aGroupName );
+ for (nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ if ( pBaseGroupDim )
+ {
+ // for each selected (intermediate) group, add all its items
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
+ if ( pBaseGroup )
+ aGroup.AddElementsFromGroup( *pBaseGroup );
+ else
+ aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
+ }
+ else
+ aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
+ }
+
+ pGroupDimension->AddGroupItem( aGroup );
+
+ if ( pNewGroupDim )
+ {
+ pDimData->AddGroupDimension( *pNewGroupDim );
+ delete pNewGroupDim; // AddGroupDimension copies the object
+ // don't access pGroupDimension after here
+ }
+ pGroupDimension = pNewGroupDim = NULL;
+
+ // set orientation
+ ScDPSaveDimension* pSaveDimension = aData.GetDimensionByName( aGroupDimName );
+ if ( pSaveDimension->GetOrientation() == sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ ScDPSaveDimension* pOldDimension = aData.GetDimensionByName( aDimName );
+ pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
+ long nPosition = 0; //! before (immediate) base
+ aData.SetPosition( pSaveDimension, nPosition );
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+}
+
+void ScDBFunc::UngroupDataPilot()
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+ //! test first if DimensionData exists?
+
+ BOOL bApply = FALSE;
+
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
+ const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName );
+ if ( ( pGroupDim && pGroupDim->GetDatePart() != 0 ) ||
+ ( pNumGroupDim && pNumGroupDim->GetDatePart() != 0 ) )
+ {
+ // Date grouping: need to remove all affected group dimensions.
+ // This is done using DateGroupDataPilot with nParts=0.
+
+ DateGroupDataPilot( ScDPNumGroupInfo(), 0 );
+ // bApply remains FALSE
+ // dimension pointers become invalid
+ }
+ else if ( pGroupDim )
+ {
+ USHORT nEntryCount = aEntries.GetCount();
+ for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ pGroupDim->RemoveGroup( aEntryName );
+ }
+ // remove group dimension if empty
+ bool bEmptyDim = pGroupDim->IsEmpty();
+ if ( !bEmptyDim )
+ {
+ // If all remaining groups in the dimension aren't shown, remove
+ // the dimension too, as if it was completely empty.
+ ScStrCollection aVisibleEntries;
+ pDPObj->GetMemberResultNames( aVisibleEntries, nSelectDimension );
+ bEmptyDim = pGroupDim->HasOnlyHidden( aVisibleEntries );
+ }
+ if ( bEmptyDim )
+ {
+ pDimData->RemoveGroupDimension( aDimName ); // pGroupDim is deleted
+
+ // also remove SaveData settings for the dimension that no longer exists
+ aData.RemoveDimensionByName( aDimName );
+ }
+ bApply = TRUE;
+ }
+ else if ( pNumGroupDim )
+ {
+ // remove the numerical grouping
+ pDimData->RemoveNumGroupDimension( aDimName );
+ // SaveData settings can remain unchanged - the same dimension still exists
+ bApply = TRUE;
+ }
+
+ if ( bApply )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+ }
+}
+
+static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
+{
+ sal_Int32 n = rSubtotal.getLength();
+ const sal_Unicode* p = rSubtotal.getStr();
+ OUStringBuffer aBuf, aWordBuf;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (c == sal_Unicode(' '))
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ aBuf.append(c);
+ }
+ else if (c == sal_Unicode('\\'))
+ {
+ // Escape a backslash character.
+ aWordBuf.append(c);
+ aWordBuf.append(c);
+ }
+ else if (c == sal_Unicode('?'))
+ {
+ // A literal '?' must be escaped with a backslash ('\');
+ aWordBuf.append(sal_Unicode('\\'));
+ aWordBuf.append(c);
+ }
+ else
+ aWordBuf.append(c);
+ }
+
+ if (aWordBuf.getLength() > 0)
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString )
+{
+ using namespace ::com::sun::star::sheet;
+
+ String aNewName( rString );
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() );
+ if (!pDPObj)
+ return;
+
+ String aOldText;
+ pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+
+ if ( aOldText == rString )
+ {
+ // nothing to do: silently exit
+ return;
+ }
+
+ USHORT nErrorId = 0;
+
+ pDPObj->BuildAllDimensionMembers();
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ BOOL bChange = FALSE;
+
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( rPos, nOrient );
+ if ( nField >= 0 )
+ {
+ // changing a field title
+ if ( aData.GetExistingDimensionData() )
+ {
+ // only group dimensions can be renamed
+
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing dimension (group or other)
+ if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) )
+ {
+ pGroupDim->Rename( aNewName );
+
+ // also rename in SaveData to preserve the field settings
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
+ pSaveDim->SetName( aNewName );
+
+ bChange = TRUE;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(nField, bDataLayout);
+ ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(aDimName))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ }
+ else if (pDPObj->IsDataDescriptionCell(rPos))
+ {
+ // There is only one data dimension.
+ ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pDim->GetName()))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else
+ {
+ // This is not a field header.
+ sheet::DataPilotTableHeaderData aPosData;
+ pDPObj->GetHeaderPositionData(rPos, aPosData);
+
+ if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() )
+ {
+ if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
+
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing group in this dimension
+ //! ignore case?
+ if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
+ {
+ ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
+ if ( pGroup )
+ pGroup->Rename( aNewName ); // rename the existing group
+ else
+ {
+ // create a new group to replace the automatic group
+ ScDPSaveGroupItem aGroup( aNewName );
+ aGroup.AddElement( aOldText );
+ pGroupDim->AddGroupItem( aGroup );
+ }
+
+ // in both cases also adjust savedata, to preserve member settings (show details)
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
+ ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
+ if ( pSaveMember )
+ pSaveMember->SetName( aNewName );
+
+ bChange = TRUE;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL))
+ {
+ aData.SetGrandTotalName(rString);
+ bChange = true;
+ }
+ else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout);
+ if (bDataLayout)
+ {
+ // data dimension
+ do
+ {
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ break;
+
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName);
+ if (!pDim)
+ break;
+
+ if (!rString.Len())
+ {
+ nErrorId = STR_INVALIDNAME;
+ break;
+ }
+
+ if (aPosData.MemberName.equalsIgnoreAsciiCase(rString))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ while (false);
+ }
+ else
+ {
+ // field member
+ do
+ {
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName);
+ if (!pDim)
+ break;
+
+ ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName);
+ if (!pMem)
+ break;
+
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ {
+ // Change subtotal only when the table has one data dimension.
+ if (aData.GetDataDimensionCount() > 1)
+ break;
+
+ // display name for subtotal is allowed only if the subtotal type is 'Automatic'.
+ if (pDim->GetSubTotalsCount() != 1)
+ break;
+
+ if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO)
+ break;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ String aMemberName;
+ if (pLayoutName)
+ aMemberName = *pLayoutName;
+ else
+ aMemberName = aPosData.MemberName;
+
+ String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName);
+ pDim->SetSubtotalName(aNew);
+ bChange = true;
+ }
+ else
+ {
+ // Check to make sure the member name isn't
+ // already used.
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pMem->GetName()))
+ {
+ pMem->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDim->IsMemberNameInUse(rString))
+ {
+ pMem->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ while (false);
+ }
+ }
+ }
+ }
+
+ if ( bChange )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+ }
+ else
+ {
+ if ( !nErrorId )
+ nErrorId = STR_ERR_DATAPILOT_INPUT;
+ ErrorMessage( nErrorId );
+ }
+}
+
+void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName )
+{
+ ScDPSaveMember* pNewMember = NULL;
+ const ScDPSaveMember* pOldMember = rDim.GetExistingMemberByName( rItemName );
+ if ( pOldMember )
+ pNewMember = new ScDPSaveMember( *pOldMember );
+ else
+ pNewMember = new ScDPSaveMember( rItemName );
+ rDim.AddMember( pNewMember );
+ // AddMember takes ownership of the new pointer,
+ // puts it to the end of the list even if it was in the list before.
+}
+
+struct ScOUStringCollate
+{
+ CollatorWrapper* mpCollator;
+
+ ScOUStringCollate(CollatorWrapper* pColl) : mpCollator(pColl) {}
+
+ bool operator()(const rtl::OUString& rStr1, const rtl::OUString& rStr2) const
+ {
+ return ( mpCollator->compareString(rStr1, rStr2) < 0 );
+ }
+};
+
+bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
+ if (!pDPObj)
+ return false;
+
+ // We need to run this to get all members later.
+ if ( pUserListId )
+ pDPObj->BuildAllDimensionMembers();
+
+ USHORT nOrientation;
+ long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
+ if (nDimIndex < 0)
+ // Invalid dimension index. Bail out.
+ return false;
+
+ BOOL bDataLayout;
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (!pSaveData)
+ return false;
+
+ ScDPSaveData aNewSaveData(*pSaveData);
+ String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout);
+ ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName);
+ if (!pSaveDim)
+ return false;
+
+ // manual evaluation of sort order is only needed if a user list id is given
+ if ( pUserListId )
+ {
+ typedef ScDPSaveDimension::MemberList MemList;
+ const MemList& rDimMembers = pSaveDim->GetMembers();
+ list<OUString> aMembers;
+ hash_set<OUString, ::rtl::OUStringHash> aMemberSet;
+ size_t nMemberCount = 0;
+ for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ ScDPSaveMember* pMem = *itr;
+ aMembers.push_back(pMem->GetName());
+ aMemberSet.insert(pMem->GetName());
+ ++nMemberCount;
+ }
+
+ // Sort the member list in ascending order.
+ ScOUStringCollate aCollate( ScGlobal::GetCollator() );
+ aMembers.sort(aCollate);
+
+ // Collect and rank those custom sort strings that also exist in the member name list.
+
+ typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap;
+ UserSortMap aSubStrs;
+ sal_uInt16 nSubCount = 0;
+ if (pUserListId)
+ {
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (!pUserList)
+ return false;
+
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ if (!n || *pUserListId >= n)
+ return false;
+ }
+
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]);
+ if (pData)
+ {
+ sal_uInt16 n = pData->GetSubCount();
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ OUString aSub = pData->GetSubStr(i);
+ if (!aMemberSet.count(aSub))
+ // This string doesn't exist in the member name set. Don't add this.
+ continue;
+
+ aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++));
+ }
+ }
+ }
+
+ // Rank all members.
+
+ vector<OUString> aRankedNames(nMemberCount);
+ sal_uInt16 nCurStrId = 0;
+ for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ OUString aName = *itr;
+ sal_uInt16 nRank = 0;
+ UserSortMap::const_iterator itrSub = aSubStrs.find(aName);
+ if (itrSub == aSubStrs.end())
+ nRank = nSubCount + nCurStrId++;
+ else
+ nRank = itrSub->second;
+
+ if (!bAscending)
+ nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 );
+
+ aRankedNames[nRank] = aName;
+ }
+
+ // Re-order ScDPSaveMember instances with the new ranks.
+
+ for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end();
+ itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr);
+ if (!pOldMem)
+ // All members are supposed to be present.
+ continue;
+
+ ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem);
+ pSaveDim->AddMember(pNewMem);
+ }
+
+ // Set the sorting mode to manual for now. We may introduce a new sorting
+ // mode later on.
+
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ pSaveDim->SetSortInfo(&aSortInfo);
+ }
+ else
+ {
+ // without user list id, just apply sorting mode
+
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::NAME;
+ aSortInfo.IsAscending = bAscending;
+ pSaveDim->SetSortInfo(&aSortInfo);
+ }
+
+ // Update the datapilot with the newly sorted field members.
+
+ auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj));
+ pNewObj->SetSaveData(aNewSaveData);
+ ScDBDocFunc aFunc(*GetViewData()->GetDocShell());
+
+ return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
+}
+
+BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
+{
+ BOOL bRet = FALSE;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( rSource.aStart.Col(), rSource.aStart.Row(), rSource.aStart.Tab() );
+ if ( pDPObj && pDPObj == pDoc->GetDPAtCursor( rDest.Col(), rDest.Row(), rDest.Tab() ) )
+ {
+ sheet::DataPilotTableHeaderData aDestData;
+ pDPObj->GetHeaderPositionData( rDest, aDestData );
+ bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field
+
+ // look through the source range
+ std::hash_set< rtl::OUString, rtl::OUStringHash, std::equal_to<rtl::OUString> > aMembersSet; // for lookup
+ std::vector< rtl::OUString > aMembersVector; // members in original order, for inserting
+ aMembersVector.reserve( std::max( static_cast<SCSIZE>( rSource.aEnd.Col() - rSource.aStart.Col() + 1 ),
+ static_cast<SCSIZE>( rSource.aEnd.Row() - rSource.aStart.Row() + 1 ) ) );
+ for (SCROW nRow = rSource.aStart.Row(); bValid && nRow <= rSource.aEnd.Row(); ++nRow )
+ for (SCCOL nCol = rSource.aStart.Col(); bValid && nCol <= rSource.aEnd.Col(); ++nCol )
+ {
+ sheet::DataPilotTableHeaderData aSourceData;
+ pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, rSource.aStart.Tab() ), aSourceData );
+ if ( aSourceData.Dimension == aDestData.Dimension && aSourceData.MemberName.getLength() )
+ {
+ if ( aMembersSet.find( aSourceData.MemberName ) == aMembersSet.end() )
+ {
+ aMembersSet.insert( aSourceData.MemberName );
+ aMembersVector.push_back( aSourceData.MemberName );
+ }
+ // duplicates are ignored
+ }
+ else
+ bValid = false; // empty (subtotal) or different field
+ }
+
+ if ( bValid )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPSaveDimension* pDim = aData.GetDimensionByName( aDimName );
+
+ // get all member names in source order
+ uno::Sequence<rtl::OUString> aMemberNames;
+ pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames );
+
+ bool bInserted = false;
+
+ sal_Int32 nMemberCount = aMemberNames.getLength();
+ for (sal_Int32 nMemberPos=0; nMemberPos<nMemberCount; ++nMemberPos)
+ {
+ String aMemberStr( aMemberNames[nMemberPos] );
+
+ if ( !bInserted && aMemberNames[nMemberPos] == aDestData.MemberName )
+ {
+ // insert dragged items before this item
+ for ( std::vector<rtl::OUString>::const_iterator aIter = aMembersVector.begin();
+ aIter != aMembersVector.end(); ++aIter )
+ lcl_MoveToEnd( *pDim, *aIter );
+ bInserted = true;
+ }
+
+ if ( aMembersSet.find( aMemberStr ) == aMembersSet.end() ) // skip dragged items
+ lcl_MoveToEnd( *pDim, aMemberStr );
+ }
+ // insert dragged item at end if dest wasn't found (for example, empty)
+ if ( !bInserted )
+ for ( std::vector<rtl::OUString>::const_iterator aIter = aMembersVector.begin();
+ aIter != aMembersVector.end(); ++aIter )
+ lcl_MoveToEnd( *pDim, *aIter );
+
+ // Items that were in SaveData, but not in the source, end up at the start of the list.
+
+ // set flag for manual sorting
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ pDim->SetSortInfo( &aSortInfo );
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE ); //! bApi for drag&drop?
+ delete pNewObj;
+
+ Unmark(); // entry was moved - no use in leaving the old cell selected
+
+ bRet = TRUE;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+BOOL ScDBFunc::HasSelectionForDrillDown( USHORT& rOrientation )
+{
+ BOOL bRet = FALSE;
+
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName( aDimName );
+ if ( pDim )
+ {
+ USHORT nDimOrient = pDim->GetOrientation();
+ ScDPSaveDimension* pInner = pSaveData->GetInnermostDimension( nDimOrient );
+ if ( pDim == pInner )
+ {
+ rOrientation = nDimOrient;
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+void ScDBFunc::SetDataPilotDetails( BOOL bShow, const String* pNewDimensionName )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPSaveDimension* pDim = aData.GetDimensionByName( aDimName );
+
+ if ( bShow && pNewDimensionName )
+ {
+ // add the new dimension with the same orientation, at the end
+
+ ScDPSaveDimension* pNewDim = aData.GetDimensionByName( *pNewDimensionName );
+ ScDPSaveDimension* pDuplicated = NULL;
+ if ( pNewDim->GetOrientation() == sheet::DataPilotFieldOrientation_DATA )
+ {
+ // Need to duplicate the dimension, create column/row in addition to data:
+ // The duplicated dimension inherits the existing settings, pNewDim is modified below.
+ pDuplicated = aData.DuplicateDimension( *pNewDimensionName );
+ }
+
+ USHORT nOrientation = pDim->GetOrientation();
+ pNewDim->SetOrientation( nOrientation );
+
+ long nPosition = LONG_MAX;
+ aData.SetPosition( pNewDim, nPosition );
+
+ ScDPSaveDimension* pDataLayout = aData.GetDataLayoutDimension();
+ if ( pDataLayout->GetOrientation() == nOrientation &&
+ aData.GetDataDimensionCount() <= 1 )
+ {
+ // If there is only one data dimension, the data layout dimension
+ // must still be the last one in its orientation.
+ aData.SetPosition( pDataLayout, nPosition );
+ }
+
+ if ( pDuplicated )
+ {
+ // The duplicated (data) dimension needs to be behind the original dimension
+ aData.SetPosition( pDuplicated, nPosition );
+ }
+
+ // Hide details for all visible members (selected are changed below).
+ //! Use all members from source level instead (including non-visible)?
+
+ ScStrCollection aVisibleEntries;
+ pDPObj->GetMemberResultNames( aVisibleEntries, nSelectDimension );
+
+ USHORT nVisCount = aVisibleEntries.GetCount();
+ for (USHORT nVisPos=0; nVisPos<nVisCount; nVisPos++)
+ {
+ String aVisName = aVisibleEntries[nVisPos]->GetString();
+ ScDPSaveMember* pMember = pDim->GetMemberByName( aVisName );
+ pMember->SetShowDetails( FALSE );
+ }
+ }
+
+ USHORT nEntryCount = aEntries.GetCount();
+ for (USHORT nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ ScDPSaveMember* pMember = pDim->GetMemberByName( aEntryName );
+ pMember->SetShowDetails( bShow );
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+ }
+}
+
+void ScDBFunc::ShowDataPilotSourceData( ScDPObject& rDPObj, const Sequence<sheet::DataPilotFieldFilter>& rFilters )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (pDoc->GetDocumentShell()->IsReadOnly())
+ {
+ ErrorMessage(STR_READONLYERR);
+ return;
+ }
+
+ Reference<sheet::XDimensionsSupplier> xDimSupplier = rDPObj.GetSource();
+ Reference<container::XNameAccess> xDims = xDimSupplier->getDimensions();
+ Reference<sheet::XDrillDownDataSupplier> xDDSupplier(xDimSupplier, UNO_QUERY);
+ if (!xDDSupplier.is())
+ return;
+
+ Sequence< Sequence<Any> > aTabData = xDDSupplier->getDrillDownData(rFilters);
+ sal_Int32 nRowSize = aTabData.getLength();
+ if (nRowSize <= 1)
+ // There is no data to show. Bail out.
+ return;
+
+ sal_Int32 nColSize = aTabData[0].getLength();
+
+ SCTAB nNewTab = GetViewData()->GetTabNo();
+
+ auto_ptr<ScDocument> pInsDoc(new ScDocument(SCDOCMODE_CLIP));
+ pInsDoc->ResetClip( pDoc, nNewTab );
+ for (SCROW nRow = 0; nRow < nRowSize; ++nRow)
+ {
+ for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
+ {
+ const Any& rAny = aTabData[nRow][nCol];
+ rtl::OUString aStr;
+ double fVal;
+ if (rAny >>= aStr)
+ pInsDoc->PutCell( ScAddress(nCol, nRow, nNewTab), new ScStringCell(String(aStr)) );
+ else if (rAny >>= fVal)
+ pInsDoc->SetValue(nCol, nRow, nNewTab, fVal);
+ }
+ }
+
+ // set number format (important for dates)
+ for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
+ {
+ rtl::OUString aStr;
+ if (!(aTabData[0][nCol] >>= aStr))
+ continue;
+
+ Reference<XPropertySet> xPropSet(xDims->getByName(aStr), UNO_QUERY);
+ if (!xPropSet.is())
+ continue;
+
+ Any any = xPropSet->getPropertyValue( rtl::OUString::createFromAscii(SC_UNO_NUMBERFO) );
+ sal_Int32 nNumFmt = 0;
+ if (!(any >>= nNumFmt))
+ continue;
+
+ ScPatternAttr aPattern( pInsDoc->GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item(ATTR_VALUE_FORMAT, static_cast<UINT32>(nNumFmt)) );
+ pInsDoc->ApplyPatternAreaTab(nCol, 1, nCol, nRowSize-1, nNewTab, aPattern);
+ }
+
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pInsDoc->GetCellArea( nNewTab, nEndCol, nEndRow );
+ pInsDoc->SetClipArea( ScRange( 0, 0, nNewTab, nEndCol, nEndRow, nNewTab ) );
+
+ SfxUndoManager* pMgr = GetViewData()->GetDocShell()->GetUndoManager();
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_DOOUTLINE );
+ pMgr->EnterListAction( aUndo, aUndo );
+
+ String aNewTabName;
+ pDoc->CreateValidTabName(aNewTabName);
+ if ( InsertTable(aNewTabName, nNewTab) )
+ PasteFromClip( IDF_ALL, pInsDoc.get() );
+
+ pMgr->LeaveListAction();
+}
+
+//
+// DB-Operationen (Sortieren, Filtern, Teilergebnisse) wiederholen
+//
+
+void ScDBFunc::RepeatDB( BOOL bRecord )
+{
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBData* pDBData = GetDBData();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScQueryParam aQueryParam;
+ pDBData->GetQueryParam( aQueryParam );
+ BOOL bQuery = aQueryParam.GetEntry(0).bDoQuery;
+
+ ScSortParam aSortParam;
+ pDBData->GetSortParam( aSortParam );
+ BOOL bSort = aSortParam.bDoSort[0];
+
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ BOOL bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly;
+
+ if ( bQuery || bSort || bSubTotal )
+ {
+ BOOL bQuerySize = FALSE;
+ ScRange aOldQuery;
+ ScRange aNewQuery;
+ if (bQuery && !aQueryParam.bInplace)
+ {
+ ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, TRUE );
+ if (pDest && pDest->IsDoSize())
+ {
+ pDest->GetArea( aOldQuery );
+ bQuerySize = TRUE;
+ }
+ }
+
+ SCTAB nDummy;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDBData->GetArea( nDummy, nStartCol, nStartRow, nEndCol, nEndRow );
+
+ //! Undo nur benoetigte Daten ?
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ ScRangeName* pUndoRange = NULL;
+ ScDBCollection* pUndoDB = NULL;
+
+ if (bRecord)
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ SCCOLROW nOutStartCol; // Zeilen/Spaltenstatus
+ SCCOLROW nOutStartRow;
+ SCCOLROW nOutEndCol;
+ SCCOLROW nOutEndRow;
+ pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
+ pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+
+ // Datenbereich sichern - incl. Filter-Ergebnis
+ pDoc->CopyToDocument( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab, IDF_ALL, FALSE, pUndoDoc );
+
+ // alle Formeln wegen Referenzen
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, IDF_FORMULA, FALSE, pUndoDoc );
+
+ // DB- und andere Bereiche
+ ScRangeName* pDocRange = pDoc->GetRangeName();
+ if (pDocRange->GetCount())
+ pUndoRange = new ScRangeName( *pDocRange );
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+ }
+
+ if (bSort && bSubTotal)
+ {
+ // Sortieren ohne SubTotals
+
+ aSubTotalParam.bRemoveOnly = TRUE; // wird unten wieder zurueckgesetzt
+ DoSubTotals( aSubTotalParam, FALSE );
+ }
+
+ if (bSort)
+ {
+ pDBData->GetSortParam( aSortParam ); // Bereich kann sich geaendert haben
+ Sort( aSortParam, FALSE, FALSE);
+ }
+ if (bQuery)
+ {
+ 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 );
+
+ // bei nicht-inplace kann die Tabelle umgestellt worden sein
+ if ( !aQueryParam.bInplace && aQueryParam.nDestTab != nTab )
+ SetTabNo( nTab );
+ }
+ if (bSubTotal)
+ {
+ pDBData->GetSubTotalParam( aSubTotalParam ); // Bereich kann sich geaendert haben
+ aSubTotalParam.bRemoveOnly = FALSE;
+ DoSubTotals( aSubTotalParam, FALSE );
+ }
+
+ if (bRecord)
+ {
+ SCTAB nDummyTab;
+ SCCOL nDummyCol;
+ SCROW nDummyRow, nNewEndRow;
+ pDBData->GetArea( nDummyTab, nDummyCol,nDummyRow, nDummyCol,nNewEndRow );
+
+ const ScRange* pOld = NULL;
+ const ScRange* pNew = NULL;
+ if (bQuerySize)
+ {
+ ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, TRUE );
+ if (pDest)
+ {
+ pDest->GetArea( aNewQuery );
+ pOld = &aOldQuery;
+ pNew = &aNewQuery;
+ }
+ }
+
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoRepeatDB( GetViewData()->GetDocShell(), nTab,
+ nStartCol, nStartRow, nEndCol, nEndRow,
+ nNewEndRow,
+ nCurX, nCurY,
+ pUndoDoc, pUndoTab,
+ pUndoRange, pUndoDB,
+ pOld, pNew ) );
+ }
+
+ GetViewData()->GetDocShell()->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+ }
+ else // "Keine Operationen auszufuehren"
+ ErrorMessage(STR_MSSG_REPEATDB_0);
+}
+
+
+
+
diff --git a/sc/source/ui/view/dbfunc4.cxx b/sc/source/ui/view/dbfunc4.cxx
new file mode 100644
index 000000000000..870622293e37
--- /dev/null
+++ b/sc/source/ui/view/dbfunc4.cxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+
+#include "dbfunc.hxx"
+#include "drwlayer.hxx"
+#include "document.hxx"
+
+// -----------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+using namespace com::sun::star;
+
+//==================================================================
+
+// static
+USHORT ScDBFunc::DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, BOOL bAllCharts )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return 0;
+
+ USHORT nFound = 0;
+
+ USHORT nPageCount = pModel->GetPageCount();
+ for (USHORT nPageNo=0; nPageNo<nPageCount; nPageNo++)
+ {
+ SdrPage* pPage = pModel->GetPage(nPageNo);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart( pObject ) )
+ {
+ String aName = ((SdrOle2Obj*)pObject)->GetPersistName();
+ BOOL bHit = TRUE;
+ if ( !bAllCharts )
+ {
+ ScRangeList aRanges;
+ BOOL bColHeaders = FALSE;
+ BOOL bRowHeaders = FALSE;
+ pDoc->GetOldChartParameters( aName, aRanges, bColHeaders, bRowHeaders );
+ bHit = aRanges.In( rPos );
+ }
+ if ( bHit )
+ {
+ pDoc->UpdateChart( aName );
+ ++nFound;
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ return nFound;
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/view/drawattr.cxx b/sc/source/ui/view/drawattr.cxx
new file mode 100644
index 000000000000..fa7872617c03
--- /dev/null
+++ b/sc/source/ui/view/drawattr.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "drawattr.hxx"
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+
+String __EXPORT SvxDrawToolItem::GetValueText() const
+{
+ return GetValueText(GetValue());
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT SvxDrawToolItem::GetValueText( USHORT nVal ) const
+{
+ const sal_Char* p;
+
+ switch (nVal)
+ {
+ case 0 : p = "SVX_SNAP_DRAW_SELECT" ; break;
+ //
+ case 1 : p = "SVX_SNAP_DRAW_LINE" ; break;
+ case 2 : p = "SVX_SNAP_DRAW_RECT" ; break;
+ case 3 : p = "SVX_SNAP_DRAW_ELLIPSE" ; break;
+ case 4 : p = "SVX_SNAP_DRAW_POLYGON" ; break;
+ case 5 : p = "SVX_SNAP_DRAW_ARC" ; break;
+ case 6 : p = "SVX_SNAP_DRAW_PIE" ; break;
+ case 7 : p = "SVX_SNAP_DRAW_CIRCLECUT" ; break;
+ case 8 : p = "SVX_SNAP_DRAW_TEXT" ; break;
+ default : return EMPTY_STRING;
+ }
+ return String::CreateFromAscii( p );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT SvxDrawToolItem::Clone( SfxItemPool * ) const
+{
+ return new SvxDrawToolItem(*this);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT SvxDrawToolItem::Create( SvStream& rStream, USHORT nVer ) const
+{
+ USHORT nVal;
+ rStream >> nVal;
+ return new SvxDrawToolItem(nVal);
+}
+
+
+
diff --git a/sc/source/ui/view/drawutil.cxx b/sc/source/ui/view/drawutil.cxx
new file mode 100644
index 000000000000..ba250767c169
--- /dev/null
+++ b/sc/source/ui/view/drawutil.cxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <vcl/outdev.hxx>
+
+#include "drawutil.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+
+inline Fraction MakeFraction( long nA, long nB )
+{
+ return ( nA && nB ) ? Fraction(nA,nB) : Fraction(1,1);
+}
+
+void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ OutputDevice* pDev,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ double nPPTX, double nPPTY,
+ Fraction& rScaleX, Fraction& rScaleY )
+{
+ long nPixelX = 0;
+ long nTwipsX = 0;
+ long nPixelY = 0;
+ long nTwipsY = 0;
+ for (SCCOL i=nStartCol; i<nEndCol; i++)
+ {
+ USHORT nWidth = pDoc->GetColWidth(i,nTab);
+ nTwipsX += (long) nWidth;
+ nPixelX += ScViewData::ToPixel( nWidth, nPPTX );
+ }
+
+ for (SCROW nRow = nStartRow; nRow <= nEndRow-1; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow))
+ {
+ nRow = nLastRow;
+ continue;
+ }
+
+ USHORT nHeight = pDoc->GetRowHeight(nRow, nTab);
+ nTwipsY += static_cast<long>(nHeight);
+ nPixelY += ScViewData::ToPixel(nHeight, nPPTY);
+ }
+
+ MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY );
+ Point aPixelLog = pDev->PixelToLogic( Point( nPixelX,nPixelY ), aHMMMode );
+
+ // Fraction(double) ctor can be used here (and avoid overflows of PixelLog * Zoom)
+ // because ReduceInaccurate is called later anyway.
+
+ if ( aPixelLog.X() && nTwipsX )
+ rScaleX = Fraction( ((double)aPixelLog.X()) *
+ ((double)rZoomX.GetNumerator()) /
+ ((double)nTwipsX) /
+ ((double)HMM_PER_TWIPS) /
+ ((double)rZoomX.GetDenominator()) );
+ else
+ rScaleX = Fraction( 1, 1 );
+
+ if ( aPixelLog.Y() && nTwipsY )
+ rScaleY = Fraction( ((double)aPixelLog.Y()) *
+ ((double)rZoomY.GetNumerator()) /
+ ((double)nTwipsY) /
+ ((double)HMM_PER_TWIPS) /
+ ((double)rZoomY.GetDenominator()) );
+ else
+ rScaleY = Fraction( 1, 1 );
+
+ // 25 bits of accuracy are needed to always hit the right part of
+ // cells in the last rows (was 17 before 1M rows).
+ rScaleX.ReduceInaccurate( 25 );
+ rScaleY.ReduceInaccurate( 25 );
+}
+
+
+
+
diff --git a/sc/source/ui/view/drawvie2.cxx b/sc/source/ui/view/drawvie2.cxx
new file mode 100644
index 000000000000..c760ce86a3d7
--- /dev/null
+++ b/sc/source/ui/view/drawvie2.cxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "drawview.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+
+// UpdateBrowser in MarkListHasChanged gerufen
+
+void ScDrawView::UpdateBrowser()
+{
+ // VC's und den Browser dazu gibts nicht mehr...
+}
+
+void ScDrawView::VCAddWin( Window* /* pWin */ )
+{
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+void ScDrawView::VCRemoveWin( Window* /* pWin */ )
+{
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx
new file mode 100644
index 000000000000..ffa1efe28654
--- /dev/null
+++ b/sc/source/ui/view/drawvie3.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+#include "viewdata.hxx"
+#include "dbfunc.hxx"
+#include "document.hxx"
+#include "userdat.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+
+void ScIMapDlgSet( const Graphic& rGraphic, const ImageMap* pImageMap,
+ const TargetList* pTargetList, void* pEditingObj ); // imapwrap
+USHORT ScIMapChildWindowId();
+
+// STATIC DATA -----------------------------------------------------------
+
+ScDrawView::ScDrawView( OutputDevice* pOut, ScViewData* pData ) :
+ FmFormView( pData->GetDocument()->GetDrawLayer(), pOut ),
+ pViewData( pData ),
+ pDev( pOut ),
+ pDoc( pData->GetDocument() ),
+ nTab( pData->GetTabNo() ),
+ pDropMarker( NULL ),
+ pDropMarkObj( NULL ),
+ bInConstruct( TRUE )
+ //HMHbDisableHdl( FALSE )
+{
+ // #i73602# Use default from the configuration
+ SetBufferedOverlayAllowed(getOptionsDrawinglayer().IsOverlayBuffer_Calc());
+
+ // #i74769#, #i75172# Use default from the configuration
+ SetBufferedOutputAllowed(getOptionsDrawinglayer().IsPaintBuffer_Calc());
+
+ Construct();
+}
+
+// Verankerung setzen
+
+void ScDrawView::SetAnchor( ScAnchorType eType )
+{
+ SdrObject* pObj = NULL;
+ if( AreObjectsMarked() )
+ {
+ const SdrMarkList* pMark = &GetMarkedObjectList();
+ ULONG nCount = pMark->GetMarkCount();
+ for( ULONG i=0; i<nCount; i++ )
+ {
+ pObj = pMark->GetMark(i)->GetMarkedSdrObj();
+ ScDrawLayer::SetAnchor( pObj, eType );
+ }
+
+ if ( pViewData )
+ pViewData->GetDocShell()->SetDrawModified();
+ }
+}
+
+ScAnchorType ScDrawView::GetAnchor() const
+{
+ BOOL bPage = FALSE;
+ BOOL bCell = FALSE;
+ const SdrObject* pObj = NULL;
+ if( AreObjectsMarked() )
+ {
+ const SdrMarkList* pMark = &GetMarkedObjectList();
+ ULONG nCount = pMark->GetMarkCount();
+ Point p0;
+ for( ULONG i=0; i<nCount; i++ )
+ {
+ pObj = pMark->GetMark(i)->GetMarkedSdrObj();
+ if( ScDrawLayer::GetAnchor( pObj ) == SCA_CELL )
+ bCell =TRUE;
+ else
+ bPage = TRUE;
+ }
+ }
+ if( bPage && !bCell )
+ return SCA_PAGE;
+ if( !bPage && bCell )
+ return SCA_CELL;
+ return SCA_DONTKNOW;
+}
+
+void __EXPORT ScDrawView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA(ScTabDeletedHint)) // Tabelle geloescht
+ {
+ SCTAB nDelTab = ((ScTabDeletedHint&)rHint).GetTab();
+ if (ValidTab(nDelTab))
+ {
+ // used to be: HidePagePgNum(nDelTab) - hide only if the deleted sheet is shown here
+ if ( nDelTab == nTab )
+ HideSdrPage();
+ }
+ }
+ else if (rHint.ISA(ScTabSizeChangedHint)) // Groesse geaendert
+ {
+ if ( nTab == ((ScTabSizeChangedHint&)rHint).GetTab() )
+ UpdateWorkArea();
+ }
+ else
+ FmFormView::Notify( rBC,rHint );
+}
+
+void ScDrawView::UpdateIMap( SdrObject* pObj )
+{
+ if ( pViewData &&
+ pViewData->GetViewShell()->GetViewFrame()->HasChildWindow( ScIMapChildWindowId() ) &&
+ pObj && ( pObj->ISA(SdrGrafObj) || pObj->ISA(SdrOle2Obj) ) )
+ {
+ Graphic aGraphic;
+ TargetList aTargetList;
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo( pObj );
+ const ImageMap* pImageMap = NULL;
+ if ( pIMapInfo )
+ pImageMap = &pIMapInfo->GetImageMap();
+
+ // Target-Liste besorgen
+ pViewData->GetViewShell()->GetViewFrame()->GetTargetList( aTargetList );
+
+ // Grafik vom Objekt besorgen
+ if ( pObj->ISA( SdrGrafObj ) )
+ aGraphic = ( (SdrGrafObj*) pObj )->GetGraphic();
+ else
+ {
+ Graphic* pGraphic = ((const SdrOle2Obj*) pObj )->GetGraphic();
+ if ( pGraphic )
+ aGraphic = *pGraphic;
+ }
+
+ ScIMapDlgSet( aGraphic, pImageMap, &aTargetList, pObj ); // aus imapwrap
+
+ // TargetListe kann von uns wieder geloescht werden
+ String* pEntry = aTargetList.First();
+ while( pEntry )
+ {
+ delete pEntry;
+ pEntry = aTargetList.Next();
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx
new file mode 100644
index 000000000000..d4c5d714b2ee
--- /dev/null
+++ b/sc/source/ui/view/drawvie4.cxx
@@ -0,0 +1,394 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include "drawview.hxx"
+#include "global.hxx"
+#include "drwlayer.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "drwtrans.hxx"
+#include "transobj.hxx" // SetDrawClipDoc
+#include "drawutil.hxx"
+#include "scmod.hxx"
+#include "globstr.hrc"
+#include "chartarr.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+Point aDragStartDiff;
+
+// -----------------------------------------------------------------------
+
+//! welche Funktionen aus drawview/drawvie4 muessen wirklich ohne Optimierung sein?
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+// -----------------------------------------------------------------------
+
+void lcl_CheckOle( const SdrMarkList& rMarkList, BOOL& rAnyOle, BOOL& rOneOle )
+{
+ rAnyOle = rOneOle = FALSE;
+ ULONG nCount = rMarkList.GetMarkCount();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ UINT16 nSdrObjKind = pObj->GetObjIdentifier();
+ if (nSdrObjKind == OBJ_OLE2)
+ {
+ rAnyOle = TRUE;
+ rOneOle = (nCount == 1);
+ break;
+ }
+ else if ( pObj->ISA(SdrObjGroup) )
+ {
+ SdrObjListIter aIter( *pObj, IM_DEEPNOGROUPS );
+ SdrObject* pSubObj = aIter.Next();
+ while (pSubObj)
+ {
+ if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ rAnyOle = TRUE;
+ // rOneOle remains FALSE - a group isn't treated like a single OLE object
+ return;
+ }
+ pSubObj = aIter.Next();
+ }
+ }
+ }
+}
+
+#if 0
+void lcl_RefreshChartData( SdrModel* pModel, ScDocument* pSourceDoc )
+{
+ USHORT nPages = pModel->GetPageCount();
+ for (SCTAB nTab=0; nTab<nPages; nTab++)
+ {
+ SdrPage* pPage = pModel->GetPage(nTab);
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ SvInPlaceObjectRef aIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if ( aIPObj.Is() && SotExchange::IsChart( aIPObj->GetStorage()->GetClassName() ) )
+ {
+ SchMemChart* pOldData = SchDLL::GetChartData(aIPObj);
+ if ( pOldData )
+ {
+ // create data from source document
+ ScChartArray aArray( pSourceDoc, *pOldData );
+ if ( aArray.IsValid() )
+ {
+ SchMemChart* pNewData = aArray.CreateMemChart();
+ SchDLL::Update( aIPObj, pNewData );
+ delete pNewData;
+ ((SdrOle2Obj*)pObject)->GetNewReplacement();
+ }
+ }
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+#endif
+
+
+BOOL ScDrawView::BeginDrag( Window* pWindow, const Point& rStartPos )
+{
+ BOOL bReturn = FALSE;
+
+ if ( AreObjectsMarked() )
+ {
+ BrkAction();
+
+ Rectangle aMarkedRect = GetAllMarkedRect();
+ Region aRegion( aMarkedRect );
+
+ aDragStartDiff = rStartPos - aMarkedRect.TopLeft();
+
+ BOOL bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ ScDocShellRef aDragShellRef;
+ if (bAnyOle)
+ {
+ aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
+ aDragShellRef->DoInitNew(NULL);
+ }
+ ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
+ SdrModel* pModel = GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ // Charts now always copy their data in addition to the source reference, so
+ // there's no need to call SchDLL::Update for the charts in the clipboard doc.
+ // Update with the data (including NumberFormatter) from the live document would
+ // also store the NumberFormatter in the clipboard chart (#88749#)
+ // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ pTransferObj->SetDrawPersist( &aDragShellRef ); // keep persist for ole objects alive
+ pTransferObj->SetDragSource( this ); // copies selection
+
+ SC_MOD()->SetDragObject( NULL, pTransferObj ); // for internal D&D
+ pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+ }
+
+ return bReturn;
+}
+
+void ScDrawView::DoCopy()
+{
+ BOOL bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ // update ScGlobal::pDrawClipDocShellRef
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+ SdrModel* pModel = GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ // Charts now always copy their data in addition to the source reference, so
+ // there's no need to call SchDLL::Update for the charts in the clipboard doc.
+ // Update with the data (including NumberFormatter) from the live document would
+ // also store the NumberFormatter in the clipboard chart (#88749#)
+ // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( pViewData->GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( NULL, pTransferObj ); // internal clipboard
+}
+
+uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable()
+{
+ BOOL bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ // update ScGlobal::pDrawClipDocShellRef
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+ SdrModel* pModel = GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ // Charts now always copy their data in addition to the source reference, so
+ // there's no need to call SchDLL::Update for the charts in the clipboard doc.
+ // Update with the data (including NumberFormatter) from the live document would
+ // also store the NumberFormatter in the clipboard chart (#88749#)
+ // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
+ }
+
+ return xTransferable;
+}
+
+// Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
+
+void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const
+{
+ Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = ScGlobal::nScreenPPTX;
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ if (pViewData)
+ nPPTX /= pViewData->GetDocShell()->GetOutputFactor();
+
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pDoc->GetTableArea( nTab, nEndCol, nEndRow );
+ if (nEndCol<20)
+ nEndCol = 20;
+ if (nEndRow<20)
+ nEndRow = 1000;
+
+ Fraction aZoom(1,1);
+ ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom,
+ nPPTX, nPPTY, rFractX,rFractY );
+}
+
+void ScDrawView::SetMarkedOriginalSize()
+{
+ SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*GetModel());
+
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ long nDone = 0;
+ ULONG nCount = rMarkList.GetMarkCount();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ USHORT nIdent = pObj->GetObjIdentifier();
+ BOOL bDo = FALSE;
+ Size aOriginalSize;
+ if (nIdent == OBJ_OLE2)
+ {
+ // TODO/LEAN: working with visual area can switch object to running state
+ uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), uno::UNO_QUERY );
+ if ( xObj.is() ) // #121612# NULL for an invalid object that couldn't be loaded
+ {
+ sal_Int64 nAspect = ((SdrOle2Obj*)pObj)->GetAspect();
+
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ {
+ MapMode aMapMode( MAP_100TH_MM );
+ aOriginalSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize( &aMapMode );
+ bDo = TRUE;
+ }
+ else
+ {
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( ((SdrOle2Obj*)pObj)->GetAspect() ) );
+ awt::Size aSz;
+ try
+ {
+ aSz = xObj->getVisualAreaSize( ((SdrOle2Obj*)pObj)->GetAspect() );
+ aOriginalSize = OutputDevice::LogicToLogic(
+ Size( aSz.Width, aSz.Height ),
+ aUnit, MAP_100TH_MM );
+ bDo = TRUE;
+ } catch( embed::NoVisualAreaSizeException& )
+ {
+ OSL_ENSURE( sal_False, "Can't get the original size of the object!" );
+ }
+ }
+ }
+ }
+ else if (nIdent == OBJ_GRAF)
+ {
+ const Graphic& rGraphic = ((SdrGrafObj*)pObj)->GetGraphic();
+
+ MapMode aSourceMap = rGraphic.GetPrefMapMode();
+ MapMode aDestMap( MAP_100TH_MM );
+ if (aSourceMap.GetMapUnit() == MAP_PIXEL)
+ {
+ // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
+
+ Fraction aNormScaleX, aNormScaleY;
+ CalcNormScale( aNormScaleX, aNormScaleY );
+ aDestMap.SetScaleX(aNormScaleX);
+ aDestMap.SetScaleY(aNormScaleY);
+ }
+ if (pViewData)
+ {
+ Window* pActWin = pViewData->GetActiveWin();
+ if (pActWin)
+ {
+ aOriginalSize = pActWin->LogicToLogic(
+ rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
+ bDo = TRUE;
+ }
+ }
+ }
+
+ if ( bDo )
+ {
+ Rectangle aDrawRect = pObj->GetLogicRect();
+
+ pUndoGroup->AddAction( new SdrUndoGeoObj( *pObj ) );
+ pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ),
+ Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) );
+ ++nDone;
+ }
+ }
+
+ if (nDone)
+ {
+ pUndoGroup->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE ));
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ pDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
+ pDocSh->SetDrawModified();
+ }
+ else
+ delete pUndoGroup;
+}
+
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+
+
+
diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx
new file mode 100644
index 000000000000..489da0cc4899
--- /dev/null
+++ b/sc/source/ui/view/drawview.cxx
@@ -0,0 +1,849 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/embed/EmbedStates.hpp>
+
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdomedia.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "drawview.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "drawutil.hxx"
+#include "futext.hxx"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "client.hxx"
+#include "scmod.hxx"
+#include "drwlayer.hxx"
+#include "docsh.hxx"
+#include "viewuno.hxx"
+#include "userdat.hxx"
+#include "postit.hxx"
+#include "undocell.hxx"
+
+#include "sc.hrc"
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define SC_HANDLESIZE_BIG 9
+#define SC_HANDLESIZE_SMALL 7
+
+// -----------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+
+void ScDrawView::Construct()
+{
+ EnableExtendedKeyInputDispatcher(FALSE);
+ EnableExtendedMouseEventDispatcher(FALSE);
+ EnableExtendedCommandEventDispatcher(FALSE);
+
+ SetFrameDragSingles(TRUE);
+// SetSolidMarkHdl(TRUE); // einstellbar -> UpdateUserViewOptions
+
+ SetMinMoveDistancePixel( 2 );
+ SetHitTolerancePixel( 2 );
+
+ if (pViewData)
+ {
+ SCTAB nViewTab = pViewData->GetTabNo();
+ ShowSdrPage(GetModel()->GetPage(nViewTab));
+
+ BOOL bEx = pViewData->GetViewShell()->IsDrawSelMode();
+ BOOL bProt = pDoc->IsTabProtected( nViewTab ) ||
+ pViewData->GetSfxDocShell()->IsReadOnly();
+
+ SdrLayer* pLayer;
+ SdrLayerAdmin& rAdmin = GetModel()->GetLayerAdmin();
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
+ if (pLayer)
+ SetLayerLocked( pLayer->GetName(), bProt || !bEx );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
+ if (pLayer)
+ SetLayerLocked( pLayer->GetName(), TRUE );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
+ if (pLayer)
+ {
+ SetLayerLocked( pLayer->GetName(), bProt );
+ SetActiveLayer( pLayer->GetName() ); // FRONT als aktiven Layer setzen
+ }
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
+ if (pLayer)
+ SetLayerLocked( pLayer->GetName(), bProt );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
+ if (pLayer)
+ {
+ SetLayerLocked( pLayer->GetName(), bProt );
+ SetLayerVisible( pLayer->GetName(), sal_False);
+ }
+
+ SetSwapAsynchron(TRUE);
+ }
+ else
+ {
+ ShowSdrPage(GetModel()->GetPage(nTab));
+ }
+
+ UpdateUserViewOptions();
+ RecalcScale();
+ UpdateWorkArea();
+
+ bInConstruct = FALSE;
+}
+
+void ScDrawView::ImplClearCalcDropMarker()
+{
+ if(pDropMarker)
+ {
+ delete pDropMarker;
+ pDropMarker = 0L;
+ }
+}
+
+__EXPORT ScDrawView::~ScDrawView()
+{
+ ImplClearCalcDropMarker();
+}
+
+void ScDrawView::AddCustomHdl()
+{
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+
+ const SdrMarkList &rMrkList = GetMarkedObjectList();
+ UINT32 nCount = rMrkList.GetMarkCount();
+ for(UINT32 nPos=0; nPos<nCount; nPos++ )
+ {
+ const SdrObject* pObj = rMrkList.GetMark(nPos)->GetMarkedSdrObj();
+ if(ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ const INT32 nDelta = 1;
+
+ Rectangle aBoundRect = pObj->GetCurrentBoundRect();
+ Point aPos;
+ if (bNegativePage)
+ {
+ aPos = aBoundRect.TopRight();
+ aPos.X() = -aPos.X(); // so the loop below is the same
+ }
+ else
+ aPos = aBoundRect.TopLeft();
+ long nPosX = (long) (aPos.X() / HMM_PER_TWIPS) + nDelta;
+ long nPosY = (long) (aPos.Y() / HMM_PER_TWIPS) + nDelta;
+
+ SCCOL nCol;
+ INT32 nWidth = 0;
+
+ for(nCol=0; nCol<=MAXCOL && nWidth<=nPosX; nCol++)
+ nWidth += pDoc->GetColWidth(nCol,nTab);
+
+ if(nCol > 0)
+ --nCol;
+
+ SCROW nRow = nPosY <= 0 ? 0 : pDoc->GetRowForHeight( nTab,
+ (ULONG) nPosY);
+ if(nRow > 0)
+ --nRow;
+
+ ScTabView* pView = pViewData->GetView();
+ ScAddress aScAddress(nCol, nRow, nTab);
+ pView->CreateAnchorHandles(aHdl, aScAddress);
+ }
+ }
+}
+
+void ScDrawView::InvalidateAttribs()
+{
+ if (!pViewData) return;
+ SfxBindings& rBindings = pViewData->GetBindings();
+
+ // echte Statuswerte:
+ rBindings.InvalidateAll( TRUE );
+}
+
+void ScDrawView::InvalidateDrawTextAttrs()
+{
+ if (!pViewData) return;
+ SfxBindings& rBindings = pViewData->GetBindings();
+
+ // cjk/ctl font items have no configured slots,
+ // need no invalidate
+
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+ rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_10 );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_15 );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_20 );
+ rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
+ rBindings.Invalidate( SID_SET_SUB_SCRIPT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
+ rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+}
+
+//void ScDrawView::DrawMarks( OutputDevice* pOut ) const
+//{
+// DBG_ASSERT(pOut, "ScDrawView::DrawMarks: No OutputDevice (!)");
+// SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
+//
+// if(pPaintWindow)
+// {
+// if(pPaintWindow->isXorVisible())
+// {
+// ToggleShownXor(pOut, 0L);
+// }
+// }
+//}
+
+void ScDrawView::SetMarkedToLayer( BYTE nLayerNo )
+{
+ if (AreObjectsMarked())
+ {
+ // #i11702# use SdrUndoObjectLayerChange for undo
+ // STR_UNDO_SELATTR is "Attributes" - should use a different text later
+ BegUndo( ScGlobal::GetRscString( STR_UNDO_SELATTR ) );
+
+ const SdrMarkList& rMark = GetMarkedObjectList();
+ ULONG nCount = rMark.GetMarkCount();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
+ if ( !pObj->ISA(SdrUnoObj) && (pObj->GetLayer() != SC_LAYER_INTERN) )
+ {
+ AddUndo( new SdrUndoObjectLayerChange( *pObj, pObj->GetLayer(), (SdrLayerID)nLayerNo) );
+ pObj->SetLayer( nLayerNo );
+ }
+ }
+
+ EndUndo();
+
+ // repaint is done in SetLayer
+
+ pViewData->GetDocShell()->SetDrawModified();
+
+ // #84073# check mark list now instead of later in a timer
+ CheckMarked();
+ MarkListHasChanged();
+ }
+}
+
+bool ScDrawView::HasMarkedControl() const
+{
+ SdrObjListIter aIter( GetMarkedObjectList() );
+ for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
+ if( pObj->ISA( SdrUnoObj ) )
+ return true;
+ return false;
+}
+
+bool ScDrawView::HasMarkedInternal() const
+{
+ // internal objects should not be inside a group, but who knows...
+ SdrObjListIter aIter( GetMarkedObjectList() );
+ for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
+ if( pObj->GetLayer() == SC_LAYER_INTERN )
+ return true;
+ return false;
+}
+
+void ScDrawView::UpdateWorkArea()
+{
+ SdrPage* pPage = GetModel()->GetPage(static_cast<sal_uInt16>(nTab));
+ if (pPage)
+ {
+ Point aPos;
+ Size aPageSize( pPage->GetSize() );
+ Rectangle aNewArea( aPos, aPageSize );
+ if ( aPageSize.Width() < 0 )
+ {
+ // RTL: from max.negative (left) to zero (right)
+ aNewArea.Right() = 0;
+ aNewArea.Left() = aPageSize.Width() + 1;
+ }
+ SetWorkArea( aNewArea );
+ }
+ else
+ {
+ DBG_ERROR("Page nicht gefunden");
+ }
+}
+
+void ScDrawView::DoCut()
+{
+ DoCopy();
+ BegUndo( ScGlobal::GetRscString( STR_UNDO_CUT ) );
+ DeleteMarked(); // auf dieser View - von der 505f Umstellung nicht betroffen
+ EndUndo();
+}
+
+void ScDrawView::GetScale( Fraction& rFractX, Fraction& rFractY ) const
+{
+ rFractX = aScaleX;
+ rFractY = aScaleY;
+}
+
+void ScDrawView::RecalcScale()
+{
+ double nPPTX;
+ double nPPTY;
+ Fraction aZoomX(1,1);
+ Fraction aZoomY(1,1);
+
+ if (pViewData)
+ {
+ nTab = pViewData->GetTabNo();
+ nPPTX = pViewData->GetPPTX();
+ nPPTY = pViewData->GetPPTY();
+ aZoomX = pViewData->GetZoomX();
+ aZoomY = pViewData->GetZoomY();
+ }
+ else
+ {
+ Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ nPPTX = aLogic.X() / 1000.0;
+ nPPTY = aLogic.Y() / 1000.0;
+ //! Zoom uebergeben ???
+ }
+
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pDoc->GetTableArea( nTab, nEndCol, nEndRow );
+ if (nEndCol<20)
+ nEndCol = 20;
+ if (nEndRow<20)
+ nEndRow = 1000;
+
+ ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY,
+ aScaleX,aScaleY );
+}
+
+void ScDrawView::DoConnect(SdrOle2Obj* pOleObj)
+{
+ if ( pViewData )
+ pViewData->GetViewShell()->ConnectObject( pOleObj );
+}
+
+void ScDrawView::MarkListHasChanged()
+{
+ FmFormView::MarkListHasChanged();
+
+ UpdateBrowser();
+
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ // #i110829# remove the cell selection only if drawing objects are selected
+ if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() )
+ {
+ pViewSh->Unmark(); // remove cell selection
+
+ // #65379# end cell edit mode if drawing objects are selected
+ SC_MOD()->InputEnterHandler();
+ }
+
+ // IP deaktivieren
+
+ ScModule* pScMod = SC_MOD();
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ ScClient* pClient = (ScClient*) pViewSh->GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
+ {
+ // #41730# beim ViewShell::Activate aus dem Reset2Open nicht die Handles anzeigen
+ //HMHbDisableHdl = TRUE;
+ pClient->DeactivateObject();
+ //HMHbDisableHdl = FALSE;
+ // Image-Ole wieder durch Grafik ersetzen passiert jetzt in ScClient::UIActivate
+ }
+
+ // Ole-Objekt selektiert?
+
+ SdrOle2Obj* pOle2Obj = NULL;
+ SdrGrafObj* pGrafObj = NULL;
+ SdrMediaObj* pMediaObj = NULL;
+
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ ULONG nMarkCount = rMarkList.GetMarkCount();
+
+ if ( nMarkCount == 0 && !pViewData->GetViewShell()->IsDrawSelMode() && !bInConstruct )
+ {
+ // relock layers that may have been unlocked before
+ LockBackgroundLayer();
+ LockInternalLayer();
+ }
+
+ BOOL bSubShellSet = FALSE;
+ if (nMarkCount == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() == OBJ_OLE2)
+ {
+ pOle2Obj = (SdrOle2Obj*) pObj;
+ if (!pDoc->IsChart(pObj) )
+ pViewSh->SetOleObjectShell(TRUE);
+ else
+ pViewSh->SetChartShell(TRUE);
+ bSubShellSet = TRUE;
+ }
+ else if (pObj->GetObjIdentifier() == OBJ_GRAF)
+ {
+ pGrafObj = (SdrGrafObj*) pObj;
+ pViewSh->SetGraphicShell(TRUE);
+ bSubShellSet = TRUE;
+ }
+ else if (pObj->GetObjIdentifier() == OBJ_MEDIA)
+ {
+ pMediaObj = (SdrMediaObj*) pObj;
+ pViewSh->SetMediaShell(TRUE);
+ bSubShellSet = TRUE;
+ }
+ else if (pObj->GetObjIdentifier() != OBJ_TEXT // Verhindern, das beim Anlegen
+ || !pViewSh->IsDrawTextShell()) // eines TextObjekts auf die
+ { // DrawShell umgeschaltet wird.
+ pViewSh->SetDrawShell(TRUE); //@#70206#
+ }
+ }
+
+ if ( nMarkCount && !bSubShellSet )
+ {
+ BOOL bOnlyControls = TRUE;
+ BOOL bOnlyGraf = TRUE;
+ for (ULONG i=0; i<nMarkCount; i++)
+ {
+ SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ if ( pObj->ISA( SdrObjGroup ) )
+ {
+ const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+ ULONG nListCount = pLst->GetObjCount();
+ if ( nListCount == 0 )
+ {
+ // #104156# An empty group (may occur during Undo) is no control or graphics object.
+ // Creating the form shell during undo would lead to problems with the undo manager.
+ bOnlyControls = FALSE;
+ bOnlyGraf = FALSE;
+ }
+ for ( USHORT j = 0; j < nListCount; ++j )
+ {
+ SdrObject *pSubObj = pLst->GetObj( j );
+
+ if (!pSubObj->ISA(SdrUnoObj))
+ bOnlyControls = FALSE;
+ if (pSubObj->GetObjIdentifier() != OBJ_GRAF)
+ bOnlyGraf = FALSE;
+
+ if ( !bOnlyControls && !bOnlyGraf ) break;
+ }
+ }
+ else
+ {
+ if (!pObj->ISA(SdrUnoObj))
+ bOnlyControls = FALSE;
+ if (pObj->GetObjIdentifier() != OBJ_GRAF)
+ bOnlyGraf = FALSE;
+ }
+
+ if ( !bOnlyControls && !bOnlyGraf ) break;
+ }
+
+ if(bOnlyControls)
+ {
+ pViewSh->SetDrawFormShell(TRUE); // jetzt UNO-Controls
+ }
+ else if(bOnlyGraf)
+ {
+ pViewSh->SetGraphicShell(TRUE);
+ }
+ else if(nMarkCount>1)
+ {
+ pViewSh->SetDrawShell(TRUE);
+ }
+ }
+
+
+
+ // Verben anpassen
+
+ SfxViewFrame* pViewFrame = pViewSh->GetViewFrame();
+ BOOL bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace();
+ if ( pOle2Obj && !bOle )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = pOle2Obj->GetObjRef();
+ if (xObj.is())
+ pViewSh->SetVerbs( xObj->getSupportedVerbs() );
+ else
+ {
+ DBG_ERROR("SdrOle2Obj ohne ObjRef");
+ pViewSh->SetVerbs( 0 );
+ }
+ }
+ else
+ pViewSh->SetVerbs( 0 );
+
+ // Image-Map Editor
+
+ if ( pOle2Obj )
+ UpdateIMap( pOle2Obj );
+ else if ( pGrafObj )
+ UpdateIMap( pGrafObj );
+
+ InvalidateAttribs(); // nach dem IMap-Editor Update
+ InvalidateDrawTextAttrs();
+
+ for(sal_uInt32 a(0L); a < PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
+ OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
+
+ if(OUTDEV_WINDOW == rOutDev.GetOutDevType())
+ {
+ ((Window&)rOutDev).Update();
+ }
+ }
+
+ // uno object for view returns drawing objects as selection,
+ // so it must notify its SelectionChangeListeners
+
+ if (pViewFrame)
+ {
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ uno::Reference<frame::XController> xController = rFrame.GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->SelectionChanged();
+ }
+ }
+
+ // update selection transfer object
+
+ pViewSh->CheckSelectionTransfer();
+
+}
+
+void __EXPORT ScDrawView::ModelHasChanged()
+{
+ SdrObject* pEditObj = GetTextEditObject();
+ if ( pEditObj && !pEditObj->IsInserted() && pViewData )
+ {
+ // #111700# SdrObjEditView::ModelHasChanged will end text edit in this case,
+ // so make sure the EditEngine's undo manager is no longer used.
+ pViewData->GetViewShell()->SetDrawTextUndo(NULL);
+ SetCreateMode(); // don't leave FuText in a funny state
+ }
+
+ FmFormView::ModelHasChanged();
+}
+
+void __EXPORT ScDrawView::UpdateUserViewOptions()
+{
+ if (pViewData)
+ {
+ const ScViewOptions& rOpt = pViewData->GetOptions();
+ const ScGridOptions& rGrid = rOpt.GetGridOptions();
+
+ BOOL bBigHdl = rOpt.GetOption( VOPT_BIGHANDLES );
+
+ SetDragStripes( rOpt.GetOption( VOPT_HELPLINES ) );
+ SetSolidMarkHdl( rOpt.GetOption( VOPT_SOLIDHANDLES ) );
+ SetMarkHdlSizePixel( bBigHdl ? SC_HANDLESIZE_BIG : SC_HANDLESIZE_SMALL );
+
+ SetGridVisible( rGrid.GetGridVisible() );
+ SetSnapEnabled( rGrid.GetUseGridSnap() );
+ SetGridSnap( rGrid.GetUseGridSnap() );
+
+ // Snap from grid options is no longer used
+// SetSnapGrid( Size( rGrid.GetFldSnapX(), rGrid.GetFldSnapY() ) );
+
+ Fraction aFractX( rGrid.GetFldDrawX(), rGrid.GetFldDivisionX() + 1 );
+ Fraction aFractY( rGrid.GetFldDrawY(), rGrid.GetFldDivisionY() + 1 );
+ SetSnapGridWidth( aFractX, aFractY );
+
+ SetGridCoarse( Size( rGrid.GetFldDrawX(), rGrid.GetFldDrawY() ) );
+ SetGridFine( Size( rGrid.GetFldDrawX() / (rGrid.GetFldDivisionX() + 1),
+ rGrid.GetFldDrawY() / (rGrid.GetFldDivisionY() + 1) ) );
+ }
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+BOOL ScDrawView::SelectObject( const String& rName )
+{
+ UnmarkAll();
+
+ SCTAB nObjectTab = 0;
+ SdrObject* pFound = NULL;
+
+ SfxObjectShell* pShell = pDoc->GetDocumentShell();
+ if (pShell)
+ {
+ SdrModel* pDrawLayer = GetModel();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount && !pFound; i++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !pFound)
+ {
+ if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
+ {
+ pFound = pObject;
+ nObjectTab = i;
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+
+ if ( pFound )
+ {
+ ScTabView* pView = pViewData->GetView();
+ if ( nObjectTab != nTab ) // Tabelle umschalten
+ pView->SetTabNo( nObjectTab );
+
+ DBG_ASSERT( nTab == nObjectTab, "Tabellen umschalten hat nicht geklappt" );
+
+ pView->ScrollToObject( pFound );
+
+ /* #61585# To select an object on the background layer, the layer has to
+ be unlocked even if exclusive drawing selection mode is not active
+ (this is reversed in MarkListHasChanged when nothing is selected) */
+ if ( pFound->GetLayer() == SC_LAYER_BACK &&
+ !pViewData->GetViewShell()->IsDrawSelMode() &&
+ !pDoc->IsTabProtected( nTab ) &&
+ !pViewData->GetSfxDocShell()->IsReadOnly() )
+ {
+ UnlockBackgroundLayer();
+ }
+
+ SdrPageView* pPV = GetSdrPageView();
+ MarkObj( pFound, pPV );
+ }
+
+ return ( pFound != NULL );
+}
+
+//UNUSED2008-05 String ScDrawView::GetSelectedChartName() const
+//UNUSED2008-05 {
+//UNUSED2008-05 // used for modifying a chart's data area - PersistName must always be used
+//UNUSED2008-05 // (as in ScDocument::FindChartData and UpdateChartArea)
+//UNUSED2008-05
+//UNUSED2008-05 const SdrMarkList& rMarkList = GetMarkedObjectList();
+//UNUSED2008-05 if (rMarkList.GetMarkCount() == 1)
+//UNUSED2008-05 {
+//UNUSED2008-05 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+//UNUSED2008-05 if (pObj->GetObjIdentifier() == OBJ_OLE2)
+//UNUSED2008-05 if ( pDoc->IsChart(pObj) )
+//UNUSED2008-05 return static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return EMPTY_STRING; // nichts gefunden
+//UNUSED2008-05 }
+
+FASTBOOL ScDrawView::InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, ULONG nOptions)
+{
+ // Markierung nicht aendern, wenn Ole-Objekt aktiv
+ // (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
+
+ if (pViewData)
+ {
+ SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ nOptions |= SDRINSERT_DONTMARK;
+ }
+
+ return InsertObjectAtView( pObj, rPV, nOptions );
+}
+
+SdrObject* ScDrawView::GetMarkedNoteCaption( ScDrawObjData** ppCaptData )
+{
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ if( pViewData && (rMarkList.GetMarkCount() == 1) )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, pViewData->GetTabNo() ) )
+ {
+ if( ppCaptData ) *ppCaptData = pCaptData;
+ return pObj;
+ }
+ }
+ return 0;
+}
+
+void ScDrawView::LockCalcLayer( SdrLayerID nLayer, bool bLock )
+{
+ SdrLayer* pLockLayer = GetModel()->GetLayerAdmin().GetLayerPerID( nLayer );
+ if( pLockLayer && (IsLayerLocked( pLockLayer->GetName() ) != bLock) )
+ SetLayerLocked( pLockLayer->GetName(), bLock );
+}
+
+void __EXPORT ScDrawView::MakeVisible( const Rectangle& rRect, Window& rWin )
+{
+ //! rWin richtig auswerten
+ //! ggf Zoom aendern
+
+ if ( pViewData && pViewData->GetActiveWin() == &rWin )
+ pViewData->GetView()->MakeVisible( rRect );
+}
+
+void ScDrawView::DeleteMarked()
+{
+ // try to delete a note caption object with its cell note in the Calc document
+ ScDrawObjData* pCaptData = 0;
+ if( SdrObject* pCaptObj = GetMarkedNoteCaption( &pCaptData ) )
+ {
+ (void)pCaptObj; // prevent 'unused variable' compiler warning in pro builds
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ ScDocShell* pDocShell = pViewData ? pViewData->GetDocShell() : 0;
+ SfxUndoManager* pUndoMgr = pDocShell ? pDocShell->GetUndoManager() : 0;
+ bool bUndo = pDrawLayer && pDocShell && pUndoMgr && pDoc->IsUndoEnabled();
+
+ // remove the cell note from document, we are its owner now
+ ScPostIt* pNote = pDoc->ReleaseNote( pCaptData->maStart );
+ DBG_ASSERT( pNote, "ScDrawView::DeleteMarked - cell note missing in document" );
+ if( pNote )
+ {
+ // rescue note data for undo (with pointer to caption object)
+ ScNoteData aNoteData = pNote->GetNoteData();
+ DBG_ASSERT( aNoteData.mpCaption == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" );
+ // collect the drawing undo action created while deleting the note
+ if( bUndo )
+ pDrawLayer->BeginCalcUndo();
+ // delete the note (already removed from document above)
+ delete pNote;
+ // add the undo action for the note
+ if( bUndo )
+ pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, pCaptData->maStart, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
+ // repaint the cell to get rid of the note marker
+ if( pDocShell )
+ pDocShell->PostPaintCell( pCaptData->maStart );
+ // done, return now to skip call of FmFormView::DeleteMarked()
+ return;
+ }
+ }
+
+ FmFormView::DeleteMarked();
+}
+
+SdrEndTextEditKind ScDrawView::ScEndTextEdit()
+{
+ BOOL bIsTextEdit = IsTextEdit();
+ SdrEndTextEditKind eKind = SdrEndTextEdit();
+
+ if ( bIsTextEdit && pViewData )
+ pViewData->GetViewShell()->SetDrawTextUndo(NULL); // "normaler" Undo-Manager
+
+ return eKind;
+}
+
+void ScDrawView::MarkDropObj( SdrObject* pObj )
+{
+ if ( pDropMarkObj != pObj )
+ {
+ pDropMarkObj = pObj;
+ ImplClearCalcDropMarker();
+
+ if(pDropMarkObj)
+ {
+ pDropMarker = new SdrDropMarkerOverlay(*this, *pDropMarkObj);
+ }
+ }
+}
+
+//UNUSED2009-05 void ScDrawView::CaptionTextDirection( USHORT nSlot )
+//UNUSED2009-05 {
+//UNUSED2009-05 if(nSlot != SID_TEXTDIRECTION_LEFT_TO_RIGHT && nSlot != SID_TEXTDIRECTION_TOP_TO_BOTTOM)
+//UNUSED2009-05 return;
+//UNUSED2009-05
+//UNUSED2009-05 SdrObject* pObject = GetTextEditObject();
+//UNUSED2009-05 if ( ScDrawLayer::IsNoteCaption( pObject ) )
+//UNUSED2009-05 {
+//UNUSED2009-05 if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
+//UNUSED2009-05 {
+//UNUSED2009-05 SfxItemSet aAttr(pCaption->GetMergedItemSet());
+//UNUSED2009-05 aAttr.Put( SvxWritingModeItem(
+//UNUSED2009-05 nSlot == SID_TEXTDIRECTION_LEFT_TO_RIGHT ?
+//UNUSED2009-05 com::sun::star::text::WritingMode_LR_TB : com::sun::star::text::WritingMode_TB_RL,
+//UNUSED2009-05 SDRATTR_TEXTDIRECTION ) );
+//UNUSED2009-05 pCaption->SetMergedItemSet(aAttr);
+//UNUSED2009-05 FuPoor* pPoor = pViewData->GetView()->GetDrawFuncPtr();
+//UNUSED2009-05 if ( pPoor )
+//UNUSED2009-05 {
+//UNUSED2009-05 FuText* pText = static_cast<FuText*>(pPoor);
+//UNUSED2009-05 pText->StopEditMode(TRUE);
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
new file mode 100644
index 000000000000..848a0a3c7636
--- /dev/null
+++ b/sc/source/ui/view/editsh.cxx
@@ -0,0 +1,1206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/clipfmtitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <svl/srchitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/exchange.hxx>
+#include <svtools/cliplistener.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <sot/formats.hxx>
+#include <svtools/transfer.hxx>
+#include <svl/stritem.hxx>
+
+#define _EDITSH_CXX
+#include "editsh.hxx"
+
+#include "scresid.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "viewutil.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+//CHINA001 #include "namepast.hxx"
+#include "reffind.hxx"
+#include "tabvwsh.hxx"
+//CHINA001 #include "textdlgs.hxx"
+#include "editutil.hxx"
+#include "globstr.hrc"
+
+#define ScEditShell
+#include "scslots.hxx"
+
+#include "scui_def.hxx" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+
+
+using namespace ::com::sun::star;
+
+
+TYPEINIT1( ScEditShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScEditShell, SfxShell, ScResId(SCSTR_EDITSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_EDIT) );
+}
+
+
+ScEditShell::ScEditShell(EditView* pView, ScViewData* pData) :
+ pEditView (pView),
+ pViewData (pData),
+ pClipEvtLstnr (NULL),
+ bPastePossible (FALSE),
+ bIsInsertMode (TRUE)
+{
+ SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
+ SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("EditCell")));
+}
+
+ScEditShell::~ScEditShell()
+{
+ if ( pClipEvtLstnr )
+ {
+ pClipEvtLstnr->AddRemoveListener( pViewData->GetActiveWin(), FALSE );
+
+ // #122057# The listener may just now be waiting for the SolarMutex and call the link
+ // afterwards, in spite of RemoveListener. So the link has to be reset, too.
+ pClipEvtLstnr->ClearCallbackLink();
+
+ pClipEvtLstnr->release();
+ }
+}
+
+ScInputHandler* ScEditShell::GetMyInputHdl()
+{
+ return SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
+}
+
+void ScEditShell::SetEditView(EditView* pView)
+{
+ pEditView = pView;
+ pEditView->SetInsertMode( bIsInsertMode );
+ SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
+ SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
+}
+
+void lcl_RemoveAttribs( EditView& rEditView )
+{
+ ScEditEngineDefaulter* pEngine = static_cast<ScEditEngineDefaulter*>(rEditView.GetEditEngine());
+
+ BOOL bOld = pEngine->GetUpdateMode();
+ pEngine->SetUpdateMode(FALSE);
+
+ String aName = ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
+ pEngine->GetUndoManager().EnterListAction( aName, aName );
+
+ rEditView.RemoveAttribs(TRUE);
+ pEngine->RepeatDefaults(); // #97226# paragraph attributes from cell formats must be preserved
+
+ pEngine->GetUndoManager().LeaveListAction();
+
+ pEngine->SetUpdateMode(bOld);
+}
+
+void lclInsertCharacter( EditView* pTableView, EditView* pTopView, sal_Unicode cChar )
+{
+ String aString( cChar );
+ if( pTableView )
+ pTableView->InsertText( aString );
+ if( pTopView )
+ pTopView->InsertText( aString );
+}
+
+void ScEditShell::Execute( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+ SfxBindings& rBindings = pViewData->GetBindings();
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT(pHdl,"kein ScInputHandler");
+
+ EditView* pTopView = pHdl->GetTopView(); // hat Eingabezeile den Focus?
+ EditView* pTableView = pHdl->GetTableView();
+
+ DBG_ASSERT(pTableView,"no EditView :-(");
+ /* #i91683# No EditView if spell-check dialog is active and positioned on
+ * an error and user immediately (without double click or F2) selected a
+ * text portion of that cell with the mouse and wanted to modify it. */
+ /* FIXME: Bailing out only cures the symptom and prevents a crash, no edit
+ * action is possible. A real fix somehow would need to create a valid
+ * EditView from the spell-check view. */
+ if (!pTableView)
+ return;
+
+ EditEngine* pEngine = pTableView->GetEditEngine();
+
+ pHdl->DataChanging();
+ BOOL bSetSelIsRef = FALSE;
+
+ switch ( nSlot )
+ {
+ case FID_INS_CELL_CONTENTS: // Insert-Taste, weil als Acc definiert
+ bIsInsertMode = !pTableView->IsInsertMode();
+ pTableView->SetInsertMode( bIsInsertMode );
+ if (pTopView)
+ pTopView->SetInsertMode( bIsInsertMode );
+ rBindings.Invalidate( SID_ATTR_INSERT );
+ break;
+
+ case SID_ATTR_INSERT:
+ if ( pReqArgs )
+ {
+ bIsInsertMode = ((const SfxBoolItem&)pReqArgs->Get(nSlot)).GetValue();
+ pTableView->SetInsertMode( bIsInsertMode );
+ if (pTopView)
+ pTopView->SetInsertMode( bIsInsertMode );
+ rBindings.Invalidate( SID_ATTR_INSERT );
+ }
+ break;
+
+ case SID_THES:
+ {
+ String aReplaceText;
+ SFX_REQUEST_ARG( rReq, pItem2, SfxStringItem, SID_THES , sal_False );
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (aReplaceText.Len() > 0)
+ ReplaceTextWithSynonym( *pEditView, aReplaceText );
+ }
+ break;
+
+ case SID_COPY:
+ pTableView->Copy();
+ break;
+
+ case SID_CUT:
+ pTableView->Cut();
+ if (pTopView)
+ pTopView->DeleteSelected();
+ break;
+
+ case SID_PASTE:
+ pTableView->PasteSpecial();
+ if (pTopView)
+ pTopView->Paste();
+ break;
+
+ case SID_DELETE:
+ pTableView->DeleteSelected();
+ if (pTopView)
+ pTopView->DeleteSelected();
+ break;
+
+ case SID_CELL_FORMAT_RESET: // "Standard"
+ lcl_RemoveAttribs( *pTableView );
+ if ( pTopView )
+ lcl_RemoveAttribs( *pTopView );
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ ULONG nFormat = 0;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+
+ if ( nFormat )
+ {
+ if (SOT_FORMAT_STRING == nFormat)
+ pTableView->Paste();
+ else
+ pTableView->PasteSpecial();
+
+ if (pTopView)
+ pTopView->Paste();
+ }
+ }
+ break;
+
+ case SID_PASTE_SPECIAL:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( pViewData->GetDialogParent() );
+ ULONG nFormat = 0;
+ if ( pDlg )
+ {
+ pDlg->Insert( SOT_FORMAT_STRING, EMPTY_STRING );
+ pDlg->Insert( SOT_FORMAT_RTF, EMPTY_STRING );
+
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+
+ nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+ DELETEZ(pDlg);
+ }
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ return;
+ }
+
+ if (nFormat > 0)
+ {
+ if (SOT_FORMAT_STRING == nFormat)
+ pTableView->Paste();
+ else
+ pTableView->PasteSpecial();
+
+ if (pTopView)
+ pTopView->Paste();
+ }
+
+ if (pTopView)
+ pTopView->GetWindow()->GrabFocus();
+ }
+ break;
+
+ case SID_SELECTALL:
+ {
+ USHORT nPar = pEngine->GetParagraphCount();
+ if (nPar)
+ {
+ xub_StrLen nLen = pEngine->GetTextLen(nPar-1);
+ pTableView->SetSelection(ESelection(0,0,nPar-1,nLen));
+ if (pTopView)
+ pTopView->SetSelection(ESelection(0,0,nPar-1,nLen));
+ }
+ }
+ break;
+
+ case SID_CHARMAP:
+ {
+ USHORT nScript = pTableView->GetSelectedScriptType();
+ USHORT nFontWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? EE_CHAR_FONTINFO_CJK :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? EE_CHAR_FONTINFO_CTL :
+ EE_CHAR_FONTINFO );
+ const SvxFontItem& rItem = (const SvxFontItem&)
+ pTableView->GetAttribs().Get(nFontWhich);
+
+ String aString;
+ SvxFontItem aNewItem( EE_CHAR_FONTINFO );
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = 0;
+ if( pArgs )
+ pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), FALSE, &pItem);
+
+ if ( pItem )
+ {
+ aString = ((const SfxStringItem*)pItem)->GetValue();
+ const SfxPoolItem* pFtItem = NULL;
+ pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), FALSE, &pFtItem);
+ const SfxStringItem* pFontItem = PTR_CAST( SfxStringItem, pFtItem );
+ if ( pFontItem )
+ {
+ String aFontName(pFontItem->GetValue());
+ Font aFont(aFontName, Size(1,1)); // Size nur wg. CTOR
+ aNewItem = SvxFontItem( aFont.GetFamily(), aFont.GetName(),
+ aFont.GetStyleName(), aFont.GetPitch(),
+ aFont.GetCharSet(), ATTR_FONT );
+ }
+ else
+ aNewItem = rItem;
+ }
+ else
+ {
+ ScViewUtil::ExecuteCharMap( rItem, *pViewData->GetViewShell()->GetViewFrame(), aNewItem, aString );
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ return;
+ }
+ }
+
+ if ( aString.Len() )
+ {
+ // if string contains WEAK characters, set all fonts
+ BYTE nSetScript;
+ ScDocument* pDoc = pViewData->GetDocument();
+ if ( pDoc->HasStringWeakCharacters( aString ) )
+ nSetScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ else
+ nSetScript = pDoc->GetStringScriptType( aString );
+
+ SfxItemSet aSet( pTableView->GetEmptyItemSet() );
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, GetPool() );
+ aSetItem.PutItemForScriptType( nSetScript, aNewItem );
+ aSet.Put( aSetItem.GetItemSet(), FALSE );
+
+ // SetAttribs an der View selektiert ein Wort, wenn nichts selektiert ist
+ pTableView->GetEditEngine()->QuickSetAttribs( aSet, pTableView->GetSelection() );
+ pTableView->InsertText(aString);
+ if (pTopView)
+ pTopView->InsertText(aString);
+
+ SfxStringItem aStringItem( SID_CHARMAP, aString );
+ SfxStringItem aFontItem( SID_ATTR_SPECIALCHAR, aNewItem.GetFamilyName() );
+ rReq.AppendItem( aFontItem );
+ rReq.AppendItem( aStringItem );
+ rReq.Done();
+
+
+ }
+
+ if (pTopView)
+ pTopView->GetWindow()->GrabFocus();
+ }
+ break;
+
+ case FID_INSERT_NAME:
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ //CHINA001 ScNamePasteDlg* pDlg = new ScNamePasteDlg( pViewData->GetDialogParent(),
+ //CHINA001 pDoc->GetRangeName(), FALSE );
+ // "Liste" disablen
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNamePasteDlg* pDlg = pFact->CreateScNamePasteDlg( pViewData->GetDialogParent(), pDoc->GetRangeName(), RID_SCDLG_NAMES_PASTE, FALSE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ short nRet = pDlg->Execute();
+ // pDlg is needed below
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ delete pDlg;
+ return;
+ }
+
+ if ( nRet == BTN_PASTE_NAME )
+ {
+ String aName = pDlg->GetSelectedName();
+ pTableView->InsertText(aName);
+ if (pTopView)
+ pTopView->InsertText(aName);
+ }
+ delete pDlg;
+
+ if (pTopView)
+ pTopView->GetWindow()->GrabFocus();
+ }
+ break;
+
+ case SID_CHAR_DLG:
+ {
+ SfxItemSet aAttrs( pTableView->GetAttribs() );
+
+ SfxObjectShell* pObjSh = pViewData->GetSfxDocShell();
+
+ //CHINA001 ScCharDlg* pDlg = new ScCharDlg( pViewData->GetDialogParent(), &aAttrs, pObjSh );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScCharDlg( pViewData->GetDialogParent(), &aAttrs,
+ pObjSh, RID_SCDLG_CHAR );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ short nRet = pDlg->Execute();
+ // pDlg is needed below
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ delete pDlg;
+ return;
+ }
+
+ if ( nRet == RET_OK )
+ {
+ const SfxItemSet* pOut = pDlg->GetOutputItemSet();
+ pTableView->SetAttribs( *pOut );
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_TOGGLE_REL:
+ {
+ BOOL bOk = FALSE;
+ if (pEngine->GetParagraphCount() == 1)
+ {
+ String aText = pEngine->GetText();
+ ESelection aSel = pEditView->GetSelection(); // aktuelle View
+
+ ScRefFinder aFinder( aText, pViewData->GetDocument() );
+ aFinder.ToggleRel( aSel.nStartPos, aSel.nEndPos );
+ if (aFinder.GetFound())
+ {
+ String aNew = aFinder.GetText();
+ ESelection aNewSel( 0,aFinder.GetSelStart(), 0,aFinder.GetSelEnd() );
+ pEngine->SetText( aNew );
+ pTableView->SetSelection( aNewSel );
+ if ( pTopView )
+ {
+ pTopView->GetEditEngine()->SetText( aNew );
+ pTopView->SetSelection( aNewSel );
+ }
+ bOk = TRUE;
+
+ // Referenz wird selektiert -> beim Tippen nicht ueberschreiben
+ bSetSelIsRef = TRUE;
+ }
+ }
+ if (!bOk)
+ Sound::Beep(); // keine Referenzen oder mehrere Absaetze
+ }
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem;
+ const String& rName = pHyper->GetName();
+ const String& rURL = pHyper->GetURL();
+ const String& rTarget = pHyper->GetTargetFrame();
+ SvxLinkInsertMode eMode = pHyper->GetInsertMode();
+
+ BOOL bDone = FALSE;
+ if ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD )
+ {
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ {
+ // altes Feld selektieren
+
+ ESelection aSel = pTableView->GetSelection();
+ aSel.Adjust();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pTableView->SetSelection( aSel );
+
+ // neues Feld einfuegen
+
+ SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR );
+ aURLField.SetTargetFrame( rTarget );
+ SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
+ pTableView->InsertField( aURLItem );
+ pTableView->SetSelection( aSel ); // select inserted field
+
+ // #57254# jetzt doch auch Felder in der Top-View
+
+ if ( pTopView )
+ {
+ aSel = pTopView->GetSelection();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pTopView->SetSelection( aSel );
+ pTopView->InsertField( aURLItem );
+ pTopView->SetSelection( aSel ); // select inserted field
+ }
+
+ bDone = TRUE;
+ }
+ }
+
+ if (!bDone)
+ {
+ pViewData->GetViewShell()->
+ InsertURL( rName, rURL, rTarget, (USHORT) eMode );
+
+ // InsertURL an der ViewShell schaltet bei "Button"
+ // die EditShell ab, darum sofort return
+
+ return;
+ }
+ }
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ {
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
+ return;
+ }
+ //break;
+
+ case FN_INSERT_SOFT_HYPHEN:
+ lclInsertCharacter( pTableView, pTopView, CHAR_SHY );
+ break;
+ case FN_INSERT_HARDHYPHEN:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NBHY );
+ break;
+ case FN_INSERT_HARD_SPACE:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NBSP );
+ break;
+ case SID_INSERT_RLM:
+ lclInsertCharacter( pTableView, pTopView, CHAR_RLM );
+ break;
+ case SID_INSERT_LRM:
+ lclInsertCharacter( pTableView, pTopView, CHAR_LRM );
+ break;
+ case SID_INSERT_ZWSP:
+ lclInsertCharacter( pTableView, pTopView, CHAR_ZWSP );
+ break;
+ case SID_INSERT_ZWNBSP:
+ lclInsertCharacter( pTableView, pTopView, CHAR_ZWNBSP );
+ break;
+ }
+
+ pHdl->DataChanged();
+ if (bSetSelIsRef)
+ pHdl->SetSelIsRef(TRUE);
+}
+
+void lcl_DisableAll( SfxItemSet& rSet ) // disable all slots
+{
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void __EXPORT ScEditShell::GetState( SfxItemSet& rSet )
+{
+ // #125326# When deactivating the view, edit mode is stopped, but the EditShell is left active
+ // (a shell can't be removed from within Deactivate). In that state, the EditView isn't inserted
+ // into the EditEngine, so it can have an invalid selection and must not be used.
+ if ( !pViewData->HasEditView( pViewData->GetActivePart() ) )
+ {
+ lcl_DisableAll( rSet );
+ return;
+ }
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
+
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_ATTR_INSERT: // Statuszeile
+ {
+ if ( pActiveView )
+ rSet.Put( SfxBoolItem( nWhich, pActiveView->IsInsertMode() ) );
+ else
+ rSet.Put( SfxBoolItem( nWhich, 42 ) );
+ }
+ break;
+
+ case SID_HYPERLINK_GETLINK:
+ {
+ SvxHyperlinkItem aHLinkItem;
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ {
+ aHLinkItem.SetName( pURLField->GetRepresentation() );
+ aHLinkItem.SetURL( pURLField->GetURL() );
+ aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() );
+ }
+ else if ( pActiveView )
+ {
+ // use selected text as name for urls
+ String sReturn = pActiveView->GetSelected();
+ sReturn.Erase(255);
+ sReturn.EraseTrailingChars();
+ aHLinkItem.SetName(sReturn);
+ }
+ rSet.Put(aHLinkItem);
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ {
+ if ( !GetURLField() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAGANA:
+ case SID_INSERT_RLM:
+ case SID_INSERT_LRM:
+ case SID_INSERT_ZWNBSP:
+ case SID_INSERT_ZWSP:
+ ScViewUtil::HideDisabledSlot( rSet, pViewData->GetBindings(), nWhich );
+ break;
+
+ case SID_THES:
+ {
+ String aStatusVal;
+ LanguageType nLang = LANGUAGE_NONE;
+ bool bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, *pActiveView );
+ rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
+
+ // disable thesaurus context menu entry if there is nothing to look up
+ BOOL bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang );
+ if (!bIsLookUpWord || !bCanDoThesaurus)
+ rSet.DisableItem( SID_THES );
+ }
+ break;
+
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+const SvxURLField* ScEditShell::GetURLField()
+{
+ ScInputHandler* pHdl = GetMyInputHdl();
+ EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
+ if ( pActiveView )
+ {
+ const SvxFieldItem* pFieldItem = pActiveView->GetFieldAtSelection();
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ return (const SvxURLField*)pField;
+ }
+ }
+
+ return NULL;
+}
+
+IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
+{
+ if ( pDataHelper )
+ {
+ bPastePossible = ( pDataHelper->HasFormat( SOT_FORMAT_STRING ) || pDataHelper->HasFormat( SOT_FORMAT_RTF ) );
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+ rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ return 0;
+}
+
+void __EXPORT ScEditShell::GetClipState( SfxItemSet& rSet )
+{
+ if ( !pClipEvtLstnr )
+ {
+ // create listener
+ pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScEditShell, ClipboardChanged ) );
+ pClipEvtLstnr->acquire();
+ Window* pWin = pViewData->GetActiveWin();
+ pClipEvtLstnr->AddRemoveListener( pWin, TRUE );
+
+ // get initial state
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+ bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PASTE:
+ case SID_PASTE_SPECIAL:
+ if( !bPastePossible )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ if( bPastePossible )
+ {
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+
+ if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ aFormats.AddClipbrdFormat( SOT_FORMAT_STRING );
+ if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ aFormats.AddClipbrdFormat( SOT_FORMAT_RTF );
+
+ rSet.Put( aFormats );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void lcl_InvalidateUnder( SfxBindings& rBindings )
+{
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+}
+
+void ScEditShell::ExecuteAttr(SfxRequest& rReq)
+{
+ SfxItemSet aSet( pEditView->GetEmptyItemSet() );
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_FONT:
+ {
+ if (pArgs)
+ {
+ // #i78017 establish the same behaviour as in Writer
+ USHORT nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ {
+ nScript = pEditView->GetSelectedScriptType();
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+ }
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ USHORT nWhich = rPool.GetWhich( nSlot );
+ aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
+
+ aSet.Put( aSetItem.GetItemSet(), FALSE );
+ }
+ }
+ break;
+
+ case SID_ATTR_CHAR_COLOR:
+ {
+ if (pArgs)
+ {
+ aSet.Put( pArgs->Get( pArgs->GetPool()->GetWhich( nSlot ) ) );
+ rBindings.Invalidate( nSlot );
+ }
+ }
+ break;
+
+ // Toggles
+
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ USHORT nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+
+ BOOL bOld = FALSE;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), FALSE );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxWeightItem*)pCore)->GetWeight() > WEIGHT_NORMAL )
+ bOld = TRUE;
+
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ aSetItem.PutItemForScriptType( nScript,
+ SvxWeightItem( bOld ? WEIGHT_NORMAL : WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
+ aSet.Put( aSetItem.GetItemSet(), FALSE );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ USHORT nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+
+ BOOL bOld = FALSE;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), FALSE );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxPostureItem*)pCore)->GetValue() != ITALIC_NONE )
+ bOld = TRUE;
+
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ aSetItem.PutItemForScriptType( nScript,
+ SvxPostureItem( bOld ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
+ aSet.Put( aSetItem.GetItemSet(), FALSE );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ULINE_VAL_NONE:
+ aSet.Put( SvxUnderlineItem( UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
+ lcl_InvalidateUnder( rBindings );
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE: // Toggles
+ case SID_ULINE_VAL_SINGLE:
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ FontUnderline eOld = ((const SvxUnderlineItem&) pEditView->
+ GetAttribs().Get(EE_CHAR_UNDERLINE)).GetLineStyle();
+ FontUnderline eNew = eOld;
+ switch (nSlot)
+ {
+ case SID_ATTR_CHAR_UNDERLINE:
+ eNew = ( eOld != UNDERLINE_NONE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == UNDERLINE_SINGLE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == UNDERLINE_DOUBLE ) ? UNDERLINE_NONE : UNDERLINE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == UNDERLINE_DOTTED ) ? UNDERLINE_NONE : UNDERLINE_DOTTED;
+ break;
+ }
+ aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) );
+ lcl_InvalidateUnder( rBindings );
+ }
+ break;
+
+ case SID_ATTR_CHAR_OVERLINE:
+ {
+ FontUnderline eOld = ((const SvxOverlineItem&) pEditView->
+ GetAttribs().Get(EE_CHAR_OVERLINE)).GetLineStyle();
+ FontUnderline eNew = ( eOld != UNDERLINE_NONE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ aSet.Put( SvxOverlineItem( eNew, EE_CHAR_OVERLINE ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_STRIKEOUT:
+ {
+ BOOL bOld = ((const SvxCrossedOutItem&)pEditView->GetAttribs().
+ Get(EE_CHAR_STRIKEOUT)).GetValue() != STRIKEOUT_NONE;
+ aSet.Put( SvxCrossedOutItem( bOld ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_SHADOWED:
+ {
+ BOOL bOld = ((const SvxShadowedItem&)pEditView->GetAttribs().
+ Get(EE_CHAR_SHADOW)).GetValue();
+ aSet.Put( SvxShadowedItem( !bOld, EE_CHAR_SHADOW ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_CONTOUR:
+ {
+ BOOL bOld = ((const SvxContourItem&)pEditView->GetAttribs().
+ Get(EE_CHAR_OUTLINE)).GetValue();
+ aSet.Put( SvxContourItem( !bOld, EE_CHAR_OUTLINE ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_SET_SUPER_SCRIPT:
+ {
+ SvxEscapement eOld = (SvxEscapement) ((const SvxEscapementItem&)
+ pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT)).GetEnumValue();
+ SvxEscapement eNew = (eOld == SVX_ESCAPEMENT_SUPERSCRIPT) ?
+ SVX_ESCAPEMENT_OFF : SVX_ESCAPEMENT_SUPERSCRIPT;
+ aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+ case SID_SET_SUB_SCRIPT:
+ {
+ SvxEscapement eOld = (SvxEscapement) ((const SvxEscapementItem&)
+ pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT)).GetEnumValue();
+ SvxEscapement eNew = (eOld == SVX_ESCAPEMENT_SUBSCRIPT) ?
+ SVX_ESCAPEMENT_OFF : SVX_ESCAPEMENT_SUBSCRIPT;
+ aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+ }
+
+ //
+ // anwenden
+ //
+
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ BOOL bOld = pEngine->GetUpdateMode();
+ pEngine->SetUpdateMode(FALSE);
+
+ pEditView->SetAttribs( aSet );
+
+ pEngine->SetUpdateMode(bOld);
+ pEditView->Invalidate();
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ pHdl->SetModified();
+
+ rReq.Done();
+}
+
+void ScEditShell::GetAttrState(SfxItemSet &rSet)
+{
+ if ( !pViewData->HasEditView( pViewData->GetActivePart() ) ) // #125326#
+ {
+ lcl_DisableAll( rSet );
+ return;
+ }
+
+ SfxItemSet aAttribs = pEditView->GetAttribs();
+ rSet.Put( aAttribs );
+
+ // choose font info according to selection script type
+
+ USHORT nScript = pEditView->GetSelectedScriptType();
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+
+ // #i55929# input-language-dependent script type (depends on input language if nothing selected)
+ USHORT nInputScript = nScript;
+ if ( !pEditView->GetSelection().HasRange() )
+ {
+ LanguageType nInputLang = pViewData->GetActiveWin()->GetInputLanguage();
+ if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ }
+
+ // #i55929# according to spec, nInputScript is used for font and font height only
+ if ( rSet.GetItemState( EE_CHAR_FONTINFO ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTINFO, nInputScript );
+ if ( rSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTHEIGHT, nInputScript );
+ if ( rSet.GetItemState( EE_CHAR_WEIGHT ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_WEIGHT, nScript );
+ if ( rSet.GetItemState( EE_CHAR_ITALIC ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_ITALIC, nScript );
+
+ // Unterstreichung
+
+ SfxItemState eState = aAttribs.GetItemState( EE_CHAR_UNDERLINE, TRUE );
+ if ( eState == SFX_ITEM_DONTCARE )
+ {
+ rSet.InvalidateItem( SID_ULINE_VAL_NONE );
+ rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
+ }
+ else
+ {
+ FontUnderline eUnderline = ((const SvxUnderlineItem&)
+ aAttribs.Get(EE_CHAR_UNDERLINE)).GetLineStyle();
+ USHORT nId = SID_ULINE_VAL_NONE;
+ switch (eUnderline)
+ {
+ case UNDERLINE_SINGLE: nId = SID_ULINE_VAL_SINGLE; break;
+ case UNDERLINE_DOUBLE: nId = SID_ULINE_VAL_DOUBLE; break;
+ case UNDERLINE_DOTTED: nId = SID_ULINE_VAL_DOTTED; break;
+ default:
+ break;
+ }
+ rSet.Put( SfxBoolItem( nId, TRUE ) );
+ }
+
+ //! Testen, ob Klammer-Hervorhebung aktiv ist !!!!
+ ScInputHandler* pHdl = GetMyInputHdl();
+ if ( pHdl && pHdl->IsFormulaMode() )
+ rSet.ClearItem( EE_CHAR_WEIGHT ); // hervorgehobene Klammern hier nicht
+}
+
+String ScEditShell::GetSelectionText( BOOL bWholeWord )
+{
+ String aStrSelection;
+
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) ) // #125326#
+ {
+ if ( bWholeWord )
+ {
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ ESelection aSel = pEditView->GetSelection();
+ String aStrCurrentDelimiters = pEngine->GetWordDelimiters();
+
+ pEngine->SetWordDelimiters( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" .,;\"'")) );
+ aStrSelection = pEngine->GetWord( aSel.nEndPara, aSel.nEndPos );
+ pEngine->SetWordDelimiters( aStrCurrentDelimiters );
+ }
+ else
+ {
+ aStrSelection = pEditView->GetSelected();
+ }
+ }
+
+ return aStrSelection;
+}
+
+void ScEditShell::ExecuteUndo(SfxRequest& rReq)
+{
+ // #81733# Undo must be handled here because it's called for both EditViews
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT(pHdl,"no ScInputHandler");
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ DBG_ASSERT(pTableView,"no EditView");
+
+ pHdl->DataChanging();
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_UNDO:
+ case SID_REDO:
+ {
+ BOOL bIsUndo = ( nSlot == SID_UNDO );
+
+ USHORT nCount = 1;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ nCount = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ for (USHORT i=0; i<nCount; i++)
+ {
+ if ( bIsUndo )
+ {
+ pTableView->Undo();
+ if (pTopView)
+ pTopView->Undo();
+ }
+ else
+ {
+ pTableView->Redo();
+ if (pTopView)
+ pTopView->Redo();
+ }
+ }
+ }
+ break;
+ }
+ pViewData->GetBindings().InvalidateAll(FALSE);
+
+ pHdl->DataChanged();
+}
+
+void ScEditShell::GetUndoState(SfxItemSet &rSet)
+{
+ // Undo state is taken from normal ViewFrame state function
+
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ if ( pViewFrm && GetUndoManager() )
+ {
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ pViewFrm->GetSlotState( nWhich, NULL, &rSet );
+ nWhich = aIter.NextWhich();
+ }
+ }
+
+ // disable if no action in input line EditView
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT(pHdl,"no ScInputHandler");
+ EditView* pTopView = pHdl->GetTopView();
+ if (pTopView)
+ {
+ SfxUndoManager& rTopMgr = pTopView->GetEditEngine()->GetUndoManager();
+ if ( rTopMgr.GetUndoActionCount() == 0 )
+ rSet.DisableItem( SID_UNDO );
+ if ( rTopMgr.GetRedoActionCount() == 0 )
+ rSet.DisableItem( SID_REDO );
+ }
+}
+
+void ScEditShell::ExecuteTrans( SfxRequest& rReq )
+{
+ sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
+ if ( nType )
+ {
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT( pHdl, "no ScInputHandler" );
+
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ DBG_ASSERT( pTableView, "no EditView" );
+
+ pHdl->DataChanging();
+
+ pTableView->TransliterateText( nType );
+ if (pTopView)
+ pTopView->TransliterateText( nType );
+
+ pHdl->DataChanged();
+ }
+}
+
diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx
new file mode 100644
index 000000000000..12a1bb87211b
--- /dev/null
+++ b/sc/source/ui/view/formatsh.cxx
@@ -0,0 +1,2168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+//------------------------------------------------------------------
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+#define _SI_NOSBXCONTROLS
+#define _VCONT_HXX
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#define _ZFORLIST_DECLARE_TABLE
+#include <svl/stritem.hxx>
+#include <svl/zformat.hxx>
+#include <svl/languageoptions.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/numinf.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/templdlg.hxx>
+#include <sfx2/tplpitem.hxx>
+#include <editeng/svxenum.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/shaditem.hxx>
+
+#include "formatsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "docsh.hxx"
+#include "patattr.hxx"
+#include "scmod.hxx"
+//CHINA001 #include "styledlg.hxx"
+#include "attrdlg.hrc"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "printfun.hxx"
+#include "docpool.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+#include "undostyl.hxx"
+
+
+#define ScFormatShell
+#define TableFont
+#define FormatForSelection
+#include "scslots.hxx"
+
+#define Interior
+#include <svx/svxslots.hxx>
+
+#include "scabstdlg.hxx" //CHINA001
+
+namespace {
+
+SvxCellHorJustify lclConvertSlotToHAlign( USHORT nSlot )
+{
+ SvxCellHorJustify eHJustify = SVX_HOR_JUSTIFY_STANDARD;
+ switch( nSlot )
+ {
+ case SID_ALIGN_ANY_HDEFAULT: eHJustify = SVX_HOR_JUSTIFY_STANDARD; break;
+ case SID_ALIGN_ANY_LEFT: eHJustify = SVX_HOR_JUSTIFY_LEFT; break;
+ case SID_ALIGN_ANY_HCENTER: eHJustify = SVX_HOR_JUSTIFY_CENTER; break;
+ case SID_ALIGN_ANY_RIGHT: eHJustify = SVX_HOR_JUSTIFY_RIGHT; break;
+ case SID_ALIGN_ANY_JUSTIFIED: eHJustify = SVX_HOR_JUSTIFY_BLOCK; break;
+ default: DBG_ERRORFILE( "lclConvertSlotToHAlign - invalid slot" );
+ }
+ return eHJustify;
+}
+
+SvxCellVerJustify lclConvertSlotToVAlign( USHORT nSlot )
+{
+ SvxCellVerJustify eVJustify = SVX_VER_JUSTIFY_STANDARD;
+ switch( nSlot )
+ {
+ case SID_ALIGN_ANY_VDEFAULT: eVJustify = SVX_VER_JUSTIFY_STANDARD; break;
+ case SID_ALIGN_ANY_TOP: eVJustify = SVX_VER_JUSTIFY_TOP; break;
+ case SID_ALIGN_ANY_VCENTER: eVJustify = SVX_VER_JUSTIFY_CENTER; break;
+ case SID_ALIGN_ANY_BOTTOM: eVJustify = SVX_VER_JUSTIFY_BOTTOM; break;
+ default: DBG_ERRORFILE( "lclConvertSlotToVAlign - invalid slot" );
+ }
+ return eVJustify;
+}
+
+} // namespace
+
+TYPEINIT1( ScFormatShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScFormatShell, SfxShell, ScResId(SCSTR_FORMATSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_FORMAT));
+
+}
+
+
+ScFormatShell::ScFormatShell(ScViewData* pData) :
+ SfxShell(pData->GetViewShell()),
+ pViewData(pData)
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+
+ SetPool( &pTabViewShell->GetPool() );
+ SfxUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId(HID_SCSHELL_FORMATSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Format")));
+}
+
+ScFormatShell::~ScFormatShell()
+{
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScFormatShell::GetStyleState( SfxItemSet& rSet )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+
+ BOOL bProtected = FALSE;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (pDoc->IsTabProtected(i)) // ueberhaupt eine Tabelle geschuetzt?
+ bProtected = TRUE;
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ USHORT nSlotId = 0;
+
+ while ( nWhich )
+ {
+ nSlotId = SfxItemPool::IsWhich( nWhich )
+ ? GetPool().GetSlotId( nWhich )
+ : nWhich;
+
+ switch ( nSlotId )
+ {
+ case SID_STYLE_APPLY:
+ if ( !pStylePool )
+ rSet.DisableItem( nSlotId );
+ break;
+
+ case SID_STYLE_FAMILY2: // Zellvorlagen
+ {
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
+ pTabViewShell->GetStyleSheetFromMarked();
+
+ if ( pStyleSheet )
+ rSet.Put( SfxTemplateItem( nSlotId, pStyleSheet->GetName() ) );
+ else
+ rSet.Put( SfxTemplateItem( nSlotId, String() ) );
+ }
+ break;
+
+ case SID_STYLE_FAMILY4: // Seitenvorlagen
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ String aPageStyle = pDoc->GetPageStyle( nCurTab );
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)pStylePool->
+ Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+
+ if ( pStyleSheet )
+ rSet.Put( SfxTemplateItem( nSlotId, aPageStyle ) );
+ else
+ rSet.Put( SfxTemplateItem( nSlotId, String() ) );
+ }
+ break;
+
+ case SID_STYLE_WATERCAN:
+ {
+ rSet.Put( SfxBoolItem( nSlotId, SC_MOD()->GetIsWaterCan() ) );
+ }
+ break;
+
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ {
+ ISfxTemplateCommon* pDesigner = SFX_APP()->
+ GetCurrentTemplateCommon(pTabViewShell->GetViewFrame()->GetBindings());
+ BOOL bPage = pDesigner && SFX_STYLE_FAMILY_PAGE == pDesigner->GetActualFamily();
+
+ if ( bProtected || bPage )
+ rSet.DisableItem( nSlotId );
+ }
+ break;
+
+ case SID_STYLE_EDIT:
+ case SID_STYLE_DELETE:
+ {
+ ISfxTemplateCommon* pDesigner = SFX_APP()->
+ GetCurrentTemplateCommon(pTabViewShell->GetViewFrame()->GetBindings());
+ BOOL bPage = pDesigner && SFX_STYLE_FAMILY_PAGE == pDesigner->GetActualFamily();
+
+ if ( bProtected && !bPage )
+ rSet.DisableItem( nSlotId );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScFormatShell::ExecuteStyle( SfxRequest& rReq )
+{
+ // Wenn ToolBar vertikal :
+ if ( !rReq.GetArgs() )
+ {
+ pViewData->GetDispatcher().Execute( SID_STYLE_DESIGNER, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
+ return;
+ }
+
+ //--------------------------------------------------------------------
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const USHORT nSlotId = rReq.GetSlot();
+ const SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScTabViewShell* pTabViewShell= GetViewData()->GetViewShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScModule* pScMod = SC_MOD();
+ String aRefName;
+ BOOL bUndo = pDoc->IsUndoEnabled();
+
+ if ( (nSlotId == SID_STYLE_NEW)
+ || (nSlotId == SID_STYLE_EDIT)
+ || (nSlotId == SID_STYLE_DELETE)
+ || (nSlotId == SID_STYLE_APPLY)
+ || (nSlotId == SID_STYLE_WATERCAN)
+ || (nSlotId == SID_STYLE_FAMILY)
+ || (nSlotId == SID_STYLE_NEW_BY_EXAMPLE)
+ || (nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE) )
+ {
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = NULL;
+
+ BOOL bStyleToMarked = FALSE;
+ BOOL bListAction = FALSE;
+ BOOL bAddUndo = FALSE; // add ScUndoModifyStyle (style modified)
+ ScStyleSaveData aOldData; // for undo/redo
+ ScStyleSaveData aNewData;
+
+ SfxStyleFamily eFamily = SFX_STYLE_FAMILY_PARA;
+ const SfxPoolItem* pFamItem;
+ if ( pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_STYLE_FAMILY, TRUE, &pFamItem ) )
+ eFamily = (SfxStyleFamily)((const SfxUInt16Item*)pFamItem)->GetValue();
+ else
+ if ( pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_STYLE_FAMILYNAME, TRUE, &pFamItem ) )
+ {
+ String sFamily = ((const SfxStringItem*)pFamItem)->GetValue();
+ if (sFamily.CompareToAscii("CellStyles") == COMPARE_EQUAL)
+ eFamily = SFX_STYLE_FAMILY_PARA;
+ else
+ if (sFamily.CompareToAscii("PageStyles") == COMPARE_EQUAL)
+ eFamily = SFX_STYLE_FAMILY_PAGE;
+ }
+
+ String aStyleName;
+ USHORT nRetMask = 0xffff;
+// #96983# only stylist sends focus to sheet
+// BOOL bGrabFocus = ( SID_STYLE_APPLY == nSlotId );
+
+ pStylePool->SetSearchMask( eFamily, SFXSTYLEBIT_ALL );
+
+ switch ( nSlotId )
+ {
+ case SID_STYLE_NEW:
+ {
+ const SfxPoolItem* pNameItem;
+ if (pArgs && SFX_ITEM_SET == pArgs->GetItemState( nSlotId, TRUE, &pNameItem ))
+ aStyleName = ((const SfxStringItem*)pNameItem)->GetValue();
+
+ const SfxPoolItem* pRefItem=NULL;
+ if (pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_STYLE_REFERENCE, TRUE, &pRefItem ))
+ {
+ if(pRefItem!=NULL)
+ aRefName = ((const SfxStringItem*)pRefItem)->GetValue();
+ }
+
+ pStyleSheet = &(pStylePool->Make( aStyleName, eFamily,
+ SFXSTYLEBIT_USERDEF ) );
+
+ if ( pStyleSheet && pStyleSheet->HasParentSupport() )
+ pStyleSheet->SetParent(aRefName);
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ {
+ SFX_REQUEST_ARG( rReq, pNameItem, SfxStringItem, SID_APPLY_STYLE, sal_False );
+ SFX_REQUEST_ARG( rReq, pFamilyItem, SfxStringItem, SID_STYLE_FAMILYNAME, sal_False );
+ if ( pFamilyItem && pNameItem )
+ {
+ com::sun::star::uno::Reference< com::sun::star::style::XStyleFamiliesSupplier > xModel(pDocSh->GetModel(), com::sun::star::uno::UNO_QUERY);
+ try
+ {
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xStyles;
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xCont = xModel->getStyleFamilies();
+ xCont->getByName(pFamilyItem->GetValue()) >>= xStyles;
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xInfo;
+ xStyles->getByName( pNameItem->GetValue() ) >>= xInfo;
+ ::rtl::OUString aUIName;
+ xInfo->getPropertyValue( ::rtl::OUString::createFromAscii("DisplayName") ) >>= aUIName;
+ if ( aUIName.getLength() )
+ rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) );
+ }
+ catch( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ case SID_STYLE_EDIT:
+ case SID_STYLE_DELETE:
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ {
+ const SfxPoolItem* pNameItem;
+ if (pArgs && SFX_ITEM_SET == pArgs->GetItemState( nSlotId, TRUE, &pNameItem ))
+ aStyleName = ((const SfxStringItem*)pNameItem)->GetValue();
+ pStyleSheet = pStylePool->Find( aStyleName, eFamily );
+
+ aOldData.InitFromStyle( pStyleSheet );
+ }
+ break;
+
+ case SID_STYLE_WATERCAN:
+ {
+ BOOL bWaterCan = pScMod->GetIsWaterCan();
+
+ if( !bWaterCan )
+ {
+ const SfxPoolItem* pItem;
+
+ if ( SFX_ITEM_SET ==
+ pArgs->GetItemState( nSlotId, TRUE, &pItem ) )
+ {
+ const SfxStringItem* pStrItem = PTR_CAST(SfxStringItem,pItem);
+ if ( pStrItem )
+ {
+ aStyleName = pStrItem->GetValue();
+ pStyleSheet = pStylePool->Find( aStyleName, eFamily );
+
+ if ( pStyleSheet )
+ {
+ ((ScStyleSheetPool*)pStylePool)->
+ SetActualStyleSheet( pStyleSheet );
+ rReq.Done();
+ }
+ }
+ }
+ }
+
+ if ( !bWaterCan && pStyleSheet )
+ {
+ pScMod->SetWaterCan( TRUE );
+ pTabViewShell->SetActivePointer( Pointer(POINTER_FILL) );
+ rReq.Done();
+ }
+ else
+ {
+ pScMod->SetWaterCan( FALSE );
+ pTabViewShell->SetActivePointer( Pointer(POINTER_ARROW) );
+ rReq.Done();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Neuen Style fuer WaterCan-Mode setzen
+ if ( nSlotId == SID_STYLE_APPLY && pScMod->GetIsWaterCan() && pStyleSheet )
+ ((ScStyleSheetPool*)pStylePool)->SetActualStyleSheet( pStyleSheet );
+
+ switch ( eFamily )
+ {
+ case SFX_STYLE_FAMILY_PARA:
+ {
+ switch ( nSlotId )
+ {
+ case SID_STYLE_DELETE:
+ {
+ if ( pStyleSheet )
+ {
+ pTabViewShell->RemoveStyleSheetInUse( (SfxStyleSheet*)pStyleSheet );
+ pStylePool->Remove( pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ nRetMask = TRUE;
+ bAddUndo = TRUE;
+ rReq.Done();
+ }
+ else
+ nRetMask = FALSE;
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ {
+ if ( pStyleSheet && !pScMod->GetIsWaterCan() )
+ {
+ // Anwenden der Vorlage auf das Dokument
+ pTabViewShell->SetStyleSheetToMarked( (SfxStyleSheet*)pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ {
+ // Vorlage erzeugen/ersetzen durch Attribute
+ // an der Cursor-Position:
+
+ const ScPatternAttr* pAttrItem = NULL;
+
+ // Die Abfrage, ob markiert ist, war hier immer falsch,
+ // darum jetzt gar nicht mehr, und einfach vom Cursor.
+ // Wenn Attribute aus der Selektion genommen werden sollen,
+ // muss noch darauf geachtet werden, Items aus Vorlagen nicht
+ // zu uebernehmen (GetSelectionPattern sammelt auch Items aus
+ // Vorlagen zusammen) (#44748#)
+ // pAttrItem = GetSelectionPattern();
+
+ // ScViewData* pViewData = GetViewData();
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ pAttrItem = pDoc->GetPattern( nCol, nRow, nCurTab );
+
+ SfxItemSet aAttrSet = pAttrItem->GetItemSet();
+ aAttrSet.ClearItem( ATTR_MERGE );
+ aAttrSet.ClearItem( ATTR_MERGE_FLAG );
+ // bedingte Formatierung und Gueltigkeit nicht uebernehmen,
+ // weil sie in der Vorlage nicht editiert werden koennen
+ aAttrSet.ClearItem( ATTR_VALIDDATA );
+ aAttrSet.ClearItem( ATTR_CONDITIONAL );
+
+ if ( SID_STYLE_NEW_BY_EXAMPLE == nSlotId )
+ {
+ if ( bUndo )
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_EDITCELLSTYLE );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ bListAction = TRUE;
+ }
+
+ BOOL bConvertBack = FALSE;
+ SfxStyleSheet* pSheetInUse = (SfxStyleSheet*)
+ pTabViewShell->GetStyleSheetFromMarked();
+
+ // wenn neuer Style vorhanden und in der Selektion
+ // verwendet wird, so darf der Parent nicht uebernommen
+ // werden:
+
+ if ( pStyleSheet && pSheetInUse && pStyleSheet == pSheetInUse )
+ pSheetInUse = NULL;
+
+ // wenn bereits vorhanden, erstmal entfernen...
+ if ( pStyleSheet )
+ {
+ // Style-Pointer zu Namen vor Erase,
+ // weil Zellen sonst ungueltige Pointer
+ // enthalten.
+ //!!! bei Gelenheit mal eine Methode, die
+ // das fuer einen bestimmten Style macht
+ pDoc->StylesToNames();
+ bConvertBack = TRUE;
+ pStylePool->Remove(pStyleSheet);
+ }
+
+ // ...und neu anlegen
+ pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
+ SFXSTYLEBIT_USERDEF );
+
+ // wenn ein Style vorhanden ist, so wird dieser
+ // Parent der neuen Vorlage:
+ if ( pSheetInUse && pStyleSheet->HasParentSupport() )
+ pStyleSheet->SetParent( pSheetInUse->GetName() );
+
+ if ( bConvertBack )
+ // Namen zu Style-Pointer
+ pDoc->UpdStlShtPtrsFrmNms();
+ else
+ pDoc->GetPool()->CellStyleCreated( aStyleName );
+
+ // Attribute uebernehmen und Style anwenden
+ pStyleSheet->GetItemSet().Put( aAttrSet );
+ pTabViewShell->UpdateStyleSheetInUse( (SfxStyleSheet*)pStyleSheet );
+
+ // call SetStyleSheetToMarked after adding the ScUndoModifyStyle
+ // (pStyleSheet pointer is used!)
+ bStyleToMarked = TRUE;
+ }
+ else // ( nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE )
+ {
+ pStyleSheet = (SfxStyleSheet*)pTabViewShell->GetStyleSheetFromMarked();
+
+ if ( pStyleSheet )
+ {
+ aOldData.InitFromStyle( pStyleSheet );
+
+ if ( bUndo )
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_EDITCELLSTYLE );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ bListAction = TRUE;
+ }
+
+ pStyleSheet->GetItemSet().Put( aAttrSet );
+ pTabViewShell->UpdateStyleSheetInUse( (SfxStyleSheet*)pStyleSheet );
+
+ // call SetStyleSheetToMarked after adding the ScUndoModifyStyle
+ // (pStyleSheet pointer is used!)
+ bStyleToMarked = TRUE;
+ }
+ }
+
+ aNewData.InitFromStyle( pStyleSheet );
+ bAddUndo = TRUE;
+ rReq.Done();
+ }
+ break;
+
+ default:
+ break;
+ }
+ } // case SFX_STYLE_FAMILY_PARA:
+ break;
+
+ case SFX_STYLE_FAMILY_PAGE:
+ {
+ switch ( nSlotId )
+ {
+ case SID_STYLE_DELETE:
+ {
+ nRetMask = ( NULL != pStyleSheet );
+ if ( pStyleSheet )
+ {
+ if ( pDoc->RemovePageStyleInUse( pStyleSheet->GetName() ) )
+ {
+ ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(TRUE), nCurTab ).UpdatePages();
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+ pStylePool->Remove( pStyleSheet );
+ rBindings.Invalidate( SID_STYLE_FAMILY4 );
+ pDocSh->SetDocumentModified();
+ bAddUndo = TRUE;
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ {
+ nRetMask = ( NULL != pStyleSheet );
+ if ( pStyleSheet && !pScMod->GetIsWaterCan() )
+ {
+ ScUndoApplyPageStyle* pUndoAction = 0;
+ for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ if( rMark.GetTableSelect( nTab ) )
+ {
+ String aOldName = pDoc->GetPageStyle( nTab );
+ if ( aOldName != aStyleName )
+ {
+ pDoc->SetPageStyle( nTab, aStyleName );
+ ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(TRUE), nTab ).UpdatePages();
+ if( !pUndoAction )
+ pUndoAction = new ScUndoApplyPageStyle( pDocSh, aStyleName );
+ pUndoAction->AddSheetAction( nTab, aOldName );
+ }
+ }
+ }
+ if( pUndoAction )
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( pUndoAction );
+ pDocSh->SetDocumentModified();
+ rBindings.Invalidate( SID_STYLE_FAMILY4 );
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ {
+ const String& rStrCurStyle = pDoc->GetPageStyle( nCurTab );
+
+ if ( rStrCurStyle != aStyleName )
+ {
+ SfxStyleSheetBase* pCurStyle = pStylePool->Find( rStrCurStyle, eFamily );
+ SfxItemSet aAttrSet = pCurStyle->GetItemSet();
+ SCTAB nInTab;
+ BOOL bUsed = pDoc->IsPageStyleInUse( aStyleName, &nInTab );
+
+ // wenn bereits vorhanden, erstmal entfernen...
+ if ( pStyleSheet )
+ pStylePool->Remove( pStyleSheet );
+
+ // ...und neu anlegen
+ pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
+ SFXSTYLEBIT_USERDEF );
+
+ // Attribute uebernehmen
+ pStyleSheet->GetItemSet().Put( aAttrSet );
+ pDocSh->SetDocumentModified();
+
+ // wenn in Verwendung -> Update
+ if ( bUsed )
+ ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(TRUE), nInTab ).UpdatePages();
+
+ aNewData.InitFromStyle( pStyleSheet );
+ bAddUndo = TRUE;
+ rReq.Done();
+ nRetMask = TRUE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ } // switch ( nSlotId )
+ } // case SFX_STYLE_FAMILY_PAGE:
+ break;
+
+ default:
+ break;
+ } // switch ( eFamily )
+
+ // Neu anlegen oder bearbeiten ueber Dialog:
+ if ( nSlotId == SID_STYLE_NEW || nSlotId == SID_STYLE_EDIT )
+ {
+ if ( pStyleSheet )
+ {
+ SvxNumberInfoItem* pNumberInfoItem = NULL;
+
+ SfxStyleFamily eFam = pStyleSheet->GetFamily();
+ // ScDocument* pDoc = GetViewData()->GetDocument();
+ // ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ //CHINA001 ScStyleDlg* pDlg = NULL;
+ SfxAbstractTabDialog* pDlg = NULL; //CHINA001
+ USHORT nRsc = 0;
+
+ // #37034#/#37245# alte Items aus der Vorlage merken
+ SfxItemSet aOldSet = pStyleSheet->GetItemSet();
+ String aOldName = pStyleSheet->GetName();
+
+ switch ( eFam )
+ {
+ case SFX_STYLE_FAMILY_PAGE:
+ nRsc = RID_SCDLG_STYLES_PAGE;
+ break;
+
+ case SFX_STYLE_FAMILY_PARA:
+ default:
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+
+ const SfxPoolItem* pItem;
+ if ( rSet.GetItemState( ATTR_VALUE_FORMAT,
+ FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ // NumberFormat Value aus Value und Language
+ // erzeugen und eintueten
+ ULONG nFormat =
+ ((SfxUInt32Item*)pItem)->GetValue();
+ LanguageType eLang =
+ ((SvxLanguageItem*)&rSet.Get(
+ ATTR_LANGUAGE_FORMAT ))->GetLanguage();
+ ULONG nLangFormat = pDoc->GetFormatTable()->
+ GetFormatForLanguageIfBuiltIn( nFormat, eLang );
+ if ( nLangFormat != nFormat )
+ {
+ SfxUInt32Item aNewItem( ATTR_VALUE_FORMAT, nLangFormat );
+ rSet.Put( aNewItem );
+ aOldSet.Put( aNewItem );
+ // auch in aOldSet fuer Vergleich nach dem Dialog,
+ // sonst geht evtl. eine Aenderung der Sprache verloren
+ }
+ }
+
+ pTabViewShell->MakeNumberInfoItem( pDoc, GetViewData(), &pNumberInfoItem );
+ pDocSh->PutItem( *pNumberInfoItem );
+ nRsc = RID_SCDLG_STYLES_PAR;
+
+ // auf jeden Fall ein SvxBoxInfoItem mit Table = FALSE im Set:
+ // (wenn gar kein Item da ist, loescht der Dialog auch das
+ // BORDER_OUTER SvxBoxItem aus dem Vorlagen-Set)
+
+ if ( rSet.GetItemState( ATTR_BORDER_INNER, FALSE ) != SFX_ITEM_SET )
+ {
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+ aBoxInfoItem.SetTable(FALSE); // keine inneren Linien
+ aBoxInfoItem.SetDist(TRUE);
+ aBoxInfoItem.SetMinDist(FALSE);
+ rSet.Put( aBoxInfoItem );
+ }
+ }
+ break;
+ }
+
+ // If GetDefDialogParent is a dialog, it must be used
+ // (style catalog)
+
+ Window* pParent = Application::GetDefDialogParent();
+ if ( !pParent || !pParent->IsDialog() )
+ {
+ // #107256# GetDefDialogParent currently doesn't return the window
+ // that was set with SetDefDialogParent (but dynamically finds the
+ // topmost parent of the focus window), so IsDialog above is FALSE
+ // even if called from the style catalog.
+ // -> Use NULL if a modal dialog is open, to enable the Dialog's
+ // default parent handling.
+ if ( Application::IsInModalMode() )
+ pParent = NULL;
+ else
+ pParent = pTabViewShell->GetDialogParent();
+ }
+
+ pTabViewShell->SetInFormatDialog(TRUE);
+
+ //CHINA001 pDlg = new ScStyleDlg( pParent, *pStyleSheet, nRsc );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScStyleDlg( pParent, *pStyleSheet, nRsc, nRsc );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ short nResult = pDlg->Execute();
+ pTabViewShell->SetInFormatDialog(FALSE);
+
+ if ( nResult == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ if ( pOutSet )
+ {
+ nRetMask = pStyleSheet->GetMask();
+
+ // #37034#/#37245# Attribut-Vergleiche (frueher in ModifyStyleSheet)
+ // jetzt hier mit den alten Werten (Style ist schon veraendert)
+
+ if ( SFX_STYLE_FAMILY_PARA == eFam )
+ {
+// pDoc->CellStyleChanged( *pStyleSheet, aOldSet );
+
+ SfxItemSet& rNewSet = pStyleSheet->GetItemSet();
+ BOOL bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate(
+ bNumFormatChanged, aOldSet, rNewSet ) )
+ pDoc->InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
+ ULONG nOldFormat = ((const SfxUInt32Item&)aOldSet.
+ Get( ATTR_VALUE_FORMAT )).GetValue();
+ ULONG nNewFormat = ((const SfxUInt32Item&)rNewSet.
+ Get( ATTR_VALUE_FORMAT )).GetValue();
+ if ( nNewFormat != nOldFormat )
+ {
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ const SvNumberformat* pOld = pFormatter->GetEntry( nOldFormat );
+ const SvNumberformat* pNew = pFormatter->GetEntry( nNewFormat );
+ if ( pOld && pNew && pOld->GetLanguage() != pNew->GetLanguage() )
+ rNewSet.Put( SvxLanguageItem(
+ pNew->GetLanguage(), ATTR_LANGUAGE_FORMAT ) );
+ }
+
+ pDoc->GetPool()->CellStyleCreated( pStyleSheet->GetName() );
+ }
+ else
+ {
+ //! auch fuer Seitenvorlagen die Abfragen hier
+
+ String aNewName = pStyleSheet->GetName();
+ if ( aNewName != aOldName &&
+ pDoc->RenamePageStyleInUse( aOldName, aNewName ) )
+ {
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+
+ pDoc->ModifyStyleSheet( *pStyleSheet, *pOutSet );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+
+ pDocSh->SetDocumentModified();
+
+ if ( SFX_STYLE_FAMILY_PARA == eFam )
+ {
+ pTabViewShell->UpdateNumberFormatter( pDoc,
+ (const SvxNumberInfoItem&)
+ *(pDocSh->GetItem(SID_ATTR_NUMBERFORMAT_INFO)) );
+
+ pTabViewShell->UpdateStyleSheetInUse( (SfxStyleSheet*)pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ }
+
+ aNewData.InitFromStyle( pStyleSheet );
+ bAddUndo = TRUE;
+ }
+ }
+ else
+ {
+ if ( nSlotId == SID_STYLE_NEW )
+ pStylePool->Remove( pStyleSheet );
+ else
+ {
+ // falls zwischendurch etwas mit dem temporaer geaenderten
+ // ItemSet gepainted wurde:
+ pDocSh->PostPaintGridAll();
+ }
+ }
+ delete pDlg;
+ }
+ }
+
+// if ( nRetMask != 0xffff )// Irgendein Wert MUSS geliefert werden JN
+ rReq.SetReturnValue( SfxUInt16Item( nSlotId, nRetMask ) );
+
+// #96983# only stylist sends focus to sheet
+// if ( bGrabFocus )
+// pTabViewShell->GetActiveWin()->GrabFocus();
+
+ if ( bAddUndo && bUndo)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( pDocSh, eFamily, aOldData, aNewData ) );
+
+ if ( bStyleToMarked )
+ {
+ // call SetStyleSheetToMarked after adding the ScUndoModifyStyle,
+ // so redo will find the modified style
+ pTabViewShell->SetStyleSheetToMarked( (SfxStyleSheet*)pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ }
+
+ if ( bListAction )
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ else
+ {
+ DBG_ERROR( "Unknown slot (ScViewShell::ExecuteStyle)" );
+ }
+}
+
+void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq )
+{
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ // Eingabe beenden
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ switch ( nSlot )
+ {
+ case SID_NUMBER_TWODEC:
+ case SID_NUMBER_SCIENTIFIC:
+ case SID_NUMBER_DATE:
+ case SID_NUMBER_CURRENCY:
+ case SID_NUMBER_PERCENT:
+ case SID_NUMBER_STANDARD:
+ case SID_NUMBER_FORMAT:
+ case SID_NUMBER_INCDEC:
+ case SID_NUMBER_DECDEC:
+ case FID_DEFINE_NAME:
+ case FID_USE_NAME:
+ case FID_INSERT_NAME:
+ case SID_SPELL_DIALOG:
+ case SID_HANGUL_HANJA_CONVERSION:
+
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ( nSlot )
+ {
+ case SID_NUMBER_TWODEC:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER, 4 ); // Standard+4 = #.##0,00
+ rReq.Done();
+ break;
+ case SID_NUMBER_SCIENTIFIC:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_SCIENTIFIC );
+ rReq.Done();
+ break;
+ case SID_NUMBER_DATE:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_DATE );
+ rReq.Done();
+ break;
+ case SID_NUMBER_TIME:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_TIME );
+ rReq.Done();
+ break;
+ case SID_NUMBER_CURRENCY:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_CURRENCY );
+ rReq.Done();
+ break;
+ case SID_NUMBER_PERCENT:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_PERCENT );
+ rReq.Done();
+ break;
+ case SID_NUMBER_STANDARD:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER );
+ rReq.Done();
+ break;
+ case SID_NUMBER_INCDEC:
+ pTabViewShell->ChangeNumFmtDecimals( TRUE );
+ rReq.Done();
+ break;
+ case SID_NUMBER_DECDEC:
+ pTabViewShell->ChangeNumFmtDecimals( FALSE );
+ rReq.Done();
+ break;
+
+ case SID_NUMBER_FORMAT:
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if(pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET)
+ {
+ String aCode = ((const SfxStringItem*)pItem)->GetValue();
+ pTabViewShell->SetNumFmtByStr( aCode );
+ }
+ }
+ break;
+
+ case SID_ATTR_NUMBERFORMAT_VALUE:
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( ATTR_VALUE_FORMAT, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ // We have to accomplish this using ApplyAttributes()
+ // because we also need the language information to be
+ // considered.
+ const SfxItemSet& rOldSet =
+ pTabViewShell->GetSelectionPattern()->GetItemSet();
+ SfxItemPool* pDocPool = GetViewData()->GetDocument()->GetPool();
+ SfxItemSet aNewSet( *pDocPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
+ aNewSet.Put( *pItem );
+ pTabViewShell->ApplyAttributes( &aNewSet, &rOldSet, TRUE );
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR("falscher Slot bei ExecuteEdit");
+ break;
+ }
+}
+
+
+//------------------------------------------------------------------
+
+#define APPLY_HOR_JUSTIFY(j) \
+ { \
+ if ( !pHorJustify || (eHorJustify != (j) ) ) \
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( (j) ) ); \
+ else \
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD ) ); \
+ }
+
+#define APPLY_VER_JUSTIFY(j) \
+ { \
+ if ( !pVerJustify || (eVerJustify != (j) ) ) \
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( (j) ) ); \
+ else \
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( SVX_VER_JUSTIFY_STANDARD ) ); \
+ }
+
+void ScFormatShell::ExecuteAlignment( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pSet = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ switch( nSlot )
+ {
+ // pseudo slots for Format menu
+ case SID_ALIGN_ANY_HDEFAULT:
+ case SID_ALIGN_ANY_LEFT:
+ case SID_ALIGN_ANY_HCENTER:
+ case SID_ALIGN_ANY_RIGHT:
+ case SID_ALIGN_ANY_JUSTIFIED:
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( lclConvertSlotToHAlign( nSlot ), ATTR_HOR_JUSTIFY ) );
+ break;
+ case SID_ALIGN_ANY_VDEFAULT:
+ case SID_ALIGN_ANY_TOP:
+ case SID_ALIGN_ANY_VCENTER:
+ case SID_ALIGN_ANY_BOTTOM:
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( lclConvertSlotToVAlign( nSlot ), ATTR_VER_JUSTIFY ) );
+ break;
+
+ default:
+ if( pSet )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if( pSet->GetItemState(GetPool().GetWhich(nSlot), TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_ALIGN_HOR_JUSTIFY:
+ case SID_ATTR_ALIGN_VER_JUSTIFY:
+ case SID_ATTR_ALIGN_INDENT:
+ case SID_ATTR_ALIGN_HYPHENATION:
+ case SID_ATTR_ALIGN_DEGREES:
+ case SID_ATTR_ALIGN_LOCKPOS:
+ case SID_ATTR_ALIGN_MARGIN:
+ case SID_ATTR_ALIGN_STACKED:
+ pTabViewShell->ApplyAttr( *pItem );
+ break;
+
+ case SID_H_ALIGNCELL:
+ {
+ SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem*)pItem)->GetValue();
+ // #i78476# update alignment of text in cell edit mode
+ pTabViewShell->UpdateInputHandlerCellAdjust( eJust );
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( eJust, ATTR_HOR_JUSTIFY ) );
+ }
+ break;
+ case SID_V_ALIGNCELL:
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( (SvxCellVerJustify)((const SvxVerJustifyItem*)pItem)->GetValue(), ATTR_VER_JUSTIFY ) );
+ break;
+ default:
+ DBG_ERROR( "ExecuteAlignment: invalid slot" );
+ return;
+ }
+ }
+ }
+ }
+
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ALIGNTOP );
+ rBindings.Invalidate( SID_ALIGNBOTTOM );
+ rBindings.Invalidate( SID_ALIGNCENTERVER );
+ rBindings.Invalidate( SID_V_ALIGNCELL );
+ rBindings.Invalidate( SID_H_ALIGNCELL );
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+ rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_TOP );
+ rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
+ rBindings.Update();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+}
+
+void ScFormatShell::ExecuteTextAttr( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
+ const SfxItemSet* pSet = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+ SfxAllItemSet* pNewSet = 0;
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( (nSlot == SID_ATTR_CHAR_WEIGHT)
+ ||(nSlot == SID_ATTR_CHAR_POSTURE)
+ ||(nSlot == SID_ATTR_CHAR_UNDERLINE)
+ ||(nSlot == SID_ULINE_VAL_NONE)
+ ||(nSlot == SID_ULINE_VAL_SINGLE)
+ ||(nSlot == SID_ULINE_VAL_DOUBLE)
+ ||(nSlot == SID_ULINE_VAL_DOTTED) )
+ {
+ pNewSet = new SfxAllItemSet( GetPool() );
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ BYTE nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ if ( pSet )
+ aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_WEIGHT ) );
+ else
+ {
+ // toggle manually
+
+ FontWeight eWeight = WEIGHT_BOLD;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), FALSE );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxWeightItem*)pCore)->GetWeight() == WEIGHT_BOLD )
+ eWeight = WEIGHT_NORMAL;
+
+ aSetItem.PutItemForScriptType( nScript, SvxWeightItem( eWeight, ATTR_FONT_WEIGHT ) );
+ }
+ pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
+ pNewSet->Put( aSetItem.GetItemSet(), FALSE );
+ }
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ BYTE nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ if ( pSet )
+ aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_POSTURE ) );
+ else
+ {
+ // toggle manually
+
+ FontItalic eItalic = ITALIC_NORMAL;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), FALSE );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxPostureItem*)pCore)->GetPosture() == ITALIC_NORMAL )
+ eItalic = ITALIC_NONE;
+
+ aSetItem.PutItemForScriptType( nScript, SvxPostureItem( eItalic, ATTR_FONT_POSTURE ) );
+ }
+ pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
+ pNewSet->Put( aSetItem.GetItemSet(), FALSE );
+ }
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ {
+ FontUnderline eUnderline;
+
+ if( pSet )
+ {
+ const SvxUnderlineItem& rUnderline = (const SvxUnderlineItem&)pSet->Get( ATTR_FONT_UNDERLINE );
+
+ if( rUnderline.ISA(SvxUnderlineItem) )
+ {
+ pTabViewShell->ApplyAttr( rUnderline );
+ pNewSet->Put( rUnderline,rUnderline.Which() );
+ }
+ }
+ else
+ {
+ SvxUnderlineItem aUnderline( (const SvxUnderlineItem&)
+ pAttrs->GetItem(
+ ATTR_FONT_UNDERLINE ) );
+ eUnderline = (UNDERLINE_NONE != aUnderline.GetLineStyle())
+ ? UNDERLINE_NONE
+ : UNDERLINE_SINGLE;
+ aUnderline.SetLineStyle( eUnderline );
+ pTabViewShell->ApplyAttr( aUnderline );
+ pNewSet->Put( aUnderline,aUnderline.Which() );
+ }
+ }
+ break;
+
+ case SID_ULINE_VAL_NONE:
+ pTabViewShell->ApplyAttr( SvxUnderlineItem( UNDERLINE_NONE, ATTR_FONT_UNDERLINE ) );
+ break;
+ case SID_ULINE_VAL_SINGLE: // Toggles
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ FontUnderline eOld = ((const SvxUnderlineItem&)
+ pAttrs->GetItem(ATTR_FONT_UNDERLINE)).GetLineStyle();
+ FontUnderline eNew = eOld;
+ switch (nSlot)
+ {
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == UNDERLINE_SINGLE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == UNDERLINE_DOUBLE ) ? UNDERLINE_NONE : UNDERLINE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == UNDERLINE_DOTTED ) ? UNDERLINE_NONE : UNDERLINE_DOTTED;
+ break;
+ }
+ pTabViewShell->ApplyAttr( SvxUnderlineItem( eNew, ATTR_FONT_UNDERLINE ) );
+ }
+ break;
+
+ default:
+ break;
+ }
+ rBindings.Invalidate( nSlot );
+ }
+ else
+ {
+ /*
+ * "Selbstgemachte" RadioButton-Funktionalitaet
+ * Beim Toggle gibt es den Standard-State, d.h. kein
+ * Button ist gedrueckt
+ */
+
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ const SfxPoolItem* pItem = NULL;
+ const SvxHorJustifyItem* pHorJustify = NULL;
+ const SvxVerJustifyItem* pVerJustify = NULL;
+ SvxCellHorJustify eHorJustify = SVX_HOR_JUSTIFY_STANDARD;
+ SvxCellVerJustify eVerJustify = SVX_VER_JUSTIFY_STANDARD;
+
+ if (rAttrSet.GetItemState(ATTR_HOR_JUSTIFY, TRUE,&pItem ) == SFX_ITEM_SET)
+ {
+ pHorJustify = (const SvxHorJustifyItem*)pItem;
+ eHorJustify = SvxCellHorJustify( pHorJustify->GetValue() );
+ }
+ if (rAttrSet.GetItemState(ATTR_VER_JUSTIFY, TRUE,&pItem ) == SFX_ITEM_SET)
+ {
+ pVerJustify = (const SvxVerJustifyItem*)pItem;
+ eVerJustify = SvxCellVerJustify( pVerJustify->GetValue() );
+ }
+
+ switch ( nSlot )
+ {
+ case SID_ALIGNLEFT:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_LEFT) ?
+ SVX_HOR_JUSTIFY_LEFT : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_LEFT );
+ //break;
+
+ case SID_ALIGNRIGHT:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_RIGHT) ?
+ SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_RIGHT );
+ //break;
+
+ case SID_ALIGNCENTERHOR:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_CENTER) ?
+ SVX_HOR_JUSTIFY_CENTER : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_CENTER );
+ //break;
+
+ case SID_ALIGNBLOCK:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_BLOCK) ?
+ SVX_HOR_JUSTIFY_BLOCK : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_BLOCK );
+ //break;
+
+ case SID_ALIGNTOP:
+ rReq.SetSlot( SID_V_ALIGNCELL );
+ rReq.AppendItem( SvxVerJustifyItem(
+ !pVerJustify || (eVerJustify != SVX_VER_JUSTIFY_TOP) ?
+ SVX_VER_JUSTIFY_TOP : SVX_VER_JUSTIFY_STANDARD, SID_V_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_VER_JUSTIFY( SVX_VER_JUSTIFY_TOP );
+ //break;
+
+ case SID_ALIGNBOTTOM:
+ rReq.SetSlot( SID_V_ALIGNCELL );
+ rReq.AppendItem( SvxVerJustifyItem(
+ !pVerJustify || (eVerJustify != SVX_VER_JUSTIFY_BOTTOM) ?
+ SVX_VER_JUSTIFY_BOTTOM : SVX_VER_JUSTIFY_STANDARD, SID_V_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_VER_JUSTIFY( SVX_VER_JUSTIFY_BOTTOM );
+ //break;
+
+ case SID_ALIGNCENTERVER:
+ rReq.SetSlot( SID_V_ALIGNCELL );
+ rReq.AppendItem( SvxVerJustifyItem(
+ !pVerJustify || (eVerJustify != SVX_VER_JUSTIFY_CENTER) ?
+ SVX_VER_JUSTIFY_CENTER : SVX_VER_JUSTIFY_STANDARD, SID_V_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_VER_JUSTIFY( SVX_VER_JUSTIFY_CENTER );
+ //break;
+
+ default:
+ break;
+ }
+
+ }
+
+ rBindings.Update();
+// rReq.Done();
+
+ if( pNewSet )
+ {
+ rReq.Done( *pNewSet );
+ delete pNewSet;
+ }
+ else
+ {
+ rReq.Done();
+ }
+
+}
+
+#undef APPLY_HOR_JUSTIFY
+#undef APPLY_VER_JUSTIFY
+
+//------------------------------------------------------------------
+
+void ScFormatShell::ExecuteAttr( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pNewAttrs = rReq.GetArgs();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( !pNewAttrs )
+ {
+ USHORT nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ pTabViewShell->ExecuteCellFormatDlg( rReq, TP_FONT ); // wenn ToolBar vertikal
+ break;
+
+ case SID_ATTR_ALIGN_LINEBREAK: // ohne Parameter als Toggle
+ {
+ const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
+ BOOL bOld = ((const SfxBoolItem&)pAttrs->GetItem(ATTR_LINEBREAK)).GetValue();
+ SfxBoolItem aBreakItem( ATTR_LINEBREAK, !bOld );
+ pTabViewShell->ApplyAttr( aBreakItem );
+
+ SfxAllItemSet aNewSet( GetPool() );
+ aNewSet.Put( aBreakItem,aBreakItem.Which() );
+ rReq.Done( aNewSet );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_BACKGROUND_COLOR:
+ {
+ // SID_BACKGROUND_COLOR without arguments -> set transparent background
+
+ SvxBrushItem aBrushItem( (const SvxBrushItem&)
+ pTabViewShell->GetSelectionPattern()->
+ GetItem( ATTR_BACKGROUND ) );
+
+ aBrushItem.SetColor( COL_TRANSPARENT );
+
+ pTabViewShell->ApplyAttr( aBrushItem );
+ }
+ break;
+ }
+ }
+ else
+ {
+ USHORT nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_OVERLINE:
+ case SID_ATTR_CHAR_STRIKEOUT:
+ case SID_ATTR_ALIGN_LINEBREAK:
+ case SID_ATTR_CHAR_COLOR:
+ case SID_ATTR_CHAR_CONTOUR:
+ case SID_ATTR_CHAR_SHADOWED:
+ case SID_ATTR_CHAR_RELIEF:
+ case SID_SCATTR_PROTECTION :
+ pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhich( nSlot ) ) );
+ rBindings.Invalidate( nSlot );
+ rBindings.Update( nSlot );
+ break;
+
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ BYTE nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ nScript = pTabViewShell->GetSelectionScriptType();
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ USHORT nWhich = rPool.GetWhich( nSlot );
+ aSetItem.PutItemForScriptType( nScript, pNewAttrs->Get( nWhich ) );
+
+ pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
+
+ rBindings.Invalidate( nSlot );
+ rBindings.Update( nSlot );
+ }
+ break;
+
+ case SID_FRAME_LINESTYLE:
+ {
+ // Default-Linie aktualisieren
+ const SvxBorderLine* pLine =
+ ((const SvxLineItem&)
+ pNewAttrs->Get( SID_FRAME_LINESTYLE )).
+ GetLine();
+
+ if ( pLine )
+ {
+ SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
+
+ if ( pDefLine )
+ {
+ pDefLine->SetOutWidth( pLine->GetOutWidth() );
+ pDefLine->SetInWidth ( pLine->GetInWidth() );
+ pDefLine->SetDistance( pLine->GetDistance() );
+ pTabViewShell->SetSelectionFrameLines( pDefLine, FALSE );
+ }
+ else
+ {
+ pTabViewShell->SetDefaultFrameLine( pLine );
+ pTabViewShell->GetDefaultFrameLine()->SetColor( COL_BLACK );
+ pTabViewShell->SetSelectionFrameLines( pLine, FALSE );
+ }
+ }
+ else
+ {
+ Color aColorBlack( COL_BLACK );
+ SvxBorderLine aDefLine( &aColorBlack, 20, 0, 0 );
+ pTabViewShell->SetDefaultFrameLine( &aDefLine );
+ pTabViewShell->SetSelectionFrameLines( NULL, FALSE );
+ }
+ }
+ break;
+
+ case SID_FRAME_LINECOLOR:
+ {
+ SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
+ const Color& rColor = ((const SvxColorItem&)
+ pNewAttrs->Get( SID_FRAME_LINECOLOR )).
+ GetValue();
+
+ // Default-Linie aktualisieren
+ if ( pDefLine )
+ {
+ pDefLine->SetColor( rColor );
+ pTabViewShell->SetSelectionFrameLines( pDefLine, TRUE );
+ }
+ else
+ {
+ SvxBorderLine aDefLine( &rColor, 20, 0, 0 );
+ pTabViewShell->SetDefaultFrameLine( &aDefLine );
+ pTabViewShell->SetSelectionFrameLines( &aDefLine, FALSE );
+ }
+ }
+ break;
+
+ case SID_ATTR_BORDER_OUTER:
+ case SID_ATTR_BORDER:
+ {
+ SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
+ const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxItemSet* pOldSet =
+ new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ SfxItemSet* pNewSet =
+ new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ const SfxPoolItem& rBorderAttr =
+ pOldAttrs->GetItemSet().
+ Get( ATTR_BORDER );
+
+ // Border-Items vom Controller auswerten:
+ const SfxPoolItem* pItem = 0;
+
+ if ( pNewAttrs->GetItemState( ATTR_BORDER, TRUE, &pItem )
+ == SFX_ITEM_SET )
+ {
+ // #100959# The SvxFrameToolBoxControl toolbox controller uses a default
+ // SvxBorderLine (all widths 0) to mark the lines that should be set.
+ // Macro recording uses a SvxBoxItem with the real values (OutWidth > 0)
+ // or NULL pointers for no lines.
+ // -> Substitute existing lines with pDefLine only if widths are 0.
+ SvxBoxItem aBoxItem ( *(const SvxBoxItem*)pItem );
+ if ( aBoxItem.GetTop() && aBoxItem.GetTop()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_TOP );
+ if ( aBoxItem.GetBottom() && aBoxItem.GetBottom()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_BOTTOM );
+ if ( aBoxItem.GetLeft() && aBoxItem.GetLeft()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_LEFT );
+ if ( aBoxItem.GetRight() && aBoxItem.GetRight()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_RIGHT );
+ pNewSet->Put( aBoxItem );
+ rReq.AppendItem( aBoxItem );
+ }
+
+ if ( pNewAttrs->GetItemState( ATTR_BORDER_INNER, TRUE, &pItem )
+ == SFX_ITEM_SET )
+ {
+ SvxBoxInfoItem aBoxInfoItem( *(const SvxBoxInfoItem*)pItem );
+ if ( aBoxInfoItem.GetHori() && aBoxInfoItem.GetHori()->GetOutWidth() == 0 )
+ aBoxInfoItem.SetLine( pDefLine, BOXINFO_LINE_HORI );
+ if ( aBoxInfoItem.GetVert() && aBoxInfoItem.GetVert()->GetOutWidth() == 0 )
+ aBoxInfoItem.SetLine( pDefLine, BOXINFO_LINE_VERT );
+ pNewSet->Put( aBoxInfoItem );
+ rReq.AppendItem( aBoxInfoItem );
+ }
+ else
+ {
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+ aBoxInfoItem.SetLine( NULL, BOXINFO_LINE_HORI );
+ aBoxInfoItem.SetLine( NULL, BOXINFO_LINE_VERT );
+ pNewSet->Put( aBoxInfoItem );
+ }
+
+ pOldSet->Put( rBorderAttr );
+ pTabViewShell->ApplyAttributes( pNewSet, pOldSet );
+
+ delete pOldSet;
+ delete pNewSet;
+ }
+ break;
+
+ // ATTR_BACKGROUND (=SID_ATTR_BRUSH) muss ueber zwei IDs
+ // gesetzt werden:
+ case SID_BACKGROUND_COLOR:
+ {
+ const SvxColorItem rNewColorItem = (const SvxColorItem&)
+ pNewAttrs->Get( SID_BACKGROUND_COLOR );
+
+ SvxBrushItem aBrushItem( (const SvxBrushItem&)
+ pTabViewShell->GetSelectionPattern()->
+ GetItem( ATTR_BACKGROUND ) );
+
+ aBrushItem.SetColor( rNewColorItem.GetValue() );
+
+ pTabViewShell->ApplyAttr( aBrushItem );
+ }
+ break;
+
+ case SID_ATTR_BRUSH:
+ {
+ SvxBrushItem aBrushItem( (const SvxBrushItem&)
+ pTabViewShell->GetSelectionPattern()->
+ GetItem( ATTR_BACKGROUND ) );
+ const SvxBrushItem& rNewBrushItem = (const SvxBrushItem&)
+ pNewAttrs->Get( GetPool().GetWhich(nSlot) );
+ aBrushItem.SetColor(rNewBrushItem.GetColor());
+ pTabViewShell->ApplyAttr( aBrushItem );
+ }
+ break;
+
+ case SID_ATTR_BORDER_SHADOW:
+ {
+ const SvxShadowItem& rNewShadowItem = (const SvxShadowItem&)
+ pNewAttrs->Get( ATTR_SHADOW );
+ pTabViewShell->ApplyAttr( rNewShadowItem );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( ! rReq.IsAPI() )
+ if( ! rReq.IsDone() )
+ rReq.Done();
+ }
+}
+
+void ScFormatShell::GetAttrState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ const SvxBorderLine* pLine = pTabViewShell->GetDefaultFrameLine();
+ const SvxBrushItem& rBrushItem = (const SvxBrushItem&)rAttrSet.Get( ATTR_BACKGROUND );
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+
+ rSet.Put( rAttrSet, FALSE );
+
+ // choose font info according to selection script type
+ BYTE nScript = 0; // GetSelectionScriptType never returns 0
+ if ( rSet.GetItemState( ATTR_FONT ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT, nScript );
+ }
+ if ( rSet.GetItemState( ATTR_FONT_HEIGHT ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_HEIGHT, nScript );
+ }
+
+ while ( nWhich )
+ {
+ switch(nWhich)
+ {
+ case SID_BACKGROUND_COLOR:
+ {
+ rSet.Put( SvxColorItem( rBrushItem.GetColor(), SID_BACKGROUND_COLOR ) );
+ }
+ break;
+ case SID_FRAME_LINECOLOR:
+ {
+ rSet.Put( SvxColorItem( pLine ? pLine->GetColor() : Color(), SID_FRAME_LINECOLOR ) );
+ }
+ break;
+ case SID_ATTR_BRUSH:
+ {
+ rSet.Put( rBrushItem, GetPool().GetWhich(nWhich) );
+ }
+ break;
+/* case SID_ATTR_ALIGN_LINEBREAK:
+ {
+ const SfxBoolItem& rBreakItem = (const SfxBoolItem&)rAttrSet.Get( ATTR_LINEBREAK );
+ rSet.Put( rBreakItem, GetPool().GetWhich(nWhich) );
+ }
+ break;
+*/
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScFormatShell::GetTextAttrState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ rSet.Put( rAttrSet, FALSE ); // ItemStates mitkopieren
+
+ // choose font info according to selection script type
+ BYTE nScript = 0; // GetSelectionScriptType never returns 0
+ if ( rSet.GetItemState( ATTR_FONT_WEIGHT ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_WEIGHT, nScript );
+ }
+ if ( rSet.GetItemState( ATTR_FONT_POSTURE ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_POSTURE, nScript );
+ }
+
+ SfxItemState eState;
+// const SfxPoolItem* pItem;
+
+ //--------------------------------------------------------------------
+ // eigene Kontrolle ueber RadioButton-Funktionalitaet:
+ //--------------------------------------------------------------------
+ // Unterstreichung
+ //------------------------
+
+ eState = rAttrSet.GetItemState( ATTR_FONT_UNDERLINE, TRUE );
+ if ( eState == SFX_ITEM_DONTCARE )
+ {
+ rSet.InvalidateItem( SID_ULINE_VAL_NONE );
+ rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
+ }
+ else
+ {
+ FontUnderline eUnderline = ((const SvxUnderlineItem&)
+ rAttrSet.Get(ATTR_FONT_UNDERLINE)).GetLineStyle();
+ USHORT nId = SID_ULINE_VAL_NONE;
+ switch (eUnderline)
+ {
+ case UNDERLINE_SINGLE: nId = SID_ULINE_VAL_SINGLE; break;
+ case UNDERLINE_DOUBLE: nId = SID_ULINE_VAL_DOUBLE; break;
+ case UNDERLINE_DOTTED: nId = SID_ULINE_VAL_DOTTED; break;
+ default:
+ break;
+ }
+ rSet.Put( SfxBoolItem( nId, TRUE ) );
+ }
+
+ //------------------------
+ // horizontale Ausrichtung
+ //------------------------
+
+ const SvxHorJustifyItem* pHorJustify = NULL;
+ const SvxVerJustifyItem* pVerJustify = NULL;
+ SvxCellHorJustify eHorJustify = SVX_HOR_JUSTIFY_STANDARD;
+ SvxCellVerJustify eVerJustify = SVX_VER_JUSTIFY_STANDARD;
+ USHORT nWhich = 0;
+ BOOL bJustifyStd = FALSE;
+ SfxBoolItem aBoolItem ( 0, TRUE );
+
+ eState = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY, TRUE,
+ (const SfxPoolItem**)&pHorJustify );
+ switch ( eState )
+ {
+ case SFX_ITEM_SET:
+ {
+ eHorJustify = SvxCellHorJustify( pHorJustify->GetValue() );
+
+ switch ( SvxCellHorJustify( pHorJustify->GetValue() ) )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ break;
+
+ case SVX_HOR_JUSTIFY_LEFT:
+ nWhich = SID_ALIGNLEFT;
+ break;
+
+ case SVX_HOR_JUSTIFY_RIGHT:
+ nWhich = SID_ALIGNRIGHT;
+ break;
+
+ case SVX_HOR_JUSTIFY_CENTER:
+ nWhich = SID_ALIGNCENTERHOR;
+ break;
+
+ case SVX_HOR_JUSTIFY_BLOCK:
+ nWhich = SID_ALIGNBLOCK;
+ break;
+
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default:
+ bJustifyStd = TRUE;
+ break;
+ }
+ }
+ break;
+
+ case SFX_ITEM_DONTCARE:
+ rSet.InvalidateItem( SID_ALIGNLEFT );
+ rSet.InvalidateItem( SID_ALIGNRIGHT );
+ rSet.InvalidateItem( SID_ALIGNCENTERHOR );
+ rSet.InvalidateItem( SID_ALIGNBLOCK );
+ break;
+
+ default:
+ bJustifyStd = TRUE;
+ break;
+ }
+
+ if ( nWhich )
+ {
+ aBoolItem.SetWhich( nWhich );
+ rSet.Put( aBoolItem );
+ }
+ else if ( bJustifyStd )
+ {
+ aBoolItem.SetValue( FALSE );
+ aBoolItem.SetWhich( SID_ALIGNLEFT ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNRIGHT ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNCENTERHOR ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNBLOCK ); rSet.Put( aBoolItem );
+ bJustifyStd = FALSE;
+ }
+
+ //------------------------
+ // vertikale Ausrichtung
+ //------------------------
+
+ nWhich = 0;
+ aBoolItem.SetValue( TRUE );
+
+ eState = rAttrSet.GetItemState( ATTR_VER_JUSTIFY, TRUE,
+ (const SfxPoolItem**)&pVerJustify );
+
+ switch ( eState )
+ {
+ case SFX_ITEM_SET:
+ {
+ eVerJustify = SvxCellVerJustify( pVerJustify->GetValue() );
+
+ switch ( eVerJustify )
+ {
+ case SVX_VER_JUSTIFY_TOP:
+ nWhich = SID_ALIGNTOP;
+ break;
+
+ case SVX_VER_JUSTIFY_BOTTOM:
+ nWhich = SID_ALIGNBOTTOM;
+ break;
+
+ case SVX_VER_JUSTIFY_CENTER:
+ nWhich = SID_ALIGNCENTERVER;
+ break;
+
+ case SVX_VER_JUSTIFY_STANDARD:
+ default:
+ bJustifyStd = TRUE;
+ break;
+ }
+ }
+ break;
+
+ case SFX_ITEM_DONTCARE:
+ rSet.InvalidateItem( SID_ALIGNTOP );
+ rSet.InvalidateItem( SID_ALIGNBOTTOM );
+ rSet.InvalidateItem( SID_ALIGNCENTERVER );
+ break;
+
+ default:
+ bJustifyStd = TRUE;
+ break;
+ }
+
+ if ( nWhich )
+ {
+ aBoolItem.SetWhich( nWhich );
+ rSet.Put( aBoolItem );
+ }
+ else if ( bJustifyStd )
+ {
+ aBoolItem.SetValue( FALSE );
+ aBoolItem.SetWhich( SID_ALIGNTOP ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNBOTTOM ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNCENTERVER ); rSet.Put( aBoolItem );
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void ScFormatShell::GetBorderState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SvxBoxItem aBoxItem( ATTR_BORDER );
+ SvxBoxInfoItem aInfoItem( ATTR_BORDER_INNER );
+
+ pTabViewShell->GetSelectionFrame( aBoxItem, aInfoItem );
+
+ if ( rSet.GetItemState( ATTR_BORDER ) != SFX_ITEM_UNKNOWN )
+ rSet.Put( aBoxItem );
+ if ( rSet.GetItemState( ATTR_BORDER_INNER ) != SFX_ITEM_UNKNOWN )
+ rSet.Put( aInfoItem );
+}
+
+//------------------------------------------------------------------
+
+void ScFormatShell::GetAlignState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+
+ SvxCellHorJustify eHAlign = SVX_HOR_JUSTIFY_STANDARD;
+ bool bHasHAlign = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY ) != SFX_ITEM_DONTCARE;
+ if( bHasHAlign )
+ eHAlign = (SvxCellHorJustify)((const SvxHorJustifyItem&) rAttrSet.Get( ATTR_HOR_JUSTIFY )).GetValue();
+
+ SvxCellVerJustify eVAlign = SVX_VER_JUSTIFY_STANDARD;
+ bool bHasVAlign = rAttrSet.GetItemState( ATTR_VER_JUSTIFY ) != SFX_ITEM_DONTCARE;
+ if( bHasVAlign )
+ eVAlign = (SvxCellVerJustify)((const SvxVerJustifyItem&) rAttrSet.Get( ATTR_VER_JUSTIFY )).GetValue();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_H_ALIGNCELL:
+ if ( bHasHAlign )
+ rSet.Put( SvxHorJustifyItem( eHAlign, nWhich ));
+ break;
+ case SID_V_ALIGNCELL:
+ if ( bHasVAlign )
+ rSet.Put( SvxVerJustifyItem( eVAlign, nWhich ));
+ break;
+
+ // pseudo slots for Format menu
+ case SID_ALIGN_ANY_HDEFAULT:
+ case SID_ALIGN_ANY_LEFT:
+ case SID_ALIGN_ANY_HCENTER:
+ case SID_ALIGN_ANY_RIGHT:
+ case SID_ALIGN_ANY_JUSTIFIED:
+ rSet.Put( SfxBoolItem( nWhich, bHasHAlign && (eHAlign == lclConvertSlotToHAlign( nWhich )) ) );
+ break;
+ case SID_ALIGN_ANY_VDEFAULT:
+ case SID_ALIGN_ANY_TOP:
+ case SID_ALIGN_ANY_VCENTER:
+ case SID_ALIGN_ANY_BOTTOM:
+ rSet.Put( SfxBoolItem( nWhich, bHasVAlign && (eVAlign == lclConvertSlotToVAlign( nWhich )) ) );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScFormatShell::GetNumFormatState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+
+ // ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_NUMBER_FORMAT:
+ {
+ String aFormatCode; // bleibt leer, wenn dont-care
+
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ if ( rAttrSet.GetItemState( ATTR_VALUE_FORMAT ) != SFX_ITEM_DONTCARE )
+ {
+ ULONG nNumberFormat = ((const SfxUInt32Item&)rAttrSet.Get(
+ ATTR_VALUE_FORMAT )).GetValue();
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ const SvNumberformat* pFormatEntry = pFormatter->GetEntry( nNumberFormat );
+ if ( pFormatEntry )
+ aFormatCode = pFormatEntry->GetFormatstring();
+ }
+
+ rSet.Put( SfxStringItem( nWhich, aFormatCode ) );
+ }
+ break;
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+void ScFormatShell::ExecuteTextDirection( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ SC_MOD()->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ }
+
+ USHORT nSlot = rReq.GetSlot();
+ switch( nSlot )
+ {
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ {
+ BOOL bVert = (nSlot == SID_TEXTDIRECTION_TOP_TO_BOTTOM);
+ ScPatternAttr aAttr( GetViewData()->GetDocument()->GetPool() );
+ SfxItemSet& rItemSet = aAttr.GetItemSet();
+ rItemSet.Put( SfxBoolItem( ATTR_STACKED, bVert ) );
+ rItemSet.Put( SfxBoolItem( ATTR_VERTICAL_ASIAN, bVert ) );
+ pTabViewShell->ApplySelectionPattern( aAttr );
+ pTabViewShell->AdjustBlockHeight();
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ SvxFrameDirection eDirection = ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT ) ?
+ FRMDIR_HORI_LEFT_TOP : FRMDIR_HORI_RIGHT_TOP;
+ pTabViewShell->ApplyAttr( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ) );
+ }
+ break;
+ }
+}
+
+void ScFormatShell::GetTextDirectionState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+
+ BOOL bVertDontCare =
+ (rAttrSet.GetItemState( ATTR_VERTICAL_ASIAN ) == SFX_ITEM_DONTCARE) ||
+ (rAttrSet.GetItemState( ATTR_STACKED ) == SFX_ITEM_DONTCARE);
+ BOOL bLeftRight = !bVertDontCare &&
+ !((const SfxBoolItem&) rAttrSet.Get( ATTR_STACKED )).GetValue();
+ BOOL bTopBottom = !bVertDontCare && !bLeftRight &&
+ ((const SfxBoolItem&) rAttrSet.Get( ATTR_VERTICAL_ASIAN )).GetValue();
+
+ BOOL bBidiDontCare = (rAttrSet.GetItemState( ATTR_WRITINGDIR ) == SFX_ITEM_DONTCARE);
+ EEHorizontalTextDirection eBidiDir = EE_HTEXTDIR_DEFAULT;
+ if ( !bBidiDontCare )
+ {
+ SvxFrameDirection eCellDir = (SvxFrameDirection)((const SvxFrameDirectionItem&)
+ rAttrSet.Get( ATTR_WRITINGDIR )).GetValue();
+ if ( eCellDir == FRMDIR_ENVIRONMENT )
+ eBidiDir = (EEHorizontalTextDirection)GetViewData()->GetDocument()->
+ GetEditTextDirection( GetViewData()->GetTabNo() );
+ else if ( eCellDir == FRMDIR_HORI_RIGHT_TOP )
+ eBidiDir = EE_HTEXTDIR_R2L;
+ else
+ eBidiDir = EE_HTEXTDIR_L2R;
+ }
+
+ SvtLanguageOptions aLangOpt;
+ BOOL bDisableCTLFont = !aLangOpt.IsCTLFontEnabled();
+ BOOL bDisableVerticalText = !aLangOpt.IsVerticalTextEnabled();
+
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ if ( bDisableVerticalText )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ if( bVertDontCare )
+ rSet.InvalidateItem( nWhich );
+ else if ( nWhich == SID_TEXTDIRECTION_LEFT_TO_RIGHT )
+ rSet.Put( SfxBoolItem( nWhich, bLeftRight ) );
+ else
+ rSet.Put( SfxBoolItem( nWhich, bTopBottom ) );
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ if ( bDisableCTLFont )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ if ( bTopBottom )
+ rSet.DisableItem( nWhich );
+ else if ( bBidiDontCare )
+ rSet.InvalidateItem( nWhich );
+ else if ( nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT )
+ rSet.Put( SfxBoolItem( nWhich, eBidiDir == EE_HTEXTDIR_L2R ) );
+ else
+ rSet.Put( SfxBoolItem( nWhich, eBidiDir == EE_HTEXTDIR_R2L ) );
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScFormatShell::ExecFormatPaintbrush( SfxRequest& rReq )
+{
+ ScViewFunc* pView = pViewData->GetView();
+ if ( pView->HasPaintBrush() )
+ {
+ // cancel paintbrush mode
+ pView->ResetBrushDocument();
+ }
+ else
+ {
+ BOOL bLock = FALSE;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ if( pArgs && pArgs->Count() >= 1 )
+ bLock = static_cast<const SfxBoolItem&>(pArgs->Get(SID_FORMATPAINTBRUSH)).GetValue();
+
+ // in case of multi selection, deselect all and use the cursor position
+ ScRange aDummy;
+ if ( pViewData->GetSimpleArea(aDummy) != SC_MARK_SIMPLE )
+ pView->Unmark();
+
+ ScDocument* pBrushDoc = new ScDocument( SCDOCMODE_CLIP );
+ pView->CopyToClip( pBrushDoc, FALSE, TRUE );
+ pView->SetBrushDocument( pBrushDoc, bLock );
+ }
+}
+
+void ScFormatShell::StateFormatPaintbrush( SfxItemSet& rSet )
+{
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
+ rSet.DisableItem( SID_FORMATPAINTBRUSH );
+ else
+ rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, pViewData->GetView()->HasPaintBrush() ) );
+}
+
diff --git a/sc/source/ui/view/galwrap.cxx b/sc/source/ui/view/galwrap.cxx
new file mode 100644
index 000000000000..1d92cb5f303a
--- /dev/null
+++ b/sc/source/ui/view/galwrap.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <vcl/graph.hxx>
+#include <svx/gallery.hxx>
+#include <sfx2/app.hxx>
+
+// -----------------------------------------------------------------------
+
+Graphic GalleryGetGraphic()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+ return pGal->GetGraphic();
+}
+
+USHORT GallerySGA_FORMAT_GRAPHIC()
+{
+ return SGA_FORMAT_GRAPHIC;
+}
+
+BOOL GalleryIsLinkage()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+ return pGal->IsLinkage();
+}
+
+String GalleryGetFullPath()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+// return pGal->GetPath().GetFull();
+ return pGal->GetURL().GetMainURL(INetURLObject::NO_DECODE);
+ // URL as stored in GraphicLink must be encoded
+}
+
+String GalleryGetFilterName()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+ return pGal->GetFilterName();
+}
+
+
+
+
diff --git a/sc/source/ui/view/gridmerg.cxx b/sc/source/ui/view/gridmerg.cxx
new file mode 100644
index 000000000000..5a1f501e38ca
--- /dev/null
+++ b/sc/source/ui/view/gridmerg.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <vcl/outdev.hxx>
+
+#include "gridmerg.hxx"
+
+//------------------------------------------------------------------
+
+ScGridMerger::ScGridMerger( OutputDevice* pOutDev, long nOnePixelX, long nOnePixelY ) :
+ pDev( pOutDev ),
+ nOneX( nOnePixelX ),
+ nOneY( nOnePixelY ),
+ nCount( 0 ),
+ bVertical( FALSE )
+{
+ // optimize (DrawGrid) only for pixel MapMode,
+ // to avoid rounding errors
+
+ bOptimize = ( pDev->GetMapMode().GetMapUnit() == MAP_PIXEL );
+}
+
+ScGridMerger::~ScGridMerger()
+{
+ Flush();
+}
+
+void ScGridMerger::AddLine( long nStart, long nEnd, long nPos )
+{
+ if ( nCount )
+ {
+ // not first line - test fix position
+ // more than one previous line - test distance
+
+ if ( nStart != nFixStart || nEnd != nFixEnd )
+ {
+ if ( nCount == 1 && nPos == nVarStart &&
+ ( nStart == nFixEnd ||
+ nStart == nFixEnd + ( bVertical ? nOneY : nOneX ) ) )
+ {
+ // additional optimization: extend connected lines
+ // keep nCount at 1
+ nFixEnd = nEnd;
+ }
+ else
+ Flush();
+ }
+ else if ( nCount == 1 )
+ {
+ nVarDiff = nPos - nVarStart;
+ ++nCount;
+ }
+ else if ( nPos != nVarStart + nCount * nVarDiff ) //! keep VarEnd?
+ Flush();
+ else
+ ++nCount;
+ }
+
+ if ( !nCount )
+ {
+ // first line (or flushed above) - just store
+
+ nFixStart = nStart;
+ nFixEnd = nEnd;
+ nVarStart = nPos;
+ nVarDiff = 0;
+ nCount = 1;
+ }
+}
+
+void ScGridMerger::AddHorLine( long nX1, long nX2, long nY )
+{
+ if ( bOptimize )
+ {
+ if ( bVertical )
+ {
+ Flush();
+ bVertical = FALSE;
+ }
+ AddLine( nX1, nX2, nY );
+ }
+ else
+ pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
+}
+
+void ScGridMerger::AddVerLine( long nX, long nY1, long nY2 )
+{
+ if ( bOptimize )
+ {
+ if ( !bVertical )
+ {
+ Flush();
+ bVertical = TRUE;
+ }
+ AddLine( nY1, nY2, nX );
+ }
+ else
+ pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
+}
+
+void ScGridMerger::Flush()
+{
+ if (nCount)
+ {
+ if (bVertical)
+ {
+ if ( nCount == 1 )
+ pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
+ else
+ {
+ long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
+ if ( nVarDiff < 0 )
+ {
+ // nVarDiff is negative in RTL layout mode
+ // Change the positions so DrawGrid is called with a positive distance
+ // (nVarStart / nVarDiff can be modified, aren't used after Flush)
+
+ nVarDiff = -nVarDiff;
+ long nTemp = nVarStart;
+ nVarStart = nVarEnd;
+ nVarEnd = nTemp;
+ }
+ pDev->DrawGrid( Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
+ Size( nVarDiff, nFixEnd - nFixStart ),
+ GRID_VERTLINES );
+ }
+ }
+ else
+ {
+ if ( nCount == 1 )
+ pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
+ else
+ {
+ long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
+ pDev->DrawGrid( Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
+ Size( nFixEnd - nFixStart, nVarDiff ),
+ GRID_HORZLINES );
+ }
+ }
+ nCount = 0;
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
new file mode 100644
index 000000000000..0f07b8772254
--- /dev/null
+++ b/sc/source/ui/view/gridwin.cxx
@@ -0,0 +1,5706 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+
+#include <memory> //auto_ptr
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <svx/dbexch.hrc>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/svdetc.hxx>
+#include <editeng/editobj.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/svlbox.hxx>
+#include <svtools/svtabbx.hxx>
+#include <svl/urlbmk.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/hatch.hxx>
+#include <sot/formats.hxx>
+#include <sot/clsids.hxx>
+
+#include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
+#include <editeng/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
+#include <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpagv.hxx>
+
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/DataPilotTableResultData.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
+#include <com/sun/star/sheet/MemberResultFlags.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+
+#include "gridwin.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+#include "tabview.hxx"
+#include "select.hxx"
+#include "scmod.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "dbcolect.hxx"
+#include "stlpool.hxx"
+#include "printfun.hxx"
+#include "cbutton.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "editutil.hxx"
+#include "scresid.hxx"
+#include "inputhdl.hxx"
+#include "uiitems.hxx" // Filter-Dialog - auslagern !!!
+#include "filtdlg.hxx"
+#include "impex.hxx" // Sylk-ID fuer CB
+#include "cell.hxx" // fuer Edit-Felder
+#include "patattr.hxx"
+#include "notemark.hxx"
+#include "rfindlst.hxx"
+#include "docpool.hxx"
+#include "output.hxx"
+#include "docfunc.hxx"
+#include "dbdocfun.hxx"
+#include "dpobject.hxx"
+#include "dpoutput.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "seltrans.hxx"
+#include "sizedev.hxx"
+#include "AccessibilityHints.hxx"
+#include "dpsave.hxx"
+#include "viewuno.hxx"
+#include "compiler.hxx"
+#include "editable.hxx"
+#include "fillinfo.hxx"
+#include "scitems.hxx"
+#include "userdat.hxx"
+#include "drwlayer.hxx"
+#include "attrib.hxx"
+#include "validat.hxx"
+#include "tabprotection.hxx"
+#include "postit.hxx"
+#include "dpcontrol.hxx"
+#include "cellsuno.hxx"
+
+#include "drawview.hxx"
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/sdr/overlay/overlayselection.hxx>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+
+const BYTE SC_NESTEDBUTTON_NONE = 0;
+const BYTE SC_NESTEDBUTTON_DOWN = 1;
+const BYTE SC_NESTEDBUTTON_UP = 2;
+
+#define SC_AUTOFILTER_ALL 0
+#define SC_AUTOFILTER_TOP10 1
+#define SC_AUTOFILTER_CUSTOM 2
+
+// Modi fuer die FilterListBox
+enum ScFilterBoxMode
+{
+ SC_FILTERBOX_FILTER,
+ SC_FILTERBOX_DATASELECT,
+ SC_FILTERBOX_SCENARIO,
+ SC_FILTERBOX_PAGEFIELD
+};
+
+extern SfxViewShell* pScActiveViewShell; // global.cxx
+extern USHORT nScClickMouseModifier; // global.cxx
+extern USHORT nScFillModeMouseModifier; // global.cxx
+
+#define SC_FILTERLISTBOX_LINES 12
+
+// ============================================================================
+
+ScGridWindow::VisibleRange::VisibleRange() :
+ mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW)
+{
+}
+
+bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const
+{
+ return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2;
+}
+
+// ============================================================================
+
+class ScFilterListBox : public ListBox
+{
+private:
+ ScGridWindow* pGridWin;
+ SCCOL nCol;
+ SCROW nRow;
+ BOOL bButtonDown;
+ BOOL bInit;
+ BOOL bCancelled;
+ BOOL bInSelect;
+ bool mbListHasDates;
+ ULONG nSel;
+ ScFilterBoxMode eMode;
+
+protected:
+ virtual void LoseFocus();
+ void SelectHdl();
+
+public:
+ ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
+ SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode );
+ ~ScFilterListBox();
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void Select();
+
+ SCCOL GetCol() const { return nCol; }
+ SCROW GetRow() const { return nRow; }
+ ScFilterBoxMode GetMode() const { return eMode; }
+ BOOL IsDataSelect() const { return (eMode == SC_FILTERBOX_DATASELECT); }
+ void EndInit();
+ BOOL IsInInit() const { return bInit; }
+ void SetCancelled() { bCancelled = TRUE; }
+ BOOL IsInSelect() const { return bInSelect; }
+ void SetListHasDates(bool b) { mbListHasDates = b; }
+ bool HasDates() const { return mbListHasDates; }
+};
+
+//-------------------------------------------------------------------
+
+// ListBox in einem FloatingWindow (pParent)
+ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
+ SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) :
+ ListBox( pParent, WB_AUTOHSCROLL ),
+ pGridWin( pGrid ),
+ nCol( nNewCol ),
+ nRow( nNewRow ),
+ bButtonDown( FALSE ),
+ bInit( TRUE ),
+ bCancelled( FALSE ),
+ bInSelect( FALSE ),
+ mbListHasDates(false),
+ nSel( 0 ),
+ eMode( eNewMode )
+{
+}
+
+__EXPORT ScFilterListBox::~ScFilterListBox()
+{
+ if (IsMouseCaptured())
+ ReleaseMouse();
+}
+
+void ScFilterListBox::EndInit()
+{
+ USHORT nPos = GetSelectEntryPos();
+ if ( LISTBOX_ENTRY_NOTFOUND == nPos )
+ nSel = 0;
+ else
+ nSel = nPos;
+
+ bInit = FALSE;
+}
+
+void __EXPORT ScFilterListBox::LoseFocus()
+{
+#ifndef UNX
+ Hide();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+long ScFilterListBox::PreNotify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
+ KeyCode aCode = aKeyEvt.GetKeyCode();
+ if ( !aCode.GetModifier() ) // ohne alle Modifiers
+ {
+ USHORT nKey = aCode.GetCode();
+ if ( nKey == KEY_RETURN )
+ {
+ SelectHdl(); // auswaehlen
+ nDone = 1;
+ }
+ else if ( nKey == KEY_ESCAPE )
+ {
+ pGridWin->ClickExtern(); // loescht die List-Box !!!
+ nDone = 1;
+ }
+ }
+ }
+
+ return nDone ? nDone : ListBox::PreNotify( rNEvt );
+}
+
+void __EXPORT ScFilterListBox::Select()
+{
+ ListBox::Select();
+ SelectHdl();
+}
+
+void __EXPORT ScFilterListBox::SelectHdl()
+{
+ if ( !IsTravelSelect() && !bInit && !bCancelled )
+ {
+ USHORT nPos = GetSelectEntryPos();
+ if ( LISTBOX_ENTRY_NOTFOUND != nPos )
+ {
+ nSel = nPos;
+ if (!bButtonDown)
+ {
+ // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
+ bInSelect = TRUE;
+ pGridWin->FilterSelect( nSel );
+ bInSelect = FALSE;
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+// use a System floating window for the above filter listbox
+class ScFilterFloatingWindow : public FloatingWindow
+{
+public:
+ ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN );
+ virtual ~ScFilterFloatingWindow();
+ // required for System FloatingWindows that will not process KeyInput by themselves
+ virtual Window* GetPreferredKeyInputWindow();
+};
+
+ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) :
+ FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater
+ {}
+
+ScFilterFloatingWindow::~ScFilterFloatingWindow()
+{
+ EndPopupMode();
+}
+
+Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
+{
+ // redirect keyinput in the child window
+ return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL; // will be the FilterBox
+}
+
+// ============================================================================
+
+BOOL lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange )
+{
+ // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
+ // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
+ //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
+
+ if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(),
+ rRange.aEnd.Col(),rRange.aEnd.Row() ) )
+ return FALSE;
+
+ ScAddress aPos;
+ const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd );
+ return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
+ ((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart );
+
+}
+
+void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData )
+{
+ if (!pView && !pPV && !pDrDoc && !pViewData)
+ return;
+
+ ScDocument& rDoc = *pViewData->GetDocument();
+ ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
+ ScPostIt* pNote = rDoc.GetNote( aCellPos );
+ SdrObject* pObj = pNote ? pNote->GetCaption() : 0;
+ if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) )
+ {
+ const ScProtectionAttr* pProtAttr = static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) );
+ bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ;
+ bool bProtectDoc = rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ;
+ // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
+ pView->LockInternalLayer( bProtectDoc && bProtectAttr );
+ }
+}
+
+sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell )
+{
+ BOOL bFound = FALSE;
+ do
+ {
+ pDoc->GetCell( rPosX, rPosY, nTab, rpCell );
+ if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE )
+ {
+ if ( rPosX <= 0 )
+ return FALSE; // alles leer bis links
+ else
+ --rPosX; // weitersuchen
+ }
+ else if ( rpCell->GetCellType() == CELLTYPE_EDIT)
+ bFound = TRUE;
+ else if (rpCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell())
+ bFound = TRUE;
+ else
+ return FALSE; // andere Zelle
+ }
+ while ( !bFound );
+
+ return bFound;
+}
+
+// ---------------------------------------------------------------------------
+// WB_DIALOGCONTROL noetig fuer UNO-Controls
+ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos )
+: Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
+ DropTargetHelper( this ),
+ DragSourceHelper( this ),
+ mpOOCursors( NULL ),
+ mpOOSelection( NULL ),
+ mpOOAutoFill( NULL ),
+ mpOODragRect( NULL ),
+ mpOOHeader( NULL ),
+ mpOOShrink( NULL ),
+ mpAutoFillRect(static_cast<Rectangle*>(NULL)),
+ pViewData( pData ),
+ eWhich( eWhichPos ),
+ pNoteMarker( NULL ),
+ pFilterBox( NULL ),
+ pFilterFloat( NULL ),
+ mpDPFieldPopup(NULL),
+ mpFilterButton(NULL),
+ nCursorHideCount( 0 ),
+ bMarking( FALSE ),
+ nButtonDown( 0 ),
+ bEEMouse( FALSE ),
+ nMouseStatus( SC_GM_NONE ),
+ nNestedButtonState( SC_NESTEDBUTTON_NONE ),
+ bDPMouse( FALSE ),
+ bRFMouse( FALSE ),
+ nPagebreakMouse( SC_PD_NONE ),
+ bPagebreakDrawn( FALSE ),
+ nPageScript( 0 ),
+ bDragRect( FALSE ),
+ meDragInsertMode( INS_NONE ),
+ nCurrentPointer( 0 ),
+ bIsInScroll( FALSE ),
+ bIsInPaint( FALSE ),
+ aComboButton( this ),
+ aCurMousePos( 0,0 ),
+ nPaintCount( 0 ),
+ bNeedsRepaint( FALSE ),
+ bAutoMarkVisible( FALSE ),
+ bListValButton( FALSE )
+{
+ switch(eWhich)
+ {
+ case SC_SPLIT_TOPLEFT:
+ eHWhich = SC_SPLIT_LEFT;
+ eVWhich = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_TOPRIGHT:
+ eHWhich = SC_SPLIT_RIGHT;
+ eVWhich = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_BOTTOMLEFT:
+ eHWhich = SC_SPLIT_LEFT;
+ eVWhich = SC_SPLIT_BOTTOM;
+ break;
+ case SC_SPLIT_BOTTOMRIGHT:
+ eHWhich = SC_SPLIT_RIGHT;
+ eVWhich = SC_SPLIT_BOTTOM;
+ break;
+ default:
+ DBG_ERROR("GridWindow: falsche Position");
+ }
+
+ SetBackground();
+
+ SetMapMode(pViewData->GetLogicMode(eWhich));
+// EnableDrop();
+ EnableChildTransparentMode();
+ SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );
+
+ SetHelpId( HID_SC_WIN_GRIDWIN );
+ SetUniqueId( HID_SC_WIN_GRIDWIN );
+
+ SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ EnableRTL( FALSE );
+}
+
+__EXPORT ScGridWindow::~ScGridWindow()
+{
+ // #114409#
+ ImpDestroyOverlayObjects();
+
+ delete pFilterBox;
+ delete pFilterFloat;
+ delete pNoteMarker;
+}
+
+void __EXPORT ScGridWindow::Resize( const Size& )
+{
+ // gar nix
+}
+
+void ScGridWindow::ClickExtern()
+{
+ do
+ {
+ // #i81298# don't delete the filter box when called from its select handler
+ // (possible through row header size update)
+ // #i84277# when initializing the filter box, a Basic error can deactivate the view
+ if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
+ {
+ break;
+ }
+
+ DELETEZ(pFilterBox);
+ DELETEZ(pFilterFloat);
+ }
+ while (false);
+
+ if (mpDPFieldPopup.get())
+ {
+ mpDPFieldPopup->close(false);
+ mpDPFieldPopup.reset();
+ }
+}
+
+IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
+{
+ if (pFilterBox)
+ pFilterBox->SetCancelled(); // nicht mehr auswaehlen
+ GrabFocus();
+ return 0;
+}
+
+IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo )
+{
+ if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG )
+ pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
+ return 0;
+}
+
+void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, BOOL bHasSelection, const String& rStr )
+{
+ //! gridwin2 ?
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+ if ( pDPObj && nCol > 0 )
+ {
+ // look for the dimension header left of the drop-down arrow
+ USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
+ if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
+ {
+ ScDPSaveData aSaveData( *pDPObj->GetSaveData() );
+
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName);
+
+ if ( bHasSelection )
+ pDim->SetCurrentPage( &rStr );
+ else
+ pDim->SetCurrentPage( NULL );
+
+ ScDPObject aNewObj( *pDPObj );
+ aNewObj.SetSaveData( aSaveData );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, TRUE, FALSE );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ }
+ }
+}
+
+void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
+{
+ //! merge position/size handling with DoAutoFilterMenue
+
+ delete pFilterBox;
+ delete pFilterFloat;
+
+ USHORT i;
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ long nHeight = 0;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ if ( bLayoutRTL )
+ aPos.X() -= nSizeX;
+
+ Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
+
+ aPos.X() -= 1;
+ aPos.Y() += nSizeY - 1;
+
+ pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // not resizable etc.
+ pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
+ pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD );
+ if ( bLayoutRTL )
+ pFilterBox->EnableMirroring();
+
+ nSizeX += 1;
+
+ {
+ Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
+ MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
+
+ nHeight = GetTextHeight();
+ nHeight *= SC_FILTERLISTBOX_LINES;
+
+ SetMapMode( aOldMode );
+ SetFont( aOldFont );
+ }
+
+ // SetSize comes later
+
+ TypedScStrCollection aStrings( 128, 128 );
+
+ // get list box entries and selection
+ BOOL bHasCurrentPage = FALSE;
+ String aCurrentPage;
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+ if ( pDPObj && nCol > 0 )
+ {
+ // look for the dimension header left of the drop-down arrow
+ USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
+ if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
+ {
+ pDPObj->FillPageList( aStrings, nField );
+
+ // get current page from SaveData
+
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
+ if ( pSaveData && !bIsDataLayout )
+ {
+ ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName);
+ if ( pDim && pDim->HasCurrentPage() )
+ {
+ aCurrentPage = pDim->GetCurrentPage();
+ bHasCurrentPage = TRUE;
+ }
+ }
+ }
+ }
+
+ // include all entry widths for the size of the drop-down
+ long nMaxText = 0;
+ USHORT nCount = aStrings.GetCount();
+ for (i=0; i<nCount; i++)
+ {
+ TypedStrData* pData = aStrings[i];
+ long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ }
+
+ // add scrollbar width if needed (string entries are counted here)
+ // (scrollbar is shown if the box is exactly full?)
+ if ( nCount >= SC_FILTERLISTBOX_LINES )
+ nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ nMaxText += 4; // for borders
+
+ if ( nMaxText > nSizeX )
+ nSizeX = nMaxText; // just modify width - starting position is unchanged
+
+ // adjust position and size to window
+
+ Size aParentSize = GetParent()->GetOutputSizePixel();
+ Size aSize( nSizeX, nHeight );
+
+ if ( aSize.Height() > aParentSize.Height() )
+ aSize.Height() = aParentSize.Height();
+ if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
+ aPos.Y() = aParentSize.Height() - aSize.Height();
+
+ pFilterBox->SetSizePixel( aSize );
+ pFilterBox->Show(); // Show must be called before SetUpdateMode
+ pFilterBox->SetUpdateMode(FALSE);
+
+ pFilterFloat->SetOutputSizePixel( aSize );
+ pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
+
+ // fill the list box
+ BOOL bWait = ( nCount > 100 );
+
+ if (bWait)
+ EnterWait();
+
+ for (i=0; i<nCount; i++)
+ pFilterBox->InsertEntry( aStrings[i]->GetString() );
+
+ pFilterBox->SetSeparatorPos( 0 );
+
+ if (bWait)
+ LeaveWait();
+
+ pFilterBox->SetUpdateMode(TRUE);
+
+ USHORT nSelPos = LISTBOX_ENTRY_NOTFOUND;
+ if (bHasCurrentPage)
+ nSelPos = pFilterBox->GetEntryPos( aCurrentPage );
+
+ if ( nSelPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelPos = 0; // first entry
+
+ pFilterBox->GrabFocus();
+
+ // call Select after GrabFocus, so the focus rectangle ends up in the right position
+ if ( nSelPos != LISTBOX_ENTRY_NOTFOUND )
+ pFilterBox->SelectEntryPos( nSelPos );
+
+ pFilterBox->EndInit();
+
+ nMouseStatus = SC_GM_FILTER;
+ CaptureMouse();
+}
+
+void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
+ if (!pDPObj)
+ return;
+
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
+}
+
+void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
+{
+ delete pFilterBox;
+ delete pFilterFloat;
+
+ SCCOL nCol = rScenRange.aEnd.Col(); // Zelle unterhalb des Buttons
+ SCROW nRow = rScenRange.aStart.Row();
+ if (nRow == 0)
+ {
+ nRow = rScenRange.aEnd.Row() + 1; // Bereich ganz oben -> Button unterhalb
+ if (nRow>MAXROW) nRow = MAXROW;
+ //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
+ }
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ long nHeight = 0;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ if ( bLayoutRTL )
+ aPos.X() -= nSizeX;
+ Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
+ aCellRect.Top() -= nSizeY;
+ aCellRect.Bottom() -= nSizeY - 1;
+ // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
+ // (wenn die Linie verdeckt wird, sieht es komisch aus...)
+
+ pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc.
+ pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
+ pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO );
+ if ( bLayoutRTL )
+ pFilterBox->EnableMirroring();
+
+ nSizeX += 1;
+
+ {
+ Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
+ MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
+
+ nHeight = GetTextHeight();
+ nHeight *= SC_FILTERLISTBOX_LINES;
+
+ SetMapMode( aOldMode );
+ SetFont( aOldFont );
+ }
+
+ // SetSize spaeter
+/*
+ pFilterBox->SetSelectionMode( SINGLE_SELECTION );
+ pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
+ pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
+*/
+
+ // ParentSize Abfrage fehlt
+ Size aSize( nSizeX, nHeight );
+ pFilterBox->SetSizePixel( aSize );
+ pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!!
+ pFilterBox->SetUpdateMode(FALSE);
+
+ // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
+
+ // Listbox fuellen
+
+ long nMaxText = 0;
+ String aCurrent;
+ String aTabName;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nEntryCount = 0;
+ for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ {
+ if (pDoc->HasScenarioRange( i, rScenRange ))
+ if (pDoc->GetName( i, aTabName ))
+ {
+ pFilterBox->InsertEntry( aTabName );
+ if (pDoc->IsActiveScenario(i))
+ aCurrent = aTabName;
+ long nTextWidth = pFilterBox->GetTextWidth( aTabName );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ ++nEntryCount;
+ }
+ }
+ if (nEntryCount > SC_FILTERLISTBOX_LINES)
+ nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
+ nMaxText += 4; // fuer Rand
+ if ( nMaxText > 300 )
+ nMaxText = 300; // auch nicht uebertreiben (Pixel)
+
+ if (nMaxText > nSizeX) // Groesse auf benoetigte Groesse anpassen
+ {
+ long nDiff = nMaxText - nSizeX;
+ aSize = Size( nMaxText, nHeight );
+ pFilterBox->SetSizePixel( aSize );
+ pFilterFloat->SetOutputSizePixel( aSize );
+
+ if ( !bLayoutRTL )
+ {
+ // also move popup position
+ long nNewX = aCellRect.Left() - nDiff;
+ if ( nNewX < 0 )
+ nNewX = 0;
+ aCellRect.Left() = nNewX;
+ }
+ }
+
+ pFilterFloat->SetOutputSizePixel( aSize );
+ pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS );
+
+ pFilterBox->SetUpdateMode(TRUE);
+ pFilterBox->GrabFocus();
+
+ // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
+//! SvLBoxEntry* pSelect = NULL;
+ USHORT nPos = LISTBOX_ENTRY_NOTFOUND;
+ if (aCurrent.Len())
+ {
+ nPos = pFilterBox->GetEntryPos( aCurrent );
+//! pSelect = pFilterBox->GetEntry( nPos );
+ }
+ if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 )
+ nPos = 0;
+//! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein
+ if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND != nPos )
+ pFilterBox->SelectEntryPos(nPos);
+
+ pFilterBox->EndInit();
+
+ // Szenario-Auswahl kommt aus MouseButtonDown:
+ // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
+
+ nMouseStatus = SC_GM_FILTER;
+ CaptureMouse();
+}
+
+void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect )
+{
+ delete pFilterBox;
+ delete pFilterFloat;
+
+ USHORT i;
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ long nHeight = 0;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ if ( bLayoutRTL )
+ aPos.X() -= nSizeX;
+
+ Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
+
+ aPos.X() -= 1;
+ aPos.Y() += nSizeY - 1;
+
+ pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc.
+ pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
+ pFilterBox = new ScFilterListBox(
+ pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER );
+ if ( bLayoutRTL )
+ pFilterBox->EnableMirroring();
+
+ nSizeX += 1;
+
+ {
+ Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
+ MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
+
+ nHeight = GetTextHeight();
+ nHeight *= SC_FILTERLISTBOX_LINES;
+
+ SetMapMode( aOldMode );
+ SetFont( aOldFont );
+ }
+
+ // SetSize spaeter
+/*
+ pFilterBox->SetSelectionMode( SINGLE_SELECTION );
+ pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
+ pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
+*/
+
+ BOOL bEmpty = FALSE;
+ TypedScStrCollection aStrings( 128, 128 );
+ if ( bDataSelect ) // Auswahl-Liste
+ {
+ // Liste fuellen
+ aStrings.SetCaseSensitive( TRUE );
+ pDoc->GetDataEntries( nCol, nRow, nTab, aStrings );
+ if ( aStrings.GetCount() == 0 )
+ bEmpty = TRUE;
+ }
+ else // AutoFilter
+ {
+ //! wird der Titel ueberhaupt ausgewertet ???
+ String aString;
+ pDoc->GetString( nCol, nRow, nTab, aString );
+ pFilterBox->SetText( aString );
+
+ long nMaxText = 0;
+
+ // default entries
+ static const USHORT nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER };
+ const USHORT nDefCount = sizeof(nDefIDs) / sizeof(USHORT);
+ for (i=0; i<nDefCount; i++)
+ {
+ String aEntry( (ScResId) nDefIDs[i] );
+ pFilterBox->InsertEntry( aEntry );
+ long nTextWidth = pFilterBox->GetTextWidth( aEntry );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ }
+ pFilterBox->SetSeparatorPos( nDefCount - 1 );
+
+ // get list entries
+ bool bHasDates = false;
+ pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates);
+ pFilterBox->SetListHasDates(bHasDates);
+
+ // check widths of numerical entries (string entries are not included)
+ // so all numbers are completely visible
+ USHORT nCount = aStrings.GetCount();
+ for (i=0; i<nCount; i++)
+ {
+ TypedStrData* pData = aStrings[i];
+ if ( !pData->IsStrData() ) // only numerical entries
+ {
+ long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ }
+ }
+
+ // add scrollbar width if needed (string entries are counted here)
+ // (scrollbar is shown if the box is exactly full?)
+ if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES )
+ nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ nMaxText += 4; // for borders
+
+ if ( nMaxText > nSizeX )
+ nSizeX = nMaxText; // just modify width - starting position is unchanged
+ }
+
+ if (!bEmpty)
+ {
+ // Position und Groesse an Fenster anpassen
+ //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
+
+ Size aParentSize = GetParent()->GetOutputSizePixel();
+ Size aSize( nSizeX, nHeight );
+
+ if ( aSize.Height() > aParentSize.Height() )
+ aSize.Height() = aParentSize.Height();
+ if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
+ aPos.Y() = aParentSize.Height() - aSize.Height();
+
+ pFilterBox->SetSizePixel( aSize );
+ pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!!
+ pFilterBox->SetUpdateMode(FALSE);
+
+ pFilterFloat->SetOutputSizePixel( aSize );
+ pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
+
+ // Listbox fuellen
+ USHORT nCount = aStrings.GetCount();
+ BOOL bWait = ( nCount > 100 );
+
+ if (bWait)
+ EnterWait();
+
+ for (i=0; i<nCount; i++)
+ pFilterBox->InsertEntry( aStrings[i]->GetString() );
+
+ if (bWait)
+ LeaveWait();
+
+ pFilterBox->SetUpdateMode(TRUE);
+ }
+
+//! SvLBoxEntry* pSelect = NULL;
+ USHORT nSelPos = LISTBOX_ENTRY_NOTFOUND;
+
+ if (!bDataSelect) // AutoFilter: aktiven Eintrag selektieren
+ {
+ ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ if (pDBData)
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben
+
+ BOOL bValid = TRUE;
+ for (SCSIZE j=0; j<MAXQUERY && bValid; j++) // bisherige Filter-Einstellungen
+ if (aParam.GetEntry(j).bDoQuery)
+ {
+ //! Abfrage mit DrawButtons zusammenfassen!
+
+ ScQueryEntry& rEntry = aParam.GetEntry(j);
+ if (j>0)
+ if (rEntry.eConnect != SC_AND)
+ bValid = FALSE;
+ if (rEntry.nField == nCol)
+ {
+ if (rEntry.eOp == SC_EQUAL)
+ {
+ String* pStr = rEntry.pStr;
+ if (pStr)
+ {
+ nSelPos = pFilterBox->GetEntryPos( *pStr );
+//! pSelect = pFilterBox->GetEntry( nPos );
+ }
+ }
+ else if (rEntry.eOp == SC_TOPVAL && rEntry.pStr &&
+ rEntry.pStr->EqualsAscii("10"))
+ nSelPos = SC_AUTOFILTER_TOP10;
+ else
+ nSelPos = SC_AUTOFILTER_CUSTOM;
+ }
+ }
+
+ if (!bValid)
+ nSelPos = SC_AUTOFILTER_CUSTOM;
+ }
+ }
+ else
+ {
+
+ ULONG nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
+ nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue();
+ if ( nIndex )
+ {
+ const ScValidationData* pData = pDoc->GetValidationEntry( nIndex );
+ if (pData)
+ {
+ TypedStrData* pNew = NULL;
+ String aDocStr;
+ pDoc->GetString( nCol, nRow, nTab, aDocStr );
+ if ( pDoc->HasValueData( nCol, nRow, nTab ) )
+ {
+ double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab));
+ pNew = new TypedStrData( aDocStr, fVal, SC_STRTYPE_VALUE );
+ }
+ else
+ pNew = new TypedStrData( aDocStr, 0.0, SC_STRTYPE_STANDARD );
+
+ bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING);
+ if ( bSortList )
+ {
+ USHORT nStrIndex;
+ if (aStrings.Search(pNew,nStrIndex))
+ nSelPos = nStrIndex;
+ }
+ else
+ {
+ USHORT nCount = aStrings.GetCount();
+ for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++)
+ {
+ if ( aStrings.Compare(aStrings[i], pNew)==0 )
+ nSelPos = i;
+ }
+ }
+ delete pNew;
+ }
+ }
+ }
+
+ // neu (309): irgendwas muss immer selektiert sein:
+ if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect)
+ nSelPos = 0;
+
+ // keine leere Auswahl-Liste anzeigen:
+
+ if ( bEmpty )
+ {
+ DELETEZ(pFilterBox); // war nix
+ DELETEZ(pFilterFloat);
+ Sound::Beep(); // bemerkbar machen
+ }
+ else
+ {
+// pFilterBox->Show(); // schon vorne
+ pFilterBox->GrabFocus();
+
+ // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
+ if ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
+ pFilterBox->SelectEntryPos( nSelPos );
+ else
+ {
+ if (bDataSelect)
+ pFilterBox->SetNoSelection();
+ }
+
+ pFilterBox->EndInit();
+
+ if (!bDataSelect)
+ {
+ // AutoFilter (aus MouseButtonDown):
+ // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
+
+ nMouseStatus = SC_GM_FILTER;
+ CaptureMouse();
+ }
+ }
+}
+
+void ScGridWindow::FilterSelect( ULONG nSel )
+{
+ String aString;
+/*
+ SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
+ if (pEntry)
+ {
+ SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
+ if ( pStringEntry )
+ aString = pStringEntry->GetText();
+ }
+*/
+ aString = pFilterBox->GetEntry( static_cast< USHORT >( nSel ) );
+
+ SCCOL nCol = pFilterBox->GetCol();
+ SCROW nRow = pFilterBox->GetRow();
+ switch ( pFilterBox->GetMode() )
+ {
+ case SC_FILTERBOX_DATASELECT:
+ ExecDataSelect( nCol, nRow, aString );
+ break;
+ case SC_FILTERBOX_FILTER:
+ ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() );
+ break;
+ case SC_FILTERBOX_SCENARIO:
+ pViewData->GetView()->UseScenario( aString );
+ break;
+ case SC_FILTERBOX_PAGEFIELD:
+ // first entry is "all"
+ ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString );
+ break;
+ }
+
+ if (pFilterFloat)
+ pFilterFloat->EndPopupMode();
+
+ GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
+}
+
+void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr )
+{
+ if ( rStr.Len() )
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ ScViewFunc* pView = pViewData->GetView();
+ pView->EnterData( nCol, nRow, nTab, rStr );
+
+ // #i52307# CellContentChanged is not in EnterData so it isn't called twice
+ // if the cursor is moved afterwards.
+ pView->CellContentChanged();
+ }
+}
+
+void ScGridWindow::ExecFilter( ULONG nSel,
+ SCCOL nCol, SCROW nRow,
+ const String& aValue, bool bCheckForDates )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ if (pDBData)
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben
+
+ 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 );
+ }
+ else
+ {
+ BOOL bDeleteOld = FALSE;
+ SCSIZE nQueryPos = 0;
+ BOOL bFound = FALSE;
+ if (!aParam.bInplace)
+ bDeleteOld = TRUE;
+ if (aParam.bRegExp)
+ bDeleteOld = TRUE;
+ for (SCSIZE i=0; i<MAXQUERY && !bDeleteOld; i++) // bisherige Filter-Einstellungen
+ if (aParam.GetEntry(i).bDoQuery)
+ {
+ //! Abfrage mit DrawButtons zusammenfassen!
+
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (i>0)
+ if (rEntry.eConnect != SC_AND)
+ bDeleteOld = TRUE;
+
+ if (rEntry.nField == nCol)
+ {
+ if (bFound) // diese Spalte zweimal?
+ bDeleteOld = TRUE;
+ nQueryPos = i;
+ bFound = TRUE;
+ }
+ if (!bFound)
+ nQueryPos = i + 1;
+ }
+
+ if (bDeleteOld)
+ {
+ SCSIZE nEC = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aParam.GetEntry(i).Clear();
+ nQueryPos = 0;
+ aParam.bInplace = TRUE;
+ aParam.bRegExp = FALSE;
+ }
+
+ if ( nQueryPos < MAXQUERY || SC_AUTOFILTER_ALL == nSel ) // loeschen geht immer
+ {
+ if (nSel)
+ {
+ ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos);
+
+ rNewEntry.bDoQuery = TRUE;
+ rNewEntry.bQueryByString = TRUE;
+ rNewEntry.nField = nCol;
+ rNewEntry.bQueryByDate = bCheckForDates;
+ if ( nSel == SC_AUTOFILTER_TOP10 )
+ {
+ rNewEntry.eOp = SC_TOPVAL;
+ *rNewEntry.pStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
+ }
+ else
+ {
+ rNewEntry.eOp = SC_EQUAL;
+ *rNewEntry.pStr = aValue;
+ }
+ if (nQueryPos > 0)
+ rNewEntry.eConnect = SC_AND;
+ }
+ else
+ {
+ if (bFound)
+ aParam.DeleteQuery(nQueryPos);
+ }
+
+ // #100597# end edit mode - like in ScCellShell::ExecuteDB
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
+ {
+ SC_MOD()->InputEnterHandler();
+ pViewData->GetViewShell()->UpdateInputHandler();
+ }
+
+ pViewData->GetView()->Query( aParam, NULL, TRUE );
+ pDBData->SetQueryParam( aParam ); // speichern
+ }
+ else // "Zuviele Bedingungen"
+ pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY );
+ }
+ }
+ else
+ {
+ DBG_ERROR("Wo ist der Datenbankbereich?");
+ }
+}
+
+void ScGridWindow::SetPointer( const Pointer& rPointer )
+{
+ nCurrentPointer = 0;
+ Window::SetPointer( rPointer );
+}
+
+void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin )
+{
+ if (nButtonDown)
+ {
+ rDestWin.nButtonDown = nButtonDown;
+ rDestWin.nMouseStatus = nMouseStatus;
+ }
+
+ if (bRFMouse)
+ {
+ rDestWin.bRFMouse = bRFMouse;
+ rDestWin.bRFSize = bRFSize;
+ rDestWin.nRFIndex = nRFIndex;
+ rDestWin.nRFAddX = nRFAddX;
+ rDestWin.nRFAddY = nRFAddY;
+ bRFMouse = FALSE;
+ }
+
+ if (nPagebreakMouse)
+ {
+ rDestWin.nPagebreakMouse = nPagebreakMouse;
+ rDestWin.nPagebreakBreak = nPagebreakBreak;
+ rDestWin.nPagebreakPrev = nPagebreakPrev;
+ rDestWin.aPagebreakSource = aPagebreakSource;
+ rDestWin.aPagebreakDrag = aPagebreakDrag;
+ nPagebreakMouse = SC_PD_NONE;
+ }
+}
+
+BOOL ScGridWindow::TestMouse( const MouseEvent& rMEvt, BOOL bAction )
+{
+ // MouseEvent buttons must only be checked if bAction==TRUE
+ // to allow changing the mouse pointer in MouseMove,
+ // but not start AutoFill with right button (#74229#).
+ // with bAction==TRUE, SetFillMode / SetDragMode is called
+
+ if ( bAction && !rMEvt.IsLeft() )
+ return FALSE;
+
+ BOOL bNewPointer = FALSE;
+
+ SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
+ BOOL bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
+
+ if ( pViewData->IsActive() && !bOleActive )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ // Auto-Fill
+
+ ScRange aMarkRange;
+ if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE)
+ {
+ if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect)
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ if (mpAutoFillRect->IsInside(aMousePos))
+ {
+ SetPointer( Pointer( POINTER_CROSS ) ); //! dickeres Kreuz ?
+ if (bAction)
+ {
+ SCCOL nX = aMarkRange.aEnd.Col();
+ SCROW nY = aMarkRange.aEnd.Row();
+
+ if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) )
+ pViewData->SetDragMode(
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX );
+ else
+ pViewData->SetFillMode(
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY );
+
+ // #108266# The simple selection must also be recognized when dragging,
+ // where the Marking flag is set and MarkToSimple won't work anymore.
+ pViewData->GetMarkData().MarkToSimple();
+ }
+ bNewPointer = TRUE;
+ }
+ }
+ }
+
+ // Embedded-Rechteck
+
+ if (pDoc->IsEmbedded())
+ {
+ ScRange aRange;
+ pDoc->GetEmbedded( aRange );
+ if ( pViewData->GetTabNo() == aRange.aStart.Tab() )
+ {
+ Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich );
+ Point aEndPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich );
+ Point aMousePos = rMEvt.GetPosPixel();
+ if ( bLayoutRTL )
+ {
+ aStartPos.X() += 2;
+ aEndPos.X() += 2;
+ }
+ BOOL bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 &&
+ aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 );
+ BOOL bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 &&
+ aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 );
+ if ( bTop || bBottom )
+ {
+ SetPointer( Pointer( POINTER_CROSS ) );
+ if (bAction)
+ {
+ BYTE nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB;
+ pViewData->SetDragMode(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), nMode );
+ }
+ bNewPointer = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!bNewPointer && bAction)
+ {
+// SetPointer( POINTER_ARROW ); // in Fu...
+ pViewData->ResetFillMode();
+ }
+
+ return bNewPointer;
+}
+
+void __EXPORT ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ nNestedButtonState = SC_NESTEDBUTTON_DOWN;
+
+ HandleMouseButtonDown( rMEvt );
+
+ if ( nNestedButtonState == SC_NESTEDBUTTON_UP )
+ {
+ // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
+ // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
+ // simulate another MouseButtonUp call, so the selection state is consistent.
+
+ nButtonDown = rMEvt.GetButtons();
+ FakeButtonUp();
+
+ if ( IsTracking() )
+ EndTracking(); // normally done in VCL as part of MouseButtonUp handling
+ }
+ nNestedButtonState = SC_NESTEDBUTTON_NONE;
+}
+
+void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
+{
+ // We have to check if a context menu is shown and we have an UI
+ // active inplace client. In that case we have to ignore the event.
+ // Otherwise we would crash (context menu has been
+ // opened by inplace client and we would deactivate the inplace client,
+ // the contex menu is closed by VCL asynchronously which in the end
+ // would work on deleted objects or the context menu has no parent anymore)
+ // See #126086# and #128122#
+ SfxViewShell* pViewSh = pViewData->GetViewShell();
+ SfxInPlaceClient* pClient = pViewSh->GetIPClient();
+ if ( pClient &&
+ pClient->IsObjectInPlaceActive() &&
+ PopupMenu::IsInExecute() )
+ return;
+
+ aCurMousePos = rMEvt.GetPosPixel();
+
+ // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
+ // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
+#if 0
+ // merken, dass FilterBox geloescht wird, damit sichergestellt
+ // ist, dass in diesem Handler nicht an gleicher Stelle wieder
+ // eine neue geoeffnet wird.
+ BOOL bWasFilterBox = ( pFilterBox != NULL &&
+ ((Window*)pFilterBox)->IsVisible() &&
+ !pFilterBox->IsDataSelect() );
+ SCCOL nOldColFBox = bWasFilterBox ? pFilterBox->GetCol() : 0;
+ SCROW nOldRowFBox = bWasFilterBox ? pFilterBox->GetRow() : 0;
+#endif
+
+ ClickExtern(); // loescht FilterBox, wenn vorhanden
+
+ HideNoteMarker(); // Notiz-Anzeige
+
+ bEEMouse = FALSE;
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
+ {
+ Sound::Beep();
+ return;
+ }
+
+ pScActiveViewShell = pViewData->GetViewShell(); // falls auf Link geklickt wird
+ nScClickMouseModifier = rMEvt.GetModifier(); // um Control-Klick immer zu erkennen
+
+ BOOL bDetective = pViewData->GetViewShell()->IsAuditShell();
+ BOOL bRefMode = pViewData->IsRefMode(); // Referenz angefangen
+ BOOL bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
+ BOOL bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE
+ BOOL bDouble = (rMEvt.GetClicks() == 2);
+
+ // DeactivateIP passiert nur noch bei MarkListHasChanged
+
+ // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
+ // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
+
+ if ( !nButtonDown || !bDouble ) // single (first) click is always valid
+ nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works
+
+// pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
+ if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode )
+ GrabFocus();
+
+ // #i31846# need to cancel a double click if the first click has set the "ignore" state,
+ // but a single (first) click is always valid
+ if ( nMouseStatus == SC_GM_IGNORE && bDouble )
+ {
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ return;
+ }
+
+ if ( bDetective ) // Detektiv-Fuell-Modus
+ {
+ if ( rMEvt.IsLeft() && !rMEvt.GetModifier() )
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX );
+ SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY );
+ pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aPosXItem, &aPosYItem, (void*)0L );
+
+ }
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ return;
+ }
+
+ if (!bDouble)
+ nMouseStatus = SC_GM_NONE;
+
+ if (!bFormulaMode)
+ {
+ if ( pViewData->GetActivePart() != eWhich )
+ pViewData->GetView()->ActivatePart( eWhich );
+ }
+ else
+ {
+ ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
+ pSelEng->SetWindow(this);
+ pSelEng->SetWhich(eWhich);
+ pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
+ }
+
+ if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()))
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ SCCOL nEndCol = pViewData->GetEditEndCol();
+ SCROW nEndRow = pViewData->GetEditEndRow();
+
+ if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
+ nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
+ {
+ // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
+ if (bFormulaMode) // sonst ist es oben schon passiert
+ GrabFocus();
+
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ bEEMouse = TRUE;
+ bEditMode = pEditView->MouseButtonDown( rMEvt );
+ return;
+ }
+ }
+
+ if (pScMod->GetIsWaterCan())
+ {
+ //! was is mit'm Mac ???
+ if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT )
+ {
+ nMouseStatus = SC_GM_WATERUNDO;
+ return;
+ }
+ }
+
+ // Reihenfolge passend zum angezeigten Cursor:
+ // RangeFinder, AutoFill, PageBreak, Drawing
+
+ if ( HitRangeFinder( rMEvt.GetPosPixel(), bRFSize, &nRFIndex, &nRFAddX, &nRFAddY ) )
+ {
+ bRFMouse = TRUE; // die anderen Variablen sind oben initialisiert
+
+ if ( pViewData->GetActivePart() != eWhich )
+ pViewData->GetView()->ActivatePart( eWhich ); //! schon oben immer ???
+
+ // CaptureMouse();
+ StartTracking();
+ return;
+ }
+
+ BOOL bCrossPointer = TestMouse( rMEvt, TRUE );
+ if ( bCrossPointer )
+ {
+ if ( bDouble )
+ pViewData->GetView()->FillCrossDblClick();
+ else
+ pScMod->InputEnterHandler(); // Autofill etc.
+ }
+
+ if ( !bCrossPointer )
+ {
+ nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource,
+ &nPagebreakBreak, &nPagebreakPrev );
+ if (nPagebreakMouse)
+ {
+ bPagebreakDrawn = FALSE;
+ // CaptureMouse();
+ StartTracking();
+ PagebreakMove( rMEvt, FALSE );
+ return;
+ }
+ }
+
+ if (!bFormulaMode && !bEditMode && rMEvt.IsLeft())
+ {
+ if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) )
+ {
+ //if (DrawHasMarkedObj())
+ // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert
+ return;
+ }
+
+ pViewData->GetViewShell()->SetDrawShell( FALSE ); // kein Draw-Objekt selektiert
+
+ // TestMouse schon oben passiert
+ }
+
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+
+ //
+ // AutoFilter buttons
+ //
+
+ if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() )
+ {
+ ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*)
+ pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
+ if (pAttr->HasAutoFilter())
+ {
+ if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
+ return;
+ }
+ if (pAttr->HasButton())
+ {
+ DoPushButton( nPosX, nPosY, rMEvt ); // setzt evtl. bPivotMouse / bDPMouse
+ return;
+ }
+
+ // List Validity drop-down button
+
+ if ( bListValButton )
+ {
+ Rectangle aButtonRect = GetListValButtonRect( aListValPos );
+ if ( aButtonRect.IsInside( aPos ) )
+ {
+ DoAutoFilterMenue( aListValPos.Col(), aListValPos.Row(), TRUE );
+
+ nMouseStatus = SC_GM_FILTER; // not set in DoAutoFilterMenue for bDataSelect
+ CaptureMouse();
+ return;
+ }
+ }
+ }
+
+ //
+ // scenario selection
+ //
+
+ ScRange aScenRange;
+ if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) )
+ {
+ DoScenarioMenue( aScenRange );
+ return;
+ }
+
+ //
+ // Doppelklick angefangen ?
+ //
+
+ // StopMarking kann aus DrawMouseButtonDown gerufen werden
+
+ if ( nMouseStatus != SC_GM_IGNORE && !bRefMode )
+ {
+ if ( bDouble && !bCrossPointer )
+ {
+ if (nMouseStatus == SC_GM_TABDOWN)
+ nMouseStatus = SC_GM_DBLDOWN;
+ }
+ else
+ nMouseStatus = SC_GM_TABDOWN;
+ }
+
+ //
+ // Links in Edit-Zellen
+ //
+
+ BOOL bAlt = rMEvt.IsMod2();
+ if ( !bAlt && rMEvt.IsLeft() &&
+ GetEditUrl(rMEvt.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
+ {
+ SetPointer( Pointer( POINTER_REFHAND ) );
+ nMouseStatus = SC_GM_URLDOWN; // auch nur dann beim ButtonUp ausfuehren
+ return;
+ }
+
+ //
+ // Gridwin - SelectionEngine
+ //
+
+ if ( rMEvt.IsLeft() )
+ {
+ ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
+ pSelEng->SetWindow(this);
+ pSelEng->SetWhich(eWhich);
+ pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
+
+ // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
+ if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) )
+ {
+ if (IsMouseCaptured())
+ {
+ // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
+ //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
+ ReleaseMouse();
+ StartTracking();
+ }
+ pViewData->GetMarkData().SetMarking(TRUE);
+ return;
+ }
+ }
+}
+
+void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ aCurMousePos = rMEvt.GetPosPixel();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ // #i41690# detect a MouseButtonUp call from within MouseButtonDown
+ // (possible through Reschedule from storing an OLE object that is deselected)
+
+ if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN )
+ nNestedButtonState = SC_NESTEDBUTTON_UP;
+
+ if (nButtonDown != rMEvt.GetButtons())
+ nMouseStatus = SC_GM_IGNORE; // reset und return
+
+ nButtonDown = 0;
+
+ if (nMouseStatus == SC_GM_IGNORE)
+ {
+ nMouseStatus = SC_GM_NONE;
+ // Selection-Engine: Markieren abbrechen
+ pViewData->GetView()->GetSelEngine()->Reset();
+ rMark.SetMarking(FALSE);
+ if (pViewData->IsAnyFillMode())
+ {
+ pViewData->GetView()->StopRefMode();
+ pViewData->ResetFillMode();
+ }
+ StopMarking();
+ DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
+ ReleaseMouse();
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_FILTER)
+ {
+ if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
+ {
+ if (mpFilterButton.get())
+ {
+ bool bFilterActive = IsAutoFilterActive(
+ pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );
+
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
+ }
+ nMouseStatus = SC_GM_NONE;
+ ReleaseMouse();
+ return; // da muss nix mehr passieren
+ }
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
+ return;
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ if (bEEMouse && pViewData->HasEditView( eWhich ))
+ {
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ pEditView->MouseButtonUp( rMEvt );
+
+ if ( rMEvt.IsMiddle() &&
+ GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
+ {
+ // EditView may have pasted from selection
+ pScMod->InputChanged( pEditView );
+ }
+ else
+ pScMod->InputSelection( pEditView ); // parentheses etc.
+
+ pViewData->GetView()->InvalidateAttribs();
+ rBindings.Invalidate( SID_HYPERLINK_GETLINK );
+ bEEMouse = FALSE;
+ return;
+ }
+
+ if (bDPMouse)
+ {
+ DPMouseButtonUp( rMEvt ); // resets bDPMouse
+ return;
+ }
+
+ if (bRFMouse)
+ {
+ RFMouseMove( rMEvt, TRUE ); // Range wieder richtigherum
+ bRFMouse = FALSE;
+ SetPointer( Pointer( POINTER_ARROW ) );
+ ReleaseMouse();
+ return;
+ }
+
+ if (nPagebreakMouse)
+ {
+ PagebreakMove( rMEvt, TRUE );
+ nPagebreakMouse = SC_PD_NONE;
+ SetPointer( Pointer( POINTER_ARROW ) );
+ ReleaseMouse();
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus
+ {
+ SfxUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager();
+ if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE )
+ pMgr->Undo();
+ else
+ Sound::Beep();
+ return;
+ }
+
+ if (DrawMouseButtonUp(rMEvt)) // includes format paint brush handling for drawing objects
+ return;
+
+ rMark.SetMarking(FALSE);
+
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ if (pViewData->IsFillMode() ||
+ ( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() ))
+ {
+ nScFillModeMouseModifier = rMEvt.GetModifier();
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
+// DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
+// "Block falsch fuer AutoFill" );
+ ScRange aDelRange;
+ BOOL bIsDel = pViewData->GetDelMark( aDelRange );
+
+ ScViewFunc* pView = pViewData->GetView();
+ pView->StopRefMode();
+ pViewData->ResetFillMode();
+ pView->GetFunctionSet()->SetAnchorFlag( FALSE ); // #i5819# don't use AutoFill anchor flag for selection
+
+ if ( bIsDel )
+ {
+ pView->MarkRange( aDelRange, FALSE );
+ pView->DeleteContents( IDF_CONTENTS );
+ SCTAB nTab = pViewData->GetTabNo();
+ ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
+ if ( aBlockRange != aDelRange )
+ {
+ if ( aDelRange.aStart.Row() == nStartRow )
+ aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 );
+ else
+ aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 );
+ pView->MarkRange( aBlockRange, FALSE );
+ }
+ }
+ else
+ pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else if (pViewData->GetFillMode() == SC_FILL_MATRIX)
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
+ ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
+ SCCOL nFillCol = pViewData->GetRefEndX();
+ SCROW nFillRow = pViewData->GetRefEndY();
+ ScAddress aEndPos( nFillCol, nFillRow, nTab );
+
+ ScTabView* pView = pViewData->GetView();
+ pView->StopRefMode();
+ pViewData->ResetFillMode();
+ pView->GetFunctionSet()->SetAnchorFlag( FALSE );
+
+ if ( aEndPos != aBlockRange.aEnd )
+ {
+ pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, FALSE );
+ pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) );
+ }
+ }
+ else if (pViewData->IsAnyFillMode())
+ {
+ // Embedded-Area has been changed
+ ScTabView* pView = pViewData->GetView();
+ pView->StopRefMode();
+ pViewData->ResetFillMode();
+ pView->GetFunctionSet()->SetAnchorFlag( FALSE );
+ pViewData->GetDocShell()->UpdateOle(pViewData);
+ }
+
+ BOOL bRefMode = pViewData->IsRefMode();
+ if (bRefMode)
+ pScMod->EndReference();
+
+ //
+ // Giesskannen-Modus (Gestalter)
+ //
+
+ if (pScMod->GetIsWaterCan())
+ {
+ // Abfrage auf Undo schon oben
+
+ ScStyleSheetPool* pStylePool = (ScStyleSheetPool*)
+ (pViewData->GetDocument()->
+ GetStyleSheetPool());
+ if ( pStylePool )
+ {
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
+ pStylePool->GetActualStyleSheet();
+
+ if ( pStyleSheet )
+ {
+ SfxStyleFamily eFamily = pStyleSheet->GetFamily();
+
+ switch ( eFamily )
+ {
+ case SFX_STYLE_FAMILY_PARA:
+ pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet );
+ pViewData->GetView()->DoneBlockMode();
+ break;
+
+ case SFX_STYLE_FAMILY_PAGE:
+ pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(),
+ pStyleSheet->GetName() );
+
+ ScPrintFunc( pViewData->GetDocShell(),
+ pViewData->GetViewShell()->GetPrinter(TRUE),
+ pViewData->GetTabNo() ).UpdatePages();
+
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ ScDBFunc* pView = pViewData->GetView();
+ ScDocument* pBrushDoc = pView->GetBrushDocument();
+ if ( pBrushDoc )
+ {
+ pView->PasteFromClip( IDF_ATTRIB, pBrushDoc );
+ if ( !pView->IsPaintBrushLocked() )
+ pView->ResetBrushDocument(); // invalidates pBrushDoc pointer
+ }
+
+ //
+ // double click (only left button)
+ //
+
+ BOOL bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() );
+ if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() )
+ {
+ // data pilot table
+ 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, nTab );
+ if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
+ {
+ ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );
+
+ // Check for header drill-down first.
+ sheet::DataPilotTableHeaderData aData;
+ pDPObj->GetHeaderPositionData(aCellPos, aData);
+
+ if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
+ ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) )
+ {
+ USHORT nDummy;
+ if ( pView->HasSelectionForDrillDown( nDummy ) )
+ {
+ // execute slot to show dialog
+ pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else
+ {
+ // toggle single entry
+ ScDPObject aNewObj( *pDPObj );
+ pDPObj->ToggleDetails( aData, &aNewObj );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, TRUE, FALSE );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ }
+ else
+ {
+ // Check if the data area is double-clicked.
+
+ Sequence<sheet::DataPilotFieldFilter> aFilters;
+ if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) )
+ pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters );
+ else
+ Sound::Beep(); // nothing to expand/collapse/show
+ }
+
+ return;
+ }
+
+ // 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 )
+ {
+ // 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;
+ }
+
+ //
+ // Links in edit cells
+ //
+
+ BOOL bAlt = rMEvt.IsMod2();
+ if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN )
+ {
+ // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
+
+ String aName, aUrl, aTarget;
+ if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) )
+ {
+ nMouseStatus = SC_GM_NONE; // keinen Doppelklick anfangen
+ ScGlobal::OpenURL( aUrl, aTarget );
+
+ // fire worksheet_followhyperlink event
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor();
+ if( xVbaEvents.is() ) try
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ ScBaseCell* pCell = NULL;
+ if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) )
+ {
+ ScAddress aCellPos( nPosX, nPosY, nTab );
+ uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) );
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[0] <<= xCell;
+ xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return;
+ }
+ }
+
+ //
+ // Gridwin - SelectionEngine
+ //
+
+ // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
+ // TRUE for any call, so IsLeft must be checked here, too.
+
+ if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) )
+ {
+// rMark.MarkToSimple();
+ pViewData->GetView()->UpdateAutoFillMark();
+
+ SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher();
+ BOOL bFormulaMode = pScMod->IsFormulaMode();
+ DBG_ASSERT( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" );
+
+ // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
+ // multiple selection, so the argument string completely describes the selection,
+ // and executing the slot won't change the existing selection (executing the slot
+ // here and from a recorded macro is treated equally)
+
+ if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() )
+ {
+ String aAddr; // CurrentCell
+ if( rMark.IsMarked() )
+ {
+// BOOL bKeep = rMark.IsMultiMarked(); //! wohin damit ???
+
+ ScRange aScRange;
+ rMark.GetMarkArea( aScRange );
+ aScRange.Format( aAddr, SCR_ABS );
+ if ( aScRange.aStart == aScRange.aEnd )
+ {
+ // make sure there is a range selection string even for a single cell
+ String aSingle = aAddr;
+ aAddr.Append( (sal_Char) ':' );
+ aAddr.Append( aSingle );
+ }
+
+ //! SID_MARKAREA gibts nicht mehr ???
+ //! was passiert beim Markieren mit dem Cursor ???
+ }
+ else // nur Cursor bewegen
+ {
+ ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 );
+ aScAddress.Format( aAddr, SCA_ABS );
+ }
+
+ SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
+ pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aPosItem, (void*)0L );
+
+ pViewData->GetView()->InvalidateAttribs();
+ }
+ return;
+ }
+}
+
+void ScGridWindow::FakeButtonUp()
+{
+ if ( nButtonDown )
+ {
+ MouseEvent aEvent( aCurMousePos ); // nButtons = 0 -> ignore
+ MouseButtonUp( aEvent );
+ }
+}
+
+void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ aCurMousePos = rMEvt.GetPosPixel();
+
+ if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() )
+ HideNoteMarker();
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
+ return;
+
+ // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
+ // nicht anders mit:
+
+ if (bEEMouse && nButtonDown && !rMEvt.GetButtons())
+ {
+ bEEMouse = FALSE;
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_IGNORE)
+ return;
+
+ if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus -> nur auf Up warten
+ return;
+
+ if ( pViewData->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
+ {
+ SetPointer( Pointer( POINTER_FILL ) );
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_FILTER && pFilterBox)
+ {
+ Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
+ if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) )
+ {
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
+ {
+ if (mpFilterButton.get())
+ {
+ mpFilterButton->setHasHiddenMember(false);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
+ }
+ ReleaseMouse();
+ pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
+ return;
+ }
+ }
+
+ BOOL bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
+
+ if (bEEMouse && pViewData->HasEditView( eWhich ))
+ {
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ pEditView->MouseMove( rMEvt );
+ return;
+ }
+
+ if (bDPMouse)
+ {
+ DPMouseMove( rMEvt );
+ return;
+ }
+
+ if (bRFMouse)
+ {
+ RFMouseMove( rMEvt, FALSE );
+ return;
+ }
+
+ if (nPagebreakMouse)
+ {
+ PagebreakMove( rMEvt, FALSE );
+ return;
+ }
+
+ // anderen Mauszeiger anzeigen?
+
+ BOOL bEditMode = pViewData->HasEditView(eWhich);
+
+ //! Testen ob RefMode-Dragging !!!
+ if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ SCCOL nEndCol = pViewData->GetEditEndCol();
+ SCROW nEndRow = pViewData->GetEditEndRow();
+
+ if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
+ nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
+ {
+ // Field can only be URL field
+ BOOL bAlt = rMEvt.IsMod2();
+ if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() )
+ SetPointer( Pointer( POINTER_REFHAND ) );
+ else if ( pEditView && pEditView->GetEditEngine()->IsVertical() )
+ SetPointer( Pointer( POINTER_TEXT_VERTICAL ) );
+ else
+ SetPointer( Pointer( POINTER_TEXT ) );
+ return;
+ }
+ }
+
+ BOOL bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush();
+ if (bWater)
+ SetPointer( Pointer(POINTER_FILL) );
+
+ if (!bWater)
+ {
+ BOOL bCross = FALSE;
+
+ // Range-Finder
+
+ BOOL bCorner;
+ if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) )
+ {
+ if (bCorner)
+ SetPointer( Pointer( POINTER_CROSS ) );
+ else
+ SetPointer( Pointer( POINTER_HAND ) );
+ bCross = TRUE;
+ }
+
+ // Page-Break-Modus
+
+ USHORT nBreakType;
+ if ( !nButtonDown && pViewData->IsPagebreakMode() &&
+ ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 )
+ {
+ PointerStyle eNew = POINTER_ARROW;
+ switch ( nBreakType )
+ {
+ case SC_PD_RANGE_L:
+ case SC_PD_RANGE_R:
+ case SC_PD_BREAK_H:
+ eNew = POINTER_ESIZE;
+ break;
+ case SC_PD_RANGE_T:
+ case SC_PD_RANGE_B:
+ case SC_PD_BREAK_V:
+ eNew = POINTER_SSIZE;
+ break;
+ case SC_PD_RANGE_TL:
+ case SC_PD_RANGE_BR:
+ eNew = POINTER_SESIZE;
+ break;
+ case SC_PD_RANGE_TR:
+ case SC_PD_RANGE_BL:
+ eNew = POINTER_NESIZE;
+ break;
+ }
+ SetPointer( Pointer( eNew ) );
+ bCross = TRUE;
+ }
+
+ // Fill-Cursor anzeigen ?
+
+ if ( !bFormulaMode && !nButtonDown )
+ if (TestMouse( rMEvt, FALSE ))
+ bCross = TRUE;
+
+ if ( nButtonDown && pViewData->IsAnyFillMode() )
+ {
+ SetPointer( Pointer( POINTER_CROSS ) );
+ bCross = TRUE;
+ nScFillModeMouseModifier = rMEvt.GetModifier(); // ausgewertet bei AutoFill und Matrix
+ }
+
+ if (!bCross)
+ {
+ BOOL bAlt = rMEvt.IsMod2();
+
+ if (bEditMode) // Edit-Mode muss zuerst kommen!
+ SetPointer( Pointer( POINTER_ARROW ) );
+ else if ( !bAlt && !nButtonDown &&
+ GetEditUrl(rMEvt.GetPosPixel()) )
+ SetPointer( Pointer( POINTER_REFHAND ) );
+ else if ( DrawMouseMove(rMEvt) ) // setzt Pointer um
+ return;
+ }
+ }
+
+ if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) )
+ return;
+}
+
+void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt )
+{
+ rEvent.Modifiers = 0;
+ if ( rEvt.IsShift() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT;
+ if ( rEvt.IsMod1() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1;
+ if ( rEvt.IsMod2() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2;
+ if ( rEvt.IsMod3() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3;
+
+ rEvent.Buttons = 0;
+ if ( rEvt.IsLeft() )
+ rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT;
+ if ( rEvt.IsRight() )
+ rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT;
+ if ( rEvt.IsMiddle() )
+ rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE;
+
+ rEvent.X = rEvt.GetPosPixel().X();
+ rEvent.Y = rEvt.GetPosPixel().Y();
+ rEvent.ClickCount = rEvt.GetClicks();
+ rEvent.PopupTrigger = sal_False;
+}
+
+long ScGridWindow::PreNotify( NotifyEvent& rNEvt )
+{
+ bool bDone = false;
+ USHORT nType = rNEvt.GetType();
+ if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
+ {
+ Window* pWindow = rNEvt.GetWindow();
+ if (pWindow == this && pViewData)
+ {
+ SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp && pImp->IsMouseListening())
+ {
+ ::com::sun::star::awt::MouseEvent aEvent;
+ lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() );
+ if ( rNEvt.GetWindow() )
+ aEvent.Source = rNEvt.GetWindow()->GetComponentInterface();
+ if ( nType == EVENT_MOUSEBUTTONDOWN)
+ bDone = pImp->MousePressed( aEvent );
+ else
+ bDone = pImp->MouseReleased( aEvent );
+ }
+ }
+ }
+ }
+ }
+ if (bDone) // event consumed by a listener
+ {
+ if ( nType == EVENT_MOUSEBUTTONDOWN )
+ {
+ const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent();
+ if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 )
+ {
+ // If a listener returned true for a right-click call, also prevent opening the context menu
+ // (this works only if the context menu is opened on mouse-down)
+ nMouseStatus = SC_GM_IGNORE;
+ }
+ }
+
+ return 1;
+ }
+ else
+ return Window::PreNotify( rNEvt );
+}
+
+void ScGridWindow::Tracking( const TrackingEvent& rTEvt )
+{
+ // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
+ // die verschiedenen MouseHandler verteilen...
+
+ const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
+
+ if ( rTEvt.IsTrackingCanceled() ) // alles abbrechen...
+ {
+ if (!pViewData->GetView()->IsInActivatePart())
+ {
+ if (bDPMouse)
+ bDPMouse = FALSE; // gezeichnet wird per bDragRect
+ if (bDragRect)
+ {
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ }
+ if (bRFMouse)
+ {
+ RFMouseMove( rMEvt, TRUE ); // richtig abbrechen geht dabei nicht...
+ bRFMouse = FALSE;
+ }
+ if (nPagebreakMouse)
+ {
+ // if (bPagebreakDrawn)
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
+ bPagebreakDrawn = FALSE;
+ UpdateDragRectOverlay();
+ nPagebreakMouse = SC_PD_NONE;
+ }
+
+ SetPointer( Pointer( POINTER_ARROW ) );
+ StopMarking();
+ MouseButtonUp( rMEvt ); // mit Status SC_GM_IGNORE aus StopMarking
+
+ BOOL bRefMode = pViewData->IsRefMode();
+ if (bRefMode)
+ SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen
+ }
+ }
+ else if ( rTEvt.IsTrackingEnded() )
+ {
+ // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
+ // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
+ // abgebrochen wurde.
+
+ MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(),
+ rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() );
+ MouseButtonUp( aUpEvt );
+ }
+ else
+ MouseMove( rMEvt );
+}
+
+void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
+{
+ if ( pFilterBox || nPagebreakMouse )
+ return;
+
+ HideNoteMarker();
+
+ CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, TRUE );
+
+ if (bEEMouse && pViewData->HasEditView( eWhich ))
+ {
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+
+ // #63263# don't remove the edit view while switching views
+ ScModule* pScMod = SC_MOD();
+ pScMod->SetInEditCommand( TRUE );
+
+ pEditView->Command( aDragEvent );
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if (pHdl)
+ pHdl->DataChanged();
+
+ pScMod->SetInEditCommand( FALSE );
+ if (!pViewData->IsActive()) // dropped to different view?
+ {
+ ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if ( pViewHdl && pViewData->HasEditView( eWhich ) )
+ {
+ pViewHdl->CancelHandler();
+ ShowCursor(); // missing from KillEditView
+ }
+ }
+ }
+ else
+ if ( !DrawCommand(aDragEvent) )
+ pViewData->GetView()->GetSelEngine()->Command( aDragEvent );
+}
+
+void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin )
+{
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, TRUE );
+ aEditArea.Right() = aEditArea.Left();
+ aEditArea = pWin->PixelToLogic( aEditArea );
+ pWin->SetCursorRect( &aEditArea );
+}
+
+void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt )
+{
+ // The command event is send to the window after a possible context
+ // menu from an inplace client is closed. Now we have the chance to
+ // deactivate the inplace client without any problem regarding parent
+ // windows and code on the stack.
+ // For more information, see #126086# and #128122#
+ USHORT nCmd = rCEvt.GetCommand();
+ ScTabViewShell* pTabViewSh = pViewData->GetViewShell();
+ SfxInPlaceClient* pClient = pTabViewSh->GetIPClient();
+ if ( pClient &&
+ pClient->IsObjectInPlaceActive() &&
+ nCmd == COMMAND_CONTEXTMENU )
+ {
+ pTabViewSh->DeactivateOle();
+ return;
+ }
+
+ ScModule* pScMod = SC_MOD();
+ DBG_ASSERT( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
+
+ if ( nCmd == COMMAND_STARTEXTTEXTINPUT ||
+ nCmd == COMMAND_ENDEXTTEXTINPUT ||
+ nCmd == COMMAND_EXTTEXTINPUT ||
+ nCmd == COMMAND_CURSORPOS )
+ {
+ BOOL bEditView = pViewData->HasEditView( eWhich );
+ if (!bEditView)
+ {
+ // only if no cell editview is active, look at drawview
+ SdrView* pSdrView = pViewData->GetView()->GetSdrView();
+ if ( pSdrView )
+ {
+ OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
+ if ( pOlView && pOlView->GetWindow() == this )
+ {
+ pOlView->Command( rCEvt );
+ return; // done
+ }
+ }
+ }
+
+ if ( nCmd == COMMAND_CURSORPOS && !bEditView )
+ {
+ // #88458# CURSORPOS may be called without following text input,
+ // to set the input method window position
+ // -> input mode must not be started,
+ // manually calculate text insert position if not in input mode
+
+ lcl_SetTextCursorPos( pViewData, eWhich, this );
+ return;
+ }
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if ( pHdl )
+ {
+ pHdl->InputCommand( rCEvt, TRUE );
+ return; // done
+ }
+
+ Window::Command( rCEvt );
+ return;
+ }
+
+ if ( nCmd == COMMAND_VOICE )
+ {
+ // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
+ // also muss es eine EditView oder ein editiertes Zeichenobjekt geben
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if ( pHdl && pViewData->HasEditView( eWhich ) )
+ {
+ EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0
+ pHdl->DataChanging();
+ pEditView->Command( rCEvt );
+ pHdl->DataChanged();
+ return; // erledigt
+ }
+ SdrView* pSdrView = pViewData->GetView()->GetSdrView();
+ if ( pSdrView )
+ {
+ OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
+ if ( pOlView && pOlView->GetWindow() == this )
+ {
+ pOlView->Command( rCEvt );
+ return; // erledigt
+ }
+ }
+ Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern...
+ return;
+ }
+
+ if ( nCmd == COMMAND_PASTESELECTION )
+ {
+ if ( bEEMouse )
+ {
+ // EditEngine handles selection in MouseButtonUp - no action
+ // needed in command handler
+ }
+ else
+ {
+ PasteSelection( rCEvt.GetMousePosPixel() );
+ }
+ return;
+ }
+
+ if ( nCmd == COMMAND_INPUTLANGUAGECHANGE )
+ {
+ // #i55929# Font and font size state depends on input language if nothing is selected,
+ // so the slots have to be invalidated when the input language is changed.
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ return;
+ }
+
+ if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
+ {
+ BOOL bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich );
+ if (!bDone)
+ Window::Command(rCEvt);
+ return;
+ }
+ // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
+ BOOL bDisable = pScMod->IsFormulaMode() ||
+ pScMod->IsModalMode(pViewData->GetSfxDocShell());
+ if (bDisable)
+ return;
+
+ if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() )
+ {
+ BOOL bMouse = rCEvt.IsMouseEvent();
+ if ( bMouse && nMouseStatus == SC_GM_IGNORE )
+ return;
+
+ if (pViewData->IsAnyFillMode())
+ {
+ pViewData->GetView()->StopRefMode();
+ pViewData->ResetFillMode();
+ }
+ ReleaseMouse();
+ StopMarking();
+
+ Point aPosPixel = rCEvt.GetMousePosPixel();
+ Point aMenuPos = aPosPixel;
+
+ if ( bMouse )
+ {
+ SCsCOL nCellX = -1;
+ SCsROW nCellY = -1;
+ pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSelectAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ // This sheet is protected. Check if a context menu is allowed on this cell.
+ bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED);
+ bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if (bCellProtected)
+ bSelectAllowed = bSelProtected;
+ else
+ bSelectAllowed = bSelUnprotected;
+ }
+ if (!bSelectAllowed)
+ // Selecting this cell is not allowed, neither is context menu.
+ return;
+
+ // #i18735# First select the item under the mouse pointer.
+ // This can change the selection, and the view state (edit mode, etc).
+ SelectForContextMenu( aPosPixel, nCellX, nCellY );
+ }
+
+ BOOL bDone = FALSE;
+ BOOL bEdit = pViewData->HasEditView(eWhich);
+ if ( !bEdit )
+ {
+ // Edit-Zelle mit Spelling-Errors ?
+ if ( bMouse && GetEditUrlOrError( TRUE, aPosPixel ) )
+ {
+ // GetEditUrlOrError hat den Cursor schon bewegt
+
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ bEdit = pViewData->HasEditView(eWhich); // hat's geklappt ?
+
+ DBG_ASSERT( bEdit, "kann nicht in Edit-Modus schalten" );
+ }
+ }
+ if ( bEdit )
+ {
+ EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0
+
+ if ( !bMouse )
+ {
+ Cursor* pCur = pEditView->GetCursor();
+ if ( pCur )
+ {
+ Point aLogicPos = pCur->GetPos();
+ // use the position right of the cursor (spell popup is opened if
+ // the cursor is before the word, but not if behind it)
+ aLogicPos.X() += pCur->GetWidth();
+ aLogicPos.Y() += pCur->GetHeight() / 2; // center vertically
+ aMenuPos = LogicToPixel( aLogicPos );
+ }
+ }
+
+ // if edit mode was just started above, online spelling may be incomplete
+ pEditView->GetEditEngine()->CompleteOnlineSpelling();
+
+ // IsCursorAtWrongSpelledWord could be used for !bMouse
+ // if there was a corresponding ExecuteSpellPopup call
+
+ if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) )
+ {
+ // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
+ // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
+ // (Bug #40968#)
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if (pHdl)
+ pHdl->SetModified();
+
+ Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl );
+ pEditView->ExecuteSpellPopup( aMenuPos, &aLink );
+
+ bDone = TRUE;
+ }
+ }
+ else if ( !bMouse )
+ {
+ // non-edit menu by keyboard -> use lower right of cell cursor position
+
+ SCCOL nCurX = pViewData->GetCurX();
+ SCROW nCurY = pViewData->GetCurY();
+ aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, TRUE );
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix );
+ aMenuPos.X() += nSizeXPix;
+ aMenuPos.Y() += nSizeYPix;
+
+ if (pViewData)
+ {
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ if (pViewSh)
+ {
+ // Is a draw object selected?
+
+ SdrView* pDrawView = pViewSh->GetSdrView();
+ if (pDrawView && pDrawView->AreObjectsMarked())
+ {
+ // #100442#; the conext menu should open in the middle of the selected objects
+ Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect()));
+ aMenuPos = aSelectRect.Center();
+ }
+ }
+ }
+ }
+
+ if (!bDone)
+ {
+ SfxDispatcher::ExecutePopup( 0, this, &aMenuPos );
+ }
+ }
+}
+
+void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY )
+{
+ // #i18735# if the click was outside of the current selection,
+ // the cursor is moved or an object at the click position selected.
+ // (see SwEditWin::SelectMenuPosition in Writer)
+
+ ScTabView* pView = pViewData->GetView();
+ ScDrawView* pDrawView = pView->GetScDrawView();
+
+ // check cell edit mode
+
+ if ( pViewData->HasEditView(eWhich) )
+ {
+ ScModule* pScMod = SC_MOD();
+ SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
+ SCROW nEditStartRow = pViewData->GetEditViewRow();
+ SCCOL nEditEndCol = pViewData->GetEditEndCol();
+ SCROW nEditEndRow = pViewData->GetEditEndRow();
+
+ if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol &&
+ nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow )
+ {
+ // handle selection within the EditView
+
+ EditView* pEditView = pViewData->GetEditView( eWhich ); // not NULL (HasEditView)
+ EditEngine* pEditEngine = pEditView->GetEditEngine();
+ Rectangle aOutputArea = pEditView->GetOutputArea();
+ Rectangle aVisArea = pEditView->GetVisArea();
+
+ Point aTextPos = PixelToLogic( rPosPixel );
+ if ( pEditEngine->IsVertical() ) // have to manually transform position
+ {
+ aTextPos -= aOutputArea.TopRight();
+ long nTemp = -aTextPos.X();
+ aTextPos.X() = aTextPos.Y();
+ aTextPos.Y() = nTemp;
+ }
+ else
+ aTextPos -= aOutputArea.TopLeft();
+ aTextPos += aVisArea.TopLeft(); // position in the edit document
+
+ EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos);
+ ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
+ ESelection aSelection = pEditView->GetSelection();
+ aSelection.Adjust(); // needed for IsLess/IsGreater
+ if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
+ {
+ // clicked outside the selected text - deselect and move text cursor
+ MouseEvent aEvent( rPosPixel );
+ pEditView->MouseButtonDown( aEvent );
+ pEditView->MouseButtonUp( aEvent );
+ pScMod->InputSelection( pEditView );
+ }
+
+ return; // clicked within the edit view - keep edit mode
+ }
+ else
+ {
+ // outside of the edit view - end edit mode, regardless of cell selection, then continue
+ pScMod->InputEnterHandler();
+ }
+ }
+
+ // check draw text edit mode
+
+ Point aLogicPos = PixelToLogic( rPosPixel ); // after cell edit mode is ended
+ if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() )
+ {
+ OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView();
+ Rectangle aOutputArea = pOlView->GetOutputArea();
+ if ( aOutputArea.IsInside( aLogicPos ) )
+ {
+ // handle selection within the OutlinerView
+
+ Outliner* pOutliner = pOlView->GetOutliner();
+ const EditEngine& rEditEngine = pOutliner->GetEditEngine();
+ Rectangle aVisArea = pOlView->GetVisArea();
+
+ Point aTextPos = aLogicPos;
+ if ( pOutliner->IsVertical() ) // have to manually transform position
+ {
+ aTextPos -= aOutputArea.TopRight();
+ long nTemp = -aTextPos.X();
+ aTextPos.X() = aTextPos.Y();
+ aTextPos.Y() = nTemp;
+ }
+ else
+ aTextPos -= aOutputArea.TopLeft();
+ aTextPos += aVisArea.TopLeft(); // position in the edit document
+
+ EPosition aDocPosition = rEditEngine.FindDocPosition(aTextPos);
+ ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
+ ESelection aSelection = pOlView->GetSelection();
+ aSelection.Adjust(); // needed for IsLess/IsGreater
+ if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
+ {
+ // clicked outside the selected text - deselect and move text cursor
+ // use DrawView to allow extra handling there (none currently)
+ MouseEvent aEvent( rPosPixel );
+ pDrawView->MouseButtonDown( aEvent, this );
+ pDrawView->MouseButtonUp( aEvent, this );
+ }
+
+ return; // clicked within the edit area - keep edit mode
+ }
+ else
+ {
+ // Outside of the edit area - end text edit mode, then continue.
+ // DrawDeselectAll also ends text edit mode and updates the shells.
+ // If the click was on the edited object, it will be selected again below.
+ pView->DrawDeselectAll();
+ }
+ }
+
+ // look for existing selection
+
+ BOOL bHitSelected = FALSE;
+ if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) )
+ {
+ // clicked on selected object -> don't change anything
+ bHitSelected = TRUE;
+ }
+ else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) )
+ {
+ // clicked on selected cell -> don't change anything
+ bHitSelected = TRUE;
+ }
+
+ // select drawing object or move cell cursor
+
+ if ( !bHitSelected )
+ {
+ BOOL bWasDraw = ( pDrawView && pDrawView->AreObjectsMarked() );
+ BOOL bHitDraw = FALSE;
+ if ( pDrawView )
+ {
+ pDrawView->UnmarkAllObj();
+ // Unlock the Internal Layer in order to activate the context menu.
+ // re-lock in ScDrawView::MarkListHasChanged()
+ lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData);
+ bHitDraw = pDrawView->MarkObj( aLogicPos );
+ // draw shell is activated in MarkListHasChanged
+ }
+ if ( !bHitDraw )
+ {
+ pView->Unmark();
+ pView->SetCursor(nCellX, nCellY);
+ if ( bWasDraw )
+ pViewData->GetViewShell()->SetDrawShell( FALSE ); // switch shells
+ }
+ }
+}
+
+void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ // #96965# Cursor control for ref input dialog
+ if( SC_MOD()->IsRefDialogOpen() )
+ {
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
+ {
+ SC_MOD()->EndReference();
+ return;
+ }
+ else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) )
+ {
+ ScRange aRef(
+ pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
+ pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
+ SC_MOD()->SetReference( aRef, pViewData->GetDocument() );
+ return;
+ }
+ }
+ // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
+ else if( !pViewData->IsAnyFillMode() )
+ {
+ // query for existing note marker before calling ViewShell's keyboard handling
+ // which may remove the marker
+ BOOL bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() );
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ if (pViewData->GetDocShell()->GetProgress())
+ return;
+
+ if (DrawKeyInput(rKEvt))
+ return;
+
+ if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
+ { //! DrawShell abfragen !!!
+ if (pViewSh->TabKeyInput(rKEvt))
+ return;
+ }
+ else
+ if (pViewSh->SfxViewShell::KeyInput(rKEvt)) // von SfxViewShell
+ return;
+
+ KeyCode aCode = rKEvt.GetKeyCode();
+ if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 )
+ {
+ if ( bHadKeyMarker )
+ HideNoteMarker();
+ else
+ pViewSh->Escape();
+ return;
+ }
+ if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 )
+ {
+ // ctrl-F1 shows or hides the note or redlining info for the cursor position
+ // (hard-coded because F1 can't be configured)
+
+ if ( bHadKeyMarker )
+ HideNoteMarker(); // hide when previously visible
+ else
+ ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), TRUE );
+ return;
+ }
+ }
+
+ Window::KeyInput(rKEvt);
+}
+
+void ScGridWindow::StopMarking()
+{
+ DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
+
+ if (nButtonDown)
+ {
+ pViewData->GetMarkData().SetMarking(FALSE);
+ nMouseStatus = SC_GM_IGNORE;
+ }
+}
+
+void ScGridWindow::UpdateInputContext()
+{
+ BOOL bReadOnly = pViewData->GetDocShell()->IsReadOnly();
+ ULONG nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT );
+
+ // when font from InputContext is used,
+ // it must be taken from the cursor position's cell attributes
+
+ InputContext aContext;
+ aContext.SetOptions( nOptions );
+ SetInputContext( aContext );
+}
+
+//--------------------------------------------------------
+
+ // sensitiver Bereich (Pixel)
+#define SCROLL_SENSITIVE 20
+
+BOOL ScGridWindow::DropScroll( const Point& rMousePos )
+{
+/* doch auch auf nicht aktiven Views...
+ if ( !pViewData->IsActive() )
+ return FALSE;
+*/
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ Size aSize = GetOutputSizePixel();
+
+ if (aSize.Width() > SCROLL_SENSITIVE * 3)
+ {
+ if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 )
+ nDx = -1;
+ if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE
+ && pViewData->GetPosX(WhichH(eWhich)) < MAXCOL )
+ nDx = 1;
+ }
+ if (aSize.Height() > SCROLL_SENSITIVE * 3)
+ {
+ if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 )
+ nDy = -1;
+ if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE
+ && pViewData->GetPosY(WhichV(eWhich)) < MAXROW )
+ nDy = 1;
+ }
+
+ if ( nDx != 0 || nDy != 0 )
+ {
+// if (bDragRect)
+// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+
+ if ( nDx != 0 )
+ pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 )
+ pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+
+// if (bDragRect)
+// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ }
+
+ return FALSE;
+}
+
+BOOL lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange)
+{
+ // Testet, ob bei eingeschalteten RedLining,
+ // bei einem Drop ein Scenario betroffen ist.
+
+ BOOL bReturn = FALSE;
+ SCTAB nTab = aDragRange.aStart.Tab();
+ SCTAB nTabCount = pDoc->GetTableCount();
+
+ if(pDoc->GetChangeTrack()!=NULL)
+ {
+ if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange))
+ {
+ bReturn = TRUE;
+ }
+ else
+ {
+ for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ {
+ if(pDoc->HasScenarioRange(i, aDragRange))
+ {
+ bReturn = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ return bReturn;
+}
+
+ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource )
+{
+ SCCOL nCol1 = nPosX;
+ SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() );
+ if ( nCol2 > MAXCOL )
+ {
+ nCol1 -= nCol2 - MAXCOL;
+ nCol2 = MAXCOL;
+ }
+ SCROW nRow1 = nPosY;
+ SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() );
+ if ( nRow2 > MAXROW )
+ {
+ nRow1 -= nRow2 - MAXROW;
+ nRow2 = MAXROW;
+ }
+
+ return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+}
+
+//--------------------------------------------------------
+
+extern BOOL bPasteIsDrop; // viewfun4 -> move to header
+extern BOOL bPasteIsMove; // viewfun7 -> move to header
+
+//--------------------------------------------------------
+
+sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt )
+{
+ if ( rEvt.mbLeaving )
+ {
+ // if (bDragRect)
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ return rEvt.mnAction;
+ }
+
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rData.pCellTransfer )
+ {
+ // Don't move source that would include filtered rows.
+ if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows())
+ {
+ if (bDragRect)
+ {
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+
+ Point aPos = rEvt.maPosPixel;
+
+ ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument();
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ if (pSourceDoc == pThisDoc)
+ {
+ if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) )
+ {
+ if (bDragRect) // Rechteck loeschen
+ {
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ }
+
+ //! highlight chart? (selection border?)
+
+ sal_Int8 nRet = rEvt.mnAction;
+//! if ( rEvt.GetAction() == DROP_LINK )
+//! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart
+ return nRet;
+ }
+ }
+//! else
+//! if ( rEvt.GetAction() == DROP_MOVE )
+//! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY
+
+
+ if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) // whole sheet?
+ {
+ BOOL bOk = pThisDoc->IsDocEditable();
+ return bOk ? rEvt.mnAction : 0; // don't draw selection frame
+ }
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ ScRange aSourceRange = rData.pCellTransfer->GetRange();
+ SCCOL nSourceStartX = aSourceRange.aStart.Col();
+ SCROW nSourceStartY = aSourceRange.aStart.Row();
+ SCCOL nSourceEndX = aSourceRange.aEnd.Col();
+ SCROW nSourceEndY = aSourceRange.aEnd.Row();
+ SCCOL nSizeX = nSourceEndX - nSourceStartX + 1;
+ SCROW nSizeY = nSourceEndY - nSourceStartY + 1;
+
+ if ( rEvt.mnAction != DND_ACTION_MOVE )
+ nSizeY = rData.pCellTransfer->GetNonFilteredRows(); // copy/link: no filtered rows
+
+ SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX();
+ if (nNewDragX<0) nNewDragX=0;
+ if (nNewDragX+(nSizeX-1) > MAXCOL)
+ nNewDragX = MAXCOL-(nSizeX-1);
+ SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY();
+ if (nNewDragY<0) nNewDragY=0;
+ if (nNewDragY+(nSizeY-1) > MAXROW)
+ nNewDragY = MAXROW-(nSizeY-1);
+
+ // don't break scenario ranges, don't drop on filtered
+ SCTAB nTab = pViewData->GetTabNo();
+ ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange );
+ if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) ||
+ lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) ||
+ ScViewUtil::HasFiltered( aDropRange, pThisDoc) )
+ {
+ if (bDragRect)
+ {
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+
+ InsCellCmd eDragInsertMode = INS_NONE;
+ Window::PointerState aState = GetPointerState();
+
+ // check for datapilot item sorting
+ ScDPObject* pDPObj = NULL;
+ if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL )
+ {
+ // drop on DataPilot table: sort or nothing
+
+ bool bDPSort = false;
+ if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
+ {
+ sheet::DataPilotTableHeaderData aDestData;
+ pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData );
+ bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field
+
+ // look through the source range
+ for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow )
+ for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol )
+ {
+ sheet::DataPilotTableHeaderData aSourceData;
+ pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData );
+ if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() )
+ bValid = false; // empty (subtotal) or different field
+ }
+
+ if ( bValid )
+ {
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
+ const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName );
+ if ( pDim )
+ {
+ ScRange aOutRange = pDPObj->GetOutRange();
+
+ USHORT nOrient = pDim->GetOrientation();
+ if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN )
+ {
+ eDragInsertMode = INS_CELLSRIGHT;
+ nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1;
+ bDPSort = true;
+ }
+ else if ( nOrient == sheet::DataPilotFieldOrientation_ROW )
+ {
+ eDragInsertMode = INS_CELLSDOWN;
+ nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1;
+ bDPSort = true;
+ }
+ }
+ }
+ }
+
+ if ( !bDPSort )
+ {
+ // no valid sorting in a DataPilot table -> disallow
+ if ( bDragRect )
+ {
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+ }
+ else if ( aState.mnState & KEY_MOD2 )
+ {
+ if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() )
+ {
+ long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) );
+ long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) );
+ if ( nDeltaX <= nDeltaY )
+ {
+ eDragInsertMode = INS_CELLSDOWN;
+ }
+ else
+ {
+ eDragInsertMode = INS_CELLSRIGHT;
+ }
+
+ if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY &&
+ ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX &&
+ ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) ||
+ ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX &&
+ ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY &&
+ ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) )
+ {
+ if ( bDragRect )
+ {
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+ }
+ else
+ {
+ if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) )
+ {
+ eDragInsertMode = INS_CELLSDOWN;
+
+ }
+ else
+ {
+ eDragInsertMode = INS_CELLSRIGHT;
+ }
+ }
+ }
+
+ if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY ||
+ nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY ||
+ !bDragRect || eDragInsertMode != meDragInsertMode )
+ {
+ // if (bDragRect)
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+
+ nDragStartX = nNewDragX;
+ nDragStartY = nNewDragY;
+ nDragEndX = nDragStartX+nSizeX-1;
+ nDragEndY = nDragStartY+nSizeY-1;
+ bDragRect = TRUE;
+ meDragInsertMode = eDragInsertMode;
+
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+
+ UpdateDragRectOverlay();
+
+ // show target position as tip help
+#if 0
+ if (Help::IsQuickHelpEnabled())
+ {
+ ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab );
+ String aHelpStr;
+ aRange.Format( aHelpStr, SCA_VALID ); // non-3D
+
+ Point aPos = Pointer::GetPosPixel();
+ USHORT nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT;
+ Rectangle aRect( aPos, aPos );
+ Help::ShowQuickHelp(aRect, aHelpStr, nAlign);
+ }
+#endif
+ }
+ }
+
+ return rEvt.mnAction;
+}
+
+sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rEvt.mbLeaving )
+ {
+ DrawMarkDropObj( NULL );
+ if ( rData.pCellTransfer )
+ return AcceptPrivateDrop( rEvt ); // hide drop marker for internal D&D
+ else
+ return rEvt.mnAction;
+ }
+
+ if ( pViewData->GetDocShell()->IsReadOnly() )
+ return DND_ACTION_NONE;
+
+
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ if (rData.pCellTransfer)
+ {
+ ScRange aSource = rData.pCellTransfer->GetRange();
+ if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL ||
+ aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW )
+ DropScroll( rEvt.maPosPixel );
+
+ nRet = AcceptPrivateDrop( rEvt );
+ }
+ else
+ {
+ if ( rData.aLinkDoc.Len() )
+ {
+ String aThisName;
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ if (pDocSh && pDocSh->HasName())
+ aThisName = pDocSh->GetMedium()->GetName();
+
+ if ( rData.aLinkDoc != aThisName )
+ nRet = rEvt.mnAction;
+ }
+ else if (rData.aJumpTarget.Len())
+ {
+ // internal bookmarks (from Navigator)
+ // local jumps from an unnamed document are possible only within a document
+
+ if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
+ nRet = rEvt.mnAction;
+ }
+ else
+ {
+ sal_Int8 nMyAction = rEvt.mnAction;
+
+ if ( !rData.pDrawTransfer ||
+ !IsMyModel(rData.pDrawTransfer->GetDragSourceView()) ) // drawing within the document
+ if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE )
+ nMyAction = DND_ACTION_COPY;
+
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(
+ pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) );
+ if ( pHitObj && nMyAction == DND_ACTION_LINK && !rData.pDrawTransfer )
+ {
+ if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB)
+ || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE)
+ || IsDropFormatSupported(SOT_FORMAT_BITMAP) )
+ {
+ // graphic dragged onto drawing object
+ DrawMarkDropObj( pHitObj );
+ nRet = nMyAction;
+ }
+ }
+ if (!nRet)
+ DrawMarkDropObj( NULL );
+
+ if (!nRet)
+ {
+ switch ( nMyAction )
+ {
+ case DND_ACTION_COPY:
+ case DND_ACTION_MOVE:
+ case DND_ACTION_COPYMOVE:
+ {
+ BOOL bMove = ( nMyAction == DND_ACTION_MOVE );
+ if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
+ IsDropFormatSupported( SOT_FORMAT_STRING ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) ||
+ IsDropFormatSupported( SOT_FORMAT_RTF ) ||
+ IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) ||
+ IsDropFormatSupported( SOT_FORMAT_BITMAP ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ||
+ ( !bMove && (
+ IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
+ IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) )
+ {
+ nRet = nMyAction;
+ }
+ }
+ break;
+ case DND_ACTION_LINK:
+ if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
+ IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
+ IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
+ {
+ nRet = nMyAction;
+ }
+ break;
+ }
+
+ if ( nRet )
+ {
+ // Simple check for protection: It's not known here if the drop will result
+ // in cells or drawing objects (some formats can be both) and how many cells
+ // the result will be. But if IsFormatEditable for the drop cell position
+ // is FALSE (ignores matrix formulas), nothing can be pasted, so the drop
+ // can already be rejected here.
+
+ Point aPos = rEvt.maPosPixel;
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY );
+ if ( !aTester.IsFormatEditable() )
+ nRet = DND_ACTION_NONE; // forbidden
+ }
+ }
+ }
+
+ // scroll only for accepted formats
+ if (nRet)
+ DropScroll( rEvt.maPosPixel );
+ }
+
+ return nRet;
+}
+
+ULONG lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false )
+{
+ TransferableDataHelper aDataHelper( xTransfer );
+
+ if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
+ {
+ // use bookmark formats if no sba is present
+
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
+ return SOT_FORMATSTR_ID_SOLK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
+ return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
+ return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
+ return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
+ }
+
+ ULONG nFormatId = 0;
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
+ nFormatId = SOT_FORMATSTR_ID_DRAWING;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
+ nFormatId = SOT_FORMATSTR_ID_SVXB;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) )
+ {
+ // If it's a Writer object, insert RTF instead of OLE
+
+ BOOL bDoRtf = FALSE;
+ SotStorageStreamRef xStm;
+ TransferableObjectDescriptor aObjDesc;
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
+ aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
+ {
+ SotStorageRef xStore( new SotStorage( *xStm ) );
+ bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
+ aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
+ && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+ if ( bDoRtf )
+ nFormatId = FORMAT_RTF;
+ else
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
+ }
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
+ nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) )
+ nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) )
+ nFormatId = SOT_FORMATSTR_ID_BIFF_8;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) )
+ nFormatId = SOT_FORMATSTR_ID_BIFF_5;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ nFormatId = SOT_FORMAT_RTF;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) )
+ nFormatId = SOT_FORMATSTR_ID_HTML;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) )
+ nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) )
+ nFormatId = SOT_FORMATSTR_ID_SYLK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK;
+ else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
+ nFormatId = SOT_FORMAT_STRING;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
+ nFormatId = SOT_FORMAT_FILE_LIST;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
+ nFormatId = SOT_FORMAT_FILE;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ nFormatId = SOT_FORMAT_STRING;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
+ nFormatId = SOT_FORMAT_GDIMETAFILE;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
+ nFormatId = SOT_FORMAT_BITMAP;
+
+ return nFormatId;
+}
+
+ULONG lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer )
+{
+ TransferableDataHelper aDataHelper( xTransfer );
+
+ ULONG nFormatId = 0;
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
+ nFormatId = SOT_FORMAT_FILE_LIST;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )
+ nFormatId = SOT_FORMAT_FILE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
+ nFormatId = SOT_FORMATSTR_ID_SOLK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
+ nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
+ nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
+ nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
+
+ return nFormatId;
+}
+
+
+sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt )
+{
+ // hide drop marker
+ // if (bDragRect)
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = FALSE;
+ UpdateDragRectOverlay();
+
+ ScModule* pScMod = SC_MOD();
+ const ScDragData& rData = pScMod->GetDragData();
+
+ return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY,
+ PixelToLogic(rEvt.maPosPixel), rEvt.mnAction );
+}
+
+sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
+ const Point& rLogicPos, sal_Int8 nDndAction )
+{
+ if ( !pTransObj )
+ return 0;
+
+ ScDocument* pSourceDoc = pTransObj->GetSourceDocument();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ ScViewFunc* pView = pViewData->GetView();
+ SCTAB nThisTab = pViewData->GetTabNo();
+ USHORT nFlags = pTransObj->GetDragSourceFlags();
+
+ BOOL bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
+ BOOL bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi );
+
+ // workaround for wrong nDndAction on Windows when pressing solely
+ // the Alt key during drag and drop;
+ // can be removed after #i79215# has been fixed
+ if ( meDragInsertMode != INS_NONE )
+ {
+ bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi );
+ }
+
+ BOOL bIsLink = ( nDndAction == DND_ACTION_LINK );
+
+ ScRange aSource = pTransObj->GetRange();
+
+ // only use visible tab from source range - when dragging within one table,
+ // all selected tables at the time of dropping are used (handled in MoveBlockTo)
+ SCTAB nSourceTab = pTransObj->GetVisibleTab();
+ aSource.aStart.SetTab( nSourceTab );
+ aSource.aEnd.SetTab( nSourceTab );
+
+ SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
+ SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) :
+ pTransObj->GetNonFilteredRows()); // copy/link: no filtered rows
+ ScRange aDest( nDestPosX, nDestPosY, nThisTab,
+ nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab );
+
+
+ /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
+ * dragging and adapted drawing of the selection frame. We check here
+ * (again) because this may actually also be called from PasteSelection(),
+ * we would have to duplicate determination of flags and destination range
+ * and would lose the context of the "filtered destination is OK" cases
+ * below, which is already awkward enough as is. */
+
+ // Don't move filtered source.
+ bool bFiltered = (bIsMove && pTransObj->HasFilteredRows());
+ if (!bFiltered)
+ {
+ if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) ||
+ (!bIsLink && meDragInsertMode == INS_NONE)))
+ {
+ // Nothing. Either entire sheet to be dropped, or the one case
+ // where PasteFromClip() is to be called that handles a filtered
+ // destination itself. Drag-copy from another document without
+ // inserting cells.
+ }
+ else
+ // Don't copy or move to filtered destination.
+ bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc);
+ }
+
+ BOOL bDone = FALSE;
+
+ if (!bFiltered && pSourceDoc == pThisDoc)
+ {
+ if ( nFlags & SC_DROP_TABLE ) // whole sheet?
+ {
+ if ( pThisDoc->IsDocEditable() )
+ {
+ SCTAB nSrcTab = aSource.aStart.Tab();
+ pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, TRUE ); // with Undo
+ pView->SetTabNo( nThisTab, TRUE );
+ bDone = TRUE;
+ }
+ }
+ else // move/copy block
+ {
+ String aChartName;
+ if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName ))
+ {
+ String aRangeName;
+ aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc );
+ SfxStringItem aNameItem( SID_CHART_NAME, aChartName );
+ SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName );
+ USHORT nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE;
+ pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ &aRangeItem, &aNameItem, (void*) NULL );
+ bDone = TRUE;
+ }
+ else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) )
+ {
+ // drop on DataPilot table: try to sort, fail if that isn't possible
+
+ ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab );
+ if ( aDestPos != aSource.aStart )
+ bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos );
+ else
+ bDone = TRUE; // same position: nothing
+ }
+ else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() ||
+ nSourceTab != nThisTab )
+ {
+ String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ bDone = TRUE;
+ if ( meDragInsertMode != INS_NONE )
+ {
+ // call with bApi = TRUE to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, TRUE /*bRecord*/, TRUE /*bApi*/, TRUE /*bPartOfPaste*/ );
+ if ( bDone )
+ {
+ if ( nThisTab == nSourceTab )
+ {
+ if ( meDragInsertMode == INS_CELLSDOWN &&
+ nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
+ {
+ bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
+ }
+ else if ( meDragInsertMode == INS_CELLSRIGHT &&
+ nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
+ {
+ bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
+ }
+ }
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+
+ if ( bDone )
+ {
+ if ( bIsLink )
+ {
+ // call with bApi = TRUE to avoid error messages in drop handler
+ bDone = pView->LinkBlock( aSource, aDest.aStart, TRUE /*bApi*/ );
+ }
+ else
+ {
+ // call with bApi = TRUE to avoid error messages in drop handler
+ bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, TRUE /*bRecord*/, TRUE /*bPaint*/, TRUE /*bApi*/ );
+ }
+ }
+
+ if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab )
+ {
+ DelCellCmd eCmd = DEL_NONE;
+ if ( meDragInsertMode == INS_CELLSDOWN )
+ {
+ eCmd = DEL_CELLSUP;
+ }
+ else if ( meDragInsertMode == INS_CELLSRIGHT )
+ {
+ eCmd = DEL_CELLSLEFT;
+ }
+
+ if ( ( eCmd == DEL_CELLSUP && nDestPosX == aSource.aStart.Col() ) ||
+ ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) )
+ {
+ // call with bApi = TRUE to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, TRUE /*bRecord*/, TRUE /*bApi*/ );
+ if ( bDone )
+ {
+ if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
+ {
+ bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
+ }
+ else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
+ {
+ bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
+ }
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+ }
+
+ if ( bDone )
+ {
+ pView->MarkRange( aDest, FALSE, FALSE );
+ pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+ }
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ if (!bDone)
+ Sound::Beep(); // instead of error message in drop handler
+ }
+ else
+ bDone = TRUE; // nothing to do
+ }
+
+ if (bDone)
+ pTransObj->SetDragWasInternal(); // don't delete source in DragFinished
+ }
+ else if ( !bFiltered && pSourceDoc ) // between documents
+ {
+ if ( nFlags & SC_DROP_TABLE ) // copy/link sheets between documents
+ {
+ if ( pThisDoc->IsDocEditable() )
+ {
+ ScDocShell* pSrcShell = pTransObj->GetSourceDocShell();
+
+ SCTAB nTabs[MAXTABCOUNT];
+
+ ScMarkData aMark = pTransObj->GetSourceMarkData();
+ SCTAB nTabCount = pSourceDoc->GetTableCount();
+ SCTAB nTabSelCount = 0;
+
+ for(SCTAB i=0; i<nTabCount; i++)
+ {
+ if(aMark.GetTableSelect(i))
+ {
+ nTabs[nTabSelCount++]=i;
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j)))
+ {
+ nTabs[nTabSelCount++]=j;
+ i=j;
+ }
+ else break;
+ }
+ }
+ }
+
+ pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab );
+ bDone = TRUE;
+ }
+ }
+ else if ( bIsLink )
+ {
+ // as in PasteDDE
+ // (external references might be used instead?)
+
+ SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell();
+ DBG_ASSERT(pSourceSh, "drag document has no shell");
+ if (pSourceSh)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ bDone = TRUE;
+ if ( meDragInsertMode != INS_NONE )
+ {
+ // call with bApi = TRUE to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, TRUE /*bRecord*/, TRUE /*bApi*/, TRUE /*bPartOfPaste*/ );
+ if ( bDone )
+ {
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+
+ if ( bDone )
+ {
+ String aApp = Application::GetAppName();
+ String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME );
+ String aItem;
+ aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc );
+
+ // TODO: we could define ocQuote for "
+ const String aQuote( '"' );
+ const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
+ String aFormula( '=' );
+ aFormula += ScCompiler::GetNativeSymbol( ocDde);
+ aFormula += ScCompiler::GetNativeSymbol( ocOpen);
+ aFormula += aQuote;
+ aFormula += aApp;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aTopic;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aItem;
+ aFormula += aQuote;
+ aFormula += ScCompiler::GetNativeSymbol( ocClose);
+
+ pView->DoneBlockMode();
+ pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab );
+ pView->MarkCursor( nDestPosX + nSizeX - 1,
+ nDestPosY + nSizeY - 1, nThisTab );
+
+ pView->EnterMatrix( aFormula );
+
+ pView->MarkRange( aDest, FALSE, FALSE );
+ pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+ }
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ }
+ else
+ {
+ //! HasSelectedBlockMatrixFragment without selected sheet?
+ //! or don't start dragging on a part of a matrix
+
+ String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ bDone = TRUE;
+ if ( meDragInsertMode != INS_NONE )
+ {
+ // call with bApi = TRUE to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, TRUE /*bRecord*/, TRUE /*bApi*/, TRUE /*bPartOfPaste*/ );
+ if ( bDone )
+ {
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+
+ if ( bDone )
+ {
+ pView->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
+ pView->SetCursor( nDestPosX, nDestPosY );
+ bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() ); // clip-doc
+ if ( bDone )
+ {
+ pView->MarkRange( aDest, FALSE, FALSE );
+ pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+ }
+ }
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ // no longer call ResetMark here - the inserted block has been selected
+ // and may have been copied to primary selection
+ }
+ }
+
+ sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE;
+ return nRet;
+}
+
+sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ DrawMarkDropObj( NULL ); // drawing layer
+
+ ScModule* pScMod = SC_MOD();
+ const ScDragData& rData = pScMod->GetDragData();
+ if (rData.pCellTransfer)
+ return ExecutePrivateDrop( rEvt );
+
+ Point aPos = rEvt.maPosPixel;
+
+ if ( rData.aLinkDoc.Len() )
+ {
+ // try to insert a link
+
+ BOOL bOk = TRUE;
+ String aThisName;
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ if (pDocSh && pDocSh->HasName())
+ aThisName = pDocSh->GetMedium()->GetName();
+
+ if ( rData.aLinkDoc == aThisName ) // error - no link within a document
+ bOk = FALSE;
+ else
+ {
+ ScViewFunc* pView = pViewData->GetView();
+ if ( rData.aLinkTable.Len() )
+ pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
+ rData.aLinkTable );
+ else if ( rData.aLinkArea.Len() )
+ {
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, FALSE, FALSE );
+
+ pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
+ rData.aLinkArea, 0 );
+ }
+ else
+ {
+ DBG_ERROR("drop with link: no sheet nor area");
+ bOk = FALSE;
+ }
+ }
+
+ return bOk ? rEvt.mnAction : DND_ACTION_NONE; // don't try anything else
+ }
+
+ Point aLogicPos = PixelToLogic(aPos);
+
+ if (rData.pDrawTransfer)
+ {
+ USHORT nFlags = rData.pDrawTransfer->GetDragSourceFlags();
+
+ BOOL bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
+ BOOL bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi );
+
+ bPasteIsMove = bIsMove;
+
+ pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() );
+
+ if (bPasteIsMove)
+ rData.pDrawTransfer->SetDragWasInternal();
+ bPasteIsMove = FALSE;
+
+ return rEvt.mnAction;
+ }
+
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ if (rData.aJumpTarget.Len())
+ {
+ // internal bookmark (from Navigator)
+ // bookmark clipboard formats are in PasteScDataObject
+
+ if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
+ {
+ pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget,
+ nPosX, nPosY );
+ return rEvt.mnAction;
+ }
+ }
+
+ BOOL bIsLink = ( rEvt.mnAction == DND_ACTION_LINK );
+
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) );
+ if ( pHitObj && bIsLink )
+ {
+ // dropped on drawing object
+ // PasteOnDrawObject checks for valid formats
+ if ( pViewData->GetView()->PasteOnDrawObject( rEvt.maDropEvent.Transferable, pHitObj, TRUE ) )
+ return rEvt.mnAction;
+ }
+
+ BOOL bDone = FALSE;
+
+ ULONG nFormatId = bIsLink ?
+ lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) :
+ lcl_GetDropFormatId( rEvt.maDropEvent.Transferable );
+ if ( nFormatId )
+ {
+ pScMod->SetInExecuteDrop( TRUE ); // #i28468# prevent error messages from PasteDataFormat
+ bPasteIsDrop = TRUE;
+ bDone = pViewData->GetView()->PasteDataFormat(
+ nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink );
+ bPasteIsDrop = FALSE;
+ pScMod->SetInExecuteDrop( FALSE );
+ }
+
+ sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE;
+ return nRet;
+}
+
+//--------------------------------------------------------
+
+void ScGridWindow::PasteSelection( const Point& rPosPixel )
+{
+ Point aLogicPos = PixelToLogic( rPosPixel );
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY );
+
+ ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer();
+ if ( pOwnSelection )
+ {
+ // within Calc
+
+ ScTransferObj* pCellTransfer = pOwnSelection->GetCellData();
+ if ( pCellTransfer )
+ {
+ // keep a reference to the data in case the selection is changed during paste
+ uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer );
+ DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY );
+ }
+ else
+ {
+ ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData();
+ if ( pDrawTransfer )
+ {
+ // keep a reference to the data in case the selection is changed during paste
+ uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer );
+
+ // #96821# bSameDocClipboard argument for PasteDraw is needed
+ // because only DragData is checked directly inside PasteDraw
+ pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), FALSE,
+ pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
+ }
+ }
+ }
+ else
+ {
+ // get selection from system
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
+ uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable();
+ if ( xTransferable.is() )
+ {
+ ULONG nFormatId = lcl_GetDropFormatId( xTransferable, true );
+ if ( nFormatId )
+ {
+ bPasteIsDrop = TRUE;
+ pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos );
+ bPasteIsDrop = FALSE;
+ }
+ }
+ }
+}
+
+//--------------------------------------------------------
+
+void ScGridWindow::UpdateEditViewPos()
+{
+ if (pViewData->HasEditView(eWhich))
+ {
+ EditView* pView;
+ SCCOL nCol;
+ SCROW nRow;
+ pViewData->GetEditView( eWhich, pView, nCol, nRow );
+ SCCOL nEndCol = pViewData->GetEditEndCol();
+ SCROW nEndRow = pViewData->GetEditEndRow();
+
+ // hide EditView?
+
+ BOOL bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) );
+ if ( SC_MOD()->IsFormulaMode() )
+ if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() )
+ bHide = TRUE;
+
+ if (bHide)
+ {
+ Rectangle aRect = pView->GetOutputArea();
+ long nHeight = aRect.Bottom() - aRect.Top();
+ aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()).
+ Height() * 2;
+ aRect.Bottom() = aRect.Top() + nHeight;
+ pView->SetOutputArea( aRect );
+ pView->HideCursor();
+ }
+ else
+ {
+ // bForceToTop = TRUE for editing
+ Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, TRUE );
+ Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() );
+
+ Rectangle aRect = pView->GetOutputArea();
+ aRect.SetPos( aScrPos );
+ pView->SetOutputArea( aRect );
+ pView->ShowCursor();
+ }
+ }
+}
+
+void ScGridWindow::ScrollPixel( long nDifX, long nDifY )
+{
+ ClickExtern();
+ HideNoteMarker();
+
+ bIsInScroll = TRUE;
+ //BOOL bXor=DrawBeforeScroll();
+
+ SetMapMode(MAP_PIXEL);
+ Scroll( nDifX, nDifY, SCROLL_CHILDREN );
+ SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
+
+ UpdateEditViewPos();
+
+ DrawAfterScroll(); //bXor);
+ bIsInScroll = FALSE;
+}
+
+// Formeln neu zeichnen -------------------------------------------------
+
+void ScGridWindow::UpdateFormulas()
+{
+ if (pViewData->GetView()->IsMinimized())
+ return;
+
+ if ( nPaintCount )
+ {
+ // nicht anfangen, verschachtelt zu painten
+ // (dann wuerde zumindest der MapMode nicht mehr stimmen)
+
+ bNeedsRepaint = TRUE; // -> am Ende vom Paint nochmal Invalidate auf alles
+ aRepaintPixel = Rectangle(); // alles
+ return;
+ }
+
+ SCCOL nX1 = pViewData->GetPosX( eHWhich );
+ SCROW nY1 = pViewData->GetPosY( eVWhich );
+ SCCOL nX2 = nX1 + pViewData->VisibleCellsX( eHWhich );
+ SCROW nY2 = nY1 + pViewData->VisibleCellsY( eVWhich );
+
+ if (nX2 > MAXCOL) nX2 = MAXCOL;
+ if (nY2 > MAXROW) nY2 = MAXROW;
+
+ // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
+
+ // don't draw directly - instead use OutputData to find changed area and invalidate
+
+ SCROW nPosY = nY1;
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nMirrorWidth = GetSizePixel().Width();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
+ if ( bLayoutRTL )
+ {
+ long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
+ nMirrorWidth = aScrPos.X() - nEndPixel;
+ aScrPos.X() = nEndPixel + 1;
+ }
+
+ long nScrX = aScrPos.X();
+ long nScrY = aScrPos.Y();
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, FALSE, FALSE );
+
+ Fraction aZoomX = pViewData->GetZoomX();
+ Fraction aZoomY = pViewData->GetZoomY();
+ ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
+ &aZoomX, &aZoomY );
+ aOutputData.SetMirrorWidth( nMirrorWidth );
+
+ aOutputData.FindChanged();
+
+ PolyPolygon aChangedPoly( aOutputData.GetChangedArea() ); // logic (PixelToLogic)
+ if ( aChangedPoly.Count() )
+ {
+ Invalidate( aChangedPoly );
+ }
+
+ CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
+}
+
+void ScGridWindow::UpdateAutoFillMark(BOOL bMarked, const ScRange& rMarkRange)
+{
+ if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) )
+ {
+ HideCursor();
+ bAutoMarkVisible = bMarked;
+ if ( bMarked )
+ aAutoMarkPos = rMarkRange.aEnd;
+ ShowCursor();
+
+ UpdateAutoFillOverlay();
+ }
+}
+
+void ScGridWindow::UpdateListValPos( BOOL bVisible, const ScAddress& rPos )
+{
+ BOOL bOldButton = bListValButton;
+ ScAddress aOldPos = aListValPos;
+
+ bListValButton = bVisible;
+ aListValPos = rPos;
+
+ if ( bListValButton )
+ {
+ if ( !bOldButton || aListValPos != aOldPos )
+ {
+ // paint area of new button
+ Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) );
+ }
+ }
+ if ( bOldButton )
+ {
+ if ( !bListValButton || aListValPos != aOldPos )
+ {
+ // paint area of old button
+ Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) );
+ }
+ }
+}
+
+void ScGridWindow::HideCursor()
+{
+ ++nCursorHideCount;
+ if (nCursorHideCount==1)
+ {
+ DrawCursor();
+ DrawAutoFillMark();
+ }
+}
+
+void ScGridWindow::ShowCursor()
+{
+ if (nCursorHideCount==0)
+ {
+ DBG_ERROR("zuviel ShowCursor");
+ return;
+ }
+
+ if (nCursorHideCount==1)
+ {
+ // #i57745# Draw the cursor before setting the variable, in case the
+ // GetSizePixel call from drawing causes a repaint (resize handler is called)
+ DrawAutoFillMark();
+ DrawCursor();
+ }
+
+ --nCursorHideCount;
+}
+
+void __EXPORT ScGridWindow::GetFocus()
+{
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ pViewShell->GotFocus();
+ pViewShell->SetFormShellAtTop( FALSE ); // focus in GridWindow -> FormShell no longer on top
+
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible()));
+
+
+ if ( !SC_MOD()->IsFormulaMode() )
+ {
+ pViewShell->UpdateInputHandler();
+// StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
+ // MO: nur wenn nicht im RefInput-Modus
+ // -> GetFocus/MouseButtonDown-Reihenfolge
+ // auf dem Mac
+ }
+
+ Window::GetFocus();
+}
+
+void __EXPORT ScGridWindow::LoseFocus()
+{
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ pViewShell->LostFocus();
+
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible()));
+
+ Window::LoseFocus();
+}
+
+Point ScGridWindow::GetMousePosPixel() const { return aCurMousePos; }
+
+//------------------------------------------------------------------------
+
+BOOL ScGridWindow::HitRangeFinder( const Point& rMouse, BOOL& rCorner,
+ USHORT* pIndex, SCsCOL* pAddX, SCsROW* pAddY )
+{
+ BOOL bFound = FALSE;
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
+ if (pHdl)
+ {
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if ( pRangeFinder && !pRangeFinder->IsHidden() &&
+ pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY );
+ // zusammengefasste (einzeln/Bereich) ???
+ ScAddress aAddr( nPosX, nPosY, nTab );
+
+// Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
+
+ Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, TRUE );
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix );
+ aNext.X() += nSizeXPix * nLayoutSign;
+ aNext.Y() += nSizeYPix;
+
+ BOOL bCornerHor;
+ if ( bLayoutRTL )
+ bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 );
+ else
+ bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() );
+
+ BOOL bCellCorner = ( bCornerHor &&
+ rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() );
+ // corner is hit only if the mouse is within the cell
+
+ USHORT nCount = (USHORT)pRangeFinder->Count();
+ for (USHORT i=nCount; i;)
+ {
+ // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
+ --i;
+ ScRangeFindData* pData = pRangeFinder->GetObject(i);
+ if ( pData && pData->aRef.In(aAddr) )
+ {
+ if (pIndex) *pIndex = i;
+ if (pAddX) *pAddX = nPosX - pData->aRef.aStart.Col();
+ if (pAddY) *pAddY = nPosY - pData->aRef.aStart.Row();
+ bFound = TRUE;
+ rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd );
+ break;
+ }
+ }
+ }
+ }
+ return bFound;
+}
+
+#define SCE_TOP 1
+#define SCE_BOTTOM 2
+#define SCE_LEFT 4
+#define SCE_RIGHT 8
+#define SCE_ALL 15
+
+void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, USHORT nEdges )
+{
+ // der Range ist immer richtigherum
+
+ SCCOL nCol1 = rRange.aStart.Col();
+ SCROW nRow1 = rRange.aStart.Row();
+ SCTAB nTab1 = rRange.aStart.Tab();
+ SCCOL nCol2 = rRange.aEnd.Col();
+ SCROW nRow2 = rRange.aEnd.Row();
+ SCTAB nTab2 = rRange.aEnd.Tab();
+ BOOL bHiddenEdge = FALSE;
+ SCROW nTmp;
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) )
+ {
+ --nCol1;
+ bHiddenEdge = TRUE;
+ }
+ while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) )
+ {
+ ++nCol2;
+ bHiddenEdge = TRUE;
+ }
+ nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1);
+ if (!ValidRow(nTmp))
+ nTmp = 0;
+ if (nTmp < nRow1)
+ {
+ nRow1 = nTmp;
+ bHiddenEdge = TRUE;
+ }
+ nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1);
+ if (!ValidRow(nTmp))
+ nTmp = MAXROW;
+ if (nTmp > nRow2)
+ {
+ nRow2 = nTmp;
+ bHiddenEdge = TRUE;
+ }
+
+ if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge )
+ {
+ // nur an den Raendern entlang
+ // (die Ecken werden evtl. zweimal getroffen)
+
+ if ( nEdges & SCE_TOP )
+ pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS );
+ if ( nEdges & SCE_LEFT )
+ pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS );
+ if ( nEdges & SCE_RIGHT )
+ pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
+ if ( nEdges & SCE_BOTTOM )
+ pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
+ }
+ else // everything in one call
+ pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
+}
+
+void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn )
+{
+ // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
+
+ ScRange aOld = rOldUn;
+ ScRange aNew = rNewUn;
+ aOld.Justify();
+ aNew.Justify();
+
+ if ( aOld.aStart == aOld.aEnd ) //! Tab ignorieren?
+ pDocSh->GetDocument()->ExtendMerge(aOld);
+ if ( aNew.aStart == aNew.aEnd ) //! Tab ignorieren?
+ pDocSh->GetDocument()->ExtendMerge(aNew);
+
+ SCCOL nOldCol1 = aOld.aStart.Col();
+ SCROW nOldRow1 = aOld.aStart.Row();
+ SCCOL nOldCol2 = aOld.aEnd.Col();
+ SCROW nOldRow2 = aOld.aEnd.Row();
+ SCCOL nNewCol1 = aNew.aStart.Col();
+ SCROW nNewRow1 = aNew.aStart.Row();
+ SCCOL nNewCol2 = aNew.aEnd.Col();
+ SCROW nNewRow2 = aNew.aEnd.Row();
+ SCTAB nTab1 = aOld.aStart.Tab(); // Tab aendert sich nicht
+ SCTAB nTab2 = aOld.aEnd.Tab();
+
+ if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 ||
+ nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 ||
+ ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 &&
+ nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) )
+ {
+ // komplett weggeschoben oder alle Seiten veraendert
+ // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
+
+ lcl_PaintOneRange( pDocSh, aOld, SCE_ALL );
+ }
+ else // alle vier Kanten einzeln testen
+ {
+ // oberer Teil
+ if ( nNewRow1 < nOldRow1 ) // nur obere Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL );
+ else if ( nNewRow1 > nOldRow1 ) // den Teil, der oben wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ),
+ SCE_ALL &~ SCE_BOTTOM );
+
+ // unterer Teil
+ if ( nNewRow2 > nOldRow2 ) // nur untere Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
+ else if ( nNewRow2 < nOldRow2 ) // den Teil, der unten wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ),
+ SCE_ALL &~ SCE_TOP );
+
+ // linker Teil
+ if ( nNewCol1 < nOldCol1 ) // nur linke Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL );
+ else if ( nNewCol1 > nOldCol1 ) // den Teil, der links wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ),
+ SCE_ALL &~ SCE_RIGHT );
+
+ // rechter Teil
+ if ( nNewCol2 > nOldCol2 ) // nur rechte Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
+ else if ( nNewCol2 < nOldCol2 ) // den Teil, der rechts wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ),
+ SCE_ALL &~ SCE_LEFT );
+ }
+}
+
+void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, BOOL bUp )
+{
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
+ if (!pHdl)
+ return;
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if (!pRangeFinder || nRFIndex >= pRangeFinder->Count())
+ return;
+ ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex );
+ if (!pData)
+ return;
+
+ // Mauszeiger
+
+ if (bRFSize)
+ SetPointer( Pointer( POINTER_CROSS ) );
+ else
+ SetPointer( Pointer( POINTER_HAND ) );
+
+ // Scrolling
+
+ BOOL bTimer = FALSE;
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ if ( aPos.X() < 0 ) nDx = -1;
+ if ( aPos.Y() < 0 ) nDy = -1;
+ Size aSize = GetOutputSizePixel();
+ if ( aPos.X() >= aSize.Width() )
+ nDx = 1;
+ if ( aPos.Y() >= aSize.Height() )
+ nDy = 1;
+ if ( nDx != 0 || nDy != 0 )
+ {
+ if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+ bTimer = TRUE;
+ }
+
+ // Umschalten bei Fixierung (damit Scrolling funktioniert)
+
+ if ( eWhich == pViewData->GetActivePart() ) //??
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ if ( nDx > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ if ( nDy > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+ }
+
+ // Verschieben
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ ScRange aOld = pData->aRef;
+ ScRange aNew = aOld;
+ if ( bRFSize )
+ {
+ aNew.aEnd.SetCol((SCCOL)nPosX);
+ aNew.aEnd.SetRow((SCROW)nPosY);
+ }
+ else
+ {
+ long nStartX = nPosX - nRFAddX;
+ if ( nStartX < 0 ) nStartX = 0;
+ long nStartY = nPosY - nRFAddY;
+ if ( nStartY < 0 ) nStartY = 0;
+ long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col();
+ if ( nEndX > MAXCOL )
+ {
+ nStartX -= ( nEndX - MAXROW );
+ nEndX = MAXCOL;
+ }
+ long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row();
+ if ( nEndY > MAXROW )
+ {
+ nStartY -= ( nEndY - MAXROW );
+ nEndY = MAXROW;
+ }
+
+ aNew.aStart.SetCol((SCCOL)nStartX);
+ aNew.aStart.SetRow((SCROW)nStartY);
+ aNew.aEnd.SetCol((SCCOL)nEndX);
+ aNew.aEnd.SetRow((SCROW)nEndY);
+ }
+
+ if ( bUp )
+ aNew.Justify(); // beim ButtonUp wieder richtigherum
+
+ if ( aNew != aOld )
+ {
+ pHdl->UpdateRange( nRFIndex, aNew );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ // nur das neuzeichnen, was sich veraendert hat...
+ lcl_PaintRefChanged( pDocSh, aOld, aNew );
+
+ // neuen Rahmen nur drueberzeichnen (synchron)
+ pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) );
+
+ Update(); // was man bewegt, will man auch sofort sehen
+ }
+
+ // Timer fuer Scrolling
+
+ if (bTimer)
+ pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
+ else
+ pViewData->GetView()->ResetTimer();
+}
+
+//------------------------------------------------------------------------
+
+BOOL ScGridWindow::GetEditUrl( const Point& rPos,
+ String* pName, String* pUrl, String* pTarget )
+{
+ return GetEditUrlOrError( FALSE, rPos, pName, pUrl, pTarget );
+}
+
+BOOL ScGridWindow::GetEditUrlOrError( BOOL bSpellErr, const Point& rPos,
+ String* pName, String* pUrl, String* pTarget )
+{
+ //! nPosX/Y mit uebergeben?
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY );
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScBaseCell* pCell = NULL;
+
+ BOOL bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell );
+ if( !bFound )
+ return FALSE;
+
+ ScHideTextCursor aHideCursor( pViewData, eWhich ); // before GetEditArea (MapMode is changed)
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
+ // bForceToTop = FALSE, use the cell's real position
+ Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, FALSE );
+ if (rPos.Y() < aEditRect.Top())
+ return FALSE;
+
+ // vertikal kann (noch) nicht angeklickt werden:
+
+ if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
+ return FALSE;
+
+ BOOL bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
+ ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK);
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern->
+ GetItem(ATTR_HOR_JUSTIFY)).GetValue();
+
+ // EditEngine
+
+ ScFieldEditEngine aEngine( pDoc->GetEditPool() );
+ ScSizeDeviceProvider aProv(pDocSh);
+ aEngine.SetRefDevice( aProv.GetDevice() );
+ aEngine.SetRefMapMode( MAP_100TH_MM );
+ SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
+ pPattern->FillEditItemSet( &aDefault );
+ SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
+ switch (eHorJust)
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
+ case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type
+ eSvxAdjust = SVX_ADJUST_LEFT;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ eSvxAdjust = SVX_ADJUST_RIGHT;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_HOR_JUSTIFY_BLOCK:
+ eSvxAdjust = SVX_ADJUST_BLOCK;
+ break;
+ }
+ aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+ aEngine.SetDefaults( aDefault );
+ if (bSpellErr)
+ aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING );
+
+ MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung
+ Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
+ long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1;
+ Size aPaperSize = Size( 1000000, 1000000 );
+ if(pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ long nSizeX = 0;
+ long nSizeY = 0;
+ pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
+ aPaperSize = Size(nSizeX, nSizeY );
+ aPaperSize = PixelToLogic(aPaperSize);
+ }
+
+ if (bBreak)
+ aPaperSize.Width() = nThisColLogic;
+ aEngine.SetPaperSize( aPaperSize );
+
+ ::std::auto_ptr< EditTextObject > pTextObj;
+ const EditTextObject* pData;
+ if(pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ ((ScEditCell*)pCell)->GetData(pData);
+ if (pData)
+ aEngine.SetText(*pData);
+ }
+ else // HyperLink Formula cell
+ {
+ pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject());
+ if (pTextObj.get())
+ aEngine.SetText(*pTextObj);
+ }
+
+ long nStartX = aLogicEdit.Left();
+
+ long nTextWidth = aEngine.CalcTextWidth();
+ long nTextHeight = aEngine.GetTextHeight();
+ if ( nTextWidth < nThisColLogic )
+ {
+ if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
+ nStartX += nThisColLogic - nTextWidth;
+ else if (eHorJust == SVX_HOR_JUSTIFY_CENTER)
+ nStartX += (nThisColLogic - nTextWidth) / 2;
+ }
+
+ aLogicEdit.Left() = nStartX;
+ if (!bBreak)
+ aLogicEdit.Right() = nStartX + nTextWidth;
+
+ // There is one glitch when dealing with a hyperlink cell and
+ // the cell content is NUMERIC. This defaults to right aligned and
+ // we need to adjust accordingly.
+ if(pCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(pCell)->IsValue() &&
+ eHorJust == SVX_HOR_JUSTIFY_STANDARD)
+ {
+ aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1;
+ aLogicEdit.Left() = aLogicEdit.Right() - nTextWidth;
+ }
+ aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight;
+
+
+ Point aLogicClick = PixelToLogic(rPos,aEditMode);
+ if ( aLogicEdit.IsInside(aLogicClick) )
+ {
+// aEngine.SetUpdateMode(FALSE);
+ EditView aTempView( &aEngine, this );
+ aTempView.SetOutputArea( aLogicEdit );
+
+ BOOL bRet = FALSE;
+ MapMode aOld = GetMapMode();
+ SetMapMode(aEditMode); // kein return mehr
+
+ if (bSpellErr) // Spelling-Fehler suchen
+ {
+ bRet = aTempView.IsWrongSpelledWordAtPos( rPos );
+ if ( bRet )
+ pViewData->GetView()->SetCursor( nPosX, nPosY ); // Cursor setzen
+ }
+ else // URL suchen
+ {
+ const SvxFieldItem* pFieldItem = aTempView.GetFieldUnderMousePointer();
+
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ if ( pName || pUrl || pTarget )
+ {
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+ if (pName)
+ *pName = pURLField->GetRepresentation();
+ if (pUrl)
+ *pUrl = pURLField->GetURL();
+ if (pTarget)
+ *pTarget = pURLField->GetTargetFrame();
+ }
+ bRet = TRUE;
+ }
+ }
+ }
+
+ SetMapMode(aOld);
+
+ // text cursor is restored in ScHideTextCursor dtor
+
+ return bRet;
+ }
+ return FALSE;
+}
+
+BOOL ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
+ {
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Size aButSize = pViewData->GetScenButSize();
+ long nBWidth = aButSize.Width();
+ if (!nBWidth)
+ return FALSE; // noch kein Button gezeichnet -> da ist auch keiner
+ long nBHeight = aButSize.Height();
+ long nHSpace = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() );
+
+ //! Ranges an der Table cachen!!!!
+
+ ScMarkData aMarks;
+ for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ pDoc->MarkScenario( i, nTab, aMarks, FALSE, SC_SCENARIO_SHOWFRAME );
+ ScRangeList aRanges;
+ aMarks.FillRangeListWithMarks( &aRanges, FALSE );
+
+
+ ULONG nRangeCount = aRanges.Count();
+ for (ULONG j=0; j<nRangeCount; j++)
+ {
+ ScRange aRange = *aRanges.GetObject(j);
+ // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
+ // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
+ pDoc->ExtendTotalMerge( aRange );
+
+ BOOL bTextBelow = ( aRange.aStart.Row() == 0 );
+
+ Point aButtonPos;
+ if ( bTextBelow )
+ {
+ aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1,
+ eWhich, TRUE );
+ }
+ else
+ {
+ aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(),
+ eWhich, TRUE );
+ aButtonPos.Y() -= nBHeight;
+ }
+ if ( bLayoutRTL )
+ aButtonPos.X() -= nHSpace - 1;
+ else
+ aButtonPos.X() -= nBWidth - nHSpace; // same for top or bottom
+
+ Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) );
+ if ( aButRect.IsInside( rPosPixel ) )
+ {
+ rScenRange = aRange;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// #114409#
+void ScGridWindow::DrawLayerCreated()
+{
+ SetMapMode( GetDrawMapMode() );
+
+ // initially create overlay objects
+ ImpCreateOverlayObjects();
+}
+
+// #114409#
+void ScGridWindow::CursorChanged()
+{
+ // here the created OverlayObjects may be transformed in later versions. For
+ // now, just re-create them
+
+ UpdateCursorOverlay();
+}
+
+// #114409#
+void ScGridWindow::ImpCreateOverlayObjects()
+{
+ UpdateCursorOverlay();
+ UpdateSelectionOverlay();
+ UpdateAutoFillOverlay();
+ UpdateDragRectOverlay();
+ UpdateHeaderOverlay();
+ UpdateShrinkOverlay();
+}
+
+// #114409#
+void ScGridWindow::ImpDestroyOverlayObjects()
+{
+ DeleteCursorOverlay();
+ DeleteSelectionOverlay();
+ DeleteAutoFillOverlay();
+ DeleteDragRectOverlay();
+ DeleteHeaderOverlay();
+ DeleteShrinkOverlay();
+}
+
+void ScGridWindow::UpdateAllOverlays()
+{
+ // delete and re-allocate all overlay objects
+
+ ImpDestroyOverlayObjects();
+ ImpCreateOverlayObjects();
+}
+
+void ScGridWindow::DeleteCursorOverlay()
+{
+ DELETEZ( mpOOCursors );
+}
+
+void ScGridWindow::UpdateCursorOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ // Existing OverlayObjects may be transformed in later versions.
+ // For now, just re-create them.
+
+ DeleteCursorOverlay();
+
+ std::vector<Rectangle> aPixelRects;
+
+ //
+ // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
+ //
+
+ SCTAB nTab = pViewData->GetTabNo();
+ SCCOL nX = pViewData->GetCurX();
+ SCROW nY = pViewData->GetCurY();
+
+ if (!maVisibleRange.isInside(nX, nY))
+ return;
+
+ // don't show the cursor in overlapped cells
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
+ const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
+ BOOL bOverlapped = rMergeFlag.IsOverlapped();
+
+ // left or above of the screen?
+
+ BOOL bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
+ if (!bVis)
+ {
+ SCCOL nEndX = nX;
+ SCROW nEndY = nY;
+ const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
+ if (rMerge.GetColMerge() > 1)
+ nEndX += rMerge.GetColMerge()-1;
+ if (rMerge.GetRowMerge() > 1)
+ nEndY += rMerge.GetRowMerge()-1;
+ bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
+ }
+
+ if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
+ {
+ Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE );
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ // completely right of/below the screen?
+ // (test with logical start position in aScrPos)
+ BOOL bMaybeVisible;
+ if ( bLayoutRTL )
+ bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
+ else
+ {
+ Size aOutSize = GetOutputSizePixel();
+ bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
+ }
+ if ( bMaybeVisible )
+ {
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+
+ if ( bLayoutRTL )
+ aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring
+
+ BOOL bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+ pViewData->GetVSplitMode() == SC_SPLIT_FIX );
+ if ( pViewData->GetActivePart()==eWhich || bFix )
+ {
+ aScrPos.X() -= 2;
+ aScrPos.Y() -= 2;
+ Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+
+ aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+ aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+ aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+ aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
+ }
+ else
+ {
+ Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
+ aPixelRects.push_back( aRect );
+ }
+ }
+ }
+
+ if ( aPixelRects.size() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+
+ for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
+ {
+ const Rectangle aRA(aPixelRects[a]);
+ basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+ }
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_SOLID,
+ aCursorColor,
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOCursors = new ::sdr::overlay::OverlayObjectList;
+ mpOOCursors->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteSelectionOverlay()
+{
+ DELETEZ( mpOOSelection );
+}
+
+void ScGridWindow::UpdateSelectionOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteSelectionOverlay();
+ std::vector<Rectangle> aPixelRects;
+ GetSelectionRects( aPixelRects );
+
+ if ( aPixelRects.size() && pViewData->IsActive() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+
+ for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
+ {
+ const Rectangle aRA(aPixelRects[a]);
+ basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+ }
+
+ // #i97672# get the system's hilight color and limit it to the maximum
+ // allowed luminance. This is needed to react on too bright hilight colors
+ // which would otherwise vive a bad visualisation
+ Color aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ const basegfx::BColor aSelection(aHighlight.getBColor());
+ const double fLuminance(aSelection.luminance());
+ const double fMaxLum(aSvtOptionsDrawinglayer.GetSelectionMaximumLuminancePercent() / 100.0);
+
+ if(fLuminance > fMaxLum)
+ {
+ const double fFactor(fMaxLum / fLuminance);
+ const basegfx::BColor aNewSelection(
+ aSelection.getRed() * fFactor,
+ aSelection.getGreen() * fFactor,
+ aSelection.getBlue() * fFactor);
+
+ aHighlight = Color(aNewSelection);
+ }
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_TRANSPARENT,
+ aHighlight,
+ aRanges,
+ true);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOSelection = new ::sdr::overlay::OverlayObjectList;
+ mpOOSelection->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteAutoFillOverlay()
+{
+ DELETEZ( mpOOAutoFill );
+ mpAutoFillRect.reset();
+}
+
+void ScGridWindow::UpdateAutoFillOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteAutoFillOverlay();
+
+ //
+ // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
+ //
+
+ if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() &&
+ !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
+ {
+ SCCOL nX = aAutoMarkPos.Col();
+ SCROW nY = aAutoMarkPos.Row();
+
+ if (!maVisibleRange.isInside(nX, nY))
+ // Autofill mark is not visible. Bail out.
+ return;
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE );
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+ if ( bLayoutRTL )
+ aFillPos.X() -= nSizeXPix + 3;
+ else
+ aFillPos.X() += nSizeXPix - 2;
+
+ aFillPos.Y() += nSizeYPix;
+ aFillPos.Y() -= 2;
+ mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6)));
+
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+ basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);
+
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_SOLID,
+ aHandleColor,
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOAutoFill = new ::sdr::overlay::OverlayObjectList;
+ mpOOAutoFill->append(*pOverlay);
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+ }
+}
+
+void ScGridWindow::DeleteDragRectOverlay()
+{
+ DELETEZ( mpOODragRect );
+}
+
+void ScGridWindow::UpdateDragRectOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteDragRectOverlay();
+
+ //
+ // get the rectangles in pixels (moved from DrawDragRect)
+ //
+
+ if ( bDragRect || bPagebreakDrawn )
+ {
+ std::vector<Rectangle> aPixelRects;
+
+ SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col();
+ SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row();
+ SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col();
+ SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row();
+
+ SCTAB nTab = pViewData->GetTabNo();
+
+ SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
+ SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
+ if (nX1 < nPosX) nX1 = nPosX;
+ if (nX2 < nPosX) nX2 = nPosX;
+ if (nY1 < nPosY) nY1 = nPosY;
+ if (nY2 < nPosY) nY2 = nPosY;
+
+ Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
+
+ long nSizeXPix=0;
+ long nSizeYPix=0;
+ ScDocument* pDoc = pViewData->GetDocument();
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+ SCCOLROW i;
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ if (ValidCol(nX2) && nX2>=nX1)
+ for (i=nX1; i<=nX2; i++)
+ nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
+ else
+ {
+ aScrPos.X() -= nLayoutSign;
+ nSizeXPix += 2;
+ }
+
+ if (ValidRow(nY2) && nY2>=nY1)
+ for (i=nY1; i<=nY2; i++)
+ nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
+ else
+ {
+ aScrPos.Y() -= 1;
+ nSizeYPix += 2;
+ }
+
+ aScrPos.X() -= 2 * nLayoutSign;
+ aScrPos.Y() -= 2;
+// Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+ Rectangle aRect( aScrPos.X(), aScrPos.Y(),
+ aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
+ if ( bLayoutRTL )
+ {
+ aRect.Left() = aRect.Right(); // end position is left
+ aRect.Right() = aScrPos.X();
+ }
+
+ if ( meDragInsertMode == INS_CELLSDOWN )
+ {
+ aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) );
+ }
+ else if ( meDragInsertMode == INS_CELLSRIGHT )
+ {
+ aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) );
+ aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) );
+ }
+ else
+ {
+ aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) );
+ aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) );
+ }
+
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+
+ for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
+ {
+ const Rectangle aRA(aPixelRects[a]);
+ basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+ }
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_INVERT,
+ Color(COL_BLACK),
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOODragRect = new ::sdr::overlay::OverlayObjectList;
+ mpOODragRect->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteHeaderOverlay()
+{
+ DELETEZ( mpOOHeader );
+}
+
+void ScGridWindow::UpdateHeaderOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteHeaderOverlay();
+
+ // Pixel rectangle is in aInvertRect
+ if ( !aInvertRect.IsEmpty() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+ basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);
+
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_INVERT,
+ Color(COL_BLACK),
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOHeader = new ::sdr::overlay::OverlayObjectList;
+ mpOOHeader->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteShrinkOverlay()
+{
+ DELETEZ( mpOOShrink );
+}
+
+void ScGridWindow::UpdateShrinkOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteShrinkOverlay();
+
+ //
+ // get the rectangle in pixels
+ //
+
+ Rectangle aPixRect;
+ ScRange aRange;
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() &&
+ pViewData->GetDelMark( aRange ) )
+ {
+ //! limit to visible area
+ if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
+ aRange.aStart.Row() <= aRange.aEnd.Row() )
+ {
+ Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
+ aRange.aStart.Row(), eWhich );
+ Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
+ aRange.aEnd.Row()+1, eWhich );
+ aEnd.X() -= 1;
+ aEnd.Y() -= 1;
+
+ aPixRect = Rectangle( aStart,aEnd );
+ }
+ }
+
+ if ( !aPixRect.IsEmpty() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+ basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);
+
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_INVERT,
+ Color(COL_BLACK),
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOShrink = new ::sdr::overlay::OverlayObjectList;
+ mpOOShrink->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+// #i70788# central method to get the OverlayManager safely
+::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager()
+{
+ SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView();
+
+ if(pPV)
+ {
+ SdrPageWindow* pPageWin = pPV->FindPageWindow( *this );
+
+ if ( pPageWin )
+ {
+ return (pPageWin->GetOverlayManager());
+ }
+ }
+
+ return 0L;
+}
+
+void ScGridWindow::flushOverlayManager()
+{
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ pOverlayManager->flush();
+ }
+}
+
+// ---------------------------------------------------------------------------
+// eof
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
new file mode 100644
index 000000000000..669f1fda010d
--- /dev/null
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -0,0 +1,1061 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+
+#include "gridwin.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+#include "pivot.hxx"
+//CHINA001 #include "pfiltdlg.hxx"
+#include "uiitems.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "pagedata.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpoutput.hxx" // ScDPPositionData
+#include "dpshttab.hxx"
+#include "dbdocfun.hxx"
+#include "dpcontrol.hxx"
+#include "dpcontrol.hrc"
+#include "strload.hxx"
+#include "userlist.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include "scabstdlg.hxx" //CHINA001
+
+#include <vector>
+#include <hash_map>
+
+using namespace com::sun::star;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::std::vector;
+using ::std::auto_ptr;
+using ::std::hash_map;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const
+{
+ using namespace ::com::sun::star::sheet;
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+ if (!pDPObj)
+ return DataPilotFieldOrientation_HIDDEN;
+
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+
+ // Check for page field first.
+ if (nCol > 0)
+ {
+ // look for the dimension header left of the drop-down arrow
+ long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
+ if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
+ {
+ BOOL bIsDataLayout = FALSE;
+ String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
+ if ( aFieldName.Len() && !bIsDataLayout )
+ return DataPilotFieldOrientation_PAGE;
+ }
+ }
+
+ nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ // Now, check for row/column field.
+ long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient);
+ if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
+ {
+ BOOL bIsDataLayout = FALSE;
+ String aFieldName = pDPObj->GetDimName(nField, bIsDataLayout);
+ if (aFieldName.Len() && !bIsDataLayout)
+ return static_cast<DataPilotFieldOrientation>(nOrient);
+ }
+
+ return DataPilotFieldOrientation_HIDDEN;
+}
+
+// private method for mouse button handling
+BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow )
+{
+ if (GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE)
+ {
+ LaunchPageFieldMenu( nCol, nRow );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ Point aDiffPix = rMEvt.GetPosPixel();
+
+ aDiffPix -= aScrPos;
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ if ( bLayoutRTL )
+ aDiffPix.X() = -aDiffPix.X();
+
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc));
+ mpFilterButton->setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
+ mpFilterButton->setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
+ Point aPopupPos;
+ Size aPopupSize;
+ mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ if ( DoPageFieldSelection( nCol, nRow ) )
+ return true;
+
+ bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setDrawBaseButton(false);
+ mpFilterButton->setDrawPopupButton(true);
+ mpFilterButton->setPopupPressed(true);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ DoAutoFilterMenue(nCol, nRow, false);
+ return true;
+ }
+
+ return false;
+}
+
+void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+
+ if (pDPObj)
+ {
+ USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ ScAddress aPos( nCol, nRow, nTab );
+ long nField = pDPObj->GetHeaderDim( aPos, nOrient );
+ if ( nField >= 0 )
+ {
+ bDPMouse = TRUE;
+ nDPField = nField;
+ pDragDPObj = pDPObj;
+
+ if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj))
+ {
+ // field name pop up menu has been launched. Don't activate
+ // field move.
+ bDPMouse = false;
+ return;
+ }
+
+ DPTestMouse( rMEvt, TRUE );
+ StartTracking();
+ }
+ else if ( pDPObj->IsFilterButton(aPos) )
+ {
+ ReleaseMouse(); // may have been captured in ButtonDown
+
+ ScQueryParam aQueryParam;
+ SCTAB nSrcTab = 0;
+ const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
+ DBG_ASSERT(pDesc, "no sheet source for filter button");
+ if (pDesc)
+ {
+ aQueryParam = pDesc->aQueryParam;
+ nSrcTab = pDesc->aSourceRange.aStart.Tab();
+ }
+
+ SfxItemSet aArgSet( pViewData->GetViewShell()->GetPool(),
+ SCITEM_QUERYDATA, SCITEM_QUERYDATA );
+ aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, pViewData, &aQueryParam ) );
+
+//CHINA001 ScPivotFilterDlg* pDlg = new ScPivotFilterDlg(
+//CHINA001 pViewData->GetViewShell()->GetDialogParent(),
+//CHINA001 aArgSet, nSrcTab );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScPivotFilterDlg* pDlg = pFact->CreateScPivotFilterDlg( pViewData->GetViewShell()->GetDialogParent(),
+ aArgSet, nSrcTab,
+ RID_SCDLG_PIVOTFILTER);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScSheetSourceDesc aNewDesc;
+ if (pDesc)
+ aNewDesc = *pDesc;
+
+ const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
+ aNewDesc.aQueryParam = rQueryItem.GetQueryData();
+
+ ScDPObject aNewObj( *pDPObj );
+ aNewObj.SetSheetDesc( aNewDesc );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, TRUE, FALSE );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ delete pDlg;
+ }
+ else
+ Sound::Beep();
+ }
+ else
+ {
+ DBG_ERROR("Da is ja garnix");
+ }
+}
+
+// -----------------------------------------------------------------------
+//
+// Data Pilot interaction
+//
+
+void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove )
+{
+ DBG_ASSERT(pDragDPObj, "pDragDPObj missing");
+
+ // scroll window if at edges
+ //! move this to separate method
+
+ BOOL bTimer = FALSE;
+ Point aPixel = rMEvt.GetPosPixel();
+
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ if ( aPixel.X() < 0 )
+ nDx = -1;
+ if ( aPixel.Y() < 0 )
+ nDy = -1;
+ Size aSize = GetOutputSizePixel();
+ if ( aPixel.X() >= aSize.Width() )
+ nDx = 1;
+ if ( aPixel.Y() >= aSize.Height() )
+ nDy = 1;
+ if ( nDx != 0 || nDy != 0 )
+ {
+ UpdateDragRect( FALSE, Rectangle() );
+
+ if ( nDx != 0)
+ pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 )
+ pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+
+ bTimer = TRUE;
+ }
+
+ // ---
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), eWhich, nPosX, nPosY );
+ BOOL bMouseLeft;
+ BOOL bMouseTop;
+ pViewData->GetMouseQuadrant( aPixel, eWhich, nPosX, nPosY, bMouseLeft, bMouseTop );
+
+ ScAddress aPos( nPosX, nPosY, pViewData->GetTabNo() );
+
+ Rectangle aPosRect;
+ USHORT nOrient;
+ long nDimPos;
+ BOOL bHasRange = pDragDPObj->GetHeaderDrag( aPos, bMouseLeft, bMouseTop, nDPField,
+ aPosRect, nOrient, nDimPos );
+ UpdateDragRect( bHasRange && bMove, aPosRect );
+
+ BOOL bIsDataLayout;
+ sal_Int32 nDimFlags = 0;
+ String aDimName = pDragDPObj->GetDimName( nDPField, bIsDataLayout, &nDimFlags );
+ bool bAllowed = !bHasRange || ScDPObject::IsOrientationAllowed( nOrient, nDimFlags );
+
+ if (bMove) // set mouse pointer
+ {
+ PointerStyle ePointer = POINTER_PIVOT_DELETE;
+ if ( !bAllowed )
+ ePointer = POINTER_NOTALLOWED;
+ else if ( bHasRange )
+ switch (nOrient)
+ {
+ case sheet::DataPilotFieldOrientation_COLUMN: ePointer = POINTER_PIVOT_COL; break;
+ case sheet::DataPilotFieldOrientation_ROW: ePointer = POINTER_PIVOT_ROW; break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ case sheet::DataPilotFieldOrientation_DATA: ePointer = POINTER_PIVOT_FIELD; break;
+ }
+ SetPointer( ePointer );
+ }
+ else // execute change
+ {
+ if (!bHasRange)
+ nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ if ( bIsDataLayout && ( nOrient != sheet::DataPilotFieldOrientation_COLUMN &&
+ nOrient != sheet::DataPilotFieldOrientation_ROW ) )
+ {
+ // removing data layout is not allowed
+ pViewData->GetView()->ErrorMessage(STR_PIVOT_MOVENOTALLOWED);
+ }
+ else if ( bAllowed )
+ {
+ ScDPSaveData aSaveData( *pDragDPObj->GetSaveData() );
+
+ ScDPSaveDimension* pDim;
+ if ( bIsDataLayout )
+ pDim = aSaveData.GetDataLayoutDimension();
+ else
+ pDim = aSaveData.GetDimensionByName(aDimName);
+ pDim->SetOrientation( nOrient );
+ aSaveData.SetPosition( pDim, nDimPos );
+
+ //! docfunc method with ScDPSaveData as argument?
+
+ ScDPObject aNewObj( *pDragDPObj );
+ aNewObj.SetSaveData( aSaveData );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ // when dragging fields, allow re-positioning (bAllowMove)
+ aFunc.DataPilotUpdate( pDragDPObj, &aNewObj, TRUE, FALSE, TRUE );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ }
+
+ if (bTimer && bMove)
+ pViewData->GetView()->SetTimer( this, rMEvt ); // repeat event
+ else
+ pViewData->GetView()->ResetTimer();
+}
+
+bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ BOOL bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings());
+ aBtn.setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
+ aBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
+ Point aPopupPos;
+ Size aPopupSize;
+ aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ // Mouse cursor inside the popup arrow box. Launch the field menu.
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj);
+ return true;
+ }
+
+ return false;
+}
+
+namespace {
+
+struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
+{
+ ScPivotParam maDPParam;
+ ScDPObject* mpDPObj;
+ long mnDim;
+};
+
+class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
+{
+public:
+ explicit DPFieldPopupOKAction(ScGridWindow* p) :
+ mpGridWindow(p) {}
+
+ virtual void execute()
+ {
+ mpGridWindow->UpdateDPFromFieldPopupMenu();
+ }
+private:
+ ScGridWindow* mpGridWindow;
+};
+
+class PopupSortAction : public ScMenuFloatingWindow::Action
+{
+public:
+ enum SortType { ASCENDING, DESCENDING, CUSTOM };
+
+ explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
+ maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
+
+ virtual void execute()
+ {
+ switch (meType)
+ {
+ case ASCENDING:
+ mpViewShell->DataPilotSort(maPos, true);
+ break;
+ case DESCENDING:
+ mpViewShell->DataPilotSort(maPos, false);
+ break;
+ case CUSTOM:
+ mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
+ break;
+ default:
+ ;
+ }
+ }
+
+private:
+ ScAddress maPos;
+ SortType meType;
+ sal_uInt16 mnUserListIndex;
+ ScTabViewShell* mpViewShell;
+};
+
+}
+
+void ScGridWindow::DPLaunchFieldPopupMenu(
+ const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ // We need to get the list of field members.
+ auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
+ pDPObj->FillLabelData(pDPData->maDPParam);
+ pDPData->mpDPObj = pDPObj;
+
+ USHORT nOrient;
+ pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
+
+ if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
+ // out-of-bound dimension ID. This should never happen!
+ return;
+
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+
+ mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument()));
+ mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup"));
+ mpDPFieldPopup->setExtendedData(pDPData.release());
+ mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
+ {
+ // Populate field members.
+ size_t n = rLabelData.maMembers.size();
+ mpDPFieldPopup->setMemberSize(n);
+ for (size_t i = 0; i < n; ++i)
+ {
+ const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
+ mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible);
+ }
+ mpDPFieldPopup->initMembers();
+ }
+
+ vector<OUString> aUserSortNames;
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (pUserList)
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ aUserSortNames.reserve(n);
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
+ aUserSortNames.push_back(pData->GetString());
+ }
+ }
+
+ // Populate the menus.
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
+ ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
+
+ if (pSubMenu && !aUserSortNames.empty())
+ {
+ size_t n = aUserSortNames.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ pSubMenu->addMenuItem(
+ aUserSortNames[i], true,
+ new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell));
+ }
+ }
+
+ BOOL bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+
+ Rectangle aCellRect(rScrPos, rScrSize);
+ const Size& rPopupSize = mpDPFieldPopup->getWindowSize();
+ if (bLayoutRTL)
+ {
+ // RTL: rScrPos is logical-left (visual right) position, always right-align with that
+ aCellRect.SetPos(Point(rScrPos.X() - rPopupSize.Width() + 1, rScrPos.Y()));
+ }
+ else if (rScrSize.getWidth() > rPopupSize.getWidth())
+ {
+ // If the cell width is larger than the popup window width, launch it
+ // right-aligned with the cell.
+ long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth();
+ aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y()));
+ }
+ mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
+ mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
+}
+
+void ScGridWindow::UpdateDPFromFieldPopupMenu()
+{
+ typedef hash_map<OUString, OUString, OUStringHash> MemNameMapType;
+ typedef hash_map<OUString, bool, OUStringHash> MemVisibilityType;
+
+ if (!mpDPFieldPopup.get())
+ return;
+
+ DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
+ if (!pDPData)
+ return;
+
+ ScDPObject* pDPObj = pDPData->mpDPObj;
+ ScDPObject aNewDPObj(*pDPObj);
+ aNewDPObj.BuildAllDimensionMembers();
+ ScDPSaveData* pSaveData = aNewDPObj.GetSaveData();
+
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
+ ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
+ if (!pDim)
+ return;
+
+ // Build a map of layout names to original names.
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+ MemNameMapType aMemNameMap;
+ for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end();
+ itr != itrEnd; ++itr)
+ aMemNameMap.insert(MemNameMapType::value_type(itr->maLayoutName, itr->maName));
+
+ // The raw result may contain a mixture of layout names and original names.
+ MemVisibilityType aRawResult;
+ mpDPFieldPopup->getResult(aRawResult);
+
+ MemVisibilityType aResult;
+ for (MemVisibilityType::const_iterator itr = aRawResult.begin(), itrEnd = aRawResult.end(); itr != itrEnd; ++itr)
+ {
+ MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(itr->first);
+ if (itrNameMap == aMemNameMap.end())
+ // This is an original member name. Use it as-is.
+ aResult.insert(MemVisibilityType::value_type(itr->first, itr->second));
+ else
+ {
+ // This is a layout name. Get the original member name and use it.
+ aResult.insert(MemVisibilityType::value_type(itrNameMap->second, itr->second));
+ }
+ }
+ pDim->UpdateMemberVisibility(aResult);
+
+ ScDBDocFunc aFunc(*pViewData->GetDocShell());
+ aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false);
+}
+
+void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt )
+{
+ DPTestMouse( rMEvt, TRUE );
+}
+
+void ScGridWindow::DPMouseButtonUp( const MouseEvent& rMEvt )
+{
+ bDPMouse = FALSE;
+ ReleaseMouse();
+
+ DPTestMouse( rMEvt, FALSE );
+ SetPointer( Pointer( POINTER_ARROW ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ScGridWindow::UpdateDragRect( BOOL bShowRange, const Rectangle& rPosRect )
+{
+ SCCOL nStartX = ( rPosRect.Left() >= 0 ) ? static_cast<SCCOL>(rPosRect.Left()) : SCCOL_MAX;
+ SCROW nStartY = ( rPosRect.Top() >= 0 ) ? static_cast<SCROW>(rPosRect.Top()) : SCROW_MAX;
+ SCCOL nEndX = ( rPosRect.Right() >= 0 ) ? static_cast<SCCOL>(rPosRect.Right()) : SCCOL_MAX;
+ SCROW nEndY = ( rPosRect.Bottom() >= 0 ) ? static_cast<SCROW>(rPosRect.Bottom()) : SCROW_MAX;
+
+ if ( bShowRange == bDragRect && nDragStartX == nStartX && nDragEndX == nEndX &&
+ nDragStartY == nStartY && nDragEndY == nEndY )
+ {
+ return; // everything unchanged
+ }
+
+ // if ( bDragRect )
+ // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
+ if ( bShowRange )
+ {
+ nDragStartX = nStartX;
+ nDragStartY = nStartY;
+ nDragEndX = nEndX;
+ nDragEndY = nEndY;
+ bDragRect = TRUE;
+ // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
+ }
+ else
+ bDragRect = FALSE;
+
+ UpdateDragRectOverlay();
+}
+
+// -----------------------------------------------------------------------
+
+// Page-Break-Modus
+
+USHORT ScGridWindow::HitPageBreak( const Point& rMouse, ScRange* pSource,
+ SCCOLROW* pBreak, SCCOLROW* pPrev )
+{
+ USHORT nFound = SC_PD_NONE; // 0
+ ScRange aSource;
+ SCCOLROW nBreak = 0;
+ SCCOLROW nPrev = 0;
+
+ ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
+ if ( pPageData )
+ {
+ BOOL bHori = FALSE;
+ BOOL bVert = FALSE;
+ SCCOL nHitX = 0;
+ SCROW nHitY = 0;
+
+ long nMouseX = rMouse.X();
+ long nMouseY = rMouse.Y();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( nMouseX, nMouseY, eWhich, nPosX, nPosY );
+ Point aTL = pViewData->GetScrPos( nPosX, nPosY, eWhich );
+ Point aBR = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
+
+ // Horizontal mehr Toleranz als vertikal, weil mehr Platz ist
+ if ( nMouseX <= aTL.X() + 4 )
+ {
+ bHori = TRUE;
+ nHitX = nPosX;
+ }
+ else if ( nMouseX >= aBR.X() - 6 )
+ {
+ bHori = TRUE;
+ nHitX = nPosX+1; // linker Rand der naechsten Zelle
+ }
+ if ( nMouseY <= aTL.Y() + 2 )
+ {
+ bVert = TRUE;
+ nHitY = nPosY;
+ }
+ else if ( nMouseY >= aBR.Y() - 4 )
+ {
+ bVert = TRUE;
+ nHitY = nPosY+1; // oberer Rand der naechsten Zelle
+ }
+
+ if ( bHori || bVert )
+ {
+ USHORT nCount = sal::static_int_cast<USHORT>( pPageData->GetCount() );
+ for (USHORT nPos=0; nPos<nCount && !nFound; nPos++)
+ {
+ ScPrintRangeData& rData = pPageData->GetData(nPos);
+ ScRange aRange = rData.GetPrintRange();
+ BOOL bLHit = ( bHori && nHitX == aRange.aStart.Col() );
+ BOOL bRHit = ( bHori && nHitX == aRange.aEnd.Col() + 1 );
+ BOOL bTHit = ( bVert && nHitY == aRange.aStart.Row() );
+ BOOL bBHit = ( bVert && nHitY == aRange.aEnd.Row() + 1 );
+ BOOL bInsideH = ( nPosX >= aRange.aStart.Col() && nPosX <= aRange.aEnd.Col() );
+ BOOL bInsideV = ( nPosY >= aRange.aStart.Row() && nPosY <= aRange.aEnd.Row() );
+
+ if ( bLHit )
+ {
+ if ( bTHit )
+ nFound = SC_PD_RANGE_TL;
+ else if ( bBHit )
+ nFound = SC_PD_RANGE_BL;
+ else if ( bInsideV )
+ nFound = SC_PD_RANGE_L;
+ }
+ else if ( bRHit )
+ {
+ if ( bTHit )
+ nFound = SC_PD_RANGE_TR;
+ else if ( bBHit )
+ nFound = SC_PD_RANGE_BR;
+ else if ( bInsideV )
+ nFound = SC_PD_RANGE_R;
+ }
+ else if ( bTHit && bInsideH )
+ nFound = SC_PD_RANGE_T;
+ else if ( bBHit && bInsideH )
+ nFound = SC_PD_RANGE_B;
+ if (nFound)
+ aSource = aRange;
+
+ // Umbrueche
+
+ if ( bVert && bInsideH && !nFound )
+ {
+ size_t nRowCount = rData.GetPagesY();
+ const SCROW* pRowEnd = rData.GetPageEndY();
+ for (size_t nRowPos=0; nRowPos+1<nRowCount; nRowPos++)
+ if ( pRowEnd[nRowPos]+1 == nHitY )
+ {
+ nFound = SC_PD_BREAK_V;
+ aSource = aRange;
+ nBreak = nHitY;
+ if ( nRowPos )
+ nPrev = pRowEnd[nRowPos-1]+1;
+ else
+ nPrev = aRange.aStart.Row();
+ }
+ }
+ if ( bHori && bInsideV && !nFound )
+ {
+ size_t nColCount = rData.GetPagesX();
+ const SCCOL* pColEnd = rData.GetPageEndX();
+ for (size_t nColPos=0; nColPos+1<nColCount; nColPos++)
+ if ( pColEnd[nColPos]+1 == nHitX )
+ {
+ nFound = SC_PD_BREAK_H;
+ aSource = aRange;
+ nBreak = nHitX;
+ if ( nColPos )
+ nPrev = pColEnd[nColPos-1]+1;
+ else
+ nPrev = aRange.aStart.Col();
+ }
+ }
+ }
+ }
+ }
+
+ if (pSource)
+ *pSource = aSource; // Druckbereich
+ if (pBreak)
+ *pBreak = nBreak; // X/Y Position des verchobenen Seitenumbruchs
+ if (pPrev)
+ *pPrev = nPrev; // X/Y Anfang der Seite, die am Umbruch zuende ist
+ return nFound;
+}
+
+void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp )
+{
+ //! Scrolling und Umschalten mit RFMouseMove zusammenfassen !
+ //! (Weginvertieren vor dem Scrolling ist anders)
+
+ // Scrolling
+
+ BOOL bTimer = FALSE;
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ if ( aPos.X() < 0 ) nDx = -1;
+ if ( aPos.Y() < 0 ) nDy = -1;
+ Size aSize = GetOutputSizePixel();
+ if ( aPos.X() >= aSize.Width() )
+ nDx = 1;
+ if ( aPos.Y() >= aSize.Height() )
+ nDy = 1;
+ if ( nDx != 0 || nDy != 0 )
+ {
+ if ( bPagebreakDrawn ) // weginvertieren
+ {
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
+ bPagebreakDrawn = FALSE;
+ UpdateDragRectOverlay();
+ }
+
+ if ( nDx != 0 ) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+ bTimer = TRUE;
+ }
+
+ // Umschalten bei Fixierung (damit Scrolling funktioniert)
+
+ if ( eWhich == pViewData->GetActivePart() ) //??
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ if ( nDx > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ if ( nDy > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+ }
+
+ // ab hier neu
+
+ // gesucht wird eine Position zwischen den Zellen (vor nPosX / nPosY)
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ BOOL bLeft, bTop;
+ pViewData->GetMouseQuadrant( aPos, eWhich, nPosX, nPosY, bLeft, bTop );
+ if ( !bLeft ) ++nPosX;
+ if ( !bTop ) ++nPosY;
+
+ BOOL bBreak = ( nPagebreakMouse == SC_PD_BREAK_H || nPagebreakMouse == SC_PD_BREAK_V );
+ BOOL bHide = FALSE;
+ BOOL bToEnd = FALSE;
+ ScRange aDrawRange = aPagebreakSource;
+ if ( bBreak )
+ {
+ if ( nPagebreakMouse == SC_PD_BREAK_H )
+ {
+ if ( nPosX > aPagebreakSource.aStart.Col() &&
+ nPosX <= aPagebreakSource.aEnd.Col() + 1 ) // ans Ende ist auch erlaubt
+ {
+ bToEnd = ( nPosX == aPagebreakSource.aEnd.Col() + 1 );
+ aDrawRange.aStart.SetCol( nPosX );
+ aDrawRange.aEnd.SetCol( nPosX - 1 );
+ }
+ else
+ bHide = TRUE;
+ }
+ else
+ {
+ if ( nPosY > aPagebreakSource.aStart.Row() &&
+ nPosY <= aPagebreakSource.aEnd.Row() + 1 ) // ans Ende ist auch erlaubt
+ {
+ bToEnd = ( nPosY == aPagebreakSource.aEnd.Row() + 1 );
+ aDrawRange.aStart.SetRow( nPosY );
+ aDrawRange.aEnd.SetRow( nPosY - 1 );
+ }
+ else
+ bHide = TRUE;
+ }
+ }
+ else
+ {
+ if ( nPagebreakMouse & SC_PD_RANGE_L )
+ aDrawRange.aStart.SetCol( nPosX );
+ if ( nPagebreakMouse & SC_PD_RANGE_T )
+ aDrawRange.aStart.SetRow( nPosY );
+ if ( nPagebreakMouse & SC_PD_RANGE_R )
+ {
+ if ( nPosX > 0 )
+ aDrawRange.aEnd.SetCol( nPosX-1 );
+ else
+ bHide = TRUE;
+ }
+ if ( nPagebreakMouse & SC_PD_RANGE_B )
+ {
+ if ( nPosY > 0 )
+ aDrawRange.aEnd.SetRow( nPosY-1 );
+ else
+ bHide = TRUE;
+ }
+ if ( aDrawRange.aStart.Col() > aDrawRange.aEnd.Col() ||
+ aDrawRange.aStart.Row() > aDrawRange.aEnd.Row() )
+ bHide = TRUE;
+ }
+
+ if ( !bPagebreakDrawn || bUp || aDrawRange != aPagebreakDrag )
+ {
+ // zeichnen...
+
+ if ( bPagebreakDrawn )
+ {
+ // weginvertieren
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
+ bPagebreakDrawn = FALSE;
+ }
+ aPagebreakDrag = aDrawRange;
+ if ( !bUp && !bHide )
+ {
+ // hininvertieren
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
+ bPagebreakDrawn = TRUE;
+ }
+ UpdateDragRectOverlay();
+ }
+
+ // bei ButtonUp die Aenderung ausfuehren
+
+ if ( bUp )
+ {
+ ScViewFunc* pViewFunc = pViewData->GetView();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ if ( bBreak )
+ {
+ BOOL bColumn = ( nPagebreakMouse == SC_PD_BREAK_H );
+ SCCOLROW nNew = bColumn ? static_cast<SCCOLROW>(nPosX) : static_cast<SCCOLROW>(nPosY);
+ if ( nNew != nPagebreakBreak )
+ {
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_DRAG_BREAK );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ BOOL bGrow = !bHide && nNew > nPagebreakBreak;
+ if ( bColumn )
+ {
+ if (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & BREAK_MANUAL)
+ {
+ ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab );
+ pViewFunc->DeletePageBreak( TRUE, TRUE, &aOldAddr, FALSE );
+ }
+ if ( !bHide && !bToEnd ) // am Ende nicht
+ {
+ ScAddress aNewAddr( static_cast<SCCOL>(nNew), nPosY, nTab );
+ pViewFunc->InsertPageBreak( TRUE, TRUE, &aNewAddr, FALSE );
+ }
+ if ( bGrow )
+ {
+ // vorigen Break auf hart, und Skalierung aendern
+ bool bManualBreak = (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakPrev), nTab) & BREAK_MANUAL);
+ if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak )
+ {
+ ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab );
+ pViewFunc->InsertPageBreak( TRUE, TRUE, &aPrev, FALSE );
+ }
+
+ if (!pDocSh->AdjustPrintZoom( ScRange(
+ static_cast<SCCOL>(nPagebreakPrev),0,nTab, static_cast<SCCOL>(nNew-1),0,nTab ) ))
+ bGrow = FALSE;
+ }
+ }
+ else
+ {
+ if (pDoc->HasRowBreak(nPagebreakBreak, nTab) & BREAK_MANUAL)
+ {
+ ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab );
+ pViewFunc->DeletePageBreak( FALSE, TRUE, &aOldAddr, FALSE );
+ }
+ if ( !bHide && !bToEnd ) // am Ende nicht
+ {
+ ScAddress aNewAddr( nPosX, nNew, nTab );
+ pViewFunc->InsertPageBreak( FALSE, TRUE, &aNewAddr, FALSE );
+ }
+ if ( bGrow )
+ {
+ // vorigen Break auf hart, und Skalierung aendern
+ bool bManualBreak = (pDoc->HasRowBreak(nPagebreakPrev, nTab) & BREAK_MANUAL);
+ if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak )
+ {
+ ScAddress aPrev( nPosX, nPagebreakPrev, nTab );
+ pViewFunc->InsertPageBreak( FALSE, TRUE, &aPrev, FALSE );
+ }
+
+ if (!pDocSh->AdjustPrintZoom( ScRange(
+ 0,nPagebreakPrev,nTab, 0,nNew-1,nTab ) ))
+ bGrow = FALSE;
+ }
+ }
+
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+
+ if (!bGrow) // sonst in AdjustPrintZoom schon passiert
+ {
+ pViewFunc->UpdatePageBreakData( TRUE );
+ pDocSh->SetDocumentModified();
+ }
+ }
+ }
+ else if ( bHide || aPagebreakDrag != aPagebreakSource )
+ {
+ // Druckbereich setzen
+
+ String aNewRanges;
+ USHORT nOldCount = pDoc->GetPrintRangeCount( nTab );
+ if ( nOldCount )
+ {
+ for (USHORT nPos=0; nPos<nOldCount; nPos++)
+ {
+ const ScRange* pOld = pDoc->GetPrintRange( nTab, nPos );
+ if ( pOld )
+ {
+ String aTemp;
+ if ( *pOld != aPagebreakSource )
+ pOld->Format( aTemp, SCA_VALID );
+ else if ( !bHide )
+ aPagebreakDrag.Format( aTemp, SCA_VALID );
+ if (aTemp.Len())
+ {
+ if ( aNewRanges.Len() )
+ aNewRanges += ';';
+ aNewRanges += aTemp;
+ }
+ }
+ }
+ }
+ else if (!bHide)
+ aPagebreakDrag.Format( aNewRanges, SCA_VALID );
+
+ pViewFunc->SetPrintRanges( pDoc->IsPrintEntireSheet( nTab ), &aNewRanges, NULL, NULL, FALSE );
+ }
+ }
+
+ // Timer fuer Scrolling
+
+ if (bTimer && !bUp)
+ pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
+ else
+ pViewData->GetView()->ResetTimer();
+}
+
+
+
+
diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx
new file mode 100644
index 000000000000..cdb7e8acfba7
--- /dev/null
+++ b/sc/source/ui/view/gridwin3.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/svdoutl.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdpagv.hxx>
+#include <editeng/sizeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/ptitem.hxx>
+
+#include "tabvwsh.hxx"
+#include "gridwin.hxx"
+#include "dbfunc.hxx"
+#include "viewdata.hxx"
+#include "output.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+
+#include "drawutil.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include <vcl/svapp.hxx>
+
+// -----------------------------------------------------------------------
+
+BOOL ScGridWindow::DrawMouseButtonDown(const MouseEvent& rMEvt)
+{
+ BOOL bRet = FALSE;
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ Point aLogicPos = PixelToLogic(rMEvt.GetPosPixel());
+ if ( pDraw->IsDetectiveHit( aLogicPos ) )
+ {
+ // auf Detektiv-Pfeilen gar nichts (Doppelklick wird bei ButtonUp ausgewertet)
+ bRet = TRUE;
+ }
+ else
+ {
+ bRet = pDraw->MouseButtonDown( rMEvt );
+ if ( bRet )
+ UpdateStatusPosSize();
+ }
+ }
+
+ // bei rechter Taste Draw-Aktion abbrechen
+
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ if ( pDrView && !rMEvt.IsLeft() && !bRet )
+ {
+ pDrView->BrkAction();
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+BOOL ScGridWindow::DrawMouseButtonUp(const MouseEvent& rMEvt)
+{
+ ScViewFunc* pView = pViewData->GetView();
+ BOOL bRet = FALSE;
+ FuPoor* pDraw = pView->GetDrawFuncPtr();
+ if (pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ bRet = pDraw->MouseButtonUp( rMEvt );
+
+ // execute "format paint brush" for drawing objects
+ SfxItemSet* pDrawBrush = pView->GetDrawBrushSet();
+ if ( pDrawBrush )
+ {
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ if ( pDrView )
+ {
+ BOOL bReplaceAll = TRUE;
+ pDrView->SetAttrToMarked(*pDrawBrush, bReplaceAll);
+ }
+
+ if ( !pView->IsPaintBrushLocked() )
+ pView->ResetBrushDocument(); // end paint brush mode if not locked
+ }
+ }
+
+ return bRet;
+}
+
+BOOL ScGridWindow::DrawMouseMove(const MouseEvent& rMEvt)
+{
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ BOOL bRet = pDraw->MouseMove( rMEvt );
+ if ( bRet )
+ UpdateStatusPosSize();
+ return bRet;
+ }
+ else
+ {
+ SetPointer( Pointer( POINTER_ARROW ) );
+ return FALSE;
+ }
+}
+
+void ScGridWindow::DrawEndAction()
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ if ( pDrView && pDrView->IsAction() )
+ pDrView->BrkAction();
+
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDraw)
+ pDraw->StopDragTimer();
+
+ // ReleaseMouse beim Aufruf
+}
+
+BOOL ScGridWindow::DrawCommand(const CommandEvent& rCEvt)
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDrView && pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ BYTE nUsed = pDraw->Command( rCEvt );
+ if( nUsed == SC_CMD_USED )
+ nButtonDown = 0; // MouseButtonUp wird verschluckt...
+ if( nUsed || pDrView->IsAction() )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL ScGridWindow::DrawKeyInput(const KeyEvent& rKEvt)
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDrView && pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ BOOL bOldMarked = pDrView->AreObjectsMarked();
+ if (pDraw->KeyInput( rKEvt ))
+ {
+ BOOL bLeaveDraw = FALSE;
+ BOOL bUsed = TRUE;
+ BOOL bNewMarked = pDrView->AreObjectsMarked();
+ if ( !pViewData->GetView()->IsDrawSelMode() )
+ if ( !bNewMarked )
+ {
+ pViewData->GetViewShell()->SetDrawShell( FALSE );
+ bLeaveDraw = TRUE;
+ if ( !bOldMarked &&
+ rKEvt.GetKeyCode().GetCode() == KEY_DELETE )
+ bUsed = FALSE; // nichts geloescht
+ }
+ if (!bLeaveDraw)
+ UpdateStatusPosSize(); // #108137# for moving/resizing etc. by keyboard
+ return bUsed;
+ }
+ }
+
+ return FALSE;
+}
+
+void ScGridWindow::DrawRedraw( ScOutputData& rOutputData, ScUpdateMode eMode, ULONG nLayer )
+{
+ // #109985#
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+
+ // use new flags at SdrPaintView for hiding objects
+ const bool bDrawOle(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_OLE));
+ const bool bDrawChart(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_CHART));
+ const bool bDrawDraw(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_DRAW));
+
+ if(bDrawOle || bDrawChart || bDrawDraw)
+ {
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+
+ if(pDrView)
+ {
+ pDrView->setHideOle(!bDrawOle);
+ pDrView->setHideChart(!bDrawChart);
+ pDrView->setHideDraw(!bDrawDraw);
+ pDrView->setHideFormControl(!bDrawDraw);
+ }
+
+ if(SC_UPDATE_CHANGED == eMode)
+ {
+ rOutputData.DrawingSingle((sal_uInt16)nLayer);
+ }
+ else
+ {
+ rOutputData.DrawSelectiveObjects((sal_uInt16)nLayer);
+ }
+ }
+}
+
+void ScGridWindow::DrawSdrGrid( const Rectangle& rDrawingRect, OutputDevice* pContentDev )
+{
+ // Draw-Gitterlinien
+
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if ( pDrView && pDrView->IsGridVisible() )
+ {
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ DBG_ASSERT(pPV, "keine PageView");
+ if (pPV)
+ {
+ pContentDev->SetLineColor(COL_GRAY);
+
+ pPV->DrawPageViewGrid( *pContentDev, rDrawingRect );
+ }
+ }
+}
+
+MapMode ScGridWindow::GetDrawMapMode( BOOL bForce )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+
+ MapMode aDrawMode = pViewData->GetLogicMode();
+
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if ( pDrView || bForce )
+ {
+ Fraction aScaleX;
+ Fraction aScaleY;
+ if (pDrView)
+ pDrView->GetScale( aScaleX, aScaleY );
+ else
+ {
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pDoc->GetTableArea( nTab, nEndCol, nEndRow );
+ if (nEndCol<20) nEndCol = 20;
+ if (nEndRow<20) nEndRow = 1000;
+ ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, this,
+ pViewData->GetZoomX(),pViewData->GetZoomY(),
+ pViewData->GetPPTX(),pViewData->GetPPTY(),
+ aScaleX,aScaleY );
+ }
+ aDrawMode.SetScaleX(aScaleX);
+ aDrawMode.SetScaleY(aScaleY);
+ }
+ aDrawMode.SetOrigin(Point());
+ Point aStartPos = pViewData->GetPixPos(eWhich);
+ if ( bNegativePage )
+ {
+ // RTL uses negative positions for drawing objects
+ aStartPos.X() = -aStartPos.X() + GetOutputSizePixel().Width() - 1;
+ }
+ aDrawMode.SetOrigin( PixelToLogic( aStartPos, aDrawMode ) );
+
+ return aDrawMode;
+}
+
+//BOOL ScGridWindow::DrawBeforeScroll()
+//{
+// ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+//
+// BOOL bXor = FALSE;
+// if (pDrView)
+// {
+// bXor=pDrView->IsShownXorVisible(this);
+// if (bXor) pDrView->HideShownXor(this);
+// }
+// return bXor;
+//}
+
+void ScGridWindow::DrawAfterScroll(/*BOOL bVal*/)
+{
+ Update(); // immer, damit das Verhalten mit/ohne DrawingLayer gleich ist
+
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ {
+ //if (bVal)
+ // pDrView->ShowShownXor(this);
+
+ OutlinerView* pOlView = pDrView->GetTextEditOutlinerView();
+ if (pOlView && pOlView->GetWindow() == this)
+ pOlView->ShowCursor(FALSE); // ist beim Scrollen weggekommen
+ }
+}
+
+//void ScGridWindow::DrawMarks()
+//{
+// ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+// if (pDrView)
+// pDrView->DrawMarks(this);
+//}
+
+//BOOL ScGridWindow::NeedDrawMarks()
+//{
+// ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+// return pDrView && pDrView->IsMarkHdlShown() && pDrView->AreObjectsMarked();
+//}
+
+void ScGridWindow::CreateAnchorHandle(SdrHdlList& rHdl, const ScAddress& rAddress)
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ {
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ if(rOpts.GetOption( VOPT_ANCHOR ))
+ {
+ BOOL bNegativePage = pViewData->GetDocument()->IsNegativePage( pViewData->GetTabNo() );
+ Point aPos = pViewData->GetScrPos( rAddress.Col(), rAddress.Row(), eWhich, TRUE );
+ aPos = PixelToLogic(aPos);
+ rHdl.AddHdl(new SdrHdl(aPos, bNegativePage ? HDL_ANCHOR_TR : HDL_ANCHOR));
+ }
+ }
+}
+
+SdrObject* ScGridWindow::GetEditObject()
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ {
+ OutlinerView* pOlView = pDrView->GetTextEditOutlinerView();
+ if (pOlView && pOlView->GetWindow() == this)
+ return pDrView->GetTextEditObject();
+ }
+
+ return NULL;
+}
+
+void ScGridWindow::UpdateStatusPosSize()
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (!pDrView)
+ return; // shouldn't be called in that case
+
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ if (!pPV)
+ return; // shouldn't be called in that case either
+
+ SfxItemSet aSet(pViewData->GetViewShell()->GetPool(), SID_ATTR_POSITION, SID_ATTR_SIZE);
+
+ // Fill items for position and size:
+ // #108137# show action rectangle during action,
+ // position and size of selected object(s) if something is selected,
+ // mouse position otherwise
+
+ BOOL bActionItem = FALSE;
+ if ( pDrView->IsAction() ) // action rectangle
+ {
+ Rectangle aRect;
+ pDrView->TakeActionRect( aRect );
+ if ( !aRect.IsEmpty() )
+ {
+ pPV->LogicToPagePos(aRect);
+ aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
+ aSet.Put( SvxSizeItem( SID_ATTR_SIZE,
+ Size( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ) ) );
+ bActionItem = TRUE;
+ }
+ }
+ if ( !bActionItem )
+ {
+ if ( pDrView->AreObjectsMarked() ) // selected objects
+ {
+ Rectangle aRect = pDrView->GetAllMarkedRect();
+ pPV->LogicToPagePos(aRect);
+ aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
+ aSet.Put( SvxSizeItem( SID_ATTR_SIZE,
+ Size( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ) ) );
+ }
+ else // mouse position
+ {
+ Point aPos = PixelToLogic(aCurMousePos);
+ pPV->LogicToPagePos(aPos);
+ aSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos ) );
+ aSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
+ }
+ }
+
+ pViewData->GetBindings().SetState(aSet);
+}
+
+BOOL ScGridWindow::DrawHasMarkedObj()
+{
+ ScDrawView* p = pViewData->GetScDrawView();
+ return p ? p->AreObjectsMarked() : FALSE;
+}
+
+//void ScGridWindow::DrawStartTimer()
+//{
+ //ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ //if (pDrView)
+ //{
+ /* jetzt in DrawMarks
+ USHORT nWinNum = pDrView->FindWin(this);
+ if (nWinNum!=SDRVIEWWIN_NOTFOUND)
+ pDrView->AfterInitRedraw(nWinNum);
+ */
+
+ // pDrView->PostPaint();
+ // pDrView->RestartAfterPaintTimer();
+ //}
+//}
+
+void ScGridWindow::DrawMarkDropObj( SdrObject* pObj )
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ pDrView->MarkDropObj(pObj);
+}
+
+
+
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
new file mode 100644
index 000000000000..372dcc582a45
--- /dev/null
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -0,0 +1,2069 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svtools/colorcfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/printer.hxx>
+
+#include <svx/svdview.hxx>
+#include "tabvwsh.hxx"
+
+#include "gridwin.hxx"
+#include "viewdata.hxx"
+#include "output.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx" // InvertSimple
+#include "dbcolect.hxx"
+#include "docoptio.hxx"
+#include "notemark.hxx"
+#include "dbfunc.hxx" // oder GetPageBreakData an die ViewData
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "rfindlst.hxx"
+#include "hiranges.hxx"
+#include "pagedata.hxx"
+#include "docpool.hxx"
+#include "globstr.hrc"
+#include "docsh.hxx" // oder GetSfxInPlaceObject
+#include "cbutton.hxx"
+#include "invmerge.hxx"
+#include "editutil.hxx"
+#include "inputopt.hxx"
+#include "fillinfo.hxx"
+#include "dpcontrol.hxx"
+#include "queryparam.hxx"
+#include "sc.hrc"
+#include <vcl/virdev.hxx>
+
+// #i74769#
+#include <svx/sdrpaintwindow.hxx>
+
+//#include "tabvwsh.hxx" //! Test !!!!
+
+//------------------------------------------------------------------------
+
+void lcl_LimitRect( Rectangle& rRect, const Rectangle& rVisible )
+{
+ if ( rRect.Top() < rVisible.Top()-1 ) rRect.Top() = rVisible.Top()-1;
+// if ( rRect.Left() < rVisible.Left()-1 ) rRect.Left() = rVisible.Left()-1;
+ if ( rRect.Bottom() > rVisible.Bottom()+1 ) rRect.Bottom() = rVisible.Bottom()+1;
+// if ( rRect.Right() > rVisible.Right()+1 ) rRect.Right() = rVisible.Right()+1;
+
+ // #51122# auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl.
+ // die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr.
+ // Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen.
+}
+
+void lcl_DrawOneFrame( OutputDevice* pDev, const Rectangle& rInnerPixel,
+ const String& rTitle, const Color& rColor, BOOL bTextBelow,
+ double nPPTX, double nPPTY, const Fraction& rZoomY,
+ ScDocument* pDoc, ScViewData* pButtonViewData, BOOL bLayoutRTL )
+{
+ // pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen,
+ // darf ansonsten NULL sein!
+
+ Rectangle aInner = rInnerPixel;
+ if ( bLayoutRTL )
+ {
+ aInner.Left() = rInnerPixel.Right();
+ aInner.Right() = rInnerPixel.Left();
+ }
+
+ Rectangle aVisible( Point(0,0), pDev->GetOutputSizePixel() );
+ lcl_LimitRect( aInner, aVisible );
+
+ Rectangle aOuter = aInner;
+ long nHor = (long) ( SC_SCENARIO_HSPACE * nPPTX );
+ long nVer = (long) ( SC_SCENARIO_VSPACE * nPPTY );
+ aOuter.Left() -= nHor;
+ aOuter.Right() += nHor;
+ aOuter.Top() -= nVer;
+ aOuter.Bottom() += nVer;
+
+ // use ScPatternAttr::GetFont only for font size
+ Font aAttrFont;
+ ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
+ GetFont(aAttrFont,SC_AUTOCOL_BLACK,pDev,&rZoomY);
+
+ // everything else from application font
+ Font aAppFont = pDev->GetSettings().GetStyleSettings().GetAppFont();
+ aAppFont.SetSize( aAttrFont.GetSize() );
+
+ aAppFont.SetAlign( ALIGN_TOP );
+ pDev->SetFont( aAppFont );
+
+ Size aTextSize( pDev->GetTextWidth( rTitle ), pDev->GetTextHeight() );
+
+ if ( bTextBelow )
+ aOuter.Bottom() += aTextSize.Height();
+ else
+ aOuter.Top() -= aTextSize.Height();
+
+ pDev->SetLineColor();
+ pDev->SetFillColor( rColor );
+ // links, oben, rechts, unten
+ pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aInner.Left(), aOuter.Bottom() ) );
+ pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aOuter.Right(), aInner.Top() ) );
+ pDev->DrawRect( Rectangle( aInner.Right(), aOuter.Top(), aOuter.Right(), aOuter.Bottom() ) );
+ pDev->DrawRect( Rectangle( aOuter.Left(), aInner.Bottom(), aOuter.Right(), aOuter.Bottom() ) );
+
+ long nButtonY = bTextBelow ? aInner.Bottom() : aOuter.Top();
+
+ ScDDComboBoxButton aComboButton((Window*)pDev);
+ aComboButton.SetOptSizePixel();
+ long nBWidth = ( aComboButton.GetSizePixel().Width() * rZoomY.GetNumerator() )
+ / rZoomY.GetDenominator();
+ long nBHeight = nVer + aTextSize.Height() + 1;
+ Size aButSize( nBWidth, nBHeight );
+ long nButtonPos = bLayoutRTL ? aOuter.Left() : aOuter.Right()-nBWidth+1;
+ aComboButton.Draw( Point(nButtonPos, nButtonY), aButSize, FALSE );
+ if (pButtonViewData)
+ pButtonViewData->SetScenButSize( aButSize );
+
+ long nTextStart = bLayoutRTL ? aInner.Right() - aTextSize.Width() + 1 : aInner.Left();
+
+ BOOL bWasClip = FALSE;
+ Region aOldClip;
+ BOOL bClip = ( aTextSize.Width() > aOuter.Right() - nBWidth - aInner.Left() );
+ if ( bClip )
+ {
+ if (pDev->IsClipRegion())
+ {
+ bWasClip = TRUE;
+ aOldClip = pDev->GetActiveClipRegion();
+ }
+ long nClipStartX = bLayoutRTL ? aOuter.Left() + nBWidth : aInner.Left();
+ long nClipEndX = bLayoutRTL ? aInner.Right() : aOuter.Right() - nBWidth;
+ pDev->SetClipRegion( Rectangle( nClipStartX, nButtonY + nVer/2,
+ nClipEndX, nButtonY + nVer/2 + aTextSize.Height() ) );
+ }
+
+ pDev->DrawText( Point( nTextStart, nButtonY + nVer/2 ), rTitle );
+
+ if ( bClip )
+ {
+ if ( bWasClip )
+ pDev->SetClipRegion(aOldClip);
+ else
+ pDev->SetClipRegion();
+ }
+
+ pDev->SetFillColor();
+ pDev->SetLineColor( COL_BLACK );
+ pDev->DrawRect( aInner );
+ pDev->DrawRect( aOuter );
+}
+
+void lcl_DrawScenarioFrames( OutputDevice* pDev, ScViewData* pViewData, ScSplitPos eWhich,
+ SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
+ {
+ if ( nX1 > 0 ) --nX1;
+ if ( nY1>=2 ) nY1 -= 2; // Hack: Titelzeile beruehrt zwei Zellen
+ else if ( nY1 > 0 ) --nY1;
+ if ( nX2 < MAXCOL ) ++nX2;
+ if ( nY2 < MAXROW-1 ) nY2 += 2; // Hack: Titelzeile beruehrt zwei Zellen
+ else if ( nY2 < MAXROW ) ++nY2;
+ ScRange aViewRange( nX1,nY1,nTab, nX2,nY2,nTab );
+
+ //! Ranges an der Table cachen!!!!
+
+ ScMarkData aMarks;
+ for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ pDoc->MarkScenario( i, nTab, aMarks, FALSE, SC_SCENARIO_SHOWFRAME );
+ ScRangeListRef xRanges = new ScRangeList;
+ aMarks.FillRangeListWithMarks( xRanges, FALSE );
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ USHORT nRangeCount = (USHORT)xRanges->Count();
+ for (USHORT j=0; j<nRangeCount; j++)
+ {
+ ScRange aRange = *xRanges->GetObject(j);
+ // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
+ // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
+ pDoc->ExtendTotalMerge( aRange );
+
+ //! -> Repaint beim Zusammenfassen erweitern !!!
+
+ if ( aRange.Intersects( aViewRange ) ) //! Platz fuer Text/Button?
+ {
+ Point aStartPos = pViewData->GetScrPos(
+ aRange.aStart.Col(), aRange.aStart.Row(), eWhich, TRUE );
+ Point aEndPos = pViewData->GetScrPos(
+ aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich, TRUE );
+ // on the grid:
+ aStartPos.X() -= nLayoutSign;
+ aStartPos.Y() -= 1;
+ aEndPos.X() -= nLayoutSign;
+ aEndPos.Y() -= 1;
+
+ BOOL bTextBelow = ( aRange.aStart.Row() == 0 );
+
+ String aCurrent;
+ Color aColor( COL_LIGHTGRAY );
+ for (SCTAB nAct=nTab+1; nAct<nTabCount && pDoc->IsScenario(nAct); nAct++)
+ if ( pDoc->IsActiveScenario(nAct) && pDoc->HasScenarioRange(nAct,aRange) )
+ {
+ String aDummyComment;
+ USHORT nDummyFlags;
+ pDoc->GetName( nAct, aCurrent );
+ pDoc->GetScenarioData( nAct, aDummyComment, aColor, nDummyFlags );
+ }
+
+ if (!aCurrent.Len())
+ aCurrent = ScGlobal::GetRscString( STR_EMPTYDATA );
+
+ //! eigener Text "(keins)" statt "(leer)" ???
+
+ lcl_DrawOneFrame( pDev, Rectangle( aStartPos, aEndPos ),
+ aCurrent, aColor, bTextBelow,
+ pViewData->GetPPTX(), pViewData->GetPPTY(), pViewData->GetZoomY(),
+ pDoc, pViewData, bLayoutRTL );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void lcl_DrawHighlight( ScOutputData& rOutputData, ScViewData* pViewData,
+ ScHighlightRanges& rHighlightRanges )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ULONG nCount = rHighlightRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScHighlightEntry* pEntry = rHighlightRanges.GetObject( i );
+ if (pEntry)
+ {
+ ScRange aRange = pEntry->aRef;
+ if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
+ {
+ rOutputData.DrawRefMark(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ pEntry->aColor, FALSE );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScGridWindow::DoInvertRect( const Rectangle& rPixel )
+{
+// Invert( PixelToLogic(rPixel) );
+
+ if ( rPixel == aInvertRect )
+ aInvertRect = Rectangle(); // aufheben
+ else
+ {
+ DBG_ASSERT( aInvertRect.IsEmpty(), "DoInvertRect nicht paarig" );
+
+ aInvertRect = rPixel; // neues Rechteck merken
+ }
+
+ UpdateHeaderOverlay(); // uses aInvertRect
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScGridWindow::PrePaint()
+{
+ // forward PrePaint to DrawingLayer
+ ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
+
+ if(pTabViewShell)
+ {
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+
+ if(pDrawView)
+ {
+ pDrawView->PrePaint();
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScGridWindow::Paint( const Rectangle& rRect )
+{
+ //TODO/LATER: how to get environment? Do we need that?!
+ /*
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv();
+ if (pEnv && pEnv->GetRectsChangedLockCount())
+ {
+ Invalidate(rRect);
+ return;
+ }*/
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ if ( pDoc->IsInInterpreter() )
+ {
+ // via Reschedule, interpretierende Zellen nicht nochmal anstossen
+ // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
+ // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
+
+ if ( bNeedsRepaint )
+ {
+ //! Rechtecke zusammenfassen?
+ aRepaintPixel = Rectangle(); // mehrfach -> alles painten
+ }
+ else
+ {
+ bNeedsRepaint = TRUE;
+ aRepaintPixel = LogicToPixel(rRect); // nur betroffenen Bereich
+ }
+ return;
+ }
+
+ if (bIsInPaint)
+ return;
+
+ bIsInPaint = TRUE;
+
+ Rectangle aPixRect = LogicToPixel( rRect );
+
+ SCCOL nX1 = pViewData->GetPosX(eHWhich);
+ SCROW nY1 = pViewData->GetPosY(eVWhich);
+
+ SCTAB nTab = pViewData->GetTabNo();
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ Rectangle aMirroredPixel = aPixRect;
+ if ( pDoc->IsLayoutRTL( nTab ) )
+ {
+ // mirror and swap
+ long nWidth = GetSizePixel().Width();
+ aMirroredPixel.Left() = nWidth - 1 - aPixRect.Right();
+ aMirroredPixel.Right() = nWidth - 1 - aPixRect.Left();
+ }
+
+ long nScrX = ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
+ while ( nScrX <= aMirroredPixel.Left() && nX1 < MAXCOL )
+ {
+ ++nX1;
+ nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
+ }
+ SCCOL nX2 = nX1;
+ while ( nScrX <= aMirroredPixel.Right() && nX2 < MAXCOL )
+ {
+ ++nX2;
+ nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX );
+ }
+
+ long nScrY = 0;
+ ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab);
+ SCROW nY2 = nY1;
+ if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW)
+ {
+ ++nY2;
+ ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab);
+ }
+
+ Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS ); // nicht weiterzeichnen
+
+ bIsInPaint = FALSE;
+}
+
+//
+// Draw ----------------------------------------------------------------
+//
+
+void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode )
+{
+ ScModule* pScMod = SC_MOD();
+ BOOL bTextWysiwyg = pScMod->GetInputOptions().GetTextWysiwyg();
+ BOOL bGridFirst = TRUE; //! entscheiden!!!
+
+ if (pViewData->IsMinimized())
+ return;
+
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ DBG_ASSERT( ValidCol(nX2) && ValidRow(nY2), "GridWin Draw Bereich zu gross" );
+
+ SCCOL nPosX = pViewData->GetPosX( eHWhich );
+ SCROW nPosY = pViewData->GetPosY( eVWhich );
+ if (nX2 < nPosX || nY2 < nPosY)
+ return; // unsichtbar
+ if (nX1 < nPosX) nX1 = nPosX;
+ if (nY1 < nPosY) nY1 = nPosY;
+
+ SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
+ if (nXRight > MAXCOL) nXRight = MAXCOL;
+ SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
+ if (nYBottom > MAXROW) nYBottom = MAXROW;
+
+ // Store the current visible range.
+ maVisibleRange.mnCol1 = nPosX;
+ maVisibleRange.mnCol2 = nXRight;
+ maVisibleRange.mnRow1 = nPosY;
+ maVisibleRange.mnRow2 = nYBottom;
+
+ if (nX1 > nXRight || nY1 > nYBottom)
+ return; // unsichtbar
+ if (nX2 > nXRight) nX2 = nXRight;
+ if (nY2 > nYBottom) nY2 = nYBottom;
+
+ if ( eMode != SC_UPDATE_MARKS )
+ if (nX2 < nXRight)
+ nX2 = nXRight; // zum Weiterzeichnen
+
+ // ab hier kein return mehr
+
+ ++nPaintCount; // merken, dass gemalt wird (wichtig beim Invertieren)
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nMirrorWidth = GetSizePixel().Width();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ if ( bLayoutRTL )
+ {
+ long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
+ nMirrorWidth = aScrPos.X() - nEndPixel;
+ aScrPos.X() = nEndPixel + 1;
+ }
+
+ long nScrX = aScrPos.X();
+ long nScrY = aScrPos.Y();
+
+ SCCOL nCurX = pViewData->GetCurX();
+ SCROW nCurY = pViewData->GetCurY();
+ SCCOL nCurEndX = nCurX;
+ SCROW nCurEndY = nCurY;
+ pDoc->ExtendMerge( nCurX, nCurY, nCurEndX, nCurEndY, nTab );
+ BOOL bCurVis = nCursorHideCount==0 &&
+ ( nCurEndX+1 >= nX1 && nCurX <= nX2+1 && nCurEndY+1 >= nY1 && nCurY <= nY2+1 );
+
+ // AutoFill-Anfasser
+ if ( !bCurVis && nCursorHideCount==0 && bAutoMarkVisible && aAutoMarkPos.Tab() == nTab &&
+ ( aAutoMarkPos.Col() != nCurX || aAutoMarkPos.Row() != nCurY ) )
+ {
+ SCCOL nHdlX = aAutoMarkPos.Col();
+ SCROW nHdlY = aAutoMarkPos.Row();
+ pDoc->ExtendMerge( nHdlX, nHdlY, nHdlX, nHdlY, nTab );
+ bCurVis = ( nHdlX+1 >= nX1 && nHdlX <= nX2 && nHdlY+1 >= nY1 && nHdlY <= nY2 );
+ // links und oben ist nicht betroffen
+
+ //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
+ }
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ BOOL bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
+ BOOL bMarkClipped = rOpts.GetOption( VOPT_CLIPMARKS );
+
+ // Datenblock
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
+ nPPTX, nPPTY, FALSE, bFormulaMode,
+ &pViewData->GetMarkData() );
+
+ //--------------------------------------------------------------------
+
+ Fraction aZoomX = pViewData->GetZoomX();
+ Fraction aZoomY = pViewData->GetZoomY();
+ ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
+ &aZoomX, &aZoomY );
+
+ aOutputData.SetMirrorWidth( nMirrorWidth ); // needed for RTL
+
+ std::auto_ptr< VirtualDevice > xFmtVirtDev;
+ BOOL bLogicText = bTextWysiwyg; // call DrawStrings in logic MapMode?
+
+ if ( bTextWysiwyg )
+ {
+ // use printer for text formatting
+
+ OutputDevice* pFmtDev = pDoc->GetPrinter();
+ pFmtDev->SetMapMode( pViewData->GetLogicMode(eWhich) );
+ aOutputData.SetFmtDevice( pFmtDev );
+ }
+ else if ( aZoomX != aZoomY && pViewData->IsOle() )
+ {
+ // #i45033# For OLE inplace editing with different zoom factors,
+ // use a virtual device with 1/100th mm as text formatting reference
+
+ xFmtVirtDev.reset( new VirtualDevice );
+ xFmtVirtDev->SetMapMode( MAP_100TH_MM );
+ aOutputData.SetFmtDevice( xFmtVirtDev.get() );
+
+ bLogicText = TRUE; // use logic MapMode
+ }
+
+ const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
+ Color aGridColor( rColorCfg.GetColorValue( svtools::CALCGRID, FALSE ).nColor );
+ if ( aGridColor.GetColor() == COL_TRANSPARENT )
+ {
+ // use view options' grid color only if color config has "automatic" color
+ aGridColor = rOpts.GetGridColor();
+ }
+
+ aOutputData.SetSyntaxMode ( pViewData->IsSyntaxMode() );
+ aOutputData.SetGridColor ( aGridColor );
+ aOutputData.SetShowNullValues ( rOpts.GetOption( VOPT_NULLVALS ) );
+ aOutputData.SetShowFormulas ( bFormulaMode );
+ aOutputData.SetShowSpellErrors ( pDoc->GetDocOptions().IsAutoSpell() );
+ aOutputData.SetMarkClipped ( bMarkClipped );
+
+ aOutputData.SetUseStyleColor( TRUE ); // always set in table view
+
+ aOutputData.SetEditObject( GetEditObject() );
+ aOutputData.SetViewShell( pViewData->GetViewShell() );
+
+ BOOL bGrid = rOpts.GetOption( VOPT_GRID );
+ BOOL bPage = rOpts.GetOption( VOPT_PAGEBREAKS );
+
+ if ( eMode == SC_UPDATE_CHANGED )
+ {
+ aOutputData.FindChanged();
+ aOutputData.SetSingleGrid(TRUE);
+ }
+
+ BOOL bPageMode = pViewData->IsPagebreakMode();
+ if (bPageMode) // nach FindChanged
+ {
+ // SetPagebreakMode initialisiert auch bPrinted Flags
+ aOutputData.SetPagebreakMode( pViewData->GetView()->GetPageBreakData() );
+ }
+
+ EditView* pEditView = NULL;
+ BOOL bEditMode = pViewData->HasEditView(eWhich);
+ if ( bEditMode && pViewData->GetRefTabNo() == nTab )
+ {
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ SCCOL nEditEndCol = pViewData->GetEditEndCol();
+ SCROW nEditEndRow = pViewData->GetEditEndRow();
+
+ if ( nEditEndCol >= nX1 && nEditCol <= nX2 && nEditEndRow >= nY1 && nEditRow <= nY2 )
+ aOutputData.SetEditCell( nEditCol, nEditRow );
+ else
+ bEditMode = FALSE;
+
+ // nur Edit-Area zu zeichnen?
+ //! dann muss trotzdem noch der Rand / das Gitter gemalt werden!
+
+// if ( nEditCol <= nX1 && nEditEndCol >= nX2 && nEditRow <= nY1 && nEditEndRow >= nY2 )
+// bOnlyEdit = TRUE;
+ }
+
+ // define drawing layer map mode and paint rectangle
+ const MapMode aDrawMode = GetDrawMapMode();
+ Rectangle aDrawingRectLogic;
+
+ {
+ // get drawing pixel rect
+ Rectangle aDrawingRectPixel(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
+
+ // correct for border (left/right)
+ if(MAXCOL == nX2)
+ {
+ if(bLayoutRTL)
+ {
+ aDrawingRectPixel.Left() = 0L;
+ }
+ else
+ {
+ aDrawingRectPixel.Right() = GetOutputSizePixel().getWidth();
+ }
+ }
+
+ // correct for border (bottom)
+ if(MAXROW == nY2)
+ {
+ aDrawingRectPixel.Bottom() = GetOutputSizePixel().getHeight();
+ }
+
+ // get logic positions
+ aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode);
+ }
+
+// not necessary with overlay
+// if (bCurVis)
+// HideCursor();
+
+ OutputDevice* pContentDev = this; // device for document content, used by overlay manager
+ SdrPaintWindow* pTargetPaintWindow = 0; // #i74769# work with SdrPaintWindow directly
+
+ {
+ // init redraw
+ ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
+
+ if(pTabViewShell)
+ {
+ MapMode aCurrentMapMode(pContentDev->GetMapMode());
+ pContentDev->SetMapMode(aDrawMode);
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+
+ if(pDrawView)
+ {
+ // #i74769# Use new BeginDrawLayers() interface
+ Region aDrawingRegion(aDrawingRectLogic);
+ pTargetPaintWindow = pDrawView->BeginDrawLayers(this, aDrawingRegion);
+ OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
+
+ // #i74769# get target device from SdrPaintWindow, this may be the prerender
+ // device now, too.
+ pContentDev = &(pTargetPaintWindow->GetTargetOutputDevice());
+ aOutputData.SetContentDevice( pContentDev );
+ }
+
+ pContentDev->SetMapMode(aCurrentMapMode);
+ }
+ }
+
+ // Rand (Wiese) (Pixel)
+ if ( nX2==MAXCOL || nY2==MAXROW )
+ {
+ // save MapMode and set to pixel
+ MapMode aCurrentMapMode(pContentDev->GetMapMode());
+ pContentDev->SetMapMode(MAP_PIXEL);
+
+ Rectangle aPixRect = Rectangle( Point(), GetOutputSizePixel() );
+ pContentDev->SetFillColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
+ pContentDev->SetLineColor();
+ if ( nX2==MAXCOL )
+ {
+ Rectangle aDrawRect( aPixRect );
+ if ( bLayoutRTL )
+ aDrawRect.Right() = nScrX - 1;
+ else
+ aDrawRect.Left() = nScrX + aOutputData.GetScrW();
+ if (aDrawRect.Right() >= aDrawRect.Left())
+ pContentDev->DrawRect( aDrawRect );
+ }
+ if ( nY2==MAXROW )
+ {
+ Rectangle aDrawRect( aPixRect );
+ aDrawRect.Top() = nScrY + aOutputData.GetScrH();
+ if ( nX2==MAXCOL )
+ {
+ // no double painting of the corner
+ if ( bLayoutRTL )
+ aDrawRect.Left() = nScrX;
+ else
+ aDrawRect.Right() = nScrX + aOutputData.GetScrW() - 1;
+ }
+ if (aDrawRect.Bottom() >= aDrawRect.Top())
+ pContentDev->DrawRect( aDrawRect );
+ }
+
+ // restore MapMode
+ pContentDev->SetMapMode(aCurrentMapMode);
+ }
+
+ if ( pDoc->HasBackgroundDraw( nTab, aDrawingRectLogic ) )
+ {
+ pContentDev->SetMapMode(MAP_PIXEL);
+ aOutputData.DrawClear();
+
+ // Drawing Hintergrund
+
+ pContentDev->SetMapMode(aDrawMode);
+ DrawRedraw( aOutputData, eMode, SC_LAYER_BACK );
+ }
+ else
+ aOutputData.SetSolidBackground(TRUE);
+
+ pContentDev->SetMapMode(MAP_PIXEL);
+ aOutputData.DrawBackground();
+ if ( bGridFirst && ( bGrid || bPage ) )
+ aOutputData.DrawGrid( bGrid, bPage );
+ if ( bPageMode )
+ {
+ // #87655# DrawPagePreview draws complete lines/page numbers, must always be clipped
+ if ( aOutputData.SetChangedClip() )
+ {
+ DrawPagePreview(nX1,nY1,nX2,nY2, pContentDev);
+ pContentDev->SetClipRegion();
+ }
+ }
+ aOutputData.DrawShadow();
+ aOutputData.DrawFrame();
+ if ( !bLogicText )
+ aOutputData.DrawStrings(FALSE); // in pixel MapMode
+
+ // edit cells and printer-metrics text must be before the buttons
+ // (DataPilot buttons contain labels in UI font)
+
+ pContentDev->SetMapMode(pViewData->GetLogicMode(eWhich));
+ if ( bLogicText )
+ aOutputData.DrawStrings(TRUE); // in logic MapMode if bTextWysiwyg is set
+ aOutputData.DrawEdit(TRUE);
+ pContentDev->SetMapMode(MAP_PIXEL);
+
+ // Autofilter- und Pivot-Buttons
+
+ DrawButtons( nX1, nY1, nX2, nY2, aTabInfo, pContentDev ); // Pixel
+
+ // Notiz-Anzeiger
+
+ if ( rOpts.GetOption( VOPT_NOTES ) )
+ aOutputData.DrawNoteMarks();
+
+ if ( !bGridFirst && ( bGrid || bPage ) )
+ {
+ aOutputData.DrawGrid( bGrid, bPage );
+ }
+ aOutputData.DrawClipMarks();
+
+ // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
+
+ //! Test, ob ChangeTrack-Anzeige aktiv ist
+ //! Szenario-Rahmen per View-Optionen abschaltbar?
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScHighlightRanges* pHigh = pViewData->GetView()->GetHighlightRanges();
+ BOOL bHasScenario = ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) );
+ BOOL bHasChange = ( pDoc->GetChangeTrack() != NULL );
+
+ if ( bHasChange || bHasScenario || pHigh != NULL )
+ {
+
+ //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
+
+ BOOL bAny = TRUE;
+ if (eMode == SC_UPDATE_CHANGED)
+ bAny = aOutputData.SetChangedClip();
+ if (bAny)
+ {
+ if ( bHasChange )
+ aOutputData.DrawChangeTrack();
+
+ if ( bHasScenario )
+ lcl_DrawScenarioFrames( pContentDev, pViewData, eWhich, nX1,nY1,nX2,nY2 );
+
+ if ( pHigh )
+ lcl_DrawHighlight( aOutputData, pViewData, *pHigh );
+
+ if (eMode == SC_UPDATE_CHANGED)
+ pContentDev->SetClipRegion();
+ }
+ }
+
+ // Drawing Vordergrund
+
+ pContentDev->SetMapMode(aDrawMode);
+
+ DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT );
+ DrawRedraw( aOutputData, eMode, SC_LAYER_INTERN );
+ DrawSdrGrid( aDrawingRectLogic, pContentDev );
+
+ if (!bIsInScroll) // Drawing Markierungen
+ {
+ if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip())
+ {
+ pContentDev->SetClipRegion();
+ }
+
+ //BOOL bDraw = TRUE;
+ //if (eMode == SC_UPDATE_CHANGED)
+ // bDraw = NeedDrawMarks() && aOutputData.SetChangedClip();
+ //if (bDraw)
+ //{
+ // DrawMarks();
+ // if (eMode == SC_UPDATE_CHANGED)
+ // pContentDev->SetClipRegion();
+ //}
+ }
+
+ pContentDev->SetMapMode(MAP_PIXEL);
+
+#ifdef OLD_SELECTION_PAINT
+ if (pViewData->IsActive())
+ aOutputData.DrawMark( this );
+#endif
+
+ if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() )
+ {
+ // The AutoFill shrink area has an own overlay now
+#if 0
+ // Schraffur beim Loeschen per AutoFill
+ if ( pViewData->GetRefType() == SC_REFTYPE_FILL )
+ {
+ ScRange aRange;
+ if ( pViewData->GetDelMark( aRange ) )
+ {
+ if ( aRange.aStart.Col() < nX1 ) aRange.aStart.SetCol(nX1);
+ if ( aRange.aEnd.Col() > nX2 ) aRange.aEnd.SetCol(nX2);
+ if ( aRange.aStart.Row() < nY1 ) aRange.aStart.SetRow(nY1);
+ if ( aRange.aEnd.Row() > nY2 ) aRange.aEnd.SetRow(nY2);
+ if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
+ aRange.aStart.Row() <= aRange.aEnd.Row() )
+ {
+ Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
+ aRange.aStart.Row(), eWhich );
+ Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
+ aRange.aEnd.Row()+1, eWhich );
+ aEnd.X() -= 1;
+ aEnd.Y() -= 1;
+
+ // Markierung aufheben - roter Rahmen bleibt stehen
+ Rectangle aRect( aStart,aEnd );
+ Invert( aRect, INVERT_HIGHLIGHT );
+
+ //! Delete-Bereich extra kennzeichnen?!?!?
+ }
+ }
+ }
+#endif
+
+ Color aRefColor( rColorCfg.GetColorValue(svtools::CALCREFERENCE).nColor );
+ aOutputData.DrawRefMark( pViewData->GetRefStartX(), pViewData->GetRefStartY(),
+ pViewData->GetRefEndX(), pViewData->GetRefEndY(),
+ aRefColor, FALSE );
+ }
+
+ // Range-Finder
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if (pHdl)
+ {
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if ( pRangeFinder && !pRangeFinder->IsHidden() &&
+ pRangeFinder->GetDocName() == pDocSh->GetTitle() )
+ {
+ USHORT nCount = (USHORT)pRangeFinder->Count();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScRangeFindData* pData = pRangeFinder->GetObject(i);
+ if (pData)
+ {
+ ScRange aRef = pData->aRef;
+ aRef.Justify();
+ if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
+ aOutputData.DrawRefMark( aRef.aStart.Col(), aRef.aStart.Row(),
+ aRef.aEnd.Col(), aRef.aEnd.Row(),
+ Color( ScRangeFindList::GetColorName( i ) ),
+ TRUE );
+ }
+ }
+ }
+ }
+
+ {
+ // end redraw
+ ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
+
+ if(pTabViewShell)
+ {
+ MapMode aCurrentMapMode(pContentDev->GetMapMode());
+ pContentDev->SetMapMode(aDrawMode);
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+
+ if(pDrawView)
+ {
+ // #i74769# work with SdrPaintWindow directly
+ pDrawView->EndDrawLayers(*pTargetPaintWindow, true);
+ }
+
+ pContentDev->SetMapMode(aCurrentMapMode);
+ }
+ }
+
+ // InPlace Edit-View
+ // moved after EndDrawLayers() to get it outside the overlay buffer and
+ // on top of everything
+ if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
+ {
+ //! use pContentDev for EditView?
+ SetMapMode(MAP_PIXEL);
+ SCCOL nCol1 = pViewData->GetEditStartCol();
+ SCROW nRow1 = pViewData->GetEditStartRow();
+ SCCOL nCol2 = pViewData->GetEditEndCol();
+ SCROW nRow2 = pViewData->GetEditEndRow();
+ SetLineColor();
+ SetFillColor( pEditView->GetBackgroundColor() );
+ Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich );
+ Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich );
+ aEnd.X() -= 2 * nLayoutSign; // don't overwrite grid
+ aEnd.Y() -= 2;
+ DrawRect( Rectangle( aStart,aEnd ) );
+
+ SetMapMode(pViewData->GetLogicMode());
+ pEditView->Paint( PixelToLogic( Rectangle( Point( nScrX, nScrY ),
+ Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ) );
+ SetMapMode(MAP_PIXEL);
+ }
+
+ if (pViewData->HasEditView(eWhich))
+ {
+ // flush OverlayManager before changing the MapMode
+ flushOverlayManager();
+
+ // set MapMode for text edit
+ SetMapMode(pViewData->GetLogicMode());
+ }
+ else
+ SetMapMode(aDrawMode);
+
+ if ( pNoteMarker )
+ pNoteMarker->Draw(); // ueber den Cursor, im Drawing-MapMode
+
+ //DrawStartTimer(); // fuer bunte Handles ohne System-Clipping
+
+ //
+ // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
+ // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
+ //
+
+ DBG_ASSERT(nPaintCount, "nPaintCount falsch");
+ --nPaintCount;
+ if (!nPaintCount)
+ CheckNeedsRepaint();
+}
+
+void ScGridWindow::CheckNeedsRepaint()
+{
+ // called at the end of painting, and from timer after background text width calculation
+
+ if (bNeedsRepaint)
+ {
+ bNeedsRepaint = FALSE;
+ if (aRepaintPixel.IsEmpty())
+ Invalidate();
+ else
+ Invalidate(PixelToLogic(aRepaintPixel));
+ aRepaintPixel = Rectangle();
+
+ // selection function in status bar might also be invalid
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_STATUS_SUM );
+ rBindings.Invalidate( SID_ATTR_SIZE );
+ rBindings.Invalidate( SID_TABLE_CELL );
+ }
+}
+
+void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, OutputDevice* pContentDev )
+{
+ ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
+ if (pPageData)
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ Size aWinSize = GetOutputSizePixel();
+ const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
+ Color aManual( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
+ Color aAutomatic( rColorCfg.GetColorValue(svtools::CALCPAGEBREAK).nColor );
+
+ String aPageText = ScGlobal::GetRscString( STR_PAGE );
+ if ( nPageScript == 0 )
+ {
+ // get script type of translated "Page" string only once
+ nPageScript = pDoc->GetStringScriptType( aPageText );
+ if (nPageScript == 0)
+ nPageScript = ScGlobal::GetDefaultScriptType();
+ }
+ aPageText += ' ';
+
+ Font aFont;
+ ScEditEngineDefaulter* pEditEng = NULL;
+ const ScPatternAttr& rDefPattern = ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
+ if ( nPageScript == SCRIPTTYPE_LATIN )
+ {
+ // use single font and call DrawText directly
+ rDefPattern.GetFont( aFont, SC_AUTOCOL_BLACK );
+ aFont.SetColor( Color( COL_LIGHTGRAY ) );
+ // font size is set as needed
+ }
+ else
+ {
+ // use EditEngine to draw mixed-script string
+ pEditEng = new ScEditEngineDefaulter( EditEngine::CreatePool(), TRUE );
+ pEditEng->SetRefMapMode( pContentDev->GetMapMode() );
+ SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
+ rDefPattern.FillEditItemSet( pEditDefaults );
+ pEditDefaults->Put( SvxColorItem( Color( COL_LIGHTGRAY ), EE_CHAR_COLOR ) );
+ pEditEng->SetDefaults( pEditDefaults );
+ }
+
+ USHORT nCount = sal::static_int_cast<USHORT>( pPageData->GetCount() );
+ for (USHORT nPos=0; nPos<nCount; nPos++)
+ {
+ ScPrintRangeData& rData = pPageData->GetData(nPos);
+ ScRange aRange = rData.GetPrintRange();
+ if ( aRange.aStart.Col() <= nX2+1 && aRange.aEnd.Col()+1 >= nX1 &&
+ aRange.aStart.Row() <= nY2+1 && aRange.aEnd.Row()+1 >= nY1 )
+ {
+ // 3 Pixel Rahmen um den Druckbereich
+ // (mittlerer Pixel auf den Gitterlinien)
+
+ pContentDev->SetLineColor();
+ if (rData.IsAutomatic())
+ pContentDev->SetFillColor( aAutomatic );
+ else
+ pContentDev->SetFillColor( aManual );
+
+ Point aStart = pViewData->GetScrPos(
+ aRange.aStart.Col(), aRange.aStart.Row(), eWhich, TRUE );
+ Point aEnd = pViewData->GetScrPos(
+ aRange.aEnd.Col() + 1, aRange.aEnd.Row() + 1, eWhich, TRUE );
+ aStart.X() -= 2;
+ aStart.Y() -= 2;
+
+ // Ueberlaeufe verhindern:
+ if ( aStart.X() < -10 ) aStart.X() = -10;
+ if ( aStart.Y() < -10 ) aStart.Y() = -10;
+ if ( aEnd.X() > aWinSize.Width() + 10 )
+ aEnd.X() = aWinSize.Width() + 10;
+ if ( aEnd.Y() > aWinSize.Height() + 10 )
+ aEnd.Y() = aWinSize.Height() + 10;
+
+ pContentDev->DrawRect( Rectangle( aStart, Point(aEnd.X(),aStart.Y()+2) ) );
+ pContentDev->DrawRect( Rectangle( aStart, Point(aStart.X()+2,aEnd.Y()) ) );
+ pContentDev->DrawRect( Rectangle( Point(aStart.X(),aEnd.Y()-2), aEnd ) );
+ pContentDev->DrawRect( Rectangle( Point(aEnd.X()-2,aStart.Y()), aEnd ) );
+
+ // Seitenumbrueche
+ //! anders darstellen (gestrichelt ????)
+
+ size_t nColBreaks = rData.GetPagesX();
+ const SCCOL* pColEnd = rData.GetPageEndX();
+ size_t nColPos;
+ for (nColPos=0; nColPos+1<nColBreaks; nColPos++)
+ {
+ SCCOL nBreak = pColEnd[nColPos]+1;
+ if ( nBreak >= nX1 && nBreak <= nX2+1 )
+ {
+ //! hidden suchen
+ if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL)
+ pContentDev->SetFillColor( aManual );
+ else
+ pContentDev->SetFillColor( aAutomatic );
+ Point aBreak = pViewData->GetScrPos(
+ nBreak, aRange.aStart.Row(), eWhich, TRUE );
+ pContentDev->DrawRect( Rectangle( aBreak.X()-1, aStart.Y(), aBreak.X(), aEnd.Y() ) );
+ }
+ }
+
+ size_t nRowBreaks = rData.GetPagesY();
+ const SCROW* pRowEnd = rData.GetPageEndY();
+ size_t nRowPos;
+ for (nRowPos=0; nRowPos+1<nRowBreaks; nRowPos++)
+ {
+ SCROW nBreak = pRowEnd[nRowPos]+1;
+ if ( nBreak >= nY1 && nBreak <= nY2+1 )
+ {
+ //! hidden suchen
+ if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL)
+ pContentDev->SetFillColor( aManual );
+ else
+ pContentDev->SetFillColor( aAutomatic );
+ Point aBreak = pViewData->GetScrPos(
+ aRange.aStart.Col(), nBreak, eWhich, TRUE );
+ pContentDev->DrawRect( Rectangle( aStart.X(), aBreak.Y()-1, aEnd.X(), aBreak.Y() ) );
+ }
+ }
+
+ // Seitenzahlen
+
+ SCROW nPrStartY = aRange.aStart.Row();
+ for (nRowPos=0; nRowPos<nRowBreaks; nRowPos++)
+ {
+ SCROW nPrEndY = pRowEnd[nRowPos];
+ if ( nPrEndY >= nY1 && nPrStartY <= nY2 )
+ {
+ SCCOL nPrStartX = aRange.aStart.Col();
+ for (nColPos=0; nColPos<nColBreaks; nColPos++)
+ {
+ SCCOL nPrEndX = pColEnd[nColPos];
+ if ( nPrEndX >= nX1 && nPrStartX <= nX2 )
+ {
+ Point aPageStart = pViewData->GetScrPos(
+ nPrStartX, nPrStartY, eWhich, TRUE );
+ Point aPageEnd = pViewData->GetScrPos(
+ nPrEndX+1,nPrEndY+1, eWhich, TRUE );
+
+ long nPageNo = rData.GetFirstPage();
+ if ( rData.IsTopDown() )
+ nPageNo += ((long)nColPos)*nRowBreaks+nRowPos;
+ else
+ nPageNo += ((long)nRowPos)*nColBreaks+nColPos;
+ String aPageStr = aPageText;
+ aPageStr += String::CreateFromInt32(nPageNo);
+
+ if ( pEditEng )
+ {
+ // find right font size with EditEngine
+ long nHeight = 100;
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+ pEditEng->SetText( aPageStr );
+ Size aSize100( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
+
+ // 40% of width or 60% of height
+ long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
+ long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
+ nHeight = Min(nSizeX,nSizeY);
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+
+ // centered output with EditEngine
+ Size aTextSize( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
+ Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
+ (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
+ pEditEng->Draw( pContentDev, aPos );
+ }
+ else
+ {
+ // find right font size for DrawText
+ aFont.SetSize( Size( 0,100 ) );
+ pContentDev->SetFont( aFont );
+ Size aSize100( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() );
+
+ // 40% of width or 60% of height
+ long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
+ long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
+ aFont.SetSize( Size( 0,Min(nSizeX,nSizeY) ) );
+ pContentDev->SetFont( aFont );
+
+ // centered output with DrawText
+ Size aTextSize( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() );
+ Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
+ (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
+ pContentDev->DrawText( aPos, aPageStr );
+ }
+ }
+ nPrStartX = nPrEndX + 1;
+ }
+ }
+ nPrStartY = nPrEndY + 1;
+ }
+ }
+ }
+
+ delete pEditEng;
+ }
+}
+
+void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2*/, ScTableInfo& rTabInfo, OutputDevice* pContentDev )
+{
+ aComboButton.SetOutputDevice( pContentDev );
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc);
+
+ SCCOL nCol;
+ SCROW nRow;
+ SCSIZE nArrY;
+ SCSIZE nQuery;
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDBData* pDBData = NULL;
+ ScQueryParam* pQueryParam = NULL;
+
+ RowInfo* pRowInfo = rTabInfo.mpRowInfo;
+ USHORT nArrCount = rTabInfo.mnArrCount;
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Point aOldPos = aComboButton.GetPosPixel(); // Zustand fuer MouseDown/Up
+ Size aOldSize = aComboButton.GetSizePixel(); // merken
+
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ if ( pRowInfo[nArrY].bAutoFilter && pRowInfo[nArrY].bChanged )
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ nRow = pThisRowInfo->nRowNo;
+
+
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
+ if ( pInfo->bAutoFilter && !pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ if (!pQueryParam)
+ pQueryParam = new ScQueryParam;
+
+ BOOL bNewData = TRUE;
+ if (pDBData)
+ {
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nAreaTab;
+ pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ if ( nCol >= nStartCol && nCol <= nEndCol &&
+ nRow >= nStartRow && nRow <= nEndRow )
+ bNewData = FALSE;
+ }
+ if (bNewData)
+ {
+ pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ if (pDBData)
+ pDBData->GetQueryParam( *pQueryParam );
+ else
+ {
+ // can also be part of DataPilot table
+ // DBG_ERROR("Auto-Filter-Button ohne DBData");
+ }
+ }
+
+ // pQueryParam kann nur MAXQUERY Eintraege enthalten
+
+ BOOL bSimpleQuery = TRUE;
+ BOOL bColumnFound = FALSE;
+ if (!pQueryParam->bInplace)
+ bSimpleQuery = FALSE;
+ for (nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++)
+ if (pQueryParam->GetEntry(nQuery).bDoQuery)
+ {
+ // hier nicht auf EQUAL beschraenken
+ // (auch bei ">1" soll der Spaltenkopf blau werden)
+
+ if (pQueryParam->GetEntry(nQuery).nField == nCol)
+ bColumnFound = TRUE;
+ if (nQuery > 0)
+ if (pQueryParam->GetEntry(nQuery).eConnect != SC_AND)
+ bSimpleQuery = FALSE;
+ }
+
+ bool bArrowState = bSimpleQuery && bColumnFound;
+ long nSizeX;
+ long nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+
+ aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1), bLayoutRTL);
+ aCellBtn.setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
+ aCellBtn.setDrawBaseButton(false);
+ aCellBtn.setDrawPopupButton(true);
+ aCellBtn.setHasHiddenMember(bArrowState);
+ aCellBtn.draw();
+ }
+ }
+ }
+
+ if ( pRowInfo[nArrY].bPushButton && pRowInfo[nArrY].bChanged )
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ nRow = pThisRowInfo->nRowNo;
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
+ if ( pInfo->bPushButton && !pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ long nSizeX;
+ long nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ long nPosX = aScrPos.X();
+ long nPosY = aScrPos.Y();
+ // bLayoutRTL is handled in setBoundingBox
+
+ String aStr;
+ pDoc->GetString(nCol, nRow, nTab, aStr);
+ aCellBtn.setText(aStr);
+ aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL);
+ aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
+ aCellBtn.setDrawBaseButton(true);
+ aCellBtn.setDrawPopupButton(pInfo->bPopupButton);
+ aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
+ aCellBtn.draw();
+ }
+ }
+ }
+
+ if ( bListValButton && pRowInfo[nArrY].nRowNo == aListValPos.Row() && pRowInfo[nArrY].bChanged )
+ {
+ Rectangle aRect = GetListValButtonRect( aListValPos );
+ aComboButton.SetPosPixel( aRect.TopLeft() );
+ aComboButton.SetSizePixel( aRect.GetSize() );
+ pContentDev->SetClipRegion( aRect );
+ aComboButton.Draw( FALSE, FALSE );
+ pContentDev->SetClipRegion(); // always called from Draw() without clip region
+ aComboButton.SetPosPixel( aOldPos ); // restore old state
+ aComboButton.SetSizePixel( aOldSize ); // for MouseUp/Down (AutoFilter)
+ }
+ }
+
+ delete pQueryParam;
+ aComboButton.SetOutputDevice( this );
+}
+
+Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ ScDDComboBoxButton aButton( this ); // for optimal size
+ Size aBtnSize = aButton.GetSizePixel();
+
+ SCCOL nCol = rButtonPos.Col();
+ SCROW nRow = rButtonPos.Row();
+
+ long nCellSizeX; // width of this cell, including merged
+ long nDummy;
+ pViewData->GetMergeSizePixel( nCol, nRow, nCellSizeX, nDummy );
+
+ // for height, only the cell's row is used, excluding merged cells
+ long nCellSizeY = ScViewData::ToPixel( pDoc->GetRowHeight( nRow, nTab ), pViewData->GetPPTY() );
+ long nAvailable = nCellSizeX;
+
+ // left edge of next cell if there is a non-hidden next column
+ SCCOL nNextCol = nCol + 1;
+ const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(pDoc->GetAttr( nCol,nRow,nTab, ATTR_MERGE ));
+ if ( pMerge->GetColMerge() > 1 )
+ nNextCol = nCol + pMerge->GetColMerge(); // next cell after the merged area
+ while ( nNextCol <= MAXCOL && pDoc->ColHidden(nNextCol, nTab) )
+ ++nNextCol;
+ BOOL bNextCell = ( nNextCol <= MAXCOL );
+ if ( bNextCell )
+ nAvailable = ScViewData::ToPixel( pDoc->GetColWidth( nNextCol, nTab ), pViewData->GetPPTX() );
+
+ if ( nAvailable < aBtnSize.Width() )
+ aBtnSize.Width() = nAvailable;
+ if ( nCellSizeY < aBtnSize.Height() )
+ aBtnSize.Height() = nCellSizeY;
+
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich, TRUE );
+ aPos.X() += nCellSizeX * nLayoutSign; // start of next cell
+ if (!bNextCell)
+ aPos.X() -= aBtnSize.Width() * nLayoutSign; // right edge of cell if next cell not available
+ aPos.Y() += nCellSizeY - aBtnSize.Height();
+ // X remains at the left edge
+
+ if ( bLayoutRTL )
+ aPos.X() -= aBtnSize.Width()-1; // align right edge of button with cell border
+
+ return Rectangle( aPos, aBtnSize );
+}
+
+BOOL ScGridWindow::IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ ScQueryParam aQueryParam;
+
+ if ( pDBData )
+ pDBData->GetQueryParam( aQueryParam );
+ else
+ {
+ DBG_ERROR("Auto-Filter-Button ohne DBData");
+ }
+
+ BOOL bSimpleQuery = TRUE;
+ BOOL bColumnFound = FALSE;
+ SCSIZE nQuery;
+
+ if ( !aQueryParam.bInplace )
+ bSimpleQuery = FALSE;
+
+ // aQueryParam kann nur MAXQUERY Eintraege enthalten
+
+ for ( nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++ )
+ if ( aQueryParam.GetEntry(nQuery).bDoQuery )
+ {
+ if (aQueryParam.GetEntry(nQuery).nField == nCol)
+ bColumnFound = TRUE;
+
+ if (nQuery > 0)
+ if (aQueryParam.GetEntry(nQuery).eConnect != SC_AND)
+ bSimpleQuery = FALSE;
+ }
+
+ return ( bSimpleQuery && bColumnFound );
+}
+
+void ScGridWindow::DrawComboButton( const Point& rCellPos,
+ long nCellSizeX,
+ long nCellSizeY,
+ BOOL bArrowState,
+ BOOL bBtnIn )
+{
+ Point aScrPos = rCellPos;
+ Size aBtnSize = aComboButton.GetSizePixel();
+
+ if ( nCellSizeX < aBtnSize.Width() || nCellSizeY < aBtnSize.Height() )
+ {
+ if ( nCellSizeX < aBtnSize.Width() )
+ aBtnSize.Width() = nCellSizeX;
+
+ if ( nCellSizeY < aBtnSize.Height() )
+ aBtnSize.Height() = nCellSizeY;
+
+ aComboButton.SetSizePixel( aBtnSize );
+ }
+
+ BOOL bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+
+ if ( bLayoutRTL )
+ aScrPos.X() -= nCellSizeX - 1;
+ else
+ aScrPos.X() += nCellSizeX - aBtnSize.Width();
+ aScrPos.Y() += nCellSizeY - aBtnSize.Height();
+
+ aComboButton.SetPosPixel( aScrPos );
+
+ HideCursor();
+ aComboButton.Draw( bArrowState, bBtnIn );
+ ShowCursor();
+}
+
+void ScGridWindow::InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ BOOL bTestMerge, BOOL bRepeat )
+{
+ //! if INVERT_HIGHLIGHT swaps foreground and background (like on Mac),
+ //! use INVERT_HIGHLIGHT only for cells that have no background color set
+ //! (here and in ScOutputData::DrawMark)
+
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ SCCOL nTestX2 = nX2;
+ SCROW nTestY2 = nY2;
+ if (bTestMerge)
+ pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
+
+ SCCOL nPosX = pViewData->GetPosX( eHWhich );
+ SCROW nPosY = pViewData->GetPosY( eVWhich );
+ if (nTestX2 < nPosX || nTestY2 < nPosY)
+ return; // unsichtbar
+ SCCOL nRealX1 = nX1;
+ if (nX1 < nPosX)
+ nX1 = nPosX;
+ if (nY1 < nPosY)
+ nY1 = nPosY;
+
+ SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
+ if (nXRight > MAXCOL) nXRight = MAXCOL;
+ SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
+ if (nYBottom > MAXROW) nYBottom = MAXROW;
+
+ if (nX1 > nXRight || nY1 > nYBottom)
+ return; // unsichtbar
+ if (nX2 > nXRight) nX2 = nXRight;
+ if (nY2 > nYBottom) nY2 = nYBottom;
+
+ MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!!
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ ScInvertMerger aInvert( this );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nScrY = aScrPos.Y();
+ BOOL bWasHidden = FALSE;
+ for (SCROW nY=nY1; nY<=nY2; nY++)
+ {
+ BOOL bFirstRow = ( nY == nPosY ); // first visible row?
+ BOOL bDoHidden = FALSE; // versteckte nachholen ?
+ USHORT nHeightTwips = pDoc->GetRowHeight( nY,nTab );
+ BOOL bDoRow = ( nHeightTwips != 0 );
+ if (bDoRow)
+ {
+ if (bTestMerge)
+ if (bWasHidden) // auf versteckte zusammengefasste testen
+ {
+// --nY; // nY geaendert -> vorherige zeichnen
+ bDoHidden = TRUE;
+ bDoRow = TRUE;
+ }
+
+ bWasHidden = FALSE;
+ }
+ else
+ {
+ bWasHidden = TRUE;
+ if (bTestMerge)
+ if (nY==nY2)
+ bDoRow = TRUE; // letzte Zeile aus Block
+ }
+
+ if ( bDoRow )
+ {
+ SCCOL nLoopEndX = nX2;
+ if (nX2 < nX1) // Rest von zusammengefasst
+ {
+ SCCOL nStartX = nX1;
+ while ( ((const ScMergeFlagAttr*)pDoc->
+ GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
+ --nStartX;
+ if (nStartX <= nX2)
+ nLoopEndX = nX1;
+ }
+
+ long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
+ long nScrX = aScrPos.X();
+ for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
+ {
+ long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
+ if ( nWidth > 0 )
+ {
+ long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
+ if (bTestMerge)
+ {
+ SCROW nThisY = nY;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
+ const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
+ GetItem(ATTR_MERGE_FLAG);
+ if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
+ {
+ while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
+ (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
+ {
+ --nThisY;
+ pPattern = pDoc->GetPattern( nX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ // nur Rest von zusammengefasster zu sehen ?
+ SCCOL nThisX = nX;
+ if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
+ {
+ while ( pMergeFlag->IsHorOverlapped() )
+ {
+ --nThisX;
+ pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ if ( rMark.IsCellMarked( nThisX, nThisY, TRUE ) == bRepeat )
+ {
+ if ( !pMergeFlag->IsOverlapped() )
+ {
+ ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
+ {
+ Point aEndPos = pViewData->GetScrPos(
+ nThisX + pMerge->GetColMerge(),
+ nThisY + pMerge->GetRowMerge(), eWhich );
+ if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,
+ aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
+ }
+ }
+ else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+ }
+ }
+ else // !bTestMerge
+ {
+ if ( rMark.IsCellMarked( nX, nY, TRUE ) == bRepeat &&
+ nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+
+ nScrX = nEndX + nLayoutSign;
+ }
+ }
+ nScrY = nEndY + 1;
+ }
+ }
+
+ aInvert.Flush(); // before restoring MapMode
+
+ SetMapMode(aOld);
+
+ CheckInverted();
+}
+
+void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects )
+{
+ // transformed from ScGridWindow::InvertSimple
+
+// ScMarkData& rMark = pViewData->GetMarkData();
+ ScMarkData aMultiMark( pViewData->GetMarkData() );
+ aMultiMark.SetMarking( FALSE );
+ aMultiMark.MarkToMulti();
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ if ( !aMultiMark.IsMultiMarked() )
+ return;
+
+ ScRange aMultiRange;
+ aMultiMark.GetMultiMarkArea( aMultiRange );
+ SCCOL nX1 = aMultiRange.aStart.Col();
+ SCROW nY1 = aMultiRange.aStart.Row();
+ SCCOL nX2 = aMultiRange.aEnd.Col();
+ SCROW nY2 = aMultiRange.aEnd.Row();
+
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ BOOL bTestMerge = TRUE;
+ BOOL bRepeat = TRUE;
+
+ SCCOL nTestX2 = nX2;
+ SCROW nTestY2 = nY2;
+ if (bTestMerge)
+ pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
+
+ SCCOL nPosX = pViewData->GetPosX( eHWhich );
+ SCROW nPosY = pViewData->GetPosY( eVWhich );
+ if (nTestX2 < nPosX || nTestY2 < nPosY)
+ return; // unsichtbar
+ SCCOL nRealX1 = nX1;
+ if (nX1 < nPosX)
+ nX1 = nPosX;
+ if (nY1 < nPosY)
+ nY1 = nPosY;
+
+ SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
+ if (nXRight > MAXCOL) nXRight = MAXCOL;
+ SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
+ if (nYBottom > MAXROW) nYBottom = MAXROW;
+
+ if (nX1 > nXRight || nY1 > nYBottom)
+ return; // unsichtbar
+ if (nX2 > nXRight) nX2 = nXRight;
+ if (nY2 > nYBottom) nY2 = nYBottom;
+
+// MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!!
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ ScInvertMerger aInvert( &rPixelRects );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nScrY = aScrPos.Y();
+ BOOL bWasHidden = FALSE;
+ for (SCROW nY=nY1; nY<=nY2; nY++)
+ {
+ BOOL bFirstRow = ( nY == nPosY ); // first visible row?
+ BOOL bDoHidden = FALSE; // versteckte nachholen ?
+ USHORT nHeightTwips = pDoc->GetRowHeight( nY,nTab );
+ BOOL bDoRow = ( nHeightTwips != 0 );
+ if (bDoRow)
+ {
+ if (bTestMerge)
+ if (bWasHidden) // auf versteckte zusammengefasste testen
+ {
+ bDoHidden = TRUE;
+ bDoRow = TRUE;
+ }
+
+ bWasHidden = FALSE;
+ }
+ else
+ {
+ bWasHidden = TRUE;
+ if (bTestMerge)
+ if (nY==nY2)
+ bDoRow = TRUE; // letzte Zeile aus Block
+ }
+
+ if ( bDoRow )
+ {
+ SCCOL nLoopEndX = nX2;
+ if (nX2 < nX1) // Rest von zusammengefasst
+ {
+ SCCOL nStartX = nX1;
+ while ( ((const ScMergeFlagAttr*)pDoc->
+ GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
+ --nStartX;
+ if (nStartX <= nX2)
+ nLoopEndX = nX1;
+ }
+
+ long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
+ long nScrX = aScrPos.X();
+ for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
+ {
+ long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
+ if ( nWidth > 0 )
+ {
+ long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
+ if (bTestMerge)
+ {
+ SCROW nThisY = nY;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
+ const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
+ GetItem(ATTR_MERGE_FLAG);
+ if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
+ {
+ while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
+ (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
+ {
+ --nThisY;
+ pPattern = pDoc->GetPattern( nX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ // nur Rest von zusammengefasster zu sehen ?
+ SCCOL nThisX = nX;
+ if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
+ {
+ while ( pMergeFlag->IsHorOverlapped() )
+ {
+ --nThisX;
+ pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ if ( aMultiMark.IsCellMarked( nThisX, nThisY, TRUE ) == bRepeat )
+ {
+ if ( !pMergeFlag->IsOverlapped() )
+ {
+ ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
+ {
+ Point aEndPos = pViewData->GetScrPos(
+ nThisX + pMerge->GetColMerge(),
+ nThisY + pMerge->GetRowMerge(), eWhich );
+ if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,
+ aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
+ }
+ }
+ else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+ }
+ }
+ else // !bTestMerge
+ {
+ if ( aMultiMark.IsCellMarked( nX, nY, TRUE ) == bRepeat &&
+ nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+
+ nScrX = nEndX + nLayoutSign;
+ }
+ }
+ nScrY = nEndY + 1;
+ }
+ }
+
+// aInvert.Flush(); // before restoring MapMode
+}
+
+// -------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScGridWindow::DrawDragRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( nX2 < pViewData->GetPosX(eHWhich) || nY2 < pViewData->GetPosY(eVWhich) )
+//UNUSED2008-05 return;
+//UNUSED2008-05
+//UNUSED2008-05 Update(); // wegen XOR
+//UNUSED2008-05
+//UNUSED2008-05 MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
+//UNUSED2008-05
+//UNUSED2008-05 SCTAB nTab = pViewData->GetTabNo();
+//UNUSED2008-05
+//UNUSED2008-05 SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
+//UNUSED2008-05 SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
+//UNUSED2008-05 if (nX1 < nPosX) nX1 = nPosX;
+//UNUSED2008-05 if (nX2 < nPosX) nX2 = nPosX;
+//UNUSED2008-05 if (nY1 < nPosY) nY1 = nPosY;
+//UNUSED2008-05 if (nY2 < nPosY) nY2 = nPosY;
+//UNUSED2008-05
+//UNUSED2008-05 Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
+//UNUSED2008-05
+//UNUSED2008-05 long nSizeXPix=0;
+//UNUSED2008-05 long nSizeYPix=0;
+//UNUSED2008-05 ScDocument* pDoc = pViewData->GetDocument();
+//UNUSED2008-05 double nPPTX = pViewData->GetPPTX();
+//UNUSED2008-05 double nPPTY = pViewData->GetPPTY();
+//UNUSED2008-05 SCCOLROW i;
+//UNUSED2008-05
+//UNUSED2008-05 BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+//UNUSED2008-05 long nLayoutSign = bLayoutRTL ? -1 : 1;
+//UNUSED2008-05
+//UNUSED2008-05 if (ValidCol(nX2) && nX2>=nX1)
+//UNUSED2008-05 for (i=nX1; i<=nX2; i++)
+//UNUSED2008-05 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 aScrPos.X() -= nLayoutSign;
+//UNUSED2008-05 nSizeXPix += 2;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 if (ValidRow(nY2) && nY2>=nY1)
+//UNUSED2008-05 for (i=nY1; i<=nY2; i++)
+//UNUSED2008-05 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 aScrPos.Y() -= 1;
+//UNUSED2008-05 nSizeYPix += 2;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 aScrPos.X() -= 2 * nLayoutSign;
+//UNUSED2008-05 aScrPos.Y() -= 2;
+//UNUSED2008-05 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+//UNUSED2008-05 Rectangle aRect( aScrPos.X(), aScrPos.Y(),
+//UNUSED2008-05 aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
+//UNUSED2008-05 if ( bLayoutRTL )
+//UNUSED2008-05 {
+//UNUSED2008-05 aRect.Left() = aRect.Right(); // end position is left
+//UNUSED2008-05 aRect.Right() = aScrPos.X();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+//UNUSED2008-05 Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+//UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+//UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
+//UNUSED2008-05
+//UNUSED2008-05 SetMapMode(aOld);
+//UNUSED2008-05 }
+
+// -------------------------------------------------------------------------
+
+void ScGridWindow::DrawCursor()
+{
+// #114409#
+// SCTAB nTab = pViewData->GetTabNo();
+// SCCOL nX = pViewData->GetCurX();
+// SCROW nY = pViewData->GetCurY();
+//
+// // in verdeckten Zellen nicht zeichnen
+//
+// ScDocument* pDoc = pViewData->GetDocument();
+// const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
+// const ScMergeFlagAttr& rMerge = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
+// if (rMerge.IsOverlapped())
+// return;
+//
+// // links/oben ausserhalb des Bildschirms ?
+//
+// BOOL bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
+// if (!bVis)
+// {
+// SCCOL nEndX = nX;
+// SCROW nEndY = nY;
+// ScDocument* pDoc = pViewData->GetDocument();
+// const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
+// if (rMerge.GetColMerge() > 1)
+// nEndX += rMerge.GetColMerge()-1;
+// if (rMerge.GetRowMerge() > 1)
+// nEndY += rMerge.GetRowMerge()-1;
+// bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
+// }
+//
+// if ( bVis )
+// {
+// // hier kein Update, da aus Paint gerufen und laut Zaehler Cursor schon da
+// // wenn Update noetig, dann bei Hide/Showcursor vor dem Hoch-/Runterzaehlen
+//
+// MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
+//
+// Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE );
+// BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+//
+// // completely right of/below the screen?
+// // (test with logical start position in aScrPos)
+// BOOL bMaybeVisible;
+// if ( bLayoutRTL )
+// bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
+// else
+// {
+// Size aOutSize = GetOutputSizePixel();
+// bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
+// }
+// if ( bMaybeVisible )
+// {
+// long nSizeXPix;
+// long nSizeYPix;
+// pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+//
+// if ( bLayoutRTL )
+// aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring
+//
+// BOOL bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+// pViewData->GetVSplitMode() == SC_SPLIT_FIX );
+// if ( pViewData->GetActivePart()==eWhich || bFix )
+// {
+// // old UNX version with two Invert calls causes flicker.
+// // if optimization is needed, a new flag should be added
+// // to InvertTracking
+//
+// aScrPos.X() -= 2;
+// aScrPos.Y() -= 2;
+// Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+//
+// Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+// Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+// Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+// Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
+// }
+// else
+// {
+// Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
+// Invert( aRect );
+// }
+// }
+//
+// SetMapMode(aOld);
+// }
+}
+
+ // AutoFill-Anfasser:
+
+void ScGridWindow::DrawAutoFillMark()
+{
+// #114409#
+// if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() )
+// {
+// SCCOL nX = aAutoMarkPos.Col();
+// SCROW nY = aAutoMarkPos.Row();
+// SCTAB nTab = pViewData->GetTabNo();
+// ScDocument* pDoc = pViewData->GetDocument();
+// BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+//
+// Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE );
+// long nSizeXPix;
+// long nSizeYPix;
+// pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+// if ( bLayoutRTL )
+// aFillPos.X() -= nSizeXPix + 3;
+// else
+// aFillPos.X() += nSizeXPix - 2;
+//
+// aFillPos.Y() += nSizeYPix;
+// aFillPos.Y() -= 2;
+// Rectangle aFillRect( aFillPos, Size(6,6) );
+// // Anfasser von Zeichenobjekten sind 7*7
+//
+// MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
+// Invert( aFillRect );
+// SetMapMode(aOld);
+// }
+}
+
+// -------------------------------------------------------------------------
+
+void ScGridWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged(rDCEvt);
+
+ if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( rDCEvt.GetType() == DATACHANGED_FONTS && eWhich == pViewData->GetActivePart() )
+ pViewData->GetDocShell()->UpdateFontList();
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ if ( eWhich == pViewData->GetActivePart() ) // only once for the view
+ {
+ ScTabView* pView = pViewData->GetView();
+
+ // update scale in case the UI ScreenZoom has changed
+ ScGlobal::UpdatePPT(this);
+ pView->RecalcPPT();
+
+ // RepeatResize in case scroll bar sizes have changed
+ pView->RepeatResize();
+ pView->UpdateAllOverlays();
+
+ // invalidate cell attribs in input handler, in case the
+ // EditEngine BackgroundColor has to be changed
+ if ( pViewData->IsActive() )
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+ }
+ }
+ }
+
+ Invalidate();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/gridwin5.cxx b/sc/source/ui/view/gridwin5.cxx
new file mode 100644
index 000000000000..4a9dbbaf98b6
--- /dev/null
+++ b/sc/source/ui/view/gridwin5.cxx
@@ -0,0 +1,439 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+
+#include <editeng/flditem.hxx>
+
+#include <editeng/editview.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+#include <svtools/imapobj.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/help.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+
+#include "viewuno.hxx"
+#include "AccessibleDocument.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+#include "gridwin.hxx"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+#include "drawpage.hxx"
+#include "document.hxx"
+#include "notemark.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "dbfunc.hxx"
+#include "tabvwsh.hxx"
+#include "userdat.hxx"
+#include "postit.hxx"
+
+// -----------------------------------------------------------------------
+
+ScHideTextCursor::ScHideTextCursor( ScViewData* pData, ScSplitPos eW ) :
+ pViewData(pData),
+ eWhich(eW)
+{
+ Window* pWin = pViewData->GetView()->GetWindowByPos( eWhich );
+ if (pWin)
+ {
+ Cursor* pCur = pWin->GetCursor();
+ if ( pCur && pCur->IsVisible() )
+ pCur->Hide();
+ }
+}
+
+ScHideTextCursor::~ScHideTextCursor()
+{
+ Window* pWin = pViewData->GetView()->GetWindowByPos( eWhich );
+ if (pWin)
+ {
+ // restore text cursor
+ if ( pViewData->HasEditView(eWhich) && pWin->HasFocus() )
+ pViewData->GetEditView(eWhich)->ShowCursor( FALSE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScGridWindow::ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, BOOL bKeyboard )
+{
+ BOOL bDone = FALSE;
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScAddress aCellPos( nPosX, nPosY, nTab );
+
+ String aTrackText;
+ BOOL bLeftEdge = FALSE;
+
+ // Change-Tracking
+
+ ScChangeTrack* pTrack = pDoc->GetChangeTrack();
+ ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
+ if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges())
+ {
+ const ScChangeAction* pFound = NULL;
+ const ScChangeAction* pFoundContent = NULL;
+ const ScChangeAction* pFoundMove = NULL;
+ long nModified = 0;
+ const ScChangeAction* pAction = pTrack->GetFirst();
+ while (pAction)
+ {
+ if ( pAction->IsVisible() &&
+ ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
+ {
+ ScChangeActionType eType = pAction->GetType();
+ const ScBigRange& rBig = pAction->GetBigRange();
+ if ( rBig.aStart.Tab() == nTab )
+ {
+ ScRange aRange = rBig.MakeRange();
+
+ if ( eType == SC_CAT_DELETE_ROWS )
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ else if ( eType == SC_CAT_DELETE_COLS )
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+
+ if ( aRange.In( aCellPos ) )
+ {
+ pFound = pAction; // der letzte gewinnt
+ switch ( eType )
+ {
+ case SC_CAT_CONTENT :
+ pFoundContent = pAction;
+ break;
+ case SC_CAT_MOVE :
+ pFoundMove = pAction;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ++nModified;
+ }
+ }
+ if ( eType == SC_CAT_MOVE )
+ {
+ ScRange aRange =
+ ((const ScChangeActionMove*)pAction)->
+ GetFromRange().MakeRange();
+ if ( aRange.In( aCellPos ) )
+ {
+ pFound = pAction;
+ ++nModified;
+ }
+ }
+ }
+ pAction = pAction->GetNext();
+ }
+
+ if ( pFound )
+ {
+ if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT )
+ pFound = pFoundContent; // Content gewinnt
+ if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE &&
+ pFoundMove->GetActionNumber() >
+ pFound->GetActionNumber() )
+ pFound = pFoundMove; // Move gewinnt
+
+ // bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
+ if ( pFound->GetType() == SC_CAT_DELETE_COLS )
+ bLeftEdge = TRUE;
+
+ DateTime aDT = pFound->GetDateTime();
+ aTrackText = pFound->GetUser();
+ aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
+ aTrackText += ScGlobal::pLocaleData->getDate(aDT);
+ aTrackText += ' ';
+ aTrackText += ScGlobal::pLocaleData->getTime(aDT);
+ aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ":\n" ));
+ String aComStr=pFound->GetComment();
+ if(aComStr.Len()>0)
+ {
+ aTrackText += aComStr;
+ aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n( " ));
+ }
+ pFound->GetDescription( aTrackText, pDoc );
+ if(aComStr.Len()>0)
+ {
+ aTrackText +=')';
+ }
+ }
+ }
+
+ // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird:
+ const ScPostIt* pNote = pDoc->GetNote( aCellPos );
+ if ( (aTrackText.Len() > 0) || (pNote && !pNote->IsCaptionShown()) )
+ {
+ BOOL bNew = TRUE;
+ BOOL bFast = FALSE;
+ if ( pNoteMarker ) // schon eine Notiz angezeigt
+ {
+ if ( pNoteMarker->GetDocPos() == aCellPos ) // dieselbe
+ bNew = FALSE; // dann stehenlassen
+ else
+ bFast = TRUE; // sonst sofort
+
+ // marker which was shown for ctrl-F1 isn't removed by mouse events
+ if ( pNoteMarker->IsByKeyboard() && !bKeyboard )
+ bNew = FALSE;
+ }
+ if ( bNew )
+ {
+ if ( bKeyboard )
+ bFast = TRUE; // keyboard also shows the marker immediately
+
+ delete pNoteMarker;
+
+ bool bHSplit = pViewData->GetHSplitMode() != SC_SPLIT_NONE;
+ bool bVSplit = pViewData->GetVSplitMode() != SC_SPLIT_NONE;
+
+ Window* pLeft = pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
+ Window* pRight = bHSplit ? pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT ) : 0;
+ Window* pBottom = bVSplit ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT ) : 0;
+ Window* pDiagonal = (bHSplit && bVSplit) ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT ) : 0;
+ DBG_ASSERT( pLeft, "ScGridWindow::ShowNoteMarker - missing top-left grid window" );
+
+ /* If caption is shown from right or bottom windows, adjust
+ mapmode to include size of top-left window. */
+ MapMode aMapMode = GetDrawMapMode( TRUE );
+ Size aLeftSize = pLeft->PixelToLogic( pLeft->GetOutputSizePixel(), aMapMode );
+ Point aOrigin = aMapMode.GetOrigin();
+ if( (this == pRight) || (this == pDiagonal) )
+ aOrigin.X() += aLeftSize.Width();
+ if( (this == pBottom) || (this == pDiagonal) )
+ aOrigin.Y() += aLeftSize.Height();
+ aMapMode.SetOrigin( aOrigin );
+
+ pNoteMarker = new ScNoteMarker( pLeft, pRight, pBottom, pDiagonal,
+ pDoc, aCellPos, aTrackText,
+ aMapMode, bLeftEdge, bFast, bKeyboard );
+ }
+
+ bDone = TRUE; // something is shown (old or new)
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void ScGridWindow::RequestHelp(const HelpEvent& rHEvt)
+{
+ BOOL bDone = FALSE;
+ BOOL bHelpEnabled = ( rHEvt.GetMode() & ( HELPMODE_BALLOON | HELPMODE_QUICK ) ) != 0;
+ SdrView* pDrView = pViewData->GetScDrawView();
+
+ BOOL bDrawTextEdit = FALSE;
+ if (pDrView)
+ bDrawTextEdit = pDrView->IsTextEdit();
+
+ // notes or change tracking
+
+ if ( bHelpEnabled && !bDrawTextEdit )
+ {
+ Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
+
+ if ( ShowNoteMarker( nPosX, nPosY, FALSE ) )
+ {
+ Window::RequestHelp( rHEvt ); // alte Tip/Balloon ausschalten
+ bDone = TRUE;
+ }
+ }
+
+ if ( !bDone && pNoteMarker )
+ {
+ if ( pNoteMarker->IsByKeyboard() )
+ {
+ // marker which was shown for ctrl-F1 isn't removed by mouse events
+ }
+ else
+ DELETEZ(pNoteMarker);
+ }
+
+ // Image-Map / Text-URL
+
+ if ( bHelpEnabled && !bDone && !nButtonDown ) // nur ohne gedrueckten Button
+ {
+ String aHelpText;
+ Rectangle aPixRect;
+ Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+
+ if ( pDrView ) // URL / Image-Map
+ {
+ SdrViewEvent aVEvt;
+ MouseEvent aMEvt( aPosPixel, 1, 0, MOUSE_LEFT );
+ SdrHitKind eHit = pDrView->PickAnything( aMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
+
+ if ( eHit != SDRHIT_NONE && aVEvt.pObj != NULL )
+ {
+ // URL fuer IMapObject unter Pointer ist Hilfetext
+ if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) )
+ {
+ Point aLogicPos = PixelToLogic( aPosPixel );
+ IMapObject* pIMapObj = ScDrawLayer::GetHitIMapObject(
+ aVEvt.pObj, aLogicPos, *this );
+
+ if ( pIMapObj )
+ {
+ // #44990# Bei ImageMaps die Description anzeigen, wenn vorhanden
+ aHelpText = pIMapObj->GetAltText();
+ if (!aHelpText.Len())
+ aHelpText = pIMapObj->GetURL();
+ aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
+ }
+ }
+ // URL in shape text or at shape itself (URL in text overrides object URL)
+ if ( aHelpText.Len() == 0 )
+ {
+ if( aVEvt.eEvent == SDREVENT_EXECUTEURL )
+ {
+ aHelpText = aVEvt.pURLField->GetURL();
+ aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
+ }
+ else
+ {
+ SdrObject* pObj = 0;
+ SdrPageView* pPV = 0;
+ Point aMDPos = PixelToLogic( aPosPixel );
+ if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
+ {
+ if ( pObj->IsGroupObject() )
+ {
+ SdrObject* pHit = 0;
+ if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
+ pObj = pHit;
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
+ if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
+ {
+ aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
+ aHelpText = pInfo->GetHlink();
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+
+ if ( !aHelpText.Len() ) // Text-URL
+ {
+ String aUrl;
+ if ( GetEditUrl( aPosPixel, NULL, &aUrl, NULL ) )
+ {
+ aHelpText = INetURLObject::decode( aUrl, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_UNAMBIGUOUS );
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
+ pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
+
+ ScHideTextCursor aHideCursor( pViewData, eWhich ); // MapMode is changed in GetEditArea
+
+ // bForceToTop = FALSE, use the cell's real position
+ aPixRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, FALSE );
+ }
+ }
+
+ if ( aHelpText.Len() )
+ {
+ Rectangle aScreenRect(OutputToScreenPixel(aPixRect.TopLeft()),
+ OutputToScreenPixel(aPixRect.BottomRight()));
+
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon(this,rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
+ else if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ Help::ShowQuickHelp(this,aScreenRect, aHelpText);
+
+ bDone = TRUE;
+ }
+ }
+
+ // Basic-Controls
+
+ if ( pDrView && bHelpEnabled && !bDone )
+ {
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ DBG_ASSERT( pPV, "SdrPageView* ist NULL" );
+ if (pPV)
+ bDone = ((ScDrawPage*)pPV->GetPage())->RequestHelp( this, pDrView, rHEvt );
+ }
+
+ // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
+
+ if ( nMouseStatus == SC_GM_TABDOWN && pViewData->GetRefType() == SC_REFTYPE_FILL &&
+ Help::IsQuickHelpEnabled() )
+ bDone = TRUE;
+
+ if (!bDone)
+ Window::RequestHelp( rHEvt );
+}
+
+BOOL ScGridWindow::IsMyModel(SdrEditView* pSdrView)
+{
+ return pSdrView &&
+ pSdrView->GetModel() == pViewData->GetDocument()->GetDrawLayer();
+}
+
+void ScGridWindow::HideNoteMarker()
+{
+ DELETEZ(pNoteMarker);
+}
+
+com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ ScGridWindow::CreateAccessible()
+{
+ ScAccessibleDocument* pAccessibleDocument =
+ new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
+ pViewData->GetViewShell(), eWhich);
+
+ com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccessible = pAccessibleDocument;
+
+ pAccessibleDocument->Init();
+
+ return xAccessible;
+}
diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx
new file mode 100644
index 000000000000..25f3c1c8f10a
--- /dev/null
+++ b/sc/source/ui/view/hdrcont.cxx
@@ -0,0 +1,1046 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/dispatch.hxx>
+#include <vcl/help.hxx>
+#include <tools/poly.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "hdrcont.hxx"
+#include "scmod.hxx" // Optionen
+#include "inputopt.hxx" // Optionen
+#include "gridmerg.hxx"
+#include "document.hxx"
+
+// -----------------------------------------------------------------------
+
+#define SC_DRAG_MIN 2
+
+// passes in paint
+// (selection left/right must be first because the continuous lines
+// are partly overwritten later)
+
+#define SC_HDRPAINT_SEL_RIGHT 0
+#define SC_HDRPAINT_SEL_LEFT 1
+#define SC_HDRPAINT_TOP 2
+#define SC_HDRPAINT_SEL_TOP 3
+#define SC_HDRPAINT_SEL_BOTTOM 4
+#define SC_HDRPAINT_BOTTOM 5
+#define SC_HDRPAINT_TEXT 6
+#define SC_HDRPAINT_COUNT 7
+
+//==================================================================
+
+ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
+ SCCOLROW nNewSize, USHORT nNewFlags ) :
+ Window ( pParent ),
+ pSelEngine ( pSelectionEngine ),
+ nFlags ( nNewFlags ),
+ bVertical ( (nNewFlags & HDR_VERTICAL) != 0 ),
+ nSize ( nNewSize ),
+ nMarkStart ( 0 ),
+ nMarkEnd ( 0 ),
+ bMarkRange ( FALSE ),
+ bDragging ( FALSE ),
+ bIgnoreMove ( FALSE )
+{
+ // --- RTL --- no default mirroring for this window, the spreadsheet itself
+ // is also not mirrored
+ // #107811# mirror the vertical window for correct border drawing
+ // #106948# table layout depends on sheet format, not UI setting, so the
+ // borders of the vertical window have to be handled manually, too.
+ EnableRTL( FALSE );
+
+ aNormFont = GetFont();
+ aNormFont.SetTransparent( TRUE ); //! WEIGHT_NORMAL hart setzen ???
+ aBoldFont = aNormFont;
+ aBoldFont.SetWeight( WEIGHT_BOLD );
+
+ SetFont(aBoldFont);
+ bBoldSet = TRUE;
+
+ Size aSize = LogicToPixel( Size(
+ GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888")) ),
+ GetTextHeight() ) );
+ aSize.Width() += 4; // Platz fuer hervorgehobene Umrandung
+ aSize.Height() += 3;
+ SetSizePixel( aSize );
+
+ nWidth = nSmallWidth = aSize.Width();
+ nBigWidth = LogicToPixel( Size( GetTextWidth(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5;
+
+ SetBackground(); // sonst Probleme auf OS/2 !?!?!
+}
+
+void ScHeaderControl::SetWidth( long nNew )
+{
+ DBG_ASSERT( bVertical, "SetDigits nur fuer Zeilenkoepfe erlaubt" );
+ if ( nNew != nWidth )
+ {
+ Size aSize( nNew, GetSizePixel().Height() ); // Hoehe nicht aendern
+ SetSizePixel( aSize );
+
+ nWidth = nNew;
+
+ Invalidate(); // neu zentrieren
+ }
+}
+
+ScHeaderControl::~ScHeaderControl()
+{
+}
+
+void ScHeaderControl::DoPaint( SCCOLROW nStart, SCCOLROW nEnd )
+{
+ BOOL bLayoutRTL = IsLayoutRTL();
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Rectangle aRect( Point(0,0), GetOutputSizePixel() );
+ if ( bVertical )
+ {
+ aRect.Top() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line at top of selection
+ aRect.Bottom() = GetScrPos( nEnd+1 )-nLayoutSign;
+ }
+ else
+ {
+ aRect.Left() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line left of selection
+ aRect.Right() = GetScrPos( nEnd+1 )-nLayoutSign;
+ }
+ Invalidate(aRect);
+}
+
+void ScHeaderControl::SetMark( BOOL bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd )
+{
+ BOOL bEnabled = SC_MOD()->GetInputOptions().GetMarkHeader(); //! cachen?
+ if (!bEnabled)
+ bNewSet = FALSE;
+
+ // Variablen setzen
+
+ BOOL bOldSet = bMarkRange;
+ SCCOLROW nOldStart = nMarkStart;
+ SCCOLROW nOldEnd = nMarkEnd;
+ PutInOrder( nNewStart, nNewEnd );
+ bMarkRange = bNewSet;
+ nMarkStart = nNewStart;
+ nMarkEnd = nNewEnd;
+
+ // Paint
+
+ if ( bNewSet )
+ {
+ if ( bOldSet )
+ {
+ if ( nNewStart == nOldStart )
+ {
+ if ( nNewEnd != nOldEnd )
+ DoPaint( Min( nNewEnd, nOldEnd ) + 1, Max( nNewEnd, nOldEnd ) );
+ // sonst nix
+ }
+ else if ( nNewEnd == nOldEnd )
+ DoPaint( Min( nNewStart, nOldStart ), Max( nNewStart, nOldStart ) - 1 );
+ else if ( nNewStart > nOldEnd || nNewEnd < nOldStart )
+ {
+ // zwei Bereiche...
+ DoPaint( nOldStart, nOldEnd );
+ DoPaint( nNewStart, nNewEnd );
+ }
+ else // irgendwie ueberlappend... (kommt eh nicht oft vor)
+ DoPaint( Min( nNewStart, nOldStart ), Max( nNewEnd, nOldEnd ) );
+ }
+ else
+ DoPaint( nNewStart, nNewEnd ); // komplett neu
+ }
+ else if ( bOldSet )
+ DoPaint( nOldStart, nOldEnd ); // komplett aufheben
+
+ // sonst war nix, is nix
+}
+
+long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo )
+{
+ long nScrPos;
+
+ long nMax = ( bVertical ? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1;
+ if (nEntryNo >= nSize)
+ nScrPos = nMax;
+ else
+ {
+ nScrPos = 0;
+ for (SCCOLROW i=GetPos(); i<nEntryNo && nScrPos<nMax; i++)
+ {
+ USHORT nAdd = GetEntrySize(i);
+ if (nAdd)
+ nScrPos += nAdd;
+ else
+ {
+ SCCOLROW nHidden = GetHiddenCount(i);
+ if (nHidden > 0)
+ i += nHidden - 1;
+ }
+ }
+ }
+
+ if ( IsLayoutRTL() )
+ nScrPos = nMax - nScrPos - 2;
+
+ return nScrPos;
+}
+
+// draw a rectangle across the window's width/height, with the outer part in a lighter color
+
+void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBaseColor )
+{
+ Color aWhite( COL_WHITE );
+
+ Color aInner( rBaseColor ); // highlight color, unchanged
+ Color aCenter( rBaseColor );
+ aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
+ Color aOuter( rBaseColor );
+ aOuter.Merge( aWhite, 0xa0 ); // lighten up more
+
+ if ( IsMirrored() )
+ std::swap( aInner, aOuter ); // just swap colors instead of positions
+
+ Size aWinSize = GetSizePixel();
+ long nBarSize = bVertical ? aWinSize.Width() : aWinSize.Height();
+ long nCenterPos = (nBarSize / 2) - 1;
+
+ SetLineColor();
+ SetFillColor( aOuter );
+ if (bVertical)
+ DrawRect( Rectangle( 0, nStart, nCenterPos-1, nEnd ) );
+ else
+ DrawRect( Rectangle( nStart, 0, nEnd, nCenterPos-1 ) );
+ SetFillColor( aCenter );
+ if (bVertical)
+ DrawRect( Rectangle( nCenterPos, nStart, nCenterPos, nEnd ) );
+ else
+ DrawRect( Rectangle( nStart, nCenterPos, nEnd, nCenterPos ) );
+ SetFillColor( aInner );
+ if (bVertical)
+ DrawRect( Rectangle( nCenterPos+1, nStart, nBarSize-1, nEnd ) );
+ else
+ DrawRect( Rectangle( nStart, nCenterPos+1, nEnd, nBarSize-1 ) );
+}
+
+//
+// Paint
+//
+
+void ScHeaderControl::Paint( const Rectangle& rRect )
+{
+ // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren
+ // Linien zusammengefasst
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ BOOL bHighContrast = rStyleSettings.GetHighContrastMode();
+ BOOL bDark = rStyleSettings.GetFaceColor().IsDark();
+ // Use the same distinction for bDark as in Window::DrawSelectionBackground
+
+ Color aTextColor = rStyleSettings.GetButtonTextColor();
+ Color aSelTextColor = rStyleSettings.GetHighlightTextColor();
+ aNormFont.SetColor( aTextColor );
+ if ( bHighContrast )
+ aBoldFont.SetColor( aTextColor );
+ else
+ aBoldFont.SetColor( aSelTextColor );
+ SetTextColor( ( bBoldSet && !bHighContrast ) ? aSelTextColor : aTextColor );
+
+ Color aBlack( COL_BLACK );
+ Color aSelLineColor = rStyleSettings.GetHighlightColor();
+ aSelLineColor.Merge( aBlack, 0xe0 ); // darken just a little bit
+
+ BOOL bLayoutRTL = IsLayoutRTL();
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ BOOL bMirrored = IsMirrored();
+
+// const FunctionSet* pFuncSet = pSelEngine->GetFunctionSet();
+ String aString;
+ USHORT nBarSize;
+ Point aScrPos;
+ Size aTextSize;
+// Size aSize = GetOutputSizePixel();
+
+ if (bVertical)
+ nBarSize = (USHORT) GetSizePixel().Width();
+ else
+ nBarSize = (USHORT) GetSizePixel().Height();
+
+ SCCOLROW nPos = GetPos();
+
+ long nPStart = bVertical ? rRect.Top() : rRect.Left();
+ long nPEnd = bVertical ? rRect.Bottom() : rRect.Right();
+
+ long nTransStart = nPEnd + 1;
+ long nTransEnd = 0;
+
+ long nInitScrPos = 0;
+ if ( bLayoutRTL )
+ {
+ long nTemp = nPStart; // swap nPStart / nPEnd
+ nPStart = nPEnd;
+ nPEnd = nTemp;
+ nTemp = nTransStart; // swap nTransStart / nTransEnd
+ nTransStart = nTransEnd;
+ nTransEnd = nTemp;
+ if ( bVertical ) // start loops from the end
+ nInitScrPos = GetSizePixel().Height() - 1;
+ else
+ nInitScrPos = GetSizePixel().Width() - 1;
+ }
+
+ // aeussere Linien komplett durchzeichnen
+ // Zuerst Ende der letzten Zelle finden
+
+// long nLineEnd = -1;
+ long nLineEnd = nInitScrPos - nLayoutSign;
+
+ for (SCCOLROW i=nPos; i<nSize; i++)
+ {
+ USHORT nSizePix = GetEntrySize( i );
+ if (nSizePix)
+ {
+ nLineEnd += nSizePix * nLayoutSign;
+
+ if ( bMarkRange && i >= nMarkStart && i <= nMarkEnd )
+ {
+ long nLineStart = nLineEnd - ( nSizePix - 1 ) * nLayoutSign;
+ if ( nLineStart * nLayoutSign < nTransStart * nLayoutSign )
+ nTransStart = nLineStart;
+ if ( nLineEnd * nLayoutSign > nTransEnd * nLayoutSign )
+ nTransEnd = nLineEnd;
+ }
+
+ if ( nLineEnd * nLayoutSign > nPEnd * nLayoutSign )
+ {
+ nLineEnd = nPEnd;
+ break;
+ }
+ }
+ else
+ {
+ SCCOLROW nHidden = GetHiddenCount(i);
+ if (nHidden > 0)
+ i += nHidden - 1;
+ }
+ }
+
+ // background is different for entry area and behind the entries
+
+ Rectangle aFillRect;
+ SetLineColor();
+
+ if ( nLineEnd * nLayoutSign >= nInitScrPos * nLayoutSign )
+ {
+ if ( bHighContrast )
+ {
+ // high contrast: single-color background
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ if ( bVertical )
+ aFillRect = Rectangle( 0, nInitScrPos, nBarSize-1, nLineEnd );
+ else
+ aFillRect = Rectangle( nInitScrPos, 0, nLineEnd, nBarSize-1 );
+ DrawRect( aFillRect );
+ }
+ else
+ {
+ // normal: 3-part background
+ DrawShadedRect( nInitScrPos, nLineEnd, rStyleSettings.GetFaceColor() );
+ }
+ }
+
+ if ( nLineEnd * nLayoutSign < nPEnd * nLayoutSign )
+ {
+ SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND).nColor );
+ if ( bVertical )
+ aFillRect = Rectangle( 0, nLineEnd+nLayoutSign, nBarSize-1, nPEnd );
+ else
+ aFillRect = Rectangle( nLineEnd+nLayoutSign, 0, nPEnd, nBarSize-1 );
+ DrawRect( aFillRect );
+ }
+
+ if ( nLineEnd * nLayoutSign >= nPStart * nLayoutSign )
+ {
+ if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign )
+ {
+ if ( bHighContrast )
+ {
+ if ( bDark )
+ {
+ // solid grey background for dark face color is drawn before lines
+
+ SetLineColor();
+ SetFillColor( COL_LIGHTGRAY );
+ if (bVertical)
+ DrawRect( Rectangle( 0, nTransStart, nBarSize-1, nTransEnd ) );
+ else
+ DrawRect( Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 ) );
+ }
+ }
+ else
+ {
+ // background for selection
+
+ DrawShadedRect( nTransStart, nTransEnd, rStyleSettings.GetHighlightColor() );
+ }
+ }
+
+#if 0
+ // 3D border is no longer used
+ SetLineColor( rStyleSettings.GetLightColor() );
+ if (bVertical)
+ DrawLine( Point( 0, nPStart ), Point( 0, nLineEnd ) );
+ else
+ DrawLine( Point( nPStart, 0 ), Point( nLineEnd, 0 ) );
+#endif
+
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ if (bVertical)
+ {
+ long nDarkPos = bMirrored ? 0 : nBarSize-1;
+ DrawLine( Point( nDarkPos, nPStart ), Point( nDarkPos, nLineEnd ) );
+ }
+ else
+ DrawLine( Point( nPStart, nBarSize-1 ), Point( nLineEnd, nBarSize-1 ) );
+
+ // line in different color for selection
+ if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && !bHighContrast )
+ {
+ SetLineColor( aSelLineColor );
+ if (bVertical)
+ {
+ long nDarkPos = bMirrored ? 0 : nBarSize-1;
+ DrawLine( Point( nDarkPos, nTransStart ), Point( nDarkPos, nTransEnd ) );
+ }
+ else
+ DrawLine( Point( nTransStart, nBarSize-1 ), Point( nTransEnd, nBarSize-1 ) );
+ }
+ }
+
+ //
+ // loop through entries several times to avoid changing the line color too often
+ // and to allow merging of lines
+ //
+
+ ScGridMerger aGrid( this, 1, 1 );
+
+ // start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different
+ // borders, light border at top isn't used anymore
+ // use SC_HDRPAINT_SEL_BOTTOM for different color
+
+ for (USHORT nPass = SC_HDRPAINT_SEL_BOTTOM; nPass < SC_HDRPAINT_COUNT; nPass++)
+ {
+ // set line color etc. before entry loop
+ switch ( nPass )
+ {
+ case SC_HDRPAINT_SEL_BOTTOM:
+ // same as non-selected for high contrast
+ SetLineColor( bHighContrast ? rStyleSettings.GetDarkShadowColor() : aSelLineColor );
+ break;
+ case SC_HDRPAINT_BOTTOM:
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ break;
+ case SC_HDRPAINT_TEXT:
+ // DrawSelectionBackground is used only for high contrast on light background
+ if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && bHighContrast && !bDark )
+ {
+ // Transparent selection background is drawn after lines, before text.
+ // #109814# Use DrawSelectionBackground to make sure there is a visible
+ // difference. The case of a dark face color, where DrawSelectionBackground
+ // would just paint over the lines, is handled separately (bDark).
+ // Otherwise, GetHighlightColor is used with 80% transparency.
+ // The window's background color (SetBackground) has to be the background
+ // of the cell area, for the contrast comparison in DrawSelectionBackground.
+
+ Rectangle aTransRect;
+ if (bVertical)
+ aTransRect = Rectangle( 0, nTransStart, nBarSize-1, nTransEnd );
+ else
+ aTransRect = Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 );
+ SetBackground( Color( rStyleSettings.GetFaceColor() ) );
+ DrawSelectionBackground( aTransRect, 0, TRUE, FALSE, FALSE );
+ SetBackground();
+ }
+ break;
+ }
+
+ SCCOLROW nCount=0;
+ long nScrPos=nInitScrPos;
+ do
+ {
+ if (bVertical)
+ aScrPos = Point( 0, nScrPos );
+ else
+ aScrPos = Point( nScrPos, 0 );
+
+ SCCOLROW nEntryNo = nCount + nPos;
+ if ( nEntryNo >= nSize ) // MAXCOL/MAXROW
+ nScrPos = nPEnd + nLayoutSign; // beyond nPEnd -> stop
+ else
+ {
+ USHORT nSizePix = GetEntrySize( nEntryNo );
+
+ if (nSizePix == 0)
+ {
+ SCCOLROW nHidden = GetHiddenCount(nEntryNo);
+ if (nHidden > 0)
+ nCount += nHidden - 1;
+ }
+ else if ((nScrPos+nSizePix*nLayoutSign)*nLayoutSign >= nPStart*nLayoutSign)
+ {
+ Point aEndPos(aScrPos);
+ if (bVertical)
+ aEndPos = Point( aScrPos.X()+nBarSize-1, aScrPos.Y()+(nSizePix-1)*nLayoutSign );
+ else
+ aEndPos = Point( aScrPos.X()+(nSizePix-1)*nLayoutSign, aScrPos.Y()+nBarSize-1 );
+
+ BOOL bMark = bMarkRange && nEntryNo >= nMarkStart && nEntryNo <= nMarkEnd;
+ BOOL bNextToMark = bMarkRange && nEntryNo + 1 >= nMarkStart && nEntryNo <= nMarkEnd;
+
+ switch ( nPass )
+ {
+ case SC_HDRPAINT_SEL_BOTTOM:
+ case SC_HDRPAINT_BOTTOM:
+ if ( nPass == ( bNextToMark ? SC_HDRPAINT_SEL_BOTTOM : SC_HDRPAINT_BOTTOM ) )
+ {
+ if (bVertical)
+ aGrid.AddHorLine( aScrPos.X(), aEndPos.X(), aEndPos.Y() );
+ else
+ aGrid.AddVerLine( aEndPos.X(), aScrPos.Y(), aEndPos.Y() );
+
+ // thick bottom for hidden rows
+ // (drawn directly, without aGrid)
+ if ( nEntryNo+1 < nSize )
+ if ( GetEntrySize(nEntryNo+1)==0 )
+ {
+ if (bVertical)
+ DrawLine( Point(aScrPos.X(),aEndPos.Y()-nLayoutSign),
+ Point(aEndPos.X(),aEndPos.Y()-nLayoutSign) );
+ else
+ DrawLine( Point(aEndPos.X()-nLayoutSign,aScrPos.Y()),
+ Point(aEndPos.X()-nLayoutSign,aEndPos.Y()) );
+ }
+ }
+ break;
+
+ case SC_HDRPAINT_TEXT:
+ if ( nSizePix > 1 ) // minimal check for small columns/rows
+ {
+ if ( bMark != bBoldSet )
+ {
+ if (bMark)
+ SetFont(aBoldFont);
+ else
+ SetFont(aNormFont);
+ bBoldSet = bMark;
+ }
+ aString = GetEntryText( nEntryNo );
+ aTextSize.Width() = GetTextWidth( aString );
+ aTextSize.Height() = GetTextHeight();
+
+ Point aTxtPos(aScrPos);
+ if (bVertical)
+ {
+ aTxtPos.X() += (nBarSize-aTextSize.Width())/2;
+ aTxtPos.Y() += (nSizePix*nLayoutSign-aTextSize.Height())/2;
+ if ( bMirrored )
+ aTxtPos.X() += 1; // dark border is left instead of right
+ }
+ else
+ {
+ aTxtPos.X() += (nSizePix*nLayoutSign-aTextSize.Width()+1)/2;
+ aTxtPos.Y() += (nBarSize-aTextSize.Height())/2;
+ }
+ DrawText( aTxtPos, aString );
+ }
+ break;
+ }
+
+ // bei Selektion der ganzen Zeile/Spalte:
+ // InvertRect( Rectangle( aScrPos, aEndPos ) );
+ }
+ nScrPos += nSizePix * nLayoutSign; // also if before the visible area
+ }
+ ++nCount;
+ }
+ while ( nScrPos * nLayoutSign <= nPEnd * nLayoutSign );
+
+ aGrid.Flush();
+ }
+}
+
+//
+// Maus - Handling
+//
+
+SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder )
+{
+ BOOL bFound=FALSE;
+ SCCOLROW nCount = 1;
+ SCCOLROW nPos = GetPos();
+ SCCOLROW nHitNo = nPos;
+ long nScrPos;
+ long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
+ long nDif;
+ Size aSize = GetOutputSizePixel();
+ long nWinSize = bVertical ? aSize.Height() : aSize.Width();
+
+ BOOL bLayoutRTL = IsLayoutRTL();
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ long nEndPos = bLayoutRTL ? -1 : nWinSize;
+
+ nScrPos = GetScrPos( nPos ) - nLayoutSign;
+ do
+ {
+ SCCOLROW nEntryNo = nCount + nPos;
+
+// nScrPos = GetScrPos( nEntryNo ) - 1;
+
+ if (nEntryNo > nSize)
+ nScrPos = nEndPos + nLayoutSign;
+ else
+ nScrPos += GetEntrySize( nEntryNo - 1 ) * nLayoutSign; //! GetHiddenCount() ??
+
+ nDif = nMousePos - nScrPos;
+ if (nDif >= -2 && nDif <= 2 && nCount > 0)
+ {
+ bFound=TRUE;
+ nHitNo=nEntryNo-1;
+ }
+ else if (nDif * nLayoutSign >= 0 && nEntryNo < nSize)
+ nHitNo = nEntryNo;
+ ++nCount;
+ }
+ while ( nScrPos * nLayoutSign < nEndPos * nLayoutSign && nDif * nLayoutSign > 0 );
+
+ rBorder = bFound;
+ return nHitNo;
+}
+
+bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos) const
+{
+ ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+ if (!pViewSh)
+ return false;
+
+ ScViewData* pViewData = pViewSh->GetViewData();
+ USHORT nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSelectAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ // This sheet is protected. Check if a context menu is allowed on this cell.
+ bool bCellsProtected = false;
+ if (bVertical)
+ {
+ // row header
+ SCROW nRPos = static_cast<SCROW>(nPos);
+ bCellsProtected = pDoc->HasAttrib(0, nRPos, nTab, MAXCOL, nRPos, nTab, HASATTR_PROTECTED);
+ }
+ else
+ {
+ // column header
+ SCCOL nCPos = static_cast<SCCOL>(nPos);
+ bCellsProtected = pDoc->HasAttrib(nCPos, 0, nTab, nCPos, MAXROW, nTab, HASATTR_PROTECTED);
+ }
+
+ bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if (bCellsProtected)
+ bSelectAllowed = bSelProtected;
+ else
+ bSelectAllowed = bSelUnprotected;
+ }
+ return bSelectAllowed;
+}
+
+void ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (IsDisabled())
+ return;
+
+ bIgnoreMove = FALSE;
+ SelectWindow();
+
+ BOOL bFound;
+ SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
+ if (!IsSelectionAllowed(nHitNo))
+ return;
+
+ if ( bFound && rMEvt.IsLeft() && ResizeAllowed() )
+ {
+ nDragNo = nHitNo;
+ USHORT nClicks = rMEvt.GetClicks();
+ if ( nClicks && nClicks%2==0 )
+ {
+ SetEntrySize( nDragNo, HDR_SIZE_OPTIMUM );
+ SetPointer( Pointer( POINTER_ARROW ) );
+ }
+ else
+ {
+ if (bVertical)
+ nDragStart = rMEvt.GetPosPixel().Y();
+ else
+ nDragStart = rMEvt.GetPosPixel().X();
+ nDragPos = nDragStart;
+ ShowDragHelp();
+ DrawInvert( nDragPos );
+
+ // CaptureMouse();
+ StartTracking();
+ bDragging = TRUE;
+ bDragMoved = FALSE;
+ }
+ }
+ else if (rMEvt.IsLeft())
+ {
+ pSelEngine->SetWindow( this );
+ Point aPoint;
+ Rectangle aVis( aPoint,GetOutputSizePixel() );
+ if (bVertical)
+ aVis.Left() = LONG_MIN, aVis.Right() = LONG_MAX;
+ else
+ aVis.Top() = LONG_MIN, aVis.Bottom() = LONG_MAX;
+ pSelEngine->SetVisibleArea( aVis );
+
+ SetMarking( TRUE ); // muss vor SelMouseButtonDown sein
+ pSelEngine->SelMouseButtonDown( rMEvt );
+
+ // #74215# In column/row headers a simple click already is a selection.
+ // -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor
+ // if the next click is somewhere else with Control key).
+ pSelEngine->SelMouseMove( rMEvt );
+
+ if (IsMouseCaptured())
+ {
+ // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
+ //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
+ ReleaseMouse();
+ StartTracking();
+ }
+ }
+}
+
+void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( IsDisabled() )
+ return;
+
+ SetMarking( FALSE );
+ bIgnoreMove = FALSE;
+// BOOL bFound;
+// SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
+
+ if ( bDragging )
+ {
+ DrawInvert( nDragPos );
+ ReleaseMouse();
+ bDragging = FALSE;
+
+ long nScrPos = GetScrPos( nDragNo );
+ long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
+ BOOL bLayoutRTL = IsLayoutRTL();
+ long nNewWidth = bLayoutRTL ? ( nScrPos - nMousePos + 1 )
+ : ( nMousePos + 2 - nScrPos );
+
+ if ( nNewWidth < 0 /* && !IsSelected(nDragNo) */ )
+ {
+ SCCOLROW nStart = 0;
+ SCCOLROW nEnd = nDragNo;
+ while (nNewWidth < 0)
+ {
+ nStart = nDragNo;
+ if (nDragNo>0)
+ {
+ --nDragNo;
+ nNewWidth += GetEntrySize( nDragNo ); //! GetHiddenCount() ???
+ }
+ else
+ nNewWidth = 0;
+ }
+ HideEntries( nStart, nEnd );
+ }
+ else
+ {
+ if (nNewWidth<0) nNewWidth=0;
+ if (bDragMoved)
+ SetEntrySize( nDragNo, (USHORT) nNewWidth );
+ }
+ }
+ else
+ {
+ pSelEngine->SelMouseButtonUp( rMEvt );
+ ReleaseMouse();
+ }
+}
+
+void ScHeaderControl::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( IsDisabled() )
+ {
+ SetPointer( Pointer( POINTER_ARROW ) );
+ return;
+ }
+
+ BOOL bFound;
+ (void)GetMousePos( rMEvt, bFound );
+
+ if ( bDragging )
+ {
+ long nNewPos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
+ if ( nNewPos != nDragPos )
+ {
+ DrawInvert( nDragPos );
+ nDragPos = nNewPos;
+ ShowDragHelp();
+ DrawInvert( nDragPos );
+
+ if (nDragPos <= nDragStart-SC_DRAG_MIN || nDragPos >= nDragStart+SC_DRAG_MIN)
+ bDragMoved = TRUE;
+ }
+ }
+ else
+ {
+ if ( bFound && rMEvt.GetButtons()==0 && ResizeAllowed() )
+ SetPointer( Pointer( bVertical ? POINTER_VSIZEBAR : POINTER_HSIZEBAR ) );
+ else
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ if (!bIgnoreMove)
+ pSelEngine->SelMouseMove( rMEvt );
+ }
+}
+
+void ScHeaderControl::Tracking( const TrackingEvent& rTEvt )
+{
+ // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
+ // die verschiedenen MouseHandler verteilen...
+
+ if ( rTEvt.IsTrackingCanceled() )
+ StopMarking();
+ else if ( rTEvt.IsTrackingEnded() )
+ MouseButtonUp( rTEvt.GetMouseEvent() );
+ else
+ MouseMove( rTEvt.GetMouseEvent() );
+}
+
+void ScHeaderControl::Command( const CommandEvent& rCEvt )
+{
+ USHORT nCmd = rCEvt.GetCommand();
+ if ( nCmd == COMMAND_CONTEXTMENU )
+ {
+ StopMarking(); // Selektion / Dragging beenden
+
+ // Popup ausfuehren
+
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell,
+ SfxViewShell::Current() );
+ if ( pViewSh )
+ {
+ if ( rCEvt.IsMouseEvent() )
+ {
+ // #i18735# select the column/row under the mouse pointer
+ ScViewData* pViewData = pViewSh->GetViewData();
+
+ SelectWindow(); // also deselects drawing objects, stops draw text edit
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
+ SC_MOD()->InputEnterHandler(); // always end edit mode
+
+ MouseEvent aMEvt( rCEvt.GetMousePosPixel() );
+ BOOL bBorder;
+ SCCOLROW nPos = GetMousePos( aMEvt, bBorder );
+ if (!IsSelectionAllowed(nPos))
+ // Selecting this cell is not allowed, neither is context menu.
+ return;
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScRange aNewRange;
+ if ( bVertical )
+ aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab,
+ MAXCOL, sal::static_int_cast<SCROW>(nPos), nTab );
+ else
+ aNewRange = ScRange( sal::static_int_cast<SCCOL>(nPos), 0, nTab,
+ sal::static_int_cast<SCCOL>(nPos), MAXROW, nTab );
+
+ // see if any part of the range is already selected
+ BOOL bSelected = FALSE;
+ ScRangeList aRanges;
+ pViewData->GetMarkData().FillRangeListWithMarks( &aRanges, FALSE );
+ ULONG nRangeCount = aRanges.Count();
+ for (ULONG i=0; i<nRangeCount && !bSelected; i++)
+ if ( aRanges.GetObject(i)->Intersects( aNewRange ) )
+ bSelected = TRUE;
+
+ // select the range if no part of it was selected
+ if ( !bSelected )
+ pViewSh->MarkRange( aNewRange );
+ }
+
+ ScResId aResId( bVertical ? RID_POPUP_ROWHEADER : RID_POPUP_COLHEADER );
+ pViewSh->GetDispatcher()->ExecutePopup( aResId );
+ }
+ }
+ else if ( nCmd == COMMAND_STARTDRAG )
+ {
+ pSelEngine->Command( rCEvt );
+ }
+}
+
+void ScHeaderControl::StopMarking()
+{
+ if ( bDragging )
+ {
+ DrawInvert( nDragPos );
+ bDragging = FALSE;
+ }
+
+ SetMarking( FALSE );
+ bIgnoreMove = TRUE;
+
+ // #86260# don't call pSelEngine->Reset, so selection across the parts of
+ // a split/frozen view is possible
+
+ ReleaseMouse();
+}
+
+void ScHeaderControl::ShowDragHelp()
+{
+ if (Help::IsQuickHelpEnabled())
+ {
+ long nScrPos = GetScrPos( nDragNo );
+ BOOL bLayoutRTL = IsLayoutRTL();
+ long nVal = bLayoutRTL ? ( nScrPos - nDragPos + 1 )
+ : ( nDragPos + 2 - nScrPos );
+
+ String aHelpStr = GetDragHelp( nVal );
+ Point aPos = OutputToScreenPixel( Point(0,0) );
+ Size aSize = GetSizePixel();
+
+ Point aMousePos = OutputToScreenPixel(GetPointerPosPixel());
+
+ Rectangle aRect;
+ USHORT nAlign;
+ if (!bVertical)
+ {
+ // oberhalb
+ aRect.Left() = aMousePos.X();
+ aRect.Top() = aPos.Y() - 4;
+ nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
+ }
+ else
+ {
+ // rechts oben
+ aRect.Left() = aPos.X() + aSize.Width() + 8;
+ aRect.Top() = aMousePos.Y() - 2;
+ nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
+ }
+
+ aRect.Right() = aRect.Left();
+ aRect.Bottom() = aRect.Top();
+
+ Help::ShowQuickHelp(this, aRect, aHelpStr, nAlign);
+ }
+}
+
+void ScHeaderControl::RequestHelp( const HelpEvent& rHEvt )
+{
+ // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp
+ // wieder wegnehmen lassen
+
+ BOOL bOwn = bDragging && Help::IsQuickHelpEnabled();
+ if (!bOwn)
+ Window::RequestHelp(rHEvt);
+}
+
+// -----------------------------------------------------------------------
+// Dummys fuer virtuelle Methoden
+// -----------------------------------------------------------------------
+
+SCCOLROW ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo )
+{
+ SCCOLROW nHidden = 0;
+ while ( nEntryNo < nSize && GetEntrySize( nEntryNo ) == 0 )
+ {
+ ++nEntryNo;
+ ++nHidden;
+ }
+ return nHidden;
+}
+
+BOOL ScHeaderControl::IsLayoutRTL()
+{
+ return FALSE;
+}
+
+BOOL ScHeaderControl::IsMirrored()
+{
+ return FALSE;
+}
+
+BOOL ScHeaderControl::IsDisabled()
+{
+ return FALSE;
+}
+
+BOOL ScHeaderControl::ResizeAllowed()
+{
+ return TRUE;
+}
+
+void ScHeaderControl::SelectWindow()
+{
+}
+
+void ScHeaderControl::DrawInvert( long /* nDragPos */ )
+{
+}
+
+String ScHeaderControl::GetDragHelp( long /* nVal */ )
+{
+ return EMPTY_STRING;
+}
+
+void ScHeaderControl::SetMarking( BOOL /* bSet */ )
+{
+}
+
+
+
diff --git a/sc/source/ui/view/hintwin.cxx b/sc/source/ui/view/hintwin.cxx
new file mode 100644
index 000000000000..568923f42838
--- /dev/null
+++ b/sc/source/ui/view/hintwin.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "hintwin.hxx"
+#include "global.hxx"
+
+#define HINT_LINESPACE 2
+#define HINT_INDENT 3
+#define HINT_MARGIN 4
+
+//==================================================================
+
+ScHintWindow::ScHintWindow( Window* pParent, const String& rTit, const String& rMsg ) :
+ Window( pParent, WinBits( WB_BORDER ) ),
+ aTitle( rTit ),
+ aMessage( rMsg )
+{
+ aMessage.ConvertLineEnd( LINEEND_CR );
+
+ // Hellgelb, wie Notizen in detfunc.cxx
+ Color aYellow( 255,255,192 ); // hellgelb
+ SetBackground( aYellow );
+
+ aTextFont = GetFont();
+ aTextFont.SetTransparent( TRUE );
+ aTextFont.SetWeight( WEIGHT_NORMAL );
+ aHeadFont = aTextFont;
+ aHeadFont.SetWeight( WEIGHT_BOLD );
+
+ SetFont( aHeadFont );
+ Size aHeadSize( GetTextWidth( aTitle ), GetTextHeight() );
+ SetFont( aTextFont );
+
+ Size aTextSize;
+ xub_StrLen nIndex = 0;
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ String aLine = aMessage.GetToken( 0, CHAR_CR, nIndex );
+ Size aLineSize( GetTextWidth( aLine ), GetTextHeight() );
+ nTextHeight = aLineSize.Height();
+ aTextSize.Height() += nTextHeight;
+ if ( aLineSize.Width() > aTextSize.Width() )
+ aTextSize.Width() = aLineSize.Width();
+ }
+ aTextSize.Width() += HINT_INDENT;
+
+ aTextStart = Point( HINT_MARGIN + HINT_INDENT,
+ aHeadSize.Height() + HINT_MARGIN + HINT_LINESPACE );
+
+ Size aWinSize( Max( aHeadSize.Width(), aTextSize.Width() ) + 2 * HINT_MARGIN + 1,
+ aHeadSize.Height() + aTextSize.Height() + HINT_LINESPACE + 2 * HINT_MARGIN + 1 );
+ SetOutputSizePixel( aWinSize );
+}
+
+
+ScHintWindow::~ScHintWindow()
+{
+}
+
+
+void __EXPORT ScHintWindow::Paint( const Rectangle& /* rRect */ )
+{
+ SetFont( aHeadFont );
+ DrawText( Point(HINT_MARGIN,HINT_MARGIN), aTitle );
+
+ SetFont( aTextFont );
+ xub_StrLen nIndex = 0;
+ Point aLineStart = aTextStart;
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ String aLine = aMessage.GetToken( 0, CHAR_CR, nIndex );
+ DrawText( aLineStart, aLine );
+ aLineStart.Y() += nTextHeight;
+ }
+}
diff --git a/sc/source/ui/view/imapwrap.cxx b/sc/source/ui/view/imapwrap.cxx
new file mode 100644
index 000000000000..b2f4fb714775
--- /dev/null
+++ b/sc/source/ui/view/imapwrap.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/imapdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+
+
+USHORT ScIMapChildWindowId()
+{
+ return SvxIMapDlgChildWindow::GetChildWindowId();
+}
+
+SvxIMapDlg* ScGetIMapDlg()
+{
+ //! pass view frame here and in SVXIMAPDLG()
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if( pViewFrm && pViewFrm->HasChildWindow( SvxIMapDlgChildWindow::GetChildWindowId() ) )
+ return SVXIMAPDLG();
+ else
+ return NULL;
+}
+
+void ScIMapDlgSet( const Graphic& rGraphic, const ImageMap* pImageMap,
+ const TargetList* pTargetList, void* pEditingObj )
+{
+ SvxIMapDlgChildWindow::UpdateIMapDlg( rGraphic, pImageMap, pTargetList, pEditingObj );
+}
+
+const void* ScIMapDlgGetObj( SvxIMapDlg* pDlg )
+{
+ if ( pDlg )
+ return pDlg->GetEditingObject();
+ else
+ return NULL;
+}
+
+const ImageMap& ScIMapDlgGetMap( SvxIMapDlg* pDlg )
+{
+ return pDlg->GetImageMap();
+}
+
+
+
+
diff --git a/sc/source/ui/view/invmerge.cxx b/sc/source/ui/view/invmerge.cxx
new file mode 100644
index 000000000000..a895dc5faec0
--- /dev/null
+++ b/sc/source/ui/view/invmerge.cxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/window.hxx>
+#include <tools/debug.hxx>
+
+#include "invmerge.hxx"
+
+//------------------------------------------------------------------
+
+ScInvertMerger::ScInvertMerger( Window* pWindow ) :
+ pWin( pWindow ),
+ pRects( NULL )
+{
+ // both rectangles empty
+}
+
+ScInvertMerger::ScInvertMerger( ::std::vector< Rectangle >* pRectangles ) :
+ pWin( NULL ),
+ pRects( pRectangles )
+{
+ // collect rectangles instead of inverting
+}
+
+ScInvertMerger::~ScInvertMerger()
+{
+ Flush();
+}
+
+void ScInvertMerger::Flush()
+{
+ FlushLine();
+ FlushTotal();
+
+ DBG_ASSERT( aLineRect.IsEmpty() && aTotalRect.IsEmpty(), "Flush: not empty" );
+
+ if ( pRects )
+ {
+ //
+ // also join vertically if there are non-adjacent columns involved
+ //
+
+ size_t nComparePos = 0;
+ while ( nComparePos < pRects->size() )
+ {
+ Rectangle aCompRect = (*pRects)[nComparePos];
+ sal_Int32 nBottom = aCompRect.Bottom();
+ size_t nOtherPos = nComparePos + 1;
+
+ while ( nOtherPos < pRects->size() )
+ {
+ Rectangle aOtherRect = (*pRects)[nOtherPos];
+ if ( aOtherRect.Top() > nBottom + 1 )
+ {
+ // rectangles are sorted, so we can stop searching
+ break;
+ }
+ if ( aOtherRect.Top() == nBottom + 1 &&
+ aOtherRect.Left() == aCompRect.Left() &&
+ aOtherRect.Right() == aCompRect.Right() )
+ {
+ // extend first rectangle
+ nBottom = aOtherRect.Bottom();
+ aCompRect.Bottom() = nBottom;
+ (*pRects)[nComparePos].Bottom() = nBottom;
+
+ // remove second rectangle
+ pRects->erase( pRects->begin() + nOtherPos );
+
+ // continue at unmodified nOtherPos
+ }
+ else
+ ++nOtherPos;
+ }
+
+ ++nComparePos;
+ }
+ }
+}
+
+void ScInvertMerger::FlushTotal()
+{
+ if( aTotalRect.IsEmpty() )
+ return; // nothing to do
+
+ if ( pWin )
+ pWin->Invert( aTotalRect, INVERT_HIGHLIGHT );
+ else if ( pRects )
+ pRects->push_back( aTotalRect );
+
+ aTotalRect.SetEmpty();
+}
+
+void ScInvertMerger::FlushLine()
+{
+ if( aLineRect.IsEmpty() )
+ return; // nothing to do
+
+ if ( aTotalRect.IsEmpty() )
+ {
+ aTotalRect = aLineRect; // start new total rect
+ }
+ else
+ {
+ if ( aLineRect.Left() == aTotalRect.Left() &&
+ aLineRect.Right() == aTotalRect.Right() &&
+ aLineRect.Top() == aTotalRect.Bottom() + 1 )
+ {
+ // extend total rect
+ aTotalRect.Bottom() = aLineRect.Bottom();
+ }
+ else
+ {
+ FlushTotal(); // draw old total rect
+ aTotalRect = aLineRect; // and start new one
+ }
+ }
+
+ aLineRect.SetEmpty();
+}
+
+void ScInvertMerger::AddRect( const Rectangle& rRect )
+{
+ Rectangle aJustified = rRect;
+ if ( rRect.Left() > rRect.Right() ) // switch for RTL layout
+ {
+ aJustified.Left() = rRect.Right();
+ aJustified.Right() = rRect.Left();
+ }
+
+ if ( aLineRect.IsEmpty() )
+ {
+ aLineRect = aJustified; // start new line rect
+ }
+ else
+ {
+ BOOL bDone = FALSE;
+ if ( aJustified.Top() == aLineRect.Top() &&
+ aJustified.Bottom() == aLineRect.Bottom() )
+ {
+ // try to extend line rect
+ if ( aJustified.Left() == aLineRect.Right() + 1 )
+ {
+ aLineRect.Right() = aJustified.Right();
+ bDone = TRUE;
+ }
+ else if ( aJustified.Right() + 1 == aLineRect.Left() ) // for RTL layout
+ {
+ aLineRect.Left() = aJustified.Left();
+ bDone = TRUE;
+ }
+ }
+ if (!bDone)
+ {
+ FlushLine(); // use old line rect for total rect
+ aLineRect = aJustified; // and start new one
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk
new file mode 100644
index 000000000000..1b2fef913fc2
--- /dev/null
+++ b/sc/source/ui/view/makefile.mk
@@ -0,0 +1,173 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=view
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+# drawattr.cxx fuer IDL (enums), sollte in den Svx gehen??
+
+
+SLOFILES = \
+ $(SLO)$/tabview.obj \
+ $(SLO)$/tabview2.obj \
+ $(SLO)$/tabview3.obj \
+ $(SLO)$/tabview4.obj \
+ $(SLO)$/tabview5.obj \
+ $(SLO)$/viewfunc.obj \
+ $(SLO)$/viewfun2.obj \
+ $(SLO)$/viewfun3.obj \
+ $(SLO)$/viewfun4.obj \
+ $(SLO)$/viewfun5.obj \
+ $(SLO)$/viewfun6.obj \
+ $(SLO)$/viewfun7.obj \
+ $(SLO)$/dbfunc.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/dbfunc3.obj \
+ $(SLO)$/dbfunc4.obj \
+ $(SLO)$/tabvwsh.obj \
+ $(SLO)$/tabvwsh2.obj \
+ $(SLO)$/tabvwsh3.obj \
+ $(SLO)$/tabvwsh4.obj \
+ $(SLO)$/tabvwsh5.obj \
+ $(SLO)$/tabvwsh8.obj \
+ $(SLO)$/tabvwsh9.obj \
+ $(SLO)$/tabvwsha.obj \
+ $(SLO)$/tabvwshb.obj \
+ $(SLO)$/tabvwshc.obj \
+ $(SLO)$/tabvwshd.obj \
+ $(SLO)$/tabvwshe.obj \
+ $(SLO)$/tabvwshf.obj \
+ $(SLO)$/tabvwshg.obj \
+ $(SLO)$/tabvwshh.obj \
+ $(SLO)$/printfun.obj \
+ $(SLO)$/pfuncache.obj \
+ $(SLO)$/preview.obj \
+ $(SLO)$/prevwsh.obj \
+ $(SLO)$/prevwsh2.obj \
+ $(SLO)$/prevloc.obj \
+ $(SLO)$/editsh.obj \
+ $(SLO)$/pivotsh.obj \
+ $(SLO)$/auditsh.obj \
+ $(SLO)$/gridwin.obj \
+ $(SLO)$/gridwin2.obj \
+ $(SLO)$/gridwin3.obj \
+ $(SLO)$/gridwin4.obj \
+ $(SLO)$/gridwin5.obj \
+ $(SLO)$/drawview.obj \
+ $(SLO)$/drawvie2.obj \
+ $(SLO)$/drawvie3.obj \
+ $(SLO)$/drawvie4.obj \
+ $(SLO)$/drawutil.obj \
+ $(SLO)$/output.obj \
+ $(SLO)$/output2.obj \
+ $(SLO)$/output3.obj \
+ $(SLO)$/gridmerg.obj \
+ $(SLO)$/invmerge.obj \
+ $(SLO)$/select.obj \
+ $(SLO)$/olinewin.obj \
+ $(SLO)$/hintwin.obj \
+ $(SLO)$/notemark.obj \
+ $(SLO)$/tabcont.obj \
+ $(SLO)$/tabsplit.obj \
+ $(SLO)$/viewutil.obj \
+ $(SLO)$/hdrcont.obj \
+ $(SLO)$/colrowba.obj \
+ $(SLO)$/olkact.obj \
+ $(SLO)$/galwrap.obj \
+ $(SLO)$/imapwrap.obj \
+ $(SLO)$/reffact.obj \
+ $(SLO)$/selectionstate.obj \
+ $(SLO)$/spelleng.obj \
+ $(SLO)$/spelldialog.obj \
+ $(SLO)$/waitoff.obj \
+ $(SLO)$/cellsh.obj \
+ $(SLO)$/cellsh1.obj\
+ $(SLO)$/cellsh2.obj\
+ $(SLO)$/cellsh3.obj\
+ $(SLO)$/cellsh4.obj\
+ $(SLO)$/formatsh.obj\
+ $(SLO)$/pgbrksh.obj\
+ $(SLO)$/viewdata.obj\
+ $(SLO)$/scextopt.obj
+
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
+ NOOPTFILES= \
+ $(SLO)$/drawview.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/tabvwsh2.obj \
+ $(SLO)$/viewfun4.obj \
+ $(SLO)$/viewfun2.obj
+.ELIF "$(OS)$(COM)$(CPUNAME)"=="SOLARISC52INTEL"
+ NOOPTFILES=\
+ $(SLO)$/drawview.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/tabvwsh2.obj
+.ELSE
+ NOOPTFILES=\
+ $(SLO)$/drawview.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/tabvwsh2.obj
+.ENDIF
+
+EXCEPTIONSFILES= \
+ $(SLO)$/dbfunc3.obj \
+ $(SLO)$/gridwin.obj \
+ $(SLO)$/invmerge.obj \
+ $(SLO)$/output2.obj \
+ $(SLO)$/pfuncache.obj \
+ $(SLO)$/spelldialog.obj \
+ $(SLO)$/cellsh1.obj \
+ $(SLO)$/drawvie4.obj \
+ $(SLO)$/formatsh.obj \
+ $(SLO)$/gridwin2.obj \
+ $(SLO)$/scextopt.obj \
+ $(SLO)$/tabvwshb.obj \
+ $(SLO)$/tabvwshf.obj \
+ $(SLO)$/viewdata.obj \
+ $(SLO)$/viewfunc.obj \
+ $(SLO)$/viewfun2.obj \
+ $(SLO)$/viewfun3.obj \
+ $(SLO)$/viewfun5.obj \
+ $(SLO)$/viewfun7.obj \
+ $(SLO)$/reffact.obj
+
+# goal seek -O2
+
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/view/notemark.cxx b/sc/source/ui/view/notemark.cxx
new file mode 100644
index 000000000000..065ba5899817
--- /dev/null
+++ b/sc/source/ui/view/notemark.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svdoutl.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/printer.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/itempool.hxx>
+#include <vcl/svapp.hxx>
+
+#include "notemark.hxx"
+#include "document.hxx"
+#include "postit.hxx"
+
+#define SC_NOTEMARK_TIME 800
+#define SC_NOTEMARK_SHORT 70
+
+// -----------------------------------------------------------------------
+
+ScNoteMarker::ScNoteMarker( Window* pWin, Window* pRight, Window* pBottom, Window* pDiagonal,
+ ScDocument* pD, ScAddress aPos, const String& rUser,
+ const MapMode& rMap, BOOL bLeftEdge, BOOL bForce, BOOL bKeyboard ) :
+ pWindow( pWin ),
+ pRightWin( pRight ),
+ pBottomWin( pBottom ),
+ pDiagWin( pDiagonal ),
+ pDoc( pD ),
+ aDocPos( aPos ),
+ aUserText( rUser ),
+ aMapMode( rMap ),
+ bLeft( bLeftEdge ),
+ bByKeyboard( bKeyboard ),
+ pModel( NULL ),
+ pObject( NULL ),
+ bVisible( FALSE )
+{
+ Size aSizePixel = pWindow->GetOutputSizePixel();
+ if( pRightWin )
+ aSizePixel.Width() += pRightWin->GetOutputSizePixel().Width();
+ if( pBottomWin )
+ aSizePixel.Height() += pBottomWin->GetOutputSizePixel().Height();
+ Rectangle aVisPixel( Point( 0, 0 ), aSizePixel );
+ aVisRect = pWindow->PixelToLogic( aVisPixel, aMapMode );
+
+ aTimer.SetTimeoutHdl( LINK( this, ScNoteMarker, TimeHdl ) );
+ aTimer.SetTimeout( bForce ? SC_NOTEMARK_SHORT : SC_NOTEMARK_TIME );
+ aTimer.Start();
+}
+
+ScNoteMarker::~ScNoteMarker()
+{
+ InvalidateWin();
+
+ delete pModel;
+}
+
+IMPL_LINK( ScNoteMarker, TimeHdl, Timer*, EMPTYARG )
+{
+ if (!bVisible)
+ {
+ SvtPathOptions aPathOpt;
+ String aPath = aPathOpt.GetPalettePath();
+ pModel = new SdrModel(aPath);
+ pModel->SetScaleUnit(MAP_100TH_MM);
+ SfxItemPool& rPool = pModel->GetItemPool();
+ rPool.SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
+ rPool.FreezeIdRanges();
+
+ OutputDevice* pPrinter = pDoc->GetRefDevice();
+ if (pPrinter)
+ {
+ // Am Outliner des Draw-Model ist auch der Drucker als RefDevice gesetzt,
+ // und es soll einheitlich aussehen.
+ Outliner& rOutliner = pModel->GetDrawOutliner();
+ rOutliner.SetRefDevice(pPrinter);
+ }
+
+ if( SdrPage* pPage = pModel->AllocPage( FALSE ) )
+ {
+ pObject = ScNoteUtil::CreateTempCaption( *pDoc, aDocPos, *pPage, aUserText, aVisRect, bLeft );
+ if( pObject )
+ aRect = pObject->GetCurrentBoundRect();
+
+ // #39351# Page einfuegen damit das Model sie kennt und auch deleted
+ pModel->InsertPage( pPage );
+
+ }
+ bVisible = TRUE;
+ }
+
+ Draw();
+ return 0;
+}
+
+void lcl_DrawWin( SdrObject* pObject, Window* pWindow, const MapMode& rMap )
+{
+ MapMode aOld = pWindow->GetMapMode();
+ pWindow->SetMapMode( rMap );
+
+ ULONG nOldDrawMode = pWindow->GetDrawMode();
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pWindow->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL |
+ DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
+ }
+
+ pObject->SingleObjectPainter( *pWindow ); // #110094#-17
+
+ pWindow->SetDrawMode( nOldDrawMode );
+ pWindow->SetMapMode( aOld );
+}
+
+MapMode lcl_MoveMapMode( const MapMode& rMap, const Size& rMove )
+{
+ MapMode aNew = rMap;
+ Point aOrigin = aNew.GetOrigin();
+ aOrigin.X() -= rMove.Width();
+ aOrigin.Y() -= rMove.Height();
+ aNew.SetOrigin(aOrigin);
+ return aNew;
+}
+
+void ScNoteMarker::Draw()
+{
+ if ( pObject && bVisible )
+ {
+ lcl_DrawWin( pObject, pWindow, aMapMode );
+
+ if ( pRightWin || pBottomWin )
+ {
+ Size aWinSize = pWindow->PixelToLogic( pWindow->GetOutputSizePixel(), aMapMode );
+ if ( pRightWin )
+ lcl_DrawWin( pObject, pRightWin,
+ lcl_MoveMapMode( aMapMode, Size( aWinSize.Width(), 0 ) ) );
+ if ( pBottomWin )
+ lcl_DrawWin( pObject, pBottomWin,
+ lcl_MoveMapMode( aMapMode, Size( 0, aWinSize.Height() ) ) );
+ if ( pDiagWin )
+ lcl_DrawWin( pObject, pDiagWin, lcl_MoveMapMode( aMapMode, aWinSize ) );
+ }
+ }
+}
+
+void ScNoteMarker::InvalidateWin()
+{
+ if (bVisible)
+ {
+ pWindow->Invalidate( pWindow->LogicToLogic(aRect, aMapMode, pWindow->GetMapMode()) );
+
+ if ( pRightWin || pBottomWin )
+ {
+ Size aWinSize = pWindow->PixelToLogic( pWindow->GetOutputSizePixel(), aMapMode );
+ if ( pRightWin )
+ pRightWin->Invalidate( pRightWin->LogicToLogic(aRect,
+ lcl_MoveMapMode( aMapMode, Size( aWinSize.Width(), 0 ) ),
+ pRightWin->GetMapMode()) );
+ if ( pBottomWin )
+ pBottomWin->Invalidate( pBottomWin->LogicToLogic(aRect,
+ lcl_MoveMapMode( aMapMode, Size( 0, aWinSize.Height() ) ),
+ pBottomWin->GetMapMode()) );
+ if ( pDiagWin )
+ pDiagWin->Invalidate( pDiagWin->LogicToLogic(aRect,
+ lcl_MoveMapMode( aMapMode, aWinSize ),
+ pDiagWin->GetMapMode()) );
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/olinewin.cxx b/sc/source/ui/view/olinewin.cxx
new file mode 100644
index 000000000000..b1e82fd9217f
--- /dev/null
+++ b/sc/source/ui/view/olinewin.cxx
@@ -0,0 +1,1045 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/svapp.hxx>
+#include <vcl/taskpanelist.hxx>
+
+#include "olinewin.hxx"
+#include "olinetab.hxx"
+#include "document.hxx"
+#include "dbfunc.hxx"
+#include "sc.hrc"
+
+// ============================================================================
+
+const long SC_OL_BITMAPSIZE = 12;
+const long SC_OL_POSOFFSET = 2;
+
+const size_t SC_OL_NOLEVEL = static_cast< size_t >( -1 );
+const size_t SC_OL_HEADERENTRY = static_cast< size_t >( -1 );
+
+const USHORT SC_OL_IMAGE_PLUS = 9;
+const USHORT SC_OL_IMAGE_MINUS = SC_OL_IMAGE_PLUS + 1;
+const USHORT SC_OL_IMAGE_NOTPRESSED = SC_OL_IMAGE_MINUS + 1;
+const USHORT SC_OL_IMAGE_PRESSED = SC_OL_IMAGE_NOTPRESSED + 1;
+
+// ============================================================================
+
+ScOutlineWindow::ScOutlineWindow( Window* pParent, ScOutlineMode eMode, ScViewData* pViewData, ScSplitPos eWhich ) :
+ Window( pParent ),
+ mrViewData( *pViewData ),
+ meWhich( eWhich ),
+ mbHoriz( eMode == SC_OUTLINE_HOR ),
+ mbMirrorEntries( false ), // updated in SetHeaderSize
+ mbMirrorLevels( false ), // updated in SetHeaderSize
+ mpSymbols( NULL ),
+ maLineColor( COL_BLACK ),
+ mnHeaderSize( 0 ),
+ mnHeaderPos( 0 ),
+ mnMainFirstPos( 0 ),
+ mnMainLastPos( 0 ),
+ mbMTActive( false ),
+ mbMTPressed( false ),
+ mnFocusLevel( 0 ),
+ mnFocusEntry( SC_OL_HEADERENTRY ),
+ mbDontDrawFocus( false )
+{
+ EnableRTL( FALSE ); // mirroring is done manually
+
+ InitSettings();
+ maFocusRect.SetEmpty();
+ SetHeaderSize( 0 );
+
+ // insert the window into task pane list for "F6 cycling"
+ if( SystemWindow* pSysWin = GetSystemWindow() )
+ if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
+ pTaskPaneList->AddWindow( this );
+}
+
+ScOutlineWindow::~ScOutlineWindow()
+{
+ // remove the window from task pane list
+ if( SystemWindow* pSysWin = GetSystemWindow() )
+ if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
+ pTaskPaneList->RemoveWindow( this );
+}
+
+void ScOutlineWindow::SetHeaderSize( long nNewSize )
+{
+ BOOL bLayoutRTL = GetDoc().IsLayoutRTL( GetTab() );
+ mbMirrorEntries = bLayoutRTL && mbHoriz;
+ mbMirrorLevels = bLayoutRTL && !mbHoriz;
+
+ bool bNew = (nNewSize != mnHeaderSize);
+ mnHeaderSize = nNewSize;
+ mnHeaderPos = mbMirrorEntries ? (GetOutputSizeEntry() - mnHeaderSize) : 0;
+ mnMainFirstPos = mbMirrorEntries ? 0 : mnHeaderSize;
+ mnMainLastPos = GetOutputSizeEntry() - (mbMirrorEntries ? mnHeaderSize : 0) - 1;
+ if ( bNew )
+ Invalidate();
+}
+
+long ScOutlineWindow::GetDepthSize() const
+{
+ long nSize = GetLevelCount() * SC_OL_BITMAPSIZE;
+ if ( nSize > 0 )
+ nSize += 2 * SC_OL_POSOFFSET + 1;
+ return nSize;
+}
+
+void ScOutlineWindow::ScrollPixel( long nDiff )
+{
+ HideFocus();
+ mbDontDrawFocus = true;
+
+ long nStart = mnMainFirstPos;
+ long nEnd = mnMainLastPos;
+
+ long nInvStart, nInvEnd;
+ if (nDiff < 0)
+ {
+ nStart -= nDiff;
+ nInvStart = nEnd + nDiff;
+ nInvEnd = nEnd;
+ }
+ else
+ {
+ nEnd -= nDiff;
+ nInvStart = nStart;
+ nInvEnd = nStart + nDiff;
+ }
+
+ ScrollRel( nDiff, nStart, nEnd );
+ Invalidate( GetRectangle( 0, nInvStart, GetOutputSizeLevel() - 1, nInvEnd ) );
+ Update();
+
+ // if focus becomes invisible, move it to next visible button
+ ImplMoveFocusToVisible( nDiff < 0 );
+
+ mbDontDrawFocus = false;
+ ShowFocus();
+}
+
+void ScOutlineWindow::ScrollRel( long nEntryDiff, long nEntryStart, long nEntryEnd )
+{
+ Rectangle aRect( GetRectangle( 0, nEntryStart, GetOutputSizeLevel() - 1, nEntryEnd ) );
+ if ( mbHoriz )
+ Scroll( nEntryDiff, 0, aRect );
+ else
+ Scroll( 0, nEntryDiff, aRect );
+}
+
+// internal -------------------------------------------------------------------
+
+void ScOutlineWindow::InitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ maLineColor = rStyleSettings.GetButtonTextColor();
+ mpSymbols = ScGlobal::GetOutlineSymbols( rStyleSettings.GetHighContrastMode() );
+ Invalidate();
+}
+
+const ScOutlineArray* ScOutlineWindow::GetOutlineArray() const
+{
+ const ScOutlineTable* pTable = GetDoc().GetOutlineTable( GetTab() );
+ if ( !pTable ) return NULL;
+ return mbHoriz ? pTable->GetColArray() : pTable->GetRowArray();
+}
+
+const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nEntry ) const
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ return pArray ? pArray->GetEntry( sal::static_int_cast<USHORT>(nLevel), sal::static_int_cast<USHORT>(nEntry) ) : NULL;
+}
+
+bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
+{
+ return mbHoriz ?
+ GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) :
+ GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab());
+}
+
+bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const
+{
+ // columns cannot be filtered
+ return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
+}
+
+bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
+{
+ bool bAllHidden = true;
+ for ( SCCOLROW nPos = 0; (nPos < nColRowIndex) && bAllHidden; ++nPos )
+ bAllHidden = IsHidden( nPos );
+ return bAllHidden;
+}
+
+void ScOutlineWindow::GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const
+{
+ if ( mbHoriz )
+ {
+ rnColRowStart = mrViewData.GetPosX( WhichH( meWhich ) );
+ rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsX( WhichH( meWhich ) );
+ }
+ else
+ {
+ rnColRowStart = mrViewData.GetPosY( WhichV( meWhich ) );
+ rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsY( WhichV( meWhich ) );
+ }
+
+ // include collapsed columns/rows in front of visible range
+ while ( (rnColRowStart > 0) && IsHidden( rnColRowStart - 1 ) )
+ --rnColRowStart;
+}
+
+Point ScOutlineWindow::GetPoint( long nLevelPos, long nEntryPos ) const
+{
+ return mbHoriz ? Point( nEntryPos, nLevelPos ) : Point( nLevelPos, nEntryPos );
+}
+
+Rectangle ScOutlineWindow::GetRectangle(
+ long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd ) const
+{
+ return Rectangle( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
+}
+
+long ScOutlineWindow::GetOutputSizeLevel() const
+{
+ Size aSize( GetOutputSizePixel() );
+ return mbHoriz ? aSize.Height() : aSize.Width();
+}
+
+long ScOutlineWindow::GetOutputSizeEntry() const
+{
+ Size aSize( GetOutputSizePixel() );
+ return mbHoriz ? aSize.Width() : aSize.Height();
+}
+
+size_t ScOutlineWindow::GetLevelCount() const
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ size_t nLevelCount = pArray ? pArray->GetDepth() : 0;
+ return nLevelCount ? (nLevelCount + 1) : 0;
+}
+
+long ScOutlineWindow::GetLevelPos( size_t nLevel ) const
+{
+ // #i51970# must always return the *left* edge of the area used by a level
+ long nPos = static_cast< long >( SC_OL_POSOFFSET + nLevel * SC_OL_BITMAPSIZE );
+ return mbMirrorLevels ? (GetOutputSizeLevel() - nPos - SC_OL_BITMAPSIZE) : nPos;
+}
+
+size_t ScOutlineWindow::GetLevelFromPos( long nLevelPos ) const
+{
+ if( mbMirrorLevels ) nLevelPos = GetOutputSizeLevel() - nLevelPos - 1;
+ long nStart = SC_OL_POSOFFSET;
+ if ( nLevelPos < nStart ) return SC_OL_NOLEVEL;
+ size_t nLevel = static_cast< size_t >( (nLevelPos - nStart) / SC_OL_BITMAPSIZE );
+ return (nLevel < GetLevelCount()) ? nLevel : SC_OL_NOLEVEL;
+}
+
+long ScOutlineWindow::GetColRowPos( SCCOLROW nColRowIndex ) const
+{
+ long nDocPos = mbHoriz ?
+ mrViewData.GetScrPos( static_cast<SCCOL>(nColRowIndex), 0, meWhich, TRUE ).X() :
+ mrViewData.GetScrPos( 0, static_cast<SCROW>(nColRowIndex), meWhich, TRUE ).Y();
+ return mnMainFirstPos + nDocPos;
+}
+
+long ScOutlineWindow::GetHeaderEntryPos() const
+{
+ return mnHeaderPos + (mnHeaderSize - SC_OL_BITMAPSIZE) / 2;
+}
+
+bool ScOutlineWindow::GetEntryPos(
+ size_t nLevel, size_t nEntry,
+ long& rnStartPos, long& rnEndPos, long& rnImagePos ) const
+{
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( !pEntry || !pEntry->IsVisible() )
+ return false;
+
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ long nEntriesSign = mbMirrorEntries ? -1 : 1;
+
+ // --- common calculation ---
+
+ rnStartPos = GetColRowPos( nStart );
+ rnEndPos = GetColRowPos( nEnd + 1 );
+
+ bool bHidden = IsHidden( nStart );
+ rnImagePos = bHidden ?
+ (rnStartPos - ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign) :
+ rnStartPos + nEntriesSign;
+ long nCenter = (rnStartPos + rnEndPos - SC_OL_BITMAPSIZE * nEntriesSign +
+ ( mbMirrorEntries ? 1 : 0 )) / 2L;
+ rnImagePos = mbMirrorEntries ? Max( rnImagePos, nCenter ) : Min( rnImagePos, nCenter );
+
+ // --- refinements ---
+
+ // do not cut leftmost/topmost image
+ if ( bHidden && IsFirstVisible( nStart ) )
+ rnImagePos = rnStartPos;
+
+ // do not cover previous collapsed image
+ if ( !bHidden && nEntry )
+ {
+ const ScOutlineEntry* pPrevEntry = GetOutlineEntry( nLevel, nEntry - 1 );
+ SCCOLROW nPrevEnd = pPrevEntry->GetEnd();
+ if ( (nPrevEnd + 1 == nStart) && IsHidden( nPrevEnd ) )
+ {
+ if ( IsFirstVisible( pPrevEntry->GetStart() ) )
+ rnStartPos += SC_OL_BITMAPSIZE * nEntriesSign;
+ else
+ rnStartPos += ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign;
+ rnImagePos = rnStartPos;
+ }
+ }
+
+ // restrict rnStartPos...rnEndPos to valid area
+ rnStartPos = std::max( rnStartPos, mnMainFirstPos );
+ rnEndPos = std::max( rnEndPos, mnMainFirstPos );
+
+ if ( mbMirrorEntries )
+ rnImagePos -= SC_OL_BITMAPSIZE - 1; // start pos aligns with right edge of bitmap
+
+ // --- all rows filtered? ---
+
+ bool bVisible = true;
+ if ( !mbHoriz )
+ {
+ bVisible = false;
+ for ( SCCOLROW nRow = nStart; (nRow <= nEnd) && !bVisible; ++nRow )
+ bVisible = !IsFiltered( nRow );
+ }
+ return bVisible;
+}
+
+bool ScOutlineWindow::GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const
+{
+ bool bRet = nLevel < GetLevelCount();
+ if ( bRet )
+ {
+ long nLevelPos = GetLevelPos( nLevel );
+ if ( nEntry == SC_OL_HEADERENTRY )
+ rPos = GetPoint( nLevelPos, GetHeaderEntryPos() );
+ else
+ {
+ long nStartPos, nEndPos, nImagePos;
+ bRet = GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos );
+ rPos = GetPoint( nLevelPos, nImagePos );
+ }
+ }
+ return bRet;
+}
+
+bool ScOutlineWindow::IsButtonVisible( size_t nLevel, size_t nEntry ) const
+{
+ bool bRet = false;
+ if ( nEntry == SC_OL_HEADERENTRY )
+ bRet = (mnHeaderSize > 0) && (nLevel < GetLevelCount());
+ else
+ {
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry && pEntry->IsVisible() )
+ {
+ SCCOLROW nStart, nEnd;
+ GetVisibleRange( nStart, nEnd );
+ bRet = (nStart <= pEntry->GetStart()) && (pEntry->GetStart() <= nEnd);
+ }
+ }
+ return bRet;
+}
+
+bool ScOutlineWindow::ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray ) return false;
+
+ SCCOLROW nStartIndex, nEndIndex;
+ GetVisibleRange( nStartIndex, nEndIndex );
+
+ size_t nLevel = GetLevelFromPos( mbHoriz ? rPos.Y() : rPos.X() );
+ if ( nLevel == SC_OL_NOLEVEL )
+ return false;
+
+// long nLevelPos = GetLevelPos( nLevel );
+ long nEntryMousePos = mbHoriz ? rPos.X() : rPos.Y();
+
+ // --- level buttons ---
+
+ if ( mnHeaderSize > 0 )
+ {
+ long nImagePos = GetHeaderEntryPos();
+ if ( (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
+ {
+ rnLevel = nLevel;
+ rnEntry = SC_OL_HEADERENTRY;
+ rbButton = true;
+ return true;
+ }
+ }
+
+ // --- expand/collapse buttons and expanded lines ---
+
+ // search outline entries backwards
+ size_t nEntry = pArray->GetCount( sal::static_int_cast<USHORT>(nLevel) );
+ while ( nEntry )
+ {
+ --nEntry;
+
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<USHORT>(nLevel),
+ sal::static_int_cast<USHORT>(nEntry) );
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( (nEnd >= nStartIndex) && (nStart <= nEndIndex) )
+ {
+ long nStartPos, nEndPos, nImagePos;
+ if ( GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos ) )
+ {
+ rnLevel = nLevel;
+ rnEntry = nEntry;
+
+ // button?
+ if ( (nStart >= nStartIndex) && (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
+ {
+ rbButton = true;
+ return true;
+ }
+
+ // line?
+ if ( mbMirrorEntries )
+ ::std::swap( nStartPos, nEndPos ); // in RTL mode, nStartPos is the larger value
+ if ( (nStartPos <= nEntryMousePos) && (nEntryMousePos <= nEndPos) )
+ {
+ rbButton = false;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool ScOutlineWindow::ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
+{
+ bool bButton;
+ bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
+ return bRet && bButton;
+}
+
+bool ScOutlineWindow::LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
+{
+ bool bButton;
+ bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
+ return bRet && !bButton;
+}
+
+void ScOutlineWindow::DoFunction( size_t nLevel, size_t nEntry ) const
+{
+ ScDBFunc& rFunc = *mrViewData.GetView();
+ if ( nEntry == SC_OL_HEADERENTRY )
+ rFunc.SelectLevel( mbHoriz, sal::static_int_cast<USHORT>(nLevel) );
+ else
+ {
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry )
+ {
+ if ( pEntry->IsHidden() )
+ rFunc.ShowOutline( mbHoriz, sal::static_int_cast<USHORT>(nLevel), sal::static_int_cast<USHORT>(nEntry) );
+ else
+ rFunc.HideOutline( mbHoriz, sal::static_int_cast<USHORT>(nLevel), sal::static_int_cast<USHORT>(nEntry) );
+ }
+ }
+}
+
+void ScOutlineWindow::DoExpand( size_t nLevel, size_t nEntry ) const
+{
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry && pEntry->IsHidden() )
+ DoFunction( nLevel, nEntry );
+}
+
+void ScOutlineWindow::DoCollapse( size_t nLevel, size_t nEntry ) const
+{
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry && !pEntry->IsHidden() )
+ DoFunction( nLevel, nEntry );
+}
+
+void ScOutlineWindow::Resize()
+{
+ Window::Resize();
+ SetHeaderSize( mnHeaderSize ); // recalculates header/group positions
+ if ( !IsFocusButtonVisible() )
+ {
+ HideFocus();
+ ShowFocus(); // calculates valid position
+ }
+}
+
+void ScOutlineWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ InitSettings();
+ Invalidate();
+ }
+ Window::DataChanged( rDCEvt );
+}
+
+// drawing --------------------------------------------------------------------
+
+void ScOutlineWindow::SetEntryAreaClipRegion()
+{
+ SetClipRegion( Rectangle(
+ GetPoint( 0, mnMainFirstPos ),
+ GetPoint( GetOutputSizeLevel() - 1, mnMainLastPos ) ) );
+}
+
+void ScOutlineWindow::DrawLineRel(
+ long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
+{
+ DrawLine( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
+}
+
+void ScOutlineWindow::DrawRectRel(
+ long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
+{
+ DrawRect( GetRectangle( nLevelStart, nEntryStart, nLevelEnd, nEntryEnd ) );
+}
+
+void ScOutlineWindow::DrawImageRel( long nLevelPos, long nEntryPos, USHORT nId )
+{
+ DBG_ASSERT( mpSymbols, "ScOutlineWindow::DrawImageRel - no images" );
+ const Image& rImage = mpSymbols->GetImage( nId );
+ SetLineColor();
+ SetFillColor( GetBackground().GetColor() );
+ Point aPos( GetPoint( nLevelPos, nEntryPos ) );
+ DrawRect( Rectangle( aPos, rImage.GetSizePixel() ) );
+ DrawImage( aPos, rImage );
+}
+
+void ScOutlineWindow::DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed )
+{
+ Point aPos;
+ if ( GetImagePos( nLevel, nEntry, aPos ) )
+ {
+ DBG_ASSERT( mpSymbols, "ScOutlineWindow::DrawBorderRel - no images" );
+ USHORT nId = bPressed ? SC_OL_IMAGE_PRESSED : SC_OL_IMAGE_NOTPRESSED;
+ bool bClip = (nEntry != SC_OL_HEADERENTRY);
+ if ( bClip )
+ SetEntryAreaClipRegion();
+ DrawImage( aPos, mpSymbols->GetImage( nId ) );
+ if ( bClip )
+ SetClipRegion();
+ }
+ mbMTPressed = bPressed;
+}
+
+void ScOutlineWindow::ShowFocus()
+{
+ if ( HasFocus() )
+ {
+ // first move to a visible position
+ ImplMoveFocusToVisible( true );
+
+ if ( IsFocusButtonVisible() )
+ {
+ Point aPos;
+ if ( GetImagePos( mnFocusLevel, mnFocusEntry, aPos ) )
+ {
+ aPos += Point( 1, 1 );
+ maFocusRect = Rectangle( aPos, Size( SC_OL_BITMAPSIZE - 2, SC_OL_BITMAPSIZE - 2 ) );
+ bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
+ if ( bClip )
+ SetEntryAreaClipRegion();
+ InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ if ( bClip )
+ SetClipRegion();
+ }
+ }
+ }
+}
+
+void ScOutlineWindow::HideFocus()
+{
+ if ( !maFocusRect.IsEmpty() )
+ {
+ bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
+ if ( bClip )
+ SetEntryAreaClipRegion();
+ InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ if ( bClip )
+ SetClipRegion();
+ maFocusRect.SetEmpty();
+ }
+}
+
+void ScOutlineWindow::Paint( const Rectangle& /* rRect */ )
+{
+ long nEntriesSign = mbMirrorEntries ? -1 : 1;
+ long nLevelsSign = mbMirrorLevels ? -1 : 1;
+
+ Size aSize = GetOutputSizePixel();
+ long nLevelEnd = (mbHoriz ? aSize.Height() : aSize.Width()) - 1;
+ long nEntryEnd = (mbHoriz ? aSize.Width() : aSize.Height()) - 1;
+
+ SetLineColor( maLineColor );
+ long nBorderPos = mbMirrorLevels ? 0 : nLevelEnd;
+ DrawLineRel( nBorderPos, 0, nBorderPos, nEntryEnd );
+
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray ) return;
+
+ size_t nLevelCount = GetLevelCount();
+
+ // --- draw header images ---
+
+ if ( mnHeaderSize > 0 )
+ {
+ long nEntryPos = GetHeaderEntryPos();
+ for ( size_t nLevel = 0; nLevel < nLevelCount; ++nLevel )
+ DrawImageRel( GetLevelPos( nLevel ), nEntryPos, static_cast< USHORT >( nLevel + 1 ) );
+
+ SetLineColor( maLineColor );
+ long nLinePos = mnHeaderPos + (mbMirrorEntries ? 0 : (mnHeaderSize - 1));
+ DrawLineRel( 0, nLinePos, nLevelEnd, nLinePos );
+ }
+
+ // --- draw lines & collapse/expand images ---
+
+ SetEntryAreaClipRegion();
+
+ SCCOLROW nStartIndex, nEndIndex;
+ GetVisibleRange( nStartIndex, nEndIndex );
+
+ for ( size_t nLevel = 0; nLevel + 1 < nLevelCount; ++nLevel )
+ {
+ long nLevelPos = GetLevelPos( nLevel );
+ long nEntryPos1 = 0, nEntryPos2 = 0, nImagePos = 0;
+
+ size_t nEntryCount = pArray->GetCount( sal::static_int_cast<USHORT>(nLevel) );
+ size_t nEntry;
+
+ // first draw all lines in the current level
+ SetLineColor();
+ SetFillColor( maLineColor );
+ for ( nEntry = 0; nEntry < nEntryCount; ++nEntry )
+ {
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<USHORT>(nLevel),
+ sal::static_int_cast<USHORT>(nEntry) );
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ // visible range?
+ bool bDraw = (nEnd >= nStartIndex) && (nStart <= nEndIndex);
+ // find output coordinates
+ if ( bDraw )
+ bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
+ // draw, if not collapsed
+ if ( bDraw && !pEntry->IsHidden() )
+ {
+ if ( nStart >= nStartIndex )
+ nEntryPos1 += nEntriesSign;
+ nEntryPos2 -= 2 * nEntriesSign;
+ long nLinePos = nLevelPos;
+ if ( mbMirrorLevels )
+ nLinePos += SC_OL_BITMAPSIZE - 1; // align with right edge of bitmap
+ DrawRectRel( nLinePos, nEntryPos1, nLinePos + nLevelsSign, nEntryPos2 );
+
+ if ( nEnd <= nEndIndex )
+ DrawRectRel( nLinePos, nEntryPos2 - nEntriesSign,
+ nLinePos + ( SC_OL_BITMAPSIZE / 3 ) * nLevelsSign, nEntryPos2 );
+ }
+ }
+
+ // draw all images in the level from last to first
+ nEntry = nEntryCount;
+ while ( nEntry )
+ {
+ --nEntry;
+
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<USHORT>(nLevel),
+ sal::static_int_cast<USHORT>(nEntry) );
+ SCCOLROW nStart = pEntry->GetStart();
+// SCCOLROW nEnd = pEntry->GetEnd();
+
+ // visible range?
+ bool bDraw = (nStartIndex <= nStart) && (nStart <= nEndIndex + 1);
+ // find output coordinates
+ if ( bDraw )
+ bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
+ // draw, if not hidden by higher levels
+ if ( bDraw )
+ {
+ USHORT nImageId = pEntry->IsHidden() ? SC_OL_IMAGE_PLUS : SC_OL_IMAGE_MINUS;
+ DrawImageRel( nLevelPos, nImagePos, nImageId );
+ }
+ }
+ }
+
+ SetClipRegion();
+
+ if ( !mbDontDrawFocus )
+ ShowFocus();
+}
+
+// focus ----------------------------------------------------------------------
+
+/** Increments or decrements a value and wraps at the specified limits.
+ @return true = value wrapped. */
+bool lcl_RotateValue( size_t& rnValue, size_t nMin, size_t nMax, bool bForward )
+{
+ DBG_ASSERT( nMin <= nMax, "lcl_RotateValue - invalid range" );
+ DBG_ASSERT( nMax < static_cast< size_t >( -1 ), "lcl_RotateValue - range overflow" );
+ bool bWrap = false;
+ if ( bForward )
+ {
+ if ( rnValue < nMax )
+ ++rnValue;
+ else
+ {
+ rnValue = nMin;
+ bWrap = true;
+ }
+ }
+ else
+ {
+ if ( rnValue > nMin )
+ --rnValue;
+ else
+ {
+ rnValue = nMax;
+ bWrap = true;
+ }
+ }
+ return bWrap;
+}
+
+bool ScOutlineWindow::IsFocusButtonVisible() const
+{
+ return IsButtonVisible( mnFocusLevel, mnFocusEntry );
+}
+
+bool ScOutlineWindow::ImplMoveFocusByEntry( bool bForward, bool bFindVisible )
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray )
+ return false;
+
+ bool bWrapped = false;
+ size_t nEntryCount = pArray->GetCount( sal::static_int_cast<USHORT>(mnFocusLevel) );
+ // #i29530# entry count may be decreased after changing active sheet
+ if( mnFocusEntry >= nEntryCount )
+ mnFocusEntry = SC_OL_HEADERENTRY;
+ size_t nOldEntry = mnFocusEntry;
+
+ do
+ {
+ if ( mnFocusEntry == SC_OL_HEADERENTRY )
+ {
+ // move from header to first or last entry
+ if ( nEntryCount > 0 )
+ mnFocusEntry = bForward ? 0 : (nEntryCount - 1);
+ /* wrapped, if forward from right header to first entry,
+ or if backward from left header to last entry */
+ // Header and entries are now always in consistent order,
+ // so there's no need to check for mirroring here.
+ if ( !nEntryCount || !bForward )
+ bWrapped = true;
+ }
+ else if ( lcl_RotateValue( mnFocusEntry, 0, nEntryCount - 1, bForward ) )
+ {
+ // lcl_RotateValue returns true -> wrapped the entry range -> move to header
+ mnFocusEntry = SC_OL_HEADERENTRY;
+ /* wrapped, if forward from last entry to left header,
+ or if backward from first entry to right header */
+ if ( bForward )
+ bWrapped = true;
+ }
+ }
+ while ( bFindVisible && !IsFocusButtonVisible() && (nOldEntry != mnFocusEntry) );
+
+ return bWrapped;
+}
+
+bool ScOutlineWindow::ImplMoveFocusByLevel( bool bForward )
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray )
+ return false;
+
+ bool bWrapped = false;
+ size_t nLevelCount = GetLevelCount();
+
+ if ( mnFocusEntry == SC_OL_HEADERENTRY )
+ {
+ if ( nLevelCount > 0 )
+ bWrapped = lcl_RotateValue( mnFocusLevel, 0, nLevelCount - 1, bForward );
+ }
+ else
+ {
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<USHORT>(mnFocusLevel),
+ sal::static_int_cast<USHORT>(mnFocusEntry) );
+ if ( pEntry )
+ {
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+ size_t nNewLevel = mnFocusLevel;
+ size_t nNewEntry = 0;
+
+ bool bFound = false;
+ if ( bForward && (mnFocusLevel + 2 < nLevelCount) )
+ {
+ // next level -> find first child entry
+ nNewLevel = mnFocusLevel + 1;
+ // TODO - change ScOutlineArray interface to size_t usage
+ USHORT nTmpEntry = 0;
+ bFound = pArray->GetEntryIndexInRange( sal::static_int_cast<USHORT>(nNewLevel), nStart, nEnd, nTmpEntry );
+ nNewEntry = nTmpEntry;
+ }
+ else if ( !bForward && (mnFocusLevel > 0) )
+ {
+ // previous level -> find parent entry
+ nNewLevel = mnFocusLevel - 1;
+ // TODO - change ScOutlineArray interface to size_t usage
+ USHORT nTmpEntry = 0;
+ bFound = pArray->GetEntryIndex( sal::static_int_cast<USHORT>(nNewLevel), nStart, nTmpEntry );
+ nNewEntry = nTmpEntry;
+ }
+
+ if ( bFound && IsButtonVisible( nNewLevel, nNewEntry ) )
+ {
+ mnFocusLevel = nNewLevel;
+ mnFocusEntry = nNewEntry;
+ }
+ }
+ }
+
+ return bWrapped;
+}
+
+bool ScOutlineWindow::ImplMoveFocusByTabOrder( bool bForward, bool bFindVisible )
+{
+ bool bRet = false;
+ size_t nOldLevel = mnFocusLevel;
+ size_t nOldEntry = mnFocusEntry;
+
+ do
+ {
+ /* one level up, if backward from left header,
+ or one level down, if forward from right header */
+ if ( (!bForward) && (mnFocusEntry == SC_OL_HEADERENTRY) )
+ bRet |= ImplMoveFocusByLevel( bForward );
+ // move to next/previous entry
+ bool bWrapInLevel = ImplMoveFocusByEntry( bForward, false );
+ bRet |= bWrapInLevel;
+ /* one level up, if wrapped backward to right header,
+ or one level down, if wrapped forward to right header */
+ if ( bForward && bWrapInLevel )
+ bRet |= ImplMoveFocusByLevel( bForward );
+ }
+ while ( bFindVisible && !IsFocusButtonVisible() && ((nOldLevel != mnFocusLevel) || (nOldEntry != mnFocusEntry)) );
+
+ return bRet;
+}
+
+void ScOutlineWindow::ImplMoveFocusToVisible( bool bForward )
+{
+ // first try to find an entry in the same level
+ if ( !IsFocusButtonVisible() )
+ ImplMoveFocusByEntry( bForward, true );
+ // then try to find any other entry
+ if ( !IsFocusButtonVisible() )
+ ImplMoveFocusByTabOrder( bForward, true );
+}
+
+void ScOutlineWindow::MoveFocusByEntry( bool bForward )
+{
+ HideFocus();
+ ImplMoveFocusByEntry( bForward, true );
+ ShowFocus();
+}
+
+void ScOutlineWindow::MoveFocusByLevel( bool bForward )
+{
+ HideFocus();
+ ImplMoveFocusByLevel( bForward );
+ ShowFocus();
+}
+
+void ScOutlineWindow::MoveFocusByTabOrder( bool bForward )
+{
+ HideFocus();
+ ImplMoveFocusByTabOrder( bForward, true );
+ ShowFocus();
+}
+
+void ScOutlineWindow::GetFocus()
+{
+ Window::GetFocus();
+ ShowFocus();
+}
+
+void ScOutlineWindow::LoseFocus()
+{
+ HideFocus();
+ Window::LoseFocus();
+}
+
+
+// mouse ----------------------------------------------------------------------
+
+void ScOutlineWindow::StartMouseTracking( size_t nLevel, size_t nEntry )
+{
+ mbMTActive = true;
+ mnMTLevel = nLevel;
+ mnMTEntry = nEntry;
+ DrawBorderRel( nLevel, nEntry, true );
+}
+
+void ScOutlineWindow::EndMouseTracking()
+{
+ if ( mbMTPressed )
+ DrawBorderRel( mnMTLevel, mnMTEntry, false );
+ mbMTActive = false;
+}
+
+void ScOutlineWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( IsMouseTracking() )
+ {
+ size_t nLevel, nEntry;
+ bool bHit = false;
+
+ if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
+ bHit = (nLevel == mnMTLevel) && (nEntry == mnMTEntry);
+
+ if ( bHit != mbMTPressed )
+ DrawBorderRel( mnMTLevel, mnMTEntry, bHit );
+ }
+}
+
+void ScOutlineWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( IsMouseTracking() )
+ {
+ EndMouseTracking();
+
+ size_t nLevel, nEntry;
+ if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
+ if ( (nLevel == mnMTLevel) && (nEntry == mnMTEntry) )
+ DoFunction( nLevel, nEntry );
+ }
+}
+
+void ScOutlineWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ size_t nLevel, nEntry;
+ bool bHit = ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry );
+ if ( bHit )
+ StartMouseTracking( nLevel, nEntry );
+ else if ( rMEvt.GetClicks() == 2 )
+ {
+ bHit = LineHit( rMEvt.GetPosPixel(), nLevel, nEntry );
+ if ( bHit )
+ DoFunction( nLevel, nEntry );
+ }
+
+ // if an item has been hit and window is focused, move focus to this item
+ if ( bHit && HasFocus() )
+ {
+ HideFocus();
+ mnFocusLevel = nLevel;
+ mnFocusEntry = nEntry;
+ ShowFocus();
+ }
+}
+
+
+// keyboard -------------------------------------------------------------------
+
+void ScOutlineWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ const KeyCode& rKCode = rKEvt.GetKeyCode();
+ bool bNoMod = !rKCode.GetModifier();
+ bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
+ bool bCtrl = (rKCode.GetModifier() == KEY_MOD1);
+
+ USHORT nCode = rKCode.GetCode();
+ bool bUpDownKey = (nCode == KEY_UP) || (nCode == KEY_DOWN);
+ bool bLeftRightKey = (nCode == KEY_LEFT) || (nCode == KEY_RIGHT);
+
+ // TAB key
+ if ( (nCode == KEY_TAB) && (bNoMod || bShift) )
+ // move forward without SHIFT key
+ MoveFocusByTabOrder( bNoMod ); // TAB uses logical order, regardless of mirroring
+
+ // LEFT/RIGHT/UP/DOWN keys
+ else if ( bNoMod && (bUpDownKey || bLeftRightKey) )
+ {
+ bool bForward = (nCode == KEY_DOWN) || (nCode == KEY_RIGHT);
+ if ( mbHoriz == bLeftRightKey )
+ // move inside level with LEFT/RIGHT in horizontal and with UP/DOWN in vertical
+ MoveFocusByEntry( bForward != mbMirrorEntries );
+ else
+ // move to next/prev level with LEFT/RIGHT in vertical and with UP/DOWN in horizontal
+ MoveFocusByLevel( bForward != mbMirrorLevels );
+ }
+
+ // CTRL + number
+ else if ( bCtrl && (nCode >= KEY_1) && (nCode <= KEY_9) )
+ {
+ size_t nLevel = static_cast< size_t >( nCode - KEY_1 );
+ if ( nLevel < GetLevelCount() )
+ DoFunction( nLevel, SC_OL_HEADERENTRY );
+ }
+
+ // other key codes
+ else switch ( rKCode.GetFullCode() )
+ {
+ case KEY_ADD: DoExpand( mnFocusLevel, mnFocusEntry ); break;
+ case KEY_SUBTRACT: DoCollapse( mnFocusLevel, mnFocusEntry ); break;
+ case KEY_SPACE:
+ case KEY_RETURN: DoFunction( mnFocusLevel, mnFocusEntry ); break;
+ default: Window::KeyInput( rKEvt );
+ }
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/olkact.cxx b/sc/source/ui/view/olkact.cxx
new file mode 100644
index 000000000000..248777f4e473
--- /dev/null
+++ b/sc/source/ui/view/olkact.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+
+//------------------------------------------------------------------
+
+#define _BIGINT_HXX
+#define _CACHESTR_HXX
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _CTRLTOOL_HXX
+#define _DLGCFG_HXX
+#define _DYNARR_HXX
+#define _EXTATTR_HXX
+#define _FILDLG_HXX
+#define _FONTDLG_HXX
+#define _FRM3D_HXX
+#define _INTRO_HXX
+#define _ISETBWR_HXX
+#define _NO_SVRTF_PARSER_HXX
+#define _MACRODLG_HXX
+#define _MODALDLG_HXX
+#define _MOREBUTTON_HXX
+#define _OUTLINER_HXX
+#define _PASSWD_HXX
+#define _PRNDLG_HXX
+//#define _POLY_HXX
+#define _PVRWIN_HXX
+#define _QUEUE_HXX
+#define _RULER_HXX
+#define _SCRWIN_HXX
+#define _SETBRW_HXX
+#define _STACK_HXX
+//#define _STATUS_HXX ***
+#define _STDMENU_HXX
+#define _TABBAR_HXX
+//#define _VCBRW_HXX
+#define _VCTRLS_HXX
+//#define _VCSBX_HXX
+#define _VCONT_HXX
+#define _VDRWOBJ_HXX
+
+
+//sfx
+#define _SFXAPPWIN_HXX
+#define _SFXCTRLITEM
+#define _SFXDISPATCH_HXX
+#define _SFXFILEDLG_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXIPFRM_HXX
+#define _SFX_MACRO_HXX
+#define _SFXMULTISEL_HXX
+#define _SFX_MINFITEM_HXX
+
+
+//sfxcore.hxx
+//#define _SFXINIMGR_HXX ***
+//#define _SFXCFGITEM_HXX
+//#define _SFX_PRINTER_HXX
+#define _SFXGENLINK_HXX
+#define _SFXHINTPOST_HXX
+#define _SFXDOCINF_HXX
+#define _SFXLINKHDL_HXX
+//#define _SFX_PROGRESS_HXX
+
+//sfxsh.hxx
+//#define _SFX_SHELL_HXX
+//#define _SFXAPP_HXX
+//#define _SFXDISPATCH_HXX
+//#define _SFXMSG_HXX ***
+//#define _SFXOBJFACE_HXX ***
+//#define _SFXREQUEST_HXX
+#define _SFXMACRO_HXX
+
+// SFX
+//#define _SFXAPPWIN_HXX ***
+#define _SFX_SAVEOPT_HXX
+//#define _SFX_CHILDWIN_HXX
+//#define _SFXCTRLITEM_HXX
+#define _SFXPRNMON_HXX
+#define _INTRO_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXFILEDLG_HXX
+#define _PASSWD_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXSTBMGR_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXEVENT_HXX
+
+//sfxdoc.hxx
+//#define _SFX_OBJSH_HXX
+//#define _SFX_CLIENTSH_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFX_OBJFAC_HXX
+#define _SFX_DOCFILT_HXX
+//#define _SFXDOCFILE_HXX ***
+//define _VIEWFAC_HXX
+//#define _SFXVIEWFRM_HXX
+//#define _SFXVIEWSH_HXX
+//#define _MDIFRM_HXX ***
+#define _SFX_IPFRM_HXX
+//#define _SFX_INTERNO_HXX
+
+//sfxdlg.hxx
+//#define _SFXTABDLG_HXX
+//#define _BASEDLGS_HXX ***
+#define _SFX_DINFDLG_HXX
+#define _SFXDINFEDT_HXX
+#define _SFX_MGETEMPL_HXX
+#define _SFX_TPLPITEM_HXX
+//#define _SFX_STYLEDLG_HXX
+#define _NEWSTYLE_HXX
+//#define _SFXDOCTEMPL_HXX ***
+//#define _SFXDOCTDLG_HXX ***
+//#define _SFX_TEMPLDLG_HXX ***
+//#define _SFXNEW_HXX ***
+#define _SFXDOCMAN_HXX
+//#define _SFXDOCKWIN_HXX
+
+//sfxitems.hxx
+#define _SFX_WHMAP_HXX
+#define _ARGS_HXX
+//#define _SFXPOOLITEM_HXX
+//#define _SFXINTITEM_HXX
+//#define _SFXENUMITEM_HXX
+#define _SFXFLAGITEM_HXX
+//#define _SFXSTRITEM_HXX
+#define _SFXPTITEM_HXX
+#define _SFXRECTITEM_HXX
+//#define _SFXITEMPOOL_HXX
+//#define _SFXITEMSET_HXX
+#define _SFXITEMITER_HXX
+#define _SFX_WHITER_HXX
+#define _SFXPOOLCACH_HXX
+//#define _AEITEM_HXX
+#define _SFXRNGITEM_HXX
+//#define _SFXSLSTITM_HXX
+//#define _SFXSTYLE_HXX
+
+//xout.hxx
+//#define _XENUM_HXX
+//#define _XPOLY_HXX
+//#define _XATTR_HXX
+//#define _XOUTX_HXX
+//#define _XPOOL_HXX
+//#define _XTABLE_HXX
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+//#define _SDR_NOOBJECTS
+//#define _SDR_NOVIEWS
+
+
+
+
+#define _SFXBASIC_HXX
+#define _SFX_DOCFILE_HXX
+#define _SFX_DOCFILT_HXX
+#define _SFX_DOCINF_HXX
+#define _SFX_DOCSH_HXX
+#define _SFX_TEMPLDLG_HXX
+#define _SFXSTBMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXFILEDLG_HXX
+#define _SFXREQUEST_HXX
+#define _SFXOBJFACE_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSG_HXX
+#define _SFX_PRNMON_HXX
+
+//si
+#define _SI_NOSBXCONTROLS
+#define _SI_NOCONTROL
+//#define SI_NOITEMS
+//#define SI_NODRW
+//#define SI_NOOTHERFORMS
+#define _SIDLL_HXX
+//#define _VCSBX_HXX
+//#define _VCBRW_HXX
+
+//#define _SVDATTR_HXX <--- der wars
+#define _SVDXOUT_HXX
+#define _SVDEC_HXX
+//#define _SVDIO_HXX
+//#define _SVDLAYER_HXX
+//#define _SVDRAG_HXX
+#define _SVINCVW_HXX
+//#define _SV_MULTISEL_HXX
+#define _SVRTV_HXX
+#define _SVTABBX_HXX
+
+#define _SVX_DAILDLL_HXX
+#define _SVX_HYPHEN_HXX
+#define _SVX_IMPGRF_HXX
+#define _SVX_OPTITEMS_HXX
+#define _SVX_OPTGERL_HXX
+#define _SVX_OPTSAVE_HXX
+#define _SVX_OPTSPELL_HXX
+#define _SVX_OPTPATH_HXX
+#define _SVX_OPTLINGU_HXX
+#define _SVX_RULER_HXX
+#define _SVX_RULRITEM_HXX
+#define _SVX_SPLWRAP_HXX
+#define _SVX_SPLDLG_HXX
+#define _SVX_THESDLG_HXX
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/childwin.hxx>
+#include <sfx2/objsh.hxx>
+
+#include "document.hxx"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "drawpage.hxx"
+#include "drwlayer.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+void ActivateOlk( ScViewData* /* pViewData */ )
+{
+ // Browser fuer Virtual Controls fuellen
+ // VC's und den Browser dazu gibts nicht mehr...
+
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+void DeActivateOlk( ScViewData* /* pViewData */ )
+{
+ // Browser fuer Virtual Controls fuellen
+ // VC's und den Browser dazu gibts nicht mehr...
+
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
new file mode 100644
index 000000000000..7b27ddf3f8cc
--- /dev/null
+++ b/sc/source/ui/view/output.cxx
@@ -0,0 +1,2476 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <com/sun/star/embed/EmbedMisc.hpp>
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editdata.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/svxfont.hxx>
+#include <svx/svdoole2.hxx>
+#include <tools/poly.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svx/framelinkarray.hxx>
+
+#include "output.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "tabvwsh.hxx"
+#include "progress.hxx"
+#include "pagedata.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "viewutil.hxx"
+#include "gridmerg.hxx"
+#include "invmerge.hxx"
+#include "fillinfo.hxx"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "postit.hxx"
+
+#include <math.h>
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+// Farben fuer ChangeTracking "nach Autor" wie im Writer (swmodul1.cxx)
+
+#define SC_AUTHORCOLORCOUNT 9
+
+static ColorData nAuthorColor[ SC_AUTHORCOLORCOUNT ] = {
+ COL_LIGHTRED, COL_LIGHTBLUE, COL_LIGHTMAGENTA,
+ COL_GREEN, COL_RED, COL_BLUE,
+ COL_BROWN, COL_MAGENTA, COL_CYAN };
+
+// Hilfsklasse, fuer die Farbzuordnung,
+// um nicht mehrfach hintereinander denselben User aus der Liste zu suchen
+
+class ScActionColorChanger
+{
+private:
+ const ScAppOptions& rOpt;
+ const ScStrCollection& rUsers;
+ String aLastUserName;
+ USHORT nLastUserIndex;
+ ColorData nColor;
+
+public:
+ ScActionColorChanger( const ScChangeTrack& rTrack );
+ ~ScActionColorChanger() {}
+
+ void Update( const ScChangeAction& rAction );
+ ColorData GetColor() const { return nColor; }
+};
+
+//------------------------------------------------------------------
+
+ScActionColorChanger::ScActionColorChanger( const ScChangeTrack& rTrack ) :
+ rOpt( SC_MOD()->GetAppOptions() ),
+ rUsers( rTrack.GetUserCollection() ),
+ nLastUserIndex( 0 ),
+ nColor( COL_BLACK )
+{
+}
+
+void ScActionColorChanger::Update( const ScChangeAction& rAction )
+{
+ ColorData nSetColor;
+ switch (rAction.GetType())
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ nSetColor = rOpt.GetTrackInsertColor();
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ nSetColor = rOpt.GetTrackDeleteColor();
+ break;
+ case SC_CAT_MOVE:
+ nSetColor = rOpt.GetTrackMoveColor();
+ break;
+ default:
+ nSetColor = rOpt.GetTrackContentColor();
+ break;
+ }
+ if ( nSetColor != COL_TRANSPARENT ) // Farbe eingestellt
+ nColor = nSetColor;
+ else // nach Autor
+ {
+ if ( rAction.GetUser() != aLastUserName )
+ {
+ aLastUserName = rAction.GetUser();
+ StrData aData(aLastUserName);
+ USHORT nIndex;
+ if (!rUsers.Search(&aData, nIndex))
+ {
+ // empty string is possible if a name wasn't found while saving a 5.0 file
+ DBG_ASSERT( aLastUserName.Len() == 0, "Author not found" );
+ nIndex = 0;
+ }
+ nLastUserIndex = nIndex % SC_AUTHORCOLORCOUNT;
+ }
+ nColor = nAuthorColor[nLastUserIndex];
+ }
+}
+
+//==================================================================
+
+ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
+ ScTableInfo& rTabInfo, ScDocument* pNewDoc,
+ SCTAB nNewTab, long nNewScrX, long nNewScrY,
+ SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2,
+ double nPixelPerTwipsX, double nPixelPerTwipsY,
+ const Fraction* pZoomX, const Fraction* pZoomY ) :
+ pDev( pNewDev ),
+ pRefDevice( pNewDev ), // default is output device
+ pFmtDevice( pNewDev ), // default is output device
+ mrTabInfo( rTabInfo ),
+ pRowInfo( rTabInfo.mpRowInfo ),
+ nArrCount( rTabInfo.mnArrCount ),
+ pDoc( pNewDoc ),
+ nTab( nNewTab ),
+ nScrX( nNewScrX ),
+ nScrY( nNewScrY ),
+ nX1( nNewX1 ),
+ nY1( nNewY1 ),
+ nX2( nNewX2 ),
+ nY2( nNewY2 ),
+ eType( eNewType ),
+ nPPTX( nPixelPerTwipsX ),
+ nPPTY( nPixelPerTwipsY ),
+ pEditObj( NULL ),
+ pViewShell( NULL ),
+ pDrawView( NULL ), // #114135#
+ bEditMode( FALSE ),
+ bMetaFile( FALSE ),
+ bSingleGrid( FALSE ),
+ bPagebreakMode( FALSE ),
+ bSolidBackground( FALSE ),
+ bUseStyleColor( FALSE ),
+ bForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
+ bSyntaxMode( FALSE ),
+ pValueColor( NULL ),
+ pTextColor( NULL ),
+ pFormulaColor( NULL ),
+ aGridColor( COL_BLACK ),
+ bShowNullValues( TRUE ),
+ bShowFormulas( FALSE ),
+ bShowSpellErrors( FALSE ),
+ bMarkClipped( FALSE ), // FALSE fuer Drucker/Metafile etc.
+ bSnapPixel( FALSE ),
+ bAnyRotated( FALSE ),
+ bAnyClipped( FALSE ),
+ mpTargetPaintWindow(0) // #i74769# use SdrPaintWindow direct
+{
+ if (pZoomX)
+ aZoomX = *pZoomX;
+ else
+ aZoomX = Fraction(1,1);
+ if (pZoomY)
+ aZoomY = *pZoomY;
+ else
+ aZoomY = Fraction(1,1);
+
+ nVisX1 = nX1;
+ nVisY1 = nY1;
+ nVisX2 = nX2;
+ nVisY2 = nY2;
+ pDoc->StripHidden( nVisX1, nVisY1, nVisX2, nVisY2, nTab );
+
+ nScrW = 0;
+ for (SCCOL nX=nVisX1; nX<=nVisX2; nX++)
+ nScrW += pRowInfo[0].pCellInfo[nX+1].nWidth;
+
+ nMirrorW = nScrW;
+
+ nScrH = 0;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ nScrH += pRowInfo[nArrY].nHeight;
+
+ bTabProtected = pDoc->IsTabProtected( nTab );
+ nTabTextDirection = pDoc->GetEditTextDirection( nTab );
+ bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+}
+
+ScOutputData::~ScOutputData()
+{
+ delete pValueColor;
+ delete pTextColor;
+ delete pFormulaColor;
+}
+
+void ScOutputData::SetContentDevice( OutputDevice* pContentDev )
+{
+ // use pContentDev instead of pDev where used
+
+ if ( pRefDevice == pDev )
+ pRefDevice = pContentDev;
+ if ( pFmtDevice == pDev )
+ pFmtDevice = pContentDev;
+ pDev = pContentDev;
+}
+
+void ScOutputData::SetMirrorWidth( long nNew )
+{
+ nMirrorW = nNew;
+}
+
+void ScOutputData::SetGridColor( const Color& rColor )
+{
+ aGridColor = rColor;
+}
+
+void ScOutputData::SetMarkClipped( BOOL bSet )
+{
+ bMarkClipped = bSet;
+}
+
+void ScOutputData::SetShowNullValues( BOOL bSet )
+{
+ bShowNullValues = bSet;
+}
+
+void ScOutputData::SetShowFormulas( BOOL bSet )
+{
+ bShowFormulas = bSet;
+}
+
+void ScOutputData::SetShowSpellErrors( BOOL bSet )
+{
+ bShowSpellErrors = bSet;
+}
+
+void ScOutputData::SetSnapPixel( BOOL bSet )
+{
+ bSnapPixel = bSet;
+}
+
+void ScOutputData::SetEditCell( SCCOL nCol, SCROW nRow )
+{
+ nEditCol = nCol;
+ nEditRow = nRow;
+ bEditMode = TRUE;
+}
+
+void ScOutputData::SetMetaFileMode( BOOL bNewMode )
+{
+ bMetaFile = bNewMode;
+}
+
+void ScOutputData::SetSingleGrid( BOOL bNewMode )
+{
+ bSingleGrid = bNewMode;
+}
+
+void ScOutputData::SetSyntaxMode( BOOL bNewMode )
+{
+ bSyntaxMode = bNewMode;
+ if (bNewMode)
+ if (!pValueColor)
+ {
+ pValueColor = new Color( COL_LIGHTBLUE );
+ pTextColor = new Color( COL_BLACK );
+ pFormulaColor = new Color( COL_GREEN );
+ }
+}
+
+void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage )
+{
+ SCCOL nX;
+ SCROW nY;
+ long nPosX;
+ long nPosY;
+ SCSIZE nArrY;
+ ScBreakType nBreak = BREAK_NONE;
+ ScBreakType nBreakOld = BREAK_NONE;
+
+ BOOL bSingle;
+ Color aPageColor;
+ Color aManualColor;
+
+ if (bPagebreakMode)
+ bPage = FALSE; // keine "normalen" Umbrueche ueber volle Breite/Hoehe
+
+ //! um den einen Pixel sieht das Metafile (oder die Druck-Ausgabe) anders aus
+ //! als die Bildschirmdarstellung, aber wenigstens passen Druck und Metafile zusammen
+
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+ if (bMetaFile)
+ nOneX = nOneY = 1;
+
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ long nSignedOneX = nOneX * nLayoutSign;
+
+ if ( eType == OUTTYPE_WINDOW )
+ {
+ const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
+ aPageColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor );
+ aManualColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
+ }
+ else
+ {
+ aPageColor = aGridColor;
+ aManualColor = aGridColor;
+ }
+
+ pDev->SetLineColor( aGridColor );
+ ScGridMerger aGrid( pDev, nOneX, nOneY );
+
+ //
+ // Vertikale Linien
+ //
+
+ nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - nOneX;
+
+ for (nX=nX1; nX<=nX2; nX++)
+ {
+ SCCOL nXplus1 = nX+1;
+ SCCOL nXplus2 = nX+2;
+ USHORT nWidth = pRowInfo[0].pCellInfo[nXplus1].nWidth;
+ if (nWidth)
+ {
+ nPosX += nWidth * nLayoutSign;
+
+ if ( bPage )
+ {
+ // Seitenumbrueche auch in ausgeblendeten suchen
+ SCCOL nCol = nXplus1;
+ while (nCol <= MAXCOL)
+ {
+ nBreak = pDoc->HasColBreak(nCol, nTab);
+ bool bHidden = pDoc->ColHidden(nCol, nTab);
+
+ if ( nBreak || !bHidden )
+ break;
+ ++nCol;
+ }
+
+ if (nBreak != nBreakOld)
+ {
+ aGrid.Flush();
+ pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
+ nBreak ? aPageColor : aGridColor );
+ nBreakOld = nBreak;
+ }
+ }
+
+ BOOL bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt
+
+ //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
+ //! Umbruch mitten in den Wiederholungsspalten liegt.
+ //! Dann lieber den aeusseren Rahmen zweimal ausgeben...
+#if 0
+ // auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
+ if ( eType == OUTTYPE_PRINTER && !bMetaFile )
+ {
+ if ( nX == MAXCOL )
+ bDraw = FALSE;
+ else if (pDoc->HasColBreak(nXplus1, nTab))
+ bDraw = FALSE;
+ }
+#endif
+
+ USHORT nWidthXplus2 = pRowInfo[0].pCellInfo[nXplus2].nWidth;
+ bSingle = bSingleGrid; //! in Fillinfo holen !!!!!
+ if ( nX<MAXCOL && !bSingle )
+ {
+ bSingle = ( nWidthXplus2 == 0 );
+ for (nArrY=1; nArrY+1<nArrCount && !bSingle; nArrY++)
+ {
+ if (pRowInfo[nArrY].pCellInfo[nXplus2].bHOverlapped)
+ bSingle = TRUE;
+ if (pRowInfo[nArrY].pCellInfo[nXplus1].bHideGrid)
+ bSingle = TRUE;
+ }
+ }
+
+ if (bDraw)
+ {
+ if ( nX<MAXCOL && bSingle )
+ {
+ SCCOL nVisX = nXplus1;
+ while ( nVisX < MAXCOL && !pDoc->GetColWidth(nVisX,nTab) )
+ ++nVisX;
+
+ nPosY = nScrY;
+ long nNextY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ nNextY = nPosY + pThisRowInfo->nHeight;
+
+ BOOL bHOver = pThisRowInfo->pCellInfo[nXplus1].bHideGrid;
+ if (!bHOver)
+ {
+ if (nWidthXplus2)
+ bHOver = pThisRowInfo->pCellInfo[nXplus2].bHOverlapped;
+ else
+ {
+ if (nVisX <= nX2)
+ bHOver = pThisRowInfo->pCellInfo[nVisX+1].bHOverlapped;
+ else
+ bHOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ nVisX,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
+ ->IsHorOverlapped();
+ if (bHOver)
+ bHOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ nXplus1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
+ ->IsHorOverlapped();
+ }
+ }
+
+ if (pThisRowInfo->bChanged && !bHOver)
+ {
+ //Point aStart( nPosX-nSignedOneX, nPosY );
+ //Point aEnd( nPosX-nSignedOneX, nNextY-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddVerLine( nPosX-nSignedOneX, nPosY, nNextY-nOneY );
+ }
+ nPosY = nNextY;
+ }
+ }
+ else
+ {
+ //Point aStart( nPosX-nSignedOneX, nScrY );
+ //Point aEnd( nPosX-nSignedOneX, nScrY+nScrH-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddVerLine( nPosX-nSignedOneX, nScrY, nScrY+nScrH-nOneY );
+ }
+ }
+ }
+ }
+
+ //
+ // Horizontale Linien
+ //
+
+ bool bHiddenRow = true;
+ SCROW nHiddenEndRow = -1;
+ nPosY = nScrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ SCSIZE nArrYplus1 = nArrY+1;
+ nY = pRowInfo[nArrY].nRowNo;
+ SCROW nYplus1 = nY+1;
+ nPosY += pRowInfo[nArrY].nHeight;
+
+ if (pRowInfo[nArrY].bChanged)
+ {
+ if ( bPage )
+ {
+ for (SCROW i = nYplus1; i <= MAXROW; ++i)
+ {
+ if (i > nHiddenEndRow)
+ bHiddenRow = pDoc->RowHidden(i, nTab, nHiddenEndRow);
+ /* TODO: optimize the row break thing for large hidden
+ * segments where HasRowBreak() has to be called
+ * nevertheless for each row, as a row break is drawn also
+ * for hidden rows, above them. This needed to be done only
+ * once per hidden segment, maybe giving manual breaks
+ * priority. Something like GetNextRowBreak() and
+ * GetNextManualRowBreak(). */
+ nBreak = pDoc->HasRowBreak(i, nTab);
+ if (!bHiddenRow || nBreak)
+ break;
+ }
+
+ if (nBreakOld != nBreak)
+ {
+ aGrid.Flush();
+ pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
+ (nBreak) ? aPageColor : aGridColor );
+ nBreakOld = nBreak;
+ }
+ }
+
+ BOOL bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt
+
+ //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
+ //! Umbruch mitten in den Wiederholungszeilen liegt.
+ //! Dann lieber den aeusseren Rahmen zweimal ausgeben...
+#if 0
+ // auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
+ if ( eType == OUTTYPE_PRINTER && !bMetaFile )
+ {
+ if ( nY == MAXROW )
+ bDraw = FALSE;
+ else if (pDoc->HasRowBreak(nYplus1, nTab))
+ bDraw = FALSE;
+ }
+#endif
+
+ BOOL bNextYisNextRow = (pRowInfo[nArrYplus1].nRowNo == nYplus1);
+ bSingle = !bNextYisNextRow; // Hidden
+ for (SCCOL i=nX1; i<=nX2 && !bSingle; i++)
+ {
+ if (pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped)
+ bSingle = TRUE;
+ }
+
+ if (bDraw)
+ {
+ if ( bSingle && nY<MAXROW )
+ {
+ SCROW nVisY = pRowInfo[nArrYplus1].nRowNo;
+
+ nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - nOneX;
+
+ long nNextX;
+ for (SCCOL i=nX1; i<=nX2; i++)
+ {
+ nNextX = nPosX + pRowInfo[0].pCellInfo[i+1].nWidth * nLayoutSign;
+ if (nNextX != nPosX) // sichtbar
+ {
+ BOOL bVOver;
+ if ( bNextYisNextRow )
+ bVOver = pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped;
+ else
+ {
+ bVOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ i,nYplus1,nTab,ATTR_MERGE_FLAG))
+ ->IsVerOverlapped()
+ && ((ScMergeFlagAttr*)pDoc->GetAttr(
+ i,nVisY,nTab,ATTR_MERGE_FLAG))
+ ->IsVerOverlapped();
+ //! nVisY aus Array ??
+ }
+ if (!bVOver)
+ {
+ //Point aStart( nPosX, nPosY-nOneY );
+ //Point aEnd( nNextX-nSignedOneX, nPosY-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddHorLine( nPosX, nNextX-nSignedOneX, nPosY-nOneY );
+ }
+ }
+ nPosX = nNextX;
+ }
+ }
+ else
+ {
+ //Point aStart( nScrX, nPosY-nOneY );
+ //Point aEnd( nScrX+nScrW-nOneX, nPosY-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddHorLine( nScrX, nScrX+nScrW-nOneX, nPosY-nOneY );
+ }
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void ScOutputData::SetPagebreakMode( ScPageBreakData* pPageData )
+{
+ bPagebreakMode = TRUE;
+ if (!pPageData)
+ return; // noch nicht initialisiert -> alles "nicht gedruckt"
+
+ // gedruckten Bereich markieren
+ // (in FillInfo ist schon alles auf FALSE initialisiert)
+
+ USHORT nRangeCount = sal::static_int_cast<USHORT>(pPageData->GetCount());
+ for (USHORT nPos=0; nPos<nRangeCount; nPos++)
+ {
+ ScRange aRange = pPageData->GetData( nPos ).GetPrintRange();
+
+ SCCOL nStartX = Max( aRange.aStart.Col(), nX1 );
+ SCCOL nEndX = Min( aRange.aEnd.Col(), nX2 );
+ SCROW nStartY = Max( aRange.aStart.Row(), nY1 );
+ SCROW nEndY = Min( aRange.aEnd.Row(), nY2 );
+
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged && pThisRowInfo->nRowNo >= nStartY &&
+ pThisRowInfo->nRowNo <= nEndY )
+ {
+ for (SCCOL nX=nStartX; nX<=nEndX; nX++)
+ pThisRowInfo->pCellInfo[nX+1].bPrinted = TRUE;
+ }
+ }
+ }
+}
+
+void ScOutputData::FindRotated()
+{
+ //! nRotMax speichern
+ SCCOL nRotMax = nX2;
+ for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
+ if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nRotY].nRotMaxCol;
+
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE &&
+ ( pThisRowInfo->bChanged || pRowInfo[nArrY-1].bChanged ||
+ ( nArrY+1<nArrCount && pRowInfo[nArrY+1].bChanged ) ) )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+
+ for (SCCOL nX=0; nX<=nRotMax; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ const ScPatternAttr* pPattern = pInfo->pPatternAttr;
+ const SfxItemSet* pCondSet = pInfo->pConditionSet;
+
+ if ( !pPattern && !pDoc->ColHidden(nX, nTab) )
+ {
+ pPattern = pDoc->GetPattern( nX, nY, nTab );
+ pCondSet = pDoc->GetCondResult( nX, nY, nTab );
+ }
+
+ if ( pPattern ) // Spalte nicht ausgeblendet
+ {
+ BYTE nDir = pPattern->GetRotateDir( pCondSet );
+ if (nDir != SC_ROTDIR_NONE)
+ {
+ pInfo->nRotateDir = nDir;
+ bAnyRotated = TRUE;
+ }
+ }
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+USHORT lcl_GetRotateDir( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+
+ USHORT nRet = SC_ROTDIR_NONE;
+
+ long nAttrRotate = pPattern->GetRotateVal( pCondSet );
+ if ( nAttrRotate )
+ {
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nRet = SC_ROTDIR_STANDARD;
+ else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
+ nRet = SC_ROTDIR_CENTER;
+ else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
+ {
+ long nRot180 = nAttrRotate % 18000; // 1/100 Grad
+ if ( nRot180 == 9000 )
+ nRet = SC_ROTDIR_CENTER;
+ else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
+ ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
+ nRet = SC_ROTDIR_LEFT;
+ else
+ nRet = SC_ROTDIR_RIGHT;
+ }
+ }
+
+ return nRet;
+}
+
+const SvxBrushItem* lcl_FindBackground( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ const SvxBrushItem* pBackground = (const SvxBrushItem*)
+ &pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
+
+ USHORT nDir = lcl_GetRotateDir( pDoc, nCol, nRow, nTab );
+
+ // CENTER wird wie RIGHT behandelt...
+ if ( nDir == SC_ROTDIR_RIGHT || nDir == SC_ROTDIR_CENTER )
+ {
+ // Text geht nach rechts -> Hintergrund von links nehmen
+ while ( nCol > 0 && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
+ pBackground->GetColor().GetTransparency() != 255 )
+ {
+ --nCol;
+ pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ pBackground = (const SvxBrushItem*)&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
+ }
+ }
+ else if ( nDir == SC_ROTDIR_LEFT )
+ {
+ // Text geht nach links -> Hintergrund von rechts nehmen
+ while ( nCol < MAXCOL && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
+ pBackground->GetColor().GetTransparency() != 255 )
+ {
+ ++nCol;
+ pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ pBackground = (const SvxBrushItem*)&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
+ }
+ }
+
+ return pBackground;
+}
+
+// ----------------------------------------------------------------------------
+
+BOOL lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther,
+ SCCOL nX1, SCCOL nX2, BOOL bShowProt, BOOL bPagebreakMode )
+{
+ if ( rFirst.bChanged != rOther.bChanged ||
+ rFirst.bEmptyBack != rOther.bEmptyBack )
+ return FALSE;
+
+ SCCOL nX;
+ if ( bShowProt )
+ {
+ for ( nX=nX1; nX<=nX2; nX++ )
+ {
+ const ScPatternAttr* pPat1 = rFirst.pCellInfo[nX+1].pPatternAttr;
+ const ScPatternAttr* pPat2 = rOther.pCellInfo[nX+1].pPatternAttr;
+ if ( !pPat1 || !pPat2 ||
+ &pPat1->GetItem(ATTR_PROTECTION) != &pPat2->GetItem(ATTR_PROTECTION) )
+ return FALSE;
+ }
+ }
+ else
+ {
+ for ( nX=nX1; nX<=nX2; nX++ )
+ if ( rFirst.pCellInfo[nX+1].pBackground != rOther.pCellInfo[nX+1].pBackground )
+ return FALSE;
+ }
+
+ if ( rFirst.nRotMaxCol != SC_ROTMAX_NONE || rOther.nRotMaxCol != SC_ROTMAX_NONE )
+ for ( nX=nX1; nX<=nX2; nX++ )
+ if ( rFirst.pCellInfo[nX+1].nRotateDir != rOther.pCellInfo[nX+1].nRotateDir )
+ return FALSE;
+
+ if ( bPagebreakMode )
+ for ( nX=nX1; nX<=nX2; nX++ )
+ if ( rFirst.pCellInfo[nX+1].bPrinted != rOther.pCellInfo[nX+1].bPrinted )
+ return FALSE;
+
+ return TRUE;
+}
+
+void ScOutputData::DrawBackground()
+{
+ FindRotated(); //! von aussen ?
+
+ ScModule* pScMod = SC_MOD();
+
+ // used only if bSolidBackground is set (only for ScGridWindow):
+ Color aBgColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ Rectangle aRect;
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ if (bMetaFile)
+ nOneX = nOneY = 0;
+
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ long nSignedOneX = nOneX * nLayoutSign;
+
+ pDev->SetLineColor();
+
+ BOOL bShowProt = bSyntaxMode && pDoc->IsTabProtected(nTab);
+ BOOL bDoAll = bShowProt || bPagebreakMode || bSolidBackground;
+
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nRowHeight = pThisRowInfo->nHeight;
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if ( ( ( pThisRowInfo->bEmptyBack ) || bSyntaxMode ) && !bDoAll )
+ {
+ // nichts
+ }
+ else
+ {
+ // scan for rows with the same background:
+ SCSIZE nSkip = 0;
+ while ( nArrY+nSkip+2<nArrCount &&
+ lcl_EqualBack( *pThisRowInfo, pRowInfo[nArrY+nSkip+1],
+ nX1, nX2, bShowProt, bPagebreakMode ) )
+ {
+ ++nSkip;
+ nRowHeight += pRowInfo[nArrY+nSkip].nHeight; // after incrementing
+ }
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - nOneX;
+ aRect = Rectangle( nPosX,nPosY, nPosX,nPosY+nRowHeight-nOneY );
+
+ const SvxBrushItem* pOldBackground = NULL;
+ const SvxBrushItem* pBackground;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+
+ if (bCellContrast)
+ {
+ // high contrast for cell borders and backgrounds -> empty background
+ pBackground = ScGlobal::GetEmptyBrushItem();
+ }
+ else if (bShowProt) // show cell protection in syntax mode
+ {
+ const ScPatternAttr* pP = pInfo->pPatternAttr;
+ if (pP)
+ {
+ const ScProtectionAttr& rProt = (const ScProtectionAttr&)
+ pP->GetItem(ATTR_PROTECTION);
+ if (rProt.GetProtection() || rProt.GetHideCell())
+ pBackground = ScGlobal::GetProtectedBrushItem();
+ else
+ pBackground = ScGlobal::GetEmptyBrushItem();
+ }
+ else
+ pBackground = NULL;
+ }
+ else
+ pBackground = pInfo->pBackground;
+
+ if ( bPagebreakMode && !pInfo->bPrinted )
+ pBackground = ScGlobal::GetProtectedBrushItem();
+
+ if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
+ pBackground->GetColor().GetTransparency() != 255 &&
+ !bCellContrast )
+ {
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+ pBackground = lcl_FindBackground( pDoc, nX, nY, nTab );
+ }
+
+ if ( pBackground != pOldBackground )
+ {
+ aRect.Right() = nPosX-nSignedOneX;
+ if (pOldBackground) // ==0 if hidden
+ {
+ Color aBackCol = pOldBackground->GetColor();
+ if ( bSolidBackground && aBackCol.GetTransparency() )
+ aBackCol = aBgColor;
+ if ( !aBackCol.GetTransparency() ) //! partial transparency?
+ {
+ pDev->SetFillColor( aBackCol );
+ pDev->DrawRect( aRect );
+ }
+ }
+ aRect.Left() = nPosX;
+ pOldBackground = pBackground;
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ aRect.Right() = nPosX-nSignedOneX;
+ if (pOldBackground)
+ {
+ Color aBackCol = pOldBackground->GetColor();
+ if ( bSolidBackground && aBackCol.GetTransparency() )
+ aBackCol = aBgColor;
+ if ( !aBackCol.GetTransparency() ) //! partial transparency?
+ {
+ pDev->SetFillColor( aBackCol );
+ pDev->DrawRect( aRect );
+ }
+ }
+
+ nArrY += nSkip;
+ }
+ }
+ nPosY += nRowHeight;
+ }
+}
+
+void ScOutputData::DrawShadow()
+{
+ DrawExtraShadow( FALSE, FALSE, FALSE, FALSE );
+}
+
+void ScOutputData::DrawExtraShadow(BOOL bLeft, BOOL bTop, BOOL bRight, BOOL bBottom)
+{
+ pDev->SetLineColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
+ Color aAutoTextColor;
+ if ( bCellContrast )
+ aAutoTextColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nPosY = nScrY - pRowInfo[0].nHeight;
+ for (SCSIZE nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ BOOL bCornerY = ( nArrY == 0 ) || ( nArrY+1 == nArrCount );
+ BOOL bSkipY = ( nArrY==0 && !bTop ) || ( nArrY+1 == nArrCount && !bBottom );
+
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nRowHeight = pThisRowInfo->nHeight;
+
+ if ( pThisRowInfo->bChanged && !bSkipY )
+ {
+ long nPosX = nInitPosX - pRowInfo[0].pCellInfo[nX1].nWidth * nLayoutSign;
+ for (SCCOL nArrX=nX1; nArrX<=nX2+2; nArrX++)
+ {
+ BOOL bCornerX = ( nArrX==nX1 || nArrX==nX2+2 );
+ BOOL bSkipX = ( nArrX==nX1 && !bLeft ) || ( nArrX==nX2+2 && !bRight );
+
+ for (USHORT nPass=0; nPass<2; nPass++) // horizontal / vertikal
+ {
+ const SvxShadowItem* pAttr = nPass ?
+ pThisRowInfo->pCellInfo[nArrX].pVShadowOrigin :
+ pThisRowInfo->pCellInfo[nArrX].pHShadowOrigin;
+ if ( pAttr && !bSkipX )
+ {
+ ScShadowPart ePart = nPass ?
+ pThisRowInfo->pCellInfo[nArrX].eVShadowPart :
+ pThisRowInfo->pCellInfo[nArrX].eHShadowPart;
+
+ BOOL bDo = TRUE;
+ if ( (nPass==0 && bCornerX) || (nPass==1 && bCornerY) )
+ if ( ePart != SC_SHADOW_CORNER )
+ bDo = FALSE;
+
+ if (bDo)
+ {
+ long nThisWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
+ long nMaxWidth = nThisWidth;
+ if (!nMaxWidth)
+ {
+ //! direction must depend on shadow location
+ SCCOL nWx = nArrX; // nX+1
+ while (nWx<nX2 && !pRowInfo[0].pCellInfo[nWx+1].nWidth)
+ ++nWx;
+ nMaxWidth = pRowInfo[0].pCellInfo[nWx+1].nWidth;
+ }
+
+// Rectangle aRect( Point(nPosX,nPosY),
+// Size( pRowInfo[0].pCellInfo[nArrX].nWidth,
+// pRowInfo[nArrY].nHeight ) );
+
+ // rectangle is in logical orientation
+ Rectangle aRect( nPosX, nPosY,
+ nPosX + ( nThisWidth - 1 ) * nLayoutSign,
+ nPosY + pRowInfo[nArrY].nHeight - 1 );
+
+ long nSize = pAttr->GetWidth();
+ long nSizeX = (long)(nSize*nPPTX);
+ if (nSizeX >= nMaxWidth) nSizeX = nMaxWidth-1;
+ long nSizeY = (long)(nSize*nPPTY);
+ if (nSizeY >= nRowHeight) nSizeY = nRowHeight-1;
+
+ nSizeX *= nLayoutSign; // used only to add to rectangle values
+
+ SvxShadowLocation eLoc = pAttr->GetLocation();
+ if ( bLayoutRTL )
+ {
+ // Shadow location is specified as "visual" (right is always right),
+ // so the attribute's location value is mirrored here and in FillInfo.
+ switch (eLoc)
+ {
+ case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
+ case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
+ case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break;
+ case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if (ePart == SC_SHADOW_HORIZ || ePart == SC_SHADOW_HSTART ||
+ ePart == SC_SHADOW_CORNER)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
+ aRect.Top() = aRect.Bottom() - nSizeY;
+ else
+ aRect.Bottom() = aRect.Top() + nSizeY;
+ }
+ if (ePart == SC_SHADOW_VERT || ePart == SC_SHADOW_VSTART ||
+ ePart == SC_SHADOW_CORNER)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
+ aRect.Left() = aRect.Right() - nSizeX;
+ else
+ aRect.Right() = aRect.Left() + nSizeX;
+ }
+ if (ePart == SC_SHADOW_HSTART)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
+ aRect.Right() -= nSizeX;
+ else
+ aRect.Left() += nSizeX;
+ }
+ if (ePart == SC_SHADOW_VSTART)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
+ aRect.Bottom() -= nSizeY;
+ else
+ aRect.Top() += nSizeY;
+ }
+
+ //! merge rectangles?
+ pDev->SetFillColor( bCellContrast ? aAutoTextColor : pAttr->GetColor() );
+ pDev->DrawRect( aRect );
+ }
+ }
+ }
+
+ nPosX += pRowInfo[0].pCellInfo[nArrX].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += nRowHeight;
+ }
+}
+
+//
+// Loeschen
+//
+
+void ScOutputData::DrawClear()
+{
+ Rectangle aRect;
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ // (called only for ScGridWindow)
+ Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ if (bMetaFile)
+ nOneX = nOneY = 0;
+
+ pDev->SetLineColor();
+
+ pDev->SetFillColor( aBgColor );
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nRowHeight = pThisRowInfo->nHeight;
+
+ if ( pThisRowInfo->bChanged )
+ {
+ // scan for more rows which must be painted:
+ SCSIZE nSkip = 0;
+ while ( nArrY+nSkip+2<nArrCount && pRowInfo[nArrY+nSkip+1].bChanged )
+ {
+ ++nSkip;
+ nRowHeight += pRowInfo[nArrY+nSkip].nHeight; // after incrementing
+ }
+
+ aRect = Rectangle( Point( nScrX, nPosY ),
+ Size( nScrW+1-nOneX, nRowHeight+1-nOneY) );
+ pDev->DrawRect( aRect );
+
+ nArrY += nSkip;
+ }
+ nPosY += nRowHeight;
+ }
+}
+
+
+//
+// Linien
+//
+
+long lclGetSnappedX( OutputDevice& rDev, long nPosX, bool bSnapPixel )
+{
+ return (bSnapPixel && nPosX) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( nPosX, 0 ) ) ).Width() : nPosX;
+}
+
+long lclGetSnappedY( OutputDevice& rDev, long nPosY, bool bSnapPixel )
+{
+ return (bSnapPixel && nPosY) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( 0, nPosY ) ) ).Height() : nPosY;
+}
+
+size_t lclGetArrayColFromCellInfoX( USHORT nCellInfoX, USHORT nCellInfoFirstX, USHORT nCellInfoLastX, bool bRTL )
+{
+ return static_cast< size_t >( bRTL ? (nCellInfoLastX + 2 - nCellInfoX) : (nCellInfoX - nCellInfoFirstX) );
+}
+
+void ScOutputData::DrawFrame()
+{
+ ULONG nOldDrawMode = pDev->GetDrawMode();
+
+ Color aSingleColor;
+ BOOL bUseSingleColor = FALSE;
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
+
+ // #107519# if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
+ // for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
+ // that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
+ // must be reset and the border colors handled here.
+
+ if ( ( nOldDrawMode & DRAWMODE_WHITEFILL ) && ( nOldDrawMode & DRAWMODE_BLACKLINE ) )
+ {
+ pDev->SetDrawMode( nOldDrawMode & (~DRAWMODE_WHITEFILL) );
+ aSingleColor.SetColor( COL_BLACK );
+ bUseSingleColor = TRUE;
+ }
+ else if ( ( nOldDrawMode & DRAWMODE_SETTINGSFILL ) && ( nOldDrawMode & DRAWMODE_SETTINGSLINE ) )
+ {
+ pDev->SetDrawMode( nOldDrawMode & (~DRAWMODE_SETTINGSFILL) );
+ aSingleColor = rStyleSettings.GetWindowTextColor(); // same as used in VCL for DRAWMODE_SETTINGSLINE
+ bUseSingleColor = TRUE;
+ }
+ else if ( bCellContrast )
+ {
+ aSingleColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ bUseSingleColor = TRUE;
+ }
+
+ const Color* pForceColor = bUseSingleColor ? &aSingleColor : 0;
+
+ if (bAnyRotated)
+ DrawRotatedFrame( pForceColor ); // removes the lines that must not be painted here
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+
+ // *** set column and row sizes of the frame border array ***
+
+ svx::frame::Array& rArray = mrTabInfo.maArray;
+ size_t nColCount = rArray.GetColCount();
+ size_t nRowCount = rArray.GetRowCount();
+
+ // row heights
+
+ // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
+ // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
+ long nOldPosY = nScrY - 1 - pRowInfo[ 0 ].nHeight;
+ long nOldSnapY = lclGetSnappedY( *pDev, nOldPosY, bSnapPixel );
+ rArray.SetYOffset( nOldSnapY );
+ for( size_t nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ long nNewPosY = nOldPosY + pRowInfo[ nRow ].nHeight;
+ long nNewSnapY = lclGetSnappedY( *pDev, nNewPosY, bSnapPixel );
+ rArray.SetRowHeight( nRow, nNewSnapY - nOldSnapY );
+ nOldPosY = nNewPosY;
+ nOldSnapY = nNewSnapY;
+ }
+
+ // column widths
+
+ // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
+ // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
+ long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 ].pCellInfo[ nX1 ].nWidth);
+ long nOldSnapX = lclGetSnappedX( *pDev, nOldPosX, bSnapPixel );
+ // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
+ if( !bLayoutRTL )
+ rArray.SetXOffset( nOldSnapX );
+ for( USHORT nInfoIdx = nX1; nInfoIdx <= nX2 + 2; ++nInfoIdx )
+ {
+ size_t nCol = lclGetArrayColFromCellInfoX( nInfoIdx, nX1, nX2, bLayoutRTL );
+ long nNewPosX = nOldPosX + pRowInfo[ 0 ].pCellInfo[ nInfoIdx ].nWidth * nLayoutSign;
+ long nNewSnapX = lclGetSnappedX( *pDev, nNewPosX, bSnapPixel );
+ rArray.SetColWidth( nCol, Abs( nNewSnapX - nOldSnapX ) );
+ nOldPosX = nNewPosX;
+ nOldSnapX = nNewSnapX;
+ }
+ if( bLayoutRTL )
+ rArray.SetXOffset( nOldSnapX );
+
+ // *** draw the array ***
+
+ size_t nFirstCol = 1;
+ size_t nFirstRow = 1;
+ size_t nLastCol = nColCount - 2;
+ size_t nLastRow = nRowCount - 2;
+
+ if( mrTabInfo.mbPageMode )
+ rArray.SetClipRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
+
+ // draw only rows with set RowInfo::bChanged flag
+ size_t nRow1 = nFirstRow;
+ while( nRow1 <= nLastRow )
+ {
+ while( (nRow1 <= nLastRow) && !pRowInfo[ nRow1 ].bChanged ) ++nRow1;
+ if( nRow1 <= nLastRow )
+ {
+ size_t nRow2 = nRow1;
+ while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
+ rArray.DrawRange( *pDev, nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
+ nRow1 = nRow2 + 1;
+ }
+ }
+
+ pDev->SetDrawMode(nOldDrawMode);
+}
+
+// -------------------------------------------------------------------------
+
+// Linie unter der Zelle
+
+const SvxBorderLine* lcl_FindHorLine( ScDocument* pDoc,
+ SCCOL nCol, SCROW nRow, SCTAB nTab, USHORT nRotDir,
+ BOOL bTopLine )
+{
+ if ( nRotDir != SC_ROTDIR_LEFT && nRotDir != SC_ROTDIR_RIGHT )
+ return NULL;
+
+ BOOL bFound = FALSE;
+ while (!bFound)
+ {
+ if ( nRotDir == SC_ROTDIR_LEFT )
+ {
+ // Text nach links -> Linie von rechts
+ if ( nCol < MAXCOL )
+ ++nCol;
+ else
+ return NULL; // war nix
+ }
+ else
+ {
+ // Text nach rechts -> Linie von links
+ if ( nCol > 0 )
+ --nCol;
+ else
+ return NULL; // war nix
+ }
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ if ( !pPattern->GetRotateVal( pCondSet ) ||
+ ((const SvxRotateModeItem&)pPattern->GetItem(
+ ATTR_ROTATE_MODE, pCondSet)).GetValue() == SVX_ROTATE_MODE_STANDARD )
+ bFound = TRUE;
+ }
+
+ if (bTopLine)
+ --nRow;
+ const SvxBorderLine* pThisBottom;
+ if ( ValidRow(nRow) )
+ pThisBottom = ((const SvxBoxItem*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER ))->GetBottom();
+ else
+ pThisBottom = NULL;
+ const SvxBorderLine* pNextTop;
+ if ( nRow < MAXROW )
+ pNextTop = ((const SvxBoxItem*)pDoc->GetAttr( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
+ else
+ pNextTop = NULL;
+
+ if ( ScHasPriority( pThisBottom, pNextTop ) )
+ return pThisBottom;
+ else
+ return pNextTop;
+}
+
+// lcl_HorizLine muss genau zu normal ausgegebenen Linien passen!
+
+void lcl_HorizLine( OutputDevice& rDev, const Point& rLeft, const Point& rRight,
+ const svx::frame::Style& rLine, const Color* pForceColor )
+{
+ svx::frame::DrawHorFrameBorder( rDev, rLeft, rRight, rLine, pForceColor );
+}
+
+void lcl_VertLineEnds( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
+ const Color& rColor, long nXOffs, long nWidth,
+ const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine )
+{
+ rDev.SetLineColor(rColor); // PEN_NULL ???
+ rDev.SetFillColor(rColor);
+
+ // Position oben/unten muss unabhaengig von der Liniendicke sein,
+ // damit der Winkel stimmt (oder X-Position auch anpassen)
+ long nTopPos = rTop.Y();
+ long nBotPos = rBottom.Y();
+
+ long nTopLeft = rTop.X() + nXOffs;
+ long nTopRight = nTopLeft + nWidth - 1;
+
+ long nBotLeft = rBottom.X() + nXOffs;
+ long nBotRight = nBotLeft + nWidth - 1;
+
+ // oben abschliessen
+
+ if ( rTopLine.Prim() )
+ {
+ long nLineW = rTopLine.GetWidth();
+ if (nLineW >= 2)
+ {
+ Point aTriangle[3];
+ aTriangle[0] = Point( nTopLeft, nTopPos ); // wie aPoints[0]
+ aTriangle[1] = Point( nTopRight, nTopPos ); // wie aPoints[1]
+ aTriangle[2] = Point( rTop.X(), nTopPos - (nLineW - 1) / 2 );
+ Polygon aTriPoly( 3, aTriangle );
+ rDev.DrawPolygon( aTriPoly );
+ }
+ }
+
+ // unten abschliessen
+
+ if ( rBottomLine.Prim() )
+ {
+ long nLineW = rBottomLine.GetWidth();
+ if (nLineW >= 2)
+ {
+ Point aTriangle[3];
+ aTriangle[0] = Point( nBotLeft, nBotPos ); // wie aPoints[3]
+ aTriangle[1] = Point( nBotRight, nBotPos ); // wie aPoints[2]
+ aTriangle[2] = Point( rBottom.X(), nBotPos - (nLineW - 1) / 2 + nLineW - 1 );
+ Polygon aTriPoly( 3, aTriangle );
+ rDev.DrawPolygon( aTriPoly );
+ }
+ }
+}
+
+void lcl_VertLine( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
+ const svx::frame::Style& rLine,
+ const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine,
+ const Color* pForceColor )
+{
+ if( rLine.Prim() )
+ {
+ svx::frame::DrawVerFrameBorderSlanted( rDev, rTop, rBottom, rLine, pForceColor );
+
+ svx::frame::Style aScaled( rLine );
+ aScaled.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop, rBottom ) ) );
+ if( pForceColor )
+ aScaled.SetColor( *pForceColor );
+
+ long nXOffs = (aScaled.GetWidth() - 1) / -2L;
+
+ lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
+ nXOffs, aScaled.Prim(), rTopLine, rBottomLine );
+
+ if( aScaled.Secn() )
+ lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
+ nXOffs + aScaled.Prim() + aScaled.Dist(), aScaled.Secn(), rTopLine, rBottomLine );
+ }
+}
+
+void ScOutputData::DrawRotatedFrame( const Color* pForceColor )
+{
+ //! nRotMax speichern
+ SCCOL nRotMax = nX2;
+ for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
+ if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nRotY].nRotMaxCol;
+
+ const ScPatternAttr* pPattern;
+ const SfxItemSet* pCondSet;
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
+
+ // color (pForceColor) is determined externally, including DrawMode changes
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Rectangle aClipRect( Point(nScrX, nScrY), Size(nScrW, nScrH) );
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aClipRect );
+ }
+ else
+ pDev->SetClipRegion( Region( aClipRect ) );
+
+ svx::frame::Array& rArray = mrTabInfo.maArray;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
+ {
+ // Rotated wird auch 1 Zeile ueber/unter Changed gezeichnet, falls Teile
+ // in die Zeile hineinragen...
+
+ RowInfo& rPrevRowInfo = pRowInfo[nArrY-1];
+ RowInfo& rThisRowInfo = pRowInfo[nArrY];
+ RowInfo& rNextRowInfo = pRowInfo[nArrY+1];
+
+ size_t nRow = static_cast< size_t >( nArrY );
+
+ long nRowHeight = rThisRowInfo.nHeight;
+ if ( rThisRowInfo.nRotMaxCol != SC_ROTMAX_NONE &&
+ ( rThisRowInfo.bChanged || rPrevRowInfo.bChanged ||
+ ( nArrY+1<nArrCount && rNextRowInfo.bChanged ) ) )
+ {
+ SCROW nY = rThisRowInfo.nRowNo;
+ long nPosX = 0;
+ SCCOL nX;
+ for (nX=0; nX<=nRotMax; nX++)
+ {
+ if (nX==nX1) nPosX = nInitPosX; // calculated individually for preceding positions
+
+ USHORT nArrX = nX + 1;
+
+ CellInfo* pInfo = &rThisRowInfo.pCellInfo[nArrX];
+ long nColWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
+ if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
+ !pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ pPattern = pInfo->pPatternAttr;
+ pCondSet = pInfo->pConditionSet;
+ if (!pPattern)
+ {
+ pPattern = pDoc->GetPattern( nX, nY, nTab );
+ pInfo->pPatternAttr = pPattern;
+ pCondSet = pDoc->GetCondResult( nX, nY, nTab );
+ pInfo->pConditionSet = pCondSet;
+ }
+
+ //! LastPattern etc.
+
+ long nAttrRotate = pPattern->GetRotateVal( pCondSet );
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( nAttrRotate )
+ {
+ if (nX<nX1) // negative Position berechnen
+ {
+ nPosX = nInitPosX;
+ SCCOL nCol = nX1;
+ while (nCol > nX)
+ {
+ --nCol;
+ nPosX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
+ }
+ }
+
+ // Startposition minus 1, damit auch schraege Hintergruende
+ // zur Umrandung passen (Umrandung ist auf dem Gitter)
+
+ long nTop = nPosY - 1;
+ long nBottom = nPosY + nRowHeight - 1;
+ long nTopLeft = nPosX - nLayoutSign;
+ long nTopRight = nPosX + ( nColWidth - 1 ) * nLayoutSign;
+ long nBotLeft = nTopLeft;
+ long nBotRight = nTopRight;
+
+ // inclusion of the sign here hasn't been decided yet
+ // (if not, the extension of the non-rotated background must also be changed)
+ double nRealOrient = nLayoutSign * nAttrRotate * F_PI18000; // 1/100th degrees
+ double nCos = cos( nRealOrient );
+ double nSin = sin( nRealOrient );
+ //! begrenzen !!!
+ long nSkew = (long) ( nRowHeight * nCos / nSin );
+
+ switch (eRotMode)
+ {
+ case SVX_ROTATE_MODE_BOTTOM:
+ nTopLeft += nSkew;
+ nTopRight += nSkew;
+ break;
+ case SVX_ROTATE_MODE_CENTER:
+ nSkew /= 2;
+ nTopLeft += nSkew;
+ nTopRight += nSkew;
+ nBotLeft -= nSkew;
+ nBotRight -= nSkew;
+ break;
+ case SVX_ROTATE_MODE_TOP:
+ nBotLeft -= nSkew;
+ nBotRight -= nSkew;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ Point aPoints[4];
+ aPoints[0] = Point( nTopLeft, nTop );
+ aPoints[1] = Point( nTopRight, nTop );
+ aPoints[2] = Point( nBotRight, nBottom );
+ aPoints[3] = Point( nBotLeft, nBottom );
+
+ const SvxBrushItem* pBackground = pInfo->pBackground;
+ if (!pBackground)
+ pBackground = (const SvxBrushItem*) &pPattern->GetItem(
+ ATTR_BACKGROUND, pCondSet );
+ if (bCellContrast)
+ {
+ // high contrast for cell borders and backgrounds -> empty background
+ pBackground = ScGlobal::GetEmptyBrushItem();
+ }
+ const Color& rColor = pBackground->GetColor();
+ if ( rColor.GetTransparency() != 255 )
+ {
+ // #95879# draw background only for the changed row itself
+ // (background doesn't extend into other cells).
+ // For the borders (rotated and normal), clipping should be
+ // set if the row isn't changed, but at least the borders
+ // don't cover the cell contents.
+ if ( rThisRowInfo.bChanged )
+ {
+ Polygon aPoly( 4, aPoints );
+
+ // ohne Pen wird bei DrawPolygon rechts und unten
+ // ein Pixel weggelassen...
+ if ( rColor.GetTransparency() == 0 )
+ pDev->SetLineColor(rColor);
+ else
+ pDev->SetLineColor();
+ pDev->SetFillColor(rColor);
+ pDev->DrawPolygon( aPoly );
+ }
+ }
+
+ svx::frame::Style aTopLine, aBottomLine, aLeftLine, aRightLine;
+
+ if ( nX < nX1 || nX > nX2 ) // Attribute in FillInfo nicht gesetzt
+ {
+ //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
+ const SvxBorderLine* pLeftLine;
+ const SvxBorderLine* pTopLine;
+ const SvxBorderLine* pRightLine;
+ const SvxBorderLine* pBottomLine;
+ pDoc->GetBorderLines( nX, nY, nTab,
+ &pLeftLine, &pTopLine, &pRightLine, &pBottomLine );
+ aTopLine.Set( pTopLine, nPPTY );
+ aBottomLine.Set( pBottomLine, nPPTY );
+ aLeftLine.Set( pLeftLine, nPPTX );
+ aRightLine.Set( pRightLine, nPPTX );
+ }
+ else
+ {
+ size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
+ aTopLine = rArray.GetCellStyleTop( nCol, nRow );
+ aBottomLine = rArray.GetCellStyleBottom( nCol, nRow );
+ aLeftLine = rArray.GetCellStyleLeft( nCol, nRow );
+ aRightLine = rArray.GetCellStyleRight( nCol, nRow );
+ // in RTL mode the array is already mirrored -> swap back left/right borders
+ if( bLayoutRTL )
+ std::swap( aLeftLine, aRightLine );
+ }
+
+ lcl_HorizLine( *pDev, aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine, pForceColor );
+ lcl_HorizLine( *pDev, aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine, pForceColor );
+
+ lcl_VertLine( *pDev, aPoints[0], aPoints[3], aLeftLine, aTopLine, aBottomLine, pForceColor );
+ lcl_VertLine( *pDev, aPoints[1], aPoints[2], aRightLine, aTopLine, aBottomLine, pForceColor );
+ }
+ }
+ nPosX += nColWidth * nLayoutSign;
+ }
+
+ // erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
+
+ nX = nX1 > 0 ? (nX1-1) : static_cast<SCCOL>(0);
+ for (; nX<=nX2+1; nX++) // sichtbarer Teil +- 1
+ {
+ USHORT nArrX = nX + 1;
+ CellInfo& rInfo = rThisRowInfo.pCellInfo[nArrX];
+ if ( rInfo.nRotateDir > SC_ROTDIR_STANDARD &&
+ !rInfo.bHOverlapped && !rInfo.bVOverlapped )
+ {
+ pPattern = rInfo.pPatternAttr;
+ pCondSet = rInfo.pConditionSet;
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
+
+ // horizontal: angrenzende Linie verlaengern
+ // (nur, wenn die gedrehte Zelle eine Umrandung hat)
+ USHORT nDir = rInfo.nRotateDir;
+ if ( rArray.GetCellStyleTop( nCol, nRow ).Prim() && eRotMode != SVX_ROTATE_MODE_TOP )
+ {
+ svx::frame::Style aStyle( lcl_FindHorLine( pDoc, nX, nY, nTab, nDir, TRUE ), nPPTY );
+ rArray.SetCellStyleTop( nCol, nRow, aStyle );
+ if( nRow > 0 )
+ rArray.SetCellStyleBottom( nCol, nRow - 1, aStyle );
+ }
+ if ( rArray.GetCellStyleBottom( nCol, nRow ).Prim() && eRotMode != SVX_ROTATE_MODE_BOTTOM )
+ {
+ svx::frame::Style aStyle( lcl_FindHorLine( pDoc, nX, nY, nTab, nDir, FALSE ), nPPTY );
+ rArray.SetCellStyleBottom( nCol, nRow, aStyle );
+ if( nRow + 1 < rArray.GetRowCount() )
+ rArray.SetCellStyleTop( nCol, nRow + 1, aStyle );
+ }
+
+ // always remove vertical borders
+ if( !rArray.IsMergedOverlappedLeft( nCol, nRow ) )
+ {
+ rArray.SetCellStyleLeft( nCol, nRow, svx::frame::Style() );
+ if( nCol > 0 )
+ rArray.SetCellStyleRight( nCol - 1, nRow, svx::frame::Style() );
+ }
+ if( !rArray.IsMergedOverlappedRight( nCol, nRow ) )
+ {
+ rArray.SetCellStyleRight( nCol, nRow, svx::frame::Style() );
+ if( nCol + 1 < rArray.GetColCount() )
+ rArray.SetCellStyleLeft( nCol + 1, nRow, svx::frame::Style() );
+ }
+
+ // remove diagonal borders
+ rArray.SetCellStyleTLBR( nCol, nRow, svx::frame::Style() );
+ rArray.SetCellStyleBLTR( nCol, nRow, svx::frame::Style() );
+ }
+ }
+ }
+ nPosY += nRowHeight;
+ }
+
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+}
+
+// Drucker
+
+PolyPolygon ScOutputData::GetChangedArea()
+{
+ PolyPolygon aPoly;
+
+ Rectangle aDrawingRect;
+ aDrawingRect.Left() = nScrX;
+ aDrawingRect.Right() = nScrX+nScrW-1;
+
+ BOOL bHad = FALSE;
+ long nPosY = nScrY;
+ SCSIZE nArrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if (!bHad)
+ {
+ aDrawingRect.Top() = nPosY;
+ bHad = TRUE;
+ }
+ aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
+ }
+ else if (bHad)
+ {
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+ bHad = FALSE;
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ if (bHad)
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+
+ return aPoly;
+}
+
+BOOL ScOutputData::SetChangedClip()
+{
+ PolyPolygon aPoly;
+
+ Rectangle aDrawingRect;
+ aDrawingRect.Left() = nScrX;
+ aDrawingRect.Right() = nScrX+nScrW-1;
+
+ BOOL bHad = FALSE;
+ long nPosY = nScrY;
+ SCSIZE nArrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if (!bHad)
+ {
+ aDrawingRect.Top() = nPosY;
+ bHad = TRUE;
+ }
+ aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
+ }
+ else if (bHad)
+ {
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+ bHad = FALSE;
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ if (bHad)
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+
+ BOOL bRet = (aPoly.Count() != 0);
+ if (bRet)
+ pDev->SetClipRegion(Region(aPoly));
+ return bRet;
+}
+
+void ScOutputData::FindChanged()
+{
+ SCCOL nX;
+ SCSIZE nArrY;
+
+ BOOL bWasIdleDisabled = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( TRUE );
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ pRowInfo[nArrY].bChanged = FALSE;
+
+ BOOL bProgress = FALSE;
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ for (nX=nX1; nX<=nX2; nX++)
+ {
+ ScBaseCell* pCell = pThisRowInfo->pCellInfo[nX+1].pCell;
+ if (pCell)
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( !bProgress && pFCell->GetDirty() )
+ {
+ ScProgress::CreateInterpretProgress( pDoc, TRUE );
+ bProgress = TRUE;
+ }
+ if (!pFCell->IsRunning())
+ {
+ (void)pFCell->GetValue();
+ if (pFCell->IsChanged())
+ {
+ pThisRowInfo->bChanged = TRUE;
+ if ( pThisRowInfo->pCellInfo[nX+1].bMerged )
+ {
+ SCSIZE nOverY = nArrY + 1;
+ while ( nOverY<nArrCount &&
+ pRowInfo[nOverY].pCellInfo[nX+1].bVOverlapped )
+ {
+ pRowInfo[nOverY].bChanged = TRUE;
+ ++nOverY;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if ( bProgress )
+ ScProgress::DeleteInterpretProgress();
+ pDoc->DisableIdle( bWasIdleDisabled );
+}
+
+#ifdef OLD_SELECTION_PAINT
+void ScOutputData::DrawMark( Window* pWin )
+{
+ Rectangle aRect;
+ ScInvertMerger aInvert( pWin );
+ //! additional method AddLineRect for ScInvertMerger?
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if (pThisRowInfo->bChanged)
+ {
+ long nPosX = nScrX;
+ if (bLayoutRTL)
+ nPosX += nMirrorW - 1; // always in pixels
+
+ aRect = Rectangle( Point( nPosX,nPosY ), Size(1, pThisRowInfo->nHeight) );
+ if (bLayoutRTL)
+ aRect.Left() = aRect.Right() + 1;
+ else
+ aRect.Right() = aRect.Left() - 1;
+
+ BOOL bOldMarked = FALSE;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ if (pThisRowInfo->pCellInfo[nX+1].bMarked != bOldMarked)
+ {
+ if (bOldMarked && aRect.Right() >= aRect.Left())
+ aInvert.AddRect( aRect );
+
+ if (bLayoutRTL)
+ aRect.Right() = nPosX;
+ else
+ aRect.Left() = nPosX;
+
+ bOldMarked = pThisRowInfo->pCellInfo[nX+1].bMarked;
+ }
+
+ if (bLayoutRTL)
+ {
+ nPosX -= pRowInfo[0].pCellInfo[nX+1].nWidth;
+ aRect.Left() = nPosX+1;
+ }
+ else
+ {
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth;
+ aRect.Right() = nPosX-1;
+ }
+ }
+ if (bOldMarked && aRect.Right() >= aRect.Left())
+ aInvert.AddRect( aRect );
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+}
+#endif
+
+void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
+ SCCOL nRefEndX, SCROW nRefEndY,
+ const Color& rColor, BOOL bHandle )
+{
+ PutInOrder( nRefStartX, nRefEndX );
+ PutInOrder( nRefStartY, nRefEndY );
+
+ if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
+ pDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
+
+ if ( nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
+ nRefStartY <= nVisY2 && nRefEndY >= nVisY1 )
+ {
+ long nMinX = nScrX;
+ long nMinY = nScrY;
+ long nMaxX = nScrX+nScrW-1;
+ long nMaxY = nScrY+nScrH-1;
+ if ( bLayoutRTL )
+ {
+ long nTemp = nMinX;
+ nMinX = nMaxX;
+ nMaxX = nTemp;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ BOOL bTop = FALSE;
+ BOOL bBottom = FALSE;
+ BOOL bLeft = FALSE;
+ BOOL bRight = FALSE;
+
+ long nPosY = nScrY;
+ BOOL bNoStartY = ( nY1 < nRefStartY );
+ BOOL bNoEndY = FALSE;
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
+ {
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+
+ if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
+ {
+ nMinY = nPosY;
+ bTop = TRUE;
+ }
+ if ( nY==nRefEndY )
+ {
+ nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
+ bBottom = TRUE;
+ }
+ if ( nY>nRefEndY && bNoEndY )
+ {
+ nMaxY = nPosY-2;
+ bBottom = TRUE;
+ }
+ bNoStartY = ( nY < nRefStartY );
+ bNoEndY = ( nY < nRefEndY );
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - 1; // always in pixels
+
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ if ( nX==nRefStartX )
+ {
+ nMinX = nPosX;
+ bLeft = TRUE;
+ }
+ if ( nX==nRefEndX )
+ {
+ nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
+ bRight = TRUE;
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+
+ if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
+ nMaxY >= nMinY )
+ {
+ pDev->SetLineColor( rColor );
+ if (bTop && bBottom && bLeft && bRight)
+ {
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
+ }
+ else
+ {
+ if (bTop)
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
+ if (bBottom)
+ pDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
+ if (bLeft)
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
+ if (bRight)
+ pDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
+ }
+ if ( bHandle && bRight && bBottom )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( rColor );
+ pDev->DrawRect( Rectangle( nMaxX-3*nLayoutSign, nMaxY-3, nMaxX+nLayoutSign, nMaxY+1 ) );
+ }
+ }
+ }
+}
+
+void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
+ SCCOL nRefEndX, SCROW nRefEndY,
+ const Color& rColor, USHORT nType )
+{
+ PutInOrder( nRefStartX, nRefEndX );
+ PutInOrder( nRefStartY, nRefEndY );
+
+ if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
+ pDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
+
+ if ( nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
+ nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1 ) // +1 because it touches next cells left/top
+ {
+ long nMinX = nScrX;
+ long nMinY = nScrY;
+ long nMaxX = nScrX+nScrW-1;
+ long nMaxY = nScrY+nScrH-1;
+ if ( bLayoutRTL )
+ {
+ long nTemp = nMinX;
+ nMinX = nMaxX;
+ nMaxX = nTemp;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ BOOL bTop = FALSE;
+ BOOL bBottom = FALSE;
+ BOOL bLeft = FALSE;
+ BOOL bRight = FALSE;
+
+ long nPosY = nScrY;
+ BOOL bNoStartY = ( nY1 < nRefStartY );
+ BOOL bNoEndY = FALSE;
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
+ {
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+
+ if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
+ {
+ nMinY = nPosY - 1;
+ bTop = TRUE;
+ }
+ if ( nY==nRefEndY )
+ {
+ nMaxY = nPosY + pRowInfo[nArrY].nHeight - 1;
+ bBottom = TRUE;
+ }
+ if ( nY>nRefEndY && bNoEndY )
+ {
+ nMaxY = nPosY - 1;
+ bBottom = TRUE;
+ }
+ bNoStartY = ( nY < nRefStartY );
+ bNoEndY = ( nY < nRefEndY );
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - 1; // always in pixels
+
+ for (SCCOL nX=nX1; nX<=nX2+1; nX++)
+ {
+ if ( nX==nRefStartX )
+ {
+ nMinX = nPosX - nLayoutSign;
+ bLeft = TRUE;
+ }
+ if ( nX==nRefEndX )
+ {
+ nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 1 ) * nLayoutSign;
+ bRight = TRUE;
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+
+ if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
+ nMaxY >= nMinY )
+ {
+ if ( nType == SC_CAT_DELETE_ROWS )
+ bLeft = bRight = bBottom = FALSE; //! dicke Linie ???
+ else if ( nType == SC_CAT_DELETE_COLS )
+ bTop = bBottom = bRight = FALSE; //! dicke Linie ???
+
+ pDev->SetLineColor( rColor );
+ if (bTop && bBottom && bLeft && bRight)
+ {
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
+ }
+ else
+ {
+ if (bTop)
+ {
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
+ if ( nType == SC_CAT_DELETE_ROWS )
+ pDev->DrawLine( Point( nMinX,nMinY+1 ), Point( nMaxX,nMinY+1 ) );
+ }
+ if (bBottom)
+ pDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
+ if (bLeft)
+ {
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
+ if ( nType == SC_CAT_DELETE_COLS )
+ pDev->DrawLine( Point( nMinX+nLayoutSign,nMinY ), Point( nMinX+nLayoutSign,nMaxY ) );
+ }
+ if (bRight)
+ pDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
+ }
+ if ( bLeft && bTop )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( rColor );
+ pDev->DrawRect( Rectangle( nMinX+nLayoutSign, nMinY+1, nMinX+3*nLayoutSign, nMinY+3 ) );
+ }
+ }
+ }
+}
+
+void ScOutputData::DrawChangeTrack()
+{
+ ScChangeTrack* pTrack = pDoc->GetChangeTrack();
+ ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
+ if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
+ return; // nix da oder abgeschaltet
+
+ ScActionColorChanger aColorChanger(*pTrack);
+
+ // Clipping passiert von aussen
+ //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
+
+ SCCOL nEndX = nX2;
+ SCROW nEndY = nY2;
+ if ( nEndX < MAXCOL ) ++nEndX; // auch noch von der naechsten Zelle, weil die Markierung
+ if ( nEndY < MAXROW ) ++nEndY; // in die jeweils vorhergehende Zelle hineinragt
+ ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
+ const ScChangeAction* pAction = pTrack->GetFirst();
+ while (pAction)
+ {
+ ScChangeActionType eActionType;
+ if ( pAction->IsVisible() )
+ {
+ eActionType = pAction->GetType();
+ const ScBigRange& rBig = pAction->GetBigRange();
+ if ( rBig.aStart.Tab() == nTab )
+ {
+ ScRange aRange = rBig.MakeRange();
+
+ if ( eActionType == SC_CAT_DELETE_ROWS )
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ else if ( eActionType == SC_CAT_DELETE_COLS )
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+
+ if ( aRange.Intersects( aViewRange ) &&
+ ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
+ {
+ aColorChanger.Update( *pAction );
+ Color aColor( aColorChanger.GetColor() );
+ DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<USHORT>(eActionType) );
+
+ }
+ }
+ if ( eActionType == SC_CAT_MOVE &&
+ ((const ScChangeActionMove*)pAction)->
+ GetFromRange().aStart.Tab() == nTab )
+ {
+ ScRange aRange = ((const ScChangeActionMove*)pAction)->
+ GetFromRange().MakeRange();
+ if ( aRange.Intersects( aViewRange ) &&
+ ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
+ {
+ aColorChanger.Update( *pAction );
+ Color aColor( aColorChanger.GetColor() );
+ DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<USHORT>(eActionType) );
+ }
+ }
+ }
+
+ pAction = pAction->GetNext();
+ }
+}
+
+void ScOutputData::DrawNoteMarks()
+{
+ BOOL bFirst = TRUE;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ nInitPosX += nMirrorW - 1; // always in pixels
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ long nPosX = nInitPosX;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ ScBaseCell* pCell = pInfo->pCell;
+ BOOL bIsMerged = FALSE;
+
+ if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ // find start of merged cell
+ bIsMerged = TRUE;
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+ SCCOL nMergeX = nX;
+ SCROW nMergeY = nY;
+ pDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
+ pCell = pDoc->GetCell( ScAddress(nMergeX,nMergeY,nTab) );
+ // use origin's pCell for NotePtr test below
+ }
+
+ if ( pCell && pCell->HasNote() && ( bIsMerged ||
+ ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
+ {
+ if (bFirst)
+ {
+ pDev->SetLineColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ if ( bUseStyleColor && rStyleSettings.GetHighContrastMode() )
+ pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ else
+ pDev->SetFillColor(COL_LIGHTRED);
+
+ bFirst = FALSE;
+ }
+
+ long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
+ if ( bIsMerged || pInfo->bMerged )
+ {
+ // if merged, add widths of all cells
+ SCCOL nNextX = nX + 1;
+ while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
+ {
+ nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
+ ++nNextX;
+ }
+ }
+ if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
+ pDev->DrawRect( Rectangle( nMarkX,nPosY,nMarkX+2*nLayoutSign,nPosY+2 ) );
+ }
+
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+}
+
+void ScOutputData::AddPDFNotes()
+{
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+ if ( !pPDFData || !pPDFData->GetIsExportNotes() )
+ return;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ long nPosX = nInitPosX;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ ScBaseCell* pCell = pInfo->pCell;
+ BOOL bIsMerged = FALSE;
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+ SCCOL nMergeX = nX;
+ SCROW nMergeY = nY;
+
+ if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ // find start of merged cell
+ bIsMerged = TRUE;
+ pDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
+ pCell = pDoc->GetCell( ScAddress(nMergeX,nMergeY,nTab) );
+ // use origin's pCell for NotePtr test below
+ }
+
+ if ( pCell && pCell->HasNote() && ( bIsMerged ||
+ ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
+ {
+ long nNoteWidth = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ long nNoteHeight = (long)( SC_CLIPMARK_SIZE * nPPTY );
+
+ long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
+ if ( bIsMerged || pInfo->bMerged )
+ {
+ // if merged, add widths of all cells
+ SCCOL nNextX = nX + 1;
+ while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
+ {
+ nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
+ ++nNextX;
+ }
+ }
+ if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
+ {
+ Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
+ const ScPostIt* pNote = pCell->GetNote();
+
+ // Note title is the cell address (as on printed note pages)
+ String aTitle;
+ ScAddress aAddress( nMergeX, nMergeY, nTab );
+ aAddress.Format( aTitle, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
+
+ // Content has to be a simple string without line breaks
+ String aContent = pNote->GetText();
+ xub_StrLen nPos;
+ while ( (nPos=aContent.Search('\n')) != STRING_NOTFOUND )
+ aContent.SetChar( nPos, ' ' );
+
+ vcl::PDFNote aNote;
+ aNote.Title = aTitle;
+ aNote.Contents = aContent;
+ pPDFData->CreateNote( aNoteRect, aNote );
+ }
+ }
+
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+}
+
+void ScOutputData::DrawClipMarks()
+{
+ if (!bAnyClipped)
+ return;
+
+ Color aArrowFillCol( COL_LIGHTRED );
+
+ ULONG nOldDrawMode = pDev->GetDrawMode();
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ if ( bUseStyleColor && rStyleSettings.GetHighContrastMode() )
+ {
+ // use DrawMode to change the arrow's outline color
+ pDev->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE );
+ // use text color also for the fill color
+ aArrowFillCol.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ }
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ nInitPosX += nMirrorW - 1; // always in pixels
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Rectangle aCellRect;
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+ long nPosX = nInitPosX;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ if (pInfo->nClipMark)
+ {
+ if (pInfo->bHOverlapped || pInfo->bVOverlapped)
+ {
+ // merge origin may be outside of visible area - use document functions
+
+ SCCOL nOverX = nX;
+ SCROW nOverY = nY;
+ long nStartPosX = nPosX;
+ long nStartPosY = nPosY;
+
+ while ( nOverX > 0 && ( ((const ScMergeFlagAttr*)pDoc->GetAttr(
+ nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_HOR ) )
+ {
+ --nOverX;
+ nStartPosX -= nLayoutSign * (long) ( pDoc->GetColWidth(nOverX,nTab) * nPPTX );
+ }
+
+ while ( nOverY > 0 && ( ((const ScMergeFlagAttr*)pDoc->GetAttr(
+ nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_VER ) )
+ {
+ --nOverY;
+ nStartPosY -= nLayoutSign * (long) ( pDoc->GetRowHeight(nOverY,nTab) * nPPTY );
+ }
+
+ long nOutWidth = (long) ( pDoc->GetColWidth(nOverX,nTab) * nPPTX );
+ long nOutHeight = (long) ( pDoc->GetRowHeight(nOverY,nTab) * nPPTY );
+
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)
+ pDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE );
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nOutWidth += (long) ( pDoc->GetColWidth(nOverX+i,nTab) * nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+ nOutHeight += (long) pDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, nPPTY);
+
+ if ( bLayoutRTL )
+ nStartPosX -= nOutWidth - 1;
+ aCellRect = Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
+ }
+ else
+ {
+ long nOutWidth = pRowInfo[0].pCellInfo[nX+1].nWidth;
+ long nOutHeight = pThisRowInfo->nHeight;
+
+ if ( pInfo->bMerged && pInfo->pPatternAttr )
+ {
+ SCCOL nOverX = nX;
+ SCROW nOverY = nY;
+ const ScMergeAttr* pMerge =
+ (ScMergeAttr*)&pInfo->pPatternAttr->GetItem(ATTR_MERGE);
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nOutWidth += (long) ( pDoc->GetColWidth(nOverX+i,nTab) * nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+ nOutHeight += (long) pDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, nPPTY);
+ }
+
+ long nStartPosX = nPosX;
+ if ( bLayoutRTL )
+ nStartPosX -= nOutWidth - 1;
+ // #i80447# create aCellRect from two points in case nOutWidth is 0
+ aCellRect = Rectangle( Point( nStartPosX, nPosY ),
+ Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
+ }
+
+ aCellRect.Bottom() -= 1; // don't paint over the cell grid
+ if ( bLayoutRTL )
+ aCellRect.Left() += 1;
+ else
+ aCellRect.Right() -= 1;
+
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
+
+ if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_RIGHT : SC_CLIPMARK_LEFT ) )
+ {
+ // visually left
+ Rectangle aMarkRect = aCellRect;
+ aMarkRect.Right() = aCellRect.Left()+nMarkPixel-1;
+#if 0
+ //! Test
+ pDev->SetLineColor(); pDev->SetFillColor(COL_YELLOW);
+ pDev->DrawRect(aMarkRect);
+ //! Test
+#endif
+ SvxFont::DrawArrow( *pDev, aMarkRect, aMarkSize, aArrowFillCol, TRUE );
+ }
+ if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_LEFT : SC_CLIPMARK_RIGHT ) )
+ {
+ // visually right
+ Rectangle aMarkRect = aCellRect;
+ aMarkRect.Left() = aCellRect.Right()-nMarkPixel+1;
+#if 0
+ //! Test
+ pDev->SetLineColor(); pDev->SetFillColor(COL_LIGHTGREEN);
+ pDev->DrawRect(aMarkRect);
+ //! Test
+#endif
+ SvxFont::DrawArrow( *pDev, aMarkRect, aMarkSize, aArrowFillCol, FALSE );
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+
+ pDev->SetDrawMode(nOldDrawMode);
+}
+
+
+
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
new file mode 100644
index 000000000000..b0df298315bf
--- /dev/null
+++ b/sc/source/ui/view/output2.cxx
@@ -0,0 +1,3705 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#endif
+
+#include "output.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cellform.hxx"
+#include "editutil.hxx"
+#include "progress.hxx"
+#include "scmod.hxx"
+#include "fillinfo.hxx"
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <math.h>
+
+//! Autofilter-Breite mit column.cxx zusammenfassen
+#define DROPDOWN_BITMAP_SIZE 18
+
+#define DRAWTEXT_MAX 32767
+
+const USHORT SC_SHRINKAGAIN_MAX = 7;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+// -----------------------------------------------------------------------
+
+class ScDrawStringsVars
+{
+ ScOutputData* pOutput; // Verbindung
+
+ const ScPatternAttr* pPattern; // Attribute
+ const SfxItemSet* pCondSet; // aus bedingter Formatierung
+
+ Font aFont; // aus Attributen erzeugt
+ FontMetric aMetric;
+ long nAscentPixel; // always pixels
+ SvxCellOrientation eAttrOrient;
+ SvxCellHorJustify eAttrHorJust;
+ SvxCellVerJustify eAttrVerJust;
+ const SvxMarginItem* pMargin;
+ USHORT nIndent;
+ BOOL bRotated;
+
+ String aString; // Inhalte
+ Size aTextSize;
+ long nOriginalWidth;
+ long nMaxDigitWidth;
+ long nSignWidth;
+ long nDotWidth;
+ long nExpWidth;
+
+ ScBaseCell* pLastCell;
+ ULONG nValueFormat;
+ BOOL bLineBreak;
+ BOOL bRepeat;
+ BOOL bShrink;
+
+ BOOL bPixelToLogic;
+ BOOL bCellContrast;
+
+ Color aBackConfigColor; // used for ScPatternAttr::GetFont calls
+ Color aTextConfigColor;
+
+public:
+ ScDrawStringsVars(ScOutputData* pData, BOOL bPTL);
+ ~ScDrawStringsVars();
+
+ // SetPattern = ex-SetVars
+ // SetPatternSimple: ohne Font
+
+ void SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, BYTE nScript );
+ void SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet );
+
+ BOOL SetText( ScBaseCell* pCell ); // TRUE -> pOldPattern vergessen
+ void SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth );
+ void SetAutoText( const String& rAutoText );
+
+ const ScPatternAttr* GetPattern() const { return pPattern; }
+ SvxCellOrientation GetOrient() const { return eAttrOrient; }
+ SvxCellHorJustify GetHorJust() const { return eAttrHorJust; }
+ SvxCellVerJustify GetVerJust() const { return eAttrVerJust; }
+ const SvxMarginItem* GetMargin() const { return pMargin; }
+
+ USHORT GetLeftTotal() const { return pMargin->GetLeftMargin() + nIndent; }
+
+ const String& GetString() const { return aString; }
+ const Size& GetTextSize() const { return aTextSize; }
+ long GetOriginalWidth() const { return nOriginalWidth; }
+
+ ULONG GetValueFormat() const { return nValueFormat; }
+ BOOL GetLineBreak() const { return bLineBreak; }
+ BOOL IsRepeat() const { return bRepeat; }
+ BOOL IsShrink() const { return bShrink; }
+
+ long GetAscent() const { return nAscentPixel; }
+ BOOL IsRotated() const { return bRotated; }
+
+ void SetShrinkScale( long nScale, BYTE nScript );
+
+ BOOL HasCondHeight() const { return pCondSet && SFX_ITEM_SET ==
+ pCondSet->GetItemState( ATTR_FONT_HEIGHT, TRUE ); }
+
+ BOOL HasEditCharacters() const;
+
+private:
+ void SetHashText();
+ long GetMaxDigitWidth(); // in logic units
+ long GetSignWidth();
+ long GetDotWidth();
+ long GetExpWidth();
+ void TextChanged();
+};
+
+//==================================================================
+
+ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, BOOL bPTL) :
+ pOutput ( pData ),
+ pPattern ( NULL ),
+ pCondSet ( NULL ),
+ eAttrOrient ( SVX_ORIENTATION_STANDARD ),
+ eAttrHorJust( SVX_HOR_JUSTIFY_STANDARD ),
+ eAttrVerJust( SVX_VER_JUSTIFY_BOTTOM ),
+ pMargin ( NULL ),
+ nIndent ( 0 ),
+ bRotated ( FALSE ),
+ nOriginalWidth( 0 ),
+ nMaxDigitWidth( 0 ),
+ nSignWidth( 0 ),
+ nDotWidth( 0 ),
+ nExpWidth( 0 ),
+ pLastCell ( NULL ),
+ nValueFormat( 0 ),
+ bLineBreak ( FALSE ),
+ bRepeat ( FALSE ),
+ bShrink ( FALSE ),
+ bPixelToLogic( bPTL )
+{
+ ScModule* pScMod = SC_MOD();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ bCellContrast = pOutput->bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ const svtools::ColorConfig& rColorConfig = pScMod->GetColorConfig();
+ aBackConfigColor.SetColor( rColorConfig.GetColorValue(svtools::DOCCOLOR).nColor );
+ aTextConfigColor.SetColor( rColorConfig.GetColorValue(svtools::FONTCOLOR).nColor );
+}
+
+ScDrawStringsVars::~ScDrawStringsVars()
+{
+}
+
+void ScDrawStringsVars::SetShrinkScale( long nScale, BYTE nScript )
+{
+ // text remains valid, size is updated
+
+ OutputDevice* pDev = pOutput->pDev;
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+
+ // call GetFont with a modified fraction, use only the height
+
+ Fraction aFraction( nScale, 100 );
+ if ( !bPixelToLogic )
+ aFraction *= pOutput->aZoomY;
+ Font aTmpFont;
+ pPattern->GetFont( aTmpFont, SC_AUTOCOL_RAW, pFmtDevice, &aFraction, pCondSet, nScript );
+ long nNewHeight = aTmpFont.GetHeight();
+ if ( nNewHeight > 0 )
+ aFont.SetHeight( nNewHeight );
+
+ // set font and dependent variables as in SetPattern
+
+ pDev->SetFont( aFont );
+ if ( pFmtDevice != pDev )
+ pFmtDevice->SetFont( aFont );
+
+ aMetric = pFmtDevice->GetFontMetric();
+ if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
+ {
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ MapMode aOld = pDefaultDev->GetMapMode();
+ pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
+ aMetric = pDefaultDev->GetFontMetric( aFont );
+ pDefaultDev->SetMapMode( aOld );
+ }
+
+ nAscentPixel = aMetric.GetAscent();
+ if ( bPixelToLogic )
+ nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
+
+ SetAutoText( aString ); // same text again, to get text size
+}
+
+void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet,
+ ScBaseCell* pCell, BYTE nScript )
+{
+ nMaxDigitWidth = 0;
+ nSignWidth = 0;
+ nDotWidth = 0;
+ nExpWidth = 0;
+
+ pPattern = pNew;
+ pCondSet = pSet;
+
+ // pPattern auswerten
+
+ OutputDevice* pDev = pOutput->pDev;
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+
+ // Font
+
+ ScAutoFontColorMode eColorMode;
+ if ( pOutput->bUseStyleColor )
+ {
+ if ( pOutput->bForceAutoColor )
+ eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREALL : SC_AUTOCOL_IGNOREFONT;
+ else
+ eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREBACK : SC_AUTOCOL_DISPLAY;
+ }
+ else
+ eColorMode = SC_AUTOCOL_PRINT;
+
+ if ( bPixelToLogic )
+ pPattern->GetFont( aFont, eColorMode, pFmtDevice, NULL, pCondSet, nScript,
+ &aBackConfigColor, &aTextConfigColor );
+ else
+ pPattern->GetFont( aFont, eColorMode, pFmtDevice, &pOutput->aZoomY, pCondSet, nScript,
+ &aBackConfigColor, &aTextConfigColor );
+ aFont.SetAlign(ALIGN_BASELINE);
+
+ // Orientierung
+
+ eAttrOrient = pPattern->GetCellOrientation( pCondSet );
+
+ // alignment
+
+ eAttrHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
+
+ eAttrVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)pPattern->GetItem( ATTR_VER_JUSTIFY, pCondSet )).GetValue();
+ if ( eAttrVerJust == SVX_VER_JUSTIFY_STANDARD )
+ eAttrVerJust = SVX_VER_JUSTIFY_BOTTOM;
+
+ // line break
+
+ bLineBreak = ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK, pCondSet )).GetValue();
+
+ // handle "repeat" alignment
+
+ bRepeat = ( eAttrHorJust == SVX_HOR_JUSTIFY_REPEAT );
+ if ( bRepeat )
+ {
+ // "repeat" disables rotation (before constructing the font)
+ eAttrOrient = SVX_ORIENTATION_STANDARD;
+
+ // #i31843# "repeat" with "line breaks" is treated as default alignment (but rotation is still disabled)
+ if ( bLineBreak )
+ eAttrHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ }
+
+ short nRot;
+ switch (eAttrOrient)
+ {
+ case SVX_ORIENTATION_STANDARD:
+ nRot = 0;
+ bRotated = (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue() != 0) &&
+ !bRepeat;
+ break;
+ case SVX_ORIENTATION_STACKED:
+ nRot = 0;
+ bRotated = FALSE;
+ break;
+ case SVX_ORIENTATION_TOPBOTTOM:
+ nRot = 2700;
+ bRotated = FALSE;
+ break;
+ case SVX_ORIENTATION_BOTTOMTOP:
+ nRot = 900;
+ bRotated = FALSE;
+ break;
+ default:
+ DBG_ERROR("Falscher SvxCellOrientation Wert");
+ nRot = 0;
+ bRotated = FALSE;
+ break;
+ }
+ aFont.SetOrientation( nRot );
+
+ // Syntax-Modus
+
+ if (pOutput->bSyntaxMode)
+ pOutput->SetSyntaxColor( &aFont, pCell );
+
+ pDev->SetFont( aFont );
+ if ( pFmtDevice != pDev )
+ pFmtDevice->SetFont( aFont );
+
+ aMetric = pFmtDevice->GetFontMetric();
+
+ //
+ // Wenn auf dem Drucker das Leading 0 ist, gibt es Probleme
+ // -> Metric vom Bildschirm nehmen (wie EditEngine!)
+ //
+
+ if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
+ {
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ MapMode aOld = pDefaultDev->GetMapMode();
+ pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
+ aMetric = pDefaultDev->GetFontMetric( aFont );
+ pDefaultDev->SetMapMode( aOld );
+ }
+
+ nAscentPixel = aMetric.GetAscent();
+ if ( bPixelToLogic )
+ nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
+
+ Color aULineColor( ((const SvxUnderlineItem&)pPattern->GetItem( ATTR_FONT_UNDERLINE, pCondSet )).GetColor() );
+ pDev->SetTextLineColor( aULineColor );
+
+ Color aOLineColor( ((const SvxOverlineItem&)pPattern->GetItem( ATTR_FONT_OVERLINE, pCondSet )).GetColor() );
+ pDev->SetOverlineColor( aOLineColor );
+
+ // Zahlenformat
+
+// ULONG nOld = nValueFormat;
+ nValueFormat = pPattern->GetNumberFormat( pOutput->pDoc->GetFormatTable(), pCondSet );
+
+/* s.u.
+ if (nValueFormat != nOld)
+ pLastCell = NULL; // immer neu formatieren
+*/
+ // Raender
+
+ pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
+ if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
+ else
+ nIndent = 0;
+
+ // "Shrink to fit"
+
+ bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+
+ // zumindest die Text-Groesse muss neu geholt werden
+ //! unterscheiden, und den Text nicht neu vom Numberformatter holen?
+
+ pLastCell = NULL;
+}
+
+void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet )
+{
+ nMaxDigitWidth = 0;
+ nSignWidth = 0;
+ nDotWidth = 0;
+ nExpWidth = 0;
+ // wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer)
+
+ pPattern = pNew;
+ pCondSet = pSet; //! noetig ???
+
+ // Zahlenformat
+
+ ULONG nOld = nValueFormat;
+// nValueFormat = pPattern->GetNumberFormat( pFormatter );
+ const SfxPoolItem* pFormItem;
+ if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,TRUE,&pFormItem) != SFX_ITEM_SET )
+ pFormItem = &pPattern->GetItem(ATTR_VALUE_FORMAT);
+ const SfxPoolItem* pLangItem;
+ if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,TRUE,&pLangItem) != SFX_ITEM_SET )
+ pLangItem = &pPattern->GetItem(ATTR_LANGUAGE_FORMAT);
+ nValueFormat = pOutput->pDoc->GetFormatTable()->GetFormatForLanguageIfBuiltIn(
+ ((SfxUInt32Item*)pFormItem)->GetValue(),
+ ((SvxLanguageItem*)pLangItem)->GetLanguage() );
+
+ if (nValueFormat != nOld)
+ pLastCell = NULL; // immer neu formatieren
+
+ // Raender
+
+ pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
+
+ if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
+ else
+ nIndent = 0;
+
+ // "Shrink to fit"
+
+ bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+}
+
+inline BOOL SameValue( ScBaseCell* pCell, ScBaseCell* pOldCell ) // pCell ist != 0
+{
+ return pOldCell && pOldCell->GetCellType() == CELLTYPE_VALUE &&
+ pCell->GetCellType() == CELLTYPE_VALUE &&
+ ((ScValueCell*)pCell)->GetValue() == ((ScValueCell*)pOldCell)->GetValue();
+}
+
+BOOL ScDrawStringsVars::SetText( ScBaseCell* pCell )
+{
+ BOOL bChanged = FALSE;
+
+ if (pCell)
+ {
+ if ( !SameValue( pCell, pLastCell ) )
+ {
+ pLastCell = pCell; // Zelle merken
+
+ Color* pColor;
+ ULONG nFormat = GetValueFormat();
+ ScCellFormat::GetString( pCell,
+ nFormat, aString, &pColor,
+ *pOutput->pDoc->GetFormatTable(),
+ pOutput->bShowNullValues,
+ pOutput->bShowFormulas,
+ ftCheck );
+
+ if (aString.Len() > DRAWTEXT_MAX)
+ aString.Erase(DRAWTEXT_MAX);
+
+ if ( pColor && !pOutput->bSyntaxMode && !( pOutput->bUseStyleColor && pOutput->bForceAutoColor ) )
+ {
+ OutputDevice* pDev = pOutput->pDev;
+ aFont.SetColor(*pColor);
+ pDev->SetFont( aFont ); // nur fuer Ausgabe
+ bChanged = TRUE;
+ pLastCell = NULL; // naechstes Mal wieder hierherkommen
+ }
+
+ TextChanged();
+ }
+ // sonst String/Groesse behalten
+ }
+ else
+ {
+ aString.Erase();
+ pLastCell = NULL;
+ aTextSize = Size(0,0);
+ nOriginalWidth = 0;
+ }
+
+ return bChanged;
+}
+
+void ScDrawStringsVars::SetHashText()
+{
+ SetAutoText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
+}
+
+void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth )
+{
+ // #i113045# do the single-character width calculations in logic units
+ if (bPixelToLogic)
+ nWidth = pOutput->pRefDevice->PixelToLogic(Size(nWidth,0)).Width();
+
+ if (!pCell)
+ return;
+
+ CellType eType = pCell->GetCellType();
+ if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA)
+ // must be a value or formula cell.
+ return;
+
+ if (eType == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if (pFCell->GetErrCode() != 0)
+ {
+ SetHashText(); // If the error string doesn't fit, always use "###"
+ return;
+ }
+ // If it's formula, the result must be a value.
+ if (!pFCell->IsValue())
+ return;
+ }
+
+ ULONG nFormat = GetValueFormat();
+ if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
+ {
+ // Not 'General' number format. Set hash text and bail out.
+ SetHashText();
+ return;
+ }
+
+ double fVal = (eType == CELLTYPE_VALUE) ?
+ static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue();
+
+ const SvNumberformat* pNumFormat = pOutput->pDoc->GetFormatTable()->GetEntry(nFormat);
+ if (!pNumFormat)
+ return;
+
+ long nMaxDigit = GetMaxDigitWidth();
+ sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
+
+ if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
+ // Failed to get output string. Bail out.
+ return;
+
+ sal_uInt8 nSignCount = 0, nDecimalCount = 0, nExpCount = 0;
+ xub_StrLen nLen = aString.Len();
+ sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0];
+ for (xub_StrLen i = 0; i < nLen; ++i)
+ {
+ sal_Unicode c = aString.GetChar(i);
+ if (c == sal_Unicode('-'))
+ ++nSignCount;
+ else if (c == cDecSep)
+ ++nDecimalCount;
+ else if (c == sal_Unicode('E'))
+ ++nExpCount;
+ }
+
+ // #i112250# A small value might be formatted as "0" when only counting the digits,
+ // but fit into the column when considering the smaller width of the decimal separator.
+ if (aString.EqualsAscii("0") && fVal != 0.0)
+ nDecimalCount = 1;
+
+ if (nDecimalCount)
+ nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount;
+ if (nSignCount)
+ nWidth += (nMaxDigit - GetSignWidth()) * nSignCount;
+ if (nExpCount)
+ nWidth += (nMaxDigit - GetExpWidth()) * nExpCount;
+
+ if (nDecimalCount || nSignCount || nExpCount)
+ {
+ // Re-calculate.
+ nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
+ if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
+ // Failed to get output string. Bail out.
+ return;
+ }
+
+ long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString);
+ if (nActualTextWidth > nWidth)
+ {
+ // Even after the decimal adjustment the text doesn't fit. Give up.
+ SetHashText();
+ return;
+ }
+
+ TextChanged();
+ pLastCell = NULL; // #i113022# equal cell and format in another column may give different string
+}
+
+void ScDrawStringsVars::SetAutoText( const String& rAutoText )
+{
+ aString = rAutoText;
+
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+ aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
+ aTextSize.Height() = pFmtDevice->GetTextHeight();
+
+ if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = pOutput->GetStretch();
+ aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
+ }
+
+ aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
+ if ( GetOrient() != SVX_ORIENTATION_STANDARD )
+ {
+ long nTemp = aTextSize.Height();
+ aTextSize.Height() = aTextSize.Width();
+ aTextSize.Width() = nTemp;
+ }
+
+ nOriginalWidth = aTextSize.Width();
+ if ( bPixelToLogic )
+ aTextSize = pRefDevice->LogicToPixel( aTextSize );
+
+ pLastCell = NULL; // derselbe Text kann in der naechsten Zelle wieder passen
+}
+
+long ScDrawStringsVars::GetMaxDigitWidth()
+{
+ if (nMaxDigitWidth > 0)
+ return nMaxDigitWidth;
+
+ sal_Char cZero = '0';
+ for (sal_Char i = 0; i < 10; ++i)
+ {
+ sal_Char cDigit = cZero + i;
+ long n = pOutput->pFmtDevice->GetTextWidth(String(cDigit));
+ nMaxDigitWidth = ::std::max(nMaxDigitWidth, n);
+ }
+ return nMaxDigitWidth;
+}
+
+long ScDrawStringsVars::GetSignWidth()
+{
+ if (nSignWidth > 0)
+ return nSignWidth;
+
+ nSignWidth = pOutput->pFmtDevice->GetTextWidth(String('-'));
+ return nSignWidth;
+}
+
+long ScDrawStringsVars::GetDotWidth()
+{
+ if (nDotWidth > 0)
+ return nDotWidth;
+
+ const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator;
+ nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep);
+ return nDotWidth;
+}
+
+long ScDrawStringsVars::GetExpWidth()
+{
+ if (nExpWidth > 0)
+ return nExpWidth;
+
+ nExpWidth = pOutput->pFmtDevice->GetTextWidth(String('E'));
+ return nExpWidth;
+}
+
+void ScDrawStringsVars::TextChanged()
+{
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+ aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
+ aTextSize.Height() = pFmtDevice->GetTextHeight();
+
+ if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = pOutput->GetStretch();
+ aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
+ }
+
+ aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
+ if ( GetOrient() != SVX_ORIENTATION_STANDARD )
+ {
+ long nTemp = aTextSize.Height();
+ aTextSize.Height() = aTextSize.Width();
+ aTextSize.Width() = nTemp;
+ }
+
+ nOriginalWidth = aTextSize.Width();
+ if ( bPixelToLogic )
+ aTextSize = pRefDevice->LogicToPixel( aTextSize );
+}
+
+BOOL ScDrawStringsVars::HasEditCharacters() const
+{
+ static const sal_Unicode pChars[] =
+ {
+ CHAR_NBSP, CHAR_SHY, CHAR_ZWSP, CHAR_LRM, CHAR_RLM, CHAR_NBHY, CHAR_ZWNBSP, 0
+ };
+ return aString.SearchChar( pChars ) != STRING_NOTFOUND;
+}
+
+//==================================================================
+
+double ScOutputData::GetStretch()
+{
+ if ( pRefDevice->IsMapMode() )
+ {
+ // #95920# If a non-trivial MapMode is set, its scale is now already
+ // taken into account in the OutputDevice's font handling
+ // (OutputDevice::ImplNewFont, see #95414#).
+ // The old handling below is only needed for pixel output.
+ return 1.0;
+ }
+
+ // calculation in double is faster than Fraction multiplication
+ // and doesn't overflow
+
+ if ( pRefDevice == pFmtDevice )
+ {
+ MapMode aOld = pRefDevice->GetMapMode();
+ return ((double)aOld.GetScaleY()) / ((double)aOld.GetScaleX()) * ((double)aZoomY) / ((double)aZoomX);
+ }
+ else
+ {
+ // when formatting for printer, device map mode has already been taken care of
+ return ((double)aZoomY) / ((double)aZoomX);
+ }
+}
+
+//==================================================================
+
+//
+// output strings
+//
+
+void lcl_DoHyperlinkResult( OutputDevice* pDev, const Rectangle& rRect, ScBaseCell* pCell )
+{
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+
+ String aCellText;
+ String aURL;
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if ( pFCell->IsHyperLinkCell() )
+ pFCell->GetURLResult( aURL, aCellText );
+ }
+
+ if ( aURL.Len() && pPDFData )
+ {
+ vcl::PDFExtOutDevBookmarkEntry aBookmark;
+ aBookmark.nLinkId = pPDFData->CreateLink( rRect );
+ aBookmark.aBookmark = aURL;
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
+ rBookmarks.push_back( aBookmark );
+ }
+}
+
+void ScOutputData::SetSyntaxColor( Font* pFont, ScBaseCell* pCell )
+{
+ if (pCell)
+ {
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ pFont->SetColor( *pValueColor );
+ break;
+ case CELLTYPE_STRING:
+ pFont->SetColor( *pTextColor );
+ break;
+ case CELLTYPE_FORMULA:
+ pFont->SetColor( *pFormulaColor );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+void lcl_SetEditColor( EditEngine& rEngine, const Color& rColor )
+{
+ ESelection aSel( 0, 0, rEngine.GetParagraphCount(), 0 );
+ SfxItemSet aSet( rEngine.GetEmptyItemSet() );
+ aSet.Put( SvxColorItem( rColor, EE_CHAR_COLOR ) );
+ rEngine.QuickSetAttribs( aSet, aSel );
+ // function is called with update mode set to FALSE
+}
+
+void ScOutputData::SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell )
+{
+ if (pCell)
+ {
+ Color aColor;
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ aColor = *pValueColor;
+ break;
+ case CELLTYPE_STRING:
+ aColor = *pTextColor;
+ break;
+ case CELLTYPE_FORMULA:
+ aColor = *pFormulaColor;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ lcl_SetEditColor( rEngine, aColor );
+ }
+}
+
+BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
+ SCCOL& rOverX, SCROW& rOverY,
+ BOOL bVisRowChanged )
+{
+ BOOL bDoMerge = FALSE;
+ BOOL bIsLeft = ( nX == nVisX1 );
+ BOOL bIsTop = ( nY == nVisY1 ) || bVisRowChanged;
+
+ CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
+ if ( pInfo->bHOverlapped && pInfo->bVOverlapped )
+ bDoMerge = bIsLeft && bIsTop;
+ else if ( pInfo->bHOverlapped )
+ bDoMerge = bIsLeft;
+ else if ( pInfo->bVOverlapped )
+ bDoMerge = bIsTop;
+
+ // weiter solange versteckt
+/* if (!bDoMerge)
+ return FALSE;
+*/
+
+ rOverX = nX;
+ rOverY = nY;
+ BOOL bHOver = pInfo->bHOverlapped;
+ BOOL bVOver = pInfo->bVOverlapped;
+ BOOL bHidden;
+
+ while (bHOver) // nY konstant
+ {
+ --rOverX;
+ bHidden = pDoc->ColHidden(rOverX, nTab);
+ if ( !bDoMerge && !bHidden )
+ return FALSE;
+
+ if (rOverX >= nX1 && !bHidden)
+ {
+// rVirtPosX -= pRowInfo[0].pCellInfo[rOverX+1].nWidth;
+ bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
+ bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
+ }
+ else
+ {
+// if (!bClipVirt)
+// rVirtPosX -= (long) (pDoc->GetColWidth( rOverX, nTab ) * nPPTX);
+ USHORT nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ bHOver = ((nOverlap & SC_MF_HOR) != 0);
+ bVOver = ((nOverlap & SC_MF_VER) != 0);
+ }
+ }
+
+ while (bVOver)
+ {
+ --rOverY;
+ bHidden = pDoc->RowHidden(rOverY, nTab);
+ if ( !bDoMerge && !bHidden )
+ return FALSE;
+
+ if (nArrY>0)
+ --nArrY; // lokale Kopie !
+
+ if (rOverX >= nX1 && rOverY >= nY1 &&
+ !pDoc->ColHidden(rOverX, nTab) &&
+ !pDoc->RowHidden(rOverY, nTab) &&
+ pRowInfo[nArrY].nRowNo == rOverY)
+ {
+// rVirtPosY -= pRowInfo[nArrY].nHeight;
+ bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
+ bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
+ }
+ else
+ {
+// if (!bClipVirt)
+// rVirtPosY -= (long) (pDoc->GetRowHeight( rOverY, nTab ) * nPPTY);
+ USHORT nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ bHOver = ((nOverlap & SC_MF_HOR) != 0);
+ bVOver = ((nOverlap & SC_MF_VER) != 0);
+ }
+ }
+
+ return TRUE;
+}
+
+inline BOOL StringDiffer( const ScPatternAttr*& rpOldPattern, const ScPatternAttr*& rpNewPattern )
+{
+ DBG_ASSERT( rpNewPattern, "pNewPattern" );
+
+ if ( rpNewPattern == rpOldPattern )
+ return FALSE;
+ else if ( !rpOldPattern )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT ) != &rpOldPattern->GetItem( ATTR_FONT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_UNDERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_OVERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_WORDLINE ) != &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ) != &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_CONTOUR ) != &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_SHADOWED ) != &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_COLOR ) != &rpOldPattern->GetItem( ATTR_FONT_COLOR ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_STACKED ) != &rpOldPattern->GetItem( ATTR_STACKED ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_LINEBREAK ) != &rpOldPattern->GetItem( ATTR_LINEBREAK ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_MARGIN ) != &rpOldPattern->GetItem( ATTR_MARGIN ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_ROTATE_VALUE ) != &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FORBIDDEN_RULES ) != &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ) != &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_RELIEF ) != &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) )
+ return TRUE;
+ else if ( &rpNewPattern->GetItem( ATTR_BACKGROUND ) != &rpOldPattern->GetItem( ATTR_BACKGROUND ) )
+ return TRUE; // needed with automatic text color
+ else
+ {
+ rpOldPattern = rpNewPattern;
+ return FALSE;
+ }
+}
+
+inline void lcl_CreateInterpretProgress( BOOL& bProgress, ScDocument* pDoc,
+ ScFormulaCell* pFCell )
+{
+ if ( !bProgress && pFCell->GetDirty() )
+ {
+ ScProgress::CreateInterpretProgress( pDoc, TRUE );
+ bProgress = TRUE;
+ }
+}
+
+inline BYTE GetScriptType( ScDocument* pDoc, ScBaseCell* pCell,
+ const ScPatternAttr* pPattern,
+ const SfxItemSet* pCondSet )
+{
+ return pDoc->GetCellScriptType( pCell, pPattern->GetNumberFormat( pDoc->GetFormatTable(), pCondSet ) );
+}
+
+inline BOOL IsAmbiguousScript( BYTE nScript )
+{
+ return ( nScript != SCRIPTTYPE_LATIN &&
+ nScript != SCRIPTTYPE_ASIAN &&
+ nScript != SCRIPTTYPE_COMPLEX );
+}
+
+BOOL ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
+{
+ // pThisRowInfo may be NULL
+
+ BOOL bEmpty;
+ if ( pThisRowInfo && nX <= nX2 )
+ bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
+ else
+ bEmpty = ( pDoc->GetCell( ScAddress( nX, nY, nTab ) ) == NULL );
+
+ if ( !bEmpty && ( nX < nX1 || nX > nX2 || !pThisRowInfo ) )
+ {
+ // for the range nX1..nX2 in RowInfo, cell protection attribute is already evaluated
+ // into bEmptyCellText in ScDocument::FillInfo / lcl_HidePrint (printfun)
+
+ BOOL bIsPrint = ( eType == OUTTYPE_PRINTER );
+
+ if ( bIsPrint || bTabProtected )
+ {
+ const ScProtectionAttr* pAttr = (const ScProtectionAttr*)
+ pDoc->GetEffItem( nX, nY, nTab, ATTR_PROTECTION );
+ if ( bIsPrint && pAttr->GetHidePrint() )
+ bEmpty = TRUE;
+ else if ( bTabProtected )
+ {
+ if ( pAttr->GetHideCell() )
+ bEmpty = TRUE;
+ else if ( bShowFormulas && pAttr->GetHideFormula() )
+ {
+ ScBaseCell* pCell = pDoc->GetCell( ScAddress( nX, nY, nTab ) );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ bEmpty = TRUE;
+ }
+ }
+ }
+ }
+ return bEmpty;
+}
+
+void ScOutputData::GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTabP, ScBaseCell*& rpCell )
+{
+ pDoc->GetCell( nCol, nRow, nTabP, rpCell );
+ if ( rpCell && IsEmptyCellText( NULL, nCol, nRow ) )
+ rpCell = NULL;
+}
+
+BOOL ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
+{
+ // apply the same logic here as in DrawStrings/DrawEdit:
+ // Stop at non-empty or merged or overlapped cell,
+ // where a note is empty as well as a cell that's hidden by protection settings
+
+ const ScBaseCell* pCell = pDoc->GetCell( ScAddress( nX, nY, nTab ) );
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE && !IsEmptyCellText( NULL, nX, nY ) )
+ {
+ return FALSE;
+ }
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
+ if ( ((const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE)).IsMerged() ||
+ ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).IsOverlapped() )
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// nX, nArrY: loop variables from DrawStrings / DrawEdit
+// nPosX, nPosY: corresponding positions for nX, nArrY
+// nCellX, nCellY: position of the cell that contains the text
+// nNeeded: Text width, including margin
+// rPattern: cell format at nCellX, nCellY
+// nHorJustify: horizontal alignment (visual) to determine which cells to use for long strings
+// bCellIsValue: if set, don't extend into empty cells
+// bBreak: if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set)
+// bOverwrite: if set, also extend into non-empty cells (for rotated text)
+// rParam output: various area parameters.
+
+void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
+ SCCOL nCellX, SCROW nCellY, long nNeeded,
+ const ScPatternAttr& rPattern,
+ USHORT nHorJustify, bool bCellIsValue,
+ bool bBreak, bool bOverwrite,
+ OutputAreaParam& rParam )
+{
+ // rThisRowInfo may be for a different row than nCellY, is still used for clip marks
+ RowInfo& rThisRowInfo = pRowInfo[nArrY];
+
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nCellPosX = nPosX; // find nCellX position, starting at nX/nPosX
+ SCCOL nCompCol = nX;
+ while ( nCellX > nCompCol )
+ {
+ //! extra member function for width?
+ long nColWidth = ( nCompCol <= nX2 ) ?
+ pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
+ (long) ( pDoc->GetColWidth( nCompCol, nTab ) * nPPTX );
+ nCellPosX += nColWidth * nLayoutSign;
+ ++nCompCol;
+ }
+ while ( nCellX < nCompCol )
+ {
+ --nCompCol;
+ long nColWidth = ( nCompCol <= nX2 ) ?
+ pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
+ (long) ( pDoc->GetColWidth( nCompCol, nTab ) * nPPTX );
+ nCellPosX -= nColWidth * nLayoutSign;
+ }
+
+ long nCellPosY = nPosY; // find nCellY position, starting at nArrY/nPosY
+ SCSIZE nCompArr = nArrY;
+ SCROW nCompRow = pRowInfo[nCompArr].nRowNo;
+ while ( nCellY > nCompRow )
+ {
+ if ( nCompArr + 1 < nArrCount )
+ {
+ nCellPosY += pRowInfo[nCompArr].nHeight;
+ ++nCompArr;
+ nCompRow = pRowInfo[nCompArr].nRowNo;
+ }
+ else
+ {
+ USHORT nDocHeight = pDoc->GetRowHeight( nCompRow, nTab );
+ if ( nDocHeight )
+ nCellPosY += (long) ( nDocHeight * nPPTY );
+ ++nCompRow;
+ }
+ }
+ nCellPosY -= (long) pDoc->GetScaledRowHeight( nCellY, nCompRow-1, nTab, nPPTY );
+
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)&rPattern.GetItem( ATTR_MERGE );
+ BOOL bMerged = pMerge->IsMerged();
+ long nMergeCols = pMerge->GetColMerge();
+ if ( nMergeCols == 0 )
+ nMergeCols = 1;
+ long nMergeRows = pMerge->GetRowMerge();
+ if ( nMergeRows == 0 )
+ nMergeRows = 1;
+
+ long i;
+ long nMergeSizeX = 0;
+ for ( i=0; i<nMergeCols; i++ )
+ {
+ long nColWidth = ( nCellX+i <= nX2 ) ?
+ pRowInfo[0].pCellInfo[nCellX+i+1].nWidth :
+ (long) ( pDoc->GetColWidth( sal::static_int_cast<SCCOL>(nCellX+i), nTab ) * nPPTX );
+ nMergeSizeX += nColWidth;
+ }
+ long nMergeSizeY = 0;
+ short nDirect = 0;
+ if ( rThisRowInfo.nRowNo == nCellY )
+ {
+ // take first row's height from row info
+ nMergeSizeY += rThisRowInfo.nHeight;
+ nDirect = 1; // skip in loop
+ }
+ // following rows always from document
+ nMergeSizeY += (long) pDoc->GetScaledRowHeight( nCellY+nDirect, nCellY+nMergeRows-1, nTab, nPPTY);
+
+ --nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines)
+
+ rParam.mnColWidth = nMergeSizeX; // store the actual column width.
+
+ //
+ // construct the rectangles using logical left/right values (justify is called at the end)
+ //
+
+ // rAlignRect is the single cell or merged area, used for alignment.
+
+ rParam.maAlignRect.Left() = nCellPosX;
+ rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign;
+ rParam.maAlignRect.Top() = nCellPosY;
+ rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1;
+
+ // rClipRect is all cells that are used for output.
+ // For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used.
+
+ rParam.maClipRect = rParam.maAlignRect;
+ if ( nNeeded > nMergeSizeX )
+ {
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify;
+
+ long nMissing = nNeeded - nMergeSizeX;
+ long nLeftMissing = 0;
+ long nRightMissing = 0;
+ switch ( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ nRightMissing = nMissing;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ nLeftMissing = nMissing;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ nLeftMissing = nMissing / 2;
+ nRightMissing = nMissing - nLeftMissing;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ // nLeftMissing, nRightMissing are logical, eHorJust values are visual
+ if ( bLayoutRTL )
+ ::std::swap( nLeftMissing, nRightMissing );
+
+ SCCOL nRightX = nCellX;
+ SCCOL nLeftX = nCellX;
+ if ( !bMerged && !bCellIsValue && !bBreak )
+ {
+ // look for empty cells into which the text can be extended
+
+ while ( nRightMissing > 0 && nRightX < MAXCOL && ( bOverwrite || IsAvailable( nRightX+1, nCellY ) ) )
+ {
+ ++nRightX;
+ long nAdd = (long) ( pDoc->GetColWidth( nRightX, nTab ) * nPPTX );
+ nRightMissing -= nAdd;
+ rParam.maClipRect.Right() += nAdd * nLayoutSign;
+
+ if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 )
+ rThisRowInfo.pCellInfo[nRightX].bHideGrid = TRUE;
+ }
+
+ while ( nLeftMissing > 0 && nLeftX > 0 && ( bOverwrite || IsAvailable( nLeftX-1, nCellY ) ) )
+ {
+ if ( rThisRowInfo.nRowNo == nCellY && nLeftX >= nX1 && nLeftX <= nX2 )
+ rThisRowInfo.pCellInfo[nLeftX].bHideGrid = TRUE;
+
+ --nLeftX;
+ long nAdd = (long) ( pDoc->GetColWidth( nLeftX, nTab ) * nPPTX );
+ nLeftMissing -= nAdd;
+ rParam.maClipRect.Left() -= nAdd * nLayoutSign;
+ }
+ }
+
+ // Set flag and reserve space for clipping mark triangle,
+ // even if rThisRowInfo isn't for nCellY (merged cells).
+ if ( nRightMissing > 0 && bMarkClipped && nRightX >= nX1 && nRightX <= nX2 && !bBreak && !bCellIsValue )
+ {
+ rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT;
+ bAnyClipped = TRUE;
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign;
+ }
+ if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue )
+ {
+ rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT;
+ bAnyClipped = TRUE;
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ rParam.maClipRect.Left() += nMarkPixel * nLayoutSign;
+ }
+
+ rParam.mbLeftClip = ( nLeftMissing > 0 );
+ rParam.mbRightClip = ( nRightMissing > 0 );
+ }
+ else
+ {
+ rParam.mbLeftClip = rParam.mbRightClip = FALSE;
+
+ // leave space for AutoFilter on screen
+ // (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize)
+
+ if ( eType==OUTTYPE_WINDOW &&
+ ( static_cast<const ScMergeFlagAttr&>(rPattern.GetItem(ATTR_MERGE_FLAG)).GetValue() & SC_MF_AUTO ) &&
+ ( !bBreak || pRefDevice == pFmtDevice ) )
+ {
+ // filter drop-down width is now independent from row height
+ const long nFilter = DROPDOWN_BITMAP_SIZE;
+ BOOL bFit = ( nNeeded + nFilter <= nMergeSizeX );
+ if ( bFit || bCellIsValue )
+ {
+ // content fits even in the remaining area without the filter button
+ // -> align within that remaining area
+
+ rParam.maAlignRect.Right() -= nFilter * nLayoutSign;
+ rParam.maClipRect.Right() -= nFilter * nLayoutSign;
+
+ // if a number doesn't fit, don't hide part of the number behind the button
+ // -> set clip flags, so "###" replacement is used (but also within the smaller area)
+
+ if ( !bFit )
+ rParam.mbLeftClip = rParam.mbRightClip = TRUE;
+ }
+ }
+ }
+
+ // justify both rectangles for alignment calculation, use with DrawText etc.
+
+ rParam.maAlignRect.Justify();
+ rParam.maClipRect.Justify();
+
+#if 0
+ //! Test !!!
+ pDev->Push();
+ pDev->SetLineColor();
+ pDev->SetFillColor( COL_LIGHTGREEN );
+ pDev->DrawRect( pDev->PixelToLogic(rParam.maClipRect) );
+ pDev->DrawRect( rParam.maClipRect ); // print preview
+ pDev->Pop();
+ //! Test !!!
+#endif
+}
+
+void ScOutputData::DrawStrings( BOOL bPixelToLogic )
+{
+ DBG_ASSERT( pDev == pRefDevice ||
+ pDev->GetMapMode().GetMapUnit() == pRefDevice->GetMapMode().GetMapUnit(),
+ "DrawStrings: unterschiedliche MapUnits ?!?!" );
+
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+
+ BOOL bWasIdleDisabled = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( TRUE );
+ Size aMinSize = pRefDevice->PixelToLogic(Size(0,100)); // erst darueber wird ausgegeben
+// UINT32 nMinHeight = aMinSize.Height() / 200; // 1/2 Pixel
+
+ ScDrawStringsVars aVars( this, bPixelToLogic );
+
+ BOOL bProgress = FALSE;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ nInitPosX += nMirrorW - 1; // pixels
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ SCCOL nLastContentCol = MAXCOL;
+ if ( nX2 < MAXCOL )
+ nLastContentCol = sal::static_int_cast<SCCOL>(
+ nLastContentCol - pDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
+ SCCOL nLoopStartX = nX1;
+ if ( nX1 > 0 )
+ --nLoopStartX; // start before nX1 for rest of long text to the left
+
+ // variables for GetOutputArea
+ OutputAreaParam aAreaParam;
+ BOOL bCellIsValue = FALSE;
+ long nNeededWidth = 0;
+ SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ const ScPatternAttr* pPattern = NULL;
+ const SfxItemSet* pCondSet = NULL;
+ const ScPatternAttr* pOldPattern = NULL;
+ const SfxItemSet* pOldCondSet = NULL;
+ BYTE nOldScript = 0;
+
+ // alternative pattern instances in case we need to modify the pattern
+ // before processing the cell value.
+ ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+// long nCellHeight = (long) pThisRowInfo->nHeight;
+ long nPosX = nInitPosX;
+ if ( nLoopStartX < nX1 )
+ nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * nLayoutSign;
+ for (SCCOL nX=nLoopStartX; nX<=nX2; nX++)
+ {
+ BOOL bMergeEmpty = FALSE;
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ BOOL bEmpty = nX < nX1 || pInfo->bEmptyCellText;
+
+ SCCOL nCellX = nX; // position where the cell really starts
+ SCROW nCellY = nY;
+ BOOL bDoCell = FALSE;
+ BOOL bNeedEdit = FALSE;
+
+ //
+ // Part of a merged cell?
+ //
+
+ BOOL bOverlapped = ( pInfo->bHOverlapped || pInfo->bVOverlapped );
+ if ( bOverlapped )
+ {
+ bEmpty = TRUE;
+
+ SCCOL nOverX; // start of the merged cells
+ SCROW nOverY;
+ BOOL bVisChanged = !pRowInfo[nArrY-1].bChanged;
+ if (GetMergeOrigin( nX,nY, nArrY, nOverX,nOverY, bVisChanged ))
+ {
+ nCellX = nOverX;
+ nCellY = nOverY;
+ bDoCell = TRUE;
+ }
+ else
+ bMergeEmpty = TRUE;
+ }
+
+ //
+ // Rest of a long text further to the left?
+ //
+
+ if ( bEmpty && !bMergeEmpty && nX < nX1 && !bOverlapped )
+ {
+ SCCOL nTempX=nX1;
+ while (nTempX > 0 && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
+ --nTempX;
+
+ if ( nTempX < nX1 &&
+ !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
+ !pDoc->HasAttrib( nTempX,nY,nTab, nX1,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ nCellX = nTempX;
+ bDoCell = TRUE;
+ }
+ }
+
+ //
+ // Rest of a long text further to the right?
+ //
+
+ if ( bEmpty && !bMergeEmpty && nX == nX2 && !bOverlapped )
+ {
+ // don't have to look further than nLastContentCol
+
+ SCCOL nTempX=nX;
+ while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
+ ++nTempX;
+
+ if ( nTempX > nX &&
+ !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
+ !pDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ nCellX = nTempX;
+ bDoCell = TRUE;
+ }
+ }
+
+ //
+ // normal visible cell
+ //
+
+ if (!bEmpty)
+ bDoCell = TRUE;
+
+ //
+ // don't output the cell that's being edited
+ //
+
+ if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
+ bDoCell = FALSE;
+
+ //
+ // output the cell text
+ //
+
+ ScBaseCell* pCell = NULL;
+ if (bDoCell)
+ {
+ if ( nCellY == nY && nCellX == nX && nCellX >= nX1 && nCellX <= nX2 )
+ pCell = pThisRowInfo->pCellInfo[nCellX+1].pCell;
+ else
+ GetVisibleCell( nCellX, nCellY, nTab, pCell ); // get from document
+ if ( !pCell )
+ bDoCell = FALSE;
+ else if ( pCell->GetCellType() == CELLTYPE_EDIT )
+ bNeedEdit = TRUE;
+ }
+ if (bDoCell && !bNeedEdit)
+ {
+ if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 )
+ {
+ CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
+ pPattern = rCellInfo.pPatternAttr;
+ pCondSet = rCellInfo.pConditionSet;
+
+ if ( !pPattern )
+ {
+ // #i68085# pattern from cell info for hidden columns is null,
+ // test for null is quicker than using column flags
+ pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
+ pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
+ }
+ }
+ else // get from document
+ {
+ pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
+ pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
+ }
+
+ if (pCell->HasValueData() &&
+ static_cast<const SfxBoolItem&>(
+ pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue())
+ {
+ // Disable line break when the cell content is numeric.
+ aAltPatterns.push_back(new ScPatternAttr(*pPattern));
+ ScPatternAttr* pAltPattern = &aAltPatterns.back();
+ SfxBoolItem aLineBreak(ATTR_LINEBREAK, false);
+ pAltPattern->GetItemSet().Put(aLineBreak);
+ pPattern = pAltPattern;
+ }
+
+ BYTE nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet );
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+ if ( pPattern != pOldPattern || pCondSet != pOldCondSet ||
+ nScript != nOldScript || bSyntaxMode )
+ {
+ if ( StringDiffer(pOldPattern,pPattern) ||
+ pCondSet != pOldCondSet || nScript != nOldScript || bSyntaxMode )
+ aVars.SetPattern( pPattern, pCondSet, pCell, nScript );
+ else
+ aVars.SetPatternSimple( pPattern, pCondSet );
+ pOldPattern = pPattern;
+ pOldCondSet = pCondSet;
+ nOldScript = nScript;
+ }
+
+ // use edit engine for rotated, stacked or mixed-script text
+ if ( aVars.GetOrient() == SVX_ORIENTATION_STACKED ||
+ aVars.IsRotated() || IsAmbiguousScript(nScript) )
+ bNeedEdit = TRUE;
+ }
+ if (bDoCell && !bNeedEdit)
+ {
+ BOOL bFormulaCell = (pCell->GetCellType() == CELLTYPE_FORMULA );
+ if ( bFormulaCell )
+ lcl_CreateInterpretProgress( bProgress, pDoc, (ScFormulaCell*)pCell );
+ if ( aVars.SetText(pCell) )
+ pOldPattern = NULL;
+ bNeedEdit = aVars.HasEditCharacters() ||
+ (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult());
+ }
+ long nTotalMargin = 0;
+ if (bDoCell && !bNeedEdit)
+ {
+ CellType eCellType = pCell->GetCellType();
+ bCellIsValue = ( eCellType == CELLTYPE_VALUE );
+ if ( eCellType == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ bCellIsValue = pFCell->IsRunning() || pFCell->IsValue();
+ }
+
+ eOutHorJust = ( aVars.GetHorJust() != SVX_HOR_JUSTIFY_STANDARD ) ?
+ aVars.GetHorJust() :
+ ( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
+
+ if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
+
+ BOOL bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK );
+ BOOL bRepeat = aVars.IsRepeat() && !bBreak;
+ BOOL bShrink = aVars.IsShrink() && !bBreak && !bRepeat;
+
+ nTotalMargin =
+ static_cast<long>(aVars.GetLeftTotal() * nPPTX) +
+ static_cast<long>(aVars.GetMargin()->GetRightMargin() * nPPTX);
+
+ nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin;
+
+ // GetOutputArea gives justfied rectangles
+ GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth,
+ *pPattern, sal::static_int_cast<USHORT>(eOutHorJust),
+ bCellIsValue || bRepeat || bShrink, bBreak, FALSE,
+ aAreaParam );
+
+ if ( bShrink )
+ {
+ if ( aVars.GetOrient() != SVX_ORIENTATION_STANDARD )
+ {
+ // Only horizontal scaling is handled here.
+ // DrawEdit is used to vertically scale 90 deg rotated text.
+ bNeedEdit = TRUE;
+ }
+ else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) // horizontal
+ {
+ long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
+ long nScaleSize = aVars.GetTextSize().Width(); // without margin
+
+ if ( nScaleSize > 0 ) // 0 if the text is empty (formulas, number formats)
+ {
+ long nScale = ( nAvailable * 100 ) / nScaleSize;
+
+ aVars.SetShrinkScale( nScale, nOldScript );
+ long nNewSize = aVars.GetTextSize().Width();
+
+ USHORT nShrinkAgain = 0;
+ while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
+ {
+ // If the text is still too large, reduce the scale again by 10%, until it fits,
+ // at most 7 times (it's less than 50% of the calculated scale then).
+
+ nScale = ( nScale * 9 ) / 10;
+ aVars.SetShrinkScale( nScale, nOldScript );
+ nNewSize = aVars.GetTextSize().Width();
+ ++nShrinkAgain;
+ }
+ // If even at half the size the font still isn't rendered smaller,
+ // fall back to normal clipping (showing ### for numbers).
+ if ( nNewSize <= nAvailable )
+ aAreaParam.mbLeftClip = aAreaParam.mbRightClip = FALSE;
+
+ pOldPattern = NULL;
+ }
+ }
+ }
+
+ if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip )
+ {
+ long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
+ long nRepeatSize = aVars.GetTextSize().Width(); // without margin
+ // When formatting for the printer, the text sizes don't always add up.
+ // Round down (too few repetitions) rather than exceeding the cell size then:
+ if ( pFmtDevice != pRefDevice )
+ ++nRepeatSize;
+ if ( nRepeatSize > 0 )
+ {
+ long nRepeatCount = nAvailable / nRepeatSize;
+ if ( nRepeatCount > 1 )
+ {
+ String aCellStr = aVars.GetString();
+ String aRepeated = aCellStr;
+ for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
+ aRepeated.Append( aCellStr );
+ aVars.SetAutoText( aRepeated );
+ }
+ }
+ }
+
+ // use edit engine if automatic line breaks are needed
+ if ( bBreak )
+ {
+ if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD )
+ bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip );
+ else
+ {
+ long nHeight = aVars.GetTextSize().Height() +
+ (long)(aVars.GetMargin()->GetTopMargin()*nPPTY) +
+ (long)(aVars.GetMargin()->GetBottomMargin()*nPPTY);
+ bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() );
+ }
+ }
+ }
+ if (bNeedEdit)
+ {
+ // mark the cell in CellInfo to be drawn in DrawEdit:
+ // Cells to the left are marked directly, cells to the
+ // right are handled by the flag for nX2
+ SCCOL nMarkX = ( nCellX <= nX2 ) ? nCellX : nX2;
+ RowInfo* pMarkRowInfo = ( nCellY == nY ) ? pThisRowInfo : &pRowInfo[0];
+ pMarkRowInfo->pCellInfo[nMarkX+1].bEditEngine = TRUE;
+ bDoCell = FALSE; // don't draw here
+ }
+ if ( bDoCell )
+ {
+ if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
+ {
+ // Adjust the decimals to fit the available column width.
+ aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin);
+ nNeededWidth = aVars.GetTextSize().Width() +
+ (long) ( aVars.GetLeftTotal() * nPPTX ) +
+ (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX );
+ if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() )
+ aAreaParam.mbLeftClip = aAreaParam.mbRightClip = FALSE;
+
+ // If the "###" replacement doesn't fit into the cells, no clip marks
+ // are shown, as the "###" already denotes too little space.
+ // The rectangles from the first GetOutputArea call remain valid.
+ }
+
+ long nJustPosX = aAreaParam.maAlignRect.Left(); // "justified" - effect of alignment will be added
+ long nJustPosY = aAreaParam.maAlignRect.Top();
+ long nAvailWidth = aAreaParam.maAlignRect.GetWidth();
+ long nOutHeight = aAreaParam.maAlignRect.GetHeight();
+
+ BOOL bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
+ if ( aAreaParam.maClipRect.Left() < nScrX )
+ {
+ aAreaParam.maClipRect.Left() = nScrX;
+ aAreaParam.mbLeftClip = TRUE;
+ }
+ if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
+ {
+ aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
+ aAreaParam.mbRightClip = TRUE;
+ }
+
+ BOOL bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
+ BOOL bVClip = FALSE;
+
+ if ( aAreaParam.maClipRect.Top() < nScrY )
+ {
+ aAreaParam.maClipRect.Top() = nScrY;
+ bVClip = TRUE;
+ }
+ if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
+ {
+ aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
+ bVClip = TRUE;
+ }
+
+ //
+ // horizontalen Platz testen
+ //
+
+ BOOL bRightAdjusted = FALSE; // to correct text width calculation later
+ BOOL bNeedEditEngine = FALSE;
+ if ( !bNeedEditEngine && !bOutside )
+ {
+ switch (eOutHorJust)
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ nJustPosX += (long) ( aVars.GetLeftTotal() * nPPTX );
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ nJustPosX += nAvailWidth - aVars.GetTextSize().Width() -
+ (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX );
+ bRightAdjusted = TRUE;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ nJustPosX += ( nAvailWidth - aVars.GetTextSize().Width() +
+ (long) ( aVars.GetLeftTotal() * nPPTX ) -
+ (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ) ) / 2;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ long nTestClipHeight = aVars.GetTextSize().Height();
+ switch (aVars.GetVerJust())
+ {
+ case SVX_VER_JUSTIFY_TOP:
+ {
+ long nTop = (long)( aVars.GetMargin()->GetTopMargin() * nPPTY );
+ nJustPosY += nTop;
+ nTestClipHeight += nTop;
+ }
+ break;
+ case SVX_VER_JUSTIFY_BOTTOM:
+ {
+ long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * nPPTY );
+ nJustPosY += nOutHeight - aVars.GetTextSize().Height() - nBot;
+ nTestClipHeight += nBot;
+ }
+ break;
+ case SVX_VER_JUSTIFY_CENTER:
+ {
+ long nTop = (long)( aVars.GetMargin()->GetTopMargin() * nPPTY );
+ long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * nPPTY );
+ nJustPosY += ( nOutHeight + nTop -
+ aVars.GetTextSize().Height() - nBot ) / 2;
+ nTestClipHeight += Abs( nTop - nBot );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if ( nTestClipHeight > nOutHeight )
+ {
+ // kein vertikales Clipping beim Drucken von Zellen mit
+ // optimaler Hoehe, ausser bei Groesse in bedingter Formatierung
+ if ( eType != OUTTYPE_PRINTER ||
+ ( pDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
+ ( aVars.HasCondHeight() ) )
+ bVClip = TRUE;
+ }
+
+ if ( bHClip || bVClip )
+ {
+ // nur die betroffene Dimension clippen,
+ // damit bei nicht-proportionalem Resize nicht alle
+ // rechtsbuendigen Zahlen abgeschnitten werden:
+
+ if (!bHClip)
+ {
+ aAreaParam.maClipRect.Left() = nScrX;
+ aAreaParam.maClipRect.Right() = nScrX+nScrW;
+ }
+ if (!bVClip)
+ {
+ aAreaParam.maClipRect.Top() = nScrY;
+ aAreaParam.maClipRect.Bottom() = nScrY+nScrH;
+ }
+
+ // aClipRect is not used after SetClipRegion/IntersectClipRegion,
+ // so it can be modified here
+ if (bPixelToLogic)
+ aAreaParam.maClipRect = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
+
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aAreaParam.maClipRect );
+ }
+ else
+ pDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
+ }
+
+ Point aURLStart( nJustPosX, nJustPosY ); // copy before modifying for orientation
+
+ switch (aVars.GetOrient())
+ {
+ case SVX_ORIENTATION_STANDARD:
+ nJustPosY += aVars.GetAscent();
+ break;
+ case SVX_ORIENTATION_TOPBOTTOM:
+ nJustPosX += aVars.GetTextSize().Width() - aVars.GetAscent();
+ break;
+ case SVX_ORIENTATION_BOTTOMTOP:
+ nJustPosY += aVars.GetTextSize().Height();
+ nJustPosX += aVars.GetAscent();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ // When clipping, the visible part is now completely defined by the alignment,
+ // there's no more special handling to show the right part of RTL text.
+
+ Point aDrawTextPos( nJustPosX, nJustPosY );
+ if ( bPixelToLogic )
+ {
+ // undo text width adjustment in pixels
+ if (bRightAdjusted)
+ aDrawTextPos.X() += aVars.GetTextSize().Width();
+
+ aDrawTextPos = pRefDevice->PixelToLogic( aDrawTextPos );
+
+ // redo text width adjustment in logic units
+ if (bRightAdjusted)
+ aDrawTextPos.X() -= aVars.GetOriginalWidth();
+ }
+
+ // in Metafiles immer DrawTextArray, damit die Positionen mit
+ // aufgezeichnet werden (fuer nicht-proportionales Resize):
+
+ String aString = aVars.GetString();
+ if (bMetaFile || pFmtDevice != pDev || aZoomX != aZoomY)
+ {
+ sal_Int32* pDX = new sal_Int32[aString.Len()];
+ pFmtDevice->GetTextArray( aString, pDX );
+
+ if ( !pRefDevice->GetConnectMetaFile() ||
+ pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = GetStretch();
+ xub_StrLen nLen = aString.Len();
+ for (xub_StrLen i=0; i<nLen; i++)
+ pDX[i] = (long)(pDX[i] / fMul + 0.5);
+ }
+
+ pDev->DrawTextArray( aDrawTextPos, aString, pDX );
+ delete[] pDX;
+ }
+ else
+ pDev->DrawText( aDrawTextPos, aString );
+
+ if ( bHClip || bVClip )
+ {
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+ }
+
+ // PDF: whole-cell hyperlink from formula?
+ BOOL bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
+ if ( bHasURL )
+ {
+ Rectangle aURLRect( aURLStart, aVars.GetTextSize() );
+ lcl_DoHyperlinkResult( pDev, aURLRect, pCell );
+ }
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+ if ( bProgress )
+ ScProgress::DeleteInterpretProgress();
+ pDoc->DisableIdle( bWasIdleDisabled );
+}
+
+// -------------------------------------------------------------------------------
+
+void lcl_ClearEdit( EditEngine& rEngine ) // Text und Attribute
+{
+ rEngine.SetUpdateMode( FALSE );
+
+ rEngine.SetText(EMPTY_STRING);
+ // keine Para-Attribute uebrigbehalten...
+ const SfxItemSet& rPara = rEngine.GetParaAttribs(0);
+ if (rPara.Count())
+ rEngine.SetParaAttribs( 0,
+ SfxItemSet( *rPara.GetPool(), rPara.GetRanges() ) );
+}
+
+BOOL lcl_SafeIsValue( ScBaseCell* pCell )
+{
+ if (!pCell)
+ return FALSE;
+
+ BOOL bRet = FALSE;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ bRet = TRUE;
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( pFCell->IsRunning() || pFCell->IsValue() )
+ bRet = TRUE;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return bRet;
+}
+
+void lcl_ScaleFonts( EditEngine& rEngine, long nPercent )
+{
+ BOOL bUpdateMode = rEngine.GetUpdateMode();
+ if ( bUpdateMode )
+ rEngine.SetUpdateMode( FALSE );
+
+ USHORT nParCount = rEngine.GetParagraphCount();
+ for (USHORT nPar=0; nPar<nParCount; nPar++)
+ {
+ SvUShorts aPortions;
+ rEngine.GetPortions( nPar, aPortions );
+
+ USHORT nPCount = aPortions.Count();
+ USHORT nStart = 0;
+ for ( USHORT nPos=0; nPos<nPCount; nPos++ )
+ {
+ USHORT nEnd = aPortions.GetObject( nPos );
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ SfxItemSet aAttribs = rEngine.GetAttribs( aSel );
+
+ long nWestern = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT)).GetHeight();
+ long nCJK = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CJK)).GetHeight();
+ long nCTL = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CTL)).GetHeight();
+
+ nWestern = ( nWestern * nPercent ) / 100;
+ nCJK = ( nCJK * nPercent ) / 100;
+ nCTL = ( nCTL * nPercent ) / 100;
+
+ aAttribs.Put( SvxFontHeightItem( nWestern, 100, EE_CHAR_FONTHEIGHT ) );
+ aAttribs.Put( SvxFontHeightItem( nCJK, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ aAttribs.Put( SvxFontHeightItem( nCTL, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+
+ rEngine.QuickSetAttribs( aAttribs, aSel ); //! remove paragraph attributes from aAttribs?
+
+ nStart = nEnd;
+ }
+ }
+
+ if ( bUpdateMode )
+ rEngine.SetUpdateMode( TRUE );
+}
+
+long lcl_GetEditSize( EditEngine& rEngine, BOOL bWidth, BOOL bSwap, long nAttrRotate )
+{
+ if ( bSwap )
+ bWidth = !bWidth;
+
+ if ( nAttrRotate )
+ {
+ long nRealWidth = (long) rEngine.CalcTextWidth();
+ long nRealHeight = rEngine.GetTextHeight();
+
+ // assuming standard mode, otherwise width isn't used
+
+ double nRealOrient = nAttrRotate * F_PI18000; // 1/100th degrees
+ double nAbsCos = fabs( cos( nRealOrient ) );
+ double nAbsSin = fabs( sin( nRealOrient ) );
+ if ( bWidth )
+ return (long) ( nRealWidth * nAbsCos + nRealHeight * nAbsSin );
+ else
+ return (long) ( nRealHeight * nAbsCos + nRealWidth * nAbsSin );
+ }
+ else if ( bWidth )
+ return (long) rEngine.CalcTextWidth();
+ else
+ return rEngine.GetTextHeight();
+}
+
+
+void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect,
+ long nLeftM, long nTopM, long nRightM, long nBottomM,
+ BOOL bWidth, USHORT nOrient, long nAttrRotate, BOOL bPixelToLogic,
+ long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip )
+{
+ if ( !bWidth )
+ {
+ // vertical
+
+ long nScaleSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
+
+ // Don't scale if it fits already.
+ // Allowing to extend into the margin, to avoid scaling at optimal height.
+ if ( nScaleSize <= rAlignRect.GetHeight() )
+ return;
+
+ BOOL bSwap = ( nOrient == SVX_ORIENTATION_TOPBOTTOM || nOrient == SVX_ORIENTATION_BOTTOMTOP );
+ long nAvailable = rAlignRect.GetHeight() - nTopM - nBottomM;
+ long nScale = ( nAvailable * 100 ) / nScaleSize;
+
+ lcl_ScaleFonts( rEngine, nScale );
+ rEngineHeight = lcl_GetEditSize( rEngine, FALSE, bSwap, nAttrRotate );
+ long nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
+
+ USHORT nShrinkAgain = 0;
+ while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
+ {
+ // further reduce, like in DrawStrings
+ lcl_ScaleFonts( rEngine, 90 ); // reduce by 10%
+ rEngineHeight = lcl_GetEditSize( rEngine, FALSE, bSwap, nAttrRotate );
+ nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
+ ++nShrinkAgain;
+ }
+
+ // sizes for further processing (alignment etc):
+ rEngineWidth = lcl_GetEditSize( rEngine, TRUE, bSwap, nAttrRotate );
+ long nPixelWidth = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
+ rNeededPixel = nPixelWidth + nLeftM + nRightM;
+ }
+ else if ( rLeftClip || rRightClip )
+ {
+ // horizontal
+
+ long nAvailable = rAlignRect.GetWidth() - nLeftM - nRightM;
+ long nScaleSize = rNeededPixel - nLeftM - nRightM; // without margin
+
+ if ( nScaleSize <= nAvailable )
+ return;
+
+ long nScale = ( nAvailable * 100 ) / nScaleSize;
+
+ lcl_ScaleFonts( rEngine, nScale );
+ rEngineWidth = lcl_GetEditSize( rEngine, TRUE, FALSE, nAttrRotate );
+ long nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
+
+ USHORT nShrinkAgain = 0;
+ while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
+ {
+ // further reduce, like in DrawStrings
+ lcl_ScaleFonts( rEngine, 90 ); // reduce by 10%
+ rEngineWidth = lcl_GetEditSize( rEngine, TRUE, FALSE, nAttrRotate );
+ nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
+ ++nShrinkAgain;
+ }
+ if ( nNewSize <= nAvailable )
+ rLeftClip = rRightClip = FALSE;
+
+ // sizes for further processing (alignment etc):
+ rNeededPixel = nNewSize + nLeftM + nRightM;
+ rEngineHeight = lcl_GetEditSize( rEngine, FALSE, FALSE, nAttrRotate );
+ }
+}
+
+void ScOutputData::DrawEdit(BOOL bPixelToLogic)
+{
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+
+ Size aMinSize = pRefDevice->PixelToLogic(Size(0,100)); // erst darueber wird ausgegeben
+// UINT32 nMinHeight = aMinSize.Height() / 200; // 1/2 Pixel
+
+ ScModule* pScMod = SC_MOD();
+ sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ ScFieldEditEngine* pEngine = NULL;
+ BOOL bHyphenatorSet = FALSE;
+ const ScPatternAttr* pOldPattern = NULL;
+ const SfxItemSet* pOldCondSet = NULL;
+ ScBaseCell* pCell = NULL;
+
+ Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+#if 0
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+#endif
+ nInitPosX += nMirrorW - 1;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ //! store nLastContentCol as member!
+ SCCOL nLastContentCol = MAXCOL;
+ if ( nX2 < MAXCOL )
+ nLastContentCol = sal::static_int_cast<SCCOL>(
+ nLastContentCol - pDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
+
+ long nRowPosY = nScrY;
+ for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++) // 0 fuer Reste von zusammengefassten
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+// long nCellHeight = (long) pThisRowInfo->nHeight;
+ if (nArrY==1) nRowPosY = nScrY; // vorher wird einzeln berechnet
+
+ if ( pThisRowInfo->bChanged || nArrY==0 )
+ {
+ long nPosX = 0;
+ for (SCCOL nX=0; nX<=nX2; nX++) // wegen Ueberhaengen
+ {
+ if (nX==nX1) nPosX = nInitPosX; // positions before nX1 are calculated individually
+
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ if (pInfo->bEditEngine)
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+
+ SCCOL nCellX = nX; // position where the cell really starts
+ SCROW nCellY = nY;
+ BOOL bDoCell = FALSE;
+
+ long nPosY = nRowPosY;
+ if ( nArrY == 0 )
+ {
+ nPosY = nScrY;
+ nY = pRowInfo[1].nRowNo;
+ SCCOL nOverX; // start of the merged cells
+ SCROW nOverY;
+ if (GetMergeOrigin( nX,nY, 1, nOverX,nOverY, TRUE ))
+ {
+ nCellX = nOverX;
+ nCellY = nOverY;
+ bDoCell = TRUE;
+ }
+ }
+ else if ( nX == nX2 && !pThisRowInfo->pCellInfo[nX+1].pCell )
+ {
+ // Rest of a long text further to the right?
+
+ SCCOL nTempX=nX;
+ while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
+ ++nTempX;
+
+ if ( nTempX > nX &&
+ !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
+ !pDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ nCellX = nTempX;
+ bDoCell = TRUE;
+ }
+ }
+ else
+ {
+ bDoCell = TRUE;
+ }
+
+ if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
+ bDoCell = FALSE;
+
+ const ScPatternAttr* pPattern = NULL;
+ const SfxItemSet* pCondSet = NULL;
+ if (bDoCell)
+ {
+ if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 &&
+ !pDoc->ColHidden(nCellX, nTab) )
+ {
+ CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
+ pPattern = rCellInfo.pPatternAttr;
+ pCondSet = rCellInfo.pConditionSet;
+ pCell = rCellInfo.pCell;
+ }
+ else // get from document
+ {
+ pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
+ pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
+ GetVisibleCell( nCellX, nCellY, nTab, pCell );
+ }
+ if ( !pCell )
+ bDoCell = FALSE;
+ }
+ if (bDoCell)
+ {
+ BOOL bHidden = FALSE;
+
+ //
+ // Create EditEngine
+ //
+
+ if (!pEngine)
+ {
+ // Ein RefDevice muss auf jeden Fall gesetzt werden,
+ // sonst legt sich die EditEngine ein VirtualDevice an!
+ pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() );
+ pEngine->SetUpdateMode( FALSE );
+ pEngine->SetRefDevice( pFmtDevice ); // always set
+ ULONG nCtrl = pEngine->GetControlWord();
+ if ( bShowSpellErrors )
+ nCtrl |= EE_CNTRL_ONLINESPELLING;
+ if ( eType == OUTTYPE_PRINTER )
+ nCtrl &= ~EE_CNTRL_MARKFIELDS;
+ pEngine->SetControlWord( nCtrl );
+ pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() );
+ pEngine->EnableAutoColor( bUseStyleColor );
+ pEngine->SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
+ }
+ else
+ lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(FALSE)
+
+
+ BOOL bCellIsValue = lcl_SafeIsValue(pCell);
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
+ BOOL bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
+ ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
+ BOOL bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
+ BOOL bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
+ (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+ SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
+ long nAttrRotate = ((const SfxInt32Item&)pPattern->
+ GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
+ if ( eHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ {
+ // ignore orientation/rotation if "repeat" is active
+ eOrient = SVX_ORIENTATION_STANDARD;
+ nAttrRotate = 0;
+
+ // #i31843# "repeat" with "line breaks" is treated as default alignment
+ // (but rotation is still disabled)
+ if ( bBreak )
+ eHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ }
+ if ( eOrient==SVX_ORIENTATION_STANDARD && nAttrRotate )
+ {
+ //! Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
+ //! (oder Flag schon bei DrawBackground, dann hier keine Abfrage)
+ bHidden = TRUE; // gedreht wird getrennt ausgegeben
+ }
+
+ BOOL bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED &&
+ ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() );
+ if ( bAsianVertical )
+ {
+ // in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
+ eOrient = SVX_ORIENTATION_STANDARD;
+ // default alignment for asian vertical mode is top-right
+ if ( eHorJust == SVX_HOR_JUSTIFY_STANDARD )
+ eHorJust = SVX_HOR_JUSTIFY_RIGHT;
+ }
+
+
+
+ SvxCellHorJustify eOutHorJust =
+ ( eHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? eHorJust :
+ ( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
+
+ if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
+
+
+//! if ( !bHidden && eType == OUTTYPE_PRINTER &&
+//! pDev->GetOutDevType() == OUTDEV_WINDOW &&
+//! ((const SvxFontHeightItem&)pPattern->
+//! GetItem(ATTR_FONT_HEIGHT)).GetHeight() <= nMinHeight )
+//! {
+//! Point aPos( nStartX, nStartY );
+//! pDev->DrawPixel( aPos,
+//! ((const SvxColorItem&)pPattern->
+//! GetItem( ATTR_FONT_COLOR )).GetValue() );
+//! bHidden = TRUE;
+//! }
+
+ if (!bHidden)
+ {
+ //! mirror margin values for RTL?
+ //! move margin down to after final GetOutputArea call
+
+ const SvxMarginItem* pMargin = (const SvxMarginItem*)
+ &pPattern->GetItem(ATTR_MARGIN, pCondSet);
+ USHORT nIndent = 0;
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->
+ GetItem(ATTR_INDENT, pCondSet)).GetValue();
+
+ long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * nPPTX );
+ long nTopM = (long) ( pMargin->GetTopMargin() * nPPTY );
+ long nRightM = (long) ( pMargin->GetRightMargin() * nPPTX );
+ long nBottomM = (long) ( pMargin->GetBottomMargin() * nPPTY );
+
+ SCCOL nXForPos = nX;
+ if ( nXForPos < nX1 )
+ {
+ nXForPos = nX1;
+ nPosX = nInitPosX;
+ }
+ SCSIZE nArrYForPos = nArrY;
+ if ( nArrYForPos < 1 )
+ {
+ nArrYForPos = 1;
+ nPosY = nScrY;
+ }
+
+ OutputAreaParam aAreaParam;
+
+ //
+ // Initial page size - large for normal text, cell size for automatic line breaks
+ //
+
+ Size aPaperSize = Size( 1000000, 1000000 );
+ if ( bBreak || eOrient == SVX_ORIENTATION_STACKED || bAsianVertical )
+ {
+ //! also stacked, AsianVertical
+
+ // call GetOutputArea with nNeeded=0, to get only the cell width
+
+ //! handle nArrY == 0
+ GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, 0,
+ *pPattern, sal::static_int_cast<USHORT>(eOutHorJust),
+ bCellIsValue, true, false, aAreaParam );
+
+ //! special ScEditUtil handling if formatting for printer
+
+ if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP )
+ aPaperSize.Width() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
+ else
+ aPaperSize.Width() = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
+
+ if (bAsianVertical && bBreak)
+ {
+ // add some extra height (default margin value) for safety
+ // as long as GetEditArea isn't used below
+ long nExtraHeight = (long)( 20 * nPPTY );
+ aPaperSize.Height() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight;
+ }
+ }
+ if (bPixelToLogic)
+ {
+ Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
+ if ( bBreak && !bAsianVertical && pRefDevice != pFmtDevice )
+ {
+ // #i85342# screen display and formatting for printer,
+ // use same GetEditArea call as in ScViewData::SetEditEngine
+
+ Fraction aFract(1,1);
+ Rectangle aUtilRect = ScEditUtil( pDoc, nCellX, nCellY, nTab, Point(0,0), pFmtDevice,
+ HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, FALSE );
+ aLogicSize.Width() = aUtilRect.GetWidth();
+ }
+ pEngine->SetPaperSize(aLogicSize);
+ }
+ else
+ pEngine->SetPaperSize(aPaperSize);
+
+ //
+ // Fill the EditEngine (cell attributes and text)
+ //
+
+ SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
+ pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
+
+ // default alignment for asian vertical mode is top-right
+ if ( bAsianVertical && eVerJust == SVX_VER_JUSTIFY_STANDARD )
+ eVerJust = SVX_VER_JUSTIFY_TOP;
+
+ // syntax highlighting mode is ignored here
+ // StringDiffer doesn't look at hyphenate, language items
+ if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
+ {
+ SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pPattern->FillEditItemSet( pSet, pCondSet );
+
+ pEngine->SetDefaults( pSet );
+ pOldPattern = pPattern;
+ pOldCondSet = pCondSet;
+
+ ULONG nControl = pEngine->GetControlWord();
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ nControl |= EE_CNTRL_ONECHARPERLINE;
+ else
+ nControl &= ~EE_CNTRL_ONECHARPERLINE;
+ pEngine->SetControlWord( nControl );
+
+ if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
+ {
+ // set hyphenator the first time it is needed
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
+ pEngine->SetHyphenator( xXHyphenator );
+ bHyphenatorSet = TRUE;
+ }
+
+ Color aBackCol = ((const SvxBrushItem&)
+ pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
+ if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
+ aBackCol.SetColor( nConfBackColor );
+ pEngine->SetBackgroundColor( aBackCol );
+ }
+
+ // horizontal alignment now may depend on cell content
+ // (for values with number formats with mixed script types)
+ // -> always set adjustment
+
+ SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ else if (bBreak)
+ {
+ if (eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical)
+ switch (eHorJust)
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ eSvxAdjust = bCellIsValue ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
+ break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
+ eSvxAdjust = SVX_ADJUST_LEFT;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ eSvxAdjust = SVX_ADJUST_RIGHT;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_HOR_JUSTIFY_BLOCK:
+ eSvxAdjust = SVX_ADJUST_BLOCK;
+ break;
+ }
+ else
+ switch (eVerJust)
+ {
+ case SVX_VER_JUSTIFY_TOP:
+ eSvxAdjust = (eOrient==SVX_ORIENTATION_TOPBOTTOM || bAsianVertical) ?
+ SVX_ADJUST_LEFT : SVX_ADJUST_RIGHT;
+ break;
+ case SVX_VER_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_VER_JUSTIFY_BOTTOM:
+ case SVX_HOR_JUSTIFY_STANDARD:
+ eSvxAdjust = (eOrient==SVX_ORIENTATION_TOPBOTTOM || bAsianVertical) ?
+ SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
+ break;
+ }
+ }
+ pEngine->SetDefaultItem( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+
+ // Read content from cell
+
+ BOOL bWrapFields = FALSE;
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pData;
+ ((ScEditCell*)pCell)->GetData(pData);
+
+ if (pData)
+ {
+ pEngine->SetText(*pData);
+
+ if ( bBreak && !bAsianVertical && pData->HasField() )
+ {
+ // Fields aren't wrapped, so clipping is enabled to prevent
+ // a field from being drawn beyond the cell size
+
+ bWrapFields = TRUE;
+ }
+ }
+ else
+ {
+ DBG_ERROR("pData == 0");
+ }
+ }
+ else
+ {
+ ULONG nFormat = pPattern->GetNumberFormat(
+ pDoc->GetFormatTable(), pCondSet );
+ String aString;
+ Color* pColor;
+ ScCellFormat::GetString( pCell,
+ nFormat,aString, &pColor,
+ *pDoc->GetFormatTable(),
+ bShowNullValues,
+ bShowFormulas,
+ ftCheck );
+
+ pEngine->SetText(aString);
+ if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
+ lcl_SetEditColor( *pEngine, *pColor );
+ }
+
+ if ( bSyntaxMode )
+ SetEditSyntaxColor( *pEngine, pCell );
+ else if ( bUseStyleColor && bForceAutoColor )
+ lcl_SetEditColor( *pEngine, COL_AUTO ); //! or have a flag at EditEngine
+ }
+ else
+ {
+ DBG_ERROR("pCell == NULL");
+ }
+
+ pEngine->SetVertical( bAsianVertical );
+ pEngine->SetUpdateMode( TRUE ); // after SetText, before CalcTextWidth/GetTextHeight
+
+ //
+ // Get final output area using the calculated width
+ //
+
+ long nEngineWidth;
+ if ( bBreak && eOrient != SVX_ORIENTATION_STACKED && !bAsianVertical )
+ nEngineWidth = 0;
+ else
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ long nEngineHeight = pEngine->GetTextHeight();
+
+ if (eOrient != SVX_ORIENTATION_STANDARD &&
+ eOrient != SVX_ORIENTATION_STACKED)
+ {
+ long nTemp = nEngineWidth;
+ nEngineWidth = nEngineHeight;
+ nEngineHeight = nTemp;
+ }
+
+ if (eOrient == SVX_ORIENTATION_STACKED)
+ nEngineWidth = nEngineWidth * 11 / 10;
+
+ long nNeededPixel = nEngineWidth;
+ if (bPixelToLogic)
+ nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
+ nNeededPixel += nLeftM + nRightM;
+
+ if ( ( !bBreak && eOrient != SVX_ORIENTATION_STACKED ) || bAsianVertical || bShrink )
+ {
+ // for break, the first GetOutputArea call is sufficient
+ GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, nNeededPixel,
+ *pPattern, sal::static_int_cast<USHORT>(eOutHorJust),
+ bCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
+
+ if ( bShrink )
+ {
+ BOOL bWidth = ( eOrient == SVX_ORIENTATION_STANDARD && !bAsianVertical );
+ ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect,
+ nLeftM, nTopM, nRightM, nBottomM, bWidth,
+ sal::static_int_cast<USHORT>(eOrient), 0, bPixelToLogic,
+ nEngineWidth, nEngineHeight, nNeededPixel,
+ aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+ }
+
+ if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && pEngine->GetParagraphCount() == 1 )
+ {
+ // First check if twice the space for the formatted text is available
+ // (otherwise just keep it unchanged).
+
+ long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
+ long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
+ if ( nAvailable >= 2 * nFormatted )
+ {
+ // "repeat" is handled with unformatted text (for performance reasons)
+ String aCellStr = pEngine->GetText();
+ pEngine->SetText( aCellStr );
+
+ long nRepeatSize = (long) pEngine->CalcTextWidth();
+ if (bPixelToLogic)
+ nRepeatSize = pRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
+ if ( pFmtDevice != pRefDevice )
+ ++nRepeatSize;
+ if ( nRepeatSize > 0 )
+ {
+ long nRepeatCount = nAvailable / nRepeatSize;
+ if ( nRepeatCount > 1 )
+ {
+ String aRepeated = aCellStr;
+ for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
+ aRepeated.Append( aCellStr );
+ pEngine->SetText( aRepeated );
+
+ nEngineHeight = pEngine->GetTextHeight();
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ if (bPixelToLogic)
+ nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+ else
+ nNeededPixel = nEngineWidth;
+ nNeededPixel += nLeftM + nRightM;
+ }
+ }
+ }
+ }
+
+ if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
+ {
+ pEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ if (bPixelToLogic)
+ nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+ else
+ nNeededPixel = nEngineWidth;
+ nNeededPixel += nLeftM + nRightM;
+
+ // No clip marks if "###" doesn't fit (same as in DrawStrings)
+ }
+
+ if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT && eOrient == SVX_ORIENTATION_STANDARD )
+ {
+ aPaperSize.Width() = nNeededPixel + 1;
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize);
+ }
+ }
+
+ long nStartX = aAreaParam.maAlignRect.Left();
+ long nStartY = aAreaParam.maAlignRect.Top();
+ long nCellWidth = aAreaParam.maAlignRect.GetWidth();
+ long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
+ long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
+
+ if ( bBreak || eOrient != SVX_ORIENTATION_STANDARD || bAsianVertical )
+ {
+ // text with automatic breaks is aligned only within the
+ // edit engine's paper size, the output of the whole area
+ // is always left-aligned
+
+ nStartX += nLeftM;
+ }
+ else
+ {
+ if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
+ nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
+ else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
+ nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
+ else
+ nStartX += nLeftM;
+ }
+
+ BOOL bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
+ if ( aAreaParam.maClipRect.Left() < nScrX )
+ {
+ aAreaParam.maClipRect.Left() = nScrX;
+ aAreaParam.mbLeftClip = true;
+ }
+ if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
+ {
+ aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
+ aAreaParam.mbRightClip = true;
+ }
+
+ if ( !bHidden && !bOutside )
+ {
+ bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
+ BOOL bSimClip = FALSE;
+
+ if ( bWrapFields )
+ {
+ // Fields in a cell with automatic breaks: clip to cell width
+ bClip = TRUE;
+ }
+
+ if ( aAreaParam.maClipRect.Top() < nScrY )
+ {
+ aAreaParam.maClipRect.Top() = nScrY;
+ bClip = TRUE;
+ }
+ if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
+ {
+ aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
+ bClip = TRUE;
+ }
+
+ Size aCellSize; // output area, excluding margins, in logical units
+ if (bPixelToLogic)
+ aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
+ else
+ aCellSize = Size( nOutWidth, nOutHeight );
+
+ if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
+ {
+ const ScMergeAttr* pMerge =
+ (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ BOOL bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
+
+ // Don't clip for text height when printing rows with optimal height,
+ // except when font size is from conditional formatting.
+ //! Allow clipping when vertically merged?
+ if ( eType != OUTTYPE_PRINTER ||
+ ( pDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
+ ( pCondSet && SFX_ITEM_SET ==
+ pCondSet->GetItemState(ATTR_FONT_HEIGHT, TRUE) ) )
+ bClip = TRUE;
+ else
+ bSimClip = TRUE;
+
+ // Show clip marks if height is at least 5pt too small and
+ // there are several lines of text.
+ // Not for asian vertical text, because that would interfere
+ // with the default right position of the text.
+ // Only with automatic line breaks, to avoid having to find
+ // the cells with the horizontal end of the text again.
+ if ( nEngineHeight - aCellSize.Height() > 100 &&
+ ( bBreak || eOrient == SVX_ORIENTATION_STACKED ) &&
+ !bAsianVertical && bMarkClipped &&
+ ( pEngine->GetParagraphCount() > 1 || pEngine->GetLineCount(0) > 1 ) )
+ {
+ CellInfo* pClipMarkCell = NULL;
+ if ( bMerged )
+ {
+ // anywhere in the merged area...
+ SCCOL nClipX = ( nX < nX1 ) ? nX1 : nX;
+ pClipMarkCell = &pRowInfo[(nArrY != 0) ? nArrY : 1].pCellInfo[nClipX+1];
+ }
+ else
+ pClipMarkCell = &pThisRowInfo->pCellInfo[nX+1];
+
+ pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
+ bAnyClipped = TRUE;
+
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
+ aAreaParam.maClipRect.Right() -= nMarkPixel;
+ }
+ }
+
+#if 0
+ long nClipStartY = nStartY;
+ if (nArrY==0 || bVisChanged)
+ {
+ if ( nClipStartY < nRowPosY )
+ {
+ long nDif = nRowPosY - nClipStartY;
+ bClip = TRUE;
+ nClipStartY = nRowPosY;
+ aClipSize.Height() -= nDif;
+ }
+ }
+#endif
+
+ Rectangle aLogicClip;
+ if (bClip || bSimClip)
+ {
+ // Clip marks are already handled in GetOutputArea
+
+ if (bPixelToLogic)
+ aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
+ else
+ aLogicClip = aAreaParam.maClipRect;
+
+ if (bClip) // bei bSimClip nur aClipRect initialisieren
+ {
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aLogicClip );
+ }
+ else
+ pDev->SetClipRegion( Region( aLogicClip ) );
+ }
+ }
+
+ Point aLogicStart;
+ if (bPixelToLogic)
+ aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
+ else
+ aLogicStart = Point(nStartX, nStartY);
+ if ( eOrient!=SVX_ORIENTATION_STANDARD || bAsianVertical || !bBreak )
+ {
+ long nAvailWidth = aCellSize.Width();
+ // space for AutoFilter is already handled in GetOutputArea
+
+ // horizontal alignment
+
+ if (eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical)
+ {
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
+ eHorJust==SVX_HOR_JUSTIFY_CENTER ||
+ (eHorJust==SVX_HOR_JUSTIFY_STANDARD && bCellIsValue) )
+ {
+ pEngine->SetUpdateMode( FALSE );
+
+ SvxAdjust eEditAdjust =
+ (eHorJust==SVX_HOR_JUSTIFY_CENTER) ?
+ SVX_ADJUST_CENTER : SVX_ADJUST_RIGHT;
+ pEngine->SetDefaultItem(
+ SvxAdjustItem( eEditAdjust, EE_PARA_JUST ) );
+
+ // #55142# reset adjustment for the next cell
+ pOldPattern = NULL;
+
+ pEngine->SetUpdateMode( TRUE );
+ }
+ }
+ else
+ {
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
+ aLogicStart.X() += nAvailWidth - nEngineWidth;
+ else if (eHorJust==SVX_HOR_JUSTIFY_CENTER)
+ aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
+ }
+ }
+
+ if ( bAsianVertical )
+ {
+ // paper size is subtracted below
+ aLogicStart.X() += nEngineWidth;
+ }
+
+ if ( ( bAsianVertical || eOrient == SVX_ORIENTATION_TOPBOTTOM ||
+ eOrient == SVX_ORIENTATION_BOTTOMTOP ) && bBreak )
+ {
+ // vertical adjustment is within the EditEngine
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+ else
+ aLogicStart.Y() += nTopM;
+ }
+
+ if ( ( eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical ) ||
+ eOrient==SVX_ORIENTATION_STACKED || !bBreak )
+ {
+ if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
+ eVerJust==SVX_VER_JUSTIFY_STANDARD)
+ {
+ //! if pRefDevice != pFmtDevice, keep heights in logic units,
+ //! only converting margin?
+
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM +
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
+ )).Height();
+ else
+ aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
+ }
+ else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM + (
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
+ / 2)).Height();
+ else
+ aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
+ }
+ else // top
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+ else
+ aLogicStart.Y() += nTopM;
+ }
+ }
+
+ Point aURLStart = aLogicStart; // copy before modifying for orientation
+
+ short nOriVal = 0;
+ if (eOrient==SVX_ORIENTATION_TOPBOTTOM)
+ {
+ // nOriVal = -900;
+ nOriVal = 2700;
+ aLogicStart.X() += nEngineWidth;
+ }
+ else if (eOrient==SVX_ORIENTATION_BOTTOMTOP)
+ {
+ nOriVal = 900;
+ aLogicStart.Y() += bBreak ? pEngine->GetPaperSize().Width() :
+ nEngineHeight;
+ }
+ else if (eOrient==SVX_ORIENTATION_STACKED)
+ {
+ Size aPaperLogic = pEngine->GetPaperSize();
+ aPaperLogic.Width() = nEngineWidth;
+ pEngine->SetPaperSize(aPaperLogic);
+ }
+
+ if ( pEngine->IsRightToLeft( 0 ) )
+ {
+ // For right-to-left, EditEngine always calculates its lines
+ // beginning from the right edge, but EditLine::nStartPosX is
+ // of USHORT type, so the PaperSize must be limited to USHRT_MAX.
+ Size aLogicPaper = pEngine->GetPaperSize();
+ if ( aLogicPaper.Width() > USHRT_MAX )
+ {
+ aLogicPaper.Width() = USHRT_MAX;
+ pEngine->SetPaperSize(aLogicPaper);
+ }
+ }
+
+ // bMoveClipped handling has been replaced by complete alignment
+ // handling (also extending to the left).
+
+ if ( bSimClip && !nOriVal && !bAsianVertical )
+ {
+ // kein hartes Clipping, aber nur die betroffenen
+ // Zeilen ausgeben
+
+ Point aDocStart = aLogicClip.TopLeft();
+ aDocStart -= aLogicStart;
+ pEngine->Draw( pDev, aLogicClip, aDocStart, FALSE );
+ }
+ else
+ {
+ if (bAsianVertical)
+ {
+ // with SetVertical, the start position is top left of
+ // the whole output area, not the text itself
+ aLogicStart.X() -= pEngine->GetPaperSize().Width();
+ }
+ pEngine->Draw( pDev, aLogicStart, nOriVal );
+ }
+
+ if (bClip)
+ {
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+ }
+
+ // PDF: whole-cell hyperlink from formula?
+ BOOL bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
+ if ( bHasURL )
+ {
+ long nURLWidth = (long) pEngine->CalcTextWidth();
+ long nURLHeight = pEngine->GetTextHeight();
+ if ( bBreak )
+ {
+ Size aPaper = pEngine->GetPaperSize();
+ if ( bAsianVertical )
+ nURLHeight = aPaper.Height();
+ else
+ nURLWidth = aPaper.Width();
+ }
+ if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP )
+ std::swap( nURLWidth, nURLHeight );
+ else if ( bAsianVertical )
+ aURLStart.X() -= nURLWidth;
+
+ Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
+ lcl_DoHyperlinkResult( pDev, aURLRect, pCell );
+ }
+ }
+ }
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nRowPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ delete pEngine;
+
+ if (bAnyRotated)
+ DrawRotated(bPixelToLogic); //! von aussen rufen ?
+}
+
+// -------------------------------------------------------------------------------
+
+void ScOutputData::DrawRotated(BOOL bPixelToLogic)
+{
+ //! nRotMax speichern
+ SCCOL nRotMax = nX2;
+ for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
+ if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nRotY].nRotMaxCol;
+
+
+ ScModule* pScMod = SC_MOD();
+ sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ ScFieldEditEngine* pEngine = NULL;
+ BOOL bHyphenatorSet = FALSE;
+ const ScPatternAttr* pPattern;
+ const SfxItemSet* pCondSet;
+ const ScPatternAttr* pOldPattern = NULL;
+ const SfxItemSet* pOldCondSet = NULL;
+ ScBaseCell* pCell = NULL;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+#if 0
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+#endif
+ nInitPosX += nMirrorW - 1;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nRowPosY = nScrY;
+ for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++) // 0 fuer Reste von zusammengefassten
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nCellHeight = (long) pThisRowInfo->nHeight;
+ if (nArrY==1) nRowPosY = nScrY; // vorher wird einzeln berechnet
+
+ if ( ( pThisRowInfo->bChanged || nArrY==0 ) && pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE )
+ {
+ long nPosX = 0;
+ for (SCCOL nX=0; nX<=nRotMax; nX++)
+ {
+ if (nX==nX1) nPosX = nInitPosX; // positions before nX1 are calculated individually
+
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ if ( pInfo->nRotateDir != SC_ROTDIR_NONE )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+
+ BOOL bHidden = FALSE;
+ if (bEditMode)
+ if ( nX == nEditCol && nY == nEditRow )
+ bHidden = TRUE;
+
+ if (!bHidden)
+ {
+ if (!pEngine)
+ {
+ // Ein RefDevice muss auf jeden Fall gesetzt werden,
+ // sonst legt sich die EditEngine ein VirtualDevice an!
+ pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() );
+ pEngine->SetUpdateMode( FALSE );
+ pEngine->SetRefDevice( pFmtDevice ); // always set
+ ULONG nCtrl = pEngine->GetControlWord();
+ if ( bShowSpellErrors )
+ nCtrl |= EE_CNTRL_ONLINESPELLING;
+ if ( eType == OUTTYPE_PRINTER )
+ nCtrl &= ~EE_CNTRL_MARKFIELDS;
+ pEngine->SetControlWord( nCtrl );
+ pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() );
+ pEngine->EnableAutoColor( bUseStyleColor );
+ pEngine->SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
+ }
+ else
+ lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(FALSE)
+
+ long nPosY = nRowPosY;
+ BOOL bVisChanged = FALSE;
+
+ //! Rest von zusammengefasster Zelle weiter oben funktioniert nicht!
+
+ BOOL bFromDoc = FALSE;
+ pPattern = pInfo->pPatternAttr;
+ pCondSet = pInfo->pConditionSet;
+ if (!pPattern)
+ {
+ pPattern = pDoc->GetPattern( nX, nY, nTab );
+ bFromDoc = TRUE;
+ }
+ pCell = pInfo->pCell;
+ if (bFromDoc)
+ pCondSet = pDoc->GetCondResult( nX, nY, nTab );
+
+ if (!pCell && nX>nX2)
+ GetVisibleCell( nX, nY, nTab, pCell );
+
+ if ( !pCell || IsEmptyCellText( pThisRowInfo, nX, nY ) )
+ bHidden = TRUE; // nRotateDir is also set without a cell
+
+ long nCellWidth = (long) pRowInfo[0].pCellInfo[nX+1].nWidth;
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
+ BOOL bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
+ ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
+ BOOL bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
+ BOOL bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
+ (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+ SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
+
+ const ScMergeAttr* pMerge =
+ (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ BOOL bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
+
+ long nStartX = nPosX;
+ long nStartY = nPosY;
+ if (nX<nX1)
+ {
+ if ((bBreak || eOrient!=SVX_ORIENTATION_STANDARD) && !bMerged)
+ bHidden = TRUE;
+ else
+ {
+ nStartX = nInitPosX;
+ SCCOL nCol = nX1;
+ while (nCol > nX)
+ {
+ --nCol;
+ nStartX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
+ }
+ }
+ }
+ long nCellStartX = nStartX;
+
+ // Ersatzdarstellung fuer zu kleinen Text weggelassen
+
+ if (!bHidden)
+ {
+ long nOutWidth = nCellWidth - 1;
+ long nOutHeight;
+ if (pInfo)
+ nOutHeight = nCellHeight;
+ else
+ nOutHeight = (long) ( pDoc->GetRowHeight(nY,nTab) * nPPTY );
+
+ if ( bMerged ) // Zusammengefasst
+ {
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nOutWidth += (long) ( pDoc->GetColWidth(nX+i,nTab) * nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+ nOutHeight += (long) pDoc->GetScaledRowHeight( nY+1, nY+nCountY-1, nTab, nPPTY);
+ }
+
+ SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
+ pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
+
+ // Syntax-Modus wird hier ignoriert...
+
+ // StringDiffer doesn't look at hyphenate, language items
+ if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
+ {
+ SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pPattern->FillEditItemSet( pSet, pCondSet );
+
+ // Ausrichtung fuer EditEngine
+ SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ // Adjustment fuer bBreak ist hier weggelassen
+ pSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+
+ pEngine->SetDefaults( pSet );
+ pOldPattern = pPattern;
+ pOldCondSet = pCondSet;
+
+ ULONG nControl = pEngine->GetControlWord();
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ nControl |= EE_CNTRL_ONECHARPERLINE;
+ else
+ nControl &= ~EE_CNTRL_ONECHARPERLINE;
+ pEngine->SetControlWord( nControl );
+
+ if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
+ {
+ // set hyphenator the first time it is needed
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
+ pEngine->SetHyphenator( xXHyphenator );
+ bHyphenatorSet = TRUE;
+ }
+
+ Color aBackCol = ((const SvxBrushItem&)
+ pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
+ if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
+ aBackCol.SetColor( nConfBackColor );
+ pEngine->SetBackgroundColor( aBackCol );
+ }
+
+ // Raender
+
+ //! Position und Papersize auf EditUtil umstellen !!!
+
+ const SvxMarginItem* pMargin = (const SvxMarginItem*)
+ &pPattern->GetItem(ATTR_MARGIN, pCondSet);
+ USHORT nIndent = 0;
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->
+ GetItem(ATTR_INDENT, pCondSet)).GetValue();
+
+ long nTotalHeight = nOutHeight; // ohne Rand abzuziehen
+ if ( bPixelToLogic )
+ nTotalHeight = pRefDevice->PixelToLogic(Size(0,nTotalHeight)).Height();
+
+ long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * nPPTX );
+ long nTopM = (long) ( pMargin->GetTopMargin() * nPPTY );
+ long nRightM = (long) ( pMargin->GetRightMargin() * nPPTX );
+ long nBottomM = (long) ( pMargin->GetBottomMargin() * nPPTY );
+ nStartX += nLeftM;
+ nStartY += nTopM;
+ nOutWidth -= nLeftM + nRightM;
+ nOutHeight -= nTopM + nBottomM;
+
+ // Rotation schon hier, um bei Umbruch auch PaperSize anzupassen
+ long nAttrRotate = 0;
+ double nSin = 0.0;
+ double nCos = 1.0;
+ SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
+ if ( eOrient == SVX_ORIENTATION_STANDARD )
+ {
+ nAttrRotate = ((const SfxInt32Item&)pPattern->
+ GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
+ if ( nAttrRotate )
+ {
+ eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( nAttrRotate == 18000 )
+ eRotMode = SVX_ROTATE_MODE_STANDARD; // keinen Ueberlauf
+
+ if ( bLayoutRTL )
+ nAttrRotate = -nAttrRotate;
+
+ double nRealOrient = nAttrRotate * F_PI18000; // 1/100 Grad
+ nCos = cos( nRealOrient );
+ nSin = sin( nRealOrient );
+ }
+ }
+
+ Size aPaperSize = Size( 1000000, 1000000 );
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ aPaperSize.Width() = nOutWidth; // zum Zentrieren
+ else if (bBreak)
+ {
+ if (nAttrRotate)
+ {
+ //! richtige PaperSize fuer Umbruch haengt von der Zeilenzahl
+ //! ab, solange die Zeilen nicht einzeln versetzt ausgegeben
+ //! werden koennen -> darum unbegrenzt, also kein Umbruch.
+ //! Mit versetzten Zeilen waere das folgende richtig:
+ aPaperSize.Width() = (long)(nOutHeight / fabs(nSin));
+ }
+ else if (eOrient == SVX_ORIENTATION_STANDARD)
+ aPaperSize.Width() = nOutWidth;
+ else
+ aPaperSize.Width() = nOutHeight - 1;
+ }
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize); // Scale ist immer 1
+
+ // Daten aus Zelle lesen
+
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pData;
+ ((ScEditCell*)pCell)->GetData(pData);
+
+ if (pData)
+ pEngine->SetText(*pData);
+ else
+ {
+ DBG_ERROR("pData == 0");
+ }
+ }
+ else
+ {
+ ULONG nFormat = pPattern->GetNumberFormat(
+ pDoc->GetFormatTable(), pCondSet );
+ String aString;
+ Color* pColor;
+ ScCellFormat::GetString( pCell,
+ nFormat,aString, &pColor,
+ *pDoc->GetFormatTable(),
+ bShowNullValues,
+ bShowFormulas,
+ ftCheck );
+
+ pEngine->SetText(aString);
+ if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
+ lcl_SetEditColor( *pEngine, *pColor );
+ }
+
+ if ( bSyntaxMode )
+ SetEditSyntaxColor( *pEngine, pCell );
+ else if ( bUseStyleColor && bForceAutoColor )
+ lcl_SetEditColor( *pEngine, COL_AUTO ); //! or have a flag at EditEngine
+ }
+ else
+ {
+ DBG_ERROR("pCell == NULL");
+ }
+
+ pEngine->SetUpdateMode( TRUE ); // after SetText, before CalcTextWidth/GetTextHeight
+
+ long nEngineWidth = (long) pEngine->CalcTextWidth();
+ long nEngineHeight = pEngine->GetTextHeight();
+
+ if (nAttrRotate && bBreak)
+ {
+ double nAbsCos = fabs( nCos );
+ double nAbsSin = fabs( nSin );
+
+ // #47740# adjust witdh of papersize for height of text
+ int nSteps = 5;
+ while (nSteps > 0)
+ {
+ // everything is in pixels
+ long nEnginePixel = pRefDevice->LogicToPixel(
+ Size(0,nEngineHeight)).Height();
+ long nEffHeight = nOutHeight - (long)(nEnginePixel * nAbsCos) + 2;
+ long nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
+ BOOL bFits = ( nNewWidth >= aPaperSize.Width() );
+ if ( bFits )
+ nSteps = 0;
+ else
+ {
+ if ( nNewWidth < 4 )
+ {
+ // can't fit -> fall back to using half height
+ nEffHeight = nOutHeight / 2;
+ nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
+ nSteps = 0;
+ }
+ else
+ --nSteps;
+
+ // set paper width and get new text height
+ aPaperSize.Width() = nNewWidth;
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize); // Scale ist immer 1
+ //pEngine->QuickFormatDoc( TRUE );
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ nEngineHeight = pEngine->GetTextHeight();
+ }
+ }
+ }
+
+ long nRealWidth = nEngineWidth;
+ long nRealHeight = nEngineHeight;
+
+ // wenn gedreht, Groesse anpassen
+ if (nAttrRotate)
+ {
+ double nAbsCos = fabs( nCos );
+ double nAbsSin = fabs( nSin );
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nEngineWidth = (long) ( nRealWidth * nAbsCos +
+ nRealHeight * nAbsSin );
+ else
+ nEngineWidth = (long) ( nRealHeight / nAbsSin );
+ //! begrenzen !!!
+
+ nEngineHeight = (long) ( nRealHeight * nAbsCos +
+ nRealWidth * nAbsSin );
+ }
+
+ if (!nAttrRotate) // hier nur gedrehter Text
+ bHidden = TRUE; //! vorher abfragen !!!
+
+ //! weglassen, was nicht hereinragt
+
+ if (!bHidden)
+ {
+ BOOL bClip = FALSE;
+ Size aClipSize = Size( nScrX+nScrW-nStartX, nScrY+nScrH-nStartY );
+
+ // weiterschreiben
+
+ Size aCellSize;
+ if (bPixelToLogic)
+ aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
+ else
+ aCellSize = Size( nOutWidth, nOutHeight ); // Scale ist 1
+
+ long nGridWidth = nEngineWidth;
+ BOOL bNegative = FALSE;
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ {
+ nGridWidth = aCellSize.Width() +
+ Abs((long) ( aCellSize.Height() * nCos / nSin ));
+ bNegative = ( pInfo->nRotateDir == SC_ROTDIR_LEFT );
+ if ( bLayoutRTL )
+ bNegative = !bNegative;
+ }
+
+ // use GetOutputArea to hide the grid
+ // (clip region is done manually below)
+ OutputAreaParam aAreaParam;
+
+ SCCOL nCellX = nX;
+ SCROW nCellY = nY;
+ SvxCellHorJustify eOutHorJust = eHorJust;
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ eOutHorJust = bNegative ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
+ long nNeededWidth = nGridWidth; // in pixel for GetOutputArea
+ if ( bPixelToLogic )
+ nNeededWidth = pRefDevice->LogicToPixel(Size(nNeededWidth,0)).Width();
+
+ GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth,
+ *pPattern, sal::static_int_cast<USHORT>(eOutHorJust),
+ FALSE, FALSE, TRUE, aAreaParam );
+
+ if ( bShrink )
+ {
+ long nPixelWidth = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth;
+ long nNeededPixel = nPixelWidth + nLeftM + nRightM;
+
+ aAreaParam.mbLeftClip = aAreaParam.mbRightClip = TRUE;
+
+ // always do height
+ ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
+ FALSE, sal::static_int_cast<USHORT>(eOrient), nAttrRotate, bPixelToLogic,
+ nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ {
+ // do width only if rotating within the cell (standard mode)
+ ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
+ TRUE, sal::static_int_cast<USHORT>(eOrient), nAttrRotate, bPixelToLogic,
+ nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+ }
+
+ // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine
+ // (but width is only valid for standard mode)
+ nRealWidth = (long) pEngine->CalcTextWidth();
+ nRealHeight = pEngine->GetTextHeight();
+
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ nEngineWidth = (long) ( nRealHeight / fabs( nSin ) );
+ }
+
+ // BOOL bVClip = ( nEngineHeight > aCellSize.Height() );
+
+ long nClipStartX = nStartX;
+ if (nX<nX1)
+ {
+ //! Clipping unnoetig, wenn links am Fenster
+
+ bClip = TRUE; // nur Rest ausgeben!
+ if (nStartX<nScrX)
+ {
+ long nDif = nScrX - nStartX;
+ nClipStartX = nScrX;
+ aClipSize.Width() -= nDif;
+ }
+ }
+
+ long nClipStartY = nStartY;
+ if (nArrY==0 || bVisChanged)
+ {
+ if ( nClipStartY < nRowPosY )
+ {
+ long nDif = nRowPosY - nClipStartY;
+ bClip = TRUE;
+ nClipStartY = nRowPosY;
+ aClipSize.Height() -= nDif;
+ }
+ }
+
+ bClip = TRUE; // always clip at the window/page border
+
+ //Rectangle aClipRect;
+ if (bClip)
+ {
+ if ( nAttrRotate /* && eRotMode != SVX_ROTATE_MODE_STANDARD */ )
+ {
+ // gedrehten, ausgerichteten Text nur an den
+ // Seitengrenzen clippen
+ nClipStartX = nScrX;
+ aClipSize.Width() = nScrW;
+ }
+
+ if (bPixelToLogic)
+ aAreaParam.maClipRect = pRefDevice->PixelToLogic( Rectangle(
+ Point(nClipStartX,nClipStartY), aClipSize ) );
+ else
+ aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY),
+ aClipSize ); // Scale = 1
+
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aAreaParam.maClipRect );
+ }
+ else
+ pDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
+ }
+
+ Point aLogicStart;
+ if (bPixelToLogic)
+ aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
+ else
+ aLogicStart = Point(nStartX, nStartY);
+ if ( eOrient!=SVX_ORIENTATION_STANDARD || !bBreak )
+ {
+ long nAvailWidth = aCellSize.Width();
+ if (eType==OUTTYPE_WINDOW &&
+ eOrient!=SVX_ORIENTATION_STACKED &&
+ pInfo && pInfo->bAutoFilter)
+ {
+ // filter drop-down width is now independent from row height
+ if (bPixelToLogic)
+ nAvailWidth -= pRefDevice->PixelToLogic(Size(0,DROPDOWN_BITMAP_SIZE)).Height();
+ else
+ nAvailWidth -= DROPDOWN_BITMAP_SIZE;
+ long nComp = nEngineWidth;
+ if (nAvailWidth<nComp) nAvailWidth=nComp;
+ }
+
+ // horizontale Ausrichtung
+
+ if (eOrient==SVX_ORIENTATION_STANDARD && !nAttrRotate)
+ {
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
+ eHorJust==SVX_HOR_JUSTIFY_CENTER)
+ {
+ pEngine->SetUpdateMode( FALSE );
+
+ SvxAdjust eSvxAdjust =
+ (eHorJust==SVX_HOR_JUSTIFY_RIGHT) ?
+ SVX_ADJUST_RIGHT : SVX_ADJUST_CENTER;
+ pEngine->SetDefaultItem(
+ SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+
+ aPaperSize.Width() = nOutWidth;
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize);
+
+ pEngine->SetUpdateMode( TRUE );
+ }
+ }
+ else
+ {
+ // bei gedrehtem Text ist Standard zentriert
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
+ aLogicStart.X() += nAvailWidth - nEngineWidth;
+ else if (eHorJust==SVX_HOR_JUSTIFY_CENTER ||
+ eHorJust==SVX_HOR_JUSTIFY_STANDARD)
+ aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
+ }
+ }
+
+ if ( bLayoutRTL )
+ {
+ if (bPixelToLogic)
+ aLogicStart.X() -= pRefDevice->PixelToLogic(
+ Size( nCellWidth, 0 ) ).Width();
+ else
+ aLogicStart.X() -= nCellWidth;
+ }
+
+ if ( eOrient==SVX_ORIENTATION_STANDARD ||
+ eOrient==SVX_ORIENTATION_STACKED || !bBreak )
+ {
+ if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
+ eVerJust==SVX_VER_JUSTIFY_STANDARD)
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0,
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
+ )).Height();
+ else
+ aLogicStart.Y() += aCellSize.Height() - nEngineHeight;
+ }
+
+ else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0,(
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height())
+ / 2)).Height();
+ else
+ aLogicStart.Y() += (aCellSize.Height() - nEngineHeight) / 2;
+ }
+ }
+
+ // TOPBOTTON and BOTTOMTOP are handled in DrawStrings/DrawEdit
+ DBG_ASSERT( eOrient == SVX_ORIENTATION_STANDARD && nAttrRotate,
+ "DrawRotated: no rotation" );
+
+ long nOriVal = 0;
+ if ( nAttrRotate )
+ {
+ // Attribut ist 1/100, Font 1/10 Grad
+ nOriVal = nAttrRotate / 10;
+
+ double nAddX = 0.0;
+ double nAddY = 0.0;
+ if ( nCos > 0.0 && eRotMode != SVX_ROTATE_MODE_STANDARD )
+ {
+ //! begrenzen !!!
+ double nH = nRealHeight * nCos;
+ nAddX += nH * ( nCos / fabs(nSin) );
+ }
+ if ( nCos < 0.0 && eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nAddX -= nRealWidth * nCos;
+ if ( nSin < 0.0 )
+ nAddX -= nRealHeight * nSin;
+ if ( nSin > 0.0 )
+ nAddY += nRealWidth * nSin;
+ if ( nCos < 0.0 )
+ nAddY -= nRealHeight * nCos;
+
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ {
+ //! begrenzen !!!
+ double nSkew = nTotalHeight * nCos / fabs(nSin);
+ if ( eRotMode == SVX_ROTATE_MODE_CENTER )
+ nAddX -= nSkew * 0.5;
+ if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nSin > 0.0 ) ||
+ ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nSin < 0.0 ) )
+ nAddX -= nSkew;
+
+ long nUp = 0;
+ if ( eVerJust == SVX_VER_JUSTIFY_CENTER )
+ nUp = ( aCellSize.Height() - nEngineHeight ) / 2;
+ else if ( eVerJust == SVX_VER_JUSTIFY_TOP )
+ {
+ if ( nSin > 0.0 )
+ nUp = aCellSize.Height() - nEngineHeight;
+ }
+ else // BOTTOM / STANDARD
+ {
+ if ( nSin < 0.0 )
+ nUp = aCellSize.Height() - nEngineHeight;
+ }
+ if ( nUp )
+ nAddX += ( nUp * nCos / fabs(nSin) );
+ }
+
+ aLogicStart.X() += (long) nAddX;
+ aLogicStart.Y() += (long) nAddY;
+ }
+
+ // bSimClip is not used here (because nOriVal is set)
+
+ if ( pEngine->IsRightToLeft( 0 ) )
+ {
+ // For right-to-left, EditEngine always calculates its lines
+ // beginning from the right edge, but EditLine::nStartPosX is
+ // of USHORT type, so the PaperSize must be limited to USHRT_MAX.
+ Size aLogicPaper = pEngine->GetPaperSize();
+ if ( aLogicPaper.Width() > USHRT_MAX )
+ {
+ aLogicPaper.Width() = USHRT_MAX;
+ pEngine->SetPaperSize(aLogicPaper);
+ }
+ }
+
+ pEngine->Draw( pDev, aLogicStart, (short)nOriVal );
+
+ if (bClip)
+ {
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+ }
+ }
+ }
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nRowPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ delete pEngine;
+}
+
+
+
diff --git a/sc/source/ui/view/output3.cxx b/sc/source/ui/view/output3.cxx
new file mode 100644
index 000000000000..2c368937e156
--- /dev/null
+++ b/sc/source/ui/view/output3.cxx
@@ -0,0 +1,276 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <vcl/svapp.hxx>
+
+#include "output.hxx"
+#include "drwlayer.hxx"
+#include "document.hxx"
+#include "tabvwsh.hxx"
+#include "fillinfo.hxx"
+
+#include <svx/fmview.hxx>
+
+// STATIC DATA -----------------------------------------------------------
+
+SdrObject* pSkipPaintObj = NULL;
+
+//==================================================================
+
+// #i72502#
+Point ScOutputData::PrePrintDrawingLayer(long nLogStX, long nLogStY )
+{
+ Rectangle aRect;
+ SCCOL nCol;
+ Point aOffset;
+ long nLayoutSign(bLayoutRTL ? -1 : 1);
+
+ for (nCol=0; nCol<nX1; nCol++)
+ aOffset.X() -= pDoc->GetColWidth( nCol, nTab ) * nLayoutSign;
+ aOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nTab );
+
+ long nDataWidth = 0;
+ long nDataHeight = 0;
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ nDataWidth += pDoc->GetColWidth( nCol, nTab );
+ nDataHeight += pDoc->GetRowHeight( nY1, nY2, nTab );
+
+ if ( bLayoutRTL )
+ aOffset.X() += nDataWidth;
+
+ aRect.Left() = aRect.Right() = -aOffset.X();
+ aRect.Top() = aRect.Bottom() = -aOffset.Y();
+
+ Point aMMOffset( aOffset );
+ aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
+ aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
+
+ if (!bMetaFile)
+ aMMOffset += Point( nLogStX, nLogStY );
+
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ aRect.Right() += pDoc->GetColWidth( nCol, nTab );
+ aRect.Bottom() += pDoc->GetRowHeight( nY1, nY2, nTab );
+
+ aRect.Left() = (long) (aRect.Left() * HMM_PER_TWIPS);
+ aRect.Top() = (long) (aRect.Top() * HMM_PER_TWIPS);
+ aRect.Right() = (long) (aRect.Right() * HMM_PER_TWIPS);
+ aRect.Bottom() = (long) (aRect.Bottom() * HMM_PER_TWIPS);
+
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ // #i76114# MapMode has to be set because BeginDrawLayers uses GetPaintRegion
+ MapMode aOldMode = pDev->GetMapMode();
+ if (!bMetaFile)
+ pDev->SetMapMode( MapMode( MAP_100TH_MM, aMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
+
+ // #i74769# work with SdrPaintWindow directly
+ // #i76114# pass bDisableIntersect = true, because the intersection of the table area
+ // with the Window's paint region can be empty
+ Region aRectRegion(aRect);
+ mpTargetPaintWindow = pLocalDrawView->BeginDrawLayers(pDev, aRectRegion, true);
+ OSL_ENSURE(mpTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
+
+ if (!bMetaFile)
+ pDev->SetMapMode( aOldMode );
+ }
+ }
+
+ return aMMOffset;
+}
+
+// #i72502#
+void ScOutputData::PostPrintDrawingLayer(const Point& rMMOffset) // #i74768#
+{
+ // #i74768# just use offset as in PrintDrawingLayer() to also get the form controls
+ // painted with offset
+ MapMode aOldMode = pDev->GetMapMode();
+
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( MapMode( MAP_100TH_MM, rMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
+ }
+
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ // #i74769# work with SdrPaintWindow directly
+ pLocalDrawView->EndDrawLayers(*mpTargetPaintWindow, true);
+ mpTargetPaintWindow = 0;
+ }
+ }
+
+ // #i74768#
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( aOldMode );
+ }
+}
+
+// #i72502#
+void ScOutputData::PrintDrawingLayer(const sal_uInt16 nLayer, const Point& rMMOffset)
+{
+ bool bHideAllDrawingLayer(false);
+
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ bHideAllDrawingLayer = pLocalDrawView->getHideOle() && pLocalDrawView->getHideChart()
+ && pLocalDrawView->getHideDraw() && pLocalDrawView->getHideFormControl();
+ }
+ }
+
+ // #109985#
+ if(bHideAllDrawingLayer || (!pDoc->GetDrawLayer()))
+ {
+ return;
+ }
+
+ MapMode aOldMode = pDev->GetMapMode();
+
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( MapMode( MAP_100TH_MM, rMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
+ }
+
+ // #109985#
+ DrawSelectiveObjects( nLayer );
+
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( aOldMode );
+ }
+}
+
+// #109985#
+void ScOutputData::DrawSelectiveObjects(const sal_uInt16 nLayer)
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return;
+
+ // #i46362# high contrast mode (and default text direction) must be handled
+ // by the application, so it's still needed when using DrawLayer().
+
+ SdrOutliner& rOutl = pModel->GetDrawOutliner();
+ rOutl.EnableAutoColor( bUseStyleColor );
+ rOutl.SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
+
+ // #i69767# The hyphenator must be set (used to be before drawing a text shape with hyphenation).
+ // LinguMgr::GetHyphenator (EditEngine) uses a wrapper now that creates the real hyphenator on demand,
+ // so it's not a performance problem to call UseHyphenator even when it's not needed.
+
+ pModel->UseHyphenator();
+
+ ULONG nOldDrawMode = pDev->GetDrawMode();
+ if ( bUseStyleColor && Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pDev->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL |
+ DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
+ }
+
+ // #109985#
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ SdrPageView* pPageView = pLocalDrawView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ pPageView->DrawLayer(sal::static_int_cast<SdrLayerID>(nLayer), pDev);
+ }
+ }
+ }
+
+ pDev->SetDrawMode(nOldDrawMode);
+
+ // #109985#
+ return;
+}
+
+// Teile nur fuer Bildschirm
+
+// #109985#
+void ScOutputData::DrawingSingle(const sal_uInt16 nLayer)
+{
+ BOOL bHad = FALSE;
+ long nPosY = nScrY;
+ SCSIZE nArrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if (!bHad)
+ {
+ bHad = TRUE;
+ }
+ }
+ else if (bHad)
+ {
+ DrawSelectiveObjects( nLayer );
+ bHad = FALSE;
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ if (bHad)
+ DrawSelectiveObjects( nLayer );
+}
+
+
+
+
diff --git a/sc/source/ui/view/pfuncache.cxx b/sc/source/ui/view/pfuncache.cxx
new file mode 100644
index 000000000000..b503d3a73fb7
--- /dev/null
+++ b/sc/source/ui/view/pfuncache.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/multisel.hxx>
+
+#include "pfuncache.hxx"
+#include "printfun.hxx"
+#include "docsh.hxx"
+#include "markdata.hxx"
+#include "prevloc.hxx"
+
+//------------------------------------------------------------------------
+
+ScPrintFuncCache::ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark,
+ const ScPrintSelectionStatus& rStatus ) :
+ aSelection( rStatus ),
+ pDocSh( pD ),
+ nTotalPages( 0 ),
+ bLocInitialized( false )
+{
+ // page count uses the stored cell widths for the printer anyway,
+ // so ScPrintFunc with the document's printer can be used to count
+
+ SfxPrinter* pPrinter = pDocSh->GetPrinter();
+
+ ScRange aRange;
+ const ScRange* pSelRange = NULL;
+ if ( rMark.IsMarked() )
+ {
+ rMark.GetMarkArea( aRange );
+ pSelRange = &aRange;
+ }
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTab;
+ for ( nTab=0; nTab<nTabCount; nTab++ )
+ {
+ long nAttrPage = nTab > 0 ? nFirstAttr[nTab-1] : 1;
+
+ long nThisTab = 0;
+ if ( rMark.GetTableSelect( nTab ) )
+ {
+ pDoc->InvalidatePageBreaks( nTab ); // user print area (selection) may be different
+
+ ScPrintFunc aFunc( pDocSh, pPrinter, nTab, nAttrPage, 0, pSelRange, &aSelection.GetOptions() );
+ nThisTab = aFunc.GetTotalPages();
+ nFirstAttr[nTab] = aFunc.GetFirstPageNo(); // from page style or previous sheet
+ }
+ else
+ nFirstAttr[nTab] = nAttrPage;
+
+ nPages[nTab] = nThisTab;
+ nTotalPages += nThisTab;
+ }
+}
+
+ScPrintFuncCache::~ScPrintFuncCache()
+{
+}
+
+void ScPrintFuncCache::InitLocations( const ScMarkData& rMark, OutputDevice* pDev )
+{
+ if ( bLocInitialized )
+ return; // initialize only once
+
+ ScRange aRange;
+ const ScRange* pSelRange = NULL;
+ if ( rMark.IsMarked() )
+ {
+ rMark.GetMarkArea( aRange );
+ pSelRange = &aRange;
+ }
+
+ long nRenderer = 0; // 0-based physical page number across sheets
+ long nTabStart = 0;
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
+ {
+ if ( rMark.GetTableSelect( nTab ) )
+ {
+ ScPrintFunc aFunc( pDev, pDocSh, nTab, nFirstAttr[nTab], nTotalPages, pSelRange, &aSelection.GetOptions() );
+ aFunc.SetRenderFlag( TRUE );
+
+ long nDisplayStart = GetDisplayStart( nTab );
+
+ for ( long nPage=0; nPage<nPages[nTab]; nPage++ )
+ {
+ Range aPageRange( nRenderer+1, nRenderer+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ ScPreviewLocationData aLocData( pDoc, pDev );
+ aFunc.DoPrint( aPage, nTabStart, nDisplayStart, FALSE, NULL, &aLocData );
+
+ ScRange aCellRange;
+ Rectangle aPixRect;
+ if ( aLocData.GetMainCellRange( aCellRange, aPixRect ) )
+ aLocations.push_back( ScPrintPageLocation( nRenderer, aCellRange, aPixRect ) );
+
+ ++nRenderer;
+ }
+
+ nTabStart += nPages[nTab];
+ }
+ }
+
+ bLocInitialized = true;
+}
+
+bool ScPrintFuncCache::FindLocation( const ScAddress& rCell, ScPrintPageLocation& rLocation ) const
+{
+ for ( std::vector<ScPrintPageLocation>::const_iterator aIter(aLocations.begin());
+ aIter != aLocations.end(); aIter++ )
+ {
+ if ( aIter->aCellRange.In( rCell ) )
+ {
+ rLocation = *aIter;
+ return true;
+ }
+ }
+ return false; // not found
+}
+
+BOOL ScPrintFuncCache::IsSameSelection( const ScPrintSelectionStatus& rStatus ) const
+{
+ return aSelection == rStatus;
+}
+
+SCTAB ScPrintFuncCache::GetTabForPage( long nPage ) const
+{
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTab = 0;
+ while ( nTab < nTabCount && nPage >= nPages[nTab] )
+ nPage -= nPages[nTab++];
+ return nTab;
+}
+
+long ScPrintFuncCache::GetTabStart( SCTAB nTab ) const
+{
+ long nRet = 0;
+ for ( SCTAB i=0; i<nTab; i++ )
+ nRet += nPages[i];
+ return nRet;
+}
+
+long ScPrintFuncCache::GetDisplayStart( SCTAB nTab ) const
+{
+ //! merge with lcl_GetDisplayStart in preview?
+
+ long nDisplayStart = 0;
+ ScDocument* pDoc = pDocSh->GetDocument();
+ for (SCTAB i=0; i<nTab; i++)
+ {
+ if ( pDoc->NeedPageResetAfterTab(i) )
+ nDisplayStart = 0;
+ else
+ nDisplayStart += nPages[i];
+ }
+ return nDisplayStart;
+}
+
+
diff --git a/sc/source/ui/view/pgbrksh.cxx b/sc/source/ui/view/pgbrksh.cxx
new file mode 100644
index 000000000000..0e792b2bb279
--- /dev/null
+++ b/sc/source/ui/view/pgbrksh.cxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+
+#include "pgbrksh.hxx"
+#include "tabvwsh.hxx"
+#include "scresid.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+
+//------------------------------------------------------------------------
+
+#define ScPageBreakShell
+#include "scslots.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScPageBreakShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScPageBreakShell, SfxShell, ScResId(SCSTR_PAGEBREAKSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_PAGEBREAK) );
+}
+
+
+//------------------------------------------------------------------------
+ScPageBreakShell::ScPageBreakShell( ScTabViewShell* pViewSh ) :
+ SfxShell(pViewSh)
+{
+ SetPool( &pViewSh->GetPool() );
+ ScViewData* pViewData = pViewSh->GetViewData();
+ SfxUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_PAGEBREAK );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("PageBreak")));
+}
+
+//------------------------------------------------------------------------
+ScPageBreakShell::~ScPageBreakShell()
+{
+}
+
+
diff --git a/sc/source/ui/view/pivotsh.cxx b/sc/source/ui/view/pivotsh.cxx
new file mode 100644
index 000000000000..a65f86ffed2c
--- /dev/null
+++ b/sc/source/ui/view/pivotsh.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "sc.hrc"
+#include "pivotsh.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+#include "dpshttab.hxx"
+#include "dbdocfun.hxx"
+#include "uiitems.hxx"
+//CHINA001 #include "pfiltdlg.hxx"
+#include "scabstdlg.hxx" //CHINA001
+//------------------------------------------------------------------------
+
+#define ScPivotShell
+#include "scslots.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScPivotShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScPivotShell, SfxShell, ScResId(SCSTR_PIVOTSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_PIVOT) );
+}
+
+
+//------------------------------------------------------------------------
+
+ScPivotShell::ScPivotShell( ScTabViewShell* pViewSh ) :
+ SfxShell(pViewSh),
+ pViewShell( pViewSh )
+{
+ SetPool( &pViewSh->GetPool() );
+ ScViewData* pViewData = pViewSh->GetViewData();
+ SfxUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_PIVOTSH );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Pivot")));
+}
+
+//------------------------------------------------------------------------
+ScPivotShell::~ScPivotShell()
+{
+}
+
+//------------------------------------------------------------------------
+void ScPivotShell::Execute( SfxRequest& rReq )
+{
+ switch ( rReq.GetSlot() )
+ {
+ case SID_PIVOT_RECALC:
+ pViewShell->RecalcPivotTable();
+ break;
+
+ case SID_PIVOT_KILL:
+ pViewShell->DeletePivotTable();
+ break;
+
+ case SID_DP_FILTER:
+ {
+ ScDPObject* pDPObj = GetCurrDPObject();
+ if( pDPObj )
+ {
+ ScQueryParam aQueryParam;
+ SCTAB nSrcTab = 0;
+ const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
+ DBG_ASSERT( pDesc, "no sheet source for DP filter dialog" );
+ if( pDesc )
+ {
+ aQueryParam = pDesc->aQueryParam;
+ nSrcTab = pDesc->aSourceRange.aStart.Tab();
+ }
+
+ ScViewData* pViewData = pViewShell->GetViewData();
+ SfxItemSet aArgSet( pViewShell->GetPool(),
+ SCITEM_QUERYDATA, SCITEM_QUERYDATA );
+ aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, pViewData, &aQueryParam ) );
+
+ //CHINA001 ScPivotFilterDlg* pDlg = new ScPivotFilterDlg(
+ //CHINA001 pViewShell->GetDialogParent(), aArgSet, nSrcTab );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScPivotFilterDlg* pDlg = pFact->CreateScPivotFilterDlg( pViewShell->GetDialogParent(),
+ aArgSet, nSrcTab,
+ RID_SCDLG_PIVOTFILTER);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if( pDlg->Execute() == RET_OK )
+ {
+ ScSheetSourceDesc aNewDesc;
+ if( pDesc )
+ aNewDesc = *pDesc;
+
+ const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
+ aNewDesc.aQueryParam = rQueryItem.GetQueryData();
+
+ ScDPObject aNewObj( *pDPObj );
+ aNewObj.SetSheetDesc( aNewDesc );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, TRUE, FALSE );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ delete pDlg;
+ }
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------
+void __EXPORT ScPivotShell::GetState( SfxItemSet& rSet )
+{
+ ScDocShell* pDocSh = pViewShell->GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bDisable = pDocSh->IsReadOnly() || pDoc->GetChangeTrack();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PIVOT_RECALC:
+ case SID_PIVOT_KILL:
+ {
+ //! move ReadOnly check to idl flags
+ if ( bDisable )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ case SID_DP_FILTER:
+ {
+ ScDPObject* pDPObj = GetCurrDPObject();
+ if( bDisable || !pDPObj || !pDPObj->IsSheetData() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+//------------------------------------------------------------------------
+
+ScDPObject* ScPivotShell::GetCurrDPObject()
+{
+ const ScViewData& rViewData = *pViewShell->GetViewData();
+ return rViewData.GetDocument()->GetDPAtCursor(
+ rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
+}
+
diff --git a/sc/source/ui/view/preview.cxx b/sc/source/ui/view/preview.cxx
new file mode 100644
index 000000000000..83fdab9000e6
--- /dev/null
+++ b/sc/source/ui/view/preview.cxx
@@ -0,0 +1,1603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/pstm.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svtools/colorcfg.hxx>
+#include <svx/fmview.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/svdpagv.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svl/itemset.hxx>
+#include <tools/multisel.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/sound.hxx>
+
+#include "preview.hxx"
+#include "prevwsh.hxx"
+#include "prevloc.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "printfun.hxx"
+#include "printopt.hxx"
+#include "stlpool.hxx"
+#include "undostyl.hxx"
+#include "drwlayer.hxx"
+#include "scmod.hxx"
+#include "globstr.hrc"
+#include "sc.hrc" // fuer ShellInvalidate
+#include "AccessibleDocumentPagePreview.hxx"
+#include <vcl/lineinfo.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include "attrib.hxx"
+#include "pagepar.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include "AccessibilityHints.hxx"
+#include <vcl/svapp.hxx>
+#include "viewutil.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+#define SC_PREVIEW_SHADOWSIZE 2
+
+long lcl_GetDisplayStart( SCTAB nTab, ScDocument* pDoc, long* pPages )
+{
+ long nDisplayStart = 0;
+ for (SCTAB i=0; i<nTab; i++)
+ {
+ if ( pDoc->NeedPageResetAfterTab(i) )
+ nDisplayStart = 0;
+ else
+ nDisplayStart += pPages[i];
+ }
+ return nDisplayStart;
+}
+
+
+ScPreview::ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh ) :
+ Window( pParent ),
+ nPageNo( 0 ),
+ nZoom( 100 ),
+ bValid( FALSE ),
+ nTabsTested( 0 ),
+ nTab( 0 ),
+ nTabStart( 0 ),
+ nDisplayStart( 0 ),
+ nTotalPages( 0 ),
+ bStateValid( FALSE ),
+ bLocationValid( FALSE ),
+ pLocationData( NULL ),
+ pDrawView( NULL ),
+ bInPaint( FALSE ),
+ bInGetState( FALSE ),
+ pDocShell( pDocSh ),
+ pViewShell( pViewSh ),
+ bLeftRulerMove( FALSE ),
+ bRightRulerMove( FALSE ),
+ bTopRulerMove( FALSE ),
+ bBottomRulerMove( FALSE ),
+ bHeaderRulerMove( FALSE ),
+ bFooterRulerMove( FALSE ),
+ bLeftRulerChange( FALSE ),
+ bRightRulerChange( FALSE ),
+ bTopRulerChange( FALSE ),
+ bBottomRulerChange( FALSE ),
+ bHeaderRulerChange( FALSE ),
+ bFooterRulerChange( FALSE ),
+ bPageMargin ( FALSE ),
+ bColRulerMove( FALSE ),
+ mnScale( 0 ),
+ nColNumberButttonDown( 0 ),
+ nHeaderHeight ( 0 ),
+ nFooterHeight ( 0 )
+{
+ SetOutDevViewType( OUTDEV_VIEWTYPE_PRINTPREVIEW ); //#106611#
+ SetBackground();
+
+ SetHelpId( HID_SC_WIN_PREVIEW );
+ SetUniqueId( HID_SC_WIN_PREVIEW );
+
+ SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+}
+
+
+__EXPORT ScPreview::~ScPreview()
+{
+ delete pDrawView;
+ delete pLocationData;
+}
+
+void ScPreview::UpdateDrawView() // nTab muss richtig sein
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pModel = pDoc->GetDrawLayer(); // ist nicht 0
+
+ // #114135#
+ if ( pModel )
+ {
+ SdrPage* pPage = pModel->GetPage(nTab);
+ if ( pDrawView && ( !pDrawView->GetSdrPageView() || pDrawView->GetSdrPageView()->GetPage() != pPage ) )
+ {
+ // die angezeigte Page der DrawView umzustellen (s.u.) funktioniert nicht ?!?
+ delete pDrawView;
+ pDrawView = NULL;
+ }
+
+ if ( !pDrawView ) // neu anlegen?
+ {
+ pDrawView = new FmFormView( pModel, this );
+ // #55259# die DrawView uebernimmt den Design-Modus vom Model
+ // (Einstellung "Im Entwurfsmodus oeffnen"), darum hier zuruecksetzen
+ pDrawView->SetDesignMode( TRUE );
+ pDrawView->SetPrintPreview( TRUE );
+ pDrawView->ShowSdrPage(pPage);
+ }
+#if 0
+ else if ( !pDrawView->GetSdrPageView()) // angezeigte Page umstellen
+ {
+ pDrawView->HideSdrPage();
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ }
+#endif
+ }
+ else if ( pDrawView )
+ {
+ delete pDrawView; // fuer diese Tabelle nicht gebraucht
+ pDrawView = NULL;
+ }
+}
+
+
+void ScPreview::TestLastPage()
+{
+ if (nPageNo >= nTotalPages)
+ {
+ if (nTotalPages)
+ {
+ nPageNo = nTotalPages - 1;
+ nTab = nTabCount - 1;
+ while (nTab > 0 && !nPages[nTab]) // letzte nicht leere Tabelle
+ --nTab;
+ DBG_ASSERT(nPages[nTab],"alle Tabellen leer?");
+ nTabPage = nPages[nTab] - 1;
+ nTabStart = 0;
+ for (USHORT i=0; i<nTab; i++)
+ nTabStart += nPages[i];
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
+ }
+ else // leeres Dokument
+ {
+ nTab = 0;
+ nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
+ aState.nPrintTab = 0;
+ aState.nStartCol = aState.nEndCol = 0;
+ aState.nStartRow = aState.nEndRow = 0;
+ aState.nZoom = 0;
+ aState.nPagesX = aState.nPagesY = 0;
+ aState.nTabPages = aState.nTotalPages =
+ aState.nPageStart = aState.nDocPages = 0;
+ }
+ }
+}
+
+
+void ScPreview::CalcPages( SCTAB /*nToWhichTab*/ )
+{
+ WaitObject( this );
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ nTabCount = pDoc->GetTableCount();
+
+ //SCTAB nAnz = Min( nTabCount, SCTAB(nToWhichTab+1) );
+ SCTAB nAnz = nTabCount;
+ SCTAB nStart = nTabsTested;
+ if (!bValid)
+ {
+ nStart = 0;
+ nTotalPages = 0;
+ 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();
+
+ for (SCTAB i=nStart; i<nAnz; i++)
+ {
+ long nAttrPage = i > 0 ? nFirstAttr[i-1] : 1;
+
+ long nThisStart = nTotalPages;
+ ScPrintFunc aPrintFunc( this, pDocShell, i, nAttrPage, 0, NULL, &aOptions );
+ long nThisTab = aPrintFunc.GetTotalPages();
+ nPages[i] = nThisTab;
+ nTotalPages += nThisTab;
+ nFirstAttr[i] = aPrintFunc.GetFirstPageNo(); // behalten oder aus Vorlage
+
+ if (nPageNo>=nThisStart && nPageNo<nTotalPages)
+ {
+ nTab = i;
+ nTabPage = nPageNo - nThisStart;
+ nTabStart = nThisStart;
+
+ aPrintFunc.GetPrintState( aState );
+ aPageSize = aPrintFunc.GetPageSize();
+ }
+ }
+
+ nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
+
+ if (nAnz > nTabsTested)
+ nTabsTested = nAnz;
+
+ // testen, ob hinter letzter Seite
+
+ if ( nTabsTested >= nTabCount )
+ TestLastPage();
+
+ aState.nDocPages = nTotalPages;
+
+ bValid = TRUE;
+ bStateValid = TRUE;
+ DoInvalidate();
+}
+
+
+void ScPreview::RecalcPages() // nur nPageNo geaendert
+{
+ if (!bValid)
+ return; // dann wird CalcPages aufgerufen
+
+ SCTAB nOldTab = nTab;
+
+ BOOL bDone = FALSE;
+ while (nPageNo >= nTotalPages && nTabsTested < nTabCount)
+ {
+ CalcPages( nTabsTested );
+ bDone = TRUE;
+ }
+
+ if (!bDone)
+ {
+ long nPartPages = 0;
+ for (SCTAB i=0; i<nTabsTested; i++)
+ {
+ long nThisStart = nPartPages;
+ nPartPages += nPages[i];
+
+ if (nPageNo>=nThisStart && nPageNo<nPartPages)
+ {
+ nTab = i;
+ nTabPage = nPageNo - nThisStart;
+ nTabStart = nThisStart;
+
+// aPageSize = aPrintFunc.GetPageSize();
+ }
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
+ }
+
+ TestLastPage(); // testen, ob hinter letzter Seite
+
+ if ( nTab != nOldTab )
+ bStateValid = FALSE;
+
+ DoInvalidate();
+}
+
+
+void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation )
+{
+ if (!bValid)
+ {
+ CalcPages(0);
+ RecalcPages();
+ UpdateDrawView(); // Tabelle evtl. geaendert
+ }
+
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ BOOL bDoPrint = ( pFillLocation == NULL );
+ BOOL bValidPage = ( nPageNo < nTotalPages );
+
+ ScModule* pScMod = SC_MOD();
+ const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
+ Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
+
+ if ( bDoPrint && ( aOffset.X() < 0 || aOffset.Y() < 0 ) && bValidPage )
+ {
+ SetMapMode( aMMMode );
+ SetLineColor();
+ SetFillColor(aBackColor);
+
+ Size aWinSize = GetOutputSize();
+ if ( aOffset.X() < 0 )
+ DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
+ if ( aOffset.Y() < 0 )
+ DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
+ }
+
+ Size aLocalPageSize;
+ if ( bValidPage )
+ {
+ ScPrintOptions aOptions = pScMod->GetPrintOptions();
+
+ ScPrintFunc* pPrintFunc;
+ if (bStateValid)
+ pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
+ else
+ pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
+
+ pPrintFunc->SetOffset(aOffset);
+ pPrintFunc->SetManualZoom(nZoom);
+ pPrintFunc->SetDateTime(aDate,aTime);
+ pPrintFunc->SetClearFlag(TRUE);
+ pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
+
+ pPrintFunc->SetDrawView( pDrawView );
+
+ // MultiSelection fuer die eine Seite muss etwas umstaendlich erzeugt werden...
+ Range aPageRange( nPageNo+1, nPageNo+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, NULL, pFillLocation );
+ DBG_ASSERT(nPrinted<=1, "was'n nu los?");
+
+ SetMapMode(aMMMode);
+// USHORT nPrintZoom = pPrintFunc->GetZoom();
+
+ if (nPrinted) // wenn nichts, alles grau zeichnen
+ {
+ aLocalPageSize = pPrintFunc->GetPageSize();
+ aLocalPageSize.Width() = (long) (aLocalPageSize.Width() * HMM_PER_TWIPS );
+ aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS );
+ }
+
+ if (!bStateValid)
+ {
+ pPrintFunc->GetPrintState( aState );
+ aState.nDocPages = nTotalPages;
+ bStateValid = TRUE;
+ }
+ delete pPrintFunc;
+ }
+
+ if ( bDoPrint )
+ {
+ long nPageEndX = aLocalPageSize.Width() - aOffset.X();
+ long nPageEndY = aLocalPageSize.Height() - aOffset.Y();
+ if ( !bValidPage )
+ nPageEndX = nPageEndY = 0;
+
+ Size aWinSize = GetOutputSize();
+ Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
+ BOOL bRight = nPageEndX <= aWinEnd.X();
+ BOOL bBottom = nPageEndY <= aWinEnd.Y();
+ if (bRight || bBottom)
+ {
+ SetLineColor();
+ SetFillColor(aBackColor);
+ if (bRight)
+ DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
+ if (bBottom)
+ {
+ if (bRight)
+ DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Ecke nicht doppelt
+ else
+ DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
+ }
+ }
+
+ if ( bValidPage )
+ {
+ Color aBorderColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ // draw border
+
+ if ( aOffset.X() <= 0 || aOffset.Y() <= 0 || bRight || bBottom )
+ {
+ SetLineColor( aBorderColor );
+ SetFillColor();
+
+ Rectangle aPixel( LogicToPixel( Rectangle( -aOffset.X(), -aOffset.Y(), nPageEndX, nPageEndY ) ) );
+ --aPixel.Right();
+ --aPixel.Bottom();
+ DrawRect( PixelToLogic( aPixel ) );
+ }
+
+ // draw shadow
+
+ SetLineColor();
+ SetFillColor( aBorderColor );
+
+ Rectangle aPixel;
+
+ aPixel = LogicToPixel( Rectangle( nPageEndX, -aOffset.Y(), nPageEndX, nPageEndY ) );
+ aPixel.Top() += SC_PREVIEW_SHADOWSIZE;
+ aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
+ aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
+ DrawRect( PixelToLogic( aPixel ) );
+
+ aPixel = LogicToPixel( Rectangle( -aOffset.X(), nPageEndY, nPageEndX, nPageEndY ) );
+ aPixel.Left() += SC_PREVIEW_SHADOWSIZE;
+ aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
+ aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
+ DrawRect( PixelToLogic( aPixel ) );
+ }
+ }
+}
+
+//Issue51656 Add resizeable margin on page preview from maoyg
+void __EXPORT ScPreview::Paint( const Rectangle& /* rRect */ )
+{
+ if (!bValid)
+ {
+ CalcPages(0);
+ RecalcPages();
+ UpdateDrawView(); // Table possibly amended
+ }
+
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ ScModule* pScMod = SC_MOD();
+ const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
+ Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
+
+ if ( aOffset.X() < 0 || aOffset.Y() < 0 )
+ {
+ SetMapMode( aMMMode );
+ SetLineColor();
+ SetFillColor(aBackColor);
+
+ Size aWinSize = GetOutputSize();
+ if ( aOffset.X() < 0 )
+ DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
+ if ( aOffset.Y() < 0 )
+ DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
+ }
+
+ long nLeftMargin = 0;
+ long nRightMargin = 0;
+ long nTopMargin = 0;
+ long nBottomMargin = 0;
+ BOOL bHeaderOn = FALSE;
+ BOOL bFooterOn = FALSE;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Size aPaintPageSize;
+ if ( nPageNo < nTotalPages )
+ {
+ ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
+
+ ScPrintFunc* pPrintFunc;
+ if ( bStateValid )
+ pPrintFunc = new ScPrintFunc( pDocShell, this, aState, &aOptions );
+ else
+ pPrintFunc = new ScPrintFunc( pDocShell, this, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
+
+ pPrintFunc->SetOffset(aOffset);
+ pPrintFunc->SetManualZoom(nZoom);
+ pPrintFunc->SetDateTime(aDate,aTime);
+ pPrintFunc->SetClearFlag(TRUE);
+ pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
+ pPrintFunc->SetDrawView( pDrawView );
+
+ // Multi Selection for one side must be something umstaendlich generated ...
+ Range aPageRange( nPageNo+1, nPageNo+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart );
+ DBG_ASSERT(nPrinted<=1, "was'n nu los?");
+
+ SetMapMode(aMMMode);
+
+ //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
+ nLeftMargin = pPrintFunc->GetLeftMargin();
+ nRightMargin = pPrintFunc->GetRightMargin();
+ nTopMargin = pPrintFunc->GetTopMargin();
+ nBottomMargin = pPrintFunc->GetBottomMargin();
+ nHeaderHeight = pPrintFunc->GetHeader().nHeight;
+ nFooterHeight = pPrintFunc->GetFooter().nHeight;
+ bHeaderOn = pPrintFunc->GetHeader().bEnable;
+ bFooterOn = pPrintFunc->GetFooter().bEnable;
+ mnScale = pPrintFunc->GetZoom();
+
+ Rectangle aPixRect;
+ Rectangle aRectCellPosition;
+ Rectangle aRectPosition;
+ GetLocationData().GetMainCellRange( aPageArea, aPixRect );
+ if( !bLayoutRTL )
+ {
+ GetLocationData().GetCellPosition( aPageArea.aStart, aRectPosition );
+ nLeftPosition = aRectPosition.Left();
+ for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ )
+ {
+ GetLocationData().GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition );
+ nRight[i] = aRectCellPosition.Right();
+ }
+ }
+ else
+ {
+ GetLocationData().GetCellPosition( aPageArea.aEnd, aRectPosition );
+ nLeftPosition = aRectPosition.Right()+1;
+
+ GetLocationData().GetCellPosition( aPageArea.aStart,aRectCellPosition );
+ nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left();
+ for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- )
+ {
+ GetLocationData().GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition );
+ nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1;
+ }
+ }
+
+ if ( nPrinted ) // If nothing, all gray draw
+ {
+ aPaintPageSize = pPrintFunc->GetPageSize();
+ aPaintPageSize.Width() = (long) (aPaintPageSize.Width() * HMM_PER_TWIPS );
+ aPaintPageSize.Height() = (long) (aPaintPageSize.Height() * HMM_PER_TWIPS );
+
+ nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS );
+ nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS );
+ nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS );
+ nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS );
+ nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin );
+ nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin );
+ }
+
+ if ( !bStateValid )
+ {
+ pPrintFunc->GetPrintState( aState );
+ aState.nDocPages = nTotalPages;
+ bStateValid = TRUE;
+ }
+
+ delete pPrintFunc;
+ }
+
+
+ long nPageEndX = aPaintPageSize.Width() - aOffset.X();
+ long nPageEndY = aPaintPageSize.Height() - aOffset.Y();
+ Size aWinSize = GetOutputSize();
+ Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
+ BOOL bRight = nPageEndX <= aWinEnd.X();
+ BOOL bBottom = nPageEndY <= aWinEnd.Y();
+
+ if( bPageMargin )
+ {
+ SetMapMode(aMMMode);
+ SetLineColor( COL_BLACK );
+ DrawInvert( (long)( nTopMargin - aOffset.Y() ), POINTER_VSIZEBAR );
+ DrawInvert( (long)(nPageEndY - nBottomMargin ), POINTER_VSIZEBAR );
+ DrawInvert( (long)( nLeftMargin - aOffset.X() ), POINTER_HSIZEBAR );
+ DrawInvert( (long)( nPageEndX - nRightMargin ) , POINTER_HSIZEBAR );
+ if( bHeaderOn )
+ {
+ DrawInvert( nHeaderHeight - aOffset.Y(), POINTER_VSIZEBAR );
+ }
+ if( bFooterOn )
+ {
+ DrawInvert( nPageEndY - nFooterHeight, POINTER_VSIZEBAR );
+ }
+
+ SetMapMode( MapMode( MAP_PIXEL ) );
+ for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
+ {
+ Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
+ SetLineColor( COL_BLACK );
+ SetFillColor( COL_BLACK );
+ DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) ));
+ DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) );
+ }
+ SetMapMode( aMMMode );
+ }
+
+ if (bRight || bBottom)
+ {
+ SetMapMode(aMMMode);
+ SetLineColor();
+ SetFillColor(aBackColor);
+ if (bRight)
+ DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
+ if (bBottom)
+ {
+ if (bRight)
+ DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Ecke nicht doppelt
+ else
+ DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
+ }
+ }
+ pViewShell->UpdateScrollBars();
+}
+//Issue51656 Add resizeable margin on page preview from maoyg
+
+void __EXPORT ScPreview::Command( const CommandEvent& rCEvt )
+{
+ USHORT nCmd = rCEvt.GetCommand();
+ if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
+ {
+ BOOL bDone = pViewShell->ScrollCommand( rCEvt );
+ if (!bDone)
+ Window::Command(rCEvt);
+ }
+ else if ( nCmd == COMMAND_CONTEXTMENU )
+ SfxDispatcher::ExecutePopup();
+ else
+ Window::Command( rCEvt );
+}
+
+
+void __EXPORT ScPreview::KeyInput( const KeyEvent& rKEvt )
+{
+ // The + and - keys can't be configured as accelerator entries, so they must be handled directly
+ // (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
+
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ USHORT nKey = rKeyCode.GetCode();
+ BOOL bHandled = FALSE;
+ if(!rKeyCode.GetModifier())
+ {
+ USHORT nSlot = 0;
+ switch(nKey)
+ {
+ case KEY_ADD: nSlot = SID_PREVIEW_ZOOMIN; break;
+ case KEY_ESCAPE: nSlot = ScViewUtil::IsFullScreen( *pViewShell ) ? SID_CANCEL : SID_PREVIEW_CLOSE; break;
+ case KEY_SUBTRACT: nSlot = SID_PREVIEW_ZOOMOUT; break;
+ }
+ if(nSlot)
+ {
+ bHandled = TRUE;
+ pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSlot, SFX_CALLMODE_ASYNCHRON );
+ }
+ }
+
+ if ( !bHandled && !pViewShell->KeyInput(rKEvt) )
+ Window::KeyInput(rKEvt);
+}
+
+
+const ScPreviewLocationData& ScPreview::GetLocationData()
+{
+ if ( !pLocationData )
+ {
+ pLocationData = new ScPreviewLocationData( pDocShell->GetDocument(), this );
+ bLocationValid = FALSE;
+ }
+ if ( !bLocationValid )
+ {
+ pLocationData->Clear();
+ DoPrint( pLocationData );
+ bLocationValid = TRUE;
+ }
+ return *pLocationData;
+}
+
+
+void ScPreview::DataChanged(BOOL bNewTime)
+{
+ if (bNewTime)
+ {
+ aDate = Date();
+ aTime = Time();
+ }
+
+ bValid = FALSE;
+ InvalidateLocationData( SC_HINT_DATACHANGED );
+ Invalidate();
+}
+
+
+String ScPreview::GetPosString()
+{
+ if (!bValid)
+ {
+ CalcPages(nTab);
+ UpdateDrawView(); // Tabelle evtl. geaendert
+ }
+
+ String aString( ScGlobal::GetRscString( STR_PAGE ) );
+ aString += ' ';
+ aString += String::CreateFromInt32(nPageNo+1);
+
+ if (nTabsTested >= nTabCount)
+ {
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aString += String::CreateFromInt32(nTotalPages);
+ }
+
+ return aString;
+}
+
+
+void ScPreview::SetZoom(USHORT nNewZoom)
+{
+ if (nNewZoom < 20)
+ nNewZoom = 20;
+ if (nNewZoom > 400)
+ nNewZoom = 400;
+ if (nNewZoom != nZoom)
+ {
+ nZoom = nNewZoom;
+
+ // apply new MapMode and call UpdateScrollBars to update aOffset
+
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+ SetMapMode( aMMMode );
+
+ bInPaint = TRUE; // don't scroll during SetYOffset in UpdateScrollBars
+ pViewShell->UpdateScrollBars();
+ bInPaint = FALSE;
+
+ bStateValid = FALSE;
+ InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
+ DoInvalidate();
+ Invalidate();
+ }
+}
+
+
+void ScPreview::SetPageNo( long nPage )
+{
+ nPageNo = nPage;
+ RecalcPages();
+ UpdateDrawView(); // Tabelle evtl. geaendert
+ InvalidateLocationData( SC_HINT_DATACHANGED );
+ Invalidate();
+}
+
+
+long ScPreview::GetFirstPage(SCTAB nTabP)
+{
+ SCTAB nDocTabCount = pDocShell->GetDocument()->GetTableCount();
+ if (nTabP >= nDocTabCount)
+ nTabP = nDocTabCount-1;
+
+ long nPage = 0;
+ if (nTabP>0)
+ {
+ CalcPages( nTabP );
+ UpdateDrawView(); // Tabelle evtl. geaendert
+
+ for (SCTAB i=0; i<nTabP; i++)
+ nPage += nPages[i];
+
+ // bei leerer Tabelle vorhergehende Seite
+
+ if ( nPages[nTabP]==0 && nPage > 0 )
+ --nPage;
+ }
+
+ return nPage;
+}
+
+
+Size lcl_GetDocPageSize( ScDocument* pDoc, SCTAB nTab )
+{
+ String aName = pDoc->GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aName, SFX_STYLE_FAMILY_PAGE );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ return ((const SvxSizeItem&) rStyleSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ }
+ else
+ {
+ DBG_ERROR( "PageStyle not found" );
+ return Size();
+ }
+}
+
+
+USHORT ScPreview::GetOptimalZoom(BOOL bWidthOnly)
+{
+ double nWinScaleX = ScGlobal::nScreenPPTX / pDocShell->GetOutputFactor();
+ double nWinScaleY = ScGlobal::nScreenPPTY;
+ Size aWinSize = GetOutputSizePixel();
+
+ // desired margin is 0.25cm in default MapMode (like Writer),
+ // but some additional margin is introduced by integer scale values
+ // -> add only 0.10cm, so there is some margin in all cases.
+ Size aMarginSize( LogicToPixel( Size( 100, 100 ), MAP_100TH_MM ) );
+ aWinSize.Width() -= 2 * aMarginSize.Width();
+ aWinSize.Height() -= 2 * aMarginSize.Height();
+
+ Size aLocalPageSize = lcl_GetDocPageSize( pDocShell->GetDocument(), nTab );
+ if ( aLocalPageSize.Width() && aLocalPageSize.Height() )
+ {
+ long nZoomX = (long) ( aWinSize.Width() * 100 / ( aLocalPageSize.Width() * nWinScaleX ));
+ long nZoomY = (long) ( aWinSize.Height() * 100 / ( aLocalPageSize.Height() * nWinScaleY ));
+
+ long nOptimal = nZoomX;
+ if (!bWidthOnly && nZoomY<nOptimal)
+ nOptimal = nZoomY;
+
+ if (nOptimal<20)
+ nOptimal = 20;
+ if (nOptimal>400)
+ nOptimal = 400;
+
+ return (USHORT) nOptimal;
+ }
+ else
+ return nZoom;
+}
+
+
+void ScPreview::SetXOffset( long nX )
+{
+ if ( aOffset.X() == nX )
+ return;
+
+ if (bValid)
+ {
+ long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X();
+ aOffset.X() = nX;
+ if (nDif && !bInPaint)
+ {
+ MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
+ Scroll( nDif, 0 );
+ SetMapMode(aOldMode);
+ }
+ }
+ else
+ {
+ aOffset.X() = nX;
+ if (!bInPaint)
+ Invalidate();
+ }
+ InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
+ Paint(Rectangle());
+}
+
+
+void ScPreview::SetYOffset( long nY )
+{
+ if ( aOffset.Y() == nY )
+ return;
+
+ if (bValid)
+ {
+ long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y();
+ aOffset.Y() = nY;
+ if (nDif && !bInPaint)
+ {
+ MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
+ Scroll( 0, nDif );
+ SetMapMode(aOldMode);
+ }
+ }
+ else
+ {
+ aOffset.Y() = nY;
+ if (!bInPaint)
+ Invalidate();
+ }
+ InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
+ Paint(Rectangle());
+}
+
+
+void ScPreview::DoInvalidate()
+{
+ // Wenn das ganze aus dem GetState der Shell gerufen wird,
+ // muss das Invalidate hinterher asynchron kommen...
+
+ if (bInGetState)
+ Application::PostUserEvent( STATIC_LINK( this, ScPreview, InvalidateHdl ) );
+ else
+ StaticInvalidate(); // sofort
+}
+
+void ScPreview::StaticInvalidate()
+{
+ // static method, because it's called asynchronously
+ // -> must use current viewframe
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (!pViewFrm)
+ return;
+
+ SfxBindings& rBindings = pViewFrm->GetBindings();
+ rBindings.Invalidate(SID_STATUS_DOCPOS);
+ rBindings.Invalidate(SID_STATUS_PAGESTYLE);
+ rBindings.Invalidate(SID_PREVIEW_PREVIOUS);
+ rBindings.Invalidate(SID_PREVIEW_NEXT);
+ rBindings.Invalidate(SID_PREVIEW_FIRST);
+ rBindings.Invalidate(SID_PREVIEW_LAST);
+ rBindings.Invalidate(SID_ATTR_ZOOM);
+ rBindings.Invalidate(SID_PREVIEW_ZOOMIN);
+ rBindings.Invalidate(SID_PREVIEW_ZOOMOUT);
+ rBindings.Invalidate(SID_PREVIEW_SCALINGFACTOR);
+ rBindings.Invalidate(SID_ATTR_ZOOMSLIDER);
+}
+
+IMPL_STATIC_LINK( ScPreview, InvalidateHdl, void*, EMPTYARG )
+{
+ (void)pThis; // avoid warning
+
+ StaticInvalidate();
+ return 0;
+}
+
+void ScPreview::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged(rDCEvt);
+
+ if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( rDCEvt.GetType() == DATACHANGED_FONTS )
+ pDocShell->UpdateFontList();
+
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ // scroll bar size may have changed
+ pViewShell->InvalidateBorder(); // calls OuterResizePixel
+ }
+
+ Invalidate();
+ InvalidateLocationData( SC_HINT_DATACHANGED );
+ }
+}
+
+//Issue51656 Add resizeable margin on page preview from maoyg
+void __EXPORT ScPreview::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ aButtonDownChangePoint = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
+ aButtonDownPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
+
+ CaptureMouse();
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
+ {
+ SetMapMode( aMMMode );
+ if( bLeftRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
+ bLeftRulerMove = TRUE;
+ bRightRulerMove = FALSE;
+ }
+ else if( bRightRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
+ bLeftRulerMove = FALSE;
+ bRightRulerMove = TRUE;
+ }
+ }
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
+ {
+ SetMapMode( aMMMode );
+ if( bTopRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bTopRulerMove = TRUE;
+ bBottomRulerMove = FALSE;
+ }
+ else if( bBottomRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bTopRulerMove = FALSE;
+ bBottomRulerMove = TRUE;
+ }
+ else if( bHeaderRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bHeaderRulerMove = TRUE;
+ bFooterRulerMove = FALSE;
+ }
+ else if( bFooterRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bHeaderRulerMove = FALSE;
+ bFooterRulerMove = TRUE;
+ }
+ }
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
+ {
+ Point aNowPt = rMEvt.GetPosPixel();
+ SCCOL i = 0;
+ for( i = aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
+ {
+ if( aNowPt.X() < nRight[i] + 2 && aNowPt.X() > nRight[i] - 2 )
+ {
+ nColNumberButttonDown = i;
+ break;
+ }
+ }
+ if( i == aPageArea.aEnd.Col()+1 )
+ return;
+
+ SetMapMode( aMMMode );
+ if( nColNumberButttonDown == aPageArea.aStart.Col() )
+ DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+ else
+ DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+
+ DrawInvert( aButtonDownChangePoint.X(), POINTER_HSPLIT );
+ bColRulerMove = TRUE;
+ }
+}
+
+void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ aButtonUpPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
+
+ long nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
+ long nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
+ {
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ BOOL bMoveRulerAction= TRUE;
+
+ ScDocument * pDoc = pDocShell->GetDocument();
+ String aOldName = pDoc->GetPageStyle( nTab );
+ BOOL bUndo( pDoc->IsUndoEnabled() );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+
+ if ( pStyleSheet )
+ {
+ ScStyleSaveData aOldData;
+ if( bUndo )
+ aOldData.InitFromStyle( pStyleSheet );
+
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ SvxLRSpaceItem aLRItem = ( const SvxLRSpaceItem& ) rStyleSet.Get( ATTR_LRSPACE );
+
+ if(( bLeftRulerChange || bRightRulerChange ) && ( aButtonUpPt.X() <= ( 0 - aOffset.X() ) || aButtonUpPt.X() > nWidth * HMM_PER_TWIPS - aOffset.X() ) )
+ {
+ bMoveRulerAction = FALSE;
+ Paint(Rectangle(0,0,10000,10000));
+ }
+ else if( bLeftRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS > nWidth - aLRItem.GetRight() - aOffset.X() / HMM_PER_TWIPS ) )
+ {
+ bMoveRulerAction = FALSE;
+ Paint(Rectangle(0,0,10000,10000));
+ }
+ else if( bRightRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS < aLRItem.GetLeft() - aOffset.X() / HMM_PER_TWIPS ) )
+ {
+ bMoveRulerAction = FALSE;
+ Paint(Rectangle(0,0,10000,10000));
+ }
+ else if( aButtonDownPt.X() == aButtonUpPt.X() )
+ {
+ bMoveRulerAction = FALSE;
+ DrawInvert( aButtonUpPt.X(), POINTER_HSIZEBAR );
+ }
+ if( bMoveRulerAction )
+ {
+ if( bLeftRulerChange && bLeftRulerMove )
+ {
+ aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS ));
+ rStyleSet.Put( aLRItem );
+ }
+ else if( bRightRulerChange && bRightRulerMove )
+ {
+ aLRItem.SetRight( (long)( nWidth - aButtonUpPt.X() / HMM_PER_TWIPS - aOffset.X() / HMM_PER_TWIPS ));
+ rStyleSet.Put( aLRItem );
+ }
+
+ ScStyleSaveData aNewData;
+ aNewData.InitFromStyle( pStyleSheet );
+ if( bUndo )
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
+ aOldData, aNewData ) );
+ }
+
+ if ( ValidTab( nTab ) )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, this, nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ Rectangle aRect(0,0,10000,10000);
+ Paint( aRect );
+ bLeftRulerChange = FALSE;
+ bRightRulerChange = FALSE;
+ }
+ }
+ bLeftRulerMove = FALSE;
+ bRightRulerMove = FALSE;
+ }
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
+ {
+ SetPointer( POINTER_ARROW );
+
+ BOOL bMoveRulerAction = TRUE;
+ if( ( bTopRulerChange || bBottomRulerChange || bHeaderRulerChange || bFooterRulerChange ) && ( aButtonUpPt.Y() <= ( 0 - aOffset.Y() ) || aButtonUpPt.Y() > nHeight * HMM_PER_TWIPS -aOffset.Y() ) )
+ {
+ bMoveRulerAction = FALSE;
+ Paint( Rectangle(0,0,10000,10000) );
+ }
+ else if( aButtonDownPt.Y() == aButtonUpPt.Y() )
+ {
+ bMoveRulerAction = FALSE;
+ DrawInvert( aButtonUpPt.Y(), POINTER_VSIZEBAR );
+ }
+ if( bMoveRulerAction )
+ {
+ ScDocument * pDoc = pDocShell->GetDocument();
+ BOOL bUndo( pDoc->IsUndoEnabled() );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ ScStyleSaveData aOldData;
+ if( bUndo )
+ aOldData.InitFromStyle( pStyleSheet );
+
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ SvxULSpaceItem aULItem = ( const SvxULSpaceItem&)rStyleSet.Get( ATTR_ULSPACE );
+
+ if( bTopRulerMove && bTopRulerChange )
+ {
+ aULItem.SetUpperValue( (USHORT)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS ) );
+ rStyleSet.Put( aULItem );
+ }
+ else if( bBottomRulerMove && bBottomRulerChange )
+ {
+ aULItem.SetLowerValue( (USHORT)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS ) );
+ rStyleSet.Put( aULItem );
+ }
+ else if( bHeaderRulerMove && bHeaderRulerChange )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if ( rStyleSet.GetItemState( ATTR_PAGE_HEADERSET, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ SfxItemSet& pHeaderSet = ((SvxSetItem*)pItem)->GetItemSet();
+ Size aHeaderSize = ((const SvxSizeItem&)pHeaderSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ aHeaderSize.Height() = (long)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS - aULItem.GetUpper());
+ aHeaderSize.Height() = aHeaderSize.Height() * 100 / mnScale;
+ SvxSetItem aNewHeader( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_HEADERSET) );
+ aNewHeader.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aHeaderSize ) );
+ rStyleSet.Put( aNewHeader );
+ }
+ }
+ else if( bFooterRulerMove && bFooterRulerChange )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if( rStyleSet.GetItemState( ATTR_PAGE_FOOTERSET, FALSE, &pItem ) == SFX_ITEM_SET )
+ {
+ SfxItemSet& pFooterSet = ((SvxSetItem*)pItem)->GetItemSet();
+ Size aFooterSize = ((const SvxSizeItem&)pFooterSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ aFooterSize.Height() = (long)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS - aULItem.GetLower() );
+ aFooterSize.Height() = aFooterSize.Height() * 100 / mnScale;
+ SvxSetItem aNewFooter( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_FOOTERSET) );
+ aNewFooter.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aFooterSize ) );
+ rStyleSet.Put( aNewFooter );
+ }
+ }
+
+ ScStyleSaveData aNewData;
+ aNewData.InitFromStyle( pStyleSheet );
+ if( bUndo )
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
+ aOldData, aNewData ) );
+ }
+
+ if ( ValidTab( nTab ) )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, this, nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ Rectangle aRect(0,0,10000,10000);
+ Paint( aRect );
+ bTopRulerChange = FALSE;
+ bBottomRulerChange = FALSE;
+ bHeaderRulerChange = FALSE;
+ bFooterRulerChange = FALSE;
+ }
+ }
+ bTopRulerMove = FALSE;
+ bBottomRulerMove = FALSE;
+ bHeaderRulerMove = FALSE;
+ bFooterRulerMove = FALSE;
+ }
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
+ {
+ SetPointer(POINTER_ARROW);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ BOOL bMoveRulerAction = TRUE;
+ if( aButtonDownPt.X() == aButtonUpPt.X() )
+ {
+ bMoveRulerAction = FALSE;
+ if( nColNumberButttonDown == aPageArea.aStart.Col() )
+ DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+ else
+ DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+ DrawInvert( aButtonUpPt.X(), POINTER_HSPLIT );
+ }
+ if( bMoveRulerAction )
+ {
+ long nNewColWidth = 0;
+ ScDocFunc aFunc(*pDocShell);
+ SCCOLROW nCols[2] = { nColNumberButttonDown, nColNumberButttonDown };
+
+ if( !bLayoutRTL )
+ {
+ nNewColWidth = (long) ( PixelToLogic( Point( rMEvt.GetPosPixel().X() - nRight[ nColNumberButttonDown ], 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
+ nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
+ }
+ else
+ {
+
+ nNewColWidth = (long) ( PixelToLogic( Point( nRight[ nColNumberButttonDown ] - rMEvt.GetPosPixel().X(), 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
+ nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
+ }
+
+ if( nNewColWidth >= 0 )
+ {
+ aFunc.SetWidthOrHeight( TRUE, 1,nCols, nTab, SC_SIZE_DIRECT, (USHORT)nNewColWidth, TRUE, TRUE);
+ }
+ if ( ValidTab( nTab ) )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, this, nTab );
+ aPrintFunc.UpdatePages();
+ }
+ Rectangle nRect(0,0,10000,10000);
+ Paint( nRect );
+ }
+ bColRulerMove = FALSE;
+ }
+ ReleaseMouse();
+}
+
+void __EXPORT ScPreview::MouseMove( const MouseEvent& rMEvt )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+ Point aMouseMovePoint = PixelToLogic( rMEvt.GetPosPixel(), aMMMode );
+
+ long nLeftMargin = 0;
+ long nRightMargin = 0;
+ long nTopMargin = 0;
+ long nBottomMargin = 0;
+ Size PageSize;
+
+ long nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
+ long nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
+
+ if ( nPageNo < nTotalPages )
+ {
+ ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
+
+ ScPrintFunc* pPrintFunc;
+
+ if (bStateValid)
+ pPrintFunc = new ScPrintFunc( pDocShell, this, aState, &aOptions );
+ else
+ pPrintFunc = new ScPrintFunc( pDocShell, this, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
+
+ nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() );
+ nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS );
+ nRightMargin = (long)( nWidth * HMM_PER_TWIPS - nRightMargin - aOffset.X() );
+ nTopMargin = (long)( pPrintFunc->GetTopMargin() * HMM_PER_TWIPS - aOffset.Y() );
+ nBottomMargin = (long)( pPrintFunc->GetBottomMargin() * HMM_PER_TWIPS );
+ nBottomMargin = (long)( nHeight * HMM_PER_TWIPS - nBottomMargin - aOffset.Y() );
+ if( mnScale > 0 )
+ {
+ nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS * mnScale / 100 );
+ nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS * mnScale / 100 );
+ }
+ else
+ {
+ nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS );
+ nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS );
+ }
+ delete pPrintFunc;
+ }
+
+ Point aPixPt( rMEvt.GetPosPixel() );
+ Point aLeftTop = LogicToPixel( Point( nLeftMargin, -aOffset.Y() ) , aMMMode );
+ Point aLeftBottom = LogicToPixel( Point( nLeftMargin ,(long)(nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
+ Point aRightTop = LogicToPixel( Point( nRightMargin, -aOffset.Y() ), aMMMode );
+ Point aTopLeft = LogicToPixel( Point( -aOffset.X(), nTopMargin ), aMMMode );
+ Point aTopRight = LogicToPixel( Point( (long)(nWidth * HMM_PER_TWIPS - aOffset.X()), nTopMargin ), aMMMode );
+ Point aBottomLeft = LogicToPixel( Point( -aOffset.X(), nBottomMargin ), aMMMode );
+ Point aHeaderLeft = LogicToPixel( Point( -aOffset.X(), nHeaderHeight ), aMMMode );
+ Point aFooderLeft = LogicToPixel( Point( -aOffset.X(), nFooterHeight ), aMMMode );
+
+ BOOL bOnColRulerChange = FALSE;
+
+ for( SCCOL i=aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
+ {
+ Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
+ Point aColumnBottom = LogicToPixel( Point( 0, (long)( nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
+ if( aPixPt.X() < ( nRight[i] + 2 ) && ( aPixPt.X() > ( nRight[i] - 2 ) ) && ( aPixPt.X() < aRightTop.X() ) && ( aPixPt.X() > aLeftTop.X() )
+ && ( aPixPt.Y() > aColumnTop.Y() ) && ( aPixPt.Y() < aColumnBottom.Y() ) && !bLeftRulerMove && !bRightRulerMove
+ && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ bOnColRulerChange = TRUE;
+ if( !rMEvt.GetButtons() && GetPointer() == POINTER_HSPLIT )
+ nColNumberButttonDown = i;
+ break;
+ }
+ }
+
+ if( aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 ) && !bRightRulerMove )
+ {
+ bLeftRulerChange = TRUE;
+ bRightRulerChange = FALSE;
+ }
+ else if( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) && !bLeftRulerMove )
+ {
+ bLeftRulerChange = FALSE;
+ bRightRulerChange = TRUE;
+ }
+ else if( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ bTopRulerChange = TRUE;
+ bBottomRulerChange = FALSE;
+ bHeaderRulerChange = FALSE;
+ bFooterRulerChange = FALSE;
+ }
+ else if( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) && !bTopRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ bTopRulerChange = FALSE;
+ bBottomRulerChange = TRUE;
+ bHeaderRulerChange = FALSE;
+ bFooterRulerChange = FALSE;
+ }
+ else if( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bFooterRulerMove )
+ {
+ bTopRulerChange = FALSE;
+ bBottomRulerChange = FALSE;
+ bHeaderRulerChange = TRUE;
+ bFooterRulerChange = FALSE;
+ }
+ else if( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove )
+ {
+ bTopRulerChange = FALSE;
+ bBottomRulerChange = FALSE;
+ bHeaderRulerChange = FALSE;
+ bFooterRulerChange = TRUE;
+ }
+
+ if( bPageMargin )
+ {
+ if(( (aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 )) || bLeftRulerMove ||
+ ( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) ) || bRightRulerMove || bOnColRulerChange || bColRulerMove )
+ && aPixPt.Y() > aLeftTop.Y() && aPixPt.Y() < aLeftBottom.Y() )
+ {
+ if( bOnColRulerChange || bColRulerMove )
+ {
+ SetPointer( Pointer( POINTER_HSPLIT ) );
+ if( bColRulerMove )
+ {
+ if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
+ DragMove( aMouseMovePoint.X(), POINTER_HSPLIT );
+ }
+ }
+ else
+ {
+ if( bLeftRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ SetPointer( Pointer( POINTER_HSIZEBAR ) );
+ if( bLeftRulerMove )
+ {
+ if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
+ DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
+ }
+ }
+ else if( bRightRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ SetPointer( Pointer( POINTER_HSIZEBAR ) );
+ if( bRightRulerMove )
+ {
+ if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
+ DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
+ }
+ }
+ }
+ }
+ else
+ {
+ if( ( ( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) ) || bTopRulerMove ||
+ ( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) ) || bBottomRulerMove ||
+ ( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) ) || bHeaderRulerMove ||
+ ( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) ) || bFooterRulerMove )
+ && aPixPt.X() > aTopLeft.X() && aPixPt.X() < aTopRight.X() )
+ {
+ if( bTopRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bTopRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ else if( bBottomRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bBottomRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ else if( bHeaderRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bHeaderRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ else if( bFooterRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bFooterRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ }
+ else
+ SetPointer( Pointer( POINTER_ARROW ) );
+ }
+ }
+}
+//Issue51656 Add resizeable margin on page preview from maoyg
+void ScPreview::InvalidateLocationData(ULONG nId)
+{
+ bLocationValid = FALSE;
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility( SfxSimpleHint( nId ) );
+}
+
+void ScPreview::GetFocus()
+{
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility( ScAccWinFocusGotHint(GetAccessible()) );
+}
+
+void ScPreview::LoseFocus()
+{
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility( ScAccWinFocusLostHint(GetAccessible()) );
+}
+
+com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> ScPreview::CreateAccessible()
+{
+ ScAccessibleDocumentPagePreview* pAccessible =
+ new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell );
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xAccessible = pAccessible;
+ pAccessible->Init();
+ return xAccessible;
+}
+
+//Issue51656 Add resizeable margin on page preview from maoyg
+void ScPreview::DragMove( long nDragMovePos, USHORT nFlags )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+ SetMapMode( aMMMode );
+ long nPos = nDragMovePos;
+ if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
+ {
+ if( nDragMovePos != aButtonDownChangePoint.X() )
+ {
+ DrawInvert( aButtonDownChangePoint.X(), nFlags );
+ aButtonDownChangePoint.X() = nPos;
+ DrawInvert( aButtonDownChangePoint.X(), nFlags );
+ }
+ }
+ else if( nFlags == POINTER_VSIZEBAR )
+ {
+ if( nDragMovePos != aButtonDownChangePoint.Y() )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), nFlags );
+ aButtonDownChangePoint.Y() = nPos;
+ DrawInvert( aButtonDownChangePoint.Y(), nFlags );
+ }
+ }
+}
+
+void ScPreview::DrawInvert( long nDragPos, USHORT nFlags )
+{
+ long nHeight = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Height();
+ long nWidth = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Width();
+ if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
+ {
+ Rectangle aRect( nDragPos, -aOffset.Y(), nDragPos + 1,(long)( ( nHeight * HMM_PER_TWIPS ) - aOffset.Y()));
+ Invert( aRect,INVERT_50 );
+ }
+ else if( nFlags == POINTER_VSIZEBAR )
+ {
+ Rectangle aRect( -aOffset.X(), nDragPos,(long)( ( nWidth * HMM_PER_TWIPS ) - aOffset.X() ), nDragPos + 1 );
+ Invert( aRect,INVERT_50 );
+ }
+}
+//Issue51656 Add resizeable margin on page preview from maoyg
diff --git a/sc/source/ui/view/prevloc.cxx b/sc/source/ui/view/prevloc.cxx
new file mode 100644
index 000000000000..fd36a1b2c1d0
--- /dev/null
+++ b/sc/source/ui/view/prevloc.cxx
@@ -0,0 +1,792 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/outdev.hxx>
+#include <tools/debug.hxx>
+
+#include "prevloc.hxx"
+#include "document.hxx"
+
+//==================================================================
+
+enum ScPreviewLocationType
+{
+ SC_PLOC_CELLRANGE,
+ SC_PLOC_COLHEADER,
+ SC_PLOC_ROWHEADER,
+ SC_PLOC_LEFTHEADER,
+ SC_PLOC_RIGHTHEADER,
+ SC_PLOC_LEFTFOOTER,
+ SC_PLOC_RIGHTFOOTER,
+ SC_PLOC_NOTEMARK,
+ SC_PLOC_NOTETEXT
+};
+
+struct ScPreviewLocationEntry
+{
+ ScPreviewLocationType eType;
+ Rectangle aPixelRect;
+ ScRange aCellRange;
+ BOOL bRepeatCol;
+ BOOL bRepeatRow;
+
+ ScPreviewLocationEntry( ScPreviewLocationType eNewType, const Rectangle& rPixel, const ScRange& rRange,
+ BOOL bRepCol, BOOL bRepRow ) :
+ eType( eNewType ),
+ aPixelRect( rPixel ),
+ aCellRange( rRange ),
+ bRepeatCol( bRepCol ),
+ bRepeatRow( bRepRow )
+ {
+ }
+};
+
+//==================================================================
+
+ScPreviewTableInfo::ScPreviewTableInfo() :
+ nTab(0),
+ nCols(0),
+ nRows(0),
+ pColInfo(NULL),
+ pRowInfo(NULL)
+{
+}
+
+ScPreviewTableInfo::~ScPreviewTableInfo()
+{
+ delete[] pColInfo;
+ delete[] pRowInfo;
+}
+
+void ScPreviewTableInfo::SetTab( SCTAB nNewTab )
+{
+ nTab = nNewTab;
+}
+
+void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo )
+{
+ delete[] pColInfo;
+ pColInfo = pNewInfo;
+ nCols = nCount;
+}
+
+void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo )
+{
+ delete[] pRowInfo;
+ pRowInfo = pNewInfo;
+ nRows = nCount;
+}
+
+void ScPreviewTableInfo::LimitToArea( const Rectangle& rPixelArea )
+{
+ if ( pColInfo )
+ {
+ // cells completely left of the visible area
+ SCCOL nStart = 0;
+ while ( nStart < nCols && pColInfo[nStart].nPixelEnd < rPixelArea.Left() )
+ ++nStart;
+
+ // cells completely right of the visible area
+ SCCOL nEnd = nCols;
+ while ( nEnd > 0 && pColInfo[nEnd-1].nPixelStart > rPixelArea.Right() )
+ --nEnd;
+
+ if ( nStart > 0 || nEnd < nCols )
+ {
+ if ( nEnd > nStart )
+ {
+ SCCOL nNewCount = nEnd - nStart;
+ ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
+ for (SCCOL i=0; i<nNewCount; i++)
+ pNewInfo[i] = pColInfo[nStart + i];
+ SetColInfo( nNewCount, pNewInfo );
+ }
+ else
+ SetColInfo( 0, NULL ); // all invisible
+ }
+ }
+
+ if ( pRowInfo )
+ {
+ // cells completely above the visible area
+ SCROW nStart = 0;
+ while ( nStart < nRows && pRowInfo[nStart].nPixelEnd < rPixelArea.Top() )
+ ++nStart;
+
+ // cells completely below the visible area
+ SCROW nEnd = nRows;
+ while ( nEnd > 0 && pRowInfo[nEnd-1].nPixelStart > rPixelArea.Bottom() )
+ --nEnd;
+
+ if ( nStart > 0 || nEnd < nRows )
+ {
+ if ( nEnd > nStart )
+ {
+ SCROW nNewCount = nEnd - nStart;
+ ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
+ for (SCROW i=0; i<nNewCount; i++)
+ pNewInfo[i] = pRowInfo[nStart + i];
+ SetRowInfo( nNewCount, pNewInfo );
+ }
+ else
+ SetRowInfo( 0, NULL ); // all invisible
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) :
+ pWindow( pWin ),
+ pDoc( pDocument ),
+ nDrawRanges( 0 ),
+ nPrintTab( 0 )
+{
+}
+
+ScPreviewLocationData::~ScPreviewLocationData()
+{
+ Clear();
+}
+
+void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode )
+{
+ aCellMapMode = rMapMode;
+}
+
+void ScPreviewLocationData::SetPrintTab( SCTAB nNew )
+{
+ nPrintTab = nNew;
+}
+
+void ScPreviewLocationData::Clear()
+{
+ void* pEntry = aEntries.First();
+ while ( pEntry )
+ {
+ delete (ScPreviewLocationEntry*) pEntry;
+ pEntry = aEntries.Next();
+ }
+ aEntries.Clear();
+
+ nDrawRanges = 0;
+}
+
+void ScPreviewLocationData::AddCellRange( const Rectangle& rRect, const ScRange& rRange, BOOL bRepCol, BOOL bRepRow,
+ const MapMode& rDrawMap )
+{
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_CELLRANGE, aPixelRect, rRange, bRepCol, bRepRow ) );
+
+ DBG_ASSERT( nDrawRanges < SC_PREVIEW_MAXRANGES, "too many ranges" );
+ if ( nDrawRanges < SC_PREVIEW_MAXRANGES )
+ {
+ aDrawRectangle[nDrawRanges] = aPixelRect;
+ aDrawMapMode[nDrawRanges] = rDrawMap;
+ if (bRepCol)
+ if (bRepRow)
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_EDGE;
+ else
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPCOL;
+ else
+ if (bRepRow)
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPROW;
+ else
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_TAB;
+ ++nDrawRanges;
+ }
+}
+
+void ScPreviewLocationData::AddColHeaders( const Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, BOOL bRepCol )
+{
+ SCTAB nTab = 0; //! ?
+ ScRange aRange( nStartCol, 0, nTab, nEndCol, 0, nTab );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_COLHEADER, aPixelRect, aRange, bRepCol, FALSE ) );
+}
+
+void ScPreviewLocationData::AddRowHeaders( const Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, BOOL bRepRow )
+{
+ SCTAB nTab = 0; //! ?
+ ScRange aRange( 0, nStartRow, nTab, 0, nEndRow, nTab );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_ROWHEADER, aPixelRect, aRange, FALSE, bRepRow ) );
+}
+
+void ScPreviewLocationData::AddHeaderFooter( const Rectangle& rRect, BOOL bHeader, BOOL bLeft )
+{
+ ScRange aRange; //! ?
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+
+ ScPreviewLocationType eType = bHeader ?
+ ( bLeft ? SC_PLOC_LEFTHEADER : SC_PLOC_RIGHTHEADER ) :
+ ( bLeft ? SC_PLOC_LEFTFOOTER : SC_PLOC_RIGHTFOOTER );
+ aEntries.Insert( new ScPreviewLocationEntry( eType, aPixelRect, aRange, FALSE, FALSE ) );
+}
+
+void ScPreviewLocationData::AddNoteMark( const Rectangle& rRect, const ScAddress& rPos )
+{
+ ScRange aRange( rPos );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_NOTEMARK, aPixelRect, aRange, FALSE, FALSE ) );
+}
+
+void ScPreviewLocationData::AddNoteText( const Rectangle& rRect, const ScAddress& rPos )
+{
+ ScRange aRange( rPos );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_NOTETEXT, aPixelRect, aRange, FALSE, FALSE ) );
+}
+
+//------------------------------------------------------------------
+
+void ScPreviewLocationData::GetDrawRange( USHORT nPos, Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const
+{
+ DBG_ASSERT( nPos < nDrawRanges, "wrong position" );
+ if ( nPos < nDrawRanges )
+ {
+ rPixelRect = aDrawRectangle[nPos];
+ rMapMode = aDrawMapMode[nPos];
+ rRangeId = aDrawRangeId[nPos];
+ }
+}
+
+ScPreviewLocationEntry* lcl_GetEntryByAddress( const List& rEntries, const ScAddress& rPos, ScPreviewLocationType eType )
+{
+ ULONG nCount = rEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)rEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aCellRange.In( rPos ) )
+ return pEntry;
+ }
+ return NULL;
+}
+
+//UNUSED2008-05 ScAddress ScPreviewLocationData::GetCellFromRange( const Size& rOffsetPixel, const ScRange& rRange ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 const double nScaleX = HMM_PER_TWIPS;
+//UNUSED2008-05 const double nScaleY = HMM_PER_TWIPS;
+//UNUSED2008-05
+//UNUSED2008-05 Size aOffsetLogic = pWindow->PixelToLogic( rOffsetPixel, aCellMapMode );
+//UNUSED2008-05 SCTAB nTab = rRange.aStart.Tab();
+//UNUSED2008-05
+//UNUSED2008-05 long nPosX = 0;
+//UNUSED2008-05 SCCOL nCol = rRange.aStart.Col();
+//UNUSED2008-05 SCCOL nEndCol = rRange.aEnd.Col();
+//UNUSED2008-05 while ( nCol <= nEndCol && nPosX < aOffsetLogic.Width() )
+//UNUSED2008-05 {
+//UNUSED2008-05 USHORT nDocW = pDoc->GetColWidth( nCol, nTab );
+//UNUSED2008-05 if (nDocW)
+//UNUSED2008-05 nPosX += (long) (nDocW * nScaleX);
+//UNUSED2008-05 ++nCol;
+//UNUSED2008-05 }
+//UNUSED2008-05 if ( nCol > rRange.aStart.Col() )
+//UNUSED2008-05 --nCol;
+//UNUSED2008-05
+//UNUSED2008-05 long nPosY = 0;
+//UNUSED2008-05 ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter(
+//UNUSED2008-05 pDoc->GetRowFlagsArray( nTab), rRange.aStart.Row(),
+//UNUSED2008-05 rRange.aEnd.Row(), CR_HIDDEN, 0, pDoc->GetRowHeightArray( nTab));
+//UNUSED2008-05 while ( aIter && nPosY < aOffsetLogic.Height() )
+//UNUSED2008-05 {
+//UNUSED2008-05 USHORT nDocH = *aIter;
+//UNUSED2008-05 if (nDocH)
+//UNUSED2008-05 nPosY += (long) (nDocH * nScaleY);
+//UNUSED2008-05 ++aIter;
+//UNUSED2008-05 }
+//UNUSED2008-05 SCROW nRow = aIter.GetPos();
+//UNUSED2008-05 if ( nRow > rRange.aStart.Row() )
+//UNUSED2008-05 --nRow;
+//UNUSED2008-05
+//UNUSED2008-05 return ScAddress( nCol, nRow, nTab );
+//UNUSED2008-05 }
+
+Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const
+{
+ const double nScaleX = HMM_PER_TWIPS;
+ const double nScaleY = HMM_PER_TWIPS;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ long nPosX = 0;
+ SCCOL nEndCol = rCellPos.Col();
+ for (SCCOL nCol = rRange.aStart.Col(); nCol < nEndCol; nCol++)
+ {
+ USHORT nDocW = pDoc->GetColWidth( nCol, nTab );
+ if (nDocW)
+ nPosX += (long) (nDocW * nScaleX);
+ }
+ long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX );
+
+ SCROW nEndRow = rCellPos.Row();
+ long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(),
+ nEndRow, nTab, nScaleY);
+ long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY );
+
+ Size aOffsetLogic( nPosX, nPosY );
+ Size aSizeLogic( nSizeX, nSizeY );
+ Size aOffsetPixel = pWindow->LogicToPixel( aOffsetLogic, aCellMapMode );
+ Size aSizePixel = pWindow->LogicToPixel( aSizeLogic, aCellMapMode );
+
+ return Rectangle( Point( aOffsetPixel.Width(), aOffsetPixel.Height() ), aSizePixel );
+}
+
+BOOL ScPreviewLocationData::GetCellPosition( const ScAddress& rCellPos, Rectangle& rCellRect ) const
+{
+ ScPreviewLocationEntry* pEntry = lcl_GetEntryByAddress( aEntries, rCellPos, SC_PLOC_CELLRANGE );
+ if ( pEntry )
+ {
+ Rectangle aOffsetRect = GetOffsetPixel( rCellPos, pEntry->aCellRange );
+ rCellRect = Rectangle( aOffsetRect.Left() + pEntry->aPixelRect.Left(),
+ aOffsetRect.Top() + pEntry->aPixelRect.Top(),
+ aOffsetRect.Right() + pEntry->aPixelRect.Left(),
+ aOffsetRect.Bottom() + pEntry->aPixelRect.Top() );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ScPreviewLocationData::HasCellsInRange( const Rectangle& rVisiblePixel ) const
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ ScPreviewLocationType eType = pEntry->eType;
+ if ( eType == SC_PLOC_CELLRANGE || eType == SC_PLOC_COLHEADER || eType == SC_PLOC_ROWHEADER )
+ if ( pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ScPreviewLocationData::GetHeaderPosition( Rectangle& rRect ) const
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTHEADER || pEntry->eType == SC_PLOC_RIGHTHEADER )
+ {
+ rRect = pEntry->aPixelRect;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL ScPreviewLocationData::GetFooterPosition( Rectangle& rRect ) const
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTFOOTER || pEntry->eType == SC_PLOC_RIGHTFOOTER )
+ {
+ rRect = pEntry->aPixelRect;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL ScPreviewLocationData::IsHeaderLeft() const
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTHEADER )
+ return TRUE;
+ if ( pEntry->eType == SC_PLOC_RIGHTHEADER )
+ return FALSE;
+ }
+ return FALSE;
+}
+
+BOOL ScPreviewLocationData::IsFooterLeft() const
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTFOOTER )
+ return TRUE;
+ if ( pEntry->eType == SC_PLOC_RIGHTFOOTER )
+ return FALSE;
+ }
+ return FALSE;
+}
+
+long ScPreviewLocationData::GetNoteCountInRange( const Rectangle& rVisiblePixel, BOOL bNoteMarks ) const
+{
+ ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
+
+ ULONG nRet = 0;
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ ++nRet;
+ }
+ return nRet;
+}
+
+BOOL ScPreviewLocationData::GetNoteInRange( const Rectangle& rVisiblePixel, long nIndex, BOOL bNoteMarks,
+ ScAddress& rCellPos, Rectangle& rNoteRect ) const
+{
+ ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
+
+ ULONG nPos = 0;
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ {
+ if ( nPos == sal::static_int_cast<ULONG>(nIndex) )
+ {
+ rCellPos = pEntry->aCellRange.aStart;
+ rNoteRect = pEntry->aPixelRect;
+ return TRUE;
+ }
+ ++nPos;
+ }
+ }
+ return FALSE;
+}
+
+Rectangle ScPreviewLocationData::GetNoteInRangeOutputRect(const Rectangle& rVisiblePixel, BOOL bNoteMarks, const ScAddress& aCellPos) const
+{
+ ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
+
+ ULONG nPos = 0;
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ {
+ if ( aCellPos == pEntry->aCellRange.aStart )
+ return pEntry->aPixelRect;
+ ++nPos;
+ }
+ }
+ return Rectangle();
+}
+
+void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const
+{
+ const double nScaleX = HMM_PER_TWIPS;
+ const double nScaleY = HMM_PER_TWIPS;
+
+ // from left to right:
+ BOOL bHasHeaderCol = FALSE;
+ BOOL bHasRepCols = FALSE;
+ BOOL bHasMainCols = FALSE;
+ SCCOL nRepeatColStart = 0;
+ SCCOL nRepeatColEnd = 0;
+ SCCOL nMainColStart = 0;
+ SCCOL nMainColEnd = 0;
+
+ // from top to bottom:
+ BOOL bHasHeaderRow = FALSE;
+ BOOL bHasRepRows = FALSE;
+ BOOL bHasMainRows = FALSE;
+ SCROW nRepeatRowStart = 0;
+ SCROW nRepeatRowEnd = 0;
+ SCROW nMainRowStart = 0;
+ SCROW nMainRowEnd = 0;
+
+ Rectangle aHeaderRect, aRepeatRect, aMainRect;
+ SCTAB nTab = 0;
+
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_CELLRANGE )
+ {
+ if ( pEntry->bRepeatCol )
+ {
+ bHasRepCols = TRUE;
+ nRepeatColStart = pEntry->aCellRange.aStart.Col();
+ nRepeatColEnd = pEntry->aCellRange.aEnd.Col();
+ aRepeatRect.Left() = pEntry->aPixelRect.Left();
+ aRepeatRect.Right() = pEntry->aPixelRect.Right();
+ }
+ else
+ {
+ bHasMainCols = TRUE;
+ nMainColStart = pEntry->aCellRange.aStart.Col();
+ nMainColEnd = pEntry->aCellRange.aEnd.Col();
+ aMainRect.Left() = pEntry->aPixelRect.Left();
+ aMainRect.Right() = pEntry->aPixelRect.Right();
+ }
+ if ( pEntry->bRepeatRow )
+ {
+ bHasRepRows = TRUE;
+ nRepeatRowStart = pEntry->aCellRange.aStart.Row();
+ nRepeatRowEnd = pEntry->aCellRange.aEnd.Row();
+ aRepeatRect.Top() = pEntry->aPixelRect.Top();
+ aRepeatRect.Bottom() = pEntry->aPixelRect.Bottom();
+ }
+ else
+ {
+ bHasMainRows = TRUE;
+ nMainRowStart = pEntry->aCellRange.aStart.Row();
+ nMainRowEnd = pEntry->aCellRange.aEnd.Row();
+ aMainRect.Top() = pEntry->aPixelRect.Top();
+ aMainRect.Bottom() = pEntry->aPixelRect.Bottom();
+ }
+ nTab = pEntry->aCellRange.aStart.Tab(); //! store separately?
+ }
+ else if ( pEntry->eType == SC_PLOC_ROWHEADER )
+ {
+ // row headers result in an additional column
+ bHasHeaderCol = TRUE;
+ aHeaderRect.Left() = pEntry->aPixelRect.Left();
+ aHeaderRect.Right() = pEntry->aPixelRect.Right();
+ }
+ else if ( pEntry->eType == SC_PLOC_COLHEADER )
+ {
+ // column headers result in an additional row
+ bHasHeaderRow = TRUE;
+ aHeaderRect.Top() = pEntry->aPixelRect.Top();
+ aHeaderRect.Bottom() = pEntry->aPixelRect.Bottom();
+ }
+ }
+
+ //
+ // get column info
+ //
+
+ SCCOL nColCount = 0;
+ SCCOL nCol;
+ if ( bHasHeaderCol )
+ ++nColCount;
+ if ( bHasRepCols )
+ for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ ++nColCount;
+ if ( bHasMainCols )
+ for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ ++nColCount;
+
+ if ( nColCount > 0 )
+ {
+ ScPreviewColRowInfo* pColInfo = new ScPreviewColRowInfo[ nColCount ];
+ SCCOL nColPos = 0;
+
+ if ( bHasHeaderCol )
+ {
+ pColInfo[nColPos].Set( TRUE, 0, aHeaderRect.Left(), aHeaderRect.Right() );
+ ++nColPos;
+ }
+ if ( bHasRepCols )
+ {
+ long nPosX = 0;
+ for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ {
+ USHORT nDocW = pDoc->GetColWidth( nCol, nTab );
+ long nNextX = nPosX + (long) (nDocW * nScaleX);
+
+ long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
+ long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
+ pColInfo[nColPos].Set( FALSE, nCol,
+ aRepeatRect.Left() + nPixelStart,
+ aRepeatRect.Left() + nPixelEnd );
+
+ nPosX = nNextX;
+ ++nColPos;
+ }
+ }
+ if ( bHasMainCols )
+ {
+ long nPosX = 0;
+ for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ {
+ USHORT nDocW = pDoc->GetColWidth( nCol, nTab );
+ long nNextX = nPosX + (long) (nDocW * nScaleX);
+
+ long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
+ long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
+ pColInfo[nColPos].Set( FALSE, nCol,
+ aMainRect.Left() + nPixelStart,
+ aMainRect.Left() + nPixelEnd );
+
+ nPosX = nNextX;
+ ++nColPos;
+ }
+ }
+ rInfo.SetColInfo( nColCount, pColInfo );
+ }
+ else
+ rInfo.SetColInfo( 0, NULL );
+
+ //
+ // get row info
+ //
+
+ SCROW nRowCount = 0;
+ if ( bHasHeaderRow )
+ ++nRowCount;
+ if ( bHasRepRows )
+ nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab);
+ if ( bHasMainRows )
+ nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab);
+
+ if ( nRowCount > 0 )
+ {
+ ScPreviewColRowInfo* pRowInfo = new ScPreviewColRowInfo[ nRowCount ];
+ SCROW nRowPos = 0;
+
+ if ( bHasHeaderRow )
+ {
+ pRowInfo[nRowPos].Set( TRUE, 0, aHeaderRect.Top(), aHeaderRect.Bottom() );
+ ++nRowPos;
+ }
+ if ( bHasRepRows )
+ {
+ long nPosY = 0;
+ for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow)
+ {
+ if (pDoc->RowHidden(nRow, nTab))
+ continue;
+
+ USHORT nDocH = pDoc->GetOriginalHeight( nRow, nTab );
+ long nNextY = nPosY + (long) (nDocH * nScaleY);
+
+ long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
+ long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
+ pRowInfo[nRowPos].Set( FALSE, nRow,
+ aRepeatRect.Top() + nPixelStart,
+ aRepeatRect.Top() + nPixelEnd );
+
+ nPosY = nNextY;
+ ++nRowPos;
+ }
+ }
+ if ( bHasMainRows )
+ {
+ long nPosY = 0;
+ for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow)
+ {
+ if (pDoc->RowHidden(nRow, nTab))
+ continue;
+
+ USHORT nDocH = pDoc->GetOriginalHeight( nRow, nTab );
+ long nNextY = nPosY + (long) (nDocH * nScaleY);
+
+ long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
+ long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
+ pRowInfo[nRowPos].Set( FALSE, nRow,
+ aMainRect.Top() + nPixelStart,
+ aMainRect.Top() + nPixelEnd );
+
+ nPosY = nNextY;
+ ++nRowPos;
+ }
+ }
+ rInfo.SetRowInfo( nRowCount, pRowInfo );
+ }
+ else
+ rInfo.SetRowInfo( 0, NULL );
+
+ //
+ // limit to visible area
+ //
+
+ rInfo.SetTab( nTab );
+ rInfo.LimitToArea( rVisiblePixel );
+}
+
+Rectangle ScPreviewLocationData::GetHeaderCellOutputRect(const Rectangle& rVisRect, const ScAddress& rCellPos, sal_Bool bColHeader) const
+{
+ // first a stupid implementation
+ // NN says here should be done more
+ Rectangle aClipRect;
+ ScPreviewTableInfo aTableInfo;
+ GetTableInfo( rVisRect, aTableInfo );
+
+ if ( (rCellPos.Col() >= 0) &&
+ (rCellPos.Row() >= 0) && (rCellPos.Col() < aTableInfo.GetCols()) &&
+ (rCellPos.Row() < aTableInfo.GetRows()) )
+ {
+ SCCOL nCol(0);
+ SCROW nRow(0);
+ if (bColHeader)
+ nCol = rCellPos.Col();
+ else
+ nRow = rCellPos.Row();
+ const ScPreviewColRowInfo& rColInfo = aTableInfo.GetColInfo()[nCol];
+ const ScPreviewColRowInfo& rRowInfo = aTableInfo.GetRowInfo()[nRow];
+
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ aClipRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
+ }
+ return aClipRect;
+}
+
+Rectangle ScPreviewLocationData::GetCellOutputRect(const ScAddress& rCellPos) const
+{
+ // first a stupid implementation
+ // NN says here should be done more
+ Rectangle aRect;
+ GetCellPosition(rCellPos, aRect);
+ return aRect;
+}
+
+// GetMainCellRange is used for links in PDF export
+
+BOOL ScPreviewLocationData::GetMainCellRange( ScRange& rRange, Rectangle& rPixRect ) const
+{
+ ULONG nCount = aEntries.Count();
+ for (ULONG nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_CELLRANGE && !pEntry->bRepeatCol && !pEntry->bRepeatRow )
+ {
+ rRange = pEntry->aCellRange;
+ rPixRect = pEntry->aPixelRect;
+ return TRUE;
+ }
+ }
+ return FALSE; // not found
+}
+
diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx
new file mode 100644
index 000000000000..48ffd4fd39a4
--- /dev/null
+++ b/sc/source/ui/view/prevwsh.cxx
@@ -0,0 +1,1241 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <svx/svdview.hxx>
+//CHINA001 #include <svx/zoom.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svtools/printdlg.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/help.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+
+#ifndef _SVX_ZOOMSLIDERITEM_HXX
+#include <svx/zoomslideritem.hxx>
+#endif
+#include "prevwsh.hxx"
+#include "preview.hxx"
+#include "printfun.hxx"
+#include "attrib.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "stlpool.hxx"
+#include "editutil.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "ViewSettingsSequenceDefines.hxx"
+#include "tpprint.hxx"
+#include "printopt.hxx"
+#include <xmloff/xmluconv.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+
+#ifndef _SVX_ZOOM_HXX
+#include <svx/zoom_def.hxx>
+#endif
+
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+// fuer Rad-Maus
+#define SC_DELTA_ZOOM 10
+#define MINZOOM_SLIDER 10
+#define MAXZOOM_SLIDER 400
+
+#define SC_USERDATA_SEP ';'
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define ScPreviewShell
+#include "scslots.hxx"
+
+TYPEINIT1( ScPreviewShell, SfxViewShell );
+
+SFX_IMPL_INTERFACE( ScPreviewShell, SfxViewShell, ScResId(SCSTR_PREVIEWSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION(SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|
+ SFX_VISIBILITY_SERVER|SFX_VISIBILITY_READONLYDOC,
+ ScResId(RID_OBJECTBAR_PREVIEW));
+ SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_PREVIEW));
+}
+
+SFX_IMPL_NAMED_VIEWFACTORY( ScPreviewShell, "PrintPreview" )
+{
+ SFX_VIEW_REGISTRATION(ScDocShell);
+}
+
+//------------------------------------------------------------------
+
+void ScPreviewShell::Construct( Window* pParent )
+{
+ eZoom = SVX_ZOOM_WHOLEPAGE;
+
+ pCorner = new ScrollBarBox( pParent, WB_SIZEABLE );
+
+ pHorScroll = new ScrollBar(pParent, WB_HSCROLL );
+ pVerScroll = new ScrollBar(pParent, WB_VSCROLL);
+
+ // SSA: --- RTL --- no mirroring for horizontal scrollbars
+ pHorScroll->EnableRTL( FALSE );
+
+ pHorScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
+ pVerScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
+
+ pPreview = new ScPreview( pParent, pDocShell, this );
+
+ SetPool( &SC_MOD()->GetPool() );
+ SetWindow( pPreview );
+ StartListening(*pDocShell,TRUE);
+ StartListening(*SFX_APP(),TRUE); // #i62045# #i62046# application is needed for Calc's own hints
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+
+// pPreview->Show(); // wird vom Sfx angezeigt
+ pHorScroll->Show();
+ pVerScroll->Show();
+ pCorner->Show();
+ SetHelpId( HID_SCSHELL_PREVWSH );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Preview")));
+}
+
+ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh ) :
+ SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ),
+ pDocShell( (ScDocShell*)pViewFrame->GetObjectShell() ),
+ nSourceDesignMode( SC_FORCEMODE_NONE ),
+ pAccessibilityBroadcaster( NULL )
+{
+ Construct( &pViewFrame->GetWindow() );
+
+ if ( pOldSh && pOldSh->ISA( ScTabViewShell ) )
+ {
+ // store view settings, show table from TabView
+ //! store live ScViewData instead, and update on ScTablesHint?
+ //! or completely forget aSourceData on ScTablesHint?
+
+ ScTabViewShell* pTabViewShell = ((ScTabViewShell*)pOldSh);
+ ScViewData* pData = pTabViewShell->GetViewData();
+ pData->WriteUserDataSequence( aSourceData );
+ InitStartTable( pData->GetTabNo() );
+
+ // #106334# also have to store the TabView's DesignMode state
+ // (only if draw view exists)
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+ if ( pDrawView )
+ nSourceDesignMode = pDrawView->IsDesignMode();
+ }
+}
+
+__EXPORT ScPreviewShell::~ScPreviewShell()
+{
+ // #108333#; notify Accessibility that Shell is dying and before destroy all
+ BroadcastAccessibility( SfxSimpleHint( SFX_HINT_DYING ) );
+ DELETEZ(pAccessibilityBroadcaster);
+
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ EndListening(*SFX_APP());
+ EndListening(*pDocShell);
+
+ SetWindow(0);
+ delete pPreview;
+ delete pHorScroll;
+ delete pVerScroll;
+ delete pCorner;
+
+ // #97612# normal mode of operation is switching back to default view in the same frame,
+ // so there's no need to activate any other window here anymore
+}
+
+void ScPreviewShell::InitStartTable(SCTAB nTab)
+{
+ pPreview->SetPageNo( pPreview->GetFirstPage(nTab) );
+}
+
+//------------------------------------------------------------------
+
+String __EXPORT ScPreviewShell::GetDescription() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" ** Test ** "));
+}
+
+Size __EXPORT ScPreviewShell::GetOptimalSizePixel() const
+{
+ Size aOptSize(100,100);
+
+ ScTabViewShell* pViewSh = pDocShell->GetBestViewShell();
+
+ if ( pViewSh )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ SCTAB nCurTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ pDoc->GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
+
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ const SvxSizeItem& rItem = (const SvxSizeItem&)rSet.Get( ATTR_PAGE_SIZE );
+ const Size& rPageSize = rItem.GetSize();
+
+ aOptSize.Width() = (long) (rPageSize.Width() * pViewData->GetPPTX());
+ aOptSize.Height() = (long) (rPageSize.Height() * pViewData->GetPPTY());
+ }
+ }
+ else
+ {
+ DBG_ERROR( "TabViewShell not found :-/" );
+ }
+
+ return aOptSize;
+}
+
+void __EXPORT ScPreviewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
+{
+ long nBarW = GetViewFrame()->GetWindow().GetSettings().GetStyleSettings().GetScrollBarSize();
+ long nBarH = nBarW;
+// long nBarW = pVerScroll->GetSizePixel().Width();
+// long nBarH = pHorScroll->GetSizePixel().Height();
+
+ Size aOutSize( rSize.Width()-nBarW, rSize.Height()-nBarH );
+ pPreview->SetPosSizePixel( rPos, aOutSize );
+ pHorScroll->SetPosSizePixel( Point( rPos.X(), rPos.Y() + aOutSize.Height() ),
+ Size( aOutSize.Width(), nBarH ) );
+ pVerScroll->SetPosSizePixel( Point( rPos.X() + aOutSize.Width(), rPos.Y() ),
+ Size( nBarW, aOutSize.Height() ) );
+ pCorner->SetPosSizePixel( Point( rPos.X() + aOutSize.Width(), rPos.Y() + aOutSize.Height() ),
+ Size( nBarW, nBarH ) );
+
+ if ( SVX_ZOOM_WHOLEPAGE == eZoom )
+ pPreview->SetZoom( pPreview->GetOptimalZoom(FALSE) );
+ else if ( SVX_ZOOM_PAGEWIDTH == eZoom )
+ pPreview->SetZoom( pPreview->GetOptimalZoom(TRUE) );
+
+ UpdateScrollBars();
+}
+
+void __EXPORT ScPreviewShell::InnerResizePixel( const Point &rOfs, const Size &rSize )
+{
+ AdjustPosSizePixel( rOfs,rSize );
+}
+
+void __EXPORT ScPreviewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
+{
+ AdjustPosSizePixel( rOfs,rSize );
+}
+
+void ScPreviewShell::UpdateScrollBars()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = pPreview->GetTab();
+
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ),
+ SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT(pStyleSheet,"StyleSheet nicht gefunden");
+ if (!pStyleSheet) return;
+ const SfxItemSet* pParamSet = &pStyleSheet->GetItemSet();
+
+ Size aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
+ aPageSize.Width() = (long) (aPageSize.Width() * HMM_PER_TWIPS );
+ aPageSize.Height() = (long) (aPageSize.Height() * HMM_PER_TWIPS );
+
+ // for centering, page size without the shadow is used
+
+ Size aWindowSize = pPreview->GetOutputSize();
+
+ Point aOfs = pPreview->GetOffset();
+ long nMaxPos;
+
+ if( pHorScroll )
+ {
+ pHorScroll->SetRange( Range( 0, aPageSize.Width() ) );
+ pHorScroll->SetLineSize( aWindowSize.Width() / 16 );
+ pHorScroll->SetPageSize( aWindowSize.Width() );
+ pHorScroll->SetVisibleSize( aWindowSize.Width() );
+ nMaxPos = aPageSize.Width() - aWindowSize.Width();
+ if ( nMaxPos<0 )
+ {
+ // page smaller than window -> center (but put scrollbar to 0)
+ aOfs.X() = 0;
+ pPreview->SetXOffset( nMaxPos / 2 );
+ }
+ else if (aOfs.X() < 0)
+ {
+ // page larger than window -> never use negative offset
+ aOfs.X() = 0;
+ pPreview->SetXOffset( 0 );
+ }
+ else if (aOfs.X() > nMaxPos)
+ {
+ // limit offset to align with right edge of window
+ aOfs.X() = nMaxPos;
+ pPreview->SetXOffset(nMaxPos);
+ }
+ pHorScroll->SetThumbPos( aOfs.X() );
+ }
+
+ if( pVerScroll )
+ {
+ long nPageNo = pPreview->GetPageNo();
+ long nTotalPages = pPreview->GetTotalPages();
+
+ nMaxVertPos = aPageSize.Height() - aWindowSize.Height();
+ pVerScroll->SetLineSize( aWindowSize.Height() / 16 );
+ pVerScroll->SetPageSize( aWindowSize.Height() );
+ pVerScroll->SetVisibleSize( aWindowSize.Height() );
+ if ( nMaxVertPos < 0 )
+ {
+ // page smaller than window -> center (but put scrollbar to 0)
+ aOfs.Y() = 0;
+ pPreview->SetYOffset( nMaxVertPos / 2 );
+ pVerScroll->SetThumbPos( nPageNo * aWindowSize.Height() );
+ pVerScroll->SetRange( Range( 0, aWindowSize.Height() * nTotalPages ));
+ }
+ else if (aOfs.Y() < 0)
+ {
+ // page larger than window -> never use negative offset
+ pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
+ aOfs.Y() = 0;
+ pPreview->SetYOffset( 0 );
+ pVerScroll->SetThumbPos( aOfs.Y() );
+ }
+ else if (aOfs.Y() > nMaxVertPos )
+ {
+ // limit offset to align with window bottom
+ pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
+ aOfs.Y() = nMaxVertPos;
+ pPreview->SetYOffset( nMaxVertPos );
+ pVerScroll->SetThumbPos( aOfs.Y() );
+ }
+ }
+}
+
+IMPL_LINK (ScPreviewShell,ScrollHandler, ScrollBar* ,pScroll )
+{
+ long nPos = pScroll->GetThumbPos();
+ long nDelta = pScroll->GetDelta();
+ long nMaxRange = pScroll->GetRangeMax();
+ long nTotalPages = pPreview->GetTotalPages();
+ long nPageNo = 0;
+ long nPerPageLength = 0;
+ BOOL bIsDivide = TRUE;
+
+ if( nTotalPages )
+ nPerPageLength = nMaxRange / nTotalPages;
+
+ if( nPerPageLength )
+ {
+ nPageNo = nPos / nPerPageLength;
+ if( nPos % nPerPageLength )
+ {
+ bIsDivide = FALSE;
+ nPageNo ++;
+ }
+ }
+
+ BOOL bHoriz = ( pScroll == pHorScroll );
+
+ if( bHoriz )
+ pPreview->SetXOffset( nPos );
+ else
+ {
+ if( nMaxVertPos > 0 )
+ pPreview->SetYOffset( nPos );
+ else
+ {
+ Point aMousePos = pScroll->OutputToNormalizedScreenPixel( pScroll->GetPointerPosPixel() );
+ Point aPos = pScroll->GetParent()->OutputToNormalizedScreenPixel( pScroll->GetPosPixel() );
+ String aHelpStr;
+ Rectangle aRect;
+ USHORT nAlign;
+
+ if( nDelta < 0 )
+ {
+ if ( nTotalPages && nPageNo > 0 && !bIsDivide )
+ pPreview->SetPageNo( nPageNo-1 );
+ if( bIsDivide )
+ pPreview->SetPageNo( nPageNo );
+
+ aHelpStr = ScGlobal::GetRscString( STR_PAGE );
+ aHelpStr += ' ';
+ aHelpStr += String::CreateFromInt32( nPageNo );
+
+ aHelpStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aHelpStr += String::CreateFromInt32( nTotalPages );
+ }
+ else if( nDelta > 0 )
+ {
+ BOOL bAllTested = pPreview->AllTested();
+ if ( nTotalPages && ( nPageNo < nTotalPages || !bAllTested ) )
+ pPreview->SetPageNo( nPageNo );
+
+ aHelpStr = ScGlobal::GetRscString( STR_PAGE );
+ aHelpStr += ' ';
+ aHelpStr += String::CreateFromInt32( nPageNo+1 );
+
+ aHelpStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aHelpStr += String::CreateFromInt32( nTotalPages );
+ }
+
+ aRect.Left() = aPos.X() - 8;
+ aRect.Top() = aMousePos.Y();
+ aRect.Right() = aRect.Left();
+ aRect.Top() = aRect.Top();
+ nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
+ Help::ShowQuickHelp( pScroll->GetParent(), aRect, aHelpStr, nAlign );
+ }
+ }
+
+ return 0;
+}
+
+BOOL ScPreviewShell::ScrollCommand( const CommandEvent& rCEvt )
+{
+ BOOL bDone = FALSE;
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
+ {
+ long nOld = pPreview->GetZoom();
+ long nNew = nOld;
+ if ( pData->GetDelta() < 0 )
+ nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
+ else
+ nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );
+
+ if ( nNew != nOld )
+ {
+ eZoom = SVX_ZOOM_PERCENT;
+ pPreview->SetZoom( (USHORT)nNew );
+ }
+
+ bDone = TRUE;
+ }
+ else
+ {
+ bDone = pPreview->HandleScrollCommand( rCEvt, pHorScroll, pVerScroll );
+ }
+
+ return bDone;
+}
+
+SfxPrinter* __EXPORT ScPreviewShell::GetPrinter( BOOL bCreate )
+{
+ return pDocShell->GetPrinter(bCreate);
+}
+
+USHORT __EXPORT ScPreviewShell::SetPrinter( SfxPrinter *pNewPrinter, USHORT nDiffFlags, bool )
+{
+ return pDocShell->SetPrinter( pNewPrinter, nDiffFlags );
+}
+
+PrintDialog* __EXPORT ScPreviewShell::CreatePrintDialog( Window* pParent )
+{
+ pDocShell->GetDocument()->SetPrintOptions(); // Optionen aus OFA am Printer setzen
+ (void)GetPrinter();
+
+ const long nCurPage = pPreview->GetPageNo()+1;
+ const long nDocPageMax = pPreview->GetTotalPages();
+ PrintDialog* pDlg = new PrintDialog( pParent, true );
+// wenn zu langsam wieder einbauen
+// if ( pPreview->AllTested() )
+// nPageMax = pPreview->GetTotalPages();
+
+ pDlg->EnableSheetRange( true, PRINTSHEETS_ALL );
+ pDlg->EnableSheetRange( true, PRINTSHEETS_SELECTED_SHEETS );
+ pDlg->EnableSheetRange( false, PRINTSHEETS_SELECTED_CELLS );
+ bool bAllTabs = SC_MOD()->GetPrintOptions().GetAllSheets();
+ pDlg->CheckSheetRange( bAllTabs ? PRINTSHEETS_ALL : PRINTSHEETS_SELECTED_SHEETS );
+
+ if ( nDocPageMax > 0 )
+ pDlg->SetRangeText( String::CreateFromInt32( nCurPage ) );
+
+ pDlg->EnableRange ( PRINTDIALOG_ALL );
+ pDlg->EnableRange ( PRINTDIALOG_RANGE );
+ pDlg->SetFirstPage ( 1 );
+ pDlg->SetMinPage ( 1 );
+ pDlg->SetLastPage ( (USHORT)nDocPageMax );
+ pDlg->SetMaxPage ( (USHORT)nDocPageMax );
+ pDlg->EnableCollate ();
+
+ // Selektion hier nicht
+
+ return pDlg;
+}
+
+SfxTabPage* ScPreviewShell::CreatePrintOptionsPage( Window *pParent, const SfxItemSet &rOptions )
+{
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ //CHINA001 return ScTpPrintOptions::Create( pParent, rOptions );
+ ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT );
+ if ( ScTpPrintOptionsCreate )
+ return (*ScTpPrintOptionsCreate)( pParent, rOptions);
+ return 0;
+}
+
+void __EXPORT ScPreviewShell::PreparePrint( PrintDialog* pPrintDialog )
+{
+ SfxViewShell::PreparePrint( pPrintDialog );
+
+ ScMarkData aMarkData;
+ aMarkData.SelectTable( static_cast< SCTAB >( pPreview->GetTab() ), TRUE );
+ pDocShell->PreparePrint( pPrintDialog, &aMarkData );
+}
+
+ErrCode ScPreviewShell::DoPrint( SfxPrinter *pPrinter,
+ PrintDialog *pPrintDialog, BOOL bSilent, BOOL bIsAPI )
+{
+ ErrCode nRet = ERRCODE_IO_ABORT;
+
+ ScMarkData aMarkData;
+ aMarkData.SelectTable( static_cast< SCTAB >( pPreview->GetTab() ), TRUE );
+
+ if ( pDocShell->CheckPrint( pPrintDialog, &aMarkData, false, bIsAPI ) )
+ {
+ // SfxViewShell::DoPrint calls Print (after StartJob etc.)
+ nRet = SfxViewShell::DoPrint( pPrinter, pPrintDialog, bSilent, bIsAPI );
+ }
+
+ return nRet;
+}
+
+USHORT __EXPORT ScPreviewShell::Print( SfxProgress& rProgress, BOOL bIsAPI, PrintDialog* pPrintDialog )
+{
+ pDocShell->GetDocument()->SetPrintOptions(); // Optionen aus OFA am Printer setzen
+
+ // get the list of affected sheets before SfxViewShell::Print
+ bool bAllTabs = ( pPrintDialog ? ( pPrintDialog->GetCheckedSheetRange() == PRINTSHEETS_ALL ) : SC_MOD()->GetPrintOptions().GetAllSheets() );
+
+ ScMarkData aMarkData;
+ aMarkData.SelectTable( static_cast< SCTAB >( pPreview->GetTab() ), TRUE );
+
+ uno::Sequence< sal_Int32 > aSheets;
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ sal_Int32 nPrinted = 0;
+ for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ if ( bAllTabs || aMarkData.GetTableSelect( nTab ) )
+ {
+ aSheets.realloc( nPrinted + 1 );
+ aSheets[nPrinted] = nTab;
+ ++nPrinted;
+ }
+ }
+
+ uno::Sequence < beans::PropertyValue > aProps(1);
+ aProps[0].Name = ::rtl::OUString::createFromAscii( "PrintSheets" );
+ aProps[0].Value <<= aSheets;
+ SetAdditionalPrintOptions( aProps );
+
+ SfxViewShell::Print( rProgress, bIsAPI, pPrintDialog );
+ pDocShell->Print( rProgress, pPrintDialog, &aMarkData, pPreview, FALSE, bIsAPI );
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScPreviewShell::Activate(BOOL bMDI)
+{
+ SfxViewShell::Activate(bMDI);
+
+ //! Basic etc. -> auslagern in eigene Datei (s. tabvwsh4)
+
+ if (bMDI)
+ {
+ // InputHdl ist jetzt meistens Null, keine Assertion mehr!
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ pInputHdl->NotifyChange( NULL );
+ }
+}
+
+void __EXPORT ScPreviewShell::Deactivate(BOOL bMDI)
+{
+ SfxViewShell::Deactivate(bMDI);
+
+ if (bMDI)
+ {
+ }
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScPreviewShell::Execute( SfxRequest& rReq )
+{
+ USHORT nSlot = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ switch ( nSlot )
+ {
+ case SID_FORMATPAGE:
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ pDocShell->ExecutePageStyle( *this, rReq, pPreview->GetTab() );
+ break;
+ case SID_REPAINT:
+ pPreview->Invalidate();
+ rReq.Done();
+ break;
+ case SID_PREV_TABLE: // Accelerator
+ case SID_PREVIEW_PREVIOUS:
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage > 0)
+ pPreview->SetPageNo( nPage-1 );
+ }
+ break;
+ case SID_NEXT_TABLE: // Accelerator
+ case SID_PREVIEW_NEXT:
+ {
+ BOOL bAllTested = pPreview->AllTested();
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && (nPage+1 < nTotal || !bAllTested))
+ pPreview->SetPageNo( nPage+1 );
+ }
+ break;
+ case SID_CURSORTOPOFFILE: // Accelerator
+ case SID_PREVIEW_FIRST:
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage != 0)
+ pPreview->SetPageNo( 0 );
+ }
+ break;
+ case SID_CURSORENDOFFILE: // Accelerator
+ case SID_PREVIEW_LAST:
+ {
+ if (!pPreview->AllTested())
+ pPreview->CalcAll();
+
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage+1 != nTotal)
+ pPreview->SetPageNo( nTotal-1 );
+ }
+ break;
+ case SID_ATTR_ZOOM:
+ case FID_SCALE:
+ {
+ USHORT nZoom = 100;
+ BOOL bCancel = FALSE;
+
+ eZoom = SVX_ZOOM_PERCENT;
+
+ if ( pReqArgs )
+ {
+
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pReqArgs->Get(SID_ATTR_ZOOM);
+
+ eZoom = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+ else
+ {
+ SfxItemSet aSet ( GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM );
+ SvxZoomItem aZoomItem( SVX_ZOOM_PERCENT, pPreview->GetZoom(), SID_ATTR_ZOOM );
+
+ aSet.Put( aZoomItem );
+ //CHINA001 SvxZoomDialog* pDlg = pDlg = new SvxZoomDialog( NULL, aSet );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ AbstractSvxZoomDialog* pDlg = pFact->CreateSvxZoomDialog(NULL, aSet);
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ pDlg->SetLimits( 20, 400 );
+ pDlg->HideButton( ZOOMBTN_OPTIMAL );
+ bCancel = ( RET_CANCEL == pDlg->Execute() );
+
+ if ( !bCancel )
+ {
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pDlg->GetOutputItemSet()->
+ Get( SID_ATTR_ZOOM );
+
+ eZoom = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+
+ delete pDlg;
+ }
+ }
+
+ if ( !bCancel )
+ {
+ switch ( eZoom )
+ {
+ case SVX_ZOOM_OPTIMAL:
+ case SVX_ZOOM_WHOLEPAGE:
+ nZoom = pPreview->GetOptimalZoom(FALSE);
+ break;
+ case SVX_ZOOM_PAGEWIDTH:
+ nZoom = pPreview->GetOptimalZoom(TRUE);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ pPreview->SetZoom( nZoom );
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_PREVIEW_ZOOMIN:
+ {
+ USHORT nNew = pPreview->GetZoom() + 20 ;
+ nNew -= nNew % 20;
+ pPreview->SetZoom( nNew );
+ eZoom = SVX_ZOOM_PERCENT;
+ rReq.Done();
+ }
+ break;
+ case SID_PREVIEW_ZOOMOUT:
+ {
+ USHORT nNew = pPreview->GetZoom() - 1;
+ nNew -= nNew % 20;
+ pPreview->SetZoom( nNew );
+ eZoom = SVX_ZOOM_PERCENT;
+ rReq.Done();
+ }
+ break;
+ case SID_PREVIEW_MARGIN:
+ {
+ BOOL bMargin = pPreview->GetPageMargins();
+ pPreview->SetPageMargins( !bMargin );
+ pPreview->Invalidate();
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ const SfxPoolItem* pItem;
+ eZoom = SVX_ZOOM_PERCENT;
+ if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_ZOOMSLIDER, TRUE, &pItem ) )
+ {
+ const USHORT nCurrentZoom = ((const SvxZoomSliderItem*)pItem)->GetValue();
+ if( nCurrentZoom )
+ {
+ pPreview->SetZoom( nCurrentZoom );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+ case SID_PREVIEW_SCALINGFACTOR:
+ {
+ const SfxPoolItem* pItem;
+ SCTAB nTab = pPreview->GetTab();
+ String aOldName = pDocShell->GetDocument()->GetPageStyle( pPreview->GetTab() );
+ ScStyleSheetPool* pStylePool = pDocShell->GetDocument()->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pReqArgs && pStyleSheet && SFX_ITEM_SET == pReqArgs->GetItemState( SID_PREVIEW_SCALINGFACTOR, TRUE, &pItem ) )
+ {
+ const USHORT nCurrentZoom = ((const SvxZoomSliderItem *)pItem)->GetValue();
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nCurrentZoom ) );
+ ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ rReq.Done();
+ }
+ GetViewFrame()->GetBindings().Invalidate( nSlot );
+ }
+ break;
+ case SID_PRINTPREVIEW:
+ case SID_PREVIEW_CLOSE:
+ // print preview is now always in the same frame as the tab view
+ // -> always switch this frame back to normal view
+ // (ScTabViewShell ctor reads stored view data)
+
+ GetViewFrame()->GetDispatcher()->Execute( SID_VIEWSHELL0, SFX_CALLMODE_ASYNCHRON );
+ break;
+ case SID_CURSORPAGEUP:
+ case SID_CURSORPAGEDOWN:
+ case SID_CURSORHOME:
+ case SID_CURSOREND:
+ case SID_CURSORUP:
+ case SID_CURSORDOWN:
+ case SID_CURSORLEFT:
+ case SID_CURSORRIGHT:
+ DoScroll( nSlot );
+ break;
+ case SID_CANCEL:
+ if( ScViewUtil::IsFullScreen( *this ) )
+ ScViewUtil::SetFullScreen( *this, false );
+ break;
+
+ default:
+ break;
+ }
+}
+
+void __EXPORT ScPreviewShell::GetState( SfxItemSet& rSet )
+{
+ pPreview->SetInGetState(TRUE);
+
+ SCTAB nTab = pPreview->GetTab();
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ USHORT nZoom = pPreview->GetZoom();
+ BOOL bAllTested = pPreview->AllTested();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ pDocShell->GetStatePageStyle( *this, rSet, nTab );
+ break;
+ case SID_UNDO:
+ case SID_REDO:
+ case SID_REPEAT:
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_PREVIOUS:
+ case SID_PREVIEW_FIRST:
+ if (!nTotal || nPage==0)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_NEXT:
+ case SID_PREVIEW_LAST:
+ if (bAllTested)
+ if (!nTotal || nPage==nTotal-1)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_ZOOMIN:
+ if (nZoom >= 400)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_ZOOMOUT:
+ if (nZoom <= 20)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_ATTR_ZOOM:
+ {
+ SvxZoomItem aZoom( eZoom, nZoom, nWhich );
+ aZoom.SetValueSet( SVX_ZOOM_ENABLE_ALL & ~SVX_ZOOM_ENABLE_OPTIMAL );
+ rSet.Put( aZoom );
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ SvxZoomSliderItem aZoomSliderItem( nZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ break;
+ case SID_PREVIEW_SCALINGFACTOR:
+ {
+ if( pDocShell->IsReadOnly() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ String aOldName = pDocShell->GetDocument()->GetPageStyle( pPreview->GetTab() );
+ ScStyleSheetPool* pStylePool = pDocShell->GetDocument()->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ USHORT nCurrentZoom = ((const SfxUInt16Item&)rStyleSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ if( nCurrentZoom )
+ {
+ SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM_SLIDER, MAXZOOM_SLIDER, SID_PREVIEW_SCALINGFACTOR );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ }
+ }
+ break;
+ case SID_STATUS_DOCPOS:
+ rSet.Put( SfxStringItem( nWhich, pPreview->GetPosString() ) );
+ break;
+ case SID_PRINTPREVIEW:
+ rSet.Put( SfxBoolItem( nWhich, TRUE ) );
+ break;
+ case SID_FORMATPAGE:
+ case SID_PREVIEW_MARGIN:
+ if( pDocShell->IsReadOnly() )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+
+ pPreview->SetInGetState(FALSE);
+}
+
+void ScPreviewShell::FillFieldData( ScHeaderFieldData& rData )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = pPreview->GetTab();
+ pDoc->GetName( nTab, rData.aTabName );
+
+ rData.aTitle = pDocShell->GetTitle();
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ rData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if ( rData.aLongDocName.Len() )
+ rData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
+ else
+ rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+ rData.nPageNo = pPreview->GetPageNo() + 1;
+
+ BOOL bAllTested = pPreview->AllTested();
+ if (bAllTested)
+ rData.nTotalPages = pPreview->GetTotalPages();
+ else
+ rData.nTotalPages = 99;
+
+ // eNumType kennt der Dialog selber
+}
+
+void __EXPORT ScPreviewShell::WriteUserData(String& rData, BOOL /* bBrowse */)
+{
+ // nZoom
+ // nPageNo
+
+ rData = String::CreateFromInt32(pPreview->GetZoom());
+ rData += (sal_Unicode) SC_USERDATA_SEP;
+ rData += String::CreateFromInt32(pPreview->GetPageNo());
+}
+
+void __EXPORT ScPreviewShell::ReadUserData(const String& rData, BOOL /* bBrowse */)
+{
+ xub_StrLen nCount = rData.GetTokenCount();
+ if (nCount)
+ {
+ xub_StrLen nIndex = 0;
+ pPreview->SetZoom((USHORT)rData.GetToken( 0, SC_USERDATA_SEP, nIndex ).ToInt32());
+ pPreview->SetPageNo(rData.GetToken( 0, SC_USERDATA_SEP, nIndex ).ToInt32());
+ eZoom = SVX_ZOOM_PERCENT;
+ }
+}
+
+void __EXPORT ScPreviewShell::WriteUserDataSequence(uno::Sequence < beans::PropertyValue >& rSeq, sal_Bool /* bBrowse */)
+{
+ rSeq.realloc(3);
+ beans::PropertyValue* pSeq = rSeq.getArray();
+ if(pSeq)
+ {
+ sal_uInt16 nViewID(GetViewFrame()->GetCurViewId());
+ pSeq[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEWID));
+ rtl::OUStringBuffer sBuffer(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEW)));
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nViewID));
+ pSeq[0].Value <<= sBuffer.makeStringAndClear();
+ pSeq[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
+ pSeq[1].Value <<= sal_Int32 (pPreview->GetZoom());
+ pSeq[2].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageNumber"));
+ pSeq[2].Value <<= pPreview->GetPageNo();
+ }
+}
+
+void __EXPORT ScPreviewShell::ReadUserDataSequence(const uno::Sequence < beans::PropertyValue >& rSeq, sal_Bool /* bBrowse */)
+{
+ sal_Int32 nCount(rSeq.getLength());
+ if (nCount)
+ {
+ sal_Int32 nTemp = 0;
+ const beans::PropertyValue* pSeq = rSeq.getConstArray();
+ if(pSeq)
+ {
+ for(sal_Int32 i = 0; i < nCount; i++, pSeq++)
+ {
+ rtl::OUString sName(pSeq->Name);
+ if(sName.compareToAscii(SC_ZOOMVALUE) == 0)
+ {
+ if (pSeq->Value >>= nTemp)
+ pPreview->SetZoom(sal_uInt16(nTemp));
+ }
+ else if (sName.compareToAscii("PageNumber") == 0)
+ {
+ if (pSeq->Value >>= nTemp)
+ pPreview->SetPageNo(nTemp);
+ }
+ }
+ }
+ }
+}
+
+void ScPreviewShell::DoScroll( USHORT nMode )
+{
+ Point aCurPos, aPrevPos;
+
+ long nHRange = pHorScroll->GetRange().Max();
+ long nHLine = pHorScroll->GetLineSize();
+ long nHPage = pHorScroll->GetPageSize();
+ long nVRange = pVerScroll->GetRange().Max();
+ long nVLine = pVerScroll->GetLineSize();
+ long nVPage = pVerScroll->GetPageSize();
+
+ aCurPos.X() = pHorScroll->GetThumbPos();
+ aCurPos.Y() = pVerScroll->GetThumbPos();
+ aPrevPos = aCurPos;
+
+ long nThumbPos = pVerScroll->GetThumbPos();
+ long nRangeMax = pVerScroll->GetRangeMax();
+
+ switch( nMode )
+ {
+ case SID_CURSORUP:
+ if( nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+
+ if( nPage>0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ aCurPos.Y() -= nVLine;
+ break;
+ case SID_CURSORDOWN:
+ if( nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+
+ // before testing for last page, make sure all page counts are calculated
+ if ( nPage+1 == nTotal && !pPreview->AllTested() )
+ {
+ pPreview->CalcAll();
+ nTotal = pPreview->GetTotalPages();
+ }
+
+ if( nPage<nTotal-1 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ aCurPos.Y() += nVLine;
+ break;
+ case SID_CURSORLEFT:
+ aCurPos.X() -= nHLine;
+ break;
+ case SID_CURSORRIGHT:
+ aCurPos.X() += nHLine;
+ break;
+ case SID_CURSORPAGEUP:
+ if( nThumbPos==0 || nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+
+ if( nPage>0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
+ Execute( aSfxRequest );
+ aCurPos.Y() = nVRange;
+ }
+ }
+ else
+ aCurPos.Y() -= nVPage;
+ break;
+ case SID_CURSORPAGEDOWN:
+ if( (abs(nVPage+nThumbPos-nRangeMax)<10) || nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+
+ // before testing for last page, make sure all page counts are calculated
+ if ( nPage+1 == nTotal && !pPreview->AllTested() )
+ {
+ pPreview->CalcAll();
+ nTotal = pPreview->GetTotalPages();
+ }
+ if( nPage<nTotal-1 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
+ Execute( aSfxRequest );
+ aCurPos.Y() = 0;
+ }
+ }
+ else
+ aCurPos.Y() += nVPage;
+ break;
+ case SID_CURSORHOME:
+ if( nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if( nTotal && nPage != 0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_FIRST );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ {
+ aCurPos.Y() = 0;
+ aCurPos.X() = 0;
+ }
+ break;
+ case SID_CURSOREND:
+ if( nMaxVertPos<0 )
+ {
+ if( !pPreview->AllTested() )
+ pPreview->CalcAll();
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if( nTotal && nPage+1 != nTotal )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_LAST );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ {
+ aCurPos.Y() = nVRange;
+ aCurPos.X() = nHRange;
+ }
+ break;
+ }
+
+ // nHRange-nHPage kann negativ sein, deshalb Abfrage auf < 0 hinterher
+
+ if( aCurPos.Y() > (nVRange-nVPage) )
+ aCurPos.Y() = (nVRange-nVPage);
+ if( aCurPos.Y() < 0 )
+ aCurPos.Y() = 0;
+ if( aCurPos.X() > (nHRange-nHPage) )
+ aCurPos.X() = (nHRange-nHPage);
+ if( aCurPos.X() < 0 )
+ aCurPos.X() = 0;
+
+ if( nMaxVertPos>=0 )
+ {
+ if( aCurPos.Y() != aPrevPos.Y() )
+ {
+ pVerScroll->SetThumbPos( aCurPos.Y() );
+ pPreview->SetYOffset( aCurPos.Y() );
+ }
+ }
+
+ if( aCurPos.X() != aPrevPos.X() )
+ {
+ pHorScroll->SetThumbPos( aCurPos.X() );
+ pPreview->SetXOffset( aCurPos.X() );
+ }
+
+}
+
+void ScPreviewShell::AddAccessibilityObject( SfxListener& rObject )
+{
+ if (!pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster = new SfxBroadcaster;
+
+ rObject.StartListening( *pAccessibilityBroadcaster );
+}
+
+void ScPreviewShell::RemoveAccessibilityObject( SfxListener& rObject )
+{
+ if (pAccessibilityBroadcaster)
+ rObject.EndListening( *pAccessibilityBroadcaster );
+ else
+ {
+ DBG_ERROR("kein Accessibility-Broadcaster?");
+ }
+}
+
+void ScPreviewShell::BroadcastAccessibility( const SfxHint &rHint )
+{
+ if (pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster->Broadcast( rHint );
+}
+
+BOOL ScPreviewShell::HasAccessibilityObjects()
+{
+ return pAccessibilityBroadcaster && pAccessibilityBroadcaster->HasListeners();
+}
+
+const ScPreviewLocationData& ScPreviewShell::GetLocationData()
+{
+ return pPreview->GetLocationData();
+}
+
+ScDocument* ScPreviewShell::GetDocument()
+{
+ return pDocShell->GetDocument();
+}
+
+
diff --git a/sc/source/ui/view/prevwsh2.cxx b/sc/source/ui/view/prevwsh2.cxx
new file mode 100644
index 000000000000..07af90f797aa
--- /dev/null
+++ b/sc/source/ui/view/prevwsh2.cxx
@@ -0,0 +1,357 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+
+//------------------------------------------------------------------
+
+// TOOLS
+#define _BIGINT_HXX
+#define _SFXMULTISEL_HXX
+#define _STACK_HXX
+#define _QUEUE_HXX
+#define _DYNARR_HXX
+#define _TREELIST_HXX
+#define _CACHESTR_HXX
+#define _NEW_HXX
+//#define _SHL_HXX
+//#define _LINK_HXX
+//#define _ERRCODE_HXX
+//#define _GEN_HXX
+//#define _FRACT_HXX
+//#define _STRING_HXX
+//#define _MTF_HXX
+//#define _CONTNR_HXX
+//#define _LIST_HXX
+//#define _TABLE_HXX
+#define _DYNARY_HXX
+//#define _UNQIDX_HXX
+#define _SVMEMPOOL_HXX
+//#define _UNQID_HXX
+//#define _DEBUG_HXX
+//#define _DATE_HXX
+//#define _TIME_HXX
+//#define _DATETIME_HXX
+//#define _INTN_HXX
+//#define _WLDCRD_HXX
+//#define _FSYS_HXX
+//#define _STREAM_HXX
+#define _CACHESTR_HXX
+//#define _SV_MULTISEL_HXX
+
+//SV
+//#define _CLIP_HXX ***
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _FONTDLG_HXX
+#define _PRVWIN_HXX
+//#define _COLOR_HXX
+//#define _PAL_HXX
+//#define _BITMAP_HXX
+//#define _GDIOBJ_HXX
+//#define _POINTR_HXX
+//#define _ICON_HXX
+//#define _IMAGE_HXX
+//#define _KEYCOD_HXX
+//#define _EVENT_HXX
+#define _HELP_HXX
+//#define _APP_HXX
+//#define _MDIAPP_HXX
+//#define _TIMER_HXX
+//#define _METRIC_HXX
+//#define _REGION_HXX
+//#define _OUTDEV_HXX
+//#define _SYSTEM_HXX
+//#define _VIRDEV_HXX
+//#define _JOBSET_HXX
+//#define _PRINT_HXX
+//#define _WINDOW_HXX
+//#define _SYSWIN_HXX
+//#define _WRKWIN_HXX
+#define _MDIWIN_HXX
+//#define _FLOATWIN_HXX
+//#define _DOCKWIN_HXX
+//#define _CTRL_HXX
+//#define _SCRBAR_HXX
+//#define _BUTTON_HXX
+//#define _IMAGEBTN_HXX
+//#define _FIXED_HXX
+//#define _GROUP_HXX
+//#define _EDIT_HXX
+//#define _COMBOBOX_HXX
+//#define _LSTBOX_HXX
+//#define _SELENG_HXX ***
+//#define _SPLIT_HXX
+#define _SPIN_HXX
+//#define _FIELD_HXX
+//#define _MOREBTN_HXX ***
+//#define _TOOLBOX_HXX
+//#define _STATUS_HXX ***
+//#define _DIALOG_HXX
+//#define _MSGBOX_HXX
+//#define _SYSDLG_HXX
+//#define _PRNDLG_HXX
+#define _COLDLG_HXX
+//#define _TABDLG_HXX
+//#define _GDIMTF_HXX
+//#define _POLY_HXX
+//#define _ACCEL_HXX
+//#define _GRAPH_HXX
+#define _SOUND_HXX
+
+#if defined WIN
+#define _MENUBTN_HXX
+#endif
+
+//svtools
+#define _SCRWIN_HXX
+#define _RULER_HXX
+//#define _TABBAR_HXX
+//#define _VALUESET_HXX
+#define _STDMENU_HXX
+//#define _STDCTRL_HXX
+//#define _CTRLBOX_HXX
+#define _CTRLTOOL_HXX
+#define _EXTATTR_HXX
+#define _FRM3D_HXX
+#define _EXTATTR_HXX
+
+//SVTOOLS
+//#define _SVTREELIST_HXX ***
+#define _FILTER_HXX
+//#define _SVLBOXITM_HXX ***
+//#define _SVTREEBOX_HXX ***
+#define _SVICNVW_HXX
+#define _SVTABBX_HXX
+
+//sfxcore.hxx
+//#define _SFXINIMGR_HXX ***
+//#define _SFXCFGITEM_HXX
+//#define _SFX_PRINTER_HXX
+#define _SFXGENLINK_HXX
+#define _SFXHINTPOST_HXX
+#define _SFXDOCINF_HXX
+#define _SFXLINKHDL_HXX
+//#define _SFX_PROGRESS_HXX
+
+//sfxsh.hxx
+//#define _SFX_SHELL_HXX
+//#define _SFXAPP_HXX
+//#define _SFXDISPATCH_HXX
+//#define _SFXMSG_HXX ***
+//#define _SFXOBJFACE_HXX ***
+//#define _SFXREQUEST_HXX
+#define _SFXMACRO_HXX
+
+// SFX
+//#define _SFXAPPWIN_HXX ***
+#define _SFX_SAVEOPT_HXX
+//#define _SFX_CHILDWIN_HXX
+//#define _SFXCTRLITEM_HXX
+#define _SFXPRNMON_HXX
+#define _INTRO_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXFILEDLG_HXX
+#define _PASSWD_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXSTBMGR_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXEVENT_HXX
+
+//sfxdoc.hxx
+//#define _SFX_OBJSH_HXX
+//#define _SFX_CLIENTSH_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFX_OBJFAC_HXX
+#define _SFX_DOCFILT_HXX
+//#define _SFXDOCFILE_HXX ***
+//define _VIEWFAC_HXX
+//#define _SFXVIEWFRM_HXX
+//#define _SFXVIEWSH_HXX
+//#define _MDIFRM_HXX ***
+#define _SFX_IPFRM_HXX
+//#define _SFX_INTERNO_HXX
+
+//sfxdlg.hxx
+//#define _SFXTABDLG_HXX
+//#define _BASEDLGS_HXX ***
+#define _SFX_DINFDLG_HXX
+#define _SFXDINFEDT_HXX
+#define _SFX_MGETEMPL_HXX
+#define _SFX_TPLPITEM_HXX
+//#define _SFX_STYLEDLG_HXX
+#define _NEWSTYLE_HXX
+//#define _SFXDOCTEMPL_HXX ***
+//#define _SFXDOCTDLG_HXX ***
+//#define _SFX_TEMPLDLG_HXX ***
+//#define _SFXNEW_HXX ***
+#define _SFXDOCMAN_HXX
+#define _SFXDOCKWIN_HXX
+
+//sfxitems.hxx
+#define _SFX_WHMAP_HXX
+//#define _ARGS_HXX ***
+//#define _SFXPOOLITEM_HXX
+//#define _SFXINTITEM_HXX
+//#define _SFXENUMITEM_HXX
+#define _SFXFLAGITEM_HXX
+//#define _SFXSTRITEM_HXX
+#define _SFXPTITEM_HXX
+#define _SFXRECTITEM_HXX
+//#define _SFXITEMPOOL_HXX
+//#define _SFXITEMSET_HXX
+#define _SFXITEMITER_HXX
+#define _SFX_WHITER_HXX
+#define _SFXPOOLCACH_HXX
+//#define _AEITEM_HXX
+#define _SFXRNGITEM_HXX
+//#define _SFXSLSTITM_HXX
+//#define _SFXSTYLE_HXX
+
+//xout.hxx
+//#define _XENUM_HXX
+//#define _XPOLY_HXX
+//#define _XATTR_HXX
+//#define _XOUTX_HXX
+//#define _XPOOL_HXX
+//#define _XTABLE_HXX
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+//#define _SDR_NOOBJECTS
+//#define _SDR_NOVIEWS
+#define _SDR_NOTRANSFORM
+#define _SDR_NOVIEWMARKER
+#define _SDR_NODRAGMETHODS
+#define _SDR_NOUNDO
+#define _SDR_NOXOUTDEV
+
+
+//#define SI_NOITEMS
+//#define SI_NODRW
+#define _SI_NOSBXCONTROLS
+//#define _VCATTR_HXX
+#define _VCONT_HXX
+//#define _VCSBX_HXX
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+//#define _VCDRWOBJ_HXX
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+//#define _SIDLL_HXX ***
+
+#define _SVX_DAILDLL_HXX
+#define _SVX_HYPHEN_HXX
+#define _SVX_IMPGRF_HXX
+#define _SVX_OPTITEMS_HXX
+#define _SVX_OPTGERL_HXX
+#define _SVX_OPTSAVE_HXX
+#define _SVX_OPTSPELL_HXX
+#define _SVX_OPTPATH_HXX
+#define _SVX_OPTLINGU_HXX
+#define _SVX_RULER_HXX
+#define _SVX_RULRITEM_HXX
+#define _SVX_SPLWRAP_HXX
+#define _SVX_SPLDLG_HXX
+#define _SVX_THESDLG_HXX
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdmodel.hxx>
+#include <svl/smplhint.hxx>
+
+#include "prevwsh.hxx"
+#include "docsh.hxx"
+#include "preview.hxx"
+#include "hints.hxx"
+#include "sc.hrc"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScPreviewShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ BOOL bDataChanged = FALSE;
+
+ if (rHint.ISA(SfxSimpleHint))
+ {
+ ULONG nSlot = ((const SfxSimpleHint&)rHint).GetId();
+ switch ( nSlot )
+ {
+ case FID_DATACHANGED:
+ case SID_SCPRINTOPTIONS:
+ bDataChanged = TRUE;
+ break;
+ case SC_HINT_DRWLAYER_NEW:
+ {
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+ }
+ break;
+ }
+ }
+ else if (rHint.ISA(ScPaintHint))
+ {
+ if ( ((const ScPaintHint&)rHint).GetPrintFlag() )
+ {
+ USHORT nParts = ((const ScPaintHint&)rHint).GetParts();
+ if (nParts & ( PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ))
+ bDataChanged = TRUE;
+ }
+ }
+ else if (rHint.ISA(SdrHint))
+ {
+ // SdrHints are no longer used for invalidating, thus react on objectchange instead
+ if(HINT_OBJCHG == ((const SdrHint&)rHint).GetKind())
+ bDataChanged = TRUE;
+ }
+
+ if (bDataChanged)
+ pPreview->DataChanged(TRUE);
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
new file mode 100644
index 000000000000..378ea1233cf9
--- /dev/null
+++ b/sc/source/ui/view/printfun.cxx
@@ -0,0 +1,3202 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include "printfun.hxx"
+
+#include <svx/svxids.hrc>
+#include <editeng/adjitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS
+#include <svx/fmview.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/svdpagv.hxx>
+#include <editeng/ulspitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/progress.hxx>
+#include <tools/multisel.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+#include <svx/xoutbmp.hxx>
+
+#include "editutil.hxx"
+#include "docsh.hxx"
+#include "output.hxx"
+#include "viewdata.hxx"
+#include "viewopti.hxx"
+#include "stlpool.hxx"
+#include "pagepar.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "drawutil.hxx"
+#include "globstr.hrc"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "pagedata.hxx"
+#include "printopt.hxx"
+#include "prevloc.hxx"
+#include "scmod.hxx"
+#include "drwlayer.hxx"
+#include "fillinfo.hxx"
+#include "postit.hxx"
+
+#include <vcl/lineinfo.hxx>
+#include <tools/pstm.hxx>
+
+#include <boost/scoped_ptr.hpp>
+
+#define ZOOM_MIN 10
+
+#define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue()
+#define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
+#define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )
+
+//------------------------------------------------------------------------
+
+ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
+{
+ nStartRow = r.nStartRow;
+ nEndRow = r.nEndRow;
+ nPagesX = r.nPagesX;
+ if (r.pHidden && nPagesX)
+ {
+ pHidden = new BOOL[nPagesX];
+ memcpy( pHidden, r.pHidden, nPagesX * sizeof(BOOL) );
+ }
+ else
+ pHidden = NULL;
+}
+
+const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
+{
+ delete[] pHidden;
+
+ nStartRow = r.nStartRow;
+ nEndRow = r.nEndRow;
+ nPagesX = r.nPagesX;
+ if (r.pHidden && nPagesX)
+ {
+ pHidden = new BOOL[nPagesX];
+ memcpy( pHidden, r.pHidden, nPagesX * sizeof(BOOL) );
+ }
+ else
+ pHidden = NULL;
+
+ return *this;
+}
+
+void ScPageRowEntry::SetPagesX(size_t nNew)
+{
+ if (pHidden)
+ {
+ DBG_ERROR("SetPagesX nicht nach SetHidden");
+ delete[] pHidden;
+ pHidden = NULL;
+ }
+ nPagesX = nNew;
+}
+
+void ScPageRowEntry::SetHidden(size_t nX)
+{
+ if ( nX < nPagesX )
+ {
+ if ( nX+1 == nPagesX ) // letzte Seite?
+ --nPagesX;
+ else
+ {
+ if (!pHidden)
+ {
+ pHidden = new BOOL[nPagesX];
+ memset( pHidden, FALSE, nPagesX * sizeof(BOOL) );
+ }
+ pHidden[nX] = TRUE;
+ }
+ }
+}
+
+BOOL ScPageRowEntry::IsHidden(size_t nX) const
+{
+ return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
+}
+
+size_t ScPageRowEntry::CountVisible() const
+{
+ if ( pHidden )
+ {
+ size_t nVis = 0;
+ for (size_t i=0; i<nPagesX; i++)
+ if (!pHidden[i])
+ ++nVis;
+ return nVis;
+ }
+ else
+ return nPagesX;
+}
+
+//------------------------------------------------------------------------
+
+long lcl_LineTotal(const SvxBorderLine* pLine)
+{
+ return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0;
+}
+
+void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
+{
+ pDocShell->UpdatePendingRowHeights( nPrintTab );
+ pDoc = pDocShell->GetDocument();
+
+ SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ if (pDocPrinter)
+ aOldPrinterMode = pDocPrinter->GetMapMode();
+
+ // einheitlicher MapMode ueber alle Aufrufe (z.B. Repaint !!!),
+ // weil die EditEngine sonst unterschiedliche Texthoehen liefert
+ pDev->SetMapMode(MAP_PIXEL);
+
+ pPageEndX = NULL;
+ pPageEndY = NULL;
+ pPageRows = NULL;
+ pBorderItem = NULL;
+ pBackgroundItem = NULL;
+ pShadowItem = NULL;
+
+ pEditEngine = NULL;
+ pEditDefaults = NULL;
+
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ pDoc->GetPageStyle( nPrintTab ),
+ SFX_STYLE_FAMILY_PAGE );
+ if (pStyleSheet)
+ pParamSet = &pStyleSheet->GetItemSet();
+ else
+ {
+ DBG_ERROR("Seitenvorlage nicht gefunden" );
+ pParamSet = NULL;
+ }
+
+ if (!bState)
+ nZoom = 100;
+ nManualZoom = 100;
+ bClearWin = FALSE;
+ bUseStyleColor = FALSE;
+ bIsRender = FALSE;
+
+ InitParam(pOptions);
+
+ pPageData = NULL; // wird nur zur Initialisierung gebraucht
+}
+
+ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
+ long nPage, long nDocP, const ScRange* pArea,
+ const ScPrintOptions* pOptions,
+ ScPageBreakData* pData )
+ : pDocShell ( pShell ),
+ pPrinter ( pNewPrinter ),
+ pDrawView ( NULL ),
+ nPrintTab ( nTab ),
+ nPageStart ( nPage ),
+ nDocPages ( nDocP ),
+ pUserArea ( pArea ),
+ bState ( FALSE ),
+ bSourceRangeValid ( FALSE ),
+ bPrintCurrentTable ( FALSE ),
+ bMultiArea ( FALSE ),
+ nTabPages ( 0 ),
+ nTotalPages ( 0 ),
+ pPageData ( pData )
+{
+ pDev = pPrinter;
+ aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
+ Construct( pOptions );
+}
+
+ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
+ long nPage, long nDocP, const ScRange* pArea,
+ const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ nPrintTab ( nTab ),
+ nPageStart ( nPage ),
+ nDocPages ( nDocP ),
+ pUserArea ( pArea ),
+ bState ( FALSE ),
+ bSourceRangeValid ( FALSE ),
+ bPrintCurrentTable ( FALSE ),
+ bMultiArea ( FALSE ),
+ nTabPages ( 0 ),
+ nTotalPages ( 0 ),
+ pPageData ( NULL )
+{
+ pDev = pOutDev;
+ Construct( pOptions );
+}
+
+ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
+ const ScPrintState& rState, const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ pUserArea ( NULL ),
+ bSourceRangeValid ( FALSE ),
+ bPrintCurrentTable ( FALSE ),
+ bMultiArea ( FALSE ),
+ pPageData ( NULL )
+{
+ pDev = pOutDev;
+
+ nPrintTab = rState.nPrintTab;
+ nStartCol = rState.nStartCol;
+ nStartRow = rState.nStartRow;
+ nEndCol = rState.nEndCol;
+ nEndRow = rState.nEndRow;
+ nZoom = rState.nZoom;
+ nPagesX = rState.nPagesX;
+ nPagesY = rState.nPagesY;
+ nTabPages = rState.nTabPages;
+ nTotalPages = rState.nTotalPages;
+ nPageStart = rState.nPageStart;
+ nDocPages = rState.nDocPages;
+ bState = TRUE;
+
+ Construct( pOptions );
+}
+ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow, SCTAB nTab,
+ long nPage, long nDocP, const ScRange* pArea,
+ const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ nPrintTab ( nTab ),
+ nPageStart ( nPage ),
+ nDocPages ( nDocP ),
+ pUserArea ( pArea ),
+ bState ( FALSE ),
+ bPrintCurrentTable ( FALSE ),
+ bMultiArea ( FALSE ),
+ nTabPages ( 0 ),
+ nTotalPages ( 0 ),
+ pPageData ( NULL )
+{
+ pDev = pWindow;
+ Construct( pOptions );
+}
+ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow,
+ const ScPrintState& rState, const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ pUserArea ( NULL ),
+ bPrintCurrentTable ( FALSE ),
+ bMultiArea ( FALSE ),
+ pPageData ( NULL )
+{
+ pDev = pWindow;
+
+ nPrintTab = rState.nPrintTab;
+ nStartCol = rState.nStartCol;
+ nStartRow = rState.nStartRow;
+ nEndCol = rState.nEndCol;
+ nEndRow = rState.nEndRow;
+ nZoom = rState.nZoom;
+ nPagesX = rState.nPagesX;
+ nPagesY = rState.nPagesY;
+ nTabPages = rState.nTabPages;
+ nTotalPages = rState.nTotalPages;
+ nPageStart = rState.nPageStart;
+ nDocPages = rState.nDocPages;
+ bState = TRUE;
+
+ Construct( pOptions );
+}
+
+void ScPrintFunc::GetPrintState( ScPrintState& rState )
+{
+ rState.nPrintTab = nPrintTab;
+ rState.nStartCol = nStartCol;
+ rState.nStartRow = nStartRow;
+ rState.nEndCol = nEndCol;
+ rState.nEndRow = nEndRow;
+ rState.nZoom = nZoom;
+ rState.nPagesX = nPagesX;
+ rState.nPagesY = nPagesY;
+ rState.nTabPages = nTabPages;
+ rState.nTotalPages = nTotalPages;
+ rState.nPageStart = nPageStart;
+ rState.nDocPages = nDocPages;
+}
+
+BOOL ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
+{
+ rRange = aLastSourceRange;
+ return bSourceRangeValid;
+}
+
+void ScPrintFunc::FillPageData()
+{
+ if (pPageData)
+ {
+ USHORT nCount = sal::static_int_cast<USHORT>( pPageData->GetCount() );
+ ScPrintRangeData& rData = pPageData->GetData(nCount); // hochzaehlen
+
+ rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
+ nEndCol, nEndRow, nPrintTab ) );
+ rData.SetPagesX( nPagesX, pPageEndX );
+ rData.SetPagesY( nTotalY, pPageEndY );
+
+ // Einstellungen
+ rData.SetTopDown( aTableParam.bTopDown );
+ rData.SetAutomatic( !aAreaParam.bPrintArea );
+ }
+}
+
+ScPrintFunc::~ScPrintFunc()
+{
+ ScAddress* pTripel = (ScAddress*) aNotePosList.First();
+ while (pTripel)
+ {
+ delete pTripel;
+ pTripel = (ScAddress*) aNotePosList.Next();
+ }
+ aNotePosList.Clear();
+
+ delete[] pPageEndX;
+ delete[] pPageEndY;
+ delete[] pPageRows;
+ delete pEditDefaults;
+ delete pEditEngine;
+
+ // Druckereinstellungen werden jetzt von aussen wiederhergestellt
+
+ // #64294# Fuer DrawingLayer/Charts muss der MapMode am Drucker (RefDevice) immer stimmen
+ SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ if (pDocPrinter)
+ pDocPrinter->SetMapMode(aOldPrinterMode);
+}
+
+void ScPrintFunc::SetDrawView( FmFormView* pNew )
+{
+ pDrawView = pNew;
+}
+
+void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
+{
+ for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
+ if (!rCellInfo.bEmptyCellText)
+ if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
+ GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
+ {
+ pThisRowInfo->pCellInfo[nX+1].pCell = NULL;
+ pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = TRUE;
+ }
+ }
+ }
+}
+
+//
+// Ausgabe auf Device (static)
+//
+// wird benutzt fuer:
+// - Clipboard/Bitmap
+// - Ole-Object (DocShell::Draw)
+// - Vorschau bei Vorlagen
+
+void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
+ const Rectangle& rBound, ScViewData* pViewData, BOOL bMetaFile )
+{
+ //! nPrintFactor auswerten !!!
+
+ SCTAB nTab = 0;
+ if (pViewData)
+ nTab = pViewData->GetTabNo();
+
+ BOOL bDoGrid, bNullVal, bFormula;
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ if (pStyleSheet)
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
+ bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
+ bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
+ }
+ else
+ {
+ const ScViewOptions& rOpt = pDoc->GetViewOptions();
+ bDoGrid = rOpt.GetOption(VOPT_GRID);
+ bNullVal = rOpt.GetOption(VOPT_NULLVALS);
+ bFormula = rOpt.GetOption(VOPT_FORMULAS);
+ }
+
+ MapMode aMode = pDev->GetMapMode();
+
+ Rectangle aRect = rBound;
+
+ if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
+ aRect = Rectangle( Point(), pDev->GetOutputSize() );
+
+ SCCOL nX1 = 0;
+ SCROW nY1 = 0;
+ SCCOL nX2 = OLE_STD_CELLS_X - 1;
+ SCROW nY2 = OLE_STD_CELLS_Y - 1;
+ if (bMetaFile)
+ {
+ ScRange aRange = pDoc->GetRange( nTab, rBound );
+ nX1 = aRange.aStart.Col();
+ nY1 = aRange.aStart.Row();
+ nX2 = aRange.aEnd.Col();
+ nY2 = aRange.aEnd.Row();
+ }
+ else if (pViewData)
+ {
+ ScSplitPos eWhich = pViewData->GetActivePart();
+ ScHSplitPos eHWhich = WhichH(eWhich);
+ ScVSplitPos eVWhich = WhichV(eWhich);
+ nX1 = pViewData->GetPosX(eHWhich);
+ nY1 = pViewData->GetPosY(eVWhich);
+ nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
+ if (nX2>nX1) --nX2;
+ nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
+ if (nY2>nY1) --nY2;
+ }
+
+ if (nX1 > MAXCOL) nX1 = MAXCOL;
+ if (nX2 > MAXCOL) nX2 = MAXCOL;
+ if (nY1 > MAXROW) nY1 = MAXROW;
+ if (nY2 > MAXROW) nY2 = MAXROW;
+
+ long nDevSizeX = aRect.Right()-aRect.Left()+1;
+ long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
+
+ Rectangle aLines;
+ ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
+// BOOL bAddLines = pDoc->HasLines( aRange, aLines );
+
+ long nTwipsSizeX = 0;
+ for (SCCOL i=nX1; i<=nX2; i++)
+ nTwipsSizeX += pDoc->GetColWidth( i, nTab );
+ long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
+
+ // wenn keine Linien, dann trotzdem Platz fuer den Aussenrahmen (20 Twips = 1pt)
+ // (HasLines initalisiert aLines auf 0,0,0,0)
+ nTwipsSizeX += aLines.Left() + Max( aLines.Right(), 20L );
+ nTwipsSizeY += aLines.Top() + Max( aLines.Bottom(), 20L );
+
+ double nScaleX = (double) nDevSizeX / nTwipsSizeX;
+ double nScaleY = (double) nDevSizeY / nTwipsSizeY;
+
+ //! Flag bei FillInfo uebergeben !!!!!
+ ScRange aERange;
+ BOOL bEmbed = pDoc->IsEmbedded();
+ if (bEmbed)
+ {
+ pDoc->GetEmbedded(aERange);
+ pDoc->ResetEmbedded();
+ }
+
+ // Daten zusammenstellen
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
+ nScaleX, nScaleY, FALSE, bFormula );
+ lcl_HidePrint( aTabInfo, nX1, nX2 );
+
+ if (bEmbed)
+ pDoc->SetEmbedded(aERange);
+
+/* if (!bMetaFile)
+ pDev->SetMapMode(MAP_PIXEL);
+*/
+ long nScrX = aRect.Left();
+ long nScrY = aRect.Top();
+
+ // Wenn keine Linien, trotzdem Platz fuer Gitterlinien lassen
+ // (werden sonst abgeschnitten)
+ long nAddX = (long)( aLines.Left() * nScaleX );
+ nScrX += ( nAddX ? nAddX : 1 );
+ long nAddY = (long)( aLines.Top() * nScaleY );
+ nScrY += ( nAddY ? nAddY : 1 );
+
+ ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
+ aOutputData.SetMetaFileMode(bMetaFile);
+ aOutputData.SetShowNullValues(bNullVal);
+ aOutputData.SetShowFormulas(bFormula);
+
+ // #114135#
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ FmFormView* pDrawView = NULL;
+
+ if( pModel )
+ {
+ pDrawView = new FmFormView( pModel, pDev );
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ pDrawView->SetPrintPreview( TRUE );
+ aOutputData.SetDrawView( pDrawView );
+ }
+
+ //! SetUseStyleColor ??
+
+ if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
+ aOutputData.SetSnapPixel();
+
+ Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
+ long nLogStX = aLogStart.X();
+ long nLogStY = aLogStart.Y();
+
+ //! nZoom fuer GetFont in OutputData ???
+
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
+
+ // #i72502#
+ const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
+ aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
+
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(aMode);
+
+ aOutputData.DrawBackground();
+
+#ifdef OS2
+ if (bMetaFile && !bDoGrid)
+ {
+ // unter OS2 fuer Metafiles gesamte Flaeche benutzen,
+ // weil sonst die Groesse nicht erkannt wird
+ pDev->SetLineColor();
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nScrX,nScrY,
+ nScrX+aOutputData.GetScrW(), nScrY+aOutputData.GetScrH() ) );
+ }
+#endif
+
+ aOutputData.DrawShadow();
+ aOutputData.DrawFrame();
+ aOutputData.DrawStrings();
+
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
+
+ aOutputData.DrawEdit(!bMetaFile);
+
+ if (bDoGrid)
+ {
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(aMode);
+
+ aOutputData.DrawGrid( TRUE, FALSE ); // keine Seitenumbrueche
+
+ pDev->SetLineColor( COL_BLACK );
+
+ Size aOne = pDev->PixelToLogic( Size(1,1) );
+ if (bMetaFile)
+ aOne = Size(1,1); // compatible with DrawGrid
+ long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
+ long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ // extra line at the left edge for left-to-right, right for right-to-left
+ if ( bLayoutRTL )
+ pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
+ else
+ pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
+ // extra line at the top in both cases
+ pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
+ }
+
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
+ aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
+ aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
+
+ // #114135#
+ delete pDrawView;
+}
+
+//
+// Drucken
+//
+
+void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
+{
+ // nDistance muss vorher unterschiedlich initalisiert sein
+
+ if ( pHFSet == NULL )
+ {
+ rParam.bEnable = FALSE;
+ rParam.pBorder = NULL;
+ rParam.pBack = NULL;
+ rParam.pShadow = NULL;
+ }
+ else
+ {
+ rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
+ rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
+ rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
+ rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
+ const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
+ long nTmp;
+ nTmp = pHFLR->GetLeft();
+ rParam.nLeft = nTmp < 0 ? 0 : USHORT(nTmp);
+ nTmp = pHFLR->GetRight();
+ rParam.nRight = nTmp < 0 ? 0 : USHORT(nTmp);
+ rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
+ rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
+ rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);;
+
+// jetzt doch wieder schon im Dialog:
+// rParam.nHeight += rParam.nDistance; // nicht mehr im Dialog ???
+
+ if (rParam.pBorder)
+ rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
+ lcl_LineTotal( rParam.pBorder->GetBottom() );
+
+ rParam.nManHeight = rParam.nHeight;
+ }
+
+ if (!rParam.bEnable)
+ rParam.nHeight = 0;
+}
+
+// bNew = TRUE: benutzten Bereich aus dem Dokument suchen
+// bNew = FALSE: nur ganze Zeilen/Spalten begrenzen
+
+BOOL ScPrintFunc::AdjustPrintArea( BOOL bNew )
+{
+ SCCOL nOldEndCol = nEndCol; // nur wichtig bei !bNew
+ SCROW nOldEndRow = nEndRow;
+ BOOL bChangeCol = TRUE; // bei bNew werden beide angepasst
+ BOOL bChangeRow = TRUE;
+
+ BOOL bNotes = aTableParam.bNotes;
+ if ( bNew )
+ {
+ nStartCol = 0;
+ nStartRow = 0;
+ if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
+ return FALSE; // nix
+ }
+ else
+ {
+ BOOL bFound = TRUE;
+ bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
+ bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
+ BOOL bForcedChangeRow = FALSE;
+
+ // #i53558# Crop entire column of old row limit to real print area with
+ // some fuzzyness.
+ if (!bChangeRow && nStartRow == 0)
+ {
+ SCROW nPAEndRow;
+ bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
+ // Say we don't want to print more than ~1000 empty rows, which are
+ // about 14 pages intentionally left blank..
+ const SCROW nFuzzy = 23*42;
+ if (nPAEndRow + nFuzzy < nEndRow)
+ {
+ bForcedChangeRow = TRUE;
+ nEndRow = nPAEndRow;
+ }
+ else
+ bFound = TRUE; // user seems to _want_ to print some empty rows
+ }
+ // TODO: in case we extend the number of columns we may have to do the
+ // same for horizontal cropping.
+
+ if ( bChangeCol && bChangeRow )
+ bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
+ else if ( bChangeCol )
+ bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
+ else if ( bChangeRow )
+ bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
+
+ if (!bFound)
+ return FALSE; // leer
+
+ if (bForcedChangeRow)
+ bChangeRow = TRUE;
+ }
+
+ pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
+ FALSE, TRUE ); // kein Refresh, incl. Attrs
+
+ if ( bChangeCol )
+ {
+ OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ pRefDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize
+
+ pDoc->ExtendPrintArea( pRefDev,
+ nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ // nEndCol wird veraendert
+ }
+
+ if ( nEndCol < MAXCOL && pDoc->HasAttrib(
+ nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
+ ++nEndCol;
+ if ( nEndRow < MAXROW && pDoc->HasAttrib(
+ nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
+ ++nEndRow;
+
+ if (!bChangeCol) nEndCol = nOldEndCol;
+ if (!bChangeRow) nEndRow = nOldEndRow;
+
+ return TRUE;
+}
+
+long ScPrintFunc::TextHeight( const EditTextObject* pObject )
+{
+ if (!pObject)
+ return 0;
+
+// pEditEngine->SetPageNo( nTotalPages );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, FALSE );
+
+ return (long) pEditEngine->GetTextHeight();
+}
+
+// nZoom muss gesetzt sein !!!
+// und der entsprechende Twip-MapMode eingestellt
+
+void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
+{
+ DBG_ASSERT( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
+
+ if (rParam.bEnable && rParam.bDynamic)
+ {
+ // nHeight aus Inhalten berechnen
+
+ MakeEditEngine();
+ long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
+ rParam.nLeft - rParam.nRight ) * 100 / nZoom;
+ if (rParam.pBorder)
+ nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
+ rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
+ lcl_LineTotal(rParam.pBorder->GetLeft()) +
+ lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
+
+ if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
+ nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
+ rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
+
+ pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
+
+ long nMaxHeight = 0;
+ if ( rParam.pLeft )
+ {
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
+ }
+ if ( rParam.pRight )
+ {
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
+ }
+
+ rParam.nHeight = nMaxHeight + rParam.nDistance;
+ if (rParam.pBorder)
+ rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
+ rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
+ lcl_LineTotal( rParam.pBorder->GetTop() ) +
+ lcl_LineTotal( rParam.pBorder->GetBottom() );
+ if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
+ rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
+ rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
+
+ if (rParam.nHeight < rParam.nManHeight)
+ rParam.nHeight = rParam.nManHeight; // eingestelltes Minimum
+ }
+}
+
+void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
+{
+ if (!pParamSet)
+ return;
+
+ // TabPage "Seite"
+ const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
+ long nTmp;
+ nTmp = pLRItem->GetLeft();
+ nLeftMargin = nTmp < 0 ? 0 : USHORT(nTmp);
+ nTmp = pLRItem->GetRight();
+ nRightMargin = nTmp < 0 ? 0 : USHORT(nTmp);
+ const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
+ nTopMargin = pULItem->GetUpper();
+ nBottomMargin = pULItem->GetLower();
+
+ const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
+ nPageUsage = pPageItem->GetPageUsage();
+ bLandscape = pPageItem->IsLandscape();
+ aFieldData.eNumType = pPageItem->GetNumType();
+
+ bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
+ bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
+
+ aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
+ if ( !aPageSize.Width() || !aPageSize.Height() )
+ {
+ DBG_ERROR("PageSize Null ?!?!?");
+ aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
+ }
+
+ pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
+ pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
+ pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
+
+ // TabPage "Kopfzeile"
+
+ aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Inhalt
+ aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
+
+ const SvxSetItem* pHeaderSetItem;
+ const SfxItemSet* pHeaderSet = NULL;
+ if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, FALSE,
+ (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
+ {
+ pHeaderSet = &pHeaderSetItem->GetItemSet();
+ // Kopfzeile hat unteren Abstand
+ aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
+ }
+ lcl_FillHFParam( aHdr, pHeaderSet );
+
+ // TabPage "Fusszeile"
+
+ aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Inhalt
+ aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
+
+ const SvxSetItem* pFooterSetItem;
+ const SfxItemSet* pFooterSet = NULL;
+ if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, FALSE,
+ (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
+ {
+ pFooterSet = &pFooterSetItem->GetItemSet();
+ // Fusszeile hat oberen Abstand
+ aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
+ }
+ lcl_FillHFParam( aFtr, pFooterSet );
+
+ //------------------------------------------------------
+ // Table-/Area-Params aus einzelnen Items zusammenbauen:
+ //------------------------------------------------------
+ // TabPage "Tabelle"
+
+ const SfxUInt16Item* pScaleItem = NULL;
+ const ScPageScaleToItem* pScaleToItem = NULL;
+ const SfxUInt16Item* pScaleToPagesItem = NULL;
+ SfxItemState eState;
+
+ eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, FALSE,
+ (const SfxPoolItem**)&pScaleItem );
+ if ( SFX_ITEM_DEFAULT == eState )
+ pScaleItem = (const SfxUInt16Item*)
+ &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
+
+ eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, FALSE,
+ (const SfxPoolItem**)&pScaleToItem );
+ if ( SFX_ITEM_DEFAULT == eState )
+ pScaleToItem = (const ScPageScaleToItem*)
+ &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
+
+ eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, FALSE,
+ (const SfxPoolItem**)&pScaleToPagesItem );
+ if ( SFX_ITEM_DEFAULT == eState )
+ pScaleToPagesItem = (const SfxUInt16Item*)
+ &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
+
+ DBG_ASSERT( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
+
+ aTableParam.bCellContent = TRUE;
+ aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
+ aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
+ aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
+ aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
+ aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
+ aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
+ aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
+ aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
+ aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
+ aTableParam.bLeftRight = !aTableParam.bLeftRight;
+ aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
+ if (!aTableParam.nFirstPageNo)
+ aTableParam.nFirstPageNo = (USHORT) nPageStart; // von vorheriger Tabelle
+
+ if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
+ {
+ UINT16 nScaleAll = pScaleItem->GetValue();
+ UINT16 nScaleToPages = pScaleToPagesItem->GetValue();
+
+ aTableParam.bScaleNone = (nScaleAll == 100);
+ aTableParam.bScaleAll = (nScaleAll > 0 );
+ aTableParam.bScaleTo = pScaleToItem->IsValid();
+ aTableParam.bScalePageNum = (nScaleToPages > 0 );
+ aTableParam.nScaleAll = nScaleAll;
+ aTableParam.nScaleWidth = pScaleToItem->GetWidth();
+ aTableParam.nScaleHeight = pScaleToItem->GetHeight();
+ aTableParam.nScalePageNum = nScaleToPages;
+ }
+ else
+ {
+ aTableParam.bScaleNone = TRUE;
+ aTableParam.bScaleAll = FALSE;
+ aTableParam.bScaleTo = FALSE;
+ aTableParam.bScalePageNum = FALSE;
+ aTableParam.nScaleAll = 0;
+ aTableParam.nScaleWidth = 0;
+ aTableParam.nScaleHeight = 0;
+ aTableParam.nScalePageNum = 0;
+ }
+
+ // skip empty pages only if options with that flag are passed
+ aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
+ if ( pPageData )
+ aTableParam.bSkipEmpty = FALSE;
+ // Wenn pPageData gesetzt ist, interessieren fuer die Umbruch-Vorschau
+ // nur die Umbrueche, leere Seiten werden nicht speziell behandelt
+
+ //------------------------------------------------------
+ // TabPage "Bereiche":
+ //------------------------------------------------------
+
+ //! alle PrintAreas der Tabelle durchgehen !!!
+ const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
+ const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
+ const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
+
+ // ATTR_PAGE_PRINTTABLES wird ignoriert
+
+ if ( pUserArea ) // UserArea (Selektion) hat Vorrang
+ {
+ bPrintCurrentTable =
+ aAreaParam.bPrintArea = TRUE; // Selektion
+ aAreaParam.aPrintArea = *pUserArea;
+
+ // Die Tabellen-Abfrage ist schon in DocShell::Print, hier immer
+ aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
+ aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
+
+// lcl_LimitRange( aAreaParam.aPrintArea, nPrintTab ); // ganze Zeilen/Spalten...
+ }
+ else if ( pDoc->HasPrintRange() )
+ {
+ if ( pPrintArea ) // mindestens eine gesetzt ?
+ {
+ bPrintCurrentTable =
+ aAreaParam.bPrintArea = TRUE;
+ aAreaParam.aPrintArea = *pPrintArea;
+
+ bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
+ }
+ else
+ {
+ // do not print hidden sheets with "Print entire sheet" flag
+ bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
+ aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
+ }
+ }
+ else
+ {
+ // #74834# don't print hidden tables if there's no print range defined there
+ if ( pDoc->IsVisible( nPrintTab ) )
+ {
+ aAreaParam.bPrintArea = FALSE;
+ bPrintCurrentTable = TRUE;
+ }
+ else
+ {
+ aAreaParam.bPrintArea = TRUE; // otherwise the table is always counted
+ bPrintCurrentTable = FALSE;
+ }
+ }
+
+ if ( pRepeatCol )
+ {
+ aAreaParam.bRepeatCol = TRUE;
+ aAreaParam.aRepeatCol = *pRepeatCol;
+ nRepeatStartCol = pRepeatCol->aStart.Col();
+ nRepeatEndCol = pRepeatCol->aEnd .Col();
+ }
+ else
+ {
+ aAreaParam.bRepeatCol = FALSE;
+ nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
+ }
+
+ if ( pRepeatRow )
+ {
+ aAreaParam.bRepeatRow = TRUE;
+ aAreaParam.aRepeatRow = *pRepeatRow;
+ nRepeatStartRow = pRepeatRow->aStart.Row();
+ nRepeatEndRow = pRepeatRow->aEnd .Row();
+ }
+ else
+ {
+ aAreaParam.bRepeatRow = FALSE;
+ nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
+ }
+
+ //
+ // Seiten aufteilen
+ //
+
+ if (!bState)
+ {
+ nTabPages = CountPages(); // berechnet auch Zoom
+ nTotalPages = nTabPages;
+ nTotalPages += CountNotePages();
+ }
+ else
+ {
+ CalcPages(); // nur Umbrueche suchen
+ CountNotePages(); // Notizen zaehlen, auch wenn Seitenzahl schon bekannt
+ }
+
+ if (nDocPages)
+ aFieldData.nTotalPages = nDocPages;
+ else
+ aFieldData.nTotalPages = nTotalPages;
+
+ SetDateTime( Date(), Time() );
+
+ aFieldData.aTitle = pDocShell->GetTitle();
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if ( aFieldData.aLongDocName.Len() )
+ aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
+ else
+ aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
+
+ // Druckereinstellungen (Orientation, Paper) jetzt erst bei DoPrint
+}
+
+Size ScPrintFunc::GetDataSize() const
+{
+ Size aSize = aPageSize;
+ aSize.Width() -= nLeftMargin + nRightMargin;
+ aSize.Height() -= nTopMargin + nBottomMargin;
+ aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
+ return aSize;
+}
+
+void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
+{
+ rPhysSize = aPageSize;
+ rPhysSize.Width() -= nLeftMargin + nRightMargin;
+ rPhysSize.Height() -= nTopMargin + nBottomMargin;
+
+ rDocHdr = aHdr.nHeight;
+ rDocFtr = aFtr.nHeight;
+}
+
+void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
+{
+ aFieldData.aDate = rDate;
+ aFieldData.aTime = rTime;
+}
+
+void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
+ const Rectangle &rGrf, const Rectangle &rOut )
+{
+ const FASTBOOL bNotInside = !rOut.IsInside( rGrf );
+ if ( bNotInside )
+ {
+ pOut->Push();
+ pOut->IntersectClipRegion( rOut );
+ }
+
+ ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
+
+ if ( bNotInside )
+ pOut->Pop();
+}
+
+void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
+ const Rectangle &rOrg, const Rectangle &rOut )
+{
+ Size aGrfSize(0,0);
+ const Graphic *pGraphic = rBrush.GetGraphic();
+ SvxGraphicPosition ePos;
+ if ( pGraphic && pGraphic->IsSupportedGraphic() )
+ {
+ const MapMode aMapMM( MAP_100TH_MM );
+ if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
+ aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
+ else
+ aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode(), aMapMM );
+ ePos = rBrush.GetGraphicPos();
+ }
+ else
+ ePos = GPOS_NONE;
+
+ Point aPos;
+ Size aDrawSize = aGrfSize;
+
+ FASTBOOL bDraw = TRUE;
+// FASTBOOL bRetouche = TRUE;
+ switch ( ePos )
+ {
+ case GPOS_LT: aPos = rOrg.TopLeft();
+ break;
+ case GPOS_MT: aPos.Y() = rOrg.Top();
+ aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
+ break;
+ case GPOS_RT: aPos.Y() = rOrg.Top();
+ aPos.X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
+ aPos.X() = rOrg.Left();
+ break;
+ case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
+ aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
+ break;
+ case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
+ aPos.X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
+ aPos.X() = rOrg.Left();
+ break;
+ case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
+ aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
+ break;
+ case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
+ aPos.X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_AREA:
+ aPos = rOrg.TopLeft();
+ aDrawSize = rOrg.GetSize();
+// bRetouche = FALSE;
+ break;
+ case GPOS_TILED:
+ {
+ // #104004# use GraphicObject::DrawTiled instead of an own loop
+ // (pixel rounding is handled correctly, and a very small bitmap
+ // is duplicated into a bigger one for better performance)
+
+ GraphicObject aObject( *pGraphic );
+
+ if( pOut->GetPDFWriter() &&
+ (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
+ {
+ // #104004# For PDF export, every draw
+ // operation for bitmaps takes a noticeable
+ // amount of place (~50 characters). Thus,
+ // optimize between tile bitmap size and
+ // number of drawing operations here.
+ //
+ // A_out
+ // n_chars = k1 * ---------- + k2 * A_bitmap
+ // A_bitmap
+ //
+ // minimum n_chars is obtained for (derive for
+ // A_bitmap, set to 0, take positive
+ // solution):
+ // k1
+ // A_bitmap = Sqrt( ---- A_out )
+ // k2
+ //
+ // where k1 is the number of chars per draw
+ // operation, and k2 is the number of chars
+ // per bitmap pixel. This is approximately 50
+ // and 7 for current PDF writer, respectively.
+ //
+ const double k1( 50 );
+ const double k2( 7 );
+ const Size aSize( rOrg.GetSize() );
+ const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
+
+ aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
+ NULL, GRFMGR_DRAW_STANDARD,
+ ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
+ }
+ else
+ {
+ aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
+ }
+
+ bDraw = FALSE;
+// bRetouche = FALSE;
+ }
+ break;
+
+ case GPOS_NONE:
+ bDraw = FALSE;
+ break;
+
+ default: DBG_ASSERT( !pOut, "new Graphic position?" );
+ }
+ Rectangle aGrf( aPos,aDrawSize );
+ if ( bDraw && aGrf.IsOver( rOut ) )
+ {
+ lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
+ }
+}
+
+// Rahmen wird nach innen gezeichnet
+
+void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
+ const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
+ const SvxShadowItem* pShadow )
+{
+ //! direkte Ausgabe aus SvxBoxItem !!!
+
+ if (pBorderData)
+ if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
+ !pBorderData->GetRight() )
+ pBorderData = NULL;
+
+ if (!pBorderData && !pBackground && !pShadow)
+ return; // nichts zu tun
+
+ long nLeft = 0;
+ long nRight = 0;
+ long nTop = 0;
+ long nBottom = 0;
+
+ // aFrameRect - aussen um die Umrandung, ohne Schatten
+ if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
+ {
+ nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
+ nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
+ nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
+ nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
+ }
+ Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
+ Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
+
+ // Mitte der Umrandung, um Linien ueber OutputData zu zeichnen:
+ if (pBorderData)
+ {
+ nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
+ nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
+ nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
+ nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
+ }
+ long nEffHeight = nScrH - nTop - nBottom;
+ long nEffWidth = nScrW - nLeft - nRight;
+ if (nEffHeight<=0 || nEffWidth<=0)
+ return; // leer
+
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ BOOL bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ if ( pBackground && !bCellContrast )
+ {
+// Rectangle aBackRect( Point(nScrX+nLeft, nScrY+nTop), Size(nEffWidth,nEffHeight) );
+ if (pBackground->GetGraphicPos() != GPOS_NONE)
+ {
+ OutputDevice* pRefDev;
+ if ( bIsRender )
+ pRefDev = pDev; // don't use printer for PDF
+ else
+ pRefDev = pDoc->GetPrinter(); // use printer also for preview
+
+ lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect );
+ }
+ else
+ {
+ pDev->SetFillColor(pBackground->GetColor());
+ pDev->SetLineColor();
+ pDev->DrawRect(aFrameRect);
+ }
+ }
+
+ if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
+ {
+ if ( bCellContrast )
+ pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ else
+ pDev->SetFillColor(pShadow->GetColor());
+ pDev->SetLineColor();
+ long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
+ long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
+ switch (pShadow->GetLocation())
+ {
+ case SVX_SHADOW_TOPLEFT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
+ aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
+ aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
+ break;
+ case SVX_SHADOW_TOPRIGHT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
+ aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Right(), aFrameRect.Top()-nShadowY,
+ aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
+ break;
+ case SVX_SHADOW_BOTTOMLEFT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
+ aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
+ aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
+ break;
+ case SVX_SHADOW_BOTTOMRIGHT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
+ aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Right(), aFrameRect.Top()+nShadowY,
+ aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if (pBorderData)
+ {
+ ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
+ pBorderDoc->InitUndo( pDoc, 0,0, TRUE,TRUE );
+ if (pBorderData)
+ pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
+
+ ScTableInfo aTabInfo;
+ pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
+ nScaleX, nScaleY, FALSE, FALSE );
+ DBG_ASSERT(aTabInfo.mnArrCount,"nArrCount == 0");
+
+ aTabInfo.mpRowInfo[1].nHeight = (USHORT) nEffHeight;
+ aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
+ aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (USHORT) nEffWidth;
+
+ ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
+ nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
+ aOutputData.SetUseStyleColor( bUseStyleColor );
+
+// pDev->SetMapMode(aTwipMode);
+
+ if (pBorderData)
+ aOutputData.DrawFrame();
+
+ delete pBorderDoc;
+ }
+}
+
+void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
+{
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+ SCCOL nCol;
+
+ long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
+ long nEndY = nScrY + nHeight - nOneY;
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
+ }
+ else
+ nPosX -= nOneX;
+ long nPosY = nScrY - nOneY;
+ String aText;
+
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ USHORT nDocW = pDoc->GetColWidth( nCol, nPrintTab );
+ if (nDocW)
+ {
+ long nWidth = (long) (nDocW * nScaleX);
+ long nEndX = nPosX + nWidth * nLayoutSign;
+
+ pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
+
+ aText = ::ScColToAlpha( nCol);
+ long nTextWidth = pDev->GetTextWidth(aText);
+ long nTextHeight = pDev->GetTextHeight();
+ long nAddX = ( nWidth - nTextWidth ) / 2;
+ long nAddY = ( nHeight - nTextHeight ) / 2;
+ long nTextPosX = nPosX+nAddX;
+ if ( bLayoutRTL )
+ nTextPosX -= nWidth;
+ pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
+
+ nPosX = nEndX;
+ }
+ }
+}
+
+void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
+{
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+
+ long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
+ long nEndX = nScrX + nWidth;
+ long nPosX = nScrX;
+ if ( !bLayoutRTL )
+ {
+ nEndX -= nOneX;
+ nPosX -= nOneX;
+ }
+ long nPosY = nScrY - nOneY;
+ String aText;
+
+ for (SCROW nRow=nY1; nRow<=nY2; nRow++)
+ {
+ USHORT nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
+ if (nDocH)
+ {
+ long nHeight = (long) (nDocH * nScaleY);
+ long nEndY = nPosY + nHeight;
+
+ pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
+
+ aText = String::CreateFromInt32( nRow+1 );
+ long nTextWidth = pDev->GetTextWidth(aText);
+ long nTextHeight = pDev->GetTextHeight();
+ long nAddX = ( nWidth - nTextWidth ) / 2;
+ long nAddY = ( nHeight - nTextHeight ) / 2;
+ pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
+
+ nPosY = nEndY;
+ }
+ }
+}
+
+void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
+ BOOL bRepCol, ScPreviewLocationData& rLocationData )
+{
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
+ long nEndY = nScrY + nHeight - nOneY;
+
+ long nPosX = nScrX - nOneX;
+ for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
+ {
+ USHORT nDocW = pDoc->GetColWidth( nCol, nPrintTab );
+ if (nDocW)
+ nPosX += (long) (nDocW * nScaleX);
+ }
+ Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
+ rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
+}
+
+void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
+ BOOL bRepRow, ScPreviewLocationData& rLocationData )
+{
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+
+ long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
+ long nEndX = nScrX + nWidth;
+ if ( !bLayoutRTL )
+ nEndX -= nOneX;
+
+ long nPosY = nScrY - nOneY;
+ nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
+ Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
+ rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
+}
+
+void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ long nScrX, long nScrY, BOOL bRepCol, BOOL bRepRow,
+ ScPreviewLocationData& rLocationData )
+{
+ // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
+
+ Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
+ long nLogStX = aLogPos.X();
+ long nLogStY = aLogPos.Y();
+
+ SCCOL nCol;
+ Point aTwipOffset;
+ for (nCol=0; nCol<nX1; nCol++)
+ aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
+ aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
+
+ Point aMMOffset( aTwipOffset );
+ aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
+ aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
+ aMMOffset += Point( nLogStX, nLogStY );
+ MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
+
+ // get pixel rectangle
+
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ long nPosX = nScrX - nOneX;
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ USHORT nDocW = pDoc->GetColWidth( nCol, nPrintTab );
+ if (nDocW)
+ nPosX += (long) (nDocW * nScaleX);
+ }
+
+ long nPosY = nScrY - nOneY;
+ nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
+ Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
+ rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
+ bRepCol, bRepRow, aDrawMapMode );
+}
+
+void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ long nScrX, long nScrY,
+ BOOL bShLeft, BOOL bShTop, BOOL bShRight, BOOL bShBottom )
+{
+ // #i47547# nothing to do if the end of the print area is before the end of
+ // the repeat columns/rows (don't use negative size for ScOutputData)
+ if ( nX2 < nX1 || nY2 < nY1 )
+ return;
+
+ //! Flag bei FillInfo uebergeben !!!!!
+ ScRange aERange;
+ BOOL bEmbed = pDoc->IsEmbedded();
+ if (bEmbed)
+ {
+ pDoc->GetEmbedded(aERange);
+ pDoc->ResetEmbedded();
+ }
+
+ Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
+ long nLogStX = aPos.X();
+ long nLogStY = aPos.Y();
+
+ // Daten zusammenstellen
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
+ nScaleX, nScaleY, TRUE, aTableParam.bFormulas );
+ lcl_HidePrint( aTabInfo, nX1, nX2 );
+
+ if (bEmbed)
+ pDoc->SetEmbedded(aERange);
+
+ ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
+
+ // #114135#
+ aOutputData.SetDrawView( pDrawView );
+
+ // test if all paint parts are hidden, then a paint is not necessary at all
+ const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
+ const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
+ && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
+
+ if(!bHideAllDrawingLayer)
+ {
+ pDev->SetMapMode(aLogicMode);
+ // hier kein Clipping setzen (Mapmode wird verschoben)
+
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
+ }
+
+ pDev->SetMapMode(aOffsetMode);
+
+ aOutputData.SetShowFormulas( aTableParam.bFormulas );
+ aOutputData.SetShowNullValues( aTableParam.bNullVals );
+ aOutputData.SetUseStyleColor( bUseStyleColor );
+
+ Color aGridColor( COL_BLACK );
+ if ( bUseStyleColor )
+ aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ aOutputData.SetGridColor( aGridColor );
+
+ if ( !pPrinter )
+ {
+ OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ Fraction aPrintFrac( nZoom, 100 ); // ohne nManualZoom
+ // MapMode, wie er beim Drucken herauskommen wuerde:
+ pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
+
+ // when rendering (PDF), don't use printer as ref device, but printer's MapMode
+ // has to be set anyway, as charts still use it (#106409#)
+ if ( !bIsRender )
+ aOutputData.SetRefDevice( pRefDev );
+ }
+
+// aOutputData.SetMetaFileMode(TRUE);
+ if( aTableParam.bCellContent )
+ aOutputData.DrawBackground();
+
+ pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) );
+ pDev->SetClipRegion();
+
+// aOutputData.SetMetaFileMode(FALSE);
+ if( aTableParam.bCellContent )
+ {
+ aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
+ aOutputData.DrawFrame();
+ aOutputData.DrawStrings();
+
+ // pDev->SetMapMode(aLogicMode);
+ aOutputData.DrawEdit(FALSE);
+ }
+
+// pDev->SetMapMode(aOffsetMode);
+ if (aTableParam.bGrid)
+ aOutputData.DrawGrid( TRUE, FALSE ); // keine Seitenumbrueche
+
+/*!!!!!!!!!!! Notizen in Tabelle markieren ??????????????????????????
+
+ if (aTableParam.bNotes)
+ {
+ pDev->SetMapMode(aOffsetMode);
+ aOutputData.PrintNoteMarks(aNotePosList);
+ pDev->SetMapMode(aLogicMode);
+ }
+*/
+
+ aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
+
+// pDev->SetMapMode(aDrawMode);
+
+ // test if all paint parts are hidden, then a paint is not necessary at all
+ if(!bHideAllDrawingLayer)
+ {
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
+ }
+
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
+ aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
+}
+
+BOOL ScPrintFunc::IsMirror( long nPageNo ) // Raender spiegeln ?
+{
+ SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
+ return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
+}
+
+BOOL ScPrintFunc::IsLeft( long nPageNo ) // linke Fussnoten ?
+{
+ SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
+ BOOL bLeft;
+ if (eUsage == SVX_PAGE_LEFT)
+ bLeft = TRUE;
+ else if (eUsage == SVX_PAGE_RIGHT)
+ bLeft = FALSE;
+ else
+ bLeft = (nPageNo & 1) != 0;
+ return bLeft;
+}
+
+void ScPrintFunc::MakeTableString()
+{
+ pDoc->GetName( nPrintTab, aFieldData.aTabName );
+}
+
+void ScPrintFunc::MakeEditEngine()
+{
+ if (!pEditEngine)
+ {
+ // can't use document's edit engine pool here,
+ // because pool must have twips as default metric
+ pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), TRUE );
+
+ pEditEngine->EnableUndo(FALSE);
+ pEditEngine->SetRefDevice( pDev );
+ pEditEngine->SetWordDelimiters(
+ ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
+ pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
+ pEditEngine->EnableAutoColor( bUseStyleColor );
+
+ // Default-Set fuer Ausrichtung
+ pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
+
+ const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
+ rPattern.FillEditItemSet( pEditDefaults );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ // #69193# dont use font color, because background color is not used
+ //! there's no way to set the background for note pages
+ pEditDefaults->ClearItem( EE_CHAR_COLOR );
+ if (ScGlobal::IsSystemRTL())
+ pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
+ }
+
+ pEditEngine->SetData( aFieldData ); // Seitennummer etc. setzen
+}
+
+// nStartY = logic
+void ScPrintFunc::PrintHF( long nPageNo, BOOL bHeader, long nStartY,
+ BOOL bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
+
+ pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips
+
+ BOOL bLeft = IsLeft(nPageNo) && !rParam.bShared;
+ const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
+
+ long nLineStartX = aPageRect.Left() + rParam.nLeft;
+ long nLineEndX = aPageRect.Right() - rParam.nRight;
+ long nLineWidth = nLineEndX - nLineStartX + 1;
+
+ // Edit-Engine
+
+ Point aStart( nLineStartX, nStartY );
+ Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
+ if ( rParam.pBorder )
+ {
+ long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
+ long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
+ aStart.X() += nLeft;
+ aStart.Y() += nTop;
+ aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
+ aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
+ }
+
+ if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
+ {
+ long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
+ long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
+ aStart.X() += nLeft;
+ aStart.Y() += nTop;
+ aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
+ aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
+ }
+
+ aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
+ MakeEditEngine();
+
+ pEditEngine->SetPaperSize(aPaperSize);
+ const EditTextObject* pObject;
+
+ // Rahmen / Hintergrund
+
+ Point aBorderStart( nLineStartX, nStartY );
+ Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
+ if ( rParam.bDynamic )
+ {
+ // hier nochmal anpassen, wegen geraden/ungeraden Kopf/Fusszeilen
+ // und evtl. anderen Umbruechen durch Variablen (Seitennummer etc.)
+
+ long nMaxHeight = 0;
+ nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
+ if (rParam.pBorder)
+ nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
+ lcl_LineTotal( rParam.pBorder->GetBottom() ) +
+ rParam.pBorder->GetDistance(BOX_LINE_TOP) +
+ rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
+ if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
+ nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
+ rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
+
+ if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
+ nMaxHeight = rParam.nManHeight-rParam.nDistance; // eingestelltes Minimum
+
+ aBorderSize.Height() = nMaxHeight;
+ }
+
+ if ( bDoPrint )
+ {
+ double nOldScaleX = nScaleX;
+ double nOldScaleY = nScaleY;
+ nScaleX = nScaleY = 1.0; // direkt in Twips ausgeben
+ DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
+ rParam.pBorder, rParam.pBack, rParam.pShadow );
+ nScaleX = nOldScaleX;
+ nScaleY = nOldScaleY;
+
+ // Clipping fuer Text
+
+ pDev->SetClipRegion( Rectangle( aStart, aPaperSize ) );
+
+ // links
+
+ pObject = pHFItem->GetLeftArea();
+ if (pObject)
+ {
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, FALSE );
+ Point aDraw = aStart;
+ long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
+ if (nDif > 0)
+ aDraw.Y() += nDif / 2;
+ pEditEngine->Draw( pDev, aDraw, 0 );
+ }
+
+ // Mitte
+
+ pObject = pHFItem->GetCenterArea();
+ if (pObject)
+ {
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, FALSE );
+ Point aDraw = aStart;
+ long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
+ if (nDif > 0)
+ aDraw.Y() += nDif / 2;
+ pEditEngine->Draw( pDev, aDraw, 0 );
+ }
+
+ // rechts
+
+ pObject = pHFItem->GetRightArea();
+ if (pObject)
+ {
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, FALSE );
+ Point aDraw = aStart;
+ long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
+ if (nDif > 0)
+ aDraw.Y() += nDif / 2;
+ pEditEngine->Draw( pDev, aDraw, 0 );
+ }
+
+ pDev->SetClipRegion();
+ }
+
+ if ( pLocationData )
+ {
+ Rectangle aHeaderRect( aBorderStart, aBorderSize );
+ pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
+ }
+}
+
+long ScPrintFunc::DoNotes( long nNoteStart, BOOL bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ if (bDoPrint)
+ pDev->SetMapMode(aTwipMode);
+
+ MakeEditEngine();
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+ pEditEngine->SetDefaults( *pEditDefaults );
+
+ Font aMarkFont;
+ ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
+ ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
+//? aMarkFont.SetWeight( WEIGHT_BOLD );
+ pDev->SetFont( aMarkFont );
+ long nMarkLen = pDev->GetTextWidth(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:")));
+ // ohne Space, weil's eh selten so weit kommt
+
+ Size aDataSize = aPageRect.GetSize();
+ if ( nMarkLen > aDataSize.Width() / 2 ) // alles viel zu klein?
+ nMarkLen = aDataSize.Width() / 2; // Seite bruederlich aufteilen
+ aDataSize.Width() -= nMarkLen;
+
+ pEditEngine->SetPaperSize( aDataSize );
+ long nPosX = aPageRect.Left() + nMarkLen;
+ long nPosY = aPageRect.Top();
+
+ long nCount = 0;
+ BOOL bOk;
+ do
+ {
+ bOk = FALSE;
+ ScAddress* pPos = (ScAddress*) aNotePosList.GetObject( nNoteStart+nCount );
+ if (pPos)
+ {
+ ScBaseCell* pCell = pDoc->GetCell( *pPos);
+ if( const ScPostIt* pNote = pCell->GetNote() )
+ {
+ if(const EditTextObject *pEditText = pNote->GetEditTextObject())
+ pEditEngine->SetText(*pEditText);
+ long nTextHeight = pEditEngine->GetTextHeight();
+ if ( nPosY + nTextHeight < aPageRect.Bottom() )
+ {
+ if (bDoPrint)
+ {
+ pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
+
+ String aMarkStr;
+ pPos->Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
+ aMarkStr += ':';
+
+ // Zellposition auch per EditEngine, damit die Position stimmt
+ pEditEngine->SetText(aMarkStr);
+ pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
+ }
+
+ if ( pLocationData )
+ {
+ Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
+ pLocationData->AddNoteText( aTextRect, *pPos );
+ Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
+ pLocationData->AddNoteMark( aMarkRect, *pPos );
+ }
+
+ nPosY += nTextHeight;
+ nPosY += 200; // Abstand
+ ++nCount;
+ bOk = TRUE;
+ }
+ }
+ }
+ }
+ while (bOk);
+
+ return nCount;
+}
+
+long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, BOOL bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ if ( nNoteStart >= (long) aNotePosList.Count() || !aTableParam.bNotes )
+ return 0;
+
+ if ( bDoPrint && bClearWin )
+ {
+ //! mit PrintPage zusammenfassen !!!
+
+ Color aBackgroundColor( COL_WHITE );
+ if ( bUseStyleColor )
+ aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ pDev->SetMapMode(aOffsetMode);
+ pDev->SetLineColor();
+ pDev->SetFillColor(aBackgroundColor);
+ pDev->DrawRect(Rectangle(Point(),
+ Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
+ (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
+ }
+
+
+ // aPageRect auf linke / rechte Seiten anpassen
+
+ Rectangle aTempRect = Rectangle( Point(), aPageSize );
+ if (IsMirror(nPageNo))
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
+ }
+ else
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
+ }
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "StartPage does not exist anymore" );
+ // pPrinter->StartPage();
+ }
+
+ if ( bDoPrint || pLocationData )
+ {
+ // Kopf- und Fusszeilen
+
+ if (aHdr.bEnable)
+ {
+ long nHeaderY = aPageRect.Top()-aHdr.nHeight;
+ PrintHF( nPageNo, TRUE, nHeaderY, bDoPrint, pLocationData );
+ }
+ if (aFtr.bEnable)
+ {
+ long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
+ PrintHF( nPageNo, FALSE, nFooterY, bDoPrint, pLocationData );
+ }
+ }
+
+ long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "EndPage does not exist anymore" );
+ // pPrinter->EndPage();
+ }
+
+ return nCount;
+}
+
+void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ BOOL bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ // nPageNo is the page number within all sheets of one "start page" setting
+
+ if ( bClearWin && bDoPrint )
+ {
+ // muss genau zum Zeichnen des Rahmens in preview.cxx passen !!!
+
+ Color aBackgroundColor( COL_WHITE );
+ if ( bUseStyleColor )
+ aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ pDev->SetMapMode(aOffsetMode);
+ pDev->SetLineColor();
+ pDev->SetFillColor(aBackgroundColor);
+ pDev->DrawRect(Rectangle(Point(),
+ Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
+ (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
+ }
+
+
+ // aPageRect auf linke / rechte Seiten anpassen
+
+ Rectangle aTempRect = Rectangle( Point(), aPageSize );
+ if (IsMirror(nPageNo))
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
+ }
+ else
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
+ }
+
+ if ( aAreaParam.bRepeatCol )
+ if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
+ nX1 = nRepeatEndCol + 1;
+ BOOL bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
+ if ( aAreaParam.bRepeatRow )
+ if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
+ nY1 = nRepeatEndRow + 1;
+ BOOL bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
+
+ // use new object hide flags in SdrPaintView
+ if(pDrawView)
+ {
+ pDrawView->setHideOle(!aTableParam.bObjects);
+ pDrawView->setHideChart(!aTableParam.bCharts);
+ pDrawView->setHideDraw(!aTableParam.bDrawings);
+ pDrawView->setHideFormControl(!aTableParam.bDrawings);
+ }
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "StartPage does not exist anymore" );
+ // pPrinter->StartPage();
+ }
+
+ // Kopf- und Fusszeilen (ohne Zentrierung)
+
+ if (aHdr.bEnable)
+ {
+ long nHeaderY = aPageRect.Top()-aHdr.nHeight;
+ PrintHF( nPageNo, TRUE, nHeaderY, bDoPrint, pLocationData );
+ }
+ if (aFtr.bEnable)
+ {
+ long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
+ PrintHF( nPageNo, FALSE, nFooterY, bDoPrint, pLocationData );
+ }
+
+ // Position ( Raender / zentrieren )
+
+ long nLeftSpace = aPageRect.Left(); // Document-Twips
+ long nTopSpace = aPageRect.Top();
+ if ( bCenterHor || bLayoutRTL )
+ {
+ long nDataWidth = 0;
+ SCCOL i;
+ for (i=nX1; i<=nX2; i++)
+ nDataWidth += pDoc->GetColWidth( i,nPrintTab );
+ if (bDoRepCol)
+ for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
+ nDataWidth += pDoc->GetColWidth( i,nPrintTab );
+ if (aTableParam.bHeaders)
+ nDataWidth += (long) PRINT_HEADER_WIDTH;
+ if (pBorderItem)
+ nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
+ pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
+ pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
+ if ( bCenterHor )
+ {
+ nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
+ if (pBorderItem)
+ nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
+ }
+ else if ( bLayoutRTL )
+ nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
+ }
+ if ( bCenterVer )
+ {
+ long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
+ if (bDoRepRow)
+ nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
+ nRepeatEndRow, nPrintTab);
+ if (aTableParam.bHeaders)
+ nDataHeight += (long) PRINT_HEADER_HEIGHT;
+ if (pBorderItem)
+ nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
+ pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
+ pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
+ nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
+ if (pBorderItem)
+ nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
+ }
+
+ // calculate sizes of the elements for partitioning
+ // (header, repeat, data)
+
+ long nHeaderWidth = 0;
+ long nHeaderHeight = 0;
+ long nRepeatWidth = 0;
+ long nRepeatHeight = 0;
+ long nContentWidth = 0; // scaled - not the same as nDataWidth above
+ long nContentHeight = 0;
+ if (aTableParam.bHeaders)
+ {
+ nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
+ nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
+ }
+ if (bDoRepCol)
+ for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
+ nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
+ if (bDoRepRow)
+ nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
+ nRepeatEndRow, nPrintTab, nScaleY);
+ for (SCCOL i=nX1; i<=nX2; i++)
+ nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
+ nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
+ nScaleY);
+
+ // partition the page
+
+ long nStartX = ((long) ( nLeftSpace * nScaleX ));
+ long nStartY = ((long) ( nTopSpace * nScaleY ));
+// nStartX -= aOffset.X(); // schon im MapMode
+// nStartY -= aOffset.Y();
+
+ long nInnerStartX = nStartX;
+ long nInnerStartY = nStartY;
+ if (pBorderItem)
+ {
+ nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
+ pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
+ nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
+ pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
+ }
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ {
+ nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
+ nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
+ }
+
+ if ( bLayoutRTL )
+ {
+ // arrange elements starting from the right edge
+ nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
+
+ // make rounding easier so the elements are really next to each other in preview
+ Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
+ long nOffsetOneX = aOffsetOnePixel.Width();
+ nInnerStartX += nOffsetOneX / 2;
+ }
+
+ long nFrameStartX = nInnerStartX;
+ long nFrameStartY = nInnerStartY;
+
+ long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
+ long nRepStartY = nInnerStartY + nHeaderHeight;
+ long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
+ long nDataY = nRepStartY + nRepeatHeight;
+ long nEndX = nDataX + nContentWidth * nLayoutSign;
+ long nEndY = nDataY + nContentHeight;
+ long nFrameEndX = nEndX;
+ long nFrameEndY = nEndY;
+
+ if ( bLayoutRTL )
+ {
+ // each element's start position is its left edge
+ //! subtract one pixel less?
+ nInnerStartX -= nHeaderWidth; // used for header
+ nRepStartX -= nRepeatWidth;
+ nDataX -= nContentWidth;
+
+ // continue right of the main elements again
+ nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
+ }
+
+ // Seiten-Rahmen / Hintergrund
+
+ //! nEndX/Y anpassen
+
+ long nBorderEndX = nEndX;
+ long nBorderEndY = nEndY;
+ if (pBorderItem)
+ {
+ nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
+ pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
+ nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
+ pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
+ }
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ {
+ nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
+ nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
+ }
+
+ if ( bDoPrint )
+ {
+ pDev->SetMapMode( aOffsetMode );
+ DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
+ pBorderItem, pBackgroundItem, pShadowItem );
+
+ pDev->SetMapMode( aTwipMode );
+ }
+
+ pDev->SetMapMode( aOffsetMode );
+
+ // Wiederholungszeilen/Spalten ausgeben
+
+ if (bDoRepCol && bDoRepRow)
+ {
+ if ( bDoPrint )
+ PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
+ nRepStartX,nRepStartY, TRUE,TRUE,FALSE,FALSE );
+ if ( pLocationData )
+ LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
+ nRepStartX,nRepStartY, TRUE,TRUE, *pLocationData );
+ }
+ if (bDoRepCol)
+ {
+ if ( bDoPrint )
+ PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
+ TRUE,!bDoRepRow,FALSE,TRUE );
+ if ( pLocationData )
+ LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, TRUE,FALSE, *pLocationData );
+ }
+ if (bDoRepRow)
+ {
+ if ( bDoPrint )
+ PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
+ !bDoRepCol,TRUE,TRUE,FALSE );
+ if ( pLocationData )
+ LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, FALSE,TRUE, *pLocationData );
+ }
+
+ // Daten ausgeben
+
+ if ( bDoPrint )
+ PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,TRUE,TRUE );
+ if ( pLocationData )
+ LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, FALSE,FALSE, *pLocationData );
+
+ // Spalten-/Zeilenkoepfe ausgeben
+ // nach den Daten (ueber evtl. weitergezeichneten Schatten)
+
+ Color aGridColor( COL_BLACK );
+ if ( bUseStyleColor )
+ aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ if (aTableParam.bHeaders)
+ {
+ if ( bDoPrint )
+ {
+ pDev->SetLineColor( aGridColor );
+ pDev->SetFillColor();
+ pDev->SetMapMode(aOffsetMode);
+ }
+
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ Font aFont;
+ ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
+ aPattern.GetFont( aFont, eColorMode, pDev );
+ pDev->SetFont( aFont );
+
+ if (bDoRepCol)
+ {
+ if ( bDoPrint )
+ PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
+ if ( pLocationData )
+ LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, TRUE, *pLocationData );
+ }
+ if ( bDoPrint )
+ PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
+ if ( pLocationData )
+ LocateColHdr( nX1,nX2, nDataX,nInnerStartY, FALSE, *pLocationData );
+ if (bDoRepRow)
+ {
+ if ( bDoPrint )
+ PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
+ if ( pLocationData )
+ LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, TRUE, *pLocationData );
+ }
+ if ( bDoPrint )
+ PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
+ if ( pLocationData )
+ LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, FALSE, *pLocationData );
+ }
+
+ // einfacher Rahmen
+
+ if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ long nLeftX = nFrameStartX;
+ long nTopY = nFrameStartY - nOneY;
+ long nRightX = nFrameEndX;
+ long nBottomY = nFrameEndY - nOneY;
+ if ( !bLayoutRTL )
+ {
+ nLeftX -= nOneX;
+ nRightX -= nOneX;
+ }
+ pDev->SetMapMode(aOffsetMode);
+ pDev->SetLineColor( aGridColor );
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
+ // nEndX/Y ohne Rahmen-Anpassung
+ }
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "EndPage does not exist anymore" );
+ // pPrinter->EndPage();
+ }
+
+ aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
+ bSourceRangeValid = TRUE;
+}
+
+void ScPrintFunc::SetOffset( const Point& rOfs )
+{
+ aSrcOffset = rOfs;
+}
+
+void ScPrintFunc::SetManualZoom( USHORT nNewZoom )
+{
+ nManualZoom = nNewZoom;
+}
+
+void ScPrintFunc::SetClearFlag( BOOL bFlag )
+{
+ bClearWin = bFlag;
+}
+
+void ScPrintFunc::SetUseStyleColor( BOOL bFlag )
+{
+ bUseStyleColor = bFlag;
+ if (pEditEngine)
+ pEditEngine->EnableAutoColor( bUseStyleColor );
+}
+
+void ScPrintFunc::SetRenderFlag( BOOL bFlag )
+{
+ bIsRender = bFlag; // set when using XRenderable (PDF)
+}
+
+void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
+{
+ aTableParam.bCellContent = false;
+ aTableParam.bNotes = false;
+ aTableParam.bGrid = false;
+ aTableParam.bHeaders = false;
+ aTableParam.bFormulas = false;;
+ aTableParam.bNullVals = false;;
+ aTableParam.bNullVals = false;;
+}
+
+//
+// UpdatePages wird nur von aussen gerufen, um die Umbrueche fuer die Anzeige
+// richtig zu setzen - immer ohne UserArea
+//
+
+BOOL ScPrintFunc::UpdatePages()
+{
+ if (!pParamSet)
+ return FALSE;
+
+ // Zoom
+
+ nZoom = 100;
+ if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
+ nZoom = ZOOM_MIN; // stimmt fuer Umbrueche
+ else if (aTableParam.bScaleAll)
+ {
+ nZoom = aTableParam.nScaleAll;
+ if ( nZoom <= ZOOM_MIN )
+ nZoom = ZOOM_MIN;
+ }
+
+ String aName = pDoc->GetPageStyle( nPrintTab );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
+ {
+ // Wiederholungszeilen / Spalten
+ pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
+
+ // Umbrueche setzen
+ ResetBreaks(nTab);
+ pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
+ }
+
+ return TRUE;
+}
+
+long ScPrintFunc::CountPages() // setzt auch nPagesX, nPagesY
+{
+ BOOL bAreaOk = FALSE;
+
+ if (pDoc->HasTable( nPrintTab ))
+ {
+ if (aAreaParam.bPrintArea) // Druckbereich angegeben?
+ {
+ if ( bPrintCurrentTable )
+ {
+ ScRange& rRange = aAreaParam.aPrintArea;
+
+ // hier kein Vergleich der Tabellen mehr, die Area gilt immer fuer diese Tabelle
+ // wenn hier verglichen werden soll, muss die Tabelle der Druckbereiche beim
+ // Einfuegen von Tabellen etc. angepasst werden !
+
+ nStartCol = rRange.aStart.Col();
+ nStartRow = rRange.aStart.Row();
+ nEndCol = rRange.aEnd .Col();
+ nEndRow = rRange.aEnd .Row();
+ bAreaOk = AdjustPrintArea(FALSE); // begrenzen
+ }
+ else
+ bAreaOk = FALSE;
+ }
+ else // aus Dokument suchen
+ bAreaOk = AdjustPrintArea(TRUE);
+ }
+
+ if (bAreaOk)
+ {
+ long nPages = 0;
+ size_t nY;
+ if (bMultiArea)
+ {
+ USHORT nRCount = pDoc->GetPrintRangeCount( nPrintTab );
+ for (USHORT i=0; i<nRCount; i++)
+ {
+ CalcZoom(i);
+ if ( aTableParam.bSkipEmpty )
+ for (nY=0; nY<nPagesY; nY++)
+ nPages += pPageRows[nY].CountVisible();
+ else
+ nPages += ((long) nPagesX) * nPagesY;
+ if ( pPageData )
+ FillPageData();
+ }
+ }
+ else
+ {
+ CalcZoom(RANGENO_NORANGE); // Zoom berechnen
+ if ( aTableParam.bSkipEmpty )
+ for (nY=0; nY<nPagesY; nY++)
+ nPages += pPageRows[nY].CountVisible();
+ else
+ nPages += ((long) nPagesX) * nPagesY;
+ if ( pPageData )
+ FillPageData();
+ }
+ return nPages;
+ }
+ else
+ {
+// nZoom = 100; // nZoom auf letztem Wert stehenlassen !!!
+ nPagesX = nPagesY = nTotalY = 0;
+ return 0;
+ }
+}
+
+long ScPrintFunc::CountNotePages()
+{
+ if ( !aTableParam.bNotes || !bPrintCurrentTable )
+ return 0;
+
+ long nCount=0;
+ SCCOL nCol;
+ SCROW nRow;
+
+ BOOL bError = FALSE;
+ if (!aAreaParam.bPrintArea)
+ bError = !AdjustPrintArea(TRUE); // komplett aus Dok suchen
+
+ USHORT nRepeats = 1; // wie oft durchgehen ?
+ if (bMultiArea)
+ nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
+ if (bError)
+ nRepeats = 0;
+
+ for (USHORT nStep=0; nStep<nRepeats; nStep++)
+ {
+ BOOL bDoThis = TRUE;
+ if (bMultiArea) // alle Areas durchgehen
+ {
+ const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
+ if ( pThisRange )
+ {
+ nStartCol = pThisRange->aStart.Col();
+ nStartRow = pThisRange->aStart.Row();
+ nEndCol = pThisRange->aEnd .Col();
+ nEndRow = pThisRange->aEnd .Row();
+ bDoThis = AdjustPrintArea(FALSE);
+ }
+ }
+
+ if (bDoThis)
+ {
+ ScHorizontalCellIterator aIter( pDoc, nPrintTab, nStartCol,nStartRow, nEndCol,nEndRow );
+ ScBaseCell* pCell = aIter.GetNext( nCol, nRow );
+ while (pCell)
+ {
+ if (pCell->HasNote())
+ {
+ aNotePosList.Insert( new ScAddress( nCol,nRow,nPrintTab ), LIST_APPEND );
+ ++nCount;
+ }
+
+ pCell = aIter.GetNext( nCol, nRow );
+ }
+ }
+ }
+
+ long nPages = 0;
+ long nNoteNr = 0;
+ long nNoteAdd;
+ do
+ {
+ nNoteAdd = PrintNotes( nPages, nNoteNr, FALSE, NULL );
+ if (nNoteAdd)
+ {
+ nNoteNr += nNoteAdd;
+ ++nPages;
+ }
+ }
+ while (nNoteAdd);
+
+ return nPages;
+}
+
+void ScPrintFunc::InitModes() // aus nZoom etc. die MapModes setzen
+{
+ aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
+
+ long nEffZoom = nZoom * (long) nManualZoom;
+
+// nScaleX = nScaleY = 1.0; // Ausgabe in Twips
+ nScaleX = nScaleY = HMM_PER_TWIPS; // Ausgabe in 1/100 mm
+
+ Fraction aZoomFract( nEffZoom,10000 );
+ Fraction aHorFract = aZoomFract;
+
+ if ( !pPrinter && !bIsRender ) // adjust scale for preview
+ {
+ double nFact = pDocShell->GetOutputFactor();
+ aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
+ }
+
+ aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
+
+ Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
+ aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
+
+ Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
+ aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
+}
+
+//--------------------------------------------------------------------
+
+void ScPrintFunc::ApplyPrintSettings()
+{
+ if ( pPrinter )
+ {
+ //
+ // Printer zum Drucken umstellen
+ //
+
+ Size aEnumSize = aPageSize;
+
+
+ pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
+ if ( bLandscape )
+ {
+ // landscape is always interpreted as a rotation by 90 degrees !
+ // this leads to non WYSIWIG but at least it prints!
+ // #i21775#
+ long nTemp = aEnumSize.Width();
+ aEnumSize.Width() = aEnumSize.Height();
+ aEnumSize.Height() = nTemp;
+ }
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, TRUE );
+ USHORT nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
+
+ pPrinter->SetPaper( ePaper );
+ if ( PAPER_USER == ePaper )
+ {
+ MapMode aPrinterMode = pPrinter->GetMapMode();
+ MapMode aLocalMode( MAP_TWIP );
+ pPrinter->SetMapMode( aLocalMode );
+ pPrinter->SetPaperSizeUser( aEnumSize );
+ pPrinter->SetMapMode( aPrinterMode );
+ }
+
+ pPrinter->SetPaperBin( nPaperBin );
+ }
+}
+
+//--------------------------------------------------------------------
+// rPageRanges = Range fuer alle Tabellen
+// nStartPage = in rPageRanges beginnen bei nStartPage
+// nDisplayStart = lfd. Nummer fuer Anzeige der Seitennummer
+
+long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
+ long nStartPage, long nDisplayStart, BOOL bDoPrint,
+ SfxProgress* pProgress, ScPreviewLocationData* pLocationData )
+{
+ DBG_ASSERT(pDev,"Device == NULL");
+ if (!pParamSet)
+ return 0;
+
+ if ( pPrinter && bDoPrint )
+ ApplyPrintSettings();
+
+ //--------------------------------------------------------------------
+
+ InitModes();
+ if ( pLocationData )
+ {
+ pLocationData->SetCellMapMode( aOffsetMode );
+ pLocationData->SetPrintTab( nPrintTab );
+ }
+
+ MakeTableString();
+
+ if ( pProgress )
+ pProgress->SetText( String( ScResId( SCSTR_STAT_PRINT ) ) );
+
+ //--------------------------------------------------------------------
+
+ long nPageNo = 0;
+ long nPrinted = 0;
+ long nEndPage = rPageRanges.GetTotalRange().Max();
+
+ USHORT nRepeats = 1; // wie oft durchgehen ?
+ if (bMultiArea)
+ nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
+ for (USHORT nStep=0; nStep<nRepeats; nStep++)
+ {
+ if (bMultiArea) // Bereich neu belegen ?
+ {
+ CalcZoom(nStep); // setzt auch nStartCol etc. neu
+ InitModes();
+ }
+
+ SCCOL nX1;
+ SCROW nY1;
+ SCCOL nX2;
+ SCROW nY2;
+ size_t nCountX;
+ size_t nCountY;
+
+ if (aTableParam.bTopDown) // von oben nach unten
+ {
+ nX1 = nStartCol;
+ for (nCountX=0; nCountX<nPagesX; nCountX++)
+ {
+ nX2 = pPageEndX[nCountX];
+ for (nCountY=0; nCountY<nPagesY; nCountY++)
+ {
+ nY1 = pPageRows[nCountY].GetStartRow();
+ nY2 = pPageRows[nCountY].GetEndRow();
+ if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
+ {
+ if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
+ {
+ PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
+ bDoPrint, pLocationData );
+
+ if ( pProgress )
+ {
+ pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
+ pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+ }
+ ++nPrinted;
+ }
+ ++nPageNo;
+ }
+ }
+ nX1 = nX2 + 1;
+ }
+ }
+ else // von links nach rechts
+ {
+ for (nCountY=0; nCountY<nPagesY; nCountY++)
+ {
+ nY1 = pPageRows[nCountY].GetStartRow();
+ nY2 = pPageRows[nCountY].GetEndRow();
+ nX1 = nStartCol;
+ for (nCountX=0; nCountX<nPagesX; nCountX++)
+ {
+ nX2 = pPageEndX[nCountX];
+ if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
+ {
+ if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
+ {
+ PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
+ bDoPrint, pLocationData );
+
+ if ( pProgress )
+ {
+ pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
+ pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+ }
+ ++nPrinted;
+ }
+ ++nPageNo;
+ }
+ nX1 = nX2 + 1;
+ }
+ }
+ }
+ }
+
+ aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
+
+ long nNoteNr = 0;
+ long nNoteAdd;
+ do
+ {
+ if ( nPageNo+nStartPage <= nEndPage )
+ {
+ BOOL bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
+ nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
+ ( bPageSelected ? pLocationData : NULL ) );
+ if ( nNoteAdd )
+ {
+ nNoteNr += nNoteAdd;
+ if ( pProgress && bPageSelected )
+ {
+ pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
+ pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+ }
+ if (bPageSelected)
+ {
+ ++nPrinted;
+ bSourceRangeValid = FALSE; // last page was no cell range
+ }
+ ++nPageNo;
+ }
+ }
+ else
+ nNoteAdd = 0;
+ }
+ while (nNoteAdd);
+
+ if ( bMultiArea )
+ ResetBreaks(nPrintTab); // Breaks fuer Anzeige richtig
+
+ return nPrinted;
+}
+
+void ScPrintFunc::CalcZoom( USHORT nRangeNo ) // Zoom berechnen
+{
+ USHORT nRCount = pDoc->GetPrintRangeCount( nPrintTab );
+ const ScRange* pThisRange = NULL;
+ if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
+ pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
+ if ( pThisRange )
+ {
+ nStartCol = pThisRange->aStart.Col();
+ nStartRow = pThisRange->aStart.Row();
+ nEndCol = pThisRange->aEnd .Col();
+ nEndRow = pThisRange->aEnd .Row();
+ }
+
+ if (!AdjustPrintArea(FALSE)) // leer
+ {
+ nZoom = 100;
+ nPagesX = nPagesY = nTotalY = 0;
+ return;
+ }
+
+ pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
+
+ if (aTableParam.bScalePageNum)
+ {
+ nZoom = 100;
+ USHORT nPagesToFit = aTableParam.nScalePageNum;
+
+ sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
+ while (true)
+ {
+ if (nZoom <= ZOOM_MIN)
+ break;
+
+ CalcPages();
+ bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
+
+ if (bFitsPage)
+ {
+ if (nZoom == 100)
+ // If it fits at 100 %, it's good enough for me.
+ break;
+
+ nLastFitZoom = nZoom;
+ nZoom = (nLastNonFitZoom + nZoom) / 2;
+
+ if (nLastFitZoom == nZoom)
+ // It converged. Use this zoom level.
+ break;
+ }
+ else
+ {
+ if (nZoom - nLastFitZoom <= 1)
+ {
+ nZoom = nLastFitZoom;
+ CalcPages();
+ break;
+ }
+
+ nLastNonFitZoom = nZoom;
+ nZoom = (nLastFitZoom + nZoom) / 2;
+ }
+ }
+ }
+ else if (aTableParam.bScaleTo)
+ {
+ nZoom = 100;
+ USHORT nW = aTableParam.nScaleWidth;
+ USHORT nH = aTableParam.nScaleHeight;
+
+ sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
+ while (true)
+ {
+ if (nZoom <= ZOOM_MIN)
+ break;
+
+ CalcPages();
+ bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
+
+ if (bFitsPage)
+ {
+ if (nZoom == 100)
+ // If it fits at 100 %, it's good enough for me.
+ break;
+
+ nLastFitZoom = nZoom;
+ nZoom = (nLastNonFitZoom + nZoom) / 2;
+
+ if (nLastFitZoom == nZoom)
+ // It converged. Use this zoom level.
+ break;
+ }
+ else
+ {
+ if (nZoom - nLastFitZoom <= 1)
+ {
+ nZoom = nLastFitZoom;
+ CalcPages();
+ break;
+ }
+
+ nLastNonFitZoom = nZoom;
+ nZoom = (nLastFitZoom + nZoom) / 2;
+ }
+ }
+ }
+ else if (aTableParam.bScaleAll)
+ {
+ nZoom = aTableParam.nScaleAll;
+ if ( nZoom <= ZOOM_MIN )
+ nZoom = ZOOM_MIN;
+ CalcPages();
+ }
+ else
+ {
+ DBG_ASSERT( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
+ nZoom = 100;
+ CalcPages();
+ }
+}
+
+Size ScPrintFunc::GetDocPageSize()
+{
+ // Hoehe Kopf-/Fusszeile anpassen
+
+ InitModes(); // aTwipMode aus nZoom initialisieren
+ pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips
+ UpdateHFHeight( aHdr );
+ UpdateHFHeight( aFtr );
+
+ // Seitengroesse in Document-Twips
+ // Berechnung Left / Right auch in PrintPage
+
+ aPageRect = Rectangle( Point(), aPageSize );
+ aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
+ aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
+ aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
+
+ Size aDocPageSize = aPageRect.GetSize();
+ if (aTableParam.bHeaders)
+ {
+ aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
+ aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
+ }
+ if (pBorderItem)
+ {
+ aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
+ lcl_LineTotal(pBorderItem->GetRight()) +
+ pBorderItem->GetDistance(BOX_LINE_LEFT) +
+ pBorderItem->GetDistance(BOX_LINE_RIGHT);
+ aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
+ lcl_LineTotal(pBorderItem->GetBottom()) +
+ pBorderItem->GetDistance(BOX_LINE_TOP) +
+ pBorderItem->GetDistance(BOX_LINE_BOTTOM);
+ }
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ {
+ aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
+ pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
+ aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
+ pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
+ }
+ return aDocPageSize;
+}
+
+void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Breaks fuer Anzeige richtig setzen
+{
+ pDoc->SetPageSize( nTab, GetDocPageSize() );
+ pDoc->UpdatePageBreaks( nTab, NULL );
+}
+
+void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
+ SCCOL nStartCol, const SCCOL* pPageEndX )
+{
+ size_t nPagesX = rPageRowEntry.GetPagesX();
+ SCROW nStartRow = rPageRowEntry.GetStartRow();
+ SCROW nEndRow = rPageRowEntry.GetEndRow();
+
+ BOOL bLeftIsEmpty = FALSE;
+ ScRange aTempRange;
+ Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
+
+ for (size_t i=0; i<nPagesX; i++)
+ {
+ SCCOL nEndCol = pPageEndX[i];
+ if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
+ bLeftIsEmpty, &aTempRange, &aTempRect ) )
+ {
+ rPageRowEntry.SetHidden(i);
+ bLeftIsEmpty = TRUE;
+ }
+ else
+ bLeftIsEmpty = FALSE;
+
+ nStartCol = nEndCol+1;
+ }
+}
+
+void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten aus nZoom
+{
+ if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1];
+ if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1];
+ if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! vorher zaehlen !!!!
+
+ pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
+ if (aAreaParam.bPrintArea)
+ {
+ ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
+ pDoc->UpdatePageBreaks( nPrintTab, &aRange );
+ }
+ else
+ pDoc->UpdatePageBreaks( nPrintTab, NULL ); // sonst wird das Ende markiert
+
+ //
+ // Seiteneinteilung nach Umbruechen in Col/RowFlags
+ // Von mehreren Umbruechen in einem ausgeblendeten Bereich zaehlt nur einer.
+ //
+
+ nPagesX = 0;
+ nPagesY = 0;
+ nTotalY = 0;
+
+ bool bVisCol = false;
+ SCCOL nLastCol = -1;
+ for (SCCOL i=nStartCol; i<=nEndCol; i++)
+ {
+ bool bHidden = pDoc->ColHidden(i, nPrintTab, nLastCol);
+ bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
+ if ( i>nStartCol && bVisCol && bPageBreak )
+ {
+ pPageEndX[nPagesX] = i-1;
+ ++nPagesX;
+ bVisCol = false;
+ }
+ if (!bHidden)
+ bVisCol = true;
+ }
+ if (bVisCol) // auch am Ende keine leeren Seiten
+ {
+ pPageEndX[nPagesX] = nEndCol;
+ ++nPagesX;
+ }
+
+ bool bVisRow = false;
+ SCROW nPageStartRow = nStartRow;
+ SCROW nLastVisibleRow = -1;
+
+ ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
+ SCROW nNextPageBreak = pRowBreakIter->first();
+ while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
+ // Skip until the page break position is at the start row or greater.
+ nNextPageBreak = pRowBreakIter->next();
+
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ bool bPageBreak = (nNextPageBreak == nRow);
+ if (bPageBreak)
+ nNextPageBreak = pRowBreakIter->next();
+
+ if (nRow > nStartRow && bVisRow && bPageBreak )
+ {
+ pPageEndY[nTotalY] = nRow-1;
+ ++nTotalY;
+
+ if ( !aTableParam.bSkipEmpty ||
+ !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
+ {
+ pPageRows[nPagesY].SetStartRow( nPageStartRow );
+ pPageRows[nPagesY].SetEndRow( nRow-1 );
+ pPageRows[nPagesY].SetPagesX( nPagesX );
+ if (aTableParam.bSkipEmpty)
+ lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
+ ++nPagesY;
+ }
+
+ nPageStartRow = nRow;
+ bVisRow = false;
+ }
+
+ if (nRow <= nLastVisibleRow)
+ {
+ // This row is still visible. Don't bother calling RowHidden() to
+ // find out, for speed optimization.
+ bVisRow = true;
+ continue;
+ }
+
+ SCROW nLastRow = -1;
+ if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
+ {
+ bVisRow = true;
+ nLastVisibleRow = nLastRow;
+ }
+ else
+ // skip all hidden rows.
+ nRow = nLastRow;
+ }
+
+ if (bVisRow)
+ {
+ pPageEndY[nTotalY] = nEndRow;
+ ++nTotalY;
+
+ if ( !aTableParam.bSkipEmpty ||
+ !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
+ {
+ pPageRows[nPagesY].SetStartRow( nPageStartRow );
+ pPageRows[nPagesY].SetEndRow( nEndRow );
+ pPageRows[nPagesY].SetPagesX( nPagesX );
+ if (aTableParam.bSkipEmpty)
+ lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
+ ++nPagesY;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// class ScJobSetup
+//------------------------------------------------------------------------
+
+ScJobSetup::ScJobSetup( SfxPrinter* pPrinter )
+{
+ eOrientation = pPrinter->GetOrientation();
+ nPaperBin = pPrinter->GetPaperBin();
+ ePaper = pPrinter->GetPaper();
+
+ if ( PAPER_USER == ePaper )
+ {
+ aUserSize = pPrinter->GetPaperSize();
+ aUserMapMode = pPrinter->GetMapMode();
+ }
+};
+
+
+
+
+
diff --git a/sc/source/ui/view/reffact.cxx b/sc/source/ui/view/reffact.cxx
new file mode 100644
index 000000000000..0d5d64964f5c
--- /dev/null
+++ b/sc/source/ui/view/reffact.cxx
@@ -0,0 +1,434 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/app.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "reffact.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "acredlin.hxx"
+#include "simpref.hxx"
+#include "scmod.hxx"
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#include "validate.hxx"
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+
+// -----------------------------------------------------------------------
+
+SFX_IMPL_MODELESSDIALOG(ScNameDlgWrapper, FID_DEFINE_NAME )
+SFX_IMPL_MODELESSDIALOG(ScSolverDlgWrapper, SID_OPENDLG_SOLVE )
+SFX_IMPL_MODELESSDIALOG(ScOptSolverDlgWrapper, SID_OPENDLG_OPTSOLVER )
+SFX_IMPL_MODELESSDIALOG(ScPivotLayoutWrapper, SID_OPENDLG_PIVOTTABLE )
+SFX_IMPL_MODELESSDIALOG(ScTabOpDlgWrapper, SID_OPENDLG_TABOP )
+SFX_IMPL_MODELESSDIALOG(ScFilterDlgWrapper, SID_FILTER )
+SFX_IMPL_MODELESSDIALOG(ScSpecialFilterDlgWrapper, SID_SPECIAL_FILTER )
+SFX_IMPL_MODELESSDIALOG(ScDbNameDlgWrapper, SID_DEFINE_DBNAME )
+SFX_IMPL_MODELESSDIALOG(ScConsolidateDlgWrapper, SID_OPENDLG_CONSOLIDATE )
+SFX_IMPL_MODELESSDIALOG(ScPrintAreasDlgWrapper, SID_OPENDLG_EDIT_PRINTAREA )
+SFX_IMPL_MODELESSDIALOG(ScCondFormatDlgWrapper, SID_OPENDLG_CONDFRMT )
+SFX_IMPL_MODELESSDIALOG(ScColRowNameRangesDlgWrapper, SID_DEFINE_COLROWNAMERANGES )
+SFX_IMPL_MODELESSDIALOG(ScFormulaDlgWrapper, SID_OPENDLG_FUNCTION )
+SFX_IMPL_MODELESSDIALOG(ScAcceptChgDlgWrapper, FID_CHG_ACCEPT )
+SFX_IMPL_MODELESSDIALOG(ScHighlightChgDlgWrapper, FID_CHG_SHOW )
+SFX_IMPL_MODELESSDIALOG(ScSimpleRefDlgWrapper, WID_SIMPLE_REF )
+/*!!! dafuer muss der Funktionsautopilot noch umgebaut werden
+SFX_IMPL_CHILDWINDOW(ScFunctionDlgWrapper, SID_OPENDLG_FUNCTION )
+SFX_IMPL_CHILDWINDOW(ScEditFunctionDlgWrapper, SID_OPENDLG_EDITFUNCTION )
+SFX_IMPL_CHILDWINDOW(ScArgumentDlgWrapper, SID_OPENDLG_ARGUMENT )
+*/
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+//SFX_IMPL_MODELESSDIALOG(ScValidityRefChildWin, SID_VALIDITY_REFERENCE )
+SFX_IMPL_CHILDWINDOW(ScValidityRefChildWin, SID_VALIDITY_REFERENCE)
+SfxChildWinInfo __EXPORT ScValidityRefChildWin::GetInfo() const
+{
+ SfxChildWinInfo anInfo = SfxChildWindow::GetInfo();
+
+ if( Window *pWnd = GetWindow() )
+ {
+ anInfo.aSize = pWnd->GetSizePixel();
+
+ if( pWnd->IsDialog() )
+ if ( static_cast<Dialog*>(pWnd)->IsRollUp() )
+ anInfo.nFlags |= SFX_CHILDWIN_ZOOMIN;
+ }
+
+ return anInfo;
+}
+
+namespace { ScTabViewShell * lcl_GetTabViewShell( SfxBindings *pBindings ); }
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+
+#define IMPL_CHILD_CTOR(Class,sid) \
+ Class::Class( Window* pParentP, \
+ USHORT nId, \
+ SfxBindings* p, \
+ SfxChildWinInfo* pInfo ) \
+ : SfxChildWindow(pParentP, nId) \
+ { \
+ /*//<!--Added by PengYunQuan for Validity Cell Range Picker*/\
+ /************************************************************************************/\
+ /* When a new document is creating, the SfxViewFrame may be ready, */\
+ /* But the ScTabViewShell may have not been activated yet. In this */\
+ /* situation, SfxViewShell::Current() does not get the correct shell, */\
+ /* and we should lcl_GetTabViewShell( p ) instead of SfxViewShell::Current() */\
+ /************************************************************************************/\
+ ScTabViewShell* pViewShell = lcl_GetTabViewShell( p ); \
+ /*//-->Added by PengYunQuan for Validity Cell Range Picker*/\
+ if (!pViewShell) \
+ pViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); \
+ DBG_ASSERT( pViewShell, "missing view shell :-(" ); \
+ pWindow = pViewShell ? \
+ pViewShell->CreateRefDialog( p, this, pInfo, pParentP, sid ) : NULL; \
+ if (pViewShell && !pWindow) \
+ pViewShell->GetViewFrame()->SetChildWindow( nId, FALSE ); \
+ }
+
+
+//=========================================================================
+
+//-------------------------------------------------------------------------
+// ScNameDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScNameDlgWrapper, FID_DEFINE_NAME )
+
+//-------------------------------------------------------------------------
+// ScSolverDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScSolverDlgWrapper, SID_OPENDLG_SOLVE )
+
+//-------------------------------------------------------------------------
+// ScOptSolverDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScOptSolverDlgWrapper, SID_OPENDLG_OPTSOLVER )
+
+//-------------------------------------------------------------------------
+// ScPivotLayoutWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScPivotLayoutWrapper, SID_OPENDLG_PIVOTTABLE )
+
+//-------------------------------------------------------------------------
+// ScTabOpDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScTabOpDlgWrapper, SID_OPENDLG_TABOP )
+
+//-------------------------------------------------------------------------
+// ScFilterDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScFilterDlgWrapper, SID_FILTER )
+
+//-------------------------------------------------------------------------
+// ScSpecialFilterDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScSpecialFilterDlgWrapper, SID_SPECIAL_FILTER )
+
+//-------------------------------------------------------------------------
+// ScDbNameDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScDbNameDlgWrapper, SID_DEFINE_DBNAME )
+
+//-------------------------------------------------------------------------
+// ScColRowNameRangesDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScColRowNameRangesDlgWrapper, SID_DEFINE_COLROWNAMERANGES )
+
+//-------------------------------------------------------------------------
+// ScConsolidateDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScConsolidateDlgWrapper, SID_OPENDLG_CONSOLIDATE )
+
+//-------------------------------------------------------------------------
+// ScPrintAreasDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScPrintAreasDlgWrapper, SID_OPENDLG_EDIT_PRINTAREA )
+
+//-------------------------------------------------------------------------
+// ScCondFormatDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScCondFormatDlgWrapper, SID_OPENDLG_CONDFRMT )
+
+//-------------------------------------------------------------------------
+// ScFormulaDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScFormulaDlgWrapper, SID_OPENDLG_FUNCTION )
+
+
+//-------------------------------------------------------------------------
+// ScSimpleRefDlgWrapper
+//-------------------------------------------------------------------------
+
+static BOOL bScSimpleRefFlag;
+static long nScSimpleRefHeight;
+static long nScSimpleRefWidth;
+static long nScSimpleRefX;
+static long nScSimpleRefY;
+static BOOL bAutoReOpen=TRUE;
+
+ScSimpleRefDlgWrapper::ScSimpleRefDlgWrapper( Window* pParentP,
+ USHORT nId,
+ SfxBindings* p,
+ SfxChildWinInfo* pInfo )
+ : SfxChildWindow(pParentP, nId)
+{
+// ScTabViewShell* pViewShell =
+// PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+
+ ScTabViewShell* pViewShell = NULL;
+ SfxDispatcher* pDisp = p->GetDispatcher();
+ if ( pDisp )
+ {
+ SfxViewFrame* pViewFrm = pDisp->GetFrame();
+ if ( pViewFrm )
+ pViewShell = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
+ }
+
+ DBG_ASSERT( pViewShell, "missing view shell :-(" );
+
+ if(pInfo!=NULL && bScSimpleRefFlag)
+ {
+ pInfo->aPos.X()=nScSimpleRefX;
+ pInfo->aPos.Y()=nScSimpleRefY;
+ pInfo->aSize.Height()=nScSimpleRefHeight;
+ pInfo->aSize.Width()=nScSimpleRefWidth;
+ }
+ pWindow = NULL;
+
+ if(bAutoReOpen && pViewShell)
+ pWindow = pViewShell->CreateRefDialog( p, this, pInfo, pParentP, WID_SIMPLE_REF);
+
+ if (!pWindow)
+ {
+ SC_MOD()->SetRefDialog( nId, FALSE );
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetDefaultPosSize(Point aPos, Size aSize, BOOL bSet)
+{
+ bScSimpleRefFlag=bSet;
+ if(bScSimpleRefFlag)
+ {
+ nScSimpleRefX=aPos.X();
+ nScSimpleRefY=aPos.Y();
+ nScSimpleRefHeight=aSize.Height();
+ nScSimpleRefWidth=aSize.Width();
+ }
+}
+
+
+String ScSimpleRefDlgWrapper::GetRefString()
+{
+ String aResult;
+ if(pWindow!=NULL)
+ {
+ aResult=((ScSimpleRefDlg*)pWindow)->GetRefString();
+ }
+ return aResult;
+}
+
+void ScSimpleRefDlgWrapper::SetAutoReOpen(BOOL bFlag)
+{
+ bAutoReOpen=bFlag;
+}
+
+void ScSimpleRefDlgWrapper::SetRefString(const String& rStr)
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetRefString(rStr);
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetCloseHdl( const Link& rLink )
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetCloseHdl( rLink );
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetUnoLinks( const Link& rDone,
+ const Link& rAbort, const Link& rChange )
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetUnoLinks( rDone, rAbort, rChange );
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetFlags( BOOL bCloseOnButtonUp, BOOL bSingleCell, BOOL bMultiSelection )
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetFlags( bCloseOnButtonUp, bSingleCell, bMultiSelection );
+ }
+}
+
+void ScSimpleRefDlgWrapper::StartRefInput()
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->StartRefInput();
+ }
+}
+
+
+
+//-------------------------------------------------------------------------
+// ScAcceptChgDlgWrapper //Kommentar: sollte in die ViewShell
+//-------------------------------------------------------------------------
+
+ScAcceptChgDlgWrapper::ScAcceptChgDlgWrapper( Window* pParentP,
+ USHORT nId,
+ SfxBindings* pBindings,
+ SfxChildWinInfo* pInfo ) :
+ SfxChildWindow( pParentP, nId )
+{
+ ScTabViewShell* pViewShell =
+ PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ DBG_ASSERT( pViewShell, "missing view shell :-(" );
+ pWindow = pViewShell ?
+ new ScAcceptChgDlg( pBindings, this, pParentP, pViewShell->GetViewData() ) :
+ NULL;
+ if(pWindow!=NULL)
+ {
+ ((ScAcceptChgDlg*)pWindow)->Initialize( pInfo );
+ }
+ if (pViewShell && !pWindow)
+ pViewShell->GetViewFrame()->SetChildWindow( nId, FALSE );
+}
+
+void ScAcceptChgDlgWrapper::ReInitDlg()
+{
+ ScTabViewShell* pViewShell =
+ PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ DBG_ASSERT( pViewShell, "missing view shell :-(" );
+
+ if(pWindow!=NULL && pViewShell)
+ {
+ ((ScAcceptChgDlg*)pWindow)->ReInit(pViewShell->GetViewData());
+ }
+}
+
+//-------------------------------------------------------------------------
+// ScHighlightChgDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScHighlightChgDlgWrapper, FID_CHG_SHOW )
+
+/*------------------------------------------------------------------------*/
+/*@@@
+ //-------------------------------------------------------------------------
+ // ScFunctionDlgWrapper
+ //-------------------------------------------------------------------------
+
+ IMPL_CHILD_CTOR( ScFunctionDlgWrapper, SID_OPENDLG_FUNCTION )
+
+ //-------------------------------------------------------------------------
+ // ScEditFunctionDlgWrapper
+ //-------------------------------------------------------------------------
+
+ IMPL_CHILD_CTOR( ScEditFunctionDlgWrapper, SID_OPENDLG_EDITFUNCTION )
+
+ //-------------------------------------------------------------------------
+ // ScArgumentDlgWrapper
+ //-------------------------------------------------------------------------
+
+ IMPL_CHILD_CTOR( ScArgumentDlgWrapper, SID_OPENDLG_ARGUMENT )
+@@@*/
+/*------------------------------------------------------------------------*/
+
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+namespace
+{
+ ScTabViewShell * lcl_GetTabViewShell( SfxBindings *pBindings )
+ {
+ if( pBindings )
+ if( SfxDispatcher* pDisp = pBindings ->GetDispatcher() )
+ if( SfxViewFrame *pFrm = pDisp->GetFrame() )
+ if( SfxViewShell* pViewSh = pFrm->GetViewShell() )
+ return dynamic_cast<ScTabViewShell*>( pViewSh );
+
+ return NULL;
+ }
+}
+
+ScValidityRefChildWin::ScValidityRefChildWin( Window* pParentP, \
+ USHORT nId, \
+ SfxBindings* p, \
+ SfxChildWinInfo* /*pInfo*/ ) \
+ : SfxChildWindow(pParentP, nId),
+ m_bVisibleLock( false ),
+ m_bFreeWindowLock( false ),
+ m_pSavedWndParent( NULL )
+{
+ SetWantsFocus( FALSE );\
+ ScTabViewShell* pViewShell = \
+ NULL != ( pWindow = ScValidationDlg::Find1AliveObject( pParentP ) ) ? static_cast<ScValidationDlg*>(pWindow)->GetTabViewShell() :
+ lcl_GetTabViewShell( p );
+ if (!pViewShell)
+ pViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ DBG_ASSERT( pViewShell, "missing view shell :-(" ); \
+ if (pViewShell && !pWindow) \
+ pViewShell->GetViewFrame()->SetChildWindow( nId, FALSE ); \
+ else if( pWindow /*&& pWindow->ISA(ScValidationDlg)*/ )
+ {}//pWindow = new Window( pParentP, WB_HIDE );
+
+ if( pWindow ) m_pSavedWndParent = pWindow->GetParent();
+}
+
+ScValidityRefChildWin::~ScValidityRefChildWin()
+{
+ if( pWindow ) pWindow->SetParent( m_pSavedWndParent );
+
+ if( m_bFreeWindowLock )
+ pWindow = NULL;
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx
new file mode 100644
index 000000000000..d5816ecdd289
--- /dev/null
+++ b/sc/source/ui/view/scextopt.cxx
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "scextopt.hxx"
+
+#include <vector>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+// ============================================================================
+
+ScExtDocSettings::ScExtDocSettings() :
+ mfTabBarWidth( -1.0 ),
+ mnLinkCnt( 0 ),
+ mnDisplTab( 0 )
+{
+}
+
+// ============================================================================
+
+ScExtTabSettings::ScExtTabSettings() :
+ maUsedArea( ScAddress::INITIALIZE_INVALID ),
+ maCursor( ScAddress::INITIALIZE_INVALID ),
+ maFirstVis( ScAddress::INITIALIZE_INVALID ),
+ maSecondVis( ScAddress::INITIALIZE_INVALID ),
+ maFreezePos( 0, 0, 0 ),
+ maSplitPos( 0, 0 ),
+ meActivePane( SCEXT_PANE_TOPLEFT ),
+ maGridColor( COL_AUTO ),
+ mnNormalZoom( 0 ),
+ mnPageZoom( 0 ),
+ mbSelected( false ),
+ mbFrozenPanes( false ),
+ mbPageMode( false )
+{
+}
+
+// ============================================================================
+
+/** A container for ScExtTabSettings objects.
+ @descr Internally, a std::map with shared pointers to ScExtTabSettings is
+ used. The copy constructor and assignment operator make deep copies of the
+ objects. */
+class ScExtTabSettingsCont
+{
+public:
+ explicit ScExtTabSettingsCont();
+ ScExtTabSettingsCont( const ScExtTabSettingsCont& rSrc );
+ ScExtTabSettingsCont& operator=( const ScExtTabSettingsCont& rSrc );
+
+ const ScExtTabSettings* GetTabSettings( SCTAB nTab ) const;
+ ScExtTabSettings& GetOrCreateTabSettings( SCTAB nTab );
+
+private:
+ typedef ::boost::shared_ptr< ScExtTabSettings > ScExtTabSettingsRef;
+ typedef ::std::map< SCTAB, ScExtTabSettingsRef > ScExtTabSettingsMap;
+
+ /** Makes a deep copy of all objects in the passed map. */
+ void CopyFromMap( const ScExtTabSettingsMap& rMap );
+
+ ScExtTabSettingsMap maMap;
+};
+
+// ----------------------------------------------------------------------------
+
+ScExtTabSettingsCont::ScExtTabSettingsCont()
+{
+}
+
+ScExtTabSettingsCont::ScExtTabSettingsCont( const ScExtTabSettingsCont& rSrc )
+{
+ CopyFromMap( rSrc.maMap );
+}
+
+ScExtTabSettingsCont& ScExtTabSettingsCont::operator=( const ScExtTabSettingsCont& rSrc )
+{
+ CopyFromMap( rSrc.maMap );
+ return *this;
+}
+
+const ScExtTabSettings* ScExtTabSettingsCont::GetTabSettings( SCTAB nTab ) const
+{
+ ScExtTabSettingsMap::const_iterator aIt = maMap.find( nTab );
+ return (aIt == maMap.end()) ? 0 : aIt->second.get();
+}
+
+ScExtTabSettings& ScExtTabSettingsCont::GetOrCreateTabSettings( SCTAB nTab )
+{
+ ScExtTabSettingsRef& rxTabSett = maMap[ nTab ];
+ if( !rxTabSett )
+ rxTabSett.reset( new ScExtTabSettings );
+ return *rxTabSett;
+}
+
+void ScExtTabSettingsCont::CopyFromMap( const ScExtTabSettingsMap& rMap )
+{
+ maMap.clear();
+ for( ScExtTabSettingsMap::const_iterator aIt = rMap.begin(), aEnd = rMap.end(); aIt != aEnd; ++aIt )
+ maMap[ aIt->first ].reset( new ScExtTabSettings( *aIt->second ) );
+}
+
+// ============================================================================
+
+/** Implementation struct for ScExtDocOptions containing all members. */
+struct ScExtDocOptionsImpl
+{
+ typedef ::std::vector< String > StringVec;
+
+ ScExtDocSettings maDocSett; /// Global document settings.
+ ScExtTabSettingsCont maTabSett; /// Settings for all sheets.
+ StringVec maCodeNames; /// Codenames for all sheets (VBA module names).
+ bool mbChanged; /// Use only if something has been changed.
+
+ explicit ScExtDocOptionsImpl();
+};
+
+ScExtDocOptionsImpl::ScExtDocOptionsImpl() :
+ mbChanged( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScExtDocOptions::ScExtDocOptions() :
+ mxImpl( new ScExtDocOptionsImpl )
+{
+}
+
+ScExtDocOptions::ScExtDocOptions( const ScExtDocOptions& rSrc ) :
+ mxImpl( new ScExtDocOptionsImpl( *rSrc.mxImpl ) )
+{
+}
+
+ScExtDocOptions::~ScExtDocOptions()
+{
+}
+
+ScExtDocOptions& ScExtDocOptions::operator=( const ScExtDocOptions& rSrc )
+{
+ *mxImpl = *rSrc.mxImpl;
+ return *this;
+}
+
+bool ScExtDocOptions::IsChanged() const
+{
+ return mxImpl->mbChanged;
+}
+
+void ScExtDocOptions::SetChanged( bool bChanged )
+{
+ mxImpl->mbChanged = bChanged;
+}
+
+const ScExtDocSettings& ScExtDocOptions::GetDocSettings() const
+{
+ return mxImpl->maDocSett;
+}
+
+ScExtDocSettings& ScExtDocOptions::GetDocSettings()
+{
+ return mxImpl->maDocSett;
+}
+
+const ScExtTabSettings* ScExtDocOptions::GetTabSettings( SCTAB nTab ) const
+{
+ return mxImpl->maTabSett.GetTabSettings( nTab );
+}
+
+ScExtTabSettings& ScExtDocOptions::GetOrCreateTabSettings( SCTAB nTab )
+{
+ return mxImpl->maTabSett.GetOrCreateTabSettings( nTab );
+}
+
+SCTAB ScExtDocOptions::GetCodeNameCount() const
+{
+ return static_cast< SCTAB >( mxImpl->maCodeNames.size() );
+}
+
+const String& ScExtDocOptions::GetCodeName( SCTAB nTab ) const
+{
+ DBG_ASSERT( (0 <= nTab) && (nTab < GetCodeNameCount()), "ScExtDocOptions::GetCodeName - invalid sheet index" );
+ return ((0 <= nTab) && (nTab < GetCodeNameCount())) ? mxImpl->maCodeNames[ static_cast< size_t >( nTab ) ] : EMPTY_STRING;
+}
+
+void ScExtDocOptions::SetCodeName( SCTAB nTab, const String& rCodeName )
+{
+ DBG_ASSERT( nTab >= 0, "ScExtDocOptions::SetCodeName - invalid sheet index" );
+ if( nTab >= 0 )
+ {
+ size_t nIndex = static_cast< size_t >( nTab );
+ if( nIndex >= mxImpl->maCodeNames.size() )
+ mxImpl->maCodeNames.resize( nIndex + 1 );
+ mxImpl->maCodeNames[ nIndex ] = rCodeName;
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx
new file mode 100644
index 000000000000..b2c9ffdc1395
--- /dev/null
+++ b/sc/source/ui/view/select.cxx
@@ -0,0 +1,891 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/urlobj.hxx>
+#include <vcl/sound.hxx>
+#include <sfx2/docfile.hxx>
+
+#include "select.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "scmod.hxx"
+#include "document.hxx"
+//#include "dataobj.hxx"
+#include "transobj.hxx"
+#include "docsh.hxx"
+#include "tabprotection.hxx"
+
+extern USHORT nScFillModeMouseModifier; // global.cxx
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+static Point aSwitchPos; //! Member
+static BOOL bDidSwitch = FALSE;
+
+// -----------------------------------------------------------------------
+
+//
+// View (Gridwin / Tastatur)
+//
+
+ScViewFunctionSet::ScViewFunctionSet( ScViewData* pNewViewData ) :
+ pViewData( pNewViewData ),
+ pEngine( NULL ),
+ bAnchor( FALSE ),
+ bStarted( FALSE )
+{
+ DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet");
+}
+
+ScSplitPos ScViewFunctionSet::GetWhich()
+{
+ if (pEngine)
+ return pEngine->GetWhich();
+ else
+ return pViewData->GetActivePart();
+}
+
+void ScViewFunctionSet::SetSelectionEngine( ScViewSelectionEngine* pSelEngine )
+{
+ pEngine = pSelEngine;
+}
+
+// Drag & Drop
+
+void __EXPORT ScViewFunctionSet::BeginDrag()
+{
+ SCTAB nTab = pViewData->GetTabNo();
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ if (pEngine)
+ {
+ Point aMPos = pEngine->GetMousePosPixel();
+ pViewData->GetPosFromPixel( aMPos.X(), aMPos.Y(), GetWhich(), nPosX, nPosY );
+ }
+ else
+ {
+ nPosX = pViewData->GetCurX();
+ nPosY = pViewData->GetCurY();
+ }
+
+ ScModule* pScMod = SC_MOD();
+ BOOL bRefMode = pScMod->IsFormulaMode();
+ if (!bRefMode)
+ {
+ pViewData->GetView()->FakeButtonUp( GetWhich() ); // ButtonUp wird verschluckt
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+// rMark.SetMarking(FALSE); // es fehlt ein ButtonUp
+ rMark.MarkToSimple();
+ if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ // bApi = TRUE -> no error mesages
+ BOOL bCopied = pViewData->GetView()->CopyToClip( pClipDoc, FALSE, TRUE );
+ if ( bCopied )
+ {
+ sal_Int8 nDragActions = pViewData->GetView()->SelectionEditable() ?
+ ( DND_ACTION_COPYMOVE | DND_ACTION_LINK ) :
+ ( DND_ACTION_COPY | DND_ACTION_LINK );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ // set position of dragged cell within range
+ ScRange aMarkRange = pTransferObj->GetRange();
+ SCCOL nStartX = aMarkRange.aStart.Col();
+ SCROW nStartY = aMarkRange.aStart.Row();
+ SCCOL nHandleX = (nPosX >= (SCsCOL) nStartX) ? nPosX - nStartX : 0;
+ SCROW nHandleY = (nPosY >= (SCsROW) nStartY) ? nPosY - nStartY : 0;
+ pTransferObj->SetDragHandlePos( nHandleX, nHandleY );
+ pTransferObj->SetVisibleTab( nTab );
+
+ pTransferObj->SetDragSource( pDocSh, rMark );
+
+ Window* pWindow = pViewData->GetActiveWin();
+ if ( pWindow->IsTracking() )
+ pWindow->EndTracking( ENDTRACK_CANCEL ); // abort selecting
+
+ SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D
+ pTransferObj->StartDrag( pWindow, nDragActions );
+
+ return; // dragging started
+ }
+ else
+ delete pClipDoc;
+ }
+ }
+
+ Sound::Beep(); // can't drag
+}
+
+// Selektion
+
+void __EXPORT ScViewFunctionSet::CreateAnchor()
+{
+ if (bAnchor) return;
+
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ SetAnchor( pViewData->GetRefStartX(), pViewData->GetRefStartY() );
+ else
+ SetAnchor( pViewData->GetCurX(), pViewData->GetCurY() );
+}
+
+void ScViewFunctionSet::SetAnchor( SCCOL nPosX, SCROW nPosY )
+{
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ ScTabView* pView = pViewData->GetView();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ if (bRefMode)
+ {
+ pView->DoneRefMode( FALSE );
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ pView->InitRefMode( aAnchorPos.Col(), aAnchorPos.Row(), aAnchorPos.Tab(),
+ SC_REFTYPE_REF );
+ bStarted = TRUE;
+ }
+ else if (pViewData->IsAnyFillMode())
+ {
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ bStarted = TRUE;
+ }
+ else
+ {
+ // nicht weg und gleich wieder hin
+ if ( bStarted && pView->IsMarking( nPosX, nPosY, nTab ) )
+ {
+ // nix
+ }
+ else
+ {
+ pView->DoneBlockMode( TRUE );
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(),
+ aAnchorPos.Tab(), TRUE );
+ bStarted = TRUE;
+ }
+ else
+ bStarted = FALSE;
+ }
+ }
+ bAnchor = TRUE;
+}
+
+void __EXPORT ScViewFunctionSet::DestroyAnchor()
+{
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ pViewData->GetView()->DoneRefMode( TRUE );
+ else
+ pViewData->GetView()->DoneBlockMode( TRUE );
+
+ bAnchor = FALSE;
+}
+
+void ScViewFunctionSet::SetAnchorFlag( BOOL bSet )
+{
+ bAnchor = bSet;
+}
+
+BOOL __EXPORT ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOOL /* bDontSelectAtCursor */ )
+{
+ if ( bDidSwitch )
+ {
+ if ( rPointPixel == aSwitchPos )
+ return FALSE; // nicht auf falschem Fenster scrollen
+ else
+ bDidSwitch = FALSE;
+ }
+ aSwitchPos = rPointPixel; // nur wichtig, wenn bDidSwitch
+
+ // treat position 0 as -1, so scrolling is always possible
+ // (with full screen and hidden headers, the top left border may be at 0)
+ // (moved from ScViewData::GetPosFromPixel)
+
+ Point aEffPos = rPointPixel;
+ if ( aEffPos.X() == 0 )
+ aEffPos.X() = -1;
+ if ( aEffPos.Y() == 0 )
+ aEffPos.Y() = -1;
+
+ // Scrolling
+
+ Size aWinSize = pEngine->GetWindow()->GetOutputSizePixel();
+ BOOL bRightScroll = ( aEffPos.X() >= aWinSize.Width() );
+ BOOL bBottomScroll = ( aEffPos.Y() >= aWinSize.Height() );
+ BOOL bNegScroll = ( aEffPos.X() < 0 || aEffPos.Y() < 0 );
+ BOOL bScroll = bRightScroll || bBottomScroll || bNegScroll;
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aEffPos.X(), aEffPos.Y(), GetWhich(),
+ nPosX, nPosY, TRUE, TRUE ); // mit Repair
+
+ // fuer AutoFill in der Mitte der Zelle umschalten
+ // dabei aber nicht das Scrolling nach rechts/unten verhindern
+ if ( pViewData->IsFillMode() || pViewData->GetFillMode() == SC_FILL_MATRIX )
+ {
+ BOOL bLeft, bTop;
+ pViewData->GetMouseQuadrant( aEffPos, GetWhich(), nPosX, nPosY, bLeft, bTop );
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( bLeft && !bRightScroll )
+ do --nPosX; while ( nPosX>=0 && pDoc->ColHidden( nPosX, nTab ) );
+ if ( bTop && !bBottomScroll )
+ {
+ if (--nPosY >= 0)
+ {
+ nPosY = pDoc->LastVisibleRow(0, nPosY, nTab);
+ if (!ValidRow(nPosY))
+ nPosY = -1;
+ }
+ }
+ // negativ ist erlaubt
+ }
+
+ // ueber Fixier-Grenze bewegt?
+
+ ScSplitPos eWhich = GetWhich();
+ if ( eWhich == pViewData->GetActivePart() )
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ if ( aEffPos.X() >= aWinSize.Width() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bScroll = FALSE, bDidSwitch = TRUE;
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = FALSE, bDidSwitch = TRUE;
+ }
+
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ if ( aEffPos.Y() >= aWinSize.Height() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bScroll = FALSE, bDidSwitch = TRUE;
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = FALSE, bDidSwitch = TRUE;
+ }
+ }
+
+ pViewData->ResetOldCursor();
+ return SetCursorAtCell( nPosX, nPosY, bScroll );
+}
+
+BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScroll )
+{
+ 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 );
+
+ BOOL bHide = !bRefMode && !pViewData->IsAnyFillMode() &&
+ ( nPosX != (SCsCOL) pViewData->GetCurX() || nPosY != (SCsROW) pViewData->GetCurY() );
+
+ if (bHide)
+ pView->HideAllCursors();
+
+ if (bScroll)
+ {
+ if (bRefMode)
+ {
+ ScSplitPos eWhich = GetWhich();
+ pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE, &eWhich );
+ }
+ else
+ pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE );
+ }
+
+ if (bRefMode)
+ {
+ // #90910# if no input is possible from this doc, don't move the reference cursor around
+ if ( !pScMod->IsModalMode(pViewData->GetSfxDocShell()) )
+ {
+ if (!bAnchor)
+ {
+ pView->DoneRefMode( TRUE );
+ pView->InitRefMode( nPosX, nPosY, pViewData->GetTabNo(), SC_REFTYPE_REF );
+ }
+
+ pView->UpdateRef( nPosX, nPosY, pViewData->GetTabNo() );
+ }
+ }
+ else if (pViewData->IsFillMode() ||
+ (pViewData->GetFillMode() == SC_FILL_MATRIX && (nScFillModeMouseModifier & KEY_MOD1) ))
+ {
+ // Wenn eine Matrix angefasst wurde, kann mit Ctrl auf AutoFill zurueckgeschaltet werden
+
+ SCCOL nStartX, nEndX;
+ SCROW nStartY, nEndY; // Block
+ SCTAB nDummy;
+ pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy );
+
+ if (pViewData->GetRefType() != SC_REFTYPE_FILL)
+ {
+ pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
+ CreateAnchor();
+ }
+
+ ScRange aDelRange;
+ BOOL bOldDelMark = pViewData->GetDelMark( aDelRange );
+
+ if ( nPosX+1 >= (SCsCOL) nStartX && nPosX <= (SCsCOL) nEndX &&
+ nPosY+1 >= (SCsROW) nStartY && nPosY <= (SCsROW) nEndY &&
+ ( nPosX != nEndX || nPosY != nEndY ) ) // verkleinern ?
+ {
+ // Richtung (links oder oben)
+
+ long nSizeX = 0;
+ for (SCCOL i=nPosX+1; i<=nEndX; i++)
+ nSizeX += pDoc->GetColWidth( i, nTab );
+ long nSizeY = (long) pDoc->GetRowHeight( nPosY+1, nEndY, nTab );
+
+ SCCOL nDelStartX = nStartX;
+ SCROW nDelStartY = nStartY;
+ if ( nSizeX > nSizeY )
+ nDelStartX = nPosX + 1;
+ else
+ nDelStartY = nPosY + 1;
+ // 0 braucht nicht mehr getrennt abgefragt zu werden, weil nPosX/Y auch negativ wird
+
+ if ( nDelStartX < nStartX )
+ nDelStartX = nStartX;
+ if ( nDelStartY < nStartY )
+ nDelStartY = nStartY;
+
+ // Bereich setzen
+
+ pViewData->SetDelMark( ScRange( nDelStartX,nDelStartY,nTab,
+ nEndX,nEndY,nTab ) );
+ pViewData->GetView()->UpdateShrinkOverlay();
+
+#if 0
+ if ( bOldDelMark )
+ {
+ ScUpdateRect aRect( aDelRange.aStart.Col(), aDelRange.aStart.Row(),
+ aDelRange.aEnd.Col(), aDelRange.aEnd.Row() );
+ aRect.SetNew( nDelStartX,nDelStartY, nEndX,nEndY );
+ SCCOL nPaintStartX;
+ SCROW nPaintStartY;
+ SCCOL nPaintEndX;
+ SCROW nPaintEndY;
+ if (aRect.GetDiff( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY ))
+ pViewData->GetView()->
+ PaintArea( nPaintStartX, nPaintStartY,
+ nPaintEndX, nPaintEndY, SC_UPDATE_MARKS );
+ }
+ else
+#endif
+ pViewData->GetView()->
+ PaintArea( nStartX,nDelStartY, nEndX,nEndY, SC_UPDATE_MARKS );
+
+ nPosX = nEndX; // roten Rahmen um ganzen Bereich lassen
+ nPosY = nEndY;
+
+ // Referenz wieder richtigherum, falls unten umgedreht
+ if ( nStartX != pViewData->GetRefStartX() || nStartY != pViewData->GetRefStartY() )
+ {
+ pViewData->GetView()->DoneRefMode();
+ pViewData->GetView()->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
+ }
+ }
+ else
+ {
+ if ( bOldDelMark )
+ {
+ pViewData->ResetDelMark();
+ pViewData->GetView()->UpdateShrinkOverlay();
+
+#if 0
+ pViewData->GetView()->
+ PaintArea( aDelRange.aStart.Col(), aDelRange.aStart.Row(),
+ aDelRange.aEnd.Col(), aDelRange.aEnd.Row(), SC_UPDATE_MARKS );
+#endif
+ }
+
+ BOOL bNegX = ( nPosX < (SCsCOL) nStartX );
+ BOOL bNegY = ( nPosY < (SCsROW) nStartY );
+
+ long nSizeX = 0;
+ if ( bNegX )
+ {
+ // #94321# in SetCursorAtPoint hidden columns are skipped.
+ // They must be skipped here too, or the result will always be the first hidden column.
+ do ++nPosX; while ( nPosX<nStartX && pDoc->ColHidden(nPosX, nTab) );
+ for (SCCOL i=nPosX; i<nStartX; i++)
+ nSizeX += pDoc->GetColWidth( i, nTab );
+ }
+ else
+ for (SCCOL i=nEndX+1; i<=nPosX; i++)
+ nSizeX += pDoc->GetColWidth( i, nTab );
+
+ long nSizeY = 0;
+ if ( bNegY )
+ {
+ // #94321# in SetCursorAtPoint hidden rows are skipped.
+ // They must be skipped here too, or the result will always be the first hidden row.
+ if (++nPosY < nStartY)
+ {
+ nPosY = pDoc->FirstVisibleRow(nPosY, nStartY-1, nTab);
+ if (!ValidRow(nPosY))
+ nPosY = nStartY;
+ }
+ nSizeY += pDoc->GetRowHeight( nPosY, nStartY-1, nTab );
+ }
+ else
+ nSizeY += pDoc->GetRowHeight( nEndY+1, nPosY, nTab );
+
+ if ( nSizeX > nSizeY ) // Fill immer nur in einer Richtung
+ {
+ nPosY = nEndY;
+ bNegY = FALSE;
+ }
+ else
+ {
+ nPosX = nEndX;
+ bNegX = FALSE;
+ }
+
+ SCCOL nRefStX = bNegX ? nEndX : nStartX;
+ SCROW nRefStY = bNegY ? nEndY : nStartY;
+ if ( nRefStX != pViewData->GetRefStartX() || nRefStY != pViewData->GetRefStartY() )
+ {
+ pViewData->GetView()->DoneRefMode();
+ pViewData->GetView()->InitRefMode( nRefStX, nRefStY, nTab, SC_REFTYPE_FILL );
+ }
+ }
+
+ pView->UpdateRef( nPosX, nPosY, nTab );
+ }
+ else if (pViewData->IsAnyFillMode())
+ {
+ BYTE nMode = pViewData->GetFillMode();
+ if ( nMode == SC_FILL_EMBED_LT || nMode == SC_FILL_EMBED_RB )
+ {
+ DBG_ASSERT( pDoc->IsEmbedded(), "!pDoc->IsEmbedded()" );
+ ScRange aRange;
+ pDoc->GetEmbedded( aRange);
+ ScRefType eRefMode = (nMode == SC_FILL_EMBED_LT) ? SC_REFTYPE_EMBED_LT : SC_REFTYPE_EMBED_RB;
+ if (pViewData->GetRefType() != eRefMode)
+ {
+ if ( nMode == SC_FILL_EMBED_LT )
+ pView->InitRefMode( aRange.aEnd.Col(), aRange.aEnd.Row(), nTab, eRefMode );
+ else
+ pView->InitRefMode( aRange.aStart.Col(), aRange.aStart.Row(), nTab, eRefMode );
+ CreateAnchor();
+ }
+
+ pView->UpdateRef( nPosX, nPosY, nTab );
+ }
+ else if ( nMode == SC_FILL_MATRIX )
+ {
+ SCCOL nStartX, nEndX;
+ SCROW nStartY, nEndY; // Block
+ SCTAB nDummy;
+ pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy );
+
+ if (pViewData->GetRefType() != SC_REFTYPE_FILL)
+ {
+ pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
+ CreateAnchor();
+ }
+
+ if ( nPosX < nStartX ) nPosX = nStartX;
+ if ( nPosY < nStartY ) nPosY = nStartY;
+
+ pView->UpdateRef( nPosX, nPosY, nTab );
+ }
+ // else neue Modi
+ }
+ else // normales Markieren
+ {
+ BOOL bHideCur = bAnchor && ( (SCCOL)nPosX != pViewData->GetCurX() ||
+ (SCROW)nPosY != pViewData->GetCurY() );
+ if (bHideCur)
+ pView->HideAllCursors(); // sonst zweimal: Block und SetCursor
+
+ if (bAnchor)
+ {
+ if (!bStarted)
+ {
+ BOOL bMove = ( nPosX != (SCsCOL) aAnchorPos.Col() ||
+ nPosY != (SCsROW) aAnchorPos.Row() );
+ if ( bMove || ( pEngine && pEngine->GetMouseEvent().IsShift() ) )
+ {
+ pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(),
+ aAnchorPos.Tab(), TRUE );
+ bStarted = TRUE;
+ }
+ }
+ if (bStarted)
+ pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, FALSE, FALSE, TRUE );
+ }
+ else
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if (rMark.IsMarked() || rMark.IsMultiMarked())
+ {
+ pView->DoneBlockMode(TRUE);
+ pView->InitBlockMode( nPosX, nPosY, nTab, TRUE );
+ pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab );
+
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ bStarted = TRUE;
+ }
+ // #i3875# *Hack* When a new cell is Ctrl-clicked with no pre-selected cells,
+ // it highlights that new cell as well as the old cell where the cursor is
+ // positioned prior to the click. A selection mode via Shift-F8 should also
+ // follow the same behavior.
+ else if ( pViewData->IsSelCtrlMouseClick() )
+ {
+ SCCOL nOldX = pViewData->GetCurX();
+ SCROW nOldY = pViewData->GetCurY();
+
+ pView->InitBlockMode( nOldX, nOldY, nTab, TRUE );
+ pView->MarkCursor( (SCCOL) nOldX, (SCROW) nOldY, nTab );
+
+ if ( nOldX != nPosX || nOldY != nPosY )
+ {
+ pView->DoneBlockMode( TRUE );
+ pView->InitBlockMode( nPosX, nPosY, nTab, TRUE );
+ pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab );
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ }
+
+ bStarted = TRUE;
+ }
+ }
+
+ pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
+ pViewData->SetRefStart( nPosX, nPosY, nTab );
+ if (bHideCur)
+ pView->ShowAllCursors();
+ }
+
+ if (bHide)
+ pView->ShowAllCursors();
+
+ return TRUE;
+}
+
+BOOL __EXPORT ScViewFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
+{
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ return FALSE;
+
+ if (pViewData->IsAnyFillMode())
+ return FALSE;
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if (bAnchor || !rMark.IsMultiMarked())
+ {
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), GetWhich(), nPosX, nPosY );
+ return pViewData->GetMarkData().IsCellMarked( (SCCOL) nPosX, (SCROW) nPosY );
+ }
+
+ return FALSE;
+}
+
+void __EXPORT ScViewFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ )
+{
+ // gibt's nicht
+}
+
+void __EXPORT ScViewFunctionSet::DeselectAll()
+{
+ if (pViewData->IsAnyFillMode())
+ return;
+
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ {
+ pViewData->GetView()->DoneRefMode( FALSE );
+ }
+ else
+ {
+ pViewData->GetView()->DoneBlockMode( FALSE );
+ pViewData->GetViewShell()->UpdateInputHandler();
+ }
+
+ bAnchor = FALSE;
+}
+
+//------------------------------------------------------------------------
+
+ScViewSelectionEngine::ScViewSelectionEngine( Window* pWindow, ScTabView* pView,
+ ScSplitPos eSplitPos ) :
+ SelectionEngine( pWindow, pView->GetFunctionSet() ),
+ eWhich( eSplitPos )
+{
+ // Parameter einstellen
+ SetSelectionMode( MULTIPLE_SELECTION );
+ EnableDrag( TRUE );
+}
+
+
+//------------------------------------------------------------------------
+
+//
+// Spalten- / Zeilenheader
+//
+
+ScHeaderFunctionSet::ScHeaderFunctionSet( ScViewData* pNewViewData ) :
+ pViewData( pNewViewData ),
+ bColumn( FALSE ),
+ eWhich( SC_SPLIT_TOPLEFT ),
+ bAnchor( FALSE ),
+ nCursorPos( 0 )
+{
+ DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet");
+}
+
+void ScHeaderFunctionSet::SetColumn( BOOL bSet )
+{
+ bColumn = bSet;
+}
+
+void ScHeaderFunctionSet::SetWhich( ScSplitPos eNew )
+{
+ eWhich = eNew;
+}
+
+void __EXPORT ScHeaderFunctionSet::BeginDrag()
+{
+ // gippsnich
+}
+
+void __EXPORT ScHeaderFunctionSet::CreateAnchor()
+{
+ if (bAnchor)
+ return;
+
+ ScTabView* pView = pViewData->GetView();
+ pView->DoneBlockMode( TRUE );
+ if (bColumn)
+ {
+ pView->InitBlockMode( static_cast<SCCOL>(nCursorPos), 0, pViewData->GetTabNo(), TRUE, TRUE, FALSE );
+ pView->MarkCursor( static_cast<SCCOL>(nCursorPos), MAXROW, pViewData->GetTabNo() );
+ }
+ else
+ {
+ pView->InitBlockMode( 0, nCursorPos, pViewData->GetTabNo(), TRUE, FALSE, TRUE );
+ pView->MarkCursor( MAXCOL, nCursorPos, pViewData->GetTabNo() );
+ }
+ bAnchor = TRUE;
+}
+
+void __EXPORT ScHeaderFunctionSet::DestroyAnchor()
+{
+ pViewData->GetView()->DoneBlockMode( TRUE );
+ bAnchor = FALSE;
+}
+
+BOOL __EXPORT ScHeaderFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOOL /* bDontSelectAtCursor */ )
+{
+ if ( bDidSwitch )
+ {
+ // die naechste gueltige Position muss vom anderen Fenster kommen
+ if ( rPointPixel == aSwitchPos )
+ return FALSE; // nicht auf falschem Fenster scrollen
+ else
+ bDidSwitch = FALSE;
+ }
+
+ // Scrolling
+
+ Size aWinSize = pViewData->GetActiveWin()->GetOutputSizePixel();
+ BOOL bScroll;
+ if (bColumn)
+ bScroll = ( rPointPixel.X() < 0 || rPointPixel.X() >= aWinSize.Width() );
+ else
+ bScroll = ( rPointPixel.Y() < 0 || rPointPixel.Y() >= aWinSize.Height() );
+
+ // ueber Fixier-Grenze bewegt?
+
+ BOOL bSwitched = FALSE;
+ if ( bColumn )
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ {
+ if ( rPointPixel.X() > aWinSize.Width() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bSwitched = TRUE;
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = TRUE;
+ }
+ }
+ }
+ else // Zeilenkoepfe
+ {
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ {
+ if ( rPointPixel.Y() > aWinSize.Height() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bSwitched = TRUE;
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = TRUE;
+ }
+ }
+ }
+ if (bSwitched)
+ {
+ aSwitchPos = rPointPixel;
+ bDidSwitch = TRUE;
+ return FALSE; // nicht mit falschen Positionen rechnen
+ }
+
+ //
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(),
+ nPosX, nPosY, FALSE );
+ if (bColumn)
+ {
+ nCursorPos = static_cast<SCCOLROW>(nPosX);
+ nPosY = pViewData->GetPosY(WhichV(pViewData->GetActivePart()));
+ }
+ else
+ {
+ nCursorPos = static_cast<SCCOLROW>(nPosY);
+ nPosX = pViewData->GetPosX(WhichH(pViewData->GetActivePart()));
+ }
+
+ ScTabView* pView = pViewData->GetView();
+ BOOL bHide = pViewData->GetCurX() != nPosX ||
+ pViewData->GetCurY() != nPosY;
+ if (bHide)
+ pView->HideAllCursors();
+
+ if (bScroll)
+ pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE );
+ pView->SetCursor( nPosX, nPosY );
+
+ if ( !bAnchor || !pView->IsBlockMode() )
+ {
+ pView->DoneBlockMode( TRUE );
+ pViewData->GetMarkData().MarkToMulti(); //! wer verstellt das ???
+ pView->InitBlockMode( nPosX, nPosY, pViewData->GetTabNo(), TRUE, bColumn, !bColumn );
+
+ bAnchor = TRUE;
+ }
+
+ pView->MarkCursor( nPosX, nPosY, pViewData->GetTabNo(), bColumn, !bColumn );
+
+ // SelectionChanged innerhalb von HideCursor wegen UpdateAutoFillMark
+ pView->SelectionChanged();
+
+ if (bHide)
+ pView->ShowAllCursors();
+
+ return TRUE;
+}
+
+BOOL __EXPORT ScHeaderFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
+{
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(),
+ nPosX, nPosY, FALSE );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if (bColumn)
+ return rMark.IsColumnMarked( nPosX );
+ else
+ return rMark.IsRowMarked( nPosY );
+}
+
+void __EXPORT ScHeaderFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ )
+{
+}
+
+void __EXPORT ScHeaderFunctionSet::DeselectAll()
+{
+ pViewData->GetView()->DoneBlockMode( FALSE );
+ bAnchor = FALSE;
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderSelectionEngine::ScHeaderSelectionEngine( Window* pWindow, ScHeaderFunctionSet* pFuncSet ) :
+ SelectionEngine( pWindow, pFuncSet )
+{
+ // Parameter einstellen
+ SetSelectionMode( MULTIPLE_SELECTION );
+ EnableDrag( FALSE );
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/selectionstate.cxx b/sc/source/ui/view/selectionstate.cxx
new file mode 100644
index 000000000000..0edd50a0b825
--- /dev/null
+++ b/sc/source/ui/view/selectionstate.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "selectionstate.hxx"
+
+#include <editeng/editview.hxx>
+#include "viewdata.hxx"
+
+// ============================================================================
+
+ScSelectionState::ScSelectionState( ScViewData& rViewData ) :
+ meType( SC_SELECTTYPE_NONE )
+{
+ maCursor.SetTab( rViewData.GetTabNo() );
+ ScSplitPos eWhich = rViewData.GetActivePart();
+
+ if( rViewData.HasEditView( eWhich ) )
+ {
+ meType = SC_SELECTTYPE_EDITCELL;
+ maCursor.SetCol( rViewData.GetEditViewCol() );
+ maCursor.SetRow( rViewData.GetEditViewRow() );
+ maEditSel = rViewData.GetEditView( eWhich )->GetSelection();
+ }
+ else
+ {
+ maCursor.SetCol( rViewData.GetCurX() );
+ maCursor.SetRow( rViewData.GetCurY() );
+
+ ScMarkData& rMarkData = rViewData.GetMarkData();
+ rMarkData.MarkToMulti();
+ if( rMarkData.IsMultiMarked() )
+ {
+ meType = SC_SELECTTYPE_SHEET;
+ rMarkData.FillRangeListWithMarks( &maSheetSel, FALSE );
+ }
+ // else type is SC_SELECTTYPE_NONE - already initialized
+ }
+}
+
+bool operator==( const ScSelectionState& rL, const ScSelectionState& rR )
+{
+ bool bEqual = rL.GetSelectionType() == rR.GetSelectionType();
+ if( bEqual ) switch( rL.GetSelectionType() )
+ {
+ case SC_SELECTTYPE_EDITCELL:
+ bEqual &= ( rL.GetEditSelection().IsEqual( rR.GetEditSelection() ) != FALSE );
+ // run through!
+ case SC_SELECTTYPE_SHEET:
+ bEqual &= (rL.GetSheetSelection() == rR.GetSheetSelection()) == TRUE;
+ // run through!
+ case SC_SELECTTYPE_NONE:
+ bEqual &= rL.GetCellCursor() == rR.GetCellCursor();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return bEqual;
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/spelldialog.cxx b/sc/source/ui/view/spelldialog.cxx
new file mode 100644
index 000000000000..ee13ee9fbf90
--- /dev/null
+++ b/sc/source/ui/view/spelldialog.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "spelldialog.hxx"
+
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/unolingu.hxx>
+#include "selectionstate.hxx"
+
+#include "spelleng.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "editable.hxx"
+#include "undoblk.hxx"
+
+// ============================================================================
+
+SFX_IMPL_CHILDWINDOW( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
+
+ScSpellDialogChildWindow::ScSpellDialogChildWindow( Window* pParentP, USHORT nId,
+ SfxBindings* pBindings, SfxChildWinInfo* pInfo ) :
+ ::svx::SpellDialogChildWindow( pParentP, nId, pBindings, pInfo ),
+ mpViewShell( 0 ),
+ mpViewData( 0 ),
+ mpDocShell( 0 ),
+ mpDoc( 0 ),
+ mbNeedNextObj( false ),
+ mbOldIdleDisabled( false )
+{
+ Init();
+}
+
+ScSpellDialogChildWindow::~ScSpellDialogChildWindow()
+{
+ Reset();
+}
+
+SfxChildWinInfo ScSpellDialogChildWindow::GetInfo() const
+{
+ return ::svx::SpellDialogChildWindow::GetInfo();
+}
+
+void ScSpellDialogChildWindow::InvalidateSpellDialog()
+{
+ ::svx::SpellDialogChildWindow::InvalidateSpellDialog();
+}
+
+// protected ------------------------------------------------------------------
+
+::svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ )
+{
+ ::svx::SpellPortions aPortions;
+ if( mxEngine.get() && mpViewData )
+ {
+ if( EditView* pEditView = mpViewData->GetSpellingView() )
+ {
+ // edit engine handles cell iteration internally
+ do
+ {
+ if( mbNeedNextObj )
+ mxEngine->SpellNextDocument();
+ mbNeedNextObj = !mxEngine->IsFinished() && !mxEngine->SpellSentence( *pEditView, aPortions, false );
+ }
+ while( mbNeedNextObj );
+ }
+
+ // finished? - close the spelling dialog
+ if( mxEngine->IsFinished() )
+ GetBindings().GetDispatcher()->Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
+ }
+ return aPortions;
+}
+
+void ScSpellDialogChildWindow::ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck )
+{
+ if( mxEngine.get() && mpViewData )
+ if( EditView* pEditView = mpViewData->GetSpellingView() )
+ mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck );
+}
+
+void ScSpellDialogChildWindow::GetFocus()
+{
+ if( IsSelectionChanged() )
+ {
+ Reset();
+ InvalidateSpellDialog();
+ Init();
+ }
+}
+
+void ScSpellDialogChildWindow::LoseFocus()
+{
+}
+
+// private --------------------------------------------------------------------
+
+void ScSpellDialogChildWindow::Reset()
+{
+ if( mpViewShell && (mpViewShell == PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
+ {
+ if( mxEngine.get() && mxEngine->IsAnyModified() )
+ {
+ const ScAddress& rCursor = mxOldSel->GetCellCursor();
+ SCTAB nTab = rCursor.Tab();
+ SCCOL nOldCol = rCursor.Col();
+ SCROW nOldRow = rCursor.Row();
+ SCCOL nNewCol = mpViewData->GetCurX();
+ SCROW nNewRow = mpViewData->GetCurY();
+ mpDocShell->GetUndoManager()->AddUndoAction( new ScUndoConversion(
+ mpDocShell, mpViewData->GetMarkData(),
+ nOldCol, nOldRow, nTab, mxUndoDoc.release(),
+ nNewCol, nNewRow, nTab, mxRedoDoc.release(),
+ ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
+ mpDoc->SetDirty();
+ mpDocShell->SetDocumentModified();
+ }
+
+ mpViewData->SetSpellingView( 0 );
+ mpViewShell->KillEditView( TRUE );
+ mpDocShell->PostPaintGridAll();
+ mpViewShell->UpdateInputHandler();
+ mpDoc->DisableIdle( mbOldIdleDisabled );
+ }
+ mxEngine.reset();
+ mxUndoDoc.reset();
+ mxRedoDoc.reset();
+ mxOldSel.reset();
+ mpViewShell = 0;
+ mpViewData = 0;
+ mpDocShell = 0;
+ mpDoc = 0;
+ mbNeedNextObj = false;
+ mbOldIdleDisabled = false;
+}
+
+void ScSpellDialogChildWindow::Init()
+{
+ if( mpViewShell )
+ return;
+ if( (mpViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) == 0 )
+ return;
+
+ mpViewData = mpViewShell->GetViewData();
+
+ // exit edit mode - TODO support spelling in edit mode
+ if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
+ SC_MOD()->InputEnterHandler();
+
+ mxOldSel.reset( new ScSelectionState( *mpViewData ) );
+
+ mpDocShell = mpViewData->GetDocShell();
+ mpDoc = mpDocShell->GetDocument();
+
+ const ScAddress& rCursor = mxOldSel->GetCellCursor();
+ SCCOL nCol = rCursor.Col();
+ SCROW nRow = rCursor.Row();
+ SCTAB nTab = rCursor.Tab();
+
+ ScMarkData& rMarkData = mpViewData->GetMarkData();
+ rMarkData.MarkToMulti();
+
+ switch( mxOldSel->GetSelectionType() )
+ {
+ case SC_SELECTTYPE_NONE:
+ case SC_SELECTTYPE_SHEET:
+ {
+ // test if there is something editable
+ ScEditableTester aTester( mpDoc, rMarkData );
+ if( !aTester.IsEditable() )
+ {
+ // #i85751# Don't show a ErrorMessage here, because the vcl
+ // parent of the InfoBox is not fully initialized yet.
+ // This leads to problems in the modality behaviour of the
+ // ScSpellDialogChildWindow.
+
+ //mpViewShell->ErrorMessage( aTester.GetMessageId() );
+ return;
+ }
+ }
+ break;
+
+ // edit mode exited, see TODO above
+// case SC_SELECTTYPE_EDITCELL:
+// break;
+
+ default:
+ DBG_ERRORFILE( "ScSpellDialogChildWindow::Init - unknown selection type" );
+ }
+
+ mbOldIdleDisabled = mpDoc->IsIdleDisabled();
+ mpDoc->DisableIdle( TRUE ); // #42726# stop online spelling
+
+ // *** create Undo/Redo documents *** -------------------------------------
+
+ mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
+ mxUndoDoc->InitUndo( mpDoc, nTab, nTab );
+ mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
+ mxRedoDoc->InitUndo( mpDoc, nTab, nTab );
+
+ if ( rMarkData.GetSelectCount() > 1 )
+ {
+ SCTAB nTabCount = mpDoc->GetTableCount();
+ for( SCTAB nOtherTab = 0; nOtherTab < nTabCount; ++nOtherTab )
+ {
+ if( rMarkData.GetTableSelect( nOtherTab ) && (nOtherTab != nTab) )
+ {
+ mxUndoDoc->AddUndoTab( nOtherTab, nOtherTab );
+ mxRedoDoc->AddUndoTab( nOtherTab, nOtherTab );
+ }
+ }
+ }
+
+ // *** create and init the edit engine *** --------------------------------
+
+ mxEngine.reset( new ScSpellingEngine(
+ mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
+ mxEngine->SetRefDevice( mpViewData->GetActiveWin() );
+
+ mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
+ EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
+ mpViewData->SetSpellingView( pEditView );
+ Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
+ pEditView->SetOutputArea( aRect );
+ mxEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
+ mxEngine->EnableUndo( FALSE );
+ mxEngine->SetPaperSize( aRect.GetSize() );
+ mxEngine->SetText( EMPTY_STRING );
+ mxEngine->ClearModifyFlag();
+
+ mbNeedNextObj = true;
+}
+
+bool ScSpellDialogChildWindow::IsSelectionChanged()
+{
+ if( !mxOldSel.get() || !mpViewShell || (mpViewShell != PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
+ return true;
+
+ if( EditView* pEditView = mpViewData->GetSpellingView() )
+ if( pEditView->GetEditEngine() != mxEngine.get() )
+ return true;
+
+ ScSelectionState aNewSel( *mpViewData );
+ return mxOldSel->GetSheetSelection() != aNewSel.GetSheetSelection();
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/spelleng.cxx b/sc/source/ui/view/spelleng.cxx
new file mode 100644
index 000000000000..ac6288028dfc
--- /dev/null
+++ b/sc/source/ui/view/spelleng.cxx
@@ -0,0 +1,458 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "spelleng.hxx"
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+
+#include <memory>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/langitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editview.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "spelldialog.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "waitoff.hxx"
+#include "globstr.hrc"
+
+
+using namespace ::com::sun::star;
+
+// ============================================================================
+
+namespace {
+
+bool lclHasString( ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString )
+{
+ String aCompStr;
+ rDoc.GetString( nCol, nRow, nTab, aCompStr );
+ return aCompStr == rString; //! case-insensitive?
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ScConversionEngineBase::ScConversionEngineBase(
+ SfxItemPool* pEnginePoolP, ScViewData& rViewData,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
+ ScEditEngineDefaulter( pEnginePoolP ),
+ mrViewData( rViewData ),
+ mrDocShell( *rViewData.GetDocShell() ),
+ mrDoc( *rViewData.GetDocShell()->GetDocument() ),
+ maSelState( rViewData ),
+ mpUndoDoc( pUndoDoc ),
+ mpRedoDoc( pRedoDoc ),
+ meCurrLang( LANGUAGE_ENGLISH_US ),
+ mbIsAnyModified( false ),
+ mbInitialState( true ),
+ mbWrappedInTable( false ),
+ mbFinished( false )
+{
+ maSelState.GetCellCursor().GetVars( mnStartCol, mnStartRow, mnStartTab );
+ // start with cell A1 in cell/range/multi-selection, will seek to first selected
+ if( maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET )
+ {
+ mnStartCol = 0;
+ mnStartRow = 0;
+ }
+ mnCurrCol = mnStartCol;
+ mnCurrRow = mnStartRow;
+}
+
+ScConversionEngineBase::~ScConversionEngineBase()
+{
+}
+
+bool ScConversionEngineBase::FindNextConversionCell()
+{
+ ScMarkData& rMark = mrViewData.GetMarkData();
+ ScTabViewShell* pViewShell = mrViewData.GetViewShell();
+ ScBaseCell* pCell = NULL;
+ const ScPatternAttr* pPattern = NULL;
+ const ScPatternAttr* pLastPattern = NULL;
+ ::std::auto_ptr< SfxItemSet > pEditDefaults( new SfxItemSet( GetEmptyItemSet() ) );
+
+ if( IsModified() )
+ {
+ mbIsAnyModified = true;
+
+ String aNewStr = GetText();
+
+ BOOL bMultiTab = (rMark.GetSelectCount() > 1);
+ String aVisibleStr;
+ if( bMultiTab )
+ mrDoc.GetString( mnCurrCol, mnCurrRow, mnStartTab, aVisibleStr );
+
+ for( SCTAB nTab = 0, nTabCount = mrDoc.GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ // #69965# always change the cell on the visible tab,
+ // on the other selected tabs only if they contain the same text
+
+ if( (nTab == mnStartTab) ||
+ (bMultiTab && rMark.GetTableSelect( nTab ) &&
+ lclHasString( mrDoc, mnCurrCol, mnCurrRow, nTab, aVisibleStr )) )
+ {
+ ScAddress aPos( mnCurrCol, mnCurrRow, nTab );
+ CellType eCellType = mrDoc.GetCellType( aPos );
+ pCell = mrDoc.GetCell( aPos );
+
+ if( mpUndoDoc && pCell )
+ {
+ ScBaseCell* pUndoCell = pCell->CloneWithoutNote( *mpUndoDoc );
+ mpUndoDoc->PutCell( aPos, pUndoCell );
+ }
+
+ if( eCellType == CELLTYPE_EDIT )
+ {
+ if( pCell )
+ {
+ ScEditCell* pEditCell = static_cast< ScEditCell* >( pCell );
+ ::std::auto_ptr< EditTextObject > pEditObj( CreateTextObject() );
+ pEditCell->SetData( pEditObj.get(), GetEditTextObjectPool() );
+ }
+ }
+ else
+ {
+ mrDoc.SetString( mnCurrCol, mnCurrRow, nTab, aNewStr );
+ pCell = mrDoc.GetCell( aPos );
+ }
+
+ if( mpRedoDoc && pCell )
+ {
+ ScBaseCell* pRedoCell = pCell->CloneWithoutNote( *mpRedoDoc );
+ mpRedoDoc->PutCell( aPos, pRedoCell );
+ }
+
+ mrDocShell.PostPaintCell( mnCurrCol, mnCurrRow, nTab );
+ }
+ }
+ }
+ pCell = NULL;
+ SCCOL nNewCol = mnCurrCol;
+ SCROW nNewRow = mnCurrRow;
+
+ if( mbInitialState )
+ {
+ /* On very first call, decrement row to let GetNextSpellingCell() find
+ the first cell of current range. */
+ mbInitialState = false;
+ --nNewRow;
+ }
+
+ bool bSheetSel = maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET;
+ bool bLoop = true;
+ bool bFound = false;
+ while( bLoop && !bFound )
+ {
+ bLoop = mrDoc.GetNextSpellingCell( nNewCol, nNewRow, mnStartTab, bSheetSel, rMark );
+ if( bLoop )
+ {
+ FillFromCell( mnCurrCol, mnCurrRow, mnStartTab );
+
+ if( mbWrappedInTable && ((nNewCol > mnStartCol) || ((nNewCol == mnStartCol) && (nNewRow >= mnStartRow))) )
+ {
+ ShowFinishDialog();
+ bLoop = false;
+ mbFinished = true;
+ }
+ else if( nNewCol > MAXCOL )
+ {
+ // no more cells in the sheet - try to restart at top of sheet
+
+ if( bSheetSel || ((mnStartCol == 0) && (mnStartRow == 0)) )
+ {
+ // conversion started at cell A1 or in selection, do not query to restart at top
+ ShowFinishDialog();
+ bLoop = false;
+ mbFinished = true;
+ }
+ else if( ShowTableWrapDialog() )
+ {
+ // conversion started anywhere but in cell A1, user wants to restart
+ nNewRow = MAXROW + 2;
+ mbWrappedInTable = true;
+ }
+ else
+ {
+ bLoop = false;
+ mbFinished = true;
+ }
+ }
+ else
+ {
+ pPattern = mrDoc.GetPattern( nNewCol, nNewRow, mnStartTab );
+ if( pPattern && (pPattern != pLastPattern) )
+ {
+ pPattern->FillEditItemSet( pEditDefaults.get() );
+ SetDefaults( *pEditDefaults );
+ pLastPattern = pPattern;
+ }
+
+ // language changed?
+ const SfxPoolItem* pItem = mrDoc.GetAttr( nNewCol, nNewRow, mnStartTab, ATTR_FONT_LANGUAGE );
+ if( const SvxLanguageItem* pLangItem = PTR_CAST( SvxLanguageItem, pItem ) )
+ {
+ LanguageType eLang = static_cast< LanguageType >( pLangItem->GetValue() );
+ if( eLang == LANGUAGE_SYSTEM )
+ eLang = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
+ if( eLang != meCurrLang )
+ {
+ meCurrLang = eLang;
+ SetDefaultLanguage( eLang );
+ }
+ }
+
+ FillFromCell( nNewCol, nNewRow, mnStartTab );
+
+ bFound = bLoop && NeedsConversion();
+ }
+ }
+ }
+
+ if( bFound )
+ {
+ pViewShell->AlignToCursor( nNewCol, nNewRow, SC_FOLLOW_JUMP );
+ pViewShell->SetCursor( nNewCol, nNewRow, TRUE );
+ mrViewData.GetView()->MakeEditView( this, nNewCol, nNewRow );
+ EditView* pEditView = mrViewData.GetSpellingView();
+ // maSelState.GetEditSelection() returns (0,0) if not in edit mode -> ok
+ pEditView->SetSelection( maSelState.GetEditSelection() );
+
+ ClearModifyFlag();
+ mnCurrCol = nNewCol;
+ mnCurrRow = nNewRow;
+ }
+
+ return bFound;
+}
+
+void ScConversionEngineBase::RestoreCursorPos()
+{
+ const ScAddress& rPos = maSelState.GetCellCursor();
+ mrViewData.GetViewShell()->SetCursor( rPos.Col(), rPos.Row() );
+}
+
+bool ScConversionEngineBase::ShowTableWrapDialog()
+{
+ // default: no dialog, always restart at top
+ return true;
+}
+
+void ScConversionEngineBase::ShowFinishDialog()
+{
+ // default: no dialog
+}
+
+// private --------------------------------------------------------------------
+
+void ScConversionEngineBase::FillFromCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ CellType eCellType;
+ mrDoc.GetCellType( nCol, nRow, nTab, eCellType );
+
+ switch( eCellType )
+ {
+ case CELLTYPE_STRING:
+ {
+ String aText;
+ mrDoc.GetString( nCol, nRow, nTab, aText );
+ SetText( aText );
+ }
+ break;
+ case CELLTYPE_EDIT:
+ {
+ ScBaseCell* pCell = NULL;
+ mrDoc.GetCell( nCol, nRow, nTab, pCell );
+ if( pCell )
+ {
+ const EditTextObject* pNewEditObj = NULL;
+ static_cast< ScEditCell* >( pCell )->GetData( pNewEditObj );
+ if( pNewEditObj )
+ SetText( *pNewEditObj );
+ }
+ }
+ break;
+ default:
+ SetText( EMPTY_STRING );
+ }
+}
+
+// ============================================================================
+
+ScSpellingEngine::ScSpellingEngine(
+ SfxItemPool* pEnginePoolP, ScViewData& rViewData,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc,
+ XSpellCheckerRef xSpeller ) :
+ ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc )
+{
+ SetSpeller( xSpeller );
+}
+
+void ScSpellingEngine::ConvertAll( EditView& rEditView )
+{
+ EESpellState eState = EE_SPELL_OK;
+ if( FindNextConversionCell() )
+ eState = rEditView.StartSpeller( static_cast< BOOL >( TRUE ) );
+
+ DBG_ASSERT( eState != EE_SPELL_NOSPELLER, "ScSpellingEngine::Convert - no spell checker" );
+ if( eState == EE_SPELL_NOLANGUAGE )
+ {
+ Window* pParent = GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ InfoBox( pParent, ScGlobal::GetRscString( STR_NOLANGERR ) ).Execute();
+ }
+}
+
+BOOL ScSpellingEngine::SpellNextDocument()
+{
+ return FindNextConversionCell();
+}
+
+bool ScSpellingEngine::NeedsConversion()
+{
+ return HasSpellErrors() != EE_SPELL_OK;
+}
+
+bool ScSpellingEngine::ShowTableWrapDialog()
+{
+ Window* pParent = GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ MessBox aMsgBox( pParent, WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_SPELLING_BEGIN_TAB) );
+ return aMsgBox.Execute() == RET_YES;
+}
+
+void ScSpellingEngine::ShowFinishDialog()
+{
+ Window* pParent = GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ InfoBox( pParent, ScGlobal::GetRscString( STR_SPELLING_STOP_OK ) ).Execute();
+}
+
+Window* ScSpellingEngine::GetDialogParent()
+{
+ USHORT nWinId = ScSpellDialogChildWindow::GetChildWindowId();
+ SfxViewFrame* pViewFrm = mrViewData.GetViewShell()->GetViewFrame();
+ if( pViewFrm->HasChildWindow( nWinId ) )
+ if( SfxChildWindow* pChild = pViewFrm->GetChildWindow( nWinId ) )
+ if( Window* pWin = pChild->GetWindow() )
+ if( pWin->IsVisible() )
+ return pWin;
+
+ // fall back to standard dialog parent
+ return mrDocShell.GetActiveDialogParent();
+}
+
+// ============================================================================
+
+ScConversionParam::ScConversionParam( ScConversionType eConvType ) :
+ meConvType( eConvType ),
+ meSourceLang( LANGUAGE_NONE ),
+ meTargetLang( LANGUAGE_NONE ),
+ mnOptions( 0 ),
+ mbUseTargetFont( false ),
+ mbIsInteractive( false )
+{
+}
+
+ScConversionParam::ScConversionParam( ScConversionType eConvType,
+ LanguageType eLang, sal_Int32 nOptions, bool bIsInteractive ) :
+ meConvType( eConvType ),
+ meSourceLang( eLang ),
+ meTargetLang( eLang ),
+ mnOptions( nOptions ),
+ mbUseTargetFont( false ),
+ mbIsInteractive( bIsInteractive )
+{
+ if (LANGUAGE_KOREAN == eLang)
+ mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+}
+
+ScConversionParam::ScConversionParam( ScConversionType eConvType,
+ LanguageType eSourceLang, LanguageType eTargetLang, const Font& rTargetFont,
+ sal_Int32 nOptions, bool bIsInteractive ) :
+ meConvType( eConvType ),
+ meSourceLang( eSourceLang ),
+ meTargetLang( eTargetLang ),
+ maTargetFont( rTargetFont ),
+ mnOptions( nOptions ),
+ mbUseTargetFont( true ),
+ mbIsInteractive( bIsInteractive )
+{
+ if (LANGUAGE_KOREAN == meSourceLang && LANGUAGE_KOREAN == meTargetLang)
+ mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+}
+
+// ----------------------------------------------------------------------------
+
+ScTextConversionEngine::ScTextConversionEngine(
+ SfxItemPool* pEnginePoolP, ScViewData& rViewData,
+ const ScConversionParam& rConvParam,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
+ ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc ),
+ maConvParam( rConvParam )
+{
+}
+
+void ScTextConversionEngine::ConvertAll( EditView& rEditView )
+{
+ if( FindNextConversionCell() )
+ {
+ rEditView.StartTextConversion(
+ maConvParam.GetSourceLang(), maConvParam.GetTargetLang(), maConvParam.GetTargetFont(),
+ maConvParam.GetOptions(), maConvParam.IsInteractive(), TRUE );
+ // #i34769# restore initial cursor position
+ RestoreCursorPos();
+ }
+}
+
+BOOL ScTextConversionEngine::ConvertNextDocument()
+{
+ return FindNextConversionCell();
+}
+
+bool ScTextConversionEngine::NeedsConversion()
+{
+ return HasConvertibleTextPortion( maConvParam.GetSourceLang() );
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx
new file mode 100644
index 000000000000..6014ded96e1e
--- /dev/null
+++ b/sc/source/ui/view/tabcont.cxx
@@ -0,0 +1,638 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <vcl/sound.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include "tabcont.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "transobj.hxx"
+#include "clipparam.hxx"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) :
+ TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL |
+ WB_RANGESELECT | WB_MULTISELECT | WB_DRAG | WB_SIZEABLE ) ),
+ DropTargetHelper( this ),
+ DragSourceHelper( this ),
+ pViewData( pData ),
+ nMouseClickPageId( TabBar::PAGE_NOT_FOUND ),
+ nSelPageIdByMouse( TabBar::PAGE_NOT_FOUND ),
+ bErrorShown( FALSE )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ String aString;
+ Color aTabBgColor;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ if (pDoc->GetName(i,aString))
+ {
+ if ( pDoc->IsScenario(i) )
+ InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL );
+ else
+ InsertPage( static_cast<sal_uInt16>(i)+1, aString );
+ if ( !pDoc->IsDefaultTabBgColor(i) )
+ {
+ aTabBgColor = pDoc->GetTabBgColor(i);
+ SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor );
+ }
+ }
+ }
+ }
+
+ SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
+
+ SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) );
+
+ SetSplitHdl( LINK( pViewData->GetView(), ScTabView, TabBarResize ) );
+
+ EnableEditMode();
+}
+
+ScTabControl::~ScTabControl()
+{
+}
+
+USHORT ScTabControl::GetMaxId() const
+{
+ USHORT nVisCnt = GetPageCount();
+ if (nVisCnt)
+ return GetPageId(nVisCnt-1);
+
+ return 0;
+}
+
+SCTAB ScTabControl::GetPrivatDropPos(const Point& rPos )
+{
+ USHORT nPos = ShowDropPos(rPos);
+
+ SCTAB nRealPos = static_cast<SCTAB>(nPos);
+
+ if(nPos !=0 )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ SCTAB nCount = pDoc->GetTableCount();
+
+ USHORT nViewPos=0;
+ nRealPos = nCount;
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ nViewPos++;
+ if(nViewPos==nPos)
+ {
+ SCTAB j;
+ for (j=i+1; j<nCount; j++)
+ {
+ if (pDoc->IsVisible(j))
+ {
+ break;
+ }
+ }
+ nRealPos =j;
+ break;
+ }
+ }
+ }
+ }
+ return nRealPos ;
+}
+
+void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ ScModule* pScMod = SC_MOD();
+ if ( !pScMod->IsModalMode() && !pScMod->IsFormulaMode() && !IsInEditMode() )
+ {
+ // View aktivieren
+ pViewData->GetViewShell()->SetActive(); // Appear und SetViewFrame
+ pViewData->GetView()->ActiveGrabFocus();
+ }
+
+ /* #47745# Click into free area -> insert new sheet (like in Draw).
+ Needing clean left click without modifiers (may be context menu).
+ #106948# Remember clicks to all pages, to be able to move mouse pointer later. */
+ if( rMEvt.IsLeft() && (rMEvt.GetModifier() == 0) )
+ nMouseClickPageId = GetPageId( rMEvt.GetPosPixel() );
+ else
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+
+ TabBar::MouseButtonDown( rMEvt );
+}
+
+void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ Point aPos = PixelToLogic( rMEvt.GetPosPixel() );
+
+ // mouse button down and up on same page?
+ if( nMouseClickPageId != GetPageId( aPos ) )
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+
+ if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TAB_PAGE_NOTFOUND )
+ {
+ SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher();
+ pDispatcher->Execute( FID_TAB_MENU_RENAME, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+ }
+
+ if( nMouseClickPageId == 0 )
+ {
+ // Click in the area next to the existing tabs:
+ // #i70320# if several sheets are selected, deselect all ecxept the current sheet,
+ // otherwise add new sheet
+ USHORT nSlot = ( GetSelectPageCount() > 1 ) ? FID_TAB_DESELECTALL : FID_INS_TABLE;
+ SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher();
+ pDispatcher->Execute( nSlot, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+ // forget page ID, to be really sure that the dialog is not called twice
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+ }
+
+ TabBar::MouseButtonUp( rMEvt );
+}
+
+void ScTabControl::Select()
+{
+ /* Remember last clicked page ID. */
+ nSelPageIdByMouse = nMouseClickPageId;
+ /* Reset nMouseClickPageId, so that next Select() call may invalidate
+ nSelPageIdByMouse (i.e. if called from keyboard). */
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+
+ ScModule* pScMod = SC_MOD();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nCount = pDoc->GetTableCount();
+ SCTAB i;
+
+ if ( pScMod->IsTableLocked() ) // darf jetzt nicht umgeschaltet werden ?
+ {
+ // den alten Zustand des TabControls wiederherstellen:
+
+ for (i=0; i<nCount; i++)
+ SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) );
+ SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
+
+ Sound::Beep();
+ return;
+ }
+
+ USHORT nCurId = GetCurPageId();
+ if (!nCurId) return; // kann vorkommen, wenn bei Excel-Import alles versteckt ist
+ USHORT nPage = nCurId - 1;
+
+ // OLE-inplace deaktivieren
+ if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNo()) )
+ pViewData->GetView()->DrawMarkListHasChanged();
+
+ // InputEnterHandler nur wenn nicht Referenzeingabe
+
+ BOOL bRefMode = pScMod->IsFormulaMode();
+ if (!bRefMode)
+ pScMod->InputEnterHandler();
+
+ for (i=0; i<nCount; i++)
+ rMark.SelectTable( i, IsPageSelected(static_cast<sal_uInt16>(i)+1) );
+
+/* Markierungen werden per Default nicht pro Tabelle gehalten
+ USHORT nSelCnt = GetSelectPageCount();
+ if (nSelCnt>1)
+ pDoc->ExtendMarksFromTable( nPage );
+*/
+
+ SfxDispatcher& rDisp = pViewData->GetDispatcher();
+ if (rDisp.IsLocked())
+ pViewData->GetView()->SetTabNo( static_cast<SCTAB>(nPage) );
+ else
+ {
+ // Tabelle fuer Basic ist 1-basiert
+ SfxUInt16Item aItem( SID_CURRENTTAB, nPage + 1 );
+ rDisp.Execute( SID_CURRENTTAB, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aItem, (void*) NULL );
+ }
+
+ SfxBindings& rBind = pViewData->GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+
+ rBind.Invalidate( FID_INS_TABLE );
+ rBind.Invalidate( FID_TAB_APPEND );
+ rBind.Invalidate( FID_TAB_MOVE );
+ rBind.Invalidate( FID_TAB_RENAME );
+ rBind.Invalidate( FID_DELETE_TABLE );
+ rBind.Invalidate( FID_TABLE_SHOW );
+ rBind.Invalidate( FID_TABLE_HIDE );
+ rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR );
+
+ // SetReference nur wenn der Konsolidieren-Dialog offen ist
+ // (fuer Referenzen ueber mehrere Tabellen)
+ // bei anderen gibt das nur unnoetiges Gezappel
+
+ if ( bRefMode && pViewData->GetRefType() == SC_REFTYPE_REF )
+ if ( pViewData->GetViewShell()->GetViewFrame()->HasChildWindow(SID_OPENDLG_CONSOLIDATE) )
+ {
+ ScRange aRange(
+ pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
+ pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
+ pScMod->SetReference( aRange, pDoc, &rMark );
+ pScMod->EndReference(); // wegen Auto-Hide
+ }
+}
+
+void ScTabControl::UpdateStatus()
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ BOOL bActive = pViewData->IsActive();
+
+ SCTAB nCount = pDoc->GetTableCount();
+ SCTAB i;
+ String aString;
+ SCTAB nMaxCnt = Max( nCount, static_cast<SCTAB>(GetMaxId()) );
+ Color aTabBgColor;
+
+ BOOL bModified = FALSE; // Tabellen-Namen
+ for (i=0; i<nMaxCnt && !bModified; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ pDoc->GetName(i,aString);
+ aTabBgColor = pDoc->GetTabBgColor(i);
+ }
+ else
+ {
+ aString.Erase();
+ }
+
+ if ( (GetPageText(static_cast<sal_uInt16>(i)+1) != aString) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) )
+ bModified = TRUE;
+ }
+
+ if (bModified)
+ {
+ Clear();
+ for (i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ if (pDoc->GetName(i,aString))
+ {
+ if ( pDoc->IsScenario(i) )
+ InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL );
+ else
+ InsertPage( static_cast<sal_uInt16>(i)+1, aString );
+ if ( !pDoc->IsDefaultTabBgColor(i) )
+ {
+ aTabBgColor = pDoc->GetTabBgColor(i);
+ SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor );
+ }
+ }
+ }
+ }
+ }
+ SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
+
+ if (bActive)
+ {
+ bModified = FALSE; // Selektion
+ for (i=0; i<nMaxCnt && !bModified; i++)
+ if ( rMark.GetTableSelect(i) != IsPageSelected(static_cast<sal_uInt16>(i)+1) )
+ bModified = TRUE;
+
+ // #i99576# the following loop is mis-optimized on unxsoli4 and the reason
+ // why this file is in NOOPTFILES.
+ if ( bModified )
+ for (i=0; i<nCount; i++)
+ SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) );
+ }
+ else
+ {
+ }
+}
+
+void ScTabControl::ActivateView(BOOL bActivate)
+{
+// ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+// ResetMark direkt in TabView
+// pDoc->ResetMark();
+
+ USHORT nCurId = GetCurPageId();
+ if (!nCurId) return; // kann vorkommen, wenn bei Excel-Import alles versteckt ist
+ USHORT nPage = nCurId - 1;
+// USHORT nCount = GetMaxId();
+
+ /*
+ USHORT i;
+ for (i=0; i<nCount; i++)
+ {
+ SelectPage( i+1, FALSE );
+ if (bActivate)
+ rMark.SelectTable( i, FALSE );
+ }
+ */
+ if (bActivate)
+ {
+ SelectPage( nPage+1, TRUE );
+ rMark.SelectTable( static_cast<SCTAB>(nPage), TRUE );
+ }
+ Invalidate();
+}
+
+void ScTabControl::SetSheetLayoutRTL( BOOL bSheetRTL )
+{
+ SetEffectiveRTL( bSheetRTL );
+ nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND;
+}
+
+
+void ScTabControl::Command( const CommandEvent& rCEvt )
+{
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ BOOL bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
+
+ // ViewFrame erstmal aktivieren (Bug 19493):
+ pViewSh->SetActive();
+
+ USHORT nCmd = rCEvt.GetCommand();
+ if ( nCmd == COMMAND_CONTEXTMENU )
+ {
+ if (!bDisable)
+ {
+ // #i18735# select the page that is under the mouse cursor
+ // if multiple tables are selected and the one under the cursor
+ // is not part of them then unselect them
+ USHORT nId = GetPageId( rCEvt.GetMousePosPixel() );
+ if (nId)
+ {
+ BOOL bAlreadySelected = IsPageSelected( nId );
+ //make the clicked page the current one
+ SetCurPageId( nId );
+ //change the selection when the current one is not already
+ //selected or part of a multi selection
+ if(!bAlreadySelected)
+ {
+ USHORT nCount = GetMaxId();
+
+ for (USHORT i=1; i<=nCount; i++)
+ SelectPage( i, i==nId );
+ Select();
+ }
+ }
+
+ // #i52073# OLE inplace editing has to be stopped before showing the sheet tab context menu
+ pViewSh->DeactivateOle();
+
+ // Popup-Menu:
+ // get Dispatcher from ViewData (ViewFrame) instead of Shell (Frame), so it can't be null
+ pViewData->GetDispatcher().ExecutePopup( ScResId(RID_POPUP_TAB) );
+ }
+ }
+}
+
+void ScTabControl::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
+{
+ ScModule* pScMod = SC_MOD();
+ BOOL bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
+
+ if (!bDisable)
+ {
+ Region aRegion( Rectangle(0,0,0,0) );
+ CommandEvent aCEvt( rPosPixel, COMMAND_STARTDRAG, TRUE ); // needed for StartDrag
+ if (TabBar::StartDrag( aCEvt, aRegion ))
+ DoDrag( aRegion );
+ }
+}
+
+void ScTabControl::DoDrag( const Region& /* rRegion */ )
+{
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScMarkData aTabMark = pViewData->GetMarkData();
+ aTabMark.ResetMark(); // doesn't change marked table information
+ aTabMark.SetMarkArea( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
+
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ ScClipParam aClipParam(ScRange(0, 0, 0, MAXCOL, MAXROW, 0), false);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &aTabMark, false);
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ pTransferObj->SetDragSourceFlags( SC_DROP_TABLE );
+
+ pTransferObj->SetDragSource( pDocSh, aTabMark );
+
+ Window* pWindow = pViewData->GetActiveWin();
+ SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D
+ pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+}
+
+USHORT lcl_DocShellNr( ScDocument* pDoc )
+{
+ USHORT nShellCnt = 0;
+ SfxObjectShell* pShell = SfxObjectShell::GetFirst();
+ while ( pShell )
+ {
+ if ( pShell->Type() == TYPE(ScDocShell) )
+ {
+ if ( ((ScDocShell*)pShell)->GetDocument() == pDoc )
+ return nShellCnt;
+
+ ++nShellCnt;
+ }
+ pShell = SfxObjectShell::GetNext( *pShell );
+ }
+
+ DBG_ERROR("Dokument nicht gefunden");
+ return 0;
+}
+
+sal_Int8 ScTabControl::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ EndSwitchPage();
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rData.pCellTransfer && ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) &&
+ rData.pCellTransfer->GetSourceDocument() == pDoc )
+ {
+ // moving of tables within the document
+ SCTAB nPos = GetPrivatDropPos( rEvt.maPosPixel );
+ HideDropPos();
+
+ if ( nPos == rData.pCellTransfer->GetVisibleTab() && rEvt.mnAction == DND_ACTION_MOVE )
+ {
+ // #i83005# do nothing - don't move to the same position
+ // (too easily triggered unintentionally, and might take a long time in large documents)
+ }
+ else
+ {
+ if ( !pDoc->GetChangeTrack() && pDoc->IsDocEditable() )
+ {
+ //! use table selection from the tab control where dragging was started?
+ pViewData->GetView()->MoveTable( lcl_DocShellNr(pDoc), nPos, rEvt.mnAction != DND_ACTION_MOVE );
+
+ rData.pCellTransfer->SetDragWasInternal(); // don't delete
+ return TRUE;
+ }
+ else
+ Sound::Beep();
+ }
+ }
+
+ return 0;
+}
+
+sal_Int8 ScTabControl::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ if ( rEvt.mbLeaving )
+ {
+ EndSwitchPage();
+ HideDropPos();
+ return rEvt.mnAction;
+ }
+
+ const ScDocument* pDoc = pViewData->GetDocument();
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rData.pCellTransfer && ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) &&
+ rData.pCellTransfer->GetSourceDocument() == pDoc )
+ {
+ // moving of tables within the document
+ if ( !pDoc->GetChangeTrack() && pDoc->IsDocEditable() )
+ {
+ ShowDropPos( rEvt.maPosPixel );
+ return rEvt.mnAction;
+ }
+ }
+ else // switch sheets for all formats
+ {
+ SwitchPage( rEvt.maPosPixel ); // switch sheet after timeout
+ return 0; // nothing can be dropped here
+ }
+
+ return 0;
+}
+
+long ScTabControl::StartRenaming()
+{
+ if ( pViewData->GetDocument()->IsDocEditable() )
+ return TABBAR_RENAMING_YES;
+ else
+ return TABBAR_RENAMING_NO;
+}
+
+long ScTabControl::AllowRenaming()
+{
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ DBG_ASSERT( pViewSh, "pViewData->GetViewShell()" );
+
+ long nRet = TABBAR_RENAMING_CANCEL;
+ USHORT nId = GetEditPageId();
+ if ( nId )
+ {
+ SCTAB nTab = nId - 1;
+ String aNewName = GetEditText();
+ BOOL bDone = pViewSh->RenameTable( aNewName, nTab );
+ if ( bDone )
+ nRet = TABBAR_RENAMING_YES;
+ else if ( bErrorShown )
+ {
+ // if the error message from this TabControl is currently visible,
+ // don't end edit mode now, to avoid problems when returning to
+ // the other call (showing the error) - this should not happen
+ DBG_ERROR("ScTabControl::AllowRenaming: nested calls");
+ nRet = TABBAR_RENAMING_NO;
+ }
+ else if ( Application::IsInModalMode() )
+ {
+ // #73472# don't show error message above any modal dialog
+ // instead cancel renaming without error message
+ nRet = TABBAR_RENAMING_CANCEL;
+ }
+ else
+ {
+ bErrorShown = TRUE;
+ pViewSh->ErrorMessage( STR_INVALIDTABNAME );
+ bErrorShown = FALSE;
+ nRet = TABBAR_RENAMING_NO;
+ }
+ }
+ return nRet;
+}
+
+void ScTabControl::EndRenaming()
+{
+ if ( HasFocus() )
+ pViewData->GetView()->ActiveGrabFocus();
+}
+
+void ScTabControl::Mirror()
+{
+ TabBar::Mirror();
+ if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND )
+ {
+ Rectangle aRect( GetPageRect( GetCurPageId() ) );
+ if( !aRect.IsEmpty() )
+ SetPointerPosPixel( aRect.Center() );
+ nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select()
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/tabpopsh.cxx b/sc/source/ui/view/tabpopsh.cxx
new file mode 100644
index 000000000000..f5033d5d0df5
--- /dev/null
+++ b/sc/source/ui/view/tabpopsh.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "tabpopsh.hxx"
+#include "sc.hrc"
+
+#undef ShellClass
+#define ShellClass ScTabPopShell
+SFX_SLOTMAP(ScTabPopShell)
+{
+ SFX_SLOT( 0,0, DummyExec, DummyState, 0, SfxVoidItem )
+};
+
+
+TYPEINIT1(ScTabPopShell,SfxShell);
+
+//SFX_IMPL_IDL_INTERFACE(ScTabPopShell, SfxShell, 0)
+SFX_IMPL_INTERFACE(ScTabPopShell, SfxShell, ResId( 0, NULL))
+{
+ SFX_POPUPMENU_REGISTRATION( RID_POPUP_TAB );
+}
+
+
+
+
+ScTabPopShell::ScTabPopShell(SfxItemPool& rItemPool)
+{
+ SetPool( &rItemPool );
+}
+
+
+ScTabPopShell::~ScTabPopShell()
+{
+}
+
+
+void ScTabPopShell::DummyExec( SfxRequest& rReq )
+{
+}
+
+
+void ScTabPopShell::DummyState( SfxItemSet& rSet )
+{
+}
diff --git a/sc/source/ui/view/tabsplit.cxx b/sc/source/ui/view/tabsplit.cxx
new file mode 100644
index 000000000000..0f72e0e73d02
--- /dev/null
+++ b/sc/source/ui/view/tabsplit.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "tabsplit.hxx"
+#include "viewdata.hxx"
+#include "dbfunc.hxx"
+
+//==================================================================
+
+ScTabSplitter::ScTabSplitter( Window* pParent, WinBits nWinStyle, ScViewData* pData ) :
+ Splitter( pParent, nWinStyle ),
+ pViewData(pData)
+{
+ SetFixed(FALSE);
+ EnableRTL( FALSE );
+}
+
+
+ScTabSplitter::~ScTabSplitter()
+{
+}
+
+void __EXPORT ScTabSplitter::MouseMove( const MouseEvent& rMEvt )
+{
+ if (bFixed)
+ Window::MouseMove( rMEvt );
+ else
+ Splitter::MouseMove( rMEvt );
+}
+
+void __EXPORT ScTabSplitter::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if (bFixed)
+ Window::MouseButtonUp( rMEvt );
+ else
+ Splitter::MouseButtonUp( rMEvt );
+}
+
+void __EXPORT ScTabSplitter::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (bFixed)
+ Window::MouseButtonDown( rMEvt );
+ else
+ Splitter::MouseButtonDown( rMEvt );
+}
+
+void __EXPORT ScTabSplitter::Splitting( Point& rSplitPos )
+{
+ Window* pParent = GetParent();
+ Point aScreenPos = pParent->OutputToNormalizedScreenPixel( rSplitPos );
+ pViewData->GetView()->SnapSplitPos( aScreenPos );
+ Point aNew = pParent->NormalizedScreenToOutputPixel( aScreenPos );
+ if ( IsHorizontal() )
+ rSplitPos.X() = aNew.X();
+ else
+ rSplitPos.Y() = aNew.Y();
+}
+
+
+void ScTabSplitter::SetFixed(BOOL bSet)
+{
+ bFixed = bSet;
+ if (bSet)
+ SetPointer(POINTER_ARROW);
+ else if (IsHorizontal())
+ SetPointer(POINTER_HSPLIT);
+ else
+ SetPointer(POINTER_VSPLIT);
+}
+
+
+
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
new file mode 100644
index 000000000000..0bc4617a9af4
--- /dev/null
+++ b/sc/source/ui/view/tabview.cxx
@@ -0,0 +1,2535 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+//------------------------------------------------------------------
+
+#if 0
+#define _MACRODLG_HXX
+#define _BIGINT_HXX
+#define _SVCONTNR_HXX
+#define BASIC_NODIALOGS
+#define _SFXMNUITEM_HXX
+#define _SVDXOUT_HXX
+#define _SVDATTR_HXX
+#define _SFXMNUITEM_HXX
+#define _DLGCFG_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXBASIC_HXX
+#define _MODALDLG_HXX
+#define _SFX_TEMPLDLG_HXX
+#define _SFXSTBMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _BASE_DLGS_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXTBXCTRL_HXX
+#define _PASSWD_HXX
+//#define _SFXFILEDLG_HXX
+//#define _SFXREQUEST_HXX
+#define _SFXOBJFACE_HXX
+
+#define _SDR_NOTRANSFORM
+#define _SVDXOUT_HXX
+#endif
+#include <vcl/svapp.hxx>
+
+///////////////////////////////////////////////////////////////////////////
+// NODRAW.HXX
+// Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden
+// Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg
+///////////////////////////////////////////////////////////////////////////
+
+#if 0
+#define _SDR_NOTRANSFORM // Transformationen, selten verwendet
+#define _SDR_NOTOUCH // Hit-Tests, selten verwendet
+
+#define _SDR_NOUNDO // Undo-Objekte
+#define _SDR_NOPAGEOBJ // SdrPageObj
+#define _SDR_NOVIRTOBJ // SdrVirtObj
+#define _SDR_NOGROUPOBJ // SdrGroupObj
+#define _SDR_NOTEXTOBJ // SdrTextObj
+#define _SDR_NOPATHOBJ // SdrPathObj
+#define _SDR_NOEDGEOBJ // SdrEdgeObj
+#define _SDR_NORECTOBJ // SdrRectObj
+#define _SDR_NOCAPTIONOBJ // SdrCaptionObj
+#define _SDR_NOCIRCLEOBJ // SdrCircleObj
+#define _SDR_NOGRAFOBJ // SdrGrafObj
+#define _SDR_NOOLE2OBJ // SdrOle2Obj
+#endif
+
+// Dieses define entfernt die VCControls aus SI.HXX
+
+#define _SI_HXX // VCControls
+
+////////////////////// Umsetzen der Standard-Defines //////////////////////
+
+//#define _SVDDRAG_HXX // SdrDragStat
+#define _SVDPAGE_HXX // SdrPage
+
+#ifdef _SDR_NOSURROGATEOBJ
+ #undef _SDR_NOSURROGATEOBJ
+ #define _SVDSURO_HXX
+#endif
+
+#ifdef _SDR_NOPAGEOBJ
+ #undef _SDR_NOPAGEOBJ
+ #define _SVDOPAGE_HXX
+#endif
+
+#ifdef _SDR_NOVIRTOBJ
+ #undef _SDR_NOVIRTOBJ
+ #define _SVDOVIRT_HXX
+#endif
+
+#ifdef _SDR_NOGROUPOBJ
+ #undef _SDR_NOGROUPOBJ
+ #define _SVDOGRP_HXX
+#endif
+
+#ifdef _SDR_NOTEXTOBJ
+ #undef _SDR_NOTEXTOBJ
+ #define _SVDOTEXT_HXX
+#endif
+
+#ifdef _SDR_NOPATHOBJ
+ #undef _SDR_NOPATHOBJ
+ #define _SVDOPATH_HXX
+#endif
+
+#ifdef _SDR_NOEDGEOBJ
+ #undef _SDR_NOEDGEOBJ
+ #define _SVDOEDGE_HXX
+#endif
+
+#ifdef _SDR_NORECTOBJ
+ #undef _SDR_NORECTOBJ
+ #define _SVDORECT_HXX
+#else
+ #undef _SDVOTEXT_OBJ
+#endif
+
+#ifdef _SDR_NOCAPTIONOBJ
+ #undef _SDR_NOCAPTIONOBJ
+ #define _SVDCAPT_HXX
+#endif
+
+#ifdef _SDR_NOCIRCLEOBJ
+ #undef _SDR_NOCIRCLEOBJ
+ #define _SVDOCIRC_HXX
+#endif
+
+#ifdef _SDR_NOGRAFOBJ
+ #undef _SDR_NOGRAFOBJ
+ #define _SVDOGRAF_HXX
+#else
+ #undef _SVDOTEXT_HXX
+ #undef _SVDORECT_HXX
+#endif
+
+#ifdef _SDR_NOOLE2OBJ
+ #undef _SDR_NOOLE2OBJ
+ #define _SVDOOLE2_HXX
+#else
+ #undef _SVDOTEXT_HXX
+ #undef _SVDORECT_HXX
+#endif
+
+//#ifdef _SDR_NOVIEWS
+// #define _SVDDRAG_HXX
+//#endif
+
+////////////////////// Ende der SVDRAW-Modifikationen /////////////////////
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/help.hxx>
+#include <rtl/logfile.hxx>
+
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "olinetab.hxx"
+#include "tabsplit.hxx"
+#include "colrowba.hxx"
+#include "tabcont.hxx"
+#include "scmod.hxx"
+#include "sc.hrc"
+#include "viewutil.hxx"
+#include "globstr.hrc"
+#include "drawview.hxx"
+#include "docsh.hxx"
+#include "viewuno.hxx"
+#include "AccessibilityHints.hxx"
+#include "appoptio.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+
+#include <string>
+#include <algorithm>
+
+#define SPLIT_MARGIN 30
+#define SC_ICONSIZE 36
+
+#define SC_SCROLLBAR_MIN 30
+#define SC_TABBAR_MIN 6
+
+// fuer Rad-Maus
+#define SC_DELTA_ZOOM 10
+
+using namespace ::com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//==================================================================
+
+// Corner-Button
+
+ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, BOOL bAdditional ) :
+ Window( pParent, WinBits( 0 ) ),
+ pViewData( pData ),
+ bAdd( bAdditional )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ EnableRTL( FALSE );
+}
+
+__EXPORT ScCornerButton::~ScCornerButton()
+{
+}
+
+void __EXPORT ScCornerButton::Paint( const Rectangle& rRect )
+{
+ Size aSize = GetOutputSizePixel();
+ long nPosX = aSize.Width()-1;
+ long nPosY = aSize.Height()-1;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Window::Paint(rRect);
+
+ BOOL bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+ long nDarkX = bLayoutRTL ? 0 : nPosX;
+
+ if ( !bAdd && !rStyleSettings.GetHighContrastMode() )
+ {
+ // match the shaded look of column/row headers
+
+ Color aFace( rStyleSettings.GetFaceColor() );
+ Color aWhite( COL_WHITE );
+ Color aCenter( aFace );
+ aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
+ Color aOuter( aFace );
+ aOuter.Merge( aWhite, 0xa0 ); // lighten up more
+
+ long nCenterX = (aSize.Width() / 2) - 1;
+ long nCenterY = (aSize.Height() / 2) - 1;
+
+ SetLineColor();
+ SetFillColor(aCenter);
+ DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) );
+ DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) );
+ SetFillColor(aOuter);
+ DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) );
+ if ( bLayoutRTL )
+ DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) );
+ else
+ DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) );
+ }
+
+ // both buttons have the same look now - only dark right/bottom lines
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point(0,nPosY), Point(nPosX,nPosY) );
+ DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) );
+}
+
+void ScCornerButton::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ Invalidate();
+}
+
+
+void __EXPORT ScCornerButton::Resize()
+{
+ Invalidate();
+}
+
+void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ ScModule* pScMod = SC_MOD();
+ BOOL bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
+ if (!bDisable)
+ {
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ pViewSh->SetActive(); // Appear und SetViewFrame
+ pViewSh->ActiveGrabFocus();
+
+ BOOL bControl = rMEvt.IsMod1();
+ pViewSh->SelectAll( bControl );
+ }
+}
+
+//==================================================================
+
+BOOL lcl_HasColOutline( const ScViewData& rViewData )
+{
+ const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
+ if (pTable)
+ {
+ const ScOutlineArray* pArray = pTable->GetColArray();
+ if ( pArray->GetDepth() > 0 )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL lcl_HasRowOutline( const ScViewData& rViewData )
+{
+ const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
+ if (pTable)
+ {
+ const ScOutlineArray* pArray = pTable->GetRowArray();
+ if ( pArray->GetDepth() > 0 )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//==================================================================
+
+// Init und Konstruktoren
+// ScTabView::Init() in tabview5.cxx wegen out of keys
+
+
+#define TABVIEW_INIT \
+ pSelEngine( NULL ), \
+ aFunctionSet( &aViewData ), \
+ pHdrSelEng( NULL ), \
+ aHdrFunc( &aViewData ), \
+ pDrawView( NULL ), \
+ bDrawSelMode( FALSE ), \
+ aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
+ aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
+ aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
+ aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
+ aCornerButton( pFrameWin, &aViewData, FALSE ), \
+ aTopButton( pFrameWin, &aViewData, TRUE ), \
+ aScrollBarBox( pFrameWin, WB_SIZEABLE ), \
+ pInputHintWindow( NULL ), \
+ pPageBreakData( NULL ), \
+ pHighlightRanges( NULL ), \
+ pBrushDocument( NULL ), \
+ pDrawBrushSet( NULL ), \
+ bLockPaintBrush( FALSE ), \
+ pTimerWindow( NULL ), \
+ nTipVisible( 0 ), \
+ bDragging( FALSE ), \
+ bIsBlockMode( FALSE ), \
+ bBlockNeg( FALSE ), \
+ bBlockCols( FALSE ), \
+ bBlockRows( FALSE ), \
+ mfPendingTabBarWidth( -1.0 ), \
+ bMinimized( FALSE ), \
+ bInUpdateHeader( FALSE ), \
+ bInActivatePart( FALSE ), \
+ bInZoomUpdate( FALSE ), \
+ bMoveIsShift( FALSE ), \
+ bNewStartIfMarking( FALSE )
+
+
+ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
+ pFrameWin( pParent ),
+ aViewData( &rDocSh, pViewShell ),
+ TABVIEW_INIT
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
+
+ Init();
+}
+
+//UNUSED2009-05 ScTabView::ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell ) :
+//UNUSED2009-05 pFrameWin( pParent ),
+//UNUSED2009-05 aViewData( rScTabView.aViewData ),
+//UNUSED2009-05 TABVIEW_INIT
+//UNUSED2009-05 {
+//UNUSED2009-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
+//UNUSED2009-05
+//UNUSED2009-05 aViewData.SetViewShell( pViewShell );
+//UNUSED2009-05 Init();
+//UNUSED2009-05
+//UNUSED2009-05 UpdateShow();
+//UNUSED2009-05 if ( aViewData.GetActivePart() != SC_SPLIT_BOTTOMLEFT )
+//UNUSED2009-05 pGridWin[SC_SPLIT_BOTTOMLEFT]->Show();
+//UNUSED2009-05
+//UNUSED2009-05 InvalidateSplit();
+//UNUSED2009-05 }
+
+void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
+{
+ rScrollBar.SetRange( Range( 0, nMaxVal ) );
+ rScrollBar.SetLineSize( 1 );
+ rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt
+ rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt
+
+ rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
+ rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
+}
+
+// Scroll-Timer
+
+void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
+{
+ pTimerWindow = pWin;
+ aTimerMEvt = rMEvt;
+ aScrollTimer.Start();
+}
+
+void ScTabView::ResetTimer()
+{
+ aScrollTimer.Stop();
+ pTimerWindow = NULL;
+}
+
+IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG )
+{
+// aScrollTimer.Stop();
+ if (pTimerWindow)
+ pTimerWindow->MouseMove( aTimerMEvt );
+
+ return 0;
+}
+
+// --- Resize ---------------------------------------------------------------------
+
+void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize,
+ long nTotalWidth, BOOL bLayoutRTL )
+{
+ Point aNewPos = rPos;
+ if ( bLayoutRTL )
+ {
+ aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
+ if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
+ {
+ // Document windows are manually painted right-to-left, so they need to
+ // be repainted if the size changes.
+ rWindow.Invalidate();
+ }
+ }
+ rWindow.SetPosSizePixel( aNewPos, rSize );
+}
+
+void ScTabView::DoResize( const Point& rOffset, const Size& rSize, BOOL bInner )
+{
+ HideListBox();
+
+ BOOL bHasHint = ( pInputHintWindow != NULL );
+ if (bHasHint)
+ RemoveHintWindow();
+
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ long nTotalWidth = rSize.Width();
+ if ( bLayoutRTL )
+ nTotalWidth += 2*rOffset.X();
+
+ BOOL bVScroll = aViewData.IsVScrollMode();
+ BOOL bHScroll = aViewData.IsHScrollMode();
+ BOOL bTabControl = aViewData.IsTabMode();
+ BOOL bHeaders = aViewData.IsHeaderMode();
+ BOOL bOutlMode = aViewData.IsOutlineMode();
+ BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+
+ // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
+ SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
+ if ( eMode == SCROLLING_NO )
+ bHScroll = bVScroll = FALSE;
+ else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
+ bHScroll = bVScroll = TRUE;
+
+ if ( aViewData.GetDocShell()->IsPreview() )
+ bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = FALSE;
+
+ long nBarX = 0;
+ long nBarY = 0;
+ long nOutlineX = 0;
+ long nOutlineY = 0;
+ long nOutPosX;
+ long nOutPosY;
+
+ long nPosX = rOffset.X();
+ long nPosY = rOffset.Y();
+ long nSizeX = rSize.Width();
+ long nSizeY = rSize.Height();
+ long nSize1;
+
+ bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
+ if ( bMinimized )
+ return;
+
+ long nSplitSizeX = SPLIT_HANDLE_SIZE;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ nSplitSizeX = 1;
+ long nSplitSizeY = SPLIT_HANDLE_SIZE;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ nSplitSizeY = 1;
+
+ const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
+
+ aBorderPos = rOffset;
+ aFrameSize = rSize;
+
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
+ {
+ aViewData.SetHSplitMode( SC_SPLIT_NONE );
+ if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ InvalidateSplit();
+// UpdateShow();
+ }
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
+ {
+ aViewData.SetVSplitMode( SC_SPLIT_NONE );
+ if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ InvalidateSplit();
+// UpdateShow();
+ }
+
+ UpdateShow();
+
+ if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal
+ {
+ long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize();
+ if (bVScroll)
+ {
+// nBarX = aVScrollBottom.GetSizePixel().Width();
+ nBarX = nScrollBarSize;
+ nSizeX -= nBarX - nOverlap;
+ }
+ if (bHScroll)
+ {
+// nBarY = aHScrollLeft.GetSizePixel().Height();
+ nBarY = nScrollBarSize;
+ nSizeY -= nBarY - nOverlap;
+ }
+
+ // window at the bottom right
+ lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
+ nTotalWidth, bLayoutRTL );
+
+ if (bHScroll) // Scrollbars horizontal
+ {
+ long nSizeLt = 0; // left scroll bar
+ long nSizeRt = 0; // right scroll bar
+ long nSizeSp = 0; // splitter
+
+ switch (aViewData.GetHSplitMode())
+ {
+ case SC_SPLIT_NONE:
+ nSizeSp = nSplitSizeX;
+ nSizeLt = nSizeX - nSizeSp + nOverlap; // Ecke ueberdecken
+ break;
+ case SC_SPLIT_NORMAL:
+ nSizeSp = nSplitSizeX;
+ nSizeLt = aViewData.GetHSplitPos();
+ break;
+ case SC_SPLIT_FIX:
+ nSizeSp = 0;
+ nSizeLt = 0;
+ break;
+ }
+ nSizeRt = nSizeX - nSizeLt - nSizeSp;
+
+ long nTabSize = 0;
+ if (bTabControl)
+ {
+ // pending relative tab bar width from extended document options
+ if( mfPendingTabBarWidth >= 0.0 )
+ {
+ SetRelTabBarWidth( mfPendingTabBarWidth );
+ mfPendingTabBarWidth = -1.0;
+ }
+
+ nTabSize = pTabControl->GetSizePixel().Width()-nOverlap;
+
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // bei linkem Scrollbar
+ {
+ if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
+ if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
+ nSizeLt -= nTabSize;
+ }
+ else // bei rechtem Scrollbar
+ {
+ if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
+ if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
+ nSizeRt -= nTabSize;
+ }
+ }
+
+ lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY),
+ Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+ pTabControl->SetSheetLayoutRTL( bLayoutRTL );
+
+ lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY),
+ Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ),
+ Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap,
+ nPosY+nSizeY),
+ Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+
+ // SetDragRectPixel is done below
+ }
+
+ if (bVScroll) // Scrollbars vertikal
+ {
+ long nSizeUp = 0; // upper scroll bar
+ long nSizeSp = 0; // splitter
+ long nSizeDn; // unterer Scrollbar
+
+ switch (aViewData.GetVSplitMode())
+ {
+ case SC_SPLIT_NONE:
+ nSizeUp = 0;
+ nSizeSp = nSplitSizeY;
+ break;
+ case SC_SPLIT_NORMAL:
+ nSizeUp = aViewData.GetVSplitPos();
+ nSizeSp = nSplitSizeY;
+ break;
+ case SC_SPLIT_FIX:
+ nSizeUp = 0;
+ nSizeSp = 0;
+ break;
+ }
+ nSizeDn = nSizeY - nSizeUp - nSizeSp;
+
+ lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap),
+ Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ),
+ Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX,
+ nPosY+nSizeUp+nSizeSp-nOverlap),
+ Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL );
+
+ // SetDragRectPixel is done below
+ }
+ }
+
+ // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist
+ if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ pHSplitter->SetDragRectPixel(
+ Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
+ if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ pVSplitter->SetDragRectPixel(
+ Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
+
+ if (bTabControl && ! bHScroll )
+ {
+ nBarY = aHScrollLeft.GetSizePixel().Height();
+ nBarX = aVScrollBottom.GetSizePixel().Width();
+
+ nSize1 = nSizeX + nOverlap;
+
+ long nTabSize = nSize1;
+ if (nTabSize < 0) nTabSize = 0;
+
+ lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY),
+ Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+ nSizeY -= nBarY - nOverlap;
+ lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
+ nTotalWidth, bLayoutRTL );
+
+ if( bVScroll )
+ {
+ Size aVScrSize = aVScrollBottom.GetSizePixel();
+ aVScrSize.Height() -= nBarY;
+ aVScrollBottom.SetSizePixel( aVScrSize );
+ }
+ }
+
+ nOutPosX = nPosX;
+ nOutPosY = nPosY;
+
+ // Outline-Controls
+ if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
+ {
+ nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
+ nSizeX -= nOutlineX;
+ nPosX += nOutlineX;
+ }
+ if (bHOutline && pColOutline[SC_SPLIT_LEFT])
+ {
+ nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
+ nSizeY -= nOutlineY;
+ nPosY += nOutlineY;
+ }
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ nSizeX -= nBarX;
+ nSizeY -= nBarY;
+ nPosX += nBarX;
+ nPosY += nBarY;
+ }
+ else
+ nBarX = nBarY = 0;
+
+ //
+ // Splitter auswerten
+ //
+
+ long nLeftSize = nSizeX;
+ long nRightSize = 0;
+ long nTopSize = 0;
+ long nBottomSize = nSizeY;
+ long nSplitPosX = nPosX;
+ long nSplitPosY = nPosY;
+
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ {
+ long nSplitHeight = rSize.Height();
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ {
+ // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen
+ if ( bHScroll )
+ nSplitHeight -= aHScrollLeft.GetSizePixel().Height();
+ else if ( bTabControl && pTabControl )
+ nSplitHeight -= pTabControl->GetSizePixel().Height();
+ }
+ nSplitPosX = aViewData.GetHSplitPos();
+ lcl_SetPosSize( *pHSplitter,
+ Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL );
+ nLeftSize = nSplitPosX - nPosX;
+ nSplitPosX += nSplitSizeX;
+ nRightSize = nSizeX - nLeftSize - nSplitSizeX;
+ }
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ {
+ long nSplitWidth = rSize.Width();
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
+ nSplitWidth -= aVScrollBottom.GetSizePixel().Width();
+ nSplitPosY = aViewData.GetVSplitPos();
+ lcl_SetPosSize( *pVSplitter,
+ Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
+ nTopSize = nSplitPosY - nPosY;
+ nSplitPosY += nSplitSizeY;
+ nBottomSize = nSizeY - nTopSize - nSplitSizeY;
+ }
+
+ // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow
+
+ if (bHOutline) // Outline-Controls
+ {
+ if (pColOutline[SC_SPLIT_LEFT])
+ {
+ pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
+ lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
+ Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
+ }
+ if (pColOutline[SC_SPLIT_RIGHT])
+ {
+ pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
+ lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
+ Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
+ }
+ }
+ if (bVOutline)
+ {
+ if (nTopSize)
+ {
+ if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
+ {
+ pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
+ lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
+ Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
+ pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
+ lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
+ Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
+ }
+ }
+ else if (pRowOutline[SC_SPLIT_BOTTOM])
+ {
+ pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
+ lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
+ Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
+ }
+ }
+ if (bHOutline && bVOutline)
+ {
+ lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
+ aTopButton.Show();
+ }
+ else
+ aTopButton.Hide();
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
+ Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
+ if (pColBar[SC_SPLIT_RIGHT])
+ lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
+ Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
+
+ if (pRowBar[SC_SPLIT_TOP])
+ lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
+ Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
+ Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
+
+ lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
+ aCornerButton.Show();
+ pColBar[SC_SPLIT_LEFT]->Show();
+ pRowBar[SC_SPLIT_BOTTOM]->Show();
+ }
+ else
+ {
+ aCornerButton.Hide();
+ pColBar[SC_SPLIT_LEFT]->Hide(); // immer da
+ pRowBar[SC_SPLIT_BOTTOM]->Hide();
+ }
+
+
+ // Grid-Windows
+
+ if (bInner)
+ {
+ long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
+ }
+ else
+ {
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
+ Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
+ Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
+ Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
+ Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
+ }
+
+ //
+ // Scrollbars updaten
+ //
+
+ if (!bInUpdateHeader)
+ {
+ UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen
+ UpdateHeaderWidth();
+
+ InterpretVisible(); // #69343# have everything calculated before painting
+ }
+
+ if (bHasHint)
+ TestHintWindow(); // neu positionieren
+
+ UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED));
+}
+
+void ScTabView::UpdateVarZoom()
+{
+ // update variable zoom types
+
+ SvxZoomType eZoomType = GetZoomType();
+ if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate )
+ {
+ bInZoomUpdate = TRUE;
+ const Fraction& rOldX = GetViewData()->GetZoomX();
+ const Fraction& rOldY = GetViewData()->GetZoomY();
+ long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
+ USHORT nNewZoom = CalcZoom( eZoomType, (USHORT)nOldPercent );
+ Fraction aNew( nNewZoom, 100 );
+
+ if ( aNew != rOldX || aNew != rOldY )
+ {
+ SetZoom( aNew, aNew, FALSE ); // always separately per sheet
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
+ aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
+ }
+ bInZoomUpdate = FALSE;
+ }
+}
+
+void ScTabView::UpdateFixPos()
+{
+ BOOL bResize = FALSE;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixX())
+ bResize = TRUE;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixY())
+ bResize = TRUE;
+ if (bResize)
+ RepeatResize(FALSE);
+}
+
+void ScTabView::RepeatResize( BOOL bUpdateFix )
+{
+ if ( bUpdateFix )
+ {
+ ScSplitMode eHSplit = aViewData.GetHSplitMode();
+ ScSplitMode eVSplit = aViewData.GetVSplitMode();
+
+ // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
+ // outline windows to be available. So UpdateShow has to be called before
+ // (also called from DoResize).
+ if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
+ UpdateShow();
+
+ if ( eHSplit == SC_SPLIT_FIX )
+ aViewData.UpdateFixX();
+ if ( eVSplit == SC_SPLIT_FIX )
+ aViewData.UpdateFixY();
+ }
+
+ DoResize( aBorderPos, aFrameSize );
+
+ //! Border muss neu gesetzt werden ???
+}
+
+void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
+{
+ BOOL bScrollBars = aViewData.IsVScrollMode();
+ BOOL bHeaders = aViewData.IsHeaderMode();
+ BOOL bOutlMode = aViewData.IsOutlineMode();
+ BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+
+ rBorder = SvBorder();
+
+ if (bScrollBars) // Scrollbars horizontal oder vertikal
+ {
+ rBorder.Right() += aVScrollBottom.GetSizePixel().Width();
+ rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height();
+ }
+
+ // Outline-Controls
+ if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
+ rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
+ if (bHOutline && pColOutline[SC_SPLIT_LEFT])
+ rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ }
+
+ if ( bLayoutRTL )
+ ::std::swap( rBorder.Left(), rBorder.Right() );
+}
+
+IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG )
+{
+ BOOL bHScrollMode = aViewData.IsHScrollMode();
+
+ // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
+ SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
+ if ( eMode == SCROLLING_NO )
+ bHScrollMode = FALSE;
+ else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
+ bHScrollMode = TRUE;
+
+ if( bHScrollMode )
+ {
+ const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
+ long nSize = pTabControl->GetSplitSize();
+
+ if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
+ {
+ long nMax = pHSplitter->GetPosPixel().X();
+ if( pTabControl->IsEffectiveRTL() )
+ nMax = pFrameWin->GetSizePixel().Width() - nMax;
+ --nMax;
+ if (nSize>nMax) nSize = nMax;
+ }
+
+ if ( nSize != pTabControl->GetSizePixel().Width() )
+ {
+ pTabControl->SetSizePixel( Size( nSize+nOverlap,
+ pTabControl->GetSizePixel().Height() ) );
+ RepeatResize();
+ }
+ }
+
+ return 0;
+}
+
+void ScTabView::SetTabBarWidth( long nNewWidth )
+{
+ Size aSize = pTabControl->GetSizePixel();
+
+ if ( aSize.Width() != nNewWidth )
+ {
+ aSize.Width() = nNewWidth;
+ pTabControl->SetSizePixel( aSize );
+ }
+}
+
+void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
+{
+ if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
+ if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
+ SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
+}
+
+void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
+{
+ mfPendingTabBarWidth = fRelTabBarWidth;
+ SetRelTabBarWidth( fRelTabBarWidth );
+}
+
+long ScTabView::GetTabBarWidth() const
+{
+ return pTabControl->GetSizePixel().Width();
+}
+
+double ScTabView::GetRelTabBarWidth() const
+{
+ if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
+ return static_cast< double >( GetTabBarWidth() ) / nFrameWidth;
+ return 0.0;
+}
+
+double ScTabView::GetPendingRelTabBarWidth() const
+{
+ return mfPendingTabBarWidth;
+}
+
+Window* ScTabView::GetActiveWin()
+{
+ ScSplitPos ePos = aViewData.GetActivePart();
+ DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster");
+ return pGridWin[ePos];
+}
+
+Window* ScTabView::GetWindowByPos( ScSplitPos ePos )
+{
+ return pGridWin[ePos];
+}
+
+void ScTabView::SetActivePointer( const Pointer& rPointer )
+{
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetPointer( rPointer );
+
+/* ScSplitPos ePos = aViewData.GetActivePart();
+ if (pGridWin[ePos])
+ pGridWin[ePos]->SetPointer( rPointer );
+*/
+}
+
+//UNUSED2008-05 void ScTabView::SetActivePointer( const ResId& )
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ERRORFILE( "keine Pointer mit ResId!" );
+//UNUSED2008-05 }
+
+void ScTabView::ActiveGrabFocus()
+{
+ ScSplitPos ePos = aViewData.GetActivePart();
+ if (pGridWin[ePos])
+ pGridWin[ePos]->GrabFocus();
+}
+
+//UNUSED2008-05 void ScTabView::ActiveCaptureMouse()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
+//UNUSED2008-05 if (pGridWin[ePos])
+//UNUSED2008-05 pGridWin[ePos]->CaptureMouse();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::ActiveReleaseMouse()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
+//UNUSED2008-05 if (pGridWin[ePos])
+//UNUSED2008-05 pGridWin[ePos]->ReleaseMouse();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 Point ScTabView::ActivePixelToLogic( const Point& rDevicePoint )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
+//UNUSED2008-05 if (pGridWin[ePos])
+//UNUSED2008-05 return pGridWin[ePos]->PixelToLogic(rDevicePoint);
+//UNUSED2008-05 else
+//UNUSED2008-05 return Point();
+//UNUSED2008-05 }
+
+ScSplitPos ScTabView::FindWindow( Window* pWindow ) const
+{
+ ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
+ for (USHORT i=0; i<4; i++)
+ if ( pGridWin[i] == pWindow )
+ eVal = (ScSplitPos) i;
+
+ return eVal;
+}
+
+Point ScTabView::GetGridOffset() const
+{
+ Point aPos;
+
+ // Groessen hier wie in DoResize
+
+ BOOL bHeaders = aViewData.IsHeaderMode();
+ BOOL bOutlMode = aViewData.IsOutlineMode();
+ BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+
+ // Outline-Controls
+ if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
+ aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
+ if (bHOutline && pColOutline[SC_SPLIT_LEFT])
+ aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ if (pRowBar[SC_SPLIT_BOTTOM])
+ aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ if (pColBar[SC_SPLIT_LEFT])
+ aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ }
+
+ return aPos;
+}
+
+// --- Scroll-Bars --------------------------------------------------------
+
+BOOL ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
+{
+ HideNoteMarker();
+
+ BOOL bDone = FALSE;
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
+ {
+ if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ // for ole inplace editing, the scale is defined by the visarea and client size
+ // and can't be changed directly
+
+ const Fraction& rOldY = aViewData.GetZoomY();
+ long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
+ long nNew = nOld;
+ if ( pData->GetDelta() < 0 )
+ nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
+ else
+ nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );
+
+ if ( nNew != nOld )
+ {
+ // scroll wheel doesn't set the AppOptions default
+
+ BOOL bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
+ SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
+ Fraction aFract( nNew, 100 );
+ SetZoom( aFract, aFract, bSyncZoom );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
+ aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
+ }
+
+ bDone = TRUE;
+ }
+ }
+ else
+ {
+ ScHSplitPos eHPos = WhichH(ePos);
+ ScVSplitPos eVPos = WhichV(ePos);
+ ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight;
+ ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? &aVScrollTop : &aVScrollBottom;
+ if ( pGridWin[ePos] )
+ bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
+ }
+ return bDone;
+}
+
+IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll )
+{
+ BOOL bOnlineScroll = TRUE; //! Optionen
+
+ if ( bDragging )
+ {
+ if ( bOnlineScroll ) // nur Ranges aktualisieren
+ UpdateScrollBars();
+ else
+ {
+ long nScrollMin = 0; // RangeMin simulieren
+ if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
+ nScrollMin = aViewData.GetFixPosX();
+ if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
+ nScrollMin = aViewData.GetFixPosY();
+
+ if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight )
+ {
+ BOOL bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL();
+ ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+ long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich);
+ if (nDelta) ScrollX( nDelta, eWhich );
+ }
+ else // VScroll...
+ {
+ ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+ long nDelta = GetScrollBarPos( *pScroll, FALSE ) + nScrollMin - aViewData.GetPosY(eWhich);
+ if (nDelta) ScrollY( nDelta, eWhich );
+ }
+ }
+ bDragging = FALSE;
+ }
+ return 0;
+}
+
+IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll )
+{
+ BOOL bOnlineScroll = TRUE; //! Optionen
+
+ BOOL bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight );
+ long nViewPos;
+ if ( bHoriz )
+ nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
+ else
+ nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM );
+
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ BOOL bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL());
+
+ ScrollType eType = pScroll->GetType();
+ if ( eType == SCROLL_DRAG )
+ {
+ if (!bDragging)
+ {
+ bDragging = TRUE;
+ nPrevDragPos = nViewPos;
+ }
+
+ // Scroll-Position anzeigen
+ // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer)
+
+ if (Help::IsQuickHelpEnabled())
+ {
+ Size aSize = pScroll->GetSizePixel();
+
+ /* Convert scrollbar mouse position to screen position. If RTL
+ mode of scrollbar differs from RTL mode of its parent, then the
+ direct call to Window::OutputToNormalizedScreenPixel() will
+ give unusable results, because calcualtion of screen position
+ is based on parent orientation and expects equal orientation of
+ the child position. Need to mirror mouse position before. */
+ Point aMousePos = pScroll->GetPointerPosPixel();
+ if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
+ aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
+ aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
+
+ // convert top-left position of scrollbar to screen position
+ Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
+
+ // get scrollbar scroll position for help text (row number/column name)
+ long nScrollMin = 0; // RangeMin simulieren
+ if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
+ nScrollMin = aViewData.GetFixPosX();
+ if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
+ nScrollMin = aViewData.GetFixPosY();
+ long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
+
+ String aHelpStr;
+ Rectangle aRect;
+ USHORT nAlign;
+ if (bHoriz)
+ {
+ aHelpStr = ScGlobal::GetRscString(STR_COLUMN);
+ aHelpStr += ' ';
+ aHelpStr += ScColToAlpha((SCCOL) nScrollPos);
+
+ aRect.Left() = aMousePos.X();
+ aRect.Top() = aPos.Y() - 4;
+ nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
+ }
+ else
+ {
+ aHelpStr = ScGlobal::GetRscString(STR_ROW);
+ aHelpStr += ' ';
+ aHelpStr += String::CreateFromInt32(nScrollPos + 1);
+
+ // show quicktext always inside sheet area
+ aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
+ aRect.Top() = aMousePos.Y();
+ nAlign = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER;
+ }
+ aRect.Right() = aRect.Left();
+ aRect.Bottom() = aRect.Top();
+
+ Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
+ }
+ }
+
+ if ( bOnlineScroll || eType != SCROLL_DRAG )
+ {
+ if ( bMirror )
+ {
+ // change scroll type so visible/previous cells calculation below remains the same
+ switch ( eType )
+ {
+ case SCROLL_LINEUP: eType = SCROLL_LINEDOWN; break;
+ case SCROLL_LINEDOWN: eType = SCROLL_LINEUP; break;
+ case SCROLL_PAGEUP: eType = SCROLL_PAGEDOWN; break;
+ case SCROLL_PAGEDOWN: eType = SCROLL_PAGEUP; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ long nDelta = pScroll->GetDelta();
+ switch ( eType )
+ {
+ case SCROLL_LINEUP:
+ nDelta = -1;
+ break;
+ case SCROLL_LINEDOWN:
+ nDelta = 1;
+ break;
+ case SCROLL_PAGEUP:
+ if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
+ if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
+ if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
+ if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
+ if (nDelta==0) nDelta=-1;
+ break;
+ case SCROLL_PAGEDOWN:
+ if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
+ if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
+ if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
+ if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
+ if (nDelta==0) nDelta=1;
+ break;
+ case SCROLL_DRAG:
+ {
+ // nur in die richtige Richtung scrollen, nicht um ausgeblendete
+ // Bereiche herumzittern
+
+ long nScrollMin = 0; // RangeMin simulieren
+ if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
+ nScrollMin = aViewData.GetFixPosX();
+ if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
+ nScrollMin = aViewData.GetFixPosY();
+
+ long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
+ nDelta = nScrollPos - nViewPos;
+ if ( nScrollPos > nPrevDragPos )
+ {
+ if (nDelta<0) nDelta=0;
+ }
+ else if ( nScrollPos < nPrevDragPos )
+ {
+ if (nDelta>0) nDelta=0;
+ }
+ else
+ nDelta = 0;
+ nPrevDragPos = nScrollPos;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nDelta)
+ {
+ BOOL bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern
+ if ( bHoriz )
+ ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
+ else
+ ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
+ }
+ }
+
+ return 0;
+}
+
+void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, BOOL bUpdBars )
+{
+ BOOL bHasHint = ( pInputHintWindow != NULL );
+ if (bHasHint)
+ RemoveHintWindow();
+
+ SCCOL nOldX = aViewData.GetPosX(eWhich);
+ SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
+ if ( nNewX < 0 )
+ {
+ nDeltaX -= nNewX;
+ nNewX = 0;
+ }
+ if ( nNewX > MAXCOL )
+ {
+ nDeltaX -= nNewX - MAXCOL;
+ nNewX = MAXCOL;
+ }
+
+ SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( pDoc->ColHidden(nNewX, nTab) &&
+ nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
+ nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );
+
+ // Fixierung
+
+ if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
+ {
+ if (eWhich == SC_SPLIT_LEFT)
+ nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen
+ else
+ {
+ SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
+ if (nNewX < nFixX)
+ nNewX = nFixX;
+ }
+ }
+ if (nNewX == static_cast<SCsCOL>(nOldX))
+ return;
+
+ HideAllCursors();
+
+ if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
+ {
+ SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );
+
+ // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update
+ // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl.
+ // mit schon geaenderter Pos. gepainted werden -
+ // darum vorher einmal Update am Col-/RowBar
+
+ if (pColBar[eWhich])
+ pColBar[eWhich]->Update();
+
+ long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
+ aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
+ long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
+
+ if ( eWhich==SC_SPLIT_LEFT )
+ {
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
+ }
+ else
+ {
+ pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
+ }
+ if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
+ if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
+ if (bUpdBars)
+ UpdateScrollBars();
+ }
+
+ if (nDeltaX==1 || nDeltaX==-1)
+ pGridWin[aViewData.GetActivePart()]->Update();
+
+ ShowAllCursors();
+
+ SetNewVisArea(); // MapMode muss schon gesetzt sein
+
+ if (bHasHint)
+ TestHintWindow(); // neu positionieren
+}
+
+void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, BOOL bUpdBars )
+{
+ BOOL bHasHint = ( pInputHintWindow != NULL );
+ if (bHasHint)
+ RemoveHintWindow();
+
+ SCROW nOldY = aViewData.GetPosY(eWhich);
+ SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
+ if ( nNewY < 0 )
+ {
+ nDeltaY -= nNewY;
+ nNewY = 0;
+ }
+ if ( nNewY > MAXROW )
+ {
+ nDeltaY -= nNewY - MAXROW;
+ nNewY = MAXROW;
+ }
+
+ SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( pDoc->RowHidden(nNewY, nTab) &&
+ nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
+ nNewY += nDir;
+
+ // Fixierung
+
+ if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
+ {
+ if (eWhich == SC_SPLIT_TOP)
+ nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen
+ else
+ {
+ SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
+ if (nNewY < nFixY)
+ nNewY = nFixY;
+ }
+ }
+ if (nNewY == static_cast<SCsROW>(nOldY))
+ return;
+
+ HideAllCursors();
+
+ if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
+ {
+ SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );
+
+ // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht
+ // doppelt gepainted werden muss
+ // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben
+ SCROW nUNew = static_cast<SCROW>(nNewY);
+ UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen
+
+ if (pRowBar[eWhich])
+ pRowBar[eWhich]->Update();
+
+ long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
+ aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
+ long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
+
+ if ( eWhich==SC_SPLIT_TOP )
+ {
+ pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
+ }
+ else
+ {
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
+ }
+ if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
+ if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
+ if (bUpdBars)
+ UpdateScrollBars();
+ }
+
+ if (nDeltaY==1 || nDeltaY==-1)
+ pGridWin[aViewData.GetActivePart()]->Update();
+
+ ShowAllCursors();
+
+ SetNewVisArea(); // MapMode muss schon gesetzt sein
+
+ if (bHasHint)
+ TestHintWindow(); // neu positionieren
+}
+
+void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
+{
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ if (nDeltaX)
+ ScrollX(nDeltaX,WhichH(eWhich));
+ if (nDeltaY)
+ ScrollY(nDeltaY,WhichV(eWhich));
+}
+
+SCROW lcl_LastVisible( ScViewData& rViewData )
+{
+ // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?),
+ // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden
+ //! als Member ans Dokument ???
+
+ ScDocument* pDoc = rViewData.GetDocument();
+ SCTAB nTab = rViewData.GetTabNo();
+
+ SCROW nVis = MAXROW;
+ while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
+ --nVis;
+ return nVis;
+}
+
+void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
+{
+ if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
+ return;
+
+ SCROW nEndPos = MAXROW;
+ if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ // fuer OLE Inplace immer MAXROW
+
+ if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
+ nEndPos = *pPosY;
+ else
+ nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
+ nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY
+ if (nEndPos > MAXROW)
+ nEndPos = lcl_LastVisible( aViewData );
+
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ {
+ SCROW nTopEnd;
+ if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
+ nTopEnd = *pPosY;
+ else
+ nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
+ nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY
+ if (nTopEnd > MAXROW)
+ nTopEnd = lcl_LastVisible( aViewData );
+
+ if ( nTopEnd > nEndPos )
+ nEndPos = nTopEnd;
+ }
+ }
+
+ long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
+ long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
+ long nDiff = nBig - nSmall;
+
+ if (nEndPos>10000)
+ nEndPos = 10000;
+ else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
+ nEndPos = 1;
+ long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
+
+ if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
+ {
+ bInUpdateHeader = TRUE;
+
+ pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
+ if (pRowBar[SC_SPLIT_TOP])
+ pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
+
+ RepeatResize();
+
+ // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster)
+ //aCornerButton.Update(); // der bekommt sonst nie ein Update
+
+ bInUpdateHeader = FALSE;
+ }
+}
+
+inline void ShowHide( Window* pWin, BOOL bShow )
+{
+ DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da");
+ if (pWin)
+ pWin->Show(bShow);
+}
+
+void ScTabView::UpdateShow()
+{
+ BOOL bHScrollMode = aViewData.IsHScrollMode();
+ BOOL bVScrollMode = aViewData.IsVScrollMode();
+ BOOL bTabMode = aViewData.IsTabMode();
+ BOOL bOutlMode = aViewData.IsOutlineMode();
+ BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+ BOOL bHeader = aViewData.IsHeaderMode();
+
+ BOOL bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
+ BOOL bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
+
+ // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
+ SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
+ if ( eMode == SCROLLING_NO )
+ bHScrollMode = bVScrollMode = FALSE;
+ else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
+ bHScrollMode = bVScrollMode = TRUE;
+
+ if ( aViewData.GetDocShell()->IsPreview() )
+ bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = FALSE;
+
+ //
+ // Windows anlegen
+ //
+
+ if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
+ {
+ pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
+ DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
+ }
+ if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
+ {
+ pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
+ DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
+ }
+ if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
+ {
+ pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
+ DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
+ }
+
+ if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
+ pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
+ if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
+ pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );
+
+ if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
+ pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
+ if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
+ pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );
+
+ if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
+ pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT,
+ &aHdrFunc, pHdrSelEng );
+ if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
+ pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP,
+ &aHdrFunc, pHdrSelEng );
+
+ //
+ // Windows anzeigen
+ //
+
+ ShowHide( &aHScrollLeft, bHScrollMode );
+ ShowHide( &aHScrollRight, bShowH && bHScrollMode );
+ ShowHide( &aVScrollBottom, bVScrollMode );
+ ShowHide( &aVScrollTop, bShowV && bVScrollMode );
+ ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode );
+
+ ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt
+ ShowHide( pVSplitter, bVScrollMode || bShowV );
+ ShowHide( pTabControl, bTabMode );
+
+ // ab hier dynamisch angelegte
+
+ ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
+ ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
+ ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
+
+ ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
+ ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
+
+ ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
+ ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
+
+ ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
+ ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
+
+
+ //! neue Gridwindows eintragen
+}
+
+// --- Splitter --------------------------------------------------------
+
+IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter )
+{
+ if ( pSplitter == pHSplitter )
+ DoHSplit( pHSplitter->GetSplitPosPixel() );
+ else
+ DoVSplit( pVSplitter->GetSplitPosPixel() );
+
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ FreezeSplitters( TRUE );
+
+ DoResize( aBorderPos, aFrameSize );
+
+ return 0;
+}
+
+void ScTabView::DoHSplit(long nSplitPos)
+{
+ // nSplitPos is the real pixel position on the frame window,
+ // mirroring for RTL has to be done here.
+
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ if ( bLayoutRTL )
+ nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
+
+ long nMinPos;
+ long nMaxPos;
+ SCCOL nOldDelta;
+ SCCOL nNewDelta;
+
+ nMinPos = SPLIT_MARGIN;
+ if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
+ nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
+ nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
+
+ ScSplitMode aOldMode = aViewData.GetHSplitMode();
+ ScSplitMode aNewMode = SC_SPLIT_NORMAL;
+
+ aViewData.SetHSplitPos( nSplitPos );
+ if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
+ aNewMode = SC_SPLIT_NONE;
+
+ aViewData.SetHSplitMode( aNewMode );
+
+ if ( aNewMode != aOldMode )
+ {
+ UpdateShow(); // vor ActivatePart !!
+
+ if ( aNewMode == SC_SPLIT_NONE )
+ {
+ if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
+ ActivatePart( SC_SPLIT_TOPLEFT );
+ if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ }
+ else
+ {
+ nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
+// aViewData.SetPosX( SC_SPLIT_LEFT, nOldDelta );
+ long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ if ( nLeftWidth < 0 ) nLeftWidth = 0;
+ nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
+ (USHORT) nLeftWidth );
+ if ( nNewDelta > MAXCOL )
+ nNewDelta = MAXCOL;
+ aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
+ if ( nNewDelta > aViewData.GetCurX() )
+ ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
+ SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
+ else
+ ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
+ SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
+ }
+
+ // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ PaintGrid();
+ PaintTop();
+
+ InvalidateSplit();
+ }
+}
+
+void ScTabView::DoVSplit(long nSplitPos)
+{
+ long nMinPos;
+ long nMaxPos;
+ SCROW nOldDelta;
+ SCROW nNewDelta;
+
+ nMinPos = SPLIT_MARGIN;
+ if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
+ nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
+ nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
+
+ ScSplitMode aOldMode = aViewData.GetVSplitMode();
+ ScSplitMode aNewMode = SC_SPLIT_NORMAL;
+
+ aViewData.SetVSplitPos( nSplitPos );
+ if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
+ aNewMode = SC_SPLIT_NONE;
+
+ aViewData.SetVSplitMode( aNewMode );
+
+ if ( aNewMode != aOldMode )
+ {
+ UpdateShow(); // vor ActivatePart !!
+
+ if ( aNewMode == SC_SPLIT_NONE )
+ {
+ nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
+ aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
+
+ if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
+ ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+ else
+ {
+ if ( aOldMode == SC_SPLIT_NONE )
+ nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
+ else
+ nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
+
+ aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
+ long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ if ( nTopHeight < 0 ) nTopHeight = 0;
+ nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
+ (USHORT) nTopHeight );
+ if ( nNewDelta > MAXROW )
+ nNewDelta = MAXROW;
+ aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
+ if ( nNewDelta > aViewData.GetCurY() )
+ ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
+ SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
+ else
+ ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
+ SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
+ }
+
+ // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ PaintGrid();
+ PaintLeft();
+
+ InvalidateSplit();
+ }
+}
+
+Point ScTabView::GetInsertPos()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+ SCTAB nTab = aViewData.GetTabNo();
+ long nPosX = 0;
+ for (SCCOL i=0; i<nCol; i++)
+ nPosX += pDoc->GetColWidth(i,nTab);
+ nPosX = (long)(nPosX * HMM_PER_TWIPS);
+ if ( pDoc->IsNegativePage( nTab ) )
+ nPosX = -nPosX;
+ long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
+ nPosY = (long)(nPosY * HMM_PER_TWIPS);
+ return Point(nPosX,nPosY);
+}
+
+Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
+{
+ Point aInsertPos;
+ const long nBorder = 100; // leave 1mm for border
+ long nNeededWidth = rSize.Width() + 2 * nBorder;
+ long nNeededHeight = rSize.Height() + 2 * nBorder;
+
+ // use the active window, or lower/right if frozen (as in CalcZoom)
+ ScSplitPos eUsedPart = aViewData.GetActivePart();
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+
+ ScGridWindow* pWin = pGridWin[eUsedPart];
+ DBG_ASSERT( pWin, "Window not found" );
+ if (pWin)
+ {
+ ActivatePart( eUsedPart );
+
+ // get the visible rectangle in logic units
+
+ MapMode aDrawMode = pWin->GetDrawMapMode();
+ Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
+ long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );
+
+ if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
+ aVisible.Left() = nDocX;
+ if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
+ aVisible.Right() = nDocX;
+ if ( aVisible.Top() > nDocY )
+ aVisible.Top() = nDocY;
+ if ( aVisible.Bottom() > nDocY )
+ aVisible.Bottom() = nDocY;
+
+ // get the logic position of the selection
+
+ Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
+ rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
+
+ long nLeftSpace = aSelection.Left() - aVisible.Left();
+ long nRightSpace = aVisible.Right() - aSelection.Right();
+ long nTopSpace = aSelection.Top() - aVisible.Top();
+ long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
+
+ bool bFitLeft = ( nLeftSpace >= nNeededWidth );
+ bool bFitRight = ( nRightSpace >= nNeededWidth );
+
+ if ( bFitLeft || bFitRight )
+ {
+ // first preference: completely left or right of the selection
+
+ // if both fit, prefer left in RTL mode, right otherwise
+ bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
+
+ if ( bPutLeft )
+ aInsertPos.X() = aSelection.Left() - nNeededWidth;
+ else
+ aInsertPos.X() = aSelection.Right() + 1;
+
+ // align with top of selection (is moved again if it doesn't fit)
+ aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
+ }
+ else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
+ {
+ // second preference: completely above or below the selection
+
+ if ( nBottomSpace > nNeededHeight ) // bottom is preferred
+ aInsertPos.Y() = aSelection.Bottom() + 1;
+ else
+ aInsertPos.Y() = aSelection.Top() - nNeededHeight;
+
+ // align with (logic) left edge of selection (moved again if it doesn't fit)
+ if ( bLayoutRTL )
+ aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
+ else
+ aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
+ }
+ else
+ {
+ // place to the (logic) right of the selection and move so it fits
+
+ if ( bLayoutRTL )
+ aInsertPos.X() = aSelection.Left() - nNeededWidth;
+ else
+ aInsertPos.X() = aSelection.Right() + 1;
+ aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
+ }
+
+ // move the position if the object doesn't fit in the screen
+
+ Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
+ if ( aCompareRect.Right() > aVisible.Right() )
+ aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
+ if ( aCompareRect.Bottom() > aVisible.Bottom() )
+ aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();
+
+ if ( aInsertPos.X() < aVisible.Left() )
+ aInsertPos.X() = aVisible.Left();
+ if ( aInsertPos.Y() < aVisible.Top() )
+ aInsertPos.Y() = aVisible.Top();
+
+ // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
+ // object position, inside the border
+
+ aInsertPos.X() += nBorder;
+ aInsertPos.Y() += nBorder;
+ }
+ return aInsertPos;
+}
+
+Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
+{
+ // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
+
+ Point aRet;
+
+ // use the active window, or lower/right if frozen (as in CalcZoom)
+ ScSplitPos eUsedPart = aViewData.GetActivePart();
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+
+ ScGridWindow* pWin = pGridWin[eUsedPart];
+ DBG_ASSERT( pWin, "Window not found" );
+ if (pWin)
+ {
+ MapMode aDrawMode = pWin->GetDrawMapMode();
+ Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
+ Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
+ pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
+
+ Rectangle aDesktop = pWin->GetDesktopRectPixel();
+ Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ bool bCenterHor = false;
+
+ if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
+ {
+ // first preference: below the chart
+
+ aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
+ bCenterHor = true;
+ }
+ else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
+ {
+ // second preference: above the chart
+
+ aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
+ bCenterHor = true;
+ }
+ else
+ {
+ bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
+ bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
+
+ if ( bFitLeft || bFitRight )
+ {
+ // if both fit, prefer right in RTL mode, left otherwise
+ bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
+ if ( bPutRight )
+ aRet.X() = aObjAbs.Right() + aSpace.Width();
+ else
+ aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();
+
+ // center vertically
+ aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
+ }
+ else
+ {
+ // doesn't fit on any edge - put at the bottom of the screen
+ aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
+ bCenterHor = true;
+ }
+ }
+ if ( bCenterHor )
+ aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;
+
+ // limit to screen (centering might lead to invalid positions)
+ if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
+ aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
+ if ( aRet.X() < aDesktop.Left() )
+ aRet.X() = aDesktop.Left();
+ if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
+ aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
+ if ( aRet.Y() < aDesktop.Top() )
+ aRet.Y() = aDesktop.Top();
+ }
+
+ return aRet;
+}
+
+void ScTabView::LockModifiers( USHORT nModifiers )
+{
+ pSelEngine->LockModifiers( nModifiers );
+ pHdrSelEng->LockModifiers( nModifiers );
+}
+
+USHORT ScTabView::GetLockedModifiers() const
+{
+ return pSelEngine->GetLockedModifiers();
+}
+
+Point ScTabView::GetMousePosPixel()
+{
+ Point aPos;
+ ScGridWindow* pWin = (ScGridWindow*)GetActiveWin();
+
+ if ( pWin )
+ aPos = pWin->GetMousePosPixel();
+
+ return aPos;
+}
+
+BOOL lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin )
+{
+ if (pWin)
+ {
+ // SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau
+ // auf dem Splitter nicht aussetzt
+
+ Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
+ Size aWinSize = pWin->GetOutputSizePixel();
+ if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE &&
+ aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ScTabView::SnapSplitPos( Point& rScreenPosPixel )
+{
+ BOOL bOverWin = FALSE;
+ USHORT i;
+ for (i=0; i<4; i++)
+ if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i]))
+ bOverWin = TRUE;
+
+ if (!bOverWin)
+ return;
+
+ // #74761# don't snap to cells if the scale will be modified afterwards
+ if ( GetZoomType() != SVX_ZOOM_PERCENT )
+ return;
+
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+
+ Window* pWin = pGridWin[ePos];
+ if (!pWin)
+ {
+ DBG_ERROR("Window NULL");
+ return;
+ }
+
+ Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ // #52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters
+ aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, TRUE, FALSE, FALSE );
+ BOOL bLeft;
+ BOOL bTop;
+ aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop );
+ if (!bLeft)
+ ++nPosX;
+ if (!bTop)
+ ++nPosY;
+ aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, TRUE );
+ rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse );
+}
+
+void ScTabView::FreezeSplitters( BOOL bFreeze )
+{
+ ScSplitMode eOldH = aViewData.GetHSplitMode();
+ ScSplitMode eOldV = aViewData.GetVSplitMode();
+
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( eOldV != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+ Window* pWin = pGridWin[ePos];
+
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+
+ if ( bFreeze )
+ {
+ Point aWinStart = pWin->GetPosPixel();
+
+ Point aSplit;
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE)
+ {
+ if (eOldH != SC_SPLIT_NONE)
+ {
+ long nSplitPos = aViewData.GetHSplitPos();
+ if ( bLayoutRTL )
+ nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
+ aSplit.X() = nSplitPos - aWinStart.X();
+ }
+ if (eOldV != SC_SPLIT_NONE)
+ aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();
+
+ aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
+ BOOL bLeft;
+ BOOL bTop;
+ aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
+ if (!bLeft)
+ ++nPosX;
+ if (!bTop)
+ ++nPosY;
+ }
+ else
+ {
+ nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
+ nPosY = static_cast<SCsROW>( aViewData.GetCurY());
+ }
+
+ SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
+ SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
+ SCCOL nRightPos = static_cast<SCCOL>(nPosX);
+ SCROW nBottomPos = static_cast<SCROW>(nPosY);
+ if (eOldH != SC_SPLIT_NONE)
+ if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
+ nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
+ if (eOldV != SC_SPLIT_NONE)
+ {
+ nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
+ if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
+ nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
+ }
+
+ aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, TRUE );
+ if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
+ {
+ long nSplitPos = aSplit.X() + aWinStart.X();
+ if ( bLayoutRTL )
+ nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
+
+ aViewData.SetHSplitMode( SC_SPLIT_FIX );
+ aViewData.SetHSplitPos( nSplitPos );
+ aViewData.SetFixPosX( nPosX );
+
+ aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
+ aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
+ }
+ else
+ aViewData.SetHSplitMode( SC_SPLIT_NONE );
+ if (aSplit.Y() > 0)
+ {
+ aViewData.SetVSplitMode( SC_SPLIT_FIX );
+ aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
+ aViewData.SetFixPosY( nPosY );
+
+ aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
+ aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
+ }
+ else
+ aViewData.SetVSplitMode( SC_SPLIT_NONE );
+ }
+ else // Fixierung aufheben
+ {
+ if ( eOldH == SC_SPLIT_FIX )
+ aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
+ if ( eOldV == SC_SPLIT_FIX )
+ aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
+ }
+
+ // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ RepeatResize(FALSE);
+
+ UpdateShow();
+ PaintLeft();
+ PaintTop();
+ PaintGrid();
+
+ // SC_FOLLOW_NONE: only update active part
+ AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
+ UpdateAutoFillMark();
+
+ InvalidateSplit();
+}
+
+void ScTabView::RemoveSplit()
+{
+ DoHSplit( 0 );
+ DoVSplit( 0 );
+ RepeatResize();
+}
+
+void ScTabView::SplitAtCursor()
+{
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+ Window* pWin = pGridWin[ePos];
+ Point aWinStart = pWin->GetPosPixel();
+
+ SCCOL nPosX = aViewData.GetCurX();
+ SCROW nPosY = aViewData.GetCurY();
+ Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, TRUE );
+ if ( nPosX > 0 )
+ DoHSplit( aSplit.X() + aWinStart.X() );
+ else
+ DoHSplit( 0 );
+ if ( nPosY > 0 )
+ DoVSplit( aSplit.Y() + aWinStart.Y() );
+ else
+ DoVSplit( 0 );
+ RepeatResize();
+}
+
+void ScTabView::SplitAtPixel( const Point& rPixel, BOOL bHor, BOOL bVer ) // fuer API
+{
+ // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin
+
+ if (bHor)
+ {
+ if ( rPixel.X() > 0 )
+ DoHSplit( rPixel.X() );
+ else
+ DoHSplit( 0 );
+ }
+ if (bVer)
+ {
+ if ( rPixel.Y() > 0 )
+ DoVSplit( rPixel.Y() );
+ else
+ DoVSplit( 0 );
+ }
+ RepeatResize();
+}
+
+void ScTabView::InvalidateSplit()
+{
+ SfxBindings& rBindings = aViewData.GetBindings();
+ rBindings.Invalidate( SID_WINDOW_SPLIT );
+ rBindings.Invalidate( SID_WINDOW_FIX );
+
+ pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
+ pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
+}
+
+void ScTabView::SetNewVisArea()
+{
+ // #63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein
+ // (auch wenn ansonsten der Edit-MapMode gesetzt ist)
+ MapMode aOldMode[4];
+ MapMode aDrawMode[4];
+ USHORT i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ aOldMode[i] = pGridWin[i]->GetMapMode();
+ aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
+ if (aDrawMode[i] != aOldMode[i])
+ pGridWin[i]->SetMapMode(aDrawMode[i]);
+ }
+
+ Window* pActive = pGridWin[aViewData.GetActivePart()];
+ if (pActive)
+ aViewData.GetViewShell()->VisAreaChanged(
+ pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
+ if (pDrawView)
+ pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster
+
+ UpdateAllOverlays(); // #i79909# with drawing MapMode set
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
+ {
+ pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
+ pGridWin[i]->SetMapMode(aOldMode[i]);
+ }
+
+ SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->VisAreaChanged();
+ }
+ }
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
+}
+
+sal_Bool ScTabView::HasPageFieldDataAtCursor() const
+{
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+ if (pWin)
+ return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
+
+ return sal_False;
+}
+
+void ScTabView::StartDataSelect()
+{
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+
+ if (!pWin)
+ return;
+
+ switch (pWin->GetDPFieldOrientation(nCol, nRow))
+ {
+ case sheet::DataPilotFieldOrientation_PAGE:
+ // #i36598# If the cursor is on a page field's data cell,
+ // no meaningful input is possible anyway, so this function
+ // can be used to select a page field entry.
+ pWin->LaunchPageFieldMenu( nCol, nRow );
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ case sheet::DataPilotFieldOrientation_ROW:
+ pWin->LaunchDPFieldMenu( nCol, nRow );
+ break;
+ default:
+ pWin->DoAutoFilterMenue( nCol, nRow, TRUE );
+ }
+}
+
+void ScTabView::EnableRefInput(BOOL bFlag)
+{
+ aHScrollLeft.EnableInput(bFlag);
+ aHScrollRight.EnableInput(bFlag);
+ aVScrollBottom.EnableInput(bFlag);
+ aVScrollTop.EnableInput(bFlag);
+ aScrollBarBox.EnableInput(bFlag);
+
+ // ab hier dynamisch angelegte
+
+ if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,TRUE);
+
+ if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL)
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,FALSE);
+ if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL)
+ pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,FALSE);
+ if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL)
+ pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,FALSE);
+ if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL)
+ pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,FALSE);
+ if(pColBar[SC_SPLIT_RIGHT]!=NULL)
+ pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,FALSE);
+ if(pRowBar[SC_SPLIT_TOP]!=NULL)
+ pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,FALSE);
+}
+
+
+
diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx
new file mode 100644
index 000000000000..674f6f8ae0ff
--- /dev/null
+++ b/sc/source/ui/view/tabview2.cxx
@@ -0,0 +1,982 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <vcl/timer.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/childwin.hxx>
+
+#include "attrib.hxx"
+#include "pagedata.hxx"
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "printfun.hxx"
+#include "stlpool.hxx"
+#include "docsh.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "viewutil.hxx"
+#include "colrowba.hxx"
+#include "waitoff.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+
+#define SC_BLOCKMODE_NONE 0
+#define SC_BLOCKMODE_NORMAL 1
+#define SC_BLOCKMODE_OWN 2
+
+
+
+//
+// Markier - Funktionen
+//
+
+void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+ if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+ if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+ if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+
+ BOOL bLeft = (nStartCol==0 && nEndCol==MAXCOL);
+ BOOL bTop = (nStartRow==0 && nEndRow==MAXROW);
+
+ if (bLeft)
+ PaintLeftArea( nStartRow, nEndRow );
+ if (bTop)
+ PaintTopArea( nStartCol, nEndCol );
+
+ aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
+ aViewData.GetTabNo() );
+ PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
+}
+
+BOOL ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ return bIsBlockMode
+ && nBlockStartX == nCol
+ && nBlockStartY == nRow
+ && nBlockStartZ == nTab;
+}
+
+void ScTabView::InitOwnBlockMode()
+{
+ if (!bIsBlockMode)
+ {
+ // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ GetSelEngine()->CursorPosChanging( FALSE, FALSE );
+
+// bIsBlockMode = TRUE;
+ bIsBlockMode = SC_BLOCKMODE_OWN; //! Variable umbenennen!
+ nBlockStartX = 0;
+ nBlockStartY = 0;
+ nBlockStartZ = 0;
+ nBlockEndX = 0;
+ nBlockEndY = 0;
+ nBlockEndZ = 0;
+
+ SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt
+ }
+}
+
+void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ BOOL bTestNeg, BOOL bCols, BOOL bRows )
+{
+ if (!bIsBlockMode)
+ {
+ if (!ValidCol(nCurX)) nCurX = MAXCOL;
+ if (!ValidRow(nCurY)) nCurY = MAXROW;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ // Teil von Markierung aufheben?
+ if (bTestNeg)
+ {
+ if ( bCols )
+ bBlockNeg = rMark.IsColumnMarked( nCurX );
+ else if ( bRows )
+ bBlockNeg = rMark.IsRowMarked( nCurY );
+ else
+ bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
+ }
+ else
+ bBlockNeg = FALSE;
+ rMark.SetMarkNegative(bBlockNeg);
+
+// bIsBlockMode = TRUE;
+ bIsBlockMode = SC_BLOCKMODE_NORMAL; //! Variable umbenennen!
+ bBlockCols = bCols;
+ bBlockRows = bRows;
+ nBlockStartX = nBlockStartXOrig = nCurX;
+ nBlockStartY = nBlockStartYOrig = nCurY;
+ nBlockStartZ = nCurZ;
+ nBlockEndX = nOldCurX = nBlockStartX;
+ nBlockEndY = nOldCurY = nBlockStartY;
+ nBlockEndZ = nBlockStartZ;
+
+ if (bBlockCols)
+ {
+ nBlockStartY = nBlockStartYOrig = 0;
+ nBlockEndY = MAXROW;
+ }
+
+ if (bBlockRows)
+ {
+ nBlockStartX = nBlockStartXOrig = 0;
+ nBlockEndX = MAXCOL;
+ }
+
+ rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
+
+#ifdef OLD_SELECTION_PAINT
+ InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
+#endif
+ UpdateSelectionOverlay();
+
+ bNewStartIfMarking = FALSE; // use only once
+ }
+}
+
+void ScTabView::SetNewStartIfMarking()
+{
+ bNewStartIfMarking = TRUE;
+}
+
+void ScTabView::DoneBlockMode( BOOL bContinue ) // Default FALSE
+{
+ // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
+ // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
+ // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
+
+ if (bIsBlockMode && !bMoveIsShift)
+ {
+ ScMarkData& rMark = aViewData.GetMarkData();
+ BOOL bFlag = rMark.GetMarkingFlag();
+ rMark.SetMarking(FALSE);
+
+ if (bBlockNeg && !bContinue)
+ rMark.MarkToMulti();
+
+ if (bContinue)
+ rMark.MarkToMulti();
+ else
+ {
+ // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
+ // aus SetTabNo aufgerufen wird
+ // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
+
+ SCTAB nTab = aViewData.GetTabNo();
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( pDoc->HasTable(nTab) )
+ PaintBlock( TRUE ); // TRUE -> Block loeschen
+ else
+ rMark.ResetMark();
+ }
+// bIsBlockMode = FALSE;
+ bIsBlockMode = SC_BLOCKMODE_NONE; //! Variable umbenennen!
+
+ rMark.SetMarking(bFlag);
+ rMark.SetMarkNegative(FALSE);
+ }
+}
+
+void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ BOOL bCols, BOOL bRows, BOOL bCellSelection )
+{
+ if (!ValidCol(nCurX)) nCurX = MAXCOL;
+ if (!ValidRow(nCurY)) nCurY = MAXROW;
+
+ if (!bIsBlockMode)
+ {
+ DBG_ERROR( "MarkCursor nicht im BlockMode" );
+ InitBlockMode( nCurX, nCurY, nCurZ, FALSE, bCols, bRows );
+ }
+
+ if (bCols)
+ nCurY = MAXROW;
+ if (bRows)
+ nCurX = MAXCOL;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ DBG_ASSERT(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
+ ScRange aMarkRange;
+ rMark.GetMarkArea(aMarkRange);
+ if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
+ ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
+ ( bIsBlockMode == SC_BLOCKMODE_OWN ))
+ {
+ // Markierung ist veraendert worden
+ // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
+ // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
+
+ BOOL bOldShift = bMoveIsShift;
+ bMoveIsShift = FALSE; // wirklich umsetzen
+ DoneBlockMode(FALSE); //! direkt Variablen setzen? (-> kein Geflacker)
+ bMoveIsShift = bOldShift;
+
+ InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
+ }
+
+ SCCOL nOldBlockEndX = nBlockEndX;
+ SCROW nOldBlockEndY = nBlockEndY;
+
+ if ( nCurX != nOldCurX || nCurY != nOldCurY )
+ {
+ // Current cursor has moved
+
+ SCTAB nTab = nCurZ;
+
+#ifdef OLD_SELECTION_PAINT
+ SCCOL nDrawStartCol;
+ SCROW nDrawStartRow;
+ SCCOL nDrawEndCol;
+ SCROW nDrawEndRow;
+#endif
+
+ // Set old selection area
+ ScUpdateRect aRect( nBlockStartX, nBlockStartY, nOldBlockEndX, nOldBlockEndY );
+
+ if ( bCellSelection )
+ {
+ // Expand selection area accordingly when the current selection ends
+ // with a merged cell.
+ SCsCOL nCurXOffset = 0;
+ SCsCOL nBlockStartXOffset = 0;
+ SCsROW nCurYOffset = 0;
+ SCsROW nBlockStartYOffset = 0;
+ BOOL bBlockStartMerged = FALSE;
+ const ScMergeAttr* pMergeAttr = NULL;
+ ScDocument* pDocument = aViewData.GetDocument();
+
+ // The following block checks whether or not the "BlockStart" (anchor)
+ // cell is merged. If it's merged, it'll then move the position of the
+ // anchor cell to the corner that's diagonally opposite of the
+ // direction of a current selection area. For instance, if a current
+ // selection is moving in the upperleft direction, the anchor cell will
+ // move to the lower-right corner of the merged anchor cell, and so on.
+
+ pMergeAttr = static_cast<const ScMergeAttr*>(
+ pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
+ if ( pMergeAttr->IsMerged() )
+ {
+ SCsCOL nColSpan = pMergeAttr->GetColMerge();
+ SCsROW nRowSpan = pMergeAttr->GetRowMerge();
+
+ if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
+ {
+ nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
+ nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
+ nCurXOffset = nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1 ?
+ nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
+ nCurYOffset = nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1 ?
+ nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
+ bBlockStartMerged = TRUE;
+ }
+ }
+
+ // The following block checks whether or not the current cell is
+ // merged. If it is, it'll then set the appropriate X & Y offset
+ // values (nCurXOffset & nCurYOffset) such that the selection area will
+ // grow by those specified offset amounts. Note that the values of
+ // nCurXOffset/nCurYOffset may also be specified in the previous code
+ // block, in which case whichever value is greater will take on.
+
+ pMergeAttr = static_cast<const ScMergeAttr*>(
+ pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
+ if ( pMergeAttr->IsMerged() )
+ {
+ SCsCOL nColSpan = pMergeAttr->GetColMerge();
+ SCsROW nRowSpan = pMergeAttr->GetRowMerge();
+
+ if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
+ {
+ if ( nBlockStartX <= nCurX + nColSpan - 1 )
+ {
+ SCsCOL nCurXOffsetTemp = nCurX < nCurX + nColSpan - 1 ? nColSpan - 1 : 0;
+ nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
+ }
+ if ( nBlockStartY <= nCurY + nRowSpan - 1 )
+ {
+ SCsROW nCurYOffsetTemp = nCurY < nCurY + nRowSpan - 1 ? nRowSpan - 1 : 0;
+ nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
+ }
+ if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
+ !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
+ {
+ nBlockStartXOffset = nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1 ? nCurX - nBlockStartX : 0;
+ nBlockStartYOffset = nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1 ? nCurY - nBlockStartY : 0;
+ }
+ }
+ }
+ else
+ {
+ // The current cell is not merged. Move the anchor cell to its
+ // original position.
+ if ( !bBlockStartMerged )
+ {
+ nBlockStartX = nBlockStartXOrig;
+ nBlockStartY = nBlockStartYOrig;
+ }
+ }
+
+ nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
+ nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
+ nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
+ nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
+ }
+ else
+ {
+ nBlockEndX = nCurX;
+ nBlockEndY = nCurY;
+ }
+ // end of "if ( bCellSelection )"
+
+ // Set new selection area
+ aRect.SetNew( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
+ rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
+
+#ifdef OLD_SELECTION_PAINT
+ BOOL bCont;
+ BOOL bDraw = aRect.GetXorDiff( nDrawStartCol, nDrawStartRow,
+ nDrawEndCol, nDrawEndRow, bCont );
+ if ( bDraw )
+ {
+//? PutInOrder( nDrawStartCol, nDrawEndCol );
+//? PutInOrder( nDrawStartRow, nDrawEndRow );
+
+ HideAllCursors();
+ InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
+ if (bCont)
+ {
+ aRect.GetContDiff( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
+ InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
+ }
+ ShowAllCursors();
+ }
+#endif
+ UpdateSelectionOverlay();
+
+ nOldCurX = nCurX;
+ nOldCurY = nCurY;
+
+ aViewData.GetViewShell()->UpdateInputHandler();
+// InvalidateAttribs();
+ }
+
+ if ( !bCols && !bRows )
+ aHdrFunc.SetAnchorFlag( FALSE );
+}
+
+void ScTabView::UpdateSelectionOverlay()
+{
+ for (USHORT i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateSelectionOverlay();
+}
+
+void ScTabView::UpdateShrinkOverlay()
+{
+ for (USHORT i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateShrinkOverlay();
+}
+
+void ScTabView::UpdateAllOverlays()
+{
+ for (USHORT i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateAllOverlays();
+}
+
+//!
+//! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
+//!
+
+void ScTabView::PaintBlock( BOOL bReset )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+ BOOL bMark = rMark.IsMarked();
+ BOOL bMulti = rMark.IsMultiMarked();
+ if (bMark || bMulti)
+ {
+ ScRange aMarkRange;
+ HideAllCursors();
+ if (bMulti)
+ {
+ BOOL bFlag = rMark.GetMarkingFlag();
+ rMark.SetMarking(FALSE);
+ rMark.MarkToMulti();
+ rMark.GetMultiMarkArea(aMarkRange);
+ rMark.MarkToSimple();
+ rMark.SetMarking(bFlag);
+
+ bMark = rMark.IsMarked();
+ bMulti = rMark.IsMultiMarked();
+ }
+ else
+ rMark.GetMarkArea(aMarkRange);
+
+ nBlockStartX = aMarkRange.aStart.Col();
+ nBlockStartY = aMarkRange.aStart.Row();
+ nBlockStartZ = aMarkRange.aStart.Tab();
+ nBlockEndX = aMarkRange.aEnd.Col();
+ nBlockEndY = aMarkRange.aEnd.Row();
+ nBlockEndZ = aMarkRange.aEnd.Tab();
+
+ BOOL bDidReset = FALSE;
+
+ if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
+ {
+ if ( bReset )
+ {
+ // Invertieren beim Loeschen nur auf aktiver View
+ if ( aViewData.IsActive() )
+ {
+ USHORT i;
+ if ( bMulti )
+ {
+#ifdef OLD_SELECTION_PAINT
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ pGridWin[i]->InvertSimple( nBlockStartX, nBlockStartY,
+ nBlockEndX, nBlockEndY,
+ TRUE, TRUE );
+#endif
+ rMark.ResetMark();
+ UpdateSelectionOverlay();
+ bDidReset = TRUE;
+ }
+ else
+ {
+#ifdef OLD_SELECTION_PAINT
+ // (mis)use InvertBlockMark to remove all of the selection
+ // -> set bBlockNeg (like when removing parts of a selection)
+ // and convert everything to Multi
+
+ rMark.MarkToMulti();
+ BOOL bOld = bBlockNeg;
+ bBlockNeg = TRUE;
+ // #73130# (negative) MarkArea must be set in case of repaint
+ rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab,
+ nBlockEndX,nBlockEndY, nTab ) );
+
+ InvertBlockMark( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
+
+ bBlockNeg = bOld;
+#endif
+ rMark.ResetMark();
+ UpdateSelectionOverlay();
+ bDidReset = TRUE;
+ }
+
+ // repaint if controls are touched (#69680# in both cases)
+ // #i74768# Forms are rendered by DrawingLayer's EndDrawLayers()
+ static bool bSuppressControlExtraStuff(true);
+
+ if(!bSuppressControlExtraStuff)
+ {
+ Rectangle aMMRect = pDoc->GetMMRect(nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY, nTab);
+ if (pDoc->HasControl( nTab, aMMRect ))
+ {
+ for (i=0; i<4; i++)
+ {
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ {
+ // MapMode muss logischer (1/100mm) sein !!!
+ pDoc->InvalidateControls( pGridWin[i], nTab, aMMRect );
+ pGridWin[i]->Update();
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
+ }
+
+ if ( bReset && !bDidReset )
+ rMark.ResetMark();
+
+ ShowAllCursors();
+ }
+}
+
+void ScTabView::SelectAll( BOOL bContinue )
+{
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
+ return;
+ }
+
+ DoneBlockMode( bContinue );
+ InitBlockMode( 0,0,nTab );
+ MarkCursor( MAXCOL,MAXROW,nTab );
+
+ SelectionChanged();
+}
+
+void ScTabView::SelectAllTables()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+// SCTAB nTab = aViewData.GetTabNo();
+ SCTAB nCount = pDoc->GetTableCount();
+
+ if (nCount>1)
+ {
+ for (SCTAB i=0; i<nCount; i++)
+ rMark.SelectTable( i, TRUE );
+
+ // Markierungen werden per Default nicht pro Tabelle gehalten
+// pDoc->ExtendMarksFromTable( nTab );
+
+ aViewData.GetDocShell()->PostPaintExtras();
+ SfxBindings& rBind = aViewData.GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+ }
+}
+
+void ScTabView::DeselectAllTables()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+ SCTAB nCount = pDoc->GetTableCount();
+
+ for (SCTAB i=0; i<nCount; i++)
+ rMark.SelectTable( i, ( i == nTab ) );
+
+ aViewData.GetDocShell()->PostPaintExtras();
+ SfxBindings& rBind = aViewData.GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+}
+
+BOOL lcl_FitsInWindow( double fScaleX, double fScaleY, USHORT nZoom,
+ long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ SCCOL nFixPosX, SCROW nFixPosY )
+{
+ double fZoomFactor = (double)Fraction(nZoom,100);
+ fScaleX *= fZoomFactor;
+ fScaleY *= fZoomFactor;
+
+ long nBlockX = 0;
+ SCCOL nCol;
+ for (nCol=0; nCol<nFixPosX; nCol++)
+ {
+ // for frozen panes, add both parts
+ USHORT nColTwips = pDoc->GetColWidth( nCol, nTab );
+ if (nColTwips)
+ {
+ nBlockX += (long)(nColTwips * fScaleX);
+ if (nBlockX > nWindowX)
+ return FALSE;
+ }
+ }
+ for (nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ USHORT nColTwips = pDoc->GetColWidth( nCol, nTab );
+ if (nColTwips)
+ {
+ nBlockX += (long)(nColTwips * fScaleX);
+ if (nBlockX > nWindowX)
+ return FALSE;
+ }
+ }
+
+ long nBlockY = 0;
+ for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
+ {
+ if (pDoc->RowHidden(nRow, nTab))
+ continue;
+
+ // for frozen panes, add both parts
+ USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab);
+ if (nRowTwips)
+ {
+ nBlockY += (long)(nRowTwips * fScaleY);
+ if (nBlockY > nWindowY)
+ return FALSE;
+ }
+ }
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab);
+ if (nRowTwips)
+ {
+ nBlockY += (long)(nRowTwips * fScaleY);
+ if (nBlockY > nWindowY)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+USHORT ScTabView::CalcZoom( SvxZoomType eType, USHORT nOldZoom )
+{
+ USHORT nZoom = 0; // Ergebnis
+
+ switch ( eType )
+ {
+ case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
+ nZoom = nOldZoom;
+ break;
+
+ case SVX_ZOOM_OPTIMAL: // nZoom entspricht der optimalen Gr"o\se
+ {
+ ScMarkData& rMark = aViewData.GetMarkData();
+ ScDocument* pDoc = aViewData.GetDocument();
+
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ nZoom = 100; // nothing selected
+ else
+ {
+ SCTAB nTab = aViewData.GetTabNo();
+ ScRange aMarkRange;
+ if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
+ rMark.GetMultiMarkArea( aMarkRange );
+
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+
+ if ( nTab < nStartTab && nTab > nEndTab )
+ nTab = nStartTab;
+
+ ScSplitPos eUsedPart = aViewData.GetActivePart();
+
+ SCCOL nFixPosX = 0;
+ SCROW nFixPosY = 0;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ {
+ // use right part
+ eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
+ nFixPosX = aViewData.GetFixPosX();
+ if ( nStartCol < nFixPosX )
+ nStartCol = nFixPosX;
+ }
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ {
+ // use bottom part
+ eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+ nFixPosY = aViewData.GetFixPosY();
+ if ( nStartRow < nFixPosY )
+ nStartRow = nFixPosY;
+ }
+
+ if (pGridWin[eUsedPart])
+ {
+ // Because scale is rounded to pixels, the only reliable way to find
+ // the right scale is to check if a zoom fits
+
+ Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
+
+ // for frozen panes, use sum of both parts for calculation
+
+ if ( nFixPosX != 0 )
+ aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
+ if ( nFixPosY != 0 )
+ aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
+
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ USHORT nMin = MINZOOM;
+ USHORT nMax = MAXZOOM;
+ while ( nMax > nMin )
+ {
+ USHORT nTest = (nMin+nMax+1)/2;
+ if ( lcl_FitsInWindow(
+ nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
+ pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
+ nFixPosX, nFixPosY ) )
+ nMin = nTest;
+ else
+ nMax = nTest-1;
+ }
+ DBG_ASSERT( nMin == nMax, "Schachtelung ist falsch" );
+ nZoom = nMin;
+
+ if ( nZoom != nOldZoom )
+ {
+ // scroll to block only in active split part
+ // (the part for which the size was calculated)
+
+ if ( nStartCol <= nEndCol )
+ aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
+ if ( nStartRow <= nEndRow )
+ aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
+ }
+ }
+ }
+ }
+ break;
+
+ case SVX_ZOOM_WHOLEPAGE: // nZoom entspricht der ganzen Seite oder
+ case SVX_ZOOM_PAGEWIDTH: // nZoom entspricht der Seitenbreite
+ {
+ SCTAB nCurTab = aViewData.GetTabNo();
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet =
+ pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
+
+ if ( pStyleSheet )
+ {
+ ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
+ aViewData.GetViewShell()->GetPrinter(TRUE),
+ nCurTab );
+
+ Size aPageSize = aPrintFunc.GetDataSize();
+
+ // use the size of the largest GridWin for normal split,
+ // or both combined for frozen panes, with the (document) size
+ // of the frozen part added to the page size
+ // (with frozen panes, the size of the individual parts
+ // depends on the scale that is to be calculated)
+
+ if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
+ Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
+ ScSplitMode eHMode = aViewData.GetHSplitMode();
+ if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
+ {
+ long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
+ GetOutputSizePixel().Width();
+ if ( eHMode == SC_SPLIT_FIX )
+ {
+ aWinSize.Width() += nOtherWidth;
+ for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
+ nCol < aViewData.GetFixPosX(); nCol++ )
+ aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
+ }
+ else if ( nOtherWidth > aWinSize.Width() )
+ aWinSize.Width() = nOtherWidth;
+ }
+ ScSplitMode eVMode = aViewData.GetVSplitMode();
+ if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
+ {
+ long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
+ GetOutputSizePixel().Height();
+ if ( eVMode == SC_SPLIT_FIX )
+ {
+ aWinSize.Height() += nOtherHeight;
+ aPageSize.Height() += pDoc->GetRowHeight(
+ aViewData.GetPosY(SC_SPLIT_TOP),
+ aViewData.GetFixPosY()-1, nCurTab);
+ }
+ else if ( nOtherHeight > aWinSize.Height() )
+ aWinSize.Height() = nOtherHeight;
+ }
+
+ double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ long nZoomX = (long) ( aWinSize.Width() * 100 /
+ ( aPageSize.Width() * nPPTX ) );
+ long nZoomY = (long) ( aWinSize.Height() * 100 /
+ ( aPageSize.Height() * nPPTY ) );
+ long nNew = nZoomX;
+
+ if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
+ nNew = nZoomY;
+
+ nZoom = (USHORT) nNew;
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR("Unknown Zoom-Revision");
+ nZoom = 0;
+ }
+
+ return nZoom;
+}
+
+// wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
+
+void ScTabView::StopMarking()
+{
+ ScSplitPos eActive = aViewData.GetActivePart();
+ if (pGridWin[eActive])
+ pGridWin[eActive]->StopMarking();
+
+ ScHSplitPos eH = WhichH(eActive);
+ if (pColBar[eH])
+ pColBar[eH]->StopMarking();
+
+ ScVSplitPos eV = WhichV(eActive);
+ if (pRowBar[eV])
+ pRowBar[eV]->StopMarking();
+}
+
+void ScTabView::HideNoteMarker()
+{
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ pGridWin[i]->HideNoteMarker();
+}
+
+void ScTabView::MakeDrawLayer()
+{
+ if (!pDrawView)
+ {
+ aViewData.GetDocShell()->MakeDrawLayer();
+
+ // pDrawView wird per Notify gesetzt
+ DBG_ASSERT(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
+
+ // #114409#
+ for(sal_uInt16 a(0); a < 4; a++)
+ {
+ if(pGridWin[a])
+ {
+ pGridWin[a]->DrawLayerCreated();
+ }
+ }
+ }
+}
+
+void ScTabView::ErrorMessage( USHORT nGlobStrId )
+{
+ if ( SC_MOD()->IsInExecuteDrop() )
+ {
+ // #i28468# don't show error message when called from Drag&Drop, silently abort instead
+ return;
+ }
+
+ StopMarking(); // falls per Focus aus MouseButtonDown aufgerufen
+
+ Window* pParent = aViewData.GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ BOOL bFocus = pParent && pParent->HasFocus();
+
+ if(nGlobStrId==STR_PROTECTIONERR)
+ {
+ if(aViewData.GetDocShell()->IsReadOnly())
+ {
+ nGlobStrId=STR_READONLYERR;
+ }
+ }
+
+ InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
+ aBox.Execute();
+ if (bFocus)
+ pParent->GrabFocus();
+}
+
+Window* ScTabView::GetParentOrChild( USHORT nChildId )
+{
+ SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
+
+ if ( pViewFrm->HasChildWindow(nChildId) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+
+ return aViewData.GetDialogParent();
+}
+
+void ScTabView::UpdatePageBreakData( BOOL bForcePaint )
+{
+ ScPageBreakData* pNewData = NULL;
+
+ if (aViewData.IsPagebreakMode())
+ {
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ USHORT nCount = pDoc->GetPrintRangeCount(nTab);
+ if (!nCount)
+ nCount = 1;
+ pNewData = new ScPageBreakData(nCount);
+
+ ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
+ // ScPrintFunc fuellt im ctor die PageBreakData
+ if ( nCount > 1 )
+ {
+ aPrintFunc.ResetBreaks(nTab);
+ pNewData->AddPages();
+ }
+
+ // Druckbereiche veraendert?
+ if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) )
+ PaintGrid();
+ }
+
+ delete pPageBreakData;
+ pPageBreakData = pNewData;
+}
+
+
+
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
new file mode 100644
index 000000000000..90bfe0c24e5c
--- /dev/null
+++ b/sc/source/ui/view/tabview3.cxx
@@ -0,0 +1,2790 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <rangelst.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/brshitem.hxx>
+#include <editeng/editview.hxx>
+#include <svx/fmshell.hxx>
+#include <svx/svdoole2.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/cursor.hxx>
+
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "colrowba.hxx"
+#include "tabcont.hxx"
+#include "scmod.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "viewutil.hxx"
+#include "editutil.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "validat.hxx"
+#include "hintwin.hxx"
+#include "inputopt.hxx"
+#include "rfindlst.hxx"
+#include "hiranges.hxx"
+#include "viewuno.hxx"
+#include "chartarr.hxx"
+#include "anyrefdg.hxx"
+#include "dpobject.hxx"
+#include "patattr.hxx"
+#include "dociter.hxx"
+#include "seltrans.hxx"
+#include "fillinfo.hxx"
+#include "AccessibilityHints.hxx"
+#include "rangeutl.hxx"
+#include "client.hxx"
+#include "tabprotection.hxx"
+
+#include <com/sun/star/chart2/data/HighlightedRange.hpp>
+
+namespace
+{
+
+ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
+{
+ ScAddress aResult( rRange.aStart );
+
+ SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
+ SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
+ SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
+ if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
+ {
+ // row by row from first to last sheet
+ sal_Int32 nArea = nWidth * nHeight;
+ aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
+ aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
+ aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
+ if( !rRange.In( aResult ) )
+ aResult = rRange.aStart;
+ }
+
+ return ScRange( aResult );
+}
+
+} // anonymous namespace
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+//
+// --- Public-Funktionen
+//
+
+void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, BOOL bControl )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
+ --nPosX;
+ while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
+ --nPosY;
+
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+
+ if ( bRefMode )
+ {
+ DoneRefMode( FALSE );
+
+ if (bControl)
+ SC_MOD()->AddRefEntry();
+
+ InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
+ }
+ else
+ {
+ DoneBlockMode( bControl );
+ aViewData.ResetOldCursor();
+ SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
+ }
+}
+
+void ScTabView::UpdateAutoFillMark()
+{
+ // single selection or cursor
+ ScRange aMarkRange;
+ BOOL bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
+
+ USHORT i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
+
+ for (i=0; i<2; i++)
+ {
+ if (pColBar[i] && pColBar[i]->IsVisible())
+ pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
+ if (pRowBar[i] && pRowBar[i]->IsVisible())
+ pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
+ }
+
+ // selection transfer object is checked together with AutoFill marks,
+ // because it has the same requirement of a single continuous block.
+ CheckSelectionTransfer(); // update selection transfer object
+}
+
+void ScTabView::FakeButtonUp( ScSplitPos eWhich )
+{
+ if (pGridWin[eWhich])
+ pGridWin[eWhich]->FakeButtonUp();
+}
+
+void ScTabView::HideAllCursors()
+{
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ Cursor* pCur = pGridWin[i]->GetCursor();
+ if (pCur)
+ if (pCur->IsVisible())
+ pCur->Hide();
+ pGridWin[i]->HideCursor();
+ }
+}
+
+void ScTabView::ShowAllCursors()
+{
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ pGridWin[i]->ShowCursor();
+
+ // #114409#
+ pGridWin[i]->CursorChanged();
+ }
+}
+
+void ScTabView::HideCursor()
+{
+ pGridWin[aViewData.GetActivePart()]->HideCursor();
+}
+
+void ScTabView::ShowCursor()
+{
+ pGridWin[aViewData.GetActivePart()]->ShowCursor();
+
+ // #114409#
+ pGridWin[aViewData.GetActivePart()]->CursorChanged();
+}
+
+void ScTabView::InvalidateAttribs()
+{
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ rBindings.Invalidate( SID_STYLE_APPLY );
+ rBindings.Invalidate( SID_STYLE_FAMILY2 );
+ // StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
+
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+
+ rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
+
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+
+ rBindings.Invalidate( SID_ALIGNTOP );
+ rBindings.Invalidate( SID_ALIGNBOTTOM );
+ rBindings.Invalidate( SID_ALIGNCENTERVER );
+
+ rBindings.Invalidate( SID_BACKGROUND_COLOR );
+
+ rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
+ rBindings.Invalidate( SID_NUMBER_FORMAT );
+
+ rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
+ rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+ rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_TOP );
+ rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
+
+// rBindings.Invalidate( SID_RANGE_VALUE );
+// rBindings.Invalidate( SID_RANGE_FORMULA );
+}
+
+// SetCursor - Cursor setzen, zeichnen, InputWin updaten
+// oder Referenz verschicken
+// ohne Optimierung wegen BugId 29307
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, BOOL bNew )
+{
+ SCCOL nOldX = aViewData.GetCurX();
+ SCROW nOldY = aViewData.GetCurY();
+
+ // DeactivateIP nur noch bei MarkListHasChanged
+
+ if ( nPosX != nOldX || nPosY != nOldY || bNew )
+ {
+ ScTabViewShell* pViewShell = aViewData.GetViewShell();
+ bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
+ if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
+ {
+ UpdateInputLine();
+ }
+
+ HideAllCursors();
+
+ aViewData.SetCurX( nPosX );
+ aViewData.SetCurY( nPosY );
+
+ ShowAllCursors();
+
+ CursorPosChanged();
+ }
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+void ScTabView::CheckSelectionTransfer()
+{
+ if ( aViewData.IsActive() ) // only for active view
+ {
+ ScModule* pScMod = SC_MOD();
+ ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
+ if ( pOld && pOld->GetView() == this && pOld->StillValid() )
+ {
+ // selection not changed - nothing to do
+ }
+ else
+ {
+ ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
+ if ( pNew )
+ {
+ // create new selection
+
+ if (pOld)
+ pOld->ForgetView();
+
+ uno::Reference<datatransfer::XTransferable> xRef( pNew );
+ pScMod->SetSelectionTransfer( pNew );
+ pNew->CopyToSelection( GetActiveWin() ); // may delete pOld
+ }
+ else if ( pOld && pOld->GetView() == this )
+ {
+ // remove own selection
+
+ pOld->ForgetView();
+ pScMod->SetSelectionTransfer( NULL );
+ TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
+ }
+ // else: selection from outside: leave unchanged
+ }
+ }
+}
+
+// Eingabezeile / Menues updaten
+// CursorPosChanged ruft SelectionChanged
+// SelectionChanged ruft CellContentChanged
+
+void ScTabView::CellContentChanged()
+{
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ rBindings.Invalidate( SID_ATTR_SIZE ); // -> Fehlermeldungen anzeigen
+ rBindings.Invalidate( SID_THESAURUS );
+ rBindings.Invalidate( SID_HYPERLINK_GETLINK );
+
+ InvalidateAttribs(); // Attribut-Updates
+ TestHintWindow(); // Eingabemeldung (Gueltigkeit)
+
+ aViewData.GetViewShell()->UpdateInputHandler();
+}
+
+void ScTabView::SelectionChanged()
+{
+ SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->SelectionChanged();
+ }
+ }
+
+ UpdateAutoFillMark(); // also calls CheckSelectionTransfer
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ rBindings.Invalidate( SID_CURRENTCELL ); // -> Navigator
+ rBindings.Invalidate( SID_AUTO_FILTER ); // -> Menue
+ rBindings.Invalidate( FID_NOTE_VISIBLE );
+ rBindings.Invalidate( SID_DELETE_NOTE );
+
+ // Funktionen, die evtl disabled werden muessen
+
+ rBindings.Invalidate( FID_INS_ROWBRK );
+ rBindings.Invalidate( FID_INS_COLBRK );
+ rBindings.Invalidate( FID_DEL_ROWBRK );
+ rBindings.Invalidate( FID_DEL_COLBRK );
+ rBindings.Invalidate( FID_MERGE_ON );
+ rBindings.Invalidate( FID_MERGE_OFF );
+ rBindings.Invalidate( FID_MERGE_TOGGLE );
+ rBindings.Invalidate( SID_AUTOFILTER_HIDE );
+ rBindings.Invalidate( SID_UNFILTER );
+// rBindings.Invalidate( SID_IMPORT_DATA ); // jetzt wieder immer moeglich
+ rBindings.Invalidate( SID_REIMPORT_DATA );
+ rBindings.Invalidate( SID_REFRESH_DBAREA );
+ rBindings.Invalidate( SID_OUTLINE_SHOW );
+ rBindings.Invalidate( SID_OUTLINE_HIDE );
+ rBindings.Invalidate( SID_OUTLINE_REMOVE );
+ rBindings.Invalidate( FID_FILL_TO_BOTTOM );
+ rBindings.Invalidate( FID_FILL_TO_RIGHT );
+ rBindings.Invalidate( FID_FILL_TO_TOP );
+ rBindings.Invalidate( FID_FILL_TO_LEFT );
+ rBindings.Invalidate( FID_FILL_SERIES );
+ rBindings.Invalidate( SID_SCENARIOS );
+ rBindings.Invalidate( SID_AUTOFORMAT );
+ rBindings.Invalidate( SID_OPENDLG_TABOP );
+ rBindings.Invalidate( SID_DATA_SELECT );
+
+ rBindings.Invalidate( SID_CUT );
+ rBindings.Invalidate( SID_COPY );
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+
+ rBindings.Invalidate( FID_INS_ROW );
+ rBindings.Invalidate( FID_INS_COLUMN );
+ rBindings.Invalidate( FID_INS_CELL );
+ rBindings.Invalidate( FID_INS_CELLSDOWN );
+ rBindings.Invalidate( FID_INS_CELLSRIGHT );
+
+ rBindings.Invalidate( FID_CHG_COMMENT );
+
+ // nur wegen Zellschutz:
+
+ rBindings.Invalidate( SID_CELL_FORMAT_RESET );
+ rBindings.Invalidate( SID_DELETE );
+ rBindings.Invalidate( SID_DELETE_CONTENTS );
+ rBindings.Invalidate( FID_DELETE_CELL );
+ rBindings.Invalidate( FID_CELL_FORMAT );
+ rBindings.Invalidate( SID_ENABLE_HYPHENATION );
+ rBindings.Invalidate( SID_INSERT_POSTIT );
+ rBindings.Invalidate( SID_CHARMAP );
+ rBindings.Invalidate( SID_OPENDLG_FUNCTION );
+// rBindings.Invalidate( FID_CONDITIONAL_FORMAT );
+ rBindings.Invalidate( SID_OPENDLG_CONDFRMT );
+ rBindings.Invalidate( FID_VALIDATION );
+ rBindings.Invalidate( SID_EXTERNAL_SOURCE );
+ rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
+ rBindings.Invalidate( SID_SORT_ASCENDING );
+ rBindings.Invalidate( SID_SORT_DESCENDING );
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_CURSORCHANGED));
+
+ CellContentChanged();
+}
+
+void ScTabView::CursorPosChanged()
+{
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
+ aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
+
+ // Broadcast, damit andere Views des Dokuments auch umschalten
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ bool bDP = NULL != pDoc->GetDPAtCursor(
+ aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
+ aViewData.GetViewShell()->SetPivotShell(bDP);
+
+ // UpdateInputHandler jetzt in CellContentChanged
+
+ SelectionChanged();
+
+ aViewData.SetTabStartCol( SC_TABSTART_NONE );
+}
+
+void ScTabView::TestHintWindow()
+{
+ // show input help window and list drop-down button for validity
+
+ BOOL bListValButton = FALSE;
+ ScAddress aListValPos;
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ const SfxUInt32Item* pItem = (const SfxUInt32Item*)
+ pDoc->GetAttr( aViewData.GetCurX(),
+ aViewData.GetCurY(),
+ aViewData.GetTabNo(),
+ ATTR_VALIDDATA );
+ if ( pItem->GetValue() )
+ {
+ const ScValidationData* pData = pDoc->GetValidationEntry( pItem->GetValue() );
+ DBG_ASSERT(pData,"ValidationData nicht gefunden");
+ String aTitle, aMessage;
+ if ( pData && pData->GetInput( aTitle, aMessage ) && aMessage.Len() > 0 )
+ {
+ //! Abfrage, ob an gleicher Stelle !!!!
+
+ DELETEZ(pInputHintWindow);
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ Window* pWin = pGridWin[eWhich];
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+ Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
+ Size aWinSize = pWin->GetOutputSizePixel();
+ // Cursor sichtbar?
+ if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
+ nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
+ aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
+ {
+ aPos += pWin->GetPosPixel(); // Position auf Frame
+ long nSizeXPix;
+ long nSizeYPix;
+ aViewData.GetMergeSizePixel( nCol, nRow, nSizeXPix, nSizeYPix );
+
+ // HintWindow anlegen, bestimmt seine Groesse selbst
+ pInputHintWindow = new ScHintWindow( pFrameWin, aTitle, aMessage );
+ Size aHintSize = pInputHintWindow->GetSizePixel();
+ Size aFrameWinSize = pFrameWin->GetOutputSizePixel();
+
+ // passende Position finden
+ // erster Versuch: unter dem Cursor
+ Point aHintPos( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
+ if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
+ {
+ // zweiter Versuch: rechts vom Cursor
+ aHintPos = Point( aPos.X() + nSizeXPix + 3, aPos.Y() + nSizeYPix / 2 );
+ if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
+ {
+ // dritter Versuch: ueber dem Cursor
+ aHintPos = Point( aPos.X() + nSizeXPix / 2,
+ aPos.Y() - aHintSize.Height() - 3 );
+ if ( aHintPos.Y() < 0 )
+ {
+ // oben und unten kein Platz - dann Default und abschneiden
+ aHintPos = Point( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
+ aHintSize.Height() = aFrameWinSize.Height() - aHintPos.Y();
+ pInputHintWindow->SetSizePixel( aHintSize );
+ }
+ }
+ }
+
+ // X anpassen
+ if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
+ aHintPos.X() = aFrameWinSize.Width() - aHintSize.Width();
+ // Y anpassen
+ if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
+ aHintPos.Y() = aFrameWinSize.Height() - aHintSize.Height();
+
+ pInputHintWindow->SetPosPixel( aHintPos );
+ pInputHintWindow->ToTop();
+ pInputHintWindow->Show();
+ }
+ }
+ else
+ DELETEZ(pInputHintWindow);
+
+ // list drop-down button
+ if ( pData && pData->HasSelectionList() )
+ {
+ aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
+ bListValButton = TRUE;
+ }
+ }
+ else
+ DELETEZ(pInputHintWindow);
+
+ for ( USHORT i=0; i<4; i++ )
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
+}
+
+void ScTabView::RemoveHintWindow()
+{
+ DELETEZ(pInputHintWindow);
+}
+
+
+// find window that should not be over the cursor
+Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
+{
+ //! auch Spelling ??? (dann beim Aufruf Membervariable setzen)
+
+ // Suchen & Ersetzen
+ if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+
+ // Aenderungen uebernehmen
+ if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+
+ return NULL;
+}
+
+ //
+ // Bildschirm an Cursorposition anpassen
+ //
+
+void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
+ const ScSplitPos* pWhich )
+{
+ //
+ // aktiven Teil umschalten jetzt hier
+ //
+
+ ScSplitPos eActive = aViewData.GetActivePart();
+ ScHSplitPos eActiveX = WhichH(eActive);
+ ScVSplitPos eActiveY = WhichV(eActive);
+ BOOL bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
+ BOOL bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
+ if (bHFix)
+ if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
+ {
+ ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
+ eActiveX = SC_SPLIT_RIGHT;
+ }
+ if (bVFix)
+ if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
+ {
+ ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
+ eActiveY = SC_SPLIT_BOTTOM;
+ }
+
+ //
+ // eigentliches Align
+ //
+
+ if ( eMode != SC_FOLLOW_NONE )
+ {
+ ScSplitPos eAlign;
+ if (pWhich)
+ eAlign = *pWhich;
+ else
+ eAlign = aViewData.GetActivePart();
+ ScHSplitPos eAlignX = WhichH(eAlign);
+ ScVSplitPos eAlignY = WhichV(eAlign);
+
+ SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
+ SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
+ SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
+ SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);
+
+ long nCellSizeX;
+ long nCellSizeY;
+ if ( nCurX >= 0 && nCurY >= 0 )
+ aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
+ else
+ nCellSizeX = nCellSizeY = 0;
+ Size aScrSize = aViewData.GetScrSize();
+ long nSpaceX = ( aScrSize.Width() - nCellSizeX ) / 2;
+ long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
+ // nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
+
+ BOOL bForceNew = FALSE; // force new calculation of JUMP position (vertical only)
+
+ // VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
+
+ //-------------------------------------------------------------------------------
+ // falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
+ // wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
+
+ //! nicht, wenn schon komplett sichtbar
+
+ if ( eMode == SC_FOLLOW_JUMP )
+ {
+ Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
+ if (pCare)
+ {
+ BOOL bLimit = FALSE;
+ Rectangle aDlgPixel;
+ Size aWinSize;
+ Window* pWin = GetActiveWin();
+ if (pWin)
+ {
+ aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
+ aWinSize = pWin->GetOutputSizePixel();
+ // ueberdeckt der Dialog das GridWin?
+ if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
+ {
+ if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
+ nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
+ bLimit = TRUE; // es wird sowieso gescrollt
+ else
+ {
+ // Cursor ist auf dem Bildschirm
+ Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
+ long nCSX, nCSY;
+ aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
+ Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
+ if ( aCursor.IsOver( aDlgPixel ) )
+ bLimit = TRUE; // Zelle vom Dialog ueberdeckt
+ }
+ }
+ }
+
+ if (bLimit)
+ {
+ BOOL bBottom = FALSE;
+ long nTopSpace = aDlgPixel.Top();
+ long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
+ if ( nBotSpace > 0 && nBotSpace > nTopSpace )
+ {
+ long nDlgBot = aDlgPixel.Bottom();
+ SCsCOL nWPosX;
+ SCsROW nWPosY;
+ aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
+ ++nWPosY; // unter der letzten betroffenen Zelle
+
+ SCsROW nDiff = nWPosY - nDeltaY;
+ if ( nCurY >= nDiff ) // Pos. kann nicht negativ werden
+ {
+ nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
+ bBottom = TRUE;
+ bForceNew = TRUE;
+ }
+ }
+ if ( !bBottom && nTopSpace > 0 )
+ {
+ nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
+ bForceNew = TRUE;
+ }
+ }
+ }
+ }
+ //-------------------------------------------------------------------------------
+
+ SCsCOL nNewDeltaX = nDeltaX;
+ SCsROW nNewDeltaY = nDeltaY;
+ BOOL bDoLine = FALSE;
+
+ switch (eMode)
+ {
+ case SC_FOLLOW_JUMP:
+ if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
+ {
+ nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<USHORT>(nSpaceX) ));
+ if (nNewDeltaX < 0) nNewDeltaX = 0;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
+ {
+ nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<USHORT>(nSpaceY) ));
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+ bDoLine = TRUE;
+ break;
+
+ case SC_FOLLOW_LINE:
+ bDoLine = TRUE;
+ break;
+
+ case SC_FOLLOW_FIX:
+ if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
+ {
+ nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
+ {
+ nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+
+ // like old version of SC_FOLLOW_JUMP:
+
+ if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
+ {
+ nNewDeltaX = nCurX - (nSizeX / 2);
+ if (nNewDeltaX < 0) nNewDeltaY = 0;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
+ {
+ nNewDeltaY = nCurY - (nSizeY / 2);
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+
+ bDoLine = TRUE;
+ break;
+
+ case SC_FOLLOW_NONE:
+ break;
+ default:
+ DBG_ERROR("Falscher Cursormodus");
+ break;
+ }
+
+ if (bDoLine)
+ {
+ while ( nCurX >= nNewDeltaX+nSizeX )
+ {
+ nNewDeltaX = nCurX-nSizeX+1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
+ ++nNewDeltaX;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ while ( nCurY >= nNewDeltaY+nSizeY )
+ {
+ nNewDeltaY = nCurY-nSizeY+1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
+ ++nNewDeltaY;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+ if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
+ if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
+ }
+
+ if ( nNewDeltaX != nDeltaX )
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
+ if (nNewDeltaX < 0) nNewDeltaX = 0;
+
+ if ( nNewDeltaY != nDeltaY )
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+
+ if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
+ if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
+ }
+
+ //
+ // nochmal aktiven Teil umschalten
+ //
+
+ if (bHFix)
+ if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
+ {
+ ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
+ eActiveX = SC_SPLIT_LEFT;
+ }
+ if (bVFix)
+ if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
+ {
+ ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
+ eActiveY = SC_SPLIT_TOP;
+ }
+}
+
+BOOL ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
+{
+ BOOL bRet = FALSE;
+
+ // #i3875# *Hack*
+ BOOL bMod1Locked = aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1 ? TRUE : FALSE;
+ aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
+
+ if ( pSelEngine )
+ {
+ bMoveIsShift = rMEvt.IsShift();
+ bRet = pSelEngine->SelMouseButtonDown( rMEvt );
+ bMoveIsShift = FALSE;
+ }
+
+ aViewData.SetSelCtrlMouseClick( FALSE ); // #i3875# *Hack*
+
+ return bRet;
+}
+
+ //
+ // MoveCursor - mit Anpassung des Bildausschnitts
+ //
+
+void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
+ BOOL bShift, BOOL bControl, BOOL bKeepOld, BOOL bKeepSel )
+{
+ if (!bKeepOld)
+ aViewData.ResetOldCursor();
+
+ if (nCurX < 0) nCurX = 0;
+ if (nCurY < 0) nCurY = 0;
+ if (nCurX > MAXCOL) nCurX = MAXCOL;
+ if (nCurY > MAXROW) nCurY = MAXROW;
+
+ HideAllCursors();
+
+ if ( bShift && bNewStartIfMarking && IsBlockMode() )
+ {
+ // used for ADD selection mode: start a new block from the cursor position
+ DoneBlockMode( TRUE );
+ InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), TRUE );
+ }
+
+ // aktiven Teil umschalten jetzt in AlignToCursor
+
+ AlignToCursor( nCurX, nCurY, eMode );
+ //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
+
+ if (bKeepSel)
+ SetCursor( nCurX, nCurY ); // Markierung stehenlassen
+ else
+ {
+ BOOL bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
+ bMoveIsShift = bShift;
+ pSelEngine->CursorPosChanging( bShift, bControl );
+ bMoveIsShift = FALSE;
+ aFunctionSet.SetCursorAtCell( nCurX, nCurY, FALSE );
+
+ // Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
+ // Aufheben der Selektion hier einzeln passieren:
+ if (bSame)
+ SelectionChanged();
+ }
+
+ ShowAllCursors();
+}
+
+void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+ BOOL bShift, BOOL bKeepSel )
+{
+ 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;
+ SCsROW nCurY;
+ if ( aViewData.IsRefMode() )
+ {
+ nOldX = (SCsCOL) aViewData.GetRefEndX();
+ nOldY = (SCsROW) aViewData.GetRefEndY();
+ nCurX = nOldX + nMovX;
+ nCurY = nOldY + nMovY;
+ }
+ else
+ {
+ nOldX = (SCsCOL) aViewData.GetCurX();
+ nOldY = (SCsROW) aViewData.GetCurY();
+ nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
+ nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
+ }
+
+ BOOL bSkipCell = FALSE;
+ aViewData.ResetOldCursor();
+
+ if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
+ {
+ BOOL bHFlip = FALSE;
+ do
+ {
+ SCCOL nLastCol = -1;
+ bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || 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;
+ bSkipCell = FALSE;
+ }
+ else
+ {
+ nMovX = -nMovX;
+ if (nMovX > 0) ++nCurX; else --nCurX; // zuruecknehmen
+ bHFlip = TRUE;
+ }
+ }
+ else
+ if (nMovX > 0) ++nCurX; else --nCurX;
+ }
+ }
+ while (bSkipCell);
+
+ if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
+ {
+ aViewData.SetOldCursor( nCurX,nCurY );
+ while (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
+ --nCurY;
+ }
+ }
+
+ if (nMovY != 0 && VALIDCOLROW(nCurX,nCurY))
+ {
+ BOOL bVFlip = FALSE;
+ do
+ {
+ SCROW nLastRow = -1;
+ bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || 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;
+ bSkipCell = FALSE;
+ }
+ else
+ {
+ nMovY = -nMovY;
+ if (nMovY > 0) ++nCurY; else --nCurY; // zuruecknehmen
+ bVFlip = TRUE;
+ }
+ }
+ else
+ if (nMovY > 0) ++nCurY; else --nCurY;
+ }
+ }
+ while (bSkipCell);
+
+ if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
+ {
+ aViewData.SetOldCursor( nCurX,nCurY );
+ while (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
+ --nCurX;
+ }
+ }
+
+ MoveCursorAbs( nCurX, nCurY, eMode, bShift, FALSE, TRUE, bKeepSel );
+}
+
+void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
+{
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ ScHSplitPos eWhichX = WhichH( eWhich );
+ ScVSplitPos eWhichY = WhichV( eWhich );
+
+ SCsCOL nPageX;
+ SCsROW nPageY;
+ if (nMovX >= 0)
+ nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
+ else
+ nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
+
+ if (nMovY >= 0)
+ nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
+ else
+ nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
+
+ if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
+ if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
+
+ MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
+}
+
+void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
+{
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ // FindAreaPos kennt nur -1 oder 1 als Richtung
+
+ SCsCOLROW i;
+ if ( nMovX > 0 )
+ for ( i=0; i<nMovX; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
+ if ( nMovX < 0 )
+ for ( i=0; i<-nMovX; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
+ if ( nMovY > 0 )
+ for ( i=0; i<nMovY; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
+ if ( nMovY < 0 )
+ for ( i=0; i<-nMovY; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
+
+ if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
+ {
+ if (nMovX != 0 && nNewX == MAXCOL)
+ eMode = SC_FOLLOW_LINE;
+ if (nMovY != 0 && nNewY == MAXROW)
+ eMode = SC_FOLLOW_LINE;
+ }
+
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
+}
+
+void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+
+ SCCOL nUsedX = 0;
+ SCROW nUsedY = 0;
+ if ( nMovX > 0 || nMovY > 0 )
+ pDoc->GetPrintArea( nTab, nUsedX, nUsedY ); // Ende holen
+
+ if (nMovX<0)
+ nNewX=0;
+ else if (nMovX>0)
+ nNewX=nUsedX; // letzter benutzter Bereich
+
+ if (nMovY<0)
+ nNewY=0;
+ else if (nMovY>0)
+ nNewY=nUsedY;
+
+ aViewData.ResetOldCursor();
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
+}
+
+void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
+ SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
+
+ SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
+ if (nAddX != 0)
+ --nAddX;
+ SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
+ if (nAddY != 0)
+ --nAddY;
+
+ if (nMovX<0)
+ nNewX=nPosX;
+ else if (nMovX>0)
+ nNewX=nPosX+nAddX;
+
+ if (nMovY<0)
+ nNewY=nPosY;
+ else if (nMovY>0)
+ nNewY=nPosY+nAddY;
+
+// aViewData.ResetOldCursor();
+ aViewData.SetOldCursor( nNewX,nNewY );
+
+ while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
+ --nNewX;
+ while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
+ --nNewY;
+
+ MoveCursorAbs( nNewX, nNewY, eMode, bShift, FALSE, TRUE );
+}
+
+void ScTabView::MoveCursorEnter( BOOL bShift ) // bShift -> hoch/runter
+{
+ const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
+ if (!rOpt.GetMoveSelection())
+ {
+ aViewData.UpdateInputHandler(TRUE);
+ return;
+ }
+
+ SCsCOL nMoveX = 0;
+ SCsROW nMoveY = 0;
+ switch ((ScDirection)rOpt.GetMoveDir())
+ {
+ case DIR_BOTTOM:
+ nMoveY = bShift ? -1 : 1;
+ break;
+ case DIR_RIGHT:
+ nMoveX = bShift ? -1 : 1;
+ break;
+ case DIR_TOP:
+ nMoveY = bShift ? 1 : -1;
+ break;
+ case DIR_LEFT:
+ nMoveX = bShift ? 1 : -1;
+ break;
+ }
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (rMark.IsMarked() || rMark.IsMultiMarked())
+ {
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+ SCTAB nTab = aViewData.GetTabNo();
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, TRUE,FALSE, rMark );
+
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
+ SC_FOLLOW_LINE, FALSE, TRUE );
+
+ // update input line even if cursor was not moved
+ if ( nNewX == nCurX && nNewY == nCurY )
+ aViewData.UpdateInputHandler(TRUE);
+ }
+ else
+ {
+ if ( nMoveY != 0 && !nMoveX )
+ {
+ // nach Tab und Enter wieder zur Ausgangsspalte
+ SCCOL nTabCol = aViewData.GetTabStartCol();
+ if (nTabCol != SC_TABSTART_NONE)
+ {
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
+ }
+ }
+
+ MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, FALSE );
+ }
+}
+
+
+BOOL ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
+{
+ const KeyCode& rKCode = rKeyEvent.GetKeyCode();
+
+ enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
+ rKCode.IsMod1() ?
+ (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
+ (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
+
+ BOOL bSel = rKCode.IsShift();
+ USHORT nCode = rKCode.GetCode();
+
+ // CURSOR keys
+ SCsCOL nDX = 0;
+ SCsROW nDY = 0;
+ switch( nCode )
+ {
+ case KEY_LEFT: nDX = -1; break;
+ case KEY_RIGHT: nDX = 1; break;
+ case KEY_UP: nDY = -1; break;
+ case KEY_DOWN: nDY = 1; break;
+ }
+ if( nDX != 0 || nDY != 0 )
+ {
+ switch( eModifier )
+ {
+ case MOD_NONE: MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel ); break;
+ case MOD_CTRL: MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ // always TRUE to suppress changes of col/row size (ALT+CURSOR)
+ return TRUE;
+ }
+
+ // PAGEUP/PAGEDOWN
+ if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
+ {
+ nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
+ switch( eModifier )
+ {
+ case MOD_NONE: MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel ); break;
+ case MOD_ALT: MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel ); break;
+ case MOD_CTRL: SelectNextTab( nDX ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return TRUE;
+ }
+
+ // HOME/END
+ if( (nCode == KEY_HOME) || (nCode == KEY_END) )
+ {
+ nDX = (nCode == KEY_HOME) ? -1 : 1;
+ ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
+ switch( eModifier )
+ {
+ case MOD_NONE: MoveCursorEnd( nDX, 0, eMode, bSel ); break;
+ case MOD_CTRL: MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+ // naechste/vorherige nicht geschuetzte Zelle
+void ScTabView::FindNextUnprot( BOOL bShift, BOOL bInSelection )
+{
+ short nMove = bShift ? -1 : 1;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ BOOL bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+ SCTAB nTab = aViewData.GetTabNo();
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked,TRUE, rMark );
+
+ SCCOL nTabCol = aViewData.GetTabStartCol();
+ if ( nTabCol == SC_TABSTART_NONE )
+ nTabCol = nCurX; // auf diese Spalte zurueck bei Enter
+
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
+ SC_FOLLOW_LINE, FALSE, TRUE );
+
+ // in MoveCursorRel wird die TabCol zurueckgesetzt...
+ aViewData.SetTabStartCol( nTabCol );
+}
+
+void ScTabView::MarkColumns()
+{
+ SCCOL nStartCol;
+ SCCOL nEndCol;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ nStartCol = aMarkRange.aStart.Col();
+ nEndCol = aMarkRange.aEnd.Col();
+ }
+ else
+ {
+ SCROW nDummy;
+ aViewData.GetMoveCursor( nStartCol, nDummy );
+ nEndCol=nStartCol;
+ }
+
+ SCTAB nTab = aViewData.GetTabNo();
+ DoneBlockMode();
+ InitBlockMode( nStartCol,0, nTab );
+ MarkCursor( nEndCol,MAXROW, nTab );
+ SelectionChanged();
+}
+
+void ScTabView::MarkRows()
+{
+ SCROW nStartRow;
+ SCROW nEndRow;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ nStartRow = aMarkRange.aStart.Row();
+ nEndRow = aMarkRange.aEnd.Row();
+ }
+ else
+ {
+ SCCOL nDummy;
+ aViewData.GetMoveCursor( nDummy, nStartRow );
+ nEndRow=nStartRow;
+ }
+
+ SCTAB nTab = aViewData.GetTabNo();
+ DoneBlockMode();
+ InitBlockMode( 0,nStartRow, nTab );
+ MarkCursor( MAXCOL,nEndRow, nTab );
+ SelectionChanged();
+}
+
+void ScTabView::MarkDataArea( BOOL bIncludeCursor )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ SCCOL nStartCol = aViewData.GetCurX();
+ SCROW nStartRow = aViewData.GetCurY();
+ SCCOL nEndCol = nStartCol;
+ SCROW nEndRow = nStartRow;
+
+ pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
+
+ HideAllCursors();
+ DoneBlockMode();
+ InitBlockMode( nStartCol, nStartRow, nTab );
+ MarkCursor( nEndCol, nEndRow, nTab );
+ ShowAllCursors();
+
+ SelectionChanged();
+}
+
+void ScTabView::MarkMatrixFormula()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
+ ScRange aMatrix;
+ if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
+ {
+ MarkRange( aMatrix, FALSE ); // cursor is already within the range
+ }
+}
+
+void ScTabView::MarkRange( const ScRange& rRange, BOOL bSetCursor, BOOL bContinue )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ SetTabNo( nTab );
+
+ HideAllCursors();
+ DoneBlockMode( bContinue ); // bContinue==TRUE -> clear old mark
+ if (bSetCursor) // Wenn Cursor gesetzt wird, immer auch alignen
+ {
+ SCCOL nAlignX = rRange.aStart.Col();
+ SCROW nAlignY = rRange.aStart.Row();
+ if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
+ nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
+ if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+ nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
+ AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
+ }
+ InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
+ MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
+ if (bSetCursor)
+ {
+ SCCOL nPosX = rRange.aStart.Col();
+ SCROW nPosY = rRange.aStart.Row();
+ ScDocument* pDoc = aViewData.GetDocument();
+
+ while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
+ --nPosX;
+ while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
+ --nPosY;
+
+ aViewData.ResetOldCursor();
+ SetCursor( nPosX, nPosY );
+ }
+ ShowAllCursors();
+
+ SelectionChanged();
+}
+
+void ScTabView::Unmark()
+{
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, FALSE, FALSE );
+
+ SelectionChanged();
+ }
+}
+
+void ScTabView::SetMarkData( const ScMarkData& rNew )
+{
+ DoneBlockMode();
+ InitOwnBlockMode();
+ aViewData.GetMarkData() = rNew;
+
+ MarkDataChanged();
+}
+
+void ScTabView::MarkDataChanged()
+{
+ // has to be called after making direct changes to mark data (not via MarkCursor etc)
+
+ UpdateSelectionOverlay();
+}
+
+void ScTabView::SelectNextTab( short nDir, BOOL bExtendSelection )
+{
+ if (!nDir) return;
+ DBG_ASSERT( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ if (nDir<0)
+ {
+ if (!nTab) return;
+ --nTab;
+ while (!pDoc->IsVisible(nTab))
+ {
+ if (!nTab) return;
+ --nTab;
+ }
+ }
+ else
+ {
+ SCTAB nCount = pDoc->GetTableCount();
+ ++nTab;
+ if (nTab >= nCount) return;
+ while (!pDoc->IsVisible(nTab))
+ {
+ ++nTab;
+ if (nTab >= nCount) return;
+ }
+ }
+
+ SetTabNo( nTab, FALSE, bExtendSelection );
+ PaintExtras();
+}
+
+
+// SetTabNo - angezeigte Tabelle
+
+void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection )
+{
+ if ( !ValidTab(nTab) )
+ {
+ DBG_ERROR("SetTabNo: falsche Tabelle");
+ return;
+ }
+
+ if ( nTab != aViewData.GetTabNo() || bNew )
+ {
+ // #57724# Die FormShell moechte vor dem Umschalten benachrichtigt werden
+ FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
+ if (pFormSh)
+ {
+ BOOL bAllowed = sal::static_int_cast<BOOL>( pFormSh->PrepareClose( TRUE ) );
+ if (!bAllowed)
+ {
+ //! Fehlermeldung? oder macht das die FormShell selber?
+ //! Fehler-Flag zurueckgeben und Aktionen abbrechen
+
+ return; // Die FormShell sagt, es kann nicht umgeschaltet werden
+ }
+ }
+
+ // nicht InputEnterHandler wegen Referenzeingabe !
+
+ 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
+ {
+ BOOL bUp = (nTab>=nOldPos);
+ if (bUp)
+ {
+ ++nTab;
+ if (nTab>=nTabCount)
+ {
+ nTab = nOldPos;
+ bUp = FALSE;
+ }
+ }
+
+ if (!bUp)
+ {
+ if (nTab != 0)
+ --nTab;
+ else
+ {
+ DBG_ERROR("keine sichtbare Tabelle");
+ pDoc->SetVisible( 0, TRUE );
+ }
+ }
+ }
+
+ // #i71490# Deselect drawing objects before changing the sheet number in view data,
+ // so the handling of notes still has the sheet selected on which the notes are.
+ DrawDeselectAll();
+
+ ScModule* pScMod = SC_MOD();
+ BOOL bRefMode = pScMod->IsFormulaMode();
+ if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
+ {
+ DoneBlockMode();
+ pSelEngine->Reset(); // reset all flags, including locked modifiers
+ aViewData.SetRefTabNo( nTab );
+ }
+
+ ScSplitPos eOldActive = aViewData.GetActivePart(); // before switching
+ BOOL bFocus = pGridWin[eOldActive]->HasFocus();
+
+ aViewData.SetTabNo( nTab );
+ // UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
+ // Fenster findet (wird aus SetCursor gerufen)
+ UpdateShow();
+ aViewData.ResetOldCursor();
+ SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), TRUE );
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+ ScMarkData& rMark = aViewData.GetMarkData();
+
+ bool bAllSelected = true;
+ for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
+ {
+ if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
+ {
+ if (nTab == nSelTab)
+ // This tab is already in selection. Keep the current
+ // selection.
+ bExtendSelection = true;
+ }
+ else
+ {
+ bAllSelected = false;
+ if (bExtendSelection)
+ // We got what we need. No need to stay in the loop.
+ break;
+ }
+ }
+ if (bAllSelected && !bNew)
+ // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
+ // (not if called with bNew to update settings)
+ bExtendSelection = false;
+
+ if (bExtendSelection)
+ rMark.SelectTable( nTab, TRUE );
+ else
+ {
+ rMark.SelectOneTable( nTab );
+ rBindings.Invalidate( FID_FILL_TAB );
+ rBindings.Invalidate( FID_TAB_DESELECTALL );
+ }
+
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
+ RefreshZoom();
+ UpdateVarZoom();
+
+ if ( bRefMode ) // hide EditView if necessary (after aViewData.SetTabNo !)
+ {
+ for ( USHORT i=0; i<4; i++ )
+ if ( pGridWin[i] )
+ if ( pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateEditViewPos();
+ }
+
+ TabChanged(); // DrawView
+
+ aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist
+ if ( !bUnoRefDialog )
+ aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames
+ else
+ {
+ // hide / show inplace client
+
+ ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ {
+ Rectangle aObjArea = pClient->GetObjArea();
+ if ( nTab == aViewData.GetRefTabNo() )
+ {
+ // move to its original position
+
+ SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
+ if ( pDrawObj )
+ {
+ Rectangle aRect = pDrawObj->GetLogicRect();
+ MapMode aMapMode( MAP_100TH_MM );
+ Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
+ aRect.SetSize( aOleSize );
+ aObjArea = aRect;
+ }
+ }
+ else
+ {
+ // move to an invisible position
+
+ aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
+ }
+ pClient->SetObjArea( aObjArea );
+ }
+ }
+
+ if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
+ ActiveGrabFocus(); // grab focus to the pane that's active now
+
+ // Fixierungen
+
+ BOOL bResize = FALSE;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixX())
+ bResize = TRUE;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixY())
+ bResize = TRUE;
+ if (bResize)
+ RepeatResize();
+ InvalidateSplit();
+
+ if ( aViewData.IsPagebreakMode() )
+ UpdatePageBreakData(); //! asynchron ??
+
+ // #53551# Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ PaintExtras();
+
+ DoResize( aBorderPos, aFrameSize );
+ rBindings.Invalidate( SID_DELETE_PRINTAREA ); // Menue
+ rBindings.Invalidate( FID_DEL_MANUALBREAKS );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE ); // Statusbar
+ rBindings.Invalidate( SID_CURRENTTAB ); // Navigator
+ rBindings.Invalidate( SID_STYLE_FAMILY2 ); // Gestalter
+ rBindings.Invalidate( SID_STYLE_FAMILY4 ); // Gestalter
+ rBindings.Invalidate( SID_TABLES_COUNT );
+
+ if(pScMod->IsRefDialogOpen())
+ {
+ USHORT nCurRefDlgId=pScMod->GetCurRefDlgId();
+ SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
+ SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ pRefDlg->ViewShellChanged(NULL);
+ }
+ }
+ }
+}
+
+//
+// Paint-Funktionen - nur fuer diese View
+//
+
+void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
+{
+ DrawDeselectAll();
+
+ if (pDrawView)
+ DrawEnableAnim( FALSE );
+
+ EditView* pSpellingView = aViewData.GetSpellingView();
+
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
+ {
+ ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
+ ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
+ SCCOL nScrX = aViewData.GetPosX( eHWhich );
+ SCROW nScrY = aViewData.GetPosY( eVWhich );
+
+ BOOL bPosVisible =
+ ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
+ nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
+
+ // #102421# for the active part, create edit view even if outside the visible area,
+ // so input isn't lost (and the edit view may be scrolled into the visible area)
+
+ // #i26433# during spelling, the spelling view must be active
+ if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
+ ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
+ {
+ pGridWin[i]->HideCursor();
+
+ pGridWin[i]->DeleteCursorOverlay();
+ pGridWin[i]->DeleteAutoFillOverlay();
+
+ // flush OverlayManager before changing MapMode to text edit
+ pGridWin[i]->flushOverlayManager();
+
+ // MapMode must be set after HideCursor
+ pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
+
+ aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
+
+ if ( !bPosVisible )
+ {
+ // move the edit view area to the real (possibly negative) position,
+ // or hide if completely above or left of the window
+ pGridWin[i]->UpdateEditViewPos();
+ }
+ }
+ }
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
+}
+
+void ScTabView::UpdateEditView()
+{
+ ScSplitPos eActive = aViewData.GetActivePart();
+ for (USHORT i=0; i<4; i++)
+ if (aViewData.HasEditView( (ScSplitPos) i ))
+ {
+ EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
+ aViewData.SetEditEngine( (ScSplitPos) i,
+ static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
+ pGridWin[i], GetViewData()->GetCurX(), GetViewData()->GetCurY() );
+ if ( (ScSplitPos)i == eActive )
+ pEditView->ShowCursor( FALSE );
+ }
+}
+
+void ScTabView::KillEditView( BOOL bNoPaint )
+{
+ USHORT i;
+ SCCOL nCol1 = aViewData.GetEditStartCol();
+ SCROW nRow1 = aViewData.GetEditStartRow();
+ SCCOL nCol2 = aViewData.GetEditEndCol();
+ SCROW nRow2 = aViewData.GetEditEndRow();
+ BOOL bPaint[4];
+ BOOL bNotifyAcc(false);
+
+ BOOL bExtended = nRow1 != nRow2; // Col wird sowieso bis zum Ende gezeichnet
+ BOOL bAtCursor = nCol1 <= aViewData.GetCurX() &&
+ nCol2 >= aViewData.GetCurX() &&
+ nRow1 == aViewData.GetCurY();
+ for (i=0; i<4; i++)
+ {
+ bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
+ if (bPaint[i])
+ bNotifyAcc = true;
+ }
+
+ // #108931#; notify accessibility before all things happen
+ if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
+
+ aViewData.ResetEditView();
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && bPaint[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ pGridWin[i]->ShowCursor();
+
+ pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
+
+ // #i73567# the cell still has to be repainted
+ if (bExtended || ( bAtCursor && !bNoPaint ))
+ {
+ pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
+ pGridWin[i]->UpdateSelectionOverlay();
+ }
+ }
+
+ if (pDrawView)
+ DrawEnableAnim( TRUE );
+
+ // GrabFocus immer dann, wenn diese View aktiv ist und
+ // die Eingabezeile den Focus hat
+
+ BOOL bGrabFocus = FALSE;
+ if (aViewData.IsActive())
+ {
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ {
+ ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
+ if (pInputWin && pInputWin->IsInputActive())
+ bGrabFocus = TRUE;
+ }
+ }
+
+ if (bGrabFocus)
+ {
+// So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
+//! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
+// deshalb erstmal so:
+ GetActiveWin()->GrabFocus();
+ }
+
+ // Cursor-Abfrage erst nach GrabFocus
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ {
+ Cursor* pCur = pGridWin[i]->GetCursor();
+ if (pCur && pCur->IsVisible())
+ pCur->Hide();
+
+ if(bPaint[i])
+ {
+ pGridWin[i]->UpdateCursorOverlay();
+ pGridWin[i]->UpdateAutoFillOverlay();
+ // pGridWin[i]->UpdateAllOverlays();
+ }
+ }
+}
+
+void ScTabView::UpdateFormulas()
+{
+ if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
+ return ;
+
+ USHORT i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ pGridWin[i]->UpdateFormulas();
+
+ if ( aViewData.IsPagebreakMode() )
+ UpdatePageBreakData(); //! asynchron
+
+ UpdateHeaderWidth();
+
+ // if in edit mode, adjust edit view area because widths/heights may have changed
+ if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
+ UpdateEditView();
+}
+
+// PaintArea -Block neu zeichnen
+
+void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ ScUpdateMode eMode )
+{
+ USHORT i;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCCOL nCol2;
+ SCROW nRow2;
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
+ ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
+ BOOL bOut = FALSE;
+
+ nCol1 = nStartCol;
+ nRow1 = nStartRow;
+ nCol2 = nEndCol;
+ nRow2 = nEndRow;
+
+ SCCOL nScrX = aViewData.GetPosX( eHWhich );
+ SCROW nScrY = aViewData.GetPosY( eVWhich );
+ if (nCol1 < nScrX) nCol1 = nScrX;
+ if (nCol2 < nScrX)
+ {
+ if ( eMode == SC_UPDATE_ALL ) // #91240# for UPDATE_ALL, paint anyway
+ nCol2 = nScrX; // (because of extending strings to the right)
+ else
+ bOut = TRUE; // completely outside the window
+ }
+ if (nRow1 < nScrY) nRow1 = nScrY;
+ if (nRow2 < nScrY) bOut = TRUE;
+
+ SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
+ SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
+ if (nCol1 > nLastX) bOut = TRUE;
+ if (nCol2 > nLastX) nCol2 = nLastX;
+ if (nRow1 > nLastY) bOut = TRUE;
+ if (nRow2 > nLastY) nRow2 = nLastY;
+
+ if (!bOut)
+ {
+ if ( eMode == SC_UPDATE_CHANGED )
+ pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
+ else // ALL oder MARKS
+ {
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
+ Point aEnd = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
+ if ( eMode == SC_UPDATE_ALL )
+ aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
+ aEnd.X() -= nLayoutSign;
+ aEnd.Y() -= 1;
+
+ // #i85232# include area below cells (could be done in GetScrPos?)
+ if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
+ aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
+
+ BOOL bShowChanges = TRUE; //! ...
+ if (bShowChanges)
+ {
+ aStart.X() -= nLayoutSign; // include change marks
+ aStart.Y() -= 1;
+ }
+
+ BOOL bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
+ if (bMarkClipped)
+ {
+ // dazu muesste ScColumn::IsEmptyBlock optimiert werden
+ // (auf Search() umstellen)
+ //!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
+ //! aViewData.GetTabNo(),
+ //! 0, nRow1, nCol1-1, nRow2 ) )
+ {
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
+ aStart.X() -= nMarkPixel * nLayoutSign;
+ if (!bShowChanges)
+ aStart.X() -= nLayoutSign; // cell grid
+ }
+ }
+
+ pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
+ }
+ }
+ }
+
+ // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
+ // with a wrong MapMode if editing in a cell (reference input).
+ // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
+ // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
+ // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
+ // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
+ // is set (width or height changed).
+}
+
+void ScTabView::PaintRangeFinder( long nNumber )
+{
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
+ if (pHdl)
+ {
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
+ {
+ SCTAB nTab = aViewData.GetTabNo();
+ USHORT nCount = (USHORT)pRangeFinder->Count();
+ for (USHORT i=0; i<nCount; i++)
+ if ( nNumber < 0 || nNumber == i )
+ {
+ ScRangeFindData* pData = pRangeFinder->GetObject(i);
+ if (pData)
+ {
+ ScRange aRef = pData->aRef;
+ aRef.Justify(); // Justify fuer die Abfragen unten
+
+ if ( aRef.aStart == aRef.aEnd ) //! Tab ignorieren?
+ aViewData.GetDocument()->ExtendMerge(aRef);
+
+ if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
+ {
+ SCCOL nCol1 = aRef.aStart.Col();
+ SCROW nRow1 = aRef.aStart.Row();
+ SCCOL nCol2 = aRef.aEnd.Col();
+ SCROW nRow2 = aRef.aEnd.Row();
+
+ // wegnehmen -> Repaint
+ // SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
+
+ BOOL bHiddenEdge = FALSE;
+ SCROW nTmp;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCCOL nLastCol = -1;
+ while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) )
+ {
+ --nCol1;
+ bHiddenEdge = TRUE;
+ }
+ while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) )
+ {
+ ++nCol2;
+ bHiddenEdge = TRUE;
+ }
+ nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
+ if (!ValidRow(nTmp))
+ nTmp = 0;
+ if (nTmp < nRow1)
+ {
+ nRow1 = nTmp;
+ bHiddenEdge = TRUE;
+ }
+ nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
+ if (!ValidRow(nTmp))
+ nTmp = MAXROW;
+ if (nTmp > nRow2)
+ {
+ nRow2 = nTmp;
+ bHiddenEdge = TRUE;
+ }
+
+ if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
+ {
+ // nur an den Raendern entlang
+ PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
+ PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
+ PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
+ PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
+ }
+ else // alles am Stueck
+ PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
+ }
+ }
+ }
+ }
+ }
+}
+
+// fuer Chart-Daten-Markierung
+
+void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
+{
+ if (!pHighlightRanges)
+ pHighlightRanges = new ScHighlightRanges;
+ pHighlightRanges->Insert( new ScHighlightEntry( rRange, rColor ) );
+
+ SCTAB nTab = aViewData.GetTabNo();
+ if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
+ PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
+}
+
+void ScTabView::ClearHighlightRanges()
+{
+ if (pHighlightRanges)
+ {
+ ScHighlightRanges* pTemp = pHighlightRanges;
+ pHighlightRanges = NULL; // Repaint ohne Highlight
+
+ SCTAB nTab = aViewData.GetTabNo();
+ ULONG nCount = pTemp->Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScHighlightEntry* pEntry = pTemp->GetObject( i );
+ if (pEntry)
+ {
+ ScRange aRange = pEntry->aRef;
+ if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
+ PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
+ }
+ }
+ delete pTemp;
+ }
+}
+
+void ScTabView::DoChartSelection(
+ const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
+{
+ ClearHighlightRanges();
+
+ for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
+ {
+ Color aSelColor( rHilightRanges[i].PreferredColor );
+ ScRangeList aRangeList;
+ ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
+ if( ScRangeStringConverter::GetRangeListFromString(
+ aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
+ {
+ for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
+ {
+ if( rHilightRanges[i].Index == - 1 )
+ AddHighlightRange( *p, aSelColor );
+ else
+ AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
+ }
+ }
+ }
+}
+
+// DrawDragRect - Drag&Drop-Rechteck zeichnen (XOR)
+
+//UNUSED2008-05 void ScTabView::DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
+//UNUSED2008-05 ScSplitPos ePos )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+//UNUSED2008-05 {
+//UNUSED2008-05 for (USHORT i=0; i<4; i++)
+//UNUSED2008-05 if (pGridWin[i])
+//UNUSED2008-05 if (pGridWin[i]->IsVisible())
+//UNUSED2008-05 pGridWin[i]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 pGridWin[ePos]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 // PaintCell - einzelne Zelle neu zeichnen
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aViewData.GetTabNo() == nTab )
+//UNUSED2008-05 {
+//UNUSED2008-05 USHORT i;
+//UNUSED2008-05 for (i=0; i<4; i++)
+//UNUSED2008-05 if (pGridWin[i])
+//UNUSED2008-05 if (pGridWin[i]->IsVisible())
+//UNUSED2008-05 pGridWin[i]->Draw( nCol, nRow, nCol, nRow );
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::PaintLeftRow( SCROW nRow )
+//UNUSED2008-05 {
+//UNUSED2008-05 PaintLeftArea( nRow, nRow );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::PaintTopCol( SCCOL nCol )
+//UNUSED2008-05 {
+//UNUSED2008-05 PaintTopArea( nCol, nCol );
+//UNUSED2008-05 }
+
+// PaintGrid - Datenbereiche neu zeichnen
+
+void ScTabView::PaintGrid()
+{
+ USHORT i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ pGridWin[i]->Invalidate();
+}
+
+// PaintTop - obere Kontrollelemente neu zeichnen
+
+void ScTabView::PaintTop()
+{
+ USHORT i;
+ for (i=0; i<2; i++)
+ {
+ if (pColBar[i])
+ pColBar[i]->Invalidate();
+ if (pColOutline[i])
+ pColOutline[i]->Invalidate();
+ }
+}
+
+void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
+{
+ UINT16 i;
+
+ for(i=0; i<4; i++)
+ {
+ if(pGridWin[i])
+ {
+ if(pGridWin[i]->IsVisible())
+ {
+ pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
+ }
+ }
+ }
+}
+
+void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
+{
+ // Pixel-Position der linken Kante
+
+ if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
+ nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
+ aViewData.RecalcPixPos();
+
+ // Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
+
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
+ if (aViewData.UpdateFixX())
+ RepeatResize();
+
+ // zeichnen
+
+ if (nStartCol>0)
+ --nStartCol; //! allgemeiner ?
+
+ BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ for (USHORT i=0; i<2; i++)
+ {
+ ScHSplitPos eWhich = (ScHSplitPos) i;
+ if (pColBar[eWhich])
+ {
+ Size aWinSize = pColBar[eWhich]->GetSizePixel();
+ long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
+ long nEndX;
+ if (nEndCol >= MAXCOL)
+ nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
+ else
+ nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
+ pColBar[eWhich]->Invalidate(
+ Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
+ }
+ if (pColOutline[eWhich])
+ pColOutline[eWhich]->Invalidate();
+ }
+}
+
+
+// PaintLeft - linke Kontrollelemente neu zeichnen
+
+void ScTabView::PaintLeft()
+{
+ USHORT i;
+ for (i=0; i<2; i++)
+ {
+ if (pRowBar[i])
+ pRowBar[i]->Invalidate();
+ if (pRowOutline[i])
+ pRowOutline[i]->Invalidate();
+ }
+}
+
+void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
+{
+ // Pixel-Position der oberen Kante
+
+ if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
+ nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
+ aViewData.RecalcPixPos();
+
+ // Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
+
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
+ if (aViewData.UpdateFixY())
+ RepeatResize();
+
+ // zeichnen
+
+ if (nStartRow>0)
+ --nStartRow;
+
+ for (USHORT i=0; i<2; i++)
+ {
+ ScVSplitPos eWhich = (ScVSplitPos) i;
+ if (pRowBar[eWhich])
+ {
+ Size aWinSize = pRowBar[eWhich]->GetSizePixel();
+ long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
+ long nEndY;
+ if (nEndRow >= MAXROW)
+ nEndY = aWinSize.Height()-1;
+ else
+ nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
+ pRowBar[eWhich]->Invalidate(
+ Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
+ }
+ if (pRowOutline[eWhich])
+ pRowOutline[eWhich]->Invalidate();
+ }
+}
+
+// InvertBlockMark - Block invertieren
+
+void ScTabView::InvertBlockMark(SCCOL nStartX, SCROW nStartY,
+ SCCOL nEndX, SCROW nEndY)
+{
+ if ( !aViewData.IsActive() )
+ return; // invertiert wird nur auf aktiver View
+
+ PutInOrder( nStartX, nEndX );
+ PutInOrder( nStartY, nEndY );
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ if ( pDocSh->GetLockCount() )
+ {
+ // if paint is locked, avoid repeated inverting
+ // add repaint areas to paint lock data instead
+ pDocSh->PostPaint( nStartX,nStartY,nTab, nEndX,nEndY,nTab, PAINT_GRID );
+ return;
+ }
+
+ BOOL bSingle = rMark.IsMultiMarked();
+ BOOL bMerge = pDoc->HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED );
+
+ USHORT i;
+ if ( bMerge || bSingle )
+ {
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ pGridWin[i]->InvertSimple( nStartX, nStartY, nEndX, nEndY,
+ bMerge, bBlockNeg );
+ }
+ else
+ {
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ ScSplitPos ePos = (ScSplitPos) i;
+ Point aStartPoint = aViewData.GetScrPos( nStartX, nStartY, ePos );
+ Point aEndPoint = aViewData.GetScrPos( nEndX+1, nEndY+1, ePos );
+ if ( pDoc->IsLayoutRTL( nTab ) )
+ {
+ long nTemp = aStartPoint.X();
+ aStartPoint.X() = aEndPoint.X() + 1; // +1 - excluding start of nEndX+1
+ aEndPoint.X() = nTemp;
+ }
+ else
+ aEndPoint.X() -= 1;
+ aEndPoint.Y() -= 1;
+ if ( aEndPoint.X() >= aStartPoint.X() && aEndPoint.Y() >= aStartPoint.Y() )
+ {
+ MapMode aOld = pGridWin[ePos]->GetMapMode();
+ pGridWin[ePos]->SetMapMode(MAP_PIXEL);
+ pGridWin[ePos]->Invert( Rectangle(aStartPoint,aEndPoint), INVERT_HIGHLIGHT );
+ pGridWin[ePos]->SetMapMode(aOld);
+ pGridWin[ePos]->CheckInverted();
+ }
+ }
+ }
+
+ //
+ // wenn Controls betroffen, neu malen
+ //
+
+ BOOL bHide = TRUE; // wird Teil der Markierung aufgehoben ?
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ if ( aMarkRange.aStart.Col() <= nStartX && aMarkRange.aEnd.Col() >= nEndX &&
+ aMarkRange.aStart.Row() <= nStartY && aMarkRange.aEnd.Row() >= nEndY )
+ {
+ bHide = FALSE; // der ganze Bereich ist markiert
+ }
+ }
+}
+
+BOOL ScTabView::PaintExtras()
+{
+ BOOL bRet = FALSE;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ if (!pDoc->HasTable(nTab)) // Tabelle geloescht ?
+ {
+ SCTAB nCount = pDoc->GetTableCount();
+ aViewData.SetTabNo(nCount-1);
+ bRet = TRUE;
+ }
+ pTabControl->UpdateStatus(); // TRUE = active
+ return bRet;
+}
+
+void ScTabView::RecalcPPT()
+{
+ // called after changes that require the PPT values to be recalculated
+ // (currently from detective operations)
+
+ double nOldX = aViewData.GetPPTX();
+ double nOldY = aViewData.GetPPTY();
+
+ aViewData.RefreshZoom(); // pre-calculate new PPT values
+
+ BOOL bChangedX = ( aViewData.GetPPTX() != nOldX );
+ BOOL bChangedY = ( aViewData.GetPPTY() != nOldY );
+ if ( bChangedX || bChangedY )
+ {
+ // call view SetZoom (including draw scale, split update etc)
+ // and paint only if values changed
+
+ Fraction aZoomX = aViewData.GetZoomX();
+ Fraction aZoomY = aViewData.GetZoomY();
+ SetZoom( aZoomX, aZoomY, FALSE );
+
+ PaintGrid();
+ if (bChangedX)
+ PaintTop();
+ if (bChangedY)
+ PaintLeft();
+ }
+}
+
+void ScTabView::ActivateView( BOOL bActivate, BOOL bFirst )
+{
+ if ( bActivate == aViewData.IsActive() && !bFirst )
+ {
+ // keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
+ // auf ein anderes Dokument umgeschaltet wurde
+ return;
+ }
+
+ // wird nur bei MDI-(De)Activate gerufen
+ // aViewData.Activate hinten wegen Cursor-Show bei KillEditView
+ // Markierung nicht mehr loeschen - wenn an der ViewData Activate(FALSE) gesetzt ist,
+ // wird die Markierung nicht ausgegeben
+
+ if (!bActivate)
+ {
+ ScModule* pScMod = SC_MOD();
+ BOOL bRefMode = pScMod->IsFormulaMode();
+
+ // Referenzeingabe nicht abbrechen, um Referenzen auf
+ // andere Dokumente zuzulassen
+
+ if (!bRefMode)
+ {
+ //pScMod->InputEnterHandler();
+
+ // #80843# pass view to GetInputHdl, this view may not be current anymore
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
+ if (pHdl)
+ pHdl->EnterHandler();
+ }
+ }
+ pTabControl->ActivateView(bActivate);
+ PaintExtras();
+
+ aViewData.Activate(bActivate);
+
+ PaintBlock(FALSE); // Repaint, Markierung je nach Active-Status
+
+ if (!bActivate)
+ HideAllCursors(); // Cursor
+ else if (!bFirst)
+ ShowAllCursors();
+
+ //HMHif (pDrawView)
+ //HMH DrawShowMarkHdl(bActivate); // Drawing-Markierung
+
+ if (bActivate)
+ {
+ if ( bFirst )
+ {
+ ScSplitPos eWin = aViewData.GetActivePart();
+ DBG_ASSERT( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
+ if ( !pGridWin[eWin] )
+ {
+ eWin = SC_SPLIT_BOTTOMLEFT;
+ if ( !pGridWin[eWin] )
+ {
+ short i;
+ for ( i=0; i<4; i++ )
+ {
+ if ( pGridWin[i] )
+ {
+ eWin = (ScSplitPos) i;
+ break; // for
+ }
+ }
+ DBG_ASSERT( i<4, "und BUMM" );
+ }
+ aViewData.SetActivePart( eWin );
+ }
+ }
+ // hier nicht mehr selber GrabFocus rufen!
+ // Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
+ // Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
+
+ UpdateInputContext();
+ }
+ else
+ pGridWin[aViewData.GetActivePart()]->ClickExtern();
+}
+
+void ScTabView::ActivatePart( ScSplitPos eWhich )
+{
+ ScSplitPos eOld = aViewData.GetActivePart();
+ if ( eOld != eWhich )
+ {
+ bInActivatePart = TRUE;
+
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+
+ // #40565# the HasEditView call during SetCursor would fail otherwise
+ if ( aViewData.HasEditView(eOld) && !bRefMode )
+ UpdateInputLine();
+
+ ScHSplitPos eOldH = WhichH(eOld);
+ ScVSplitPos eOldV = WhichV(eOld);
+ ScHSplitPos eNewH = WhichH(eWhich);
+ ScVSplitPos eNewV = WhichV(eWhich);
+ BOOL bTopCap = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
+ BOOL bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
+
+ BOOL bFocus = pGridWin[eOld]->HasFocus();
+ BOOL bCapture = pGridWin[eOld]->IsMouseCaptured();
+ if (bCapture)
+ pGridWin[eOld]->ReleaseMouse();
+ pGridWin[eOld]->ClickExtern();
+ pGridWin[eOld]->HideCursor();
+ pGridWin[eWhich]->HideCursor();
+ aViewData.SetActivePart( eWhich );
+
+ ScTabViewShell* pShell = aViewData.GetViewShell();
+ pShell->WindowChanged();
+
+ pSelEngine->SetWindow(pGridWin[eWhich]);
+ pSelEngine->SetWhich(eWhich);
+ pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
+
+ pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
+
+ if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
+ {
+ // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
+ // (SelectionEngine ruft CaptureMouse beim SetWindow)
+ //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
+ pGridWin[eWhich]->ReleaseMouse();
+ pGridWin[eWhich]->StartTracking();
+ }
+
+ if ( bTopCap && pColBar[eNewH] )
+ {
+ pColBar[eOldH]->SetIgnoreMove(TRUE);
+ pColBar[eNewH]->SetIgnoreMove(FALSE);
+ pHdrSelEng->SetWindow( pColBar[eNewH] );
+ long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
+ pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
+ pColBar[eNewH]->CaptureMouse();
+ }
+ if ( bLeftCap && pRowBar[eNewV] )
+ {
+ pRowBar[eOldV]->SetIgnoreMove(TRUE);
+ pRowBar[eNewV]->SetIgnoreMove(FALSE);
+ pHdrSelEng->SetWindow( pRowBar[eNewV] );
+ long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
+ pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
+ pRowBar[eNewV]->CaptureMouse();
+ }
+ aHdrFunc.SetWhich(eWhich);
+
+ pGridWin[eOld]->ShowCursor();
+ pGridWin[eWhich]->ShowCursor();
+
+ SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
+ BOOL bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
+
+ // #103823# don't switch ViewShell's active window during RefInput, because the focus
+ // might change, and subsequent SetReference calls wouldn't find the right EditView
+ if ( !bRefMode && !bOleActive )
+ aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
+
+ if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
+ {
+ // GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
+ // (z.B. wegen Suchen & Ersetzen)
+//! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
+ pGridWin[eWhich]->GrabFocus();
+ }
+
+ bInActivatePart = FALSE;
+ }
+}
+
+void ScTabView::HideListBox()
+{
+ for (USHORT i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->ClickExtern();
+}
+
+void ScTabView::UpdateInputContext()
+{
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ if (pWin)
+ pWin->UpdateInputContext();
+}
+
+// GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
+
+long ScTabView::GetGridWidth( ScHSplitPos eWhich )
+{
+ ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+ if (pGridWin[eGridWhich])
+ return pGridWin[eGridWhich]->GetSizePixel().Width();
+ else
+ return 0;
+}
+
+// GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
+
+long ScTabView::GetGridHeight( ScVSplitPos eWhich )
+{
+ ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+ if (pGridWin[eGridWhich])
+ return pGridWin[eGridWhich]->GetSizePixel().Height();
+ else
+ return 0;
+}
+
+void ScTabView::UpdateInputLine()
+{
+ SC_MOD()->InputEnterHandler();
+}
+
+void ScTabView::ZoomChanged()
+{
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
+ if (pHdl)
+ pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
+
+ UpdateFixPos();
+
+ UpdateScrollBars();
+
+ // VisArea...
+ // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
+ // but is not. Setting only on one window causes the first repaint to have the old mapMode
+ // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
+ // Changing to setting map mode at all windows.
+ sal_uInt32 a;
+
+ for(a = 0L; a < 4L; a++)
+ {
+ if(pGridWin[a])
+ {
+ pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
+ }
+ }
+
+ SetNewVisArea();
+
+ /* the old code
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ if (pWin)
+ {
+ pWin->SetMapMode( pWin->GetDrawMapMode() ); // mit neuem Zoom
+ SetNewVisArea(); // benutzt den gesetzten MapMode
+ } */
+
+ InterpretVisible(); // #69343# have everything calculated before painting
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+ rBindings.Invalidate( SID_ATTR_ZOOM );
+ rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
+
+ HideNoteMarker();
+
+ // AW: To not change too much, use pWin here
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+
+ if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
+ {
+ // flush OverlayManager before changing the MapMode
+ pWin->flushOverlayManager();
+
+ // #93650# make sure the EditView's position and size are updated
+ // with the right (logic, not drawing) MapMode
+ pWin->SetMapMode( aViewData.GetLogicMode() );
+ UpdateEditView();
+ }
+}
+
+void ScTabView::CheckNeedsRepaint()
+{
+ USHORT i;
+ for (i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->CheckNeedsRepaint();
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabview4.cxx b/sc/source/ui/view/tabview4.cxx
new file mode 100644
index 000000000000..abbc0224704e
--- /dev/null
+++ b/sc/source/ui/view/tabview4.cxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+
+#include "tabview.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "gridwin.hxx"
+#include "globstr.hrc"
+#include "cell.hxx"
+#include "dociter.hxx"
+
+extern USHORT nScFillModeMouseModifier; // global.cxx
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+//
+// --- Referenz-Eingabe / Fill-Cursor
+//
+
+void ScTabView::HideTip()
+{
+ if ( nTipVisible )
+ {
+ Help::HideTip( nTipVisible );
+ nTipVisible = 0;
+ }
+}
+
+void ScTabView::ShowRefTip()
+{
+ BOOL bDone = FALSE;
+ if ( aViewData.GetRefType() == SC_REFTYPE_REF && Help::IsQuickHelpEnabled() )
+ {
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nEndX != nStartX || nEndY != nStartY ) // nicht fuer einzelne Zelle
+ {
+ BOOL bLeft = ( nEndX < nStartX );
+ BOOL bTop = ( nEndY < nStartY );
+ PutInOrder( nStartX, nEndX );
+ PutInOrder( nStartY, nEndY );
+ SCCOL nCols = nEndX+1-nStartX;
+ SCROW nRows = nEndY+1-nStartY;
+
+ String aHelp = ScGlobal::GetRscString( STR_QUICKHELP_REF );
+ aHelp.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%1")),
+ String::CreateFromInt32(nRows) );
+ aHelp.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%2")),
+ String::CreateFromInt32(nCols) );
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ Window* pWin = pGridWin[eWhich];
+ if ( pWin )
+ {
+ Point aStart = aViewData.GetScrPos( nStartX, nStartY, eWhich );
+ Point aEnd = aViewData.GetScrPos( nEndX+1, nEndY+1, eWhich );
+
+ Point aPos( bLeft ? aStart.X() : ( aEnd.X() + 3 ),
+ bTop ? aStart.Y() : ( aEnd.Y() + 3 ) );
+ USHORT nFlags = ( bLeft ? QUICKHELP_RIGHT : QUICKHELP_LEFT ) |
+ ( bTop ? QUICKHELP_BOTTOM : QUICKHELP_TOP );
+
+ // nicht ueber die editierte Formel
+ if ( !bTop && aViewData.HasEditView( eWhich ) &&
+ nEndY+1 == aViewData.GetEditViewRow() )
+ {
+ // dann an der oberen Kante der editierten Zelle ausrichten
+ aPos.Y() -= 2; // die 3 von oben
+ nFlags = ( nFlags & ~QUICKHELP_TOP ) | QUICKHELP_BOTTOM;
+ }
+
+ Rectangle aRect( pWin->OutputToScreenPixel( aPos ), Size(1,1) );
+
+ //! Test, ob geaendert ??
+
+ HideTip();
+ nTipVisible = Help::ShowTip( pWin, aRect, aHelp, nFlags );
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if (!bDone)
+ HideTip();
+}
+
+void ScTabView::StopRefMode()
+{
+ if (aViewData.IsRefMode())
+ {
+ aViewData.SetRefMode( FALSE, SC_REFTYPE_NONE );
+
+ HideTip();
+ UpdateShrinkOverlay();
+
+ if ( aViewData.GetTabNo() >= aViewData.GetRefStartZ() &&
+ aViewData.GetTabNo() <= aViewData.GetRefEndZ() )
+ {
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, aViewData.GetTabNo() );
+
+ PaintArea( nStartX,nStartY,nEndX,nEndY, SC_UPDATE_MARKS );
+ }
+
+ pSelEngine->Reset();
+ pSelEngine->SetAddMode( FALSE ); //! sollte das nicht bei Reset passieren?
+
+ ScSplitPos eOld = pSelEngine->GetWhich();
+ ScSplitPos eNew = aViewData.GetActivePart();
+ if ( eNew != eOld )
+ {
+ pSelEngine->SetWindow( pGridWin[ eNew ] );
+ pSelEngine->SetWhich( eNew );
+ pSelEngine->SetVisibleArea( Rectangle(Point(),
+ pGridWin[eNew]->GetOutputSizePixel()) );
+ pGridWin[eOld]->MoveMouseStatus(*pGridWin[eNew]);
+ }
+ }
+
+ // AlignToCursor(SC_FOLLOW_NONE): Only switch active part.
+ // This must also be done if no RefMode was active (for RangeFinder dragging),
+ // but if RefMode was set, AlignToCursor must be after SelectionEngine reset,
+ // so the SelectionEngine SetWindow call from AlignToCursor doesn't capture
+ // the mouse again when called from Tracking/MouseButtonUp (#94562#).
+ AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
+}
+
+void ScTabView::DoneRefMode( BOOL bContinue )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( aViewData.GetRefType() == SC_REFTYPE_REF && bContinue )
+ SC_MOD()->AddRefEntry();
+
+ BOOL bWasRef = aViewData.IsRefMode();
+ aViewData.SetRefMode( FALSE, SC_REFTYPE_NONE );
+
+ HideTip();
+ UpdateShrinkOverlay();
+
+ // Paint:
+ if ( bWasRef && aViewData.GetTabNo() >= aViewData.GetRefStartZ() &&
+ aViewData.GetTabNo() <= aViewData.GetRefEndZ() )
+ {
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, aViewData.GetTabNo() );
+
+ PaintArea( nStartX,nStartY,nEndX,nEndY, SC_UPDATE_MARKS );
+ }
+}
+
+void ScTabView::UpdateRef( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+
+ if (!aViewData.IsRefMode())
+ {
+ // Das kommt vor, wenn bei einem Referenz-Dialog als erstes mit Control in die
+ // die Tabelle geklickt wird. Dann die neue Referenz an den alten Inhalt anhaengen:
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsFormulaMode())
+ pScMod->AddRefEntry();
+
+ InitRefMode( nCurX, nCurY, nCurZ, SC_REFTYPE_REF );
+ }
+
+ if ( nCurX != aViewData.GetRefEndX() || nCurY != aViewData.GetRefEndY() ||
+ nCurZ != aViewData.GetRefEndZ() )
+ {
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
+ ScUpdateRect aRect( nStartX, nStartY, nEndX, nEndY );
+
+ aViewData.SetRefEnd( nCurX, nCurY, nCurZ );
+
+ nStartX = aViewData.GetRefStartX();
+ nStartY = aViewData.GetRefStartY();
+ nEndX = aViewData.GetRefEndX();
+ nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
+ aRect.SetNew( nStartX, nStartY, nEndX, nEndY );
+
+ ScRefType eType = aViewData.GetRefType();
+ if ( eType == SC_REFTYPE_REF )
+ {
+ ScRange aRef(
+ aViewData.GetRefStartX(), aViewData.GetRefStartY(), aViewData.GetRefStartZ(),
+ aViewData.GetRefEndX(), aViewData.GetRefEndY(), aViewData.GetRefEndZ() );
+ SC_MOD()->SetReference( aRef, pDoc, &rMark );
+ ShowRefTip();
+ }
+ else if ( eType == SC_REFTYPE_EMBED_LT || eType == SC_REFTYPE_EMBED_RB )
+ {
+ PutInOrder(nStartX,nEndX);
+ PutInOrder(nStartY,nEndY);
+ pDoc->SetEmbedded( ScRange(nStartX,nStartY,nTab, nEndX,nEndY,nTab) );
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ pDocSh->UpdateOle( &aViewData, TRUE );
+ pDocSh->SetDocumentModified();
+ }
+
+ SCCOL nPaintStartX;
+ SCROW nPaintStartY;
+ SCCOL nPaintEndX;
+ SCROW nPaintEndY;
+ if (aRect.GetDiff( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY ))
+ PaintArea( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY, SC_UPDATE_MARKS );
+ }
+
+ // Tip-Hilfe fuer Auto-Fill
+
+ if ( aViewData.GetRefType() == SC_REFTYPE_FILL && Help::IsQuickHelpEnabled() )
+ {
+ String aHelpStr;
+ ScRange aMarkRange;
+ aViewData.GetSimpleArea( aMarkRange );
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ ScRange aDelRange;
+ if ( aViewData.GetFillMode() == SC_FILL_MATRIX && !(nScFillModeMouseModifier & KEY_MOD1) )
+ {
+ aHelpStr = ScGlobal::GetRscString( STR_TIP_RESIZEMATRIX );
+ SCCOL nCols = nEndX + 1 - aViewData.GetRefStartX(); // Reihenfolge ist richtig
+ SCROW nRows = nEndY + 1 - aViewData.GetRefStartY();
+ aHelpStr.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%1")),
+ String::CreateFromInt32(nRows) );
+ aHelpStr.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%2")),
+ String::CreateFromInt32(nCols) );
+ }
+ else if ( aViewData.GetDelMark( aDelRange ) )
+ aHelpStr = ScGlobal::GetRscString( STR_QUICKHELP_DELETE );
+ else if ( nEndX != aMarkRange.aEnd.Col() || nEndY != aMarkRange.aEnd.Row() )
+ aHelpStr = pDoc->GetAutoFillPreview( aMarkRange, nEndX, nEndY );
+
+ // je nach Richtung die obere oder untere Ecke:
+ SCCOL nAddX = ( nEndX >= aMarkRange.aEnd.Col() ) ? 1 : 0;
+ SCROW nAddY = ( nEndY >= aMarkRange.aEnd.Row() ) ? 1 : 0;
+ Point aPos = aViewData.GetScrPos( nEndX+nAddX, nEndY+nAddY, aViewData.GetActivePart() );
+ aPos.X() += 8;
+ aPos.Y() += 4;
+ Window* pWin = GetActiveWin();
+ if ( pWin )
+ aPos = pWin->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, aPos );
+ USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_TOP;
+ Help::ShowQuickHelp(pWin, aRect, aHelpStr, nAlign);
+ }
+}
+
+void ScTabView::InitRefMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScRefType eType, BOOL bPaint )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (!aViewData.IsRefMode())
+ {
+ aViewData.SetRefMode( TRUE, eType );
+ aViewData.SetRefStart( nCurX, nCurY, nCurZ );
+ aViewData.SetRefEnd( nCurX, nCurY, nCurZ );
+
+ if (nCurZ == aViewData.GetTabNo() && bPaint)
+ {
+ SCCOL nStartX = nCurX;
+ SCROW nStartY = nCurY;
+ SCCOL nEndX = nCurX;
+ SCROW nEndY = nCurY;
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, aViewData.GetTabNo() );
+
+ //! nur Markierung ueber Inhalte zeichnen!
+ PaintArea( nStartX,nStartY,nEndX,nEndY, SC_UPDATE_MARKS );
+
+ // SetReference ohne Merge-Anpassung
+ ScRange aRef( nCurX,nCurY,nCurZ, nCurX,nCurY,nCurZ );
+ SC_MOD()->SetReference( aRef, pDoc, &rMark );
+ }
+ }
+}
+
+//UNUSED2008-05 void ScTabView::EndSelection()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScModule* pScMod = SC_MOD();
+//UNUSED2008-05 BOOL bRefMode = pScMod->IsFormulaMode();
+//UNUSED2008-05 if ( bRefMode )
+//UNUSED2008-05 pScMod->EndReference();
+//UNUSED2008-05 }
+
+// static
+void ScTabView::SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, BOOL bLayoutRTL )
+{
+ if ( nVisible == 0 )
+ nVisible = 1; // #i59893# don't use visible size 0
+
+ // RTL layout uses a negative range to simulate a mirrored scroll bar.
+ // SetScrollBar/GetScrollBarPos hide this so outside of these functions normal cell
+ // addresses can be used.
+
+ if ( bLayoutRTL )
+ {
+ rScroll.SetRange( Range( -nRangeMax, 0 ) );
+ rScroll.SetVisibleSize( nVisible );
+ rScroll.SetThumbPos( -nPos - nVisible );
+ }
+ else
+ {
+ rScroll.SetRange( Range( 0, nRangeMax ) );
+ rScroll.SetVisibleSize( nVisible );
+ rScroll.SetThumbPos( nPos );
+ }
+}
+
+// static
+long ScTabView::GetScrollBarPos( ScrollBar& rScroll, BOOL bLayoutRTL )
+{
+ if ( bLayoutRTL )
+ return -rScroll.GetThumbPos() - rScroll.GetVisibleSize();
+ else
+ return rScroll.GetThumbPos();
+}
+
+// UpdateScrollBars - sichtbaren Bereich und Scrollweite der Scrollbars einstellen
+
+long lcl_UpdateBar( ScrollBar& rScroll, SCCOLROW nSize ) // Size = (komplette) Zellen
+{
+ long nOldPos;
+ long nNewPos;
+
+ nOldPos = rScroll.GetThumbPos();
+ rScroll.SetPageSize( static_cast<long>(nSize) );
+ nNewPos = rScroll.GetThumbPos();
+#ifndef UNX
+ rScroll.SetPageSize( 1 ); // immer moeglich !
+#endif
+
+ return nNewPos - nOldPos;
+}
+
+long lcl_GetScrollRange( SCCOLROW nDocEnd, SCCOLROW nPos, SCCOLROW nVis, SCCOLROW nMax, SCCOLROW nStart )
+{
+ // get the end (positive) of a scroll bar range that always starts at 0
+
+ ++nVis;
+ ++nMax; // for partially visible cells
+ SCCOLROW nEnd = Max(nDocEnd, (SCCOLROW)(nPos+nVis)) + nVis;
+ if (nEnd > nMax)
+ nEnd = nMax;
+
+ return ( nEnd - nStart ); // for range starting at 0
+}
+
+void ScTabView::UpdateScrollBars()
+{
+ long nDiff;
+ BOOL bTop = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
+ BOOL bRight = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ BOOL bMirror = pDoc->IsLayoutRTL( nTab ) != Application::GetSettings().GetLayoutRTL();
+ SCCOL nUsedX;
+ SCROW nUsedY;
+ pDoc->GetTableArea( nTab, nUsedX, nUsedY ); //! cachen !!!!!!!!!!!!!!!
+
+ SCCOL nVisXL = 0;
+ SCCOL nVisXR = 0;
+ SCROW nVisYB = 0;
+ SCROW nVisYT = 0;
+
+ SCCOL nStartX = 0;
+ SCROW nStartY = 0;
+ if (aViewData.GetHSplitMode()==SC_SPLIT_FIX)
+ nStartX = aViewData.GetFixPosX();
+ if (aViewData.GetVSplitMode()==SC_SPLIT_FIX)
+ nStartY = aViewData.GetFixPosY();
+
+ nVisXL = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
+ long nMaxXL = lcl_GetScrollRange( nUsedX, aViewData.GetPosX(SC_SPLIT_LEFT), nVisXL, MAXCOL, 0 );
+ SetScrollBar( aHScrollLeft, nMaxXL, nVisXL, aViewData.GetPosX( SC_SPLIT_LEFT ), bMirror );
+
+ nVisYB = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
+ long nMaxYB = lcl_GetScrollRange( nUsedY, aViewData.GetPosY(SC_SPLIT_BOTTOM), nVisYB, MAXROW, nStartY );
+ SetScrollBar( aVScrollBottom, nMaxYB, nVisYB, aViewData.GetPosY( SC_SPLIT_BOTTOM ) - nStartY, FALSE );
+
+ if (bRight)
+ {
+ nVisXR = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
+ long nMaxXR = lcl_GetScrollRange( nUsedX, aViewData.GetPosX(SC_SPLIT_RIGHT), nVisXR, MAXCOL, nStartX );
+ SetScrollBar( aHScrollRight, nMaxXR, nVisXR, aViewData.GetPosX( SC_SPLIT_RIGHT ) - nStartX, bMirror );
+ }
+
+ if (bTop)
+ {
+ nVisYT = aViewData.VisibleCellsY( SC_SPLIT_TOP );
+ long nMaxYT = lcl_GetScrollRange( nUsedY, aViewData.GetPosY(SC_SPLIT_TOP), nVisYT, MAXROW, 0 );
+ SetScrollBar( aVScrollTop, nMaxYT, nVisYT, aViewData.GetPosY( SC_SPLIT_TOP ), FALSE );
+ }
+
+ // Bereich testen
+
+ nDiff = lcl_UpdateBar( aHScrollLeft, nVisXL );
+ if (nDiff) ScrollX( nDiff, SC_SPLIT_LEFT );
+ if (bRight)
+ {
+ nDiff = lcl_UpdateBar( aHScrollRight, nVisXR );
+ if (nDiff) ScrollX( nDiff, SC_SPLIT_RIGHT );
+ }
+
+ nDiff = lcl_UpdateBar( aVScrollBottom, nVisYB );
+ if (nDiff) ScrollY( nDiff, SC_SPLIT_BOTTOM );
+ if (bTop)
+ {
+ nDiff = lcl_UpdateBar( aVScrollTop, nVisYT );
+ if (nDiff) ScrollY( nDiff, SC_SPLIT_TOP );
+ }
+
+ // set visible area for online spelling
+
+ if ( aViewData.IsActive() )
+ {
+ ScSplitPos eActive = aViewData.GetActivePart();
+ ScHSplitPos eHWhich = WhichH( eActive );
+ ScVSplitPos eVWhich = WhichV( eActive );
+ SCCOL nPosX = aViewData.GetPosX(eHWhich);
+ SCROW nPosY = aViewData.GetPosY(eVWhich);
+ SCCOL nEndX = nPosX + ( ( eHWhich == SC_SPLIT_LEFT ) ? nVisXL : nVisXR );
+ SCROW nEndY = nPosY + ( ( eVWhich == SC_SPLIT_TOP ) ? nVisYT : nVisYB );
+ if ( nEndX > MAXCOL ) nEndX = MAXCOL;
+ if ( nEndY > MAXROW ) nEndY = MAXROW;
+ ScRange aVisible( nPosX, nPosY, nTab, nEndX, nEndY, nTab );
+ if ( pDoc->SetVisibleSpellRange( aVisible ) )
+ SC_MOD()->AnythingChanged(); // if visible area has changed
+ }
+}
+
+#ifndef HDR_SLIDERSIZE
+#define HDR_SLIDERSIZE 2
+#endif
+
+void ScTabView::InvertHorizontal( ScVSplitPos eWhich, long nDragPos )
+{
+ for (USHORT i=0; i<4; i++)
+ if (WhichV((ScSplitPos)i)==eWhich)
+ {
+ ScGridWindow* pWin = pGridWin[i];
+ if (pWin)
+ {
+ Rectangle aRect( 0,nDragPos, pWin->GetOutputSizePixel().Width()-1,nDragPos+HDR_SLIDERSIZE-1 );
+ pWin->Update();
+ pWin->DoInvertRect( aRect ); // Pixel
+ }
+ }
+}
+
+void ScTabView::InvertVertical( ScHSplitPos eWhich, long nDragPos )
+{
+ for (USHORT i=0; i<4; i++)
+ if (WhichH((ScSplitPos)i)==eWhich)
+ {
+ ScGridWindow* pWin = pGridWin[i];
+ if (pWin)
+ {
+ Rectangle aRect( nDragPos,0, nDragPos+HDR_SLIDERSIZE-1,pWin->GetOutputSizePixel().Height()-1 );
+ pWin->Update();
+ pWin->DoInvertRect( aRect ); // Pixel
+ }
+ }
+}
+
+//==================================================================
+
+void ScTabView::InterpretVisible()
+{
+ // make sure all visible cells are interpreted,
+ // so the next paint will not execute a macro function
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( !pDoc->GetAutoCalc() )
+ return;
+
+ SCTAB nTab = aViewData.GetTabNo();
+ for (USHORT i=0; i<4; i++)
+ {
+ // rely on gridwin pointers to find used panes
+ // no IsVisible test in case the whole view is not yet shown
+
+ if (pGridWin[i])
+ {
+ ScHSplitPos eHWhich = WhichH( ScSplitPos(i) );
+ ScVSplitPos eVWhich = WhichV( ScSplitPos(i) );
+
+ SCCOL nX1 = aViewData.GetPosX( eHWhich );
+ SCROW nY1 = aViewData.GetPosY( eVWhich );
+ SCCOL nX2 = nX1 + aViewData.VisibleCellsX( eHWhich );
+ SCROW nY2 = nY1 + aViewData.VisibleCellsY( eVWhich );
+
+ if (nX2 > MAXCOL) nX2 = MAXCOL;
+ if (nY2 > MAXROW) nY2 = MAXROW;
+
+ ScCellIterator aIter( pDoc, nX1, nY1, nTab, nX2, nY2, nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetDirty() )
+ ((ScFormulaCell*)pCell)->Interpret();
+
+ pCell = aIter.GetNext();
+ }
+ }
+ }
+
+ // #i65047# repaint during the above loop may have set the bNeedsRepaint flag
+ CheckNeedsRepaint();
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx
new file mode 100644
index 000000000000..f0ac3fc42869
--- /dev/null
+++ b/sc/source/ui/view/tabview5.cxx
@@ -0,0 +1,722 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svx/fmshell.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoutl.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+#include <tools/ref.hxx>
+
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "tabsplit.hxx"
+#include "colrowba.hxx"
+#include "tabcont.hxx"
+#include "hintwin.hxx"
+#include "sc.hrc"
+#include "pagedata.hxx"
+#include "hiranges.hxx"
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+#include "fusel.hxx" // Start-Function
+#include "seltrans.hxx"
+#include "scmod.hxx"
+#include "AccessibilityHints.hxx"
+#include "docsh.hxx"
+#include "viewuno.hxx"
+
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+void __EXPORT ScTabView::Init()
+{
+ /* RTL layout of the view windows is done manually, because it depends on
+ the sheet orientation, not the UI setting. Note: controls that are
+ already constructed (e.g. scroll bars) have the RTL setting of the GUI.
+ Eventually this has to be disabled manually (see below). */
+ pFrameWin->EnableRTL( FALSE );
+
+ USHORT i;
+
+ aScrollTimer.SetTimeout(10);
+ aScrollTimer.SetTimeoutHdl( LINK( this, ScTabView, TimerHdl ) );
+
+ for (i=0; i<4; i++)
+ pGridWin[i] = NULL;
+ pGridWin[SC_SPLIT_BOTTOMLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMLEFT );
+
+ pSelEngine = new ScViewSelectionEngine( pGridWin[SC_SPLIT_BOTTOMLEFT], this,
+ SC_SPLIT_BOTTOMLEFT );
+ aFunctionSet.SetSelectionEngine( pSelEngine );
+
+ pHdrSelEng = new ScHeaderSelectionEngine( pFrameWin, &aHdrFunc );
+
+ pColBar[SC_SPLIT_LEFT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_LEFT,
+ &aHdrFunc, pHdrSelEng );
+ pColBar[SC_SPLIT_RIGHT] = NULL;
+ pRowBar[SC_SPLIT_BOTTOM] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_BOTTOM,
+ &aHdrFunc, pHdrSelEng );
+ pRowBar[SC_SPLIT_TOP] = NULL;
+ for (i=0; i<2; i++)
+ pColOutline[i] = pRowOutline[i] = NULL;
+
+ pHSplitter = new ScTabSplitter( pFrameWin, WinBits( WB_HSCROLL ), &aViewData );
+ pVSplitter = new ScTabSplitter( pFrameWin, WinBits( WB_VSCROLL ), &aViewData );
+
+ // SSA: override default keyboard step size to allow snap to row/column
+ pHSplitter->SetKeyboardStepSize( 1 );
+ pVSplitter->SetKeyboardStepSize( 1 );
+
+ pTabControl = new ScTabControl( pFrameWin, &aViewData );
+ /* #i97900# The tab control has to remain in RTL mode if GUI is RTL, this
+ is needed to draw the 3D effect correctly. The base TabBar implementes
+ mirroring independent from the GUI direction. Have to set RTL mode
+ explicitly because the parent frame window is already RTL disabled. */
+ pTabControl->EnableRTL( Application::GetSettings().GetLayoutRTL() );
+
+ InitScrollBar( aHScrollLeft, MAXCOL+1 );
+ InitScrollBar( aHScrollRight, MAXCOL+1 );
+ InitScrollBar( aVScrollTop, MAXROW+1 );
+ InitScrollBar( aVScrollBottom, MAXROW+1 );
+ /* #i97900# scrollbars remain in correct RTL mode, needed mirroring etc.
+ is now handled correctly at the respective places. */
+
+ // Hier noch nichts anzeigen (Show), weil noch falsch angeordnet ist
+ // Show kommt dann aus UpdateShow beim ersten Resize
+ // pTabControl, pGridWin, aHScrollLeft, aVScrollBottom,
+ // aCornerButton, aScrollBarBox, pHSplitter, pVSplitter
+
+ // Splitter
+
+ pHSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
+ pVSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
+
+ // UpdateShow kommt beim Resize, oder bei Kopie einer bestehenden View aus dem ctor
+
+ pDrawActual = NULL;
+ pDrawOld = NULL;
+
+ // DrawView darf nicht im TabView - ctor angelegt werden,
+ // wenn die ViewShell noch nicht konstruiert ist...
+ // Das gilt auch fuer ViewOptionsHasChanged()
+
+ TestHintWindow();
+}
+
+__EXPORT ScTabView::~ScTabView()
+{
+ USHORT i;
+
+ // remove selection object
+ ScModule* pScMod = SC_MOD();
+ ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
+ if ( pOld && pOld->GetView() == this )
+ {
+ pOld->ForgetView();
+ pScMod->SetSelectionTransfer( NULL );
+ TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
+ }
+
+ DELETEZ(pBrushDocument);
+ DELETEZ(pDrawBrushSet);
+
+ DELETEZ(pPageBreakData);
+ DELETEZ(pHighlightRanges);
+
+ DELETEZ(pDrawOld);
+ DELETEZ(pDrawActual);
+
+ aViewData.KillEditView(); // solange GridWin's noch existieren
+
+ DELETEZ(pInputHintWindow);
+
+ if (pDrawView)
+ {
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ pDrawView->VCRemoveWin(pGridWin[i]);
+ pDrawView->DeleteWindowFromPaintView(pGridWin[i]);
+ }
+
+ pDrawView->HideSdrPage();
+ delete pDrawView;
+ }
+
+ delete pSelEngine;
+
+ for (i=0; i<4; i++)
+ delete pGridWin[i];
+
+ delete pHdrSelEng;
+
+ for (i=0; i<2; i++)
+ {
+ delete pColBar[i];
+ delete pRowBar[i];
+ delete pColOutline[i];
+ delete pRowOutline[i];
+ }
+
+ delete pHSplitter;
+ delete pVSplitter;
+
+ delete pTabControl;
+}
+
+void ScTabView::MakeDrawView( BYTE nForceDesignMode )
+{
+ if (!pDrawView)
+ {
+ ScDrawLayer* pLayer = aViewData.GetDocument()->GetDrawLayer();
+ DBG_ASSERT(pLayer, "wo ist der Draw Layer ??");
+
+ USHORT i;
+ pDrawView = new ScDrawView( pGridWin[SC_SPLIT_BOTTOMLEFT], &aViewData );
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ if ( SC_SPLIT_BOTTOMLEFT != (ScSplitPos)i )
+ pDrawView->AddWindowToPaintView(pGridWin[i]);
+ pDrawView->VCAddWin(pGridWin[i]);
+ }
+ pDrawView->RecalcScale();
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
+
+ pGridWin[i]->Update(); // wegen Invalidate im DrawView ctor (ShowPage),
+ // damit gleich gezeichnet werden kann
+ }
+ SfxRequest aSfxRequest(SID_OBJECT_SELECT, 0,aViewData.GetViewShell()->GetPool());
+ SetDrawFuncPtr(new FuSelection( aViewData.GetViewShell(), GetActiveWin(), pDrawView,
+ pLayer,aSfxRequest));
+
+ // #106334# used when switching back from page preview: restore saved design mode state
+ // (otherwise, keep the default from the draw view ctor)
+ if ( nForceDesignMode != SC_FORCEMODE_NONE )
+ pDrawView->SetDesignMode( (BOOL)nForceDesignMode );
+
+ // an der FormShell anmelden
+ FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
+ if (pFormSh)
+ pFormSh->SetView(pDrawView);
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_MAKEDRAWLAYER));
+
+ }
+}
+
+void ScTabView::DoAddWin( ScGridWindow* pWin )
+{
+ if (pDrawView)
+ {
+ pDrawView->AddWindowToPaintView(pWin);
+ pDrawView->VCAddWin(pWin);
+
+ // #114409#
+ pWin->DrawLayerCreated();
+ }
+}
+
+//==================================================================
+
+void ScTabView::TabChanged()
+{
+ if (pDrawView)
+ {
+ DrawDeselectAll(); // beendet auch Text-Edit-Modus
+
+ USHORT i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ pDrawView->VCRemoveWin(pGridWin[i]); // fuer alte Page
+
+ SCTAB nTab = aViewData.GetTabNo();
+ pDrawView->HideSdrPage();
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+
+ UpdateLayerLocks();
+
+ pDrawView->RecalcScale();
+ pDrawView->UpdateWorkArea(); // #54782# PageSize ist pro Page unterschiedlich
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ pDrawView->VCAddWin(pGridWin[i]); // fuer neue Page
+ }
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ // Es gibt keine einfache Moeglichkeit, alle Slots der FormShell zu invalidieren
+ // (fuer disablete Slots auf geschuetzten Tabellen), darum hier einfach alles...
+ rBindings.InvalidateAll(FALSE);
+
+#if 0
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Invalidate( FID_PROTECT_TABLE );
+ rBindings.Invalidate( FID_DELETE_TABLE );
+ rBindings.Invalidate( FID_TABLE_SHOW );
+ rBindings.Invalidate( FID_TABLE_HIDE );
+
+ // Auswirkungen von geschuetzten Tabellen.
+ rBindings.Invalidate( FID_TAB_RENAME );
+ rBindings.Invalidate( FID_TAB_MOVE );
+ rBindings.Invalidate( SID_DEL_ROWS );
+ rBindings.Invalidate( SID_DEL_COLS );
+ rBindings.Invalidate( FID_INS_ROW );
+ rBindings.Invalidate( FID_INS_COLUMN );
+ rBindings.Invalidate( FID_INS_CELL );
+ rBindings.Invalidate( FID_INS_CELLSDOWN );
+ rBindings.Invalidate( FID_INS_CELLSRIGHT );
+ rBindings.Invalidate( FID_DELETE_CELL );
+
+ rBindings.Invalidate( SID_OPENDLG_CHART );
+ rBindings.Invalidate( SID_INSERT_OBJECT );
+ rBindings.Invalidate( SID_INSERT_DIAGRAM );
+ rBindings.Invalidate( SID_INSERT_SMATH );
+ rBindings.Invalidate( SID_INSERT_GRAPHIC );
+#endif
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ {
+ SfxSimpleHint aAccHint(SC_HINT_ACC_TABLECHANGED);
+ aViewData.GetViewShell()->BroadcastAccessibility(aAccHint);
+ }
+
+ // notification for XActivationBroadcaster
+ SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->SheetChanged();
+ }
+ }
+}
+
+void ScTabView::UpdateLayerLocks()
+{
+ if (pDrawView)
+ {
+ SCTAB nTab = aViewData.GetTabNo();
+ BOOL bEx = aViewData.GetViewShell()->IsDrawSelMode();
+ BOOL bProt = aViewData.GetDocument()->IsTabProtected( nTab ) ||
+ aViewData.GetSfxDocShell()->IsReadOnly();
+ BOOL bShared = aViewData.GetDocShell()->IsDocShared();
+
+ SdrLayer* pLayer;
+ SdrLayerAdmin& rAdmin = pDrawView->GetModel()->GetLayerAdmin();
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || !bEx || bShared );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), TRUE );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
+ if (pLayer)
+ {
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
+ pDrawView->SetLayerVisible( pLayer->GetName(), sal_False);
+ }
+ }
+}
+
+void ScTabView::DrawDeselectAll()
+{
+ if (pDrawView)
+ {
+ ScTabViewShell* pViewSh = aViewData.GetViewShell();
+ if ( pDrawActual &&
+ ( pViewSh->IsDrawTextShell() || pDrawActual->GetSlotID() == SID_DRAW_NOTEEDIT ) )
+ {
+ // end text edit (as if escape pressed, in FuDraw)
+ aViewData.GetDispatcher().Execute( pDrawActual->GetSlotID(),
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+
+ if (!pViewSh->IsDrawSelMode())
+ pViewSh->SetDrawShell( FALSE );
+ }
+}
+
+BOOL ScTabView::IsDrawTextEdit() const
+{
+ if (pDrawView)
+ return pDrawView->IsTextEdit();
+ else
+ return FALSE;
+}
+
+//UNUSED2008-05 String ScTabView::GetSelectedChartName() const
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pDrawView)
+//UNUSED2008-05 return pDrawView->GetSelectedChartName();
+//UNUSED2008-05 else
+//UNUSED2008-05 return EMPTY_STRING;
+//UNUSED2008-05 }
+
+SvxZoomType ScTabView::GetZoomType() const
+{
+ return aViewData.GetZoomType();
+}
+
+void ScTabView::SetZoomType( SvxZoomType eNew, BOOL bAll )
+{
+ aViewData.SetZoomType( eNew, bAll );
+}
+
+void ScTabView::SetZoom( const Fraction& rNewX, const Fraction& rNewY, BOOL bAll )
+{
+ aViewData.SetZoom( rNewX, rNewY, bAll );
+ if (pDrawView)
+ pDrawView->RecalcScale();
+ ZoomChanged(); // einzeln wegen CLOOKs
+}
+
+void ScTabView::RefreshZoom()
+{
+ aViewData.RefreshZoom();
+ if (pDrawView)
+ pDrawView->RecalcScale();
+ ZoomChanged();
+}
+
+void ScTabView::SetPagebreakMode( BOOL bSet )
+{
+ aViewData.SetPagebreakMode(bSet);
+ if (pDrawView)
+ pDrawView->RecalcScale();
+ ZoomChanged(); // einzeln wegen CLOOKs
+}
+
+void ScTabView::ResetDrawDragMode()
+{
+ if (pDrawView)
+ pDrawView->SetDragMode( SDRDRAG_MOVE );
+}
+
+void ScTabView::ViewOptionsHasChanged( BOOL bHScrollChanged, BOOL bGraphicsChanged )
+{
+ // DrawView erzeugen, wenn Gitter angezeigt werden soll
+ if ( !pDrawView && aViewData.GetOptions().GetGridOptions().GetGridVisible() )
+ MakeDrawLayer();
+
+ if (pDrawView)
+ pDrawView->UpdateUserViewOptions();
+
+ if (bGraphicsChanged)
+ DrawEnableAnim(TRUE); // DrawEnableAnim checks the options state
+
+ // if TabBar is set to visible, make sure its size is not 0
+ BOOL bGrow = ( aViewData.IsTabMode() && pTabControl->GetSizePixel().Width() <= 0 );
+
+ // if ScrollBar is set to visible, TabBar must make room
+ BOOL bShrink = ( bHScrollChanged && aViewData.IsTabMode() && aViewData.IsHScrollMode() &&
+ pTabControl->GetSizePixel().Width() > SC_TABBAR_DEFWIDTH );
+
+ if ( bGrow || bShrink )
+ {
+ Size aSize = pTabControl->GetSizePixel();
+ aSize.Width() = SC_TABBAR_DEFWIDTH; // initial size
+ pTabControl->SetSizePixel(aSize); // DoResize is called later...
+ }
+}
+
+// Helper-Funktion gegen das Include des Drawing Layers
+
+SdrView* ScTabView::GetSdrView()
+{
+ return pDrawView;
+}
+
+void ScTabView::DrawMarkListHasChanged()
+{
+ if ( pDrawView )
+ pDrawView->MarkListHasChanged();
+}
+
+void ScTabView::UpdateAnchorHandles()
+{
+ if ( pDrawView )
+ pDrawView->AdjustMarkHdl();
+}
+
+void ScTabView::UpdateIMap( SdrObject* pObj )
+{
+ if ( pDrawView )
+ pDrawView->UpdateIMap( pObj );
+}
+
+void ScTabView::DrawMarkRect( const Rectangle& rRect )
+{
+ //! store rectangle for repaint during drag
+
+ for (USHORT i=0; i<4; i++)
+ {
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ {
+ RasterOp aROp = pGridWin[i]->GetRasterOp();
+ BOOL bHasLine = pGridWin[i]->IsLineColor();
+ Color aLine = pGridWin[i]->GetLineColor();
+ BOOL bHasFill = pGridWin[i]->IsFillColor();
+ Color aFill = pGridWin[i]->GetFillColor();
+
+ pGridWin[i]->SetRasterOp( ROP_INVERT );
+ pGridWin[i]->SetLineColor( COL_BLACK );
+ pGridWin[i]->SetFillColor();
+
+ pGridWin[i]->DrawRect(rRect);
+
+ pGridWin[i]->SetRasterOp(aROp);
+ if (bHasLine)
+ pGridWin[i]->SetLineColor(aLine);
+ else
+ pGridWin[i]->SetLineColor();
+ if (bHasFill)
+ pGridWin[i]->SetFillColor(aFill);
+ else
+ pGridWin[i]->SetFillColor();
+ }
+ }
+}
+
+void ScTabView::DrawEnableAnim(BOOL bSet)
+{
+ USHORT i;
+ if ( pDrawView )
+ {
+ // #71040# dont start animations if display of graphics is disabled
+ // graphics are controlled by VOBJ_TYPE_OLE
+ if ( bSet && aViewData.GetOptions().GetObjMode(VOBJ_TYPE_OLE) == VOBJ_MODE_SHOW )
+ {
+ if ( !pDrawView->IsAnimationEnabled() )
+ {
+ pDrawView->SetAnimationEnabled(TRUE);
+
+ // Animierte GIFs muessen wieder gestartet werden:
+ ScDocument* pDoc = aViewData.GetDocument();
+ for (i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pDoc->StartAnimations( aViewData.GetTabNo(), pGridWin[i] );
+ }
+ }
+ else
+ {
+ pDrawView->SetAnimationEnabled(FALSE);
+ }
+ }
+}
+
+//HMHvoid ScTabView::DrawShowMarkHdl(BOOL bShow)
+//HMH{
+ //HMHif (!pDrawView)
+ //HMH return;
+
+ //HMHif (bShow)
+ //HMH{
+ //HMH if (!pDrawView->IsDisableHdl())
+ //HMH pDrawView->ShowMarkHdl();
+ //HMH}
+ //HMHelse
+ //HMH pDrawView->HideMarkHdl();
+//HMH}
+
+void ScTabView::UpdateDrawTextOutliner()
+{
+ if ( pDrawView )
+ {
+ Outliner* pOL = pDrawView->GetTextEditOutliner();
+ if (pOL)
+ aViewData.UpdateOutlinerFlags( *pOL );
+ }
+}
+
+void ScTabView::DigitLanguageChanged()
+{
+ LanguageType eNewLang = SC_MOD()->GetOptDigitLanguage();
+ for (USHORT i=0; i<4; i++)
+ if ( pGridWin[i] )
+ pGridWin[i]->SetDigitLanguage( eNewLang );
+}
+
+//---------------------------------------------------------------
+
+void ScTabView::ScrollToObject( SdrObject* pDrawObj )
+{
+ if ( pDrawObj )
+ MakeVisible( pDrawObj->GetLogicRect() );
+}
+
+void ScTabView::MakeVisible( const Rectangle& rHMMRect )
+{
+ Window* pWin = GetActiveWin();
+ Size aWinSize = pWin->GetOutputSizePixel();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ Rectangle aRect = pWin->LogicToPixel( rHMMRect );
+
+ long nScrollX=0, nScrollY=0; // Pixel
+
+ if ( aRect.Right() >= aWinSize.Width() ) // rechts raus
+ {
+ nScrollX = aRect.Right() - aWinSize.Width() + 1; // rechter Rand sichtbar
+ if ( aRect.Left() < nScrollX )
+ nScrollX = aRect.Left(); // links sichtbar (falls zu gross)
+ }
+ if ( aRect.Bottom() >= aWinSize.Height() ) // unten raus
+ {
+ nScrollY = aRect.Bottom() - aWinSize.Height() + 1; // unterer Rand sichtbar
+ if ( aRect.Top() < nScrollY )
+ nScrollY = aRect.Top(); // oben sichtbar (falls zu gross)
+ }
+
+ if ( aRect.Left() < 0 ) // links raus
+ nScrollX = aRect.Left(); // linker Rand sichtbar
+ if ( aRect.Top() < 0 ) // oben raus
+ nScrollY = aRect.Top(); // oberer Rand sichtbar
+
+ if (nScrollX || nScrollY)
+ {
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( pDoc->IsNegativePage( nTab ) )
+ nScrollX = -nScrollX;
+
+ double nPPTX = aViewData.GetPPTX();
+ double nPPTY = aViewData.GetPPTY();
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ SCCOL nPosX = aViewData.GetPosX(WhichH(eWhich));
+ SCROW nPosY = aViewData.GetPosY(WhichV(eWhich));
+
+ long nLinesX=0, nLinesY=0; // Spalten/Zeilen - um mindestens nScrollX/Y scrollen
+
+ if (nScrollX > 0)
+ while (nScrollX > 0 && nPosX < MAXCOL)
+ {
+ nScrollX -= (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
+ ++nPosX;
+ ++nLinesX;
+ }
+ else if (nScrollX < 0)
+ while (nScrollX < 0 && nPosX > 0)
+ {
+ --nPosX;
+ nScrollX += (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
+ --nLinesX;
+ }
+
+ if (nScrollY > 0)
+ while (nScrollY > 0 && nPosY < MAXROW)
+ {
+ nScrollY -= (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
+ ++nPosY;
+ ++nLinesY;
+ }
+ else if (nScrollY < 0)
+ while (nScrollY < 0 && nPosY > 0)
+ {
+ --nPosY;
+ nScrollY += (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
+ --nLinesY;
+ }
+
+ ScrollLines( nLinesX, nLinesY ); // ausfuehren
+ }
+}
+
+//---------------------------------------------------------------
+
+void ScTabView::SetBrushDocument( ScDocument* pNew, BOOL bLock )
+{
+ delete pBrushDocument;
+ delete pDrawBrushSet;
+
+ pBrushDocument = pNew;
+ pDrawBrushSet = NULL;
+
+ bLockPaintBrush = bLock;
+
+ aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
+}
+
+void ScTabView::SetDrawBrushSet( SfxItemSet* pNew, BOOL bLock )
+{
+ delete pBrushDocument;
+ delete pDrawBrushSet;
+
+ pBrushDocument = NULL;
+ pDrawBrushSet = pNew;
+
+ bLockPaintBrush = bLock;
+
+ aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
+}
+
+void ScTabView::ResetBrushDocument()
+{
+ if ( HasPaintBrush() )
+ {
+ SetBrushDocument( NULL, FALSE );
+ SetActivePointer( Pointer( POINTER_ARROW ) ); // switch pointers also when ended with escape key
+ }
+}
+
+
diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx
new file mode 100644
index 000000000000..2fc2bba072d9
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/galbrws.hxx>
+#include <svx/imapdlg.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/templdlg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/app.hxx>
+#include <avmedia/mediaplayer.hxx>
+
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "reffact.hxx"
+#include "scresid.hxx"
+#include "dwfunctr.hxx"
+#include "sc.hrc" // -> SID_TOOL_xxx
+#include "drawattr.hxx" // -> SvxDrawToolItem
+#include "spelldialog.hxx"
+
+
+#define ScTabViewShell
+#include "scslots.hxx"
+
+#define SearchSettings
+#include <svx/svxslots.hxx>
+
+TYPEINIT2(ScTabViewShell,SfxViewShell,SfxListener);
+
+SFX_IMPL_INTERFACE(ScTabViewShell,SfxViewShell,ScResId(SCSTR_TABVIEWSHELL))
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_FULLSCREEN | SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_TOOLS) );
+
+ SFX_CHILDWINDOW_REGISTRATION(FID_INPUTLINE_STATUS);
+ SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR);
+ SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE);
+ SFX_CHILDWINDOW_REGISTRATION(ScNameDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSolverDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScOptSolverDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScPivotLayoutWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScTabOpDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFilterDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSpecialFilterDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScDbNameDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScConsolidateDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScPrintAreasDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScCondFormatDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScColRowNameRangesDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFormulaDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(SvxIMapDlgChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFunctionChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFormulaDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScAcceptChgDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScHighlightChgDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSimpleRefDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(SID_SEARCH_DLG);
+ SFX_CHILDWINDOW_REGISTRATION(SID_HYPERLINK_DIALOG);
+ SFX_CHILDWINDOW_REGISTRATION(GalleryChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSpellDialogChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION( ::avmedia::MediaPlayer::GetChildWindowId() );
+
+ //<!--Added by PengYunQuan for Validity Cell Range Picker
+ SFX_CHILDWINDOW_REGISTRATION(ScValidityRefChildWin::GetChildWindowId());
+ //-->Added by PengYunQuan for Validity Cell Range Picker
+}
+
+SFX_IMPL_NAMED_VIEWFACTORY( ScTabViewShell, "Default" )
+{
+ SFX_VIEW_REGISTRATION(ScDocShell);
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScTabViewShell, HtmlOptionsHdl, void*, EMPTYARG )
+{
+ // Invalidierung, falls blinkender Text erlaubt/verboten wurde
+ GetViewFrame()->GetBindings().Invalidate(SID_DRAW_TEXT_MARQUEE);
+ return 0;
+}
diff --git a/sc/source/ui/view/tabvwsh2.cxx b/sc/source/ui/view/tabvwsh2.cxx
new file mode 100644
index 000000000000..ca47535ad2cf
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh2.cxx
@@ -0,0 +1,481 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/aeitem.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include "tabvwsh.hxx"
+#include "drawattr.hxx"
+#include "drawsh.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+#include "fuconrec.hxx"
+#include "fuconpol.hxx"
+#include "fuconarc.hxx"
+#include "fuconuno.hxx"
+#include "fusel.hxx"
+#include "futext.hxx"
+#include "fumark.hxx"
+#include "fuinsert.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+
+// #98185# Create default drawing objects via keyboard
+#include <svx/svdpagv.hxx>
+#include <svl/stritem.hxx>
+#include <svx/svdpage.hxx>
+#include <fuconcustomshape.hxx>
+
+// -----------------------------------------------------------------------
+
+SdrView* __EXPORT ScTabViewShell::GetDrawView() const
+{
+ return ((ScTabViewShell*)this)->GetScDrawView(); // GetScDrawView ist nicht-const
+}
+
+void ScTabViewShell::WindowChanged()
+{
+ Window* pWin = GetActiveWin();
+
+ ScDrawView* pDrView = GetScDrawView();
+ if (pDrView)
+ pDrView->SetActualWin(pWin);
+
+ FuPoor* pFunc = GetDrawFuncPtr();
+ if (pFunc)
+ pFunc->SetWindow(pWin);
+
+ // when font from InputContext is used,
+ // this must be moved to change of cursor position:
+ UpdateInputContext();
+}
+
+void ScTabViewShell::ExecDraw(SfxRequest& rReq)
+{
+ SC_MOD()->InputEnterHandler();
+ UpdateInputHandler();
+
+ MakeDrawLayer();
+
+ ScTabView* pTabView = GetViewData()->GetView();
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+
+ Window* pWin = pTabView->GetActiveWin();
+ ScDrawView* pView = pTabView->GetScDrawView();
+ SdrModel* pDoc = pView->GetModel();
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ USHORT nNewId = rReq.GetSlot();
+
+ if ( nNewId == SID_DRAW_CHART )
+ {
+ // #i71254# directly insert a chart instead of drawing its output rectangle
+ FuInsertChart(this, pWin, pView, pDoc, rReq);
+ return;
+ }
+
+ //
+ // Pseudo-Slots von Draw-Toolbox auswerten
+ //! wird das ueberhaupt noch gebraucht ?????
+ //
+
+ if (nNewId == SID_INSERT_DRAW && pArgs)
+ {
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( SID_INSERT_DRAW, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SvxDrawToolItem ) )
+ {
+ SvxDrawToolEnum eSel = (SvxDrawToolEnum)((const SvxDrawToolItem*)pItem)->GetValue();
+ switch (eSel)
+ {
+ case SVX_SNAP_DRAW_SELECT: nNewId = SID_OBJECT_SELECT; break;
+ case SVX_SNAP_DRAW_LINE: nNewId = SID_DRAW_LINE; break;
+ case SVX_SNAP_DRAW_RECT: nNewId = SID_DRAW_RECT; break;
+ case SVX_SNAP_DRAW_ELLIPSE: nNewId = SID_DRAW_ELLIPSE; break;
+ case SVX_SNAP_DRAW_POLYGON_NOFILL: nNewId = SID_DRAW_POLYGON_NOFILL; break;
+ case SVX_SNAP_DRAW_BEZIER_NOFILL: nNewId = SID_DRAW_BEZIER_NOFILL; break;
+ case SVX_SNAP_DRAW_FREELINE_NOFILL: nNewId = SID_DRAW_FREELINE_NOFILL; break;
+ case SVX_SNAP_DRAW_ARC: nNewId = SID_DRAW_ARC; break;
+ case SVX_SNAP_DRAW_PIE: nNewId = SID_DRAW_PIE; break;
+ case SVX_SNAP_DRAW_CIRCLECUT: nNewId = SID_DRAW_CIRCLECUT; break;
+ case SVX_SNAP_DRAW_TEXT: nNewId = SID_DRAW_TEXT; break;
+ case SVX_SNAP_DRAW_TEXT_VERTICAL: nNewId = SID_DRAW_TEXT_VERTICAL; break;
+ case SVX_SNAP_DRAW_TEXT_MARQUEE: nNewId = SID_DRAW_TEXT_MARQUEE; break;
+ case SVX_SNAP_DRAW_CAPTION: nNewId = SID_DRAW_CAPTION; break;
+ case SVX_SNAP_DRAW_CAPTION_VERTICAL: nNewId = SID_DRAW_CAPTION_VERTICAL; break;
+ }
+ }
+ else // USHORT-Item vom Controller
+ {
+ rReq.Done();
+ return;
+ }
+ }
+
+ if ( nNewId == SID_DRAW_SELECT )
+ nNewId = SID_OBJECT_SELECT;
+
+ USHORT nNewFormId = 0;
+ if ( nNewId == SID_FM_CREATE_CONTROL && pArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( SID_FM_CONTROL_IDENTIFIER, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SfxUInt16Item ) )
+ nNewFormId = ((const SfxUInt16Item*)pItem)->GetValue();
+ }
+
+ String sStringItemValue;
+ if ( pArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( nNewId, TRUE, &pItem ) == SFX_ITEM_SET && pItem->ISA( SfxStringItem ) )
+ sStringItemValue = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ }
+ bool bSwitchCustom = ( sStringItemValue.Len() && sDrawCustom.Len() && sStringItemValue != sDrawCustom );
+
+ if (nNewId == SID_INSERT_FRAME) // vom Tbx-Button
+ nNewId = SID_DRAW_TEXT;
+
+ // #97016# CTRL-SID_OBJECT_SELECT is used to select the first object,
+ // but not if SID_OBJECT_SELECT is the result of clicking a create function again,
+ // so this must be tested before changing nNewId below.
+ BOOL bSelectFirst = ( nNewId == SID_OBJECT_SELECT && (rReq.GetModifier() & KEY_MOD1) );
+
+ BOOL bEx = IsDrawSelMode();
+ if ( rReq.GetModifier() & KEY_MOD1 )
+ {
+ // #97016# always allow keyboard selection also on background layer
+ // #98185# also allow creation of default objects if the same object type
+ // was already active
+ bEx = TRUE;
+ }
+ else if ( nNewId == nDrawSfxId && ( nNewId != SID_FM_CREATE_CONTROL ||
+ nNewFormId == nFormSfxId || nNewFormId == 0 ) && !bSwitchCustom )
+ {
+ // #i52871# if a different custom shape is selected, the slot id can be the same,
+ // so the custom shape type string has to be compared, too.
+
+ // SID_FM_CREATE_CONTROL mit nNewFormId==0 (ohne Parameter) kommt beim Deaktivieren
+ // aus FuConstruct::SimpleMouseButtonUp
+ // #59280# Execute fuer die Form-Shell, um im Controller zu deselektieren
+ if ( nNewId == SID_FM_CREATE_CONTROL )
+ {
+ GetViewData()->GetDispatcher().Execute(SID_FM_LEAVE_CREATE);
+ GetViewFrame()->GetBindings().InvalidateAll(FALSE);
+ //! was fuer einen Slot braucht der komische Controller wirklich, um das anzuzeigen????
+ }
+
+ bEx = !bEx;
+ nNewId = SID_OBJECT_SELECT;
+ }
+ else
+ bEx = TRUE;
+
+ if ( nDrawSfxId == SID_FM_CREATE_CONTROL && nNewId != nDrawSfxId )
+ {
+ // Wechsel von Control- zu Zeichenfunktion -> im Control-Controller deselektieren
+ GetViewData()->GetDispatcher().Execute(SID_FM_LEAVE_CREATE);
+ GetViewFrame()->GetBindings().InvalidateAll(FALSE);
+ //! was fuer einen Slot braucht der komische Controller wirklich, um das anzuzeigen????
+ }
+
+ SetDrawSelMode(bEx);
+
+ pView->LockBackgroundLayer( !bEx );
+
+ if ( bSelectFirst )
+ {
+ // #97016# select first draw object if none is selected yet
+ if(!pView->AreObjectsMarked())
+ {
+ // select first object
+ pView->UnmarkAllObj();
+ pView->MarkNextObj(TRUE);
+
+ // ...and make it visible
+ if(pView->AreObjectsMarked())
+ pView->MakeVisible(pView->GetAllMarkedRect(), *pWin);
+ }
+ }
+
+ nDrawSfxId = nNewId;
+ sDrawCustom.Erase(); // value is set below for custom shapes
+
+ if ( nNewId != SID_DRAW_CHART ) // Chart nicht mit DrawShell
+ {
+ if ( nNewId == SID_DRAW_TEXT || nNewId == SID_DRAW_TEXT_VERTICAL ||
+ nNewId == SID_DRAW_TEXT_MARQUEE || nNewId == SID_DRAW_NOTEEDIT )
+ SetDrawTextShell( TRUE );
+ else
+ {
+ if ( bEx || pView->GetMarkedObjectList().GetMarkCount() != 0 )
+ SetDrawShellOrSub();
+ else
+ SetDrawShell( FALSE );
+ }
+ }
+
+ if (pTabView->GetDrawFuncPtr())
+ {
+ if (pTabView->GetDrawFuncOldPtr() != pTabView->GetDrawFuncPtr())
+ delete pTabView->GetDrawFuncOldPtr();
+
+ pTabView->GetDrawFuncPtr()->Deactivate();
+ pTabView->SetDrawFuncOldPtr(pTabView->GetDrawFuncPtr());
+ pTabView->SetDrawFuncPtr(NULL);
+ }
+
+ SfxRequest aNewReq(rReq);
+ aNewReq.SetSlot(nDrawSfxId);
+
+ switch (nNewId)
+ {
+ case SID_OBJECT_SELECT:
+ //@#70206# Nicht immer zurueckschalten
+ if(pView->GetMarkedObjectList().GetMarkCount() == 0) SetDrawShell(bEx);
+ pTabView->SetDrawFuncPtr(new FuSelection(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_LINE:
+ case SID_DRAW_RECT:
+ case SID_DRAW_ELLIPSE:
+ pTabView->SetDrawFuncPtr(new FuConstRectangle(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_CAPTION:
+ case SID_DRAW_CAPTION_VERTICAL:
+ pTabView->SetDrawFuncPtr(new FuConstRectangle(this, pWin, pView, pDoc, aNewReq));
+ pView->SetFrameDragSingles( FALSE );
+ rBindings.Invalidate( SID_BEZIER_EDIT );
+ break;
+
+ case SID_DRAW_POLYGON:
+ case SID_DRAW_POLYGON_NOFILL:
+ case SID_DRAW_BEZIER_NOFILL:
+ case SID_DRAW_FREELINE_NOFILL:
+ pTabView->SetDrawFuncPtr(new FuConstPolygon(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_ARC:
+ case SID_DRAW_PIE:
+ case SID_DRAW_CIRCLECUT:
+ pTabView->SetDrawFuncPtr(new FuConstArc(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_TEXT:
+ case SID_DRAW_TEXT_VERTICAL:
+ case SID_DRAW_TEXT_MARQUEE:
+ case SID_DRAW_NOTEEDIT:
+ pTabView->SetDrawFuncPtr(new FuText(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_FM_CREATE_CONTROL:
+ SetDrawFormShell(TRUE);
+ pTabView->SetDrawFuncPtr(new FuConstUnoControl(this, pWin, pView, pDoc, aNewReq));
+ nFormSfxId = nNewFormId;
+ break;
+
+ case SID_DRAW_CHART:
+//UNUSED2008-05 bChartDlgIsEdit = FALSE;
+ pTabView->SetDrawFuncPtr(new FuMarkRect(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAWTBX_CS_BASIC :
+ case SID_DRAWTBX_CS_SYMBOL :
+ case SID_DRAWTBX_CS_ARROW :
+ case SID_DRAWTBX_CS_FLOWCHART :
+ case SID_DRAWTBX_CS_CALLOUT :
+ case SID_DRAWTBX_CS_STAR :
+ case SID_DRAW_CS_ID :
+ {
+ pTabView->SetDrawFuncPtr( new FuConstCustomShape( this, pWin, pView, pDoc, aNewReq ));
+ if ( nNewId != SID_DRAW_CS_ID )
+ {
+ SFX_REQUEST_ARG( rReq, pEnumCommand, SfxStringItem, nNewId, sal_False );
+ if ( pEnumCommand )
+ {
+ aCurrShapeEnumCommand[ nNewId - SID_DRAWTBX_CS_BASIC ] = pEnumCommand->GetValue();
+ SfxBindings& rBind = GetViewFrame()->GetBindings();
+ rBind.Invalidate( nNewId );
+ rBind.Update( nNewId );
+
+ sDrawCustom = pEnumCommand->GetValue(); // to detect when a different shape type is selected
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (pTabView->GetDrawFuncPtr())
+ pTabView->GetDrawFuncPtr()->Activate();
+
+ rReq.Done();
+
+ rBindings.Invalidate( SID_INSERT_DRAW );
+ rBindings.Update( SID_INSERT_DRAW );
+
+ // #98185# Create default drawing objects via keyboard
+ // with qualifier construct directly
+ FuPoor* pFuActual = GetDrawFuncPtr();
+
+ if(pFuActual && (rReq.GetModifier() & KEY_MOD1))
+ {
+ // #98185# Create default drawing objects via keyboard
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+ sal_uInt32 nDefaultObjectSizeWidth = rAppOpt.GetDefaultObjectSizeWidth();
+ sal_uInt32 nDefaultObjectSizeHeight = rAppOpt.GetDefaultObjectSizeHeight();
+
+ // calc position and size
+ Rectangle aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
+ Point aPagePos = aVisArea.Center();
+ aPagePos.X() -= nDefaultObjectSizeWidth / 2;
+ aPagePos.Y() -= nDefaultObjectSizeHeight / 2;
+ Rectangle aNewObjectRectangle(aPagePos, Size(nDefaultObjectSizeWidth, nDefaultObjectSizeHeight));
+
+ ScDrawView* pDrView = GetScDrawView();
+
+ if(pDrView)
+ {
+ SdrPageView* pPageView = pDrView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ // create the default object
+ SdrObject* pObj = pFuActual->CreateDefaultObject(nNewId, aNewObjectRectangle);
+
+ if(pObj)
+ {
+ // insert into page
+ pView->InsertObjectAtView(pObj, *pPageView);
+
+ if ( nNewId == SID_DRAW_CAPTION || nNewId == SID_DRAW_CAPTION_VERTICAL )
+ {
+ // #105815# use KeyInput to start edit mode (FuText is created).
+ // For FuText objects, edit mode is handled within CreateDefaultObject.
+ // KEY_F2 is handled in FuDraw::KeyInput.
+
+ pFuActual->KeyInput( KeyEvent( 0, KeyCode( KEY_F2 ) ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScTabViewShell::GetDrawState(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_INSERT_DRAW:
+ {
+ // SID_OBJECT_SELECT nur, wenn "harter" Selektionsmodus
+ USHORT nPutId = nDrawSfxId;
+ if ( nPutId == SID_OBJECT_SELECT && !IsDrawSelMode() )
+ nPutId = USHRT_MAX;
+ // nur die Images, die auch auf dem Controller liegen
+ if ( nPutId != SID_OBJECT_SELECT &&
+ nPutId != SID_DRAW_LINE &&
+ nPutId != SID_DRAW_RECT &&
+ nPutId != SID_DRAW_ELLIPSE &&
+ nPutId != SID_DRAW_POLYGON_NOFILL &&
+ nPutId != SID_DRAW_BEZIER_NOFILL &&
+ nPutId != SID_DRAW_FREELINE_NOFILL &&
+ nPutId != SID_DRAW_ARC &&
+ nPutId != SID_DRAW_PIE &&
+ nPutId != SID_DRAW_CIRCLECUT &&
+ nPutId != SID_DRAW_TEXT &&
+ nPutId != SID_DRAW_TEXT_VERTICAL &&
+ nPutId != SID_DRAW_TEXT_MARQUEE &&
+ nPutId != SID_DRAW_CAPTION &&
+ nPutId != SID_DRAW_CAPTION_VERTICAL )
+ nPutId = USHRT_MAX;
+ SfxAllEnumItem aItem( nWhich, nPutId );
+ if ( !SvtLanguageOptions().IsVerticalTextEnabled() )
+ {
+ aItem.DisableValue( SID_DRAW_TEXT_VERTICAL );
+ aItem.DisableValue( SID_DRAW_CAPTION_VERTICAL );
+ }
+ rSet.Put( aItem );
+ }
+ break;
+
+ case SID_DRAW_CHART:
+ {
+ BOOL bOle = GetViewFrame()->GetFrame().IsInPlace();
+ if ( bOle || !SvtModuleOptions().IsChart() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_OBJECT_SELECT: // wichtig fuer den ollen Control-Controller
+ rSet.Put( SfxBoolItem( nWhich, nDrawSfxId == SID_OBJECT_SELECT && IsDrawSelMode() ) );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+BOOL ScTabViewShell::SelectObject( const String& rName )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+ if (!pView)
+ return FALSE;
+
+ BOOL bFound = pView->SelectObject( rName );
+ // DrawShell etc. is handled in MarkListHasChanged
+
+ return bFound;
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx
new file mode 100644
index 000000000000..c291d01d71c2
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh3.cxx
@@ -0,0 +1,1234 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+//CHINA001 #include <svx/zoom.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/passwd.hxx>
+#include <sfx2/request.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <tools/urlobj.hxx>
+
+#include <vcl/msgbox.hxx>
+#include <vcl/vclenum.hxx>
+
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "inputwin.hxx"
+#include "scresid.hxx"
+#include "printfun.hxx"
+#include "docsh.hxx"
+#include "rangelst.hxx"
+#include "prevwsh.hxx"
+#include "rangeutl.hxx"
+#include "reffact.hxx"
+#include "uiitems.hxx"
+#include "cell.hxx"
+#include "inputhdl.hxx"
+//CHINA001 #include "scendlg.hxx"
+//CHINA001 #include "mtrindlg.hxx"
+#include "autoform.hxx"
+#include "autofmt.hxx"
+#include "dwfunctr.hxx"
+#include "shtabdlg.hxx"
+#include "tabprotection.hxx"
+#include "protectiondlg.hxx"
+
+#include <svl/ilstitem.hxx>
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+
+#include <svx/zoomslideritem.hxx>
+#include <svx/svxdlg.hxx> //CHINA001
+#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)
+#define GET_STRING(nid) ((const SfxStringItem&)pReqArgs->Get(nid)).GetValue()
+#define GET_UINT16(nid) ((const SfxUInt16Item&)pReqArgs->Get(nid)).GetValue()
+#define GET_BOOL(nid) ((const SfxBoolItem&)pReqArgs->Get(nid)).GetValue()
+#define RECALC_PAGE(pDocSh) ScPrintFunc( pDocSh, GetPrinter(), nCurTab ).UpdatePages()
+
+//------------------------------------------------------------------
+
+/** Try to parse the given range using Calc-style syntax first, then
+ Excel-style if that fails. */
+USHORT lcl_ParseRange(ScRange& rScRange, const String& aAddress, ScDocument* pDoc, USHORT /* nSlot */)
+{
+ USHORT nResult = rScRange.Parse(aAddress, pDoc);
+ if ( (nResult & SCA_VALID) )
+ return nResult;
+
+ return rScRange.Parse(aAddress, pDoc, ScAddress::Details(formula::FormulaGrammar::CONV_XL_A1, 0, 0));
+}
+
+/** Try to parse the given address using Calc-style syntax first, then
+ Excel-style if that fails. */
+USHORT lcl_ParseAddress(ScAddress& rScAddress, const String& aAddress, ScDocument* pDoc, USHORT /* nSlot */)
+{
+ USHORT nResult = rScAddress.Parse(aAddress, pDoc);
+ if ( (nResult & SCA_VALID) )
+ return nResult;
+
+ return rScAddress.Parse(aAddress, pDoc, ScAddress::Details(formula::FormulaGrammar::CONV_XL_A1, 0, 0));
+}
+
+void ScTabViewShell::Execute( SfxRequest& rReq )
+{
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ SfxBindings& rBindings = pThisFrame->GetBindings();
+ ScModule* pScMod = SC_MOD();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+
+ if (nSlot != SID_CURRENTCELL) // der kommt beim MouseButtonUp
+ HideListBox(); // Autofilter-DropDown-Listbox
+
+ switch ( nSlot )
+ {
+ case FID_INSERT_FILE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(FID_INSERT_FILE,TRUE,&pItem) == SFX_ITEM_SET )
+ {
+ String aFileName = ((const SfxStringItem*)pItem)->GetValue();
+
+ // Einfuege-Position
+
+ Point aInsertPos;
+ if ( pReqArgs->GetItemState(FN_PARAM_1,TRUE,&pItem) == SFX_ITEM_SET )
+ aInsertPos = ((const SfxPointItem*)pItem)->GetValue();
+ else
+ aInsertPos = GetInsertPos();
+
+ // als Link?
+
+ BOOL bAsLink = FALSE;
+ if ( pReqArgs->GetItemState(FN_PARAM_2,TRUE,&pItem) == SFX_ITEM_SET )
+ bAsLink = ((const SfxBoolItem*)pItem)->GetValue();
+
+ // ausfuehren
+
+ PasteFile( aInsertPos, aFileName, bAsLink );
+ }
+ }
+ break;
+
+ case SID_OPENDLG_EDIT_PRINTAREA:
+ {
+ USHORT nId = ScPrintAreasDlgWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case SID_CHANGE_PRINTAREA:
+ {
+ if ( pReqArgs ) // OK aus Dialog
+ {
+ String aPrintStr;
+ String aRowStr;
+ String aColStr;
+ BOOL bEntire = FALSE;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_CHANGE_PRINTAREA, TRUE, &pItem ) == SFX_ITEM_SET )
+ aPrintStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_2, TRUE, &pItem ) == SFX_ITEM_SET )
+ aRowStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_3, TRUE, &pItem ) == SFX_ITEM_SET )
+ aColStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_4, TRUE, &pItem ) == SFX_ITEM_SET )
+ bEntire = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
+ SetPrintRanges( bEntire, &aPrintStr, &aColStr, &aRowStr, FALSE );
+
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_ADD_PRINTAREA:
+ case SID_DEFINE_PRINTAREA: // Menue oder Basic
+ {
+ BOOL bAdd = ( nSlot == SID_ADD_PRINTAREA );
+ if ( pReqArgs )
+ {
+ String aPrintStr;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_DEFINE_PRINTAREA, TRUE, &pItem ) == SFX_ITEM_SET )
+ aPrintStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ SetPrintRanges( FALSE, &aPrintStr, NULL, NULL, bAdd );
+ }
+ else
+ {
+ SetPrintRanges( FALSE, NULL, NULL, NULL, bAdd ); // aus Selektion
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_DELETE_PRINTAREA:
+ {
+ String aEmpty;
+ SetPrintRanges( FALSE, &aEmpty, NULL, NULL, FALSE ); // Druckbereich loeschen
+ rReq.Done();
+ }
+ break;
+
+ case FID_DEL_MANUALBREAKS:
+ RemoveManualBreaks();
+ rReq.Done();
+ break;
+
+ case FID_ADJUST_PRINTZOOM:
+ AdjustPrintZoom();
+ rReq.Done();
+ break;
+
+ case FID_RESET_PRINTZOOM:
+ SetPrintZoom( 100, 0 ); // 100%, nicht auf Seiten
+ rReq.Done();
+ break;
+
+ case SID_FORMATPAGE:
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ GetViewData()->GetDocShell()->
+ ExecutePageStyle( *this, rReq, GetViewData()->GetTabNo() );
+ break;
+
+ case SID_JUMPTOMARK:
+ case SID_CURRENTCELL:
+ if ( pReqArgs )
+ {
+ String aAddress;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ aAddress = ((const SfxStringItem*)pItem)->GetValue();
+ else if ( nSlot == SID_JUMPTOMARK && pReqArgs->GetItemState(
+ SID_JUMPTOMARK, TRUE, &pItem ) == SFX_ITEM_SET )
+ aAddress = ((const SfxStringItem*)pItem)->GetValue();
+
+ // #i14927# SID_CURRENTCELL with a single cell must unmark if FN_PARAM_1
+ // isn't set (for recorded macros, because IsAPI is no longer available).
+ // ScGridWindow::MouseButtonUp no longer executes the slot for a single
+ // cell if there is a multi selection.
+ BOOL bUnmark = ( nSlot == SID_CURRENTCELL );
+ if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
+ bUnmark = ((const SfxBoolItem*)pItem)->GetValue();
+
+ if ( nSlot == SID_JUMPTOMARK )
+ {
+ // #106586# URL has to be decoded for escaped characters (%20)
+ aAddress = INetURLObject::decode( aAddress, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_WITH_CHARSET,
+ RTL_TEXTENCODING_UTF8 );
+ }
+
+ BOOL bFound = FALSE;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ ScRange aScRange;
+ ScAddress aScAddress;
+ USHORT nResult = lcl_ParseRange(aScRange, aAddress, pDoc, nSlot);
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bMark = TRUE;
+
+ // Is this a range ?
+ if( nResult & SCA_VALID )
+ {
+ if ( nResult & SCA_TAB_3D )
+ {
+ if( aScRange.aStart.Tab() != nTab )
+ SetTabNo( nTab = aScRange.aStart.Tab() );
+ }
+ else
+ {
+ aScRange.aStart.SetTab( nTab );
+ aScRange.aEnd.SetTab( nTab );
+ }
+ }
+ // Is this a cell ?
+ else if ( (nResult = lcl_ParseAddress(aScAddress, aAddress, pDoc, nSlot)) & SCA_VALID )
+ {
+ if ( nResult & SCA_TAB_3D )
+ {
+ if( aScAddress.Tab() != nTab )
+ SetTabNo( nTab = aScAddress.Tab() );
+ }
+ else
+ aScAddress.SetTab( nTab );
+
+ aScRange = ScRange( aScAddress, aScAddress );
+ // Zellen sollen nicht markiert werden
+ bMark = FALSE;
+ }
+ // Ist es benahmster Bereich (erst Namen dann DBBereiche) ?
+ else
+ {
+ ScRangeUtil aRangeUtil;
+ formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ if( aRangeUtil.MakeRangeFromName( aAddress, pDoc, nTab, aScRange, RUTL_NAMES, eConv ) ||
+ aRangeUtil.MakeRangeFromName( aAddress, pDoc, nTab, aScRange, RUTL_DBASE, eConv ) )
+ {
+ nResult |= SCA_VALID;
+ if( aScRange.aStart.Tab() != nTab )
+ SetTabNo( nTab = aScRange.aStart.Tab() );
+ }
+ }
+
+ if ( !(nResult & SCA_VALID) &&
+ ByteString(aAddress, RTL_TEXTENCODING_ASCII_US).IsNumericAscii() )
+ {
+ sal_Int32 nNumeric = aAddress.ToInt32();
+ if ( nNumeric > 0 && nNumeric <= MAXROW+1 )
+ {
+ // 1-basierte Zeilennummer
+
+ aScAddress.SetRow( (SCROW)(nNumeric - 1) );
+ aScAddress.SetCol( pViewData->GetCurX() );
+ aScAddress.SetTab( nTab );
+ aScRange = ScRange( aScAddress, aScAddress );
+ bMark = FALSE;
+ nResult = SCA_VALID;
+ }
+ }
+
+ if ( !ValidRow(aScRange.aStart.Row()) || !ValidRow(aScRange.aEnd.Row()) )
+ nResult = 0;
+
+ // wir haben was gefunden
+ if( nResult & SCA_VALID )
+ {
+ bFound = TRUE;
+ SCCOL nCol = aScRange.aStart.Col();
+ SCROW nRow = aScRange.aStart.Row();
+ BOOL bNothing = ( pViewData->GetCurX()==nCol && pViewData->GetCurY()==nRow );
+
+ // markieren
+ if( bMark )
+ {
+ if (rMark.IsMarked()) // ist derselbe Bereich schon markiert?
+ {
+ ScRange aOldMark;
+ rMark.GetMarkArea( aOldMark );
+ aOldMark.Justify();
+ ScRange aCurrent = aScRange;
+ aCurrent.Justify();
+ bNothing = ( aCurrent == aOldMark );
+ }
+ else
+ bNothing = FALSE;
+
+ if (!bNothing)
+ MarkRange( aScRange, FALSE ); // Cursor kommt hinterher...
+ }
+ else
+ {
+ // remove old selection, unless bUnmark argument is FALSE (from navigator)
+ if( bUnmark )
+ {
+ MoveCursorAbs( nCol, nRow,
+ SC_FOLLOW_NONE, FALSE, FALSE );
+ }
+ }
+
+ // und Cursor setzen
+
+ // zusammengefasste Zellen beruecksichtigen:
+ while ( pDoc->IsHorOverlapped( nCol, nRow, nTab ) ) //! ViewData !!!
+ --nCol;
+ while ( pDoc->IsVerOverlapped( nCol, nRow, nTab ) )
+ --nRow;
+
+ // Navigator-Aufrufe sind nicht API!!!
+
+ if( bNothing )
+ {
+ if (rReq.IsAPI())
+ rReq.Ignore(); // wenn Makro, dann gar nix
+ else
+ rReq.Done(); // sonst wenigstens aufzeichnen
+ }
+ else
+ {
+ pViewData->ResetOldCursor();
+ SetCursor( nCol, nRow );
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+ rBindings.Invalidate( SID_CURRENTCELL );
+ rBindings.Update( nSlot );
+
+ if (!rReq.IsAPI())
+ rReq.Done();
+ }
+
+ rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) );
+ }
+
+ if (!bFound) // kein gueltiger Bereich
+ {
+ // wenn es ein Tabellenname ist, umschalten (fuer Navigator/URL's)
+
+ SCTAB nNameTab;
+ if ( pDoc->GetTable( aAddress, nNameTab ) )
+ {
+ bFound = TRUE;
+ if ( nNameTab != nTab )
+ SetTabNo( nNameTab );
+ }
+ }
+
+ if ( !bFound && nSlot == SID_JUMPTOMARK )
+ {
+ // Grafik-Objekte probieren (nur bei URL's)
+
+ bFound = SelectObject( aAddress );
+ }
+
+ if (!bFound && !rReq.IsAPI())
+ ErrorMessage( STR_ERR_INVALID_AREA );
+ }
+ break;
+
+ case SID_CURRENTOBJECT:
+ if ( pReqArgs )
+ {
+ String aName = ((const SfxStringItem&)pReqArgs->Get(nSlot)).GetValue();
+ SelectObject( aName );
+ }
+ break;
+
+ case SID_CURRENTTAB:
+ if ( pReqArgs )
+ {
+ // Tabelle fuer Basic ist 1-basiert
+ SCTAB nTab = ((const SfxUInt16Item&)pReqArgs->Get(nSlot)).GetValue() - 1;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( nTab < pDoc->GetTableCount() )
+ {
+ SetTabNo( nTab );
+ rBindings.Update( nSlot );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ //! sonst Fehler ?
+ }
+ break;
+
+ case SID_CURRENTDOC:
+ if ( pReqArgs )
+ {
+ String aStrDocName( ((const SfxStringItem&)pReqArgs->
+ Get(nSlot)).GetValue() );
+
+ SfxViewFrame* pViewFrame = NULL;
+ ScDocShell* pDocSh = (ScDocShell*)SfxObjectShell::GetFirst();
+ BOOL bFound = FALSE;
+
+ // zu aktivierenden ViewFrame suchen
+
+ while ( pDocSh && !bFound )
+ {
+ if ( pDocSh->GetTitle() == aStrDocName )
+ {
+ pViewFrame = SfxViewFrame::GetFirst( pDocSh );
+ bFound = ( NULL != pViewFrame );
+ }
+
+ pDocSh = (ScDocShell*)SfxObjectShell::GetNext( *pDocSh );
+ }
+
+ if ( bFound )
+ pViewFrame->GetFrame().Appear();
+
+ rReq.Ignore();//XXX wird von SFX erledigt
+ }
+
+ case SID_ATTR_SIZE://XXX ???
+ break;
+
+
+ case SID_PRINTPREVIEW:
+ {
+ if ( !pThisFrame->GetFrame().IsInPlace() ) // nicht bei OLE
+ {
+ // print preview is now always in the same frame as the tab view
+ // -> always switch this frame back to normal view
+ // (ScPreviewShell ctor reads view data)
+
+ // #102785#; finish input
+ pScMod->InputEnterHandler();
+
+ pThisFrame->GetDispatcher()->Execute( SID_VIEWSHELL1, SFX_CALLMODE_ASYNCHRON );
+ }
+ // else Fehler (z.B. Ole)
+ }
+ break;
+
+ case SID_DETECTIVE_DEL_ALL:
+ DetectiveDelAll();
+ rReq.Done();
+ break;
+
+ // SID_TABLE_ACTIVATE und SID_MARKAREA werden von Basic aus an der versteckten
+ // View aufgerufen, um auf der sichtbaren View zu markieren/umzuschalten:
+
+ case SID_TABLE_ACTIVATE:
+ DBG_ERROR("old slot SID_TABLE_ACTIVATE");
+ break;
+
+ case SID_REPAINT:
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ PaintExtras();
+ rReq.Done();
+ break;
+
+ case FID_NORMALVIEWMODE:
+ case FID_PAGEBREAKMODE:
+ {
+ BOOL bWantPageBreak = nSlot == FID_PAGEBREAKMODE;
+
+ // check whether there is an explicit argument, use it
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET )
+ {
+ BOOL bItemValue = ((const SfxBoolItem*)pItem)->GetValue();
+ bWantPageBreak = (nSlot == FID_PAGEBREAKMODE) == bItemValue;
+ }
+
+ if( GetViewData()->IsPagebreakMode() != bWantPageBreak )
+ {
+ SetPagebreakMode( bWantPageBreak );
+ UpdatePageBreakData();
+ SetCurSubShell( GetCurObjectSelectionType(), TRUE );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ rBindings.Invalidate( nSlot );
+ rReq.AppendItem( SfxBoolItem( nSlot, TRUE ) );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case FID_FUNCTION_BOX:
+ {
+ USHORT nChildId = ScFunctionChildWindow::GetChildWindowId();
+ if ( rReq.GetArgs() )
+ pThisFrame->SetChildWindow( nChildId, ((const SfxBoolItem&) (rReq.GetArgs()->Get(FID_FUNCTION_BOX))).GetValue());
+ else
+ {
+ pThisFrame->ToggleChildWindow( nChildId );
+ rReq.AppendItem( SfxBoolItem( FID_FUNCTION_BOX , pThisFrame->HasChildWindow( nChildId ) ) );
+ }
+
+ GetViewFrame()->GetBindings().Invalidate(FID_FUNCTION_BOX);
+ rReq.Done ();
+ }
+ break;
+
+
+ case FID_TOGGLESYNTAX:
+ {
+ BOOL bSet = !GetViewData()->IsSyntaxMode();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+ GetViewData()->SetSyntaxMode( bSet );
+ PaintGrid();
+ rBindings.Invalidate( FID_TOGGLESYNTAX );
+ rReq.AppendItem( SfxBoolItem( nSlot, bSet ) );
+ rReq.Done();
+ }
+ break;
+ case FID_TOGGLEHEADERS:
+ {
+ BOOL bSet = !GetViewData()->IsHeaderMode();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+ GetViewData()->SetHeaderMode( bSet );
+ RepeatResize();
+ rBindings.Invalidate( FID_TOGGLEHEADERS );
+ rReq.AppendItem( SfxBoolItem( nSlot, bSet ) );
+ rReq.Done();
+ }
+ break;
+
+ case FID_TOGGLEFORMULA:
+ {
+ ScViewData* pViewData = GetViewData();
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ BOOL bFormulaMode = !rOpts.GetOption( VOPT_FORMULAS );
+ const SfxPoolItem *pItem;
+ if( pReqArgs && pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET )
+ bFormulaMode = ((const SfxBoolItem *)pItem)->GetValue();
+
+ ScViewOptions rSetOpts = ScViewOptions( rOpts );
+ rSetOpts.SetOption( VOPT_FORMULAS, bFormulaMode );
+ pViewData->SetOptions( rSetOpts );
+
+ pViewData->GetDocShell()->PostPaintGridAll();
+
+ rBindings.Invalidate( FID_TOGGLEFORMULA );
+ rReq.AppendItem( SfxBoolItem( nSlot, bFormulaMode ) );
+ rReq.Done();
+ }
+ break;
+
+ case FID_TOGGLEINPUTLINE:
+ {
+ USHORT nId = ScInputWindowWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+ BOOL bSet = ( pWnd == NULL );
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, TRUE, &pItem) == SFX_ITEM_SET )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+
+ pThisFrame->SetChildWindow( nId, bSet );
+ rBindings.Invalidate( FID_TOGGLEINPUTLINE );
+ rReq.AppendItem( SfxBoolItem( nSlot, bSet ) );
+ rReq.Done();
+ }
+ break;
+
+ case SID_ATTR_ZOOM: // Statuszeile
+ case FID_SCALE:
+ {
+ BOOL bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
+ SvxZoomType eOldZoomType = GetZoomType();
+ SvxZoomType eNewZoomType = eOldZoomType;
+ const Fraction& rOldY = GetViewData()->GetZoomY(); // Y wird angezeigt
+ USHORT nOldZoom = (USHORT)(( rOldY.GetNumerator() * 100 )
+ / rOldY.GetDenominator());
+ USHORT nZoom = nOldZoom;
+ BOOL bCancel = FALSE;
+
+ if ( pReqArgs )
+ {
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pReqArgs->Get(SID_ATTR_ZOOM);
+
+ eNewZoomType = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+ else
+ {
+ SfxItemSet aSet ( GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM );
+ SvxZoomItem aZoomItem( eOldZoomType, nOldZoom, SID_ATTR_ZOOM );
+ //CHINA001 SvxZoomDialog* pDlg = NULL;
+ AbstractSvxZoomDialog* pDlg = NULL;
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ USHORT nBtnFlags = SVX_ZOOM_ENABLE_50
+ | SVX_ZOOM_ENABLE_75
+ | SVX_ZOOM_ENABLE_100
+ | SVX_ZOOM_ENABLE_150
+ | SVX_ZOOM_ENABLE_200
+ | SVX_ZOOM_ENABLE_WHOLEPAGE
+ | SVX_ZOOM_ENABLE_PAGEWIDTH;
+
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ nBtnFlags = nBtnFlags | SVX_ZOOM_ENABLE_OPTIMAL;
+
+ aZoomItem.SetValueSet( nBtnFlags );
+ aSet.Put( aZoomItem );
+ //CHINA001 pDlg = new SvxZoomDialog( GetDialogParent(), aSet );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ pDlg = pFact->CreateSvxZoomDialog(GetDialogParent(), aSet );
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ }
+ pDlg->SetLimits( MINZOOM, MAXZOOM );
+
+ bCancel = ( RET_CANCEL == pDlg->Execute() );
+
+ if ( !bCancel )
+ {
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pDlg->GetOutputItemSet()->
+ Get( SID_ATTR_ZOOM );
+
+ eNewZoomType = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+
+ delete pDlg;
+ }
+
+ if ( !bCancel )
+ {
+ if ( eNewZoomType == SVX_ZOOM_PERCENT )
+ {
+ if ( nZoom < MINZOOM ) nZoom = MINZOOM;
+ if ( nZoom > MAXZOOM ) nZoom = MAXZOOM;
+ }
+ else
+ {
+ nZoom = CalcZoom( eNewZoomType, nOldZoom );
+ bCancel = nZoom == 0;
+ }
+
+ switch ( eNewZoomType )
+ {
+ case SVX_ZOOM_WHOLEPAGE:
+ case SVX_ZOOM_PAGEWIDTH:
+ SetZoomType( eNewZoomType, bSyncZoom );
+ break;
+
+ default:
+ SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
+ }
+ }
+
+ if ( nZoom != nOldZoom && !bCancel )
+ {
+ if (!GetViewData()->IsPagebreakMode())
+ {
+ ScAppOptions aNewOpt = pScMod->GetAppOptions();
+ aNewOpt.SetZoom( nZoom );
+ aNewOpt.SetZoomType( GetZoomType() );
+ pScMod->SetAppOptions( aNewOpt );
+ }
+ Fraction aFract( nZoom, 100 );
+ SetZoom( aFract, aFract, bSyncZoom );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ rBindings.Invalidate( SID_ATTR_ZOOM );
+ rReq.AppendItem( SvxZoomItem( GetZoomType(), nZoom, nSlot ) );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ const SfxPoolItem* pItem = NULL;
+ BOOL bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
+ if ( pReqArgs && pReqArgs->GetItemState(SID_ATTR_ZOOMSLIDER, TRUE, &pItem) == SFX_ITEM_SET )
+ {
+ const USHORT nCurrentZoom = ((const SvxZoomSliderItem *)pItem)->GetValue();
+ if( nCurrentZoom )
+ {
+ SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
+ if (!GetViewData()->IsPagebreakMode())
+ {
+ ScAppOptions aNewOpt = pScMod->GetAppOptions();
+ aNewOpt.SetZoom( nCurrentZoom );
+ aNewOpt.SetZoomType( GetZoomType() );
+ pScMod->SetAppOptions( aNewOpt );
+ }
+ Fraction aFract( nCurrentZoom,100 );
+ SetZoom( aFract, aFract, bSyncZoom );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //----------------------------------------------------------------
+
+ case FID_TAB_SELECTALL:
+ SelectAllTables();
+ rReq.Done();
+ break;
+
+ case FID_TAB_DESELECTALL:
+ DeselectAllTables();
+ rReq.Done();
+ break;
+
+ case SID_SELECT_TABLES:
+ {
+ ScViewData& rViewData = *GetViewData();
+ ScDocument& rDoc = *rViewData.GetDocument();
+ ScMarkData& rMark = rViewData.GetMarkData();
+ SCTAB nTabCount = rDoc.GetTableCount();
+ SCTAB nTab;
+
+ SvULongs aIndexList( 4, 4 );
+ SFX_REQUEST_ARG( rReq, pItem, SfxIntegerListItem, SID_SELECT_TABLES, sal_False );
+ if ( pItem )
+ pItem->GetList( aIndexList );
+ else
+ {
+ //CHINA001 ScShowTabDlg* pDlg = new ScShowTabDlg( GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScShowTabDlg* pDlg = pFact->CreateScShowTabDlg( GetDialogParent(), RID_SCDLG_SHOW_TAB);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetDescription(
+ String( ScResId( STR_DLG_SELECTTABLES_TITLE ) ),
+ String( ScResId( STR_DLG_SELECTTABLES_LBNAME ) ),
+ SID_SELECT_TABLES, HID_SELECTTABLES );
+
+ // fill all table names with selection state
+ String aTabName;
+ for( nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ rDoc.GetName( nTab, aTabName );
+ pDlg->Insert( aTabName, rMark.GetTableSelect( nTab ) );
+ }
+
+ if( pDlg->Execute() == RET_OK )
+ {
+ sal_uInt16 nSelCount = pDlg->GetSelectEntryCount();
+ sal_uInt16 nSelIx;
+ for( nSelIx = 0; nSelIx < nSelCount; ++nSelIx )
+ aIndexList.Insert( pDlg->GetSelectEntryPos( nSelIx ), nSelIx );
+ delete pDlg;
+ rReq.AppendItem( SfxIntegerListItem( SID_SELECT_TABLES, aIndexList ) );
+ }
+ else
+ rReq.Ignore();
+ }
+
+ if ( aIndexList.Count() )
+ {
+ sal_uInt16 nSelCount = aIndexList.Count();
+ sal_uInt16 nSelIx;
+ SCTAB nFirstVisTab = 0;
+
+ // special case: only hidden tables selected -> do nothing
+ sal_Bool bVisSelected = sal_False;
+ for( nSelIx = 0; !bVisSelected && (nSelIx < nSelCount); ++nSelIx )
+ bVisSelected = rDoc.IsVisible( nFirstVisTab = static_cast<SCTAB>(aIndexList[nSelIx]) );
+ if( !bVisSelected )
+ nSelCount = 0;
+
+ // select the tables
+ if( nSelCount )
+ {
+ for( nTab = 0; nTab < nTabCount; ++nTab )
+ rMark.SelectTable( nTab, sal_False );
+
+ for( nSelIx = 0; nSelIx < nSelCount; ++nSelIx )
+ rMark.SelectTable( static_cast<SCTAB>(aIndexList[nSelIx]), sal_True );
+
+ // activate another table, if current is deselected
+ if( !rMark.GetTableSelect( rViewData.GetTabNo() ) )
+ {
+ rMark.SelectTable( nFirstVisTab, sal_True );
+ SetTabNo( nFirstVisTab );
+ }
+
+ rViewData.GetDocShell()->PostPaintExtras();
+ SfxBindings& rBind = rViewData.GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+ }
+
+ rReq.Done();
+ }
+ }
+ break;
+
+
+ case SID_OUTLINE_DELETEALL:
+ RemoveAllOutlines();
+ rReq.Done();
+ break;
+
+ case SID_AUTO_OUTLINE:
+ AutoOutline();
+ rReq.Done();
+ break;
+
+
+ case SID_WINDOW_SPLIT:
+ {
+ ScSplitMode eHSplit = GetViewData()->GetHSplitMode();
+ ScSplitMode eVSplit = GetViewData()->GetVSplitMode();
+ if ( eHSplit == SC_SPLIT_NORMAL || eVSplit == SC_SPLIT_NORMAL ) // aufheben
+ RemoveSplit();
+ else if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX ) // normal
+ FreezeSplitters( FALSE );
+ else // erzeugen
+ SplitAtCursor();
+ rReq.Done();
+
+ InvalidateSplit();
+ }
+ break;
+
+ case SID_WINDOW_FIX:
+ {
+ ScSplitMode eHSplit = GetViewData()->GetHSplitMode();
+ ScSplitMode eVSplit = GetViewData()->GetVSplitMode();
+ if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX ) // aufheben
+ RemoveSplit();
+ else
+ FreezeSplitters( TRUE ); // erzeugen oder fixieren
+ rReq.Done();
+
+ InvalidateSplit();
+ }
+ break;
+
+ // ----------------------------------------------------------------
+
+ case FID_CHG_SHOW:
+ {
+ USHORT nId = ScHighlightChgDlgWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ }
+ break;
+
+ case FID_CHG_ACCEPT:
+ {
+ pThisFrame->ToggleChildWindow(ScAcceptChgDlgWrapper::GetChildWindowId());
+ GetViewFrame()->GetBindings().Invalidate(FID_CHG_ACCEPT);
+ rReq.Done ();
+
+ /*
+ USHORT nId = ScAcceptChgDlgWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
+ */
+ }
+ break;
+
+ case FID_CHG_COMMENT:
+ {
+ ScViewData* pData = GetViewData();
+ ScAddress aCursorPos( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+ ScDocShell* pDocSh = pData->GetDocShell();
+
+ ScChangeAction* pAction = pDocSh->GetChangeAction( aCursorPos );
+ if ( pAction )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SfxStringItem ) )
+ {
+ String aComment = ((const SfxStringItem*)pItem)->GetValue();
+ pDocSh->SetChangeComment( pAction, aComment );
+ rReq.Done();
+ }
+ else
+ {
+ pDocSh->ExecuteChangeCommentDialog( pAction, GetDialogParent() );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case SID_CREATE_SW_DRAWVIEW:
+ // wird von den Forms gerufen, wenn die DrawView mit allem Zubehoer
+ // angelegt werden muss
+ if (!GetScDrawView())
+ {
+ GetViewData()->GetDocShell()->MakeDrawLayer();
+ rBindings.InvalidateAll(FALSE);
+ }
+ break;
+
+ case FID_PROTECT_DOC:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxPasswordDialog* pDlg;
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_PROTECT_DOC, &pItem ) &&
+ ((const SfxBoolItem*)pItem)->GetValue() == pDoc->IsDocProtected() )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
+
+ ScDocProtection* pProtect = pDoc->GetDocProtection();
+ if (pProtect && pProtect->isProtected())
+ {
+ BOOL bCancel = FALSE;
+ String aPassword;
+
+ if (pProtect->isProtectedWithPass())
+ {
+ String aText( ScResId(SCSTR_PASSWORD) );
+
+ pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTDOC) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_DOC );
+ pDlg->SetEditHelpId( HID_PASSWD_DOC );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+ else
+ bCancel = TRUE;
+ delete pDlg;
+ }
+ if (!bCancel)
+ {
+ Unprotect( TABLEID_DOC, aPassword );
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_DOC, FALSE ) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+
+ pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
+ pDlg->SetText( ScResId(SCSTR_PROTECTDOC) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_DOC );
+ pDlg->SetEditHelpId( HID_PASSWD_DOC );
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ String aPassword = pDlg->GetPassword();
+ Protect( TABLEID_DOC, aPassword );
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_DOC, TRUE ) );
+ rReq.Done();
+ }
+
+ delete pDlg;
+ }
+ rBindings.Invalidate( FID_PROTECT_DOC );
+ }
+ break;
+
+
+ case FID_PROTECT_TABLE:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ bool bOldProtection = pDoc->IsTabProtected(nTab);
+
+#if ENABLE_SHEET_PROTECTION
+
+ if( pReqArgs )
+ {
+ 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 (bOldProtection)
+ {
+ // Unprotect a protected sheet.
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
+ {
+ 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)
+ {
+ String aPassword = pDlg->GetPassword();
+ Unprotect(nTab, aPassword);
+ }
+ }
+ else
+ // this sheet is not password-protected.
+ Unprotect(nTab, String());
+
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ // Protect a current sheet.
+
+ auto_ptr<ScTableProtectionDlg> pDlg(new ScTableProtectionDlg(GetDialogParent()));
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect)
+ pDlg->SetDialogData(*pProtect);
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ pScMod->InputEnterHandler();
+
+ 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( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
+
+ if ( bOldProtection)
+ {
+ // Unprotect a protected sheet.
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
+ {
+ 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
+ bCancel = TRUE;
+ }
+
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+
+ 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 );
+ }
+
+ if( !pReqArgs )
+ {
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
+ rReq.Done();
+ }
+ }
+#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
+ PaintGrid();
+ rReq.Done();
+ }
+ break;
+
+ default:
+ DBG_ERROR("Unbekannter Slot bei ScTabViewShell::Execute");
+ break;
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
new file mode 100644
index 000000000000..0835d08de9fd
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh4.cxx
@@ -0,0 +1,2114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <editeng/boxitem.hxx>
+#include <svx/fmshell.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <svx/prtqry.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svtools/printdlg.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <rtl/logfile.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "rangeutl.hxx"
+#include "printfun.hxx"
+#include "drawsh.hxx"
+#include "drformsh.hxx"
+#include "editsh.hxx"
+#include "pivotsh.hxx"
+#include "auditsh.hxx"
+#include "drtxtob.hxx"
+#include "inputhdl.hxx"
+#include "editutil.hxx"
+#include "inputopt.hxx"
+#include "inputwin.hxx"
+#include "scresid.hxx"
+#include "dbcolect.hxx" // fuer ReImport
+#include "reffact.hxx"
+#include "viewuno.hxx"
+#include "dispuno.hxx"
+#include "anyrefdg.hxx"
+#include "chgtrack.hxx"
+#include "cellsh.hxx"
+#include "oleobjsh.hxx"
+#include "chartsh.hxx"
+#include "graphsh.hxx"
+#include "mediash.hxx"
+#include "pgbrksh.hxx"
+#include "dpobject.hxx"
+#include "prevwsh.hxx"
+#include "tpprint.hxx"
+#include "scextopt.hxx"
+#include "printopt.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+#include "navsett.hxx"
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "externalrefmgr.hxx"
+
+void ActivateOlk( ScViewData* pViewData );
+void DeActivateOlk( ScViewData* pViewData );
+
+extern SfxViewShell* pScActiveViewShell; // global.cxx
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+USHORT ScTabViewShell::nInsertCtrlState = SID_INSERT_GRAPHIC;
+USHORT ScTabViewShell::nInsCellsCtrlState = 0;
+USHORT ScTabViewShell::nInsObjCtrlState = SID_INSERT_DIAGRAM;
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::Activate(BOOL bMDI)
+{
+ SfxViewShell::Activate(bMDI);
+
+ // hier kein GrabFocus, sonst gibt's Probleme wenn etwas inplace editiert wird!
+
+ if ( bMDI )
+ {
+ // fuer Eingabezeile (ClearCache)
+ ScModule* pScMod = SC_MOD();
+ pScMod->ViewShellChanged();
+
+ ActivateView( TRUE, bFirstActivate );
+ ActivateOlk( GetViewData() );
+
+ // #56870# AutoCorrect umsetzen, falls der Writer seins neu angelegt hat
+ UpdateDrawTextOutliner();
+
+ // RegisterNewTargetNames gibts nicht mehr
+
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ if ( pInputHandler && pThisFrame->HasChildWindow(FID_INPUTLINE_STATUS) )
+ {
+ // eigentlich nur beim Reload (letzte Version) noetig:
+ // Das InputWindow bleibt stehen, aber die View mitsamt InputHandler wird
+ // neu angelegt, darum muss der InputHandler am InputWindow gesetzt werden.
+ SfxChildWindow* pChild = pThisFrame->GetChildWindow(FID_INPUTLINE_STATUS);
+ if (pChild)
+ {
+ ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ {
+
+ ScInputHandler* pOldHdl=pWin->GetInputHandler();
+
+ TypeId aScType = TYPE(ScTabViewShell);
+
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh!=NULL && pOldHdl!=NULL)
+ {
+ if (((ScTabViewShell*)pSh)->GetInputHandler() == pOldHdl)
+ {
+ pOldHdl->ResetDelayTimer();
+ break;
+ }
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+
+ pWin->SetInputHandler( pInputHandler );
+ }
+ }
+ }
+
+ UpdateInputHandler( TRUE );
+
+ if ( bFirstActivate )
+ {
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_NAVIGATOR_UPDATEALL ) );
+ bFirstActivate = FALSE;
+
+ // #116278# ReadExtOptions (view settings from Excel import) must also be done
+ // after the ctor, because of the potential calls to Window::Show.
+ // Even after the fix for #104887# (Window::Show no longer notifies the access
+ // bridge, it's done in ImplSetReallyVisible), there are problems if Window::Show
+ // is called during the ViewShell ctor and reschedules asynchronous calls
+ // (for example from the FmFormShell ctor).
+ ScExtDocOptions* pExtOpt = GetViewData()->GetDocument()->GetExtDocOptions();
+ if ( pExtOpt && pExtOpt->IsChanged() )
+ {
+ GetViewData()->ReadExtOptions(*pExtOpt); // Excel view settings
+ SetTabNo( GetViewData()->GetTabNo(), TRUE );
+ pExtOpt->SetChanged( false );
+ }
+ }
+
+ pScActiveViewShell = this;
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl(this);
+ if (pHdl)
+ {
+ pHdl->SetRefScale( GetViewData()->GetZoomX(), GetViewData()->GetZoomY() );
+ }
+
+ // Aenderungs-Dialog aktualisieren
+
+ if ( pThisFrame->HasChildWindow(FID_CHG_ACCEPT) )
+ {
+ SfxChildWindow* pChild = pThisFrame->GetChildWindow(FID_CHG_ACCEPT);
+ if (pChild)
+ {
+ ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg();
+ }
+ }
+
+ if(pScMod->IsRefDialogOpen())
+ {
+ USHORT nModRefDlgId=pScMod->GetCurRefDlgId();
+ SfxChildWindow* pChildWnd = pThisFrame->GetChildWindow( nModRefDlgId );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ pRefDlg->ViewShellChanged(this);
+ }
+ }
+ }
+
+ // don't call CheckSelectionTransfer here - activating a view should not change the
+ // primary selection (may be happening just because the mouse was moved over the window)
+
+ // Wenn Referenzeingabe-Tip-Hilfe hier wieder angezeigt werden soll (ShowRefTip),
+ // muss sie beim Verschieben der View angepasst werden (gibt sonst Probleme unter OS/2
+ // beim Umschalten zwischen Dokumenten)
+}
+
+void __EXPORT ScTabViewShell::Deactivate(BOOL bMDI)
+{
+ HideTip();
+
+ ScDocument* pDoc=GetViewData()->GetDocument();
+
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pChanges!=NULL)
+ {
+ Link aLink;
+ pChanges->SetModifiedLink(aLink);
+ }
+
+ SfxViewShell::Deactivate(bMDI);
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(this);
+
+ if( bMDI )
+ {
+ // #85421# during shell deactivation, shells must not be switched, or the loop
+ // through the shell stack (in SfxDispatcher::DoDeactivate_Impl) will not work
+ BOOL bOldDontSwitch = bDontSwitch;
+ bDontSwitch = TRUE;
+
+ DeActivateOlk( GetViewData() );
+ ActivateView( FALSE, FALSE );
+
+ if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace
+ GetViewData()->GetDocShell()->UpdateOle(GetViewData(),TRUE);
+
+ if ( pHdl )
+ pHdl->NotifyChange( NULL, TRUE ); // Timer-verzoegert wg. Dokumentwechsel
+
+ if (pScActiveViewShell == this)
+ pScActiveViewShell = NULL;
+
+ bDontSwitch = bOldDontSwitch;
+ }
+ else
+ {
+ HideNoteMarker(); // Notiz-Anzeige
+
+ if ( pHdl )
+ pHdl->HideTip(); // Formel-AutoEingabe-Tip abschalten
+ }
+}
+
+void ScTabViewShell::SetActive()
+{
+ // Die Sfx-View moechte sich gerne selbst aktivieren, weil dabei noch
+ // magische Dinge geschehen (z.B. stuerzt sonst evtl. der Gestalter ab)
+ ActiveGrabFocus();
+
+#if 0
+ SfxViewFrame* pFrame = GetViewFrame();
+ pFrame->GetFrame().Appear();
+
+ SFX_APP()->SetViewFrame( pFrame ); // immer erst Appear, dann SetViewFrame (#29290#)
+#endif
+}
+
+USHORT __EXPORT ScTabViewShell::PrepareClose(BOOL bUI, BOOL bForBrowsing)
+{
+ // Call EnterHandler even in formula mode here,
+ // so a formula change in an embedded object isn't lost
+ // (ScDocShell::PrepareClose isn't called then).
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( this );
+ if ( pHdl && pHdl->IsInputMode() )
+ pHdl->EnterHandler();
+
+ // #110797# draw text edit mode must be closed
+ FuPoor* pPoor = GetDrawFuncPtr();
+ if ( pPoor && ( IsDrawTextShell() || pPoor->GetSlotID() == SID_DRAW_NOTEEDIT ) )
+ {
+ // "clean" end of text edit, including note handling, subshells and draw func switching,
+ // as in FuDraw and ScTabView::DrawDeselectAll
+ GetViewData()->GetDispatcher().Execute( pPoor->GetSlotID(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ ScDrawView* pDrView = GetScDrawView();
+ if ( pDrView )
+ {
+ // force end of text edit, to be safe
+ // #128314# ScEndTextEdit must always be used, to ensure correct UndoManager
+ pDrView->ScEndTextEdit();
+ }
+
+ if ( pFormShell )
+ {
+ USHORT nRet = pFormShell->PrepareClose(bUI, bForBrowsing);
+ if (nRet!=TRUE)
+ return nRet;
+ }
+ return SfxViewShell::PrepareClose(bUI,bForBrowsing);
+}
+
+//------------------------------------------------------------------
+
+Size __EXPORT ScTabViewShell::GetOptimalSizePixel() const
+{
+ Size aOptSize;
+
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ pDoc->GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
+
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ const SvxSizeItem& rItem = (const SvxSizeItem&)rSet.Get( ATTR_PAGE_SIZE );
+ const Size& rPageSize = rItem.GetSize();
+
+ aOptSize.Width() = (long) (rPageSize.Width() * GetViewData()->GetPPTX());
+ aOptSize.Height() = (long) (rPageSize.Height() * GetViewData()->GetPPTY());
+ }
+
+ return aOptSize;
+}
+
+//------------------------------------------------------------------
+
+// Zoom fuer In-Place berechnen
+// aus Verhaeltnis von VisArea und Fenstergroesse des GridWin
+
+void ScTabViewShell::UpdateOleZoom()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ //TODO/LATER: is there a difference between the two GetVisArea methods?
+ Size aObjSize = ((const SfxObjectShell*)pDocSh)->GetVisArea().GetSize();
+ if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
+ {
+ Window* pWin = GetActiveWin();
+ Size aWinHMM = pWin->PixelToLogic( pWin->GetOutputSizePixel(), MAP_100TH_MM );
+ SetZoomFactor( Fraction( aWinHMM.Width(),aObjSize.Width() ),
+ Fraction( aWinHMM.Height(),aObjSize.Height() ) );
+ }
+ }
+}
+
+void __EXPORT ScTabViewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
+{
+ OuterResizePixel( rPos, rSize );
+}
+
+void __EXPORT ScTabViewShell::InnerResizePixel( const Point &rOfs, const Size &rSize )
+{
+ Size aNewSize( rSize );
+ if ( GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ SvBorder aBorder;
+ GetBorderSize( aBorder, rSize );
+ SetBorderPixel( aBorder );
+
+ Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
+
+ Size aSize( rSize );
+ aSize.Width() -= (aBorder.Left() + aBorder.Right());
+ aSize.Height() -= (aBorder.Top() + aBorder.Bottom());
+
+ if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
+ {
+ Size aLogicSize = GetWindow()->PixelToLogic( aSize, MAP_100TH_MM );
+ SfxViewShell::SetZoomFactor( Fraction( aLogicSize.Width(),aObjSize.Width() ),
+ Fraction( aLogicSize.Height(),aObjSize.Height() ) );
+ }
+
+ Point aPos( rOfs );
+ aPos.X() += aBorder.Left();
+ aPos.Y() += aBorder.Top();
+ GetWindow()->SetPosSizePixel( aPos, aSize );
+ }
+ else
+ {
+ SvBorder aBorder;
+ GetBorderSize( aBorder, rSize );
+ SetBorderPixel( aBorder );
+ aNewSize.Width() += aBorder.Left() + aBorder.Right();
+ aNewSize.Height() += aBorder.Top() + aBorder.Bottom();
+ }
+
+ DoResize( rOfs, aNewSize, TRUE ); // rSize = Groesse von gridwin
+
+ UpdateOleZoom(); // Zoom fuer In-Place berechnen
+
+// GetViewData()->GetDocShell()->UpdateOle( GetViewData() );
+ GetViewData()->GetDocShell()->SetDocumentModified();
+}
+
+void __EXPORT ScTabViewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
+{
+ SvBorder aBorder;
+ GetBorderSize( aBorder, rSize );
+ SetBorderPixel( aBorder );
+
+ DoResize( rOfs, rSize ); // Position und Groesse von tabview wie uebergeben
+
+ // ForceMove als Ersatz fuer den Sfx-Move-Mechanismus
+ // (aWinPos muss aktuell gehalten werden, damit ForceMove beim Ole-Deaktivieren klappt)
+
+ ForceMove();
+}
+
+void __EXPORT ScTabViewShell::SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY )
+{
+ // fuer OLE...
+
+ Fraction aFrac20( 1,5 );
+ Fraction aFrac400( 4,1 );
+
+ Fraction aNewX( rZoomX );
+ if ( aNewX < aFrac20 )
+ aNewX = aFrac20;
+ if ( aNewX > aFrac400 )
+ aNewX = aFrac400;
+ Fraction aNewY( rZoomY );
+ if ( aNewY < aFrac20 )
+ aNewY = aFrac20;
+ if ( aNewY > aFrac400 )
+ aNewY = aFrac400;
+
+ GetViewData()->UpdateScreenZoom( aNewX, aNewY );
+ SetZoom( aNewX, aNewY, TRUE );
+
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+
+ SfxViewShell::SetZoomFactor( rZoomX, rZoomY );
+}
+
+void __EXPORT ScTabViewShell::QueryObjAreaPixel( Rectangle& rRect ) const
+{
+ // auf ganze Zellen anpassen (in 1/100 mm)
+
+ Size aPixelSize = rRect.GetSize();
+ Window* pWin = ((ScTabViewShell*)this)->GetActiveWin();
+ Size aLogicSize = pWin->PixelToLogic( aPixelSize );
+
+ const ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScSplitPos ePos = pViewData->GetActivePart();
+ SCCOL nCol = pViewData->GetPosX(WhichH(ePos));
+ SCROW nRow = pViewData->GetPosY(WhichV(ePos));
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bNegativePage = pDoc->IsNegativePage( nTab );
+
+ Rectangle aLogicRect = pDoc->GetMMRect( nCol, nRow, nCol, nRow, nTab );
+ if ( bNegativePage )
+ {
+ // use right edge of aLogicRect, and aLogicSize
+ aLogicRect.Left() = aLogicRect.Right() - aLogicSize.Width() + 1; // Right() is set below
+ }
+ aLogicRect.SetSize( aLogicSize );
+
+ pDoc->SnapVisArea( aLogicRect );
+
+ rRect.SetSize( pWin->LogicToPixel( aLogicRect.GetSize() ) );
+
+#if 0
+ // auf ganze Zellen anpassen (in Pixeln)
+
+ ScViewData* pViewData = ((ScTabViewShell*)this)->GetViewData();
+ Size aSize = rRect.GetSize();
+
+ ScSplitPos ePos = pViewData->GetActivePart();
+ Window* pWin = ((ScTabViewShell*)this)->GetActiveWin();
+
+ Point aTest( aSize.Width(), aSize.Height() );
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aTest.X(), aTest.Y(), ePos, nPosX, nPosY );
+ BOOL bLeft;
+ BOOL bTop;
+ pViewData->GetMouseQuadrant( aTest, ePos, nPosX, nPosY, bLeft, bTop );
+ if (!bLeft)
+ ++nPosX;
+ if (!bTop)
+ ++nPosY;
+ aTest = pViewData->GetScrPos( (SCCOL)nPosX, (SCROW)nPosY, ePos, TRUE );
+
+ rRect.SetSize(Size(aTest.X(),aTest.Y()));
+#endif
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::Move()
+{
+ Point aNewPos = GetViewFrame()->GetWindow().OutputToScreenPixel(Point());
+
+ if (aNewPos != aWinPos)
+ {
+ StopMarking();
+ aWinPos = aNewPos;
+ }
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::ShowCursor(FASTBOOL /* bOn */)
+{
+/*!!! ShowCursor wird nicht paarweise wie im gridwin gerufen.
+ Der CursorLockCount am Gridwin muss hier direkt auf 0 gesetzt werden
+
+ if (bOn)
+ ShowAllCursors();
+ else
+ HideAllCursors();
+*/
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::WriteUserData(String& rData, BOOL /* bBrowse */)
+{
+ GetViewData()->WriteUserData(rData);
+}
+
+void ScTabViewShell::WriteUserDataSequence (uno::Sequence < beans::PropertyValue >& rSettings, sal_Bool /* bBrowse */ )
+{
+ GetViewData()->WriteUserDataSequence (rSettings);
+}
+
+void __EXPORT ScTabViewShell::ReadUserData(const String& rData, BOOL /* bBrowse */)
+{
+ if ( !GetViewData()->GetDocShell()->IsPreview() )
+ DoReadUserData( rData );
+}
+
+void ScTabViewShell::ReadUserDataSequence (const uno::Sequence < beans::PropertyValue >& rSettings, sal_Bool /* bBrowse */ )
+{
+ if ( !GetViewData()->GetDocShell()->IsPreview() )
+ DoReadUserDataSequence( rSettings );
+}
+
+void ScTabViewShell::DoReadUserDataSequence( const uno::Sequence < beans::PropertyValue >& rSettings )
+{
+ Window* pOldWin = GetActiveWin();
+ BOOL bFocus = pOldWin && pOldWin->HasFocus();
+
+ GetViewData()->ReadUserDataSequence(rSettings);
+ SetTabNo( GetViewData()->GetTabNo(), TRUE );
+
+ if ( GetViewData()->IsPagebreakMode() )
+ SetCurSubShell( GetCurObjectSelectionType(), TRUE );
+
+ Window* pNewWin = GetActiveWin();
+ if (pNewWin && pNewWin != pOldWin)
+ {
+ SetWindow( pNewWin ); //! ist diese ViewShell immer aktiv???
+ if (bFocus)
+ pNewWin->GrabFocus();
+ WindowChanged(); // Drawing-Layer (z.B. #56771#)
+ }
+
+ if (GetViewData()->GetHSplitMode() == SC_SPLIT_FIX ||
+ GetViewData()->GetVSplitMode() == SC_SPLIT_FIX)
+ {
+ InvalidateSplit();
+ }
+
+ ZoomChanged();
+
+ TestHintWindow();
+
+ //! if ViewData has more tables than document, remove tables in ViewData
+}
+
+// DoReadUserData is also called from ctor when switching from print preview
+
+void ScTabViewShell::DoReadUserData( const String& rData )
+{
+ Window* pOldWin = GetActiveWin();
+ BOOL bFocus = pOldWin && pOldWin->HasFocus();
+
+ GetViewData()->ReadUserData(rData);
+ SetTabNo( GetViewData()->GetTabNo(), TRUE );
+
+ if ( GetViewData()->IsPagebreakMode() )
+ SetCurSubShell( GetCurObjectSelectionType(), TRUE );
+
+ Window* pNewWin = GetActiveWin();
+ if (pNewWin && pNewWin != pOldWin)
+ {
+ SetWindow( pNewWin ); //! ist diese ViewShell immer aktiv???
+ if (bFocus)
+ pNewWin->GrabFocus();
+ WindowChanged(); // Drawing-Layer (z.B. #56771#)
+ }
+
+ if (GetViewData()->GetHSplitMode() == SC_SPLIT_FIX ||
+ GetViewData()->GetVSplitMode() == SC_SPLIT_FIX)
+ {
+ InvalidateSplit();
+ }
+
+ ZoomChanged();
+
+ TestHintWindow();
+
+ //! if ViewData has more tables than document, remove tables in ViewData
+}
+
+//------------------------------------------------------------------
+
+//UNUSED2008-05 void ScTabViewShell::ExecuteShowNIY( SfxRequest& /* rReq */ )
+//UNUSED2008-05 {
+//UNUSED2008-05 ErrorMessage(STR_BOX_YNI);
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 //------------------------------------------------------------------
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabViewShell::StateDisabled( SfxItemSet& rSet )
+//UNUSED2008-05 {
+//UNUSED2008-05 SfxWhichIter aIter( rSet );
+//UNUSED2008-05 USHORT nWhich = aIter.FirstWhich();
+//UNUSED2008-05
+//UNUSED2008-05 while ( nWhich )
+//UNUSED2008-05 {
+//UNUSED2008-05 rSet.DisableItem( nWhich );
+//UNUSED2008-05 nWhich = aIter.NextWhich();
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+void ScTabViewShell::SetDrawShellOrSub()
+{
+ bActiveDrawSh = TRUE;
+
+ if(bActiveDrawFormSh)
+ {
+ SetCurSubShell(OST_DrawForm);
+ }
+ else if(bActiveGraphicSh)
+ {
+ SetCurSubShell(OST_Graphic);
+ }
+ else if(bActiveMediaSh)
+ {
+ SetCurSubShell(OST_Media);
+ }
+ else if(bActiveChartSh)
+ {
+ SetCurSubShell(OST_Chart);
+ }
+ else if(bActiveOleObjectSh)
+ {
+ SetCurSubShell(OST_OleObject);
+ }
+ else
+ {
+ SetCurSubShell(OST_Drawing, true /* force: different toolbars are
+ visible concerning shape type
+ and shape state */);
+ }
+}
+
+void ScTabViewShell::SetDrawShell( BOOL bActive )
+{
+ if(bActive)
+ {
+ SetCurSubShell(OST_Drawing, true /* force: different toolbars are
+ visible concerning shape type
+ and shape state */);
+ }
+ else
+ {
+ if(bActiveDrawFormSh || bActiveDrawSh ||
+ bActiveGraphicSh || bActiveMediaSh || bActiveOleObjectSh||
+ bActiveChartSh || bActiveDrawTextSh)
+ {
+ SetCurSubShell(OST_Cell);
+ }
+ bActiveDrawFormSh=FALSE;
+ bActiveGraphicSh=FALSE;
+ bActiveMediaSh=FALSE;
+ bActiveOleObjectSh=FALSE;
+ bActiveChartSh=FALSE;
+ }
+
+ BOOL bWasDraw = bActiveDrawSh || bActiveDrawTextSh;
+
+ bActiveDrawSh = bActive;
+ bActiveDrawTextSh = FALSE;
+
+ if ( !bActive )
+ {
+ ResetDrawDragMode(); // Mirror / Rotate aus
+
+ if (bWasDraw && (GetViewData()->GetHSplitMode() == SC_SPLIT_FIX ||
+ GetViewData()->GetVSplitMode() == SC_SPLIT_FIX))
+ {
+ // Aktiven Teil an Cursor anpassen, etc.
+ MoveCursorAbs( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ SC_FOLLOW_NONE, FALSE, FALSE, TRUE );
+ }
+ }
+}
+
+void ScTabViewShell::SetDrawTextShell( BOOL bActive )
+{
+ bActiveDrawTextSh = bActive;
+ if ( bActive )
+ {
+ bActiveDrawFormSh=FALSE;
+ bActiveGraphicSh=FALSE;
+ bActiveMediaSh=FALSE;
+ bActiveOleObjectSh=FALSE;
+ bActiveChartSh=FALSE;
+ bActiveDrawSh = FALSE;
+ SetCurSubShell(OST_DrawText);
+ }
+ else
+ SetCurSubShell(OST_Cell);
+
+}
+
+void ScTabViewShell::SetPivotShell( BOOL bActive )
+{
+ bActivePivotSh = bActive;
+
+ // #68771# #76198# SetPivotShell is called from CursorPosChanged every time
+ // -> don't change anything except switching between cell and pivot shell
+
+ if ( eCurOST == OST_Pivot || eCurOST == OST_Cell )
+ {
+ if ( bActive )
+ {
+ bActiveDrawTextSh = bActiveDrawSh = FALSE;
+ bActiveDrawFormSh=FALSE;
+ bActiveGraphicSh=FALSE;
+ bActiveMediaSh=FALSE;
+ bActiveOleObjectSh=FALSE;
+ bActiveChartSh=FALSE;
+ SetCurSubShell(OST_Pivot);
+ }
+ else
+ SetCurSubShell(OST_Cell);
+ }
+}
+
+void ScTabViewShell::SetAuditShell( BOOL bActive )
+{
+ bActiveAuditingSh = bActive;
+ if ( bActive )
+ {
+ bActiveDrawTextSh = bActiveDrawSh = FALSE;
+ bActiveDrawFormSh=FALSE;
+ bActiveGraphicSh=FALSE;
+ bActiveMediaSh=FALSE;
+ bActiveOleObjectSh=FALSE;
+ bActiveChartSh=FALSE;
+ SetCurSubShell(OST_Auditing);
+ }
+ else
+ SetCurSubShell(OST_Cell);
+}
+
+void ScTabViewShell::SetDrawFormShell( BOOL bActive )
+{
+ bActiveDrawFormSh = bActive;
+
+ if(bActiveDrawFormSh)
+ SetCurSubShell(OST_DrawForm);
+}
+void ScTabViewShell::SetChartShell( BOOL bActive )
+{
+ bActiveChartSh = bActive;
+
+ if(bActiveChartSh)
+ SetCurSubShell(OST_Chart);
+}
+
+void ScTabViewShell::SetGraphicShell( BOOL bActive )
+{
+ bActiveGraphicSh = bActive;
+
+ if(bActiveGraphicSh)
+ SetCurSubShell(OST_Graphic);
+}
+
+void ScTabViewShell::SetMediaShell( BOOL bActive )
+{
+ bActiveMediaSh = bActive;
+
+ if(bActiveMediaSh)
+ SetCurSubShell(OST_Media);
+}
+
+void ScTabViewShell::SetOleObjectShell( BOOL bActive )
+{
+ bActiveOleObjectSh = bActive;
+
+ if(bActiveOleObjectSh)
+ SetCurSubShell(OST_OleObject);
+ else
+ SetCurSubShell(OST_Cell);
+}
+
+void ScTabViewShell::SetEditShell(EditView* pView, BOOL bActive )
+{
+ if(bActive)
+ {
+ if (pEditShell)
+ pEditShell->SetEditView( pView );
+ else
+ pEditShell = new ScEditShell( pView, GetViewData() );
+
+ SetCurSubShell(OST_Editing);
+ }
+ else if(bActiveEditSh)
+ {
+ SetCurSubShell(OST_Cell);
+ }
+ bActiveEditSh = bActive;
+}
+
+void ScTabViewShell::SetCurSubShell(ObjectSelectionType eOST, BOOL bForce)
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ if(bDontSwitch) return;
+
+ if(!pCellShell) //Wird eh immer gebraucht.
+ {
+ pCellShell = new ScCellShell( GetViewData() );
+ pCellShell->SetRepeatTarget( &aTarget );
+ }
+
+ BOOL bPgBrk=pViewData->IsPagebreakMode();
+
+ if(bPgBrk && !pPageBreakShell)
+ {
+ pPageBreakShell = new ScPageBreakShell( this );
+ pPageBreakShell->SetRepeatTarget( &aTarget );
+ }
+
+
+ if ( eOST!=eCurOST || bForce )
+ {
+ BOOL bCellBrush = FALSE; // "format paint brush" allowed for cells
+ BOOL bDrawBrush = FALSE; // "format paint brush" allowed for drawing objects
+
+ if(eCurOST!=OST_NONE) RemoveSubShell();
+
+ if (pFormShell && !bFormShellAtTop)
+ AddSubShell(*pFormShell); // add below own subshells
+
+ switch(eOST)
+ {
+ case OST_Cell:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+ bCellBrush = TRUE;
+ }
+ break;
+ case OST_Editing:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+
+ if(pEditShell)
+ {
+ AddSubShell(*pEditShell);
+ }
+ }
+ break;
+ case OST_DrawText:
+ {
+ if ( !pDrawTextShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pDrawTextShell = new ScDrawTextObjectBar( GetViewData() );
+ }
+ AddSubShell(*pDrawTextShell);
+ }
+ break;
+ case OST_Drawing:
+ {
+ if (svx::checkForSelectedCustomShapes(
+ GetScDrawView(), true /* bOnlyExtruded */ )) {
+ if (pExtrusionBarShell == 0)
+ pExtrusionBarShell = new svx::ExtrusionBar(this);
+ AddSubShell( *pExtrusionBarShell );
+ }
+ sal_uInt32 nCheckStatus = 0;
+ if (svx::checkForSelectedFontWork(
+ GetScDrawView(), nCheckStatus )) {
+ if (pFontworkBarShell == 0)
+ pFontworkBarShell = new svx::FontworkBar(this);
+ AddSubShell( *pFontworkBarShell );
+ }
+
+ if ( !pDrawShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pDrawShell = new ScDrawShell( GetViewData() );
+ pDrawShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pDrawShell);
+ bDrawBrush = TRUE;
+ }
+ break;
+
+ case OST_DrawForm:
+ {
+ if ( !pDrawFormShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pDrawFormShell = new ScDrawFormShell( GetViewData() );
+ pDrawFormShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pDrawFormShell);
+ bDrawBrush = TRUE;
+ }
+ break;
+
+ case OST_Chart:
+ {
+ if ( !pChartShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pChartShell = new ScChartShell( GetViewData() );
+ pChartShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pChartShell);
+ bDrawBrush = TRUE;
+ }
+ break;
+
+ case OST_OleObject:
+ {
+ if ( !pOleObjectShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pOleObjectShell = new ScOleObjectShell( GetViewData() );
+ pOleObjectShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pOleObjectShell);
+ bDrawBrush = TRUE;
+ }
+ break;
+
+ case OST_Graphic:
+ {
+ if ( !pGraphicShell)
+ {
+ pDocSh->MakeDrawLayer();
+ pGraphicShell = new ScGraphicShell( GetViewData() );
+ pGraphicShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pGraphicShell);
+ bDrawBrush = TRUE;
+ }
+ break;
+
+ case OST_Media:
+ {
+ if ( !pMediaShell)
+ {
+ pDocSh->MakeDrawLayer();
+ pMediaShell = new ScMediaShell( GetViewData() );
+ pMediaShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pMediaShell);
+ }
+ break;
+
+ case OST_Pivot:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+
+ if ( !pPivotShell )
+ {
+ pPivotShell = new ScPivotShell( this );
+ pPivotShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pPivotShell);
+ bCellBrush = TRUE;
+ }
+ break;
+ case OST_Auditing:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+
+ if ( !pAuditingShell )
+ {
+ pDocSh->MakeDrawLayer(); // die Wartezeit lieber jetzt als beim Klick
+
+ pAuditingShell = new ScAuditingShell( GetViewData() );
+ pAuditingShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pAuditingShell);
+ bCellBrush = TRUE;
+ }
+ break;
+ default:
+ DBG_ERROR("Falsche Shell angefordert");
+ break;
+ }
+
+ if (pFormShell && bFormShellAtTop)
+ AddSubShell(*pFormShell); // add on top of own subshells
+
+ eCurOST=eOST;
+
+ // abort "format paint brush" when switching to an incompatible shell
+ if ( ( GetBrushDocument() && !bCellBrush ) || ( GetDrawBrushSet() && !bDrawBrush ) )
+ ResetBrushDocument();
+ }
+}
+
+void ScTabViewShell::SetFormShellAtTop( BOOL bSet )
+{
+ if ( pFormShell && !bSet )
+ pFormShell->ForgetActiveControl(); // let the FormShell know it no longer has the focus
+
+ if ( bFormShellAtTop != bSet )
+ {
+ bFormShellAtTop = bSet;
+ SetCurSubShell( GetCurObjectSelectionType(), TRUE );
+ }
+}
+
+IMPL_LINK( ScTabViewShell, FormControlActivated, FmFormShell*, EMPTYARG )
+{
+ // a form control got the focus, so the form shell has to be on top
+ SetFormShellAtTop( TRUE );
+ return 0;
+}
+
+ObjectSelectionType ScTabViewShell::GetCurObjectSelectionType()
+{
+ return eCurOST;
+}
+
+// GetMySubShell / SetMySubShell: altes Verhalten simulieren,
+// dass es nur eine SubShell gibt (nur innerhalb der 5 eignenen SubShells)
+
+SfxShell* ScTabViewShell::GetMySubShell() const
+{
+ // GetSubShell() war frueher const, und GetSubShell(USHORT) sollte es auch sein...
+
+ USHORT nPos = 0;
+ SfxShell* pSub = ((ScTabViewShell*)this)->GetSubShell(nPos);
+ while (pSub)
+ {
+ if ( pSub == pDrawShell || pSub == pDrawTextShell || pSub == pEditShell ||
+ pSub == pPivotShell || pSub == pAuditingShell || pSub == pDrawFormShell ||
+ pSub == pCellShell || pSub == pOleObjectShell|| pSub == pChartShell ||
+ pSub == pGraphicShell || pSub == pMediaShell || pSub == pPageBreakShell)
+ return pSub; // gefunden
+
+ pSub = ((ScTabViewShell*)this)->GetSubShell(++nPos);
+ }
+ return NULL; // keine von meinen dabei
+}
+
+//UNUSED2008-05 void ScTabViewShell::SetMySubShell( SfxShell* pShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 SfxShell* pOld = GetMySubShell();
+//UNUSED2008-05 if ( pOld != pShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pOld)
+//UNUSED2008-05 RemoveSubShell(pOld); // alte SubShell entfernen
+//UNUSED2008-05 if (pShell)
+//UNUSED2008-05 AddSubShell(*pShell); // neue setzen
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+BOOL ScTabViewShell::IsDrawTextShell() const
+{
+ return ( pDrawTextShell && ( GetMySubShell() == pDrawTextShell ) );
+}
+
+BOOL ScTabViewShell::IsAuditShell() const
+{
+ return ( pAuditingShell && ( GetMySubShell() == pAuditingShell ) );
+}
+
+void ScTabViewShell::SetDrawTextUndo( SfxUndoManager* pNewUndoMgr )
+{
+ // Default: Undo-Manager der DocShell
+ if (!pNewUndoMgr)
+ pNewUndoMgr = GetViewData()->GetDocShell()->GetUndoManager();
+
+ if (pDrawTextShell)
+ {
+ pDrawTextShell->SetUndoManager(pNewUndoMgr);
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pNewUndoMgr == pDocSh->GetUndoManager() &&
+ !pDocSh->GetDocument()->IsUndoEnabled() )
+ {
+ pNewUndoMgr->SetMaxUndoActionCount( 0 );
+ }
+ }
+ else
+ {
+ DBG_ERROR("SetDrawTextUndo ohne DrawTextShell");
+ }
+}
+
+//------------------------------------------------------------------
+
+ScTabViewShell* ScTabViewShell::GetActiveViewShell()
+{
+ return PTR_CAST(ScTabViewShell,Current());
+}
+
+//------------------------------------------------------------------
+
+SfxPrinter* __EXPORT ScTabViewShell::GetPrinter( BOOL bCreate )
+{
+ // Drucker ist immer da (wird fuer die FontListe schon beim Starten angelegt)
+ return GetViewData()->GetDocShell()->GetPrinter(bCreate);
+}
+
+USHORT __EXPORT ScTabViewShell::SetPrinter( SfxPrinter *pNewPrinter, USHORT nDiffFlags, bool )
+{
+ return GetViewData()->GetDocShell()->SetPrinter( pNewPrinter, nDiffFlags );
+}
+
+PrintDialog* __EXPORT ScTabViewShell::CreatePrintDialog( Window *pParent )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ pDoc->SetPrintOptions(); // Optionen aus OFA am Printer setzen
+ SfxPrinter* pPrinter = GetPrinter();
+
+ String aStrRange;
+ PrintDialog* pDlg = new PrintDialog( pParent, true );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ long nDocPageMax = 0;
+
+ pDlg->EnableSheetRange( true, PRINTSHEETS_ALL );
+ pDlg->EnableSheetRange( true, PRINTSHEETS_SELECTED_SHEETS );
+ pDlg->EnableSheetRange( true, PRINTSHEETS_SELECTED_CELLS );
+ 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 );
+ nDocPageMax += aPrintFunc.GetTotalPages();
+ }
+
+ if ( nDocPageMax > 0 )
+ {
+ aStrRange = '1';
+ if ( nDocPageMax > 1 )
+ {
+ aStrRange += '-';
+ aStrRange += String::CreateFromInt32( nDocPageMax );
+ }
+ }
+
+ pDlg->SetRangeText ( aStrRange );
+ pDlg->EnableRange ( PRINTDIALOG_ALL );
+ pDlg->EnableRange ( PRINTDIALOG_RANGE );
+ pDlg->SetFirstPage ( 1 );
+ pDlg->SetMinPage ( 1 );
+ pDlg->SetLastPage ( (USHORT)nDocPageMax );
+ pDlg->SetMaxPage ( (USHORT)nDocPageMax );
+ pDlg->EnableCollate ();
+
+ return pDlg;
+}
+
+SfxTabPage* ScTabViewShell::CreatePrintOptionsPage( Window *pParent, const SfxItemSet &rOptions )
+{
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ //CHINA001 return ScTpPrintOptions::Create( pParent, rOptions );
+ ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT );
+ if ( ScTpPrintOptionsCreate )
+ return (*ScTpPrintOptionsCreate)( pParent, rOptions);
+ return 0;
+}
+
+void __EXPORT ScTabViewShell::PreparePrint( PrintDialog* pPrintDialog )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+
+ SfxViewShell::PreparePrint( pPrintDialog );
+ pDocShell->PreparePrint( pPrintDialog, &GetViewData()->GetMarkData() );
+}
+
+ErrCode ScTabViewShell::DoPrint( SfxPrinter *pPrinter,
+ PrintDialog *pPrintDialog, BOOL bSilent, BOOL bIsAPI )
+{
+ // #72527# if SID_PRINTDOCDIRECT is executed and there's a selection,
+ // ask if only the selection should be printed
+
+ const ScMarkData& rMarkData = GetViewData()->GetMarkData();
+ if ( !pPrintDialog && !bSilent && !bIsAPI && ( rMarkData.IsMarked() || rMarkData.IsMultiMarked() ) )
+ {
+ SvxPrtQryBox aQuery( GetDialogParent() );
+ short nBtn = aQuery.Execute();
+
+ if ( nBtn == RET_CANCEL )
+ return ERRCODE_IO_ABORT;
+
+ if ( nBtn == RET_OK )
+ bPrintSelected = TRUE;
+ }
+
+ ErrCode nRet = ERRCODE_IO_ABORT;
+
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ if ( pDocShell->CheckPrint( pPrintDialog, &GetViewData()->GetMarkData(), bPrintSelected, bIsAPI ) )
+ {
+ // get the list of affected sheets before SfxViewShell::Print
+ bool bAllTabs = ( pPrintDialog ? ( pPrintDialog->GetCheckedSheetRange() == PRINTSHEETS_ALL ) : SC_MOD()->GetPrintOptions().GetAllSheets() );
+
+ uno::Sequence<sal_Int32> aSheets;
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ USHORT nPrinted = 0;
+ for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
+ if ( bAllTabs || rMarkData.GetTableSelect(nTab) )
+ {
+ aSheets.realloc( nPrinted + 1 );
+ aSheets[nPrinted] = nTab;
+ ++nPrinted;
+ }
+
+ uno::Sequence < beans::PropertyValue > aProps(1);
+ aProps[0].Name=::rtl::OUString::createFromAscii("PrintSheets");
+ aProps[0].Value <<= aSheets;
+ SetAdditionalPrintOptions( aProps );
+
+ // SfxViewShell::DoPrint calls Print (after StartJob etc.)
+ nRet = SfxViewShell::DoPrint( pPrinter, pPrintDialog, bSilent, bIsAPI );
+ }
+
+ bPrintSelected = FALSE;
+
+ return nRet;
+}
+
+USHORT __EXPORT ScTabViewShell::Print( SfxProgress& rProgress, BOOL bIsAPI,
+ PrintDialog* pPrintDialog )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ pDocShell->GetDocument()->SetPrintOptions(); // Optionen aus OFA am Printer setzen
+
+ SfxViewShell::Print( rProgress, bIsAPI, pPrintDialog );
+ pDocShell->Print( rProgress, pPrintDialog, &GetViewData()->GetMarkData(),
+ GetDialogParent(), bPrintSelected, bIsAPI );
+ return 0;
+}
+
+void ScTabViewShell::StopEditShell()
+{
+ if ( pEditShell != NULL && !bDontSwitch )
+ SetEditShell(NULL, FALSE );
+}
+
+//------------------------------------------------------------------
+
+// close handler to ensure function of dialog:
+
+IMPL_LINK( ScTabViewShell, SimpleRefClose, String*, EMPTYARG )
+{
+ SfxInPlaceClient* pClient = GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ {
+ // If range selection was started with an active embedded object,
+ // switch back to original sheet (while the dialog is still open).
+
+ SetTabNo( GetViewData()->GetRefTabNo() );
+ }
+
+ ScSimpleRefDlgWrapper::SetAutoReOpen( TRUE );
+ return 0;
+}
+
+// handlers to call UNO listeners:
+
+ScTabViewObj* lcl_GetViewObj( ScTabViewShell& rShell )
+{
+ ScTabViewObj* pRet = NULL;
+ SfxViewFrame* pViewFrame = rShell.GetViewFrame();
+ if (pViewFrame)
+ {
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ uno::Reference<frame::XController> xController = rFrame.GetController();
+ if (xController.is())
+ pRet = ScTabViewObj::getImplementation( xController );
+ }
+ return pRet;
+}
+
+IMPL_LINK( ScTabViewShell, SimpleRefDone, String*, pResult )
+{
+ ScTabViewObj* pImpObj = lcl_GetViewObj( *this );
+ if ( pImpObj && pResult )
+ pImpObj->RangeSelDone( *pResult );
+ return 0;
+}
+
+IMPL_LINK( ScTabViewShell, SimpleRefAborted, String*, pResult )
+{
+ ScTabViewObj* pImpObj = lcl_GetViewObj( *this );
+ if ( pImpObj && pResult )
+ pImpObj->RangeSelAborted( *pResult );
+ return 0;
+}
+
+IMPL_LINK( ScTabViewShell, SimpleRefChange, String*, pResult )
+{
+ ScTabViewObj* pImpObj = lcl_GetViewObj( *this );
+ if ( pImpObj && pResult )
+ pImpObj->RangeSelChanged( *pResult );
+ return 0;
+}
+
+void ScTabViewShell::StartSimpleRefDialog(
+ const String& rTitle, const String& rInitVal,
+ BOOL bCloseOnButtonUp, BOOL bSingleCell, BOOL bMultiSelection )
+{
+ SfxViewFrame* pViewFrm = GetViewFrame();
+
+ if ( GetActiveViewShell() != this )
+ {
+ // #i18833# / #i34499# The API method can be called for a view that's not active.
+ // Then the view has to be activated first, the same way as in Execute for SID_CURRENTDOC.
+ // Can't use GrabFocus here, because it needs to take effect immediately.
+
+ pViewFrm->GetFrame().Appear();
+ }
+
+ USHORT nId = ScSimpleRefDlgWrapper::GetChildWindowId();
+
+ SC_MOD()->SetRefDialog( nId, TRUE, pViewFrm );
+
+ ScSimpleRefDlgWrapper* pWnd = (ScSimpleRefDlgWrapper*)pViewFrm->GetChildWindow( nId );
+ if (pWnd)
+ {
+ pWnd->SetCloseHdl( LINK( this, ScTabViewShell, SimpleRefClose ) );
+ pWnd->SetUnoLinks( LINK( this, ScTabViewShell, SimpleRefDone ),
+ LINK( this, ScTabViewShell, SimpleRefAborted ),
+ LINK( this, ScTabViewShell, SimpleRefChange ) );
+ pWnd->SetRefString( rInitVal );
+ pWnd->SetFlags( bCloseOnButtonUp, bSingleCell, bMultiSelection );
+ pWnd->SetAutoReOpen( FALSE );
+ Window* pWin = pWnd->GetWindow();
+ pWin->SetText( rTitle );
+ pWnd->StartRefInput();
+ }
+}
+
+void ScTabViewShell::StopSimpleRefDialog()
+{
+ SfxViewFrame* pViewFrm = GetViewFrame();
+ USHORT nId = ScSimpleRefDlgWrapper::GetChildWindowId();
+
+ ScSimpleRefDlgWrapper* pWnd = (ScSimpleRefDlgWrapper*)pViewFrm->GetChildWindow( nId );
+ if (pWnd)
+ {
+ Window* pWin = pWnd->GetWindow();
+ if (pWin && pWin->IsSystemWindow())
+ ((SystemWindow*)pWin)->Close(); // calls abort handler
+ }
+}
+
+//------------------------------------------------------------------
+
+BOOL ScTabViewShell::TabKeyInput(const KeyEvent& rKEvt)
+{
+ ScModule* pScMod = SC_MOD();
+
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ if ( pThisFrame->GetChildWindow( SID_OPENDLG_FUNCTION ) )
+ return FALSE;
+
+ KeyCode aCode = rKEvt.GetKeyCode();
+ BOOL bShift = aCode.IsShift();
+ BOOL bControl = aCode.IsMod1();
+ BOOL bAlt = aCode.IsMod2();
+ USHORT nCode = aCode.GetCode();
+ BOOL bUsed = FALSE;
+ BOOL bInPlace = pScMod->IsEditMode(); // Editengine bekommt alles
+ BOOL bAnyEdit = pScMod->IsInputMode(); // nur Zeichen & Backspace
+ BOOL bDraw = IsDrawTextEdit();
+
+ HideNoteMarker(); // Notiz-Anzeige
+
+ // don't do extra HideCursor/ShowCursor calls if EnterHandler will switch to a different sheet
+ BOOL bOnRefSheet = ( GetViewData()->GetRefTabNo() == GetViewData()->GetTabNo() );
+ BOOL bHideCursor = ( ( nCode == KEY_RETURN && bInPlace ) || nCode == KEY_TAB ) && bOnRefSheet;
+
+ if (bHideCursor)
+ HideAllCursors();
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc )
+ pDoc->KeyInput( rKEvt ); // TimerDelays etc.
+
+ if( bInPlace )
+ {
+ bUsed = pScMod->InputKeyEvent( rKEvt ); // Eingabe
+ if( !bUsed )
+ bUsed = sal::static_int_cast<BOOL>(SfxViewShell::KeyInput( rKEvt )); // accelerators
+ }
+ else if( bAnyEdit )
+ {
+ BOOL bIsType = FALSE;
+ USHORT nModi = aCode.GetModifier();
+ USHORT nGroup = aCode.GetGroup();
+
+ if ( nGroup == KEYGROUP_NUM || nGroup == KEYGROUP_ALPHA || nGroup == 0 )
+ if ( !bControl && !bAlt )
+ bIsType = TRUE;
+
+ if ( nGroup == KEYGROUP_MISC )
+ switch ( nCode )
+ {
+ case KEY_RETURN:
+ bIsType = bControl && !bAlt; // Control, Shift-Control-Return
+ if ( !bIsType && nModi == 0 )
+ {
+ // Will der InputHandler auch ein einfaches Return?
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl(this);
+ bIsType = pHdl && pHdl->TakesReturn();
+ }
+ break;
+ case KEY_SPACE:
+ bIsType = !bControl && !bAlt; // ohne Modifier oder Shift-Space
+ break;
+ case KEY_ESCAPE:
+ case KEY_BACKSPACE:
+ bIsType = (nModi == 0); // nur ohne Modifier
+ break;
+ default:
+ bIsType = TRUE;
+ }
+
+ if( bIsType )
+ bUsed = pScMod->InputKeyEvent( rKEvt ); // Eingabe
+
+ if( !bUsed )
+ bUsed = sal::static_int_cast<BOOL>(SfxViewShell::KeyInput( rKEvt )); // accelerators
+
+ if ( !bUsed && !bIsType && nCode != KEY_RETURN ) // Eingabe nochmal hinterher
+ bUsed = pScMod->InputKeyEvent( rKEvt );
+ }
+ else
+ {
+ // #51889# Spezialfall: Copy/Cut bei Mehrfachselektion -> Fehlermeldung
+ // (Slot ist disabled, SfxViewShell::KeyInput wuerde also kommentarlos verschluckt)
+ KeyFuncType eFunc = aCode.GetFunction();
+ if ( eFunc == KEYFUNC_CUT )
+ {
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy );
+ if ( eMarkType != SC_MARK_SIMPLE &&
+ !(eFunc == KEYFUNC_COPY && eMarkType == SC_MARK_SIMPLE_FILTERED) )
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ bUsed = TRUE;
+ }
+ }
+ if (!bUsed)
+ bUsed = sal::static_int_cast<BOOL>(SfxViewShell::KeyInput( rKEvt )); // accelerators
+
+ // #74696# during inplace editing, some slots are handled by the
+ // container app and are executed during Window::KeyInput.
+ // -> don't pass keys to input handler that would be used there
+ // but should call slots instead.
+ BOOL bParent = ( GetViewFrame()->GetFrame().IsInPlace() && eFunc != KEYFUNC_DONTKNOW );
+
+ if( !bUsed && !bDraw && nCode != KEY_RETURN && !bParent )
+ bUsed = pScMod->InputKeyEvent( rKEvt, TRUE ); // Eingabe
+ }
+
+ if (!bInPlace && !bUsed && !bDraw)
+ {
+ switch (nCode)
+ {
+ case KEY_RETURN:
+ {
+ BOOL bNormal = !bControl && !bAlt;
+ if ( !bAnyEdit && bNormal )
+ {
+ // je nach Optionen mit Enter in den Edit-Modus schalten
+
+ const ScInputOptions& rOpt = pScMod->GetInputOptions();
+ if ( rOpt.GetEnterEdit() )
+ {
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ bUsed = TRUE;
+ }
+ }
+
+ BOOL bEditReturn = bControl && !bShift; // An Edit-Engine weiter
+ if ( !bUsed && !bEditReturn )
+ {
+ if ( bOnRefSheet )
+ HideAllCursors();
+
+ BYTE nMode = SC_ENTER_NORMAL;
+ if ( bShift && bControl )
+ nMode = SC_ENTER_MATRIX;
+ else if ( bAlt )
+ nMode = SC_ENTER_BLOCK;
+ pScMod->InputEnterHandler(nMode);
+
+ if (nMode == SC_ENTER_NORMAL)
+ {
+ if( bShift )
+ GetViewData()->GetDispatcher().Execute( SID_CURSORENTERUP,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ else
+ GetViewData()->GetDispatcher().Execute( SID_CURSORENTERDOWN,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else
+ UpdateInputHandler(TRUE);
+
+ if ( bOnRefSheet )
+ ShowAllCursors();
+
+ // hier kein UpdateInputHandler, weil bei Referenzeingabe auf ein
+ // anderes Dokument diese ViewShell nicht die ist, auf der eingegeben
+ // wird!
+
+ bUsed = TRUE;
+ }
+ }
+ break;
+ }
+ }
+
+ // Alt-Cursortasten hart codiert, weil Alt nicht konfigurierbar ist
+
+ if ( !bUsed && bAlt && !bControl )
+ {
+ USHORT nSlotId = 0;
+ switch (nCode)
+ {
+ case KEY_UP:
+ ModifyCellSize( DIR_TOP, bShift );
+ bUsed = TRUE;
+ break;
+ case KEY_DOWN:
+ ModifyCellSize( DIR_BOTTOM, bShift );
+ bUsed = TRUE;
+ break;
+ case KEY_LEFT:
+ ModifyCellSize( DIR_LEFT, bShift );
+ bUsed = TRUE;
+ break;
+ case KEY_RIGHT:
+ ModifyCellSize( DIR_RIGHT, bShift );
+ bUsed = TRUE;
+ break;
+ case KEY_PAGEUP:
+ nSlotId = bShift ? SID_CURSORPAGELEFT_SEL : SID_CURSORPAGELEFT_;
+ break;
+ case KEY_PAGEDOWN:
+ nSlotId = bShift ? SID_CURSORPAGERIGHT_SEL : SID_CURSORPAGERIGHT_;
+ break;
+ }
+ if ( nSlotId )
+ {
+ GetViewData()->GetDispatcher().Execute( nSlotId, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ bUsed = TRUE;
+ }
+ }
+
+ if (bHideCursor)
+ ShowAllCursors();
+
+ return bUsed;
+}
+
+BOOL ScTabViewShell::SfxKeyInput(const KeyEvent& rKeyEvent)
+{
+ return sal::static_int_cast<BOOL>(SfxViewShell::KeyInput( rKeyEvent ));
+}
+
+FASTBOOL __EXPORT ScTabViewShell::KeyInput( const KeyEvent &rKeyEvent )
+{
+// return SfxViewShell::KeyInput( rKeyEvent );
+ return TabKeyInput( rKeyEvent );
+}
+
+//------------------------------------------------------------------
+
+#define __INIT_ScTabViewShell \
+ eCurOST(OST_NONE), \
+ nDrawSfxId(0), \
+ nCtrlSfxId(USHRT_MAX), \
+ nFormSfxId(USHRT_MAX), \
+ pDrawShell(NULL), \
+ pDrawTextShell(NULL), \
+ pEditShell(NULL), \
+ pPivotShell(NULL), \
+ pAuditingShell(NULL), \
+ pDrawFormShell(NULL), \
+ pCellShell(NULL), \
+ pOleObjectShell(NULL), \
+ pChartShell(NULL), \
+ pGraphicShell(NULL), \
+ pMediaShell(NULL), \
+ pPageBreakShell(NULL), \
+ pExtrusionBarShell(NULL), \
+ pFontworkBarShell(NULL), \
+ pFormShell(NULL), \
+ pInputHandler(NULL), \
+ pCurFrameLine(NULL), \
+ aTarget( this ), \
+ pDialogDPObject(NULL), \
+ pNavSettings(NULL), \
+ bActiveDrawSh(FALSE), \
+ bActiveDrawTextSh(FALSE), \
+ bActivePivotSh(FALSE), \
+ bActiveAuditingSh(FALSE), \
+ bActiveDrawFormSh(FALSE), \
+ bActiveOleObjectSh(FALSE), \
+ bActiveChartSh(FALSE), \
+ bActiveGraphicSh(FALSE), \
+ bActiveMediaSh(FALSE), \
+ bActiveEditSh(FALSE), \
+ bFormShellAtTop(FALSE), \
+ bDontSwitch(FALSE), \
+ bInFormatDialog(FALSE), \
+ bPrintSelected(FALSE), \
+ bReadOnly(FALSE), \
+ pScSbxObject(NULL), \
+ /*bChartDlgIsEdit(FALSE),*/ \
+ bChartAreaValid(FALSE), \
+ nCurRefDlgId(0), \
+ pAccessibilityBroadcaster(NULL)
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::Construct( BYTE nForceDesignMode )
+{
+ SfxApplication* pSfxApp = SFX_APP();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ bReadOnly = pDocSh->IsReadOnly();
+
+ SetName( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("View")) ); // fuer SBX
+ Color aColBlack( COL_BLACK );
+// SetPool( &pSfxApp->GetPool() );
+ SetPool( &SC_MOD()->GetPool() );
+ SetWindow( GetActiveWin() );
+
+ pCurFrameLine = new SvxBorderLine( &aColBlack, 20, 0, 0 );
+ pPivotSource = new ScArea;
+ StartListening(*GetViewData()->GetDocShell(),TRUE);
+ StartListening(*GetViewFrame(),TRUE);
+ StartListening(*pSfxApp,TRUE); // #i62045# #i62046# application is needed for Calc's own hints
+
+ SfxViewFrame* pFirst = SfxViewFrame::GetFirst(pDocSh);
+ BOOL bFirstView = !pFirst
+ || (pFirst == GetViewFrame() && !SfxViewFrame::GetNext(*pFirst,pDocSh));
+
+ if ( pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ //TODO/LATER: is there a difference between the two GetVisArea methods?
+ Rectangle aVisArea = ((const SfxObjectShell*)pDocSh)->GetVisArea();
+
+ SCTAB nVisTab = pDoc->GetVisibleTab();
+ if (!pDoc->HasTable(nVisTab))
+ {
+ nVisTab = 0;
+ pDoc->SetVisibleTab(nVisTab);
+ }
+ SetTabNo( nVisTab );
+ BOOL bNegativePage = pDoc->IsNegativePage( nVisTab );
+ // show the right cells
+ GetViewData()->SetScreenPos( bNegativePage ? aVisArea.TopRight() : aVisArea.TopLeft() );
+
+ if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace
+ {
+ pDocSh->SetInplace( TRUE ); // schon so initialisiert
+ if (pDoc->IsEmbedded())
+ pDoc->ResetEmbedded(); // keine blaue Markierung
+ }
+ else if ( bFirstView )
+ {
+ pDocSh->SetInplace( FALSE );
+ GetViewData()->RefreshZoom(); // recalculate PPT
+ if (!pDoc->IsEmbedded())
+ pDoc->SetEmbedded( aVisArea ); // VisArea markieren
+ }
+ }
+
+ // ViewInputHandler
+ // #48721# jeder Task hat neuerdings sein eigenes InputWindow,
+ // darum muesste eigentlich entweder jeder Task seinen InputHandler bekommen,
+ // oder das InputWindow muesste sich beim App-InputHandler anmelden, wenn der
+ // Task aktiv wird, oder das InputWindow muesste sich den InputHandler selbst
+ // anlegen (dann immer ueber das InputWindow suchen, und nur wenn das nicht da
+ // ist, den InputHandler von der App nehmen).
+ // Als Sofortloesung bekommt erstmal jede View ihren Inputhandler, das gibt
+ // nur noch Probleme, wenn zwei Views in einem Task-Fenster sind.
+
+ pInputHandler = new ScInputHandler;
+
+ // Alte Version:
+ // if ( !GetViewFrame()->ISA(SfxTopViewFrame) ) // OLE oder Plug-In
+ // pInputHandler = new ScInputHandler;
+
+ // FormShell vor MakeDrawView anlegen, damit die DrawView auf jeden Fall
+ // an der FormShell angemeldet werden kann
+ // Gepusht wird die FormShell im ersten Activate
+ pFormShell = new FmFormShell(this);
+ pFormShell->SetControlActivationHandler( LINK( this, ScTabViewShell, FormControlActivated ) );
+
+ // DrawView darf nicht im TabView - ctor angelegt werden,
+ // wenn die ViewShell noch nicht kostruiert ist...
+ if (pDoc->GetDrawLayer())
+ MakeDrawView( nForceDesignMode );
+ ViewOptionsHasChanged(FALSE); // legt auch evtl. DrawView an
+
+ SfxUndoManager* pMgr = pDocSh->GetUndoManager();
+ SetUndoManager( pMgr );
+ pFormShell->SetUndoManager( pMgr );
+ if ( !pDoc->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetRepeatTarget( &aTarget );
+ pFormShell->SetRepeatTarget( &aTarget );
+ SetHelpId( HID_SCSHELL_TABVWSH );
+
+ if ( bFirstView ) // first view?
+ {
+ pDoc->SetDocVisible( TRUE ); // used when creating new sheets
+ if ( pDocSh->IsEmpty() )
+ {
+ // set first sheet's RTL flag (following will already be initialized because of SetDocVisible)
+ pDoc->SetLayoutRTL( 0, ScGlobal::IsSystemRTL() );
+
+ // append additional sheets (not for OLE object)
+ if ( pDocSh->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ SCTAB nInitTabCount = 3; //! konfigurierbar !!!
+ for (SCTAB i=1; i<nInitTabCount; i++)
+ pDoc->MakeTable(i,false);
+ }
+
+ pDocSh->SetEmpty( FALSE ); // #i6232# make sure this is done only once
+ }
+
+ // ReadExtOptions is now in Activate
+
+ // Link-Update nicht verschachteln
+ if ( pDocSh->GetCreateMode() != SFX_CREATE_MODE_INTERNAL &&
+ pDocSh->IsUpdateEnabled() ) // #105575#; update only in the first creation of the ViewShell
+ {
+ // Check if there are any external data.
+ bool bLink = pDoc->GetExternalRefManager()->hasExternalData();
+ if (!bLink)
+ {
+ // #i100042# sheet links can still exist independently from external formula references
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount && !bLink; i++)
+ if (pDoc->IsLinked(i))
+ bLink = true;
+ }
+ if (!bLink)
+ if (pDoc->HasDdeLinks() || pDoc->HasAreaLinks())
+ bLink = TRUE;
+ if (bLink)
+ {
+ if ( !pFirst )
+ pFirst = GetViewFrame();
+
+ if(SC_MOD()->GetCurRefDlgId()==0)
+ {
+ pFirst->GetDispatcher()->Execute( SID_UPDATETABLINKS,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
+ }
+ }
+
+ BOOL bReImport = FALSE; // importierte Daten aktualisieren
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ if ( pDBColl )
+ {
+ USHORT nCount = pDBColl->GetCount();
+ for (USHORT i=0; i<nCount && !bReImport; i++)
+ {
+ ScDBData* pData = (*pDBColl)[i];
+ if ( pData->IsStripData() &&
+ pData->HasImportParam() && !pData->HasImportSelection() )
+ bReImport = TRUE;
+ }
+ }
+ if (bReImport)
+ {
+ if ( !pFirst )
+ pFirst = GetViewFrame();
+ if(SC_MOD()->GetCurRefDlgId()==0)
+ {
+ pFirst->GetDispatcher()->Execute( SID_REIMPORT_AFTER_LOAD,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
+ }
+ }
+ }
+ }
+
+ UpdateAutoFillMark();
+
+ // ScDispatchProviderInterceptor registers itself in ctor
+ xDisProvInterceptor = new ScDispatchProviderInterceptor( this );
+
+ bFirstActivate = TRUE; // NavigatorUpdate aufschieben bis Activate()
+
+ // #105575#; update only in the first creation of the ViewShell
+ pDocSh->SetUpdateEnabled(FALSE);
+
+ if ( GetViewFrame()->GetFrame().IsInPlace() )
+ UpdateHeaderWidth(); // The implace activation requires headers to be calculated
+
+ SvBorder aBorder;
+ GetBorderSize( aBorder, Size() );
+ SetBorderPixel( aBorder );
+}
+
+//------------------------------------------------------------------
+
+//UNUSED2008-05 ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame,
+//UNUSED2008-05 const ScTabViewShell& rWin ) :
+//UNUSED2008-05 SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ),
+//UNUSED2008-05 ScDBFunc( &pViewFrame->GetWindow(), rWin, this ),
+//UNUSED2008-05 __INIT_ScTabViewShell
+//UNUSED2008-05 {
+//UNUSED2008-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabViewShell::ScTabViewShell" );
+//UNUSED2008-05
+//UNUSED2008-05 Construct();
+//UNUSED2008-05
+//UNUSED2008-05 UpdatePageBreakData();
+//UNUSED2008-05
+//UNUSED2008-05 /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+//UNUSED2008-05 if (xFrame.is())
+//UNUSED2008-05 xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/
+//UNUSED2008-05 // make Controller known to SFX
+//UNUSED2008-05 new ScTabViewObj( this );
+//UNUSED2008-05
+//UNUSED2008-05 SetCurSubShell(OST_Cell);
+//UNUSED2008-05 SvBorder aBorder;
+//UNUSED2008-05 GetBorderSize( aBorder, Size() );
+//UNUSED2008-05 SetBorderPixel( aBorder );
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------
+
+ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh ) :
+ SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ),
+ ScDBFunc( &pViewFrame->GetWindow(), (ScDocShell&)*pViewFrame->GetObjectShell(), this ),
+ __INIT_ScTabViewShell
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabViewShell::ScTabViewShell" );
+
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+
+ // if switching back from print preview,
+ // restore the view settings that were active when creating the preview
+ // #89897# ReadUserData must not happen from ctor, because the view's edit window
+ // has to be shown by the sfx. ReadUserData is deferred until the first Activate call.
+ // #106334# old DesignMode state from form layer must be restored, too
+
+ BYTE nForceDesignMode = SC_FORCEMODE_NONE;
+ if ( pOldSh && pOldSh->ISA( ScPreviewShell ) )
+ {
+ ScPreviewShell* pPreviewShell = ((ScPreviewShell*)pOldSh);
+ nForceDesignMode = pPreviewShell->GetSourceDesignMode();
+ }
+
+ Construct( nForceDesignMode );
+
+ if ( GetViewData()->GetDocShell()->IsPreview() )
+ {
+ // preview for template dialog: always show whole page
+ SetZoomType( SVX_ZOOM_WHOLEPAGE, TRUE ); // zoom value is recalculated at next Resize
+ }
+ else
+ {
+ Fraction aFract( rAppOpt.GetZoom(), 100 );
+ SetZoom( aFract, aFract, TRUE );
+ SetZoomType( rAppOpt.GetZoomType(), TRUE );
+ }
+
+ /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ if (xFrame.is())
+ xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/
+ // make Controller known to SFX
+ new ScTabViewObj( this );
+
+ SetCurSubShell(OST_Cell);
+ SvBorder aBorder;
+ GetBorderSize( aBorder, Size() );
+ SetBorderPixel( aBorder );
+
+ // #114409#
+ MakeDrawLayer();
+}
+
+#undef __INIT_ScTabViewShell
+
+//------------------------------------------------------------------
+
+__EXPORT ScTabViewShell::~ScTabViewShell()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ EndListening(*pDocSh);
+ EndListening(*GetViewFrame());
+ EndListening(*SFX_APP()); // #i62045# #i62046# needed now - SfxViewShell no longer does it
+
+ SC_MOD()->ViewShellGone(this);
+
+ RemoveSubShell(); // alle
+ SetWindow(0);
+
+ // #54104# alles auf NULL, falls aus dem TabView-dtor noch darauf zugegriffen wird
+ //! (soll eigentlich nicht !??!?!)
+
+ DELETEZ(pFontworkBarShell);
+ DELETEZ(pExtrusionBarShell);
+ DELETEZ(pCellShell);
+ DELETEZ(pPageBreakShell);
+ DELETEZ(pDrawShell);
+ DELETEZ(pDrawFormShell);
+ DELETEZ(pOleObjectShell);
+ DELETEZ(pChartShell);
+ DELETEZ(pGraphicShell);
+ DELETEZ(pMediaShell);
+ DELETEZ(pDrawTextShell);
+ DELETEZ(pEditShell);
+ DELETEZ(pPivotShell);
+ DELETEZ(pAuditingShell);
+ DELETEZ(pCurFrameLine);
+ DELETEZ(pInputHandler);
+ DELETEZ(pPivotSource);
+ DELETEZ(pDialogDPObject);
+ DELETEZ(pNavSettings);
+
+ DELETEZ(pFormShell);
+ DELETEZ(pAccessibilityBroadcaster);
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetDialogDPObject( const ScDPObject* pObj )
+{
+ delete pDialogDPObject;
+ if (pObj)
+ pDialogDPObject = new ScDPObject( *pObj );
+ else
+ pDialogDPObject = NULL;
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::FillFieldData( ScHeaderFieldData& rData )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ pDoc->GetName( nTab, rData.aTabName );
+
+ rData.aTitle = pDocShell->GetTitle();
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ rData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if ( rData.aLongDocName.Len() )
+ rData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
+ else
+ rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+ rData.nPageNo = 1;
+ rData.nTotalPages = 99;
+
+ // eNumType kennt der Dialog selber
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetChartArea( const ScRangeListRef& rSource, const Rectangle& rDest )
+{
+ bChartAreaValid = TRUE;
+ aChartSource = rSource;
+ aChartPos = rDest;
+ nChartDestTab = GetViewData()->GetTabNo();
+}
+
+//UNUSED2008-05 void ScTabViewShell::ResetChartArea()
+//UNUSED2008-05 {
+//UNUSED2008-05 bChartAreaValid = FALSE;
+//UNUSED2008-05 }
+
+BOOL ScTabViewShell::GetChartArea( ScRangeListRef& rSource, Rectangle& rDest, SCTAB& rTab ) const
+{
+ rSource = aChartSource;
+ rDest = aChartPos;
+ rTab = nChartDestTab;
+ return bChartAreaValid;
+}
+
+//UNUSED2008-05 BOOL ScTabViewShell::IsChartDlgEdit() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return bChartDlgIsEdit;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 const String& ScTabViewShell::GetEditChartName() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return aEditChartName;
+//UNUSED2008-05 }
+
+ScNavigatorSettings* ScTabViewShell::GetNavigatorSettings()
+{
+ if( !pNavSettings )
+ pNavSettings = new ScNavigatorSettings;
+ return pNavSettings;
+}
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecTbx( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+ const SfxPoolItem* pItem = NULL;
+ if ( pReqArgs )
+ pReqArgs->GetItemState( nSlot, TRUE, &pItem );
+
+ switch ( nSlot )
+ {
+ case SID_TBXCTL_INSERT:
+ if ( pItem )
+ nInsertCtrlState = ((const SfxUInt16Item*)pItem)->GetValue();
+ break;
+ case SID_TBXCTL_INSCELLS:
+ if ( pItem )
+ nInsCellsCtrlState = ((const SfxUInt16Item*)pItem)->GetValue();
+ break;
+ case SID_TBXCTL_INSOBJ:
+ if ( pItem )
+ nInsObjCtrlState = ((const SfxUInt16Item*)pItem)->GetValue();
+ break;
+ default:
+ DBG_ERROR("Slot im Wald");
+ }
+ GetViewFrame()->GetBindings().Invalidate( nSlot );
+}
+
+void ScTabViewShell::GetTbxState( SfxItemSet& rSet )
+{
+ rSet.Put( SfxUInt16Item( SID_TBXCTL_INSERT, nInsertCtrlState ) );
+ rSet.Put( SfxUInt16Item( SID_TBXCTL_INSCELLS, nInsCellsCtrlState ) );
+
+ // ohne installiertes Chart darf Chart nicht Default sein...
+ if ( nInsObjCtrlState == SID_DRAW_CHART && !SvtModuleOptions().IsChart() )
+ nInsObjCtrlState = SID_INSERT_OBJECT;
+
+ rSet.Put( SfxUInt16Item( SID_TBXCTL_INSOBJ, nInsObjCtrlState ) );
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx
new file mode 100644
index 000000000000..1a3dd6928a17
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh5.cxx
@@ -0,0 +1,428 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <svl/smplhint.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/numfmtsh.hxx>
+#include <svx/numinf.hxx>
+#include <svx/svxids.hrc>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "global.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "uiitems.hxx"
+#include "editsh.hxx"
+#include "hints.hxx"
+
+
+//==================================================================
+
+void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA(SfxSimpleHint)) // ohne Parameter
+ {
+ ULONG nSlot = ((SfxSimpleHint&)rHint).GetId();
+ switch ( nSlot )
+ {
+ case FID_DATACHANGED:
+ UpdateFormulas();
+ break;
+
+ case FID_REFMODECHANGED:
+ {
+ BOOL bRefMode = SC_MOD()->IsFormulaMode();
+ if (!bRefMode)
+ StopRefMode();
+ else
+ {
+ GetSelEngine()->Reset();
+ GetFunctionSet()->SetAnchorFlag(TRUE);
+ // AnchorFlag, damit gleich mit Control angehaengt werden kann
+ }
+ }
+ break;
+
+ case FID_KILLEDITVIEW:
+ case FID_KILLEDITVIEW_NOPAINT:
+ StopEditShell();
+ KillEditView( nSlot == FID_KILLEDITVIEW_NOPAINT );
+ break;
+
+ case SFX_HINT_DOCCHANGED:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (!pDoc->HasTable( GetViewData()->GetTabNo() ))
+ {
+ SetTabNo(0);
+ }
+ }
+ break;
+
+ case SC_HINT_DRWLAYER_NEW:
+ MakeDrawView();
+ break;
+
+ case SC_HINT_DOC_SAVED:
+ {
+ // beim "Save as" kann ein vorher schreibgeschuetztes Dokument
+ // bearbeitbar werden, deshalb die Layer-Locks neu (#39884#)
+ // (Invalidate etc. passiert schon vom Sfx her)
+ // #42091# bei SID_EDITDOC kommt kein SFX_HINT_TITLECHANGED, darum
+ // der eigene Hint aus DoSaveCompleted
+ //! was ist mit SFX_HINT_SAVECOMPLETED ?
+
+ UpdateLayerLocks();
+
+ // #54891# Design-Modus bei jedem Speichern anzupassen, waere zuviel
+ // (beim Speichern unter gleichem Namen soll er unveraendert bleiben)
+ // Darum nur bei SFX_HINT_MODECHANGED (vom ViewFrame)
+ }
+ break;
+
+ case SFX_HINT_MODECHANGED:
+ // #54891#/#58510# Da man sich nicht mehr darauf verlassen kann, woher
+ // dieser Hint kommt, den Design-Modus immer dann umschalten, wenn der
+ // ReadOnly-Status sich wirklich geaendert hat:
+
+ if ( GetViewData()->GetSfxDocShell()->IsReadOnly() != bReadOnly )
+ {
+ bReadOnly = GetViewData()->GetSfxDocShell()->IsReadOnly();
+
+ SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadOnly);
+ GetViewData()->GetDispatcher().Execute( SID_FM_DESIGN_MODE, SFX_CALLMODE_ASYNCHRON,
+ &aItem, 0L );
+
+ UpdateInputContext();
+ }
+ break;
+
+ case SC_HINT_SHOWRANGEFINDER:
+ PaintRangeFinder();
+ break;
+
+ case SC_HINT_FORCESETTAB:
+ SetTabNo( GetViewData()->GetTabNo(), TRUE );
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (rHint.ISA(ScPaintHint)) // neu zeichnen
+ {
+ ScPaintHint* pHint = (ScPaintHint*) &rHint;
+ USHORT nParts = pHint->GetParts();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if (pHint->GetStartTab() <= nTab && pHint->GetEndTab() >= nTab)
+ {
+ if (nParts & PAINT_EXTRAS) // zuerst, falls Tabelle weg ist !!!
+ 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)
+ PaintArea( pHint->GetStartCol(), pHint->GetStartRow(),
+ pHint->GetEndCol(), pHint->GetEndRow() );
+ if (nParts & PAINT_MARKS)
+ PaintArea( pHint->GetStartCol(), pHint->GetStartRow(),
+ pHint->GetEndCol(), pHint->GetEndRow(), SC_UPDATE_MARKS );
+ if (nParts & PAINT_LEFT)
+ PaintLeftArea( pHint->GetStartRow(), pHint->GetEndRow() );
+ if (nParts & PAINT_TOP)
+ PaintTopArea( pHint->GetStartCol(), pHint->GetEndCol() );
+ if (nParts & PAINT_INVERT)
+ InvertBlockMark( pHint->GetStartCol(), pHint->GetStartRow(),
+ pHint->GetEndCol(), pHint->GetEndRow() );
+
+ // #i84689# call UpdateAllOverlays here instead of in ScTabView::PaintArea
+ if (nParts & ( PAINT_LEFT | PAINT_TOP )) // only if widths or heights changed
+ UpdateAllOverlays();
+
+ HideNoteMarker();
+ }
+ }
+ else if (rHint.ISA(ScEditViewHint)) // Edit-View anlegen
+ {
+ // ScEditViewHint kommt nur an aktiver View an
+
+ ScEditViewHint* pHint = (ScEditViewHint*) &rHint;
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if ( pHint->GetTab() == nTab )
+ {
+ SCCOL nCol = pHint->GetCol();
+ SCROW nRow = pHint->GetRow();
+ {
+ HideNoteMarker();
+
+ MakeEditView( pHint->GetEngine(), nCol, nRow );
+
+ StopEditShell(); // sollte nicht gesetzt sein
+
+ ScSplitPos eActive = GetViewData()->GetActivePart();
+ if ( GetViewData()->HasEditView(eActive) )
+ {
+ // MakeEditView geht schief, wenn der Cursor ausserhalb des
+ // Bildschirms steht. GetEditView gibt dann eine nicht aktive
+ // View zurueck, darum die Abfrage HasEditView.
+
+ EditView* pView = GetViewData()->GetEditView(eActive); // ist nicht 0
+
+ SetEditShell(pView ,TRUE);
+ }
+ }
+ }
+ }
+ else if (rHint.ISA(ScTablesHint)) // Tabelle eingefuegt / geloescht
+ {
+ // aktuelle Tabelle zuerst holen (kann bei DeleteTab an ViewData geaendert werden)
+ SCTAB nActiveTab = GetViewData()->GetTabNo();
+
+ const ScTablesHint& rTabHint = (const ScTablesHint&)rHint;
+ SCTAB nTab1 = rTabHint.GetTab1();
+ SCTAB nTab2 = rTabHint.GetTab2();
+ USHORT nId = rTabHint.GetId();
+ switch (nId)
+ {
+ case SC_TAB_INSERTED:
+ GetViewData()->InsertTab( nTab1 );
+ break;
+ case SC_TAB_DELETED:
+ GetViewData()->DeleteTab( nTab1 );
+ break;
+ case SC_TAB_MOVED:
+ GetViewData()->MoveTab( nTab1, nTab2 );
+ break;
+ case SC_TAB_COPIED:
+ GetViewData()->CopyTab( nTab1, nTab2 );
+ break;
+ case SC_TAB_HIDDEN:
+ break;
+ default:
+ DBG_ERROR("unbekannter ScTablesHint");
+ }
+
+ // hier keine Abfrage auf IsActive() mehr, weil die Aktion von Basic ausgehen
+ // kann und dann auch die aktive View umgeschaltet werden muss.
+
+ SCTAB nNewTab = nActiveTab;
+ BOOL bForce = FALSE;
+ switch (nId)
+ {
+ case SC_TAB_INSERTED:
+ if ( nTab1 <= nNewTab ) // vorher eingefuegt
+ ++nNewTab;
+ break;
+ case SC_TAB_DELETED:
+ if ( nTab1 < nNewTab ) // vorher geloescht
+ --nNewTab;
+ else if ( nTab1 == nNewTab ) // aktuelle geloescht
+ bForce = TRUE;
+ break;
+ case SC_TAB_MOVED:
+ if ( nNewTab == nTab1 ) // verschobene Tabelle
+ nNewTab = nTab2;
+ else if ( nTab1 < nTab2 ) // nach hinten verschoben
+ {
+ if ( nNewTab > nTab1 && nNewTab <= nTab2 ) // nachrueckender Bereich
+ --nNewTab;
+ }
+ else // nach vorne verschoben
+ {
+ if ( nNewTab >= nTab2 && nNewTab < nTab1 ) // nachrueckender Bereich
+ ++nNewTab;
+ }
+ break;
+ case SC_TAB_COPIED:
+ if ( nNewTab >= nTab2 ) // vorher eingefuegt
+ ++nNewTab;
+ break;
+ case SC_TAB_HIDDEN:
+ if ( nTab1 == nNewTab ) // aktuelle ausgeblendet
+ bForce = TRUE;
+ break;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( nNewTab >= pDoc->GetTableCount() )
+ nNewTab = pDoc->GetTableCount() - 1;
+
+ SetTabNo( nNewTab, bForce );
+ }
+ else if (rHint.ISA(ScIndexHint))
+ {
+ const ScIndexHint& rIndexHint = (const ScIndexHint&)rHint;
+ USHORT nId = rIndexHint.GetId();
+ USHORT nIndex = rIndexHint.GetIndex();
+ switch (nId)
+ {
+ case SC_HINT_SHOWRANGEFINDER:
+ PaintRangeFinder( nIndex );
+ break;
+ }
+ }
+
+ SfxViewShell::Notify( rBC, rHint );
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::MakeNumberInfoItem( ScDocument* pDoc,
+ ScViewData* pViewData,
+ SvxNumberInfoItem** ppItem )
+{
+ //------------------------------
+ // NumberInfo-Item konstruieren:
+ //------------------------------
+ ScBaseCell* pCell = NULL;
+ SvxNumberValueType eValType = SVX_VALUE_TYPE_UNDEFINED;
+ double nCellValue = 0;
+ String aCellString;
+
+ pDoc->GetCell( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo(),
+ pCell );
+
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ {
+ nCellValue = ((ScValueCell*)pCell)->GetValue();
+ eValType = SVX_VALUE_TYPE_NUMBER;
+ aCellString.Erase();
+ }
+ break;
+
+ case CELLTYPE_STRING:
+ {
+ ((ScStringCell*)pCell)->GetString( aCellString );
+ eValType = SVX_VALUE_TYPE_STRING;
+ }
+ break;
+
+ case CELLTYPE_FORMULA:
+ {
+ if ( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ nCellValue = ((ScFormulaCell*)pCell)->GetValue();
+ eValType = SVX_VALUE_TYPE_NUMBER;
+ }
+ else
+ {
+ nCellValue = 0;
+ eValType = SVX_VALUE_TYPE_UNDEFINED;
+ }
+ aCellString.Erase();
+ }
+ break;
+
+ default:
+ nCellValue = 0;
+ eValType = SVX_VALUE_TYPE_UNDEFINED;
+ aCellString.Erase();
+ }
+ }
+ else // Zelle noch leer (== nicht erzeugt)
+ {
+ nCellValue = 0;
+ eValType = SVX_VALUE_TYPE_UNDEFINED;
+ aCellString.Erase();
+ }
+
+ switch ( eValType )
+ {
+ case SVX_VALUE_TYPE_STRING:
+ *ppItem = new SvxNumberInfoItem(
+ pDoc->GetFormatTable(),
+ aCellString,
+ SID_ATTR_NUMBERFORMAT_INFO );
+ break;
+
+ case SVX_VALUE_TYPE_NUMBER:
+ *ppItem = new SvxNumberInfoItem(
+ pDoc->GetFormatTable(),
+ nCellValue,
+ SID_ATTR_NUMBERFORMAT_INFO );
+ break;
+
+ case SVX_VALUE_TYPE_UNDEFINED:
+ default:
+ *ppItem = new SvxNumberInfoItem(
+ pDoc->GetFormatTable(),
+ (const USHORT)
+ SID_ATTR_NUMBERFORMAT_INFO );
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::UpdateNumberFormatter(
+ ScDocument* pDoc,
+ const SvxNumberInfoItem& rInfoItem )
+{
+ const sal_uInt32 nDelCount = rInfoItem.GetDelCount();
+
+ if ( nDelCount > 0 )
+ {
+ const sal_uInt32* pDelArr = rInfoItem.GetDelArray();
+
+ for ( USHORT i=0; i<nDelCount; i++ )
+ rInfoItem.GetNumberFormatter()->DeleteEntry( pDelArr[i] );
+ }
+
+ // sollte besser UpdateNumberFormats() heissen ?
+ pDoc->DeleteNumberFormat( rInfoItem.GetDelArray(),
+ rInfoItem.GetDelCount() );
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwsh8.cxx b/sc/source/ui/view/tabvwsh8.cxx
new file mode 100644
index 000000000000..b3612fa0c6f2
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh8.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+
+#include "tabvwsh.hxx"
+#include "document.hxx"
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetDefaultFrameLine( const SvxBorderLine* pLine )
+{
+ if ( pLine )
+ {
+ delete pCurFrameLine;
+ pCurFrameLine = new SvxBorderLine( &pLine->GetColor(),
+ pLine->GetOutWidth(),
+ pLine->GetInWidth(),
+ pLine->GetDistance() );
+ }
+ else if ( pCurFrameLine )
+ {
+ delete pCurFrameLine;
+ pCurFrameLine = NULL;
+ }
+}
+
+//------------------------------------------------------------------
+
+BOOL __EXPORT ScTabViewShell::HasSelection( BOOL bText ) const
+{
+ BOOL bHas = FALSE;
+ ScViewData* pData = (ScViewData*)GetViewData(); // const weggecasted
+ if ( bText )
+ {
+ // Text enthalten: Anzahl2 >= 1
+ ScDocument* pDoc = pData->GetDocument();
+ ScMarkData& rMark = pData->GetMarkData();
+ ScAddress aCursor( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+ double fVal = 0.0;
+ if ( pDoc->GetSelectionFunction( SUBTOTAL_FUNC_CNT2, aCursor, rMark, fVal ) )
+ bHas = ( fVal > 0.5 );
+ }
+ else
+ {
+ ScRange aRange;
+ ScMarkType eMarkType = pData->GetSimpleArea( aRange );
+ if ( eMarkType == SC_MARK_SIMPLE )
+ bHas = ( aRange.aStart != aRange.aEnd ); // more than 1 cell
+ else
+ bHas = TRUE; // multiple selection or filtered
+ }
+ return bHas;
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::UIDeactivated( SfxInPlaceClient* pClient )
+{
+ ClearHighlightRanges();
+
+ // Move an der ViewShell soll eigentlich vom Sfx gerufen werden, wenn sich
+ // das Frame-Window wegen unterschiedlicher Toolboxen o.ae. verschiebt
+ // (um nicht aus Versehen z.B. Zeichenobjekte zu verschieben, #56515#).
+ // Dieser Mechanismus funktioniert aber momentan nicht, darum hier der Aufruf
+ // per Hand (im Move wird verglichen, ob die Position wirklich geaendert ist).
+ ForceMove();
+ SfxViewShell::UIDeactivated( pClient );
+}
+
+
diff --git a/sc/source/ui/view/tabvwsh9.cxx b/sc/source/ui/view/tabvwsh9.cxx
new file mode 100644
index 000000000000..30f9c50fd925
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh9.cxx
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+#include <svx/galbrws.hxx>
+#include <svx/gallery.hxx>
+#include <svx/hlnkitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/whiter.hxx>
+#include <avmedia/mediaplayer.hxx>
+
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+#include "tabview.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "docsh.hxx"
+
+// forwards -> galwrap.cxx (wg. CLOOKs)
+
+USHORT GallerySGA_FORMAT_GRAPHIC();
+Graphic GalleryGetGraphic ();
+BOOL GalleryIsLinkage ();
+String GalleryGetFullPath ();
+String GalleryGetFilterName ();
+
+// forwards -> imapwrap.cxx (wg. CLOOKs)
+
+class SvxIMapDlg;
+
+USHORT ScIMapChildWindowId();
+SvxIMapDlg* ScGetIMapDlg();
+const void* ScIMapDlgGetObj( SvxIMapDlg* pDlg );
+const ImageMap& ScIMapDlgGetMap( SvxIMapDlg* pDlg );
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecChildWin(SfxRequest& rReq)
+{
+ USHORT nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case SID_GALLERY:
+ {
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ pThisFrame->ToggleChildWindow( GalleryChildWindow::GetChildWindowId() );
+ pThisFrame->GetBindings().Invalidate( SID_GALLERY );
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_AVMEDIA_PLAYER:
+ {
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ pThisFrame->ToggleChildWindow( ::avmedia::MediaPlayer::GetChildWindowId() );
+ pThisFrame->GetBindings().Invalidate( SID_AVMEDIA_PLAYER );
+ rReq.Ignore();
+ }
+ break;
+ }
+}
+
+void ScTabViewShell::GetChildWinState( SfxItemSet& rSet )
+{
+ if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_GALLERY ) )
+ {
+ USHORT nId = GalleryChildWindow::GetChildWindowId();
+ rSet.Put( SfxBoolItem( SID_GALLERY, GetViewFrame()->HasChildWindow( nId ) ) );
+ }
+ else if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_AVMEDIA_PLAYER ) )
+ {
+ USHORT nId = ::avmedia::MediaPlayer::GetChildWindowId();
+ rSet.Put( SfxBoolItem( SID_AVMEDIA_PLAYER, GetViewFrame()->HasChildWindow( nId ) ) );
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecGallery( SfxRequest& rReq )
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ if ( pArgs )
+ {
+ const SfxPoolItem* pItem = NULL;
+ SfxItemState eState = pArgs->GetItemState(SID_GALLERY_FORMATS, TRUE, &pItem);
+ if ( eState == SFX_ITEM_SET )
+ {
+ UINT32 nFormats = ((const SfxUInt32Item*)pItem)->GetValue();
+
+ /******************************************************************
+ * Graphik einfuegen
+ ******************************************************************/
+ if ( nFormats & GallerySGA_FORMAT_GRAPHIC() )
+ {
+ MakeDrawLayer();
+
+ Graphic aGraphic = GalleryGetGraphic();
+ Point aPos = GetInsertPos();
+
+ String aPath, aFilter;
+ if ( GalleryIsLinkage() ) // als Link einfuegen?
+ {
+ aPath = GalleryGetFullPath();
+ aFilter = GalleryGetFilterName();
+ }
+
+ PasteGraphic( aPos, aGraphic, aPath, aFilter );
+ }
+ else if ( nFormats & SGA_FORMAT_SOUND )
+ {
+ // #98115# for sounds (linked or not), insert a hyperlink button,
+ // like in Impress and Writer
+
+ GalleryExplorer* pGal = SVX_GALLERY();
+ if ( pGal )
+ {
+ const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, pGal->GetURL().GetMainURL( INetURLObject::NO_DECODE ) );
+ GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON, &aMediaURLItem, 0L );
+ }
+ }
+ }
+ }
+}
+
+void ScTabViewShell::GetGalleryState( SfxItemSet& /* rSet */ )
+{
+}
+
+//------------------------------------------------------------------
+
+ScInputHandler* ScTabViewShell::GetInputHandler() const
+{
+ return pInputHandler;
+}
+
+//------------------------------------------------------------------
+
+String __EXPORT ScTabViewShell::GetDescription() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" ** Test ** "));
+}
+
+void ScTabViewShell::ExecImageMap( SfxRequest& rReq )
+{
+ USHORT nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case SID_IMAP:
+ {
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ USHORT nId = ScIMapChildWindowId();
+ pThisFrame->ToggleChildWindow( nId );
+ GetViewFrame()->GetBindings().Invalidate( SID_IMAP );
+
+ if ( pThisFrame->HasChildWindow( nId ) )
+ {
+ SvxIMapDlg* pDlg = ScGetIMapDlg();
+ if ( pDlg )
+ {
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if ( rMarkList.GetMarkCount() == 1 )
+ UpdateIMap( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
+ }
+ }
+ }
+
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_IMAP_EXEC:
+ {
+ SdrView* pDrView = GetSdrView();
+ SdrMark* pMark = pDrView ? pDrView->GetMarkedObjectList().GetMark(0) : 0;
+
+ if ( pMark )
+ {
+ SdrObject* pSdrObj = pMark->GetMarkedSdrObj();
+ SvxIMapDlg* pDlg = ScGetIMapDlg();
+
+ if ( ScIMapDlgGetObj(pDlg) == (void*) pSdrObj )
+ {
+ const ImageMap& rImageMap = ScIMapDlgGetMap(pDlg);
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo( pSdrObj );
+
+ if ( !pIMapInfo )
+ pSdrObj->InsertUserData( new ScIMapInfo( rImageMap ) );
+ else
+ pIMapInfo->SetImageMap( rImageMap );
+
+ GetViewData()->GetDocShell()->SetDrawModified();
+ }
+ }
+ }
+ break;
+ }
+}
+
+void ScTabViewShell::GetImageMapState( SfxItemSet& rSet )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_IMAP:
+ {
+ // Disabled wird nicht mehr...
+
+ BOOL bThere = FALSE;
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ USHORT nId = ScIMapChildWindowId();
+ if ( pThisFrame->KnowsChildWindow(nId) )
+ if ( pThisFrame->HasChildWindow(nId) )
+ bThere = TRUE;
+
+ ObjectSelectionType eType=GetCurObjectSelectionType();
+ BOOL bEnable=(eType==OST_OleObject) ||(eType==OST_Graphic);
+ if(!bThere && !bEnable)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( nWhich, bThere ) );
+ }
+ }
+ break;
+
+ case SID_IMAP_EXEC:
+ {
+ BOOL bDisable = TRUE;
+
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if ( rMarkList.GetMarkCount() == 1 )
+ if ( ScIMapDlgGetObj(ScGetIMapDlg()) ==
+ (void*) rMarkList.GetMark(0)->GetMarkedSdrObj() )
+ bDisable = FALSE;
+ }
+
+ rSet.Put( SfxBoolItem( SID_IMAP_EXEC, bDisable ) );
+ }
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
new file mode 100644
index 000000000000..7734f3e24ff8
--- /dev/null
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -0,0 +1,890 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/zformat.hxx>
+#include <editeng/boxitem.hxx>
+#include <svx/numinf.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "global.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "document.hxx"
+#include "cell.hxx" // Input Status Edit-Zellen
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+//CHINA001 #include "attrdlg.hxx"
+#include "appoptio.hxx"
+#include "sc.hrc"
+#include "stlpool.hxx"
+#include "tabvwsh.hxx"
+#include "dwfunctr.hxx"
+#include "scabstdlg.hxx" //CHINA001
+#include "compiler.hxx"
+
+
+BOOL ScTabViewShell::GetFunction( String& rFuncStr, sal_uInt16 nErrCode )
+{
+ String aStr;
+
+ ScSubTotalFunc eFunc = (ScSubTotalFunc) SC_MOD()->GetAppOptions().GetStatusFunc();
+ ScViewData* pViewData = GetViewData();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ bool bIgnoreError = (rMark.IsMarked() || rMark.IsMultiMarked());
+
+ if (bIgnoreError && (eFunc == SUBTOTAL_FUNC_CNT || eFunc == SUBTOTAL_FUNC_CNT2))
+ nErrCode = 0;
+
+ if (nErrCode)
+ {
+ rFuncStr = ScGlobal::GetLongErrorString(nErrCode);
+ return true;
+ }
+
+ USHORT nGlobStrId = 0;
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_AVE: nGlobStrId = STR_FUN_TEXT_AVG; break;
+ case SUBTOTAL_FUNC_CNT: nGlobStrId = STR_FUN_TEXT_COUNT; break;
+ case SUBTOTAL_FUNC_CNT2: nGlobStrId = STR_FUN_TEXT_COUNT2; break;
+ case SUBTOTAL_FUNC_MAX: nGlobStrId = STR_FUN_TEXT_MAX; break;
+ case SUBTOTAL_FUNC_MIN: nGlobStrId = STR_FUN_TEXT_MIN; break;
+ case SUBTOTAL_FUNC_SUM: nGlobStrId = STR_FUN_TEXT_SUM; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if (nGlobStrId)
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ aStr = ScGlobal::GetRscString(nGlobStrId);
+ aStr += '=';
+
+ ScAddress aCursor( nPosX, nPosY, nTab );
+ double nVal;
+ if ( pDoc->GetSelectionFunction( eFunc, aCursor, rMark, nVal ) )
+ {
+ if ( nVal == 0.0 )
+ aStr += '0';
+ else
+ {
+ // Anzahl im Standardformat, die anderen nach Cursorposition
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_uInt32 nNumFmt = 0;
+ if ( eFunc != SUBTOTAL_FUNC_CNT && eFunc != SUBTOTAL_FUNC_CNT2 )
+ {
+ // Zahlformat aus Attributen oder Formel
+ pDoc->GetNumberFormat( nPosX, nPosY, nTab, nNumFmt );
+ if ( (nNumFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ {
+ ScBaseCell* pCell;
+ pDoc->GetCell( nPosX, nPosY, nTab, pCell );
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+
+ nNumFmt = ((ScFormulaCell*)pCell)->GetStandardFormat(*pFormatter, nNumFmt );
+ }
+ }
+ }
+
+ String aValStr;
+ Color* pDummy;
+ pFormatter->GetOutputString( nVal, nNumFmt, aValStr, &pDummy );
+ aStr += aValStr;
+ }
+ }
+
+ rFuncStr = aStr;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
+// Funktionen, die je nach Selektion disabled sind
+// Default:
+// SID_DELETE,
+// SID_DELETE_CONTENTS,
+// FID_DELETE_CELL
+// FID_VALIDATION
+
+
+void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ USHORT nMyId = 0;
+
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ BOOL bOle = GetViewFrame()->GetFrame().IsInPlace();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case FID_CHG_COMMENT:
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScAddress aPos( nPosX, nPosY, nTab );
+ if ( pDocSh->IsReadOnly() || !pDocSh->GetChangeAction(aPos) || pDocSh->IsDocShared() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_OPENDLG_EDIT_PRINTAREA:
+ case SID_ADD_PRINTAREA:
+ case SID_DEFINE_PRINTAREA:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_DELETE_PRINTAREA:
+ if ( nTabSelCount > 1 )
+ {
+ // #i22589# also take "Print Entire Sheet" into account here
+ BOOL bHas = FALSE;
+ for (SCTAB i=0; !bHas && i<nTabCount; i++)
+ bHas = rMark.GetTableSelect(i) && (pDoc->GetPrintRangeCount(i) || pDoc->IsPrintEntireSheet(i));
+ if (!bHas)
+ rSet.DisableItem( nWhich );
+ }
+ else if ( !pDoc->GetPrintRangeCount( nTab ) && !pDoc->IsPrintEntireSheet( nTab ) )
+ rSet.DisableItem( nWhich );
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ GetViewData()->GetDocShell()->GetStatePageStyle( *this, rSet, nTab );
+ break;
+
+ case SID_SEARCH_ITEM:
+ rSet.Put( ScGlobal::GetSearchItem() );
+ break;
+
+ case SID_SEARCH_OPTIONS:
+ {
+ USHORT nOptions = 0xffff; // alles erlaubt
+ // wenn ReadOnly, kein Ersetzen:
+ if (GetViewData()->GetDocShell()->IsReadOnly())
+ nOptions &= ~( SEARCH_OPTIONS_REPLACE | SEARCH_OPTIONS_REPLACE_ALL );
+ rSet.Put( SfxUInt16Item( nWhich, nOptions ) );
+ }
+ break;
+
+ case SID_CURRENTCELL:
+ {
+ ScAddress aScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), 0 );
+ String aAddr;
+ aScAddress.Format( aAddr, SCA_ABS, NULL, pDoc->GetAddressConvention() );
+ SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
+
+ rSet.Put( aPosItem );
+ }
+ break;
+
+ case SID_CURRENTTAB:
+ // Tabelle fuer Basic ist 1-basiert
+ rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(GetViewData()->GetTabNo()) + 1 ) );
+ break;
+
+ case SID_CURRENTDOC:
+ rSet.Put( SfxStringItem( nWhich, GetViewData()->GetDocShell()->GetTitle() ) );
+ break;
+
+ case FID_TOGGLEINPUTLINE:
+ {
+ USHORT nId = ScInputWindowWrapper::GetChildWindowId();
+
+ if ( pThisFrame->KnowsChildWindow( nId ) )
+ {
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+ rSet.Put( SfxBoolItem( nWhich, pWnd ? TRUE : FALSE ) );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_DEL_MANUALBREAKS:
+ if (!pDoc->HasManualBreaks(nTab))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_RESET_PRINTZOOM:
+ {
+ // disablen, wenn schon Default eingestellt
+
+ String aStyleName = pDoc->GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName,
+ SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ USHORT nScale = ((const SfxUInt16Item&)
+ rStyleSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ USHORT nPages = ((const SfxUInt16Item&)
+ rStyleSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
+ if ( nScale == 100 && nPages == 0 )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_SCALE:
+ case SID_ATTR_ZOOM:
+ if ( bOle )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ const Fraction& rOldY = GetViewData()->GetZoomY();
+ USHORT nZoom = (USHORT)(( rOldY.GetNumerator() * 100 )
+ / rOldY.GetDenominator());
+ rSet.Put( SvxZoomItem( SVX_ZOOM_PERCENT, nZoom, nWhich ) );
+ }
+ break;
+
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ if ( bOle )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ const Fraction& rOldY = GetViewData()->GetZoomY();
+ USHORT nCurrentZoom = (USHORT)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
+
+ if( nCurrentZoom )
+ {
+ SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ }
+ }
+ break;
+
+ case FID_TOGGLESYNTAX:
+ rSet.Put(SfxBoolItem(nWhich, GetViewData()->IsSyntaxMode()));
+ break;
+
+ case FID_TOGGLEHEADERS:
+ rSet.Put(SfxBoolItem(nWhich, GetViewData()->IsHeaderMode()));
+ break;
+
+ case FID_TOGGLEFORMULA:
+ {
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ BOOL bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
+ rSet.Put(SfxBoolItem(nWhich, bFormulaMode ));
+ }
+ break;
+
+ case FID_NORMALVIEWMODE:
+ case FID_PAGEBREAKMODE:
+ // always handle both slots - they exclude each other
+ if ( bOle )
+ {
+ rSet.DisableItem( FID_NORMALVIEWMODE );
+ rSet.DisableItem( FID_PAGEBREAKMODE );
+ }
+ else
+ {
+ rSet.Put(SfxBoolItem(FID_NORMALVIEWMODE, !GetViewData()->IsPagebreakMode()));
+ rSet.Put(SfxBoolItem(FID_PAGEBREAKMODE, GetViewData()->IsPagebreakMode()));
+ }
+ break;
+
+ case FID_FUNCTION_BOX:
+ nMyId = ScFunctionChildWindow::GetChildWindowId();
+ rSet.Put(SfxBoolItem(FID_FUNCTION_BOX, pThisFrame->HasChildWindow(nMyId)));
+ break;
+
+ case FID_PROTECT_DOC:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsDocProtected() ) );
+ }
+ }
+ break;
+
+ case FID_PROTECT_TABLE:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsTabProtected( nTab ) ) );
+ }
+ }
+ break;
+
+ case SID_AUTO_OUTLINE:
+ {
+ if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_OUTLINE_DELETEALL:
+ {
+ SCTAB nOlTab = GetViewData()->GetTabNo();
+ ScOutlineTable* pOlTable = pDoc->GetOutlineTable( nOlTab );
+ if (pOlTable == NULL)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_WINDOW_SPLIT:
+ rSet.Put(SfxBoolItem(nWhich,
+ pViewData->GetHSplitMode() == SC_SPLIT_NORMAL ||
+ pViewData->GetVSplitMode() == SC_SPLIT_NORMAL ));
+ break;
+
+ case SID_WINDOW_FIX:
+ rSet.Put(SfxBoolItem(nWhich,
+ pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+ pViewData->GetVSplitMode() == SC_SPLIT_FIX ));
+ break;
+
+ case FID_CHG_SHOW:
+ {
+ if ( pDoc->GetChangeTrack() == NULL || ( pDocShell && pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case FID_CHG_ACCEPT:
+ {
+ rSet.Put(SfxBoolItem(FID_CHG_ACCEPT,
+ pThisFrame->HasChildWindow(FID_CHG_ACCEPT)));
+ if(pDoc->GetChangeTrack()==NULL)
+ {
+ if ( !pThisFrame->HasChildWindow(FID_CHG_ACCEPT) )
+ {
+ rSet.DisableItem( nWhich);
+ }
+ }
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_FORMATPAGE:
+ //! bei geschuetzten Tabellen ???
+ if ( pDocShell && ( pDocShell->IsReadOnly() || pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_PRINTPREVIEW:
+ // #58924# Toggle-Slot braucht einen State
+ rSet.Put( SfxBoolItem( nWhich, FALSE ) );
+ break;
+
+ case SID_READONLY_MODE:
+ rSet.Put( SfxBoolItem( nWhich, GetViewData()->GetDocShell()->IsReadOnly() ) );
+ break;
+
+ case FID_TAB_DESELECTALL:
+ if ( nTabSelCount == 1 )
+ rSet.DisableItem( nWhich ); // enabled only if several sheets are selected
+ break;
+
+ } // switch ( nWitch )
+ nWhich = aIter.NextWhich();
+ } // while ( nWitch )
+}
+
+//------------------------------------------------------------------
+void ScTabViewShell::ExecuteCellFormatDlg( SfxRequest& rReq, USHORT nTabPage )
+{
+ //CHINA001 ScAttrDlg* pDlg = NULL;
+ SfxAbstractTabDialog * pDlg = NULL; //CHINA001
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ SvxBoxItem aLineOuter( ATTR_BORDER );
+ SvxBoxInfoItem aLineInner( ATTR_BORDER_INNER );
+
+ SvxNumberInfoItem* pNumberInfoItem = NULL;
+ const ScPatternAttr* pOldAttrs = GetSelectionPattern();
+ SfxItemSet* pOldSet = new SfxItemSet(
+ pOldAttrs->GetItemSet() );
+
+
+ // Umrandungs-Items holen und in den Set packen:
+ GetSelectionFrame( aLineOuter, aLineInner );
+ pOldSet->Put( aLineOuter );
+ pOldSet->Put( aLineInner );
+
+ // NumberFormat Value aus Value und Language erzeugen und eintueten
+ pOldSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT,
+ pOldAttrs->GetNumberFormat( pDoc->GetFormatTable() ) ) );
+
+ MakeNumberInfoItem( pDoc, GetViewData(), &pNumberInfoItem );
+
+ pOldSet->MergeRange( SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO );
+ pOldSet->Put(*pNumberInfoItem );
+
+ bInFormatDialog = TRUE;
+ //CHINA001 pDlg = new ScAttrDlg( GetViewFrame(), GetDialogParent(), pOldSet );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScAttrDlg( GetViewFrame(), GetDialogParent(), pOldSet, RID_SCDLG_ATTR);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( nTabPage != 0xffff )
+ pDlg->SetCurPageId( nTabPage );
+ short nResult = pDlg->Execute();
+ bInFormatDialog = FALSE;
+
+ if ( nResult == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ const SfxPoolItem* pItem=NULL;
+ if(pOutSet->GetItemState(SID_ATTR_NUMBERFORMAT_INFO,TRUE,&pItem)==SFX_ITEM_SET)
+ {
+
+ UpdateNumberFormatter( pDoc,(const SvxNumberInfoItem&)*pItem);
+ }
+
+ ApplyAttributes( pOutSet, pOldSet );
+
+ rReq.Done( *pOutSet );
+ }
+ delete pOldSet;
+ delete pNumberInfoItem;
+ delete pDlg;
+}
+
+//------------------------------------------------------------------
+
+bool ScTabViewShell::IsRefInputMode() const
+{
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod )
+ {
+ if( pScMod->IsRefDialogOpen() )
+ return pScMod->IsFormulaMode();
+ if( pScMod->IsFormulaMode() )
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if ( pHdl )
+ {
+ String aString = pHdl->GetEditString();
+ if ( !pHdl->GetSelIsRef() && aString.Len() > 1 &&
+ ( aString.GetChar(0) == '+' || aString.GetChar(0) == '-' ) )
+ {
+ const ScViewData* pViewData = GetViewData();
+ if ( pViewData )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ if ( pDoc )
+ {
+ const ScAddress aPos( pViewData->GetCurPos() );
+ ScCompiler aComp( pDoc, aPos );
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.SetCloseBrackets( false );
+ ScTokenArray* pArr = aComp.CompileString( aString );
+ if ( pArr && pArr->MayReferenceFollow() )
+ {
+ return true;
+ }
+ }
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteInputDirect()
+{
+ if ( !IsRefInputMode() )
+ {
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod )
+ {
+ pScMod->InputEnterHandler();
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::UpdateInputHandler( BOOL bForce /* = FALSE */, BOOL bStopEditing /* = TRUE */ )
+{
+ ScInputHandler* pHdl = pInputHandler ? pInputHandler : SC_MOD()->GetInputHdl();
+
+ if ( pHdl )
+ {
+ String aString;
+ const EditTextObject* pObject = NULL;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ CellType eType;
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCTAB nStartTab = 0;
+ SCTAB nEndTab = 0;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+
+ pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+
+ BOOL bHideFormula = FALSE;
+ BOOL bHideAll = FALSE;
+
+ if (pDoc->IsTabProtected(nTab))
+ {
+ const ScProtectionAttr* pProt = (const ScProtectionAttr*)
+ pDoc->GetAttr( nPosX,nPosY,nTab,
+ ATTR_PROTECTION);
+ bHideFormula = pProt->GetHideFormula();
+ bHideAll = pProt->GetHideCell();
+ }
+
+ if (!bHideAll)
+ {
+ pDoc->GetCellType( nPosX, nPosY, nTab, eType );
+ if (eType == CELLTYPE_FORMULA)
+ {
+ if (!bHideFormula)
+ pDoc->GetFormula( nPosX, nPosY, nTab, aString );
+ }
+ else if (eType == CELLTYPE_EDIT)
+ {
+ ScBaseCell* pCell;
+ pDoc->GetCell( nPosX, nPosY, nTab, pCell );
+ ((ScEditCell*)pCell)->GetData( pObject );
+ }
+ else
+ {
+ pDoc->GetInputString( nPosX, nPosY, nTab, aString );
+ if (eType == CELLTYPE_STRING)
+ {
+ // Bei Bedarf ein ' vorneweg, damit der String nicht ungewollt
+ // als Zahl interpretiert wird, und um dem Benutzer zu zeigen,
+ // dass es ein String ist (#35060#).
+ //! Auch bei Zahlformat "Text"? -> dann beim Editieren wegnehmen
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_uInt32 nNumFmt;
+ pDoc->GetNumberFormat( nPosX, nPosY, nTab, nNumFmt );
+ double fDummy;
+ if ( pFormatter->IsNumberFormat(aString, nNumFmt, fDummy) )
+ aString.Insert('\'',0);
+ }
+ }
+ }
+
+ ScInputHdlState aState( ScAddress( nPosX, nPosY, nTab ),
+ ScAddress( nStartCol, nStartRow, nTab ),
+ ScAddress( nEndCol, nEndRow, nTab ),
+ aString,
+ pObject );
+
+ // if using the view's local input handler, this view can always be set
+ // as current view inside NotifyChange.
+ ScTabViewShell* pSourceSh = pInputHandler ? this : NULL;
+
+ pHdl->NotifyChange( &aState, bForce, pSourceSh, bStopEditing );
+ }
+
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+ rBindings.Invalidate( SID_STATUS_SUM ); // immer zusammen mit Eingabezeile
+ rBindings.Invalidate( SID_ATTR_SIZE );
+ rBindings.Invalidate( SID_TABLE_CELL );
+}
+
+void ScTabViewShell::UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust )
+{
+ if( ScInputHandler* pHdl = pInputHandler ? pInputHandler : SC_MOD()->GetInputHdl() )
+ pHdl->UpdateCellAdjust( eJust );
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::ExecuteSave( SfxRequest& rReq )
+{
+ // nur SID_SAVEDOC / SID_SAVEASDOC
+
+ // Eingabe auf jeden Fall abschliessen, auch wenn eine Formel bearbeitet wird
+ SC_MOD()->InputEnterHandler();
+
+ if ( GetViewData()->GetDocShell()->IsDocShared() )
+ {
+ GetViewData()->GetDocShell()->SetDocumentModified();
+ }
+
+ // ansonsten normal weiter
+ GetViewData()->GetDocShell()->ExecuteSlot( rReq );
+}
+
+void __EXPORT ScTabViewShell::GetSaveState( SfxItemSet& rSet )
+{
+ SfxShell* pDocSh = GetViewData()->GetDocShell();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ if ( nWhich != SID_SAVEDOC || !GetViewData()->GetDocShell()->IsDocShared() )
+ {
+ // get state from DocShell
+ pDocSh->GetSlotState( nWhich, NULL, &rSet );
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteUndo(SfxRequest& rReq)
+{
+ SfxShell* pSh = GetViewData()->GetDispatcher().GetShell(0);
+ SfxUndoManager* pUndoManager = pSh->GetUndoManager();
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_UNDO:
+ case SID_REDO:
+ if ( pUndoManager )
+ {
+ BOOL bIsUndo = ( nSlot == SID_UNDO );
+
+ USHORT nCount = 1;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ nCount = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ // lock paint for more than one cell undo action (not for editing within a cell)
+ BOOL bLockPaint = ( nCount > 1 && pUndoManager == GetUndoManager() );
+ if ( bLockPaint )
+ pDocSh->LockPaint();
+
+ for (USHORT i=0; i<nCount; i++)
+ {
+ if ( bIsUndo )
+ pUndoManager->Undo(0);
+ else
+ pUndoManager->Redo(0);
+ }
+
+ if ( bLockPaint )
+ pDocSh->UnlockPaint();
+
+ GetViewFrame()->GetBindings().InvalidateAll(sal_False);
+ }
+ break;
+// default:
+// GetViewFrame()->ExecuteSlot( rReq );
+ }
+}
+
+void ScTabViewShell::GetUndoState(SfxItemSet &rSet)
+{
+ SfxShell* pSh = GetViewData()->GetDispatcher().GetShell(0);
+ SfxUndoManager* pUndoManager = pSh->GetUndoManager();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_GETUNDOSTRINGS:
+ case SID_GETREDOSTRINGS:
+ {
+ SfxStringListItem aStrLst( nWhich );
+ if ( pUndoManager )
+ {
+ List* pList = aStrLst.GetList();
+ BOOL bIsUndo = ( nWhich == SID_GETUNDOSTRINGS );
+ USHORT nCount = bIsUndo ? pUndoManager->GetUndoActionCount() : pUndoManager->GetRedoActionCount();
+ for (USHORT i=0; i<nCount; i++)
+ pList->Insert( new String( bIsUndo ? pUndoManager->GetUndoActionComment(i) :
+ pUndoManager->GetRedoActionComment(i) ),
+ LIST_APPEND );
+ }
+ rSet.Put( aStrLst );
+ }
+ break;
+ default:
+ // get state from sfx view frame
+ GetViewFrame()->GetSlotState( nWhich, NULL, &rSet );
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecDrawOpt( SfxRequest& rReq )
+{
+ ScViewOptions aViewOptions = GetViewData()->GetOptions();
+ ScGridOptions aGridOptions = aViewOptions.GetGridOptions();
+
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ USHORT nSlotId = rReq.GetSlot();
+ switch (nSlotId)
+ {
+ case SID_GRID_VISIBLE:
+ if ( pArgs && pArgs->GetItemState(nSlotId,TRUE,&pItem) == SFX_ITEM_SET )
+ {
+ aGridOptions.SetGridVisible( ((const SfxBoolItem*)pItem)->GetValue() );
+ aViewOptions.SetGridOptions(aGridOptions);
+ rBindings.Invalidate(SID_GRID_VISIBLE);
+ }
+ break;
+
+ case SID_GRID_USE:
+ if ( pArgs && pArgs->GetItemState(nSlotId,TRUE,&pItem) == SFX_ITEM_SET )
+ {
+ aGridOptions.SetUseGridSnap( ((const SfxBoolItem*)pItem)->GetValue() );
+ aViewOptions.SetGridOptions(aGridOptions);
+ rBindings.Invalidate(SID_GRID_USE);
+ }
+ break;
+
+ case SID_HELPLINES_MOVE:
+ if ( pArgs && pArgs->GetItemState(nSlotId,TRUE,&pItem) == SFX_ITEM_SET )
+ {
+ aViewOptions.SetOption( VOPT_HELPLINES, ((const SfxBoolItem*)pItem)->GetValue() );
+ rBindings.Invalidate(SID_HELPLINES_MOVE);
+ }
+ break;
+ }
+
+ GetViewData()->SetOptions(aViewOptions);
+}
+
+void ScTabViewShell::GetDrawOptState( SfxItemSet& rSet )
+{
+ SfxBoolItem aBool;
+
+ const ScViewOptions& rViewOptions = GetViewData()->GetOptions();
+ const ScGridOptions& rGridOptions = rViewOptions.GetGridOptions();
+
+ aBool.SetValue(rGridOptions.GetGridVisible());
+ aBool.SetWhich( SID_GRID_VISIBLE );
+ rSet.Put( aBool );
+
+ aBool.SetValue(rGridOptions.GetUseGridSnap());
+ aBool.SetWhich( SID_GRID_USE );
+ rSet.Put( aBool );
+
+ aBool.SetValue(rViewOptions.GetOption( VOPT_HELPLINES ));
+ aBool.SetWhich( SID_HELPLINES_MOVE );
+ rSet.Put( aBool );
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx
new file mode 100644
index 000000000000..8f4a203ea14d
--- /dev/null
+++ b/sc/source/ui/view/tabvwshb.cxx
@@ -0,0 +1,500 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+
+
+
+//------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <sfx2/app.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <svx/pfiledlg.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdview.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svx/fontworkbar.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svtools/soerr.hxx>
+#include <svl/rectitem.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sot/exchange.hxx>
+
+#include "tabvwsh.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "client.hxx"
+#include "fuinsert.hxx"
+#include "docsh.hxx"
+#include "chartarr.hxx"
+#include "drawview.hxx"
+#include "ChartRangeSelectionListener.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+void ScTabViewShell::ConnectObject( SdrOle2Obj* pObj )
+{
+ // wird aus dem Paint gerufen
+
+ uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
+ Window* pWin = GetActiveWin();
+
+ // #41412# wenn schon connected ist, nicht nochmal SetObjArea/SetSizeScale
+
+ SfxInPlaceClient* pClient = FindIPClient( xObj, pWin );
+ if ( !pClient )
+ {
+ pClient = new ScClient( this, pWin, GetSdrView()->GetModel(), pObj );
+ Rectangle aRect = pObj->GetLogicRect();
+ Size aDrawSize = aRect.GetSize();
+
+ Size aOleSize = pObj->GetOrigObjSize();
+
+ Fraction aScaleWidth (aDrawSize.Width(), aOleSize.Width() );
+ Fraction aScaleHeight(aDrawSize.Height(), aOleSize.Height() );
+ aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj
+ aScaleHeight.ReduceInaccurate(10);
+ pClient->SetSizeScale(aScaleWidth,aScaleHeight);
+
+ // sichtbarer Ausschnitt wird nur inplace veraendert!
+ // the object area must be set after the scaling since it triggers the resizing
+ aRect.SetSize( aOleSize );
+ pClient->SetObjArea( aRect );
+
+ ((ScClient*)pClient)->SetGrafEdit( NULL );
+ }
+}
+
+BOOL ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb )
+{
+ // #41081# Gueltigkeits-Hinweisfenster nicht ueber dem Objekt stehenlassen
+ RemoveHintWindow();
+
+ uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
+ Window* pWin = GetActiveWin();
+ ErrCode nErr = ERRCODE_NONE;
+ BOOL bErrorShown = FALSE;
+
+ // linked objects aren't supported
+// if ( xIPObj->IsLink() )
+// nErr = xIPObj->DoVerb(nVerb); // gelinkt -> ohne Client etc.
+// else
+ {
+ SfxInPlaceClient* pClient = FindIPClient( xObj, pWin );
+ if ( !pClient )
+ pClient = new ScClient( this, pWin, GetSdrView()->GetModel(), pObj );
+
+ if ( !(nErr & ERRCODE_ERROR_MASK) && xObj.is() )
+ {
+ Rectangle aRect = pObj->GetLogicRect();
+ Size aDrawSize = aRect.GetSize();
+
+ MapMode aMapMode( MAP_100TH_MM );
+ Size aOleSize = pObj->GetOrigObjSize( &aMapMode );
+
+ if ( pClient->GetAspect() != embed::Aspects::MSOLE_ICON
+ && ( xObj->getStatus( pClient->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
+ {
+ // scale must always be 1 - change VisArea if different from client size
+
+ if ( aDrawSize != aOleSize )
+ {
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( pClient->GetAspect() ) );
+ aOleSize = OutputDevice::LogicToLogic( aDrawSize,
+ MAP_100TH_MM, aUnit );
+ awt::Size aSz( aOleSize.Width(), aOleSize.Height() );
+ xObj->setVisualAreaSize( pClient->GetAspect(), aSz );
+ }
+ Fraction aOne( 1, 1 );
+ pClient->SetSizeScale( aOne, aOne );
+ }
+ else
+ {
+ // calculate scale from client and VisArea size
+
+ Fraction aScaleWidth (aDrawSize.Width(), aOleSize.Width() );
+ Fraction aScaleHeight(aDrawSize.Height(), aOleSize.Height() );
+ aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj
+ aScaleHeight.ReduceInaccurate(10);
+ pClient->SetSizeScale(aScaleWidth,aScaleHeight);
+ }
+
+ // sichtbarer Ausschnitt wird nur inplace veraendert!
+ // the object area must be set after the scaling since it triggers the resizing
+ aRect.SetSize( aOleSize );
+ pClient->SetObjArea( aRect );
+
+ ((ScClient*)pClient)->SetGrafEdit( NULL );
+
+ nErr = pClient->DoVerb( nVerb );
+ bErrorShown = TRUE;
+ // SfxViewShell::DoVerb zeigt seine Fehlermeldungen selber an
+
+ // attach listener to selection changes in chart that affect cell
+ // ranges, so those can be highlighted
+ // note: do that after DoVerb, so that the chart controller exists
+ if ( SvtModuleOptions().IsChart() )
+ {
+ SvGlobalName aObjClsId ( xObj->getClassID() );
+ if (SotExchange::IsChart( aObjClsId ))
+ {
+ try
+ {
+ uno::Reference < embed::XComponentSupplier > xSup( xObj, uno::UNO_QUERY_THROW );
+ uno::Reference< chart2::data::XDataReceiver > xDataReceiver(
+ xSup->getComponent(), uno::UNO_QUERY_THROW );
+ uno::Reference< chart2::data::XRangeHighlighter > xRangeHightlighter(
+ xDataReceiver->getRangeHighlighter());
+ if( xRangeHightlighter.is())
+ {
+ uno::Reference< view::XSelectionChangeListener > xListener(
+ new ScChartRangeSelectionListener( this ));
+ xRangeHightlighter->addSelectionChangeListener( xListener );
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_ERROR( "Exception caught while querying chart" );
+ }
+ }
+ }
+ }
+ }
+ if (nErr != ERRCODE_NONE && !bErrorShown)
+ ErrorHandler::HandleError(nErr);
+
+ //! SetDocumentName sollte schon im Sfx passieren ???
+ //TODO/LATER: how "SetDocumentName"?
+ //xIPObj->SetDocumentName( GetViewData()->GetDocShell()->GetTitle() );
+
+ return ( !(nErr & ERRCODE_ERROR_MASK) );
+}
+
+ErrCode __EXPORT ScTabViewShell::DoVerb(long nVerb)
+{
+ SdrView* pView = GetSdrView();
+ if (!pView)
+ return ERRCODE_SO_NOTIMPL; // soll nicht sein
+
+ SdrOle2Obj* pOle2Obj = NULL;
+ SdrGrafObj* pGrafObj = NULL;
+ SdrObject* pObj = NULL;
+ ErrCode nErr = ERRCODE_NONE;
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() == OBJ_OLE2)
+ pOle2Obj = (SdrOle2Obj*) pObj;
+ else if (pObj->GetObjIdentifier() == OBJ_GRAF)
+ {
+ pGrafObj = (SdrGrafObj*) pObj;
+ }
+ }
+
+ if (pOle2Obj)
+ {
+ ActivateObject( pOle2Obj, nVerb );
+ }
+ else
+ {
+ DBG_ERROR("kein Objekt fuer Verb gefunden");
+ }
+
+ return nErr;
+}
+
+void ScTabViewShell::DeactivateOle()
+{
+ // deactivate inplace editing if currently active
+
+ ScModule* pScMod = SC_MOD();
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ ScClient* pClient = (ScClient*) GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
+ pClient->DeactivateObject();
+}
+
+void ScTabViewShell::ExecDrawIns(SfxRequest& rReq)
+{
+ USHORT nSlot = rReq.GetSlot();
+ if (nSlot != SID_OBJECTRESIZE )
+ {
+ SC_MOD()->InputEnterHandler();
+ UpdateInputHandler();
+ }
+
+ // Rahmen fuer Chart einfuegen wird abgebrochen:
+ FuPoor* pPoor = GetDrawFuncPtr();
+ if ( pPoor && pPoor->GetSlotID() == SID_DRAW_CHART )
+ GetViewData()->GetDispatcher().Execute(SID_DRAW_CHART, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+
+ MakeDrawLayer();
+
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+ ScTabView* pTabView = GetViewData()->GetView();
+ Window* pWin = pTabView->GetActiveWin();
+ ScDrawView* pView = pTabView->GetScDrawView();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+// SdrModel* pDrModel = pDocSh->MakeDrawLayer();
+ SdrModel* pDrModel = pView->GetModel();
+
+ switch ( nSlot )
+ {
+ case SID_INSERT_GRAPHIC:
+ FuInsertGraphic(this, pWin, pView, pDrModel, rReq);
+ // shell is set in MarkListHasChanged
+ break;
+
+ case SID_INSERT_AVMEDIA:
+ FuInsertMedia(this, pWin, pView, pDrModel, rReq);
+ // shell is set in MarkListHasChanged
+ break;
+
+ case SID_INSERT_DIAGRAM:
+ FuInsertChart(this, pWin, pView, pDrModel, rReq);
+//? SC_MOD()->SetFunctionDlg( NULL );//XXX
+ break;
+
+ case SID_INSERT_OBJECT:
+ case SID_INSERT_PLUGIN:
+ case SID_INSERT_SOUND:
+ case SID_INSERT_VIDEO:
+ case SID_INSERT_APPLET:
+ case SID_INSERT_SMATH:
+ case SID_INSERT_FLOATINGFRAME:
+ FuInsertOLE(this, pWin, pView, pDrModel, rReq);
+ break;
+
+ case SID_OBJECTRESIZE:
+ {
+ // Der Server moechte die Clientgrosse verandern
+
+ SfxInPlaceClient* pClient = GetIPClient();
+
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ {
+ const SfxRectangleItem& rRect =
+ (SfxRectangleItem&)rReq.GetArgs()->Get(SID_OBJECTRESIZE);
+ Rectangle aRect( pWin->PixelToLogic( rRect.GetValue() ) );
+
+ if ( pView->AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ UINT16 nSdrObjKind = pObj->GetObjIdentifier();
+
+ if (nSdrObjKind == OBJ_OLE2)
+ {
+ if ( ( (SdrOle2Obj*) pObj)->GetObjRef().is() )
+ {
+ pObj->SetLogicRect(aRect);
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_LINKS:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractLinksDialog* pDlg = pFact->CreateLinksDialog( pWin, pDoc->GetLinkManager() );
+ if ( pDlg )
+ {
+ pDlg->Execute();
+ rBindings.Invalidate( nSlot );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+ rReq.Done();
+ }
+ }
+ break;
+
+ // #98721#
+ case SID_FM_CREATE_FIELDCONTROL:
+ {
+ SFX_REQUEST_ARG( rReq, pDescriptorItem, SfxUnoAnyItem, SID_FM_DATACCESS_DESCRIPTOR, sal_False );
+ DBG_ASSERT( pDescriptorItem, "SID_FM_CREATE_FIELDCONTROL: invalid request args!" );
+
+ if(pDescriptorItem)
+ {
+ //! merge with ScViewFunc::PasteDataFormat (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)?
+
+ ScDrawView* pDrView = GetScDrawView();
+ SdrPageView* pPageView = pDrView ? pDrView->GetSdrPageView() : NULL;
+ if(pPageView)
+ {
+ ::svx::ODataAccessDescriptor aDescriptor(pDescriptorItem->GetValue());
+ SdrObject* pNewDBField = pDrView->CreateFieldControl(aDescriptor);
+
+ if(pNewDBField)
+ {
+ Rectangle aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
+ Point aObjPos(aVisArea.Center());
+ Size aObjSize(pNewDBField->GetLogicRect().GetSize());
+ aObjPos.X() -= aObjSize.Width() / 2;
+ aObjPos.Y() -= aObjSize.Height() / 2;
+ Rectangle aNewObjectRectangle(aObjPos, aObjSize);
+
+ pNewDBField->SetLogicRect(aNewObjectRectangle);
+
+ // controls must be on control layer, groups on front layer
+ if ( pNewDBField->ISA(SdrUnoObj) )
+ pNewDBField->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pNewDBField->NbcSetLayer(SC_LAYER_FRONT);
+ if (pNewDBField->ISA(SdrObjGroup))
+ {
+ SdrObjListIter aIter( *pNewDBField, IM_DEEPWITHGROUPS );
+ SdrObject* pSubObj = aIter.Next();
+ while (pSubObj)
+ {
+ if ( pSubObj->ISA(SdrUnoObj) )
+ pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pSubObj->NbcSetLayer(SC_LAYER_FRONT);
+ pSubObj = aIter.Next();
+ }
+ }
+
+ pView->InsertObjectAtView(pNewDBField, *pPageView);
+ }
+ }
+ }
+ rReq.Done();
+ }
+ break;
+
+ case SID_FONTWORK_GALLERY_FLOATER:
+ svx::FontworkBar::execute( pView, rReq, GetViewFrame()->GetBindings() );
+ rReq.Ignore();
+ break;
+ }
+}
+
+void ScTabViewShell::GetDrawInsState(SfxItemSet &rSet)
+{
+ BOOL bOle = GetViewFrame()->GetFrame().IsInPlace();
+ BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
+ ScDocShell* pDocShell = ( GetViewData() ? GetViewData()->GetDocShell() : NULL );
+ bool bShared = ( pDocShell ? pDocShell->IsDocShared() : false );
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_INSERT_DIAGRAM:
+ if ( bOle || bTabProt || !SvtModuleOptions().IsChart() || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_SMATH:
+ if ( bOle || bTabProt || !SvtModuleOptions().IsMath() || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_OBJECT:
+ case SID_INSERT_PLUGIN:
+ case SID_INSERT_FLOATINGFRAME:
+ if ( bOle || bTabProt || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_SOUND:
+ case SID_INSERT_VIDEO:
+ /* #i102735# discussed with NN: removed for performance reasons
+ || !SvxPluginFileDlg::IsAvailable(nWhich)
+ */
+ if ( bOle || bTabProt || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_APPLET:
+ // wenn SOLAR_JAVA nicht definiert ist, immer disablen
+#ifdef SOLAR_JAVA
+ if (bOle || bTabProt)
+#endif
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_GRAPHIC:
+ case SID_INSERT_AVMEDIA:
+ case SID_FONTWORK_GALLERY_FLOATER:
+ if ( bTabProt || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_LINKS:
+ {
+ if (GetViewData()->GetDocument()->GetLinkManager()->GetLinks().Count() == 0 )
+ rSet.DisableItem( SID_LINKS );
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
new file mode 100644
index 000000000000..7d1cbb05761b
--- /dev/null
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+#include "scitems.hxx"
+#include <vcl/msgbox.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "uiitems.hxx"
+#include "pivot.hxx"
+#include "namedlg.hxx"
+#include "solvrdlg.hxx"
+#include "optsolver.hxx"
+#include "tabopdlg.hxx"
+#include "autoform.hxx" // Core
+#include "autofmt.hxx" // Dialog
+#include "consdlg.hxx"
+//CHINA001 #include "sortdlg.hxx"
+#include "filtdlg.hxx"
+#include "dbnamdlg.hxx"
+#include "pvlaydlg.hxx"
+#include "areasdlg.hxx"
+#include "condfrmt.hxx"
+#include "rangeutl.hxx"
+#include "crnrdlg.hxx"
+#include "formula.hxx"
+#include "cell.hxx" // Input Status Edit-Zellen
+#include "acredlin.hxx"
+#include "highred.hxx"
+#include "simpref.hxx"
+#include "funcdesc.hxx"
+#include "dpobject.hxx"
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetCurRefDlgId( USHORT nNew )
+{
+ // CurRefDlgId is stored in ScModule to find if a ref dialog is open,
+ // and in the view to identify the view that has opened the dialog
+ nCurRefDlgId = nNew;
+}
+
+SfxModelessDialog* ScTabViewShell::CreateRefDialog(
+ SfxBindings* pB, SfxChildWindow* pCW, SfxChildWinInfo* pInfo,
+ Window* pParent, USHORT nSlotId )
+{
+ // Dialog nur aufmachen, wenn ueber ScModule::SetRefDialog gerufen, damit
+ // z.B. nach einem Absturz offene Ref-Dialoge nicht wiederkommen (#42341#).
+
+ if ( SC_MOD()->GetCurRefDlgId() != nSlotId )
+ return NULL;
+
+ if ( nCurRefDlgId != nSlotId )
+ {
+ // the dialog has been opened in a different view
+ // -> lock the dispatcher for this view (modal mode)
+
+ GetViewData()->GetDispatcher().Lock( TRUE ); // lock is reset when closing dialog
+ return NULL;
+ }
+
+ SfxModelessDialog* pResult = 0;
+
+ if(pCW)
+ pCW->SetHideNotDelete(TRUE);
+
+ switch( nSlotId )
+ {
+ case FID_DEFINE_NAME:
+ pResult = new ScNameDlg( pB, pCW, pParent, GetViewData(),
+ ScAddress( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() ) );
+ break;
+
+ case SID_DEFINE_COLROWNAMERANGES:
+ {
+ pResult = new ScColRowNameRangesDlg( pB, pCW, pParent, GetViewData() );
+ }
+ break;
+
+ case SID_OPENDLG_CONSOLIDATE:
+ {
+ SfxItemSet aArgSet( GetPool(),
+ SCITEM_CONSOLIDATEDATA,
+ SCITEM_CONSOLIDATEDATA );
+
+ const ScConsolidateParam* pDlgData =
+ GetViewData()->GetDocument()->GetConsolidateDlgData();
+
+ if ( !pDlgData )
+ {
+ ScConsolidateParam aConsParam;
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nStartTab, nEndTab;
+
+ GetViewData()->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+
+ aConsParam.nCol = nStartCol;
+ aConsParam.nRow = nStartRow;
+ aConsParam.nTab = nStartTab;
+
+ aArgSet.Put( ScConsolidateItem( SCITEM_CONSOLIDATEDATA,
+ &aConsParam ) );
+ }
+ else
+ {
+ aArgSet.Put( ScConsolidateItem( SCITEM_CONSOLIDATEDATA, pDlgData ) );
+ }
+ pResult = new ScConsolidateDlg( pB, pCW, pParent, aArgSet );
+ }
+ break;
+
+ case SID_DEFINE_DBNAME:
+ {
+ // wenn auf einem bestehenden Bereich aufgerufen, den markieren
+ GetDBData( TRUE, SC_DB_OLD );
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ MarkDataArea( FALSE );
+
+ pResult = new ScDbNameDlg( pB, pCW, pParent, GetViewData() );
+ }
+ break;
+
+ case SID_SPECIAL_FILTER:
+ {
+ ScQueryParam aQueryParam;
+ SfxItemSet aArgSet( GetPool(),
+ SCITEM_QUERYDATA,
+ SCITEM_QUERYDATA );
+
+ ScDBData* pDBData = GetDBData( TRUE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN);
+ pDBData->GetQueryParam( aQueryParam );
+
+ ScQueryItem aItem( SCITEM_QUERYDATA, GetViewData(), &aQueryParam );
+ ScRange aAdvSource;
+ if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ aItem.SetAdvancedQuerySource( &aAdvSource );
+
+ aArgSet.Put( aItem );
+
+ // aktuelle Tabelle merken (wg. RefInput im Dialog)
+ GetViewData()->SetRefTabNo( GetViewData()->GetTabNo() );
+
+ pResult = new ScSpecialFilterDlg( pB, pCW, pParent, aArgSet );
+ }
+ break;
+
+ case SID_FILTER:
+ {
+
+ ScQueryParam aQueryParam;
+ SfxItemSet aArgSet( GetPool(),
+ SCITEM_QUERYDATA,
+ SCITEM_QUERYDATA );
+
+ ScDBData* pDBData = GetDBData( TRUE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN);
+ pDBData->GetQueryParam( aQueryParam );
+
+ aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA,
+ GetViewData(),
+ &aQueryParam ) );
+
+ // aktuelle Tabelle merken (wg. RefInput im Dialog)
+ GetViewData()->SetRefTabNo( GetViewData()->GetTabNo() );
+
+ pResult = new ScFilterDlg( pB, pCW, pParent, aArgSet );
+ }
+ break;
+
+ case SID_OPENDLG_TABOP:
+ {
+ ScViewData* pViewData = GetViewData();
+ ScRefAddress aCurPos ( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo(),
+ FALSE, FALSE, FALSE );
+
+ pResult = new ScTabOpDlg( pB, pCW, pParent, pViewData->GetDocument(), aCurPos );
+ }
+ break;
+
+ case SID_OPENDLG_SOLVE:
+ {
+ ScViewData* pViewData = GetViewData();
+ ScAddress aCurPos( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo());
+ pResult = new ScSolverDlg( pB, pCW, pParent, pViewData->GetDocument(), aCurPos );
+ }
+ break;
+
+ case SID_OPENDLG_OPTSOLVER:
+ {
+ ScViewData* pViewData = GetViewData();
+ ScAddress aCurPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo());
+ pResult = new ScOptSolverDlg( pB, pCW, pParent, pViewData->GetDocShell(), aCurPos );
+ }
+ break;
+
+ case SID_OPENDLG_PIVOTTABLE:
+ {
+ // all settings must be in pDialogDPObject
+
+ if( pDialogDPObject )
+ {
+ GetViewData()->SetRefTabNo( GetViewData()->GetTabNo() );
+ pResult = new ScDPLayoutDlg( pB, pCW, pParent, *pDialogDPObject );
+ }
+ }
+ break;
+
+ case SID_OPENDLG_EDIT_PRINTAREA:
+ {
+ pResult = new ScPrintAreasDlg( pB, pCW, pParent );
+ }
+ break;
+
+ case SID_OPENDLG_CONDFRMT:
+ {
+ ScViewData* pViewData = GetViewData();
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScConditionalFormat* pForm = pDoc->GetCondFormat(
+ pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
+
+ // aktuelle Tabelle merken (wg. RefInput im Dialog)
+ pViewData->SetRefTabNo( pViewData->GetTabNo() );
+
+ pResult = new ScConditionalFormatDlg( pB, pCW, pParent, pDoc, pForm );
+ }
+ break;
+
+ case SID_OPENDLG_FUNCTION:
+ {
+ // Dialog schaut selber, was in der Zelle steht
+
+ pResult = new ScFormulaDlg( pB, pCW, pParent, GetViewData(),ScGlobal::GetStarCalcFunctionMgr() );
+ }
+ break;
+
+ case FID_CHG_SHOW:
+ {
+ // Dialog schaut selber, was in der Zelle steht
+
+ pResult = new ScHighlightChgDlg( pB, pCW, pParent, GetViewData() );
+ }
+ break;
+
+ case WID_SIMPLE_REF:
+ {
+ // Dialog schaut selber, was in der Zelle steht
+
+ ScViewData* pViewData = GetViewData();
+ pViewData->SetRefTabNo( pViewData->GetTabNo() );
+ pResult = new ScSimpleRefDlg( pB, pCW, pParent, pViewData );
+ }
+ break;
+
+
+ default:
+ DBG_ERROR( "ScTabViewShell::CreateRefDialog: unbekannte ID" );
+ break;
+ }
+
+ if (pResult)
+ {
+ // Die Dialoge gehen immer mit eingeklapptem Zusaetze-Button auf,
+ // darum muss die Groesse ueber das Initialize gerettet werden
+ // (oder den Zusaetze-Status mit speichern !!!)
+
+ Size aSize = pResult->GetSizePixel();
+ pResult->Initialize( pInfo );
+ pResult->SetSizePixel(aSize);
+ }
+
+ return pResult;
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwshd.cxx b/sc/source/ui/view/tabvwshd.cxx
new file mode 100644
index 000000000000..4ef5186a25a0
--- /dev/null
+++ b/sc/source/ui/view/tabvwshd.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/childwin.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include "tabvwsh.hxx"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "sc.hrc"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+//------------------------------------------------------------------
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+//! Parent-Window fuer Dialoge
+//! Problem: OLE Server!
+
+Window* ScTabViewShell::GetDialogParent()
+{
+ // #95513# if a ref-input dialog is open, use it as parent
+ // (necessary when a slot is executed from the dialog's OK handler)
+ if ( nCurRefDlgId && nCurRefDlgId == SC_MOD()->GetCurRefDlgId() )
+ {
+ SfxViewFrame* pViewFrm = GetViewFrame();
+ if ( pViewFrm->HasChildWindow(nCurRefDlgId) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(nCurRefDlgId);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pDocSh->IsOle() )
+ {
+ //TODO/LATER: how to GetEditWindow in embedded document?!
+ //It should be OK to return the VieShell Window!
+ return GetWindow();
+ //SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv();
+ //if (pEnv)
+ // return pEnv->GetEditWin();
+ }
+
+ return GetActiveWin(); // for normal views, too
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshe.cxx b/sc/source/ui/view/tabvwshe.cxx
new file mode 100644
index 000000000000..6034ac81ecba
--- /dev/null
+++ b/sc/source/ui/view/tabvwshe.cxx
@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <editeng/eeitem.hxx>
+
+#include "scitems.hxx"
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objface.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/sound.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "impex.hxx"
+#include "editsh.hxx"
+#include "dociter.hxx"
+#include "inputhdl.hxx"
+#include "document.hxx"
+
+//==================================================================
+
+String __EXPORT ScTabViewShell::GetSelectionText( BOOL bWholeWord )
+{
+ String aStrSelection;
+
+ if ( pEditShell && pEditShell == GetMySubShell() )
+ {
+ aStrSelection = pEditShell->GetSelectionText( bWholeWord );
+ }
+ else
+ {
+ ScRange aRange;
+
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( bInFormatDialog && aRange.aStart.Row() != aRange.aEnd.Row() )
+ {
+ // Range auf eine Datenzeile begrenzen
+ // (#48613# nur wenn der Aufruf aus einem Format-Dialog kommt)
+ ScHorizontalCellIterator aIter( pDoc, aRange.aStart.Tab(),
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() );
+ SCCOL nCol;
+ SCROW nRow;
+ if ( aIter.GetNext( nCol, nRow ) )
+ {
+ aRange.aStart.SetCol( nCol );
+ aRange.aStart.SetRow( nRow );
+ aRange.aEnd.SetRow( nRow );
+ }
+ else
+ aRange.aEnd = aRange.aStart;
+ }
+ else
+ {
+ // #i111531# with 1M rows it was necessary to limit the range
+ // to the actually used data area.
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ SCTAB nTab1, nTab2;
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ bool bShrunk;
+ pDoc->ShrinkToUsedDataArea( bShrunk, nTab1, nCol1, nRow1, nCol2, nRow2, false);
+ if (bShrunk)
+ {
+ aRange.aStart.SetCol( nCol1 );
+ aRange.aStart.SetRow( nRow1 );
+ aRange.aEnd.SetCol( nCol2 );
+ aRange.aEnd.SetRow( nRow2 );
+ }
+ }
+
+ ScImportExport aObj( pDoc, aRange );
+ aObj.SetFormulas( GetViewData()->GetOptions().GetOption( VOPT_FORMULAS ) );
+ rtl::OUString aExportOUString;
+ aObj.ExportString( aExportOUString );
+ aStrSelection = aExportOUString;
+
+ aStrSelection.ConvertLineEnd( LINEEND_CR );
+
+ // Tab/CR durch Space ersetzen, wenn fuer Dialog oder per Basic/SelectionTextExt,
+ // oder wenn es eine einzelne Zeile ist.
+ // Sonst mehrzeilig mit Tabs beibehalten (z.B. Mail oder Basic/SelectionText).
+ // Fuer Mail werden die Tabs dann spaeter in (mehrere) Spaces gewandelt.
+
+ if ( bInFormatDialog || bWholeWord || aRange.aEnd.Row() == aRange.aStart.Row() )
+ {
+ xub_StrLen nAt;
+ while ( (nAt = aStrSelection.Search( CHAR_CR )) != STRING_NOTFOUND )
+ aStrSelection.SetChar( nAt, ' ' );
+ while ( (nAt = aStrSelection.Search( '\t' )) != STRING_NOTFOUND )
+ aStrSelection.SetChar( nAt, ' ' );
+
+ aStrSelection.EraseTrailingChars( ' ' );
+ }
+ }
+ }
+
+ return aStrSelection;
+}
+
+//------------------------------------------------------------------------
+
+void ScTabViewShell::InsertURL( const String& rName, const String& rURL, const String& rTarget,
+ USHORT nMode )
+{
+ SvxLinkInsertMode eMode = (SvxLinkInsertMode) nMode;
+ BOOL bAsText = ( eMode != HLINK_BUTTON ); // Default ist jetzt Text
+
+ if ( bAsText )
+ {
+ if ( GetViewData()->IsActive() )
+ {
+ // if the view is active, always use InsertURLField, which starts EditMode
+ // and selects the URL, so it can be changed from the URL bar / dialog
+
+ InsertURLField( rName, rURL, rTarget );
+ }
+ else
+ {
+ // #91216# if the view is not active, InsertURLField doesn't work
+ // -> use InsertBookmark to directly manipulate cell content
+ // bTryReplace=TRUE -> if cell contains only one URL, replace it
+
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ InsertBookmark( rName, rURL, nPosX, nPosY, &rTarget, TRUE );
+ }
+ }
+ else
+ {
+ SC_MOD()->InputEnterHandler();
+ InsertURLButton( rName, rURL, rTarget );
+ }
+}
+
+//------------------------------------------------------------------------
+
+// wenn CLOOKs: -> mit <editview.hxx> <flditem.hxx>in neue tabvwsh
+
+void lcl_SelectFieldAfterInsert( EditView& rView )
+{
+ ESelection aSel = rView.GetSelection();
+ if ( aSel.nStartPos == aSel.nEndPos && aSel.nStartPos > 0 )
+ {
+ // Cursor is behind the inserted field -> extend selection to the left
+
+ --aSel.nStartPos;
+ rView.SetSelection( aSel );
+ }
+}
+
+void ScTabViewShell::InsertURLField( const String& rName, const String& rURL, const String& rTarget )
+{
+ SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR );
+ aURLField.SetTargetFrame( rTarget );
+ SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
+
+ ScViewData* pViewData = GetViewData();
+ ScModule* pScMod = SC_MOD();
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+
+ BOOL bSelectFirst = FALSE;
+ if ( !pScMod->IsEditMode() )
+ {
+ if ( !SelectionEditable() )
+ {
+ // no error message (may be called from drag&drop)
+ Sound::Beep();
+ return;
+ }
+
+ // single url in cell is shown in the dialog and replaced
+ bSelectFirst = HasBookmarkAtCursor( NULL );
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ }
+
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ DBG_ASSERT( pTopView || pTableView, "No EditView" );
+
+ if ( bSelectFirst )
+ {
+ if ( pTopView )
+ pTopView->SetSelection( ESelection(0,0,0,1) );
+ if ( pTableView )
+ pTableView->SetSelection( ESelection(0,0,0,1) );
+ }
+
+ pHdl->DataChanging();
+
+ if ( pTopView )
+ {
+ pTopView->InsertField( aURLItem );
+ lcl_SelectFieldAfterInsert( *pTopView );
+ }
+ if ( pTableView )
+ {
+ pTableView->InsertField( aURLItem );
+ lcl_SelectFieldAfterInsert( *pTableView );
+ }
+
+ pHdl->DataChanged();
+}
+
+void ScTabViewShell::ExecSearch( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ USHORT nSlot = rReq.GetSlot();
+ const SfxPoolItem* pItem;
+
+ switch ( nSlot )
+ {
+ case FID_SEARCH_NOW:
+ {
+ if ( pReqArgs &&
+ SFX_ITEM_SET == pReqArgs->GetItemState(SID_SEARCH_ITEM, FALSE, &pItem) )
+ {
+ DBG_ASSERT( pItem->ISA(SvxSearchItem), "falsches Item" );
+ const SvxSearchItem* pSearchItem = (const SvxSearchItem*) pItem;
+
+ ScGlobal::SetSearchItem( *pSearchItem );
+ SearchAndReplace( pSearchItem, TRUE, rReq.IsAPI() );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_SEARCH_ITEM:
+ if (pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState(SID_SEARCH_ITEM, FALSE, &pItem))
+ {
+ // Search-Item merken
+ DBG_ASSERT( pItem->ISA(SvxSearchItem), "falsches Item" );
+ ScGlobal::SetSearchItem( *(const SvxSearchItem*) pItem );
+ }
+ else
+ {
+ DBG_ERROR("SID_SEARCH_ITEM ohne Parameter");
+ }
+ break;
+ case FID_SEARCH:
+ case FID_REPLACE:
+ case FID_REPLACE_ALL:
+ case FID_SEARCH_ALL:
+ {
+ if (pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState(nSlot, FALSE, &pItem))
+ {
+ // SearchItem holen
+
+ SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
+
+ // SearchItem fuellen
+
+ aSearchItem.SetSearchString(((SfxStringItem*)pItem)->GetValue());
+ if(SFX_ITEM_SET == pReqArgs->GetItemState(FN_PARAM_1, FALSE, &pItem))
+ aSearchItem.SetReplaceString(((SfxStringItem*)pItem)->GetValue());
+
+ if (nSlot == FID_SEARCH)
+ aSearchItem.SetCommand(SVX_SEARCHCMD_FIND);
+ else if(nSlot == FID_REPLACE)
+ aSearchItem.SetCommand(SVX_SEARCHCMD_REPLACE);
+ else if(nSlot == FID_REPLACE_ALL)
+ aSearchItem.SetCommand(SVX_SEARCHCMD_REPLACE_ALL);
+ else
+ aSearchItem.SetCommand(SVX_SEARCHCMD_FIND_ALL);
+
+ // Request ausfuehren (dabei wird das SearchItem gespeichert)
+
+ aSearchItem.SetWhich(SID_SEARCH_ITEM);
+ GetViewData()->GetDispatcher().Execute( FID_SEARCH_NOW,
+ rReq.IsAPI() ? SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON :
+ SFX_CALLMODE_STANDARD,
+ &aSearchItem, 0L );
+ }
+ else
+ {
+ GetViewData()->GetDispatcher().Execute(
+ SID_SEARCH_DLG, SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
+ }
+ }
+ break;
+ case FID_REPEAT_SEARCH:
+ {
+ // nochmal mit ScGlobal::GetSearchItem()
+
+ SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
+ aSearchItem.SetWhich(SID_SEARCH_ITEM);
+ GetViewData()->GetDispatcher().Execute( FID_SEARCH_NOW,
+ rReq.IsAPI() ? SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON :
+ SFX_CALLMODE_STANDARD,
+ &aSearchItem, 0L );
+ }
+ break;
+// case FID_SEARCH_COUNT:
+ }
+}
+
+//--------------------------------------------------------------------
+
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshf.cxx b/sc/source/ui/view/tabvwshf.cxx
new file mode 100644
index 000000000000..20a10f149a3a
--- /dev/null
+++ b/sc/source/ui/view/tabvwshf.cxx
@@ -0,0 +1,964 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <boost/scoped_ptr.hpp>
+
+#include "scitems.hxx"
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <basic/sbstar.hxx>
+#include <layout/layout.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/svxdlg.hxx>
+#include <editeng/colritem.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "shtabdlg.hxx"
+#include "scresid.hxx"
+//CHINA001 #include "instbdlg.hxx"
+#include "globstr.hrc"
+//CHINA001 #include "strindlg.hxx"
+//CHINA001 #include "mvtabdlg.hxx"
+#include "docfunc.hxx"
+#include "eventuno.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+#include "tabbgcolor.hxx"
+#include "tabbgcolordlg.hxx"
+
+using ::boost::scoped_ptr;
+using namespace com::sun::star;
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteTable( SfxRequest& rReq )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ SCTAB nCurrentTab = pViewData->GetTabNo();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ USHORT nSlot = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ HideListBox(); // Autofilter-DropDown-Listbox
+
+ switch ( nSlot )
+ {
+ case FID_TABLE_VISIBLE:
+ {
+ String aName;
+ pDoc->GetName( nCurrentTab, aName );
+
+ BOOL bVisible=TRUE;
+ if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_TABLE_VISIBLE, &pItem ) )
+ bVisible = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+
+ if( ! bVisible ) // ausblenden
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ USHORT nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+ if ( nVis<2 || !pDoc->IsDocEditable() || nTabSelCount > 1 )
+ break;
+
+ SCTAB nHideTab;
+ if (pDoc->GetTable( aName, nHideTab ))
+ HideTable( nHideTab );
+ }
+ else // einblenden
+ {
+ ShowTable( aName );
+ }
+ }
+ break;
+
+ case FID_TABLE_HIDE:
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ USHORT nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+ if ( nVis<2 || !pDoc->IsDocEditable() || nTabSelCount > 1 )
+ break;
+
+
+ String aName;
+ if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_TABLE_HIDE, &pItem ) )
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (!aName.Len())
+ {
+ pDoc->GetName( nCurrentTab, aName ); // aktuelle Tabelle
+ rReq.AppendItem( SfxStringItem( FID_TABLE_HIDE, aName ) );
+ }
+
+ SCTAB nHideTab;
+ if (pDoc->GetTable( aName, nHideTab ))
+ HideTable( nHideTab );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ break;
+
+ case FID_TABLE_SHOW:
+ {
+ String aName;
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_TABLE_SHOW, &pItem ) )
+ {
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+
+ ShowTable( aName );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ }
+ else
+ {
+ //CHINA001 ScShowTabDlg* pDlg = new ScShowTabDlg( GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScShowTabDlg* pDlg = pFact->CreateScShowTabDlg( GetDialogParent(), RID_SCDLG_SHOW_TAB);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ String aTabName;
+ BOOL bFirst = TRUE;
+ for ( SCTAB i=0; i != nTabCount; i++ )
+ {
+ if (!pDoc->IsVisible(i))
+ {
+ pDoc->GetName( i, aTabName );
+ pDlg->Insert( aTabName, bFirst );
+ bFirst = FALSE;
+ }
+ }
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ USHORT nCount = pDlg->GetSelectEntryCount();
+ for (USHORT nPos=0; nPos<nCount; nPos++)
+ {
+ aName = pDlg->GetSelectEntry(nPos);
+ ShowTable( aName );
+ }
+ rReq.AppendItem( SfxStringItem( FID_TABLE_SHOW, aName ) );
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_INS_TABLE:
+ case FID_INS_TABLE_EXT:
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ SCTAB nTabNr = nCurrentTab;
+
+ if ( !pDoc->IsDocEditable() )
+ break; // gesperrt
+
+ if ( pReqArgs != NULL ) // von Basic
+ {
+ BOOL bOk = FALSE;
+ const SfxPoolItem* pTabItem;
+ const SfxPoolItem* pNameItem;
+ String aName;
+
+ if ( IS_AVAILABLE( FN_PARAM_1, &pTabItem ) &&
+ IS_AVAILABLE( nSlot, &pNameItem ) )
+ {
+ // Tabellennr. von Basic: 1-basiert
+
+ aName = ((const SfxStringItem*)pNameItem)->GetValue();
+ nTabNr = ((const SfxUInt16Item*)pTabItem)->GetValue() - 1;
+ if ( nTabNr < nTabCount )
+ bOk = InsertTable( aName, nTabNr );
+ }
+
+ if (bOk)
+ rReq.Done( *pReqArgs );
+ //! sonst Fehler setzen
+ }
+ else // Dialog
+ {
+//CHINA001 ScInsertTableDlg* pDlg = new ScInsertTableDlg(
+//CHINA001 GetDialogParent(),
+//CHINA001 *pViewData,nTabSelCount);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertTableDlg* pDlg = pFact->CreateScInsertTableDlg( GetDialogParent(), *pViewData,
+ nTabSelCount, nSlot == FID_INS_TABLE_EXT,
+ RID_SCDLG_INSERT_TABLE);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( RET_OK == pDlg->Execute() )
+ {
+ if (pDlg->GetTablesFromFile())
+ {
+ SCTAB nTabs[MAXTABCOUNT];
+ SCTAB nCount = 0;
+ USHORT n = 0;
+ const String* pStr = pDlg->GetFirstTable( &n );
+ while ( pStr )
+ {
+ nTabs[nCount++] = static_cast<SCTAB>(n);
+ pStr = pDlg->GetNextTable( &n );
+ }
+ BOOL bLink = pDlg->GetTablesAsLink();
+ if (nCount != 0)
+ {
+ if(pDlg->IsTableBefore())
+ {
+ ImportTables( pDlg->GetDocShellTables(), nCount, nTabs,
+ bLink,nTabNr );
+ }
+ else
+ {
+ SCTAB nTabAfter = nTabNr+1;
+
+ for(SCTAB j=nCurrentTab+1;j<nTabCount;j++)
+ {
+ if(!pDoc->IsScenario(j))
+ {
+ nTabAfter=j;
+ break;
+ }
+ }
+
+ ImportTables( pDlg->GetDocShellTables(), nCount, nTabs,
+ bLink,nTabAfter );
+ }
+ }
+ }
+ else
+ {
+ SCTAB nCount=pDlg->GetTableCount();
+ if(pDlg->IsTableBefore())
+ {
+ if(nCount==1 && pDlg->GetFirstTable()->Len()>0)
+ {
+ rReq.AppendItem( SfxStringItem( FID_INS_TABLE, *pDlg->GetFirstTable() ) );
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nTabNr) + 1 ) ); // 1-based
+ rReq.Done();
+
+ InsertTable( *pDlg->GetFirstTable(), nTabNr );
+ }
+ else
+ InsertTables( NULL, nTabNr,nCount );
+ }
+ else
+ {
+ SCTAB nTabAfter = nTabNr+1;
+ SCTAB nSelHigh=0;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ nSelHigh=i;
+ }
+ }
+
+ for(SCTAB j=nSelHigh+1;j<nTabCount;j++)
+ {
+ if(!pDoc->IsScenario(j))
+ {
+ nTabAfter=j;
+ break;
+ }
+ else // #101672#; increase nTabAfter, because it is possible that the scenario tables are the last
+ nTabAfter = j + 1;
+ }
+
+ if(nCount==1 && pDlg->GetFirstTable()->Len()>0)
+ {
+ rReq.AppendItem( SfxStringItem( FID_INS_TABLE, *pDlg->GetFirstTable() ) );
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nTabAfter) + 1 ) ); // 1-based
+ rReq.Done();
+
+ InsertTable( *pDlg->GetFirstTable(), nTabAfter);
+ }
+ else
+ {
+ InsertTables( NULL, nTabAfter,nCount);
+ }
+ }
+ }
+ }
+
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_TAB_APPEND:
+ case FID_TAB_RENAME:
+ case FID_TAB_MENU_RENAME:
+ {
+ // FID_TAB_MENU_RENAME - "umbenennen" im Menu
+ // FID_TAB_RENAME - "Name"-Property fuer Basic
+ // Execute ist gleich, aber im GetState wird MENU_RENAME evtl. disabled
+
+ if ( nSlot == FID_TAB_MENU_RENAME )
+ nSlot = FID_TAB_RENAME; // Execute ist gleich
+
+ SCTAB nTabNr = pViewData->GetTabNo();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ if ( !pDoc->IsDocEditable() )
+ break; // alles gesperrt
+
+ if ( nSlot != FID_TAB_APPEND &&
+ ( pDoc->IsTabProtected( nTabNr ) || nTabSelCount > 1 ) )
+ break; // kein Rename
+
+#if 0
+ // ScSbxObject wird nicht mehr benutzt, stattdessen aus dem
+ // ScSbxTable::Notify die richtige Tabelle an der Basic-View eingestellt
+ if( rReq.IsAPI() )
+ {
+ SbxObject* pObj = GetScSbxObject();
+ ScSbxTable* pSbxTab = PTR_CAST( ScSbxTable, pObj );
+ DBG_ASSERT( pSbxTab, "pSbxTab???" );
+
+ if( pSbxTab )
+ nTabNr = pSbxTab->GetTableNr();
+ }
+#endif
+
+ if( pReqArgs != NULL )
+ {
+ BOOL bDone = FALSE;
+ const SfxPoolItem* pItem;
+ String aName;
+
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nTabNr = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( nSlot, &pItem ) )
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+
+ switch ( nSlot )
+ {
+ case FID_TAB_APPEND:
+ bDone = AppendTable( aName );
+ break;
+ case FID_TAB_RENAME:
+ bDone = RenameTable( aName, nTabNr );
+ break;
+ }
+
+ if( bDone )
+ {
+ rReq.Done( *pReqArgs );
+ }
+ }
+ else
+ {
+ USHORT nRet = RET_OK;
+ BOOL bDone = FALSE;
+ String aErrMsg ( ScGlobal::GetRscString( STR_INVALIDTABNAME ) );
+ String aName;
+ String aDlgTitle;
+
+ switch ( nSlot )
+ {
+ case FID_TAB_APPEND:
+ aDlgTitle = String(ScResId(SCSTR_APDTABLE));
+ pDoc->CreateValidTabName( aName );
+ break;
+
+ case FID_TAB_RENAME:
+ aDlgTitle = String(ScResId(SCSTR_RENAMETAB));
+ pDoc->GetName( pViewData->GetTabNo(), aName );
+ break;
+ }
+
+//CHINA001 ScStringInputDlg* pDlg =
+//CHINA001 new ScStringInputDlg( GetDialogParent(),
+//CHINA001 aDlgTitle,
+//CHINA001 String(ScResId(SCSTR_NAME)),
+//CHINA001 aName,
+//CHINA001 nSlot );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScStringInputDlg* pDlg = pFact->CreateScStringInputDlg( GetDialogParent(),
+ aDlgTitle,
+ String(ScResId(SCSTR_NAME)),
+ aName,
+ nSlot,RID_SCDLG_STRINPUT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ while ( !bDone && nRet == RET_OK )
+ {
+ nRet = pDlg->Execute();
+
+ if ( nRet == RET_OK )
+ {
+ pDlg->GetInputString( aName );
+
+
+ switch ( nSlot )
+ {
+ case FID_TAB_APPEND:
+ bDone = AppendTable( aName );
+ break;
+ case FID_TAB_RENAME:
+ bDone = RenameTable( aName, nTabNr );
+ break;
+ }
+
+ if ( bDone )
+ {
+ rReq.AppendItem( SfxStringItem( nSlot, aName ) );
+ rReq.Done();
+ }
+ else
+ {
+ if( rReq.IsAPI() )
+ {
+ StarBASIC::Error( SbERR_SETPROP_FAILED ); // XXX Fehlerbehandlung???
+ }
+ else
+ {
+ nRet = ErrorBox( GetDialogParent(),
+ WinBits( WB_OK | WB_DEF_OK ),
+ aErrMsg
+ ).Execute();
+ }
+ }
+ }
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_TAB_MOVE:
+ {
+ if ( pDoc->GetChangeTrack() != NULL )
+ break; // bei aktiviertem ChangeTracking kein TabMove
+
+ BOOL bDoIt = FALSE;
+ USHORT nDoc = 0;
+ SCTAB nTab = pViewData->GetTabNo();
+ BOOL bCpy = FALSE;
+ String aDocName;
+
+ if( pReqArgs != NULL )
+ {
+ SCTAB nTableCount = pDoc->GetTableCount();
+ const SfxPoolItem* pItem;
+
+ if( IS_AVAILABLE( FID_TAB_MOVE, &pItem ) )
+ aDocName = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ {
+ // Tabelle ist 1-basiert
+ nTab = ((const SfxUInt16Item*)pItem)->GetValue() - 1;
+ if ( nTab >= nTableCount )
+ nTab = SC_TAB_APPEND;
+ }
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ bCpy = ((const SfxBoolItem*)pItem)->GetValue();
+
+ if( aDocName.Len() )
+ {
+ SfxObjectShell* pSh = SfxObjectShell::GetFirst();
+ ScDocShell* pScSh = NULL;
+ USHORT i=0;
+
+ while ( pSh )
+ {
+ pScSh = PTR_CAST( ScDocShell, pSh );
+
+ if( pScSh )
+ {
+ pScSh->GetTitle();
+
+ if( pScSh->GetTitle() == aDocName )
+ {
+ nDoc = i;
+ ScDocument* pDestDoc = pScSh->GetDocument();
+ nTableCount = pDestDoc->GetTableCount();
+ bDoIt = pDestDoc->IsDocEditable();
+ break;
+ }
+
+ i++; // nur die ScDocShell's zaehlen
+ }
+ pSh = SfxObjectShell::GetNext( *pSh );
+ }
+ }
+ else // Kein Dokumentname -> neues Dokument
+ {
+ nDoc = SC_DOC_NEW;
+ bDoIt = TRUE;
+ }
+
+ if ( bDoIt && nTab >= nTableCount ) // ggf. anhaengen
+ nTab = SC_TAB_APPEND;
+ }
+ else
+ {
+ //CHINA001 ScMoveTableDlg* pDlg = new ScMoveTableDlg( GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMoveTableDlg* pDlg = pFact->CreateScMoveTableDlg( GetDialogParent(), RID_SCDLG_MOVETAB );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ SCTAB nTableCount = pDoc->GetTableCount();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+
+ if(nTableCount==nTabSelCount)
+ {
+ pDlg->SetCopyTable();
+ pDlg->EnableCopyTable(FALSE);
+ }
+ if ( pDlg->Execute() == RET_OK )
+ {
+ nDoc = pDlg->GetSelectedDocument();
+ nTab = pDlg->GetSelectedTable();
+ bCpy = pDlg->GetCopyTable();
+ bDoIt = TRUE;
+
+ String aFoundDocName;
+ if ( nDoc != SC_DOC_NEW )
+ {
+ ScDocShell* pSh = ScDocShell::GetShellByNum( nDoc );
+ if (pSh)
+ {
+ aFoundDocName = pSh->GetTitle();
+ if ( !pSh->GetDocument()->IsDocEditable() )
+ {
+ ErrorMessage(STR_READONLYERR);
+ bDoIt = FALSE;
+ }
+ }
+ }
+ rReq.AppendItem( SfxStringItem( FID_TAB_MOVE, aFoundDocName ) );
+ // Tabelle ist 1-basiert, wenn nicht APPEND
+ SCTAB nBasicTab = ( nTab <= MAXTAB ) ? (nTab+1) : nTab;
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nBasicTab) ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_2, bCpy ) );
+ }
+ delete pDlg;
+ }
+
+ if( bDoIt )
+ {
+ rReq.Done(); // aufzeichnen, solange das Dokument noch aktiv ist
+
+ MoveTable( nDoc, nTab, bCpy );
+ }
+ }
+ break;
+
+ case FID_DELETE_TABLE:
+ {
+ // Parameter war ueberfluessig, weil die Methode an der Table haengt
+
+ BOOL bDoIt = rReq.IsAPI();
+ if( !bDoIt )
+ {
+ // wenn's nicht von Basic kommt, nochmal nachfragen:
+
+#if ENABLE_LAYOUT
+// Using layout::QueryBox without client code modification is
+// deprecated, rather add HIG-complient buttons with verbs.
+#define QueryBox( parent, winbits, question ) layout::QueryBox (parent, question, ScGlobal::GetRscString (STR_UNDO_DELETE_TAB))
+#endif /* ENABLE_LAYOUT */
+
+ bDoIt = ( RET_YES ==
+ QueryBox( GetDialogParent(),
+ WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString(STR_QUERY_DELTAB)
+ ).Execute() );
+ }
+ if( bDoIt )
+ {
+ SCTAB nNewTab = nCurrentTab;
+ SCTAB nFirstTab=0;
+ BOOL bTabFlag=FALSE;
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SvShorts TheTabs;
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i) &&!pDoc->IsTabProtected(i))
+ {
+ TheTabs.Insert(i,TheTabs.Count());
+ bTabFlag=TRUE;
+ if(nNewTab==i) nNewTab++;
+ }
+ if(!bTabFlag) nFirstTab=i;
+ }
+ if(nNewTab>=nTabCount) nNewTab=nFirstTab;
+
+ pViewData->SetTabNo(nNewTab);
+ DeleteTables(TheTabs);
+ TheTabs.Remove(0,TheTabs.Count());
+ rReq.Done();
+ }
+ }
+ break;
+
+ case FID_TAB_RTL:
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocFunc aFunc(*pDocSh);
+ BOOL bSet = !pDoc->IsLayoutRTL( nCurrentTab );
+
+ const ScMarkData& rMark = pViewData->GetMarkData();
+ if ( rMark.GetSelectCount() != 0 )
+ {
+ // handle several sheets
+
+ SfxUndoManager* pUndoManager = pDocSh->GetUndoManager();
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_TAB_RTL );
+ pUndoManager->EnterListAction( aUndo, aUndo );
+
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( rMark.GetTableSelect(nTab) )
+ aFunc.SetLayoutRTL( nTab, bSet, FALSE );
+
+ pUndoManager->LeaveListAction();
+ }
+ else
+ aFunc.SetLayoutRTL( nCurrentTab, bSet, FALSE );
+ }
+ break;
+
+ case FID_TAB_SET_TAB_BG_COLOR:
+ case FID_TAB_MENU_SET_TAB_BG_COLOR:
+ {
+ if ( nSlot == FID_TAB_MENU_SET_TAB_BG_COLOR )
+ nSlot = FID_TAB_SET_TAB_BG_COLOR;
+ SCTAB nTabNr = pViewData->GetTabNo();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ if ( !pDoc->IsDocEditable() )
+ break;
+
+ if ( pDoc->IsTabProtected( nTabNr ) ) // ||nTabSelCount > 1
+ break;
+
+ if( pReqArgs != NULL )
+ {
+ BOOL bDone = FALSE;
+ const SfxPoolItem* pItem;
+ Color aColor;
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nTabNr = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( nSlot, &pItem ) )
+ aColor = ((const SvxColorItem*)pItem)->GetValue();
+
+ if ( nTabSelCount > 1 )
+ {
+ scoped_ptr<ScUndoTabColorInfo::List>
+ pTabColorList(new ScUndoTabColorInfo::List);
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if ( rMark.GetTableSelect(nTab) && !pDoc->IsTabProtected(nTab) )
+ {
+ ScUndoTabColorInfo aTabColorInfo(nTab);
+ aTabColorInfo.maNewTabBgColor = aColor;
+ pTabColorList->push_back(aTabColorInfo);
+ }
+ }
+ bDone = SetTabBgColor( *pTabColorList );
+ }
+ else
+ {
+ bDone = SetTabBgColor( aColor, nCurrentTab ); //ScViewFunc.SetTabBgColor
+ }
+ if( bDone )
+ {
+ rReq.Done( *pReqArgs );
+ }
+ }
+ else
+ {
+ USHORT nRet = RET_OK; /// temp
+ BOOL bDone = FALSE; /// temp
+ Color aTabBgColor;
+ Color aNewTabBgColor;
+
+ aTabBgColor = pDoc->GetTabBgColor( nCurrentTab );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");
+ AbstractScTabBgColorDlg* pDlg = pFact->CreateScTabBgColorDlg(
+ GetDialogParent(),
+ String(ScResId(SCSTR_SET_TAB_BG_COLOR)),
+ String(ScResId(SCSTR_NO_TAB_BG_COLOR)),
+ aTabBgColor,
+ nSlot,RID_SCDLG_TAB_BG_COLOR);
+ while ( !bDone && nRet == RET_OK )
+ {
+ nRet = pDlg->Execute();
+ if( nRet == RET_OK )
+ {
+ Color aSelectedColor;
+ pDlg->GetSelectedColor(aSelectedColor);
+ scoped_ptr<ScUndoTabColorInfo::List>
+ pTabColorList(new ScUndoTabColorInfo::List);
+ if ( nTabSelCount > 1 )
+ {
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if ( rMark.GetTableSelect(nTab) && !pDoc->IsTabProtected(nTab) )
+ {
+ ScUndoTabColorInfo aTabColorInfo(nTab);
+ aTabColorInfo.maNewTabBgColor = aSelectedColor;
+ pTabColorList->push_back(aTabColorInfo);
+ }
+ }
+ bDone = SetTabBgColor( *pTabColorList );
+ }
+ else
+ {
+ bDone = SetTabBgColor( aSelectedColor, nCurrentTab ); //ScViewFunc.SetTabBgColor
+ }
+ if ( bDone )
+ {
+ rReq.AppendItem( SvxColorItem( aTabBgColor, nSlot ) );
+ rReq.Done();
+ }
+ else
+ {
+ if( rReq.IsAPI() )
+ {
+ StarBASIC::Error( SbERR_SETPROP_FAILED );
+ }
+ }
+ }
+ }
+ delete( pDlg );
+ }
+ }
+ break;
+
+ case FID_TAB_EVENTS:
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ uno::Reference<container::XNameReplace> xEvents( new ScSheetEventsObj( pDocSh, nCurrentTab ) );
+ uno::Reference<frame::XFrame> xFrame = GetViewFrame()->GetFrame().GetFrameInterface();
+ SvxAbstractDialogFactory* pDlgFactory = SvxAbstractDialogFactory::Create();
+ if (pDlgFactory)
+ {
+ std::auto_ptr<VclAbstractDialog> pDialog( pDlgFactory->CreateSvxMacroAssignDlg(
+ GetDialogParent(), xFrame, false, xEvents, 0 ) );
+ if ( pDialog.get() && pDialog->Execute() == RET_OK )
+ {
+ // the dialog modifies the settings directly
+ }
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell");
+ break;
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::GetStateTable( SfxItemSet& rSet )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+
+ case FID_TABLE_VISIBLE:
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsVisible(nTab) ));
+ break;
+
+ case FID_TABLE_HIDE:
+ {
+ USHORT nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+
+ if ( nVis<2 || !pDoc->IsDocEditable() || nTabSelCount > 1 )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_TABLE_SHOW:
+ {
+ BOOL bHasHidden = FALSE;
+ for ( SCTAB i=0; i < nTabCount && !bHasHidden; i++ )
+ if (!pDoc->IsVisible(i))
+ bHasHidden = TRUE;
+ if ( !bHasHidden || pDoc->IsDocProtected() || nTabSelCount > 1 )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_DELETE_TABLE:
+ {
+ if ( pDoc->GetChangeTrack() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ USHORT nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+ if ( pDoc->IsTabProtected(nTab)
+ || !pDoc->IsDocEditable()
+ || nVis < 2
+ || nTabSelCount == nTabCount)
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_INS_TABLE:
+ case FID_INS_TABLE_EXT:
+ case FID_TAB_APPEND:
+ if ( !pDoc->IsDocEditable() ||
+ nTabCount > MAXTAB ||
+ ( nWhich == FID_INS_TABLE_EXT && pDocShell && pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_TAB_MOVE:
+ if ( !pDoc->IsDocEditable()
+ || pDoc->GetChangeTrack() != NULL
+ || nTabCount > MAXTAB)
+ rSet.DisableItem( nWhich );
+ break;
+
+ // FID_TAB_MENU_RENAME - "umbenennen" im Menu
+ // FID_TAB_RENAME - "Name"-Property fuer Basic
+
+ case FID_TAB_MENU_RENAME:
+ if ( !pDoc->IsDocEditable() ||
+ pDoc->IsTabProtected(nTab) ||nTabSelCount > 1 ||
+ ( pDocShell && pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_TAB_RENAME:
+ {
+ String aTabName;
+ pDoc->GetName( nTab, aTabName );
+
+ rSet.Put( SfxStringItem( nWhich, aTabName ));
+
+ }
+ break;
+
+ case FID_TAB_RTL:
+ {
+ SvtLanguageOptions aLangOpt;
+ if ( !aLangOpt.IsCTLFontEnabled() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsLayoutRTL( nTab ) ) );
+ }
+ break;
+
+ case FID_TAB_MENU_SET_TAB_BG_COLOR:
+ {
+ if ( !pDoc->IsDocEditable()
+ || ( pDocShell && pDocShell->IsDocShared() )
+ || pDoc->IsTabProtected(nTab) )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_TAB_SET_TAB_BG_COLOR:
+ {
+ Color aColor;
+ aColor = pDoc->GetTabBgColor( nTab );
+ rSet.Put( SvxColorItem( aColor, nWhich ) );
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshg.cxx b/sc/source/ui/view/tabvwshg.cxx
new file mode 100644
index 000000000000..b30b07c43cb9
--- /dev/null
+++ b/sc/source/ui/view/tabvwshg.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+//#define SI_VCDRAWOBJ
+
+#include <tools/urlobj.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpagv.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+
+using namespace com::sun::star;
+
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "drawview.hxx"
+#include "globstr.hrc"
+#include <avmedia/mediawindow.hxx>
+
+//------------------------------------------------------------------------
+
+void ScTabViewShell::InsertURLButton( const String& rName, const String& rURL,
+ const String& rTarget,
+ const Point* pInsPos )
+{
+ // Tabelle geschuetzt ?
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ MakeDrawLayer();
+
+ ScTabView* pView = pViewData->GetView();
+// SdrView* pDrView = pView->GetSdrView();
+ ScDrawView* pDrView = pView->GetScDrawView();
+ SdrModel* pModel = pDrView->GetModel();
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(FmFormInventor, OBJ_FM_BUTTON,
+ pDrView->GetSdrPageView()->GetPage(), pModel);
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObj);
+
+ uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
+ DBG_ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Any aAny;
+
+ aAny <<= rtl::OUString(rName);
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "Label" ), aAny );
+
+ ::rtl::OUString aTmp = INetURLObject::GetAbsURL( pDoc->GetDocumentShell()->GetMedium()->GetBaseURL(), rURL );
+ aAny <<= aTmp;
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "TargetURL" ), aAny );
+
+ if( rTarget.Len() )
+ {
+ aAny <<= rtl::OUString(rTarget);
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "TargetFrame" ), aAny );
+ }
+
+ form::FormButtonType eButtonType = form::FormButtonType_URL;
+ aAny <<= eButtonType;
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "ButtonType" ), aAny );
+
+ if ( ::avmedia::MediaWindow::isMediaURL( rURL ) )
+ {
+ // #105638# OJ
+ aAny <<= sal_True;
+ xPropSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DispatchURLInternal" )), aAny );
+ }
+
+ Point aPos;
+ if (pInsPos)
+ aPos = *pInsPos;
+ else
+ aPos = GetInsertPos();
+
+ // Groesse wie in 3.1:
+ Size aSize = GetActiveWin()->PixelToLogic(Size(140, 20));
+
+ if ( pDoc->IsNegativePage(nTab) )
+ aPos.X() -= aSize.Width();
+
+ pObj->SetLogicRect(Rectangle(aPos, aSize));
+// pObj->Resize(Point(), Fraction(1, 1), Fraction(1, 1));
+
+ // am alten VC-Button musste die Position/Groesse nochmal explizit
+ // gesetzt werden - das scheint mit UnoControls nicht noetig zu sein
+
+ // nicht markieren wenn Ole
+ pDrView->InsertObjectSafe( pObj, *pDrView->GetSdrPageView() );
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshh.cxx b/sc/source/ui/view/tabvwshh.cxx
new file mode 100644
index 000000000000..480514741bae
--- /dev/null
+++ b/sc/source/ui/view/tabvwshh.cxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <svx/svdmark.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdview.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <basic/sbxcore.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "tabvwsh.hxx"
+#include "client.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "sc.hrc"
+#include "drwlayer.hxx" // GetVisibleName
+#include "retypepassdlg.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteSbx( SfxRequest& /* rReq */ )
+{
+ // SID_RANGE_OFFSET (Offset),
+ // SID_PIVOT_CREATE (DataPilotCreate) - removed (old Basic)
+}
+
+void ScTabViewShell::GetSbxState( SfxItemSet& /* rSet */ )
+{
+ // SID_RANGE_REGION (CurrentRegion) - removed (old Basic)
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteObject( SfxRequest& rReq )
+{
+ USHORT nSlotId = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ // Objekte aktivieren/deaktivieren immer auf der sichtbaren View
+
+ ScTabViewShell* pVisibleSh = this;
+ if ( nSlotId == SID_OLE_SELECT || nSlotId == SID_OLE_ACTIVATE || nSlotId == SID_OLE_DEACTIVATE )
+ {
+ DBG_ERROR("old slot SID_OLE...");
+ }
+
+ switch (nSlotId)
+ {
+ case SID_OLE_SELECT:
+ case SID_OLE_ACTIVATE:
+ {
+ // in beiden Faellen erstmal auf der sichtbaren View selektieren
+
+ String aName;
+ SdrView* pDrView = GetSdrView();
+ if (pDrView)
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ aName = ScDrawLayer::GetVisibleName( rMarkList.GetMark(0)->GetMarkedSdrObj() );
+ }
+ pVisibleSh->SelectObject( aName );
+
+ // aktivieren
+
+ if ( nSlotId == SID_OLE_ACTIVATE )
+ pVisibleSh->DoVerb( 0 );
+ }
+ break;
+ case SID_OLE_DEACTIVATE:
+ pVisibleSh->DeactivateOle();
+ break;
+
+ case SID_OBJECT_LEFT:
+ case SID_OBJECT_TOP:
+ case SID_OBJECT_WIDTH:
+ case SID_OBJECT_HEIGHT:
+ {
+ BOOL bDone = FALSE;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlotId, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ long nNewVal = ((const SfxInt32Item*)pItem)->GetValue();
+ if ( nNewVal < 0 )
+ nNewVal = 0;
+
+ //! von irgendwas in 1/100mm umrechnen ??????
+
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ Rectangle aRect = pObj->GetLogicRect();
+
+ if ( nSlotId == SID_OBJECT_LEFT )
+ pDrView->MoveMarkedObj( Size( nNewVal - aRect.Left(), 0 ) );
+ else if ( nSlotId == SID_OBJECT_TOP )
+ pDrView->MoveMarkedObj( Size( 0, nNewVal - aRect.Top() ) );
+ else if ( nSlotId == SID_OBJECT_WIDTH )
+ pDrView->ResizeMarkedObj( aRect.TopLeft(),
+ Fraction( nNewVal, aRect.GetWidth() ),
+ Fraction( 1, 1 ) );
+ else // if ( nSlotId == SID_OBJECT_HEIGHT )
+ pDrView->ResizeMarkedObj( aRect.TopLeft(),
+ Fraction( 1, 1 ),
+ Fraction( nNewVal, aRect.GetHeight() ) );
+ bDone = TRUE;
+ }
+ }
+ }
+ if (!bDone)
+ SbxBase::SetError( SbxERR_BAD_PARAMETER ); // Basic-Fehler
+ }
+ break;
+
+ }
+}
+
+uno::Reference < embed::XEmbeddedObject > lcl_GetSelectedObj( SdrView* pDrView ) //! Member von ScDrawView?
+{
+ uno::Reference < embed::XEmbeddedObject > xRet;
+ if (pDrView)
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() == OBJ_OLE2)
+ {
+ SdrOle2Obj* pOle2Obj = (SdrOle2Obj*) pObj;
+ xRet = pOle2Obj->GetObjRef();
+ }
+ }
+ }
+
+ return xRet;
+}
+
+void ScTabViewShell::GetObjectState( SfxItemSet& rSet )
+{
+ // SID_OLE_OBJECT - removed (old Basic)
+
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_ACTIVE_OBJ_NAME:
+ {
+ String aName;
+ uno::Reference < embed::XEmbeddedObject > xOLE = lcl_GetSelectedObj( GetSdrView() );
+ if (xOLE.is())
+ {
+ aName = GetViewData()->GetSfxDocShell()->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xOLE );
+ }
+ rSet.Put( SfxStringItem( nWhich, aName ) );
+ }
+ break;
+ case SID_OBJECT_LEFT:
+ case SID_OBJECT_TOP:
+ case SID_OBJECT_WIDTH:
+ case SID_OBJECT_HEIGHT:
+ {
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ Rectangle aRect = pObj->GetLogicRect();
+
+ long nVal;
+ if ( nWhich == SID_OBJECT_LEFT )
+ nVal = aRect.Left();
+ else if ( nWhich == SID_OBJECT_TOP )
+ nVal = aRect.Top();
+ else if ( nWhich == SID_OBJECT_WIDTH )
+ nVal = aRect.GetWidth();
+ else // if ( nWhich == SID_OBJECT_HEIGHT )
+ nVal = aRect.GetHeight();
+
+ //! von 1/100mm in irgendwas umrechnen ??????
+
+ rSet.Put( SfxInt32Item( nWhich, nVal ) );
+ }
+ }
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScTabViewShell::AddAccessibilityObject( SfxListener& rObject )
+{
+ if (!pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster = new SfxBroadcaster;
+
+ rObject.StartListening( *pAccessibilityBroadcaster );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (pDoc)
+ pDoc->AddUnoObject(rObject);
+}
+
+void ScTabViewShell::RemoveAccessibilityObject( SfxListener& rObject )
+{
+ if (pAccessibilityBroadcaster)
+ {
+ rObject.EndListening( *pAccessibilityBroadcaster );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (pDoc)
+ pDoc->RemoveUnoObject(rObject);
+ }
+ else
+ {
+ DBG_ERROR("kein Accessibility-Broadcaster?");
+ }
+}
+
+void ScTabViewShell::BroadcastAccessibility( const SfxHint &rHint )
+{
+ if (pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster->Broadcast( rHint );
+}
+
+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/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
new file mode 100644
index 000000000000..7b35328f68bb
--- /dev/null
+++ b/sc/source/ui/view/viewdata.cxx
@@ -0,0 +1,3179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <sfx2/viewfrm.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unolingu.hxx>
+
+#include <vcl/svapp.hxx>
+#include <rtl/math.hxx>
+
+#include "viewdata.hxx"
+#include "docoptio.hxx"
+#include "scmod.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "sc.hrc"
+#include "patattr.hxx"
+#include "editutil.hxx"
+#include "scextopt.hxx"
+#include "miscuno.hxx"
+#include "unonames.hxx"
+#include "inputopt.hxx"
+#include "viewutil.hxx"
+#include <xmloff/xmluconv.hxx>
+#include "ViewSettingsSequenceDefines.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+#define SC_GROWY_SMALL_EXTRA 100
+#define SC_GROWY_BIG_EXTRA 200
+
+#define TAG_TABBARWIDTH "tw:"
+
+static BOOL bMoveArea = FALSE; //! Member?
+USHORT nEditAdjust = SVX_ADJUST_LEFT; //! Member !!!
+
+//==================================================================
+
+ScViewDataTable::ScViewDataTable() :
+ eZoomType( SVX_ZOOM_PERCENT ),
+ aZoomX( 1,1 ),
+ aZoomY( 1,1 ),
+ aPageZoomX( 3,5 ), // Page-Default: 60%
+ aPageZoomY( 3,5 ),
+ nHSplitPos( 0 ),
+ nVSplitPos( 0 ),
+ eHSplitMode( SC_SPLIT_NONE ),
+ eVSplitMode( SC_SPLIT_NONE ),
+ eWhichActive( SC_SPLIT_BOTTOMLEFT ),
+ nFixPosX( 0 ),
+ nFixPosY( 0 ),
+ nCurX( 0 ),
+ nCurY( 0 ),
+ bOldCurValid( FALSE )
+{
+ nPosX[0]=nPosX[1]=0;
+ nPosY[0]=nPosY[1]=0;
+ nTPosX[0]=nTPosX[1]=0;
+ nTPosY[0]=nTPosY[1]=0;
+ nMPosX[0]=nMPosX[1]=0;
+ nMPosY[0]=nMPosY[1]=0;
+ nPixPosX[0]=nPixPosX[1]=0;
+ nPixPosY[0]=nPixPosY[1]=0;
+}
+
+ScViewDataTable::~ScViewDataTable()
+{
+}
+
+void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& /*rViewData*/, SCTAB /*nTab*/)
+{
+ rSettings.realloc(SC_TABLE_VIEWSETTINGS_COUNT);
+ beans::PropertyValue* pSettings = rSettings.getArray();
+ if (pSettings)
+ {
+ pSettings[SC_CURSOR_X].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURSORPOSITIONX));
+ pSettings[SC_CURSOR_X].Value <<= sal_Int32(nCurX);
+ pSettings[SC_CURSOR_Y].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURSORPOSITIONY));
+ pSettings[SC_CURSOR_Y].Value <<= sal_Int32(nCurY);
+ pSettings[SC_HORIZONTAL_SPLIT_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSPLITMODE));
+ pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eHSplitMode);
+ pSettings[SC_VERTICAL_SPLIT_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VERTICALSPLITMODE));
+ pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eVSplitMode);
+ pSettings[SC_HORIZONTAL_SPLIT_POSITION].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSPLITPOSITION));
+ if (eHSplitMode == SC_SPLIT_FIX)
+ pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosX);
+ else
+ pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nHSplitPos);
+ pSettings[SC_VERTICAL_SPLIT_POSITION].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VERTICALSPLITPOSITION));
+ if (eVSplitMode == SC_SPLIT_FIX)
+ pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosY);
+ else
+ pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nVSplitPos);
+ pSettings[SC_ACTIVE_SPLIT_RANGE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVESPLITRANGE));
+ pSettings[SC_ACTIVE_SPLIT_RANGE].Value <<= sal_Int16(eWhichActive);
+ pSettings[SC_POSITION_LEFT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONLEFT));
+ pSettings[SC_POSITION_LEFT].Value <<= sal_Int32(nPosX[SC_SPLIT_LEFT]);
+ pSettings[SC_POSITION_RIGHT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONRIGHT));
+ pSettings[SC_POSITION_RIGHT].Value <<= sal_Int32(nPosX[SC_SPLIT_RIGHT]);
+ pSettings[SC_POSITION_TOP].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONTOP));
+ pSettings[SC_POSITION_TOP].Value <<= sal_Int32(nPosY[SC_SPLIT_TOP]);
+ pSettings[SC_POSITION_BOTTOM].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONBOTTOM));
+ pSettings[SC_POSITION_BOTTOM].Value <<= sal_Int32(nPosY[SC_SPLIT_BOTTOM]);
+
+ sal_Int32 nZoomValue ((aZoomY.GetNumerator() * 100) / aZoomY.GetDenominator());
+ sal_Int32 nPageZoomValue ((aPageZoomY.GetNumerator() * 100) / aPageZoomY.GetDenominator());
+ pSettings[SC_TABLE_ZOOM_TYPE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMTYPE));
+ pSettings[SC_TABLE_ZOOM_TYPE].Value <<= sal_Int16(eZoomType);
+ pSettings[SC_TABLE_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
+ pSettings[SC_TABLE_ZOOM_VALUE].Value <<= nZoomValue;
+ pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE));
+ pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
+ }
+}
+
+void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& aSettings, ScViewData& rViewData, SCTAB nTab, bool& rHasZoom )
+{
+ rHasZoom = false;
+
+ sal_Int32 nCount(aSettings.getLength());
+ sal_Int32 nTemp32(0);
+ sal_Int16 nTemp16(0);
+ sal_Int32 nTempPosV(0);
+ sal_Int32 nTempPosH(0);
+ sal_Int32 nTempPosVTw(0);
+ sal_Int32 nTempPosHTw(0);
+ bool bHasVSplitInTwips = false;
+ bool bHasHSplitInTwips = false;
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ rtl::OUString sName(aSettings[i].Name);
+ if (sName.compareToAscii(SC_CURSORPOSITIONX) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nCurX = SanitizeCol( static_cast<SCCOL>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_CURSORPOSITIONY) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nCurY = SanitizeRow( static_cast<SCROW>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSPLITMODE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eHSplitMode = static_cast<ScSplitMode>(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_VERTICALSPLITMODE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eVSplitMode = static_cast<ScSplitMode>(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSPLITPOSITION) == 0)
+ {
+ aSettings[i].Value >>= nTempPosH;
+ bHasHSplitInTwips = false;
+ }
+ else if (sName.compareToAscii(SC_VERTICALSPLITPOSITION) == 0)
+ {
+ aSettings[i].Value >>= nTempPosV;
+ bHasVSplitInTwips = false;
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSPLITPOSITION_TWIPS) == 0)
+ {
+ aSettings[i].Value >>= nTempPosHTw;
+ bHasHSplitInTwips = true;
+ }
+ else if (sName.compareToAscii(SC_VERTICALSPLITPOSITION_TWIPS) == 0)
+ {
+ aSettings[i].Value >>= nTempPosVTw;
+ bHasVSplitInTwips = true;
+ }
+ else if (sName.compareToAscii(SC_ACTIVESPLITRANGE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eWhichActive = static_cast<ScSplitPos>(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_POSITIONLEFT) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosX[SC_SPLIT_LEFT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_POSITIONRIGHT) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosX[SC_SPLIT_RIGHT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_POSITIONTOP) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosY[SC_SPLIT_TOP] = SanitizeRow( static_cast<SCROW>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_POSITIONBOTTOM) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosY[SC_SPLIT_BOTTOM] = SanitizeRow( static_cast<SCROW>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eZoomType = SvxZoomType(nTemp16);
+ rHasZoom = true; // set if there is any zoom information
+ }
+ else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ Fraction aZoom(nTemp32, 100);
+ aZoomX = aZoomY = aZoom;
+ rHasZoom = true;
+ }
+ else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ Fraction aZoom(nTemp32, 100);
+ aPageZoomX = aPageZoomY = aZoom;
+ rHasZoom = true;
+ }
+ else if (sName.compareToAscii(SC_TABLESELECTED) == 0)
+ {
+ bool bSelected = false;
+ aSettings[i].Value >>= bSelected;
+ rViewData.GetMarkData().SelectTable( nTab, bSelected );
+ }
+ else if (sName.compareToAscii(SC_UNONAME_TABCOLOR) == 0)
+ {
+ // There are documents out there that have their tab color defined as a view setting.
+ sal_Int32 nColor = COL_AUTO;
+ aSettings[i].Value >>= nColor;
+ if (static_cast<ColorData>(nColor) != COL_AUTO)
+ {
+ ScDocument* pDoc = rViewData.GetDocument();
+ pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor)));
+ }
+ }
+ }
+ if (eHSplitMode == SC_SPLIT_FIX)
+ nFixPosX = SanitizeCol( static_cast<SCCOL>( bHasHSplitInTwips ? nTempPosHTw : nTempPosH ));
+ else
+ nHSplitPos = bHasHSplitInTwips ? static_cast< long >( nTempPosHTw * rViewData.GetPPTX() ) : nTempPosH;
+
+ if (eVSplitMode == SC_SPLIT_FIX)
+ nFixPosY = SanitizeRow( static_cast<SCROW>( bHasVSplitInTwips ? nTempPosVTw : nTempPosV ));
+ else
+ nVSplitPos = bHasVSplitInTwips ? static_cast< long >( nTempPosVTw * rViewData.GetPPTY() ) : nTempPosV;
+}
+
+//==================================================================
+
+ScViewData::ScViewData( ScDocShell* pDocSh, ScTabViewShell* pViewSh )
+ : pDocShell ( pDocSh ),
+ pDoc ( NULL ),
+ pView ( pViewSh ),
+ pViewShell ( pViewSh ),
+ pOptions ( new ScViewOptions ),
+ pSpellingView ( NULL ),
+ aLogicMode ( MAP_100TH_MM ),
+ eDefZoomType( SVX_ZOOM_PERCENT ),
+ aDefZoomX ( 1,1 ),
+ aDefZoomY ( 1,1 ),
+ aDefPageZoomX( 3,5 ),
+ aDefPageZoomY( 3,5 ),
+ eRefType ( SC_REFTYPE_NONE ),
+ nTabNo ( 0 ),
+ nRefTabNo ( 0 ),
+ eEditActivePart( SC_SPLIT_BOTTOMLEFT ),
+ bActive ( TRUE ), //! wie initialisieren?
+ bIsRefMode ( FALSE ),
+ bDelMarkValid( FALSE ),
+ nFillMode ( SC_FILL_NONE ),
+ bPagebreak ( FALSE ),
+ bSelCtrlMouseClick( FALSE )
+{
+
+ SetGridMode ( TRUE );
+ SetSyntaxMode ( FALSE );
+ SetHeaderMode ( TRUE );
+ SetTabMode ( TRUE );
+ SetVScrollMode ( TRUE );
+ SetHScrollMode ( TRUE );
+ SetOutlineMode ( TRUE );
+
+ aScrSize = Size( (long) ( STD_COL_WIDTH * PIXEL_PER_TWIPS * OLE_STD_CELLS_X ),
+ (long) ( ScGlobal::nStdRowHeight * PIXEL_PER_TWIPS * OLE_STD_CELLS_Y ) );
+ pTabData[0] = new ScViewDataTable;
+ for ( SCTAB i = 1; i <= MAXTAB; i++ )
+ pTabData[i] = NULL;
+ pThisTab = pTabData[nTabNo];
+ for (USHORT j=0; j<4; j++)
+ {
+ pEditView[j] = NULL;
+ bEditActive[j] = FALSE;
+ }
+
+ nEditEndCol = nEditStartCol = nEditCol = 0;
+ nEditEndRow = nEditRow = 0;
+ nTabStartCol = SC_TABSTART_NONE;
+
+ if (pDocShell)
+ {
+ pDoc = pDocShell->GetDocument();
+ *pOptions = pDoc->GetViewOptions();
+ }
+
+ // keine ausgeblendete Tabelle anzeigen:
+ if (pDoc && !pDoc->IsVisible(nTabNo))
+ {
+ while ( !pDoc->IsVisible(nTabNo) && pDoc->HasTable(nTabNo+1) )
+ ++nTabNo;
+
+ pTabData[nTabNo] = new ScViewDataTable;
+ pThisTab = pTabData[nTabNo];
+ }
+
+ CalcPPT();
+}
+
+ScViewData::ScViewData( const ScViewData& rViewData )
+ : pDocShell ( rViewData.pDocShell ),
+ pDoc ( rViewData.pDoc ),
+ pView ( rViewData.pView ),
+ pViewShell ( rViewData.pViewShell ),
+ pOptions ( new ScViewOptions( *(rViewData.pOptions) ) ),
+ pSpellingView ( rViewData.pSpellingView ),
+ aLogicMode ( rViewData.aLogicMode ),
+ eDefZoomType( rViewData.eDefZoomType ),
+ aDefZoomX ( rViewData.aDefZoomX ),
+ aDefZoomY ( rViewData.aDefZoomY ),
+ aDefPageZoomX( rViewData.aDefPageZoomX ),
+ aDefPageZoomY( rViewData.aDefPageZoomY ),
+ eRefType ( SC_REFTYPE_NONE ),
+ nTabNo ( rViewData.nTabNo ),
+ nRefTabNo ( rViewData.nTabNo ), // kein RefMode
+ eEditActivePart( rViewData.eEditActivePart ),
+ bActive ( TRUE ), //! wie initialisieren?
+ bIsRefMode ( FALSE ),
+ bDelMarkValid( FALSE ),
+ nFillMode ( SC_FILL_NONE ),
+ bPagebreak ( rViewData.bPagebreak ),
+ bSelCtrlMouseClick( rViewData.bSelCtrlMouseClick )
+{
+
+ SetGridMode ( rViewData.IsGridMode() );
+ SetSyntaxMode ( rViewData.IsSyntaxMode() );
+ SetHeaderMode ( rViewData.IsHeaderMode() );
+ SetTabMode ( rViewData.IsTabMode() );
+ SetVScrollMode ( rViewData.IsVScrollMode() );
+ SetHScrollMode ( rViewData.IsHScrollMode() );
+ SetOutlineMode ( rViewData.IsOutlineMode() );
+
+ aScrSize = rViewData.aScrSize;
+ for ( SCTAB i = 0; i <= MAXTAB; i++ )
+ if (rViewData.pTabData[i])
+ pTabData[i] = new ScViewDataTable( *rViewData.pTabData[i] );
+ else
+ pTabData[i] = NULL;
+ pThisTab = pTabData[nTabNo];
+ for (USHORT j=0; j<4; j++)
+ {
+ pEditView[j] = NULL;
+ bEditActive[j] = FALSE;
+ }
+
+ nEditEndCol = nEditStartCol = nEditCol = 0;
+ nEditEndRow = nEditRow = 0;
+ nTabStartCol = SC_TABSTART_NONE;
+ CalcPPT();
+}
+
+void ScViewData::InitData( ScDocument* pDocument )
+{
+ pDoc = pDocument;
+ *pOptions = pDoc->GetViewOptions();
+}
+
+//UNUSED2008-05 void ScViewData::InitFrom( const ScViewData* pRef )
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pRef==NULL)
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ERROR("ScViewData::InitFrom mit NULL");
+//UNUSED2008-05 return;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 aScrSize = pRef->aScrSize;
+//UNUSED2008-05 nTabNo = pRef->nTabNo;
+//UNUSED2008-05 eDefZoomType = pRef->eDefZoomType;
+//UNUSED2008-05 aDefZoomX = pRef->aDefZoomX;
+//UNUSED2008-05 aDefZoomY = pRef->aDefZoomY;
+//UNUSED2008-05 aDefPageZoomX = pRef->aDefPageZoomX;
+//UNUSED2008-05 aDefPageZoomY = pRef->aDefPageZoomY;
+//UNUSED2008-05 bPagebreak = pRef->bPagebreak;
+//UNUSED2008-05 aLogicMode = pRef->aLogicMode;
+//UNUSED2008-05
+//UNUSED2008-05 SetGridMode ( pRef->IsGridMode() );
+//UNUSED2008-05 SetSyntaxMode ( pRef->IsSyntaxMode() );
+//UNUSED2008-05 SetHeaderMode ( pRef->IsHeaderMode() );
+//UNUSED2008-05 SetTabMode ( pRef->IsTabMode() );
+//UNUSED2008-05 SetVScrollMode ( pRef->IsVScrollMode() );
+//UNUSED2008-05 SetHScrollMode ( pRef->IsHScrollMode() );
+//UNUSED2008-05 SetOutlineMode ( pRef->IsOutlineMode() );
+//UNUSED2008-05
+//UNUSED2008-05 for (SCTAB i=0; i<=MAXTAB; i++)
+//UNUSED2008-05 {
+//UNUSED2008-05 delete pTabData[i];
+//UNUSED2008-05 if (pRef->pTabData[i])
+//UNUSED2008-05 pTabData[i] = new ScViewDataTable( *pRef->pTabData[i] );
+//UNUSED2008-05 else
+//UNUSED2008-05 pTabData[i] = NULL;
+//UNUSED2008-05 }
+//UNUSED2008-05 pThisTab = pTabData[nTabNo];
+//UNUSED2008-05 CalcPPT();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScViewData::SetDocShell( ScDocShell* pShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 pDocShell = pShell;
+//UNUSED2008-05 pDoc = pDocShell->GetDocument();
+//UNUSED2008-05 *pOptions = pDoc->GetViewOptions();
+//UNUSED2008-05 CalcPPT();
+//UNUSED2008-05 }
+
+ScDocument* ScViewData::GetDocument() const
+{
+ if (pDoc)
+ return pDoc;
+ else if (pDocShell)
+ return pDocShell->GetDocument();
+
+ DBG_ERROR("kein Document an ViewData");
+ return NULL;
+}
+
+ScViewData::~ScViewData()
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTabData[i])
+ delete pTabData[i];
+
+ KillEditView();
+ delete pOptions;
+}
+
+void ScViewData::UpdateThis()
+{
+ do
+ {
+ pThisTab = pTabData[nTabNo];
+ if (!pThisTab)
+ {
+ if (nTabNo>0)
+ --nTabNo;
+ else
+ pThisTab = pTabData[0] = new ScViewDataTable;
+
+ // hier keine Assertion, weil sonst Paints kommen, bevor alles initialisiert ist!
+ }
+ }
+ while (!pThisTab);
+}
+
+void ScViewData::InsertTab( SCTAB nTab )
+{
+ delete pTabData[MAXTAB];
+
+ for (SCTAB i=MAXTAB; i>nTab; i--)
+ pTabData[i] = pTabData[i-1];
+
+ pTabData[nTab] = NULL; // force creating new
+ CreateTabData( nTab );
+
+ UpdateThis();
+ aMarkData.InsertTab( nTab );
+}
+
+void ScViewData::DeleteTab( SCTAB nTab )
+{
+ delete pTabData[nTab];
+
+ for (SCTAB i=nTab; i<MAXTAB; i++)
+ pTabData[i] = pTabData[i+1];
+
+ pTabData[MAXTAB] = NULL;
+
+ UpdateThis();
+ aMarkData.DeleteTab( nTab );
+}
+
+void ScViewData::CopyTab( SCTAB nSrcTab, SCTAB nDestTab )
+{
+ if (nDestTab==SC_TAB_APPEND)
+ nDestTab = pDoc->GetTableCount() - 1; // am Doc muss vorher kopiert worden sein
+
+ if (nDestTab > MAXTAB)
+ {
+ DBG_ERROR("Zuviele Tabellen");
+ return;
+ }
+
+ delete pTabData[MAXTAB];
+
+ for (SCTAB i=MAXTAB; i>nDestTab; i--)
+ pTabData[i] = pTabData[i-1];
+
+ if ( pTabData[nSrcTab] )
+ pTabData[nDestTab] = new ScViewDataTable( *pTabData[nSrcTab] );
+ else
+ pTabData[nDestTab] = NULL;
+
+ UpdateThis();
+ aMarkData.InsertTab( nDestTab );
+}
+
+void ScViewData::MoveTab( SCTAB nSrcTab, SCTAB nDestTab )
+{
+ if (nDestTab==SC_TAB_APPEND)
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ SCTAB i;
+ ScViewDataTable* pTab = pTabData[nSrcTab];
+
+ SCTAB nInsTab = nDestTab;
+ if ( nSrcTab < nDestTab )
+ {
+ --nInsTab;
+ for (i=nSrcTab; i<nDestTab; i++)
+ pTabData[i] = pTabData[i+1];
+ }
+ else
+ for (i=nSrcTab; i>nDestTab; i--)
+ pTabData[i] = pTabData[i-1];
+
+ pTabData[nDestTab] = pTab;
+
+ UpdateThis();
+ aMarkData.DeleteTab( nSrcTab );
+ aMarkData.InsertTab( nInsTab ); // ggf. angepasst
+}
+
+//UNUSED2008-05 void ScViewData::UpdateOle( ScSplitPos /* eWhich */ )
+//UNUSED2008-05 {
+//UNUSED2008-05 GetDocShell()->UpdateOle(this);
+//UNUSED2008-05 }
+
+void ScViewData::SetViewShell( ScTabViewShell* pViewSh )
+{
+ if (pViewSh)
+ {
+ pViewShell = pViewSh;
+ pView = pViewSh;
+ }
+ else
+ {
+ pViewShell = NULL;
+ pView = NULL;
+ }
+}
+void ScViewData::CreateTabData( std::vector< SCTAB >& rvTabs )
+{
+ std::vector< SCTAB >::iterator it_end = rvTabs.end();
+ for ( std::vector< SCTAB >::iterator it = rvTabs.begin(); it != it_end; ++it )
+ if ( !pTabData[*it] )
+ CreateTabData( *it );
+}
+
+void ScViewData::SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs )
+{
+ BOOL bAll = ( tabs.size() == 0 );
+
+ if ( !bAll ) // create associated table data
+ CreateTabData( tabs );
+
+ if ( bAll )
+ {
+ for ( SCTAB i = 0; i <= MAXTAB; ++i )
+ {
+ if ( pTabData[i] )
+ pTabData[i]->eZoomType = eNew;
+ }
+ eDefZoomType = eNew;
+ }
+ else
+ {
+ std::vector< SCTAB >::iterator it_end = tabs.end();
+ std::vector< SCTAB >::iterator it = tabs.begin();
+ for ( ; it != it_end; ++it )
+ {
+ SCTAB i = *it;
+ if ( pTabData[i] )
+ pTabData[i]->eZoomType = eNew;
+ }
+ }
+}
+
+void ScViewData::SetZoomType( SvxZoomType eNew, BOOL bAll )
+{
+ std::vector< SCTAB > vTabs; // Empty for all tabs
+ if ( !bAll ) // get selected tabs
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ if ( aMarkData.GetTableSelect(i) )
+ vTabs.push_back( i );
+ }
+ }
+ SetZoomType( eNew, vTabs );
+}
+
+void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs )
+{
+ BOOL bAll = ( tabs.size() == 0 );
+ if ( !bAll ) // create associated table data
+ CreateTabData( tabs );
+ Fraction aFrac20( 1,5 );
+ Fraction aFrac400( 4,1 );
+
+ Fraction aValidX = rNewX;
+ if (aValidX<aFrac20)
+ aValidX = aFrac20;
+ if (aValidX>aFrac400)
+ aValidX = aFrac400;
+
+ Fraction aValidY = rNewY;
+ if (aValidY<aFrac20)
+ aValidY = aFrac20;
+ if (aValidY>aFrac400)
+ aValidY = aFrac400;
+
+ if ( bAll )
+ {
+ for ( SCTAB i = 0; i <= MAXTAB; ++i )
+ {
+ if ( pTabData[i] )
+ {
+ if ( bPagebreak )
+ {
+ pTabData[i]->aPageZoomX = aValidX;
+ pTabData[i]->aPageZoomY = aValidY;
+ }
+ else
+ {
+ pTabData[i]->aZoomX = aValidX;
+ pTabData[i]->aZoomY = aValidY;
+ }
+ }
+ }
+ if ( bPagebreak )
+ {
+ aDefPageZoomX = aValidX;
+ aDefPageZoomY = aValidY;
+ }
+ else
+ {
+ aDefZoomX = aValidX;
+ aDefZoomY = aValidY;
+ }
+ }
+ else
+ {
+ std::vector< SCTAB >::iterator it_end = tabs.end();
+ std::vector< SCTAB >::iterator it = tabs.begin();
+ for ( ; it != it_end; ++it )
+ {
+ SCTAB i = *it;
+ if ( pTabData[i] )
+ {
+ if ( bPagebreak )
+ {
+ pTabData[i]->aPageZoomX = aValidX;
+ pTabData[i]->aPageZoomY = aValidY;
+ }
+ else
+ {
+ pTabData[i]->aZoomX = aValidX;
+ pTabData[i]->aZoomY = aValidY;
+ }
+ }
+ }
+ }
+ RefreshZoom();
+}
+
+void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, BOOL bAll )
+{
+ std::vector< SCTAB > vTabs;
+ if ( !bAll ) // get selected tabs
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ if ( aMarkData.GetTableSelect(i) )
+ vTabs.push_back( i );
+ }
+ }
+ SetZoom( rNewX, rNewY, vTabs );
+}
+
+void ScViewData::RefreshZoom()
+{
+ // recalculate zoom-dependent values (only for current sheet)
+
+ CalcPPT();
+ RecalcPixPos();
+ aScenButSize = Size(0,0);
+ aLogicMode.SetScaleX( GetZoomX() );
+ aLogicMode.SetScaleY( GetZoomY() );
+}
+
+void ScViewData::SetPagebreakMode( BOOL bSet )
+{
+ bPagebreak = bSet;
+
+ RefreshZoom();
+}
+
+
+ScMarkType ScViewData::GetSimpleArea( ScRange & rRange, ScMarkData & rNewMark ) const
+{
+ ScMarkType eMarkType = SC_MARK_NONE;
+
+ if ( rNewMark.IsMarked() || rNewMark.IsMultiMarked() )
+ {
+ if ( rNewMark.IsMultiMarked() )
+ rNewMark.MarkToSimple();
+
+ if ( rNewMark.IsMarked() && !rNewMark.IsMultiMarked() )
+ {
+ rNewMark.GetMarkArea( rRange );
+ if (ScViewUtil::HasFiltered( rRange, GetDocument()))
+ eMarkType = SC_MARK_SIMPLE_FILTERED;
+ else
+ eMarkType = SC_MARK_SIMPLE;
+ }
+ else
+ eMarkType = SC_MARK_MULTI;
+ }
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ {
+ if (eMarkType == SC_MARK_NONE)
+ eMarkType = SC_MARK_SIMPLE;
+ rRange = ScRange( GetCurX(), GetCurY(), GetTabNo() );
+ }
+ return eMarkType;
+}
+
+
+ScMarkType ScViewData::GetSimpleArea( SCCOL& rStartCol, SCROW& rStartRow, SCTAB& rStartTab,
+ SCCOL& rEndCol, SCROW& rEndRow, SCTAB& rEndTab ) const
+{
+ // parameter bMergeMark is no longer needed: The view's selection is never modified
+ // (a local copy is used), and a multi selection that adds to a single range can always
+ // be treated like a single selection (#108266# - GetSimpleArea isn't used in selection
+ // handling itself)
+
+ ScRange aRange;
+ ScMarkData aNewMark( aMarkData ); // use a local copy for MarkToSimple
+ ScMarkType eMarkType = GetSimpleArea( aRange, aNewMark);
+ aRange.GetVars( rStartCol, rStartRow, rStartTab, rEndCol, rEndRow, rEndTab);
+ return eMarkType;
+}
+
+ScMarkType ScViewData::GetSimpleArea( ScRange& rRange ) const
+{
+ // parameter bMergeMark is no longer needed, see above
+
+ ScMarkData aNewMark( aMarkData ); // use a local copy for MarkToSimple
+ return GetSimpleArea( rRange, aNewMark);
+}
+
+void ScViewData::GetMultiArea( ScRangeListRef& rRange ) const
+{
+ // parameter bMergeMark is no longer needed, see GetSimpleArea
+
+ ScMarkData aNewMark( aMarkData ); // use a local copy for MarkToSimple
+
+ BOOL bMulti = aNewMark.IsMultiMarked();
+ if (bMulti)
+ {
+ aNewMark.MarkToSimple();
+ bMulti = aNewMark.IsMultiMarked();
+ }
+ if (bMulti)
+ {
+ rRange = new ScRangeList;
+ aNewMark.FillRangeListWithMarks( rRange, FALSE );
+ }
+ else
+ {
+ ScRange aSimple;
+ GetSimpleArea(aSimple);
+ rRange = new ScRangeList;
+ rRange->Append(aSimple);
+ }
+}
+
+BOOL ScViewData::SimpleColMarked()
+{
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ if (nStartRow==0 && nEndRow==MAXROW)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL ScViewData::SimpleRowMarked()
+{
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ if (nStartCol==0 && nEndCol==MAXCOL)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL ScViewData::IsMultiMarked()
+{
+ // Test for "real" multi selection, calling MarkToSimple on a local copy,
+ // and taking filtered in simple area marks into account.
+
+ ScRange aDummy;
+ ScMarkType eType = GetSimpleArea(aDummy);
+ return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE;
+}
+
+void ScViewData::SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ nFillMode = SC_FILL_FILL;
+ nFillStartX = nStartCol;
+ nFillStartY = nStartRow;
+ nFillEndX = nEndCol;
+ nFillEndY = nEndRow;
+}
+
+void ScViewData::SetDragMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ BYTE nMode )
+{
+ nFillMode = nMode;
+ nFillStartX = nStartCol;
+ nFillStartY = nStartRow;
+ nFillEndX = nEndCol;
+ nFillEndY = nEndRow;
+}
+
+void ScViewData::ResetFillMode()
+{
+ nFillMode = SC_FILL_NONE;
+}
+
+void ScViewData::GetFillData( SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow )
+{
+ rStartCol = nFillStartX;
+ rStartRow = nFillStartY;
+ rEndCol = nFillEndX;
+ rEndRow = nFillEndY;
+}
+
+SCCOL ScViewData::GetOldCurX() const
+{
+ if (pThisTab->bOldCurValid)
+ return pThisTab->nOldCurX;
+ else
+ return pThisTab->nCurX;
+}
+
+SCROW ScViewData::GetOldCurY() const
+{
+ if (pThisTab->bOldCurValid)
+ return pThisTab->nOldCurY;
+ else
+ return pThisTab->nCurY;
+}
+
+void ScViewData::SetOldCursor( SCCOL nNewX, SCROW nNewY )
+{
+ pThisTab->nOldCurX = nNewX;
+ pThisTab->nOldCurY = nNewY;
+ pThisTab->bOldCurValid = TRUE;
+}
+
+void ScViewData::ResetOldCursor()
+{
+ pThisTab->bOldCurValid = FALSE;
+}
+
+Rectangle ScViewData::GetEditArea( ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY,
+ Window* pWin, const ScPatternAttr* pPattern,
+ BOOL bForceToTop )
+{
+ return ScEditUtil( pDoc, nPosX, nPosY, nTabNo, GetScrPos(nPosX,nPosY,eWhich,TRUE),
+ pWin, nPPTX, nPPTY, GetZoomX(), GetZoomY() ).
+ GetEditArea( pPattern, bForceToTop );
+}
+
+void ScViewData::SetEditEngine( ScSplitPos eWhich,
+ ScEditEngineDefaulter* pNewEngine,
+ Window* pWin, SCCOL nNewX, SCROW nNewY )
+{
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
+ ScHSplitPos eHWhich = WhichH(eWhich);
+
+ BOOL bWasThere = FALSE;
+ if (pEditView[eWhich])
+ {
+ // Wenn die View schon da ist, nichts aufrufen, was die Cursorposition aendert
+
+ if (bEditActive[eWhich])
+ bWasThere = TRUE;
+ else
+ pEditView[eWhich]->SetEditEngine(pNewEngine);
+
+ if (pEditView[eWhich]->GetWindow() != pWin)
+ {
+ pEditView[eWhich]->SetWindow(pWin);
+ DBG_ERROR("EditView Window geaendert");
+ }
+ }
+ else
+ {
+ pEditView[eWhich] = new EditView( pNewEngine, pWin );
+ }
+
+ // bei IdleFormat wird manchmal ein Cursor gemalt, wenn die View schon weg ist (23576)
+
+ ULONG nEC = pNewEngine->GetControlWord();
+ pNewEngine->SetControlWord(nEC & ~EE_CNTRL_DOIDLEFORMAT);
+
+ ULONG nVC = pEditView[eWhich]->GetControlWord();
+ pEditView[eWhich]->SetControlWord(nVC & ~EV_CNTRL_AUTOSCROLL);
+
+ bEditActive[eWhich] = TRUE;
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nNewX, nNewY, nTabNo );
+ SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
+
+ BOOL bBreak = ( eJust == SVX_HOR_JUSTIFY_BLOCK ) ||
+ ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
+
+ BOOL bAsianVertical = pNewEngine->IsVertical(); // set by InputHandler
+
+ Rectangle aPixRect = ScEditUtil( pDoc, nNewX,nNewY,nTabNo, GetScrPos(nNewX,nNewY,eWhich),
+ pWin, nPPTX,nPPTY,GetZoomX(),GetZoomY() ).
+ GetEditArea( pPattern, TRUE );
+
+ // when right-aligned, leave space for the cursor
+ // in vertical mode, editing is always right-aligned
+ if ( nEditAdjust == SVX_ADJUST_RIGHT || bAsianVertical )
+ aPixRect.Right() += 1;
+
+ Rectangle aOutputArea = pWin->PixelToLogic( aPixRect, GetLogicMode() );
+ pEditView[eWhich]->SetOutputArea( aOutputArea );
+
+ if ( bActive && eWhich == GetActivePart() )
+ {
+ // keep the part that has the active edit view available after
+ // switching sheets or reference input on a different part
+ eEditActivePart = eWhich;
+
+ // modify members nEditCol etc. only if also extending for needed area
+ nEditCol = nNewX;
+ nEditRow = nNewY;
+ const ScMergeAttr* pMergeAttr = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ nEditEndCol = nEditCol;
+ if (pMergeAttr->GetColMerge() > 1)
+ nEditEndCol += pMergeAttr->GetColMerge() - 1;
+ nEditEndRow = nEditRow;
+ if (pMergeAttr->GetRowMerge() > 1)
+ nEditEndRow += pMergeAttr->GetRowMerge() - 1;
+ nEditStartCol = nEditCol;
+
+ // For growing use only the alignment value from the attribute, numbers
+ // (existing or started) with default aligment extend to the right.
+ BOOL bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
+ BOOL bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT ); // visual left
+ BOOL bGrowBackwards = bGrowToLeft; // logical left
+ if ( bLayoutRTL )
+ bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
+ if ( bAsianVertical )
+ bGrowCentered = bGrowToLeft = bGrowBackwards = FALSE; // keep old behavior for asian mode
+
+ long nSizeXPix;
+ if (bBreak && !bAsianVertical)
+ nSizeXPix = aPixRect.GetWidth(); // Papersize -> kein H-Scrolling
+ else
+ {
+ DBG_ASSERT(pView,"keine View fuer EditView");
+
+ if ( bGrowCentered )
+ {
+ // growing into both directions until one edge is reached
+ //! should be limited to whole cells in both directions
+ long nLeft = aPixRect.Left();
+ long nRight = pView->GetGridWidth(eHWhich) - aPixRect.Right();
+ nSizeXPix = aPixRect.GetWidth() + 2 * Min( nLeft, nRight );
+ }
+ else if ( bGrowToLeft )
+ nSizeXPix = aPixRect.Right(); // space that's available in the window when growing to the left
+ else
+ nSizeXPix = pView->GetGridWidth(eHWhich) - aPixRect.Left();
+
+ if ( nSizeXPix <= 0 )
+ nSizeXPix = aPixRect.GetWidth(); // editing outside to the right of the window -> keep cell width
+ }
+ DBG_ASSERT(pView,"keine View fuer EditView");
+ long nSizeYPix = pView->GetGridHeight(WhichV(eWhich)) - aPixRect.Top();
+ if ( nSizeYPix <= 0 )
+ nSizeYPix = aPixRect.GetHeight(); // editing outside below the window -> keep cell height
+
+ Size aPaperSize = pView->GetActiveWin()->PixelToLogic( Size( nSizeXPix, nSizeYPix ), GetLogicMode() );
+ if ( bBreak && !bAsianVertical && SC_MOD()->GetInputOptions().GetTextWysiwyg() )
+ {
+ // #95593# if text is formatted for printer, use the exact same paper width
+ // (and same line breaks) as for output.
+
+ Fraction aFract(1,1);
+ Rectangle aUtilRect = ScEditUtil( pDoc,nNewX,nNewY,nTabNo, Point(0,0), pWin,
+ HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, FALSE );
+ aPaperSize.Width() = aUtilRect.GetWidth();
+ }
+ pNewEngine->SetPaperSize( aPaperSize );
+
+ // sichtbarer Ausschnitt
+ Size aPaper = pNewEngine->GetPaperSize();
+ Rectangle aVis = pEditView[eWhich]->GetVisArea();
+ long nDiff = aVis.Right() - aVis.Left();
+ if ( nEditAdjust == SVX_ADJUST_RIGHT )
+ {
+ aVis.Right() = aPaper.Width() - 1;
+ bMoveArea = !bLayoutRTL;
+ }
+ else if ( nEditAdjust == SVX_ADJUST_CENTER )
+ {
+ aVis.Right() = ( aPaper.Width() - 1 + nDiff ) / 2;
+ bMoveArea = TRUE; // always
+ }
+ else
+ {
+ aVis.Right() = nDiff;
+ bMoveArea = bLayoutRTL;
+ }
+ aVis.Left() = aVis.Right() - nDiff;
+ // --> OD 2005-12-22 #i49561#
+ // Important note:
+ // The set offset of the visible area of the EditView for centered and
+ // right alignment in horizontal layout is consider by instances of
+ // class <ScEditObjectViewForwarder> in its methods <LogicToPixel(..)>
+ // and <PixelToLogic(..)>. This is needed for the correct visibility
+ // of paragraphs in edit mode at the accessibility API.
+ // <--
+ pEditView[eWhich]->SetVisArea(aVis);
+ //
+
+ // UpdateMode has been disabled in ScInputHandler::StartTable
+ // must be enabled before EditGrowY (GetTextHeight)
+ pNewEngine->SetUpdateMode( TRUE );
+
+ pNewEngine->SetStatusEventHdl( LINK( this, ScViewData, EditEngineHdl ) );
+
+ EditGrowY( TRUE ); // adjust to existing text content
+ EditGrowX();
+
+ Point aDocPos = pEditView[eWhich]->GetWindowPosTopLeft(0);
+ if (aDocPos.Y() < aOutputArea.Top())
+ pEditView[eWhich]->Scroll( 0, aOutputArea.Top() - aDocPos.Y() );
+
+ //! Status (Event) zuruecksetzen
+ }
+
+ // hier muss bEditActive schon gesetzt sein
+ // (wegen Map-Mode bei Paint)
+ if (!bWasThere)
+ pNewEngine->InsertView(pEditView[eWhich]);
+
+ // Hintergrundfarbe der Zelle
+ Color aBackCol = ((const SvxBrushItem&)pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
+
+ ScModule* pScMod = SC_MOD();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
+ if ( aBackCol.GetTransparency() > 0 ||
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+ }
+ pEditView[eWhich]->SetBackgroundColor( aBackCol );
+
+ pEditView[eWhich]->Invalidate(); // noetig ??
+ // noetig, wenn Position geaendert
+}
+
+IMPL_LINK_INLINE_START( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
+{
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
+
+IMPL_LINK( ScViewData, EditEngineHdl, EditStatus *, pStatus )
+{
+ ULONG nStatus = pStatus->GetStatusWord();
+ if (nStatus & (EE_STAT_HSCROLL | EE_STAT_TEXTHEIGHTCHANGED | EE_STAT_TEXTWIDTHCHANGED | EE_STAT_CURSOROUT))
+ {
+ EditGrowY();
+ EditGrowX();
+
+ if (nStatus & EE_STAT_CURSOROUT)
+ {
+ ScSplitPos eWhich = GetActivePart();
+ if (pEditView[eWhich])
+ pEditView[eWhich]->ShowCursor(FALSE);
+ }
+ }
+ return 0;
+}
+
+void ScViewData::EditGrowX()
+{
+ ScDocument* pLocalDoc = GetDocument();
+
+ ScSplitPos eWhich = GetActivePart();
+ ScHSplitPos eHWhich = WhichH(eWhich);
+ EditView* pCurView = pEditView[eWhich];
+
+ if ( !pCurView || !bEditActive[eWhich])
+ return;
+
+ BOOL bLayoutRTL = pLocalDoc->IsLayoutRTL( nTabNo );
+
+ ScEditEngineDefaulter* pEngine =
+ (ScEditEngineDefaulter*) pCurView->GetEditEngine();
+ Window* pWin = pCurView->GetWindow();
+
+ SCCOL nLeft = GetPosX(eHWhich);
+ SCCOL nRight = nLeft + VisibleCellsX(eHWhich);
+
+ Size aSize = pEngine->GetPaperSize();
+ Rectangle aArea = pCurView->GetOutputArea();
+ long nOldRight = aArea.Right();
+
+ // Margin ist schon bei der urspruenglichen Breite beruecksichtigt
+ long nTextWidth = pEngine->CalcTextWidth();
+
+ BOOL bChanged = FALSE;
+ BOOL bAsianVertical = pEngine->IsVertical();
+
+ // get bGrow... variables the same way as in SetEditEngine
+ const ScPatternAttr* pPattern = pLocalDoc->GetPattern( nEditCol, nEditRow, nTabNo );
+ SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
+ BOOL bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
+ BOOL bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT ); // visual left
+ BOOL bGrowBackwards = bGrowToLeft; // logical left
+ if ( bLayoutRTL )
+ bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
+ if ( bAsianVertical )
+ bGrowCentered = bGrowToLeft = bGrowBackwards = FALSE; // keep old behavior for asian mode
+
+ BOOL bUnevenGrow = FALSE;
+ if ( bGrowCentered )
+ {
+ while (aArea.GetWidth() + 0 < nTextWidth && ( nEditStartCol > nLeft || nEditEndCol < nRight ) )
+ {
+ long nLogicLeft = 0;
+ if ( nEditStartCol > nLeft )
+ {
+ --nEditStartCol;
+ long nLeftPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
+ nLogicLeft = pWin->PixelToLogic(Size(nLeftPix,0)).Width();
+ }
+ long nLogicRight = 0;
+ if ( nEditEndCol < nRight )
+ {
+ ++nEditEndCol;
+ long nRightPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
+ nLogicRight = pWin->PixelToLogic(Size(nRightPix,0)).Width();
+ }
+
+ aArea.Left() -= bLayoutRTL ? nLogicRight : nLogicLeft;
+ aArea.Right() += bLayoutRTL ? nLogicLeft : nLogicRight;
+
+ if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
+ {
+ long nCenter = ( aArea.Left() + aArea.Right() ) / 2;
+ long nHalf = aSize.Width() / 2;
+ aArea.Left() = nCenter - nHalf + 1;
+ aArea.Right() = nCenter + aSize.Width() - nHalf - 1;
+ }
+
+ bChanged = TRUE;
+ if ( nLogicLeft != nLogicRight )
+ bUnevenGrow = TRUE;
+ }
+ }
+ else if ( bGrowBackwards )
+ {
+ while (aArea.GetWidth() + 0 < nTextWidth && nEditStartCol > nLeft)
+ {
+ --nEditStartCol;
+ long nPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
+ long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
+ if ( !bLayoutRTL )
+ aArea.Left() -= nLogicWidth;
+ else
+ aArea.Right() += nLogicWidth;
+
+ if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
+ {
+ if ( !bLayoutRTL )
+ aArea.Left() = aArea.Right() - aSize.Width() + 1;
+ else
+ aArea.Right() = aArea.Left() + aSize.Width() - 1;
+ }
+
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ while (aArea.GetWidth() + 0 < nTextWidth && nEditEndCol < nRight)
+ {
+ ++nEditEndCol;
+ long nPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
+ long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
+ if ( bLayoutRTL )
+ aArea.Left() -= nLogicWidth;
+ else
+ aArea.Right() += nLogicWidth;
+
+ if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
+ {
+ if ( bLayoutRTL )
+ aArea.Left() = aArea.Right() - aSize.Width() + 1;
+ else
+ aArea.Right() = aArea.Left() + aSize.Width() - 1;
+ }
+
+ bChanged = TRUE;
+ }
+ }
+
+ if (bChanged)
+ {
+ if ( bMoveArea || bGrowCentered || bGrowBackwards || bLayoutRTL )
+ {
+ Rectangle aVis = pCurView->GetVisArea();
+
+ if ( bGrowCentered )
+ {
+ // switch to center-aligned (undo?) and reset VisArea to center
+
+ pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+
+ long nCenter = aSize.Width() / 2;
+ long nVisSize = aArea.GetWidth();
+ aVis.Left() = nCenter - nVisSize / 2;
+ aVis.Right() = aVis.Left() + nVisSize - 1;
+ }
+ else if ( bGrowToLeft )
+ {
+ // switch to right-aligned (undo?) and reset VisArea to the right
+
+ pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+
+ aVis.Right() = aSize.Width() - 1;
+ aVis.Left() = aSize.Width() - aArea.GetWidth(); // with the new, increased area
+ }
+ else
+ {
+ // switch to left-aligned (undo?) and reset VisArea to the left
+
+ pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+
+ long nMove = aVis.Left();
+ aVis.Left() = 0;
+ aVis.Right() -= nMove;
+ }
+ pCurView->SetVisArea( aVis );
+ bMoveArea = FALSE;
+ }
+
+ pCurView->SetOutputArea(aArea);
+
+ // In vertical mode, the whole text is moved to the next cell (right-aligned),
+ // so everything must be repainted. Otherwise, paint only the new area.
+ // If growing in centered alignment, if the cells left and right have different sizes,
+ // the whole text will move, and may not even obscure all of the original display.
+ if ( bUnevenGrow )
+ {
+ aArea.Left() = pWin->PixelToLogic( Point(0,0) ).X();
+ aArea.Right() = pWin->PixelToLogic( aScrSize ).Width();
+ }
+ else if ( !bAsianVertical && !bGrowToLeft && !bGrowCentered )
+ aArea.Left() = nOldRight;
+ pWin->Invalidate(aArea);
+ }
+}
+
+void ScViewData::EditGrowY( BOOL bInitial )
+{
+ ScSplitPos eWhich = GetActivePart();
+ ScVSplitPos eVWhich = WhichV(eWhich);
+ EditView* pCurView = pEditView[eWhich];
+
+ if ( !pCurView || !bEditActive[eWhich])
+ return;
+
+ ULONG nControl = pEditView[eWhich]->GetControlWord();
+ if ( nControl & EV_CNTRL_AUTOSCROLL )
+ {
+ // if end of screen had already been reached and scrolling enabled,
+ // don't further try to grow the edit area
+
+ pCurView->SetOutputArea( pCurView->GetOutputArea() ); // re-align to pixels
+ return;
+ }
+
+ EditEngine* pEngine = pCurView->GetEditEngine();
+ Window* pWin = pCurView->GetWindow();
+
+ SCROW nBottom = GetPosY(eVWhich) + VisibleCellsY(eVWhich);
+
+ Size aSize = pEngine->GetPaperSize();
+ Rectangle aArea = pCurView->GetOutputArea();
+ long nOldBottom = aArea.Bottom();
+ long nTextHeight = pEngine->GetTextHeight();
+
+ // #106635# When editing a formula in a cell with optimal height, allow a larger portion
+ // to be clipped before extending to following rows, to avoid obscuring cells for
+ // reference input (next row is likely to be useful in formulas).
+ long nAllowedExtra = SC_GROWY_SMALL_EXTRA;
+ if ( nEditEndRow == nEditRow && !( pDoc->GetRowFlags( nEditRow, nTabNo ) & CR_MANUALSIZE ) &&
+ pEngine->GetParagraphCount() <= 1 )
+ {
+ // If the (only) paragraph starts with a '=', it's a formula.
+ // If this is the initial call and the text is empty, allow the larger value, too,
+ // because this occurs in the normal progress of editing a formula.
+ // Subsequent calls with empty text might involve changed attributes (including
+ // font height), so they are treated like normal text.
+ String aText = pEngine->GetText( (USHORT) 0 );
+ if ( ( aText.Len() == 0 && bInitial ) || aText.GetChar(0) == (sal_Unicode)'=' )
+ nAllowedExtra = SC_GROWY_BIG_EXTRA;
+ }
+
+ BOOL bChanged = FALSE;
+ BOOL bMaxReached = FALSE;
+ while (aArea.GetHeight() + nAllowedExtra < nTextHeight && nEditEndRow < nBottom && !bMaxReached)
+ {
+ ++nEditEndRow;
+ ScDocument* pLocalDoc = GetDocument();
+ long nPix = ToPixel( pLocalDoc->GetRowHeight( nEditEndRow, nTabNo ), nPPTY );
+ aArea.Bottom() += pWin->PixelToLogic(Size(0,nPix)).Height();
+
+ if ( aArea.Bottom() > aArea.Top() + aSize.Height() - 1 )
+ {
+ aArea.Bottom() = aArea.Top() + aSize.Height() - 1;
+ bMaxReached = TRUE; // don't occupy more cells beyond paper size
+ }
+
+ bChanged = TRUE;
+ nAllowedExtra = SC_GROWY_SMALL_EXTRA; // larger value is only for first row
+ }
+
+ if (bChanged)
+ {
+ pCurView->SetOutputArea(aArea);
+
+ if (nEditEndRow >= nBottom || bMaxReached)
+ {
+ if ((nControl & EV_CNTRL_AUTOSCROLL) == 0)
+ pCurView->SetControlWord( nControl | EV_CNTRL_AUTOSCROLL );
+ }
+
+ aArea.Top() = nOldBottom;
+ pWin->Invalidate(aArea);
+ }
+}
+
+void ScViewData::ResetEditView()
+{
+ EditEngine* pEngine = NULL;
+ for (USHORT i=0; i<4; i++)
+ if (pEditView[i])
+ {
+ if (bEditActive[i])
+ {
+ pEngine = pEditView[i]->GetEditEngine();
+ pEngine->RemoveView(pEditView[i]);
+ pEditView[i]->SetOutputArea( Rectangle() );
+ }
+ bEditActive[i] = FALSE;
+ }
+
+ if (pEngine)
+ pEngine->SetStatusEventHdl( LINK( this, ScViewData, EmptyEditHdl ) );
+}
+
+void ScViewData::KillEditView()
+{
+ for (USHORT i=0; i<4; i++)
+ if (pEditView[i])
+ {
+ if (bEditActive[i])
+ pEditView[i]->GetEditEngine()->RemoveView(pEditView[i]);
+ delete pEditView[i];
+ pEditView[i] = NULL;
+ }
+}
+
+void ScViewData::GetEditView( ScSplitPos eWhich, EditView*& rViewPtr, SCCOL& rCol, SCROW& rRow )
+{
+ rViewPtr = pEditView[eWhich];
+ rCol = nEditCol;
+ rRow = nEditRow;
+}
+
+void ScViewData::CreateTabData( SCTAB nNewTab )
+{
+ if (!pTabData[nNewTab])
+ {
+ pTabData[nNewTab] = new ScViewDataTable;
+
+ pTabData[nNewTab]->eZoomType = eDefZoomType;
+ pTabData[nNewTab]->aZoomX = aDefZoomX;
+ pTabData[nNewTab]->aZoomY = aDefZoomY;
+ pTabData[nNewTab]->aPageZoomX = aDefPageZoomX;
+ pTabData[nNewTab]->aPageZoomY = aDefPageZoomY;
+ }
+}
+
+void ScViewData::CreateSelectedTabData()
+{
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( aMarkData.GetTableSelect(i) && !pTabData[i] )
+ CreateTabData( i );
+}
+
+void ScViewData::SetTabNo( SCTAB nNewTab )
+{
+ if (!ValidTab(nNewTab))
+ {
+ DBG_ERROR("falsche Tabellennummer");
+ return;
+ }
+
+ nTabNo = nNewTab;
+ CreateTabData(nTabNo);
+ pThisTab = pTabData[nTabNo];
+
+ CalcPPT(); // for common column width correction
+ RecalcPixPos(); //! nicht immer noetig!
+}
+
+void ScViewData::SetActivePart( ScSplitPos eNewActive )
+{
+ pThisTab->eWhichActive = eNewActive;
+}
+
+Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const
+{
+ DBG_ASSERT( eWhich==SC_SPLIT_LEFT || eWhich==SC_SPLIT_RIGHT, "Falsche Position" );
+ ScSplitPos ePos = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+ return GetScrPos( nWhereX, nWhereY, ePos );
+}
+
+Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const
+{
+ DBG_ASSERT( eWhich==SC_SPLIT_TOP || eWhich==SC_SPLIT_BOTTOM, "Falsche Position" );
+ ScSplitPos ePos = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+ return GetScrPos( nWhereX, nWhereY, ePos );
+}
+
+Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
+ BOOL bAllowNeg ) const
+{
+ ScHSplitPos eWhichX = SC_SPLIT_LEFT;
+ ScVSplitPos eWhichY = SC_SPLIT_BOTTOM;
+ switch( eWhich )
+ {
+ case SC_SPLIT_TOPLEFT:
+ eWhichX = SC_SPLIT_LEFT;
+ eWhichY = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_TOPRIGHT:
+ eWhichX = SC_SPLIT_RIGHT;
+ eWhichY = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_BOTTOMLEFT:
+ eWhichX = SC_SPLIT_LEFT;
+ eWhichY = SC_SPLIT_BOTTOM;
+ break;
+ case SC_SPLIT_BOTTOMRIGHT:
+ eWhichX = SC_SPLIT_RIGHT;
+ eWhichY = SC_SPLIT_BOTTOM;
+ break;
+ }
+
+ if (pView)
+ {
+ ((ScViewData*)this)->aScrSize.Width() = pView->GetGridWidth(eWhichX);
+ ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
+ }
+
+ USHORT nTSize;
+
+ SCCOL nPosX = GetPosX(eWhichX);
+ SCCOL nX;
+
+ long nScrPosX=0;
+ if (nWhereX >= nPosX)
+ for (nX=nPosX; nX<nWhereX && (bAllowNeg || nScrPosX<=aScrSize.Width()); nX++)
+ {
+ if ( nX > MAXCOL )
+ nScrPosX = 65535;
+ else
+ {
+ nTSize = pDoc->GetColWidth( nX, nTabNo );
+ if (nTSize)
+ {
+ long nSizeXPix = ToPixel( nTSize, nPPTX );
+ nScrPosX += nSizeXPix;
+ }
+ }
+ }
+ else if (bAllowNeg)
+ for (nX=nPosX; nX>nWhereX;)
+ {
+ --nX;
+ nTSize = pDoc->GetColWidth( nX, nTabNo );
+ if (nTSize)
+ {
+ long nSizeXPix = ToPixel( nTSize, nPPTX );
+ nScrPosX -= nSizeXPix;
+ }
+ }
+
+ SCROW nPosY = GetPosY(eWhichY);
+ SCROW nY;
+
+ long nScrPosY=0;
+ if (nWhereY >= nPosY)
+ for (nY=nPosY; nY<nWhereY && (bAllowNeg || nScrPosY<=aScrSize.Height()); nY++)
+ {
+ if ( nY > MAXROW )
+ nScrPosY = 65535;
+ else
+ {
+ nTSize = pDoc->GetRowHeight( nY, nTabNo );
+ if (nTSize)
+ {
+ long nSizeYPix = ToPixel( nTSize, nPPTY );
+ nScrPosY += nSizeYPix;
+ }
+ else if ( nY < MAXROW )
+ {
+ // skip multiple hidden rows (forward only for now)
+ SCROW nNext = pDoc->FirstVisibleRow(nY + 1, MAXROW, nTabNo);
+ if ( nNext > MAXROW )
+ nY = MAXROW;
+ else
+ nY = nNext - 1; // +=nDir advances to next visible row
+ }
+ }
+ }
+ else if (bAllowNeg)
+ for (nY=nPosY; nY>nWhereY;)
+ {
+ --nY;
+ nTSize = pDoc->GetRowHeight( nY, nTabNo );
+ if (nTSize)
+ {
+ long nSizeYPix = ToPixel( nTSize, nPPTY );
+ nScrPosY -= nSizeYPix;
+ }
+ }
+
+ if ( pDoc->IsLayoutRTL( nTabNo ) )
+ {
+ // mirror horizontal position
+ nScrPosX = aScrSize.Width() - 1 - nScrPosX;
+ }
+
+ if (nScrPosX > 32767) nScrPosX=32767;
+ if (nScrPosY > 32767) nScrPosY=32767;
+ return Point( nScrPosX, nScrPosY );
+}
+
+//
+// Anzahl Zellen auf einem Bildschirm
+//
+
+SCCOL ScViewData::CellsAtX( SCsCOL nPosX, SCsCOL nDir, ScHSplitPos eWhichX, USHORT nScrSizeX ) const
+{
+ DBG_ASSERT( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
+
+ if (pView)
+ ((ScViewData*)this)->aScrSize.Width() = pView->GetGridWidth(eWhichX);
+
+ SCsCOL nX;
+ USHORT nScrPosX = 0;
+ if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = (USHORT) aScrSize.Width();
+
+ if (nDir==1)
+ nX = nPosX; // vorwaerts
+ else
+ nX = nPosX-1; // rueckwaerts
+
+ BOOL bOut = FALSE;
+ for ( ; nScrPosX<=nScrSizeX && !bOut; nX = sal::static_int_cast<SCsCOL>(nX + nDir) )
+ {
+ SCsCOL nColNo = nX;
+ if ( nColNo < 0 || nColNo > MAXCOL )
+ bOut = TRUE;
+ else
+ {
+ USHORT nTSize = pDoc->GetColWidth( nColNo, nTabNo );
+ if (nTSize)
+ {
+ long nSizeXPix = ToPixel( nTSize, nPPTX );
+ nScrPosX = sal::static_int_cast<USHORT>( nScrPosX + (USHORT) nSizeXPix );
+ }
+ }
+ }
+
+ if (nDir==1)
+ nX = sal::static_int_cast<SCsCOL>( nX - nPosX );
+ else
+ nX = (nPosX-1)-nX;
+
+ if (nX>0) --nX;
+ return nX;
+}
+
+SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHORT nScrSizeY ) const
+{
+ DBG_ASSERT( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
+
+ if (pView)
+ ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
+
+ if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = (USHORT) aScrSize.Height();
+
+ SCROW nY;
+
+ if (nDir==1)
+ {
+ // forward
+ nY = nPosY;
+ long nScrPosY = 0;
+ AddPixelsWhile( nScrPosY, nScrSizeY, nY, MAXROW, nPPTY, pDoc, nTabNo);
+ // Original loop ended on last evaluated +1 or if that was MAXROW even
+ // on MAXROW+2.
+ nY += (nY == MAXROW ? 2 : 1);
+ nY -= nPosY;
+ }
+ else
+ {
+ // backward
+ nY = nPosY-1;
+ long nScrPosY = 0;
+ AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo);
+ // Original loop ended on last evaluated -1 or if that was 0 even on
+ // -2.
+ nY -= (nY == 0 ? 2 : 1);
+ nY = (nPosY-1)-nY;
+ }
+
+ if (nY>0) --nY;
+ return nY;
+}
+
+SCCOL ScViewData::VisibleCellsX( ScHSplitPos eWhichX ) const
+{
+ return CellsAtX( GetPosX( eWhichX ), 1, eWhichX, SC_SIZE_NONE );
+}
+
+SCROW ScViewData::VisibleCellsY( ScVSplitPos eWhichY ) const
+{
+ return CellsAtY( GetPosY( eWhichY ), 1, eWhichY, SC_SIZE_NONE );
+}
+
+SCCOL ScViewData::PrevCellsX( ScHSplitPos eWhichX ) const
+{
+ return CellsAtX( GetPosX( eWhichX ), -1, eWhichX, SC_SIZE_NONE );
+}
+
+SCROW ScViewData::PrevCellsY( ScVSplitPos eWhichY ) const
+{
+ return CellsAtY( GetPosY( eWhichY ), -1, eWhichY, SC_SIZE_NONE );
+}
+
+//UNUSED2008-05 SCCOL ScViewData::LastCellsX( ScHSplitPos eWhichX ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 return CellsAtX( MAXCOL+1, -1, eWhichX, SC_SIZE_NONE );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 SCROW ScViewData::LastCellsY( ScVSplitPos eWhichY ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 return CellsAtY( MAXROW+1, -1, eWhichY, SC_SIZE_NONE );
+//UNUSED2008-05 }
+
+BOOL ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix )
+{
+ const ScMergeAttr* pMerge = (const ScMergeAttr*) pDoc->GetAttr( nX,nY,nTabNo, ATTR_MERGE );
+ if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
+ {
+ long nOutWidth = 0;
+ long nOutHeight = 0;
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=0; i<nCountX; i++)
+ nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+
+ for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowHidden(nRow, nTabNo, NULL, &nLastRow))
+ {
+ nRow = nLastRow;
+ continue;
+ }
+
+ USHORT nHeight = pDoc->GetRowHeight(nRow, nTabNo);
+ nOutHeight += ToPixel(nHeight, nPPTY);
+ }
+
+ rSizeXPix = nOutWidth;
+ rSizeYPix = nOutHeight;
+ return TRUE;
+ }
+ else
+ {
+ rSizeXPix = ToPixel( pDoc->GetColWidth( nX, nTabNo ), nPPTX );
+ rSizeYPix = ToPixel( pDoc->GetRowHeight( nY, nTabNo ), nPPTY );
+ return FALSE;
+ }
+}
+
+BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
+ SCsCOL& rPosX, SCsROW& rPosY,
+ BOOL bTestMerge, BOOL bRepair, BOOL bNextIfLarge )
+{
+ // special handling of 0 is now in ScViewFunctionSet::SetCursorAtPoint
+
+ ScHSplitPos eHWhich = WhichH(eWhich);
+ ScVSplitPos eVWhich = WhichV(eWhich);
+
+ if ( pDoc->IsLayoutRTL( nTabNo ) )
+ {
+ // mirror horizontal position
+ if (pView)
+ aScrSize.Width() = pView->GetGridWidth(eHWhich);
+ nClickX = aScrSize.Width() - 1 - nClickX;
+ }
+
+ SCsCOL nStartPosX = GetPosX(eHWhich);
+ SCsROW nStartPosY = GetPosY(eVWhich);
+ rPosX = nStartPosX;
+ rPosY = nStartPosY;
+ long nScrX = 0;
+ long nScrY = 0;
+
+ if (nClickX > 0)
+ {
+ while ( rPosX<=MAXCOL && nClickX >= nScrX )
+ {
+ nScrX += ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
+ ++rPosX;
+ }
+ --rPosX;
+ }
+ else
+ {
+ while ( rPosX>0 && nClickX < nScrX )
+ {
+ --rPosX;
+ nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
+ }
+ }
+
+ if (nClickY > 0)
+ AddPixelsWhile( nScrY, nClickY, rPosY, MAXROW, nPPTY, pDoc, nTabNo );
+ else
+ {
+ /* TODO: could need some "SubPixelsWhileBackward" method */
+ while ( rPosY>0 && nClickY < nScrY )
+ {
+ --rPosY;
+ nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY );
+ }
+ }
+
+ if (bNextIfLarge) // zu grosse Zellen ?
+ {
+ if ( rPosX == nStartPosX && nClickX > 0 )
+ {
+ if (pView)
+ aScrSize.Width() = pView->GetGridWidth(eHWhich);
+ if ( nClickX > aScrSize.Width() )
+ ++rPosX;
+ }
+ if ( rPosY == nStartPosY && nClickY > 0 )
+ {
+ if (pView)
+ aScrSize.Height() = pView->GetGridHeight(eVWhich);
+ if ( nClickY > aScrSize.Height() )
+ ++rPosY;
+ }
+ }
+
+ if (rPosX<0) rPosX=0;
+ if (rPosX>MAXCOL) rPosX=MAXCOL;
+ if (rPosY<0) rPosY=0;
+ if (rPosY>MAXROW) rPosY=MAXROW;
+
+ if (bTestMerge)
+ {
+ //! public Methode um Position anzupassen
+
+ BOOL bHOver = FALSE;
+ while (pDoc->IsHorOverlapped( rPosX, rPosY, nTabNo ))
+ { --rPosX; bHOver=TRUE; }
+ BOOL bVOver = FALSE;
+ while (pDoc->IsVerOverlapped( rPosX, rPosY, nTabNo ))
+ { --rPosY; bVOver=TRUE; }
+
+ if ( bRepair && ( bHOver || bVOver ) )
+ {
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)
+ pDoc->GetAttr( rPosX, rPosY, nTabNo, ATTR_MERGE );
+ if ( ( bHOver && pMerge->GetColMerge() <= 1 ) ||
+ ( bVOver && pMerge->GetRowMerge() <= 1 ) )
+ {
+ DBG_ERROR("Merge-Fehler gefunden");
+
+ pDoc->RemoveFlagsTab( 0,0, MAXCOL,MAXROW, nTabNo, SC_MF_HOR | SC_MF_VER );
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+ pDoc->ExtendMerge( 0,0, nEndCol,nEndRow, nTabNo, TRUE, FALSE );
+ if (pDocShell)
+ pDocShell->PostPaint( ScRange(0,0,nTabNo,MAXCOL,MAXROW,nTabNo), PAINT_GRID );
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+void ScViewData::GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
+ SCsCOL nPosX, SCsROW nPosY, BOOL& rLeft, BOOL& rTop )
+{
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Point aCellStart = GetScrPos( nPosX, nPosY, eWhich, TRUE );
+ long nSizeX;
+ long nSizeY;
+ GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
+ rLeft = ( rClickPos.X() - aCellStart.X() ) * nLayoutSign <= nSizeX / 2;
+ rTop = rClickPos.Y() - aCellStart.Y() <= nSizeY / 2;
+}
+
+void ScViewData::SetPosX( ScHSplitPos eWhich, SCCOL nNewPosX )
+{
+ if (nNewPosX != 0)
+ {
+ SCCOL nOldPosX = pThisTab->nPosX[eWhich];
+ long nTPosX = pThisTab->nTPosX[eWhich];
+ long nPixPosX = pThisTab->nPixPosX[eWhich];
+ SCCOL i;
+ if ( nNewPosX > nOldPosX )
+ for ( i=nOldPosX; i<nNewPosX; i++ )
+ {
+ long nThis = pDoc->GetColWidth( i,nTabNo );
+ nTPosX -= nThis;
+ nPixPosX -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTX);
+ }
+ else
+ for ( i=nNewPosX; i<nOldPosX; i++ )
+ {
+ long nThis = pDoc->GetColWidth( i,nTabNo );
+ nTPosX += nThis;
+ nPixPosX += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTX);
+ }
+
+ pThisTab->nPosX[eWhich] = nNewPosX;
+ pThisTab->nTPosX[eWhich] = nTPosX;
+ pThisTab->nMPosX[eWhich] = (long) (nTPosX * HMM_PER_TWIPS);
+ pThisTab->nPixPosX[eWhich] = nPixPosX;
+ }
+ else
+ pThisTab->nPixPosX[eWhich] =
+ pThisTab->nTPosX[eWhich] =
+ pThisTab->nMPosX[eWhich] =
+ pThisTab->nPosX[eWhich] = 0;
+}
+
+void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
+{
+ if (nNewPosY != 0)
+ {
+ SCROW nOldPosY = pThisTab->nPosY[eWhich];
+ long nTPosY = pThisTab->nTPosY[eWhich];
+ long nPixPosY = pThisTab->nPixPosY[eWhich];
+ SCROW i, nHeightEndRow;
+ if ( nNewPosY > nOldPosY )
+ for ( i=nOldPosY; i<nNewPosY; i++ )
+ {
+ long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
+ SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i;
+ i = nHeightEndRow;
+ nTPosY -= nThis * nRows;
+ nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY) * nRows;
+ }
+ else
+ for ( i=nNewPosY; i<nOldPosY; i++ )
+ {
+ long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
+ SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i;
+ i = nHeightEndRow;
+ nTPosY += nThis * nRows;
+ nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY) * nRows;
+ }
+
+ pThisTab->nPosY[eWhich] = nNewPosY;
+ pThisTab->nTPosY[eWhich] = nTPosY;
+ pThisTab->nMPosY[eWhich] = (long) (nTPosY * HMM_PER_TWIPS);
+ pThisTab->nPixPosY[eWhich] = nPixPosY;
+ }
+ else
+ pThisTab->nPixPosY[eWhich] =
+ pThisTab->nTPosY[eWhich] =
+ pThisTab->nMPosY[eWhich] =
+ pThisTab->nPosY[eWhich] = 0;
+}
+
+void ScViewData::RecalcPixPos() // nach Zoom-Aenderungen
+{
+ for (USHORT eWhich=0; eWhich<2; eWhich++)
+ {
+ long nPixPosX = 0;
+ SCCOL nPosX = pThisTab->nPosX[eWhich];
+ for (SCCOL i=0; i<nPosX; i++)
+ nPixPosX -= ToPixel(pDoc->GetColWidth(i,nTabNo), nPPTX);
+ pThisTab->nPixPosX[eWhich] = nPixPosX;
+
+ long nPixPosY = 0;
+ SCROW nPosY = pThisTab->nPosY[eWhich];
+ for (SCROW j=0; j<nPosY; j++)
+ nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY);
+ pThisTab->nPixPosY[eWhich] = nPixPosY;
+ }
+}
+
+const MapMode& ScViewData::GetLogicMode( ScSplitPos eWhich )
+{
+ aLogicMode.SetOrigin( Point( pThisTab->nMPosX[WhichH(eWhich)],
+ pThisTab->nMPosY[WhichV(eWhich)] ) );
+ return aLogicMode;
+}
+
+const MapMode& ScViewData::GetLogicMode()
+{
+ aLogicMode.SetOrigin( Point() );
+ return aLogicMode;
+}
+
+void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ USHORT nTSize;
+ long nSizePix;
+ long nScrPosX = 0;
+ long nScrPosY = 0;
+
+ SetActivePart( SC_SPLIT_BOTTOMLEFT );
+ SetPosX( SC_SPLIT_LEFT, nCol1 );
+ SetPosY( SC_SPLIT_BOTTOM, nRow1 );
+
+ for (nCol=nCol1; nCol<=nCol2; nCol++)
+ {
+ nTSize = pDoc->GetColWidth( nCol, nTabNo );
+ if (nTSize)
+ {
+ nSizePix = ToPixel( nTSize, nPPTX );
+ nScrPosX += (USHORT) nSizePix;
+ }
+ }
+
+ for (nRow=nRow1; nRow<=nRow2; nRow++)
+ {
+ nTSize = pDoc->GetRowHeight( nRow, nTabNo );
+ if (nTSize)
+ {
+ nSizePix = ToPixel( nTSize, nPPTY );
+ nScrPosY += (USHORT) nSizePix;
+ }
+ }
+
+ aScrSize = Size( nScrPosX, nScrPosY );
+}
+
+void ScViewData::SetScreenPos( const Point& rVisAreaStart )
+{
+ long nSize;
+ long nTwips;
+ long nAdd;
+ BOOL bEnd;
+
+ nSize = 0;
+ nTwips = (long) (rVisAreaStart.X() / HMM_PER_TWIPS);
+ if ( pDoc->IsLayoutRTL( nTabNo ) )
+ nTwips = -nTwips;
+ SCCOL nX1 = 0;
+ bEnd = FALSE;
+ while (!bEnd)
+ {
+ nAdd = (long) pDoc->GetColWidth(nX1,nTabNo);
+ if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
+ {
+ nSize += nAdd;
+ ++nX1;
+ }
+ else
+ bEnd = TRUE;
+ }
+
+ nSize = 0;
+ nTwips = (long) (rVisAreaStart.Y() / HMM_PER_TWIPS);
+ SCROW nY1 = 0;
+ bEnd = FALSE;
+ while (!bEnd)
+ {
+ nAdd = (long) pDoc->GetRowHeight(nY1,nTabNo);
+ if (nSize+nAdd <= nTwips+1 && nY1<MAXROW)
+ {
+ nSize += nAdd;
+ ++nY1;
+ }
+ else
+ bEnd = TRUE;
+ }
+
+ SetActivePart( SC_SPLIT_BOTTOMLEFT );
+ SetPosX( SC_SPLIT_LEFT, nX1 );
+ SetPosY( SC_SPLIT_BOTTOM, nY1 );
+
+ SetCurX( nX1 );
+ SetCurY( nY1 );
+}
+
+void ScViewData::SetScreen( const Rectangle& rVisArea )
+{
+ SetScreenPos( rVisArea.TopLeft() );
+
+ // hier ohne GetOutputFactor(), weil fuer Ausgabe in Metafile
+
+ aScrSize = rVisArea.GetSize();
+ aScrSize.Width() = (long)
+ ( aScrSize.Width() * ScGlobal::nScreenPPTX / HMM_PER_TWIPS );
+ aScrSize.Height() = (long)
+ ( aScrSize.Height() * ScGlobal::nScreenPPTY / HMM_PER_TWIPS );
+}
+
+SfxObjectShell* ScViewData::GetSfxDocShell() const
+{
+ return pDocShell;
+}
+
+SfxBindings& ScViewData::GetBindings()
+{
+ DBG_ASSERT( pViewShell, "GetBindings() without ViewShell" );
+ return pViewShell->GetViewFrame()->GetBindings();
+}
+
+SfxDispatcher& ScViewData::GetDispatcher()
+{
+ DBG_ASSERT( pViewShell, "GetDispatcher() without ViewShell" );
+ return *pViewShell->GetViewFrame()->GetDispatcher();
+}
+
+Window* ScViewData::GetDialogParent()
+{
+ DBG_ASSERT( pViewShell, "GetDialogParent() ohne ViewShell" );
+ return pViewShell->GetDialogParent();
+}
+
+Window* ScViewData::GetActiveWin()
+{
+ DBG_ASSERT( pView, "GetActiveWin() ohne View" );
+ return pView->GetActiveWin();
+}
+
+ScDrawView* ScViewData::GetScDrawView()
+{
+ DBG_ASSERT( pView, "GetScDrawView() ohne View" );
+ return pView->GetScDrawView();
+}
+
+BOOL ScViewData::IsMinimized()
+{
+ DBG_ASSERT( pView, "IsMinimized() ohne View" );
+ return pView->IsMinimized();
+}
+
+void ScViewData::UpdateScreenZoom( const Fraction& rNewX, const Fraction& rNewY )
+{
+ Fraction aOldX = GetZoomX();
+ Fraction aOldY = GetZoomY();
+
+ SetZoom( rNewX, rNewY, FALSE );
+
+ Fraction aWidth = GetZoomX();
+ aWidth *= Fraction( aScrSize.Width(),1 );
+ aWidth /= aOldX;
+
+ Fraction aHeight = GetZoomY();
+ aHeight *= Fraction( aScrSize.Height(),1 );
+ aHeight /= aOldY;
+
+ aScrSize.Width() = (long) aWidth;
+ aScrSize.Height() = (long) aHeight;
+}
+
+void ScViewData::CalcPPT()
+{
+ nPPTX = ScGlobal::nScreenPPTX * (double) GetZoomX();
+ if (pDocShell)
+ nPPTX = nPPTX / pDocShell->GetOutputFactor(); // Faktor ist Drucker zu Bildschirm
+ nPPTY = ScGlobal::nScreenPPTY * (double) GetZoomY();
+
+ // #83616# if detective objects are present,
+ // try to adjust horizontal scale so the most common column width has minimal rounding errors,
+ // to avoid differences between cell and drawing layer output
+
+ if ( pDoc && pDoc->HasDetectiveObjects(nTabNo) )
+ {
+ SCCOL nEndCol = 0;
+ SCROW nDummy = 0;
+ pDoc->GetTableArea( nTabNo, nEndCol, nDummy );
+ if (nEndCol<20)
+ nEndCol = 20; // same end position as when determining draw scale
+
+ USHORT nTwips = pDoc->GetCommonWidth( nEndCol, nTabNo );
+ if ( nTwips )
+ {
+ double fOriginal = nTwips * nPPTX;
+ if ( fOriginal < static_cast<double>(nEndCol) )
+ {
+ // if one column is smaller than the column count,
+ // rounding errors are likely to add up to a whole column.
+
+ double fRounded = ::rtl::math::approxFloor( fOriginal + 0.5 );
+ if ( fRounded > 0.0 )
+ {
+ double fScale = fRounded / fOriginal + 1E-6;
+ if ( fScale >= 0.9 && fScale <= 1.1 )
+ nPPTX *= fScale;
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+#define SC_OLD_TABSEP '/'
+#define SC_NEW_TABSEP '+'
+
+void ScViewData::WriteUserData(String& rData)
+{
+ // nZoom (bis 364v) oder nZoom/nPageZoom/bPageMode (ab 364w)
+ // nTab
+ // Tab-ControlBreite
+ // pro Tabelle:
+ // CursorX/CursorY/HSplitMode/VSplitMode/HSplitPos/VSplitPos/SplitActive/
+ // PosX[links]/PosX[rechts]/PosY[oben]/PosY[unten]
+ // wenn Zeilen groesser 8192, "+" statt "/"
+
+ USHORT nZoom = (USHORT)((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
+ rData = String::CreateFromInt32( nZoom );
+ rData += '/';
+ nZoom = (USHORT)((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
+ rData += String::CreateFromInt32( nZoom );
+ rData += '/';
+ if (bPagebreak)
+ rData += '1';
+ else
+ rData += '0';
+
+ rData += ';';
+ rData += String::CreateFromInt32( nTabNo );
+ rData += ';';
+ rData.AppendAscii(RTL_CONSTASCII_STRINGPARAM( TAG_TABBARWIDTH ));
+ rData += String::CreateFromInt32( pView->GetTabBarWidth() );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ rData += ';'; // Numerierung darf auf keinen Fall durcheinanderkommen
+ if (pTabData[i])
+ {
+ sal_Unicode cTabSep = SC_OLD_TABSEP; // wie 3.1
+ if ( pTabData[i]->nCurY > MAXROW_30 ||
+ pTabData[i]->nPosY[0] > MAXROW_30 || pTabData[i]->nPosY[1] > MAXROW_30 ||
+ ( pTabData[i]->eVSplitMode == SC_SPLIT_FIX &&
+ pTabData[i]->nFixPosY > MAXROW_30 ) )
+ {
+ cTabSep = SC_NEW_TABSEP; // um eine 3.1-Version nicht umzubringen
+ }
+
+
+ rData += String::CreateFromInt32( pTabData[i]->nCurX );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nCurY );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->eHSplitMode );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->eVSplitMode );
+ rData += cTabSep;
+ if ( pTabData[i]->eHSplitMode == SC_SPLIT_FIX )
+ rData += String::CreateFromInt32( pTabData[i]->nFixPosX );
+ else
+ rData += String::CreateFromInt32( pTabData[i]->nHSplitPos );
+ rData += cTabSep;
+ if ( pTabData[i]->eVSplitMode == SC_SPLIT_FIX )
+ rData += String::CreateFromInt32( pTabData[i]->nFixPosY );
+ else
+ rData += String::CreateFromInt32( pTabData[i]->nVSplitPos );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->eWhichActive );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosX[0] );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosX[1] );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosY[0] );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosY[1] );
+ }
+ }
+}
+
+void ScViewData::ReadUserData(const String& rData)
+{
+ if (!rData.Len()) // Leerer String kommt bei "neu Laden"
+ return; // dann auch ohne Assertion beenden
+
+ xub_StrLen nCount = rData.GetTokenCount(';');
+ if ( nCount <= 2 )
+ {
+ // #45208# beim Reload in der Seitenansicht sind evtl. die Preview-UserData
+ // stehengelassen worden. Den Zoom von der Preview will man hier nicht...
+ DBG_ERROR("ReadUserData: das sind nicht meine Daten");
+ return;
+ }
+
+ String aTabOpt;
+ xub_StrLen nTagLen = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(TAG_TABBARWIDTH)).Len();
+
+ //-------------------
+ // nicht pro Tabelle:
+ //-------------------
+ SCTAB nTabStart = 2;
+
+ Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY; //! evaluate (all sheets?)
+
+ String aZoomStr = rData.GetToken(0); // Zoom/PageZoom/Modus
+ USHORT nNormZoom = sal::static_int_cast<USHORT>(aZoomStr.GetToken(0,'/').ToInt32());
+ if ( nNormZoom >= MINZOOM && nNormZoom <= MAXZOOM )
+ aZoomX = aZoomY = Fraction( nNormZoom, 100 ); // "normaler" Zoom (immer)
+ USHORT nPageZoom = sal::static_int_cast<USHORT>(aZoomStr.GetToken(1,'/').ToInt32());
+ if ( nPageZoom >= MINZOOM && nPageZoom <= MAXZOOM )
+ aPageZoomX = aPageZoomY = Fraction( nPageZoom, 100 ); // Pagebreak-Zoom, wenn gesetzt
+ sal_Unicode cMode = aZoomStr.GetToken(2,'/').GetChar(0); // 0 oder "0"/"1"
+ SetPagebreakMode( cMode == '1' );
+ // SetPagebreakMode muss immer gerufen werden wegen CalcPPT / RecalcPixPos()
+
+ //
+ // Tabelle kann ungueltig geworden sein (z.B. letzte Version):
+ //
+ SCTAB nNewTab = static_cast<SCTAB>(rData.GetToken(1).ToInt32());
+ if (pDoc->HasTable( nNewTab ))
+ SetTabNo(nNewTab);
+
+ //
+ // wenn vorhanden, TabBar-Breite holen:
+ //
+ aTabOpt = rData.GetToken(2);
+
+ if ( nTagLen && aTabOpt.Copy(0,nTagLen).EqualsAscii(TAG_TABBARWIDTH) )
+ {
+ pView->SetTabBarWidth( aTabOpt.Copy(nTagLen).ToInt32() );
+ nTabStart = 3;
+ }
+
+ //-------------
+ // pro Tabelle:
+ //-------------
+ SCTAB nPos = 0;
+ while ( nCount > nPos+nTabStart )
+ {
+ aTabOpt = rData.GetToken(static_cast<xub_StrLen>(nPos+nTabStart));
+ if (!pTabData[nPos])
+ pTabData[nPos] = new ScViewDataTable;
+
+ sal_Unicode cTabSep = 0;
+ if (aTabOpt.GetTokenCount(SC_OLD_TABSEP) >= 11)
+ cTabSep = SC_OLD_TABSEP;
+#ifndef SC_LIMIT_ROWS
+ else if (aTabOpt.GetTokenCount(SC_NEW_TABSEP) >= 11)
+ cTabSep = SC_NEW_TABSEP;
+ // '+' ist nur erlaubt, wenn wir mit Zeilen > 8192 umgehen koennen
+#endif
+
+ if (cTabSep)
+ {
+ pTabData[nPos]->nCurX = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(0,cTabSep).ToInt32()));
+ pTabData[nPos]->nCurY = SanitizeRow( aTabOpt.GetToken(1,cTabSep).ToInt32());
+ pTabData[nPos]->eHSplitMode = (ScSplitMode) aTabOpt.GetToken(2,cTabSep).ToInt32();
+ pTabData[nPos]->eVSplitMode = (ScSplitMode) aTabOpt.GetToken(3,cTabSep).ToInt32();
+
+ if ( pTabData[nPos]->eHSplitMode == SC_SPLIT_FIX )
+ {
+ pTabData[nPos]->nFixPosX = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(4,cTabSep).ToInt32()));
+ UpdateFixX(nPos);
+ }
+ else
+ pTabData[nPos]->nHSplitPos = aTabOpt.GetToken(4,cTabSep).ToInt32();
+
+ if ( pTabData[nPos]->eVSplitMode == SC_SPLIT_FIX )
+ {
+ pTabData[nPos]->nFixPosY = SanitizeRow( aTabOpt.GetToken(5,cTabSep).ToInt32());
+ UpdateFixY(nPos);
+ }
+ else
+ pTabData[nPos]->nVSplitPos = aTabOpt.GetToken(5,cTabSep).ToInt32();
+
+ pTabData[nPos]->eWhichActive = (ScSplitPos) aTabOpt.GetToken(6,cTabSep).ToInt32();
+ pTabData[nPos]->nPosX[0] = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(7,cTabSep).ToInt32()));
+ pTabData[nPos]->nPosX[1] = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(8,cTabSep).ToInt32()));
+ pTabData[nPos]->nPosY[0] = SanitizeRow( aTabOpt.GetToken(9,cTabSep).ToInt32());
+ pTabData[nPos]->nPosY[1] = SanitizeRow( aTabOpt.GetToken(10,cTabSep).ToInt32());
+
+ // Test, ob der aktive Teil laut SplitMode ueberhaupt existiert
+ // (Bug #44516#)
+ ScSplitPos eTest = pTabData[nPos]->eWhichActive;
+ if ( ( WhichH( eTest ) == SC_SPLIT_RIGHT &&
+ pTabData[nPos]->eHSplitMode == SC_SPLIT_NONE ) ||
+ ( WhichV( eTest ) == SC_SPLIT_TOP &&
+ pTabData[nPos]->eVSplitMode == SC_SPLIT_NONE ) )
+ {
+ // dann wieder auf Default (unten links)
+ pTabData[nPos]->eWhichActive = SC_SPLIT_BOTTOMLEFT;
+ DBG_ERROR("SplitPos musste korrigiert werden");
+ }
+ }
+ ++nPos;
+ }
+
+ RecalcPixPos();
+}
+
+void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
+{
+ // *** Fill extended document data for export filters ***
+
+ // document settings
+ ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
+
+ // displayed sheet
+ rDocSett.mnDisplTab = GetTabNo();
+
+ // width of the tabbar, relative to frame window width
+ rDocSett.mfTabBarWidth = pView->GetPendingRelTabBarWidth();
+ if( rDocSett.mfTabBarWidth < 0.0 )
+ rDocSett.mfTabBarWidth = pView->GetRelTabBarWidth();
+
+ // sheet settings
+ for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ if( const ScViewDataTable* pViewTab = pTabData[ nTab ] )
+ {
+ ScExtTabSettings& rTabSett = rDocOpt.GetOrCreateTabSettings( nTab );
+
+ // split mode
+ ScSplitMode eHSplit = pViewTab->eHSplitMode;
+ ScSplitMode eVSplit = pViewTab->eVSplitMode;
+ bool bHSplit = eHSplit != SC_SPLIT_NONE;
+ bool bVSplit = eVSplit != SC_SPLIT_NONE;
+ bool bRealSplit = (eHSplit == SC_SPLIT_NORMAL) || (eVSplit == SC_SPLIT_NORMAL);
+ bool bFrozen = (eHSplit == SC_SPLIT_FIX) || (eVSplit == SC_SPLIT_FIX);
+ DBG_ASSERT( !bRealSplit || !bFrozen, "ScViewData::WriteExtOptions - split and freeze in same sheet" );
+ rTabSett.mbFrozenPanes = !bRealSplit && bFrozen;
+
+ // split and freeze position
+ rTabSett.maSplitPos = Point( 0, 0 );
+ rTabSett.maFreezePos.Set( 0, 0, nTab );
+ if( bRealSplit )
+ {
+ Point& rSplitPos = rTabSett.maSplitPos;
+ rSplitPos = Point( bHSplit ? pViewTab->nHSplitPos : 0, bVSplit ? pViewTab->nVSplitPos : 0 );
+ rSplitPos = Application::GetDefaultDevice()->PixelToLogic( rSplitPos, MapMode( MAP_TWIP ) );
+ if( pDocShell )
+ rSplitPos.X() = (long)((double)rSplitPos.X() / pDocShell->GetOutputFactor());
+ }
+ else if( bFrozen )
+ {
+ if( bHSplit ) rTabSett.maFreezePos.SetCol( pViewTab->nFixPosX );
+ if( bVSplit ) rTabSett.maFreezePos.SetRow( pViewTab->nFixPosY );
+ }
+
+ // first visible cell in top-left and additional panes
+ rTabSett.maFirstVis.Set( pViewTab->nPosX[ SC_SPLIT_LEFT ], pViewTab->nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ], nTab );
+ rTabSett.maSecondVis.Set( pViewTab->nPosX[ SC_SPLIT_RIGHT ], pViewTab->nPosY[ SC_SPLIT_BOTTOM ], nTab );
+
+ // active pane
+ switch( pViewTab->eWhichActive )
+ {
+ // no horizontal split -> always use left panes
+ // no vertical split -> always use top panes
+ case SC_SPLIT_TOPLEFT:
+ rTabSett.meActivePane = SCEXT_PANE_TOPLEFT;
+ break;
+ case SC_SPLIT_TOPRIGHT:
+ rTabSett.meActivePane = bHSplit ? SCEXT_PANE_TOPRIGHT : SCEXT_PANE_TOPLEFT;
+ break;
+ case SC_SPLIT_BOTTOMLEFT:
+ rTabSett.meActivePane = bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT;
+ break;
+ case SC_SPLIT_BOTTOMRIGHT:
+ rTabSett.meActivePane = bHSplit ?
+ (bVSplit ? SCEXT_PANE_BOTTOMRIGHT : SCEXT_PANE_TOPRIGHT) :
+ (bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT);
+ break;
+ }
+
+ // cursor position
+ rTabSett.maCursor.Set( pViewTab->nCurX, pViewTab->nCurY, nTab );
+
+ // sheet selection and selected ranges
+ const ScMarkData& rMarkData = GetMarkData();
+ rTabSett.mbSelected = rMarkData.GetTableSelect( nTab );
+ rMarkData.FillRangeListWithMarks( &rTabSett.maSelection, TRUE );
+
+ // grid color
+ rTabSett.maGridColor.SetColor( COL_AUTO );
+ if( pOptions )
+ {
+ const Color& rGridColor = pOptions->GetGridColor();
+ if( rGridColor.GetColor() != SC_STD_GRIDCOLOR )
+ rTabSett.maGridColor = rGridColor;
+ }
+
+ // view mode and zoom
+ rTabSett.mbPageMode = bPagebreak;
+ rTabSett.mnNormalZoom = static_cast< long >( pViewTab->aZoomY * Fraction( 100.0 ) );
+ rTabSett.mnPageZoom = static_cast< long >( pViewTab->aPageZoomY * Fraction( 100.0 ) );
+ }
+ }
+}
+
+void ScViewData::ReadExtOptions( const ScExtDocOptions& rDocOpt )
+{
+ // *** Get extended document data from import filters ***
+
+ if( !rDocOpt.IsChanged() ) return;
+
+ // document settings
+ const ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
+
+ // displayed sheet
+ SetTabNo( rDocSett.mnDisplTab );
+
+ /* Width of the tabbar, relative to frame window width. We do not have the
+ correct width of the frame window here -> store in ScTabView, which sets
+ the size in the next resize. */
+ pView->SetPendingRelTabBarWidth( rDocSett.mfTabBarWidth );
+
+ // sheet settings
+ for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nTab ) )
+ {
+ if( !pTabData[ nTab ] )
+ pTabData[ nTab ] = new ScViewDataTable;
+
+ const ScExtTabSettings& rTabSett = *pTabSett;
+ ScViewDataTable& rViewTab = *pTabData[ nTab ];
+
+ // split mode initialization
+ bool bFrozen = rTabSett.mbFrozenPanes;
+ bool bHSplit = bFrozen ? (rTabSett.maFreezePos.Col() > 0) : (rTabSett.maSplitPos.X() > 0);
+ bool bVSplit = bFrozen ? (rTabSett.maFreezePos.Row() > 0) : (rTabSett.maSplitPos.Y() > 0);
+
+ // first visible cell of top-left pane and additional panes
+ rViewTab.nPosX[ SC_SPLIT_LEFT ] = rTabSett.maFirstVis.Col();
+ rViewTab.nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ] = rTabSett.maFirstVis.Row();
+ if( bHSplit ) rViewTab.nPosX[ SC_SPLIT_RIGHT ] = rTabSett.maSecondVis.Col();
+ if( bVSplit ) rViewTab.nPosY[ SC_SPLIT_BOTTOM ] = rTabSett.maSecondVis.Row();
+
+ // split mode, split and freeze position
+ rViewTab.eHSplitMode = rViewTab.eVSplitMode = SC_SPLIT_NONE;
+ rViewTab.nHSplitPos = rViewTab.nVSplitPos = 0;
+ rViewTab.nFixPosX = 0;
+ rViewTab.nFixPosY = 0;
+ if( bFrozen )
+ {
+ if( bHSplit )
+ {
+ rViewTab.eHSplitMode = SC_SPLIT_FIX;
+ rViewTab.nFixPosX = rTabSett.maFreezePos.Col();
+ UpdateFixX( nTab );
+ }
+ if( bVSplit )
+ {
+ rViewTab.eVSplitMode = SC_SPLIT_FIX;
+ rViewTab.nFixPosY = rTabSett.maFreezePos.Row();
+ UpdateFixY( nTab );
+ }
+ }
+ else
+ {
+ Point aPixel = Application::GetDefaultDevice()->LogicToPixel(
+ rTabSett.maSplitPos, MapMode( MAP_TWIP ) ); //! Zoom?
+ // #109648# - the test for use of printer metrics for text formatting here
+ // effectively results in the nFactor = 1.0 regardless of the Option setting.
+ if( pDocShell && SC_MOD()->GetInputOptions().GetTextWysiwyg())
+ {
+ double nFactor = pDocShell->GetOutputFactor();
+ aPixel.X() = (long)( aPixel.X() * nFactor + 0.5 );
+ }
+ if( bHSplit )
+ {
+ rViewTab.eHSplitMode = SC_SPLIT_NORMAL;
+ rViewTab.nHSplitPos = aPixel.X();
+ }
+ if( bVSplit )
+ {
+ rViewTab.eVSplitMode = SC_SPLIT_NORMAL;
+ rViewTab.nVSplitPos = aPixel.Y();
+ }
+ }
+
+ // active pane
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ switch( rTabSett.meActivePane )
+ {
+ // no horizontal split -> always use left panes
+ // no vertical split -> always use *bottom* panes
+ case SCEXT_PANE_TOPLEFT:
+ ePos = bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+ break;
+ case SCEXT_PANE_TOPRIGHT:
+ ePos = bHSplit ?
+ (bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT) :
+ (bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT);
+ break;
+ case SCEXT_PANE_BOTTOMLEFT:
+ ePos = SC_SPLIT_BOTTOMLEFT;
+ break;
+ case SCEXT_PANE_BOTTOMRIGHT:
+ ePos = bHSplit ? SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_BOTTOMLEFT;
+ break;
+ }
+ rViewTab.eWhichActive = ePos;
+
+ // cursor position
+ const ScAddress& rCursor = rTabSett.maCursor;
+ if( rCursor.IsValid() )
+ {
+ rViewTab.nCurX = rCursor.Col();
+ rViewTab.nCurY = rCursor.Row();
+ }
+
+ // sheet selection and selected ranges
+ ScMarkData& rMarkData = GetMarkData();
+ rMarkData.SelectTable( nTab, rTabSett.mbSelected );
+
+ // zoom for each sheet
+ if( rTabSett.mnNormalZoom )
+ rViewTab.aZoomX = rViewTab.aZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
+ if( rTabSett.mnPageZoom )
+ rViewTab.aPageZoomX = rViewTab.aPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
+
+ // get some settings from displayed Excel sheet, set at Calc document
+ if( nTab == GetTabNo() )
+ {
+ // selection only for displayed sheet, do not select single cell
+// Disabled, does not work correctly. Anyway, our own XML filters do not import a selection at all.
+// const ScRangeList& rSel = rTabSett.maSelection;
+// if( (rSel.Count() >= 2) || ((rSel.Count() == 1) && (*rSel.GetObject( 0 ) != ScRange( rCursor ))) )
+// rMarkData.MarkFromRangeList( rTabSett.maSelection, FALSE );
+
+ // grid color -- #i47435# set automatic grid color explicitly
+ if( pOptions )
+ {
+ Color aGridColor( rTabSett.maGridColor );
+ if( aGridColor.GetColor() == COL_AUTO )
+ aGridColor.SetColor( SC_STD_GRIDCOLOR );
+ pOptions->SetGridColor( aGridColor, EMPTY_STRING );
+ }
+
+ // view mode and default zoom (for new sheets) from current sheet
+ if( rTabSett.mnNormalZoom )
+ aDefZoomX = aDefZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
+ if( rTabSett.mnPageZoom )
+ aDefPageZoomX = aDefPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
+ /* #i46820# set pagebreak mode via SetPagebreakMode(), this will
+ update map modes that are needed to draw text correctly. */
+ SetPagebreakMode( rTabSett.mbPageMode );
+ }
+ }
+ }
+
+ // RecalcPixPos oder so - auch nMPos - auch bei ReadUserData ??!?!
+}
+
+void ScViewData::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings)
+{
+ rSettings.realloc(SC_VIEWSETTINGS_COUNT);
+ // + 1, because we have to put the view id in the sequence
+ beans::PropertyValue* pSettings = rSettings.getArray();
+ if (pSettings)
+ {
+ sal_uInt16 nViewID(pViewShell->GetViewFrame()->GetCurViewId());
+ pSettings[SC_VIEW_ID].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEWID));
+ rtl::OUStringBuffer sBuffer(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEW)));
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nViewID));
+ pSettings[SC_VIEW_ID].Value <<= sBuffer.makeStringAndClear();
+
+ SCTAB nTabCount (pDoc->GetTableCount());
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
+ if( xServiceFactory.is() )
+ {
+ rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.NamedPropertyValues"));
+ uno::Reference<container::XNameContainer> xNameContainer = uno::Reference<container::XNameContainer>(xServiceFactory->createInstance(sName), uno::UNO_QUERY);
+ if (xNameContainer.is())
+ {
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pTabData[nTab])
+ {
+ uno::Sequence <beans::PropertyValue> aTableViewSettings;
+ pTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this, nTab);
+ String sTabName;
+ GetDocument()->GetName( nTab, sTabName );
+ rtl::OUString sOUName(sTabName);
+ uno::Any aAny;
+ aAny <<= aTableViewSettings;
+ try
+ {
+ xNameContainer->insertByName(sTabName, aAny);
+ }
+ //#101739#; two tables with the same name are possible
+ catch ( container::ElementExistException& )
+ {
+ DBG_ERRORFILE("seems there are two tables with the same name");
+ }
+ catch ( uno::RuntimeException& )
+ {
+ DBG_ERRORFILE("something went wrong");
+ }
+ }
+ }
+ pSettings[SC_TABLE_VIEWSETTINGS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_TABLES));
+ pSettings[SC_TABLE_VIEWSETTINGS].Value <<= xNameContainer;
+ }
+ }
+
+ String sName;
+ GetDocument()->GetName( nTabNo, sName );
+ rtl::OUString sOUName(sName);
+ pSettings[SC_ACTIVE_TABLE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
+ pSettings[SC_ACTIVE_TABLE].Value <<= sOUName;
+ pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSCROLLBARWIDTH));
+ pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Value <<= sal_Int32(pView->GetTabBarWidth());
+ sal_Int32 nZoomValue ((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
+ sal_Int32 nPageZoomValue ((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
+ pSettings[SC_ZOOM_TYPE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMTYPE));
+ pSettings[SC_ZOOM_TYPE].Value <<= sal_Int16(pThisTab->eZoomType);
+ pSettings[SC_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
+ pSettings[SC_ZOOM_VALUE].Value <<= nZoomValue;
+ pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE));
+ pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
+ pSettings[SC_PAGE_BREAK_PREVIEW].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SHOWPAGEBREAKPREVIEW));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_PAGE_BREAK_PREVIEW].Value, bPagebreak);
+
+ if (pOptions)
+ {
+ pSettings[SC_SHOWZERO].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWZERO));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWZERO].Value, pOptions->GetOption( VOPT_NULLVALS ) );
+ pSettings[SC_SHOWNOTES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWNOTES));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWNOTES].Value, pOptions->GetOption( VOPT_NOTES ) );
+ pSettings[SC_SHOWGRID].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWGRID));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWGRID].Value, pOptions->GetOption( VOPT_GRID ) );
+ pSettings[SC_GRIDCOLOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_GRIDCOLOR));
+ String aColorName;
+ Color aColor = pOptions->GetGridColor(&aColorName);
+ pSettings[SC_GRIDCOLOR].Value <<= static_cast<sal_Int64>(aColor.GetColor());
+ pSettings[SC_SHOWPAGEBR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWPAGEBR));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWPAGEBR].Value, pOptions->GetOption( VOPT_PAGEBREAKS ) );
+ pSettings[SC_COLROWHDR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COLROWHDR));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_COLROWHDR].Value, pOptions->GetOption( VOPT_HEADER ) );
+ pSettings[SC_SHEETTABS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETTABS));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHEETTABS].Value, pOptions->GetOption( VOPT_TABCONTROLS ) );
+ pSettings[SC_OUTLSYMB].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_OUTLSYMB));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_OUTLSYMB].Value, pOptions->GetOption( VOPT_OUTLINER ) );
+
+ const ScGridOptions& aGridOpt = pOptions->GetGridOptions();
+ pSettings[SC_SNAPTORASTER].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SNAPTORASTER));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SNAPTORASTER].Value, aGridOpt.GetUseGridSnap() );
+ pSettings[SC_RASTERVIS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERVIS));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERVIS].Value, aGridOpt.GetGridVisible() );
+ pSettings[SC_RASTERRESX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESX));
+ pSettings[SC_RASTERRESX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawX() );
+ pSettings[SC_RASTERRESY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESY));
+ pSettings[SC_RASTERRESY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawY() );
+ pSettings[SC_RASTERSUBX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBX));
+ pSettings[SC_RASTERSUBX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionX() );
+ pSettings[SC_RASTERSUBY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBY));
+ pSettings[SC_RASTERSUBY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionY() );
+ pSettings[SC_RASTERSYNC].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSYNC));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERSYNC].Value, aGridOpt.GetSynchronize() );
+ }
+ }
+}
+
+void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& rSettings)
+{
+ Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY; //! evaluate (all sheets?)
+
+ std::vector<bool> aHasZoomVect( GetDocument()->GetTableCount(), false );
+
+ sal_Int32 nCount(rSettings.getLength());
+ sal_Int32 nTemp32(0);
+ sal_Int16 nTemp16(0);
+ sal_Bool bPageMode(sal_False);
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ // SC_VIEWID has to parse and use by mba
+ rtl::OUString sName(rSettings[i].Name);
+ if (sName.compareToAscii(SC_TABLES) == 0)
+ {
+ uno::Reference<container::XNameContainer> xNameContainer;
+ if ((rSettings[i].Value >>= xNameContainer) && xNameContainer->hasElements())
+ {
+ uno::Sequence< rtl::OUString > aNames(xNameContainer->getElementNames());
+ for (sal_Int32 nTabPos = 0; nTabPos < aNames.getLength(); nTabPos++)
+ {
+ String sTabName(aNames[nTabPos]);
+ SCTAB nTab(0);
+ if (GetDocument()->GetTable(sTabName, nTab))
+ {
+ uno::Any aAny = xNameContainer->getByName(aNames[nTabPos]);
+ uno::Sequence<beans::PropertyValue> aTabSettings;
+ if (aAny >>= aTabSettings)
+ {
+ pTabData[nTab] = new ScViewDataTable;
+ bool bHasZoom = false;
+ pTabData[nTab]->ReadUserDataSequence(aTabSettings, *this, nTab, bHasZoom);
+ aHasZoomVect[nTab] = bHasZoom;
+ }
+ }
+ }
+ }
+ }
+ else if (sName.compareToAscii(SC_ACTIVETABLE) == 0)
+ {
+ rtl::OUString sValue;
+ if(rSettings[i].Value >>= sValue)
+ {
+ String sTabName(sValue);
+ SCTAB nTab(0);
+ if (GetDocument()->GetTable(sTabName, nTab))
+ nTabNo = nTab;
+ }
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSCROLLBARWIDTH) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp32)
+ pView->SetTabBarWidth(nTemp32);
+ }
+ else if (sName.compareToAscii(SC_RELHORIZONTALTABBARWIDTH) == 0)
+ {
+ double fWidth = 0.0;
+ if (rSettings[i].Value >>= fWidth)
+ pView->SetPendingRelTabBarWidth( fWidth );
+ }
+ else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp16)
+ eDefZoomType = SvxZoomType(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp32)
+ {
+ Fraction aZoom(nTemp32, 100);
+ aDefZoomX = aDefZoomY = aZoom;
+ }
+ }
+ else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp32)
+ {
+ Fraction aZoom(nTemp32, 100);
+ aDefPageZoomX = aDefPageZoomY = aZoom;
+ }
+ }
+ else if (sName.compareToAscii(SC_SHOWPAGEBREAKPREVIEW) == 0)
+ bPageMode = ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value );
+ else if ( sName.compareToAscii( SC_UNO_SHOWZERO ) == 0 )
+ pOptions->SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHOWNOTES ) == 0 )
+ pOptions->SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHOWGRID ) == 0 )
+ pOptions->SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_GRIDCOLOR ) == 0 )
+ {
+ sal_Int64 nColor = 0;
+ if (rSettings[i].Value >>= nColor)
+ {
+ String aColorName;
+ Color aColor(static_cast<sal_uInt32>(nColor));
+ // #i47435# set automatic grid color explicitly
+ if( aColor.GetColor() == COL_AUTO )
+ aColor.SetColor( SC_STD_GRIDCOLOR );
+ pOptions->SetGridColor(aColor, aColorName);
+ }
+ }
+ else if ( sName.compareToAscii( SC_UNO_SHOWPAGEBR ) == 0 )
+ pOptions->SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_COLROWHDR ) == 0 )
+ pOptions->SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHEETTABS ) == 0 )
+ pOptions->SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_OUTLSYMB ) == 0 )
+ pOptions->SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHOWOBJ ) == 0 )
+ {
+ // #i80528# placeholders not supported anymore
+ if ( rSettings[i].Value >>= nTemp16 )
+ pOptions->SetObjMode( VOBJ_TYPE_OLE, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
+ }
+ else if ( sName.compareToAscii( SC_UNO_SHOWCHARTS ) == 0 )
+ {
+ // #i80528# placeholders not supported anymore
+ if ( rSettings[i].Value >>= nTemp16 )
+ pOptions->SetObjMode( VOBJ_TYPE_CHART, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
+ }
+ else if ( sName.compareToAscii( SC_UNO_SHOWDRAW ) == 0 )
+ {
+ // #i80528# placeholders not supported anymore
+ if ( rSettings[i].Value >>= nTemp16 )
+ pOptions->SetObjMode( VOBJ_TYPE_DRAW, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
+ }
+ else
+ {
+ ScGridOptions aGridOpt(pOptions->GetGridOptions());
+ if ( sName.compareToAscii( SC_UNO_SNAPTORASTER ) == 0 )
+ aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERVIS ) == 0 )
+ aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERRESX ) == 0 )
+ aGridOpt.SetFldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERRESY ) == 0 )
+ aGridOpt.SetFldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERSUBX ) == 0 )
+ aGridOpt.SetFldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERSUBY ) == 0 )
+ aGridOpt.SetFldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERSYNC ) == 0 )
+ aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ pOptions->SetGridOptions(aGridOpt);
+ }
+ }
+
+ // copy default zoom to sheets where a different one wasn't specified
+ for (SCTAB nZoomTab=0; nZoomTab<=MAXTAB; ++nZoomTab)
+ if (pTabData[nZoomTab] && ( nZoomTab >= static_cast<SCTAB>(aHasZoomVect.size()) || !aHasZoomVect[nZoomTab] ))
+ {
+ pTabData[nZoomTab]->eZoomType = eDefZoomType;
+ pTabData[nZoomTab]->aZoomX = aDefZoomX;
+ pTabData[nZoomTab]->aZoomY = aDefZoomY;
+ pTabData[nZoomTab]->aPageZoomX = aDefPageZoomX;
+ pTabData[nZoomTab]->aPageZoomY = aDefPageZoomY;
+ }
+
+ if (nCount)
+ SetPagebreakMode( bPageMode );
+
+ // #i47426# write view options to document, needed e.g. for Excel export
+ pDoc->SetViewOptions( *pOptions );
+}
+
+void ScViewData::SetOptions( const ScViewOptions& rOpt )
+{
+ // if visibility of horiz. ScrollBar is changed, TabBar may have to be resized...
+ BOOL bHScrollChanged = ( rOpt.GetOption(VOPT_HSCROLL) != pOptions->GetOption(VOPT_HSCROLL) );
+
+ // if graphics are turned on or off, animation has to be started or stopped
+ // graphics are controlled by VOBJ_TYPE_OLE
+ BOOL bGraphicsChanged = ( pOptions->GetObjMode(VOBJ_TYPE_OLE) !=
+ rOpt.GetObjMode(VOBJ_TYPE_OLE) );
+
+ *pOptions = rOpt;
+ DBG_ASSERT( pView, "No View" );
+
+ if( pView )
+ {
+ pView->ViewOptionsHasChanged( bHScrollChanged, bGraphicsChanged );
+ }
+}
+
+Point ScViewData::GetMousePosPixel()
+{
+ DBG_ASSERT( pView, "GetMousePosPixel() ohne View" );
+ return pView->GetMousePosPixel();
+}
+
+void ScViewData::UpdateInputHandler( BOOL bForce, BOOL bStopEditing )
+{
+ if (pViewShell)
+ pViewShell->UpdateInputHandler( bForce, bStopEditing );
+}
+
+BOOL ScViewData::IsOle()
+{
+ return pDocShell && pDocShell->IsOle();
+}
+
+BOOL ScViewData::UpdateFixX( SCTAB nTab ) // TRUE = Wert geaendert
+{
+ if (!ValidTab(nTab)) // Default
+ nTab=nTabNo; // akuelle Tabelle
+
+ if (!pView || pTabData[nTab]->eHSplitMode != SC_SPLIT_FIX)
+ return FALSE;
+
+ ScDocument* pLocalDoc = GetDocument();
+ if (!pLocalDoc->HasTable(nTab)) // #114007# if called from reload, the sheet may not exist
+ return FALSE;
+
+ SCCOL nFix = pTabData[nTab]->nFixPosX;
+ long nNewPos = 0;
+ for (SCCOL nX=pTabData[nTab]->nPosX[SC_SPLIT_LEFT]; nX<nFix; nX++)
+ {
+ USHORT nTSize = pLocalDoc->GetColWidth( nX, nTab );
+ if (nTSize)
+ {
+ long nPix = ToPixel( nTSize, nPPTX );
+ nNewPos += nPix;
+ }
+ }
+ nNewPos += pView->GetGridOffset().X();
+ if (nNewPos != pTabData[nTab]->nHSplitPos)
+ {
+ pTabData[nTab]->nHSplitPos = nNewPos;
+ if (nTab == nTabNo)
+ RecalcPixPos(); //! sollte nicht noetig sein !!!
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL ScViewData::UpdateFixY( SCTAB nTab ) // TRUE = Wert geaendert
+{
+ if (!ValidTab(nTab)) // Default
+ nTab=nTabNo; // akuelle Tabelle
+
+ if (!pView || pTabData[nTab]->eVSplitMode != SC_SPLIT_FIX)
+ return FALSE;
+
+ ScDocument* pLocalDoc = GetDocument();
+ if (!pLocalDoc->HasTable(nTab)) // #114007# if called from reload, the sheet may not exist
+ return FALSE;
+
+ SCROW nFix = pTabData[nTab]->nFixPosY;
+ long nNewPos = 0;
+ for (SCROW nY=pTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++)
+ {
+ USHORT nTSize = pLocalDoc->GetRowHeight( nY, nTab );
+ if (nTSize)
+ {
+ long nPix = ToPixel( nTSize, nPPTY );
+ nNewPos += nPix;
+ }
+ }
+ nNewPos += pView->GetGridOffset().Y();
+ if (nNewPos != pTabData[nTab]->nVSplitPos)
+ {
+ pTabData[nTab]->nVSplitPos = nNewPos;
+ if (nTab == nTabNo)
+ RecalcPixPos(); //! sollte nicht noetig sein !!!
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ScViewData::UpdateOutlinerFlags( Outliner& rOutl ) const
+{
+ ScDocument* pLocalDoc = GetDocument();
+ BOOL bOnlineSpell = pLocalDoc->GetDocOptions().IsAutoSpell();
+
+ ULONG nCntrl = rOutl.GetControlWord();
+ nCntrl |= EE_CNTRL_URLSFXEXECUTE;
+ nCntrl |= EE_CNTRL_MARKFIELDS;
+ nCntrl |= EE_CNTRL_AUTOCORRECT;
+ if( bOnlineSpell )
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ rOutl.SetControlWord(nCntrl);
+
+ rOutl.SetCalcFieldValueHdl( LINK( SC_MOD(), ScModule, CalcFieldValueHdl ) );
+
+ // #97417# don't call GetSpellChecker if online spelling isn't enabled.
+ // The language for AutoCorrect etc. is taken from the pool defaults
+ // (set in ScDocument::UpdateDrawLanguages)
+
+ if ( bOnlineSpell )
+ {
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
+ rOutl.SetSpeller( xXSpellChecker1 );
+ }
+
+ rOutl.SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pLocalDoc->GetEditTextDirection( nTabNo ) );
+}
+
+ScAddress ScViewData::GetCurPos() const
+{
+ return ScAddress( GetCurX(), GetCurY(), GetTabNo() );
+}
+
+
+// static
+void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
+ SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
+{
+ SCROW nRow = rPosY;
+ while (rScrY <= nEndPixels && nRow <= nEndRow)
+ {
+ SCROW nHeightEndRow;
+ USHORT nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow);
+ if (nHeightEndRow > nEndRow)
+ nHeightEndRow = nEndRow;
+ if (!nHeight)
+ nRow = nHeightEndRow + 1;
+ else
+ {
+ SCROW nRows = nHeightEndRow - nRow + 1;
+ sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
+ sal_Int64 nAdd = nPixel * nRows;
+ if (nAdd + rScrY > nEndPixels)
+ {
+ sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
+ nRows -= static_cast<SCROW>(nDiff / nPixel);
+ nAdd = nPixel * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rScrY <= nEndPixels)
+ {
+ ++nRows;
+ nAdd += nPixel;
+ }
+ }
+ rScrY += static_cast<long>(nAdd);
+ nRow += nRows;
+ }
+ }
+ if (nRow > rPosY)
+ --nRow;
+ rPosY = nRow;
+}
+
+
+// static
+void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
+ SCTAB nTabNo )
+{
+ SCROW nRow = rPosY;
+ while (rScrY <= nEndPixels && nRow >= nStartRow)
+ {
+ SCROW nHeightStartRow;
+ USHORT nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL);
+ if (nHeightStartRow < nStartRow)
+ nHeightStartRow = nStartRow;
+ if (!nHeight)
+ nRow = nHeightStartRow - 1;
+ else
+ {
+ SCROW nRows = nRow - nHeightStartRow + 1;
+ sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
+ sal_Int64 nAdd = nPixel * nRows;
+ if (nAdd + rScrY > nEndPixels)
+ {
+ sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
+ nRows -= static_cast<SCROW>(nDiff / nPixel);
+ nAdd = nPixel * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rScrY <= nEndPixels)
+ {
+ ++nRows;
+ nAdd += nPixel;
+ }
+ }
+ rScrY += static_cast<long>(nAdd);
+ nRow -= nRows;
+ }
+ }
+ if (nRow < rPosY)
+ ++nRow;
+ rPosY = nRow;
+}
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
new file mode 100644
index 000000000000..a125cbea6f50
--- /dev/null
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -0,0 +1,3145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#define _SVSTDARR_STRINGS
+#include <editeng/boxitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/svstdarr.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/waitobj.hxx>
+
+#include "viewfunc.hxx"
+
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include "attrib.hxx"
+#include "autoform.hxx"
+#include "cell.hxx" // EnterAutoSum
+#include "compiler.hxx"
+#include "docfunc.hxx"
+#include "docpool.hxx"
+#include "docsh.hxx"
+#include "global.hxx"
+#include "patattr.hxx"
+#include "printfun.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "refundo.hxx"
+#include "tablink.hxx"
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "undoblk.hxx"
+#include "undocell.hxx"
+#include "undotab.hxx"
+#include "sizedev.hxx"
+#include "editable.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "funcdesc.hxx"
+#include "docuno.hxx"
+#include "charthelper.hxx"
+#include "tabbgcolor.hxx"
+
+#include <basic/sbstar.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+using namespace com::sun::star;
+
+// helper func defined in docfunc.cxx
+void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );
+
+// STATIC DATA ---------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::AdjustBlockHeight( BOOL bPaint, ScMarkData* pMarkData )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if (!pMarkData)
+ pMarkData = &GetViewData()->GetMarkData();
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
+ if (nRangeCnt == 0)
+ {
+ pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
+ nRangeCnt = 1;
+ }
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ BOOL bAnyChanged = FALSE;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ SCCOLROW* pOneRange = pRanges;
+ BOOL bChanged = FALSE;
+ SCROW nPaintY = 0;
+ for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCROW nStartNo = *(pOneRange++);
+ SCROW nEndNo = *(pOneRange++);
+ if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, FALSE ))
+ {
+ if (!bChanged)
+ nPaintY = nStartNo;
+ bAnyChanged = bChanged = TRUE;
+ }
+ }
+ if ( bPaint && bChanged )
+ pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+ }
+ }
+ delete[] pRanges;
+
+ if ( bPaint && bAnyChanged )
+ pDocSh->UpdateOle(GetViewData());
+
+ return bAnyChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, BOOL bPaint )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+ USHORT nOldPixel = 0;
+ if (nStartRow == nEndRow)
+ nOldPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+ BOOL bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
+
+ if (bChanged && ( nStartRow == nEndRow ))
+ {
+ USHORT nNewPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+ if ( nNewPixel == nOldPixel )
+ bChanged = FALSE;
+ }
+
+ if ( bPaint && bChanged )
+ pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+
+ return bChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+enum ScAutoSum
+{
+ ScAutoSumNone = 0,
+ ScAutoSumData,
+ ScAutoSumSum
+};
+
+
+ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
+ SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
+{
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if ( pCell && pCell->HasValueData() )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
+ if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
+ {
+ if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
+ ScAddress( nCol, nRow, nTab ), eDir ) )
+ return ScAutoSumSum;
+ }
+ }
+ return ScAutoSumData;
+ }
+ return ScAutoSumNone;
+}
+
+
+//----------------------------------------------------------------------------
+
+#define SC_AUTOSUM_MAXCOUNT 20
+
+ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
+ SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
+{
+ USHORT nCount = 0;
+ while (nCount < SC_AUTOSUM_MAXCOUNT)
+ {
+ if ( eDir == DIR_TOP )
+ {
+ if (nRow > 0)
+ --nRow;
+ else
+ return ScAutoSumNone;
+ }
+ else
+ {
+ if (nCol > 0)
+ --nCol;
+ else
+ return ScAutoSumNone;
+ }
+ ScAutoSum eSum;
+ if ( (eSum = lcl_IsAutoSumData(
+ pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
+ return eSum;
+ ++nCount;
+ }
+ return ScAutoSumNone;
+}
+
+#undef SC_AUTOSUM_MAXCOUNT
+
+//----------------------------------------------------------------------------
+
+bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
+ SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
+{
+ const SCROW nTmp = nRow;
+ ScAutoSum eSkip = ScAutoSumNone;
+ while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
+ nRow > nMinRow )
+ {
+ --nRow;
+ }
+ if ( eSkip == ScAutoSumSum && nRow < nTmp )
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
+ SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
+{
+ const SCCOL nTmp = nCol;
+ ScAutoSum eSkip = ScAutoSumNone;
+ while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
+ nCol > nMinCol )
+ {
+ --nCol;
+ }
+ if ( eSkip == ScAutoSumSum && nCol < nTmp )
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
+{
+ const ScAddress aStart = rRange.aStart;
+ const ScAddress aEnd = rRange.aEnd;
+ if ( aStart.Col() != aEnd.Col() )
+ {
+ return false;
+ }
+
+ const SCTAB nTab = aEnd.Tab();
+ const SCCOL nCol = aEnd.Col();
+ SCROW nEndRow = aEnd.Row();
+ SCROW nStartRow = nEndRow;
+ SCCOLROW nExtend = 0;
+ const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
+
+ if ( eSum == ScAutoSumSum )
+ {
+ bool bContinue = false;
+ do
+ {
+ rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
+ nEndRow = static_cast< SCROW >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
+ {
+ nStartRow = nEndRow;
+ }
+ } while ( bContinue );
+ }
+ else
+ {
+ while ( nStartRow > aStart.Row() &&
+ lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
+ {
+ --nStartRow;
+ }
+ rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
+{
+ const ScAddress aStart = rRange.aStart;
+ const ScAddress aEnd = rRange.aEnd;
+ if ( aStart.Row() != aEnd.Row() )
+ {
+ return false;
+ }
+
+ const SCTAB nTab = aEnd.Tab();
+ const SCROW nRow = aEnd.Row();
+ SCCOL nEndCol = aEnd.Col();
+ SCCOL nStartCol = nEndCol;
+ SCCOLROW nExtend = 0;
+ const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
+
+ if ( eSum == ScAutoSumSum )
+ {
+ bool bContinue = false;
+ do
+ {
+ rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
+ nEndCol = static_cast< SCCOL >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
+ {
+ nStartCol = nEndCol;
+ }
+ } while ( bContinue );
+ }
+ else
+ {
+ while ( nStartCol > aStart.Col() &&
+ lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
+ {
+ --nStartCol;
+ }
+ rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+
+ SCCOL nStartCol = nCol;
+ SCROW nStartRow = nRow;
+ SCCOL nEndCol = nCol;
+ SCROW nEndRow = nRow;
+ SCCOL nSeekCol = nCol;
+ SCROW nSeekRow = nRow;
+ SCCOLROW nExtend; // wird per Reference gueltig bei ScAutoSumSum
+
+ BOOL bCol = FALSE;
+ BOOL bRow = FALSE;
+
+ ScAutoSum eSum;
+ if ( nRow != 0
+ && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
+ DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
+ && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ )
+ {
+ bRow = TRUE;
+ nSeekRow = nRow - 1;
+ }
+ else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ {
+ bCol = TRUE;
+ nSeekCol = nCol - 1;
+ }
+ else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
+ bRow = TRUE;
+ else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
+ bCol = TRUE;
+
+ if ( bCol || bRow )
+ {
+ if ( bRow )
+ {
+ nStartRow = nSeekRow; // nSeekRow evtl. per Reference angepasst
+ if ( eSum == ScAutoSumSum )
+ nEndRow = nStartRow; // nur Summen summieren
+ else
+ nEndRow = nRow - 1; // Datenbereich evtl. nach unten erweitern
+ }
+ else
+ {
+ nStartCol = nSeekCol; // nSeekCol evtl. per Reference angepasst
+ if ( eSum == ScAutoSumSum )
+ nEndCol = nStartCol; // nur Summen summieren
+ else
+ nEndCol = nCol - 1; // Datenbereich evtl. nach rechts erweitern
+ }
+ BOOL bContinue = FALSE;
+ do
+ {
+ if ( eSum == ScAutoSumData )
+ {
+ if ( bRow )
+ {
+ while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
+ nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
+ --nStartRow;
+ }
+ else
+ {
+ while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
+ nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
+ --nStartCol;
+ }
+ }
+ rRangeList.Append(
+ ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
+ if ( eSum == ScAutoSumSum )
+ {
+ if ( bRow )
+ {
+ nEndRow = static_cast< SCROW >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
+ {
+ nStartRow = nEndRow;
+ }
+ }
+ else
+ {
+ nEndCol = static_cast< SCCOL >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
+ {
+ nStartCol = nEndCol;
+ }
+ }
+ }
+ } while ( bContinue );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal) // Block mit Summen fuellen
+{
+ String aFormula = GetAutoSumFormula( rRangeList, bSubTotal );
+ EnterBlock( aFormula, NULL );
+}
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ const SCCOL nEndCol = rRange.aEnd.Col();
+ const SCROW nEndRow = rRange.aEnd.Row();
+ SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
+
+ // ignore rows at the top of the given range which don't contain autosum data
+ bool bRowData = false;
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
+ {
+ bRowData = true;
+ break;
+ }
+ }
+ if ( bRowData )
+ {
+ nStartRow = nRow;
+ break;
+ }
+ }
+ if ( !bRowData )
+ {
+ return false;
+ }
+
+ // ignore columns at the left of the given range which don't contain autosum data
+ bool bColData = false;
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
+ {
+ bColData = true;
+ break;
+ }
+ }
+ if ( bColData )
+ {
+ nStartCol = nCol;
+ break;
+ }
+ }
+ if ( !bColData )
+ {
+ return false;
+ }
+
+ const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
+ const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
+ bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
+ bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
+
+ // find an empty row for entering the result
+ SCROW nInsRow = nEndRow;
+ if ( bRow && !bEndRowEmpty )
+ {
+ if ( nInsRow < MAXROW )
+ {
+ ++nInsRow;
+ while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
+ {
+ if ( nInsRow < MAXROW )
+ {
+ ++nInsRow;
+ }
+ else
+ {
+ bRow = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bRow = false;
+ }
+ }
+
+ // find an empty column for entering the result
+ SCCOL nInsCol = nEndCol;
+ if ( bCol && !bEndColEmpty )
+ {
+ if ( nInsCol < MAXCOL )
+ {
+ ++nInsCol;
+ while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
+ {
+ if ( nInsCol < MAXCOL )
+ {
+ ++nInsCol;
+ }
+ else
+ {
+ bCol = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bCol = false;
+ }
+ }
+
+ if ( !bRow && !bCol )
+ {
+ return false;
+ }
+
+ SCCOL nMarkEndCol = nEndCol;
+ SCROW nMarkEndRow = nEndRow;
+
+ if ( bRow )
+ {
+ // calculate the row sums for all columns of the given range
+
+ SCROW nSumEndRow = nEndRow;
+
+ if ( bEndRowEmpty )
+ {
+ // the last row of the given range is empty;
+ // don't take into account for calculating the autosum
+ --nSumEndRow;
+ }
+ else
+ {
+ // increase mark range
+ ++nMarkEndRow;
+ }
+
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
+ {
+ ScRangeList aRangeList;
+ const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
+ if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
+ {
+ const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
+ EnterData( nCol, nInsRow, nTab, aFormula );
+ }
+ }
+ }
+ }
+
+ if ( bCol )
+ {
+ // calculate the column sums for all rows of the given range
+
+ SCCOL nSumEndCol = nEndCol;
+
+ if ( bEndColEmpty )
+ {
+ // the last column of the given range is empty;
+ // don't take into account for calculating the autosum
+ --nSumEndCol;
+ }
+ else
+ {
+ // increase mark range
+ ++nMarkEndCol;
+ }
+
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
+ {
+ ScRangeList aRangeList;
+ const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
+ if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
+ {
+ const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
+ EnterData( nInsCol, nRow, nTab, aFormula );
+ }
+ }
+ }
+ }
+
+ // set new mark range and cursor position
+ const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
+ MarkRange( aMarkRange, FALSE, bContinue );
+ if ( bSetCursor )
+ {
+ SetCursor( nMarkEndCol, nMarkEndRow );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal )
+{
+ String aFormula = '=';
+ ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+ const ScFuncDesc* pDesc = NULL;
+ if ( bSubTotal )
+ {
+ pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL );
+ }
+ else
+ {
+ pDesc = pFuncMgr->Get( SC_OPCODE_SUM );
+ }
+ if ( pDesc && pDesc->pFuncName )
+ {
+ aFormula += *pDesc->pFuncName;
+ if ( bSubTotal )
+ {
+ aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) );
+ }
+ else
+ {
+ aFormula += '(';
+ }
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ String aRef;
+ rRangeList.Format( aRef, SCA_VALID, pDoc );
+ aFormula += aRef;
+ aFormula += ')';
+ }
+ return aFormula;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
+{
+ // Mehrfachselektion vorher abfragen...
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToSimple();
+ if ( rMark.IsMultiMarked() )
+ { // "Einfuegen auf Mehrfachselektion nicht moeglich"
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+
+ // insert into single cell
+ if ( pData )
+ EnterData( nCol, nRow, nTab, pData );
+ else
+ EnterData( nCol, nRow, nTab, rString );
+ return;
+ }
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ String aNewStr = rString;
+ if ( pData )
+ {
+ const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
+ aEngine.SetText(*pData);
+
+ ScEditAttrTester aTester( &aEngine );
+ if (!aTester.NeedsObject())
+ {
+ aNewStr = aEngine.GetText();
+ pData = NULL;
+ }
+ }
+
+ // Einfuegen per PasteFromClip
+
+ WaitObject aWait( GetFrameWin() );
+
+ ScAddress aPos( nCol, nRow, nTab );
+
+ ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
+ pInsDoc->ResetClip( pDoc, nTab );
+
+ if (aNewStr.GetChar(0) == '=') // Formel ?
+ {
+ // SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
+ ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
+ pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
+ }
+ else if ( pData )
+ pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
+ else
+ pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
+
+ pInsDoc->SetClipArea( ScRange(aPos) );
+ // auf Block einfuegen, mit Undo etc.
+ if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, FALSE, FALSE,
+ FALSE, INS_NONE, IDF_ATTRIB ) )
+ {
+ const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
+ nCol, nRow, nTab, ATTR_VALUE_FORMAT );
+ if ( pItem )
+ { // Numberformat setzen wenn inkompatibel
+ // MarkData wurde bereits in PasteFromClip MarkToSimple'ed
+ ScRange aRange;
+ rMark.GetMarkArea( aRange );
+ ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
+ pPattern->GetItemSet().Put( *pItem );
+ short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
+ pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
+ *pPattern, nNewType );
+ delete pPattern;
+ }
+ }
+
+ delete pInsDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScViewFunc::PaintWidthHeight( BOOL bColumns, SCCOLROW nStart, SCCOLROW nEnd )
+//UNUSED2008-05 {
+//UNUSED2008-05 SCTAB nTab = GetViewData()->GetTabNo();
+//UNUSED2008-05 ScDocument* pDoc = GetViewData()->GetDocument();
+//UNUSED2008-05
+//UNUSED2008-05 USHORT nParts = PAINT_GRID;
+//UNUSED2008-05 SCCOL nStartCol = 0;
+//UNUSED2008-05 SCROW nStartRow = 0;
+//UNUSED2008-05 SCCOL nEndCol = MAXCOL; // fuer Test auf Merge
+//UNUSED2008-05 SCROW nEndRow = MAXROW;
+//UNUSED2008-05 if ( bColumns )
+//UNUSED2008-05 {
+//UNUSED2008-05 nParts |= PAINT_TOP;
+//UNUSED2008-05 nStartCol = static_cast<SCCOL>(nStart);
+//UNUSED2008-05 nEndCol = static_cast<SCCOL>(nEnd);
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 nParts |= PAINT_LEFT;
+//UNUSED2008-05 nStartRow = nStart;
+//UNUSED2008-05 nEndRow = nEnd;
+//UNUSED2008-05 }
+//UNUSED2008-05 if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+//UNUSED2008-05 HASATTR_MERGED | HASATTR_OVERLAPPED ))
+//UNUSED2008-05 {
+//UNUSED2008-05 nStartCol = 0;
+//UNUSED2008-05 nStartRow = 0;
+//UNUSED2008-05 }
+//UNUSED2008-05 GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
+//UNUSED2008-05 }
+
+
+//----------------------------------------------------------------------------
+// manueller Seitenumbruch
+
+void ScViewFunc::InsertPageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
+ BOOL bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::DeletePageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
+ BOOL bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::RemoveManualBreaks()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if (bUndo)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
+ pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pUndoDoc );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
+ }
+
+ pDoc->RemoveManualBreaks(nTab);
+ pDoc->UpdatePageBreaks(nTab);
+
+ UpdatePageBreakData( TRUE );
+ pDocSh->SetDocumentModified();
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintZoom(USHORT nScale, USHORT nPages)
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ pDocSh->SetPrintZoom( nTab, nScale, nPages );
+}
+
+void ScViewFunc::AdjustPrintZoom()
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
+ GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
+ GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintRanges( BOOL bEntireSheet, const String* pPrint,
+ const String* pRepCol, const String* pRepRow,
+ BOOL bAddPrint )
+{
+ // on all selected tables
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab;
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ {
+ ScRange aRange( 0,0,nTab );
+
+ // print ranges
+
+ if( !bAddPrint )
+ pDoc->ClearPrintRanges( nTab );
+
+ if( bEntireSheet )
+ {
+ pDoc->SetPrintEntireSheet( nTab );
+ }
+ else if ( pPrint )
+ {
+ if ( pPrint->Len() )
+ {
+ const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ USHORT nTCount = pPrint->GetTokenCount(sep);
+ for (USHORT i=0; i<nTCount; i++)
+ {
+ String aToken = pPrint->GetToken(i, sep);
+ if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
+ pDoc->AddPrintRange( nTab, aRange );
+ }
+ }
+ }
+ else // NULL = use selection (print range is always set), use empty string to delete all ranges
+ {
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ pDoc->AddPrintRange( nTab, aRange );
+ }
+ else if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToMulti();
+ ScRangeListRef aList( new ScRangeList );
+ rMark.FillRangeListWithMarks( aList, FALSE );
+ USHORT nCnt = (USHORT) aList->Count();
+ if ( nCnt )
+ {
+ ScRangePtr pR;
+ USHORT i;
+ for ( pR = aList->First(), i=0; i < nCnt;
+ pR = aList->Next(), i++ )
+ {
+ pDoc->AddPrintRange( nTab, *pR );
+ }
+ }
+ }
+ }
+
+ // repeat columns
+
+ if ( pRepCol )
+ {
+ if ( !pRepCol->Len() )
+ pDoc->SetRepeatColRange( nTab, NULL );
+ else
+ if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
+ pDoc->SetRepeatColRange( nTab, &aRange );
+ }
+
+ // repeat rows
+
+ if ( pRepRow )
+ {
+ if ( !pRepRow->Len() )
+ pDoc->SetRepeatRowRange( nTab, NULL );
+ else
+ if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
+ pDoc->SetRepeatRowRange( nTab, &aRange );
+ }
+ }
+
+ // undo (for all tables)
+ if (bUndo)
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
+ }
+
+ // update page breaks
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_DELETE_PRINTAREA );
+
+ pDocSh->SetDocumentModified();
+}
+
+//----------------------------------------------------------------------------
+// Zellen zusammenfassen
+
+BOOL ScViewFunc::TestMergeCells() // Vorab-Test (fuer Menue)
+{
+ // simple test: TRUE if there's a selection but no multi selection and not filtered
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ ScRange aDummy;
+ return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
+ }
+ else
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord )
+{
+ // Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
+ // damit dann nicht die Inhalte-QueryBox kommt
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ rMark.MarkToSimple();
+ if (!rMark.IsMarked())
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ return FALSE;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+ if ( nStartCol == nEndCol && nStartRow == nEndRow )
+ {
+ // nichts zu tun
+ return TRUE;
+ }
+
+ if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ { // "Zusammenfassen nicht verschachteln !"
+ ErrorMessage(STR_MSSG_MERGECELLS_0);
+ return FALSE;
+ }
+
+ BOOL bOk = TRUE;
+
+ if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
+ !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) )
+ {
+ if (!bApi)
+ {
+ MessBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
+ USHORT nRetVal = aBox.Execute();
+
+ if ( nRetVal == RET_YES )
+ rDoContents = TRUE;
+ else if ( nRetVal == RET_CANCEL )
+ bOk = FALSE;
+ }
+ }
+
+ if (bOk)
+ {
+ HideCursor();
+ bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi );
+ ShowCursor();
+
+ if (bOk)
+ {
+ SetCursor( nStartCol, nStartRow );
+ //DoneBlockMode( FALSE);
+ Unmark();
+
+ pDocSh->UpdateOle(GetViewData());
+ UpdateInputLine();
+ }
+ }
+
+ return bOk;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::TestRemoveMerge()
+{
+ BOOL bMerged = FALSE;
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
+ bMerged = TRUE;
+ }
+ return bMerged;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::RemoveMerge( BOOL bRecord )
+{
+ ScRange aRange;
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+ else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScRange aExtended( aRange );
+ GetViewData()->GetDocument()->ExtendMerge( aExtended );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ HideCursor();
+ BOOL bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, FALSE );
+ MarkRange( aExtended );
+ ShowCursor();
+
+ if (bOk)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ return TRUE; //! bOk ??
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSimple( FillDir eDir, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, FALSE );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+ }
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
+ double fStart, double fStep, double fMax, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().
+ FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
+ fStart, fStep, fMax, bRecord, FALSE );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+ }
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, ULONG nCount, BOOL bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
+ ScRange aSourceRange( aRange );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().
+ FillAuto( aRange, &rMark, eDir, nCount, bRecord, FALSE );
+ if (bSuccess)
+ {
+ MarkRange( aRange, FALSE ); // aRange ist in FillAuto veraendert worden
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ ScRange aChangeRange( aRange );
+ switch ( eDir )
+ {
+ case FILL_TO_BOTTOM:
+ {
+ aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
+ }
+ break;
+ case FILL_TO_TOP:
+ {
+ aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
+ }
+ break;
+ case FILL_TO_RIGHT:
+ {
+ aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
+ }
+ break;
+ case FILL_TO_LEFT:
+ {
+ aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
+ }
+ break;
+ default:
+ {
+
+ }
+ break;
+ }
+ aChangeRanges.Append( aChangeRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillTab( USHORT nFlags, USHORT nFunction, BOOL bSkipEmpty, BOOL bAsLink )
+{
+ //! allow source sheet to be protected
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ 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(), nTab );
+
+ ScDocument* pUndoDoc = NULL;
+// if ( bRecord )
+ if (bUndo)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+// pUndoDoc->SelectTable( nTab, TRUE ); // nur fuer Markierung
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && rMark.GetTableSelect(i))
+ {
+ pUndoDoc->AddUndoTab( i, i );
+ aMarkRange.aStart.SetTab( i );
+ aMarkRange.aEnd.SetTab( i );
+ pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
+// pUndoDoc->SelectTable( i, TRUE );
+ }
+ }
+
+ if (bMulti)
+ pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
+ else
+ {
+ aMarkRange.aStart.SetTab( nTab );
+ aMarkRange.aEnd.SetTab( nTab );
+ pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
+ }
+
+// if ( bRecord )
+ if (bUndo)
+ { //! fuer ChangeTrack erst zum Schluss
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoFillTable( pDocSh, rMark,
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
+ pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
+ }
+
+ pDocSh->PostPaintGridAll();
+ pDocSh->PostDataChanged();
+}
+
+//----------------------------------------------------------------------------
+
+/** Downward fill of selected cell(s) by double-clicking cross-hair cursor
+
+ Extends a current selection down to the last non-empty cell of an adjacent
+ column when the lower-right corner of the selection is double-clicked. It
+ uses a left-adjoining non-empty column as a guide if such is available,
+ otherwise a right-adjoining non-empty column is used.
+
+ @author Kohei Yoshida (kohei@openoffice.org)
+
+ @return No return value
+
+ @see #i12313#
+*/
+void ScViewFunc::FillCrossDblClick()
+{
+ ScRange aRange;
+ GetViewData()->GetSimpleArea( aRange );
+ aRange.Justify();
+
+ SCTAB nTab = GetViewData()->GetCurPos().Tab();
+ SCCOL nStartX = aRange.aStart.Col();
+ SCROW nStartY = aRange.aStart.Row();
+ SCCOL nEndX = aRange.aEnd.Col();
+ SCROW nEndY = aRange.aEnd.Row();
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ // Make sure the selection is not empty
+ if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
+ return;
+
+ if ( nEndY < MAXROW )
+ {
+ if ( nStartX > 0 )
+ {
+ SCCOL nMovX = nStartX - 1;
+ SCROW nMovY = nStartY;
+
+ if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
+ pDoc->HasData( nMovX, nStartY + 1, nTab ) )
+ {
+ pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
+
+ if ( nMovY > nEndY )
+ {
+ FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
+ nMovY - nEndY );
+ return;
+ }
+ }
+ }
+
+ if ( nEndX < MAXCOL )
+ {
+ SCCOL nMovX = nEndX + 1;
+ SCROW nMovY = nStartY;
+
+ if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
+ pDoc->HasData( nMovX, nStartY + 1, nTab ) )
+ {
+ pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
+
+ if ( nMovY > nEndY )
+ {
+ FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
+ nMovY - nEndY );
+ return;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::TransliterateText( sal_Int32 nType )
+{
+ ScMarkData aFuncMark = GetViewData()->GetMarkData();
+ if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
+ {
+ // no selection -> use cursor position
+
+ ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ aFuncMark.SetMarkArea( ScRange( aCursor ) );
+ }
+
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ TransliterateText( aFuncMark, nType, TRUE, FALSE );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+}
+
+//----------------------------------------------------------------------------
+// AutoFormat
+
+ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
+{
+ ScAutoFormatData* pData = NULL;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ pData = new ScAutoFormatData;
+ pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
+ }
+ }
+ return pData;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::AutoFormat( USHORT nFormatNo, BOOL bRecord )
+{
+#if 1
+
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ BOOL bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, FALSE );
+ if (bSuccess)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+
+#else
+
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
+ pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ IDF_ATTRIB, FALSE, pUndoDoc );
+ if (bSize)
+ {
+ pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
+ IDF_NONE, FALSE, pUndoDoc );
+ }
+ pDoc->BeginDrawUndo();
+ }
+
+ GetFrameWin()->EnterWait();
+ pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
+ GetFrameWin()->LeaveWait();
+
+ if (bSize)
+ {
+ SetMarkedWidthOrHeight( TRUE, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, FALSE, FALSE );
+ SetMarkedWidthOrHeight( FALSE, SC_SIZE_VISOPT, 0, FALSE, FALSE );
+ pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP );
+ }
+ else
+ {
+ BOOL bAdj = AdjustBlockHeight( FALSE );
+ if (bAdj)
+ pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
+ PAINT_GRID | PAINT_LEFT );
+ else
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab, PAINT_GRID );
+ }
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFormat( pDocSh,
+ ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
+ pUndoDoc, rMark, bSize, nFormatNo ) );
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ pDocSh->SetDocumentModified();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+
+#endif
+}
+
+
+//----------------------------------------------------------------------------
+// Suchen & Ersetzen
+
+void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
+ BOOL bAddUndo, BOOL bIsApi )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (bAddUndo && !pDoc->IsUndoEnabled())
+ bAddUndo = FALSE;
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+// BOOL bAttrib = pSearchItem->GetPattern();
+ USHORT nCommand = pSearchItem->GetCommand();
+ BOOL bAllTables = pSearchItem->IsAllTables();
+ BOOL* pOldSelectedTables = NULL;
+ USHORT nOldSelectedCount = 0;
+ SCTAB nOldTab = nTab;
+ SCTAB nLastTab = pDoc->GetTableCount() - 1;
+ SCTAB nStartTab, nEndTab;
+ if ( bAllTables )
+ {
+ nStartTab = 0;
+ nEndTab = nLastTab;
+ pOldSelectedTables = new BOOL [ nEndTab + 1 ];
+ for ( SCTAB j = 0; j <= nEndTab; j++ )
+ {
+ pOldSelectedTables[j] = rMark.GetTableSelect( j );
+ if ( pOldSelectedTables[j] )
+ ++nOldSelectedCount;
+ }
+ }
+ else
+ { //! mindestens eine ist immer selektiert
+ nStartTab = nEndTab = rMark.GetFirstSelected();
+ for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
+ {
+ if ( rMark.GetTableSelect( j ) )
+ nEndTab = j;
+ }
+ }
+
+ if ( nCommand == SVX_SEARCHCMD_REPLACE
+ || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ if ( (bAllTables || rMark.GetTableSelect( j )) &&
+ pDoc->IsTabProtected( j ) )
+ {
+ if ( pOldSelectedTables )
+ delete [] pOldSelectedTables;
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+ }
+ }
+
+ if ( nCommand == SVX_SEARCHCMD_FIND
+ || nCommand == SVX_SEARCHCMD_FIND_ALL)
+ bAddUndo = FALSE;
+
+ //! bAttrib bei Undo beruecksichtigen !!!
+
+ ScDocument* pUndoDoc = NULL;
+ ScMarkData* pUndoMark = NULL;
+ String aUndoStr;
+ if (bAddUndo)
+ {
+ pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert
+ if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ }
+ }
+
+ if ( bAllTables )
+ { //! alles selektieren, erst nachdem pUndoMark erzeugt wurde
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, TRUE );
+ }
+ }
+
+ DoneBlockMode(TRUE); // Markierung nicht loeschen!
+ InitOwnBlockMode();
+
+ // wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
+ BOOL bFirst = TRUE;
+ if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
+ bFirst = FALSE;
+
+ BOOL bFound = FALSE;
+ while (TRUE)
+ {
+ GetFrameWin()->EnterWait();
+ if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
+ {
+ bFound = TRUE;
+ bFirst = TRUE;
+ if (bAddUndo)
+ {
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
+ nCol, nRow, nTab,
+ aUndoStr, pUndoDoc, pSearchItem ) );
+ pUndoDoc = NULL;
+ }
+
+ break; // Abbruch while True
+ }
+ else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
+ nCommand == SVX_SEARCHCMD_REPLACE) )
+ {
+ bFirst = FALSE;
+ USHORT nRetVal;
+ GetFrameWin()->LeaveWait();
+ if ( bIsApi )
+ nRetVal = RET_NO;
+ else
+ {
+ // Suchen-Dialog als Parent, wenn vorhanden
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ USHORT nStrId;
+ if ( pSearchItem->GetBackward() )
+ {
+ if ( nStartTab == nEndTab )
+ nStrId = STR_MSSG_SEARCHANDREPLACE_1;
+ else
+ nStrId = STR_MSSG_SEARCHANDREPLACE_4;
+ }
+ else
+ {
+ if ( nStartTab == nEndTab )
+ nStrId = STR_MSSG_SEARCHANDREPLACE_2;
+ else
+ nStrId = STR_MSSG_SEARCHANDREPLACE_5;
+ }
+ MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
+ ScGlobal::GetRscString( nStrId ) );
+ nRetVal = aBox.Execute();
+ }
+
+ if ( nRetVal == RET_YES )
+ {
+ ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
+ if (pSearchItem->GetBackward())
+ nTab = nEndTab;
+ else
+ nTab = nStartTab;
+ }
+ else
+ {
+ break; // Abbruch while True
+ }
+ }
+ else // nichts gefunden
+ {
+ if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pDocSh->PostPaintGridAll(); // Markierung
+ }
+
+ GetFrameWin()->LeaveWait();
+ if (!bIsApi)
+ {
+ // Suchen-Dialog als Parent, wenn vorhanden
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ // "nichts gefunden"
+ InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
+ aBox.Execute();
+ }
+
+ break; // Abbruch while True
+ }
+ } // of while TRUE
+
+ if ( pOldSelectedTables )
+ { // urspruenglich selektierte Tabellen wiederherstellen
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, pOldSelectedTables[j] );
+ }
+ if ( bFound )
+ { // durch Fundstelle neu selektierte Tabelle bleibt
+ rMark.SelectTable( nTab, TRUE );
+ // wenn vorher nur eine selektiert war, ist es ein Tausch
+ //! wenn nicht, ist jetzt evtl. eine mehr selektiert
+ if ( nOldSelectedCount == 1 && nTab != nOldTab )
+ rMark.SelectTable( nOldTab, FALSE );
+ }
+ delete [] pOldSelectedTables;
+ }
+
+ MarkDataChanged();
+
+ if ( bFound )
+ {
+ if ( nTab != GetViewData()->GetTabNo() )
+ SetTabNo( nTab );
+
+ // wenn nichts markiert ist, DoneBlockMode, damit von hier aus
+ // direkt per Shift-Cursor markiert werden kann:
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ DoneBlockMode(TRUE);
+
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+ SetCursor( nCol, nRow, TRUE );
+
+ if ( nCommand == SVX_SEARCHCMD_REPLACE
+ || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ if ( nCommand == SVX_SEARCHCMD_REPLACE )
+ pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
+ else
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+ }
+ else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
+ pDocSh->PostPaintGridAll(); // Markierung
+ GetFrameWin()->LeaveWait();
+ }
+
+ delete pUndoDoc; // loeschen wenn nicht benutzt
+ delete pUndoMark; // kann immer geloescht werden
+}
+
+
+//----------------------------------------------------------------------------
+// Zielwertsuche
+
+void ScViewFunc::Solve( const ScSolveParam& rParam )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ SCCOL nDestCol = rParam.aRefVariableCell.Col();
+ SCROW nDestRow = rParam.aRefVariableCell.Row();
+ SCTAB nDestTab = rParam.aRefVariableCell.Tab();
+
+ ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ if ( pDoc )
+ {
+ String aTargetValStr;
+ if ( rParam.pStrTargetVal != NULL )
+ aTargetValStr = *(rParam.pStrTargetVal);
+
+ String aMsgStr;
+ String aResStr;
+ double nSolveResult;
+
+ GetFrameWin()->EnterWait();
+
+ BOOL bExact =
+ pDoc->Solver(
+ rParam.aRefFormulaCell.Col(),
+ rParam.aRefFormulaCell.Row(),
+ rParam.aRefFormulaCell.Tab(),
+ nDestCol, nDestRow, nDestTab,
+ aTargetValStr,
+ nSolveResult );
+
+ GetFrameWin()->LeaveWait();
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ ULONG nFormat = 0;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
+ if ( pPattern )
+ nFormat = pPattern->GetNumberFormat( pFormatter );
+ Color* p;
+ pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
+
+ if ( bExact )
+ {
+ aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
+ aMsgStr += String( aResStr );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
+ }
+ else
+ {
+ aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
+ aMsgStr += String( aResStr );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
+ }
+
+ MessBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
+ USHORT nRetVal = aBox.Execute();
+
+ if ( RET_YES == nRetVal )
+ EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
+
+ GetViewData()->GetViewShell()->UpdateInputHandler( TRUE );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Mehrfachoperation
+
+void ScViewFunc::TabOp( const ScTabOpParam& rParam, BOOL bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, FALSE );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
+ const Color& rColor, USHORT nFlags )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
+ if (nFlags & SC_SCENARIO_COPYALL)
+ SetTabNo( nNewTab, TRUE ); // SC_SCENARIO_COPYALL -> sichtbar
+ else
+ {
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
+ rBindings.Invalidate( SID_TABLES_COUNT );
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Invalidate( FID_TABLE_SHOW );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::ExtendScenario()
+{
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ // Undo: Attribute anwenden
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
+ aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
+ ApplySelectionPattern(aPattern);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UseScenario( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ DoneBlockMode();
+ InitOwnBlockMode();
+ pDocSh->UseScenario( nTab, rName );
+}
+
+
+//----------------------------------------------------------------------------
+// Tabelle einfuegen
+
+BOOL ScViewFunc::InsertTable( const String& rName, SCTAB nTab, BOOL bRecord )
+{
+ // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertTable( nTab, rName, bRecord, FALSE );
+ if (bSuccess)
+ SetTabNo( nTab, TRUE );
+
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+// Tabellen einfuegen
+
+BOOL ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
+ SCTAB nCount, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ SvStrings *pNameList= NULL;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ {
+ pNameList= new SvStrings;
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+ }
+
+ BOOL bFlag=FALSE;
+
+ String aValTabName;
+ String *pStr;
+
+ for(SCTAB i=0;i<nCount;i++)
+ {
+ if(pNames!=NULL)
+ {
+ pStr=pNames->GetObject(static_cast<USHORT>(i));
+ }
+ else
+ {
+ aValTabName.Erase();
+ pDoc->CreateValidTabName( aValTabName);
+ pStr=&aValTabName;
+ }
+
+ if(pDoc->InsertTab( nTab+i,*pStr))
+ {
+ bFlag=TRUE;
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
+ }
+ else
+ {
+ break;
+ }
+
+ if(pNameList!=NULL)
+ pNameList->Insert(new String(*pStr),pNameList->Count());
+
+ }
+
+ if (bFlag)
+ {
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTables( pDocSh, nTab, FALSE, pNameList));
+
+ // Views updaten:
+
+ SetTabNo( nTab, TRUE );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::AppendTable( const String& rName, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+
+ if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
+ {
+ SCTAB nTab = pDoc->GetTableCount()-1;
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDocSh, nTab, TRUE, rName));
+ GetViewData()->InsertTab( nTab );
+ SetTabNo( nTab, TRUE );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::DeleteTable( SCTAB nTab, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ BOOL bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, FALSE );
+ if (bSuccess)
+ {
+ SCTAB nNewTab = nTab;
+ if ( nNewTab >= pDoc->GetTableCount() )
+ --nNewTab;
+ SetTabNo( nNewTab, TRUE );
+ }
+ return bSuccess;
+}
+
+BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : FALSE;
+ SCTAB nNewTab = TheTabs[0];
+ int i;
+ WaitObject aWait( GetFrameWin() );
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
+ --nNewTab;
+
+ BOOL bWasLinked = FALSE;
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+// pUndoDoc->InitDrawLayer( pDocSh );
+ SCTAB nCount = pDoc->GetTableCount();
+
+// pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref.
+
+ String aOldName;
+ for(i=0;i<TheTabs.Count();i++)
+ {
+ SCTAB nTab = TheTabs[sal::static_int_cast<USHORT>(i)];
+ if (i==0)
+ pUndoDoc->InitUndo( pDoc, nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
+ else
+ pUndoDoc->AddUndoTab( nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
+
+ pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pUndoDoc );
+ pDoc->GetName( nTab, aOldName );
+ pUndoDoc->RenameTab( nTab, aOldName, FALSE );
+ if (pDoc->IsLinked(nTab))
+ {
+ bWasLinked = TRUE;
+ pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
+ pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
+ pDoc->GetLinkTab(nTab),
+ pDoc->GetLinkRefreshDelay(nTab) );
+ }
+ if ( pDoc->IsScenario(nTab) )
+ {
+ pUndoDoc->SetScenario( nTab, TRUE );
+ String aComment;
+ Color aColor;
+ USHORT nScenFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
+ pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
+ BOOL bActive = pDoc->IsActiveScenario( nTab );
+ pUndoDoc->SetActiveScenario( nTab, bActive );
+ }
+ pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
+ pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
+ pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
+
+ if ( pDoc->IsTabProtected( nTab ) )
+ pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
+
+ // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
+ // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
+ }
+
+ pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
+
+ pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+
+ BOOL bDelDone = FALSE;
+
+ for(i=TheTabs.Count()-1;i>=0;i--)
+ {
+ String sCodeName;
+ BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName );
+ if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc ))
+ {
+ bDelDone = TRUE;
+ if( bVbaEnabled )
+ {
+ if( bHasCodeName )
+ {
+ VBA_DeleteModule( *pDocSh, sCodeName );
+ }
+ }
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(i)] ) );
+ }
+ }
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
+ pUndoDoc, pUndoData ));
+ }
+
+
+ if (bDelDone)
+ {
+ if ( nNewTab >= pDoc->GetTableCount() )
+ nNewTab = pDoc->GetTableCount() - 1;
+
+ SetTabNo( nNewTab, TRUE );
+
+ if (bWasLinked)
+ {
+ pDocSh->UpdateLinks(); // Link-Manager updaten
+ GetViewData()->GetBindings().Invalidate(SID_LINKS);
+ }
+
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+
+ SfxApplication* pSfxApp = SFX_APP(); // Navigator
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pUndoData;
+ }
+ return bDelDone;
+}
+
+
+//----------------------------------------------------------------------------
+
+BOOL ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
+{
+ // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
+ BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RenameTable( nTab, rName, TRUE, FALSE );
+ if (bSuccess)
+ {
+ // Der Tabellenname koennte in einer Formel vorkommen...
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, TRUE, FALSE );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, TRUE, FALSE );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertAreaLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rSource, ULONG nRefresh )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aPos( nPosX, nPosY, nTab );
+
+ pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, FALSE, FALSE );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertTableLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rTabName )
+{
+ String aFilterName = rFilter;
+ String aOpt = rOptions;
+ ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
+ if (!aLoader.IsError())
+ {
+ ScDocShell* pSrcSh = aLoader.GetDocShell();
+ ScDocument* pSrcDoc = pSrcSh->GetDocument();
+ SCTAB nTab = MAXTAB+1;
+ if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle
+ nTab = 0;
+ else
+ {
+ String aTemp;
+ SCTAB nCount = pSrcDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pSrcDoc->GetName( i, aTemp );
+ if ( aTemp == rTabName )
+ nTab = i;
+ }
+ }
+
+ if ( nTab <= MAXTAB )
+ ImportTables( pSrcSh, 1, &nTab, TRUE,
+ GetViewData()->GetTabNo() );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Tabellen aus anderem Dokument kopieren / linken
+
+void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
+ SCTAB nCount, const SCTAB* pSrcTabs, BOOL bLink,SCTAB nTab )
+{
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ //SCTAB nTab = GetViewData()->GetTabNo();
+
+ BOOL bError = FALSE;
+ BOOL bRefs = FALSE;
+ BOOL bName = FALSE;
+
+ if (pSrcDoc->GetDrawLayer())
+ pDocSh->MakeDrawLayer();
+
+ if (bUndo)
+ pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ SCTAB nInsCount = 0;
+ SCTAB i;
+ for( i=0; i<nCount; i++ )
+ { // #63304# insert sheets first and update all references
+ String aName;
+ pSrcDoc->GetName( pSrcTabs[i], aName );
+ pDoc->CreateValidTabName( aName );
+ if ( !pDoc->InsertTab( nTab+i, aName ) )
+ {
+ bError = TRUE; // total error
+ break; // for
+ }
+ ++nInsCount;
+ }
+ for (i=0; i<nCount && !bError; i++)
+ {
+ SCTAB nSrcTab = pSrcTabs[i];
+ SCTAB nDestTab1=nTab+i;
+ ULONG nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
+ FALSE ); // no insert
+
+ switch (nErrVal)
+ {
+ case 0: // interner Fehler oder voll Fehler
+ bError = TRUE;
+ break;
+ case 2:
+ bRefs = TRUE;
+ break;
+ case 3:
+ bName = TRUE;
+ break;
+ case 4:
+ bRefs = bName = TRUE;
+ break;
+ }
+
+ // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
+ if ( !bError )
+ pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );
+
+ if(!bError &&pSrcDoc->IsScenario(nSrcTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
+ pDoc->SetScenario( nDestTab1,TRUE);
+ pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
+ BOOL bActive = pSrcDoc->IsActiveScenario(nSrcTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ BOOL bVisible=pSrcDoc->IsVisible(nSrcTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+
+ }
+ }
+
+ if (bLink)
+ {
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ SfxMedium* pMed = pSrcShell->GetMedium();
+ String aFileName = pMed->GetName();
+ String aFilterName;
+ if (pMed->GetFilter())
+ aFilterName = pMed->GetFilter()->GetFilterName();
+ String aOptions = ScDocumentLoader::GetOptions(*pMed);
+
+ BOOL bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
+
+ ULONG nRefresh = 0;
+ String aTabStr;
+ for (i=0; i<nInsCount; i++)
+ {
+ pSrcDoc->GetName( pSrcTabs[i], aTabStr );
+ pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
+ aFileName, aFilterName, aOptions, aTabStr, nRefresh );
+ }
+
+ if (!bWasThere) // Link pro Quelldokument nur einmal eintragen
+ {
+ ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
+ pLink->SetInCreate( TRUE );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
+ pLink->Update();
+ pLink->SetInCreate( FALSE );
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_LINKS );
+ }
+ }
+
+
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
+ }
+
+ for (i=0; i<nInsCount; i++)
+ GetViewData()->InsertTab(nTab);
+ SetTabNo(nTab,TRUE);
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
+
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+
+ if (bRefs)
+ ErrorMessage(STR_ABSREFLOST);
+ if (bName)
+ ErrorMessage(STR_NAMECONFLICT);
+}
+
+
+//----------------------------------------------------------------------------
+// Tabelle in anderes Dokument verschieben / kopieren
+
+void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDestDoc = NULL;
+ ScDocShell* pDestShell = NULL;
+ ScTabViewShell* pDestViewSh = NULL;
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ BOOL bNewDoc = ( nDestDocNo == SC_DOC_NEW );
+ if ( bNewDoc )
+ {
+ nDestTab = 0; // als erstes einfuegen
+
+ // ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
+
+ String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
+ aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
+ SfxStringItem aItem( SID_FILE_NAME, aUrl );
+ SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
+
+ const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
+ SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
+ if ( pRetItem )
+ {
+ if ( pRetItem->ISA( SfxObjectItem ) )
+ pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
+ else if ( pRetItem->ISA( SfxViewFrameItem ) )
+ {
+ SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
+ if (pFrm)
+ pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
+ }
+ if (pDestShell)
+ pDestViewSh = pDestShell->GetBestViewShell();
+ }
+ }
+ else
+ pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
+
+ if (!pDestShell)
+ {
+ DBG_ERROR("Dest-Doc nicht gefunden !!!");
+ return;
+ }
+
+ pDestDoc = pDestShell->GetDocument();
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ if (pDestDoc != pDoc)
+ {
+ if (bNewDoc)
+ {
+ while (pDestDoc->GetTableCount() > 1)
+ pDestDoc->DeleteTab(0);
+ pDestDoc->RenameTab( 0,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
+ FALSE );
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SvShorts TheTabs;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabs.Insert(i,TheTabs.Count());
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabs.Insert(j,TheTabs.Count());
+ i=j;
+ }
+ else break;
+ }
+ }
+ }
+
+ GetFrameWin()->EnterWait();
+
+ if (pDoc->GetDrawLayer())
+ pDestShell->MakeDrawLayer();
+
+ if (!bNewDoc && bUndo)
+ pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ ULONG nErrVal =1;
+ if(nDestTab==SC_TAB_APPEND)
+ nDestTab=pDestDoc->GetTableCount();
+ SCTAB nDestTab1=nDestTab;
+ for( USHORT j=0; j<TheTabs.Count(); j++, nDestTab1++ )
+ { // #63304# insert sheets first and update all references
+ String aName;
+ pDoc->GetName( TheTabs[j], aName );
+ pDestDoc->CreateValidTabName( aName );
+ if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
+ {
+ nErrVal = 0; // total error
+ break; // for
+ }
+ }
+ if ( nErrVal > 0 )
+ {
+ nDestTab1 = nDestTab;
+ for(USHORT i=0;i<TheTabs.Count();i++)
+ {
+ nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
+ FALSE ); // no insert
+
+ // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
+ if ( nErrVal > 0 )
+ pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );
+
+ if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
+ pDestDoc->SetScenario(nDestTab1,TRUE);
+ pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ BOOL bActive = pDoc->IsActiveScenario(TheTabs[i]);
+ pDestDoc->SetActiveScenario(nDestTab1, bActive );
+
+ BOOL bVisible=pDoc->IsVisible(TheTabs[i]);
+ pDestDoc->SetVisible(nDestTab1,bVisible );
+
+ }
+
+ if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
+ pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
+
+ nDestTab1++;
+ }
+ }
+ String sName;
+ if (!bNewDoc && bUndo)
+ {
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDestShell, nDestTab,
+ static_cast<SCTAB>(TheTabs.Count()), FALSE));
+
+ }
+ else
+ {
+ pDestShell->GetUndoManager()->Clear();
+ }
+
+ GetFrameWin()->LeaveWait();
+ switch (nErrVal)
+ {
+ case 0: // interner Fehler oder voll Fehler
+ {
+ ErrorMessage(STR_TABINSERT_ERROR);
+ return;
+ }
+ //break;
+ case 2:
+ ErrorMessage(STR_ABSREFLOST);
+ break;
+ case 3:
+ ErrorMessage(STR_NAMECONFLICT);
+ break;
+ case 4:
+ {
+ ErrorMessage(STR_ABSREFLOST);
+ ErrorMessage(STR_NAMECONFLICT);
+ }
+ break;
+ default:
+ break;
+ }
+ //pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!!
+/*
+ String sName;
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDestShell, nDestTab, TRUE, sName ) );
+*/
+ if (!bCopy)
+ {
+ if(nTabCount!=nTabSelCount)
+ DeleteTables(TheTabs);// incl. Paint & Undo
+ else
+ ErrorMessage(STR_TABREMOVE_ERROR);
+ }
+
+ if (bNewDoc)
+ {
+ // ChartListenerCollection must be updated before DeleteTab
+ if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
+ pDestDoc->UpdateChartListenerCollection();
+
+ pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.Count())); // alte erste Tabelle
+//? pDestDoc->SelectTable(0, TRUE); // neue erste Tabelle selektieren
+ if (pDestViewSh)
+ pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
+ pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT |
+ PAINT_EXTRAS | PAINT_SIZE );
+ // PAINT_SIZE fuer Gliederung
+ }
+ else
+ {
+ pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
+ pDestShell->PostPaintExtras();
+ pDestShell->PostPaintGridAll();
+ }
+
+ TheTabs.Remove(0,TheTabs.Count());
+
+ pDestShell->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+ else // innerhalb des Dokuments
+ {
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+
+ SvShorts TheTabs;
+ SvShorts TheDestTabs;
+ SvStrings TheTabNames;
+ String aDestName;
+ String *pString;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
+
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
+ i=j;
+ }
+ else break;
+ }
+
+ }
+ }
+
+ if (bCopy && bUndo)
+ pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ pDoc->GetName( nDestTab, aDestName);
+ SCTAB nDestTab1=nDestTab;
+ SCTAB nMovTab=0;
+ for(int j=0;j<TheTabNames.Count();j++)
+ {
+ nTabCount = pDoc->GetTableCount();
+ pString=TheTabNames[sal::static_int_cast<USHORT>(j)];
+ if(!pDoc->GetTable(*pString,nMovTab))
+ {
+ nMovTab=nTabCount;
+ }
+ if(!pDoc->GetTable(aDestName,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, FALSE ); // Undo ist hier
+
+ if(bCopy && pDoc->IsScenario(nMovTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+
+ pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
+ pDoc->SetScenario(nDestTab1,TRUE);
+ pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ BOOL bActive = pDoc->IsActiveScenario(nMovTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ BOOL bVisible=pDoc->IsVisible(nMovTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+ }
+
+ TheTabs.Insert(nMovTab,TheTabs.Count());
+
+ if(!bCopy)
+ {
+ if(!pDoc->GetTable(*pString,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ }
+
+ TheDestTabs.Insert(nDestTab1,TheDestTabs.Count());
+ delete pString;
+ }
+
+ nTab = GetViewData()->GetTabNo();
+
+ if (bUndo)
+ {
+ if (bCopy)
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
+ }
+ else
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
+ }
+ }
+
+ SCTAB nNewTab = nDestTab;
+ if (nNewTab == SC_TAB_APPEND)
+ nNewTab = pDoc->GetTableCount()-1;
+ else if (!bCopy && nTab<nDestTab)
+ nNewTab--;
+
+ SetTabNo( nNewTab, TRUE );
+
+ //#i29848# adjust references to data on the copied sheet
+ if( bCopy )
+ ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::ShowTable( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ BOOL bFound = FALSE;
+ SCTAB nPos = 0;
+ String aTabName;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pDoc->GetName( i, aTabName );
+ if ( aTabName == rName )
+ {
+ nPos = i;
+ bFound = TRUE;
+ }
+ }
+
+ if (bFound)
+ {
+ pDoc->SetVisible( nPos, TRUE );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, TRUE ) );
+ }
+ SetTabNo( nPos, TRUE );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ pDocSh->SetDocumentModified();
+ }
+ else
+ Sound::Beep();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::HideTable( SCTAB nTab )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ BOOL bUndo(pDoc->IsUndoEnabled());
+ SCTAB nVisible = 0;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ ++nVisible;
+ }
+
+ if (nVisible > 1)
+ {
+ pDoc->SetVisible( nTab, FALSE );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, FALSE ) );
+ }
+
+ // Views updaten:
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
+
+ SetTabNo( nTab, TRUE );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ pDocSh->SetDocumentModified();
+ }
+ else
+ Sound::Beep();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
+{
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ const sal_Unicode* pChar = rStr.GetBuffer();
+ ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
+ SvxFontItem aFontItem( rFont.GetFamily(),
+ rFont.GetName(),
+ rFont.GetStyleName(),
+ rFont.GetPitch(),
+ rFont.GetCharSet(),
+ ATTR_FONT );
+
+ // if string contains WEAK characters, set all fonts
+ BYTE nScript;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasStringWeakCharacters( rStr ) )
+ nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ else
+ nScript = pDoc->GetStringScriptType( rStr );
+
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
+ aSetItem.PutItemForScriptType( nScript, aFontItem );
+ ApplyUserItemSet( aSetItem.GetItemSet() );
+
+ while ( *pChar )
+ pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
+ const SvxBorderLine* pDestLine,
+ const SvxBorderLine* pSrcLine,
+ BOOL bColor )
+{
+ if ( pSrcLine && pDestLine )
+ {
+ if ( bColor )
+ {
+ rLine.SetColor ( pSrcLine->GetColor() );
+ rLine.SetOutWidth ( pDestLine->GetOutWidth() );
+ rLine.SetInWidth ( pDestLine->GetInWidth() );
+ rLine.SetDistance ( pDestLine->GetDistance() );
+ }
+ else
+ {
+ rLine.SetColor ( pDestLine->GetColor() );
+ rLine.SetOutWidth ( pSrcLine->GetOutWidth() );
+ rLine.SetInWidth ( pSrcLine->GetInWidth() );
+ rLine.SetDistance ( pSrcLine->GetDistance() );
+ }
+ }
+}
+
+
+#define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
+ pBoxLine = aBoxItem.Get##LINE(); \
+ if ( pBoxLine ) \
+ { \
+ if ( pLine ) \
+ { \
+ UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
+ aBoxItem.SetLine( &aLine, BOXLINE ); \
+ } \
+ else \
+ aBoxItem.SetLine( NULL, BOXLINE ); \
+ }
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
+ BOOL bColorOnly )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScPatternAttr* pSelAttrs = GetSelectionPattern();
+ const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
+
+ const SfxPoolItem* pBorderAttr = NULL;
+ SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, TRUE, &pBorderAttr );
+
+ const SfxPoolItem* pTLBRItem = 0;
+ SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, TRUE, &pTLBRItem );
+
+ const SfxPoolItem* pBLTRItem = 0;
+ SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, TRUE, &pBLTRItem );
+
+ // any of the lines visible?
+ if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
+ {
+ // none of the lines don't care?
+ if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
+ {
+ SfxItemSet* pOldSet = new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ SfxItemSet* pNewSet = new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ //------------------------------------------------------------
+ const SvxBorderLine* pBoxLine = NULL;
+ SvxBorderLine aLine;
+
+ // hier wird die pBoxLine benutzt:
+
+ if( pBorderAttr )
+ {
+ SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+
+ SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
+ SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
+ SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
+ SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
+
+ aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
+ aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
+ aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
+
+ pOldSet->Put( *pBorderAttr );
+ pNewSet->Put( aBoxItem );
+ pNewSet->Put( aBoxInfoItem );
+ }
+
+ if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
+ {
+ SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
+ UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
+ aTLBRItem.SetLine( &aLine );
+ pOldSet->Put( *pTLBRItem );
+ pNewSet->Put( aTLBRItem );
+ }
+
+ if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
+ {
+ SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
+ UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
+ aBLTRItem.SetLine( &aLine );
+ pOldSet->Put( *pBLTRItem );
+ pNewSet->Put( aBLTRItem );
+ }
+
+ ApplyAttributes( pNewSet, pOldSet );
+
+ delete pOldSet;
+ delete pNewSet;
+ }
+ else // if ( eItemState == SFX_ITEM_DONTCARE )
+ {
+ aFuncMark.MarkToMulti();
+ pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
+ }
+
+ ScRange aMarkRange;
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ pDocSh->UpdateOle( GetViewData() );
+ pDocSh->SetDocumentModified();
+ }
+}
+
+#undef SET_LINE_ATTRIBUTES
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ULONG nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo
+ SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
+
+ ApplyAttr( aItem ); // mit Paint und Undo...
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetValidation( const ScValidationData& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ULONG nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo
+ SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
+
+ ApplyAttr( aItem ); // mit Paint und Undo...
+}
+
+
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
new file mode 100644
index 000000000000..24fab9ac2eba
--- /dev/null
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -0,0 +1,1789 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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"
+
+
+
+//----------------------------------------------------------------------------
+
+#define _SV_NOXSOUND
+
+#ifdef WIN
+ #define _MENUBTN_HXX
+#endif
+
+#define _BASE_DLGS_HXX
+#define _BIGINT_HXX
+#define _CACHESTR_HXX
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _CTRLTOOL_HXX
+#define _DLGCFG_HXX
+#define _DYNARR_HXX
+#define _EXTATTR_HXX
+#define _FILDLG_HXX
+#define _FONTDLG_HXX
+#define _FRM3D_HXX
+#define _INTRO_HXX
+#define _ISETBWR_HXX
+#define _NO_SVRTF_PARSER_HXX
+#define _MACRODLG_HXX
+#define _MODALDLG_HXX
+#define _MOREBUTTON_HXX
+#define _OUTLINER_HXX
+//#define _PRNDLG_HXX
+//#define _POLY_HXX
+#define _PVRWIN_HXX
+//#define _QUEUE_HXX
+#define _RULER_HXX
+#define _SCRWIN_HXX
+#define _SETBRW_HXX
+//#define _STACK_HXX
+//#define _STATUS_HXX ***
+#define _STDCTRL_HXX
+#define _STDMENU_HXX
+//#define _TAB_HXX
+#define _TABBAR_HXX
+#define _TREELIST_HXX
+#define _VALUESET_HXX
+#define _VCATTR_HXX
+#define _VCBRW_HXX
+#define _VCTRLS_HXX
+#define _VCSBX_HXX
+#define _VCONT_HXX
+#define _VDRWOBJ_HXX
+
+//#define _SELENG_HXX
+//#define _SOUND_HXX
+//#define _SYSDLG_HXX
+
+
+
+
+#define _PASSWD_HXX
+
+#define _SFX_DOCFILE_HXX
+//#define _SFX_DOCFILT_HXX
+#define _SFX_DOCINF_HXX
+#define _SFX_DOCSH_HXX
+//#define _SFXDOCFILT_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFXDOCSH_HXX
+#define _SFX_PRNMON_HXX
+#define _SFX_RESMGR_HXX
+#define _SFX_TEMPLDLG_HXX
+//#define _SFXAPPWIN_HXX
+#define _SFXBASIC_HXX
+#define _SFXCTRLITEM
+#define _SFXDLGCFG_HXX
+//#define _SFXDISPATCH_HXX
+#define _SFXFILEDLG_HXX
+//#define _SFXIMGMGR_HXX
+#define _SFXIPFRM_HXX
+#define _SFX_MACRO_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXMULTISEL_HXX
+//#define _SFXMSG_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXOBJFACE_HXX
+#define _SFXOBJFAC_HXX
+#define _SFX_SAVEOPT_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXSTBMGR_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXTBXMGR_HXX
+
+#define _SI_HXX
+//#define _SI_DLL_HXX
+//#define _SIDLL_HXX
+//#define _SI_NOITEMS
+//#define _SI_NOOTHERFORMS
+//#define _SI_NOSBXCONTROLS
+//#define _SINOSBXCONTROLS
+//#define _SI_NODRW
+//#define _SI_NOCONTROL
+
+#define _SVBOXITM_HXX
+#define _SVCONTNR_HXX //
+
+#define _SDR_NOTRANSFORM
+
+#define _SVDRAG_HXX
+#define _SVINCVW_HXX
+//#define _SV_MULTISEL_HXX
+#define _SVRTV_HXX
+#define _SVTABBX_HXX
+#define _SVTREEBOX_HXX
+#define _SVTREELIST_HXX
+
+#define _SVX_DAILDLL_HXX
+#define _SVX_HYPHEN_HXX
+#define _SVX_IMPGRF_HXX
+#define _SVX_LAYCTRL_HXX
+#define _SVX_OPTITEMS_HXX
+#define _SVX_OPTGERL_HXX
+#define _SVX_OPTSAVE_HXX
+#define _SVX_OPTSPELL_HXX
+#define _SVX_OPTPATH_HXX
+#define _SVX_OPTLINGU_HXX
+#define _SVX_RULER_HXX
+#define _SVX_RULRITEM_HXX
+#define _SVX_SELCTRL_HXX
+#define _SVX_SPLWRAP_HXX
+#define _SVX_SPLDLG_HXX
+#define _SVX_STDDLG_HXX
+#define _SVX_THESDLG_HXX
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/dbexch.hrc>
+#include <svx/svdetc.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/stritem.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/urlbmk.hxx>
+#include <sot/clsids.hxx>
+#include <sot/formats.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/urlobj.hxx>
+#include <sot/exchange.hxx>
+#include <memory>
+
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "dociter.hxx"
+#include "viewfunc.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "undoblk.hxx"
+#include "refundo.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "impex.hxx" // Sylk-ID fuer CB
+#include "chgtrack.hxx"
+#include "waitoff.hxx"
+#include "scmod.hxx"
+#include "sc.hrc"
+#include "inputopt.hxx"
+#include "warnbox.hxx"
+#include "drwlayer.hxx"
+#include "editable.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "docuno.hxx"
+#include "clipparam.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA ---------------------------------------------------------------
+
+
+//============================================================================
+
+// GlobalName der Writer-DocShell kommt jetzt aus comphelper/classids.hxx
+
+//----------------------------------------------------------------------------
+// C U T
+
+void ScViewFunc::CutToClip( ScDocument* pClipDoc, BOOL bIncludeObjects )
+{
+ UpdateInputLine();
+
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable()) // selection editable?
+ {
+ ErrorMessage( aTester.GetMessageId() );
+ return;
+ }
+
+ ScRange aRange; // zu loeschender Bereich
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ const BOOL bRecord(pDoc->IsUndoEnabled()); // Undo/Redo
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) // mark the range if not marked yet
+ {
+ DoneBlockMode();
+ InitOwnBlockMode();
+ rMark.SetMarkArea( aRange );
+ MarkDataChanged();
+ }
+
+ CopyToClip( pClipDoc, TRUE, FALSE, bIncludeObjects ); // Ab ins Clipboard
+
+ ScAddress aOldEnd( aRange.aEnd ); // Zusammengefasste Zellen im Bereich?
+ pDoc->ExtendMerge( aRange, TRUE );
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndoSelected( pDoc, rMark );
+ // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
+ ScRange aCopyRange = aRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(pDoc->GetTableCount()-1);
+ pDoc->CopyToDocument( aCopyRange, (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS, FALSE, pUndoDoc );
+ pDoc->BeginDrawUndo();
+ }
+
+ USHORT nExtFlags = 0;
+ pDocSh->UpdatePaintExt( nExtFlags, aRange );
+
+ HideCursor(); // Cursor aendert sich !
+
+ rMark.MarkToMulti();
+ pDoc->DeleteSelection( IDF_ALL, rMark );
+ if ( bIncludeObjects )
+ pDoc->DeleteObjectsInSelection( rMark );
+ rMark.MarkToSimple();
+
+ if ( !AdjustRowHeight( aRange.aStart.Row(), aRange.aEnd.Row() ) )
+ pDocSh->PostPaint( aRange, PAINT_GRID, nExtFlags );
+
+ if ( bRecord ) // erst jetzt ist Draw-Undo verfuegbar
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoCut( pDocSh, aRange, aOldEnd, rMark, pUndoDoc ) );
+
+ aModificator.SetDocumentModified();
+ ShowCursor(); // Cursor aendert sich !
+ pDocSh->UpdateOle(GetViewData());
+
+ CellContentChanged();
+ }
+ else
+ ErrorMessage( STR_NOMULTISELECT );
+}
+
+
+//----------------------------------------------------------------------------
+// C O P Y
+
+BOOL ScViewFunc::CopyToClip( ScDocument* pClipDoc, BOOL bCut, BOOL bApi, BOOL bIncludeObjects, BOOL bStopEdit )
+{
+ BOOL bDone = FALSE;
+ if ( bStopEdit )
+ UpdateInputLine();
+
+ ScRange aRange;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aRange );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
+ {
+ if ( !pDoc->HasSelectedBlockMatrixFragment(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ rMark ) )
+ {
+ BOOL bSysClip = FALSE;
+ if ( !pClipDoc ) // no clip doc specified
+ {
+ pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj)
+ bSysClip = TRUE; // and copy into system
+ }
+
+ if ( !bCut )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+ }
+
+ if ( bSysClip && bIncludeObjects )
+ {
+ BOOL bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark );
+ // update ScGlobal::pDrawClipDocShellRef
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+ }
+
+ ScClipParam aClipParam(aRange, bCut);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, bIncludeObjects);
+ if (bSysClip)
+ {
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ ScGlobal::SetClipDocName( pDoc->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME ) );
+ }
+ pClipDoc->ExtendMerge( aRange, TRUE );
+
+ if (bSysClip)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
+ }
+
+ bDone = TRUE;
+ }
+ else
+ {
+ if (!bApi)
+ ErrorMessage(STR_MATRIXFRAGMENTERR);
+ }
+ }
+ else if (eMarkType == SC_MARK_MULTI)
+ {
+ bool bSuccess = false;
+ ScClipParam aClipParam;
+ aClipParam.mbCutMode = false;
+ rMark.MarkToSimple();
+ rMark.FillRangeListWithMarks(&aClipParam.maRanges, false);
+
+ do
+ {
+ if (bCut)
+ // We con't support cutting of multi-selections.
+ break;
+
+ if (pClipDoc)
+ // TODO: What's this for?
+ break;
+
+ ::std::auto_ptr<ScDocument> pDocClip(new ScDocument(SCDOCMODE_CLIP));
+
+ // Check for geometrical feasibility of the ranges.
+ bool bValidRanges = true;
+ ScRangePtr p = aClipParam.maRanges.First();
+ SCCOL nPrevColDelta = 0;
+ SCROW nPrevRowDelta = 0;
+ SCCOL nPrevCol = p->aStart.Col();
+ SCROW nPrevRow = p->aStart.Row();
+ SCCOL nPrevColSize = p->aEnd.Col() - p->aStart.Col() + 1;
+ SCROW nPrevRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
+ for (p = aClipParam.maRanges.Next(); p; p = aClipParam.maRanges.Next())
+ {
+ if (pDoc->HasSelectedBlockMatrixFragment(
+ p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark))
+ {
+ if (!bApi)
+ ErrorMessage(STR_MATRIXFRAGMENTERR);
+ return false;
+ }
+
+ SCCOL nColDelta = p->aStart.Col() - nPrevCol;
+ SCROW nRowDelta = p->aStart.Row() - nPrevRow;
+
+ if ((nColDelta && nRowDelta) || (nPrevColDelta && nRowDelta) || (nPrevRowDelta && nColDelta))
+ {
+ bValidRanges = false;
+ break;
+ }
+
+ if (aClipParam.meDirection == ScClipParam::Unspecified)
+ {
+ if (nColDelta)
+ aClipParam.meDirection = ScClipParam::Column;
+ if (nRowDelta)
+ aClipParam.meDirection = ScClipParam::Row;
+ }
+
+ SCCOL nColSize = p->aEnd.Col() - p->aStart.Col() + 1;
+ SCROW nRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
+
+ if (aClipParam.meDirection == ScClipParam::Column && nRowSize != nPrevRowSize)
+ {
+ // column-oriented ranges must have identical row size.
+ bValidRanges = false;
+ break;
+ }
+ if (aClipParam.meDirection == ScClipParam::Row && nColSize != nPrevColSize)
+ {
+ // likewise, row-oriented ranges must have identical
+ // column size.
+ bValidRanges = false;
+ break;
+ }
+
+ nPrevCol = p->aStart.Col();
+ nPrevRow = p->aStart.Row();
+ nPrevColDelta = nColDelta;
+ nPrevRowDelta = nRowDelta;
+ nPrevColSize = nColSize;
+ nPrevRowSize = nRowSize;
+ }
+ if (!bValidRanges)
+ break;
+
+ pDoc->CopyToClip(aClipParam, pDocClip.get(), &rMark, false, false, bIncludeObjects);
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
+ }
+
+ bSuccess = true;
+ }
+ while (false);
+
+ if (!bSuccess && !bApi)
+ ErrorMessage(STR_NOMULTISELECT);
+
+ bDone = bSuccess;
+ }
+ else
+ {
+ if (!bApi)
+ ErrorMessage(STR_NOMULTISELECT);
+ }
+
+ return bDone;
+}
+
+ScTransferObj* ScViewFunc::CopyToTransferable()
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !pDoc->HasSelectedBlockMatrixFragment(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ rMark ) )
+ {
+ ScDocument *pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj)
+
+ BOOL bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark );
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+
+ ScClipParam aClipParam(aRange, false);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, true);
+
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+ pClipDoc->ExtendMerge( aRange, TRUE );
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ return pTransferObj;
+ }
+ }
+
+ return NULL;
+}
+
+//----------------------------------------------------------------------------
+// P A S T E
+
+void ScViewFunc::PasteDraw()
+{
+ ScViewData* pViewData = GetViewData();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ Window* pWin = GetActiveWin();
+ Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY,
+ pViewData->GetActivePart() ) );
+ ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
+ if (pDrawClip)
+ PasteDraw( aPos, pDrawClip->GetModel(), FALSE,
+ pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
+}
+
+void ScViewFunc::PasteFromSystem()
+{
+ UpdateInputLine();
+
+ Window* pWin = GetActiveWin();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
+
+ if (pOwnClip)
+ {
+ // #129384# keep a reference in case the clipboard is changed during PasteFromClip
+ uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
+ PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
+ TRUE ); // allow warning dialog
+ }
+ else if (pDrawClip)
+ PasteDraw();
+ else
+ {
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+
+// if (pClipObj.Is())
+ {
+ ULONG nBiff8 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff8")));
+ ULONG nBiff5 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff5")));
+
+ // als erstes SvDraw-Model, dann Grafik
+ // (Grafik darf nur bei einzelner Grafik drinstehen)
+
+ if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
+ {
+ // special case for tables from drawing
+ if( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ {
+ PasteFromSystem( FORMAT_RTF );
+ }
+ else
+ {
+ PasteFromSystem( SOT_FORMATSTR_ID_DRAWING );
+ }
+ }
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
+ PasteFromSystem( SOT_FORMATSTR_ID_SVXB );
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
+ {
+ // If it's a Writer object, insert RTF instead of OLE
+
+ BOOL bDoRtf = FALSE;
+ TransferableObjectDescriptor aObjDesc;
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) )
+ {
+ bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
+ aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
+ && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+ if ( bDoRtf )
+ PasteFromSystem( FORMAT_RTF );
+ else
+ PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ }
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE );
+ // the following format can not affect scenario from #89579#
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
+ // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
+ else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
+ PasteFromSystem(nBiff8);
+ else if (aDataHelper.HasFormat(nBiff5))
+ PasteFromSystem(nBiff5);
+ else if (aDataHelper.HasFormat(FORMAT_RTF))
+ PasteFromSystem(FORMAT_RTF);
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
+ PasteFromSystem(SOT_FORMATSTR_ID_HTML);
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
+ PasteFromSystem(SOT_FORMATSTR_ID_HTML_SIMPLE);
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
+ PasteFromSystem(SOT_FORMATSTR_ID_SYLK);
+ else if (aDataHelper.HasFormat(FORMAT_STRING))
+ PasteFromSystem(FORMAT_STRING);
+ else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
+ PasteFromSystem(FORMAT_GDIMETAFILE);
+ else if (aDataHelper.HasFormat(FORMAT_BITMAP))
+ PasteFromSystem(FORMAT_BITMAP);
+ // #89579# xxx_OLE formats come last, like in SotExchange tables
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE );
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE_OLE );
+// else
+// ErrorMessage(STR_PASTE_ERROR);
+ }
+// else
+// ErrorMessage(STR_PASTE_ERROR);
+ }
+
+ // keine Fehlermeldung, weil SID_PASTE in der idl das FastCall-Flag hat,
+ // also auch gerufen wird, wenn nichts im Clipboard steht (#42531#)
+}
+
+void ScViewFunc::PasteFromTransferable( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
+{
+ ScTransferObj *pOwnClip=0;
+ ScDrawTransferObj *pDrawClip=0;
+ uno::Reference<lang::XUnoTunnel> xTunnel( rxTransferable, uno::UNO_QUERY );
+ if ( xTunnel.is() )
+ {
+ sal_Int64 nHandle = xTunnel->getSomething( ScTransferObj::getUnoTunnelId() );
+ if ( nHandle )
+ pOwnClip = (ScTransferObj*) (sal_IntPtr) nHandle;
+ else
+ {
+ nHandle = xTunnel->getSomething( ScDrawTransferObj::getUnoTunnelId() );
+ if ( nHandle )
+ pDrawClip = (ScDrawTransferObj*) (sal_IntPtr) nHandle;
+ }
+ }
+
+ if (pOwnClip)
+ {
+ PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
+ PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
+ TRUE ); // allow warning dialog
+ }
+ else if (pDrawClip)
+ {
+ ScViewData* pViewData = GetViewData();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ Window* pWin = GetActiveWin();
+ Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY, pViewData->GetActivePart() ) );
+ PasteDraw( aPos, pDrawClip->GetModel(), FALSE, pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
+ }
+ else
+ {
+ TransferableDataHelper aDataHelper( rxTransferable );
+ {
+ ULONG nBiff8 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff8")));
+ ULONG nBiff5 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff5")));
+ ULONG nFormatId = 0;
+ // als erstes SvDraw-Model, dann Grafik
+ // (Grafik darf nur bei einzelner Grafik drinstehen)
+
+ if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
+ nFormatId = SOT_FORMATSTR_ID_DRAWING;
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
+ nFormatId = SOT_FORMATSTR_ID_SVXB;
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
+ {
+ // If it's a Writer object, insert RTF instead of OLE
+ BOOL bDoRtf = FALSE;
+ TransferableObjectDescriptor aObjDesc;
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) )
+ {
+ bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
+ aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
+ && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+ if ( bDoRtf )
+ nFormatId = FORMAT_RTF;
+ else
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
+ }
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
+ // the following format can not affect scenario from #89579#
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
+ nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
+ // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
+ else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
+ nFormatId = nBiff8;
+ else if (aDataHelper.HasFormat(nBiff5))
+ nFormatId = nBiff5;
+ else if (aDataHelper.HasFormat(FORMAT_RTF))
+ nFormatId = FORMAT_RTF;
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
+ nFormatId = SOT_FORMATSTR_ID_HTML;
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
+ nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
+ nFormatId = SOT_FORMATSTR_ID_SYLK;
+ else if (aDataHelper.HasFormat(FORMAT_STRING))
+ nFormatId = FORMAT_STRING;
+ else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
+ nFormatId = FORMAT_GDIMETAFILE;
+ else if (aDataHelper.HasFormat(FORMAT_BITMAP))
+ nFormatId = FORMAT_BITMAP;
+ // #89579# xxx_OLE formats come last, like in SotExchange tables
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
+ else
+ return;
+
+ PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
+ GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ NULL, FALSE, FALSE );
+ }
+ }
+}
+
+BOOL ScViewFunc::PasteFromSystem( ULONG nFormatId, BOOL bApi )
+{
+ UpdateInputLine();
+
+ BOOL bRet = TRUE;
+ Window* pWin = GetActiveWin();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ if ( nFormatId == 0 && pOwnClip )
+ {
+ // #129384# keep a reference in case the clipboard is changed during PasteFromClip
+ uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
+ PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
+ !bApi ); // allow warning dialog
+ }
+ else
+ {
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+ if ( !aDataHelper.GetTransferable().is() )
+ return FALSE;
+
+ bRet = PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
+ GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ NULL, FALSE, !bApi ); // allow warning dialog
+
+ if ( !bRet && !bApi )
+ ErrorMessage(STR_PASTE_ERROR);
+ }
+ return bRet;
+}
+
+
+//----------------------------------------------------------------------------
+// P A S T E
+
+BOOL ScViewFunc::PasteOnDrawObject( const uno::Reference<datatransfer::XTransferable>& rxTransferable,
+ SdrObject* pHitObj, BOOL bLink )
+{
+ BOOL bRet = FALSE;
+ if ( bLink )
+ {
+ TransferableDataHelper aDataHelper( rxTransferable );
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
+ {
+ SotStorageStreamRef xStm;
+ if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
+ {
+ Graphic aGraphic;
+ *xStm >> aGraphic;
+ bRet = ApplyGraphicToObject( pHitObj, aGraphic );
+ }
+ }
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
+ {
+ GDIMetaFile aMtf;
+ if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
+ bRet = ApplyGraphicToObject( pHitObj, Graphic(aMtf) );
+ }
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
+ {
+ Bitmap aBmp;
+ if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) )
+ bRet = ApplyGraphicToObject( pHitObj, Graphic(aBmp) );
+ }
+ }
+ else
+ {
+ // ham' wa noch nich
+ }
+ return bRet;
+}
+
+BOOL lcl_SelHasAttrib( ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rTabSelection, USHORT nMask )
+{
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( rTabSelection.GetTableSelect(nTab) && pDoc->HasAttrib( nCol1, nRow1, nTab, nCol2, nRow2, nTab, nMask ) )
+ return TRUE;
+ return FALSE;
+}
+
+//
+// Einfuegen auf Tabelle:
+//
+
+// internes Paste
+
+namespace {
+
+class CursorSwitcher
+{
+public:
+ CursorSwitcher(ScViewFunc* pViewFunc) :
+ mpViewFunc(pViewFunc)
+ {
+ mpViewFunc->HideCursor();
+ }
+
+ ~CursorSwitcher()
+ {
+ mpViewFunc->ShowCursor();
+ }
+private:
+ ScViewFunc* mpViewFunc;
+};
+
+bool lcl_checkDestRangeForOverwrite(const ScRange& rDestRange, const ScDocument* pDoc, const ScMarkData& rMark, Window* pParentWnd)
+{
+ bool bIsEmpty = true;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab < nTabCount && bIsEmpty; ++nTab)
+ {
+ if (!rMark.GetTableSelect(nTab))
+ continue;
+
+ bIsEmpty = pDoc->IsBlockEmpty(nTab, rDestRange.aStart.Col(), rDestRange.aStart.Row(),
+ rDestRange.aEnd.Col(), rDestRange.aEnd.Row());
+ }
+
+ if (!bIsEmpty)
+ {
+ ScReplaceWarnBox aBox(pParentWnd);
+ if (aBox.Execute() != RET_YES)
+ {
+ // changing the configuration is within the ScReplaceWarnBox
+ return false;
+ }
+ }
+ return true;
+}
+
+}
+
+BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc,
+ USHORT nFunction, BOOL bSkipEmpty,
+ BOOL bTranspose, BOOL bAsLink,
+ InsCellCmd eMoveMode, USHORT nUndoExtraFlags,
+ BOOL bAllowDialogs )
+{
+ if (!pClipDoc)
+ {
+ DBG_ERROR("PasteFromClip: pClipDoc=0 not allowed");
+ return FALSE;
+ }
+
+ // fuer Undo etc. immer alle oder keine Inhalte sichern
+ USHORT nContFlags = IDF_NONE;
+ if (nFlags & IDF_CONTENTS)
+ nContFlags |= IDF_CONTENTS;
+ if (nFlags & IDF_ATTRIB)
+ nContFlags |= IDF_ATTRIB;
+ // evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
+ USHORT nUndoFlags = nContFlags;
+ if (nUndoExtraFlags & IDF_ATTRIB)
+ nUndoFlags |= IDF_ATTRIB;
+ // do not copy note captions into undo document
+ nUndoFlags |= IDF_NOCAPTIONS;
+
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ if (rClipParam.isMultiRange())
+ return PasteMultiRangesFromClip(
+ nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
+ eMoveMode, nContFlags, nUndoFlags);
+
+ BOOL bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
+ BOOL bIncludeFiltered = bCutMode;
+
+ // paste drawing: also if IDF_NOTE is set (to create drawing layer for note captions)
+ BOOL bPasteDraw = ( pClipDoc->GetDrawLayer() && ( nFlags & (IDF_OBJECTS|IDF_NOTE) ) );
+
+ ScDocShellRef aTransShellRef; // for objects in xTransClip - must remain valid as long as xTransClip
+ ScDocument* pOrigClipDoc = NULL;
+ ::std::auto_ptr< ScDocument > xTransClip;
+ if ( bTranspose )
+ {
+ SCCOL nX;
+ SCROW nY;
+ // include filtered rows until TransposeClip can skip them
+ bIncludeFiltered = TRUE;
+ pClipDoc->GetClipArea( nX, nY, TRUE );
+ if ( nY > static_cast<sal_Int32>(MAXCOL) ) // zuviele Zeilen zum Transponieren
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return FALSE;
+ }
+ pOrigClipDoc = pClipDoc; // fuer Referenzen
+
+ if ( bPasteDraw )
+ {
+ aTransShellRef = new ScDocShell; // DocShell needs a Ref immediately
+ aTransShellRef->DoInitNew(NULL);
+ }
+ ScDrawLayer::SetGlobalDrawPersist(aTransShellRef);
+
+ xTransClip.reset( new ScDocument( SCDOCMODE_CLIP ));
+ pClipDoc->TransposeClip( xTransClip.get(), nFlags, bAsLink );
+ pClipDoc = xTransClip.get();
+
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+ }
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ SCCOL nClipSizeX;
+ SCROW nClipSizeY;
+ pClipDoc->GetClipArea( nClipSizeX, nClipSizeY, TRUE ); // size in clipboard doc
+
+ // size in target doc: include filtered rows only if CutMode is set
+ SCCOL nDestSizeX;
+ SCROW nDestSizeY;
+ pClipDoc->GetClipArea( nDestSizeX, nDestSizeY, bIncludeFiltered );
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
+ const BOOL bRecord(pDoc->IsUndoEnabled());
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScRange aMarkRange;
+ ScMarkData aFilteredMark( rMark); // local copy for all modifications
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange, aFilteredMark);
+ bool bMarkIsFiltered = (eMarkType == SC_MARK_SIMPLE_FILTERED);
+ bool bNoPaste = ((eMarkType != SC_MARK_SIMPLE && !bMarkIsFiltered) ||
+ (bMarkIsFiltered && (eMoveMode != INS_NONE || bAsLink)));
+ if (!bNoPaste && !rMark.IsMarked())
+ {
+ // Create a selection with clipboard row count and check that for
+ // filtered.
+ nStartCol = GetViewData()->GetCurX();
+ nStartRow = GetViewData()->GetCurY();
+ nStartTab = GetViewData()->GetTabNo();
+ nEndCol = nStartCol + nDestSizeX;
+ nEndRow = nStartRow + nDestSizeY;
+ nEndTab = nStartTab;
+ aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ if (ScViewUtil::HasFiltered( aMarkRange, pDoc))
+ {
+ bMarkIsFiltered = true;
+ // Fit to clipboard's row count unfiltered rows. If there is no
+ // fit assume that pasting is not possible. Note that nDestSizeY is
+ // size-1 (difference).
+ if (!ScViewUtil::FitToUnfilteredRows( aMarkRange, pDoc, nDestSizeY+1))
+ bNoPaste = true;
+ }
+ aFilteredMark.SetMarkArea( aMarkRange);
+ }
+ if (bNoPaste)
+ {
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return FALSE;
+ }
+
+ SCROW nUnfilteredRows = aMarkRange.aEnd.Row() - aMarkRange.aStart.Row() + 1;
+ ScRangeList aRangeList;
+ if (bMarkIsFiltered)
+ {
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc);
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, FALSE);
+ nUnfilteredRows = 0;
+ for (ScRange* p = aRangeList.First(); p; p = aRangeList.Next())
+ {
+ nUnfilteredRows += p->aEnd.Row() - p->aStart.Row() + 1;
+ }
+#if 0
+ /* This isn't needed but could be a desired restriction. */
+ // For filtered, destination rows have to be an exact multiple of
+ // source rows. Note that nDestSizeY is size-1 (difference), so
+ // nDestSizeY==0 fits always.
+ if ((nUnfilteredRows % (nDestSizeY+1)) != 0)
+ {
+ /* FIXME: this should be a more descriptive error message then. */
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return FALSE;
+ }
+#endif
+ }
+
+ SCCOL nMarkAddX = 0;
+ SCROW nMarkAddY = 0;
+
+ // Also for a filtered selection the area is used, for undo et al.
+ if ( aFilteredMark.IsMarked() || bMarkIsFiltered )
+ {
+ aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ SCCOL nBlockAddX = nEndCol-nStartCol;
+ SCROW nBlockAddY = nEndRow-nStartRow;
+
+ // #58422# Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
+ // als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
+
+ // ClipSize is not size, but difference
+ if ( ( nBlockAddX != 0 && nBlockAddX < nDestSizeX ) ||
+ ( nBlockAddY != 0 && nBlockAddY < nDestSizeY ) ||
+ ( bMarkIsFiltered && nUnfilteredRows < nDestSizeY+1 ) )
+ {
+ ScWaitCursorOff aWaitOff( GetFrameWin() );
+ String aMessage = ScGlobal::GetRscString( STR_PASTE_BIGGER );
+ QueryBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO), aMessage );
+ if ( aBox.Execute() != RET_YES )
+ {
+ return FALSE;
+ }
+ }
+
+ if (nBlockAddX > nDestSizeX)
+ nMarkAddX = nBlockAddX - nDestSizeX; // fuer Merge-Test
+ else
+ nEndCol = nStartCol + nDestSizeX;
+
+ if (nBlockAddY > nDestSizeY)
+ nMarkAddY = nBlockAddY - nDestSizeY; // fuer Merge-Test
+ else
+ {
+ nEndRow = nStartRow + nDestSizeY;
+ if (bMarkIsFiltered || nEndRow > aMarkRange.aEnd.Row())
+ {
+ // Same as above if nothing was marked: re-fit selection to
+ // unfiltered rows. Extending the selection actually may
+ // introduce filtered rows where there weren't any before, so
+ // we also need to test for that.
+ aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ if (bMarkIsFiltered || ScViewUtil::HasFiltered( aMarkRange, pDoc))
+ {
+ bMarkIsFiltered = true;
+ // Worst case: all rows up to the end of the sheet are filtered.
+ if (!ScViewUtil::FitToUnfilteredRows( aMarkRange, pDoc, nDestSizeY+1))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return FALSE;
+ }
+ }
+ aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ aFilteredMark.SetMarkArea( aMarkRange);
+ if (bMarkIsFiltered)
+ {
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc);
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, TRUE);
+ }
+ }
+ }
+ }
+ else
+ {
+ nStartCol = GetViewData()->GetCurX();
+ nStartRow = GetViewData()->GetCurY();
+ nStartTab = GetViewData()->GetTabNo();
+ nEndCol = nStartCol + nDestSizeX;
+ nEndRow = nStartRow + nDestSizeY;
+ nEndTab = nStartTab;
+ }
+
+ bool bOffLimits = !ValidCol(nEndCol) || !ValidRow(nEndRow);
+
+ // Zielbereich, wie er angezeigt wird:
+ ScRange aUserRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
+
+ // Sollen Zellen eingefuegt werden?
+ // (zu grosse nEndCol/nEndRow werden weiter unten erkannt)
+ BOOL bInsertCells = ( eMoveMode != INS_NONE && !bOffLimits );
+ if ( bInsertCells )
+ {
+ // #94115# Instead of EnterListAction, the paste undo action is merged into the
+ // insert action, so Repeat can insert the right cells
+
+ MarkRange( aUserRange ); // wird vor CopyFromClip sowieso gesetzt
+
+ // #72930# CutMode is reset on insertion of cols/rows but needed again on cell move
+ BOOL bCut = pClipDoc->IsCutMode();
+ if (!InsertCells( eMoveMode, bRecord, TRUE )) // is inserting possible?
+ {
+ return FALSE;
+ // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
+ // its undo action on failure, so no undo handling is needed here
+ }
+ if ( bCut )
+ pClipDoc->SetCutMode( bCut );
+ }
+ else if (!bOffLimits)
+ {
+ BOOL bAskIfNotEmpty = bAllowDialogs &&
+ ( nFlags & IDF_CONTENTS ) &&
+ nFunction == PASTE_NOFUNC &&
+ SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
+ if ( bAskIfNotEmpty )
+ {
+ if (!lcl_checkDestRangeForOverwrite(aUserRange, pDoc, aFilteredMark, GetViewData()->GetDialogParent()))
+ return false;
+ }
+ }
+
+ SCCOL nClipStartX; // Clipboard-Bereich erweitern
+ SCROW nClipStartY;
+ pClipDoc->GetClipStart( nClipStartX, nClipStartY );
+ SCCOL nUndoEndCol = nClipStartX + nClipSizeX;
+ SCROW nUndoEndRow = nClipStartY + nClipSizeY; // end of source area in clipboard document
+ BOOL bClipOver = FALSE;
+ // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
+ // The same end column/row can be used for all calls because the clip doc doesn't contain
+ // content outside the clip area.
+ for (SCTAB nClipTab=0; nClipTab<=MAXTAB; nClipTab++)
+ if ( pClipDoc->HasTable(nClipTab) )
+ if ( pClipDoc->ExtendMerge( nClipStartX,nClipStartY, nUndoEndCol,nUndoEndRow, nClipTab, FALSE ) )
+ bClipOver = TRUE;
+ nUndoEndCol -= nClipStartX + nClipSizeX;
+ nUndoEndRow -= nClipStartY + nClipSizeY; // now contains only the difference added by ExtendMerge
+ nUndoEndCol = sal::static_int_cast<SCCOL>( nUndoEndCol + nEndCol );
+ nUndoEndRow = sal::static_int_cast<SCROW>( nUndoEndRow + nEndRow ); // destination area, expanded for merged cells
+
+// if (nUndoEndCol < nEndCol) nUndoEndCol = nEndCol;
+// if (nUndoEndRow < nEndRow) nUndoEndRow = nEndRow;
+
+// nUndoEndCol += nMarkAddX;
+// nUndoEndRow += nMarkAddY;
+
+ if (nUndoEndCol>MAXCOL || nUndoEndRow>MAXROW)
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return FALSE;
+ }
+
+ pDoc->ExtendMergeSel( nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, FALSE );
+
+ // Test auf Zellschutz
+
+ ScEditableTester aTester( pDoc, nStartTab, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return FALSE;
+ }
+
+ //! Test auf Ueberlappung
+ //! nur wirkliche Schnittmenge testen !!!!!!!
+
+ // pDoc->HasCommonAttr( StartCol,nStartRow, nUndoEndCol,nUndoEndRow, nStartTab,
+ // pClipDoc, nClipStartX, nClipStartY );
+
+ ScDocFunc& rDocFunc = pDocSh->GetDocFunc();
+ if ( bRecord )
+ {
+ String aUndo = ScGlobal::GetRscString( pClipDoc->IsCutMode() ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pUndoMgr->EnterListAction( aUndo, aUndo );
+ }
+
+ if (bClipOver)
+ if (lcl_SelHasAttrib( pDoc, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, HASATTR_OVERLAPPED ))
+ { // "Cell merge not possible if cells already merged"
+ ScDocAttrIterator aIter( pDoc, nStartTab, nStartCol, nStartRow, nUndoEndCol, nUndoEndRow );
+ const ScPatternAttr* pPattern = NULL;
+ const ScMergeAttr* pMergeFlag = NULL;
+ const ScMergeFlagAttr* pMergeFlagAttr = NULL;
+ SCCOL nCol = -1;
+ SCROW nRow1 = -1;
+ SCROW nRow2 = -1;
+ while ( ( pPattern = aIter.GetNext( nCol, nRow1, nRow2 ) ) != NULL )
+ {
+ pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
+ pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ if( ( pMergeFlag && pMergeFlag->IsMerged() ) || ( pMergeFlagAttr && pMergeFlagAttr->IsOverlapped() ) )
+ {
+ ScRange aRange(nCol, nRow1, nStartTab);
+ pDoc->ExtendOverlapped(aRange);
+ pDoc->ExtendMerge(aRange, TRUE, TRUE);
+ rDocFunc.UnmergeCells(aRange, bRecord, TRUE);
+ }
+ }
+ }
+
+ if ( !bCutMode )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+ }
+
+ BOOL bColInfo = ( nStartRow==0 && nEndRow==MAXROW );
+ BOOL bRowInfo = ( nStartCol==0 && nEndCol==MAXCOL );
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRefUndoDoc = NULL;
+ ScDocument* pRedoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndoSelected( pDoc, aFilteredMark, bColInfo, bRowInfo );
+
+ // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pDoc->CopyToDocument( nStartCol, nStartRow, 0, nUndoEndCol, nUndoEndRow, nTabCount-1,
+ nUndoFlags, FALSE, pUndoDoc );
+
+ if ( bCutMode )
+ {
+ pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE );
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+ }
+
+ USHORT nExtFlags = 0;
+ pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab ); // content before the change
+
+ if (GetViewData()->IsActive())
+ {
+ DoneBlockMode();
+ InitOwnBlockMode();
+ }
+ rMark.SetMarkArea( aUserRange );
+ MarkDataChanged();
+
+ HideCursor(); // Cursor aendert sich !
+
+ //
+ // Aus Clipboard kopieren,
+ // wenn gerechnet werden soll, Originaldaten merken
+ //
+
+ ScDocument* pMixDoc = NULL;
+ if ( bSkipEmpty || nFunction )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ {
+ pMixDoc = new ScDocument( SCDOCMODE_UNDO );
+ pMixDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ IDF_CONTENTS, FALSE, pMixDoc );
+ }
+ }
+
+ /* Make draw layer and start drawing undo.
+ - Needed before AdjustBlockHeight to track moved drawing objects.
+ - Needed before pDoc->CopyFromClip to track inserted note caption objects.
+ */
+ if ( bPasteDraw )
+ pDocSh->MakeDrawLayer();
+ if ( bRecord )
+ pDoc->BeginDrawUndo();
+
+ USHORT nNoObjFlags = nFlags & ~IDF_OBJECTS;
+ if (!bAsLink)
+ {
+ // copy normally (original range)
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags,
+ pRefUndoDoc, pClipDoc, TRUE, FALSE, bIncludeFiltered,
+ bSkipEmpty, (bMarkIsFiltered ? &aRangeList : NULL) );
+
+ // bei Transpose Referenzen per Hand anpassen
+ if ( bTranspose && bCutMode && (nFlags & IDF_CONTENTS) )
+ pDoc->UpdateTranspose( aUserRange.aStart, pOrigClipDoc, aFilteredMark, pRefUndoDoc );
+ }
+ else if (!bTranspose)
+ {
+ // copy with bAsLink=TRUE
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags, pRefUndoDoc, pClipDoc,
+ TRUE, TRUE, bIncludeFiltered, bSkipEmpty );
+ }
+ else
+ {
+ // alle Inhalte kopieren (im TransClipDoc stehen nur Formeln)
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, nContFlags, pRefUndoDoc, pClipDoc );
+ }
+
+ // skipped rows and merged cells don't mix
+ if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
+ rDocFunc.UnmergeCells( aUserRange, FALSE, TRUE );
+
+ pDoc->ExtendMergeSel( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, TRUE ); // Refresh
+ // und Bereich neu
+
+ if ( pMixDoc ) // Rechenfunktionen mit Original-Daten auszufuehren ?
+ {
+ pDoc->MixDocument( aUserRange, nFunction, bSkipEmpty, pMixDoc );
+ }
+ delete pMixDoc;
+
+ AdjustBlockHeight(); // update row heights before pasting objects
+
+ if ( nFlags & IDF_OBJECTS )
+ {
+ // Paste the drawing objects after the row heights have been updated.
+
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, IDF_OBJECTS, pRefUndoDoc, pClipDoc,
+ TRUE, FALSE, bIncludeFiltered );
+ }
+
+ //
+ //
+ //
+
+ pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab ); // content after the change
+
+
+ // ggf. Autofilter-Koepfe loeschen
+ if (bCutMode)
+ if (pDoc->RefreshAutoFilter( nClipStartX,nClipStartY, nClipStartX+nClipSizeX,
+ nClipStartY+nClipSizeY, nStartTab ))
+ pDocSh->PostPaint( nClipStartX,nClipStartY,nStartTab,
+ nClipStartX+nClipSizeX,nClipStartY,nStartTab,
+ PAINT_GRID );
+
+ ShowCursor(); // Cursor aendert sich !
+
+ //! Block-Bereich bei RefUndoDoc weglassen !!!
+
+ if ( bRecord )
+ {
+ // Redo-Daten werden erst beim ersten Undo kopiert
+ // ohne RefUndoDoc muss das Redo-Doc noch nicht angelegt werden
+
+ if (pRefUndoDoc)
+ {
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nStartTab, nEndTab, bColInfo, bRowInfo );
+
+ // angepasste Referenzen ins Redo-Doc
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pRedoDoc->AddUndoTab( 0, nTabCount-1 );
+ pDoc->CopyUpdated( pRefUndoDoc, pRedoDoc );
+
+ // alte Referenzen ins Undo-Doc
+
+ //! Tabellen selektieren ?
+ pUndoDoc->AddUndoTab( 0, nTabCount-1 );
+ pRefUndoDoc->DeleteArea( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, IDF_ALL );
+ pRefUndoDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
+ IDF_FORMULA, FALSE, pUndoDoc );
+ delete pRefUndoDoc;
+ }
+
+ // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
+ // UndoData for redo is made during first undo
+
+ ScUndoPasteOptions aOptions; // store options for repeat
+ aOptions.nFunction = nFunction;
+ aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bTranspose = bTranspose;
+ aOptions.bAsLink = bAsLink;
+ aOptions.eMoveMode = eMoveMode;
+
+ SfxUndoAction* pUndo = new ScUndoPaste( pDocSh,
+ nStartCol, nStartRow, nStartTab,
+ nUndoEndCol, nUndoEndRow, nEndTab, aFilteredMark,
+ pUndoDoc, pRedoDoc, nFlags | nUndoFlags,
+ pUndoData, NULL, NULL, NULL,
+ FALSE, &aOptions ); // FALSE = Redo data not yet copied
+
+ if ( bInsertCells )
+ {
+ // Merge the paste undo action into the insert action.
+ // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
+
+ pUndoMgr->AddUndoAction( new ScUndoWrapper( pUndo ), TRUE );
+ }
+ else
+ pUndoMgr->AddUndoAction( pUndo );
+ pUndoMgr->LeaveListAction();
+ }
+
+ USHORT nPaint = PAINT_GRID;
+ if (bColInfo)
+ {
+ nPaint |= PAINT_TOP;
+ nUndoEndCol = MAXCOL; // nur zum Zeichnen !
+ }
+ if (bRowInfo)
+ {
+ nPaint |= PAINT_LEFT;
+ nUndoEndRow = MAXROW; // nur zum Zeichnen !
+ }
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nUndoEndCol, nUndoEndRow, nEndTab, nPaint, nExtFlags );
+ // AdjustBlockHeight has already been called above
+
+ aModificator.SetDocumentModified();
+ PostPasteFromClip(aUserRange, rMark);
+ return TRUE;
+}
+
+bool ScViewFunc::PasteMultiRangesFromClip(
+ sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
+ bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, sal_uInt16 /*nContFlags*/, sal_uInt16 nUndoFlags)
+{
+ ScViewData& rViewData = *GetViewData();
+ ScDocument* pDoc = rViewData.GetDocument();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScMarkData aMark(rViewData.GetMarkData());
+ const ScAddress& rCurPos = rViewData.GetCurPos();
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ SCCOL nColSize = rClipParam.getPasteColSize();
+ SCROW nRowSize = rClipParam.getPasteRowSize();
+
+ if (bTranspose)
+ {
+ if (static_cast<SCROW>(rCurPos.Col()) + nRowSize-1 > static_cast<SCROW>(MAXCOL))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return false;
+ }
+
+ ::std::auto_ptr<ScDocument> pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink);
+ pClipDoc = pTransClip.release();
+ SCCOL nTempColSize = nColSize;
+ nColSize = static_cast<SCCOL>(nRowSize);
+ nRowSize = static_cast<SCROW>(nTempColSize);
+ }
+
+ if (!ValidCol(rCurPos.Col()+nColSize-1) || !ValidRow(rCurPos.Row()+nRowSize-1))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return false;
+ }
+
+ // Determine the first and last selected sheet numbers.
+ SCTAB nTab1 = aMark.GetFirstSelected();
+ SCTAB nTab2 = nTab1;
+ for (SCTAB i = nTab1+1; i <= MAXTAB; ++i)
+ if (aMark.GetTableSelect(i))
+ nTab2 = i;
+
+ ScDocShellModificator aModificator(*pDocSh);
+
+ // For multi-selection paste, we don't support cell duplication for larger
+ // destination range. In case the destination is marked, we reset it to
+ // the clip size.
+ ScRange aMarkedRange(rCurPos.Col(), rCurPos.Row(), nTab1,
+ rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, nTab2);
+
+ // Extend the marked range to account for filtered rows in the destination
+ // area.
+ if (ScViewUtil::HasFiltered(aMarkedRange, pDoc))
+ {
+ if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange, pDoc, nRowSize))
+ return false;
+ }
+
+ bool bAskIfNotEmpty =
+ bAllowDialogs && (nFlags & IDF_CONTENTS) &&
+ nFunction == PASTE_NOFUNC && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
+
+ if (bAskIfNotEmpty)
+ {
+ if (!lcl_checkDestRangeForOverwrite(aMarkedRange, pDoc, aMark, rViewData.GetDialogParent()))
+ return false;
+ }
+
+ aMark.SetMarkArea(aMarkedRange);
+ MarkRange(aMarkedRange);
+
+ bool bInsertCells = (eMoveMode != INS_NONE);
+ if (bInsertCells)
+ {
+ if (!InsertCells(eMoveMode, pDoc->IsUndoEnabled(), true))
+ return false;
+ }
+
+ ::std::auto_ptr<ScDocument> pUndoDoc;
+ if (pDoc->IsUndoEnabled())
+ {
+ pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
+ pUndoDoc->InitUndoSelected(pDoc, aMark, false, false);
+ pDoc->CopyToDocument(aMarkedRange, nUndoFlags, false, pUndoDoc.get(), &aMark, true);
+ }
+
+ ::std::auto_ptr<ScDocument> pMixDoc;
+ if ( bSkipEmpty || nFunction )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ {
+ pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
+ pMixDoc->InitUndoSelected(pDoc, aMark, false, false);
+ pDoc->CopyToDocument(aMarkedRange, IDF_CONTENTS, false, pMixDoc.get(), &aMark, true);
+ }
+ }
+
+ /* Make draw layer and start drawing undo.
+ - Needed before AdjustBlockHeight to track moved drawing objects.
+ - Needed before pDoc->CopyFromClip to track inserted note caption objects.
+ */
+ if (nFlags & IDF_OBJECTS)
+ pDocSh->MakeDrawLayer();
+ if (pDoc->IsUndoEnabled())
+ pDoc->BeginDrawUndo();
+
+ CursorSwitcher aCursorSwitch(this);
+ sal_uInt16 nNoObjFlags = nFlags & ~IDF_OBJECTS;
+ pDoc->CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc,
+ true, bAsLink, false, bSkipEmpty);
+
+ if (pMixDoc.get())
+ pDoc->MixDocument(aMarkedRange, nFunction, bSkipEmpty, pMixDoc.get());
+
+ AdjustBlockHeight(); // update row heights before pasting objects
+
+ if (nFlags & IDF_OBJECTS)
+ {
+ // Paste the drawing objects after the row heights have been updated.
+ pDoc->CopyMultiRangeFromClip(rCurPos, aMark, IDF_OBJECTS, pClipDoc,
+ true, false, false, true);
+ }
+
+ pDocSh->PostPaint(
+ aMarkedRange.aStart.Col(), aMarkedRange.aStart.Row(), nTab1,
+ aMarkedRange.aEnd.Col(), aMarkedRange.aEnd.Row(), nTab1, PAINT_GRID);
+
+ if (pDoc->IsUndoEnabled())
+ {
+ SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
+ String aUndo = ScGlobal::GetRscString(
+ pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
+ pUndoMgr->EnterListAction(aUndo, aUndo);
+
+ ScUndoPasteOptions aOptions; // store options for repeat
+ aOptions.nFunction = nFunction;
+ aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bTranspose = bTranspose;
+ aOptions.bAsLink = bAsLink;
+ aOptions.eMoveMode = eMoveMode;
+
+ ScUndoPaste* pUndo = new ScUndoPaste(pDocSh,
+ aMarkedRange.aStart.Col(),
+ aMarkedRange.aStart.Row(),
+ aMarkedRange.aStart.Tab(),
+ aMarkedRange.aEnd.Col(),
+ aMarkedRange.aEnd.Row(),
+ aMarkedRange.aEnd.Tab(),
+ aMark, pUndoDoc.release(), NULL, nFlags|nUndoFlags, NULL, NULL, NULL, NULL, false, &aOptions);
+
+ if (bInsertCells)
+ pUndoMgr->AddUndoAction(new ScUndoWrapper(pUndo), true);
+ else
+ pUndoMgr->AddUndoAction(pUndo, false);
+
+ pUndoMgr->LeaveListAction();
+ }
+ aModificator.SetDocumentModified();
+ PostPasteFromClip(aMarkedRange, aMark);
+ return true;
+}
+
+void ScViewFunc::PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark)
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pViewData->GetDocument();
+ pDocSh->UpdateOle(pViewData);
+
+ SelectionChanged();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for ( SCTAB i = 0; i < nTabCount; ++i )
+ {
+ if ( rMark.GetTableSelect( i ) )
+ {
+ ScRange aChangeRange(rPasteRange);
+ aChangeRange.aStart.SetTab( i );
+ aChangeRange.aEnd.SetTab( i );
+ aChangeRanges.Append( aChangeRange );
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// D R A G A N D D R O P
+//
+// innerhalb des Dokuments
+
+BOOL ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
+ BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ HideAllCursors(); // wegen zusammengefassten
+
+ BOOL bSuccess = TRUE;
+ SCTAB nDestTab = rDestPos.Tab();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rSource.aStart.Tab() == nDestTab && rSource.aEnd.Tab() == nDestTab && rMark.GetSelectCount() > 1 )
+ {
+ // moving within one table and several tables selected -> apply to all selected tables
+
+ if ( bRecord )
+ {
+ String aUndo = ScGlobal::GetRscString( bCut ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ // collect ranges of consecutive selected tables
+
+ ScRange aLocalSource = rSource;
+ ScAddress aLocalDest = rDestPos;
+ SCTAB nTabCount = pDocSh->GetDocument()->GetTableCount();
+ SCTAB nStartTab = 0;
+ while ( nStartTab < nTabCount && bSuccess )
+ {
+ while ( nStartTab < nTabCount && !rMark.GetTableSelect(nStartTab) )
+ ++nStartTab;
+ if ( nStartTab < nTabCount )
+ {
+ SCTAB nEndTab = nStartTab;
+ while ( nEndTab+1 < nTabCount && rMark.GetTableSelect(nEndTab+1) )
+ ++nEndTab;
+
+ aLocalSource.aStart.SetTab( nStartTab );
+ aLocalSource.aEnd.SetTab( nEndTab );
+ aLocalDest.SetTab( nStartTab );
+
+ bSuccess = pDocSh->GetDocFunc().MoveBlock(
+ aLocalSource, aLocalDest, bCut, bRecord, bPaint, bApi );
+
+ nStartTab = nEndTab + 1;
+ }
+ }
+
+ if ( bRecord )
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ else
+ {
+ // move the block as specified
+ bSuccess = pDocSh->GetDocFunc().MoveBlock(
+ rSource, rDestPos, bCut, bRecord, bPaint, bApi );
+ }
+
+ ShowAllCursors();
+ if (bSuccess)
+ {
+ // Zielbereich markieren
+ ScAddress aDestEnd(
+ rDestPos.Col() + rSource.aEnd.Col() - rSource.aStart.Col(),
+ rDestPos.Row() + rSource.aEnd.Row() - rSource.aStart.Row(),
+ nDestTab );
+
+ BOOL bIncludeFiltered = bCut;
+ if ( !bIncludeFiltered )
+ {
+ // find number of non-filtered rows
+ SCROW nPastedCount = pDocSh->GetDocument()->CountNonFilteredRows(
+ rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab());
+
+ if ( nPastedCount == 0 )
+ nPastedCount = 1;
+ aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 );
+ }
+
+ MarkRange( ScRange( rDestPos, aDestEnd ), FALSE ); //! FALSE ???
+
+ pDocSh->UpdateOle(GetViewData());
+ SelectionChanged();
+ }
+ return bSuccess;
+}
+
+// Link innerhalb des Dokuments
+
+BOOL ScViewFunc::LinkBlock( const ScRange& rSource, const ScAddress& rDestPos, BOOL bApi )
+{
+ // Test auf Ueberlappung
+
+ if ( rSource.aStart.Tab() == rDestPos.Tab() )
+ {
+ SCCOL nDestEndCol = rDestPos.Col() + ( rSource.aEnd.Col() - rSource.aStart.Col() );
+ SCROW nDestEndRow = rDestPos.Row() + ( rSource.aEnd.Row() - rSource.aStart.Row() );
+
+ if ( rSource.aStart.Col() <= nDestEndCol && rDestPos.Col() <= rSource.aEnd.Col() &&
+ rSource.aStart.Row() <= nDestEndRow && rDestPos.Row() <= rSource.aEnd.Row() )
+ {
+ if (!bApi)
+ ErrorMessage( STR_ERR_LINKOVERLAP );
+ return FALSE;
+ }
+ }
+
+ // Ausfuehren per Paste
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ pDoc->CopyTabToClip( rSource.aStart.Col(), rSource.aStart.Row(),
+ rSource.aEnd.Col(), rSource.aEnd.Row(),
+ rSource.aStart.Tab(), pClipDoc );
+
+ // Zielbereich markieren (Cursor setzen, keine Markierung)
+
+ if ( GetViewData()->GetTabNo() != rDestPos.Tab() )
+ SetTabNo( rDestPos.Tab() );
+
+ MoveCursorAbs( rDestPos.Col(), rDestPos.Row(), SC_FOLLOW_NONE, FALSE, FALSE );
+
+ // Paste
+
+ PasteFromClip( IDF_ALL, pClipDoc, PASTE_NOFUNC, FALSE, FALSE, TRUE ); // als Link
+
+ delete pClipDoc;
+
+ return TRUE;
+}
+
+
+
+
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
new file mode 100644
index 000000000000..123464cd5fda
--- /dev/null
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -0,0 +1,846 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/svxerr.hxx>
+#include <editeng/unolingu.hxx>
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <svtools/langtab.hxx>
+#include <svtools/filter.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/transfer.hxx>
+#include <svl/urlbmk.hxx>
+#include <vcl/msgbox.hxx>
+#include <avmedia/mediawindow.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include "viewfunc.hxx"
+#include "docsh.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "undoblk.hxx"
+#include "undocell.hxx"
+#include "cell.hxx"
+#include "scmod.hxx"
+#include "spelleng.hxx"
+#include "patattr.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "editutil.hxx"
+#include "editable.hxx"
+#include "dociter.hxx"
+#include "reffind.hxx"
+#include "compiler.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+BOOL bPasteIsDrop = FALSE;
+
+//==================================================================
+
+void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable )
+{
+ TransferableDataHelper aDataHelper( rxTransferable );
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
+ {
+ HideAllCursors();
+
+ ScDocument* pUndoDoc = NULL;
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ const BOOL bRecord (pDoc->IsUndoEnabled());
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nStartCol, nStartRow, nTab );
+ ScTabEditEngine* pEngine = new ScTabEditEngine( *pPattern, pDoc->GetEnginePool() );
+ pEngine->EnableUndo( FALSE );
+
+ Window* pActWin = GetActiveWin();
+ if (pActWin)
+ {
+ pEngine->SetPaperSize(Size(100000,100000));
+ Window aWin( pActWin );
+ EditView aEditView( pEngine, &aWin );
+ aEditView.SetOutputArea(Rectangle(0,0,100000,100000));
+
+ // same method now for clipboard or drag&drop
+ // mba: clipboard always must contain absolute URLs (could be from alien source)
+ aEditView.InsertText( rxTransferable, String(), TRUE );
+ }
+
+ ULONG nParCnt = pEngine->GetParagraphCount();
+ if (nParCnt)
+ {
+ SCROW nEndRow = nStartRow + static_cast<SCROW>(nParCnt) - 1;
+ if (nEndRow > MAXROW)
+ nEndRow = MAXROW;
+
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL, FALSE, pUndoDoc );
+ }
+
+ SCROW nRow = nStartRow;
+ for( USHORT n = 0; n < nParCnt; n++ )
+ {
+ EditTextObject* pObject = pEngine->CreateTextObject( n );
+ EnterData( nStartCol, nRow, nTab, pObject, FALSE, TRUE );
+ // kein Undo, auf einfache Strings testen
+ delete pObject;
+ if( ++nRow > MAXROW )
+ break;
+ }
+
+ if (bRecord)
+ {
+ ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL|IDF_NOCAPTIONS, FALSE, pRedoDoc );
+
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nTab );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPaste( pDocSh, nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab,
+ aDestMark,
+ pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) );
+ }
+ }
+
+ delete pEngine;
+
+ ShowAllCursors();
+ }
+ else
+ {
+ HideAllCursors();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScImportExport aImpEx( pDocSh->GetDocument(),
+ ScAddress( nStartCol, nStartRow, GetViewData()->GetTabNo() ) );
+
+ ::rtl::OUString aStr;
+ SotStorageStreamRef xStream;
+ if ( aDataHelper.GetSotStorageStream( SOT_FORMAT_RTF, xStream ) && xStream.Is() )
+ // mba: clipboard always must contain absolute URLs (could be from alien source)
+ aImpEx.ImportStream( *xStream, String(), SOT_FORMAT_RTF );
+ else if ( aDataHelper.GetString( SOT_FORMAT_RTF, aStr ) )
+ aImpEx.ImportString( aStr, SOT_FORMAT_RTF );
+
+ AdjustRowHeight( nStartRow, aImpEx.GetRange().aEnd.Row() );
+ pDocSh->UpdateOle(GetViewData());
+ 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 )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScSplitPos eWhich = GetViewData()->GetActivePart();
+ CellType eCellType;
+ EESpellState eState;
+ String sOldText, sNewString;
+ EditTextObject* pOldTObj = NULL;
+ const EditTextObject* pTObject = NULL;
+ ScBaseCell* pCell = NULL;
+ EditView* pEditView = NULL;
+ ESelection* pEditSel = NULL;
+ ScEditEngineDefaulter* pThesaurusEngine;
+ BOOL bIsEditMode = GetViewData()->HasEditView(eWhich);
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ if (bIsEditMode) // Edit-Mode aktiv
+ {
+ GetViewData()->GetEditView(eWhich, pEditView, nCol, nRow);
+ pEditSel = new ESelection(pEditView->GetSelection());
+ SC_MOD()->InputEnterHandler();
+ GetViewData()->GetBindings().Update(); // sonst kommt der Sfx durcheinander...
+ }
+ else
+ {
+ nCol = GetViewData()->GetCurX();
+ nRow = GetViewData()->GetCurY();
+ }
+ nTab = GetViewData()->GetTabNo();
+
+ ScEditableTester aTester( pDoc, nCol, nRow, nCol, nRow, rMark );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ delete pEditSel;
+ return;
+ }
+ pDoc->GetCellType(nCol, nRow, nTab, eCellType);
+ if (eCellType != CELLTYPE_STRING && eCellType != CELLTYPE_EDIT)
+ {
+ ErrorMessage(STR_THESAURUS_NO_STRING);
+ return;
+ }
+
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1>
+ xSpeller = LinguMgr::GetSpellChecker();
+ //! if (...) // thesaurus not available
+ //! {
+ //! ErrorMessage(STR_EXPORT_ASCII_WARNING);
+ //! delete pEditSel;
+ //! return;
+ //! }
+
+ pThesaurusEngine = new ScEditEngineDefaulter( pDoc->GetEnginePool() );
+ pThesaurusEngine->SetEditTextObjectPool( pDoc->GetEditPool() );
+ pThesaurusEngine->SetRefDevice(GetViewData()->GetActiveWin());
+ pThesaurusEngine->SetSpeller(xSpeller);
+ MakeEditView(pThesaurusEngine, nCol, nRow );
+ const ScPatternAttr* pPattern = NULL;
+ SfxItemSet* pEditDefaults = new SfxItemSet(pThesaurusEngine->GetEmptyItemSet());
+ pPattern = pDoc->GetPattern(nCol, nRow, nTab);
+ if (pPattern )
+ {
+ pPattern->FillEditItemSet( pEditDefaults );
+ pThesaurusEngine->SetDefaults( *pEditDefaults );
+ }
+
+ if (eCellType == CELLTYPE_STRING)
+ {
+ pDoc->GetString(nCol, nRow, nTab, sOldText);
+ pThesaurusEngine->SetText(sOldText);
+ }
+ else if (eCellType == CELLTYPE_EDIT)
+ {
+ pDoc->GetCell(nCol, nRow, nTab, pCell);
+ if (pCell)
+ {
+ ((ScEditCell*) pCell)->GetData(pTObject);
+ pOldTObj = pTObject->Clone();
+ if (pTObject)
+ pThesaurusEngine->SetText(*pTObject);
+ }
+ }
+ else
+ {
+ DBG_ERROR("DoThesaurus: Keine String oder Editzelle");
+ }
+ pEditView = GetViewData()->GetEditView(GetViewData()->GetActivePart());;
+ if (pEditSel)
+ pEditView->SetSelection(*pEditSel);
+ else
+ pEditView->SetSelection(ESelection(0,0,0,0));
+
+ pThesaurusEngine->ClearModifyFlag();
+
+ // language is now in EditEngine attributes -> no longer passed to StartThesaurus
+
+ eState = pEditView->StartThesaurus();
+ DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
+
+ if (eState == EE_SPELL_ERRORFOUND) // sollte spaeter durch Wrapper geschehen!
+ {
+ LanguageType eLnge = ScViewUtil::GetEffLanguage( pDoc, ScAddress( nCol, nRow, nTab ) );
+ SvtLanguageTable aLangTab;
+ String aErr = aLangTab.GetString(eLnge);
+ aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG );
+ InfoBox aBox( GetViewData()->GetDialogParent(), aErr );
+ aBox.Execute();
+ }
+ if (pThesaurusEngine->IsModified())
+ {
+ EditTextObject* pNewTObj = NULL;
+ if (pCell && pTObject)
+ {
+ pNewTObj = pThesaurusEngine->CreateTextObject();
+ pCell = new ScEditCell( pNewTObj, pDoc,
+ pThesaurusEngine->GetEditTextObjectPool() );
+ pDoc->PutCell( nCol, nRow, nTab, pCell );
+ }
+ else
+ {
+ sNewString = pThesaurusEngine->GetText();
+ pDoc->SetString(nCol, nRow, nTab, sNewString);
+ }
+// erack! it's broadcasted
+// pDoc->SetDirty();
+ pDocSh->SetDocumentModified();
+ if (bRecord)
+ {
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoThesaurus( GetViewData()->GetDocShell(),
+ nCol, nRow, nTab,
+ sOldText, pOldTObj, sNewString, pNewTObj));
+ }
+ delete pNewTObj;
+ }
+ KillEditView(TRUE);
+ delete pEditDefaults;
+ delete pThesaurusEngine;
+ delete pOldTObj;
+ delete pEditSel;
+ pDocSh->PostPaintGridAll();
+}
+
+//UNUSED2008-05 // Spelling Checker - Undo ok
+//UNUSED2008-05 void ScViewFunc::DoSpellingChecker( BOOL bRecord )
+//UNUSED2008-05 {
+//UNUSED2008-05 DoSheetConversion( ScConversionParam( SC_CONVERSION_SPELLCHECK ), bRecord );
+//UNUSED2008-05 }
+
+void ScViewFunc::DoHangulHanjaConversion( BOOL bRecord )
+{
+ ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true );
+ DoSheetConversion( aConvParam, bRecord );
+}
+
+void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam, BOOL bRecord )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ ScViewData& rViewData = *GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = rViewData.GetMarkData();
+ ScSplitPos eWhich = rViewData.GetActivePart();
+ EditView* pEditView = NULL;
+ ESelection* pEditSel = NULL;
+ BOOL bIsEditMode = rViewData.HasEditView(eWhich);
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ if (bIsEditMode) // Edit-Mode aktiv
+ {
+ rViewData.GetEditView(eWhich, pEditView, nCol, nRow);
+ pEditSel = new ESelection(pEditView->GetSelection());
+ SC_MOD()->InputEnterHandler();
+ }
+ else
+ {
+ nCol = rViewData.GetCurX();
+ nRow = rViewData.GetCurY();
+
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP);
+ }
+ nTab = rViewData.GetTabNo();
+
+ rMark.MarkToMulti();
+ BOOL bMarked = rMark.IsMultiMarked();
+ if (bMarked)
+ {
+ ScEditableTester aTester( pDoc, rMark );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ delete pEditSel;
+ return;
+ }
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRedoDoc = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( rMark.GetSelectCount() > 1 )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( rMark.GetTableSelect(i) && i != nTab )
+ {
+ pUndoDoc->AddUndoTab( i, i );
+ pRedoDoc->AddUndoTab( i, i );
+ }
+ }
+ }
+
+ // ab hier kein return mehr
+
+ BOOL bOldDis = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( TRUE ); // #42726# stop online spelling
+
+ // *** create and init the edit engine *** --------------------------------
+
+ ScConversionEngineBase* pEngine = NULL;
+ switch( rConvParam.GetType() )
+ {
+ case SC_CONVERSION_SPELLCHECK:
+ pEngine = new ScSpellingEngine(
+ pDoc->GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() );
+ break;
+ case SC_CONVERSION_HANGULHANJA:
+ case SC_CONVERSION_CHINESE_TRANSL:
+ pEngine = new ScTextConversionEngine(
+ pDoc->GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc );
+ break;
+ default:
+ DBG_ERRORFILE( "ScViewFunc::DoSheetConversion - unknown conversion type" );
+ }
+
+ MakeEditView( pEngine, nCol, nRow );
+ pEngine->SetRefDevice( rViewData.GetActiveWin() );
+ // dummy Zelle simulieren:
+ pEditView = rViewData.GetEditView( rViewData.GetActivePart() );
+ rViewData.SetSpellingView( pEditView );
+ Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
+ pEditView->SetOutputArea( aRect );
+ pEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
+ pEngine->EnableUndo( FALSE );
+ pEngine->SetPaperSize( aRect.GetSize() );
+ pEngine->SetText( EMPTY_STRING );
+
+ // *** do the conversion *** ----------------------------------------------
+
+ pEngine->ClearModifyFlag();
+ pEngine->ConvertAll( *pEditView );
+
+ // *** undo/redo *** ------------------------------------------------------
+
+ if( pEngine->IsAnyModified() )
+ {
+ if (bRecord)
+ {
+ SCCOL nNewCol = rViewData.GetCurX();
+ SCROW nNewRow = rViewData.GetCurY();
+ rViewData.GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoConversion(
+ pDocSh, rMark,
+ nCol, nRow, nTab, pUndoDoc,
+ nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) );
+ }
+ pDoc->SetDirty();
+ pDocSh->SetDocumentModified();
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pRedoDoc;
+ }
+
+ // *** final cleanup *** --------------------------------------------------
+
+ rViewData.SetSpellingView( NULL );
+ KillEditView(TRUE);
+ delete pEngine;
+ delete pEditSel;
+ pDocSh->PostPaintGridAll();
+ rViewData.GetViewShell()->UpdateInputHandler();
+ pDoc->DisableIdle(bOldDis);
+}
+
+
+//UNUSED2008-05 IMPL_LINK_INLINE_START( ScViewFunc, SpellError, void *, nLang )
+//UNUSED2008-05 {
+//UNUSED2008-05 SvtLanguageTable aLangTab;
+//UNUSED2008-05 String aErr = aLangTab.GetString((LanguageType) (ULONG) nLang);
+//UNUSED2008-05 ErrorHandler::HandleError(*new StringErrorInfo(
+//UNUSED2008-05 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr) );
+//UNUSED2008-05
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+//UNUSED2008-05 IMPL_LINK_INLINE_END( ScViewFunc, SpellError, void *, nLang )
+
+// Pasten von FORMAT_FILE-Items
+// wird nicht direkt aus Drop aufgerufen, sondern asynchron -> Dialoge sind erlaubt
+
+BOOL ScViewFunc::PasteFile( const Point& rPos, const String& rFile, BOOL bLink )
+{
+ INetURLObject aURL;
+ aURL.SetSmartURL( rFile );
+ String aStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
+
+ // is it a media URL?
+ if( ::avmedia::MediaWindow::isMediaURL( aStrURL ) )
+ {
+ const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aStrURL );
+ return BOOL( 0 != GetViewData()->GetDispatcher().Execute(
+ SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON,
+ &aMediaURLItem, 0L ) );
+ }
+
+ if (!bLink) // bei bLink nur Grafik oder URL
+ {
+ // 1. Kann ich die Datei oeffnen?
+ const SfxFilter* pFlt = NULL;
+
+ // nur nach eigenen Filtern suchen, ohne Auswahlbox (wie in ScDocumentLoader)
+ SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() );
+ SfxMedium aSfxMedium( aStrURL, (STREAM_READ | STREAM_SHARE_DENYNONE), FALSE );
+ // #i73992# GuessFilter no longer calls UseInteractionHandler.
+ // This is UI, so it can be called here.
+ aSfxMedium.UseInteractionHandler(TRUE);
+ ErrCode nErr = aMatcher.GuessFilter( aSfxMedium, &pFlt );
+
+ if ( pFlt && !nErr )
+ {
+ // Code aus dem SFX geklaut!
+ 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, &aTargetItem, 0L) );
+ }
+ }
+
+ // 2. Kann die Datei ueber die Grafik-Filter eingefuegt werden?
+ // (als Link, weil Gallery das so anbietet)
+
+ USHORT nFilterFormat;
+ Graphic aGraphic;
+ GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter();
+
+// GraphicProgress aGraphicProgress(&aGraphicFilter);
+
+ if (!pGraphicFilter->ImportGraphic(aGraphic, aURL,
+ GRFILTER_FORMAT_DONTKNOW, &nFilterFormat ))
+ {
+ if ( bLink )
+ {
+ String aFltName = pGraphicFilter->GetImportFormatName(nFilterFormat);
+ return PasteGraphic( rPos, aGraphic, aStrURL, aFltName );
+ }
+ else
+ {
+ // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
+ return PasteGraphic( rPos, aGraphic, EMPTY_STRING, EMPTY_STRING );
+ }
+ }
+
+ if (bLink) // bei bLink alles, was nicht Grafik ist, als URL
+ {
+ Rectangle aRect( rPos, Size(0,0) );
+ ScRange aRange = GetViewData()->GetDocument()->
+ GetRange( GetViewData()->GetTabNo(), aRect );
+ SCCOL nPosX = aRange.aStart.Col();
+ SCROW nPosY = aRange.aStart.Row();
+
+ InsertBookmark( aStrURL, aStrURL, nPosX, nPosY );
+ return TRUE;
+ }
+ else
+ {
+ // 3. Kann die Datei als OLE eingefuegt werden?
+ // auch nicht-Storages, z.B. Sounds (#38282#)
+ uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
+
+ //TODO/LATER: what about "bLink"?
+
+ uno::Sequence < beans::PropertyValue > aMedium(1);
+ aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ aMedium[0].Value <<= ::rtl::OUString( aStrURL );
+
+ comphelper::EmbeddedObjectContainer aCnt( xStorage );
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
+ if( xObj.is() )
+ return PasteObject( rPos, xObj );
+
+ // #105851# If an OLE object can't be created, insert a URL button
+
+ GetViewData()->GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_STRING, &rPos );
+ return TRUE;
+ }
+}
+
+BOOL ScViewFunc::PasteBookmark( ULONG nFormatId,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
+ SCCOL nPosX, SCROW nPosY )
+{
+ INetBookmark aBookmark;
+ TransferableDataHelper aDataHelper( rxTransferable );
+ if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) )
+ return FALSE;
+
+ InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY );
+ return TRUE;
+}
+
+void ScViewFunc::InsertBookmark( const String& rDescription, const String& rURL,
+ SCCOL nPosX, SCROW nPosY, const String* pTarget,
+ BOOL bTryReplace )
+{
+ ScViewData* pViewData = GetViewData();
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) &&
+ nPosX >= pViewData->GetEditStartCol() && nPosX <= pViewData->GetEditEndCol() &&
+ nPosY >= pViewData->GetEditStartRow() && nPosY <= pViewData->GetEditEndRow() )
+ {
+ // in die gerade editierte Zelle einfuegen
+
+ String aTargetFrame;
+ if (pTarget)
+ aTargetFrame = *pTarget;
+ pViewData->GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame );
+ return;
+ }
+
+ // in nicht editierte Zelle einfuegen
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCellPos( nPosX, nPosY, nTab );
+ ScBaseCell* pCell = pDoc->GetCell( aCellPos );
+ EditEngine aEngine( pDoc->GetEnginePool() );
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pOld = ((ScEditCell*)pCell)->GetData();
+ if (pOld)
+ aEngine.SetText(*pOld);
+ }
+ else
+ {
+ String aOld;
+ pDoc->GetInputString( nPosX, nPosY, nTab, aOld );
+ if (aOld.Len())
+ aEngine.SetText(aOld);
+ }
+ }
+
+ USHORT nPara = aEngine.GetParagraphCount();
+ if (nPara)
+ --nPara;
+ xub_StrLen nTxtLen = aEngine.GetTextLen(nPara);
+ ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen );
+
+ if ( bTryReplace && HasBookmarkAtCursor( NULL ) )
+ {
+ // if called from hyperlink slot and cell contains only a URL,
+ // replace old URL with new one
+
+ aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field)
+ }
+
+ SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT );
+ if (pTarget)
+ aField.SetTargetFrame(*pTarget);
+ aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel );
+
+ EditTextObject* pData = aEngine.CreateTextObject();
+ EnterData( nPosX, nPosY, nTab, pData );
+ delete pData;
+}
+
+BOOL ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent )
+{
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
+
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
+ if (pData)
+ {
+ BOOL bField = pData->IsFieldObject();
+ if (bField)
+ {
+ const SvxFieldItem* pFieldItem = pData->GetField();
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ if (pContent)
+ {
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+ pContent->SetName( pURLField->GetRepresentation() );
+ pContent->SetURL( pURLField->GetURL() );
+ pContent->SetTargetFrame( pURLField->GetTargetFrame() );
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+
diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx
new file mode 100644
index 000000000000..dc4e96bbbf34
--- /dev/null
+++ b/sc/source/ui/view/viewfun5.cxx
@@ -0,0 +1,749 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+
+
+#include <svx/unomodel.hxx>
+#include <unotools/streamwrap.hxx>
+
+//------------------------------------------------------------------
+
+#include <svx/dbexch.hrc>
+#include <svx/fmmodel.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sot/clsids.hxx>
+#include <sot/formats.hxx>
+#include <sot/filelist.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/transfer.hxx>
+#include <vcl/graph.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <sot/formats.hxx>
+#define SOT_FORMATSTR_ID_STARCALC_CURRENT SOT_FORMATSTR_ID_STARCALC_50
+
+#include "viewfunc.hxx"
+#include "docsh.hxx"
+#include "drawview.hxx"
+#include "impex.hxx"
+#include "dbfunc.hxx"
+#include "dbcolect.hxx"
+#include "sc.hrc"
+#include "filter.hxx"
+#include "scextopt.hxx"
+#include "tabvwsh.hxx" // wegen GetViewFrame
+#include "compiler.hxx"
+
+#include "asciiopt.hxx"
+#include "scabstdlg.hxx"
+#include "clipparam.hxx"
+#include <vcl/msgbox.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/dbaexchange.hxx>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+BOOL ScViewFunc::PasteDataFormat( ULONG nFormatId,
+ const uno::Reference<datatransfer::XTransferable>& rxTransferable,
+ SCCOL nPosX, SCROW nPosY, Point* pLogicPos, BOOL bLink, BOOL bAllowDialogs )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ pDoc->SetPastingDrawFromOtherDoc( TRUE );
+
+ Point aPos; // inserting position (1/100 mm)
+ if (pLogicPos)
+ aPos = *pLogicPos;
+ else
+ {
+ // inserting position isn't needed for text formats
+ BOOL bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
+ nFormatId == FORMAT_RTF );
+ if ( !bIsTextFormat )
+ {
+ // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+ long nXT = 0;
+ for (SCCOL i=0; i<nPosX; i++)
+ nXT += pDoc->GetColWidth(i,nTab);
+ if (pDoc->IsNegativePage(nTab))
+ nXT = -nXT;
+ ULONG nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab);
+ aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) );
+ }
+ }
+
+ TransferableDataHelper aDataHelper( rxTransferable );
+ BOOL bRet = FALSE;
+
+ //
+ // handle individual formats
+ //
+
+ if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE ||
+ nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE ||
+ nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ||
+ nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE_OLE ||
+ nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
+ {
+ uno::Reference < io::XInputStream > xStm;
+ TransferableObjectDescriptor aObjDesc;
+
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
+ aDataHelper.GetInputStream( nFormatId, xStm ) )
+ {
+ if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
+ {
+ uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
+
+ // mba: BaseURL doesn't make sense for clipboard
+ // #i43716# Medium must be allocated with "new".
+ // DoLoad stores the pointer and deletes it with the SfxObjectShell.
+ SfxMedium* pMedium = new SfxMedium( xStore, String() );
+
+ // TODO/LATER: is it a problem that we don't support binary formats here?
+ ScDocShellRef xDocShRef = new ScDocShell(SFX_CREATE_MODE_EMBEDDED);
+ if (xDocShRef->DoLoad(pMedium))
+ {
+ ScDocument* pSrcDoc = xDocShRef->GetDocument();
+ SCTAB nSrcTab = pSrcDoc->GetVisibleTab();
+ if (!pSrcDoc->HasTable(nSrcTab))
+ nSrcTab = 0;
+
+ ScMarkData aSrcMark;
+ aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+
+ SCCOL nFirstCol, nLastCol;
+ SCROW nFirstRow, nLastRow;
+ if ( pSrcDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
+ pSrcDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
+ else
+ {
+ nFirstCol = nLastCol = 0;
+ nFirstRow = nLastRow = 0;
+ }
+ ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, 0, nLastCol, nLastRow, 0), false);
+ pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSrcMark);
+ ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );
+
+ SetCursor( nPosX, nPosY );
+ Unmark();
+ PasteFromClip( IDF_ALL, pClipDoc,
+ PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
+ bAllowDialogs );
+ delete pClipDoc;
+ bRet = TRUE;
+ }
+
+ xDocShRef->DoClose();
+ xDocShRef.Clear();
+ }
+ else
+ {
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = GetViewData()->GetViewShell()->GetObjectShell()->
+ GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
+ if ( xObj.is() )
+ {
+ // try to get the replacement image from the clipboard
+ Graphic aGraphic;
+ ULONG nGrFormat = 0;
+// (wg. Selection Manager bei Trustet Solaris)
+#ifndef SOLARIS
+/*
+ if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
+ nGrFormat = SOT_FORMATSTR_ID_SVXB;
+ else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
+ nGrFormat = SOT_FORMAT_GDIMETAFILE;
+ else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
+ nGrFormat = SOT_FORMAT_BITMAP;
+*/
+#endif
+
+ // insert replacement image ( if there is one ) into the object helper
+ if ( nGrFormat )
+ {
+ datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
+ PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
+ }
+ else
+ PasteObject( aPos, xObj, &aObjDesc.maSize );
+
+ bRet = TRUE;
+ }
+ else
+ {
+ DBG_ERROR("Error in CreateAndLoad");
+ }
+ }
+ }
+ else
+ {
+// uno::Reference < io::XInputStream > xStm;
+// TransferableObjectDescriptor aObjDesc;
+
+ if ( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE, aObjDesc ) )
+ {
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj;
+
+ if ( aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, xStm )
+ || aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, xStm ) )
+ {
+ xObj = GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
+ }
+ else
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator(
+ ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.MSOLEObjectSystemCreator") ) ),
+ uno::UNO_QUERY_THROW );
+
+ embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
+ xTmpStor,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DummyName" ) ),
+ uno::Sequence< beans::PropertyValue >() );
+
+ // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
+ // for example whether the object should be an iconified one
+ xObj = aInfo.Object;
+ if ( xObj.is() )
+ GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( xObj.is() )
+ {
+ // try to get the replacement image from the clipboard
+ Graphic aGraphic;
+ ULONG nGrFormat = 0;
+
+// (wg. Selection Manager bei Trustet Solaris)
+#ifndef SOLARIS
+ if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
+ nGrFormat = SOT_FORMATSTR_ID_SVXB;
+ else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
+ nGrFormat = SOT_FORMAT_GDIMETAFILE;
+ else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
+ nGrFormat = SOT_FORMAT_BITMAP;
+#endif
+
+ // insert replacement image ( if there is one ) into the object helper
+ if ( nGrFormat )
+ {
+ datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
+ PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
+ }
+ else
+ PasteObject( aPos, xObj, &aObjDesc.maSize );
+
+ // let object stay in loaded state after insertion
+ SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
+ bRet = TRUE;
+ }
+ else
+ {
+ DBG_ERROR("Error creating external OLE object");
+ }
+ }
+ //TODO/LATER: if format is not available, create picture
+ }
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_LINK ) // LINK is also in ScImportExport
+ {
+ bRet = PasteDDE( rxTransferable );
+ }
+ else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SOT_FORMAT_RTF )
+ {
+ if ( nFormatId == SOT_FORMAT_RTF && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
+ {
+ // use EditView's PasteSpecial / Drop
+ PasteRTF( nPosX, nPosY, rxTransferable );
+ bRet = TRUE;
+ }
+ else
+ {
+ ScAddress aCellPos( nPosX, nPosY, GetViewData()->GetTabNo() );
+ ScImportExport aObj( GetViewData()->GetDocument(), aCellPos );
+
+ ::rtl::OUString aStr;
+ SotStorageStreamRef xStream;
+ if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.Is() )
+ // mba: clipboard always must contain absolute URLs (could be from alien source)
+ bRet = aObj.ImportStream( *xStream, String(), nFormatId );
+ else if (nFormatId == FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
+ {
+ // Do CSV dialog if more than one line.
+ sal_Int32 nDelim = aStr.indexOf('\n');
+#if 0
+ ::rtl::OString tmpStr = OUStringToOString( aStr,
+ RTL_TEXTENCODING_UTF8 );
+ fprintf( stderr, "String is '%s' (%d) [%d]\n", tmpStr.getStr(),
+ tmpStr.getLength(), nDelim);
+#endif
+ if (nDelim >= 0 && nDelim != aStr.getLength () - 1)
+ {
+ ScImportStringStream aStrm( aStr);
+ ScAbstractDialogFactory* pFact =
+ ScAbstractDialogFactory::Create();
+ AbstractScImportAsciiDlg *pDlg =
+ pFact->CreateScImportAsciiDlg( NULL, String(), &aStrm,
+ RID_SCDLG_ASCII);
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ ScAsciiOptions aOptions;
+ pDlg->GetOptions( aOptions );
+ aObj.SetExtOptions( aOptions );
+
+ bRet = aObj.ImportString( aStr, nFormatId );
+
+ // TODO: what if (aObj.IsOverflow())
+ // Content was partially pasted, which can be undone by
+ // the user though.
+ if (aObj.IsOverflow())
+ bRet = FALSE;
+ }
+ else
+ bRet = TRUE;
+ // Yes, no failure, don't raise a "couldn't paste"
+ // dialog if user cancelled.
+ delete pDlg;
+ }
+ else
+ bRet = aObj.ImportString( aStr, nFormatId );
+ }
+ else if (nFormatId != FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
+ bRet = aObj.ImportString( aStr, nFormatId );
+
+ InvalidateAttribs();
+ GetViewData()->UpdateInputHandler();
+ }
+ }
+ else if (nFormatId == SOT_FORMATSTR_ID_SBA_DATAEXCHANGE)
+ {
+ // import of database data into table
+
+ String sDataDesc;
+ if ( aDataHelper.GetString( nFormatId, sDataDesc ) )
+ {
+ SfxStringItem aDataDesc(SID_SBA_IMPORT, sDataDesc);
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ ClickCursor(nPosX, nPosY, FALSE); // set cursor position
+
+ // Creation of database area "Import1" isn't here, but in the DocShell
+ // slot execute, so it can be added to the undo action
+
+ ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP );
+ String sTarget;
+ if (pDBData)
+ sTarget = pDBData->GetName();
+ else
+ {
+ ScAddress aCellPos( nPosX,nPosY,nTab );
+ aCellPos.Format( sTarget, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ }
+ SfxStringItem aTarget(FN_PARAM_1, sTarget);
+
+ BOOL bAreaIsNew = !pDBData;
+ SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
+
+ ::svx::ODataAccessDescriptor aDesc;
+ DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
+ ::std::auto_ptr<SfxUsrAnyItem> pCursorItem;
+ if ( ::svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
+ {
+ aDesc = ::svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper);
+ if ( aDesc.has(::svx::daCursor) )
+ pCursorItem.reset(new SfxUsrAnyItem(FN_PARAM_3, aDesc[::svx::daCursor]));
+ }
+
+ // asynchronous, to avoid doing the whole import in drop handler
+ SfxDispatcher& rDisp = GetViewData()->GetDispatcher();
+ rDisp.Execute(SID_SBA_IMPORT, SFX_CALLMODE_ASYNCHRON,
+ &aDataDesc, &aTarget, &aAreaNew, pCursorItem.get(), (void*)0 );
+
+ bRet = TRUE;
+ }
+ }
+ else if (nFormatId == SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)
+ {
+ // insert database field control
+
+ if ( ::svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), CTF_COLUMN_DESCRIPTOR | CTF_CONTROL_EXCHANGE ) )
+ {
+ MakeDrawLayer();
+ ScDrawView* pScDrawView = GetScDrawView();
+ SdrObject* pObj = pScDrawView->CreateFieldControl( ::svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
+ if (pObj)
+ {
+ Point aInsPos = aPos;
+ Rectangle aRect(pObj->GetLogicRect());
+ aInsPos.X() -= aRect.GetSize().Width() / 2;
+ aInsPos.Y() -= aRect.GetSize().Height() / 2;
+ if ( aInsPos.X() < 0 ) aInsPos.X() = 0;
+ if ( aInsPos.Y() < 0 ) aInsPos.Y() = 0;
+ aRect.SetPos(aInsPos);
+ pObj->SetLogicRect(aRect);
+
+ if ( pObj->ISA(SdrUnoObj) )
+ pObj->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pObj->NbcSetLayer(SC_LAYER_FRONT);
+ if (pObj->ISA(SdrObjGroup))
+ {
+ SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
+ SdrObject* pSubObj = aIter.Next();
+ while (pSubObj)
+ {
+ if ( pSubObj->ISA(SdrUnoObj) )
+ pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pSubObj->NbcSetLayer(SC_LAYER_FRONT);
+ pSubObj = aIter.Next();
+ }
+ }
+
+ pScDrawView->InsertObjectSafe(pObj, *pScDrawView->GetSdrPageView());
+
+ GetViewData()->GetViewShell()->SetDrawShell( TRUE );
+ bRet = TRUE;
+ }
+ }
+ }
+ else if (nFormatId == SOT_FORMAT_BITMAP)
+ {
+ Bitmap aBmp;
+ if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) )
+ bRet = PasteBitmap( aPos, aBmp );
+ }
+ else if (nFormatId == SOT_FORMAT_GDIMETAFILE)
+ {
+ GDIMetaFile aMtf;
+ if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
+ bRet = PasteMetaFile( aPos, aMtf );
+ }
+ else if (nFormatId == SOT_FORMATSTR_ID_SVXB)
+ {
+ SotStorageStreamRef xStm;
+ if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
+ {
+ Graphic aGraphic;
+ *xStm >> aGraphic;
+ bRet = PasteGraphic( aPos, aGraphic, EMPTY_STRING, EMPTY_STRING );
+ }
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_DRAWING )
+ {
+ SotStorageStreamRef xStm;
+ if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) )
+ {
+ MakeDrawLayer(); // before loading model, so 3D factory has been created
+
+ SvtPathOptions aPathOpt;
+ String aPath = aPathOpt.GetPalettePath();
+
+ ScDocShellRef aDragShellRef( new ScDocShell );
+ aDragShellRef->DoInitNew(NULL);
+ FmFormModel* pModel = new FmFormModel( aPath, NULL, aDragShellRef );
+
+ pModel->GetItemPool().FreezeIdRanges();
+ xStm->Seek(0);
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
+ SvxDrawingLayerImport( pModel, xInputStream );
+
+ // set everything to right layer:
+ ULONG nObjCount = 0;
+ USHORT nPages = pModel->GetPageCount();
+ for (USHORT i=0; i<nPages; i++)
+ {
+ SdrPage* pPage = pModel->GetPage(i);
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->ISA(SdrUnoObj) )
+ pObject->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pObject->NbcSetLayer(SC_LAYER_FRONT);
+ pObject = aIter.Next();
+ }
+
+ nObjCount += pPage->GetObjCount(); // #105888# count group object only once
+ }
+
+ PasteDraw( aPos, pModel, (nObjCount > 1) ); // grouped if more than 1 object
+ delete pModel;
+ aDragShellRef->DoClose();
+ bRet = TRUE;
+ }
+ }
+ else if ( (nFormatId == SOT_FORMATSTR_ID_BIFF_5) || (nFormatId == SOT_FORMATSTR_ID_BIFF_8) )
+ {
+ // do excel import into a clipboard document
+ //TODO/MBA: testing
+ uno::Reference < io::XInputStream > xStm;
+ if( aDataHelper.GetInputStream( nFormatId, xStm ) )
+ {
+#if 0
+ SotStorage aDest( "d:\\test.xls" ); // to see the file
+ pStor->CopyTo( &aDest );
+#endif
+ ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
+ SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
+ pInsDoc->ResetClip( pDoc, nSrcTab );
+
+ SfxMedium aMed;
+ aMed.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, uno::makeAny( xStm ) ) );
+ FltError eErr = ScFormatFilter::Get().ScImportExcel( aMed, pInsDoc, EIF_AUTO );
+ if ( eErr == eERR_OK )
+ {
+ ScRange aSource;
+ const ScExtDocOptions* pExtOpt = pInsDoc->GetExtDocOptions();
+ const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : 0;
+ if( pTabSett && pTabSett->maUsedArea.IsValid() )
+ {
+ aSource = pTabSett->maUsedArea;
+ // ensure correct sheet indexes
+ aSource.aStart.SetTab( nSrcTab );
+ aSource.aEnd.SetTab( nSrcTab );
+// #92240# don't use selection area: if cursor is moved in Excel after Copy, selection
+// represents the new cursor position and not the copied area
+ }
+ else
+ {
+ DBG_ERROR("no dimension"); //! possible?
+ SCCOL nFirstCol, nLastCol;
+ SCROW nFirstRow, nLastRow;
+ if ( pInsDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
+ pInsDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
+ else
+ {
+ nFirstCol = nLastCol = 0;
+ nFirstRow = nLastRow = 0;
+ }
+ aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
+ nLastCol, nLastRow, nSrcTab );
+ }
+
+ if ( pLogicPos )
+ {
+ // position specified (Drag&Drop) - change selection
+ MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, FALSE, FALSE );
+ Unmark();
+ }
+
+ pInsDoc->SetClipArea( aSource );
+ PasteFromClip( IDF_ALL, pInsDoc,
+ PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
+ bAllowDialogs );
+ delete pInsDoc;
+
+ bRet = TRUE;
+ }
+ }
+ }
+ else if ( nFormatId == SOT_FORMAT_FILE )
+ {
+ String aFile;
+ if ( aDataHelper.GetString( nFormatId, aFile ) )
+ bRet = PasteFile( aPos, aFile, bLink );
+ }
+ else if ( nFormatId == SOT_FORMAT_FILE_LIST )
+ {
+ FileList aFileList;
+ if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
+ {
+ ULONG nCount = aFileList.Count();
+ for( ULONG i = 0; i < nCount ; i++ )
+ {
+ String aFile = aFileList.GetFile( i );
+
+ PasteFile( aPos, aFile, bLink );
+#if 0
+ SfxStringItem aNameItem( FID_INSERT_FILE, aFile );
+ SfxPointItem aPosItem( FN_PARAM_1, aPos );
+ SfxDispatcher* pDisp =
+ GetViewData()->GetViewShell()->GetViewFrame()->GetDispatcher();
+ if (pDisp)
+ pDisp->Execute( FID_INSERT_FILE, SFX_CALLMODE_ASYNCHRON,
+ &aNameItem, &aPosItem, (void*)0 );
+#endif
+
+ aPos.X() += 400;
+ aPos.Y() += 400;
+ }
+ bRet = TRUE;
+ }
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_SOLK ||
+ nFormatId == SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ||
+ nFormatId == SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ||
+ nFormatId == SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR )
+ {
+ bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
+ }
+
+ pDoc->SetPastingDrawFromOtherDoc( FALSE );
+
+ return bRet;
+}
+
+ByteString lcl_GetSubString( sal_Char* pData, long nStart, long nDataSize )
+{
+ if ( nDataSize <= nStart /* || pData[nDataSize] != 0 */ )
+ {
+ DBG_ERROR("DDE Data: invalid data");
+ return ByteString();
+ }
+ return ByteString( pData + nStart );
+}
+
+BOOL ScViewFunc::PasteDDE( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
+{
+ TransferableDataHelper aDataHelper( rxTransferable );
+
+ // get link data from transferable before string data,
+ // so the source knows it will be used for a link
+
+ uno::Sequence<sal_Int8> aSequence;
+ if ( !aDataHelper.GetSequence( SOT_FORMATSTR_ID_LINK, aSequence ) )
+ {
+ DBG_ERROR("DDE Data not found.");
+ return FALSE;
+ }
+
+ // check size (only if string is available in transferable)
+
+ USHORT nCols = 1;
+ USHORT nRows = 1;
+ if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ {
+ String aDataStr;
+ if ( aDataHelper.GetString( SOT_FORMAT_STRING, aDataStr ) )
+ {
+ // get size from string the same way as in ScDdeLink::DataChanged
+
+ aDataStr.ConvertLineEnd(LINEEND_LF);
+ xub_StrLen nLen = aDataStr.Len();
+ if (nLen && aDataStr.GetChar(nLen-1) == '\n')
+ aDataStr.Erase(nLen-1);
+
+ if (aDataStr.Len())
+ {
+ nRows = aDataStr.GetTokenCount( '\n' );
+ String aLine = aDataStr.GetToken( 0, '\n' );
+ if (aLine.Len())
+ nCols = aLine.GetTokenCount( '\t' );
+ }
+ }
+ }
+
+ // create formula
+
+ long nSeqLen = aSequence.getLength();
+ sal_Char* pData = (sal_Char*)aSequence.getConstArray();
+
+ rtl_TextEncoding eSysEnc = gsl_getSystemTextEncoding();
+
+ ByteString aByteApp = lcl_GetSubString( pData, 0, nSeqLen );
+ ByteString aByteTopic = lcl_GetSubString( pData, aByteApp.Len() + 1, nSeqLen );
+ ByteString aByteItem = lcl_GetSubString( pData, aByteApp.Len() + aByteTopic.Len() + 2, nSeqLen );
+
+ String aApp( aByteApp, eSysEnc );
+ String aTopic( aByteTopic, eSysEnc );
+ String aItem( aByteItem, eSysEnc );
+
+ // TODO: we could define ocQuote for "
+ const String aQuote( '"' );
+ const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
+ String aFormula( '=' );
+ aFormula += ScCompiler::GetNativeSymbol( ocDde);
+ aFormula += ScCompiler::GetNativeSymbol( ocOpen);
+ aFormula += aQuote;
+ aFormula += aApp;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aTopic;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aItem;
+ aFormula += aQuote;
+ aFormula += ScCompiler::GetNativeSymbol( ocClose);
+
+ // mark range
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ HideAllCursors();
+ DoneBlockMode();
+ InitBlockMode( nCurX, nCurY, nTab );
+ MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
+ ShowAllCursors();
+
+ // enter formula
+
+ EnterMatrix( aFormula );
+ CursorPosChanged();
+
+ return TRUE;
+}
+
+
diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx
new file mode 100644
index 000000000000..6f25af2a0826
--- /dev/null
+++ b/sc/source/ui/view/viewfun6.cxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svdundo.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+
+#include "viewfunc.hxx"
+#include "detfunc.hxx"
+#include "detdata.hxx"
+#include "viewdata.hxx"
+#include "drwlayer.hxx"
+#include "docsh.hxx"
+#include "undocell.hxx"
+#include "futext.hxx"
+#include "docfunc.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "fusel.hxx"
+
+//==================================================================
+
+void ScViewFunc::DetectiveAddPred()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveAddPred( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT(); //! use broadcast in DocFunc instead?
+}
+
+void ScViewFunc::DetectiveDelPred()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveDelPred( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveAddSucc()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveAddSucc( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveDelSucc()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveDelSucc( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveAddError()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveAddError( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveDelAll()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveDelAll( GetViewData()->GetTabNo() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveMarkInvalid()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().
+ DetectiveMarkInvalid( GetViewData()->GetTabNo() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveRefresh()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bDone = pDocSh->GetDocFunc().DetectiveRefresh();
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+//---------------------------------------------------------------------------
+
+void ScViewFunc::ShowNote( bool bShow )
+{
+ if( bShow )
+ HideNoteMarker();
+ const ScViewData& rViewData = *GetViewData();
+ ScAddress aPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
+ // show note moved to ScDocFunc, to be able to use it in notesuno.cxx
+ rViewData.GetDocShell()->GetDocFunc().ShowNote( aPos, bShow );
+}
+
+void ScViewFunc::EditNote()
+{
+ // zum Editieren einblenden und aktivieren
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aPos( nCol, nRow, nTab );
+
+ // start drawing undo to catch undo action for insertion of the caption object
+ pDocSh->MakeDrawLayer();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ pDrawLayer->BeginCalcUndo();
+ // generated undo action is processed in FuText::StopEditMode
+
+ // get existing note or create a new note (including caption drawing object)
+ if( ScPostIt* pNote = pDoc->GetOrCreateNote( aPos ) )
+ {
+ // hide temporary note caption
+ HideNoteMarker();
+ // show caption object without changing internal visibility state
+ pNote->ShowCaptionTemp( aPos );
+
+ /* 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
+ if( FuPoor* pDraw = GetDrawFuncPtr() )
+ static_cast< FuSelection* >( pDraw )->ActivateNoteHandles( pCaption );
+
+ // activate object (as in FuSelection::TestComment)
+ GetViewData()->GetDispatcher().Execute( SID_DRAW_NOTEEDIT, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+ // jetzt den erzeugten FuText holen und in den EditModus setzen
+ FuPoor* pPoor = GetDrawFuncPtr();
+ if ( pPoor && (pPoor->GetSlotID() == SID_DRAW_NOTEEDIT) ) // hat keine RTTI
+ {
+ ScrollToObject( pCaption ); // Objekt komplett sichtbar machen
+ static_cast< FuText* >( pPoor )->SetInEditMode( pCaption );
+ }
+ }
+ }
+}
diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx
new file mode 100644
index 000000000000..afa06ddfee3e
--- /dev/null
+++ b/sc/source/ui/view/viewfun7.cxx
@@ -0,0 +1,454 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/xbitmap.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xoutbmp.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/embed/Aspects.hpp>
+
+#include "document.hxx" // fuer MapMode Initialisierung in PasteDraw
+#include "viewfunc.hxx"
+#include "tabvwsh.hxx"
+#include "drawview.hxx"
+#include "scmod.hxx"
+#include "drwlayer.hxx"
+#include "drwtrans.hxx"
+#include "globstr.hrc"
+
+extern Point aDragStartDiff;
+
+// STATIC DATA -----------------------------------------------------------
+
+BOOL bPasteIsMove = FALSE;
+
+using namespace com::sun::star;
+
+//==================================================================
+
+void lcl_AdjustInsertPos( ScViewData* pData, Point& rPos, Size& rSize )
+{
+// SdrPage* pPage = pData->GetDocument()->GetDrawLayer()->GetPage( pData->GetTabNo() );
+ SdrPage* pPage = pData->GetScDrawView()->GetModel()->GetPage( static_cast<sal_uInt16>(pData->GetTabNo()) );
+ DBG_ASSERT(pPage,"pPage ???");
+ Size aPgSize( pPage->GetSize() );
+ if (aPgSize.Width() < 0)
+ aPgSize.Width() = -aPgSize.Width();
+ long x = aPgSize.Width() - rPos.X() - rSize.Width();
+ long y = aPgSize.Height() - rPos.Y() - rSize.Height();
+ // ggf. Ajustments (80/200) fuer Pixel-Rundungsfehler
+ if( x < 0 )
+ rPos.X() += x + 80;
+ if( y < 0 )
+ rPos.Y() += y + 200;
+ rPos.X() += rSize.Width() / 2; // Position bei Paste gibt Mittelpunkt an
+ rPos.Y() += rSize.Height() / 2;
+}
+
+void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel,
+ BOOL bGroup, BOOL bSameDocClipboard )
+{
+ MakeDrawLayer();
+ Point aPos( rLogicPos );
+
+ // #64184# MapMode am Outliner-RefDevice muss stimmen (wie in FuText::MakeOutliner)
+ //! mit FuText::MakeOutliner zusammenfassen?
+ MapMode aOldMapMode;
+ OutputDevice* pRef = GetViewData()->GetDocument()->GetDrawLayer()->GetRefDevice();
+ if (pRef)
+ {
+ aOldMapMode = pRef->GetMapMode();
+ pRef->SetMapMode( MapMode(MAP_100TH_MM) );
+ }
+
+ BOOL bNegativePage = GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() );
+
+ SdrView* pDragEditView = NULL;
+ ScModule* pScMod = SC_MOD();
+ const ScDragData& rData = pScMod->GetDragData();
+ ScDrawTransferObj* pDrawTrans = rData.pDrawTransfer;
+ if (pDrawTrans)
+ {
+ pDragEditView = pDrawTrans->GetDragSourceView();
+
+ aPos -= aDragStartDiff;
+ if ( bNegativePage )
+ {
+ if (aPos.X() > 0) aPos.X() = 0;
+ }
+ else
+ {
+ if (aPos.X() < 0) aPos.X() = 0;
+ }
+ if (aPos.Y() < 0) aPos.Y() = 0;
+ }
+
+ ScDrawView* pScDrawView = GetScDrawView();
+ if (bGroup)
+ pScDrawView->BegUndo( ScGlobal::GetRscString( STR_UNDO_PASTE ) );
+
+ BOOL bSameDoc = ( pDragEditView && pDragEditView->GetModel() == pScDrawView->GetModel() );
+ if (bSameDoc)
+ {
+ // lokal kopieren - incl. Charts
+
+ Point aSourceStart = pDragEditView->GetAllMarkedRect().TopLeft();
+ long nDiffX = aPos.X() - aSourceStart.X();
+ long nDiffY = aPos.Y() - aSourceStart.Y();
+
+ // innerhalb einer Page verschieben?
+
+ if ( bPasteIsMove &&
+ pScDrawView->GetSdrPageView()->GetPage() ==
+ pDragEditView->GetSdrPageView()->GetPage() )
+ {
+ if ( nDiffX != 0 || nDiffY != 0 )
+ pDragEditView->MoveAllMarked(Size(nDiffX,nDiffY), FALSE);
+ }
+ else
+ {
+ SdrModel* pDrawModel = pDragEditView->GetModel();
+ SdrPage* pDestPage = pDrawModel->GetPage( static_cast<sal_uInt16>(GetViewData()->GetTabNo()) );
+ DBG_ASSERT(pDestPage,"nanu, Page?");
+
+ SdrMarkList aMark = pDragEditView->GetMarkedObjectList();
+ aMark.ForceSort();
+ ULONG nMarkAnz=aMark.GetMarkCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++) {
+ const SdrMark* pM=aMark.GetMark(nm);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+
+ // #116235#
+ SdrObject* pNeuObj=pObj->Clone();
+ //SdrObject* pNeuObj=pObj->Clone(pDestPage,pDrawModel);
+
+ if (pNeuObj!=NULL)
+ {
+ pNeuObj->SetModel(pDrawModel);
+ pNeuObj->SetPage(pDestPage);
+
+ // #68787# copy graphics within the same model - always needs new name
+ if ( pNeuObj->ISA(SdrGrafObj) && !bPasteIsMove )
+ pNeuObj->SetName(((ScDrawLayer*)pDrawModel)->GetNewGraphicName());
+
+ if (nDiffX!=0 || nDiffY!=0)
+ pNeuObj->NbcMove(Size(nDiffX,nDiffY));
+ pDestPage->InsertObject( pNeuObj );
+ pScDrawView->AddUndo(new SdrUndoInsertObj( *pNeuObj ));
+
+ // Chart braucht nicht mehr getrennt behandelt zu werden,
+ // weil es seine Daten jetzt selber hat
+ }
+ }
+
+ if (bPasteIsMove)
+ pDragEditView->DeleteMarked();
+ }
+ }
+ else
+ {
+ bPasteIsMove = FALSE; // kein internes Verschieben passiert
+
+ SdrView aView(pModel); // #i71529# never create a base class of SdrView directly!
+ SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
+ aView.MarkAllObj(pPv);
+ Size aSize = aView.GetAllMarkedRect().GetSize();
+ lcl_AdjustInsertPos( GetViewData(), aPos, aSize );
+
+ // #41333# Markierung nicht aendern, wenn Ole-Objekt aktiv
+ // (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
+
+ ULONG nOptions = 0;
+ SfxInPlaceClient* pClient = GetViewData()->GetViewShell()->GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ nOptions |= SDRINSERT_DONTMARK;
+
+ // #89247# Set flag for ScDocument::UpdateChartListeners() which is
+ // called during paste.
+ if ( !bSameDocClipboard )
+ GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( TRUE );
+
+ pScDrawView->Paste( *pModel, aPos, NULL, nOptions );
+
+ if ( !bSameDocClipboard )
+ GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( FALSE );
+
+ // #68991# Paste puts all objects on the active (front) layer
+ // controls must be on SC_LAYER_CONTROLS
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+ SdrPage* pPage = pScDrawView->GetModel()->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->ISA(SdrUnoObj) && pObject->GetLayer() != SC_LAYER_CONTROLS )
+ pObject->NbcSetLayer(SC_LAYER_CONTROLS);
+ pObject = aIter.Next();
+ }
+ }
+
+ // #75299# all graphics objects must have names
+ GetViewData()->GetDocument()->EnsureGraphicNames();
+ }
+
+ if (bGroup)
+ {
+ pScDrawView->GroupMarked();
+ pScDrawView->EndUndo();
+ }
+
+ if (pRef)
+ pRef->SetMapMode( aOldMapMode );
+
+ // GetViewData()->GetViewShell()->SetDrawShell( TRUE );
+ // #99759# It is not sufficient to just set the DrawShell if we pasted, for
+ // example, a chart. SetDrawShellOrSub() would only work for D&D in the
+ // same document but not if inserting from the clipboard, therefore
+ // MarkListHasChanged() is what we need.
+ pScDrawView->MarkListHasChanged();
+
+}
+
+BOOL ScViewFunc::PasteObject( const Point& rPos, const uno::Reference < embed::XEmbeddedObject >& xObj,
+ const Size* pDescSize, const Graphic* pReplGraph, const ::rtl::OUString& aMediaType, sal_Int64 nAspect )
+{
+ MakeDrawLayer();
+ if ( xObj.is() )
+ {
+ ::rtl::OUString aName;
+ //TODO/MBA: is that OK?
+ comphelper::EmbeddedObjectContainer& aCnt = GetViewData()->GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer();
+ if ( !aCnt.HasEmbeddedObject( xObj ) )
+ aCnt.InsertEmbeddedObject( xObj, aName );
+ else
+ aName = aCnt.GetEmbeddedObjectName( xObj );
+
+ svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
+ if ( pReplGraph )
+ aObjRef.SetGraphic( *pReplGraph, aMediaType );
+
+ Size aSize;
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ {
+ MapMode aMapMode( MAP_100TH_MM );
+ aSize = aObjRef.GetSize( &aMapMode );
+ }
+ else
+ {
+ // working with visual area can switch object to running state
+ MapUnit aMapObj = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+ MapUnit aMap100 = MAP_100TH_MM;
+
+ if ( pDescSize && pDescSize->Width() && pDescSize->Height() )
+ {
+ // use size from object descriptor if given
+ aSize = OutputDevice::LogicToLogic( *pDescSize, aMap100, aMapObj );
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+ }
+
+ awt::Size aSz;
+ try
+ {
+ aSz = xObj->getVisualAreaSize( nAspect );
+ }
+ catch ( embed::NoVisualAreaSizeException& )
+ {
+ // the default size will be set later
+ }
+
+ aSize = Size( aSz.Width, aSz.Height );
+ aSize = OutputDevice::LogicToLogic( aSize, aMapObj, aMap100 ); // fuer SdrOle2Obj
+
+ if( aSize.Height() == 0 || aSize.Width() == 0 )
+ {
+ DBG_ERROR("SvObjectDescriptor::GetSize == 0");
+ aSize.Width() = 5000;
+ aSize.Height() = 5000;
+ aSize = OutputDevice::LogicToLogic( aSize, aMap100, aMapObj );
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+ }
+ }
+
+ // don't call AdjustInsertPos
+ Point aInsPos = rPos;
+ if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) )
+ aInsPos.X() -= aSize.Width();
+ Rectangle aRect( aInsPos, aSize );
+
+ ScDrawView* pDrView = GetScDrawView();
+ SdrOle2Obj* pSdrObj = new SdrOle2Obj( aObjRef, aName, aRect );
+
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ pDrView->InsertObjectSafe( pSdrObj, *pPV ); // nicht markieren wenn Ole
+ GetViewData()->GetViewShell()->SetDrawShell( TRUE );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+BOOL ScViewFunc::PasteBitmap( const Point& rPos, const Bitmap& rBmp )
+{
+ String aEmpty;
+ Graphic aGraphic(rBmp);
+ return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty );
+}
+
+BOOL ScViewFunc::PasteMetaFile( const Point& rPos, const GDIMetaFile& rMtf )
+{
+ String aEmpty;
+ Graphic aGraphic(rMtf);
+ return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty );
+}
+
+BOOL ScViewFunc::PasteGraphic( const Point& rPos, const Graphic& rGraphic,
+ const String& rFile, const String& rFilter )
+{
+ MakeDrawLayer();
+ ScDrawView* pScDrawView = GetScDrawView();
+
+ Point aPos( rPos );
+ Window* pWin = GetActiveWin();
+ MapMode aSourceMap = rGraphic.GetPrefMapMode();
+ MapMode aDestMap( MAP_100TH_MM );
+
+ if (aSourceMap.GetMapUnit() == MAP_PIXEL)
+ {
+ // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
+
+ Fraction aScaleX, aScaleY;
+ pScDrawView->CalcNormScale( aScaleX, aScaleY );
+ aDestMap.SetScaleX(aScaleX);
+ aDestMap.SetScaleY(aScaleY);
+ }
+
+ Size aSize = pWin->LogicToLogic( rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
+// lcl_AdjustInsertPos( GetViewData(), aPos, aSize );
+ if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) )
+ aPos.X() -= aSize.Width();
+
+ GetViewData()->GetViewShell()->SetDrawShell( TRUE );
+
+ Rectangle aRect(aPos, aSize);
+ SdrGrafObj* pGrafObj = new SdrGrafObj(rGraphic, aRect);
+
+ // #118522# calling SetGraphicLink here doesn't work
+
+ // #49961# Pfad wird nicht mehr als Name der Grafik gesetzt
+
+ ScDrawLayer* pLayer = (ScDrawLayer*) pScDrawView->GetModel();
+ String aName = pLayer->GetNewGraphicName(); // "Grafik x"
+ pGrafObj->SetName(aName);
+
+ // nicht markieren wenn Ole
+ pScDrawView->InsertObjectSafe(pGrafObj, *pScDrawView->GetSdrPageView());
+
+ // #118522# SetGraphicLink has to be used after inserting the object,
+ // otherwise an empty graphic is swapped in and the contact stuff crashes.
+ // See #i37444#.
+ if (rFile.Len())
+ pGrafObj->SetGraphicLink( rFile, rFilter );
+
+ return TRUE;
+}
+
+BOOL ScViewFunc::ApplyGraphicToObject( SdrObject* pPickObj, const Graphic& rGraphic )
+{
+ BOOL bRet = FALSE;
+ SdrGrafObj* pNewGrafObj = NULL;
+
+ ScDrawView* pScDrawView = GetScDrawView();
+ if ( pScDrawView && pPickObj )
+ {
+ /**********************************************************************
+ * Objekt neu attributieren
+ **********************************************************************/
+ SdrPageView* pPV = pScDrawView->GetSdrPageView();
+ if (pPickObj->ISA(SdrGrafObj))
+ {
+ /******************************************************************
+ * Das Graphik-Objekt bekommt eine neue Graphik
+ ******************************************************************/
+ pNewGrafObj = (SdrGrafObj*) pPickObj->Clone();
+ pNewGrafObj->SetGraphic(rGraphic);
+
+ pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
+ pScDrawView->ReplaceObjectAtView(pPickObj, *pPV, pNewGrafObj);
+ pScDrawView->EndUndo();
+
+ bRet = TRUE;
+ }
+ else if (pPickObj->IsClosedObj() && !pPickObj->ISA(SdrOle2Obj))
+ {
+ /******************************************************************
+ * Das Objekt wird mit der Graphik gefuellt
+ ******************************************************************/
+ //pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
+ pScDrawView->AddUndo(new SdrUndoAttrObj(*pPickObj));
+ //pScDrawView->EndUndo();
+
+ XOBitmap aXOBitmap( rGraphic.GetBitmap() );
+ SfxItemSet aSet( pScDrawView->GetModel()->GetItemPool(),
+ XATTR_FILLSTYLE, XATTR_FILLBITMAP );
+ aSet.Put(XFillStyleItem(XFILL_BITMAP));
+ aSet.Put(XFillBitmapItem(String(), aXOBitmap));
+
+ pPickObj->SetMergedItemSetAndBroadcast(aSet);
+
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
new file mode 100644
index 000000000000..231eb4e67562
--- /dev/null
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -0,0 +1,3018 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/wrkwin.hxx>
+#include <stdlib.h> // qsort
+
+#include "viewfunc.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "undocell.hxx"
+#include "undoblk.hxx"
+#include "undotab.hxx"
+#include "refundo.hxx"
+#include "dbcolect.hxx"
+#include "olinetab.hxx"
+#include "rangeutl.hxx"
+#include "rangenam.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "stlsheet.hxx"
+#include "editutil.hxx"
+//CHINA001 #include "namecrea.hxx" // wegen Flags
+#include "cell.hxx"
+#include "scresid.hxx"
+#include "inputhdl.hxx"
+#include "scmod.hxx"
+#include "inputopt.hxx"
+#include "compiler.hxx"
+#include "docfunc.hxx"
+#include "appoptio.hxx"
+#include "dociter.hxx"
+#include "sizedev.hxx"
+#include "editable.hxx"
+#include "scui_def.hxx" //CHINA001
+#include "funcdesc.hxx"
+#include "docuno.hxx"
+#include "cellsuno.hxx"
+//==================================================================
+
+ScViewFunc::ScViewFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
+ ScTabView( pParent, rDocSh, pViewShell ),
+ bFormatValid( FALSE )
+{
+}
+
+//UNUSED2008-05 ScViewFunc::ScViewFunc( Window* pParent, const ScViewFunc& rViewFunc, ScTabViewShell* pViewShell ) :
+//UNUSED2008-05 ScTabView( pParent, rViewFunc, pViewShell ),
+//UNUSED2008-05 bFormatValid( FALSE )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScViewFunc::~ScViewFunc()
+{
+}
+
+//------------------------------------------------------------------------------------
+
+void ScViewFunc::StartFormatArea()
+{
+ // ueberhaupt aktiviert?
+ if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
+ return;
+
+ // start only with single cell (marked or cursor position)
+ ScRange aMarkRange;
+ BOOL bOk = (GetViewData()->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
+ if ( bOk && aMarkRange.aStart != aMarkRange.aEnd )
+ bOk = FALSE;
+
+ if (bOk)
+ {
+ bFormatValid = TRUE;
+ aFormatSource = aMarkRange.aStart;
+ aFormatArea = ScRange( aFormatSource );
+ }
+ else
+ bFormatValid = FALSE; // keinen alten Bereich behalten
+}
+
+BOOL ScViewFunc::TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bAttrChanged )
+{
+ // ueberhaupt aktiviert?
+ if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
+ return FALSE;
+
+ // Test: Eingabe mit Zahlformat (bAttrChanged) immer als neue Attributierung behandeln
+ // (alte Area verwerfen). Wenn das nicht gewollt ist, den if-Teil weglassen:
+ if ( bAttrChanged )
+ {
+ StartFormatArea();
+ return FALSE;
+ }
+
+ //! Abfrage, ob Zelle leer war ???
+
+ BOOL bFound = FALSE;
+ ScRange aNewRange = aFormatArea;
+ if ( bFormatValid && nTab == aFormatSource.Tab() )
+ {
+ if ( nRow >= aFormatArea.aStart.Row() && nRow <= aFormatArea.aEnd.Row() )
+ {
+ // innerhalb ?
+ if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
+ {
+ bFound = TRUE; // Bereich nicht aendern
+ }
+ // links ?
+ if ( nCol+1 == aFormatArea.aStart.Col() )
+ {
+ bFound = TRUE;
+ aNewRange.aStart.SetCol( nCol );
+ }
+ // rechts ?
+ if ( nCol == aFormatArea.aEnd.Col()+1 )
+ {
+ bFound = TRUE;
+ aNewRange.aEnd.SetCol( nCol );
+ }
+ }
+ if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
+ {
+ // oben ?
+ if ( nRow+1 == aFormatArea.aStart.Row() )
+ {
+ bFound = TRUE;
+ aNewRange.aStart.SetRow( nRow );
+ }
+ // unten ?
+ if ( nRow == aFormatArea.aEnd.Row()+1 )
+ {
+ bFound = TRUE;
+ aNewRange.aEnd.SetRow( nRow );
+ }
+ }
+ }
+
+ if (bFound)
+ aFormatArea = aNewRange; // erweitern
+ else
+ {
+ bFormatValid = FALSE; // ausserhalb -> abbrechen
+ if ( bAttrChanged ) // Wert mit Zahlformat eingegeben?
+ StartFormatArea(); // dann ggf. neu starten
+ }
+
+ return bFound;
+}
+
+void ScViewFunc::DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ BOOL bAttrChanged, BOOL bAddUndo )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bAddUndo && !pDoc->IsUndoEnabled())
+ bAddUndo = FALSE;
+
+ const ScPatternAttr* pSource = pDoc->GetPattern(
+ aFormatSource.Col(), aFormatSource.Row(), nTab );
+ if ( !((const ScMergeAttr&)pSource->GetItem(ATTR_MERGE)).IsMerged() )
+ {
+ const ScPatternAttr* pDocOld = pDoc->GetPattern( nCol, nRow, nTab );
+ // pDocOld ist nur bis zum Apply... gueltig!
+
+ ScPatternAttr* pOldPattern = NULL;
+ if ( bAddUndo )
+ pOldPattern = new ScPatternAttr( *pDocOld );
+
+ const ScStyleSheet* pSrcStyle = pSource->GetStyleSheet();
+ if ( pSrcStyle && pSrcStyle != pDocOld->GetStyleSheet() )
+ pDoc->ApplyStyle( nCol, nRow, nTab, *pSrcStyle );
+ pDoc->ApplyPattern( nCol, nRow, nTab, *pSource );
+ AdjustRowHeight( nRow, nRow, TRUE ); //! nicht doppelt ?
+
+ if ( bAddUndo )
+ {
+ const ScPatternAttr* pNewPattern = pDoc->GetPattern( nCol, nRow, nTab );
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoCursorAttr( pDocSh, nCol, nRow, nTab,
+ pOldPattern, pNewPattern, pSource,
+ TRUE ) );
+
+ delete pOldPattern; // wird im Undo kopiert (Pool)
+ }
+ }
+
+ if ( bAttrChanged ) // Wert mit Zahlformat eingegeben?
+ aFormatSource.Set( nCol, nRow, nTab ); // dann als neue Quelle
+}
+
+//------------------------------------------------------------------------------------
+
+// Hilfsroutinen
+
+USHORT ScViewFunc::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, BOOL bFormula )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ USHORT nTwips = pDoc->GetOptimalColWidth( nCol, nTab, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, bFormula, &rMark );
+ return nTwips;
+}
+
+BOOL ScViewFunc::SelectionEditable( BOOL* pOnlyNotBecauseOfMatrix /* = NULL */ )
+{
+ BOOL bRet;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (rMark.IsMarked() || rMark.IsMultiMarked())
+ bRet = pDoc->IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix );
+ else
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ bRet = pDoc->IsBlockEditable( nTab, nCol, nRow, nCol, nRow,
+ pOnlyNotBecauseOfMatrix );
+ }
+ return bRet;
+}
+
+#ifndef LRU_MAX
+#define LRU_MAX 10
+#endif
+
+BOOL lcl_FunctionKnown( USHORT nOpCode )
+{
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ ULONG nCount = pFuncList->GetCount();
+ for (ULONG i=0; i<nCount; i++)
+ if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL lcl_AddFunction( ScAppOptions& rAppOpt, USHORT nOpCode )
+{
+ USHORT nOldCount = rAppOpt.GetLRUFuncListCount();
+ USHORT* pOldList = rAppOpt.GetLRUFuncList();
+ USHORT nPos;
+ for (nPos=0; nPos<nOldCount; nPos++)
+ if (pOldList[nPos] == nOpCode) // is the function already in the list?
+ {
+ if ( nPos == 0 )
+ return FALSE; // already at the top -> no change
+
+ // count doesn't change, so the original array is modified
+
+ for (USHORT nCopy=nPos; nCopy>0; nCopy--)
+ pOldList[nCopy] = pOldList[nCopy-1];
+ pOldList[0] = nOpCode;
+
+ return TRUE; // list has changed
+ }
+
+ if ( !lcl_FunctionKnown( nOpCode ) )
+ return FALSE; // not in function list -> no change
+
+ USHORT nNewCount = Min( (USHORT)(nOldCount + 1), (USHORT)LRU_MAX );
+ USHORT nNewList[LRU_MAX];
+ nNewList[0] = nOpCode;
+ for (nPos=1; nPos<nNewCount; nPos++)
+ nNewList[nPos] = pOldList[nPos-1];
+ rAppOpt.SetLRUFuncList( nNewList, nNewCount );
+
+ return TRUE; // list has changed
+}
+
+// eigentliche Funktionen
+
+// Eingabe - Undo OK
+
+void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
+ BOOL bRecord, const EditTextObject* pData )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nSelCount = rMark.GetSelectCount();
+ SCTAB i;
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScEditableTester aTester( pDoc, nCol,nRow, nCol,nRow, rMark );
+ if (aTester.IsEditable())
+ {
+ BOOL bEditDeleted = FALSE;
+ BYTE nOldScript = 0;
+
+ ScBaseCell** ppOldCells = NULL;
+ BOOL* pHasFormat = NULL;
+ ULONG* pOldFormats = NULL;
+ SCTAB* pTabs = NULL;
+ SCTAB nUndoPos = 0;
+ EditTextObject* pUndoData = NULL;
+ if ( bRecord )
+ {
+ ppOldCells = new ScBaseCell*[nSelCount];
+ pHasFormat = new BOOL[nSelCount];
+ pOldFormats = new ULONG[nSelCount];
+ pTabs = new SCTAB[nSelCount];
+ nUndoPos = 0;
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ {
+ pTabs[nUndoPos] = i;
+ ScBaseCell* pDocCell;
+ pDoc->GetCell( nCol, nRow, i, pDocCell );
+ if ( pDocCell )
+ {
+ ppOldCells[nUndoPos] = pDocCell->CloneWithoutNote( *pDoc );
+ if ( pDocCell->GetCellType() == CELLTYPE_EDIT )
+ bEditDeleted = TRUE;
+
+ BYTE nDocScript = pDoc->GetScriptType( nCol, nRow, i, pDocCell );
+ if ( nOldScript == 0 )
+ nOldScript = nDocScript;
+ else if ( nDocScript != nOldScript )
+ bEditDeleted = TRUE;
+ }
+ else
+ {
+ ppOldCells[nUndoPos] = NULL;
+ }
+
+ const SfxPoolItem* pItem;
+ const ScPatternAttr* pPattern = pDoc->GetPattern(nCol, nRow, i);
+ if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
+ ATTR_VALUE_FORMAT,FALSE,&pItem) )
+ {
+ pHasFormat[nUndoPos] = TRUE;
+ pOldFormats[nUndoPos] = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+ else
+ pHasFormat[nUndoPos] = FALSE;
+
+ ++nUndoPos;
+ }
+
+ DBG_ASSERT( nUndoPos==nSelCount, "nUndoPos!=nSelCount" );
+
+ pUndoData = ( pData ? pData->Clone() : NULL );
+ }
+
+ bool bFormula = false;
+
+ // a single '=' character is handled as string (needed for special filters)
+ if ( rString.Len() > 1 )
+ {
+ if ( rString.GetChar(0) == '=' )
+ {
+ // handle as formula
+ bFormula = true;
+ }
+ else if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
+ {
+ // if there is more than one leading '+' or '-' character, remove the additional ones
+ String aString( rString );
+ xub_StrLen nIndex = 1;
+ xub_StrLen nLen = aString.Len();
+ while ( nIndex < nLen && ( aString.GetChar( nIndex ) == '+' || aString.GetChar( nIndex ) == '-' ) )
+ {
+ ++nIndex;
+ }
+ aString.Erase( 1, nIndex - 1 );
+
+ // if the remaining part without the leading '+' or '-' character
+ // is non-empty and not a number, handle as formula
+ if ( aString.Len() > 1 )
+ {
+ sal_uInt32 nFormat = 0;
+ pDoc->GetNumberFormat( nCol, nRow, nTab, nFormat );
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ double fNumber = 0;
+ if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
+ {
+ bFormula = true;
+ }
+ }
+ }
+ }
+
+ BOOL bNumFmtChanged = FALSE;
+ if ( bFormula )
+ { // Formel, compile mit AutoCorrection
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ break;
+ ScAddress aPos( nCol, nRow, i );
+ ScCompiler aComp( pDoc, aPos);
+ aComp.SetGrammar(pDoc->GetGrammar());
+//2do: AutoCorrection via CalcOptions abschaltbar machen
+ aComp.SetAutoCorrection( TRUE );
+ if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
+ {
+ aComp.SetExtendedErrorDetection( true );
+ }
+ String aFormula( rString );
+ ScTokenArray* pArr;
+ BOOL bAgain;
+ do
+ {
+ bAgain = FALSE;
+ BOOL bAddEqual = FALSE;
+ ScTokenArray* pArrFirst = pArr = aComp.CompileString( aFormula );
+ BOOL bCorrected = aComp.IsCorrected();
+ if ( bCorrected )
+ { // probieren, mit erster Parser-Korrektur neu zu parsen
+ pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
+ }
+ if ( !pArr->GetCodeError() )
+ {
+ bAddEqual = TRUE;
+ aComp.CompileTokenArray();
+ bCorrected |= aComp.IsCorrected();
+ }
+ if ( bCorrected )
+ {
+ String aCorrectedFormula;
+ if ( bAddEqual )
+ {
+ aCorrectedFormula = '=';
+ aCorrectedFormula += aComp.GetCorrectedFormula();
+ }
+ else
+ aCorrectedFormula = aComp.GetCorrectedFormula();
+ short nResult;
+ if ( aCorrectedFormula.Len() == 1 )
+ nResult = RET_NO; // leere Formel, nur '='
+ else
+ {
+ String aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION ) );
+ aMessage += aCorrectedFormula;
+ nResult = QueryBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_YES),
+ aMessage ).Execute();
+ }
+ if ( nResult == RET_YES )
+ {
+ aFormula = aCorrectedFormula;
+ if ( pArr != pArrFirst )
+ delete pArrFirst;
+ bAgain = TRUE;
+ }
+ else
+ {
+ if ( pArr != pArrFirst )
+ {
+ delete pArr;
+ pArr = pArrFirst;
+ }
+ }
+ }
+ } while ( bAgain );
+ // um in mehreren Tabellen eingesetzt zu werden, muss die Formel
+ // via ScFormulaCell copy-ctor evtl. wegen RangeNames neu kompiliert
+ // werden, gleiches Code-Array fuer alle Zellen geht nicht.
+ // Wenn das Array einen Fehler enthaelt, muss in den neu erzeugten
+ // Zellen RPN geloescht und der Fehler explizit gesetzt werden, da
+ // via FormulaCell copy-ctor und Interpreter das, wenn moeglich,
+ // wieder glattgebuegelt wird, zu intelligent.. z.B.: =1))
+ USHORT nError = pArr->GetCodeError();
+ if ( !nError )
+ {
+ // #68693# update list of recent functions with all functions that
+ // are not within parentheses
+
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aAppOpt = pScMod->GetAppOptions();
+ BOOL bOptChanged = FALSE;
+
+ formula::FormulaToken** ppToken = pArr->GetArray();
+ USHORT nTokens = pArr->GetLen();
+ USHORT nLevel = 0;
+ for (USHORT nTP=0; nTP<nTokens; nTP++)
+ {
+ formula::FormulaToken* pTok = ppToken[nTP];
+ OpCode eOp = pTok->GetOpCode();
+ if ( eOp == ocOpen )
+ ++nLevel;
+ else if ( eOp == ocClose && nLevel )
+ --nLevel;
+ if ( nLevel == 0 && pTok->IsFunction() &&
+ lcl_AddFunction( aAppOpt, sal::static_int_cast<USHORT>( eOp ) ) )
+ bOptChanged = TRUE;
+ }
+
+ if ( bOptChanged )
+ {
+ pScMod->SetAppOptions(aAppOpt);
+ pScMod->RecentFunctionsChanged();
+ }
+ }
+
+ ScFormulaCell aCell( pDoc, aPos, pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
+ delete pArr;
+ BOOL bAutoCalc = pDoc->GetAutoCalc();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ for ( ; i<nTabCount; i++)
+ {
+ if (rMark.GetTableSelect(i))
+ {
+ aPos.SetTab( i );
+ ULONG nIndex = (ULONG) ((SfxUInt32Item*) pDoc->GetAttr(
+ nCol, nRow, i, ATTR_VALUE_FORMAT ))->GetValue();
+ if ( pFormatter->GetType( nIndex ) == NUMBERFORMAT_TEXT ||
+ ( ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' ) && nError && rString.Equals( aFormula ) ) )
+ {
+ if ( pData )
+ {
+ ScEditCell* pCell = new ScEditCell( pData, pDoc, NULL );
+ pDoc->PutCell( aPos, pCell );
+ }
+ else
+ {
+ ScStringCell* pCell = new ScStringCell( aFormula );
+ pDoc->PutCell( aPos, pCell );
+ }
+ }
+ else
+ {
+ DELETEZ(pUndoData);
+ ScFormulaCell* pCell = new ScFormulaCell( aCell, *pDoc, aPos );
+ if ( nError )
+ {
+ pCell->GetCode()->DelRPN();
+ pCell->SetErrCode( nError );
+ if(pCell->GetCode()->IsHyperLink())
+ pCell->GetCode()->SetHyperLink(FALSE);
+ }
+ pDoc->PutCell( aPos, pCell );
+ if ( !bAutoCalc )
+ { // einmal nur die Zelle berechnen und wieder dirty setzen
+ pCell->Interpret();
+ pCell->SetDirtyVar();
+ pDoc->PutInFormulaTree( pCell );
+ }
+ }
+
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ if (pDoc->SetString( nCol, nRow, i, rString ))
+ bNumFmtChanged = TRUE;
+ }
+
+ // row height must be changed if new text has a different script type
+ for (i=0; i<nTabCount && !bEditDeleted; i++)
+ if (rMark.GetTableSelect(i))
+ if ( pDoc->GetScriptType( nCol, nRow, i ) != nOldScript )
+ bEditDeleted = TRUE;
+
+ HideAllCursors();
+
+ if (bEditDeleted || pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ))
+ AdjustRowHeight(nRow,nRow);
+
+ BOOL bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
+ if (bAutoFormat)
+ DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged, bRecord);
+
+ if ( bRecord )
+ { // wg. ChangeTrack erst jetzt
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nUndoPos, pTabs,
+ ppOldCells, pHasFormat, pOldFormats,
+ rString, pUndoData ) );
+ }
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ pDocSh->PostPaintCell( nCol, nRow, i );
+
+ ShowAllCursors();
+
+ pDocSh->UpdateOle(GetViewData());
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( i = 0; i < nTabCount; ++i )
+ {
+ if ( rMark.GetTableSelect( i ) )
+ {
+ aChangeRanges.Append( ScRange( nCol, nRow, i ) );
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+
+ aModificator.SetDocumentModified();
+ }
+ else
+ {
+ ErrorMessage(aTester.GetMessageId());
+ PaintArea( nCol, nRow, nCol, nRow ); // da steht evtl. noch die Edit-Engine
+ }
+}
+
+// Wert in einzele Zelle eintragen (nur auf nTab)
+
+void ScViewFunc::EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ if ( pDoc && pDocSh )
+ {
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScEditableTester aTester( pDoc, nTab, nCol,nRow, nCol,nRow );
+ if (aTester.IsEditable())
+ {
+ ScAddress aPos( nCol, nRow, nTab );
+ ScBaseCell* pOldCell = pDoc->GetCell( aPos );
+ BOOL bNeedHeight = ( pOldCell && pOldCell->GetCellType() == CELLTYPE_EDIT )
+ || pDoc->HasAttrib(
+ nCol,nRow,nTab, nCol,nRow,nTab, HASATTR_NEEDHEIGHT );
+
+ // Undo
+ ScBaseCell* pUndoCell = (bUndo && pOldCell) ? pOldCell->CloneWithoutNote( *pDoc ) : 0;
+
+ pDoc->SetValue( nCol, nRow, nTab, rValue );
+
+ // wg. ChangeTrack nach Aenderung im Dokument
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoEnterValue( pDocSh, aPos, pUndoCell, rValue, bNeedHeight ) );
+ }
+
+/*! Zeilenhoehe anpassen? Dann auch bei Undo...
+ if (bNeedHeight)
+ AdjustRowHeight(nRow,nRow);
+*/
+
+ pDocSh->PostPaintCell( aPos );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ }
+ else
+ ErrorMessage(aTester.GetMessageId());
+ }
+}
+
+void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextObject* pData,
+ BOOL bRecord, BOOL bTestSimple )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScEditableTester aTester( pDoc, nTab, nCol,nRow, nCol,nRow );
+ if (aTester.IsEditable())
+ {
+ //
+ // Test auf Attribute
+ //
+ BOOL bSimple = FALSE;
+ BOOL bCommon = FALSE;
+ 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
+ {
+ ScEditAttrTester aAttrTester( &aEngine );
+ bSimple = !aAttrTester.NeedsObject();
+ bCommon = aAttrTester.NeedsCellAttr();
+
+ // formulas have to be recognized even if they're formatted
+ // (but commmon attributes are still collected)
+
+ if ( !bSimple && aEngine.GetParagraphCount() == 1 )
+ {
+ String aParStr = aEngine.GetText( (USHORT) 0 );
+ if ( aParStr.GetChar(0) == '=' )
+ bSimple = TRUE;
+ }
+
+ if (bCommon) // Attribute fuer Tabelle
+ {
+ pCellAttrs = new ScPatternAttr( *pOldPattern );
+ pCellAttrs->GetFromEditItemSet( &aAttrTester.GetAttribs() );
+ //! remove common attributes from EditEngine?
+ }
+ }
+
+ // #i97726# always get text for "repeat" of undo action
+ aString = ScEditUtil::GetSpaceDelimitedString(aEngine);
+
+ //
+ // Undo
+ //
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nSelCount = rMark.GetSelectCount();
+ SCTAB i;
+ ScBaseCell** ppOldCells = NULL;
+ SCTAB* pTabs = NULL;
+ SCTAB nPos = 0;
+ EditTextObject* pUndoData = NULL;
+ if (bRecord && !bSimple)
+ {
+ ppOldCells = new ScBaseCell*[nSelCount];
+ pTabs = new SCTAB[nSelCount];
+ nPos = 0;
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ {
+ pTabs[nPos] = i;
+ ScBaseCell* pDocCell;
+ pDoc->GetCell( nCol, nRow, i, pDocCell );
+ ppOldCells[nPos] = pDocCell ? pDocCell->CloneWithoutNote( *pDoc ) : 0;
+ ++nPos;
+ }
+
+ DBG_ASSERT( nPos==nSelCount, "nPos!=nSelCount" );
+
+ pUndoData = pData->Clone();
+ }
+
+ //
+ // Daten eintragen
+ //
+
+ if (bCommon)
+ pDoc->ApplyPattern(nCol,nRow,nTab,*pCellAttrs); //! Undo
+
+ if (bSimple)
+ {
+ if (bCommon)
+ AdjustRowHeight(nRow,nRow);
+
+ EnterData(nCol,nRow,nTab,aString,bRecord);
+ }
+ else
+ {
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ pDoc->PutCell( nCol, nRow, i, new ScEditCell( pData, pDoc, NULL ) );
+
+ if ( bRecord )
+ { // wg. ChangeTrack erst jetzt
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nPos, pTabs,
+ ppOldCells, NULL, NULL, aString,
+ pUndoData ) );
+ }
+
+ HideAllCursors();
+
+ AdjustRowHeight(nRow,nRow);
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ pDocSh->PostPaintCell( nCol, nRow, i );
+
+ ShowAllCursors();
+
+ pDocSh->UpdateOle(GetViewData());
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( i = 0; i < nTabCount; ++i )
+ {
+ if ( rMark.GetTableSelect( i ) )
+ {
+ aChangeRanges.Append( ScRange( nCol, nRow, i ) );
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+
+ aModificator.SetDocumentModified();
+ }
+
+ delete pCellAttrs;
+ delete pNewData;
+ }
+ else
+ {
+ ErrorMessage(aTester.GetMessageId());
+ PaintArea( nCol, nRow, nCol, nRow ); // da steht evtl. noch die Edit-Engine
+ }
+}
+
+void ScViewFunc::EnterDataAtCursor( const String& rString )
+{
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ EnterData( nPosX, nPosY, nTab, rString );
+}
+
+void ScViewFunc::EnterMatrix( const String& rString )
+{
+ ScViewData* pData = GetViewData();
+ const ScMarkData& rMark = pData->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // nichts markiert -> automatisch Block mit Groesse des Ergebnisses
+ // Formel temporaer berechnen, um an die Groesse heranzukommen
+
+ ScDocument* pDoc = pData->GetDocument();
+ SCCOL nCol = pData->GetCurX();
+ SCROW nRow = pData->GetCurY();
+ SCTAB nTab = pData->GetTabNo();
+ ScFormulaCell aFormCell( pDoc, ScAddress(nCol,nRow,nTab), rString,formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA );
+
+ SCSIZE nSizeX;
+ SCSIZE nSizeY;
+ aFormCell.GetResultDimensions( nSizeX, nSizeY );
+ if ( nSizeX != 0 && nSizeY != 0 &&
+ nCol+nSizeX-1 <= sal::static_int_cast<SCSIZE>(MAXCOL) &&
+ nRow+nSizeY-1 <= sal::static_int_cast<SCSIZE>(MAXROW) )
+ {
+ ScRange aResult( nCol, nRow, nTab,
+ sal::static_int_cast<SCCOL>(nCol+nSizeX-1),
+ sal::static_int_cast<SCROW>(nRow+nSizeY-1), nTab );
+ MarkRange( aResult, FALSE );
+ }
+ }
+
+ ScRange aRange;
+ if (pData->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = pData->GetDocShell();
+ BOOL bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, FALSE, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
+ if (bSuccess)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+BYTE ScViewFunc::GetSelectionScriptType()
+{
+ BYTE nScript = 0;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // no selection -> cursor
+
+ nScript = pDoc->GetScriptType( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ }
+ else
+ {
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, FALSE );
+ ULONG nCount = aRanges.Count();
+ for (ULONG i=0; i<nCount; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ nScript |= pDoc->GetScriptType( aIter.GetCol(), aIter.GetRow(), aIter.GetTab(), pCell );
+ pCell = aIter.GetNext();
+ }
+ }
+ }
+
+ if (nScript == 0)
+ nScript = ScGlobal::GetDefaultScriptType();
+
+ return nScript;
+}
+
+const ScPatternAttr* ScViewFunc::GetSelectionPattern()
+{
+ // Don't use UnmarkFiltered in slot state functions, for performance reasons.
+ // The displayed state is always that of the whole selection including filtered rows.
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ // MarkToMulti is no longer necessary for pDoc->GetSelectionPattern
+ const ScPatternAttr* pAttr = pDoc->GetSelectionPattern( rMark );
+ return pAttr;
+ }
+ else
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ ScMarkData aTempMark( rMark ); // copy sheet selection
+ aTempMark.SetMarkArea( ScRange( nCol, nRow, nTab ) );
+ const ScPatternAttr* pAttr = pDoc->GetSelectionPattern( aTempMark );
+ return pAttr;
+ }
+}
+
+void ScViewFunc::GetSelectionFrame( SvxBoxItem& rLineOuter,
+ SvxBoxInfoItem& rLineInner )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ if ( rMark.IsMultiMarked() )
+ {
+ ScMarkData aNewMark( rMark ); // use local copy for MarkToSimple
+ aNewMark.MarkToSimple(); // simple block is needed for GetSelectionFrame
+ pDoc->GetSelectionFrame( aNewMark, rLineOuter, rLineInner );
+ }
+ else
+ pDoc->GetSelectionFrame( rMark, rLineOuter, rLineInner );
+ }
+ else
+ {
+ const ScPatternAttr* pAttrs =
+ pDoc->GetPattern( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+
+ rLineOuter = (const SvxBoxItem&) (pAttrs->GetItem( ATTR_BORDER ));
+ rLineInner = (const SvxBoxInfoItem&)(pAttrs->GetItem( ATTR_BORDER_INNER ));
+ rLineInner.SetTable(FALSE);
+ rLineInner.SetDist(TRUE);
+ rLineInner.SetMinDist(FALSE);
+ }
+}
+
+//
+// Attribute anwenden - Undo OK
+//
+// kompletter Set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
+//
+
+void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet,
+ const SfxItemSet* pOldSet,
+ BOOL bRecord )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScPatternAttr aOldAttrs( new SfxItemSet(*pOldSet) );
+ ScPatternAttr aNewAttrs( new SfxItemSet(*pDialogSet) );
+ aNewAttrs.DeleteUnchanged( &aOldAttrs );
+
+ if ( pDialogSet->GetItemState( ATTR_VALUE_FORMAT ) == SFX_ITEM_SET )
+ { // #82521# don't reset to default SYSTEM GENERAL if not intended
+ sal_uInt32 nOldFormat =
+ ((const SfxUInt32Item&)pOldSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ sal_uInt32 nNewFormat =
+ ((const SfxUInt32Item&)pDialogSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ if ( nNewFormat != nOldFormat )
+ {
+ SvNumberFormatter* pFormatter =
+ GetViewData()->GetDocument()->GetFormatTable();
+ const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
+ LanguageType eOldLang =
+ pOldEntry ? pOldEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+ const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
+ LanguageType eNewLang =
+ pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+ if ( eNewLang != eOldLang )
+ {
+ aNewAttrs.GetItemSet().Put(
+ SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
+
+ // #40606# nur die Sprache geaendert -> Zahlformat-Attribut nicht anfassen
+ sal_uInt32 nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
+ if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
+ nNewMod <= SV_MAX_ANZ_STANDARD_FORMATE )
+ aNewAttrs.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
+ }
+ }
+ }
+
+ const SvxBoxItem* pOldOuter = (const SvxBoxItem*) &pOldSet->Get( ATTR_BORDER );
+ const SvxBoxItem* pNewOuter = (const SvxBoxItem*) &pDialogSet->Get( ATTR_BORDER );
+ const SvxBoxInfoItem* pOldInner = (const SvxBoxInfoItem*) &pOldSet->Get( ATTR_BORDER_INNER );
+ const SvxBoxInfoItem* pNewInner = (const SvxBoxInfoItem*) &pDialogSet->Get( ATTR_BORDER_INNER );
+ SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
+ SfxItemPool* pNewPool = rNewSet.GetPool();
+
+ pNewPool->Put( *pNewOuter ); // noch nicht loeschen
+ pNewPool->Put( *pNewInner );
+ rNewSet.ClearItem( ATTR_BORDER );
+ rNewSet.ClearItem( ATTR_BORDER_INNER );
+
+ /*
+ * Feststellen, ob Rahmenattribute zu setzen sind:
+ * 1. Neu != Alt
+ * 2. Ist eine der Linien nicht-DontCare (seit 238.f: IsxxValid())
+ *
+ */
+
+ BOOL bFrame = (pDialogSet->GetItemState( ATTR_BORDER ) != SFX_ITEM_DEFAULT)
+ || (pDialogSet->GetItemState( ATTR_BORDER_INNER ) != SFX_ITEM_DEFAULT);
+
+ if ( pNewOuter==pOldOuter && pNewInner==pOldInner )
+ bFrame = FALSE;
+
+ // das sollte doch der Pool abfangen: ?!??!??
+
+ if ( bFrame && pNewOuter && pNewInner )
+ if ( *pNewOuter == *pOldOuter && *pNewInner == *pOldInner )
+ bFrame = FALSE;
+
+ if ( pNewInner )
+ {
+ bFrame = bFrame
+ && ( pNewInner->IsValid(VALID_LEFT)
+ || pNewInner->IsValid(VALID_RIGHT)
+ || pNewInner->IsValid(VALID_TOP)
+ || pNewInner->IsValid(VALID_BOTTOM)
+ || pNewInner->IsValid(VALID_HORI)
+ || pNewInner->IsValid(VALID_VERT) );
+ }
+ else
+ bFrame = FALSE;
+
+ if (!bFrame)
+ ApplySelectionPattern( aNewAttrs, bRecord ); // nur normale
+ else
+ {
+ // wenn neue Items Default-Items sind, so muessen die
+ // alten Items geputtet werden:
+
+ BOOL bDefNewOuter = ( SFX_ITEMS_STATICDEFAULT == pNewOuter->GetKind() );
+ BOOL bDefNewInner = ( SFX_ITEMS_STATICDEFAULT == pNewInner->GetKind() );
+
+ ApplyPatternLines( aNewAttrs,
+ bDefNewOuter ? pOldOuter : pNewOuter,
+ bDefNewInner ? pOldInner : pNewInner,
+ bRecord );
+ }
+
+ pNewPool->Remove( *pNewOuter ); // freigeben
+ pNewPool->Remove( *pNewInner );
+
+ // Hoehen anpassen
+ AdjustBlockHeight();
+
+ // CellContentChanged wird von ApplySelectionPattern / ApplyPatternLines gerufen
+}
+
+void ScViewFunc::ApplyAttr( const SfxPoolItem& rAttrItem )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScPatternAttr aNewAttrs( new SfxItemSet( *GetViewData()->GetDocument()->GetPool(),
+ ATTR_PATTERN_START, ATTR_PATTERN_END ) );
+
+ aNewAttrs.GetItemSet().Put( rAttrItem );
+ // Wenn Ausrichtung eingestellt wird (ueber Buttons), immer Einzug 0
+ if ( rAttrItem.Which() == ATTR_HOR_JUSTIFY )
+ aNewAttrs.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT, 0 ) );
+ ApplySelectionPattern( aNewAttrs );
+
+ AdjustBlockHeight();
+
+ // CellContentChanged wird von ApplySelectionPattern gerufen
+}
+
+
+// Pattern und Rahmen
+
+void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem* pNewOuter,
+ const SvxBoxInfoItem* pNewInner, BOOL bRecord )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScRange aMarkRange;
+ aFuncMark.MarkToSimple();
+ BOOL bMulti = aFuncMark.IsMultiMarked();
+ if (bMulti)
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ else if (aFuncMark.IsMarked())
+ aFuncMark.GetMarkArea( aMarkRange );
+ else
+ {
+ aMarkRange = ScRange( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ DoneBlockMode();
+ InitOwnBlockMode();
+ aFuncMark.SetMarkArea(aMarkRange);
+ MarkDataChanged();
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ 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 );
+
+ 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, 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, aMarkRange ); // content before the change
+
+ pDoc->ApplySelectionFrame( aFuncMark, pNewOuter, pNewInner );
+
+ pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content after the change
+
+ aFuncMark.MarkToMulti();
+ pDoc->ApplySelectionPattern( rAttr, aFuncMark );
+
+ pDocSh->PostPaint( aMarkRange, PAINT_GRID, nExt );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+
+ StartFormatArea();
+}
+
+// nur Pattern
+
+void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,
+ BOOL bRecord, BOOL bCursorOnly )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData aFuncMark( pViewData->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ // State from old ItemSet doesn't matter for paint flags, as any change will be
+ // from SFX_ITEM_SET in the new ItemSet (default is ignored in ApplyPattern).
+ // New alignment is checked (check in PostPaint isn't enough) in case a right
+ // alignment is changed to left.
+ const SfxItemSet& rNewSet = rAttr.GetItemSet();
+ BOOL bSetLines = rNewSet.GetItemState( ATTR_BORDER, TRUE ) == SFX_ITEM_SET ||
+ rNewSet.GetItemState( ATTR_SHADOW, TRUE ) == SFX_ITEM_SET;
+ BOOL bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY, TRUE ) == SFX_ITEM_SET;
+
+ USHORT nExtFlags = 0;
+ if ( bSetLines )
+ nExtFlags |= SC_PF_LINES;
+ if ( bSetAlign )
+ nExtFlags |= SC_PF_WHOLEROWS;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ BOOL bMulti = aFuncMark.IsMultiMarked();
+ aFuncMark.MarkToMulti();
+ BOOL bOnlyTab = (!aFuncMark.IsMultiMarked() && !bCursorOnly && aFuncMark.GetSelectCount() > 1);
+ if (bOnlyTab)
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aFuncMark.SetMarkArea(ScRange(nCol,nRow,nTab));
+ aFuncMark.MarkToMulti();
+ }
+
+ ScRangeList aChangeRanges;
+
+ if (aFuncMark.IsMultiMarked() && !bCursorOnly)
+ {
+ ScRange aMarkRange;
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for ( SCTAB i = 0; i < nTabCount; ++i )
+ {
+ if ( aFuncMark.GetTableSelect( i ) )
+ {
+ ScRange aChangeRange( aMarkRange );
+ aChangeRange.aStart.SetTab( i );
+ aChangeRange.aEnd.SetTab( i );
+ aChangeRanges.Append( aChangeRange );
+ }
+ }
+
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+
+ if (bRecord)
+ {
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nStartTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &aFuncMark );
+
+ aFuncMark.MarkToMulti();
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionAttr(
+ pDocSh, aFuncMark,
+ nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ pUndoDoc, bMulti, &rAttr ) );
+ }
+
+ pDoc->ApplySelectionPattern( rAttr, aFuncMark );
+
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ PAINT_GRID, nExtFlags | SC_PF_TESTMERGE );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+ }
+ else // einzelne Zelle - Undo einfacher
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aChangeRanges.Append( ScRange( nCol, nRow, nTab ) );
+ ScPatternAttr* pOldPat = new ScPatternAttr(*pDoc->GetPattern( nCol, nRow, nTab ));
+
+ pDoc->ApplyPattern( nCol, nRow, nTab, rAttr );
+
+ const ScPatternAttr* pNewPat = pDoc->GetPattern( nCol, nRow, nTab );
+
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoCursorAttr( pDocSh,
+ nCol, nRow, nTab,
+ pOldPat, pNewPat, &rAttr,
+ FALSE ) ); // FALSE = nicht automatisch
+ }
+ delete pOldPat; // wird im Undo kopiert (Pool)
+
+ pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nExtFlags | SC_PF_TESTMERGE );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+ }
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aProperties;
+ sal_Int32 nCount = 0;
+ const SfxItemPropertyMap* pMap = ScCellObj::GetCellPropertyMap();
+ PropertyEntryVector_t aPropVector = pMap->getPropertyEntries();
+ for ( USHORT nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; ++nWhich )
+ {
+ const SfxPoolItem* pItem = 0;
+ if ( rNewSet.GetItemState( nWhich, TRUE, &pItem ) == SFX_ITEM_SET && pItem )
+ {
+ PropertyEntryVector_t::const_iterator aIt = aPropVector.begin();
+ while ( aIt != aPropVector.end())
+ {
+ if ( aIt->nWID == nWhich )
+ {
+ ::com::sun::star::uno::Any aVal;
+ pItem->QueryValue( aVal, aIt->nMemberId );
+ aProperties.realloc( nCount + 1 );
+ aProperties[ nCount ].Name = aIt->sName;
+ aProperties[ nCount ].Value <<= aVal;
+ ++nCount;
+ }
+ ++aIt;
+ }
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute" ) ), aChangeRanges, aProperties );
+ }
+
+ StartFormatArea();
+}
+
+void ScViewFunc::ApplyUserItemSet( const SfxItemSet& rItemSet )
+{
+ // ItemSet from UI, may have different pool
+
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScPatternAttr aNewAttrs( GetViewData()->GetDocument()->GetPool() );
+ SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
+ rNewSet.Put( rItemSet, FALSE );
+ ApplySelectionPattern( aNewAttrs );
+
+ AdjustBlockHeight();
+}
+
+const SfxStyleSheet* ScViewFunc::GetStyleSheetFromMarked()
+{
+ // Don't use UnmarkFiltered in slot state functions, for performance reasons.
+ // The displayed state is always that of the whole selection including filtered rows.
+
+ const ScStyleSheet* pSheet = NULL;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ pSheet = pDoc->GetSelectionStyle( rMark ); // MarkToMulti isn't necessary
+ else
+ pSheet = pDoc->GetStyle( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo() );
+
+ return pSheet;
+}
+
+void ScViewFunc::SetStyleSheetToMarked( SfxStyleSheet* pStyleSheet, BOOL bRecord )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ if ( !pStyleSheet) return;
+ // -------------------------------------------------------------------
+
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData aFuncMark( pViewData->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if ( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() )
+ {
+ ScRange aMarkRange;
+ aFuncMark.MarkToMulti();
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+
+ if ( bRecord )
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pUndoDoc, &aFuncMark );
+ aFuncMark.MarkToMulti();
+
+ String aName = pStyleSheet->GetName();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionStyle( pDocSh, aFuncMark, aMarkRange, aName, pUndoDoc ) );
+ }
+
+ pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, aFuncMark );
+
+ if (!AdjustBlockHeight())
+ pViewData->GetDocShell()->PostPaint( aMarkRange, PAINT_GRID );
+
+ aFuncMark.MarkToSimple();
+ }
+ else
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ if ( bRecord )
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange( nCol, nRow, 0, nCol, nRow, nTabCount-1 );
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, FALSE, pUndoDoc );
+
+ ScRange aMarkRange ( nCol, nRow, nTab );
+ ScMarkData aUndoMark = aFuncMark;
+ aUndoMark.SetMultiMarkArea( aMarkRange );
+
+ String aName = pStyleSheet->GetName();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionStyle( pDocSh, aUndoMark, aMarkRange, aName, pUndoDoc ) );
+ }
+
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (aFuncMark.GetTableSelect(i))
+ pDoc->ApplyStyle( nCol, nRow, i, (ScStyleSheet&)*pStyleSheet );
+
+ if (!AdjustBlockHeight())
+ pViewData->GetDocShell()->PostPaintCell( nCol, nRow, nTab );
+
+ }
+
+ aModificator.SetDocumentModified();
+
+ StartFormatArea();
+}
+
+
+void ScViewFunc::RemoveStyleSheetInUse( SfxStyleSheet* pStyleSheet )
+{
+ if ( !pStyleSheet) return;
+ // -------------------------------------------------------------------
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ VirtualDevice aVirtDev;
+ aVirtDev.SetMapMode(MAP_PIXEL);
+ pDoc->StyleSheetChanged( pStyleSheet, TRUE, &aVirtDev,
+ pViewData->GetPPTX(),
+ pViewData->GetPPTY(),
+ pViewData->GetZoomX(),
+ pViewData->GetZoomY() );
+
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ aModificator.SetDocumentModified();
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+}
+
+void ScViewFunc::UpdateStyleSheetInUse( SfxStyleSheet* pStyleSheet )
+{
+ if ( !pStyleSheet) return;
+ // -------------------------------------------------------------------
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ VirtualDevice aVirtDev;
+ aVirtDev.SetMapMode(MAP_PIXEL);
+ pDoc->StyleSheetChanged( pStyleSheet, FALSE, &aVirtDev,
+ pViewData->GetPPTX(),
+ pViewData->GetPPTY(),
+ pViewData->GetZoomX(),
+ pViewData->GetZoomY() );
+
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ aModificator.SetDocumentModified();
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+}
+
+// Zellen einfuegen - Undo OK
+
+BOOL ScViewFunc::InsertCells( InsCellCmd eCmd, BOOL bRecord, BOOL bPartOfPaste )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ BOOL bSuccess = pDocSh->GetDocFunc().InsertCells( aRange, &rMark, eCmd, bRecord, FALSE, bPartOfPaste );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ CellContentChanged();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ ::rtl::OUString aOperation = ( eCmd == INS_INSROWS ?
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-rows" ) ) :
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-columns" ) ) );
+ pModelObj->NotifyChanges( aOperation, aChangeRanges );
+ }
+ }
+ }
+ return bSuccess;
+ }
+ else
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ return FALSE;
+ }
+}
+
+// Zellen loeschen - Undo OK
+
+void ScViewFunc::DeleteCells( DelCellCmd eCmd, BOOL bRecord )
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( pDocSh->IsDocShared() && ( eCmd == DEL_DELROWS || eCmd == DEL_DELCOLS ) )
+ {
+ ScRange aDelRange( aRange.aStart );
+ SCCOLROW nCount = 0;
+ if ( eCmd == DEL_DELROWS )
+ {
+ nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Row() - aRange.aStart.Row() + 1 );
+ }
+ else
+ {
+ nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Col() - aRange.aStart.Col() + 1 );
+ }
+ while ( nCount > 0 )
+ {
+ pDocSh->GetDocFunc().DeleteCells( aDelRange, &rMark, eCmd, bRecord, FALSE );
+ --nCount;
+ }
+ }
+ else
+ {
+ pDocSh->GetDocFunc().DeleteCells( aRange, &rMark, eCmd, bRecord, FALSE );
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ CellContentChanged();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ if ( eCmd == DEL_DELROWS || eCmd == DEL_DELCOLS )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ ::rtl::OUString aOperation = ( eCmd == DEL_DELROWS ?
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-rows" ) ) :
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-columns" ) ) );
+ pModelObj->NotifyChanges( aOperation, aChangeRanges );
+ }
+ }
+
+ // #58106# Cursor direkt hinter den geloeschten Bereich setzen
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ if ( eCmd==DEL_CELLSLEFT || eCmd==DEL_DELCOLS )
+ nCurX = aRange.aStart.Col();
+ else
+ nCurY = aRange.aStart.Row();
+ SetCursor( nCurX, nCurY );
+ }
+ else
+ {
+ if (eCmd == DEL_DELCOLS)
+ DeleteMulti( FALSE, bRecord );
+ else if (eCmd == DEL_DELROWS)
+ DeleteMulti( TRUE, bRecord );
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+ }
+
+ Unmark();
+}
+
+void ScViewFunc::DeleteMulti( BOOL bRows, BOOL bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = bRows ? aFuncMark.GetMarkRowRanges( pRanges ) :
+ aFuncMark.GetMarkColumnRanges( pRanges );
+ if (nRangeCnt == 0)
+ {
+ pRanges[0] = pRanges[1] = bRows ? static_cast<SCCOLROW>(GetViewData()->GetCurY()) : static_cast<SCCOLROW>(GetViewData()->GetCurX());
+ nRangeCnt = 1;
+ }
+
+ // Test ob erlaubt
+
+ SCCOLROW* pOneRange = pRanges;
+ USHORT nErrorId = 0;
+ BOOL bNeedRefresh = FALSE;
+ SCCOLROW nRangeNo;
+ for (nRangeNo=0; nRangeNo<nRangeCnt && !nErrorId; nRangeNo++)
+ {
+ SCCOLROW nStart = *(pOneRange++);
+ SCCOLROW nEnd = *(pOneRange++);
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ if ( bRows )
+ {
+ nStartCol = 0;
+ nEndCol = MAXCOL;
+ nStartRow = static_cast<SCROW>(nStart);
+ nEndRow = static_cast<SCROW>(nEnd);
+ }
+ else
+ {
+ nStartCol = static_cast<SCCOL>(nStart);
+ nEndCol = static_cast<SCCOL>(nEnd);
+ nStartRow = 0;
+ nEndRow = MAXROW;
+ }
+
+ // cell protection (only needed for first range, as all following cells are moved)
+ if ( nRangeNo == 0 )
+ {
+ // test to the end of the sheet
+ ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, MAXCOL, MAXROW );
+ if (!aTester.IsEditable())
+ nErrorId = aTester.GetMessageId();
+ }
+
+ // merged cells
+ SCCOL nMergeStartX = nStartCol;
+ SCROW nMergeStartY = nStartRow;
+ SCCOL nMergeEndX = nEndCol;
+ SCROW nMergeEndY = nEndRow;
+ pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
+ pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
+
+ if ( nMergeStartX != nStartCol || nMergeStartY != nStartRow )
+ {
+ // Disallow deleting parts of a merged cell.
+ // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.
+
+ nErrorId = STR_MSSG_DELETECELLS_0;
+ }
+ if ( nMergeEndX != nEndCol || nMergeEndY != nEndRow )
+ {
+ // detect if the start of a merged cell is deleted, so the merge flags can be refreshed
+
+ bNeedRefresh = TRUE;
+ }
+ }
+
+ if ( nErrorId )
+ {
+ ErrorMessage( nErrorId );
+ delete[] pRanges;
+ return;
+ }
+
+ // ausfuehren
+
+ WaitObject aWait( GetFrameWin() ); // wichtig wegen TrackFormulas bei UpdateReference
+
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, !bRows, bRows ); // Zeilenhoehen
+
+ pOneRange = pRanges;
+ for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nStart = *(pOneRange++);
+ SCCOLROW nEnd = *(pOneRange++);
+ if (bRows)
+ pDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,FALSE,pUndoDoc );
+ else
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
+ static_cast<SCCOL>(nEnd),MAXROW,nTab,
+ IDF_ALL,FALSE,pUndoDoc );
+ }
+
+ // alle Formeln wegen Referenzen
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE );
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA,FALSE,pUndoDoc );
+
+ pUndoData = new ScRefUndoData( pDoc );
+
+ pDoc->BeginDrawUndo();
+ }
+
+ pOneRange = &pRanges[2*nRangeCnt]; // rueckwaerts
+ for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nEnd = *(--pOneRange);
+ SCCOLROW nStart = *(--pOneRange);
+
+ if (bRows)
+ pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart, static_cast<SCSIZE>(nEnd-nStart+1) );
+ else
+ pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
+ }
+
+ if (bNeedRefresh)
+ {
+ SCCOLROW nFirstStart = pRanges[0];
+ SCCOL nStartCol = bRows ? 0 : static_cast<SCCOL>(nFirstStart);
+ SCROW nStartRow = bRows ? static_cast<SCROW>(nFirstStart) : 0;
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+
+ pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
+ pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, TRUE );
+ }
+
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteMulti( pDocSh, bRows, bNeedRefresh, nTab, pRanges, nRangeCnt,
+ pUndoDoc, pUndoData ) );
+ }
+
+ if (!AdjustRowHeight(0, MAXROW))
+ {
+ if (bRows)
+ pDocSh->PostPaint( 0,pRanges[0],nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT );
+ else
+ pDocSh->PostPaint( static_cast<SCCOL>(pRanges[0]),0,nTab,
+ MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_TOP );
+ }
+ aModificator.SetDocumentModified();
+
+ CellContentChanged();
+
+ // #58106# Cursor direkt hinter den ersten geloeschten Bereich setzen
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ if ( bRows )
+ nCurY = pRanges[0];
+ else
+ nCurX = static_cast<SCCOL>(pRanges[0]);
+ SetCursor( nCurX, nCurY );
+
+ delete[] pRanges;
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+// Inhalte loeschen
+
+void ScViewFunc::DeleteContents( USHORT nFlags, BOOL bRecord )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ BOOL bEditable = SelectionEditable( &bOnlyNotBecauseOfMatrix );
+ if ( !bEditable )
+ {
+ if ( !(bOnlyNotBecauseOfMatrix &&
+ ((nFlags & (IDF_ATTRIB | IDF_EDITATTR)) == nFlags)) )
+ {
+ ErrorMessage(bOnlyNotBecauseOfMatrix ? STR_MATRIXFRAGMENTERR : STR_PROTECTIONERR);
+ return;
+ }
+ }
+
+ ScRange aMarkRange;
+ BOOL bSimple = FALSE;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
+ {
+ aMarkRange.aStart.SetCol(GetViewData()->GetCurX());
+ aMarkRange.aStart.SetRow(GetViewData()->GetCurY());
+ aMarkRange.aStart.SetTab(GetViewData()->GetTabNo());
+ aMarkRange.aEnd = aMarkRange.aStart;
+ if ( pDoc->HasAttrib( aMarkRange, HASATTR_MERGED ) )
+ {
+// InitOwnBlockMode();
+ aFuncMark.SetMarkArea( aMarkRange );
+ }
+ else
+ bSimple = TRUE;
+ }
+
+ aFuncMark.SetMarking(FALSE); // for MarkToMulti
+ aFuncMark.MarkToSimple(); // before bMulti test below
+
+ DBG_ASSERT( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() || bSimple, "delete what?" );
+
+ ScDocument* pUndoDoc = NULL;
+ BOOL bMulti = !bSimple && aFuncMark.IsMultiMarked();
+ if (!bSimple)
+ {
+ aFuncMark.MarkToMulti();
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ }
+ ScRange aExtendedRange(aMarkRange);
+ if (!bSimple)
+ {
+ if ( pDoc->ExtendMerge( aExtendedRange, TRUE ) )
+ bMulti = FALSE;
+ }
+
+ // keine Objekte auf geschuetzten Tabellen
+ BOOL bObjects = FALSE;
+ if ( nFlags & IDF_OBJECTS )
+ {
+ bObjects = TRUE;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aFuncMark.GetTableSelect(nTab) && pDoc->IsTabProtected(nTab))
+ bObjects = FALSE;
+ }
+
+ USHORT nExtFlags = 0; // extra flags are needed only if attributes are deleted
+ if ( nFlags & IDF_ATTRIB )
+ pDocSh->UpdatePaintExt( nExtFlags, aMarkRange );
+
+ // Reihenfolge:
+ // 1) BeginDrawUndo
+ // 2) Objekte loeschen (DrawUndo wird gefuellt)
+ // 3) Inhalte fuer Undo kopieren
+ // 4) Inhalte loeschen
+ // 5) Undo-Aktion anlegen
+
+ BOOL bDrawUndo = bObjects || ( nFlags & IDF_NOTE ); // needed for shown notes
+ if ( bDrawUndo && bRecord )
+ pDoc->BeginDrawUndo();
+
+ if (bObjects)
+ {
+ if (bMulti)
+ pDoc->DeleteObjectsInSelection( aFuncMark );
+ else
+ pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+/*!*/ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
+ aFuncMark );
+ }
+
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nTab = aMarkRange.aStart.Tab();
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+ ScRange aCopyRange = aExtendedRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+
+ // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
+ // nur mit IDF_HARDATTR zu langsam ist:
+ USHORT nUndoDocFlags = nFlags;
+ if (nFlags & IDF_ATTRIB)
+ nUndoDocFlags |= IDF_ATTRIB;
+ if (nFlags & IDF_EDITATTR) // Edit-Engine-Attribute
+ nUndoDocFlags |= IDF_STRING; // -> Zellen werden geaendert
+ if (nFlags & IDF_NOTE)
+ nUndoDocFlags |= IDF_CONTENTS; // #68795# copy all cells with their notes
+ // do not copy note captions to undo document
+ nUndoDocFlags |= IDF_NOCAPTIONS;
+ pDoc->CopyToDocument( aCopyRange, nUndoDocFlags, bMulti, pUndoDoc, &aFuncMark );
+ }
+
+ HideAllCursors(); // falls Zusammenfassung aufgehoben wird
+ if (bSimple)
+ pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
+ aFuncMark, nFlags );
+ else
+ {
+ pDoc->DeleteSelection( nFlags, aFuncMark );
+// aFuncMark.MarkToSimple();
+ }
+
+ if ( bRecord )
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteContents( pDocSh, aFuncMark, aExtendedRange,
+ pUndoDoc, bMulti, nFlags, bDrawUndo ) );
+ }
+
+ if (!AdjustRowHeight( aExtendedRange.aStart.Row(), aExtendedRange.aEnd.Row() ))
+ pDocSh->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
+
+ pDocSh->UpdateOle(GetViewData());
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ if ( bSimple )
+ {
+ aChangeRanges.Append( aMarkRange );
+ }
+ else
+ {
+ aFuncMark.FillRangeListWithMarks( &aChangeRanges, FALSE );
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+ ShowAllCursors();
+
+ if ( nFlags & IDF_ATTRIB )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ ForgetFormatArea();
+ else
+ StartFormatArea(); // Attribute loeschen ist auch Attributierung
+ }
+}
+
+// Spaltenbreiten/Zeilenhoehen (ueber Header) - Undo OK
+
+void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
+ ScSizeMode eMode, USHORT nSizeTwips,
+ BOOL bRecord, BOOL bPaint, ScMarkData* pMarkData )
+{
+ if (nRangeCnt == 0)
+ return;
+
+ // use view's mark if none specified
+ if ( !pMarkData )
+ pMarkData = &GetViewData()->GetMarkData();
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nFirstTab = pMarkData->GetFirstSelected();
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ SCTAB nTab;
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ BOOL bAllowed = TRUE;
+ for (nTab=0; nTab<nTabCount && bAllowed; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ for ( SCCOLROW i=0; i<nRangeCnt && bAllowed; i++ )
+ {
+ BOOL bOnlyMatrix;
+ if (bWidth)
+ bAllowed = pDoc->IsBlockEditable( nTab,
+ static_cast<SCCOL>(pRanges[2*i]),0,
+ static_cast<SCCOL>(pRanges[2*i+1]),MAXROW,
+ &bOnlyMatrix ) || bOnlyMatrix;
+ else
+ bAllowed = pDoc->IsBlockEditable( nTab, 0,pRanges[2*i],
+ MAXCOL,pRanges[2*i+1], &bOnlyMatrix ) ||
+ bOnlyMatrix;
+ }
+ }
+ if ( !bAllowed )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ SCCOLROW nStart = pRanges[0];
+ SCCOLROW nEnd = pRanges[2*nRangeCnt-1];
+
+ BOOL bFormula = FALSE;
+ if ( eMode == SC_SIZE_OPTIMAL )
+ {
+ const ScViewOptions& rOpts = GetViewData()->GetOptions();
+ bFormula = rOpts.GetOption( VOPT_FORMULAS );
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ SCCOLROW* pUndoRanges = NULL;
+
+ if ( bRecord )
+ {
+ pDoc->BeginDrawUndo(); // Drawing Updates
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ if (bWidth)
+ {
+ if ( nTab == nFirstTab )
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE );
+ else
+ pUndoDoc->AddUndoTab( nTab, nTab, TRUE, FALSE );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE,
+ FALSE, pUndoDoc );
+ }
+ else
+ {
+ if ( nTab == nFirstTab )
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE );
+ else
+ pUndoDoc->AddUndoTab( nTab, nTab, FALSE, TRUE );
+ pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc );
+ }
+ }
+
+ pUndoRanges = new SCCOLROW[ 2*nRangeCnt ];
+ memmove( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(SCCOLROW) );
+
+ //! outlines from all tables?
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nCurTab );
+ if (pTable)
+ pUndoTab = new ScOutlineTable( *pTable );
+ }
+
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ pMarkData->MarkToMulti();
+
+ BOOL bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
+ BOOL bOutline = FALSE;
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ 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++);
+ SCCOLROW nEndNo = *(pTabRanges++);
+
+ if ( !bWidth ) // Hoehen immer blockweise
+ {
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ {
+ BOOL bAll = ( eMode==SC_SIZE_OPTIMAL );
+ if (!bAll)
+ {
+ // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
+ // dann SetOptimalHeight mit bShrink = FALSE
+ for (SCROW nRow = nStartNo; nRow <= nEndNo; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow))
+ {
+ nRow = nLastRow;
+ continue;
+ }
+
+ BYTE nOld = pDoc->GetRowFlags(nRow, nTab);
+ if (nOld & CR_MANUALSIZE)
+ pDoc->SetRowFlags(nRow, nTab, nOld & ~CR_MANUALSIZE);
+ }
+ }
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, nSizeTwips, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, bAll );
+ if (bAll)
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, TRUE );
+
+ // Manual-Flag wird bei bAll=TRUE schon in SetOptimalHeight gesetzt
+ // (an bei Extra-Height, sonst aus).
+ }
+ else if ( eMode==SC_SIZE_DIRECT )
+ {
+ if (nSizeTwips)
+ {
+ pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
+ pDoc->SetManualHeight( nStartNo, nEndNo, nTab, TRUE ); // height was set manually
+ }
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
+ }
+ else if ( eMode==SC_SIZE_SHOW )
+ {
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, TRUE );
+ }
+ }
+ else // Spaltenbreiten
+ {
+ for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
+ {
+ if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab) )
+ {
+ USHORT nThisSize = nSizeTwips;
+
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ nThisSize = nSizeTwips + GetOptimalColWidth( nCol, nTab, bFormula );
+ if ( nThisSize )
+ pDoc->SetColWidth( nCol, nTab, nThisSize );
+
+ pDoc->ShowCol( nCol, nTab, bShow );
+ }
+ }
+ }
+
+ // Outline anpassen
+
+ if (bWidth)
+ {
+ if ( pDoc->UpdateOutlineCol( static_cast<SCCOL>(nStartNo),
+ static_cast<SCCOL>(nEndNo), nTab, bShow ) )
+ bOutline = TRUE;
+ }
+ else
+ {
+ if ( pDoc->UpdateOutlineRow( nStartNo, nEndNo, nTab, bShow ) )
+ bOutline = TRUE;
+ }
+ }
+ pDoc->DecSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln
+ }
+
+
+ if (!bOutline)
+ DELETEZ(pUndoTab);
+
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoWidthOrHeight( pDocSh, *pMarkData,
+ nStart, nCurTab, nEnd, nCurTab,
+ pUndoDoc, nRangeCnt, pUndoRanges,
+ pUndoTab, eMode, nSizeTwips, bWidth ) );
+ }
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ pDoc->UpdatePageBreaks( nTab );
+
+ GetViewData()->GetView()->UpdateScrollBars();
+
+ if (bPaint)
+ {
+ HideCursor();
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ if (bWidth)
+ {
+ if (pDoc->HasAttrib( static_cast<SCCOL>(nStart),0,nTab,
+ static_cast<SCCOL>(nEnd),MAXROW,nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ nStart = 0;
+ if (nStart > 0) // weiter oben anfangen wegen Linien und Cursor
+ --nStart;
+ pDocSh->PostPaint( static_cast<SCCOL>(nStart), 0, nTab,
+ MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_TOP );
+ }
+ else
+ {
+ if (pDoc->HasAttrib( 0,nStart,nTab, MAXCOL,nEnd,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ nStart = 0;
+ if (nStart != 0)
+ --nStart;
+ pDocSh->PostPaint( 0, nStart, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_LEFT );
+ }
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+
+ ShowCursor();
+ }
+
+ // #i97876# Spreadsheet data changes are not notified
+ if ( bWidth )
+ {
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ if ( pMarkData->GetTableSelect( nTab ) )
+ {
+ const SCCOLROW* pTabRanges = pRanges;
+ for ( SCCOLROW nRange = 0; nRange < nRangeCnt; ++nRange )
+ {
+ SCCOL nStartCol = static_cast< SCCOL >( *(pTabRanges++) );
+ SCCOL nEndCol = static_cast< SCCOL >( *(pTabRanges++) );
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ aChangeRanges.Append( ScRange( nCol, 0, nTab ) );
+ }
+ }
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "column-resize" ) ), aChangeRanges );
+ }
+ }
+}
+
+// Spaltenbreiten/Zeilenhoehen (ueber Blockmarken)
+
+void ScViewFunc::SetMarkedWidthOrHeight( BOOL bWidth, ScSizeMode eMode, USHORT nSizeTwips,
+ BOOL bRecord, BOOL bPaint )
+{
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ rMark.MarkToMulti();
+ if (!rMark.IsMultiMarked())
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ DoneBlockMode();
+ InitOwnBlockMode();
+ rMark.SetMultiMarkArea( ScRange( nCol,nRow,nTab ), TRUE );
+ MarkDataChanged();
+ }
+
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = 0;
+
+ if ( bWidth )
+ nRangeCnt = rMark.GetMarkColumnRanges( pRanges );
+ else
+ nRangeCnt = rMark.GetMarkRowRanges( pRanges );
+
+ SetWidthOrHeight( bWidth, nRangeCnt, pRanges, eMode, nSizeTwips, bRecord, bPaint );
+
+ delete[] pRanges;
+ rMark.MarkToSimple();
+}
+
+void ScViewFunc::ModifyCellSize( ScDirection eDir, BOOL bOptimal )
+{
+ //! Schrittweiten einstellbar
+ // Schrittweite ist auch Minimum
+ USHORT nStepX = STD_COL_WIDTH / 5;
+ USHORT nStepY = ScGlobal::nStdRowHeight;
+
+ ScModule* pScMod = SC_MOD();
+ BOOL bAnyEdit = pScMod->IsInputMode();
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ BOOL bAllowed, bOnlyMatrix;
+ if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
+ bAllowed = pDoc->IsBlockEditable( nTab, nCol,0, nCol,MAXROW, &bOnlyMatrix );
+ else
+ bAllowed = pDoc->IsBlockEditable( nTab, 0,nRow, MAXCOL,nRow, &bOnlyMatrix );
+ if ( !bAllowed && !bOnlyMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ HideAllCursors();
+
+ USHORT nWidth = pDoc->GetColWidth( nCol, nTab );
+ USHORT nHeight = pDoc->GetRowHeight( nRow, nTab );
+ SCCOLROW nRange[2];
+ if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
+ {
+ if (bOptimal) // Breite dieser einen Zelle
+ {
+ if ( bAnyEdit )
+ {
+ // beim Editieren die aktuelle Breite der Eingabe
+ ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData()->GetViewShell() );
+ if (pHdl)
+ {
+ long nEdit = pHdl->GetTextSize().Width(); // in 1/100mm
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SvxMarginItem& rMItem =
+ (const SvxMarginItem&)pPattern->GetItem(ATTR_MARGIN);
+ USHORT nMargin = rMItem.GetLeftMargin() + rMItem.GetRightMargin();
+ if ( ((const SvxHorJustifyItem&) pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_LEFT )
+ nMargin = sal::static_int_cast<USHORT>(
+ nMargin + ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue() );
+
+ nWidth = (USHORT)(nEdit * pDocSh->GetOutputFactor() / HMM_PER_TWIPS)
+ + nMargin + STD_EXTRA_WIDTH;
+ }
+ }
+ else
+ {
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ long nPixel = pDoc->GetNeededSize( nCol, nRow, nTab, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, TRUE );
+ USHORT nTwips = (USHORT)( nPixel / nPPTX );
+ if (nTwips != 0)
+ nWidth = nTwips + STD_EXTRA_WIDTH;
+ else
+ nWidth = STD_COL_WIDTH;
+ }
+ }
+ else // vergroessern / verkleinern
+ {
+ if ( eDir == DIR_RIGHT )
+ nWidth = sal::static_int_cast<USHORT>( nWidth + nStepX );
+ else if ( nWidth > nStepX )
+ nWidth = sal::static_int_cast<USHORT>( nWidth - nStepX );
+ if ( nWidth < nStepX ) nWidth = nStepX;
+ if ( nWidth > MAX_COL_WIDTH ) nWidth = MAX_COL_WIDTH;
+ }
+ nRange[0] = nRange[1] = nCol;
+ SetWidthOrHeight( TRUE, 1, nRange, SC_SIZE_DIRECT, nWidth );
+
+ // hier bei Breite auch Hoehe anpassen (nur die eine Zeile)
+
+ if (!bAnyEdit)
+ {
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ BOOL bNeedHeight =
+ ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue() ||
+ ((const SvxHorJustifyItem&)pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK;
+ if (bNeedHeight)
+ AdjustRowHeight( nRow, nRow );
+ }
+ }
+ else
+ {
+ ScSizeMode eMode;
+ if (bOptimal)
+ {
+ eMode = SC_SIZE_OPTIMAL;
+ nHeight = 0;
+ }
+ else
+ {
+ eMode = SC_SIZE_DIRECT;
+ if ( eDir == DIR_BOTTOM )
+ nHeight = sal::static_int_cast<USHORT>( nHeight + nStepY );
+ else if ( nHeight > nStepY )
+ nHeight = sal::static_int_cast<USHORT>( nHeight - nStepY );
+ if ( nHeight < nStepY ) nHeight = nStepY;
+ if ( nHeight > MAX_COL_HEIGHT ) nHeight = MAX_COL_HEIGHT;
+ //! MAX_COL_HEIGHT umbenennen in MAX_ROW_HEIGHT in global.hxx !!!!!!
+ }
+ nRange[0] = nRange[1] = nRow;
+ SetWidthOrHeight( FALSE, 1, nRange, eMode, nHeight );
+ }
+
+ if ( bAnyEdit )
+ {
+ UpdateEditView();
+ if ( pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ) )
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData()->GetViewShell() );
+ if (pHdl)
+ pHdl->SetModified(); // damit bei Enter die Hoehe angepasst wird
+ }
+ }
+
+ 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();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ BOOL bUndo(pDoc->IsUndoEnabled());
+
+ if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
+ aFunc.Protect( nTab, rPassword, FALSE );
+ else
+ {
+ // 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.Protect( i, rPassword, FALSE );
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+
+ UpdateLayerLocks(); //! broadcast to all views
+}
+
+BOOL ScViewFunc::Unprotect( SCTAB nTab, const String& rPassword )
+{
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ BOOL bChanged = FALSE;
+ BOOL bUndo (pDoc->IsUndoEnabled());
+
+ if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
+ bChanged = aFunc.Unprotect( nTab, rPassword, FALSE );
+ else
+ {
+ // modifying several tables is handled here
+
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_UNPROTECT_TAB );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ if ( rMark.GetTableSelect(i) )
+ if ( aFunc.Unprotect( i, rPassword, FALSE ) )
+ bChanged = TRUE;
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+
+ if (bChanged)
+ UpdateLayerLocks(); //! broadcast to all views
+
+ return bChanged;
+}
+
+void ScViewFunc::SetNoteText( const ScAddress& rPos, const String& rNoteText )
+{
+ GetViewData()->GetDocShell()->GetDocFunc().SetNoteText( rPos, rNoteText, FALSE );
+}
+
+void ScViewFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate )
+{
+ GetViewData()->GetDocShell()->GetDocFunc().ReplaceNote( rPos, rNoteText, pAuthor, pDate, FALSE );
+}
+
+void ScViewFunc::SetNumberFormat( short nFormatType, ULONG nAdd )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ sal_uInt32 nNumberFormat = 0;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ LanguageType eLanguage = ScGlobal::eLnge;
+ ScPatternAttr aNewAttrs( pDoc->GetPool() );
+
+ // #67936# always take language from cursor position, even if there is a selection
+
+ sal_uInt32 nCurrentNumberFormat;
+ pDoc->GetNumberFormat( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo(),
+ nCurrentNumberFormat );
+ const SvNumberformat* pEntry = pNumberFormatter->GetEntry( nCurrentNumberFormat );
+ if (pEntry)
+ eLanguage = pEntry->GetLanguage(); // sonst ScGlobal::eLnge behalten
+
+ nNumberFormat = pNumberFormatter->GetStandardFormat( nFormatType, eLanguage ) + nAdd;
+
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
+ // ATTR_LANGUAGE_FORMAT nicht
+ ApplySelectionPattern( aNewAttrs, TRUE );
+}
+
+void ScViewFunc::SetNumFmtByStr( const String& rCode )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ // Sprache immer von Cursorposition
+
+ sal_uInt32 nCurrentNumberFormat;
+ pDoc->GetNumberFormat( pViewData->GetCurX(), pViewData->GetCurY(),
+ pViewData->GetTabNo(), nCurrentNumberFormat );
+ const SvNumberformat* pEntry = pFormatter->GetEntry( nCurrentNumberFormat );
+ LanguageType eLanguage = pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge;
+
+ // Index fuer String bestimmen
+
+ BOOL bOk = TRUE;
+ sal_uInt32 nNumberFormat = pFormatter->GetEntryKey( rCode, eLanguage );
+ if ( nNumberFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ {
+ // neu eintragen
+
+ String aFormat = rCode; // wird veraendert
+ xub_StrLen nErrPos = 0;
+ short nType = 0; //! ???
+ bOk = pFormatter->PutEntry( aFormat, nErrPos, nType, nNumberFormat, eLanguage );
+ }
+
+ if ( bOk ) // gueltiges Format?
+ {
+ ScPatternAttr aNewAttrs( pDoc->GetPool() );
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
+ rSet.Put( SvxLanguageItem( eLanguage, ATTR_LANGUAGE_FORMAT ) );
+ ApplySelectionPattern( aNewAttrs, TRUE );
+ }
+
+ //! sonst Fehler zuerueckgeben / Meldung ausgeben ???
+}
+
+void ScViewFunc::ChangeNumFmtDecimals( BOOL bIncrement )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ BOOL bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ sal_uInt32 nOldFormat;
+ pDoc->GetNumberFormat( nCol, nRow, nTab, nOldFormat );
+ const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
+ if (!pOldEntry)
+ {
+ DBG_ERROR("Zahlformat nicht gefunden !!!");
+ return;
+ }
+
+ // was haben wir denn da?
+
+ sal_uInt32 nNewFormat = nOldFormat;
+ BOOL bError = FALSE;
+
+ LanguageType eLanguage = pOldEntry->GetLanguage();
+ BOOL bThousand, bNegRed;
+ USHORT nPrecision, nLeading;
+ pOldEntry->GetFormatSpecialInfo( bThousand, bNegRed, nPrecision, nLeading );
+
+ short nOldType = pOldEntry->GetType();
+ if ( 0 == ( nOldType & (
+ NUMBERFORMAT_NUMBER | NUMBERFORMAT_CURRENCY | NUMBERFORMAT_PERCENT ) ) )
+ {
+ // Datum, Zeit, Bruch, logisch, Text kann nicht angepasst werden
+ //! bei Wisssenschaftlich kann es der Numberformatter auch nicht
+ bError = TRUE;
+ }
+
+ //! Das SvNumberformat hat einen Member bStandard, verraet ihn aber nicht
+ BOOL bWasStandard = ( nOldFormat == pFormatter->GetStandardIndex( eLanguage ) );
+ if (bWasStandard)
+ {
+ // bei "Standard" die Nachkommastellen abhaengig vom Zellinhalt
+ // 0 bei leer oder Text -> keine Nachkommastellen
+ double nVal = pDoc->GetValue( ScAddress( nCol, nRow, nTab ) );
+
+ // Die Wege des Numberformatters sind unergruendlich, darum ausprobieren:
+ String aOut;
+ Color* pCol;
+ ((SvNumberformat*)pOldEntry)->GetOutputString( nVal, aOut, &pCol );
+
+ nPrecision = 0;
+ // 'E' fuer Exponential ist fest im Numberformatter
+ if ( aOut.Search('E') != STRING_NOTFOUND )
+ bError = TRUE; // Exponential nicht veraendern
+ else
+ {
+ String aDecSep( pFormatter->GetFormatDecimalSep( nOldFormat ) );
+ xub_StrLen nPos = aOut.Search( aDecSep );
+ if ( nPos != STRING_NOTFOUND )
+ nPrecision = aOut.Len() - nPos - aDecSep.Len();
+ // sonst 0 behalten
+ }
+ }
+
+ if (!bError)
+ {
+ if (bIncrement)
+ {
+ if (nPrecision<20)
+ ++nPrecision; // erhoehen
+ else
+ bError = TRUE; // 20 ist Maximum
+ }
+ else
+ {
+ if (nPrecision)
+ --nPrecision; // vermindern
+ else
+ bError = TRUE; // weniger als 0 geht nicht
+ }
+ }
+
+ if (!bError)
+ {
+ String aNewPicture;
+ pFormatter->GenerateFormat( aNewPicture, nOldFormat, eLanguage,
+ bThousand, bNegRed, nPrecision, nLeading );
+
+ nNewFormat = pFormatter->GetEntryKey( aNewPicture, eLanguage );
+ if ( nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ {
+ xub_StrLen nErrPos = 0;
+ short nNewType = 0;
+ BOOL bOk = pFormatter->PutEntry( aNewPicture, nErrPos,
+ nNewType, nNewFormat, eLanguage );
+ DBG_ASSERT( bOk, "falsches Zahlformat generiert" );
+ if (!bOk)
+ bError = TRUE;
+ }
+ }
+
+ if (!bError)
+ {
+ ScPatternAttr aNewAttrs( pDoc->GetPool() );
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
+ // ATTR_LANGUAGE_FORMAT nicht
+ ApplySelectionPattern( aNewAttrs, TRUE );
+ }
+ else
+ Sound::Beep(); // war nix
+}
+
+void ScViewFunc::ChangeIndent( BOOL bIncrement )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ ScMarkData aWorkMark = rMark;
+ ScViewUtil::UnmarkFiltered( aWorkMark, pDocSh->GetDocument() );
+ aWorkMark.MarkToMulti();
+ if (!aWorkMark.IsMultiMarked())
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aWorkMark.SetMultiMarkArea( ScRange(nCol,nRow,nTab) );
+ }
+
+ BOOL bSuccess = pDocSh->GetDocFunc().ChangeIndent( aWorkMark, bIncrement, FALSE );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(pViewData);
+ StartFormatArea();
+ }
+}
+
+BOOL ScViewFunc::InsertName( const String& rName, const String& rSymbol,
+ const String& rType )
+{
+ // Type = P,R,C,F (und Kombinationen)
+ //! Undo...
+
+ BOOL bOk = FALSE;
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRangeName* pList = pDoc->GetRangeName();
+
+ RangeType nType = RT_NAME;
+ ScRangeData* pNewEntry = new ScRangeData( pDoc, rName, rSymbol,
+ ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ nTab), nType );
+ String aUpType = rType;
+ aUpType.ToUpperAscii();
+ if ( aUpType.Search( 'P' ) != STRING_NOTFOUND )
+ nType |= RT_PRINTAREA;
+ if ( aUpType.Search( 'R' ) != STRING_NOTFOUND )
+ nType |= RT_ROWHEADER;
+ if ( aUpType.Search( 'C' ) != STRING_NOTFOUND )
+ nType |= RT_COLHEADER;
+ if ( aUpType.Search( 'F' ) != STRING_NOTFOUND )
+ nType |= RT_CRITERIA;
+ pNewEntry->AddType(nType);
+
+ if ( !pNewEntry->GetErrCode() ) // Text gueltig?
+ {
+ ScDocShellModificator aModificator( *pDocSh );
+
+ pDoc->CompileNameFormula( TRUE ); // CreateFormulaString
+
+ // Eintrag bereits vorhanden? Dann vorher entfernen (=Aendern)
+ USHORT nFoundAt;
+ if ( pList->SearchName( rName, nFoundAt ) )
+ { // alten Index uebernehmen
+ pNewEntry->SetIndex( ((ScRangeData*)pList->At(nFoundAt))->GetIndex() );
+ pList->AtFree( nFoundAt );
+ }
+
+ if ( pList->Insert( pNewEntry ) )
+ {
+ pNewEntry = NULL; // nicht loeschen
+ bOk = TRUE;
+ }
+
+ pDoc->CompileNameFormula( FALSE ); // CompileFormulaString
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+ }
+
+ delete pNewEntry; // wenn er nicht eingefuegt wurde
+ return bOk;
+}
+
+void ScViewFunc::CreateNames( USHORT nFlags )
+{
+ BOOL bDone = FALSE;
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE )
+ bDone = GetViewData()->GetDocShell()->GetDocFunc().CreateNames( aRange, nFlags, FALSE );
+
+ if (!bDone)
+ ErrorMessage(STR_CREATENAME_MARKERR);
+}
+
+USHORT ScViewFunc::GetCreateNameFlags()
+{
+ USHORT nFlags = 0;
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nDummy;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nDummy,nEndCol,nEndRow,nDummy) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ BOOL bOk;
+ SCCOL i;
+ SCROW j;
+
+ bOk = TRUE;
+ SCCOL nFirstCol = nStartCol;
+ SCCOL nLastCol = nEndCol;
+ if (nStartCol+1 < nEndCol) { ++nFirstCol; --nLastCol; }
+ for (i=nFirstCol; i<=nLastCol && bOk; i++)
+ if (!pDoc->HasStringData( i,nStartRow,nTab ))
+ bOk = FALSE;
+ if (bOk)
+ nFlags |= NAME_TOP;
+ else // Bottom nur wenn nicht Top
+ {
+ bOk = TRUE;
+ for (i=nFirstCol; i<=nLastCol && bOk; i++)
+ if (!pDoc->HasStringData( i,nEndRow,nTab ))
+ bOk = FALSE;
+ if (bOk)
+ nFlags |= NAME_BOTTOM;
+ }
+
+ bOk = TRUE;
+ SCROW nFirstRow = nStartRow;
+ SCROW nLastRow = nEndRow;
+ if (nStartRow+1 < nEndRow) { ++nFirstRow; --nLastRow; }
+ for (j=nFirstRow; j<=nLastRow && bOk; j++)
+ if (!pDoc->HasStringData( nStartCol,j,nTab ))
+ bOk = FALSE;
+ if (bOk)
+ nFlags |= NAME_LEFT;
+ else // Right nur wenn nicht Left
+ {
+ bOk = TRUE;
+ for (j=nFirstRow; j<=nLastRow && bOk; j++)
+ if (!pDoc->HasStringData( nEndCol,j,nTab ))
+ bOk = FALSE;
+ if (bOk)
+ nFlags |= NAME_RIGHT;
+ }
+ }
+
+ if (nStartCol == nEndCol)
+ nFlags &= ~( NAME_LEFT | NAME_RIGHT );
+ if (nStartRow == nEndRow)
+ nFlags &= ~( NAME_TOP | NAME_BOTTOM );
+
+ return nFlags;
+}
+
+void ScViewFunc::InsertNameList()
+{
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pDocSh->GetDocFunc().InsertNameList( aPos, FALSE ) )
+ pDocSh->UpdateOle(GetViewData());
+}
+
+
+
+
diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx
new file mode 100644
index 000000000000..a6b4e320d3ab
--- /dev/null
+++ b/sc/source/ui/view/viewutil.cxx
@@ -0,0 +1,640 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <tools/list.hxx>
+#include "scitems.hxx"
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dispatch.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/wrkwin.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+
+#include <com/sun/star/i18n/TransliterationModules.hpp>
+#include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
+
+
+#include "viewutil.hxx"
+#include "global.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "markdata.hxx"
+
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+// static
+void ScViewUtil::PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet,
+ USHORT nWhichId, USHORT nScript )
+{
+ // take the effective item from rCoreSet according to nScript
+ // and put in rShellSet under the (base) nWhichId
+
+ SfxItemPool& rPool = *rShellSet.GetPool();
+ SvxScriptSetItem aSetItem( rPool.GetSlotId(nWhichId), rPool );
+ // use PutExtended with eDefaultAs = SFX_ITEM_SET, so defaults from rCoreSet
+ // (document pool) are read and put into rShellSet (MessagePool)
+ aSetItem.GetItemSet().PutExtended( rCoreSet, SFX_ITEM_DONTCARE, SFX_ITEM_SET );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
+ if (pI)
+ rShellSet.Put( *pI, nWhichId );
+ else
+ rShellSet.InvalidateItem( nWhichId );
+}
+
+// static
+USHORT ScViewUtil::GetEffLanguage( ScDocument* pDoc, const ScAddress& rPos )
+{
+ // used for thesaurus
+
+ BYTE nScript = pDoc->GetScriptType( rPos.Col(), rPos.Row(), rPos.Tab() );
+ USHORT nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : ATTR_FONT_LANGUAGE );
+ const SfxPoolItem* pItem = pDoc->GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
+ SvxLanguageItem* pLangIt = PTR_CAST( SvxLanguageItem, pItem );
+ LanguageType eLnge;
+ if (pLangIt)
+ {
+ eLnge = (LanguageType) pLangIt->GetValue();
+ if (eLnge == LANGUAGE_DONTKNOW) //! can this happen?
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ eLnge = ( nScript == SCRIPTTYPE_ASIAN ) ? eCjk :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? eCtl : eLatin );
+ }
+ }
+ else
+ eLnge = LANGUAGE_ENGLISH_US;
+ if ( eLnge == LANGUAGE_SYSTEM )
+ eLnge = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
+
+ return eLnge;
+}
+
+// static
+sal_Int32 ScViewUtil::GetTransliterationType( USHORT nSlotID )
+{
+ sal_Int32 nType = 0;
+ switch ( nSlotID )
+ {
+ case SID_TRANSLITERATE_SENTENCE_CASE:
+ nType = com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE;
+ break;
+ case SID_TRANSLITERATE_TITLE_CASE:
+ nType = com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE;
+ break;
+ case SID_TRANSLITERATE_TOGGLE_CASE:
+ nType = com::sun::star::i18n::TransliterationModulesExtra::TOGGLE_CASE;
+ break;
+ case SID_TRANSLITERATE_UPPER:
+ nType = com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
+ break;
+ case SID_TRANSLITERATE_LOWER:
+ nType = com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;
+ break;
+ case SID_TRANSLITERATE_HALFWIDTH:
+ nType = com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;
+ break;
+ case SID_TRANSLITERATE_FULLWIDTH:
+ nType = com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
+ break;
+ case SID_TRANSLITERATE_HIRAGANA:
+ nType = com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;
+ break;
+ case SID_TRANSLITERATE_KATAGANA:
+ nType = com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
+ break;
+ }
+ return nType;
+}
+
+// static
+BOOL ScViewUtil::IsActionShown( const ScChangeAction& rAction,
+ const ScChangeViewSettings& rSettings,
+ ScDocument& rDocument )
+{
+ // abgelehnte werden durch eine invertierende akzeptierte Action dargestellt,
+ // die Reihenfolge von ShowRejected/ShowAccepted ist deswegen wichtig
+
+ if ( !rSettings.IsShowRejected() && rAction.IsRejecting() )
+ return FALSE;
+
+ if ( !rSettings.IsShowAccepted() && rAction.IsAccepted() && !rAction.IsRejecting() )
+ return FALSE;
+
+ if ( rSettings.HasAuthor() )
+ {
+ if ( rSettings.IsEveryoneButMe() )
+ {
+ // GetUser() am ChangeTrack ist der aktuelle Benutzer
+ ScChangeTrack* pTrack = rDocument.GetChangeTrack();
+ if ( !pTrack || rAction.GetUser() == pTrack->GetUser() )
+ return FALSE;
+ }
+ else if ( rAction.GetUser() != rSettings.GetTheAuthorToShow() )
+ return FALSE;
+ }
+
+ if ( rSettings.HasComment() )
+ {
+ String aComStr=rAction.GetComment();
+ aComStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ rAction.GetDescription( aComStr, &rDocument );
+ aComStr+=')';
+
+ if(!rSettings.IsValidComment(&aComStr))
+ return FALSE;
+ }
+
+ if ( rSettings.HasRange() )
+ if ( !rSettings.GetTheRangeList().Intersects( rAction.GetBigRange().MakeRange() ) )
+ return FALSE;
+
+ if ( rSettings.HasDate() && rSettings.GetTheDateMode() != SCDM_NO_DATEMODE )
+ {
+ DateTime aDateTime = rAction.GetDateTime();
+ const DateTime& rFirst = rSettings.GetTheFirstDateTime();
+ const DateTime& rLast = rSettings.GetTheLastDateTime();
+ switch ( rSettings.GetTheDateMode() )
+ { // korrespondiert mit ScHighlightChgDlg::OKBtnHdl
+ case SCDM_DATE_BEFORE:
+ if ( aDateTime > rFirst )
+ return FALSE;
+ break;
+
+ case SCDM_DATE_SINCE:
+ if ( aDateTime < rFirst )
+ return FALSE;
+ break;
+
+ case SCDM_DATE_EQUAL:
+ case SCDM_DATE_BETWEEN:
+ if ( aDateTime < rFirst || aDateTime > rLast )
+ return FALSE;
+ break;
+
+ case SCDM_DATE_NOTEQUAL:
+ if ( aDateTime >= rFirst && aDateTime <= rLast )
+ return FALSE;
+ break;
+
+ case SCDM_DATE_SAVE:
+ {
+ ScChangeTrack* pTrack = rDocument.GetChangeTrack();
+ if ( !pTrack || pTrack->GetLastSavedActionNumber() >=
+ rAction.GetActionNumber() )
+ return FALSE;
+ }
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if ( rSettings.HasActionRange() )
+ {
+ ULONG nAction = rAction.GetActionNumber();
+ ULONG nFirstAction;
+ ULONG nLastAction;
+ rSettings.GetTheActionRange( nFirstAction, nLastAction );
+ if ( nAction < nFirstAction || nAction > nLastAction )
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+// static
+void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc )
+{
+ rMark.MarkToMulti();
+
+ ScRange aMultiArea;
+ rMark.GetMultiMarkArea( aMultiArea );
+ SCCOL nStartCol = aMultiArea.aStart.Col();
+ SCROW nStartRow = aMultiArea.aStart.Row();
+ SCCOL nEndCol = aMultiArea.aEnd.Col();
+ SCROW nEndRow = aMultiArea.aEnd.Row();
+
+ bool bChanged = false;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( rMark.GetTableSelect(nTab ) )
+ {
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow))
+ {
+ // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns
+ // (visible in repaint for indentation)
+ rMark.SetMultiMarkArea(
+ ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false);
+ bChanged = true;
+ nRow = nLastRow;
+ }
+ }
+ }
+
+ if ( bChanged && !rMark.HasAnyMultiMarks() )
+ rMark.ResetMark();
+
+ rMark.MarkToSimple();
+}
+
+
+// static
+bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ bool bOneTabOnly = (nTab == rRange.aEnd.Tab());
+ // Always fit the range on its first sheet.
+ DBG_ASSERT( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet");
+ SCROW nStartRow = rRange.aStart.Row();
+ SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab);
+ if (ValidRow(nLastRow))
+ rRange.aEnd.SetRow(nLastRow);
+ SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab);
+ return static_cast<size_t>(nCount) == nRows && bOneTabOnly;
+}
+
+
+// static
+bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc )
+{
+ SCROW nStartRow = rRange.aStart.Row();
+ SCROW nEndRow = rRange.aEnd.Row();
+ for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++)
+ {
+ if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab))
+ return true;
+ }
+
+ return false;
+}
+
+// static
+void ScViewUtil::HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, USHORT nSlotId )
+{
+ SvtCJKOptions aCJKOptions;
+ SvtCTLOptions aCTLOptions;
+ bool bEnabled = true;
+
+ switch( nSlotId )
+ {
+ case SID_CHINESE_CONVERSION:
+ case SID_HANGUL_HANJA_CONVERSION:
+ bEnabled = aCJKOptions.IsAnyEnabled();
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAGANA:
+ bEnabled = aCJKOptions.IsChangeCaseMapEnabled();
+ break;
+
+ case SID_INSERT_RLM:
+ case SID_INSERT_LRM:
+ case SID_INSERT_ZWNBSP:
+ case SID_INSERT_ZWSP:
+ bEnabled = aCTLOptions.IsCTLFontEnabled();
+ break;
+
+ default:
+ DBG_ERRORFILE( "ScViewUtil::HideDisabledSlot - unknown slot ID" );
+ return;
+ }
+
+ rBindings.SetVisibleState( nSlotId, bEnabled );
+ if( !bEnabled )
+ rSet.DisableItem( nSlotId );
+}
+
+//==================================================================
+
+BOOL ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont,
+ SfxViewFrame& rFrame,
+ SvxFontItem& rNewFont,
+ String& rString )
+{
+ BOOL bRet = FALSE;
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() );
+ aSet.Put( SfxBoolItem( FN_PARAM_1, FALSE ) );
+ aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) );
+ SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
+ if ( pDlg->Execute() == RET_OK )
+ {
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, FALSE );
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT, FALSE );
+ if ( pItem )
+ rString = pItem->GetValue();
+ if ( pFontItem )
+ rNewFont = SvxFontItem( pFontItem->GetFamily(), pFontItem->GetFamilyName(), pFontItem->GetStyleName(), pFontItem->GetPitch(), pFontItem->GetCharSet(), rNewFont.Which() );
+ bRet = TRUE;
+ }
+ delete pDlg;
+ }
+ return bRet;
+}
+
+bool ScViewUtil::IsFullScreen( SfxViewShell& rViewShell )
+{
+ SfxBindings& rBindings = rViewShell.GetViewFrame()->GetBindings();
+ SfxPoolItem* pItem = 0;
+ bool bIsFullScreen = false;
+
+ if (rBindings.QueryState( SID_WIN_FULLSCREEN, pItem ) >= SFX_ITEM_DEFAULT)
+ bIsFullScreen = static_cast< SfxBoolItem* >( pItem )->GetValue();
+ return bIsFullScreen;
+}
+
+void ScViewUtil::SetFullScreen( SfxViewShell& rViewShell, bool bSet )
+{
+ if( IsFullScreen( rViewShell ) != bSet )
+ {
+ SfxBoolItem aItem( SID_WIN_FULLSCREEN, bSet );
+ rViewShell.GetDispatcher()->Execute( SID_WIN_FULLSCREEN, SFX_CALLMODE_RECORD, &aItem, 0L );
+ }
+}
+
+//------------------------------------------------------------------
+
+ScUpdateRect::ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+{
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ nOldStartX = nX1;
+ nOldStartY = nY1;
+ nOldEndX = nX2;
+ nOldEndY = nY2;
+}
+
+void ScUpdateRect::SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+{
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ nNewStartX = nX1;
+ nNewStartY = nY1;
+ nNewEndX = nX2;
+ nNewEndY = nY2;
+}
+
+BOOL ScUpdateRect::GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
+{
+ if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
+ nNewStartY == nOldStartY && nNewEndY == nOldEndY )
+ {
+ rX1 = nNewStartX;
+ rY1 = nNewStartY;
+ rX2 = nNewStartX;
+ rY2 = nNewStartY;
+ return FALSE;
+ }
+
+ rX1 = Min(nNewStartX,nOldStartX);
+ rY1 = Min(nNewStartY,nOldStartY);
+ rX2 = Max(nNewEndX,nOldEndX);
+ rY2 = Max(nNewEndY,nOldEndY);
+
+ if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX )
+ {
+ if ( nNewStartY == nOldStartY )
+ {
+ rY1 = Min( nNewEndY, nOldEndY );
+ rY2 = Max( nNewEndY, nOldEndY );
+ }
+ else if ( nNewEndY == nOldEndY )
+ {
+ rY1 = Min( nNewStartY, nOldStartY );
+ rY2 = Max( nNewStartY, nOldStartY );
+ }
+ }
+ else if ( nNewStartY == nOldStartY && nNewEndY == nOldEndY )
+ {
+ if ( nNewStartX == nOldStartX )
+ {
+ rX1 = Min( nNewEndX, nOldEndX );
+ rX2 = Max( nNewEndX, nOldEndX );
+ }
+ else if ( nNewEndX == nOldEndX )
+ {
+ rX1 = Min( nNewStartX, nOldStartX );
+ rX2 = Max( nNewStartX, nOldStartX );
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef OLD_SELECTION_PAINT
+BOOL ScUpdateRect::GetXorDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, BOOL& rCont )
+{
+ rCont = FALSE;
+
+ if (nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
+ nNewStartY == nOldStartY && nNewEndY == nOldEndY)
+ {
+ rX1 = nNewStartX;
+ rY1 = nNewStartY;
+ rX2 = nNewStartX;
+ rY2 = nNewStartY;
+ return FALSE;
+ }
+
+ rX1 = Min(nNewStartX,nOldStartX);
+ rY1 = Min(nNewStartY,nOldStartY);
+ rX2 = Max(nNewEndX,nOldEndX);
+ rY2 = Max(nNewEndY,nOldEndY);
+
+ if (nNewStartX == nOldStartX && nNewEndX == nOldEndX) // nur vertikal
+ {
+ if (nNewStartY == nOldStartY)
+ {
+ rY1 = Min( nNewEndY, nOldEndY ) + 1;
+ rY2 = Max( nNewEndY, nOldEndY );
+ }
+ else if (nNewEndY == nOldEndY)
+ {
+ rY1 = Min( nNewStartY, nOldStartY );
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ }
+ else
+ {
+ rY1 = Min( nNewStartY, nOldStartY );
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ rCont = TRUE;
+ nContY1 = Min( nNewEndY, nOldEndY ) + 1;
+ nContY2 = Max( nNewEndY, nOldEndY );
+ nContX1 = rX1;
+ nContX2 = rX2;
+ }
+ }
+ else if (nNewStartY == nOldStartY && nNewEndY == nOldEndY) // nur horizontal
+ {
+ if (nNewStartX == nOldStartX)
+ {
+ rX1 = Min( nNewEndX, nOldEndX ) + 1;
+ rX2 = Max( nNewEndX, nOldEndX );
+ }
+ else if (nNewEndX == nOldEndX)
+ {
+ rX1 = Min( nNewStartX, nOldStartX );
+ rX2 = Max( nNewStartX, nOldStartX ) - 1;
+ }
+ else
+ {
+ rX1 = Min( nNewStartX, nOldStartX );
+ rX2 = Max( nNewStartX, nOldStartX ) - 1;
+ rCont = TRUE;
+ nContX1 = Min( nNewEndX, nOldEndX ) + 1;
+ nContX2 = Max( nNewEndX, nOldEndX );
+ nContY1 = rY1;
+ nContY2 = rY2;
+ }
+ }
+ else if (nNewEndX == nOldEndX && nNewEndY == nOldEndY) // links oben
+ {
+ if ((nNewStartX<nOldStartX) == (nNewStartY<nOldStartY))
+ rX1 = Min( nNewStartX, nOldStartX );
+ else
+ rX1 = Max( nNewStartX, nOldStartX ); // Ecke weglassen
+ rX2 = nOldEndX;
+ rY1 = Min( nNewStartY, nOldStartY ); // oben
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ rCont = TRUE;
+ nContY1 = rY2+1;
+ nContY2 = nOldEndY;
+ nContX1 = Min( nNewStartX, nOldStartX ); // links
+ nContX2 = Max( nNewStartX, nOldStartX ) - 1;
+ }
+ else if (nNewStartX == nOldStartX && nNewEndY == nOldEndY) // rechts oben
+ {
+ if ((nNewEndX<nOldEndX) != (nNewStartY<nOldStartY))
+ rX2 = Max( nNewEndX, nOldEndX );
+ else
+ rX2 = Min( nNewEndX, nOldEndX ); // Ecke weglassen
+ rX1 = nOldStartX;
+ rY1 = Min( nNewStartY, nOldStartY ); // oben
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ rCont = TRUE;
+ nContY1 = rY2+1;
+ nContY2 = nOldEndY;
+ nContX1 = Min( nNewEndX, nOldEndX ) + 1; // rechts
+ nContX2 = Max( nNewEndX, nOldEndX );
+ }
+ else if (nNewEndX == nOldEndX && nNewStartY == nOldStartY) // links unten
+ {
+ if ((nNewStartX<nOldStartX) != (nNewEndY<nOldEndY))
+ rX1 = Min( nNewStartX, nOldStartX );
+ else
+ rX1 = Max( nNewStartX, nOldStartX ); // Ecke weglassen
+ rX2 = nOldEndX;
+ rY1 = Min( nNewEndY, nOldEndY ) + 1; // unten
+ rY2 = Max( nNewEndY, nOldEndY );
+ rCont = TRUE;
+ nContY1 = nOldStartY;
+ nContY2 = rY1-1;
+ nContX1 = Min( nNewStartX, nOldStartX ); // links
+ nContX2 = Max( nNewStartX, nOldStartX ) - 1;
+ }
+ else if (nNewStartX == nOldStartX && nNewStartY == nOldStartY) // rechts unten
+ {
+ if ((nNewEndX<nOldEndX) == (nNewEndY<nOldEndY))
+ rX2 = Max( nNewEndX, nOldEndX );
+ else
+ rX2 = Min( nNewEndX, nOldEndX ); // Ecke weglassen
+ rX1 = nOldStartX;
+ rY1 = Min( nNewEndY, nOldEndY ) + 1; // unten
+ rY2 = Max( nNewEndY, nOldEndY );
+ rCont = TRUE;
+ nContY1 = nOldStartY;
+ nContY2 = rY1-1;
+ nContX1 = Min( nNewEndX, nOldEndX ) + 1; // rechts
+ nContX2 = Max( nNewEndX, nOldEndX );
+ }
+ else // Ueberschlag
+ {
+ rX1 = nOldStartX;
+ rY1 = nOldStartY;
+ rX2 = nOldEndX;
+ rY2 = nOldEndY;
+ rCont = TRUE;
+ nContX1 = nNewStartX;
+ nContY1 = nNewStartY;
+ nContX2 = nNewEndX;
+ nContY2 = nNewEndY;
+ }
+
+ return TRUE;
+}
+
+void ScUpdateRect::GetContDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
+{
+ rX1 = nContX1;
+ rY1 = nContY1;
+ rX2 = nContX2;
+ rY2 = nContY2;
+}
+#endif
+
+
+
+
+
+
diff --git a/sc/source/ui/view/waitoff.cxx b/sc/source/ui/view/waitoff.cxx
new file mode 100644
index 000000000000..2e3c3e8476af
--- /dev/null
+++ b/sc/source/ui/view/waitoff.cxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <vcl/window.hxx>
+
+#include "waitoff.hxx"
+
+//------------------------------------------------------------------------
+
+ScWaitCursorOff::ScWaitCursorOff( Window* pWinP )
+ :
+ pWin( pWinP ),
+ nWaiters(0)
+{
+ if ( pWin )
+ {
+ while ( pWin->IsWait() )
+ {
+ nWaiters++;
+ pWin->LeaveWait();
+ }
+ }
+}
+
+ScWaitCursorOff::~ScWaitCursorOff()
+{
+ if ( pWin )
+ {
+ while ( nWaiters )
+ {
+ nWaiters--;
+ pWin->EnterWait();
+ }
+ }
+}
+
+
+
+